pax_global_header00006660000000000000000000000064122637572550014530gustar00rootroot0000000000000052 comment=6d01f08542ac986fab6b182e1382c69252b0d9c9 libsynthesis-3.4.0.47.1/000077500000000000000000000000001226375725500146445ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/.gitignore000066400000000000000000000012241226375725500166330ustar00rootroot00000000000000# ignore multi-git repos .git_*/ switchgit # ignore XCode build dir src/build/ # ignore XCode user specific settings/schemes xcuserdata/ # ignore generated files *.o src/sysync_SDK/bin src/Makefile.am src/CLIENT_FILES src/EXCLUDE_FILES src/EXTRA_FILES src/SDK_FILES src/SERVER_FILES src/SDK_EXCLUDE_FILES Makefile.in configure m4 aclocal.m4 autom4te.cache config.guess config.log config.status config.sub config.h.in depcomp install-sh libtool ltmain.sh missing compile Makefile # ignore Mac OS X finder metadata files .DS_Store # ignore Mac OS X ressource dir created by zip __MACOSX/ # ignore all sorts of backup files *.orig *~ *.BAK *.bak # no CVS CVS/ libsynthesis-3.4.0.47.1/AUTHORS000066400000000000000000000002631226375725500157150ustar00rootroot00000000000000Lukas Zeller : core engine Beat Forster : SDK, database adapters, time zone handling Patrick Ohly : autotools compilation libsynthesis-3.4.0.47.1/COPYING000066400000000000000000000007601226375725500157020ustar00rootroot00000000000000Unless noted otherwise, all files are triple-licensed LGPL v2.1 (LICENSE.LGPL-2.1), LGPL 3.0 (LICENSE.LGPL-3) and EPL (LICENSE.EPL) For a commercial license, please contact synthesis.ch or plan44.ch. Files in the following directories are under a different license: src/expat : public domain (src/expat/copying.txt) doc, src/sysync_SDK : BSD (LICENSE.BSD) src/syncml_tk : BSD-like license (src/syncml_tk/opensource_license.txt) src/zlib : BSD-like (src/zlib/README) libsynthesis-3.4.0.47.1/ChangeLog000066400000000000000000000000001226375725500164040ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/CodingStyle000066400000000000000000000041061226375725500170140ustar00rootroot00000000000000The coding style varies a bit with author and age of the code. When changing existing code emulate its style. If you disagree with a certain style, format code the way you are more comfortable with. These are all merely guidelines - use common sense. Here are some general guidelines for new code: * Similar to GNU formatting. * Indention is two spaces, no tabs. * Avoid curly brackets after if/while/do for single statements (as in the Linux kernel) but only if the statement needs no comment lines. * One space right and left of assignment operators, none around normal operators (such as in "a = b+c;"). Other formatting is also common. Use extra spaces if it helps readability in complex expressions. * Usually all capital with underscores for global constants. Sometimes also with lower case. * Mixed case with first upper case character for methods and functions. Inside the engine lower case beginning is more common. * Lower case for variables, if necessary upper case characters in the middle to separate words. * Prefix and suffix characters for entity names are used: prefix a: function and method argument, may also be replaced with other letters to denote special context (e.g., m = module, s = session) prefix c: constant prefix f: class or struct data member ("field") prefix T: structured type or enum suffix P[P]: pointer [to pointer] suffix H: opaque handle The following .emacs snippet can be used to configure Emacs accordingly when editing files in a "/synthesis/" directory: (add-hook 'c-mode-hook (lambda () (let ((filename (buffer-file-name))) (when (and filename (string-match "/synthesis/" filename)) (setq c-basic-offset 2) ) ))) (add-hook 'c++-mode-hook (lambda () (let ((filename (buffer-file-name))) (when (and filename (string-match "/synthesis/" filename)) (setq c-basic-offset 2) ) ))) libsynthesis-3.4.0.47.1/INSTALL000066400000000000000000000224501226375725500157000ustar00rootroot00000000000000Installation Instructions ************************* Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. This file is free documentation; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. Basic Installation ================== Briefly, the shell commands `./configure; make; make install' should configure, build, and install this package. The following more-detailed instructions are generic; see the `README' file for instructions specific to this package. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a `Makefile' in each directory of the package. It may also create one or more `.h' files containing system-dependent definitions. Finally, it creates a shell script `config.status' that you can run in the future to recreate the current configuration, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). It can also use an optional file (typically called `config.cache' and enabled with `--cache-file=config.cache' or simply `-C') that saves the results of its tests to speed up reconfiguring. Caching is disabled by default to prevent problems with accidental use of stale cache files. If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the `README' so they can be considered for the next release. If you are using the cache, and at some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.ac' (or `configure.in') is used to create `configure' by a program called `autoconf'. You need `configure.ac' if you want to change it or regenerate `configure' using a newer version of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type `./configure' to configure the package for your system. Running `configure' might take a while. While running, it prints some messages telling which features it is checking for. 2. Type `make' to compile the package. 3. Optionally, type `make check' to run any self-tests that come with the package. 4. Type `make install' to install the programs and any data files and documentation. 5. You can remove the program binaries and object files from the source code directory by typing `make clean'. To also remove the files that `configure' created (so you can compile the package for a different kind of computer), type `make distclean'. There is also a `make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. 6. Often, you can also type `make uninstall' to remove the installed files again. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the `configure' script does not know about. Run `./configure --help' for details on some of the pertinent environment variables. You can give `configure' initial values for configuration parameters by setting variables in the command line or in the environment. Here is an example: ./configure CC=c99 CFLAGS=-g LIBS=-lposix *Note Defining Variables::, for more details. Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you can use GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. With a non-GNU `make', it is safer to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use `make distclean' before reconfiguring for another architecture. Installation Names ================== By default, `make install' installs the package's commands under `/usr/local/bin', include files under `/usr/local/include', etc. You can specify an installation prefix other than `/usr/local' by giving `configure' the option `--prefix=PREFIX'. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you pass the option `--exec-prefix=PREFIX' to `configure', the package uses PREFIX as the prefix for installing programs and libraries. Documentation and other data files still use the regular prefix. In addition, if you use an unusual directory layout you can give options like `--bindir=DIR' to specify different values for particular kinds of files. Run `configure --help' for a list of the directories you can set and what kinds of files go in them. If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving `configure' the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. Optional Features ================= Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE is something like `gnu-as' or `x' (for the X Window System). The `README' should mention any `--enable-' and `--with-' options that the package recognizes. For packages that use the X Window System, `configure' can usually find the X include and library files automatically, but if it doesn't, you can use the `configure' options `--x-includes=DIR' and `--x-libraries=DIR' to specify their locations. Specifying the System Type ========================== There may be some features `configure' cannot figure out automatically, but needs to determine by the type of machine the package will run on. Usually, assuming the package is built to be run on the _same_ architectures, `configure' can figure that out, but if it prints a message saying it cannot guess the machine type, give it the `--build=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name which has the form: CPU-COMPANY-SYSTEM where SYSTEM can have one of these forms: OS KERNEL-OS See the file `config.sub' for the possible values of each field. If `config.sub' isn't included in this package, then this package doesn't need to know the machine type. If you are _building_ compiler tools for cross-compiling, you should use the option `--target=TYPE' to select the type of system they will produce code for. If you want to _use_ a cross compiler, that generates code for a platform different from the build platform, you should specify the "host" platform (i.e., that on which the generated programs will eventually be run) with `--host=TYPE'. Sharing Defaults ================ If you want to set default values for `configure' scripts to share, you can create a site shell script called `config.site' that gives default values for variables like `CC', `cache_file', and `prefix'. `configure' looks for `PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it exists. Or, you can set the `CONFIG_SITE' environment variable to the location of the site script. A warning: not all `configure' scripts look for a site script. Defining Variables ================== Variables not defined in a site shell script can be set in the environment passed to `configure'. However, some packages may run configure again during the build, and the customized values of these variables may be lost. In order to avoid this problem, you should set them in the `configure' command line, using `VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc causes the specified `gcc' to be used as the C compiler (unless it is overridden in the site shell script). Unfortunately, this technique does not work for `CONFIG_SHELL' due to an Autoconf bug. Until the bug is fixed you can use this workaround: CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash `configure' Invocation ====================== `configure' recognizes the following options to control how it operates. `--help' `-h' Print a summary of the options to `configure', and exit. `--version' `-V' Print the version of Autoconf used to generate the `configure' script, and exit. `--cache-file=FILE' Enable the cache: use and save the results of the tests in FILE, traditionally `config.cache'. FILE defaults to `/dev/null' to disable caching. `--config-cache' `-C' Alias for `--cache-file=config.cache'. `--quiet' `--silent' `-q' Do not print messages saying which checks are being made. To suppress all normal output, redirect it to `/dev/null' (any error messages will still be shown). `--srcdir=DIR' Look for the package's source code in directory DIR. Usually `configure' can determine that directory automatically. `configure' also accepts some other, not widely useful, options. Run `configure --help' for more details. libsynthesis-3.4.0.47.1/LICENSE.BSD000066400000000000000000000027331226375725500162650ustar00rootroot00000000000000Copyright (c) The Regents of the University of California. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. 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. 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. libsynthesis-3.4.0.47.1/LICENSE.EPL000066400000000000000000000257611226375725500163030ustar00rootroot00000000000000Eclipse Public License -v 1.0 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement , including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), 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 OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. libsynthesis-3.4.0.47.1/LICENSE.LGPL-2.1000066400000000000000000000636371226375725500167230ustar00rootroot00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 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! libsynthesis-3.4.0.47.1/LICENSE.LGPL-3000066400000000000000000000167271226375725500165630ustar00rootroot00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. "The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. d) Do one of the following: 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. 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 that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU 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 as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. libsynthesis-3.4.0.47.1/Makefile.am000066400000000000000000000010551226375725500167010ustar00rootroot00000000000000## Process this file with automake to produce Makefile.in SUBDIRS = src # list all additional files which need to be included by "make dist", # check with "make distcheck" EXTRA_DIST = # extra files which need to be removed during "make distclean" MAINTAINERCLEANFILES = Makefile.in config.guess config.sub configure depcomp install-sh ltmain.sh missing mkinstalldirs # required for rebuilding autotools files via make ACLOCAL_AMFLAGS = -I m4 -I m4-repo ${ACLOCAL_FLAGS} pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = synthesis.pc synthesis-sdk.pc libsynthesis-3.4.0.47.1/NEWS000066400000000000000000000000001226375725500153310ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/README000066400000000000000000000031771226375725500155340ustar00rootroot00000000000000Build dependencies ------------------ pcre sqlite3 xmltok or expat (optional, bundled source is used automatically if not installed) zlib Ubuntu 8.04: libpcre3-dev libsqlite3-dev libexpat-dev libz-dev Contributions ------------- You are free to modify and distribute under the licenses indicated in COPYING. As many other companies which dual-license their code, Synthesis must be able to use all code in the upstream repository for their commercial offerings. Therefore please sign the Synthesis_AG_Contributor_Agreement.pdf and send it to Synthesis before submitting patches and code to Synthesis for inclusion. By doing so you simplify your own usage of the code (no need to merge your changes with new upstream releases again and again) and ensure that Synthesis will continue to release updates under an open source license (we need to finance the development with sales from our commercial products for commercial platforms and applications). Synthesis is a small, entirely self-funded venture and the code that is now becoming opensource is the work of 8 years focus on SyncML. So we count on contributors to understand that in our own interest as well as the interest of the project's future we need to be able to continue our commercial products without complicating the process of developing them. With the contributor agreement we can avoid the need for forking our internal work into an open source branch and an internal branch, which would severely reduce the possible output on the opensource branch. The contributor agreement ensures we'll be able to share our internal progress in the project without delay with the open source community. libsynthesis-3.4.0.47.1/README.DLT000066400000000000000000000103661226375725500161540ustar00rootroot00000000000000GENIVI Diagnostic Log and Trace (DLT) support ============================================= DLT is a logging mechanism defined by GENIVI. It supports the context of log message contexts (arbitrary groups, defined by the app or library) and levels (off, fatal, error, warning, information, debug, verbose). The log level can be set per context, using mechanisms provided by DLT (for example, interactively via DLT client connected to a system running the DLT daemon and apps using that daemon). If DLT support is enabled during compilation of libsynthesis (use --enable-dlt on Linux) and in the configuration (use "dlt" as "logformat" and ignore all other logging options), then libsynthesis uses DLT for logging instead of writing its own files. libsynthesis has no concept of a strictly ordered log level. Instead major categories are combined with minor ones, which allows enabling "more verbose" logging for some aspects of a major category while leaving "less verbose" ones disabled. When using DLT, a hard-coded mapping between minor categories and log level is used, so some flexibility is lost. The mapping is as follows: Context ID = Synthesis debug topic: description (from SySync_config_reference.pdf) PROT = "proto": SyncML protocol related information. SESS = "session": Session management related information. ADMN = "admin": Everything that has to do with administrative data (anchors, targets, map table). DATA = "data": Everything that has to do with handling user data (data objects). Actual user data will however be shown only if loglevel >= debug. REMI = "remoteinfo": This shows information delivered in the remote party's device information, such as manufacturer name, datatypes supported, fields supported etc. PARS = "parse": This shows information related to parsing and processing incoming data from the remote party. Actual user data will however be shown only if loglevel >= debug. GEN = "generate": This shows information related to generating outgoing data for the remote party. Actual user data will however be shown only if loglevel >= debug. TRNS = "transp": Shows transport (http and TCP communication) related information. SMLT = "syncml_rtk": Messages generated by the SyncML Toolkit code. SYSY = "rest": Any other debug log message that does not fit in any of the above contexts. The default log level of each context can be set via env variables called LIBSYNTHESIS_, with values from 0 (off) to 6 (verbose). The log level of a message is derived from the other Synthesis debug topics: "error" => ERROR: error messages. "hot"=> INFO: most important information (of all topics). This should never be switched of (except when switching off debug logging completely). "userdata" => DEBUG: Anything that is user data. To create anonymized logs that do not show user's data, use a log level less than debug (and, depending on the database interface, "dbapi" as well, as it might show SQL commands revealing user data as well). "dbapi" => VERBOSE: Information related to accessing the database. For ODBC, this enables showing SQL statements issued to the database, for plugin datastores, this includes all communication with the plugins and also messages generated by the plugin itself (see "plugin" below). "plugin" => DEBUG: Messages generated by database adapter plugins. "scripts" => VERBOSE: This is useful to debug scripts, and shows each line of executed scripts (but only for enabled debug topics!). Switching this on can generate huge log files, so it should normally be switched off in productive environments. "expressions" => VERBOSE: Together with "scripts" this causes detailed step-by-step logging of script expression evaluation. "filter" => DEBUG. Information about data item filtering. "match" => VERBOSE: Information about matching data in slow sync. Note that together with "exotic" this can produce extremely large logs as matching is an O(N^2) operation, so use with care. "conflict" => DEBUG: Information about conflict resolution and data merging. "details" => increases log level by one. Enabling this option adds generally some more detail to the debug output. "exotic" => VERBOSE: Enabling this adds the highest level of exotic detail possible. This is usually only required to track down device interoperability issues or bugs in the server/config. libsynthesis-3.4.0.47.1/autogen.sh000077500000000000000000000005211226375725500166430ustar00rootroot00000000000000#!/bin/sh set -e # wipe out temporary autotools files, necessary # when switching between distros rm -rf m4 aclocal.m4 autom4te.cache config.guess config.sub config.h.in configure depcomp install-sh ltmain.sh missing mkdir m4 (cd src && ./gen-makefile-am.sh) libtoolize -c aclocal -I m4 -I m4-repo autoheader automake -a -c autoconf libsynthesis-3.4.0.47.1/configure.in000066400000000000000000000211411226375725500171540ustar00rootroot00000000000000dnl Invoke autogen.sh to produce a configure script. AC_INIT(src/sysync/engineinterface.cpp) AC_CONFIG_MACRO_DIR([m4]) # four digit upstream version, one additional digit for # Linux/SyncEvolution specific extensions: AM_INIT_AUTOMAKE(synthesis, 3.4.0.47.1) AM_CONFIG_HEADER(config.h) AC_LIBTOOL_DLOPEN dnl check for programs. AC_PROG_CXX AC_PROG_LIBTOOL AC_PROG_MAKE_SET AM_PROG_CC_C_O # --enable-warning=min/max/fatal/none DK_ARG_ENABLE_WARNINGS([SYNTHESIS_WFLAGS], [-Wall -Wno-unknown-pragmas -Wno-unused-but-set-variable], [-Wall -Wno-unknown-pragmas -Wno-unused-but-set-variable], []) dnl Extract PIC flags from libtool configure for libsynthesissdk.a dnl (makes assumptions about libtool var naming!). Some versions dnl of libtool use PIC mode automatically for static libraries, dnl others don't (?!). See "[os-libsynthesis] libsynthesissdk.a built without -fPIC". PIC_CXXFLAGS="$lt_prog_compiler_pic_CXX" AC_SUBST(PIC_CXXFLAGS) AC_ARG_ENABLE(debug-logs, AS_HELP_STRING([--enable-debug-logs], [For developers: add links to call location to HTML log files. Depends on Doxygen (for HTML version of source) and g++ (for __PRETTY_FUNCTION__).]), enable_debug_logs="$enableval", enable_debug_logs="no") if test "$enable_debug_logs" = "yes"; then AC_DEFINE_UNQUOTED(SYDEBUG_LOCATION, "`pwd`/src/html", [absolute path to Doxygen HTML output]) fi AM_CONDITIONAL([COND_DOXYGEN], [test "$enable_debug_logs" = "yes"]) dnl All of these libraries have to be compiled and installed dnl separately. TODO: build bundled sources? dnl dnl WARNING: the initial PKG_CHECK_MODULES() must be executed dnl in all cases (i.e., not depend on an if clause) because dnl it initializes pkg-config checking. PKG_CHECK_MODULES(FOOBAR, foobar, [true], [true]) AC_ARG_ENABLE(sqlite, AS_HELP_STRING([--enable-sqlite], [enable the sqlite-based ODBC backend, depends on libsqlite3, enabled by default]), [enable_sqlite=$enableval], [enable_sqlite="yes"]) if test "$enable_sqlite" == "yes"; then PKG_CHECK_MODULES(SQLITE3, sqlite3) HAVE_SQLITE=1 else HAVE_SQLITE=0 fi AC_DEFINE_UNQUOTED(ONOFF_SQLITE_SUPPORT, $HAVE_SQLITE, [controls whether ODBC backend with libsqlite is enabled]) AC_ARG_ENABLE(regex, AS_HELP_STRING([--enable-regex], [enable regular expression support in scripts, depends on libpcre, enabled by default]), [enable_regex=$enableval], [enable_regex="yes"]) if test "$enable_regex" == "yes"; then PKG_CHECK_MODULES(PCRE, libpcre, [HAVE_PCRE=1], [AC_ERROR([libpcre not found, required for --enable-regex])]) HAVE_PCRE=1 else HAVE_PCRE=0 fi AC_DEFINE_UNQUOTED(ONOFF_REGEX_SUPPORT, $HAVE_PCRE, "regular expressions in scripts") AC_ARG_ENABLE(dlt, AS_HELP_STRING([--enable-dlt], [enable logging mode "dlt" = GENIVI Diagnostic Log and Trace]), [enable_dlt=$enableval test $enable_dlt = "yes" || test $enable_dlt = "no" || AC_ERROR([invalid value of --enable-dlt: $enableval])], [enable_dlt="no"]) if test "$enable_dlt" = "yes"; then PKG_CHECK_MODULES(DLT, automotive-dlt, [USE_DLT=1], [AC_ERROR([dlt not found, required for --enable-dlt])]) AC_DEFINE(USE_DLT, 1, "optionally use GENIVI Diagnostic Log and Trace for logging") fi AC_CHECK_HEADER(zlib.h, , [AC_ERROR(zlib.h not found.)]) AC_CHECK_HEADER(xmltok/xmlparse.h, have_system_xmltok="yes") AC_CHECK_HEADER(expat.h, have_system_expat="yes") dnl libical might be installed stand-alone (upstream) dnl or bundled with libecal. Upstream is preferred and dnl thus checked first. libical is optional, so don't dnl complain if not found. AC_ARG_ENABLE(libical, AS_HELP_STRING([--enable-libical], [use libical (if necessary, the one in libecal) to improve time zone support, enabled by default if necessary libs are found]), [enable_libical=$enableval], [enable_libical="yes"]) if test "$enable_libical" == "yes"; then PKG_CHECK_MODULES(LIBICAL, libical, [AC_DEFINE(HAVE_LIBICAL, 1, "libical available")], [PKG_CHECK_MODULES(LIBECAL, libecal-1.2, [AC_DEFINE(HAVE_LIBICAL, 1, "libical available") AC_DEFINE(HAVE_LIBECAL, 1, "libecal available")], [true])]) fi AC_ARG_ENABLE(evolution-compatibility, AS_HELP_STRING([--enable-evolution-compatibility], [build executables which only call Evolution via dlopen/dlsym: this avoids all hard dependencies on EDS shared objects, but might lead to crashes when their ABI changes]), enable_evolution_compatibility="$enableval", enable_evolution_compatibility="no") if test "$enable_evolution_compatibility" == "yes"; then AC_DEFINE(EVOLUTION_COMPATIBILITY, 1, [avoid hard dependency on Evolution shared objects]) LIBICAL_LIBS= LIBECAL_LIBS= fi AC_ARG_WITH(xmltok, AS_HELP_STRING([--with-xmltok=], [Chooses which xmltok/xmlparse gets used. "builtin" = compile code into libsynthesis. "system" = use header files and libxmlparse from standard search paths. "path" = use header files in "path/include" and libxmlparse in "path/lib". Default is system if header files are found, otherwise builtin.]), [ if test "$withval" = "builtin"; then with_xmltok="builtin" elif test "$withval" = "system" || test "$withval" = "yes"; then with_xmltok="system" else with_xmltok="$withval" fi ], [ with_xmltok="no" ]) AC_ARG_WITH(expat, AS_HELP_STRING([--with-expat=], [Choose expat as the XML parser library. Replaces --with-xmltok. "system" = use header files and libexpat from standard search paths. "path" = use header files in "path/include", and libexpat in "path/lib".]), [ if test "$withval" = "system" || test "$withval" = "yes"; then with_expat="system" else with_expath="$withval" fi ], [ with_expat="no" ]) if test "$with_xmltok" = "no" && test "$with_expat" = "no"; then if test "$have_system_expat" = "yes"; then with_expat="yes" XMLPARSE_LIBS="-lexpat" elif test "$have_system_xmltok" = "yes"; then with_xmltok="yes" XMLPARSE_LIBS="-lxmlparse" else with_xmltok="builtin" fi elif test "$with_expat" != "no"; then if test "$with_expat" = "system"; then if test "$have_system_expat" = "yes"; then XMLPARSE_LIBS="-lexpat" else AC_ERROR(expat.h not found.) fi else # user path XMLPARSE_LIBS="-L$with_expat/lib -lexpat" XMLPARSE_CFLAGS="-I$with_expat/include" fi with_expat="yes" else # with_xmltok if test "$with_xmltok" = "system"; then if test "$have_system_xmltok" = "yes"; then XMLPARSE_LIBS="-lxmlparse" else AC_ERROR(xmltok/xmplarse.h not found.) fi elif test "$with_xmltok" != "builtin"; then XMLPARSE_LIBS="-L$with_xmltok/lib -lxmlparse" XMLPARSE_CFLAGS="-I$with_xmltok/include" fi fi if test "$with_expat" = "yes"; then AC_DEFINE(HAVE_EXPAT, 1, [Define to 1 to use expat as XML parser]) elif test "$with_xmltok" != "builtin"; then AC_DEFINE(HAVE_SYS_XMLTOK, 1, [Define to 1 use system xmltok as XML parser]) else AC_DEFINE(HAVE_BUILTIN_XMLTOK, 1, [Define to 1 use builtin xmltok as XML Parser]) fi AC_SUBST(XMLPARSE_LIBS) AC_SUBST(XMLPARSE_CFLAGS) AM_CONDITIONAL([COND_XMLPARSE], [test "$with_xmltok" = "builtin"]) AC_CHECK_HEADER(stdint.h) # the autotools SDK always assumes that it is linked against the engine AC_DEFINE(UIAPI_LINKED, 1, [libsynthesis.a linked statically]) AC_DEFINE(DBAPI_LINKED, 1, [client engine linked statically]) AC_DEFINE(DBAPI_SRV_LINKED, 1, [server engine linked statically]) # determines which object files are needed in the SDK: # if linking statically, some object files are shared with # libsynthesis.a AM_CONDITIONAL([COND_STATIC], [test "$enable_shared" = "no"]) # Disable unconditionally at the moment. Would add dependency of SDK # on SyncML Toolkit. #AC_DEFINE(WITHOUT_SAN_1_1, 1, # [support for Server Alerted Notifications according to SyncML 1.1]) AC_CONFIG_FILES(Makefile src/Makefile synthesis.pc synthesis-sdk.pc) AC_OUTPUT libsynthesis-3.4.0.47.1/doc/000077500000000000000000000000001226375725500154115ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/doc/SDK_manual.doc000066400000000000000000022420001226375725500200560ustar00rootroot00000000000000ÐÏࡱá>þÿ  Ÿþÿÿÿ“”•–—˜™š›œÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿì¥ÁY¿®dbjbjóWóW-4‘=‘=+[}ÿÿÿÿÿÿ]&0&0&0&0444242424248j4Ì66ä24>úN;ÈA(>A>A>A½`Ú—u¼S|`$8ô,¶)4³_`^½`³³)o…&0&0>A>A!N;o…o…o…³¼&0Ü>A4>A2424&0&0&0&0³o…o……Œ†ßp34>A94À)²1ìzÉ2424o…O´  HYPERLINK "http://www.synthesis.ch/"  Reference Manual for SDK and Plugin Interface V1.5.2 of the Synthesis Sync Engine V3.0 / V3.1 / V3.2 20-Jan-2009  HYPERLINK "http://www.syncml.org/"   © 2004 - 2009 by Synthesis AG This manual was written for Synthesis SyncML Engine V3.0 / V3.1 / V3.2 This manual and the Synthesis Sync Server/Client software described in it are copyrighted, with all rights reserved. This manual and the Synthesis Sync Server/Client software may not be copied, except as otherwise provided in your software license or as expressly permitted in writing by Synthesis AG ( HYPERLINK "http://www.synthesis.ch/" http://www.synthesis.ch/). Synthesis SyncML Engine uses parts of the following software: expat - XML parser - HYPERLINK "http://sourceforge.net/projects/expat"http://sourceforge.net/projects/expat Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd SyncML toolkit - HYPERLINK "http://sourceforge.net/projects/syncml-ctoolkit/"http://sourceforge.net/projects/syncml-ctoolkit/ This product includes software developed by The SyncML Initiative. Copyright (c) 2000 Ericsson, IBM, Lotus, Matsushita Communications Industrial Co., LTD, Motorola, Nokia, Palm, Inc., Psion, Starfish Software. All rights reserved. zlib compression library - HYPERLINK "http://www.zlib.net/"http://www.zlib.net/ zlib software copyright © 1995-2004 Jean-loup Gailly and Mark Adler SQLite 3 database engine - HYPERLINK "http://www.sqlite.org/"http://www.sqlite.org/ PCRE Library -  HYPERLINK "http://www.pcre.org/license.txt" http://www.pcre.org/license.txt Copyright (c) 1997-2007 University of Cambridge The project files to create the SySync SDK plug-ins are using the following software: C/C++ CodeWarrior compiler environment - HYPERLINK "http://www.metrowerks.com/"http://www.metrowerks.com Copyright © 2005 Metrowerks, a Freescale company. All rights reserved. Visual Studio - HYPERLINK "http://www.microsoft.com/"http://www.microsoft.com Copyright © 2005 Microsoft Corporation. All rights reserved. XCode - HYPERLINK "http://developer.apple.com/tools/xcode/"http://developer.apple.com/tools/xcode Copyright © 1999 – 2007 Apple Inc. All rights reserved. Disclaimer Use of the Synthesis Sync Server/Client software and other software accompanying your license (the "Software") and its documentation is at your sole risk. The Software and its documentation (including this manual), and software maintainance by Synthesis AG, if applicable, are provided "AS IS" and without warranty of any kind and Synthesis AG EXPRESSLY DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND NON-INFRINGEMENT. IN NO EVENT SHALL SYNTHESIS AG 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. Contents  VERZEICHNIS \o "2-9" \t "Überschrift 1;1;Überschrift 4;4" 1. Introduction  SEITENREF _Toc216071380 \h 5 2. Overview  SEITENREF _Toc216071381 \h 6 3. Distribution Files  SEITENREF _Toc216071382 \h 8 4. SySync DBApi SDK description  SEITENREF _Toc216071383 \h 10 4.1 How to write a database plugin ?  SEITENREF _Toc216071384 \h 10 4.2 Module Handling  SEITENREF _Toc216071385 \h 10 4.3 Session Handling  SEITENREF _Toc216071386 \h 11 4.4 Datastore Handling  SEITENREF _Toc216071387 \h 13 4.4.1 The “open” section  SEITENREF _Toc216071388 \h 13 4.4.2 The “admin read” section  SEITENREF _Toc216071389 \h 14 4.4.3 The “read” section  SEITENREF _Toc216071390 \h 14 4.4.4 The “update” section  SEITENREF _Toc216071391 \h 15 4.4.5 The “admin write” section  SEITENREF _Toc216071392 \h 16 4.4.6 The “general” section  SEITENREF _Toc216071393 \h 16 4.4.7 The “close” section  SEITENREF _Toc216071394 \h 17 4.5 Callback calls  SEITENREF _Toc216071395 \h 17 4.6 The global context  SEITENREF _Toc216071396 \h 18 4.7 The OceanBlue / SnowWhite adapter  SEITENREF _Toc216071397 \h 19 5. SySync UIApi SDK description  SEITENREF _Toc216071398 \h 20 5.1 Connecting the SyncML core library via UIApi  SEITENREF _Toc216071399 \h 20 5.2 Using a SyncML Client Library via UIApi  SEITENREF _Toc216071400 \h 21 5.2.1 Preparation for initialisation  SEITENREF _Toc216071401 \h 21 5.2.2 Engine Init  SEITENREF _Toc216071402 \h 22 5.2.3 Acessing Settings  SEITENREF _Toc216071403 \h 22 5.2.3.1 Preparations before accessing settings profiles  SEITENREF _Toc216071404 \h 23 5.2.3.2 Editing Settings  SEITENREF _Toc216071405 \h 24 5.2.4 Running Sync Sessions  SEITENREF _Toc216071406 \h 25 6. Setup Guide  SEITENREF _Toc216071407 \h 28 6.1 Plug-in System for C/C++  SEITENREF _Toc216071408 \h 28 6.2 Plug-in System for Java  SEITENREF _Toc216071409 \h 29 6.3 Plug-in System for C#  SEITENREF _Toc216071410 \h 29 6.4 Plug-in module XML configuration  SEITENREF _Toc216071411 \h 30 6.5 Module naming convention  SEITENREF _Toc216071412 \h 30 6.6 Plugin_Info program  SEITENREF _Toc216071413 \h 32 6.7 UIApi C# interface  SEITENREF _Toc216071414 \h 33 7. Change History  SEITENREF _Toc216071415 \h 34 7.1 Changes since SDK V1.0.0.2  SEITENREF _Toc216071416 \h 34 7.2 Changes since SDK V1.3.0  SEITENREF _Toc216071417 \h 35 7.3 Changes since SDK V1.4.0  SEITENREF _Toc216071418 \h 36 7.4 Changes since SDK V1.5.0  SEITENREF _Toc216071419 \h 36 8. DBApi Interface description  SEITENREF _Toc216071420 \h 37 8.1 Function overview  SEITENREF _Toc216071421 \h 37 8.2 Function Documentation  SEITENREF _Toc216071422 \h 38 9. UIApi Interface description  SEITENREF _Toc216071423 \h 53 9.1 Functions in the UI_Call_In call-in structure  SEITENREF _Toc216071424 \h 53 9.2 TEngineModuleBase Class Reference  SEITENREF _Toc216071425 \h 54 9.2.1 Public Member Function Overview  SEITENREF _Toc216071426 \h 54 9.2.2 Member Function Documentation  SEITENREF _Toc216071427 \h 56 9.3 Settings keys supported in SyncML Client Engine  SEITENREF _Toc216071428 \h 63 9.3.1 Global settings keys - accessed using OpenKeyByPath()  SEITENREF _Toc216071429 \h 63 9.3.2 Session local settings/values, accessed using OpenSessionKey()  SEITENREF _Toc216071430 \h 67 10. Error codes  SEITENREF _Toc216071431 \h 68 10.1 SyncML Status Codes  SEITENREF _Toc216071432 \h 68 10.2 Internal Error Codes  SEITENREF _Toc216071433 \h 69  Introduction Thank you for choosing Synthesis Sync Server/Client as your SyncML solution. It provides you with a very efficient compliant SyncML engine with many advanced features and especially a high configurability. Synthesis Sync Server/Client exists in different versions for different database interfaces. This manual covers Synthesis SyncML products supporting custom plugins for interfacing with the database (DB Api), like the Synthesis SyncML Servers in the PRO version as well as Synthesis SyncML library products which come as a loadable library (.dll, .so, .dylib) and have a API to access the SyncML functionality from a client application (UI Api) . Custom plugins and applications can be written in C/C++, C# and Java as well as in any programming language capable of the C-style calling conventions (e.g. Borland Delphi). This manual contains the reference for the Software Development Kit (SDK ) required to create both custom database plugins and applications. This manual does not cover configuration of the SyncML engine itself. Please refer to the  HYPERLINK "SySync_config_reference.pdf" SySync_config_reference.pdf manual which is part of the SDK package and most server product packages. Overview Synthesis AG makes their SyncML engine functionality available for customized database plug-in adapters as a Software Development Kit ( SDK ). Synthesis Plugin technology allows the customer to develop data base adapters or user interfaces without the need of understanding the details of the SyncML standard. It's an ideal division of work between Synthesis and the customer's project: Synthesis delivers a scalable, high performance SyncML OMA DS 1.2 engine, which is interoperability-tested against a huge variety of SyncML devices on the market. The customer only needs the specific knowledge to access his own data base framework or his own user interface which can be written in several programming languages. A small interface with only 48 + 23 well documented and easy-to-use functions is the bridge of interaction. All SyncML protocol details are hidden. There are mainly two sections of the SDK: The data base interface ( DBApi ) for writing data base plugins (see chapter  REF _Ref185328417 \r \h 4). The user interface ( UIApi ) for writting user interfaces (see chapter  REF _Ref216070495 \r \h 5). Both sections can be used completely independently, though some interface files are shared.  Programming interface for C/C++. A plug-in for access to Java thru JNI (Java Native Interface) is also available. The UI and DB interfaces for C# are available (since version V1.4.0). The UI and DB interfaces for Delphi are available ( since version V1.4.0). Other interfaces will be implemented on request. „Ready to use“ example code for a demo database module in C, a „textdb“ interface in C++, the OceanBlue/SnowWhite example adapter in C++ and a demo module in Java, C# and Delphi are part of the package to demonstrate the DBApi (see chapter 4). „Ready to use“ complete SyncML client examples for Mozilla sunbird calendar for Windows/Delphi, MacOSX/Cocoa/XCode and Linux/Gtk/Glide are included to demonstrate the UIApi (see chapter 5). Several small sample applications to demonstrate specific aspects of the UIApi are also available. Windows, Linux and MacOSX target platforms are supported at this time. For development, Metrowerks' CodeWarrior project files are available for all these three platforms, as well as Visual Studio 2005 vcproj file for Windows, XCode project file for Mac OSX and a makefile for Linux. Versions for Windows Mobile, SymbianOS, PalmOS, iPhone and eventually Android are planned for the future. The code can be compiled by the customer as an application for the UI application and as a Dynamic Link Library ( DLL ) for the DB Api plugins. Multiple plug-ins can be used in parallel at the same time. The SDK allows multi-threading to support multiple simultaneous sessions of the SyncML server. Easy configuration via the main XML configuration file There is no specific version of the Synthesis SyncML Server/Client with the plug-in technology, all future servers will contain it. Only the license decides, whether the functionality can be used or not. The Synthesis demo server and client contain the current version of „SDK_textdb“ as a built-in plug-in. With the SySync DBApi SDK, the customer is able to create plug-ins, which will be called directly by the Synthesis SyncML engine. The SyncML engine acts as a master: It makes subroutine calls into the plugin DLL. Each routine must return an error status, which will be handled by the engine. The main three blocks are the Module, the Session and the Datastore handling. These three blocks are normally kept within one DLL, but they can be separated into different DLLs as well. The description of each routine with several programming hints can be found in the interface definition file „sync_dbapi.h“. The access to all blocks is context based, so at the beginning a routine „Create_XXX“ will be called, which has to return a unique identifier which will be used for each subsequent call of this context. The „Delete_XXX“ will remove this context again later. Variables which are local within such a context must be stored within this environment during its lifetime. This can be done either by using the context identifier as pointer to a local structure or using it as an index. With the SySync UIApi SDK, the customer can write his own user interface and communication code (in the current version for SyncML available for client applications) and is calling the SyncML engine for initialisation, syncing, message reading/writing and parameter setup. In this configuration, the UI application is usually a program which acts as master and is using the SyncML engine as shared (or linked) library. Distribution Files The distribution media (normally a .ZIP archive) contains the following files (NOTE: depending on the version you have, not all of the listed files will be included):  The JNI / Java files can be found at:  Alternatively the same classes are available with a „sysync“ package. The equivalent files can be found in the „sysync“ sub directory. There are other subdirectories with specific projects examples for C#, Delphi, XCode (sunbird client example), .... SySync DBApi SDK description The main three blocks of the SySync Software Development Kit (SDK) are the Module, the Session and the Datastore handling. These three blocks are normally kept within one DLL, but they can be separated into different DLLs as well. The description of each routine with several programming hints can be found in the interface definition file „sync_dbapi.h“ and in chapter 7 of this manual. Here is an overwiew over the routines of these three main blocks: How to write a database plugin ? After having chosen the programming language for the plugin ( C, C++, C#, Java, Delphi ), the best starting point is to take the dbapi example and add the specific functionality. Not all functions must be implemented at all or right from the beginning, replacement can be done step by step. The calling direction is always from SyncML engine to the plugin module and returning afterwards to the SyncML engine (usually with an error code). The DBApi plugin has identical structure for SyncML servers and clients, so the same plugin module can be used on both sides. For C++ programming, a good starting point is the OceanBlue / SnowWhite adapter, see chapter  REF _Ref216070116 \r \h 4.7. It is recommended to use the callback debug output system, which is already part of all example files. So the DBApi plugin will write the flow information directly into the log file. A good starting point is the implementation and adaption of the module context which must return information of the plugin module to the engine. All basic information is already implemented at the example files. In a second phase the session context is needed for assigning user and devices, here a minimum setup for login handling is requested. The most important part is the datastore context handling where the user data will be read and written. The admin section needn’t to be implemented for every database plugin, as it can be handled by a different module as well (the config file must contain the appropriate info for this). A detailed descriptions of these context systems is described in the next chapters. Module Handling - Module_CreateContext - Module_Version - Module_Capabilities - Module_PluginParams - Module_DisposeObj *) - Module_DeleteContext *) Not implemented for JNI and C#, because Java and C# run their own garbage collection This is the set of routines for the Plug-In access on the module level. When the SyncML engine connects to a Plug-In module, „Module_CreateContext“ will be called first.When disconnecting, „Module_DeleteContext“ will be called as the final call. The SyncML engine will create a module context for the sessions and one for each datastore admin and data section. „Module_CreateContext“ can either create a new context or share a global module context among session and datastores. Module context „0“ is reserved. „Module_Version“ and „Module_Capabilities“ inform the engine, what is currently supported within the plug-in module. With „Module_PluginParams“ the SyncML engine informs the plug-in module about of the XML config file. The plugin must be able to return „Module_Version“ of context „0“ without any preceding „Module_CreateContext“. The module version cannot be defined by the plugin programmer, as it contains compatibility information for the engine. The only thing the user can define is the build number 0..255. „Module_Capabilities“ can return NoField identifiers ( example: „plugin_sessionauth:no“ ) which allows to remove some DLL functions completely, not even the entry points must be available then. This is also true for the Java environment where these methods needn’t to be implemented, if switched off. For C# all functions must be available. Supported NoField sections: - Plugin_Session „plugin_se:no“ (the whole session) - Plugin_SE_Adapt „plugin_sessionadapt:no“ (session adaptitem) - Plugin_SE_Auth „plugin_sessionauth:no“ (session login) - Plugin_DV_Admin „plugin_deviceadmin:no“ (session admin) - Plugin_DV_DBTime „plugin_dbtime:no“ (session „GetDBTime“) - Plugin_Datastore „plugin_ds:no“ (the whole datastores) - Plugin_DS_Admin „plugin_datastoreadmin:no“ (admin part) - Plugin_DS_Data „plugin_datastore:no“ (data part) - Plugin_DS_Blob „plugin_datablob:no“ (BLOB support) - Plugin_DS_Adapt „plugin_dataadapt:no“ (data adaptitem) The plugin_info program, which is part of the SDK package, shows the feedback about these informations. NOTE: The admin part requires also BLOB support for SyncML 1.2. That’s because an incomplete item during suspend/resume will be stored as BLOB. „Module_DisposeObj“ asks for deallocation of memory (which has been allocated within the module to get the capabilities string). Session Handling These routines handle the session context at a plug-in module. Main tasks of this blocks are device info & nonce handling and the user authentification (login). The return values of this block will be used later to access the datastores. NOTE: The Session_PasswordMode mode must be in line with the config file’s authentification settings. Multiple sessions can run in parallel, using the concept of multi-threading at the SyncML engine. Therefore all operations MUST refer only to the variable ( which must be created in the plug-in function „Session_CreateContext“ and deleted with „Session_DeleteContext“). The SyncML engine will never call a context again after „Session_DeleteContext“, it assumes that all allocated resources of the session are removed there. Interference between sessions should be avoided or must be made thread-safe. Even the thread of a running session can change: The SyncML engine will give a notification before such a change by calling the routine „Session_ThreadMayChangeNow“. As the name says, it may change (but it must not). If this information is not needed for the plugin module, it can be implemented empty. - Session_CreateContext - Session_AdaptItem 1) - Session_CheckDevice 2) - Session_GetNonce 2) - Session_SaveNonce 2) - Session_SaveDeviceInfo 2) - Session_GetDBTime 3) - Session_PasswordMode 4) - Session_Login 4) - Session_Logout 4) - Session_ThreadMayChangeNow - Session_DisposeObj 5) - Session_DispItems 6) - Session_DeleteContext Needn’t to be implemented with „plugin_sessionadapt:no“ at Module_Capabilities 2) These routines will be called only, if is set to yes at the config Needn’t to be implemented with „plugin_deviceadmin:no“ at Module_Capabilities 3) Needn’t to be implemented with „plugin_dbtime:no“ at Module_Capabilities 4) These routines will be called only, if is set to yes at the config Needn’t to be implemented with „plugin_sessionauth:no“ at Module_Capabilities Not implemented for JNI and C#, because Java and C# run their own garbage collection Will never be called by the SyncML engine; for debug purposes only. Datastore Handling A datastore will always be accessed within a session. Multiple datastore accesses within a session will not run sequentially, they can even run in parallel to other sessions. The datastore handling has always the same flow: open – [admin read ] - read – update – [admin write ] - close. Therefore the datastore handling is divided into several sub sections. Detailed description can be found at „sync_dbapi.h“. NOTE: For each datastore two separate contexts will be opened for the admin and the data part. This is because they can be handled by two separate plugin modules or one of them as ODBC, the other one as plugin. So they will be handled separately even if they are using the same plugin module.To distinguish which one is which, the engine can be configured (by returning „ADMIN_Info:yes“ with „Module_Capabilities“) to add the word „ ADMIN“ to of „CreateContext“ when called as admin context. The “open” section The „open“ section will „Create_Context“ and provides context and filter options to the SyncML engine. - CreateContext - ContextSupport - FilterSupport" NOTE: „ContextSupport“ and „FilterSupport“ calls will appear usually at the beginning of the data store handling, but under certain conditions they can be called at any time during the datastore handling. Multiple calls are possible. Example: FilterContext call 1: daterangestart:20070219T191809Z daterangeend:20070619T191809Z FilterContext call 2: staticfilter: dynamicfilter: invisiblefilter:F.SYNCLVL:=0|F.SYNCLVL*=E FilterContext call 1 will pass the /dr(-before/after) conditions (as ISO8601 time) to the plugin. The field names are predefined, for details see also the filter section at the Synthesis Config Reference manual. The plugin should return 2 (for 2 supported fields), if both values are supported and fully considered. It should return 0, if they are not or partly considered. E.g. a plugin might be able to filter only on date resolution, so it can make this raw prefiltering. By returning 0, the engine will make still the fine filtering. FilterContext call 2 will switch off staticfilter and dynamicfilter and will try to install the invisiblefilter. If the plugin supports invisible filtering, it should return the value 3 (for 3 supported fields). datarangestart/datarangeend are not affected with the 2nd call, so they are still active. The “admin read” section The „admin read“ section allows to handle the map tables. Detailed description can be found in „sync_dbapi.h“. All routines of this section can be implemented empty with return code DB_Forbidden = 403, if the admin tables will be handled by the SyncML engine itself. There is even a way to remove these routines completely. NOTE: For Windows, the according entry points must be removed from the „.def“ file. - LoadAdminData - ReadNextMapItem These routines will be called only, if is set to yes in the config. It needn’t to be implemented with „plugin_datastoreadmin:no“ at Module_Capabilities NOTE: Some of the Synthesis SyncML (client) engines have the admin part built-in, so it cannot be redirected to a plugin module for these cases. The “read” section The „read“ section starts with „StartDataRead“ and ends with „EndDataRead“. - StartDataRead - ReadNextItem *) - ReadNextItemAsKey *) - ReadItem *) - ReadItemAsKey *) - ReadBlob **) - EndDataRead *) Needn’t to be implemented with „plugin_datastore:no“ at Module_Capabilities **) Needn’t to be implemented with „plugin_datablob:no“ at Module_Capabilities „ReadNextItem“/ „ReadItem“: returns the data, formatted as multiline, where / are the identifiers and /
the data fields: The field separator generated by the engine is = \r\n = 0x0d 0x0a.. ( The engine is able to handle only, as well as only as separator ) aa:bbcc:dd[] The identifiers are either assigned to the fieldmap names, or just numbered by an index, if automap indexasname is true: Example: : 0:Joe1:Smith2:New York with XML config file entry: The „SDK_textdb“ sample is expecting indexasname=“true“, because the fieldmap names will not be stored, so the ordering of the config file’s fieldmap determines the index assignment. NOTE: Adding fields in-between or changing the ordering of fields will make the system incompatible to already existing TDB_*.txt files, when indexasname is true. The data fields can be multiline, so carriage returns must be escaped using „\r“, linefeeds must be escaped using „\n“. To allow this, also backslashes themselves must be escaped (using „\\“). Double quotes and ctrl characters must be escaped as well. For details see the string conversion routines at „stringutil.cpp“, which is part of the SDK package. There are two extensions to this syntax: BLOBs: For binary large object blocks the field contains only a reference to the BLOB identifier which will be read and written with ReadBlob/WriteBlob. Syntax: aa;BLOBID=xyz where is the name of the BLOB. Arrays: For array fields a syntax with index will be used Syntax: aa[index]:bb „ReadNextItemAsKey“ and „ReadItemAsKey“ are equivalent to „ReadNextItem“/ „ReadItem“, but they are using an appPointer instead of transferring the . They will be used instead by the SyncML engine, if „ITEM_AS_KEY:true“ is returned with Module_Capabilities and at least SDK 1.4.0 is used. These keys are completely opaque for the plugin module. Their attached context must be read or written with the GetValue/SetValue callback functions. The “update” section The „update“ section starts with „StartDataWrite“ and ends with „EndDataWrite“. Read commands ( ReadItem / ReadBlob ) can appear here as well. - StartDataWrite - InsertItem *) - InsertItemAsKey *) - FinalizeLocalID - UpdateItem *) - UpdateItemAsKey *) - MoveItem - DeleteItem - DeleteSyncSet - WriteBlob **) - DeleteBlob **) - EndDataWrite *) Needn’t to be implemented with „plugin_datastore:no“ at Module_Capabilities **) Needn’t to be implemented with „plugin_datablob:no“ at Module_Capabilities „InsertItemAsKey“ and „UpdateItemAsKey“ are equivalent to „InsertItem“/ „UpdateItem“, but they are using an appPointer instead of transferring the . They will be used instead by the SyncML engine, if „ITEM_AS_KEY:true“ is returned with Module_Capabilities and at least SDK 1.4.0 is used. These keys are completely opaque for the plugin module. Their attached context must be read or written with the GetValue/SetValue callback functions. NOTE: „MoveItem“ is prepared for handling hierarchical datastores. In the current version the SyncML engine has not yet implemented this feature. Therefore this function will not yet be called. For current plugin implementations LOCERR_NOTIMP (20030) can be returned. The “admin write” section The „admin write“ section allows to handle the map tables. Detailed description can be found at „sync_dbapi.h“. All routines of this section can be implemented with return code DB_Forbidden = 403, if the admin tables will be handled by the SyncML engine itself. - SaveAdminData - InsertMapItem - UpdateMapItem - DeleteMapItem These routines will be called only, if is set to yes in the config. Needn’t to be implemented with „plugin_datastoreadmin:no“ at Module_Capabilities NOTE: Some of the Synthesis SyncML (client) engines have the admin part built-in, so it cannot be redirected to a plugin module for these cases. The “general” section Some general routines are part of this section: - ThreadMayChangeNow - WriteLogData - AdaptItem *) - DisposeObj **) - DispItems ***) *) Is not yet implemented in the SyncML engine, so it will never be called. Needn’t to be implemented with „plugin_dataadapt:no“ at Module_Capabilities **) Not implemented for JNI and C#, because Java and C# run their own garbage collection ***) Will never be called by the SyncML engine; for debug purposes only. As the name says, the thread may change after „ThreadMayChangeNow“ (but it must not). If this information is not needed for the plugin module, it can be implemented empty. The “close” section The „close“ section releases the data store. The plug-in must release here all allocated memory for this datastore. All objects returned to the SyncML engine will be released with ‚DisposeObj’ prior this call. - DeleteContext No access to this context will be done after „DeleteContext“. Callback calls The Synthesis SyncML engine supports a callback mechanism, which can be used at the plug-in modules for writing comments to the log files. Logging will be done on module, session and datastore level. The user should NEVER use „printf“ or „cout“ calls, as this kind of output is not supported by all versions of the Synthesis SyncML server and will not be logged in an appropriate way. The SDK_util file provides the DEBUG_Call and the DEBUG_DB call: void DEBUG_Call( void* aCB, unsigned short debugFlags, const char* ident, const char* routine, const char* text, ... ); void DEBUG_DB ( void* aCB, const char* ident, const char* routine, const char* text, ... ); DEBUG_DB is a DEBUG_Call with = DBG_PLUGIN_DB The variable will be passed with the creation of each context (and must be stored within the context object for subsequent use). The SyncML engine will write the text to the context assigned log file. For more details see descriptions at „sync_dbapi.h“. Sometimes, very extensive logging is requested, which should not be visible in normal log files. The SyncML engine supports a flag called . Calls of DEBUG_Exotic_Call or DEBUG_Exotic_DB will be shown only, if the global "exotic" debug flag is set: void DEBUG_Exotic_Call( void* aCB, unsigned short debugFlags, const char* ident, const char* routine, const char* text, ... ); void DEBUG_Exotic_DB ( void* aCB, const char* ident, const char* routine, const char* text, ... ); DEBUG_Exotic_DB is a DEBUG_Exotic_Call with = DBG_PLUGIN_DB The log file can be structured using logical blocks. To add these structures, use DEBUG_Block / DEBUG_EndBlock as pairs. identifies such a pair. void DEBUG_Block ( void* aCB, const char* aTag, const char* aDesc, const char* aAttrText ); void DEBUG_EndBlock( void* aCB, const char* aTag ); The end of a thread can be signalled with. This information helps to create more structured logs. void DEBUG_EndThread( void* aCB ); NOTE: The underlying debug callback calls are using cb->callbackRef as first parameter, not directly. If you are using these calls directly (e.g. on language platforms where SDK_util is not available), please be aware that debug callback calls and UI callin calls are treated differently concerning this first parameter. The global context There are two main reasons to have a global context: Either 1) for some reasons no global variables are allowed within the plugin module or 2) there is a need to share some variables between different plugin modules. For both cases the SyncML engine provides a mechanism to get such a global context without the need of global variables. A structure „GlobContext“ (defined at „sysync_dbapidef.h“) will be provided at „Module_CreateContext“ thru mCB->gContext. /*! Structure of GlobContext */ typedef struct { void* ref; /* reference field */ void* next; /* reference to the next GlobContext structure */ uInt32 cnt; /* link count */ char refName[ 80 ]; /* the reference's name, length restricted */ } GlobContext; which is initially empty can be assigned any specific name of this context and should point to the desired global structure. The must be incremented by 1. The field needn’t to be handled, this will be done by the SyncML engine. mCB->gContext actually points to a linked list of GlobContext, where points to next element, as long as not NULL. In subsequent calls of „Module_CreateContext“ it can be searched for the specific name at this linked list. If available, is the desired reference. Don’t forget to increment for each assigned reference. Each module context with such a reference must decrement at „Module_DeleteContext“ again. When reaches 0, the reference structure should be deleted, then set to NULL and to „“. The SyncML engine will automatically remove such empty elements. Each plugin module can use up to 3 such GlobContexts with a different . The function „GlobContextFound“ can be used to search/assign such a GlobContext. An example for a global structure which will be used by different plugin modules is a reference to a virtual machine which only exists once per system. The Java Bridge „JNI“ is built with such a reference to the JavaVM. The OceanBlue / SnowWhite adapter For C++ an example implementation with a base class ( „OceanBlue“ ) and a derived class („SnowWhite“ ) is part of the package. „OceanBlue“ contains all interface function as virtual methods which can be overriden by the „SnowWhite“ classes. The given example implements version and capablity feedback for the module level, login for the session level and the data handling methods readnext/read/insert/update/delete with some example code. The intension is that „OceanBlue“ must not be changed, all adaptions will be done at the „SnowWhite“ module. Here is a step-by-step tutorial how to create your own database adapter. Make a copy of „snowwhite.h“ and „snowwhite.cpp“ for creating your own database adapter. Adapt the name „snowwhite“ at „myadapter.h“ to your own plugin’s name. The snowwhite sources do not contain „SnowWhite“ directly, they use MyAdapter. Adapt the build number 0..255 to return it at the Version method. The build number is a part of the version number which is completely user defined. The rest of the version number must not be changed, as it will be used for upwards/downwards compability checks of the engine. Change the name and description at the Capabilities method The SnowWhite adapter is using methods for ReadNext / Read / Insert and Update, and for Delete. The example shows in a simple way how to do this operations with static elements. Replace them by your real database access. Adapt the Login for different users. The SnowWhite login example just expects username= super and password=user (MD5 encoded) and returns the = „5678“. If you’re using the database adapter for the client side with only one user, you can implement it as dummy. Please note thate CreateContext is currently checking the returned For the client engine you don’t need an admin data implementation. For the server side, you can either configure an ODBC implementation use the INTERNAL_ADMIN implementation (using textdb way of using it) implement your own admin part by overriding the virtual admin methods For the BLOB implementation use the INTERNAL_BLOB implementation (using textdb way of using it) implement your own BLOB part by overriding the virtual BLOB methods NOTE: Suspend/Resume is using the BLOB implementation for partial items, so running the datastore with OMA DS 1.2 requires a BLOB implementation. Optionally implement now other things you need like filter support, e.g. for date ranges. The SDK contains a lot of utiltiy functions ( SDK_util / SDK_support ) which can be used by the database adapter. SySync UIApi SDK description The SySync UIApi provides core SyncML functionality in form of a library (.dll, .so, .dlib etc. depending on the platform) to create SyncML applications not only with custom specific UI but also custom specific SyncML communication layers. This is because network communication is, especially on mobile devices, tightly coupled with the UI (asking user for network to use, connection to establish, certificates to accept or deny etc.). In addition, modern operating systems all provide built-in support libraries for common communication layers like HTTP or OBEX which match platform specifics optimally. Connecting the SyncML core library via UIApi The UI Api interface is based on an interface structure with several methods in it. So as the first step, the UI application must get this UI_Call_In interface structure and the engine’s version number from the SyncML engine. There is a unified function call „ConnectEngine“: /* Main entry point when connecting engine from outside */ ENGINE_ENTRY TSyError ConnectEngine ( UI_Call_In *aCI, CVersion *aEngVersion, CVersion aPrgVersion, uInt16 aDebugFlags ) ENTRY_ATTR; NOTE: For C# „ConnectEngineS“ must be used instead. That’s beause the interface structure must be allocated within the managed environment. is the current version of this structure, as it might increase for future versions. It is allowed to use „ConnectEngineS“ (as replacement for „ConnectEngine“) also in the C/C++ environment. ENGINE_ENTRY TSyError ConnectEngineS( UI_Call_In aCI, uInt16 aCallbackVersion, CVersion *aEngVersion, CVersion aPrgVersion, uInt16 aDebugFlags ) ENTRY_ATTR; The UI_Call_In structure allows now to access to all the UI application functions (through its function pointer members). The UI_Call_In interface structure is based on the same SDK_Interface_Structure (defined at sync_dbapidef.h), which is also used by the DBApi SDK. The DBApi and UIApi share some of the functions – for example the DB_DebugXXXX functions can be called in both APIs for creating log file entries. Likewise, the GetValueXXX and SetValueXXX routines are available in both APIs. For C++, there is a wrapper class named TEngineModuleBridge is provided as part of the SDK to facilitate access; likewise, for Borland/Codegear Delphi a similar Delphi wrapper class (Delphi\sdk_sources_delphi\sysync_engine.pas) in Pascal exists. The engine version can be used for compatibility check or action. The engine itself makes some checks for compatibility with versus , so is strongly recommended to take „Plugin_Version( )“ as or the version definitions of Java or C#. The UI Api contains 3 sections: Engine Init Running Sync Sessions Settings Access For detailed information see method descriptions in „enginemodulebase.h“ The UI application must disconnect the engine at the end to make sure that all settings are stored correctly: /* Entry point for disconnecting the engine at the end */ ENGINE_ENTRY TSyError DisconnectEngine( UI_Call_In aCB ) ENTRY_ATTR; Using a SyncML Client Library via UIApi The following paragraphs describe the basic steps to take to create a SyncML client application. Details may differ depending on your actual setup. Please also refer to the fully functional sample clients provided as part of the SDK (SyncML clients for Mozilla Sunbird/Lightning as GUI applications for Windows (in Codegear Delphi Pascal), MacOSX (in XCode Cocoa/Objective C) and Linux (Glide/Gtk C++). Preparation for initialisation First, the engine library must be connected as described in  REF _Ref185308797 \r \h 5.1. Then, before actually initializing the engine with a XML configuration file, some preparations might be needed. The Synthesis SyncML engine version 3.1 and later support so-called "config variables", which can be used to embed dynamic data from the runtime environment in a config file. For example, command line arguments can be used to define path specifications in the config file (debug logs, data files...) without actually modifying the config file. Assume the config file contains a debug log directory specification as follows: $(mylogpath) To make this work, the config variable "mylogpath" must be defined before actually reading the XML config (see  HYPERLINK "SySync_config_reference.pdf" SySync_config_reference.pdf chapter "Configuration variables and conditional configuration"). In C, this will look as follows: // Assume that UI_Call_In *callInP contains the call-in structure // as returned by ConnectEngine() TSyError sta; // open the settings key that provides access to config variables appPointer keyH = NULL; // will receive the opened key's handle sta = callInP->OpenKeyByPath(callInP, &keyH, NULL, "/configvars",0); if (sta==LOCERR_OK) { // config variable settings key opened successfully // - define text mode callInP->SetTextMode(callInP, keyH, CHS_UTF8, LEM_CSTR, false); // - set the config variable's value callInP->SetValue( callInP, keyH, "mylogpath", VALTYPE_TEXT, "C:\\syncml\\logfiles", // the config var value to set -1 // automatically calculate length from null-terminated string ); // done with config variables, close settings key callInP->CloseKey(callInP,keyH); keyH=NULL; } When all config variables are defined, the engine can be initialized. Engine Init As the next step, the configuration must be provided to the SyncML engine. This can be done on three different ways. One of these ways must be chosen: the file name must be provided to the engine, so the engine can read the file directly (using InitEngineFile). the whole configuration must be presented as one contiguous data block in memory (using InitEngineXML). a callback for config reading must be given, so the engine can read it step by step (using InitEngineCB). The string mode can be chosen (using SetStringMode) prior to the engine initialisation, if default settings are not fitting, e.g. a charset which is not UTF-8 Acessing Settings There are several SyncML engine settings which can be configured from the UI application side. The settings are embedded within a tree, comparable to a directory or Windows registry tree. Setting values have therefore a path name, which must be opened first (with „OpenKeyByPath“). Then values can be read („GetValue“ / „GetValueByID“) or written ( „SetValue“ / „SetValueByID“ ). Multiple settings paths can be opened at the same time. „SetTextMode“ and „SetTimeMode“ can be defined for each context. The UI Application interface does not provide any undo functionality, so changes will usually take effect immediately (or after calling „CloseKey“). If undo is required, the UI application itself must provide this functionality. An example program „UI_app_settings.cpp“ shows how these settings can be read and written. A list of common path and key names supported for the SyncML client engine can be found in  REF _Ref207680839 \r \h 9.3. Depending on the version, special functionality and platform of the client library the available path and key names might be different from the standard set in  REF _Ref207680839 \r \h 9.3 – please refer to separate manuals for specific products. Examples for key paths are: - „/profiles“ - „/engineinfo“ Examples for „/profile“ sub entries are: - „serverURI“ - „serverPassword“ Example for „/engineinfo“ entries is: - „version“ The policy should be to close keys immediately after use, this will avoid consistency and locking problems in some cases. Some values will be stored persistently, others must be set up each time the UI application is starting. Preparations before accessing settings profiles At least one client settings profile should be present after initialisation. So it is recommended to check for an existing profile at startup of a client application and create a profile if none already exists. The following code sample shows the steps: // Still assume that UI_Call_In *callInP contains the call-in structure // as returned by ConnectEngine() // access settings to make sure a profile exists appPointer profilesKeyH=NULL, profileKeyH=NULL; // - open the profiles container sta = callInP->OpenKeyByPath(callInP,&profilesKeyH,NULL,"/profiles",0); if (sta==LOCERR_OK) { // - first check settings status. This returns an error code if // configuration data was found, but is not compatible with current // version of the engine. If so, the "overwrite" flag must be // explicitly set to force overwriting the old config with a new, // empty copy. short settingsstatus; memSize sz; sta = callInP->GetValue( callInP, profilesKeyH, "settingsstatus", VALTYPE_INT16, // we want the value as 16-bit integer (appPointer)&settingsstatus, // put value here sizeof(settingsstatus), // size of variable &sz ); if (sta!=LOCERR_OK || settingsstatus==LOCERR_CFGPARSE) { // problem with current config. // We could ask user here to preserve old config and // exit the application. For now, we just force // creation of a new config // - set "overwrite" flag to force creation of new config uInt8 overwrite=1; sta = callInP->SetValue( callInP, profilesKeyH, "overwrite", VALTYPE_INT8, &overwrite, // the config var value to set sizeof(overwrite) // size ); // - now check status again (will create new settings in the engine) sta = callInP->GetValue( callInP, profilesKeyH, "settingsstatus", VALTYPE_INT16, // we want the value as 16-bit integer (appPointer)&settingsstatus, // put value here sizeof(settingsstatus), // size of variable &sz ); } // see if at least one profile exists - if not, create default profile sta = callInP->OpenSubkey( callInP, &profileKeyH, profilesKeyH, KEYVAL_ID_FIRST, 0 ); if (sta==DB_NoContent) { // no profile exists, create default profile now sta = callInP->OpenSubkey( callInP, &profileKeyH, profilesKeyH, KEYVAL_ID_NEW_DEFAULT, 0 ); if (sta!=LOCERR_OK) { // Error, cannot create settings // You could show an user alert here exit(1); // terminate } } if (sta==LOCERR_OK && profileKeyH!=NULL) { // profile exists now callInP->CloseKey(callInP,profileKeyH); // close for now } // done with profiles for now callInP->CloseKey(callInP,profilesKeyH); } Editing Settings To provide editing of client settings, the applications must open the "/profiles" key as show above, then open one of the contained profiles. This profile contains some session-level configuration like Server URL, username, password. As a session can target more than a single datastore for synchronisation, each profile contains a "targets" container which in turn contains a key for each datastore the client supports. To identify the targets, the XML configuration file must include a numeric identifier in the tag in each section (see  HYPERLINK "SySync_config_reference.pdf" SySync_config_reference.pdf). Within the "targets" key, this identifier can be used to open the individual targets by id using OpenSubkey(). So the settings hierarchy for SyncML clients is as follows (details see  REF _Ref207680839 \r \h 9.3): "/profiles" is the container of all client settings profiles. At least one profile is required, multiple profiles can be used to maintain settings for synchronizing with more than one SyncML server. "/profiles" contains the special "settingstatus" and "overwrite" values used to check "health" of current settings, as described in  REF _Ref185318147 \r \h 5.2.3.1. Profiles within "/profiles" must be opened by using OpenSubkey(), usually by iterating over available profiles using the special KEYVAL_ID_FIRST and KEYVAL_ID_NEXT values as id. Each profile contains a number of session level settings values, like "serverURI", "serverUser" etc. - these are accessed using GetValueXXX and SetValueXXX routines. Each profile contains a "targets" container key which can be opened by OpenKeyByPath(). "targets" contains a target key for each datastore supported by the SyncML client engine (that is, those defined in the XML configuration). Each target must be opened using OpenSubKey(), using the numeric identifier specified with in the XML config for each datastore. It is also possible to iterate over all targets using the special KEYVAL_ID_FIRST and KEYVAL_ID_NEXT values as id. Each target contains a number of datastore level settings values, like "syncmode", "remotepath" etc. - these are accessed using GetValueXXX and SetValueXXX routines. When accessing these settings, make sure you don't close container keys as long as subkeys contained are still open. So usually, keys are opened in the order "/profiles", profile, "targets", target and closed in the reverse order. It is allowed to have multiple profiles or targets open at the same time, as long as the parent key remains open as well. Running Sync Sessions Running a sync session consists of three basic steps: creating a sync session using OpenSession() calling SessionStep() repeatedly in a loop until it returns STEPCMD_DONE. The return value in aStepCmd (see "engine_defs.h" for SESSIONSTEP_xxx definitions) must be checked to see when the engine has SyncML data ready to send to the SyncML server or needs an answer from the SyncML server. If so, the needed comminication with the server (http, OBEX) must take place using GetSyncMLBuffer()/RetSyncMLBuffer() or ReadSyncMLBuffer()/WriteSyncMLBuffer() routines to get or put SyncML data. For Java applications, only Read/WriteSyncMLBuffer are available. To send data to the SyncML server, the application must query the SyncML engine for the URL and content type to use by opening the session-local session key using OpenSessionKey() and querying its "connectURI" and "contenttype" values. The communication channel can be held open between calls to SessionStep() until STEPCMD_RESTART is returned in aStepCmd. Each call to SessionStep() returns a record of TEngineProgressInfo type, which indicates progress of the sync session. The information in this record is useful to show progress in the UI of the application. See "engine_defs.h" for progress event PEV_XXX definitions. closing the sync session using CloseSession() The following C code skeleton shows the basic implementation required to run a sync session: // Assume that UI_Call_In *callInP contains the call-in structure // as returned by ConnectEngine() // run a sync session // - variables TEngineProgressInfo progressInfo; appPointer sessionH = NULL; TSyError sta; uInt16 stepCmd = STEPCMD_CLIENTSTART; // first step const memSize textbuffersize = 300; memSize textsize; char textbuffer[textbuffersize]; // - create a session sta = callInP->OpenSession(callInP,&sessionH,0,"mySyncSession"); if (sta!=LOCERR_OK) { // error, exit exit(1); } // sync main loop do { // take next step sta = callInP->SessionStep(callInP,sessionH,&stepCmd,&progressInfo); if (sta!=LOCERR_OK) { // error, terminate with error stepCmd=STEPCMD_ERROR; } else { // step ran ok, evaluate step command switch (stepCmd) { case STEPCMD_OK: // no progress info, call step again stepCmd = STEPCMD_STEP; break; case STEPCMD_PROGRESS: // new progress info to show // Check special case of interactive display alert if (progressInfo.eventtype==PEV_DISPLAY100) { // alert 100 received from remote, message text is in // SessionKey's "displayalert" field appPointer sessionKeyH; sta = callInP->OpenSessionKey(callInP,sessionH,&sessionKeyH,0); if (sta==LOCERR_OK) { // get message from server to display callInP->GetValue( callInP, sessionKeyH, "displayalert", VALTYPE_TEXT, // we want the value as 16-bit integer (appPointer)&textbuffer, // put value here textbuffersize, // size of variable &textsize ); // tbd: display message to user callInP->CloseKey(callInP,sessionH); } } else { // normal progress info // tbd: show progress in the UI } stepCmd = STEPCMD_STEP; break; case STEPCMD_ERROR: // error, terminate (should not happen, as status is // already checked above) break; case STEPCMD_RESTART: // make sure connection is closed and will be re-opened for next request // tbd: close communication channel if still open to make sure it is // re-opened for the next request stepCmd = STEPCMD_STEP; break; case STEPCMD_SENDDATA: // send data to remote // tbd: use OpenSessionKey() and GetValue() to retrieve "connectURI" // and "contenttype" to be used to send data to the server // tbd: use GetSyncMLBuffer()/RetSyncMLBuffer() to access the data to be // sent or have it copied into caller's buffer using // ReadSyncMLBuffer(), then send it to the server // status for next step if (true) /* tbd: check if communication with server successful */ stepCmd = STEPCMD_SENTDATA; // we have sent the request data else stepCmd = STEPCMD_TRANSPFAIL; // communication with server failed break; case STEPCMD_NEEDDATA: // tbd: wait for receiving answer from server // tbd: put answer received into SyncML engine's buffer, either by // directly accessing it using GetSyncMLBuffer()/RetSyncMLBuffer() // or by copying it with WriteSyncMLBuffer(). // status for next step if (true) /* tbd: check if communication with server successful */ stepCmd = STEPCMD_GOTDATA; // we have received response data else stepCmd = STEPCMD_TRANSPFAIL; // communication with server failed break; } // switch stepcmd } // check for suspend or abort, if so, modify step command for next step if (false /* tdb: check if user requests suspending the session */) { stepCmd = STEPCMD_SUSPEND; } if (false /* tdb: check if user requests aborting the session */) { stepCmd = STEPCMD_ABORT; } // loop until session done or aborted with error } while (stepCmd!=STEPCMD_DONE && stepCmd!=STEPCMD_ERROR); // done, now close the SyncML session sta = callInP->CloseSession(callInP,sessionH); SessionStep() is designed to keep execution time as short as possible, such that implementing a responsive SyncML client is possible without using a separate thread. The code skeleton above can be integrated in a GUI application main loop to allow processing SyncML, showing progress in the UI and responding to user's requests (like pressing an abort button) in parallel. NOTE: It’s recommend (on Windows systems) to initialize the network access before opening the session for the first time. That’s because the information will be taken from network information, if available. Setup Guide This setup guide consists of two main sections: Section  REF _Ref43725462 \r \h  \* FORMATVERBINDEN 6.1 describes the installation of the C/C++ interface, Section  REF _Ref150068798 \r \h 6.2 describes the usage of the JNI interface for Java. We recommend, that if you are new to Synthesis SyncML Server/Client, start testing with the standalone version as you have immediate visible feedback on the console screen. If everything is working fine, then you can easily switch to the ISAPI or Apache version. For installation of the ISAPI or Apache version see the description of „SySync_Server_manual“. Plug-in System for C/C++ Metrowerks CodeWarrior project files ( .mcp) are part of the SDK delivery for Windows, Linux and MacOSX, as well as the compiled shared libraries. The examples are based on CodeWarrior V8.X for Windows and V9.X for MacOSX. For Windows alternatively Visual Studio 2005 can be used. Ready-to-use *.vcproj files are part of the SDK package. For Linux, a generated makefile „Sysync_SDK_linux.mk“ is part of delivery as well and can be used directly by calling „make“: make –f Sysync_SDK_linux.mk. For MacOSX XCode can be used to create Universal Binaries which are working on PPC and X86 architectures. Three plug-in modules (a simple demo module in pure „C“ , a text DB module in „C++“ and a module for adapting items) can be compiled and linked directly. Result will be the three shared library modules „SDK_demodb“ , „SDK_textdb“ and „adaptitem“. .dll for Windows, .so for Linux, .dylib for MacOSX Standard C example: The „SDK_demodb“ is just printing a debug message for each routine. This can be a good and helpful starting point to implement routine by routine. Writing debug messages is done thru the callback mechanism of the SyncML engine, using the „Debug_DB“ call. The debug messages will be stored in the SyncML engine’s log files. Don’t use „printf“ calls, as not all versions of the Synthesis SyncML server are able to create such kind of output. C++ example: The „SDK_textdb“ is a text DB interface, which acts the same way as the so called Synthesis SyncML demo server. This module can be a starting point when it’s easier to adapt from an already running system. Plugin parameters , and are supported. NOTE: The CurrentTime() function used at „Session_GetDBtime“ and „StartDataRead“ is implemented very rudimentary. For a good implementation, this function should be replaced by an enhanced version. The example configuration „syncserv_odbc.xml“ is set up to access the „SDK_textdb“ directly by default. is configured for „SDK_textdb“ on session and datastore level. The admin tables of the „SDK_textdb“ will be used. For Linux and MacOSX „LD_LIBRARY_PATH“ must be set in order to access these plugin library modules. Plug-in System for Java The Java Virtual Machine V1.4 or higher must be correctly installed. For Linux and MacOSX „LD_LIBRARY_PATH“ must be set to access the JavaVM, e.g. at “/usr/java/jre/lib/i386/client“ or „/usr/java/jre/lib/i386/server“. For MacOSX this is normally „/system/Library/Frameworks/JavaVM.frameworks/Libraries“. There is a Java example „SDK_javadb.java“ and its compiled classes (which have been created with „javac SDK_javadb.java“). The SDK class can also be within a Java package: A package example (named „sysync“) can be found in the subdirectory „sysync“. The functionality of the package sample is identical to the one on the top level. A package can be accessed by adding the package name, separated by a space. JavaVM options can be added after the class and package name. Examples: [JNI!SDK_javadb sysync] [JNI!SDK_javadb sysync –verbose:jni] The SyncML engine (PRO version only) has a built-in plug-in module for the JNI handling. The identical plug-in is also available in compiled form as shared library „JNI.dll“ for test purposes (but not as part of the SDK). For an operative environment, this external plug-in will not be used, because the internal JNI is the preferred solution. For UI applications, written in Java, the engine connection will be done with a „ConnectEngine“ call, which then provides access to all the UI application specific functions. A simple sample program how to use the interface is part of the SDK: uiapp.java Example: java –cp . uiapp.java Plug-in System for C# Will be accessed via GUID. There is a common GUID for the interface (which shouldn’t be changed and a class specific GUID. The class specific GUID will be expected as subname at the config file. GUIDs must be registered to the system using „regasm“. regasm dbapi_csharp.dll /tlb: dbapi_csharp.tlb Example: CSHARP!348330a6-c7ee-4ba4-888b-39250cb31db1" Plug-in module XML configuration Plug-in modules must be activated at the XML configuration file. This can be done for the session and/or each datastore separately. It is even possible to use different plug-ins for the session and each datastore. For the session, must be set. The must be set to the plug-in name, e.g. SDK_textdb As there are built-in modules and external modules, the syntax for internal plug-ins is using brackets. Example: - Internal demo plug-in: [SDK_demodb] - Shared library for demo plug-in: SDK_demodb Built-in means, that the plug-in is compiled and statically linked to the SyncML engine. Only Synthesis can create built-in modules; the SDK user can only create external modules as shared libraries. „SDK_demodb“ and „SDK_textdb“ are available both as built-in and as external modules. The PRO version of the Synthesis server contains the JNI as built-in plug-in module. For system performance, there is no measurable difference between internal / external modules. By default, the SyncML engine doesn’t use authentification and device administration of the plug-in module. They must be switched on in the configuration. To use the login part of the plug-in, yes must be set. To use the admin part of the plug-in, yes is required. For the datastore access, must be set, where the NAME is e.g. „contacts“. The must be set the same way as for the session. If is active on session level, it will be used for each datastore as well. Module naming convention The Synthesis SyncML plug-in modules will used with the following naming convention: name A shared library „name.dll“ ( or „name.so“ for Linux ) must exist in the search path of the system. The SyncML engine will create an error 20010, if the library does not exist. „name“ can consist of a main module name and sub module names, e.g. „aaa!bbb“, where ‚aaa’ is the name of the library ( „aaa.dll“ ) and ‚bbb’ is a local name for the plug-in module. This concept allows to build cascades or hierarchies of plug-ins, where the sub module name is given to the next plug-in module. „aaa!bbb!ccc“ is an example for a plug-in with a two level sub system. Example: The bridge to Java The Java plug-in is an example of such a sub system: The syntax for the SDK sample must be: JNI!SDK_javadb Here we have a plug-in called „JNI.dll“ which is the bridge between the SyncML engine (written in C++) and the the Java plug-in (SDK_javadb) with the static class „SDK_javadb“. Error 20034 will be returned, if the sub system is not available. For Java, the CLASSPATH can be included directly as well. As an example for a classpath at „C:\java_files“, the Java Virtual Machine will be attached correctly with: [JNI!C:\java_files\SDK_javadb] NOTE: SDK V1.3.8.X and later allow to connect more than one Java class with a given class-path and package name for different plugin sections, however the VM options are the same and will be shared among all Java plugins. The options of the first connecting context (usually the session context) will considered, options of other sections will be ignored. NOTE: The plugin module names are case sensitive in some cases, e.g. in Java environment. C# database adapters are using a GUID as sub system name: Example: C# bridge CSHARP!348330a6-c7ee-4ba4-888b-39250cb31db1" Plugin_Info program A utility program for testing plugin modules independently is part of the SDK. It returns some version and identification info about a plugin: Example: plugin_info –p SDK_textdb Synthesis Plugin_Info Tool V1.5.2.0 Name : SDK_textdb Version : V1.5.2.0 ... at least : V1.5.1.0 required as engine's SDK version Version : V1.5.2.0 Manufacturer : Synthesis AG Description : Text database module. Writes data directly to TDB_*.txt file Platform : Windows (CodeWarrior) (DLL) GlobContext : 0014AAB0 (00159868 'TextDB') plugin_sessionauth : yes plugin_deviceadmin : yes plugin_datastoreadmin : yes plugin_datastore : yes plugin_dataadapt : yes ADMIN_Info : yes Session context : available (0015C1F0) Datastore context (admin) : available (0015C280) Datastore context (data) : available (0015CF58) Example: plugin_info –p “[JNI!SDK-javadb sysync]“ Synthesis Plugin_Info Tool V1.5.2.0 Name : [JNI!SDK_javadb sysync] Version : V1.5.2.0 ... at least : V1.5.1.0 required as engine's SDK version Name : JNI Version : V1.5.2.0 Manufacturer : Synthesis AG Description : JNI bridge to Java Platform : Windows (CodeWarrior) (LIB) GlobContext : 0014B130 (00145158 'JNI') sub system ---------- Name : SDK_javadb sysync Version : V1.5.2.0 Manufacturer : Synthesis AG Description : Java Example Module (package) Platform : Java plugin_sessionauth : yes plugin_deviceadmin : yes plugin_datastoreadmin : yes plugin_datastore : yes plugin_dataadapt : yes ADMIN_Info : yes Session context : available (0014C1B8) Datastore context (admin) : available (0014C430) Datastore context (data) : available (0014C6B8) The program allows to get some debug information (with options –d and –e) as well as forcing any desired engine SDK version other than the current version for test (option –v). For Linux and MacOSX „LD_LIBRARY_PATH“ must be set in order to access these plugin library modules. UIApi C# interface For C# there exists an equivalent SDK interface to the UI functions of the engine. The usage of the functions is identical, they are implemented via delegate marshal calls. The interface definition can be found in the program.cs example of the SDK package. „ConnectEngineS“ and „DisconnectEngine“ are implemented as DLL calls. The difference to the function „ConnectEngine“ is, that the SDK_Interface_Struct will allocated on the C# side; will be needed additionally. class Program { const String DllName = "syncclient_test.dll"; static debug_calls d = new debug_calls(); static uiapp_calls u = new uiapp_calls(); // ... // ---------------------------------------------------------------------------------- [DllImport(DllName)] public static extern TSyError ConnectEngineS ( ref SDK_Interface_Struct aCB, UInt16 aCallbackVersion, ref UInt32 aEngVersion, UInt32 aPrgVersion, UInt16 aDebugFlags ); [DllImport(DllName)] public static extern TSyError DisconnectEngine( ref SDK_Interface_Struct aCB ); // ... } As an example, the „InitEngineXML“ call is shown below. The whole UI call in is implemented as class „uiapp_calls“ at „sysync_uiapp_calls“ as part of the SDK package. public class uiapp_calls { // The method prototype definitions ... delegate TSyError InitEngineXML_Func ( ref SDK_Interface_Struct aCB, String aConfigXML ); // ... and the marshal calls public TSyError InitEngineXML( ref SDK_Interface_Struct aCB, String aConfigXML ) { IntPtr ip= aCB.InitEngineXML; InitEngineXML_Func v= (InitEngineXML_Func)Marshal.GetDelegateForFunctionPointer( ip, typeof(InitEngineXML_Func) ); return v( ref aCB, aConfigXML ); } // InitEngineXML // ... } Change History Changes since SDK V1.0.0.2 For customers who have started to implement a plug-in with SDK V1.0.0.2, some adaptions must be made to make it conformant to SDK V1.3.8.X. Best way to do this, is to install this new SDK package and adapt the plug-in’s c/cpp or java files. The SyncML engine is written to be downwards compatible for all these features, so it will run correctly with all versions, as long as the „Plugin_Version“ of SDK_util will return the correct version number, so this version number MUST NOT be changed ( except for the customer defined build number, which represents the last digit 0..255 of the version number ). Upwards compatibility ( SDK version newer than engine ) are covered partly, because an older engine cannot handle cases of changed parameter lists or no longer existing functions or methods. However the engine informs the plugin about its version (NOTE: this is not SyncML server’s / client’s version, e.g. V2.1.1.28, but the plugin interface version, e.g. V1.5.2.0). Additionally the plugin returns (with „Module_Capabilities“ ) the minimum required version. The server automatically stops then with an error 20033 if the this build is too old for this SDK/plugin. The following things MUST BE CHANGED: Module_PluginParams: Has now a new additional parameter (to inform the plug-in about its version) Callback calls: Up to callbackVersion = 5 is now supported, see structure definition at „sync_dbapidef.h“. Hierarchical logs and exotic output are supported now. Boolean alignment problems are fixed. DeleteBlob: New function added ( allows consistent BLOB handling now ) Session_AdaptItem, New functions added, these function will allow the manipulation AdaptItem: of variables of the script context ( They are not yet supported by the SyncML engine, but the implementation is prepared now ). InsertMapItem: New function added, no longer combined with „UpdateMapItem“ MapID: The MapID struct contains a new element uInt8 ident.. It will be used to store the status of Suspend/Resume of OMA DS 1.2. Build numbers: System has changed from V1.0.N.2, where „N“ was the platform identifier, to V1.3.8.X, where „X“ is a customer defined build number. StartDataRead: Has now a new additional parameter for OMA DS 1.2 support ( Suspend/Resume ). Session_GetDBTime: New function added ( returns the database’s time, if available ) DB_Full: Definition has been changed from 520 to 420. DBG_PLUGIN_XXX: A separate flag system (with 16 flags) for the plugin debug logging has been introduced. Bits 0 and 1 are defined and reserved. DEBUG_Exotic: Has been separated into DEBUG_Exotic_Call and DEBUG_Exotic_DB. Session_Login (Java only): Parameter „String sPwd“ has been changed to „VAR_String sPwd“, to allow the usage of all password modes. Changes since SDK V1.3.0 JCallback (Java only): The callback functions are now using as 1st return parameter. This solves a problem with using Java packages. Example: public native void DebugDB( int thisCB, String aTxt ); Module_Capabilites: „ADMIN_Info“ will be considered now, it adds the identifier „ADMIN“ to at admin’s „CreateContext“. FilterContext: Is supported by the SyncML engine for SDK version >= V1.3.8. Callback calls: Up to callbackVersion = 8 is now supported, see structure definition at „sync_dbapidef.h“. UI Api: Is supported by the SyncML engine for SDK version >= V1.4.0 callbackVersion = 8 with the UI interface functions will be used. DatastoreContext: 4 additional functions „*AsKey“ have been added. They allow an handling instead of using . Is supported by the SyncML engine for SDK version >= V1.4.0 SDK_Interface_Structure: is the new name of the former „DB_Callback_Structure“. Two (equivalent) pointer types for this structure are defined now: The already existing „DB_Callback“ for the DBApi SDK and „UI_Call_In“ for the UIApi SDK. Changes since SDK V1.4.0 C# (dbapi) DebugDB and other callback calls can log now to the engine’s log file directly: „sysync_debug_calls.cs“ is part of the SDK now. [MarshalAs(UnmanagedType.LPWStr)] will be used now for all string parameters (instead of LPStr), the SyncML engine will make the conversion from/to UTF-8 internally. The new files „dbapi_interface.cs“ and „sysync_debug_calls.cs“ (with the LPWStr defs) must be used. C# (uiapp) The UI call in methods have changed from direct DLL calls to marshalled delegate calls: „sysync_uiapp_calls.cs“ is part of the SDK now. C# ConnectEngineS Must be used instead of „ConnectEngine“ now. InsertItem DB Plugin may return a DB_DataMerged (207) error which informs the engine about an already existing item which has been updated now. The engine will read this item again to keep track of this update (either in the same or the next session). NOTE: This feature is supported for server only. Callback calls: Up to callbackVersion = 9 is now supported, see structure definition at „sync_dbapidef.h“. FinalizeLocalID: New function has been added to replace a temporary ID sion by its final ID at the end of the session. The function can return LOCERR_NOTIMP, if not needed. DeleteSyncSet:: All elements of the sync set will be removed. If the function returns LOCERR_NOTIMP, the engine will remove element by element. Changes since SDK V1.5.0 GlobContext „GlobContext“ extended for multi module usage SDK_textdb example Adapted for GlobContext use Callback calls: Up to callbackVersion = 11 is now supported, see structure definition at „sync_dbapidef.h“. OceanBlue/SnowWhite C++ example added SDK_textdb example NID_* file has been added, containing a persistent new ID for inserted items. For more details of the SDK change history see „sync_dbapidef.h“. DBApi Interface description Function overview TSyError Module_CreateContext (CContext *mContext, cAppCharP moduleName, cAppCharP subName, cAppCharP mContextName, DB_Callback mCB) CVersion Module_Version (CContext mContext) TSyError Module_Capabilities (CContext mContext, appCharP *mCapabilities) TSyError Module_PluginParams (CContext mContext, cAppCharP mConfigParams, CVersion engineVersion) void Module_DisposeObj (CContext mContext, void *memory) TSyError Module_DeleteContext (CContext mContext) TSyError Session_CreateContext (CContext *sContext, cAppCharP sessionName, DB_Callback sCB) TSyError Session_AdaptItem (CContext sContext, appCharP *sItemData1, appCharP *sItemData2, appCharP *sLocalVars, uInt32 sIdentifier) TSyError Session_CheckDevice (CContext sContext, cAppCharP aDeviceID, appCharP *sDevKey, appCharP *nonce) TSyError Session_GetNonce (CContext sContext, appCharP *nonce) TSyError Session_SaveNonce (CContext sContext, cAppCharP nonce) TSyError Session_SaveDeviceInfo (CContext sContext, cAppCharP aDeviceInfo) TSyError Session_GetDBTime (CContext sContext, appCharP *currentDBTime) sInt32 Session_PasswordMode (CContext sContext) TSyError Session_Login (CContext sContext, cAppCharP sUsername, appCharP *sPassword, appCharP *sUsrKey) TSyError Session_Logout (CContext sContext) void Session_DisposeObj (CContext sContext, void *memory) void Session_ThreadMayChangeNow (CContext sContext) void Session_DispItems (CContext sContext, bool allFields, cAppCharP specificItem) TSyError Session_DeleteContext (CContext sContext) TSyError CreateContext (CContext *aContext, cAppCharP aContextName, DB_Callback aCB, cAppCharP sDevKey, cAppCharP sUsrKey) uInt32 ContextSupport (CContext aContext, cAppCharP aContextRules) uInt32 FilterSupport (CContext aContext, cAppCharP aFilterRules) TSyError LoadAdminData (CContext aContext, cAppCharP aLocalDB, cAppCharP aRemoteDB, appCharP *adminData) TSyError SaveAdminData (CContext aContext, cAppCharP adminData) bool ReadNextMapItem (CContext aContext, MapID mID, bool aFirst) TSyError InsertMapItem (CContext aContext, MapID mID) TSyError UpdateMapItem (CContext aContext, MapID mID) TSyError DeleteMapItem (CContext aContext, MapID mID) void DisposeObj (CContext aContext, void *memory) void ThreadMayChangeNow (CContext aContext) void WriteLogData (CContext aContext, cAppCharP logData) void DispItems (CContext aContext, bool allFields, cAppCharP specificItem) TSyError AdaptItem (CContext aContext, appCharP *aItemData1, appCharP *aItemData2, appCharP *aLocalVars, uInt32 aIdentifier) TSyError StartDataRead (CContext aContext, cAppCharP lastToken, cAppCharP resumeToken) TSyError ReadNextItem (CContext aContext, ItemID aID, appCharP *aItemData, sInt32 *aStatus, bool aFirst) TSyError ReadNextItemAsKey (CContext aContext, ItemID aID, appPointer aItemKey, sInt32 *aStatus, bool aFirst) TSyError ReadItem (CContext aContext, ItemID aID, appCharP *aItemData) TSyError ReadItemAsKey (CContext aContext, const ItemID aID, appPointer aItemKey) TSyError ReadBlob (CContext aContext, const ItemID aID, cAppCharP aBlobID, void **aBlkPtr, unsigned long *aBlkSize, unsigned long *aTotSize, bool aFirst, bool *aLast) TSyError EndDataRead (CContext aContext) TSyError StartDataWrite (CContext aContext) TSyError InsertItem (CContext aContext, cAppCharP aItemData, ItemID newID) TSyError InsertItemAsKey (CContext aContext, appPointer aItemKey, ItemID newID) TSyError FinalizeLocalID (CContext aContext, const ItemID aID, ItemID updID) TSyError UpdateItem (CContext aContext, cAppCharP aItemData, const ItemID aID, ItemID updID) TSyError UpdateItemAsKey (CContext aContext, appPointer aItemKey, const ItemID aID, ItemID updID) TSyError MoveItem (CContext aContext, const ItemID aID, cAppCharP newParentID) TSyError DeleteItem (CContext aContext, const ItemID aID) TSyError DeleteSyncSet (CContext aContext) TSyError WriteBlob (CContext aContext, const ItemID aID, cAppCharP aBlobID, void *aBlkPtr, unsigned long aBlkSize, unsigned long aTotSize, bool aFirst, bool aLast) TSyError DeleteBlob (CContext aContext, const ItemID aID, cAppCharP aBlobID) TSyError EndDataWrite (CContext aContext, bool success, appCharP *newToken) TSyError DeleteContext (CContext aContext) Function Documentation XE "AdaptItem:sync_dbapi.h"XE "sync_dbapi.h:AdaptItem"_ENTRY_ TSyError AdaptItem (CContext aContext, appCharP * aItemData1, appCharP * aItemData2, appCharP * aLocalVars, uInt32 aIdentifier) This function adapts aItemData Parameters: The datastore context The 1st item's data The 2nd item's data The local vars To identify, where it is called Returns: error code NOTE: The memory for adapted strings must be allocated locally. The SyncML engine will call 'DisposeObj' later, to release again its memory. One or more strings can be returned unchanged as well. XE "ContextSupport:sync_dbapi.h"XE "sync_dbapi.h:ContextSupport"_ENTRY_ uInt32 ContextSupport (CContext aContext, cAppCharP aSupportRules) This function asks for specific context configurations Parameters: The datastore context The SyncML sends a list of support rules. This function has to reply, up to which rule, contexts are supported (and switched on now). Data is formatted as multiline aa:bbcc:dd[] Returns: Up to fields are supported (and switched on) for this context. If 0 will be returned, no field of is supported. XE "CreateContext:sync_dbapi.h"XE "sync_dbapi.h:CreateContext"_ENTRY_ TSyError CreateContext (CContext * aContext, cAppCharP aContextName, DB_Callback aCB, cAppCharP sDevKey, cAppCharP sUsrKey) This routine is called to create a new context for a datastore access. It must allocate all resources for this context and initialize the parameter with a value that allows re-identifying the context. can either be a pointer to the local context structure or any key value which allows to re-identify the context later. Subsequent calls related to this context will pass the value as returned from CreateContext. The context must be valid until 'DeleteContext' is called. can be defined individually. NOTE: The SyncML engine treats simply as a key. The only condition is uniqueness for all datastore contexts. Even = 0 can be used. Parameters: Returns a value, which allows to identify this datastore context. Allows to identify the context, if more than one must be handled. is defined at the XML configuration. DB_Callback structure for datatstore logging. The result of 'Session_CheckDevice' comes in here. The result of 'Session_Login' comes in here. Returns: error code, if context could not be created (e.g. not enough memory), 0 if context successfully created. XE "DeleteBlob:sync_dbapi.h"XE "sync_dbapi.h:DeleteBlob"_ENTRY_ TSyError DeleteBlob (CContext aContext, const ItemID aID, cAppCharP aBlobID) This routine deletes the specific binary logic block at the database. Parameters: The datastore context. ItemID ( with , ). The assigned ID of the blob. Returns: error code, if not ok ( e.g. invalid , ) XE "DeleteContext:sync_dbapi.h"XE "sync_dbapi.h:DeleteContext"_ENTRY_ TSyError DeleteContext (CContext aContext) This routine is called to delete a context, that was previously created with 'CreateContext'. The DB Module must free all resources related to this context. No calls with will be done after calling this routine, so the assigned structure, allocated at 'CreateContext' can be released here. Parameters: The datastore context. Returns: error code, if context could not be deleted ( e.g. not existing ). XE "DeleteItem:sync_dbapi.h"XE "sync_dbapi.h:DeleteItem"_ENTRY_ TSyError DeleteItem (CContext aContext, const ItemID aID) This routine deletes a dataset from the database Parameters: The datastore context. ItemID ( with , ) to be deleted. Returns: error code LOCERR_OK ( =0 ), if successful DB_NotFound ( =404 ), if unknown ... or any other SyncML error code, see Reference Manual XE "DeleteMapItem:sync_dbapi.h"XE "sync_dbapi.h:DeleteMapItem"_ENTRY_ TSyError DeleteMapItem (CContext aContext, MapID mID) Map table handling: Delete a map item of this context Parameters: The datastore context MapID ( with , and ). Returns: error code, if this MapID can't be deleted, or if this MapID does not exist. USED ONLY WITH XE "DeleteSyncSet:sync_dbapi.h"XE "sync_dbapi.h:DeleteSyncSet"_ENTRY_ TSyError DeleteSyncSet (CContext aContext) This routine deletes all datasets from the database Parameters: The datastore context. Returns: error code LOCERR_OK ( =0 ), if successful LOCERR_NOTIMP ( =20030 ). For this case, the engine removes all items directly ... or any other SyncML error code, see Reference Manual XE "DispItems:sync_dbapi.h"XE "sync_dbapi.h:DispItems"_ENTRY_ void DispItems (CContext aContext, bool allFields, cAppCharP specificItem) Writes the context of all items to dbg output path This routine is implemented for debug purposes only and will NOT BE CALLED by the SyncML engine. Can be implemented empty, if not needed. Parameters: The datastore context. true : all fields, also empty ones, will be displayed; false: only fields <> "" will be shown "" : all items will be shown; else : shows the Returns: - XE "DisposeObj:sync_dbapi.h"XE "sync_dbapi.h:DisposeObj"_ENTRY_ void DisposeObj (CContext aContext, void * memory) Disposes memory, which has been allocated within the datastore context. 'DisposeObj' can occur at any time within . Parameters: The datastore context. Dispose allocated memory. Returns: - XE "EndDataRead:sync_dbapi.h"XE "sync_dbapi.h:EndDataRead"_ENTRY_ TSyError EndDataRead (CContext aContext) This routine terminates the read from database phase It can be used e.g. for termination of a transaction. In standard case it can be implemented empty, returning simply a value LOCERR_OK = 0. Parameters: The datastore context. Returns: error code XE "EndDataWrite:sync_dbapi.h"XE "sync_dbapi.h:EndDataWrite"_ENTRY_ TSyError EndDataWrite (CContext aContext, bool success, appCharP * newToken) Advises the database to finsish the running transaction Parameters: The datastore context. true: All former actions were successful, so the database can commit false: The transaction was not successful, so the database may rollback or ignore the transaction. An internally generated string value, which will be used to identify changed database records. It is normally an ISO8601 formatted string, which represents the module's current time (at the time the 'StartDataRead' of this context has been called). All changed records of the currrent context must get this token as timestamp as as well. The SyncML engine will return this value with the 'StartDataRead' call within the next session. It must return NULL in case of no . Returns: error code, if operation can't be performed. No is not an error. NOTE: By default, the SyncML engine expects an ISO8601 string for . But the SyncML engine can be configured to treat this value completely opaque, if implemented in a different way. The must be allocated locally and will be disposed with a 'DisposeObj' call later by the SyncML engine. XE "FilterSupport:sync_dbapi.h"XE "sync_dbapi.h:FilterSupport"_ENTRY_ uInt32 FilterSupport (CContext aContext, cAppCharP aFilterRules) This function asks for filter support. Parameters: The datastore context The SyncML sends a list of filter rules. This function has to reply, up to which rule, filters are supported (and switched on now). Data is formatted as multiline aa:bbcc:dd[] Returns: Up to filters are supported (and switched on) for this context If 0 will be returned, no field of are supported. XE "FinalizeLocalID:sync_dbapi.h"XE "sync_dbapi.h:FinalizeLocalID"_ENTRY_ TSyError FinalizeLocalID (CContext aContext, const ItemID aID, ItemID updID) This routine updates a temporary to an at the end For cached systems which assign IDs at the end of a run. Parameters: The datastore context. Database key of dataset to be updated Input: NULL is assigned as default value to and . Output: The updated database key for . Can be NULL, if the same as Returns: error code LOCERR_OK ( =0 ), if successful DB_Forbidden ( =403 ), if can't be resolved DB_NotFound ( =404 ), if unknown LOCERR_NOTIMP ( =20030 ), if no finalizing is needed at all ... or any other SyncML error code, see Reference Manual NOTE: must either contain NULL references ( if the same as ), or the memory for must be allocated locally. The SyncML engine will call 'DisposeObj' later for to release the memory. should be always NULL. XE "InsertItem:sync_dbapi.h"XE "sync_dbapi.h:InsertItem"_ENTRY_ TSyError InsertItem (CContext aContext, cAppCharP aItemData, ItemID aID) This routine inserts a new dataset to the database. The assigned new ItemID will be returned. Parameters: The datastore context. The data, formatted as multiline aa:bbcc:dd[] Database key of the new dataset. Returns: error code LOCERR_OK ( =0 ), if successful DB_DataMerged ( =207 ), if successful, but "ReadItem" requested to inform about updates DB_Forbidden ( =403 ), if can't be resolved DB_Full ( =420 ), if not enough space in the DB ... or any other SyncML error code, see Reference Manual NOTE: The memory for must be allocated locally. The SyncML engine will call 'DisposeObj' later for , to release the memory XE "InsertItemAsKey:sync_dbapi.h"XE "sync_dbapi.h:InsertItemAsKey"_ENTRY_ TSyError InsertItemAsKey (CContext aContext, appPointer aItemKey, ItemID aID) XE "InsertMapItem:sync_dbapi.h"XE "sync_dbapi.h:InsertMapItem"_ENTRY_ TSyError InsertMapItem (CContext aContext, MapID mID) Map table handling: Insert a map item of this context Parameters: The datastore context MapID ( with , and ). A new item with will be added. Returns: error code, if this MapID can't be inserted, or if already existing USED ONLY WITH XE "LoadAdminData:sync_dbapi.h"XE "sync_dbapi.h:LoadAdminData"_ENTRY_ TSyError LoadAdminData (CContext aContext, cAppCharP aLocalDB, cAppCharP aRemoteDB, appCharP * adminData) This function gets the stored information about the record with the four paramters: , , , . yes: Admin/Map routines will be used. Parameters: The datastore context Name of the local DB Name of the remote DB The data, saved with the last 'SaveAdminData' call Returns: error code 404 (NotFound), if record is not (yet) available, 0 (no error) if admin data found NOTE: and have been passed with 'CreateContext' already. The plug-in module must have stored them within the datastore context. USED ONLY WITH XE "Module_Capabilities:sync_dbapi.h"XE "sync_dbapi.h:Module_Capabilities"_ENTRY_ TSyError Module_Capabilities (CContext mContext, appCharP * mCapabilities) Get the module's capabilities Currently the SyncML engine currently understands and supports: "plugin_sessionauth" "plugin_deviceadmin" "plugin_datastoreadmin" "plugin_datastore" If one of these identifiers will be defined as "no" ( e.g. "plugin_sessionauth:no" ), the according routines will not be connected and used. NOTE: The can be allocated with "StrAlloc" (SDK_util.h) for C/C++ Parameters: The module context. Returns the module's capabilities as multiline aa:bbcc:dd[] Returns: error code XE "Module_CreateContext:sync_dbapi.h"XE "sync_dbapi.h:Module_CreateContext"_ENTRY_ TSyError Module_CreateContext (CContext * mContext, cAppCharP moduleName, cAppCharP subName, cAppCharP mContextName, DB_Callback mCB) Create a module context This routine will be called as the 1st or 2nd call, when this module will be connected. (The 1st call is usually a 'Module_Version( 0 )' call outside any context). It will be called not only once, but for each session and datastore context, as defined at the XML config file. This routine can return error 20028 (LOCERR_ALREADY), if already created. This will be treated not as an error. For this case, it must return the same as for the former call(s). NOTE: The module context can exist once and can be shared for all plug-in accesses. Please note, that write access to such a common module context structure must be thread-safe, when accessed from the session or datastore context. All the 'Module_CreateContext' calls for this module will be called sequentially by one thread. The plug-in programmer is responsible not to re-initialize the context for subsequent calls. If the module name at the XML config file is defined as "aaa!bbb!ccc" it will be passed as "aaa" to and "bbb!ccc" to . This mechanism can be used to cascade plug-in modules, where the next module gets "bbb" as and "ccc" as . The JNI plug-in for Java is using this structure to address the JNI plug-in and its assigned Java class. Parameters: Returns a value, which allows to identify this module context. Allowed values: Anything except 0, which is reserved for no context. Name of this plug-in Name of sub module (if available) Name of the (datastore) context, e.g. "contacts"; this string is empty for calll concerning the session. DB_Callback structure for module logging Returns: error code, if context could not be created (e.g. not enough memory), 0 if context successfully created. XE "Module_DeleteContext:sync_dbapi.h"XE "sync_dbapi.h:Module_DeleteContext"_ENTRY_ TSyError Module_DeleteContext (CContext mContext) This routine will be called as the last call, before this module is disconnected. The SyncML engine will call 'Module_DisposeObj' (if required) before this call NOTE: This routine will be called ONLY, if the server stops in a controlled way. Its good programming practice not to wait for this 'DeleteContext' call. Parameters: The module context. Returns: error code XE "Module_DisposeObj:sync_dbapi.h"XE "sync_dbapi.h:Module_DisposeObj"_ENTRY_ void Module_DisposeObj (CContext mContext, void * memory) Disposes memory, which has been allocated within the module context. (At the moment this is only the capabilities string). 'Module_DisposeObj' can occur at any time within . NOTE: - If has been allocated with "StrAlloc", use "Str_Dispose" (SDK_util.h) to release the memory again. If it is defined as const within the plugin module (the module itself knows about !), this routine can be implemented empty. Parameters: The module context. Dispose allocated memory. Returns: - XE "Module_PluginParams:sync_dbapi.h"XE "sync_dbapi.h:Module_PluginParams"_ENTRY_ TSyError Module_PluginParams (CContext mContext, cAppCharP mConfigParams, CVersion engineVersion) The module's config params will be sent to the plug-in. It can be used for access path definitions or other things. The can be defined individually for each session and datastore. The SyncML engine checks the syntax, but not the content. This routine should return an error 20010 (LOCERR_CFGPARSE), if one of these parameters is not supported. EXAMPLE: Definition at XML config file: /var/log/sysync 42 will be passed as: "datapath:/var/log/sysync ultimate_answer:42" NOTE: Module_PluginParams will be called ALWAYS for each module context, even if no plug-in parameter is defined. This allows to react consistently on parameters, which are not always available. Parameters: The module context. The plugin params as multiline aa:bbcc:dd[] The SyncML engine's version Returns: error code XE "Module_Version:sync_dbapi.h"XE "sync_dbapi.h:Module_Version"_ENTRY_ CVersion Module_Version (CContext mContext) Get the module's version. NOTE: The SyncML will take decisions depending on this version number, so the plug-in developer should not change the values at the delivered sample code. Plugin_Version( short buildNumber ) of 'SDK_util' should be used. The can be defined by the user. NOTE: This function can be called by the engine outside any context with = 0. For this case, any callback is not permitted (as no DB_Callback is available). Parameters: The module context ( 0, if none ). Returns: current version as SDK_VERSION_MAJOR | SDK_VERSION_MINOR) | SDK_SUBVERSION | buildNumber XE "MoveItem:sync_dbapi.h"XE "sync_dbapi.h:MoveItem"_ENTRY_ TSyError MoveItem (CContext aContext, const ItemID aID, cAppCharP newParentID) This routine moves from to Parameters: The datastore context. ItemID ( with , ) to be moved. New parent ID for Returns: error code LOCERR_OK ( =0 ), if successful DB_NotFound ( =404 ), if unknown DB_Full ( =420 ), if not enough space in the DB ... or any other SyncML error code, see Reference Manual XE "ReadBlob:sync_dbapi.h"XE "sync_dbapi.h:ReadBlob"_ENTRY_ TSyError ReadBlob (CContext aContext, const ItemID aID, cAppCharP aBlobID, void ** aBlkPtr, ulong * aBlkSize, ulong * aTotSize, bool aFirst, bool * aLast) This routine reads the specific binary logic block , from the database. Parameters: The datastore context. ItemID ( with , ). The assigned ID of the blob. Position and size (in bytes) of the blob block. Input: Maximum size (in bytes) of the blob block to be read. If is 0, the result size is not limited. Output: Size (in bytes) of the blob block. must not be larger than its input value. Total size of the blob (in bytes), can be also 0, if not available, e.g. for a stream. (Input) true : Engine asks for the first block of this blob. false: Engine asks for the next block of this blob. (Output) true : This is the last part (or the whole) blob. false: More blocks will follow. Returns: error code, if not ok ( e.g. invalid , ) NOTE 1) The memory at , must be allocated locally. The SyncML engine will call 'DisposeObj' later for , to release the memory. NOTE 2) Empty blobs are allowed, and must be set to 0, can be undefined, must be true. No 'DisposeObj' call is required for this case. NOTE 3) The SyncML engine can change to read another blob before having read the whole blob. It will never resume reading of this incomplete blob, but start reading again with = true. XE "ReadItem:sync_dbapi.h"XE "sync_dbapi.h:ReadItem"_ENTRY_ TSyError ReadItem (CContext aContext, const ItemID aID, appCharP * aItemData) This routine reads the contents of a specific ItemID from the database. Parameters: The datastore context. The assigned ItemID in the database Returns the data, formatted as multiline aa:bbcc:dd[] Returns: error code, if not ok ( e.g. invalid ) NOTE: The memory for must be allocated locally. The SyncML engine will call 'DisposeObj' later for , to release again its memory. XE "ReadItemAsKey:sync_dbapi.h"XE "sync_dbapi.h:ReadItemAsKey"_ENTRY_ TSyError ReadItemAsKey (CContext aContext, const ItemID aID, appPointer aItemKey) XE "ReadNextItem:sync_dbapi.h"XE "sync_dbapi.h:ReadNextItem"_ENTRY_ TSyError ReadNextItem (CContext aContext, ItemID aID, appCharP * aItemData, sInt32 * aStatus, bool aFirst) This routine reads the next ItemID from the database. of 'ContextSupport' ( "ReadNextItem:allfields" ) and of 'FilterSupport' must be considered. If is true, the routine must return the first element (again). Parameters: The datastore context. The assigned ItemID in the database; will be ignored by the SyncML engine, if = 0 The data, formatted as multiline aa:bbcc:dd[]; will be ignored by the SyncML engine, if = 0 ReadItem_EOF ( =0 ) for none ( =eof ), ReadItem_Changed ( =1 ) for a changed item, ReadItem_Unchanged ( =2 ) for unchanged item. ReadItem_Resumed ( =3 ) for a changed item (since resumed) true: the routine must return the first element false: the routine must return the next element Returns: error code, if not ok. No datasets found is a success as well ! NOTE: The memory for and must be allocated locally. The SyncML engine will call 'DisposeObj' later for these objects to release the memory again. It needn't to be allocated, if is ReadItem_EOF. NOTE: By default, the SyncML engine asks for only. can be returned, if anyway available or must be returned, if the engine asks for it (when calling "ReadNextItem:allfields" at 'ContextSupport' with ). XE "ReadNextItemAsKey:sync_dbapi.h"XE "sync_dbapi.h:ReadNextItemAsKey"_ENTRY_ TSyError ReadNextItemAsKey (CContext aContext, ItemID aID, appPointer aItemKey, sInt32 * aStatus, bool aFirst) XE "ReadNextMapItem:sync_dbapi.h"XE "sync_dbapi.h:ReadNextMapItem"_ENTRY_ bool ReadNextMapItem (CContext aContext, MapID mID, bool aFirst) Map table handling: Get the next map item of this context. If is true, the routine must start to return the first element Parameters: The datastore context MapID ( with , and ). Starting with the first MapID. When creating a context, the first call will get the first MapID, even if is false. Returns: true: as long as there is a MapID available, which must be assigned to false: if there is no more MapID. Nothing must be assigned to USED ONLY WITH XE "SaveAdminData:sync_dbapi.h"XE "sync_dbapi.h:SaveAdminData"_ENTRY_ TSyError SaveAdminData (CContext aContext, cAppCharP adminData) This functions stores the new for this context Parameters: The datastore context The new set of admin data to be stored, will be loaded again with the next 'LoadAdminData' call. Returns: error code, if data could not be saved (e.g. not enough memory); 0 if successfully created. USED ONLY WITH XE "Session_AdaptItem:sync_dbapi.h"XE "sync_dbapi.h:Session_AdaptItem"_ENTRY_ TSyError Session_AdaptItem (CContext sContext, appCharP * sItemData1, appCharP * sItemData2, appCharP * sLocalVars, uInt32 sIdentifier) This function adapts itemData Parameters: The session context The 1st item's data The 2nd item's data The local vars To identify, where it is called Returns: error code NOTE: The memory for adapted strings must be allocated locally. The SyncML engine will call 'DisposeObj' later, to release again its memory. One or more strings can be returned unchanged as well. XE "Session_CheckDevice:sync_dbapi.h"XE "sync_dbapi.h:Session_CheckDevice"_ENTRY_ TSyError Session_CheckDevice (CContext sContext, cAppCharP aDeviceID, appCharP * sDevKey, appCharP * nonce) Check the database entry of and return its string. If is not yet available at the plug-in, return "" for Parameters: The session context The assigned device ID string The device key string (will be used for datastore accesses later) The nonce string of the last session If is not yet available, return "" for and error code 0. Returns: error code 403 (Forbidden), if plugin_deviceadmin is not supported; 0, if successful USED ONLY WITH XE "Session_CreateContext:sync_dbapi.h"XE "sync_dbapi.h:Session_CreateContext"_ENTRY_ TSyError Session_CreateContext (CContext * sContext, cAppCharP sessionName, DB_Callback sCB) By default the session context will be handled by the ODBC interface. The session context of this plug-in module will be used only, if and is defined ( name_of_the_plugin ). can be defined individually. Parameters: Returns a value, which allows to identify this session context. Name of this session DB_Callback structure for session logging Returns: error code, if context could not be created (e.g. not enough memory) 0 if context successfully created, Flags (at the XML config file): yes: "Session_CheckDevice", "Session_GetNonce" "Session_SaveNonce" and "Session_SaveDeviceInfo" will be used. yes: "Session_PasswordMode", "Session_Login" and "Session_Logout" will be used. XE "Session_DeleteContext:sync_dbapi.h"XE "sync_dbapi.h:Session_DeleteContext"_ENTRY_ TSyError Session_DeleteContext (CContext sContext) Delete a session context. No access to will be done after this call Parameters: The session context Returns: error code, if context could not be deleted. XE "Session_DispItems:sync_dbapi.h"XE "sync_dbapi.h:Session_DispItems"_ENTRY_ void Session_DispItems (CContext sContext, bool allFields, cAppCharP specificItem) Writes the context of all items to dbg output path This routine is implemented for debug purposes only and will NOT BE CALLED by the SyncML engine. Can be implemented empty Parameters: The session context true : all fields, also empty ones, will be displayed; false: only fields <> "" will be shown "" : all items will be shown; else shows the Returns: - XE "Session_DisposeObj:sync_dbapi.h"XE "sync_dbapi.h:Session_DisposeObj"_ENTRY_ void Session_DisposeObj (CContext sContext, void * memory) Disposes memory, which has been allocated within the session context. 'Session_DisposeObj' can occur at any time within . Parameters: The session context. Dispose allocated memory. Returns: - XE "Session_GetDBTime:sync_dbapi.h"XE "sync_dbapi.h:Session_GetDBTime"_ENTRY_ TSyError Session_GetDBTime (CContext sContext, appCharP * currentDBTime) Get the current DB time of Parameters: The session context The current time of the plugin's DB (as ISO8601 format). Returns: error code 403 (Forbidden), if plugin_deviceadmin is not supported; 404 (NotFound), if not available -> the engine creates its own time 0, if successful XE "Session_GetNonce:sync_dbapi.h"XE "sync_dbapi.h:Session_GetNonce"_ENTRY_ TSyError Session_GetNonce (CContext sContext, appCharP * nonce) Get a new nonce from the database. If this routine returns an error, the SyncML engine will create its own nonce. Parameters: The session context A valid new nonce value (for the assigned device ID). Returns: error code 404 (NotFound), if no has been generated; 0, if a valid has been generated USED ONLY WITH XE "Session_Login:sync_dbapi.h"XE "sync_dbapi.h:Session_Login"_ENTRY_ TSyError Session_Login (CContext sContext, cAppCharP sUsername, appCharP * sPassword, appCharP * sUsrKey) Get of , in the session context. Parameters: The session context The user name ... ... and the password. is an input parameter for 'Password_ClrTxt_IN' mode and an output parameter for 'Password_ClrText_OUT' and 'Password_MD5_OUT' modes. Returns the internal reference key, which will be passed to to the datastore contexts later. Returns: error code 403 (Forbidden), if plugin_sessionauth is not supported; 0, if successful USED ONLY WITH XE "Session_Logout:sync_dbapi.h"XE "sync_dbapi.h:Session_Logout"_ENTRY_ TSyError Session_Logout (CContext sContext) Logout for this session context Parameters: The session context Returns: error code 403 (Forbidden), if plugin_sessionauth is not supported; 0, if successful USED ONLY WITH XE "Session_PasswordMode:sync_dbapi.h"XE "sync_dbapi.h:Session_PasswordMode"_ENTRY_ sInt32 Session_PasswordMode (CContext sContext) Get the password mode. There are currently 4 different password modes supported. Parameters: The session context Returns: Password_ClrText_IN : 'SessionLogin' will get clear text password Password_ClrText_OUT : " must return clear text password Password_MD5_OUT : " must return MD5 coded password Password_MD5_Nonce_IN: " will get MD5B64(MD5B64(user:pwd):nonce) USED ONLY WITH XE "Session_SaveDeviceInfo:sync_dbapi.h"XE "sync_dbapi.h:Session_SaveDeviceInfo"_ENTRY_ TSyError Session_SaveDeviceInfo (CContext sContext, cAppCharP aDeviceInfo) Save the device info for Parameters: The session context More information about the assigned device (for DB and logging) Returns: error code 403 (Forbidden), if plugin_deviceadmin is not supported; 0, if successful USED ONLY WITH XE "Session_SaveNonce:sync_dbapi.h"XE "sync_dbapi.h:Session_SaveNonce"_ENTRY_ TSyError Session_SaveNonce (CContext sContext, cAppCharP nonce) Save the new nonce (which will be expected to be returned in the next session for this device ID. Parameters: The session context New for the next session (of the assigned device ID) Returns: error code 403 (Forbidden), if plugin_deviceadmin is not supported; 0, if successful USED ONLY WITH XE "Session_ThreadMayChangeNow:sync_dbapi.h"XE "sync_dbapi.h:Session_ThreadMayChangeNow"_ENTRY_ void Session_ThreadMayChangeNow (CContext sContext) Due to the architecture of the SyncML engine, the system may run in a multithread environment. The consequence is that each routine of this plugin module can be called by a different thread. Normally this is not a problem, nevertheless this routine notifies about thread changes in . It can be ignored ( =implemented empty), if not really needed. Parameters: The session context Returns: - XE "StartDataRead:sync_dbapi.h"XE "sync_dbapi.h:StartDataRead"_ENTRY_ TSyError StartDataRead (CContext aContext, cAppCharP lastToken, cAppCharP resumeToken) This routine initializes reading from the database StartDataRead must prepare the database to return the objects of this context. Parameters: The datastore context. The value which has been returned by this module at the last "EndDataWrite" call will be given. It will be "", when called the first time. Normally this token is an ISO8601 formatted string which represents the module's current time (at the beginning of a session). It will be used to decide at 'ReadNextItem' whether a record has been changed. Token for Suspend/Resume mode. Returns: error code XE "StartDataWrite:sync_dbapi.h"XE "sync_dbapi.h:StartDataWrite"_ENTRY_ TSyError StartDataWrite (CContext aContext) This routine initializes writing to the database Parameters: The datastore context. Returns: error code, if not ok (e.g. invalid select options) XE "ThreadMayChangeNow:sync_dbapi.h"XE "sync_dbapi.h:ThreadMayChangeNow"_ENTRY_ void ThreadMayChangeNow (CContext aContext) Due to the architecture of the SyncML engine, the system may run in a multithread environment. The consequence is that each routine of this API module can be called by a different thread. Normally this is not a problem, nevertheless this routine notifies about thread changes in . It can be ignored ( =implemented empty), if not really needed. Parameters: The datastore context. Returns: - XE "UpdateItem:sync_dbapi.h"XE "sync_dbapi.h:UpdateItem"_ENTRY_ TSyError UpdateItem (CContext aContext, cAppCharP aItemData, const ItemID aID, ItemID updID) This routine updates an existing dataset of the database Parameters: The datastore context. The data, formatted as multiline aa:bbcc:dd[] Database key of dataset to be updated Input: NULL is assigned as default value to and . Output: The updated database key for . Can be NULL, if the same as Returns: error code LOCERR_OK ( =0 ), if successful DB_Forbidden ( =403 ), if can't be resolved DB_NotFound ( =404 ), if unknown DB_Full ( =420 ), if not enough space in the DB ... or any other SyncML error code, see Reference Manual NOTE: must either contain NULL references ( if the same as ), or the memory for , must be allocated locally. The SyncML engine will call 'DisposeObj' later for and to release the memory. can be NULL, if the hierarchical model is not supported. XE "UpdateItemAsKey:sync_dbapi.h"XE "sync_dbapi.h:UpdateItemAsKey"_ENTRY_ TSyError UpdateItemAsKey (CContext aContext, appPointer aItemKey, const ItemID aID, ItemID updID) XE "UpdateMapItem:sync_dbapi.h"XE "sync_dbapi.h:UpdateMapItem"_ENTRY_ TSyError UpdateMapItem (CContext aContext, MapID mID) Map table handling: Update a map item of this context Parameters: The datastore context MapID ( with , and ). If there is already a MapID element with localID, it will be update, else created. Returns: error code, if this MapID can't be updated (e.g. not yet existing). USED ONLY WITH XE "WriteBlob:sync_dbapi.h"XE "sync_dbapi.h:WriteBlob"_ENTRY_ TSyError WriteBlob (CContext aContext, const ItemID aID, cAppCharP aBlobID, void * aBlkPtr, ulong aBlkSize, ulong aTotSize, bool aFirst, bool aLast) This routine writes the specific binary logic block to the database. Parameters: The datastore context. ItemID ( with , ). The assigned ID of the blob. Position and size (in bytes) of the blob block. Total size of the blob (in bytes), Can be also 0, if not available, e.g. for a stream. true : this is the first block of the blob. false: this is the next block. true : this is the last block. false: more blocks will follow. Returns: error code, if not ok ( e.g. invalid , ) NOTE: Empty blobs are possible, and will be set to 0, will be NULL, and will be true. XE "WriteLogData:sync_dbapi.h"XE "sync_dbapi.h:WriteLogData"_ENTRY_ void WriteLogData (CContext aContext, cAppCharP logData) This functions writes for this context Can be implemented empty, if not needed. Parameters: The datastore context. Logging information, formatted as multiline aa:bbcc:dd[] Returns: - UIApi Interface description Functions in the UI_Call_In call-in structure The following list only shows the function prototypes. These are required when accessing the UIApi from plain C. See documentation of the TEngineModuleBase class members for details. The routines shown here are all also implemented as methods of TEngineModuleBase (and are available in the wrapper class TEngineModuleBridge which facilitates access from C++ code and is part of the SDK), and have similar signatures (but no aCB first argument because the callback structure is a class member and using by-reference arguments instead of plain pointers where appropriate). void DebugDB (void *aCB, cAppCharP aParams) void DebugExotic (void *aCB, cAppCharP aParams) void DebugBlock (void *aCB, cAppCharP aTag, cAppCharP aDesc, cAppCharP aAttrText) void DebugEndBlock (void *aCB, cAppCharP aTag) void DebugEndThread (void *aCB) TSyError SetStringMode (void *aCB, uInt16 aCharSet, uInt16 aLineEndMode, bool aBigEndian) TSyError InitEngineXML (void *aCB, cAppCharP aConfigXML) TSyError InitEngineFile (void *aCB, cAppCharP aConfigFilePath) TSyError InitEngineCB (void *aCB, TXMLConfigReadFunc aReaderFunc, void *aContext) TSyError OpenSession (void *aCB, appPointer *aSessionH, uInt32 aSelector, cAppCharP aSessionName) TSyError OpenSessionKey (void *aCB, appPointer aSessionH, appPointer *aKeyH, uInt16 aMode) TSyError SessionStep (void *aCB, appPointer aSessionH, uInt16 *aStepCmd, TEngineProgressInfo *aInfoP) TSyError GetSyncMLBuffer (void *aCB, appPointer aSessionH, bool aForSend, appPointer *aBuffer, memSize *aBufSize) TSyError RetSyncMLBuffer (void *aCB, appPointer aSessionH, bool aForSend, memSize aRetSize) TSyError ReadSyncMLBuffer (void *aCB, appPointer aSessionH, appPointer aBuffer, memSize aBufSize, memSize *aValSize) TSyError WriteSyncMLBuffer (void *aCB, appPointer aSessionH, appPointer aBuffer, memSize aValSize) TSyError CloseSession (void *aCB, appPointer aSessionH) TSyError OpenKeyByPath (void *aCB, appPointer *aKeyH, appPointer aParentKeyH, cAppCharP aPath, uInt16 aMode) TSyError OpenSubkey (void *aCB, appPointer *aKeyH, appPointer aParentKeyH, sInt32 aID, uInt16 aMode) TSyError DeleteSubkey (void *aCB, appPointer aParentKeyH, sInt32 aID) TSyError GetKeyID (void *aCB, appPointer aKeyH, sInt32 *aID) TSyError SetTextMode (void *aCB, appPointer aKeyH, uInt16 aCharSet, uInt16 aLineEndMode, bool aBigEndian) TSyError SetTimeMode (void *aCB, appPointer aKeyH, uInt16 aTimeMode) TSyError CloseKey (void *aCB, appPointer aKeyH) TSyError GetValue (void *aCB, appPointer aKeyH, cAppCharP aValName, uInt16 aValType, appPointer aBuffer, memSize aBufSize, memSize *aValSize) TSyError GetValueByID (void *aCB, appPointer aKeyH, sInt32 aID, sInt32 aArrayIndex, uInt16 aValType, appPointer aBuffer, memSize aBufSize, memSize *aValSize) sInt32 GetValueID (void *aCB, appPointer aKeyH, cAppCharP aName) TSyError SetValue (void *aCB, appPointer aKeyH, cAppCharP aValName, uInt16 aValType, cAppPointer aBuffer, memSize aValSize) TSyError SetValueByID (void *aCB, appPointer aKeyH, sInt32 aID, sInt32 aArrayIndex, uInt16 aValType, cAppPointer aBuffer, memSize aValSize) TEngineModuleBase Class Reference Public Member Function Overview TEngineModuleBase () virtual ~TEngineModuleBase () TSyError Connect (string aEngineName, unsigned long aPrgVersion=0, unsigned short aDebugFlags=DBG_PLUGIN_NONE) virtual TSyError Init ()=0 virtual TSyError SetStringMode (uInt16 aCharSet, uInt16 aLineEndMode=LEM_CSTR, bool aBigEndian=false)=0 Set the global mode for string paramaters (when never called, default params are UTF-8 with C-style line ends). virtual TSyError InitEngineXML (cAppCharP aConfigXML)=0 init object, optionally passing XML config text in memory virtual TSyError InitEngineFile (cAppCharP aConfigFilePath)=0 init object, optionally passing a open FILE for reading config virtual TSyError InitEngineCB (TXMLConfigReadFunc aReaderFunc, void *aContext)=0 init object, optionally passing a callback for reading config virtual TSyError OpenSession (appPointer &aNewSessionH, uInt32 aSelector=0, cAppCharP aSessionName=NULL)=0 Open a session. virtual TSyError OpenSessionKey (appPointer aSessionH, appPointer &aNewKeyH, uInt16 aMode)=0 open session specific runtime parameter/settings key virtual TSyError SessionStep (appPointer aSessionH, uInt16 &aStepCmd, TEngineProgressInfo *aInfoP=NULL)=0 Executes sync session or other sync related activity step by step. virtual TSyError GetSyncMLBuffer (appPointer aSessionH, bool aForSend, appPointer &aBuffer, memSize &aBufSize)=0 Get access to SyncML message buffer. virtual TSyError RetSyncMLBuffer (appPointer aSessionH, bool aForSend, memSize aProcessed)=0 Return SyncML message buffer to engine. virtual TSyError ReadSyncMLBuffer (appPointer aSessionH, appPointer aBuffer, memSize aBufSize, memSize &aMsgSize)=0 Read data from SyncML message buffer. virtual TSyError WriteSyncMLBuffer (appPointer aSessionH, appPointer aBuffer, memSize aMsgSize)=0 Write data to SyncML message buffer. virtual TSyError CloseSession (appPointer aSessionH)=0 Close a session. virtual TSyError OpenKeyByPath (appPointer &aNewKeyH, appPointer aParentKeyH, cAppCharP aPath, uInt16 aMode)=0 open Settings key by path specification virtual TSyError OpenSubkey (appPointer &aNewKeyH, appPointer aParentKeyH, sInt32 aID, uInt16 aMode)=0 open Settings subkey key by ID or iterating over all subkeys virtual TSyError DeleteSubkey (appPointer aParentKeyH, sInt32 aID)=0 delete Settings subkey key by ID virtual TSyError GetKeyID (appPointer aKeyH, sInt32 &aID)=0 Get key ID of currently open key. Note that the Key ID is only locally unique within the parent key. virtual TSyError SetTextMode (appPointer aKeyH, uInt16 aCharSet, uInt16 aLineEndMode=LEM_CSTR, bool aBigEndian=false)=0 Set text format parameters (when never called, default params are those set with global SetStringMode()). virtual TSyError SetTimeMode (appPointer aKeyH, uInt16 aTimeMode)=0 Set time format parameters. virtual TSyError CloseKey (appPointer aKeyH)=0 Closes a key opened by OpenKeyByPath() or OpenSubKey(). virtual TSyError GetValue (appPointer aKeyH, cAppCharP aValName, uInt16 aValType, appPointer aBuffer, memSize aBufSize, memSize &aValSize)=0 Reads a named value in specified format into passed memory buffer. virtual sInt32 GetValueID (appPointer aKeyH, cAppCharP aName)=0 get value's ID for use with Get/SetValueByID() virtual TSyError GetValueByID (appPointer aKeyH, sInt32 aID, sInt32 aArrayIndex, uInt16 aValType, appPointer aBuffer, memSize aBufSize, memSize &aValSize)=0 Reads a named value in specified format into passed memory buffer. virtual TSyError SetValue (appPointer aKeyH, cAppCharP aValName, uInt16 aValType, cAppPointer aBuffer, memSize aValSize)=0 Writes a named value in specified format passed in memory buffer. virtual TSyError SetValueByID (appPointer aKeyH, sInt32 aID, sInt32 aArrayIndex, uInt16 aValType, cAppPointer aBuffer, memSize aValSize)=0 Writes a named value in specified format passed in memory buffer. TSyError CloseKeyAndNULL (appPointer &aKeyH) Closes a key and nulls the handle. TSyError CloseSessionAndNULL (appPointer &aSessionH) Closes a session and nulls the handle. Member Function Documentation XE "Connect:sysync\:\:TEngineModuleBase"XE "sysync\:\:TEngineModuleBase:Connect"TSyError sysync::TEngineModuleBase::Connect (string aEngineName, unsigned long aPrgVersion = 0, unsigned short aDebugFlags = DBG_PLUGIN_NONE) XE "SetStringMode:sysync\:\:TEngineModuleBase"XE "sysync\:\:TEngineModuleBase:SetStringMode"virtual TSyError sysync::TEngineModuleBase::SetStringMode (uInt16 aCharSet, uInt16 aLineEndMode = LEM_CSTR, bool aBigEndian = false) [pure virtual] Set the global mode for string paramaters (when never called, default params are UTF-8 with C-style line ends). Parameters: aCharSet[in] charset aLineEndMode[in] line end mode (default is C-lineends of the platform (almost always LF)) aBigEndian[in] determines endianness of UTF16 text (defaults to little endian = intel order) Returns: LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure XE "InitEngineXML:sysync\:\:TEngineModuleBase"XE "sysync\:\:TEngineModuleBase:InitEngineXML"virtual TSyError sysync::TEngineModuleBase::InitEngineXML (cAppCharP aConfigXML) [pure virtual] init object, optionally passing XML config text in memory Parameters: aConfigXML[in] NULL or empty string if no external config needed, config text otherwise Returns: LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure XE "InitEngineFile:sysync\:\:TEngineModuleBase"XE "sysync\:\:TEngineModuleBase:InitEngineFile"virtual TSyError sysync::TEngineModuleBase::InitEngineFile (cAppCharP aConfigFilePath) [pure virtual] init object, optionally passing a open FILE for reading config Parameters: aConfigFilePath[in] path to config file Returns: LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure XE "InitEngineCB:sysync\:\:TEngineModuleBase"XE "sysync\:\:TEngineModuleBase:InitEngineCB"virtual TSyError sysync::TEngineModuleBase::InitEngineCB (TXMLConfigReadFunc aReaderFunc, void * aContext) [pure virtual] init object, optionally passing a callback for reading config Parameters: aReaderFunc[in] callback function which can deliver next chunk of XML config data aContext[in] free context pointer passed back with callback Returns: LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure XE "OpenSession:sysync\:\:TEngineModuleBase"XE "sysync\:\:TEngineModuleBase:OpenSession"virtual TSyError sysync::TEngineModuleBase::OpenSession (appPointer & aNewSessionH, uInt32 aSelector = 0, cAppCharP aSessionName = NULL) [pure virtual] Open a session. Parameters: aNewSessionH[out] receives session handle for all session execution calls aSelector[in] selector, depending on session type. For multi-profile clients: profile ID to use aSessionName[in] a text name/id to identify a session, useage depending on session type. Returns: LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure XE "OpenSessionKey:sysync\:\:TEngineModuleBase"XE "sysync\:\:TEngineModuleBase:OpenSessionKey"virtual TSyError sysync::TEngineModuleBase::OpenSessionKey (appPointer aSessionH, appPointer & aNewKeyH, uInt16 aMode) [pure virtual] open session specific runtime parameter/settings key Note: key handle obtained with this call must be closed BEFORE SESSION IS CLOSED! Parameters: aSessionH[in] session handle obtained with OpenSession aNewKeyH[out] receives the opened key's handle on success aMode[in] the open mode Returns: LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure XE "SessionStep:sysync\:\:TEngineModuleBase"XE "sysync\:\:TEngineModuleBase:SessionStep"virtual TSyError sysync::TEngineModuleBase::SessionStep (appPointer aSessionH, uInt16 & aStepCmd, TEngineProgressInfo * aInfoP = NULL) [pure virtual] Executes sync session or other sync related activity step by step. Parameters: aSessionH[in] session handle obtained with OpenSession aStepCmd[in/out] step command (STEPCMD_xxx): tells caller to send or receive data or end the session etc. instructs engine to suspend or abort the session etc. aInfoP[in] pointer to a TEngineProgressInfo structure, NULL if no progress info needed Returns: LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure XE "GetSyncMLBuffer:sysync\:\:TEngineModuleBase"XE "sysync\:\:TEngineModuleBase:GetSyncMLBuffer"virtual TSyError sysync::TEngineModuleBase::GetSyncMLBuffer (appPointer aSessionH, bool aForSend, appPointer & aBuffer, memSize & aBufSize) [pure virtual] Get access to SyncML message buffer. Parameters: aSessionH[in] session handle obtained with OpenSession aForSend[in] direction send/receive aBuffer[out] receives pointer to buffer (empty for receive, full for send) aBufSize[out] receives size of empty or full buffer Returns: LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure XE "RetSyncMLBuffer:sysync\:\:TEngineModuleBase"XE "sysync\:\:TEngineModuleBase:RetSyncMLBuffer"virtual TSyError sysync::TEngineModuleBase::RetSyncMLBuffer (appPointer aSessionH, bool aForSend, memSize aProcessed) [pure virtual] Return SyncML message buffer to engine. Parameters: aSessionH[in] session handle obtained with OpenSession aForSend[in] direction send/receive aProcessed[in] number of bytes put into or read from the buffer Returns: LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure XE "ReadSyncMLBuffer:sysync\:\:TEngineModuleBase"XE "sysync\:\:TEngineModuleBase:ReadSyncMLBuffer"virtual TSyError sysync::TEngineModuleBase::ReadSyncMLBuffer (appPointer aSessionH, appPointer aBuffer, memSize aBufSize, memSize & aMsgSize) [pure virtual] Read data from SyncML message buffer. Parameters: aSessionH[in] session handle obtained with OpenSession aBuffer[in] pointer to buffer aBufSize[in] size of buffer, maximum to be read aMsgSize[out] size of data available in the buffer for read INCLUDING just returned data. Note: If the aBufSize is too small to return all available data LOCERR_TRUNCATED will be returned, and the caller can repeat calls to ReadSyncMLBuffer to get the next chunk. Returns: LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure XE "WriteSyncMLBuffer:sysync\:\:TEngineModuleBase"XE "sysync\:\:TEngineModuleBase:WriteSyncMLBuffer"virtual TSyError sysync::TEngineModuleBase::WriteSyncMLBuffer (appPointer aSessionH, appPointer aBuffer, memSize aMsgSize) [pure virtual] Write data to SyncML message buffer. Parameters: aSessionH[in] session handle obtained with OpenSession aBuffer[in] pointer to buffer aMsgSize[in] size of message to write to the buffer Returns: LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure XE "CloseSession:sysync\:\:TEngineModuleBase"XE "sysync\:\:TEngineModuleBase:CloseSession"virtual TSyError sysync::TEngineModuleBase::CloseSession (appPointer aSessionH) [pure virtual] Close a session. Note: It depends on session type if this also destroys the session or if it may persist and can be re-opened. Parameters: aSessionH[in] session handle obtained with OpenSession Returns: LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure XE "OpenKeyByPath:sysync\:\:TEngineModuleBase"XE "sysync\:\:TEngineModuleBase:OpenKeyByPath"virtual TSyError sysync::TEngineModuleBase::OpenKeyByPath (appPointer & aNewKeyH, appPointer aParentKeyH, cAppCharP aPath, uInt16 aMode) [pure virtual] open Settings key by path specification Parameters: aNewKeyH[out] receives the opened key's handle on success aParentKeyH[in] NULL if path is absolute from root, handle to an open key for relative access aPath[in] the path specification as null terminated string aMode[in] the open mode Returns: LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure XE "OpenSubkey:sysync\:\:TEngineModuleBase"XE "sysync\:\:TEngineModuleBase:OpenSubkey"virtual TSyError sysync::TEngineModuleBase::OpenSubkey (appPointer & aNewKeyH, appPointer aParentKeyH, sInt32 aID, uInt16 aMode) [pure virtual] open Settings subkey key by ID or iterating over all subkeys Parameters: aNewKeyH[out] receives the opened key's handle on success aParentKeyH[in] handle to the parent key aID[in] the ID of the subkey to open, or KEYVAL_ID_FIRST/KEYVAL_ID_NEXT to iterate over existing subkeys or KEYVAL_ID_NEW to create a new subkey aMode[in] the open mode Returns: LOCERR_OK on success, DB_NoContent when no more subkeys are found with KEYVAL_ID_FIRST/KEYVAL_ID_NEXT or any other SyncML or LOCERR_xxx error code on failure XE "DeleteSubkey:sysync\:\:TEngineModuleBase"XE "sysync\:\:TEngineModuleBase:DeleteSubkey"virtual TSyError sysync::TEngineModuleBase::DeleteSubkey (appPointer aParentKeyH, sInt32 aID) [pure virtual] delete Settings subkey key by ID Parameters: aParentKeyH[in] handle to the parent key aID[in] the ID of the subkey to delete Returns: LOCERR_OK on success or any other SyncML or LOCERR_xxx error code on failure XE "GetKeyID:sysync\:\:TEngineModuleBase"XE "sysync\:\:TEngineModuleBase:GetKeyID"virtual TSyError sysync::TEngineModuleBase::GetKeyID (appPointer aKeyH, sInt32 & aID) [pure virtual] Get key ID of currently open key. Note that the Key ID is only locally unique within the parent key. Parameters: aKeyH[in] an open key handle aID[out] receives the ID of the open key, which can be used to re-access the key within its parent using OpenSubkey() Returns: LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure XE "SetTextMode:sysync\:\:TEngineModuleBase"XE "sysync\:\:TEngineModuleBase:SetTextMode"virtual TSyError sysync::TEngineModuleBase::SetTextMode (appPointer aKeyH, uInt16 aCharSet, uInt16 aLineEndMode = LEM_CSTR, bool aBigEndian = false) [pure virtual] Set text format parameters (when never called, default params are those set with global SetStringMode()). Parameters: aKeyH[in] an open key handle aCharSet[in] charset aLineEndMode[in] line end mode (defaults to C-lineends of the platform (almost always LF)) aBigEndian[in] determines endianness of UTF16 text (defaults to little endian = intel order) Returns: LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure XE "SetTimeMode:sysync\:\:TEngineModuleBase"XE "sysync\:\:TEngineModuleBase:SetTimeMode"virtual TSyError sysync::TEngineModuleBase::SetTimeMode (appPointer aKeyH, uInt16 aTimeMode) [pure virtual] Set time format parameters. Parameters: aKeyH[in] an open key handle aTimeMode[in] time mode, see TMODE_xxx (default is platform's lineratime_t when SetTimeMode() is not used) Returns: LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure XE "CloseKey:sysync\:\:TEngineModuleBase"XE "sysync\:\:TEngineModuleBase:CloseKey"virtual TSyError sysync::TEngineModuleBase::CloseKey (appPointer aKeyH) [pure virtual] Closes a key opened by OpenKeyByPath() or OpenSubKey(). Parameters: aKeyH[in] an open key handle. Will be invalid when call returns with LOCERR_OK. Do not re-use! Returns: LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure XE "GetValue:sysync\:\:TEngineModuleBase"XE "sysync\:\:TEngineModuleBase:GetValue"virtual TSyError sysync::TEngineModuleBase::GetValue (appPointer aKeyH, cAppCharP aValName, uInt16 aValType, appPointer aBuffer, memSize aBufSize, memSize & aValSize) [pure virtual] Reads a named value in specified format into passed memory buffer. Parameters: aKeyH[in] an open key handle aValName[in] name of the value to read aValType[in] desired return type, see VALTYPE_xxxx aBuffer[in/out] buffer where to store the data aBufSize[in] size of buffer in bytes (ALWAYS in bytes, even if value is Unicode string) aValSize[out] actual size of value. For VALTYPE_TEXT, size is string length (IN BYTES) excluding NULL terminator Note that this will be set also when return value is LOCERR_BUFTOOSMALL, to indicate the required buffer size Returns: LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure XE "GetValueID:sysync\:\:TEngineModuleBase"XE "sysync\:\:TEngineModuleBase:GetValueID"virtual sInt32 sysync::TEngineModuleBase::GetValueID (appPointer aKeyH, cAppCharP aName) [pure virtual] get value's ID for use with Get/SetValueByID() Returns: KEYVAL_ID_UNKNOWN when no ID available for name, ID of value otherwise XE "GetValueByID:sysync\:\:TEngineModuleBase"XE "sysync\:\:TEngineModuleBase:GetValueByID"virtual TSyError sysync::TEngineModuleBase::GetValueByID (appPointer aKeyH, sInt32 aID, sInt32 aArrayIndex, uInt16 aValType, appPointer aBuffer, memSize aBufSize, memSize & aValSize) [pure virtual] Reads a named value in specified format into passed memory buffer. Parameters: aKeyH[in] an open key handle aID[in] ID of the value to read aArrayIndex[in] 0-based array element index for array values. aValType[in] desired return type, see VALTYPE_xxxx aBuffer[in/out] buffer where to store the data aBufSize[in] size of buffer in bytes (ALWAYS in bytes, even if value is Unicode string) aValSize[out] actual size of value. For VALTYPE_TEXT, size is string length (IN BYTES) excluding NULL terminator Note that this will be set also when return value is LOCERR_BUFTOOSMALL, to indicate the required buffer size Returns: LOCERR_OK on success, LOCERR_OUTOFRANGE when array index is out of range SyncML or LOCERR_xxx error code on other failure XE "SetValue:sysync\:\:TEngineModuleBase"XE "sysync\:\:TEngineModuleBase:SetValue"virtual TSyError sysync::TEngineModuleBase::SetValue (appPointer aKeyH, cAppCharP aValName, uInt16 aValType, cAppPointer aBuffer, memSize aValSize) [pure virtual] Writes a named value in specified format passed in memory buffer. Parameters: aKeyH[in] an open key handle aValName[in] name of the value to write aValType[in] type of value passed in, see VALTYPE_xxxx aBuffer[in] buffer containing the data aValSize[in] size of value. For VALTYPE_TEXT, size can be passed as -1 if string is null terminated Returns: LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure XE "SetValueByID:sysync\:\:TEngineModuleBase"XE "sysync\:\:TEngineModuleBase:SetValueByID"virtual TSyError sysync::TEngineModuleBase::SetValueByID (appPointer aKeyH, sInt32 aID, sInt32 aArrayIndex, uInt16 aValType, cAppPointer aBuffer, memSize aValSize) [pure virtual] Writes a named value in specified format passed in memory buffer. Parameters: aKeyH[in] an open key handle aID[in] ID of the value to read aArrayIndex[in] 0-based array element index for array values. aValType[in] type of value passed in, see VALTYPE_xxxx aBuffer[in] buffer containing the data aValSize[in] size of value. For VALTYPE_TEXT, size can be passed as -1 if string is null terminated Returns: LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure XE "CloseKeyAndNULL:sysync\:\:TEngineModuleBase"XE "sysync\:\:TEngineModuleBase:CloseKeyAndNULL"TSyError sysync::TEngineModuleBase::CloseKeyAndNULL (appPointer & aKeyH) [inline] Closes a key and nulls the handle. Parameters: aKeyH[in/out] an open key handle. Will be set to NULL on exit (to make sure it is not re-used) Returns: LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure XE "CloseSessionAndNULL:sysync\:\:TEngineModuleBase"XE "sysync\:\:TEngineModuleBase:CloseSessionAndNULL"TSyError sysync::TEngineModuleBase::CloseSessionAndNULL (appPointer & aSessionH) [inline] Closes a session and nulls the handle. Parameters: aSessionH[in] session handle obtained with OpenSession Returns: LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure Settings keys supported in SyncML Client Engine The settings keys and values accessible trough the OpenKeyXXXX, GetValueXXX, SetValueXXX etc. block of routines (see  REF _Ref185314626 \r \h 5.2.3) may vary depending on the version and type of client library. The standard client library supports the following settings keys and values: Global settings keys - accessed using OpenKeyByPath() /engineinfo general info about engine (read-only) version - SySync full version string platform - name of the platform name - name of the Synthesis SyncML engine product manufacturer - returns Synthesis AG comment - returns special release comment string, which might indicate special builds like expiring demo versions etc. variantcode - returns variant classification code of the engine: 0=unknown, 1=STD, 2=PRO, 3=custom variant, 10=DEMO /configvars configuration variables (predefined, volatile when written) platformname - name of the current platform platformvers - version string of the current platform globcfg_path - global system-wide config path (such as C:\Windows or /etc) loccfg_path - local config path (such as exedir or user's dir) defout_path - default path to writable directory to write logs and other output by default temp_path - path where we can write temp files exedir_path - path to directory where executable resides userdir_path - path to the user's home directory for user-visible documents and files appdata_path - path to the user's preference directory for this application prefs_path - path to directory where all application prefs reside (not just mine) device_uri - URI of the device (some unique ID, usually a hardware serial number or network derived system name) device_name - Name of the device hardware (such as a model name) user_name - name of the currently logged-in user on the host platform conferrpath - not defined by default, can be set to a file path where XML config parsing error messages will be written to. Can be set to "console" to output XML config parsing errors to the system stdout path (if such a path exists on the platform) xxxx - user-defined variables (can also set to override default value of one of the above) /licensing license (volatile, text/code must be set every time app ist started) licensetext - license text licensecode - Writeonly: license code (setting it will recalculate all the following status variables) regStatus - Readonly: TSyError status code of currently set license regOK - Readonly: if true, license is ok productCode - Readonly: product code from license productFlags - Readonly: product flags from license quantity - Readonly: licensed quantity licenseType - Readonly: license type daysleft - Readonly: number of days left of expiring license or demo mode (-1 = not expiring) /profiles Client settings profiles (persistent) settingsstatus - TSyError status of the settings. MUST BE CALLED AT LEAST ONCE before opening subkeys overwrite - (volatile) boolean flag. In case opening settings would cause deleting incompatible settings, this is done only if overwrite is set to 1. provisioningstring - Writeonly: Allows creating and modifying settings using so-called provisioning strings. These are strings which can be created using our free ClientConfigurator tool to package settings in a form that can be easily delivered in various forms. One of them is writing them into the provisioningstring value. checkForFeature - Writeonly. When written with a feature code (see APP_FTR_xxx in engine_defs.h), the write operation either succeeds (=feature available) or returns 204/ DB_NoContent (=feature not available). Note that checkForFeature is also available in the profile to check for features affecting only a specific profile and on the target level for features specific to a single target. / Profile ID (as assigned by engine when profile is created) profileName - display name of the profile protocol - transport protocol: 0=included in URI, 1=http, 2=https, 3=wsp, 4=obex_irda, 5=obex_bt, 6=obex_tcp serverURI - SyncML Server URI URIpath - Path element appended to SyncML Server URI (e.g. in case URI is hardcoded) serverUser - SyncML Server user serverPassword - SyncML Server password (stored in disguised form) transportUser - user for login at the transport level (e.g. HTTP auth) transportPassword - password for transport level login (stored in disguised form) socksHost - SOCKS proxy address proxyHost - HTTP proxy address proxyUser - user for login at the proxy proxyPassword - password for proxy login (stored in disguised form) encoding - SyncML encoding (1=WBXML, 2=XML - note that not some client builds only support WBXML) syncmlvers - SyncML version to use to start session (0=automatic, 1=1.0, 2=1.1, 3=1.2) useProxy - If set to 1, this indicates that configured proxy server(s) should be used useConnectionProxy - if set to 1, this indicates that OS-defined, connection specific proxies should be used timedSyncMobile - Number of minutes for mobile timed autosync (0=none) timedSyncCradled - Number of minutes for cradled timed autosync (0=none) dangerFlags - Readonly: returns the "danger" status of the next sync, i.e. indication when either server (DANGERFLAG_WILLZAPSERVER) or client (DANGERFLAG_WILLZAPCLIENT) side data will be cleared completely and replaced with the other side's content in any of the datastores currently enabled for sync. Client implementations should check these before starting a sync and warn users appropriately. Note that each target has also a dangerFlag which can be queried to get each datastore's flags separately. checkForFeature - Writeonly. When written with a feature code (see APP_FTR_xxx in engine_defs.h), the write operation either succeeds (=feature available) or returns 204/ DB_NoContent (=feature not available). Note that checkForFeature is also available in each target to check for features specific to one target and on the profiles container level for global-level features. checkForReadOnly - Writeonly. When written with a readonly flag value (see RDONLY_xxx in engine_defs.h), the write operation either succeeds (=queried settings should be made readonly in the UI) or returns 204/ DB_NoContent (=queried settings should be editable in the UI). Note that actual profile and target fields may still be technically writable using SetValue() – checkForReadOnly is indended to give the UI implementation the needed information to make some fields not editable for the end user. checkForReadOnly is also available in each target to check for readonly fields at the target level. readOnlyFlags - These flags can be set (usually by provisioning, see "provisioningstring") to make certain aspects of a settings profile read-only. See RDONLY_xxx constants in engine_defs.h. Note that these flags don't actually prohibit writing to settings fields, but should be queried by UI code to using checkForReadOnly (see above). UI code should never check readOnlyFlags directly, because depending on the engine build some readonly conditions might exist without the corresponding flag explicitly set in readOnlyFlags. transpFlags - 32 bit Flagword reserved for transport related settings flags. profileFlags - 32 bit Flagword reserved for general profile related settings flags. profileExtra1 - 32 bit Integer reserved for general profile related settings value. profileExtra2 - 32 bit Integer reserved for general profile related settings value. profileData - 256 bytes general purpose BLOB reserved for general profile related persistent storage. /autosynclevels / Autosync level ID, 0..2, 0=first priority, 2=least priority mode - Autosync mode for this level (0=IPP, 1=timed, 2=off, 3=server alerted) startDayTime - minute of the day when autosync starts in this level endDayTime - minute of the day when autosync ends in this level weekdayMask - weekdays where autosync is enabled in this level (Bit 0=Sun, 1=Mon .. 6=Sat chargeLevel - percentage of battery charge needed to enable autosync (0..100, 100=with AC supply only) memLevel - percentage of memory free needed to enable autosync (0..100) flags - flags reserved for future use /targets Targets (databases available for sync in this profile) / Target ID is the as defined in the config enabled - if set to 1, this datastore will be included in next sync forceslow - if set to 1, next sync will be a slow sync syncmode - sync mode: 0=twoway, 1=from server only, 2=from client only limit1 - sync range limit (such as number of days in the past, depends on datastore) limit2 - sync range limit (such as number of days in the future, depends on datastore) extras - flags for sync range limist (depends on datastore) localpath - local database path (if any), to differentiate multiple instances of the same database type remotepath - remote (server) database path localcontainer - local container name, if any (usage depends on datastore implementation) dbname - Readonly: name of the related (in the XML config) lastSync - Readonly: time of last successful sync lastToRemoteSync - Readonly: time of last sync that sent data to the remote party (server) dangerFlags - Readonly: returns the "danger" status of the next sync, i.e. indication when either server (DANGERFLAG_WILLZAPSERVER) or client (DANGERFLAG_WILLZAPCLIENT) side data will be cleared completely and replaced with the other side's content. Client implementations should check these before starting a sync and warn users appropriately. Note that the profile has also a dangerFlag which represents all target's dangerFlags combined. checkForFeature - Writeonly. When written with a feature code (see APP_FTR_xxx in engine_defs.h), the write operation either succeeds (=feature available) or returns 204/ DB_NoContent (=feature not available). Note that checkForFeature is also available in the profile to check for features affecting all targets and on the profiles level for global-level features. checkForReadOnly - Writeonly. When written with a readonly flag value (see RDONLY_xxx in engine_defs.h), the write operation either succeeds (=queried settings should be made readonly in the UI) or returns 204/ DB_NoContent (=queried settings should be editable in the UI). Note that actual profile and target fields may still be technically writable using SetValue() – checkForReadOnly is indended to give the UI implementation the needed information to make some fields not editable for the end user. checkForReadOnly is also available at the profile level. isAvailable - Readonly. Returns non-zero if the datastore is available for being used (vs. only implemented, but currently blocked, e.g. because the server side does not support the type). The UI implementation should visually show the datastore related UI in a disabled state or completely hide it when isAvailable returns zero. dispName - Readonly. Returns the display name of the datastore as specified in the XML config with . If is not set, the technical name of the datastore is returned. lastSyncIdentifer - Readonly: Returns the identifier used by the datastore implementation (possibly a plugin) to identify the time of last sync. remoteDispName - Readonly: Returns the display name of the datastore as transmitted in the remote party's devInf (if at all contained in the devInf). remoteFilters - Filter expression to be passed to server (in TAF/CGI syntax format). localFilters - Filter expression to be used locally to synchonize only a subset of the local data set (in TAF/CGI syntax format). Not active yet, reserved for future use. filterCapDesc - Readonly. Reserved for future use (will contain a description of filter capabilities of the server for creating UI like popup menus for filter creation). Session local settings/values, accessed using OpenSessionKey() Session key unnamed implicit per-session key obtained by OpenSessionKey() connectURI - URI to use to connect to SyncML server. Note that this might be different from the original Server URI in profile's "serverURI" as the SyncML server might request sending requests to another URI during a sync session. connectHost - This is the host (server address) part of the connectURI. This is what is normally required to create a connection at the network level. connectDoc - This is the document part of the connect URI, which is normally required to prepare a HTTP POST request. contenttype - content type string to use for the HTTP "Content-Type:" header. localSessionID - local identification string of the current sync session. sessionPassword - this is a write-only value. It can be used to provide the session password from a secure storage (like Mac OS X keychain) rather than actually storing it in the profile settings (from where it could be extracted by unauthorized parties). To provide the session password via this value, it must be set immediately after the initial STEPCMD_CLIENTSTART or STEPCMD_CLIENTAUTOSTART has been successfully executed. /sessionvars Session context script variables (for PRO engines with scripting only) - access (read and write) to any script variable defined in session context scripts (like ). This is useful to pass extra data back and forth between engine and database plugins or UI. /profile Access to current session's profile record. See / above for description of profile values and subkeys. This is useful for example for database plugins to make use of profile flags and settings configured for the current session. Error codes This section lists the error codes that can occur (normally visible in the logs or on the console). SyncML Status Codes These codes are defined by the SyncML standard. For details, see HYPERLINK "http://www.openmobilealliance.org/release_program/ds_v12.html" http://www.openmobilealliance.org/release_program/ds_v12.html. Note that this list is not complete, but only contains the codes that are important for the SyncML engine. 0 No error 101 Server is busy (session limit reached) 200 OK, successful operation 201 Item added 207 Conflict resolved with merge 208 Conflict resolved - client wins 209 Conflict resolved by duplicating item 210 Deleted without archive 211 Item not deleted 212 Authentication accepted for entire session 213 Chunked item accepted and buffered (this status is sent for each non-final part of a data item that has been split across multiple SyncML messages) 400 Bad request 401 Unauthorized (bad credentials) 403 Forbidden (e.g. attempt to write to a read-only database) 404 Object not found 405 Command not allowed 406 Optional feature not supported 407 Authentication required (no credentials found) 408 Timeout 409 Conflict, operation failed 410 Gone, requested object not here any more 412 Incomplete command 415 Unsupported media type or format 418 Object already exists 419 Conflict resolved with server data 420 Device full 500 Command failed 501 Command not implemented 503 Service unavailable 505 DTD version not supported 508 Slow sync required 509 Authentication required 510 Database error 511 Server error 512 Synchronisation failed 513 SyncML Version not supported Cancelled Internal Error Codes 0 No error 10000..10999 These have the same meaning as the SyncML Status Codes (see  REF _Ref47451048 \r \h 10.1), but they are offset by 10000 to make clear that they were generated internally, and not sent or received via SyncML. 20001 Bad or unknown transport protocol 20002 Fatal problem with SyncML encoder/decoder 20003 Cannot open communication 20004 Cannot send data 20005 Cannot receive data 20006 Bad content type (message received with an unknown MIME-type) 20007 Error processing incoming SyncML message (for example invalid XML or WBXML formatting) 20008 Cannot close communication 20009 Transport layer authorisation (e.g. HTTP auth) failed 20010 Error parsing XML config file 20011 Error reading config file 20012 No configuration found at all, or not enough for requested operation (client) 20013 Config file could not be found 20014 License expired or no license found 20015 Internal fatal error 20016 Bad handle 20017 Session aborted by user 20018 Invalid license 20019 Limited trial version 20020 Connection timeout 20021 Connection SSL certificate expired 20022 Connection SSL certificate invalid 20023 incomplete sync session (some datastores failed, some completed) 20025 Out of memory 20026 Connection impossible (e.g. no network available) 20027 Establishing connection failed (e.g. network layer login failure) 20028 element is already installed 20029 this build is too new for this license (need upgrading license) 20030 function not implemented 20031 this license code is valid, but not for this product (e.g. STD license used in PRO product, or client license in server product) 20032 Explicitly suspended by user 20033 this build is too old for this SDK/plugin 20034 unknown subsystem 20036 local datastore not ready 20037 session should be restarted from scratch 20038 internal pipe communication problem 20039 buffer too small for requested value 20040 value truncated to fit into field 20041 bad parameter 20042 out of range 20043 external transport failure (no details known in engine) 20044 class not registered 20500..20599 These represent SIG_xxx codes in Linux versions of the server. Unexpected SIG_xxx will generate a error code of 20500+signal_code. 20998 Internal unkown exception 20999 Unknown error 21000...21999 Database plugin module specific error codes Page  SEITE 70 © 2004 - 2009 by Synthesis AG, Zürich, Switzerland -  HYPERLINK "www.synthesis.ch" www.synthesis.ch SDK_javadb.java SDK_javadb.class uiapp.java uiapp.class VAR_boolean.class VAR_byteArray.class VAR_short.class VAR_int.class VAR_String.class DB_Callback.class ItemID.class MapID.class ModuleContext.class SessionContext.class DStoreContext.class JCallback.class JCallback.h Java SySync SDK for Java oceanblue.h / .cpp snowwhite.h / .cpp myadapter.h SySync SDK C / C++ package DLL core Example plug-in modules UI application example sysync_SDK_linux.mcp sysync_SDK_linux.mk sysync_SDK_win.mcp *_visual.vcproj sysync_SDK_mac.mcp (some of these files, depending on the platform) .... sync_dbapi_text.cpp DLL/target_options.h sync_dbapi_demo.c DLL/target_options.h DB_Interfaces UI_app_setting.cpp UI_util.h / .cpp UI_Appli-cations SDK.def dbapi_DLL.lib DLL engine_defs.h generic_types.h syerror.h sync_include.h sync_dbapidef.h sync_dbapi.h admindata.h / .cpp blobs.h / .cpp dbitem.h / .cpp SDK_util.h / .c SDK_support.h / .cpp stringutil.h / .cpp timeutil.h / .cpp enginemodulebase.h / .cpp enginemodulebridge.h / .cpp Sources CodeWarrior, Visual Studio project files / makefile UIApi DBApi Synthesis SySync Engine Customer‘s DB Plugin A Synthesis SySync Engine Customer‘s application with user interface Customer‘s DB Plugin B ()*+,-.CdÉÊÕÖ×ûüýþÿ$%lvwš›ÁÂÃÛÜ234efgŒŽÒâãúòúíúêçãçÞçÙÑÙÌÙÉ¿¼¹ú±ú®ú©ž—ˆž—ž…©CJjÞ„>*B*OJQJU 0JOJQJj0JOJQJUOJQJ0Jj;„UNHCJmH  j¥§UmH CJ j•Uje”U j°UCJmH >*CJ(CJ(CJ j£UjU jU0-.CdÉÊÖ$lßàŽÒT—< Õ - ýú÷õõõúúõõúïëéýýýéäáäÝáäá„Ä@&„Ä@&„ „ „Å$$-.CdÉÊÖ$lßàŽÒT—< Õ - ½ ¾  È  W ½ õ €®æ)q¨àVüüüüùöüüóðíèåâßÚØÕØÒÕØÕÕØÏÌÇØÂ¿º·²¯¬§¢˜“މ„zíýÿÿ'þÿÿ_þÿÿ–þÿÿÞþÿÿ!ÿÿÿYÿÿÿ‡ÿÿÿöÿÿÿ÷ÿÿÿþÿÿŒþÿÿÄþÿÿ*ÿÿÿgÿÿÿ¹ÿÿÿyÿÿÿÏÿÿÿÐÿÿÿ½ÿÿÿâýÿÿ þÿÿ!þÿÿ”ÿÿÿÜÿÿÿüÿÿÿýÿÿÿÿÿÿÿšÿÿÿ›ÿÿÿ0ãä !"RST€‘—ªòó% < W X x y z Ž ‘ µ Å Ê Õ ð ñ    + , < = j k l ‹ Œ ¥ ¼ ¾  5 6 = > d e f  öñåöÞöÛ×Ñ×Û×Ñ×ÛöñÅöÞöÛ×Û×öñ¹öÞööñ­öÞöÛ×ÛªªŸÞŸÞjш>*B*OJQJUj0JOJQJUNHjˆOJQJUjQ‡OJQJUjž†OJQJU 5CJNH5CJCJ 0JOJQJj³…OJQJUOJQJjOJQJU8- ½ ¾  È  W ½ õ €®æ)q¨àV˜Ôü÷óñï÷ïóïóïñêäääääââââàààà Æd#  & F„Ä„Ä@&@& € È Ø Ù þ ÿ   W _ ` “ ” • » ¼ õ W X ¤¥ñò@AefMN^_{|}~Œ©ª«¬­ÄÅáâãäå#$%ôñôêÛôêôñôêÌôêôññÇñÂñÂñÂñÇñÂñ½½½µ½½½­½½½¥½½½½jŒUj ŒUj£‹Uj&‹U jUCJNHCJNHjMŠ>*B*OJQJUj‰>*B*OJQJU 0JOJQJCJj0JOJQJU>%'(NOklmop…†¢£¤¦§½¾ÚÛÜÞß÷ø34PQRTUuv’“”–—±²ÎÏÐÒÓïð  23OPQSTqrŽúúòúúúêúúúâúúúÚúúúÒúúúÊúúúÂúúúºúúú²úúúj‘Uj…UjUj‹UjUj‘ŽUjŽUj—UjU jUDV˜ÔU”ÑAŠÍ!p¸í(ƒ¿þ0p¯ì4t¯é` à b›ûöñìçâÝØÓÎÉÄ¿ºµ°«¦¡œ—’ˆƒ~ytoje`[¥õÿÿçõÿÿ'öÿÿgöÿÿ§öÿÿéöÿÿ÷ÿÿX÷ÿÿ“÷ÿÿÓ÷ÿÿøÿÿXøÿÿ—øÿÿ×øÿÿ ùÿÿHùÿÿ„ùÿÿßùÿÿúÿÿOúÿÿ—úÿÿæúÿÿ:ûÿÿ}ûÿÿÆûÿÿüÿÿ6üÿÿsüÿÿ²üÿÿõüÿÿ3ýÿÿoýÿÿ±ýÿÿ!U”ÑAŠÍ!p¸í(ƒ¿þ0p¯ì4t¯é` à ýýýûûûõûûýýýóóýõûûûûûûûõûûûû Æd# Ž’“®¯ËÌÍÏÐäå;<=?@gh„…†ˆ‰ª«ÇÈÉËÌþÿ MNjklno•–²³´¶·ÊËçèéëì÷òòòêòòòâòòòÚòòòÒòòòÊòòòÂòòòºòòò²òòòªòòjä•Ujg•Ujê”Ujm”Ujð“Ujs“Ujö’Ujy’Ujü‘U jUj‘UCì"#$&'`a}~‚œ¹º»½¾ÛÜøùúüý *+,./MNjklnoŒ©ª«­®ÉÊæçèêë./023QRnoúòúúúêúúúâúúúÚúúúÒúúúÊúúúÂúúúºúúú²úúúªjÆšUjIšUjÌ™UjO™UjÒ˜UjU˜UjØ—Uj[—UjÞ–Uja–U jUCoprsŒ©ª«­®ÆÇãäåçèûü=>Z[\^_}~š›œžŸ½¾ÚÛÜÞßýþ?@\]^`axy•–—™š¶·ÓúúúòúúúêúúúâúúúÚúúúÒúúúÊúúúÂúúúºúúú²úúúj+ŸUj®žUj1žUj´Uj7UjºœUj=œUjÀ›UjC›U jUE b›ÙÚÛr»K¢iœØ$%óôQ R ³!a"b"ï"ù÷÷ùùù÷÷õõ÷õõù÷÷óñëóóóóóóóó Æ_¾$ Æd# ÓÔÕרúûOPlmnpq˜™µ¶·¹ºáâþÿ()EFGIJ€œž ¡ÞßûüýÿFGcdeghyz–—˜š›÷òòòêòòòâòòòÚòòòÒòòòÊòòòÂòòòºòòò²òòòªòòj ¤Uj£Uj£Uj–¢Uj¢Ujœ¡Uj¡Uj¢ Uj% U jUj¨ŸUC›ÙÚÛr»K¢iœØ$%óôQ R ³!a"b"ï"ð"Þ#ß#è#é#¶&J'K'v'æ'P(Q(ûöñìçâÝØÓÎÉÄ¿º·±¬©¦£ š—”‘Ž‹ƒ€}zwtnfcûÿÿùûÿÿ‚   iüÿÿ‚ ”üÿÿ•üÿÿ)ýÿÿöÿÿÿ÷ÿÿÿY  9ûÿÿ'üÿÿ(üÿÿµüÿÿ¶üÿÿdýÿÿÅþÿÿÆþÿÿ#ÿÿÿ$ÿÿÿòÿÿÿóÿÿÿ Y òñÿÿ/òÿÿkòÿÿžòÿÿóÿÿeóÿÿ¼óÿÿôÿÿLôÿÿ•ôÿÿêôÿÿ,õÿÿ-õÿÿ.õÿÿlõÿÿ%›µ¶ÒÓÔÖ×òó#$%<EFXèé¼  ! !©!¯!å!î!ó!ø! " "§"ª"K#L#u#v#w#’#“#q$t$£$¤$%%x&y& &¡&''z''’'˜'Å'Æ'ß'à'á'â'ã'ê'ù'ü'(/(úòúúúêúúÝØÓÑÑÎÑÎÑÑÑÎÑúÆúÃúÑÎÎÎÎÎÑÑú»úúÑÑj\¦U0Jj„¥UNH5OJQJmH nHjOJPJQJUmHj¥UjФU jUJï"ð"Þ#ß#è#é#¶&J'K'v'æ'P(Q(­(°(Ñ(")h)³)ä)Ø*ù+-~-.J.ýýýúýýýýýììææàÛÛÛÛÛÛÛÛÛÛÛ & Fx Æ_¾$ ƨ € & F‚„Ð Æ hШ €$/(0(I(J(K(L(M(§(¨(­(®(°(Ê(Ï(é(í(î(?)A)…)‹)*+++s+t+ù+,,, ,,G,H,œ,,--Ú-Û-Ž//(0-0.010r0s0Z1`1f1m1v11M2N222d4m45-5/56585P5S5c5Ý5Þ5e6f6´6µ6Þ6ß6j8p8v8}8†88Ç:È:Ó;Ü;ò;ù;þ;úòúúïèãßßÝßßïïßßßïïïïïÝÝïÝÝÝïÝÝÝÝÝÝïïèèÝÝÝïÝÝ55B*OJQJ jUmHNHjÙ¦U jUWQ(­(°(Ñ(")h)³)ä)Ø*ù+-~-.J.©.á.­/00s2t2S4T4÷5 6 6Z6³6´6Ü6Ý6Þ6ü÷ñéáÙÑÉÁ¹±©¡™‘‰~{xurogda^[XURÿÿÿÿÿÿCÿÿÿDÿÿÿÿÿÿìÿÿÿíÿÿÿY  ‹ïÿÿŒïÿÿkñÿÿlñÿÿÇóÿÿÈóÿÿ2ôÿÿx  þôÿÿx  6õÿÿx  •õÿÿx  Ñõÿÿx  aöÿÿx  Ëöÿÿx  æ÷ÿÿx  ùÿÿx  ûùÿÿx  ,úÿÿx  wúÿÿx  ½úÿÿx  ûÿÿx   /ûÿÿx 2ûÿÿŽûÿÿJ.©.á.­/00s2t2S4T4÷5 6 6Z6³6´6Ü6Ý6Þ6à6á6â6ã6ä6å6æ6ç6è6é6úúúúøøøøøøöøøøøøøøøøøøøøøøøø & FxÞ6à6á6â6ã6ä6å6æ6ç6è6é6ê6ë6ì6í6î6ï6ð6ñ6ò6ó6ô6õ6ö6÷6ø6ù6ú6û6ü6ý6þ6ÿ677777‹7Œ78888å9æ9üùöóðíêçäáÞÛØÕÒÏÌÉÆÃÀ½º·´±®«¨¥¢Ÿœ™–“Ї„|yvsþÿÿâÿÿÿãÿÿÿY  ÷ýÿÿkþÿÿlþÿÿóþÿÿôþÿÿõþÿÿöþÿÿ÷þÿÿøþÿÿùþÿÿúþÿÿûþÿÿüþÿÿýþÿÿþþÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿ ÿÿÿ ÿÿÿ ÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ-é6ê6ë6ì6í6î6ï6ð6ñ6ò6ó6ô6õ6ö6÷6ø6ù6ú6û6ü6ý6þ6ÿ677777‹7Œ7ýýýýýýýýýýýýýýýýýýýýýýýýýýýýýŒ78888å9æ9:<<»<¼<s=t=H>I>Ï>Ð>ð?ñ?E@F@G@W@n@@•@«@Ä@Û@ýýûýýýùýýýýýýýýýýýýýýùýóýýýý Æ_¾$æ9:<<»<¼<s=t=H>I>Ï>Ð>ð?ñ?E@F@G@W@n@@•@«@Ä@Û@Ü@4A5A6A7A¡B8C9C%DMENE¤F¥FÁFùF;GwG³GòGôñîëèåâßÜÙÖÓÐÍʼ¹´±®«¨¥¢Ÿœ™–“Ї„|yvspm”øÿÿÐøÿÿ ùÿÿNùÿÿ†ùÿÿ¢ùÿÿ£ùÿÿùúÿÿúúÿÿ"üÿÿýÿÿýÿÿ¦ýÿÿÿÿÿÿÿÿÿÿÿÿÿÿkÿÿÿlÿÿÿƒÿÿÿœÿÿÿ²ÿÿÿÈÿÿÿÙÿÿÿðÿÿÿº÷ÿÿY   º÷ÿÿ ùÿÿ¡ùÿÿõùÿÿöùÿÿûÿÿûÿÿûÿÿžûÿÿrüÿÿsüÿÿ*ýÿÿ+ýÿÿªýÿÿßÿÿÿþÿÿY  þÿÿ)þ;<n<‹<”<•<™<š<³<´<µ<¸<¹<´=º=*>+>_>f>ï>ø>Y@n@@Æ@Ú@µAÉAõA BCCpExE_F`FbFcF¤F¥F¿FòFóFI.I/I0IwIxII†I×IØIKK”K™KòKóKÓLèLýLMMM1OFOP–PðRñRUU2U7U@UDU_VmV«V¬VW#WhWvWˆWšW›W¡WWXýûøóëóóýøýýûæûûûøýøøæýøýýøýøøýøûûâûûûøýýýýøûûææýB*NHOJQJjV§U jUNHB*5YÛ@Ü@4A5A6A7A¡B8C9C%DMENE¤F¥FÁFùF;GwG³GòGóG/HkH¡HÙHIII€Iýýýýýýýýýýýý÷ýýýýýýýýýýýýýýý Æ_¾$òGóG/HkH¡HÙHIII€IIJJ“J”J¥J“K”KûKüKM±M²M.O/OGO`OaO{O“O¬OÉOÊOãOäOÿOP*P+PHPcPP—P˜P™PüùöóðíêçäáÞÛØÕÇÄÁ¾»¸µ²¯¬©¦£ š—”‘Ž‹ˆ…‚|yvspüùÿÿýùÿÿúÿÿ1úÿÿLúÿÿiúÿÿjúÿÿ€úÿÿ•úÿÿ°úÿÿ±úÿÿÊúÿÿËúÿÿèúÿÿûÿÿûÿÿ3ûÿÿ4ûÿÿMûÿÿeûÿÿfûÿÿâüÿÿãüÿÿ~ýÿÿ˜þÿÿ™þÿÿÿÿÿÿÿÿïÿÿÿmíÿÿY   míÿÿ´õÿÿ5öÿÿ6öÿÿÆöÿÿÇöÿÿ0÷ÿÿ1÷ÿÿ2÷ÿÿn÷ÿÿ¦÷ÿÿÜ÷ÿÿøÿÿTøÿÿUøÿÿ,€IIJJ“J”J¥J“K”KûKüKM±M²M.O/OGO`OaO{O“O¬OÉOÊOãOäOÿOP*P+Pýýýýýûýýýýýýýýýýýýýýýýýýýýýýý+PHPcPP—P˜P™PéPêPEQšQ›QëQìQIR R¡RöR:S;S*OJQJOJQJNH[^[_[3\\Ž\\¨\³]ì]í]B^C^S^e^f^Ã^__ª_«_¬_¿_ ` ``/`F`V`j`{`‰`Š`Û`-a.a€aÇab`babzb{büùöóðâßÜÙÖÓÐÍÊÇÄÁ¾»¸ª§¤¡ž›–“Ї„~{xurol2ýÿÿKýÿÿLýÿÿšýÿÿåýÿÿ,þÿÿ~þÿÿþÿÿÑþÿÿ"ÿÿÿ#ÿÿÿ1ÿÿÿBÿÿÿVÿÿÿfÿÿÿ}ÿÿÿÿÿÿ ÿÿÿ¡ÿÿÿíÿÿÿ‘óÿÿY   ‘óÿÿäüÿÿåüÿÿvýÿÿwýÿÿÌýÿÿ)þÿÿ*þÿÿ<þÿÿLþÿÿMþÿÿ¢þÿÿ£þÿÿÜþÿÿçÿÿÿ®öÿÿY   ®öÿÿ[úÿÿ\úÿÿ¶úÿÿŠûÿÿ‹ûÿÿ)í]B^C^S^e^f^Ã^__ª_«_¬_¿_ ` ``/`F`V`j`{`‰`Š`Û`-a.a€aÇabýýýýýýýýýýýûýýýýýõýýýýýýýýýý Æ_¾$b`babzb{bÔbôbõbþb c4c5cQcqc•c¡c¢cYdüdýdifjf”f-gkglg¦gýýùýýýýýýñýýñýíýýýýýýýèääß & FÙ„h & F؄ńŠÆ_¾$„Å{bÔbôbõbþb c4c5cQcqc•c¡c¢cYdüdýdifjf”f-gkglg¦g»g¼gˆi‰iŠiŸi.j/j@jRjhjzjŒj¢j­jºjÊjÜjïjþjüùöóðëèåàÝÚ×ÔÑÎËÈÅ¿¼¹³°­ª§¤–“Ї„~{xurol›þÿÿ®þÿÿÀþÿÿÐþÿÿÝþÿÿèþÿÿþþÿÿÿÿÿ"ÿÿÿ8ÿÿÿJÿÿÿ[ÿÿÿ\ÿÿÿëÿÿÿ³éÿÿY   ³éÿÿ#öÿÿ$öÿÿð÷ÿÿñ÷ÿÿøÿÿ @øÿÿÙ Aøÿÿøÿÿ ùÿÿØ BùÿÿCùÿÿ¯úÿÿ°úÿÿSûÿÿ üÿÿ üÿÿüÿÿ;üÿÿ[üÿÿwüÿÿxüÿÿ¡üÿÿ®üÿÿ·üÿÿ¸üÿÿØüÿÿ1ýÿÿ*¦g»g¼gˆi‰iŠiŸi.j/j@jRjhjzjŒj¢j­jºjÊjÜjïjþjÿjPk¢k£kNlompm|nûùùùù÷ùùùùùùùùùùùùùùùùùùùùùù„hþjÿjPk¢k£kNlompm|n}n—nožo®o¾oÎoÞoßo¯u¯Ž¯¯Â¯Ã¯¦°§°¨°üùöóðëæáÜÎËÈÁ¹±®«¨š—”‘Ž‹ˆ…‚|yvspmjgd’ùÿÿ“ùÿÿvúÿÿwúÿÿªúÿÿ«úÿÿÄúÿÿûúÿÿüúÿÿûÿÿ>ûÿÿ?ûÿÿ·üÿÿýÿÿýÿÿøýÿÿùýÿÿîÿÿÿCôÿÿY   Côÿÿ{ýÿÿþÿÿþÿÿ…þÿÿ„  íþÿÿ„   b\ÿÿÿ„ ]ÿÿÿôÿÿÿÉöÿÿY   Éöÿÿˆøÿÿ‰øÿÿÏøÿÿÐøÿÿÒøÿÿßøÿÿùÿÿ6ùÿÿ;ùÿÿ%Kª@¬A¬&­'­‚­ú®û®'¯=¯>¯u¯Ž¯¯Â¯Ã¯¦°§°¨°Ø°Ö±×±²A²B²s²£²Ä² ³ýýýýýýýýýýýýýýýýýýûýýóóóóóóó„hH$7$8$Ÿ® ®¹®º®»®¾®¿®Ü®Ý®×±s²£²Ä²ü²³ ³³$³d³f³¬³®³î³ð³4´6´G´I´N´ª´º´Ï´ö´µ)µ-µ3µEµYµhµjµ¥µÅµÉµþµ¶2¶6¶R¶V¶¶í¶ø¶ ·?·E·K·W·_·j·¯·ó·¸¸A¸d¸v¸|¸‚¸”¸¨¸¿¸¹h¹j¹…¹¶¹úòúúïãØãØÌØÀØãØãØãØãØãØÀØÌØãØãØÀØãØÀØãØãØãØãØãØÌØãØÀØãØãØÌØãØãØÀØãØãØÀØãB*CJOJPJQJmHB* CJOJPJQJmHCJOJPJQJmHB* CJOJPJQJmHNHj¥©U jUL¨°Ø°Ö±×±²A²B²s²£²Ä² ³"³d³¬³î³4´G´_´m´‡´”´¦´¼´ö´)µYµaµfµ¡µÅµþµ2¶R¶¶§¶Ä¶Ó¶ç¶ú¶·?·_·f·¯·Ê·ôñîëèåâßÜÙÖÓÐÍÊÇÄÁ¾»¸µ²¯¬©¦£ š—”‘Ž‹ˆ…‚|yvsùøÿÿBùÿÿIùÿÿiùÿÿšùÿÿ®ùÿÿÁùÿÿÕùÿÿäùÿÿúÿÿúÿÿVúÿÿvúÿÿªúÿÿãúÿÿûÿÿBûÿÿGûÿÿOûÿÿûÿÿ²ûÿÿìûÿÿüÿÿüÿÿ!üÿÿ;üÿÿIüÿÿaüÿÿtüÿÿºüÿÿüüÿÿDýÿÿ†ýÿÿœýÿÿäýÿÿþÿÿ5þÿÿfþÿÿgþÿÿ‰þÿÿÑþÿÿÒþÿÿÐÿÿÿ‘ùÿÿY  ‘ùÿÿ, ³"³d³¬³î³4´G´_´m´‡´”´¦´¼´ö´)µYµaµfµ¡µÅµþµ2¶R¶¶§¶Ä¶Ó¶ç¶ú¶÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷„hH$7$8$ú¶·?·_·f·¯·Ê·Ù·í·¸A¸v¸¨¸²¸¹¸½¸¹%¹a¹f¹¹¶¹Ó¹ºº6º]ºˆº¤º÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷„hH$7$8$Ê·Ù·í·¸A¸v¸¨¸²¸¹¸½¸¹%¹a¹f¹¹¶¹Ó¹ºº6º]ºˆº¤ºªº®ºÛºõº2»6»V»»ƒ»„»…»–»ƒ¾î¾ï¾¶¿`ÀÁüùöóðíêçäáÞÛØÕÒÏÌÉÆÃÀ½º·´±®«¨¥¢ŸœŽ‹ˆ…wo%ûÿÿ…  Ïûÿÿ…   –üÿÿ… —üÿÿýÿÿïÿÿÿ´îÿÿY   ´îÿÿ$õÿÿ%õÿÿ'õÿÿRõÿÿrõÿÿvõÿÿ³õÿÿÍõÿÿúõÿÿþõÿÿöÿÿ öÿÿKöÿÿröÿÿŠöÿÿ‘öÿÿÕöÿÿòöÿÿ'÷ÿÿB÷ÿÿG÷ÿÿƒ÷ÿÿ ÷ÿÿë÷ÿÿï÷ÿÿö÷ÿÿøÿÿ2øÿÿgøÿÿ£øÿÿ»øÿÿÏøÿÿÞøÿÿ(¶¹ º"º<º]ºcºˆº—º¤º°º²ºßºõº!»2»8»V»…»–»ö»÷»W¼X¼‘¼˜¼É½Ê½ó½ô½õ½¾¾Ë¾Ì¾å¾æ¾ç¾ê¾ë¾î¾°¿±¿¶¿:À;ÀTÀUÀVÀ]À^À_ÀÁ·Á¸Á›œÂ^ßĠģťÅƸÊ=Ë>ËõéõÝõÝõÝõéõÝõÝõÝõÚÕÚÕÚÑÚÌÄÌÁÌ̹ÌÌÚÕÚ̱ÌÌÚÚÚÚÚÕÚ¬¬©NHOJQJjw«UjúªU0Jj"ªU jU6mHNHmHmHB* CJOJPJQJmHB*CJOJPJQJmHCJOJPJQJmHB¤ºªº®ºÛºõº2»6»V»»ƒ»„»…»–»ƒ¾î¾ï¾¶¿`ÀÁ¸Áœ›ÃAÄBÄ÷÷÷÷÷÷÷÷÷÷÷õóóóêêêááÚÚÓó & F…*$ & F…*$ & F…*$„›þ & F…*$„›þ„hH$7$8$Á¸Áœ›ÃAÄBģŤťŻÅñÅÆgÆGÈ3É­É¸ÊæÊçÊDËEˇ˩˪ËÀËÏËñËöêáÕÌÉÆÁ¼®«¥›ƒvia^[XUROLIFÖùÿÿåùÿÿûùÿÿüùÿÿúÿÿ`úÿÿaúÿÿ¾úÿÿ¿úÿÿíúÿÿ†  øûÿÿ†   püÿÿrüÿÿ†   êüÿÿ^ýÿÿ†   Öýÿÿ>ÿÿÿ†  ¶ÿÿÿˆÿÿÿ†   ´ÿÿÿ† êÿÿÿרÿÿY   רÿÿáõÿÿâõÿÿC÷ÿÿD÷ÿÿê÷ÿÿ…  ÿÿÿéøÿÿ…   ÿÿÿuùÿÿ…  ¨ÿÿÿÍùÿÿ…   ¨þÿÿsúÿÿ…  NÿÿÿBģŤťŻÅñÅÆgÆGÈ3É­É¸ÊæÊçÊDËEˇ˩˪ËÀËÏËñËý÷÷õýæ×ÌÌÌÌÃýýý»»»»»»„hH$7$8$ & F†¤<¤<  & F†*$¤<¤< & F†*$„Ê„›þ¤<¤< & F†*$„Ê„›þ¤<¤< Æ_¾$>ËEËÏËAÌOÌTÌsÌxÌ‹Ì̬ÌÂÌñÌÍÍÍÍ)Í5ÍGÍIÍNÍ`ͩͫÍÂÍáÍÎÎ Î1Î5Î;ÎNÎRÎgΌδιÎÁÎÅÎàÎýÎÏ8Ï@ÏBÏxÏÝÏSÐUÐuЛÐúÐÑ&ÑMÑtцѤѸÑëÑÒZÒ^Òj҂ҌҬÒÞÒãÒëÒïÒÓ^ÓfÓkÓsÓwÓ‘ÓÚÓâÓ'ÔóèóÜèÜèÜèóèÐèÜèóèóÜèóèÜèóèÜèóèÜèÜèóèÜèÜèóèóèÜèóèÜèóèÐèóèóèóèóèÜèóèóèÜèÜèóèÜèÜèóèóB* CJOJPJQJmHB*CJOJPJQJmHCJOJPJQJmHB* CJOJPJQJmHRñË ÌÌOÌs̬̋ÌÂÌÍÍ)Í3Í5ÍGÍLÍ`ͧͿÍáÍûÍÿÍÎ1ÎHÎ_ÎŒÎ¬Î»ÎØÎýÎ8ÏnÏ®ÏÝÏÿÏIÐiЛкÐÑÐìÐ ÑMцѸÑÐÑßÑüùöóðíêçäáÞÛØÕÒÏÌÉÆÃÀ½º·´±®«¨¥¢Ÿœ™–“Ї„~{xuÕóÿÿíóÿÿôÿÿXôÿÿ›ôÿÿ¹ôÿÿÔôÿÿëôÿÿ õÿÿ<õÿÿ\õÿÿ¦õÿÿÈõÿÿ÷õÿÿ7öÿÿmöÿÿ¨öÿÿÍöÿÿêöÿÿùöÿÿ÷ÿÿF÷ÿÿ]÷ÿÿt÷ÿÿ÷ÿÿ¦÷ÿÿª÷ÿÿÄ÷ÿÿæ÷ÿÿþ÷ÿÿEøÿÿYøÿÿ^øÿÿpøÿÿrøÿÿ|øÿÿŒøÿÿ¢øÿÿãøÿÿùøÿÿùÿÿ2ùÿÿVùÿÿŠùÿÿ˜ùÿÿ´ùÿÿ.ñË ÌÌOÌs̬̋ÌÂÌÍÍ)Í3Í5ÍGÍLÍ`ͧͿÍáÍûÍÿÍÎ1ÎHÎ_ÎŒÎ¬Î»ÎØÎ÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷„hH$7$8$ØÎýÎ8ÏnÏ®ÏÝÏÿÏIÐiЛкÐÑÐìÐ ÑMцѸÑÐÑßÑ Ò<ÒHÒRÒaÒ‚Ò¬Ò¶ÒÖÒåÒ÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷„hH$7$8$ßÑ Ò<ÒHÒRÒaÒ‚Ò¬Ò¶ÒÖÒåÒÿÒ<Ó^ÓmÓ‰ÓÚÓ'ÔVÔvÔ„Ô¡ÔÀÔÁÔÕVÕ§ÕêÕ)Ö*ÖJÖ•ÖÜÖéÖ5×C×`×–×—×â×2ØmØnØŽØÙØ Ù-ÙüùöóðíêçäáÞÛØÕÒÏÌÉÆÃÀ½º·´±®«¨¥¢Ÿœ™–“Ї„~{xu…ìÿÿÌìÿÿíÿÿ7íÿÿ8íÿÿsíÿÿÃíÿÿîÿÿîÿÿEîÿÿbîÿÿpîÿÿ¼îÿÿÉîÿÿïÿÿ[ïÿÿ{ïÿÿ|ïÿÿ»ïÿÿþïÿÿOðÿÿ—ðÿÿäðÿÿåðÿÿñÿÿ!ñÿÿ/ñÿÿOñÿÿ~ñÿÿËñÿÿòÿÿ8òÿÿGòÿÿiòÿÿ¦òÿÿÀòÿÿÏòÿÿïòÿÿùòÿÿ#óÿÿDóÿÿSóÿÿ]óÿÿióÿÿšóÿÿÆóÿÿ.åÒÿÒ<Ó^ÓmÓ‰ÓÚÓ'ÔVÔvÔ„Ô¡ÔÀÔÁÔÕVÕ§ÕêÕ)Ö*ÖJÖ•ÖÜÖéÖ5×C×`×–×—×÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷„hH$7$8$'Ô/ÔVÔ}Ô‚ÔŠÔŽÔ©ÔÁÔÉÔVÕ^Õ§Õ¯Õ*Ö2ÖJÖRÖTÖVÖ[Ö\Ö”Ö»ÖÜÖäÖéÖ×5×<×A×I×M×hחן×nØvØŽØ–Ø˜ØšØŸØ ØØØþØ Ù(Ù-ÙUÙyÙنَ٠٦ÙîÙðÙòÙôÙùÙúÙ2ÚZÚ\Ú^ÚcÚdÚšÚÁÚòÚôÚùÚ-ÛSÛ‚ÛùÜúÜÿܱÝõéõÝõÝõéõéõéõéõéõÝõÝõéõéõÝõéõÝõÝõéõéõéõÝõÝõéõéõÝõéõÝõéõéõÝõÝõéõÝõÝõéõéõÝõÑõÎÌ5mHB* CJOJPJQJmHB*CJOJPJQJmHB* CJOJPJQJmHCJOJPJQJmHO—×â×2ØmØnØŽØÙØ Ù-Ùyو٠٤ÙîÙ6ÚUÚXÚžÚ»Ú¿ÚòÚ-ÛSÛ‚ÛƒÛùÜúÜÒÝÞÝ÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷õõõõó„hH$7$8$-Ùyو٠٤ÙîÙ6ÚUÚXÚžÚ»Ú¿ÚòÚ-ÛSÛ‚ÛƒÛùÜúÜÒÝÞÝßÝÞÞÛÞÜÞBàCàDà]à=á>á²á³áPâQâ»â¼â´ãµãÊãüùöóðíêçäáÞÛØÕÒÏÌÉÆ¾»¸±¬§˜“‡„~{xurolifüÿÿüÿÿˆýÿÿ‰ýÿÿóýÿÿôýÿÿ‘þÿÿ’þÿÿÿÿÿÿÿÿçÿÿÿŽýÿÿY  Žýÿÿbýÿÿbýÿÿböþÿÿk  b÷þÿÿbSÿÿÿ bÃÿÿÿk óÿÿÿôÿÿÿY  «èÿÿ¬èÿÿ"êÿÿ#êÿÿRêÿÿxêÿÿ³êÿÿæêÿÿêêÿÿëÿÿMëÿÿPëÿÿoëÿÿ·ëÿÿìÿÿìÿÿìÿÿ,ìÿÿxìÿÿ(±Ý²ÝÞÞÞ0Þ1ÞEÞFÞIÞJÞmÞrÞÞ‡ÞˆÞ¡Þ¢Þ£Þ¦Þ§Þ¨ÞÕÞÙÞàÞáÞŽßßèßéß,à-à]àsà«à²à´à¹à¾àÄàBáIáXáfá·á¼á*â.âUâ[â\âaâzã{ãÛãîãïãä½åÉåìæòæ6ç7çç‚ç’ç“ç\è]èíêùêçëõëì ì&ì/ìƒì†ìÁíýûôûêûôûôæûôûÜôûôûæÙýýý×ææææ×æ×æ×ýÒÐÐ×ýýýý××××Ì5B*>*OJQJ5NHjo¬6U5B*jô«6U j6U6NHPÞÝßÝÞÞÛÞÜÞBàCàDà]à=á>á²á³áPâQâ»â¼â´ãµãÊãÛãîãïã¼å½åýýûôïûïïíýýýýýýýýýýééáýÜØ„h & Fy„Å Æ_¾$„Åb & Fb & F„hbÊãÛãîãïã¼å½åëæìæ²ç³çjèŸèééébé÷éMêNêÉêÊê%ì&ìIìoìpìÈíÉíyîÉîÊîëîìîíîïýïþï-ð.ð/ðü÷ôîëãàÝÚ×ÔÑÎÀ½º·´±®«¨¥¢Ÿœ™–“Їyvsnkh¿þÿÿÀþÿÿ`ïþÿÿðþÿÿêÿÿÿåîÿÿY   åîÿÿúÿÿúÿÿ:úÿÿ;úÿÿ‹úÿÿ;ûÿÿ<ûÿÿ”üÿÿ•üÿÿ»üÿÿÞüÿÿßüÿÿ:þÿÿ;þÿÿ¶þÿÿ·þÿÿ ÿÿÿ¢ÿÿÿèÿÿÿÎôÿÿY   ÎôÿÿA÷ÿÿ¥÷ÿÿÚ÷ÿÿ‘øÿÿ’øÿÿXùÿÿYùÿÿ‡úÿÿy  ˆúÿÿ Uüÿÿy Vüÿÿiüÿÿzüÿÿ'½åëæìæ²ç³çjèŸèééébé÷éMêNêÉêÊê%ì&ìIìoìpìÈíÉíyîÉîÊîëîìîúøòøøøøøðøøøøøøøøøêøøøøøøøø„ńńT„qü & FyÁíÂíÍíÜí$î%îÊîÒîþï-ð.ð9ðJñKñ†ññò‚òOôRô™ôšôùôúôdömö÷÷Ò÷Ó÷_ø`ø´ø ù3ú;úÞûçûhüiü¶ü¼üäüüü+þ0þMþ[þ~þþ‡þ›þÂþÊþÉÿÑÿíÿžŸ¦Ñ%DUŽ 34:;6 = > F J O P ýûýûöûýûóïýýûýýýöíûýûûûûýûííæöíãûûýÝÓËÁËÓËB* CJOJQJhCJOJQJhB*CJOJQJh OJQJhCJ CJOJQJ>*5B*NHkOJQJ5NHLìîíîïýïþï-ð.ð/ð9ð…ð†ð§ðèð}ñ~ñ³ñíñò ò’òÛò,ó-ó†ó ôÿôõ›õ[öýûýý÷ýýýýýûýýýýýýóýýýýýýýýýý„Ä`¤/ð9ð…ð†ð§ðèð}ñ~ñ³ñíñò ò’òÛò,ó-ó†ó ôÿôõ›õ[ö\ö ÷m÷n÷‡÷Ü÷Ý÷øø³ø´ø ùjù2ú3úOú¬ú­úÛúÜúüùöèåâßÜÙÖÓÐÍÊÇÄÁ¾»¸µ²¯¬©›˜•’Œ‰„~{xurol“üÿÿÁüÿÿÂüÿÿýÿÿ;ýÿÿ<ýÿÿþÿÿeþÿÿºþÿÿ»þÿÿlÿÿÿmÿÿÿ‘ÿÿÿ’ÿÿÿçÿÿÿdæÿÿY   dæÿÿùÿÿyùÿÿ*úÿÿ+úÿÿëúÿÿ†ûÿÿ‡ûÿÿæûÿÿýÿÿYýÿÿZýÿÿ«ýÿÿôýÿÿfþÿÿgþÿÿ™þÿÿÓþÿÿÿÿÿ ÿÿÿžÿÿÿßÿÿÿLíÿÿY   Líÿÿhþÿÿ´þÿÿ¾þÿÿ)[ö\ö ÷m÷n÷‡÷Ü÷Ý÷øø³ø´ø ùjù2ú3úOú¬ú­úÛúÜúûÏûÐû üvüwüµü¶üýýýýûýýýýýýõýýýýýýýýýýýýýýýý Æ_¾$ÜúûÏûÐû üvüwüµü¶ü*þ+þ…þ†þ‡þÁþÂþÖþ×þ#ÿ$ÿ9ÿÈÿÉÿìÿíÿ,D}~–²þ)UVrŽüùöóðíêçäáÞÛØÕÒÏÌÉÆ¸µ²¯¬§¢˜“މ„zupkf²ýÿÿÎýÿÿÏýÿÿûýÿÿ&þÿÿrþÿÿŽþÿÿ¦þÿÿ§þÿÿàþÿÿøþÿÿÿÿÿÿÿÿ7ÿÿÿ8ÿÿÿ[ÿÿÿ\ÿÿÿëÿÿÿ®ÞÿÿY   ®ÞÿÿKøÿÿ—øÿÿ˜øÿÿ¬øÿÿ­øÿÿçøÿÿèøÿÿéøÿÿCùÿÿDùÿÿ¸úÿÿ¹úÿÿ÷úÿÿøúÿÿdûÿÿžûÿÿŸûÿÿáûÿÿ’üÿÿ&¶ü*þ+þ…þ†þ‡þÁþÂþÖþ×þ#ÿ$ÿ9ÿÈÿÉÿìÿíÿ,D}~–²þ)UVýýýýýýýýýýýûøýýýöööööööööööö*$VrŽªÆâþÿ4ižŸÑÒö÷6opƒ›·Ù-.9Dýýýýýýýýýý÷õóóóóóóóóóóóóóóóóU Æ_¾$ŽªÆâþÿ4ižŸÑÒö÷6opƒ›·Ù-.9De}™ÆÚÛÜøûöñìçâÝØÓÐËÆÁ¼·²­¨£ž™”Š…€{vqlgb]XUHúÿÿUIúÿÿUJúÿÿU^úÿÿU‹úÿÿU§úÿÿU¿úÿÿUàúÿÿUëúÿÿUöúÿÿU÷úÿÿU ûÿÿUKûÿÿUmûÿÿU‰ûÿÿU¡ûÿÿU´ûÿÿUµûÿÿUîûÿÿUüÿÿU-üÿÿU.üÿÿURüÿÿUSüÿÿ…üÿÿ†üÿÿ»üÿÿðüÿÿ%ýÿÿ&ýÿÿBýÿÿ^ýÿÿzýÿÿ–ýÿÿ"De}™ÆÚÛÜø0Lh„…ºï$%×;NûO•–6 7 8 F ýýýýýýýýýýýýýýýýýýûûùûûûûûûûûUø0Lh„…ºï$%×;NûO•–6 7 8 F H x y ¥ Ñ Ò Û Ü 4 `   è + „ ° í ð ù û ûöñìçâÝØÓÎËȺ·´±®«¨¥¢Ÿœ™–“Ї„~{xuroliBûÿÿKûÿÿNûÿÿ‹ûÿÿ·ûÿÿüÿÿSüÿÿ›üÿÿÛüÿÿýÿÿ_ýÿÿ`ýÿÿiýÿÿjýÿÿ–ýÿÿÂýÿÿÃýÿÿóýÿÿõýÿÿþÿÿþÿÿþÿÿ¥þÿÿ¦þÿÿìþÿÿ@ÿÿÿíÿÿÿ—ÖÿÿY   —ÖÿÿMøÿÿÿøÿÿUùÿÿU5ùÿÿUjùÿÿUŸùÿÿU ùÿÿU¼ùÿÿUØùÿÿUôùÿÿUúÿÿU,úÿÿ(F H x y ¥ Ñ Ò Û Ü 4 `   è + „ ° í ð ù û ü ý þ ¥ ¦ ¿ Á ë ì H ýýýýýýýýýýýýýýýýýýýýýýýýýýýýýP V a v {  ‚ ƒ „  ’ • – ¡ § ­ ® ¹ ¾ Á  Í Ô Ü Þ 6 7 @ K Q R X Y ` b j } €  • Ï Õ     Z ` n t ‡  › ¡ ¢ ¨ © ° ² º Í Ð Ñ å ì í ù ú þ ¥ ¦ ¬ ­ ² ³ öîäîÚîöÎöîÚîöîÚîöîÚîöîÄîÄîöîÚîÚîÚîöîÚîöîöîÚîöîöîöîöîÚîÚîÚîöîÚîöîÁÄî»»ÚîÚî OJQJhCJB* CJOJQJhB* CJNHOJQJhB*CJOJQJhB* CJOJQJhCJOJQJhB* CJOJQJhJû ü ý þ ¥ ¦ ¿ Á ë ì H I o  Æ è c޳ÈÉÒÔÕäå^_•–¼½56IJž)üùöóðíêçäáÞÛØÕÒÏÌÉÆÃÀ½º·´¬§›˜•’Œ‰†ƒ€}zwtqnGùÿÿ›ùÿÿœùÿÿãùÿÿäùÿÿ¯úÿÿ°úÿÿÞúÿÿ(ûÿÿ)ûÿÿOûÿÿPûÿÿ†ýÿÿ‡ýÿÿåÿÿÿðÿÿÿY  ðÿÿÿUñÿÿÿY  gøÿÿiøÿÿrøÿÿsøÿÿˆøÿÿ­øÿÿ®øÿÿØøÿÿ)ùÿÿSùÿÿuùÿÿyùÿÿÌùÿÿòùÿÿóùÿÿOúÿÿPúÿÿzúÿÿ|úÿÿ•úÿÿ–úÿÿ=ûÿÿ>ûÿÿ?ûÿÿ@ûÿÿ+³ ¿ à ì ö ÷ ÿ      - 3 9 I o w x €  “ ” ¨ ® ´ Ê Ð û  %,-78?ouvˆ’˜œŸ·ÇÈÒÓÔÕäåÔÕ_grs78]cij«º½ÐMaöîäÚîöîöîÚîöîöîäÚîöîÚîöîöîöîöîöÎöîöîÚîöîÚîÚîäîäîÈîÅÃÀÃÀÀÀÃüÃÃ5B*NH5CJ OJQJhB* CJNHOJQJhB*CJOJQJhB* CJOJQJhCJOJQJhB* CJOJQJhJH I o  Æ è c޳ÈÉÒÔÕäå^_•–¼½56ýýýýýýýýýýýýýýýûù÷ýýýýýýýýññ„ „íôUa†‡ I\–—§*7hiv|§²úûœû QYƒ†ˆ‰@QYZ[hkxðó WYbcœžª«ãõabiwÎál®¯Úß:;o†ÄÎ$=G\]­ » -!.!Þ!ß!æ!ð!ýûûýûûýûûûûûûûûýûûû÷ûûûûõýûûíæûýûûýûûûýûûûûûûýýû CJOJQJ5CJOJQJH*5NH5NH[IJž)*vwúûŽûüQRˆ‰jkðñòó  ùùùùùùùùùùùùùùùùùùùùùùùùùù÷õ„ „íô)*vwúûŽûüQRˆ‰jkðñòó  œ«âãij¶·%&k®¯no\]^_`üùöóðíêçäáÞÛØÕÒÏÌÉÆÃÀ²¯¬©¦£ š—”‘Ž‹ˆ…‚|yvsp”ûÿÿ•ûÿÿ–ûÿÿ—ûÿÿ„üÿÿ…üÿÿDýÿÿEýÿÿˆýÿÿÍýÿÿÎýÿÿ<þÿÿ=þÿÿ‰þÿÿŠþÿÿÿÿÿÿÿÿHÿÿÿVÿÿÿWÿÿÿæÿÿÿçÿÿÿâôÿÿY   âôÿÿóôÿÿôôÿÿõôÿÿzõÿÿ{õÿÿËõÿÿÌõÿÿ\öÿÿ]öÿÿ“öÿÿ”öÿÿéöÿÿêöÿÿV÷ÿÿW÷ÿÿê÷ÿÿë÷ÿÿnøÿÿoøÿÿ»øÿÿ¼øÿÿ, œ«âãij¶·%&k®¯no\]^_`abcde~ ùùùõõùùùùùùùùùùùùùùùùùùùùùóù„ „ „íô`abcde~    © ª é ê æ!""Š"‹"9#:#Ê#Ë#ä#$$N$O$½$¾$ä$å$F%G%H%Š%¦%§%¹%º%üùöóðâßÜÙÖÓÐÍÊÇÄÁ¾»¸µ²¯¡ßž›˜•’Œ‰†ƒ€xuifîÿÿÿãÿÿÿY  ãÿÿÿäÿÿÿY  ƒþÿÿ„þÿÿ…þÿÿæþÿÿçþÿÿ ÿÿÿÿÿÿ|ÿÿÿ}ÿÿÿ¬ÿÿÿ­ÿÿÿ ëÿÿY   ëÿÿ›úÿÿ+ûÿÿ,ûÿÿÚûÿÿÛûÿÿIüÿÿJüÿÿüÿÿ{ýÿÿ|ýÿÿ»ýÿÿ¼ýÿÿOþÿÿPþÿÿZÿÿÿ\ÿÿÿçÿÿÿpðÿÿY   pðÿÿûÿÿûÿÿ‘ûÿÿ’ûÿÿ“ûÿÿ(    © ª é ê æ!""Š"‹"9#:#Ê#Ë#ä#$$N$O$½$¾$ä$å$F%G%H%ùõùùùùùùóùùóùùùùñùùùùùóùùùùù„ „ „íôð!3"F"k"l"‹"š"9#G#‰#Š#ñ#ü#$*$N$O$f$z$ž$Ÿ$½$¾$å$ï$º%Â%Ã%×%Ù%á%í%ö%& &&&&&.&9&?&G&H&V&X&`&k&s&t&‡&‰&‘&œ&¤&µ&½&¾&Ñ&Ó&Û&æ&ï&ÿ&' ' ''-'/'7'P'X'Y'm'o'w'ƒ'‹'Œ'¡'£'«'·'À'Î'Ù'ß'ç'è'ù'û'((($(,(:(B(P(ýúýýúýýýýúýýýýýýýúýýýýýýýýýýýýýýúýýýýýýýýýýýýýýýýNH5cH%Š%¦%§%¹%º%?&k&µ&'P'‚'ƒ'ß'd(Î( )M)˜)à)*x*¤*Þ*+e+˜+™+,ýûýùý÷÷÷÷÷÷ò÷÷÷÷÷÷÷÷÷÷÷÷÷÷ò÷‘ & F‘º%?&k&µ&'P'‚'ƒ'ß'd(Î( )M)˜)à)*x*¤*Þ*+e+øîäÚÐÆÁ·­£™…{qg]SI?‘•úÿÿˆ  ‘Éúÿÿˆ  ‘ûÿÿˆ  ‘/ûÿÿˆ  ‘—ûÿÿˆ  ‘Çûÿÿˆ  ‘üÿÿˆ  ‘Züÿÿˆ  ‘šüÿÿˆ  ‘Ùüÿÿˆ  ‘Cýÿÿˆ  ‘Èýÿÿˆ  ‘$þÿÿˆ  ‘%þÿÿ‘Wþÿÿˆ  ‘þÿÿˆ  ‘òþÿÿˆ  ‘<ÿÿÿˆ  ‘hÿÿÿˆ   ‘íÿÿÿˆ P(V(d(l(m(€(‚(Š(•(ž(ª(²(½(Å(Î(Ö(×(ç(é(ñ(ü() )))')))1)<)E)M)U)V)l)n)v))Š)˜) )¡)²)´)¼)Ç)Ï)à)æ)ç)û)ý)****&*(*0*;*D*P*X*e*m*x*€***‘*™*©*»*½*Å*ã*ý*ÿ*++(+*+2+=+A+M+V+e+m+n+ƒ+…++™+¡+¢+¯+±+¹+Å+Î+Ý+ýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýý5de+˜+™+,W,˜,-A-‚-¸-î-$.V.‚.»./ƒ/Ú/C0±0ø0öñçÝÓÉ¿µ«¡—ƒyoe[QG=‘öôÿÿˆ  %‘dõÿÿˆ  $‘Íõÿÿˆ  #‘$öÿÿˆ  "‘¡öÿÿˆ  !‘ìöÿÿˆ  ‘%÷ÿÿˆ  ‘Q÷ÿÿˆ  ‘ƒ÷ÿÿˆ  ‘¹÷ÿÿˆ  ‘ï÷ÿÿˆ  ‘%øÿÿˆ  ‘føÿÿˆ  ‘¦øÿÿˆ  ‘ùÿÿˆ  ‘Pùÿÿˆ  ‘“ùÿÿˆ  ‘úÿÿˆ  ‘úÿÿ‘Búÿÿˆ  Ý+è+î+÷+, ,,,,),+,3,>,G,W,],^,k,m,u,€,‰,˜, ,¡,®,°,¸,Ã,Ì,×,à,ì,ô,- - ---!-,-5-A-E-F-U-W-_-j-o-u-y-‚-Š-‹-˜-š-¢-­-²-¸-À-Á-Î-Ð-Ø-ã-è-î-ö-÷-.....).3.5.=.[.m.o.w.‡.“.•..¨.±.À.É.Ë.Ó.Þ.â.î.÷.///ýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýý5d,W,˜,-A-‚-¸-î-$.V.‚.»./ƒ/Ú/C0±0ø0J1ñ12F2‘2á2.3‹3í3<4v4¡4ýýýýýýýýýýýýýýýýýýýýýýýýýýýýý‘///"/-/5/C/K/Y/a/o/u/ƒ/‹/Œ/™/›/£/®/·/Ã/Ì/Ú/â/ã/ï/ñ/ù/0 000%0+060:0C0K0L0]0_0g0r0x0~0ˆ0“0™0¤0¨0±0¹0º0Â0Ä0Ì0×0Ý0ã0ë0ø011111)1/151?1J1R1S1[1]1e1v1|1‚1‹1¦1§1×1Û1ä1è1ñ1ù1ú12222"2#21232;2F2N2ýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýúýýýýýýýýýNH5cø0J1ñ12F2‘2á2.3‹3í3<4v4¡4E5’5Þ5 6 6 6"6ä677öìâØÎĺ°¦œ’ˆ~tj`[VHC@;BáÿÿÿeœéÿÿÿïÿÿY   ïÿÿ‘ïÿÿƒžïÿÿ‘Éïÿÿˆ  5‘ðÿÿˆ  4‘bðÿÿˆ  3‘ñÿÿˆ  2‘1ñÿÿˆ  1‘kñÿÿˆ  0‘ºñÿÿˆ  /‘òÿÿˆ  .‘yòÿÿˆ  -‘Æòÿÿˆ  ,‘óÿÿˆ  +‘aóÿÿˆ  *‘óÿÿˆ  )‘¶óÿÿˆ  (‘]ôÿÿˆ  '‘¯ôÿÿˆ  &N2O2Y2[2c2n2w2ƒ2‰2‘2™2š2©2«2³2¾2È2Ó2Ù2á2é2ê2ù2û2333 3&3.36373A3C3K3V3_3q3w3}3ƒ3‹3“3”3£3¥3­3¸3Â3Ó3Ù3ß3å3í3õ3ö3þ34444%4.46474<4D4E4O4Q4Y4j4p4v4~44Œ4Ž4–4¡4©4ª4³4µ4½4Î4Ô4Ú4ã4ý4þ4,50595=5E5M5N5X5Z5ýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýúýýýýýýýýýýýýúýýýýNH5c¡4E5’5Þ5 6 6 6"6ä67717S7u7’7À7É7Ô7™8(9_9k99[:d:é:¯;ýýýýöñïíèæäääääæäàíèæääæäíe„hzBe„h@&œ‘ & Fƒ & F„‘Z5b5s5y55ˆ5’5š5›5§5©5±5¼5À5Ê5Ò5Þ5æ5ç5ô5ö5þ5"6#6>6@6[6\66‰6–6 6­6·6Ä6Î6×6â67717=7S7_7u77’7Ÿ7™8š8º8¼8Ü8Ý89 9999&9k9u99œ9é:ê: ; ;*;+;V;^;j;v;„;‡;“;š;¦;¨;©;­;>=?=z>„>È>Ö>M?ýýýýýýýýýýýôðôðôîîîîîîîîîîçåçåçîîáîîîçåçåçîîîîîáîÞîîNH6NH jU6CJjCJU5X717S7u7’7À7É7Ô7™8(9_9k99[:d:é:¯;Õ=n>z>È>M?‚?À?÷?@j@û@JAVAyA¡AÈAÑA BûöñìçâÝØÓÐËÆÁ¼·²­¨£ž™”Š…€{vqlgb]XzW÷ÿÿB`÷ÿÿz‡÷ÿÿz¯÷ÿÿzÒ÷ÿÿBÞ÷ÿÿe-øÿÿœ¾øÿÿz(ùÿÿB1ùÿÿzhùÿÿz¦ùÿÿzÛùÿÿz`úÿÿz®úÿÿBºúÿÿeSûÿÿeyýÿÿœ?þÿÿzÄþÿÿBÍþÿÿz›ÿÿÿz½ÿÿÿBÉÿÿÿeœKþÿÿeÿÿÿzÿÿÿB$ÿÿÿzRÿÿÿzoÿÿÿz‘ÿÿÿz³ÿÿÿzÕÿÿÿ"¯;Õ=n>z>È>M?‚?À?÷?@j@û@JAVAyA¡AÈAÑA B~B«C·CÙCâC1D¯DàDìDEûûù÷÷÷÷÷ù÷õûù÷÷÷ù÷õûù÷ù÷õðù÷e„h@&œzBe„hM?R?S?^?‚?‹?À?É?U@V@j@k@‡@‰@¥@¦@Ì@Ô@ã@æ@ò@ù@VA`AyA~AA…A¡AªA B B)B+BJBKBtB|B·CÁC1D2DNDPDlDmD“D›DªD­DìDöDEEEEÝEÞEýEÿEFFHFPFXF[FŸF©FÁFÆFÇFÌFGG8G=GwGxG—G™G¸G¹GâGêG,H6HÉHÊH I I'I)IDIEIfIýûýýøñïñïñýýýýýûýñïñïñýýñïñïñýýýýûñïñïñýýýýûûûñïñïñýýøñïñïñ jUNH56^ B~B«C·CÙCâC1D¯DàDìDEDEMEXExE£EÝE]F“FŸFÁFøFGNGwGìG H,HNHWHbH‚HÑHûöñìçâÝÚÕÐËÆÁº°¦¡Úœ—’ˆƒ~Úytoj`V.jÿÿÿ€  .Šÿÿÿ€  z•ÿÿÿBžÿÿÿzÀÿÿÿBÌÿÿÿœæþÿÿeÿÿÿz\ÿÿÿBeÿÿÿzœÿÿÿz¾ÿÿÿBÊÿÿÿœÒþÿÿ. ÿÿÿ€  .7ÿÿÿ€   .Wÿÿÿ€ zbÿÿÿBkÿÿÿz ÿÿÿzÃÿÿÿBÏÿÿÿeœ÷ôÿÿzFõÿÿBOõÿÿzqõÿÿB}õÿÿeªöÿÿœ÷ÿÿ EDEMEXExE£EÝE]F“FŸFÁFøFGNGwGìG H,HNHWHbH‚HÑH I˜IUJaJ„Jýûýùùù÷òûýýûýî÷òûýûýùùù÷îûýe„he„h@&œ.BzÑH I˜IUJaJ„J‘JÈJðJñJKK?K@KIKLKÃKALMLpL“LœLŸLMÏMÛMþMNN¨NàNöñìçâÝÓÉÄ¿µ«¦¡œ—’ˆƒ~ytoje`[VSeœÙùÿÿzåùÿÿBîùÿÿzúÿÿBúÿÿeÞúÿÿœMûÿÿzPûÿÿBYûÿÿz|ûÿÿzŸûÿÿB«ûÿÿe)üÿÿœ üÿÿz£üÿÿB¬üÿÿz­üÿÿ.Íüÿÿ€  .ëüÿÿ€  zûüÿÿzüüÿÿ.$ýÿÿ€  .[ýÿÿ€  zhýÿÿz‹ýÿÿB—ýÿÿeTþÿÿœáþÿÿ.ÿÿÿ€  fInIuI~IŠI–IaJkJ„JJñJÿJLKMKiKkK‡KˆKªK²K»KÁKMLWLpLxLŸL L½L¿LÜLÝLM MpMqMÁMÂMÛMåMNN2N4NRNSN{NƒNŠN‘NžN¦NìNöNOO­O®OÃOÍO&P'PWQXQ´RµR5S6SUSWSvSwSžS¦S²SµS¶S¾SóSýST#TnUoUU’U³U´UßUçUöUùUVýýýýýýöôöôöýýýýöôöôöýññýöôöôöýýýýýñýîññöôöôöýýêýýýöôöôöýý6NHNHcNH jU6\„J‘JÈJðJñJKK?K@KIKLKÃKALMLpL“LœLŸLMÏMÛMþMNN¨NàNìNOýûûýýûûýùý÷óùýýùý÷óùýùý÷îùýe„h@&e„hœB.zàNìNOO_OÂOÃO­Q¶QRÁR5SÀSçSóSTàTéTnU V‚VŽV±VÞVçV4W‚WƒWŒW—W·WûöñçÝØÓÎÉÄ¿ºµ°«¦¡œ—’ˆƒ~tje`[Q.÷ÿÿ€  z÷ÿÿB%÷ÿÿz&÷ÿÿ.t÷ÿÿ€  .Á÷ÿÿ€  zÊ÷ÿÿz÷÷ÿÿzøÿÿB&øÿÿeŸøÿÿœ:ùÿÿz¿ùÿÿBÈùÿÿz“úÿÿzµúÿÿBÁúÿÿeèúÿÿœsûÿÿeçûÿÿe§üÿÿzòüÿÿBûüÿÿzåþÿÿzæþÿÿ.Iÿÿÿ€  .Žÿÿÿ€  z™ÿÿÿz¼ÿÿÿBÈÿÿÿOO_OÂOÃO­Q¶QRÁR5SÀSçSóSTàTéTnU V‚VŽV±VÞVçV4W‚WƒWŒW—W·Wýûûýýùýõõóõùýýùýóõùýýýûûýùýûœe„hB.zVVŽV˜V±V¶VÞVåV&W'WŽYY«Y­YÉYÊYðYøYZ ZZZ`ZfZvZwZ‹Z•Z®Z¹ZõZúZ¢\£\Ø\Ù\ú\ü\]]I]Q]^]f]o]r]u]v]•]—]¶]·]à]è]ð]ó]7^A^Y^^^_^d^¢^£^Ö^Û^/_0_O_Q_p_q_š_¢_®_¶_Â_Ë_Ø_á_Ã`Í`å`ï`aa)a4aŒbb²b´bÙbÚb cýýýýúóñóñóýýýïúýýýúóñóñóýýýóñóñóýýýýïúïóñóñóýýýýýýýýóñóñó5 jUNH6^·WïWXRX‹XŽYZZ‹Z®ZõZ[%[0[P[¨[à[\I\Ø\t]u]õ]+^7^Y^¹^Â^_öìâØÓÎÉÄ¿ºµ°«¡—ƒytojeb]XSNIz3ÿÿÿB<ÿÿÿzœÿÿÿz¾ÿÿÿBÊÿÿÿeœ3ñÿÿe4ñÿÿœÐñÿÿe_òÿÿ.˜òÿÿ€  .Èòÿÿ€  .óÿÿ€  .Xóÿÿ€  .xóÿÿ€  zƒóÿÿBŒóÿÿz³óÿÿzúóÿÿzôÿÿB)ôÿÿeôÿÿœõÿÿeöÿÿ.Vöÿÿ€  .’öÿÿ€  .¹öÿÿ€  .ñöÿÿ€  ·WïWXRX‹XŽYZZ‹Z®ZõZ[%[0[P[¨[à[\I\Ø\t]u]õ]+^7^Y^¹^Â^ýýýýù÷ùõóóóõóýýýýýù÷ñ÷ìõóóõe„h@&ezBœe„h.Â^_/_ã_f`g`¶`·`Ã`å`a)ahaqaÏacbŒb-c‹c cµcÍcàcácndÀdÌdìdEeýù÷ùùõùóýýýýóýùù÷ùõõõõùùùóýýBƒœe„hz_/_ã_f`g`¶`·`Ã`å`a)ahaqaÏacbŒb-c‹c cµcÍcàcácndÀdÌdìdEeNeZe8fûöñìåàÛÖÑÌǽ¸³®©Ÿ•‹|wrmhc^YTœ›øÿÿz§øÿÿB°øÿÿz ùÿÿz)ùÿÿB5ùÿÿe‡ùÿÿeúÿÿeúÿÿƒ(úÿÿ{  ƒ@úÿÿ{  ƒUúÿÿ{  ƒjúÿÿ{  eÈúÿÿœiûÿÿe’ûÿÿe&üÿÿz„üÿÿBüÿÿzÌüÿÿzïüÿÿzýÿÿz2ýÿÿB>ýÿÿe?ýÿÿ ƒŽýÿÿ{ eýÿÿeþÿÿœÆþÿÿeïþÿÿ ccc+cƒc„cÌdÖdìdûdZe[eeƒe©eªeÜeäeðeúef ffff%f3f6f÷føfRk\kâkîkll2l@l”l•l«l°l±l¼l8m9mMmNmtmvmœmmÍmÕmÔnÕno(oSoTowoyoœooÆoÎo×oÝoppœq¦q¼qÄqìqíqrr9r:rirqr}rŠr•r¢r¶uÀuÖuåuv.vavbvýýúýýóñóñóýýýýíýýúýýýýúýëúóñóñóýúýóñóñóýýúýýóñóñóýýýýýýó56NH jUNH6]EeNeZe8fÿf,hÐiFkRkâkl2l«lÚlãlMm×mxnoo>oGoSoßo—pqqqœqýûùõõõõýûûûûûýûùõõýûýûùõõóõýƒe„hœzB8fÿf,hÐiFkRkâkl2l«lÚlãlMm×mxnoo>oGoSoßo—pqqqœq¼qàqéqìq¤r t4tEtûöñìçâÝØÓÎÉÄ¿ºµ°«¦¡œ—’ˆƒ~ytoje`[VeÁéÿÿeééÿÿeQëÿÿœ ìÿÿz ìÿÿBìÿÿz9ìÿÿzYìÿÿBeìÿÿefìÿÿƒãìÿÿ{  e^íÿÿeîÿÿœ¢îÿÿz®îÿÿB·îÿÿz×îÿÿBãîÿÿe}ïÿÿeðÿÿœ¨ðÿÿzñÿÿBñÿÿzJñÿÿzÃñÿÿzðñÿÿzòÿÿz£òÿÿB¯òÿÿe%ôÿÿeÉõÿÿeööÿÿe½÷ÿÿ!œq¼qàqéqìq¤r t4tEtkt’t¤t·tÒtçtªu¶uÖuvLvUvavÙvóvþw¦x²xáxêxýýûýùõõõõõõõõõõûýýýûýùõõõûýûe„hœBzEtkt’t¤t·tÒtçtªu¶uÖuvLvUvavÙvóvþw¦x²xáxêxDyÓyz zCzwzz¦z±zÑz{ûöñìçâÝØÓÎÉÄ¿ºµ°«¦¡œ—’ˆƒ~ytoe[.$ãÿÿ€  .Dãÿÿ€  zOãÿÿBXãÿÿz~ãÿÿz²ãÿÿzÕãÿÿBáãÿÿe"äÿÿœ±äÿÿz åÿÿBåÿÿzCåÿÿBOåÿÿe÷åÿÿeçÿÿeçÿÿœ”çÿÿz çÿÿB©çÿÿzÖçÿÿzèÿÿz?èÿÿBKèÿÿeéÿÿe#éÿÿe>éÿÿeQéÿÿecéÿÿeŠéÿÿe°éÿÿbv‚v„v¤v¥vÏv×vMwNwŽw¨w©w±w‹x–x²x¼xDyEy_yay{y|y y¨y·yºyÆyÍyÎyÑy z*zCzHzIzOzwz„zj{k{…{‡{¡{¢{Æ{Î{Ý{à{ì{ó{ý{||| |(|/|5|>|C|§|±|Ê|Ï|Ð|Ö|ò|û|}"}T}^}È}É}0~:~’~š~ »¼ÖØòó‚‚.‚1‚>‚ýöýöôñïëïïôöýöýöôôôçôôôïôöýöýöôôôôôôôôôôïôôôñôôôöýöýöôô6NH5NH5NH6 jU[êxDyÓyz zCzwzz¦z±zÑz{0{j{E|›|§|Ê|ò|}T}`}Ð}/~0~’~£~Ø~ ýû÷õýýýõýóóóóû÷õýýýýýóóýýýóó.Be„hœz{0{j{E|›|§|Ê|ò|}T}`}Ð}/~0~’~£~Ø~  PpqzµM€ù€»I‚öìçâÝØÓÎÉĺ°«¦¡—ˆƒyoje`[VQLœ:ÜÿÿeüÜÿÿe¨Ýÿÿe@Þÿÿz{ÞÿÿB„Þÿÿz…Þÿÿ.¥Þÿÿ€  !.×Þÿÿ€  zèÞÿÿzéÞÿÿ.ßÿÿ€  .Rßÿÿ€  zcßÿÿzÅßÿÿzÆßÿÿ.%àÿÿ€  .•àÿÿ€  z¡àÿÿzÜàÿÿzáÿÿz+áÿÿzNáÿÿBZáÿÿe°áÿÿœ‹âÿÿ.Åâÿÿ€  .õâÿÿ€    PpqzµM€ù€»I‚—‚£‚Æ‚ñ‚?ƒHƒyƒ„¯„°„c…X†d†‡†ê†i‡ýýûûýùýõõõóõùýýýùýõóñóõùýýýeœe„hB.z>‚G‚w‚}‚£‚­‚Ƃ˂ق߂ñ‚ü‚„„3„5„T„U„~„†„•„˜„¥„©„ª„­„°„±„τфï„ð„… …)…,…9…B…M…T…[…a…………¿…À…d†n†‡†Œ†š† †ê†õ†i‡r‡2ˆ:ˆ{Š|ЏйŠÜŠÞŠ‹‹/‹7‹@‹C‹P‹T‹U‹X‹c‹j‹q‹w‹z‹{‹œ‹ž‹¿‹À‹ç‹ï‹÷‹ú‹ŒŒ˜Œ¢ŒºŒ¿ŒýûýýûýôòôòôýýýîýôòôòôýýýýýûëýýûýýýëôòôòôýýýîýýýôòôòôýýýýýNH6NH jU56]I‚—‚£‚Æ‚ñ‚?ƒHƒyƒ„¯„°„c…X†d†‡†ê†i‡t‡›‡LJõ‡1ˆ2ˆ<ˆlˆœˆˆ¦ˆæˆĉ¸ŠûöñìçâÝØÓÎÉÄ¿ºµ°­£™…€{qgb]XSNe¥ýÿÿeƒþÿÿzÃþÿÿBÌþÿÿzÍþÿÿ.ýþÿÿ€  '.-ÿÿÿ€  &z7ÿÿÿz8ÿÿÿ.tÿÿÿ€  %.¢ÿÿÿ€  $.Îÿÿÿ€  #.õÿÿÿ€  "zz ×ÿÿzn×ÿÿz‘×ÿÿB×ÿÿe’ØÿÿœEÙÿÿeFÙÿÿœâÙÿÿe|Úÿÿz­ÚÿÿB¶ÚÿÿzÛÿÿz/ÛÿÿzRÛÿÿB^Ûÿÿe¬Ûÿÿi‡t‡›‡LJõ‡1ˆ2ˆ<ˆlˆœˆˆ¦ˆæˆĉ¸Šy‹z‹ ŒŒŒ˜ŒºŒòŒw€ÎŽ;ŽÅŽüúúúúøøúúøöøòòðîðòöøøøöèúòð. ƃeœe„hBz.z@&¸Šy‹z‹ ŒŒŒ˜ŒºŒòŒw€ÎŽ;ŽÅŽ .›¤)‘!‘-‘M‘o‘‘‘®‘Ü‘å‘𑵒w“”ûöñìçâÝØÓÉ¿ºµ²­¨£ž™”²Š…€{vqlgb]XeŒýÿÿœNþÿÿeÿÿÿzÿÿÿB'ÿÿÿzUÿÿÿzrÿÿÿz”ÿÿÿz¶ÿÿÿzÖÿÿÿBâÿÿÿœœþÿÿeÅþÿÿz!ÿÿÿB*ÿÿÿz—ÿÿÿz¹ÿÿÿBÅÿÿÿeœ.ùÿÿeWùÿÿ.›ùÿÿ€  ).éùÿÿ€  (Bòùÿÿzwúÿÿz¯úÿÿzÑúÿÿBÝúÿÿe`ûÿÿœïûÿÿeðûÿÿœ±üÿÿ!¿ŒÀŒÅŒòŒúŒUZ¢éî;Ž<Ž[Ž]Ž|Ž}Ž¦Ž®ŽºŽ»Ž¼ŽÃŽ .9Žùú)*MOrs ¨µ¿ÌÖãíöúû‘-‘7‘M‘Y‘o‘{‘‘‘‘®‘»‘µ’¶’Û’Ý’““2“:“F“O“\“c“p“u“””4”?”_”h”¬”³”©•ª•ѕӕú•û•.–6–B–M–[–ýûýýýýôòôòôûûîûûûëëôòôòôûûûûûîûûûûûûôòôòôûûûûûûûûôòôòôûûNH6NH jU65]ÅŽ .›¤)‘!‘-‘M‘o‘‘‘®‘Ü‘å‘𑵒w“””4”_”¬”&•/•„•©•úøööøöòðúøöööööøöòðòøööööøöòœe„hzBe„h@&””4”_”¬”&•/•„•©•`–——Ù—ý—-˜6˜ž˜¾˜U™V™W™Ñ™^š­š¹šÙšâ𛵛bœnœŽœùœûöñìçâÝØÓÎÉÄ¿ºµ°«¡œ—ˆ…€{vqlgb]XzÐýÿÿzðýÿÿBüýÿÿe©þÿÿœNÿÿÿz|ÿÿÿB…ÿÿÿz¥ÿÿÿB±ÿÿÿeœ2÷ÿÿƒ¬÷ÿÿ{  e­÷ÿÿe®÷ÿÿƒEøÿÿ{  eeøÿÿzÍøÿÿBÖøÿÿzùÿÿz*ùÿÿzvùÿÿB‚ùÿÿe£úÿÿœZûÿÿeûÿÿzÔûÿÿBÝûÿÿzWüÿÿz¤üÿÿzÏüÿÿzïüÿÿBûüÿÿ [–^–v—w————Ù—æ—ý—˜˜˜Š˜‹˜Ñ™Ò™ù™û™"š#šTš\š¹šÚ››4›6›Y›Z›ƒ›‹›’›››§›«›¬›³›nœxœŽœ™œùœPQuw›œÆÎ×Ýožyžž˜ž¿žÀžãžåžŸ Ÿ6Ÿ>ŸKŸXŸŒŸ–Ÿ¬Ÿ»Ÿ˜ ™ » ½ ß à  ¡¡!¡&¡¦¡°¡Æ¡Í¡˜¢™¢¸¢º¢Ù¢Ú¢£ £ýúýýýøúñïñïñýýñïñïñýýýëýýýýñïñïñýýýýñïñïñýýýýñïñïñýýýýñïñïñý6NH jU5NH6]©•`–——Ù—ý—-˜6˜ž˜¾˜U™V™W™Ñ™^š­š¹šÙšâ𛵛bœnœŽœùœDMPýù÷õõõ÷õùóùùóýî÷õ÷õýù÷õõõ÷õe„h@&ƒzBe„hœùœDMPßcžožž³ž¼ž¿žZŸ€ŸŒŸ¬ŸõŸþŸ˜ (¡š¡¦¡Æ¡¢ ¢s¢˜¢L££™£¹£Ø£Œ¤ó¤ü¤ûöñìçâÝØÓÎÉÄ¿ºµ°«¦¡œ—’ˆƒ~ytoje`[BkõÿÿzÒõÿÿz†öÿÿz¥öÿÿzÅöÿÿBÑöÿÿe÷ÿÿœÆ÷ÿÿeë÷ÿÿzQøÿÿBZøÿÿz˜øÿÿz¸øÿÿBÄøÿÿe6ùÿÿœÆùÿÿz`úÿÿBiúÿÿz²úÿÿzÒúÿÿBÞúÿÿeûÿÿœŸûÿÿz¢ûÿÿB«ûÿÿzÎûÿÿzïûÿÿBûûÿÿeüÿÿœýÿÿzýÿÿBýÿÿzeýÿÿ!Pßcžožž³ž¼ž¿žZŸ€ŸŒŸ¬ŸõŸþŸ˜ (¡š¡¦¡Æ¡¢ ¢s¢˜¢L££™£¹£Ø£Œ¤ýù÷õõ÷õýù÷õõ÷õýù÷õõ÷õùýù÷õõõzBe„hœ ££ £-£6£C£J£™£££¹£Ä£Ø£ã£Œ¤•¤v¥w¥—¥™¥¹¥º¥ä¥ì¥¦$¦¼¦½¦ã¦å¦ § §:§B§¡§«§ߨ਩ ©2©3©e©m©y©„©¶©À©Ö©ã©§ª¨ª˪ͪðªñª«&«2«7«‘«’«§«±«Ç«Ϋ¬¬¼¬¾¬ê¬ë¬­%­E®F®˜®¢®Ä®Å®ä®æ®¯¯/¯7¯C¯L¯X¯c¯įůó¯ý¯°!°|±ýýýýýýýöôöôöýýöôöôöýýöôöôöýýýýöôöôöýýñýýöôöôöýñýöôöôöýýýñýýNH jU6_Œ¤ó¤ü¤Q¥v¥î¥¦¦9¦B¦—¦¼¦D§•§¡§À§ɧʧ ¨E¨y¨º¨ߨ†©ª©¶©Ö©$ªýûý÷õðûýûý÷õ÷ûýûýîîîî÷õ÷ûýý.e„h@&œe„hBzü¤Q¥v¥î¥¦¦9¦B¦—¦¼¦D§•§¡§À§ɧʧ ¨E¨y¨º¨ߨ†©ª©¶©Ö©$ª-ª‚ª§ª9«›«§«ûöñîéäßÚÕÐËÆÁ¼·­£™Š…€{vqlgb]XSBSúÿÿeµúÿÿœGûÿÿelûÿÿzÁûÿÿBÊûÿÿzüÿÿz8üÿÿBDüÿÿehüÿÿœýÿÿe4ýÿÿ.uýÿÿ€  -.©ýÿÿ€  ,.âýÿÿ€  +.$þÿÿ€  *z%þÿÿB.þÿÿzMþÿÿBYþÿÿeªþÿÿœ2ÿÿÿeWÿÿÿz¬ÿÿÿBµÿÿÿzÔÿÿÿBàÿÿÿeœèôÿÿe õÿÿzbõÿÿ$ª-ª‚ª§ª9«›«§«Ç« ¬¬j¬¬'­Œ®˜®¸®Á®Ä®e¯ç¯ó¯°|±©±²±¾±6²g²s²ýû÷õ÷ýûûýû÷õ÷ýûýûõ÷ýûûûýûõðýe„h@&œe„hzB§«Ç« ¬¬j¬¬'­Œ®˜®¸®Á®Ä®e¯ç¯ó¯°|±©±²±¾±6²g²s²–²Ÿ²Ô²T³¶´´ä´í´ð´‘µʵÖµûöñìçâÝØÓÎÉÄ¿ºµ°«¦¡œ™”Š…€{vqlgb™]BÇÿÿÿœFýÿÿzIýÿÿBRýÿÿztýÿÿB€ýÿÿeâþÿÿœbÿÿÿz—ÿÿÿB ÿÿÿzÃÿÿÿBÏÿÿÿeœ0ôÿÿz<ôÿÿBEôÿÿzrôÿÿzØõÿÿzûõÿÿBöÿÿe‰öÿÿœ*÷ÿÿz-÷ÿÿB6÷ÿÿzV÷ÿÿBb÷ÿÿeÇøÿÿœ_ùÿÿe„ùÿÿzÙùÿÿBâùÿÿz'úÿÿzGúÿÿ"|±‰±¾±¿±ß±á±²²,²4²s²}²Ô²Õ²ù²û²³ ³J³R³´´´Ì´ð´ñ´ µµ+µ,µRµZµfµoµ~µµеµÖµàµùµ¶@¶E¶m¶t¶µ¶¶¶¸øV¹W¹x¹z¹›¹œ¹ǹϹܹä¹ó¹ö¹ÿ¹ººº'º)ºHºIºrºzº‚º…ºɺÓºëºðºñºöº8»=»’»—»ë»ì»¼ ¼$¼%¼J¼R¼a¼d¼p¼ýöôöôöýýöôöôöýñýöôöôöýýýýýýýýññöôöôöýýýýöôöôöýýýýïïïöôöôöýý5NH jU6^s²–²Ÿ²Ô²T³¶´´ä´í´ð´‘µʵÖµùµ@¶m¶v¶ö···&·F·~·¥·Õ·¸V¹ýûýùõûýûýùðûýýýýîîýûýîîîîîõ.e„h@&e„hœBzÖµùµ@¶m¶v¶ö···&·F·~·¥·Õ·¸V¹ºº‡º½ºɺëºu»~»»ë»¼½½?½ûöñìâØÓÎÉ¿µ«¡—’ˆƒ€{vqlgb]XSNzkýÿÿBwýÿÿeÅýÿÿœœþÿÿeÅþÿÿz ÿÿÿBÿÿÿzœÿÿÿz¾ÿÿÿBÊÿÿÿeœŠûÿÿe‹ûÿÿœ;üÿÿeƒýÿÿ.¼ýÿÿ€  4.ìýÿÿ€  3.þÿÿ€  2.Kþÿÿ€  1.kþÿÿ€  0zvþÿÿBþÿÿz€þÿÿ.Îþÿÿ€  /.ÿÿÿ€  .z$ÿÿÿzQÿÿÿz˜ÿÿÿz»ÿÿÿV¹ºº‡º½ºɺëºu»~»»ë»¼½½?½g½޽™½Õ½7¾A¾m¾¾޾—¾¶¾Ö¾×¾ýûýöôòòôòîýîôòòòòòòëééòòééò.z@&e„hzBe„h@&eœp¼w¼€¼‡¼¼—¼Ÿ¼§¼®¼´¼»¼À¼½&½?½D½E½K½g½p½޽—½™½£½Õ½ß½7¾?¾޾•¾œ¿¿»¿½¿Û¿Ü¿ÀÀÀÀƒÀÀ¦À¯ÀÁÖÁçÁBÂTÂ{ˆÃÔùÃÄÃéÃóÃ-Ä.Ä;ÄHÄjÄxÄÄÄêÄ÷Ä#Å1ÅbÅnÅ´Å¿ÅÆÆÆ$ÆqÆ|ÆׯæÆIÇXÇŒÇǥǵÇÈ+ÈmÈnÈ}ÈýýýýýýýýûýýýýýýôòôòôýýýýïëïëïëïûûûèûûûûûûûèûûûûèûûèNH5mHmH jU56\?½g½޽™½Õ½7¾A¾m¾¾޾—¾¶¾Ö¾×¾à¾¿œ¿ÀwÀƒÀ¦ÀõÀþÀÁÁÁLÁ‡ÃˆÃ´ÃûöñìçäÚÐËÆ¼²­¨£ž™”Š…€{xpda^T‘–ýÿÿˆ  6—ýÿÿÒÿÿÿäÿÿÿY  äÿÿÿY  6ýÿÿz9ýÿÿBBýÿÿz‘ýÿÿz´ýÿÿBÀýÿÿeþÿÿœ›þÿÿe ÿÿÿzWÿÿÿB`ÿÿÿzaÿÿÿ.ÿÿÿ€  8. ÿÿÿ€  7z©ÿÿÿzªÿÿÿ.Êÿÿÿ€  6.öÿÿÿ€  5zz²üÿÿzîüÿÿzùüÿÿz ýÿÿzHýÿÿ׾྿œ¿ÀwÀƒÀ¦ÀõÀþÀÁÁÁLÁ‡ÃˆÃ´ÃäÃ6ÄeąĆćÄáÄÅYÅýû÷õ÷ýûûýûóñïììêêêêêãÜêêê. & F„„ƒ & F„‘*$œe„hzB´ÃäÃ6ÄeąĆćÄáÄÅYūŠÆhÆÎÆ@ÇœÇÈtȬÈÉ~ÉÄÉöìâØÓÎĺ°¦œ’ˆ~tj`VLB8‘ ÷ÿÿˆ  I‘øÿÿˆ  H‘røÿÿˆ  G‘ªøÿÿˆ  F‘ ùÿÿˆ  E‘‚ùÿÿˆ  D‘Þùÿÿˆ  C‘Púÿÿˆ  B‘¶úÿÿˆ  A‘ûÿÿˆ  @‘sûÿÿˆ  ?‘Åûÿÿˆ  >‘üÿÿˆ  =‘=üÿÿˆ  <‘—üÿÿˆ  ;.˜üÿÿƒ™üÿÿ‘¹üÿÿˆ  :‘èüÿÿˆ  9‘:ýÿÿˆ  8‘jýÿÿˆ  7YūŠÆhÆÎÆ@ÇœÇÈtȬÈÉ~ÉÄÉÊkʰÊàÊnË ÌMÌÉÌUÍVÍxͭ͘ÍËÍ:ÎUÎýýýýýýýýýýýýýýýýýýýýýöôòýýýýƒ & F„‘}ȉȵÈÂÈ"É,ɇɓÉÍÉÕÉ ÊÊtÊʹÊÁÊéÊñÊw˃ËÌÌVÌ^ÌÒÌÞ̘ͩ͵ÍÇÍÔÍÛÍ"Î#ÎKÎOÎfÎsήίνÎ.Ï?ÏLÏfϡϲÏÀÏßÏÐ0Ð<Ð>ÐPÐpЯÐÀÐËÐ Ñ ÑÑ+Ñ<ÑJшѾÑÏÑÚÑÒÒ(ÒlÒ}ÒŒÒÊÒËÒÝÒÓÓ#Ó`Ó‰ÓšÓªÓýÓ$Ô5ÔFÔtÔuÔ†Ô¬Ô½ÔÉÔãÔõÔÕÕdÕýýýýýýýýýýýýýýýýúýýúøýøýøýýøýúøýøýýøýúøýøýøýúøýøý6NH5bÄÉÊkʰÊàÊnË ÌMÌÉÌUÍVÍxͭ͘ÍËÍ:ÎUνÎ.ÏfÏ¡ÏßÏöìâØÎĺ°¦¡“‡}si_UPFA7‘×ýÿÿˆ  Yeþÿÿ‘Jþÿÿˆ  Xe»þÿÿ‘#ÿÿÿˆ  W‘>ÿÿÿˆ  V‘­ÿÿÿˆ  U‘Ëÿÿÿˆ  T‘àÿÿÿˆ  SÞÿÿÿY  Þÿÿÿ¬óÿÿY   ¬óÿÿƒÉóÿÿ‘Uôÿÿˆ  R‘Ñôÿÿˆ  Q‘õÿÿˆ  P‘°õÿÿˆ  O‘>öÿÿˆ  N‘nöÿÿˆ  M‘³öÿÿˆ  L‘÷ÿÿˆ  K‘Z÷ÿÿˆ  JUνÎ.ÏfÏ¡ÏßÏÐpЯÐÑ+шѾÑ(ÒlÒÝÒÓ`Ó‰ÓýÓ$Ô†Ô¬ÔãÔõÔdÕÕôÕ2ÖwÖýùýùýùýùýùýùýùýùýùýùýùýùýùýùýe„h‘ßÏÐpЯÐÑ+шѾÑ(ÒlÒÝÒÓ`Ó‰ÓýÓ$Ô†Ô¬ÔãÔõÔdÕÕôÕ2ÖwÖ™ÖûñìâÝÓÎÄ¿µ°¦¡—’ˆƒytje[VLGe÷ÿÿ‘F÷ÿÿˆ  ee„÷ÿÿ‘ë÷ÿÿˆ  deøÿÿ‘ƒøÿÿˆ  ce•øÿÿ‘Ìøÿÿˆ  beòøÿÿ‘Tùÿÿˆ  ae{ùÿÿ‘ïùÿÿˆ  `eúÿÿ‘uúÿÿˆ  _e›úÿÿ‘ ûÿÿˆ  ^ePûÿÿ‘ºûÿÿˆ  ]eðûÿÿ‘Müÿÿˆ  \e^üÿÿ‘Éüÿÿˆ  [eýÿÿ‘Yýÿÿˆ  Ze™ýÿÿdÕÕžÕ¨ÕôÕ2ÖCÖOÖwÖ™ÖªÖ²ÖÕÖ;×L×W×³× Ø ØØØØ/Ø:ØbØØØ˜Ø®ØÅØÔØçØøØÙGÙHÙtÙ¸ÙÇÙÑÙøÙ(Ú9ÚEÚÅÚ ÛÛ"Û„ÛÇÛØÛäÛRܕܞܭÜÂÜæÜïÜÝÝCÝaÝb݊݌ݑݒݴݵÝéÝôÝÞÞÞÞÞÞ$Þ/Þ2ÞAÞDÞEÞsÞuÞýûýûýûýûý÷ñ÷ýûýûý÷ýûîýûýûýûýûýûýûýçåçåáåçýýÝýØýØçåçOJQJ6NHNH jUNH 56NH5656UwÖ™ÖÕÖ;׳רbØØ®ØçØtÙ¸ÙøÙ(ÚÅÚ Û„ÛÇÛRÜ•ÜÂÜæÜÝCÝaÝCÞDÞ8ß©ßûùûùûùûùûùûùûùûùûùûùûùû÷õóõûœ‘e„h™ÖÕÖ;׳רbØØ®ØçØtÙ¸ÙøÙ(ÚÅÚ Û„ÛÇÛRÜ•ÜÂÜæÜÝCÝaÝCÞDÞöñçâØÓÉ嵫¦œ—ˆ~yoj`[MHEÿÿÿœâÿÿÿðÿÿY   ðÿÿe]ðÿÿ‘’ðÿÿˆ  pe¶ðÿÿ‘ãðÿÿˆ  oe&ñÿÿ‘±ñÿÿˆ  neôñÿÿ‘oòÿÿˆ  me³òÿÿ‘Póÿÿˆ  le€óÿÿ‘Àóÿÿˆ  keôÿÿ‘‘ôÿÿˆ  jeÊôÿÿ‘ùôÿÿˆ  ieõÿÿ‘Zõÿÿˆ  heÅõÿÿ‘=öÿÿˆ  ge£öÿÿ‘ßöÿÿˆ  fuÞzÞ{Þ£Þ¤ÞæÞîÞ÷Þßßßßß"ß'ß(ß7ßµßÁßËßÛß&à4àÏàÐàþàááá.á/átá~ááŽá×áåá'â(â{â|â«â­â²â³âÜâÝâ#ã2ã3ãBãã£ãää2ä4ä9ä:äaäbä¯äºäÃäÆäÇäËäÌäÛä(å7å{å‡åææ0æ2æ7æ8æ^æ_æ¥æ±æºæÃæÆæÇæÓæßæâæææýùýòððëðëëðððòýòýùýòðëðèòýòýùýòðëðòýòýùýòððäðëððòýòýùýòððëðë6NHNHOJQJ6 jUNHZDÞ8ߩߵßËß&à„ààÏàáÊáËá×á0â9â{âCãƒã„ãã¹ãÂãäÜäåå(å{å¸åÁåæ÷æç çûöñìçâÝØÓÎÉÄ¿ºµ°«¦¡œ—’ˆƒ~ytoje`[e;öÿÿeLöÿÿœ@÷ÿÿz‚÷ÿÿB‹÷ÿÿzÈ÷ÿÿzøÿÿB'øÿÿe(øÿÿegøÿÿœ?ùÿÿzùÿÿBŠùÿÿz³ùÿÿB¿ùÿÿeÀùÿÿeúÿÿœÈúÿÿz ûÿÿBûÿÿzlûÿÿBxûÿÿeyûÿÿe´ûÿÿœtüÿÿz¶üÿÿB¿üÿÿzýÿÿzxýÿÿzŽýÿÿBšýÿÿe þÿÿœÿþÿÿ!©ßµßËß&à„ààÏàáÊáËá×á0â9â{âCãƒã„ãã¹ãÂãäÜäåå(å{å¸åÁåæýûûûýûùõõýûýûùõõýûýûùõõýûûýûe„hœzBææçæöæç&ç`çmçÁçÑçfègè–è˜èèžèÇèÈèéé'é/é8é=é>éMéäéñéê)êWê`ê»ê¼êèêêêïêðêëë[ëdëoëwëë•ë˜ëœëë¬ëþë ì6ìFìØìâìðìí{í|í¬í®í³í´íÞíßí'î0î7î?îNîUîaîiîjîyî­îºîåîñî ïïVïcïÖï×ïð ððð9ð:ð‚ð‹ðûùùùòðòðìðòùùùûùùùòðòðìðòùùùûûùùùêòðòðìðòùùùùûùùùùòðòðìðòù5NH jU6OJQJ\æ÷æç çç`çÁçè$èfèNé„é…é‹éØéäéêWêpêyê»ê­ëñëòëþë6ìcì ì×ìýùù÷õõõ÷õýùù÷õ÷õõõ÷õýùù÷õõóó.zBe„hœ çç`çÁçè$èfèNé„é…é‹éØéäéêWêpêyê»ê­ëñëòëþë6ìcì ì×ìØì0í9í{ízî î¡îûöñìçâÝØÓÎÉÄ¿ºµ°«¦¡œ—’ƒytoje`[Ve£îÿÿeÉîÿÿœÈïÿÿz ðÿÿBðÿÿzkðÿÿzlðÿÿ.£ðÿÿ€  :.àðÿÿ€  9z ñÿÿzEñÿÿBQñÿÿeRñÿÿe–ñÿÿœˆòÿÿzÊòÿÿBÓòÿÿzìòÿÿz'óÿÿz_óÿÿBkóÿÿz¸óÿÿB¾óÿÿe¿óÿÿeõóÿÿœÝôÿÿzõÿÿB(õÿÿz‚õÿÿzãõÿÿz.öÿÿB:öÿÿ ×ìØì0í9í{ízî î¡î­îåî ïVï‹ï”ïÖï¿ðèðéðõð-ñRñ“ñœñÞñáòó óóMóýýûýùõõûýýýýûýùõõûýýýûýùõõûýe„hœBz¡î­îåî ïVï‹ï”ïÖï¿ðèðéðõð-ñRñ“ñœñÞñáòó óóMólóóøóþó§ô°ôòôäõ ö ööOöûöñìçâÝØÓÎÉÄ¿ºµ°«¦¡œ—’ˆƒ~ytoje`[z,çÿÿB8çÿÿe9çÿÿe_çÿÿœQèÿÿz“èÿÿBœèÿÿzEéÿÿBKéÿÿz¦éÿÿz×éÿÿzöéÿÿz.êÿÿB:êÿÿe;êÿÿebêÿÿœeëÿÿz§ëÿÿB°ëÿÿzñëÿÿzìÿÿzNìÿÿBZìÿÿe[ìÿÿe„ìÿÿœmíÿÿz¯íÿÿB¸íÿÿzííÿÿz9îÿÿz^îÿÿz–îÿÿB¢îÿÿ!‹ð’ðšð¤ð®ð¯ð¾ðõðñ-ñ9ñRñ`ñÞñßñòòòòCòDòò–ò£òªò´ò¼òÈòÐòÑòàòó"óMóXólóxóóªóòôóô%õ'õ,õ-õYõZõ¤õ­õºõÁõËõÓõÔõãõö$öOöZönözöîöïö÷÷#÷$÷K÷L÷‘÷š÷›÷ª÷9øFø¼ø½øëøíøòøóøùùdùlùyù„ùù•ùžù£ù¤ù³ùêùýýøýýýñïñïëïñýýýýøýýýýñïñïëïñýýýøýýýñïñïëïñýøýñïñïëïñýýýýøNH jUOJQJ6]Mólóóøóþó§ô°ôòôäõ ö ööOönö£ö¬öîö«÷½÷¾÷Ä÷-ø9øqøzø¼ø´ùÝùÞùýýýûýûýùõõûýýýûýùõõûýûýûýùõõe„hœBzOönö£ö¬öîö«÷½÷¾÷Ä÷-ø9øqøzø¼ø´ùÝùÞùêù%ú„úÀúÙúâú$ûüLüMüYü”ü¾üPýiýrýþûöñìçâÝØÓÎÉÄ¿ºµ°«¦¡œ—’ˆƒ~ytoje`[zÑßÿÿBÚßÿÿzóßÿÿz…àÿÿz¯àÿÿzêàÿÿBöàÿÿe÷àÿÿe5áÿÿœâÿÿzaâÿÿBjâÿÿzƒâÿÿz¿âÿÿzãÿÿzYãÿÿBeãÿÿefãÿÿeãÿÿœ‡äÿÿzÉäÿÿBÒäÿÿz åÿÿBåÿÿzåÿÿB…åÿÿe†åÿÿe˜åÿÿœUæÿÿz—æÿÿB æÿÿzÕæÿÿzôæÿÿ!Þùêù%ú„úÀúÙúâú$ûüLüMüYü”ü¾üPýiýrýþÜþþþÿþ ÿ5ÿ]ÿfÿ´ÿoÕÖýûûûûýûùõõýûûûûýûùõõýûûýûùõõe„hœzBêù÷ù%ú4úvúwú„úúÀúÉú$û%ûPûRûWûXû}û~ûÃûËûØûãûìûïûøûýûþû üYüfü”ü£ü¾üÅü,ý-ýPýYý»ý¼ýþþ?þAþFþGþnþoþ´þ¿þÈþËþÌþÛþ ÿÿ5ÿ<ÿ®ÿ¯ÿ´ÿµÿÞÿàÿåÿæÿ  KP[^_nâëiuÂÃïñö÷bgpxýýúýýóñóñíñóýýýýèýýýúýúóñóñíñóýýèýýúóñóñíñóýýèýýæóñóñíñóýý5OJQJNH jUNH6[þÜþþþÿþ ÿ5ÿ]ÿfÿ´ÿoÕÖâw€ÂÂ-.:XnÊ(1s;XYeƒïøûöñìçâÝØÓÎÉÄ¿ºµ°«¦¡œ—’ˆƒ~ytoje`[BT×ÿÿzÀ×ÿÿzÞ×ÿÿBê×ÿÿeë×ÿÿeØÿÿœÐØÿÿzÙÿÿBÙÿÿzyÙÿÿzÕÙÿÿzëÙÿÿz ÚÿÿBÚÿÿeÚÿÿeÚÿÿœÛÿÿzÃÛÿÿBÌÛÿÿzCÜÿÿzaÜÿÿBmÜÿÿenÜÿÿeÔÜÿÿœÝÿÿzÝÝÿÿBæÝÿÿzÞÿÿz8ÞÿÿBDÞÿÿeEÞÿÿegÞÿÿœ2ßÿÿ!Öâw€ÂÂ-.:XnÊ(1s;XYeƒïø:ç !-ýûûýûùõõýûûûûýûùõõýûûýûùõõýûe„hœzBx˜Ÿ¤¥©¬±²Á):CXdn~¾¿ÊØst ¢§¨ÎÏ!*+:enƒÓà:;dfklÑÖ×àáæþ -6ØÙ  -.ot€ˆ‘™¦­·¿ËÓÔýøýôýøøòîòýýýëýäâäâÞâäýýøýýòäâäâÞâäýø×øòýäâäâÞâäýýýýýý NHOJQJNH jUNH5NH56NHOJQJ6Uø:ç !-–Øä( ) 5 S { ¯ ß 8  ! c % U V _ § Ë :[šÎûöñìçâÝØÓÎÉÄ¿ºµ°«¦¡œ—’ˆƒ~ytoje`[z©ÎÿÿzèÎÿÿz Ïÿÿz'ÏÿÿB3Ïÿÿe4ÏÿÿexÏÿÿœœÐÿÿzäÐÿÿBíÐÿÿeîÐÿÿeÑÿÿœàÑÿÿz"ÒÿÿB+Òÿÿz ÓÿÿzdÓÿÿz”ÓÿÿzÈÓÿÿzðÓÿÿzÔÿÿBÔÿÿeÔÿÿe_ÔÿÿœkÕÿÿz­ÕÿÿB¶ÕÿÿzÖÿÿB"Öÿÿe#Öÿÿe\Öÿÿœ ×ÿÿzK×ÿÿ!–Øä( ) 5 S { ¯ ß 8  ! c % U V _ § Ë :[šÎþýûùõõýûûûûûûýûùõõýûùõõýûûûûûe„hœzBÔã5 > S _ { ‡ ¯ ¾ ß ë 8 E c d  ‘ – — ¼ ½ þ     $ § ¨ Õ × Ü Ý   J O X [ d o x €  ” ž ¦ ² º » Ä Å Ê %:A[jš¦ÎÝþ Wd»¼åçìíRWckt|Š‘›£¤³ "ûùùùùùùòðòðìðòùùûòðòðìðòùùùùùùùûåûùùùùùùùòðòðìðòùùùùùûù NHOJQJNH jU6OJQJZÎþW7@»´÷ø"Kƒ«[l¯°¼Úû:ršÿJ$%1‘ûöñìçâÝØÓÎÉÄ¿ºµ°«¦¡œ—’ˆƒ~ytoje`[zÆÿÿBÆÿÿeÆÿÿeCÆÿÿœùÆÿÿz;ÇÿÿBDÇÿÿz©ÇÿÿzÑÇÿÿz ÈÿÿzHÈÿÿziÈÿÿz‡ÈÿÿB“Èÿÿe”Èÿÿe×ÈÿÿœèÉÿÿz*ÊÿÿB3Êÿÿz˜ÊÿÿzÀÊÿÿzøÊÿÿz!Ëÿÿz?ËÿÿBKËÿÿeLËÿÿeËÿÿœˆÌÿÿzÍÿÿB ÍÿÿzìÍÿÿzEÎÿÿzuÎÿÿ!þW7@»´÷ø"Kƒ«[l¯°¼Úû:ršÿJýýûýùõõûýýýýýûýùõõûýýýýýýûýùe„hœBz".KWƒŽ«·[\‰‹‘¸¹þ #,4BIS[\efk¼ÅÚáû :Fr}š¦JK{}‚ƒ­®ðõöÿ1>ÜÝGHŽ—˜¡×äZÞß!ýýýýöôöôðôöýýýýýýëäëýýýýýýöôöôðôöýëýöôöôðôöýëýáÜáÕáËÕájì¬UmH jUmHNHmHmH NHOJQJOJQJNH jU6P$%1‘šÜ¢ÊË×Z‹¯°æç@b—½6¬­ûûù÷ù÷õûûù÷ù÷óññïßßßßßßßßß1$„ü „öH$7$8$ Æn œzBe„h‘šÜ¢ÊË×Z‹¯°æç@b—½6¬­õ#[¨éFw² X­ c « §!""ûöñìçâÝØÓÅ¿³°­ª§¤¡ž›˜•’Œ‰†ƒ€}zwtqnkhe¬øÿÿ ùÿÿúÿÿMúÿÿúÿÿûÿÿXûÿÿ¦ûÿÿþûÿÿ9üÿÿjüÿÿÇüÿÿýÿÿUýÿÿýÿÿ»ýÿÿþÿÿþÿÿzþÿÿóþÿÿÿÿÿNÿÿÿpÿÿÿ—ÿÿÿÉÿÿÿÊÿÿÿªþÿÿY  ªþÿÿ«þÿÿÏÿÿÿ¨§ÿÿY   ¨§ÿÿz+ÄÿÿB4ÄÿÿzlÄÿÿBxÄÿÿeyÄÿÿe¡ÄÿÿœgÅÿÿz©ÅÿÿB²Åÿÿ'!"°æç­õ§¨  "U"Õ"Ö"_$`$g$—$ð%&Æ&Ø&w'x'þ'ÿ'G(H(j(´(È)É)k/u/N0O0•0¤0*1+1„1…1¨2¸2-3=3ç3è3È4Ø4ö4÷455x5y5•5—5˜5¢5g7Ä7ï9‚:ƒ:‡:¬;­;<<¸<¹<M=N=E?F?º?Ä?Ï?Ð?ã?í?”@•@AAÁAøõíëëèèëèèëææèèèëèæèæèèææèæèæèæâæëëÞëèèèèèæèæèè5NH6NH6NH55CJOJQJmH jUmHX­õ#[¨éFw² X­ c « §!""U"r"Û"!#L#€#¶#ß#$f$ïïïïïïïïïïïïïïïïïïïïïïïïïïï1$„ü „öH$7$8$ Æn "U"r"Û"!#L#€#¶#ß#$f$g$—$ÿ$—%à&i(j(´(â(S)u)Î)ò)9*„*Ú*þ*!+M+•+û+V,°,!-l-¹-µ/21‘3¤5õ5M6¥6ý6g7h7üùöóðíêçäáÞÛØÕÒÏÌÉÆÃÀ½º·´±®«¨¥¢Ÿœ™–“Ї„~{xuIãÿÿ³ãÿÿ äÿÿcäÿÿ»äÿÿ åÿÿçÿÿ~éÿÿûêÿÿ÷ìÿÿDíÿÿíÿÿîÿÿZîÿÿµîÿÿïÿÿcïÿÿïÿÿ²ïÿÿÖïÿÿ,ðÿÿwðÿÿ¾ðÿÿâðÿÿ;ñÿÿ]ñÿÿÎñÿÿüñÿÿFòÿÿGòÿÿÐóÿÿõÿÿ±õÿÿöÿÿIöÿÿJöÿÿªöÿÿÑöÿÿúöÿÿ0÷ÿÿd÷ÿÿ÷ÿÿÕ÷ÿÿ>øÿÿ[øÿÿ«øÿÿ.f$g$—$ÿ$—%à&i(j(´(â(S)u)Î)ò)9*„*Ú*þ*!+M+•+û+V,°,!-l-¹-µ/ïïïïïïïïïïïïïïïïïïïïïïïïïïï1$„ü „öH$7$8$ Æn µ/21‘3¤5õ5M6¥6ý6g7h7|7Ä78b8¨89u9Ã9ï9ð94:‡:Ñ:;[;¶;<U<ïïïïïïïïïïïïïïïïïïïïïïïïïïï1$„ü „öH$7$8$ Æn h7|7Ä78b8¨89u9Ã9ï9ð94:‡:Ñ:;[;¶;<U<Ã<ô<T=¡=Ù=:>ù?mA£CóD¹EPFìFGGøG¨H©HèHéH4I5IJ·J/KKËKüùöóðíêçäáÞÛØÕÒÏÌÉÆÃÀ½º·´±®«¨¥¢Ÿœ™–ˆ…‚|yvsp*ýÿÿzýÿÿòýÿÿ‹þÿÿtÿÿÿuÿÿÿÀÿÿÿÁÿÿÿ±ÐÿÿY   ±ÐÿÿÒÿÿ¸ÒÿÿiÓÿÿÄÓÿÿ`Ôÿÿ÷Ôÿÿ½Õÿÿ ×ÿÿCÙÿÿ·ÚÿÿvÜÿÿ×ÜÿÿÝÿÿ\Ýÿÿ¼ÝÿÿíÝÿÿ[ÞÿÿÞÿÿúÞÿÿUßÿÿ¢ßÿÿßßÿÿ)àÿÿ|àÿÿÀàÿÿÁàÿÿíàÿÿ;áÿÿ¨áÿÿâÿÿNâÿÿ˜âÿÿìâÿÿ4ãÿÿHãÿÿ,U<Ã<ô<T=¡=Ù=:>ù?mA£CóD¹EPFìFGGøG¨H©HèHéH4I5IJ·J/KKËKÍLïïïïïïïïïïïïïïïïïíïïïïïïïïï1$„ü „öH$7$8$ Æn ÁAÂAåBõBjCzC–C—C„D…DîDïDäFåFèHéH,I-I5IJ JMMuMvM|MÑMÒMN+N¬N­N+OlOmO©OªO«OPPqPrP»P¼P½PûPüPjQlQuQyQ Q¤QªQ«Q½QÁQÌQÐQíQñQRR.R/R;R?RWR[RlRpR•R–RýûûýýýýóíåíàÙàÙàÙàíÑàËàíàÙàÈýûøö¶¶ý¶¶¶¶ý¶¶¶ý50Jji­U jUmH 6OJQJ5OJQJmH NHOJQJOJQJ5NHOJQJ 5OJQJ5CJOJQJ6NHHËKÍL{M|MÒM¬N­N*O©OªO«O·OPP0PiQjQuQ Q½QÌQíQR;RWRlR›R3SCSfS¤S¹SÑSôS'T3TRTüùöóðíêçäáÙÖÓÇÄÁ¼·²­¨£ž™”Š…€{vqlgb]déûÿÿdõûÿÿd(üÿÿdKüÿÿdcüÿÿdxüÿÿd¶üÿÿdÙüÿÿdéüÿÿdýÿÿd°ýÿÿdÅýÿÿdáýÿÿd þÿÿd/þÿÿdPþÿÿd_þÿÿd|þÿÿd§þÿÿd²þÿÿ³þÿÿìÿÿÿÿÿÿY  ÿÿÿÿÿÿôÿÿÿY  ÿøÿÿùÿÿùÿÿüùÿÿýùÿÿ×úÿÿ-ûÿÿ.ûÿÿÜûÿÿÞüÿÿ$ÍL{M|MÒM¬N­N*O©OªO«O·OPP0PiQjQuQ Q½QÌQíQR;RWRlR›R3Sïïïïïïïïïíëëéëëçççççççççççd1$„ü „öH$7$8$ Æn –R›RžR3S7SWYWZWhWnW€WWˆWŽWŸW¥W¹W¿WÅWÆWþWXTXUX[XaXtXuX|X‚XšX›X¸X¾XÒXÓXÜXâXüXYJYKYPYVYuY{YŸY¥YºYÀYÆYÇYËYÑYéYïYÿYZZZZ!Z/Z0Z4Z:Z?Z@Z]ZcZhZiZ†ZŒZÄZÅZÍZÒZáZæZóZôZ[[.[/[a[f[{[|[…[Š[Â[Ã[É[Ð[Þ[ß[è[ð[ýûûýûýûûûýûýûýûýûýûûýûûûûýûûûýûýûýûýûýûûýûýûýûýûýû5NHcüXPYuYŸYºYËYéYÿYZ4Z]Z†ZÍZáZ[a[„[Ê[é[q\”\Ä\Ü\ü\+]U]€]¨]¼]Ï] ^(^)^¹^ûöñìçâÝØÓÎÉÄ¿ºµ°«¦¡œ—’ˆƒ~ytoje`[dæ÷ÿÿdç÷ÿÿdøÿÿd@øÿÿdSøÿÿdgøÿÿdøÿÿdºøÿÿdäøÿÿdùÿÿd3ùÿÿdKùÿÿd{ùÿÿdžùÿÿd&úÿÿdEúÿÿd‹úÿÿd®úÿÿdöúÿÿd.ûÿÿdBûÿÿd‰ûÿÿd²ûÿÿdÛûÿÿdôûÿÿdüÿÿd&üÿÿdDüÿÿdUüÿÿdpüÿÿdšüÿÿd¿üÿÿdýÿÿ!„[Ê[é[q\”\Ä\Ü\ü\+]U]€]¨]¼]Ï] ^(^)^¹^º^Ú^î^ï^*_+_=_>_¦_§_¨_ýýýýýýýýýýýýýýý÷ýýýýýýýôòòòò$d„„dð[q\w\“\š\Ã\Ê\Ü\â\û\]+]1]P]Q]T][]€]†]¨]®]¼]Â]Ï]Õ] ^^)^5^_^`^™^š^º^À^Ú^à^ï^ý^+_0_1_8_9_;_<_=_>_s_t_’_“_”_¤_¥_¦_¨_·_¸_Ê_Õ_á_¿`À`Å`Æ`Ú`Û` aýýýýýýúýýýýýýýúúýýý÷ð÷ðëð÷èáè×áÒáèËÆÂËÆÂ¼µ­B*CJhmH 5B*CJ$h B*CJhB*h >*B*h 5>*B*h0JCJjé®CJU jCJUCJ0JmH j0JU0JNH5D¹^º^Ú^î^ï^*_+_0_9_;_<_=_>_¦_§_¨_¸_É_Ê_Õ_á_â_ô_``&`7`I`V`b`c`w`Œ` `¡`±`½`¾`¿`À`Å`Æ`Ñ`Ú`Û`î`a aaa)a*a3a4aOaPa_akalaa•a¨a¸aËaÌaäaÿabbbb0b1bEbZb[bibjbkb~bbb‘b¢b£b¤b¬b­b»bûöñìçâààààààÞààààààààààààààààà dåöÿÿd ÷ÿÿd!÷ÿÿd5÷ÿÿdU÷ÿÿdV÷ÿÿX¨_¸_É_Ê_Õ_á_â_ô_``&`7`I`V`b`c`w`Œ` `¡`±`½`¾`¿`À`Å`Æ`Ñ`Ú`Û`ýýýýýýýýýýýýýýýýýýýýýýýýúýýýý$Û`î`a aaa)a*a3a4aOaPa_akalaa•a¨a¸aËaÌaäaÿabbbb0b1bEbüüüúúúúúúúúúúúúúúúúúúúúüúúüúú$ aa)a*a3a4aJaKaOaPakalaøaùaþaÿabbb/b0b1bZb[bhbibjbkbbb‘b¢b£b»b¼b½bÁbÂbcc”c•c¢c£cºc»cÊcËcÌcÔcÕc d ddøòòêòâÜÔÜÐÈÜÐܼȶȮÜÐÂܨܨ¢š¢š¢Ü– 5B*CJhB* hB*CJNHh B*CJh B*CJhB*CJhmH CJhmH B*CJ(h B*CJhB*CJhmHB*hB*CJNHh B*CJhB* CJhmHB* CJNHh B* CJh 5B*CJ$h5EbZb[bibjbkb~bbb‘b¢b£b¤b¬b­b»b¼b½bÁbÂbÐbàbêbùb ccc*c9cIcüúüúúúúúúüúúúúúúúüúúúúúúúúúúú$»b¼b½bÁbÂbÐbàbêbùb ccc*c9cIcYcnc‚c”c•c¯cËcÌcÔcÕcðc d ddddd"d*d1d2d=dIdJdUd]dddedfdrdd“d”dŸd«d­d®dþþþþþþþþþþþþùdåöÿÿ3IcYcnc‚c”c•c¯cËcÌcÔcÕcðc d ddddd"d*d1d2d=dIdJdUd]dddedfdýýýýýýýýúýýýýýýýýúúúýúúýúúúýú$dddddddd#d$d1d2dHdIdJdVdWdddedfdzd{d’d“d”dªd«d®døñèñøáØáÑááØáËÑÂѼѵ >*B*CJh B*CJ(h5B*CJ$NHh B*CJ$h 5B*CJ$h5B*CJ$NHh 5B*CJ$h5B*CJNHh 5B*CJh >*B*CJhfdrdd“d”dŸd«d¬d­d®düüüúüüúúød$ + 0€1h°‚. °ÆA!°Š"°Š#Š$n%° Ä£DÐÉêyùºÎŒ‚ªK© àÉêyùºÎŒ‚ªK© 2http://www.synthesis.ch/“Ddõ*e c èèðˆ² ð c ðdAÁ@¿ÿLogo-Quadrat, alleinstehen .jpgð€Rðæ’O91ÍîÐü¹»s"œµ!ÿÂ’ç Fðº’O91ÍîÐü¹»s"œµ!ÿÿØÿàJFIF,,ÿîAdobedÿÛ„         ÿÀ*õÿÝ?ÿÄ¢  s!1AQa"q2‘¡±B#ÁRÑá3bð$r‚ñ%C4S’¢²csÂ5D'“£³6TdtÃÒâ&ƒ „”EF¤´VÓU(òãóÄÔäôeu…•¥µÅÕåõfv†–¦¶ÆÖæö7GWgw‡—§·Ç×ç÷8HXhxˆ˜¨¸ÈØèø)9IYiy‰™©¹ÉÙéù*:JZjzŠšªºÊÚêúm!1AQa"q‘2¡±ðÁÑá#BRbrñ3$4C‚’S%¢c²ÂsÒ5âDƒT“ &6E'dtU7ò£³Ã()Óã󄔤´ÄÔäôeu…•¥µÅÕåõFVfv†–¦¶ÆÖæöGWgw‡—§·Ç×ç÷8HXhxˆ˜¨¸ÈØèø9IYiy‰™©¹ÉÙéù*:JZjzŠšªºÊÚêúÿÚ ?ôjþoÔ/õô´ÓÒÚÆá­¿Ò½b䨿»øw®*­ÿ!þÔÿôõŠ»þB/ý©ÿéëwü„_ûSÿÓÖ*™èÿâ2þ™ú§*Gê~¥)¿.^§ÑJb©†*—ëâ1~†ú§*Ÿ[랥)·>ŸÓZâ©gü„_ûSÿÓÖ*ïù¿ö§ÿ§¬UßòíOÿOXª+Mÿ}mIþŽú?«zþ­iðÓŸÃ×®*œâªÿ_ú¤Ÿ£ý/®Pz>¿/JµåÃâéኤòíOÿOX«¿ä"ÿÚŸþž±WÈEÿµ?ý=b­¯ü¬>C—èŽ5ø©õšÓÛdX«±V:ßò°ù?¢8×á¯ÖkO|U¯ù¿ö§ÿ§¬UßòíOÿOX«¿ä"ÿÚŸþž±TòÃëÿTô‡¥õÊ[ÐåéV¦œyü]¿«Z|Uáðõ銡ä"ÿÚŸþž±WÈEÿµ?ý=b®ÿ‹ÿjúzÅS=üAÆ_Ó?TåQèýOÔ¥7åËÔú)LU0ÅRýcüAÆ/ÐßTåSë}sÔ¥6ãÇÓúk\U,ÿ‹ÿjúzÅ]ÿ!þÔÿôõŠ»þB/ý©ÿéëEi¿ã/­¯é?ÑßS¡çõo_Õ­>søzõÅSœUBÿëÿT“ô¥õÊG×åéV¢¼¸|]<1TþB/ý©ÿéëwü„_ûSÿÓÖ*ïù¿ö§ÿ§¬Uµÿ•‡ÈrýÆ¿>³Z{b¬‹v*Ç[þV#ÇôGü5úÍiÿ!þÔÿôõŠ»þB/ý©ÿéëwü„_ûSÿÓÖ*éߤ~§é/Gë»ú¿Wåé}£Ç?‹ìÒµý¬UŠ¤Ú—øËëmú3ôwÔè8}g×õkOм>½1T/ü„_ûSÿÓÖ*ïù¿ö§ÿ§¬UßòíOÿOXªe£ÿˆÿ}úgê³è}OÕ÷åÏÔÿcÇŽ*˜â©~±þ ãèoªr©õ¾¹êR›qãéý5®*–ÈEÿµ?ý=b®ÿ‹ÿjúzÅ]ÿ!þÔÿôõŠ¢tïñ§×#ý%ú7ê[ú¿Wõý_²xñçðýªV¿³Š§X«±WÿÐô7”ÞÏ0ÛJOøŠâ¬v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUت_­k ¥Ão#DeúÅÄvÀƆSN]LU0Å_ÿÑô¦‰¤M§Ï©É#«‹ë§¸Œ-vVPÔuÛMqWb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]бÏ<¼zoý´­¿âGdx«ÿÒõN*ìUت”—v±7 &ùY€?q8ªßÒòÓüÿ\Uߤ,?å¦/ø5þ¸«¿HXËL_ðkýqW~°ÿ–˜¿à×úâ®ý!aÿ-1Á¯õÅ]úBÃþZbÿƒ_늻ô…‡ü´Åÿ¿×wé ùi‹þ ®*ïÒòÓüÿ\Uߤ,?å¦/ø5þ¸«¿HXËL_ðkýqW~°ÿ–˜¿à×úâ®ý!aÿ-1Á¯õÅ]úBÃþZbÿƒ_늻ô…‡ü´Åÿ¿×wé ùi‹þ ®*ïÒòÓüÿ\Uߤ,?å¦/ø5þ¸«¿HXËL_ðkýqW~°ÿ–˜¿à×úâ®ý!aÿ-1Á¯õÅ]úBÃþZbÿƒ_늻ô…‡ü´Åÿ¿×S¸Ö4‹hZk‹ëxaZr’IQTTÐT’SЍ[y›ËwRzVº­œòÓ—®"v ïEcŠ¢ÿHXËL_ðkýqW~°ÿ–˜¿à×úâªZþ…fª×z­º±¢´³F€ŸɆ*Õ§˜t ÎTÔ­n}:sô§øÖ´¯4­1TGé ùi‹þ ®*ïÒòÓüÿ\Uߤ,?å¦/ø5þ¸«¿HXËL_ðkýqW~°ÿ–˜¿à×úâ®ý!aÿ-1Á¯õÅ]úBÃþZbÿƒ_늻ô…‡ü´Åÿ¿×wé ùi‹þ ®*ïÒòÓüÿ\Uߤ,?å¦/ø5þ¸«¿HXËL_ðkýqW~°ÿ–˜¿à×úâ®ý!aÿ-1Á¯õÅ]úBÃþZbÿƒ_늻ô…‡ü´Åÿ¿×wé ùi‹þ ®*ïÒòÓüÿ\Uߤ,?å¦/ø5þ¸«¿HXËL_ðkýqW~°ÿ–˜¿à×úâ®ý!aÿ-1Á¯õÅ]úBÃþZbÿƒ_늻ô…‡ü´Åÿ¿×wé ùi‹þ ®*º+«Y[ŒS$׊°&ŸAÅUqWb¬sÏï›ÿm+oø‘ÅY*ÿÿÓôÚßIwƒYÌÖórøÔi¹Û|UŠ»xçç¯æ™äxQºO¬]L«…˜Zþ`_i֚Εg¦²%¬Ò4!Ô¢¿©'=^|«ñ|ù9*ú«v*ðïùÊŸùGô?ù‹—þMâ©üâý5?ôaÿc8«èUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìU<òüuüboÖ1VkŠ»cžxÿxôßûi[ÄŽ*ÈñWÿÔô7”ÞÏ0ÛJOøŠâ¬v*øÛþsY®ÿÆú*°?T,a=½C'ï?áDXªEÿ8ݬyÂ{ôÖÞÛ_’D67|Tz\wH¤…ŸÚVƒíqÅ^÷­y?Êšü–÷®™o{-»¤°Lè UM@ä7dñFýÛ~Òâ©ÐØtÅ^;cÿ97å+»Û{DÒ¯Õî$H•˜C@]‚‚i'¾*õùåÃ$¬ XÔ¹­Wy•ÿ9-åMGS³ÓâÒïÒ[Éã·ØCÄ4®I ¥N*ôÏ1ù—Dòæ—&©¬Ý-¥œd/6©,Ƥ"(«;š}•Å^E{ÿ9Qåèî8Ùh—Wýì²G |Â/üKeÞCüïò›ïSM‡ÖÓõY+éZ\I8ŽGÓ‘ ) e¸7ù8«Ì¿:¿8´?0hº‡•m¬®¢¼¶½óÉéúDÛHÊÔâÅ·§Ãðâ¬òÏÚo’<Ís«jó\Ã=“Ú¬vüyyb̨ãHŽ*úoòëó'JóÕ•åÞk=ªYȱ:Üp©,¼ª83b©›¿ç <‡åû©,¡yu{ØÌ)‰uV•Š©ÿž~¦*Æm?ç*tœ-Þ…u ÞH¥ŽW§úŒ"ðø«Öü­æÍ ÍJjš-ȹµbQ¶*èãª:Õ…ãeøqW—~g~dþXYy¶m'̾Y}[QÒÄ@] qÆXÖeP]Õ™©öáåËgéç½*?ËåóŠZʺjÚ‹•´P‚QVeÅQmóÇ–<¥d.õËÕ·_B Í)’5ø»}…ý¦Å^Y{ÿ9S $¤YhwSÅSGšXáoøÿıVYäoÏO'y²ú=1Ún§)¤÷AxÊi^1Ȥ©oò_ƒ7ìòÅU???òRë¿ôiÿQâ¯ü‰ó&åÏ7ÝêÚ½À·²ƒN›“Ù˜ÉTE³·e«Ó.¿ç*|¾—%mt;©­«OVIcéãÀ ü>*ô"~ey_ζ²I¤LÉsæÆpxÁØ5edÿ-±WœÎTÿÊ?¡ÿÌ\¿òoKÿçÿé©ÿ£ûÅ^Õæ6yËiÔu»Ä´·¯Á©y•á ³·ú¸«É¯ç*<»ül´K»ˆA§©,‘ÂÔñ =_ø–*Í<…ùÏäÿ8Ü W’ÇU •±ºYøŠ·¤êY$ ýŸ†OÚáÇg˜«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»O<Ÿÿcÿ›õŒUšâ®ÅRo4i·wöÖIj¡ÚØ'2KñTçÿÕô7”ÞÏ0ÛJOøŠâ¬v*òÎïËíÎêÚv£Ê)¢U’Êö0 ÈE ý¤oÛOÚÿ[‹*¯–<Ïÿ8õùƒ£´’Y@šÍšÔ¬¶ûÞ>ð½—ù1ú¸«Ð<íç'_ì/nl^¤Ú|ܽ*Ž«$|5ÿcÏ}cùcçÈ<íåhµeŒAw›{ûu©T™'wàÊÊëÿû8«ã.ÿÊA¦Ì\òqqWÝzüsîãÿÄN*øwÉŸò˜h_öеÿ“銽—þr²MC×òôdŸÑånY@­ À <¾IN?ìñVùWwù8–wvÞzµ•¯¥—ýìú愨inÜÖN|‰~ËŠ½ÃòÉ¿–z\—º§•/ãÕ§ˆ³«Ëm n! ³§»:ó|U‚~x~RyWBòí÷™ìžèêW7ªÒ $VŠ·Yè¡ê~‹`_’žFÑ|çæ«­/Wi–Ú.Û¸Fæ³D‚¤«|ä ý¨Ãpž&§Šò\Uîó•/hDƒu!Æ,Uÿ8ŸÿMOýØÎ*óOÎ/7^y“Ïz“É!6VIga j‹,P²Y}Fÿ›WzƒÿBÅc¡Åcxº…ëFÝô–úˆvˆÇÆ5ôÖ¿c‡û.MмV›OÑüÕ4þV¿’{+;6•Å£’ŠC¡!Õ’„ü ËŽ*ûcËz°Ö<½¦jÀúý¬7%FáL±‡+þÄšb©Ž*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb©ç“ÿã¬ã~±Š³\UØ«±Wb¯ÿÖô7”ÞÏ0ÛJOøŠâ¬v*ñ_ϯ̽+ÈÁ®f qª\F«§Ør¡vwjn±'í7û UˆùsóóòëV°Žk»ñ¥^q{;¥o…»ñ‘T¤‹_³û_ä.*ñÏŸ;yWÍ~c´Ÿ@_Um`1\ê ~±-U0W+ÿÚþ\Uê_ó‹úmÝ¿“/ïea½½?V£,H¨Î=‹òOù犾nŒË¤ëJ]yK§Ü‚Èv«C&àøn¸«êýó·òú/*\ꚬW72Û¿Õl¾»Jèx#ÇNQü_m›á\Uòß“?å0пí¡kÿ'Ó}ù™þ_)ÜÉç(Ò]&2 ©¯ªf¡ âCú§zq?g—/ÝóÅ^;©~E~_êZ;ë^WódqZÌ©õÇŠH†ÕâÃNÍÓö±W–þ]kZ–çmïOwYšîd =X¥‘QâaÜ88«èÿùÈå'òÊà€HVäûDb¯ÿœ{ó.‰ yêiõ{¨ì­îìeµŽâb1!–)7? ‚±7ÄØ«ßüéçÝ=<‡æ WËZŒ×:|Dö’$뒪ܲrN\ÿØüX«æ/Ë?*XùÏÎéš¾ öÑÜ '–^@Í3Ê#=xõåȇý¬U꿚_•ß•OòeÕÊ$‰¬ºpÓ—ÒÉ)a¿§P¥QwsÇû,U‰ÿÎ3䯗þÙóÿÉȱTŸóóÿ&Ö»ÿFŸõ*öývoûtÿÌÌUãßù6´/ú;ÿ¨9±WÑ_ßù+5ÿøÅüŸ|ûÿ8óÿ“OMÿŒW?òañU_ùÈo0êzæ%æ›<Œ,´¥ŽKrh«êD’;ÓùŸí' UèžAü…ü¼ºò¥†³ªÜÉ©=åº\M"Ïé[ÆYy2Nû¿²üßí/ì}œUáÞƒËþpÔ­ü°yhpºÇhÜÚ@JÆ¢B®Ä–S(“‹Wì⯢2¿õý³ô¯ù=mмSòSÏ–Nóy»Ôê4ÛØÖæURÆ*²ºÉÄ|L’Œö[}¬þv~\iº[ß&± ëñ&Kb^gjT/?w_8ñÅ_&C ÿ™üÒ#‰?Óu›ÃEQPâJŸö+Ëþ{Ïüå$k–´“ì¥Ìеð1Tüâý5?ôaÿc8«Èÿ2´ ÏZÖŸ:êI`'ö¡™Œ‘0?ê0¯ùX«Ö|«ù7ù3æ-VÓ^¾@Ñ«]@÷VŠð=*É 0¼OÚûXªFü·ü…ÕüÉ?—ì¼Ã©½ôL Ö†#âX$ô8ÈÊ~òÿÝ|×} hÖº&‹e¤Z3½µ„)o ÊAr±ŠÅB¯/’â¨üUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®ÅSÏ'ÿÇXÿÆ&ýcf¸«±U ËûK$î¤,²,1’ «¿Ù]늫â¯ÿ×ôg–-.­îõ¶ž&g¿’HK rBxŒU=Å]оüýü”Ò|ïæ©Çw%†²GÌk,.‹Rªñ’8Ò¿j6_ò•ñWÝÿÎ4~cC)HZÆê:í$s²Š{‰*È|­ÿ8»¨µÊMæ}N(íTÕ­,y;¸²euAû“}¦é¶e„}„ mej‚8 AEU^ƒûqW‹þfÎ;O®kw:ß–ï ¶šõÌ×v7\Ö?U·wŽDYïâ(Éö¿oI<¥ÿ8Á«~’Š4_[®Ÿ{[6w’Z°]–1Ÿæ^mþ¯ÚÅ[Ðç|×§kšv¡.©`ñYÝCpè¾·"±HT¥h1W£þm~S7Ÿ"µ’VK› Â(-[–ä”JÉÛÔ¾‡†*ñçÿœaüÁp[½5£®ÒúÓOqèòü1W¢~ZÎ>YykTƒ[Ö¯QÔ­;X"R¶ñH:=[â‘—ö>ãü¸«Ó|ÏåÍ;Ìš 拨©kKØø9_´¬$u¯í#…uÅ_;j¿ó‹Þq†å†™¨XÞZ×÷o+I´ÿ)H¿t˜«Óÿ*?)¯<³å}cEóÛ^Ǭ5&†Ü» ŒÆP©gXÏ-û/ʼçÌó‹¾c†õÛ@Ô­®l‹V5»/ Ê;ÁŸÍ𩊣ôÏùÆ-M´ûÙµVõwˆ¥Œq™ !Ø<²2‰ˆû(©ö¿›d”Ÿ’Zÿ’üÒúÅýý¥Ì k%¸ŽSŸ'd`~4QOƒ@þe~Aù“Í^uÔuû=FÎ kÏGÓŠoW˜ô Ž#^(Ëö£¯\Uœÿ€u/ùTŸà¿¬Cõÿ©}Wë?£Ë—*ôçÇýŽ*Á¿- üÉå_:éÚýæ£g=µŸ­êE«Ìú°I§$UûRW®*õÌ-Ýy›ÉÚž‡i,pÜ^¢$rË^¬Šûñô_ Uæ–‘bòœm5ËÝBÎâÞÝ&FŠW™2FÈ)Éu>8ªuùµùoç;ÅÖ4Û¤°Ö‚æõT˜gTÙ •ø‘Ô|<èÿ㊼ãLÿœcóÄ“úú¥•­aê´/,Ì@î±”[ý›¦*™kß󋺤š¤¡ê6Ðé"XRèÊf,±*ÈÏÁ Õåÿób¯Tóg‘µ gò»ü!Ä1ÞýVÎßëËÒåjñ3j7¤xü8«ÌtùÅë…[صíJ²ÃKìù—ŠpÀ†e‘Q^><•’¿ð?kHgÿœ_óÒݘá¿Ó¤¶¯ÃpÒL†Ÿå'¤Ä7°-þ¶*õ_ÊßÉ#Ésþ”»œjZáR±Üpã…D¤“ÉâÒ7ìý•O’¨ŸÎOËmWÏZfi§]Ajös<®×èC' تò_ò³XòéÒ7v÷_¤¾­é}_ŸÃèz¼¹sUëêŠb©Ïæ?å_—¼ói× ZjVà­®£Ôø:šz‘×~5_òy6*ñ;ßùÅÿ<Å?Ký>æ~剩âÉéµ?Ø»â¬ÃÈóVzeì:š/P–…°a%Ü‘‚¼‚¿±Â?ò¹}œUWb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»O<Ÿÿcÿ›õŒUšâ®ÅXçž?Þ=7þÚVßñ#в™uúÄÄv,ÍHþü*‚Òÿç%?1mf yõMB*üI,>™§ù-Jš¶*úòóΫç.E¬®Ÿ6œŠ¦¡V+Õ¢}½Hëðóâ¿,U“b®Å]Š»|«ùÓù«æ]CÍš†‹§ÞÍc¤i“=§£ní–HVZ3|a‚¯ØãþV*»òƒÊŸ˜)ç-W¸´Ô"Ñf“Ô{¦õ=6ŒÆÌ¥…»}¾&~,Uôž§æÏ*éW"×TÖll.J‡]\à ñ5¸»+q4늣4íOMÔíVóN»†öÑÉ qo"Ë*h@t,¦‡lUŠ»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]а/ÌÎ/-y'ýP×ú˨tÓ¡ ì´Îj#Sògÿ#Ž*ñ-Sþr[óêV6Kg§Å_c‡Ôj”Ò—ü•qUMþrgÏ–s/é(m5;züjSÐò^?…~˜›}ä?èžuÑŽ£¦sâaݬ£ãŠJV†›2ŸÙuû_ð¸«&Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®ÅZfURÌBªŠ³€¹ÅR8|ûäiæŽ<Å¥Ë4¬(’öÝ™™UCÔ±=*žâ®Å]ЧžOÿޱÿŒMúÆ*ÍqWb¬sÏï›ÿm+oø‘ÅY*ÿÿÒô7”ÞÏ0ÛJOøŠâ¬v*øçþs[Pºo8èºy¨´ŽÍ®~ËI#ð?JªøXó_—üѧKB»–k#BÒ„’:H ¥dT~Œ§ìâ©wš2¼“å[ȬµíHYÝO­^Œò“b¼¿t’ñ+uÅS/-y§Bó6›úOD¸7V%Ú!1ŽXªÉN@ UÒ¿jœqV;¯þtþ[蓵µÖ°“Ü¡!¡´W¸ Ž ¼`Æù%ñT6ùïùeª\­²j¿T™Ïq¼(~ré/û7\UŸ«”ÕNàŽ„b¬ßó×ò®æâ+xu¾sLëkõ[ÁVc@*a©ÅQjüâò–/ÛNÔoËßÇOVÚÞ6™£®ÿQÁ[üŽ\ÿÉÅY^›©ZjZe®§jŬï`Žæ`T˜å@êH=>аÍoóÇòÏHíåÕ…Ôèhéh8´þñG¥ÿŠ£¼­ùµä/3Ü­¦—©¯×_ìZN­Œ|8 !öFlU—â®ÅR=ùž?+ùGS×C½œ5F™ÈŽ%>ÆF^_ä⯌ôû-sÍþhŠÕÝjú½ÇÅ,‡«¹äî粨«7òªâ¯©<§ùä Â8ïlW¿â>±wv9†joÂ"}4OåÛŸó;b¨o3ÿÎ=yYž ìámÒ@×"ÓìKtàĤmü®ƒýƒb¯@Ðô-'BÓ!Ó4›d´²·Ž(ÇÞÌz³·í;|MŠ­×<áè6F÷Y¾†ÆØ &`¼›¯iÛü•±V ÿó‘?•Ë?¤/§d­=qm/ ‡ÿ„ÅY§—<Ûå¿2Z›P†ú%§¨#4t¯Nq·¿åªâª¾aóåÝ*]WY¸ú­„%VI¸<”.ÁWá]÷cü¸ªC¢þnþ]kR\ǧë1¹³®®žX§·D…P¹yã>Ôˆ´åËâÅRgÿœ†ü­K£é™¡¸[iŒñð˜«=Ò5+Y°PÒ²›û¹â`Ê|AðaÝOĸª&Yb†'–WXâŒy…UQ¹$€«Õ¿>ÿ,4éÚªÉѤO*”€Ûýƒ¶*œyWóCÈÞh˜[èú¤r^_ªJ7[òη§ú*8à–S¡õнÀŒ:WÔ†ž“ÂÉû\±WËÚÎú7X¾Ó½OWêWÛú´ãËÒrœ¸Õ¸òãZW{µ—üâ×;Bÿâz}f%Ûê?f¬¯ÿ-ýšb¯*üÌòø#Ìk£}{ô‡+t¸õý/Cí³/<åéï,U˜~^~@ÿŒ<«m¯~žúÖTú·Õ=n>”…+ÏÖŽµã_±Š£ÿç"¼úß˺¬'ÕHícÒnæ À4–Éû§+SF‘ŸµþëÅY_üâÿ™Ï–u- gýæ™8žÇaÀÜe•›þ2b¯óf¥uæ8kZ­º4Ââk‹• ¯hªTŸd…WzÏüâǘ==CYòü´ñ¥õº“ûQNZ{°xÿà1Vù˯?˜?2õW„™b·”XZ(©ÚÝ¿ëK͇úØ«éÝÈVV¿—ÞO¹/FÏм’ÝÌoêÉñÌêËã+1þV_…¹.*ò}3òÉ:%ÅÃùÛÌ$bCõ(â+@b­å2ü\Ú¿b?…ߊ°/Ío(ùF{k¿'ë‘j6ó³Gqd&I䉀¨udëtø¾Ë~ÓrøU{güã˜îµo ›K© ’é7-kcVô ,‘ƒßáäè¿ä¦*ùV e†h慊͇PÊjúqW¸i?óŒ~`ÕlÆ£®k«e¨Ýþþ[A®\<Ÿõd2EûÊŸŽþ/ÚÅZüðó^¥åí Cüº±º Zi¶é«ÜEUõDh"HüUÓ2:þ×(ÿÊÅR¯ËÊ¿!ë:jþjóV’\3}_OŠêÞTRW”¾§&«UJ/Ãþ¶*Ä¿2¼£¥yOÌ1C¡jñêš|È'¶¸ŠXÞX˜1$h9­9+˜«éïÉÿ7\ù«Èvãs¿ˆµ­ãÿ4šsùºvÿ)±Viм«þrQæ_Ëb#¯½·ÓùhçöAqW’Î6Çnÿ™q´´çÃA_çøTÓýƒ>*úÃv*£yu¤÷w  xÚYœöD˜ýb¯ŠüÛæ0yÿÍßXpóMw0·ÒìÔFŽÜc‰JšŽmûoñb¯LƒþqWYm4K6½Z‰ZýU`w„5:¹«}>†*òëk¯4~^ùÉø1´Õô¹¸M$Ç"ìJ·NqJ›ÿªÜ±WпœzÕ¶¹ùÚۤ7ëe:¯R¼åBTû¡øN*ù×ÈþTÕ|׿t-6A —jÞ¼®Hb÷Œ\/Úªñ_çኲßÌÿÉCÈÚU¾ªº’jvRJ ˜ˆL²–SÇœ¡ñ#—/µŠ²¿ùÅnáumgCg&ÞKu½Ž2vWÄNT–%N_ê.*…ÿœüÀ¿º×O”,¦1éÖ*¨*zÓÈ¢EV#ªDŒ¿ûó—/°¼UJ¿/¿çu¯5è±k7zŠi6W µ¢˜LòÈ ‘̧8‚¡§ÁñüX«;üµÿœy} ÌÒj¾až+ج$VÒRÁdqFJ¤|<ÙŽ¿oüŽ<Õb?ó‘˜ú‡™%ò­¤Í“¦ðúÒ! šå”9-N«`Š¿ÏÍ¿—EyòwòÚóË–×Þdó4QêW‘ ~­oyk€8ª«sÍ"µû*ßUæþgÓÉ~sx´]U/Œ‘Üiú³«TjP²óSðºÿƸ«êï01~Jj:ß}¡]É*‹(¶‘dQì$ LUòO—´­[XÕíô%Yï¯ÛиÔ6íÈÿ QÉÿÉÅ^Ç/üâ®®ºq’=~ÔB×ê¦XKxzÜË}>†*ò+Tó‘¼ÙëÃÊÓUÓ&1\ÀNÍÁ©$OMš7§ün¿³Š¾…üÄü¨ƒó"K7Ûë&ÂÝ´¸}smëCÎá[Ÿ«*&ãN8«æ}Ný%¬XéÞ§¥õÛˆ­ýZrãê¸N\j¼¸ò­+оšü¼üÿy¦Û^ý=õ﫤©õoªz<½XÊWŸ­%)Ê¿gx'æž±¨ê¿˜:ì÷ÌÆHo&µŠ6ÿuÅo!|•à¾,UèzäŸåç˜tËmYµçEf†âH¸#t0*­Ä_O©Š¾Œüòä»q¥éõ’G¤¼»qGš_„#öTtDý•ÿ+“2¯ZÅ]Š»v*ÿÿÔô7”ÞÏ0ÛJOøŠâ¬v*ò¿Î9h¾QŽ}_Vˆ‘!…(d–Bã•cÿ ¿*‘ùwÏ^Róž—ºf¥¨ëÊHYÕfÅeŒžHGýsоmÿœ‚HÿÛ·–¹¸h˜êßS*`õy|càõiËÔãþO/g_óŽúeýçå§™­”ñŠúi µ'oÞ5ª£0?ì£ÿÅ^å=J=Î:V¡}ôÛèeºŠŸH €?™hÙb¯¶¬õÍ÷M­ôiÅyýmdS_Õ¢ûòÅ_"~uy—Lóæýö˜âk(Ö;xîìÈb@Ô÷^U ß´¸«é_É6çMü±Ð-®AYL ?êâWü‹Š¾IóŸü¦ïý´.¿äû⯸´ïøçÛÆ$ÿˆŒUòïüäÏþLh¿íŸüœ—zçüã¥Õ¼ß–6pÅ"¼¶ÓÜ$èèÍ)p÷VVÅY柖™ü…ªiÑw>—ÖlˆÞ³CûÄ ÿ)éÿ³Å_%y/ΞW¼Ô.-«[ý>æÁ¸š3'îÜÆ9B6*ôùÆÏ(Ûk^a½¾§ÔΛB6?\¯©Ou)ÿ=1VåÝgRü¾óÛ\²s»Òe¹µž.„õýž_*œ~HyqüÇù“d÷Õ‚À¶¥v[z˜ˆ)Zõå;G_òyb¯vüûóÆ©åo(D4™ †§7Õ’å~ÔQ„-#!ìÿeTþÏ.Kñ.*ðÏËÊKóâúö}HZZÚº‹›—S<òK%ZK/‡Äîÿðxª7ó{ò“Eò&›a=¶«-ååìÌŸW•QO¦ˆK8ã¾ÍÁÙb¯@ÿœVÿ”\ÿ˜¸¿äÞ*ùóËê­¯iªÀ2µÔ!”î2.Ç}銾Rÿœ“Ónm¿1šî@} ûXd»~ì™~‚•ÿeЬü¼ü_;y}uk?0Eo*»EufÐx]NÁˆ‘kÍ8ºšb©­çüãµ–«i¤ÝùÆÒ Jø3ZZ¼<( +/¿Ãüÿ±ö[{GåOåüÞFòíÆ‘5êß´÷ov&XÌ`Ž8øñ,ÿïªÿ²ÅYž*Åÿ3<¬þhò>«£ÂÖ¥ˆIi_÷ô,$ŒW·6^ÿ+|åO1j>RóM¦¯d]iò‘-»Õy- Kw^JYÉÅ_aù[óÊg±K­3Q„» Éi+¬wžáã'—û!ð7ì¶*“ùçóŸÉ¾SÇ%ÂêWÏ"«ÙYº;Æ•øÝÍx¡Uû(Ç“ÿ«ñª©œú¾•ço!êå륺MBÆæÚ"§‹¤²ÂÈÔîŽ tlUò/‘5›mκF©|¤[Ù]Æ÷"•e@hçó <©Š¾Öƒ[Ñ®4Ñ©Ã}šq^\YÑãJÔ½xŒUñçç˜ôï0þa꺖šÂK&há†aÒA KqþK2žäqÅ^·æý6çMÿœf²´¹gX¬äun«ë\,¡Oú¡éа¯ùÆoü˜ÒÿÛ>ù9*õŸùÈÿü–sÿÌ]¿üHâ¯.ÿœ]ÿ”ÿPÿ¶Lßõoб¿Ï=6æÇó?YõãtÑÜÀçö£’5ܪÁ“ý†*ú/òkÍš.·äMÚÒâ?®éÖÚ]ÚrThGȧ^2qæ­Š²Í7_Ñu9îíôëØnæ°qäq8s‘PŸçË’ý¥lUòç6›s§þfk©8#׸úÌLz4s¨‘HùWûU–ùGþqçüOåë-nÃÌú7q†x¾®ÌÑH6x›÷ƒâ¾UXÎ;Xq´!çOÓ œØúÔôØ =_jñû\~/²Ø«Ö[Ê’yOòCWòü—"ñì´N· ¥z«<£á%©ÇÔã×|áùAæM7Ë¿˜ZV§©7§b¦H¦š•ôÄÑ4aÏù*Ì9‘Ë}‹.³¤E§NKØN Ïë†Dôxøó¯Ç|[ù‘¯YkþyÖu{÷Žæàú E9"(Œ=N|y⯮¼«§O¦þ]év­Å¶—s)ê²5ÿbÛb¯|«q·š4{‰ÜG7ÖÒK#tTIT±? 1WÝ‚D!H`Cý‚Çjíã¶*òÌßÉo(ù“Ìk5¶¬š7™55iE«t¹ô€ë$uz}¶CþW\ÛxÇæäïš¼‘kýü–÷:|²ˆRæÙØñr (tuF‚·Ùæ¿åb¯pÿœ:óηªjº——µ;‡»ŽÊÔ\XË),èœÂ ä¸ªi¯~Fþkêzbkœ«y†yV6³{˜™¡· Ä—–WXëÏáfUÿˆ*ô¿È$ùŸÊš>«o¯Ù}Jk›„’õb—’ªPšÄò¿Ž*ñíò+óRÛX±¸›Dá 7I#}jÌÑUÁ&‚bz Uõ¶*Ä¿2?.4<è¢Êñ½í¹/a|£“DíN@­G8ÞƒšWþ|õqù7ùÇåk÷—FŽvê¢ûJ¹àY|(9‡Ò˜ª¶‡ùùŸæ-P]k¥´ärmBúQ4æŸÊŠÍ#8ÿ‹?õñWÔ>ú7KµÓþ±5ßÕbX¾³rÞ¤ÒqäíÝŽ*ŒÅ]мŸóKòMó]ÌšÆ2iºÛŠÎÑîùŸˆä’xÈ¡¹~Òrø±W†jŸ’Ÿ™Út¬’hs\(? ¶¥'V FKöJ¸ª¦‹ùù™ªÌ¨4w²Œý©ïX@‹Ú¥Md?ìclUôwågåfäM6UYæ«yÇë·t*´_³iSDZõûOÿª«üÖÿœ|—YÔg×|ªñCwrÆKÍ6SÁFݤ‰ú+9Ý‘þ_5û8«ÈßòWóEgô—ççZT©dlå„KëÛËñ³¡ŒR;tSÛzçg–5Ï2ù]/E¶úÝó\C"ÃÎ8þ$±å+"íþ¶*Àÿ!,|ñå_8^jö›õ;9tù-ã—×·–²4ð¸^1HíöQ·§UŸ~j~Uiž{Óâ&Ag¬Z,ïxòNæ)@ûQ“Óö£o‰m]WÎÚ¯äOæ~;Gú ÞF {I#•Ü ¬€®‹Š³ŸÉßÊoÍ ÌkºèvJiw ¬²½Ä5©Òˆßù¤dhþÚb¯Kü×ü¤Ó¼õiñʶZ媕¶¼ ²ºTŸJP7áÈÕX|Qÿ•öqW„ÿÊ«üíòÌòÅ¥Áyrü/6—uÅ$â7G§üdEÅS%ÿÎ?yÿPÖ"ÔµéßD%=Ϭ$½vµƒ?ÿ‹$‡íp|Uï~~Óü»ó|™øi«ÉÏ&4¶qR{œUñß’|µþ'ó=–„&ú»_zˆ“È+¬NëQü¼”rÅY§ùùŸarÐþ†k´‰=¬‘Éñ_öh˜«?ü«ÿœzÕbÕmõŸ7Æ–ðZ²Ëo¥†YIÕLÅK"Æ:ðäÌÿ·Çö•}@ ‚*ÄUò·ž?ç¼ã¦ê·ù~×ô¦#³ÛzN¢hКˆÝ«1_³É9òÿ'ìâ©×ä—å¿æ“ç›SWÓ&´Ó-#YçtL‘2¨XùsÜŸÙ\UKó;òó^ÿÍ7:ì.¶$pÖÓ[ȰK jv‚'eáéþϤò¿â励¹-?<|ÄÑ[êVÚ…Ìq‘Àê7UŽ>Õ´‡þb¯¤?ç*G‘fº–òtºÖoâ¥Ì‘WÓ‚±ÆZŒß,ÏÅy|?ʽçv*Ç|ì̶zwEu`i¶ÜŽ*ȱWÿÖõ4pCsj†Fç!P&=Í:œU~*ìUƒù·þ; þ¢~¬U&Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUþaÿÊæoûdßÔ3⯕$òièñ–_ù1&*û+v*ìUØ«±Wb®ÅSÏ'ÿÇXÿÆ&ýcf¸«±V9ç÷Mÿ¶•·üHâ¬ÿ×õN*ìUØ«óoüvýDýXªMŠ»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUت•Õ­µÝ¬Ö—Q¬Ö×ÑO Š«£‚¬¬Ue48ªK§~_ù#M½ŠûOÐì­o $Ãq(®¤‚  ¶8ªŠ»v*ìUØ«±Wb©ç“ÿã¬ã~±Š³\UØ«óÇûǦÿÛJÛþ$qVGŠ¿ÿÐôg–.î®.õµžV‘`¿’8Cñ@x U=Å]а6ÿÇa¿ÔOÕŠ¤Ø«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»O<Ÿÿcÿ›õŒUšâ®ÅXçž?Þ=7þÚVßñ#в·Ö.b¶§.<}RG.Zxb©Ž*ÿÿÓô¦‰¤M§Ï©É#«‹ë§¸Œ-vVPÔuÛMqWb¬Í¿ñØoõõb©6*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®ÅSÏ'ÿÇXÿÆ&ýcf¸«±V9ç÷Mÿ¶•·üHâ¬ÿÔõN*ìUØ«ó{*êÎÌBªÆ¥˜ì©Å^+æ¯ùÈŸ"h³ÉkdeÖnc%XÚ;zÎ@oœk"â¬R?ùÊëc5$òÓ¬5ûkx©þ©…Gü>*Î|Ÿùíä?2ͧÖKÔ$!c¶½ ØöIT´g}”3#·òbªþ{üãòÿ’µHôýcNÔ]¦ŒKͼp<2/F Ï27$;:•ÿ…eÅRþr;ÈZ®­i¦¥¾¡j÷’¬)qs ³š/6Yœª×jñÅ^©Š´Ìª¥˜…Uf;sм–ïþroòúÞîkuµÔ®dÅŽ@¦œÐ´êܪòUÅYw?2´ŸW×<ͪ¦•¢Û«ÇÊ‚QÙˆUE¨ßzßüã?æ4†xßO¹ ýV)ÜHO…dŽ8ëÿ=1Uÿ”ÿ’¦¹®Kqæ[Yl´2cͼ¡’K‰“ýÔ½?v?Ý’/ú±ÿ2*÷OÍ/ËËO8ùIôØ‘"Ô,Ç«¥I@H«ON½£‘~ÿbÿ±Š¾5¹¶¹´º–Úæ6†æÝÚ9¢qFGCFR;F*ú÷òOÏÃ;Pˆ]KÏXÓ8Ûj?Ð~êoùê£âÿ‹LU"ÿœˆüÂýåñåÛ 8êšÂ;)£Ei^.~sÆ?ÈõqW;Zòö¥æ-rÏFÓcõ.ï$¿Ê«Õ¼oòqWÛRòÆå/YèšxýŪQ¤ ’C»ÈÔý§mÿáqW˜ª¤ÍÑÏ ´sDÁâ‘MYMU8«ìÏÊ>Ãç?)Á|ì£S¶¥¾§Ú“(û`$£ã_öIû«3Å_Ÿ˜«êÿ$é7šÇüãäUSw{§]AsÅK¼²SÛyý ‡ægûâÓþ’úb¬?ΞE×üŽ´‘¤÷zñˆœH8r+¹늭òg’uß8j’éš*F÷PÀ×.%qújè‡sß”‹Š³/úÌÏ÷ŧý$/ôÅ^±æÍûCÿœw¸Ò/­å”1ι/!p‡cß®*ù[~â®Å_*ÿÎLÿ䯋þÙðÉÉqTãþq[þR sþa"ÿ“˜«Òç!¿òVj_ñ–ÛþO¦*ù&ÞÞk›ˆ­á^sLëkP*ÌhMSгßùP›_õbÿ§»?ú­Š»þTæ×ýX¿éîÏþ«b¯gÿœ~ò/š¼§g­Gæ ©=Ü5¸õa—EpßÝ<”§!ö±T«þr[Ïwºm§•´ùL2jQ´úƒ¡£~E=·ã++óÿ%8þÓb¯Ÿü»å½kÌz¬ZVl×W²Ôª >Ó31 ª?™±W£\Î3~cEhgI4ùå¿UŽwV*ñ¤Uÿž˜ªÏÊïÈýk]óßâ+Yl4.P—±H I4ƒF3ü´¡yý†ø>×,UõÔÁ¤Í(#†+vHãQ@ª©@ð|оÓüŸÿÉgåßù„_ø‘Å_?~ùî÷]ó…΋¤i,†„…îá–F«+r•Wü¶ÅX·’?-|×ç9e]Ý~¯ =äíéÂŒw M 3’ŠØ«$óüãÇæ.d÷‹¶§kÊD°‘Þ@£© "DÏò›b¬óòòuí ¿›üÁ[’=M"ÅÁ0zO þb?ºOÙþóíqâ«Þ±Wb®Å]о|ÿœ¡ó}_Nò¥³ì¿éÚ€&©ÏGeÿŒmоÅ_b~GùÀy—ÈVfi9êgú å~Ñ1鿉ç ·óóÅYþ*£yymei5åÔ‹ µ´m,ò¶Êˆ€³1öb¯¿5?55_;j®ˆïo [¹úiP6ÊÚ‘¿ä—ÙOÚfU"òŸ‘|Õæ»–ƒB°{¯Nž´Ä„†:ÿ<ŽUÿ&¼¿ÉÅYúÿÎ0þaD†ïLJú&i¹|¶‡‡ü6*ÀüÛù}æß)αëvr0Ü©BçÁdZ¯/òÇþN*ú‡þqGòÏUòÄ“ë:´³A{©Ûº_"#Ž ÊÊò§C9í_î“áûLüU}#Š»cžxÿxôßûi[ÄŽ*ÈñWÿÖô7”ÞÏ0ÛJOøŠâ¬v*ø‡þsNº·ü׎ñÁ6÷º|§ÃX‹# >+ð±ÿ_a“_˜¶^Hó÷Z…»Ía}¡;D’:0euŽCo‰kо¢ò÷æ’¼ÄiŵįömËúsïÿIÂOø\U‘b®Å_<ÎH~[zR4È¿w!Xõ˜Ôl®h±Ü³Ú9?Êàß¶ø«Ì¿+|û7’¼Õ¦Cɧʦ FÝ)W…·ª‚@çëÿûXªQæï3êgóî·|}w!e޵Xã$kþJ-}ÿ8ùùmúDÿj1qÕõhÇ Œ7†ÔÑ”{4Û;“é¯ób¯^Å_Ÿ˜«4ó/e±ò/—|Ýh¬öz”MøÜúw +ª7²J‹ÿü늯ü¢óüžLód7R¹ýyK}N1¸ôÉÚJ4-ñÿ«Í?o}•±ËKŽE ަ ©Øâ¯ÏìUö_äþJÍþ1Iÿ'äÅYÆ*ù—þr›þRý'þÙãþOÉŠ¡ÿçå?Ô?í“7ýDÛ⯨±VùÝÿ’³_ÿŒQÿÉøñWƘ«ë/úÿË?÷ýßý#·õÅ]ÿCùgþÿ»ÿ¤vþ¸«Âÿ:|ã¢ù·Î ªèí#Ú-¤P*Ûš3“±ÿXb¬Ïþq[þR sþa"ÿ“˜«Òç!¿òVj_ñ–ÛþO¦*ùGF¸†ÛX±¸™¸C ÄRHÔ&Š® 4=*úÛþWçå/ý_éÒóþ¨â®ÿ•ùùKÿWßút¼ÿª8«-òß™ô?2鋪h·?[±ghÖnGñ&Ì8ʨÛ«Š¾uÿœ¡Ó®¢ó®Ÿ~À›[«Ž'¦Üá•ù ù ¿Ùâ¬SòóÓÉi}BöÝ籺­n=*YÕà$¡MÖ¸«ê_.þcùÌAF“¬[Í3Ò–ÎÞ”õ=½)8H~…ÅY&*‡ÔãŸsÿŸþ"qWÀ˜«í?Éÿü–~]ÿ˜Eÿ‰Uò‡æFu§yûÌ· ‰üòÂ…’Y ‘¿û4ulUèß‘_œ_ò®›>¯+ÛÛMp×0j©‘Tº*²Ê«WýÅ•_} ¢yŸËºä^®©[_­*D+²ÿ¬ ò_öCLñWb®Å]Ѝ_ÞÚØXÜ_]¸ŠÖÖ7šyEHÔ³  Uð×›|ÅuæO2êÝÍD—Ó4Їö# iþÂ0©Š²>þYÜygÊ>WÖ™[ÔÕ a¨©éîLÑf07Í b©·ü㿜?ByÝt¹ßޏ¢Ø‚hÂ’`o¤–‹þz⯫ñW”ÿÎHëòé¿—âÆã&­r–ïCCè 2¿ÞQ¿É|Uóƒ£ÜëZ݆‘m´÷óÇo™/#ìµäqWÜ>Zòî—åÍ×GÓ"ZZ UþgoÚw=ÝÏÄÇDjz¾“¥[ ­Rö bÁ÷R¤)ÈÔ…äåW‘§LU$¹óÇåµÔb;Ÿ0hÓÆ®²*IyjÀ¼…]|Oò—|»æÏ,ê>Yó扨-.-ˆp(²!Ý$_ò]lUôüãæ'éM!¼§¨K[ý19iìÇy-A§ ú´Óþ1qÿ}¶*ù›}—ù#ÿ’³@ÿŒRÉù1Vqоeÿœ¦ÿ”¿Iÿ¶xÿ“òb¨ùÅßùOõûdÍÿQ6ø«ê,Uƒþwä¬×ÿãò~Ü£Fãæ¬Å^‹ùcùÝæ/-jözµÔš‡—Ý‚MÄÉ$M9Âæ­ðuô¾Ã“ö±WÕw²$šdòFÁ‘àvV‚ Å_b¯´ÿ'ÿòYùwþaþ$qT»ó?òwDóÂ-ØéúÜ)Â+å^Jê7 2TrÊÀó_ò—àÅ_=y—òCóAæï¦6¡j•ÿI°>¸ îP2õ£ÅXD3^XÝ a’K[¸át-ˆÃcB(ÊÃ}ùùÑ«jº¤^Vó$ßZšuoѺƒPH]c§öù(<$û|¾çÏáUïX«±Wb¯ ÿœ“óè¿(Å¡[¿½ié-:‹hHgùs~ þRú˜«À?.4MwΚ^Ÿ{$qX„·¯+*§£æêKmñ…ôÇúØ«ê/Ío/ùŸÈÚž•¡h×b?^Ä £¯¯Æ€|_·OOýž*øò æ‚hç…ÌsDÁã‘M ²š‚ˆ8«íÿ ù¦4ùGMÖÒ‚K˜€¹Aû3§Á*ü¹ƒÇüœUå_ó•qÊt/È+é-Äêþ™¯à­Š¼—òjh"üÏòóÍNä ­>ÛÆÈËeÅ_gâ¯&ÿœ™ÿÉsý´ ÿˆIоUÅ^—ÿ8Ýÿ“·Êßñžoú†—~„â®Å]Š»ÿÐô7”ÞÏ0ÛJOøŠâ¬v*ó_Í1i>]z¾«0†ÊÚ$.z³²¢Úw;(ÅR_.ù“Eó—§£Ý%Õ¤£í)ø‘©R޽Q׺¶*Å;tï,Üþ_j—ÚD%¶ÛMÀ-ѺHÛí~ñ«¨ýµŠ¾9Å_yym.S˺Z]Wë+gž½yˆ”7ü6*˜â¯“ç#ÿòfOÿ0–ÿñвŸùÅ?øèyþ1ZÿÄ¥Å_Dâ®Å_Ÿ˜«ì¿Éü•šüb“þOÉŠ±ŸùÈ˿ӺóŸ-WHBgU¶ƒâaþ´;È¿äzŸä⯛<»¯j>_Öìõ9ý;Ë)‘žÄtdjuGRQÿÉlU-Å_eþHÿä¬Ð?ãŸò~LUœb¯™ç)¿å/Òíž?äü˜ªþqwþSýCþÙ3ÔM¾*ú‹`ÿßù+5ÿøÅüŸ|iŠ¿@ñWb¯•ç&òcEÿlø?ä个qÿ8­ÿ)¹ÿ0‘ÉÌUé?óßù+5/øËmÿ'Ó|«åßùH4Ïù‹ƒþN.*ûÏv*ìU¯kº^ƒ¤ÜêÚ¤âÞÊÕ9Ë!ÜøQûLÇáUý¦ÅT<±æÌÚTZžr·6ÒÈ9ÆÄT¤‹Õ”â©ç囿 êÒëÉ[{yÊwÔKž'Ñô›írgâ¼GÛû-ð⯌qWÜ^[K”ü½Ò’ê¿Y]&=zóÊþ|;оÓüŸÿÉgåßù„_ø‘ÅQþmóç–<¦¶m­Ýý_ëÒˆ`P 7ùR0ˆã¯Æøªykumwoͬ©=¼Ê)£`èÊwXTм;þr‡NòÊi}ñH£ó—,¶ÁŸ©O´¨þŸo³öWí6*ñŸË¹Ì_-‹zúƒQ¶-OäY“þI†Å_nb®Å]о0üßó‡ø«Ïw÷Ñ?; cõ; ê=I‡´Ž^_öx«ŽÎîT:Œ¨Ä}àb«¿GjòË/üLUNX'„4m;€êV¿~*÷/ùÆ8z÷•.‘Þy` ÿwF J£ýx¿üòlU韞žT›Ì—׉j†KÝ5ÖþÝ©oH"Žõ1;ñ´ÜqWÈvwwwp]Û9ŠæÞE–ªº0eaò#}ùiù¥¡yÓKˆ¤ÑÛëh€^é¬B¸p>'ˆWˆõ ¿göñVmмgþrŽîÔy+N´3Gõ¶Ô£•mùPƶó«8Jòâ”ÿ+yoüãwþNß+Æy¿ê\UúŠ»Cßj6v)ÝIé¬Ò,1š3VGÙGÂ\UŠ¿ÿÑôg–-.­îõ¶ž&g¿’HK rBxŒU=Å]о+ÿœº_Ì)¼æ_U¶áåkp£I’سÂy(çj7 Ó‹Ž*¿ <þ7u^¦ë¶—1ŸL½¸±œìe¶•áz¬…N*»T×u½YÖMWP¹Ô>ÃÝM$Ä|Œ…±W þN~Qê~iÕíµMFÝ¡òݬ‹,²J¤ ’†¢(ÁûjÄRGû*¿å⯭1Wb¯“ç#ÿòfOÿ0–ÿñвŸùÅ?øèyþ1ZÿÄ¥Å_Dâ®Å_Ÿ˜«ì¿Éü•šüb“þOÉŠ³vPÀ« ©ØƒÐŒUñ÷çWåéòšÜÚÇÇEÔËO§>ß÷ÿÏ&?üVÉŠ¼û}—ù#ÿ’³@ÿŒRÉù1Vqоeÿœ¦ÿ”¿Iÿ¶xÿ“òb¨ùÅßùOõûdÍÿQ6ø«ê,Uƒþwä¬×ÿãò~¦8+µZ€ ÑŠ¾bü×O=7›®n<áC{)"߈?WôTü+nße¢ð\¿¼ýç,Ué~fó&“G¥jך|ljÉkq, Ÿq.*„»½¾¿¹3ÞO-ÝËÐ4³;HíáVbXâ¯ÿœü¤Ô¬/—ÍÚõ»[H¨Ë¥YÊ Ê ƒ‹Nê~ÇÀYcVø¾.ÉÉW¾b®ÅXçW›ÿÃ>B¾–㨩Yo¸iãþ1ÅÍ«üü1WǶÖÓÝ\Åmn†K‰Ýb†5êÎ犨ù“оæòw—mü·å7D‚…l Tw·!ø¥örlU8Å^Aÿ9)å/ÒžP‡\‚>WZ,•”ަÚj+üø8¿É_S|ÙåÝróA×lu›3þ‘a2LŠMq;¡§ìºÕüœU÷>‘ªYêÚU¦§füíoaIánüdP´î+ñb¯Ÿ7¿!/Ἰ×ü£nn,æc%Ö‘þò&=Zn6?î¥ø£ýŽIöxq·<ฅ½ÑÑÔýXU8|óÀ‹ÑbÔÄ4§¦/.8Óœ銤ÓÏ=Ä­4ò4³9«ÈìY‰ñ$îqW°Î1y7ÍŸšš·›1Ò,^i®oÙxBÀñü,üD‡›ªñ“b¯¼1Wb¬sÏï›ÿm+oø‘ÅY*ÿÿÒõN*ìUتÿBÒoË›ÛdŸÔ^¤2Ò”"´#a§üã¿ä¶§!’çʶ¨Í¹ú³Ïj>ëy"ª¦“ÿ8ýù7¤È²YùZÐÈŸa® ·$ô‡—|U—¯–´5P«hªª(ª ì7Å[ÿh¿òÊ¿{\UßáÍþYWïo능—åwåΩtnõ?-é÷×D3ÜÛÇ4…W æášƒUÒ.|‡£´¤h6ZsL™­!X …­zayR»WL¿Ãš/ü²¯Þß×wøsEÿ–UûÛúâ¬{þTÏå/ýIúGý!Ãÿ4â©Í“¼¯akŽ› ¥¤@ˆ­à_N4Ô…E¢®ç¶*ˆÿh¿òÊ¿{\UªùÉz¼)­£ZêÆÜãŠê1:«Rœ‚Éȡ능Ÿò¦)êOÒ?éù§Nl|å{ XììtØm-"Eoúq &¤*-w=±TGøsEÿ–UûÛúâ©^«ùiù«Ì“êÞ_±Ô&xG-Ô ;*Ö¼CH…©éе¥þY~^é s¥yvÃO¸t1¼Ö°$.PÅKFñª©ãþN*šÿ‡4_ùe_½¿®*‡¾òw•ïíd³¾Óa»´”-¼ëêFà€ÈÕVÜwÅRoùS?”¿õ'éô‡üÓŠ²ðæ‹ÿ,«÷·õÅ]þÑå•~öþ¸ªS©þX~]ê·"ëTòæŸr žêÝ&~"¤/' ÜEzb«ô¯Ëo éI&“ XéÒJÊö¤ Ê @cZŒU¨ù'Êz«Yê:U½í£^Þá}XÉSPJ?%4;â©Gü©ŸÊ_ú“ôúC‡þiÅ]ÿ*gò—þ¤ý#þáÿšqWÊ™ü¥ÿ©?Hÿ¤8æœU¥~Z~_é<úO—ìtù¤^Kk@̵¯Ñ…%j:b©“ùgB‘ÍebÄv ‚qVªÿÎ<þLjŽ^ëʶªÍÔÛ4Ö¾ÿñîñb­é_óŸ“:T‹%§•­K¡ªµÃMtA­kþòòÎ…*%š*( ª¥€lâ­·–´6R­h¬¬(ÊKAìwÅXÿü©ŸÊ_ú“ôúC‡þiÅS«?(yfÊÖ;K-:kXG „ãEðTRGËY¨ù'Êz•«Zj:\–¯»Ap¾¬dzŒU†ÞÎ4þGÝËêKåx•M!¸»wÿ&)‘ U9п&+t)DÚW–ìí®Õ.8³Ê»×á’BÎ>†ÅYøsEÿ–UûÛúâ®ÿh¿òÊ¿{\UßáÍþYWïo능ú·åï‘õ…u}ÏQXI0­ÜK8BÔ©_S—Ó¶*ƒ¶ü¢ü®µ¸Šæ×Êš\0°’ⵉMU••C+ÐŒU<ÿh¿òÊ¿{\UßáÍþYWïo늩\ùOË—VòÛ]XE=´Êcš AttaFVV%YHê*‘ÿÊ™ü¥ÿ©?Hÿ¤8æœU9±òw•ì-c³±Óa´´ˆ¼ 鯀š¨´UÜöÅQáÍþYWïo늤ºïåG导yk_³½’”JŸ½v$ðX«?󌑆oXùa9Ô »à›'áÿ ЧZWäå.”Áì¼­`’.ë+Æep}žRì>üU•Ùèúmœž¥´'§‚zxnqTf*ìUŽyãýãÓí¥mÿ8«#Å_ÿÓõ,76Ó4‹ ©#DÅ%ÁŠ8ê­O²ÞÇTÅ]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*Ç<ñþñé¿öÒ¶ÿ‰U‘â¯ÿÔîÚ¿£iºŽ»õÜvò>¡#*¹5+@+øb©ÏøÓÊ¿õr‡ï?ÓwøÓÊ¿õr‡ï?ÓGéÚ¾›©#½…Â\$g‹²v'|UŠ u-sIÓ5¿ºKs(&0õÜ´ûñTøÓÊ¿õr‡ï?ÓwøÓÊ¿õr‡ï?ÓwøÓÊ¿õr‡ï?ÓDXy“B¿¸öw±Ï9„jMh:öÅS,UFööÖÊÙî®åÛÇNr7AÈ…‰ÅR¿ñ§•êåÞ¦*ïñ§•êåÞ¦*ïñ§•êåÞ¦*ÚyÇË:¢j0³¹ ª ܇lU9Å]Ф¿ãO*ÿÕʼÿLUßãO*ÿÕʼÿLUßãO*ÿÕʼÿLUßãO*ÿÕʼÿLU5µº·º·K‹wÁ(å‹ÐŒUWJï|Ï Y\½­ÝôpÜGNq±5€aÛÀâª?ãO*ÿÕʼÿLUßãO*ÿÕʼÿLUßãO*ÿÕʼÿLU§jún¤Žö p‘ž.ÉØñT^*‚Ôµ­+Lôþ¿r–þ·/OŸíq¥iòä1TøÓÊ¿õr‡ï?ÓwøÓÊ¿õr‡ï?ÓwøÓÊ¿õr‡ï?ÓDXy“B¿¸öw±Ï9„jMh:öÅS,UFööÖÊÙî®åÛÇNr7AÈ…‰ÅR¿ñ§•êåÞ¦*ïñ§•êåÞ¦*ïñ§•êåÞ¦*ÚyÇË:¢j0³¹ ª ܇lU9Å]Ф¿ãO*ÿÕʼÿLUßãO*ÿÕʼÿLUßãO*ÿÕʼÿLUßãO*ÿÕʼÿLU5µº·º·K‹wÁ(å‹ÐŒUWJï|Ï Y\½­ÝôpÜGNq±5€aÛÀâª?ãO*ÿÕʼÿLUßãO*ÿÕʼÿLUßãO*ÿÕʼÿLU§jún¤Žö p‘ž.ÉØñT^*‚Ôµ­+Lôþ¿r–þ·/OŸíq¥iòä1TøÓÊ¿õr‡ï?ÓwøÓÊ¿õr‡ï?ÓwøÓÊ¿õr‡ï?ÓDXy“B¿¸öw±Ï9„jMh:öÅS,UŽùÙY¬ôî šj6ÄÓ}¹U‘b¯ÿÕõéöÅÞÚ&f5f(¤“îHÅZý§Ë,?ò-¦*ïѺwü²Ãÿ"×úbªÛÛ†$ˆÈE _»TÅTæµ¶œƒ4))_³ÍCR¾ÅTÿFéßòËü‹_銻ônÿ,°ÿȵþ˜«¿FéßòËü‹_銮ŠÊÎ'çÆý9**Ÿ¼ U[[$QÊ…$@èz«A¦ý*£ú7Nÿ–XäZÿLUߣtïùe‡þE¯ôÅ]ú7Nÿ–XäZÿLUÃNÓÁZÂÜÿLUŠ»CþÓ¿å–ù¿ÓwèÝ;þYaÿ‘ký1W~Ó¿å–ù¿ÓwèÝ;þYaÿ‘ký1UtD"„EØ*Šô U¼UFK)\¼–ñ»ž¬È¤šmÔŒUoèÝ;þYaÿ‘ký1W~Ó¿å–ù¿ÓwèÝ;þYaÿ‘ký1UHmíáCDä"…¯ÝŠªbªs[[OOZ$—xóPÔ¯ZWSý§Ë,?ò-¦*ïѺwü²Ãÿ"×úb®ý§Ë,?ò-¦*º++8ŸœPGô䨪~ð1UlUl‘G*‘¡ê¬›ô8ªèÝ;þYaÿ‘ký1W~Ó¿å–ù¿ÓwèÝ;þYaÿ‘ký1W ;Ok#pDký1TF*ìUú7Nÿ–XäZÿLUߣtïùe‡þE¯ôÅ]ú7Nÿ–XäZÿLUߣtïùe‡þE¯ôÅUÑ4Š`ª(Ð1VñU,l¥rò[Æîz³"’i·R1U¿£tïùe‡þE¯ôÅ]ú7Nÿ–XäZÿLUߣtïùe‡þE¯ôÅU!··„ I;Š¿v*©Š©Ímm==h’^5ãÍCR½i\UOônÿ,°ÿȵþ˜«¿FéßòËü‹_銻ônÿ,°ÿȵþ˜ªè¬¬â~qAoÓ’¢©ûÀÅU±Wb®Å_ÿÖõN*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb©µço/hÞ`Ñt ùÙ5O04ɦ@‘»ó6áZBÌ ˆÀ7|U=Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUتEªyÛËÚgš4+ÝÎË­k‹3éÖë¸u·BòeP*‚~_Ýâ©güägæ/›tKKo/ù"F‹ÌR[\k:…Ê*9¶Ó,QšG!Ã/ï\p]¿a“ö×zo’¼Ã»ä­_gj÷s1 gˆ4€öø[8«Ç!ó¯æ˜ÿ/2<ý¥êÓYé´£ÉЬqÒ;M4†žärB_ë+¯Æ_ÓoWzÇ埘fóå×—u˹=K«Ý:Þ[ÉH þ˜5:ÞÅ^Gä?Î/6ëÿ° ‰Z?!y’=BÛÊÐ2 I[MãÊä7R²zRìÏþìãû8«Ð?<¼íªùcÉÉ€ÔóV¿u• ª€Íõ‹†¡p¤7÷iË~<}Fcëæ8èžÞVò†¡¬Ë¨èú¶‚ÜıÆ=MBÙdi¦ªª]açÄ«"üëóž³åÿ,A§ùoâów˜îSKÐJË)øæ½,|G›¹É¬rMýç¡ÀªÿÅŠ­ü¿×<ûå_Íéÿ-<Ñ­7™4ëÍ3ô®‹©ÎŠ·(ªå JA$×Ó˜LÿaxóeÅROùÊ]Ï^T×5Ôó”©åËÆµµÊ‹eÌÆŽ ß?Sâeyÿ»ÿбVmùuùeù“å»Í%õ_?˪hš}¸€ùôt'Š8ýu’GãâƒãôñW›ÜêÞsÔ?ç&üáiä¸aý*tûm7ô½Ðçoal±Ã-Ä̃ûÉ}`±Ãí?Ûødwòæç•|·©y¿KüÊÔ5KH‚Kû›+Èb[9¢}I•a£÷jÅW‹'ÃË–*õËß57š|‹¢yŽhÖ u+8î.#a$+IÔŸƒ˜n5ýœUç6þdüÄüÖÔ¯“5Uò¯¬&{U×Öž÷R–3Gke’‰º·Â$ ÏýŽ(•J|á¡þq~Vé­æý#Î^mÒ4ò²kZ.®™­êɵf^=O>ßï”x«=üÁüÙ³òçå)óí„?Y–¶Ói0IPïB˜}JPñ@üäZþÇU‹EùQù˪i‹ªê?™—¶^c™=e²²‰N…Èä°ðR¾ª/Ù2qÿbÿ¶«Ð¿-OŸÿ‹çÅ·_1§%íX0tàyÊGÛX¹GûKö¸"¬_ò?ÍžaóMÇõJñ®tÛo0]iú,EQDVöô`£ˆ j²ÇRØ«ÓuÌ/Íß0kï£ùšO)ù/A¾—K·z+_]Ü@y^V ÅĬœe¸påñ⬗È^YüâòלçÓõmy|Ïäy-½Hu î)} ÅH¨^O'OÔoOƒr‹«ÆÊ½CcÞ~óÆ‹ä+^y‹WcõkPp%=I¦sH⌮íÿ¼¾Å^o§yCó¿ÏãXóšæò]¥ÐXùwG‰DÐÆÛ¯ÖnŒž­)Í>/ùåýÞ*žy Ë¿œ~[ó\šfµ®Eæ%¼àÔ®À‹P†jü1ÑC¿Êi]÷L«Ì-5O;êßó‘ž~¶òZC£4v¶3k—J%ƒOµ¶Ž4Äîéä™A|<¹óøáU?óç’?6ü•å«ï9i?˜ú†©}¤'Öîôûø£ú¤Ñ% ¡c«$& Çü•dozGü¬Cÿ*üõaê~…ý+õ:ž>¯ÕýONµ¯Sáåü¸«ÿÑõN*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»x–½=¯–ÿç(´ÝV᎖½å«˜ngr†²f¹‘‰=a·ŒœUùI¡Ÿ7¯š?0õ¸˜ÿŒýK&  :\¡‰)û-qOROæâ’~Þ*óÍ Î:ÅüãÌ~F±~~n¹Õî¼™h ÊÏ1i\Ò¥V+i¸sÝü о€Ó<‘¥é¾@Évš|zsi¥ºŽIŸµ!fwÿ)±WϾNón«'üãÖƒä=&OKÍšþ¡wåÈ:†]¥¼¸Ÿ³ok7añ/%|U™þpy{NòF‘ùi«éiéYy7X´³v?hXÝ(Šá˜ÿ4žšs?´ïËL,óßçíÖ yåÿ˘ •§t“W»¿aQCèF=7±"Fت—çœcNüÄüªó58¬ÑÒç“jqÔ å_å !ÿ‚ÅQ^P_ñßæþ¯çGoW@ò‡©¡yoùñ€ý!t¿*ý]\|2Gþ¦*Äü¿ç8,¢üãÓäâFÔÆ©£ÚŸÚ}eÕâQ½P8‡—ò¯&þlUê’ÞJŸÊ—Ú}…í[Y¼å¨ëR¿Û{Ûª<¼ÎÕdb¯üWгœUã¿óWúV¥{ª~[ùÆûÊM)¹›L ·6 #,D QáËÖãöWáøqTwäÿŸ<÷yæ¿3y Ï?Vº×|¶ ”j¶KÂ9â¹PëÍUÅãeà‰ö¸²rOT«óÃ?ó‘¾Dó(ø-<Ém>{MÁSâòMÿžXª¦ˆ¿ò³?:®¼ÀçÖò‡¬t~ñÏ«µ óŽÍè…Õ‚Dý¬U¿ùÊŽ‹äÿ+ÿÔÁæKYWz¾%`wµ$x«ÚUT*€ª¢Š£`ì1WŒÙ«ÎXj3Tò÷–b¶ä;Kq2Ê íÞ;‰1WÎK§ÁäO,¯]kÌÖK ñ†>JõØì ¨Äÿ“нŸx¯üã¬I¨kŸ™^j§&ÔüÉqi‡¯£iVŒTšý›Š²ÿÏmPi¿“Þm¸&‚M:k]ünÀ¶û÷HÒóAÿœ^x-¹GwmåFv*$‘ìùÊGqijŸòqVùUùOçKïËŸ/^èŸ™š†›¦ÝYÇ4Z}½¬M'Å,j}O‹„ÆE-ö¹b©þ¯ùçÝKN¸ÓuOÍ]J{ Ô6÷òÚÅÆEP¡ýèûX«:“ò¿Ë—–vŸ—Ú°kÍ*ÞÊ &˜~îRöê¼gMÛÓ“šz |Kûb¯8Ô?+ÿ8|‡£Ïyä?ͨiº\-,z· L 0!oI'<øü#Š*$ þZ®*ô/Ë¿ÌFóGå]îí–Ñ嵸žê'€{G’9 דf…+ɸ6*Åÿç,%ƒòsO½š¾¶«uy{)"„“;EÊŸåyb«u¿ùÇùbó¡æ? ù²ÿÊŽ©!¸½¶„ ‹e$±chþÓo‰¤TäÞšqø1W~Uùßó?Ì=còÛÏrÚêzŽ›bºž·f‚!,ãN2 ¼Ï¬´ãqá'Ûø{*ñOùÈy o4þWZj Mo0Æ÷Ç˜Ä<ê@§Ç ßöyâ¯kÅ]мWþqš$¾‡Ï^j"³k¾e¼!û˜!!â&¼U§”*þÎ*Éç"5A¦þKùªrw–Õm@ñ7R¤ýùŠ®ÿ ùPá®Öÿ }S }o¨ñ­:×Ôø©Š¿ÿÒõN*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»ygçoäÅ׿=Ç—åµÔÆ”ÚSÜÅw(V2Iiz©ñ¡SÔÆŒ¿Ãñâ¯KÓ´û=7O¶ÓìbX,ìâH-¡_²‘Æ¡QGúª1W–ywò!tÏÎMOÏ—ëq§M-Åî—¥aè^Þ¢%Äí_€– ø~/îÿ“zÞ*òOËÈ…ò§æ½æË»ä½Šîâêm ÅU‚Ù­ô¥æ?§¨cXá䟱Ïf?š^Hxò­åYmä¿= ‡R˱H²£7§$ÞŸ³Š¨þT~_#yB-[Ÿ¯êsM-æ­¨šò¹º¹<„·Ä~ ñ|_*…üåüº½ó÷”cÒ4ûåÓu[Ø/ì¯\1Ë!Èp£âíÄâ©×<›aäß'éž[²ø£°„,³R†Y›âšSï$ŒÏÿ аO8þD/™?7tÏ:K~©£@¶ÒjšG­ÍÅ‘‘­Ùˆø(ƒ+¯ÙGþ|U—~iùgÍžeòuΑåmhè:¬ÒFEð.‡ÒV«Æ$‹÷‘ò´Ÿê}—ÅWßyõoË‘äíkUº¹š[¬¯5ˆœÅs$¨Šjƒûn¼™¿¨¿¾§&Å^w£ùþrW˺|z“æÍÿG¶Q –¡¨Á?×b…G7à>Ï«,¿ëqÅYÇååœ^L·Ônï5 5¯3k“ sZ™B4Ò-x" $G|›‚Wö¿—Š"¬þr¶½òŸ—´Ë |Õw­Û‡#„ÒS:†V`ÃtDõ³þËúX«Ò.<‘aäŸ&iž\³£}N!õ©Àþúåþ)¥5ßãž5û)ÅgJ¼õùuyæ;y+]qÃaåk›‹»‹VR^i$ú\HÙ}6‹¿ób¬ë`¾Pü»½Ñ1|åç Û¸®[Ì­h¶‘"°h!µŒÇÅËËô¾Ïòb¨?ÎOËMwÎ1è:——5(tß1ùjóëÚl—H^ݘñªÉ@äoðåãñb©×í?3`·½“Ï7ÚeÝÜ¥>¥•©ACsäò#—%{|Ïôèæ‰^ËÑú»@À1qáÀŽ„ÛxÖùKù·äInlÿ-<Ëa'–§•æ·Ñ5øåeµ2°ŠhVI ×ýEþegå#*™éŸ”žw×uë oó3Ì˪&•2]iº”kaÄg’K#|2ÎPýŽkËü¾“Mÿ6+õ_7¾“«hôú™4m6à’Ù‹Ž$I xò¥WÔ ß¼r$‰öUc7ÞAÿœ„óM‹è^jó^‘§h7 bÔ%Ñ`•¯.aaGŒ™’4‹Ô_´cÿtø1W j>G·‡òÚóÉ^])§ÀúdÚe„É„BXZ/Q©Ffø¹³}¦‹Cùoòî 7ò¶ÓÈ—WRpOúÍå›´sp}I"añ)æÅ–¿ìùb¯?п.ÿç"|¡`º–üÕ¢ê>_·„º¼­Õ¼#eD$ŠÜ?dI#/û‡fŸ––ùVëS×u½Qõÿ8k¥««È‚%á¢C k´q'·Ûø~àˆªµkä=/æõß›.|Ï#ùQ­Dž[Bâ5MTóB}-¤7¬?}ñzÝâ©·æ?åî‡çï+Í jüф֗QKop€„•+µG&VSö‘™qVgå?ùÉÝ.Ýt«O6èZ„kéÅ«jó õ@( DGŠG2É#7í»b¬ÇÈ@Õü­¥jfûÌ7z÷˜5w7š…Û ÏÂú0Ë (â>ÙEý”DUZüœü½—òÿÈV^[¸¹K˨$ž[‹˜”ª;K+2Ð6ûGÁqUŸœŸ—×þòiòå¥äv+5Ô]K*³†.È‘ñãLU›úqú~ŸéÓ É&[Ž—‚”P)¢; %ü?d ^’xIâ%ˆ—d ^’xI⥶¥ÑÓ½ãCTÝf®¢kÄqÿì>ý­¥0¦‡@À±.üXû»‡´‰AŸÞ±=ºD8® • ç·Å˜ËSêüðvCÕ(%”?ÜËÿv)Œ0 ŠÃÚr@›¸–ÍT—0T‘~G˜íBaÄí<„B( !àº2ü–Q•€ `¨Z[iÛ: Às©"#ÂoÉ À ¶m;ŽÓ–CÚ4¡Œ1B(Dø¹ÀFÀUUMh“Ïs*^’xIâ%ˆ—d ^’xIâ%ˆ—d ^’xIâ%ˆ—d ^’xIâ%ˆ—d ^’xIâ%ˆ—d ^’xIâ%ˆ—d ^’xIâ%ˆ—d ^’xIâ%ˆ—d ^’xIâ%ˆ—d ^’xIâ%ˆ—d ^’xIâ%ˆ—d ^’xIâ%ˆ—d ^’xIâ%ˆ—d ^’xIâ%ˆ—d ^’xIâ%ˆ—d ^’xIâ%ˆ—d ^’xIâ%ˆ—d ^’xIâÕŽã´åiŒ1|u]߀mÛ¸bÇÄǯÎ?¢ ¸oØžÿ„ïÇá-ƒÏÙ‰j7Çq(¥Š¢`·8>އŸo‡RUà¯xà£ëºØÉà9ÅÇGîBcØÆ²,×u)¥Ðú`Ê@ `Y!„Rl7ئsÕnŠ¢0ÆLÓ좢(¶my(ŠB‚lzÊŸÿÀG¼:´ZRçÛ¶#""’’’úôé£ë:PJ-ËâãéÜü_"„ {–––ææfJill,¥”¯HJ)wPŽãà ÐuÝëõ¶´´PJ{÷îmšæÍ›7ãããÑtâ@ÚÍ@Q”æææˆˆˆ»wïnݺu÷îÝÕÕÕÜÌy›ÐÐÐaÆåääLž<9<<\Ó4à>ƒJgá7ºŠ«RªªªëºW®\;v,¥tÕªUsæÌA@@×uœSnï¶m뺞——wàÀQ£F}ùå—ß|óÍܹs?þøãI“&¯›?®Ž¬ƒˆˆ¯×»xñâ;v@«3E‹Ãå¯(ʯ¿þúõ×_—––644,X° ** Zý!ä/ˆÜTy^@ñz½PPPðòË/GGGcÿ¹Qó•ªëzyyyaa!!äöíÛ”R¿ßãÆ 4¦Nˆ8¤}ûö!°,kÆŒÅÅŇ:|øðêÕ«SRRø¨Þ}÷ÝS§Naèã]ÿ <®K ]ПFFÆñãÇ> (Zà+Û¶ÿñÄÅÅõïßO†C°m»s£ZG|c¬¤¤DQô§¯¾úê_|¿Z–5bĈìììÌÌ̆†¶}ûö°°0˲lÛVUuРAQQQ<}¢”ÖÕÕ]ºtÉ0 ÆXRRR ¨­­UUUQ”¬¬,Ó4/\¸PYYùóÏ?wéÒ¥OŸ>Œ÷ûý¯ë8ÎÍ›7:tïÞ½ëׯ;Ž–œœÜ·oߌŒ ]×¹ës]wæÌ™¶m/_¾|̘1š¦á@xÂöqôèÑâââÏ>ûl×®]~¿ßu]L@0’wnXîÈšr]÷—_~]×Ç1MÓçó…„„¸®‹Kµoß¾………MMM˜bGGGïß¿ݺuxø¶mÛæÍ›­YŠßïŸ7o^yy9†îªªª¯¾újõêÕ]TTôÑG•””ð@¢(JŸ>}Ö®]›Pïܹ³fÍšuëÖiš†É Zë3Ï<³uëÖ””tâ”Ò¸¸¸üüü1cÆìÛ·oöìÙØm<ÆØ† G޹sçÎà|ïÏXÁa@)MII)++3MSUÕÝ»wß¹sçÙgŸMHHxì±Çúõë×½{÷¬¬,´SÌG{öì‰ EY¿~ýÔ©SCCCÑ \¼xñøñãÕ§M›6`À€àÎÈëõΚ5«®®ZÎìõë×óòò’’’žxâ ŸÏ7þüýû÷€iš”Ò°°0EQ¼^/æ6§OŸž4iÒ®]»† bš¦ã8>Ÿo̘1ÉÉÉ7nÌÎÎ6 CQtY¸Ž=ZZZúÉ'ŸÄÆÆZ–å8ßåà t.‰Žì“`öìÙ½{÷Û¶ !eee«V­ÊÍÍ:thrrrZZÚôéÓóóó8à÷û)¥IIIo¾ù&²¦¦¦¼¼}¥tçÎÜ_{í5àöèóùêêê²²²¶lÙ²wïÞüüüÈÈHÜ666–––Ú¶½bÅ @)Y\\¼téÒS§Nùý~œPÛ¶Eijjjnn¾xñ"躞‘‘±~ýúΚ5kË–- Fíºî­[·öìÙ¶m=:==4Mã9åÈ‘#qš4M³,«gÏž¹¹¹8 ÍÍÍÛ¶mÃŽuíÚuóæÍƒÆXïÞ½SSS¯_¿~äÈ˲***®^½Š¶Œ»–qãÆ=ÿüók×®2eJHHˆeYš¦©ªZ^^~îܹ‚‚‚ˆˆɹáót'.…ŽÔ*¥4--íàÁƒG-,,\¶lYNNNRRRxx8oi†išeee¹¹¹MMM©©©Ó¦MÃÅ^RRRUU¥ªê¾}ûÑM¿ÿþûh§ý Ãp'//àÖé…^À6À»qãÆ½{÷°®0lØ0„ôK555W¯^­®®ŽÇ¹Ãꪪ‹/®®®Þ³gªªÉ|ø•W^ñù|+W®0`ÀôéÓùx9ƒà¼Hp­ë0~ø¡ã8º®›¦yðàÁ§Ÿ~:66‹w8<¯×Ë(ŠÒ­[7LnnîÎ;ïß¿_WW—››‹ç2dÈøñãyUU×u´èà +/bî–eõë×/..®¡¡ÁuÝ'N”——gff¬Ê½þúëçϟdzýðÃÈØ², 0a„ôôô+VŒ;öرc§OŸ.**òx<Áµ¦à”‰GˆG0`^gÛ6híßrµûE‰ŠŠZ¸p!˜¦©iÚ¥K—^zé¥;vTVVÖÖÖ^¹reíÚµ|ð¶gŒõêÕ+##ç.%%eâĉ®ëâ½Øœ9s µìŠ•p¹ÏçÃ=ÿk8)Œ±°°°œœƘÇãiiiY°`Á¦M›|>_KKË·ß~;yòd (ÊÌ™3cccÑkáÕ±{¡¡¡ .¼|ùòš5kÖ¯_Ÿžž>jÔ(x¸ômš&‰ Ã@x¥MÓÄóàÂå{òöªƒûƒ·ß~»¢¢âرcX„¨¨¨˜={vxx8º¿ßÏ`¬W¯^ØWMÓæÌ™STTäóù°²Ý¯_¿)S¦`Ä£‚Ý:‚Â#„`ÖûÞ{ïUTT OûþûïóòòòóóCBBêëëMÓÄyŒ‰‰yë­·pGé8ŽÇãAçÆ7%›6mZ¹r%!¤°°044”/œ\<ægÏž5 í »­µÛ¶GŒí÷QaÀ‹ß¾}ûÖ­[?ÿüó;wî躎[*Ã0Ð_£ýfff.Z´ÓPì( >|äÈ‘EEEØû¹sçvïÞZ—3´ºÓ4£¢¢0—çLÓìÖ­[cc#îª!QQQ7nܶm[ss3–Ø8BÃ0FŒ±téÒAƒáù5MÃ;&c¸I^¸pá™3g233srr‚»Šö…YV8ÐCë†Ð'ÇÄÄ|÷ÝwQ=£Û;ŸdËñÒßm4婌]º AvjšfSSSUUUmm-zÛ¶ ÈŒŒìÞ½{ÿþýSSSqHÁÅêŸ~úiâĉgΜÑu=::úôéÓqqq8)ØàÚµkwïÞUÅçó 4(44Zc£ëº'OžìÒ¥ DFF&$$`$gŒ]½zµ²²²¾¾¾¥¥7111‰‰‰Äí:!¤¹¹¹ªª*999** ïÕ`ÑÔ4ÍÊÊÊ®]»&&&â÷˜V)ŠR[[{ÿþýÔÔT¯×[]]m&c¸:yµ&44Ôçó 2„©Tc€?ýÚ\üÝÉÎgÇ"ì(ÚŸDì%Ÿz|­¯¯¯¯¯wg×®]6lÀ–o¼ñ¾.Àñûì<üâªç>š»#Jip¢òŸ·¯¡õ7Z6ý=¿oÛa‘Û ¯ñ‹ò°Œ=q]ã?¿:!ÄÖ^É‹ÐôpÖøX¼I“BhM!0M€'NL:5xŽbbbæÏŸGy<¼)ýÈÝ0§‹¤¹wbŒÜ â¬Ùw†{mžÅ—}¸çá=7)~,æ'ÐTUE»áç±,ë¯È‹c<æÜ-òB<´¥Wkp\Ål5!!aåÊ•)))¸ñ† ¿,ð” Å<÷€VÒtïƒaXRÆz^‚ß´À3óEƒã}æ·0Gðx-ûßÎü‘ y(@Æ\ŠÒ¶©M \Æ\` aí.ÛRò¯îcýëŸÈ¿ºªs†öÈ _!FhÛî¶µiÀ.Ä!ÄQÚü²‡ÿg÷¯º.àá?jüÝ ´¯º×¦uÐÔÒlY–J…æ´ïV*O-8 œk^²ç  úKáßWÁ»¿æûÞ¶Ò&ÇþYõÇ:&õ[úoXûwIâ%ˆ—d ^’xIâ%ˆ—d ^’xIâ%ˆ×ÿ3 ïÉH8öIEND®B`‚–ÜDdÆ*‰+rq𢲠ð c ð~AÁZ¿ÿ..\Sync Server Manual\sysync_diagram_big.jpgð€Rð ÛTª(†D»NCTœZÌ2ÿ|Ûé§ FðtÛTª(†D»NCTœZÌ2ÿÿØÿàJFIFddÿìDuckyGÿîAdobedÀÿÛ„   ÿÀçÚÿÄ¢  s!1AQa"q2‘¡±B#ÁRÑá3bð$r‚ñ%C4S’¢²csÂ5D'“£³6TdtÃÒâ&ƒ „”EF¤´VÓU(òãóÄÔäôeu…•¥µÅÕåõfv†–¦¶ÆÖæö7GWgw‡—§·Ç×ç÷8HXhxˆ˜¨¸ÈØèø)9IYiy‰™©¹ÉÙéù*:JZjzŠšªºÊÚêúm!1AQa"q‘2¡±ðÁÑá#BRbrñ3$4C‚’S%¢c²ÂsÒ5âDƒT“ &6E'dtU7ò£³Ã()Óã󄔤´ÄÔäôeu…•¥µÅÕåõFVfv†–¦¶ÆÖæöGWgw‡—§·Ç×ç÷8HXhxˆ˜¨¸ÈØèø9IYiy‰™©¹ÉÙéù*:JZjzŠšªºÊÚêúÿÚ ?÷ö*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š¥ú–»¢hñúº¾¥k§Å¿Çwq ·]ä`2“¨Æ šh°½Oóçò_H¨½óÞ‹É~ÒA ËÀ¡HÛ¿†?˜ŸÈþ¤ð–'ÿ9{ÿ8ûaÉÅŸYnÛOÔ%®ôÙ½Ÿ{câž‘?gé!xXåßüçä}¹"ÕîèH<( ~×ï¥Mßí‰/柳õ¯ Mqÿ9õùMqo¡y†gRBo`ˆÔ;ýlú¸ñO¸|ÿbð üüòï·•õ£ó6cþga”§ÐŸüuxP­ÿ?òw6 äíLÆ àÆêØ;7§ß’‰—QøùáFùÏÿËz ùc\¯z /ú¯“^TóŸ”­nt1G-OöŸ"Ó·Ä׈ QœÛÿÎr~GÎXJu‹jR†]=O*øzR¿ãŠð²ùËÿùÇËÒù°ÛHIn4ÝI­y‹r€|Û¦Y¦þ~JjÔž}Ñ‚ÜßÃhIÛ`.Lg¾+LÓKó®/-U³Ô–•ågs À§bfÅ –*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUŽù“ϾIòt~§š¼Å§hâ• {y ß꣰fúTsDm{ùn~A4^1æùÍoÈýœzuí÷˜n£†™f꜇üYv`R=Ö¹G”OÇoÛö'…å÷¿óœÞoóïeùkùq-ìÀÑy./ä$ýšÛÙD¤ùèr¬¹ŒÎQ€óýd¹Š\þ|ÿœáó¿Å§éÑùfÒJòãkceÀmE¥œ}¹©ÏÛš8}YL½ß® }íƒîB·äGü䯚èÞrüÎ’œ­ÓSÔ.x×­aAU§ƒf¯7µ:AËŸ¾¿I%˜ÂQó„z37«¯ùÊöúfÝÚÚÒ;rMûSI9=¿Ï¦ý³ŸðcÞoõ2ð<ÙnŸÿ8wù?eO¬þ•Ôi×ëWªµÜþ­9ƒ“Úí\¹ppýd²bÉìç$l(bòœ2°¥Zâêö⦔©ÌÃð¦aÏÚ=l¿Ê|„GèeáG¹>´ü—ü¥³Cä¨8þûO·Ÿj×ýÜ­¿¿\Æ—ljåÏ,¾d}ÉàÉ´—¾A¶áõo*èðúTôý=2Ñ8S§1ŠS(–¿9ç’_éŠxGr3ü'å_ú±éÿô…üÑ•þk/óÌ­ËŸ’Ö6Mÿ9Qù“jÖÑX­µq5ôÐ.©h¥™ÙöÄåü—„Þ÷÷2h€õ—Ôá?*ÿÕOÿ¤(?æŒã?5—ùÇæ[è!¦ò‘®\Éqå&Yfi4ëV$R›“ÉvqÊrÿLW„%7?“Ÿ”÷@,¾IÑ éi–°úÔÄ‹—ǵõCü¬ÿÓpäŠóþq¿òJûûÿ(Û§Oî./-úÆ “2aí¶<²?xG…æ3¨Î ~N^‚- Ôtê­ñjmJ¬¤ß=ó3µºÈó1>ñú©‰Ã%¨ÿÎùa›ž…æÍFÅÔò‰®­àº*A$Äm÷t§ôÎÅí¦QõcÜHýlNÞ…OùÇ¿ùÈO*Êù§1‚=’ÞKýJÅTl=3Æ}Û68½³Â~¸H{¨þ¦NQ1ù£þs—ÉKYÒ/3XB¢Ó¯ §ü`0Ý1ù×6˜}¥ÑÏøèù‚?c„÷# ÿœÙüÈò¬‹æwå“ÚµB¼°Í.‡Åc¼ŽpÕì=AóͶV,¿D„½Ä³‘åŸùÎÉMo„zÄš——'4 oìÌÐò>dÓš{².d1§´y_ó3ò÷ÎG•<ϦjÒ°¯Õío!{ß⇗¨¿JâŠeX«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«D…˜ÑFä€i^SçùÉ?É ´kh·»Ô£¨:v—]Bà0ß‹}_’!ÿŒŽ¹_Š:oøï䞀ëóœ~cóãé”BŸP¼'÷S߬·r•&€›;Ÿò<Œ§6ns”`?M}ÅŠC6‰ÿ9“ù¬9y‹ÌÊZ<Ûý].NýÙê¾–œsþ¬Ì>ìçõ^Ñèñõ9ÙöÔ~MÑÂ}ÉŽÿ8[åÅ—ë¾uó5þ³xçœËh©jŒÝü¾¼óªœÒgöÇ',P{þ¦Á€uzÏ—¿ ¿'ü³Å´ÿ)ÙM2ÐúÚ‚¶ ü‡í­´€õ@Í£·uyyä?OÝMƒGG¢[Û[ÚB–ö¤ñŠ$Q"¢(ð  š©HÈÙ6Yª`Wb®Å]Š»v*ìUØ«äÏÉ_ýjÿÌÏù‡Ö?î«i¿lÿÆ^|ÜÉ¢Y}gœC{ãÿÎmR÷Sÿœ„_-OçëŸ#h0ip<ÚŒÒÛÅÂ'•j‹4KÍË*õ”Îï±ñè8Æ!–FGj¿Ð\yŸW:ezE­ß•?-üé­Ï6ó&žÖ¶[ëàËzÚ5ijñ–+›É+/¨©·Æ½@Û0²ÈfÔbåx ŸO.!^è«ÜÈlïVò¯š4Ÿ+þXhçœ|Û í¬¶pH|Ç|Ì^úêe•' !b‡áy°"¹¤Õi§—S8bÆA¿¤o_-¿C`47,‹ËÞuòŸ›4ùµ_-kº¥…µE̶²¬ž‰ Ê’(ø”Óz˜º\2œLIïH/6ÿœlóÿ›¿2|¡ªùÍw 9MRk=?„ÂVáŠMÄj ï%+í›h´´¹£ b½6}öS R$nÈ7ÿ5àü§Ò´Eô¶Ö'Õ¯ÓOŠÊ+…·‰ÜÈ¥‘ÃQ•ŽßjµÚ‡²{,ë%(ñpˆ‹º´Î|/EÍS6ThäPñ°£#A±iX˜$¿)üÑÌêþRÓÚWÝ絇êS1ñ2ÚœŸ™ÍžŸ¶uX¾œ’øï÷ÛŒ%óüáw‘¯Y®<«­jÕyF’ð½n8ƒéJ>™No4þØçŽÙ"$>Gô±¬àX<‡ÿ9uù[Y<‘çó™ø,d»[ŠF:¨¶ÕDÛ´O_ ó Ó{[¥É´®ÌXû?ST°ßLÿœÓüÆò]Äzoçåô¹×"8Wо\òŸ–|¡d4ï,i6ºU˜”v¬eÈèd`99ÿ)‰9Êj5Y3K‹$Œ›prN2„»v*ìUØ«±Wb®Å]Š»v*–j¾dòö‡u§Øë:­¥…î«(·Òí®n#Šk¹‹¤| G!œò‘ 9»Ÿ&@LbHŽæ‡/r 3ÊRìUØ«äoÉÛ»[OùÊïÌ–»ž8Hu„ŒÊêŸô«qˆ©¢“OÏkÀ˲ðP½ãþæN<>²ú»ô¶•ÿ-Öÿò:?ëœO….âäZ,EFàô9v*£ygg¨[IgoÕ¤£Œ¶óƲÆãÁ‘Á|òP™‰°hª^þVòÛèÓùté‹ Ü‚·lvñÇm b ¦´Û-¬œb|Gˆu½ÑAŽy«òƒÈ>oò§’õ=-bÑ4ê-mÃ%›EaqZlMCq™z^Öχ)Ëz¥ÎúûÐ`¦%åOùÆŸ#ù3Îz74kÝBKÍ9“н™.VáåŠX}WbŠC*Éð…¢ü#jÔœíW´y³á–)Ô»¶®_©ˆÄ·¤ùÛËŸâÿ(k¾WýYµ{›$¸§!ÍEr;€H$f£E¨ðsC%_ œ…Šx¿ä¥ÿæÇ‘?BþSùŸÈŽ4;º‹üUep²[ä–”5v¥y†¡û΃¶a¥Ôqj1åõô¿wãïkÇcjy_”?5tËï6þtë>my¬¼ÿ¨Ïs…dmæ—îYb"•URaøœÁAÍÖ¯²ç©Å¦Ž:8â±åû~-q|ÑÞ^˜?—_ó‹š~»ä¥Y×u9u^ò–{›k‘Õª Á,â¬NÛ°¯Qù}Oi˜fúa2ü‘b3ï!ù÷óËŸ2ù¿Kó&›ù‘¤éQG6˜×1þŠÔ¡ôxIz—êÄ"áæÉWvb TšÍv‡NuÇ(K —:õGú<=ök¹”djù¡?çÿ5üËæýCZ²ósê·SêÒϪhÓMnL¶´ŠB&Ž+“FÚI¡Uâ¦ã'í'eãÜ|#†£-ýDô±îÝqLžo¡´ï1yWž[m'V³¿¹‚¾¼6·PÎñÐÐóXØ‘¿Žr¹4ù .Q ðÜL²¥@ë&æ 'ÓuÝ>ßSÓäûv·¤ñãÆ@E}òÌ9§Ž\P&'Ëe"ß?ùßþpûÉZ¼‡Rò5ôþVÕú‘D¥îlýE< ì%Œ×ö–J/eΧCív|{ecäWÙñi–y1‹OÌOùÊùDz#óU±ó¿’mÍ ÔÏ%ê¤KZ•½Qõˆ¶éõ…*:–ƒ·tÚ£*—óNÇöüyâ!ïß–ó–ߔߘޅÕéò¿˜¥!›«²ÇŽ{Ct?tÛì”rz.nˆ{À €A¨=(v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUãÿšÿó’¿–”¾­Ž«~u_3 4Ðt³\+v½DpïÔ;r¦áN)ó ÷Ÿÿç&ç%eh<±y3òþf*g‚I-!’"hD—”õî *aP‡ö—¾j;G¶ôú]¦n_ÍŸÙñm†"^‰ùwÿ8£ùyäÿFÿÌH|Õ®¡d½@¶HÿäZ‚U‡üe/ãAœ/h{S¨Íb»—?Ÿê§&8@{´PÅoAk1€±ÆŠU@  €ÍI²Ú¿»v*ìUØ«±Wb®Å]а¿$~gùÏÚ¿™ô] ¸®¼«x,5º„G’‘9DUš£”Oö¸ž†›æÃ[Ù¹4ð„¤Ed+ôüØÆ`²ë‹ËKCºž8 αB%uNr9 ª¼ˆ©$€ÌÀžA’AæïÌ%ù gó~µm¥-Á"Ý&bÒËJR(Ã;QRƒ¾dé4µŒq2¤J@sBÏù£äX¼‘uù‰± ß•-´·¶ÕóäEÃf32¨FÔŠÓ'ÌÎs &$Lô?¹b­òwç?ç^•çÙ|‡ækVÑÓCÕÅåî¥n±ÛÝ[—ŠFheBÀ•hWïíÛö?cKN2ã3Œ¸ãD¸;ó‰Îé÷yÓ’ìUØ«óþëòòÇó/þróB¿¼–Æ+{Jõ&Q˜¼w±EćڄHs¼í>ÞŸfvf °ˆ‘<1£çÐÝÙºêsJÕ ûGëeÿô)ž]ÿ©Š÷þDCœüGúŒ~eÞÿ¡|Ï(aÿ8IaçíçzŸPñ=GÁp‡ñˇü¤~­8#úÿñÂÖ}—2}ŸµzÿÎ=þbé¿ñÅüƹ‹U(×–¿jî§zn:e£þúIÿy¦ûb~ø†©{31Ë ù+¯‘ç'ôz¾›ù„×ÀV‹6©y3ŸÚéw/QAñeÑöϱr}x%ócþö_¡¦^ÎêG)DüOêD'šç14 åôu«téÊ-.ZÒ§¤^”¦´ï™í?g³ÿ<~°ãO²5qþø„Ló“ž^_ßÍ¿—‰, ^SCifßÕcjsû9¬Çüî£ûY ±/KÒµÍ]·úÞ‰©ZêV¿ïû+ˆ®#ÿ‚‰˜fŸ.ã58˜Ÿ1M€Úž©åÝ\Šxu.ÓPŠæ?Bán­â›Ô‹~ ÍM@` ­ökS†dF<` ±ú»ü·Lr‚ô>~aykòãËÃÌÞešDÒÚhm£kxÌÎòMR¼Bö⥫^ƒ5zMNOz½ÙÊ@Egwo¨ÙÁ}jÞ¥¥ÜI4/B9G*†SC¾à÷ÌYÄÄy„¼óþq£òÓÏÞµìV_áýz@Oé1V5wñšßhŸ´@V?Í›ÞÏöS§¡|qî—è<ÿG“\±ò fÿœ›ÿœeSI¹>pü½·ûVÌ%½µŠñ„Ÿ^Öƒ¼méƒÔ¶w]íŸSBø%ÜAä~ÿ'xH} ùMÿ9qùcù—õm3QŸü-橸§èÝE×êóJ{[ÝÑQªv áöS›æ’ýŠŠ»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Vù•ù»äÊ}0j>sÕRÖI6šlT–úê›~æ<ˆ®ÅÍwaŠÓä-wóËóçþr.ö/þRiÒù[ÉÜŒWZ¢Êb”¡ÿ–‹ð> ý+qϵXf»_Ú¸4¢òK~î§àÛ d³Ë/ùÅ?#y5¢Õ|ÓO5yO>WIKœïð[’y‘üÒ–ñ §8Òö§>{Ž?ÝÇËêùþ§*8@æ÷ÄD8Ô*( ª¢€° æ ¶ÖñWb®Å]Š»v*ìUتԒ9 Ü1CÅøx°¡§C¾$R¼3Ìÿó•Ÿ—z*Κ¶¡æ+»9fŽþKY ©Uyfk•B«É¸©ã¹´Ú½&›Ù}DëŒÆò³w}ÔÔs#¬ÎOùÖÔiÞ{°òz/äÍåêØ Né¿Ü”®•X§+G Ê6V+Nu9‡Ù¬'‹ Éûð.‡ÓåÓ~~ NSζMÿÄ:ýÿçÿš-µræ*y§Ëï7—ä³e·’ÚI­¢¬A$j§šñœ«5zÛe—Ç<ñ€ãÇ?Uï{Ø›õñÊ—:çæâßXùª[_"ùFh¦Ô|ׯ갛RöÞOQb´g©^k±U'Z¿ è3jµô”qÞLƒhB&¢?ÇŬO=™'çÖ§¢þ}GæûíZ×Kò¶½¦[Gåß3_é_¦l­áFαEÅÇ3 sÈ –Z칉Ù1Œô>‰”á#Å.wëðû“?ª×ù/òµ|ïù;çý+ÈúÍæ®úŽ¡mwa%æ–º.Ÿuue+HæÍG^¡ B#*T(è5§àjðË,DxbA©qÈüíº|o~iŒ.&•<Ùoùçù§ùi§~\ËwÒŸËëbn5 ©ã€^=¢‹HÖÒ9–$CF.äHʰ#K-“S,þ7ìÕï½_ܧŠB©õÖ†/F‹¦J?GQ¶âòÊÅ'ô—Ô^HYM¢¡ˆ÷Î7¸yY§ #²µv*øÃòûÿZó#ý][þêVÙ¾ö×þ1tÿÖ‡û‰»Og?ÆeýS÷Åô.xëÛ»v*ìUØ«±T·Sòö­¯ gK´Ôö»¶Š~Ôÿv)̽6¿>îòJÕ‘sNLŸÕ}á‚ë•zÀvý õ Þ¿¾±žX8×Â>F?øLèôžÝvžò¼cº@·êû]v^ÃÓOøkÝø¦}ÿ8´–7_ò_šîôÛ¸êa7 Wµ'¶h™~„9Óé¿à"8u#!ý_ìeÅ÷ºÌÞÌGø&G¿öSp7üå‡å埫ŠtèúÅ,©¨ÕGM®Â\}Ù¶ÅÛÝ…¬úÃ/1Ãþæãóuy»Uâ_·tóIÿœÅÖô;„Ó¿3¼“=Èþòk/RÞM¶%mozÿÈìÍ>ËáÏ=6a1ð?ì£útå8œH/eò—üä7圌pØyŠ÷§ú¨ Œ•=4Ô²;f“Wؼ˜;ã¿Ý¿Ø‘¦:AwG"¤öÓ¡WFã’7 ƒPA4à|Ù±Mò¯òãËš¿éíË}†® º‚Ý£/³zc¢T|m™¹»SQ–œŒ{­ˆ€5·ü©ó7å—•2uï,ÜIæŸÌO6<²ÚܤqÚMÎMJ‰%#”m,’ìßk¶måÚ˜õYpà ðñcçחíóaÀ@5Íãzò5—‘¿%<•ùr4x%üÏó¶¡ ÄÍ$(o vuýØzR¦H`ãZ}¿|è4:Ùj5™sq øÆçä×(Ô@ê^—«­ë?œXü–òýÚ]y/ÈÚM´^mÑ]AxÖÐÄ8ȳ¤ƒ•D(¬%fz³PqBIê¦*ydx(ÕY=ß~ÌïÕ]ÌŠOùÈsäï0?—7¼³uå$žY¿Ejñ}a=²¹³4ˆ`¥yðçCÔ/Aˆ=Ÿñññé¦2wŽDìø§Ä£»Ûí® ¼·†îÙÄ–Ó¢K ƒ£#€ÊE|AÎvQ1$aµS¼oó;þq¯ò÷óM¿ø̯R5M>5T•Ï{‹}’Ov\ÿ6oû7Ú=FšÕ[›«‰(bEYÝÜ€ ¤œUòæ—üæ-þ¯©Ÿ"ÿÎ?éÒkZíþmÚU ZglÃ㯭0?•‡Å•fÏ Q2™¥”clgÉŸóŠz™.§óo玵sªùƒPVw°Šé¤twZqtjY’»GÀ(>&]³‡í/kÍðéÆßÎ? ~¿“• éOä˜5OÉÏÍ-cò;ͲŸÑ÷÷´{†$FnÙA…Ò»¹‹É¯Rr]»‚:Ý,uxùê÷uÿJ~ÅÆxMØÁ¹Å]Š»v*ìUØ«ó§æW‘¿/ †9kPibâ¿W…„“O(H W¨îÁh37GÙÙõ$ŒQ2¯—Ìì‰HoÿœüËón}ä¯5ù%5DòÕš[ëjO¨%ã«Û[ÜÇð7:FÜ£ ýŽtþÎön)Ç.<¼ªŸ—¦VKÏ,]Ïlîn #‚<Å}:Ñ—ï¾:>Ɇ9 <¼,†ý]2 î=kšÊw¾áè¾iÿœ”¸ògåÇ–õ½[BüÛæM/ìœ@ÃJlUUdºµ “7¦„°Z ŽA³S¥ötgÔN1˜à„¨ÿ:¿[3–ƒ?—óFп+ôŸÌŸ8Æ,íõ­L–ºlƒP =Îâ4‘8© µOÃB*O]`ì™äÔË-Ⱦ~ƒ.:YÝ­ÆŸ®ép]ÂëKÔ I£'Ã, eä’Œ§pÃ5’Œ±Èƒ±‰ûC>ož¿2ÿçtRèùŸò²ïü-æˆ_׎Ö7’+'™O д»×¡J¯J*õγ²ý«ÉŠ£›×ÿâ¯ïóižy!/ÿç+¼õùc«Gä?ùÈ*ä¬TH|‘v±•åXþ ˜ÿâØ.µæÙßéuxóÇ„ƒ‰(û'ËþbмפÛkÞ[Ô Õ4{µåoyk ’6ÅGB̧pv9’Á3Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb¯4üÝüóò'äÖ™õŸ2ÝúúÌè_OЭJ½íÏP‰ $u2=Zr;b!HŸÿó—:Šßk³Ÿ*þUÅ';{XËg ÛzHxµÔ¢›Êä"šñãöN‡µ»pýSþhý=ß{v“UfÇ—Vz•³Ë _;~wþRùËÊþw¼úÞ‘q2ÛùSÌRÙ­±ŸÑc"J°ªFLHñÆA¥~&Jü;kûJXt¼y1 zãw_÷ç÷³…ÈY‡å§å7žì¼»såÍýgNó?”Ê;NÐá…¤H£ùG!¸xà“’¨ »(¤0¦ø£Ú¸%dÓFPÙ—¿ÊÈüre¢Ë|—ù%ùcù}¨6¯å};mT†T¼šY_b"k‡~mU¡#bNak;gS©IØîØ}Ì£ŒLÿ5lŠ»v*ìUØ«±Wb®Å]о0ü¾ÿÖŸüÈÿWVÿº•¶o½µÿŒ]?õ¡þânÓÙÏñ™Týñ} ž:öîÅ]Š»v*ìUl’G m,α³»ªª7$“°(ÄÈÐÜ šæ–iþhòÖ­pmt½fÆúékÊ k¸&Pj±±=eçìÝFñdÇ8ŽóÚa©Ç3Q'È„×0›ÝŠ»v*ìU ©é:^µhö½”öR}»{˜’hÏûW/Ój²`—9HuØ×“f*@æñ6Î1ùKSs}å;¹¼½¨©çjZâטܬÂD5î¯AÙs¿ì¯ø#ê°úucþ–_¨ü¾.‡Uìæ)ïŒð˜Ilü÷ÿ9ù#Æ=v/ñ” ØÍ3=â¤b•+t \EA°õ”¨ì3®Óê{#µ¿»—…ÿ ôŸ—Ó/óM¼î§³µ¨Xïþ>/lü»ÿœ ü´óߥe{uþ×\ Ùjn©¿qÖÑ··> {.`v‡³Z>àqǾ?¤sûÜHåì—6Öº…¤Ö—Q¥Å•ÔoÑ8 ±H¥YXt!¡ÍdbAØðo2Î+ù{PƒNÒ¼¿®êzg•aÔ÷PòÔ×—:|—D·¤'#•$!ÎùÒéý§Ée8FSá¡*_ÿvÍGaÿ˜ÐXùþrcÊþNóô gä.ÞòÍÞÓR¸’4nUYB™©íN14å\ÏìùKfäË„ÞIQ½â?³‹o %Þ]¿Ó¯5oüŸäÆ·Ñ¿"¼ƒ äÞiŽeIôûÛ‡Ë1˜Ý RU Õ"bŒê1Ê:Q“-ËQ˜Ž’¥W—?3ºƒ½Aë^Xÿœˆü¢óVºžZÑõÕ]BWY ›y­a¹sEU…æEZ±4Uj;sE©öW†r†Ýhƒ^öÁ’%êy¦fǼåäo*ùÿI}ÍšlZ‘©Œ¸+,.nVŽî§~‡lÊÑëréçÅŽTÑ(ƒÍòî¥äÎ/ùÆZ8~Sê3kžHf2êZ\Èf¤Kÿ-–É@à/ü|Cņõà:ú/d{MQPÉèŸØ}ߨý®.L4úoòGþrWÈÿœ¶ñéñ8Ñ|ê‰Êç@¹“ˆ%žÒRL  uî´Üõ9iÅÅ]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUòŸçüåÌûùòr%ó窾¥ }jÖÖføx[¢róE=yn¹ 䌔ÈFØWåüã-7æç•Ëëžf½¬¶q/Ö9¥òJ‘!Kð(Ûâà{cÚ£+†Ÿaüî¿ï?s—{é袊’Qc†5 hªªŠP6ƒ8’I6[×b®ÅVÉsFñJ‚H¤]VV ƒ±b nñ…³Mÿ8Áùôö²–òÓÍ”âÌO¥´²|-]Ç+I‰ïéþÐÏA«¡¿ò¸þÿøðû}Î7Ñ/'Ú Êêd` °5„óç%¼UØ«å:jÏù%ÿ9/'æ'˜mä“Éžo²[GÔ6”ÛÈ*K#Û£•]ý6økÓ;m/ÏvoƒëÆn»ùý÷óh‘ᕳo6ÎOyr-CEп,-‡ž<ê\$oeng·D…ÔÓ÷Ïù_„…PÅ©šý/³Y e<çÂŒG=ÙŽŒŽQÓt£[ÿœpótžp×õ'ù¼yoÊr!üͦÀŽóVBÍÐâ`2cãž?¤ý×ø¡¿_.'GÛÆqÃÇbbzŸÛIGœ7uã¦ùFò!Šo8ù¦ ;Éв¤1K]H4äüªß²³;²}•Áâj²êìaÀeë ô÷ Û©hÕö¬øqG×0ãñÑ‹þe]y‹ó'ó;KüŸR0éÖ1Âu›˜‡î'âêyŒ`ÐñZ,q’@nù¹öwŸ³;6}¢ar‘<ó‹†1¿3¼Pâv„²ju1Óql>¯3VOê —Vÿœ\ò©³·>XÕ/t½fÝãe¾šA8`¬91Dàn¥wÍF—þ Z®3ãÂ3Ò}»íß`¹Y}›ÅC‚F2y½§L¶“IҬ쯯Þökh£†Kû’‹$î /7ãAÉŽpœƒ6YJ$ðŽCÈ;üqàˆÝu(ìÆmv*ìUØ«±Wb®Å^cçÈ!ùÌIr¶Ÿ¡µ‡«}OUŒ3òÃö§© cüÙ×ö7¶ÚíG‹Ä‡óg¿Èów“¨Öv. Û× »Çêy½¬ŸŸ¿ó”}ëüQäXNö®²\ÁcÆúÖûTÖ&1Ú¯Lô='löWlí?Üæ=û_º\¥ñ©w–ÕöN}>ãÕñúGO¹îß–_ó“Ÿ—¿˜>†}7øsÌ’¿P¿‘DÈ{Asð£o°WàDzœÂí/fõkqï¤hp#”²\YÚÝðúÌ)#DKBì8Ù”¡dnªx±Rh#29džùÿò2ÃEü–ó_“+ìäK½Jxµ7¶yšY®LÇ)dsÈ€‘Ò5bw÷$çG í¹OY.s´GºÁßõµK¤€ð6y§Ë>~ò/•?)¼‹ä‹»/Ì› ­"¸SfÉe$ éÜ9™ªy¹ í"­Äô gK¥ÒäÓçɨ˔D¼ï–ܶò÷¢A»×µùÉKÏ/yþo+Ùh÷>hò¿–l½?6êÚe»Ü\¥ä+Ig‰¬hãƒú¥Ey|Bƒ–‹³£&ÈcœÏ HЮƒ¾ý͇-{’¼ëåïÌ/[yŸË&çL¹ä¿˜åŠT4x¥Cº²ž½»‚A9Íf&›!ÇQ ±"Ùb¥óÇæÿüã—æißÍß—/—<ë ýdE0ZÝέÌ81ÐÁ5w&Äý¡SÈu}í<ðT2Ü¡ßÔ~±øòiž+ä§ùCÿ9c®y[W–Ÿó¶òéÚ½«-¼>cš0¬; ½TYHû71Ô»w|ôm>¢ 'Ä ‰(Óìˆ'‚ê®­eI­¦E’£`é"8䬬µj˘*b®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®ÅP:γ¤ù{KºÖõËØtý&Ê3-ÝíÌ‹Q ڬͷ]‡‰Û|9ù•ùñùÿ9®Ü~XþI[Ïcå姬žvòÝÛ“Åžy)X-ÛzGöä¹0µÝ¡‹K<†‡Ú}Í/[üžüˆò§å-žŸ›&N7ºäÈ€zÇn¦¾”~4<›ö‰Ø/í~Üˬ•L:Gõ÷—6Ä^«šVnÅ]Š»v*òßÏßÊèÿ4|…u§ÚƧ̚g+íR>/Yゾ(ááË‹³›žÂí3¤Î úe´¿_Á†HXaÿóŠšy·Êry'\‘‡™ü¬«Yj%›OSéÄÄëýÓø|5Üæµ™àåñaôdÿuûyüØáŠ}œ»k±T¯¢èþ`°“K×l-õ-6jz¶—p¤ñ1‚R@EGcÛ,ÅšxåÅb{ÆÊE¥ž\ò’¼ òIåÃIšPD³ZZÅ®§~&@9·Ù­2íF»6oï&eï(“!ÌT»v*Ðt,ÈZrPwéQ+ϼ©ù©cù‹'šlülòOåÆ[T¾ÔWѲº½oRˆ†2òp_Oâr üBŠsiªìÉi¼3”ý{Ðæß"wtòtÿœ˜×4|ßåŸÍ=?,ùëN´»¸Ð 'ÕnÜDÂÕ¤g©.*²(â´¡máör<šyqã‘]ã¿û9†¿®ù³ßùÆí3]·ü²²×¼Ñw¨ëÞd‘õYî/ç’âQ”KeV’Ä¢@?Ë9¬ö‹$¤ÃŒ=; ߯۷Á–!¶éü凗¼ÙæË™Dk?Ð:X—S×c¹}h‹bž‰µ(¨ )“•>þ9>Ëj1cÔzïŠ^˜×-ùßÙHÌ {ʾCóæwüã÷­qç+½K[Õ!Šû@"¶BÊk%{sdï”’7*Q™€¡ø¨HÌ­V»—_CŒbj]n÷âò?Øc̓èvÔ9¿0(¼¯¯C"yƒÉ÷òù•&Vîtþ¤’räßVÇó³”Í–}t:}FHN@8}Òþß“."§ó‘ÿ,?ç#ÿ0n¼õ¢¶¥§]D—V·+f—¿U{¸á¸wá'@æCqÐü= ÈÇ}Wga¥ÂFÜêêÇèº[FÕÿ+.uOÌO'þoÊO/ySÎ7¿”ínU¡Œµ­Ô·qÑV¼cǪî@¯ ‡iö„tÙ´üGŽxÇ®¼À>gûSØ>i?—?)|Ѩþ„òŸ™¿-u‹ûëI£‹UÔ5O0ˬcÓkèªP(C% V¨ã‘¨í\QâÉ<@#az¯Îÿb*}º«ÅBÔš*MI§‰Ï:r[Å_~_ëOþd««ÝJÛ7ÞÚÿÆ.ŸúÐÿq7iìçøÌ¿ª~ø¾…Ï{wb®Å]Ф>vòâù»ÊZÇ–Ë*>£m$PÈõ(“S”NÔ©¢¸Ri›>ÆíÉê±çþd>î£ån6³Oãb”;ÃÌ&?%u?"ê·ž`óeŽö°‘-ž’mä’hà·ãG`eD ‘DQM–¿ÍµþØc×âŽ81…ñNÀžœ‰÷žó]Σ²;"X$g‚ysüÑÒ<Çùqù¥oùâØ>¥¡Îª5xb÷<`ò‰8ƒÅYu“ µÛ–ÓÙ­VŸ´»0önYðdA=}\B»È;ÿ7—–/ibɦÔLGzü«ð{ÙFÿ9%äÿ1ù‡KÐ,tÝF6ÔŸÑk‰¢Ž‘LßaxBò3z¶Üzô­4úïøêôØ2fœàx7 Nã®ä ÷us0{A‹&HÀ z˜×æ'™|±ù‹æÙ¼½’õO5¿•x®f°º6Ș$£Š)f ÉDø”’ 6Í·`vv§³t£1ÔãÁãÑQâóë} êâkõõ9L9dðï‘¥È2ÜØjþtÓÞ[Ø|•¢B×QÙêŒ^ãO1;ŒöR\0û=:å¾ÜötrbÓLœùO ÃéÖþ{‘^ö=‡¨1–A¿EÔ¹…þRÿœŽóV¡§Þ^jO¸Õá‚tn´˜fXaªH¸‘„‹Ïuâ>w;d{Sþúly#j#Œ‘ÊdY?ÑçÞº^ßË(’q™oü?§›Ùï1¼¦j‹¡êzõ•ž±ð¬–’Ü h€<$o²§~ŒFp}ŸÖåÅâãÅ)C¼~c©ø;ùö†ˆS]ÖÁõ¯Ì¿17çf•ù{å¿«Ë¥¬Q¶¶&Œ¹Z£\ÈQÕ”©ñã¹›ps¢Ñû;§“YžÄìðQóá?­wä9ºìÝ£“ó‘à ¯âûþç°g ï]Š»v*ìUå¾ü†òWž=[Øaý ¯>ÿ¤,Б¼f‚¡ÜŽ,›;.ÂößY¡¨“âcþlºV\ÇÚ<6»±0çÜzeÞ?HxÏ‘??0)5{Ï-Ïv¾rò–“3[Ï<ޱGú|ín™K"ÖC†Oå×=wQØú}~(eáðgXå{‹¢:Ÿvýï0qÈÆø„O7Ø¿–ßœ>GüÓ²õ¼·}ÇRC]è÷4ŠòR¤:ÿ—e÷®ÙÃödgÒJ¦6é!Èþ<Û#1&a«XK¨é·öv—Ri×—–ò[ǨۅõíÙÑ•$N`‚P·%¯|ÀÅF@‘ĺ<‹"6ù£Éú§ä?äôÞOò5¥Ö¿ç9Þ>û]†Õ¶úÙôT¹½2Q„P«?Ûfz×:Ý6®=¡«2‘b#}Ûü{ϦƒÐêöoÊËØ,|ƒ¦yT:Í}kNá>Ì·“žR•ÿ%vE=ÕFh;[^uYå“§!î‹m„hRa{ù‘äm3ÍQù'RÖà²ó<ɰXÜóƒÕY‰ˆå‘DLÌE«“]©•C³³Ï‹“ñø´ñ ¦S˜I`Ÿ™ÿ”žPüÖÒ?GùŠÛ…ü*Gêð·v¬•ÚB~ÔmðŸf¡.Íí\ºIÜÝGCøïc8 >xòŸææ§üâ6½•<ë ¾bü«»•…Œ±V5-ÉžÉÜÒ7ý§¶sÄÅ+Ìúfv¶-d.XõŽ÷&2sy?Î^Yóömæo)j1jz5ÐýÜñÑÀ£‘ŒŽµø‘À#6)î*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»c^|ó÷•¿-¼·sæ¯7ß-Ž•mð¯íK<ÄÁÝäjl£æh «á½SVüÑÿœÇóAŽ?SË”:UÇÀ´&0V´gÜ ‹¢§ <"µjú^×í¬z8ï¼Ï(þ“Üñâ·Ô~Fò–?.´|½åk1kgiZ=Ì´¡–y( 9û‡EPg–ëuÙu33ÈlýƒÈ9‘ˆ™.b%Ø«±Wb®Å]Š»|wùߢê_‘ß›šOçO•¡? õ‹‚5‹DшÓg¨}2rû¾ãÜÂq1Ü"¿ç|ëå=Eºü»Õ¥“JóÝÅô·³[j èµá™c³š³U>›Qy-ErÕhòÎc4}XÀ­º{ÿZáåÕùý¦X~f~s~_~T˜ÇIõjê%Q:Z8.bJ|9§Jºûd{ $´º<Úpˆé~ïØS\€Fþ\[~pþOyÅ-ïô»Ï8þ[Lk¤kpËO…3ÈÁ-(ð3 }¨ê6jûFZMnHcËüQþwã¿æ±â‰®¡u}.Ï\Ò¯´]E=M?R·šÎî:Óœ7˜¤Zû«åqe8æ%q6> Ä[È<‡ù9'ä•¶±æ ;_Ö¼Ïka§ß7Êž‹K£0/0g‘â ­­Ièk›íwkþ|Æ„`I?³sÜ/«\aÂÇÿ&ü­æ-óƒÍ_œ~`ò¬þR±¿µKM+M½_NáåD&Ъ0b!«A¼›r¡9•Úú¬xô˜ôÐÈ2l‘Ë­·ìcL‰¦e?ånº??m¿5l®­@m,Øj6¬ò‹É&ôÝU”*)æ@v;xëãÚpüÓx¸¬w}þþŒ¸=VõœÒ6;v*ìUñ‡å÷þ´ÿæGúº·ýÔ­³}í¯übéÿ­÷vžÎŒËú§ï‹è\ñ×·v*ìUØ«±Wb®ÅPvÚF•e;ÜÙØ[ÛÜÉ_RhaŽ7jø²€NddÕeœxe2@èI-qÅ›óÍSòSKŸÌמjòþ»ªùnÿSf}R=2àGÃ9äç§ Y¾&øˆ¯@3¨Ó{c–:héóbÇš0ú8Ř÷|†ß}º¼ä„¥.ty°áù9æÏ'~Xù³Ëþ_š=oÌžb¸ˆIpŒ-™¬PJ}v¡sYú?\ßktºÞÒÓæÌ,Xbvú½ËééÑÁþIˇM’õJgÝ·ÇãófÞSòö£ùyù4ÖVPÓÌvšUåûÆ3FH^p†• UøÇþÇ9îÔ×ãí×â‘ýÔ²F?æ#~V7ø» . iô”¨DŸóªÿcÅ(<£ùQæo'k:ÏŸob“]k‰Úêk‹×·šÚ ĨŽLÌY‹Õ? :×Ð=«í^ÔÒêñâÒDŒt(Ø‘åGm«a[W7AÙZ].\R–Sê¾ú¤÷þqg˯su¯yÖížržž“§ÜMñ9U $¿h’(‚; ŒÖÿÁ/^#ZXÐç9òoû\f´öe”ïü#ñò}/žHõ®Å]Š»v*òŸÏ¯ÌOð7”ÏO—‡˜u°ö¶%OÇ TýôþÜAâ§ù˜Ç;Ob;óú¾)ÝâõKÌÿ ~<Ït½·¯ð1Pú¥°ý%gägå¤OòQ}bÕY×ÑgÔá™p”úV̬)²±.ûLGl—¶žÑKY¬ýÔ-¢GY|ùyv7g 8}CÕ>~îæ=çùÇx¾º<Ïù]xÞ_ó »úñY¤¯A½`•([­ëÛá¸ì/ø Ê#ÁÖn/âÿ8ßïpûCÙèËÕ‡Ò{º|;¿“/Ë¿ùÊ-kËZ’ù+óÊÆ[+è8ĺ臋èê(ÅOi¡?Êwlêu~ÏâÔãñôR‰éqè|ìyyqc— Åú§OÔ,5k(5-.æ+Í>åD–÷Vò,±H‡£+¡ –qÙ1Ê1¢-Œ~j7œò÷Ìä Ç͂ںpŒ/Û_WÒ ZÉésôÇóR›æoeŒ?˜‡ô^ÿŽëæÆw[>.ó>¯æ _˺7‘â×®|éæ3ˆ!»Ð¼Á¤Ï±¢êI"–’Úöo‹eh÷r¡yæ§ é±c†Ie0¡ ©BC†qóˆùûÜbMW7Ðw?óþWü»ó'—ÿ,<Átuôë,üÏæQ%b¶¿†SÉ@%É*ÆZn¤¹ä-ÀË©Ç<ð6I„{Åþ)»ÄÓÜ´­WL×4ëm_G»ŠûL»A-µÝ»‰"‘ueÛ®ÇÀç7—±ÈÆBˆèÚ ¡üÅåÍÍš=΃æ+õ &íxÏm0¨> ¤P«º²AÜžŸQ<3¢E¾JÕ¼·ù™ÿ8•æy<ëù}<š×åµÜŠ5; ù4b2HX¯U>ɤW*űñoMìOh!«ôäîè}ß©ÄÉŠ½Ï³?)¿7¼¡ùÅåµ×ü¯qIâàš¦•1êÆvá*ŽªhxH¿ p@égءث±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]аÍOÍ(þPùfO1ùªç>QéÚtTk«ë€µB¿ñ'? ÷=*¨‹4/,þaÎZù´yûóWÒ¿.¬¢Ótè "4`ÔÃfÔëܶäì½(œßn{A à†ùÊ>ÿÔäbÅ~çך6‹¤ùwKµÑt;8¬4«4[ZÀ¡Q{w$îIÜÎùæ³O,Œ¦lž®`ŽÊÕØ«±Wb®$S°N*ñ̿ϟðíÝ®…ùo¤¯ž¼É4sÝ]Á¦Íõ˜¬­­˜$7ÕDË‘ãÇjwìAÙ݇âƒ<ò𣰵“Ýt×,•Ëv]ùQù¡¢~lyV/1i*m®coCSÓ]ÃÉip%K9)’=!Ø@ÀíNÌž/·xe ñsšæLoÏþKÓ?0|£ªyKU[ꕎjh'_Š)–½ÑÀ>ý;æ^ƒY-6Xä1öŽ¡Š|çÿ8»çMSÊcÖ?!üæLŒ÷£; c«Ü@„õW_ßÄFÄr=Æu~Óhã›ux¹8¿AýàÓŠTxKë â[ÝŠ¸ ³(Ü“°b¬GTüÄÐ!òŸ™|ÓåÛ«o0§–mîç½·²»‰‡©iâi˜SÄxÎÅÙùXc˜0ã"¬wš¶&[[Ïu›o&~v~HGç¿âhVn@ >2$J…ý´âΣµN“W”é² Ãé==@ýŸ"Õ ˆ°ǫ̈üÅÿ9äß'ÙyCF½±Ñ.õ}æ5DúÕb·A…2Ó×Võ‘ æ>ø³CÙÇfæÈrHÔxw»û¹u®m’¹OKüÀüü¿üɸÓïµë) Ôtâ‚í>Am;ƒhdp§’ ¸þÒþË šéôµŸJ±.‡qïg,`²]'ÈþUÑu6×,´ØÛ_’­¥ÖnKÝj1,*­up^R8¢òø¾*TÔæ&]nYÇ€ËÓwÂ6ÈlÈD2 ÅK±Wb®Å]Š»v*ìUØ«ã/ËÏýiïÌ¿õ5oû©ÚçAí§übàþ´?ÜMÙ{=þ2ª~ðú–§ ƒ£\[»cÐ’ üI_³"íãCP4¥Ù9´’©ºHr?ŽçL¼Çä-+U½ºó.“gŸ…ÆŸ§ù—ÐÏl'^!ø’•¥¶à¡ Õ§×J•Ë‚c|ÔÇæùÇÍ>^Ñÿ!?-¦òd6‹æ¯Í¿ÌQ-”÷&¸2zçƒ …Ǧ§âyO3° ë4º‰ö†¤e'ÃÇ~î_û†Í$pŠêQ¾QüÓòÿüã×—,+®,¯¼Ñæû1%ÿ˜¡ÒÂÉo§ËqI^äLjT?Ƶ$‚i•êû3'id:€F8£ÅÎU×â‘1LûÍ?ó“^PÓ<¥ kÞX·—^Ö|Ë,qézNî‚q ÂU^eX0hÒ¹½8ÕjF¯KìÞYåœ2ܺr±_frŠÙ쪑êºj¦£eÆ+غÓî–9(²§Ç ª £R¥XTûŒÐY„½'‘ؼ6>MüÅü¦ó‡ä?™?åo~HÍ$Z]¹-©èÊo«Äæ²+Gþíµ;rSñGöÛ’ú`ûF3V,ƧÒ]ÿ·ïqrâ­ÃêoÈÏÏ+~vh?YÓȱóE’!Öt9²@ÇoV"¼…›ì¸éÑ€={‡«â‡b®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]мóó‡ó‡Êß“>V“Ì`“Ö¾›”zF‘q}px­kÅ É!QâÅT©ñÿ’¼ƒçoùɯ5¯æÇæä­”‘øéZDAâŽâØ‘²–&;pßnJòÖ†µaÊvÿ´#Oxñï“¿ù¿µÈÅŠ÷èúöÖÖÚÆÚ+(RÞÎÝ+{x”$qÆƒŠ¢*Р<ÒR2$“d¹j¸Ø«±Wb¨ g\Ñ|»`ú¦¿¨[ištd»¼š8" zr*{ùfÉ.#Ü7Rió÷üäüѨ~\þžü­Ö¬µ?%KëØy¢m8Çs2Gs¤+*3pOŠŽ Zž$çSìö‹uˆ˜äØÂöåø÷4å‘­¹0‹_(Êý[Éÿœ¿‘P]ù‹ÉšÔQiºÖ•¹»e¸uWJ(¨,é¸;G2 ü'ˆØËWù¸dÓjÈ„ã¼eÈmøøÄ±áª!ïÞPüÑ<çýsÏÚÕÍŒ^a…Ç—"YÇ37©$Œ*ž[ àK€Jµ1«íyæÁ 3ð«¯ãïÙ¶0£oIÍC7b¯–ÿç+¿/ïì&Òÿ:ü£Êß]Ð¥·]VHWãáƒmtiÔÆÔëZ©_Ù\ìý–ׯBZ\›Æw_¤|yÿkFhõtü®óþŸù™ä7Í–4InÓÔ-—þ=ï"Mõ4 ºWª{ç7Úz isKéËÌtm„¬[0ÌN C¸=F*ù‡óGòSÌžK¼Õ|ïù+ú®±kqgæ'Ä£º‚éYíb^¤s,#¡û™ØöglãÎ#‹UÎ$O¸ŽóúzõïhœÜ3oËïËmzóþqâÃò×ÍO.‡ªÝ[Ý[_”ô¥šyµ &81J¼/SÆ»Š‚3]¯íG´|~°#ßÂÞÎ1ôÑzg“|©¦yËo•4v‘´Ý./F•¥`X»3•U–bMÍ>³U,ùe’\äÎ"…'™Ž—b®Å]Š»IµÏ7ùSË*[ÌZ冔åKÛ¸mØe‘5íLÈä˗艗¸ƒ i­ÿÎRþKhÅ‘5×ÔçZÖ->Òâ^‘Õ#5ö|ÛáögY?àá÷‘ý¬X° [þssÊ–]Ë•ûtO­ÍofÓoîÍÁÜûLÙâö3)úòD{¬þ¦8è)¿ç-45jŸ,~]€¦¼ ‰}A½*`H+ÛüúX}Ñbþ÷PÆ1ûÉr!‡<þœr?P’~wÎRju6žZ³±¤±1Ð ©þ—pß?ìÊΟ±qóÍÿr¨öN¶\±Ÿ»ïC·ç0.¨EÜ6A{t3ο5“§Ñ:¾ÁS/ùYûˆû=¯?Á_þµ/Ò_󖲓+ù•ßâd®ž´'zQ â>°*öÛ€ü¥úÛ³:ß/˜bV@üøÓ<Ǩy¶Æþ|Ū‰F¡|&·-0šEšJ«FTUÑNÊ:eÚ¾ßì}FáÉ(F¨Qé°ëæÙƒÙí~)qB÷„ô'üå©å±Ŷ#ýƽ)ÿ¢§ÝšžfçÏò³ôIÌükG”ÿKúBåóüå5 °Cz«QȦ”yס¤,‡oÀ{;Ù©ò&?Ÿ¦Ñáv¼yÆÿÒ~µëù³ÿ9 ¦m}äøoP1K ™Ójƒm1þÎ@û+ØY~Aùñÿ}ÒÄêûJðßù§ôEÿœžó.–iæO#É3‰¦µ§OÙšÿ‰dü ôù¹Ôƒðû¤h2ãþó1÷„ÿMÿœªò-É ©iº•‹ž¬±Ãíp¨¿sS9íW±½§‡žêÔ¿Ü’]†.ØÓO”À÷í÷³‹-BÃR„\i×PÝÛž’ÛÈ’¡ÿd„Œçs`ž#Ã8˜žâ)ØBq°l"2¦nÅ]Š»v*ìUØ«±Wb®Å_?ÿÎGyÖîD°ü®òç)µ­má7ÑÄ~?IÜ,ûw•÷oòGƒg§Àÿ±à õù¶† xo¼T¿Ío˜yžßÖX!õKŸèªþ\ù&ÓÈR±òõ¿¸}]BáÝ÷rd}÷¥~ÿ$ âý í‰ö†ªY¥ÈíÝÈ~“çnç³ôcOˆ@sëïey¥s]Š»[$qËÅ*‡ŠE(èÀ2²°¡ˆ#%A¢@"‹çÿ>þFjZ¦¾{ü¸“J×mÎt«wôÁ?´mXš Ž°·ÂÃaO²}SÙßnã’?—×ú¢vã?ïÿâ¾}ï'Ú}^¼?éWêz?ä¯ü䵇œ'Éߘºžbo«¬’)‚ÞöTŠÿœ~ÿœÐ?;4-ééþvÓã_Ó:7-ˆÙ~³mÈÕ¡cô¡ø[öY»—‡²â‡b®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb¬ócóWË?”R¸óW™$.kèéÚtD ﮈ%a޽:UÜì«¿€*€ø×ÈGóOüäÏfüßü×äžSÄzN’¡ÒˆâbVÞwèkê?Y»×‘§´=¿ùqác>³Ìÿ7ö¹8±^åõüAkvÖѬ6ÐªÇ 1¨DDAÅUUhPži)lór×àWb®Å]мƒÍÿó‘ÞCò7šu*ùŽûk½*Ò+¨¥Ä­ô²‘H- “FR¨‡âø‡÷ºOg³ê1G$"F¹òó?‹ä×, yWç«åÝ[ó·É‡óHÜCùQu¤‹Í2”¸··úܪ䛨¬ŠÁ½5‘z¨áÊŠNnû#Hh²~^¼a*5D×—Núø°™Bù*~Jé^TÔ?;<óeùs]þP\é"ÛT…ħËu1}$|Lïørýž|~8;g.Xè±ûf±üêø|>Ϋ8r}ùsùkåßÊí}ËMrÖ72Þ8»¦!ä   ÑT*…]–¦•jó—íÑÉ«˜œêÀ­ƒlb0ÌNÅ]Š¡µ>ËWÓî´½J¹Óïb’ÞêÞAT’)T£©ö Ó'$¡!(š#p¤>=ü³Ôo?ç;µË-~vÿyŽHÿG^LH@e$Y\× ©­¼Æ€r¯Î󴱎ÒÑ ð¸sî‡ûáû\xž Sì¼à‡b®Å]Š»v*¥uukco%ÝìñÛZÄ9K<αƋâÌÄ>xc#@YWy¿þr‡ò‡ÊlðG«6½|•ßFŒ\­GOß±H¯òÈs}¤ökW›~ý-¾Îc\²Ä<ƒPÿœ²üÉódkùk䵊2Jýnáf¿uÿ(úb(£?ë–¸>Îèô¢õ9€òÚ?¬Ÿƒf Y³Ç/ƒºÒç$üøKù§ÍÒérÿyi ×Õ×ý“œ6§ùmóß1çídivÅÄ=õúg¿È;¬Ëjò}d@{÷û?[Z_üãfzÚö³y¨NÇ“ú –ÊÌMO"þ«ø!šýOü3±cŒGËþ%Üàö;úæeîÛõ³M3òsòßKâbТ¸‘z½ÛÉsËæ²³'ܹ¡Ô{U¯ËÏ)Õ¨ýÛ»|>ÏèñòƾÏß³,°Ñt},Ó4ûk%€[A ”øf—6¯._®r—¼“÷»xÐ<Çåû¯3i²Iú&ÌÍëÉ$LŽ>®‚G!w&Šs;[ØùôÙã‚`qÊ«~óAÅÒö–,øŽX“Â.þ±¸¿=¿,¤n-«¬~¦ÒëþrWÉ1Ü2éñu c¾åOPGt~ƒ–gµÜãàÈûá÷\yi{SOË÷ƒý7ê’o¤ÿÎQËa8°óç•î4û¥ –KNJñ­µ×ÿŒ‡5ú¯øŒ‘ãÒgÒÿŠÿ¹ahŒlf'ñÐþ·«ùcókò÷Í¥#Ò5ÈãÐ +¢mn ÙT›#þ¥sŠí/eµú=òb«S8ÌåÈ<+òË:‡›üɪþqy z·7LšXaðú­ðK"û1§îcú—=#ÛžÑÇ£ÓãìÜ» >r>©|;Þs°ôòÍ’ZœœÉÛñåÈ>Ï'z´–ÿ;^Òõë-j7ñÛkš4–0JxúÜX'c·"Oµ©í› —¨Ë‚Yá(@Ôˆéû;ÏN®<õXã1jRäf½Èv*ìUث˿5¿%´OÌHQ´á¦ù²5Ž¢¢‰?@—!waMƒ‰}Çç²þÙfìâ1Îç‡ù½cçÕÈù:NÔìhj}3ûýÿ­ ü©ÿœóåþ²Ÿ–_ÂH–±Xy‚r]âBx§Ö$ßÕ…©ðÎ7_Ú¨Ý}]Øøu¸¿3¢"@ÿýǾ?ƒÆLO¸2 !õŒ°éÚŧ4pßé—h­ÅÕ'‚hÚŽ¦†ªÀìFq ÊÚÁÍ.ówšt¯$ùoQóN´df™šqm,¸UUUîÌ@© I|·I¥–|‘ÇrD |›uæ_ο0Gwÿ9%寗|µ¡Å(òï—µn Ë9HRžœF?PÊxÑÜQÂñBÓ·Ž›GŽ´Tg)}R±ýö6‹‘õ>Žü¥üÓÑ4<«§êö÷°ëòÂÏ©èÝG-Å£Ç+@Ìñõ¯(˲Ã9>ÕìÉé2˜xoiVǯö·Bvök>QüêüžÖ¿.uøÿ;ÿ&Ùôûí2_®êº]ªž1ïY'Š5ØÂ¢âðñ$ýšß{9í`Ìwþ~ƒú —PúWòóÛ@üîòѼ¶U±óNœ±¦»£ÔŸIÚ¡f„Ú ñ=Tü-ØžåÄ!ëX¡Ø«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*Æ0<ûåÏËO*ßy¿Í7?WÒì–Tr–âfÚ8!_Úw;Ó¹¢‚qWÃ~Vòÿ›¿ç,0eüÈüÀY,¿/4Ù}-7KFoEѩۓJƒJÜÎXì)·kÚÝXðC|‡ýŸêr1b¿sìK[[khl¬¡K{;tX­íâP‘Ç*ˆ«@€ òéHÈ’M’æ*àWb®Å]аÍoÌûoËM*ÂH¬Xó·tšvƒ£Dâ6ºº€99Š‚Ê ¡ÜÞ£gÙ}šuR;ðÆ"å.àÆs§ˆy»È~[ü溗RO4Ágùó …¬±y~×TŽâÎÂêË”o F’›·Æcðp^Ÿk:=&»&„pødéìúŒhzŸÚ75‰{Ù/åüÿ™ÿšsÛywó“ÈKåm&ÖH¯ïõkb—7Z€¢Å=²8Ø•›DîHað¦aëã¦Ò=6cÇ#°‰ØG¸þß—TÆåÌ=ãDÐtO-ié¥yN·Ó4ØÉdµ´…!Œ1êÜPI¦äîsšÍžyeÅ2d{Ëp˜eJìUØ«±Wb¯ÿœžü«?˜>HmgI‡Ÿš|¶$»³àµ’âÚ•žÜSrh9 þe ûG:?f»SòÙ¸d}Øù…«,,#¿ç¿5?åeù(u)½O4è>–­Í’eãû‹“ß÷ŠcüêÙ_´]—ù\÷èžãô‡ÜœS°ö<Ð6;v*Áüõù¿ùyùs4kPÃ|SL‚·¯µGîc«(=™ø¯¾lt=“¨Ôÿw]ü‡ÍŒ¦7ÎÚÿüåž¼ás.•ùEåg‰~ÏéÈþ·p¡º9¡¯ûñä\é£ìæ—K=^P<®‡ë?ƒ\æ±DÈþ>LNoʯÌÿÌ;”Ô4¼×3¯"âÈJnZ2z„xÛÅÿ<Á‰›Û ”pé1_™ôø£ñ§£Òû%š{æˆîŸÕ÷³/~Lþ_yx+¦–ºÒÒ·‰$‘ßÓ`"ä™Ëk½¬×j9Ï€wCÓöý_kÓi=žÒaþ#ß-þÎ_c0Ô5=ËÖ[Ô®`Ӵ訂IYaIû*µ ¯€¤Á§Ë¨Ÿ œvåÚåÍ nDF#àƒòç›ü¹æØîeòíú_%œ‚+‚ŠèQ˜rHªH=˜lh|2ýeê4†#4xx…Ž_¡§I¯Ã¨ã—syOæg熳å/3^ykFÓ­¬„[»“$œŒÐ¤ß !@( ÉÎÇÙïcñjôñÍ’rõ^º9ïÜó]³í.M>cŠšÜù‹òïdŸ›¾`Õ­ÿ."ó'–/d²/%Ážk•âH;èvÍW²úRל9â%´…çGû °ííVHèÆ\R1úMŽãý¡åú” ó‹g­ùÓóCÑŽþœéóÝs•CõJM8ÜR”ç]Ÿ´å§Í,Zm˜šâÛìéyÌZ›gŸU\BèŸ×/ÐúKJx$ÒìžÖqulÖð´7#¤Ñ˜ÁYúÃ|òÍHÉ!!ÂlØîß—Áïða6(oßæñÏùÉx ycF¹Þ‘ߘÎÛ~òmÏÁÇü§þwÃî#õ¼§¶QýÌô¿C$“ò{ò÷^òô –776ÑÉå»:˼`†û\Z•èÀŒÕÇÚ­v æò#±äwû>Àû?¤Íˆz8IÇ7Ÿ~Pkïä=ybòS,M¥Ä–§—%A4¤ˆ§ùkeÄçKíN’Y¥ÏG$…ü kã¿ÜèûQ#¦ÏŠFįˆ•ýÈÏÊ‹‰äoœh¯n5uÜiѸ&¾ç(ö–ùcOçáÿÓB{gù37—û€À¼—ç/!è^TŸMó/•XÔ¦–vŠõ­í÷VE ¸Þ-?g¥vε»+[ŸR'‡?‡¦åóáä~.“³»CK‡Ž\\r$ïCå|Þ¯ÿ8ï ëš?—µ+VÞ[[kùã’Ê”£ˆUåÛ€ÕPzxS8ßnõ¸sg„q‘#xˆ÷ò¿/ÒôÞÉirãÅ#0@‘Úþ÷¨ù[ƒËzþ»sK „/;Ä„~=ܳ‘ÐhΧ41DÑ™§¤ÖjF RÈwóhç"üˆñÚ4ðßE-À&tXŵ¨õ1ZËà ±ñÛ:™û­Tb@å¿ÕîÛá½<ü}­Òб-ü¹{÷û­éöšÆ—}¥Å­ZÝÆúTщ£»,?LþÑ-J{צrYt¹!ã”O5]mè±ê!8 ‚8H»kO×4]\¸Òµ+[⛸µ¸Šb´‰ {ˆ(üÆnv*ƒÔ´/X·6ºµ”ÖÇýÕsJ»÷Áß/Óêra—9Ÿ#MY°C ©ÄHy‹y§˜¿ç|«‡—Kh·F¤w2ÁÈ÷h¥'odeίCíÆ³Ù+ óØüÇéçµ~Êé²o òÜ|è¦/—¿>?,¨ÞVÕ›^ÑbéeË×P‹_‡ê×eù@Õͬõ‹ÚŸßã𦋗û(óÿ<:iöWhi?»—‰ïøéÿzÊ|³ÿ9A§zÿ£<ÿ£M¢_ÆxKqn$JÝýH Sä9œÒvü ²pñé2 ±è ðôŸö)Áí‡4Lã§1ö½¿Bóƒæk1åýF FÓ`Ò[ȯÀžÎê}˜žy­ìüúYðfówÁè0ê!”\!3Ì6çb®Å_1þpë‡æ§æ.™ùMå¹èû ëª\'Ä‚áGï¤qÒ–ñÔR»¹+Ö™ëþÉé1öOgÏ´3TÇ Gø@þ¹ÿcG½ä{[,µzˆéáÈýý~_{èÝF°òö‘e¢iqz:}„)ºm^()V"•cÕs¾yN³W=NYeÈnS6sÔáÅp Ìf×̾nó‡/üäPÕ<Åx–Ú“l‘ÝÜ“ÎXâõQcQ»?¯p¿ Šž9ëÝ• Ì;ÃÃrjeöFû‡ :÷¼Ž«<¿Šf£Œ~>ÒͼŸùÑ«ù«SÔµ™4%Ó?,,crÞ`½˜ÂèÑV¤ìË!m—Ò재jsÝ­ì†-&8bxõR?ÝÄ_?º¿.}ÎÃIÚóË#.CøãpJ¯?ç+<•ù‚×JÔn¬¸›À°ÆXö’7pH=¹>Ã3qÀÇY(\²B2îÜüÍ}ÖÓ?i°‰P‰#½ë^PóŸ—|ó¥.±å˱sm^!%†JT¤¨wSøÄŒâ;W²5 ¾hðžÄw‚îôº¼yãÅa?Íc’ìUˆþ`~]y{óH:nµ ¨ƒ F ={Y *Tžªiñ!Øû¾ìh³ön^cÒb¼³–KEÔ¡å‹Æh. ™iÞ¡•¡8©Âx§Fã(Ÿˆ+Íã_šß”7>uó>“æ}r+É.Y½Ýæ‡6¾œ–«¿"ƒ¦cýº‚ˆ ¨¹fÿ²ûX`Å!Ž7žf„¹óý7ó;–©ÂÎüžqùe¥Ûþe~x[~`þ]hQùWòÛÊѵ‰»¶„Z~”uÐ)œ:óªÆ£‘äTfß´².ˆáÍ?.MèïÃøûùlÂåc“é*þcy7Ηڞ—åíR;WFš[}NÁ•⸅âÄÇ„K/!NiU÷ÎGUÙù°F2œhHX=Äe$(w¨Ì4¾FüÞü´ó'ä§›¢üñüž­­•¼¾®³¤À„Ãn¬A—”hG+YiûÔÿuÖ‚œ=Ù¾ßñ@Ôú¿„÷ù{þÿdÑH‚þ.0ë:S7)ln¸Ô¡4‘ºÇ%(ÃÁƒÙ¸¤=;v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±T·­é^[Ò/uírî;#O…î/.æn)h*Iý@ ÉØoоÔu4Îd~ho_Jü¤òÜ„B›+¬NÔ¯B¦êà-OU|iñé{o¶#£Ç|ç/¤~“äß‹¾½Ñ´}3Ëú]¦‹£ZÇe¥ØÆ°ÚÚ¼Q{âz’w's¾y6lÒÉ#)%Í‘¹Z»v*ìUŒjÞyòÍ—˜í¼ˆÚͽŸœµKi¦ÓmeS!E™AQRjÊ…”¸V¦fbÑd–3›„˜Dïøý=d.Ÿ1K0ó'˜òCþrbi—S†ñ¯<¥æëvKo\\;¡FÓ—¤|“á#Ó4eZv xXÿ5¡ª§u_mŽ¿6Žf¤Ë?,"/ôïÌÛo6Ï Aå/,ùTÝÛh–±\«íaÜÉ ÝÝHÌÅAGåÇá¦À-+˜=¥Û‘–˜ã9'’Œ¶¡[Pǽ¾˜ÎA¹ØªÅޤÝ]ÊZÀ­$ÓÊÁ#U™™¨rNÄÈÐܪO¢ùÏÊžb·±ºÑ5›Kص?_ô¥2ò¸ú«˜Æ„†n|T}9~m\D‰ÄŽ¿+ä SÌÇK±Wb®Å_ùÊÖçþq£óÖÓÎz\L¿—Þhi>·k%)]MÜzr‰ÊÏÚ‹Ó–zŽCµ4'¿¼ÇËô#óq¥è•ô}“kum}k휫=¥Ìi5¼ÑÉ$r(de#¨ Ôg(˜’Ä9/8üÊüøü¼ü±G·Ö/þ»®€xhº®«ÛÕÜ$C÷cGÙ6ÝØzVñç_·àÂY|ß«þs~z~s»Ùù&ÐùWË YZîÞFÊÖ”{æPäŽâÝTøçE=/föX¼òñ'üÞì✽fêuÝÇnó°ùþ¥O+ÿÎ>ywOqæ«™5ÝI©$d´VÜÉäIós^ìÔ=×9îÒöçQ—Ó€ QùËõ€ø½~‡Ù<8÷ÊxÏÈ~³øÙë6:}Ž™l–Zm´V–qŠG¬q¯ÉPœ^lóË#)ÈÈž¤ÙzŒX£Ž<1àÂÿ244ÿ˨­R{o¯ï–Fµ‰cŠ‘P7©!©°è§7ÝìäûDȉÆ5}NýÃöºžØí¨h€¸™rîÛÏö%ú·š5/8~OÜù§ËW/§j¢Õ®$ú»|q½«ÿ¤Æ 9 ª·±ès'MÙØô}«€œ8«~¼_Iû¯âÑŸ[=Ogœ¸ ªöòú‡ÞÇ´ëé1!oṑ®u}>ÞXæw%äiôò.#%𤳯¤õ$æÏ>ÙݵP™wTý'à ¸roeÈå~qÜ|Å<¿Èµ÷‘"Ó|ýcÎ}[™t1ZƒÐí20ñ°1ŸæB+ñg]ÛzhkŒô’Úb"xÏØ~Ñ¿‘£ÎvVyiuÞÁ1öýܼǚmªÙ[ùßUüÐÖì\CkoÕœëN,HŽXwÞ(ZŸŽai³KEEŠ{÷ƒþúAÊÏŒj§ªœw>~€YΑsþ,ÿœv¼·sÎ}:Êxdht×Ä?äZ&sú¬”íØž“?éö?i.çO?ÌvIc?Òn>Êy¯’-ÿ%ãÐb½óµÅÔšï©(–Â?¬p(­ð`E¥E:É×:®×Ÿkæ:aއ«ÓñæCÏöl;8bÎOûoúé{%­†‡ù­å[|£«jZ…¢JúxŠ&tyR(# YX•Ueâ^§®pÙ3æì­LΣ2äÈ8·édïË©îz¸bÅÚ"0ÎXáÃö?½)üÓò%íåvŸå½ oõÉìu¸SÀÜÝ0”NÎXDµ OlÌös¶¡>Ñžl¼„¡_ÍŽÜ5Ìù8Ý·Ù’†Š8±ñLÆWÞ‹»Þ”[yóËRÑ­<·¢ù`é1Çm §×ç‰á™Q#órʪh*h„ŽÛævMccË,Ù3x„ÈË„ïøA'çN,5}§iòõöŸ%¾·%ñ´µõ#-"Íg KFV+ñeÜæË¶{[M›µ0fŒÁ„lïµNG¹ÂìÎÎÏA—£S—|@Bé–Z¾¥ù-7—5;&µó ­ÍÅþŸ œyú¨v]‰þñy ߸9n£ÚXû\f„¸±ÈÈù~ÃE«cdŸgRL!øóäο)/üÇqå8tß4é÷V:¦—ÆÙdº‰£úÄ~éÁn¤žUïœ÷´ø4ñÔ™àœeïé7G¯ë±Ýv\ÇŽX˜Ê;n9ŽŸ© ùë}õ/Ë]Q£ÞIkl‡ç:ÈÃC—{‡´ š$~Â>òÕí6^¼è}¯.‹óȶÿ”å ¬]uãhÐýM­ÈSu ª]ú?hH kÛ¦uòì-d»Só_»â»¿áá_gsÍǵ´ÑìÿÇ×UU×ù×ö£mµ§òwåW—ü£¬h¿¦55=Á¶Ó'‘ Xà–e1òañfud¡­jÊ2i³´²ê1äðã‚®@]7ølAçîn† é´8ðÎg-ÔNÛ^ß}„—P±Õ4?ù:¼±•u‰o èÂæ;¨$òŒ3qrV$ü[øfv Øõ-A9ŽxŸª<&$yí}îq2âžV1 R2L®ÅŽ?K4óožüûÿ+hùgÉ4»KKxÒ}2OH[Ë'¤gg’I*¨¡¸º“N5®h{3±´_Éž>§ÓÄMK{øhÏ‘æ;vúþÓÕ~ÂÁ½§jå{Ÿ“!—ó3UòO—í¦ü̲ æ;Û™â²ÓôµG/a>6&V^­Ù¼6­s[g±ks‘¢—îãe)÷›Ûé¿ÁÝΗlÏKˆT}r&„{¶ódJüÊò÷ž$¸´ÓÄöšµ ås§^GéΊRÂ…”Ššu¨îk;_Ùüú%:”%ÊQ6îÎíŒZ¢DlHs‰æÌsFí]Ф¾aò—–üÕoõ}M†õ@!$u¤©_ä•hëôÏÐöž£K+Å3»â9W Ã¨’"_Ï›ÈuoÈkË׿§?,uÙì¯cÝ-f”Å%:•KˆèíÁÖž-®›Û,:˜xZìBQ=@±þ”ýàûƒÊj½–ž3Ǧ™¸þ¿×óFè?óžmò}Úh?›:$¦E¢JÖ)ÙA¡s¤Rò¢e<Ä×{¥ÖDåìü£ú¤Ø÷_Õt¯àáãí¬Úypj`o¿ñ±ø=óË>oòלl¿HyoR‡P·õmIb' ’&£¡öeæ}£ÙZø3ÀÀùò>ãÈü‹OªÇ˜\$ üßóü_—¾N¹Ô¢uý5w[]"#½no!ËÕϽ|Úû)ØG´uqú#ꟻ»üî_oGµuÃOˆËøŽÃßûwüãŸåüš'5”-¯ùˆz‘< ™#²fæµ'zÌxÞ#Žo¿àÛ£Qœi±ÿw‡m¹rÿcôüÜÀÐøpñeõOîý¼þOnÏ|óõN Uî}\\Gßéâ뽤‘Œ!í~꯽ì¾Xò7–|«åø¼»¦ØBÖ˜K––$v»jO9#ã,wßnÃjgÚ]µ©Õç9§3Å{Q>Ÿ(÷S¾Óh±âÇÁ+ï÷±#þPAä/9k>cÑõRº.¬®£@[nCY‰I}F¨CÈ'À(™¸í¯jåÚLxrcõãÿ)ŹڎÕ×kÜî=e >iN2ôËøkö½/9nìUتCç'è~yÐçÐ5ø=[I~(äZ,°J ,LAâË_‘‚Fm;#¶3è3 ¸£¤‡qü{œMfŽˆpÌ~ǃùKÎ~qÿœaójùgÌ.¯ùc¨ÈÏm*B+7Å=¸$ð‘kûè+Fê:«g´cž›·´þ.Nhó}Ǽ6_´<¯I“K>rè{ßhéz¦æ]ßTÒî"Ôt]F/R ã£Å4N(Aé ¤mÐç—ñLÆC†Qb ¾xüóü½“O»ò|¶qj“] sNò¹ϧÈÜå[уÉC]¸±P»ïÔö&¿ˆd¾žuÂgÊ_ÑüsÛ¹§$yw0_ÊÝgZó?æ-§ŸïµE!~^ÅmçËØZÊçU²’"¶ð]Õ«"òZw¥ |ek²í<0ŧ8DyšˆÆ7=HîŽL lß@ú³È¾{ò÷æ.€žeòIJK¦<³[†š…ÃÂÜ[á~Çbññ¨V»C“M“ƒ'7"22à‚ê -®cY­¦VŽhdPèèã‹++TA¡1c" Ži|uç//y£þqSóßó?òö6¹ò§!ƒRÒÙ¤‰#{9ˆŠ9[KBTŠþß§û=ÛƒU ŸÞGýï÷÷üÜL¸ëÜû›Èžyòïæ?•¬<ßå{Ÿ¬iZ‚r¨%‚A´Ì ž2!Ù…~U9Ó¸Ìv*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«‰MêqWÁž?˜úïüä—æ·äÇå¤Õò^9“UÕ­ËÀÀKu#)Á i×÷Žk½R˜=¡¯†—É>œ‡yîl„,¾‘ò7’t/Ëß,Ùy[ËÐúvkñHÔ2Ï3y4¬«¹Üý€žA­ÖÏSä™ÜýžN|cB™b¥Ø«±Wb¯/üýüÉÔ+ü‚ÚÎ>¹¨]Ã¥i²MÄÅ ó¤’z®€…Hš•Û•+µssØ]^~} qpéö°É* óò³OÕüåÈ?2<Ýigù¹o$‹¤y¹Ü[}bîK—¸Ž×á ÌŠQ8HG%Tì»?´å ó81“„ýPçBªÿù†ÛÕü…ù/ç{Ì‘ù¯óúêËÌ3鱨è:p *#G2Íõ™Li3UiF _‘åÐwl`ÇÃу#r? ¡ÏötL`I¹>…ÎYµØ«±WžyÓó[òÛGÔ.<‡­yŠÂÏÌ—ð< g} ·±µÌDF/ «’I’Ÿpsk£ì½Dâ3FÄcc·ózüa)ŽO—¼»åWÿœ`üÍÐõ¿Ì‹}S@Ôí¤KmnÅ'–=*ñÇïDHô,P&©ÈÆÜ“pË–£Uü«¦”0Dý&½CÏñÏŸ{@w×¾AóÞùåØüÏ¡Gq›,×Eõ¸L.â sPj °c¸ pšý ôÙ<9ÕÐåæäÆV-“æ]Š»`¿›ß—6šFÔ<³?¿+õ&å¿Ý±bb{+T£ÿ’Ç6]“ÚIœd¹sÆÅ>)ò׿'ç…î•ä–ƒyú*])îmî$åõkèaŽB²A%Ã1eX˜@=6Ü gwÚ:} ÖeBUæ éCÏÏdè´¹u3±ógþNü…òÞˆËæVý=«“Í„À‹Es¹¤d’çÄÈH?Ê3†íomuî8u/«çÓáó{ÎÎö[VOÞKý˯Çäõ˜ãŽÖ(‘c‰TDUTl`3Œ”‰6y½8 J®ñ:Fæ)HI Qˆ j=ñ‰‚E¬#gÉVžuüÊÐüé¨êW÷ÓjwúJº®Ÿ,„C%¢J#›„J*ƒÅª‹·Ú¥ÏhËÙŸŸIB"Ë\q*±góæ|¹ÓæûGY‹Q)JFGÔ:Uï·ê÷³ÌoËÞyÕ-5K9ºf§y5¥ôMÇœHóZ$±H»ñ`$oÀ¨sEØLúzÈHT¡(ùí:#ËoÐí{cS‹W=4ân2‘ËxØ?4_äÔ¾\ó'™?+µŸ‹Œ’Íj®> cÓ–ƒÂH¸8ö)ö¿Ôéðë±÷|¯qþ–V}›™Á›.’}û~Ÿ˜¢·òr¾Sóÿš¿.ow·”¼–‹&áÄñÛÆHd ÕÉ{Uþ¢Á¬1Ïãú¤+âgÿÁõYtÒåÓáúâW~Wùþ¼ñä0i· 勯1Û^K$nÖò¼k$.Â…ˆ*êE~ÈÈûEÛ#MªÃ1âÇrßÔ¢>câžÅìÉŸHŸ\¸óaø2_ÊʽCÉPyŠÛ^šÞê\Eo€±oB/YX¿5æ$¯LÕ{Mí$5²ÂqŽÎýç‡î§aØ]‡=(È2DöÛ»¾Ù/’¿.4¯%è7Þ_†ê{û=E®ÅÁ@¤É‰ø*( eµ'5]¯ÛÙu¹£”ÄDÕy~nó»"\RÆ —;÷S¬?*?.tÚ}_˶OùiV»ÿ¨–“þÓkòsÍ/‡§ýÍ..ÂÒC–1ñßï¶Ugac§EèiöÑZAZúPF±%zWŠ3O—4òœŒ™·g`* äˆÊ™»v*ìUØ«±Wþqy;_ó¿–ít Cv·S¬ò4|Õ"‘© Àîýé?²½«ƒC¨–L·F<"…õ©Ñ{AÙùuXD1ÖÆ÷÷Q”¼¼!°7šU•Õí„Á ÜÖÑK*ˆP"ñ‘×¥6ÍDûS=ˆrŒdI H¿•»è1Tx¡b²íæ¡æÿ#ywÏqZkÖìæÝ™í®"sЖ7ØÐTFÃÃ,ì¾ØÏ¡™–#Ϙ;‚ô;3ª d¹¡Œéÿ’þ^Ó<Ï¥ùšÖöòIôÐk Ô¿Xõ˜+…vwÜXtÛnNm³ûYŸ.žx%>±\º|>×]‹ÙÜXóC(”®=ûß5¾Hü½Öt/=ù›ÍúäÖó¶ª\X˜ؤsLdd`ê´*5®ØíÌYôXtøU÷][+Ù½““«.l„>Uæoõ1OÎOËWúݦ‰æHoô9ìciô4E–+ñb‚8Ï&@@«Xt¦çsì–ŸQ ²á0Ê$jx‰£[ïg‘òäC¬ö‹6äÊ%qÉÒýÝßh)•ÿ3|ÇkùeæO2ÝÃÚ½¬ÖövZÇ ª÷2Ja§!@v…hAa¾ÀæOhû=§—háÃD$ ¥ ú@ßÓÝÄ{¼ÈhÑvÎhè²å •s½·ïáa+æZÇFý9wæŸ0XùÝŠÝÛ[^,§O½‚GDU, úd8.¡;JßžÎÅ“/…¥ƒé&5Ç;þ;lo«§ÜÇâ¹#—˜ød<¾ï³èüʱÒ/tŸ;yŠ'C¨{kuÞi¾×¦®@¥8«}‘žl=ŸžmvM6ô™n{‡Ø=ïp{b8ôÏ}@l;ÏwÞŸh^sòǘý$Ò5Kyîå….>¤%ArˆëË㊼î)¶ku“¨ÓYÉ5Å^ŸŸ'7MÚ8s×$]^ÿ%Þjóv…äÍ0êºõÇ£`‘F£”²¹ý˜Ó©#©ð;7²ók2xx…Ÿ°{ÊuÚüZhqä4>ÓîW»°Ð¼Û¤Dº…¤Z†•yM\DwY’°+PõØŒ¯|ÚL§‚F‰­w»ŸÜÏ&,ZŒcˆ F[î=¯þFêº÷ø‹ò³UšÃPŠ­‹Ìcz«Åwù%Ø÷líô^ØbÔCÁ×ã‰þ*¿œL~O'­ö^XåâidAþmýÇõüØ«æWÍ^~Ð-¿:¤’ÇMÒJCyÕž:ÇÈÈÎÑ'ûø…WxÇÙÝFÃ:=7fbÒhržÌRɼ}@ïË™þnä×›ÍçÏ<šˆÇUqç·ãŸxèû[KÔ4ÝV ýâ­6eÞ{wW‰”l8•Ûn”íŸ>êpdÅ3 €ÆC˜<Þ÷HÎ ÄØòEå ŽÅ]аÿ̯Ëí7ó#ËRhW²}ZåO§ß*ókyÔŽJA*Ë]Ǹ7¾ÎöîNÌÔ ±C”£Þ?_qýhhc©ÇÀv=qyß-ÿ;ü™¬Ûi¾t’ßËÍ: ÖçUõíЂ£““¸eR KÐûgSÛ™;[†SÒƒLȨT÷&[ްÞún³Cfˆåß}»¾h]gó·Gó̶Ú?’<Í7”uˆ®‰‚ÿU³êWà+(ˆ·)$5eAò®]¤ö;6€K&«Ô@ÇxÂGŠ}/üÒXeíˆg"8§á›ç!±òëö³ŸÊ?ÌKï<Øj–:å´vÞeòõÏÔµAnko+U•dŽ¤Ò¥SÒ£cAÎûUØÐNÄL±f/˜å±ùÀv—¯–xÈHT h÷"-?6ü¯ù‚ÿ—–>µÎ£?;ØSÔ¶Y⤄²Ô‚ª>&û ü5®U—ÙmN=ÖJ£~“´¨ò—Ç»oÉœ{S³ø#sßÒû™îsNÉØªKæ¿*hžtÑ.4 ~ÜOc8ª° ’«ÒÏK“†\º÷Ø—¾aòôÞS¹ó3HšŸ–Ê[ÉÞ3x—ž‘gãæj8Óçœ|4ùQéÖûQabŸù—Ì7^v‹Ëz¾±£Kå_ùÆ»fÛLµÓm¡õc~RIq0†¥Íóuû$…Ÿ“DÓiÆ8Æ^&¨ÄÈ“÷ üwíN17îf¾Y»ò]üä_–¬¿!efÐ.¬Ý|×ohÓ¾œÑª9,}S¹QÀòû!øñ®ÔÃ4»>gWõèºâü~†B¸½/®mo¬¯LâÊæ+ƒm+[Üú2,ž”èh߉lO!ƒÿ9,ôýv-6é¡ÒEÊÇêÙÛž0<«*²Ôoé´œ¨FrÝ©¬Åãøšc(q ëmÏ:ý>mЉª/U··‚Öí­bH-¡UŽbPˆˆ¢Šª«@Í,¤I³Íš¦v*ìUØ«ãÿùÊ?#_y'Íš_çg•#ôÄ“E¶ˆQr«Â9Øž0b“¦àw|íýŸÔCW§ž/"=>ï׸ýˆÇšX2Ç,9ƒøù³o.kÖ>gÑ,µÝ9«k{‘Vµ(ÝÕSòÏ3×è§¥Í,Sçø?Öôš¨çÇ‘å šf’ìUóïæÕ±ò?æF‡ù\ôëò Õ#ãÉdྌÊÀíûÈ€êNz_³?=Ùùt„ú¡¼|ºÇå/½áûz•ÖCP¦[Kî?8¥þbü¡Ö4¯:hú¯’­ÛPòÅÕä:„0£NЬ‰#,@àT| ZÓáê9:j1eÒdÇ©<czËb>}ããîÇÕöLz˜OâÆd%ý^_gwÉëŸåŽ£ùcçè拾»³HÄ–Ð"ÿ¤I$ îÕØÆ}6wÎ3Oí ñèe¤1'sÐáïÜy½>nÆŒõQÔqGA×ð6déåÍ 5™<ºt§%[P1«OEOLsR¿÷lÔ~cˆaã<øonwËÞìF“ÉâpŽ>þ½Éžb9Å]Š u kGÒW–«¨[X¯^W3Çûäa™4™rÿw KÜ ûšrê1ãúä#ï 1kïÍÿË}>¾·˜ ŽÖË-Í~Fqøæã²Ý¡“–"=õ¼‡[—·ôpç|,ýÌzïþròöÞ¾×®éÓѶ¿ò9ãÍž/auÒçÃ|¿P.Ok4‘åÄ}Ãõ”Ïÿ91å•?èÚ5ü‚§y íØü.ù›øj:äˆùŸÐY{e‡¤%ö~´ÎNiá.LW±7h ãÓ9xÿäÿÕ‡ú_ÚÔ}³‡ú™ùþÅ¿ô3¶]ü·/ý&¯ýRÂàw/õaþ—þ<¿èÎêgý7ìT‹þroK$úÞ^¸AØ¥Ôn\„¿ày“¦Qþ”þ´ÇÛ8uÆ~i…¿ü䯔ŸZÒõ(‰¾š[ÈúeM³ð?Õ¦p?é‡ûÒßltçœd>_­:³üÿü·¹§­ysg_÷ý¤­Où$̾ÄëãÊ1—ºCôÓ—Ú¹’=àþ‹dzæoåþ§Akæ+ ÍÑg˜[±Þ”~¹ªÏìö»Õ†_Å÷[Ÿ‹¶t¹9dÄ×ßLžÞêÚî!5¤É<'¤‘:ºŸ¥I©ÉŽP5 Aóv0˜°l*ä;Q¹µµ½…­ï ŽâݾÔS"ȇæ¬ÉãÉ(‰ ù1œ#!RÝkË:6» \ùnîÙSJ¹Ó1B«§CÉZ0V†Ýs/IÚpg¢}`õÞýþ÷Q¢Ç—ÄG¤÷<çIü¯ó¾›qc¤]y–ÛVò5“ÿÇ2þÍei ©ˆ«Ø)¢þòŠw¶u¯h´yc,‘Ã,yä>¨Ê·ïý~ûÝÅÔÀÆ(ž(ÿ £{w~ üÁÓeó§æO—ÿ-,­ÞÏËš4 $Áchã„Vs¥8¬j‘!è‘›>ÃÔ gåÖȉdÈvë¿KøÜ“ƒÚ¸N«YKP€û<¾›4Ö,ÿ-?(Q¼ÓŸ¦¨ð=¥¬.æ[ª•n(®ÍCP9IØëÓ4:\½¡ÚçÀ32ñyGŸ:û¶ÔcÑöoïDjU@gñÞ“ùGÉš¯šuSù“ùž¡$@dÒtYÇ, _ˆ<¨û ·úÍ¿LîÔílZ\_“ÐÿŸ1ÎG¸ú=ÃgAÙÓÔOóZ¯óbyDyþ<ËÑt:ùK^½};GÖm/o`†eg`½JÚ¹Zç/ªìVqäÇ(ǼÅ|]öÑÁš\0˜‘÷§Ù®sR/3ù?˾p²6:ý’\ Ò˜|3Â|c‘~!òè{ƒ›Îí\ú9ñb•yt>ðáë{?¦<9#x÷ŠÜùSó+òNö]sÈ—²j¾Y¯©wdêdþZ-Ԋлb¡øŒîãÚ=ŸÛpµQËÒ\¿ÒËýì¶÷¼V§²µ]žLðž8u¬~‘ö=›òÓó·Êÿ˜h–$+Ì”øôÉÜTRmäØH=¨xS|óÿh½ŽÔöq2þóó‡OëŸw›²ìîØÇ¨Ûé—wêïznrÝØ«±T6£akªé÷z]òz¶W°ËmsØybÉ5(G¼nd€œLO")ó7¼‡ùƒä*'4;[_4ùSX»d²šK×ÚtÓ8ãY„BÄí)SM÷]†zçcöÞƒ]ªüÞYKlqõ?DÀò«5üßw7’Öh³àÅàÀ ÂGm·ã¿îCjòþUè0þQùŽ¥ù®º¶½kG6òJ¼}i¸e^çì-_bß Ø0ÖÎ{GWèÓbþî2êñ+ùš!¼'3¤€Óáß$¾¢:yÆÜÞ¹ùKùw ~XØ-ÍݼþtÔU[Q—Õ_Põe†b‚øÒ¬w=€áý©íüý©>(ÆC>‘[{äyYû9w“»ì½4±¢GçúƒÓówÅ]Ф>pò~…ç}_·õ­%ø¢•h&‚PYbbZüB$f×±ûc7gçqúŽ’ÅÄÖèᨄ¿±â?•ÿ˜>aÿœwó‰ü·üÀ•§òôœôý@1Zú­µÌ5©ôÉ?¿ˆ}–« šóöŒøðvÖ˜jtÿÞc¯õOŸqê>Ï>Ï‚zl†üy¾¿¿Ò|³«yuôÍBÒÎëʲۯ+i&²6Ê¡ö¨”Ž”g ¹!“Š$‰ßÆÔOüåù­åæo!Î=iÖºýݶŸ®yÞŠF­s'¦‹Å —ïXô cµÞ²òL ÚÉ Ž?w—èù÷8ò˜åC§ézßüã'Ÿ¼¡åÝ;]_0ùÏ·‰o¬XMk^-Ñ’+qs©i)Ê`UKhÃry L™aÚ¸2NPà–!é7µnk»£ 8ó}=«y›ËÚ Îe­jvÖz¼ßVÓ!¹™#{™¶ø# ENà|ÈHÎ;›&A#’",×Fâ@H¿3¿.´_Í)]ù_Xÿ{az4–—HŽdéâC üJHÌžÍí é2Œ‘øŽñ܉ÆÅ<_þqwó[Zü³óuÏüãÇæ{›sÁ‡ËWr±áć’Û+µ+ À!íÏó?¶û“U øÆHÀœh¾Ú̆Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å^]ù÷ùŦþLyã_—„úýákO/éìkëÝ•¯6ƒéÄ>9Éz°Å >uÿœdü­Ô§šãó¯ÏÅï<ׯ´—:[Ýo*EsS%ÛW£Ì ƒhúlÛyçµ]±Ç/aõyžï‡ßîs0ã­ßMgÞìUتòöÖÆ5{™â„Êë i!$Òl‘©n¬Ç`ù(@ËW…ySþr VƒÌÚŸåÿæ~–üê%›ô–f‡M½W,má{’²q®Ê³(*þ¾Òê»s`‘ž?âþpï5ú:{š†Mè¼ãówÌ›z—“uO*þo~_ìù5Ö•æo/òš++ˆjb–EV•xLmÍ£< Ú¹¶ì>’9£“Mš#õ{½ýwa2jˆ{_üã¯æOü¬Ë‹+‹Ù½O0èôÓu~F®òD£Òœ×sêÇF'ùùÙÏ{AÙߕԦ[Çõ|ÙM¸åaë9£fìU%ó™ ò–5O3ÜÚÜ^Á¥Û½ËÚÙÆež@•GnìÇec°Ì&œæÉ`ÄktHз˜ùó¿LüÜÓµ/þ^Zߦ¾ú ÍÒjCÂ×OÔ¦£‚ÚYIÔñ+„±ëMÆ~Å–ŽQžb8xÀ®²S]ÌN.O’t­CËsiñyͺ4ß”c–/ÊÐiwj^a×ff¡ÔnQUÄ(üCÂ%V+ð§lîrãÈ%ÇŽDÇ'9ñCú#¿Î½î8#«î-ù2Û^·ò¯¿04;#ù§YßE"Ù¼ÇÔô• 0¬U¢–åŹ"¹ç:aÆrbÃ#áHüüþ?ÚåÝÍŸf±“±Wb®Å]Š»J¼ÏåÍ/ÍÞ_Ô|µ­Eëiz¤mp‚œ€q³©5£)£)ì@9v›Q,9#8ó‰´añ/彯©ùWù…«þPù¡éÜ1Óg5ò N•è·q vj¤çQíVŠ:í,u¸†ñ¯wütýEì·ixY ¥Ëúß·ï{ÎyƒèNÅRígAѼÃo¦·eý¬2¬ñÃ:óA"‚¡¸ŽÌEei5¹tò2Å#EXîhÔiqædˆ÷GEpF‹1¨Hã@UTP*°t);’Ý€(r_‘JQÕtÍÜÝê×°XÚŽ³\Ê‘%|*ä åø4Ù3K‡LpÕ›<1‹œ„G™§škßó^DÒ¹G§5Ʊp*Õ£ôá¨ñ’n;{ª¶uz/aõ¹wcfÏÈ_ÚCÏj½«ÒãÚ73åËækÎ/Í?4íäÿ,‹[Y>ÅËE%Á¾“Ó‡ï\ßãöC³ôÿßå2=Ö#ö —ÚëÇmö†«ûŒ4;蟴ÔPíäïί3ü^bó+X@ÿÞ@—,½â«0±ø,̆£²ôßÝa=õúee¶=ƒÚšïrðëýÛíDXÿÎ>èêÞ¦¯¬Ý]¹5A#‚§Ü¿ªry=©ÉÊß¿êrðû ˆo“$¥î¡÷ñ2[/ɯËûJÓžéÇG¸¸˜û}”eS÷f¿'´©{€v¸}’ÐÜ ½äþ‚{mä_&ZSÐÐ,íb‘…<Á9‡>ÓÔKžI|Ë²ÇØºHrÅô ýé¤:F“l)oao¥)¦Þ˜òÔd—9ñrá¥Å¦|-UQB  £` Pòʉ¶ð)¼ Y$0ÍA4k 9¨j}ù!"91”æ-?—´  EΕg05¨’Ú¯.¿iO\º:¼±å9‰q§ Á?«O¾!(ºü¸ò-å}mÑkþùÐÿ“%s&¯©,‡ã¿ÞáeöE>x£ð÷S¾üŽòØ?WŠêÄžŸW¹f§üfv?i5QæD½ãõS¬ÍìnŠ|„£î—üU±éÿ!®leúÏ–üÉ5¤ãìz‘²7·ïau#þ3G´±˜¬¸„‡ã¡¯'±ðæ ùÒè\¶ßóVÞÏRý7j›²¼±Ý–Çëaeÿ5ÌyéûSõCÃ>W÷>Ÿ›D´±¦úeâx—ûª?$]§ü䘴YVÓÏWx$èÒÀ%¶jâ+€Á¶ðp37°¸rŽ-6o©}±ýL#íF|'‡Q„ƒñØ[ÐtÎËÝŒiª >å¿ÝŠýXŠÿÅ„˜¾çÎc[ìž»O¹‡ìú¾Çu¥ö‹I›øøOt¶ûy}¬ö9#š5–'Y"qTu!•îØç;(hów@‚,.È¥®*X5  MÀ4¨¯Ñ†Ö˜*þYÙÝyê:ë·²jÎ?DØÜ*ˆ¬ŠÔìÍÄî› “Vø³¡>ÐÎ:1¦Åùòåøëò6tñ£-IÏ’FÍ”?^ìwþr&ÿS´ò<YKKËÈá¿t¯÷B7uF§ì³(¯Êógì&sÖ.q‰1÷Øßäà{[–qÓFTX›<¿ùyå_$hÞiòn¤©æÈ^ÒkK¨î̳\ɱ¼™WŽä€ ²zçGÙšív«Y“¦º"@Ž*]oÞ{ä×i4š}42à—ïosß·ìòz瑵{ý È:v«ù‰¬F—7 %®‘2G(å Lƅ߈äkñoNÙÅvÆ–õ³Ç£ÆhmQ³¸æ|…ü§³3Ë–3ÔÏsÖ[{‡™ûYf¯èž`€Üèš…¾¡ š;[ʲp'³5SìsMªÑfÓˇ, ˜§g§ÕcÌ/„‡‘Ls½äÿ˜_’zW™õ¯-2èþdSꆎ©oq Ü º=wõuê ß;.Ãö¿.˜xy¿y—˜¤yƒÌö·³xóúñz'öÕï ‘<õï(jCÉ›ÐËÄDpë.¥¥Eè¦~5õPö•*|yuöß±X5˜ÿ3ÙÄoÎ?Íþiþ‰øS¤Òö¶]<ü-H Ž¿¯¼y¾µº¶½¶ŠòÎd¸´VHg‰ƒÇ"0¨ee¨ Žã<£&)c‘Œs˜zxÈHX6r Š»yDß—šå~Ÿç??yvnüÇ%­í圗lnÔúFFT-RÀ½Y™ªÄlOR{Xvö~ÕɦÒf"8Ä£píŽoðØV×½:S †–92ÃyQ"÷§Î:^ƒi„>süÅŠëQÑ|Ïíiæ[+‰d¸Óµ(¤‘i˜¨4jíöz0ÏVÔë¥)6ŒÆÀEâN§¸oÓãÌ<®<DeÍf3º;Æ^o¥¿!üɬkÿ–¶:‡˜åi'†il὜üWÆá#fcNG‘ôëÔ•Þ§<“ÛnÎŧíC @‘ˆþEŸø¯+îzÎÅÔO&œ÷Õ÷þ9=?8÷pìUØ«üÆü¾Ò?1¼».©Üu“M¿ Y-gÛâ*ÔâëÜxßû;Ûù{38Éâv”œ?XèEºîÒìøêqðžc‘ütyßä接är_ÈŸÍ:, íi¢]\Ñ¡_V¼m™¤”û†>!:Öû_EY„kt¦Ákïòþ'1–)sCßo¿%¿.®ü‹yùyo¤%‡—oÎÂÐð.yr[+rbêvRõ~qÛ9ÈvÆ gŒ®C¿•w{¿·›.TùÛÌ>\ò?äšlN’º§ææýÌkþ°¾ ööJü¢ŠfX—”Œ(ÁXôý›:½>£?hâ<\8p¨Žg¼y~9´"{Ë3òݾ—¯åÍ;þr3Z²Ö?3ouA¨ù_H þ¦‹,ꌱÊöαð‘âŒG©NcáçRF¿Q)NZ(˜â©Ÿçü÷ÚÍžuÜÈK›é\ä[žÿ9+ù40¼¼¾fòì$yãAC%±‹i/-P—kzË©øá÷ªþÖÝ/³}±ùlœ>‰}‡¿õþƬ°°Î?ç¿=Gæß”¯ÎŸ|¼‰¦€÷¶ÿb;À½Éû3S£ï°uêN ÅÅ]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±T.§©ØhÚuÞ¯ªÜ%¦™a —7—Rš$PÂ¥ÝØø Å_i‹¨ÿÎZþvÝù·YŽH¿,<°Ëœ‚Šöêå¡·#qêNÃÕ¸ð_†¿c9ÿh{_ò˜ª?\¹yyþ¯7#;/±Q$XãP‘  ˆ U€:žPM¹â®Å]мßó¯òïÊÿ˜~Rú§™µS¡>U¸Óµ†œE ­ÓÒ(ÚEvXÜÁhÔ;ü,¤æÛ±»C.›-ãósãvˆ#wκÝô‰èþOÿÎLÛ1©_)~d@9¼B€+I1¼Œü"B~.ž¨¯ï«Ãz þ¾/ÙÐ÷}Í'ºOlü‹Ó¿6|¶Ú‡”|ë5¶³å 6(_Ë^fŽs$·PK¼hŸh´jƒöÈ)²‚èT¯=Ûy4¹k& c9}Q®GõýþE·#bïÉï˯4ùÎþ}ó×™­­ôñ5ç=Êo^/J ‹—`%ùUv »«ZcÚý¡‹&X±“.¼Žß‡êæ°‰—³g>ØìUóïæçüäO•¼»¬j¿—÷Z>§¨éÉÚùYÓ&ú»X-üC‡ à|OÅÅ tØWqGe{?—$#˜J17qŒ·ºïü©äfiùeæ$ó;þqz÷üA¢ê6©oªé³£%ÑPÔ‘]à©çS$|‘âzñøIUØÏ´±çâÁ¯b/¿àw0à#x¾‡ü¼ÑüÏ—ìoÿ1–ÆïÏl$k»Ë[xÕ¡IºAê.ÌcSÄ”¢üþÓr½¡›ÈF ú~ß‹tA­ù³,ÀdìUFòòÏO¶–öþâ;[8G)®'‘bŠ5ñgr3’„ eVØê¥ª^é—PÞÙK_NæÚDš'¡¡âèH?~3Ç( ù­¢2*ìUØ«±WÎó––3kþ^ƒó@—Ì~X®ÚIdÓÕ½BõÖ¬ƒÁKçWì¿hˆLàŸÑ“¿¿þ=ËäÕRÂOùgçX¼óå[mM™F§ú>¥ý›„­Oqó§lãý¡ìƒ¡Ô˜ Þ>ïÙÉõ>Æí«À'üCi{ÿo6cš7jìU‚y³ó{ÉRõ ¹¾Ú’mõM oj„OpÍ_lè»3Ù}f®ˆ -‡Ã©øK®íý6Ÿc.)wGØaqù§ù©ç×k#é¢ôâJ›Ú,JÐÖâp±ƒNȼ‡c–e»?G¾¦~$»¹ô£™§D;W´5Æ´Øøcßÿ;|·[cù#©k¤¼÷¯Íyvô/.Ò¿ÈÏ=~T ò9›?hqៈ÷WØ?[™§ö2y§)‘îÿ²?©è:/åç“t-§é0™Ö”¸œ}bZŽá¥åÄÿ«LÒê;WQ›ê™®á°û£GØ:M?ÑŒ_yÜý¿¡“ôØtÍs·v*ìUØ«±Wb®Å]Š»v*ìUØ«±WbªsÛÛÝDÐ]D“Àû4r(t?0Õ(ÌÄØ4XOf*@æÁµßÉï#ë\ž;#¦\µi-ƒzK^ߺ ÇO’ŒÜi»S‹œ¸‡ô·ûy¼ö·ÙM}Äxôvû9}Œ;þU¿æW’Üù_k‹u<¾§ÌBXûÃ1hæHùfÇ'ihu¢µ8…÷óûEH<îOfuÚCzlœC»—Ø}%5Ò?u­åt¿ÌMX']Õ´fr0JxµzòGÀf£Yì>,£IÝ-ÇúaËâ>,q{O—¸5XÌOxöÐ^¿å¿9ùcͰzÚ¥ÛÊHá<ëÄôqó¥3‡íÉÔi eŸCî<žŸGÚ8uñÈ¿åÍ>Íkšñ?=¯Ÿü½æ-CR¼±9ùTÒŸHãQknj=8Ô•d=%âj>ÑåB;îÆ:FB2ü¾¢Äÿœ}ç˜?ͱ嵼‡iVÒ”£ãaú{¾»¿ç»òG"óÇ!Õ­¼¹&ä›I¥‚wšapñžB1$û¹sNAvT÷5nƒ¶;lèt‡³ ¹åµŠçQå]/r|¹i»7²†«R&1øx£ÐÙ¿+<ïìiÇæîªù—óJÃËòÜÛÚÛÇd’èñß3-¤ònîŒE22”÷ …ì¾|znÍ–Q"eSáú€è~ßĹ]¿†yõ±ÆH‡ÓÅôŸíä§äÑ«Aù¿¤AiåïðÍÀµš=zÎÙ‰²¸HÖ@ÓFWnP‘Ì ë\ŸjøR켆Y|aÄ2~¡ué>|û¶Ggøƒ´ ?Ñãé<÷\¾/`±üÎòÿšoü¥É[ëyÜ8ÙÝ"ÉZU âyR§a\áó{=©Ç¦Ž ÇÓ.ŸÅäkÍê±vÖ ç–w^ž{ù3Ñ»V;æÿ$èwÓŽŸ­Û‡eÛ]¥xþÔoúÔì{ŒÚv_kçÑdãÄ}ã¡÷þ-À×ön-T8rqê=ÏÓ5¿>α廞SXp‘*Y Ž4>jLîµz½tqá8”x2§·ëëÈw‡Iü•‹”øˆÇFây<¢dó‡ç¬‰åï!Z'—-t"´3EIèÒ˜•‹Ê~Ð@ ÔššžÒIØ#ÆÕËÆÕeÜÖæ:¾Qé{qt(iˆË¯ôb¡Ëñß÷=_òsó;VóN¡«ù'ÌÖÑ'˜|¸)/-dy!¹Ky>¬ìÍ#9/ÈË—ÇZÐgío³x´˜ñê°áæß†@!Ä9VÕÒ¶ów=“Ú2Ë)b˜õC¨ë[~;Þ»œ3¼v*ìUåß_•P~bh\ÓÔGæ½1´é¶_]Ämœø1Ýì·±lí}ö övn ‡÷3>¯èŸçÓåît}³Ù˜‡~¸ý¾_©8ÿœiüê›Îvy Î4^zÐÐÆ­qU–úÞÁ‹rßÖˆü2ƒ¹ÿ;h»a#6-ñÏ»¡? ôþÇ‹Ç>‡›Õüý k:ž‡yäÓieçèí%·Ñu‹«t’HŒ­$jì Pái]À4$f“Cž˜lã¿TAæÎC»›äßÌ/ þ]þTùnå|Í®^ù—óïU+qcwewp.-.ä ¬´W…jj¼Ÿ°ö{»Q«È<8ˆiãÌ(ÇvëD¢"<ßU~QŸ77å·—žùÿЍú÷¬IžœÛÑ3rßÕô¸zµßk¾q]­á~b~Ñ{~šò¾^MðºÝšf½“ä?Î.ë¿™Úgç·"¦—wrFµ`µ‹‰ªfŽN#h®–»Óá“~¼3Ò=–í Ϫ#o8þϹÅÍ«íß#ùËDüÁò¦•ç.ÍëiZ¬"h«Nq¸%dŠ@:ü¾Ñ|íy£]ü‚ó¡ùùe¤pÌ&@³hâX ¶Ïo8õ~±ˆj@*À Àí5ù±ãÅ d/Yó·ÞÆÞûý," ðó¬4 KòÆ‹cåým¥iÐ¥½¬ –âˆ;“RIêIêsˆÏžYfg#fGw Lr¥v*ò>~}~SygQºòn¿¯M£"5µóé©pïdeR¤´öàð‘k_€–SÛ7zÃÕeˆË æ.·øŸc dg‰y=5Èß0 þØyãò_óã‹OÕ­ úä’“Ó‰$D›<^-ù/Åá“:-YŽ¿>|<ÁÛñïù÷µGÓæ è_Ë?Ê.~U>¶<·sxözÅÂΖW3´Z"-q/C¹?UŠñíSËv—kdÕðñqÀæÝ½5lŠ õ=_JÑmþ·¬_[éö…‚ îæŽù‹ÊB¢§Ã'æj “庒ùþr‹ÍÖÞhòY׬Ÿ_ü¶šÖîò.¾¯g¨j|Y õ®#`=4åT6ÊÍJԌ콙Ó‹/àË`]YŒzÐïæÑ”î;›ÿœl{/)yÆïÉš5ÂkÓjöŸ¥õÛPúƃ¡ÏéZÂi/­.è'­Óo‹%öˆØFYÃ!SŸy<¨yWÞ¸¶4ú¯8¦÷b®Å]Ьš®"’ ãY`•Y%‰Ô2:0£+)Ø‚6 áƒa_ kLßóœóinY<…æ:Ii#r)´ŽxTšÕ­œ”mÉày~ÐÎã[„vÇgñï±}ýGùÃí÷;ÃíÊj7>‰ìAø}ÌÛοœ~Qòp’ØOúSY^–Œð–]Õ>[·ù9ÅöG²š­eJ¸!üé~ÌýÞomÚ>ÐéôÛ_»‡é=>ÿ'–Mù»ù·¼múÊòý¥íâ’3î+,Õì+á¾ÏìÞËéâäûŸÕ½ÑÃiv¦ã÷xÏÀÓ/¹–ùgògÊZIï¢:ÅúЙnÀôCå€|4ÿ_–bë=¡Ï—hžåÏçú©é;;Ù-.žŒÇ‰/érÿKËçoCDHÑcBF E@Í7¹z€À—b®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®ÅP𖕦ëÍgªÚEyjÛ˜§Eu¯JŽCcî2Ü9çŒñ@|š5ly£Ã’"CÍåšÿäuªÏúOÉZ„šN£ç /#˜Õ»zs)õçñgG¦öŒ‘Áž"q<ÿhä~Ç×û ãÓHÂC¡åð<ÇÚ†Ó6¿0|u—ù‹¦É¨iäðŽøYˆÒeýÜ»vj7‹f.¯ÙM¶&zIpK»§Ëœ~y:ÈöγC. T ÿ¨ò—Þö¿+yÛË^rµúÎ|“²€f¶o‚âß¼‰¾!¿~‡±Ï>í.ÇÔhåÖ5Üzqü«ÑvŽLo¯Ë¨÷†AšÇ5y³É[ó­¢Zy‚ÐMè’mîŒsÂ[¯]è{©¨>³ìÎ×Ôh¤eŠU|Ç0}ãð\wfáÕF² ®G¨a~o±Ô-.ΑäKKËé™ä·†èÒy¬bºnR:ð·o³E cSÐfû²ócí-‰ª”b*Èä$cËŸ—?-F¿ô:N 8”+æc|ÞwæOË¿*y òÈÜùž3?ž5>?T++††v!Š*«q+ÿxÄž‡uΟAÛºhpà5‚öæ;ûìžC»âèu“ƒI¢¼»å—-ùÙ×û¥ùg¨?–ÿ.ôVó¾§ „Ó+µ©Ô.#……»1hP´¬*B@ìÈ{C€juù?- 9ð‚wêvóû^“±²øHxò'—­ºsòzíž¡n—v]ZH+ðH²ÆÃü–BAÎk.㑌Á‰¢ï1äŒÅÄ‚;ÂÍKM°Ö,gÓuKt»°¹^A*òV~ðwnã%§ÔO ÄàLd9ŒØa’&3GÏúÇ—¼Ýù®7›ü•+ÞyNfQ}e)fUBM"¸Uꢿ»˜nÇü¯HÓkt½½‡òú‘Ô}2||ûã×îàuÝ››³gâáßQÝäAüE~_þah˜º0ÕtY8Ͼ°ZÖR+Å€ê§~.6o@òžÝìý››ÃÊ6?LºH~9ŽŽ÷C¯†¦QøŽæYšG5ت×D•9žÂì/z†uèɹæO¬{ í rÃòľ‚Ü~˜ü»žC·û2ó¿_ë}!ùCùŸ¥þky>ÛÌ6a`Ô£¥¾¯§†©¶»P ]ø7Ú»ppv·fËG˜ÀòþÞ?Ý 'Äwù‡}ùcå­SÏÞ{ò­µïç.…§G5ÊI²›&>œécuô¹• ²îBïJµv½Ÿ NXáÅ‘‚rùõ®þŸ˜J…‘Íä3è¾yò—å¶“ÿ9æ5Þ¡¯Ï5¥ÕΕ<ò=µÌw3¬fÒ¦R¨þò>X8›ØæÁ›Q-‚E‹­Å|¾GõµÑŠß`ù7Ο<»gæŸ.LÓé7¡ý&t1º´ncut;‚¬¤g¬ÒOO㘢ˆÊÅ¢|ËåÝ'ͺ¡å­r¬iZœ-osCÅ· §³)‘»0!¦ÔOA81*E¾fÿœwóŽ­ùù·¨þFùÚà-kw´[É’îZ iГ@—*ni QÙ³Ù;;]Vä_°õHQ}Ý™­nÅ]Š»v*ìUØ«±Wb®Å]Š»v*ìUçß?šååî§ç ¾_"ý[G³riu¨L£ƒÄP»Ðý…nø¤Ì_óŠß—šÑÔ:¼ä^ëÌžc’vÓfŸy=)¤&âèÔlÓ=Uz|ÓgÏ<ö·µxåà@í«ßÝðûýÎfu};œ[{±Wb¨ ròÿOѯﴫÔõ;{ye³Ó‘Ò6¹™”ˆ<„*òj “–a„e0$xA;žå/‡<•ù±aäëÏ=ùçÍÖ÷WŸZ„Íc¥é×v²,VÂj%µ+é£`§‚ª'Újz>³²¥œbÅŒ§ÉŸö÷÷Ù.,gVO7Òº_å|ÿ˜Ÿ•ú>‘ùáj¾húÍ{km{bdÝK¼Uâ%Û‹7PÔ©ärö˜Óje-/¦ÜÁøww7XÝ”þZ~VySò§F—Fò´s¹“Ö¼½»‘e¹¸p(¾£"¢ÑFʪ ™'0»G´òêçÅ’¶ä Ê0äÍ3^ÉØ«Ö?2¼££ùÃJòΡO5ëA¥œhdô”Fî¯1 n(&§Â›ævÎË<2Ì¢<Ïêbd.Ÿ ùSÍ~Tü¶òÿ?.ÿ5¢Ó ŽO!(õH’F yr_‹¯wªÒåÕdÅ›OG­p×=¹rÚ»“Ž‚7}/ÿ8íåkÊ”ú&“æHÚ-L´÷¢ÒPyÚ-ÌŒé º°SV‹œ‡´¸fÕJPå°¾úoÆ(=W4¬ÝŠ u=kIÑÍšjw°ÚI¨\Ge`“HÜ]Kö"ŒËtf<3ð‚hYòêKäkë­+ó?ó«SÐ?ç!?-Zh6RÅ¡é^k[)KNd§(š&áψØq+Ô#-&Ž3ÑúÌϪUg—*÷ûëíqùËÔœÎ;è:/˜o0|ƒ,+æ¯Ê-6ý@ŸQŒM Nd&J32S³mÏ|h3ÏØ4‡ª»¶çøû“Œ]Ž¥<³äï+y2ÎK*éºM¬­êL–±,fG‘‡ÄÄ ‡"s‘Ôêòç7’FG͸DIÞc¥Ø«±Wb¬SÏŸ™Oü¶ÒŽ«æÍE-Uƒ}ZÑh÷WL¿³ òos²Ú#3t=›U.q¿>ƒÞXÊ@s|]ù“ù…çùÉF×NÑ4(´ï*éS<–·SŽR©qÁškŠPrZF }ùPÞè´˜;&&SÎCýôŸ±ÊÐv^£]*Ç¿œyè§ÞOüŸòß–‚]ß ÕµaCëNƒÑ¿â¸FÇöš§Â™§×öþlûGÑ.ú7e{)§ÓT§ûÉ÷žCÜ?[Ñ:l:f‰ê]Š»v*ìUØ«±Wb¬ÍŸ›š”uI´kËKÉïáÍé$B"$@âŒÒßùsw¡ì,ºˆ ‚>ûûžgµ=©Á£ÊqJ22Õ[üCoÏ›ë÷ht,Ks îfyV´¬qDâY³ÌFòeáúItÇÛYä5‹—ÆþÀ?KÖô+ë­KF°¿¾¶kKÛˆ#’æÕÑ‘¢•”s^/ñ Ò¹ÌjqÆ%›ì|ž×EšYpÂs2 Xî=y¦C”ìUØ«±Wb®Å]Š»v*ìUØ«±Wbª–Vz´–wðGsi(ã$2¨taîlž<’≢òá†H˜Ì м—Ì“ÙÝ~ü½½“MÔá&Hì̬ƒ—„3ÉkàÕÄ é´¾Ð ÇÃÔÄN'­}ã«Äv²2ñ4’àþûOÌ"ü©ùåªh·£ËŸšrZÝFB~“X¸°MŠ?ïÈ¿à{æ§µ=ŒÇ–>.ŠV?›îOè—ÍÃÑûG“ ü-\LHþ*ûÇé'¹XßYjv‘_i÷ÝYΡážާ¸eÛ<ï6 â‘„ÁŒ‡0^ÃHÎ"Q6PˆÊ™°o3þXi>kó^•æmRæibÓ—‹éoG¶—.”ìüF®7ä(6·³½¢Ë¤ÓO"Ÿñï÷í˹Ók{£<2Ìšðô?޽ïóF‘æ8þgyŠC :•×—d­|½tïÖ¬#?f¬¿²C‘Q^]úó³µX4}„Y€Ì äxf{þï*ø¼–·]N·!¡#”Xù}ÿEù-¨¬Ÿ˜:õ——,®tß)½¢Íq¥Ý3?Õ/TÆ…AbH<Œk¹Q¿MµžÖà#CŠY¥åâ¡(ÿwý?{ìîkÕäŽ(˜ã«1=%·íø=ÃIÖôv)§Ñï"¼ŠÞi-¦h[Ib4e?ÃÄn6Ï>Ôèòà d‰‰ }ÅìpjqåÂB@ø£eŠ9ãxfE’¤‘¸ ¬¬(UØ‚:Œ¢2166!ºQQäù÷Î>I×ÿ)u¥üÂü¸‘ÓK¹j¤1“VG_Û€÷®éÖ½ô®Ëíl¯‡òzÐ8Ó.óÞ;§÷ý‡‚í^ÈÉ¡Ÿ§úzŽïøïÜ÷ïËoÌó'DŽœDŒSRÓ]’ÚB>ŽHÔ<›û@òÿh}žÍÙ™¸'¼OÓ.’¯¼~‡oÙý¡ L8£Ï¨îfy sÝŠ»|ãæk{ïÊ¿ÎkïÌÍgHŸVò†§©[Æ&}>IR8ªj@R p^D@IÛ=[³²Cµ»":Y<Ð?I5ÆŸ;ëêí»Êê#-&¬ç”L¡.½Ü¿âÄïôÝ_þr ó óVò…¬º'•ͼ¦©0áëEú„ʱµ$ÑxÇÈì©È޹»Á¨Åìî‚8õ2rÙ” 7¢vÚþ˜ó¹WYU¸SÇ>ÐÎeŒp¨ŸÇ3åî}%äO(yWÉz9Ñü®‘”‰ý;ëË$ó\G³Ýh~‹ÐžOÛ}«ª×eñ3ÞÿHäOóGwŸW«Ñiq`‡?}ù²ŒÓ9ŽÅVÉsFñL‹$R²Fà2²°¡ ÄÔ”&bAˆc(‚(ò|Íëê?󌟛ëšzI/åǘ›Ó»¶NL©:¼B§ymÉç?iîÔ÷^É×÷t2¡Ÿ?º]{ÁóîÓÐ.]¾™rý_²~cþ]y®ûÌð~q~L¾Ÿª]ëZrÙëš5ñF±Ö¬fDly²#‡Œ"°ieRZâvhbŽ#¦Õ\Deqçý¾E”MØb–¿ó‰òO¨·˜¿5…ºBfk‹_(iŽÂÊ&cQ꺱øGûí ®Üœî¹Ú>ÔÔx4÷Ëë—?Ç™ù1Ž÷Ôö––¶ÑYXÁµœ ±Áo ,qFŠ(@М\ædl›%½["¯ÿœ¡ü©o=y?üM¢ÂO›<²¯si.,—ãšMË-=HýÁvΗٞÕü¾n DþÃÐþƒû²ÂÃÒÿç8ÇæçåÔ-ªMÏΧa®‚~9è]ü¦U<¿ËWíLõ'‡·b‡b®Å]Š»v*ìUØ«±Wb®Å]Š»~mÎP~`jŸŸšsyGÊ­ëyoÊ+qmmñ…Š{¤!n® èAp°ÄzPrۑʲæŽ1eÆÖkqé¡Çкd•ÿó•W^U[?%þki&ÎÞÆ8­mµk(=3 1(=kTJ€>ܺ!ëœWj{,2Þ]<¬øIûëù¹Ú]t2ÄJ$J=áõ†…æ Ìúl:Ç—µ5-2îî­dYž¥I^Œ+ºÇ|áóàž)pÌŸ78HIŽT—b®Å^kù­ù!äßÍ‹>Z¤FÃÌQ/-vÕGÖ#¦ê² „©_ÙnŸ²W®mû/¶³hϧxõ‰åû ãUü›òßæ?•|½u£~bëQks[\˜´{”å$¿REZYžŒÅEaU§ÚjŠGµõ|ٰdžǫßä»ÑsTÍØ«±WÊ~aÖ5É?Ï2yïÌ^X»ó—üÑ I¥jö1‰fµ))…y|*~K)*†ÕÚéðÃ]¡†(LBXÎàõóh'†VõÉSóÍjþpüÀ´ýc¨\†òž=¼QÜØØƒ'&w¤„Èãê6úNØÅ§Âc â zå{÷måÞÙNåꙥfìU(ԼͤiöWËqãÛHö«ik,Oq5ê)ag—ÎÝ2AËñé§)U{Ùå_Î÷y —ÈŸœ_œ^^üÄòÙÓ5ý'Pò'æ–.SÐ’þ9 ´‘µ•Q]Âò^q*óUøúçuÙ‘“M“ŠŽ\S2¯¾¿o"vqç0Gqz†¹äÿ/ÿÎQþRhÞgƒÒ°óŠ[Ÿ«__Bò*¥Å¬ÜjƽÔàu ¦Á«ÉÙ:¹c;Âùyt#Ïû DŲïùÇÿñ…¿‘Fç/.Cåëý"æk¾­ 6±^Ç ân…U%Ôq“í®Ç0{{Á9ø±LÌH^ökÊÏàreŽëwªf•›±Wb®Å_:þrÎQi>Qš_*þ_¢kÞpfôáA–ÎÒBxñ f”¸.Àõ5sªìf¥˜x™½ûOêÚÖfIሲ^¤~Zy‹Îz³yÇó^þ{íFä‡úŒ’!^ª’²ÐF‚»E)íÓ6ú®ÛÇ‚”_Õßï/kØÞÇ™VMOúOø£úÍë––v–ÑÙØÀ–Ö°Ž1C„EV€g-“$¦L¤l—бbŽ8ˆÄ@­lv*ìUØ«±Wb®ùuÅ^Kå¯Î«;›½V7ˆ4„³*¶«šfv Ë"’¡‹BÒŠ3§Ö{;(Æ ÎùòçŠìÿká)äŠÇÃʬ÷ß➯ ÑÜCð·(¥UxØt* ýÙÍJ$=ÎŽE .¤Oto§°¶’ô€¦åà¥!zdrÛ¶ùduxDw^Í2Òb”¸Ì"eßBþoü•ÿq^yó€ßæP§oŠÒäGM÷­ç]íï4Øò{¿Ù |ÿÙÝksbò?ìe_¥2Ô<Çæ$~iÅk¬j3Üù[VoÜ,îZ(c¸4k°1H({ðùæ>-&-Vˆ˜D îë_¬}®^}~}iä™8²r¾@ø“ö{Û–êûÍ£O†æa¤hj²K r8Œ›t y(4Þg |F1„pvwЧþ:²É=Wlp  \Åíéÿ@þgÜk×?š6• ^Igy%µ´p°‘„bFšcê2ßcÓ.ìhbŽŠsÉ~á³íLòí,xñHĘƷÚî[¥¾lÑ<íù]%—™-üË>¥Äâ+TÊ¡¥*d $o$Õ‚¶õ®_¡ÔéµâXŽ1råähS‹Úz=ge˜æŒÁ4nùó¢ 6ïIóæD^\ò~æ X[ýf(d°·ž êÄ%fzP ‡RFh;?²mD±“´ ³î4õ]­íÓi!š"å|Åïî`“yëó/EÓíüÕy©éZ¦•3FgÓ-Þ’“p®bPÊM@¯7¡¥suÌÑå™ÅÎ2ÄoŸê;>ÚíÆyOàjâ*Å÷×ë/jÑu[}sI²Ö-÷°¤è­ö—˜©SîÇ9F‹$ yÄÓßhõ1ÏŠ9#ÊBÝ­jqhºEö¯:—ŠÆ n«zh[ˆùÒ˜éðœ¹#üF—W©1K!åOÉàú6³ùÁçÁ}­hZŠÃom'µGŠäG1jÊk@FîwñÎÏQ§Ði8a’6Hç¹øŸØùÆ“WÚºþ,¸§B'–Ãà?kÓ¿-µß9k6 æý1­f¶NÖA ¸*HpbÚ…HûJ8Ÿ£9î×ÓiñHx2°zs¯à½³úÝ^hÌC„Ç”¹_~Þ]ãbÎ3Nô.Å]Š»v*ìU&ó'•4?5Ù-jÕfQ_JaðÍ ?µÇË¡îeé5Ùtò⯸ûÜÐìÌ:¸på÷£Ü^?&™çÿÉkÇÕ<¿;j¾SfåsÑ…ÿ‹££SýÚ›t¯òçGhû^GN‡¯Àõþ©ý¯¨ìýgdHÏãÅ×öŽŸÖçµùó+ËÞ}´å§Éõ}V5åu¦LÃÖÄ©Ø:Wö—é¦yÇm{?ŸA/Xâå!Ëö/•½/fvÆ\}&¥Ö=hófY¢v¬'Ο•¾Xó¼ñß߉¬õx”"jN#” ­ÃV¾÷ÍÿdûG¨ÐÄÂ(á–ãáø§QÚ=‰‡Tx¥q—ó‡6ù•­êV—Ð~Xù"ÍÿÄzÄ6é«j¾ˆ†[˜–1ŸUB†øõd袪;Ó£öGŽp:ÝT‡‡Œž]ˆ›¾^ÿ¦<Éߺô±©œd4¸#ë˜Rª$WÞzrEy_òÎ~F¼Ó%òß™!ú´ó#y‚ -T#"­HJÕœuE©ò©¥=£í>“] ŒØMû³Åø¼óîîmÑv£I(œYëø¾îïRÐüÑåÿ2Ç,š¡ è¸N‘µ$º|hÔaíQœ†³³³éˆ`c|¼þ<žM­ÅœŽBTšº$ˆÑÈ¡ãpU•…Ab=³  ‡(‹|ùç_'k_”ž`ó#òø˜ô´~ÓÇ#(ì £¨ëô§ìS±•Ù=©‡µð³yW¦]O˜þ˜û~wÀö·eOC“ó>ž£»þ:~Çп—¿˜7æ.µ¥Nu¤wö.ÀËk5*U©ÕOTj|CÞ ygovnÍÎqdÜ ºH~9ŽŽçA®†¦QøŽæYšG5تWæ/.éjÑî´rÜ\é×kÆHÎĺº7Ue;©™ ×åÒfŽ\G†QüQò-:ŒË á¾eÕ¼ý¥~aYþV~VÉaåÝ/M°K»+kˆã Dæà¼‘ÈÌÄò]¨I ÌÕÜz/git9t×ëÄóNsá‘ú7¡°#Èü@¿ÔeÏ ã €ˆ±æÅ´8®—ù› Üè6—:_šµíJm?óË.ÒËlnu uµ*d’P|iöOŹ×vIËÙ¹cšQž,PÓåØJ¸O ×º1å½ß>Xx5|˜ÊU’=.ùýçËÜú¿¯Î1±Ø« üÃüØòGå…Ö¼Ó¨¬wn…ít¸)-íÍ6ýÜUÛ›•_|ØöefÕʱºžƒâÆS›ä¯9~y~iþsK6“åHÛËLbc™â¬ÓFv>½ÈGX¡oFå×;þÍös–¥?ÞOÏ÷Ò\­fê5†±ÇnóËçúIùaæ‹ÿùÇ/Í=\šwºò®§²Öʧ%¬Œ¢R§ã…¸Ê›ïök¹Î’2´ößbÏC(‚x„‡?>¡ú‡oqݼWV²,ÖÓ¢Ë Ñ°d’7••†ÄjMÑ*b®Å]Š»v*ìUØ«±Wb®Å]мCþr›ókþUWåÛi·/5ùƒž™¢i$|×ý"åG_ÝFvnÎÉãŠ@|aùcåŸÐZ ÝÜ'GRã4µê‘S÷I÷GÜûf‡[ŸŽt9Í}£íÌgáL6þ¥’ë:“¯Ú›MVÙ.#߃GŒžèãu?,ÆÇ–P6 ©ÒkréåÅŽT~ÿ{±Ò?0ÿ*u&×ÿ-5iÌ‹˜Èƒöe€þîaïNC·Žefð5qàÍïýG£Ývgµ8òTrú%ßü'õ|vó} ù_ÿ9iå2´Z/Ÿã_,ù‚¢3tÄ:gèjïñB}¤øGóöÎG´ý•ˋՇ×ïâý¿“ØcÔ‚7åÞú.)bž4šY!‘CÇ"ÊÊ ‚6 Œå ÑrAµØØ«±Wb®Å]Š»v*ìUØ«â=~RyßòëÎz§æ]¿—#Õÿ/4­h꟠_QšïÔˆ ®È´Ef5.¡xÁfô]jáÔáŽ>’æþ9ô£³(o£Ü¼§ù“ä/ùÈ;OD“Éój^]ÓlṓPÔía’4»–¡íU™d BŒSFû4RÜæ«³³öpŒüAHÕDž]þï{h—D§þqkEÕt¸¼ïwu¤yQÕÌÞTÓõhî¥I˜«’Ôà!J’jTïPrÿi³Bg2È#ë#—Jý'âŒCŸsè<å›]Š»BêZ–Ÿ£Ø\jš­Ìvzu¢4×7S¸Ž(£QRÌÍ@O9NB1OE|kù£ùýæ¯ÍJ_!þS$Ö~]jÇ}«|PÏuFf~°À|>Ûý<3¼ìþÅᇩ Ë ç_¬ýƒílÒi2êòxx…Ÿ°{×ùòÏEò\KqA{®2Ò[ùìTn°©¯ïÔ÷ðÍoiöÆMQ¯¦ß­õ.Åöwˆ_Õ“ùß«»ïfù§zb®Å]Š»v*Ó*XÄxŠTÓ°®‚^=}ùÇ©ëÒÈZ<ÒkNìºE%"@99@ÜTÔÓâjùÔãö~G¢c‡Ë½á³{Y“P|=&2gÅÝßW÷•žMóv§çŸÓ_—¾v_GR– ‘&HÄ2‚‡ŒˆÈ>HhË·c\=¡ †—ƒQƒx‚<ÿDz{S&»ÄÑê¶‘z£æ+¼s Dù[Còw潎…©Ä/<½?¥é}{‹rVz]¦µ)›OÎåÔèe’&¦?›äS¤þMãí8â˜âÆj¸¼ÅoÓê}jm^…‘ŒCmHPñã)Ùh)ðç>+¹]÷êúž3 ¨Õ ¶éä­lxž‰¤jº_熡s…ÁÒîd¹3^,2ë6ÿX¤QÄUÈž¹×jsÃ'fÄ![^ûåî|ÿG¥Ë‹¶g!ÀL¬Ñ¯Tx¹òæË?8¼·»äû‹ÂU/tp×HÆ•E½Ž¿å(¨Ø Öö°âÔôžÇôÇGuí_gÇ>Ëø±ú‡é¼;ù ¥LÖZ¿™ï Is8%’̱þòF©ëÉßsâ¹í>qÅ Qå©Õû¦&3Ës3WîÜüÉûÿæL:ž¡ù¹§Úhó‹]UbµW öVUç*–Øí]ºÎìyB ‹›\g´É“µ!g†uç¹Dê~PüÙóæ¡i§ù±c³Òm“Îoéï³:¤LÌîWe®ÃÛ|¯¿C¤‰–2>ÿÓÈ6ê;+µ5óŒ5Dóô×¾Üþ6e?›^D»Öüµ¦¦K>† Cf»´–슄-z²ðZû÷Íoavœqf—ˆhO¯Ÿà»Ÿj;YôðEœ\£ßnÁæ±Aå VæËM_$j–ú³º¦¢–“Íû¾Ìñ¤Áûšñn ý󠔵ĥãÀÇøl¶«ô¼œa¤Ë(ÃòÙïÕÂNÞ`ûkÞú/CÒ-t&ÏG².Ö¶qˆ¢iHiب¿!œ&§<³d3—9Ô´zXéñGn¢+~j:þ¥ XY<ÃsWßè¦;‡ %õ¾€u"‡¹Û%¥Ã–r¼`“öéMzíF p¬Ò2ôïÖöx˜´1~Nj æ,^™¼½w(ŠKy~ «,S/FÆE¡Ýúý&«iCÃ˘ÿHýOŸkô:ŽÆÉã`•㑪?t»üˆßôõ›;ZÃä3çc¦h.#·s_ß?À‘’)Pd!ká¾s0ìéW}jü»þOk“¶"4_šªôÝyô5#yÒ3yZO2jö‰¦ÁJEvhÞ8“ÊU¢•=O´»8`Ì1@ñ_oF¾Æíyj´Ç6Hð~êÏâù2=/WÒõ«Qy¤ÞE{jvõ pàVMÁö;ælÅ.ƒæítÚ¬yãÅŽBCÉ”¹Å]Š»v*æUe*À"„Á±Â ·ùÓò–h.ÿÅ—Ò6Ÿ¬@Þ±²…ý%fò·aN þGÙ>ÝM í¸Ê>¤q@ígŸ¿›ÃöDzÄKÆÒzf7á¥î÷r÷2/ËOÎxµ¹“Ë>rQ§yÑI}(®]vâÊiéËþOBzPü9ÍûCì‘Àm?«:æcúãö޽ì;Ú”øYý9Ý×ú—ö=ƒ8g¨Xa…¦[†L謉)QÍUÈ,¡º€JŠa’5W²8EßW‡ùë[óµ×æŠybÏÌ+åm1m’ãK¸˜‚îOL1XQ‰“’Qª>•4>ØÚ={8ç–/\U 9Ä_Ní¨í¾ýÏÚzLµ¾rxQ«‰èoƒòö©¨ß~hhÚ6›maæ;)¥·óEÎ’éú>úÑ]KÍÆ/€¹W«ñèvv›;;,²NRÇ !?®Þ†ûó¯óo¦î·IžsÖ㈌âHÈaôÊ=û~.žÁuùÇùylÑ/éˆåi.Í‹>›)£Jõ¥"ïÁP{V‡8|~Êk¥»"£Å¿_!ý//›ÕOÚ$k×{ðþßw›9t†æŽEYmåR®Œ#£ A¨ ƒœø&&ÆÄ;’…Á|ïæ#\ü‡ó|^uòŠ´ÞS½Jòı(ªÇ“[Êhh§¬2ucþW¦hµ{{JtÚ²ÇxËýðÿ|:ýÞ}ÚZönoøåÌwyÐÓÞUóFç-×ÌÞµÒÖ†‚Hœ}¨äPMNÄ}ÛgŽöŸfåÑf–¢¥‘óEè´Ú˜f€œNÅ9Ì!Ø«üÎü½¶óîƒ,6Âo3[)mUu!íä ¯¨Ÿ«Ò„ŠÓíQ³}½.ÏÎ ®X¥õü{¹Xûy:îÑÐ D(m!ôžçE¢~QjysÉV¯æßÎ ¢Öך¬¼‘YÍ «Åmìî?h÷ý£J¦z\°fíŒc6ªCO£Žñ…€d##Ðw}ƒøžhN9pb&c±=ÞïÇêf_•ÞpóÇ”<È<¥ù«¥&§æ™ÅÆ“<‹ÌQ¹^.=H]¸©øC"ŠE±!Ch}¥ì³Où€ŽSÄžíˆó¢wŸ™fêóaÉáê®gn¿wà>ƒÏ0zwb®Å^ ÿ9 ä{Ô[/Í?+3[y‡Ëï—’Á´†_œWƒv…º“ûËž¡ÿîÝGC›xd¾ïëó¾ÿ{Ë{EÙöUóG坿·¨[i1@>­­‰¤–÷ñ¨2F ’O=ž5b¬;æf¿±òâÔœ0]cæ?Þj3[Ã?0¿ç,µÏ1]Iå¯É­>D.xvæ Ó°­ AÕ#_ø²nß²§|é»3Ù(Ƨ¨7ýúOêù²Ã&ypb‰‘y~“ùs5íëëÞy¾“XÖnXË:Ë+ÊÉ­e•Ï)áóξ"0ˆŒGÏoÙ~ÇÆ5=Aâ?;'¯ÝïzQEi (±Ã ‘  ª£`‹ÚãÇDF"€è/9yy<Ë¡Obúâ~úÍÎÜfA°¯ƒ ©ùä¢hºÎÛìÑ«ÓÊÄ7¿öò}ÿ8Où®þjò]Çåη9>bòˆ f’m$šI!#;ŸAÿt|Æ3!ñiăEõ6,Š»v*ìUØ«±Wb®Å]Š»~i~pùÇþW¿ç¥Ô–ÒzÞIòÅl´þ&±K¼Ÿ¼”v?Xš¤¾˜_åÌ]^oeÔöçh~WNHú¥°ý½’ç<ùc±C±V5æ_#h>gV{¸} ú|7°QeÛ§.Ì?Öú)™8uSÇË“¶ìîÙÏ¥5qþiåûo,yßósò"P4ÛÓ~LVå&Ÿ?9mBÖ¬BÔ½»wä‡zò鎯³ôºñê3ïÿkßvgoáÔmÁ/æŸÑß÷¾«ü®ÿœ‡òæjÃc Çè38´[çUw~âÞ]–QàÅFpݧìþ}-šâ‡ó‡é>ï7¢† ŽÅëY£rŠ»v*ìUØ«±Wb®Å\@"‡pzŒU a¦éÚTUÒí!²¶äÏèÛDÇÍ·f†žç'“$¦nD“æ´‰È+±Wb©G™üÑ¡y7Dºó™/RÃI³^RÏ!êOÙDQ»;•Wrrý6šyæ!d­¾!ó¯Ÿ|ëÿ9#¯¶›¦‰4oË› AXXÔµã-Ç“0û1ƒÅ>öo@Óé°vN>)z²Ëñ·póëö9Ý•Ù9{BuLÕ/Ç3äô?-ycGòžššf¥¡–V¡–g¥ ÈÛTþ¶sÍnMDø¦P÷>µÙý‹Iƒ¡öŸ2œf#žìUØ«±T‹ÍpÐ|ŸkÖ·pcõÉX!KË!Zr⣰®ä홺-]Lˆ€åÍÖö—jàÑÄK)«ä:”ÂßWÒ®îÒÚön¤nÒ‘ZCnôã'kÄò9Dôóˆ³×ǹÊǪÅ9Æ@’8ª÷®ÿsÊüóæíOUól¾JÓu¤òÞ—c­ªjìá’‹'nJvä *°$×zgIÙºcÀ3Ê$¤}1xÞÙíL™uGM ƒ b.sûvåÞ6ZMùmæo2[ùÁ´;BëÍ>Vwá-óÅ5! *&¬ÕhÀm™KPö©¦eö¾ Óø’ˆÅ“»mü¶æà{?Ú:ˆêü(ÎYñ:ŽÞ{ò÷[\ÈŸë°MÖ^ªNÀ%þÛW YÇÜ1¿Íöoô¡þ÷þ:´4±ÝŸïÿãÉßš|©æ+?Í]/Í^[°{¨'ô¥¾hÊÆŠS÷«3£”DR½MsE®Å- ±e•u÷µØv—fg‡iÃ>F_îeó‹+óß宕ç©-n®n$³¾µSÏ«sˆž\[À’FýÎk{3¶'¤?{¹í¯g±kÌe"c(íc¹3òg“tÿ$érištóOÒ›‰^vRL…U P (£1ûC´'ªŸ€+g/²;'‡„ 6o~öE˜ÕØ«Ì|ñù{æÿ6j×Wó´òÝÈ„6žÍ3(1ªÔúbˆj×\è{7µpiñ‹Çs¾ß{ÈöÏajµyMeáÅ*ôïÓË—=ÙÏ–´ O,hvz‘- ¢q20¤v%ÈÌÄœÓë5RÏä—2ô=Ÿ¡Ž— qG”Gϼ±íCòî-CÏ6¾v}A’KS !*DHWwå]ɯÙÌì]¬a¦88yÞöë3öɭލÏé¯MwyÛ6ÍCÐ;v*ìU‡yóòïJóÕ´FyÓT¶m¯QCQNå –»õ‡­v½™ÚÓÒBây‡EÛ}ƒ‹_g†qå/ÐGPóÁù%æûé-ì5¿2,Ú ³VÄ·2/OÝÃ(„¶lÞÿ¢=<”1Ôϸ|Èܼ¸ö?UˆeÍxãËy;š/óÆѼ£ èZlf=9}6§Aõx¸Ä¬ÝÉ«6ýH®Uìܼ\ù2K꯼îßí”<.,P~á·éJü×ç¯.Ú~YéÞUò½Ð–ææ`ºEVV†0ÏΠNûÞ§2t=™–ZÉeÊ(Hóîù´ûkOΆ ³ òå~dþ–W§ËåOåTwR(ÅÊz¢6-}vµE#¿¦ rsY–'´5Ô>‘þä~¿ÒîpHvOf ¬ïþ|¿PçîI¼³ùâm´ëeó…•ÃÏ+•]BÚHž1AÈ‚ã“^\ö—¬öoŠgÁ®âwü{ÜÎöˇ1gø€Ú¾{ù×Éì–7¶š•¤7ö,öw$†d5VVÜœ¦Lr„Œd(‡»Ãš9`'q<оAµØ«±Wb®ÅXæ厛ç8Zöן˜£_Ý]D›ˆÙ& 7ƒS÷fë²»fzcÂ}Pîî÷~§›íßgqëG}9#ßå/×Ì}‰'å׿¾©åÝE|‹ù“Î ˆYa´ÔîéÙVw?iÜ%ûÍ7ûAì¼3Àêt{Þæ#¯õ|ûãòÝç;/¶²iò~_W`„éòî—ö½ì@ Ô‡<؇³I¼Ñå}'ͺTúV­:ÈŽÜ¢’[vqOR#*°V÷ÙÝ£—I”dÆNÇqdäj¬8šÝ=F3 ŽÖ<żÇQ] þqûÉÀéþ‘ó6¨Æ$¼•8ú²(äYÀ'ŒQ×hÁÜž»–ηÍí¯Öx1Cz—|ö<îa‹±ôþ‘Å’}{ÿ`îþÖ+åßÊ=Ë¥ùòóêRë7WÂòóK¿‰U)Iv–EQÄ5Mx*ÕMÚwµ! écÄ!ðÆQ=GAåæNþçY¤ì Q”5áâ2³çÏ˧½ô–y[è]KM±Ö,.4½J¹°»FŠx_£+|·¸#pwvŸQ<3©DØ-y°Ç$ $,oŸô=SWÿœyóëi÷Í%×5§¯3V¢A2Óa,5¤Š>Òöû4ô}~—´Z.8ÔuÿýYtî?óÉF}•¨á;âŸãæ:÷üŸXÚÝ[^ÛCyg*Ïip‹,FÁ’HÜrVR6 ƒQž%—±ÈÆBˆ4GqzØÈH9\ƒ'b©d]Ðíu›¯1A§ÀšåêGÕøAëH‘*¥ºJN´è32züÒÃ&gÉ$G ¿ÇâÚc‚f`#Õ0hbiRfLцXä* *½9z€h+òÌQ2^Ŷ…ÚüŠ]Š´î‘£I#E™˜Ð7$“Ûš%៙ó‘XÒb¸Ð<­o™uIÕíå$ÓטâUˆÞjÖœScüÙèÞÎ{ªÍ(åÎN‚þÃù¾ó¿“Ïv‡nãÃã'o/ÛðxG–ÿ+u=H-ƼͦéÌޢء&c_f$&Û|UožÞd½£²½‘Ë–¥ŸÑïâýŸ“ÖtKÐíE¦—l–ðíˈ«9ÝŽì~yY6úC‹MqŽ}èü[±Wb¬ÏÌwŸ’ß›ºæN˜Œt©æ+«[GÒXeø.â§JºQ+ûb½²ìeòßk»3ÁÍâÄzrºëóçó~Ÿi÷öZ­…®©§L·:}ô1\Ú\Fj’Ã2 #u> ¤–2ü²òðÐü¹ÄËKíKÌÕ*„~é>…5ù“š nn9×@ù§´zÿP@úa°ý'ñÜÍ3 çÝŠ»v*â;ƒÔb–æoÊÝ#W-y£‘¥êhzc÷ÃqTdû§Üs;ºQÚ[‡¤ìïiráôäõÇíùõøüÓß$ÿÎCþfþS\C¡þ`[Kæ-©Ãq+òºD´€Ø—~Õ\×뽞ÓêÁ–#Á/³â?SÞviãÏÅ+Í<ÇêûGsë þhy'ó*Ãë¾TÔÒæTPnl$ýÕݽ{I |@Wö…Tö9Âkû36–U’5çÐü]¾<ñ–Üwãô3 Ànv*ìUØ«±Wb®Å]Š»v*ìU&óWš´/%h7ždóÚÙéVIÎYí3~Ìq¯Vv;*ާ/ÒégžbJ’7Ã^có/›ÿç%<Øn.Ìš_åþ—)ú­¢š¬`þ\:ý¦è€í·Úô(Cdá¡êË/ÇÂ#íû¶}ØÓí ŸÍÇrýÏîûú¾“¤éÚ„:f•n¶ÖP©¼±êIîNç9ùç–FS6Këš].<Æ8b¹KìUØ«±T©«éš-©½Õ®â³´/«3„Eê}†]‡òˆÈù8úV<âÉ!æóÏÌ› ÿÌMƒÉÂÏU°–ä´×bAÊÝ‘ R­Ê€P²¸#—M³yÙc£Ë#›Š]ÿŽ1íöŽ 7 âe¹¾_޽y0ïÈÈ4{1jš¤/šíƒ­¯¨ì F¿»š0›kï]ºR‡6¾ÒË!ÅxÏ?Ð}΋ØÈbŽyÇ #,y_w) ïütL¿2/5 _]O9ùZÞb ™ õˆy-ϤH£/%!8º«r­~Œ~ÈíhcÅàå&r>ýÿ±Ëöƒ°rfÍùœdêõŽÞV6£Fí¢ùÏþcÕtÉ5Eò‡–´£É,ôç6Í5YK§Ÿ—ÅÆœš€•9^£U¥Ã pŸsë-ëæ´šv§, ãù|Xÿ†›ïäo~òõ;ÝDÔo Ôµ .¯­T¥¼ÓF²Åy|!ª®àç9U’1Œˆ=Žm“œ¥D‹¤Ç1ܧb®Å]Š»v*ìUØ«±Wb®Å]Š»v*¡{ce©[=ž¡oÕ¤›IȲ#SqU`FOY@ñD|š³a†X˜Ì ÐîÂ5/Ê'Þߨ_[[›bèÍknAp©'¨VE ±'¥ytÛ7{QÊ$ñqu<ǹçõÊé'8J#‡„òŽ÷¿ö¼«ókÌWjóDºf]i>^I Ë4fB>±#Ð)¢WÚ½ó¤ì- Óá‘©düD~—ö£_-^¤ÂŠnÿßÑý¬Ïÿ™IÖ¼„t z——·±04Rô™X’JñT ­|+˜—ÙœZ®9òfþ¯Ç=ݧn{A£Í¢ðñîMTj¸kìÛ–ßs ò®¦ß—¿”Öºž¶¬Im-áfk™áˆwÜmà+á˜Zì?œ××SîæC³ìÍOòweÆyyî@þ±ôÓä¥äßέS³Š4Ï›«=*¢Ëè8 £³+I¦î|vÉv‡³¹1Èœ@Ê? ý¿&“í~°9×Z÷ù|Þ¨¬®¡Ð†F«PAèAÎlŠ{ m¼ v*ìUØ«ó×´¯;éþ•Àj)ú•úŠ2wâãöž£îÍŸfv¤ô²±¼O1øêé{k±1k¡RÚcé—wë #òçóVò&¬?/¿0 GjŒ#°¿–4@\ý¨[ö[ö:¾ÎG´>ÏcÖãüÖ—êþ(ÿ;þ=Þ:ûùñÝ—Ú™tY+ªÚ¹îíÿšzŸw¡TnCž^CÛ±Ï;ù+IóÞŠÚ>«Ê2­êÚ]GOR € 0®ÄhÊzz´ì~×Ë¡Íâc÷ÐÇW_Ú]W‚Ü^Oùˆšíÿš|±ùA¦êÓÙérÙÄ×7óÈL×Tõ20*^‹ ⵜӗa8ôÙ»BxĤ$j m\»¾­Ï@ó=¬2Ï>-fDLw'™çÏ¿—.ô<Ÿä§ž¼½¤Ùkj^Zó ‚Þ{¶hÙ¤XŒž˜$ «+-+B¹lócí­\’Æ!“±!×bjþŽ›Å>ËÔã„fe ›ñ«ûCèLó7¹c¾vò~›ç}ãDÔVoÞZ\Ò­o:ƒÂEûèø$fÓ²;W&‡8ˈïߎ®iv|5XŽ9|qïyÏä_žµ/(ëÓþPùͽ)"•“FšC²JÇ— õIkÎâiû@Û^ÄÇ«À;GM½Xòþw¾<¥óè^3²5SÓå:l»vý^ãÌ>”Ï%z§b®Å]Š»y÷æç“¿/cx/®>½®R±é6Œ­5i·ªzF?ÖßÀéû Ù-_h`8qÿ>\¾Îø|HušîÖŧ؛—pülùã\óGæwç4…n$ý åj­¬e’Pk£Î~tJôãžÓØ~Éèû4Ç“ùòçðé†þeÔaÒk{Oîñ}Ÿ®_w¹‘yoÉ:–P=¤^µõ(÷³Q¥5ê²—Ó\è̉{NÌì->Œ\EËùÇŸìø2<‹¹v*ìUØ«±T‹Íú ù@ºÓ€X§«jÇ´Ñî¿~ê}ŽJ&‹«ížÏüÞžXúó¼rý_пó„™§ÌÞAºü¾Õ$ÿs^Pz[,„ú’i·.Í͹ô¤åþUà3!ñ9 /©±bìUØ«±Wb®Å]Š»v*üçÿœ‘ó[~nþ~/•­dõ¼¯äÐö$)ª4Ѱ{÷ö-([öæ>«/ êë»_[ùm<¦9‡¼þ®i€ €è3œ|ءث±Wb©FæM7]¹¿µ±õ=]6f‚ãœeT°bµVÜxŸl»&@z¹Ú¾ÏÉ‚0”ª¦,n›å. …Ý­ý»ÚÞ—Ò Ì ÔÐä ‹äÃ!‰áÜô|ïaqyù£çhô>NÚy±Kµ†Îܘή+çÈr å¹!sºËè4Þ&œqqVç}»ÿï—áÉ>ÕÖ Z³ÁÃÅQoÝ×ðôÉïÿ%üðÚmô?•µ>?¾#fˆš,Ôsˆš8GÍr£ÓÓqGl‘üW¸ôþÖÍ<çØºÎ ’qO¯—¾=±™ùÓò†×ͺÂy‡HÔ—N–éTÝ‹ÕI~ P«- ^½_ê{?·¥§ÇáÎúvOnñÿ"}äÖ…?Ÿš¤†¶þV<Æ·29¯ÌB2Ñì´<¿gí@öÃQ/§LkÞOû×Êø×?êV?ò:_ú¥úÇþ«ö~ÕÿEš¯ùF?ì¿âW/üäÔ;^ùa’›³ ¶ZõZã€û*,¿gíAöÓ$>½9>ø£í?ç ü¼ä Ý*ò õ1¦þ £Ê'ì®QôÎ'æ?[v/n°«‡ºêdVœ¾@¾!_P{I€-̯ÞÈGÒÙ—ÙýT?†ýÄ;<Öègüf>ðheºn½¢kºV£m{µH‚d‘‡Ì)$}9¬Í¥É뉼;½>·oîç{ˆ)†På;v*§qOo, +ÂÒ£ š2ÆXS’–Tu(Jˆ5l2GŠ$]Xæ:0¯ þ[Yy'ô“¼ãP¹¾n ;ÇÄ‹PôÙIaRÄòñÛ6ý©ÚòÕpíÂ#÷÷ºÃö~2O—Zþï×ß².Ë!Zj¥bÑ¡ yª³ÈЫ šˆYŒcþƒ¶U.ÙÕJf¾óæÝg4PÉâ bþ5òºû'ù“çüãædŽ?RO)hò"HÑVŽ­"¤³Ô7ÙŽ½¾g:îÈìó¦Ãf¼IѰýoík f¢…œ8ÏO~òøòµ•~ißþ\Mä¸!ÐÚÆ]EšÑ‚ÈGêĊÙ'Ä«À£þÕ<3[ظµcPNN.ø¯¯»ötw>Òçìó¤–Ü<5c¾ú]ýY÷å̳éÿ—º,ºìÂÝ’ÆK‡•Œf 锦i;^"z¹Œb÷éß[ý¶ô#AŒå5·^ëO/÷y;ù rùGàóÒöWŇ×´~±Ì3¿ÉOÌ´üÃòºývAþ$ÒÂAª&ÀÉQû»€ißÁíLåý±ötöv§Ò?u=áå߇ÝN?cö‡æqïõGŸëø½/9nìU"óOœ|·ä½<ê^dÔ#²ƒIÖY˜³kVsòwÍ—fvN£]“ƒ Ø=çqµ:¼x#Å3Oœ<ÕùççÌ™t?Ë›It$ž2êí÷iGÃöB_Á»g°öütújÉ©#,ÿ›üáü_¼žtëõZéxzh;ÿYä>ô¯Ë–:fšâÿ\Òš£mêTÀ®MIâÛ¹¯í?ÝžÅB†Áè»/ÙLX}yy?ö#õü~LðP €¬¼UØ«±Wb®Å]Š»b>Oó[~J~{hÞr©‹Ëš»›}` —ê·L#º®ÛúoÂàä—ÀØ|ŸÚ¾Ïð5&CéÉ¿Ç¯ëø¿NÕ•”2TŠ‚7ã&ò­â®Å]Š»v*ìUØ«üçüÀ‹òÇòÏÌ>qfQyglcÓQ·õ/®†ÙiÜ 3’ Å!ùßùM¤Ë™uæ;âÒ_êÒ³ d©vÕ‹êîXŸ ÒöŽ[—sçþÕëxó C”9ûÏìz&kžQØ«±Wb¨MR+Û:ê :U‚úX-æzÒ7a@Ûo·\œ_&ý4¡‘3wï$Òõo4þ[]]/˜4æ»Óo¥õf¼ˆ†¬§bë Ø–þW¡>ÙµÉp8Möú.›´ã|2ˆ wu~‘oYÒ5;}kM·Õ-ÖÞåyƲ¯¤n7ðÍVHHƒÑâuZi`ÈqÊ®=È܃ŽìU+Öü½¤y†ÛêÚ­²Î£û¹>Ì‘Ÿq¸Ëqf” ‚æhõùtòâÇ*û¼0KMóò§RmòçU­Áå5ª|Lè»ñš±(ù û ËÊpj£Áš#ñÜz=¿gûG‹1'îçüîŸ?Ðv} ù]ÿ9oåŸ2´?D¾]× ýsâ6?MÉ«DIìÿùYÈöŸ²™1ܰúãÝ×ö½\5f?^ãùÃôÒ/àú> ຅.-¥I­åPñËGS¸*ËPAÎJQ ÑØ¹ñ°l/À—b®Å]Š»i™QK¹ Š f&€¹$œ@WÃß™z§ç§œcü¼òTå<“¦Ê^êõkéݼFrôë†ý£ñw} ²ô0ìÜ>aûÃÈwy{ûûœ‡&·0Åâ{‡ã™f¾^Ð4ß,é0hú\~´rwyý©÷f?çLæõz©ç™œÎåö=‡—ÇŒPo™LóÌv*ìUØ«Ï3¼û}åd±ÑôDþbÕ[·%æ"RÁ ûLÌh€íÖ¾yØÝ™A”ò„9þ>÷˜ö¶ç¥Lj^Lœ¼ºrï'“Õu/Î/ o0kw«}aøò?±éˢíØirù®ÂÚãU³ ;-=H¢¹áÅÊT Šö5§ZœñÔRÃ""vø=pÑŒðÔB&qß¼ uü~¤ë¦Ã¦a»b®Å]б1þfù?Ë%á¼¾7ÉPlìé< ŽÍBO³0ͦ“±µ÷Œhw‡ãÜèûCÚ-&—iJåüØîPø—›ß~ty·]f·ò†Š-ã$¯ÖeáÇ­4?ër·³xqï–wåËöýÏ:=¢×ëO ÷×Û´GÆÒ; Ͼfø¼Í®È!µoê3¨ÿžQðˆ}²Ç-6îà/¿öósqûÚzÍõY¸Guñ±µgùm ÁCró]7pÏÁЀøl2í žTþ“þ Þd>f‡û?jumå/Z!Ó`¨è]‡ï“‘Ìyjrd½ŸÙŽÏÃôà‡Äq}²´Î( €R’1àŠõeFDów°CÓp¥L ®Å]Š¡§Óì.kõ›Xf¯_R4z×ý`rBr‹‰ŸAƒ/׎2÷Ľ*¹òo–n«ÏOŒ%¢§Ð„Ã.ޝ êé5>Çvnnx@þ­ÇýÉ#»ü³°-êi·ÓZÊ W˜GJÀ¿2#Úø€/5¬ÿ¦ž[áË(:ÿz~Ò­kuù¯åj;SmJÍ?Ý8¸Gnÿžg1òétyþ¨ðŸ-¾ïÒê2vnhwÅ?#¥ßÙ-ÿÒ²]óäÁ(³ó~%¤âæµ ±ñ0LCòsš­G³/ ïÈþ±úšp{c,RðõXŒ$;¯ýÌ·û^£¡y«ËÞf‹ÖÑ5®è*ñ©ã*ò£z8úFsš\²D»æõº.ÒÁ©Šb_Ëšo˜®s±T¿]ÒÛ[Ñït•º’ÈÞDÐýfs@ÛrìFÇÛ¡|¿M›ÂÉЕEÅÖé¼|RÇÄcÄ*Ãòwåž“åÏ.^hzŠÇ¨É©ý#)R«"}%QZ€£q½CTצl»C¶2fÌ2GÓÃôþŸÇs§ìŸgqi´òÅ:ŸÕçÝòûÐw䇒l5¿eº¼DnqÙÜÊ ÔT"+0 Äõ˲ûI©œ8v`o÷¸Ø=ŽÑãÉÇê—‘;}Âþ'Þ¼Óo}ù‡ù¦ÞO¹ºk=Nøc…GDŽ ò2¯BîME§†û}ã£ÑxÀqJ_¯o€ûÝicŸhö—å¥.C§¸YøŸ¹C_Òäü—óF‘ êÜiz‰aue;ï,¢EL*µCÖ3Æ äô¹ÇiáœrD G‘Ù»V»L{SŽx¦L'Î'¸UÝ{öÛbú8gÓÝŠ»v*ìU~g~^Áç-7ëvJ±ùŠÍI´—eõnasà`ö>Äæë±»Té§Rú?/?Öó^ÑvÖãâŽÙ#ËÏú'ôwÿ&?2æ×bo'y•Ì~gÓƒ$-0ã%ÌQlÊÕÿvÇOˆu#~Íšk}žæ0ÝË ?ïOØvîuÏvÁÊ< »dZý#¯Ï½ìÃ=C óåw•<Óæ[O3k0<óÛEé=©zA?å‘zž5;FïQ±ßh}£ÔétòÌБ»ê;ëßötu:¾ÅÁ¨Ì2ÌY—CÝiî¯å/kÖ¶¶Z¾ Õ”‰5¬”HÞ1E¢­lW¡î3]¥íø%)c™‰¢{ïñÏ›™¨ÑbÍÄ`&À€lÌ7)¼ ùßÌö÷Ÿ’™v~wÐâcå}YÙ/m#Ù(ä5Å¿€è%‡ÜS¢ç¦è%ÜìéirŸÞãúOû™½—í|ûµ4dzµC4¢|ÇÞ?Hý©#×ti4hüÂ/¡MXRéoä‘c‡ÑW.ä7ïž3-a˜áá> << Y±Òžg‡Ž»x?žÿç%§mòÊѵ=FJÆ5Ibf[¥`‚œœŽ¼ž‹ìÃ=/°?àq9ÖMaáÌÿÎ==Ã0óÚ®Ý3—‡§Zû‡WœÙù[ó6 ÞaüÄÔf½¾˜†kc/7§P®ãeQÙ#Øv#=_I¥Ã¦Æ1ሄGAøÜù—7Aì¬òËÄÕÈ“üÛûÏè7¡ÙXÙéÖéic[ÛG²E…Q÷w÷Ë­íð`†(ˆÀÐ"06»R¹¹·³‚K›©Vxi%‘‚ªÜ“‹ ¹cŽ&R4RÁçüËK©ÞÛË=Ö´Sfš5hâ¯Ùf§úÀdø;Þ_'µr1Óâ–Zê6qûi8ò潯ê·s[kš\qÇÍ'g,®Õ€ø@­ zà ;Ìí Fi˜åÂq€9ßÙÉ’ä]Ó±Wb®ÅX‡æF‡úkË3¼KÊîÃý* ÈAûÅúV¦ž dàh¼÷´úÌiIT=Côý²ÿç1å`þNéKw(“Zòáý ¨ÔüL-Q~­!®ç”*ÝØ6^øù{–(v*ìUØ«±Wb®Å_ÎtyÊmoÌTü¡Ò¤«†]WSU5Q=Ák{Ujt(ž«°=NBsžy³ Xå9rˆ¶!aeeoal8ÛÛFÆ?ÉE +ï¶s3‘‘$õ|{>c’frç#hŒ‹S±Wb®Å^Cç»ù5]sY°¼Ô¤°Ó4+D–+Xº¸”!Z‚Ewp+½N§6ÚXpÆ$ 2?'¹ì\sŒ¥–Ugø@¿Ô˜ùGRÔ4¹ô?'ê1›¿Ò¶²ß]Éq#LУ£˜áàÕ   ­{·L¯Q!)¨Ó‰Úš|yc—SÃáÈDP«6,ß^cÒ¢Š("HaEŽÔ$q  ªª(`Íq6òr‘‘$îJü ]Š»v*Æ<Íä=ÌêÒÜEõmD†öëÛ˜èãç¿“ƒU<|¹;ŽÎí¼ú]âóOèîH¼µçͯȉÇèûƒ«yD5^ÎnrÙñ'ÃíÀÇÅvùäµz .¸z‡ ûúþ׸ìî×è7Ž\þiëðä}â¤ú·ò¿þr/È_™K¯úÌŒm*õÕ}FïèK²¸öÙ½³†í?gséw®8÷Ò‚Ð d'¿øOǧ¸×•½{4.s±Wb®Å_.ÎRþoÞBSòƒÉR4šöª=rXÇ3ÂÑHèÒƒY<oÚ4ì}šì¨×ærý1ú~~<ýÈ”ä!r—&;ùä«O$è‰f¡dÔî8ɨݲIM”¼´_¤÷ÌnÔíj²qúGã©}{°û:<<äw‘ï?¨tý¬¯5ŽéØ«±WþgyÏ^¸×­ÿ/üœÍ©qÀ^\DxÈ «ÍcWý€ãwì;õΣ±»?Äu¾‘È~Ÿ=öáý¢í|òÎ4šo¬ó#žý/¦Û’Ì¿/<­¨yGB“OÕ/íô÷2]K2³°DDâ ›Ÿ±×5]«­†£(”¾÷}Ø=›= ’â‘‘‘>ð;ýÌOóƒÊzíõÞ—æï-Æ÷†“Ä</9@ŽOZ)z·­ToÓß6}®ÅË]„ÿ°‡Ií_e朡¨Â.Xú{wîÅõmÏÿšvÖÞXƒBm:ݤGÔ.ÙeXIN…šET‹‡ÄÆ›fÇ—K ')ÉÄz ¯ñæê5ZíwjÄ`¸Ž#½}¼‡ZܽÃAÒaÐtkÝ‹Åe p‰ÅÊŠ#Üïœ~§9Ë’S?Ämô-”iðÇåI†På;v*Áüáù©åŸ)sµ2~‘Õ×o¨Û0<ÂY7TùnÞÙ¸Ðv&mFõÃóú_¹ç{WÚ]>’ã|sþhý'§ßäòCÌ_˜ß˜d¯©úA~‘DZt>'ûÉ*?Øü³©Óö~—IÓŽ]çØ>÷IƒGÚݳ¸ýÎïˆ#ýÔ¿Üû‘:Oåþ‡§…{¥7÷rÓ G_hÆÔÿZ¹n]tåË`ö]“ì‡MG ñ¥ý/§ý//²¨ãŽ$Ä¡#]•Tö0É·¶†8ÀÄ@»NÅ]Š»v*ìUØ«±Wb®Å]Š¡¯tûF/FúÞ;ˆ»,Šžàõå’„ÌMƒN&³AƒS Ðcîîø0ûÿËÄŠa}åËÉ,/c<âRíEaÓ„‹ñ¯Ï|͆ºÇ Ç|û´ÿàuŽüMÎ9@“_ }Cý’i¤~kùÇÊ3Çaç;FÔlI¢ÝŽ"p¾+"üPvjšíO``Î8°žÝÓö~6yãÛ¡Ù“õ°2I~© ¥î;÷½“ËžmÐ<×kõñg*–ðÍ{ño#íkiŽ)aúä{¿„÷ßèø<¯AòŸ|ϤØéšÖ¡sgåK"^ÎÊgjl\´pIcñ¿ŽÕé°ÑàÇ–YcâOœ«sñu™ìî«Uø„Ãå|þôŸµé:^‡åÿ'éòÉk[C¹¼”ÖFUÜ—~¿@ÛÀeä’÷šM›AŒ˜ò<þ%ˆy—ó2ÖëMÞS¹?¤ç-ùÉB±¸?z‚›OJü²Q‡{Îö§µ0ž.4½f@n:w‹üôoÌÞYó ·—|ßp.­õÒï—>2± ^d) Ÿ„ƒÐÒ›b@"Â{?]ªÑêcƒU.!“é—=ýÿgË£Òò·µv*Â|ËåýcÌúý½•ó}_ʨ'Ç q(ê¬:Švð Ôí0hy¼Ïjvvmf¢0Ÿ§Eì~£ÝøéæºÿÏ>Mò­¸°±t˜Â8¥¥‚«*üÜQñÞ¸ˆ’ËQÛú-x A¯á‡ëåöÛ¼æýgÌ÷ӵƒlôoO•µÍ5 —j¨?²»SDv/lçÖd&XøqÖÇ~~þ¿Í2JìUØ«±Vˆ °ªˆ=ÅHµ_ùį4ËŸÏ=OòþîOOEó\M ¨cEVá®lÚ¤÷¥‹Ý˜ ȉ°ølh-¨ž>€íî;‡èVIÕ»v*ìUØ«±U“M¼RO;ˆá‰Yä‘UEI$ôb¯ËË}~oÍ?Î?5~e\†kG¸éÁÁªBÃêö©½7Ktí×5Ý£’£ÃÞóÕêø0 cœÏØ?m3ìÒ¾xìUØ«±Tµwua¤ÞÞXÀno …ÞT»ðŠ êþ7ûº‘›^ÇìëÌ!ü#y/ÚÆr¡o”?)<©{q-Ïæ'™ÙîuíaäžÞI÷“ŒìZK†¯íJNßäÿ­?oëã¶ŸÑ?‡O‡ßî{ÿd;‚?™È=Rú|‡Çî÷½g9‡ºv*ìUØ«çÏ0Þ·‘¿:?OjˆÏ§\°™e§ÐžA™ãWoïÆ—æ»;ÇÔ>ðoí|Ç]›ò=¯âä™oð1áû鷣˦þ˜ŽþÒøó7‚Tô‚Ò»µh>YÇ6A>ÅÝ[¾‹f#Ä÷³Ë<…ç2yÇó Qh¯¤—ÊvBåá„Æ‘§¦ïÂÜTÄ|C‘®Ç:>ÓÐaÓi#q$«ö¼wbv®£Y¯Hœ1â¡@mÊ=>;÷=‹9Wºv*ìU¬ëzW—¬$Ôõ‹”µ³«¹Ýš• Š7f4Ù@®_§ÓO4¸`,¸º½f-< òK„ÇÅá¾aüËóOž®%Ò<švöfº'„Χ¼’ ˆÁþT<‰éž‹±0逞oT»º~ß‹ÄO´µÝ¯áÑÄÆeËý4¿‡Ü7>k4"izO‹À/¯úó~íù(Yü336¶SØlß°}†Òèêy?{“¼ý#ÝÒoÊ™^a½»±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUJ{x.¡h.cYaqGÀe#Ü1‘ÃV}<3@Âq‰æá…jI¼Ón—Xò}Ô–wОi©ùFõÿ…mŽgGU‘àÊ,ÌûcØc— ‘Œ‡ð_û™~‰mæÌ|™ùÎuÐüõÔu"1¨á7Oß'ìò‡Ãþ¨Íhû;C¨7õwýþ÷YÙ¾ÔÊð5‘ðæ6²+ý0éïåî{ :J‹$l7‘Ô‚¬¤TGPs•"¶/l"Ç&ð%Ø«ó÷“Ït3¥%ëÙJ²,ÈëV‰Êþ̨ä7¨ßcC›.Ë×þW/ߊtý·Ù_Ãቛ¿/ˆëúÑþVò¶•å*=+JŽŠ>)çjz“ÉMÝÏ€íÐe:ÝlõãŸö9›Ù¸´x†}¸ò—ö>g¯Ó˲5ƒ$î²tûÇÜ~]ï¥l¯mu8/ìeYìîcI ™ UãqÉX|ÁÏ!͆Xæa!R‰¢ÛHÎ"Q6%|©›ó‡æ•ü‘oêëWcëL9Ca $¹—‰QAþSP{æß²»S®•bŽÝd~‘ñýw]Ú«‡J.g~áÍá:Çžÿ1?5d’ÇBˆèžYbRVGe½–p?ºF)â\õ>ÇöOM£©O÷™;Ï!î¤ïîyC©×v¡áÄ<<}ÿ¬õ÷ŠqåËÍ˼.~½©­Ö¦QDoø­7 óÜûçO)’ôÝ•ìÞ -HúçÞ@é÷ù²üƒÐ¥gÒäÖ¼¿¨išMhµ™©,p€ÆŽIi$ØÐ©ãJ“UéLº¾e“U¥:ŒÆ³DóÏ©÷mï ìzGŸ|ü¶j\,ll˜.eÓrh‘Fò35êÀí#¢íÓà9*"Ey'à;žÅ ÈÆ“?«*ª‰$ãÇ›BÜw¥Ol¥ôx"6{Õ1dÆ<û¡^yƒËÒÚiõ7ѺK A hhÈÄ)BNýÀÉDÑt~Ðö|õZcP u~O9Ѽ™çM)„ÉåûgMÄ·’G1ù…õŠ xñË êñº.Ä×a60@žùßW؈ӼëçýKYH±6÷3FãÖG‡‚Ÿ‹”¢ (éÉ~ŒLE7i»s´rç¡Ã"ôyïÝæ>dÊ_Hov*ìUØ«Î?1Í÷—µ/ù÷Gc§¤]BÉ0¯Ã$ ˆjlZ¿<·x/m´V!˜Týãô¿O<¥æ;/8y_FóVœkc¬Ù[_B+R«q“÷RxŸq–¾tœâ®Å]Š»v*ñoùÊ¿<ÿ$üÁ<úz–¶«¡ØQ¸±{ðVb§¨+•…;ŒRþYi¢¼§jî¼n/ɼ“mé%ðOÓœþ·'C峿^Ñê¼]T€åOËŸÚÌsлv*ìUˆy·Ì^gÒ®à¶òöŒÚ’ËÜLc‘ÑXš*„oASó—§Ã ”©Þv^ƒM–&Y²po°±ú^{q§yîÿ_·×,4#£êLÃÕžÜËÞUv#¿Å¶ýóRøÑó,/Í~a¹ÿœ†üÚ’÷ãBòÿî¬âj€m•º‘µåבîSös"—£¯ò³ûÿT~ÿ{Ööf~P,~îËõ|~ëzò"F‹j4UTP6Û8âmö0À—b®Å]Ф>kò~‰ç+a¬DIŒ–·¹ˆ…š"„£z÷s7C¯É¦—¼t.·´û+¶.Dsç—Gÿ8ﺬºû*׊Ú)Œ…GΟFtgڳö=ýû}Ï`Çù}?Õßïz¿–¼¯£ùOM]3FƒÒ†¼¥‘)fzP¼µOà;œÖ³[“Q>)þÁî{>ÏìÜZL|Å´ù”ã1÷b¬OÏÑü‘gÎé¾±ªJ¤ÚièÀHý¹?ò¥hýÍŸfö^MT¶Ú#™üut½³Û˜´0¹o3Ê=`óx²óæ6 º÷š§h´î¶¶©T^~1!¯=ÜîÞýsµÇZHpbõ?­ÐvO³z®Ù˜ÔjɆ/á¬DtÒæz_6qgei§Û¥­”+º}”AAó=É÷9‡9™/®èôX´ØÆÐëûS³á«Á,RëÈ÷‡ñÑç”ɧTò/îVÆ=)¥–Îy‰âœZ²ÂRžqÐoSN£3½«ì#«àÔé£ÄgB@}‡ô‡›ÂviþPÏM¨<<WöÒ;ÝæÏ-wÌ—/¡~ZØÈ¼ê­©H€ÌTíɾ×ü·ßýS–v?°Ð…OTxóG/‰ëðÛÞO´9õRð´‘?Öëú‡¼ý‰>‡ùb¯pu8\¶©ªJÞ¤‘4Žè_ÆIâþ<ï #ˆÀÐ9ÝìœAñ5'ŽG§O‰æ~ï{ÐâŠ(#XaEŽ$R4U@ìØ`{@DPüY;v*ĵMÊþWRóséé-â“pYþ/Þ»Pª³Ÿ´wÉ‚N΃W¢ÒhÆMQ€2çñ=ÝÖz°Í>/ÌŸ;Æux5/Ñ– ÍõeYd·FâiE‚Ì%òFƒÍiáÚ}¢Ÿ‡NRò­†·¦é k¯Ý‹Ëðîþ°frÏ ¥ž„Iú6í•ȇºì>|XDsËŽVwçÏ̧yfìUØ«±T—ÍzOé¿/jp^RÉh7õcøÒŸ6a‰¢ë{_Gù4ñõ#oxÜ}¯¡ÿç|ñþ!ü¬ºò•Ìœ¯ü§xñF„Õ…ñkˆI®ÿÞzÊ<ŒÉ|BAõ(v*ìUØ«±W¿óœÞc“Ì>xògå}œŸ¼gP½ ½&¾“З¼qÄíò|†IðÄžæNq‡¦„Ç¢Š8"Hb^1Fªˆ£ UîÎ`›|vR2$že~.Å]Š»¼k@ó¶‰iç­cUÔLÖ¶×ãÒ¤ â6B«ñªŠÐ…ø~žù¸Ë¦‘Å7§¼×v>iè±ã…HÇ}÷|þ<Þ·c©iú¤?XÓ®¢º‡ùáupâv>Ç53‰¢)â3iòb58˜Ÿ4VE¥¢BŠ“A°ßÄš SI˜ñ4-M´úýxZÎmøý¯SÓÕÙÖàÔÔr~îìO¸þ¿µé=w3ŸzÇb®Å]Š»v*ìUØ«üÅüɱòU¯ÕmÂÝy‚áI·µ­V vKMé^‹Õ¿ÝvOdKU+;@s=þAç;{Úh£ÃVCÈwyŸÕÕäú–/õ‹×ó7œÔH&5'ÀÈ;û1ôîο&h㇈PÁaìϱóÍ?Íë®R;ˆ¾_¢=:÷3ž›™€ú›x«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š¡ïl­ug´½‰f·Q‘¿X=AˆÉBf&Ë­ÑbÔã8òÄJ2éøëæÂ,ï5ÿÊ\_é¬×~]ºp.m›ì¸ì¯ü®ÙqýFej4ØõÐá–Óã§“ã£ÙºŸgóø˜Éž ŸÀ—t»¥×æBy{Ì:_™ô¸u}"oVÚ]™Nϵ‹Ù‡ö³‚Õig‚fCÚh5øõXÆLfÁû<ši˜Îc±WH'sîiLQNÅ.Å]Š»iÝ"F’F Îì@UP*I' @½‚ Yäò¿7~uišt¥ùR!¬jÌ}5™C5²¹ØqáñJkÙvÿ+:^Ïös&J–_L{¿‹ö~6xÞÕöÃ+†âK¿øãߛʼÙåo;ÝØÏç3g•ãYá ,ÑÆGfDUG´­|Fvº}<0ÀB€x |u‰Ï—r^«ä–Ѧòí¥Î‹l–°J£Ö‰7a*|.Yˆ=ØôÁ+·Ô{X%¦Œ°ÄDcÏ­õ?E‘wÅ]Š»v*Ç|ó¦I«yWR³€rœF&‰GRа–ƒÜ…¦J&‹§íí)ϤÉά|7ý ;ËŸ™:å;{¯RMJÙZinB±âÅï_l™%ç;3Ú}>ŸGÊÌã·ûï’U*ù¿ÏúÍ–·a¦¦‘_ªÞHYVŠüÁgmÞ†¿a0ì1­í<ðÍ c‡)}óþ/€{2òâ9Ð= 7ïJå/¤‹­×b–#ç8ü¯¦¼Ë¯i¦úh¸ÚÅE žN¼‘˜-+]Ødã|ž¶ã¤ÃZŒØøÈô޽çqËæÅ‡¼íæ ò–õK?²—…m¤,CåC’ᛡþ]×j½:\\1ïçöš‹ ò—–|Õ§êo¬y‡WúÔ’ÄÑ5 g•@bQ›Š­è«‘”‡GoØý•«Å”åÏ—ˆ‘\;ŸØ>›äØ«±Wb®ÅVÿÎ.ëÿàùÈÛÏ,JÞž•æÈ.-c P‚R¿^·#ÜxWýlȉ°ø¿oé< VHô»ã¿ÙÉú!’t®Å]Š»v*üÆÖõ³ù‹ÿ9 ç/82ØYÜÜAc'UôméamAÐrŠ2ÿ<Àí Ô+½ç=©Ôpi„:ÌýƒÔÌsFùñWb®ÅR?5ùŽ/+é-¨¼Fâwt‚ÖÝM ’½H¡ì é—éðø’§cÙžuYx.…Y=Á€'˜àÖ.õ(?04+H-ôèRI¦T¬£KÇÒˆ2±nLù–”ß3¼<9Þ˜ö|°ÆI–DÌì6áÛ™îÛâÏü¯åí@±q¢r6·Ì.C»s%YP ââ¾9ƒŸ4¦}\ÃÌö–¿6¢cÅç¿iæPë’3è+æ]]%®¤´YJ1’0¥ OQP *:u˰eðåÅVçöv»òÙFN*ï`£4<¾p5Ý1:BÕ•‚öø‰Ê69ǃ/1Â^—ó›¬úÇ….þ_o/˜Ah÷¾Eó¹¶µåÙ,uÙäâÑÆÒú)ÜóJ•ñ? Ì øšŽÐìL:þ™wÒ:ýï¯{3íô£QŒ¸‡ó%ÏüÓý£ÉëþQüÃòßœc §\z:ˆ“O¸¢N´êTVŽ=ÔŸzg¯ì¬ÚcêñËö>ÃÙ}½§ÖA©4óý¿Uš×tìUØ«±Wb¬7ó϶žHÒ¹¯µ« Ëajwï,€oÁ·‰nÉìÉj§ÝÌþ{¡íîÛ†‡󜾑úOû^Aå/ÞêwæÏ3»\ê7L&eÜ‚zHàڜ¢¢–|±Ç À5û!ì¼òKóºÏTå¼ÿtÞŽŸ*œf éîÅ]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±U+›h.à’Úæ1,‚²F ƒ†2 ØiÔiáš@% °[+Í_ò£_]JÃ×—nÈK‹rM•@ëÕ¿Þ3/S§†» ¶˜ä;ßí.ÎÏìþ§ÄÇsÁ?Ç þþ׿ú/GÕôý{M·Õ´¹„öW+Ê7¬àƒ±çúŒÅ3 Š!î4º¨gÆ2@ÜdÊ\‡b®Å]Š»ažpüÍòדÕàžo®êÃìéöì ƒÿ7D=üÍ·gö6mNàpǼþŽ÷CÚ¾Ñiô{Å?æÓÝ÷ù<ºAù‰ù²áïô?•˜Õc’'ZÔ• 1÷b™Üh;#›x‹—ó?Øùþ³´u}¢}Gƒpåÿøíîz•ü‹åÿ*F „­ñ’új4ÍãÄôQì¿MsfÏO£†.C~ôúöÎßP´žÆí–×1¼S!îŽ8‘øâäN"@ƒÈ¼cÉRÜy7·’õ&Þáëi!Ø4yFðõ#ëîÈd ý–Ö6¢Zy§ËßûGÛOWÊ_Gv*ìUØ«±Wb¬cNò•ôÛÉo’ÌOq$*ŠH‘rnAcJ~É¥}òFeÒi½Òa™˜…’o}ëÜ9{ºù²l‹»kšòáÈs§.5Þ+LQbév)R¸¶¶»Ñº…'„Þœ¨®µSPhÀŠƒÓ1Fb¤{¼tjÞó<Úž©£]ýVÇKfág„øV¤"¨SÌñ<¾ º€|çó£¬92b— qÿÛáçñýBò¿š­u-Á¬êEjëÊ+ÆwXãYS®ìh*(ßNW(ÑzþÉíxgÒŒ³"=%ÐXüZ}iwm}oÝœ«=´¢±Ê†ªÀl~c"í°æŽH‰@Ø=Uñlv*ìUØ«Î<ûywå?6yWÏúpÿKÒ®à”°2YÌ·1)?åQöËq—Ï}·Òú±ån'ï¥ú—¦êº¶iªØÈ%±¾†+«iGGŠd#šr×ÏÑX«±Wb¬;ócÍ_àËO5y©_Ó¸Ó4Ë©m´ÿJhÌv⽫+ ÅCó‹òsMú·—®u{éÈSãˆÿ†/šNÑÌçÏý¬ÔqgþhûOì§£f½å]Š»Q¹º¶³‹Ö»•!‹’§9*òrEOrM0Æ$òlÇŽS5eŽyó@¿×tˆN’ÁuM>â;Ë@HÞ0G¶ÀïQ]ª3'K”B[ò"¯bk¡ƒ)ñ>‰ƒñy½ž“çgôžq¥=«kWqÜjš”ñ²"¤mÍU+@B¶ã‰>°–LQ©|#`õyuZ,<A/$B ÷í¿í{]¥´vv°ZC_JÞ4Š:îx¢…úi¥+6ùþ\†r2<ɵl mcE’v RÎ5Ÿ,ùößSºÖüµ­úñÜ»L¶LÜ)û*©'8šƒnF™±ÇŸˆŒâõzNÑÐËqgÅD âý¢¤>Ô_u½WÍMy®é–ë6û»}Ebã'ªy# -Z+ˉFÛä5x£h“¿FŽÜÑâÒS5>q½«¡ýL÷0^iØ«±Wb®Å]мïóo^k-ÔŸ­êGUû^‚Q¶ÿP{ï›ÏÅÅ.#Ñê}–Ñqå9eÊìýIß”ô5òö…k§P Ž>¥ÓÚ™÷mûÓìa›—UÚºÓ©Ï)ôä=×ëNñuÎÅZeWRŽ#H¨ õbkpÀüÃùecy'é/Iú/RBU — Ž;Æ}×ol(òzžËö£.Kˆ|zýþmhŸš¾kòmÄzGŸ,ä¼´û1ß }`(îìJ>d7‰íœßh{7'«¤÷tý¶{=íÿ@™ñcßücßßñù—³h^bÑ|Éf/´[Èî 4äÑã'ö] O±Æêt™0K†b‹ê-~L8±HH}ÞñÑ3Ìg1تQæ1éþTÑ®5­E¿s¤qñÍ+}ˆÖ½Éû†ý³+G¤ž£ „yŸ³ÍÁíÐǤÂrÏûOsçíÓPóƹ?œ|ÉñÂÏþ‹¯¦x*¨?î´éîz÷ÎþBlc?Çí/5ì¯bO´óv¨\ôÇ¡#ýì~ÓÏ«?ÌØŠ»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š¡ï¬­µYl¯#[Ì¥]OàAìGPrP™‰°âëtXµX¥‹(⌆ÿŽþâÅ<›æ;ÏÊÿ2¶ªÈÒy_QpÞ©é? Σ±,€vßz Ÿjhc­ÅÇ®?o—ê|g‹Ø:Ã)¼3ÜKý÷¼rý¢ÑÒDY#`ñ¸ ¬¦ ƒ¸ ŽÙÀ‘O¡°Þ»J<ÃæÊÖ]ÖïÚ3_J?µ,¤vÄÇðó+K¢Ëž\0÷{ƒ®í,:Xqe•}çÜ;©þaùßó æM'Èö’iÚ]xÍ{^2ñ=ä˜|1í¿ø½ÏLí;?ÙÜx½Y=rÿcû~?'Ï{CÚ}N¬˜iÁ„{ÿ‹çÓῚwåOÊ}Ee¾ÖHÕuZ‡&AþõøPý£_Ú¸gFë4ýo/Qz €è1vNÅ]м«ó“C‘!±ó~ŸT½Ó¤Ž9ä^¡9ò‰ÿؾßì±u=¥ŒÇ‡,v1?Ùö²¿/êñkº5ž«¸ŒQû2…×è`Fc‘EõÍÖNåÄ>Þ¿jgÍv*ìUØ«±Wb¯6óž³æk¿4ÚùCB¹x¸ˆIõ‚x3Ô3Î…€M8îNY*Þ3¶õº©êã¥Ã.!wÊùõøtDywËz”5a}«ù„\k7€[úê¦C3-YÛâ‡lI¾½›Ù˜ô9¸òçâÉ/Mwß¾Éß®ÏAÊ޹ثÈî4/<é^dÖmü§Ea¨J³5Ë,kW¢´µ v_„W-±[¾}“A¯ÃªË0¨ÌÝí]ý{¬·TÒ¿' ú棵Ik{5ØÖ’H?ãLNFzObºæÉðë?©é:>‘e¡iñišz²ÚÃÈ wg5bY[Äší•“oi¢ÑãÓcáôŠ?”ìUØ«±V%ù“¦þ‘òíe´áw·¤~3ÿ['»ÏûO¦ñtsï«åÏì·Ú_óŠjÿþDùZYÞ‘š5È­x}BC+ÿ"=#ôåï´â‡b®Å_0ÿÎuyŸô?äý¾Òo1j–ÐIiÊÚÐ5ÛŸzHýø¤>|òžú+ËZ]‰^/¼m*øI õþŽsZ‰ñLŸ7ÈûS?‹¨œûÉù ‡Øœå.±Wb¯-üÛ”K}åí6öVƒFžv{¹G@¢3|ÑÓ›>ÏHŽocì´j§so´ý¤,×|ŪyŸW¶ò—‘o;h#ås¨Ç+€B7”Uø¨ ¨?8°ÇLòƒ-ƒ—µ¨Ù'hÐû¹Yûcùw®kªj¾V×n>¹q¦ÔÇtX»|é²—;°$‚¤ï•ë1G„N"­Åíí‹|C„O§ÂþDÍ{Ë õ]F #MºÔîj`´‰åuZrn"¡Ev©; ž8HÕ¿M§–l‘„yÈÓ_Ì/&ùŽÂãMšþM5®âx_Ö_IÕdR¤‰(ñƒCÜæ_å2c ÕÓ¼=…«ÓLL@O„ÞÛòòرø<‡æKŒ¾Jó:Ïbÿ°&dJ‘ ÷ ËΪûÈnìçÛz|†µX*^ï×GïfžFòÄÞVÑ•ÔË=ìòµÅË¡bØ¢–¡;/Zf«8É+mvˆÕæâˆ¨A“f3¨v*ìUØ«±Wb¯²?ã_Ì©õýæ—¤ŸÜžªDŒtÿZJÉò΋K‹‚u{­GøgržN!³Õr÷ˆv*ìUØ«±T=í…–¥nö—ð%ųý¨äPÃæ<·aÏÇ®[ÝÚÝÛ%å¬ñÏi"óŽxÝ^6_ÊH#9iã”O ^÷XΖ;8@DPñdìUØ«±T&©§[êÚuÖ™t+owÃ'ˆ)Qî:ŒXd€œLOW‘þVÞ\iz†­äí@ñ¸µ•å‰MiÊ6ôå½ÂÃé9^AÕÍö;Xa)éåýa÷Ð~oPÊžùØ«±Wb®Å]мïóvÍßD¶Ô-íÃOmp¢K¥_ÞCVý¡¸RÔúrÌ|Þ?Û,$àŒãã/«¨ªÒK/þ^h‘AªkZàÔnÈY•!”ý¯´H+%kÝ› $º½?gvnœ ™³qËžÇôGÕó/SÓ5+]^ JÉ‹Zܯ8É4­#ÄC•‘Oy¥ÔÃ>8ä‡)#09Å]бíCÏXÒ¯åÓ5ï«ÞÂToCÿœó°ÛyãÈwOÆK+›mNÊ‘ZÒäÓÛÒ„fSàÙ±˜HÄóŸibÔìUØ«áùÎMUµßÌß"y[”6¶¦îUjwBåO¶¯°>ù^YpÄžàÑ«Íáaœÿš ûlæv(v*ìU,×4 +ÌVQÕ õ¡šJº5)ÉXn2ÌYeqs4zìºiñc4Pz'”tŸ-Ù\Ûh¡ žåHkǤ“¡ ~!O„š…¥2yuÈA“~³µrêf%—qáä?-ò“î|´·×š¤âçW¿™eRXV$|M¹,O&ú2ÝV d 9/¶ûZ:žã0€ÛñåÈ3Ãt-2«©W”ìA{âi䟘V‰?™´_/Ago§öY.¯âŒFÅ]Ê¢×á=k½>®“$„%"nº=·aj³GM—1‘Ÿ(“}/ßø(2y.ÏËZþ‡i¡ê—6«Kè3s¬±HŠàÇÀñ%»þ=2Ì:“’2Ó•Ùý¯=V ²ËËÃäy÷ßsÚ”qP¢¦‚•&§osLùù-â‡b®Å]Š»cÞxÖAybþõÃ'¡mãêÍð=ÔßFdiqñÌiØÚOSô»>áø¦7ù[¤~òདiq¨¹˜žþ’|ÖßNt%Ù{O«ñ5#”|zþ¯ƒ7Å犻v*ìUØ«±T§\òÞæ=NÜ;Hç_†hÿÕ~¿AÛ;EÚ9´Ò¼gáÐüM¯ÛkÞA–]IÖd}?X‰ÕíÆ7<8÷P[ì‡]Îý36“I J ˜ò/©û;í£QŠQÇÅ/Iq+îóû|Ù§•4Ðt¨à`>»5$»oòÈÙkà£lÔêsx’¾Ó>Êöìí(¼—ª~þïty|ÏT÷1Þ•Ø«±TªãÌš ¬†)õA³(1Àñ­2ØéæyéuÑè0ˆy ¾þä]ž¥§ê*ZÆê+€>ЉՈù€j>œ„ñÊ<Å9º>ÒÓêEáÉÿT‚ŠÈ¹®Å]Š»v*ìUØ«±Wb¬Yüý¡¥ëXŸ×YLúkǘnyt®eêöx¹ûy¡Žc„‰ñ pý"®ë½”æ#Ú;v*ìUØ«±Wb®ÅP#XÒïèáy¾ž‡1Σµ<}ºäü)Wlë‡liNoĉüÛßÝïòæŽÈ;b®Å]Š»`žv°ºÒ¯m<㣓휑™ÙGB§àr;ØoLÏÒÊ9"qOp_-öû±åŠQ×áÚQ#ýì¿ÞŸ‚/NѼßù¶é¬ù‹Rú ÈÂ(!"€©£,P‚BžÜ䫬3/GÙø´Â >=Kçù³ê{Dñå—§ ¾ôÞ«åÿ+èžY¶ú¶‘j±–sñM/»¹Üüºx ÍspéáŒTBq‹{±Wb®Å]Š»v*ñÌH›Ê¾}Ò¼ÙãmyÄ]S»EH¥xÄËOzà"ì–c¥ÕÃ0å{ýÇìzz°`H*EA‚q˜ï­{†ñK±Wb®Å]Š u8jÚ]Þ˜eh>µÄ&JÕ ¡ê+¿L Ó­Óxø¥ŽëˆU÷<²çJü¶òeеÕÍÆ±©¥ °€ ÇPª‹Ð׋3e–KÁåÒv_gχ/YŽc»á°ø^“å­WCÕtÄ“ËüÆ"Sêè‚/I¾ÑR‚”ë_|®@õ{NËÕéóbŽ•UðN0;b®Å^mç4yE5(ìcÒ­µ]åŽ9å0£ú`7¼À,ÌÁGOÃ,ŒKÅö×jèÆQŽ9r4 y_2|¿±è–öðZAµ´k¼J8ÐQUG@†Vö8ñƈ 9\Y»v*ìUOþq£To*ÎQK¥rámæ[[ëS]”™!Šý<àâ?·2 v|kÚM?…¬È;Ïúmþ÷è–IÑ;v*üÝüßÔÅó•¾aœQítN±€kÇêviÔø‰Ù¶aëåXÏ›£ö“7’CùĶÿBušÌ]Š»v*‚Õµ};C²}CTmíP€\Ô’Ç¢ªŠ’O€ÉãÆfh9:].LóàÆ,±ý#ó#ʺÍâØÁrðÜÈÜ![ˆÌbF;­¸©ì ~MH !Ùj½ŸÔá‡:7L·1]#±Wb¯;üøò¢ñéºî mõKjúrÛ£Êð‡¡+ EaC±âwð͆ŒeŽñ=O`ãÖãx¡p—~×îý|–ù7È:47Py‘ufÖø ÙÉÇ‚!Ag$¯`iO u:¹a\)í~ÜÍ(œ>…üïÅoFÍ{Ê»v*ìUØ«±W”~m]K©jZ/•mïgLã¨å+z1T{|y¶ìÜ|åð{OeñŒXòê%È ùnCÐí-¢²µ‚ÎÆ xÒ(×ÁQBÀfÍä²ä3‘‘æM«bÖìUØ«±Wb®Å]Š©Ï“‡”®¸«ùüÞ•š§×Þqÿ)4¿óßò:ÿwðýÌúøÒ—ü8ÿ»{¶sÏÓÅ]Š»v*ìUØ«±W“Ãä?0¦¶€ú²L$úÿ5ÝCråJòåíN¾Ûæäëqðy÷>‡Ø^ÐŽ´_Ò%~%ŽWw\ø¼«Ÿ–ïXÍ3îNÅ]Š»v*¥so ݼ¶³¯8fFŽE=Õ…ȃa§S§†lrÇ1q û‹ü³Ôåò¯šï||çê—­ÊÑÛaë(ªÛ÷‰±÷gE‹ œA~yɤ—gë'¦Ÿ v=ýÇâ>Ýž×–9ÎÅ]Š»v*ìUØ«±Vù±£ [É÷3"ÖãNe¼ÇŠ|2}Ÿ£´±qb>[¨þ_jߥü©c+·)íÔÚÍãÊ…kîS‰Ê&(½ß³š¿GyÇÒ~²™>EÞ;v*ìUØ«±Wh·~_ÐüÝæ5ó|h.䤴žâ&™}7vsÄqjVR :mó´ÙŸ;ÐæÓiµ™ÿ47!{Y=ÝE&–Í Ï™¼Åy£Äbòü…DKÇŠóæJPvÛ‘§`F òg³3Õgž!X/žß§Üôü­îмgÍ^}¿Öõ<¿c8Ñ´Ñ#Ásu1!Û‰*ÜÌaŠ­E(½{šeÑnù¿kûC“Q”àð¡tIçñ«¡ä>+|Ÿåÿ>Aki}¡gqhËé)E˜§6§^&¨@­ 1•DZaƒKÚ1˜œe«n|þ«âöpAƒPwe/¥Þ*ìUØ«±Vu©)~uy͵á7öå«@b†íVmûV))—c;>ií¶ Ï ÿ:5ò?´?Q²Çˆv*ìUùeäÝ@ù£óÏ>rcÌê7×W 曋û¹.6#jQFÃlÕöœ¶ä}°ËXñü“òþ×¢æ¡àÝŠ»I<Ó¯·–ô£©%£Þ°‘#ô•4j’Õ Ô v ^$ªéØvn„jrðpíÏñO'ó‡žô6Ã¥ÆÐ\A­È’òݸ•’ n.­^@:¹µÓéeŽùnײ{.ÌØ.Ÿ·Ï•i¿LÜê¼A^*è÷ý³ù°q5øt+‡ôùUy2Êao®5±ÐÆì u®Á¹W߉޹Úã|ëwYíQõbâúø}_}½/5Ï$ìUØ«±Wb®Å^A¥ñ殡¨ŸŠÛMõ}×÷ [->d—ÑiaÃŒ·Öƒvd!Öuöú¿cÔr÷‹v*ìUH\[›ƒh%_­* L<‡1¡¸õ¥AÅŸ‡.*ÚêüÕq`ìUØ«±Vù©­=&ÿIÔß‹ÔCº1â¾â¸½G²Ú?CýÑåø÷"<µ¤F¶² éê\ÞWݾï³ôg?¨ËÇ2_¶½›ì‘ ÑÃzªåýcÏåËÜ|¥Þ»v*óÌmíoƵ fKIQVvPO¦è8‚ÞŠo›maÃÂy¾3ÿNÄÊ3þj ˜H/è‘¶þDVýè/ùö÷E¶ŽÂ⻳‹hþ."“Zr¡ÕNYŸD&l.³Ùÿnóèq 3€ÉòÞ¤>;ßËâÏô?7ióz6îÐÞR¿W˜cN¼H$£5¹´³Ç¹äú—aû[¤íÃc?æËcðè~ÿ&7ùƒ>µ¥Ý[ÞØÞÏ •ÂðhÒF ²§°éÈ~£™zÂ@‚‡öÿ>·I–påœa1T ¡!úÇÜSß#ë2k*›™ —–Îb™ØÕ˜}¥cóŸFck1pOnE齈í™ktCÄÖ³ù¿Ãá?QÚìWé`:Œ¾†½w8ŒWr¿•ã)4Í”À'Ë»C/‡®É?æä‘ùL¦Z÷œæôÅÛÞCjä2H†H¢PßgˆR¿ŽSއ¤U»ŽÐ×vÌãùœ‡,`wqF"ùP‡qëÞYG<Ñ}¨\I¤êR™Ø!–ÞgÝþ+ýj ÌMvš1Q{O`½§Ï©É-6yqšâŒ=¹‚z÷޼ü“/9y½´–6!_R•y–aU‰ @$w'°ûò­&—ÄÜòvþØûZ{8 Xhå½ùDwûû‡ÄùÄá°óö¯j5T¸¸1°õ"X1(€€=ºW¶f™àá¡òx\:ÞÖâüÀœèî=|7çØør¾ˆÿ'ùËP„z>³#MÍéE4¿ÞG/@¬zš·Þ¹V«I(»Od=±Ô~`iµR2<"Rú£.€÷ÙÛ}í7óßšnô_GOÓ˜Gw:$˜€JG^#ˆ;TwÊtZa=Ï'}íϵt<8pœÅ™wB¼Îûôû¢6öÞz½³ý3o=Ü–ä®·-̪“^)ΤW°›)a‰á |žO¦íÌø5 ä”{ÆCt;£ÅuåODò—éæÒÖMyÃLä4 ËIV:» ©ùWÇÛWªàâô>±ìŸçΔKXnGéÛÔô¿²ÇSÐs¨<î7˜#·:„æx±˜ýFãÃÖ§xS6‡8.‡'ɰ{A®=¡Óáñ@®#UÇTËü÷曽ÑÓôæÝΆI& ‘׈âÕ$ó E¦Üò{ßn}¨Ë¡áÃ€Ôæ,˸ræwß§Ý·¶óÕíŸé›yîä· •u¹neTšñNu"½€ÌÙK O äðz}7ngÃù¨O$£Þ2¡Ý+¯*z'”¿O6–²kÎg! VZJ±ÓýØEOʾ>Ú½W¡õdÿ>t¢ZÃr?NÞ ?¥ý–:ž€û1ÞØ«±V ù‡a4Ë̶$Çwc"+ȽTåÿ±}¾œÙv~Z&/—ÿÁ#²®ÕÜ ½Çé?·ùÏdòö±¿¢XëÐ-ÜJH>_ö,Í«Æ`Ê2@K½3ŵث±Wb®Å]Š»R¹·ŠòÚkIÇ('GŠUñGR¬>ã‹DEã•SK¦jšï•îOïm¤2*ÿ• ˜e?OÁ•ä_±™Ìg— þ·Ëcú¥•=û±Wb®Å]Š»a~k¸ò¬šö›¤ù‹OŽCu²j2¸‰"Uäx³‚¨ñ¦ù8Ýló]¯—Huñg€<@úÎÀsëøæ—ÝyËJÑõ}Aò¡³—M¹b½ŽÙ z~£ª)WF IäIذðß7/máÁ› 7„¥Rᬱ}üž‰•½ƒ±T¢ÿÊþ]Õ¤¾Ó-å•É//¦«#¹%Öøá.¿QÙ:lÆçŽ$÷Öÿ>l>ûòëÈ73›kkß©]Ö‹WhíËÀ¤¼Ûñɉ—Ïì×gÎ\1Ÿ»„û –_å ü7¤Ç¤­ÉºŠ‘¢vNVFçÄ€OrwÈHÛÐöWgþSÅÅÄ5ñÝ8Àì]Š»v*ó_ÎKRúF|£â·¹hê:,e«_œc,Æñ^Ûa¼0Ÿt«æ?cô÷Éº×ø“Ê_ó<†¯¦Øßò¥+õ«tš´þl¹ó$ïcŸ˜:·è!y§]‰Ó4JôÔ{Y%Øÿ/Å_š?“Þž}vE{²Ÿ5Š4§âÇ4½¥/XOívKÏ÷Gï'õ='5Ï&ìUØ«±VçO4y'I»ú†±§&¥~T<‘¬HцÜry)BFà ó;Mƒ,…ÄÐzNÈìÝfhñ㙄}ä_À,Ñ<½ä BÿO¾Ó­¾©«¬Pê‘Ù‰_’!!‘ 2Êšl9sfˆ ›™k5úìpœ'.(Y…×Î6˜2ìUç7œEž¡ucuaqÂÚiaBÑÉÌFåCqb”­+JæÀvtˆõPöS,ñÆQ˜õhØçóJ¯5Ê?1]›íJ)m®ä Êæ9ãõ l@Yj{·_|¶8õ7f-'jé¡Á$œM{¸ž—¡¦’šU·è5EÒŠr¶‚©=~-êOZïšì¼\G‹›ÉëS–^-ñõ´Ã+q]Š»v*ìU«^7K½ÔZ”µ‚Y·îcBÀ}4Éã€ïr4¸|\±‡óˆ7šþPÙ0ÓµV]åºb z‘ò&¾åÿ 鞣ÚÌß¼†1Ê"þØôŒ^IØ«±W—~eéWúmì^r°¿0ʆ+qêèhiÀˆ;òVüp‡³ösU,šp±¹þßÐS_'þcZk\4íc¦«²£ý˜§=©_²ÇùO^Þ)Âíg¥‚ç‹Õ´~±çóg˜¼Ë±Wb¯!¼“üUùûó°Ò~E-ŽþƲŸ»1µy8qŸ7ßàUØ>&lBCaûÙ½ÿ{ö½4OÔNÅ]Š»CÝÞÙÙ"5ìÉ JÂ$20™¶|”`eÈ8º½f²<"ú“Ñ'Ôü—åýL1kQm;tšß÷d£á?HËñêç¶è;OØÞÏÕ‚N> :Ÿ³é?òêiz±² %³¸")S£˜ž‡±¦nþ¨ïÔ> x´š¿ÝˈãžÄuá–Ä{ÞÍæ}$kZ-͘œRÜøJ›¯ßö~œÐéòðLè_i»'óÚ)âUqGúÃ—Ï—ÅæžG×DÕ&MÂÒxœK]¨ñê~{úsm¬Ãǹ¾;ìOmÇAªÈj‰¿|nCôŠ—–­$óšRkÉL¯yuá@Ü©ò,BáÔKÃÇ·¹§Ù½$»Oµ§¸â9'ó¿´ÐfŸ™ßñÁ·ÿ˜ÈÿäÔ¹ƒÙßY÷~§Ðÿà™þ!øhÿq4åb'¥©ÉO” ˽(æ™gi¥ÕÿÀ¾‡<ºÜ?ß%ß™ê£X´`>#l>4‘é–öwÐ}î«þ ±œÆÚÿßI˜ù“åM>»ÿøNù­þôþ:>ì1¾ÊÃþû¹<²ãþRiæ9¿äþn#ýßÃô>'¨ÿ)Ãû·»g<ý0ð‹´Y<ǸûÃô´1Aœõ9ÿ¹/.ü¿$yžÚÒjÿȳ›}w÷eño`úçt¿Ü•?=ú¿â›ïWþ*ááÇÒZS%¢¯ 4ûsÅü©—‹ú5îàŠikiùö°½£ÊmZ40¸·Ó*8ÓãéL¦RÓÙ¾~âîôºOhåŠ'—†§•mü]È(üŸæö¾²YòŸÖÉ'¯nO>\É4~µß,:¬\5{®Çì‡kœã,±Ü¸¸‰ãÇÎîþ¦cç_)O¯olEì+é4nx‰¥…±ž¾9£Õ {Oí§²™;G‡.ü×êô£ã“é>Æ{Y>ÑâŘìåË¡|Þqoÿ)4_ó¿ò6’þïáú#ÓÿÆ”áÃýÛѼëå)õã íƒ(½…}&Ï"T°£v “×Ç5z=PDZäú×¶žÊdí¸Hñ"8híÄ.ù÷‚OÍ„ÎçåXÿãâÒÕO´°'ý’n~üØ~ë/q?kçëÏcÇøñÀëCýôwûYÇ’¼Û>¿ëYߢ‹ØH²  ‘+Ä’;Hûó_«ÒŒ{ŽO¤ûídûG‹`ÜávŽŠ:¬Ã.S~ßÝ.ü•ÕeHuO,]šOe!ž$=@céÊ£ÙXþË:Pl[ó×gñc”ðÏi@þÃö½chìUØ«±Wb®Å]Š»xƨ¿áÿÎH¥¾¬¨iãõˆÌ_Œ©\ŒÆÎ/feð;J¤öùŠûÞ¡”>¤ìUØ«±Wb®Å^O¯~Vÿ¦®£ ¯ Åß+±râŽdøUó%·â2Ñ7ídý~ ‰KÕŵy¾ý)Gå¿õX!’ ýb$¸0†Ø3TÑOú¢¸7.dÇfvnhƒ_~ò¯?/€·¡Ç$sF“DÁâ‘C£©ª²°¨ ŽÄeoa Fà¯Å“Ïÿ4uBÒÓOÑt·1ÝjÒ´lÈÜ_‚•^õ™ÆþÔË KÚÍnHBqš–S_ ¶ø’€“:wÔ8¶£?éN?ÞŸWçOäãÊ•ÿ/ÄÄâðþ³ÇðáùsûS/Ë=oPº·¿Ð5w/£ÉésV1Ô¡RNçƒ)=ˆÁ1ÕÍö[]’qž ¦åˆ×Õ|g¹«v*ìUØ«ü϶M½zU­Þ WþFªÁŽNÞwÚ¬\Z)Ÿæ~Úý/¸ÿçõÓ¾H»-É¡²{íõ ‰m;ÑŒ½òõÌPòOùÉíOôOä'ž.«ORÅ-+ÿ1·1ZS¡ë굊CâÊÛCÉv.E ï<§þG2ÁFh5Æò—̽¥ÉŬ—•±™f¡v*ìUo4#,=B9¨©jÓ 2£Vño=µß—õo1úÖ†X<úÙêï°…}HëNàE{.n4µ8ǧ£ßv(†£•$Ü{ùÑüy¦þCW×|Ìž`³³kMOÓâÓÒGLòF¡+¶Æ€oC°*Õz!ÂM’mÁí²0iÎKŠs™Ÿ¸ÿªf­ã]мÛÌ–QE4ÚÏ–ïEÝZI-ÙÉ5 ™ '³†,ØáÖíÃ!aë4>Ñ<ÑâñÚ_gè¢Æ,5ÿ*}e´¿:hpÜ!â÷úr§¦NÛ¸¶?yB~Y“>³ÿ#7¥¯·sxš¹žã_-™..¡ØªÕÌVV³ÞNxÁoË+x$jYÜ1lÅŒÎB#™5óx·Ÿ|ñcæˆ-,ôøfŽÚ Y½`Š]¸ñ^!YºÝp‡Ð» ±'¤”¥2 "…~’\Õ›½#¦ùq¡¹ˆ*,ö¾¤ÎÈ£ˆWà€7M‰ÅÉÑi%|y¬’¡ò²ôÿËÑæ5Ñž?0¬ŠñIéÚ-‘7¤ˆÈ© ®ø ÆöÿåÎ`pÖãzål»D€ÖõÒt‹ÝHõ¶…äP{¸úM.V‹OãeŒ?œ@y¿å¥‰[ ½V]æ»—‚±êV=ÉúYÝšžÑÈG¹û'þ}œ1é§š¾³Â?«Ú~Æsš÷ÓŠ»v*ó=èc¿½úä Þéè)ŠêI'ö…~ŒÚh³ãˆ£±|ÛžÁíFo?½Æ>˜Çœ{ý=o¼_Ãf$­æÔT߈©ÇêÃ×ãO? Íýß=¾Ç…‰íAxÕ˃×^îIå/#_½ä:ޱ·µ„‰í$Ž»­W°­wöÌ]V²5Qܽ²žÄg–hçÔÇ‚6"~©ÊÇAß{žUÕê¨}ãyÒ†—¯LÑ€-ïÖ#±rCø Notyx¡î~{ö㲆“_#§'¬|yý·ðeÿ–ºWմɵI’^7Éÿ}DHÛæÕû†av†K—sÞÀß²ü-4µå4?«Öo䟘6º†‹60=Ä«tŽÉ–!DRh;TŒ¯C1’MlçÿÁC›S£„q@ÎC 4íÃ?Ö„ü¹Óu :Aoí¤¶24EªW«Jüòzü‘‘mÁÿßfê4°Ì3BP³âRóHÕ5NÖ[In#H8³F…€nlhi–èrÆ16kwYÿÈÕju8処+Ò/ø‹(òm­ÅŸ–ì­®âhnÖ炬+3°¨>Ç0õrÈHülöžÇi²`ìÜXòDÆCŠÁØýr,Í>QÕíu[›»+i.¬î$i£xT»!rX«*Õ…|ÙiµP1š!òßj=’ÕâÕO&(K$'# b,‹7D öïîêŸy*ëÍW:Ÿ_ë_PŽ g‘KÕ@øˆ+˜ú¸âôÕÛÓ{ªí\ºšÔøž‰ú¢@½«zy÷±¹ü½®7˜$¸|æxÒ =6ãÃÖ¯*øS2†xpUŽO#ŸÙýqí LaŸŠMðš®;·ªkqI>‹¨Ã —–K[„T³4LÄœÓá50|Ãí½µŠY4y£r–9€;ɉ§œù'CÖ,¼Ãoqyc4*ÊI#ePLd Îm5™¡,d%ö+±5˜;BÉŠQˆÜ‚ÒY?œü¢Úò¥í‰UÔ¡^[e•áIìAè~üÄÒj¼='²öÇÙ#Ú eÅC,EoÊC»Þ:}¾PëkŸ>èþ‚¤„Uc_«úÁkÙ‹~3¥¾!Ë·N»žŒJêûÏz¥©Ò®`º– ‘M©V G&à_|ÍŒ0Äñ>o ©Ööî¯ÓÎ%Ìxt~'‡ñÕ•ùÊ·š)›PÔ@ŽêtG!Š%CDmR@Øf·R'@r{a½–Í 2ÍŸiÈpˆó¡voÌÐf¹€ú#±Wb®ÅX=´ßáŸÍ;+ xZj¥c“²Ÿ¬þèÔûHœÞhgÅÜø_µúOÊö©Ú9@—ÏcþÈ_Åî¹–â»v*ìUØ«±Wb®Å^?ùÓ Ù_ù_„~òt'ü¨&þ6ÅÔvŒŽ9à ç÷nôhäIcIc<£pXwTÆ}v2ŽE~,Š»v*ìU‹þ`é7šÏ•îílÉt†9’ݤµJÜÒ´ÎJ‹£öG=F’Q€³±®úyþ£ëk¹×õY´EÞÁ,ì­îUYÑcŒÚEjÒ¹a4ò:mml³e8«ÑÃ/çzFÖ9ì~tõ*Ú]ØùsL³¾R—PÛÆ’!5*@ÙOÈm•K›ÜöFãÓcŒþ¡œ`v/8üÕµ¼/ êV<÷wQ#Bä“ÁÖ¡A=S,ƒÆ{]Šw‡$‘Œ/ý?ñOæ–£µŽ‚¶ª~ËI£}óºÃ Z?•»[/ч‡ß?Ýo‘<¹æ­;ÌúÖ¿q‹øŸÖ $eŒÍ"¸¿ù-+_ÑzÆ¡gOkÝ:÷ÿ¾d¾ _Jb‡Îßó›:‡Ôÿ!õ zÓô†£¦ÛS}øÍõšmÿ{þ¼R0ù"«ùGFŽ”­¬Rt§÷£Ôÿ³›ÕÉ/{äý³>-VCý#ölŸå±Ø«±V#ç%?™æµ¾´ÔdÓõ 5e…Ô»šõR¬ {ƒôf^›Sá‚°]çdöÀÒ‰BPŒ¹°Û¿2yÛÉGêž`’Ï[Óê4fb<;Ió/f\pâ˼n%ßbìý»Õ„K½Æ¿WȆ{å7iþl´–[$¶{R‰42¢—Ž%Não˜:9Æwêó]«ÙY4’D.E‘æ;ªK|Ã-ä:¥&ž’=ø¶˜[, ´ž©B¨PI šå˜@3Êܽa,Ю!wʺ¾z—ë«7©æûMVä)­dáaã_^)+÷ŒßНA§Ç€ŠÓË÷ ÿs Êt Kò¹î`µmèÝÏ"EÜ7®…‚€G¨Sü™–êø…:}vŸ´„L¼Xжߣô½´ *Š(ذf•óâ[ÅÅ]Š»v*òÿΛ–n“§®æââIBޤÂüÍŸfGÔKØ{!÷™'ÜùŸØÎ¬m–ÎÊÚÑ~ͼQÄ)àŠøfÙåód㜥ÞIù¢1j[$‹o+š"Ì|8²ŒI4[~aù#V¶’Îúáã‚u)$SC(䧨& ߯zØÜ2€Ž Ò‹Òî?.×è×ÓM¸“褧þFQ±hÔãíõø„|kìÙ”E$2 h^>€¡ ]4âAßšüX»`¿š÷æ×Ë"ÕOÅ{¢ Ÿ|½Gí)®Tv*ìUØ«±V#æ:Ÿ.ê1Ù- º•©é•,Ì }–ðÌÝ>“ÄÝ<'´ÞÙžÌÔ C‰qâú¸jÉǹ緷zœ5ÄeŒ}br±CÔ¬q»1ùæÎŽ{Ÿ)Öêõ·®Tê1”Gê’}ïh²´ŠÂÎ ("·E>J)SîsC9OWè’|0ŦðDd\—b®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUþf[2Úéú¤GŒ¶Óù£˜æ§è)›Ο¨‡Ì?à›¤¼8³q‘úaï~×¶é7ɪivZ”bî§ÃÔ@Ôú+›gÇ>(ƒÞ˜³v*ìUØ«±Wb®Å^{ùÍgõŸ'}` ìî –½ÀnPþ·ºÞÕâ¾â˜ùFëë¾XÒn «XQ‹F¡íî¹D¹¾‘ØÙ¼M&)D}›'YdìUØ«±Wb¨=P_6ìilRôdú¡!Hõ¸žå·_!ÇÕŒž¼?®¿£Î.4Í«˜dš}f8Ù·¥Þ“µ*h¾ŒAkó#,¸¼fNÏí‰Ä“” kýÌi’þ[jO©ùZ &»’òê)%ŽâYË4ùsâY‹@†½>ìŒÆîïÙQͤÈÈ‚A'óøóeÙ H¼á­Íåï/^j–Êæ0‰aU#„j×%eÕöÖºZ]4²G˜åñ4ó›o1ù÷AŸJÖuùý}TxùFÂ2rA¢Q¸žJ†ù:ãqvŸhi¥.sxòÝÈû¹Ü=*}Ø«±Wb®ÅP÷Ð}fÊæÚ•õ¢’:u¯5+ßçˆjÏŽx!ê¿óïËÿSÉ^oÒùômRÞç£ë6Â:צþmü{fSà’}ƒ‹ÊŸóŸ7†/Êm ÍKsæ vb>ÉH¬nê§ý“)ú1L^% ÅèhzdNÒÝ(:|1(Û9Œ¦ä}ïkeÅšg¾RûÓ ­Åv*ìUæ?™Zœõ¿­èÒK6’±*=•¼ì­ÈYŒU«QÒ§6Z,¸â*\Þ¿Ùív“xr€'Q§§ØÆ<±mùle¾b†î×SR‘ßÈË?õ¡XÊÿÏ@3'9ÍÎ4G“·í¡\XLeèþÛûÉ£éº.Ÿj?AÁ6“Q¹Û+%6º×—ι¨É9Hú¹¼&¯Q›$¿zI#¿§Ã¢c•¸ŽÅ]Š äÒt©fK‰lmÞâ6Y#•¡ŒººU•ˆ¨ ŽLdeÈŽ«( >eqÝŠ»v*ìUثɿ3?Ó|çå­/¨&"G]¦¸ILÜvhô“æö¾Ïz4y²{þÈþ×¥æÅã]Š­tI£GYOB¡¦2 ØyoæN‡å½IŠk-28ïî¥ôã•E¨™‚«'`G|!í=œÖêså"s&1Ó²ÔõË}ÃÊ’jÝJo €\‹)ŠR@ª·ÖQ=%€C_âÞ£ úp´êûF&5mêz×7.›qz ÞKko%Àn¢V‰Kƒô“Ûá$À΂?Çb¬cóØ]y'Yˆþ̯ü‰u—þ5ÅÄ×FñKÜÇ+î=&Ù¡50<ñùÎ?ÊgÍì=”ÉÅ¢ˆî2mþ–ez7b®Å]Š»Y ,ŒŠÜ]”…=Á¥+ôbÆBÅ<ż…çÍELz¯™ˆ‰Å$Ž)gt ö)HÔåœC¹â³ý¡”V]FǸÈýž–]ä­KÐôo«iWbþ)%y&»R¤<¢ˆ@âMãJW##eè;C‹Mƒ‡¸Á$™wž_¡‘ä]Ëóî™u«yVúÊÆ#5ãz- kÕŠLŒiþÄ”MKí–yô“„ËjçÐó›ï/~eëº]ž‘{`‚ÂÄF äöèߺÓZžeÂrÀb7?gv¦§qN†[Ç ®ûdú>—ùžuKKcQˆØG*µÌÐrö€X£å¾D˜»Í“µ|XË.AÂãn_ô0Á…T‚7ôØåo` ·Š»v*ìU˜ÿÎLmõ?Ì(Ô¢¶“"~1=ìm@{žK÷fH|Q‘ÜKíÜ-Žçà· ¾Ròe¡r]FòQôaº©cÛncïÅ”^ojž•¬1qãÂ4^>P)œ¬Žï‹å•ÈŸ5l nÅ]мóÌ7ß™³ëwv~\µX´¸Š,7NŽ@Æ¥)ÍÄOE͆àGw¨ÐaìèጳJæyûÿ£ä“Ü~ZùÇÌRG?™uˆ9/Ù*†W@zŠ*Æ¿@l´kqÃ苟Ú&˜ƒû¿[>ò—–aò¦”tÈg7!¥išV@„³*¯@Oòøæ£?‰+y®Ôí«ËÆEmIîPë]Š»v*ìUØ«±Wb®Å]м›Ì¿é_›zLMÒà¥Oò &Ûé9¼ìñû¿‹Úè=•÷“úÒó5ã]Š»I¼ÍåËO3é§Ý1ƒ ELr@4î(hF.ó{Bz\œqß¡áçßò¬|×*®q­¡Ñ•‡½[† £¡¿ì°ÛÔÿ¢](Òè5RáÅ–$ž†âO¸J‰M²—xìUØ«±Wb®Å]Š»v*¥qs¤/qs"Å{¼Žhª ¦äáŒI4uŒx`g’B1Éä—‰ü½ÿW;où¿×-ü¾Oæ—Sþ‰»?ý^é‚g±ÍM ŠE ަ¡•…Axå$VÎçX䈔M‚,Ô:Y#†7šV j]ÝªŠ’O€k“$a)Y=À%Ÿâ/ÕÎÛþF¯õË¿/“ù¥Ó¢nÏÿW‡ú`˜ÛÜÁw \[H²Á&é"«i±T¢A¢í´úŒy 'ŽBQ<ˆäÿh^¯£úFßÕåǨµåZRž5Ë< ÕÑu¿è‡CÅÃãCŠê¸‡4Ï*wÅ]Š»v*ìUØ«±T«Öt»Û~¾­¼Éÿ„dñ>njáñt¹aüèH|âT#î}O-ßZ“S ë0öY"J~*s¤~{ì‰~ì7§âí]мSÎß—¾SÐL’;ß© ‰ßÕK‘<Þº‚¤¢ xÈR+MéóÂèµz,xëz³çú•eäO'éî²[hÖÂD5G‘=RèA”¶ø¤4x£Ê!âä»v*–y’¬ywW·¦[+¨è Å §¬âá!ä^qù=/?-]DzÇ{%³Er¬œÝ÷±s½,‡tÏÝ¡åo^ìUØ«±Wb¯6ó5ÝÙüÍòý™¹{kUY 5N@×cÏ‚¡d~’ñ}©šʸ!ÄcûîþtÑ. Žæ m¥¯¥24oÅŠ·4e¡Üeoc“œLO")æß”å­ï|Ã¥Á)›M¶=­TžR'!ÛâUvY“£Åû L'Ÿ7¾Ñ•½ºU´¸¿Ó®l­nšÊât(—Qмd÷éàp‡W†YqJ—#êRÊÖÑÀ‚4³×!]–gaœ{T³E¿Ï—Ï'é/2?•ðz@†aßÈýñý+d±üÏó ›{û‹m Éö”[S=@*Îá׈D´ý«ªôÎQü<þóþè3 D¶òö—•hòI\9[“sÉ€=@›z.ÏÐÇKˆc‰$ôÏšìUØ«±VCÿ89"Áù©ù‡`O ÙœD>Í!¿(zm·1LÉŸ í8ðê2éËï/»p¸‹?çá$+È1‚=F¹ÕЧí#¶ƒé¤0¬åv*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»y-Ïï:ŽþŒ{VÀÿÍC7úîƒÚÇnÇ÷Ÿ÷ïĻv*’y¯LÕum!­4[¯©ßú‘ºNd’*;ŽQØ»ËÔâ׋,x£Gjïyf¯eç½öÆÆ]~[‹û÷áooåËÈP[ÕUP*i× Úi3hu”ÆÙ1ˆû¬«ë~byb(.ïõ—kiÜDfIä•bfÞŽ+ÐÔZôSìýY1†=Æõ@_»w¯iâQaj'M8†/VU<•߀äÀíPNøQ^$¨P³²'—b¯&Öü×¾sÕÒ>dMþŒÄ×Ý¿DÿÀñðùFgïýlï4ÒÎÅ]Š»v*ìUØ«üÆÖî,,àÓ­Ç%ç&™ÔÑ„IAÄò‰ü3?A„H™œÁ¶òi°Ã3Âr_øGO讬7ËÞNÔ<à —Pɨޟ©%IgG…zœÏϪŽ3G›çÞÏ{!¨í8‘„«=O ¤–úªêqAs*~Ž5y.¢;€¿²¨CÝ¿VS.Ð Žnïü5CSNCÂæg.”ˆüG_'©EÃB•)„RÌY¨¢‚¤Ô“óÍ96möœXÆ8ˆŽ@Vûý§šü[Š»v*ìUØ«±Wb©åÔÔOù8¹‘¤þð<Ƕñ™›Ü?ÝŠ*3e„œŽÂ¡j~’3oΑ ‘ÓŸÝú^»ùy©ýwB®k5‹˜¦ßįњMv>ß{ïð>í/C៫áøãúGÁߘZŸÔtµF¤×Î"¿¦>'?©~œt8ø§}Éÿ‚i~_BqƒêÊx~åú¾/"de Ì9!=ÅJÔ} æîß”ž¼¾ïÐö¿%Ê/§¨ÿòq³A«þð¿Eûÿ˜}ÇýÑy'ý/¿èóþfæïø>„Èÿù+þýïYÎ?O;v*ìUØ«±Wb®ÅZ Ab*EìXÿä[M~ÔïéIjkÚ¬%^Ÿìs§ù§²‡ œ{ëzö.áØ«Ï¿7ìg¾òÝ´vzsj†í1rI,A£r]D[þÈSQMüi‹­í8c,Û´óOç·ŠÝ4‰Y”õç±t‘¸Ž®\¨©ùaq#¨ÕUpýRò¤úÝÎi?˜£ôu—õMÌ|BqýëðÙvûp;m1™€3æœâÞìU~‹%Ìmº¼R+b¤XÌl^Gù2ÌtI+ð‹„ {˜÷ýYVGiìAýÎAý/Ðôܭ튻v*ìU‰ùßÉ«æ«hd¶”[jÖ„›iÍx°;”b»QPGL”eNƒ·{kb O ãÈþƒøÙ‰I¡~mÞÂt»AVɇ˜Íª'}RñÉÜ^~]ŸÛ#áÊ~žûxLëÊ>V¶ò¦™õ(_Ö¸•½K«‚8ózP7¢Ð\„¥oSØÝ“ .lÉïý‰þEÛ;v*ìUØ«±Wb®Å]Ч?ó…Ž©ùëçèÒgÓï¤T=J RŸøeûó&<ŸíZ¬¿×—û¢û× ¬|Eÿ? gY-1ÉÃkÅW­H:}¤ ¾~ÿþjÔ·ý!ÝÕ\Ôþ[ó¾Ðñ?É™þ¬ÓGþ%ßã?ÍOú–ãÿ¤;¯ú«å°;í ü‘ÙŸêÇý4â]þ3üÔÿ©n?úCºÿª¸þ[ó¾Ð¿É™þ¬ÓGþ%ßã?ÍOú–ãÿ¤;¯ú«å°;í ü‘ÙŸêÇý4â]þ3üÔÿ©n?úCºÿª¸þ[ó¾Ð¿É™þ¬ÓGþ%ßã?ÍOú–ãÿ¤;¯ú«å°;í ü‘ÙŸêÇý4â]þ3üÔÿ©n?úCºÿª¸þ[ó¾Ð¿É™þ¬ÓGþ%ßâÿÍi~òìhÇ£}VàS¿W–˜þ_ó¾Ð¿É]˜7ñúhÿÄ»üIù¹ÿVHÿäAÿª¸ø:ç/òeªŸŸìwø“ósþ¬‘ÿȃÿUqðtÿÎ_äþÊÿU??Øïñ'æçýY#ÿ‘þªãàéÿœ¿Éý•þª~±ßâOÍÏú²Gÿ"ýUÇÁÓÿ9“û+ýTüÿc¿ÄŸ›ŸõdþDú«ƒ§þrÿ'öWú©ùþlj?7?êÉüˆ?õWOüåþOì¯õSóýŽÿ~nÕ’?ùê®>ŸùËüŸÙ_ê§çûþ$üÜÿ«$ò ÿÕ\|?ó—ù?²¿ÕOÏö;üIù¹ÿVHÿäAÿª¸ø:ç/òeªŸŸìI¼·s«Þ~g vmª¼oõˆUx…¥ TÚ§ª€zæÇ b y9½¥;7‡¸^ÇüïÖö±à]Š»yçæƒ­K¨iþfБ§¹° ¯ n¾›™Õ?krC¿L!꽟×açƒ)¡>¾ñD_O&9ªj>sóè·ÑŽ–m`IÌâ)Q€W“¼ü=~x»}6ŸGÙ÷—Äâ5¶àŸ€{×ì­–ÊÎÞͲÛÅJÇ©¨P ›'Ì»É?5|Zм—Nÿɬ«7ë0õÿÝü_¥à=ýô?áRûÃ<Í+ôS±Wb®Å]Š»v*¿0|½wªÛÛßX!–{Nk$**ÍPÕGréï™úâƒÕó¿oýŸË¬Ç ØG±ÝÄs1=Þîï6 ¡y§Uòáx-½»7)-¦S@Ý Pƒ¶l3i£“sÍó^Âö£UÙwQ‰;Æ]ÿx?Šgº/晩J–·±›‡¢«3„±Úœ¶"¾âžù®Í¡”EÃéý‹ÿ6ªCXœR>w÷í_^m~aÛß.›§cq,-jÜgX¤d9 !Of§ßކC‹„Žhÿ‚Ÿ8ÓÇQ†r†j\$LºíÜ~ô'对=â]é—“4ÓFDð´Œ]Š+бè >üž¿ øvÜó ˜2ÈÊCÕ6k‘÷ù¡ÿ25»‹{‹M6Êw…ÕZyÌNÈO#Å*G9.ÏÂ2!Æÿ‚7mdÇ“ S1 qK„‘Ïhò÷±VÚ=BÏòúîþ{™íÐYÒF•ˤfET I¨¨ßéÁ#œ6 ºhj0{?“4ç.<• LÅ(ô±¿Å‡ézÇ™%•ì´û›‰î®×ÓÔwp+È•ä~·Úì3;&,`YƒÀögkö”äqaœå<‚¹’{ö³·¿ S¾‡Ìz Ò5ëÜZܿƒz¤ò§Z:1÷à ڈj×aíÎÊS)shžs´ }èÝÆÒ2…‘%&NL@‚±a¹ý¬´fÄvÙÔ˱{g eáÈ ˆÜKÕg•Ñâg:Ì¥¿‘nãÖ'â428PŠHûD6k±œÃ„P}+¶0ê±öHêgÇ’…Ÿó£·™ý~Ö äëÕ/ol¬öSªW³òB‡è`luSáù¾i솀jóeÂÀ÷Ükäiù}¨?_ú”¤¬wªae;RTø’£Çb¿NW®ÇÅ îvð?í¦×øRØe?ç Çéÿ05Ô|À,`«¥š¬(£zÊæ­O}Âýèaà =Síþ¼êµã 7Àˆþ±ÜþðAyËOM.úËOO÷E”*Äw~NXý,IË4“ã‰=å×ûa Lø°àÅñ¹Yø›/JòWü¢úwúÿ'5:¿ï ìÆÆfqÿt^IÿKïú<ÿ™¹»þƒáò?þJÿ¿{ÖsÓÎÅ]Š»v*ìUØ«±Wb¬sò;ýèó/‡;=þ™ó¦'æ¾Îþó'¿õ½ƒ ¶v*‘ù·ÌÖÞSÑeÕ®PÊÁ–+xâd•êUk½'Øbãêu8‹ËÿåfþbZšå d*Aú¼ÑÇÁŽÄJX‘ZìÄpº¯ÏçˆÇÓîz懫ÚëúM¦±e_«Ý§5ª°%YOº°*p;Œ9FH‰©†-®ÅVº,ˆÈâªÀ«v8 ‡ÍžHóF· Ay•¥¶¥Î!T‘½6ýØ=}ü22ˆ.»°{[>–2ñø€‘ß·É•ÿÊÈó‡ýKÈ«Ÿù§!À;Ýÿú'ÖÿÊ9ùKõ;þVžå·ò´…FÌ~­tûÿ±ï_ôGÚútçý,˿ǟ˜Ÿõ+IÿHw˜ðŽõÿD¥ÿ(çý$Ýþ<üÄÿ©ZOúC¼Ç„w¯ú í/ùG?é&ïñçæ'ýJÒÒæ<#½ÑiÊ9ÿI7?1?êV“þï1áëþˆ;KþQÏúI»üyù‰ÿR´Ÿô‡yï_ôAÚ_òŽÒMßãÏÌOú•¤ÿ¤;ÌxGzÿ¢Òÿ”sþ’nÿ~bÔ­'ý!ÞcÂ;×ýv—ü£Ÿô“wøóóþ¥i?éó޿胴¿åÿ¤›¿ÇŸ˜Ÿõ+IÿHw˜ðŽõÿD¥ÿ(çý$Ýþ<üÄÿ©ZOúC¼Ç„w¯ú í/ùG?é&ïñçæ'ýJÒÒæ<#½ÑiÊ9ÿI7?3ŸâËJ¨z´ºåôÖAú±ázÿ.v©åƒýŒÿâþ1üÑÿ©r?úDºÿª¸ðǽ–»[ý@¥ŸüS¿Æ?š?õ.GÿH—_õW÷¯ò×k¨ô³ÿŠwøÇóGþ¥ÈÿéëþªãÃõþZíoõþ–ñOXÿœ ¸½ºüøóEΣ‚þ]P{ˆB• !ÔìK/$Š–…í “žiË á‘&Çq~„ápŸÿÏÁãU±ü½½ßÁq«¬gµmÔ|Ð`!5`†œ«âŽÅ]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb¯%›÷_-ß×AíJX͹¿Ñt?^ÔoØþãþÿö½32ž5Ø«±V!ç=sÍZDÖ±ù{NúôS£™œ[Í;FêE7Œ€*|]÷cè´¹„Žið‘ËÔüØÉó?期èü èÂÑÇâÍL.ãù7²Æþ'û!úú_órR,xµô"ù—4Å)Ù#œïâCÕp«1†ãÁ¢o…›î<†nr—ÝCáÝ™ž}‘Úcüœ¸eýS±?/Pø*]ó_›™#$Çuqé£ øÁ܇É–þë¸6ꌻcµˆ,“¡åµÿ¥ôŸ8FùNú(׌qÇ¢ŽVEf«Ho(}Úüq‡eeŒEþš,#òÍTëó’*VÒB¾ÇÕŒ~£›Ñú½óøÄ|ü±ËýÔ¯Í>£§šn%pÍ3³~¢ôðO¸Â¤~åž@Y_Ë:²Aýó<¢?õÌǺ¼Hßãv¯`c9vn Cê&UïàÄ<£-´dÓä¼ B$"­Ð9FOÉÈÌíP'§‚öK.,}¥†Y~ž.½ôDÙSÛ™•\…¤ÐTšôœçߤ% 7&’/:ÿÊ/¨ÿ¨Ÿòqs#IýàyŸlÿã37¸º òÛþRÿ˜iâI›.Ðþïâù‡ü?ã@ÿR_|P¾m´“CóL³Ûü/mØmBÇ‘§ÉÁÉéeÇŽ¹Áö³K-jJpÚÈɉ¿÷@¯òu¬ºßšRêçãôÝïnŃTуW. t=ÍžÈie¯íA’{ð“’^ûÛý‘ ÿ™?ò¯üÃEÿ|gÿwñr¿àÿú‘ûäÏ|•ÿ(¾þ£ÿÉÆÍn¯ûÂú±Ÿñ™‡ÜÝ’tתz}oþfæïø>„Èÿù)þýî¿X·ÿ~§üÎw„¿Lþcó‡ÍrI•àêÔëăú°Ê#.Dø³v*ìUØ«±Wb®ÅXçä`,ÞbœÝÈöœ|võÏñÓŽOÍ]™.)d#‘?­ì»wb¯=üâÑï5O+$öQ™M„ëq®•X¡ Xÿ’8Œ.^ÒŒ±p¹äô_Ë­"ïEò~e|†;²$šH˜Q“Ö‘œ) QãÙèqbóe8¹nÅTo6´¸ÿŒoÿ8±—"òÉøæjŸñž?ø†U‘ÙûýÖOë¹éÙ[Û»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Цÿó…ñ ¿?<÷xM-3P€(èCê–ÛÿÉ1™äølÊõY¯/¼¾÷É:·Æ¿óðkuo,ù&ï‘åýüA{,±?G YEçй’ä;Ub¸®r¤nø¬ÅàbìUØ«óž¥æ=&ÎÚ÷˶Ÿ^t”‹»oI¥&"§p†ØŽÙ“¦„$H‘§oÙ}>i˜æ—Û­þæ;¤~ph·$C­[K§\ÅÜZ A¡­qòâs#'gH}&ݦ«ÙLÑß„ÇÈþ¯µéÚ¶™«Eëé—q]ÅÜÄáŠ×³¸>Ç0gŽQæ)ç3éra58˜Ÿ4fAÇv*ìUØ«±Wb®Å]Š»v*ò]sýóƒO—§­{Žü¡x¿†ot÷Ok¤õvLÇq?x/LÌÇv*ìUŠùÏ\óŒ¶CËÚw×Ús/¯û™g)À/ˆ"µ=|1w}¢Óçâñ§ÁU[|ûؘ׿6.éèé¦ ÿ˲§¿û¸œ.ïò=•s¿ó¯îOo!üÁž÷AšÒA°‚ßô²1…@œßnAtöÀëpÏAen\ù ~Ös‹Í»yF®>©ù¯§eºD'ß•±ˆu÷^Ù¬ˆ¾ïÿ=O£¾qù‰~’ÎsBýPìUØ«±Wb®Å]аß<ùwYÖÖ4ù„À7±$%_Œ1Øšm¿Ñ™Ú<ð‡?›çþÛû=¬×ˆË ®1ÿ'ËçÈž›Õtæ^~4/4Ú“v7¨í£¡í¹JŒÙxØÎö+‡Ú˜I€Å”_óD«ìÙ9Ð?/õ;ˈæÕ£6–*C:1¬€~ÈQÒ½ÉÊ3ë¢Grô]ƒì§>A-HðñŽ`ýRò®žóòzº"ÆŠˆ¢€ª£`Øšb_p„@P3üÍÓ»]V:r¦)‡rÑ…½þO£6Ý’ÁsãŸðKìÁ Øõþ1Ã/|y–ß©ùe¥sšëX|1«ÀOó5ÏÐ(>œ£“aïøv_òjd>ŸD}çy}”>%™y¦Îæÿ@½´´ŒËq*¨Ž0@$‡SÞƒ Ì 4„f äúµLš\xǤóƒò—µ'XžçQ´h!kg\²±’6á'°9›­Ï Àz¼7°žÏë4zÉO63œd]Ž|Q=‘M<ÿ¤j:½œztwŽVg TP¥~"2XÀ›.ïÛÞÉÔkpãŽq˜È“Ë»ÍSÈ:V¡¤é·0ê0%yù¢’¦«ÁE~{Œܱœ£g°}•¨Ñé§ ðà&v9ráÉ™ÿ/îd¹—PкJKÉfHFV&§4ö$S¶diµÀ —Íç=¦ö$²Ë6’ˆ–æ¨õáé^[WDƒônxY¼mDzi$„D„t*Y¸Š{fO„oaå»k-b0ÈDy#Â=ÖxYõ\ù:}>ûÖ®èªgvÔ€ÌÔ€œÖÂpAÔµ½Ÿ®ËØóÖ²f rëêÉØšæµ ò7—5­+ZkBÑ €Á",„r,¤„Ÿ ÉÖg„á@õyaýÖèõ§&lf1à"ìs±ÜSO?ùz÷XŽÎçM„Íu 4r * ÅAøˆèGã”èsˆX—'síï³Ùµ±Ç“x§A}'~½Ä}ªžAòýÖku>¡£ypáB  Ûì’7$àÖç A·Ø>ÀˡŒy£Ã9š¯èwy'ä<ùsZÕu¥¹Óíx¡pÈ ÌHøˆñËôyáQ=]·ÎëušÑ“3(ðv9Ùï,ÃÊÖw6•¥Üf+ˆ•„‘’ »Õ`êd%2G'½ö_I“O Å á”A±þqyË-åĉ§¹G–FSÎ=ÁbAûY·†¯wƵžÇö”óNC £"yǿޡþ óGý[Ÿþ?ù«%ù¼}î7ú í?õóëf—ú«¤M~Ú•³@²¬B2̧‘RÕû$øæ»4f ·Ð½€ìMVŠyNxq×.—ÜK:Í{énÅ]Š»v*ìU}7Õì®gééE#×ýU'%d]—ÃÁ9ÿ62? €üŒ·ã¡êwTþöíb­?ßQ+uÿg3ó§dGÐO›Õ0;wb©/™¼Ó¤ùNÀ_êŽÔvá€ÒÊÝHPH¤šbѨÔGnO>Ñ2/§ÕRI´8ô»§oƒQ6Öç‹7w‘uùïůÀeôðžúZVVPÊC+A ƒÜbîÅ.ÅRí~Q…ªNiH­.\ÔÐ|11ÜâÕ˜Ô ò/4üœŒ.ÞÊz=ë¨êÃÿŽU“›¼ö*?àÓ?Óýz.Vö.Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb©÷üá ^¿æ÷æýxñ´™=:V¾¶¢µöááß2cÉðÞÕ•êréËýÑ}á…×¾Nÿœýµ/ù]åÛÝ©¿?å~úÆé¶öýÞø²‹Æ´Yº>Ÿ(èöÐ0ÿeœåò ‘÷¾9¬e˜þ‘ûÑÙØ«±T=íõž›l÷—󥵬nYX*¿sØd£#A·åŒ$÷<NÕÐÜk^™£E­Í©]<–O4F_J0Ì9ªÕiß7³Ç´I— Ó3éO<“ÈqGÕF¬íµòûÙÏ?.µ=R^Õ¦HgU%Œ_¢•<Ü W¢×ç˜Z½dgóyÞÜíüyñœXÁ#oQòîNÍkÈ;cÞmó†å+4žíL×SÔ[Z¡œ¯RI袢§ðÌ>žYNܧeöVMdÈŽÀs?ެþV—šâA¨\yp Ðú¼.JŸ ˆ)ôñÌßÈãä%»Ñ¡­)<7¯»Ó÷sz7—õû2i‘êz{Ud¶x¤ixŠæ¿6#ŽT^W]¡ž›!„ùýã½4Êœ7b®Å]Š»y7æú'æ–ïÎÈßVFù%ËrðìùºìÓè#Íí{ × Íë¹ýKÌ÷v*ìU'ó>»—4kQÓÔt¢CiÎG4PO‡s틟ٺ©Ì1¯Ÿ¹ç\üÒ{3æE_÷Õô½88~× ‡÷œiûU­;Ó Öf øÇËœ¹ûù[Ѽ­¯ÇæM MSÓ•«ñP’¦Ì±ê=Ž“í= Òæ8îÇOrs‹¯v*ò¿Ìuú‡›ô[¢0øˆf«¾C,ny>£ÿwƒšù™c/«û‹6Îqû9Ø«±Wb®Å]Š»v*ìUØ«ó‡™çòÚÙ›x’g¸i9,œ¾ÊèTжeétã%ßGö¿Úl–1DHÌËc|…w{Þo­kšŸ›/ Vˆs»¶¶„»úÔ’{æ×â‰|‡¶{oSÛà wåFúþ“ú¹åý(hÚE®Ÿ·©ò˜Žò?ÄûüͶi3äã™/»û?ÙcC¤Ç‡¨¯ëÏÛö&yS¹v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±T“Í÷?UòÖ¥%iÊ#üŽ"?øÛ/ÒÆòö·QàönywLJý7§ô§ß”VUòE¤„PÝËq9ÿ‘†!ø Îñ>Ìalë`ìUãÿ›ò髿/-~’˜=¤.úÏ‹ú³Ì¼ÜPPòËJ×a…Òö™/—Qä£ù}ä‹ý ÎßA6sêÍ4bÔY*HèC+ú`qïÛ=¡<2€«òz‡–!k_/ivrL“Ímk2¼ny¤aHV´éÛiÅB#¸&Ø·;c¾|¸ú¯“u¹+NV’Åÿ#‡¥ÿbãk%X¥îbŸ•0|Ÿ”§Ö&žAïGôÿãL¦|Þ¯Ù|: œd~Úý Û ôÎÅ]Š»v*ìUØ«±Wb®ÅXך¼ë¥ùSÑŠé^âöqÊ+hiË…iɉ; ìžÿFd‡ÁµrâÉ#ÞOÞû‡ ŒùÇþs~ÀÞ~EÜ\H°Õ4ë’Ag·Þ¿ñ—¶)š|™7¯å=ü,àOîÐ'ðÎoR+$½ï’ö¼8uYôÚm<Ês±Wb¬Íúÿ‘u[)4]_VôÕ&S2Û¬ h[uøQ€ßc™Ú|Ybx¢²´:ÜSqã½¶º­þ!+°üÁü¼òÕ¿Õt[Iý?Úh`ä>.ó:³}9dô™²‘s3ö¿S.,²æy{€=GÕ Ö´»]VÙY!ºA"#ÓÞ”4$vÌ 0‘£ÌêôÒÁ’XåÎ%qм§ÎMgæv‡&·OÑèd§¤œ¼KWj 8ò¯n»fÓM~¸y½§d‰žÎÊ1}vysþÑtõGHå’E‚®Œ9+) ŽàŒÖƒc›Ì¿)RH¯¼ËQ¼Zr\F!ŠE*ÈÁ¥H=^<‡Ë6=¡Ê=ôõÞÔa„“r£uðý<žŸš×v*ìUØ«±W•þsÂñ&‰©Ç³A,É]ú°G_øÍ¯fKêgìŒ9`zúGéz2¤ðÇ<{¤ª®¿&´y)ÀÄz*bÁØ«óÎ…qæ/OegCy$ð!4ÉZ­NÛ‚iï‹·ìMttÚ)}'cñFiÚ]Úùf Q˜ ¯ª}Vi¡q¬|U¨ïÜïL\}F¦RrÀmÅÄ÷ÚÉÞ[>WÒåÓšqpïq$Í"Ž#â ª(kCÅA8·v¿hþo(pìãâY.©Ø«Ï?7¬}mÒùEZÖã‹™H?ðʸCÕ{'Ÿ‡<¡üá÷~ q¤^ CK³½­LðÆíþ±QÈ}¹Íå‡ ˆ~åì_æt¸²ÿ: ükµvÅ]Š»v*ìUØ«±Wbª7–·kÂêçAÑeEq÷08c"9Œú\Y…dˆþïYm§iöD›;HmÉØ˜bHöÿbd”¹›jÓv~Ÿ÷Xãêĸ"r.c±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»a?™—žŽof æ`HñH–§þ®gö|.d÷Îà•¬àÑÃç’_dGë1zÿ–ôó¥hfšÃŒ–ÖÐÇ ÿ‹ðÕÍÃÀà‡ î ¦-ÎÅXœ4 ^ÜÅqæ×‚+ÓŽ–éà“Ó H¢«­EIÞ˜¸Z¬XI¼•~ö:¿”IÕíÅæ¨Ü¼%‚xgŠ£ý;­…ÆþLÅ1q%åÏÊHü¹æMjU® ¶2lðpfå*üjälH?g¶X;7Ø—'¥bíа?Î ±m䛘kCw=¼Þë̼]iʱ:Uò=¯Ôü¥¤CJr·Y©ÿ‰—þ6Ê%ÍôÁÅáèñèßÏÒÈ2.ÝØ«±Wb®Å]Š»v*ìUØ«Ìüü—Ú&º¾gŽÐÝØËa-ƒ¸6Ò¸p²t4û_¬eÜSÄûCš}Gæx¢`aýS¾ÿoÞ?%¥×˜oü¹ ­£CaåÕ™îoŽÂG‘Ìœ}ªmZîÇ%-­ÕögªÉ€F5rï$Ý~<ËÚ2—ÒŠ»v*¥q(‚ g="Fs_òEqa’|1'¸='þ}óbÉå¯;j„mscoËSo’‹¿÷Ý;}9”øŸebÅã¿ó•:oé_È:ÛVŠÚÚìÔ}RöƒØöC_lR~XÜ ü•§ Õ¢3ÄÞÜfr?áHÎ\+)|ÃÚ8pë'çGì ¿1±Wb¬Í>GòôZN³«Yi‹&®ñÜ\‰¥sê5]™P±ZŠ’\ÎÁª™”bNÏGÙ½³œåÇŽS¨X9{ù°í?]ò^A“N¹‚3­eFŒÛ“3Üž\$ñ ±¯-†ÞÙ—ÛÈH" :ÔøÚƒ2t¦wî㱥¨9<&¸ÅwÁŽXþnÃ%Ô+ªéXi×-HoK—Z¹QAÏiï™2ìó[J˵Íì©>A9qüö½"8âBí*™[œŒ m@9:š+šâ^RR'ŸEø»v*ìUØ«üÚ²ú×”%œ ›9áŸÜL'þNfwgʲ{ÞÙ|ܰ?œý?¡äËϯyWIžµ"Ý"'ÄÃû£ø®nÜ.ØÅáê²;ùïúSÜ]c±U“4‹ ó•UŠ!Ø3°úN, "ù¬¯@ÔŸžç±´º{­7\·]AQØ1ŠYÕ6ûŠøbé5ú~=œ¢#,Rà÷€kïûmè¸MتMæ½4êþ]Ôlr–HY¢2GûÄK(ÅØv^§ÁÔB}ßÜv,'òâÿë:Y±¬–R²þDŸŸ¼¶iõð©ß{ö‡üµþ.„â<ñH„½Cíâù3Á{÷b®Å]Š»v*ìUJæâH$¹¸N”¼ŽjB¨Ü°Æ$š :D0ã–IšŒE“ä’ÿ|¯ÿWÿ€“þiËÿ)“¹ç¿ÑŸf«”¿S¿Æ¾Wÿ«ŠÀIÿ4ãùLËþŒû3ýX|¥ú‘ún¹¥jí"é·+;D*°â´û@xey0ÊP§eÙ½·¥Ö™ áçϯ¼Ã+v®Å]Š»v*ìUkºF$Œ4˜ÐI$ⱜÄA”¹)6›æÍV¼66W<®J+# .ç`+—äÓNÈÙçû7Ú½³1ÅŠw.–â®ëþÔï(z'b®Å]Š»v*ìUØ«±Wb®Å]Š»v*ÀõHĘº>†(-Z6zŠô‰~ôP3sÙð¨_{â~Þjÿ1ÚPÂ9cýçÔ~Ê{Îg:×b®$S°N*ðï.ùJ?yŸÌwÞc¹—•¥Ç¦±BêògU܆øP§_è0i†|“3<Н”ì®|Ÿù¥'•ôË—¸ÒæSõ…r+Ãêæt.ƒ’š Ó¿¾,´Ð8µ6?e½³½v*ìU俞M%¾‹£ÅñIs<“p(4ûýC‹¨íReÃÌ–{in¶–°Z§Ø‚4‰~H¡GêÌgÖð〈èù+bØìUØ«±Wb®Å]Š»v*ìUç—_˜7Vw~g’D„Ùi&;kXÒY.™™7vRC3t wË89<~_hçŽz‚@áÇQˆêe¸øŽdùo#ù³]Õ59ôO0[$7)l—°2/é1@($nHî;à”GFÞÁí}Fl§x€xx‡M¶ýcô³ÜƒÕ»v*ìU)ó4ÿUòæ­84d³¸*Êô˜/O|1æàv®N 6IwF_sè_ùÁ 7ê“W׬£–£®ÞL­µJGmm‘ºøæKá²}?ŠŸæŽuÿË_8hмäÔ4]NÞ 'Ô’ÒEB®á¨F*›ß“W^¯–î­‰ø­îÞƒÁdüCf“´cëÉóÿkqÖ¢2ïÜKÑs^ò®Å]Ф:çœü»åÙ…¶«vbºd,+ŽÌ¬HR;§/ŦœÅ³³ÑöF£R8±ÆÇ+°ó›ß6þY5ã]ÛyuîîÉ,O¤‘ÄÄnINd{š¦l#§ÏTeAêpö_hðpË7÷’~uúYç’¼Ùþ,´¹¹[c´‹C‘uqÆ»7Àé˜:?†@»y¾Øì¿ÊN1ãâ2øÜ²ŒÆtîÅX7æ®{«yi^Æ6šK)ÖâHTZ0ŒŒ@’9Wå\ÍÐdžý^‹Ù\0ê*F„…_žÌ;ÌÞxµó®‘kåÝJ›ô”ÒÄBB±¤\ '¤-f`ÒœR2‘ÙßvwcKE–Y²d ¿ðw{o%žŸii+s–b‰ßù™);ø‘š‰›$¼.£ žIHr$”NE¥Ø«±Wb®ÅR¿2iÿ¥4 KO¯=¼«ÿ‹8’ŸðÀe¸'Ã0|ÜÎÏÏág„û¤>]X/å%÷¯åû‹&5{;† ðŽU ?áƒgH]ÿµx8uÎhü bòîÅ]мÃUü¾ó&¥­ê’Û_Çe¤_HÑY“ÕZ9E Ô5ÝO\6öZ^ÞÓâÃŒJS€ù|Nãà­“¡~W¤:­ç¯¨^Ý7Õ–áQR8øšŠX‘P:üGnصÏWŸµ‰Ç„c½u?ƒ5ÒüãkS\A¥Ý-ËÚð3 Äs­(Hôíçµ]Ÿ›$xx¹&˜¸NÅ^?¥'ø_Ï÷ú3wŽÑhß½ŠŸ J|ó]ŠÜý+ÿ~Ýýô##¶XðŸëÇ—ÏôÏBÍ+ôS±Wb®Å]Š»v*”ùŸþQíOþa¥ÿˆœ»Oýä}îÚoøÏÏýI}ÏÑt™µ½B=:ÝÖ9dCÉ^#‚–==³{›(„l¿=ö7dÏ_¨ DL¯sËa}Gü« _þ[-¿ä§üÓ˜Ê1î/kÿ&ËWþ©ö_ñ,ŸÉÞU¼òä—ou4R‹…Œ/¥Ën‰¯ _£$OÄ_É"üÅó%ÿ–ô‹iôÇ y=ÂÆ *¸ôÂ36Ìzd -Õ{KÚy4˜c,f¤e_ ?±•ÚúÿV‡ë$ž ëøŽT<ƒ¿ÅÅÂ8¹Öþõl[мw[—òÂóÌ’êWw&OT¨¡Œµ´®Mx–¡#âã×¶Z8©ó­tû+&¨ä”¥w¸ÒOÊýõÍ—ùFßC½Öõ2éZ›j2]zqñdt6è@<>0¤Š¨ã¶ÀS#+ªzÇǧɟ.£Oʇ"8Gvþí»€fy¤v*ìUØ«üȹú·“u#Z4¢(—ßœªü-rPæè}§ËÁ¢ÉçCæCìÿùÄÍ$éPÖ“]Çy{!ñ7³IêÝe3!ñÂö¬PÓ*º²:†F2‘PAØ‚*ü®ü»².y»Î>Q–¢M6òK~,(ÀÙ\Knõë¿LÕvœv‰xÿl1zqÏÞ>ïÔô¬Ô¼+±Wb©V£å­W»KÝNÂ+«¨ÐD(-D X VIí–Ã<â(stý£Ÿ La3MìóÌg‘|Ñæ+mnÉ iæ-i%¼*¬Åq¢²•"žæË.f„LK×ët95úl2Å+¡½ž»_Änš~YI6¡¯y‡Z´ít+·¬10¢™K–j…'•:W*ÖF'r/hâ1àÊG‹$Fþêü|žŸš×v*†Ô.šÆÂêõ"3µ´RL!SBþš–â æ”ÉB6@nÁ‹ÄœcuÄ@¿{Ë¿Çq½\ùwÊ‚Ý{ƒo,¬Ã®Î¢0Oß›?ÊãJoaü¤…G6{ò°?[3ò»wæ/G{,s_,’Ç9Œ¡ ÉU”Bøæ¯„èrt=·¢ŽŸ9Œ¡LŸ1;±Wb®Å]Š»xÿ“‡ø{óZòó|0Ü Ò¼­ßñŽt¸gÅ^ß¶?Â4óu_ÜÙ©eìUØ« üÉó© i6í¥·£-̦7¸â¢…-E¨ ãˆzgtµO‰¸ˆºb?—>fÔ4éõWQ7Wë š P^âG4åÑ NAÃnû´:ly•ìWmçí <瘋Œ«a[P/8ódó/˜õY1  @è3i¥Ã‘ûWšc´s#õw¢/´5êÖÏæ ÈšXÝLÓŽb.µXɨP: Œ3bà^·°»WYŒërÄÈÅÏ~(ôû¢7òû\»¶ÕâÒ¤•žÆè2¬lIXÝT¸e¯JÒ†™^»1âê°·›®:s"qä±GøHîå_&Cçÿ3Üék•§¹Šêtõ&™M#&€)ìI~Ù¡Ó‰z'ªö÷ÚlšA>Ã9‹”‡1B»‰ß~ƒÞÂ4¿-yƒ[F¿³‰™*H¸’@œÜuâXÔš÷͆MD!±|ß²ý›í x9±D‘Q5gÈÏ¿íQÖ/5Ô’=?WyVæÌ^dóâÛŠ°?ð8qFãÈ´v¾¯\%:“!,[oÎŽüúùµéz±òrÄ¿Õ.O"wÿvwÍVaûÿˆ}‡±$Oa{øy?ß0O"Í3ù¦ÁZFe>½AbG÷›`üu|ËØ|Ó=©„¯û\‘˜SJžcuIWÑ‹`ć!¡Ãrÿàƒ–qí#Ó4z'š¼ÇcðFšÒÖ+eyÕbPŸ±öÜ÷93›3]\<}‹Ú½©‚9¨ÊˆŒlÖÑéùnz›Yåj÷HÖm­ÄŒ-'•a¸·bxümÇ—Щ5êÂ'zµû%ÛY´ZÈBÏä#(ôÜÕ×xùôz?›üÆ|½§«À_\’–áº-YÈïJ¼Nj´¸»íw´_ɺpa¾Ií.ù|6øÀt¿.ëþqY5+›¿Ý*²Ü37&îFÀ xfË&xaô€ùf{=¯í°sÏ&×W2MŸèŽáðÈx®õ¿#ëÙÞª„4&£nàÆ•#g…¸˜µZÞÀÖxdì9Æý‰ëú0~!ìv×]ÛÃu å è²F|UÇ!øÑÊ$/ÐmDscŽH}2CÜwUÀÜìUØ«±Wb®ÅXwæ&­õ=!tèúEûp u!¾óEûó;A‹ŠwÜððCíoH0Äú²šÿ4sùì>oLò6ƒþòÅŽœëÆè§­wãëËñ0?êì¿Fn_7ÒaðñÕ‘bä»cqòÕ—œ¬—D—PkYàu¹ G5âȦHͮ曌\MV˜pÝ<³TÓ<ÿùdmä±Õ}}*yE¼nQzŒ Txf¨R@;©úpºœ˜óiª¥·ã£Ùü½>«u¢XÜëq¬:¬±+ÜÄŠÈ›p ±$)ÈW®y€ÈÀsLñmv*Ó2ª–bTI4çäËŽ,ú¥gñÜçËGÙ¸äÊr}ÿ¹ýlɶ^lµ¿¼o2êðß3F£êqËÍàzÔ@ª«Q^™©–2§UÚù´³„| f;ó#ŸÆÍ³<ÃtÅ^g}æ/Ìûû»«-E[X¢’H’éã¡`¬T:½Ã*µvS›(aÁ ¥o]‡AÙ¸ãdÉÄH¯ôGµ:ü¼ò®¡å›¶ÕeW¾¾•e’4nJœAêÝØ’kL§Yœd"¹_ÛݧU8øcÓ_&e˜n…Ø«±Wb®Å]м“ó!@󆋿˜IÅg+ÜÀÔzÿ­ñú3sÙÓ¸˜÷=·³çóL¸>Ÿ_"˜¬®¡Ð†V©=l4ŠÙ¼PìU/Ö´í?R°’-JÓë°Eûõ·iž0H ºîzuÅÊÑê2bÈ %ÂN×ïy«yûÌÚÝ4ï'i_W‚0#GTõ]l*H §ˆúp½xì-6^§%“ð¿÷Å:Ñü›®_éš…ŸœoZd¿h¥EIŒ“A$DïÈ‚‚µ§Q×jûc<–š5Ác•Ûñf:6“k¡i–úU—#mn)òrY‹±$¹$âè5š©j2’æQø¸ÈMSNƒVÓ®tÛŸînchØõ+Q³pw¹]D°äŒãÎ&Þ[ä[Éô­FûÊzÃ<2;@B˳…¯b(Ëôæ·´0ò~´ÿ´É§'iŽ8¾éøIŸæ­ö7b®Å]Š»v*”ùŸþQíOþa¥ÿˆœ»Oýä}îÚoøÏÏýI}Ï(òjØ>¿êB´ã/1pÇ^•ç·^™¹Õñpo‡{×Àg0©_pý&¾­žõ%¾´¿ølÔqfþ—Úû7åûùº–4~œÚ,|­ô“jµýãÅjbè9èÊòqó•ü]§gKE†›ÃHÇÃîºÞñï7ÊK©Æcú†o4¿Ý‡À=­ÿ,ÿÖ{8iü@}Sµ8f‡ø¾/ÐÔ?/]8CÆ<£ÿ).›ÿ‡ê9¾Õv_ž}’ÿ,ÖL¿1b‘<ÈîÿbXbhÿÕ‰üAÊ´÷nßþx¥Ò$ò”bG»—Þ Ð|Ÿey Y%«¯;x’)ârIQ‰åQšÍT fo«êžÈk°çÐbȸDFC¨#c~þl óþÊóY‰-d{x½9äBäXž5Í–‚0ß«æðD×aϬˆÆDŒ#R#¾É¯‡é¦_¡ÿÊ¿óuÿ337÷ÿ÷݇ÿ#þ“ýóò'ü¥zü÷ÿ¨y3e­þèþ:¾aì/üjáÿ?þ™Éù‰ÿ),Ÿñ†/ÔrîÜ¿ø!ÿÆ‘þ¬^“åp—tÀÕâ;{­sU©þò^÷×ý˜Ùø?©¹äy–P:}y¿äþo#ýßÃô> Ÿþ4¥ÿ?îÙoæ”RúÚlÛ˜J̃À0*ú³ ³NÄ=×ü1K¿†¤>;}ÿ¡%Ð<³®kV&çLÔ"ŠvF…¦™®êˆFõ®_ŸQJ¤w°=š×k°qàÍÄá2˜ û„HÝ/5¹®¾¯6£g%ïþ›Ï+IéÔ€hc­+è`sr{­É—‚Y±Õќ̫¿èºzN‡e>›¤ÚX\²¼öñˆÝ’¦ž€ Õf˜”‰__ìMôºLxfA”#F¹}´˜enÑØ«±Wb®ÅZ$I4rN*MnXG•¬ÛÏ~~mN@[EÑÊÈ•û-é±ôWý“‚çØS: 6.Õù÷¶;DöŸhK'ù8mpåó>§ºåíŽÅXÍžtMGÌóùZÑ™î G->Þ“KâNäROMŽ.,5–CÍŽyËò¾ï_Õ¥ó—«µ¾¦á8E0!‚…$ŠŒ¢ƒù[ ‹ªìó’\q•0þBüË×n­4¯2]´º,k‰.RPF*+ê3R¡yø¸§G¨™™ÛÞ÷ ùØ«±V-ù‹¬ Éú•·îêoC΀‘î“}¸šì¼‰ø1ßÊí/ôw•!Å&¿w¹o'àAÿµúr™Þ»ÙM'…¤ó™âýì Ó ô®Å]Š»v*óŸÌGQ¼Ô4Ï&i’ú/©Ñîž´¬lå?gábý2ȯí>§&L˜ô˜Íœý×Cá±µ;ÉÍØíon¤ášB†&zw@µû5G¾>#žÅaðê3—yª¿urø¤ß—çSÖ|Ý êìd—Ëö’[†mÏ í†=ÈÛÿ“†{YìÖ—s‚&?i¤üžÇ•>ŽìUŽùÏÌÿá]#ëÉžîi±5x™«Sz;uÉF6éûoµ%‡Œ ‘4›ºówœô•‚9h°Í¢]:ƒF•Zî(90 EW'Â:<¾nØ×`£«Ä9áúÎþRz¥©·6е UµdV„ ¡ªÐ PS*{Ì\<#‡•mîVűث±Wb¯=ónœ|×ù‹ä%¨-úJöÖÝÔ-õÜväŸS¿l·ç>Üg¼˜áÜ ùšýÕ µàÝŠ»|ÿ9«¥ÿ‡¿9¼•çDNú•œpNãnrX])¯¥š¬K\ú\SƒùåMûfÇÊ YâßÜõÙ¸òéñÌGŠ^ þ­ïcº©ùßPÒ5/.j–ÒÏ-¾¿õ¨õʱˆä‘–èOÃÏÇcØæF¨‰F@ÿ S¶í¬˜ócÍŽ@‹„Ç¿p?]=·4Ïž»v*ìUØ«±Vù™£þ—òÓFµ¸°"ò/FÀ9—¢ÉÃyìï}Õø:¨ß)ú~|¾ÕËÝ_ô¿•í ·+‹:ÚMãX€à~”+›â½¿¤ðu2®Rõ?¶ÙN.•Ø«±Vç¿1ËåM2Ú×G…#½½gK~(8Æ©NL¨ U€¡ì>ÎÌ’–RLcÏÏãðb—ù—å{t×õ £qh¬¿Xµ’_T(s@hšUØ]Þ1Ùº¹0„ ù~רé:”:Æ›k©ÛŠEsÈîTžª}Á¨Àñz½<°ä–9s‰Fâã»y—æn‹=ͯœ4ÁÆâÝ‘nÈÔÒ9·ì7Ñ‚Q^÷خ۞Ÿ(ˆ5(ž({úÇ› ѵH5: BßìÊ¿V¥lÊ~G9ì¸Ì$A~Ïì~Ô†»O Ðþ!¸î=GÁ•»7b®Å]Š»KõËY¯t{ë;qÊyá’8ÔfZ ÎY†B3÷º¾ÛÒÏ>.8 ”¢@÷ò¿ùWþhÿ–Tÿ‘Ñÿ\Ü~{{â_è´ÿÔÇúhþ·Ê¿óGü²§üŽúãùì}ëþ€{OýL¦ëd¾Gò¾³¢jÓ]j0¬p½»Ä¬$GøŒˆÀQIì§1uš˜N Õì=‰öcY ÕË&h¨ø¢z{ŠYæ%ùƒPÖ¯ommÕ­æ´leI‰®[ƒWÀ]?´Æv†§[—.8JǪ?­é~›}SÒ§Çéñ§¿f¦÷}‡Ã>^ûiåï%ùƒOÖ¬¯n­Õmá4Œ%ˆ=®m³êá( ãÞÏûÚmn,¹ c+>¨þ¶gæŸ,[ùŽÙ1 ì5ô'¥FýU½á˜:mAÆ|ŸAö£Ùœ}§ˆoÃ’?L¿Aòû¾ÃÏòÿÍËé¤(Èj É2§û"Ÿìsgùìds|¦^ÀöœgB ç ûhý‰g˜47Ð.¡²–ešá Yfá^(ìì8‚w;–àÍâ|Ý7oö!ìì±Å) HÀJUÈe·È§yzÚY|‘ ²-fšÖeI¥Lœøî|kšœò5ù¾ÍìþžsìHãÕ,süî*ûØß•<Ÿ¯izý¥ýì –Ñz¼ØJŒG(Àש•©ÕBp Þ?Ù_d5ÚM~<Ù`#Å~¨žpè{Ê·œ|§­ëÓÞØ@²[˜ãPÆDSUìÄŽ“SB‰r=°öS[­Öœ¸b xb> 9{Ë5Ðíf²Ñìlîà†8äPA•hwšBS$w¾‹ØšYàÑâÇ1RŒ@>ðu7’|ÂúÜ—«n¿Wk¦˜7«xyV•¯LÚ f> ½éòlÞÅv„µ§(€á9 ¾¨òâ¾þç¢kZ5¦»`ö`…?r/ÚÇF«Ã”㕇Ö;k±ñv†‡'¼±=ãñÉçäß7è³»é4ˆvõm¦^Ü•ŠŸ£|Ú^)WÚùýŽí}BtÄ‘ß pØóÒ‰Ñüæ+A5VåìÝX;L%õ.Xó'èÈeÖc¨‹ûœÎÈö#´rê}DÎ2 ñqqd?iø§ …:ûæ¥ö`Þ*ìUØ«±Wb¬?ÏÚãXØ.“hK_êUÝ–ð‡v?ús;CƒŠ\Gxo»wòÚËÀþó/Ù¿é¹|Þ‰ùåuò¯—¡´”Ò7éÍÿ°|Q~u=órù®‹OáBºžl§- ©µÊi·d+x°JmÀêex~4ņKá5Ξ ùwæÏ-ùNÇT¾Ô¡y¼ÂÌ¢ð%8ý‘!'ÅöÉíN¸^{C©ÇˆHŸ©»…üÉÖtÛŸ>ɨIigï!g’ ÄÜÄ¿þQø¿ÊÅeãÎ'-Ðürzç<Ásæo,ZêW }p†vPvŒÓ˜¥E ÷ÀîtYÎL`žlŸ-Ø«±W~nÝˬëš/“¬š²;¬³ <ÇÓŒŸõW“c‰.§[Ÿ40Ç™?{Ñ-mâ³¶†ÒÆ"‰|*¸f3ëX± q(Šl[Š»v*ìUç?™F« þç  ×`Už0 ˆåÕ¸ÊÕ˜=;e=7Ú}h䆫³Ÿ¸ Í ¥üå·{*Zé’~”e¢£:˜UÎÕ¨ø˜{q|7~ÛDãôã<~ý¯ï?$ïòÓË÷ºNu©êˆSRÕdº8£¬kR¼‡bK1#å‘™·gì¿gO)dÈ*y ü?³ŒƒÔ%>dÓõ-SHšËI¼6²)r ©PŽ€ÈA¥0‚ëûOM—6 Rà‘­÷ïòy–¹åŸÌéí¢µ¼‘5k{yVxY&tt õé¾X%ˆ×öWjÊ"2# ‰±¸»øÑS×µÏ3ù•´Ï.ëºLºm¼×0‹‰R•‹p=J(oü0€ì{C_ªÕœx3b8Á³G~›^Ïc†(íᎇ¢UD_Q@>ì¥ôx@F"#TÅ“±Wb®ÅRÿÈÍ,y·þr«Jf¥——ãžòOcihUµ.$\¾gÈ=©ÔxšÉ÷F£òý¶ýɼã±Wb¯•?ç<ü²u?Êí#Ì‘')´UV§Ø¶¾‰¢s_yRŠbðÿ.j¥t7P&¯qoÈâÎ ?ü09Ìæ‡ Èó|ƒ´0xYçâ~]<©Ãv*ìU+óüú^ƒ¨ê6ËÊâÚÞY"î*š<S–နÀ=îggàsÂå"O£ùùƒËRy²ãV™õ™V{ˆÈ<èð–;nå‰^£§¾m2jø'ÀÏkªí¿Ëêœc‡Ï»£Ð¿.õ›ÍoÊö×7ìd»‰¤·’f¯)=3³zš ñÌ f1 „O1ÛÚH`ÔÊ0Ø5Ýl«1]+±V=æÍËzµ‘¾ó_¹°F—ë ÌŽˆ>&MÈ4é÷fFŸ,âj=]§eëµgÄï=©‚Ú~fÏcl‡IòÌ‹å[2!YðPiS'·èIß¾fËD õKÔ^/³±É#âf,·­¾ë¿Ç'§éz•¦±§Ûêv/ÎÖåÆH¡ˆ#ÄAÍnH’ ÇêtòÃÂ\âŒÈ4;v*ìUت×D‘94n ²ÁPƒ„@l<É…ü§çmOÊ—‹k’~ªOr€Éÿeûí&œp{~ÙW¢† s?¸ü‹Õ2ljv*ìU†~bùn÷\Óí®ôÀ[RÓ]¤Š54gWãÈ-hR>X‡ ö´a§É(äúf(þ>,;TóGœ<×eþHh®%(·Œ±È¬ÜHmù€#šŸ§ ¿Óvf“I?ä°>Çèúž™åÝ>=FÓ´i¦Cp‘•¥@ç!¬’pr'èÀñý¡œê3O(_ÙÈZq‹€ìUFêÖ Ûi¬îIo:4r¡èU…ųYc”M»È4é.<…æi´=Aè{¶ íöhÛG/üjÿÙ˜šÌq±Ì?GÿÀ×Û(ã5&Òþ„ûýÝþTz=4ÑŽÅ]Š»v*ìUØ«±Wb®Å]Š»`_˜“kœmⱂUÓ£"i.a©>ªŸ†¼7P½j{ü³c ÞÎï˜ÿÁ 6º¡QÅQ”œ9rÜó÷û˜Ì˜>e†Dͤ dˆH ?H̳¡ÆO'ŽÁíÿiB&Q—™ˆ¿Ñö„&Ÿ¤k~lÔLîOU¹½Qt;ì6~¬žL°ÅûÏìolê8Íž#êÈyÑîˆûÚ-m¢³¶†ÒH`Eù((3C)Kô>—M£ŽLˆ÷ •°7»v*ìUØ«±Wb®Å]Š»v*ìU ©j6ÚUŒ×÷mÆV§Å@£Ü†O33AÂí.ÐÇ£Á,Ù F#ûó,{òÛ@¹óV½7µ”­­¼Ÿè1Õ¦_³Æ¿³éþWÈçC‹„@ÏòÔä×êe©ËÔì;»€òiɹîÅ]б{Ï˯'_êGU¹Ó®™½Iy9µ«F¬ÔõÛ~ø¸’Ð┸ˆÝ üÏÓ|٪ǧh^ˆ6‘{ð],iÄFb ¯«%h±Ò„:¯}†´1ä•FãäÌ|³¡Ãå½ÏF…¹‹d¤’Rœär]ÛébiíÍÓáà#Ü›bÜìUdóEm —°HbV’G=TT“òBËÅ|вù«Îš·œnTú13-°nÍ áêD(~c!³öSLsêgœò/yýCïz¶Rú3±Wb®Å]Š u@i:Uî¦ËÏêÉ0NœŠ) }'l [­Ôøg“ù –äÿ0ßÚyR÷Íg¼õ­fšImW¬›L¢ïJE:ôé9 è<×bö–Hhç©ÔJâI1ïî¡ñä:%Ú'æ.›u­@u ;½~º‚ª—«7ÉŠ-ENìØL6p´>ÒâžqÇ„CŒí/ÛCâ^§•=Û±Wb¯ó&¿æ«ÛOSÒõ³Ó4ëÕÓ-m¢4i¦¯vôåñ}hó¾Óí^IdÉŽ|0„ü8Ôþ7Ý‘ùGUó«ù‚ëAóA<61†¸¸Pë .% Ô0=Jvß|Œ€­ÇcjõÇS,9øH€Üí{òª®~æ}zÇb®Å]Š­‘Ò$i$ÞCÜÞÎ×s¨?äú1Wæ3$ÁõyÎ\’™þ"O̾äÂã;v*óïÏ?*·(|ãåÈÓÕ¹¹ÓgšÒ *^æÎ—vê¼±(Å!ùóùC©}oÊídÍY,'’0½Är~õOÞ[îÍhB§}ï{U§àÔñ<˜Ûõ3üÀy—b®ÅVMSÅ$ ’U’DaPÊ„àFi”$bAÃ˓͖žI½ºòö…¢Ë>¦ËÏS¼ Í"™H«->ñ^Gz}9³:s” J[žOb{.zèG6\ NcÒ:mø³\­“hþh–o2K¢\AvW°CE¹€ü3À­ϧÄM[¦ÛûÆÉ‚¡Ä9‹¨ÕöhŽœe™DðL‡õteÙˆèÝŠ¥>fÒäÖ´ CK…¸Ís ,DšP|J ð$rÜ8& ›ÙÚ‘ƒ<2@ý)¶óÍΕå‡ò]Æ/镊[%B(¤KÈr)NDü]Úñͤ´¢Sñ¶æö™;9u#Sƒ‚ľ^Šz‘4Ùü¹å+huvòRy„¬a1`¬NÃjWß05S2˜í­@Ôê¤qî6ºÒ{¦êÚn±“i—QÝC†)$ˆòPà"½ÄtÊ'ŽQæ)Öê4¹0'EîÈ8îÅ]Š»v*òßÍ­*kY4ï7Ø76r$S°(Üásòj©ùŒÚvv^q/c쾦3ÓÏ”…¸Ç›6Ñõ85.×S·þîæ0ük^-Ñ”û«TfÕæµši`Ë,rçŽÅÆv*ìU„ù×Ï^_¸IÓlžmNáE+©1щQÁWwjŽ›}8½cv,u19'*„y÷ü{ƒ ºÑüí`bóβޤ–’G+Âó™P°qQÅTÖ…GL/C‹W¢ÉzL[ .¶ýdùý¯Xòö·oæ&ßU·R‹(!âcRާ‹)?>žØ#_¢–›)Ç-ëí ¦.±V7çO+Eæ(”MFÞ²YÊzr¦èÇù[ú]¿cö™Òe¿á?Pý>ðÃü“æ)\·—5zÇ©ZV8}M™–=ŠþÒÓé,ÔëtÔx‡'ë¯`=«Ž§tÙ%rÑ/çG»Þ>ÑîfÙ¯}9Ø«±Wb®Å]Š»v*ìUØ«±Wbª/km#ú lãpÌŠOÞF#ÞÑ-.)1û‚¨ €è07Mâ®Å]Š»v*ìUØ«±Wb®Å]Š»i™QK¹ ª f&€Ô“Š%!g`{*Þþey’-LfC´nwØ(4iO‰?f1ý´Þi4þ³Ì¾íOoKµu#ûœgý1þwèí{¶§ÚiV6úu„b+Kdă°ω=Iîs-Ä„@EbÍØªI®y¿Ë~\‘!Öu¶šAÉbã$²q­*V%b¹¸ùµXñýF‘Ú^¯¦kVÂóJ»ŽîÞ´/Äø0ê±Å³XÌ\M£qlv*ìUØ«Îÿ8<Åú+Ë£I·z_jÌb!~зZû-“Ü…Ööž~pŽrFy+BÿyvÒÉ×Û^ïÇÖ“rú¢‹ôf<—Ðû ³ÿ+¦ŒÔw—¼þ®_C‘vîÅ]Š»v*†¿²ƒQ²¸°¹ÛÝFðÈÇ‹©SCã¾Zu#—¡.R‹Ì­¿)µ/­Ei«úÞ\‚C*[«H“ÔÏÀ„‹rÏâ1{—ŒFyo7[ý܇½WÍ–š÷›t+ZX}/KT™¦Qð}]¸†"›¡8(þl4-³¶4óÔë1i£c£ÑÛìCÍê9[Ü»Ku=wJÒ_®ÝEñB÷"ÝVW'‚’ èFØ@·UÚpÇ U{;˜”Þ^ÒüÛåi¯´}6}Jçô–à°&xÝÔ– ÍÄnÔ+óÉ]žŸfâ×i ð^3’\w/çy󮼓%ùsQÓ÷XÖ¯“PÕuL4Ñ1tF(´bµùSld\ÎÃì̘Lò昜òVã•=¿—d…Ø«±Wb¬sÏzèÏ)êsƒI$ˆÛÇãÊr"Û䜔Fî›Ú Oƒ£É.¤WúmŸVÿÎyTùsò7N¾•8\ùŽòóV´¸´‹è1À®?Ö̇ÅËèLPìUØ«±WåÜ'ü«¯Î¿:y¯¥f—WÁÄÀŽn-v÷·’¹®í\îyk4üx#“ù§ì?¶™æi_ŠWçwùÞþIv‹¢\y.çM󯸋qõ 2Ö ÒˆŒ¡«ÍÅ@V}·ùíLž\£(1Æ<Ë•¬ÖG[áÒÇŸªDíu\‡>ç§éú¾™« ›L»Ší`NV…ƒªµ+JŽÞ­ž9G˜§Ï¥É†¸âc}è܃ŽìU‚y³Ìžn¶Õ΋å­טƎºƒ)‘xIׯJ2‘ñ1Ìí>fßÓé£Zl_çÅŸ‰ ÿ@òÞ“å«gµÒb1¤„4¬îÎÎÀPSO¸ ÀËšY ÉæµÝ¡—U.,†ë’m•8.Å]Š»v*‚Õ´Û}cLºÒº£b:©={ƒB2xæc GG#K¨–‘Éq6óËmFãGÔõ%ꇄðÈïl غm"­z†:ûTçI GW­öOØáªÇÈÿGê?§dž5Ø«±T-âÇ5úÚ‹›Ëhä0*ªú¦¢¥NTì$“ÁÅÃ}Þóîy<’ùÏó*Siõ 6õªÃðšüMö¤aà6à ÜF:>ËOO·þ:>ß{Óü¿¢[y{J‡KµbéKÊßiÝYˆíòÀñÚýlµ9NIuLñpŠ»`?˜L—Q§˜4E)¬Ûqi=šeMÃ-?m{x¼1«Ø½o³]¿-,Ä%*q—óOêûŽêQóTzí¿Õ®ˆV€RXúz€mÍGüHvÍ&«Lq›Ÿ¯ý‘öª£‚d ÑççÒ:{™>b=›±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«ÏüìßyŸRO(ùeL­3úw3)øZŸhr¢/Voó;m–½Ræøÿ¶~ÕLŽL}<§!ü^Cú#©ëîç×¼¡åK/(é)§Úþòáè÷—$|RËMÏ²ŽŠ<=뛘Òé†(Ðø§ø¹.Å]оr¼¾Ó®ï|Îúµ›ên½¼ú–—láȈ3´|”)  ªù>ø^fS‰3â2h2ï,Éwå2hÞGÒþ¯4—H.¼Á:¯9DÅ]Œ\Á *(^;w¯íbæiÉÅ’8£[ï'¯àwNÅ]Š´HPYˆ I;*ñ 'oÌOÌIµW«èzA_@²R6>ÿfõûm‘™ ãö&“óºÎ3ôcßõ|ÎïYÊPv*ìUØ«±Wb®Å]езл`™O‡Y5;N+¬<æ¸Fa“á­Ojdá*y/i»:ˆŒ‘þóa¼¨Výû}É3ù#ÏÚ5»ZhкӥS¢\ÇD}‰T“’¯^ªÕÉqÍÖžÁíY /YØýŸùMt4Ñî®çÔõImõoÑñjÚF¡”YäaÉ£$Õ‹3*C•>¶ñx€¡µÑuùÚ1€0ã8ç9þêÏÉí¾UÔçÖ|»§jw+ÆââeÚ€º’¥€ðb*3Mž3 >}ÚzháÔNä q”¸Å]Š»v*ìUå_ššLÚeítÂ#º†Hã¹÷uÞ'#¾Ãƒ{S6Ý›ø Ùû5ªa=.MÁ¿Oë ÛCÖ-µí.ßTµ?»jÉÝlÈ~G6o5­ÒKO–XåÓíéŽ.#±Wb­¢€t’¡{{i§[Iy}2Ák«Êæ€R{ [0ážYÀY/*Ö¼ã®yÎðè>S†HìÞ¢YGÃ$‰Ð³·DOÄý4ÂöÚ>ÈÁ¡‡¨ Ë» ÷wŸÇ›Ó´KKë*ÖÓR¹w° In#‘:îh6äzõÀñÚܰɖR„xbO/Çà#ñq]мßÎþGœN|Ëå€ÑjQ7«qmÅÈë$`~×ó/í|ú‚y=¿³>ÓÏM8ÆR11>‰ÿ7ÈùaÙ•|Ýo®Æ-.©­ýäGa%:²Wñ^Ù¥ÔéN3c“õ¯²¾×cíN£˜ ÇIyÇôŽžæO˜fìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®ÅZ$S°N*M0-oÌWþb¿_+ùMLòÜÜÆiÈ~ÐVì€}§þvºMz¥ò|‹Ú¿l¥œ.Œìv”Ç^ñ.ùué·>¡äo$Yù;O)UŸV¸Þ]×þ+Jî~'sà6o%£Ò 1óêÊð9ŽÅ\H§`:œUæš_æ¡«ë·z˜1YùL2Cqw'RÉÄúl ø‰&”Tûáuxõ²œÌ¹c uΉä/Í J{­ú[e;…q( z†7¥O@J°÷µKL‰‰¢Ìü¡ä-Éë$–eîu ‡o&§>5¯QV¢§Ç¹Àçi´pÃËsÞÊqrÝŠ»y×æçš¿Bè¡í$¦£ª†F¡ø£¶HÞܾÀú|0ºÎÓÔðC„s—ܯä//Çåÿ/[Äh×w@\Ý:À»¨¢‚6!EÞsFËßû=ÙÃK¦ˆþ)zÇõ2|‹¼v*ìUØ«±Wb®Å]Š»v*ìUãþwHõmcÌsê/Õ´XO·SÅL·A@s±iÁ=ȧ†[öôF|ÙåšÃð9Vÿ3÷/ò¶‹ªèþfÒtÛeþ§=”Zå°cé•&_‰MIÙ¶Ûñdl2ìl¬xá”𘠒<Årøí³×r§ÐŠ»v*ìU*üÐåbÿÎOiœÓÖÒ¼©ÏQž¢¡?FÝöÚòDËà6|ƒÚ_¬r§åÏí·éM犻v*ìUóÿüæ?‘¿Æ’º–¡o=KÊóG¬ÁAñb¬WB¿Ê!vÿ¨1H|¡ù}«þ™ò¥„Ìܧ·_ªÏã΄WܯúsÕãáÈ_,íÝ/ƒª˜è}Cãûm“æ3§v*ìUNx!º†K{˜ÖkyT¤‘:†VS±ˆÂ Ã8LăD<·R°üÂÔêÕî-¼¹å›7’5–"¶°˜Uˆ 8ô#ĪœÙÂxcFŒ¤~/c§Ï Æ# %›,«cê7÷}å1ò‡—¼—%•Ί5Hõ÷žD¹ž* I+êF€ò1är½Fl–%\./jëõ‚qËÀqP |By{¶zqÇ i J(Ô""€UEtf6òò‘‘³Ì®ÀÅ ¨XZê–Sé÷©êZÜ¡ŽT>¸ð#¨9(LÄØnÁžX¦'D1ü¯Ðä³±±¾žâê>Yž"_‰hå ˆ˜Šü#ìÓ¿Jæ_ç¥dŠï´™„å(0>c¯¿ßlÖb·†;xc‚%TŽ4UUИdÞåÐNfD’l•ø;v*ìU¦eU,Ĥ€¹Å [ϼÍù«¦i¬ÖZ OQ'€‘jmÑŽÃuÝϲýù°Á ”·–Áéû7Ùœ¹}Y}ÿeû>?$·Hü¶óžîSWóµÔ¶6òŠÙ€ð=£‹ìÄ=Ørñ®l¢!ŒTCÓÃ. $x0Ä_ë=P^[–ïÈo»òn®ÿè72i9ÙK7÷Ri¼å—bÜÝÑVšÕ~î¿.oSÂð.Å]Š»y–¿å?6y«Ì’[ê7݃ÛÊ¿ÝúmÐ"V¦JlÄôùPa{jétša( ÈyŽ·æ›ÜŠÖµÝ òïN:6ƒ >¬àòe$m$íÜï²þ¡‹FCŸ´²x¹Cñ´_ÞSŸ%ù¾×ÌvEq4k­"Ÿ¬[©!›ŽÜÀ úµ¦¶;&Zl„€|>‡ôk*ÅÒ;v*À|åù~5)ZÐÕu¥>£¢·™†üâþýNû¬ìig¥”c2h}2ãû>ÑÑ(ò÷›ÖýæU6š”GÓõä^ Ì6¤€Ó‹{ô>ÙªÔèˆÞ<»Ÿ¨ý“ÿ‚=LcS $~œŸÃ/qóåîfù®}AØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wbªw–¶ïuy*Ão«Èæ€Sà0ÆFƒ«ÕâÓã92ÈF#™, }G^üÁ¿:–¡h´ÑO¬Ü5Tp¯Ú•‡Ù_ŸÃ7:m†çrø¿´^×fí){†.§¬½ýÃ˯^á×|Ÿä½+Éö^ õ¯¥ëW® I!ðʵ迬æk§Òéc„PçÞÉ1rŠ»b³þaù-5ÑæÕ#õëé»qsc±S0>g•=ñq»¾ü£´Ò>·ªÝêS\ùbÌ=ëXÀ¿¿tKqäX%Bþ߇†]>͹qÒ+ò¿C7¾`¾ó½‡è½ Ñ Ó-A?x©`Nä¿èXíÓ}Ÿ‡Šg 1èõÜ娫±T6¡k¥Ù\j²­-‘¥•ÏeQ]¼Iì1a9ˆ‚O ùîÚÞïó3ÍÚ¥û<6 ?dŠÅ ÃÔ^í·Žei´þ!òyÈÄêr_ŠG"yÏòñÌ–R~‘ÐA,ñÍ­w,•¬gÝM$)r3cÙÿÄG:Ùë}–âÊ"æ#éûM$>sÓ<µåWÑõ(L«¬$êÂ(®s,|jf¥MjæFšsÉÄ'ÉÙvF£Q«!¨Šê*wã•=§4ÏìUØ«±Wb®Å]Š»cfóÞ…å…hî%úΡO†Ê ×·3ÑÏs'–y9rwØ™õ[QþqýìÞ×óóZO€~ŒòÑmÜòH ƒÿ3Â×ùsm‹1y—³ÓhtºcÕ>þ¿³ï÷½[Ê–¾\ò‚¤öñ}sUâÔ..Mz ùoâNL–N¶yyì;™ŽEÃyçæÇ’š4oÒ:|u×4Åg€(ø¦‡«Åîi=öï–c•aÙú¯T~’Çüæ±æ-/ê÷Mþ嬀Kšõ‘z,¿OF÷ùŒ¼¼Çov_å²Ü~‰ròòý^L¿BìUتÜSMk46Ó{‡FX§ ÆäP5ƇÌRŒd …€yw¼û@òM§—ÅÇ™<ãq÷q3ÉYÉo´ŒXUÝ¿gúô/S¯í©êk˜Àû¼‡ã’A¦¼žlüÁ‹WÐí¥…¬‘K< qýÔ{ôØ4€qâ;}'i©ˆÑè<²â”yžï(óüe¨~gùfÒ'{yîTŸÐôcZQNR)mŠÓ§‰ûðSÏàökS2"®ÿG¿îeÖ—PÞÚÃynKA:,‘–R¤« ƒFŒ]\GŒeÌl­‹[±V;æ&é^h†· èj) ì`sÇí/±úÅÛvgleÒ·Xþ®âóžó?åüéc¬Âo4bxÁ2’VŸñ[ž‡ü†úŽ3Ül_zö7þ RÅ|Lcø×êùyr÷3}'[Óu¨=}>q%)Î3´ˆOfS¸ýY¨Ë†P4Cï]•ÛZm|8ðÊûÇñxüäÃ+v®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb¬sÌsÒ´0ІúÕøémû'ü¶Ü/˯¶e`ÒJ~Aä»Û/gƒ|LŸÍ?¬z}þI^ä¿4~`\G©ùŽGÓô0yCYÔïû˜Û¥Gû±þŠæãã>G¯×jûS'yTzDráúNïeÑô]3A±M?J·[{TÞ‹ö™»³±Ý‰ñ9k~,Q€¨Šü[Š»Hüßm¬ÞùzöË@!u;•#³ð ŽÀHCv<*.>¦3”2ò7ò•†³ªÚyI‚It«qq¯ë %iøh¦¢ª©Où§réΚ3Å\#ÔYåÿ™%Žmòwå¨Uþ­|çá;GéÆMy¡*Û~ÏÜ1r;2y¤ï÷«€P@ÀÜ7Š»v*ñ?Ío4Ï®jqy/E&Xã•EÙCýíÅ~ê?e:·ù_êä£MEÚ:ƒ9xqüIåÝ K‡OŠ øî%ûÉ[í7˰öÍþB§/Ž4šå­Ì?Ì—ú^¬ZæÂ–«rŒ~éۯă¡÷_Ç0óhã=ÆÅÂÏ¢Œ÷ªÇÎ>lòTÉaæxÿM¯î9rz‘)Ù¿Õ}þY§Í¦”áÚv´º!Ì8áß×ç×ãózn‰æ-#Ì6ÿXÒ®V`)êD~c'³¡Ü|úxf)÷úÒê9_—Qï ¦9Ø«±Wb®Å]Ф¾m»¾²òíüúdO~c1«;©“á.Ôü òú0Ç›­íŒÙ1é¦q‚eT+žý~Þuùoæß,è6¦j%ìõ ¥gžæD¬l~Ê/%«#ù…*NY8’ñÞÌvÆ—MŒãÉq‘;’6ò4OæÅ–­/—íô¹c¸¾¸•½ ¡eÙ~%4¡nŸ,a³wµy1ç8#Œ‰JGb7çCïz¶T÷®Å]Š»v*ó¯ÍF_ÑÖ^^³V–óT™r€³:FG 7«HVŸ,³xÏlõ¼cˆs™³î¶¾OÒ/ÊŸ$ÃùuùuåÏ&D I¥YD—eiG»’³]8§f™Ý†\ùf8«±Wb®Å]Š»|ÿ9§åI<—ù£å¿Í}:-5¤[}L ëwb¢3ÈÒ€ËlÊ‹þ£ey±ñÄŽ÷Y¦ðËþ!ýŸjU±ÏO ŠEWÇFV|Æs$Sãò‰‰ ó ð1v*ìU¬húv»a&©Â&¶’†•!•‡FV‚2Ìy ‡'I«É§˜œ òéí¿-|‰õ¤–}_V·$ÃkêG*Ã"‹TPAþbHð®l͘WÒÆ;G_8fˆ±ó'î÷²¿"yæO6½ôwPÅk,,­m HÚ"7¨'‘âz°P7Ì]V—ªÝÒößc ‰‰2™®¿Ž–Ís çÝŠ»v*ìU-Öuý'ËößZÕ®’Þ3^ w’B;" ÏÑ–cÅ)šˆrôšº‰pãýÃÞ^guç?7ùêí´$ÙKokÒK• ”)?iåû1‘¯¿lÛaÐÆËröº/g°i‡r%.îŸ.¿™—”%ô)—Pó+_T¯3 ©µF&»†ÞCîû“ß2%“¹ÌÔv”¥´=#íýQUTUDP¨ P(ÊÝcx¡Ø«±WƒþcyróÈÞb‹Ï^ŽšmÌŸé°-BG+ŸX‰'Qàßìrür½¾! ^‡'>‡ôûÃ5ѵ{=sNƒR±~PÌ*Tý¤aö‘‡bXùî³I=>C ó‹Gââ»v*‘ù§Ë¾iÓÖÊâW£q$R¡¯ÐÕkCQ_–.˳;JZLœQØ¢€Ôï´oË¿/*ÚAµJ[A_Šiˆ©gn½¾#ôع:l9»KQê>óÜ<¿CÎ,<æo0ÛMæÄX¾·$ÂâÞÖDU&`­D ^¾ÖÿIzÜý¯¦ÓHiÍÐOóMû¹}ݲÓë?U‡ëßõÄUôÄ”ø¸×zW¦Îòðñ«ÚùÒ¶-nÅ]Š©\Û[Þ@ö×Q,Öò2E"†VàâÏIBBQ4CÎu¿Ë-æ:Ÿ”.ZÖå!hÎ@ùG'QòjüðH(½¿bûg—O0fLd9N;~’Wkç}[EœiÞm±‘&]½u@®GNEvVå)Í~nÏx—ß½žÿ‚ˆœ@Αšì˜¥aõ^Îí6²¯ê;l¿IÌŒZYÏÙæ»_Ú݆ÄçÅ?æÇsñè>%Ž[Üùãϲ5¾…ll4¢xÉtID§~SRÉŒW6xtP†çrù‡iûc¯í †Ýcòçñ—üM=Ê•Z—Ê^jÕ5U£ e_ÜÆßäFj öš§Â™˜étýn}Ežâ슻yÇæ¥‡šV?0h²¬Qõf³ˆP« þÿañ€V¨ضYÚ0ÉBq?OOÒÇï?2µÏ7Yiz•Úù‚øº_²>Ÿ¦+XÜôVbz­)‹-|òˆÆHóB¾±çïËMVÓüGzÚ®‘v~>S=ʲ­9ðy€uu´Ø|X¹´Ògˆ‹#×*ε­M®iÃYZjƒäjŒÅ–@ q*ËU~¼[û09Y»;Ž|Q• sz¤ÙèZe¶“`¥m-S„|X’K31ñf$Ÿ|]Ž,b‚;Çb®ÅX7æW×ÊÚgÕ,œ~œ½R s }R?÷ùauúý_…Q`ÿ—žXkHÄ‚“{r ¶WÝ’6êæ½ßõ|óm¢ÓÐâ<Ü-ž‡æYög»b®ÅT®-­îá{{¨–hQã‘C)àà”AQ(‚(°=WòþæÊàj¾Q¹{K¸Ï%·õ ýÉ^ÿÊÛ{æ»>‚÷ÉÁ:iâ—È#4?Ìû›Æ•ç;g·¹J)¼XÊŸœ‘æM½³S“ ‰§§ìßkˆ<‘GùÃôÕòzU­Ý­ô ug2\[H*’ÆÁ”ý#({Œ9¡’"P"@õ ø¶;v*ìUتK¬ùS@×Ôþ’²I&=.zsökB~Gl"D:Ýwdiõ?Þ@ßÈüØÞ‰ùae¡ù†^¶žÒí¼È ¬¤qR]h“öFôÉØtºeqéµ#(•Ä]Îýÿ±Ÿd±Ø«±Wb®ÅR¿È,ŸÍ_ùÈëKÉSÖòÿ”+¨ÊiT&ÁÀ·èy]2½;¨=³"ƒãžÒk¿1ª‘£éÛoÒ,“ v*ìUØ«±Wb®Å^Kÿ9'ùwÿ+/ò‡^Ñ­âõu›ÿKhàNnì~ §¨I$°¯-d.SŸÀ›š“×}³; Ë”pƒ°z] µºØ PFÓo>§îH<¼šÿœ<ímçaú3Kxú»V0¬ r!}BܨX òܱ̌]—g¯84z9i¸øæ~Ãú=Ï\ÍKûv*¥qsoiÜÝJ[Æ9I,Œä†MxñÊdF"Éîy™?6ÓÔýå8¾±räF·²)ãɶ(ÎìkзÜsgƒ³úÏäöì©>¬æ‡óGé?«æŒòïäö­­ÜkóòF’CËê+')XuIÈ?ÈO¼fwˆ¨‡y-n<1àÃãñ»ØtÍ+NÑ­ÃJµŽÒÒ?³JW¹=É=ÉÜådÛ«žILÜ”f,Ÿž|ù¦y&Áe¸XÔ§êv*Ôg§Vc¿4ùd¡ rôºIf;rïAyGòþrgózÉ<Áe,VÐnG«a%ü¯§¤¨EAŽ8cšá”ƒUw^-ØÓ20î=(WïBùÇÈÿó‘_‘ñ~—ó<ùʨ@¹Ô-dkÛhêiY$)Ä^Ï"p©¦çl,rö~)…&Gå8i>rÓ¡¦· R‹uhäz°9ìÔêì·FcÊ4èuib•ßPÓìõ[)ôëø„öw(cš&èÊQð=°M0™‰sŸ^-Gò“ͧޟË7íΩZ¥iÌûiPwFeFVþÐÑG´0ÜvÉÅ{G©Ã470¤ð:˪9‚¬¤TFÏ'AB¦,Š»c¾rò´~jÓ¨Cyz–³0%CR…Z›Ñ»âí»#´Î“/\NÄ%zþ¯äß"FnæŽ}^%KXdEø¶Ë×ípQÖ›‘‹™§Á‹]®< ˆ‘óýV^y¥¥ÍåÄókÝÞ—¯¼BçO–veŠddõz…»vùôÂõz“D X£“ðÈc§/Çézåÿ˜n¼Å ýbûâ¼¶•­å” 8ª°j «FÞ˜ Æöö‚:lü0úd,y2AƒPwbé[ÅÅ]Š¡oôë Rm¨ÛGsý‰T5ˆ®àûŒ[°j2b—$b|˜«ùOkê}kË—¯ap§’E#3 =¸È¿ý<±;ózÎÎöÇ6)1¸þ(úeøù$ò]~bùcáÔlÎ¥dŸîྰâ;ú‘|Cç ÌLš,rå³ë}‡ÿŒÂ¢rG îÉ´¿Ómì‘–™Z4ô[èe³“ö=XÇÒ¿ü.aϳæ9núvƒþ :<›eŒ±ŸôÑùÿز;=E¿ê—ðÈÇ¢s ÿð-Fü3x'`½v“·´ZîòÀù]‘ßìL²§lìUØ«±Wb®ÅV¼‘Ä¥ä`ˆ:³úN [äŒÈ€<ÒkÏ7yrƾ¶¡°ýˆI˜×Ã÷uürøirK£Ïë=­ìí?Õš$÷GÕþæØíÏæ?Ö%º›-ÕÃí0jO´qò'ï—Î?Ä^?]ÿÈ}:|FG¾[±0ˆƒÊ™žlßQisõI¥Uî=$¬‡å!Kr#®í®Ó×í’|?ÃHû7?çgåïÊ/,hå'¿VÕo~Wö„mÿ[2 ™ŽŸQg¨‰,q¨HÔTPt À ]Š]Š»BjZ•Ž‘e6£¨Ì¶öp/)$nÞ¹$ìÜâÃ&Ag“²üåòõÞ¤–w—–3ßL©¥]A4_zŸ|.º©* ÞÇüãåkß#k0ùãÊH> Î{`¼£€È8¶Àÿtà‘·Ù=;QqµZs‚^.>_±cÁæ¯Íù,.&‚ ;ËV²8yc•]¹íê|5çÊŸd~¸©5th‡´ÅACãj¨‹àª(ÝÞB—â—b®ÅR?5ùžÃÊzLšéäÿbÖÜŠiHÙG·v=†.>§P1Gˆ¼S˺]ÿž5ÉüͯŸRÔIÈ©Ž¿f%öR¿wŽfé4üfÏ èôøåžfsäõ03rîÏ)yWVó¦½kåí^]Y‘1®ï$„B¨ëµ{ šd2dZòåwš|£æ&j¤y†Íín–¦6?S%vxœlÊ}ºt4;c ˜°¸²ÆbâRL›c±Wb©~­¢išÜWÔ­ÖUaúH‡ÅXn2¼˜£1D5eÊ!Üh>gò,²jžZ»k5k$ð=½}HþË?iwùf§Q¡1Ün4ùµ)qá–ÝGOˆý<Ù§“ÿ0ôÿ2‘gt«cª€)8ôæ=?tM ?äõùæ¶P§»ì_i1êýôO»¡÷~¯½šd•Ø«±Wb®Å]Š»v*ìUتAç-lh]½¿VãrWѵއ֗áR?ÕݾŒ”E—UÛzïÊé§>¼£ï?«ŸÁô—üáåÑò§å|¾o¾‹Ž­ç þ²„ƒÍtûRÑ[)¯ó1’]º«.d>'"úo;v*ìUØ«±Wb®Å_š™þT?“ózž•zVó+}wLê#X/œ²¢íJC8x†û.ç®aëqqÃÌ:_h4^>˜‘õCÔ?OØÉó@ù{±Wb®ÅP·šu†¡èýzÚ;ŸAýXD¨#ÐŽ@ûä£3E»¢xï‚DX£H¬‹S±C±VæÌÝBçi`F¥ª ¯¥~ê6éñÈ*+þJÔøÓ3phe=ÎÁè»7ÙÌÚŠ”½óæ}Ãõý¬»òóþqócóžk}{ó âO*ù=ˆ– yb+w2ÇÕíœîÙ·î ÜaÁc`÷zÎÃ¥c÷õ/_üíÿœJòU·äü°~Zi™ü·ÏRŠà“5î© úÌ3Hwv(¼âE^(£‘Ëœà^+ùSçñW—+¹9júg{Êš´‹OÝJküÀPÿ”bä›í 7‡=¹wpnî ²µžöå¸[[FóL碤jYÐ,£M?ÿ8Áù^Ÿÿ˜¯æ­Åוt’;-6aÊ ‹Ês†8"þÓ2Ö °9q­Ãˆb€ˆ~„ Ðd™©ÏPKmsMm24sC"‡IÇVV¨ ƒB*üýÿœ‹ü”Ô?"¼ËæŸåÄE<‘}8QÓ‘ŽÂiML,Ñå?ݟ؇o‚±”m†l1Ë&:¹eæ="×YÓÚ¶×IÈ)ûHÀÑ‘©ÝH æ)^W6#ŽF'¢Í^XÓ|Û¤K¤ê+EoŽ ÔUà”EùWqÜmŒeE–Ÿ<±KˆÐÀ­¼¯æKï«ùcÌöQÏ£Û#¥ž±_Z*}>-È;âÉáóÂôÙ;OOŽóà‘‘õ@ò=ÿ¶ ß2ÞÁä.Áå C&«v¤ÜN¢ŽCFz ÑžœTvåŠ{7 µúƒ©Ê*ä=Ý=ÙókËמxò¤6}ö™ëi“¾òÍ5LG"9+0QAb|qOhbÑk ç ÔÀä?ø¢NÛOš2í­m<£/­xÔi=2Z=øªqö˜ûtùãM=™ì锵"£>~v:ûÉ×^sy.m<Õnª°ª4W_wgýŸÝ| êE)ïØ:Î×Å£2Óž|Æÿ§vY‹£v*ìUتW¨ùoAÕªu>än²” 'üÑ¿\Ý?hçÃôL»åÉ‹_~Rùrâ­g-Å›vUq"¡ÁoølmÝ`ö«Q¨F_aû?RRß•Úýüqõò }}[ù6Ï‘”"y€ô/ø eÃô™ãþ¤ÏüuaòßæŸ÷„wéIQëÿ#ÐeGKŒôzm7ü5ÿ/1ýh‰Å-ú·æÜU­ºH«VËâØ0?†CòX»®?ø0gÚóƒïÇú¢–iz¿æ6­©Ýézz‹‹ûbâ{r–È!(üân#fÛv8þGs½Ò{wÚ¹½PÈ$$,zc°=Û¶Ó±¡þrM±‰ <ìw¯È·L#E¹Ê—µ=µ/ãüܨª¯å÷æ…ïûÕ¬El§­.dSô#§ã– 61ü!ÃÉÚ}«—êÏ!î—ûšEAù#qpâMg^y›ºÇcô<Žâ9hˆtû?&Sy2;?ydšwå“,hÓÁ5üƒ~W35+þ¬\ÞÜ}™Š<ų /MÒãôtÛ8m"î°D‘ƒóâqsaŽ1ä)‹7b®Å]Š»xÞ¡ù¡æ.y³V°ÕaŠúÚ:ÃgklB*¸5¹|MV÷€÷éÓ ¤ŸhOI n:2½KLrò–¡æØ®4³dúòÂ"¡_ÒžJÕj‹P»âåäÇãc%Æ·§œjSÅç= Só>·¨Çai§s¶ÐtH¢•zšŠAﲊbë2r4Ó£~Z'˜dòäšOšl8-É·¶7 rš dhÛ~+г)Û¦.Ï@&qðÌrfvVVšu¬VV0¥½¤#ŒPÆ¡UGÈ`s¡C’¾,Š»Kõ½kOòþ›6©©J#¶„V›rvý”@z±ì1jË–8âdy<I5Í/1µÝÑh4›s@ Õmá&¡Ò…Ú›ŸàÌ>ù<ÿ«U’Ï õ+KK{h­-#[B¡#z3{ˆŠÞ19"a†[‰£·YåeŽ(Ðgv4UP7$ž˜II4úËóúíµ­®¥7šCóO­YÙÀœÞ)ö¥I«¿(¤ò³]“\ÕaÕäí“\7â×óEó·_•¿ž–PÁ¬ÙÈmãÖ#…¥á—˜Ñfe‘hŒáFÆ ¯&³§”yˆíÜò_ÍÊ{¿ËkÈ&Žö;ýPg|åÑn¬‘×zöÓá?ä’fiõ ós´º¡”r¢s™[±Wb¬#Îz–»©XùËP½æ·«M Þsw™€ŠáÈXšPuØœ×k³× |]_hj(p‹ê[þpKÉ·¾EÒtý/S—Kóý²‹ÝdžÎúèürz°9T1+FT…§ ç5nŸ‰ó‡™´¯ÍŸÈ½F=#óJ’ïEvôìõh˜Ío0ƛúr…zvQ•Êõ•í^lŸ¼û!ñëñù†G¡ù“Fó¾—r²0É|3Gþ²Çϧʈ§Ñt§ƒWÇ+òê=ãðl{±Wb®Å]Š»v*ìU€jZ-÷æŸæ‡–ÿ+´–n3Ü"ÞÊ‚¾’°õ'”ìºY¾ñ—cš{eÚyFÊŸëÔ>÷ꙦÙhÚmž‘§D Óôø"´´~ÌpÀ‚8Ð{eŠÅ]Š»v*ìUØ«±Wb¯™¿ç5ÿ,œ?-ÎZl<õÏ';]9E«É¦ÍÅn—o÷ÝjžŠ­ãŠCæï$y€y˶·Îܯ#…àî&ŒIÿXQ¾œç5X¸&GGÊ{gCùmD¢9Ǹþ®L‹1ÝS±Wb®Å]Ф>có†‡åˆ«¨Ï[¢9Gggðø{v Ëðéå““²ÐvVmQô »Ï/ǹ)ò’?8ÿç ®LV±:7“y¸Õî ÃiÄ03S”Ì;ǧóS®n0hã ù—½ìÞÀÁ¦õ\ûÏè‚û/òwþqkòãò˜Aª4â8FoPH…üm-þ$‹ÙªÒuøèi™ŽòÞ㊊¿;?ç ¿.ï¿ ?4£óï—m‰òš&½´`íçú—t/ûöß ¥W¢Œ£a§Q€e‡ æÊ4ûûMVÆßQ°”Mgr‹,2/B¬?_ˆÌB)ågAæGç.±ú/É70#qŸR’;4§^$ú’}P¯Ó“Æ,¹Ý›‹(=Û¾Åÿœcò`òG䟕´ù#ôïõÓÕX˨Ÿ¬(qüÉG¯òæSÑ—®â‡b©O™ü¹¥y¿ËºŸ•õ¸DúN­m-¥Ü{W„ªW’“Z2Ÿ‰[±â¯ÍÉÑ{¡kkò=ëú£Þ:>È–^Úb7;Šz僧í|cÓ'®e.•ŒùÛÉzw4¦³º+èkÚU¡øø©ý¥þ4ÉFTäéuRÅ+º¼ËždÔ¼—©7“ü⦠>«¨ïý¿ßÔU•Ô2ÊÀ`j=8¼1Þ(v*ìUØ«ƒÈ–©æ¹|Ísr÷\« €Ls¨Øª°)·Ñ‹½ŸnHéFÄG¡#¨ýgª{®ê–š6“u¨ßÐD†±~ñ›e@óL]n‡K<ùcs'åçðxÿ•¼¡«ùëb±4Éc¸çgÅ ¡~\Ÿ€_²«PÇà ÞvŸkbÒÖƒ0G«•÷’ô}oζ^Y¼‹NÔmîç>ŠH÷‘GB )È€ËMÆû|°<ž‹±§ªœ Fäp’SÍ+WÓµ»E¾Ó'YíÉâH¨*겚~xºÝV“& ðdQظÎÅ]Š»v*ìUØ«±Wž~ZäÆóWúןõ0¾éì¯÷Pÿ…ÇîbÅë]Š»v*ìUتK¬ù»Ë~_ªêÚŒPJ}L’ÿȸÃ7á‹F]N<QK4ßÌ¿%ê—Igo©¸…ŒO«°ÝB׿qjǯÅ#@§bó‡–t©µmE£#]ÞI좃Üÿn-ÙóGx‹Íu̯=iki®j¾]»` ‰ß÷î„rëÏ$t&0=°º¹ëóF¤bOãñ³¼Ëù{ ë~Z›ÌþRÚò厠‰È‘$l+$*ƒe Ô…ëËáù+¨ÑBxøñó;þÅ?+~j]_Á¥ynëK“Q¿•ÖÒö`yz–çà/Æ›°SñòÛbk¾Ê4ý¢d#<¹”éß”žQÓµAª"O7¦þ¤6“ȯ05q Àv ÇÞ¸¸vn(ˉb슻v*€Öu;@Ó¦Ôõ9„6°ÏVv=v=†-yrÇx¥Éàš†¡¯~iëÔ¶ÑíÀc·Œ÷=9HÔÿh ¿ÐyéÎz©÷ö~×¥iZ]žcŸbœ Œu;³1êÌ{“›ÌxÄk€ É¶=ò_ÌþRòŸœ¡Õ<ÙlÒB…•èøÒÊf4õž m¶ä7^ Øú¬r”j.&³ç ‹èWò-–Ÿç»¿Î½GÌ2j~_µ³–úÊ8«+"´L¼#1UZ‰Œ/R~*î[]ã .¯Ç&mò¯¼Ï?œ¼×ªyšxý&Ô&çU©Ž$QHOr¨ª Ͷ,|ÝaÇÁäªëRÔ/¡µ·½º–â ý 8å‘a‹‘~ ØT“A’˜ˆ¸Y;J|Ç®Cåý*[ù(Òý‹xíÊÃá.çÛ*Ï”B6ÓŸ0Ç{¿üágäİÃ/çg›"õ5mSÕËqÊ( rR{ÊÃK¼qô¢r;‡ ”‰6^js$Ù}“‚UÒt½wO¸Òu«(5.éLw6Wq$ðJ‡³Ç *GÌb¯5ÿçáËæÉ;öÒµ8ë òõÔÌ!fî-n˜–ŒŸä”²’~Ú®ØÓvóÇ!(’ê;ÿŒ¼Íä­^O+~hi^­nB¼²Bc’£:ž¢H¶# 9T±÷=ße{dEGP?Τ~¯“<²¾³ÔmÒîÂt¸¶³,lO¶Ýý²²óxeˆ”=B#k±Wb®Å]Š¥úÖ«‰¥]ê·Çm~5§&èª=Ùˆ@·]«ŽŸ ²K”Gö‰zwüà¿åä÷§ÿ95Èù]êRK¦èÎàׇ1%äË]¨ÏÆ%=Gó >¨Í,“3—9/´0´»v*ìUØ«±Wb®Å]Š©][[ÞÛMgwÏip ðÈ$‘È¥YXˆ ÐŒUù…©ybëòKó—Zü»¾fý { }"âN’ÛÊKÙÉ^ç‰1=?l À×áâ…Žaç}¦ÐøØoÖ¿-üϨAs¥Ø]K¾§m*Ïl² Ã+F\‘hJõFÙ€<²¬½Ã®í È8¢7Gjöñ~s~kyCòï@˜^iÓ\F/nm›š¬r-Ô– úVñ–¯F8£IìÝ9Çd(—éô0Åop@‚8bUHãQEUQ@k°_Š»yOç×çf‰ù-äùµ;‡K3ß,ùJ¨/5Çï]zˆc$4òQ» Râ?ÉQ¶Óõ4ë›P×ä+IýãFœÊÞò3–ùP÷Ì|²²è{S8”„Gð½C*uNÅX×<—¥ùÓL6W£Ò¼Š­gz«W…ÏÝU?´½þt9(Êœ6ªX¥c—sÇ4Ís[üºÕ?Âþn›L–·@ vxÍ*ñžëÕ ÉíNdž²>.§Ôwþ£÷ý¯P‚xn¡K‹iX$£‘e`{‚1xIÂP&2B¦,Š»v*‘ù§Ë¾i°[+™ä€Æþ¤RFjÒ•d;6ÇeÙ¥-&N(€ocýªëÉå_'Ü~ƒŠa%¸§. ²£HGr.kôâÙ¡W«)úÎÿ«ô07Tóá÷~×¥iZU–‹e…„|!MÉ;³±êÌ{“›¼xÄk€ ŽÉ¶=Kò7ÈžVóö¿¨iždžUh- Öv°·¦e<Â;ú›ïT…¦õ¯A¾.¯, ·<±Ä²ýwþqœÝ$÷~@ó ¾©.ñ=Û(–9#4xÌÐÕyƒ±VD¡ë”Ã]_P¦ˆv•}b’¯)ù—ó7ò2ïêfÑ®¤òœûûY©;½µÂrŒ6õ+ÊܸžHcÌ,ÙåÇP.'v ù«ù;[ó]ơ䛰Ò%D.¤zk$är‘Ò‘Šž‰Ù^ÖáÍQËè—ðŸOÍž+”‚¤T¸ ÷[×mâ®Å]м÷ͶگŸ|á þVùpzšŽ¥s MJ•W—ì—¦üc”¯í¿l·êùç¶}¥rxž[ËßÐ~Ÿˆ~šy7ʺW‘ü«¤yGDNfm¤3ðOÚv«¹îÄ寞b®Å]Š»v*ìUØ«±Wb®Å_-ÿÎl~TIæÏ#Áù‡£E_0y<4—e*$—Kv )oX÷£Á}Cמ{Ï^Jóy—@·¾fò1èÞ¨í2SOaóÎsS‡Ã™(íÒç0þ¼}ß³’$‰4’°HÐwb¨’Iè2€lbI¡ÍçÚßælmvš/“mZÖnE¥È#l4Œs•¼íîsaƒ³ÉÞ[«ìßeòdõfôïâýYü²ÿœ8óŸžn óOçn£6™`Ôx´Müˆ~.20;t;UTêC¾m±ãŒOm¦ÒãÁq›í/(y'Ê~@Ñ£Ð|¡¥[éTB¦(ŒìÛ–F«ÈÞ.ìO¾XÞðÿÎùÌO ~^ýcEò™O6ùµ9Fbµ“ýÇ[IÓ÷×+Pä÷\<ºfCŠiâ”ó•?˜q~p[7æÕñËiHìÅ«Çõk=1ȶžÿeyŸNVsÈ©äìx ³&)B¸…[¦ÖaÎ Å!.F·Ý÷þVÞìU¦eU,Ĥ€¹Å_žÿó?ó¾düÜó×å×å­ÛÙyÍžýF 3ªq<IhE½vŽ1öþÓV .F›M,Òá‹®í^ÕáÅâe>áÔžàòÛ/Ë/AKÃ-Üä|r—1Šÿ’©Ð|ÉÎbâ{%òÍW·ºÙÎñðÂ=Õ2E(A£y§òÓXƒÎ¿—Å®¥aWâ¤}3öÔŠq•ûQ²îTó—üæÏ|Û<º7äÇ–ÑOÂ5mB5º»PNÎ ZÁO÷cÈ0Î0#O0Ó?.¼Çæ}xùËó_U“ZÖd!ͬҙêA%VW?E'h£ø>²™eîu:®Ô±Ãçúž¦PEØÐ ¥Ò·Š»v*“y—ÊúG›4×Óuxy¦æ—iazPpòä‘yhúB3‹új>)V3W4I$¹¦-‘Úë¼L‡ë¿…òýH?"ù§Ë—zE‡–%ONñÑà’ÚHëÆŒÌKn§˜ì{í…ÈíÎÌÔC,óƒq»»ÜbYù•®^ǨÚùcM2Ad‘¤— j¤;†¯ÂÓáU§O˜‡3ÙÍ9g]/ÇRÆLiž\¸²Ô<£¨^ä~¿axÔ 7†Üw#®.ßò™51”50ôeÛ»ß0>bìUØ«±Wb¯<ü´ÿÉæ¯õ¯?ê0a}ÓÙ_î¡ÿ Üŋֻv*ìUØ«±Wˆùî7ò_æ6Ÿæ«u"Òñ–iBŽ¥@ŠåG¹BæØ]°x9ÄÇ#ø+¼Õù…yçxÛʾPÓæ’;²iœRDV€ªHE¨ø™›§†)ÔëNoF1Íé~Iò×øSËÖúS¸’ê­5Ü‹öLÒuã^À£åÚi0xPê·òß—í/›S¶Ó-¢¿rXÜ,(‘êA¦Ä÷¦,ã‚ñ-4Źث±Wb®ÅX?0tŸ(ÂÐÔ]ë +’7Ù¯F”Šñ‰üqpµZØâÌ÷<–ÇHóæ¤u½~gKh¯N  5ôíÐôQü߬×34úS=ÎÁÓÃõâŸ/Ç'§XØÚi¶±ÙØÄ°ÛÆ(¨¿¬ž¤žäæâ¼ "(rDä™;dGóEÇ“|×¥ùŽÞ¤YL­8Õ›L_SyËPòwåqÔ¿5´øû\óJC˜‰ÈZ—hCú•‘‰øìõcš¼BY*t¸c<µŒì"ð=ó×óÌž[ŸËZÔ& ¦X¼‚Ä‘nL,c!8«D‰ œÏ†’•‡i 8ˈ<×2\·b®Å]Š¥Zöaæ?ª_)O(fJ¼A>=ÆU›È(´æÁ‚Š Ë:çç‡åŠˆ<æÉ×KBZ==¤I-Æõ?è·‚HVµÜ®kg ˜å»ªÉÙÓ·z^•ÿ9£ùå pO4ù[OÕíþòt¶¸µ™¼G«ÿ‘Y,0\Ié§`½[É_óß–ÚÜñYyÃI¾òµÄ„+]5 (ÏCÍâT˜oá÷¦TÒbúwGÖt0é¶úÎ…}¥¤Ý¯©m{i*Í «ZU] „PûâÅ^ÚòÒóÕú¥Äw„þ“«úsGöã~$Ñ—ºÆ*¯Š¼›óoþq×òÛó~.5»ÑþeãH|Á§…Šì(¢mŠÌ»R’@û%qH/Š|÷ù7ùÉÿ8úò^zâo ÆIý#jŽðÅ=g‹â’ØûÔÇ_Úc‘”Aw½•í}&ÀñGù§—ûñ²–¼÷¡y”,PKõmDŠÊr“ßèã忈L¢Cé=—Ûú}^ÀðÏù§ôwþ6dùv—kš½¾…¥]j·G÷vèX/ws² ÷f aÜM~²:l2É.Q3Ð|^“ÿ8?ùiuu«þvùŽ>w5†€Î:Õ©ypƒ°¨ôø°f@ˆjuË3926_kaqÝŠ»v*ìUØ«±Wb®Å]Š»R¹¶·¼·šÒî$žÖá)à‘C¤‘¸*ÈÊv ƒB*ü½üÇòåÿüã—æ®·åñÝy_QC{¢‚Ü}[IK>#_Š& “Ö…©ºæ.«L2Þê»c²F²_ ¢yùud>Aüˆüãüý’OW'ÊÞA‡Žîæ7Q4}µ±*ót‘ʧ^-Û%‡M |¹÷³ìþÉÁ¥rþqçû>¶¿*!¿.'íycNëLœ.uëÞ3_Í_´”5?ÉUñ©ß2’—æ¿üäåÇ峯˜µu¯åo X•šöBETºÔ”ÿ<„{W¦)ñæçÇççÃϧY1òÇå,†ÂÕÝhúsq@ó“Ý,~+]ó7K É›¡Þè{_ÚM.€TÏÿš9ü{¾?ËÞIѼ¾dO­j­ÜÀù Ñ_¾tÚNÍLJ~g¼¾OÛ>Õjµ×x!üØþ“×îòRóç—¿NhÍ$ ]BË”ÖôêËO>*=ÀÈv¦“ÅÇcœy6û!Û?“Õ#èÉé——qø}ľÑÿœKüá™ÿ—0éZµÏ«ç+¬v:—6¬·àRÖèÔ’K"𑺗ROÚǾâCß±CÁ¿ç/?0çò俣Ÿ)‡Xó,©¢ZH†s«=ËŠn?rŽ€ŽŒÀâø¯Èz"húËKËÐ.'nôqT_¡çcÙšaï–åðÏk»Têõ’ú1úcðæ~'ì¦Q›—v*óß0¦»ù®ÛùÿÈ÷Òé„lé$ö¤+Bó!˜ ÅÁ!~yÌö¾„@ø‘äy¾µìG´'4-”Ü¢='¼w{ÇO/s!ò7å®›ækX¼éæËùµëýTµÌ‚Id ÈX‡3ÈÇÔ‘ÃËp+ãœäò§¨Öö„ã#íO\²±²Ó­ÖÓO¶ŠÖÙ>Ì0"ƃäªÊItò™‘²m‹b¨Í3HÔõ«¥²Òm%¼ºn‘Â…ˆ&›îvÄ g r‘ -êþZü‹¸‘à—Í×éd&?ºÓ­Zw re2¨ H@Ûwlqw»<=˜Œ×“Ï|ñ¢XysÍ:†¦N×–®¡Àä¥9BGRµâNÙ Š.§„ÌG&=‘hCÞØÙêV²ØßÀ—6“/a•C+pq”dblsx™¿,µï&Þ7˜|‡,³Y­ZkWš4­Jñÿv§·Úýrøä¾nÔgŪ‡‡œã‘FùSóM×BYêluc·4†Vÿ!B”ýË)å{SÙìš{”=pûG¿õýÌ×v*ìUØ«±Wb©[yoAkåÔŽ¿F,ëVæ CmJš÷ÅÍ£œCƒŒðò«Hüáå ­bê×\Ñn×]²§¦Ï²HªK($B 4Ú‡¡ÅÙvGkG e‹(âÇ/±¥h>aÕu'›Îšu„¶¡Ó‘B –D5 ­XƒûA˜ÔW#U®ÓáÆ–süê¾?e{‹Ì;v*ìUØ«Ï?-?òcy«ýkÏúŒ_töWû¨Âã÷±bõ®Å]Š»v*ìU'ó–4o4Co³š+i}h»!'‰R¥–‡‰®àZ3éã”.ˆ½7HÒôx¶—i¤;Ua@¼©ÝˆÜŸs‹¨ì\³^S6õ?ä×çá›=>‹¬þM:} ž)þ=ïDUTUDP¨ P(Í“´JµÏ2i>_ˆI¨MûÖŽÞ1ÊWù/aîh2¬¹ã»NmDqÒ?ÌþvóKwå'_jz|D‡žÚÚêéVŸÌÐFT|³ö‰èt»Lô úŸlu+¯Ñº” ¦êaŒ~”§à2Ä¥HR­]¸°öÌŒ:ÈÌÑØ¹85Ñ™£±eÙ˜ç= RüÔ¼Ô¿+ôÿË«‹D•ìç,u ~&[x›œ ìÓ!?Èîi8 ÜXé@ÊfóÜÈrŠ»bžkó\ºTé·ä‚žPóSV@¶ñÿ¸Ë‰ãÔ·JzD‘öá¥:”c‹!"&y‚Í?ÉMM4?ÌÝitæb–š¢ŸV)ÕEkÐø$ÛrŽCÚãÓ+”¿²½­Í†£—÷‘ÿd?_Çæ‚ß~vùãË¿—~Qg6×Ò£ÜÜ20-9Í4Šfƒ7¹ØvƤ{OÛ±ÕpÃô Ï™ýÔ,ysJò‡—tÏ+èˆ4&Ú+KHö¯”/&"•f?7rIË=6Å]Š»v*ìUØ«±Wb®Å]Š»v*Ç|Åä/&ù·QÒuo3è–šµþ†ÒÉ¥Ky˜[¼ÜyU5à¤r„7ÅVù×ÏÞNüºÑÛ\óž¯o¤iËQ™«$Ì¢¥ …’F§ì¢“ŠÓâÌïùÌo<ùúâ-þMØÍ¡é ðK­JêR)¨,¦¦;e=¨Yû†S¶]ƒO<¦¢-Ã×öŽ $8óHD}§Ü9—èÿ—ð‹—Õ¼ÏpÚ¾¯;™¦i]¤C#³;?Å#Ô·Ý“±á çê?gí|»¶½¹Ížá§ýÜ{ÿˆÿÄü7ófŠŠŠ*(¢¨À ÜO);•ءثÑ|Ë­~F~céÿ˜ž[RúTÎaÔìãðJAžÙ»ÀsŒþ˨4øs”í]‡.8ý2û ìþÆöÿæðø9ï1ôÑï÷ŽGà_§>SóV‰ç-é¾kòåȺѵXVâÖQJ€Û28ñt`U×öXš‡³|Aÿ9½æ#æÍ)þ][¿+m&ßë7Š»qŸQĬ£õ²í>/$cÞ\.ÒÕþ[M“/óbOǧÚÄ@ ¨¢€wÎD’l·Š»I¼Ö°·–µQqOOê³˧0¤§ÓÊ”Ì]p ︻gŒÆ»>8ü¯²ÓÈÉŒžJhËòôo'UZ‚QJ£RªI9çÙy¾ÅÚ£÷¿¥ånµØ«±W®hÿvú—ca¦ynÚÝããú@ÂÞ”rñز*­y0ß““Cã–ŒµÑÚãí!€"<Þ£Ÿ,]\_~kY_Ïumõ)VKiÜ·Õ0$•P1< mþŽX+êsñðs{|Ÿ6ÉúSÌz­ÕÌPÉw¨]¼÷r¤(Ò1©2Èh š ó›Ïž)Èžd¥øÝŠ»yÿ¿*4?5ú—ÖtÓu¶©7¯î¦n¿¾AÔŸæø×'„; /hOÇpóD×<éùstš_š­^ïL¯'åÈáš”m¿a÷äåàƒÉ†³±túÀgˆðKìøÒ>×¢hž`Ò¼Ál.´ÉÄ€yøeŒø:Çϧ†ŠÖè2é¥ÃWŸCî)ž.±Wb®Å]Š»v*ìUØ«±Wb®Å^yùiÿ“Í_ë^Ô`Âû§²¿ÝCþ¸=‹­v*ìUØ«±Wb®Å]Š»v*ìUØ«ó_æ7—¼¬ $úÆÜ‚ÊâÇÜ'Ó¿¶.§] [s=Ï(º½ó¯æmÅe?TѾ’Ùh~ù3#šY9ru–]IîÙûY¯—¼¥¥yu[§­zEî@ šõ ÙG°úk›|:hãåÍÏÁ¥Ž>\ûÓì½Éc>oód^]¶X`]Và«ÅÔ é͇…zç1µ:Œy¸š­HÆ6æ÷ùÇßùÄc«?1?:á{›‹¾7–'ªü'u’ülw+n(û}Ðie##eÐO!‘³Íö••žk ŽŸo¥ºˆà¶‚5Š(Ñz*" 2-o ÿœŠÿœlòÿæî‘s®hÐG§~bÙÄïe¬k¨_†Þî€rœRCñ'ºÕqH/ˆ|‰®Ýß[ÜhÚ·%ÕôÆ1ʲ‚%(§ù#-ôW|Üh³ñŠ<þÐê8ãG˜fšç»v*Çü׿{-Ø6“P˜kî{»’?™¨Î17S¨ãæúþqþqæâÑ¡üåüÄ·2k·¿é[ÓîWâ·ŽAµìªÝ$pr´øâêWŽŽR$ÙyÙÌÈÙ}ƒukm}k=•äI=Ìo Ä(d’9«£)Ø‚ ÀÁùyæß(Éù5ùÕ®y ƒ.…{ ›Gw$†µ¸¬¶¦§©Z´ {°9™¢ËÃ:è]gæát)þn]ë±U®é4’0XÐv&€*I8“H&˜W”ô9¿7<õÊpËå="’OԗóLFþ €Îo´5vl|;;FuÚþˆóý_¹õ\qÇkJ$QUU°fô€_ÿ+<©ç˜Ú[ûªêô¤z¥° 5@ØH:H=›2Üy¥UÚ=‡T.B¥üáÏãÞÃ<³çïÏùÆ™VŸüSùsPÙÌd{h£&¿»oŠKVûã©èÇ6óÆ^÷í.Ãͦ܎(ÿ8~žçØ”ó‘–ÿœÇo£^þŽó/Íåí@¬Wu¬a5ã2÷ŒÔ´«—:RµŠýoBѼɦ\hÞ`°·Ôô›¥áqgwM upEGP{b¬cÊÿ”–þJó-ï›|©åë]#[Ô-ťĶŠc‹Ñçê0ŽxGÈ…åÁEx YJDófø±v*ìUØ«±Wb®Å]Š»v*ìUتPÔ,4«)õ-Rê+->Õ ·7w,PÅîYÝÈP‰8«äÍ¿ùÍÍ2ÂY|·ù9gú{Ycé~œ¸‰Í’7Cõx™‡fn)ßã(ÄÈÐXåÉ q2™ˆæNÁó%Þ‡æÿÌ a¼Ñù¡¬ÜêZŒ»úRKÉÂÖ¼$IÿÄùfóIؤï“o'ÎûkÛØÂá¥Gùç—Àuøü‹-²°²ÓmÖÖ··N‰ ¯‰ñ>ç:x£Q3Õk2ê&g–FR=OãìDäÜu9æŠÚ.'`Ĭò9誢¤ŸÁ)‹<ƒ€}šìíÖæ#$‡(ôùFGâh'ÞXóIÖ¤ŸN¿·6ZÕŸûÑlkB+NK]éR6÷-oŠLd8d9‡AÛÝù1¸¥âaŸÓ/Ðü“KOµÕlfÓï¼ëŇqÜ|AÜf^lQÉr.—C­É¦Ë¸ÍJ'ñóDþG~}ë?óŽšÿ•|Õgs¬yõšâÚ;b¢[yéOZÜJBà,e…Ä kËŠÕie†\'û_}ìŽ×ůÂ2c;ÿzÄ÷~£Õˆiú¾­ù‘ùƒæÍ=r?N]JâW¶Ž¥„a€#F4ªÃ ¬@÷ͧb鉑ÈyOí÷kF8†š'Õ#rò>ó¿Ã͘çJùC±U »ËKZâöd·zÉ#_¼ä'’0#A»O¦ÉšBâe#Ð b:n™æoÏ/6ZyÈ–ìönë%õó«,Q@Œ9ÜNvãW`wf 9~ÒíÓ§ï}ƒÙOe¿$‘‹Éj´YpÉÇ$ÃØ«±Wb®Å]Š»v*ìUØ«Ï?-?òcy«ýkÏúŒ_töWû¨Âã÷±bõ®Å]Š»v*ìUØ«±Wb®ÅX·˜ÿ0|±å®QÝÝ ï–¿èvÔ–ZŽÍCÅÙ‹‰Ÿ[3¿sËõ=ùßÏ2=—àm?N? ˜ZÄÿ¿. )òZ}9n<2™Ø:™ë3gÚ‡ãª3Aü¶°²+s¬¸¾»ëèŠú zîïôíí›<:Çyn[pè#å¹g‰ª"…E*¨ t ÎØ»v*žÿÎ ùÏó7óOZüÀ×ãZ_• 2Ø[H*{rÎ-MÄB‘3Óùøç²äã‘/1¨Êg"_¡¹[C±Wb¯ÎOùÊ/'ÊïÏh¼Õi£åß8«_¹.Y„wËSÔ‡)9ÿ\eÚ|œÊÒåà˜)x ŠŽ™¿zFñT›Ì~c²ò呸¸<î¢ÚØ4Œ?RŽç)ÏœcZ3çÅ—¥Î1ÿÎ<_þbêÐþmþgÚ“åÈÝ&Ðt™’‰¨º¤²FÕÿFJ|*½=~óÑäÈfl¼öl¦fËï@: ƒK±WÈßó_—2ê¾VÒ?3ô˜é/,Ê-5)#_ê. RÖ‘O@üXǶ Ó(š/žô Z=oI¶Ôc#”ªÊ?fUÙ×ïéíœqéðåãˆ)žXÚÂ?25;˜lmtk*›MÊ0O´È¤ýf`? À×åáw¸ü†„G9>„ü¾òe§‘¼³k£@®ÈjýÝràs5ðe}†rYrq}²ôÒáúžòÊr·`ìU¦Uu(à2°!”Š‚PF*CÈüéù£jÓgÉó‡õèØK‡’Z´Šj*|Q5z4{å̬z’9îó¥ìÎ,×,^‰±?«áòO<…ÿ9Wù›ùI{•?:ôÙõ;²œMúF»sYvŽèM–OænÙ ‚Cg„Öh2éåÃ’5÷q}äÌ?&~dhé®y3WƒT±4ˆÉY cûBôxÛÙÔ{m“p™>*ìUØ«±Wb®Å]Š»v*ìUØ«±W€~qÎZþ]~W›#Ky£ÍñU›c*‹kw®®€eR;¢zìÁzâyÃΛŸž÷«}çM´ÿ-«ú–š< ÐZF+QéÛV¬Â»K33S¡#lÚi;+&]åé#Û>Ùi´— ¼Ÿ—Ò=çô±¢yoHÐ"ôôøÈE$¸ŠWù·ðgK¦ÑãÂ=#ãÕòŽÕí½NºW–[tˆÚ#áúNé¶dº—b®ÅRÏ1YM¨èwöVÿßÍ ¬cÅ©P>šS1õxÌñJ#™ϱuQÓêñd—Ó ÷~ăò÷YÓî4˜tDNÅdúų!SA&ïZSr£­s ²µ0ùJ<ÃÐ{gÙy¡¨– ú±ä#†WåËä6éI¿èm,y›ôÂÎWV0{`éF‹dæRœ¼kLÊü¼F—¢$h±Æ¡#Pª€°$¹LÈÙ6JRÕ,4‹V¼ÔgX-×nMÕ‚¹>Ã*Íš8ãÅ#AÊÐè3j² x¢e/Ç>æ/¥ë>{üÂÔ·ùcåÛ­Jë`ó$&SmƒÈº‰kûRµ3A¨í¹±Šó/¥ö_üñÄ jeÄ›‡Ï™øSÜ<‘ÿ89æ¿0Í­ù¿æSh„†m#MassÄîQ®÷1hÒAïš\¹§Ü½Þ“E‡MPCïïø¾¾ò寒,tq¢y+H‡L´j5Ä«W¸¹qûsÌä»öäh:(l­ÉNõÍHó.‘y ëÖqj>¡Ayg:òŽXÛ¨#±Aƒ¸ß~x~l~Pù»þq£Ìïæo,¬Ú·å~¡"©w%ŒÛá¶»*>ZÒ)©FéÖ«‘”m§S¦ŽhÑæÉ<µæ#ÍšjjZDÜÓa4-´°½*REìÛ1eg> b•I9ÀÒìU—þ[êþZмɧæh¤’šÑ‘y¬sÕÙ:š~Í:þRîåèòB¹2ËoÍû^÷S´ó®™õï-_ȯkl€;ÚTJÖ£v`ÀÖ´ëLŸ‰|ܘö€‘"bâ~Åú¯š#óðÓÿ.<‡§7C’E3<Š÷q·¨Y‘ Š~2Krf§~©—Á93øÕ‹ È¼Ãÿ*±n´ÏËmF)ãšÄÇ WÖéúRÊ6Y&5z±~MEãÈïÓiMù| G’ù÷Ê/ä¿0ɤz¦{gn-&aFh\•€Ú¡•”Ó­+í•N4]f«OáO…Œä\gb®ÅRícBÑõûoªk6Q^A¿*Õ‰Fe>êFHlÇ–P7O(×#d·›ô‡“57¶¸CÉ-®”¯ücž1È{_öYlr÷»Hv˜áËŽŒy¼Õçÿ&:Ûy³L{‹`B‰ä^5ö[ˆ¹FßMNZ<œþÏéuâ—û>GvO¤~dy_Tâ’\ ƒAéÝ‹_i)O™ÓÎêýÔâÜ1ýÕÍ•Ç,s"Ë ¬‘0ªºÊG±bé%DQ_‹b®Å]Š»v*ìU矖Ÿù1¼ÕþµçýF /º{+ýÔ?áqûƒØ±z×b®Å]Š»v*ìU ¨jºf•¯©ÞCifžEŽ¿.DWèÅ„òF"äiçÚççO—¬CG£C.§?g ÁüŽGþéÂësv¬#ôîÃnuÏ̯<Õaå§érTR.VЕ>.k#=²üziÏp¥—QŸ–Ãä˜èß–ze¡Yµi ôý}1T„<›é?Fl1h">­Û±v|FòÝ›C6Ñ,ñ¬P ¢FŠTx6ÌÐØ9à°T—b®Å]вùÃ=iþ@üÈó寽2ÚGæCésÊB£^Ú Qr= ÑÊxW«Q»g;’2!åóã1‘ÏÐ<ƒK±Wb¯ÿœ¬ü¬—ó?òªñt»s?™¼¾ß¥t”QñËé­. _ñTª÷u\R á¯!y…5%-&÷!b«ŠNïÙßm¿Ï7Z<Üq®¡è4Yøã]B7Ìþj±òÝ·)šþAû‹PÔcþSx/¾YŸP16ÍF¤coTÿœtÿœbÔ0oaüÏüß·qåù8O£hSU úý¤–dê–À}ˆúÉÔüoI“!™²è2å36_yEPD‹1¨Hã@UTP*°t•ø«±T·£i¾bÑïô fÝn´NÞ[KÛw­$†d(ëQ¸¨=Fã~gþh~UùÇþqÇ͇Š][òïQ”?SQð0?f9HŽáÆ»HGù9}AÆ|œÍ.¨ã>It~ò«À&kïL‘SE'0|(ªGÜsh5˜ë›·ÜuvÇ^ÏÍ›šý¶ùy ÞêWújÉ8{u«ªŠ775á>͹ØoAšÝ^qŠn«T' cµ='Jüÿ»Ðæ:æNy§k–„GtñÃéIËÆ[Yý6CãB}€éšyé;‹Õh½­h›ïêgz_ç徫ÄE®Ão#uKÅ’Û‰÷iUSîl à˜èïpöö“')ïÛïfVwö:Œ"ãO¹ŠîÜô– T?ì‘•C´Ç–3òD`fìUªéf¹c&›«ÚE{c(øà™­{^„v#q†2 ØjÍ‚bc0=ïÔ)|ßä `y¿òcZ¹Óõj~¢&á/ ÔÆ®ÿ¨i¼S å³7«¤ž/´½•"倨þiýõüÞÏùSÿ9­g5ÒyWó¯Oo/k±0…µ¨¡‘-Yº­[µd…v^IÞˆ30x옥c!Dt/­´ýBÃU²ƒRÒÓîKmwo"Ë ±¶á‘Е øƒ…©Š»v*ìUØ«±Wb®Å]оÿœ¬üÝüáÿ•…wùRn×ÊþV›ÓrY;ÆÚÇØ–{9ñ$2…Ây뺊ÐýbUPÿÅi¸=ϾušNÌÇ‹sê—ê|[¶½®Ôën øxÿš:ÿXõ÷l<™VlžU-ÖµÍ;@´7šŒ¼ík¼’7òª÷ýYF£S 1â‘v]—Ù9õ¹<|ùæ$ Ûøù=GiöwgvvžX¤N]D‡1üô}²>@³œÜ<+±Wb¬gÍO§Þù‹M³ô¹E…®B „‘Ôz}ªPuýY¯×†É8¹[Ó{?k³cÒæÈ|+âá¾ ‡w_·«Òît_-Z§šu[ãªy†þ>qEœ™yÔïµ:1nñÖàž<ñg.9ÉêûC«´2 ~ f‰#»¯ésç#ÝÑtë³coxa{vÌ2©WBz‚o±d㈕U¾o­ÓxeˆK„ÕŽE–8ÎÅRoË!Yþu~yÃäß0Þ½¯—ôøf¹šß„³ÅlªÍDÖ#0,ÝBMÀÎ?µsæ òŽÏ¸û¡† 'êÉê'îú_¤ÞXò§–ü™£Á yWL·Òt‹qH­mcµîÌz³Úv%RsZõ)Æ*ìUتRÓtýbÂçJÕ­b½Óo#hn­.dŠXÜQ•ÑUð_ç_üãgš?&µ;ÌÊZóÊ Ê]GG«O>ŸjÁ”’Ó[æÝã·BùFØeÅ‘á’_äo>i~v±2[ÿ£êpõËj²WöÐþÒßïÌižoU¤–¿.öY‘qŠ»{‘µo.ùÈ·ÞjŽæÏ4ßk ¨`d„Ôúq²Âíê9èhZe°""ú»]6HaÄgw"˜Aæ/Ê-jþ;kM-Ÿ˜¢ô¥¹ÓøÌѽÌ@p¨¬p)ñŸ뇊'vÁ›O#âKiw<ÓÏžl9yŠ}_ŠÔ*ÁgnÉd•åMªI,~y\åe×j³ø³âcYØ«LʪYˆ I;sŠ¡bÕ4Ù¤Cy’‚$ÈÌOÈãLÎ9ˆ¼X,–(¦¢™HœQÑÀe`{v8¤`úçå’µ®r%™Ónš§Ö±oHTøÆAîQ“sqvŽXu±æÁn¿&üá¡H×SÖĨ }"ïk#xhÛý‘`Ê:¹SÖ`Ì+,ûjO0þhùdñ×ôW¹~ÔÆFßñuµcûòb@¸9;E›û¹pŸè;¢ì7ôi¨5 )íX÷Œ¬È>gà?ð¹*u™ý’Í¢B^ý¿["³ó甯iéê‘FǨŸ”úe ?§7aêñóÆO»¹<·½²¼­.b|b‘\“‹®É†pú¢G¼+âÔìUØ«Ï?-?òcy«ýkÏúŒ_töWû¨Âã÷±bõ®Å]Š¥×šþ…§Wëú­±V[ˆÐü¨Mqj–hG™Ž_þky"Æ _›©ì[E#ÿëÿ ‹>ÑöÅ5Ï8*cÑ´‡‘ŽÉ%Ôwíû¸¹Wþ ‡>×ÚM7š?5¼Ì8ÚFú}³÷‚1j´ñJKÿÀ¶] 4åÈ4F§'-‡ÉJÛòÎþö_­yƒT2LÛÈ#-,ó–^ÿìNeóÏñG³å#s“-ÒüŸåí#‹[Ù¬“¯û¾Þ½|G-‡û37šäÜzXCOr÷!Ø«±W·yCò[A¶ò̘™ÚYùbHãž+["d’E—dY$Ujv)³{ƒ˜Y5G‹†w]—Y#. ÑŸ˜MüªÔ,Ï¿—ÑIaõ˜íY%{ŠÜ‘chÊ\3ü@82ž€ý× ÉÃ&83ex'½¼3Ý›±V-æï(¦¾‰yfâßX·Ñš¤Ô+¸¡û-Û1u:aXæáê´£ ±Íë¿•ÿóšiò<0y_ó‹I¹Ö-­•cƒ[¶à5M>ꬅc¸ ÿvVþbä×4ó‰¢LR‰¢)õ“ç#&<ò"FóeœÒÐ IŽŸqÌþ­Ð@íÿÙ² tõ%euWF ŒV ƒ¸ ŒPÞ*øcóëò+òŠO9]ëžRüÌÐü•æ[™]KB½½"Žw$É$fõ`äMLe­iÄm„HÃ8ÌÃ%üŠÿœJòÖ ó×™üÓcù‰,N }:E¸Ò–u¡i9»NW¨F ¿Ì­‰$óYLžo°€è00v*ìUØ«±V5çýoÉ^_ò–¥©~aIhžRHøê ϪÄÑeoQ˜ÓŠ$žƒ|æüáMÿ™È¼ü±Ôí4¹fîP^]¬Hyͬ`½â±÷*?`ôÅ–ï¼<‰¤ùKòå›þ^YéöžY¼.mJŽ4‚tqU“”`s$uf©ñÅŠ3Ì>Qò¯›m¾§æÃZ¶‹¡i Ð_uõU¸Ÿ1Wù‡þpóò_äñy~]á«Yô»ÛˆºøE+K§´x¦Þ3æßùÁsËË&µù?ç ÒPüQiÚ‹ i¤WŠÞ[qNG W‰T÷a€ÄmØuÆn$Äù0/&þiùƒFó ~^~lØÉ¥yš Ù.§Ñ-!ÙuÇ· Sà`GúÇ6š·‹Ûö7´ž!ós<¥úÿ[Ù³ ì]Š»c^nò–<ïkèk¶jóªñ‚ú*%Ì=þ éþKU}²Èe1äàk»7¤TÆýýGÅæZ;~uÿÎ:^ɪyQ}sÉ¥ý[Í&Ti *7&kZòCN³@Àíñ6ÌüZ‘.{ƒí/g3`¹G×.cÞ?Õ_“Ÿó–—šWÒu –|á%ô]ô«è\Hv¥­É ®Od`¯à\ÈyÂùŠŠ»v*ìUØ«±Wb¯ž?ç.¿&Oæg[Ì,§œ|¬²]Ùª-dº²§+›m·-AêG×â^#íœRùÌc_Ògjê6|b¹¯Wø$ÿdþõÎdz5~6=þ¡Ïõ¾ígb~GRLGîç¼|»ãðû©”fÅåÞùÕõMZ¼…®tkY8]D ¤¸jvø¿S¾i;V58NBâ9¾ìn^=>£OŽ\f.'¿jû>Ë¾Šš‡æ ]2iÞQ¶{ýBQDs,qûñjOz(Éeí^/NÄK^‹ØÓŒºéŒpKŸŸ•’˜ùzâçG‘tß2êés­j/êÃk^F/‡uä6Óa@+ök—é',g‡,îRéøüw:þÚÃV]& 8…wïμºÍ}TÊódònÅVº$ˆÑÈ¡ã`C+A¨ âEóLdbAˆ`Í ùkÉú”z­ìR\ë¡£pг2Š‚T oF¦Àl3Lt¸tÓã¾#·t^î=¯®í\9øp¹nx²WÀóîêNå+òí×›Tžsw-õŵé¶Õ´çaéÇ l%“(CP(íá˜ÚIçã&̈•J>]áÚvÖŸ³†ž1àŽ8Ï,ƒ™þPóÏ^÷¢G©éÒÏ´WQI<Êïk"±uCň¡Þ‡øøføf ,¾s=xÀÎPŒHv'qø÷w¢òdžëMæ/$ù§OüÏòdÆ gJ‘&—ˆ,>àK¨§(Ý+«ü§çœ÷lhI>$~?­ôïaý ŒcùL¦¿˜}ÿÃóÜ|»Ÿ¡‘ÿ~^üëò¢ë:w=vÓŒZÞŒ\4–³³/v‰èLoM÷âg<úiOÅÅ]Š»q‚¨=F*üÖüÍ´òv‰ÿ9<Öß•’ÄÚlä~™µ³§Ôíï$I ä0ðªðPB£e’ª)Çhdäãk€8M½1^YØ«±Wb®Å]Š»KµíjË˺EÞ³¨5-m»NNݽوQ„ -˜±ÈDub–’ߘ¿ó“Oæ=kS>^ü¾†fŠàÒ‰ñÚÁTS£Ì涨Ur££š†Ã~÷±^Ï¿<öœ4ÿ7j°_P~úx-gŠ´ß÷H"n¿ñfIÈây·˜ÿçÿç"?,‘ï¼›ª§›tx7ú­«±¸àõ²º¨ú!‘Û"` “K'0Ç<¡ù­©¨.yªÌè¾dÌ ŠñÆó©âb)'Ç×nß½vÊ'Ž6¯³N1ÅÃÒ²·XìUتS©yc˺Ác©éV·NÛ™$ Ÿðtåøá!¶çD†)}ù1ä;ʘ­&²cûV×÷7¨? Ê\¸vžQÖØíßüãþ˜Æº~·qnAª™¡IÈßü†‹$39íyuˆ(6üšó¦ÚgšhÙ¬—0v§ìÉx¡„µzyýXø¦/7ík°Ì®×rµHíû؆5˜h%Ïù~¢Ñò·çlCš^E#ˆ$¶5úÇÄ‹Éöqþ÷_­ƒhÒyêËÌšÂhÏÇ_ËÈÖ¶žMÑg{]E刲ÃBVeeãsVä«3ƒ×|„±3-Ë\ðÄcã3õÏߜڗô¿Ì}jËËA#ÓãxËÁ PÜ4jf)°ë°û&«Û6S#nÓG)`Ë›ËÜ—bª76–·‘náIá=c•¯ÜÀà”AæÆQb¶¡ùqåËÚµºIe!Þ°½V¾êü…=…3z[8“Ðc—-•´4þn~JÕ<™æiŸC·eiôÉ™¤³e,*$´”´{ô/ÀŒÀÏ£”ó»Q¡”ó ûÍó¿œó¦*y:ßü- ¬ vk9¤Q,¬€Jf¹ uˆž\ O‰‡Úçû82ÓÙý›—U>yèôoùÇ'ÚZ*ëWWZñ¼’7ñþB(-÷±Ì)jåÑí´þÊ`Œ}dÈü‚Oså>~@k çÿʽRâm2 RÆ_Œ5ºµLwQ'šÍXÉö…ä/éâØót]±ìä°êü“üÞÑ9ü•™ôÔšŒMõmgKçÍí.”V´£Ê6¦ãn ”òÄ=;v*…Ôõ=?FÓ®µ}Vå-4ˤ¸»º™¸Ç1)gv'°~u~cyç^ÿœ©üÆkKaù[å÷&ÙHàÌ„•7ZÏ0Nȫȵ9²ˆqÙ•-^JåõÇVy©þYùCPò³yN=:[”¶–(Ç­ Áh³ûEë»?C×5ã4„­ôLÝ‘‚x|.Nð{ýÿz3þp·ÏúŸ–üÇ®þCù¢pÙç¼ÐØÐKåu Uê²!ú º;~Öm#+ù^«O,9 %Î&Ÿkäœwb®Å_7ÿÎc~Si^tü¶½ó­¼ šü¥ ¼†ñ@WšÁ·HÝÕT´©àÃjrj©ä”~d¸óGôÍBõÌ—ð‡³º‘K½»pIêY8³{œÔç‡ ‹ë‡«9ôÑ”¹ÁœeNÙØ«±Wb¯ üßüµò=Ɖ¨ù²çýÃj6±´­uj«ÆæC²$’ªÌì@ šÎdàÍ+›ÌöïdéÎ9e>‚:Ž¿7´ÿÎj¿šZï“õ-GÍÚ¬×ÞJ†E³òâ_-É–/ïÚ9ßã0 ã«rªÉórú«;v*ìUØ«±Wb®Å_œ_ó’¿–~HþfÅç_/[ò/™äw0Æ´ŽÚå;›@ûØÛUFÈs+G©8r ]}Ϋ¶û&:ý4±|â{¥Óõ$µÌ–ñ][8’ÞeY#qÑ•…AÎÚŽEùÿ> ♄ÅJ&ˆ],QÍE2,‘8âèà2°=ˆ;& Š,1ä””Iu V¾¿³Ô¤òד4t´¼uW¸¾XR4û† S·&ï°Í6|²ŒÎ,£ÔÓÞvv“\WÚÌà ‡&ÇNÿ€÷“I—¼g¥KúGRê:Ëmq-YQúÕnOùG–di;68ϽRïu½µí^]L|,#ÂÂ6áGtò{ÙflžMØ«±T.£§Yê¶rXßÄ%¶”Q”ö=ˆ#pGc•åÅ‘1°\­·.› ÉŒðÈ0ÝF=/òóMxô»w»Ô5Wô£ŸS‘QѨ rû o\ÕfÑ .Sï{=õ»œÒÇ„YáÚ½Þf¹ô¤–|§yåÍV×UÖE ‚Hœ»Ë(Ck1?  ¯$xl7ö­= °LNuUò.nûE´4óçãâU ãRzöòï5Ò••”2TŠ‚7ã:_3 ƒEÄ" ìAÅA¦kyæ_É¿6Úþcy SÀÿé–G‘ár ÌŠG(^?dЊåûO³¼?\>ž¾_±öd½©üÈ3ŸÞ¤ÿ;þ=÷¿E¿'¿8|­ùÍåhüÁåù=èxÇ«é077W‹Rœ‘¨LrF F•îÈz(Zî‘£I#gv *¨$“Ð Uà_™?ó˜”~A3Xé׿½v*g¤2½²½iI/§ÌŽëŠ@|ÍæßÏ/ÏïÏ$“OÑ£Oò]ÍUÒÑžV&¨¤·ŒÒ‚ aUFý¥ÈJ`8Ùµ˜ñs6{—yòãIòLM:9¼Ö&^^ºñ¢Ö¼#Zž+ã½Oá”NvèµzÙfòÌ‹]×´¿-é²êº¼ÂH¨+J³¹û(Š7,|?†D qñb–IpǛέ¿>ü³-Ï¥qayolMôèEÅw]‡\UÄ%XPˆ=AÅ]Š»v*ìUØ«ç¯.ÿäÉóoüÄßÿÔiÍ×fóø>ØŸHþ¨ý ÷7@ìUتœ³CòšE|]‚Ç@A sYݤÍÂã‘ÿ•XýÀàªäUð²v*ìUØ«±WÒ“·Vÿ™–:÷åf§ 7ÖQ´º[¾åc‘½H˜w¤SÿÉ`½3[©A0êucÂÊ2%ù'ùqæû>Xk3YO§iz%˽íäècVxy#Ao¶K|-Çe¯jݪÏ9’ß­ÔC€‹²P?š}Où\Sù³ÊÓ#*[hí®“t¸{hÂHI_´Œy%Aø—%§Ãû®ue¦ÁûžuLüõÿ9æ¿2$–\ü?¦>Ï$OÎöAJÍ@¨ÿ(ä1h£Îå†ÏŒw–åã ÌÌY‰,MI;’Os™®Á¬UØ«±T«¬iú-©»ÔfGÑW«»*/Rr2ÆË^L±€²À,›YüÜó5§–´ðl´º´Ó7ÛôàJsšZ ¢¯J+ß4zÍiòptøç®Ì1Çaú;ßUùgË:G”tˆ4] ¤"¬Æ†Id#â’Fîǹú4™‘²úVGOŒB€û|Êq‘rVº$¨ÑÈ¡ãpUÑ€*ÊE õ{–~Cë¯ù'ÿ97“g—Ðòœ¸Ú®Ԍ4ÅžÁÅz•—•·û#›l3â¾OÛ:Ëg”.cÜý Ë]K±U’Ë<Ó:Ç j^I…UU,ÄìN*øó÷ó§YüþóBþSþZHËä‹I‰Ôõ O¥¨<.?#-io Ä¿¶Ôn¼†Iˆ‹.vƒC=NAsû‡{0ò‡”ô¯%èphzJR¾9¦`=Iæ`9Êäu&Ÿ@ è3U’fFËêÚ4ØÄ!ý§½=È9o üÜ:‡åçŸü­ù¿ ¥.lî¡`l²Kly*¹¦‡œMþJæ~’{SÂ{Y¢©G0þ-¿§Ù÷?Eü¿®i¾gдß1èòúÚV­m휴¡hn#%GcC¸ìs1âÓUØ«Âç-¿14ï#þNëZl“­ù¦4m2Ô5D¸.¤ oÁ!-SÓ‘Uý¬R?~Ihsè_—zj]!ŽæøÉ~èEYÛ÷uùÆæ¯Q+™}OÙí1Å¥ó—«çËìzPîÝŠ»v*ðŸ6Ǭ~y~hé?”R:ÚàRõAh£h«õ‰Þ†…`Jª¹9ãÝsc¦ÅBÏWÏ=¦íO'…é‡?9~ÏÖýò¿–´'ywMò¶ƒ·Ñô›xím"Ú¼S“YYÛ»s)äÓ|UØ«±Wb®Å]Š»v*Ä?3¿/4_Í/$êžK×½üu¶º ÊKK¨þ(n#éº7Q_‰j§bqWæž‘o®~]y³Sü¯óŒWÔ¬'hà©% Ÿ‰}64ªJ¤I÷ñ9¾ì}m\º~§Î½¹ì8þkÜ}~î’ør>^æm#åMb¬oRó¶a.fã~ƒˆ‘Ôý]%eª,Ž7´©¦Ù¯ÍÚ8á# ßì¿7¦Ðû+ªÍ†9ø} >³¦#îïDy^—T{« Bk¬X0«rFW’D?ÊFY¥Õ— ”yþ·¶{":a ¸¥Ç‹%ð“±ÛœeæÜÌtNÅ]Š¥ºÎ‡§ëÖ«k¨!dGFèÜ]w ·ì¿µã=`ÔŸIt—‘þ—ßïçï_É/ùÈß&~phRÎfEó>›O­h×éEøî!‘¸ó„u-Õ:7bt~CåÎ/ο7ÿÎBùªçÉ>Dº—Lü³²b—©xÅú§Ö.©Ä”j~æÜüÛ³Jšuˆá•/,~VyOËJ’‹a¨j+Bo/†Ñ>Âûm_|Ç–B^>¿&N´<™¶AÂv*ò­D¸üÔüçò§å\´vRÍך?´ˆènnd¡)lœ–¾ù‘ˆmoAÙX¸`eÞýÔ(?,5o,Eäëÿ*éÒùzÞomkõtVB…åËIQöÞEpÇ©9k²·Ç™ÿóŠÞü£»ŸÎ“Ww:ß—V¯w¤0ßÁîCD -Ê èQD‹ü§vÈÊ °Ë†H1Ÿ$~khþhá§ê\tÍ{ì›y‘LÃcé3w¯ì6þÌyã!Ðj»>X÷‡ ä{±Wb¯üøY­ÓËz¼`0²¹œP׉wH Óþ1» ¹ìyo!îFhÿ^ÿœ‚üÇ×2¼ëÎ}"„Z~œì}8ãµ½¨ãAÂ$ ¸æÍÈדW{Ùz!–FRä>ö}¯¯8b#ª_`{m­­­” mgvöÑŠG (±¢ªÔF <|¤dl›)»ä/'ù‘[ô¾o,ÍÖåÑŸþFÅÅþó”fÑâÉõD985Ùq}2?¡ãvü›Öü«a©j>HÔnfÑî!)ªi~£$¯l¬%*ÞdVPÜYj(ç4ZÎÈ0PÜwuz-mŒ„G £ßÓö2¿ÉVÂ÷É6Ö„‹5åŠî6¥CK#L’ymò>Íå´vž22’z½ ëÞùSåIÚ;ùŒü»£r–?P|3OåZªžÚƒÄe˜ãÔ»œÞKéŠeùëm Ûù{Ìö«ûFÕµAó]—˜àC4PóŠîØ7^ÞUâé_Œ¾àeY±qÆšuFH˜²¿=~~y×Îpͧ[ºhº$À¤––d™eB(VY̓Ѕ êU‹GoÌ´`ÐÂó/,̧5Ø«±Wb­3*©f ($ìÎ*Ã5ŸÌ X&o—á:®©+âxýF4U^¹'²ýùƒ›]í˯ϯŒvŽçì{_äïüáÿš<í}œ;ž};Jø^Û˽;ë…ûAgãþóÇãýáÞ¼çW<†f˧˚S6Kü•²´Ñ2¼û¡E­Ý”óÛÁl~ÔQ[^Ɉ+¿Âx˜ÎAë}ñ&:Ðû÷ý{̼v*ìUã_óž[žãD°ó–™Ê=O@™KÍC¬8âàëHð©9•¥ïy_j´\x†QÎýÇõÛŸ“˜ÖŸšŸ—œ t7·0¬:´)OÜj—T}‘Ëã@a”÷Í‹çe›^^Ziö“ßßÏ­¬o5ÍÌαÅQ©gwv T“Šþx~yó×^ÊÏÊI$‡ÉF©ªj”xN €Žo! 4vËÐ&Í'q¸\„æ",¹ºMFA þï2È|‹ä]ÈZ:éšbú—Qﯜ-Ì u> ?e{|êN¯&C3eõ.ÍìÜz\|1çÔ÷²Œ­Ø;H<ëå{o8ùgPòýÅ®c­¼¬?º¸OŠ'Ûz´ê*2xçÂmÃí Ôa–3×—¿¢þq+óÖÛÉþ§äæLߢ®¬®dO/Þ]0H•årÏe$Œhµr^û-È­~Åvñ ‹‘gÃ,r1¢9¾ÜÂÒóÎ?Ï_$~Lèïu®Ü­×˜&›Lòý»©»¹nŠXoéÅ_µ+ uâ¾RâM:ÇÎ?ó^t?™ß™U_/!¦—¦ ¬bRÞ;ˆTï#ä5ëRF.|ü;oSØ=„s‘“ ôö_±îÀ€lÍsè®Å]Š»y·ç/æòG—Mµ„”ó¨+.'â:I9äÖ‰þWÈåú|\GÉÑv÷j~[DúåËËÏõy½Óþq'òI¿,|–|Ëæ~xó:$÷bAûÛ;#G†Ø×pÇûɇóQOØÍ£åÒ6ú';v*ìUØ«±Wb®Å]Š»|Íÿ9wùÿ˜~\_>yVÜŸ<ùr&gŽ}]BÂ2dh”.æX^*n~%Ü•¢ )Š;‚ù/É>hO1i¼g`5;Påzs¤À÷ð?Fv=­ñ¡¿Ô9þ·Ã}©ì ÏqþîO—ô~<¾,£6/.ÁüÏ êVÓ]_y~º:Ç}FÊThBÌ *VŸ¯|Óët³‰2Æ/iÒ÷ƒÚø2FõR0ð.Xæ 8ò7± ¶Ômü޲ÚZ7é4\[¢¥ž!A#r@íR™… £K`zò}º=}ûd‰ÌxhÙ!)p¿Åݽ#HÕìu»$¾°•e‰¶p+Tp*T‚¨ùfÿxåKæ½¥Ù¹tyN<¢Þ;Ñùs‚ìUت[ªè:F¸¨º¥ªÜza‰du¯Pj{W(ϥǗëì{;µõ:2N˜ß>D|†¨iú¦ þSÒ­Nå«>2^OOïë¸nUø«O†§µ[¥£. dŸƒÁÏÏñý¯o£í,:l#]š~>£&ÐÍò®ž{u¨ó²ËÞkµÐ5[½"kæºòŰÚÝ«é½FÕ‰wòïJŒ¯I®Ž˜^1È×êr{gÙìší<3dž¢{Ê<\ÆÿÎ<ù{®‹Ó!š+ˆ’xI Š9ÕYH¨ Œèc EŽO˜åÅ,r1¢6!S žù³ÈnZ]cËE­ï È.-"%©"GƔ䤫'FŸ=hvOÏ>ïÔú?³>Ùœu‡Rn<„û¿­Þ<úuò—~EjºTº ΋>†¯i+MzNæuÑ$@àWµ+ûYÉæÞÛµa.!+°y=_*uNÅ]Š¥óˆúió7üäG›¼Ù"ó¶Ñm/Þ^´–yÒÒ¾—2à(=nš8¢<Ÿ|ä›]м ó·þqOÈß›¾·¦òçØý)mô.Ü …Ü+@ÄŸ÷jÑüyR˜¤Ⱥì_œ—ñèÿ˜ÚTš—KzVz´le‚EoBê”&Ÿî©@Ê¥ŒQÙÐɼv,çË~nÐ<×mõíeeÍlßñ¯Ü|ÆÞ(”HtYôóÄjA<ÀÐÀÿ8tÁ©yùè ¶/äUñFàßðŽÙM,Î×’ý~hß?þq~kÿÎMÌžZÐtÖò¿åáukÕò$üX×7%cõ(G$‚5»µh™DFí]Ù9µ2¨ºË z’¼“¢ùGM+HŽ®h×wŽ­q-7g#·ò¯@3Y“!‘²úggö~=.>|ORÈòs±W›ùûó]Ñõ[o-ùJMs_’/.Г"A-ÅXÙO2vÝ…6Ù‹S/ňr4iö¦LsðGŽugÈwTÏòóó#Jóí‹úkõ-vÖ«¥HÕ’2 9¥@,•ïMŽÇÞ9q'#²ûZ¸ÿ6Cœ1?*ô/ÌYÏÔu¸W¾¥j$«QÍ|7v=pâÌaîaÚV,úd?‹õ÷±+ +þrƒËö åÍϲG§ Bba‰EQ剥Œ°XÍe\^F^ÉêA bG¿ö*ùcò"Ùu'óæ¥'™uÉŸÖ™%y$…äþi¤˜™&;~Õˆ9NMQ<¶w}Ÿì¶rÒ4Ç×<Ó%äʶд”’àU#—öX”5 ™àƪ¶&ƒÁdÇž33#$#Ç;;èîø>ò.³®ëþY³Õ<ŧ7R˜P«Ë(Sº‡ê“·}ó $@4Ó³säË„K$xdñLµísNòÞw­ê²zV6q™$?´Ç¢¢ƒÕ˜ªTÕg?¦,¢ZEcy3|@…û0ÎOÃÙ$Ûj Ëôú‰b˜”\ÓììzÜÓ‘ëÜzîýŒ?HÕ­5½>FÉ«£u?i}¤opsµÓçŽX EðÒììš<ÒÅn>ÑÐz8€À©ÜB=Ž\àƒ[°mBo#–Þ[Ó$ºÕõGt†v@»òâ[®Ã¢íÒ¤íšl±QX£r“Ýèòäí™êóbÂ1å~uçÔùС¼¿y¤y)íõÝAN±zâk˜!VC¶ÊÞ˜ É?†CK“’^©nk£“ÛmOlÊ3Ób>1Ã"˜³Ëo×¾ÌÖMcL‡O]VK¨×Np¬·¾aOlÛD8Éô÷¼D;7Q<Ç9ðõF++¨t!‘€*ÀÔw–ƒn¢A£Ív(v*—ëzgé.çMõÞÛ×^>¬}Fõ¡ÁèøÊu8|XÝ[°ì­å5ÍÂ'ÂyÇ>ãа}fÒkd‡òûËv…MÂ,·×²­%E\±ë¸Üöû#4ÚŒf iñ|ÏãñÑî{3S†]©«ŸÒH„ä{«î~¢Î´6=#LµÓbbél9·V=I§j“Ó7Z|#GGƒí-tµY瘊37HìµÂHõï5èþ_¾·0{ªU-#!¥cÚ£öG¹ÌMV»¹ß»«¼ìgµ:é5²?Oí÷9ù5ªYÏç½NòòEµ¼Ô ˜ZÛRˆí$É3Op£Ç|áõy É•s6û.£HpéaŒ\„îú 0Ý3±T§ÌÚÌ>^Ðu fb´…Þ0jZR5ÿdÄ 1[pb3˜{Ðÿç|¥6›ä0yÎé—ÌZ‚[Û»T™-´Ôeæ ìešU>ë™\_Zâ‡b®Å^Sª~s~Lk>pÕ¿'¼É¨ÙɪEéÛ]Øê‘ÆÚ}Ü’ sn²IÊ&u¨VG¡å°©Šiâ™ßó„RÝËæOÉ]¼¿ª©2¦‹u,ŸUåÜ[Ý%eн•ÊŸ´«€„$(‹ÔüËù¯ùK|š?æÏ–îÆ8u ¢Z þêâ*ÛÍAÙX•Kèësö\%¼ ±:½óÏ’üÙåmZÚßV†¸²¸F‚å„#4D…ÈäAþZŒ¬@‚룥ˋ$IP¿óŽz¨¹òÎ¥¤1¬¶b`<"¹ŒqðQ¾v‰’ñ˜÷½§Ú U’2ïsÙstèб_Ì8Úù'Ëw:¬Œ óƒë-Çoå_´ÞÃÆ™‰¬ÔŒ02ëÑÍÐi|‚=:ûžuùåû7Ë÷ZÝ╟Y‘^>_hÁ Œk¿ÄÌÇÜPç–V]ïjf˜ˆþ©eN­ØªomæzÓGŸËðÞ¸Ñn+êÙ°GŒÔ†$r©¨¯ÂF#TÚ3ÌG†öFÞyßY¾òµ·”&XF•hé$L‘•—àä@f B jŸ‡®#TÎZ™t o"ã³ï1yïMÕ¿/ôo(YÛO Þœð=įÃÒGŠÜhÅ·g®ã')ا;.¨K`á€äb¯¼¾Oü¬ÿ5-v3jDq|¿×7=›õ|?Sßö'!ýQúƒ›—¡cº?™SòÛó¿Ê}¹%4Èn"Ò€j°8kK¢8îH‚ZÓ¿LÔkáS¾÷IÚP©ßx~¤Å,SÄ“Bë$2(xäBYXT2‘±t9‚ësùñùž¿”–𝛢U—V,´h$G¾¹ªÆXmU@FÜ)¤Å–?”²yð¿æoæÄÚΣ­9»·¶žFý걨šr´$7û®5¢…§cAËö·lÊ8ñí\Ïê{Æì8Î&]ïý%ïún•¥èöËg¤ÙAch´ ´I ’€ å²d”ÍÈ’|Þ·(ÀT@Élxüäg,µo,Éç->Ýc×trs4kÅç´,ƒ‘ÔÆHpOE 3 ìt¡“Ã'Ó/°¼ß´:ÏŠª?hýŒÊš«k: ìÊã§9îdŒñb~tåôç©éòqÀQ¦ÉÇS¬¹½Ø«±Wb©f»®Yù~Áïï "¼b‰~ÔŽEBâr¼ÙD–¬Ù†8ÙTü¿üŸüåüú y§D¾_òDŒUµ[²ñ[È Â%Õ¸;ðN¢„®iòê§? èóë'? ûò³þq+ò«òÙa¾¼²ió"Qާ«F’EŽöö‡”I¾ê[›ƒÑóÃ%ï€t¡Ø«Ëÿ5?ÿ-¿(`dó&¥õp¯(43ßIQPY*5?Í+(=ªvÅ 3O+y“Dóß•´ß3hÎ.´=jÕ.!æ¬r­9pMQ×±b‡Ï¿™Ÿó„ß—¾n»›Zò]ÜžMÖdc)†Ú!>šÒ}ª­¿$hªßN{&,„ˆxΩù%ÿ9_ùkÈèÓÇæýÀ¶/€è=ÁÅÉŠ¹L°DôvúnÞÕbØL‘Ý-ÿk±üúÔ´=DhŸ™žYºÐµ!gu†X] hKÚÜ Ù˜ûf<ôÅèô~Öƒ¶XלWí{6©Xêö0jzeÂ]X\¨’ ã5WSáôìGlà ƒEëñeŽH‰DØ(¬ ŽÅ]Š»`ÿ›ï˜ü½å »ï.Y©HhîÎB 諹*{þÏÚ;—`ˆ2ÝÔöÖ§.Xã}çù£¿ñÉãš”®´½IüËü¨¾—SÕ­£T×ô©©$’HÀã  JþÆäŠ2šÓ2e;&3y}6†PÇ N–FR\~ñû>!íÚ”ôI5H¼ùq¢ /ÍwÖÊ.á2ôd~óìÑK‘ð³R>g1%3\7³Öi´XÌÆs’ù~ß6[•»'b®ÅPº–£e¤X\êz”ËociMq3ôTARvÜŸ78@³A¯.X㉔ðŸ>y÷Ëúúèþ{ò^´¹å© ²è·.öí5´¤ BÄô ÔÙý2~wøFfbÄEÆCbò¥ÚX²ðgÃ?V?á;Xë·ß]=̾_ËŸ"þf]Ù~az—-§ \ÚÅ*¬7>T 0âXà°Ýr¯Pô»9vV›[!¨ßÔ‹Ø×Ü^ F€4lÃ1Þƒ“Â/`Öÿç#ÿ3l?-|¡#'•4ù ú¦¦£”KL{¶èP}8¿7Z6Û->g›æÞÐö¿æ'ÁèÚ{ÿSôOÊ~UÑ<‘å½7Êž\¶º6• ÛÚÄ)Rvw NìK;~Ós%æSœUØ«±Wb®Å]Š»v*ìUØ«±Wb©~¹¢i^eÑït rÖ;í#Q…í¯-eI"PƒÜàÁÜoŠ¿33?/5ÏùÇÌ 4»ŸRïÈzË4ÚMñó€5(Ä ¡¨Yí â›Ï×ßé<ÿ[Î{Mìü{C§l±úOûÓä~ÃñNaš+ˆ’xI Š9ÕYH¨ Œìc EŽO…åÅ,r1¢6!}ÝÓ –Û3ËZ¦´|ݧµÃÝJïivðúÉ21f*…¶Ôwö4¦sàÁ9øÑ»;»}S8ÏÚ}?ärˆˆ%.¶æ·¡ûEÛ¼­äûÝn{lÉn]ì4âH.$bõ=S^½[åƒE –P ö€åûAí.-¥=K<¨O'u ùùr÷¨GpƱD¡"@@ ªt:0,œÌÉ”“̯ÂÅØ«±V¨+ZoÒ½éŠÛóœtŸ.Jv3ß‘U´Šœ¨z'e¶`êûCŽç¹è»ÙN¿xŽ8òøwýÞhŸ'~\þ{þsúsy[HmË3Ÿ‡X»-gjPþÒÎàÉ(íXûç=¨íl¹6‘åúßMìÏc4Zj3,»åËý//¾™ü¯ÿœ#ò•¤‹VüÀºo8k`‰>ªêÐi‘¿SX¹š‡¼Å»¦k ·« ‚¯üäßüã*yîÎ/;þ\@–zÑ¡Eú°&£ol D‰ÇˆI¢‘6Õè¥Tóؾ?›ó‡Î/a— ÓÍ¿›ÒSku<‘|uO†ž„‚‹%kêré¿ÃiÌ¥C{u´8pñdÉ*„Eû¿7/ž?5|¦âó[EÕ4ÍŒªé ^¿¼€SîÕ\ËÔv^LbÈÛÉÕè»K³µ§ƒê]ÆÁ>ëçðÝ6ÓÌŸó’>sÒ|ƒåxÆ™¥Ð]êÜ:ŸJ8è&À#ŸÔŽ5݉ޟ³‡S¾Ñè†'rý0ò•´$ùgKòž¡¤iékj„ÕˆA»¹Ú¬ìK9îÄœ±ÌN±Wb¯3üøüÕ´ü üºÔ|Î̬Ê>¥ Û>þµüÊ}2WºÆ‘ý–HÅ ??¼¡ù<þyòåך<Ï}q˜5¹žòÖì䉳K2¶ïê³ê (k¾nô}”2bâ‘¢y:wlœYxbŸãÉ›ù7ó·ó§þqÞâ 'Í7›?/•„q,Ò»úHNÂÚì‚ñÚ)A^ÊÚÍ~§E“ õ »Ý–“]‹8ôûº¾¹ò/çoä×瞘Ú=µÝ­ÅÍÚñºò¶¹IrÕܯ¡7(æÆ"àw¦b9”Ä<Ëÿ8Kù!æ æ½´ƒSòÿ6äöÚMâ =h—‘\qÈ@ðÅmóåÈ¿+?ç!<ÝùujÒ-}T±YO)=±ÞÚ—j ‘Кo›~ÆÉYHï›·qñaî/fÎ¥ãÐÚ†¡g¥XÜjZ„Ë•ª4³ÌýTŸ`:äg1IäãÆg!¹/mWQüìó›êº‚¼OÒÛ„PO‚µT~Ü”å!Õû9Äö†¸å•ôèõ¢1Ñbá\¿gG¹ÇpÆÄ¡"B"(UTP@j16¿;v*ìUØ«±Wb®Å_:ùÿ&š¿ã6§ÿQË›žÍú¾©ïû”ª?Cгrô)'štüÅ¥=BÝ!õ-e?³ ±§Q‡Äuqõ8´ßÃ2´WãB¿œ>÷_^Kþl¾çÊÿ•Á‡—f,j Ü…}‡§ýuÏbÐ}‡ìïîþ,Û3\ô£¬izJzšÜvâ• íñ·úª*Çè åŒy–¼™cf˜÷ü¬¯,zÂ?Rn§­èžÞ•åÿ ˜ÿžÇn7ò†;êÊ­î »‚;›iX%PÑȦ¡î3*2Xs# E† ù£† .ù£3Y[LëqH êq* ]ÅB‘_|ÀíšÖö”MýBüºó_–<ëä½Ì>Oh†qmÚÛBE§¦¡ ³"Ð#DG´Ú›mš§HÊ1Wžþfþvþ\þRZ ¼á«,z„ˆ^×GµX¿¸§TŽ öy §ùX¤É>gÿœ™üîü踟Dü¢ÒdòÇ— æÕU»âz™/X„ÓâáõflÄÕk±`3^]\í'geÎj¿>Ÿ4¯Ëÿó:?Õo.üë©Í¬yŠý%çq¸Š æSYƒ9ç+†<¹I@{®s:Ÿh§) PüÏêünõš_fqÆ'Ä7":r¯ñ³.ÿœ:üÃÔ<‘æícòÎúlgšã@g?Ý"óš'~3Æñt Ýó«Áš9`'Eã5Zyb™„¹‡ÛÙsŽìUòoüæ'ç奷•¯¿.ZÎÏÌÞz¹”1qYBHâŸXiWtœðF¦»ü̲ˆy÷ä×—u_-yÊÇYVŠòi%ºú³ý«t˜Õc#± äGbNjµ–Ϫv–xtÂ3æl×u³ü¥Ü»BÞjzvŸ%¬7×Q[Ë{(·´I]PÍ1„@z’L ד4 @‘ˆÐó/7üâóµÞ‘å›DòÕúC.§ú6}V'V[@œ„ÚŸ…Á=À Ðåø1ÙÝÑv÷hKáʸ¥ÃÅÝßñý¬>ûIÔÿ+|ßåC¤yŽç[·óÂ[jZ}Üž§ÖÙ#2ª‚A?ÂNàŽ¬+–‰ ‘6*fLÐçÅÁÌd4AëË·û^¥åŸË/ùK̦½¢™ šª=\‹XwäÅ#ž•¯ÂÐf<ò™ Ðé;'Ÿ,²BÇNƒñötfS³v*ìU/°×t}RòûOÓïb¹½Ó$ßÁ†x\ŠÑ‡áóu$bCN=N9ÊQŒ1çäñ:ùãÏ7÷÷³y^ý4û =It='LÉ=Ʊz¥}b}U D ýªñ¥;œÊÇŽ oÝ~ç•íÑÔÎDâ—àŒjÌåןEo)iÞBü׊ûOó•ÓIó~–Æ=PÙFöËê(XFÃ--6¼J91päÕ[}ßq{…¡é¾[ÒmtM" …šp‰:“½Y˜÷f$³ç1¥##eéôÚxa€„òÍïèþÒ>LÄ€À« ©Øƒ¸ çNù$ 'Xò+Áy»äû—Ò5»WYà0HÐ…‘ CDèA‡jmòÍ&·±ã?V=wOØú`ûq“ cÔÜãüïâÿç}þ÷½þQÎijzÐyKóÂÒRbãyš¿|«Ð5Ü?x?âØw?ÊÆ­œÞLR© /ªiuXµÅ!(ž¡ö†‡¯h¾fÒ­µÏ/_Á©é‹ÎÚöÖE–)CFRwfAØïnLqWç?ç/œ%ÿœŠüíML˜Éùyå3$K~îeGêåH¨&wQD°ªÔûY™¡ÒøÙéÕÄ×êÆ F]O/{Ô"Š8"HaA1¨HãPª¨ € ìÀ§ƒ$“e©à†æ·¹f‚PVH¤Pèêv!•ª8¢¢D,óWäG–õiÿ˲¶…©ƒÍ5kbàÔN §û.ju=Ž{ÇÒ~Çu¥íÌÚ~¡ö£¼µùÙÿ9%ù3ÇMÖ >uòÄ_ mv%¼dAþû»÷éØ8`:š<ýŸ—1c¼=Ÿ´°åJqÙ#Òu4~m~wÞ~ljšèVB%V€óôù%ˆ±HÕäD26;„cÿ=Žbêtà ±ÍÃÕiFAc›Ú¿-¿1î¿ç",¼Áÿ8ûç뀿˜ÐÚ´¾ZÔî¾½—O"hÒfëë!JHÀUâ䯥X¶”Š4]¢bXÏüãçf¶Šëò³Ìêö^dÑ&¸ŽÒÞàp¤n}krüâpÛ/O²síýŒ¼Xò<ýÿµí½œí(x2;Ž^ïØ÷œæž¥Ø«Ïÿ;õÑ¿•žc˜4°Gl£jŸ¬Î7˜œÙvD8µ0wòê»k'–gʾfŸ)ykÎðhº-¾“ga-æ¤Ï!*U/#ž!iÉŽÔÛˆÏPëáU»Ã`ÖŒpª²ôß-þQÎFþfm3@“˺D»}{QMŒ)èÃ×á‡ùQFFW“Y9y5d×Î]kÜ÷_"ÿÎyfÎDÔ2¼Ás¯^’[ >¶–¤íU’wå4ƒÝ}#˜¤Û„fKÖ<ãÿ8ãù?/åæ¹¡hþMÓ,®¾¡tl5m£úü7) h]n䬯Ž£ICѶ'[àOÊë§—C¸¶v$[Ü7¦쬊ƒý•Nmô¸Ü]ïgJàGqf7¶VÚ…¬¶W‘‰m¦^2!î?ŽfÊ"B‹8 <–šžtÿœoó= }_ò÷R˜6¡¥»Q\Ó8Ø‚"GíÅÀôtz9Æ|«JqŸ'ÜúÇç—oÿ%uÿÍ!ÝG©Ç§é÷A Š=½ê¯Šê*òR®ÊY{®êH æ;‡O‹(ÿ-m¿2¾³ù£ùy.½¨êWS:Á3’²Iqi.¡;Š$bŠt"€s=³Ú³Ç/wŸÔõ½…ØøòÃÅɸ½‡ë}kikco”ÛZB¡!‚XãEª€ùg')&ËÙF"€ ­‘dðùÈ?)êo¦~kyYžÛ_òü°5Ôðm"¤R‚àS¼RlOòö\é}Ÿ×pË—#ËÞò¾Òh8¢3G˜Øû»þ®¼ùéäÏ5~TX~gëz®‹eÃÐÖEÄʉk¨Âš ,I?J>&FSMó¯xŠ|Íù©ÿ9_çÌÝBo!þDZÜÚi²ƒטJ˜¯fŒü,ÑÚÚ/ø±¨v§±Œæ",¹ZMLóဳøæ“~]þKéRtÖu·¿š õ ÂÐ[¹Ü˜•÷-_÷coà5Ùu[O¡öO³øôÕ)ú§öwëûž£˜ïBìUNyൂK›™xU¤–Y*"(«31Ø:œ@D¤",ìƼéggùÝan|,6zÑMªÝ$ÐVˆ½ `*A`¼ªžw̬gÂ>®¯-ÚãÚq‰}FÇNŒ7Aó•t+Ý~VyÛËW[Kå‰íì¼·HáEÊ»1"E_³Çáe§„Ó-”$eų«Ój°ãÂt¹ñž..œÉþw¿ï÷=sÊ“ÞOòv¢º½¹¾ÔcR¶ÓꤦÝH¡ª$j *A#¶cdÏ) z]a`ÓÏŽ7#Ó‹§»`Ïò—rìUØ«“Ît>r‡ÉSE,ZÍ›_[NáD3*±45$° Ìvè2~áâp޾P0l‹Åç~}ü¹Ö4=Y¿0ÿ,Ù­õ´f—RÒãþîí !DØÒ¯íuZ7[ñepË“¤í.ÊÉŠ˜Óm/âã¨ëÓuo9¬4?8ùGS™ü½,Ð\ÛϪ‘I:'2¤ƒP@øj¦£cB0ÿvH"Áaêí(Ã6pO ƒæôï(yb)èii3]Ýò^_È Ks<²4²;nNìíASLÇÉ>#nÿC£|b7g©ï<ØŸæßælEÒþ£§2Ëæ‹ô"Î-›êè~]רý€~Ó{–`ÃÆ|wnvÀÒÆ?\¹yyþ§®Î(Î=Ïäk3ù™ç¸L¿˜:Ò3ÚÃsV—M¶¸ÝËrÜ\LïU_ƒj¸;00œÌ‰$Ù/¨p°v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]м£óçò;Büìò©Ó®xYùžÀ<º±Â­ ¤o”ÜÃ%uí³ Æ)ùõ¤Þë¾I×®¿.¼ûnúv³¦Éõxý~ªzªÜ20!¢phTŠS:ËíXæ}Çô~§Í=°öZïS€yÎ#ýÐÿ}óïfùÑ>^Ǽßå×óš±[È"¿¶ZÕÏÙä “ØÁ×é§¥ÏÇ”)4ªà׉fPTPôVÍnÄðÄô²ú?ürDe˦1?Mýáú³ jšn·¡išÎŒÈúF¡kou`ÑÐ!·š5xø…Ø$tÎmõ4Çv*Â?8üÆ<¥ùUç0úž”ÖzMïÕ^´¥Ì±m÷÷•Ôb¡ù³ù[ièy~[¦ÕòŸBÄ6u]‰Ž±Þ_öÿSǬÁó6~êg¸xgb¬UÒu?ÌÏ=h–žZeÔn®$œ¯! aÊGb7 ažJ~±œÏmjD¤ :s}oØ.É–,RÔJÿy´Gëñ<¼½ïÓï$y?Gò”ôŸ'húz^‘n¶ñVœ¤oµ$¯OÛ‘Ë;û“š7¿x§üå÷çü«ËæòÞqéù»Ík%¥±CûËkq¹¸ÛpH>”g¯&ä>Æ)àß”žIMò¼Z޵©q¹Ô ûIQû¸Ø¿ùE³°ìÝ/ƒ~g›Äö®³ÆË·Ó‡ëgÙ°uŽÅ]Š»v*ìUãZö»¨~Q~zh›²éÍ©h‘|2F‡Û´{£äAÄnd–Äü9~ØÁ!“¡zþÃÏbàêmyþr#ò{ó8F‡æ‹[}FP£ô^¤âÂð;~ÀŽr¢B;úLãß4îê“/7þIþSùû”žhòžŸ{s.í}_U»jøÜÚ˜å?Kâ¶ñ?1ÿÎ~VjNóy{WÕ´)¼a2C{lžYQeûæÅxž}ÿ8Aù©¡>Iü·|\ýwLå¿Ù¤ r½Œv¶ïÊa,€q,GÒT©&¾Ív£(œ¬ uz¬Ã$¬ }1ÿ9Aÿ8Ûwçæåªµ·æž©-í•¿îßRXRX™hEÊþpû@WQwÇÇÄ‚ ó¿ÉßÍÛ=Ùþ„Ö©kç+¥Ô,8 µái£]¨Õþñ;ÆÝ8nÕì³§—~ƒöy>‡Øý®51á–ÓoŸëz¶iãÈÿç$]—ò¾éTÐ=Ýš¸ñ§*}àfë°ø@÷Eíÿ>ðúGþq¿Ê~TÒ(ü™¬i:5¦­}¤ÚO}¨Ám \ÜM,`ÈÒ̫͉$ƒÉ½³º|콃;y?çç7å·’ü©æ ?Vó-‚kòi÷ÐZi1L'»{—·u~nœœÉÀQÜâ™>M×µ»Ky4_.éRjz­Ô¦UXã’f WhâC½rèk†¡æ]Ž“4Àá„x‰zV›ù9ù׿Hþ¹©jèJÛ¤\´RR›|jôÿfkíš]OµÁØ™{¿Ücì}f]äx>?©!Ò$ÖlµýSò÷Îanîm¹¡g> n 59 +)ŒwþfëF¢¨ÙÄÇÇ’×rØêzßå¥&œ^÷Ⱦd·—Kóî};›;„dx˜ïÆTVf‚aº·· ÑÕi¼3c“«ÒxfÇ&Oä5ß~JëÚ^ºï{ùg愎…­"‚áT£-=;¨7hÜw§ÇÌö¿eøñâÖ>ß/Ôì{µ¿/.ýì=ÿ­õ¥Ý­ý¬7¶S%ÅÂ,°OIÅU•†ÄœD¢bhìCßÂb@ll‹% ËKmBÒ{Ø–{;˜Þˆ\UdŽE*ÊÃÀƒL”dbAÃÀHwñf¥ùycå¿Í(<‰æ›Ë‹,\\l.Q€Èã UU,ʱHüz¯€ÏBÒk|l"cŸ_{çßɰǬ²’ NÇÈòýEõ/—¼±¡yVÁtÝÊ;;aBü^Fœ¤sVcîÇ1§3#eô}.ðãÛ"䡯u?LˆO¨ÝÃg#¼!ßû;ÑŸó‹ÚŸšõxÿ=4ãiæ¸]ùkN¸ZzŒ c½tíR–ñÓü¾k´Œ@+Ôêgšfs6K팓ŽìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUá¿ó‘¿ó:Gç>€×ÚrEgù¦ÄF“©n_U¹ ¡ßƒuFÜlX ¾Ðuí_CÕî<ç‹ytÿ0éò›R.‡=EÛÓ’½ÿ‘ú0¦ý é;3´øª;ô/•û[ì—‡z8ôó”GO1åÞ:{¹Mó|ùÂSæ].]gB½Ó``“NƒÓ$ÐrF>­ck0œ¸¥Ì»nÂ×ÇI«ÇšBÄNþâû.Þ{–uMVÖM>ÆÞm!y[&­gp¡#/û¾Ü‘¹ø*ÀýsGòG† ×<½áô<ݽ§ÓdrJ9ö™Å8ýCúùì|¹#µß;ê–:ËhvÚÇ3@‚ñ˸EP¬¦”ëö©Ó¥kÒÝOiN<8‘@ÿ[ƒÙÊéóiF§,fe(Èð zþ‹ç±ªçÑÕÔðRêdeä?h TS¶ù¿óy@îhÕ¥Þ`ѡ״›6SÄÈ+‡ö$]Õ¾þ¾ÙF«N3c1.ñ»NZ-DsG§1Þ:ÇW¬Î þ{.Î?$¿0.>ªRf_,^Ü0’HÜšÅÜöv< =É+]Ðg“¡#sÐ:mN=F8äÆn2päо@ÿœçüϵ´òÝå“/­®k“[ÞjÐFjb³‚NpFà~Ô³*²¯q„MJbÊF€Ýáš4}ËMÛ•¼J²ÐÈ~'#æÄçu¥ÃáãŒ{ƒó¿kë¿5©É—ùÇow!öRc—ºä›Íì~^Ñæ¾jƒû»XÏíJÃáúÚ>Ã1uº‘‡—^ž÷sØ“-v¦8ÿ‡œtG?Ÿ!æ_DÿÎ~PÉ¡ù~ëókÌQ¯ù™Z=#ÕZi~M6û†¸q_õHÙŽq‘&Ï7èB0ˆŒE(>©Õµ]?CÒïu­Zá-t½> n¯.d4H¡… »±ð À—æõ¶¯¨~þqꟙzÌN¾[ÒäHô›9hV8¢'êS¡#y¥§íŸͯdéÜòüãÏä×—ü«¥Z'é:¼íkn÷Ž©co¨Oq+Fä/r²S‘5â”QØfC½´Îãþqãò>éUdòŽ¡MG¥h°Ÿ¤ÅÄŸ§´©¿ç? ™Ï’-AbI¥Åêüœôb¶?óˆ?óŽÄ“þ ëÿkm`ØÞ+mРÎ:ÿÔ›ÿsmcþÊñ[GXÿÎ*ÿÎ?éßï?’mŸ¯ûÓu}u×þb'|VÙE‡ä·å™Ceä=7‘!ÒlÞAQCGxÙ©NÕÅmšZÚZXÀ–¶0Gmk¤pB‹j<¨b…lUñüæGå=Ÿ“®¬=<‘"húÀ¾Š-f™c\ÉVŽî4;b ΣíƒÈ¶MyqÆq1°[°æ–9 DÑ ³ÉúðóG•´0„ôÛQµ†y#¢HËûÅì g›j°øY%âúž“?‹Š3þp@þcyOüoäÍWËhâ+›¨Õ­do²·¸–.G²–P­ìNY Ôøc>ƒîkí /†Pêy{Þiùeÿ9=ùƒùåˆ.|×äYµ”ÒZDÓfk©,dŽs!Œ¸·¸IT3´øvÞƒ= §Aq!óLÚ<˜åR‰;½ÿœ¨ÿœ‘óµcò'’ Ñ¬å¨Šñí%¸q^”¹¼híÍ=ãʳv†TÃnÌÏ“é?`ù–7äÏùÉÌe#óÏ“YØMýõ„wOéŸõ­,DVÆŸëf¯7´Xcôƒ/³ñòw=˜Í/¨ˆý§ññLü¹ÿ8ÍäM$¤ÚÜ×:åÂД•þ­lHéHá<þƒ!©ÏíiíˆùŸÇÁÝiý›Á æLÏÈ}Ÿ­ëZ>…¢ù~ÔYhz}¾k±1ZÄ‘)#»p§Üïš\¹§Ü‰'ÍÞaÁ b G’a•¶¾Ióã$¿óº¡†€"@%e<¹‘¦F |)P>ŒôŸeÁð¡þwÞ^´ ëå^_îBi«éÑjÚmÎ0.#eþËuVú u¹!ÅåÆ'W¤Î)ùsË¿œÿ•mü¡óÌ{}úý"åX-݃j "³[1œd™… žd5AÎuåå±aš…—æü⚓˾gWÖ.5]´ýB%"9 ´O¥2ƒY f¡ìMC棴û*:ci÷÷ûÝ×döÄ´ÆŽðîîó 4[N×tÛm_I¸K­:ñ¶óÆ~SóÜv îÇ8\¸¥ ÈQ¡bË‘‰°Q¹Ç“~~þ_Ÿ8ùIµM>.Zþ„æÛˆ«ÍoJϦäÐsOqAö³sغï/ úe·Ç¡t}» ññqGê†ÿ¡ ù9ç¯ñ¯•"rs×4¾6º~Ô”º˜ÿ®£òƒgOŸ ¼œîÁíÌáõGcúÇï·¡åíó×’|½iùÙ«k^póŒóOamqõM3JŽV‰ ‹ˆq^& q+öH«TœÍÉ/+³ô±í9Ï6bH£ç£þhù×Î:6Ös%Ÿ˜´Óëhró‘  ô«P@~*ìhÓ„ù;ÎØìèê1€ N?Oêy{é>~üںѴ_1hòè>_Y¾»æIau’Y(¡=5>˜©e x1ø‡¶dqGnú<ùÁ©ídÆqÝο³ì÷ìúÊ×ê–ñÆò5ÅÂÇMw" –vxó“€QS×aLÂ%í±Ã„Ì÷÷¢03v*ìUثȿ:5‹ß-]ùÌ.³$Zìz6Þ^¤‹PŽVJÄ›ø-O·53'O+mÞó]¿žXe$'Sh;áøòÝù9©^yªÃZ×5Ýdꎡ9ŠûB#Œr'$XÄN*9/q±ïVàÎ8H3ì²ÏÎsâ2;Ǥ~›)ü¿ò…Ç’4›­ß}sNúåÄúdekki[’ÄÌIäkñA¹9^\œFÝfhNšV,˜ùå€\xÌÍ]£ÚÒãã—Àw–?ÿ8ýù­þwy—þV÷æ´ þÕ´}-ÁHõ‰¾T;‹XÈßýøÝÏÇ]¤ "(>Y®ÖÏQÎgsöyß ªŠ¨Šª`7 ¼UØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±WƒÿÎGÎ8éœÚAÕôŸù…§ÄFŸ¨Æ;È×qktGìÿ¾äê‡üšŒR á½^Ö<½«Oä>[M¦ù‚ÂO«v¥0è’W¹(ãf5îz>ÍíK¨d;ô?­òßjý0½F˜zyʧœ|»ÇN›r›æýód.£ ÅÅ…Ôrú7RÅ"A/ò;) Ûx¯,I‰4iÉÑe†<ЖAÅ Hï¸`ú •‡—<­}/™tÿFQ+ ƒ/ Ó+V/Lô=;WâÍ>—p`‘Ëß>êüy½×kê³v‡hcL¼C‡ÓV8/êâý=…(òµ¦®š—˜õX®G 9·ž[÷ž*ç'*„áËð8º,yã–`ðïFù{üÇ´4°dÒ`”[D~¹r¨×ñrïáåæ'ºN©ªj•âÉkÑ«é÷Ñ¿/X¤ƒQì)Ó7x3Îs6CÞð£Ùú|!S>5‘8\?óAù¿Éðy’< Õ †~Îá«ÐöÊuýž3‹H9¾Í{M>ÏŸ ½X¤wÞcõuzwåŸüæO?.m ò¯æ¶>¿ij¾®¯5l—ýÝÀòVþfcœžlÆjBŸfÐëðjádžBCî÷ŽcâË<íÿ9ïcubö•þW¼“Y¸!¼ÖDJ!b>ÒÚÚÉ1ø"ôÊãMnVIÆ2‘§`ùëAÐu½O[ºó¿îd¾ó-ôpÍpÜäõ¬’•¦Ê£e@/fvaãŸ>ƒ¹òŸk=­Ž¢'O§>â—󼇗»œÏ7ž;H.¼‘sùûù½c嘹ÿƒôrnu‹”¯iRŒ6 3Ò(ý¾.Ç8þÓÕø¹(}1äû—²=‹ù-7‡ï2o/.èü:ù—éí­­µ¬Vq$vѤ6ðF¡R8ãP¨Š£`5¯Pøûþs_óRîUÓ#ü©!—WÖ^ ybaÈBÎ>«hOc#UÁ¥Sö\ä¡"æQ)ˆƒ#È$^Lò½§“¼¹g¡ZÑšåu0ß\>ò>ûîvƒ;m.œb€ˆx-f¤æÈf?̇åßœÞ\Öu+m̺òóËw-tÖJ 4‘³FäªÛ‰‰j£zš®ÔÁ)Î"Ì/ǹÜöF¢2„Í Š¿ŸëL|Ÿù»å¯8jpè–Ñ\ÙêòDò.QsˆUãWV$*ÃáÓ¦[¦í,yeÂ,_edÃ#Dy%¾Mó¶­æ?4ù«X–íbòŽ­*È”/ø¥ÊœQ…ir­.ªY2NWè‹v¯G x±Æ¿y/Å2-~dhz÷–ÿÄ÷ßîOõÚÔ=ü±";¨÷mËâÓ 5Ã20k¡<|gÒ/«‹¨ìùãÉáQ«Ù”Øj6¥²^é—Q^Z=xOo"˧Z26̸LHX69ã” HQT‚æÞê?ZÖTš"HFÁ֠Њ©#l"@òD¢FÅW b®Å]Š¥:•ü·«ÔêšEã7WžÚ'zø†e¨?NS=<'õDƒ~=NH}2#âõŸÈÿËýR'ÖO¦\°n“Ìÿóšú‚úWeŽÝ@$2&‹ 5Ú•··å„öö›¼üгº“ü#æry_þr§U%µÌë‹E'qo¬j·Â((-¢ACóÊ%íÈHü¿[|}—Îy˜ŸêB[ÿÎ8êÚÝüWÿ˜^r»Ö½"¤YdeÚ«õ‹©¨4dÌLÞÒôG?Ôç`öXsžÝÀ~ŸØ÷>ÂÏJ±¶Ótø– 8’ hWì¤q¨UQò9‰ÌÈ™eêñ㈈ØNE›±Wb®Å]Š»v*øî[Òßn¿¯%‚{ÈUº×Ñ™m–›ôâ¹êžÏcáÇêýïŸÎ\ż¸ŸÔɯï­ôÛ9ï®›„!w?.€{“°ÎŽs\™ÌD^Éÿ8 _ ŽF¼`ð¹ ²BøçqÙš¯Ìà£õGð Çä'³µ‚cû¹óý?.cäú)cž$šC"‡ŽE «+ ‚êÂ÷€‚,qŸQQáúbÁ˜¯NìUتÙ$Ž(ÚYX$H ;± ªª*I'`Å€,¥ú?˜t?0,í¢jj jâ)ÞÚA"«‘ÈK±ÛÃ%(‘ͧ«[à•w<Ï?š^güºóf§avmu‹J›D€:ÀÖöœ ±S»·ÅÔÜ œxDâ:<×höÎmyDÔąǧ¿ñ¿“Ñ<³¡\ÜØhúלb³¿ó…¤.Q†%ýÚÎyqV_„6ä»u§SZ'-ÈÞ“LeO0È1æœØè6™¨_ê¶QA¨êl¯p‹G™PTþ;wߩș)ÊÇ¦Ç JQs=éo|ë£yF}[Vz¹ªYÙ¡­Ì´¨D·ó7@>‡3#A£´;C—þ½ˆ~HþIy“þrÌ«ù›ù˜¯oä i)a`9F5M¿¸€uXŠK/W5U5äɵnjDP|·´5ù59 æ}àÐ+{{{Kx­-"H-`EŠ"P‘Ç*ˆ«@€ ›€©Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«Å?ç ç¼½ùÙ¤ ¨Šižy°‰—KÖü2(« k  –ˆ±Ø‰ ªÔrVR àèu2~^ë÷AüÉ´“OÕlXF%œ†*t%Á*ñ°Ý%RE=ºoû;µkÑíÐþ·Î=¨ö;Žóé†ÿÅ×Î>~]zoÎl`MTîÜs£|¬‚ §Ìš ¿˜ôÇÓ§sä$†Uá"‚#¸¡ ŒÆÖiFhp—oد=q–"ö¢;Ábz¾Ÿæ ZâÏÊR³Ç¤ÙÃºŽ¦Ê±¤ê¿ËÇj QT÷ÜôÍ^|Yr„ý z¥Þõ½›¬Ñéa“]YÈŒxîÌo¿®ýOvÚÛÍw¶×R‡tó7“ôˆÌsP y¶õÚ½öÜõÚ×J2ýÜoà¹ýžÅ“üÞ^^sbúF¾Î›ì9o<Ñõk]oO‡R³åèL ÅJš WpFn´ùã–Qä^´»;&4°äçî^ô\°Ã:çeŒõGPË÷¶QbâcË(‰ ùl§oegi_ª[Å/µéF©_Ÿ20Çò6fÕeËõÈËÞIûÑ6‡b¬?óÌIÒ¾¡jÇôŽ£X£ »,ggaNæ¼Wû3UÚº¿ ç/¹ì}Œì_Íê”m^àÇÝ©Û8l’²ì{GQâN‡ ʼÑl÷¾YÖlâ–âÆî$¯Äð2¾g#n. Tâ|Ãÿœu¼†_'ßY.ÓÛ_»ÈŒìû@â#¸§·àFP{ÃØ3r芼‹ÌÿúÑ_•öÖÐî²¹Ìöß÷‘÷~—­öû©{ÿCô‹4®íñ'üç?ü§?•¿ëÝÿÔU®UŸè—¸¹_ï#ï{ѳÌZv*ìUØ«±Wb®Å]Š»XóC"I"£ÈxƬÀ>¸@%€ÆtßÌ#êúüžWÓu»{r>`Û':1Ž¥•%+é¹5Tbv̼š Ї¢D\<}£‚y<8È~> §0Ü×ÂVzΫ¦yËÌ1Xi’êšÅííÌijí'1på¿w³1©è)ž«ÙùüÇ$jq×{×3ΟOv*Ã?4|æ”/4Z(Ô£YÒæm½;¨Áà ì® Fö5í™Ý¬:|¢]:ûi膧 ^cÞòïÈO9O}¦\yY-µ òH#–¢Cj¯À¡zÂÿðGlí5Hr.³= g†T9{¿gê{.c=K±Wb®ÅRÏ0ëúo–4{sWwO´ fhãi[ã`Š 'v`<´O$i‚v  [‰Ú¼|3'O]CÍööc–xpƒPÈEžñcñòznƒå¿-yIžßH4ý59\ÝHò3T¤`4’<„•wí˜ò™‘Ýßé´˜t°"†<Ïëcšo‘-¼Ë¹¬ÙG±˜du»½iLüHä¶ò6èŽ_ ëÞ@™É8ÐåN.ÍÒfœ}~'3Ïäz2ß.èvÞZÑ,´+IfžÚÆ1rÜÈd•€ßv?=€Ø †Ù\åÄmÙitã8ÀD{Òo>þ`èž@ÒÍî¢ÂkùA:r0ÎÞ=ø ý§#osA’ňÌìâöŸjcÒCŠ[žƒ©ýži'äwä™?<õøÿ5?6ã’%TI¥iD´_¤MQ#ZòKaݾԎå³iŠ—ëµÙ5 æwû¼ƒï[;;M>Ò #µ±µ!¶¶…8¢Š5 ˆˆ   2n¾*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]мËó£ò;ÊZèír?ªk–ªß¡õØP‹7mèEG©·£‹Q‚_žúþçÈŸ1Ÿ&þ`Ú3iVÓõ¹I°Ö‚Ki“ù£4eðß³ûLâôËxýÏí/²0Ö^\5¿d½ýÇÏçÞ%V×V÷°Gui*Ío(åˆj¤gS ‰ Ãã¹ðO Ì& d9‚²úÊ FÎkÆÞá rb‡‰ð+¾ ¸ÄâbyzMTôùc’TM‹ÃõýQ´Òì|©å«fK ¶)y|H4[Ô¦ÿ*ÆŸä Õj´óŒ#‡Øó?¯ñäö]Ú˜2ê2kusp}Ü>îƒüãÊÒûKí}n%ò×’â‰l´OÝÜ\N)¥äyזÓ†¥>ü£\¶q`¡Ìž¥Øjtš3êû@ÈÏQ¼cáŽÕòsùKåŸ5Ûë€ØÜC[[ëvÀ!‘Ê7¿¶Õïß6=pËé;Ls3Û¾ÏOGûÈz°Èúe×qbÿ:2LÏy·bªWÚ[Ëupâ8!V’G=TTœŒæ" <ƒf 2Ë1 ”æ›ÿÎ+þ[Mù»ù£?æ6¿n[Ê^U–9-¢qXæ¿_ŠÖ ö"1ûé)û\A|â5zƒ›!‘üè>ÆìÈètÑÅcê=ò<Ïêò§èžc;7À¿ó•^}»üÜüÐÓ¿&¼±qË@Ð''W¸ŒÕPU"áÛ±ÑÖ0?߅dž_¦ÀrÌDuiÔêfg¢c¨êÞZü¹òõ½©èöæp¨d5"‚¡ENÀ³xça<˜ôð°äññdÔä5¼ŽéÆ™ªéºÍšjUÔW–R}‰ápêOpHèGpwv<‘˜¸› 1J¤(£2mnÅ]Š»B_éšn«ÕµK8/­ë_Fæ$™+ãÆ@FBxã!R³†I@ÜIÉyãÈv¾kò§øfÆDÒ¢†Hæ´Ä¢hëD1§Äò=:óW£qðK™¢×9xÏ«½„y÷ɾs¹ò‰祭êZÒÍwefŒ©ql€ÇUâ 0Jrø?hÓ¦øÍ.S† úŒO!Üì4:¼#<ˆô‰ ‰èR«ÝJÌï8ùPù{A»ÒãЧYµ+ë˜>ŠFñ¿¤ P„ $OA¾U<‡S–#„î[áŒipä㘗؇?§|Ùç>ù‹L×î4]/D…âõíÉ+'Õ…âÐgfïï‘õåË–bF"?£ûz0âÅ @HËôÿkZgæoæv™ä«5^Ae}¢Gpmd¸º./.¾"*8P…yPšŠqǯÏBfˆºß™NNÍÓK1Æ «Û{å…Ø¿±µ¾T1­Ô1Ì#o´¢DCî+%Äïy™Ç†Dw ¼Ëæ?ʺ%Þ¹©µ-­R¡ø¥ì‘§»¿³+Ïš8 dz6iôòË1ó/ ò.‰©~cyšÌ/5v1KK R?vïøAÿuÅÿ Ýk8mfªY$Iæ^§S8éñŒPç×ñÞ^ݘ.•Ø«Åÿ-¦KüÜÖ|¤ÌÇRæ–ëØ2¯Ö­ëò™~g:ÄÏY+ùÃíÓ´áãic“¬°ý¯¡s¬yWb¯"ó?þ´WåGýµ´û¬®s=·ýä}ߥë}Ÿþê^ÿÐý"Í+»|Iÿ9Ïÿ)Ïåoú÷õk•gú%î.F—ûÈûÇÞôlóÖŠ¼ËÍŸŸBò–©.4—Zž£nJ]E¦D“]kÉä’5ä´ø‚“N‡|Ûi»6Xñ ˆ=î›UÛ˜0˄܈þoà2Ï&yËGóÞˆšöˆ'[&wˆ­Ì&”ä;« ú£Úµ0µzIàŸªüœý²ˆqÂëÍæ3”’ëoò¯—§ŽÛ]Ö¬´ë™@1ÃusNTíË‹°4÷é—âÒäÈ.1$y6¯3S‰ó/)üÀüñTüÁÒ´]>O¯è±¢nÒÚÙžèÉ:s„A$…ù+ÆëÀÐøï›cø¸%#´¿„ÞÞwöºMmø:ˆÄoâo¿*ûÏ6~nÝé¶~\³òæ…5ß›|мìt‹ïôg¶PxÖà)½h9@I`øúnË33‡27¿s‘ªíc<œ¢v¯z@üÅóï˜çüµüÀÓ"Ð|˪YO&‘¨i²HÖ)aY%¡«ûKJe¹ô£ŒfÅ.(Äîà5àí ÒÈpfä=$~ Æôß+^yÛòûÍ^i×5]BóÏ^R™–¸¸i°<•åW©&c^[ÍæMHÞŒ@†AÝ×—êyüzSŸO“$äNLg¿þ´ïRѬ­¼‡ùgùä½#ýËi÷0C©%Œ%§»š&>£ÊbdÅOg§Jf><¤æÍ‡$¶#kéøìr2aˆÁƒ>(îºæ}ÿö¾ªFŠâ 0Mû†¡#œy{`^¦ù~@ÎJÇæÛôh¼›æ•–=BeR@‚õ‘®S©ŠåVf~?<ï{R2`¬vý_cç}¿¤8µô–ãôý¯Ð­7RÓµ‹ }SI»†ûM»A-­Ý´‹,2ÆÝ lÛº$K2¢³»E³@Ü’N*ñ¿ÌïùÉïÊËK9Ö]bwÌA¢i2¥ÌÆ@6Y¥Œ´pŠ‘^g•7 Ý1H”,l|Ñù¥ù“©þzyÒ/Cëÿ¢`âV2Z/« ˆ6æ(aø¿i·­AÎg·õñð¢w<üž³ÙÎΑŸ!°åçæ÷ìä^ÕØ«±WÍš ÷åïôÏÍ.ÇK{™•58WdúÏ5:,ñÔ¾Ð'©×ö¬eÆp˘åîý#Úø¥¤ÔGS¿üx=§EÕìuý&ÏZÓdõlobY¡nôaº°ìÊvaØí™r‰‹ÚéóÇ,ãÊA¹Ø«óÏæ/—¼…o ê¬óßÜ×êº}° <€mÊ„€«]¹¢¹fŒ~‰{”ÎiÄÇŒãâó}ʱþkþTi’Ïõ/3ùqå±¶º`O£-± "~& 4b*‘¸ éC‘)øs=ÅÑiôC_¢€&§ŽÀ=ÕÓåKŸÊŸŸ`±o*ëÚµ¶‡"ˆ/5(óÏF_CµG^\9~ÑÜàãÄ ºN‹´²ÇÂÉ0#Èž¤}ÿuõzç•ü¹aå=ËËúh?U²N!ÛíÈìKÿœsÕdÔ-¹ëß—2¤ªBÇÌÑcºU¯£/`ÿaûoð®n]<mÇs£íÏg°v„=^™ŽRþ=ãËä³C×ôß0Z‹>^DSÕ…¶’2{2ÿ™ÖéµP͉|Wµ{>‡'Qî=¸þ ^b—Y‡IšmRMA(Â7Rå“ö‚ ‹¸® \² dãæžÅÇ¥ž¢1Ô’ zƒ[ô¿'—Ï®ˆ¯$Ô¼±sqi®jlûIú¸‘}rO"¬õý¢HøIß¶s²ÔÔ¸±'.q®¯©aìž,C²ž"á—Š½=,*½ÀÛ¯6DÖ7~PòÕÓØJ’ùªà-ÅóÕd™c­\ª’»šw'3Ž9i°žyç¿ðpjñö®º(1ÓGÓb$ô³ÐË»Üo&ê:ýêr¿–=GK–!$’pÖN Æ(j w§ëÛ+³òå—Ôx¢FÒýê}¦ÑhðšÆ,€Ô±›"ºLK–ý×ðÛynlÞEƒyÂ]W̚ƙùy娚ëYÕç† }Yå`"ŒžÂ¿“Ðzg?ÛZºýØøþ§Òý‚ì['U1°Ú¦_ |{Ÿ¥_”ÿ—:_åWôŸ%é|\ÙGÎúì/uy/Å<íßâm–½íœëéå‹ÿÎFþnÅù?ùo{¬ZÈ¿â}K–ŸåèO~µ"šÎTÖ« ÕÎÔ-ÅOÚÅ >@üòtÚF‹/šu`Ï®kß½õ%«J¶Ìy­Y·¬§÷Œk¿ÃÜgSÙNqžrûžG¶õž$ø(ýÿ±–þbëšg—¼¡¨ßê¶ñ^BSцÊáHçžM£FV¨"¿{s3[–8ñ!~Ngá–L±5çÜ9äÿ$jYÐô_7Ëæ¯ðÅî«s’ÚãŠÛKm!äŠÀü<Ìaœswáëšm6’Xáœ|GáN÷W­ŽYˇÆ">7ý¯¢úî:gHò­â®Å]Š»v*ìUØ«Ÿòó@O/k]ÑÑô»}m‹ÝÍ4¯Í¸†#Ö-± B½74Ì3¢‡¡¸œèëòx‘œ½\<˜Çš¿+õ CÊÞXòv‘<'GÒ®#}Qå-“(Ù¤T0©ç#[îcj4–8c‰Ú'ÇÍËÓv”c–y$=R~>OSUUPªª€€ØfÕÓ>yÿœƒ×–ã^Ñü±,Ï—n‰y}éG”Îc‰"¬‘©+þ¶s}·˜™‚Þ§°pT%’·;§ù[Pòåîm–."›M¶"Ž8Ũ ¦Œ­ãÈW9y{¸zˆLHñÊw¡Böò×N´šúöU†ÒÝY¥c@¨¢¤â(ÄÈÐæùfûVÖ®|Ã'æl²¦˜š´kËlž´cÖŽ ×v än½Fgá‘ÆAª:aáxgºŸcÅ"MMåŠа¨9ÞƒoŸF—áCȼÏÿ­ùQÿmmþë+œÏmÿywézßgÿº—¿ô?H³JîßÎsÿÊsù[þ½ßýEZåYþ‰{‹‘¥þò>ñ÷½<Áõ¤¹%äZ&¥.œ ÔÖá­Ü™„Lc§û*e˜@3ÊÃVrD%ÃΫ߿ɒþvÜ]iÿ•ú¥ß–odÓæÓ¦·,úlÍ k•ŠHÉ€‚?¼«/ߘ‘-DDÅØ<ýÞngmHÇM#Œ× ¶ëäóÏÌO1CyÏŠ±|2çðùw§þyƒÌ˜¿–>RüÁÑôV_3Ù]­ì¶6q3HÑ#´BH—yŠ'UÜ…=M+˜ú3O¨É†Rô‘VeÉ×G&§M4cëè~<‡Á7Ö|»çÌø4?é|žLó¶q$Vvz¯".mø¤˜úa”rgP­û×(ÅŸ”ˉ ÌzÇ›~m>mXŽh $Â]GËßÑ4ò§åÇœ¯<ñææN£isªØBÖúVŸ§+z«+©f.«Ð;>#S^[S*Ôëñ >@'r[ô½šYÆlò@LËBü½òß—µ0j6QHòùšG—U†w ógb¢:÷ã×0sk²dŒþNÃgãÇ)È?ÇÅiÚf¤ZGa¥ZCcc};kh’(–»š*7Ìl™%3r6\¬xãQ$VA›ó’ô=hï£y‚ßÕ€žpL‡ŒÖòR‚Hž†‡ð=#2tº¹à—íqušA@ð/ÖíôÞÏéñ› Èùòù~»zÂ"F‹jUQ@Øi‰w`.Å.Å]Š¥iòæŸæß/ßùwSZÙßÄbfþÒHµý¤`}Æ_¦Ï,S0ãê´ñÍŒÂ\‹ç¿É}sPò‡™uOÊ2· ˆ&•ôÒÄñõTrtBfT¤±ý=Û;¹Ê9`2G‘t>Îꥃ,´¹;ý?>cö½ó1žÍØ«ÂÕ­üä]Ìžiâ±Így~Yè#Gh£P¶Â¤LŸë“™•x¶ø¼‡cÚ§Åê=îñï‹Ó<õçÍ#È:dZ–¨¯;O(† H zÒ ,¡ÈÙ@Üü³33Aßö—icÒ@J[ÙªÒ_ËíZÑ|Çæ©å³ko.kS[ꚨñòK‹ˆùÜÆcRH!˜/J|;dòÈ;ÉÙzl˜²å$T&D‡¼óøäô<¡Ý¼{óóŠKkåòwåäGXómÔ‚Õd¶ŒÜ,39â#‰VZö¡PzÔÕs+š÷<žW¶}£Ž+LJyu=ë?cÙ¿çç£òõÌ?˜›¡u;ÊßYµÒ§qqŒ¸–v$‰§º¢v«Ë°Ÿ>É–S$“d¾¯ÂÖìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±T=õ–§g>©[Ey§Ý#Cskp‹,RÆâŒŽŽ`GPF*øƒó»þqWòÅÜþzüŽõd·BÒÝù\1yá^¬lË{Œ/VþRÛ(³ic—MY£Å©Æq刔Oãà^#å¯=Úê’~ŒÕÓô~µÞ)DwSB-Õ«±Fú3¨Ðö¬rúe´¾Âù´ÇeÑÞLW<ì£ïïcãL¨ZZ‰ÍЂ1tE ÜÔ§‡*W6žnëw‘:Œ†G‡ºÍ|’m{Êðë3Eos&Ÿ«@¥#¼‡rP×áu¨ä7=óU¢H<2C¹ìŽß–’2Å( ¸¥¹„»ûÁèU¼³åø|µ¦~Šfœ´,²°ãÉØÙjh(£jäôzQ‚ ÛOnöÌ»C?‹(ðí@sÛ~½y¢5Í^ K¸Ô®7X—àNï!ÙT|ÎOSœb‘èãöOgOY¨ŽÿßÈu/`ÿœ%ü¦žöâûóÃÌ𗺺yí|¶$Z}¢cº»_Æý¹ûg“!œŒ2ý §ÓÃ8〨ÄP}ªÌ¨¬îÁQA,ÄÐ7$“m~j~hyþÇþr óÞg¾Ž?"hlöš4RHná…ë# b*÷2ÓL/u̽äÊŽßœNÐÏ,XL¢,ýÞofUUPªª€€ØgjðLϾ@¼ó¾± ½Åê/–ôùL·úqV1ëPÀjJ8‚ÄéšýfŒæ”lúG0ìô:á‚¡ê<‹ó>—qù•ùŸ•¦Y­<±å˜·%ˆÈòSxÉ´x¢štV#0õΣQÁÊ0s´Ù—Mâ 3™L//4¯ËuŸË¾Uó%ŒzíÕâ]O˜çžX¡…â© 7ǹsÐå’”t÷LqüVÕKSSÉÂz+ô²/$þbGæ=dkqçßùuøê’Å(’ÌÆC‘4rÙ>›w?=ó'K­ñ¸¶1çÜâë4 ‘>]þækmsmywVs%Å´£”SDë$nt>õ•â›þ rq'ÙøeÒ‘z?üâ÷üä7æmì~bÜÃå-¬¦I&·šBƒzÅkdì‡Aë:ÓõÊ0·›?¤n›ÿÎ`ù_Ê¿––—ÿ•žSƒÓ‡ë÷wüZupð°¼ó2Ó“ÈÓõãÚ‹@´É9²->ÜÙØZÚ1«A QâQÿ ï¡>q’W"{Ê'$Áä^gÿÖŠü¨ÿ¶¶ƒÿu•Îg¶ÿ¼»ô½o³ÿÝKßú¤Y¥woˆç5¥üÚü¬µ“â·[Ó R²j+}áFcêÏî¥î?s•¢½‡õ‡Þôœó7Öм^ü„´ŸZº×¼™æ;ï(Þß×qØ—11fäÜDrBÊ ß"µèLÝáí¢ !’ ¯ð]~Âfx¦q“ο´'žOüòß•´=[Eºš}gôò•Õç»rÀƒöOÀjKr©zïËaL}WjäË8ÈTxyWãö9:NÈdž‰&\Uþ?jKÿœü°Ó#dm2KÖ2¤ë-ÍÔÞ¢4|¸…0´Äj;íZÐdòvÞ¢_Å^àÃ`é¡ü7ï'ôS4Ô<¡åMZøjz¦‡§Þê* »›8&–‹ö~7Rv¦Þ³¬° d@÷—c“IŠrâ”=äåUQB ŠU€Ð”7€Þ)v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb¯ž?ç%|¹žúGæ&•u–¿g4PH¼Ñ%˜#s†XÔY¢mš€ü$v\éýžÔ’N",s÷kÊûEƒ€ÇM­ÐfÒä8òÄÆ_Ž]ÿfZâ1='ËŸçg掓ùo¢»&›¦MRñ7X ‹{™Ïj¢ü׫š~Ör¯«ñ'À9Gï}—ØžÅü¶cדìOŸ?“õ CÑtÏ.hö‹n¶šN™V–VÉöc†‚§s°ÜÏ|Ô=ª?|ùùÃÿ8ùyù˜n5•¼ß') ý”cê·2ësl ©$õxø·s˦)ò¾»kùßÿ8÷r–|ÓZòˆJÛW‰Ú{vPh=;°9!?³ƒàß6z^ÕÉcê«WØø²ïL¾Ï“;òæ/•|éMØKêVM>â‘\®Õ4ZÀx¡#:-6·o¤ïÝÕæ5]Ÿ—Ô6ïèʨ+Znv'å™nË|Áùo«Ã®ë^gòÓX_I«ÀÂãJÕíáLÊ»zNÌ Tö¶ê6¬Ú Êp£ÅÒBÝÎЄqÎÇ ç_7Ÿjš§å i¾JX‚y»Î·Êׂ>cuTˆ”¨Nž,3]“±aÿ!ÝÚcÍÙå—ø1 ¿_ãÉ5òo懕<·åJñçh¢}n9&/@„³‚›(5cÇ·ÂFùoƒàê! dù´øþ6›$òDGÞÉ¡ü潺յ켯u} é×BÎâòÖQ%Ò–s¿Õ‚T†#a_¦»fPíBdjıÏäážÈ"戺<¾oKΕúE4ƒyê²Ä.#±w ;Dj9ÚO„×m³gâÇ‹†÷îu ¸x«nWÑ–5»v*ìUØ«±Vù‘ùyeçí)a.-µ‹NM§ÞU©Ê9Ü£PtÜÇÁ×h†x÷ÉØv~¼éå|ây…!ÎRþiþL-¿•?5ti|Å AHlµ#'Ô‰{%É À¢ÉGÞ”ÊgÓO© {->§ap6ú_Êó•ÿ‘žo8y–=ñéÊÏ\C`É_æ™É·ÿ”å ôžy›þrò[ÊškêWÞtÒï¯(ít»¸u™j*¡"´iÅ]™¨¾ôÅiñÿ™uŸùÉÍÿñî£hö~Lн8tË9 ‘ÀÆH¢$|-#»z³R´ iÇ6}™¤92 ¦.¯µµƒ3}Rü[Ùs­x§b¯"ó?þ´WåGýµ´û¬®s=·ýä}ߥë}Ÿþê^ÿÐý"Í+»|?ÿ9¡ÿ“‹ò·þyÝF<ÇÕÿu?ꟹËÐÿ}ë½éyæo«»v*ìUØ«±Wb®Å]Š»v*ìUØ«Ö<ÍåhÞ ÷XŠ Íi¤°³HeýóÊÀ#)Ë‹csБ™8´ù7ŽÑܸ¹µ8¶•lOå]}ü§ yÓÈL3ù—ÊK5õ»ëe7Kê~üà ,(@1ü_8$nFnu8ÙµÓv¾Hm/Pû~n£Uظ²oIû>LÓÊŸšNó´ûáo¨7ý+ï) õðZ’¯þÁŽo´úüYyû‹Îj»76bÇxeòC ¥ ±«˜Øiœ†‡MéÉÈ3i´ðãg®Ö™þ]ùâ?'ùkÍ—Wͨù_I¾Ko.óaÎc#JjÄP«µÃR@í–èµ~9“¼b}-:ý“Fr/³ö²+?ÍÍO¸Óeó·–[HÐõvU³Ô£—˜Bû¯¨¤m±©¯Mès"=¥8‘âC†2êâϲ±ÈKŸ£Ì=ëÍ>^±ÕB^ê0ÛêžÖ} [‡î~"[“Qv Iß6RÔB2á'wU6IGˆD‘t£«ùÇËzVú%¾©'£c,Jó¬®EGm½ú`É©„$óäË“&BDFñçÓïOr÷ u=9o?Gµäþ€ýTÊžµ¡á^[öÛ!âFê÷gáÊ®"²l®m­¯ {kÈRâÚAI!•чVˆ"‹(ÈÄØ4X­ù-ù{«9—ôi±™·/e+¿Dcè\×äì¼2é^çe‹¶5þ+÷þ-cùä 9ÄÓ%Ýò‚XCsp8u¨ÑXÉçóÊáØøAê~-“íÌò({‡ëz=…–™i†o­”#ŒPBG]‚í×6p€ˆ (:©ÎS7#e’`ìUäú¢¬ÿó“¿–J9D—Z4ª¾º”¬Þê¹ËöÙýèþ¯é/]Ø÷2þ·èÑÜÓ»§Ãÿóšù8¿+ç—ýÔcÌ}_÷Sþ©ûœ½÷Ðþ°ûÞ—žfú»±Wb®Å]Š»i™UK1@©'`îqT¶½¡ÞÝ =NÒâùjZÚ˜¤”¹ª+Ûå–Ë â,ÄîjŽxHÐ'Þ­©ÞþŽÓo5Eî>©·„tç'¤…ø-h*iA\Ž8qHVYdŸ L¹Ðxdž˜~bÒ¯|Åäß$Ç'—tßTÞ^]]‰PHôE1… •^yÐÇÁŽB2z ö¼Ðí½FXâÅé2Oö~”žïóãUó‡å¿æ™ Þèrö†lº\¢_\MþoâØWšmÿ+4&ùcYò Û¿žá–Úæä¬³I00Æe™ç‰ÉHøH¢œÿd7Ìí4µ3Ë8å»Ü~ªø:íTt°ÃŽXOï6=~6:Q{ zµ­þbù?ógÊ6É&“®iñ1©•FÆÜƒÌÁY@Uâ‹|ÒІ š|‡xŸOãñÍߌɨǨÆ6œ}_Ç&Uä¯Ê?Ê6¾eÒžìßùÌSJãIx½8­ ”:ƒ%‰F [áû#0õ}¥,ƪ”>÷7GÙqÂ'¸Ìòî ×JÒtÍ O‡JÑíc²Ó­ÁÛ@¡91f É$“Üï˜rÊr2‘²]Ž,QÇŠæO8ycÊ¿[ó©Ÿ‘$jË ︖®ÿìTåº}.LÆ¡Zµ¼XEÎ@~;ž/©~}yŸÎZŸøgòwËwZž¥-U.¤·iæ´æ–ñÕUG^rµ?™FtzOgzå?úÞ_[í?LCâWãÜÎ|•ÿ8iç;_Eæ_ÏŸ1Mêº%œÉquƵàóüPBµ¤*õþe9ÑáÓèËj5Y2ÊæL‹ë$~]y'òãLG’´[m"Ðê´)Yç+ѦËI!÷v9sŽÆ¿>*m?8?.u,«­D>» Üµ£ ŸL=@LOþKW¨¤Æ‘nºšÎïòÿ_ ½åæx¢†m¥ô#sÄÀïÊøHð íšýV:7Þú²ý¥âcðdw/êþϹë:ž«¦è¶Rj:µÔVv0ŠÉ<΀©êO`79Š"NÁéóf†8™L€{ŵ/Í/9~cëCÉ_’ÚMÍíìõVÔR/Þð¨S"‡¢A®òÌE+û'3qizÉâ{SÚƒ+Ž ‡óºü;¿Ÿ@~KÎh>Už?5þiËš|ÜÍë­‹—N¶”ž\ŸÕ®$ñ2ä›3@xÙÌÈÙæúUUB¨@ `ì1`Þ*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wœy÷ò#ò¿ó#V±×¼Ñ¡E6µa<‹ès-Ê@á„¶<Ý~§²ðåÞ¸OxüR—–¿?<§«·Öã“D½;-f·-Ò‚Dì|Ý`íŒsÚ^“ö:Oaå†ñõµèW²/˜4 ÄÐ5K^[Ë®¡ ãG‘ ‡6Þ•¯\ØÈø<'˜æêà<<ƒŒ& ~NyjßÊvz™m!Ôo –k‰.âi"oRV§ÀèQéÁPvÛ0°öf1ŒFbËŸŸµ²¦p4;‘þjü²Ñõ%(è±Ç¥Å‹sbTE¸@Ed&¬Üƒf$žûôË5χ»šô½£8fñ%ê½¹†_ù3óKÏ¥h^t¾]Ó&I®.mœ´·~šð­7ÄT° Èšt…=.£7 rPˆû>Í6)â³)wôü|Tt/.i¿˜ß™þoÕuûcu¤én–6öîÒF¥×÷JßRE"f§ù@äpàŽ£Q9HX~>L³ê%¦ÓcŒ oøù¤Þgò&qù©¤yGË7iɬwSÏͧlc(¬A¯ãêÛ–Êsé"uÇ[_¹ÈÓkd4²É½{ïûKß´{;» .ÖÊþñµ ØcTžõÔ#Lã«•_ çAŠ&1›=ï1–bR$ Ïœ5ûß$ëšÞe=]Ko¤B £@²±[‹oNþé\þÄTŠœæóKõñNܾOY‚±éaá <ϸïú•|¹æ=JÇÉŽÆþæëÊöb;mêå™eCs9…Bˆ%3(¥:ÐW òŽ,´Iˆåñc¨ÓÆY±XgyW{åö©ecåO-iZ®¦‡\¿²Žî(.®¹g&PT9äÔ‚‡¶ntyqÂ2>¢/~n‹_ŒË,åúA­†Û3E’7fTpÌ›8§ßÃ3m×Òì(c>jó¥”î´{[ËK›–Ön~« ÛFcj¨«Ô޼…n@>‹¨Õ F ‚x9z]³ @á»&̧Ø«Ê/¿õ¨¿,¿ã>‘ÿuó—í¿ïGõIzþÀþàÿXýÁú9šwrøþsCÿ'åoüòÿºŒy«þêÕ?s—¡þúÖ{ÒóÌßWv*ìUØ«Î;<׿/&y+ôç–¤Ž+Ä»†)žX–`!•]Ml>ÐæÓ²4ØófáŸ*u=µªÉƒ9ÛÎFXè1ùÊ1iÚ½¯Õ’ý´¨í¢ ö잨 >­$)Ü Ø¶lä%? ÀÄÝ]õù—X”cÅŒ…]WOcÿš¾iÿ•“ù9£yÊý ›-Kêš­š3ÑÚ6 Þ´$DÊ@Ýs'³tß–ÕKäc`þ>./jj¿5£ŽQ±¢?)6£ùgšü¥¬y.ËPòæ§^Ç.¯®Þ ™â£«„EV˜“Ee4ãZî´ÌÁ AÅ’9™#hŠýŽ É¦qË0ŒOªFÏë}oqm}kÕ´‰=¥Ìk,2¡ ’G"òVR6 ƒQœD¢bhó ‚ùKÉ>G×õ?5ùÇòÂËÌ÷‡cq<ÓÙÛÇͯ i¨t ý0Õ$zga«ÖB8±ç0‘û?¾Þ#E¢É<¹0 †íÞ9}ÔôÍoËòzËË,¾_¹†úÝ·’êg–CÌJV>¯-‡ìŠt­ìÞÑ”õ\S?X¯//¹Úö§fFNcè7çç÷»Ì¾Nóç˜u)~iy/Ó°óZéÐêÙ_©€†hÏ.I"ïý㣦ÁHötú¬8ã“Má{N>YcÔbÚ|;ƒ³ ü¼ü¨Õ<¯®j¾g󴚦¡æ$]fÁ-•m^y¤õ]ƒ*¢¬ pãA®í(å„aðˆîåveKå’râ3¡[_ãÉ‚j~IóÖ£w­ù{ÊÞBÒ<µ¦j2ÜY¿˜]£õNžÒ8ªÈåy¨ø„h~Cc›zÌ1œòÊdQáóu¹tYäe xclqGñÜ÷)è6ÞLò¦› ý`<]ºÇ-Ô‡€fiÔü ±&•Øg?©Ìsd3¯¨½&—ÁŠ0¿¤0ï5~}þ]y`±n R“àñF¹f<²¸škËŠHómSÍž•Ž-ÿ4<Ÿ;Ù#p:‘‹ÓiðÝÛ -œû.mpöÖHýC‹ìuû·1ûB} þxyZãÅÔšMËPzwÉÁ+Þ’¡dýb3k‡µ°Ï™á÷º|ýž‡òz¥õ–¡¹°¹ŠêݾÌÐH²¡ù23a‰ Ý\àbhŠ*ô’ç©îi’bÃ|Åùk¢ùƒ^¶ó0º¼Óu˜8+ÜXM虣M¸¾Äôøj¤m˜Yô0É1; ù; ?hÏ (J'½™æk¯y§åÏåíÞŠºüþn¶´»½Õï=r1ž¿¼QûR7QšÍˆÃˆä™{·í xŸÆHäç”ËÈ–úFf#Žîþh-£ ¢«ÈIÌ'\¯µ…aˆæ[;\Y̤y©¹w¦y{ó£ËCZlô­#IŽÞ åÚ*ˆgE$ÒƒâjWmÆQ–QǪ‡¡þ·' %“G>fRý!å¿0Êo?4¼ÿ¤ŸVHTG¦ÌV¿ I(âª#Ðåx3o›,~ šŒ°a—Å,:~­§þ[·æ·¯—Z½øf·MÂC$¾›B>"Þª‚^½¼Úʸ%(Èlùþ7nñ!-G‚qåöû™]÷˜üÇosùOc§:ɪÅm6¬L…šéf6îD¡ªNÜ…}ÎeÏ<ÁÂ/ê«óäáCOŒAᛯ.|ãZüÊóš<é¥hzìvZ,’÷¥ç™¾®ìUØ«±WŸ~wéÿ¤¿+<Çh`ŽéOqõiÒb{öS›.ÈŸ¦ξaÕvÖ>-,Ç•ü¼³Aü÷µ‡È:W“ü½¤_krNNŽ¡xãô¾Îô_Ñ­ü½¡éº«´–úm´6‘ÈÿiÄ(‘÷4®s¹òœ“2=M½6ŸÅÀrˆ¤º×Èþ]³óuïž ·qæ+ø– çõ\'¦¨‰A!w­jã-–³!Ä1é QÑcŽS”QdyŠå¨ÝÞZX@×W×Û[&ï4α¢vbÉF&F€²ÆSMœy‹óóòÓËáÑ5C«]/û£LO^¿)IX¿áóiƒ±u?‡„yíû]N£·tØÿ‹ˆÿG·—ÚÁ¡üèüÓü¹m?òŸÉ7*[Ó7† oZ=«ÉÙAüôf¹Óû9¼äO»oÇØèu>ÔLíŽ {÷ü}¬³HÿœHüñüÈ™/7<Øš6žä;é±ÉõéÔõ ··1Ú'‡%vùm›Ìä’Ûþr ;“aæï-Ýé—±3,f®§ÞÄL¿*œØãíÈÿ~N·/³Òþ ïf:_çåæ«@šÂZJzÇxoO›¸á÷6gcí<2þ*÷ºì½“¨‡ðß»v_c©éºœ~¶›yä]}KyRUûБ™Ér ¸Ç(í B/&Á.Ôô Zh›XÓmoÚXZææ)Üñ. +Mò¼˜a?¨Û<áôÈ‹î)6§£Xùk@ÖçòÆÝåê;ͦÇ@·r8*y«F%•w#a¾Q“Ç FÉéÞäcÍ,¹"':¯sçíCÊÐëÂ=3Ë>EÕt­zêUÞ4æÎÕ+ñ…iPVŸôùÏON'´1Ê2=üƒÓãÔœ~©åŒ¢;ªËÞçü½Ónu?-jòÜÌ·^Z‚;{hÓ‡¥ E W ¥»vlèŠ&P•ïšùÎ4*en‘ù}k¤j^hÔÒúI¦ó9s*º(ü̆‹ÇíSÔ¦þ1èÄe3ZåיƯ£íäò/”"òF€šWFñVY&õÚ1&B 8‚Ý)ã“Òi¼pݵëug<øê˜m÷þµå—ügÒ?î£>h{oûÑý_Ò^“°?¸?Ö?p~ŽfܾÿœÐÿÉÅù[ÿ<¿î£cêÿºŸõOÜå辇õ‡Þô¼ó7ÕÝŠ»v*§<]C%µÌi5¼ÊÑË ŠQ••ª#¨8A ØD¢£Ée­•Œ~••¼VÑ$1¬k÷(¾LË™´F;JùI&§ç)輿Kk–L½R{¸czÒ´ ÍR}€ËñérÏé‰?.¯>©ñ #Vÿœ…ü®Òõ9uV Åem+ôðyDh~†Í†.ÃÔËøkÞ]v^ßÒÃø¸½Á†Oÿ93w«Üþò?“îõ;ÇþìHÌòõ ÿGµI ÿƒÍŽ/fñÏä?s«ÍíHþ|Ïèý©­—?ç0¿0ÿÞ- ùSN—f’ê(t€ø­á{¡óEͦÂÓØâ÷—SŸÚLùpþÖW£Î ùŸ^¸ŽÿóOÏïu(ÞK}]Dò‘$ù—·ù;þq;ò7ɦ9£òâëwñÓý/\ß§s·¯}¡Ë­ì¶–––ñÙØÁµ¤#ŒPB‹h½hª >X¡[v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»JµÏ,yoÌÖÿTó&e¬ZСk ÒzÑfV«ÈüÉÿ8‰ù æ3$ƒËgHº“¬úUÔöÜÕ„³@?ä^)·”k_óïÿ/ú‚(yÛPÓeJ˜Æ¡k ãW°õ-Úԯωùa”›æÄîÿç?ç$ü¸9ykÎvz­º GßÝ#õíÜMìó"ܱå"âäÐàŸ8’CuåùËÿ-÷!åOÒѦááK+Î`ÛO˜6ôé@s*¯˜s ü?S‰>ÅÓË#ãúí&¹üÊüÞÐ+þ)ü·¾¶á»³ØêKABH3G §\ÉnO¬GãæâÏÙøR?êBÃÿ9§£˜µ//\ÛJ§Œˆ— #)îtŒÔeñíÈõ‰ù´KÙét˜ù&ÎDù&Aûë=J¥Ma–¾¬Õü2ÑÛX»ãâÑ.ÀÌ9ý¿©0‹óçòîCGº¹‹jÕíd;ø|²ÁÚø;Ïɨö& t4\ߖ޵ma£?ÊÖw„ÿÂÄFLv®ç}‡õ0=©þoÚ?[Ҽѡy·þrSòÛQòýß×,¢¼Òmä—Ò–*J·Ò9^3*ަ´¦h»SQ ¹‰±_¤½di§‡ŒÅýúgš×døOþsŸPM#ó3òïU‘ ‘ØÛ›§H Ë òÈTÜÓ*Í8÷‚ôù8'wXŸý o—¿ê^¼ÿ‘Ðç+þ†çüðö_è§ó؆oùË€ b‹zŽ™¤i:-°³Ñ¬-ôëAÒÞÒàŒvû…¡Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*”ëáŸKþv?¨zéaèpã_ø»jWyαÿB¿êÓÿà/W›Wëß ùzŸµýöõñÅ;±{þpºì,¾BZG¥©ipõñô¦\Wtº"ÎÜIêIuäàÔ‘ùŽ—oòc¼Qøb»¦~Tò?üâ ™t«Ï(]ya¼ÓÔ2i g游7jÀÄ"ˆ]¿6åÑxšâ»¾‚Å ~¡úš~•ú¯©CéýkÒ寻ñõ;b¨?ùÓ¿íYÿNتs£èÇõ~?Wâ¾—§N)ðñ¦Ô§Jb«ñWb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb¯ÿÙ£DÐÉêyùºÎŒ‚ªK© àÉêyùºÎŒ‚ªK© 2http://www.synthesis.ch/ÕDÐÉêyùºÎŒ‚ªK© àÉêyùºÎŒ‚ªK© dhttp://sourceforge.net/projects/expatyXô;H¯,‚]Ä…'c¥«ëDÐÉêyùºÎŒ‚ªK© àÉêyùºÎŒ‚ªK© zhttp://sourceforge.net/projects/syncml-ctoolkit/yXô;H¯,‚]Ä…'c¥«³DÐÉêyùºÎŒ‚ªK© àÉêyùºÎŒ‚ªK© Bhttp://www.zlib.net/yXô;H¯,‚]Ä…'c¥«·DÐÉêyùºÎŒ‚ªK© àÉêyùºÎŒ‚ªK© Fhttp://www.sqlite.org/yXô;H¯,‚]Ä…'c¥«ÉDÐÉêyùºÎŒ‚ªK© àÉêyùºÎŒ‚ªK© Xhttp://www.pcre.org/license.txtyXô;H¯,‚]Ä…'c¥«¿DÐÉêyùºÎŒ‚ªK© àÉêyùºÎŒ‚ªK© Nhttp://www.metrowerks.com/yXô;H¯,‚]Ä…'c¥«½DÐÉêyùºÎŒ‚ªK© àÉêyùºÎŒ‚ªK© Lhttp://www.microsoft.com/yXô;H¯,‚]Ä…'c¥«ÙDÐÉêyùºÎŒ‚ªK© àÉêyùºÎŒ‚ªK© hhttp://developer.apple.com/tools/xcode/yXô;H¯,‚]Ä…'c¥«}DÐÉêyùºÎŒ‚ªK© _Toc216071380}DÐÉêyùºÎŒ‚ªK© _Toc216071381}DÐÉêyùºÎŒ‚ªK© _Toc216071382}DÐÉêyùºÎŒ‚ªK© _Toc216071383}DÐÉêyùºÎŒ‚ªK© _Toc216071384}DÐÉêyùºÎŒ‚ªK© _Toc216071385}DÐÉêyùºÎŒ‚ªK© _Toc216071386}DÐÉêyùºÎŒ‚ªK© _Toc216071387}DÐÉêyùºÎŒ‚ªK© _Toc216071388}DÐÉêyùºÎŒ‚ªK© _Toc216071389}DÐÉêyùºÎŒ‚ªK© _Toc216071390}DÐÉêyùºÎŒ‚ªK© _Toc216071391}DÐÉêyùºÎŒ‚ªK© _Toc216071392}DÐÉêyùºÎŒ‚ªK© _Toc216071393}DÐÉêyùºÎŒ‚ªK© _Toc216071394}DÐÉêyùºÎŒ‚ªK© _Toc216071395}DÐÉêyùºÎŒ‚ªK© _Toc216071396}DÐÉêyùºÎŒ‚ªK© _Toc216071397}DÐÉêyùºÎŒ‚ªK© _Toc216071398}DÐÉêyùºÎŒ‚ªK© _Toc216071399}DÐÉêyùºÎŒ‚ªK© _Toc216071400}DÐÉêyùºÎŒ‚ªK© _Toc216071401}DÐÉêyùºÎŒ‚ªK© _Toc216071402}DÐÉêyùºÎŒ‚ªK© _Toc216071403}DÐÉêyùºÎŒ‚ªK© _Toc216071404}DÐÉêyùºÎŒ‚ªK© _Toc216071405}DÐÉêyùºÎŒ‚ªK© _Toc216071406}DÐÉêyùºÎŒ‚ªK© _Toc216071407}DÐÉêyùºÎŒ‚ªK© _Toc216071408}DÐÉêyùºÎŒ‚ªK© _Toc216071409}DÐÉêyùºÎŒ‚ªK© _Toc216071410}DÐÉêyùºÎŒ‚ªK© _Toc216071411}DÐÉêyùºÎŒ‚ªK© _Toc216071412}DÐÉêyùºÎŒ‚ªK© _Toc216071413}DÐÉêyùºÎŒ‚ªK© _Toc216071414}DÐÉêyùºÎŒ‚ªK© _Toc216071415}DÐÉêyùºÎŒ‚ªK© _Toc216071416}DÐÉêyùºÎŒ‚ªK© _Toc216071417}DÐÉêyùºÎŒ‚ªK© _Toc216071418}DÐÉêyùºÎŒ‚ªK© _Toc216071419}DÐÉêyùºÎŒ‚ªK© _Toc216071420}DÐÉêyùºÎŒ‚ªK© _Toc216071421}DÐÉêyùºÎŒ‚ªK© _Toc216071422}DÐÉêyùºÎŒ‚ªK© _Toc216071423}DÐÉêyùºÎŒ‚ªK© _Toc216071424}DÐÉêyùºÎŒ‚ªK© _Toc216071425}DÐÉêyùºÎŒ‚ªK© _Toc216071426}DÐÉêyùºÎŒ‚ªK© _Toc216071427}DÐÉêyùºÎŒ‚ªK© _Toc216071428}DÐÉêyùºÎŒ‚ªK© _Toc216071429}DÐÉêyùºÎŒ‚ªK© _Toc216071430}DÐÉêyùºÎŒ‚ªK© _Toc216071431}DÐÉêyùºÎŒ‚ªK© _Toc216071432}DÐÉêyùºÎŒ‚ªK© _Toc216071433ØDÐÉêyùºÎŒ‚ªK© ÀF SDGZNJ~Z.PDFÿÿ­Þ<6SySync_config_reference.pdf}DÐÉêyùºÎŒ‚ªK© _Ref185328417}DÐÉêyùºÎŒ‚ªK© _Ref216070495}DÐÉêyùºÎŒ‚ªK© _Ref216070116}DÐÉêyùºÎŒ‚ªK© _Ref185308797ØDÐÉêyùºÎŒ‚ªK© ÀF SDGZNJ~Z.PDFÿÿ­Þ<6SySync_config_reference.pdf}DÐÉêyùºÎŒ‚ªK© _Ref207680839}DÐÉêyùºÎŒ‚ªK© _Ref207680839ØDÐÉêyùºÎŒ‚ªK© ÀF SDGZNJ~Z.PDFÿÿ­Þ<6SySync_config_reference.pdf}DÐÉêyùºÎŒ‚ªK© _Ref207680839}DÐÉêyùºÎŒ‚ªK© _Ref185318147{DÐÉêyùºÎŒ‚ªK©  _Ref43725462}DÐÉêyùºÎŒ‚ªK© _Ref150068798}DÐÉêyùºÎŒ‚ªK© _Ref185314626DÐÉêyùºÎŒ‚ªK© àÉêyùºÎŒ‚ªK© ”http://www.openmobilealliance.org/release_program/ds_v12.htmlyXô;H¯,‚]Ä…'c¥«{DÐÉêyùºÎŒ‚ªK©  _Ref47451048 DÐÉêyùºÎŒ‚ªK© ÀFwww.synthesis.chÿÿ­Þ¥ [D@ñÿD Standard CJOJPJQJ_HmHsHtHR@ñR Überschrift 1$$ & FY*$¤ð¤<@&CJ$KHV@ñV Überschrift 2$$ & FY¤h¤ð@&PJmHsHuJ@ñJ Überschrift 3$$ & FY¤ð¤x@&6N@ñN Überschrift 4$$ & FY¤ð¤<@&6CJDñD Überschrift 5 & FY¤ð¤<@&CJPP Überschrift 6 & FY¤ð¤<@&6CJOJQJLL Überschrift 7 & FY¤ð¤<@& CJOJQJPP Überschrift 8 & FY¤ð¤<@&6CJOJQJR R Überschrift 9 & FY¤ð¤<@&56CJOJQJBA@òÿ¡B Absatz-StandardschriftartLþOñÿòL Font_titel#CJOJQJ_HmHnHsHtHut0t Aufzählungszeichen! & F„e„›þ¤P¤P^„e`„›þCJOJ PJQJ mHsHuL @L Fußzeile  Æ_¾$CJOJ PJQJ mHsHuN"N Kopfzeile  Æ_¾$CJOJ PJQJ mHsHufþO2f List *+ & F ÆhЄʄ›þ¤x¤x^„Ê`„›þCJOJ PJQJ mHsHu$)@¢A$ SeitenzahlD>@ñRD Titel$¤ð¤<@&a$CJ0KHmH sH u(U@¢a( Hyperlink>*B*RþOrR console*„°„h$d%d&d'd]„°^„hOJQJLþOñ‚L Zwischentitel$$¤ð¤xCJmH sH u>V@¢‘> GesichteterHyperlink>*B* >C¢> Textkörper-Einzug „h^„h2@ñ2 Verzeichnis 1CJJ@J Verzeichnis 4„8„˜þ Æd# OJQJmHF@F Verzeichnis 2„ð Æd# OJQJmHF@F Verzeichnis 3„à Æd# OJQJmH22 Verzeichnis 5„À22 Verzeichnis 6 „°22 Verzeichnis 7!„ 22 Verzeichnis 8"„22 Verzeichnis 9#„€@Y@B@ Dokumentstruktur$-D OJ QJ .BR. Textkörper%$a$JþñÿbJ Font_text&#CJOJQJ_HmHnHsHtHu<þ< Tagheader'$$„V„ªù^„V`„ªù0þO¢0 tagheadertitle5hþñÿ’h TbT.TblTxtLft)1$d$ÿ¤´¤x ÆB*CJOJQJ_HmH sH tHNþ¢N Normal (Web) *¤d¤dB*OJPJQJmH sH uN#N Abbildungsverzeichnis+„à„ þ^„à`„ þ>%Â> Absenderadresse, CJOJQJ K Anrede-^6@â^ Aufzählungszeichen 2 . & F€ ƃ„8„Lÿ^„8`„LÿCJD7òD Aufzählungszeichen 3 / & FD8D Aufzählungszeichen 4 0 & FD9D Aufzählungszeichen 5 1 & F 8"8 Beschriftung 2¤x¤x5:T2: Blocktext3„ „ ¤x]„ ^„ L Datum40+R0 Endnotentext5CJDOD Fuß/-Endnotenüberschrift60r0 Fußnotentext7CJ0?‚0 Grußformel 8„œ^„œ2 2 Index 19„ð„ÿ^„ð`„ÿ2 2 Index 2:„à„ÿ^„à`„ÿ2 2 Index 3;„Єÿ^„Ð`„ÿ2 2 Index 4<„À„ÿ^„À`„ÿ22 Index 5=„°„ÿ^„°`„ÿ22 Index 6>„ „ÿ^„ `„ÿ22 Index 7?„„ÿ^„`„ÿ22 Index 8@„€„ÿ^„€`„ÿ22 Index 9A„p„ÿ^„p`„ÿL!@’L Indexüberschrift B„h^„h5CJOJQJ222 KommentartextCCJ./B. ListeD„„åþ^„`„åþ22R2 Liste 2E„6„åþ^„6`„åþ23b2 Liste 3F„Q„åþ^„Q`„åþ24r2 Liste 4G„l„åþ^„l`„åþ25‚2 Liste 5H„‡„åþ^„‡`„åþBD’B ListenfortsetzungI„¤x^„FE¢F Listenfortsetzung 2J„6¤x^„6FF²F Listenfortsetzung 3K„Q¤x^„QFGÂF Listenfortsetzung 4L„l¤x^„lFHÒF Listenfortsetzung 5M„‡¤x^„‡41â4 Listennummer N & F 8:ò8 Listennummer 2 O & F 8;8 Listennummer 3 P & F 8<8 Listennummer 4 Q & F 8="8 Listennummer 5 R & Fb-ñÿ2b Makrotext"S Æ àÀ €` @ àOJPJQJ_HmHsHtHfIBf Nachrichtenkopf.T„n„’û$d%d&d'd-D^„n`„’ûOJQJ0Z@R0 Nur TextU CJOJQJ8b8 Standardeinzug V„Ä^„Ä6Pr6 Textkörper 2 Wdà¤x4Q‚4 Textkörper 3X¤xCJLR’L Textkörper-Einzug 2Y„dà¤x^„JS¢J Textkörper-Einzug 3Z„¤x^„CJ\MQ²\ Textkörper-Erstzeileneinzug[$„Ò¤x`„Òa$bN¡Âb Textkörper-Erstzeileneinzug 2\„„Ò¤x^„`„ÒZ$ÒZ Umschlagadresse!]„„üÿ„ôÿ„à&€+Dp/„^„OJQJ4@â4 Unterschrift ^„œ^„œ>Jò> Untertitel_$¤<@&a$OJQJ4.@4 Zusatz 1`¤x 5OJQJ4,4 Zusatz 2a„ð„ÿ^„ð`„ÿ:þO": Simple Bullet 1 b & Fk:þ2: FeatureItemc„ª„Vþ^„ª`„VþTþOBT Errorcode_descd„„éù¤¤^„`„éù PJtHuRþORR BodyTexte$¤¤<a$CJOJPJQJmH sH tHuFþbF DenseTextfCJOJPJQJmH sH tHu`þr` GroupHeaderg$„h¤x¤<^„h"5CJOJPJQJmH sH tHuTþ’T Code Example 0h-D CJOJPJQJmH sH tHu\þ¢\ Code Example 1i„h-D ^„hCJOJPJQJmH sH tHu\þ²\ Code Example 2j„Ð-D ^„ÐCJOJPJQJmH sH tHu\þÂ\ Code Example 3k„8-D ^„8CJOJPJQJmH sH tHu\þÒ\ Code Example 4l„ -D ^„ CJOJPJQJmH sH tHu\þâ\ Code Example 5m„-D ^„CJOJPJQJmH sH tHu\þò\ Code Example 6n„p-D ^„pCJOJPJQJmH sH tHu\þ\ Code Example 7o„Ø -D ^„Ø CJOJPJQJmH sH tHu\þ\ Code Example 8p„@ -D ^„@ CJOJPJQJmH sH tHu\þ\ Code Example 9q„¨ -D ^„¨ CJOJPJQJmH sH tHu`þ2` List Continue 0r$¤¤<a$CJOJPJQJmH sH tHuhþ¢h List Continue 1s$„h¤¤<^„ha$CJOJPJQJmH sH tHuhþRh List Continue 6t$„p¤¤<^„pa$CJOJPJQJmH sH tHuhþbh List Continue 7u$„Ø ¤¤<^„Ø a$CJOJPJQJmH sH tHuhþrh List Continue 8v$„@ ¤¤<^„@ a$CJOJPJQJmH sH tHuhþrh List Continue 9w$„¨ ¤¤<^„¨ a$CJOJPJQJmH sH tHuPþ’P DescContinue 0xCJOJPJQJmH sH tHuXþ¢X DescContinue 1 y„h^„hCJOJPJQJmH sH tHuVþO²V DescContinue 2 z„Ð^„ÐCJOJPJQJ]mH sH uXþÂX DescContinue 3 {„8^„8CJOJPJQJmH sH tHuXþÒX DescContinue 4 |„ ^„ CJOJPJQJmH sH tHuXþâX DescContinue 5 }„^„CJOJPJQJmH sH tHuXþòX DescContinue 6 ~„p^„pCJOJPJQJmH sH tHuXþX DescContinue 7 „Ø ^„Ø CJOJPJQJmH sH tHuXþX DescContinue 8 €„@ ^„@ CJOJPJQJmH sH tHuXþX DescContinue 9 „¨ ^„¨ CJOJPJQJmH sH tHuXþ2X LatexTOC 0‚¤¤ ÆÀ! CJOJPJQJmH sH tHudþOâd List Bullet 1ƒ & F{ Æh„„„^„„CJOJPJQJmH sH u`þâ` LatexTOC 1„ ÆÀ! „h¤¤^„hCJOJPJQJmH sH tHu`þò` LatexTOC 2… ÆÀ! „Ф¤^„ÐCJOJPJQJmH sH tHu`þ` LatexTOC 3† ÆÀ! „8¤¤^„8CJOJPJQJmH sH tHu`þ` LatexTOC 4‡ ÆÀ! „ ¤¤^„ CJOJPJQJmH sH tHu`þ’` LatexTOC 5ˆ ÆÀ! „¤¤^„CJOJPJQJmH sH tHupþ¢p List Bullet 6#‰ & F ÆhØ „Ø „˜þ^„Ø `„˜þCJOJPJQJmH sH tHupþ²p List Bullet 7#Š & F Æh@ „@ „˜þ^„@ `„˜þCJOJPJQJmH sH tHupþÂp List Bullet 8#‹ & F Æh¨ „¨ „˜þ^„¨ `„˜þCJOJPJQJmH sH tHupþÂp List Bullet 9#Œ & F Æh„„˜þ^„`„˜þCJOJPJQJmH sH tHu`þ¢` LatexTOC 6 ÆÀ! „p¤ ¤ ^„pCJOJPJQJmH sH tHu`þ²` LatexTOC 7Ž ÆÀ! „Ø ¤ ¤ ^„Ø CJOJPJQJmH sH tHu`þÂ` LatexTOC 8 ÆÀ! „@ ¤¤^„@ CJOJPJQJmH sH tHu`þÂ` LatexTOC 9 ÆÀ! „¨ ¤¤^„¨ CJOJPJQJmH sH tHujþO2j List Bullet 0!‘ & Fˆ„e„›þ¤(¤(^„e`„›þCJOJPJQJmH sH uZþ2 Z List Enum 0’„h„˜þ^„h`„˜þCJOJPJQJmH sH tHuZþB Z List Enum 1“„Є˜þ^„Ð`„˜þCJOJPJQJmH sH tHuZþR Z List Enum 2”„8„˜þ^„8`„˜þCJOJPJQJmH sH tHuZþb Z List Enum 3•„ „˜þ^„ `„˜þCJOJPJQJmH sH tHuZþr Z List Enum 4–„„˜þ^„`„˜þCJOJPJQJmH sH tHuZþ‚ Z List Enum 5—„p„˜þ^„p`„˜þCJOJPJQJmH sH tHu\þ‚ \ List Enum 51˜„Ø „˜þ^„Ø `„˜þCJOJPJQJmH sH tHuZþ¢ Z List Enum 7™„@ „˜þ^„@ `„˜þCJOJPJQJmH sH tHuZþ² Z List Enum 8š„¨ „˜þ^„¨ `„˜þCJOJPJQJmH sH tHuZþ² Z List Enum 9›„„˜þ^„`„˜þCJOJPJQJmH sH tHu„þO! „ bfo1Yœ$„µ¤à¤<$d%d&d'dNÆÿOÆÿPÆÿQÆÿ^„µPJmH sH u W@¢Ñ Strong5Zþâ Z Simple invisible bullet ž & F«PJmH sH u6þò 6 new i Ÿ & F–PJmH sH u4þ 4 list   & FÐPJmH sH u2þ 2 E-Mail-Signatur¡2þ" 2 HTML Adresse¢6]Hþ2 H HTML Vorformatiert£CJOJQJ^J<þB < Standard (Web)¤ OJQJaJ3f‚Œ¨ÄX^‰³Âéû$-bipŠ¢½ì®`ÿÿÿÿ9ÿÿÿÿ7ÿÿÿÿ4ÿÿÿÿõÿÿÿÿóÿÿÿÿòÿÿÿÿðÿÿÿÿïÿÿÿÿíÿÿÿÿëÿÿÿÿèÿÿÿÿæÿÿÿÿãÿÿÿÿÜÿÿÿÿÚÿÿÿÿÕÿÿÿÿÓÿÿÿÿÏÿÿÿÿÍÿÿÿÿËÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ3f‚Œ¨ÄX^‰³Âéû$-bipŠ¢½ì     ÿÿ®`4ÿÿÿÿ|||ã %ŽìoÓ›/(þ;WXêp‚ŒŒ¤Ÿ®¶¹>Ë'Ô±ÝÁíP ³ að!P(Ý+/N2Z5M?fIV cbv>‚¿Œ[– £|±p¼}ÈdÕuÞææ‹ðêùxÔ"!ÁA–RüVð[ ad®d?BDEHIJLNPW^hntx}‡ŠŽ™›£¦¨ª¬®±µ¹¾ÃÇËÎÒ×Ûàäçêïóöùüÿ  -  ï"J.é6Œ7Û@€I+PéVí]b¦g|nhsâyò†\Þ˜: E¦Kª ³ú¶¤ºBÄñËØÎåÒ—×Þݽåìî[ö¶üVDF H   H%,¡4¯;E„JO·WÂ^Eeœqêx i‡ÅŽ©•PŒ¤$ªs²V¹×¾YÅUÎwÖ©ßæ×ìMóÞùÖþ­f$µ/U<ÍL3S$V„[¨_Û`EbIcfd®d@CGKORTUXZ[]`acefikloqsuwz{~€ƒ„†ˆ‹‘“”–˜œž ¢¤©­°³¶¸»¼¿ÁÄÆÉÌÏÑÓÕØÚÝßâåéëíðòõøûý  V›Q(Þ6æ9òG™P^[{bþjÂs2}͈¦“{žÿ¦¨°Ê·ÁñËßÑ-ÙÊã/ðÜúŽøû )`º%e+ø07 BÑHàN·W_8fEt{I‚¸Š”ùœü¤§«Öµ?½´ÃÄÉßÏ™ÖDÞ ç¡îOöþøÎ‘"h7ËKRTüX¹^»b®dAFMQSVY\_bdgjmprvy|‚…‰Œ’•—šŸ¡¥§«¯²´·º½ÀÂÅÈÊÍÐÔÖÙÜÞáãæèìîñô÷úþ )+ÖüþšÂÛ3fŒã!RWyŽð+<k‹=eØÿ_”» M ^ | ~ Œ ª ¬ Ä â ä $'Nlo…£¦½ÛÞ÷3QTu“–±ÏÒï 2PSq’®ÌÏä<?g…ˆªÈËþMkn•³¶Êèë#&`~œº½Ûùü +.MknŒª­Éçê/2QorŒª­Æäçû=[^}›ž½ÛÞý?]`x–™¶Ô×úOmp˜¶¹áÿ(FI ÞüÿFdgy—šµÓÖòKv’Å#à#â#/$J$L$™8´8¸8–œ±œµœzŸ¥ŸÁŸÝ©ø©ü©Ÿªºª¾ªÉ¹ô¹ºËºæºêº:¼U¼]¼ÚEÚIÚ‡Ú¢Ú¦Ú!qL¼LûLxR’R—R®`Xÿ„Xÿ„Xÿ„X”ÿ•€X”ÿ•„Xÿ€XÿŒXÿŒXÿŒXÿŒXÿŒ Tÿ%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À•ŒXÔÿ€´ÿ•€Tÿ•€Tÿ•€Ôÿ•€XÔÿ€Tÿ•€Tÿ•€XÔÿ€Tÿ•€Tÿ•€Tÿ•€4ÿ•€Tÿ•€XÿŒtÿ•€ Hhy!ÿ•€Xÿ„ð˜ð/ðXRð$šˆ2IJý8[w¶×¢æ¥÷-ÿoøÿÿÿÿ2ð$:ëd¼>o4Àb3šI>©[ÿ ÿÿÿÿ@ñÿÿÿ€€€÷ðxðCðð( ð²±°¯ ðððn ðÅOÌ 8 ð3# ð ˆðð3"ñ’¿€ðx¢ ð4 ƒ ð0€…‡Š4¿»àã¿ÿðÅOuãð  ðð”ð` ð"!  ð5# ð ˆð×ÒÌ 8ðð` ð6 c ð$…‡–––¿Ëÿð¾"7ð ðr ð7 s ð*€…‡Š7ÿ™¿ÿð(ï^ð  ðð` ð8 c ð$…‡–––¿ËÿðÄ…! ð ðl ð9 c ð$€…‡Š9¿ÿð¯ïú ð  ððfB ð: s ð*…‡D¿Ë¨)ÿð?^?«ð ðfB ð; s ð*…‡D¿Ë¨)ÿð0‡0ð ð:ðn ð•&9 ðÈ# ð ˆðð3"ñ’¿€ðfB ðÉ s ð*…‡D¿Ë¨)ÿðrtQ ððfB ðÊ s ð*…‡D¿Ë¨)ÿðj~|s ððl¢ ðË c ð$€ŠË¿»àã¿ÿ𶬠Vð ðð` ðÌ c ð$…‡–––¿ËÿðêæPððr ðÍ s ð*€…‡ŠÍÿÿ¿ÿð_Â~ð ðð` ðÎ c ð$…‡–––¿Ëÿð“«æÒ ððl ðÏ c ð$€…‡ŠÏ¿ÿð_ÛÂþ ð ððfB ðÐ s ð*…‡D¿Ë¨)ÿð~×ððfB ðÑ‚ s ð*…‡D¿Ë¨)ÿð?ðð` ðÒ c ð$…‡–––¿ËÿðOê Pððr ðÓ s ð*€…‡ŠÓÿÿ¿ÿð,ë~ð ðð` ðÔ c ð$…‡–––¿ËÿðO« ëððl ðÕ c ð$€…‡ŠÕ¿ÿð,Ùë/ ð ððfB ðÖ s ð*…‡D¿Ë¨)ÿð®~®×ððfB ðׂ s ð*…‡D¿Ë¨)ÿð®7®ððð` ð` €°à  ðØ# ð ˆðT 7~ ) ðð` ðÙ c ð$…‡–––¿Ëÿð @°Àððr ðÚ s ð*€…‡ŠÚÿÿ¿ÿð` p€ðð ðð` ðÛ c ð$…‡–––¿Ëÿð °° ððl ðÜ c ð$€…‡ŠÜ¿ÿð` P€à ð ððfB ðÝ s ð*…‡D¿Ë¨)ÿð@ð@PððfB ðÞ‚ s ð*…‡D¿Ë¨)ÿð@€@pððfB ðß‚ s ð*…‡D¿Ë¨)ÿðb7bððfB ðà‚ s ð*…‡D¿Ë¨)ÿð[-|0ððJð` ð Ð@ ðá# ð ˆðÄ ê3~ðð` ðâ c ð$…‡–––¿ËÿðPÐððr ðã s ð*€ …‡Šãÿÿ¿ÿð À @ð ð ðDð` ð  pPð ðä# ð ˆðÄ «3:ðð` ðå c ð$…‡–––¿ËÿðÐ pPÀððl ðæ c ð$€ …‡Šæ¿ÿð    ðð ð ð` ðç c ð$…‡–––¿Ëÿðí Œ9 ððl ðè c ð$€ …‡Šè¿ÿðÊ «8 ð ð ðDð` ð  pPð ðé# ð ˆð¾ š -ÿ ðð` ðê c ð$…‡–––¿ËÿðÐ pPÀððl ðë c ð$€ …‡Šë¿ÿð    ðð ð ð` ðì c ð$…‡–––¿Ëÿð¦ Íâððl ðí c ð$€ …‡Ší¿ÿð•: £ð ð ðfB ðî s ð*…‡D¿Ë¨)ÿðC &C (ððx¢ ðï ƒ ð0€…‡Šï¿»àã¿ÿðM 4 l z ð ððx¢ ðð ƒ ð0€…‡Šð¿»àã¿ÿð³  Ùð ððrr ðñ “ ð6Tñ¥ÿ…‡Hn,»àã¿À33™Ë8cÿðöŽ ÏÍ ððx¢ ðò ƒ ð0€…‡Šò¿»àã¿ÿð½ =} ð ððl¢ ðó c ð$€Šó¿»àã¿ÿð -¼Áð ðð` ðô c ð$…‡–––¿Ëÿðç Š 3 ððl ðõ c ð$€…‡Šõ¿ÿðÄ µ B ð ðð”ðn ðþŽ Z  ð # ð ˆðð3"ñ’¿€ðŠ ð ³ ðB€…‡Š»àã¿ÿ?…àó ¿ÿðð ø:2ð¦ ððŠ ð ³ ðB€…‡Šÿ™Ì¿ÿ?…àó ¿ÿðþî¶Z ð¦ ððr2 ð s ð*€…‡ŠÿÌ¿ÿð¾>ì ð¦ ððfB ð‚ s ð*…‡D¿ÑÿðÎ’ r ’ ð¦ðfB ð s ð*…‡D¿Ñÿðþ²ð $ð¦ðŠ ð ³ ðB€…‡Š»àã¿ÿ?…àó ¿ÿðê Ž4Èð¦ ððfB ð‚ s ð*…‡D¿ÑÿðŒ¨ê Îð¦ðœ2 ð ã ðT€…‡ŠÿÌ¿ÿ?…àó ¿Ó°<ÿÿÔPÃ×PÃÿðr    ð¦ ððx¢ ð ƒ ð0€…‡Š¿»àã¿ÿðš=X ýð¦ ððx¢ ð ƒ ð0€…‡Š¿»àã¿ÿðÜI { ð¦ ððB ðS ð¿Ëÿ ?ð­$´2Þ2®` Æ©[!'tÈfþÿÿ¶%f$t3L'’%tÿÿ× _Ref216070074 _Hlt108492520 _Hlt13986753 _Hlt182821983 _Hlt182821972 _Hlt182821980 _Hlt182821935 _Hlt182821922contents _Toc17726654 _Toc75752647 _Toc127099644 _Toc127102463 _Toc128370874 _Toc216070194 _Toc216071379 _Hlt44132049 _Ref216070128 _Toc216071380 _Toc216071381 _Hlt216070424 _Hlt216070500 _Toc216071382 _Ref185328417 _Toc216071383 _Toc216071384 _Hlt216070155 _Toc216071385 _Toc216071386 _Toc216071387 _Toc216071388 _Toc216071389 _Toc216071390 _Toc216071391 _Toc216071392 _Toc216071393 _Toc216071394 _Toc216071395 _Toc216071396 _Ref216070116 _Toc216071397 _Ref185328437 _Hlt207680726 _Ref216070495 _Toc216071398 _Ref185308797 _Toc216071399 _Toc216071400 _Toc216071401 _Hlt185308943 _Ref184460226 _Toc184484618 _Toc216071402 _Ref185314626 _Toc216071403 _Ref185318147 _Hlt207681000 _Toc216071404 _Toc216071405 _Toc216071406 _Toc216071407 _Hlt108498210 _Hlt150068855 _Toc17726659 _Ref43725462 _Hlt43725468 _Toc216071408 _Ref108498418 _Ref150068798 _Toc216071409 _Toc216071410 _Toc216071411 _Toc216071412 _Ref150147280 _Toc216071413 _Toc216071414 _Toc216071415 _Toc216071416 _Toc216071417 _Toc216071418 _Toc216071419 _Toc216071420 _Toc216071421 _Toc216071422 AAAAAAABKN AAAAAAABKO AAAAAAABKP AAAAAAABKQ AAAAAAABKR AAAAAAABKS AAAAAAABKT AAAAAAABKU AAAAAAABKV AAAAAAABKW AAAAAAABKX AAAAAAABKY AAAAAAABKZ AAAAAAABLA AAAAAAABLB AAAAAAABLC AAAAAAABLD AAAAAAABLE AAAAAAABLF AAAAAAABLG AAAAAAABLH AAAAAAABLI AAAAAAABLJ AAAAAAABLK AAAAAAABLL AAAAAAABLM AAAAAAABLN AAAAAAABLO AAAAAAABLP AAAAAAABLQ AAAAAAABLR AAAAAAABLS AAAAAAABLT AAAAAAABLU AAAAAAABLV AAAAAAABLW AAAAAAABLX AAAAAAABLY AAAAAAABLZ AAAAAAABMA AAAAAAABMB AAAAAAABMC AAAAAAABMD AAAAAAABME AAAAAAABMF AAAAAAABMG AAAAAAABMH AAAAAAABMI AAAAAAABMJ AAAAAAABMK AAAAAAABML AAAAAAABMM AAAAAAABMN AAAAAAABMO _Toc216071423 _Toc216071424 AAAAAAAAAC AAAAAAAAAD AAAAAAAAAE AAAAAAAAAF AAAAAAAAAG AAAAAAAAAH AAAAAAAAAI AAAAAAAAAJ AAAAAAAAAK AAAAAAAAAL AAAAAAAAAM AAAAAAAAAN AAAAAAAAAO AAAAAAAAAP AAAAAAAAAQ AAAAAAAAAR AAAAAAAAAS AAAAAAAAAT AAAAAAAAAU AAAAAAAAAV AAAAAAAAAW AAAAAAAAAX AAAAAAAAAY AAAAAAAAAZ AAAAAAAABA AAAAAAAABB AAAAAAAABC AAAAAAAABD AAAAAAAABE _Toc216071425 _Toc216071426 _Toc216071427 AAAAAAAAFU AAAAAAAAFW _Ref185314205 AAAAAAAAFX AAAAAAAAFY AAAAAAAAFZ AAAAAAAAGA AAAAAAAAGB AAAAAAAAGC AAAAAAAAGD AAAAAAAAGE AAAAAAAAGF AAAAAAAAGG AAAAAAAAGH AAAAAAAAGI AAAAAAAAGJ AAAAAAAAGK AAAAAAAAGL AAAAAAAAGM AAAAAAAAGN AAAAAAAAGO AAAAAAAAGP AAAAAAAAGQ AAAAAAAAGR AAAAAAAAGS AAAAAAAAGT AAAAAAAAGU AAAAAAAAGV _Ref207680839 _Toc216071428 _Toc216071429 _Toc216071430 _Toc184484920 _Toc216071431 _Ref47451048 _Hlt47451059 _Toc184484921 _Toc216071432 _Hlt153795123 _Hlt153795208 _Hlt153795243 _Toc184484922 _Toc216071433ýZ?ƒƒ!        ßÅ#/$÷144æ5™8G<”F=OéRX¬[Še}j"mÂoq{ò‚ò‚]Œ]Œ**¦¦|š:œµŸÌŸÌŸ³£9¦9¦¨¬¨¬¨¬…·¥ÁÒÙÚ†ÚDÜDÜDÜDÜœäååíê†ìnó$û%û;Õ å óeËŠ!§! 2ä2(5¯7û<~>¯@]BìC˜EÃGI¨JÀO RVuYõYã[-_8b×ißk¤nÙrÓuExI~°€cz‡ ˆÅŠw`’^–µ—ß™Z›(LŸî¡D£†¥9§'©e«6®T¯‘±¶‡¶¸¼½½³¿ã¿5ÀdÀ„ÀàÀÁXÁªÁ ÂgÂÍÂ?ÛÃÄsÄ«ÄÅ}ÅÃÅÆjƯÆ߯mÇ ÈLÈÈÈTÉVÉxÉCÙCÚ8Û8ÛÝCßÜà÷âNå­çzê¿ìáîäñ«ó´õøÜúoüÂþ;çä%Ë ´ l¢[[°©D«K«KLLLLÜLêLîLRR¯`@@@@@  !"#$%&'(*)@+,-./01@2345687@9:;<=>@A?BCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­Ç®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÈÉÊËÌÍÏÎÐÑÒ@Ó@Ô@ÕÖþZ@„„"€        ##çã#M$ 2446¹8V<¤FOOûR§X¾[že–j7mÕo&q{ƒƒ]ŒFFFÒÒ£šXœ¶ŸãŸ ¾£J¦J¦¨¬×¬×¬•·ºÁÝÙJÚ§ÚDÜSÜSÜ\Üåååë¦ì†ó8û8ûMã ÿ  }ã¥!¸!!2ä2(5¯7û<~>¯@]BìC˜EÃGI¨JÀO RVuYõYã[-_8b×ißk¤nÙrÓuExI~°€cz‡ ˆÅŠw`’^–µ—ß™Z›(LŸî¡D£†¥9§'©e«6®T¯‘±¶‡¶¸¼½K½³¿ã¿5ÀdÀ„ÀàÀÁXÁªÁ ÂgÂÍÂ?ÛÃÄsÄ«ÄÅ}ÅÃÅÆjƯÆ߯mÇ ÈLÈÈÈTÉwÉ—É`ÙCÚ8ÛÝCßÜà÷âNå­çzê¿ìáîäñ«ó´õøÜúoüÂþ;çä%Ë ´ l¢ŠŠŠåçD¶K¶KL/L/L/LÝLëLïL#R#R¯`bcÊÌÍÐÔÕ3W    N N ^  Œ ­ Ä å (Np…§½ß÷3Uu—±Óï2Tq“®Ðä@g‰ªÌþ Mo•·Êì'`‚œ¾Ûý /MoŒ®Éë3QsŒ®Æèû=_}Ÿ½ßý?axš¶ØÙÛúOq˜ºá(J¡ÞFhy›µ×ò##K“Å#ã#/$M$5&f&õ(ö(k3k3Š3Š3D8Q8™8¹8µ†ˆ‡‰‰‰‰¶Œ)–œ¶œzŸÂŸÝ©ý©Ÿª¿ªÉ¹ºËºëº:¼^¼ Î;ÎÚJÚ‡Ú§Úœäå.ì/ìfûtû üü@üAüDüDüYüYü’ü“üžþžþòþóþ2ÿ3ÿ6ÿ6ÿKÿKÿ—ÿ˜ÿyz%%Õ:ÉÊËËå E!F!G!H!H!"xR˜R*[+[+[0[<[=[=[?[G[J[K[¨[¿\À\¬`¯`ÿÿ Beat ForsterFD:\projects\SySync\Docs\Manuals\SySyncAPI Specification\SDK_manual.doc Beat ForsterFD:\projects\SySync\Docs\Manuals\SySyncAPI Specification\SDK_manual.doc Beat ForsterFD:\projects\SySync\Docs\Manuals\SySyncAPI Specification\SDK_manual.doc Beat ForsterFD:\projects\SySync\Docs\Manuals\SySyncAPI Specification\SDK_manual.doc Beat ForsterFD:\projects\SySync\Docs\Manuals\SySyncAPI Specification\SDK_manual.doc Beat ForsterFD:\projects\SySync\Docs\Manuals\SySyncAPI Specification\SDK_manual.doc Beat ForsterVC:\DOKUME~1\BEATFO~1\LOKALE~1\Temp\AutoWiederherstellen-Speicherung von SDK_manual.asd Beat ForsterVC:\DOKUME~1\BEATFO~1\LOKALE~1\Temp\AutoWiederherstellen-Speicherung von SDK_manual.asd Beat ForsterVC:\DOKUME~1\BEATFO~1\LOKALE~1\Temp\AutoWiederherstellen-Speicherung von SDK_manual.asd Beat ForsterVC:\DOKUME~1\BEATFO~1\LOKALE~1\Temp\AutoWiederherstellen-Speicherung von SDK_manual.asd×|ÿÿÿÔè,kRÿÿÿÿÿÿÿÿ}ÿÿÿª°˜Qÿÿÿÿÿÿÿÿ~ÿÿÿ Ú¢¾PÿÿÿÿÿÿÿÿÿÿÿZüNOÿÿÿÿÿÿÿÿ€ÿÿÿìÄf­1ÿÿÿÿÿÿÿÿÿÿÿ¨­F 0ÿÿÿÿÿÿÿÿ‚ÿÿÿA>/ÿÿÿÿÿÿÿÿƒÿÿÿ(`¨Ð.ÿÿÿÿÿÿÿÿˆÿÿÿŽÂ–?Nÿÿÿÿÿÿÿÿ‰ÿÿÿÔi´äÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿbÆ‚ÿÿÿÿÿ„{êÿ€~ÆP˜>kÿÿÿÿÿÿÿÿÿõ>ôJQlWÿBûÿ D¢‰Ì\ÿÏCÀÿ³ÙÿyÔÿX@Æî\ÿX Vÿ¦­V†&ÿO ”õnJÿÿÿÿÿÿÿÿÿ8¶ cÆÿvEâ ÿ7B rHä¯ÿÆ'` †нÿN* ÿÿÿÿÿÿÿÿÿó6í ÿžLþ ÿ5DG ÿÎP© ÿør@ ÿ>¸ ÿ‰W(òC^Ðÿÿÿÿÿÿÿÿÿ &>ÿKÿÂ~í¶ÿ-z2âšÿ=8èŠNàÿ›`âš•ÿ£Vv–Sæ£ÿ8 ܪ°ÿÿÿÿÿÿÿÿÿTedÿ zRæ¿ÿØ]‚vü>íÿ¿ÿÕpÉÿ[plˆf¤FÿÌ)Æî\ÿØH„ÿG=¢ KŠÿÿÿÿÿÿÿÿÿ®\âÿ`tmÿyQ¼ÿ[3ÿPEÿ¥u¡ÿMIÕÿ•ÿ—Vê”wÿTK3!2ž‘ÿÜ+¾!ˆf¤FbMî!ÿt7#n âÿâ$@J\ÿð2+$ˆf¤FÿŠoÀ%ÿ¹Wz&,ZlRÿÿÿÿÿÿÿÿÿzU„&ÿ Ö&¢f¢‹ÿÿÿÿÿÿÿÿÿ)&'ˆ&^Ÿ±]]'ÿ½sô'ÿA(5(ÿ}1þ)2à<ÿt#ž*ÿ@+ÿÃ7C,pعÿ=³,ÿšB- ,ŒÿÎ-ÿF>A.üw²¦ÿÿÿÿÿÿÿÿÿEr.Ê¡ ºÿ%./ÿ¾c|/ÿùkž/Æî\ÿT î/ÿünû/ÿÁYÍ0àXP/ÿÖ1ÿOo<2ÿAä2ÿe"3ˆf¤Fÿ"£4ä2þÿ[t"6{¾;ÿÿÿÿÿÿÿÿÿ¿#6"O²ÿˆ[6¤ú9ÿ¿$•6ÿàÁ7ÿ(C8Ü(ŽÿAZ£9ÿK¿9ÿÔ$z:ÿrn*;ÿŠ+±;òÐðž‘ÿÿÿÿÿÿÿÿþs/=ÿŸu¥>Þ{Šÿÿÿÿÿÿÿÿÿ¿-B|:ø‘ÿGÿ§jæHõ¢ÿÿÿÿÿÿÿÿÿ–z-IÞ{Šÿÿÿÿÿÿÿÿÿg1K@âT÷ÿR2oK®°tªÿ[¥N~Ôvÿ¾DäN|g…ÿÿÿÿÿÿÿÿÿL;KOˆf¤Fÿ¹A˜Oÿ|lTPÿ·)\PÿûPx ôUÿÿÿÿÿÿÿÿÿ¬VQœ–FÿÛ/eRÿ y¾Rÿ SÿÏfS¢Ëü´ÿÿÿÿÿÿÿÿÿ2×S–ýžÿ†FUÚ’8§ÿÿÿÿÿÿÿÿÿz:%Uÿû=MUˆ1ôÿ°ÎUÿ‹%ÖVÿ+HÞVâæ®…ÿ¨OWÿðQnW¸—"ÿ?D~Wÿ:¶Wÿ˜MúWÿ¢VaXÿYÿ.Y*¶&ÿÿÿÿÿÿÿÿÿt~ÎYÿm )Z‰þ$ÿv<ÀZÿWU[tIŽÿv[ÿQv«[`âš•ÿŽRÜ[Ü(Žÿ³è\ÿÿÿÿÿÿÿÿÿóK ]ø¦#ÿbi]ècFFÿÿÿÿÿÿÿÿÿïu1]ÿ%K^Û,pÿ·V”`ÿ%ª`è`”Oƒ{u!a®°Lÿÿh5#aÿÿÿÿÿÿÿÿÿ~%aÿ¯2saÿ*]æbÿ·dÿLKQdÿïd*ðŒÊÿÿÿÿÿÿÿÿÿ YeàØˆËÿp8¹eÿHfÿIfÿ¸]§fÿS7½fÿ´!hÿŒJiŠ ­ÿ£!wjÔNÿÏ|ájÿü.–k £ˆËÿüuèk;œ0ÿÿÿÿÿÿÿÿÿÊ#ýk"NFÿÿÿÿÿÿÿÿÿQúlÿZD nÿ«M®nÿâI6oÿéZoÿåCçoÿ†~Ëpÿy5ëpÿâF£qô¨—ÿzFÈq¾ˆ£žØäqÜ(ŽÿÜdtä2þÿÈ @tv¼½ÿÿÿÿÿÿÿÿÿphvÿ_µv”)|â ÿÿÿÿÿÿÿÿɾw@J\ÿiD1xâëšÿÄõxÿØw&yÿ¨D·yÿøKãyÿ×Xäz*/JL %ùzÿ½w´{ÿú4~ÿô/~ÿÅn~ÿõ/¡~@J\ÿ‘ÿÁK ÿä^?ÿ²q{:1ÿÿÿÿÿÿÿÿÿÐ:Êvˆ^vÿ„Ô„˜þÆÔ^„Ô`„˜þ.„¹„˜þƹ^„¹`„˜þ.„ž„˜þÆž^„ž`„˜þ.„ƒ„˜þƃ^„ƒ`„˜þ. „Ô„˜þÆÔ^„Ô`„˜þOJQJo(·ð „¹„˜þƹ^„¹`„˜þOJQJo(·ð „ž„˜þÆž^„ž`„˜þOJQJo(·ð „ƒ„˜þƃ^„ƒ`„˜þOJQJo(·ð„h„˜þÆh^„h`„˜þ. „h„˜þÆh^„h`„˜þOJQJo(·ð„h„˜þÆh^„h`„˜þ.„„PþÆ8^„`„Pþ..„È„þÆ^„È`„þ...„À„xýÆØ ^„À`„xý.... „¸„èüƨ ^„¸`„èü ..... „° „XüÆx^„° `„Xü ...... „¨ „ÈûÆà^„¨ `„Èû....... „ „8ûư^„ `„8û........ „à„`úÆ€^„à`„`ú......... „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð„h„˜þÆh^„h`„˜þ. „h„˜þÆh^„h`„˜þOJQJo(·ðh„Є˜þÆÐ^„Ð`„˜þ.h„ „˜þÆ ^„ `„˜þ.’h„p„LÿÆp^„p`„Lÿ.h„@ „˜þÆ@ ^„@ `„˜þ.h„„˜þÆ^„`„˜þ.’h„à„LÿÆà^„à`„Lÿ.h„°„˜þư^„°`„˜þ.h„€„˜þÆ€^„€`„˜þ.’h„P„LÿÆP^„P`„Lÿ. „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð„h„˜þÆh^„h`„˜þ. „h„˜þÆh^„h`„˜þOJQJo(·ð„h„˜þÆh^„h`„˜þ. „h„˜þÆh^„h`„˜þOJQJo( ð „h„˜þÆhOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ðh„Є˜þÆÐ^„Ð`„˜þOJQJo(‡hˆH·ðh„ „˜þÆ ^„ `„˜þOJQJo(‡hˆHoh„p„˜þÆp^„p`„˜þOJ QJ o(‡hˆH§ðh„@ „˜þÆ@ ^„@ `„˜þOJQJo(‡hˆH·ðh„„˜þÆ^„`„˜þOJQJo(‡hˆHoh„à„˜þÆà^„à`„˜þOJ QJ o(‡hˆH§ðh„°„˜þư^„°`„˜þOJQJo(‡hˆH·ðh„€„˜þÆ€^„€`„˜þOJQJo(‡hˆHoh„P„˜þÆP^„P`„˜þOJ QJ o(‡hˆH§ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo( ð„h„˜þÆh^„h`„˜þo() „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð„h„˜þÆh^„h`„˜þ. „h„˜þÆh^„h`„˜þOJQJo(·ð„h„˜þÆh^„h`„˜þ.„h„˜þÆh^„h`„˜þ.„„èùÆ^„`„èù5o( „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo( ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo( ðh „h„˜þÆh^„h`„˜þOJQJo(·ðh „8„˜þÆ8^„8`„˜þOJQJo(oh „„˜þÆ^„`„˜þOJ QJ o(§ðh „Ø „˜þÆØ ^„Ø `„˜þOJQJo(·ðh „¨ „˜þƨ ^„¨ `„˜þOJQJo(oh „x„˜þÆx^„x`„˜þOJ QJ o(§ðh „H„˜þÆH^„H`„˜þOJQJo(·ðh „„˜þÆ^„`„˜þOJQJo(oh „脘þÆè^„è`„˜þOJ QJ o(§ð„h„˜þÆh^„h`„˜þ. „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo( ð„h„˜þÆh^„h`„˜þ.h „h„˜þÆh^„h`„˜þOJQJo(·ðh „8„˜þÆ8^„8`„˜þOJQJo(oh „„˜þÆ^„`„˜þOJ QJ o(§ðh „Ø „˜þÆØ ^„Ø `„˜þOJQJo(·ðh „¨ „˜þƨ ^„¨ `„˜þOJQJo(oh „x„˜þÆx^„x`„˜þOJ QJ o(§ðh „H„˜þÆH^„H`„˜þOJQJo(·ðh „„˜þÆ^„`„˜þOJQJo(oh „脘þÆè^„è`„˜þOJ QJ o(§ð „h„˜þÆh^„h`„˜þOJQJo(·ð„h„˜þÆh^„h`„˜þ.„h„˜þÆh^„h`„˜þ. „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð„h„˜þÆh. „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð„¹„˜þƹ^„¹`„˜þB*CJOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð„h„˜þÆh^„h`„˜þ.h „h„˜þÆh^„h`„˜þOJQJo(·ðh „8„˜þÆ8^„8`„˜þOJQJo(oh „„˜þÆ^„`„˜þOJ QJ o(§ðh „Ø „˜þÆØ ^„Ø `„˜þOJQJo(·ðh „¨ „˜þƨ ^„¨ `„˜þOJQJo(oh „x„˜þÆx^„x`„˜þOJ QJ o(§ðh „H„˜þÆH^„H`„˜þOJQJo(·ðh „„˜þÆ^„`„˜þOJQJo(oh „脘þÆè^„è`„˜þOJ QJ o(§ð„h„˜þÆh^„h`„˜þ.„„ÈûÆ^„`„Èû5o( „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo( ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(- „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo( ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð„h„˜þÆh^„h`„˜þ. „h„˜þÆh^„h`„˜þOJQJo(·ð „„˜þÆ^„`„˜þOJQJo(-„w„‰þÆw^„w`„‰þo() „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð„h„˜þÆh^„h`„˜þB*CJOJQJo(·ð„h„˜þÆh^„h`„˜þ. „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð„h„˜þÆh^„h`„˜þ.h „h„˜þÆh^„h`„˜þOJQJo(·ðh„ „˜þÆ ^„ `„˜þ.’h„p„LÿÆp^„p`„Lÿ.h„@ „˜þÆ@ ^„@ `„˜þ.h„„˜þÆ^„`„˜þ.’h„à„LÿÆà^„à`„Lÿ.h„°„˜þư^„°`„˜þ.h„€„˜þÆ€^„€`„˜þ.’h„P„LÿÆP^„P`„Lÿ. „h„˜þÆh^„h`„˜þOJQJo(·ð „-„˜þÆ-^„-`„˜þOJQJo(·ð„ý„˜þÆý^„ý`„˜þ.‚„Í „LÿÆÍ ^„Í `„Lÿ.€„ „˜þÆ ^„ `„˜þ.€„m„˜þÆm^„m`„˜þ.‚„=„LÿÆ=^„=`„Lÿ.€„ „˜þÆ ^„ `„˜þ.€„Ý„˜þÆÝ^„Ý`„˜þ.‚„­„LÿÆ­^„­`„Lÿ. „h„˜þÆh^„h`„˜þOJQJo( ð„h„˜þÆh^„h`„˜þ.h „h„˜þÆh^„h`„˜þOJQJo(·ðh „8„˜þÆ8^„8`„˜þOJQJo(oh „„˜þÆ^„`„˜þOJ QJ o(§ðh „Ø „˜þÆØ ^„Ø `„˜þOJQJo(·ðh „¨ „˜þƨ ^„¨ `„˜þOJQJo(oh „x„˜þÆx^„x`„˜þOJ QJ o(§ðh „H„˜þÆH^„H`„˜þOJQJo(·ðh „„˜þÆ^„`„˜þOJQJo(oh „脘þÆè^„è`„˜þOJ QJ o(§ð„Є˜þÆÐ^„Ð`„˜þ.„ „˜þÆ ^„ `„˜þ.‚„p„LÿÆp^„p`„Lÿ.€„@ „˜þÆ@ ^„@ `„˜þ.€„„˜þÆ^„`„˜þ.‚„à„LÿÆà^„à`„Lÿ.€„°„˜þư^„°`„˜þ.€„€„˜þÆ€^„€`„˜þ.‚„P„LÿÆP^„P`„Lÿ. „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ðh„Є˜þÆÐ^„Ð`„˜þ.h„ „˜þÆ ^„ `„˜þ.’h„p„LÿÆp^„p`„Lÿ.h„@ „˜þÆ@ ^„@ `„˜þ.h„„˜þÆ^„`„˜þ.’h„à„LÿÆà^„à`„Lÿ.h„°„˜þư^„°`„˜þ.h„€„˜þÆ€^„€`„˜þ.’h„P„LÿÆP^„P`„Lÿ. „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð„h„˜þÆh^„h`„˜þ. „h„˜þÆh^„h`„˜þOJQJo(·ðh„Є˜þÆÐ^„Ð`„˜þOJQJo(‡hˆH·ðh„ „˜þÆ ^„ `„˜þOJQJo(‡hˆHoh„p„˜þÆp^„p`„˜þOJ QJ o(‡hˆH§ðh„@ „˜þÆ@ ^„@ `„˜þOJQJo(‡hˆH·ðh„„˜þÆ^„`„˜þOJQJo(‡hˆHoh„à„˜þÆà^„à`„˜þOJ QJ o(‡hˆH§ðh„°„˜þư^„°`„˜þOJQJo(‡hˆH·ðh„€„˜þÆ€^„€`„˜þOJQJo(‡hˆHoh„P„˜þÆP^„P`„˜þOJ QJ o(‡hˆH§ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆhOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð„Á„?ýÆÁ^„Á`„?ýo() „h„˜þÆh^„h`„˜þOJQJo( ð „h„˜þÆh^„h`„˜þOJQJo(- „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð„h„˜þÆh^„h`„˜þ. „h„˜þÆh^„h`„˜þOJQJo( ð„h„˜þÆh^„h`„˜þ. „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð„h„˜þÆh^„h`„˜þ. „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ðh „Є˜þÆÐ^„Ð`„˜þOJQJo(·ðh „ „˜þÆ ^„ `„˜þOJQJo(oh „p„˜þÆp^„p`„˜þOJ QJ o(§ðh „@ „˜þÆ@ ^„@ `„˜þOJQJo(·ðh „„˜þÆ^„`„˜þOJQJo(oh „à„˜þÆà^„à`„˜þOJ QJ o(§ðh „°„˜þư^„°`„˜þOJQJo(·ðh „€„˜þÆ€^„€`„˜þOJQJo(oh „P„˜þÆP^„P`„˜þOJ QJ o(§ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð„h„˜þÆh^„h`„˜þB*CJOJQJo(·ð„h„˜þÆh^„h`„˜þo() „h„˜þÆh^„h`„˜þOJQJo(·ðh„Є˜þÆÐ^„Ð`„˜þ.h„ „˜þÆ ^„ `„˜þ.’h„p„LÿÆp^„p`„Lÿ.h„@ „˜þÆ@ ^„@ `„˜þ.h„„˜þÆ^„`„˜þ.’h„à„LÿÆà^„à`„Lÿ.h„°„˜þư^„°`„˜þ.h„€„˜þÆ€^„€`„˜þ.’h„P„LÿÆP^„P`„Lÿ. „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð„h„˜þÆh^„h`„˜þ. „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo( ð„h„˜þÆho() „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ðh „Є˜þÆÐ^„Ð`„˜þOJQJo(·ðh „ „˜þÆ ^„ `„˜þOJQJo(oh „p„˜þÆp^„p`„˜þOJ QJ o(§ðh „@ „˜þÆ@ ^„@ `„˜þOJQJo(·ðh „„˜þÆ^„`„˜þOJQJo(oh „à„˜þÆà^„à`„˜þOJ QJ o(§ðh „°„˜þư^„°`„˜þOJQJo(·ðh „€„˜þÆ€^„€`„˜þOJQJo(oh „P„˜þÆP^„P`„˜þOJ QJ o(§ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð„h„˜þÆh^„h`„˜þ. „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð„h„˜þÆh^„h`„˜þ. „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ðh „h„˜þÆh^„h`„˜þOJQJo(·ðh „8„˜þÆ8^„8`„˜þOJQJo(oh „„˜þÆ^„`„˜þOJ QJ o(§ðh „Ø „˜þÆØ ^„Ø `„˜þOJQJo(·ðh „¨ „˜þƨ ^„¨ `„˜þOJQJo(oh „x„˜þÆx^„x`„˜þOJ QJ o(§ðh „H„˜þÆH^„H`„˜þOJQJo(·ðh „„˜þÆ^„`„˜þOJQJo(oh „脘þÆè^„è`„˜þOJ QJ o(§ðh „Є˜þÆÐ^„Ð`„˜þOJQJo(·ðh „ „˜þÆ ^„ `„˜þOJQJo(oh „p„˜þÆp^„p`„˜þOJ QJ o(§ðh „@ „˜þÆ@ ^„@ `„˜þOJQJo(·ðh „„˜þÆ^„`„˜þOJQJo(oh „à„˜þÆà^„à`„˜þOJ QJ o(§ðh „°„˜þư^„°`„˜þOJQJo(·ðh „€„˜þÆ€^„€`„˜þOJQJo(oh „P„˜þÆP^„P`„˜þOJ QJ o(§ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð„h„˜þÆh^„h`„˜þ. „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð„h„˜þÆh^„h`„˜þ. „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð„h„˜þÆh^„h`„˜þB*CJOJQJo(·ð „„˜þÆ^„`„˜þOJQJo(-h„h„˜þÆh^„h`„˜þ.h„8„˜þÆ8^„8`„˜þ.’h„„LÿÆ^„`„Lÿ.h„Ø „˜þÆØ ^„Ø `„˜þ.h„¨ „˜þƨ ^„¨ `„˜þ.’h„x„LÿÆx^„x`„Lÿ.h„H„˜þÆH^„H`„˜þ.h„„˜þÆ^„`„˜þ.’h„è„LÿÆè^„è`„Lÿ. „h„˜þÆh^„h`„˜þOJQJo(·ðh „h„˜þÆh^„h`„˜þOJQJo(·ðh „8„˜þÆ8^„8`„˜þOJQJo(oh „„˜þÆ^„`„˜þOJ QJ o(§ðh „Ø „˜þÆØ ^„Ø `„˜þOJQJo(·ðh „¨ „˜þƨ ^„¨ `„˜þOJQJo(oh „x„˜þÆx^„x`„˜þOJ QJ o(§ðh „H„˜þÆH^„H`„˜þOJQJo(·ðh „„˜þÆ^„`„˜þOJQJo(oh „脘þÆè^„è`„˜þOJ QJ o(§ð„¹„˜þƹ^„¹`„˜þB*CJOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð„h„˜þÆh^„h`„˜þ.„„^„`„.„„^„`„.„„^„`„..„„^„`„... „„^„`„ .... „€„€ûÆ€^„€`„€û ..... „„ðúÆØ ^„`„ðú ...... „ „`úÆ ^„ `„`ú....... „0„ÐùÆ0^„0`„Ðù........ „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð„¹„˜þƹ^„¹`„˜þB*CJOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ðh „Є˜þÆÐ^„Ð`„˜þOJQJo(·ðh „ „˜þÆ ^„ `„˜þOJQJo(oh „p„˜þÆp^„p`„˜þOJ QJ o(§ðh „@ „˜þÆ@ ^„@ `„˜þOJQJo(·ðh „„˜þÆ^„`„˜þOJQJo(oh „à„˜þÆà^„à`„˜þOJ QJ o(§ðh „°„˜þư^„°`„˜þOJQJo(·ðh „€„˜þÆ€^„€`„˜þOJQJo(oh „P„˜þÆP^„P`„˜þOJ QJ o(§ð „h„˜þÆh^„h`„˜þOJQJo(·ðß¾DäNbi]‰ÿÿÿ‰ÿÿÿƒÿÿÿ‚ÿÿÿÿÿÿ€ÿÿÿˆÿÿÿÿÿÿ~ÿÿÿ}ÿÿÿ|ÿÿÿ?D~WYA(5(ú4~³Ùrn*;‹%ÖVÏCÀ5DG ¨OWØH„G‘ó6í |lTPyQ¼´!hÔ$z:yÔ SÏ|ájâI6oŠoÀ%·)\PŠoÀ%¿$•6þs/=àÁ7¥u¡S7½fåCço¯2sa¿%./½sô'Øw&yLKQd«M®nz:%U=³,Äõx:¶Wt#ž*¹A˜O &>Ån~PEZD nô/~¨D·yOo<2Bû%ùzünû/°ÎUéZoÖ1K>¸ Ifør@ y5ëpÛ/eR[3p8¹e~%a±]]'žLþ ÎP© ¢VaXïu1]Mî!×Xäzõ>ô DiD1xWU[7B Er.g1K—VðQnWÁYÍ0ŒJiÂâF£q[¥NÃ7C,¬VQR2oKÜ+¾!AZ£9½w´{†~Ëp†~Ëp˜MúWÕpÉ·V”`ŽRÜ[HfØäq(C8â$O ûP Ye%ª`ƒÿÿÿƒÿÿÿƒÿÿÿƒÿÿÿƒÿÿÿ Ö&ä^?vEâ phvÊ#ýkïdŠ+±;Š+±;ÁK Qúl¸]§fT î/@+`tmð2+$L;KO-ze"3û=MU zóK ])&'v<ÀZÎ-®\âv[¾c|/¿-B=8£Vv}1þ)Æ'` šB-{u!aùkž/2×S+HÞVÌ)X@Qv«[›Ø]‚zFÈq£!wjTK3!ü.–k¿#6%K^•m )Z¦­t7#8¶ Ð:ʈ[6Ted[plõ/¡~ɾwzU„&"£4K¿9„{êt~ÎYÜdt.YÈ @t–z-IŸu¥>€~ƧjæH8 üuèkG=¢²q{_µv¹Wz&‰W(ÏfS³è\N* [t"6†FU·d*]æbF>A.×Xäzh5#aX VMIÕ y¾Rÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×ÿ@€ËË<›_ËË®`P@ G‡z€ÿTimes New Roman5€Symbol3& ‡z€ÿArial?&„ ‡ŸArial Black9‡ŸGaramond71Courier?5 ‡z€ÿCourier NewA MArial-BoldMT3Times]9T?hêt?pâüBk Avenir BookCourier NewA"GenevaArial;€Wingdings"1ˆðÅ©‰KgFí¢ÑFÄãȆ•AWYñþ%PWÈéÍ!ðŠŠ´´0dÇbf+[ÿÿSDK and Plugin InterfaceReference ManualSyncML Beat Forster Beat Forsterþÿà…ŸòùOh«‘+'³Ù0¤˜¼Øð   8D ` l x„Œ”œäSDK and Plugin Interface0Reference Manualter Beat ForsterualSyncMLrync Normal.dotr Beat Forsterual149Microsoft Word 8.0r@ˆeë É@þMÊI'Â@Þ$ìzÉAWYñþÿÕÍÕœ.“—+,ù®DÕÍÕœ.“—+,ù®t0x€Œ¤¬´¼Ä ÌÔÜä ì än Synthesis AGvn %þÇbj SDK and Plugin Interface Titelt (RZ² _PID_GUID _PID_HLINKSäAN{DED6954A-ABE7-4381-8D7F-64BF75104089}A¸ra{ð>http://www.openmobilealliance.org/release_program/ds_v12.htmlBÞSySync_config_reference.pdfBÕSySync_config_reference.pdfBÆSySync_config_reference.pdft7(http://developer.apple.com/tools/xcode/_http://www.microsoft.com/?=http://www.metrowerks.com/.s http://www.pcre.org/license.txt%3http://www.sqlite.org/D\http://www.zlib.net/LT 1http://sourceforge.net/projects/syncml-ctoolkit/ &http://sourceforge.net/projects/expathttp://www.synthesis.ch/.(http://www.syncml.org/http://www.synthesis.ch/www.synthesis.ch'}* Logo-Quadrat, alleinstehen .jpg.ý*D:\Lukas\SySync\Docs\Materials\SyncML.tifb=-..\Sync Server Manual\sysync_diagram_big.jpg  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ     þÿÿÿ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòþÿÿÿôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚þÿÿÿ„…†‡ˆ‰ŠþÿÿÿŒŽ‘’þÿÿÿýÿÿÿýÿÿÿýÿÿÿýÿÿÿýÿÿÿýÿÿÿýÿÿÿýÿÿÿýÿÿÿýÿÿÿžþÿÿÿþÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿRoot Entryÿÿÿÿÿÿÿÿ ÀF`Üò•CÜÈ<Å1ìzÉ €Data ÿÿÿÿÿÿÿÿÿÿÿÿ‰¯1TableÿÿÿÿÿÿÿÿóâWordDocumentÿÿÿÿ-4SummaryInformation(ÿÿÿÿÿÿÿÿÿÿÿÿƒDocumentSummaryInformation8ÿÿÿÿÿÿÿÿ‹CompObjÿÿÿÿjObjectPoolÿÿÿÿÿÿÿÿÿÿÿÿ<Å1ìzÉ<Å1ìzÉþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿ ÿÿÿÿ ÀFMicrosoft Word-Dokument MSWordDocWord.Document.8ô9²qlibsynthesis-3.4.0.47.1/doc/SDK_manual.pdf000066400000000000000000044152231226375725500200750ustar00rootroot00000000000000%PDF-1.3 %âãÏÓ 355 0 obj << /Linearized 1 /O 357 /H [ 2110 2226 ] /L 1186451 /E 662831 /N 70 /T 1179232 >> endobj xref 355 79 0000000016 00000 n 0000001931 00000 n 0000004336 00000 n 0000004494 00000 n 0000004561 00000 n 0000004674 00000 n 0000004832 00000 n 0000005021 00000 n 0000005146 00000 n 0000005272 00000 n 0000005461 00000 n 0000005612 00000 n 0000005806 00000 n 0000006001 00000 n 0000006162 00000 n 0000006332 00000 n 0000006469 00000 n 0000006604 00000 n 0000006780 00000 n 0000006903 00000 n 0000007031 00000 n 0000007204 00000 n 0000007336 00000 n 0000007466 00000 n 0000007611 00000 n 0000007756 00000 n 0000007946 00000 n 0000008076 00000 n 0000008200 00000 n 0000008340 00000 n 0000008485 00000 n 0000008638 00000 n 0000008780 00000 n 0000008924 00000 n 0000009114 00000 n 0000009264 00000 n 0000009450 00000 n 0000009586 00000 n 0000009713 00000 n 0000009892 00000 n 0000010024 00000 n 0000010177 00000 n 0000010299 00000 n 0000010437 00000 n 0000010574 00000 n 0000010713 00000 n 0000010852 00000 n 0000010987 00000 n 0000011167 00000 n 0000011303 00000 n 0000011433 00000 n 0000011564 00000 n 0000011712 00000 n 0000011864 00000 n 0000012011 00000 n 0000012156 00000 n 0000012307 00000 n 0000012442 00000 n 0000012570 00000 n 0000012702 00000 n 0000012953 00000 n 0000013005 00000 n 0000013046 00000 n 0000013612 00000 n 0000013664 00000 n 0000013878 00000 n 0000014457 00000 n 0000015274 00000 n 0000015483 00000 n 0000048443 00000 n 0000061683 00000 n 0000064127 00000 n 0000064267 00000 n 0000065077 00000 n 0000065827 00000 n 0000096798 00000 n 0000098629 00000 n 0000002110 00000 n 0000004313 00000 n trailer << /Size 434 /Info 354 0 R /Root 356 0 R /Prev 1179221 /ID[<249cf20073e979528f301d5873119c5c><249cf20073e979528f301d5873119c5c>] >> startxref 0 %%EOF 356 0 obj << /Type /Catalog /Pages 337 0 R /Outlines 358 0 R /OpenAction [ 357 0 R /XYZ null null null ] /PageMode /UseOutlines /JT 353 0 R /PageLabels 335 0 R >> endobj 432 0 obj << /S 2443 /O 2782 /L 2798 /Filter /FlateDecode /Length 433 0 R >> stream H‰ÔV{PSWÿȃ‡!‚‹õ‘fw!†b5*vÃn:Š"+b AÐ%ò Q 2ƒWj,<Óx\…;®ÜtÐ)Ÿã uR׃ÐÑN> ˜»G§â‰ —“#¡°Š|Rc T,™p_ÅÛà?Ñ»éç¾Äšì›Áôã>¡¯£Cÿq,ž Jé?+{0ï‹ógSúOçofÄl:Â9±¯zojÊãÕòùõ~:¼FqÜ;޳-4?hˆ/½Q€3v?HºVìãͧ=iÛW8Ô+­^£<îÕ›y®#¿hGÛÝŒŸ[(t~é®=øtß<ÑPÓQ1«4ñÏùl·ÑrQo·«?·%8ìÐ+¿›ªêgÿåìîãô(i~lG¹™â»kAÄ­ÃÎM{ã?/ùXðf'OIùH-¸”T€Ïiê îµfVT­»avo ɉËùéòðS¥×’ÀãØê&«µFqŠýÅ[Q{îk÷VîsQ_øÑ’¨ñˆÛ´7|†ÙPlìþÁòðl΢ÚòêÎB'÷¦>L_qì;cždÍ­ÃühKGîk§–ò¢«”€uQÕCclçdžŒá=S…ǃûzIJZAõõ[”7,/uGöª‰Þ¦€=§3Õ­\¯Xég¨Z½gâ÷?N¨‹]ÙɪO‡ÌÊÑŠ£¦¬¡ÇÍIƒ z²nAdAѶ”þýÆÜ£wÞú¶}'ój›/‡+(ÎcÑ ‚îíÛŸ°²âè¢Zóv'ÛiT•÷Ò|¤wŸ©³‹P"îÈ6Ž–'u)(ô@Õ¢ŽÜ ·–òa^±O‹*© yÇýÕ6ƒ>äüŽ+¶Ú¯½}æ+\¡nÄÖzûÜgwð5…½.*aeîkqè§Ö²ªÃʽìç; i~qåç‡Ëp7WéÆ.D>ººlÁÓû—üY—,÷ÖîhŸÜ6{<Ø8?s$¾‰•ËLW~K2¾¼Wà? «¯©ÙÄr³”ú¼­*llЬ=•'íiÉlš;‘˜þwú's¶4eÔE»Ï™zÔßx#3-O’Xæ“ÍþM0¯°­žO•™²…êÖeAã¦xÉ)©6KéU¤jï_ ‘ŒE–ë{öîxØSô¢tWø…Ø8òJÑÀÈù³¿$ · =.Ptnºÿ»±|Ršî]vÿÝ l¥ð´ÛNÖEnj—n[òŠ—‘»ët– qcl^êþJŒAùgÍùï}›÷MYñËÏhS‡uôu™¯ê¢çåˆÝÊÊæ¤!“$=èLõõá:ºIÿru~C£lŒWxùä‹Ö¥6ž²I}ý`F[:×ú²9åÕá´jÆÜGãƒ)Ú©¡N6Û·t»ÂµaÊ€™²£+ÏÊ&{:3ëïÜæ²®ì(Úw©Þ-Ñå}iDW¤ѵìÊriBâÝþ‘«² tlεL å³¶V%Ö°çÜÑ>s·ëQž,p÷C¯¿ÅU?ÍoS¿Ó§‰²Ãݺ_ÆŽP‚^¨šÒo÷éNHÚ ÖH¦îL˜{wKRj:¿ä·6¦v]¢ëN$ˆ¾&eìÌ™(¤/2Y–U'”LRÌ_7œ;°"å±Â•]?´4+ÿûŒ­wÐçÔPyêÄä5åþ³Ÿ6u ZíöfR¿B̪¯_½\dŽ’Ý“›ëÝôi™7×ZÒ‡uDÆâʵÙ',W¡;ät@ ëÍþc(_°$"¿RÙÌ}Î+ôùŸ*ý†æ-¢Æ‡í™Ê Õ¥¦¡r¾´Eüð[çæÅ•‰Ù!~,ÕÓg]Å~¤>¬gЬ¾©–tùø“Ù㽈`ºïù%%è÷ô,))A7½qž ›ŽcØBL&Ë¡ÙâÄd«Í´éV—BÄba‹½Ôk ÂµÕØñL&“dz»˜L{/Íl×=½¸Ó11[íB.¦-´!Ú † ±HçÚRx<žX,NžÎ·â…pméd«G<í·Ñ-ûŒ6— †åèügÇxz2§y8ˆƒ£ÎItt¶Ûž<ÇH¨‡Ufˆ4wÆ@b›x6sÆ ùólKåÈDëÆã—Ìvö´­Ÿ'“â@nþA2yZÁ½ÿQLLÌ̲{zÐ cv2m!÷½Î2kàí[gO´¶Øòž=;=ù½!3õx–=õcÎpaØ·†1sìû‚rføNïš}ùQŸÿ³?4 8HY‹ž½¶Y~‹~ÃHQ0œå —0Ø„(ø ˆO \ªP™ @xÅ@À Èa ‚ ’(‡VíO@ä ýà%QŠ|D”Á›\…’Q`#­(D ¶[¡”Ö¨UD ¤Z¡$Ö@,4ð€1à à®ü\àÈ¡–ì" 9'9°8T|é/ñߊÞ 0 ¢Ëª‚“À¶àJŒáîÁü(\'øb¸ûàƒáCqhÔ+@{‚; ?µC#¸FA-Q›¤š0ÐàâÃà¢s¡ZˆÝ¸ä¢Õ@#áP4|¨ '°@‡ÓzÌ >†_ N à2)\Äø&²×ƒ§é°õ”¡gý©Fàó endstream endobj 433 0 obj 2099 endobj 357 0 obj << /Type /Page /Parent 336 0 R /Resources 414 0 R /Contents 420 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 358 0 obj << /Count 55 /First 359 0 R /Last 360 0 R >> endobj 359 0 obj << /Title (Contents) /Dest [ 13 0 R /XYZ null null null ] /Parent 358 0 R /Next 413 0 R >> endobj 360 0 obj << /Title (Error codes) /Dest [ 277 0 R /XYZ null null null ] /Parent 358 0 R /Prev 361 0 R /First 362 0 R /Last 363 0 R /Count 2 >> endobj 361 0 obj << /Title (UIApi Interface description) /Dest [ 231 0 R /XYZ null null null ] /Parent 358 0 R /Prev 364 0 R /Next 360 0 R /First 365 0 R /Last 366 0 R /Count 7 >> endobj 362 0 obj << /Title (SyncML Status Codes) /Dest [ 277 0 R /XYZ null null null ] /Parent 360 0 R /Next 363 0 R >> endobj 363 0 obj << /Title (Internal Error Codes) /Dest [ 282 0 R /XYZ null null null ] /Parent 360 0 R /Prev 362 0 R >> endobj 364 0 obj << /Title (DBApi Interface description) /Dest [ 183 0 R /XYZ null null null ] /Parent 358 0 R /Prev 372 0 R /Next 361 0 R /First 373 0 R /Last 374 0 R /Count 2 >> endobj 365 0 obj << /Title (Functions in the UI_Call_In call-in structure) /Dest [ 231 0 R /XYZ null null null ] /Parent 361 0 R /Next 367 0 R >> endobj 366 0 obj << /Title (Settings keys supported in SyncML Client Engine) /Dest [ 261 0 R /XYZ null null null ] /Parent 361 0 R /Prev 367 0 R /First 368 0 R /Last 369 0 R /Count 2 >> endobj 367 0 obj << /Title (TEngineModuleBase Class Reference) /Dest [ 234 0 R /XYZ null null null ] /Parent 361 0 R /Prev 365 0 R /Next 366 0 R /First 370 0 R /Last 371 0 R /Count 2 >> endobj 368 0 obj << /Title (Global settings keys - accessed using OpenKeyByPath\(\)) /Dest [ 261 0 R /XYZ null null null ] /Parent 366 0 R /Next 369 0 R >> endobj 369 0 obj << /Title (Session local settings/values, accessed using OpenSessionKey\(\)) /Dest [ 274 0 R /XYZ null null null ] /Parent 366 0 R /Prev 368 0 R >> endobj 370 0 obj << /Title (Public Member Function Overview) /Dest [ 234 0 R /XYZ null null null ] /Parent 367 0 R /Next 371 0 R >> endobj 371 0 obj << /Title (Member Function Documentation) /Dest [ 240 0 R /XYZ null null null ] /Parent 367 0 R /Prev 370 0 R >> endobj 372 0 obj << /Title (Change History) /Dest [ 174 0 R /XYZ null null null ] /Parent 358 0 R /Prev 375 0 R /Next 364 0 R /First 376 0 R /Last 377 0 R /Count 4 >> endobj 373 0 obj << /Title (Function overview) /Dest [ 183 0 R /XYZ null null null ] /Parent 364 0 R /Next 374 0 R >> endobj 374 0 obj << /Title (Function Documentation) /Dest [ 186 0 R /XYZ null null null ] /Parent 364 0 R /Prev 373 0 R >> endobj 375 0 obj << /Title (Setup Guide) /Dest [ 154 0 R /XYZ null null null ] /Parent 358 0 R /Prev 380 0 R /Next 372 0 R /First 381 0 R /Last 382 0 R /Count 7 >> endobj 376 0 obj << /Title (Changes since SDK V1.0.0.2) /Dest [ 174 0 R /XYZ null null null ] /Parent 372 0 R /Next 379 0 R >> endobj 377 0 obj << /Title (Changes since SDK V1.5.0) /Dest [ 180 0 R /XYZ null null null ] /Parent 372 0 R /Prev 378 0 R >> endobj 378 0 obj << /Title (Changes since SDK V1.4.0) /Dest [ 180 0 R /XYZ null null null ] /Parent 372 0 R /Prev 379 0 R /Next 377 0 R >> endobj 379 0 obj << /Title (Changes since SDK V1.3.0) /Dest [ 177 0 R /XYZ null null null ] /Parent 372 0 R /Prev 376 0 R /Next 378 0 R >> endobj 380 0 obj << /Title (SySync UIApi SDK description) /Dest [ 123 0 R /XYZ null null null ] /Parent 358 0 R /Prev 388 0 R /Next 375 0 R /First 389 0 R /Last 390 0 R /Count 8 >> endobj 381 0 obj << /Title (Plug-in System for C/C++) /Dest [ 154 0 R /XYZ null null null ] /Parent 375 0 R /Next 387 0 R >> endobj 382 0 obj << /Title (UIApi C# interface) /Dest [ 171 0 R /XYZ null null null ] /Parent 375 0 R /Prev 383 0 R >> endobj 383 0 obj << /Title (Plugin_Info program) /Dest [ 168 0 R /XYZ null null null ] /Parent 375 0 R /Prev 384 0 R /Next 382 0 R >> endobj 384 0 obj << /Title (Module naming convention) /Dest [ 162 0 R /XYZ null null null ] /Parent 375 0 R /Prev 385 0 R /Next 383 0 R >> endobj 385 0 obj << /Title (Plug-in module XML configuration) /Dest [ 162 0 R /XYZ null null null ] /Parent 375 0 R /Prev 386 0 R /Next 384 0 R >> endobj 386 0 obj << /Title (Plug-in System for C#) /Dest [ 159 0 R /XYZ null null null ] /Parent 375 0 R /Prev 387 0 R /Next 385 0 R >> endobj 387 0 obj << /Title (Plug-in System for Java) /Dest [ 159 0 R /XYZ null null null ] /Parent 375 0 R /Prev 381 0 R /Next 386 0 R >> endobj 388 0 obj << /Title (SySync DBApi SDK description) /Dest [ 92 0 R /XYZ null null null ] /Parent 358 0 R /Prev 397 0 R /Next 380 0 R /First 398 0 R /Last 399 0 R /Count 14 >> endobj 389 0 obj << /Title (Connecting the SyncML core library via UIApi) /Dest [ 123 0 R /XYZ null null null ] /Parent 380 0 R /Next 390 0 R >> endobj 390 0 obj << /Title (Using a SyncML Client Library via UIApi) /Dest [ 126 0 R /XYZ null null null ] /Parent 380 0 R /Prev 389 0 R /First 391 0 R /Last 392 0 R /Count 6 >> endobj 391 0 obj << /Title (Preparation for initialisation) /Dest [ 126 0 R /XYZ null null null ] /Parent 390 0 R /Next 394 0 R >> endobj 392 0 obj << /Title (Running Sync Sessions) /Dest [ 145 0 R /XYZ null null null ] /Parent 390 0 R /Prev 393 0 R >> endobj 393 0 obj << /Title (Acessing Settings) /Dest [ 131 0 R /XYZ null null null ] /Parent 390 0 R /Prev 394 0 R /Next 392 0 R /First 395 0 R /Last 396 0 R /Count 2 >> endobj 394 0 obj << /Title (Engine Init) /Dest [ 131 0 R /XYZ null null null ] /Parent 390 0 R /Prev 391 0 R /Next 393 0 R >> endobj 395 0 obj << /Title (Preparations before accessing settings profiles) /Dest [ 134 0 R /XYZ null null null ] /Parent 393 0 R /Next 396 0 R >> endobj 396 0 obj << /Title (Editing Settings) /Dest [ 139 0 R /XYZ null null null ] /Parent 393 0 R /Prev 395 0 R >> endobj 397 0 obj << /Title (Distribution Files) /Dest [ 86 0 R /XYZ null null null ] /Parent 358 0 R /Prev 412 0 R /Next 388 0 R >> endobj 398 0 obj << /Title (How to write a database plugin ?) /Dest [ 92 0 R /XYZ null null null ] /Parent 388 0 R /Next 411 0 R >> endobj 399 0 obj << /Title (The OceanBlue / SnowWhite adapter) /Dest [ 120 0 R /XYZ null null null ] /Parent 388 0 R /Prev 400 0 R >> endobj 400 0 obj << /Title (The global context) /Dest [ 117 0 R /XYZ null null null ] /Parent 388 0 R /Prev 401 0 R /Next 399 0 R >> endobj 401 0 obj << /Title (Callback calls) /Dest [ 114 0 R /XYZ null null null ] /Parent 388 0 R /Prev 402 0 R /Next 400 0 R >> endobj 402 0 obj << /Title (Datastore Handling) /Dest [ 102 0 R /XYZ null null null ] /Parent 388 0 R /Prev 403 0 R /Next 401 0 R /First 404 0 R /Last 405 0 R /Count 7 >> endobj 403 0 obj << /Title (Session Handling) /Dest [ 96 0 R /XYZ null null null ] /Parent 388 0 R /Prev 411 0 R /Next 402 0 R >> endobj 404 0 obj << /Title (The \215open\216 section) /Dest [ 102 0 R /XYZ null null null ] /Parent 402 0 R /Next 410 0 R >> endobj 405 0 obj << /Title (The \215close\216 section) /Dest [ 114 0 R /XYZ null null null ] /Parent 402 0 R /Prev 406 0 R >> endobj 406 0 obj << /Title (The \215general\216 section) /Dest [ 111 0 R /XYZ null null null ] /Parent 402 0 R /Prev 407 0 R /Next 405 0 R >> endobj 407 0 obj << /Title (The \215admin write\216 section) /Dest [ 111 0 R /XYZ null null null ] /Parent 402 0 R /Prev 408 0 R /Next 406 0 R >> endobj 408 0 obj << /Title (The \215update\216 section) /Dest [ 108 0 R /XYZ null null null ] /Parent 402 0 R /Prev 409 0 R /Next 407 0 R >> endobj 409 0 obj << /Title (The \215read\216 section) /Dest [ 105 0 R /XYZ null null null ] /Parent 402 0 R /Prev 410 0 R /Next 408 0 R >> endobj 410 0 obj << /Title (The \215admin read\216 section) /Dest [ 105 0 R /XYZ null null null ] /Parent 402 0 R /Prev 404 0 R /Next 409 0 R >> endobj 411 0 obj << /Title (Module Handling) /Dest [ 92 0 R /XYZ null null null ] /Parent 388 0 R /Prev 398 0 R /Next 403 0 R >> endobj 412 0 obj << /Title (Overview) /Dest [ 78 0 R /XYZ null null null ] /Parent 358 0 R /Prev 413 0 R /Next 397 0 R >> endobj 413 0 obj << /Title (Introduction) /Dest [ 73 0 R /XYZ null null null ] /Parent 358 0 R /Prev 359 0 R /Next 412 0 R >> endobj 414 0 obj << /ProcSet [ /PDF /Text /ImageC /ImageI ] /Font << /TT2 417 0 R /TT4 421 0 R >> /XObject << /Im1 429 0 R /Im2 430 0 R /Im3 431 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R /Cs10 415 0 R /Cs11 418 0 R >> >> endobj 415 0 obj [ /Indexed 416 0 R 219 428 0 R ] endobj 416 0 obj [ /ICCBased 425 0 R ] endobj 417 0 obj << /Type /Font /Subtype /TrueType /FirstChar 32 /LastChar 148 /Widths [ 333 0 0 660 0 0 0 0 389 389 0 660 333 333 333 278 667 667 667 667 667 667 667 667 667 667 0 0 0 0 0 611 0 778 778 778 778 722 667 833 833 389 667 833 667 944 0 833 722 833 778 722 722 833 778 1000 778 0 0 0 0 0 0 500 0 667 667 667 667 667 389 667 667 333 0 667 333 1000 667 667 667 0 444 611 444 667 611 944 667 611 556 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 500 500 ] /Encoding /WinAnsiEncoding /BaseFont /BAALCP+Arial-Black /FontDescriptor 419 0 R >> endobj 418 0 obj [ /Indexed 416 0 R 239 427 0 R ] endobj 419 0 obj << /Type /FontDescriptor /Ascent 1100 /CapHeight 0 /Descent -309 /Flags 32 /FontBBox [ -194 -307 1688 1083 ] /FontName /BAALCP+Arial-Black /ItalicAngle 0 /StemV 0 /FontFile2 424 0 R >> endobj 420 0 obj << /Length 504 /Filter /FlateDecode >> stream H‰lSËnÛ0¼ó+ö(´æ."mIQ m_ŠTUN $2l%(òIýË.Eù¢0@-áÝÙÑÌhuû@ð8©ƒ"6ÈŒüÈ2¦lôlv¢qÐ?«ÕÝ3Áz¯¾¨÷­Zµ-A»U2lÊp©(l‚ÌúFîÑXheöáŸæ6S?ªZþ4ÄÐö*WÒõ[}«¾jf¤jÐ$çVSÀf¹uM]5ŒýŸºñµ{‚¥a¿4|oïUmÑŸ ïh×Ë&:mâTV=¬?B7þøüôú¸án|Ž‚h0VìØn+ôÈ3òM«v ˆZ&ð" `}© &d8j›ÅùW’èe¯(â¢ÍjΊd*&žHQá:œÏËq]Îÿuí·ºöI”€—_Ìœ=Z"—É9ÓðYŒË^‹o£ M» ¤ê3ÜÍ(¢ 3ŠÁ\¸F1gÞ±ÌoDvXÁÆêˆ¶Bºª‹z’Wò"žÏIcàÐç¤8c‘] A;/(ØlêûN×®µ©j6&ü8¨¦A 3^#6Hp³9¸òÞ2N .—àÄÎ}Å/n¥ >ÊH è.Q·ç¨_&ÆhæÏ¾ò1dºõ©,Nþ‘‚VçG‚o0kœó•$Ò’ÏTMZ ªvZ&Ýrw·§·û+ÀUùÆo endstream endobj 421 0 obj << /Type /Font /Subtype /TrueType /FirstChar 32 /LastChar 252 /Widths [ 250 219 406 667 0 0 729 177 292 292 427 667 219 313 219 500 469 469 469 469 469 469 469 469 469 469 219 219 667 667 667 0 0 677 615 635 771 656 563 771 760 354 333 740 573 833 771 781 563 771 625 479 615 708 677 885 698 656 656 271 500 271 0 500 0 406 510 417 500 417 323 448 510 229 229 469 229 771 510 510 510 490 333 365 292 490 469 667 458 417 427 0 0 0 0 0 0 0 219 0 448 0 0 0 0 0 0 0 0 0 0 0 0 0 219 448 0 0 500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 760 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 490 ] /Encoding /WinAnsiEncoding /BaseFont /BAALMN+Garamond /FontDescriptor 422 0 R >> endobj 422 0 obj << /Type /FontDescriptor /Ascent 861 /CapHeight 0 /Descent -263 /Flags 34 /FontBBox [ -139 -307 1063 986 ] /FontName /BAALMN+Garamond /ItalicAngle 0 /StemV 0 /FontFile2 423 0 R >> endobj 423 0 obj << /Filter /FlateDecode /Length 32868 /Length1 44520 >> stream H‰|V PT×þÎ9÷Þå!¸V°Èª¹ë$î®ø‘˜ ì"  »jÌ.EY­X“®M-í§†N¢mó0m2ÁNîªmˆ¦ é´M›š×Œt:mm31f2>&¡Q'µÂíqÀ&=‡Ÿû¿Î¿ÿqf/€D!P¹bUÞìÚŠÀYà!Ò.¯kG^¿^¼X °Wëv·ªû·®~‹l¤ÐÆÈ¦æ›7¼È…$WlÚÚ¶1«}ÖB ³8ànl׿‘é/ x™ßHŠÔe  ñ{$g56·îé¬<þ’IÕ[[êÂláárà©+$¯oï‰Ø’®Òy/ù«ÛÂÍ ŸµtŽgž‰‘–­„›ÖqɲGv4Dr¿ysF¢òë8ª›Ð,ã æùa¸fÞ"ý÷³¡Pc𿫃èÍ!ÖüŠõ%§îZ#üŽ|¥“ ý:ö!Óð8íylÜX‰Ã,÷a=~Eº\ìÀÓ˜‹× #•tãIHÈ&ý ÌÁ:Šä\ã¡o‚‹xš˜„,âæ¡ kð°•š-æóuSz;&b ¦R§QT/|”C u³›wöâ[„ùÛ´¿G}”0Ÿ@~ƒ·ñÞǸ€'¤SY.[Ì`e´«Ù¶ŽÕ³&ªý7Ø£ìëbGسì${ŸýÙBÎn°4hœ ®P™<—ßÇ—ò0e²™:õ(×i¿ÀÿÂÏó/D–˜&f‹|á‹ghâeñ Rå8GÚ'–ÎJç¤JýÒ ¬ÈºÜA{P±)ë”Ê>åiå[®m~‚†x–r½Ž"iÒ-šnðc+_Šu°ás–ÊÄE8PÁ籟Aáy4ÿ‹å2þ;\ÇY¼KÞ¥Š ;Ù ü›Õ¬šªÙÏ® À>¬HÊSöá§„:Êw‚Q§vâ5Y§»q£ Éæ‰âO8IÓßAw}›yͼJó±¦0™îk9 ¦ºƒØFÝH“_FÓz†n5Þü…ù æÎ™=kfÞ Û5ýÞÜi9ÙYÚT§zϔɓ™3¾>!=müׯÙǦ¦ŒINJL°)²$8ƒÛ¯•„T#'dH9Zi©Ç’µ0)Â#!C%UÉhC ÅÝÔÑž^òÜx—§wÈÓ{Ç“ÙÕBzܪ_S·}šÚÃÖVˆ?èÓ‚ªq5Î/‹óRN\H!Á餪?£Ñ§,¤ú’ݺ?ä£x±ä¤b­¸!ÉãF,)™ØdâŒ-c%‹Yœá%þ‚GB ¡2Ê5Ÿß(Ó|CdûÃõFeUÀïs8AÛ`ÅuZ­­È늻 8þC)6lñר›­tСÆÜ½zgµ!טz­>¼>`ˆpÐzÇ8—±DóKö~”áq÷°ŸWŒÄâ†êÀ+(7£±²¨Ï$O]øu½}´»Ç]±2à$<š¿Sµ® ı‘;ËÈ£×[:+¡T4¿¥ mQD­HkÔ·„¨ ™º•mΙåÞWÌPîWõê€æ4îwhÁ°oR, úʶ“e^µl´ÅãŽÙÇ Õ0–:ö63&e$ÓpÇçâîG¨‡‹È,DZ5ßPëTBÐ žoýkȇ^—On´‚Œjµ™*ÒíV‰ål»¦ê×A-Ö®^­ ßÖ(Ùöë°Xkî Ù‡yÃå2¦O·fÀVLM#d‹ãò<{·Q¡EìªQA%Ce€ ò¨äN§Õ¿Ž/jI0¢U!YE­ã¼y® ÁC–¥wØ’^cY¢Ã–;ÇC ê)Xß3éFBο±ö ãý›ðÌ Cvº~5&ÉÙze '¬w8rBzgZSB—L×K4µDéá3Z«©vMUTèh8¥ót‡Ã(é öP#£ºs† bŒ/qÜ!ˆ«X¥UT­ äÇû ˜rq€¾¥. ~4øŸ„ýq¨#\ænëÅË2ýZˆ.Ô(](—û°€5¡Š×à'¼Æ<'š°ˆì‘o5b)=÷ÐÇR«èE)Ñ"Ñ ¢D›‰ê‰6Y>kÉÑŠqx˜øem5ËMf¿t9AÅ… ²³¤(ÿ’Ži¼.Þm®’/£@êB²ÒT²e*^l ¿âÃ20]ôa™tÙ¼%w#›b~jK7¯È]H’½ôô¢”»ðaÞÎ]f=‹$˜×x7ޤ܋¤tL5XNúbëÉ»¢Z¤~ ë£õQü^Ì¥g½/‹ôQQ†¸ŒŠ“Mùl§zå“ì½æ5¹Æ¼$º1‰âÙ¨~óEsH`çgŒòÿ‘•wœ(o+çáœ,ü¦/%Âv7±>s`ÝmÅq¤&ú`t¡–b¬ º’ÜJµŽˆ.ó_T‡±T{¿E¶>L¡ü¬ZY3rXé3÷߯9Ëš ¢Cq¢:Ó¹<Š](Ÿ‚‹æh†ä…›ê=ÀÿËy•ÀFu]ÑûþnlmÖ*m4V¾…uÀï¼&Ñ}ç}uýF¢Ñ€Wi¤f`%ök²Ž•6B´Àžgq—[÷€×…­µ ØÿØã  xŠý%Að»€~œ*çɇ8ZÅšeݰ>Y#¬èÀ­„h¯÷Àgeüü6Æu•À| eØ?lÌâ˜aÝò:ïÚ†¾X'Yfs ;ú—Ü(Ïäý²¾îrcú†Í#ÆÚñ¢Ù¼FöÝö8»¦û±Íñåpúo¼føð½ ’áÛCݼ'öqz Þ‹8pLAÎ ›÷2þÒÙ,½bÇl!ÇÅH†?[Ô4rÕÔq>AœŒdÎ-¶vGpÖ¿YæÜÃñÏ WgÞKíx†Öÿ[¶órGöü³ÚȲ´‡gωc‘ã)³ÖEЛ‚µMávιêÛé­#= o[éueú³8—þ^6ï²TŽ1Gïóù<Øû}lÇ]&çª_EN`íó™A—êxšeï7†{g;âùVË#—ö0­ãñ\/ÿ z»C òUªçà¯Fjä:¼ï“'—|ž´Û]Nù;Ô`÷û>rëj*PÂôœ¬ÑD»ý:òØY䪴@º„òïÁÿÀ;Û¼†÷*W$仃¸£Î¥?¶ëy ˜ëì<›‹õ>ASmMóÙecºÒ˜¾®„ýçáy {·°w gȾú ¾bñØYé³lËÈ'RÓTø£ŠaÉú+ãGoû óÙ÷lªïg|¥Ãv=në6*5f£ ‘æ¹ÐžñÚ)=˜¹£Ê›‘7.šwÙ1¦Ã¿ù8ƒ&ò1䈇ëÈ?'—]ǹßáû¾X€»šÒÆCK¸›ì¶1XÇrò1”/¦ÿ®Ü±íøä/Q­VÆúì±·ñ½Às7Ú¹{›s/òtA§?Áxúò8oñz.#ïÿšl.cÎËT ,V[=€!®X…?8cVQŸHõ ô õ ÷)ÔWÞ'qIzK|(Þ¡0±ñÍÖJsÚ6³*)|Ç#‡™½o‚«_;Pˆ“²òÀÌ#æ‘È,sC¤Â¬Þ9ƒ–\+\u8RhV'¥Ë·f²¹¦­Ô¬Ú‹Õí±ylÊoMÁÉW·ò#‡bž˜T½‹ÇR±˜ÚkuÇ¢1%A{R¨‰ÍÂòXë¡H›¹ ¨ÊqGÜ›¥Ç6ó´ñH*2Š GÔ[f¡j£gãPØ%.à€/à€ O!.@%yØÛk:m䎞O®'/È äi¦^¦Kº6Õ¬rkeÚjmöSmPKkz™¶X“% :a’T`ªŠ Sa²‚f•)—É’,a`­´UzE:-]“Tš7AèóÖü@Rt$æW€¶8´Þ¡u­u¨Ð¡±ùò9äuÈåP®CšCеüg ¼ü8Ä€×€ÃÀAàð° ØlÚÍÀ ˆM¶ÝŽù6‡ZçPCcr;4Ê!Õ!Ù ‚‡€AàÀià—ÀëÀžùÞoN4­GWëÑeúD£ÄãB£Àðc Ÿá1F.c”aš¡’AHiõñÔÓT߈º$ˆ¥=±<®ëDÜWOõKë Dü¹^ª_R¯Õ㿯 ÕÇs"MÇ„øv3jãÒ·’‚–6aË\µ¯(î›Ýt*zfßóEÌÑ}Ï77ûC÷ÿ î}õ ;OBs›NèæEÝ\«£®~ ª¢\½¨Gíª‘h£¶ú§ö·L û Š1ÉÈ.s7,©Ã\MÇ ªkž½ÂáãRî(¬º¥¨¸¹ÎïiÔÞBMqÁî¢Sø³ñ冚ã®`]<à¦iáianBÀpÓhT»3M»kŠ‹N‰72MT{áOê…¨Ë^uÚeûEpYtt†B«:VeVØÕy·üï·ÑÑÙÙeSWgGúƒ:ºØXˆ:×ÙeÑIqyîú¤4vîú¸µ¿%Ήë\Q©( Î×:;ß³bs[p¿ÌÝGpν3"D‰ÿdbÏø–!¿ åVn’~SHø qƒÔòI‘À_Û;x> ÚZ<§—O÷{'{‹ú< §>·TúŒJ –v¥? Ô"ʧbjH¸dJŠ?ZÓÆ½næºç4ú‰üŠ2þ°Ûoù%ò{œGÀÖ?è¿æOûu¿?XâõÍ,[ù̶+»f–}Ý;³¬Àsë ÕÞ¾Z;½ü-XR*O.<ãáG*+üùctÉ-4=ó‚ÆÉ7G©úè€<úŸ\W}lçß{}gŸÏ¹øì‹ü•Kì|ú;±ãÄÁ‡ 8e„˜'8! *… HGICT£ ­D—ŽM¨)ˆUý¶¡–¯uUǤHÒ¤²©üQMUÙÈZukš*V&Åì9¶nwzï½÷Þç¤çžç÷û=ÏÉÑÚP\Q<ÓÝܘÌj×á(=5ò|<žHDÃ?+]¿gùScwW0Ø»<‘¨ÔôndCnÔ¡û+Œ>bÜŠdCì)¢œ’¤UˆˆÄO>&Ÿšh#àæ’¸”L‚¿I¤-¥ÄxHþë ïxJþp¶·4u¹ãxmÜIu„›’ö$QqýL³ÞÙ¥5ž(}ŠkŸs¹ÒÚÐxéàÑèÃß›þ ]Z5ò¡è/Y8› ŠfÚç­”$Æ´Êc—e‚Ý.§ÃAñV–5‹â‰‘a“Èò%Ãç[å¶VŸµÐ&Ì P å°y‹žÓ®Šª³B¥ÝÉ+ %J²ÃÌJdÌ$"ÍIÔM ‹–$™"ÄÝsµ®ä”1…(JÀ_ÎN*•ŠiJ,©MíQbHƒµ1`+e˩ԋ©Ç–å5³t¸é°¸0®2&­2ŒÍby ,<^¬\!–{Œ#æPIÀ ªÝj{ÌÞ€ac÷† ø£¡BáÖyÜUz/?¿¹®ÅD=£¢LëÇoôyªkMÄÏÓ6§}ã¶ŽmÞl Ÿ ­ûéä çûš{»±Ï:ôBO÷Æú$Þ`!Ÿ7ì=üB`ðX~çê·ÓS±Â±£Û·Nk­CéÖØ|£§Ñf¥YŽ6±6†óöýmü'ëB.Ó¨Vëœëšm9O¬sÏ…M©½ý|ƒkCÕ”¾}×±ötaù ΄­±íç;ªwŽ´õÿ6åÝe•QuŒ!.:Éêc‚ y¡ˆÁ©¥²¢üŸœ¼WÚZZ@@ Õ8Ôª®Ÿ+} Íš/Y©Úš«êvÊ.#$ 2¢ˆýŽõàÕj\­,/ÙOC¢[#ØiD²±ÄJ9Cfˆ?e¨U¥xjŒ¸æŒºm0Ú09JZ]¼c(3uÄY³~ 1™¡=Õn®~uì‡WïžÛ{󯇒QÖÅGbý³Íüjà8®=9þL/Â?)ÙðÚêÕ§'‘à‘Wp) Êqå[ÅdQ°r½ˆ°wpT˜. &$ˆ‚_ˆ9a –×…›+žÁw¦ý'ñÿ #Œ7 ø„JbÍ+œÁfŸ£§e´FkÊØÈ›×Mw2ù5ÏÆ²Ö’îµw­}å‰]?vú/†¤­‘þçJ÷f>(þ ôÙég§Û‚.ˆgþšÔÑ<ÊbF?à¤*B!.B$ÁFC=¡5€Ð|V•³Y•å"‘ù(+G£,Šô$HÈSÁªÖl Èqrw´˜ÍvÿN„"Q“šJxª:zª]R…hO›а\–FÎÔš¼Ð‘Oå]ó‚ !hÙBïVÍK0éþ9tÝD·Ñ=DGŽ(JÔCû±cFb¾Yáûò⢸(¦ Ò+å´2 ÷ÚrR+›,Âj–7Íò‡¹ ÆÆ êæ ëÿ•$V äöx¯4ÑŽ·‡m¡¸â¡ü9l¬`ª &¸À¢œ30×a® »qóØÜÕR²9‚Ì“â+’|·cŠn¨eÌ”I¶^±Û+¯N²Þ@„}ªÞÊ»Å*î¤ÜÁfÚ#ú1MÕ¿3Nݪyžå¤Õº!è?çñ2»Çc$aâuÉRáâlkÇü*7gì¢B'í4[é©eŠ|B^u#UãÅŒ,TÕ"¿2üÚeZ0½8ÔÿKDáÈ%>o¶^ý…eN˜,/cöâü\„ãns÷8ÆÏíåÎp¿à.r×¹›ðÀáæ8Š+Ç Ü"ÒÊ“Q¶¤˜åJR¥Àkøë¾[’ %™zgåFÁ_ŒÝRzC' \ƈ}[·_ï^¹Ž˜ƒNøÑ›tiÎyÎhö9:眷´óžÖ¥}6¢?¢cШQ‚ ͽì^’Œl=bG¨œ`ubECx¼Ûl“Yè«`µ×7mÜ—;WzÓÇÐÑÝ«cvMRº_-~nÄcTþú¹^=l¢)³ _”è")¢óRÑjG²9où2'Éûä£òYù¢ÌˆrN¦dm TG2”ì›2, HVÞÅ”„’ˆú°ÑÍUCÿ5Ü6Àozig,[C­ªµkc¥ë°Fá÷1M(¶Ÿ&cÎ#M?¼ƒ{ѯ!su—ÈÛ¬•?GGP¯ýˆÜ5Zœ ›sPQ(w­‘ÄwÚÃé5MÝM«ÿÍsÕÀ6qžáû¾ï~ìó]|¶cŸqì8N.±ãàØ±ÇÁ>Àÿ$Å@ÊŸø+„1 Y!I¡c0Ä€TtL£P˜ û l¢ÙÔI©Š†*´Ih¥ª´À–!4­šê&’ìýάút¾OwgË÷¼Ïû<Ï»lfk67òðøþ©gäw²@Ò(cÆ=„)%î@ËÌ cvˆ| Ë½¦*ÇzÔ¾RšBU¤qídn wî?]ÙÚ§ÿF8/àfösË¿€ ÅU n³|ƒ™bÂÆJf33$¼ÂÜbî3O™3ÌlÐÐØ /¹Ž´Á OJ† ûÝ T1Ô,-VK[%V/Lz×`í3_\½/‹À\‘i£5Ä< . Ýê^— AŠÌÓ&ö²­‰]™M7u\¼ó³–Èyäð÷¯ZÐï­íï_ÓߌðÁm'oÄ뎡ğ?@‘«íÞ<8übíÙýë^¿4õ‡©Ñé]¨ú6üÃ3Î9™FfÙ­Ë=‚ú ¹ŠKvq]Hòz妯ä¾ÍB>ª¹J`k8íò°Œ9!ò˜ÌÊrºÉÌŠ½ã“zÁÔ((¤ªõÕ!ê€Tïç  ±«9ÜØL+I9m²¼Hmõ¥)Á7~0•F%Õ³4hƒ1þ»ÇâJš,szºÅR›O°•ΛɊpvÈ‚ä𸲶îJÄ>;Q~éŠÃ"òr9›\¶ŽGަ—שּׂÈÛ5›`+±±Ve` ˜ñ}xß9Ì_Œ†±Ú±(¾ EÈÅðÅÈÅZ⎸kÝQⲺD—جÖãÑpi4öùÂ6€ÁÝ®·ÖG‰Pÿ1â=€ß|p K öœÑâ¬Q[˜-± 3„fa°AØ#ô ?,‚È2σú°Žu½åÍT2dh{µË򬮾´í]ºÑþ©*‰€`qÊ‘‰‚#tÑM„‹07þdzQ•×ã¯âd·BíÛ·¯Z2,P¡‡å,0ÓW‹°›”¢Éxæ13œšsHR‡gÈöó/¿èY"©NÿŠËNŸÙž; ©5n–·Xì¯ÝüÎ…?z¹¢mÇ…Ãe³Å¨‰Z/'rØÂ³˜ç¡ÇÙhÕÖ#Ô»ãÌìX`M‚rì{ïžÜýøéâöC<ÆdæV„DÎXƒJ,'[ Û˜£†+\£ùP‚a6éá! iš+ˆÞb9ß²Måƒ.ÙVß ‡RcCK&Ô:"¡¡G b´Q9£ +Ÿ)¬rÏPGU< TdfÑÉDiÈÌ45Ói/79ž£!›âJ¯9Ì\â SpTæd9øCÎLp*í;L¡ˆ¬¹¿Êýjÿ®|Ϧ·¼ß:»rê_^[ZWå Å÷,ktpÓ¢No2Ò×R·÷µóä+ç…Éöî…ï®CK¯oüdj"1£Æ]©­ºéØÏÚ"uå]«³ñ¥»a¼ƒ‰æ)¹˜d™EÌc[[k[Ûñ SšÉ0­L{&÷PzØÐçñ}íc±Ãdg‰ÂZèõ±ÂTn†Ÿ%F( ·’Ÿñdj2$ÞL5fÚ„ê4!B>W}:$œÎ] ]}dA˰‚”ôsÃÞŸþaz4Mré=°!i0€‰i %€Í…b2Ï‚9s˜xæè¬fŸ˜¤w))Y`%SO5–w«‚ê†ÁAë Y˜¯ ²¼ÊÛQe 4=®h'€/]Epe1i;({Ó).‰/Õ#\Ãîó2g¹dD©Ã˜²¥µ ð8ªJö-²œÚ–©IX1öw|ÚþúÆBËÏ]Îô g9ç òCdžö¿_Ý´ۃáÓÏ€—ø@*V=OtÖpˆƒ.àEÁc³yª{QÙÎ#g_þë§o£¥»¾üo#fàíÓc¤‹+c Ìec‰"qá‚¶¹yQ’Žç;JóùŽüì,‘2T ¤öïÙß³»½¼ƒ2kÐê[ËØðú«QŸøº\–Ä’ÏkLwwWÓHnb¼£^ìõnP´ -©µ‚$pVFC9-Nͤ,”„²VM™*;>¡‰¬&_)A‰ÒrçN E¦¹ÿƒJ[»Èn•Î %ˆ`Æ “ÝÅÌÏâ¢`@.¬2k]ä;}¨¹(°ƒûøÅÞù)=È÷YYDÔØÊù ® ÑY ƒž:ãÈÀÙ–n»5²;—–Exï,γ£;{@ïqØ%N"¢AáûW×®×ýv^!±o[ †œ¢LÝP]|p†¶®Ëh[|tí†$’Ř[v+5Ö”×MX‹¶æeg?®QyŽ8­–Ò†íÑDuå“J#ÄÉ>,Eç Tí7ƒÆìäÊ!qò;fÎôWF™êÕÏó7ŠÌI8‰Y gÃiÅãÕ#¨ÓØã ú+ײÛÙ“,a¿f*+Ò®r ¾™>‘Æi9TìøZ 8£ 15Žm‰‹ ÇFcBÜ<‘ 1»—VÚ”U Q†*ô„nè›õô»ú纰Qß«ègôË:÷kÓ Ì±0 Ÿñ êž4 èqe¢ L€Ì7$êPo/ÌOu¯&?súCT©”Ö ™5£­D+üª–°„otS¦^ ¦Æòrt¹«§nΊv¿…÷zgokéï*s[äß"›°2˜Q¯9˱Ĺ]þÖÊôâUW¯\Òø›ÎÝ\¹ÝicmqqEùò7~y*²¥z`ºý}×.YpÀá±—ØK«3.~ùæn­9ryqâùÖùïÏœEë°~ú ù6ûœÉ3oüÖëõˆÖÇ )â/Dü™Œ/"ÖÓŽ‰aÖïñÉß/6>ï7ŠÃ" Šý"fD$Þ«È&²Fv4ËÆ³{²8KC"E: íJå ã9¾ñD”ôÆéìcÊwsÊTX„/Ž=´7LX\EEªÂ•T™Â5¯`i¢y%½û»÷7ô-R{T‹j[s$&«%)êrðÒ,ÿ¾†zÅò?ÂË>¦óŽãÏÛÝùl>Ûœ_ð+cŒÁ¼p|@èhœšA°A¦Bh «CH–—-]h£&tiGÂ’lm³‰EU¤uY»lt¬mÔ¥i«h[«IY§N+ÓÒMQC“JÑ^”@öÜ™TÝ_Óéñs¶Oºçå÷|¿Ÿ¯$è³m¦ÂÍõ.9£3A„ "·öÕpúòüw)u9P‘)5¼¢Ø0àû];¬9œ-1”Ø !AW£!kìzwm›]Kyv7­Ü,cPEµÿoò©„˜hFlyÚŒëÅzS¼÷€}Q„ êÍQÞ˜°j&5?ÔУ4ßGñ ›íiÛ)¶ Åè ô•GåXè,ÃÄÅgu:ù¬F”¦¤ Ò%‰R…$«_è­,õS8»;kpÀ Ç”‰¯£Â!;0áp¬mQÈD§]c‹J/*VkR?¨E(µœ¡M¹‡É ŽÔ«Æpx.\DÍù5Q7*­ÐËÌ@t«¿šGΑ Ý¢ÕxU–òWÊ\= ;æ >9à«lyç{g]W[Ò3YP³îO/ÿä·5±2(vÖÈ£k•ØRB¥¡£ÍUVÞøÄøôIô¨'tôkß~ÿüµ;W{Ê–‚Ïtžùèï¶O”û&Ë# wŒW¬ßPh‰iŒÌ~¿+¸{Ûh|èÄøÁJm÷ÐÔÐO¡<+tAtU(,÷ðM”—ëRŽÿ8câ›Ñ#QeÄ×êÒ4z @€‚à‰ƒ*$ÄJV‘:²Ž ‘ä¹Dø°ÚarÕ3]‘#Û"§"d*2A?Àˆ*K´W¦º±!ýXº®â ˨4òP>Àp• •äØÜ¢­°Ÿš9rK®®ó†ú'OýyF¯•JRû£ÛÛÇ;ê6´U¥½y­F¯³Ä|ߺòÉ -ÛÈ|ÇÆÇÏÞóû·ò‚A q¨±íŒ¾õÒ•Ôú‘÷~Ô+³Xky­váü+7ü áì¹ÿ)Lâ 6“yí,æÄY‹_]f5Š‚(x|‹®ÒëpØÅŽev-ÞQR¡’ Í+e¢r­ù+!qO¢´¬Ùo”Õ3M¡Ò†x¨²ýÜ/7‡"§¼ôq.9&é8º—ß‚Oá"šD}`äuàƒÏÉÅ—³f-; ¸—õPÑjØ;åžuÿÒ{§û{ʽàfÜspßkVk1VZx™?Äßæ àE)^~~gø°r"èÖ(»$ÞÌ(Ã^*Pþ` tµ±"ÞÔ ¹\"ú²î?[Cñ†‘Ýyq=àV¬íli à¢x0Ø•6Þ½¼v8fETV((I÷lÚõ•jœSäm2X0*» òæÓ?Fh€!ù CÂøWð9ÀÐië½€a Ä„Ö&™p¢!•Ø{"½h™p}‰ÎI¾#å¶Ð‘ƒ—W:šô`5”xHÞ¾û! ßkÅóSðÝvxùÑåñå]Ê®OÃíä7ø8Õ5dždp"‡8Ä~N\àÐ 9ú¾Æ¥F@‰&¬¬U¡Th¤mšTÜý@iøxjy2ý¿³ü†ìb„ K§Æ":»Œò1F,ˆ`ð`–‚S¾` ÐGPnšx£ 1}íMu–ÿwžf(ÁjN“ðÝñü½V2²k_nì‡ÇèkºÿL/“[Á^ˆäÖÔŽkÖ#T§øT^×¶wh|ŒM6oÝñ8“Md“‰1§%ßIÏ?™Ìæ'“Ù¬4œ­bkG+nmí‘0N÷ÏÁk¯õlJ§æiØìAxMޕե#EéÈæ2M¾dÁ~MÖ– dñ\f³[ì΀³ÚÙæL9÷9ì䜉G£“Ñ—¢W£Gš_+/Nùßð#ÿl•­G’§“(É»:7wnëÄçú·@︅ê ÍMOKJg§u<¦ÆO%NqQ¼¾³(ÞYT¸?³dŒ­®²HÅx­J> ”ɬªi€•µ5_^Š×& *ÝfEÝê}î‡!=TªÏM@UëUF¥¶HõmE±(ßäžÎq-í«£PSÿ*©h„8]žÎÊ7äùìÑ&Æní³tJn—/Th*ýÁ#rÀÈ4 å&‚½BÕÄÖýz;oÑñŒ^»½Tb LŽL©çZ¢¨T ©:^òÕáÕ¶Ž‘ˆ$E‹ 6?üëè䯭ÐÄõjY¿ìœçÕ@Ž3‡·Í§ÍÍ[ó—º>»¶D‡—‡>y³;ˆDàu,Cµ‘¦Èä ,äoâMÉÊž»‚Œ[X^<#òËèyŽ>ÇP£Æ,‡¶²Ìª¢WLÿ0é{_ì^µÁ#ÒÓ㸿LŽ1&I0~&ïEÙ`ÿ^û¯ZT»ÇÛ »» XÆèyÊiûÒçÖ_Ym=^Ÿ."¼MÞ(úêw!, anÜ´H›¥ai¯ôt[b½*tPçg*( I $3}½à´ûXEVä¢}@ñ ë×—®+þ£2l,¦µ£%1‹Ԩõ«,@‹ˆú’RDôüTçö–B™âí˜Ë#$W6³6‡ªŠ.Æ¡Ft_aÎÜÕZX1.‰ó@ZKJ`)GêVNr#‡QÛ·çxýÁóíãc`vB4XǺ¼ÅØmaY·Û¢KWcK:À›æhf©Ê·ÐÝ./}®˜˜¼^u h ÝBÌ ‚èc’LÝÿå¹êc›8ïð½w÷Þ‡ï|¾³Ï>;ŽcÇÁv‡Ø‰“7 q€Ø! $¸(R)R’”ÑQB 7‚­Aë7“”1&(K:©¬¢ëþXµ©+ªú´ÙÚj‹@Bê6œ½ïÙáξ÷¾|g½ÏïùøY)ëP´öl-ùV-¨mÅH¦>‚¸ˆ`É„ çD@àÈ€NY Š.±ÉÈeW­(+ã‰ÅÁàIQK56¬$ ‡¢ßÄ2Bõ‡¹ÎXÿ‰lüèW"=žµÛ|"ª]Pm“c·Þ|c.·yÍÔGã½3ûnÑ\·AvS䨋ŠwïÙ;û?Ï÷<0ñöÄ`;Í8Ù‹+i®2<𳿟¸yë¨ÛÚ„ý±x~ í(Sõ_ν‹®)®Dïìâ·×TW"gEÓ\ ½ædÍÅšes5ŸÔ|’ú¢†z Éåú„^YjÐîûõœ¬;Ê> ½„)ghEê‹Ôw©ïS´)u"E¦ô2éCJú´±ÙÐÆ,'è×T»1&ý¨ˆûÀ”üy’L9¾@2°?@h˜|¸€Y0wcѳæ˜9ð±I~4?o´L&l,hò1]ä…Ö‡,™0šü0.èb ˆ‡â*y,xH2ã¸e©7æ[+#í*Ò´%Ƀ¡`c÷}dQ —áò_bjcué 7VYÛYe%5>,ߺ£´á•æÝy.=½®oæõ·W½7’.õA&?H’`±ký®ßOoWKãÁ›ùÿ¬g" Ê+‰ß{s[êh+.;o±CÀ1m«úõ_&Çþq±Ï+²4`9È1ÂuŒwÍ‚;ÉÐÆq_w´;Ù½½›îîÞU5î÷û|ϳC¹æÌ®iš˜N²`? ©s¤ƒ—ìÏð¿Xdá0®¤ŒÑ ²ÑüŽÿØùp¹¹.ªÅ ÖRqdZÅÒA•[b¸ÜÅdSXQTàäãA"M©^I Ù'.9͆®ïÃ…cܨj”ª•a © 8ö„̼Dy9(³d©-•ÚN/ˆºÃV y!OÊfr$í6—5O­5¯zQêd<+nX^fªYd @#øyAö‹–’ÏV¹šES™™$gßWWÊ™6žY·¹©ËâEª9@™ŽT–¹dôL•’L2[yMPexÃk|¢Æ‰÷[b+ó*—!‘lG/µHþ4J< •BÒɰ]Ü’_²+‚Ý,³"¥H H˜uïÉ‹©Yéã'{Í¢õ‘Aºõ Ç­Ì»b¨DÚÝðT£ÒPL“E×0¯ ÊH)Ôa‚/t KJnò]ŒDØm=X YP[‚@¶Ã¢óŒk˜Eñ†V$Û¨ãxõƒóOˆþåé '¡PÇ0œ£%b…ÀiÎþp|É “HÃÃ~æ§;òÃÒ&æÅýüª­M'lôk6€5"#mhÖ(¹½³Ý‡IÒ»ºÞcC"LqîûQ§ó\[…³j r 4óíµN†fÎá‹uÕ“¯º-ämJ¹¿+µ1v¥í¬gs©iJ`9MñœI …ð–w/gi%PWοQª0”™¤,6ô_Mªl¡I^ ›ÄeÂŽÌ•_Ô _ã‘«ÅfFa\elf†­,t[+N·1}ç%Š7S«3¥\®ÐN.·sŒÅÄ› > Ð_¨BÃ("ÎЋÄÿ©.ÿ˜6Î;ŒßûÞï³ï|öÙœmLlÃa6`À8$Ø5ž )DNHnÔ!MK–t]‹N,!ŠH£h˯VQ•NÝþ˜4µRÖ5éöG&!mkÑj˪¨­ˆT”i™²ílÓªaö¾g“n:™×öÝé½çûyžg‘KòPoÖ;¸ ݉%çöê,¹ÍnèKŒ&N%HÏ|t¾~ȉô$3>¦‰!ef‘¹Î˜QæC2L¢«\a 5å ~ÿ‰è±aú] -ˆuƒ^¥gi'J·ÄìlY  8˜ `]`ˆ³ÁšP…úÆf@¡§|ŽbklâÀnÀú)´G†"#@š‚¦JoØÝa!‡B®äÜ_…¶‡G^=þlÿóõ­6g"#‰ŠÈ1.†‘%4¹m¶5Ÿ.v¿—Ý4ÚUÉ™”DžCÍ É]Ï®}ãh_v/$‘‘óS=•ºÖëñŽHô œX¸>@‡n‚{IjÈ;/÷õõûä&ZP3l’_—¯Ë·e†ÀEq ¿¼3ÖhDF›SڛǑµÔäHƼF93v)Ö$cíh"xÚ62,<%è9X¼9örâQX´Hû][ëyÅîhÚéô©Þ*d-ÈšÆ[µ½M…¯«Ó®‘~èÕà`ØÄbŠ¡=5Àç Gwñ¢ØÆS´½5œ¼>víÛßùýµ[d”?,œ $U‘’%Þ}Øe‹ÖÕTÖq|ÀÄÝéÆÌ½þMŽšÜ:¶¬ÿ•±Óè#@eòÙ•º/¾‘+ +¡•Í+ÔrÝ݆»!r¹a9´¼y¹‘j ¦‰ŒhDF f½o$˜€Æ‡3q‚8…äF<¡w⧠ĹMº{ÐaÖm•8¦¿Œ1z@?ôy|éùïégñ¥žó\€ ŽkŒô“½žqÏeéñ g@¦qeØv¼™T俦æÑf²¹yñØÄñ3—ŽíÙrÌû/Yö€=‘üÄH<¶¢Ç—_Ë¡ˆ²ÈãxâPùäktºÊþ†Êá,v†¨iyéédzy"o¼0ÝjñÜ ‹¶”‚ÉÆTЬ1 D rOë Ò¾­%†) ÌɶJEÁÿ‹ÕÊQC+qUP6FÌaG¬5RuüÊìé8lù0OÛÂ/)¬è t¼è4]sŠf'õJ´J×(Žq##Ïø$«Íá\L[¼E1ؾU´*Þr샡µÏhad‹Á&›9”–¨Ž…T ½Ïßh‚fÿ^¯i‰‚©¦ÇfeÌ>ûÕZï«Ã’ž6Y«=ØßnQ`Û @N‹h7·×GîŸdYZ=XüòÀ‚…’L¨ÐQf‰åÌ‚¡ì £Ãoöi𕶆ƒî¿|«Íî0¡Ë‰PrA¤âÐ6P|•½C)ž+®×']¬ƒ…ˆÝ$ sÑ´þõêYxþ…)Jõºku¿FEWÑúÆô^Xòåª^®§ç™£–”7I ¤†St*5P{¥iˆ¸â˜ç#˜‡H:H2Ã_Ë1˜€Lµ\ˆbJ0ÖÖ^#zr-^ˆF©·cìí¬Cu(¤Š-/j±qDKB©õ!q˜Û¿½Y ‹ OÖ]s%tuŸ›vvò;wùcúPR c\“韥·¤ëUÚ¬øü […PWœ+nú¦ÇËXÌ–²‰YÀÝxÔõûVÁfæ\&£Ý Òæ€,'vËÍ[o%ŠïvmBÿ‘j‡àdw¿æûþ~»ÕÄCœƒ¤õ1×Pš‹Éþßò w&Ïß>›üüçܓ:ÁÈš\ë {#òkò¨œ—ÇäïÊãr¡}ô[£ÇF/Y2£Ã ï-Ü^ ¦¸šj¿×«Ý\ŸKVj…qqV> Ï^™ŠŸÑ"vM‹x' ¨Ÿ¨É æE½âÄÔÔ 'Ú9N,pâ„÷ˆFïvE:õØ`ó`Vá§ë²èÌÌéû ÎìîÓ³ÙÝ(1åÜ}Ý{Ž‹dŽä,CÞ!8téÅ¡Žù¾ùÌxÁï¥8BKjÓê´¸Ö«íÓkÚUÓ´dæ@f1ó÷ •Ì gò™w3+™&sÜJZ8«•˜ŸšÉîcr‘œ]Gäµ\Þ…P“GqÊXE¹'Öøq¶Ê¸YM¬>Á1['VgéphVš^B«34‹ÖÒÐý9|B^ZZ"Âa„ \ŒåcâkWlÛÀSd”§äK@±•c>ÊçJ8AÓ‡R›‚úV™&ìÓtü:ºá”d,(É¬Ó $‚hµ«Å¸«¶ÿ˜wWÂÌQ–·Ë=×ÖÊs•̓žt#;ºT.ì Y^Ž«R\P$ÙÕq²¿’¾F½ID‘†@ò·O² Ü9Gßí®GáŠôÇU<ÉrÖ ¼ØöFŸÄ«ùâoœ JTËá:¥‹¿«î©{Nuð$ÇðµïÜÔí¶X--¢¬A‘´Àï_[(þ(”EkÃ…Žºë* Ih¢Y³Ò6O¸érñ­¥“Û+Í6…æxd«$…X"ÑV%PøÈÿó;ogk ¦ø£Ùwò{ëT¶Ã_¼ZþOñ“ácÕ~ÈXXÚl¢IÌ÷ú'ôç4CL"Ùõ'ùÏ; ‘ž³¾n;•>µóô.æÓôÃô?Òd/Û›žK“î4øƒv* ­°ìt6mÏfÓ² «€‘Ö’Y†5=„Õ*‡!±°ƒô €iþÃ)oŒ<¯¿€OšG8»’î¦Nï ²ÖO“|"xÅÉ:g¢8Û4%;Pü8ñ ÁÈèÄß¼›¸‹¾¡+dwö_œ9NÌ¿<» ”ÿâk«Èü~Çò«­qyÕÀúT» d©KùQ0ž3T;½DŒå‘&sØsJ°¬@¤Aˆ”¢T¨1dzHWå>HÙ^6MœÊС >aXº&J_ËÚ+A…QKÔ ý/ÙåÛÄ}ÇñûÿïÎwg'~±øüHlâ<ζljãè¦\_hXUagÆg¥õ vÞõÇô‰ô;>/Ë餇†,  =‡AgS½x"ú›= ÿ}—^mSã¬Ö?þ;Cäâ™Xá»ÒG$B€)`‹áÁbP-„K¬×7*–È-¨Æ°ó£‘MÊ03;ßyë^™Ã‰AZÞÖàÝs ÿ0›kj¤Jg‹sÈ9î<á¤CqÍ„fJCvj€æwà8‘ |ÐF”CÛ[R²oZc¦ÔÔ’ýDŸˆ%N'¨« àHt&`"Û¹péÒ>@»šB¹",â]ýíð£HŠãF¦p©þ¡g¢¦ FÆN~([6P ` 0f¿¯×wÀwÑGû0%‹µß¦F0%#©þTÿ\J‡ÃºánÍ4KMæÍÜîò’‡Õ"…E¥070cˆYУđÒYG,„Á€>Û:Cú‡La÷4èÍ&pûÈì ô®~ól PW|qË úÍœ5P €ƒYþõ_¶vO¥¿Ø?vWø‡OW–Ù'§Fwßë6®P7—ÛsâO;Ó_žêUÐÜÂ#%dŽÕÀ•IÍÑ9z°x󊺨å÷ ÿ)°òþAec¨À?¼üÓ¾Ó]“o8¾Ò_TòÍß§(7&ˆ'ˆc67j‰RÐ IAOPrWV‘î9¶µrƯµ^nƘµ²>¹\b;fÁ ¢QèheuòŸÀ€lƒAwuÒ“'-‘diôéŠtGb¤°+fÒø€ON®Oþ-I&‡j… ¼ aÜ9¢4ìïJU'õ“ñI?bàDŒ".•END²„ñ(#jçRsµwïÖVÿvsH ôžr2É(C·T3aIB#¬(C# Í);Ì„£Ì¤ò’ˆFÆ«0ê(6¡fTgÏ—0@ð´-·¥¿>QQâ<:l+¡h`×1´Ee9RêÛºûþ™Í’Q©bT Éú£ƒ3ƒºÜ–5Ÿ=Y³@¯T(8÷ü¨}FthV¥ßà]¼Ù¬Tê2‚¤”<t¹‘-ÑÆ¶ªv2~i;òÛ¥ówÈíˆÍ:âæ[¼N‡üx(h…‚æ ƒ ¤ãƒTôß,`YkÔ^~Õ{× ½^ë¤ ¨F£ä®rP>jåBº OIjª|S |cn·À±à>úÍØqœ8KÑ“ÉdتêóšHGäBäJ„ŠDé·ö±u­^)‡µœÜ±£§.êZ÷lÏß[QbuèUº±6‘erõO Öo‹ÄÞ.nh­Zº÷³µ¸ùïç¿ >¡+‰¯c¼Ò§X—/ï.*ªëî-»-5@Lì–9MXŽ—ÇñÒ‡—¼tá¥/íxiÍKäÌm]DŽâiÙVÇ*ÆX6¶bE|•ylÁ!h…MÂaZ8-\>X‡à Âêš))Ù4Õ•’’D\ÅIGÜŸŽŸŽSq¯^…7MÅ9Ì(–+5—‰ôC%¥âëÿ_s÷´Õ„¶ºº:c´a›*Úzä¥ÂÉ.ߨ&Î;ŽûyîÏswþsçó9vœä.±c;Ä11ÄÆ˜Ä±C‚cáJ³,°&t¡%62DÉ(+ •ÈŠè**Út…¢%bêÂ`ë´©ŠV^µ¼˜¦M“&4uãE‹Ê‹©Ó^$ÙóœMµiqä;?~îdÝï÷ý}¿àïˆW©Q˜€¡ÔJ|4$èPUÓ‰—¨‰1ªBRI@)ƒ•H#ØÕ¼Ž¶ñ²Ë^ãB_WáAì“DžR­΂ —•ã,¼¢*;.•ã£pÇž×–K';ß Ø}ÔÖ²,ЕC)~9>_‹Ó?Œƒø=ð÷´œ…WŃ…«²O³p<{. ³d ¯àØcÔ#nÅŸTg/.\È ê5·ˆyV…UUa=Ũ* T"QÜ…“¦SÑ)©2ÄɆŠú·R«Nï€ÛÊ#¡&a}L ðæßÝy{i7…Ö!_bðu-m[Ùë8¡ ÌRçø¯^N¿èñQ”dvvn•)Ö,yz¯3´g-ˆ’ÍryÕ¾úôBqó¡…;ÌŽiÚ£Öú›ˆY”ÍRh‹väó‘åìáƒ]Šo|sÿ¥mÀý···¸$`ãÏp˜$×¾^û33É ÓNÓ­ôsðìÍdκUÅíV{:;ÏûUÅïWý·Êô„6ë!=s9»ÎÁÞbßÛ“WÁ ¨ª‰ó»ýAÿ~ÿ7~¦Ó¿þS´&‰¦£ôxôrF?;åîLÞzÕzÃJYïkEp[´ã"`ª[,­àC-€%lîÔ¤4O ¬šáÔz÷³ÜBaQul|6ø#¸††â›§É$™bªÃ(èïØ¨Å@ ˆ#Â`•÷ìhÏž&Qî¹íM«,îy7WN±6½ØÁ¡Þhlä‡ëTËÖ~ž}c›Àº•½-5«ÿ>m°òfëÄŽÕÏššûhDÿÓŽÝ Š•`Írp×êÜÉ_}â´¿ÿÊôǬðQhŽG!޳rP¨k[9µú—w÷sDoÁ»Ýµ.2¸*_­=@^z #ÐÇ÷Mo­½ö‘¶¸Ðxoíµôly~®qQs:Ï.-*KK‹ ##c9MÉå´+sscåÓJ¹|z><ÛWVúúÊÙ£¾›e]¸¯[t¶ê±”¾¥ƒ—õWõ7à!ýàÁy½X<‹ ü\qž'ûim~.^årøôí¸ðSÓÌì ŒÌ¤gÎá“3OgØïΌ㓇ø”™!ÑÔ×ÜÓ˜Œ$û’û’ãÉsÉÙääï’“O“fþ¥$HÞÓé@{8>^ Ó—Ã ^\Ð4°.FrbA+ Ž~[ø¼ÀpÎZz8ôh‘›[œKi!/Ì ”ðÐNúe7Lµ] ·1´±¬eòE©L6”H‹%­ôy—ô¤*wrü¿¾ú¯ÃÔÙåP›vºiôèÑc7F²ÙŒOóùµœßwsþæíù`&›Í-—û¦lÒ2·l[žâ$üÞEÜò³E}C„ÂÃBÄœ î;£Iq`sÔT‰ø7žîxtF%&áŠwĉiÄ7³¨:c vÂÝL–﻾Å]Ö¸¯H®ÄÍï 0ÚÏ Ê=IÿÛ ª\YDUÓ" 7Ûñ/q[Ïà&÷êFšåPê-_Þßgç~æu›89ˆ­©Æø†èwxY²Ùhi]§c`¤}×n ;eÀœøJ_k†“8»º3P«äJ¬rX×±4þø‹aè&²05©Ÿ'Þižâ2z—¾u/Y¯—õZ²>Xs±ô/g&2733ÿÊ0(ãÊ<ÊP™LC±µ‹%ñE€ÿ_|`Ò¥7êi}ŸNëú%S¿¢)L© <¨©a˜@¦IÇdd2=ycòá$;y\3™ e&H¶M$JF–-­óA"Ð<•8Uá7ßRÏÿ(k(¯¹=²qC~/~ V«ùD©$îÜ•Ïï=q¢| ?èF+N#(FtFþ ½uÅU¥÷ì ¢@PrURrõ0Ÿé¢“àQÅGH2#ò¨ÈsSœx~ º1:4X1¶Â[ †Ä»'jÄa*RŠE±öâø4Tf¤uCö¿¼d“@;ûŠYëòŠ©ë»¯­~Ùl ØY˜µ×õÞŠì«muÛ,È'7 S?¶ÐÙ{Uª÷ç±Wspù7#"<“–o ˆmµµþ9­C­žÌa¼¢7}ä{?ïæÃ$ŽÙ9– Ì×®ÙMâ|àcMƒ.iòïPDNx¶Ùö ÅÅ+b‹/ä°T±¢Œg®7Íž£?v2”=°‹7ñ8ýëœJóf7'9L?ø}«ÊÊ"'x~Á¯¢3ß“Ý Íóßê4˜h,©‡î´Eí ‡£ÀÓˆ&ŒÍ¢I’ –Pca›¼o_ý"d1’CÀ”ÉÀñ˜¥qmÙ"Œo•þ>†$,]j©æ$›ÉdXTsXvLŠ 3;¢Ù‹¸{Ä'ñP³wõŸÌ¶€v¢?ä³)œ°Õ™Ì6›56èu‚MÀ¶±º„\W—R…Â,È Ïx| $Æ £c#¿Á7€¿7Ð8ªÅŸþ‡Ñ,EÁHñÝãFª—ZGZ^Ò&µ«Ú?4nNÃ×4¬iùRºJÝ?²‚¼áQ¤tt¤9• (TJè*ÀŽg#ʈF¡`À£ 1¬„cp —ÐLÇl¶8€¯ÄJßÄ61f~µÆñÉHQÅ]ãü.‘ùX§0³G.ô×î´š{f1ù׳ùÙó 67Žb9´7¾«¿J[ϘjrüòF«wëLÐ`%ÁJ_}´ŠÓê TÔ|Ý„v þr¼JS‚:‚&ÆýÕƒ“3PÉÂê:E7¡Ælþµ *>æ<î¢.Kú/3ïôsü²Ÿ>Ùwrø}R:é:ž ûý}ßi¢o÷Ý‰þØyËu»óV/s©óJß•þ61—L—íWômÓírÐåLƒ=q­C£®jwÀMi±žY³Pâ =¡ìUÞWèƒÊUeU¡Í V”–ÜNƒ8¸LóšUôOÇøÐÔ¢~B§t}4±Ù´”îQ–N¥ï¤)s:Ÿ¦ÒËøAÞøÐnê Œåø¾â¿@ô„Uå¶RÇJYÅbeWÈ,kJ y²Ɇöáùp%TbBåºX x#“'W3éN%ËŽˆH <ÉRI˜DaÒz±5nÑœ; ¹õ^Õiœ[HnL­;ýÆŒ‹ê)t·‡íœ5êqÚ„½§;F7çy¦¶Û=š×Ä–>ãéÎã 5™º@CÛ‰3kI—¹ÁÓ¹)d”Ö'ºÏ¯š‚‘ƒÛ²¡íµÄ=çÆ›bÎÅS/º,¾ª ,k:x0í¹§ò±úHÚ郎‡V¯ÓØn”E=èJ¾þv;6w¨tóúéü.ù%ù¦ü©ü™å¡<š­¡Ïñ¨y:(j¢wyõa>êVZ?dY]RU©°„vë½m[Û–Û>lcÚ¦f¼ ÞEï ï5ï}/ç=¬-ã§óñ£ú»:5¤Oêsú+:9ùD¨nÑkô„ž×Ÿ\2‘޳ú±VƒÁ°Ü}Üþ2LÒA°Ægë#©˜ni‡m,Š: <ÊŠ»c¾èyluµ‚¹(Ú3唘r:¬À4¹ìÁo”DR 4ÚG,0@­9ÓœŽd² '×úJ'1!Ãîý¼E K}EóôPÓ¤«®*4õî³ãKB ác@BLÛ|xÿ›§ÎžÜ1 ÖÆ毬`³G°…-ݘxn”õ§¹F.¦'ºwëÓ/w ãΩÜÒwmUÅöŸx£_ 9ýÖÿˆ®úØ&Î;ü¾÷ÞÙw>œí³ÇŸ‰ãØNâ$Æñ_>Hb(Ž)äB $‚ X·ú£lÀÔvt+ÊØVÐÖº0iRª1íI7BQ&…•iІ4T••½ï90ÙÒ½w~Oçûýžçù=Ï´Óìºú/Ê ÉH©¥¿# 7xíÙ ÍS•ù‚!ìSpÿȹgÎ ÛY~… ß»áq‚·ÍÞm¶j§íS”K®•…´Ð/ì^Þf5  ¸„°0&ÐÂE€ªÌ¦Yú> eö{—Eì#ðe‹+iBVáH`.?ÈJ‰ÅyRäR›z=•0~E 1*¡×³ ÷(rÂÔ鑱ßn›øð‡Ç“åwM¼4^Ú[ÿìÛc©ƒ—76MÜ¿>¶‡\_q2wfrºà7k^º¾`ZÀJÐÞ•ce‚µPbsü%ð€ü{Ôƒšâ…¹âKn¾iûßAßQßiß-ß?}_ùÔ,–n>ÞW£¾æ!À[#ow3€Ø 36Y8:k‚¦—ÚÝ *1@à— ™À#2œª@"0¸P­É »ˆõÿÁ|V¸K°'èfS{DJpqù—ÅG¬ 1¢”ä”7£V 2« šjˆM%vÅ»RQ R¸¨bkHñÌz¤tË•£>ÃÜ÷oS¨£µ46±E_îS.³±ä§/vœëYUåØ]Òë8Ò½Â@»_zvïÙß^û-êFñÄ癚"Šæ5Z½¶lzüüãÔmœ)“šU«ìª~ÆÐ42Õßu&âiæl~Ýâ©æOÞÏn¼øÎ›¿÷“Ú§–þJP„@=øDެ±ÀOµ7ô7¬xðÒdèp¦"h™ž¦‘‹ã¢éÂ2£Ë6ÊFÆH€9ð™ê¶sXÆùX_y4]Áp‘_Œ‰mb—8,2¢¸Z¥Cý¡±Ðlˆ¡ÏC”r…Âøœ]æöqw¹ÿp47‚Cv¤ô}”G§Èñ(þ¤?¢Øcf…Ì~¥) J—Ý'‘ÿù#úï\¹Bô= ž6‹ZÄjÐÄ$êó6ß‘èS±°”*Vs¹3j*x¼ç™Ê0áú»¤–†v¬8ÖæIµ­žp‹ñŠÆ®l}ºcñ/Uµ‹~ÎäßX·¯5J ˆvðMõê÷³Yýõ~5+u‰\qèO¯†Ž¥VzÂæžŠÔ[Je68;‚ÝM˜ûýKKHbêAø…ìŠDb|µªâBLuÊÄT³ëàºu¶ÿ¸åB Õ‹zWäç*íõä·Ò¥¹ÖÞÞh8†î)ztšL“ÁšÏh¬s,ÓÁþàXðNÁtðdƒ=ÝOŒÎ©J !ï)è8ŠóƒQäekªÆÉz'¿B¼˵V™–A¸ä,èIšÃŽG1µ·l¹¶+ʪ`¤.úô£üÿ‹ˆØu¢Âpì¡@¡Â"ß·Ãd(3ï0'ëÌH^¿ö‘Ô]…šbŠ¢bÒÐi§Ní§Vmꌇö´m 9N_h#oë6 ^eåuE4gÓ2š3îÇK’Ϫã8YxˆMëD” ²í,¾ÀbúhYÚ§·ð^¡l¤ ùåš’§Åm÷›Ýˆi¾(c7¥[¼ÞCÐ:Á°$wŸë:¿åfz³á®_v UßñcƒÇ‡hìtÁÐÀŽÄ~ûU ÅbråŒwÎKyg}CöÌ ìvæ Qq;Æ)ÍuÍMÍ=ÍC Ö¬ïsUÂÙJX9"KûŒê‘žý=¿ëA=}²Áo HX“Næ&[Zv2Ó®Yåreöƒ8ŒÇw]OÃ4Ö¶9씦àm¹`&9—¤’®éáŒêõ‘iÎ1ÁÞg l“ÆH¨_¨­'XXP<‘òÅŒÊ&ÉVI ~ãØ+›²‹™¶ã˜VYƧЇ4ÒGü"jäƒÅìi_ÉlÅ+26Ê–aÂ8¨ü…eò!LËÚå9¬BøîHè—G¹êµÏø Ö:ûë|­9æJøÕ‚h|Qk3h‚ý°žÑû~¶AeϬ/-Ù ¹½‡wß9uödú»¥EÑ-áî½:·¸7¿:øçÍ®º WýÛ¾]››T+ªÃÅE‚- rÆÌÏ_¹lÖø cäÄ*AðR]mm§Ó°Ò&ZÄZ–^5ßp¬+•©(›ÍTsßÁú—~ïÄѯÿÚš˜ˆ¸åZŽÖµÇRí˜ÇŽ¥‡è¿LŒ€K²ÿòÚ=¯Cç=ç×]ö þ‡vP·Zá꜔‰Ôäj3!gº„U~jéŽ,¦œIÌ ôæ¶d4Éí%êø¼%ó-“5£o•ùrX>ëå“ÙéÜ4)ŒŽŒb`˜‘™4ÓÏŒ1'™;Ì}†ŒÀ„ñ¥“ Ã\†»ANø’[ªyaQ‰6D2^“žÇð2F:›Ù¬BÙ²:DlÒòX#C«®VÉ‹¢-ú„¹ø ÷Ç ­65énâH‚`”LÁhÞ(N˜Ü„£ÞèÄÖRå-Sô!â›0ñØiáð£+ø¥/ÒîVãÜGS‰âÈ7ŸKU ,g”$9áßLéjÖÊè}q- mÕ6FÃîŒI )<¥ õ}ÞŠ˜bCêׇ5",°ðê¦ ØÓ±m¾—·2j¥‚—ýõçÏ}d²& Õ¹ÕcÃÒàs¶¢N«qªhŠSq&•^ÃÝ[;±~eÂfÜä+[“Ü>¹Õ ö ŽgÈÅÎOÍ’™ –¾†WàALË+Ž«u5 mÎuÁ9ƒ¥ÃBEß²@ƒÎXæ,ÿ¶,Yh‹º¶·’(w¹»·/–k¸)(Êæ÷Ð4šEwÐ}Ä 8£šÃIp Zå˜8É£ª%ƒ×‰õc§}rF;§¥´£Õ$HcÒ!‰–¥´Ô—´ …¥³’¤Fù‰¶ÏãQø?ÆË7¶‰ûŒã÷ûÝÿó}þsvâÄ>;vÎqbÇvâ†ü±àHJÁ€Qð M²dØŒh¥,”J0&N­Ä&±å í‹ntší+4¡iS4…¾˜º2UáE¨´nnyÁ¦•dÏïœ4{9}qΗ“ò<ßïóý<…óÕT¬”©Ly£Ñ™òÜÐvíÓ²—LÙIÌ»aX:½(&8kNš3M Ÿ7 É›ÛÏÆ`ï´§ Ï?M†_x¡±11†úÙðHÌËÀÉ4òf›\4é}©NyË_ÏZX'S HvØs[˜?㺞N¬5øœ´:Å(îf›:Ö­-7úg91<‹šg­Ö8«Ö¶åí2)JóóǨ›uR2ÕNý&ÛæŸ Xô:/éÓÿ¡ÿGgtèAx$ =#[-‡WÂ_‡×ÃL˜Û$RtÅF#:º¨m•»o…B:ø¼5EIØt]ÇËúŠþµ¾œUµ’†³Ú(ü¸§=ÐiO4žÒT-®Ñš–Llýiyâñ¼½«LP¤RV+l¥™­’Ï‘šoVœ¯–œÖÆ´ƒL=8Ò¦…§š‰(q²ÞiLÚ[§s"ø„¥çNPö¥nEåY‘æ#Æî¨Ud>6’‰¦¨îîø÷L¡åøà÷Çk·Ý@;‡ܯªˆY{{íRðÞ‡z²‚ÿpj}þ„í¡~„š³ñ]Ãhjtp°43åš™™êœ0¢.ÈýQ&Ý835JŸlÌ7žF§OMÈM9™/M‘æï¢‡YûÙ<Ê_ì“®;5T"ß—ï ¨âMs®™ðLjfç 38cÐåþ¨-©'G’tò.ú{²gtJ.֛Й"ã/¢â]ÔšÝqyìúØ­±;cÆØ…±å±•1zì –šWçóñùìüè<7?Ûp°¼t¹€fK,Êšãð ËQˆYöâÂfs 5êóU@{„ðêê‚àƒ3`$ØcµBü‘©TV¿Ž±BHŸÐþek[ óšzÿ2ÛVÓrùµûdJFúèg$eŽËT•ÿÉœä|F£‡'³1‘&yVí«I@ÉêZP=l0;ÉŽºuh¼Ñ‚X‰zQ•R$i[IOó^Ó†¡†N,XÇÝ“}T?ŽºZ=ÇuDVAYB¿UüÅ!cö³ì-ÐØw =fD¦FŸIÙµýJ}ÚëdÐnݱö¥ÊIšc¿£ŠÂö3C-†Á¸,d÷DöÇê\>Žæ‚óè'»ÄíuƯ~žÖ™³È)åaÇ[FÎýáÙ^+MéE‡Å®r˜f±Ä+­ððLÉjõë¼ÄÔçú\5ã’Cb™—8€.ãE,°X´ï½x .|q¾Á)Iœø 4)­?GŸ°íÔ6êÃ¬ë æƒ}4RhDM¢;²ç=Dwµ¼—HK©•ÞÝŒa›Sw??ÌŠvuäê›WéXo¦÷NžV1hï|¨k.Ôt"â8txWnèÚKG¿Œj´ „e±qð‘dÙ¹‚"±áƒ™LÍ/Îý.áFRÁV&ceV°œ¹”{µ¼«»Þ³vû{S ' LYTZÎPô05AU²Íy?Ê-y—rÌÜûÞ÷sôUïÕÜ /½dù}OŠøñð³aÌ #¡ãŽaÏÑ=­“±cíéÉÔ±vj²pìÐd6ä¨2°‚R#Pª9ø=§^ñŸó_÷Ó~¾ÃÄçìbëì»Z1AÄcO;®9÷/R³ËkÿCŸ¨24,B=•-Š.T¶dS{¼ ¯ØW— $#ȪT0™ 4ÑA¹™£Áãö!Ïj%üȇ\ævDG4ÄsfXl’üQ:ÙБ‡ÜçÇp‚º#)£6˜© Vër¹HW¤F²Ús¡]øA¦º6¡rÎ7^ßÓËñuí>·*hN¥Æw,ôYÍ ñŒäâÑÔ_‡]µ8ó¤¦% Ñ•ìsÔ[®À¶}(æpò¶.‹pøÜ‡×¹­»œŠ¢8Ɇ0¦5Nàä•×Úî¤F/¶·wwÇ>ÿ ¢r‚äÀ¬ÍEc…'Üœ[L/Ñ)J´-f®ÁøO ª=Âñö#²eJ{Ù‡ÿ¨}¦á=Ú¼†µ»8µÜWD,ÞúÔ‡|äwW‰BËÔBÆ*§F)†ú& ®A*é•òÆ0·gªZ`à("µ ¡õ2Ô`G»s]gþËt¹À6qßqüþ÷ôù|öÙ>|Îű'~ėĉç˜8ñ;Á! N iëCx?FhŒ*2 ÙJ—BW‘µ*ÛÊ$P&öìÔ° ”­hEÐ^Z3ú@˜`¨›¦lL£¥J²ÿÿF­³ï“ï÷ø~?¿Ž /¼ýpáóß>·oÝð«/½òDÇĆUÇ6¯æNv‡±_œyØÑ|iá“uçÇÖþqgûôÔ…·Ñ›8çÿßä–ÄòØEM ¸TîjI·µ‡i­Ë¶Ëk‡E)õ´$¦kûNϘç†çcÏÅx€‡Ñ\³E?WÉb‘“jvÌ€~-눿U?žâº³ÅìLö7Y2»e‡ï€oÂ÷-߬ïcí;ŠØF¦90Ês“Ü4w£š8ëã†9´DsKô?‚TòÎÜ#{‚äÿ…šEZkÔeHÚq,óg;@ø K © T,3@@¤WËœÂûòY, ïD¥YðmN e p–2VôÐ{»«M Àš3O¾ñþØŸö >k·àV6Ò'[¨­ƒ'_Às¸ãàóo^x=³gþSŽeŒ¢Éj³½Î}OI&ÆÎ»c÷µ$?úÉ‘ßmk6Ð}í ¿÷‹$me+q‡Ì¦…SJÁûéñï_®Cyéš¿O̽p.ëþ§¹¯­ŽÁíF7®¦O¦¯¥‰U i¢³à/z¤¢¹]Àc¾P¸VÀ Û›¬+`PG V1«[˜šƒÊ@¶r„Lg1”›@vj–äQÈ=[úàÄ»‰[ “È$J‰-‰ý‰ñÄßL"R*Xš›·BkîßA‰¢ŽŒ fâQä¡:”Ê &1vÑ0J"³¤ËN1Ï¿ä6ÌŠFä×Kq$ }R% ÇènuÃtký8² ‚h'Ð4Wkv@ý¯ î®ì$É—+)„Èñ-ÅwFN÷ïè®á æ“©?ôädokÿz²Doí‡ è÷V†:ž}ñ9[˜g"Tq–d#k„¨b¤(¶’bå䯿sqd†.î~ëßgßë´]»üÕ¡±ÁñâÉM0ŽþÅyü‡Äf¬ û‘•#ÍD§r)B!ŲË+À " ¸D¦IÑ”>…¯‚Cù®‚ßT€2ƒû4c5ÓVìê$Šj”N£“qË<3hUQ¬ÔÖæ¥è8heÿÅâ}ì$T 6¿ZgÔwàA¢Âãv(ï/—·CÌ)/ñŒgpp¡,cI”z§<žÝPØaà=à‹/2ój˜:’m]o$iƒk¥O$w×Fa<’Ì|—¯¾E¬¬6Z\œ+ä¡  “Â^ÑÌ(VÖðL¸mG³Ùd¡X^Oìv(ƒ[ñ4tƒè›Všï\) l¸UñÙ+|¬#SÎ^ó#KÂts”‘6¢Üc0öåÅÛøkDk@ûÙûÙàõÐGõäåà•ÐUåO^6]ᯈ÷¸÷LøËüU3êàëFy“Èó&>` ’Èr£†Íb·1øL±‰lä$ï È\0xÁò5BÕ2x ]f±’PUµK%U5%ü—F°cãáÅ0Þ‡ !<ÆÃçjÆ0A¼B“Ð/ ¦IмO˜p@Vø%ØŒ¥„O—°{T÷¥©Lÿ-£ÝÒì6—‚ÛópÑY‚lX‚‹ ×P“•±2ü$QW¡†AvZ«38Ò6ÉáÐCuC Nü_ìâèõ›~{`O{ª%‰,|ÞаækÉÕå:8±ð¬Ù}8^ãvÿe{Ó†cê‘/¡ÿ6¹R™fsGRÝÚÒ’ÏíJ8¤ØV/X¿¹»µ¡¦f°w_´ó+̓ƒ'*L˜£–Åà%â&Ô«mš)ÚÜDƬp"ý1,õ*ÍÁÐ'¼Àë­ÜäjkG!®ðÄ€®E6ÇT½ªjZ=­¯Çëë;´¥ ØÏ¡b/Å"Xf>)ÁÑ.ÞG¥ <€ÑuéB ež—Ä$‰*›A€“„mX€ÅA'‘¤ Ü·SrwDC8m=Õkƒz_)Çå¼ÃϲPžêp’·®3pœ% w:M¸ 6$Dï¢p¼¢úäÂg»|5傺QÒëŽÿuoÈå‚ÓŽ‘1Y®Í/¶ÔÁèT/η+6„]ׄm°F5úªúzWýD%-ecdca#amÏ ÎŠTN0YRæ™ÅÏ4§CJ™]Åêê¡"A_ŠÎFoGïEÉè.軘æJqæí9®}ÀâöÀ‰ð ǘÓÁÛAüV(ÆŒSï¿0r:&)Oxó£ùñü¤~B7åµ|_~xy‰™Î˃•y4¢ì×Qqn‰KºøßŸ+gæÒœMQ”Tj¹(Kö˜”Œz€øH¹u‰G_Ý…!/Æ$˜&XŸÝZ¡%Cj„zÃÚ€îHƒ‚¥›ôrEƒ¤e«º§ZÞYc. ¤»_ŒPðî© „\qz€âŒ8p’eL~–o___-Q€·žnMî^•…À M!´VÇí¯]ËM?h«4¾÷HSaŽ„ÅÐhº¿}»ÿ% hžæªª8ªÆÐO9àCÃUk×^4ÊMvÆg“ oå.·R4ï/~H\'d¬û§f´µ¹ò¸K²¹ñ™ÅcZœËzó¹Ü¨¼B”åmÙì°ì†Gîy¹ÍMåzÔb ØDóE±Þ£[‚æÇéìlä¸ÓËÊr¯»Í*„v†ÆB'BBt$t$„‡fÀß5ß‹X\ˆ÷ŇãgâÔdÄgÀ9M^‘Ç >áç…0u–û€» j¼|^ëïÅ{#å¹Òþr*µ¬F©Tl´Tª„93åô#_Ñ ~‚Òh¢Ñ‰v Jz‰pH¨õtŸ™ÿQ]þ1m\¿w¿Ùw>Ûçó°1á̃l W8 „Ž Ã!;v c„TáL–¤Ý’ŠMjÓ©R–jÚ”fÓ²vš2Ek›ªC•&å´ªöCcÚ2‰öe¬lBê¦jË&öî mz¶yO÷žÐIïsßÎÚ~oÛGýýÚ9û„}¤¸×® 0õ½ökVS³}©‡[šê{ +à& Ò#ÊPðXOj‰C±pŒz†"Â]à;oÆàŽ(O}BLhÈr®42®Ãwsòy æøÆ2,GZ ÖOx?}£vðG·Óãn–o`€§ aÃPX ih‘+u޽ŽmÝPB??ùº/&Rðdÿ¾ý⫘©W uAZØ;Ûýù™Ç0½1O~8¿áÝðmìÅ%I¬VgO”¼kÛ7îŠó³±µí³%=æ-•¬lʗͦú¦ffªÙ>8íãæç-‘ó‰"W­ŠœI3YqóÂmR•+¬—@©4Ãͮσy®`šcdÀl3£$iž52z.unèÜÒ9|¦ÌfóÁùYKU«oJÃkà[†ÍåGó«ù{yÂÊ?Ì£bä×ÀCº$oJªâBðp°ü}®¤AÔ!uU}S½§iÕRWàd]}¨’¢S4ï nÁ¿‹ßÂ߯âþb‰–a¬ªE Ö5 µ¬ëS ³R¨Ír©Çe˜ ¶l´lA‡Urg°ÛÜÜùÚ°Õ<_¢ìÊå'›¹Ž+îû4üØ]¨VÆ'¶ØÅ'àø^®7Ñ…9=3ÈôBÚ '|eÀ+rO0 ‘ÌôvÛ6‘iÎÿ¡0’r£ŽYª ÔÑ¢ÝwûÁ G ûã(Š¿8?4ÀF=‹, ·vYý†ÀzHšGš9÷œIÛ‡;âƒ-Á O“‰ÆD7I`{ûÒwƒƒ0@[ˆTCòë7E¹~uGb=Š `>@Ó^†Pü,Ã÷}ë_o¿¶*O 4Er¤-b #«Ä3r›Ýúä…î#î?9 ÄÜ4ÚT0’â\dÓÁ­IýR(Æâ½FS[?ÏCe{LF)ŽÂQ&ì4ÙÞÆ¾Ù¾næ¡ã§'¦°±àèôÜñ¯,=²ˆßùHÙÐ>>òqá£ÙRíéI«¶¼\è,s!ki)¬, –¦ø4M çŠÅêRØï´¥â²’ Óˆ>a°emD7 8¾3ž1ìseó$9Çv›­1s½ØJ"&a/Ò’ÉÛ"xƒ&OçžÏ};wF¯pâÑx%þ^gâ þþjèêBåP´ mZ{Oõ‚p z=ð7DuUOë+ú5}U¿§?Ô™‚>«MÞø‹þ‰N=Ю?¿¬ ‚(\0á}®¸„T¼•Be¾r¡òRåû•ŸVþSaÈ ¨¼ÿh«‹ÖâÊ"..^[DS»j I~\Ø5­V¾d§¶\…äï&s»$}1ý÷çzúânñ¾îü¡Ü¢/{î€K•úc®8‘þº‚:Pç»ßÚÕÕYÞU×@#ê„¢x"îм[»R`ç­ØÍ÷vÝuœ·× F©:õ¨èm)ÊcãIV¡paÂK+çÛO´ìÙ]— vtÈÏFº\¨M]m¹úê©Îl7À¥×Ùb8ˆc‚”‘]/÷·g¤¸òTBÄÐ#¥)–á¨Û?ºp÷Å«$#†ÛÐMãÂa³sSƒRA‹ÑëÉÆ}(ËÓ0ùcÉ4ŽÓÑ@÷½w¯¤]<´yúy#†³Î%ßo?Ò)·†¯‹&\é ÔM¹(”*~¶z›$ÂÎ¥Ô…Õ0™ƒÝ ¤ÁM –µH‚-/#Ó3 †E“›Z¬¡N¸3f_3h6ÛHÞŸ&4HÿC,¯³À`WØï±?cï³ë,c-em»f9€ÌUçÐ9;î×ʶóÖÁ±}"£À¸8š¸ C­€½ÙZ˜6|å™K}ð5è#>øØ_veÓ¦†ÖÝ÷u¤ ^>^ÈDoÀv^ ßN±«w?è¾0*vv}îÏn  Øuêæ¸̆ †6$0 a*¦¦Pµ‡—…ôð±±Þ$üÉÁ0 ­UžèéŒì9ÈPbœ$=8zÊ)‘e|OE=<Î^·/ñ¢J5ÊÁÓÙeY—)ûÙ½ûCKeŠÛç÷`>ÅPŠ%i'<ë㕃zí¬^ÚÌ磒b$F€A^(Œ€4F˼ê–ù>5Bl[¿¶ŒS-‚Œ'â±FÀ$L¼Uý>6ˆS.ÈEnûX6‹Œ!oMGÇIg³`|0 öe°:Úey¤ÁÚ#é$_j'³ #¥}lºk(Ë$e¥ñBÃÆeZYPžS^V®+¤¢$ÁHÿ…¡!$y4YMZÉkÉõ$™LŽß„›*ÃÓ®i©MÇ ËŸmÂÞg«ˆ†Àj›Ÿf×»øÕàºT—ŠŽËŽì#pŽNmN¨ÔN’¢Ô„¸2;ºðD#‚g‡u2²½^7Ä–æx\L\§fN0|ÛÄù©Î¦P›Äø8o`›Â{P@HÁWš:ßM{÷A‡Ó»íëúgûÔ¨DÓ<åg\o J˜ÿ¥Áy÷¹ÓÑFoÌÇÚöH<`¸cÍKÃ.²Að3n”Á9Úôçÿ»õk´V ‚½Zðd{»Þ„ðß¡qdš‰\=‹ ²ÁY*Ó @—ãÈPOèèéA0dlû¯Ä:q(2Œ¼e0{Ó]¶ q»VŠ-3Ã%M»Ne2 'ñÿìW{L[×ÿ{¯àËÅ66~ÄÀ¿ƒ@  #†<Ü4$¡ "[Òæ6ɲf+I›JUÓ ejÔ?º$J§4)ËHBœ¥Z--“Ö.ÓPUmR¥mÖ–?ªiHUÇ:m³ïÚÎkÕšuû§pìß½Ÿ¿s|Îw¾×9ßÙ,Mú“«‚u••³&Ølt™VWç« .rÁ £¼½Â'w——;º}C>ΗàähaCƒã ‰™N‹GLÌqZH°dÔÒ/ŽŠcâYñ’˜SâÇ¢6&Ž‹œˆ÷.Ìöêz Jö§Çœ!{©!«Rì*Ä$›”‚É)B‚Ñlâg…‹«]– 3›ŒB8ä2ÖG8—¥Èé§*U¹Í(Ö³P¼¡>*`3y½‘Ͽ̶¼óvz2‘HÿðíwØ–©7ÒïM^`‘‰ Va2ýÞ “×õÝý›ÇªJ+§_ýé÷Ks?OÿY?ô·n´‰úbjïµô…ë‰ôälsâ:ë¾Ö:‘~÷üDúÖÅ‹4ËyÖ8‘Ltè@g“ï•M¼{®èŒ¿žd…¢]kpŽ 2÷¢ðKè`çG|a‚Y¯šÍyê“T²x¯OŠ¢ÍªhavnýB m;B.GN¨$÷}4ûmÈå …\Îpz"ätFÂNgXxÚKW8Tá …•^(•ëD6M ¿‚ßðÿ­À‘€Ù`_n.ë??bÓ½$]ïäW™!£ £Qƒ[0"8\›j4K©hã09A0*&Û†Á»ËÛxgœJ¤ò©Ê‘æ;qÕ!€‹›‰5çÔ9¢Ž˜ã’#éP¥×Œƒwè´_˜'›£—E Rû‚òÕ/ܦ +æ½{èÞ ¾ìVý”()˺ïÜT‹ìödzÃìˆVØn«·ôù’ʯR»ëZ«ª7…×5õs%LíE½FU,JUµM¾µ»žX=àP™y*]¹ÚW*—™$žÜÞ¦êþŽÍF1_[‰õ%*ïs׬ØÝÛùree»!ÞÃN¨,dÁ¾)¦ƒ¢1©ÎOyõHFAICÝX|T—f$>*JcDž•.IIbhõ’,ÕIQ)&õK#QšŠÏ7Q@Ì¢ô¢_0JŠ2 ‰N S“=9²{Þ«Š®õJz½¾Í°UyÖïû=ïñ—µ¬²ÚËL&>(»ÌÎ=|ã&ÉÚ›~=‡—QŒîk yÃÚTTO_IB)R$­ïJJa:ž ÔQ3#2Y¬£bLì'žZTJ’œ„ûYŸ‘O£Þ¥Úµã>ñoO¿î<*1qAÙivíézv¨K‰‡öôi>ŠïÀŒZ \¶Ð…:ÁlSÎaí fC N'‹‡a©"a¯ÈÅ–¸LÎvY§ÊJoБàQ]L7ªKê„_阎Ül¾‰dÔÏe^Ù)š2¤È›9¬½~ÊJWjµª>£aoÆË&%r¯p‡ËÂÃ3e þˆÜR7΂7ËŒQ_YC½Ãän®\ÕP•>ã\é\á§My]²'dr6ÅÞð;û¾Ve“ ó*Jj#š‚À¶pó˜‹B?ÓÖ=&N‘þqª=„$ Þ hô€ö /äÛ  ó€Žþ+® ü€” oJýE´Žé{€ù×€e °N¶À.ˆoŸ–¸‡’?eÓ€üPqp¥ÏŸ€ÊPMëÖäµ´V½ƒtÂDŽ ŸË‹&·bh}h+Ú)Õt»€µQ «ØpØDˆÑc$û£oæð~ݺ­OÛ>zúÐ[ ô‘Ìý¯¿iÿ»i/_íö¬ö’^žœö/F®_§ùã´ÎÓëƒà0ÍñÌÇÀ·µÀ³c_2Lþw8ºßÿ’a&‹cŸÞÃsç¾8žïŽ×,a KX–°„ÿÊõ=s¿4QG£»"Sã¡T4*/_'H…zƒ±Èd.¶XmöeŽ’Ò2¹œ.„n·²ªÚWSëÔCáH}Cãò¦æ-­+Û¢è@çªÕkÖ>²®ký†›bn~lK÷ÖmÛ{ß±³7·ÂMüì¯Ñmm곂¼ôpY¿h;ª<Ð-.ªgú8±½èÃ7q Ïã$U§pór‘l“í²C.]\¤Ñ2”£ÕD¿ÚÑÞNô­ˆìÙ?øù?3[nÇzlÀFø°†'ìÃöc›±Ã8€'3üÏûÿôf5ÁÂ'hÁûPÑnõ ™TÓÌý-Ø8õhã#ãÙ7†8#ýýnûw•·Q£âSƼ–¦Å-Ímþ©œæ9ÛkÙ²ób_aË_±L›ý–t&3Ã[‡:BéÛ '´G5·é§b‹ ÿ_w©Mh endstream endobj 424 0 obj << /Filter /FlateDecode /Length 13148 /Length1 20080 >> stream H‰œVlÓÇgûk›¨I ˜6_B N0A`Õ±IH d³vâP“%#%a6@ª®C8°Ž©€Ù¨TµûоahÍØ4e+-Ó¤°i-ë?«¶ieE*S§‰N¬-ñ>ï|_×ÉØªÎÊçûÞÝ»{÷îsïÞ…M¡>²Rã¦ÇüË›ë#>¢Go¡wcKG¬sÕ݆_mx‹H|¯åkÝžÐԆͰýí}»;Ÿèø`럂D–F"-ï‰öƒ»Wÿ¨è*ÑÒ·­±øõ•îµpU‰9+è(º:y‘ãq´$:ºÜ«¾A»(¯»}oKliõZÌ ¦àoMGì@§öŠígˆçWïùj¬£uò‘öR¢ØÅ’ν]݈¿†lïÜ×Úùj÷Ë¢iwÓuí ͤêœï¸Ÿm!•PQú=n¥oÉ/ô±öôM¬Žñc{Ò·´7áé_餼™¾MŸëçTø¬Ÿ(gÄâŒÒ›D¡ÔÐ#ây¨Iª#-Ý“~5ý1 ÐèMé—Ó[.XçŒstzåÌ×7DfïÌÕ±Sßë™7wÎl÷¬™%Å3¦Ls=0uÊäü¼IN‡]³Y-‚Ê„QÍtøÜ^¯7R®Ú³Æ· k©ë^ƒ Ü^}ZEv”{¬ÙÚs&´çfÛ *2Bz †=Qè¯¢È ^F>Š¥Ô¤`¼Mî1fâÑ(fÔè.ú»_Æ¢|åçô@k^y ååC͇†±C"´VHÅ ®²sJy™Qà3,¥AF›QÝ…¢×À,…ŸZ†Ó#ÇsM„i¦V˜Ñ„a¹®gQ3¨ß3T6’<>ì¢æ¨or\Çu1Ä8DÖÒ`¢‰‰ 2¢ aƒsùq£ÇLx’:ÓLDñÕk0ë¾ýèžõޏÈ 1Íg¬ÇˆõO½ë¶&ƒ%{<ÜL&zŒ—6‡s­^þF"‘œ êpgÁ¶G°•yYfOŠ€x´×l‹qœÁ6O²¿UÆz\Æ ‡|0Õý±Ï˜Lãz0‹?’Y `T7IAMÛÃr`¯&¢ºÔXlÒ­‰x3|×o 86=VãΜ|¶'ªzÐ4Ž  O‹Ç -aC+ùÓZIÉ–J™?ÞˆÀ¬ÆOgZ©K÷$?$CDõ¿ÝßS=öRׇÄjHE“Éî %£ÉØpº¯Y÷¸ôäP}}²3ŪaÌN_éw¡ãÃMˆU Ÿ“ ´%¼Îí1›f“UÈ­|¹°€¿:%À25…½µ5qƒ§0ëMÐ3’s ¹[‰cV´1G­•YzJõz9Aû‡«© £os8ÓöP³ûUû}8([FLËô­lé3-ÙéQ«\&~ѦÎ…Ù¿\3 ƒ‰U†˜ñ?Ì­»Q[Ý–HF³¸­¬åùpÙ×Å>èù’8„ßê†Ëghðˆ{MÄ㚆*ÀÇ÷˜^¿y{8³1.èþ×ï}ìµ±®±î)}rñœŸåE»© (\ ^O­–ÖhÛh%^Ç:k©¢­¨õ@£­‹†`?Âcr)«H`|ðCžÔ‹° ø²²¯Wózáã+Àa ÝöªÓn§?²W‘8Ä€sÚ5:…9)ûÚ ¤°þy´uÖ!O;NÐIègûK5o=àG›}iNJ§!­ìýóá稥*ý¤ë²Qúbâ=Ô‡€ jµãRýOcLÒr!}NéÇÀÏaÖsæÕZOÐì§²íèÄi…ž]¥ð9 œ½YŒõ[Ô¾1Þ³¹'Ž_ù¾²1šÈÄG1¾ ŒåÄ6=pÂZ!%û|øòà²}”Ž²Ý¾›V1ß¡ðÿŠô]KÍàõ2bÔmTÈ9Á}Àm›\û|lÕ.“Ï~Š–h}Tañ¥ïa/Pl¿AßAއÏ_åÄa[\æI)ób»I³ ïbl/çh–+ðƒ¾õÀj>?Ärë=Ì·!Çd½C~æçˆmc]ðU€µŠÙЋN¨<ñ|þ¯IåÊ)S28ÿ€¹@%°ZÑûVŒWçeBå ŸÃmè¼&ß±aȸj/R<|¥ÙÎy˹Ã9ÊyÂ9"×ßFõ,yœç2×2|—|v3€yˆûE…}€¾Ë÷†ù•÷Fù–9†s6%çÌÿêµúh‘Z¯.Gž³Pm–Î5%UtQ Ó1¾‹|X‚¿Œ Ñ1ÎcÎÁ¬|‡VÈ»ªüò]1eÎÞýòî@jD•êô˜Òä&ËÑ@Nýú/ûÛ‹{¾ ÷ñ8;D¡)à<5Û†„râ>;A¦Ž¢M¡Û(îõ ú¶å÷ô,ú%ÈNìûzWã¹À—)Ís¹L)¾ 8/qneÈ»9g ×pž@^T|ë\Ìy |YΟ…­KÖÐjqüçð¾íùΑ¼F×R®gf>ZçÁ¦öÏõ€ï4×n‹çÈεBŽ%¶¿NvÇy²Û,ÅÀ/€R²[çdÆpíçøíU¨™;7Ÿ×e~8‡¥^%멬û°T÷.%ïÅ5)ýrL\žƒÕq’¶¨ù•2ÎÚhk–y/ë¹Ì)ôir­–ukÛ­ƒèËðÙ¤Æ= û'fMWö:í¼¬‡lUh‚¹.Ùîq¸qÞ~šêh‚~’k³ôÝcÖ_îã=:´Bîy'rg¡j ¿ú¤A²)Ço0æm:­Ei²ÉÊòuïû2ß3².ÉÄsì{³|¥r¹RoŸ}š\ÙÿŒ1{é¨r’›RNU8Ï£o°“ÖMªü"ÙÌ÷Çvœ¸‡ 4•ó~œà²Aûú:ø»Bnœû1¼ÇrÞùÆ2WœCN7æà}Ôž£ýðÕåHÑ~Ç%Úo÷‘Ó:b»+ç®sŒB“¹V«%p?8ÙòWÕÛ1¾Îbr;ý˜ƒ1ƒ¬›|nOÒiëÏùÝÎäðDiæ´ë…| Òw0/‘÷jÁ(mWµu° ø:úÎÊ7kÔ2×6*„6˜~ßöOqU´ô±þŸr"Ä/36–Œ\Ûçíÿ`y[¤„†‰\!ìç›üö9ÞK)Ñ?ô ‹Äç¿ù®úØ&Î3þ~܇}±}>Ÿï|±ã\ŒIh8Â_p0Ͱ…‚²AøLøpi I¡d„¯ØHí…4e4tÐA@•¦jkTi($+hÅ4ª‰† •©­6*u[™Ô 4±ª¢ä²çœ²?6iýü>÷Þ{ïó{~Ïó¾¹·_ä7 ™iGÍìôó=”g† JsÕ¨Ô…pmqϲPЈ:ß™òò}jt¯Zö‚y^ ïQKw«£ÛG;Iÿö|'Ù¡»P&íèTCe¡HgG®ƒtt–nÛ®F¶mÏí ?tFLDÛ·•²ö­J¤¿·o-mÛŒT\jº”¿T¸ôù%VoÃm[zv†<ˆ¼ 88 èôzÝ€  øñþÍú™ž„>Xðèg } ð[½ ýhwBïä‡ñé A}p"+鯎môWo÷L×/æ¦ëGš]úáæÞèm é=€ƒ€|W>—ï¦ÝÍ’žtF[n·Ög$} ‘]/é-kz3 ½?³Ú«? H¬‡Ÿ5€ÌÁH½¢%e¶¨SDKñ$÷,…«U¨© ™ÊŒqºá{¬Z¬šæ›Z)N‰û*bb¹î‹”E½ZiØ«¨!o@zE¿äñx}·Pâáx—‡2¬¾=¢ˆÓâF1'ž™eh]ÆÑÈã.]œëÒiÊ¥£9.½ÉÂ…@#j\5¿ chWÎ/XF#$gE!a4ÜMë[†0~e-ôÈKÃδÌKÚÀ‚uë[†q©ó¸'·-#ã|Ï‘ÈwíÚµF´°¯qeKaGtm¡Á1ŽF×"®Ý»÷ÿçÂçVçW/Üzø cr46&¢eì~4l²¯x¿ûæ€YÀÍäíѨÝ­€' ¹7¯˜ïžœƒà[…"¡YRLªŒI1=¬ WfXô-ª`®8ã&î°,{EŽS™cUüsýM~ØE£}A ÈBXe!âW‚î° º#~5Ä…¥²ñ—jlXBñûdxKdzʃnâuÝÔ£‡8âåCõ`%^Fc©Ç ÊBP–.ÔØ ¦±^2è©N t”2” nŽeü‘A)Æáá‰+çE)é´™î’äè ËÁ&û=AÙí‘©.`QX&QÐ…´@Ï £HñÅ+&à ³Ô¯a¤UhyjfvWÈ2-Óh0³Ù“vJ744XfÖ0v6Œ7|wV/;Óèò_í©9ø_׬ZœÍfåú¸“á á@Šó–£19î@ŠYõññºáOâè’Ïã²E}ïY÷ퟴ¿Xôébû¯K~ŠÿôYݧdÃ8âvû”û«qû+ûøi88ŽF;ìåä:dÊ‹j3å'½oRREÚé^w¯›qÅŽ\ç0ϳù¦\bfÇ&PGét‘¶Ï)~9.àÙu3J•‰Üsc7!,rs%÷À#ÇQW”܆n3kë„if‘Ù`MZ³je(¿G9œÃ p·³ßµ»é‹Eë²Ýsà倽™˜ø8 Ê'°eèŒ`Ý'¸Ý¤G<=[\%B1 s,eJ–H¡ôX:*ºrü´y¸>~Ÿ?õ›{šÙø¸=4rkŹä¶%0{ ÞOºÈXÁŒ€†(A4C 5wšÈŸ$YCšÆ ä‚ý;'æ°DL|ÆG2~t†H¥,P`è$ð=ùx´ˆOÚ[à-ÌKVz×Þ¼ù#7þö}Ч†~ôƒ§ ¼tÁå—L%a¿{Þ¢hÛ L|+ß—¤aeÊ|^¯0àËNcMÓdz>¼ŸÅe4Ìj¬Šáë¢OTÓj¿JU]í$Þ>Ÿ—cG7kR9 ¥²Y£(¡e¦¤P ÈUãd $«s$ã+ç+QލB`c~;WùWžßÜÚ¸´U²·hù¿øÇ»}¯þdåràmœþ¤çåy 6n:ûõ{ÏnúˇîÿlõõN4‹!‰>A,p³ì‚¦Îªâ‘*gS 6Síö$«2±¦X>v4Vˆ]‰}ãc±„µ—Á3>¤i‘¹Tžøæ29|ÛÎA1<À:F[¶®®Y²üÐÃë×¾|í1|Bk[ºâG[×Õ®R¦ÈMÛš-^Ç_½õÆÆSsÿMwµ5u¥á{ιÉÍÍÍ‹›ðˆH‚.H ‘–ʵº`”*,#ÖG‹¢%WAA­¸±UL]Ѝ­vw:}l»vëú¨ÛµîŒhkÛÕÝ麭³²Ñ:->»În˽ìn‚ÒÎtÂäf2CÎùÿïû¿ïûã“'ïmèú²³æXØÛ^Û¶¬!”„Ò4 ¥3*À|eCÆÌQ9jdÚ¤ƒÑ¸ Æ„CŒàÍ22N/&ÄÇòÏBúK`/´WŽäo—~þŒþ¶žuêCðµÞ(a”‹;U27{`ƪäƒR€×ž4¨87ê*,ø ¹âàl#ÎeGˆXäqøª?yRyQiC"šGZ†Û•³ÊM<}¢x€3€ZØa&0a)×͸ nàÖs˜å&¸ÖÄ:²Ù¯÷:úCÜUsIì7ÙÉFk¥gäX2[¼?T‹tP Â@D &ØÂÖ4k ZjŽ1tUòËQ$é;…ðT…j 7 câm˜ ñw€„áø9/7§ÍÜ>ý w)ò…ÈÅÈ¢tÐÜT>? <ê›8EyEsJùݧS¹a·òÍNßš+&ׯØÒµm£#Þ—xUCå&À+™ÉbÖHe=î×í¸Uè°Np3H‚A@ˆuÓÒÝý‚àdû휳_´;ÒtAtà “6›JL=&bÊ6±.œ01á:qQ;‚ò†r¨Á7Z¡æGH­#V#%k:ŽSE!ÛCž²·”FË_½/Ëêß¿ü,2‡ï¸¢Ü?„梬#uË…m *V‡ªæ¯eCùóK—Íújv™òÅ_#·Û_@~dF»PsåÁa¹uÇÆ ›¶n¦Z°8ÊÚF¦HJÇ‘Oj7|nÀ¸?Ï͸÷`‚Í„Ëd¤åäPlr)J99jZ¸»–¸Æ!«k1ûÊ•›ýØ”Uy¼*O‚®=÷Ës÷~¯(hº†âÁ¹FÇÁLd ™_K‚Ö‰Ö;Ûh1}J9 B®~ r·çŒgÐCœÉSáéòìñh<žÌÉý‰öÌ~—‰Ñ›M¹ç…m㯳Ø,æeAuÙãÓÃW…[„¼°Y,{D"úÄ N ²ˆe³Ãã½ãcT Ä` P™¡PÆP2Ð òRTD¹ØŒÀÎ |^U^ nU]0U—ÂïX°È˜ÏÈ_7©ø­GndŸš½¨uÝò½Ÿoºq¿« ÔÎ+]TãŸHX_îÿéº'Ê›‰ÍSR:¹nÑàõÕRqÑ{-MﯜÒtù™-GQey`‰¿¼6 —,mï¨[º© x[6r‰ñv£$v¹Q›°XkIT© ­<c/íê”1 ¶ƒ9ð+ ñ“Ê“:3ÊhÓDÓ¨ hƒTØ¿ÏáJb«:’>¯²—), \fEJbh R»¯v¤õZÊ}Où²lÀáåÎλ'® ý!åå³#ºñ…¶êÊÆ`Uu ò{æ—Öû¿šSŠ’.?»½O9ia­ÒSyàðÆvÊaÌøÁ÷G· ˜[ëB™kMÈdúDÖ u dÊ)1ÁKŸ'x³7ù­TÑD¿‹OðÒ§”h0zÛâ6³n[BBÊvs]êáTœ ! ²îP.¥D¥ƒœ““Ÿ ÎP•ÉEËôyG-Ú  ™Gµh h‰Sž™´`_åôÇËFe“ F0éoÝÇk"Ë •VÔ§<>v/ݰlóã>ßc5ëò.#ÍâöOæ¿ÔR±ô¨Ò•Á¦¥ÓɇüJÊósè²ùuÕ¨Zß­gu ÇñzH€¼†ç¸-ZM › $ç-„…DÈò´´"‹Í˳ú½¾¢¨aI7 k1Fz–GÐ2~ þSÒ"ˆÚâÏð„·CõØf šÀ$RÜÕÅ%:ü9±`I7ú°œ-Þa)>¼Ì&ËÃeÊœ‰nâLÅýê/^¾{Wsê›Rœ‹ÍòºAöýj´3˜•Ò,7šZðz-Ôg³Ø°-bÉ¨ÈØ“A,RÆ¥ „7œ‘áHŽ0ıŠ!]+p=©ƒe]B¦Ä6G§ÕmmÒÊÅ*q凔…}l(Pµ”ü„ã«ÊWš+æ(9(nôC©øô_•Þ•/õ®ZR´¶?ø.úp`UUÕŠ®¯««m½¦9õç[ÓÒÝï>×r¼Ðe¶‘vÿ¥YÃoT•NŸGõuéÈ5Í=àf 3Kšü3ÍHœY,ñ‹ò˜: qrDcµt˜ÍLr¢ ¶wð©|Ì7èØ1Qº=$†ªMÔœl¢Æ5èp± hWÖ›#·”?]AÛÐS(=ö„ŠOt7ÍÜÿ“i?ïÞº/h{u°åYTƒâÐj´cð‹…3R ¦nZ2ðõ±çé<Dþ¡zB"3Q²› ÑæˆQÌÔ"[‡Ö® bs§1ÉØ»a´·ÔÀ«Dðçh+ãÔ´sq¿|þ?‡g5ž^Ó»A®EÁÝm3÷½­9µú‚òõ _*òGÛ4|µäÅ·o¼I;Ö §? § L•4•a-,f#®‚ÛÆËã$îÇá ‚‡ŽÀÕtA:kõFȬ®S0£ØCBÊýòÑm*>¶)ö²§eþƒ\BLßR›:Cù‹rUù-½Å>ДÿÂ-xf¶”ÿ·¸Ä!@z^„5C@êù¼žp>œþýã¯}l¼O•?PŠààFùL~ž[3r]뾸 ú<'0\ËH¼àe"9¬¼"fÖÑZr޳uX­ÎN’F‚x\‡~‚~ ehPÝ%D*Ôq4ME×-›æLÇ…"8 –¨Fy|…¤¿÷¡òѧʷʉcçÞï¾wçP–2gü–e½¿9z¸|çBlESäžpý;¨îß·Qý’²'ßÝ=·êÉ‹ƒ7?žT¸3Ú9­Uů@JÁ{ƒ<ây‚'ˆ,ש5j›@zÆ¢$«ÂB³ýÐØA—к…Î+EJœò¨æ”<‚(G¥|„vê5 jœC·”Ô£¹¨Á !"îì%h:›t,¢‹iÉhˆ| S¡úC!mä{ZUž4ɪ 4–!ÖN›°Ð¡W»I„.R­‹fÏÿS]-@Q]gøœsïÙûØu½{ï²@ØuÙ%°ò¶‹4×G *Òj,RT¦êøH‚¤Õ`t»M¤ Xð&Ñ•T àÙ àYg¥£É±NÑ,”¨©µÉàÜ\oÈ~Èh6á^¼?‡÷c§ïÜcïý_<ôòOÞúeÏž_‚ïe/°7Ù8;uêMüôøÐù³_]9wž³þ~¨âf¨‚ óP`¦­ÚU¸MÕ§ÆÅ4(§¡$T·ú@WSÔ6Áü ¥b"æÝOþûÕ]v—ݺÇ*𥖮ßKtÐ37ÿ>tlXXØXóäjd!ÓhÛ È¤¡|ô‚Y+ŠxCx[˜Tg6„× ×Ââ¾ðž yÂ1C ªIÌH ÚíÆ2¢`±C¾pV$’%о¸{†¬}Üu~Í…p‹ºU]ËÀÀp×P^þ1åU<^W‚©¶…¹W Øp N‹Ë#¹å|äéÑeé¹ó~´êL¸ïûõûŸã¼?‹÷1;”Ü}ø`Oa^ÅöšªùÍÞ«•S=ÓXa"0÷íËx Þˆ“¬½ÂÞ 7¿?töüåÿœWÊK~n,ÐRzk¹”“Ä‚KGú.kv—á×.W n‹@¿äø`¡r>P èê&kô-ú‡Âjmg|sI(sqÝž°@/œÒ p¢ØÏͼ%áQüŽ{i}ããkŸ ûWiŸ0ô¿Âœ’9Ën(¨X±ã=óÍ {_}옰ޭ,*®©å,)…nƒZÏ@¿3c;§ÿ6½ëÍ - í Ñì—BdJЩwª¯ÎG®ø°Ï—‘t‹°ÕĤ`‚-oðñ0UÕ†&óO~­ýÍg‚›÷Ž^9)Œ´XÛL¾ÃqdžBYq­@K¥š(; ª(o‹¨Õ"|Ê'üVkªQ`ê Þ(V{çFrsxŒå”qÿ•ÒOè"æÞôÕàwœÑêÎæ ¥¥'ÙÕD{–®¢¹™l™ëÙÕuõÁ@ÎÃxËìÆßØÙ0¾ž±¡¼¡±ª¢ à±ù--G[?üÁ_?÷ÅüâPæ4¿Ùu¾mß­í8Àq,‚9íµ2Á4ÓI$˜PªK„ˆ ‰ñ´Â=ÇXÕ×BZD›Y)«d¥`4úFŽ‹õpWÇ¿°¹á>ThN>² ÕIKÊÒ_‚¤ƒþ鉩þ©›pôOkÓ„:1¼é… €ëOPXŸ:¶jçéMcGö¥çãÁî­[º û:¿<*Éj8¸|ï3ÂÆÑŽ¶ÝÝ/Âÿ§Ðñ ÃȆºÌº“`ÿ!ÂØl~걉T´D-壠|ÔF0î@67ì 6QÀp\›.P"Ú0Y…pú)ú7x$n&½d€d2¶<£_ñ µ<ÊèxÒAe-µ Rü¼?‰ÿ46ÌÒ@œ>³-Ÿ0>ŽŒ¹>á¢ÓÈÍf@*¼ì’÷8@©œ®˜+U,r䨒c:ÄFa©¸IX#Š3I%]@Sq€ Pžéh;iO}ŠÐãä8(ïìIA› NÑÖ+Én0¹@xŠê„U ¤Ó®ºíÛU8ˆoÈÐ8ÔwÇÿb~C3b„ª‚CšJVì]¶Y¶B¯*ØUì,FõИøX!U£¶6­m£m©5Ø™Èà´›>LÚ$ÕI3Ik': £Ó$5mØCç®NóÇrî°{Îï÷ý}¿ŸÓO6ÿ¾}Ý¢i³I u7Í®^µbÆ\¸°NUÉ]òõò V˜·êvìoÛþrÇÖ6Pt dŸzíaæ«åå|™´_ qÏ3H–ƒ RWB¡ëLV‚w„™r!¬°JL–¡cQ3Έ 9ÂÚ‘Û]Šc*Š´„‚y¥¾Ì[0õdèô)4:—èöÙ£(æ9ò÷‹ç?ùÎÒòq‡fm»‚8$•‘ݶåukÚw6Öm@§'lÿéÊðKo:·¡nWöÄ+=%Óg>ÛWOk_5t‡» µ—˜1LÔž[Âa–Ö^¤µ×Ì ›%FI˜ÅŒ„ÞÁ‘,ˆVkH m7[BØ&ÅQ6ŠbWLÈzt¢$Õeàÿ{p]ªÉ—Š6*KÉ>Bd!î&‰ÕM]¸þæ?’×–Ÿ¨d[æ<Õ¸ªº6Jïv§V碚ϹT .moÛzà…í;žDë„ zQÜø—=ÈsX"S…ÙÊLÈ"µcmù„ÙQ.!c‚àŽ1c™fŒb{£Ú¦y4U­0VE4*5^€Éá Æú 7LN1gS¼´10B¼cð†iüË+C9>tx)üüOÿ:ÂÈ}:ÉÊ´¦y+&{taepF–=è=s`b/þMê$ÿ}7±uí3Aˆ?’]Tåb–©^Éj3\”‘¬-!9aEXß V^ÑÛ°„¡9\\ÐkQãt…´¼C[Žx ž@Ie²²Ž 7p&-à8%ð=¼JJ'=‰KŠzÚ ½«ýý$ÚÝùÌ=ë~WP]PxÎGÞOrx~ëäª)î§yýêyd÷!T? 2ª¥)çÖçbUP•R}` þt‹Å¬íТë/Œ€wætmÌ8è’-aÈô'Ò 9"cmÎÚŸ…™€ÇÅ8Š-1“ÉËš˜5b~IÃEá$íQ e{)¥¥¨Æ)Ãy¨Óñ)Ì›‚4ñQÎÓÔ7ÚØe¨5¼tó 黇ÑkvÁô… *+—mx/¹ß¿óìL²{eÝÓMëkk#œoP)Z}icqßYylA™’½lËÙ§<ÅW^¼ùâæ­ ßÞôì¦Í›ÛZiîµÅ|Sfgæô2üÐýð}jn=é©ÕéL™Ý£ÂŒ¥‹‡î vEˆc#[Ü.Û׌ÜÏ*%:\ags(ÐÃÔI9m¨k_%M5Ój–ð°äíù5¿}'ÁU«çn˜/ÓÒËà¡=ÎLÊ™÷{ fÚ úà©·À¼0¯Lõt™@V1Ýk³ÆEƒ;.^NGyñô˳½W½÷¼¬×祧ܨ(º¬ÐDB¼m«Š’¢€¹ä?Ô <¥2EÊé@;ë¿¿u×±¢Æ×6ÿ¨D3ÇM©ZH¢³˜¹˜D9߉õ‹Eg½ý—ä©Ê-‹nJ~ˆ«gºý[¶'ÿ6¬v8yºç2ø7G úPè–GB·~“Ð*zddÿ ½­áBûùa¡s¾7Z–\÷qS3Ã~ÌŒ›)V=!Ó—±åv&XQJ9¦ÏÐ7ƒ¿0éÌÚዤuˆÜÝã„û,ù¾ÑnQª…¿#¿$Ÿ 1¯õ£îM ¶>7oÑf,~ŽžèMÜú’üæ…³Hwhßžc{÷k´CÖóØ MÜÕ4‰Ç¦h‡¥uqД!*fd…´!uLäìW=4t©&\4xE]ÈÚl¡CÄœFðçC×c~(¶)"…/_bãŸöÙS­ï.é_vbŠ–¹««j£°Õ+§Vå‘+÷ÉrW ž=×±cËÁÝ4s³  Î"2³zÚ›jsŸš>¦ÇŒA´‹Ê¯2ôÁME@¾"%Q“ë@E1€µðð€vM%T'«A)tyj/Û2ñºŽªñu¤‰ó]hm('eM ‘“°’¡O¹“°Bæ‹^&oè {>º#<˜]&}w_Í!krM^Žs¹Üª(†Üª „Üî1ªE 9"Ã#M²#¤­VQ[// ¤]E&ÃrG&8ܢâÎ+Ä}®n‘Õ>Ö/ºUÅ Ÿ*Ùà‡ÉrÇ\.CÌô[Є_j+üž®ªþÅÆ‹ÄáT †$j[ BJhŒS4Ôž æœÝÃÅ,`÷f!Ê#¥0Ðùiù²“÷¥\vúcE¶ Ât̽xV}AnaΡ?¯uÇû?ëÒv?é°æ§Ïûý{Þþuó³÷þ@þúù|UOæ¦çOpInoøxcs÷¬É;¢¾—gbn¾,‹Îúî%K/4½N•P>t‡mt2 ªï:ƒœŒb’ÓŒ ‹ƒ•»±Þ-›ÒX6áãN¹ÏvƵÄ7ZÝ!Æ„wE‘@ë#Ha…0ÊŒ”Rd»ìÞ…¨T#¼öãÍrqÁœ¬®X÷+3އ8ZO> {§;Ʀ“OsjOÿ mEã®Ñ=nÖ½ÅùÀ—JÔlì¡„ÀH±­`=ŒÂD±)n kì°M ŽC¥P?¸2ý¤&GÊán‘ÞèøÁUôjÍ´êêúqËâëïàsÉ7WÏÛx Ño âîÀ·ê˜.µ±úíWklTE>3ssì«»í*»…RKYBik±È¶ -Ï(–ZšÆšÒ*P0>B54%J ƒDª‘ÚTƒ ˆF,Š¢1"M° µ| îÅ3÷nªˆ&þÑ0'wï¹3ÓÓùΜ9çvT¡§”sä ÆRåd…j²¢”@H²¤P±6K2AY¡„4ƒâÇ¢G‰pËJ€ÉÔ#•JTR ÁÛvÅÚ£XL%šŠ…/;;Ej‡×§úa!(ðå‹Ú×¼úH3V>|‘÷ÃàZ‘”>ˆ¤“tJvø yÊšhm“2ã•ô,ê¸~†µj®ß„s‚»tíÕÎ÷¡"QC.aÍ\ÒFiQºŽÇP‘„Ó®r¿ªrI–×iºj:£t¡û J ÊH;˜ˆÐlÔ •ufªR®f€+H d9¬.QU¦2C'&¥z–!p±¨°ӗ躤#êh„íÈŠ(‚6þ‚+õŸ‹úÏÑ r?ßb=‚ÙÏ”íÛ-’òxÇI²¬§ƒ4[[[Ot[[ÐCÕt‡x.}J×Äž2ÿLGOp_l²Ÿ®¢Ç(ã’ÝF…xtd/wÄ…œ4… v ïåܺi´-ë`›Ö56é ÛºmÛ›m‹æÛÌÚ¯¨Ão'yC§’½Û_«\µPî–?¶ö<1×6Í|Ý'd0‰²˜ ܰ!Ÿ±g&¸Ü¯/ÉHN ¦”fŒa™ÃGŒ5&:ÆeÏÉÍ»5ÂmΟÁ”;¦—L›>c&Ì.3wÞ0Á²Ew•/®¸Þ¿Ü÷Ê—õï5 6âï`ð T„a(Œ,J0 ¹|%ÔÂrx¶„Ó·`ý{|Dp¼Jq¼ ê 6;ã—Ïü™@zOkOkÂûÕØ gp¨IØaàHè꾄® –!vXÒ°'ˆLÁÑ)b›ÐÎXœÐ%Ôº‚ú³E……3'ω6ÔVÕgÕWU×ýÜçB”™0æ w Ñ'µè›z˜÷À½ðjUØw½YY8"fTÃõ-ýÓ9¶wèø  dô€QÈþµl¢s$ q„K¨‰¯¾7ÔPô.¹Ò~¿ “°A ca ·x[™Ø ZSÓ–Z°£Ò]ð âöìçævý(ÞoÞÝi­Œ¯ÐÈ;ðÓ苈ß´}= endstream endobj 425 0 obj << /N 3 /Alternate /DeviceRGB /Length 2341 /Filter /FlateDecode >> stream H‰ìTwTÓY~¿’žP’ ´PÐK©¡…"Eº(`J¨AD)Š""MDPP±!Ett±ŒefÔ90FY—)ˆmt3®»Ç³»ÿÌü»ûó½{Ͻ÷ûîûãw]Ê„U1Dºš'Ò°ŒdŸþÿYkeÂÆ²È‘ÑDF.ø?þ×€~–ßœS…ƒèhâç}äÿ(¶•0aaòÓ$ˆr„ŸRS'Ÿekaok˵4µ`yˆã¥i¹¬ow–0#-CšÍÊÉŒŠX\Vެö™ÇŸþ÷{˜„ˆEÙ"‰L.å‹%I,~†$Aœ+ΰÄ–lÛ¿–}æð'eÿ†<™ôcBëz豦@á ½ P 1m²Íú8ãOA²¡õ4]ŸóÉúOW¸ö÷#GœôQÇ e ¥Ùyÿè}| @ò€T&І²oÁØGà d YB<Èò„ü¡( Šƒ’ $…Š¡íP5T5CPt:]®Cw o 9húz#0¦Ã°ló`7Ø…7ÀIp\—Ã{àF¸>ÁWàð}x~¯ !! Dá"<„"ÑH"’lEª¤éGF‘iä+dYB^£X”†²P.êˆú a¨ÍB·¢5h3zB'ѯÐ9t}¡`Ô1ÆŒ‰IÂäc*0 ˜nÌYÌæ>fó‹Å2°l¬Ö…MÁak°‡°Ø1ìì9†,%ï!#‘¿!ÿB¡P (®”hJ.e¥‡2AùŽòJŽ&g*'K+‘k‘’»+÷Bž ¯/ï&¿Q¾P¾AþŒü-ù%‚‚_!^a«B‹Â9…‡ +Š4E Å@ÅtÅÅ^ÅëŠÏ¨8ªÕ“š@-§¡NPçiM—Ƨ iÛi]´)ÚKgÓôz5ý$}†¾¬DU²V W*PjQº¨4Ë@ #QËd<`¼QÖPvS)W*÷+ßU^UQSqU©T© ¨ÜWy£ÊRõTMUݧ:¬ú„‰29Ì`f>³9Å\R£«9ª ÕªÔÕ¾U‡Õ9ê!êEêGÔoª¯hhjxkdj4iLh,i24]5S4ë5/i.jÑ´œµÄZõZ—µ~d)±ÜXi¬FÖ$kY[]ÛG[ªÝ¡=£ýV‡­¦S¦3 óD—¨ËÓMÔ­××]ÖÓÒ Ð+ÖëÓûVŸ ÏÓOÖ?¨?­¿jÀ6ˆ0Øi0lðŒ­Â° Ù}ìdžCÃ,ÃNÃ{FX#žQªÑ!£Û˜cÃIæ´pnÃÆ¶ÆbãCÆwL0&ö&“N“‡\2×›ÇíãΙ2LýMËL‡M_˜é™E›í3›6{oncžfÞeþÈ‚jákQf1jñ³%ÇRhÙbyÏŠbåeUb5bõ“µ±µÈºÍúkšM€ÍN›q›ßlíl³mûmíôìâìZíòè¼ ^ ïš=ÆÞݾÄþ‚ýk[‡\‡A‡¿9rS{Ÿ­a¯­éZ3ï¤ãïÔá4ëÌrŽs>ì<ë¢íïÒéò½«®k‚k·ëS7#··n/ÜÍݳÝϺ¯òø[øcˆ‡·G•ÇŒ'Õ3̳Ùó;/¯$¯>¯eoï"ï1ŒŸÏ>Ÿ‡ PÐ#XöµóÝâ;éGö[ç×ì÷½?Ç?Û4ð Øðx­þZÉÚá@(Üø$ˆ”t>ÜüCˆEHqÈô:ÚºØu½ë^†º‡Ö†> 3 “†‡Ë‡Ç„÷„¯FxDÔEÌFšEn‰¼ÅŒGDã¢Ã£»£WÖ{®?°~!Æ&¦"æÁö†‚ ×727¦m¼+{&×÷.>0¾3~e“`Së¦e!_xPø<Á5¡>aQä$ª=MtJ¬K|–ä”´?i1Ù%¹!yIÌ7‹JñIiOYM L=–ú!-"m Ÿ—~NB•¤J&343 2îdgVdÎf9dÈZÎöËîÎr6äŒäÒs3soJ ¥;¤syÎy-y¯òÃóÏ(H nnæl®Üü´Ð«ðhZ$,/Ö..-žÛâ¶¥c+´uÓÖñÝ’ò’…mÞÛŽ—KSKÿRf^VWöëöˆí£ååÛÊçwxïè««È®x¸Óqgû.t—x×L¥UeSåûª„ª/«Í«ªßÕk¾Üm±»q÷‡=‰{fjmkÛöb÷Jö>Øç²ïxb]aÝüþ€ýCõ¬úªú_ĸÞ`ÝÐ~xPzp¶Ñ¿q¤I¯ioÓ»æäæû-î-­ê­•­«‡Ýmsmëo×h¯nsX|øëNƒÎ†#Ø#yG~è ïš>Ê;ÚÓÍì®îþí˜äØìñã“=v==½ê½µ}pŸ´oñD̉Û'=NŽôsû;Õ§À)é©OÇ~0è78~†w¦ÿ ý/ZÏÒÎV AC›‡–‡“‡gG¢Fîœó=7>ê8zö¼éùc´/´\TºX{‰x©ü҇˅—WÆ2Ç–®$]™49qo2xrfÊoêÚU¯«ÓnÓ—¯9]û{Ñ.ÿ¼É:ɹÊ8Ê·Ë6˶Ì5̵Í5͵Î6ζÏ7ϸÐ9кÑ<ѾÒ?ÒÁÓDÓÆÔIÔËÕNÕÑÖUÖØ×\×àØdØèÙlÙñÚvÚûÛ€ÜÜŠÝÝ–ÞÞ¢ß)߯à6à½áDáÌâSâÛãcãëäsäü儿 æ–çç©è2è¼éFéÐê[êåëpëûì†ííœî(î´ï@ïÌðXðåñrñÿòŒóó§ô4ôÂõPõÞömöû÷Šøø¨ù8ùÇúWúçûwüü˜ý)ýºþKþÜÿmÿÿX‹–X endstream endobj 426 0 obj << /Type /ExtGState /SA false /SM 0.02 /OP false /op false /OPM 1 /BG2 /Default /UCR2 /Default /TR2 /Default >> endobj 427 0 obj << /Length 735 /Filter /FlateDecode >> stream H‰Ð/ýŽÂ¸ÉÜ×ÓàÝÎßÛÏåàÑâÞÔáÞÒãßÎä߯àÚæôñüÿÿùýüøÿÿûÿÿúþý÷ÿÿä÷óîøöÿÿÿÿþÿþÿÿþþþçõòíóòþýýÿüýþüüûýüéóñîôóÿþþþþýð÷öëõóüþýýÿþüüûêôòúÿþýýüûûúùùùúúù÷÷÷ÆÆÆªªª‘‘‘ˆˆˆ„„„“““¶¶¶ÝÝÝòòòãããæææóóóåååèèèÞÞÞñññììì………'''JJJ¢¢¢ÍÍÍ    ]]]WWW¾¾¾°°°___‡‡‡ïïïÀÀÀ999ëëëÂÂÂ<<<µµµ£££\\\²²²‰‰‰...···ÁÁÁ888¨¨¨OOO¹¹¹RRRºººîîî¼¼¼»»»âââÛÛÛ½½½¿¿¿ÉÉÉœœœ”””àààøøøáááiiifffsssžžžššš333¡¡¡EEE´´´???®®®===ÕÕÕ{{{NNN­­­ttt444ÒÒÒÄÄÄLLLAAA:::ooo@@@|||ŸŸŸççç$$$ôôôÊÊÊYYYpppÔÔÔMMMÌÌ̬¬¬)))///•••;;;666ÑÑÑ***lll ŠŠŠxxxÈÈȧ§§000ÏÏÏSSSGGGHHHööö›››íííTTT%%%¥¥¥!!!222```’’’nnnÐÐÐêêêØØØ³³³yyyÙÙÙvvv×××ËËËjjjqqqÎÎÎÜÜÜwwwééé©©©õõõ,,,ÚÚÚðððmmmŒŒŒ^^^"""———}}}hhh¦¦¦ƒƒƒ†††¤¤¤€€€‹‹‹ÇÇÇéöóÚÜÛ¦¨¨Ž”–•¨ªªêìëùûúéõòåõòÔçãàñíäòïçóðæðîèòðçñïåïí×äá 0ðÎE endstream endobj 428 0 obj << /Length 675 /Filter /FlateDecode >> stream H‰”kýÿÿÿþþþþþýýýüûûúüüûùùùúúùøøøßßß°°°¢¢¢•••“““”””———ššš³³³›››’’’¸¸¸¶¶¶‘‘‘¬¬¬œœœ™™™»»»‡‡‡²²²çççµµµæææ´´´ÌÌÌååå±±±èèèâââäääÉÉɺººêêê÷÷÷òòòõõõÙÙÙÑÑÑÐÐÐÓÓÓ×××ÒÒÒÕÕÕÔÔÔÄÄÄ}}}pppnnnssslll~~~®®®ÊÊʦ¦¦yyyjjjtttqqqmmmÖÖÖÛÛÛðððëëë¿¿¿ÁÁÁÈÈÈÆÆÆ¾¾¾ÀÀÀÂÂÂÇÇǽ½½bbbïïïžžžaaa... +++RRR­­­ÍÍÍwww EEE©©©"""‰‰‰¼¼¼ËËËàààÏÏψˆˆ444NNNôôôÜÜÜ···ÚÚÚ{{{JJJŒŒŒeeeÞÞÞLLL………&&&éééDDD@@@¹¹¹ccc†††ãããááက€'''```ŽŽŽªªªOOO‹‹‹§§§000%%%BBB^^^ŠŠŠ222$$$***iii£££???///HHHŸŸŸTTT)))¥¥¥dddAAA===WWW¤¤¤ÎÎΨ¨¨]]]<<<YYY VVVSSSxxxPPP¡¡¡ööövvv   íííZZZ888GGG333[[[666ooo555,,,!!!:::\\\gggkkk|||„„„___IIIfff;;;ƒƒƒÝÝÝhhh999MMM‚‚‚KKKìììóóóîîîñññØØØ óf‹ endstream endobj 429 0 obj << /Type /XObject /Subtype /Image /Width 501 /Height 554 /BitsPerComponent 8 /ColorSpace 415 0 R /Length 30799 /Filter /FlateDecode >> stream H‰ìWÅß·á~$$á$]jÛ$¥ ¢u±Ô¶îÌìÌÜ)ÔP#wE°TE­µV VQ¬øƒªP„þ°€µÅjým}³»w¹»Ý»½Óæ.Ù/IØy³3o¾ï}ç¢*ŠªjºÒª¿Š¢•ßýWµ‘½RkOzÕ[¸qƒ~Í›«!j?aܱ~¨r‰*ë?IÕ]Q~hÒÂ~RmæŒë©Ö´¡nQÒÇÚ 2”†1¥x.ª]Uš{¯Ãg«_5wwèT?䘪e´â‡ªTûá‡%uËÒ”%=ªìjCK¸+© Е„f44—1«is³ÈÕ‘\]TŠz“MNÈïÎmŽî%Zã‰:Õ¥0GÕ°(?T) ÕËŽðèD}Ý´ly2•J' “ìí«û¤Ñ× Í °"™Êô,©‘XÙÈ<™Édz“ƒ«n®_ëÍ«“½ÐÙpàʺ}Y2ПIÁô]æGfµîKv‹~dW-©ç¦~$W¤Ö¤VÔÇPvíŠdzMãEuèfŤÒ{†V¯kZ;tª,ÆòîáKÉûúÔ°ª59Ó;µŠ ¹¹†v 9edÃp°±jP§^uâ+[•y»W¶¾ôpD(ÆX0´ªŽI_4Ð+µBLú¢œí²Üók˜ôEÃ-(ËWИôEMíÉlôžcÒ àö1öžcÒ4-¡›F‡½·˜ôEcer³û ¥ÖÁõ­gž×ãFC“\ûò®%7êqª/|T“® ¥oÑTMŸ×Ÿñ¨&]ê½u~WãkA5é sË7T-‘˜ßŸᨑwã6¿)Æ‚FM!%\“¾àQ“é@º×î 5¤7²qAíÞª^S NÑ5U5Ô07dK9ØÕ…¥sá)Üé€.ÃuTR»>Óª¢ÝÜuP6U7Œ@G+¤w;\+9ÞT±Vžë Üi…tÃÐ57Û»^±¢T®¢õý ¹722TWéýÝ E34-ã-fzWë»*UÝg>ìÌ®¸&ÍT%(‡ ­îmJw—8’KïtSCHÕ{tØ`¢,iPüt!t×í+œéjW_æ€ÓoÊ 5–*ÁLvÃ9!›Õo}í+»áJ„ÊVK¤/Ýüí±ñ‰ïLt)¶nýîØ6´ýöwÜqç÷îÛ0Ûjí¼ûû»výàžíæ'Ææa‰7àéØ~’«Õ¤C]«ê!w;Ý¸×Æc„Lê Ë&Øaˆ"DA˜"ŽÚæÁ†ñ˜ã(kš‡©À„!ıÉÚ#?Éé é>¿»Ýow88º?*Ó Ix€tC™0¹ä–ewïùÉ“…ÂÞ©}wï4óÛöC»h›têÿ/Œ™i+Ê>?F,Lúé¸(® oÃó˜ô(yêAÏp(2ÑŽ s˜yèp1ÇwÚ&ٜ۹òÜ݈ nß+gœZVÂYÔ¾²Ä¤7!})ðÝ£IW{~†:òð…:]-d›m/› iˑɢ‡ç23Þ|ÇàTá8ÎôÖÑJ¦?šéšòsBñŽzÊ “…™Xäòí®Äb˜u¤,±)$}ðå 1#Tˆö=IoHúm¥ã÷ëZˆ‘ò D ^(<–7#) Yöx2ÕŸJ?œ‘™‹O”ç+1ÙöŒ1éMHׇ’ëÔ _WžÈíž áüÉBݾ¼C 7àïòLŽ,ä̧üù~Y´¦íbt ð<&½±¼/|ZS•@®«Ê:ç™Îu²$òpýj{)ŠðgýèBŽÓç<Ûç…ä'–÷ÖÑé}éá°â]U½³Âô± ;»Ÿ„rú Ã8¢Tîã¸çÀ‰ ˜ÈMÄ\@—…áÍ}áEf1‹"lqC³U&½„0—*‡Ù\Žv#‰coB;"[^¦¿ÉRv åuï}PÈÉM3²iùìJ0| S –ò>ÉkHOË¡œËv&6"õ¤Ã5T^`=1†L/ªÛ¯%:á¤ëð»)ÕœtE{ñ%O&w;ˆTD}‡^a~’c"·ÑMØ&¸ÁÁ ¿ˆÛPjS‡Ë-BÊ ªˆ,àÏú_Ä6±XŒ  ¯²bâî ñ<¶-ûÔìŽWŠãPôƒ±-0Tþ&„A9CEl1X…œR¾ ŽI80OjHïÇ»+$ȶü?$Ý]mƒ!rÅE^.Û¾4tÂI—gøÊ5÷F‘þ[Ož%˜@~MmÇ‘Ü [¦]ŽI;•ûD½ –û&Ï|.ÃƒÉ µd!iØS&BÇsAÀ* aSRBa»„Pɦ@ïIËMb\™ÀÔÌC2| ì²dAˆ1)%SØ š(\ñžk2º›ãgp¸Àlu¤[K 9&!hxDq©„k¼·‹PÒUE7”¡þ¨L¿uÊß“W‘L08¤\ 7÷yçXd!9侘xÐhæ9rdx`fs™Ã2N€*aQ–w\¢Šr‚±{”dLÉLu˜@ë!L9T08-NJõ²„雌K'žäR©0ph€¤P; Kä^ܺ€~°ÒS4nH‚ÁR=é8Ÿ%%ˆ2,,8cÇÙ'²àì@„’®)P¹mJoŽ ý–‡ü=ÙŠ‹¹¤oDÝ#=ÓŸÎ ¦O ¸IÇéúdþ¥Oa“¨g…%^{tßé×O¿qæð…4Æ[^Mަó¿øæàhêðþ#R (ÀÈÚÙg~÷ÖÙ7Þ^íFŒ ç:2ÓéÌ;éw7ì/á"Ú?8š„“É-û½³ç~?ûJ¤"çHѦØ·í÷|pôé©û¶Ÿ'4OÌZy§ˆe.üaêå‹]r.ã,%, ï ûPu óúó{gOš}â„ñ¶o €py—”.[óbéOüÅß“÷#Ú)ò±]ÒáË~ß_AmÆÎjïuæy[“¦ål¸2wÝÛwÞžFïLæàõÍÀ‰Ž/;Û?¬êºp·£ý†3NɲýbàhiÓÔU¿ý\*G²j®iÄr¯]«º]žÍ ž¯!ýü¦{Êà SO¡ <0]Oºã|zºï¥O*뼺ã\7ê IWEö鿤+7ÝYvÿoÓ†cŽØÙÊ&”9âò¼FlÔO"ÁŠ—>£6qæ#›ô¸‚ާÿþÚÖG ›Îbnùï'äé}Æ{¾8ºwÎðúlø±­‘Ok?Q8–/Õ¾ö³êå\[?W6в9ôøÅšÏ¼õÏñüüq÷¥~¦Ã•Myäs¥)éš²1=çþÕ}—ò²†¦•+Œß1K-Èu‹¤ü÷5”¡Ë+ÏÕ‘0³§ ÌÊù³™úæÞ7%•N—é¹~¥Úð“å9Y^[£>}ÖþzmïÙ’8Ó¡Žü¢nÕ…ëÿZ0gº¢«=ð×hžéŸÿ;ºz ®z3[p¶CÂCYë·îñ¦ÁåI ‘ÿÔQ0¹ ‰d€˜Â (œŠW‚í-÷ªT™ØÛ´‚Ïþ÷2È2Á_Lû’B–ø<Øáâ²\û?ùåþ[ÅqÅñkElü|e¸Ø¥ã_b*¤áX¡€"í™Ù™ÙE ¶Áƒ.Ù­KT¥*17µë„´˜‚ƒ‘b ŠëÐÔ†— ÐBÓÇßÓ3wgïþ°ù^uòìÌÜÙÙó™sÎ÷Èó¨?âÕ© ?çÀ•)LK¦ ïÙVzYìUÕ%ßmÃ×:G}ŠÜ)Ï I¿& ]Já^6—{õŸÔIHBÕT‹Ž &§nKzɹ£å §OUj¹ÿdèÞåXXÒÔ¯oŘ!ªË®hoR8¹ôK.y>tN/D‹†únÜÌœQéë¡Z:mæÐc±Ÿu:umùÆòÆþTÓL5‘âž.iéßêvI×Ï=oo¨Û?¸s0ÚîöĉÁh\Ý…㢲ìÀoþøD8}.]YÞ;4–é×@ZÝíyw^Ðò›ËõÆíë™vÏœ£z;vº8˃.zÌÔ2Ë ‚cæ¶Tc)hJÔRi3‡>7¶Úï„þ듨{Ÿž'ºJÅ S'C¨á%ˆ[°uð&tW*e¬œj`Ô!I ¶ æÿî‚%%°€Žî oÅ>¢Dè{ꡉ¾…’ ”ú$î'›ü­†r)°Ô³LniĘ̳ž~¼_ B·DU¨wm ôñ°åü($ýjÞ^Úê­Ã¸JÕ~ž§ÙžÅÓHýµÊ>õÕ$êï€àMŠAçBÞ5ýZ #¬vÑjTÚ•ʈpOa•‡~ˆ‘9A‰ 6Þ"ËÇëÂö„ˆðR†Þ±Hp: Íã°­•%‘@\åhEîP¹ ôç{•9D‡Þ_h.dÊ9©(ä 9z$ì¯#$N*Äûáó Œ¯h µgþ}´a¼SÁùûyÔw£ÎQAõzøš,t4Ϧßúéß73£®t´Õ€AÄ)é,*ÐݸŸ –´êk+ïo?~Ã0Ù EÂûËÍÄ%XnõibÂw™JÒ„ýZå×îm¿N}Cå¶ùÙE•TLc¦+Lâî‘–ÊGBé;T6&qº2|GŠ[¶Œ?ÎÊÿcmæÐg•­–ŒñnÁ¹í4Ü2"[¢½T ïc7çܶÛÎsÊ“.“¶r"OwQ©éD©•±rÎ<Œü/JºK´Z.ý¼ÂBšø¾ƒ‚ ’XbÅî=“´Ú~DÌ¢SÎ×qD}óv™¡8χ^ º[ÆQRòýY<}•.‡‘Iüäeßf̰Øâ¬¨zWN²i(ßl§ÏèÐÊ€ñŒ•¡Ë ˜ˆ¯MZ­[•Þ´tÆh£-?R’áñ‘Ô”-ˆHnvHôU|£#üÄÌ7Øùá}}1èKtsõÿý{±Ÿrê*.)øŠÄ»ë"3ž‘H‡¹ƒ2™Cä(ÓuûdÑ¿>¡••Ì3fXî¨@R›Œ2ôÂbžžþ(<“>¨eõš¥¶˜ ºÔ ûC6 Eª#´$&j{UøÓ\è}‰ãâF.­HJ§„>+›=ÿ?ÞÓç¼è@Ð͘¬q|ÚŠŸ3–8‰HT:p]e  öîË·]Ë-:ƒG–U$­¦ ú¨ ­§/¿]h‹\è½ c W6µÜr3¿òw.€×š¿WnÅ…6dé´g ïÿÀ¤¸† îú(¶1‹7ŒþŠ~A`[à€PtI$!9p(ÏxG0 ¼Ž,KA] ½§!ŠËm_>XY~ªâiCçô»è%c76.[v°u ôV?À Èñvn5‹—ð¾œ]Uèæ`K (Ê,VúὬ,ôõÇAŸû1£¤f{u’¡pSTçׯ[1äKÓÿJ‚\K]ú0‚îhæàzylÃíKÆèž÷1óðº u.„³Þá8ï‡o›6t WÂþ`¯Á-˜7ºw4±,©(4C^é9»î5ývaa*À6h Ë–w¯¼zž§Ù CŸ•˸ôÙ³VŹ¿ËÛ÷Y³$ÌÔêÿ§±ËÌÛrÌ8‚Býo†–:ײŽqnÇÑȵwÌønCTF®Õe50úM¸ÉH<€ÇiâÆ´¡Ã|s~¼£~œ9vègý¥˜l²Ä32¡Åýñœ]m£CŽ[¬;ÀBP+°˜T4M˜…{é´ÂÐg—Íšý¤œ^VöjÂÖZNv3[%èµCÆD^E¿4÷+~HÍîh®_iSY¨ž ÊdƒߎÑ2ryKw'H[8\>ÐlÛ<á7/›>ôFÓeć àdcèÞ'Ç["éo‰ÒÉ6ŽW3:ûm•£–r€¼9´u¦~½´ä==MûIá½ sºAÙ:qñðpOd?ï}$ìÍèñ/Vd«® ])·Ã»s,a´z‘? ¡ÓûæéÊÕ.‹V”ƒØ>¯w©Íýλ¼iC§µawLX4ÙÍ ¢g*t¼V©C›*kG2ÑöஹÐÕ5“&n/”pˆ_Çû¾‰hµj µ"BnnlžªYõXè±9« VSžwFC篞¬@÷–ðÝýòè¯_ŽŠ·T2°Æ#u—þ{Xä^GuAu&sw¦½ÉLތɸfkôÂ|OŸÜ~‹_@e.tšØM~r°âàpÞ$Ô¦h)é¸bÐçÄbó+_ û •ïVï{'/aû.Ž™Î¡]S‹ݪˆÿçÜ‘ôª³ $ñƒö¼µw‰x+³jp0•©óiz‚euvºô“½áãYý=ÑA.Oü>»EoZ·üÏ»´«š© ÑLlùP•CÏàLZ!‡”ë3З¼XùÜ6ð¼?E/êþ¢àôBËï礴<"Rèð¯Ü©×!¨ÞŸÿsã§‹%“Ü §œg1—œ ­ÈÓ'´ 6æ_¾ÏÃ?;¨ä¦Æhm›tASou2m›Ãæ?ˆs‡¶wLùœ¶ƒÏ›à ÚS@o¯|7VÈÕçþ`Óå©Fø¶†XÂ[ûYOŽ%Sÿ6*Jœs“•Z/9WhW†?ʶ>ÊF—å-¼nÂ}8™Ðܧ³IÖ'QY—; Y,(ü'o“”zG½ö'6äD<õIý @G̈vtŒ¶8éàÕ–T27í© ¯.KM^ô­îKåáã‰ZÜðøKUw2ã—t ìàà•|”µŠ­$Pè8’ Ýç¼îDvàn¿Á°’på›Áíz$û}¥$—Ê5t&ôfJod·hk4—åm®Š‡ýðBN࿹٧.*7&"O (A…®œK¹·ãpµž7Á´§^·*ªÞòÚ¼wÁ&õWd¸§öÔb¾NoKˆ-Ĩ3šò¿ìWýœUÞÝÒênWÚe è¶ ­õnøa›/Ĥûã=÷ãÜw ,eÒ jÃû²6M£jt##4$¡jÖ²š”ü 5ZL ÒR6ÑØùw|Ι¶t‡Õ6Û6»§ÍìÌûÞsÎóœ¯}çF(mÌ.¼8uv¸Dö5qóÉÓí4ðƒ7)<`DRPEÓÏl¿™Úi¸Š~äÙ÷[§üç›/ÿx®ÑX8¸IÇT^\hÌM5¦$çèA|™k,\,AÔ–òÜìTc¡1{Ò’£bÚ>üòc-R>F¾?7;ûâÜ;Q'_ûgcaaöø«ÍšË+μz‚R¥w:Ç™?œ=Þ˜}¯F8ÔÕš1ýì3í³p¾¦7o©®-ËLï‹Q_ß· 4'==sÏs{?øà«/ü$"Æ1ËHài‡« ¦××·îç`›Á²Äàá /c-2A}üáá¡Mû£/¹¢à¢ù(Ø#A‡=[Fwn·ššÚRx}px;³wEaP²ÓxÝDšÓúqL€%˜Ò˜JM:é (¬Ó xɺÒ`X³ñ®Mßù…õƒ)­‘Z*4öó³©Í—E"UÕ¶¼pb&BÁ’¢Èi·.T‚‹îšü®ª ´OµOnÜoÆ£sþVÄ| ¯«×>ÆÏE5½¿ï¸‚•œB’ýWÔÞêìˆMÄU8«IÕ hY;ìHâô Ø”B4Ê’šHëœÐ¢œö¥KœP¢1 D!Š.üD-FÊHˆXa³sÚp–Íy¹ cTÀÑä¡DeuHUbÆ}hq÷ªà+:*ä;^pŠõàF*ϸc$®s1è”Fì´‚ibfNÃÒèʇÝÿ-ˈôþÛ»f÷u}O%é“÷ÓG­ yè%´I^[/Ïà@¬„{-Š#I0 29f‹}(¼±Šð%ÈÃÒ4i]/¢‘U @ÖÔ>•f9©ý8=tðÈ ™:`nxÈ4…whó\tÝš„­…v"ÕyÙ¦ Ž(œ°ÓdYm5Öhè§s+òlÁZê:(”“„E‚½mÍn9YèŸ"ˆtìF°&ÿ»¬¾ e ôU(k ¯BY}Êè«PÖ@_…²ú*”Þ äõ‹Ýö´#Ö¤Ÿ^³×Þs¤De²ò¢—xÒZíxòù¿66Þ}þn&O^GÏÚh|¡°}y’|Ɇ¡ŬÔ%Óˆ’ã›GO…ðiµv©¥ËŠtù¹îê5·÷í*’'À“#ªÁ+ÀÝšèIùžJFRwÿîñɶ<ÊätR¤ó?•®›7®Q8º¨UQi§¼O ’|eJ~œëÔÛЕ㘡›çž!Óôu}· ™/^ó´ÒAÚªòØ…·§f§.¾sähä ëRõÒ14¿~prò2èxR Ò² QZFªX!áºÕ¾H¤ãŽÑ _;;{ü½So¼6‚Ÿ:T®–nr’K’qçBVK-]fMX¼èþmˆÈZÕüì3o]肋ÛÇçÇA·žJVáìåm“ç5'£•öÁ± àkOÒ¬”$‹æìöGW¨û‡¢Y]•KæÑ•BœKî2ïRÁÞôþå‹C½o›öfbÿ÷÷M~Böý}̹ÂôT’¿59yàÒ®Íx`"IAI åxýÜqmâ5*úÈÞW™9yj{âÄÕM£gŽsÁÚ’þÓe\÷@ïëÿWÔã›ÏL.’'A¼övÆo®Ü3êS-il‘¢inšZ)Ú¼ñÖb+'~î“å%óèŠ âœÈ5;²u?¾ÔÊÞéýþC(ìÝÒûj»ïùmo¼ttZsÏP§“­àyå—žûîG¾9’"7¦ª€LuÝqMR›8üï«£¼%gM™j7Z¿ŽÌQ.•¤›è§ÇXbioÐ׫âó˜Ïº¬ºc~Ï»øbn‡.RïY†ÚËÛ€^¨¨“NßlùöÀ‘¤U¸Žî¸613ow…r*ÔãRit¥%êfmkKµ}Ç–X·ŒH¿sã¶®%}ý}éÛ]<ñÊžªDUŽšE“´t%HI«!tôàƒc?Ü^>0(Švïm?ÙŒv.r•Á¼„½Øè0b ƤœoƒóÚ×r% ”82>’wžÐÿ¡1`­ä<Æ€u`ŒYdñž~’Ô¿<Óâd9ßwëÁcŠ2CÐ'ËЕò7—j&9KXf¥žJ~•y3›ì£cTW-EÖ”¾^3ºk M¢%%þ²bçP͈Ú0׎/®ñ¢¤ƒ¾Ê0,%]x<—õIœKñŽJ*þvÜ:Ìc;ñ^þ/GBAèÉ}Ü­^å±­÷- zß®ýßèØÿ§—‡F/ü^ât¨Âõâ,œïæáîv#¾%ª²»ñ¶ñh%s†‡ÂC'x‹þßIgëØ F‡¦è¥[NlYxM@[ê‚–ë©(XcÞÃ3ï[ÎDS˜ $ÐÆ j:êéÒ°oØøÅ¥AøÑ¯Û|ä¦CŒ |sìÏ\ÎTˆ%\•Ü3w%th4Êä:‘>,ɨP쀾Aµ±BO$¸,¨[rÎvš“uì¢åš Q¨^âà¢båcÌ8¶‚€[éN£œu’=ƒNᇸLçò“ÃíjÐU€ýÝäo­ÆS‘¶íÄç>úÞØD(”P V ¢\ÒnNïxÐÑœ]ˆq¸8S ’ñ ò ;Å QGªT4ðRP˜X%‰ûìÃ(µƒaÄW…ªÄƒ©eÐ9¯úç(Š4@´äÃÀ%|$ —Š[ ×)¹JªÔ>„cà𮮦{ºgf£À³ˆì¸ðCJå„ò^AR‚LJñDd ŠÜÔ¡|‰‘¥Ñ»¿æžw§g³ÙY Š©ýa§»§ûí÷ãyž7<ˆÈ¬ âàë$†‹•fQ²žÁSœë /ÀrÒÓsªÆVÄ÷Y~ýà ýÛes@Oð³µã)Jë‘ÓFhr¹eNÛ«ŽNz¶9ùõ˜kÀÁÈÚ¨ö=l$y· u‡”G‚²Æ®„!®‹åäÛB>ƒƒ0À¨p…¢7ÜáPÑ lK\èÀ!I#4Ó’r‚²ßÁt­D,êV`û¢˜ŸšÆÅÊÃPE$¡ v…]0ÃCÊ!HÚnÏ=Â$h¢×Œ¥ªE~åT‚b¤C´…¢¢(Ø‹AÚ¥ÉU–ìž9:ENÖa'' ˜Ç¥’Dß´#»‰PàJt¸×cì­gðÊ#Ó¨è2¨ ‹Ñ÷Q®ó±ˆñäúgï[Í×Xó-›(P) é!D’y¾øøè¦Á%‹f Bð‚7Us@zm›±5‘ÈØŒe·„Hš^=æøöŸºÀå@?7Ÿ èˆôp6Ó"—@?*D®‰2^謄cI9åÕ£­·¿4± Q–!àãábÝÕLð{xþþ°"Y0ÂEf%v¼½~ðÆOGšÀ¹v\ÊYHÙO£ ÏplÀ¢ë6ùåƒòˆD™'mÆT¶nE뱡ëãéX<$xK·g~`ùÎÂk­ÛçM˜••Do†­Í vß>Özv’Ï U`êÅ–äÀ‘-C»Z¯ï@#Lbˆ©»‰ ¼n¸o¬þþäKOÓ 9"’YñBcàq mk Šîe¢`N¢vÍüc».õ­’:7þòxx5zÌäêgôÑUoD•~Ç<2Ü™ÇIq[¹" ©¬'~Y¤ÄC[-ÇöÜ@ÖRtÓ©’çõÒ—pfù-óö rá ìu&)þª1€ן…w¦€7dsïÙþâŸ/â”t³Ë—<¹a3ýëlÀ°vl¾ö3æ°Õ{¥:V-3®l!ÀÇ‚ÀsßöÀГL•?ý±‘ÔRmþ|EýÁ›†Ô2twÜ5Ùž‡ƒÅà™ŸŸ8Ò$=Nó¾É›k¼î@]gÁ?KW/{ÙŠ×hLBßÒ†B›%Gñ–#Éz¯¾­#Îþ¦.I<ã*'’UâÓË3+[ éƒ#¿H’¾äìÕ‹¥Ãm‹)}5Ï…;Å¥’éŽ @YdDÜ‰Ë -`MÇÏ ‰ÌÏqxº®â½ÿ}`ÐGU½±wx§•3Œ^—r;—Õ¬5&Ö)(¨O&v››ô¡ Båå>óÉ÷ }ÍÚ’3^&47üÿ#â¡mŦ_:+¯¡©¹5Ó…ëá w¾5AXÙs¹ø!ع/ÏEÒJ\3 ÆQoç•¶ö"µW]!èÜÑ çõGû=Qd¦üîNôºž”WOô¶ìX‚Ožk°)uˆtÙ0 ?Ý«Znu¤¾êe —ç—„£f"ƒÞ0bÉ^8ɾNÿ¼Y?÷Z1ú“‚æZ.ìzsÙµ0Pêl‹9q ßæìËï Ûzå!…~¿ ?öÄÏ îäW,û&Ÿ´ kE{]Ž'fDêzÄ©p‹tW#¤„`•šGJ L ü*7†Žg'ïþ†w¼Ì%×…“ïY¨NêzhKqQ¡ŸNMWΰ—Ú¦1 ¹ E!LºÍ€öÖÂÎe·…ïGu Ýb¥Þ…¸b>ž‡wÈ hg¼Y‘È¢qt5ß œj TP”º5"‹lÜbÞöPÖŒúG;˜'ýdí`mª/sM3×ÊA‹hxíM‹tF´á…ŽP0µp³8&²^F85æµ÷ôÚ¿H]S¹¬²Ѭµäs1èc«š3hT[Xû¢þAïÜ$˜®1!ú aµÜ *ý]À\7Б° ©½q\ÇŽÌ«!^Ó®ïx‹ÍȾ¤à…þ¬ó“ðˆ™ÑÆ¿ù³ ‰„x攘^ývݦð³ÙTº‘Y‹Wu–Ñ9{In \†[Ý# ZÂéXýwóñé è^Xâ4+†”'™ëcû•fd"Bï,ž Ï+Sê§‚ž7s[?~‘'2ZóLÖ«e.3æmÌ ÿyRùÖwa®¿E "ʈ¯k±Ú .~eF¾àšÄeôÙPvÀCáõšô…M"±Îþö!:î¾ðþø3Ns¨wµf¾w¨$êë²yíŒJõ‘RØÜ³-SûHN5QLIíir¡ãGµ?Eäˆÿs^õ¿qgØN •ö986!GëÚ×P:–Za©Ò"e“’”vgfgæ6Šsð%ƒ]"!hª|¶ !|؆$¤©M€cJn !u+ €èiÿ™>s;³wöäýÁÞ›¯}ç}Þ÷yŸ×“:ìÈ¡Û?¶§•Ñç“·ç@ÔqO25òÒè¾°úÙFV—ÊQ†¹P¶*õÍŽÍ;y|Ì–ø$ÐÕ°2¦/ÙÝ—k[6m<®ƒ¾dÁ{Ä ‰à*Íý/#â»+ý Í÷"õ¤ý i¯µïwöt3ÃT:ŸC]Ò)™ž=8Û7ÛçÌ; b¾\[DËX~¸ LÃEܯ(î Ç2R)ÿýÿîÍ(O¡ÑüEÝzýí _×ð}_û†ZYR4útGzø:$¯ÕŒïid1*4²Â MrC¢Ù.nfÖŸiËx‘'©`«G“‘wbözù劕s£µ§=* *7t¨òýtÓxÙ÷ci†Š=5 “§Ò¥QrpÿëvêÍAÈ„4ä€ðA9L!/c[´¾@R!üAAl ÙÃ4²odej .ŒaNJ ˜ õQz¼€p©˜3o¾V+ ÇµeïiTô]; ×>¥¶¦‡í€V›ÀôŸ{Ìôìûó·$ú‚™Þø#Û Ï#E¤ˆ»yÛ´;·euï>$9.h¨F²Óa0haÐÛ©ÏÀœÒgú {ß3ê/ÉÅDRÉŸñiâí)CÙà›Ž¾:(Vƒ~.•_é5ÿAùœ<>, ÷Ù™R³a4nRMpž÷О”¹5pÇ"7qBiqx6ƒz_t''CE”TZæ‰ïa‰V-hž Èäµ/Ê “êTkíêdr[(W#o4ñ"IÇWYùîžgî"úÚRÕûŠ_çÁɨ‚Š ( 8¢ù|sˆ£ÏJ›ÕjÐÏWd÷§ÉÈÔmÍ]7µggºº¶ß|¸©å¶v’r»1^Sžû~Øÿ]4O*Èr-ëÑãÌ—4°i}%‹yE”ÏrP¸ûÝ•êÕtwô”µaJf{"’NfÍ{ðÆg[7gššßÔÒÔÚÞô215ÒnÚtW¦]Š>ëÎ$gÂ}ñibÐp§ƒ¾7qàêdõ'®5¬Xb¦OòhkáÔ}?…”B™Óü{f;øÙÅøS`j4 s[íÈÓ&ô" ¿ìA!‰É®ýx2–Dû*ÔÒ-aÕóî%¼ì£É’ýGz”wòöZÐ{+h:Ó¶ß±Ú8’9 p°O}paªß•ap»;…ûºàôDNé‘wÂÒæ¶Ax®¯°˜ª Âö§ìH†V¨z™>lßÿ¸é aêQ©Æ RÎ13?7{˜’´ªœií1/mÙžêÆe\»,Oí&Úç½ FA *öU7hVJ ýÍNî½ÖpýÒ@_þüz5÷ìE0>Ì™kY ëà;×’†Ÿ ŒÇÆÕ·ZÖ+Ì0tY‹eútD<%|c´"®)û‘«ÎTƒ¾ÆH?¶ž?³­ç_ª}[ôá’¡Ç!œÐžÕJ~%!Ës¦ud•uø%ã‹%÷­Â'ŒøZñH¬ï718=¦#Gìl&k¶ä¢O–@°.&äԯ췎˜Gvž@–lØ2â:s ôŒNð• (öŠ óœ5—ºI"Úd/n¥†QS·NÜ4â*òâè@›P‚øˆ-Fÿò[:¶…@ol¸'ג謟ten=×ïìÙ3ÃÝ/üø«B·~á~¾0ÈLz-z)cú‘Ó ’ìº*ˆO@< }¡20…%ø9Ÿü¼šÒäÆL©ôªL/º6cƒù™;ÑÔœo3ꉑf:ú‡€vó/+Ÿ+jÍ<”^tçZ5}ÚÍîmÍ{m_Ÿt?/ƒŠZ­ºp(œÚ¼†Ñß^÷uzR=çìðÝÊ÷Pç£ÇÃÂùNDX¦˜‚ÛÕÁ馷ÒÊ¿‘ùˆZåh¬´=Ïâî ÒÕCáîNM9mãéÿ.U½/¿}mŠóœçJ;ö× 'º¹†I­kEMV>$H×Lö/6õˆPú÷ÊÖßë8»\j¾Yc[Õ©ÃÈF¿î·Õài³T^;0½¨g£+o}_ç½[ï7¯û·£H!F$ÿ(ùîä Î`lþ÷|HMÀÓüªtdòؾÒAÅýø7e_ܧÔÅ·mˆœø¦V½_ߨ°¬¹¶(è+I}Ì÷tÍèÉçëµá¶nVîgSÕ×ÌYR»ˆž³ð4Aû"™XŸŽ”òÅqÁr†’ƒ kŒ'ê¯I7õöÞ[,‡üŠòIAW,;¾¡J⊑ ³5s­þ´£K7åu¢Î-QS„bôVÄ4¨ƒ>mƒ˜…à5Ü+%_ݳ¥4ߺµÍQ;Sþüä€2¥‰Ó|©Úëc¨ê-µ§Ýð~c½L_Þ8|Ëí‹gzãKu=qòƒJ&Kïª3{Õ牦T®½ì@¼œËæ_«^ùÖi%ÕªÔæß‹lÎów¤WHLaœ;Z×”Ç6.5>¯ÒåÛ\Çw!‘KóA—4µîé᎛!°¼¢ÚSgn3ä+¾”Ötª!6¤ÿÃû›Nú÷©ê ¯y›²¾xôä½;€4wŽlºÑ¾5 l_쾋øœïö\ø¥ÿÂs¨ïdljÿý“¾}Z<úúæµ;µ\æQ¨ ¹ÃWŸ½çÅ÷÷‚q©ë„x-é²=6ÁosøÇëoþU Z?´±èl÷È#ýͺ5óäRM…P8ÆË¼¶ëÒú2üó+íºy1ôdµspmz×gåæŽïݳ®çf›^¤§8µÙx#PÊÒ­ž¼\\ö*­:ÃÞóÿ¸ç¥«‚Ë‚W¢ +}’0†KÕM:‡¤ïèÚÄ[>·xôÙ7ë\T¹ð¯üëž3ž+Á*ÁÆ·;½/¾öïŸ;tŒÃò…Kë¯\‡"úò¦ ¿5tX|™51?<}éäg*¬?ÿ— §ûÛÍ+W5{á6/V!v¯A×?eÑ^T{¼½eÜ£‹=ìÍ$÷kõÓ«k³ù»ÅVöårçÐ;úÃB®4fÛ÷òâáƒa5ô› Þä¥[?ì|ð…}j¤ý׉%Xüκüs­§7à>¼×~¹ÖROÁuGU˜}u>7áéÏ(1qã¹ ßôÒ§?€,G¹ñÕ‚.“¢‡ô,ÕèK³RByÅ&Œ²Vœ‡ÍbݯîºóÙíÕ¯fK‡á}!Ñãr!+Ë_®úJß0O,A÷€{DÔ¡ÉAQ¹_ñ!!o~kõÆÓ“Q3Òƒ!¼¥¨šZaa´px­£ŸiÈ2Œ0ÖvÜùö_ݹ²Ð*BÝx`7° ¡|8ŠÐròïÿæã·¯¾õÞ‡5˜™`þæÂÊB¬(ŒïyúØê/~W6êBG®T#¶|ú¶Y^©Ô`*V"_Uà¥ÚW ØÃÖµêGp¿úC×>»}âç»al-/p}s„~¤¤¨¾zçÄíO²KxžW«xzÝ‚®ôW*!/îøÏ‰cÏŒ,ŸJŸ¦Õ6¡2B©îxñÖÍ_c÷¬8¼ }6µ×ö^¼½úÍk,Ô+"ªxÛz“Nhêc£3÷•îP=¹\½jjz¼Hx2€Q0…\R°œ°1‹@8lán„pÞú0qª*¬KJåêJؾx/P5}Þ,Â!øŒðªn“¢Ù$oÙ¬Âgtë„ãžõE'2„'P¦¥z`DT¢5ß·|¶#ÐM…Þ yº(Œìz³¦§_¨8=Òazø„[´5èA! Rz‘®Ï+­êëè[Ú6lÅ„îúºjºùºkÀ]—)D9Ò/Â×VÐÖuÙkýS=äH&”Z¹Â׆›[Ïú­hÃDMª"Á¦þöézHh ú”z½`Ñeg×V†µ×7Šðë°îBgGèÁ)!\³>‹;¡û¦æZ¸^ ê|ホ’‡ÚåzÄét«£…­,¼äÇ Æ!û´ÔMú¡óëÞ¾ÒÍ¥3Ýà ³J4”Nm;Fé˜A–÷Ö,ïžJwË1ÃôŽÒÍ`“®Ÿ:(ýA3ÈA®õàbÒ8ƒîéPú` yr¯Ñv¾¸¥gÖ:ˆšg ^ó½-œ ¥§‡@T²Â#¥* åoáD(=-ÈjÐPJpy…R[9JO Q3ž'¸ ý ”Ñ΄ÒÓB !Ý‚·†ø ·r*”ž¤ïsO å©‹H[9JO !ä\p!eyJ*±…S%N·¥ÛDéN¹xžR”n ’~zô%Âz³ŽÒSKéSs¦úŽÒSK¢¤ ­C(Ý–wí¥ÛBéóÏô*Gé)&‰ôш £ôô’@úXa¥[…Y:É2„Òm%FºKòjb¥Û‰QºÓzp J·sÒÊœŽ{”n1ƒÜFÇ(Ý6ÌÒ)Åòn11ƒÜFPºm¥³vα§[ &=ƒ ô ‚Ò3JÏ (=ƒ ô ‚Ò3JÏ féÍã‹ÒíÄ(2x8ÿ&ÝRbË;UÅ (ÝNb¥³¡©Ë(ÝNŒÒa”Ìö£t;1÷t⸤´{¥Û‰¹¼Sp<1u¥ÛIÌ– ~çG:Iš¼Õž¡tk0Kô4ږ§ioÐQzzé/ýPsé¸Ó“s”žbúK'ä|Û1J·…þÒ·ƒÞV˜1´t”ž^ÌÒøAé–b–®{øÄÔ”n'Fé”8.)íÆ¤[ŠQ:#0¹Íö£t;1—w-~hê2J·“XéT/ t;1÷tز‘ó”n'1[6š‡G¥ÛIly_¥ÛJÏ (=ƒ ô ‚Ò3JÏ (=ƒ ô b”Îq\øEév‚IÏ fé”¶³ŽÒ­Ä,mtŒÒmÃ,Ý¡ÌÁžn-Fé-ÛXÞ­%fsI^MÌ¡t;‰‘ž#dht¦ý÷üèe”n1ƒ8-­IxÆà¥§—ÒO¾D QGé©%‘ô´u¥[BéSsÝÝJ·‚„åõZGé©¥¿t§\¼ O±§ÛC‚¤Óí¦êŽÒÓKé1 ôÔ‚Ò3JÏ (=ƒ ô ‚Ò3JÏ (=ƒ$î2â8(Ý"Hg´s¥[BéŒ0s¥[CžN)–w{è/ºyCGGé)¦¿t]×sXÞm"Ay߯H>I·ˆÒŸüýÿ Ã;JO/ÿg¿lã8ʾ/·v;GÚØòK8›$kŒHø2U£tQù;;;3g ªµHi/D¡Ò’J!© E¨”¤‘RU"nK!*B¡ªÄ›T!•@…ÂÃ3s¹=Û·ë]åÛÍ<¿ÖŽwgvvf~ó<3[Czs|N)FéÆP,]9œGéfR(Ýõ]×kb¤›Jq¤ƒbo÷øQ”n&¥éÝY›AéfR,=ÇÍÉÃ(ÝLJÒ»ëù͉#(ÝLÊÒ»ï^:ˆÒ ¥P:dwÏ!ëÿCéfR~ËAé¦Ò-¥[J·”n!(ÝBPº… t Aé‚Ò-¥[J·”n!(ÝBPº… t )–îÓé‰9”n&(ÝBPº… t Aé‚Ò-¥[Hµô lÏ8N¥›CH_:ï8¾‡ÒÍ¡Zº™ÝtŽÒ‡—jé®çv£tS¨‘Þõ LïQ-Ýw¼†‡§w“¨éêÒGéÆPã §éæPsO/¥-(ÝBPº… t Aé‚Ò-¥[J·jéž3➺…Ò ¡ZzcÿäCðO€Ò¡Fzêú'ð1½›C é³_Ÿq}LïQcOdü² Y¥CH_˜œóFë ô¡¥ZºÛœ¼â né(}x©!}vïÓ»IÔHïÍñ9¥¥C±t×»Qº©”HœQy`¥›I¡t}ló¥›Iq¤û®:¯û(ÝLJr›£tÓ(–îº˜Þ ¦ä ·”n…Ò½nœãžn(é‚Ò-¥[J·”n!(ÝBPº… t )“Þ€Ÿ”n&…Ò¥øÞ=ŒtC)‰ô`täÂíï¢t3)‘Ž&fPº™J÷¼Àq{¥›Iq¤»®ã-LEéfRúÉæØ;Òͤ8½C û‡z‘¾ûSÏ©(ÝŠ# »ÓsúozlÆ t”>¼TK_ê\øš?ç(}ˆ©–î8绎Qº)TKßzG]”nu"ÝÁH7‹Ò ¥Eµt×Wÿ£tƒ¨Þ@éC J·”n!(ÝBPº… t Aé‚Ò-¤†tÏ÷õ”n ÕÒ=-Ø Pº1Ôˆô¥%ÇuC¥-ÕÒw5oñ=Ó»9Ôˆôõë—u‚Gé¦P-ÝÞ{ØØÑQúS-½qhbÞÜIÔHï³{朂üŽÒ‡–Ò›ãs¸§E±t 80v¥›I¡tÏk8ÁÂg0Ò ¥$Ò}ÇÛéÝTJ¤{îhëÐÄÔ^‚ïþž§„3F)ƒ?˜jMÿ*ˆd4me42¸Õ{#%”Ju‹IJƈ„;v§W­©FhQouy3(–U#c‚‡ g;Œt[€AÚmž%,‘œp.á5S-Æ9…J}IQsuSªúD)‡ùÉ¢4/—e‘ˆÊÅÕºH¯œ¥D/,ŸH&°à(c¼MU³LÛ,dœCMª×7“ú‡ê~ÀxàU°v;J>WÝËß+ºO¨U¢–×}ÙDÏ œ“,……D+Ç®L ´EIBÓòzz•)àžÇ!#ÝåÌT7T,Àª¥ç4Ò•t¢GΩdíP]Árbc‡¿ŽO© å,#!ã|:©ZÙ*+„ `&“„Š´#zPÅcê•¡š’ùu)älœ?·½=sx›P.U“*)妨F¥TÉ¡;pI9íz(Ú°Ôõ|Ç*Øûãa˜oA:Dtmtû"¤%QºÖIáb‡åÖe&F­2È!R°H¿·0E$Iªqt’XD,VN¡DèõëkŠÈóé¾÷=ÕQÎÚ 4Qšc‡j]1µF’©œ„¤æýƒ™†Õ.øb+lÃìHX"-˜¿N¿×œ„bSzÜFÄâêô)[ÍÌFY9K mÁ{ã4‚õšIBv&YRV?•aJ.‘n‚0¥*U†²­ÿ%*Õ©X‚8R{ óþ'qÜ™^Ê0XåZewW"–¦z»Ó2*h)Ã,Žà9™…Q[K/´ÎSNÌ ;кNf°£rø£Ý…mFòÏ9ÁIw܇¡²ä~ûÄóß:½¼¼üäŸn}ؤíò=I.Ð–Ì˜Š ºioÕqã\Û±.¸žœlƒæé0¥­˜®Òò´Ü>¶O/VMOVi¶–•î—\›…¥H×Y¤Â.ŽÃc³¥‹) éâç!w÷ÒsȤL×ßúÝÕg`Üwožùé›Ä ÷0:Xo2ïM¾ù†FDƒŠ{ÁøÓo½tñIxêôÅÿœ‡Íö³N\5žæ$NŽ]’i +jZI¡t•¼ #©´Â²‡ûǫß}õå÷xpÈX*È—דî]I8[ùñ)5‚>wN,BžlËçû·ÎžêïÑB-¼duý7ýâß.òhKß ô¼ì—d'~qe¹Š¿§![ü ¿ÜÞž¤?ꭜʠS,Lèõ³;µøí ¤ÕͪúL4ûì϶¯üj]ª~«˜¦ç·ÿ˜‘ˆÆz“åQ‹f»ºå©³oߦmWf.ÒMNÞïàOÐÒ/'ÉÒ)­6OþeûÎ~ðï6_ƒ³ÖGLºïƒhI¦fo ÎÎÊ/ÖCÙY¿Û¿sqª×¥n2“ÙGP­[yù•©5oiàîíHÏËn‚/1¹“œ.BÀ‘WòËíí¥Éx^v-‚ìšò˜ì۱śjïÒGð„´åwk|ÿàqgL‘Ðó{/„°ÁðÎ0\´ Ý×nlT;‡t?gzÏ|¤ÎÅõ §·È­g Çpö__ Yºä,=X¤;ç„èd“Cîž$1ûAï ìžÚÔ/NV§6Y»óûc°Ð·>ÿòÀ`ò¢‹p†  ߺ…·aîÉOòËííQòé¼ì‹Õ÷˜÷ìØâÕP}‡èãp»yµ°ÊÊû \ĉì/ŸS ×ç{u¬|ïLáSËoTµÁó,|³ÿ¢”ë#ùð)Ëöcå)ëÎ_éêÇUé=Ð׸sp^ûRiÛÏ‚ï'×å•Cú›h”ÅIÖy§_ôg5lÛä=ª„p<Ê?eò¢o€¶sHj® 8¸¼ž_ÎâØ¦ªú@MèÎÒoÂv Û"ìØÑ'K·——ö'*KõWÔ ú«>3y²·ô©_–\{Øõù¦¬úsõùÈE~Ôé®Ý§_/{æê##UéÝë_ ýr|ü‰ÒõN³%Éã§û7¾ª³MªŽq2[ûj¿àµÙ]·Eúò¯ÿO|µ?IU\áIPX0¼‡aK´zR”K~iqSÜH^æžî{»gˆ»Ì$+{k‰)J%‘ JT\_ø Å †€S˜Š eÊu#$‚–1†Xùkòõ°Ó}çÞ;;F6¡Ù¥öö»ÏwÎw¾3/,hò-ïÙ‘¸ƒø _2ÕŸ‹ÇIý%()T|Ðo[Ÿ=£Rî¿)2¶çn§qБ¿“½ ë†ÃÔý¡<(ÄÌ}ŠTŸßÁ­døÜ@jvo³sÆ[ÿß3àl=?=ŸËöi¹t,îjªí‡:LU/ĺ‰Ð ¨˜’¢=vû‡Q ¡àIî0†GÊëÙ&K¬­Å³ÐþjN{Å~Nè=`Ó@†^i^ÓHª´Õ„¸äómW=Òýí/7[Õ?»y‰j¯ á¿)¾h (3 mP@ž…¦ ù¶"·R~õù4yÇA?‹_Àžž4õ1ñ|æ–h'~+ŒÜ)†¸D!=‚&ôpÝ»¡|Ä€H^¾×(>–¦÷ó娉ßeÚ:x=?o?'ô„’ÀL½£é”GLˆÂ(& ë‘κ›®úgUµŒt$Œ/zEtzŒÞE€ºÈ¯Þز°yWü«e¤¯¬ýŸš3å¶åM·=ÓG¨n˜>cš%}aÍ1¥xÑu¾xŒ$ü3µÇ9>`¤~tcöØq¢‰¿wwù~Þ~NF¤C>øœl³VÊ•ïÂQ…æ¾àŽŠÆA—3š‚q'o^Ù&´ŸP¯ÃXæ‚83wÓ [q{¹Gg[¹©ÅåÓ˜ƒÞ¿~0¶Ó}r¹tÅçF̯_àkÈ0BœÊ»Ü”ÓÐex<2Æ󵯌IGz¹kX?Ó7("±ñH÷x{cŸK•û.½Qïïnà øˆú/AÏBè¹vÄ+D±7Už|ðuŠnüh¯ùz"èÐ÷ПnóqÐu}•Ùù¹‹Ã>…¯ï®­êbÒT-¨à÷×¹ŒuQ#:JìÛ»ëø‚¢f4<lçx×ýË»'ƒ¹"}ÍŠ›sÓ2ôû”;œaŽn„‡÷øHìSîü”"Rï;3~Ïá «IÇ:H(O~ÚÆ½U¬&±Ýj…h©Þ¯eágvÌ×Ö %£ÄW½r8etIÔ Ó+&ÏÙ…§.jÞ€‘¿©R>ìwâSSJ½‹b« ^èI¿$¨«¿ß†³Ä"TÞŒx9õ9¼"ÄÖÊXŸ6õ–{‡µ–üß¹t9Öú¬[2R:æ8 Â&m…$S—õbªç°‘9r¿ëhóÒB-Ö–3cg(?ÍD tÕpŠjèB盃Î]0f€¾O%[Ü} }ºÆN:)3¥0S4+ º‹ÓwÔ2­5Ø&I™#h{*ãôÊRŸ‡?¾ûŠ¡ÐM¨„°‰™›Q?ùñô æÆï­3'=—;n·ÿHÃB)?yé°´ÙΫ¼QçƒÎ‰0³cBä4ù‘± „^xµ §@Ô.3@¿”ÂAC¡Ð‚/¶“6›ÓÀ):N³M@wÊî5øœGòh™Ëw˜u—u»ÓEP¡»꼘¾ÿ¤X3$†¤ƒÜ+$÷ÎTÉì·2Ð<ºæ-þQ ÐWÛýGeÕ¯=ÀäѤ±úf»‹ìç¡¿Ó~íYCÏöŽìró×E„DAÄújAOÞ+Ð a½;é#¢Æh®rxs`U # xÎ6Ï}‰íØ;4ˆ{¢ð$±Öª]ò—T8]_Áî´“9¡‹ëqµÂ™îýâ· «¸@úDdèBY„3™÷¤ÑÌç¦L˵£E¤OßfX?Óƒh…ª¦„Ç›»øÞ>w•­}kÝÇŠEˆííYËK[ u-Ö'tîÍŸôR Ãù +!´ïu×;îGL“ÞF†Ë=¶ê¢d$l)̰WªáíRÈZ»?¸Ïî´¸Ã=¬H¹Cnð5«”˜vG@RA£2iúbêõI8¯Ë]—ÏÝ:ë¶ AÏç—ºέÐ&¹‰ôv¿8²Å±÷á(¨Ú”•ÅJ¢]Pyj`§I¶NzJÈ™÷]A ä®·ùnD8N6ÒtèNþ•÷~ZªEÓsDºO#Y¸´ÿ1ƒK™ZÉÌ€ˆ˜´ï#Ku¨âYÌ àg,~¼½¯rÏ(÷þnÆGѦé ÕŠËgå7Ý_˸¢t¤ ˆ—ÝüG’ÒÙUGzw¢íÞáÂ" zÿÛÉH‡á"å“\¸7ඇæúM`—:kXµ…]dÿRùœúÎØµ‡(\_ÿ»òëlˆ·p£;a§ˆðƒBÇ 8õðxä¥/HÍ}- ô¼.üªè?üS9Þž¼ð*–qg_í¿cÙ¹bÿ8`àà³÷ 刷|zc²ZÀ] |EÐ'j‘ž’Ê@¯ ¤6bú³†î=Ç–û¬µ£Oâ‹*½Gž‚¬Vér'Ñ 0‡Þµæa$]ñö‚åwÐ=jûO)#ìà-ðUM« àù@t@¢T¾`¿HšGÉ–ûùÙÜÄ O½ùÅr¢üåÃaòÒJ„Ü£õÉ©å]ƒ¾ÉliõþJwݼµC ùR\u¤OÔ2@Ïhë´ ´áøö¤G¼sôÎB+ÐE{bÕ‰ƒ¿ž—#IСjp¤]õaI(Ñ'73Ô®`; QTä–PÑÜ÷Ë­w{Ð)ySÇM›ôé·¦-SùÉF©™ÁÒxh­Ž øfÊš•™@f©÷ ’÷-‹™õY®2»ý¾f 2("FŸeŒŽÎÊ—a°¥"—wÇAçjm{¼:“±¢hNóPßœï°+† 'ƒÑúWg%\œAêqqÙÎú~,ø0<’<—²Ø=Öš~ÝíÕöž,ãŒ. =süÑçFÊÍ}#1éo o³#ç.èr3ÿ¢‹ðv鯝èݨpý€¨Ð9ô@ÖøÎg˜¹˜|B¤@GÐ]ÎZÕób¤ê7]EBöT}úe2´wÜ.ÿ3^¿âÊôÖèúõ¹;4ß2šÜ­Ö.´k¥í•¤èŽöS±ñJy?NÐG°ŠË!m Q²øöóšþA£k5HäµïΚPùxá`ÁO¨VØÞz¤3Õ˜Öm»¼Ýh–¦‘n@v‰ô‰&æž´3¥áKø̶ÓöΊÙa2#}úí®*ü&ƒ³Êå·€y£¶‘Æ'ö®ñk1{ªëa¤KÞ!7ùÄ\ÅþïB.£ÑZ˜Tª“oKfèZû`¤$tð§l_]È…>_žÖ6h{Š}Aóäî{œ,£¾†¡ ˆ½eïòxÉ«•Z?o{Å,;© ?ŽTËdáHoÆ;ž®Û]ú ;ÁKœŽ ?Q e3Ð7(bªXýƒ›} Õ&Ù¯kGïT ¯&×T]?ýñÕþÕq…ךÒÈÁ<ê -èÖRs·‘²ÆÆCEà†4éž™;3w-/®PÝîí’(†Š\!/ ¤ P RP;%Bš– (‰€òŠB[ñÏôÌÚž¹¾%† l ß™9sÎ|s¾óØŠba;ž)$áÔXkٰ슒X|<ÁòQa•Ó0¨Š†Œ*, Ìtp…ÃïR ºÁvÖý½1ó,áÎ V’Ö%çãáϺVex ªÅ–¡o»ž=íZ=œžìEå‚:°u¯±6«â݇L7Ô=‘¾ºP£pÆ%`yvAØÙ]c?‚­ ¦5¡?eºG˜ë2×ÿO÷Nj¢ ÆéN½p·"Q8>{E:F,ä uÓ°VüÅ}¢÷Éóx …µ:Œ4mx'r™ç},E¨Õ±¥ZAxÞ¸>Í…X Ó“ð)óÀ³ÝÂÊVhþ®@žg¹¿ÑÐ&dzì݃ÒR­-a#¥~€å^Üá¹âëÈ8«éJ×»$p9Ù˧#¸¯Ê¥‚N\Ù§9à++¿mÐ{{v[œBUJtéÏX÷ô†©Èî.#UÀk¾Ô;Îl“?Òµ¹UM‡3û…žû>…XlzróJ9¼ÛÒEcìf‰ëÿC  0ɽønt½íJ»ŒLŠ«|DŦàæëÞ÷@¾*cp ™NlÎP7B–ž[;nשôš.ä“zÙ¡«Wº¯^é:{õˆÁ·pKÁ%¡"ôöÞŸLoÈLU×ê¢RêAyë™ÙEލjJst·žû^óp¦WAå¥!“êýƒ2:¯ 0]UB¦w§aÀq1@J¤+¬ïÔ›y%÷-›`=Óô‡±šŽOÁFq‰:6w6´ë´L;OB%Q3šÑ# JñS鋇©…ÑW…352 ô)ªf×}RÃ6¬½ eZµœ(³Ny‰qåóêS0 LtüÝh¬mŽÍ× tnûÄñHÀP—¨#æÃÓOê{@)1K=+iV1"²3B/°è±Ù«B»ÒÏ ]jòxŽ ®¸‡yÇìÀËa®«­¡Ë8è ôIc°§Ñ{f‡PK‰ ŽãÙƒa×¼ÞâCÀWq× «"µ&X|¾> «#¤$YÀÒê‡Û*|0‰]Ä<ƪ¨›âŒ©õ„q¼ƒŠ©  çPmÈ …÷µ(»üšþÖß*ž2¬µuxÍLoÁ¸á ß’»¡ w™ðlð@ÎÑfU9Ú”ª g:Û ]X¯èI°È3ÄžIÆž“¤'t §wE·Ìò¥R€J’fáô‡v¥ gemÄÕx› CêˆçÍ·œ&I}m' œš™XÓ0Í'×½¡ñ·¶ÇiVž‡jaSVv2p÷ «ÊáÜJˆ°Î »ª=b :¾o ×7¶ã©D#\ãc-›ØYeTLp¤A ¯ážât:Øcã)]p€TC½ÄÇA*éøHIYê¦$Þ3Sª…½V¦OyXBgÓ/WC'”‚ÄT÷KCúÌ[Õ®ŒÝ5½c6YnÓñx„õ®éH°Ÿ}8w@•6’¥Ø™ê¢~­¦qL½ó l±sï–%õPj3¦šwûØ¢_ñ´óúšÇèèŸËò‡Ç„é Å'”pÔv)*»a=™:æù#™;Ðû6n{XÛiß&¾#òÍoj³«UI·ï^ÈA•FÇ#¬3èЦ—qÓë#L&…ø9½ñän \ — …}–íª§BÑÌ~½hmjM©Ù´Q,ìGiè$ó¾p–œõÏÒ—¥Ò]N’è½±ñ¿åÃëk‚>%³ƒÛË”§wۮ饿Pï2ÛfÄ ´Ž˜0è"ð™-m‰…Xo!V.xPÑèÑ×((}†-ë_{OP*=bôN\§EÑÁÖuÊ}t w™$ÞÏÒŽÓRü ÷ÀS½ûzGÇ…[ŒŽ8¾ÛY)*ðXøªzž$†AØà©íz&ú$ü×0wÚOGþj¾# ôÆÌ³lÙ¨‰·V÷¡føA÷Qs^1êü„AgDHš{¯N 'Ž}¸Æ¥~ÛôQ´ÖÜÉ?÷ThÍî¬Ê~fÔûFÅ„@Ì‹£»\F¿ûqoh׃NÔ=‰"‰úss£óírh|‘Ùÿ<±=%5ùhœÇý>4T}3n¾þN&'Š OŸ7 úìy‰%=3u¨>6Þ3èŠá 亢–ë º•¥'Ò—¼‘Ã:ŠNЯx{;´~’¾ë×A9êž+ ëdÀïPKÈPØ‚ ñÿJÕ.¾tU‚ýØ ì½oú¶LBªOÊ”S ªçÜ?÷5îÀóõÍz¯a×áŠ0蟣KÜa3kíša»qÿPÒP¿ÖJŒÇ’1ü73ûž§B§LØ»jÇ02¼;‚þ“†ê§ÈšŽþFoGc˜(è¸ &Hº$bºÎ —¥ÆŠ7ñPtš‰“ÔYº¦Æ®‹Ã~ŒÞο²V¯Ù#$—"ÔƒáA¡Ú÷ïEƒK× ^ªDu°îzË1­ããÓ6ÆuÉDAÇ«R}rq¼í:ƒî/«±`ÍÐa¡ð˜¦¿]A1Åš^NÛ‚¼xauO€¾Ô¬;¸Èè¡e.ò/3ßg ü@ŰÇÿ~g†_ƒÞã¨7ü£;ÕäÎ\)ÄA§àUW1ºr<¥Ôt Qê ¹ö¢ª.ï" k ý­ìiµKƒq÷$)·…®x&&:ÐP7Ä8c!WºmŠe0Û…Ýw¨FÕê›Ð²…AŸdeÿƒ&H¹M—‹Éfóe4ˆ‰‚®hR(̳¥WÇßl}A¸Xy2yúTjnTêÂdz7>‚ATwooMÞõYÖ•¹ v_ŠêŒ?HUµc†À*ƒôÍ‚­Mj…/d/Ž©•ìý›íÌ·jgz÷ÙýÌT{þŸL^hÁÎUÞs¦#Ü%ªøãÔrAç½™p§]%¾”•635ýUP…Iî\MPAÇ_DÝ Äê!Örɬ›å ‡£Z0÷ªP>ü)G]b#àRØR ¦Â~ô¥™þ#qÌǃž:6 }OŒ·}òbK¹„“*^ááxºù*îbD絉kÍÃnho#X¾­È¼( |© çÂç‚;Ü|Mo‹ž'ØCš¨º<¼@3år-qZ(|90R¶8¼~bÍŸ¾>X {dºTnÑS]~‘PUÛÉmØ;Þà™ ±{„”æ¦~âÇýĵBê>zo¹¯ÎÄXuí‹&eë p~Чd~¸<ß¹ž.lþãÎ÷ Áž3Ÿ.²¦ZËÛóù|gd”Öçíå·ÛòùövÒž_ÐÏŽ…ö|ÛŠGõþ £­³“,\6ßVÚ4\éh»½¾TYÀ®´i{®hËß°Ží‹ž×¶`…\Xiko¿ÝÉܰþÏ~õ¿Hu]ñ{ν÷½‰u]mRWª˜Q¢¦ëº;1*MëR’NÅ]¿å&ùa ™faa'C0‰…¥EU’64RJ¿I‰ÂR(i)%ͦQKÓšBjDHLügzνïͼ/sßîŽt6£»ûÞ}÷œs?çûm‚ÚžêñꨇîŒímÌÏÕÀh¥Q›¬Î~ùÛÓvúí÷ß߸éæä\µá¹oïè#ÕrÌרTæç+û£Zåå}ã»~ñáuËueú‰Õ±ì±ZTŸ?_®ìÝ7úhãÑщ=9{Uƪc•³M=Y»Ôî¼\9ñú÷þxùçoÿìÌ_{`¶\ÙS«ìýÎ!™/ÞKËtàÏ»ÁÚ®(EùIªÒB2O¿6)%Q'¯ü<ìý^’(ä°¤.$’}(Ô(´)cM>úQî´OZ@ˆmF—ˆHͳ%÷¬ù—TÒa—Š mµƒŒd¶€Ç•"¡é¸H‹=ˆ°]çŒHYà$µ=i–h5H°gí¶¬~Ý:  lã¥9]Šå9%@‘#5Xàó'm%°ÀålôÜÈb·‡Ü÷ØÚd ÖF»§Íµ#€âPQ|¢{µ2Û·ÅÑ4$2™DÊ’‰à)±D©"Ä Oœ% gäHÓ.Ãiã$ìྜ]ø‘,£‘ƒK Ñfë¥6Xb¦C$"Œ´:F—“év³ƒB ¼.ÂtøS0AÁ÷(´%Ú4MŰ “õ"{—‚9ŒÁ*@•‚¢‰ÔVÖÉ@d“鯶ˆUìP‘ kª·Y_DvWR"$º  \vO»’éÂæÊ4¤YJtZº¥8"q'Çq”G#m!ü¹Dú›l–Ñ÷Ý–—kô¯•9;ÕKä4„%„7É 0œ`gh§àûÎO!ºBBÂk@åüÁe=®©Ç[ È B¡m±q×äÚb§LÚf„É®•C!]0òWÔ*ÐñºHÑ®$¨”ãrvK˜ÑúÄZÀ£u)N·Q ®@EYå乚’“Ì߬Gš5ÇC’mrC˜î|ÙïV˜vGÐ)§«¢–n?ý–v”c+ɯƒŽt…ŽD#Ú!G7Ù‚H‚=„¶F;°ñ©¤ß6¤\5–í £ …–i²vA«Œ{Hìáâ š•'£0átž6‹ZOŸzƒRNwªhòêS/PÒé(¢òÔ§Þ¦\O/lÂ}ê J:ÆÕ~G_ ”t:×uÕ/ï½O©ò Ã=NŸºA)§¼t³?¼¯J9ýþm<ÆA†D`Ë~“ì¬'…Ìîkî‡øö—dÊË …Bú˜›'|û[ŒV fyÏ•Á!ìmW%Ø2´Í>”¶œÅv©îšë mß÷—Ò@8jp‘K}•¢³kCB0‹¯þsepPØËîQ@áâéýþµg²z’\8åƒÔ˜†®…Dÿ€ÈÉ#;¹7X»$)þ_ )‹ƒNDéé5nÏâàÌ_³n§{Ù>¸”Ê… ±H8ʼnÄ0,hþÙO’ex÷G—?Lh•_*H´,Ö(CX…8ˆ¶¯Ýì^[»Ã•°LO¶$äDx{”ݤ÷°éámiš;ŽÎÝ º`¤†{Y | )?ڜ߇#f]u84­lŠªúšKç¶©^X‚ì$€¿Ä£HÇ0q²¸ñÀòïŠ!CIeÞ‚E-5‡C‹ávio½‰Ã–ê ƒ;Üǯ®?ܨÍÏ—34Z+§z=Í*OÏïÊî‹©>Þ¨oK–¶ñšo¹V«7voÎÖ»?ÖóH•[“¤¤îÝŸÅÁHêc5ï¹z~¯lŒœ¾õÁÁµƒƒYX_S*Äó<8”ÛÓк¡¡z&ð‚gÖúößK†6ŽgåUSÝžªòá_½Zò8¸®XëÒ«84—¬ý¯}æ^æ&'µñz-Cã»ÆÎ.¤qªod÷5©1©ì­+„:Òݧ®Y]Ëî':»\©•ê,«0àA­Ô}½6к¯·ODt!{ø•m+ W¼7ñp¿º¯…B|:cÖuÝúTÞŸ2µ‚KgŸþw¤Â93µ©ûz!¼dÌŠ\Vñ˜Îó ÉS”¦_›ŒÙÜùô.wÿ`}gœ§Ì¹þ ×Bö»’ìræwõcnwnýà93õäòcF†ò#óBÿÊÖ ÉéŸÓм; ¿n~ع89iŒÙ*:ø©y¿s½}Z.iqRiÊq„0(‰_›_ÝÅÕió?ÌSŒcJ‚1ËÎÛJŸ–Näkú=2}å+'㥷̷îF"H¡:ȶÓ¿²u‹Brûœ1Ô‡;KÆ v. –¨¶/›1˜0SÕÎõöi¤íü~Ô˜;¡}ÜcÌ„¼‹A.X~¦¼jLØŸÞ»D Ep¯1š‡/jÆŠ&±±N±Hše]¾Ó‘nlS*ý¢ÒmÉ Tþ$¥‚Î2ôjÛ*EÆ húÐ;¥ °ý$/‹èÁu¼áˆ•2=‘V@ OC2°‹ÖwäΔ‚Kå ’š<Í:¨ÿÚ=›?‘šÞ(Åÿm3ŽŽ%I``g2%†%m&N´gµ¬øL*ò1FÇÀH(‰( ‹&™úöøte`m€Œ‘ÒâæF,ZZØ=@‰cb¡Ä QŒl9ñ)g™xDÙµKLÌÖÈ‹l™’8»é°ePìž—îÛ|óØþÝÃì:¶ÿì–dW27½¼xüxË6JHµé_\>sªjM^:zxN”ÈÀ1&íßú4UÞ½ûÇD(÷]8}æò—ì>”óO{ÁüsvöH™–„|×üžØ+ßœž¾vaÖ–k|Ã,túÖµwÊ(ÞFn Q}õêµÓWßùŒ¢ ‘çîµ.#¨£ë®Þº~ñ™“.äpæzbÇ—ãÊ•c¼€âäßÌSôwû7þ>ýÉ{üÿòxÑÌÜf( øÏt••l5Jàª1¯ËçÌoJ6C!oóm®‡•˱¬ÍV'¯¿û³ÑÏ9Kä4ž{"Ú8³Ý&qÜšúψM×÷‹¥®I%n((>Ä=WãÏ7Ê6üÌÔýlŒáT·¾/ }lLcÁ–Ûÿr_íÏU]etŸ½Ï¾çbÂCÛ‘¢VÆJi¹¤ 0IªÔ¡<‚‚¬Ê ¯@¯<†WÒ$¼’"¥ja – ï´ÍPˆ„ ¦À`iÄ ˆ”þ3®ï;—¼øÉg4ìdî=÷œ}öÙç[ß·Öúò;æsŒç—¡±ÝìòN gÆÀ"bÎ*M™ÝØcŠ€ MI…„K€ {ûk`J·õ2Tÿ\¼ã(1<&¿÷á´p¸—š ¦0и5§g÷Ü­¹Îy r€ë†ù|¹ñ L~ì·”·í!ÈçEÈIi3j5Ðx´pÇ„FÎ<"3©d†–•/k}—§Šš4mcÔë~¦]ÎÝj[|ÒŠu&§ÕÿÀ,dòœ»6¬þ'ò½‚l?X8‰[X|aÃ%žû! ¢ÏÛ:Ë"}Ú¨¨›‰ŒC­ÄŒ²™:‡áÆÕSeƒvœ7xÑFc~ÆD1`’*§fJIåËDbù&êLØY·–ש®¾_@švåÀ˜ aNk.¡Zj>Í¥âxpŠ|b¶»ÛòÖç3 ¸°L>§F1Ö +M[è+Ï&‰%O™RŠø¤”©ˆ¯K‹‡8 ¬ÒËÃr©–šì’GF[8q/mÀ’n•.T—1ƒÓsä…æ ¬ufˆ:l-°ÌC;éÕÍ®ôÝqŸçûFÆß+ÅyÄk #_ìhȘô÷%ëƒ4¬Æ#«ÄÌE#º'"ltÿÆ© ß¾eº"ó%NW'ù¢ ­[ 1"¡vdŸšŒíäiø¥2Š÷ßG*ѳÀl­ÀvcGJb}È’ ‚AÀÐPmVûaìíH© Í@`‚Qš*ŒZÊðøÝÑ¡Ê ¾ ÷nWòÎ(1›KZïG]q°âÜ>бs”øDYîîßÒ‘7CùÜ‹÷DI¸½ ÀxkÿóàÿmD ‚¥•c÷Xi‹¤~šÞÃu~þVjÀÖâV”ÍSÀ·Y3gPJú# ÓQz¿yF “ŒÃD³u¼Š z¤•t &øJ"ÌѾ-^"8›Ý,gBQÔH)Ò.¬¬U'î˜uâ!¼ºnáþzåŸà”ÞVè"úˆô!¶W´à””ÑbðÓt‡N³&“Ç¥|:‘<¯~/ìÖÃ9©ó{ó°©™W­ž D*§GÉÞüæ³û¼0îŵú³˜å²Øoå¸q¥€Oë"³Ü[È63#žñ’m˜'àH¥K£ÕÜÀu''Û³˜Ó s.PL÷̈ÉÔH4øMæJ¢ŸtEz¶ôQ®Ÿrò̤³«AV;Bi§Þ–9Fí9ÃÜUðÉ+ƒˆ—," -X”nÐ/xàÒt[†d®»ªF SóîÈô jΣ©šËÝ‹|ÃúkÈdݱïûfÎÒçŠ[6ð;gjñ‰áuœÑ&v>n†¢÷Ÿa±3`ãyB„Ü‹À¯‰h;°–ø¼"¾ÊD¶G(¯ïë h¥;?T @Böhá=6aÍL"ÑFò¤UN³ü‹XŒÜøe\sÉ >@›v}“q€Ùä2Š’3ÏQ¨édÿWú)°FÅŠåvâÝ)XW%!’v­ >qSaÅçb§+É@º)êó6ŽÃ³ÌJäµöá¯Bñ”ÒkžŒÜ% «™~Œx䎡F"õt’üxQ‚]‡ k ½\@L‚Ë(LðÍ…4W[ò1ÆòÇ¢§¨0"«»´lˆnøNe’´pêêòT9€ÖY{e´ŠaV¼-R©Æ{­“Ú–•ÖÖ—×ìa² = }|±µ€r.¸J®\F¸¢ÃâV —7˦.#G®³CÅBöð“&÷>›—z7f0ƒ–7§‚À2•­šÞ2ÕN³Ú~sPã牟k¥×¡}ß@ÉüX§*; : ÙçMZ˜Õ®«ñ:'eËtë¹dTcg”s£,/ê+¶þu—Rºf=ïè\g#NÊ—Ø­TÈgQ+dnïA“˜í›’µsšøä êÁ'*M¦ùxréâÒLh¦öˆÄì{(:ÀÏ2}Hg2}¿e ÄY-åA#šÈ“áf„f­ü ²ó$Õ1r,ôJÍw4Æ䤫½‚bÞ¿S  ²×™ n*èZ¿}ÐÜSæ'Ä…ö5˜'ùĺZÉÊvÖå ¸Š¹ÜÆjj6*ÈJ%É`ýo3>YÖ™åÀSަŽ{éóÝw.Ý9^»¤¥¥eoËî*aõ|“þѰcúÐÏsW)Ó.}B vÌðZ½t¹Ävå'6áF¦w|Ø`<›YÒ_…t3À`œç¡5 >+N*šß›h)ЊÚíÈ~OìQ Ë(J¯wGQåTÚír¿+É¢Ò°¼&ã|ÆU c‹Ýï*†” 5åH£¼N>b7ˆ±Þùjån!Nvc¯É,:>çm…¤–¸¯ˆ´3ãÁ2ìž{pœq«ç ![",­š,ÏTùuJRAûØ/_e‘Ý-ûÀIo ;wfæOK-ÞôàêMLâÞã›Ã»üz,ùï†ÿ4œ«E•uU8(Åkwâ3Ã-Ñ_1¬àሬôR´ÕœTR*–Û eÞ 8 ×Ë`?Å\4ªÇf.8uëß§K²‚¥¥ã~ܘ']$Κˆ|md’Ö÷Kø8wï~ ³òXÓãSiç¬ Âµø É:qÂ:-Y¹rÅÑ!K‰+h®BI¬×€¨YÓÞ‘:cKÊèBº{ÎuõCá©a¯‘jò>é;ã±ö¡Y}l0­Øj¦3Ò£¥éy ¿ ?$›«¦2&µñ ™m¨SöeFÃñ®cÐD VÉ´#5À”€Û©8Þ/}Y'ätÛõÞä Ù–áÏæ^#êIöªÀKïg÷¶à$ÆÁb4t®Ò?—$ÖÜl ¤w[x©e»¤Å ™b|÷Rì\e‡ä¥•l̪5ÔÖÑë¹\êÞúà Nç÷ŽÏ;¸’;¢”0q£Gt­Q4Õ²•aé­§þ Å ¨Ìýßq³)ÆË)‰—ÏÃUw }.!X²P'æ82>‹Aát`U8;qoæï@|} ÇZ=wÙ`²Ó”…ÿ‰~'¤0²[Q®4c¢“¸ÓßBÄFÚ8…ПÅD';¢}šLöŽáœTôˆŽ„¼êëV홬fº½c‰ýì®A,îâëXû?k‡¾Õ"QnÍÑ~Õ1!/êát,J+ØÒû£’ êmÌ."ïCª§t 5?D¤C/ÔýWPûYãè{8軨¹^ís6•}–îŒ{õ庥ô Dpv¿ö÷a€cÿÃ6»ïÝ,áoA* &)5©îy<ðCïa†‘–û³ªw¤$€™QíYFØðRÐ#])ùãÙxO/ÅÐÄ9tÓ§<Ú;ªƒK%§äs@³ïš\ƒÖÑ=b?5#¿Õ·â„L;󫱸Y ù}á<ìFÓ#’á㦠=­§®,Ï8¬úKKû™¼†×³%É8' $‹s&ÎR]jã×gTO,¸ûÀ*–”êˆI ëv‰ÅiœÌ3pÔÑãåò¼ÕÈõJ®†Ïñî¼%›vU¨‘Ph˜ÉT_=‡¥õ/—ŸYÓ‰lë?ŸPBÅßñpì£rù8DÝຂ'ÜnsÁÇÚSnþNÇtgQÇîÒäyÕ}é$ûN·he–ÑÍ9´Â7–¹‘¿9Œ¨ ¯jØÎØ¢*'0²ïïGp£ýuŸ32D þ>ˆàw'‹´òuý:ÙˆVjÌ8Ŧ­öÍËhôqíüB$Ÿ§£(L”'‡»¸{ê´— ·CÇø„Œë–uæ‚‚\`„¢õÊÄæÁÏ ’fÔñ°©6{µ~ØO}¨„ѹªÍ§€÷µ+z.L‡™NÛVÙLÇ î¾t›¹}ø™›—eÕîg£x L×#ÝÕ•ÖEVÂWÝK,—~<؇QŽäIûÌˈ~Go›Dç(ÓšØKöOëÉáæIO_Zh+Œóö/;õÛâfÍkmO0Õ%å7ç‹Mm¾êºóà^Õ­ç=%ìêûsï~Õþ‹MíuUtéÕ“ChI[/€­óâ–:Ç‹Ÿ=³W‡t%)-¾í7̤OÖ”q¸Ë¤\];q1ôúìá¹ÿi"¦Ê°øÄÈs>3ÑýÅú:Y4ƒE3Ô•b¸ØjÌ ÇadÕÛ“+>¤]"q0—Y‰q´W11H¯AÓP:.­]Ó>$R%ƒÓ”Û¡äôx?nߌ§§À6Xݤæ&°—Éîbé…lb©¥Â2Ý%ù¥.xɰô ü¢Æ²€)—O‡èœ†—Io~ɆT#!©—8µˆ†µÔb7aI°€$¤ST;YÌEœ}@k!y‰)(Sv™ŒÆp{oÞ“S1ö!?ux˜s±•r’t±”<µAM¬öK`™Ø•ÄÙcÏÎ.ÂüÂKÅžÇ ±…è:'þxèb eöÙ̳ýŠRþ_òâ08ÃåáÚJó7Nš0dÆÑm´_·l0àd®Æv‹¯pvŒD¸öñ , _´”x{Ï & tÚ£#|s_"]êþ˜¶ÔòÌú1ÄÖÿ¸åÇEçÒ<³(żCÜËV$róöñÙÔ5p¦ÌÄ$d!WŠbÎc¤6ÃéŠY§ª™>EæbÁ5 ‘Þ¸Ñ×iØTXÊF-˜Üݧçoôm6UÕNxEõõi1öoÈþ^RýŽ ®aÓßHÏÂÉŠVT{%”nôu6%–¦2vZUïà~‹˜I¿âŠmOšŠk û­a‰ø,¥l+P·5¤nÃÖ°ÿ»ý3t7Êý endstream endobj 430 0 obj << /Type /XObject /Subtype /Image /Width 129 /Height 128 /BitsPerComponent 8 /ColorSpace 418 0 R /Length 1660 /Filter /FlateDecode >> stream H‰ì—ù_UEÀm³µåðF­Ð)½9—û TTÔ1E4AACy¸‚%h …"à¥db¨)¦ER¢fšbRRZf‹íû¾ö/tÎÜ' }žï½úðùôù4ç‡{gî›å{–9s^—.Z´hÑ¢¥M.»üŠ+¯êdéÚõêk®õÐ- {ž,×uïyý žn„@t²2G@/O½ûÜÄ;Yàæ>·yèÛ/x' ™øVO·1èßÙ.F_O·tz D/tÓ@h  4€Ð@h  4€Ð@h  4€Ð@h  4€Ð@ü·o7œã ÀðaeA£i c@s¶°'°G¿ù @c¹ 9 I8£õè“·ý9sOà ÛT‚Móâ¹^³À­3sƒ“J>˜w'nj˜ `´W“óç«©hESÑœ{P–2©%LœNá&X Ón¾WN;;CBï¸3ì®ðZÀæaÓ‹Õ4tÐà!¶¿”9DÖpÞ¶„÷ Œ‚#GI[Fß=&T| Ï;·Ú€Â&:&v,¶ƒ)þ8`\Üx?ab[ûà‚È{d;™”€ª0ïFÀ!´I¢”“§´Ål’”É.§¶óÁÓhß{S§Ï Vª >ù€)S¹dšœL-Z³fÏIÆosÖ ðî6wäЈXlÎKŠOÏ`‘çοïþs3³ÀZ¸hú)ÙC».^2ýÁ‡r—f:ÑO.¹,oN;3åòüd>_ø¢wïTÇ)kEhhb.ö—ÒÜœ•ØZµZʘ‡•{&¡–S¹à­â¥rê|¹'”I3ä±5<]ଥÅÊ_Wú„…2± »O–ãa®ÀÆzØ€ÏJ÷–1Áù5ââèYYYrß¼¥ÜT>I”OÃÖm,Þ¯P½Ý½|Ü3ëW8AQ*®·ß.P —-+ Û‰ïgçð¹eÚ‚aUô=ßY#Ÿ‡hTß(ßUiþ¦…íNAa5«Å× Ü#å‹N@ÈÝu&˜{°±v/bÄE“ºbßθí% e˜“_Š4Щr,ˆ´4ˆ÷/0 šû_Þw Î&8˜¯à«á³€B"ÜD#°q¸³ha Ê÷ÉT#gr–¢b¦nÔCLNÃPô à‘Š|õè±D.^CÝÜeR®Ä|×€Ÿª(D£òDZ·AeZb²0B1ZÎ<\®Ã8N#€p?DÆêÜ܆P÷Q(,áðº”o,Åf ö&È&Ê­oŽ–ò­&rˆxjL<"7aúž)OÁÛÅïà!5¶mC¤‚ïy€ M7Á,XBíJlwcvåuõ´ÞiüxâÝÙI€¡šsÈnÄ Dë爜*'¢½Ø¶­x À}©3Ó‡Ä@v²}¶ƒp,¹×Eʽt%¡ d57l€YB ÚN¨rv=fÂ"LÜÌ“òº 5»0.>u•&%º\I®xîC*†ˆ†˜ÖS˜?èRÊÏŸ©ú-WEö<Ž£v,np¹»¸K~ny¦Éd‹ÅÚ•o¹ÚuìïÒÖ‘¬E‡Â¾˜t6´Ö]Ð,Fý†ªK5;º6¤Ž QZ[;œ’þé¢Ca#¿Ü_i¢B€[¸qÓ|ƒ)N×BäÂúƦªŠú诪k ®c:RBíeru« m¬9Œôg@Ý=\P¹iP•ÅMƒ©‹Ø>dLÕ¥†PgNE .ÔVXh9U‘æÝ&mÃÝWº–û0ÊØ®*u»ªË·`,CÝ]Hˉ;®9öAE&7l燎ȅªdÝuà§ÔEƒY%˜tU¥ŸÊÓv²¿š¶lt¦”¶À]K0n?н—ø: 0ÐÑAú;ß|ûÝ÷?üø“c@Çßþ‰8¸ãgO½²~«tÜ9,XÕ¶Ì·úüRØz{ø¥GÏ€Žã™ÑúǤ]uÿ/„]à×ß~ÿ£¹ƒµkn>ÔÜ|¾¹%¨¥¥ãïþJ˹óÍzТE‹-ÿOùk·ÑÐ* endstream endobj 431 0 obj << /Type /XObject /Subtype /Image /Width 730 /Height 743 /BitsPerComponent 8 /ColorSpace 416 0 R /Length 563807 /Filter /FlateDecode >> stream H‰ì–mlÇÇ?TªdÉÒi5Zvµ«Ý;ñ‘i¡EªPòRŠ1ØË ¡¼„&¡ -XwÅ€¨AC0ØP"E”HÒòÑD¸©1/D¢¢ ”V¨äà󽃹—ݙ鳳·çµkú¥¤TÑüõ÷è™gŸ™Û±ôüú¿eÔvFŸ)µ-FJSjÓò#jAÖ¦Ô¢Ô}Ì7 Žy@¼Œ#7ã+¦nàMmÏå{qXnùÞEÙHn8S‘Ø!Øü®Ý ñ•AÂwH2ü|‡÷%©¯xXOæË •Tô\ä­2E¯;¢¼‰{€áÃÊHZ†‹ ·×µ©[F‰MJ±”’Ñ^ðøeôæÿ®Qø1¦Ÿçû=£xã?lîþ±òH„„„„„„ž˜Fôâ9pÆ`¶ßTnálà…¿¥R,7èò†Ðÿa´¬‚K/<ïŒqž±9üäËq1–f,ümcÆ’aÚñøÇ Ü—–kÊUžºe¶mbÿV~EYc|4!!!!!!¡ÿN„z¶Eˆ3@,â˜x5Eâ<*M¨k € ‡µ ®°µ¹ËAiJIÑ L:¥ FövÁ‚Óx¯à(g³`ùˆdɰ‡m•ŽKUFÓKé÷úpâòZ}y6T¨`„„„„„„„ž” Áe‡5ò|´LlÞ‡Ë&ÃÓ%±Gá]& »˜sãÜP–²Û©ìCù›ý;ŒÉÌç_Ýîì¾xèÂ¥ß_è9Ò}ñ£s>ìºðÁgÝû;»÷užk?qjßšvìZó^[dwÛæ½í­û÷îéØÝvñüùË—zú®ô‚{/_Cpµ·’×ú®Þûç»X,Ð¥Œ1Ô¶}ìÄ“À ^±÷¨WæÔø¶?€[– =AhØE=™ñžìõh·/»&¹¡‡N¶ ¼;'m«ŸÒ»–ý·\á‹Xâ/W??pæÏ[Oºowû›[Z~Ú¶çç‘_×.lxnîüP}¸jîìYãLU‘†Š0ª„@SŒº¬5¬ª²¢ÊXA”À!Ã@€¨€XÇ’*Wj8#F²‚°†0¯w ¡éXÆ*VtMS0vcp¸¾¡~a}ý‚…+—¯Ø²ù7û::~Û±|¥ç2øÖ—7óre)cUiê åß…ã‡C ®žò… }ûíׂ¿"cC”¤ðÈ3’'öM«pãaöÚÀýî¾Þßžnß³û-Íá·ßª ‡_xõ•©ÇcHÖ4¤ÕñÀ*–0 ©#¨cˆCFP–ƒ©ÀX’Á°ÊÅ —(8c`ϺRij’©!¾¼Öê^Y‰FüvA¥<-—é0 ÞîN!†ÑÔ €$Iº Ù4̹sªW,[¾±©ig뎃~×ÝuîË7ÒÉ”U(0z¸LRŽŸÎe };õµU¸•Ï]¿ÿÌÅK퇬ÙÞºð«g.¬~iæ´gCªdÈ•Jà»uY“*`êv§ÑKK’®@—Gª < jX7°¡!Í1ÖÁ„Ưc2qÕAÈ[–ùrT‚ÉÔå†L,iºlÀ†ðf0ÊHØP]óŒê>õ³ le¨p · Ž !MQE4Xe€:†)8q)p¦ðH×´iS¿‡×®]ÛÑÑqìØ±ëׯ§R©§}_BBBBBBߘ(å&|dމc7íLKežK‹ˆ—$ÄÊ3jÊŠÄYÇXžÐ!B1f;e´ÈèÛºgoݹ{ò³®ÖC¯jÝ9ûµÚŸ¼úüô "d 9ˆUSV4` hÜ0JNûvz7’¡GC_‡/I•pú¹Œ€G ë’¢Pë°œoôR Û†ðwæÌš´¨î‡áÚ©¯-¨ ×=óæòïµ,Þ³íå1}ðýçç¼P…eÞ¨Ô®®pçéúîÎe«oßÞ¶qþ[?›¶dÁ¤Eµ“ÏŸ²¤ö{ófMŽ$…uœª«l }‚:A Â*ñ3*6124%¸äZ€‘Z`ÃWÐeÙ• Ö8©ºlΟS¿$¼¤£­ýOÇ÷]éͤÒÞuX6-Ý›Emîƒ1‹2›ùn͹QHùä÷ï›X„~yüþÜ[úE‡1ƒBS£´#súïaÐãt$‹PÀŒG6É9O)aÂñˆÄbN¡É¾ºs÷Ý[¶noxgÍìêêª)“4;6¨ª€X®«Ðee Sª„ŽÄ’¡@k–ä nêC±ŽV )Øhãdý]}iÆäú¹Ó—†g45VïÚ¶¨cgÍÑCËΞZsò“×ÏŸ_ÙßßœH7÷Dñæl¦%•lŽÇ7$“â‰ÆØ/“©H"¾iLÇû·- ÏÄXΈ%6§â[cý›W[e4Å× FàñÁ™ô–Áä·Æâ[À·ÿ±þJ 'NÖ=úò®Õ­-Õ‘_½¸lñŒºÙ“TeNPåÿã4ø28¨hAE×°TM,)à—$— @¥¡©H2ªPpÀÀ!øP²¤b ¦?¾®n~4Úøþž{º¯dRqƆ{@í!Ë*:—ë\¥Í/®‘8<©Ż}žuî·š!ãU úˆ°cy*(g gÊ2œL†±òenq;µ)± Œ¡ýåõ§3gû®í?|èíMM?®«™0u"22ІLS Ð9‘¤!ÉU]2ui¼Š¡õBi Æ2ÀI@Ó¦I¦„žÓÕy³ª–6Loj|qß®¹8ÒpæÔÊ¿^}#voS:¶95°!‹d’‘¡l$[ƸÿîÃd4dbÑì`Sêþú‰MCÉhêëµàì`ãÃD$—Ž‚3±w3€ c9›n®ŸR5$〤R³™ÙDôqõƒ±u™ôúd"’NE“‰hl 1•\ŸˆG“«Óƒï ¥&Ó±uéX#,=cgãp~8|4›Ø‰GSð(íéYu®kÕGkÚvÌnZ÷Êëõ?¨™5åY= £€"‚†Ÿ>4EÖ±¤+¨BLj,Á'(1 ¾¡‰+CªlÈÚ”àÔ†š¥m-í'ŽÒÛsž_"åLáÜ&eΓE ÿ¿C%#3¾Gÿb¿ìbå¨ 8þ`br“&›ÉÉäd&3ÙÝ›B¥• ¡¨@нb(¥­" Ûr{ÙwØÙ¬·¥ (!¶€‘M|¿µ ^Œ£iùHûíÝ9_ó±{»½wï®ÿÙ­•˜Ö·ÆæŸ&çœ=çÌ9gNòÿíðâ_Ã\¹råÊõ±ÖÊhÕÊ^¢ ÷—FQV:Ëg†+ý AK8³áÚÕe›êj³DM£0E4J‰aQ6ujЏ´‰‘ !k,ískµm_v«×<½ÿæCw½÷ölûC_²=±Ü+Ù¼ }Å[Jø ¢¤!ïˆiÜ.š××°èÔbî¦Ò‹˜#Y5â|Áš‘ô‘ãÀ˜(r”ª(µ;â•XTaô‰…ØÀD¸ ¯žß¢~ǶË(ѱ‘2-Iá‹N6Ã…ú§¢ƒ(Â9€P*+*Ü%ƒ2øN¤Ü P¦â¨É&˜*Ã*6;YL˜áÙ6c€ ß›0 Ô,˜ sb¶(\eëìIÀL èÒUT6cLdxvìØCÝ}`ÿ¦úw7ܶeÝ•Ÿ¢%‚ý,jàÌ'¶^,e Ô§–i™T£ºfRb”bPóÆ3õ‡š¿þå¯Þç]ðÇäÿËg±Ÿ»$ËËKÿ£ë™+W®\¹>&êFÈaF!g³h0,ŽFQ¿âä©7^yí©‡½có­W\±¼±Ê2t›"Ý4‹¬²I¡DiÙ°ŠºYDêh$6ÑŠÆÔgÖNmߺæ¡Ú ÏþxæåÃ÷½ÿ^£z"vET ØNÏ1æ º¾X˜=“Ôù®ӑ‡³‰h y‘ÅÈú®t‘ΩÈ,ÂV¢öD²Å—3GÉZUR¹aè0ðŸÚ­ =σG„h*å3æ…©–Â@ÀÌÎkx·oYg‚¦ŒbYŸfak̵ õW¼‡u  l8-FÃy]OÊžXœ•È à$yà$…#%Öïô£–jc*Ou¼”·úñ#vÊ÷ö˜wæ–b/ø`ÇRâ«veQÕ£N5Nê Æ]ì®ÃüNà?á}íëžÚÞlnÚ†Ït)1É%Ë ¶¡•ˆi¬ÒlÀ¡ifLb’’Mˆ>Eu _2½zÛ–­Oï?ð—?ýYr °´tæÜÍø&É•+W®\¹.–VÆ0²<£ÈéÓýão¿ó›ÃG¯º_ºa#-ÚŸ°hÁBFSÃÐ ™2課©Ùºn£l”ŠÄ0 ;mÃUô¾»®zæÉ͇}óÍ·vuX#Žæ‘þ€‡n²'QÈp_Â÷Ŭ•ˆz,œTÔ‘àbÁIX3›ýøá”Ï'lž‡#µ;uñè—ï½ó’M_\wå´^"S6H’h–¦[Ä‚±MƒRË0mËBA+¦Kå™7=þýÇÿáPûÔBv†¤N ¹råÊ•+×EÔ Y>ýÁ‰ã‡Ÿû…·cǵ׬7Ë&5 V‘^Fµb–\H-M3uZ¤¨Ú%½dÛ&æúÏ®yàþMžÞúâÑ»OŠ&¹/Äh+å-„f«qø¢9æ5¾0‹jW:²S„$a3G ‹•«¤‹Â¸êFÊ“qUȪ”UΪqTGcÆ!¡…sÙ„¬¢‚JÂk‹ª žAX÷„Ÿ€7¯'š0fN9r<«Æ7j)‡žD£‡s’{çuú·ßz¹ ð¢dZצeh¬_¨ÿ„:ÆF¹‘ ?cÖ\Bt² b)ó&ëɶŒòYgô…×M,:µ®ò¥ÈÆÆãÄ ù,Zxè áEQ‹ó L¶:Ìïu¼3§ ›mÈ1­u¥sÀ{£ Ö•nð“0ÌWÉü‡'GŽÜûÔþ›gw]·áê²EÀ"å ‡€I`–iá› ª2•/\½þÁÝs¿ÿíï@&“äÊ•+W®±†ÃÁäïêø‰Ö‰Ãá`”ýƒ]^É2cyØà¥áž2X^® &C–ÏŒb4:)Ú¯¿|ð^ãö7^fSH%“–¨a! ¨I¨id“®# ‹¦¦“O~z ýÚ–ëžyìÚW_¸ûÔ àGC±¹ˆWÈYð!Ðÿ¯Íšß¸år“šâ’N…¬EÌý/ýUǓٷþñí—W_:TyåÅ»Þ=¶+ |ïn²ÉÚ/ªJ_x]Ñâ ÞRÁ?Ù/û)Î;Ž ƒƒƒexf™af—»kmK•öšÔj½j5Æ«4JMÔ­Õ3ž{{·ÓÞín7{žö. š¶ -%Ö@þÒÆ$W*V’V!ÒÚjÁT´5˜D½›·çyffwïu_ú›ÙÓÚR…üsZ˜/Ã3ÏÎÌÎóìwßÏ“ò¬þ)+7cðŒ¾Òóþ¿=òìö-;¾ÐÚ,á&IÚä1‚¹ƒ FàŒbÉ<‡â ¿vMÇþüN½w²ìxußj ;ÎÖëSÕj-ðdÕ÷%\XT­V|ú®ÝnæÛNkÿÃä¡B… ê~”ë àû%¿Qÿçj•B©5°Äo>¨ÌÕ«³yÀ…~:T‚¤¨OOëå™óç?8rèÅî®õËD c¾YÄàƒ—1'‰H1H4‰¶‹âò±û»_>òËïœ;·ïú¸êzš£?W¦£“N2ÎGš†¤ƒŒ»÷8±°4R¦û)Mývlk\\$¢ˆ"p1Å'EPLà6t}vûæO¿»Þ±ŸùëŸ;ŸþL÷¶•gßO”Ê)ýúîi7ǬDÉUqXºT‰ªpô˜Ï Ž5àcÉ8ìEsâ ½q¸hJT+H00ÕG#S¢˜QðÇf¬»L- ni̱Ìò%š·Æ5æ$˜£éãùsgµ×^ÝÞ»çáÎQD("Â("ðØ#&Á™È7c )2^ öÀêZ¿ú§?~þÂ… ¾ÓfoÚ³6[©LÖêSµêdÃÓ•Ê<²“Üêÿ§¥}Á§U“C… *Ôý.ÃY™›ß?@ì=§jõ™ùÍh iB âVŸ™×ͳ¯I¦ú6,]¬Dy¡ˆ$‰QAŠ ŠÈaq n‘Ñ­ÑE]ßP²© ÇÇýÇÅD‘ {vÁ³òz%;W´²Ž¥2S¥f?³’Ž­ÂéÝSûÿ¦}Jq&rñ'Žïp‹$ưCbµ‰ãB”S¢tæt·91²cóJ a%Ú¼m«¬[û)Sõq¹Qjç ²ÇµÔ2Í0]cú#=é 2#õ}mÅÛzwvžÛL”ke4ú7ús¡†Fõ˜i‘䣷LUàø.f¦šµÍÁëŸô{sûÐ;íŒÆqDâp\cQNšdì#Š"Êþ,±,FåÅ‹ÛwíÚqìØ±®~ܰ_ƒ“k ‹Î#´¯†LìÑ@ë[ãss³ ý *T¨PŸ^ê}ÛiPÆ«PØ¡~*h•y Kç`êÌT.ÿùo¯Œ¼°uõêvÈG@Xv ÏV»ïq$.DýÆFJTÏ‚7Ì9À²»$eZ{(,;5õ!âäïL# ŽG2p»cf •©V"i`Ò€wÐüçb™ªçU<'÷á•䛿ٔÓ^»òs ŠÆ€@8f!ñ¢è¯ÐW“,7#ÔçëÖ­;|è'—/~¬€3kõ[°q;xT}<þ·«ÿÛÒ¡B… ê¾Uƒ1nÕæ‚2^»ÉA·E6˜åzÝ›®ž}ûw£Ý{W?ÔÑÔ¹8愘„^Ĉ—¢8& jiÅM«Âê3¼þú·ÎOYÖ(± –1à‡•õ̬cæ\+ïÙ¹"ɉ¦BPN¹ƒxhÌ¤Æ ¤j#ïüT½ç8±°4â0íù­i¢2×´íI *T¨P÷¯ümæ<ÜD(à•Z¥\«ÎÖ«ó@b›Ÿ¼õÖ¯’}›Z¥v·Ç„ÏK¼ÅHÁ(Ê! )’Тˆ| £M-ùÅK›þr¦Û;EI‡ØšeõB‰êg"Ñl£@Ì<5s~NÙ±U›¨„¦3 ˆâÙyÀ•F‚’èý÷'–F\'c™¹nŒ#¥ ó}»¿8Å^vôAÛØM¬Û(‡ÊÖAëú®+—únèfüµ²ÔI¦ÒñäËÑ µäjz‚ÒL±˜g4mŒï$æÞ2Í»úAIÆBm¢|ízÆqT—¨Ž^€Û#㺰sÔKã&¡%Ú& wzOj¨Eê3 Ð4Ÿ$Í4 ºžO°­”¡'m+ ÂHÎÔµ2K”h/óýë)pÍÀK4GIÎ2 §Oïç/¯ß±åK­8¢p¢Œ°¸‹Ç0'a$`°-]²¤w_bìíwÊæ9 ‘ÀÆÕÀÆ KWƒcíNö*T¨P÷ƒ NW«~µ®ûÊŠÌÍ•©LÜøàèÑC›ŸX¡HÍq"’Q„FÌqÂ2/Ä¢Ü×:äô¾eoÝbXyˆ!È 2¢î>BŒ¤Ç´Éb¦H5)@Èej º¬×%I—¤€Cɸ,ï‚¥ç¨>à¸8 ¹×3Ól¹÷8±°4BôLÑyn¸Kâø˜ØÜÓ³ä½w÷<ùÔNU5šõ¹˜+· £Ñ¨5 ™i6oD~‡£ÍÙzÕßi^›ïkõêÕã¿þÁà–g£\ FÄ…yN a,!Flc¢HìæõoZüö_üû_ÀJrEð/¯Ø‰{o÷÷yÜ%xæ€eª};B¼#FQT"á°„‰áÞ>ô¼aå f"³<ÃE9¬Õrâ?TV=Ù%â…|›°ö©ÏlùòƒÇ:PÛÂȾóóÏ'FþÀ¾g$A™¨’h'ÿ«Ú@’Š6½ïøém{_[}úÔÐ¥ ²IÔ±ü"õcfÿ®5Ž9왣Ž1jéñ¢7D8£I‡á=M]¥VʱJF©¾ÇÖUÓ’][µ4¹ìæm#^tÛ‰ž)˜²k%=Û§80S´òw¦²|xÉ”)IÚzæÂß¾~ø`ÏH?Fí Cg ŸNB/JH?ÐßÿûS'µ*Ì€z­î·Íf­³ZÈüf£þ1ˆr›[n“L @údjÌAÔÕÿYÎú1ëWæÙZíº$³u¿4ûE×m6µ§¾¿c°·³ƒåñH”8QäÁ7Y0>‘ÅÃ/î¾úС­»8©}̱Gm+ëYiGÏØšZ&÷Þîïó¸[1r¦1ö¥µK0b£‚$,ûFâ‘Í–oÞôÈúÞðŠщw·ºze:F‚ˆ#QŽ!Tuìþñn21ÛcWôœ®¥Ïþi[ÉJ+—¡‚ÞÄW"Epøõ}Wìq—Èþ@ùb#âx¾ÈsÙ¢–_ý"ÞÛ+D„˜„ð™3 j ­Q[Ï;D.:)RHÙ:$i–d×HW]µL³¶&»šR¡yÛ–© °º‡Níuµ W5 JÙU=S¨ :ÀI :Â6îØ––öq…*®Ü’.ÑQ¼F û'/úq÷–"-@N’PØÏ[^Œ¬ÄµaÄHŽE#å•÷ß{¿6S«Ïúù^¾^ä¯ÕŠÍfõFÀTùïéóщ(P @>‘ÊÕêíí›K¼YŸQ ×ë§Ñ¬Uæ¨e¶ü?ȧw|®+&qTïH1커‘*MZ®ºäáâx ¿=µž”KÞÔ´ ‡ŽSû+žêº©c'Wól«$±}k3¨bè#[6,î»|öXÉŒíZý=‡ºá‰'±ˆ˜yö›¦1ú•u=¢’8ô³w^òÜÌåIeqG«Äâ×Åc.Ê-Šñââùáù"æ$‘çÞ;÷"ÀÀ(>‚9[ßí™cðŠ–Z±!²æT’’לLÅN•IÂ52=T.Ê–Þ_q“æôÎZi”dªÃµªc¨.É—h¾d«þ MùNýàÿЈ¥Â0<´ìæ;ãØŠëæ¦®fÞý妡í=Ú%H ” cÁ"f±È‡8Äò˜Yº|ážÝ¯NN^Òh4®ÏQø¬ÿ©}ü$ú¢ (P »Ö¬°¼±1~áõ—P‰g Ϙօƒwu?½HÚBh„¤FÏ"ð5(âˆ0ÛÿÂgß:Ô÷¯+×K$Iô´i(ž-=c[*Øk‘æ\3Eµ8Õ‡î½Ýßçq—4R1ÓFcŽp˜_xòäfÏH— ®š)+®žuõ8û©ß Fp±mÏõ>꺪® wEZ˜¦]\$ ya&f[#àÎü¡uy1çÿ0P «VD9ìóÉ™Óý¦©äÕ¥.Ì·vv-Òéeoìëë¾ÎcEàÒÍRŠ4CuÙ6ä¹L™Nx¦J„VP ,S¶¬DÑQ¨®WG\*­l‰*¤ Cέ¼g¦-}fRü´!ª­gjæþì¿Ù/ûØ&Î;ŽOBŠdÉ’uzt:ÝéN¶#‡R Ñ¡PÒ²©)o­2^¬á=$ñì›O~9Yyƒ •Á€vÐAK«mj»©Û:ñ²nÓÖþC5UlC°JKbßËóÜ›Ä1ûÙ°nš–I¬“@Û}óÓùN¾»çñïùåù~~1xpêTÀÏq.ç0´%SZØP"–Hðø§{¬ð¡O3g²b˦E5þ*ÖWÅS·å¡X„xž¢áÈ2+žk8óÆIÛ4J“e$)Súß ¥8ñÿw]¹råêFãcãw!ú»R±X‚¶T¹(Þ)NØ.þp[ËóÞÇ ÄUšG 0”@{˜GvÛÆº7O¯¼ž&8fAßj¥ÀhLÒn›aS‰YjÜzUp"èm+‘ÊÉQG~ðvÿÇ}ÒȨ3Hšc}ˆõ0ˆþðw›FtqB— %j©mUr4ÙT÷ýàõ-U-ðÌÆ5 4XS^Q?ÇöËxN½¹¶¿¯¾3±zý×këëkªéš™\•2Ôk8’Ÿ¦XžÏ2; Ò9»ÆÃP~?Sý‹ u-6bf€"¾µ·>H bV>;GU"0Cã(ð@ÎE f"‹ãÿqk_ßÂæ¦'[·>êäºkƒßÄŽÓÓnÁý½‰éjÒ2:-e I*À'ðÇ+4›0à—ªâ”©À`@AÀ9 À(?˜€­&ÍP™xÛN™ä>Û“'ÀH2¶2W®$ß:Ó²}óRyƒ dy¡¤¡‘ÏËÒ¾ ÀDÂ{.œ{ÿNiâ«í§wW®\¹rõŸë^£WºS»R*NŒç‡?¿Þß®ª–òRÐ0Ò>Ø™9qœ÷Ã'åil˜þʱ¦7d%m [pœ‹%eª²©H$µ€CÄJÄ*–$µÜ«>x»Èã>i$¯Ä45ÍSt€}Œ©¢Æò}6Þ6¢Iy#Žs{Æ„‘•ò$½¿k1Ü#ðžo÷®TðÛˆJ­Ïp>†gأdzš¬[7TégÖã‚<ð—Ó _¾¡(ßü|.·ûó›)0ë` šA^%¿+O:ðPlÄiÿõùMóSÝÍË ¤\‘€ €ISÄên˜?Évõöod)¯@ù¬WÓGµ³Cþ“ßß`k©£ûòÇ)be0éÌ*›l-1ªÉ@ DdL \ $V¡‹)ó@´¨Cy£\„@¿¶^C‘¡D!lÈ¡*9ÑÁñCÆYIͦ Iê¤C5¢W¯EN¼²º±>¢ï£È¤«ƒL ò²øcèEusùîÀµk÷~rò.º»4âÊ•+W_Z¥É‰±JÓW¼=j?÷Ó—¶®e¯À²`7í­£òyýŒO`¦-]Ìv¦žú䲪gL+®*‘‚‘&Šä`ÉÒ`·— œˆ¦ L’!ÙNGï 21•0 p‹…£¦ヷû‡<î“FÆqÏ¥vPU5MÕ ^3×4˜'½*ð!I;º\À}Úpìåþgƒ ÏÒT_ÏBÃiÕsíþ$Q7ÁRûiïÎ-ó{z¿öä€Oþµ«òvÚ1c??»áY¾yõ£väæ È3 …¼D7ÒµÏPï¼óTK€ îïjì´q@ÈPcP‰½µ@úÏkòS³ü( ‘€<9~Ä‘wÞ ÏÐg/©·¨i³§Oki^hZ½¦š¶51¯ÆÃÝ@#¶ 4X4bëòTy¨°ŠTW„£]ád˜ž‰3ºš$zªBÅÀÆ1øŠsÄŽJGÞm3C´ Ñ{®ü)œI®\ºÀ'ÐUA† ÐÕ`ä-/‡à߸nÃÅóî2Éøí1—F\¹råêKªT‚þ®xcàjÿ®Euµ,ò0´ÇÏû® ìF@!Îrt{Û3?úñæ!Ü °¯ Û»wˆ”˶ÛVBÓ6bÐuBïi¨eê3´0€G^¿×B7 Ö`ªÐ±vÙZσ·û‡<î“FFõ8!QŒ{³Z‡A$Sm+žUãª%†HHXŠæGÚOŸZ¶áņ5«—œy}Öe#×MHòƒßHKê8?¨FÆïG5 \í€õ:qb™ŸA,â¥Öev® ñ±GÄ0A¦ú{‡×èz›¡ï»9(¯]Ï!41èݳM M `@ pp*¡\CG†¾b«ª‘/ÚúôõO7n¦;vÕmnzdàÚ>Ël½øþöélGžçf)z—šMÚ8|¨kÉÇ—_ú}‹©&mC"Z´SÒˆ¡$ µÂê0 —ªÞ®é¢aÈZNÖ•´­Eᆂ’´r’‘GLx6¥ ÷Ãä³8¬‘ž÷ÞÛ±{çâW%p ƒÊ8ÂÐsœŸ`]ž˜÷øá— ßriÄ•+W®þI“•Ÿ,Þ½+”›8 Žœ”ŠÅ»=Ýb9>úðb[ë.žXZøEQ l¸'P¡—£ãGŸ f‚äÂyüï ñÿ*°Æf‡e'´\šè²¢ì±¨¥eþ[ï7ÕTóÚyˆB‚À ÈK¬¨¡µƒ­[Zò_ÇjñŒ)‡Ðd‡¤ÀyÁ”ó$}ëºüöé•­[¨æU³önóÖ©•ª’2-pÿ‡º×Ì ½Äíï^`£ w;°JðQ5c_õ¿¸jÑÜÇ)Õr<ï¿ÚŽq € @tHUƒDµýò\ pÅ2 çsY€ -R02À 83 Éɉ¯læ|P„ÓäÄ ‹ìµµtÍLäªBŒïÒo÷r-¼µ`¤u,ZjxÔܧKÀÃ<û°ù ¢eLE¶nÉ ãfÈ!p/Q#IØfFSE‚E¬ª¥à%ŽdÇTù5¦öظmÔ‘¯&^;ÚôBC(D{ÆÇ Š$©²5ˆ¢xžÅÝ—þÊ~¹ÇHuÕqœ„d“I6™ÜÜܜܛ{3ìÁ ”Vh!K¬Xºˆ¥B)•ÇÎ.3Ã\çqgw»ZmmHmb+­®¥k£¨Ñ6é…mÁØû8û˜Yö5ëïÎDÃò•¦Ì7¿œ=;÷ÞsÏýs~¿Ïï¯Çªã#>ÜŽÂážøè”AlÔ?‚Õêäñ¼822~ãâC]uÕU×ÿG膆‡¯ü¥êsÈÄøHµǪc~´*;¯üjÿ]ËZÀK"‡„€Œ×`k4Ü–’ñ[x%OÚ¬Ë4â6Nº8ëZSÖ¤7›c‡QRM]­8ߣzÁ„ht\ÇñKk»w†,Ê!ÏfÂLTXÁÅ©«Úÿà‡ƒ}>¹Ýo]¢Ú$e[ª‹ ®µÛÖ÷«×Ò{R±ìÀàLoÿæáßnx|÷=Gÿ¼…`µlgÏœÖ6®ûŒ"4ˆ…9”°ˆˆse„"ˆ+^Øé¹1ËS£ƒÉ‹V vppë¡C["bvZÛʦ¹³â%€UX)=Dw’Á´GÓm_šÝ$5…Pð/m¤† 0óΑM’ùð¼&ÉŽޕ 8vòíï¼°Õ®ž/úÍV“hÄŽÁþdFÞ£®U¸p>ù•¥Á½]+Žiw|¤¨€­›·ŒŒe¦à-àRÒ¨ÞeÃ#dÊýLû»³3$FŒà¥üù oO$6¯œÓ̇QcX ˆ\ "EeÔ‚xñè w,<ÐwÀeî%Ö/WÇÇ/ÃêèèÈÄ¥baNꪫ®º>­‚X7>>6Qk';~ƒN¹Z…Úm¢¿ÿüÎݹ–ÖFIš.KY ‰(¼ŸS¢·ìsü¾~ùü¹.(!m¦2ÖIñVHÌJ2#ëX…ŽŸcFÎ%9ð .¥ªzvŒèí¶‘»^ã¬^9SC<ÇGãüþgfr û@Â…¹A{ )3 ®B¦΄ÅÅ¥85Rð17Áçœ8VÞ¶RžÔ‹1jƒF†ÔX”‰7?ðaþ§ûl»?r÷íòÃkn;øª:#PдEsä!ö,)Å,31d˜®ÚzÆ1s€moþi;hh–Â+î’-£›šÆ…Ža7NKíeœ×IF"J8ÂÎÉUìN§Ÿyj¹„D)Þ²þN` F7¿ðüý2?FšA˜7kÚ«¿~ˆZ;±±…é)VRôãå­€/AeÙí<.í1K›†˜fÁ?*|)¬ÌÍöQ'ëYšge§ô¿ÑU&yÇJYúfÓÚìzqÇU-œ4t­ÿ\ágϯ¿gñÌ ˆ,U$¤È²À¡[fÍÜûxï¿>8íŸÁj LªÉÉSY­ ´Õšn\¨¨«®ºêúر®ögÂçZ<„Êìï§ŽvÄ×Ërñ‚$„C(,ò¼"ðb#×" ±G½þÚFËPËvÖ*f*êÖ8Õ]R ÑfŽâ)kɛͨ¿èdËT…Žã£ZÂÅZ?výÆÏ¬m›Ù A¢a$ÌbªÆ$W3ì'ÖË4rå¿W5H÷0fÍ2MÛ8õ˜cª¸K ¡¹8ëÁÒw™ÝŒh¸”ò7Ü6Øa[*ÁšóDïöœ]zçÑ¿tüòÀê¾çÖ1½ÇÅ*¶’Éô”¤¥´çjgßïZ2?¨pr’íŸ?uRýÇÉío¿ùˆ?²õàëß’/›Í“‡¼Œ9<“ztÝB„Z•ðÓ{¿æÚ…þþÎ3İ0ñͲȇPZlœ¶§w¥Ë~Г^öìÓKøÆBìjÒ¾½Ô$cI«Ø>Ä2ð9“tá‘d…¦l£Ó1“¶ž˜Ê?bIú:ì%m’Â¥,Ј‹S@>”Æ»ðò‹kC|H ú ,yÀ’{ïæ‹Å.buwÇÂ,Š‚¼æ¾VB7W […[[‚ ¢‚pìH¦TTÿø‡ÕQ^æ£M­áófæè±íKæ¶.žþÉsËÏ~˜qa…»‰’)Øwàa¾ˆuÃ$™žaFÎ15à"¦«@\®¥–q>äK0‰yàxP˜Ì5a¨MžÞë¿ »ë½÷sßbñ’Hä¦GÌ!ªð¬‚pDzðµ¯:<622I#—u£ãD]uÕU×Ç­ŠŒCì;ðó¾;ÌWDòš$ h("%…£(°ze¨ïÅuE#Nˆu.…ÄÁRŽAÍ!·LT¨p!û@2bF–*Á*£7>!VfÉ]´»Ìb‡ë¦IfÜ'ºëõ 3·æ«³dQ渠 ÚNš˜ j¤€¯nWÈe»Öø$£Á²BÂõHÁ±òÌЈž£f§mÁ6Äò¯Â=ÌÆPËn’>¬ÚFà¤LòÜ¡NpÌ‚gõºV¨£âf¡%¥4€ èÏw:T%V»Ë’Dïé{yíÜÙÓ[”°ÌÉMè³ xfßf§wí\ ‚„Æù³ù'²ý{ö=¹&$.4f##;(Ž>µ© 5D,ɼ–^xælþô©mÄ,;ñî‰ö¥‹›e¹Aà‘,ùF¥YæV,_yiìj×| Óµ9¨.QÁ“ÌKÚÆ”tǬ8¸ns¬³_î1nuT©ÒI–¬Õj5ÚÕ®lŸ|ò Dy BÛ´*BÉ£äAI[¸$Çù{åÅ­å»KBò†)¥R(B‚¨„„ª$HQBZ$ª’VÐ AI®wöîìÿǵ‘ª‡+œ¦Eé*tDÇ„$,ôˆ˜”˜Ä3=œó° ®åî9|Rï¡n¤<ô«£ïÚ7®ï9sfæöÝz?xû‰¯wÇõ¸"«ób]Ã7Ì&Ýë»û¨gß¶áš8ÄÅô£hDà¥cf„~ZÀ¤nµzÊ€Ü-¥„¤ Ïb°×ÛôK ZñÜRkÍÃ3èdÆißÏRšƒ£÷r˜  ‚ñ,F-ÎMâ¤ÇxÁ<­¯É³¤ÞÓdŠsbº—NW€p êßÒî‚ïÚ `'X'«ÔqOÀm^Û:ýx_ˆ‹ÕòRU!%®Eµ•ˆҡËúóÇžäl ÀÅ+oíxýBqÓºEŠ~Ÿ.¥:•޳¿éaµjÂ¥.ëRèܘ=uú±/lÜñíׯ÷Sš¾¾ûøµÛ7uoYïÛžzùŵ׮V±ánßÑE¸ ëÚÀIJ.n)Ä6õ«N½@H‘Ñ<8¡A­›~‰Õ2¡3@k…€™Œ÷b¿ÿ¯—û8øÄ¢¤×c³@4¢k:’•ÔÂÏ>|x||€äƒ°2iIÛÚÖ¶O²AùôÞÔÔT«zšÍWâ¾§g&oMÍ>LOÞš™¹ÉùèÁƒƒ‰n i‚2SQcŠf§"­|`þ/^\qõJ,uLP:£kqQçÞ{eÿ8 Bm䩆_`8Ýð7hÕ-ƒ¼ ñ- 0Ƭ–’§%¦‰yÚÒMÏ-bšwq®Iö0džP§fqZ`"Nlîõ4H!ð*‹âñ˜ôÈ«¯>}îÜÖ×_{Ô–9îV`w¤^ãU\Ë5XvŒ"ŠKZöÜuíX[¬^hR˜eCó;àU2Va´Àýf—ë¤DgA… t·c/ç¼`3ôÌÀË…4 W ÿ¦oãaûêÛöϺêØþoýù¹­$•û)±7.e O_º¸û[¯Xóåä;ÿ 3éâW‘ÕQdûÚG½áÝ jŸ~ePwéËDB¿âXc¬ ¸p1³¨ 0`ž†À?)¢ÅŒøò%Ñ˯ „x‹Ow1§¿éíçN>àѼÔtʰxŸäZ+,À^àºý Vr]+ðˤn6©MëyŸ˜ž— .wËÌ)¶n”ØÜÀ‘k™Ÿݰú‹†• Š¢kª®jÉÝIý衵áQáÓ“¿$³á<55)ž[‘>ûS÷8 µ­mmkÛÌl.ú tj=LMOMML4ff k‰ò rZ®?«#]\]`h†¦D’:T™ê—–è'_ÚäÒªsÃnÒ½>¶![‚̪À=dž«áʸ_õFª §>)ir ÄÔDô¿?”…>’<­gCZl PÎÃyÐßµ|š xzÄ\ñ†wŠ,bÛ©÷o|<ÞÖ¤ûÏžÛ~·Ö̳ncÊââT£S‘%inRM)švÛ†dYEŽ^WcH†)0 $%‘žQ7Ò“Šš¤…šJ] ŠÁ`ùÂmíšä¶­ÉÁ‡\ýÒ‰ çÎ>uùrm´@™ÉxŸGzˆ»s¬a\oPAY ºf+å81C’ãNÚ÷ú™“¥5øiƒó›L0Ðw†¼Ÿ{û8¢¸Òð†B<àŠï‚âZ((Z€Óã~‰;%€d×ÉLL WÞüËNy\ d˜Þ™0¢‘.Up¹V*®zøÑ…†7”H滩1RmÒj®o¹Ž 5*W+âºÝ`iêÿõŒ×QTC*ZCz)uñʼn؛ŠM8D„ÃXháš)ΚYâ&8âb@Œ:PS–‘ôx×i؃{ÙP`UhœÔݺ˜ ÛKS€â  ¤„~Z­•_>¹á‘ÝFÔˆ‰2A‚U¨(ŠdXXgÞÌ^ýÏßgf&DY!BýýÀŸ÷™V·i¤mmkÛ=7ÈE³Ù¨U1µ|B5=3qkâÆð¿ Ŭ")ª‡ä†dÅ%Š ¸"o^ŸúýoŸ©;6e”¥M6ÀÝ’¨é‚"ä[ȱÿe¿üc›8Ï8>)R¤H–N§W§Óîä³'…Péªý€®kG66:Ú´Y%…ĉ[Žmy4X·²NE“¨ªµ¨ªö«´š:~ÿêZ(•:íŸ1º‰ª[ˆí»{ïî=Ÿí„@ñ¾l¡ý¢øÕ«Øyõ&öóÜó¾ŸÏS Ø{í wmjhN}QÇa̬3t4ð13[sÑÉfœrÄ=ae ,Œ¥ÎRÀ¨[Ö=3=ëìR –R¡Éª“rá¿&¡Š•²Ý!׊3#ï±t_Ïý /EDéÀOܱÌôÓ½š’¢N|ô¾6©­e>ß&ä¶S%œÌ‡T ‹œÌ%*I!D /«"/òD&¼ÄEP•áÛ4Eˆ‰SÚ¥hTb’$V”®NíÉÇJ .Û3ñƒ×_ëûðäóÿ¼rŒl¥=spÖIT Ý/&}kŒ•Sž‘œs³³4[7³W¬B­˜wËÙŠ…<ã)Ä=ºÕ1]# *TG};ý?†ø6†iq¹õYÒees«è&ö»:À(¥.ý}b<½"*´ªÅ‚i+œÚ¡´y¯ïŠ7i\]ÜÁK"ø®9µ¾d¦k³ë¤÷¿Ò§" ’øà}܉£ý¨‡_Ê$G—HDV‰´qýÃtjdÎÏÃ^Þùíº7¬´íÓæ›Îé8/ɺãÊÛSôr¾Æ`&IfÜŠÚ·²n9‡ŽÕ¼ àO¼ ð< ’c˜]˜W(›‰wÞíýQÏ킦EC½ðŒª©Hš®ëŸÿëâ ÆM!¹qÞƒäêÕ¹¦4Gs4Ç—kàzºz5¸¬®7>Ÿú,µ-+’¨HYâ1$ð¤]ꊉâÚÞyG¯3Œ”MsŽU°ŒT…ÅCÇUÉÀ7嘣ÐP\¾çÚp·&ÄÃŽ[¥ZeLDëuÏ8xauÈÀ´JPŽ<!iNIŸõò3ËÊiX£Ã®1^µ&Y9a«v çÐA·–)—Ç³ÝøîÝOÉW´ŸN.»Sߟ©µO>¤òaQ Edîw…È/«ÛÈþañ¶sý÷ä5ÝÒ3Ýr_wø‡Kµ¯Å„(ᢼä0GTµ‚^–EM4…ÄxE—d^‚‡ˆ‹¦>*QAÖx©3P-B”(dGä°-Ö.u/[´aÃ’=»¾ÿöÖ|ôñfÇɹv†šˆihIÍLaV1ßÎ fŒUì «9zÍI0:Š"„À1‘óJ`&©ÙJîWg…€æ¶Îà„vÎ1_À~XA­²«Z·Œñ³ïoÛ‘ûn_º¡·cÓêozwġ٪=nNÇ¡d"éTÄè·ž†TÔý‰²Ùß¿~±"Š0ݵ†|–¤¥8žŠÖ6âÌJŠ<Ž<5 ÔJ8NÂcæLk˜™q¨‚_ËVXƒGüõ’ÀÍ—ˆ¶0ÆíÈ®8}lµËôÕO,ðEA>~hì¨ZÌV¬Q×Þ'ðmj¸“ˆ¡ª3l•ôsçF$>–•®Îöõ«ÑHÛÑÖÝK/]¨Í¤(²¡ºŸÆÙÁ·…TiÎ.mbÖàœ¿{곬aTÝ Îä„áZ¹@tQf U̬8‰X`¶”VýŒMõ£Ç׬Z¡iDVyAäZeA‘Zˆ"^zñgF©Ü¸á 7Udnîʽ¼}š£9š£9k×®/7<Ķè/~þÒÂû»žÀEÂhsy^æø ­é]pä½~êæÁVZÂÝ^«Œá>§E´oiÏÒ]vëgªÆ²à.al¸çÚp—æÅdV-׿«­ñ‹k•2œ„êàzX$ »¹Ù.'«vÄ¡Æ&ϦæsvRs»M ÔËO•Ÿ«Ö¾£EÝuGËå?É<ÓZb¢(µ ]ªðTÏc¢ÀÉ<÷lï²;‚_ûx—(‚PRÏ7Ž«l 5à·'¸ÿ¾á§Iã”Ð8.5N¨“bãß8‚u‹¬¿uÒ8jü’Ãá×úÕ‹û„¿¼¨þ~Û3"õ¶ö}«uI{ËB%BŠ"q¡‘¢DŒ rLÖe ňÜ%q ) iDR×U¹žßÈ-}ýµ¾óç·MOow¼qÇÉYF ~BÙVË ö‹nA•¢2I°ó¨Æ¿`u0½x ߨ:A­Âg°âÐ-7áXùâeÝ÷õš÷¢éô[¥BëÆæc‡ÎkQ•Vha.dMç™]ݼTâ”°"½¼÷1ÇÌÍþ‡ý2âºãx$$K+­4žžÞèvײ± ¡N8 N(TΚr˜#ˆ{×µ‡ÝxnmlLŽr$MªŠªŠ¨¨RPƒD ¾ ©J!4ŠZ®ûرq0öN³HüST©J"WÕþô“öÍì›§wý~ßÏ/›PÕÈÉîu”Nºz¼[™¤­ÿ< )°¬B(ÁìdÄó¬¿\àW-ÊZ§éÄåLZ¹“†Ówìˆ|3ìèQǪƒûóÙ­?‰=·³sÙß/o6Ût ðCÔ=”mÍê'õVtÄJç°p H.¸¢ˆ¶ì:¾aíóÏ”ØRˆp„)" ™RVñö¾ýYËÎß¿?:ÑI¨`+XÁò–sG¿º·w÷žŠÉe4Ÿ¬BCŠSRJé‹ÕS»On´³qU­‡ÚÍÑ L‹[Mêízȇ#v›r»Ù±Dh?p¯P•=1䨰šplø–¼§ åŠBìä ÁwõZãÍ[u†Ñl« -€%°|(f¡€½kvܸ½?ü GØ1Ý“Œm—/µÿú—5««ÉêUBõJ|øðéNÛ‘¶¨”I¦SUös S‚i GJ ŠY!€ÈÜißÔüAïÖ/«d)O( ÞƒŠ~` hpöäõyà€$§Y6ÌìQJç1I?ïö·{=Ð?߆ÏAÛïž"n7rÏÜ~a¤»øËƒèÂüáVb=Ù´”Y4¥¨’øxH' <&~c„¼@96FÆ€/TÀ%H@þгbqq26ÿwï¿rfPTÕCo5͸mƒ ŠˆY5fËq8ït´4°‡%'îe[-9j)ͦœò.­6Z 4è0dtÂÁeUÑÔZAÓ59ö6#~õš¸sžh.1¤ˆþ`@,‹fO™¹£}Ñ™³5Gެ]°0 P ±ÓX;ÛÒê¤û·X r ‘'»?Šm΃C¾’z]üñô–ÍúitñÅK[LS„)ydkÔÊ™Xcítâ,ˆýïí™+ßHèfMÀÝ8¬âËÒšàÑPëm½9w€%)¸x«@–¬EmG<Ñõòª%e!ÄÁ8Ph@€…Çrïïì?`f.—›èT°‚¬`î‘>øîsó }€"<‚Ê”Øâ-âã?Õ)FܲšÕ;(0RzbØHC>ÏzXÒªK-޳Íä@[M:º—FêÍCnžplø–ü³Ëáie¬À–̯PÍvÝNiFÄ4Zò›[‘6åÖ‹Ÿmþð÷ vo/VntØrÂÑA/Ý]ž™1‰²>ÂxÂlP`±X_ÒcgÃׯí,|<¤˜ß°¾²§g]׉¯¬/¨§Ë%c4¢&_[>ÓOY6àÃè‚ñ€áTÐíCöAÆíg=éÃlÀ›~Î{3H<êÞ`ܳœ7N¯ßDἑÛ͸ðžõè>t‡¡ÿ'ð-LWNçÇ@£}äÊatj}¯'—3 æ”ã"¿ æxÀÌÌ`ìǰ{!Ž ð ³ìO£Y¥tÍÒÊÝÛVôžÜ|ëzÌÑ[€»L) ª­fl]„ëšUã¦6∵é2@¾S¦Ô’Õšm£ÞÑcŠ³í´¦5B·y»%§ 3𱓥MÓÂpÊYk‹šik¬›ä‹[ä!LTŒ&˜­ ±W?O;VìÀî¥e´qܬ§XIëÔÕÄ!"ˆRÊ,\ÎSøäÓ³5YmŸ.µézØ2:¸˜Â˜ðû›Ó,é- "Ú¬ë‚ Ïš1 .íNlHßáèm†p3ääW†hI@bi=“Ò´„ewœø¨nÍÊrˆnØ4Âa˜d€ ,ÃÌ=çèÑ£œƒ V°‚ýßÙýññq×}èÝ1×͹¹ñQ77–»Ÿo]8ß?ûéJJ9‚XIJ €<Ô¡˜]½bѹ祛"0†ùYO@Šóê,Ï'ž¾Ž[ªŒùÜÅ!3¡K¢¥¶ ÛiÇ{Ó`Ë­¶Ò šeªùlßlšØËÜ*¦K [Ý¥êaÓLB’ÿâÊËÝýÕ»ÚhŽVÔȹ³ñƒ¿­NÅ«jªç— ¦Ób(C‘ïxÏC  jâü…fı„pS˸m˾»¤´PàQðÇ^’Ô-]G7ÊóÌŠù¥¶™¶´ˆc4ò¶,œÌúYä¾øë&Ãl€éYJ ŽÃÒšò2ú_‰/®œ à›zÊÛuég¶ @žòFáý°ÙšùgâݽS¦NöcF`‚SÈŒÃ-~–û¤/  )éy³)âü®µÐƼòy“À–óϰë^šš¿?« œª€e ‹a†uì´d¤OŸÙôÆÆé-›Ÿ’®C06Ãô,# Ð ×ÚY5i) €dþ2ˆºÔd*±ü }îwÕÖ¬®6ÈQJ†Ûˆ½úãés.œÿÔÍåò™ÁËð3î:^#o¹¼=L,+XÁ öŸmüß|,—ƒ¬2zoÔƒ’܈ëÞ½|é/×½Êð!‚9 ù¼\ø*Bß« vu½~SEFì6(A‹ó"õ£h*â„ãÄ×t€ p 5Ó 4’Õ½ÕéRÔ”Z†­&KŽZrÊë•¯Ö Zofb÷ìõvÀÌ[>°Zg)­÷Fb_^{íø±7÷½µöÐoVÀ_§7†8&„AV˜RêÇ~–°“¶LÀ¾}V¢¦$"µUE„>ÖwA”µMÞñ‡ck(á|µæIUïéœ÷/öË56ŠëŠãH–,­´Òht5ºšÑíìÊ»®qSJP B åÑàòpR 0^[Þ•·ëÝÕb\p &Ð’ ´• i‹Bó0 ¢Q;6 Ò‚D¢&‚ò0öî¼îÌìÃ6öô̺¥ùBT‰¨Ö®V+í™=çþÿ¿ãXÄTíO<ò6ûþþX5/s-­`+.C|#*ñbž°f‘c²„0„¸ÁE$Gª+·,xýèš›W·šr#þ4öè©HFMòn€ Mib¡FxÀRàCßáï¢ ô}' =à+\`ZZ û«ƒ$×oìyùå•¿hŸ¿oïâ×NÔ~ôa³•mÕg{zê$À&†}ôÛ3¯œÈjоöøð‰-ùéº*UÙ¯¦Ÿ:YÔJxRÆ òpÇXæ œnlÛU}þR}:Õ™Õc@GÙ\SZn4µNšNŽ˜QKfºïÐ5 3$”ç¾+ó㭿>½z©»ˆ°—ð<'Š¢KÀè©•þ~ñª"wF ‹=1«‹ƒ"SòГñ‰"£Åø_cäk‡;¶1aŠ ÝJ'ãQ„\ˆE\ [›q æðøýfSïÒÍæÜÈNaÐ4C‰‚N ˜øljûL=+õÔ˜;O5fÈy1’êp#0XVßkȉ 3¡ÞJZ™¨i$å¡¶QÚe©uÊ`øwÖ‹,ö0↙fXW:½¨ÔÇ–Ï›C–ÿèáí Ë<¢Äs¬ˆgtŸÜ@•:“Ægû}ù0vïýåʯÀ5O|×ǹx¦Ô‡ª*ˆ *áWŽ­!¬›xJV- º[Wê 5¨·íØô˜ˆÜ"ï:ýêVª&©„w1 +Ç1³zË´¥‘^Ö©ê]Æ~u²ŒÝã¶üvgŸcì ¬ö6wþ7âá ¸ýI6à«”x¯Èy"`µ¼‚ qèaŽ)ç¡ ‹Þƒ=áßÕöxwwÍ—ƒÏéz³¥‡3Z8o8C®«Q% °±Ô0`^Fmµ”(LиÔÍÒÖÂuˆ)CêVb0Õlåg"šÚbÐ5Õ³ÂMõs=ˆ—ª¯† e‘!=ø­ÊуE¾ätw­. yõµåa0"+VeóñÔPË©îMTâJ·=¢z›a$ÒrrXŽQ« †A¥é:‹†3†ST8ugÕ¬ ÷œ‡Lf«’ޤÕÄñã+ÏQ)ןcæ0xÂãh4:øÅ è€ɱ±)%¹sg|rÒá±ÿhK1ŠQŒb|C|m‘™ø/“Ø£ºE}ðHE`b8‰ˆ"Û˜‘Xå/=òÂ’´’©ÔRMŽ€C:{®ÈT>pœ¸ÿœ2Ø(á¥àw´= z¦£ÓzÃl¿6iÂß·šÓž\XÅ»Èìr×WkèÁQcßWB~> 2eå+§›(mê=S÷ùÍ L[?jûÁ FaùºÖééö#ž¦ÔÏÏØ@Àãñ .[ôsÄÇ1O¯¬ÙòŒ÷Ög±kÿŒù0ƒ /sìèZYÛcZÿjQ_Ê»%0Ù»–g}#T(>gÔDÎM[àì³Øî‡vŠìƒ§`÷ öYÀ·Ýï¶Ï±ödŸ‡/ðöà÷­ãLïn®£†]QÎÌä8‰“0’8Ì#$bàù I"â}–ÈúÉŠY/v-¿Ô¿Yù²iT‹æÔdNë é„©ÄsF,k¶P¥Q‡{¡Æ²p`#UšÁúÔÒcÀ·àþTIz‚j­0QΕђFª-#w†w.™)AÓÙ¼¿sÔèL¥êŽýi#â½ r-šçÓS‰Œœ„_Ù²ñ;<ïÂȳ+´@Õd-^ûÔ\?Ï{Ü{¢K³zòúµd¸Yº|¥A6ÂÔÜ›L/eõ¥‡ Õ˜CŽÁ7Ì{ÒHކõt`Tkq ¨£¿]ý½ñbÁ¼Db=¥²bÖ¡C‡hF)ääØW·§”˜äÁèZ1ŠQŒÿø«ããÎ^XrâÏo=Zý8!ö ìv•wWç¢O®ï¦4¡(õ°Êåõø¨Ñf AÇ@»¦Pô ä×Ò"…|ð8q_©‚S$ÀÇ Xëm¼€$%oÊå›eµ>-7éJÇ©7Ö>¿ïû/>¿êÓ/"'OþLäÝ—BÀÒü„9ùæzšÚ¡iÑ ë%ØÃ¢Ë ‚¿+jȤ›-õ@CÝ\‘%¶ÖVŠl7•d&_¶Áç^¬_;÷ø‰%ïõ?wãf䃮ßlµrÊðSi_·ºsH༄ç|WF ¶V–ó år··,Ì™ûu¹:¬¨ GŒ4´©yÚÒHPG!ûY{ ç}Ù}œC&‚Ýï±{±Ý•³NìxƾÈM\ÀÊii KxiãŒÕs¤GD¶œeÿD„Ápyxy ÂaAÄÈëa¥ùUàÖǺ_Yÿù8¥1UmÕ”V RËHÂE€!¡2¸?à+ð†ónGÈ1w>Œ˜ðÔ#9 ¦ÏÓdFM¦ÒÉa9öæ_Öš´ÁR‚¦¬Yµe+y,ìo_“ÕZnëÉkþÜˉë‚–úQ“,·œ¿¸à˜Ÿ™"{åòM è¨ñr3׸mÉ™ž ºÏ»©º3o&€…HrFTwp: —4ó tª¡°œÞó“Ñ#mSRÉÏn6w´/(P"a°Dâ½B0ìóæÍë~ý‰ññ3‰mß¾í0ÉݧÅ(F1îw9DcrròÒ¥KµµµDð`䘬Š"+øWãöê«—ÛM3¤*!ðhØ-%j©a:Ü”wÄ6ò b O._8OÅÎI‡Iô˜šg‰äM0šð¿Ø/óØ(î+Ž#!YZi¥Ñh4úiF3šÝÕÚŽjHK 8 Vâ$&ÔP»¸â$„ƒ÷èzÙÍÃjmŒº)4MD*Â%µ‰*õ9€ø‚ÜBTš¶‚cïÎõ›c½6‡ñôÍRÔþƒÚþQŸžvóÛߎ~×{ßÏÓÍŸüñdàÝ÷êΟ}£áéY Ë”ŸöUø˜š^žqUø(ŽáXÚÃÐ|íþkfÈ´’+šAÐ]I½»oV2ªÕ´ÐÏ·7WRú(rÉSžË—€vÚ‹jP‘’†ßÞSϹi¹—<ôŅĈ"ž:ÓÒP_ýèæ»Z %JôÊWbÝÂjŠžÉ"V`y’pù„»v…|ŒËÇR/7»F‡cã…ø˜.Â@Œ®šZ.tßÒLiœ¶‘ƒ½ŒÝÇ:>Pš-@È'¤}„°{Içñhi00   ` ô÷ߦ—£þ 1ðÙ½Žª¯¡}, ÈÇ À„ (q+P'N¸xε²qÖΟ-ÿóé×rr\Åmжk1;Z_âÀ8DÄ­¸€¶ZÐP‚-f©1e$çÄhà @B.€‹¥tA œû¼ÕC–ñ,òpîÓ'7•PÑX»ms"=^5-©Â¹¶B1 <áåI×pkµ…·ZFfã†g}´ûÎÃîrƽr¹÷ÃVjz·ôUfÂ,i·ô8Î' Z×PïH§cªh)Iœéy ¦Œ!§´|Ä4#ŠžúË™D{ ÆC•y(A UÔ³% ‰b9RÂu`xq Ç )BïH¼’·JG£Eõ\ÂÄM›zÆÒ× Ÿíz{çñµ00ÕP£óæ «dȲ÷ö6]W·œ9à(‹ÊYÒ}äÈ ]ÍJ¹(VÓ¹‘ÎlêéoUyIBi_ÏÔÎþäw/šr–ÚM- q ïF2¹ãýW’ÚhPº„H‡ûóYKæFƒº¶éÐk›Ê+x‚!Ü"ΈؘN›ºáÐÈÔÝNqÓ6mÓv/ØÔÍ›·2ÆžwvWUÎB4âXŽy%xž¢ŸOïÝÝ$«ºÚ Tx\‹R†!Â#ä=]±&B²ÕåÑ8h÷øÿ®zÿo®Kâß>yèØ²üpdLAM`ÕàÛzžçi’!¼,"çÏ'w¼µbÕ+Õˆ¢x†ô#÷¡ ™RêûÍó8ª Qå¿ÞÝ„p࣎ƒÖ¿t‘Gɧ‡/‡Ë«I’ð"’õ•GÂëëëj«€LxÒÓºjžª‹y-pùrWÓó³ýœ[ } (ˆ¤¾ñ ñÆ› š0r¡r¶(mÁ¸]Sãr.E«E]ê0¥d1·y<ŸV¥Œ¢®3qÐÑÑ 5•”)'î[è¿í}äm®º(aÉñÏ_Nú(ûÐ rá§£îÒhÓöaÁîgK B:ÃàÍ€7Дþë~jJhY„*)Œäüb(ŠC<¸—b}´»®Æ“þaÃÉOW8¡„ 5Šh*Y8‚"•\´€“À*š’P¤¸®‰¹î‚U”.Em7¥Î±\vBMèrÐÐ;ñhtB<°š"BÕ³Ë邼e\ŽìøÑ|šD,Ã5-]`™2nÑq‡¡FòÒj},ýñáØ#sÊyZà‡Hæ§›k´‘n'NqÐù”ÓZ>nâØiD 8“W²Néá TælæÅkVV¤i!Iɼÿ«WkçÂÂ+8A@Qùdßž½ö”cw;ÏMÛ´MÛ]°© ÿÉÉ·z€7nõÝœº:eÝ´‹“öÄM{Ò¶¯?ñÌ¢ÅKŰˆãY/M²<í(ïw*±Þ¥qMÎBâ‚2ê®ãÁéx4^ÄYKÞd©]†Ö¡(q ÇT-bé]Zc©¥üofNnûl¨Õ”¢‡ 9eIÝúHÒæ:{Nܶ­á›5~„/]ÁSÄK/ÕY]Û/ïï[äŸõs7Øÿ‚œé8»ð¡Y‹y’í?ÔŠó1(?·w7òŽT”Úl¾¸Þ›ËV2ÂLYÞ|Mmc€ÿ†§8†æ¢ÂËpu fH—ß,ݲ€¹ÿ{à—{–ìèzîÃßÖ^:×ZÔAÄÒqõµƒ¬|ÝûyÏÐÈ×íƒNúh±òý;¼±åîÚY3 x ;ãP lâ´ œŠäç×ø£ÉÇúޝ–èþ„"^ËuÒ5Q•Ä‚™-h#Ÿœ3XíT•Œ®f€L¼WÛ 8b)A-ß¡*í–Õ>|1ýöëK/,Û¸¡.öùK©9•UpqDì{§›á¼”½0œØ¹ÿ…õ¡'ý>Ž¡|À!r34Yå¯T/¦ ¹U͇L+¡iq]JAYQÉ*Rr âE(Wãz¢ …q.UÄ)Km5åø Ó?Ø/»Ø(®+ŽçÉÒJ#­F£ÑÕŒîh?äÅà¨8»„‚ Ò¦!.ÅÔØ^{»“õîvµÆCiš&ŠÔ$M¢R(„´¥-uÆÈCdŠÔÄ öî|ß™Ù]ü¹žž±Ý”¼ñ@­öìÑèîµguï̹ÿóû«áœ‘°”¦”¶U1X®F ¹¶@¤¦Ù~årýovU¯ÜÏÓ¢Y º¦†§V<ºäü§_‚þ‹® ;“S9#IßˆÕøøØ¬xçe³¥(ÅwÓøáÜtƧ'''aÞUWÆâ„›9kt{K+æ¡"D#?8º 3žY>̳åˆõøXê·×Kr ÑÒÐûL%r×1ãsØ×lÈ6i7Ôv¢ˆ6éR³ ¥9%Uл?ûlcÍbn¶P¹ùÇÕ¶µMRê ¹´šm/ä@–¯|•zrU¹À”A‹ pÌ,ÎÏyiÄЋÐçÎ× {³ÙH¦xš °þ3ŸÔJÌìöÆEÐŒ|,ÿ«®•9«M—ÚþòáÏgá æqÍÂªÌ ¨}deu%FUàOö4OèâSëŠózfû„åK+›—¾öÚšã=›”Lª`w]k±­YjUe”¡tiñ†é¢ˆš‰šj \ê´]-ÑÈÊ“¼s’s°÷Ó'\ñ㔯ÿ]á·užU!jí÷³—LDŠ'À  #Ìfqu——œ;·MR; 9ah„DtÒ,)[eµÁÎGUµE'[L+lÑR¦’4帥0$,à¡E’uLÁKÙ«ÝׯĈ!|oëñbohy5¯]’Yó0Ôª7€) è Ïúè²çy®vþÑÃOçôpNgb…Ÿña†Y¶\ؽ÷ñ¯¯¦u#¢)q8£VšdE[é±R†ÚdHÉœÞÐ2œKf¯7çI’È-¦ö‘"9WÚ¡M% ÌlÛÆ/Ù¿½~Ó}å<‡(#Ñ~Œ‚Qbôy˲œiOTt&§óÛ¾ bllôÎJf)JQŠÛÅâÄ·-ÆÈøøðŒ]krôǪ*« QBgß$ /ïõ>´°ªçÏ;wt…Ãbä  àòñÕ« Cn/)Sßu̸Å4¤XÁLN™»(˜8ȼ›™'q"5)Ùß_´Áx}~ޏœ¼6Øuø½FËj#z“&§²ú>?ÃcÄÏ ¡Î_Ö$ÚVÿ Š“É1eϬ›« …‚¸nå\ãhß»û±ô=Я÷¿óÃ0çjõýšÑž×"»ƒ,ËQ(Àx/^hÊçÂÛ·Í÷ñ6Ô«{WæӇ߯ãw+?:^74¸Ó0_ FJ׆/äÚ4) ˜Q°RÊP»¥EsfÔ4š-5 }ŠÈÀWàUFˆ%·ŸK42“}”›½´s‚qzç#Ú÷ÁÕë|âuβ×à}¾v13Ÿçƒ´ñÐ’yDc?¸W˜`øÃüpAÕ+{—ô.ªÙ4¼Ð¼‘„r…'¬“0”+$`?‘ÛMÆIH"' QÀ²hÑ‚µŒˆ.·ž>¾åéµÁª jwwµJbö­›- ÅA…8fÝc³ºSÕ}oÐwÛj Žá‚ÿã‘͘b‚8„1Ã2xÖ½÷ô}¼ÕÐá˜$l5ðc뢢4õÛÜ%É­†Ñª*‘a+Ó“F6VÐQDwÙÙ”à1Ü›É4“ëjÀéøßj—-äƒl û¦) káPeeèýCûAˆ&&F@FÁM‘ÉøøØ´HMKÖÍNª¥(Åÿh„|ã2&gÂ=àS“…‚³Wj7> *X‹Äc?BsCüÞÖg3»ˆº*.\ì ð!ášßÝõø²¤sĸí]ï»Jðk®»ÔÀÁ‡ˆ–$šRÌVâj&–3ÂyÒª);–×Ì‚½cÌ/[~öž TÞÿE›¦Å?? ²0cÁì¿ û§rzúÌ™Í>†XåÏ­—3á_ïz"Èû×Ü0ÛPS&é¸ðEC³¡=Ž–µ8L*rdzkjæ`ì§ËŽùpÅÉã[>8úÓ ýÏ«rl˜„á.)Ûfª€pÕ¥¨ž‰ h@°…øT÷‰Ax(C‘)‡?Á<ÌXš·Àî-ÑÈÊSÈ9źïc§9'Óƒœ>Î| Ï„rÎ1g½ýøƒ)¼b®¯ 3~–£iŽA> *„2ñ–#jmµÿÐï7ª—ã£fÌVESNÝÐÓ¦Ôa©ñ+oYÍDTàÃ+&±µ)PÛ•Ì6(ŒéÌëQ]ÿtìÉk° />ô}8ĵ´§3±¦ÿâvËÝJ`È´ltLï$YÑÈÆÏœ¨øç/Ž~°¡f>Ò¾yAÏÅþFƒl#zXÓšÞxñbËüçí·6(FÚÎ'ä¬<µÈטh.‡äàdé5 %š€É[1Kn×3",Ò4S{vÝ_¢ nÉ0˜‡uQÏl\÷Õ׊ÎHѹ‰C&KRŠRüŸÅÍò߯Egêà¼üR7ϲ ‹˜f<ò±OÓ7Ì»t©Ã´[ Ò ~Ç”Å7÷­æ½X;?ô_ä½ÔßjªK¾û˜q‹ Ê r b®\åõÔh®ÃÔ¶‚8ƒ»øGÃÁ·~öÈüšÆxIp°Ï¯n0¬ðžÎÇýŒ‡§;_\ ½þ† ?Ødhý¦¥<õ`/Ûÿf-@Noo­×SæÃhÅâ E ƒÃ#Zð@F(Ȳ½=uºSyèÀÚ=é%§zZ†[s¦Hô¤¤FT+ ½f˜$Mµ±@¢S–3™×;ݹÉÖ F7t~Am/Ø.~YjWÁLºcw3(bë1è %¹CyRpz9ç4ãœö:}”ÓWÚe’ÓhN áÉôÁ?ÐN/å|Ê^?H¿c]âAÍ`?ð´~RÁ”¨4PhB ÈRë‚\(…lüX/ëÍ®÷Õ•í»¶¡´*©¢V­ÚôCUjZ؆Å"J‰’>"šiÖÞÙ™¹óÚ]Û<ìé[D|©Ä‡ªhŽG;gvFë¹çžÿï/Öd&a­W!<ô< ©³Ü ýEà9¥L¥Šù4^NJë…Äí›±7~¾ÿ›;° ^žái]•g(óõþ#žË…LÈ<ó»ÓûZ÷UwíÛø³S;>¼Ñ:Sì;÷‡ÕŒP¸‘Ì‹–Õ——RÎ~Û ?=°g½È`¹z_Y5Íê1Mî.Z=–—Õô!œêJ dE± š3e¨!k:v_ïÓ$g÷fôÆû­mj¼,òpD³nìF ª©©º·Pš·ga@ÍÍ͇ZœTóŸËQŽr|1biwC7a:nXÍ]šèUôD^éP”nKó䄤¦w7­örfhƒ‡7Èr˜äÒO33 ÊÌsU !”¬£0ç§²1Bâ²–ÖÔø«‡«Œ¨e¢Às%²žxxËä_’ªr\³Ú‡ú7ú0対püEYŠj7XQbÆ·?#p¼›[ñ«_6ÕÔt.éܬËã¥k?øë!SN[j¸ãðF¿lOÓš‰³‡´|à¼UCK’Ü茕ºP%ç%Z§¥@1Pa©=¦(ê’.iÑ"qÀÆT#@SpÔå0<ªdÄ¡¨äz`Î~À]Î$@•2<¡¼H?$ÆGök_ÀöyÎgìóPPqÛØ[¼:Æ}™±/Sö­½%¾þŠÐ¸šP-fE`,bøãù „Кµ•©ÞUï]ï-Z£D ËJ+Ñ:L-DòAXw“ôXF@S:•é´ lA‹—r CÈ+]pjä#f!|öOÁæ¦zËyYŸ@ñ•<è«×¬ô_]E ±@A_âh—_ÀßÚYwòä./æ½ü†"œ:¾ÇÃ,ß¾µ‚§i/özÙgÞ>¨‘>K6ßù÷@WÛÊ`÷Êý=^,$UÒ-ꀓÚý¯çC³F´!?h©†…¶ÑÉà¹3‡6®ó‹ˆr³àn|ŒKtó•Ûw\½òç»wï>:¸îÝsNÁ<=ñ‘YŽr”ãsŽGÅg›Ú0Œ¾þ!޲ |n/ L¹ªÝˆ2;¦³ai*Y²†@Ñ4¥gÖHk¹XQKšZdòr ’§0B^!.êgZM3ùÔ1ã1³¤ Âl´Ì6«|÷Ýöè‘gWù)¦+Üˉš&¹è¶µ¾›ëê°cÑoO¿lÙ\›i$ÆÎ5WpŒÈ¢ê*áö§K?¦äcß ×ú+žñ ô‡5³I€]ÍÏ †tùý[ù;éY£ïÖÍni*^Td*‰Å—y¬¨ (Si@]{D¤¨ÅgH™ŠÓ£E’ÖIŠ( 8‚ÛÕó)à=K=Z"C §[îv¾¯'M%¬NwY$ŠóP˜d‰CÀ¨–iä åeÎó‹r·Çð",òð \º€ìó´=Ä‚í‹n{|¥ýŽh_€‘C,ãxþ¬[z9ö±±j¹ßµÂÇñ4³BðÒ˜ç1Såf¹ 7ÕÔÈþæÝ’”Æ€Uv–[›JÈP†´€B•8Tt9`)ÒLðÓ\»¬tÏ©‚¦••1#/í©«ä?¦ß|³)›^ë¯Áh5Ë2{÷­íêØ¸¡~%¦˜j¿ÀÒþ Ž>}ºYRS[h/rûyQÄ Ëàpç×1Œ°*uuD_¿È{{Újþs;dš!€"SIêü¤äœƒ¹‘φ ™‰3d¸”.ItÞþøäÈà6õJõqˆxìæ0VÅ^ôMö#6ªå(Ç#–˜d‰F®]»ÖÐÐ"œûŸAæ/QöÆchGö¸—¶¯ÒsüØ)w¤E¬B.ã®`/rq°M±Wd¼†[_ÉôG6|ô~zÀ”cÎê+iÈ’–vü‚.|ÈffaDÎ¥ jdŽùŒ&ìh3ôû·÷zRk²R˜ß÷"ÆG [¿LAŸÒH߉ëµLDµk*]·>Iå´®[ŸÄÛö?ËÓ"Æ4æè5^ñÇ6OÝŽõ`’®Öz®…hmùŠ&F2•°ThÎ0t{ ‰jzTÊu¬„I Ø£I¡--ë/©zjòJ¼ygµ›¥ºx–àAmÚ´irrÒ~$ú©r”£ÿÿ;öþüüüÃÍ»ä)œÂì‚=c/<€oµ»ƒýŒh7Ï`$pÈÃѨ¾šzíÕˆ3õnG.ÿ‡úÀL3õÀG7[ê«O{ìç×ð[ÀæÜ³Ž+Ùà=«† èr'è£ãèsR=+;P"ɂե’vCK‘©”%'æ@I`ÖŒ’\°¨&À…Á$J’¨éBn¸H"Vn @¢ºÐÔvEú/ûeµyÇq¤H‘N:ɲYlÙºå c%¬ÉDy[5mˆteCám I”x9.wÞq„d… ÄFAC­hµj´Nk¥NQóB^†èZ*JÙ²#ÜýøÝw $ÞÏIµíf¡¥î§G–eŸìßYÏ÷ûû|%UYd¯™Mܾ) Ía´¬¼²÷ðÆ_ŸÚ<Ü·ò¦¦¤L}ב®}Ð$àE Ø{Økè±¼–4r±k—›+#¥dËsåB|E€*ÙVÇÞ¹upž¸þ—ë+C#ý¬Û=$€Þ) O`€aì3Þ9áÖrG°;@/XŸÀ*^{«¨@¿K1ÛWS?…±ß[<Ã`]96ÂùöÔ¯í{{›‘ë6Œ„ªÆqLÜ”;3êè `WÀaA?b*]º ›³ÃÒÛ´œ¨ç€"b ‹¼!‘ô±Ý?ôó4# üÊéc–x+ݸ³ae€ãx¶ôøËëMùȤ–WŽ®­âX ý‘ €[ÁÓ¾dsMT“•Ò¢bseÓ¶U¿¹‹dZ€F¡%&çb¶-eåÆùöÏ„Öc䢶•sÒ©Ÿ¯_¾´”…D—Ñ4Ï»u9Ž3ýØžq§Àͼ å™Ûœ¿=™™™³»b«X_¶šÓæãÇSîɬ„=0™q?¼6\[³<Ä…yÄ3¾0ÃÒ¾}»¾yõj›¢%UâŒæ0ïÇÓš íȹW7 4‹ižã¨eË}é»I塸ÈNͤ³XŸFâOkêåIÒ!Z¢_R–›òù¨Ib&M½;7©°×È-ˆiõlP†€…5i) ÀŒ¿^?y¼gãššÒÌX`É/O»Œ"¾D”ÖgMßÿÓK„tÛfó„ÓÆNl¨ý:Ïb–öŸ=û]9›úðâö{·,;vqDüÁ p‹ bá©ÚJêäѺìƒã¦´gÁñ H#_¼.qi ¢ÏÛ¹ÇÁ9@îEô9¢ Ã_à¬Ïax5ëu5D{-]âì>aô·ÂO¶Gž —iÇÒˆõ³…¦œ¦©WU‡^;Q§¦cšÖl˜ÑGvÂy¸ÇTEPJ^;f«]j®hÜ6ÚA2œIGKé2Pz«.·O˜½ÀÞ««¹ Í T0Àø\ÂX åB(=µtÑT÷þ¬k•@ùƒlhÅ×üC#mõ;«V.Fwoýøö'ëÖ ï½s@V p‰, ^D²" Ž¡Å‰Ü9îôÌ·UÙ>²+¹˜nô~üÑ¡õ‹Ì"††Œ ×֭ÞpåjŸë:îlÊú·×ͺÜ\þZ³-V±Šõ_ d95593«YCÜYýÎx×'&';cÃ,—ðÈÂK«Ëýož«ÏŒ%'S›(í¬ e^Éë`5¢¥½<š7¬bC8Œ1…êŽ}ǶSj¶uÂêÔåy- ¼èiM=CkÌ«Glå<Ö±¥±\Ûg·ÚOzñÀKÏîØRÑÑT5ðÇð@Ël´Œ†2‘Ö‚Ýa*q•$VWÓ`°A&töÌÖ‡¹®_½¹Q>€S,ò-áaL…0_[å¿q£E'Û ê±„¸F€4Êà¦6­[F%¯žÜD2)3ÏšûFG“çûên|º_W»²™˜o%Õù¿ÛÿëúÊÐÈ0å^ f9šÄîãöÓœÀп@{·†à~wÄï^ô»WÙëó’ߦ½“~ÆchøÚ Üóìdÿ²¾ž²új_MóX`à“sÁûê4f¨åtèÀsûKKŽÄÓV!Kãf ØCWZòzà†~€9'šŠäh £Ø¸WsM ö‚Þs/ÝøÚ™Í»¶¬Þÿ£o=¿jéb6bPo÷VÓŒç²-þÑ\]Îh)Cá®TcvÈ$uó³zÕlêhÚfxŽBRl \7åxAOj`!ÑVÛMœ°¢òƒ¦yiD!û€o>©¤Ý2SJæè{¿ß±$ˆ"‚Ó [`°$™H?ÊÌxÌ̹šG “““pœš3ºb«X_Ê* žlK¦§gž<¹rmè5µ‚|¢PˆÃe¼¯aÛÚ»ŸJ“Öqp-UÞæ`*)Ë4cÏ|îA²ÍŽÖckqÓŠìæ(:ȇ0 …ßÕ+ÍDmÏÛí6ä2EÒe¨àiM=¢´ú>èlöþ½¶½ëy¦”ì@ƒmYÿ¢w³;¯'um/¼×È»w;uîÌ‹0+ i±ìدoA~–çø55AEë¾s'ºòŠ£Ëy ¢Š0`Ç1eƒÛ[ju²ßQ¥.wD0óƒJË0Š vg]H'©œ¼GUãð–q;¡“vSmóì”tx,'/<idžE¹Ã³(28×íŽ =¼éÝÁí¹"îû¬;´p4â‘v/pîHÀæ¼yaŽ Ç$ƒ~÷2sý NÜŒ*C˜F ÆÏp˜ HÀ4åc|`k}åùó šÖ¦È¢ªÀ¸O:šd“„Eâ6‘òFLÏÅ,’ÒåDÁLÀîÕAYJ‡JD]•€dYü©´&LÑ•Á’t:©ÊIS;,uV ˆçÙŠ•ÕŒc ­é6Œ†?_ncéL  Á+—šäŒ¤eãFÊ&ãºdÉq#Ï«’w>Ïþ1ä8pˆe4çíV=× 3aÅcî§ã õ+Ê0†ŒÀR¬À²¡z¶ªö“¯ÏÚÚlÈš­Ç§Öi‹U¬b}aMO?™þWR˜qC@¶§qŠe!gP^ ý´€¸êÅøí·öÉj÷#K4sm†Ü^Ðã`\`S€:™7Ëäó1Sé2ÕĶ-íÞ¶‚£‚†Œ¶å…ˆn¥2™F[MšrGÞˆ›$ö´¦^Þ‰›F'!MéÑÎï?/4Â4Ë£¥a.ˆý¾ï­çÉÃW ZsA?Þ}°ªB( P¾·^ßdÙ-9eÿý±Îÿd¿Üc£8î8Ž„„tÒI«Õj5ÚÕ®öîdìƒ!&”ŠP·iJiKHDÌÓ i áá;c·½—®g\¢4•Z)B MU)E"UI1¶±y¥Q n!MJ ç}Íìãö‚±·¿5Í?þ Éz?Vs³ºßÎÎï;Ÿo½D33Dšë=ú$ÿñßÓí- W?#fv|ëå®Ç3?YJ™p(4'¨…T¹´+‰ß¾¹¢¾Z ±Ü£ gîÙùøÕu¸¤¬e‰ìv´ ˆm ¤ÞȺ>t%°uíø”ãA…FîÝüõú™/úŒ×Oùmpâ'Œ…>ç÷‡ÐÔ¥:‘Ò HƒöŽÓ>,dü…õû”ÿÇï´d©=”a~%8Nk ñ"$qAØösÔ8?ðÖ¯×jJ ‚®Å‹8oii(¢'j»­g#kj²¥ûP•¸¥e ü¡`KVJ)$ΟÛòΖ)×sJØÎÍÍP§ÙÀÞƒÍ&Þzk$V*ô`En^Ù(¡Àˆ«›j._Ùv¶ŸÇÚfK‡''ñHì¦-ã‘V[‘'ÝBzލ²cÆB´lfo;ʧ/¸¤Í²Šçíí U(‚"`\˜«ãʦ2w„nü &©D%*ñ¿!c££P°çÎ~°ü‰'Y0Q4’x^ Ù‹65?rå“nÓ’ ¼µˆE+™²¥fÁ=Ù¤ +mEc÷¤^†Èz!nkrÙIè#í^H…XF@TH”Àœ<¸²\ê±´<¸›"mrºÏf*Y]YæÏ–/áxŠšÉÕK,ݲ¥áào6îß»êÈᵺš´Ì-6‰ëŸ½¸;õuDÏ ±‘¦ï.0Á:ra$³më#/ˆl0¹}1¼ìMK.ÜhùôÚvÍŒÃRì;°*,Rˆ¡×¯«-ZúuÐÆ.¢vk$§á܈–Ô5‡ }CÙÝJ 9—´|̤¥¦\œ¿ew\íÑ×—¥}ih¤ŸóŽMtNrÞÐ~„œà¼w‘Ï!ý´÷÷Aoˆò“ŸÂüý‚Þ Ê_FÈy@òúy¯—ñ9ä„äHø€Ä‡– w~ ýð1¦Ž™U¬°4Ï_f«",×ø0ÿòžÇ.]‰Ë­šÖBôœÛ-#njPõ€Ð) ’•…«©ÆÀ’¸vÒÔ£ÀàJ 7¢vq#Áqm$[ÃÑa.„Xñ•_®ÑÕÔ’/™ÑÁ¾çXjbÂ"-œ:µÝ2óv1®‘ÎþÞ^ÚõC¿{öÂù- 0¶…'Û?àY\’s´Ž²ÙA”QÚn;-%ï財Ä,;zõJêÙU Õ<†éiA@œÀñO/_ñ·sÃ>ŒŽÞ¹3:Õr[‰JTâÞq—CàºïW{ëëfƒ©ó”È †jî?9ËŠ08¸Õ2e]Éq‡eÄtec§]£ËÖ²“©‡¦Å][¶””«‚áÊÚföÅß š¦CBÕ7q—.vû~ÊHÛ8p}@§^·:Úž½¯­Ø"3K ‡ÿ#—äu=EŒŒkf-­°Ê& w}x®áÀ³ÕT#ᣲ qE;æT\dhNšºòQÖ&Û Mnnª_8‡^Ú༓µ^ïLŸI†Ð­wiïtd¬w"ó´×œ:XBÞ òŽ!¯Wôú$oy”w 2JVá¼þˆ?ÞÇúƒ>¨Ð@/Ÿ½Ívl4„y‘–$D ˆG´f«Š­¯ öt/½üI[°iÓ~±è²_ÐÁi ×ÙŒ•´£wøƒ“ŽÞc» i‡ï‹•]ÉGsD¦ŽG3b›«¯_Šƒ+iœ_Ã!Fäg´o^fâ´aDÞ²èá‰åتC3mGë‚‹wó§“íày\H%Y$²cÊXÏè#yËe3­€C*N¾ñêŠyµ”ÈNçpU ›EÞÜWëFGoOµèV¢•øïƒò$^¿v‡/ ˆ_ÂtdåS³Ï ïÀvcðAm®‘-têp¤’,ˆ x] Ð¸5™z˜–ì;E.«.NjJòÚìÂyaNxÄó”г뛦…G9z€çAz7ñ&KéùÞ˜F`˜À+/­1•%ãy·–̤©$KFÞRÓ¶!c܆Íè’¦¹,ÃEP`—Üø¹&êfläbh1( Ùo¼ºPäò"]%ñŒ€P -6=YýÞÙökj”¨]¶špµNÇÞæ([oš@Qx˜ÑR»=eâa@ ÎÄQ×l-›q —¢!O9ThäÞ­o"«AÊo´7± ƒÙàêo£e_cæKÓ›s‰§¨#Ý|éO’wœš²<ûy?UÀ€¢¡»9ÓÞÖ ùw!ùãAÿ-|²‚&a}tbǨÂù×,-dYš‡ïA³"аa .šÃD75^¼°M/$KxÂÒãE’"jÄTó.É9X6õ¨E¢~éI¢çˆ5ÔœeG3ñe< bÂ7¯zHÓäûÖ„QGÕ7ÔñçÏo°ŒMgÏÄj8žcBÏH‚(ÂÔ‹4š?{Ú?/æ&¥ TÒ€I[N`œÑ!3åŽÞçKþ˜ÐqÔ°ÓÃÃùgžž €šùk‚Iš×­Çº1Õ¢[‰JüÇ8ÄØø¸76üáý§ÃøçÇþ|xNm„¡˜ˆ$qôt*´ÿÕ¯7òe«S/´Ù$DÈÔîûô½²q«­EK6µDç´ë™Co524Š„G1 jꆇc˜lƒ‡Õÿ 8/¸ÞkbÌWú¾>=år›4Á„a–¿¼ßj*©Û$:fkÙ’Ùa(±¢“VGdÛÌaœú7ûåÇu†a@°00†á0à ;;Hò-Xmì(Ôvlrñ…¶‡:Më€ã¦­l"í®w·»¬v·Û•,+v7u‰K -n’_-v¡¡!ÖÝ’#×­©Cœ&Τƕµ—9sÝ›¬ëé7»iÉìb×tt3:×ùÎû>ß¹³û}œGÄÜúµMS×3<'¯ì~j•Ì32’6oÄÙ‰ÉKû2‰-/íûú/ûŸøàò³$•†º(eÀü?ТHÒ%#ebf.R2âF> ¦`RËž‰XùHÅLìAGØWÙÈiZWÉȘùŒM—%#Q1áyÒÐcE;¥ë CO-ej©¢ž†£+Ú™Ü4d¾±²å"|J‡$m-ó ÐÈÒ¦Y:–Í\=Ý<ûŽXSè8³äZ9¦£²ëÚ`Ù¼ëæÃ èEDÏq®}¢3™µ)ˆx™—dŽ‘9™¼žpÒ&½\57Z:މô‚°ô>rǹÀܬº½z¶WÝóµ•eEq#H¼ˆ©¼#%vh×Õ˜VWÙˆU§Ã‹fÜ.t›ù”]VðÞ!©’ÞWÛ†[ W˜$’.ê½W/ÿèD¿ïã¿û³ÿÌ´4ËVeä;Þ³½l…KFÏ7ÚÚ$YDvë&é¯>qú­çvî\ƒy7zö™‡!C±È0[tš….»-æN–M7ö Dµ| øÇ±áÞEê‘ÿ•õׯíñr "Ë*œäƒ=±BÛšCçÞ]œé1¤ósóÐp“2º@é-PÊÅEhÐ……ù/TÓ}µRVÊJ¹keav¾öøc¡RqéÂ"u¯ÙÑ—{‹ ƒð Ç0*¿f÷Îõ“—:E*æ#Ö-Z`maH‹l펩F0ò!ÀÐ «[¥#$Ïï}”õxdÞ‹QcÇþvÃqAÅ̇ÀCÁÁLë._×™ÿÅèÍÈð{/¨b“"("âˆÕ^ìäƒz!e 6bFu²¿â¤ì\Ÿ£Åu-³éFÁ = :pà‡m ]`9^¤¶H ÃÃûˆÏgÓŽñ²­‡ê(˨m3áÚúòªx÷j d†Êf¤bEðà»ÀÔË[ÅL´Ýd6|«+ Aµ‰¿dGà­YHÎØ™:Û¹@Éð$Y§®wÙN§etÂP%Ò«å£E'Y¶â6‰‘\Øýš<%ò Ð}Ÿ´XS_øÖHž¶)Æ…ŠôQjj!€Ÿ’áJ™õÈD»{³áåâ­@2—þØóÍVÁãiåf c®²¯¯wii¾F K‹‹sui„dÖ„Ö˜¤Þ¨=Y’•²Rî^©]¬ÙÙÊ©¥ SS7víÚÅ!I‘|ò4KŠÖ½ãú˜®'ªv/ ˆ‘”8·M"e+"p§îYóJÈ_ºË$2`‹Ý~•gI`!Ϲwƒ`ñEqsõMï©û;Thßé¼–yð³Oú}¸QÁ¼*zÏO|ß2c3NB×czö¨Ÿc†@Ð\D1;ÒQ é£Ç· `’¢* ãñ(>1ÿÎö-ìÉã;n\‡c Vl˜EÖQä¿î__ð½G‘nfÌ» NÀ"þJiÙsXw(™1=„•ÛzÎP­p#uË9 ù& hä‚s儞;X2]ñ¯Ñc¢lfHÖEHK‚Ó3ë8‘T‹©Š“Öá­}`hä½ÚˆNðO b=Hâ%eòUŽN`:ÀÐ1xžãbÏxNù7{Ñt¹€N‡%IQŒ[1R‘ºÙט|ŽûmŸø±çÛxÎȵJmLãÈIyiŒ¥ƒˆc:Žé(‰|ÿ1ã6ëE–Žrt˜§ãü•×ùΧšVqŒÈcVTܲŽãeÃO ðèµk‡n2x ¶€H¨šGg¬þ¢†B®“lxí W®Äã¡'ßþÝóÙÜ‹T“#~ÈxQj1ò=szzÖ ÝÈѾí>^V0{êØ®üM7qøô£CW¯t¬4dðŸ–!«ó‰‘9$,]µ–Í,Û_(D³ÙLßOŸæ< >‰‘°$`^Àì¶­íŸ~ò!]Z¨SHµ<"ùe277KÿÃ'+e¥¬”»RÜ‹× PdiaþìþØâ[+ ŠÌ¯ƒË)qlûCèÌï÷ÚxP´jÇÀ‰À•E,4 Áš¶€C¥ïÔ}ÀîÝ,†ÄAF€Fj@vQOGýí^^D, ·{ç6-+_8{ý7  t¬·ï˜F ¿6}xC+Ë3M2'gÒ[‰™"Z¶VÛNÂM¬Hßk'ÚÇ;¦n¥Ä 9úäcèE‘¼ˆmôyÙàO¶þYÐ4Ò ŠÚ´€JŸŽUŒ¾b®·nô_F‘z½×4ââ“–,’tÉèqH¾à^£¸¯<78üš€Gk}!-í±5·×l1miU'hB3­OÇgì^xUȇa›·œ´]è®À·#IÀŠè-#e“¼‹pÚt€¤>ìƒA#ƒ˜‰t”¡ã,I»*4sæø_u5rÐ…ž÷çø«±Ì 5þÁ·éªüYj_'6a†SQ+ÛÜû=dzy:ê¥8kŒ}#Ûø¦Õ÷ÖK‚ñ'=s‰.óŒ3tÑ1áþcÆíÕÅÁ]üGxwåè/¿Á‡žnhÆÈ+ydžQy¥EhåpC8°ùÚG~’Oít é3e3ébmÖM: €I@4fJ~Èe ÉM÷šä˜óoöË>¶‰óŽã‘*E²tÒéôèôèNw²}rP feˆAWV±n”·uРvÙFËËP(NRÛØ²ã9@ÈFé «Zuê¤þ5TÑjÊkÈ Ô–¢¶«*^‹ ‰}ïÏí$Àíwv—ÿ"‘„:å§'§ØÉ=÷»çy~¿ïçk7mó‰Ã¿`&ÁûrËÏ eGQiºåö„H¸y¾@Íã±çõK¬œ–ì¶ÈêÇ$ê­}+,`k1“–-™1åæK·í,É'‡ 8«“Ö‘SH²+¯¦lš%±K‹Pâp±¬ ~ðþ—FîÞqQdü»n øq翦Qd:¦ã>ÇÝÊÏmË4[3, RÃ!e¸žÆFÿåoÃ*´œ¹SÛ»Å2b¶‡kEÊMÚEzªê¢ô«,Ö±‚wg#q[I\½´eN_ûYýÖÞ¢Æï—Ê—Œ´¡%#›Ÿ¨÷ <å›%ѧûâIÚC±’UB²³çÄÖZÁÖVàÈ¥F>ž»Þo×°ŠßðûÇnUMpmj.T´â¶‡¦W4’f.^ÒÚï5My=ÕÑ\P4å¤ V—š5µÌdëVÁØÊ<á– Ü[b©QØ\wÍ央¦l«M‘[ ’y°é–ÕfåÓ$ŸuwÐŒVælOëÞ]Ïì{eù;{êë 1C͘$ôƒ¡‘>4ÖËŠôЫð3@ yþÅ%È9néNjkĵ4fF¤ÑÐûõÎI¶ã¦ñ³}\5Íl|;=¢‹.@ÝØ9Šœ~~ìÃÙŸ´3ö!ÆéÂÎiì¨ôPîèG.ùŒn.lŸÄò³ýÔ®íOܸ™$$ϵ¨ê·Xä”:•’©`‰æž¢ô0 éù¸iÄ5(4c¯žk~ó/KDL "â´fypíoõ›Ð‚(zž}f¡]h½v¥cA’LSÕófç‚Bþà»z¥ÓÐÒ†2rÍ£$“k“×]A‡Æ*YÓˆiú&ËŽ &_í\V+>ÂÑÕH¸QhÙÒÅÿþú|H\ü¨0É™LÇtLÇýŒ»Î‘#çëŠöcŸÈ²"®ZôÓê³}ë e¨3ô’‘*QKN‚)«^¤ D°d¹º6Uõ)Z K‹%ek.ÀGKŽ4¥¬¥žœxäñqÄx¶¥W‚Ÿªk…|l·™¸Z?ÕçŽZie0JÚѾXâ<~ì@IŪÆç~¼=ÛÐØ°P¡°ÄÎÙê>Z_²RÚ@lX¹¨ªBã[×\Ê…`ª+[ª˜¡F*“ƒ¿3dB&Ô¿’!|ù i¤ w%S~ntt$“ŒÈN=¿}²uÓ””¡G iµHÂPvòîÁëm¶Ùn’èñÃ/|t`Óßßyü›o2/þöQhÎ>‹\Õs«çz·ºodnÔõðµ+^öœ?ã©^þ‹º5«gû9$PuuõñÇ›04ðÀÐË;§8¸~öPˆãgñ¸Z=„ÇŽ1;6Ò,Çr´ï×A¤Ä09Âw ffÕBìô#ç$çt!çëôb`§›rÎÐÎ9윢\ 9ÿ†]Aï8½Þ‡÷8ú+|Å•! ¹dÒîÂZõ¸¿8'à¨ë2kWx8®gp4<‹k½‚Ȱ?ªaþúÚÊ\n')ì j¼D Üêp›I–0Øj ÑÛu#BH´0´çv1ª ¤;þø3Œ‰ë%Ãv Y–æÔ OúCpNvï\pù‹‚1”À [ƒhÏÜà#_}ž„iG­$Tk~(JŠéÉÎØÛŒZä%HèH“7 ·vúû"¿\\ò`SHÜÙ )AOαõ¸žO “¬"‡»Žoò1^ëã Íqô…O×T„µ¢ò0¾ŸÄë¹Ö‘b›¢†½³yË“ã1âY?è(ÂŒƒ(?˜#yßûGc^åÔ° Kùd©VÕ?i<]t\ÝN´¨)—ç4ÂD ƒ×3å´i$\0(ˆYöep…xfü—½9TIC.Ðä"\CúxçbᦠˆEű…sÌå£ÒwV»8ˆ%s¬(2²—¾þ}ìÍ&Ðá)…Š’>àÄTœZÆV"ºÑ  ¾?§täµ]y#žNÿxv÷ ÕåÊ$Á?{&3é°n‡FÔ–6SѼ³ÕVÅŠ]¹Úø›cÕï¾óŠ©O'Zls_Jm½cF2‰–œÞh´³­›Ö-ó@ºä™_­1­z[k0G:’×ã'O<÷ÃÎÕ;טê>CÝ•1›¥ý%`#xYùýáZHë×ú0#ó¬,±ÔòÅøÐ¾š´¬ZìeDL ²°aÃ#Zâ@F®~Ò‹y‘æüîd¤mïʃ]ÕþU±4ºƒ®&ß(g:àt²Ïæ‘Lzqq@‘TèÁ[+] özYÔ¶]þöÓJEj\^B†ðäy‡.}­¼Bà9„½˜jÙQ1ÕÙ0SFºiÎ2ΡzYrZ"C ‡ #øêÆe+æS¬æe¼^,¢ðFzøH™s¥¹Â;,¹€É è…)ôBÒ÷’s”€Á"cÎóx@MÀøÐØ¢pxÒG‘Ë9‡ŠË Š¾ÂJ/° U%°¡ò`à¦$ÄÊŒ¸aÍ‚¾î¹Tx,éÏg·Ø[éȘÎi­Pïd´&Ûh6õVKëZ\ScY½>Úd¸‡‘ÞoÙ †Ukè¡åU¥ˆc<›^|̸Ù2n´èZ,}ÆyrXaýs `seT¿™l3 ðvXM·ZÄ)vTØû[êJÌ6:¾ >@}P9òú3¥œ b%qbž­Znª)2IîŒBH%SNP-Ø{"mánìm³íÿ¼9ð(¶Éɉ{A'&Àö“Κ —/])óBiKc–’ø Ž–,t Fs!˜©³ÆWÝõTóh&ª§šÒzõr{¹àöàRc%¾ä÷omÓ´+Õ4iÅìD Š,U¹o-äRF2šƒÒ L°ã#7ãºTêÔ–'jzz¶Ü갌Μƒ5ä­ûÖÎÌ=”Ñá®:%áÝo³ ¼qÆJ­uÔò0-`j±|º¨Pí\›¥³jÔLÆ?þÇÖ§+ËæKn/r õ-# I(ô¬dô6 G«‰fÅØùÚÁ0ó¬kó¦%§Nm>ÔYÝßýòµ¿5>¾€ÙQ‡÷¯´4ÞŽÞü,´ìQJ¾RZW;Hß]¿Lâ‘ÀÉ/=ÿˆnìM§CªÞÑwî{#"Ö% .%Õœ¸öyÜ G“dŒËy –ä“™ÁsÎË»n|\«&‚E†µdôVi¸öÐC§‘óÐp®ARü­n a˜'äòRynò]{S$ƒ0€}´‡æ°¢À¾¸I‘nLúeG ï!2ÌÎdÃx ä00ßÂ7rR\$»Áý2Wʸ9Ìó ãò îõî‰м/³˜ôp¤‡'ƒEl K€,ìWÔÀ+”H¿DÎstNó¼Ë~°ŠäL õÐJ#¤O"Þ3]ì·|nÖ-Ól˱#ŽæE¼}ãSŸ^‰é‰°bîÕí¶QØ€jZ+Ùa+QSmH+[áI0‚LÆ *Ÿ‡,#ßVŠ?Ë YÐï_âs!žÖÃc»o®ïÒ{B'ÆÈÔ$DZãÞ;M‘ôgÛl{(Û´Ìï:Lƒ±±±‰ÂØ”rg¬pü×Çb)Ïд…Em¨)¿ñI\Q›Œt“•gõ¦Kk„4ÑâN¡dÆö·¯h(…hu­~ÊwãzsÎl2Sõ9- iÎ4ï[ Y- %Ò¨…³$ Ç3¹Æ´^gM Xø¤EI7BR†Ô §ø52 ’i“Üíy5˜·U³ÎÒö*#Á¼…;T"ãÇŸ¼þÉÍP*Õ4nµj¼Ùò³UIXÆSé+5Ô}–É›!-Ñ3rÆ-å7ÓaÀÉ™Óvׯ°G€ÒN yÆ##¹kïrÕlûÅÑMQ<'>æu}z=®H¥ÚXfŽÌzÖ=ÿoöË=6ŠãŽã–,´Òj4Zvµ«Ý³ló¬Ý ’ á• ˜¶@ó¬9[ç«·ç»ëÅ6ïš´D V‚R©U)ÒVûüÄ<Ú´UCú@áÀ¾½}ßÞŸÛßúT*EâH¨F*£Ñiçî4ó›ù}Ÿ¯_×¢º¹ãØÁj0µ˜Fo]ï'Sß©òòÅ/J°/qñµ¬[¾hÏŠÅ<^¶`Nýž•ÇT=0ûw¿ÙÙziWkbÃýÛ{?2¦gK½“Reæ±äÙ¢‘Îí(èPâÛ·ub§bÉï§i$ŽiêØVÁ£…NìUùkh¼}­—°4ƒ)†žjŸ§Ý¨þ¬{…¸m” ¸réà§¹]’{˜~¥NײǷ ?ž¢þy¶l÷Z,bãò2Þ×s‚š€"–¸ûS±ÿ\Ñh‡ä&„׃ÜNÚíÜ` Êc€ †a+Û½ŸoÞHuŸ(6:æx‘L°nq¯¢±ú·G˜å„ö±ŒÀÓ|™O &3ñæ¥wî7èvÔV¾Ve°¤›v€€ZÕZ˨K’6êt%³c•ªÿºq Œ›"âR–‡›«œŒ¬>¨Í8‘ƒ^V`ÐÜ™èÎ-˜¡!”>E‹›Fƒ¥Ä`˜ÖB¶pŒ@Z¯u€vúŸìbRfKçU÷±õ{¬À“$ÿÏÛóö̵Ï!ú²¸–5ƦPh‚X‘)/e¸æÈËš±¬Úœ ²Ð8`…=ƒ0I4’I¡léý1Ç€"¸÷ÞÝCeÅ…~³˜ûƒƒ«ÒN­cתØj“c¾èüVª6cL`0‰Ý¤«É¾zÛšðD©ù’µdÈÑci+nê±§µ/€àèy˜gPCHжËI·˜j ­†?¼^}òDÕ–Íþ²éUlßàõ00”®×S±í›æ1Œ¯H$'ß]çdC©¾=Ž^“5½A×ê³™h2Y£(ò—$š¥8°r3 "~Rô•RêÍÈ<#ûL l¨òƒ®3Bþ¯šF<Ѷ‡E>‰àc‡ÖÝVõ/ÎÖ0 „>ôæZGo«h›ûúŒÚÊWüÃLe¥ö¾åXrsx©€DO©.Jêû“éÍ8Ø]ñãã¯iöxÃY 1§ ÏyyiViCnô"oØKú/2óIË Z¢°€+§¡d‚ë™ ‹q;h÷OÂám¸œÃˆ”%RõKôhûÄ< Ú#‡VäPD»PÞ.þ ¸md¸—¸×·¹ÑPûŒØ^ i‚I|37ÚZâ¡N/]·ÅWÄV–áw·º½œÛ%xÅ0 ç*çvz¼äE óC݇©<@‚UŠªr,KüØ·bFÇ'“E#°YˆH ¶ßAeøtŒý2WXŒ$Âp¼ÃÍ,Á%3¡¦ozd5õïu@²I9oÌdhÀ†+íùt)Ïšq K=ú“wVÎ.Ek*]mRÕ@&Ýtíê.Œ}]püÈjÛŽåÈ娩ÔÆÀÿš I ÒmÀ‰ý¡´vZžt³©PFèýrÚëFÐÔÞ:ܼØÏðCqØÇŽ08X_­ÙýcãÿUZOcÇFóÏ##ÃÿkÅÞž·g¯=ÎŽÇ188è ÇÆû’Ê’Å•J ´Ó~–Ìòûÿ«­†ÒâX![ɺŒÎB¶“ÑÉ¢[¯ÍYq;ØÌÊJªî왯1ÈOÊ8„æÍþü—=†6'œ5š'ÌÎ\Bßµ`~Uγ¨ÔÍa3–UäŒ.?JÇìF#UõÑI‡ŸD (O,êõÇÚVê㇚ròÂ/·Üühó`&þÉšåK<<àh¥Ñº¥|ß­¸¥UæÑY%„`VÄâG˪vôúœYŸQã¹T¢M)uaËŠ-{az)‡ŠxÄ2¼ŸˆgNWê![Jèëï7ã%,í'3DTØÖº÷ÄÛ߀ÿð˜zïüNl£mK|Sä)£—-nÿ£)g5驦kʦK8‰ó‘Ïî‚ÁlùøÆîy3}<âį\:û{ò«/ÌASE¿È ­[æz¼§ç_² ;͘Ñü𙣑^ä1F7TyâözŸ#ÝøH•oæÊxª˜BçB¥îeÉí¡ÝË´ÛQ·g/‰ó%Ž""T)ÁÛ—ãÛçè¡.v쾡ø­õÔûQÆ£—nÚ½H-\9…#«ù+¦l_ÀîXˆƒ—ÓMëùr‰ ¿í<ÓKvâ ©˜üšùŽLßWY¸yqAK óð=j¼›xAvqn¹”Ç9=ĽÂ÷P}ïSå„ò~–—¾»w;¹É£Êä.ñ?HƺÙÑvîÀë/ò…£ 1S~Ž[¿¤âJgÒ߬ëuY§6›–̸•l°•¦Œy”Žkýa¸·†J› ¦Þøé­ÆÝ~rV×#Uo”°¦’ªV—>¸¿ß2t¥î[&ÑÀ³4Ždšôþ`ÎŽBvÀËZ “´òÄ{˜VƒV H¢™j4•xÖiþõùsgùDÌr4Ç1D‹V­Xûé»yÍsÈøøøçlàóö¼ý?·ÑÑ‘ÇÏùìúäo7§Ïðó<Í–GÂT‘[±„\¹Íe÷iÉzG‹9z HÖŒ©døœ,±Ôg‘Àž©I©; ¼½îÕ"–Dqk^R4ÙÒLDûdUyÒü©FpIŽ%;v0£a!°B¶Ê™9\UCZõ*)P ˆÞÓÚTgÐOèùÒœ'øþÞÀ÷åEåÅ´„ RŽÂ– #xû^tãëåÓ$(ô~ I–ß½-·%¶qsÅKNíSL­Ž,g…=å4ZL5,a¦ê«ùúå½ÉþÕI„ü›ýòâ:â¸%$K–VZ==­žvµ«Ý[mŒCRZ7)…¦-!-r*¡¤Œ >\ßÙ×ûÕË“¨(iPšH mS¢RZ¡Ò’ÿÀ6†ô*%TjÕPˆƾýõv÷öü 0ÛYŸ„”HTBBUV{wºÝ÷æÍÌ÷3‹^ݿҡ­ž½aui»1’}u÷ZÄ2µ!õ¹Æ†Ž¶gTAQEñÒ¥¤ÙZêÓ‘v‚pE+—pûºVw¶}}Q]…ÄV‡²©±:€4#縑óC[ëÃa©ð“€…Sx–i|FúldO‰¸J¿;÷€¦Ÿ‘‚›>à ⿇ýóÂxÏ7Ï„?ùƒð÷7‰?ÈÍB¬§—ø=L@/ƒÂ…w¸/“ Œê$,`¢.ÀÒ“*YSW±—‹lå#2sò`x g@=¹Ox„`‚Çã§Ê ÉücDde.Wòâ¡&!Øi?ºp„pRK•D$õ²X%0((Va¢™eèûûÄÂþ ¬ Ô€ü>UUƒY,ž†¿=0 Åù`ÿ4ò‡g½ÚgÉþ­aHHŒ5TÁóeÀqU¼"28þão^¹’°œˆ®GŠ4§}›r“ž™sXÁjõh; ¤ä6àãBí·ÑQ˜ö~m¥Ä†!çdÌ ÷$Ç‹ju ÄJŒÓnk,âY :’ò¬.›vif†º9Mëœô2Öè]§˜ ú’OŽÛ@Ñstפ“sõG£´?½¼j¾‘ õ!‰buµzñâÅR³žž.ÝÀX‚“9›³9ó?Ï$'Ožƈá1ÀûyM›ýôr·nìrŒ0ƒ¸FŠQ׊£€"YCxVÙk·2 ŽÅBTÏÇ{OmÅrE&ˆA!Bú{£ÚhÚÖ[ŠFö^Ÿoi­;JõˆkEyà4/ZYÏË«˜³ð¬Ü¤Ûmk÷Ê@ˆC¬|gi¬ ¡Z@#‡® ‹˜gñwW+–‘Я7OO¤õ|ÖÑ3;·/û}‚†ÿ~CXAºšoÔ¢™~àG#ÃÄïcïŸå8A`¼>Áê /“ljçCŒPÅÁjâPQ¥Ôb†*ãðz}¬pªÃ š€£G­üN èK³!Et=Ÿ,/M{Qs$Û¶c!ä§Êqû»¿s«øš6º­`ÅÆ#îè)WOÌXÁir¬ÜŸ=Y.Û¸®î诶Ž]ëž*¤ï–‡Úh—çÄ-½ r{ªÐe\@ŠŒlÑéZûµ+/oßÔPÉ# WH&; ìØ±c%)~s6gsvǦ¦¦à:99 ×7¦Óé4ÇqbP;Š„*UŽ=ðÊ:(|ËŠP·Ù3öŒ T®­¥`è(x;)mÓÇîYåï›9Ïê P¤ÓŠ‚>R#kÛÉæÖU„cT±FÑo/­t½˜G#E}Ͻ??íšåÝíêÐôRvÊÕb¦·i±㠋;nŒC™kîº_ûi¹üï-ŸüóycÆ·Ð\wE–Ä‹DØýâ*lj­¸S#7eÅ9Þøõ ‘Ôb4OâY‚Âa\uõZÌÔ2T‹¹úPyÇm1òiÏŠRºf¤h¾ Xb象Áf +KWè4 ÎÚÑÓÁùÚmìß*á:…#"ÆŠ(¶4/7Mxë8j©ÆuOqX”¥#¾dñcŠ ùÕbdûÓ¼“Ú1 &SOÌfìqµh‘Æ3FÍ´>X›)艳ÔÚþ${èhHts€ñ‡±ÿžìŸeý~₞²þYÉïeüsL ªg•€OÀ‡ÿ,e¸Ò?ÍN¾öv„$$ð‚¢bTƒ…pX©ä19°û§ÈõãüB‚¡˜'XD*8y^ˆàmë%PÖÿ h"9Hü!Åü.ࢠ¼(µ±¬Zè–n|œËE¹E5 ‡«1fd¢*¸RAÌ~Pyn`{‘æ\Ø52aC_ÊBkò¬DÑN@¬„n§ jl­Ù5bÔÝ{â/7®]Lõ `ƒK¡rcÆXW€"V¬hìuõVJ7›z÷ñw¢A`C*‡V4”4ôÓ»æ¡ÓnÅB` zÊÍYcñ‚uaf¡q×j³i×+Ý+„X1Dd2kÉdòæÍÐogfnùŸçlÎþïíöíÛ_¸/ÂÌ¿531>¹¡±‘‡Làa*á±øèöÝ£ë PkFÔ΃öÝU6¿|µ½6$PqI¼xä­ç -XŒ˜£Ç&Ý$բЩ@%ÿ‡êÝ/ €Yb;ŸèÂLS+ç9-ž•Õ®·ŽÛ‘›fl<³içð_·:´æ[ËÔ×ü—ý²Ú>ãx¤H'Y:ɲ~²~²e˾Ó]Ò„A(o+4͆( Œ­¥¥ƒ2^šÒK®çæræHH!F§M[+uºI]56´uƒBH›Öm¢£ë6Šxäί?Ÿï…¤Ä{œtü¹õÒHU=:ù¬óϾŸŸçû|¾ÌÀÀ‹º•rŒxÑØY¿dnÜ"8~ìy.wÓDó—5í Eg[Áèyç×kgE†‚©”X†gå×…¼MbÃÙä¨Ñ“×UÇÞZ"­®¡@‚Û–b»MÄÞF–Ìyç¹Ë×[~pe>§º-u{ûŒi ŠÊˆo¼þMM‹çœdÉIض²iã¸Pdgxs ±U_ïó~N|NÙÿ}ñP õ¬)¥úÝnèmÑ;%ú³¸W\*•hIkº×ÒÞícÏ{|ãã+É!ÄÔFYÿŸöâVòB@ˆðކ2ïDØ;._ÀÞ ÖùéI¢iQ Z޲1tHàØ*$,}$øZrVÇa.ˆu~òo10uûÖÇ÷2ÞyÖ;Ž|´ëgN>8ŒÆ#(a!Âá² dï9,½øD€*9ÌJL@d‘ÈWa.¤*ËÌ+/dIÊ4¡CoÕ¸Äk¤†5 øDÓù-Ÿ~B'º¯àÆòF—“MIœ/(ÅrÍl¼öõô±oz­¾®fF8R% žyÆtËÎQA1À‹ÉéÝ®Ùäh±éðû ZIkƒ¥à¦V¦­”SU #Žþö‚êò0Ërb¸ yãšu9ÝòÆ=Páâ¸ëMÈó=,™Ôä;ccS0*¦c:¾¨˜dòññ±O±| ÊJ7o^[¶tb€Aád°o_{ˆlÉ—vùsSOB ðO9f|Æ´¬Žý ^bdÌ`I k¢Ôп»m½dç¶“.Xª•IØZ|¸†iûЈk%ì hT16[ÌlŒØ !1’©T éÈÙ]7>Üwþä†Iÿëê³ß}2å‚C‰…0û³73œÍÄR1*iAµÚg“-TE²ÓÑ[ Îí†l`šJ÷Ε²Ì‰ˆ!^âE™åžošoééœú™TÈ[ @²¼é«tÞ8Qus‹¡u®[53$ "EFiæ¡\Ë$nçUxûÃFúú•—jçU Æê;¹4¬¨‰;9e{炊ƒhjïþ:]W\§iäÿäy4~ õIwNEÇz%¯‚1NÒwÏ2]ë²ÌP¸ZDs­Á«ëËÄ•,EC!KRû*Úëc¼³ì·PÊájNøëŒw†÷NH^/ï pä^ÅW^ÁÊ‹«©§¾8 1Aj8Ó‡g,y0è Vx}¢wšž²}x~L”×/yÁ»}\¬¾<ĉ¼À@¶=U6Ü‹ýÍ9qúfüù'ÜãsÊC|”A˜AÁ0 ¡²y‹ðoó=Çê*ŶS6évÌXÁlÊ›I¨yà×hoÏé ¿8 Å6;l½ÕÊÄF PÆ)]kqHzo÷òù³«jçÎŽmªûøR®µ~|%¾pË!jóÓ³Ü\§etäèÙ†R^™ tµDT¸…£)ÐMÐŒD®L„ö"RÆ7–ÏÙ{Îômt!™ˆÄ#€!W®xòÿýeÌñ…xÜ7‰÷€ddttšE¦ãK€ð ï«O&ã~#\ºtiæŒFA cÁ ãV-Å×®t™v³¦5=^°ßŸ_SŸ1‹n{&[<_Žð< „°œR–n3üGK:Ùôˆ»DÃÒZ€@aî÷ó”HºHâv¶uØÙmeÒ%WuŒÑÔQ«ÇÔRgÎn{®©âá¯àƒ¯.·2j>¯˜FzÏŽU•ÌV`P…Àvm¯?zlµ(ð¦7=]egӣíÆÐ3;MÌ4ÉvvÚÚV§\^ö©’ ¶<ûˆ@à EQ^ÞÜPwùZœÜn‚ʼnÒQ$Éœ±Í5SÀ?†Ñ þ‡#"¢*99ÌD¢˜:õî:GW]»µ ·Ø–²¤¶BÂL•€Mð}¶êh)Pc]ëøÅ[ 0::¼iýb½ä»ÑiùßÙG{½ŒwšõYCžÆ^/çŒzïsû×Ó5¨<ŒË8*\ÅW-žGU±`ÂA|{§à–ųËX#–]þö!¤€x†Vy¥ªDpe /7RwB97ÿ8c×Z Îà`XÄTìÚXæ "ï÷ÌÄ3LQös(Åz½!ïlðh7,1AÌ3 åòoqÞ9ì ÐãÀ-çhÿgÇ"?ÞŠjgà(‹9€¥cËZ¾~ër'€•QˆÙ™ÓwISÎè€ /úÝ—†GOæ@ÄH¢”óO–rqch1TÛU»w.ì‡bP•Ì¢‹v$¾zU]½bnãeouÚf;8‚R>áñ¼£@ûØCjц›Æ‰¹ 4DÒñÌN[ÁVXÜÐQ,«Å\²÷ÊåžµO~5ÌSÐD1f*+£—>¸èßõÝáO9¤T*MLÓÈt|Yctô“ɃI ùoŒ~û%ŒèÇIH”Q eë|4Ðk#y |æ­Å³5ÿ§Ì畎֜wâ§Þmä‚ ÀžD½ÿ÷f0/ D€y«ÓʤÍçb¤ïûódÔ’½»`wØF3•·;†Ýä°‘0õ®H$À @˜] ìW )×Mèfó…3ɺ¹Õaa( ¦Hí¢J–‘E\þú«+ò¦š½¾Áû¤Ë5U#›&F[)׋_¼¸š¥…Ç–F‡n©/´, ó†Â<',©G]MfK‘ìÎ]%ÒïtB®Ó0܉7³¿ú庭3¿óDho÷Š? *¦¦ öJ-ä?/ÿ‡ýrâ¸ã8’¥“NZV«Ñ®vu{§³ƒÁ&(âÑ(äQ7(”¶nS  Ÿ}¾Þ]îð=z=py4ä¦AjóÒ–(jŸß6QÒ¨¨ %-i`ßcß»ç³!榿=Ký£þ¡–*F«}ÌÎÎÌþæ÷ý|Ãnþµlk´ÌDþNpn&P*t]êÿ¾»jT_ú¶OʧM9²D#¨#.2AÛ2J‘qŠ\®žô»È“ ÷²µ£¯rgBöºzû€P(q‘Ù/Å7²>Æ!2¼çø÷@Íqå‚“LPdÀIÆØ'Wñ%ò˜ÆWC&¼d€"ç6xd¹w b±ÀR…n¼ ‹F‘ ðÖ"ÒgƒY–&Òïœëç¶6À]‚‹v!ñT†Í’ó°\”½bcN2€È?Zz‹k}fÊcN¸z׸Ù3}ßR¤³¦´›ÅC%­ËÞàÞ…쎅HrÐ !½fxPô€¬õ®oz¥“Z|es ã9Â. 7ozÌËc7+~½‘S ‡M3\ȧF.ù‹·VMþêFî²ô˜nÇ<ðIBš¶3 ÜœÑÒ³$™°¦uZV¤P )2ðÉ¡Î}kE–¢)̳"ƒx‘ß{çì‚+œ+ϒʦ륲TþÿJ¥ráxÿþ<œ,ßúÍ›,C ,â)ìe|^L½qúEÕÈÌšûÕé žKé…xY‡Ø»¸ZtÌxÈzWíÒriM´¼à®e ´û›;|`šd)¬(Z1ˆ5cE )dI=z<–b'@Iê„Ô'é!YŽI`ÓŠ‰²æ¿~-ŠiÌó«ÜÎKqXg£˜”raÈf ¹ŸžÜ³s=XZƒîÖp˜‡óãwª…£wK±é›~Û÷•ºà©9ȇÑS§žXޅ등¯YzTUSAÿZè™a< íjZ‰®Œ'Õ|ZËÔ£†´I©`TÊ,=¢YÅÜAÀ˜™™´Õå8ÐÈáäãÉWžj¨«Á´Èóü«'·åL©”¾oU 3Væú_Suœs­ïzh$e*K4òßëýÊVØqdCÂc|”&cÈžhîxõé°ÓëLF=Àßí°ùaøÁr–ªGb-F¾þš!“ö»•!L.QdÌ+ââ]‡G÷×A–ôÃWœ¤Ÿ…ãŽf7ñ^¶¦ye?š@U•_¼¥¢Éeª’E6\vöù1O7`LÑ »¥k—D?²\•Ù’…¿\G† ]0ò1aødí¾/¢Öà·TÞ¹sGÓµO÷ÉrP•Ût)¢ÊºÚn!rØq°ñµbdF‹™RZ/Dí]¦uÜšJ5Õc7nÜòĆ›Óy¶ãÏŸ¶µ|ÇËP¬(€SóôyNQBùB {¡ÍÇ/K·ÿão!ÓhìÉçý’Ô>£Ã>J@ÕSZ1 ³šaÀÍ¥a ù|‡¦F =aùRg~Ù"` £:EŒŠ>qü§ @R™Ÿ_ÈÌPæç¿Z©X*Kå—Yõr¹ Çx<Ži@‡À0+؆Õ"õûwvhJdH™Ï )QÒ 8%%#MÛ`Ñ1ãaÕj*6£ôªÒþ«9àãiÔÃ\ñû¿ÝièEõëZlFOïø-%bÉ™G>$)¹è³ÏRo¿¹wßÞÚþþ—gËG¤¤ÄÐÅ »İؽ}[C©”QrAS“Õ¨ ©û!©òG~þÚ.·‹F ³ÀNðTøå7oöhjL“ºRó9ý\n}VÄŒC ½ÙþÝ¦Ô tµ·½uK»D¼F@x}Ãò?œk®ö1”0Œ ì[YKjùˆ¥€ÐæÌnEÛ+«{àÓR¬åO<”ÃËxÔD#ÎW_s+—žºÓ¥iIEOëň Vi-æ»Ué¨\Ș^d‰FPA[B1éçÈE·]³\V†œd„³ñÐbˆ#£”-¾Ðr˜ªÀýQ/…Kôn»ãi£—7¯q@›ûƒ@#Un¶vaìÀ4ï¡Ý?zi9™àìAîÇ]ÐÏF Ѵ׉Oï¡§íGU¡_D¡È„Çé÷ð*šÁ®:àZ†úÓ±•d’'i2‰lN›¤lb +CŒ½&£¸”5Éç}'[ÅzÆéÅñˆf†_íæßèÛ.ºõÂA UjÓ?¼’©ù®²™„›z1YR#Òt DòÓx„j)þõ¾§$3xc*Ö{d+ÏÑ<ǯ[ïùâzL5Û®\ 6­tðÈáa˜SÇ[¤b*7•ºwï°í2d œŒ–OÎٷɹ`I8±ÅR€Ï´ð­’459wnÏc«(æydû ³¢1ÈÑÿf’Å‹¥²Tþh¤R©”J¥]»vQ ˜ $ zm­ã“¦VeIîUòÝr1nja¥è7•.e:ù•uHÍ3²Br ”M‹÷ö< säYrï³ëñô—Çt34u§ý®y$X/ÍbâQÇ”3éØº¦Zà"QŽÇ×P¯ÿ⪃Öwúye9§lԊѲ–RóQCJZFkIšVçÇ…Ý 0hÕj/p(²f7m¢?ø lH)£×¥K:tíjò$ÏŠnMOÅY7e¨'~ØÞ´yjßøÇ÷[nÝè1å´¡Ftbº(©qKNÏhÑ9#S¼+kiH׆¹ü &÷¬`(^Ö¼Ù}°wÛÇŸtr0ª¨)utƒÙ„ Q•¨"u©R7@K…»–häA•# ªƒ¨*Ç,åìñ;É8E†ëH“A˜‘ÀÃÆ mæ'i€ùóÐØI&]Ð@ù{% 6º\À6ºL r‘úî“5<¿Lä½›<ôå7ØÊUfÉþb„ån^¤}qV ㈠{àéb®p@”XÜÈé¥hìCÛ¿Ø/ûØ&Î;ŽGŠd)ÒI§Ó£ÓéNgÝùd'J)+PmÐu¬Ûxk/£-då%8ÁvmÙñÉs„·v/h0M•к A¥v[Ë:ÂKIÊ´VC *Ò*-Pˆí{{îÅvIÌíwöTªI¨cR!åÑO§ÜåüÜóÜ=Ï÷ûù.®«¼ß螤<0ƒùÂË9`Fzwq­¾ø!à\¿4uþð7ÖÌñ2(ÎB@ -Ñüºgærñ€‘¥äd0Ãâ4 d ¦¤#Û¿Œe[•!›äsÉ-­381€ˆ³ù5Ë—±ÅQt€õ8ù"Ëéï?%À>åXR`ÄUO/ܺiö¯· _ßGU@u âeƒè‘î(bxJ È‘­&!exÛ ÔÀŒ•Kéþs[ZfÔ7‰~!è–EÌúµk-lÖh¤2>>ÅV1ݦۤ5€ññ1øÃ²¬¥K—RÅqœ€‚~J\ötèêÕ¬iÅÀSÊ8k©Qg ³Sǰ muwg´áö2NL9füej%;¡äº-'ö¯«±–&F@ƒ‘`}ðª-—2ÊMæek‘¢ÿÜsðãÄ g3žìÌ0B€öŶþðók‰ƒ½Ëüˆ^:ñÇuÖ@ÐJ¸×Ñe’”Þe+@,‰c¯­2õ~ŠÛ·kõ¾­S‡XÑB'~Õ³ø¶ÖU6Ò€¿;´,Àˆ˜ÙÚ:×4zKyÛ„£y}—µ­¤ª¤UE6¬D6G,-á ¦¹"N¾5bÆ‹ĺnà =÷2 “¡g<À°37 ‘R9Z.ÈcÆöQµ½”ÏÚZ+@DÛ@Ÿ–¹Í‹°f¦iä+\˜óF;@zøáy1]=­’É)€„*„€ ÷WQ¸€.ž\™íÁ…a¾`å¬{‚r?d¼_Áͧ%¸íͱ‰j!èŠe—Ìäl¬ÿíNd¯™aާyò[ÍõÕwExÕß螦¦î=°îÉ}Ÿ¸tˆ шx |ö€®*«œ!<<ë—Ü>Á#·÷D÷ éÍ@n€ú¿’ÜóÌðÉàî0ïGGÍ p"¢êy†œª{õ7+ ·2Àº1tº´c…‹Ú ùÞa¹L=ûö_Ÿïì\°sÛs,ÙÐÈAÆ÷òîÕº³ŒîMÏA-9’É Zâíh‘ªëŠÍÏgK¥¤šÛ6V̘…¤]HhJ±Ó<ì,#Y„Î 1GÃ#Lï‰)õVøv1ûé§Ù§–° Šððu(ôÌŠ•†¦xLr·2Õ¦1ݦÛÿß*Õ¯Tà8q÷^uÇF'&`…}tyѼyégQ¢Z×6 vÁÞQraØMÚ­è×àÎàn_®{ÿRÁ‹S8Ÿ,ê²% ±3¢hÄí‚ì(ò(wî(Ö2޹/X I[M;úvo;v¤Õ¶UÝòÍ!æÊåv/­€iiìY[æiGùêòœWOqº6#8~(â0VÃŽ¶+=nw̨YHysÑ6—-ùOÇ7?þbÈ‘ú-á<1‹¡$‰k¸òI+@1Ÿ˜ÀÃè(éò-£çÚœù… ßô“!‰fûúÖëúÞ×~¿òÑ O¢›XBxjå³]½Ñ®áÞ¥Kˆ&$IôÈÕêè˜ìï8Ue©¯j ªK³î‡3_%.€±>Ñ Ü“ås‚ Hˆüåfß÷² Wÿ`/ ýô»À$ˆç†š8A ƒ?Y¹pð£¶V Ž“Í«=Al5YÂi¬v8f ë²’K[ffÄìÆÊžWö?)1¾%nøQÈЭã÷­`\à¯W~røzäð/ p45‹g޼º¦lvÛJÔRâ@;Š×°®e,5=b%Jêž’‡ëÛ}·i„«Äçwa%Q´#ùkÝ­+ýTA$Ïó$E/øvóà•¿{:>vI*•‰š¼U&¦eº=m¢ºvkõEƒkc¸268xa^s K0Až ð ì­ddáðõCîÕÔXÉ”Õ[±Q[.ãèd»I@jnn Nl£WÉ¥ŠŽŒõe+dbæ;oÛaC}’Åm3keœÀù0ûõ¯¨a{4dU±áÏ÷n\?Ÿ£AOh?b¢Û×õðÞëe"3ªÒ:þŠ“@ÕÆ_ã8Ka%fkY ¤{‹F®{ÇêÅ¡¡äÖ-¡@øQ Î$ˆ:‘ð¤ÿòå—4¸%k«a fw3=¢ÅÇŠ=7nÆæÎ%–øìZ›í$uSþàƒØc3ëAu¬è§Ñ\É×êçrWã[ÇÖêà4ÍØŽì”cÃ$Õ4|Eõù½D/’|" øIˆ&—Ì Ìæ(Žoa|CG9÷åž•ÜÚ=ãwO3“>ž³œÛOºg)·ßïö#÷,P[=Eî9âX—¿‰n@$ÍðÔ¢£þ9øÀý÷3î¹F÷]Áýàï›9!‚ |¢(0ˆ›# ïßzÇÞm’ØjsÔî2–-àð#áXá’UrIU٤뺚}ëøæï+)žÙ2’8Þ·f~ íƒ=ÓΖqù {Ñ—y&{¼æÇ¨s;³ "ÃÉ>‘%IB+—øúþøŠi lm½=w30æ$LÒoÐHÌ";œÈëíV6:êtýáċ͖$qÖ÷¡×;m¶q¸›Í›–ªæÍ÷‰—?ëÈ;Û¡ú,=BŒ°eµ•ír=V²£f—K€9þþ†}± $‚hA#ÛZ0A%0…{ð' šìake‰ɲ‚döÄñ@½¿«0Éäää}m/ÕQÓcccîM…Ÿ'éäÄćïàCHáyIðʨ^D³~p=ô2+Ä™–r!j-¶tŒˆ‘Qê+íuF£‚wî+SX·H^<(˜A-£<°©Aa‘C<ÿ€Vz@Óa­¦,Y}$P ‰»v«\kÑLØzØõЀ&‰\ºØò@ãý`@D–ûŽÏëÑ1#2ÝýWÑ,©ÐˆIâ–!Z–.[ÝÞ™J=ûäRÑ#ÖìÙ±Ú¶CúÈÖ/§8Á"íö®DŒèk^ûÕ“ë],Õ"?ò‰7w®°ÿÀ,c7@K.«nüébEÀ-ûÞxø HÃÔ‚ q%³‹haÓl…´ðÇs9 »¾ÌÈ49[ Þwl˜¡¨ÒÈ=¢O¢§y÷Úë§)/íC.™œEÎé::¼öq´Ÿ£§9šžº¦¤ßOKEÚS‰žá]êH3ÿ8\W/ÊË"EÙÆ‹¿áh/p…2íü)HȺÇIó“°Prì¦B-Xþ`£€|Hf ê½HBHìîXBðb5;ÐE´hÆ@Fq\‡âű²ÝV2¡~Û³7š°LGž{naÿÀf'óØ5J»º–3(b}½À;ô !±ìHbx õõîU{w­=ôöS7®tŒ9 œÝ¿ Ž’¦Ñ ºaåÚ,qô¶ÞjçTÈÿá{Ï/là9†ñx<<7O‘å LŒÓ)ƒI«LRßQA‘ññ[pu_àIzôðY’‘9¢Ñ_óé…±EG-h]cN—~3œ7"E' ]ÞÆ*ø+ÿJBî H%J¹X™t‚Åè?³eŽÂ µ²ˆX*…ó<<¿fx¸Õ²â[-Y* ”ì»S—LW:LÝýÑÚò–ºgç ™«•T9ÿ`#º|åç-ÅÜ´iÄù ª È D†l3í8ë•©©Úˆ:8ô¢Äp ߨòÊã9=0j'- 8*Œq$´uOf%Æûç“/Øöž„ú˜Âr^ÁxŸÂ5<½ÎwåR±â~á[Ëùãêòk×·˜Ù(XÑTó8Q4ãDß ÊÐ Qv“Çó8Y¶’Úõ–ñBç}džŠ*Ü«ûst@ g4˜)Ýç“fé ãâÇ)Þeƒ^Öe’>ž¦¿†-±ô 8DSÀ ŠË 焱”ÿ…åÐâÀõ‡œ‹Is.®L3ÿDDû}nZ8o?¢g!€,gôdÿ47¸ž¯C ’8°c 'û¸æ á“O·c#0O²-e3neÁï„ Ž@=ŒLФÆt¶fàf¦Û)´-hàð‰ã›|ˆ÷ ^…m|ºúçÕp`ËR[3[ôúyo½T»ljÒ&͆C êXø\aý/?L-áØM87ah¼Ý X’Çm® $CWÿ2ø‹‡¿Ã‘Qâ¡ýûÞ¬øJZåêø¦ À« ‡eQâ9^ÉæÑCs˜¡t !ç?ì—l×Ç‘"Y²d=N'Ÿît¶•R2‚šA5Ä@¶F€mUº²MIÙ qœäðÍŽ=Ë4)ЮڦI[™6­­Ôn]µª:BBþ‘²Š±MʤIí‚P ñý÷lj!qrû½³¦JS)ËTˆ¦åé'ûîÝóó{ïÞû}?_7¦Ä¢qôqÚ K;FÊn’ (ÿÆ! é â†)b£gjª'Õ¹‰±_¬[µ»©®®ºš¥£<öïâµÂäÉД­Jwë|§`FE3|5ãJê­D¹ø‚¥vrïÖõˆA(Ì:ÒÞª«ù¢±h‘W ¤À!°n0~÷\½ÚÖÿÎa}Jœq’¶%Ý,¤ õñ½×z×>©MKÄm-'ëùÛÖp¡©&âŠw­Þ·ÞøæÚšÏ£a´¥>øîÛ_»öAcpRÝE= 쀋¦"ÙF—©ª$©T'³¦œr°†ËÑEÞ£ò Þã’Ä2Ü+(² }!9(Äz(â“„¼>•i@rÑ’±Ð}ÏPØ"42Èx#Ao,v._Ã2\8T‰ðµÌŠ©7TXoŒòÛ,²ÿE´. d¾ƒþ Ãa²—Cç\¿iu„G‡ØƒÀŽpÖ£·ß:$Oålóyåc±6Ç”Œ©Œ£g ÎT¯¦¤]»ÓR–ÙêRɯ\y®îaÄÓµ<…vo‹(zæ–’}¼‰¢ øÑÍÁ£(Ã=º.4q3ùÑDªiëêZVˆ0hm-ý÷?Ã!ÍÂ!%©OËqÊÒ+ˆd)RÉNkZûØåd]u@àŽg…B(“NÏÞ¾LRž]buY.Ëå?+ Ðóe¸¸=Sʦ3€Ö€"^@¡ØæÍáË—–ÑãhYGMM «â´)Zr—£e ÒÖ2p.ôBÂ5ïªòŸcTtD¤nAÊ•ÉÎ/îXÿH¨©±~ÚHM¸êÊhv|l4AÓf„ ¾|â«:|µMÁá½[箞öpô^¬äÕBóì´ˆo¥]˜¦.žýí1ž—ÄÒašeÐøx'6Z;xb à_|©LÆýÖđ-u|¨:ˆÞyí ³ÂzNÃ=hD?ýdƒ¬qup@¢®§®OŠa1ó…XnwÙ¸ÍT2Ø’&&òû÷Ô>¶_øÕ«­ÊTït1.O%=_Ô»K…´ª*bHh¹'g(q¸¶Tò⠣݆\ª‹¶™VGX]4eý¯Ä2Ü#†}È'\ ü¸D¹ÕîG„ £Þïõßÿuëc½a€{(o8¨Ÿ­þúš+°|$€è3ǯ_ðäåÅ÷)ä÷Ïé\‚YS p ¬õÀ$À]£”üû†–]Ärx€Å£ ¦:6]ÿ0Yr³`Ðf´Öi8kfNVÚU#k™Y¬t•Ô¼«ô‚‰0&{~ý‹xíš*Ša¾¼!vóF›¢w¿|j'bbÌ:ž­j9º¡÷ŧöì¯gw˜È™×÷Ø».F­Š1+9¾ÒI¨Æ”À%ð@ú…p H=±WYK%Yz»nˆï_éjÜV ("°\„(„¾—ÉÌÏÍ,,,,µÎ,—åòI™÷¼Ùùò¼]ÙœB¼¹²W†»ïXgG˜®â¹• ¨†ƒMU×Çs%û8H¨'VºA­lC¼ßªášiSNa3å ´­$MÔìvS9eËÒœ}Ä•¿cë­ØüAã8Å!EÁYðfVªÎ ]íqeñ¥ž1v‹h±ç/¶*†h™m%5·Øñ`ýyÛMìÝÉ Å!F ªìn­”m…œ+S[ -Í^KIÒ|FWŸJS{¶×Çè€@q B¯¾Þ,;ͦ™zró ÷mÔiZ{+öôÑwϵ±t”§V=±·ÆI®s•ö¢–Ǥßÿ÷r·0µœ©gM=á×ï %Su°™Ôµ.Mí4 É4³†žUqV6º!'@`ŸÍ`Yî(bÙHMËIà^,K6ÎFÆ4²¦Ú ùl&ôéê’«¥²ŠrZ× 7ò×Ä0šY¨t4iF“À™tYñ’˜äjÀfò[ÅŠØû%–ábl` Zá\Û>?ôApo˜%êC–"* ŸC¾ ú•# Ô•§´7Êqñ%j@Πè× _I~Ká&ý A×ü–•[@ hÌþ ("¦¤+¨• †Q‰ÈÐdlОèchéq弑°7‚úÃÞûäuœî`XayÐmþñuaü" uA ëséó[Ÿ!ŸR.ÂÊ3¤Û1¾Ü_÷^w ×G:†‚5l5b·5Œ~W±Ú€íaçkZü6ÈVt•ø¬ÑfÊy S' ®¶ܽâO£-p(L»kµŠE¤Nÿd»[8y[ÍÕçâ‡7ÖrÁZ¡Fà‚…b4óÚ/ØÎg¹¼OÍ'»¿ã!Ó®b CK^(ßñæ<‚%¾÷¬d~ø*/,ÌÍÏ/¡$-—ÿÛ8¤\®lKŸ–}™›ïèè³HàxŽâx:и¹m¿d( oKÍÀ·Ûû­n–w¬œbÛHÜvº]´)U²ò˜8‚¼c$J8ë~øñ éÍßìŒr>)QÕÑ0ŇÑ+§›õ鿢™.zŸ}ê¡(½J "µšœ<޵øA#¦"Œ§b,æ b<³âÍßr°kbÈRi& I†›,ΰÝ+{|Â9ª ämj¨Ø(‹˜ ɾ›…îgšŽE¸ÆÍQ͈߱ çèzâû§ö±!.ŒR×&ÂHÚÑ’‘¬Ðˆa.`,b 6‰¹ö‰£¥Á»e³õ8°+ðVr€mXÏÁ2ê>$@æTºlM,𢩴ÍözrÒLY3y §,œÖ§ÚíŠ 4ÈBÂ×Õ´¡u[fN‘SÁ?` ±*ÐéM—°š”oø`ìÛÎ>Ówîƒ}-ƒhî?ÿìPß·.<½gÛ#€¬µrm8ØwfãÕŸÇþöʪ¿üŒúëi4þÓ²_î±QwÿÉÒI+­F£ÑhV³Ú½“_Z^ H´¢¥Ž˜gKhh^u€¤%øl|Ç]Ïöé8Ò@1TŠª¶Q«Ð§Ò¢”Dý'Û`lh”¦UT©mÂ#„‡íÛ½½}ÝùlÒØl³—´R¤ !‘ø0úy½Ù™½yü¾Ÿ¯|éy©ú2N2ÁÀ#XÈÜHÈ'!œ€H!ôK ‘‚€1c†X(aa5 ‘3á <…Êð Ä9&¨âT§kÒ)gñ‡ hâ)´|JmÖZú¨ÍYǃϚF¤`( Ë‚Äúñ¥ch %:Å„à™ÿávæHà ‘òÎõ{}H#0#’àҿΛz­ñìQ­õŒVÁþ`L)^°@þÍ/ôkàívxnzltWÅK›W{'ƒàP¬B;°1lß>~l]¹”óŒÛÿ~31ååŠV"³g…Š8å*ÅË—sÇÜo[™’•‚‘)^© ˜Á¿Ô²ÇÇrëèh~çöeŠ,G©åÒ/îÜþøR‚#1±ü8üö^¾bç¶}kn‹,]<çÈó­ Ë ÷ ×ÖhßófFübo¥”…([½¾H–ñÌtÕÉV­TíÌä„Ûé[]n1Yõsþxb¦"Žåb¦j÷:ãéI7ï™=“ÌN.+Ð<)/íŒöŒ_Μ|t¨ÿ‰—µõ^Ýwxsªû¾­›·lüÂÖM‹V¯œ_¯ƒL F¹Ba L1U`=3JàW…RãsPDUèbBë#-ªÖÅÈœfQ(ƒ:¢ePO¼C0%H“# ¸¼þ˱GVi·Dvo‘Çõg»´ßuâןmxë§Ìø=h–"@E† *ÁiU¨Ø HH, 9’C aâæY%¤ œ Á0 Î…²{R²{–CB!{«Œ Q .éìãÁgýr0¬'Q0äÆ2 )f‰*w¬åS‚Iðg"Pd‹‘¼c]Ë‚ûÃ?r#LÏ_°ñZ4óHÆuàÄt¬ÄOïúŠmõZÆe7Qus¥bº:•ºv-[vÓÄ*^ ZáZrfêm$­ÂSÿúÇsŠõ ˆéwKmà¼`;{u«F±†ëUD{p™çæŠfÛDéÀíæßË\¹”Ûp?ÖaKÐ,hiÛ¶oÛV)ø=j†´& wËÝ2+¥¶'''‘ÀÑsÜM«62Á8ÂY ˤu•výòÇJøNÊ+uŠ€Ãsê[€ú ×êü´ÕÍ+‚¨ ò-ìw&Ü,(¾{=9åu›füÈ «ÁZ ˆ®saåâÕï…îñë©–{4.«:×ZV(E'o»í–“}õ•¶ûWHÿÛnÇÎWœÞJ1w»ß3Yìv ñj9uñBîK lˆ „ïÐþ¯[NÎq^±§â­%!Aò¹EêøXø$ÓH8NÖrÓ]ñe*¸.™ê\ýêÊFH#a«kÂíñA” ™=O6¿ôâöóïôÙN_ÉJxV|Òíòž†~ £}¶hÄ5;åš]7Ê™ª è¯8]@#ÞXÂ7óe+¬dâUHÑ%A˜oðzÙË™FÆë~søáþ?=ô㾕û÷®ÙºeQkëÂæ&ªê*!’JNå‘b$Òˆ#@ž S< ‚?¸V óÖØŒ¡Baà š¢ªXÒ)œSàMÓ0‘˜¢SE Ú€Àõ"ø¯0Y¥2á\&@4€)œÉH'tžªêH¦˜4êõDß 5q©e]wÏ?T÷“]ò÷²·~®½¤|p‚ P9;¥*Š@ÐÍAL$C8<Õ£â8„‚AIܪ=ÈÁaÌ6ÌJŒDƒºøù#øÜsl.F*oDÏ¥sÞ<"nÃH ¦aMŒÕëÃ48Å‚“áÔPSðSôè¾/ÖÓˆFaIÄ(ÒִзÿÝîùªó´çîk/O¤l3îYIØæ²YÆk‡DZñÒårnùB™3kí¹Ÿ­5йòÄá »¿Ö¢ª|‰ðo®Y|õJÞ2vܨ´O>1_}R>©”r%kÇ•÷:X«Gi½Î£œ#Œå ëÖWüòn¼_c’šÌÌLϪ"Ý-ŸÓróæÍðâ0ÈôtÙó7®ß aµžkšHâ‘xûŠwßÍ{nºb'€üRÚ³Ò€"åRÎËnòÓW·P7ÑW);åïßaŒ§\»çýRÞ+&?ñöùü†ÖÅœÖËĽpy÷„6àpÿ.!Ó(ã}Ö9v²hä}¿·dåJvÒ÷“Es›7Þw»ßóóŒgt•íNßîûõ¯6‚™ShlI³táBÞvU¯·êd=3ëš=Ž»ëÖÙF5Øÿ_ºÎ÷ÀOYV€dOÇ*E®'¤Žs®-Jõ‚!ÀÌ.tVÝ´[è³ËÜôTsáI»óYn¶hdÒMWÝLÙJ‹1E2À“ž“+»O¹Å~ºêg­ñ´k‚[Üg½ŽÓs}4súô£¯ìG}kÛ¾³dóú… zÌè;G0CÅ¡ñÁ §É€QBUª.4p0Hœq(QªÄÔ£s)b#,б†pŒJë …KUÆM×ÔÈh³Šè‹2FAQDDK _Â)Ôl‰E‰ªaÇÕ5ÌM@w¢„ëˆhHpQ”ƒóŒ,ûP@H޹‚ìµÿ²_ç±Q\wÀ+Y²´ÒH£§ÑèiF3ÚËJs×€6N1¤IãìÖàlˆmìś킡”)&PÄŽR)-mÕÒ¤Á`lL[)=‰6ô€€½;»3³ëÝ5¸)¼~ßn„ú+!þÇ£ŸFs¼ã;ßïóHn>ÉYb/-п¶bî·«s»}Òèzý4½uð€Lt6”Ç}2¤²ó*̬‡(–ÙE)ƒÊ\ðòV2¥Vœy<â@ç\ ÈÝ êúå¢NŒÇ(õñ›•9ì}•É@nXäk4zpýÞ€‚#:¤lPúŠXãÛ]RùÆEùÊ[‹Ë©„äzU ”Õ5y~¾ö«Ÿo·Âþ”¸ð'­Ð„í·ÃHb¡ØXÛäDó;×â8±ÆÛzº*O“Ï\S"5Ï­ JW•R¯:Ð]¼@Ĭǎù&ãþ”[›F»Ï|öc<ò¹¤}°açbNyù]’Û“·îÞ¹“­³™]fpá É($¯[³ Y•e(ºäinø\,¶ßuü0¼=Þ€ÚŠ²À!n»Õ7=ìꆩD"Š1ÕæZ-‘pC<î›HùÂÖ6×Þé:­¶ã³\ß¹ó/™šÇÐ 1óÝx*öߊïK¸õ:ס‚çÉ(L¿špƒ‘qTê¼…coC~HÚûï÷y"×:>™l±Ç:2 ”­EE#ôåÝËÆo¸Ù"í©Øþ´ŠÙuÿ'{ W`òr/{d½k™Lú£–/jµ÷ô¬Ï×Q(Q‹sæzs]»3åp£kq~8±:oáø‘ÜR.ÿ-.èD|Øž)$£{ñ@Òáõ£‘V×íH¥‚áp³ã´Z–?‘Þ¸Ù12²õTOùÞÀʪ cYÉÜ<êør˜± èI¯*H˜Tˆn¢$)º&ˆ<‡Â}ù>#E@åT¼SŠ èh)zæèž²¥Ús«µ§K…gJsw,ýÌÁg¤£ÕÆá*­«RùáVãXµñjíª1m¡ßyžtUª]_÷©övÕxmû*„žM¤»J?ô¼Ñö$ÝVJ*—‘MËé“+%ó¡ŽJsM¨HÇ=e@¨Ð«AP$­Èº.áQ4Ñ zž¤ëD1¨.‰JXøS*†@H6ˆô¸*>½HhüŠð­:rù5áúÛdê‚ÂFQïÁ!ÔVœC„ïòš›9;ãðc¹Ø÷wŸ¬(ý<¯S“ˆº‡¯*‰[Ö>{<˜L4||½i÷®&–(N²$­[» AòÇ„ùtr:»Ì.vá†DþÃ× 7ž¥•!Çß´lÒ=Û™ˆpÀÇ]È<ýÃGÇqÄ—N¡ý‡]Ý&£Ý0ª[k*ÑêØ-v,xýŸ¡Ëïïzï×µùs›=`ÁE‰}¯u­Ñä]zܠ™3ÏÆÇ¾·š­H[UÅBUÈ©ÜXrí¯$$ ¤ì=†ò½3n’û~$' oI;"¬pËà{Õùš@‰¨H†.ç ¾»•ày#pkZ­Ý›¼ÜÛÍFdlÏÔdÀãœL7€[§Ê——?¨ÿÇÑðxö‚-éxÔEâ–ß?Ä6è˜N´Ç£x͇þ]¦ÕÒ¦å³ùó¢v(jïýèïþá‹›¿ZÑP÷…µ«´"CЈ`RjÂq„(ÔÔ¨)US S5x%‡9dªPuÀ@K/!E -R¤bE®^¥o]!í«(:´Yí¯!£¯ä_(îW¦Nxïô䱓õxYŸÁz½¬[e}:ë63Û ëSY¿ÂNʬGe&;¡±7 ÖWÀúŠX7e'ç°~‰uç³·ð[•õdÚ£eoæ"\¤ YOñ¿_Ÿùžy5¤ü-¨Þ½àDþƒ*½u#}aµ¼¡D]¨’bIK`T$|¬)¥*ƨá…j#¦¬c–J%¢H\(0˜F ¼æ¯çÅÕ¤k«8"7NQ6”71\85j²‹¢ gX2"ñÝçÁ#ŽK";K?~G^]LdJ5͘'*}/ö‰½  &„ÀãB–mè¾£*–9H€Ã‘Ì‘áld 8”Ê N Ÿü¶ð¸oÉ*ªbŽ—2æ4÷…š×®bJÕŽé[Êm·nÖONt¸`y´áDü±ëÛo§Q·õÊ•¦sgš^ñmÔp-/OñüèÔ‹`|:ÞæFšŠ¤ÝiG§eL—Oøt’'½`¹Îi²£õµ м$›íñÿ,ÿòúdb‚ׂ;³™]fn¹Ë#î¸Ö—gÿœ|~*›u +-«s"ꛊuLZ|Ô¸¨°¶ÏŽ4¦'€Æ ×g‡›@‘´»çaW7wÜ—v[œH-, ï*/Oòˆä•I¾L7•}ô§ú¸S³B5[ãtêù¬)\ý°9v#˜H¶ðûÇ_"jµ'í^$=Q·¦ŒÍ@Ü­sîÿyb¶/÷Ç"ÛRö„ÝìiؾŅʆN´ÍÏzíp{*pÚí˜ÏÁM§Ïÿ÷Ž;N3’U*LG;í›-ð’éˆÄöa>f$õN¤àAWØn},rðˆGÚø7­¦xÌ«¸_‰Ó…cû\;ðÁåÚcGžØµcéSk æT'V`•dEâi:[…uÕ”©GQEUeÉ㥢.Á*žEÅfí2)P¦Ûlþ¢ÞücÈkuiw „7• 2H8¥s3:;cP8Õ§q{¼AùYDo(à2ÁvÖ$:ßX/ލü ý„u°7 ;QÈâ·ü¢ñ–p·@Ë>…ŸÊÞ«7³ÛCX¯Ä·ù3À-pŽÎúóÿuÀøC@ýÙvéèfu×µòEÚ¯Œñe* ñ+2Ét§—F5%s ý£¢Ô*”FBµÐ^Z“{øÂ¥JâmÊΡ’ KfÚ>Îþ—ýº"½ã^ Ã0 à 3ÌβI<­o§mÅÖ´GëyÕ^*õô Å"¨çk²&{»»ËMôZm¡wåÐj^6‰w¥”Ò°1&&ñ¥öè‹P8Š×k-ÕdÞwg_bÞ6O¿ÏÄkKi®M°‡‡Ífv÷™g^žß÷óhäó̓ G¯aOÝÊZj~€„­\“ü¯±äF ˆdhñŽ{Å ®ùCn°¾ý[pU$£0OôºPZýç—7×-g&Œ›Ê‰A@´~«vçöž¢›rŒ/×s=V°éâtŸ¶39ó¨m¤âLœÄ¡ç! ðÒ¹3Û ;‰e`ÞHOåÛ0£óù(ªÜG­'¨W¶ÅšÅÕã(\6:y½ñàFwÂO8Vªo5õ¸c' ù×ÛŽá›XgYVÜpbF.Vt2®òò-àSÙKæõÖ›Wöo¯Ûµ}ã*“YFaE…S4QQ.$2Œ„2Vµ’ï^Ü>D-.Ú3r`ÇF1^úþ^e8¦ŒŸ ‘Î5Pño„ÐZpT*ÉBØ(!½2ÝŸõ-ti¤·–d –ôÉ” ÃJˆ.0£–\€+xÒ"8ÒƒNj?8´ß[·˜>pŸªôk]þ+,±ôÉ•^qÁqÎ7 c¾á'8b§x³Uûi³òÆWƒ Ÿ l{&°VªÒ¬¬Š«Á3‚ÂÉaAQX^bYÊ sl<ád¦îãlÓæÇ)å½ÎZš¹ÈÊa† 1q2ä'æ€JFT2ÈÑýë< ²rˆ£mdÞ3ŒßxúÍ'ÎŒm,ó€@†Bþ Ém +dÅ Ã5žYÅñ¿îˆÁà‚ýÀ#þ+Îú&K÷ @,Â’ÿ6óþOÖÕ×ÕÕ©F`5ªº2TÓ?¸;of&ôöI;e˜l/ –‚Ó‚Õ‡g'üuìÑÖóæ¿qh½g¶ØãQZ~½”mž(¹€¤ä&¦ôcFæý?}g×Κ۷žÏ®u²XÜçêMžž˜.¤òú‰ÉB2o&ªÑÃëU¡JÆs%áÉâë_Ü2Q° •™Ç ™—ÉìÜZ…<Ýžn‹°áAšš™ÁëL¥277‡=x™™Æ`øÀ,hR„gåˆ7}™-}×Kä­žóPm$\céSÒ9Ò̶Bîˆg7z8º•ví#P ÆPrÏ´%_Ðä*ÔíÕ­ùàóÇF–…dMáV|mçÚññÃ¥Ö+?{Iá„j>¢qËÞêû²ë¶ [ v{9·hšÂÇ5bt¨v:‡ë“‹Ùc¯]8·ñÊ1Œ&3ÏÖˆ÷Þ‹•rÉüxªdüÏiãÿà=nqÂÑq‹E']vÛpF«¢/8W²œ;YrZ=3SÔOMèmã­“ffÊN•Í„•Kè?zùtóç^ܼZà¤*E Ôp²Ì0L@$E®øÏ),²U”eV„×ÈÌÖUϲ{¿ËöëÊÜ%ĺêçµìç5 Ž…SfèáI¯@ÞžOyÅw…DíÑáKæ¢F.ª´ŸNêÀO4ÒQC:4r™£2¹¨Ðè§ ÕËe… SœizüÞh‡!Ò!Ù0åƒÞÞÄo%Šè…6ÐE®t,¬¦ E”ô¸gH ’¹8Õ·Ÿ-w®ùÃe¸™Ií]¾û9v]8  ¢ÊjD–4.(G]"ñ‚Œ+ɪ<惫ÂÜÞ/ ?Ì(Þ’ÈUÈ„#×Á_ß–Â>ôßã£y„\cH?KsyÐwȇ¤ùl L cÌA2(PY]çob– âJ$¾M…?¬œ{?zàÈ-–j ,¹ÅÑÓ_âÁÏaä£B©Cf$¢(ˆ|56"V¡J”ÍØ”“ñ¬6SÏxT¹$&& zV ü˜,§é”42ž™(åZPj«ëú¯Þ0aœÄ ½ÿç3/|>$²ËV…—¼šÏíw­Vý¯ ò­“^Ò}Ðâ<„RŽæô3 ÕÓ8Ûtl}ˆD&¤Èœ(°_¨ÛBÈ#„B¥2‹˜ áoÓ•ÙY?8žnO·ÿr›—-ž¨GSSäï¡Ût,•$cÙ¨i{üØêqóDÑiE äiÎD*AïÉr>½Ô)Yr”MÎX¬àD‹˜°Ncðì¸çÄ0ûî¾Óæ%T¢ÕµÌoîDKn£;–ùÕ;û.¨ðµÃÝ{7혌ß>wzç†Úõ^zŵ¾eYe/‰¨uõ袥¹“A‰ÀÀ\£qÜ£¥búáýÔ¦õŠ&T+|&ø¹ö—-§¡ì´^›<©†ê‡ñ»:ÕTÉmÅíΛ)´œ~"sštý ÒE–Ù‚ji8 õ-—0Ì×ÁþÌkǾ׶uwý:Mb^•ÅÇ ²,È"ˆ¼Õ0ÇÔ2MrÕ®uRÓ¶OüâóûLhòüJÒ·‚dUr‰'<æd´H:yÒ=ß8ÒËWz¸Ã~¸$’KÕK¯B…ТޠH´çndÑ”¹.qŸv±àÉ®¡P¡ý«¤#LzUÒçÓä語ÉV“¾•¤K£=ô‰¤[ð1„€7ÝßSMz«)x0l|Úí« ÿÂ*ÿQ#ó­[zܺü»|átŠT5èÄêSèx²rþ|è—™Ð{”¯o–7…9\^‰×D.„&PŽHœ"<+Š"s܆0s|+3Vs8‹aƧOFD2$P¥Üà¨CúE2¨ë!r]"C<{|stÉÓù#·k<ÔM†\e)®à(°ä{û,dÃ<§†yf½*ÞûGF¡ qaÐ_‘kÀŒO¯Aœ)3wS]úSøûåÅqÇñü…dé¤Õj´íjW»wò ¤›û¦ß¹#ýÕ­¢`ñG£ÕÜìÜo~3;óû~~>vQöÿ t¶VBè‰04B|êç49¾o}yVÚÄKF n̵kâJ%Žçv„ƒG:œwʱ‚׌þL².ŸkÌdöp{׳²X¡SaÕ’ªDG͇7[3é–©B{z´ÞMÕgSMÓñœ·3—1猷nÌJ7Õ×®õS¾© &*6ØSœ™aŸ °dfæ+¥´ e¡|ö‚ƒtwzúÞ,?P%0áG.| L9S•úeqQôåÕv²­,ý¸@Ü—óyâå¦#ó.”˜%›ÌÇ<ǹ³ÇËÊzM^¦ÎK5dSmï ¾`PQ•Õïµ?™÷"“£u÷2Q7Ù¶¯n=¢t@%gN=çXõ9Ë´íÆ¿]ÝåZ½LØu¾›Ù™Ï4Lyчægº9›‰æ½¨ CÙg6ùõÛ;ýDñS@¢ôÚ5Þ™³š9~‡“GÔs”Ó@ü‡Ïù@Swû7¯|”úd¥’øßÜ.²«êôIñÙ9㻿äó2;E9á KÅs¡y÷ÿ¬Î§¾DÙo}ìŠ6Ü÷¥U~¤|”j†$A÷Û¼Qú×­½§á䤠ŒÈn@¸¡n*ž3³¹^ª ÃpgÓéZÏ‹[ióöh|cµ3VjÄP¥Eª(UŸÙ¼&™2]ÖZ NÊ}Æ[¾ü,,$Ül_‰s8º¬äN¢= ~®_n©üÁVmkµ°D“‚2 H’&½_D5ˆ¡øÔÝ»Y{ÛTnØ™‹;$ò’Äùdr)”ÄZ~ôøñ@½ ±‹g’ ";C@&Å÷„·v‘ý* õ«K™‹‘çéœvÞÙE‘ý^aç@e>Þ>Mùs¾ýæ]¨äðSžñ‚týW¡-Õ† ,•Ç]U©±n¥~åò\@7½;göÒmˆ$üVÚ<ïË;ÑÉ\³m‡d,Ÿi™tͬvìÏ;|ýúÁêj`_HP¶Ö¬0ã_y|ISIÅ׿ÿ”1ÓÉä’¶YpŽd-s®80åEòÄüˆ•njŒ<)û¨NCH÷(‘„#ÐÔ™$åçBY(±LO\>c¯ÄDAä¹ Dyñù l-ä¸pçÓ¯ÃqDsvlÂEì$ô4Šžy§«mä£híÎ/ŠÇ¾öåÐH¦ýø;5kCÒÐÉçáÉå‹;ƒò2*†Å[µL¸ûq›nÞ¨]’(!~"¤n¿iÕá"] nkf¬yÒkqSö8D¶:û°üy)0I,oÇ ÜNÒÌeZ»ë‡U‹ç28ó”«Œ`™˜2ÁÔ€®‡$´D Ô¯D©ÝÆõýX(D7‚Ñáo™ŠcëåêèµN}Ô¨Wæ]à0Lp¿×ôz"kÙìJ,W)ÒîÅòÄѰH;.ÿLkXA1!˜¨ Q ¡*…^–„4%¤¡Cß–®´'ÓÕ¼ò.ì;†&R½'8¦ñ$¸h†(ˆðа,ñóv:4 ÅÉDx)Îȼ €bóUÌjÊRÀÓá¤~y¯¹w“öÜBRg¨v·B4¢UxŒBD ` Ûç鯡­ô3øR. ~ Üϸ~ÜØy,h~Ä O²•`I¢ QïZCøÄOaþ ÒrÖœvž+LËGød¯¯ Mè…ó 9áÿ‡Mý‘rq/Ì/Q!NðEiìò¢7_¬Y¬«ÍÒT° #È*ú2[nÞ¨›K€?¬zqðÚp°@¿Ð\p£ù¡–rñ€7X?âÔ_»}æ*@k a”9¶Í³:¼\óÐ`Ó‰þmR™BCjàÆõ7KîaÇJ‹;ó¹naú.ÌJÀ™_ÊÇÝlÌs®þ£aýjT­L  Àʯ¯­^Ü.—'ÆÇgš`ÇWjLL”ai½ûÎÏÁCˆBÀ~©d|ëmàjÂj¹å¶Ûƒu#Åf'-Ú ' Æ;"ZrA×aSDKNÛƒ¦¤“ß^p_I¼²J¥Â*…¡Ìžk†/]ª-£®=þû*¢„Hd ºB™¼žeíJ³XLä[½B­c„vòêl»¾èµYÙV;s¬ö|®ýþ¥Z *2’ßW´½üî/|‡ŽæË¡6Øà×¾ˆëÑX5U(t§Ö̸~Ün.6\ˆ¹v´cð-[ÿNœzSk­6φ3Eç%Ž#Æü$ŒE£ Ó5Üö=“0 ݆Àq´Aˆ‡×^*Üà8áý¾Hô1¡Ö^“§ ÁSÀhÊwÏF}Q¹_M„pMÀÄÞÜ£OKùî°ÀqŸYH>¾{iE•Ý&¬?0 ~ƒ2á0Eˆ!Ú½Îõ¸t$È3ár/LáGD†/.A„1 n]®òãAž’… ×¶,¢DU1…eEÕ4ETÂPÆ•K´Ùéíòp:Äû™ÿ8þsÝ«€nA€¥}éêžú/䆅Z€Å%ý2BU{AäÀ»ª…ì‰ )ÏøK™¼§Ê¿ÐýkÃ/¦"&ìR‹oE~»GiZ+- bŒTxF( UP%“u‚º1‰¾ºªâõm³ÿÞo̼~ÜÀn]@ü÷@sù/]¤R’$ØS(ÄèϰTÎbAü3„Œù‡túy(ÿþFïüÁ#DBÒ£k+øYíçóÓpÆ/Ë“à$àTç(? iËüúÛ‡ªÃ!™©”€?0zíå'ì½æYí¢;y°Ú Ùø°³×ÎG=+^Œß²›‡:kpoãž§4lB›sâÄ V¶¹dµ 5ÿõ£—5%°M±ú1Éçid_Ër8Ãá$/¦íÂì|˜O)+Zµ…lhɫ떓;6B Cövÿq †ˆ‡ãḗ19ù¿EsûöÄÔE¹<>ÊùØŸ,ß>uòW‚~©BSUnÞP1ðiû-¯ÃsšŠy@*@*¶ü i8ì´º€ï,Üt½d·»C ùín®Ñ²w \OÔDtÆ„’"«?}k£“«…]cgã¶Ûúî{›«2˜lè …²¨2pøÕÕÖÍŽ’ÛTÈý¨hG‹¹ØLQÞ±[ N‹ëļñt0.”âP¤r` æäÛ=w—›«‡ÄË6A3RrjïÛ­sµ%áMÐX9¹¸cuXÙ½ùÜþñBÛðÍæÑô> g­y/ææ¢£CõŽWë¢v6qålCtǪ¹AèÅ*W}"XÖ2)6P`E«æGÞÙ…Þ¨äé°Pp  gã}!Þ£øN¢òŒÉ(‚ž€ËþOEx¦†%<¢¢4»A!´IpÁMÌ3˜óõà{„ˆÿ¦Ã7_×>íÐÞß!ïßȶ¬P¿f>O(µð© ØMÎñµ‡Ši“Æ$|ª_ImÆ*10a‘U)4Ï”R%\ƒõAð8ÐGÖè²¼a©þÙ ÈV`Âç—UŠa }ï &Ü&å›Ò1ºqy(Œe¢†dÐu M¨Ah“‚ç! ˜¯HÚ§ùEE&`M½¾M%‘Üd©'È{|ñèÒyFåJG|{1…]¤æ‰:!QEà/ðÚæ)ƒ÷†xrjN“§TqµÎv¦ ¨R “ÝJšŸ$ô}ß•×ÎhJ@e°ipPÁ!!'Á:扟œ6÷ ~Z0ýñ‹tâ (ÄÏ ~†ñs²øõpQÂï%€kˆ_º4¿ ñKÿ…iGþÃ~¹ÇFqÜqÉÒI+­F«ÕhW³ÚÝ“Ï6.Æiy¥o ¥‰E¤iZ„†ú…}ºÓÙ>L$mš¶AJ›à~R…&ZQ(cΘÒÚ¢¨ŠZ‘()ƾÛ÷߯¾éoÖ­ÿ¨B%$"*•Ñè4·7û›ùÍýæ÷ýüz´gV- `EÅ|©w&Î"PyökRf[J¢»Ú¹¤2 HòϬ/9/­Z+Pð ܹÂÓ^ðN§=3íi8®Ò¾9ï|³—|®¿’íEô¼È¸ˆá²&÷L)3xEøsKéêAlJXƒ»'.ª*_1bÇÆœZ+nt0É„³Â屨éêL¶"5x°¾âñxùzÇÙ5…eÕ÷_Þ¹¤°™ !¤ ü–õ‹1Ê ‘ áå=;VÚVcÆ­qj<+ìà Ó¨…2Ís£ŽÅªKÏŒA‡ä?WlšÃáô`MÙ&MÁ 0QPÑÉSÇA;è c’\n6Çûœ… 7—›É=$•‡íó›#óã  îäè,>yò}‘ÇPC$A&úÆã!@‘ÉÌ!Î=«*cE=£"“…ý-ÜF4kÖ9ñ¬ ƒ¨#ÂY¯ è³OÃO¬+•8R$#ºÂjÅþ±ÊI%ÆÆkM³ÊËÄS5/~ÿÕNŸzñæG/Ûæ+7îY5£NÔKG'½ÆE#pÇ-3b™a'ýúÖ-A¨Å çË„ßWþˆaÇáù˜B°°U;½oKÊ©ˆŸµ,«8Û)·ì=ÙáÆÛéÚ¡‘Jc´Â1÷f‡kØÿ›I|t£îÕ†ukã K‡H"œ&qù"¯‹ ÁÒHŒwmPÞ«Ö­Ã}3emmÉ–}ÅÔi§Â Tµ¥˜v–Ò–í*ôE´@E` Ò$²ùG@Röz§L;ü× z 8dщjýíÒk[…gWêËtDP@‚€"iDàTNTøB¯·(þ ßW°ŒÙ¸K¡oÙ†€F°DT‘oX|ø; Zw/|k'Û¤-("yƒª„áGLÑØNØÎCÏ=Æ ˆÏñÖÇÀ¦Ì袤\)[©‡”®|ùZñNÛRðeº“üåPil£‚e9€AÔôÄf2Û¾@ë_lÃŽÅìÀ>,ÁC ºçV$lÂQŸ+€â]Z1C‘6@,‰1^'f,tLbxlÂqÚÁ¬ß+´øu`f ˜çhhìg%ƒ¯½ó]åÙå€ü( ˆ»(à/ÃÂC(H[ÖpïÇ~…˜à^uV˜ _VéE…©6({¿@@—A²%&Ö0稹Nû¦³÷‹F.`ÚçCÂþ—õª‚9…7æ/øû‰eô*ç´3vb{àî®þˆ™ÛUH!ò[å ™å$—ƒ÷(l¡~ÄÈêŒ"9ð €PŸæûë» 3“=/Ð>™±Y|ÕèÄìž]Shù?¨×º‹žYQ¨a¨å $¿ékÒ''f¼ÆIk·gìµì{¸Ê¯°"cîþ¬K¥wON$H\#ulŸ5Tå^ÆhÈ@У#K¹Æpý<Ìg׈|ró`ÙÆR4%Äs"!ø½ãÝ EfX…;W炸ÌÌ£ÐÙÏ¢‡íÿ½ÍÅ ´éé©ù¯SSSH×þô;Y%,CêÖq~i(pãFl"³ØÃ6öŒd@§¢Y+<–½*y—>b6DF¬¸“Š[CÑ1¯Îój§2“‰›f䧇ʊ弆ê§Ö-/†$ ¹hÕbqèÓWL#l›õ¿9õ´qû€ã–»na•;†(¶uëÇÝ„›ŠeÍøƒ¢ÇfˆëDL«¶çìt¼ã@ó=gw»Î~'rpSpÔ‘QçÐ}£ 3¬öŒjè#6OtØ«ôF㮕H EL3zëVcwëî'Öj’ "„Õ ÑxL*Šš"ð/nÖO‡ ¬ËL²»@jå\“â ®ÀıM§ÍmÓhè/Ÿë@´C`’×.Òf :#™vÁdž¶ùjØA¦ºBÖaõã× í‚¯!6³[™x[+[²‰Œ%1À«Ö% #Q @èÍ]*í±&´)è «Ï3`¶ÓV}Nô;v€§DLTŒ®§‡šŠhÛú®n¶-j®Ì/Dy‚ ©åŒ±ýáië¢V#ŒÅQ·¬¶ù6†=% ¯ð‚Z°mMÞL{!Ûm‹N›ôÙw€â‰‚­Éßûj±Ý¬°m´K³`°ÝÇ­•i…s@´±#‚ëh“DÛmåi‡¿t³ÊæŠ4Éôç¾#Gƒ´Yf4¸Ò¿*¬wø …¹|4Òd¾0lC´ÑN‰‘ÒÛþßת[? )øôr‚%D'h!)$T@ ü,(øª§}?’™t^âsIh‘^Ør$1eèL 1ë08ïkúý¢‘ßæÓ~Žö‹Î¯…µæ°Gš+¸;É à鎬˜”þ›èz³¨&€$ü_!bcΫô ؘ=?'ÌeMÁŠ0ÿ’L/È>lð-´‡c¸r %È|‡¥“¼ÿ«Â¿W¿zÁZ>ç˰mÞî)Ù¶F0R¤â ‘ɆUÊ?nî›4âÓnkWBñÙ3j¡ruã†Q@’ÉV@-34Xs±·by‰Š9¤ ä+AiàÊöŒ³Çs·2•›Ÿ„"ãÀû7^~rÂKxézÈŠH ^2Éš PÍÓÈ0‰m$?K,+â$”§H!Tƒ 7®ƒŽÌL³òvrrr^qfr¹£vÛÿ|ƒð˜ƒññqúo ùÛ‡×J —BñCˆ$‰äËÅ|²·:ë%2NijªE2vØʸ9\ëšÕ_´j»éÚQ§XȸÍ&††jóÏ–×ì]ÿ‹î­éÁªžY+quàùE‹DBRhÓ†¼N~ó…o—•HÒéžË˜ žQŸÍÄL¸ª&ÜÙ„›®‡O¸qN*ò hŠ;U3âÔ™f9¨ÿKÏ/—ye™‚Ôíßú'ûåÅuÅaKH–Vitu5ºº£ÍCû°M± ˜P¥¨­RD´•Ò¢7ÒšËÕ¿´}¡©)6 UÉ»§j Þº MG;c+TZd¦£““ÇÖä²U¯&—ŒæS-r”jÍŽ´`2˜K?ûïò© lYNŸ|f¶Ã,¦E£T++‹|pö¯ý˜ühî/÷—ÿ¸Lú vnݺ9µƒæÂ… ³#–ÂŒa¹%‘À;ï4á¡Í'°€,—j‚Š€þ°ì¼ègMí+¹æô¥Æô¥¦|nS:ýèÜæê§g9´Ø&î¾îµ^zó^À‹m^ºý­_¯´µ"ÀÆ0fH|ÃT•êsò¹çSɆì(Îl¿ìmõ’Mx[½d#ÞÖ ¯å󲿟ٱÖëÛFG×¾÷nÓœ0qXDV®êÝñÇò…Méx`}>³Á›¶¼éT#”  é6y“-—smè†÷Ióî‹<`ØÔ1Û¤”š4`SÛÀð"‡À¥ó´x5ýx{-‰~@¼[ Õ’8ó‰/WìôpÑË%m;ÁJˆU$\ÑãŠWTÑGÅëYëÚîPÕÃf9WK¨®rÄp¹~ñeM€Ä»ië×™Kí0-æ$оŒ‰òô!%òœ¤($Ý€Žù@ïÖ|)Bö ¬´M@Ü?´;¶Æ5,FÔ”Ýmq 0 ÞY*º,Ñ©Ï7ŒneÒ¯z$îW?9c”K#~UàxPì±t¢RŽjÕ¼ÀŸÚÊþ¼E?³E?¸!T5_‰œè–£•nYT$%"óñý ò€‚c®Ø3KÆéb©—Kv¯ ï×hg7iצ<'¯B*äùû]Ñ4ñ óZÂò5ÆqéHrq$á÷¿Ïñ½âm$1eGÿKé:7‰ŽuûRŸ’:Wö0NþÒÎ_û.Y:ÓÀmBO4¦0N(a%DãŠn0¶r9þc]üžI'bÒ@ça.Ž1ñ¶è~à»dÚlä4¯ß+–j1Æ-›QÅ<³;(g€J¦hbÈ‘"°îê2l}g!s€«•5,öjˆç§G—q£ ×,µxyeÑßp/ŽRé!Ãìƒtï²sÕ»ƒ;ìÔo#¢ß•ò0¬ˆAKôCɈ¿Oþ'Ë IÃÁhâ„9yHÃnó¼„0GÅ3\®P©à'N­ÉÉñ¡ÑóGé+…6If´é²÷üxf[!½®àmûûXS]]¥Í”7Ta¿–N¤Ðóú’n¬”óÀãËgæ½eF×g½õÉ‹ÑñÌVŒí…LmæÒ†+”£nJ?߸š?ý:ž‰Â^rÉÖ?ž¬-wxÐ`¶QJ YZvþ£ï‰ÜÜž‚Îç¼ûËÿý™ÚÁs2>>¾dÉ®RGÇ̇G,ú«O¥2µb!÷nÁ#7…0¬ÒI`×£ Ÿ5µsÉ Pìx¹èùOZž~ÂŒª©ÒˆYÜ?ðÔhr}*½ºPˆ¦’R©æ®W³ÍR¢¦Î,j/y$üá¹¶drS~¼y"Û–‰zcuy¯îÊDÔKÕgF£ÓHù{]‘úr¶ÔÅÍ^¶q||óO^ü†© ƒ)µTÐÏEa8-ç­ÁdºòJË6¦Ó5Ùl­çµfSÛ6|¿~&'Řá2¸r&? “:Œ¸_ )»žÔÏït$˜L¢0á‹GÌ–ÜìuDŸ)‰/ÑD§¯]ø=$Eãv}úííö^óF÷¼ì®Rñ˰èR¥<ÄsD$øüp€²€ 28Œ´ä7 Lt ]Xô¹€r÷ S'vÄ st¥ãlÑ]DìÓ¤Ø ûnGì¾ÍÉN@™Éਠ©;\YHÝ«‹çÌ Ì"D‡k1Úù¤zu/ÈÀªù2{q«C Xúƒ2/©ñpÕ—©Òj°œæÜ)>Á_.MB\H C™f™\Q !¥f—éôø6ýv̼Ž2@sl!o@—‹°¢CšÒ±¡¹¬H!î×Ì¢÷v–¿øÍâ S±Cú£³ŠßŠÒ$.¡*¥Ig@j´4¦Š^*:ÙýƒSÁ¾z¨èÓn¡™÷j#ÝþÁ¥³™bJBÐÜxH{¸”T޲q»{li}qrªU}nq ÄUÜ—-Q i°ŒYµW¨ñZ2ò Ôöq ¾+¯GAÛÐtÙÈäQ.”õË F5[³¬úŠ*Njÿ`¿Þc£8î8€[BZ餕V£Ñj4«]íC÷ðƒ@ ´ II I DJäb¨Š `ûðÕÆ§“ p UJƒ}¶Ï@ÔG J¤Œ1Hí_j¤†6lßkoïÎw8Æœ§¿Y«(jD%*Pÿñê8Ý—™ÙÙß÷3ìcщÂÎ꜃î2'Äýšº„&.E–GWË D>ØC çÌÏŽXËç ^ê ¥Ô_Iõ£õ*»l°äþCß­y|Ž×#šÊ\ÂEsÊei6Þ|EýcÅô#± ;\Õ<øÐ†ÜIã˜Alg°/Ð.}ÉÛY@–#Æ0a’3g_K§‚¹lht¤– !Óe3Ÿn¥ŒÛMñ¡ñÂîxâÍÍYØzÄ÷€bÑus•õ(°÷\õ”12Òš Oävþù–ËvÄo¼åØáŒ½%›®/f"N¼ ø1Óò=̼r©`6&Ph9ûᆠÍ@ÁàÞ—×<¿º8^˜.•þÃ$³ÇìñícjêsW¼òùüÚµk¡†º²ãUË¢ïÔdíÖâx0=ZKºà„gdj,˜MÂ›Š¹ü‘wª¹œË…Oö¬7±HDáöš‘d(“ßßÝýâ¡özc« …ÖÄX(Ÿ¶µ=ûôrõÉ…ö}kûv:áë$Zóé HÑiÌ&ë2Éz't¯¿ñÿ¥÷‰æ’¡‚Ý ÌËØÁë_†ŸYêÁ²Çox±€Ž®vÒ­0áP`ò^¿©±;µ;‘ØêDõó+‘F]ViU01‘æ—ôeTj\!~ªâÁÇ3TcÝ>5Ø1…{£×Çó‘ç ê¢ÂËz¼*kQ÷ë1ŸÙkNwù¿8`}Üh6­–_ð¢©s†[•º]<@÷iÓÑJ›O¡œIÃÈ¢¢…éc2þù‹Ðáíp±hŸE¼XVy&Hâéí^Ö§ƒFJ}Z©[ϼ¡ý¹ŽžÞ t ð“!IAMМÃCsA¾m\=L $Îh¤{¾ÃOÀ¼—^W#¼}å‘—MU¡ ª"X¼Áì”Îbå?^,ê9D24¥óôç‘uEõ+"X“q‘V%¬ª†ß+°¶D/ëyU›„):ù´tyÙq…Ç}ÔÅÒqx1ýw¯ya/)ÉFtžÏ€I p;0V¢Oð9áúA•ƒ¤SáÓsÞAnG‚Ó¦¬ÏϺtþ§“¦Û,}`tÖ£¸ ³||¬Ç7Xâì4ù4ÂMçœSáÊKüL< é{Œ/ƒn:yD;SkT/`ì:&>û±¨# ÒȤTÃxßtñ¨·pÑdÃЄõ+_‡@%É¢JÝ–§ÇS¿Ì§·ÚvKÖ‰¤’ Ùtp’OíC·ÓÁñth<ÕÑïÄa\{áuÛôšºï¸BöX]Á©s …ô^ØÚd2MgÞß @MDz‰ý–®þ¥!ãìÈ&€ýV¿ãvã­ëá#V?µ€X2Ѱ¡RC–e(¹°­¥­˜+ÛfŽvTñXï‘xA¦GÝäêrÃ’±ÛûÎÿ£î/3/™Åàr\+tT O2zÑ µ+dIß¼´¬Ø[Î-÷¸Zˆ** Uµ°j:vPÇÒ«ð¨ò6 ‡eÀUFØÚ¶uUãW—£åªFÀ2Q+W˜Âíè|/~pm}&D'— iðFÕHÔç§ :Å8V#°^‹Ã)êã]Ä\“t꛾ 0Ü™ŒT ѽxýRÀNˆ¤ËnjÃÁf]R  Ë’XPnýdZdŠ€^¢´¿¢ÿõW*‹iÜ!"‹-f]§ÝIub~p…½>¿]ƒ°^E‰h)ØBºDݾT•b Á*Pß݈J0Ïš{”k{èþÕÒ“ó«W<¿'…W ýµÊd×Bö®ò¿hî`̽0K@2'ø„“ÉpçÞÙ^÷.øY}À!™Eu—FÖ> ‹þE»ïÀÏE$Ø'©‰PC6T¬VÊâæ%B«R:o°?Q¬\I#Äeš†Ì5&‡vQΞ~†€"ÀÄ1@üóig€~°Ïð#¢é®¼q¥D$V€Æó $ß)Íôuû_ä§¢%ñ5§(ŠF)ww"Cý$D0t$ú~ ¡›¡wÊ.!6ˆ8Kt\ðÏ!.7ÔeCˆ›†ÐÏÇr÷ŠñÞáy– ‹¤’HB¦~„$PF`»á$ÂE§ÉÛ9‘iƒÍ×Dq»=ºc"Û’  á¯n¼>ÏÄDÑÁ?|†~õe3T!89Ÿ åR­Ûá%È¿cÉ⮺ò[ÿlÍgÃvfë=~̼îÕ;»3>V›K¶äS¨-©dð½Xµ%ù)†5¬€I^ßY7}÷.›f³™=¦ï³JÓ¬øõæ®’Æ`J:/€D±HÙ® â#û'Š{·ê¿Îµeâè:3©¶ÔX°kÊ%ÃÙÄÞt|{ÆÙædZsiXê! EÚnÝ\¥aŠ’‰ l¨º&` 9j]nàjzP¤÷d-¹T˿د÷Ø8Š;à–"´ÒJ«Ñh5šÕ®ö¡;?©H¨ój”*餀€&$MCš”ØN8|õÅ®1v šR 4ÁŽÏ¯J"Ñ¢––8/SšPy$„J 4gßcïáó9‰íóô;gµâß RU«ÕÉ^¯wggç~ßϯ‘wÉ&±·æR‘B¦_êÉtW&)ä»2~8nÉgv]îy¸ãv—Ó W¯wõ«6¬oðsÉDKVI CiÃB2…L;†KbxFÆìO„‹¹Œv*‹Ï°ŸB;Á‹›LwLÄ;‰îd¢ýo®oúA£gŒ˜U”Ù¶a0TQn×S^ažùIHô¹2†b€UBH!ú˜ÌÁä S{yl ÔžÖd< ÕŠ^„RÌ,U¾óôÕeŸèò }ö‰¨Á(ZFEµ4—1› F-Þ»Aý 2ýá!÷ýf¨Júí5zd¥E™Ê,FMsþ· ÕHÄBõ²óU=®RŽÈÓSÂñm£9t©Q©’7=@§¬ww{Ç¢¡§îÑߤn¾^‘‚êWÅþ‡™U¦ZGèæeÎ<8„1H™¢É«å÷UÕY5Õ,ÀÌÀÍ–23BÄ>„²³v¹… ‘_­F Ûâ ™ƒszC6s,ZG¸µk‡4þÒ£»šáéÆö;¨è‰2?\¦LÒOD¬V*³×W#eÒKÄsüG7Ôà ù¡øä~k~¸êèV÷š*x«–¹Ä¤öx@¾^:³/´¢ASÀ7SÖ{´ŸAS#×.©<õ(,áá‚’¡0¬¿LˆØÕ"† ¯D&ÕiœpˆÉ¹$òÙ‡ì2±`Wôr9!C_H5ƒVz¿w¸Ùºëj%¨«ÈtÈ/D.79ê 1nª¢½-<õ2¢âUì¶ÕÅ)UœT¥ON:’ '¨8ƒåD> ºèb´œÂ8ᘊDž9cš<ˆ#§Õ½-†AÄ2¥fƒWQ:ªŠ1C¼zÉé_s¢wkøV€·!:ZÈeAOW6]_ñIŒJÛœ¨ÁMû¢·HP±ƒDóV4—:Yñ0Çù™Ÿ±ð·h5pÊ,Ýaµ„½ÃÈmñŠ;’}iú:Få´œPÅëôƒá'æ(œØÔò˜24°&—ëL÷!òábü¡|²¥nÍ%Z§2á|¶Mådêá#C«,J–V-šøt;òÆ›÷®½kÅw.íÜuËGŸm'Úb¿\ùõJÇÐÈî=+'üö|nsd¼ã|lC•K…³™H6‡òÒ… ƒÊYœlÅgÁïJ|ÒÝù3HÁ—á­Û‘3ggÏÿ;‹fgg²i~¾ô_ ¯¶ÿ™mnnöó¯~fæ"4R’«ââ‘_v-}Ö'z™Èö%©sOãñ¦b®=o½ïÄz¾Ü)Œë9cµçý-ç§Ú“ñN?ÕöÆë÷>ôÀSù'â‰È‹‡›MðXªw¥î,®U:z–mظÂ5Bˆðc¿[ŸMµ\êM³ÉH1ß™OG‚ÏI'²¾à‡§2ÑÌ8">šøgs!É$›ütørOÂØX³gªR <$££[²þÎ b`ØñRÐþÀeœà×hz¼ez²]Ö‡d+'—Ü™K¶O%·³­~åâþ‹~ä­Ñ?üþ5e–YÉu⤒(!Êm¢_ç.úézçã§By$æ!.£³Ï,1@Òj‰çXi!Ra$~L—A„!ubÄùûÞêC[ø†Å[ŒŠ<Ž8ÓDÌÃÎ=í^a¢y 3B¦:n]Åï÷¸bòA@»ovyœ:×6]gÚìèT59CÂ¾ÕÆdJ¸ãPå7ë4£Ÿs«óˆÙ`PœfQ£† N¯øx˜dÏ÷:[yšz·‘&¦¬‡¦ÿä×ÄsHL—3LcÜÝt­ZƒÕ¢À0¦Ù·€˨ÑÖ½ ÏE̹3Ö]«¹„¸:õtO `<´ÔÇ'º)†cjpí™{TqОí­Ü´ŒÂ-}£½èƒG=9“‡Êó ì –ç ¸Òų€.÷ƒæW:ÈÆƒÝ«%XT †Üç·2‹œ–¦ž¼f¸ã/õ“³K©òð*òìZcëêÚz‡3U å¶›WˆÎ¼¦#ë”÷öX…ƒ|fµÔ,4lÍö9b¤¾4ÌÄpÃÜ -ù<þ/ïÚ„9ñZ!™KÔÈ Óg‹X¥Î=k¾ö ÙúVÙ6ƒœ*6Á“˜Ü¤UWUi¬#ÉéükDü‘Ï:bÌøùxÙ§ "áqB§¨ÔòW1“Çqð5±¥aNyçž·–‡–æ¬/î7»Ùüi.þ€?}ô§±6[¥x×^­¶è;Ì©ÓKË@Â`¬â¯ÕuŠ¢†ª ¡Ñû¾[‘zÙ§10œÀJ£ˆza—ÒðԀܼº¢t’Hba´_–F`6ÜsÈý¹òíÃËo¨@ð)Ñ”>Öqk¾¸m"Ñ”NµN¥;Š™ÎÌøÎ)¿k2Íg$ü‰6€dàÀÆwÞh÷ã»ÎžYãR5èP5 „xÍ K½³g¶ÅÏEŸ~òÛ•¶Í‰òÞ»Qð#“Ž¢ÍI~Ö\ð#þxËùüÎéÉŽT]Rš8yñT8ÌMý ¹¯i‰ËàDS/=Xš ñ³@dÐâiáÈWÛÿý& ‚uð¹maL_”Ÿ¯þþ·&×Q<f¹œÜ¼Üúôã®\¶+Ÿoõý¦B&2™jÏ%¢X—;…ýs‘b6RÈì(f¥½ó~Ët®û쉖«¼:—²û·Ý8žê˜ðwŽ ®k\¬Þ´Ô|ì‘~ÔÏõܽ®žªŠ§/úà¯÷ç/]M¹ôô ©x³ädÉQZ³r<Ø3;ðøø.OeÚ§2—}²éî£ßš.º=ƒ±e‹éd¶'7!”Kµ¥ÆÃ ‚Ê$ÂR6Õ4éoË%ÃåšÓ&‡— §Æ›pN2×%플eýš5•¨T¶j,á.á  «× £okPŽýØ™Í0ú¸Ø@}´L‘úûåÅqðHH–NZi4­F³ÚÑ>t{ç³GÀU@ H£ j!Ò$5Q§|vqý¸QD“–ÄMðëü8›5j…Ú@l(æÑ¤Ò - ”`|ï;Ÿ ÆÆž~³®úGÿ£ %«ÕjonßÌÎ|¿ß§Ë–¶˜€D•ü—‰CT¶wòI¸%"¡) Ç^¡¶VÀq±©°ÞP¡èÀS­–„o»³f6&H³ ‚=l] SÔСµß¡oƒiÀÓŒ÷^†p/Ï‹ Ð¥Z±¡Av…0÷¯ö¸ô‡Ë¼¡Ç±®ép%Æ|±•-š^MºË´Ë{yês·sŽˆð)ˆ°7Ðø=^„(ô‘^ÈøÅFÿd;ÈUb«ë”hcе(sûh©Ÿ[¶¸Á4=È|Ô WöÍQm¼‡¯Ÿ¢Ù*æØå57ZôÙv‚© ÌiAç‹Ñ ,ööUj!™š‡T¯òIUk5äõrÄLQD—{‹ktQýv›¾€Ay‹¨Æ?®³¤Kt3iGíxª#à—11uZ6@#Œ6ïH…»vp±oaé`Wv™ËlUECìê~Ÿh.†}Þ‚Š¸‚v;²Oõ_þ¹ùa£–鈷Ýç´‚>a×-mˆM 'XVÔ+¢>éB­ä~mDt<ø Ì èo·5Ñì¤Xo®õ/óª  ª†TjbÍTÀ÷3±'¼_—ˆ³Š8AÄ ð7'Iÿ“†8Ée‹Ü¾.ñÏRyÙihQÅ EœÂ;_°T¬å(-G +“g˜{ »oÊŸEw>ÀmµNÐÐmU/]òÐÅwÈ]P£KMêGݵªMj©„<3«àÖïŠDŸ"5é8}Tœ&b¢ò…–rLÒõb¢~Þ ñP·S_“À~¢2\sC#ï+Wø °ê³-â%†Yh˼X¾|0Îf+sqHà ÃñN!€0€@ÆËeö@y•¸Ù°yã¦Ø°ª–,ô- Z±‚úëß*þðÇ%Ø èø{?ËÕ¦Ó·ó²´®‘ù°:“Ép4v«¤È™#™:0’|ªñËkU+ž`áÔ TÑ5Üßwì?:âR Žw]MŸ»}6‘ÿžß»71}266&¦Ä§ÿ´ÈoXœèˆ²à’ùê{ÓÉú¡[å™Ì6À4ÌÞ\"œ¬º“{°†}"µ/-§q v8¹+9T"T¿ÕO=ºc¨ ‘PùÂôpc2Y“OíÌîûâÆ+‘¼üã I‘O÷ìßùý8”é†û}o>+ëXMùt}6^kJ*Mz{.RRÿªjl¸>3T3’ÜøêÛÈLÃ?®”;PŸ1Ô§éÀŠ‘tÒÈH®bƒµqæSªÓ‰-9È9ñÊ|:ß(5T—º¾s;KlHÅ÷F"kV®*2 (N4S÷Y†ÍÄÜÖȦï¢öP|`©Q ~@tx¥iJ"€'à”.š‰D^»%é ´êuD›>ÑbÅø#/™’>=ˆ68âX³®ÄX@×¼OÁ[¼“’ÚT´ÞX«ŽtYoúº_*Tu$(Ž|¯—¹¤ÉD7jTG”( ëü¢E+1±fꊠ2ãÚÀÑj~žªCf›gÓuAÑéRð׊$F[©hQÅaUü½»Õ -ÃûJg7ofŸí¦¿JE Fl嫹”Ö­ÂëJÌEšé(ÚLJMâgÿ\« s ¼Ñ+˜hÆ¢G_?¦  †š$z,Ùå.ï'µœÚ&·¡¤é,±ÞÆïvñ§ %8Ÿ­* s9ŒÝ\Ža¯*ÇvP¬6×.ºÍ[MæLø* bý©’‹^S:Lù×A È¢ªX£¬é9èBïn¼Éû«qG©)åo=‹.½Ê©>=ÓÔ9·Utág†xÛ‡½‡k­Y*PÕc1}׭žU(æOš÷šÑeKçiñI½lq]¢ÍýÐðêvIStY÷m#m–ü"½`St fK‹û³[™ìä÷"Zÿ6}•Ÿ2 ¢Æ4¬èÔÀªEH‰¦ïXÃc¿åâïc w)$ÔÅ.€«"TüZƒ~&µ¤_gœó¯#GÅôrôÉAGœ"òÆ>C|€ÿăù  ËÞ#uÊm0"xZ¿*ŽiB: çé³P!ÝÂ:ñ\:¤ŠsæT'T1 Jß “ÇUxÈÑÜQ瞥³ÑÙvm²ßükSÙ5è>(>&N+â|àú‘GV?Ι2Ãä6 "fÅO–'r•1·Îº“'«†“(êeJ‡ä– %‡¶ §*òÃáçV>jh ÕÊ_îM¥¶UoÓ&`ãå+ Xƒ&ÅçO•çc!ø++‡üV“¾ußq‚ÌCOîé!ÐûêÑlm:Q &µœ€¥Œæ@QÊ¡(€¥7šØó Ç!?T ÖñFÓcŒ˜AeAf™ôÚÕXõU.½ "ÌÄÀ»v“@bI׿âÕ©XE6J$BùáÝ7¯ï=]·¨D±t¤Ž- :‚°ê¡6Ù³ºàêGDtѪŠnCR 0á“ "]PáÂ9­`)ÀMKDl—ø†¤yÞîT=Å‚|]hT§ºf‰‘>!Ÿ %”¨”ÒLS‘|N¨ä|X FY iZXJIÓ&†âc Stq·WDé¯Ö2.Áêk¢‹=¿°O8Ø‹†s¿ö‹îÚˆyv»N¨©ÖQ ~_a‰.*)ÿoöë=6Šãޏ%K'­´Òj4v4«Ý=Ýù‰q ® &ÒÔ ( I¡¦•lIEê'â¾ñxuìn£i v}Ë AÚðð^Ç© ×55lb„ÂàØóô*oè‹ÀÌøÁPèH<ÔW˜qü‰Ñý©ˆoÆ $Æ šƒ­J9¨aý”Õ\Ü7™ª™·À:6|s{‘—q\°1_d[©TêÁƒû@pü!ÿo[:þòøåæ8ÎÓkž"Xq3Ëм¦2tuO2Q œKµ†ïøÆ£þyKO¥Èñð‡Â3‰šDä¥pè@"þ“óç*&œc±1ß„³w4ÜüLy®LUŒsL¥¿»"‚wªîò@•›¸/²Þ ¬‡Z§¦phh¡íÊ×Э‡÷îÞ,ÀÉLª9‘ð‡F›œT}4ö²ô@l¬j"îØã0ZTE6®+4ˆ¥c ’ØûJéx¬º'+š„/z·v<Öš û“xý}N ×:Ž?ké;ýìÊÍÐu#‡ÚjR­¡LŸxLRêtT2ômÑgg4Eç‚l×XW€à–ª¡˜Ù*6- Ýf%H lXtûX¡8S,zø¨A¸‹óÄ6lc¥»žd<}|‰‰“yõ—”¥ˆ(à¬;™Àn:×…î·}§XÑÈ"P¡¡ßï6£hDE—%zÍÌ™æü€ÿîË":ÅHÇ Æ¨i¾å7oÔ³c[l·Û͉‹kÖò¢lÑo‰Ÿ¯]¤å—Æ<œZ› Ñ–2u1ÆÅcŠ€ve}úíçsÝÆŽRZDáL›R¾Ò@JíÍ¥Ùåœvm÷Š>6p˜n+µÜØrÝÖQÊzõÛÊçï–JvNÓ™ ¾`c`ÚíŒcIf‡{Ì}èíñJzÁ7A+´ÿ|Øô­q¶mŠmJ`C&©µÔÂ{Öºâ¿ÖÓT\TÅ€&.q…ÊÌBòó5ø7=¿ è†Æ-“z°µ$%‰Å *sùì,0åÓ@‘ÁŒ@,qE7 9z"†±¸®‹kØPì<&ޱõI..`ŠÅyh‹³Ð+·¸ŠÄ$©pŽšü9ô~>ÂÄõ÷ç¿ís µ«LÚé<\ÙC–ì3´û,Y_´u%ܘ¹‰zзìîæéé–¤S J3nžˆ5%C5ɨo"HEj£ñ}Û^(±)ÄCû;·ÿæ·å« 9ÖîyÔ‹?Ù55é½[ÛÛYÕX»*x¨qvÜÝE¬œrý‘k¦O‚$á‡5*S7ùR!ÿx¼>®º^kÍ@,à6#ëׯO$™Hz0L÷îÍ}Áøõöló…ãüs‡oêëë¡\Â2劤ô÷lM$|±ðK“ñ–ðS ÿxÌï„ë2aW“ ><ìvBc¡½±d Øñ=7w½ydM$TëÄkâcuw>{ý™òB‹R¦LC}½›¢‘šÛ«8¿ó³Ôⱪ©Dc<ôòd¼a¡í‚¸â!À~HùØØøsÖ9:öÏ–Ÿ½½éÝ£›îŽú£Žoô_oþióôäÁèØ¾‡>‘艓œûc…M\½SåhäÒîÙÔ[NÌçÄöÃãHEÉpt;;26ZŸH¶ž}תR ÆÇÍLC…¤è”Qd”YZ[%K¾—#:¨èÌdtDí^™’˜$ãKw»[î¦<­[Æ«èiäŠ.ϵÆ7¡.\H¸f˜ªªÑå ¥Žˆ~h·A#_%D‡\Åð¹Ð¿ßND»Ím,f^f©ØU@ÑdùI£M°Vb# ãw¶àgËr ¬›˜ d¢}ôºÇ v¢—­›2œ8Ýàé÷xG{1²K ¾®˜æq…i8‡ÀÔàPËq¤¬pg‹3‹ÅIèy¤H[æ–ÁTà™>>Õn7­ÕË82j¾íx˲ìšjßóøŠO¾kH„œÒÅI"ŽÑ—'Iöoöë=6Šãޏ%K'­´Òj4f5«Ý=Ý_Åàð,8 4Pªª&Š !åU0oCí+WüÐùš†’6vQ°ÏöÙgŒB“´‘¢æ!l5€”V´Uª¶jj|w{{ç;Ÿ16öô7Fêÿ– ü“Õêd¯îvóÛÝù~¦‰ûË6ãÓãå×#öp¨RÄ‘„D‰z‡ÍßÔzãß+ýE@ôšù“³ö@ÐÜUmo_F÷V£77 ÉNh‚o"¾†xÃrPÐÞ^ý­çu®SΨ:`yˆZ´ñ2æ1 MѨ¡S›¢î#õdôg°ÆT€.¤tï7fb ,súM:´¿D_ÁéD{9pNô`赩ëðܬ®Ä“¿ô‹³|úœ1­š8Ef:}[«=6ÖA¬\G6,bйÎò¼» (R*¢HôÓykžéX"G'?ui&ì<–¦í`pÚ©>2 -êÑSmæo01T³a€™Jñ­@ž×¶£¿üŠŠkL\Xâc&Y™ŠËD\b·ß5×”j²~ªûzã *®2”/i3ƒs,˜Ð9Á?XüŽIÏ|Êå á8gK ³å&ò3„yái,.›âƒ  òrŸ@ hŽCL é!ƒT\4ŇLò Œô42ç4$Ø\7TYÀ )q2à…‹æ®¶VõTƒæp„BµÕ_üí5Éh¢æn¾9›»wóÎQÇ Ál9‘:šK…S©/·|k]u™…°e(ð*!ÕZ¶P¹~eO&QŸLk ¯·`BŠBucé“0OfRµy7ä$À!…l€v7Ì¥a:¥Ü͆G¿<49ÎfƒñîÍ^ Sà¥FPR(tÿþ4$ÑäääãŒÆ¯¶Ç±=¸õSS$ ÒÖÖVJ)cŠËlj5{2å6§`6Ñ0î6OdB¹T0› æÓG!ÝT=d߸~Ô)œwš³nó¯ßÛjñb›^‚ú;wŒ¹ÁñÑW3Ù-ÿüwpÅb“³E,åñØÆô $âfŽçê3‰º±D$çw~2ïëº ñéä‰ñ ›¨/¸?ý×瑺½È"ÔÂÊÀàžÏþP³é³å‡O&Fë³™GL§!L…ù±Èޭ˹…H7woV’·NÀêæ‰´@1cO¸µ¶oÞX⣺…m¸¡i:Ó(ó/åÅ;‰{ºdn¹ªË ì6dj0€=,â€C.c»á_"óâ>A,1%ý%5ì‹c .‚ÓrÇ*U~»GQ,ÏÐml\ˆ‰á)'œkeÉ7 y¼³ŽŸx–qŒ¨UBtåf˜A {ÖRŠ¡dºŠ-ð8†e®öù«êœ^‹uJ ,îØóËUÑaÌö?(ÒXéÅ]áTõâ#T¥„Yefs8Yd1õ~L]PLùÔ9*#[Fd©è‚¬¤¢ŸÜ;Í味Ht ƒ^{¬ÒƒÇ¡9±Å" ÛðpÞžéTE÷âT Z#¢ƒˆÈdèUEŸWv¦K&Å I;0OÎ#ÚáçpÜ?×Oè³UˆÂuáûªˆûäè ÿ}HD}²Ãýzd ÆTƒ÷q¡N<01P%¥p2lPª}Æq&:ý7,F‰¦Û%Ýlá²ø.Þa‡ŸR©r£/¬,—œõþ©E³I€Ëàž¾=†€c½TʳËwëçÐ: #ÃÇ鯝ÓÓÛðšREc~óMUÅ·OU‰¸%›3_Äæ>{Mh©ÜåÅ$Kàk·DO…ˆûåð»àÁ›f‡gæ§Hó·•Rx”ˆQÜ%¼«ú"ª¼¼Eùûy&®© àÁ4sÉ”BVÛv*”*”sÓ•‹1 fð‰‹ÎºŒfÈh`À|S~@WlqËK h2ô‡u 8(e˜Š ¸f³!M-{™Iòqƒ@1ò CTRä<÷e*yÅecö¢*®$.⇦y6]^`6€d@,†Tùï ýhá¦ÕðbpÂL—(ŒÜþñÄDcjäðX²©àÂJóȨ{8õŸðd"RH49©úD¾æÆÍýk–.ÂðžÒòòrzõê7±¯::´^'*G&Ñ^?þÝÄÈI'Ì烩dë4åÝ& ÌEù¬œ‘ Ùf7Ñs"©ÔáB¶Vˆy·Ðròø7MÝÀr‡ÁÓÞÖÖ6;;û¿„‚Tz\áøÕöÝfg§§§àf?Øß~û¬er‚§Tõü¨vYæN8—ªM3N$nzÔi›uÀ9‘Ì(Øc¼‘J×:¹Úñt(ïDnÝ:°a­å%–®!?ñÅb¦œÚÌHãX¾ö•ãëLjT1©²{Ûª‡UO:[ëŒÀžÈÔ¥÷¥Ò;ÓîÉ-ÏUaM³LO‰U0¿fËÆÊÐÇ{ÓéÃ9ç`Á %r¡Ô \:œ=ôðê©s`¦Lb÷_ÿx°ÊWì¥e[ÏÝí&Üæ‚óý‰dC&ј̈́~í¥¿³Äæ "H7üqÂ¥ŒZœ´£Èi3çb‘Ê0í]@ÊxeL@X´SOç ‘5‹qHm|Òíÿ,¬w¿„DÄ¥&Þª’«Ú˜ê=X*—8ìÔÄyëé*Ûk2D•½OOÅžøð[½˜zuRB”g—s³Ñg‰3x´kÕJ_‘jÀæ•=³½¾…ÿ`­p£ð^ ÝäQ[tØ'kÜJÍRŒ ­lòÌÑ7Ú/Ñk]m)«ÀU× Ã}5ÀÔÿ²_æ±Qg·di¥'=éi4æé=½C{øo¡i8LˆŒD‰Á½ÓJiƒ ‚¶±Á€mlùÊÊ8ÇÚ‚‹/l5mÕƒDI9Qš?H@Ž@R°½×Û]ÇWv§ß,UTå¿HN#UWãÝ÷æúæ½ßïÓç:ð¯–J7Ë©C†Ð й¿¶î…ך­·žC×›õôáE¼#£pÇ|¼OÇ| d¬³ ´…€A…Ec¢ÑÏD{2ž&„$c€àÀ}ïbBöà§^̃ö,˜I7½¿· ±XY`È Î7™#¦1[SèBšµï—®øßt>Ð ܵ‘Ïb¦¹˜fÑl›àŽÈ|ÈÍOþâç ~šñ“X0z¾èã¾IÅÐCÆwy,-‹jÄFôÅlîÐßËOed æ’pQáçiúuÄ/èB@†˜¸ œáLæKð¥·0¤eD‚ð‹²èÿ¬)¤ÌVZõ%ç™g;Ç2N¥LœÌÛPè"I†ab ¯rû¢ÑHMÌÙ‰ÌD´êÓÑæx¢&­t¢u“ñ¤œN¬*<ÚZ½5ÇFþâ"|í½²d<ðáÛÊ6-! Ó@v1Ö¨‡b–ç3[ZK"ñza c•ÉHC2^îDJÇ£"šp2Y’Ó<Û©œNî Ý+Ÿšª 6Õ”/ 6˜3¼Íä?ýù÷IižšÏI pê!²R©Ï>ÿü¦üßðÏôÄ\¨çgi~õúåüº"KËÚþ¤Ä¼wç…‰X#àu"VwjÑʯÚFß“‰†D¨z2Qy>l µ •íÝóXl¼îú­òïûu¬š'1ܵ¿d"±çöÝÚÕE¦*•=[XYúÝXxï|ÍÇ ïžJ´DGàÙÙ6“Ø?úIEÔÙvëI¦.D zð`‘Ú7i4>ˆ¶<ˆµ†îUM&8d¤þA|û¼ÙˆS ×'Ã5 =ÎXà¥Ö'‰ä‚ç—`mU¡rïvy2R·]ºT»eK¾Ž¼mT„’4 1ý[|àgRê>\Èü¼ÛâTpYX‹wPA€50À¹j_ /Þåج¯65/U|ŠñÒ/@ l>Z’?-ŒÅ¼þóh†BqÉš;VPF ¦"°ˆwÐpJôyg¿ÖéÂú%Š¥—ñãªs0ßC ¤5ÙúB ¼‚÷¢îJ7%(‡(c›0‹¸›@œÚ­þ-¦dj*U1&§|¼Ó,ëÀ=óm"/µÐSKð®áWJÙ¥fÕ9¤¥zô©¾¼Ùnw –ädàöµëÇjè™WP;ˆSV¡¦ç"ÃCÌÚµ.±Æ 1 cºÛæ}vpÁ {¬¿×Xk½Y>¤˜ŠF%´H× Íl¹%BAÏþºMÞem^)iHÙxÂ' úhâövPS™âOX+<ÌE}nØv,·ÿÔ¸wÈ?3Èx‡ÊƒŒÍáAØ4ܺ‘å+!Äf%L\QŒ¯¶A” ÐKÞOx'Ø&"Úeñ~XZ¾p¡^](Jè…ÀyxÄ„ÄÇ †h)¸ :Žâ@õt¯z¹,‘ "»©B™¤Ø™6“•5ù®Ý¥úÜ) 5JŸe¿^#™²'I^Íüa‘ƇA<à'0ÊÏfÚ *óf#B„0?ëO˜=ï}rQ6‘àYóø°«c§<ñ"1¬¦O#3"B0ÞÖ„TœSœ?˜ƒUÊÍ %zA'9D‡àN`2g‰øò å§~Æäç ¡Ã&RÄ7_zž0„Á/b~þµ£§}¦‚†P Ð;K—ŽD7„jÁ¦'ÖèD"£U‰PͤS¾_>5¹;<¶kïž5#¡šûcuÝÝQ²J˜ŒÅ¨È³›¼ee‹ ¼ºA ª¸ê«Š’În¸qrر '\1 8¡†qH*šD¸11V1•DGª?¨DKa¸W[üUË€¬„jnÛ÷î• 8ñ)øûïò¹–¾þçÌü¦ÌIÿ§¤2NÏÍÍLNÏ,[ö¨©cS3t”ûm¿ëÊ•À½û[â¡Ê©xèA"º-‘¬þªmÄkŠ…Ê'bU0îƒX[,Zõþõº-›—š­kY÷# ÑdàÚûëÖ*DÊSUÕ&JñÊeKqO»UíæÍ¦X¬<)›¯ùDGjýÓÉêÉXCènÓÌø^'ÚøÞåí«W/§4ÀfX 4=‰×†Ã[!³HFkb£MãÑfpªØXul¤n"VŸˆ”Ï›DêE–!l¤w>l[½’ê˜hš‰ÑËm%ß ´>ÿUÃL‡ôV£Äo›>•È~=ëwO³É#¹¼_Dîóé`‚P}–HN»Ô Y¦ ykñý¹³‡½ï”Êð¾òPÓ‡eE#âuOôàN]ÜÛN¢¥ƒ8ô·c‰(¶††wzÖL*ËW­Ã@ ïò•Ja/C÷˜2~D¬€qó¾çbʈš&1y'ð‘ÎÙÓgëˆfjZ.•€YaÞ®ÞÜCÁQü ùiöàIPl˜…>Þgñ>&ØkìÓKÑsÇÜ‚ãBŠV,À “²íúñ…*´Êæ½V{ÙÈDz¡™<°)—Íã°39¼‹ˆ0÷òvÊ›¢ýpQ¯,¼ÑâézÆÚ´­_%·üÜÿjýw–1lâ,Ÿß~ÑJå™{±æ¢ØFšX Ú“—9>àN¦¼+’uµÛ¥#¿Lü¹Jv‘—ü¥üvª™îÒK‘l¬ÛÈ–n2Têgçéè£ÝžŒ„è©£W„„lÀæw`!”vaD<¨‰ÞàöÚâ2˜<ÔnUX"œ@°2˜Øqð.ð^’9¥68mhŸXéV°Q&”˜ÖŠó¤­‹_ÁZH¢2õ‚ƒKÿ:øF`)Ç "Cˆ_$|X@Ÿ/ù‡Ê_Eü<´ß>æ[®+ÙÈ”<#ËÜúSã Åæk¿µÄCŒŸ)2ÎêݹKt¤)ÿf¿\`£8Î8nÉÒI'­´Z­V£]íjwO÷° ØI  mVU u·HDQ )Ø®}pµ}'×ØÆ i¨Zåeü>£TmªV* ¿¨KJ«*J[D›*‚Bì{í½|çw7ýÏ¥RÔVBr„Z1ÝÍíîÍ÷Í|³ßÿ÷9¾à!]znjtN ŒR`bŠÐ)‰¾Å³…*Î Å[wéç¸IÇ96ÕE~Ò1@òÔ›(zœš ór•ZÑT¿åVb_<îG¾J$¼@ˆË—·.D‰P+2["ѵÌG›þr­®zç&SádŽsûØùÆð-o"î{çrËZ—ÍÈZÓþî»ßZ‡¬¤©x˜H6Ñžˆ²i<˜0jIE|ñHhd!ÝšŒÿÛÕÖ eD8‘ ½bÃú‡3‹·(Íä—?|>wgpç3—»}OUô~[톰ò…ÂÊOì!¢LMæy—bŸž® GÛ³ÙæTÔ ‚ÍXTÜ4}Ú4’±Ž'"Þ¥T3*4}îVǾ'MSäy»Ó¡ñ1ëáyàtëõ¾í[ CåUYÒ¥5¹U4jvy‰À‚åÍÌ·­–?ËYo"ìÞjN†›3éÆph_lþDõ£Dœ{Yâ § ^{{ì°‚ŠÕŒφæ¼À+r0;š£48š¶VÖÂT @r4ñFç듉Î×G¿íKUÅ.s²Ê´›'*Òµ@ˆCES,=þM!ÛãdY½Gd`€ÜÞ/1E,Ê>"AV–²bƒÁbŒzòƒåW[ ¤T4œZ©ªº C.»à2J':tVðùA1÷šgÌ ÈEËÃî/Up ÑEM-3øåEpB›†@'ì( I;ë…6‰9XïSºv“ UP‰HåﵩôU óá å†lƒœªPÛÒP3Cä'5ü¤Ï¸öR%¬bŠ ýêwÑQ)5d‡ÅbÌìJì'ø ê†t!Ä`"Ø/ß{üøDÇ.õcç…•!éJN5Od•3ô‰fIyP»ô,õ“<‡UôD7RNûM†”}`¬0lfƒë² @D¶Gøƒ¿üZ¥s·ÝðÐQé7]ކ :ì2ÿË&Ì Ò~Žž“§"}•¬ ˜ù}ùyñØ5SäÜê6¢ºLr¶¾xN‚Bï~—$¨€:K»¿"¾÷}y²Ùõ ' *1v­åR¯b O`¡IBLGÁ'Øê"rœBt4¨³0=N™l]ý<} \j®`í§ ¯¡Ê"–M°Šêy` œÉ É×Ú¤C[SÄ«§”+ÄÄaâ]kx§ËÁËL8Òco•R©N Þn*‚á­ÛKˆ†[¬Híâ‚?i‰ÞlJGZm‘¹Ã‰xmH¿yÅS»ƒ{f›|§å§òT§ìPDS2xQþÎVlk!ȯÓDh=QS•¿žúL¾ÀD´ÇU¥«@t^2f:L é }Ø|×ï•E7/ ¸YŒÀ‡#®•`9³Ë`Ö%vê“E8ÉØÃA{HÑg¾È–å…^“­¸‚³Š“Œ'Y@Å?vh{7ÉNœ²!k‚È ál²ìÞ®+ô× ½È3ü8ÏÓóE9\3\WF. ômN*t &põ?«¶»¹‡ˆM'k¼2¢¶Q´Ñ7uú¡Ó}K¢“:ˆ"9A¦´3žÚ%o¸4uÏæ’¥q“y{I¡ÓN:ÅÑYC‹úÙ·Þ<©æ§yfFïÖÏiÂÜÇ„’‹2À‰Îðᱟþ¼à•†$”ëéýÑ+ŽTÖ˜Š¬Û­c)>sQZQÿìDÓzÍ)mÐ$UW}¼ÿÈ#ñ¸?~½u%å·âÞÝÕ2§€¯žëz,dùÓÉ:+\”•¶|ÉXC"Ú8‰Íûbsäùx×['°•I´„æžI%;Î÷Êv›K5‰È¢ÑÝÈ//?>&\îv¡Pø¯¢v¿ý´ÄÅ7~ös™H†®j’® ¤¡öaËjM&&#t´;›j‹Î×eãmÖÜ?Ù/óØ(®3€[²di¤‘FOO£§7šÑÚd‰¹œˆBi’†ª‘8ÒÖM)ŠDÌi°o}aÙ`Â’Ð(|¬íõÕµ**mRl0ØÔ4©”V¨¤©C)`ïÎÎìeã×ï­Û*­”?L)£§ÕÌhwö}ß{óý~_]Êž3ª~鈗&íF° @­ãŸ ^ê5)¹ò‡R×Þv'Q;eïO—ÇÆ_qbÁTâ`kdz‡<ßwbÝ›ÕédÃD¼Î¹Y9iï«ùÄÇꓱJ<$¶Ü©8Á›·êœèÏÿL¤>ûË¿‘í¡‘²^Xå¹xi뾦µK r†v%£Á»‰†4xˆSnGkæÌFìú…ƒðþB—aÛÛRñÆá­–lB%V)†Âbªâ•,Ìùè k†jï½ßfr‚CýC%·xý‡Ñ"g(QÀ‡åp‡šß–!#¼ÏÚ:é{›ÌE2ñ`Ø&žo¬"Ë ŒsüØÿ-6‡Z³Äz)– >%ž9BüØ DD”¾T€ÓšnÀ¢ÎÚ´ï,dŒU*û)Ž/Êcayâ¨4‘ˆG—ÕÏŠÀÙén° ° sd·wômpŒëQX³Â!žÇz}ü„Ü0±Äí¢ý=¸ß‘íÿ³¡ÁIXçIà4T2ÞõßÖþŒÖ ç÷}T3¿ãù^ÉN̲³‰…1—«ò¢€Ðà>døÎyMY«ÅÄOHÎ cú¸Èº½ °ÆSíÖõ£‹+½<½Çëòeòã½þ¶/_Î"Ä¢¸`m‘Ð_A>=l, KÐS\¤±6åÊë뢉è| +‹¼8ku@“ž:llZ) T"„´ \2ÁÃÞÑÃf‘š³2/+´Q˜nŸÏº®»\1W¦.OæÜäs;.³ð"ß©Ô´ŽŽ5Xü#âû"âÊêãÊ–Y äGãÛ5ŒXö“JïRŸ`©ØD²¢«‚WÍU„ÐN‘ Zì¼Ä†ë—X?\áÚÀ¹üð4ÿ²1ϧ\r.Λ9‡Ø‘ÁlX´ûq_•¼f™ªH¦¢æѬ¿¶’™óRï²Ü“eIæòy¸y—8u f‚ØrÉZˆc|t—ÌF·š3·‘3"8é&MԜܱ(<‡çYO” „äå'1Ô ,X¿ ^ÔCƒn”§®3TìºUN¬Â+ŸJî‚*’vÞénÞdÉ¢O~ŒJÂãyäð[kLŠ }꟮íHA׿”^½ºoA®hb,Go÷jÛÙîÚ›'uî8t²Õnl;ØH¦Å«ƒB ½-|Æ#pYŸŽÕEo”ÝŸ¬‡n\¨æµeà¼*–@H4lþì§'fY5+$`#³—÷îMý‡ÀùÕñŽ/ÚÈÌÌXÖ+Ÿü>P¯J0ÁBöºu;ú¦ëîLÆJ'Üj@lØ! ;xvÎxÅ£¶‘TbG"ZoߪH&ª’‰FUÉ»vÍ ÷VùTª16¶)møä·?:»ù̇%—?ÞB’pö‚]ƒxÇ£ðÛŠé©Ч¹šëTÆÓ[/ÿnsñº–,4î^1z}{Ò.s#AÇ©>}z³ŠK….hiéï|57>^«JD*“ɲ˜]?gv4œŒWMÄ«’vm,Z ͯM¥%Oƒ„(¦­lwõãé>À‡ƒ¦ $¥µÏ`ð U¡>I>õX< Ä€üx‹BÕ’e ¡“;@<œž=tCžðœ•½!Wh}Ù`!/;aÞ¶15ÖcpR‡$PîÑX‹Áº)'2XSØ‚éñ ·BD^Z翎Yõjó²f‹•…Œ |3öÕù?h#>Ö!óåëhǾa4+“ù„a½ ]­N(³F fíkÁô@ö.m†ãž°0 …µFvœ°÷•Ø}*Ï×0ïƒwýÜ6á'½:xé|¿C=ör®—JŠäñɹóD5 cM’5*z):òô‹ ÐK¢Jû šeb`E'’åekŠû¿ïû9ÜŽBž-ÚáõHTUQ iÎùúå7šŸî“]XXDØx- !°å<|ÛåévóÔvú”™%ŠtK@ˆ‚t!Ö’Q‘ŽÌVìR¸‡ðèhÆl ¾u!аÜ]¬.ÔÁ… EEA݈©+èëóóG ÷tÖ¹ ÊlH矿Æsf#ç,6$ò“ð̆¿ü@d,6€§ýäÞJÿŠ À…‚<)ªŠLC¤HxÒ/Ü­³a:Ò¦EÕün¹2ì¥agevQz‡,)dò¾DÎú¬SbÒ‡žçæÏÌ$üœdPgç(ëÇlDv†m\é÷ÐU•d$™Dîëúv4R71QÅD"2^ÞÿË’<-‡`dªÂâ€08òâÈÅZþ‹êŠ'ÔC¯?ðÐ ¹2ˆ×ÀþE~4úÇú´SÕ#öÖØè¾Ûñ&'Ò„Z êâFËRN¯Ûv-4ni§ên²Î róIÝxSñKóuÁ¢È×/_¾<Ë,–q’/‚ì«ãÿñ˜áǃ^‚ŠÜ¹sçkKžÆ`„LÅ¿è1|õjc"´£±ºDd[ÒÙVÞNìIº•Îø–I÷‘ÛH:Y¶|;]cGª¢ã&ÔCäÉÍ"×*ì›;‰š±XÅ›‡¾©Jª)g¿÷î÷R±Ê¤½5eó §ìàd¢úÖÍÒ„Û4WóqbÁÏGBi–ò ¢iD0±°ú©ÀÝHÓ¤[>>Væ&ßhÜ÷4!‚F=[ª‚ŸþæüÞx¤ôv¼Ê+@æ,EXŽj7R/r Ê…[KãF6^«÷›‚LˆLh€ÐÎWI;¦sëèäœbí:kÖ8‹s!‹n†2µ½'Ól¶RN1`t;€ª½Â ÒÔë2ËŸËûpîDΔ’Ÿ—竈`• ª±¦PùûåÅqð“,di¥Õh´íhWûÐÞ ÆÊ£” -„–W’HˆK8¨_‡'÷”@ZªV4PlŸïa;6%m¨”ˆ1ÄMK#µM“6U$§(¡ñïöÖ‡í€]Ÿ§ßì©ýƒJ #5RVŸÖ³{ÞÙï›ÙÝßo&O 2âµ° ¼+ù]þÔªaKå0±^·FàX¤vÓkÇt¢™:’}´´áË`J\n$ÐGÇ8'Õɘ5Ñãç,nY¬‚%¬Ëàòp P&S?dxÚ粉ºÌUYG+” ¨-F¬Eñ ÖP8 €pw,öÿg#1™ X F@ãuAu@á¸É+‹º ÝhÆ$“ŸÖN™÷Ðëz&\ªcÛ>&âÿè¡·œ,\Ø£q‰é7;°+Ÿ:Ÿ8yý] ,€1z50 Q s·ÏC¹SëU[§dD±HIúdÕÙ§Hí-…*KȇdýÏ0û0æêͨ¶DC0ʰ¢[â7–ÉS* e~õ¥×Fâëõñ¡äDyïn¹’zDåò¦õ(³3Òƒ¦»DždÌš§{ñ)†©„o‡ÂM˜ÜɨzÈ2‰— öÊpgY™ƒKB›JNÁ X?hfç%NùÙ²‘ó„—Ù[ˆõ‰ì¢V8få4DÖ'³ß@C`o™¬<^)™ð‚1e‰—«ªWð:nøºð‡g‘Ÿˆ‚ä¸ LÉÏ^{s ï'Œ P”¢ùEmÏc%¹¹Ü¬î8O‘ IŸÆ.C˜]0X?.€8Aœ‰òÛo®Ø°Jó †¬(–D{º¶ ‡rÙæl¦Vd©tdÍ(ÑW¯¬ê{£Ñ·³ùº-_+3ðýK*_Íxùa¯RÏ+/oIº‘mrRG5•5|[ºÚ6žê–H6”ÏÕÛ`&c+Aø†çÓÍã¹jÉf[>ø°yYµJ…€¡`£åË—;Žóß8+°Ï·Ïæ6ý/>ŒMºŒÏä4ûÖÎíD– ]„ǯŒ’ßõ5Žæ÷e‡jÆs‘{m#¹ÖL&hÛµðì;‘Üð¾ë<œ;טŠŒÙm#ÃOŒçÚ6¬–TQ¥¨bÓWµÁ«‘´S70\gGžûÑNx!t(°ªuE–EÁ=‹œ1îf£éƒðmzÀĨº ‡ëð‡;0îÌ GGêG²õ ÿ£öìÙÈmÂÚy*º#/%H sæ«Zê®_`vH¬§šuT`—ÑÖS2ÿþ=Ÿ"ë*p /ظT{‰î(‘ -ǪHKjÖkª°W‘)²þÚjºÎC7–cK ]×Qiú¸É’À|3yßC]ÄûTqÛBñW }ÖhÞ­pdÇè ‘¿œ¹ dÄ Ù•Å=o°.‹“½÷.Wº`Ï5LsYéjLQ~¢nÀBÏ€xP‚NÂÛI÷ò¨Ûmì?‚{‘Ü.ˆ{‰ÀPè™›!fI©økܽu—늀ò¸kY<[ÐH™KTÌý‰”Ì ˜†Ë!¢~µ¸gÍ*áf{ãÖEg²MêÓ÷ŸÖ{ó†WzŽ~¿º_ø2é@PòÇÇ«–H$ƒ ·Ûüü¦§¥|T%¨Ö>P®’Mò°„uJPÚÓø5Šd¥„J2%>U^É4z¶ÖàóÂ=Säwï#½ŘЅT<¶ÕàSu§¯XrqîbôöÎa¼6v-õTäh”$fE6ç[¥Ñz@0s(`Ö/±~Â.`î5vQeo¸Ú0[–rÉí¹î Â™›ýå¨Ô«Si/µ(àE£Ï+µë,B¼*%^cTUqÃR¸DYŸî”êôiå˜*"A¦‰É3ß´ 4.9oÞ¹Ü6d>—àvâ‰ùkýAà È/*Aý¿oI7OÚ{òvMÌ!nØ7ÿƒ¡ ¬RsN¶íê`ÛºÕ¥¦$©šWÅÔ’Ì•äâë»Fœ“k mtø‰Fæ5X˜Ù nã A9rN}Îìؑ\6œ³C 'ùL˜ŸL7_ÏÖÚÁ?ìõÉЭö+‰rpOpbbÀ5Y(LMs~ñø|û,nÓ\& °ø3'Nú‰a²†`Q3d”ht${„ãÕï¿×ô´ÓA.!©ðÄx$›Ú7æ„3Ÿ4Žæš³Y°ñÖë™VþÄ5ya[¥¯ ŠFt"•®Y9Ï”aÝC+4%|`ɵԬ哵wÃþz6âÀ»`7]wÙ©g¯ <õà*´v•®RïîšûÏÛÚ¿BÅ`%ªAJD´3-Ãÿ|bb´ÙjËŸøh¨6óñá‰üœtK.]~e§` Ðd§šîõxŽÚŸ\;´b |ÜŒU¿Œ¯•gà èLÒàqÀLâæÓ**ÚË7T{¾£WoêÇþ\WåÑõ¥¥!,’±)úeâ15ùÝ0¸Êœ©í|›X)‘ LЉ­‹ØóK*S§ñ¯ž”~¹½sÜŠ.d?£¬ý®z›öSƒ—™påbFlîJH .Qn?ð´ôX=£ÉÊñxE¡;àýËãÑyÏlõéXx•.¿¼ %´w¾K±£d¬«Êþ¾ñZ+Œ3hžŽU®›#Äô H!•Û—HÏmöüp½ð%ói'%DÑ4$œ¬drh1¨D‘n tæ;˜½¨sãê…*èt‡[oÒà&þ‡M©ót‡âNGõ™'É*ËöcaCÆX†¯œ l^Nß;‰¹rôPv°Ž\mp÷—$.'³EùP—î$}b¡_®ß„ A~ÙóêÁ@Ñ7ØeôB‹…EÅ Š$y}2ºú"eçAȧgÕ‡K:‚7ΧIô‘Å¥ö¯A¥ÀpD7ÿÙ²Âõ †âbWæý¥géʹ^òoöË4ŠìàB 0°0 á1à 3³ì&1IÏžõªÆÚúqÇÙRôl˜/™`ÎŽŽÞ=0<øB÷žoï ¯JnÔÓËè²íЕ‘­ßYÓ(#A²„…c±-ãf´ƒsn[ÁÛÀhY+Û>ì–pvs²Í¦Ù•w"¹3Þ>á*)¸#U@XÀüÑ_¼>C¦ga„Ü›œzl#_Ð TdVHà ìòý—pVÄË¢&qJûÎ&Ç çíÀd.jºÐôœÌ³c‘‚Ñ[²ƒ°>íqX“aÀ·®wœ@Éî*Œ÷äônËêÞ÷ÊrŸT §&UÕD,ʼ$#n×Îo¥Z¥–ùÊǰ£wÇwO”zl=èd[sù`*±ÉË3 /a·î›‹? '^2>í!9=î±ì¯†7çs!Kßèz³SÞZvöÚ:ø°œ çÁ¬ô@9ÒºŸà?ÓNï¹ßmǘ…Í‹çøº}ØKN`ÒÛ¸@¡ƒpÕ\RkNy ¸Ó»Èñ²$ÕsÜM9©ÞOÊ›¿ z¨Ô°5"s¤*Ì¢[}¤‘·¤ô/½ËD˜j>‰%$ÜÌ“nžT}B¡&Ý_ Ü·¤4žNkw˧QKŽÍªTÿúzMó2FÂŒ‡—9¬Ê‚¤ðáEÇ_fI’#Ið½Åps®c‰­V%­žÃÛ×J“COS¨’3Çê¯Ýx²º]I¨»Ÿd1ž†ŒÎ`¹j´dx´šæ ¸“(Óu›âþW }®ãA7úXr²vìȪמƒÜ˜'‚x,ùxNòóøð‹þÊ9•¼ëòâ:¢æpÙU‘«Â¼QÜæO.b2Â’+,uîIõ)…]¥FeÞ~M™8'·mÒà0¨"ÅÇ£}ÛUhb¢ý{nÃ*AÀ\‡°êï}M2ÏcrE ×<Ô .áyËsÖÄnJÔI®z&ßeÿ~fý /ƒMÆ0}’¿¾æòõÝ¥tW¥Ølè]9;l» V‡£w”PftÇÔ½h&°Òûõñ co·ÝÜyæÌ–MÑDQå5/fe„%Îóõ'峿î°õpÑnËp å@ErŽÑù¯B/  ä´›™HÞê´3ív&XÈv›FtÏOW ,=‹ÊXÜÍ›# $„ÂŒ<¶‘/ìõ`ú*$—5–4.žÊ¼W`ùï>£Þíݵ¶‚ Æ ‹-²Ðô„ÙéŽ|&X²ÃÆh+ÈI1ÔGÛòN4«·Àjt2‘ '’µ›³öÞw~Ûöƒ­M®’yfÛWþÍVà CoŸ¯|Æôîb)¤ßm)›û‹fäðÇ:—Öp2ïWacØ»GóÖ'ìèx:´þi™Š’žôKWßÛ‘·;Kö+ð_f›=¶ÙáB6”3C 6ÔŒNhé‚÷SÒ!ÛiÞ¶yœGl&‚ð£•̰xÐGâ9Ø:+XNÿà€»÷-$Š^$,W™™>JçÒ‘†&?öª Œ~VüXÞ.’7Q!î!©/í=WWujþÇÑZ—°ˆ’e°Ž¤jH¿@ú¥ê‰G·£ÏЏ—Ä´ Ră-a\¶ªÝ FÉIÁ¥§F>ឪ е„«!ñZšç€ É©ÐÇ5꾸äê€ËYI˜Sɵ7†ýÓƒÚtÊÀ:ä:L WbȰDÍ9J€Â©$¥þGlfÍd6’®Æ@C 5«¸P‰C òƒ4ú8-Á’Ô£Ûè™&rÇc¢+rþ9y ’i½!¶¬V}ˆñIOy–SVnhÒø[GϹî·a1BˆkTÑWy:×`¡1DÞ[B+: 6+zFòaÄ šF ½ÓìvlH¤N¢ƒLS  ai»½Ÿ™?¬¢&qD_1(ÓÁ2Kh’761bõ€DÐt?ZÔTËü¥OšºØ@®pä=¹Ì‘ ¹¤Ð›ù¢ü%D.‚á`r Qç¹ ÁM_ãÏw+_©W^êg¤Tåã—g± U_Z-‘÷1¤1sÿdõ"NA^ÄqH]S¯~rÎu†kÜ uŸ?kºŠÉ¹â$Òû«žû×ëîœ^ãŲ„«òx²bù’Oïìºg…sFwÞŒæH9-Á—¡Nr’ÏwN—`+~±l÷èéЯ®S)\ Ë+¿,>°qOë®–<>‰«¹ÈétÛ/f#Ål¨˜¥gO;ÝS0öÌhÖ Ãv t¸_ÜgŽ·ZvóíÛ¡çÖûeŽ9T«ÖÖøk-˘‘Êý™ÿ7U_ŸçŸœœœ¬¸6²åû/HT*²ò²zχÞ£›-SXZÅlT¬u¡éY´“¹PÁÜm¥[ï{­tôã;Ra¯­wå³@óö’ (ï´2m–Èç£+bØ]V6`­S 0-e;pÏ|rNІò­Î »-?¾ÞnûÞ~kƒ;%Çh¸±uÛ7œÑhÙ–óݻӲnm£Ìó Ë$cÏÚVØÎD f¸hî/8ŽÙžÍÌñt²äDÀF@´¼Ÿc g‘b®ùŸ¶Â•$AäüŸÝ ¬îst†]šÒPþ<6€è—{6iœ cŒ$A½ÜŒÈ1þ£ŸË+•êj³ŠÊ`9ù¼ŸúˆGR›8ZW²)à`«¦“!Äx ¸a 0¢*Ò‡çÍF 40.@*0qP™pvÐý|X@*nàÛ˜@#ù€b1Ñè«ýè|«WþSÔw¾Y<õoöË=6ŠãŽã–N²´Òj4f5«Ý=ÝùŒ]°°x:@¢@Û$%*’È-^!Á`lùâÇű1IåRˆRÊÃÆœÏö¡i…¢Ò–ð°y¸´Q›>©"E ãÇù{w~ÛÓ߬I•øƒÈ¨ª”ÕW«»½½ßüfö÷ýüÖáp! ­aU³w=gm]B¶,Â[ Èæ§È¦ Z;O—šÏAëLImX €¶¨¥Oãš´ÆÕYïæ\;ëÃW•ÎÆŸk¬Ök={Ùýq.N:– y6h›2eà&ÕL…%AÁ NÁ„ x pò]œY‡ô/­ù1ó&€Éœ5œ™RÅÔù%šDE?é¹×è ¯Åo.Õ¶-2Và¿ÕsÉ*­ø‹6rãFÌÁºÿE&wð'ÀÎq&Ÿ|Ø‘_ÿB03p‚ÓßlÏr†$#N½r¦@˜i‡{âÑûö>P¨ÜÞDŽÉª„‘8n>hæ¡­¹³x–›Ðl+LÖ°,¬Ô¯w%~ÍÅU*Ϋ¢[Uq^Ÿ6—¿„Å&äª.ùá¼C&—q%N¢p%~åÛyy&Ö0ö`MUW øKuü^+Zè^ѹÀ‡>wÀ x¦ B)®2‰7Óçeà%">†éSqƉ¬Ÿzo®)\':óYŒ/Zÿì´‡•éxõH¢Öî­ºo×Ùý•Ÿ§ê† „®p t,ùÎíªâÆÐäZlæ3ËÌÛwêÊz«N„WZ.âï-#P‡âÅ©HI:^,ú<]oG ZVŠ@7¸ëó§ãþX´,5¼çÓOKò=Ø¢”*Œaó‡…ëÀÆÆÇÇ$ùæøÿ;LŽO8‹wðý& » ¥–¦þòÄËétØe¬¯<-Ž×Ú‘z;QñÄÝ3^š”»ÑŸˆõ÷ÔVíœ_¶#w R—ŠVÚ»"Ý”ÞOÕ§ã•ÑÁ‰ÿp¼~$þãd ©OW –§z§Íåᵂx’‘ xीwA^Oìj>ø#KStŒ¹¢¶ìß¼”ÞÞÝ]ºl‘ÒzìyÛ®éëñ§mÿhºÂî/MDË€j fxIáÍMFrÊ“TO8Ÿ©Ê{ƒþD_™Høö¼ˆ9§2æ¹þ} Ça‰,YŸ¡\ƒsµoôàA¦8Äþ±7ßMn[¯ÎsIÓ̺ÿ¾[Ïá*ÒÔ\êúhƒKÍa"Ýó8&—÷´“à•’÷oqÎà›–ä„é¢pmP›ãJAÇÈ‚Sbr\(% ©ðŽâ±}äÕÆïvj­Õ†Uèõåäùy4σuªZ\eÈEP¦Æ¥cL(cœ{s…"l ¢c 2¤˜ÉW„ÿ+F5J€ÝäKŸºH…U„LF-ƒšÊg:‹ ¹-ÑYaÚ¶œíùÞ¶Yï*7o5˜ÃÜ¢Å+s%ƒ×%ÈÁ¤Nè5XÙ×W”LùSñÆ›×Kž[ü-®x,FuäÓðŒ»^ï¾66V<šÜÑ{Ï¿tQì /Soþ¥$+vê­?eïH&Ëb‘@4ê$6 Û¥àDCñZ¨Ÿ²•‹Õö÷–%“¥ª2H†[Óu 7Ä÷ïß/ÄøäÄøÿÚW¿9¾Î1‹'\»ÖɯWÇÐßf¼øNÒ®{M Fâ5‰¾’áD |=y÷„mœ ô÷§Ò•?Û·\W\^>ãúõwSƒþh¯}()Á`°·b,]—Š•ŒÚñ¾7î'ËìH™=Pë Ø‘êûCéŠ'Ò³«ïΞÝo?³r…gõKy7Ÿ½{§!‘(M î)Ù¾Pç.F‰‡¢Z·$ãõý%i»üî¿©¤ß¶Kõdžýýw·Ž$ªRÑ)©IÅüC‰*`{ð‰Ó]"R4­±kS=ý÷üsò©Î ”¨ ‡×äÊú ¥¾Ê5sjþcº¸!œÃšÐõs\qŒhŽŽ>k´D»[¶´Azº½õ]ýO ù£-¦[âˆ*Žuzå¯0bÐœÇ ÒìBÎEð5ø¬-ø5èè‚ †œ N±pL<¨ßjô^«1ŽoF»W¨› вlš­qMå&‘À-רÍŧüTŠj š2"Å.€% Ê9Ñ4 íÕtb‚8é_ÀÌ”¸†AðQmeò¬Å ªŽ2-¬@‡Ä2lèÄÐ1´ DGØÄÈ"øûyxÓÚøŠçÔÆ_æðÏ-¹"ít(4ûA{Žèp‹vXSâ‰-›·à—Ì <tžþ<Ðl9ÉåbÁcÛ°k¢¼I6€½Ô–-Ú³ò$$ÿ(K¾7k!ɰ0BˆlŸ!ŽaIòN¯hš%¼ç/_I¢çSô‹í0„.ÂX4©"ä ú`"7¸Oï`GÖàS¯™7~â›ìðÊq£GOÊ á¶ãYòi!™„‰ÃDòÉî°…µ³»ÌŦêAf¶æ!”+˜ùÚ·ž'O[â ™_ž6—WQÄE,º˜¸¬Š+º¸@%T\v®t¡ÎÝl¡;3OW®2Å$:Ùoß59#:É™c ÏøðmSÒ%ü:Oø礦 Ó'ÄÓeÈxº‘¤ ².'ÈKè‹kîýÅî™éšK#ÖØ/÷Ø(Ž3€[B²tÒI«Õh5šÕ®v÷tgû Ø<œPL^¤ ¶Ó„P‚hš¶clN¾«¯~\O‡14héü6ª&êS)Â1Ï@ÒW(i+„’ª à{ìónÏŒé7KET"rÊ?ŒG§½Ý»¹Ï3ß|¿ßÈ¢oSÓ"=ÍŽ®…6+Ýng:  º‰ôÕ䯷°#â Â^B3FG×;Öv8"Ý0Á:’sk%I!'ž:ƒ3Ú5'åZñ¼ÓþÁÅÔþŸ<ÿÞ_SÖµØÇù8x:9P‘ÎôxJ+«Ÿf‹mìêŒÏ#|$AØ‚ï¼sŽÒ[÷›«Úgi7§¨U0«ª¡Þ²Š§‰ÂÒ/úÇ3?v¬f'“*[ ¹ö¢Ül)8°ôÉÏ›žNf‡‘ëpÝØÕñd¤ñ‰P!#¾yS}A1N¸fÊÎvع؄ÝîdÚ'Œ”™Ž|ì$ë`J–Ýf»9+~Ôzšâ9ÿǦÚ`™Dv4™ÔÎøFßøz>5œ®Å‹çp$ÌÍ ð~{½•í²Óq׈¹™Wœ\wÁ‰˜iðÿŽ }«•à“ ¬ ¶­î”kÉÿ¼ç3gµ­˜elsôØõ\bpd5Â\­ ù¤Àr¹ÌÚ]E9ÏFT[÷n#CA”Ã~Ú/ü>Rä«eŒ€Â{Wi¯HqDÚ¢}xr¨’@žht¾Åy\@p@Ó7á©P:—óìc€<àÔtÙÈè–lîÑÞî ö½¤m^*-…¢O求ˆ ADh˜AÄÐo+‡„E Ã…À:Fl ÂlÃsx¤¢` Þö¢aÁs:ÜT1þä[ä?”ƒÇL98øQèLþÁ.$±.ƒl@’I"{rCDFAX…ƒ.c^ö„‘%xÀb¼™0}Ryûækü²úŠ}+}¿ZÞO)¥½æ]ÌÄðg±MÆk‘-ñ ñÄU¥ƒ°v¡[C!:Â)0é—¼ÁÚ7“¿/À¬r³%fÊb7@†Tþ<Z8 J 9› ÑutÇ1QD—ûÈ7ø‚¼àÕ:M~w‡Lƒ-pžð„ØëPx÷ê2 ‡éUT×ñåûžSݾZzÝ5þ‰YÓfò3„XTl(•åÓ3…Th/‰teoMôK3^Ð0’…rÐGó¯˜ïÿÃ4†ãé¢üiž¾Iè[`#@yBOÁÈ<=®ÒãzÒãþIáæÿ¥ay,á§`A'„×»Q%Â!H ¡\ãǶiÌ[N€-ˆë%¯EùÞoÉCQé=XˆÓhÚâ„ðŽ£ÒLÏ f>ð‹ Oð1˜oUE#FšŒXòþáö'­l·­·€H@·¬–LºkàÕ8û <ã –¸½/¬Z5;(¦–æôè «óúÕž_Œ¬W‡‚$“¶‘ÊëPá;m«müJbå—I‰óþ¿œoµÓm®‘€ƒª>+äÛ#õ³ wév£¡ïZþ†—Øž#••!×uï3V´ÿÙJ”NݺUúÔöî³È¦-~ΧªªÈ 5÷þß7Ͷi¢³ô¨•k-Ø Äf¦µ`¶çx>—ÌëV‡“Näs,» NÊ4ã™l2ïFõ+)Ðì>ˆÏ,öþþqqƒžíÎ[my=V0bù\—m5‚!ßk<.Ä“‚èÙv+—˜°·À€yk““»f»“‹Œ(è ˜˜™NŒÔX£¡fÔgêæÎò <à¦0tñ\s>÷âø‡±GˆˆS Â¶6Ísi³ éê py3êäb®‘‚ý›ÉD_\‹ŽÌ„* n^ÂÓ‘Ä` ô ÀÊþ½Ò ŠüpƒÎ!ô¯¾ÚºÀ á*Á7ÐPÆ0q8ÄJ=  XvPb,¸ëPïúңà áWWÌÙÕðð†…¯=X6/XMüÁÊmÁH"ø Áúx`w@`]E X “(ObˆS‚O©„<ÌmZ }Ÿû^›@˜Ì~‘Í!,¬xŸ7¥ý˜þLa™0àY{ªÑ^•=í‡é•èÂhÊÊÊ´Ca  dg7EÚKîž' B2{ÝÍí~xe&0äiLŸzmŸöüì20+ÐÀz¥ìÒö0í#ôŒ&ÐÞ*zÃáï®RD?h£_”à ÈG*|àv;—«t@cV‘ÀD¹1Xs“ ^Á| dÆ ÌŸúïîçoòSÁr ?ÆåÌ:ÑüJÄ÷|»’žàèI‘Ž!v1Æ{ ÁÑQDÇ0}Óc©O`ñS8>]Vpr]ï Š’†|³dßž£Æ¿ö_Ç8-Ì…E,'åa¬n|\¸8PIÏò¥=%ÐßbzV—˜U¦ÍRN!:Jè˜ê\US¨lwì 4}ðÀªL6qÍÞagÚÍ\£­÷ìyy1ì5þE³¤Óck‹…d2¾$(ù K×=عuÕÓÏÔ…câ'Ø¿5ñUÓH\Ï|ž¦¹ôáÈç€0SCâÑckîVß †»nüŸ" *Èy•mgüÌÊ5ÀµRiÊÃ@Ž^ŸœöÝ,•îÄÆíÿÝ&KSŸ¬Äíšœ¼KÖß7€á,H Ÿ8Uôýòµ5öøî‚Þ:ÍL´º½ÝÎÅ'œt=ƒ,*ÖyZ’(6Oâ¦Ùj1ÓmÖ3]v¼hG²ã-¯¼\Oü‚,TG6VF§mtƒN¸F² w¸˜Iò^#±³­ î,Œ–»ÒU0’€ì 3iŽÇŠVGÑêÊ\n.8KßòÓOˆ8§ÿóòδÙÒýd¥–x_KdN>›²ÒE»óôéæùµ¾XlI:*Z±û®ÿ½[³qÇhu²mEs Dkÿ›ýzâ¸ãn ÉÒI+­V£ÕhW»Ú‡î8ÛLí3ÇÙ†³± *I+¥¡"h]Ì#ØŽml°}½ÞÃw&¥ô¡V…úöÙI›HIþIÚ µM mÔF¥„D.J”‚Ͼ÷Áðô7k”ª•.•¥æœ~Z¯íÝÙÝÙ¹ù~&Ý:öN£E„ Á¬óœ™Éù“w-MÈqjù‘5B'&Q?·Ô£ö>›;t0ïF—Rdx1ùcU. ÝÉÚŽld“q$¬g42¸š„¬óÈ -Ðå-O3†4Yn|™aJ.âz­uj5üóNn“™1cVB¬À1¼Â±ËbI0cé˜SUN± MG²+2Ï‹<£àÜb5÷[6±¦Bx ¿±K»r ð“£Ž»î*â«"ž â­˜óU?>N‚ÕÄ_I|À Cî¢%O9ñ;IÐIÿèÝH½4È‘M#;ñ9@#$° ³äs>ðU.ù«IÀFÜ눯„ËèaJòâÖEó¾»mWX–•$¶HQ+*Ãó&N¾aÉy¾tcfò&"cË^âÈØŠÝe ’­&—äðïå][ó1iÀ^FÌ_ßu§"µs‰¶{É“ÉxG4ÖôÜsöÛ¤Œ7ÍeN¦"î>ØWdeé s ¬ˆ2æ «Û«äñ\3™Æh¤±û—•͇+Ò3§ª\îŽ-Òí©¬ój<Ö<5 +ÜŸ¼ö›Vi± £ªJoßça·¸¸;Œúêóeø,¿ˆû÷ }AÆoKäúµkª,Â÷N•dXpø¼ŽHâxbÒ5“8¾Ri8w%#méhG&֑޶'¦Z¡î¤\±tó…·jR‰`:Ù#0üÏïϦ Í[¯¾WóÖ뵱ɦD¸énÊ“Œø«šÌ♽v­qr¢ÎMNº2ÑÖé¸|dD[f3®èDÓlÊ @‚€†m<Ú>“¨ƒÈ¦s'bíñÌwSIÏåøÊœúYåD¶g¾²Jdr;ŽVÃàòhÛûWMÝjð·Ä§RIw*¶ÿÿÎÿªtªm:Õ:—qÇ'àI›c±çcÑ5)5a5g¬?cãfÎæÓÉÿŒJ†²k![AÁä§ws^z,¤Öž J‘DBÆ`²¾ìítk”+ØXÏb‹sÝÒ#Óø Ë[ž‚¤-Aû޽£ÀäŒò7åôÖ†<¬§RX9‰nH„!Ã`¢Â°æåÖnÕ¿cS‹5X£›D‘•À!X–yUäÁ`*t]#pš€4QT1oÓL‡ªØsô[]ü\·™¼l¥€Ž¥]H7”á=`Æ0ØC0Þ‹h(‚7¨)Q0ôê¡6 ~ ë]– 粻ˋʭB’]Soz%« ã°†ÁLH{¶L¹šÐ’‡ëés–…sâÛµ–ÇÌkX„ õU,4¹àض\Òg£W§#$„èEáö`¿Ï¸¸îÈ$û8ì3N¶þ®Avê¬ aè<)f^.ÕøÁ6Ž\ÉE ‡NsùŽ‚Bÿ2C·#àLþÀ‘Q´RéŸ:o޳ŔÇxw óc2¹ÀàzŒ$¬Â ee ÿtíå3ÜéY}¥Y˜}ƒ!£"½·K ¹¼š’i¥42 O­‹< '|¹ 7£JH0iv ÷—ÑšÙX}êV ¬ƒ2³GÆ?>õYø`2Ñ’Ž6%&ëîÍv^x{¯ãk’_Lž¥‹ñ ‡Š?o¾›öܾÙü½}• L C½»bSîLúøôtk4|"ë|žªOE\°ŒÍdÜ®V‡Èrª¤ Ž‘ñÆõë óËñ ÔûJ#_ª@ÑøAççãÑØS;žxN¢ŒÄíUê§·'& ^f“î•JÃT„‚ƒ 1›qÏ$Ûƒ½5:ŸÛÚ°m"Üž™i¿3 q…oü¢t½Uå$G¾Å×ºí½±ºH¼ý•W·k8GfÑñ¶Æ“uÓq°a.& ¤b ÿ“Žšg“í©HS:ydæÎáÛáÚTÒ;£ÿMDfÒíéd0š®§<:o9󡃕ǎ>aæ5…~~òñèí_Yñ*Y^µoÞÂô‰ttrêx,Ò–L6­`¿­TÅc-éxóL¢=nd¦ë’I×Íñ.½Ö2ªëáîý F,d˜dÀ$sûLz/­¦Š™@Å”"Ô$âÃ0‚ÀÊÖN¿F›êiBäA(@ÃKtkT?\B%ýf2  ÊûЯýz·¸Û!­‘%©Vy$!1 &Cê*‚9’1ìëC„ÎH–2›°d2lÉ$ô|Ÿ0¬mú‰e yA&ðãqu¦W­[!lpØ>ïµó=Lè™ÑB,Š®²ç ”Úó0²Ø˜ÃÆ1ïÕI€.íÝ"©v¸11¸¼42æäRA-K!hÎeó@‡´ˆ;üun˜ÃtãóƒE¯U E2A„ˆ2Ñì‚æ^‡gK¬|GlZ`çlR¶’%±IˆlmÉÒ ÝŸÂãM(ú¾Î¦8r¢…"ÃpJ° s^׼? @ö»¼¡fâÝŠ~Ý*<<#°U6-¥ÏÁ_té4B8HÎ Ü]Spù£®êBƒ›B”úÚåÿÔs?Ú|ÏôƒMñx›i6Y–m÷LO2²;™hù¬cp¤þàþ†£/߸¾#${®ýáû5ÏcL0ÌRC"¯Ö/KĶ%bÛ#_¢¦{Ñõ<懽°’ï¸c¦}­S'º,ÁíOËKKçîÏfæçÿéôü"ÁøÕëÿú‡ÌÏ?Ê~N?z ñ¿ÝE$¢Sx’"+ ûå˯Ãh¦æÝóÿ´ ˜ŠÂ„qß·ÆBîðí]@‘›×7»Ô•yT‘…Ü­ …i5;g>ÝÙP K¤n'H²þøFè7k]¿8¼ù¥Ú]RTQ¼ùçfÄ µÌÆ:bA_2Þô´ý‰FÚ£ÁÝ€™ØÝ=‰pKÄlLÝÿÙèÐ+Cïn5C±Ʈ½ùÞ©ÆÔ¬ÿ‹;{6Ö«²M%6xŠtR4Ô·%õÞø¸-Ö'¬÷i0o»SÁ]mIÓ†Ûánû3çÇ—¯¬nó®g.ÜpÛ‚šâ±®#G7ØrcEÕÖèÏ¥Þu²¯ÛO«È È&-=¤Ì ˬü—Q+t8EnŒA®‹Å÷Cùö@`É(xÃàzˇlõ$§w;Ýkñ U× 8ZA2$¾ˆé„À]„%‡DUL,+¶­.Ûázåƒm…÷Þ*ØrxuÇ}w5ó¯áAºtÃ_Uloë¬f¾ZÖõR¦«„u—qŸp“TZ¨äBàl(·ZYÕS±P6 á)çÕ]¹¨F8 *¬*g2ÖSÎöH*xqêüwÁ!'VÞ°šWW óÁ{©UeÖNVó‚ðÕ§c 'P•鬸Ksé¯ò;kpuäÒFD "P©@Rt %PL À[_vå¾+œñ¦áÊ«¼²œ$ Ã9ٰć Æ~±hV™xÂ<±ö3*/`fL]x?ÎÑæúK> Ë 8 ò-`C0!QV°§šD‡äí°ÓM_>o2 ±Álÿ±Ë ½–…ŠB½‘ù¹žÉ *0ùÌ·LèÜÄO¡“vî«lOëç˜ÁúEv"K,Ø2b»T@ŸÃ†Nd`E#ùßr 7ŽÉ<”!Ïa6 ¹l·ÂZdEv±ÈÒiD`—)» ² ‚uDù“¢òù®åº±&G¦Âþ-›,¸> "bS±¸}y"šÙ4bWèc/-E‡s”ù™ÂžáëEúà<¹Ðï’ÁºvîDJ”W7åÇïJ†;¢Ñf3ôÆ\|_Êô¤B³ÑŽ„ÙµÇ£;±NX‡cfc2ñãP°½ïÈ&ŠràŽF4‡ ‡¯£&êNDv¥‚‡R¦?~cÑõ–ñhK"ܑлSñîKS?Y®µaBÈn­Þ·2ixÍCü=Ëôýêõ?/( Èé÷~C°«¹ŒlyTüeC8Øš2}¡º“‘ÎTܳdu'ÌÝñ× 6mŸKøþv«Ñ½£Êr!AQ[ÿ ãÊï_‹G÷ݺ¾ç𑆵uH“m5¨¨R ÙeDÅ"C¶ÁæiªM¦¼±7ô¦âÞ„ÙüÔ1¡•;Úsf{¨3ö ö}G—ƒÇG7]½ÚTì‹umzêGñ„ç`×z*0·elÛ¶­ð‘¶ko_W#;PáÊBmf¦í^´e6ؾ½=•hIF|)s÷3çÇ—*öDÂ~åͶdÄ5Ç#-a`I¨k]5QTIÅ6ƽߦìDÞBX<]åóÈÀì$,Ý”6 ±¢ò¨‚çÐa»(S”sbhqíÀöܪ4·ö€™PçúÉ­^züu¥¡D†‡&‚‰]A˜Dìrì°&a™ÿƒ Tis™£oSÉŸvU>øi÷F6©!Ð!Í!ô»W±®¯1?Ôó¬§äQ $ã_źK™jƒ¯=«õ–²·×0_%Û[Éß}ü«¿ 0ß]‘|ïr¬Î@“îh•ö¹ŒZT=ÖÈjþy1dÉÁ)=,]ÀOO) T¤y‡+x[ð’ÿ^{«ÙÞ5VUr5Šü• òéªæjX N0í¯€þ L²¯žù묞—q®wfeØ[|凮wêK7ºŠ5ªÃESdUs$%—*„¸¨…Lª*вB•Þ¬SO79Sï¨\˜c˜‡ûˆ;99B”7Ž>qž@«¬jF-·dÇ ¦Ä¸ aØó<¨†CTaCŽ‚F$6áœö` ‚¢:eíL£À0æäؘ Ú5—"b$ÃÃÂïÁlYÆú0;]‚Ihõ ¦Óe dñlçÖ]´Ÿ…lÂà§9@Ù1ìg~ŒÌ ×¹Ä%Œ+‡„Œ9w´UÏL¯b—-$LB46MØ9k^²ôŸ¶´sVbt.Iá“#y–”[_̉½_ØTª aI÷lAýÍ’®æHÙX'¤/唿/ ¼oÓK§£sˆMâ PäC™…C쪃]F§Ž®Õ‘B•eÍåÒÝX u˜÷l¬3ÜeÞñ&Âî³_î±Q\WF²di¥•FWW£«ÍhfW»klcÀx1Æ5FI”H%ŠÜB€?d[Þ{»Ý‡×””*‘@ü„$M«ˆ%*1pKQ‰’’TjqhxØ;³³;»kl°Á·çÎ:U”ÖT–\ñ££Ñ™û8wæÌù}‡™æOë¾T,œŠUêŒá¿>Ô²}Ë2‰ø†Ø½0;q¢ñú­ú̶CþÎW×ß®‡œ?S~ƒRW¿í»—éõ±Û{ÌDGç¡ NÞ¯„ æN}Ê’799ñ¨øññcjÚqcÑ‚…,ñ`^!¶í[Ê㺠ÄÔk'2á´Ñ â5Wj˜Ðê`Bàœ13<šè¾Þ–Ö÷&ŒæW:V8 B}KÔ40ð#34â>#î¿r¥îõÏ?]E1Gä$‡#nYPúäbÃh:˜Š7 Ƴõ'ÑjÄjÇ“þÌ­àx2 öìº\Äpª:oa>lR©G9sê…¤YkÆ¢kWçÉÈ¡à|ã½lNêJ®·gMìv(¥ÕŒ› ì-ÖUÀÝxÛ#ÇÿÜo"¾g,Ý©`,Ù’Òàçm2Ìh§NnUÜl/ V xt)RÀ*ÇÙÒ°GŸÂô¥›gšÒ#0®€œ,+RNF#€"o8¦µæ¿Óh„Ì„£—0Áêr*Šý²ðÕï¹6-ÀN¤¡"Q€2P$HÅ¢„m‚€‘ ñD*Q¤Ý%êÛ_­¯¤í«h{% –Òà ñ H¾c¡B”HÐÐr¦ãá*©¢?c`0*›Š–Ó} ôKi– B^Öˆ2Þ`Ô-¥á¬°VL[¤’YÐÅKCK-òÉBÂò9dÚ–ÝÇj“°Hֹ̢â¬QFJVüÏÎõÁžˆµ;XØ#çRPi¤FËØÛ‡ƒðÔK÷–Z›]A£+h{ ß -ÿô¥Š¾u‹×,YT$ÉÄÎØÊ[ #'oóà· HbDÊåÍåbÏ6|󘾅&º‹hís°è&VäÈû¾ðM³¬ XrT`í~‹Fº$à ÚÅYaã¦ýÚí` }²PÑ)Æ8¼ÂgŸ3õ?SH(Nsô,¡ƒ2='^9Ì;!¼µ*—žQèI¹º°±@䉓³KÈžG\Ñm6æÏL/ÈÎa: Ι?ýc{<í¢ç8ú'•ž·Ó³hâ#5¼É#C"U1 °åüæÍjM‹¤u?$œ±L+XRk² ɶÑxôn¢)1Ütéb ÜË;% I^Æø‰•è󫛇o·h†ÿâÅÆÕó¥¿w݈˜1Åéx8¥7d@¿âu =0¢…vþ8OUÁ¼$J…ùi3•’©©ZƒÓÇý‰‰,ì|qCG"B—x×® d´nÜô%c»àûšš®Ô0mø’Zs2ÖšŽ㷂ݯ{ÚŒnþ½îõõo-È— 9äI\wçšq½)£×¤uÀ¿n6_ù¬þðÁ­ÏTñ‘e,9y¾µf­QmÔ#³õG×ZÓIß„ïN¬5¥ïŽ'¶_ûrïSO-f`7±;—à j“ ó£qÿ×ë7nd@b¡;yÕëUûß©N&ÒzÛX"`Æö$Œ`<Þ ”>¦=züø–iZKÚ„„P7fúXU¢µe øµ}ã±Ýl~“—ˆ.àU(Ü\i³JÈYÒ°ÞA† eæ¦GÆ™ŽôŠLk@q0Žò¬O×ü™ÕJeºÖC&{Õ¿ìsìûWU+";"ìÃ@µ%Š (vˆ‚‡èu÷?·h¨q ㇋‡3ˆZâš ª Í| ­ K¯#–|ƒ”Ãp)SóŽJÖ?”RÎÎ0.XÚ-Å•±;°DÔ"„vkÎ,WÀP#œiøþ”[}¬,­°¦‚* +i:TXó„üZʬU,^D }kN‹…UÑè“4²’†,ÈG Hà¬üÆ<ål§°D1 /¹(ÜQxƱ*wâÜ2ç$Äh"ŠâX ¼$àù )Í“ÏîȽµO` ÌÐÃ3 é’N<$T²Ââ!92ƒØcy õ,`ŽðìòHß.Å´M?“i'€‡«f$‹ª‹GÛ¾_¨Û(¿V-VÙɘA××Ü{D¸й¥‚E*D‰K­uÏë­¶é,ÚTî›9Îûx«Ð6;êu1|ŒHîq¾]CJ6‚=óaQ”+‰Juñ¼Ë]Eôc…1Ãyk…žãæLýaN˜y§, 9‹¦Î UE²Â Húô8GO£;ÜsUÐs°¬ˆ¼CÅ®¿ãéiŽè x*"Ð÷Мùó!ìÓAýO¡agó@;ö©?ïZ/rv™Ÿ/#ÛïOo25 …èKl¤’jÚ„š·ÅŒïHi#ÑôÇk=Ž`‡JHsmå?‡c±¦;FÛáO(8Ç)I2¹ðÐW¾‡f¹—€y ]§úD¢V…¯ ù \P7$‚¸å…ÍYy|<ªcbâ^¶1 „StrrÎýý½ˆ#ª$K|ŽÌ¹ÞÒiO…’1öeM¬x3 Ä\©!‹F³6iìÉþབྷU!W®Î¿ú×ÝÚH hú¥¼vH– &ÕŸì¬43¯Œh/¦“MÉ‘¦d¬‘5 ÿ—ëW-seۼϯS#{3þÑáàlý‰-©T[B«ŠHkCÛ —_[‹c$‚]$¹Ý];“I¿©Õiu™xS"VsùbÝþÈÓö¯|÷ÄwoüÃgj­³~º?“hcl¦×ÃæŠL<3æOŽ´¤4Æ? £•]þŸ)%­GáçýÛgÛdÞ&Ê*F’Wäº÷@µ‹ïw;YBþµó.”™Ç 9[B3kJéQ=êfuh7¦ý`¨4« ´O€;SL¡@”®_þÜù/öë=6Šãޏ¥“,´Òj4Zfµ«Ý=Ýñ9Æ ƒÃ#¦Æ4…”<Ê#$4@I›c;öÕc_Œ±ñƒÐ6B$ÆØøA‘ªD¤RKý;8Tý£JQ+AG& Ø÷ØÛ»ó°¹éoÎÊ?¦r ý§¬Æ«½óÝÜxïçù~~¿yNø‘Ç®É2B ‘Àp¹š)lW†‹*ku±~•Òû2Èánî/Ÿÿ6ýŽ{'¸UêsYSÞ­†•W|yïmq×®U¤kXW00„È„ÂÞN !JºCÆ;V 3%Fôˆƒçu'æÕr‚òÑ!óÑEf\‘J°Çw¿‡´¥t®úç¤èró¨ j¶(ÛÀ¢XÑ ¾»(Ù%Ý#`̓ÓÍrL£\5®Ë‡ÑR-)h¢§éé9TTÞåÞ”+&Z\|%m°*/ÖÆ?ËÉ‹Â$sÖ³›¿«‹þ³NÞ–gÃØŽeCÅ:Ô¥ Û>ÜŸÍ]<ýû S0ƒÑ ì¼Èú'*ë'üz¾éNNE6(ò·iÉão ð)R×dÐÓ•ÙŸ'>¢G^H×Ä,ø§yk;¸…²³»ˆëÊí "?]&%/Êìœ0“ a>Ï Ìgî¿jꥰÂo]›óuY”A°„ lcáç#bú¢QohÌ‹•›£{'£Í±7®ŽÇ+Æþî®m9δ÷;^އŒ›»ÿqÕ»óBª·$êQž]ç:óÁ/£á†hП0k¡ŒC(˜æXi,:çþ6Øû’‹:8G#"BÇÛN3ƒ ø™žžº›’³áøðx0G2u|ÿáwWütõ«+ngtÐdª¨Ùzø‡1ªaCÅî®­fÌŠ|åÛõâcb×äLuêðpÕØ5ß ë­ñÈËÜ‹U:½Î-Ž€}°0àʃÖHÐUÅ5_=¾ÔI‰¡`›[$oo£ì¤›Ë¡ vlÄwìN™çÈ|5ÒÍIþÆV…q@ÉÉoþ œ.rçòë;WKN$.¡…(‚ÌÕ¡åD™bús9ÆéÍîËå+YC>kXÄê0hB÷å²Úü”Còf5òpü÷£ak€û ´Ëeû—°º\VŸ—bÞXýbÖ¼b¢vÅÀϳ÷å+….hdŒ°LUUÑ"«ˆ˜DsP×ï6Ø®½Íº2X›¹ÔÑHœ nÖêàR…ç;ÁxÎúéÌXŸæ‘Y¢‹”ôÉV‰Y› l|ýªsI¢h@ô¤ ±6Ï6Ä:œ—j8ETqö,T•¦ç³Ù‘L¨Ãð»že‘õ,LÒ¿UÙñL^Ÿ-°0'ëS‚rÏ êº†Wv«¼¤Û¸ëƒ2×rGºˆu¸@BìWÚC)Ü}b²²!õaö1áĬD!ÿ'A?˜šá<æ“ô¤@2¤Ýº 6ï”3‰«"®z°Ð_Œé>tëŒÀ=·ÏªžW3©‚ ²Gõ+$>.¢l€²^õÃ…›Ã÷M#ýR–w^„uö¶æ"E¢’¨RTZ²°‘ˆÔÆB¯N˜pQ-ê„UõŽCçeU˜‘×LÓw°1?zBŒákU…ô¦7WŒì©Þ¾5W'ª"’ƒÍ«ÌXuÔªŒ…ª'"5ñˆÒj®ýÍ íýìó_m(ti#dSyëÖ-,yçÎé©©Û,¥‘dêøßgôÿÛ‘"ßì­žå_’µ·¶SI%0o¸è¿Ø¯÷Ø(Ž;àH–,tÒj4Zvµ«Û]Ý6Ô8Ä6l0ÏÒ„¦•UBì…‹Í]Ž»³ ÆUÿè+l0¤‰¢J©¢ª$ŒÉƒPµBET*!)/û»{oór=ýÍA¢ö«dÉj›ÓO§½ÓÝjvvv¾Ÿwá|‹eùâ‘(¸}Ù¤rЊèRñèŒi$õ…Ç›3IO<ÒfŒé Ñ3Û¸ 0"²H$ú®ÊñpÀ´ôt2ܽ”`A"œ“R]8·Õ {&ÌÞ„±ýïŸw=³Ü Ý™S"g>hM˜Ád¼ÅŒ¦;ž{‰Þè-F{Æ X1¿i¶F¦ˆá½zå¥xÂóå­ö5Ë…Wâ±›ŒÜüe©˜'Ñï&B‘qO86m-XÑV0^Úò¦ _2æƒwxaÂaòááÊá${÷Â#få7ÿLÕx¬¤—뉈gp°ž]© «Vº ®÷³Ît°„>D‘—ÎS÷Ö~Ь=ÂÓ~£ÜN~ßü©xèemq‘@ÃA4‘Ã2ÆN0*ሀDl[;õ5Ì¿¶»z*°˜+éþEtÿ–‰] rù¸˜v/Ïæ›`»_Û_¯6W|dž Ëež/›÷›—“Qo"ÚŽn?=¼A{(HEŠ6üfrG"êO[Í©˜7Û›oK$ôl642Ôèa[# ô:Xê?rôQ >JÉî—O*©ÿ·_ÿн©¯^p¾}£HÓ$¬(’ì”ìo]*åK[,U3q_"Öɘ¶: Rfû j$Ù“N2ßOöÜ5c-ÆøÎkWw¯ù®Ó!AøJý`µëúç¾è8Ä´÷è`½B ½Q\ª*±ÝúÂoŒí˜ˆölú~‰Æ 2š¶-‹¬=É$ ºuºã‰Ýn›È¶X¦þÞ;›žY&ÕU Þµ×ox,Óc†ƒf¢ùÖÍÞ§4 Ú Ev ÐðaeÍj ‚‡è^\‡MCOdóš<_¥LL,$Wí “¤Ùê0óp àÚQöpÁÇl⛥”‘Y3kÃa}ý!žˆám»Vpôx = 9¢²9 É¿Kç«·ë4û\ô …öËômWö°ë“v²¹Æ]Šg)¨H ˆñ<†©æ¥5.é+c» û–±p UÓ»ø1X2\J»êE‚—•L#Aò­Ff¢º2r°ãšÇÓ&éZHƒ¥4XF»–Ð}ÕÔ»€Ý”ž%ðÍdhNª³|´±´u?‰Eƒ[@%R±HQ’e¤¬pàÃÏ£ÛA¤ÚOè ™žT/8Ìé4ßú9)Ð×µÀ³kj¡ˆ=åÄþ|¹ò㥶"¹ó´½›ªítçÀ,>8†v×" Ù%"m^‹v­(pK¶YXTU9P3«Ì b’„Ú 4rÒ7UzBŠž}õ'®©_rôñ°ÚÕ¼ã9B˜ÌáB`U‡³ú >ösñµX#Å…ÒMt`·½ëGL#§ít˜§Šô„Ž"ú  búx€@Fx:BH ÎçN~ 4ÂÓóÒÿá¨HGrºvXïÛ××€Mr¹QáÆ§ _Y4˰[öÏ«¯šc½7›ýþÏN5C¡§!½ Ðíô¢êßR†ìŠ »Ý":µ9mîMÆôl<`†÷dRm)³9cz2a5®ÇÍΣ}\{Ãss¯^é4Ç}ÿ¿ÚÙR­Ài0QEñÖø^Ð4nI£ (’±|ùö·hdçÛÍw§ñ¢ˆxE‚Í\¸|ù2¤áÇžP>ÿß½&'~}üˆ"0ùÖ‹<M(¶ãukQ&} õ¦M…I‚X·":P>>:˜©Ô‹Ój<c{¬HãÝŒ'ï0¬æ¿]ëhÚ^¢Õ\*QJTÛÅ‹¦Õf¤<¤—¹HYqÁù‘mf¸k"Ñž6›?騜ÃuèË“Yo6î7ÃÛã±æD²kºãI§^„Ðïõ?[$ÈN^U0´r¸¶Ìõé§ëI ŒÝé¸tiÇºÕ ¥u}=ùâÆÞ¸¹7k…Œ;ÍÀx`C42m¥-oŽ|z*Î(e†[aÎA&Ý2vÄÍ&+ÖW”‰ávx¾i˜&lk2Ò–1@GžS¼R%°3Ù.úŠ(ë[¡“åét²Ó×È1'CÈ¡o ±Câñ­Üºyv)"Q1¯JDQ 54,B¹„[k|IˆVÒÐ*ê_Æ4„(¬š‚ˆ -È¥äB&®ê©ý5,.÷-þŠ"ßjd¦ª’Í3ÞRª¥û–° .¡=uŒ¡2Ú]A;Ë™FBu4°Šv.§Ü÷=Uã¯U¾0¯á)¬¢K‚¨‚Ä‹œ`ž(O‹xcþÓ«ªñ«Ùô]0¡‡íS!ú¹üëG¥¿&ÔÞM¶bža„‹œ†5;Od©pkÉ<(Ó¾¹´_e+í„Z¯¨¼,úÃð%]ø'ûuÛÄyÇ)’%K'NNît§óYv^JHx ! ÆA7 [E›ÊØX褉+/^°;¡];ºu°HBCX×uÿ´Ó6VÈ ï]‡TÔmH£c°1ûÎ>Ÿ}&á%Éo¿ êó¤L©öÇ8=²ÎçóÝ£çžû}?ÏúùNÂQ^<§P·Ê»×‹¡^2Õ§Ô”Ï+w;Þ©-°Ï¿ß+@/“µ?Ç ¦ðØìŽES!88DÑW÷¨‡«¸¶"„Eu;$J÷?sg¸F8ƒ–Pm‡ !Ϊ³Nyüû)ÎzÉ “èüÊ©\ø½ƒ˜û²Í<8(¿ònªp N‘ˆ´D(úÍ^¼»÷îÙÜ·ÛXÊæ8 Ž ûcŸ à \`'OÉs¦‘!†°êF¼ÏÜ>YþäãªÀò^É‹S¢Ä«^½Ú”¶ü‰Ä,€fÌojõßÖ¦ˆkþ±h`àøãºÖžH4àz-k½qÍ·sû|eyB†ï-bZ™­éx ¥µZÃ̲îß×·´ÙžJøt smߦµ¹#zÊsbuuµeYSrzzêÓÿ'ÛÔÔ$üË!3;Sýýýâʉº¥œ‹5mŒc¶Æ›,Ã-“ÄTjFŠ \1:ç*õÌt ^ÖÔM}w:ÔÇ‚Ÿ\«ÕH*QŸJFºCëU^¢Xhd¡ÀÅõ¬KÅë’Ñð•?6«J˜íz|§ó[f-NÚ¿|²[Ó"qÌîèž)+ŒvÅ¢YgcV$W.ó%‡È"•©, FT™ÐbÅ}áƒ-éTKJ #pΟ©þð¢ÏJ„PøÇ[7êîf:Q2F šõ8hmhmCÇ¡ðgŒ`&ñ½TìÕ”þŠ6Úž6ƒfÒÅHø tB|ÎÆ?«Fb»­TƒkÉ$šÒz v­–(+ð¡ô¹rF?¸z°>ó6Ez³¯a³µ7p¥™õ%¹ã)ÇR/²Cå¨Ki®@ÝϽ¥Ð¾Ìadþ4j$Xn?¤Gv-·[çª{ÁªI4d÷j讜®H¶®ˆ¬_¶ZaDŽ#²ÄINQš'SŽr….Îùl‰ãí$õCC庡ÇuïM5ëü9$! ŸB¿ëú>f{“O %…Báð³`‘Â~á-ªx“@oþP³¸HV,·i¡c¢9k½1ÿ3e$—¨Pn[…zðÖláÐV§K`œ óðVEö³õ§áñ˜íóŸp3ó±\ôýj _<Ý*KN/Ϫ |NÝQ5/úk/œ›±Ä) Î>åOÏA‚;gð+…‘™ãç™{'y!Ãx‚‚;©wåêÒ–Hyï‘\‹eéÒAäg ¢…ˆKâ\ª—2ä©J<®Ây×Ô7g9)Ày~utÆewø¬†Ù”>ætó9.RD9áKë<£ñV-V?žl3ÇÂXKµ˜/®·ñ,zI½kCÉX1<´cåÂBt•,9êÚ°†Þºõ‚…4Öz7LF–Ù„Õ2{‰kš©öí†VwébƒJ2ÏSž²,{àÀ‡Yù@#³òÑ6·Ûgò`çæÍ›yyy*•dNÅ*ÑÕ]‹î³ÌpJß•‰¶¤~œøì’šÝp2 E$s•zF41ÂÉhÛí´_×ëþ~m߯µüöçÊ¢WÛ3F[T¯ùÅ{_Í÷H"[ˆ TÁ+-e-‚ýÑõ-4ÍÀítKjôûiìa²ÁH5Zñ®‰¸?s /ë7R{fÛŸ+ï>Ñè¦Yà^l}âÅÀ:Âçà¾J]‹ÜÒÅÓÏß±|i­9­7ÑzËh7jÒ±@|´i|‡ïjívÊg"Wþ+ E°ÝI‡´›¡wŽnüVµs˹«­òò-Vò%|×q|=}fòó¥¶qÓŸÖÂÉX»1æ»lÆÇtýoþ…^"ð²HE–8¹\0b鯂?K¼ß©Ô¯uäó ϹyAyÆÅ1nŽQ)¹ÐéÏ %vð…Ê ˆŸ%й:*í4 .&]´!NVCçû"ž^3sÊdÅ#Ìq ­´¥Al” §;Ov.…ÐRˆ¬€ð*{äCö hÅ"•þ)†ÎEZ6óS¹ý4;‹î„*Ol[üÍJQ ÉåE‘$J\.Vªò°?x–ýëk* ÈГ=ýñЃѯBŸlõyá8U>Z“[S©¼¾™ü¬–Ÿº¡WºÛËA?}ʺ¥wôЧ‹‚¤ª„n©$îõN ×ôʾ¢/;]”»ʇ><3ïrWQžààx,InÊþhó‚÷¾>ïçuÙçùq¦·<öz<Ћ R¡G†>亂ûSGÅ?u©_)΃©çt¹$Vúv{ó¸ËÉ ä„§™Y§ü§!0ÄÚªÁ#¨š!~ËÁyNáóònØC$Ö-ÍcÙ‚r•¿2ÀÂY‰Ý†… E|ϱ‚Èí|I#ÃI óïO¶†ÐaáociP„!†x8ǼշÆÃ#'¨@EžÐï¶!a4¦¢Ý㉎”á3ÓuzÒ?¦ùu­aÂôÇüéx-®÷‡ŸtÓ…²ñ*Tyþ;åÿ¸Þª6[ñ ¥·£uêEûOuÒ4j­D§õ§ŒZ¼øk/o’9„ç!¥7nÜx•ò9o““wa¦îÛ_&'ïlþÚV‚“”J*ÉÝøE!¥·fŒÝÉXcÒhÖms¦£Q·çR eG¹¾ÉD@µXq¿9ÖfŒ0‹cz»¯¡X"ŒD–-Ë=÷»mÉXp<îûù*óTn!V×Þª±Q¿•n‰¶¼`J«ŸméMÛóOöË=¶©ëŽã‘"E²déêèèêè^Ý«{mÙŽ ¡Iž«ªP ݪ2Ø`el+/7M²˜$¶‚Ƀ@éVUÕ$vB)lë´ ¯VÚ:´nš`<âØ×k; üö;îû‹?2&®~ºº–ïyøøœï÷óEb1£ÛÇ3HÝ3é»w§aaÙ¬e•%šœ¿·yéh²1óüñZƒÛea¢ +ú¬B1Z?løÍtrÚÿ@ef´)óg~¾¹ÉÄ›Ðë£IÏHÚ;÷§Œ-·oµ¯\ÎTâT‰ŽÂ¥Ét†=úúpl;žÐLl?žµgM#©hƒiÔÇ#U#©úÄpíƒtKb(ðQ;NI+a̪;fÉd¼£+…›+pXƒ.Ôÿ\˜íÁl(b̶! Â2‰a‰çÇ ý¬×ö½Å‰QÜr*•UÂlLÔDü©¬ÐQüÕ:–Ø9Ú–pïkËÕî2hûüíøE=•j}œOöVþ­fAÛRe±Nn “eFt‰0f³ GÌ÷ùûÏÐK¹›wj9âÅÍÆ ì‚N7ß]]2·û Êù¡›@€㉴ÂVŽÈ_ùí+ ­A•mŪhuˆêB‰fqßvéï#º0èPGHó²]´0¢”H6 祪‘¹$}u…í·*ô:§boRnÃSèrBRGnŸÎÁyX. ‚ôÉ”àSàûÇÔá_ÎØ\š_,*2EbľÐ-þ5h‡+R-d@2aPƒóHôËœR§O$ü.À€Àû¹¬MõÛ®·Y-’€ ~§G‡³"✈Lr;¤Íqˆ µ9.¦õ"ÉPè×à²8…m/ äh¼Ã‹\$pî[òa0 ÁkŽg\²þwÐéÍSýØ3…)"SdJ >ÿõ:#ô^ƨ0Z¦¢?Kù#w›2„ÖÇ׫z>£ó%Îq°3'_Å<˜NTÝ»ÕþÉÇ+~±ÿõÖ]knüe[Ú¨ÍÆ¶˜QÏH¢ÎŒÖ™†Ã#ÆX|IÔ㷼Р_"áK%?zóUÙNl “QšÖ¾õ£É)˜s²S“È%ÏÕ±ÿ¯É©q¼?z8‰+üøñØáîL¤šìTE]eùW/xµ'‡jÒ1o,Zm¤ŸšÁ%«Ó‰ÚQÓªKùR±:¾1ŒZÜˆÒ fÚšv¾¦«J­²,ª¬àà'ëbÿƒ1Ïy7®-qëÖE/[/öo5ÓÞxYÝÇ››Ó¦¦Dìì!“ðd#mÉ»Mÿþf÷šJ‡Ì $¡\×ôCÖÆîùFSž´¸r©Êí”dAW­HË;wꇱHcÚð$vOwÜÑTÝHBu&^›E2á½NR»SÃõf¬ ¡hí›N]´é"[»F-t1FD›¨8;ý» œÙ†7áûÏšFpm³IþA™”׈Ôć¼Ìv’%åLE c¬Vо:g½…Ð:œ{Æ„väâ!FWi CkXàr}õÙyb»RYl±IdµÈ’jãqÈ*0*kÊÛ/ëg¿_mKG›ÁÞ•hUÐ<ZѼæAsxî6ú¢žJµ.¶W`W)4—Á¾%c{^»Q·ôWëK*íòL™2j™ JÄÁµºE¡~¥í›}.8†¼!= q ‹Ð%äØÃ|ƒ!ýªÐãâè‹Lò$AH8Ä;ã¶?·ÛÞWà°ä»DÙ¢ª¨3'vè“=Hn8XŒýøWʪR;Õ‹önyþ27s*yV"P‰¼S–wûàL!aÊ¡è0á\„drB§:ñ+™ÕË Kâ Ž'¢W‚}öûóö¼‘ï@¡ª]’5!¯Ôiý¢…Á P8KáªÈý½ŸÁ%Æàá@2]—?mEƒ$‡H.’¾m·º8##„À G¼R+¢ Ì?š(mX÷hÁ)–Cl.süà=P´C?Þñ#ƒ/|Xb‡KEp&Ç'2'œéÎó¢}|йq¥ © #….ézÞ××fÒ“÷½¨–Y£a4é5PuQ6“éÀªU¢Â,ß]5ëëk>TÑd¬uOs¥ ^ŠÝ¡eïw±&Ì›ÙDc.ôùQÄ2‰úì·(óŽ™ hC¨·ÑXU"î8çu+ùÕYéèìC ™„‡/hä]SSœC&ONM=º÷æŒ"]‰Â˜Lèû–¦Í€ó™Q?þûq£.•zjî–Fö&"U™€mH ÕŒg|Éáj´¬MÆw˜Ééh m4&­G¬“(Seu`°*3Rý›Ó›4©ÀFgÏÒÅߟܖ“•¶ÏE°ððšF}*V›4j²&þL/’tË…ÓÛ©FBE™ÙeË?ÚK dåRߣðlØÍàpNóQÿ»è”0?Nu¹?Û¢VÎ(Æ™)T…ÙDʧÔZ.KÍ‹_ºùþBhŸme(ƒ¶Jh]¹°kNοæå°dÁó·Ñõ4êq`´.„– ØU«¥œ£æ®Š-ËNþ t}©fW$*¡) s2òR)³8ËO³?ì<ÐÙƒ Gß >S9™tjÐ턠ȸ×þDé±Á‚:¾ö8l?½Sö¯¦o-°V-WŽo¦ð©‡¬p´¼¯Fh¨haËÝäz»'¿«þéK•<7Câ¸u?Xhè1èàôÉ e£5gÆèá¦A3 КÉm‡ìtí­‰í†Ö±¶ bƒ~Ç܆—_'Óð“'äþã­ÚOêkª°¿0Žû#f9‰õzy·Gp?Z£k‘´ (bjui#lkqpãênÙD¥H*0~³6—Ù ñèÍhQ]k‡4+j^{íjLr˜±ŒL«ÁmåŠÀb*^7œúì•´Öi©aønΊ™‰ÏTP¨K¯‘¼1&ë³é nlWµFSï08Ìž3Ûl’§š3–{Ê/]Ú©Ì´ÀíL;HÉVÃ9«ÙV£ÆDÞZÊŠ Â^r_¹Ñ¼sç’ç«Ê^{Áûc©uZ#£ÐSPò…$0ÒV’wÚ }±VÝ2†'ãu3ÌpÈKò¤§pÎCWç3¼é—ŽÕóÕO9<ò,ØFÀÑç$‰Åß“{Äç[“Ž5¤kÍt|i« Ý@‘å$¶‚t,"íKHÇRÒ¾ŒÄ—PŠtB©ZñøËèwãጔñ¥ÓqÐÈ*Òý}°èt|!ú¸«H'ÄÀÓW›fÇž•½ãüØ…+0_*ÊI¥ÛºÚyeô*d®@Lqò¾@ypˆ} Fú0-€XJ—/éqSEÓˆu‘ƒÀ m¿X³ˆáÙÇ Vöý|öý¼Ÿ|äËö ÍÏ1 öŠØÇ¢ç#~rH¦êî—þÓ 7)!–DS@¢? PœSðÔ °H˜ô@ (# Y@/µ=’‡sÈHB¢ rÄÌŠodsü´ÐŸÃä„‹|ŽÉÿÿhàr)H`œE0Ó@àİÿ¯=Ì\Žá$ò‚ˆý¡*GâKÆ`"”åß~C\?·¬‚sT`q4óÝç½3p+X &=ä¤@ï6(_îU&bò9GN0…¥¢×9Hg$g$rÿ¦ÕÛ€9Æ/ø%†ùìÓMV Õty«ÍÖb¦Z¯og¡@Ä3z(¯7ÂAºeóŒË=zýµ%ªÚ©&â–Û÷γ çXîßãm™|7´™fr ‰ G.ô}j:,Ûl‚_i—i‚‰²vû™“ÛË$—–E„ÐéSƒ@‘©{÷wÝ~2_S°·÷IÚÊÎSæ‰ñsΙñÈÚ\&ž˜[ÉÔz=¹…–3éaU·œðØlgë'&c¿ÜbQÛBD¥¬–Oú6y[Ê=³r¾gt¬&RÎ[Û’7[gKnŸ˜©^]~õÆn¥o£©dÔ˜ŒÛZ4m5æÒá´+v=‰›5·3»!_~øÃï7¼Õ¹ê`ÿú~MéõŸ—FëçûXïC,?Ç#?H«m q0L>Li”ͧâ¦(^#H.Ø^àM"Qkõ s]¦ÌÚ-šol*‘E7ω"šáçÄÆÚ… £ýò7 óæ ™õ…ê–éá¼}Ô‘6ZD< h+,5DZŒ›ó¹î=»Ö*<«`Qfðç@C:öƒÿe¿lc£8ÎŒdÉÒI+­F£ÕhW»Ú½•Ï_€Ýbclcük5i ¥„Bœ¸iLu×¾úŠá°Îwvlš6 JH[ü‰m ¶¢48ƒ1‰–¨MÔ †Ï÷}ç³Á÷ö£ê?~¸"BŠ8½ZíÞÌîŽvÞ™çyá¶ŒP/wJÏUŠh‘YÄ ’5‹,‰*Õ¾mÇ·­^è«Yì-„¾𔂠­£‚»ÇZ¹Š «ÜeÐ…±º+¸¥¸K7CŸÄ# jg9ôV¦çw tc‚;ŸŸ szÖCWzº{Öιªn8ªíµùź…LY"¥DÁ…{…ųQÿ´w9Öáƒ!Ì:+ s7x¨ [aDâN2Œòlã'㹋˜º¨mhÇ3Lj±&eÚ–FWqÛ9,â󽎙Xrd“YÈæU™‰þlxWâŽiOP`O ŠÐ/Á  #y|-ŒH©Ži¼{Ž+¼uH†£Ú~ƒ+Êôů•ºb1_I¦j¶&YÚ6eÄ?0¸\ 0Aà<… cɔǻΤoG!ñ"î œ%ÜjÐ"N‹0E'‹º‘1I°2ÖÖ h)h“úÕòÜŒ,U LTY¡EÍʤ+V{xÿ´ ‘´xè0Iþä*¨Î•;ê…»6¹¨xÙ—§—>ÎIÂ5æãÇ¿¯l@°lÂdÁ¨*c?jœK¢98!¬=íX¾%cíi×ÌMçBüW‘™f„Ô–&£V‰žùKSÈ×z/þF"ÜöïϺ¬T´²,OÏú“'!ך¡ÖèŒëG܉n3±Çí‘Ù 7ºä¬38íðûí»Vm“eRÌ´åy9i?¤7¶¿¦¿;_.à·õ¸zIP1ˆüt•|íš+äk¼;ßöu 1ÎÅÛ‘;HŸDhï£B[Ôß:7g÷‡<»vT•Z>ü`×íyOØ×ŒÉàly*[p*$˦’·ß® Ý‘ðŽ×=¦X˜Uü|}éß®¼ ØgýŽD¨#¶Ïwg»Ñoƒ¾¦DÌò9–:ž…d{ÈçêsoÈÖdÜ 4žº™«²µ±ß? 9’qûʼnW ME¥†¡-ÛPgÜKt…n9’Ñ=¡™íh‘°#´Çâ¯.õ½Ÿ+FÂÛŽÆv|ÎhÀЏqgà–ãÄøV·<‘˜šðãVá`núÛ››ªU‘z½;þÎ$>á+V‘hÀ>s¢Ä¼|ˆò"b>¶gÚѲÒÌ4˜„U•F-ï<§Æ±Þµ^ëÊÚQ¥Š©Û4 bJ‚&«5&ûCýrx½ºWƒ{ Æ}÷:#O1ô–BoPW)xÊÀ³šÓ ÙÔS•V‘5ÐUôø1ú$Iôàlb”¤§»^/ƒnÌbØ_›ê©¾íZ·èAW)‡nôOtÑZL‰«­ÅMuº†Ô¤r¾H³¨D¬ª@,erÆèÙƒù0hÀ F. µ‘1³ah%W—A[a\»?$ ÀˆÂUaÌ,Ü·‰™’´R§(ð;ŠÝRCjð-[•†xL–‘kXNu,G€ÃŒó‡t8\ƒZr° 5fƒ£ F%îEÃ&ê PÕ¸« «0€–Bt¸ßr¢¤†müãÒÌAýŲ’R*-S Ù$FCù²à‡6¸`…“"\$àÕ–Nù´ àÉy¼dpî­"oò²˜—ÖWŸÿ 3uI† ¦ØÕ¹N7TjR•ÊŒ™„DUŒL‘iVJ[®4“<Úh’aó²$Òßh N˜RþA;:oðQyIâ|YMÁÝXW²‰EhØf öGsÇ\Ä>uFÂ/]¹ÜXÿýÜžµ½åÞ´7lC±è’êÞBØáöÞ™H´ÝøÜUY,Le„(2ùeïþÅ»Û_Óß"¤.]ø˜QÕªSY´äjôø‘]áYûB¼-:³‰ ´Ä"Έߞˆ4?BIÆ\þ™ŽÇw˜ŠfÐ|SYöÉßwÏE:ÑN#aç{ï5åf š*H¢œ%™Ïo*ùíÍ ëLɦÐe‘Ø›ÓÓw㎻($HÉèk±`S<à@VÎFí¨¸Üo—jþÖŽæ SB!º*j¼äÒuI¤Œ;²=ìoNÆv_šÜ»ºPxº–]ÿ—;:³ëv¬3âÛ»0çB‰G\á +¼ôï3Û ´%â®ÏÿÙñÎ5 ßS_Þü–]EŸþcç|Ô tmýn¡¡J’Å0˜²‚©šiH²*šû\Õ7gìóÉÖ¨¯í«¶‘¹¨…„ŸDœh}X•ÌG;QK¾ˆôÜžm D›NŒ50bZËVÄ"]¼Ò­þb££ Xà²Á(/d5UÊSÙPýšEOô¥1Tî´it—§ÝñTšê)Iõ®Nsª„sª1´–ÈwF*CßšÇÑ'ñHýÓS}éù­OmÊU“êZ8ï¥Ð]®Bp—ñÖ®—¥éT©¼Þ¾~ßúå¨ ”â¢ÚC’ JØ:#ãØODŽþA n#Ã:Œ3!iý°B¿ ‡¸?ö*‹GñRƒ!†´©æ\¯ƒÂ0[v‹<í`2÷½˜§ª½]¯ˆ°+b\Õ;3îÞ9bBó;²Ž£íðŸÙÙ|ŽI°è–P<°ªz£ªÂâL&½¦qXWêI­yNxµØQ3ÞðÑ/^w ;fÓÐË£_>on/îãáã2;;ûï›Ùû›¿±UÀ‰SßÛS˜ŒÀŸÈd_B«n6zÌ äÕT¯&&c-·o½¾,+Ñ0©†*ÇõãzÔ­'+j½az¿øÜ½³Â)±Ï€ ÄÙìv#êÐÂH$45áI¨G&ä·G‘ëã&€7©aáÒûdÍ÷ó_VÛ‘ cjYo?~*¯$)ÆÏr/,oÜxC‹ÿ~p¿|·&©ú׌5'U_BñMšA¨ÃÃ2|ÿƒXXÔjfݵOÂ,Ê…ˆÆ"Ÿ‰ª»{{ÂGþzðЋËì0ϱà`s„DaɉŽõ±È[¦nPkeøÛì¬ÓSõ(Jaz´¸7"{Q÷ŒR3£×E£¡Í{í66]´ç8)AB¬¤¢KÑ[é¤Þݶ†Š-¬_B¥ÊsâÂèY~?XL Iù–/µ—‘àzÚH‚-˜ZִмUdq3¼zÆâfi[CÚÊI[ é(˜†o-¶n|þY¤Ò8_i/lÿ¹¾Ä_!ä²KÁÂ&ÀŽf¶¬`úë]¤+›t#Òë Ý"éq^ì‚tg‘®rN$]<éá¬ûç2ÉYð¨à'Û ÿ°/ƒœ{v[[6 Ù4ÚR”>ùO.:&’¹¥@d lŸ`ߘub†².Û'G VÆ#œ`/™sÑÑl7Kàg¡U½˜üL°\Ôå C.f&;óº¶-¡y§„—kcVV— {ä"—r‘A/"ŠÆ6‰–ö:fúE2À”êgöeHLV–€†{¹}k1ϧ Œ…—xgøÛ6r…³ZÕí¡÷úÜùœ±åH#ŽÔÀ² õÐ !ÇžÆ2ˆ“¸‘ÁïOÇZâzˆÄ¸Ùtûf£À¤‰(¯| Ži-êÙU΋œ†Ášüœ]/­/Îw ˜Ç Ïca÷ÖôÑß+!Sw[ôh#T ù‰¼Ó”F(ªì­y¥\dX‘𫪨ÚNf¤ç1 •™¹‹‡Ïì‹ò˜ÏÕýûÓ䱌CJ{NŸöÁ<.G¤¾úÊûG0©×<-Š™Ñ@Bõš[GÕý)£Q×k Ã\Ûµ¥”Ãi·r¥D‚ð°®íë< 'Õ7ÛäØIŸw­SLzéa瀷|ã?ØÈLÞ£ÿXžÍØÖn³‹EÙÜ;rI8}¿Y•î sÙ,SÁ²§ª©yi‚•ÕV‚è¡éË$}<é„ ,é„ vË|Î"+t’ôð–5urV„ìå ’ö*,rˆÁ1"²mÎaþÔ)’–\¦É0KFDKNhr ‘Ïæ„äiÙÈÕÓä8'ËÃΈùKš¤É "ý4¹.|݇³Ø4'“¾R”\”À! ã¥Ë…ôZÅÙ+2ÌXÞ-ÜŽ˲0â@fB×®¹îìÝ rtº d14³©Ä¹Û$ßmŒ~=Ú`j†Ú2'ý°ýôÝJÓôEný¡Õ[ª\4Cày†²ã´æ¦o)wNMÅß Ñ庄æ5dï¸é=iÝS•Óðª1ÿŸ» ]°ª1<ìQ9®óô™y’þËI&§§ÿo#ÿ剚™y0_Ÿšš²>fI*‘Ì–À-A”íGooRŒæ±{ Íý´(–RÃ@aS­3bMfPsƒ¨Jý;?ÞƒÄÎ ÙNztäÕ‰¤WSZ>úpŸ„œ;ªðÐÕ£J,Oz¹ùò¥ú{s²TYÎ\ªÑT¿i4Á¯é±–”¶`Ié>h¸(´ñ&T? È;7Â0“Xi÷NWBmŸŽuŒGÚ¹îWŸlv öŽÖJ]iS#M“¦/®ùl$®ÔM˜MIͯ«ÑSö›rKÂtËJý×·=Ã×[9†rñ®û /ýúÕK¾¼ã›’@ó‹óPä^ÓDªNOŽiÐwïXÄ7½šVsO&} Ÿ{æ6bÄšM¹Ùš¹ªO‰xhÓ¸îOjF´E5ƒ¹öËO_{¹r…ĹÀß\:ÆÄ NL+˼y¬‚בÖå$œ;‡ò’Ç@_Œe®ñRˬ‚€Åb.$ùVà*e¤} é˜7–Râ[=¨².9³ÿd¿Îc£¸î8€[BZi¥‘F£§ÑÓŒÞhfV»ÞØ;!`lÇ15W!¡ä(-%=$±¸öÊ+{½Y¼ÆØP5‰B8lc£ô R“T¸1$¤¥ôL5JÛ„ØxwggfàcýÍ’¨ýǪˆhUGO£=ç½ßÛÙ÷ý¼=µðBtÔä÷WNu,ºÓUܽ­ :rD×Äi¯pÈ×ö5ˆ­¼¼yÉ“¥n~©#ÈÍ<:õxDùÌ+ñõÌöèÓ‡$B¾—|‰é ™“òòœéG'(ˆxWÏãi±$k¾G r¯„8/S‘ðL-•ƒ›|vŸŽ×þôyVBId«b×2 jp„Áq¯3è®Å9ÑY‚÷$CòíÓˆt´…r’[—æ«Ô d¸tœÁî(üŠ;%Q⤲G¸w¡ìvËÚR¯ëÝCŠ3ŒÓ¼ l `¾šFN‹pžÀûx, TGÞ®«ºÇO(ñˆ~QPÂ-kpck$#ãV›iþøÁóŠèÒ„Ú{uïÁ×ÖŽ¤¶ÿìõÕUåÝIöRZsŸçÜé–kFcÎŒ£ÆèŽŒ…K±£‘¬¶“Ms­{VªÕ2qjZ^~DJ?¿¤tø³«³³3P0ÉÍóLáÁÿ{LOOýóI¦®ßÀóÖÍ[‘)„©DZ»RcÐ-7&ƒv¢ñ¶¥X#¸9ga#AÉk±Ìž+—åe Ç1¼º,cD‘Wÿ¹ßG^UxîÕ×YVØ0vŽg"ÉDÐÂ]Ý?™Þ“µ­ÔŽ1;b'¢é6´Í­Ž'Ø9aEpTx‘ñl“•t®ðñŸ¶©Œ×ˆy•÷z&–ù|ëõdÉÔ?¸AãÝ}‡7ZF–€3“¶˜Ë·ÞoKÖˆŒ™ÑqÇ38'Îl`i}\ûpéªe•?öHY*ÀéO?ûxïòj\Êx*°7ÞxÊ6Ö½1•ªÏ™öhýd&œI†ÌxN¬‘ š©àZ#¸;0ã Vj{ÆlÌ¥°ØR$±-c„Ÿ„öDW ÌÅT^ãEPÝ^7t[ÑK›Ë  S{‘³“Ý¿ b•…í¿Äú]‡“h…S® èÄ1?»A ëZ ‹¡­Ü‘I¬r¢µêÃÀýï|þÁu¬¡F™z¡:@çRˆ®‚؃³íåZîx!wiÛ]‰Þ›Ý]Çx_µ/œOl÷C{)ÄŸø–¿Lçˆ@ HœN© xktv>à~f}¾ßG}Nâ;ðC¯Ž*ÐG6'EÂøá˜/qPn)×\ÇÁq ºeèVö®ñºyMÁte*+~ÞÕõÍ"8Lá'âcå*Q¦}°[€AÄúu8$£If”Ù†úˆÓõ€â8^2XÒü¾ËNüB¨F)çQ¤¢ŠRáÓ=B_‚“¼’3< ·M#§…ácóÆ©óˆÒ; 8+ÀyÞ×4¯6ÏÅ8@îÄÚ{…¿öèðqÞ½XâЇ„ºu]*”€_<‡¸âÞà…s™ ÆÊž DÑ'×›'žJ˜A;ŽËi(™¼úÊãº,(„ˆn\|\ŒxdèTÔ ÷Ý eWÿÃ}œiî´ú¬ÌÚ¡›ù’"sj$gî6“Û1&ÒvKÊ ®[YŠë“Dçë;1C¯OLÞ‘@ÿ8ff¦§¦‡`ûÍû¿f’L¢‰º*ˆ§O~ÇHF1‚SñÀ¸uËi;WCfL¤[ìDØŒ7#G'raÌÙo<¬ ‚KQ”êJm4Ùž¶v$‡#Ï<µXÜx=ºBî2ÓÏåÒÁäçÍv[6™Ì²©mæè–ÉL(u-4™‰^«ÏåB·:ž »s)’H4Ùvk2šH·›#QM—¿;Sº/Ï-Ùè=WSUê}¥ê¼ß]ù¡‘l³ÃcVkÖ } ?ì’,šNFÓJ{{*V-‘c”áÞµw…mE3‰ö #”I‡[BR‚¯³ýûÖá8­x}Îh¿aF'’­™x$À}A4gµ& ÿØvþ‹sé&,ÿþÎ/‹ƒ4‚'~¾±¼ŒŠ¢Èó.™2Eòán´ÎGßÜäËí^]¸o-ÃmìtW t<»ª(ÿ$w§FÚ‹áÅšÙ¶%°ot,mzðÊöÊ·ž©xíq¨†}½LòËD$„ð¢È 5úqËZ誀ö%ÐV‡™mÃÜ\v§«¸k"$¶v-A×Ánd^ tUæ÷.η?äo_ tÖØáÚ—ž(.UÝ*'H„y‰¤Q?Ç‘MU®ø>48R}ôŠp˜AüЯAä´¹4rŒÀ1 íÇ¥Ùniæ° ýzÐ'ÊÓÕótZé¡bx½ku‰¨>EÖbkŠ>{Ù[WÊ©’[è‡{J ›wüsHpνD'xÁÁ› ¢Ð/Êh$ŽLd$="ô Øû‰F¦S&EÑã¢Þ¥ZÑŸu8'À9ÙÉ}LíK(ÛDlg=ù3³+\>‰#D[è%¿=ÎO_¸oì¢þË KŠyMàÝLÑØâõåÚôYïJpª€‹è‚x€sœÃ’[í÷bÁC\,€ä<)àDÊŸåà²ÒºaÂ<2#*‘Ê‹ùO>mÅp1;ì±­ÃÃ]ÁÀr/sû¤2¨*¡ªà¯˜/¿ýÖ;²+±Íg­D0m4§“­V¢uÌŠ:[‘@aM›cé3b«ÁŠ7§[$x5/â’Ê2•¨H/^rÂã4?[8çïl¾ß-NRä¦Cf¦¦f§§{t­D(“ˆ*h;·=`1 ýÙ¨G<4Þ¶Kì̦šP#ÎOo7ZɆ 'ŸWù"]öSAÕ÷ú5¾¿|:òÒ·eNcÿ`¿îc›8ï8€#!YŠdétztzôœîtgËy§ á%/Z mÝV„+4(1!ñâáÄ8ŽíPZ´i(b¤@ÞìÔ©£-¯!…6©•˜4 P¬Äï÷bǤ4ß~g6mÿäT i֣ȾØwÏýî¹û~~"«,,¸};`šíñq÷·þô8ê·ÝHzôhk&Ñ6©ãô¼˜æ©hÓDÖŸJÌZ#ÙD@‹·ÄÍÉôþ°Ï{ ôÁÝ`N?بÇ0¥”*"ùaC‘{oåÒJ„6Q¸‚ÃßÓÒdl÷„†¢¶²XOûg] ­9—AŠLF[Q™Œ ó?3ôv1SENfvÅݸ8–rëÉ.¬2Ѷsûr‰â5êî^‹êȦZñ£f¼ßdS^$–B‹{qŸXŸ—­œ|ôá3Ù®iM_GwLLþ|«u×ÖUÂG¾]’‹Ñ!„ðeŒýzý¢É@ tb»ZÁZ+8ŽÔZ=lÇb¯þ7EjçªFÂ+b¾×[j¥%.Á…OEÊÉ”sò<˜$º(u1©˜£*'Iœ„›¹›{×B'Rd–aMžFj £þÕŸÈX=‰eÚzè\g×ú$XáµX™_¡÷ZvÕ•¬ÛØÁ&•;xærîÄVN;¡_È3€@Ÿ#*ŒZègÔÈ'íp¶dºW¶ ¿`Ð+ÂYnK“9Þ)ü©ƒ$?tíYΉ¼òÎe…DfOdÊsÑ£8«Z?&SÇÏp'çp'œd–Cú]yuàY$2ô*pŠAI…a†.Òy7Yì(âÙ!”S¢4¸æßÁ Hn°©O1¬ÿÊî3ìS×Õ»gùj»4‰§6S·¯›÷f Wdge‚R@i©Hm¥“—PAü·Ö¡Ñ!vãá³þŽâ{:ëã^åá2oÈ(ƒ2\eð ҈˜…œoÆÖWŠœS@ÈxkíÙQ‡NÀd‰ÇZ2™`Ró|aã»»ª(ŽŸ½Yx¸³öë‡þGãû ÃH&iµoV ¥h =Àö³@Ox°ÍœùÑ×j$BØy%Ç=ÑGžL&ài\)Ù9|,3JW¯ª©ð†Ìæeá-ïç¥èëÇzŠ¥„,,+øû}– ¦ÆÝéqß„Önj­/*Å04Q#˜˜Häø~3íÑ‘Ÿ5Õ-äÌ)¹@Å{™:DŽ E'º7&b‹ © CÄzŒ”G×vg‘oŒ÷Œ¸µlpñè‰V h ÇYë(æÕ5oR;ÜÖ¶Ê%Ù]Ôvñ÷»3†ûþWß_'ªR1áT…Ú§TM8çO6ñ_~ñ‹ŒéÃEûXoOÇšÒÚwPYÒMû­i›û³FhôÓÆÏ>Þ©¥ÚǶŸ:þS'µ9EYì}§ßŠ%Ûôtxdp«J­ $Û¿þ܈ùŒdãcýVk˜5¼8pJXØœáÇÛêekšÓƒñ¨×4©TWw÷†ª2»Ì«Ø!óN'QEÆm]Hx×Bd™®%ÐQ Á:c»ººAp tþw ÏQ”<9´fßB·³vs^%Ž#”J F˜ÂÛ6,oª2{ª,!ôñЋ&Q`ÀCòŒé—`X!N¢pZ„3…ÐG —uo.uò¥£¾…>qMö:~»ÍQ)2W[€Pÿq©ÍÚó)¤Žë)ó¯žw¹£Î8àg]0Dá´bí· HNK#ƒNT`X²@rÊ}¥ÐCpËp#EP-ÂǶ¤"v$·‡Ó×0ô‹`L€ÑÙ§ÿLãs®ñp‹üítáÞM|9g'‚K%ªLT'³—Ñ"Ê«çý¸Hà÷亷”gcüôE´D\uÁ×y¸Îf¯ŸS%K¬-Ä:©17‘%¸E=QVAEÂìØ9º»x~w*È>ÔB6݉ÖD¬ÕH¿o5³¹®tÔŸÕ¼¹¬'w›I?º;Ù›šzÕ!?g^yLcѦŸ>Íæ‚¢RL:‰LÊ~Õ]­™>-Õ8©'õ@:Ú”Ó_˜FÌxÈLzL̓W_ûqÄãïêºçáƒoo[ˆGg £_tR™nóöZÓĵÖ¢ž ÓmÄ['ˆ÷êé6€–h6ÓMÝ‹Ðͦø÷»¨IÛ—Jµõôldd¾ÂWÊ<ýÝÐöTª1õýã+ßÁƒ Lä%Ê©Yàà×ïÝ šF0òfRA#îËè-¦ÖŒg{\dƒ=‚Èd÷]Ùµª\x£^Ò“‘œÑœxäõ5¯íŠJeEš·a­T¿XTé|™Èjç†÷¤csšÏLxÓi·¡‡Rq:Ù–LxÌ”o%œÕs¤½Ô1¡5ë ÷D¦óúåý?Z_Ä8â )¡v“˜²É%]ÚQa©#R !Ì‹jèZ¡%ð^M>ÖA¸Á"å?É275ª™êÚòN5^+J#‚€¨wñ*•¾DžTR²gyéo6¾öÇm_¼S•4ä"ë «:*­ ×Ãá<Ï^ý‰ÌÍÄåT ‘EÐU=ÝU‘üÇP%«àýÕ“‘U¹PÝôáйØúò‘5ÐU‘8Tsì¥K'sB S‚˜TÎtoqiÇŠ W°F¿ ýH:£FúÊ¡¯N)„F8kË€ gØ£ÔBf牳Êiû²ƒ‡aöì¤üQ“²Æi³Iv§ ^þ%þ\γ§²å &ñ¬ÖiûKX‚‘ÒÜIñÉ9fñ£·$( âG<¨ƒúEk ~†Ê`ß ZeCYqJ”zuÞýA\³ÃΊò¤‘i ÄÚç'üô?Ù¯ûØ&Î;àHH–,t:N§;e;ªšç…¼B€ÒRh©Ðm´t…„Ī›Ç9Çq ˆÑ–jŒ6/k;i“*—&$ÐRi[«­oSǺjM›øí|w¶“Äöo¿Ç콩™¨Ø½<:=Jž<Ï=÷ØÏ÷ó\g¾¸h­Í£Nâ8†—¤³õ½#ipƒ1F9äÇðn㛞<õ ÿO‡Œñ0j^¼F"\¥áM:Ÿ`ðžÅú5ŒSdšï–v7‹n[ȱ•vãäßd<å%c®¤"ëážhd‡®íKDñˆ{õp§t%cƒZ¸[מӢ­èlÙ¡ÅZ¢¡½¸‹"cîºõ)m‰XK"2 Eö©¡VMíRÿñc`zJ¼`AkÚì©™YLU’­˜°ß_ßâÊdæsI/ÌÍv½à´Š¢eÇòõ†é/ÏÆ=$îuÏב6Ũø5UMá›w‡ƒ®¸Ò–HÆÜIÅsÏNmAcüòÂŽ:/Ò¢E²2¬Ñ¾ÜråÒþPh@ײajJó„¿nÓµE§ÿÝJ4ÚòÅç¾’BÄ­¥ÐfiPCíéHÿ|HNEºñ#=9¹{ìÒž±+ÛxHâ/Ra =Ú¬±79Ù«Åö«QO,Ö ·é³žÉpÛæZYꎿôÛ] eoœX«¿e_…׃7ð% Ë쬱©vùèo~¬»fbÝñ¨¿A¨¸ïZ©h§¦º¦¢­ŠÖªGÚSª;rFtd˜sú+ùÅ#[D‘biÞ,špS§$©’]úÒ#Ö©®:Ôçò¢Žœ^‰Iîwlýgù&üøjÁ_𠬆>Bï*8´Üð­%ç_r#ô7‚#¯ ü•@â¯6"?|´iùj µa…åÀº‚¡&ó{OØ8Qàhµ &æ÷{KÁS¾z¨J0Ð}«õÀzð5@¯¼•dÜ èÃË.ïYû«- ‡7Ù=V—ê+"`Ãß÷×¾²±ð›Klr\ÞY“ö–^|¢âÍ «ŽmÍÿ]KQÆSfùàk„Þjì-‹Èñ¬„Cåà«oø·d½ óX?¸zKÀßžº,ÞÕ¹gƒUà-o9Y/"Æ*2;o ®‚> ýÜ‚Ê%¤â­!¡?P;ç¯ÉúkÀ‹S÷çÈ „Y—”W¦V€×ßïUþo½ÔC_j>j+ÿáJü~1¼h53gáDqm1õnw> Yᔕ€5r–‡a‘mpëœC¢wUÊ)jîgùCÏäqб˜Eû¦qwÍ’úèO[jÌRû£†… È ¼N½ð° ±F£`2JöÇ êOm9l°0ÂÁ°@øñÒHlúNÿh˜Ü}D ÏvJ€³¶ôqëÇm£ð0`fíFÎZ”oü#¶GŠ0ðÂÀc£sÅf˜  ®³0¨@0£~©ÜdÀï;/=°~™á>ÕUt‚@ÆÂ–—Py¢Ä°’T¾Â4uš#r@¥\¾74Â’¾AÃu:cTòJñÆ2‰òŸˆÙÖäˆF©J³ìÔÃûgÃ]©éEï{ñˆ3¡¸pÃ+.5Ö áѯKLqÏLwg¢>ÜÃ¿Š´Et×_>÷6(³3<î€y$C¹æç0Ÿ†¹l²¹¨Mã=^¸“¼ßå.B‘ìÜ\ê³Ïþ,Š"Ë0&Ñ„Ö==´u&rtfª}6¸7kÕ´Ž„ö¼qê1'P*Ù£EˆI-BÒP‹Ü3̪=ÁÉödbàƒ÷ÛŸÚáL™¸|‘7Û%£Ü½áÓ;ñ®™x—r'cžX¤ã^w¼q~§™£x†“å-ÓáþÛñž™)Ïmµ_zá'PÕ\‘`"8Ylÿ ¥[ :“z'"[ uÅ£r4äIDÝ)Íœn)žá“MfÆfø¦Í-Ô­„ÚÂ!wT ´ì¯hÁ$,#œÙÕ]¡`‡kG–'£þ„"#ò¿kÄ‚®("N%Ø~;ìÖ']súÀTdßøÍgš6™Dš51f³d⺄£wˆ¶?®õ>š;¢–§ ä\îËe÷?†¾F°x*A^ þõ™Ck²Óƒè¨rÒ£– d x1a‘¥à«Ê¥[1ø«‰4úÖÀÀlÄ6éÞê2‘yFâí¼Ä\ýQøêHñV|Ù^Ú¿ÊÞQ#´•°-U4sãÖ¦½«Ó¾†?<ç(1ŠÚ&¶S½õ¢‚šÙê|qig°0KvUJçŸ\ahZÂÝOdi:Ÿ·/+~cû DH&P •Dý«à0j§8Ê·!Û· |%¨‚ÞrlÈÊÕDhœréB&Uƒ5Ä!9Cúru”R-xqQMțҔ\ÿÉÚ_o—N6™^~¬èôvÇÍ=ˆqpí¼»„N~¼ä3pÿúß ÎUÙƒõÆùÀÆ ÛòëMžÃ<PV¡yþè¶"xÑD‚68³ ^ea˜!Ñ?b…³yÙWy8ÏÞU#'¸ÈOžý›–6šÁ€ùdåM…¯?‹„(‚WòŽÛ`˜…ÓÂK[iA’l."-rÔÁ§¥á]üeç `Ø §8‘<8—Gd2ÄÀ™?ðOCœä HŠ,p®Aò–K´2FŠ-\ž‰_Òh£>~Í7ix›F<H FÇß00aY4&Xò£\eáÆóNº„baévÇåÊ ¸N¡p’ãìŸ~ÎêØ!ô–¹XXRÈ,eŒ%µ ïã»!ÂÕÿAAw{Æxx+Böš0q¢¢P`YL2Þhá„sg¶ª1WRw)ÓòL¢-¡ø»ïi!W¶‰óŽx$$K–N:ÝéN¾;9N“焼J¡+]ÉV^Ú†®ÐR 3© ‰]ljóRÙ¦­Œ„@`[Ëh7­-퀦„²MÛ´­š¶ªªVÊk^|~·SÂ[~û=fÒ¤V•ˆ”Žý±ÓÉ:Û÷öÜsÏïûyÌó•záq×õx7¦B-“¡Àþ¯u¨<å$*ÒÆ•9çGwÄC~|+¢øžÄ[æ-mC­ßøfŽdÈ‚ðóã['LvòT¸mÂl ¼T´þNdEâþhÄ“4ÛSs>?>®XÈs=Áš–Žù’a_8Ô {Ñm©ñ½)Ó;ÜKm¯s:eQ£Šö·ßïH†ýééÖp´eüÚÀº5 5‚F²I–áág&Âñ8ÂÀ.bƒåk¦•8ãnÔ3f×ÍPÇl¢{ü¢ûÀ+fÛU•Zm¼U•ì<Õ5b=¸ƒo%XrõAo ‹¶ÞºL—ßÿºGœô!3Êgƒ'|5Ð[ ÙÐWq‚AŒéŒma»•AOYFYUЇI]ÁÅÐ[˜ø¸Ý_ =µœv]‘T¢ ÔºÿëØá=•ñŽeKtJˆˆ«Òמ^Ì¿«ŠíÐßplC¯òEÄâ\fƒ¾Ç¡³p»¿Þ*ó8©š¯j¹8R /‹a“$!G tËëËná=AW1³A°’ÝÞÀŠ î†Ÿ>ãØR(TKJ/nqjW‘º°j2Ä*‡žòŒ¸ª ·:£—ªLK+þýL[f³†‹þ%Ï–j1TA,­”X7r‰°ÊÓgÚ‘%±Czœ0P9¸ïÝú¥µ·­ý±†{saOÝG»–»Ê(%HA"r6Çc)¨+ væÜB EFtá¨#êÍv8–›QÊWhä¨È•Ÿ¡=ô?zsšB¡d%ê‚æR+ k0Ì£Cà|¢%¯€RU´©—œ’å1Ȳ ¨²¶8+ü}GÆB6Άa ©ì¨£2 Qv’!™ù¿¢F†2 ɾ3"¾Þ*-Ò²9º@ç³í’QŸ'„~)Á¼Ëè¿£pN…÷ É)yî@ÌÈ0FaT„798ÏÝ:£žxQŸ>Ià4Ûál/©‘¹<‰/ùîM…áSx!rb@«ÕuQ\äÐ,±ÓÞ#ó¦lúê6Äc<üÁØ×¬§ŠB”"C¼rÙ…µ+ L…\X6çZ÷b“Ý K–YœBîLš” n_ ¹°tßJxN¿õtUÁ ‡!ääð:¯R”HE‘«µiÃSwC–ùãÎíÿ¤nfûÿùâ2 ø\ÞþÍ)*P]ÒTÅFb§XòlXñ òùÁc.›ÝØ#aßÓ“÷ÞŠv_‘(ø ö—‰ý’˜·@¼‘ð¥Ã‘q î®hÄmšîÆZWʪ-ËFtƒhÏ>©%ãþdlg,Ô5wÎ×u“‘Ží}Ô †þæM‹§¢=f‰åþôÒËE!WίujÑpoÄô&BÞ4Jl®in¶ágdÂ7u¥#ÉTÓoÅ\¯mކ‚‰/6ᎌ{¿Ú¨ÈY„òžæ²T$89ùÄt—ˆù®\êXý Í X'³ ÏŒ¬I¤{Ì)ÎÖè¤k::çQ6×Çcèª7q'M_t¢ãÿ4?ñ­\™Zlr®Ê‹Š‚/ŒuSøG‹3“AåÐëdÞ_ ^Õwºª¡³Å÷?†îE#]£›*~°ÊÖ´6r ÿRèÇF­ÿ Ö´ÎR–ïÁ è-ƒþ% ]jöÙÙ½4ã®ZÀüõc{+vÕÚqÆD‰*ÄW§Bßr”B/z¦ö‡Š€)š.¨õv ú«?ïBÛA°ÄUbwHìÏlIúûwxÚfžàrœv©¼]å±Ë'pb‘¨H»@±ˆä u ÛÔ„g){øÈ¿<ªr¶ï‘Wõ‡s-<µSä®Í°¨'k<ÇU*–á¦å3ÁЇ ¹ÛA5ø˜=°ì¢•ì$ø{0í¾šñÝõß. ŠbàýpTY ç-Ï-„Ïeyc)ù¤µŒ‚-ê,AÜïnýòZÁºÑÈ YÅú®³üvWùȺª*E3/«*T‘D™,8¸QaŸÔaD†#„1à0ÊDAÇWjä'À)pP‚#Æ­#9W÷罤þyÀ€!ýæaFȯ[óPqøÜÊ ïÌ&îÇòk*„'ê‚xt“ ô ¡0$Àa‘ùç† ØÕ‡389Dá0…#3É 4;ŒXÒ_kæ%|ã4¢ò9”³¡ð>?çô?C`TƒQç8ƒžáà·”IàœçÈè>¾waÊŠ½ñ÷xå‚ë'%ß^á’ÝN-/¬åiæK#§8«Â˜á꬧¹Ø{ŽÆ*M”TPŸÿNñÔDN`§&<ѤgÎ¥ÏôÅC^œH&cxlKtj{*ìN™¾¤é½ð×]Ï­/).†N©$ ÄfÇý\Iå*)6ìG‚#ó­“'1d¿˜º™å¿õÿóË™7ªëêUK™ «›â(å EÉTQ•ãÅ%Ë´ï6ÅâžôÔÖë1–›áqW*²;eݵǣ¾y ¾©öèxk:êIGwQŠÁšÜÝHVy¾põ³½‘øó‘ð¦TÄŸŽì™¯ëF&=Ÿ~0¤,™Ã¹Ù¼±ð··ñ¬X‘-ó µ/ï©I§zÂææD¸5aºæzþt ㎛žé¸7Ý91±5ôöÉ‹55Ò²Zu_põÕ [f¾Ë—[jœT©]´~üQËt¼=t¥m&噼ºmüR÷šm²¨c…4DáÍ7^ø|ÚŸìN…hõ¯[#Ñ+ÀI/’pÿâWOååh"Ž?ïÔÊIr‘HޝÊo) ”Íî­¸X|{Oå,†uW)˵`-ô5 I è¼ßt¯QÃs’8Õ¶ºŠ €ñꄞ¶C°Œ­H‘Þ*æ±_÷±MœwÀ‘"E²tÒéôèÑ£;=§»³ì¼‰ƒónBCÞ…²´jêÔ@(ˆ! ‰g;v[»©•Öò–™ú²všÖjK€Á6µš˜Ö• FQ7 /Žßâ$Ф‰ûÙ&MÒ"QÑ?v:Y–}Ï=owÏ÷ót¯€Œé2óÞ è©‚` ¡Ïy¨!K%2¾Jœ³o:dÖCw‘…þòOn©ž™«à²¥k‚òîó9,†Þ%3Áå¥\²Š"æáÊ9eŽ[©‰:oÙõ'å¢Fð ±åR¥±„|ÞŽZ¨º½¯xàÉ,ÎEETíLS‰¥¿>×”B§à`õ©o9‹xF†,åPž/Šº„‚ ª,+XWmBÎ4¦B5Ðã4çË_ ÞáP”€×•f ŽÌ 8!˜ :¾.ËJ-V*â©‹™NìTRDI‘DIãVQÍ…eÙ–ÏÛ×€¿n&P‘.þõ:SÈÌ¥±·¿üÈæ<è®Ù•×èd̰[¨!VÈA²m(ÊüìãpH‡Ô´Á Ý”ƃ4r"MÄÒeP ôˈ8,ÀÛÆ•Š3ÈuÜ_®ð=kåù“Y©ÃXĶg…¨Rï™Ð™Yä¸ý’É~+ gö'ˆ’fVt„š Á*$xq?¶ŠÀöîn…ÑP™.X,¤ Ée Ÿ¶ÃCˆ .`Ž3øPXpúŸÃÐgp–Á >’á¼ ïËpQ@™|ùqKͪʸ¯µ“ ˰â+Äĵ%~IàqÚ0S,9K -¼Þ¶‡˜mø{$¤&ÀoåË?vÊ’ES윣I¤_¼³1îü"áÞ¼Ðuodtsr¢+öÅÇ<¸&"î»ñ·¯ûuLÍ$$K“¬V"hLàL¬++x»é;W6í|¥òq•H˜ŒQ—Ë5—JÍÍ}9??w?sS©ùþÿøcB?ú!¡l)ã ŸÛÅR‰ûiRÅ’i£ªZ­²U•³U6nÌ¿úçæ‘áÖÉä¾dÒH´Ž·$£íɈ'ëa¥^"²ín¼+>Úq7Ñ¡vÏLûâã-·†CgÏl{çõgbaO2Þ6ï4H×êw:á¾íîö8­ w%…ÌB³5\`3­Ì¶~uÙÍí±ÑŽdrkl¼ »¼à4õM$¶Ç'^ˆŒïm›m¿ñwC5áÄ)K¶¬ãNÓýB핃gÞsÛP¢º«9/<â¹—ðLŒ¹'ÂíS1ßßoúêªVfÏSµ7žNDp|ö"Û¤¯X#ɸI‘k×[v´”0.—:Ý`š…“ÍKÉ_·ÁÁÇ!P—ò­Jç—#é.ð=¾•Ðé\ Á²yÌôGCÿ“FüåÏ.Öm”‰©`ùUÓ²é 5í,‰u!3VB ÌDEð>]Ð&KzÒÅ-Èü+T>ÛSòþóÙ3 F \‚îz8P–ÖH=–iPqµTpÍ”xC6ž2ð9¯ì¬R9S%ô ëªÉ6-g6i «~¿Ã)"a‚D¤góØÍ®*ðÔ˜5ö9Á¿²ï©bY$6Êí²¥.ßnÂéûµà+t”Ö[-¨Ê—2ªþt½é¥YÙÏŸÉ)WÙnÕ%Ú˜%ÜòTA_x !XkEO© -DHoYš(HJÄX^´«úIâPJ´ÜLI¯ËÒÞÜÿñ6ç«OæÕØMÛP¦SâP…3àø/o壞Öÿ:‘ÇÝ¥)l^/ °ÔœŸ zqf‹SþeðÒŠ#k ‡Â4¢ÑÎ…‰–ŸnΓôkpTJ pL} FŽ0óÊAd 1er؇ñb,…r0~í#¼8GçDá†dùî:Nr”á˜Ç) ä½Õ$ͪæ÷cÆìk² A+Uá5–†ÇU''Ò @ö sŽ2$‡?ypœ a^ß±ØJ©L¸®Ëªhε(ñžn‚ä"ˆ™àµ§ÿEÔˆçT8§˜·B“ )pž  æ.K›*á"’ãý$q^~³C·ë¢Dv=!üí,q„fq’Y0sŠ=4\`ð”æ!†°_:\b}n‡&fàÓŽ[ g–|ëZûLÔ3_ð®-Å$òÜ1í{÷|‘±ÞC…v‹Ì9†&W4J©Áä ®¾¼®áJsóÕÍ“M{®mÚYE‰Ä$™Ë “û^zÒü¸’T*uÿ‰òH³ÿkwLE²ù¢$Ù)‘uQh­]ôê†EÇ6Èm«30'5]¹&r›bÃÅLרÁ¾ÊO¯úÇc¡;cm‘ØÎ©‰öè¨{*ºàt~Ð99±C¥»'b»'£‘;íÉñ}ɉ}áѽS1ïdÔ3ñŒÝê˜Jz£ñ–‡¸‘Hk<ô{VY™`˜¨· 5¨úZíæuo<º=6Úz7ˆâÿ‚û ÅÆ½ñˆw2ŠŒyÂ#×>éî[ã*aªœ¡Qn°Å*•4&®ªÕ—Ú0‰l;ýì†/Ù› w|‘ì»Ýµ}ò§=Û¢·N®›L¸cá¦éäŽé¸7íüª5éýÝ¥­kk•0ˆì¸Ž.¡‹ŠEòJ•>æ_®Ô÷*¡{E::!˜_ËÍ/ø‹¯ÂŒ3LðÞGAæÇ¿Îþî¯ÏG"ÈDg”=W½{eöúA3.7åÞ Ô™üØ_ =Ëç}刊t‘jðV˜]V¤ï³5à­þãö\MÒ "` qÎgºj¡¯,}} ªïz* 9î°(n£ ™zqK×Ë .Kœèª(|ôíRðUÁþRabVþ¡É!2¼j(bO¥bÖÒS>(žóçAÀ1ì®rÈ¢L–JbWÕ_¡ÙNÿc?Û`>Ίn—Ö·Zš ¬F)A›±öÅ:«Æ,:S A<½¥8¡{ôT§{QlN_ "…A–`3ÐQ¼O[W¢œ©¬‰„;˜xªéä×{lS×pKH‘,Yº::::ºW÷Ê÷Z¶§M‰“@$P^…eˆ­K m€ BâÂBb‚ÛI(µ[ËhBâ$t-RK·¿6¬hšúצ©Ý¦­0(įØNBh;’ß~Ç´“¶ iTT©4ëȺ¾/ŸÇ½çû9ØÄfzIâ;XæÌb› Õö"ÏŠ »:ÜÂ3ó?Ðÿ^°g‘¶žrºE=ƒåpx)`OÊ»¥<Å[²­VŽ2´¸¸NdM#Ê‘UòÄ«2¼“5;œo‘Gj$”à RAˆF 2úaæ´õõ.ff’&QEãûËž‡ú".aŒa ¼iˆóGÜpÊÞµ’t­±¼ßlÿôd¼ƒÒ ƒ90 Û< «øP _— –Ø ¤À0ztƒÃ‰›7lDo©Ypï7NåpÁuç¾^úK"ôǸD`L‚k Fø5…«äèóõæTøèqÆpå]¯ª)ZžœiÕ-OËV"éYÙÎ=9\á0jëÎãFšXc.ôRô¢»¶8Ã`œ‹äzygÅt ·>ö¼÷‡o{f¦}‰ÀÏßßT·Ñi¨Ä`N»,EVË’3½+k>|©>¶c÷­Íž;/ìNmiù¤vçÏÖ>—˘…HøÖç=F! ’¹¯>óü߯ÏÀ±×pvã wà"Í%Yú·™Îl4½·Þtv…éä&¶©BuJ6f¶Q<ÉF8•©¹¨€?¾>?–L¶Ý½Û0%ÌàyR©½Ó“LL¦Ò̈R‘ŽTÔs/åIŒ{î'['£ÍÓé¿›JˆDDã¾'õ¿‰pÛdªu<ÜžûUSCCi]]áöåCCkÂQ_2é¹ïNE'£¾xÌOí|ÜûOÄ‚«Û÷T߽ݚJ¶¶µäù”Å¢íñD÷{ïÖín,àLR¸cø1 .™S»Ê-¯y6Aƒ5OFñhŽE|±Xë­›ûRác‰ñvìyìŸdÄ;?ðMkddðûy¶vE•™Šn5$V­JgšVˆ•oOél§zÝ̇`‰pH°‚˜\ÅsþÅs¸‚ÁŒöÏwýñ—žXŸk£fÆeIS5bÍ”»ÅlÖsO¯‘&|+ €î*ÂüšChaŠu¡ÜàÏ?%}_ñCM+²S#fU‘-LùtW>øò Pþðaô/}»Æ¥Úˆ…P;eµÅtäo^Ë®¼rm:«fñ¿z 0"¡£äï»J8}ЇÂ3ÞØèÕèÊ…žeØÏà_]kÌD¸d¨f›Dçz ÁWþ•/f˜;%²Áq"U·ä; 2^«ÑÎm,øéô¥„9Ë×É;’F°…Äòc—á=,?}Ë¡·:s®7TPU·JH˜,*ßZ(÷púªà’;]ÏüöE ¨•sÝK¡#ºK§¥ó=ÊÿUP 8pH¬CUB†bDò!‡¨†n¤&¶½[ýygñëßu©2ç²E#TU¬Êײ} EâQD6¨0àHSBˆ *`°"> j™ U_,4§NÁ•Ód6¤Í8aqBa ]ŒÐŠ*»Ì$Ýbn*!ðÂ-§8ài#ª‰à‡§?: Z…INk‚"} Œp¼|6äl_C Ó(Ö]Ça6ûj \Ô1¯áŠ‚êøª¹¨Ì5ÉÔ±Êtv“idƒi¸ÖÔ_g®3ÙlúIåY’n¶JRÃ…Ej*DZ·Êñ‹³Û1_jÊ3žhLEZgÞ‰ñæÉ˜g&y0mMÄÛ0%'#mX’á¶©˜7û良Ñ;{¿éôü¶•¡Ð†,œò%ÚØ”ì^)J:úÊâX¬)•òŽ{þv³9ZÿìrÜ/æ]6¨….Ì”o|♊øRáýÉdËxò‰©#ñ$£žéDÛTÇ¥-9ŒyRñ¦X¹ë™ðÞ홸Û0™jÿø/Þ¦}%VŠC¸b@ëÄÜR¡Ýþ!Â#gþcå?Jçât’–ŠÎ%_nã~±ì-誄Îr⽋DŒúÝ‚]¥sè £#¥½k­H.…㔣ãòÇÆ$•ÛeÊu.Ù™¼ÇE‡Ö‘ŠYÉäá2è]&(Òµø‘õñ?ƒ¬ÄÞ³«N­cõ …+üÅà¯üÌW¯ä€·¼*“Ú0æÕÎè;ªm 5”l¦’Ö*+t/‡ÎL,‡`6øË·½Xc觪±]n‚E~=eО‘zµ~‰C6g¨ˆûê|éÁáJ8‚‡ª*œªSæfÅÀw7›IT–¸*ë7˜nVd"ó…ŒYIæÐºð–  C:Š„d‚eÈðW‹Þë\*¼(šð./T,h'é¸FY•'ýq_)tc¦c7b ãS±|3B eâg`5Âì0X ôV‚7zŠ U5×½ËÄpt¦ÇÈ$ÀazXæëZ’®FÙ—ÏOO僎ÅáÝG¶ÕÎq]Æ(·™¹žïÞÚJ`([0ÕqJ‡ oË0Ì¡Àˆþh¥ 쳃®ø#«MÓ¯#0ìB,gdècpÊýŒ0f¢Ð§þè9Z¬RJª¨ ô†?íŸþ¡š<_†!î9ÄBðÐX™!.ʰëË>ù=“2[ )˜ÏŽ“ÛÍp‘Â5Ls*²Óe2j…«øMÄ¡«­”Ï> pM¢\>¤»ÈEU+òÌ'ö²›2òe1b1þI~ÝÇDqæqß„d“M&™L&“'3™ÉÎlvADY+ÐeyU z=«ÜµP"¾ð¢ôÔ‚°„eaOãµ½\ªVD¬^ûÇ%—æ4g¨oÉ]/Æx¶‰w6iUXö•W) û»ß³˜K./11G“NžL†Ýyž}vöù~~¨îð¶8ªâšøôOÜý384’F€Ë Üä_Q°]Òà:Ù["á–k–iA‘š¡ÑÂ6ìŒ8ƃžÉȱ@À 7Ç\A'M¨À¡© s:äœ 5ŒáˆÓjžû­§=/y‡ß,J ÞŠpDýE‚i hÇÃʺ@Ym¨´f´¬f´¢v¤ôÀXYíwµÊª¦JkÿP°MaY³¤ˆDRxñù£Oç0‰£ó Ï¢ËH‚e<æþí°%¤áᨩEZ¬dÉ3ëºwéÎnÕ](Öõ½£û5ò¶®÷-ݹbýÇ%L[¼Ùj zÉ Zdc¼Q8ŽãÙâòœá›õ3áCÁÉ¿¿j&Ü4èœ~Ò6l8GüuÓáflS¡¦é°kÜßò5`"H–ÿç¶·4‰“Òqìšd"à ŽîŸ ×Lê"ÏX¤mðFUÁ†U ¬k ™¨<˥ʆî¢5³m?Oîâ‘_Í‹iBs$v°àõdÓsgÖ|WúÚÓ0Á›=’ LX´Dúl×Ï)Q:s›R¡Õ~¹ØÊ#‘M kBƒH’€Õ^N’0PdþºjÝDëF8¶Ü+¨m<8Þ0Žlzñ|6lNUpOTÇËì‰BߨŠYÑœnNæÒ;Ãó¸W›R¯',Ô×äòV%>bF΢ÊI¸3&­2Ô7äýå›w}Á£Ÿw6Ø8¬}ÿF[(ˆ©Ã†(EÎŒ7O†žƒä§Ö‚ÁFÇ{vMeXÖ ‰šª¿{¯aÔß<çûhv¬s2àD ΑîÁ‘<ß½Ó”¤E— Õ=4‡} Óa÷«šÚƒ Äß0‰µ@˜‚dÜïštÌ9æ']#Oœ¡ ×gŸV¼f29A%¨UcpG²øÕ¯rh1Û±ŽgÍc ,??þ³ÑIeŠþ‰¹Öë·¯¥yçÅTM…ÃÙ‹î7ïìÉêÉ“*Ò™ ›za;fèàÝ žôQgJ"Ñ[Ý/ã #‹HÖp\E†Fs¹+•Fg‡5–¹všž´ Ùð?¦Ô¸^Áz*ž“UYsçkÐË8|/žÝyðë h^Ÿ¿RB£j¯òz,Á$N]¡0àÚ­kÁûP×oU$› ‡#Ox=ï5ŠÕ›ÖœØšú~Í&1xUÄ“4ž¹S•-hTVnq2CdV䕜Þ_—9Ù™êH¾[©þ¹$åý73öešvÙø?KÁ†%t­Cs.¸³O%­&Œ‘% K4MXR’jüþ¸½ºMЛg$è ×ôBô‹Ð- :¢Ý~o‰áA„s2|l„~õ¾‡Ë5V‰hQF’9ü2WÈ==­Â9åójƬ:Ù||Kôp‹ŸˆÐƒ÷±@œÆû$!N _l‚> zNq$}ZèÃÕÅ6ƒJâ8]¬¨\ÜP§_Šp…ë&äa; £+8¸úò¹ÆÂunð1Û(ßœO³i g\ňF³ÀdÇs—Ž 7Xø‚…áø®2ƒI0È&=ÇÊï®ça˜À5®ˆ0$¾2 3€¶¹%4ãcªâSjâYÙ¨=¸w`2è öMO`05OO8}Êg#Þ±ÈA_ðàÜlGð‰ó‡ ÷ý»{K E“ Ê2áì$b–T±n]úÍ’m**}»¡rGpGU Üñ¸²îAYõ·¥Õþ ÇHyÍÈnÇ£íû¿Ûíðï©¿RXž( þØ1<<¼¾Ïž-`/“~®Àó^”ºdGÉvÂ#øþE~½ÇFqÜq_餓N:iµF»ÚÕî|6ÆÀacŸœmÌ+`06ÆÁ`c jš€pñóðÙªJ•*”„—ŸÚ4•‚’4Á¡ ”¤•š4m$ÔRbؾ‡ÏÆB€ýëo ù§* !üGN£ÕÝíæ7»³óýLŒ!I$žpº\èAŠlº „ÞÍBo¡Ð[ ôç §Ö Ýk„Þ|¡¿Xèß,¼»†þ|¹¡êv‘Ú‰Pc"NïÔ…¶#G6Ýi ÔŒ‡j=ðD†wO†Û&"õ¨MláÑÝhNI4Ø4hœu¼â†Ààà&CÙ)1“¡‹«—ª_}Y9Ú11V xïÜðLŒ5ECU"|""ã•Ë3™®2bU¯ÿçMô r%:ây‰%¡m°ª{áúh¸.®åo‚M# £#¡‡žæú¤ù”Í¥„QÉbHv*6¸mCµÙǦQ³¤ZÌ —|}žÍâw[À·ö'=èp”.n̾¹7ƒèfbH6‘¦Ë ÈSä©m¿mK¡Ã+'xëâç§›ëX¾Æ ƒ0Õ¢©¯¹T¾­nàµe!Àçú¬4^%ĆñnØ5¢‰ý,Mƒö®>Ž% |8„ÔÏË¢ í’Žû4\(¹‰É¢2E‰sà¿u;fl5¿¾"ÿUÖŸöÉ&'c¢9ì”y2å  øæC;¶œaD‹‹Œ xqìKgªJyÒšÎaÐîæ Òà°{Ê›2½ ZÍ)€¢Øï>º:ÉŠnReJ©SI D\Ÿlª_ÓÀqBÇST¤wæ«Õ‹Ì¿Ù’4Úœ;ݾü«·Î‡CN¼nS­8–ñ®Û—@[¿k¨ ¼D³5žN›ö î1¿ûH¸IÖ¢ëàðÊ¿íÊ^êQŒh‡jXKUõ¯›ìpF†œŒƒwtZŸ«‘ z5èÂ8J¸%z4.‡-r‚Ö®uU¢ »x禓Ɏü…–É“Îû¿ŽWEÃb·á„n ˆ™Î8xϽ1ð> GEè¶sñ2t8ŽòÑ9HNPŽ¥.ûí#¶¬DQ'2&3ΕŒ8òc|Iá>×à"™1É HÅNÿ Î[¹7.èpÁ:ù‘Xî62ׯØë¦‘^®Úžœ§×{Iq*qJb“e‹«Ùòâ´±%Žìô‹—§‘Ë\àRgnY‘¦‹t#q%y1‘À/øŠlŒŒàÐ3ñb0=óLšÆoï¾QýKŸË!›t#‹¦R&Q…ù ®òJ¾+ßy£¬r²Üs»l×èÖª`yõhyõ÷[+¿/Ûª¨Ø±çNùnÉ-üf[eø]¡õ»“Ý|‹À>&ëÖN<žšzšÂÓOßü´_O=úó•«2¿@ —>«]2.N }yBçZ¡¿HèÚ,t—Ý„S…Âéb¡¯Xè*âû „ß ]yæ_Æ®›Ç¨o°‚K!®Œ_CWæÚ>ø¬|øž÷n n|¤öÉXM(¸7ˆï#œ’hȃÁ:öÎ:^q»õïºÌ»"™cTf:1ß §A/U7ÿóÛÖ¬áÚÅ=¡p](„D9xóz몳Æ;t6õFFêñz¢î^V=‘ âÐiD ÇB»¢‘*ür,Ð|ó‡ÛJæÄ©²àP‰×˜*Ò çÜïȇCYà[€»ZImYÓm™³mÿ§Ì$“F(~÷t V»öïogö¬ÕϾ‘Ô²ÒóÕÌÔXjwÐX§Ȩ1áãm)Nt”%‰gKØ_¶;ßYÞ}8^'´¹¯Væd%8«…2‹ªËfY-OTØuk"ø]°ßÅù×±v™ÆPs¬ÂV;LßìˆÿRØ·&NûRŸÝ²–d~D7âŒòç€oçÕŒfqð‰äæ%¡lÑuÈÂö,>ü)÷Ú–½•Œ`¤” ™Q•X_aå0èL€“6è–Ÿ«‘Nz 8Æ Oƒ2ôÐeÀq ÞsÀiÜÞ¡@D;sìY¥\nÐ}¹~s5©ÀÉzËe›$Kºš IР%:eN‘nôÄqU8?ºîü‚¤k¦Ôžê‘‡©vjÒ©BdÜ„šR㬑³\ÖáÒ!~ŽÁy­/œþ_(pɘ ü¿ƒ\bÿ:£çÚL‡·[à¢Ràíkdª¦j%šUe«æ‰¥u»­§‘F>á5 ¼x¿Ï­G†ó HØõ·'I¬a¢Ì°Ëj Ñ?úÝÛ‘psd´æa´1<ì¹n¾õà®w"à?ݹ!ÃI“é B‹%’)æ_Up§¢f¸¢zd[M´¢i¨´ahGÝmþ±z¸¬êNY%ž TÔ Oî”UÝ-¯Æ³Áí5c¥;£Û÷ nu*ŠÊdMU1+¯\»öŒ Ó3í§üš†©ÇñXZ²5¢ û˜(mJºK…þ|¡o÷FÿF¡{ó3ôâ±X8¹‘k¤g£pªXx¿Hè/Nå g6mëbSãíñH4…áÅÆåÔJ¥M©WþZ{"£µã‘Öp¸ MÂA2¶7¬»nŒšf¯¸Ý{¯þ±:5ÁüɧÛúÎÛdÔˆè óçê55+Ò“ˆƒÆ8mÒ·Ú$ß}ÓP²ÊEÌ–9ڢƽّ±½÷õ÷ƒ Áƒ/­žñ:”a4èü/ùuÛÄyÇü$$K–,=:=ºÓîlÙy!ㄼ9¯RJBŒ(')òæ“PÀÇŽcš¡N}c¬4ä…PºMÓªM¼­tíTM­¶©ÀBºàÄ!ŽÉ Büì÷˜mlÊHhù£Öéä\ÎwÏ=÷<¿ïç‰x¡=ãÁÚé0¼/÷Õß5mÌO²ð"AŠšŠq±ˆ…›óž”¹@6«Ò‡m´j5,f×-¶=þgóý{aë-ic 7ZJÍ䩘K’Wd‹’€‘dU¤3 ¢ÈóP£ ªXú‚.zhõC˜¦VšˆeYAª‘×½½qÅ—M5)É&Y§¨:•_’¢éÜëP¨-‡5‰uE.íLSAž^ßYôJ‚ ÃHA`LAi$LYS– µËÌ‘C¶¨ÏF™ ^øyŒ5¬}éÔ“Íz¿Ó>Õ–A;Ó™H½q´+s¶¥ <¢Y/¨J<¯L~íˆuŒ{·§clÒ«²'æÈºûmysÌ´©¬½Å´#ƒì±Hf×½@Ït¬]¼!”NýÙ±ñ“{ä§ É¦ùÔo¥ì̲=ôf(Aì‚¢#ºxM±"s =zO£'Í´Š0( $Ý}Ÿ°ïÝ í5Ò^3펣=–´¥H&IRÎVèžT.5‹&=A³ú8Q1hú7׋ô„Æøó›Ú0L?šïVÚ‹‰ï%B?éI‘¾i7a ŸôiÌÐ2`¡ÇíÆ·ºŒf H¯|ùø]vÝ_¨ôªžEzÓA‰¢gNÿ+zQ —Íô x†ÄŽàY ÎE½ŠÆ~Ê;s…x¬aÙ S­2QT¢0g¶“€àx¦¬ÿS_ýäÙï»Ðv6 w§ƒ˜~¦¼Ûj$(Î""©Ù)hè–{fzw$Ô o*â…Z/œs¬/Ö/ê‘"¨²fV %¹sW}QñÚô®Ö £n´r×ÝÊÝ7+ë‡k\CUΡmu£'CHõžá*ç-GÃ7ŽÆàvgÐÑt»Ê9Q圬ráœê½³ Í[ÜAà–——ƒFææ—5Î?yÌz :?ã÷× †˜{”F–ÝÌõ–rg6r}¸3[vf&Z`BJHSUUãñÖÃ'ƒ¶Ãò0…¯Û>ïË dÅÒ$‡¶-âv¡-ó_9«Ú@€äÑ>«¥@Ñ0ÖŒB¢ªGEFýÑ"é¯Î‚×ò´x¼RQM‚áʈHë£#Vê+xÜ–õñ¶Î!—ŽË)¢Þ¤êõDȲ¡Ù«äùi„ЋzYbäžµ”¤ áüîê\;Ü3;°ë7Ú]iF#¬ƒ©E#LÖ^_eRójýt;›• C•õ@‹o«n¿ÚÜÑtì Õ¸F«šÆj\Áê¦Gãðö†ÛÛFv¶Ž:\wN8ôRÕxw[ÝøŽÖ?l­])ª&«˜ˆ„œ=ažE2>ž[l,Þ'Fp‰=#EO†·S¶œëwp¥\ 7°…¨àzʸÓeÜÀF®óÉé-܇ðç&örº„A¥¿,&–-l¨|°nŦ<’¨"›Ùˆy‰è1Tð¤Äžž¬;wXŒŽ‡\ÓáÖ§™ Xtü¿52Ñv?Ü}ýAÈ ûH¤ùúç»ãM²QÖ+«¨¹6# Ü¿×2=Ñ:5Þzìxi§óȸûþTã?&¦G^‡‹„"uÏ«=“cf'™m&Ǧ"Îð¨ç£I„3#^Ò°NF’`Ø_¨Þõ1Šø ÎVÅò==VŸWQo.«Û°Z\|~üWš0°¦Bºµ¥ÑöL¶¶õÚËí+–x^Ñâ°þç•iÑŽ<ê±ÑÎâ‰:M导©e… Ž‹¨ÏJ¦¹ò“°Öqñ¼F$ô³MËgty`F2-ïÎ.t̆ŽÅ_íô½Wù†›,óhÛ<ü—«²›¼b6Û|âjAœÖybØáÙÐéðÀ«pÃþìgíeg–Ùœ„4ÓêžÜç†PJ‘+©ÐÒÍN4j£<“ŽVû!h'$ÇàÞÒ_#ýŽSˆ¨Ñ }\ ¡Ÿ&O)!ox­œ©s(_“7£«Ò¹FÏ3]5âÖÑÎÙï÷hp Ç¯s&7;·Z CÁJ¨mÍjaôŸÝL¨£O] uNšEz9œÄN-“ïÙ¡ß4qÜvj}–sY•ŒºÅNŒ½oÊÉ >#pÂo)\§/œþ—U¸Bኗeø‚Áô€ðÝÜP­P"S+•¹”¥dDö2øŒÁÅYâ+×ÈßÎR›dsÍ’?êBº¨/M#¿1çh*.™à¼2ùâ]§‘[©ÂðÇD2n}høÉÁb·C±PŽë *º‰°…&ËñE«¾ÙÚˆù˺›ã›÷ 1°Ý]_{gýŽ{¶Ý­©½³©þ›ê¿Y·†¶üðÁú]Ñõ»îoh¸¿¡>º©áï[ê¾Ý¸kpcý­šÚá{Þ¬\š‹3„{"ÆÝi`O7 ¦é•šoãÉ'?=Î$s·j5(DµSa‰ÿÙN¿`;³2ãð"¶ï·!“23s¢ãí7š´ìJÓ™óoǻƆ[ÆîÔŽÅýñèLçD¢16Ôø0ê‰F¢{GcõÓΆ©kÃÑl#±}£ñV<ÞÇ[ÑjZT»Ùv6²">Ð9÷<¨N4'^Z§#ÑÖØ½Æ±DëãDËÃÁæÑX ‚pl¸9uÏO4Ý~X7ð?ºÛÓ³»d&cñ®ª¥…œ}-‚U¸›Üïjj[©ˆì.„Œ–˜ÝåÌ}‹sÓ¹\üïÈè(~Ü•ŸŽ6O²ƒÌõ¬}îèþê?l/½ùv.æ t¦ÚgA÷|bæ~¼V—4›Ž`®";¾ÞéaÝYíå×7Ï”¸â$º¦¨;‡På£P„ò!˜ê©ZjË@/JŠš©hv™Y¹,kêÅð ¸P ¬Ã—D'„ó_¸Þp~*œ mÞ‰îJùbMUù³eIËuH3nì.%`íÂ-¾ÞTÖþâHµËDEðsz`Y6ʦ~^p¸ž†KvûdN©Ê²IÅp|ÝɯÔä ìõT¾ÿj–•J”[ubUUþáz³X0¼»ni!º•‘Ù”V9%1_=Þ”…滸µˆSy&!F]Ãd…Ìú¼§‡0ú+Ò [í…郂q±* P$ø‡Tˆõ ÌY ¦ 8BÏ×àT·NûЪê]v+¥&U¥œê*ÏVÈŸšpÒ Ç‘Lxà„#uLƒˆNèÿ•‰ø\í$˜á˜ýúDoV߈×,Y¸ÙJxz«bÐf™~Õ`‡>%Ù›uûñ*W¢Ù¦ÈFͬé<ãç»ÏUÐ ûä1 èpL‡Óêx¯Z>cÓpÿ(›lš¦}ØÎ„C.Ép…'?gpM†«|Ná"GQÀ'¨ ÷WÊUià‚RáÈ°Èæ×‹f|ý‡«V¸Là^Ã5uâ’åb‹=§ñù‹^aƒ£ºÆàcQš@☊ƒK.+pÕWd¸.]pì^¨s,˜’L•V–ÌÉñÌ’4k·RÕˆá²WÕùªþZ³ëáÖ&TÇÍší÷6Õ¿”v{íǾðùÊTÎÏ;‡yœJ¦RßÁD¸$™L‡tú“ÿï—¨óÙ“q˜ôù|ªÌu™ZLLYç{iÁ¯ô®Îx¿&£õUZb#\2j&”¨L#ÄÌ¥êµÙç?Ýýhìàh¬1«?hj× 5bbŽ ù㱦è`ô›aª5òŸÓÄ`3‚$1xøþ·mñ!ÿÃá–h´.kLÄ[bÑ}/­ßÁ–±„?ñ M‚÷ùQ¼A2t¯!mK4?¾»5q»¶vK¥šÄŒ%Dæ+²ØGëæ${bÔ¦üp³`ê÷ªØ]š…ö%žîI»¼:caW c9X˜ å {´»Áñ”3vÁ‘*h®¸±½huž1‡LÕe¹ÂÂ-vMt­„NÌqJö–¸4ÎáTÅÔøõ&W:μXÝHGù;Õ©¦¢0Ãï6Ú¡§D )äƒÐ¢wVä¢aŒŠ.©fb²qÕb`V«lüc}©ÈâÎrè(lxaà¨U™–ÏÑ×½Â_{ÿW¨•ëgµníqÛbTt‰,…‡¼ή’w—gšUpÔðã™ÐU8åó‚3"zñÞ¨+-Ö ³B-Ž™Ë&YA½n¦ªE㊎ωpã|Í ¡Ó*¡»p´ÝëÅ‚¸Il<ú³iOKž¢I‚¾Ú|jQU‹¢¦·Ì³@—YÞxKvCpÁb å.µò„Cº<àw#cK‚>hG–xÄ):-4Mé(šD))ƒÀ‚ÎR«Ì°X¦ËDWÍYÜpî-ý "¶'}vˆèÕ“§ôªi„¨ßkä{DlpJ>l:DØD?ÿE›ÝãÿE~½ÇÄqÜq? 餕V£Ñj´«]íÞêð ÌÇûx;€Ó:%®©?°q§õ#@ÀØ>ÃÜ&ªš4ªRÛàØ±]'±ÛH­ëÄØøí¸ªª´•UnÚ:®k98 ˜úܯ¿Y7IÕ,¥«Ñivïnf´³;ßÏ$È!.*Šï¿7½Gƒ:tS8ª\Û“´"EÕÄùóE[¼®Pó§P’@ö×ÑHÀ Á²UnbJl‘,cÓ„ªDf.Évò74—ðPîÈ´˜m¥-&oI[¡ƒ2F5ÝEbßX¶ˆçò\ÏK¨ˆû{÷y?®-õj1¢,*ÌÐp”¹dªRQÆ 'U%;[¨¸Þ_é†ö2Ø• ~OÏsiN"ªº.‹B²Î†vfXr+†Ž¤ëõYI"EÕýðkNqº=ðrÆñÊŒ§]±çªŒN¼ ^~C‚^Ë®ÙüA eO·¤<.ð±5%Nù ½ø—•¦Š"SM¢Ø™"öŸTÓ58?Óá ojÐ¥pìÿ$ÿ1 "„ÁQØ'Ã> HïÖ˜‘Ä©3zòE üï¥ÝŽk,×dºHå¢ vfÌ“IÛröÔH7 „ñ–÷!Zœð†GÌŸ.(O`‰²$2Cg$ÕTÇ­Ãe gôèÐ#A¯}X°‚Y/sŸÌT =È .JÑ÷¸DáœÀÉqYæH8‡ìùé*—C¯%‡™¶pBŠp>Q^x ˆ( } ô ¼k¼xÖi]$c'e¥“t*™²ªQ'+©L-w˜¿YúìÕÕ[ÂÏ5¯« WÕ V½8PµuM2KùGuÝßWo*4t…QÜ áÜýâíã5òð@ƒXŸÑÿß߬#:5ñ/˜*NÍq1‡.Ѫ4Û‘5³¦‘Ÿ?kÛ÷¤íp…íx¥íÈS¶+Å-'ëÓ$‰h5˜" LWãqwêLŒ ì]û—6†o·Fü‘š±pÃDÄ?2ìŒÔM»³­&÷ʆ"ß(QRu“ª•6ç‹°7Ëðæ<袰_ý²|©$Ê|èr@7^Ñ­¯´èëqùéºø^ Þoqe ‡ÍOÚµ<ÃN%Ü@0Is9d’ k1òBÊ쯬•©‘Ct8¬@—“k+Ý"¼¥] šnCÄ R$|yì^zœ'V¾Ëpžq3ô¸`åþL©€å´ çø@âB8E¸FzYô¢EtÈEË$(ôˆp†rÌ´}dÌÆÉpBŠ xú¬ñŸÆ‘SÞ~/þF†ÓäÝ’c‡B>vHiÂa^G|gVÉ ucÕÛú«®­Ùü×Õ›FÖÕŒ®«½YµåêìiäVÕ–±uu{Ÿ¨ Œo@•J½w''§§§ô•ÿ‹#zïб·d™’î TH¥¶îÕ¤È×ÐH‚d…íh…í`™í@¹å“J$Šðã'i9Æш¬H²¢(²„Ë—êÎIzûÄóãõýá£Ãu#õßnò?v6Ì©FXþût|¸il‹ËÈàC3ì¸=T7{iDŠD¹p†·nj¸{;t¥oÓÂyÌP%Y¤‹£’=P?µ«ÄJ„ô ¿Ú !˜Æ7§­Kæ|U÷'CG´b¸ÏMƒŽ‚h pÌÿÏV+”[Ý“¡h˃vÔEn´3ë~«÷Xe’S¥”é†Ã~d¹š‹q¨]ß^Œï;ÑEÉH¡öKÕ9|Ûš>ÈÈÃe—ª25Ìs_ï±QwÀO:餓VZ­F«Ñ®vµ·§;›Ø®ÏgßùÎgcü„!‰¡M?ˆ j ÎñŒñùÞÆ†4­”ˆÄ`cŸyT•Ü U-U0o(IÚªRþà¨*)¤Û`ó àÇýú›3DU%þpd©§ÑÊ;^ÍÌþæn¿ŸèåÆñ2nu¸¦ÕN|iQ, µ9qèÍlèrCóÎ tèò>•=j¯dÙÎeý]¸ ˜ÁFû’ìÊYÞo$kª=ÿÀ ûºB[ƒSÜê“Vfÿuã6FùÞJˆBÌâ™—M‡2 ç0SÜyº^~´W‚HËš÷}‰û -ºÊ Ã Ñ<¶¤è’¿ï¬úUMö†®«M^¯Í(šU›h¶‹2'§o[¦ÀÏ5ØO¡µ Â¡Të}æ-E>Ö¡; $A0Бž¼‡‡ìÐO Ç ý‹8ÍQv’o'¯§-Ë7]HƒM •…,Dª„çjäp:¡°t«Pa@‚Ð'úñM‚“ðfQ"T©9´m ÁŽåûš }d§yæ“ïÄÆY’ü.¡Id„Í$Rq*eü/Ÿ2ùœ¤³|è™F"ØEP&ˆNJLP—ÄKÊu¥œN8J,féE0Ò%Ë&oõå7ßjÜ6ÖèG„|Uß|mÍ–­õ__ë¿ÚÐüφæoûçJ#7êšoÔo¾²f³Ç¢â“†âCK¤ƒƒ˜ÌSS“ÿÕÉä Âÿð3|\æòòT±KŠªpÆ&a`µáÈÜiäÈ }+ }Ë ‡_1}=5òJCï2CÛ†Àr±@SEb“UŒ¿4ªEæÿ£·\§?oüf¼edxבÝwF7¾p6ÌŸF˜=ÆZ¿ÓÈÓv«ùÞ¸ŸQáÖögJÙ>>²m®æöãŒcÃÛïßÙ>zc#âäÑø/‡Ž7¦ÛD•žhV«]0E‹-‹ ­Zó¡s‹Â¶,–Q÷“6¤Â¼kd"Zû Yæbø†ª¿ö/I¼šÑV!MF²!쀠“¡¨Ý‘‰ƒ‰¥-"Ëj¬f|´X‰ÜY®'#¥Æ5;þüNÑr›Yxª¥©¢²)GxÜY{¼˜§ï[ðI UÕ6x_ÐéIKwTå¼Ñ!ó9}¿‚ƒ b‹!âc9YMÂ…lQ\Fª'œE[Ad¶·] ´âK¦1â#¾ÇA7t8!æ…ö¼É wÑSà^`qöø œÁJs…2YèÇ‹¡Ó5ÿ‹•÷A ?pÀ›7˜A[jÄs?R9‰B•2ïŰ2^¶;Q'Ä]OB®ºLNm:V\ÖzÔû­ˆÌ‰öò}¯¹U"á[ šÐ¥š§Ú‹õËwßn-͵HV*š$«¦igL¹tIŸ/–f?Ø] {J ž ‘LV¶A¨å§‘xò.s)r:äœì(Þå©Í¶ØEŨÈD6©‚R“§ÞýP‡zSé{’žg é¶`O2¡A‡”'ý·ý$‰2ù˜ÂQeb?^FoþB/·›(µòTEU/qÇ>¡Wƒî‚_×ò}u( Ûs5ÒcÃa¡—@?Å?¦ÈlÇlS‡t8@ß{Ý”A3¨bÓp¯xî8þ /kL#CœÑXè_äà,æ;™µN ìˆ0¸`ƒüÓÓS*³Ç N¤ÄYÐ$8ø9möÔA ¥(r‘0Šàøˆ“s2[ü§Ê—ÇøŽzüþ&_MDdHh.¿™éøÓê #kw}YÛŒðxP×ôÆ–o[F×´ ®74ýÖ–› ›Çëç†"Øn®ÙòU]ÓµFwÅJ…i"åê*òÎPdzz B¦g2súüÔ‰,S KaÎã ýõ GçN#ÇVúk<Žþ„&^3®1ô¡RÞ`³Yaè¯6TR •%Þ¬™æ . ”Ⱥº¹uŧWZFï·Þ¼p6ÌŸFð8C‘ÿÔȃ1ÿ½[ïŒÝÜtï–ÿþííc7ü÷Fw=›³:ŒÝöß½óîíÑ#Ã-ãc;ÇGöþöðzÏ“˜*?¶ "÷Öd1„Š&ãÅÉhY2è‚`.ÄòÙK.¦a“bñ|?Õ“ñRs¸Œ÷–þ±®°á%Åέ¢éÒz쫆à¢kÛ–~Ñä….L®,z!žÝ_i—N´ ÿùO+§w¯<ÞPPd£Ê«ø®§I‚EòɦO²c>"$BÎ3ë:¥ø@£G—îËÙ=²,+ú¬Å·Ùaì[žö—­Kîv•CÀQ¼÷"ØS mè7ÄXþB¬Šu¢ÑEMU&>û4Œ-…h!\Œ4v–A´„á'—RJ1‹]̸°+É:Ë÷%V¥,ñÃ.”@ûü§0Ò+ZÈtÄIJ¡ âÃ&!èDZ ùäbkdC—o"TÐU,kÄ’&ɲ,bÚé²Pm•ØUÑDDQ—ÓU"Ä›!VÍDBä~´ª€#TÅFù,".m‚l¡‚ü’dS¨. –÷_ɸ²£ âˆ\ˆºØ¼Ø"o£n–¤¾ 9xãÉÈbˆ/†@ÖðßÊ<›*šª “­+ÊI· &ï4Ò;†tHÉ)tÛØe=ú¬ì²ýäaB­â2xÁÌgPÕTî º­ì²^;“‡R÷e>_#*”ᘠ2›tGÖà ÄŽG¬Én}ƒÇlç^V¬¢˜kãÿÖ“Óà‚„ x¸ÄÃ)ú½4‚HÐà<58ÇÁ'N#BxÆÉyΦNOÎôÌrü³h¦@Šà8ˆ“ó:œ&~/ï]/,ÌàdJ4^H“‰óŸWKUý7¯6Œ¬Ýz½ög×ë6Žÿ›ûzâ¸ã¾’¥•NZF«Ñ®vµ{§³Û`ÇÏÃ>ãg&@,H¡À üàZ°1÷4q›¦BUCKðùlih‰ÔV­ÔG@„€*òGÿj”¦( ÔöÏOž~ܯ¿9“6ÿð‡+[Ž8F{{{3{³sóýL]S¼®é³ºÆ{{ý»îð`]#"$VÛ¯k¬m¾»§q¡4‚¼¹[×4Tï¹SÓ¼A3tJQ#85.]ºI‡$ëÄsï¹—«°ÿâÙÄ"¾V*œÛÆ‘p~Ë‚i¤ûeáüv¡‡Þ.D$»øÉÞͼŽT ï¼"\Ü$ô¿,üt›²«RfúrUÁU09ô™¥å§7|m]r6,žF¾^þ{~"vŒGÛŒ´G[dž¾ÿp´}tðèBõ;2rd$Þ:?nñ÷½½!]Ò$MÅi@mE»ðŠºÖa@ B.9Á¿ e˜ŒÓ¾®‘@~Ÿ±è »#©CÿŸ?(ÞäEÆ$3Cfæ®ò˜¿úêÎôlMtÚS†Ú1¾óf¼[žø³?Þ_Æ1©Ýª‰Íâúå"¡ª¢š„2Ó«öËßvÂ*¹p準Ľ¥é|[Iuf±0ãf}*ÿ…pbªNv”Chø ΩÊátC ‚ãÇý€¶éÌåœ@3$“Ñ[0ÿ”Çà.à)X‹ÍÎâ˜cÖ²¸Ž0ß}åÐî|ôº‹ç»oÕì)TGYòÑ”pâ±ÇÕ‹ý\‚sυߘ¯ ük¸:yÉ©ââðfAG&—c/Ã;÷ç¯?ý[ãÆåŠa`3B Ó"«© CAG+2+•%S1è§-™½ Ñ•—ðgË)V5•j¦d%evË™ÍùonÊ.K—˜,â®èšnºw:Ÿœps›ù‹ø —N#øgðqtæp7Vs¯òûqÃëYS^—·4C— &ë¦B¬4Ž2;ñ39I"IœKÚµpÎ (Š>6¶sTô˜V÷"„ xÛ:^¹o½¨,i6ª<|Ü햡ŸÂ9syÓÏ ‘#?S#aúôç?€³ ?sA…>åÉ[2œ7Gß2ª²E ÑUS¢’T›# ýÆZxÖ_±Ãû|`+óׇ”××wÂûh#锉ôôä_P„Ÿ¹AøGóÖå†ù€òF°ýk*Räöi‹;‹¦)šI»¬*8é4-C‘Ž•W ×µ}Yãù²¶q¸þÐpýÁ/j|Vƒi¨=Œ ¨y-Zß2X×ü¯šÃwj›n×·,”F>¯çu|OÓ஦‹ë·K*FK—U—Ë…Á€žszdN&ÏÓkîÍNOCÐ[ïýú2.ÁU4¦Ò &t×ýÕBÿKB_õ¼Õ1ï²í+Þlã\Áƒpµpv£ÍiXTÔþUÔ´™i$£Äñãß×Þ|c&æx¯õQ¬}$Ö12Þ‹¶|kŒ{ßo™Œ8ü`¬}"~|4êYrf|SJôèÈgr¬u$vd8æmÆZFÇ<Ñû“wÛ§†:¢ñPwÏ«T³0ª-§Š…*ëlâow8À_¨¯ NaÖä,¾:VCh 0pÑ?%h.9¦s"ä†P!ø\7ö¯sJÊL*;lT,JÍcDÍ$šª§v”g€¯"ÑåÄþq €QI—M\ŸM î7˜ALYÒ¶ºŒ›ßÉåv¨×äŽyØ,öX<ZÛ¹V't™E£ÒÉ{; —,Åž×â-ÁqæJÁ\­¿ÕP¾¿€t™ILܦ:j—‰ªéV¦Éš´3Ó„@Ñ´·”_(l(ÉͱX4³*Ǽ¬” Mè­l+ÍÔ4‚Œ¤r:®ñI°ÀoåLwÎÍ¥2d*„²ð ²s éC,r¨„Šyí[Å{ñ'‚%‹?(ÉÜÄI×›ëM•Š¢®!¥l„ºW¤}âO‡° ½I„S¡/ º ôèУ~­(OKƒ0ƒãÝÃÎD¢­ ²yó{ " tkЭóF~!Ù­—1“‘|Ý[I®„¬Ð+AO*œ¡I}¦R°_lÙÓC>í²gR(¦FS5Ŷo£WV$Pô¦<ë¯ÒykaÁJRdð'®Ë\/W §Èu×Ð3¨~owÂ ÍÆ¨ÝPuEV˜ª™Ødêq®þèÕ†±= C‹ÿO#cµÍww7 u†÷4UZmDe:ašªýêÝKH ì™$K330óü€dŽ"ÓÓSsÁz­»RcŠCÕ)‘èÞ5Bx—pa‹Ð·Uè۲虣HïW Á:²•ƒ$R+z^täëL…i†!ËT×0*S ÷eþòFÃÄpûx܃Á::ào›ŠµŽ µÆÛâÃ퓱¶Ç±£c1|Ûºô øf‰øÑØÀ‘ñáÖ‡c1Ž<žꘈ7á^þùf¦1“­ «¶‹¿ûnù£®|ƒ9§/.×ù‹¾J‡’ûGL„P„’=úr!‡aÁ<Œí+§N¹áBU²jT¦’¦P¦IùTøÉ&‚nè(HŠ cÕJÃ"JŠC“4jÑYJceêß› àx6nTŽ­)³Šh‡Bk‹M–òÝkpõ­ûùMö¿6VÝ÷VA¨téãû9+Á5ÐY’ÀGéÏ‚ÎUÐé>^þÉÑÊÓ›²NËz«Ñ½÷M’ ¦æSšòÎn'œÌK28÷öAg®èD¶RÉF¥IOœª€“Å œ$§²Æ•Å6167UË>:TÞbøaŸ½^œ?E|FáõhÝ  üNð@—ûGKë/L"Ä¡> ðx±Ç{G!t­‹µ•_4m*µHršf:˜P¤IŸ´Ã9d€¤‚<Ó› aíyJ…¤IºQ+¡Ç„ˆ4ÙŸ^÷‚`§Š¢Yªtó˜ aôé7½yUÙb‘ Idª]$äBÒ Òù’ú/8oOôgj$b@Ø g噞œ‹‡l4…i¸ °X©%âep ®ÿ‡û:âºã>’%K+­4zz=ÍhF3»²½Ø‹Y¼>ÖÇâcZpªØjX΀9lÇØ!ØØ»k¯¤¦%5ààªJ‘ÚªR«…EI$©Bˆ¨åJS{½6>b ëã×ßµÿð',òú§ÑÓX»ûföÍû~~2\°Ê$V¹h… 8á åùŒ˜çøšÍž7½ôG¹{«ˆq")Qާ„R™éŒU¤¸þPZygsíw[ÜÞ^+ÜÛZ3¼åÀжš¡Íûïm­}oå:Bˆ&«ŒÐü:4>ôx¬y|¨ñI¸eb¸¡ÿ½vIN•(eŠ,Z²’”ûsxÿˆ[}0 :V`#9Ó‚øŠXnÞ±væafñFc"˜ÉM*škvCG!‚: ß)KT1U"D§Œ‰H‘mnz­Ö;ÕV¡Bðã'x1ŒÞÊ3ìºM¤ñŠ&åñÃåà_J¹{8½úu•RIÔœNÿÍžUÐŽ…I”MÙü[º³¡Õˆ}|/²j]Áã¾ ï° Nð»x‘«f: ™ÇKH†"%öšM˜h^iÊat¯lÎwبE§qÉŠQá¶C·gÞïþ× ×TGÑ[©I6Ê kO©šÓ „Ò(‚67t•\«vμܺGÜ|8‡¦ètòŸ[6§ j$´°ð^ô}À§©:r 3×äÀºtB-ŒŒâ_®Íø6hpi ÒÉÉ®‘Ó ôšéÓxá5rƩЯCºEýÀåK$Kª!Þ:æ˜ï¡ÿ8žcĉ’a ãäBã—©6']ÇÙ^æûpN~žFæ?N€>ôN£;ô%u­£D²âv¡+DUânö¢ÄéK \´ÃùjDä ù\„ 8_Xáž‘à€ÝÕø}ÅžXi$쫹ë;pGýˆ¯ö¶¯æÚ¦ýÙª¹l¨:‚äêÕ«s&Hæçç“Føå<{ÍF£x]åe庪¥PlIâév¯0° 7LT½$ ¬ÿŸCpŒ \+ô— çÊ„ßU ¿Z¯–¥3ƒJ²”);íTÖ¨ˆ>‘r½Ç7]ÿ·<²k<üöØpã£Ñæè”:\?1Tót²%2Òs¼"…j˜Œ4OŒžŠ4<küa¸þI¤i2ÜÞÛ¹BiªdPª: 5]f_íó@G>´™ lÐl-Û Ì¦2ë…ïÒÜ?ž Á|h/‚ŽbÌ)B›wþÝbh)~|0»zi|šNE‰1âPeª©úg; ­.hÏx*€¶ºnh-~ØP^b·ÆSÕM“STq‰aÙ–›p¨h©G³™á欩ƾ µÐê6ƒ/: xµ¤CÀEÒÄ<¾YÌÐïÌçôâÏÊW­ÛžÎåÙQ2â_ûùæå¿¯Ô¦E<¯©ßW´DFQZEժɎ ·¡Œ'hN”gW1ðËÕèÓd攘L˜øÉF4F´§q[v\öeiDß—¡ß¬Ë‚c?~ïl°d®s-´{¹Føçf.<\çm/áV ½fËÌy H>©ÌNR,fhj’Jd»*ßè²EOKÜ!§døX{’ÿ×âÄ} ”¹* &ÂIiü´Û_³;yîž×¶üD$*Å ÓI­EÉâû[ɇëõiV•Ä1CM–,WS ç¹3IЋÎ1 _ƒÓNËO$WåÄQšd“â 3V%[¦ÿL9E."EH¬4òô¢—5„|!Â+\F“è“oOØËó¬ØÉ2&Y)Mu—Ÿüc¹E—*wÝÝV7¼åÀÔŽ†‡›ªïlÜ1º»!VóÕÝÝV{sóÞÑõw6í o;Øæ-a„¨DÒdµª¢rvvÆÔȼ©‘E‘yóBލ‘o®þá®N¥%„InYø°RxS,úË„³åBoåËÐÈüØÀÇ}ÏÎü}²N|Cèÿ™Ð[& ø„örZlK5Ia( ÐDf$(²·DýõŸöÞjx0Ý24Ú81Ü07Ò}xx2RŽì‰9^‘©Ÿkšišmœ­Þ?>45èí^C IVQÑ(‘sdãfm.tåAKtxÌî÷|¤H!øs ÍóÂwéPwHÐd€ß­Y<¿0/.8ZG ÿã_¹f‰÷AbØ“$f4ª‰º1S–lèrE›Ñ$ùÑN×|‹E'+’D•RÍ&2Ü<)³â»t‘ª uQáh1‹4çA†`¶@>´šÓÀ” Cpmìã{‘U§‡çoe[­ÐZÈÍÉYRÌ÷6üé3 3Bi¸!´ünè.¬J³ÙˆF4‹U5¬ŠÃI-·ª³­èÏ€¶eЕùéî\D*ªJU-£‡ñ™s!ü„ŒK6:)¥º®++•¸+[²!ô´çâZ‚ŸIkGËH‚Ù|½q2½àû€æiÏáƒ@®ù¬e= ®úËÆ4ªË"‰S™-MYŽ ¹0 GƒÔ‚ö#Hzb±úe8eŠeÀ= úu8›øø”f€F;Ý’laVŰû–Z¦{\p.yºßøá}mo†|ž&Ã9í¹é3à#ƒèe|¿apÎ~=¨,3âm6ƒˆª&¥4”R¸Lá‚È+FK|ªÃœ NƒÀ_éõ~éÈ›DÄŽƒZ4F$ª'JŠƒr»ãrUÕ#_íðöúï¶×ÝÚ´ç~åîÉíu‘õ·|{c¥‘_Ý¿¶×ÿ³ªúᮺ¡MûøþK~ÝÇD‘ÞqŸ„Äd’M&“'“'3y&;³ÙÄå–wP{Þy'UêÖª°€J+‡€TÎ7Ö}a_ÒæÒæŒõeðÒÜ¥éåš6¹öì5íµ9LcÏË]½«žZE`Aðzžz°ûëïY¼öÆþ%®¹N~À“™yvxf¾Ÿ_ûùï´”†¡¨šL$£££÷<ˆÇc )ž\E<ÞmnîËXl•µ­y+v—LcDÕÆrax£0¼^XÃ0â®'ª |’µÂÐF.¢áµ|J§ë„Ó.ax‹à_!ªH+QÓѺ”ÈU£fGæÏ×öÏNuNOwFgö`òÞ‹îK:ž’š™ØuoÖóYtïé®è­îúfǹʦX²³PU$¢Ó¶ô£Ö\8” ñ]†¯Ê˜'ÁrðŽƒ¥‹ý–Žyª!´’_Ý›,èˇ^4I.ô•A_ì3ápÕèÖÂ<-eC.{£Î¤ÔD˜2»I(vñ·:„²ÁS‡ À“‰¡=5¶U䥧Ød‘Y%;Q 3)3r¨øò æý¾gxa>b ö8yö:c¾š!'ôä'?¾¿n•Ç}ë/N—S>§`ïr~È["ØŸèÉÃehÑ@ÉŸZK¬Äʈnh"U™jØ=úû-¹wC+ XóA[M£VÈ6 ÆÎ¶bÆ#þ B%ŽÖ¨Lu(Øk¢jy&ÓòÇÖUW^tþ¥-ý6§uôÕ@¨‚/òà4¸~_#ÞL8¼ü«ø­åÇ‘Uüž”¿¶y¹Î–8fS B¨Ó4.´A¿ á¯(‚uZãµ ‘°NˆÈœ%g¬ÐOá$Á“ç(æÃý¦.Š*Su+ýÈO!LŽÂˆ}4 ÛL9fjrôó‘‰ upjB>DÐEv8£¼Ö®I²ä`|™%í^Þ¥ð[’4ü†Àdx‹ÂÛÚø/¥cmb…©é!ªLµT]f†LÊŒ¬g]·[:Ç6u]«ß1în›¬ß9în¿¹µëZSdž¶‰ú¶didÜÝqÍÝ~½±ýJCëlcû¦Ž)÷z+¾éP™•P\ðßÛÞ’l5,îvù“OÐ!>á³,“ÅCuB£Ðÿ‚0¸!¡…uOH# 5X÷Ÿêÿnbç:ah½0X+üÌ%¼¾I8µFBºl”ÝËô BeÍP |"ˆ¬R›X¿¯è­vÝñNG÷D'ö"N’΀§¥&vÍŒwÍŒwßžÞ=;{àÖX_ä„ÛF]ÃG´)RÓ.¶ÁQ ñeà]óbãV}•è/¶´%<=­*¡)’ ¾l8\1é­>·½pðÛYÇÖ¦_z 'S"ç…­9³ž5àÏn,±éTÄ6Q£‰ÓÝ+ T<ßW¾“ÞÊ8— â ÿ檿o¯úq­~ü[äGkµß·`ޚ¹ž,b—Z ¡jC(ÃΘ?+~¨€ÿzòãûëU }\Z…L ͉b fò+J­ÒWŽ<ø"P‡ª`Þ¼§zK>³2»D•\"Ö窭™*eŒIÌF—¬4ÉóYærš²”P™TÖ¿¡‰Zp Ç‘¯¡²ÑÖ*U“ …0jJÑ4)GÁ÷„%Uµ4çZþÚ^2×Sü$‹ù ÇZ˜Û¢ß‡¬˜§è¾¿‚3ñƒ× ¡ÿ—#¼ßØTš¦.Q¤Ê¥N]ºX'48• HD>Æ0¨Àˆ §T8e@?ŽÑ*Ž/‡58®_ò)è¼[’¯ñ0†Â‰ øiÚÄ€’n5D‰¦ëò{Û#5rZ¡Œø) V8­ÂšÄ§eè·v­Ví4…IÓ§^:«ÂÛzÒ4òkÞ±ÅÏ)oþ¬-Ԩ̘¦j#UÅïR¡f_¹æV“{¦±õS·çjƒçzsçÍæÎ±®‘©æÝ·Ü×v"K’¥‘1w×?êÛ¢Í]7Zo6íowß°eSTU":c—/_ŽÌÏÏ%m‹Çã±ØüÂà¥ÝÝ*¥X !ä¹4!Ü(ô¯†ž†ê„ ÂÉu«OD#ÿ]è¡Za¤.1Ÿ ¼"µÂàzá¬Kqq,¸–üÄÅÖ¨ºÆˆ¬‹AL]å/+:^Y}~ì@ôN×Ý©ÉgÀÓQ÷ow}íþçô¾©ÉîÉ)_8¼ÖaMa²®*éz¾&]ÜYÁB8€½êêØ¡2Þ'r~‚·úœÐ‹dQLŸ¼…‹br¾¿7Ÿw¬FþèAœT€ÿ èëÿ¬‚,š÷Ä{K¸üå¨_š0Ž¡Üëä«Î—7çÏ?®Àš‹; ¬²$RÉTÕt"½·½øWÍ庢˜ÔfÑ4«"Û›È(ÕˆI3¨&î]•ÆÉ|p­KS‰d5*¦Þu‰²Â4;S ƒØ‚&Q?m²>‰¯äáš÷ås,ò}@îB(ü¹Ð㌪¹IPbüPxóÎ6dZLU’­vü€TX±< ŽQ’°ýúC„À@áŒ5Žàûãas.l@„ÁI+ ¢=šÅªàM}³%Î(0@¹^Nj¯7/“ ÍTD“ÐCÆ#5‚WDó„Q!¢$LB b¢L¾8n:Ó[Y"éL©/á)iyWzÿ¤ÜºZÁì&D¦Š¤êP©©)ßÏ-ýóæÎ ÷ž‰Í/Þnj½Qßx¥©r³¾í–»}¼±sÌÝ~£±ãjS×Ç ÉÒÈÆ„FÜ3ͺ['ëw^kêüܽëÙÒJ;ÕL•É’ÜÝÝ=/dw’ñ¸¶yø<ñ#:;¡Re)AŒʈpb®årq ü[‹­‘¡-B¤Nˆ$ÔƒôÆf¡ÿœïâgòAð/êë46ŠóŒøJ–,´ÒèÕhôjF³š™Õ®OìÅ»¾v½>À6â)×`åhZ'à€‹c°½÷Ú¸T¡‡cC“´h¾…€1©MÕ¦RZUU¥¤Jì½¼Æ8øØ§Ï;8Q+á)¸ëÑÈ;;×{ìüï`³)¸ŽlÒy%K8K”Tj#‚¸ºÑvüþHOîOuMLtÝŸè™û0‘Ó“騡tÌ—Œ÷$bÝÉ»‡§ã=÷b=ÉuÎÞõ=u6¼,ðvRè‘G˜S>ïƒnï†BI¡ZYf¡9$G#Joƒ8Z QF#„¿ò­-ÅvI0 lk„krØÖç³9½Zξ°#¢ ìú×b_9+V>pÝÿ]ßì¯0lƒÍ,cêC…K!è„H5ÓQ¨Šµ……u5Ûb&²@¬`[<¾G¤t‘ÖWÆB¿ÅcnV!£»úŒ¬`µ‘øµ_W5Ky¬ˆ‹]9\±€P5ËA,¼W_ë(„(>žÂ¾ªf·`GV,5!ìÂG‚¨ë‰õN<4!öC_ô•·¨Y5zl6]0S\éaW-É`ˆ‡Ë/îÌÓAA±rÔ*[ì*ÏUËÜÁº¼Ôl_#‹ àjÊå)¯ÈÅV1[%‚oƒë ²o}ÃÆ\Ø5‹Âå©ôf»ŽÕ± xàhÑb  ŽÖg Œ²ÑÖ½l,Üö°ÁZéùÆÑ)ÆiðîÎ]áp™èP4™ÚU«fŽ# (ÓÚcDHŸC$.«ˆS憵®ÍÙ‘ðÔVj5ýî˜Îà)äòë§šÅYñGcÝiàÃh 眴À+ ÉpF^^)œVÿ1 Þ*(ª…ç5óñWu¸a†k¼/ÂX\5ÃGŒ¸.|{`á²ãÜ0>Ž 0†y¸†ûø@€+x®Ð—̇Z¼N%[ œ h¢b³ŠZ¡› Vý½åÅ>×v‹Å}ûÍÖý·[÷?-oüoõ×–—sñÍF)«ˆHÓ·î FfaA²¸¸ð0Ò3Æ<‹JY€YÈÌÁ‰ãoHTV‰hÕÅ;£Èж%àv¸ùk¬´FšMç[L£ÛL¿j1 o3üƒ Ùµü);ØS m1n1½³aæ§-¦Î J¾]×5‘"Š’n5‹œ¨gÕï(øÍ_üòVàÞdàˉŽTìÀÔ݃±Ø‘Éd0ÄÚS©Žx¬ãîö©Ô‘™©žtüÈÓçÄckd:щÄB$ît%':gR݉»¸çH"öj&Þ5vq¯®ñšÌåJD”4¤Èû?¬ŸXÑ2–£0°ò©Ùz®ÖÈSK¡3¨üz&ê]Œ¬½ÐdAarj¡*çP¢ÉBeÙ.ÅÌ_Ü]4^Qç®(£ÕÍsÌ‚_CZž¨àtÖ1§H¡(‘ïç›æýÑ6˜ìóýŒ+Ý®å4‚îbôB{Ô0„j2á5–wF¸#N0g±Bˆ4œÆYx°×@B„Ö° ×Ïù‹3¡ˆ”²SiÜŒpÃr¬>Ïlðú¬\l”#eì,Ü,7ÎEº ºƒžL´f¾ßûUij5øá/¿‹á„%²1dáZ&tkÑ“š•K¸Bö S#Õ_E×½·GÃ…nžh£‚n£ÙÚ[Î0†X 5~ôŠëÇ®ìRÙÌ™ Òn—2þrù"Z.€MkÂõéAoɶS5‹<ÿ½Ýkfº0€s»öfûúm¹Ö|—å,JÕc ÊL ìíp!“XÐÅ ÅÀ†ádã4Ú®]ùùSÊ`òÌDßÞUéÄ%Y± \K©’ø™ §8#Á°ƒõeµpN‡³2œ•nÿ²Ò­˜e’ëiž˜õƒ ëwW“b‘Ïs$ªYEóðó:œáMÎÛÓ£8«Á Fäé! ¨”室 'åS­‚LUA2çÎ&q>a)ܰÂUˆWy¸A¾­F.S¦Žk<\ç™@®TŒQFtÈu ã$ó¡yþºøn·ê‘ñ'Ÿ­Ù9ªB‰Ès¤ÆVðóƦϞ߇A„|ñÂ’½ûn y†Lòië6G9U$ —c’åÄÑc°¸ˆñ ÿag!ßü-¢«â³ÓU«V‹‚¤H²*q¦Þ¦%{<¬áÿ£FF¶šÎãv›±ÝÊîxê;¦¡íË?¼jdd³éí-¦_#]ö˜÷˜†~D›Wé:Õ\Ih‚d©D%"hüöžšñOÚîMu~ž8ðYòðýT uó@:vp*Þ1êL&:cñ¬;±ö‰dûÓçÄcVâPj²#ïB~Lǃ© ߟ·ÏNû±Ã0¹ï<§+¼†Ý"i‚Ào°·¹EüÅ)‚ÊLoDëŒÚ ¿u1ûjæXÒáë×m¤aýƒè¦ù.ïéõ¹C[‹Zݹ”š9ª6ç‘–Î*ò„fñŠj-Eú[‡~R6-¿úëÆÛªÝ”£‚"ðDSTŽHøoT¹ß¿¶é¯‘¥9†]ÔÁ,~*Aà…ÐÇVGŒc0y}èõ0øaüaG« Z™ésÏGË2ýH…"—0³á3#|åÐà÷0ºàE°Ç˜1ÜìÊÑZˆ Wª]Á*Ööá&ŸR²Q ÙzC8uL;H µUìQQ8ÑJA´à”è/Ÿ0€yÍ ƒOR ýF;|˜'Öoe,ñýnÖDN¤áæëÕ‡ËL9²9›¢I´ðÆ\¯ƒˆz ³áöÕÞï­ºµß1篃H èÇo×Îö6|¯œšy±ˆZTEzÉÏÎe]Ä ã¼ô’Ó)g ¼&¹\µp´žõboƒt@Øex¯’õ îÄÞö—¯øüa3Ák´®| ¿Ø\¢(„RExÞ¢7—šá¤#VD–P•–ÓBæ¬E‘àdþ¥Wr½b–$Ø9ÁÁ+Ô*Ù5Êó"/˜Õ×j¥‰·lpA†Á<8-}ÒSp¨Â”<óoêë>¶‰óŽøI‘,Y:=ztzt§;ùΊnÞÄo„¤ Â[“Œ¥$Ò…ñ’wi€ÄvÛ! mÕT:6Ip …–®ûcBã­k'µÐ U•:u¬-ƒBÈ{¥â{ö{–NÑŠ œŸN§ÄÎ=ÏÝãçûù¥ÑNDÛeºjít2êШ2~F= ²a `Y6yW£'!<ý“‰žÂôϘž”X#g$ˆ}àq³š8¢Àñ=# çܯ¥…ÙF£‘˜d³&Š‚€yŒfKrÀîù|UõЋµ_WUB€"™tÈS¤‘¯ªjÿ°ô!™ˆX$éɳÆFGïÞûïH×õØNž6–¬týè±c‚‹X†Nå`îà®°ü{LžO·F/á:–q˹Cå Ý¥LGWO­gyœL’¥\t× €)ãºçso–q¯–¥,ÎÐD""H¢Æ¢†áå’WìYôé?wŒ 7 \ß4Òç°îõÝìó _ß>ÔËLÒ7ì½6°ùÉsâáêæPãP¯w¸ß{cpÇpoãHŸïæÐöÞ«‡{.¯M³òDB&Éb¤<ÕúYƒ¶ºi8‹Q$lc[qzOõçLû® ) »n+T.m‚KçÅÚŠÏmÌ.³™yžŸ¥IV³·`¡uðgYz¸àís’$ð¬ð&3V6dHz$Ÿúf±` gÞõ9ß~Þž$&`uÏsZŠÑç1öû±¸ßíb±qÑæ¼ïyð85Â(’¿·qÙÌ|$¡œŒCެrX±#„c‘îs2i´8ÙG~îÑ!²}sõ¦¹ƒ ŽlɸPz¾:í“ éª3Ïo°Ý·ÎU§~¶9írCÞ·ÍóôPˆßM›ÝqíAÓXL³ËÙ©ßδá8Y¾Ã¥›=Ô<˜K› ÇLDlŽ0`vÛi$óÑ¥p6ÝF00Ch.ݽäâ6Ïv·œ¬ñ™„ûz³#±³5t2&]4â¤;óÇ‚6½-.(Cdõ'ÒWÝGË’gˆÈ, ̧bñxeîw V€YÈs¦Öd½ž¯ fl³  »Æ}9lÙ³•ïbîòç3§=zÀ­\lâÀÅG©¯ûW,TÀC$‹6Á£qÝ úŸU5d0aÕH 2B¯!ý·fÚ™ëÐèA2•bâé ôY]ük뜹V.YNPÄA™Ÿ! ×Všz÷)4Šé^)Ö¥¶UÍPˆ!QÖšJíšE÷áXM©‘.LXô½pžxqgb¦‚ˆ¬Š2´‚«•ýXÖOéYÀƒHO zF|`üÑLÏhô8ŠÃ&þñøOÏ¢½¥½üc¤ÂmD z+Â~%¥jNæ©’Š[ÕõÃkk/­Šl„LÔd¾_[[ÛSUûÄ™ñëZÕÖËë_)Kš [¨K@øÝwÞaþˆOFºÎ^±øñ)Óˆ®ß¥ããó]žÈI¢Šˆ‘k(dÉ>Á®¸@@&“8™n¼Qƽ^’Ð^Ŭ`´8VÎ~ÓµdÊ÷³±-g'%Ì-]%\W)×QÊu/æŽi–±j-4yd“À+ð‘$‰)( “¼H +¿ÒÛ88äýv¸±÷ÊÖážúñQß­¾ú«[!ʇ¶?qN1RÐ^šÄÏ ˜­[3&¯'ÒpËS¦f÷ ·èìªÜ×;FëòY|øm´ÍFý–›s³Öã×È=8ÙÕy,jÙÄí÷Þ.d‰Áp²#äi‹²ø“Ÿf¼ÿ¢ípi⯊­^§¶òÓÂT‹ÐÕš$$ÉÖB`C6 ’DÈ…eÌ+˜×°ÑŠérY¤…6˺lÕëJÜUœrx…íƒõi_z³nEÚ\Œ0 .[á\–òÁþp‡¡*‰;éf° ¸Õ}»íg"¥a }x^mðxôÖÒ¿×¹·\¢‘"ŠËqÅMÛ´)Á à%õ;èÎÚZHýÂkwX fA%^É(ü~Í3t×öž}¤Ñê¸RãT1ÂbR m¡-¹ °ÌZílŽÁ46ñˆ#>egÜ?Î8)íÓ¾~@ApÝàÄ"É¢á¼mî𓉗Aã‚Ýæ_ÀëQ íÔôýSj„¶ÚB÷K´§B¬SºM{¯1yßÜZfݳÎtñ—ºO¥í˜v‘ž_˜¤ËˆÇðµ#熷Iô DÛÓ§üÿ *ú†A»ÉÑŸÌ2"¤ˆ¼*Ë3%|z¡"zÚHÏú>¦§Ðkä¤HÏ ôž%ô8àDdç§#Ç•½››hÀHÖDÑŒ fIÀ²èÖ£‹Ê{Ömªªùæ…ê«›®­ù‹Ê­—+·\©ØüMå–I‡\«¬zâÌøu}õÆ+UµGŠW!£Q–d"l{.‹ó#öÔñã^1ª_øè#ɈYV‘·.Zɵ/¸G(@ÈãÔÈþ• Ï R¡…«/æ¢\×R®}1÷æêÿ󩃥Ì!Ñ®»”;UÂ^ÉE˹}¥ìxäy®cUBÝÈLAÁ"ÁF^ä5bšƒÍDÃÉ/%Gޝ¾Ôß0xË××_ÓwuÃíÁº;CÛnô5Žöž8'²†{·C€Fêû6Kn 4õyò"«`LH4šÂKo­ ´5“¶¸Ù~ÌÓÙ6î`™ÈS¶íOwjÛÙr³M¾1 t»­èBM–x1sÊLAHÁøz£›“?cÜQ•ûR¶(CcÉ$BŸntÓ2kÚÉ iª¹èvÈEwÚX\2dÞßïö° md{ûôÏk œ4g°p¶8XAÀ]pÿïò¯z3ÿ²6õÀbK}¾úÜl &òÐñŠÄcl ‰¢HDIVT˜¸@( Gщ*bgÂÊ}ËŒMPañ«DJaWSÖÁ¬³Še úJŒm’ðoêë5¶©ëø•,Y²tutttt¯îÕ½¶'à`'Äy:8„„¶” ˆˆBIȃ®á•G¨Ð„øÇIYתH« oRµR?lûÐ׊P»iû0ië´ƒR @Bx„À%ŽÿûŸdÝ—5¬@4ë¯c+¹÷øú<þÿßÉr¨¯äX;JØèV×vgßx=8+Ô‘±l-‡® ˆ­†h¶¨×Ýón žØ@Ås…ÓİäÌvû ‘¹rÞ¹σ#žû=h‰€Ãx!„Š5{r '+Ñ™Ž-ÄÑ«¨”,ˆ¬«÷¥âÀ¹‰†ÅÕ¢1—¢UäjÉCèœ e"Eî† [ò»i£œr¢=ï1Å·tãy!’ady¦XNxK—¢™^ØO_³±Õ‰pQ2T‚@J„=bÅö”ÞåFŠRuE‘ˆáQ8‰Ç·/ƒ š‹ja„ÀCN1á=FUèSà„Fœ0`»D\0Ìa„||HñëRW5Í!sÞ²žÞ<®ÂIÜ‹k‡À¨2ß9we8éi p\o:—eE}Îc¹ó‘ g¾DŠÐÇÖÈW2|fƒÏð^gd8kÜþ$åÓ^\%Ûu˜©‘TSqªh'®ÆJ7£:.44¯Ù}­z÷D]Ó¹º–sumßÕîG‡,Vv¤ÈÕMWjöa»äÌxĘ®kþvǾoöu»‹k˜ ¥g?=½PÍÿßAò`vnwã.]Síx¬Â•³s4^#½·QÀã?Yˆg ‘Ø&Ù´š6«m•Â륡ÍÒÉ­Ò‰M‹^\©Nm±U:U! >/¿$Ú)õWK¨)4Õ6©¯’n÷[ýx>D´3]å:‘™Ê-¹Ë7µº~}öàµ{Ç®ßnŸºÞzgªmfêÐÌö%çÄOŽÿœM\n»{ëàÔDã½[G®óvS­›qîä2gÄiS>Ú‰ÀÔí†X‘8ibÕÆ3i<~Q7{óYýi—éÕâëB…âððdÎOv¿³y¹‹X5Ùa'šJ¬¿¬t'cQ PMÑì üYªm¥)[¨br¶Ñ£?l_s/Š…ûñ ·à•^è;ӵ:ñ–Bè L‡óDé?ºV”°gæüQ ÁçÜæÏE±˜–ε¯¿ÔüÍöU¥¼ÆoA\1.3†9†PÜ‘ªŠ-ãšÆu Oªhª8˜â``8‹&WÑ"aNÆS8¶ÔÁ†ÊéS(W¹Ñ(jß WâM‚KÌoâ:&þiâéÖà]C¯È.f)4-õ9Zצ¬¯2®¼Zð}x=DK TG²Å”u­~r#æ‰"~òæpÝXˆ‹¢óAo΃®‚ÙŽ|A£ž‚[Q?Ä ÄØâÔÇË »4Ùž?Ûü± ¯ÊStbª–&Ó‚ ÃA¬Tç œ[}ÐU /½)£Wˆœ®.s*Ƈ/ù6P\ع&R6/~!.\E¨ü™áLïl÷“Ó×bÑ• á\‡{G‡:â»}8k‹ÏŽçˆT…²Õ4±—-p»¸ F Mƒ>” þуð¾S(eÈyãm½{CšËêp3¢k)Ìf1öïrî6RZŸSï÷‘Eû?Îa”B¿žý¬‹ÇOÌ·Ñb‘„óDEç'¢YUÃILEq+&1‰å¯-AqB¢k-„ƒ_Ö®ÀœdhN7±Ù4m¬œ@¤Âè @<0òÀÑ´Cw¾(pÝXb0¥—@K&ùìgG‘…XÐHÈÿç]Å£åîZŸ5M“dÕBT¦q‡“ºœL·SÕ¤Â*cšÂ¸BTjDשn0M§ŠÁ¹Î¨Ne< V¹Ìmv½Ñn´¯p½±*ýMoꛫœoeºÞò¹4Že­:êõJwî´ëN½ÌafiªƒÊª*£7 .›œØW sP|-Ä)GÅù0d Á§"Šfh<è¤û²ùxeêùƒ¹‰à‰çøâyÂ9´1VäHðn$˜@$ üäBl]¢£¢kÅÒg^FæA‚ó‹U9Vx÷€w¥±LSñIFIm^Êûyi̪—Ñ&zu¡V»ÊLºÜ¦Ñ’tMTüòÛ GÖ^|=çD™ó —îñè=AûÇÕÞ‰×ò…|p›Dsæ ôtWÎ}ü-qD2Ä– Ìâ¨Ùèɸy(§Á¯Ùdj¨)2çiºü÷ÃÎEµ0d$$à éЯÁ¨27Àà~úè×½´*Ù(•MBUƒR»ÇemÞ(ï âôs+å+R™áZ´ÿ 1΀átaØþp” ÿŒ1J—ë.™ð…üå]NËð9´x\œfð¹ ~O§?t¼³Í–£X8Áü®+VªØß5n÷¯Ê+.6ì½]×z¯¾íRCë¹M—öOÖ´N×4ßÅ:^óÊåÚ—4‚1Q'4ruG¶“õ­KÎŒGM·j›¾ihûSMs&¦]SdªªêÄÄÄH„A~@‚d iñ(¯Dbð“L$°„:5ÅP˜†YH®pIÃ[9þÅ|½ÇÄqÜqÉÒI'­´Z­V£]íêöNwÀÊÃÀñ<08œy™`¸€lóÆuð„ó>ˆc7­Ú(±’0pø¡$jÕFÊÃo÷¿V©Õ?¢´qÒÚÃÝqO×``úÀò_þÉÈAÃj؃ٹn¾ŸßØÎ«c,—>e¬ •  v4jG—Å»Þ-ÆBGÛ`CîB4’Fà~)ºlGnèÑ¿-@î:OPÇvŸ;t¹KÑðÔi3á¤ÕJ g”‚b:Žƒã˜WKîM¶/šŸxkž¶Yï O nÆï\ò´.ø;3³¾êÅé¶Å©¦§¾æ¥)ç¢Çù$Ð63ÝúØÓòºÔ³õO5ÌMÃÜšÞÆy3tàþ’·Ép.O:–fšÆ}]çÏå„]fÞÀëDNÓ‘)À OzÓHì)ô0ßñhN%PÉög6+é‹'í Ì®(J…n3T‚Ä•FZãI_,éˆI|ÖŸà=i‰6ð ‡C “UcJD(iK¯¹’Ö;ÓHwNvëEþl¦žR ’ÞÈ ¼Êù¯¹"H¿…J†®U$HaÀ ® [Ïu¥bHg,M«®t¦.ëj‡å^MÔ{ogFª"­98ñ17à Y‚úQÄ‘D=†x[6|¸È'ëÄý&å\„áÃhÓÕĈ»é–²’fóRÖ Rˆ=uµ`ï+iÞü}ßÛ’®§ì‰ í 7ü*HÎÕ qX+`c*\UàUAÔñâF”KAœdaÎÞ0ŒAÐ$ê¹CÉ¡W Õûµ‰¤#ƒtS)º`e@›qtYz¬Ô={)€á%èô‚7àŽu½3y½ó9Û¢ÛÞšÒhÙ BÇn⊘ïÞç´b…‡UÖ12¶*»'°_‡cdNT"á]@a)Ë,»€ÍŽàX‹O5„niÍ ½I¿ËŽ3à`QD,–ªÃLˆÀFÉòõ£zÒs€b¸7bç?//iP,ôÅ>¨Ë Öªœ6ˆåEY Q¤w+ëÃz2(‘LrA¿0h¦üx©R‚ÉGÒåz"0˜Å‚ÊÁ·È^xK3ñ¡BF1ùÄôÅq£Aâ^N4iÖþÀ“D: 4àÍ€¼ÕÉøÇR ð4¼Ì+±©áZrÃ@¾áÈ_yr‡!×täø„!·rGGnrä&·1\×ïðä.Onsä&Knq´ׯõ# "øKåw«²‘c´’(s¬ÆbµåÿPV;Uå/­yTR¨>¹Ý”Ÿ«vú*ê'Ë“UõÕ *_eÃ+œ*ê–SÀxªê<ÕŽG•o?(?ö]¥Ã[Q7]QûceÍOUµ3å5 •5ãÇwZ#0ɇåµUõÐi‰Jô²Ä Áœ|²Á i¾º²”K~¶ÙôÌþ°¾ÙÖææ#ÂÂáDT±ÌÉŒtæ-Fyh¤`Ç52š‹F ÑÐ!4RB)r©/f«£[Q/Ì*rf¡+‡ÑØ4ƒÜ›°£;ºhGÃ…[3Þ¾FŠè8ÃE9ïÛw9ÒÅDƒÈjUAÏIX¹ VÐëÕˆªäž?•LùÚü3Î9oÓÂDóôtËøB‹Úù¿ÇNßlkÀßæ÷mÚ£iÞ¹ß8ã91?÷z( (X À”^hdÖ×ü8ÐF&AP¾™ö¿ …©»T8‡a»­#N~Ðüq¥Òÿ?…^]ñ;~ŠB0u@%ß$.·í!ïXÉé˜ù3oÞ¯Oüm^xEÒîŽýa_—ç à´@Ê¿óiÿª"RáL1’¨aX“¤=_Iº¡HL¦çŠ÷¶gý:\s·2…ôfRŠlj¤;ñ•Sd#²iŒöî!®hÒ w’7½µz®ÍG§‘¾ º°íQOÙþ\²çx¼¦c9‰$0»›Ób^EáeÈw…Ç’¯ðz© {8Hê4–ûŒTOî¾gù6bÏZ|sÿR~ærÁþ•Û³‚ŒµÂ4ªˆƒÖW¥hËù©Ëùi+3VîV³Z˜·|0g"'ûÛ}é—,1-fãAƒ¥Ð‡³B–Ie†W8¬ST,J<Ç+‰ëdkRu·Žýâ)¬®ÌRüÓË ­ÛBúa¡b©?{¢×»£H¯…ôY)K(EâIO éÞö¾ôlà°ÃBÎì…-xz:ù¿´AÙÈ F‹A¢øqž™îQ—õ§¦Œ23Ï`ÆŒU…7kqVCYV“®G·j3Ÿu%ÓÑÞÍr¥á=ÀYij¼¢WYIÃ`­*ë°ôþ¾ìkoU>¤–81Qæ˜8êôT;'Kk·›ò÷ËjþSÒ¨LUÖOVÔMm4ÓSV7]uÂ[í|¿VúöxÙqoUÝ£ª†™£'½eT)ãÐÊŽ?ªv|_¾ã™E`zÐù¼¨Ü(`Qõ‚l z²¸D)ò [Yÿsýz!¥-O¯^ÅTb²IÄ\²Š«Ñ`!³#wÑŽkä’zàãBª w>ú´T¶XÊñ§È:ªFk(w®}~]ÊFî\4Š(@ƒùh°THG¸¸áŠí>w žx]ÈA#yè³CÈ]Š\¹Bu"£êdQ6@Fðª JŽ3Z¤¸S™ÃÿtÞ÷õÏζÍûV= Gö9PŠÿ”×ß:å;5åkš›k Ì4ù'küu¯K#À! ÈÒl+ 4&ŠÀ}˜ä“©–Å@óßn×Ę /TX\­(ÔüØh#.M‡>Ëz…žo;_ëõA隺ÜEúÂI7¤Oú=Gb•…Ý-p:–5±ÿg¾Þcں΀_)’%K–®®Ž®ŽîÕ±üP01ø‰1”€øXBbÎÒ®å‘Ä ¥ð2$íªEjµªmB Ç¢n«´¶ªÚfMWmÓþ¨²©Í¤VJYÁ$ÆØgß1Y¥ý‘iHA™õùèÚ÷úžïÞs|¾ßUec#>5…üÊó (¥]…ô¤q©}{·ž†øTYÀ’R„o~êpÒŽt΢=F€×´73‰ÂGÙˆèÞÆ4v²ä¡žlcW.¡Ç¡Œn÷åÓp.T½[/[O×lwe• ’$aY%­„uÒC ‰½ô¶¼_KÎäl¹æ°ÍUWP_1õ:©×‘Hb#沬ºLÔWò(¼Î €$æq<)ŠPŸ•z-¬õÙW]Öo²÷—#ê)‰{J¾ç¢ÞòéêÒïJm_»2 {7«ód€” H‰ðÖ`Q«„§5,Ã0Y©Ä›ôDÑ”?Øù í„ê ÷ j}ã“›™!äµ¶w²/‹Ý:˜‡}VÚS´îqùE›½¯YæÛ3éIçB¸,˜¢°k³¯lHG‹á*6R0j橎²7ªž1j2R¨Ÿ/«Þ­Îë¨H $õÛ›õAÝÌ+$X °Zȳj”-)ó¯B*žd$%MÆc]r<%Àê¶³+°|¸Ï†e¥(‰Zx â Y~SMG²èpZâm‘Ž"zæñ•è™:$¿Ø½ÆBÕÌ COOap½p˜<7¬™?­¡g CPdDó?j„Žj.¿ J*œ¦ƒ‰Â§KÊpð€à L¯ ú…Àøí—Àý<¹ë~ŽèG*z•ÿá7iÁb•NáŠG/Š‚,ÁBÝ”žý—Ÿî¾íožm84׺ëo÷7ßh80 Ý­?¸Þ*ÿ}}Ë` Ј¿eÒß /ÇÍSA†FÓ| & † —Û7ëC7@)wC·ê[ÇÞhhÙhÜö7M‚¸-þæëûC~CÜF„._úõšFVWcÿç¡I,­r†ˆÇb?)¯Ð‰g°¨ä—sïíâF}L##L‘µ­å†“c;6B¥*ÄfÚfA›†ˆlÔrGÜhw¦†»°‡¡å<°¤œIæ|-7¶›«]w§çv0@;\É WsçÀEpž:|Ò‡*·"‚5«±RÄ ^ œ"[IÝ©š¿m™ Íʹߟ:îŒÜ ÍÝ ÍGÚfgŽNMµOMµÍFÚFÚ"¡§¥@HR m‘»,‡ùHÇÜÌQh£÷^¹1ýâÄõ¶ò|„IRé´˜7é„ïZòè‰Vº²è€‰ö[io>«­¼Š®B­éÏBõé·Ð^Ûûþì¬%Ô2^«SjeQÒˆâV^HÏ!ÒÁB‘¯ãN:`Ÿêȵëp*=,ËbFéfå½îZ¶Ò6Xiï¶•¾Ìå~(gæ÷UøŸñ„.a  Y1IJÙX=…]´¯œv9æÛÍ¿õg–çòJI¡’yZTKD‡5©H—&hÓy’‰Ä\mÓ ¯gê/³¯•Ú¸ÊèÎç¾¢y·yzGAÂm[uÙ¢nû’§h9é5„Üw™æ\¦yÆ˲Û~HšÄù¤4õX!V¼,–hl[ô‡¢C­‘ñ=MwÀ?þæÛæÛþ–‹µj„‘ˆLŠlö•å(M¬ÕúÄSÖÆ}Åb+?¶àH÷ï×þ&a¬a’ð8)O5pçws—긑*nȳáðŒÖpçvqg=Üh7â厕 é)·¨ÕjQ# B$Y# ²=…ëªåÞÚÃLò~-w¡Šó0Æ@¼W½Þ~7®aò¹TÃ]„¼Ü—ö0ƒ](g2isèLZX;yàĹkZÂ<©Ñ? üõVWäæÙ;­‹³G'›§F#í ‘ÎÈd;ÄüLçìdÛÓÒÈìÔ‘µ“€Cf§€%€“vHòÞô‘]•H‡7Ë¢D²EV^ÙŸÃ0Ðo\éÍe¥|ÀA»­´ÏBOX7| í†^òè@þJó“çC*BH†a­¤"’B/òÙXÒ *"°¿«vT@ª‰ã¶¯Ÿ/Ð#YÖ¥#þ|Š1_*íwÞïµ°ä™òýÅL#@²1 %ŽåÇ¡¢ØN›’Ô¼Òc|Ó›»+ J#ˆie‹h³ˆ©E€– YsduÀ`4f_/+ˆyL]v GÜmM¸-ÔcJ¸MqyÕkqY¸€Ž„¯²ê.^r=¨.Šy-q¯5îŠØâ@·ƒÅÒt÷¯²”ìÔk£^ÈÊL½&h,,q6–°ÇN=ö¨×<ç*x謊GÜ]©rþ‹ù:m"=ŽÿdtÏq›Q+èN2È¢AäþÞ¹ yâ¡_¿‘RïWa@„yõ tÈ„êeÐWñZ®#<,ðž#úÔ …"ä¹Fž#䛯id؃È!öýš =«*(sd[tOo <ø  p‹‡›„¶oë7Éçýê±RAÔAâdÇããð&#§m/,ýìpÃÔÑæ»áæ;‡Ú&Ãç&üà2àHÓl¸éAMÆÜ‘ÈL]ä~¸q³UþAÝ©;µ ›;Xñ«O<¬mš­‹Ü«;ùU}Ë»Åå“JpOʱŽå «Qpªsž(¸áà´oìØñÅ›oÏן¾ûýã[­‘‡1±f|Lt&9}$ÒåÚ«²œ"Ë’ bMÇÊžL&¾.ôßáO"±i2aÂ3SÓª¢—EIÕ‰:Ç\.gÆCÌÀëÌðæ: ¡|Ë5Bÿ¢’?ÄŒT1#!fÂÏŒ…˜ÑÃÌh-3\Í\ö“@&Ñkq3‚ÈV«KMš+~f´œfH5RÁL”mú'BÌH3„QÅ WÑ6Æhs­–«£' v>ô3? J‡D挼¬cµœJTU5p¢É»ÎØúÿÒøÅl|nñÒü£èüTdi¶yiîÌÂÜù¹Ù¶—¥‘Çs-çÎb BÍ´àqy¡ãÁdËèû‡p nKtªNÓ»w]ÄÚ­¸Lá>±Ï íø÷}ºÏêÈßêUt :.ìÑœÍA&:£h9èAr`>6è+ùøXÑ>3Ër§ßÁŠÒ?ê·a•A;A4o%æ;/üñæù´ÙhA‰æ®÷¹ –—®ßÎK4q/Ä<3oÛ*L¾‘^T Doä¿gâ9ƒ`$‚Q ¢[.YwÜöùž(]ñ—`¡ZñI¿c=èMU”B…BîdÀƒÕ ð%%© ‚Ä !W"ä\JÇjȾ´CȾp£ VBHO"èYK"ñâ4’ù’%k¡âµ R"Xœx’/&¹t¯ÝÏ!˜ýë@à ~ïj€ž¶îwAÐIŸ¨ÒŽ…r×Ãý% |–ªâÅ ë·®œs™jžHÌ„8Ž®9²—sžÓI2»Ó¼•+ÿ&¼kþ\tá(À‘™ˆ97Ý/è™ VÊŒž}t´tåA ÇRà­ð¶Øk8Ú{+Jw¢ úœµ­Äì+HÙ.'ü]6èDjº_7g ZÔ“,H?Ùo€v„J.=íBt»V[óÍ‚ “$IE{²/K#ôEµÒ'êÅùkO7œ“gû,Z«h!˜¿@r$ùñÏŒ0ªÀÕµ0a€+,EŸFЇ13\åÒQ`€£qÍW< è¿Æs<§Èµ nŽ1¢þ—úzi#¹¾’%K–V«Ñj´«µü 8Éa0ollž!MrÁØ”„‡\CB°MœD\BÀ<’{Uí—« ï$W©ûPÛôÔ^¯jtU®UÛ¨M¯ !`‘ƒ=ý{ú¡¨¢EµGÃx±=ÿõÎÎÿ÷'CZ2ŒbCêrJåe*‘ã‘ê]¯âÅ•äW¹'’{ˆüš%÷ø™Ÿé/Ö2Éà J^#aÄX”ÁrÇSŒ÷¿~ú‘Ëÿw—Êsi±¹s¹)öxÚä‹xƒ@‘p“zhOŸzÛw›åç<Ç.ßTb2 ¿yáwM­wOœ´Ij#¡”EZ ÆGµš–C¦žÂrh­FÓ›†C׳Ìyƒ3ûLhŸ×û]çA\S gæ\þ¹&ÿ'µ-…"XDBR«ÔÙ_54þûƒ"„z)NûXlblœGHÀ8i´¥i̤‹™ÖåUMë@”ë{—µwj×ÊIÀÃoCJ„dPвð[VF¯•r¢bøÚÛ‡µzAÆc™‹ïÙ\b!éô”а» ¼ÍßèÍ$ù¤×B·å·ƒUHï¿Ïµ/ù‹ß<`CÙP¹U±ój õPï‰z82 dè?=RðŒ&h3¤æ-gNÔ™»í0Ç…ñꢸü`ÙrD« ¢0pZ¢N #ê -/«*¶«*â´•Å«J€+À@©†D_BÅq Á‰:¬›ë^idÛ^@#„/´[⎢La·Å%/E/íÖM@”2‰TÛ V=¯¶¾pX6fz:ÎÂ*ózeþFUÁ¦£¸¯†sÉÚó!Ôx5@«8b/ýIQfKŠ¤Æ ¹ÈÁæ®æÕ¤aEü’Z¤p¸A{êTd|°q÷—ÆL®ç’¾œ„¨aIIHì‘¿ +$T¶ùÍÃÔº=)¤¯ŒtÃjÏ"}‰ÅÓm¦K|Ò_JB6Ò•ùqK¶BR ˜×a™¿"ƒ\-&}ÅtŠ~¸ýQÀÄJ2-ËaN™nP¿2tæÇoXâpÀàÞé*{Ùm%}šßû+ÓÅ$جô‚Äb¡*]"ƒÀ ¼“¢ÃÓaM| ¤É ¦ºÉ(OnéɈšŒJt0,‘Q`‰ø4ãQÕŽ¡oæÉM‘L w' HÔaVÉ«EVü툆|¢ ¿àÈ/ù)šô£L ì ‡t3å>;E_úçÝi—ï ·ï±'0ím‡ñ¬Ëw›å<íÀ˜¹FßrUÍgõ-¶²\Ä‚H9 ;¿è4‡Jì®kõ^øÂXqµÏyƒª;3ÛÒŸZq·C?»{í¶M{‚ó m3Mmó$3Þ ÞÌ<ŒøH¸ñÑ1ÈòÛÛ[‰t{¥èØñamE·èŸXœÄ¢9&,ÁS`yVq­š¹õ:sÛÉŒdn70“©î»FnŸdF*™1;3Ö û®›ó¤³ÉúœìÔòt¦ã8s«ŽþëûƒzæÝJÁ¡fÊdòoN1cÿú¬’i²rßã·tÚ¤B^D2/HX8IÄZVP++¶Xûà—"—æ"Á…ÈÅ—‹—) ƒ‹«Ÿ¬^ /]Y_¼²¾\\iÙoD–ÜÏÞ‰,wÍ/ŸƒÙ#‘ŽéǾ#Æl/*%^p©Ä‘ŽRÒ0Ö—IzK÷ncÌÚ åS\ËÚè/¦ef—õÉùÒ»•¦«¦"“%×Ëâ!# A}zœ–¨½™ñÖXOñ±ƒ´|àa,KÐèí»2h¦è+ÿ´Åœ*$±¼2ÕUºøµ4‚÷T"Ò“™(r÷*~ˆ­€†Ý›øNj¡Òg|Ùc£GB¹´ö YÈeËo<¦Ú</M± I:¤Òòxž“8…Jqã5þGÖ´ð‰â¸³Rù¦£0ê´AšÞ3-üŸ·5;¥`fþ¸e"7µFôˆxx"z‘–ÃZ¹(èùõBõ²ßIBô*_- ]pu@°*à%ðxîÏ&=y”¦Ý@ +éÝCEgoôÏÓ')YŽSkJÙš­tÝvÁ,æ™·Ž¹Š#¹29 6 >‰ÝÈuÈu@Tùçß0E»JiÌ!¥Q°‘P!î‘Þ\ºØÀÆ¡Ä\ :NˆbÏâ/ùAMš$©9@ŠX}õ(háåÄM™Ð‘ï d˜Þ@(²“"öª+ÉK†udP¹5ªï°£T¨AA‡óêr™íŸHðGƒº¼ì$%âÒy‰Çp{aØÒ”RõÈÃFÿª÷â¼+ðÄXsA`€ÕƶÙfÿÃÓWë|£oÍ|Ðxö™·}¦áÌãæ ¸"âÚµ Bï <óçÎ>lúLzIJ•ÀÊ« ›qWáús MUÏù¹¦sa·o¶áì"HÛ´«zx¹ß󀵾▷}¶9øèԙϪϜȧòRvV%ÈóÍç$¶M¶^1;vx|…¤xœlo?¸óHÄ‚{Iɽ_ÇL:™I;3äd&ê™Û5ÌèþkdDq‚¹S£è¯–id-â°BÉÑu(Wɹl¹ìý×™É:fü$óa£l°†{ÏÎÜö2ãµT#5Ì-;3ûþÇYM‘v³Iî+ãb%Ç& @P$Jœ–Uà.Éo:ý‘çñ|7 _ ‡/‘ùŽ¥•ÎpäÊ—áàúrÛâšoyéRd®s¿5òåŠe¹sa®s}5¸(šï8ûFf*–)9$Ç"m-{ éµ/±^5ïÙîÙá†)Q„H<»f:&f)“Ò‘LÎË’UrZZvý“ùºi"Oã> I“&“ÉdòË43™iC)- +´@¡´´T\•¾øRJAEÞÁE‘÷¶º»ÿÜímtÏ7ÐÔ\Ü÷r—MLö»=/—Ëå.1ž»º  ÝEÒçžéî¿÷Ç&pÚ<)”dú{˜þú|?¿l1ãùóa°P9ÆöÙŽY4<‘DA"‚ê«ÆmÉA]üaµ­œ)qµxD$-ËÞ©EŠäÀ0vî†þE#áÓÈ Cém$'yÆ,¤Zغ2Xá,å笸â­jƒ#KbE‰Fzðž(a‰@Wˆì¸9{ñýЇ»K•nð—ƒßð–$)âX÷½u¼#~ç:šÄk_ö9À_ö¢²üK»m(Û(Ê*Q£ÖÐh:AÔÈDÀÁ”*Ê©­Nݽ#xó“!¶Å¹±ˆ"EF÷âV±Cرҟ§¼<ï„þŠòBeoÛ«×ó©ÑÑHRºÜäïMò¸Go3Š´Èã„#B† ú²) {‹›á£b8³ý»–RïFTgÂY6Y²ÒƒŽrÂP1„ípf[ÞIàN~ ñy÷óPÁJØõáw)ŽT-!&Q}»1i+&¸¨†ŠL®IpŸÉ¦kä3öõX&Œ¢I£gcÌUŒFJåy‡L]8j8è¢2„4)ÇJzžWiØ÷hv Çv·ªé»ºÎùÐñÙš–GÁtÈý`ËTãÉ™š–Xmû«†®ÁÖ[îÝGr¬ž ãÍ ÿ_êZb‡:cŒéÙÐ/NùGuíóuÇŸZ¾kêiÍÊãyVE>K÷ü-pt¾¡k:Ðò$Øö²éÔlCç?Í3õA<µ}—ŽÍ6ž|XßñÐÈL¨kº¶uº®}º^iAb—e†c$ŽGßÿù¯÷0ï_­½Y‡øÛ4Çÿ~¬+•ˆ£—‰“2«ÁR²¿6ŸºRCÝôRã{¨Ë•ÔõýÔx•â„ÍNùÑjÜOýºBeáL4k ^ƒ£žHŒÌZ(ÓR·Û¨ ¨‹^ê&z`5zPé /œØO¡F¼ŠÆ6_#ÕÔm\×G¤? jöåÒr*ÎOÌ#š+ËjžOÐ;?þ¦yqaäY¬yy®seæôËùÞùgžÎw.Îv'æ†6[#±gÇ_ĺŸ?o{1Û³¾0x9²KRãÉHÅ ϓɪløgcÞf®2 Ë7lúE·Cß6r sfN™C¹‚Žc6UÒUD°é¨€¨Ã=Kà·z-µ8¥4N˦ªµãÏát. m[2À€õQ«Û¦OQq)ËìRÿqWAÌäA¤úò· mÜôŽâ‘®ÍÇ®` ú18¶ÂHôYïToµ˜$VÀ¡.°4«çŒ,GXš6¦;3í+gÑÒÞRða91aÁçŒ]¤ˆ·37×öÖðŽTl¯+Ž·èWð(…¿T•Å=®ØnǤ%Ý#3"~Ÿ8¢Å`Â*»5»Ï&|Ýl~Ó› Ã%0âˆ÷e)úq'?23|˜ æD/br÷†í‡ˆóu¸pí{g1Q©U:&“Ó3hµ–U"3XŒ^âp7œ(Ô.ì€Þ28· zM·¼–l‘ae—:¹ß¾I²}uAªÉïW¶½ÉHR Xø¥ÀÚHX œ½6\pØ,‹¼^ƒßEÂäØûQ>Ï€«\æ\âášWÅM×È•t5À n¨á3.é¾hfh^-q -ªN%Ò¬†IÓq™:NfxƯ×ÿ¾20u¨ûéÁc‹ÁŽåÃÝ ¡Ö' í3µÍ¯»îïo˜9Ü9lýãÆJƒÉÈ0jŽåEM6ÃU§›¾Þ×ômm¢ÑòKS~¹¾}¶®má`û'e>s{¤UW+|sûš~²Í³Ú6ȃPÛÃ`K,Ô1[r±¾ûyã©oªMíA5-Zž…ŽoºFB?òl*ÔöHž4tžwïxŽà¬g¸–öH`æ'Ö“?ÞÁÇZ²·8Ä—4È#§ÂÉêã=Ôx5uc'5QI"ª©ë˜þ¾MOùKÊZt}®Z %†åJ $hçòuÑ©Óêô.ê“ZfŸ™0Q—öP“~¥·±$EðZTÓh•¢¦ñMn oÎÕÝÊBxOöP·êÉy?W.dpÑjAd5z‘ÓÓ¬Z,cwü¶bòÛ#O{×^õÅæºœé]™~¹Ð»´Ð½ÙYšë~ë~µÔöÃ|ßÝ/³8NƉ©Ñ²7è” Z²2d„ˆó!Œiîܰéן¿®€óÖ©Sƒ…QÓ„æ ‚¤b1_˜Y†2ˆà΂~ÂÊ´Œ:aÄú‡&«‘¡eAkà¢ÊÌÜŸ–GÎÏ«ó\z6…NIK7èùÓrii°"žåB\1\¤DÒFõßW‘"ˆ*ï9P ‘âD´xmÀ>é±8³0‰ÈhP e‘%[ˆÆAØHö–ít¯zÊâ•¶UOáº×~Ǻ׵îq&¼®5ŸkÙïúÁS÷ƒßþÖðŽÔ¢·ü× >;øŠÞx¬Ë• O!š$î+Ÿëõ^×ÝÛ±tÙDXÄ_«½ÏJ,†)ÝT(Ü;š½v?ôÉøNîŒûp„*«ÈÚg á¼ Î9Ÿv•œp鵄exQä$51¥²D’„5H4iË"³]nˆXW•=i½”Òù¤”VD¶¦‹üj&D!Ðc„sù‰óù«ƒøÒÃÖŸ5‚‡,üwò7Ž"…ñ!¼3Ì{zv{©Ä‰9C£J!Bµ…Y» …+z¸A$°0¡…ßm2E°&4pQ×¥µQ®Ip[¼œ‘%ê4mOD^e9 ')!¢p¡ôýÿ[Žaì~øäãúŽéš£S#êZ›ž×w fëŽ?¬í¨ÙjN9Ç †çYß«4nùw õ¿Ì—kLÙÇGŠdÉÒH£ÑÕèjFcyla^q0ó06Æ&‚±ŒÍ+UbòÌÃ$M·ªÔÕF›fðHÒÝ®6ÝVí—¾¶U+5}­Ôn»ÛlºI „6!,)`ßž1©ú%_¢B²WGWwîŒï93>÷ü÷3oàž÷À˪üº¦Çí?ªjÉ`8AT%óâJ=Ÿ{÷ØÜñ¼í þËü¼þÀ´¿ýIóá/x9üþÎÚÆŒ=»e·| õ¡i_û+ ‘{ Ayÿk@r¯)ôëªÇ1‚2%‰ÒüÜ#ƒ¶òº¹ãÅm9Û2yvùƒ÷¡¶ê0Š·¥PcÕ²Î^*¡Æ]²øŽVo¸¾¯Ùu¡–6¼¨F9*j¬¯gMbX­]­:WÍ8šVl6pÔÕFêm§L€ãUÔPœš&âX2¶ñÔ4ä–ý^¾Œš(§ÆÝò'­SwY‚À"Š/Šö… àÚ%y¿_ûÛ;Ë3GÏœŸïXzpdzîÐHçâ—¡G3'nÝ8n1HjŽç†æT>¿pÂF"™$œ!×pY| H8mÝ à`æW=Ϻ;3yFÜŠi,¨À¯7Y)ÖüÄ—/kGWé7’> [É`’\ŠL"Û;ÌPxÄp¢:€Rj?'²*$iP*Ïñ®4y¼ˆœ…žAºÓãsåÞ»~êÓÒޱ@;Y°þ»Õiæ$¬ƒÈÄ`Zàè4ÌKH°ø|fòýŽ'®’϶•ÊüUgnÌm^q[* –<ögnۊ˶ê.‚Áb¥uÙUHv;^;|MŒxŠ¢Î‚¯*ÌQTo#n{Ôi[qÚc•–E§mÑc¹í«¶O¶[9¬`! X1'j°DͲ“ðéQ éω ºôØH—9η†õËHάÕØ,ÒSòaMJ¹^¡ç6% ´Ad9¥Â”€Ï—oY¿È]‰\“­‘RÅh¥†G©’ò¼ßúñ¼ÛÌÂ;É@1éË&½éð09iÁ›e{î.>î3¯[ü«ü ½° éW­ùI,¨iŒ†³\E†yrAEF0âd&Þx¢Fä’ŠŒ«Ö•§« ˜IàÕ°¿ÿ²ˆ¥CYŽ¿Ô´ÞmÜÿ°éðopÒ¸é ÞòfýgüÁÏêö=i>ô纖ÛM¡eß‘?íÞg€½)òZ„·"œ‰QTA¹•ô[–²É掅æC/«ò7›Üôö$&±˜ë4Ùî×î5&ÛîÔíŸò¶Ýmé¸ÝÜñw_ð£Ý%ž­R‚tžfÝ›Sþà?ø õħBM#íS@ mk4²6†ù©Æ?Ù J² !š½v퉂ìÇ^7w¼¸­@\±X”<Ë/¶éDm"+0vÓ¡8„\ñÄE˜Ä#Ë=èþXÕ†«üD)õf­&AÇÓXÚ›M½çÚÔn!¥xšn˦†«D6ð RPcuÔ¥zjÄ)Û%5ê¡.×ÈqÂåøÆSÓ‹šˆ÷ÃÔP…<~øÄI½ã¤Ú­ú$!UIkYcµVÔ«ˆ5XÙš^ûsÿ3]Ks¡/f[ž> m4ÌÏœ|úð䣩޶æ|–¾g4™˜û³È¹mÑÎ,Bz¤ÇNºmä\ÒúÇÒa念µ,fY}ª¥ªy ˆÞb)•%¾Ç…3,\öXÉ™-Ëa#é·Ã©ðî±¢Öd”À)(Òc^)bÀŽO-ÆtéÖMO;äì¶ø)êyös ›þWÌÿëI“9í¬˜äzã–º­pÈbÌj±NŲ‰<›Àñ…½gJ^vÛ–]RUD<âÊ‹¹ò¢î‚w!̯VÅÜÖX¥9V™O\V×_ ùÖëÆ€¯‰Å\1WaÔm{Vi[¨°-9íQW ñì îbâ²·e¥2w l·õK—m²,¯?9)W¤9N)"Ø[‰×›‘2³=vá¯Gd°˜œ†ŒÊ'g‹I$Øzåÿ#92 Ê‚n$Ýi¤/w!¼ýzÈñ–Sºè6\o³>éÊ‹v&“-dÐëÌùEu–éx>c q ´¨Ñ#”‚hx¿I{똓tYÈ`Ì•¡зßü¼_£‘õCk°¾LÒ“)÷álؘß-OcYIdz’hP1Ü/Jä"&#šÕQHWm8€—!‰Œ¢»ßáO8ðfQR0Œ#$½F£BŒ+%õg5­·¼í3Mí÷j›þY·¶©c¦!xÛ¸ ï ÎúàVÇGî†o;v„-Å?ÝÕðÃò†­œH ¸@¥»V^}½>ð ³ñj„µ¢ø»Jï´·íeUþ7ðIcðÊvA÷¤oï €ÊO5µÍûC³Í‡ú;fë¿ßå=e5ªD3€! pîâ81™û«nÖе{4Ý©?°!÷}²MûÛçü¡‘R@;áÒ²2Wü×Í/n«ñئ&oУb±Ä°Š –º°—sÊì1º—‰ÈDÜ^Ê_vRg+Ãè°:­"“z§F,–ôŒDjØC}XË% +aAI yâ€ôߨ.ÇãvÆÇ5' šÌ!nj¤šºT§5˜rsR£åÔUõF9vJy†f¥ñ€#jVb³ÔÔ€%òÇÀôLÏ“¹“M#Ó-ÍùV‰ž×)±¸ÎÎÓã{RHÄ´,×j‰XÈ@>($§rÈ™u«Þ¤ÏDìA#Í Véh†÷XrÎFÎØH8}%œCz·xÏ&ÝY>Ne‘7rb€%]äLþÜQǹ1E ´³™UèE„XœÍ(¿·S?uVpp&éΖÖñ›eY§øcýÅä›…ÿ÷剘Å<£Jägisœd¤«yºXu©6/V—c±Â´ìÌma}ê´=Þe^uZˆ§x¬ÿ!¿\c›È®8>’%KÖèjt5£ÍØrâ$@ ‰óò“Ø °IÀŽ "$~‘…Bâ<h ±ã<`wAh¥ª+–$ô]‰UUUªöC«ý°Ýí¨[ qB€<6Ǿ=Z´ª”HÉ‚ÔÑÑÕ•gæÞ3ã3çÿûË”ây5w$+ìñrÛ¼ÓòÖ1à‰„ÛºX±}¶Â1ív,¸Ëž¢%·}Þ§hÚe}î2/ÂÛ{ßB<&€º…rKò}ó‹=%çõI¤U¢È$b`^\¬Eý»SÇO™I¯%ÎM„-$Z¼fõÜ‘')@ïÝùså-uêe`ˆ¡ðæ`£s&Ò¡'=-$íæßútaçhÆh0‘ È=P‰¢Ô*fc‹A1±“néN€œmÉ3Àçùò.òŽ+XR°fùwå‘ö\r6[vQÓ|Ø^Ÿ ÆŽUXÅóF^û8DGndA–ô1ëN#Y˃êóU)6‰å¹ `7²¤­4­¯dä¹’²Xí¡1àa 8ì«{^{j¤¶e¸ºîi &kêcµÇnû?É+ÔÙƒ‹QÃ1XD¥^{‡­tÆ0ævå!Wj¦‚Å ‘©Ë1Ž›ÞTå'ýǦj›ÿXuèóŠì;lùÆ[?á?úêº;ö§¤BÎZiæ8Èü'üÕÅjõÅ|û}oèAMÝß‘õ¦ˆƒLJþ†Q_Ãk™4þ½úˆ™‡ƒË`x„ñ?>$ï(Œ$¶?mžÓ08•Ŭ'CÖ÷{©ËTß^êÊ>êfuÃC]u~4€Ñàx8 £8lQH*‘NG÷¨k{©‹–ç´JQ·SO ¹©¡=Ô “ºê’```àdõéžuÏóònjø§Š¬¢†j¨ë€m9«5Ô ¿œê‹úE%õáÆ®Ö0HË€„ç1Ç#Z,äÞûQéÅ{ëN#c3ù“·0<Â’¦ãŒQûmO)éL!ÝV¹†­ ðhÙ$ºDÊÖ®ûé'Âö4ÌŽBäÅl†ž8•CÚ,² ëA/ä~µÆų9¤³„t¥‘0üYGºs–ºŠž¶VÜpg]Ú½-ìN»åO_l·Íƒ(têèIç¶óôòj;èÛÐÉ׬{ÏþÐ~¾X“Á(ió ÂÓHÇ žþ™Í0ã,\vÏ8wÄ…€ónó\¹)î±ÇÝÅ .ÇByQÜS”¬°&Êñrã‚Û4ë¶¾tYf]¶År[Ò·¾u xWÂe&n qÛ’në’Ûºà6.» HEþL¹^ ©€Sæ¸Ëºè¶Ç=;îó®Ü• lwµ¥mŠ%X•Á<âx†V–ë¿©ÞB¢VÒÄ›µfõ F aÍ(°5 ô5’Ôa®|V.iS²Ã¢ÿKïŽÑªY•ƒøê7~R"‘Ó ÿßy'Ð<­å6üzß6]ä óHÔ‹ÏM_<±9° à:”·\ák”d;9»ƒD³HG&9ë&‘¬ÄiZHOa•<’»mФ"—DàÄåÒ¿î4òy+W’±‘Ç@úI™,ÍÑÊM"wÎb»<1å==å=9î«v°éIMýhMÛSÓ¨¿é¯aÄßøÂ챯éâN'ÜyAÌЃ$NCÓÍyÛïúkG¼‡¦´îX^)`=B_VÖ¾©Äß ÷·Ly›^úŸøëÿVsäÑ–¯Ë}µY9¹<‡hÃaš:Ë1âžwë6ÿ´lÿóX ù‘/4łߊŒ›þ+(2æm€õÕ›Í#-HËEÎ%ˉ·KÉdâ¿“äëñõ9ƒÁ ±˰ˆUR—R×K×]ͯ8¨›{¨›+ÌÓðÊî–içf){©šÛ•¡äYiZ-0¼ˆ1õ©í3y5F A©h-£k¨kÎuÏóMãz%uƽԵʕ€tR %£ä”*žãI ß Ð< eæ­¿ª¸u¯=‹NÄN?›ˆLއŸMœœ~Öø"Ö83yüÛ©Ó/'ÚFcÇcÏ[æ^4ÏÇ®Fs“áç±ÐìË“£­Ï§Z_N¶N·¾œ:<÷ô‚Í_*f$L3ª²Íx:癵ó\«DiÏ–3‰:Ã9¤'›œË—% Z?Sü{¿¨á‘³âY$ñ*¬¦•. ]ت}ûòýÿñòÂEy b%û]¶6½& oD,Öb^Çj0–$Ì… š¯B™-ôf’rI$GFß^iÐ'{¶Éà \5‘ˆ‰„M¤Ç"†LoXTÝÓ&yÒ¡'ë-¯QÃ(1’$¤Sò8]Úðó}ZÒk8'á,(¶ûMf+§pjIOîíÃÆ‹%Â,äÖmøÃ 6«•¥™h±u;é6‘3z¸€DóÖ®þáaÍr@‘ƒ#èݾܞ?^—±´šeÁù)há'8ÒÇ‘A Òä*&},àH?&×ÒÏ’+¯ÆÕC 30aÉ܈Ég,éçÉ@ éä úV–º©»Û»¥Á¤LA¢Ý„~,I§ÒtëÖü?W^MmLžCþº'µM“ÞÐ7œpnÞ*ÒÂ,_µYŸÂb•R)Bž yäkþàÌWÞP™6u#£Ô±\«içdðhÌÛ G°y8Ø´0â U×­¶ïÃ`Ó°/4¾UyàãbWF·q"x, ŽC<ϲl*ŠEéH®ù¯ûµÍÿò7ŽV7<®m¹l|ì¯{ ­7¬Ào5¡;ûëÕˆôõ]ñ‡#_‚1‘XNþωõ<`»Wû~C$I¾üâ ^„yšÁyõY5´{ý…Û-Cû©kû©ç¿É¯Û˜¶®3àWBBº’%ëêèêè^Ë×–m^ƒ›„WÇ€CHHÀFŽyYRA08 3 ¤Û"US_Ô•ðÚe]*mië¶hû²M]3MËš*MÖ¤ ƒM 4/ΞëDQÍ2‘ò!èèê ¸üÜçÿ{˜éýÌL3ZÁLîcÆí¨·Œ$0Âð¹ «8B`c±Šãö$ľu9]Í|dÛz~<³€"ãÌ„ãÉ–LVÊ ù NhÈÑ&ŠHÁBõhW0ÐñH£U°mîóu_ý§ëaÈ»¸è^zÌöÜ ÷ÌϽ߆»×ƒ]÷oy—æ¼ápw4„æZWA í+‹¾•;þù[-Ëaïò‚oÈkIP±ü1Ú!;ºcÑo¦Ã/\#4{Þ¡fy…H¤¶§k¨; Xè›Ú¿kÝ{,4Oûsä>€D°Pÿþ¥7JÿÕd,Ö}Z3cõ›7íî04|÷+‰W‹-wmÖ-ã—|ݷ寖[Vʳ–›¨Ã²a/úº¤èB¾¥D¯Ú&Â,¥„Œ1aQl¦>æÄ>Õª/‹/¤}EtpÛš?>âO¨´lH—I<±Ð9£{#R}îÒŠ”(hvp繆8 b$^Šçt¬È§ ±g«37úK¨ž•El§Ì \>’rw ÿŸ­ùFµ€T¯çÅ}R—ÄÇHF´§’Ð@ Î…âGݬú÷G`¯ °¬ÈD 9¹ü¦@X›¡æ´(öÒ$:ÍÑÑ0Æ4t\¢ïc:D`:ªŽª‘Ø ;9z ÑM¢ãZ:…#°ÑÒ÷TtZ¼ÿ®ÐWÆÆ6‰‹x¢Å*ù ÃÈ‘òÊoJ^sµ^©÷DKUPÄÕCͳ®–ë ÷—µîWã’‰Hx„Ê4† µ-_Ôy>¶Õäj4J–%XøÐj»\Óò°þõÙÆ.wªÄ¥B(E-}VóÚÕÏ7ΣsΖ`CûM—û›ºÖÛíÑž;ç’¯³‡=7\î?U6˜‘U "ôo^¡D^¨LH~ÛZú÷Ú¦Å#«Þ/œ-sõ+.ïõCm³ íK.Ï5gTe½è5W×lè¸t ©,>‰ç8D¼(þþÓ?@ô?¶ÇúúÚw<ð½jäéì'' žvŽç ‚¨òp>3]Ïœ.yá©=ZÅL;™ˆìJæL%óa)dwÌ{™ó±“ùÀÁ¸3 l¼K«| `VU¬²ÐÀ 9˜_‘ÉxÙÖóã‚dò;,LUÉ×™æd™ð#ÑCÈ)^ˆ+ð+P ¹"3îûóçúÖ;çƒM¡ÅãKAoxöø›ÞÕùî•ßâm_ð¶/šFï†zBs«aÿüÎpؽîºpγ üÎ)%5Á,?]º]îÀèKi/^#i3ûõàI=/.Κ(É &SŒû™2f™"ò°–þ 'Û“ƒ‰š!„•8îHž†öîY9Q¼yÝ8]~¬á<:˜K‡²å t8r8Øà® ÁOQˆAJ^Í'ÁÔ Ž~ Aý‚œòÝ÷ìZ™¿åqü’/ZQk­"4ò¨<‹VäRGuì½cÛ;± ¢I˜ˆFž^’”…:þófõDMt8C&q¿•öï–_(ÂÞt¹ü  Bä›çׯÌÓÆ TWÆÅs¡ž#HB¢>AŠ9[N{vËøíôšiìÌ¢F:˜þÈ¿«>%³X‰qœ ª°Rœ,b9 ñ'U”åX} wÓêòX#°ä?6’aËzvM†`å•0ç¡Òtþ\KGµô”šNèè´aã”H'Ù£ÕGÕȨ†ŽDöLéé¤DGŠÄÑIøqžŽŠ¿näÍZÄc,¬ ÂH”€‡Ñ|ÛåCm_6x®Ô6¯:£¦êmWëWΦùúÖ¯]ͳõm7œ­žä4^E´<¶%$]74ݬ÷´§¤I*cdÑé?«qOØSEá8‰Ç¼(hyág&Ëç­s‡;œ-á:™%Wµ\­sG{®¼çPËõºÖPý±kíe:-"8ŒI­>–š=Qì8¿ÿàË¿-¯=»·â SÞ©ðD^©ß´Ûk4—&&ÿ¥¢n«4r½¶9è:v¥¦éb;Fœ–„qG[ûS‡žºËû] òuˆCbblja±šS«Þ!r Ï2 Ô=-á© £ãɱ¬Ü­ÒȘü]…'üá/=uka0NIJž]×Ⱥ 6Í!?I,¶öýG`ɧ¿üšaÂPµ½0 øQ¯ÝÚ”àîs¢A7ú²\áMi=L8xÖkAÝUñsœhà𶣟ºÐeú B6Ìup t+÷[Îÿs_.yHâ+\×¼ßtË‚t¢+Q·5ýHÈ œ êG ¢ky‚E‡ÞtÇ÷ëo‚w§Ûfg[g&NLN7ÌnŸiX|Ò:5|rþYpbüÌÙp>Qª8!~Út»Ê¡Ñ"Úa¢m&ÚYüÚ5Ò‘=t¶(Y­ˆ/€ƒúp©H\‚ú*­e­5ÞF i»=ÞÚi¤ ß ‚º¡W Âõ¹wÑH ¾ºj ¡#ËÇB£ÐæÐæt Õ>j¥WœÉIä´=ZƒJµ~B®ìJüz_ÁŠkÏÒ!kÌe9-‹¥p°gËãø 3¥»çö•C¶˜Ë¶â¶/ºlK.Û²+oÞ•;wÈ"›¤âÀW{‹* Sªd^gà„$N`MžAû‡štØl+-YôR:mË‘lŒ‹yòƈäÐ »iäå5®î(¤ÍVY‘t-þk£å÷¾4j§­Y²p:ãïÌŒOW$»å\>ýIæ\»IÊt¬È©‚ ×==£ø­/÷E{íÌ¢­V±®FŒ¯xÿ÷wÐ ž¸kx»rú ϱ¼ÚÈ ,'|Ù¬£}<½¨À´;‘^M =„ö`Ú'n¨‘ÞøÉ=¢,–>Þà–{4ãïëÞ-Di¬ ƒ|},Ç·™Ã^]Úßý—|èMú‚SÕ#GBªF¼µ«š„ÇüÁ!©n¨ºþqÍ©/*ŽXx‚_#¾bǘ˜ ßõíÉÉ"ƒõ¼¨ j˜.“ƒVŒUcÆŸj¾ó¶ç+oÝÈѦoý¤tbÂßxßSûH ‚I6šwØ×0éß«j©91îkøÛѰI# AÅ@U…šÍÊéêsDMX%«6òšd,@ ´Z Š,NdÙ­ÒÈC_ý˜·~\ W‡=i:Œa©°à;wîÄ °XgÁ&kd}ö“½žgY5«ÀÇ­h°RFÂ&D6ˆâf9ê=€Ê ùE ®4óŒj'Ãñ£rí@×|r¦ßr¡Û.tÝú¨ß)û¤§õ– þR9Ö6e©/w_åò²{ßäz\#À’¾rÔ_!¯ÿ¦õ:W\¨ß‡úßÙæÏŒ,tp"Ã&AG4jAÃê ødzø¶÷óû­“³Í³¦–¦Î¬N´n¤‘Ùé O&ÃϦNÏN4--´|ú«€+ôœA J¬VÞpiD¿™všÖÚòi›õuk$vѾÒn«M‡ Är¼Zàˆ™UܨL¤­i4š+Kªâ¹,Úf¦²h»ñÏ^œ¦$ÚV›Â©&Oí£Ò—;^F¢ù4’M#&Úž)·„í«ÑƒÿÒ–L.˜é Ü•IÚÒ)E¾™GÚà í»E2SŽ9NJ ‹a£*f¤ÖD»ã\¹˜·Ñ¶õçÙ¬`‚=&ŠÎ1ƒj6&tk4[oH“uHŒ#©ª×¦ûÛÕ$2ˆH/Oú´d°!’+šM5Ò«&—bÉ öÑþQoÛÕJÕ*5ŽUJjV„9¾k>2ì­‰¸ÎFìo|î NVúì¾…ÊÀL4åǾÿª ‚EGí¶Ó ‘igí°ËЏ[vÚ ¨ã ƒ%/‰«`%‹"⌑VÀÉÆ_–¸ïUgªšºBãÕ£åg&ì¾EOh lSY;ê Ðqm5›Žë¬›u‡¦@M®Úçîú‡ŽÀˆ+x×^qG+ýðT#îИ§¨3áë}c§42î®…ïù¾½fÚ^ûÛŠêƒ*•À²*„õz}$ù7l|=yñY__ûÊ$+++·oß±ˆI/qù Ì (f†,̵òíîr:Ê€¹beú¢Ø¸da.Ê)ñÆ»¡3%Ž}m/Óç :ê-`ú@Je̹ádz!”"W‹wžÿR` ó¡Ò€d0zÙo¡Gp¨.©Uìt^׊™ž!7Aâx=ÏÉ|Ìn+(E%4ÖQmâ{¯¼s×o±y}¦z3,.æ¦[Î5=^h|§5G € )d]ä-Xyò8¤#ž¼m$ç¤çÀ¶k¤ °qpµ5ÿ”QÃb$aI–ô°ðª”8ÿ {"9*07úÖñäL‰ÓñJXUJÕnAq'p.ì°t‡¿¼ÕØD©¤c?dDä\N³AÇíRÂ3!è5ÇK^µ~äh>9™¿üjêúkÆGÖÌõózI8d¹èä¤ÞóbÓŽÇñÿx=+1=±˜›W‹ÍìaÍ#–ܧEæå"ãó’Üg–¼•âÌ ‹‘XÒ‰å09qŒœÈù^ê¾½h ¹Â’~™\—É5™\Þ½¹F82$ü&,†s$jXµ„e.r5§˜îØþû%îyoó¼cg(ߨ´Ë?鉚ʲ$ô’$²ˆã¸[·n}…ø¬­=ÿú)B¢O°±¾N6È)o,G2‹L{3TÈ\”27·?µJ™åL?Äq)s¥˜÷õRš{Ï“YÕ")käc©Ìw¬Ì‡G™þæš•!Áo–17JéÉÀ7´•ùÈMaÓƒ–Gñ°sz‰EzÓsøæ39#Fh—Œ0Ïa¯e%¬Á¸4¶èËÿ|áÙÌ©ÙÅÆ¹íKÓçŸN‡žÎžÌ4?š ÏÎ6Í/µ,Ïwÿúçn5æbd­+9Aþ¸Lñð|éÉ&m°"éB{ÀpÚvkdõmiI$]M¹Þ²R¡Ä’&%JsæaE†Â<ÆðûBI£Dü¬üÈšDºrIO ]ÌÛ󷮎ìh²¤À¶w½#“îéÖ/sýB*iÙCº³?vgR#’D)VÃq ¬ÈÙKɺ…ãfRš»f{7¬Ù;»ÿ¯—RÄj&ÖÜÏò3÷Z>†G¬«E^§TaO:^z3Ÿtå¯v¤-w$ šs¢¯P´S@)íÒ™FºÓV¨c·øvH8„ͤu?iM¡ïdÏáOê$ »t2Ï zVfeS±W½t.£S?P‘"²ŒY«üÝÙCô¿:rhu¥lwŸ’îTÒfж‰Úälâ'â8YàŽ$*ÈÕ}äG®ŠäŠLzÅõë˜ôÅ’^ œ“>>Zp¿Bs˜º¬¬Vbb —U™Ã*¼¤z+>á…Ö/ÝÁOˆ¼Ô´ý´ô”€K×A)‹:…öøä¤wÖcŒÚ|w€gÊÓ4YY7ïj|à ,zê†gÇÕ“Žš‰ªàˆ­zɵ¹F6©[í¬74\Y3ꮉØÏ®¸~Vä6iãT¢Ñ"îäÞDxŒ%wpÂøÌVõÐÕøûòêyOãreý_\þ?8}SÞàÿvkøµXéûÜ런Uÿ´°‚ã95E,8•`€‘¬®¯­mj‡mÑÈê골FhMON©$‹¢Kx/Þõ~1s£˜(£<¸^²í)Ü_Ä|h¥#Qü܈VŸ•*g¾må*’¼‚ç’*Ô2ïQB\ äHà ˆò­Ž{óu:ôÕb !ZÅL_!ÓtÇ4r­„ZhŒô*3`aŠwËЙu摒üR’8Œ$>FÂrµ©ûâýÕXøÑdÝÜRmäQóý馿³_®1Q¥g?É&$“LrròæäÍ9yOæÌdÔå6†»7¹†a€a€uA†‹£¬TE.¢n7éf­Eìš6ý°n»I“vÛ¤Úì¥Ù¤Æv×U‹»ÊmÞ>ïØ4ýÒФqòää“9çyÏ™çyþ¿ÿÂÜñ¥Ç‡µ/<:6{ÿ¨7w+"tD‡DMý•¡HíƒùSÎ6D;7Ôsý8ee¶ ¨à¬óo‡S[w Q£‘ ‘€•$€sƒ(FI²IbFFÆ:$ ¢¹Vd ½·ìÛJ»™žÉu¾5%Ðn;íË¢§Sh‡™v$±§Æ1cع÷'{"y‹W‘c–×ꥣò»}±(/T”½äJ H¡iϼ¡‘ÿ“øÞe}LRœ»°?ë¢Åœ Ç‰‡òÃDÐi4ÙíÐ6¨RV<ñ BzÂg‚ÚgcÍ'û×_ÿý‰´ÃF{íLè»RéiÇ\»£:&Bg0l×¢°È"¬¶räÒ®¸NØÆŠ¢~[c§ÝNÚÇüB0•·mzŸv™éé4Úig r*ñF ;^ЉA‰žGÃ^DGõt€ÐK&:$ПɡA‰ŽèaA/+¡ABÇÕï‡bë°EÏ™%‘-(r‹@$­ÆiPßÏ,ø‹÷Ð7µ­S¾–IÏ¡©Jÿý¶,Ù(µ®ð‹OŽEâ6$Ÿ—7Þ© |]í¿åmù²äí3ögGš$YÀŸf4µ$Vì¸[Ý|Ó}ˆeÆ×úy'¾{×ÓpÛçžY¬ |쪰ȊDˆ– ­‚N$:ï–û'jÛnVúïTù?Ý_šc'ògU³î†9ß‘ùšÀByôwsQ„íÞ|µÖë¿UÝ8Wøª¬>|*ÆHŒzÃüã9†¡Ðj(@²´²òjP2þg½²´Z]ýäãë"BÀH&‹y[¹a77âbŠ?\Â4z“UXsq?ë.îZ)7Ï ÿ@êr† WJ¥÷=‘ÅV¬Â_Ë+:,$îâ>n8 $Ãa‡*`Çõ¦xqU7Èc “K¯F€ˆFJŒæq¿ôpÕpÜÜùR\£S´ ¯U‘‰¢EPçX“®èJïÿý;“wO<ÿуùÀ“Ù¦•™¦¦Ž†þyâ|_ºAe¢*¢Ö"K“†é´×Áæ!ˆ2ÌÆ.àd¦Ô›>åRØ”;i¡fz.é~[B®Þ,F`$JCÕɲ,aQx=âM¢àŽÒ~՜Ŷڱm¯?“ݤ7ný©ã׺ìKÚ“L{Ì,{/LõÔ¹öÜz1 Î@@àß´ÑbDpGìlÞîåÂ}´8‡ÚW]IË…ŽÕÂôPóµËè›Ø EŽgù¶ç.Xd/»r~çH­‹R%EËz$—FŒçEÑŽtÚ— TØ@{mÐ#kÉ´ÛF”]´Ó²î:ìMd-ЕȘ¼PÇúy½Uá™'cÄü‘ÜèµÎ,Úof¿éþ1??Éô”‰v[h0%Œßô>íoϘƶg ¦ÿ´ Z`NЀ‰š¢“'ÎJt8žŽ*ôDÇ·¬ ô’H"鞎È|WÉÝ©•õZ£hÂ(š ­¢¨F*R¯5ùFYí”/0UÓ:]Ý2SÕÄthP¤jÃhäIõá?VŸÏØû©»þNEë¼7ðØã­,é´Ø,X d$²‚½„cà› œ¶¤}SÑ4ák]¬n©ôßð5®[åÝ 3uG€¯&jZßÏÚk&’$aá(AÎ,¼çiyX¸QüÎ9Çž]ªjày¢“ í³çÞõn{[§jÓÞ–ï6ŸFn3ðó?ðú¿õ\¨;z»:°Xy,ê¼á××?Y^^$x¾¼ 4²öjX„ÑÈ¥ ±¨«©…-©¢¤µÜÑLnÌÍ]ÎçÆŠ o¾:_.àF @‹ùs…Ú\¢d¨’(6õ­\‚œ˜ä˜P’Ð+E'+Ñâ~œöo )âÆJ¹ñRv|‰¼]ã$ýJ!»á˜‡»ê}m4r¥„ÅPx3Wá«‹Ìç†JÙz°”ß­³«‚¤Á"V‘)ÅÂ#$£ %ïýéí©é¶åùö¥™ö§sm÷ÿz$Ñ  IT$£FËäXh/È1ÌC‘îTÚ•ÌP†OwÒ¦O¹`,s[A°~i ‚–•¾Ü{m{íÑYFd@¼Œe㙯KV/xÒžw…„pÒ3™Ìž03ix‰i Þö,XÚ]`ôèX',vÚn6¤§›€yømcv ƒƒà_Ù-O ÓiIî³|Ç’ËJ‹ì´8í‰Ë¶˜o£…é¯]FßĆÄZHBö…<ërA:-Þý÷ÇñF£mFD‚$UÅvôüd&=í WT]£‚žðP§Ö]‡Àp9ÔpO˜jNÅ}Ñ`Ã’Á€µª(‹Ú§Ç³iôHBÒhßvÚu›îÍ8Ö³]N´o~Ÿ:kÁÃ;õ$Ò“Û—ƒûìˆ0b,!âÑa«¼à1 Ò˘^ÒÑ!™ŸÈ“gŒ~'¨¼&V'Kˆ±Š=Öy·%ü¡°tÊW§ºaÎ×ö ¢qºÒÿ ² ˜d²ºùÇæG5RÛ[Þ¦‡¾Ö/ËêžÔ_¨j½í9‰n”×»b̰Ƃ C¢¬È„× EƒÑñ¤œ™ŠÀ#ïáÞæo½‡Ö›÷aí‘;¾Ö wý5ç^³Œ5˜Bb<&×w—}]ÙòóýÏŽ][ÖcBà_—u,ˆ’X¡šþQ{ à–Ç¿¨V¾î¼ëïªEšïùüîƒ3Þ–)oó/ö”É2†],{+«B««/ `ieå•ÑÈ‹ÏÚÚ*Ã’}øH÷„D#¼£ž»Vö‘F#£¯F…óÃÇ:ìs"™7al‰^^‰…ù B[‰`…Gh»Ieô2&@2ZÂŽC맦ñð“^r…oRÆÐë ܶüµÑƒ+7;^v±7? €äbç?*áF ¸knn¸‚ dˆÿb¿\cÚ:Ï8~$$$K–ŽŽ^½:GÇòEæžÄ `ÌÅW.Išð-ÐllLIÛ˜‘ZÆæ’´S7µÛ¤‘K!$a“¶ª»è·U“"MûÐuSZµ% —„Ò„KÓ4 ¿{^“iŸöÁ„/‘ÇÇ~Þ÷œçùÿ^X6)$ª$µRƉ*”Ù®çéžüüÌÌÒÐÜâÙÎcEJ–•Á ÅøõÜ‚õ˜• í¦(¢ (2PBõgÔ”’mŽá}dPOÎCêjr¡šRЀžJ}̰5ß=cü[‡þ“PÙjÔF.ÀzöX.Hâã¨5Ño¡_ÑÓY5nM;ï‰Ã$Kù‡ “¨å£6‹YÍ*XžÇTâX§ ß>hK8*ŸÙK—ê+SÒezê6ç4¯9ŒËš«jÇmôUlIÖ–¡Ç°DÙUÃò¢ixI #KæjJÆf³Èc r½1åÚΔƒ7>´Ýÿ 3YK™ä}73fgÆF(ì M¸èŽ&]ôÜp2Sp^—ú¨ž¹VG¯®ü¬ù |Ž aQÅ J ¨kXç¡ÌH‰áƒc—®å°L-p@ãJ^ü‹”F<h™ÁRªrŒ©‰Ï¸í*“ݨ…Œ“½¿‚Ä,4ép4éz dÄD9d¸” ¥¢,/%C†ÔLZ$“ˆšH´:ݼO`ؼB¯xi¢¿úr]Q‘Èfr@o¼VRÁ„Ò»KóêHùºLªzÃmKº,I‡1a/_·W€U­;mO]¶·ÑW±%¯x¥Îø­½‚¸MÄ]‘t”?s˜×˜>6¹³³%¥Jd‘±{x6_âþ~¢ìÙðòVÈ#±ÂT—ÓrJ·þ)ÿñ˜F šQî,oBb~BQµÙW¿5? ü\‘ˆîƒ#íè…XmXqŠ«·¹OöSø‰å“Ñ’~X§y ¦†sôP–¦U€0r䢵÷82©}<–õÁiõ|¹‚± Êykn7’窟TÕÜnîZ:>0íï›i9{ÏwrÖ×½ œà ~å }@Ò™ów/ø#3ž®­rÛ•ÀÉùæÎù6Àƒ®‡Þм7|¹ºŒds(¤·`ïoœþ/|=ÚÎÞó†oÖ¸sÀõ”jNàžëÕ.à¥Å–Îtó.û{Þq6ªä²\Ž—@“9t¨ PdËcxh„´ÚƒE_aÙGu-·š»îNÃÌx‚ÓžÛͳ¾ðvÓÈœ?rßþÒÓñ8°5<×ú ìUðvyá?þþ‰µµäËåMþÙ¤‘䯯ñ7ÛEp43窙©:j…ãàŒ ÌÕÚ—áÂ×í0ÞªgkJ«V´¨UÙJ“Š=”'‘O/5‹-Fì1ÈÚ‹˜±ÆÿÑÈÄL|"}Šøõ1æbMFÄÄ;òÑ~5 ”1ñÃÌÏÎÑð•îkês¸ÈÍÜ„:™+NŠˆ¿jdÆô8nùqm¶}W†2“Gl– IXR@I‰¬Òš¯Û+± ªë¶¯,›¼ ª'1€Í˜ÂÊɨ‰¢Èyý‹¨kÚj\CúõTÏa6ŒUÐ)oØ´Ó“¡ÔèõëH´0µ0óF¬† ™ °D|.¡ÊlI ÐЧ%$ZLSCÀq»ûˆf/¦tÞŽÒ/ž«*e*Ìky0mþí7¤Oûó:m2I®Õbâ2@|´’mÚ[ò™7¸Ü~îvs÷tSx¥åÔ}ßÉ$zg›;¾ní™k̶õηFæ=Áûž \™oëÝ*·]ð„f½Á‡í'½ÁÕ–îø"®<á Õò8n~íÖÑKí}+-=š»Vý?;þ“Ý«PH¬œÍå›6û0LÚtäó×@جղeI* /Ÿ!–ÍÆ Èó¬À•iµïX_ûôŽ¥À©¹¦Ž•ŽN{‚ žià§€ V[¶ŒÊþoøºç½¡»ÞÎ_hÖœm ~xÐ…9$òX)J­>?I‘H2¹ñ2d3PÐÊÒ²$JìKû”¾ä¡J»mÓÍ®N—4Ù„@Àøô?ª••² ¡+ýXãññ93ãsÎÿý°çëI\¡ªÑX_.UÓ`íäUÇíÑ“¡‚…ÓÙžl%£TŠBŠšã1§:Às·Ê Œâµº¸¥bÕ\õÌ\úܪ[­5lXJÖ-%OkMËf¡™Ë«-Øõ4ú6^KÄkKWÍÆ§µ†'æÂe³>n)sÆ-&ðɆ¥~ë¯ëLç2“±$1X³Ÿå¹äBQ1i‘ÖÁÃ0iaH8÷Õ5’GÎÐu7 õ•n„›Ó>÷Å{ƃFâIJ‰œÏ"C¹$\D"FÒ§[¡\/$½ð‘!gz;½Ncç÷’~,%= ¦lr*Ý+zs~ÙtP ’,ç$§eˆ ˜ÑpôŒ$òiÛ¸gßgV×}wð¾3xHàò>ñœˆºÛæœmþ¦e?€ä±û䬽Àu9K2M‘weßëʶw]¡‡r`^öß–Û¹O~áéN…šL€+ÄG%Íï]ÛÎD›:œ]Snß·/êòÞs.çIÔ "—ÎâË+—d龜û7WpÆÙõ¡îð^VHä8jC†…ì®ä9Ìa¯ÖôY•#Úxä,¸wZBà[žÐRsçSOðž£mÊÕñPîØi,:‹®`ÔqÍ8;fZ_:¼³î`Ѝ–xjYIÁ ‚-¼1Œ<‡ÿXœÄȵOn0«a ž¤]ø#o|™Ü¯ZÐÄ14ZýúÔ±M\®F:%F8 NÆõ™›Í45T ÑJ4^ƒÆ-h¼Žž¥Œ~cÿ¶— &l/ÏWèk ½ÑF4Þ€Æ*Ñu[ÂéXœ&…¹“˜Åã}*Q)0B‹M6©`Cà hÆ­FãMh´‰êh×”²M oŠeÒ¦<ž+ VˆNcT¼ Q³¢$¨ZöY_ ”cñp&‰èh…E·µrr¾„ ö“A¿k$ï?c‡•òºbHO°½‘(`³É¨jºýdÀ4Û]Ú˜ƒU &‰Kâ.+Íjñ…¹p­¶hìQgÚŠ]O”oc#n1>­/~8©+Z1k÷ *FTå2œ’OS²8bI_1,"á­u‘Cúó(’áx°€DòI¯öÛ¨@Þ›»ÒýUú žæ}xíßùu×—Ia, NÔ)¬ƒøaè+ÜÿÐb!‹ 2-GŠHoêÊPE[“ áXŽç4¢„Yœ„&IЪÕWK*!©=vž|(‡þ ïlJý†˜•} ÿtsûÒñÓw¾_µK —ÄK<‹Œ•3rhÙŒÊþ)—Þü»3¸äêºãôýÉÞy$uO‚Z…1{4%õ¾;\~] &8€ngœþéíÕuù§][¶öTNPˆXÄB2ÃL’®Þ½ÙÐzß®,9|_9:]þ)¹sJöƒ n7w~\rô‡ù¥Z»£Žà=gp·ž[0³  ¸ö×~‰‘øààüml¬=§$!0 7äy^5#ƨ»]iBc h¤Ž&ña3Íþãæ×Èõ:e[¾´-ª…,}tM‚ˆšÐµôÓc›Ñ@¿œ®¡&Ù®ÿ‘º2¶é­óà+Ð¥E#±¢I MiËEVdULNT޹t_Ç{µ+ç!;ÜêÌÏOJešF£XnÉI®(Šli2Ñ[мõZ©3kÑŠ¥hÍZ¶R_ýi¡Þ*ª”‚˜Ê©V‘¦Û 9›G.å­÷è©ÂZ*ÞþÂÕ3YTïC×½òÔôçÅÏeS D ^šd`ç— P¤ç½`ü ‘D )¨r7ÀT’!x[º;… ¸+{¹ÿðo¼‡ßMÁ,U+ žÅJ%PdÃ~_Wüy“w¹åôœ'™}¦Ù»ì íVVsø3nʆ)g×MÛ‰dºèqЍþ ¤fÞsÜuu}áôÏn¶Ÿ¶wÎ9»ÖÝÝ‘lƒYeµ¢øé‘øtÚ8¼ÐaÔZð„à·wÚé…öóÎÐ÷d¥ò|ã¬Oª£Nú@¦=ÀŒ®yOh±åˆå®ìÿ‹Ã7~øXëÞ gEYrÒïíÏ<ݳr`·žÛXEƒ TI,à’k=ÑN(Dâ/b«oF#±x|uK#ÏVìÏÐ`AͲŒ`Acv4nÛLè  ±¼Î,¼FÆ S…‚ÄI+Z2Ј]W4£Q;M¸Ã h؆ÆlÔ$Ð~{FFÿy°*83 ĪA#Uhì½£ë6ôq»ü¥HÒKð)óc“£V+YUu6ºT–˜®d¥”/Ñ+Æ4¢ ÐQåîóã¿£ý¬]©D?·¡ë'Po˜JpŠÈ¢³+§¦±°m(²ÝfŸÙMÚîšÕꪻVQ»hVQTfÎþÎÀÚÆMlÄ,ä—›{É}œ{çžûýü¶OøÅ_5÷~å&…þìë8^áÙ˜”‘$c™)p-#ä#©U8/í¡Akê5`Ù¤0•(–¤$þàñŒÀAta4á|šG#ÓÓúä7X¦fãÀÄnF§|"ôA#B^Q'œèÌükäL}üÛ&ÅXÒo.B# è¬Oì?ˆ cDáDÃ5Â'ÝÏ=?Ø–c1M¸æ6á÷иgŽ£ .':ì6ËÐþ´åÀ]Ç…s59ÞL0:àAÇ×SBMIÐ(iDc šú™Ö-¶=þ÷yÖ‰á¬Cï®CÇ}êÚ•ñŠN“¡1é—™1ÆËeE‚ ¦ÐD"%Òø¥êÕ7*y1΋ôeGÁ$}éB#s y95²/ƒpð>»ˆ† ¾/ýóî‡&ë$-™LT¡LýAz:w—D<ÜSqÍÆÐS–,áäÿ¹¸»xÒé¸å´EÝ6î)xä´=ª-âÞÊ+k3jÍŒ0ÍJ˜Q‚$VéÒm9ü@ÉþŒÇb¤¿Þºé7Òù`þ‹¿·¹|Ð6G‘þoàd¾ç˸œ]PdÀ»\NlðÙ|WhR3añ=éÓ;3FiføªDÖË ³J2Ó˜QÕë"·ÉX™ëFsÏõ†ö/ƒÝS[ ·\i ý}ñRõf çJcÇå`øª¿}2¸õ¢?ä³&ê1Rܾ,å\ {¢9|+ºéïš „'6v]lè>ꨪ֖ɔÆÙh4ÊŒ˜úGWÓ%PMKϬ@„p6v|›‚|­“›¶Mµn‡ýïúC·;'=—¡©à¶ íck=m)Y*£2¦TaÌÀT#£LR¨Ža+–ŽØË.ºn6w/Ös›ôúRÒ ÁªªRLÿð‹_=|òˆGJ#3ŸèÌÞïíR)³@ßüï(A§ëDÖÅB|d$îó¯‘þõ,K³d§a)%æøÕ ©CgFN4Z…ƪŠÆbÞó=ÿu±ƒa`ünqØ„uÐÈÙ:¡± 't¢C³„U…)›JÐûã+”DŸ´Ò€ŽÕ¡Ýi ©ldŠFëÑ7õ¡!0ÌúÅçdzÏÓ+îtG)%:¬ÈËe ðFý]qe…ɪȦ2™aœ 3Cªª«Nâo–òÁ,¾/9Ö9þK‘—V#}™|·M¬ d‡ýCjŽ%ÅÈŒ N‹N÷“üdî­¸¿ÞÁ=%Ü ‘Y,id© îÕ8yŠÿíÌ¿W“©+ŠzìªsÔäóºŠÛU¶@"5Qj‘ÍV¬eð†T|kg6?èàû³øžU±7°€÷Û¾Ó|ÉýÚ!°„uÐÈÞœyŸ/{óù`!ß›+® 7"|’+j.ïÿŒæä·–[uXÆŒ ÕÓJ¦•¤¥Z‰¬1 ^f6}òJÛ½Öí·]7«o=ìºÞÒ³h©Ú ~è¾ ý3ØudÒÔ}xu)t¸:U.1i{[øÃPçƒáŸúÚŽØ+­fR‹^V™A¯1jd,—2ÃokÎ7¶_ †A7‚a(ÉÄóïënsèJ ó‹¦ö‹mbçÏ‚¡O[zÇ+<«ÒmFœSÎDWhé ̘NJ#Ì™r¤´ú×®fÐÑ¿Úzÿh_¬çvË«ò걺¶Âzzz" „…ÒÈÌ <^›ÇÍLY÷6=$¸[„>¤ö°[äø‰Øú¥ ~€ Û hØ'Ò(ËQ××Z™w•âÍ7IÔJ4ÌT«¤‹3Åc›m­{ÑP@x`¤rÍIé[42ë0 PVŽ­‹±¤v¢Sp¬ {ºÞóè*LfއÀbp] >F?lÕíªÖ’ˆ¢ÊTSÐëUh¼N@è¸ {……ÏÔñê Q¨+’ ?§¬è—ièPÛŠ¾ß…޾†ÞÝö¼ÊÊWSŠÍXÂT¦03¼z­YÚç¡âè€]tI³Òì—jñuñ‚µ?Öè.÷-Od:…XˆE’tŒ~lOžñ:îyÖL;K¢.[R¦¶üi -id© ¢nG¤6Ÿ»|CIÔSüÐUôØ]&¹WcãJ£µÜ]J5P0½¬š‰cý¦D½ÉAÇþ ~°ïN|Ì?m¾9õ )Èãp¹\>øÉ9\~ÿ?ì—L[×ǯ„„„ô¤§§«§§÷ô,?#;Bâð;`0à5#üplŠGûÙ&$üòHhš`À¤Ò’vé–¦Iæg—Iû½FYVµ›–iÚ“Öý.ReK×v øî<“?*mTÚ4âUÊÕÑÓÅ\Ÿ{Þõ=çû9ÁâzöË4Ï'b1UÔe°"›˜„9Ú²;ïwÛw/Þè þ »ïTMã6VMq©N÷îWš?9t $uÉå»}°%â ÄKUïÈþˆ;°d÷Ür´­È .ß]ÙëLËH¡p2ËeiuÅZÝvè4¡ò€R¢cCkQÞ™ý“jGÄî_u¦cïrÏáY„—’½@# ŠsÏfû.8«Î®GNÿÇM]¿w{õ:‰JJUªœJͰœ"ò fRo¾ñm‹Bºco¿ßܵìôÝ©oùœÛwËíqnJ;[mBÓ ­Öí©,Ãh–gù?üö½c”ð4Æ:yüÆÃ¯3ÊI‰æÔ ùh¿Z‘ì³"úS¶˜î×*ò½Å4’Ô˜™¡bU˜×²†áÕœšáX€4‘ãh‰Æe*ÔS„®l`DhÝ|‹Ú'¶A#ð¼`Bß´(ÿšŠ=GêP؆ÂhÌ‚z+`ZÄZV8 ‘âù$ C¢%¥ç¦ ‘Ch¼MU ‘Ze÷‰x³Ç¿ÚDŒGìÜ{oçu 0þÁýèµtÞƒ®E—¼è«Ýèk½èœ°I:‰cS ÜPXäD ‡sØ„i æ<¡¨‡wÀøl`ÏZÞd}jŽŠh¸6"OQùjíMÆÕå€ëÖü5hu­å¤¦ò³2ôŒFžØßÍùkCÔj||ÀøÈ\üW³ñSK ÀIÔZ¶f6¬[‹V—t§I"Ï%³–Ï qg%¬Ë&§KÉ‹Yd¨€ôgý··÷³—÷4²o(„²cg“`.9k¹^$Ij5䱜ó *†-Ö¥ölºúÂÐŽ þ,ºéøy÷™ïô •¥ìLfYIT 4**ŸuùçìóNßjÓñy‡/^ªz[ö/ɾåÆö9¹=âô€Â~ØÔýr¹™çNi†BCU,´›Xªâýy¿¬=iœ86cWfÁÙœH³ "{ïÁ‡ŽŽ»²çshdÕÙ3cL;} §_ÎÈÌá„LµöDAùõÚC3_ÄåÝ¿çìxàh[´·Ì¹Úæœónï¼³¶{(ÇíÜ8½³.߀á9-ç$оòêÅG@ OFÖ£$­®®LVk0˜„ÑK•h´rËÕs¼ [•çHš´¢°E!˜( T‡^0JÛT<Íq”¨ÊÀ’ŽRéY Äd݆mèÍ*4``ÛÔ?8çártµ ½Y“pYF{N#2õé(Xކëb{U ñ ® ¢Ž”Ñ:ÌÃÕTjšÏÄR*¨9Ç!SbÒy3­Gá%¶ÑžUÇ<ª”çp5šÜÀ-›rŒÀfá}hJ¦Ú¾”Ëòj'ÁeÚ& ‹>t!ðïíÝ”«’M“T4£%5YHšB3lÕ,#ƒÅ$d ¡"Œ5h§3H&é/&&Ò_¤”ÊP¬«Šu„ Io6ÌU¢€nÔ@ Ô|ÒW4ÝZš£¦ ÆˆÜ6ŽaŠEú7&cÜeî™}¡mÝRJ,b)üÔbX·”D*JÏéSY.AÂR2Ö`V]¥gWŽf’3%¤×ð$/ É@¡2éiý™ÂÇý9qË—,29»9yJÊ(¾R¥ûH'ƒÛÉPίeצI“Ìóóm«îÎ¥†¶‡®£[}>÷eßœÓw󀬋ɆöM$ª BTë“9¬ýïq$JVWW’ÕjLÑü:v  ó–«*ˆ;ˆéd¢ï€"`6tÕ†.ïCãVe>\—ðº,Çf I RÓŒDÓ§Ìhª…+bN>‡FjbnA»Í赦µ„™,,ÁK2É »WÅ4  @£"èo]¸QIU( b"–’x‘âS0]£WPdÂÂuJÀ ;™Ñx,æxÑN8öv Y”àG­Ê1ŽYÐE[R ­áE 'ZЇ-èï¦4òRºÔƒÎy› KGQ*kAÅS,Ã4ìÒÞ”w“þÝ „ô„EO•ÓÅä4´QzÒ¿—ô”"6´'nÕÊ{ÈHú äl¡ÒÙõ宜1þ®½D¯Aé˜Rcµ ó9<óëÒ½(‹»œ=³/´}b1EÖ#y~ߟž3ž×ƒ 1ZVb1Öq”%“‰tæ“!¸ù$B¿W¹ŸCEdÐð䯿Æ-_ ªS™$˜…`ò•äíË#½Â9$˜AΖÍyŠçðX 0CïÂhs©¬`Ë)úz[ç÷NœþþÑàõ®ÐO»ßêýð80Iè®ÁdžFý'ÍÙ" ^€n±%M¿ìê\tù6´OÿÿÑÈËå¶tާ8†ç°)Y;Zn{¿ÁwKl¶~Áé$¸ko_”=`ÊÄå[ØÜÿl“VîXvûKîÀê|¿±ívs`Iö„Ìl4YÜiϧíôåÇÊëîÉÞµ¦î» GfG–[#NÏ—oÖᙳ·óÒ(n ‘{;8Ùêó”Zl üÙî5IF`Õ‚¨¥å¥ÈXˆÑÈÖèÚÚ·¯½ÅQŒ–RàªØFh¤rËUuØ¢èé„E‘QÐÖ±:4Z.× 7jÑ¥j…7ÆmÊPÿ)ú–5Ák¤+´‰&.ñb£²8\“ãÍýOÔ¢1ë?Ù¯÷˜¦²4à'!iÒ¤ÉÍÉÉÍͽ¹7}¤uy(ˆ2‹XZ¦*´¥et”G)…*«ò,u³Ž‹ÏÌÊkAœd3ë®à0£;3™Ìû×f³»™dgtVðÑì8WÎ~§dÍÄlýK¶1‘|!çžôÞsîiÏù~k Ù4Gìꟙ°ˆ_ÕH2ÖÊXQ°¤%¼NÇK›L¨½yÑ)GÂ)'SÇ)+ ¢îBô®ƒõì ¯d|¶²öpü4N²£Q£,¼&˜d†&\¤:M"jNµDÔšôèph‰©‘c-è4@'BhŸO)^'kež`"ê âxóšÆÝÕ@z»3(äz@H;h Àµtÿº¨Iòãvº†sÿÝIWþÃ=«i$›FŠÿ\—––ÈéJÀ©¼œ*â¿¿^ôØ’÷Ȳ&îéìe¼Ðñƒµx¾¼àq¹ù»òœùòê(Ü*- %k ‚Ht² ù²4´ËL# ähàÃf†–ý³Ø¯4^û¥s=³”=Y‹áüy¶s×Ò^¨&2¿ÿù†Ã–4ƒ„NI“4°ý B /—¤¼v°jÛù¶¾é`÷…ÖÞ÷ü]sç§¡Èù–žß‡z¦vG.†"Ð?¹§ïg'!^ŸÄÄ󟿹}ò¦«á’«>îüx*þêx»X,&Ó'÷ŒsÇ%WÕš¦{¾Ö˜q7Ìy›~Ú—×–ð¿b‰.·½[îÆëÎwk÷¼Í׫v~ë ý¶Ä¾V–õ˜[¡ÈÁzŒSDùÝ ›¿©aº]¸æ®»ì©»ëö_­®¿ìiœõàQ7=~€ |`ÆÃ ²ÜëÓ¾á Îxm©k4e‘Sk¦§¦£Yü)H–:Ÿ+G¨+è7ðb²$+DƒZ7¡ÁJtzù³ê6F· ¡Í,·žÙ¦¨Rµ[pé œ.s+yœ¯åêÖ¡24Tu…“Mlp² ;X·¡_o‰­-Œ10Ä©Rtæ-ô Þ^œ&*°¾D‰Ì ŠF8™õD1`Um::°T¡Ó•è=‹ °G©`Á(R² Q;z,NaëV…†lF¬hÌÆ¾)˜$4N¸‰Am”dÂC]à µ&PL@œÜ…Ž @r¬U]W!d¦(2TE€b^/È^ÒQ¢Ÿï.¦«á£‘\†£u5;Öºsî+ˆÛéÚa^ìˤ=™´Îü(÷®ø×²^‘e5VýmÓÆËzjËùÁ¶6îéìe¼Ðñ£µxÁºaÁ–ßf¾·%›¤¢zVÊ¢,ˆAR“d‘oÛ`œïºgÓ® ÚNûrh86 í‹ ^û¶p_›läHÌêtöä½oÏ)Ö«EŽSD£ÎFUžo)µ;>Ü{`º¹ë³PßÇ-áɦŽöü¤µ÷ƒP42ÙÆXPùc[ÿÙ`׿ŒQ”ˆ¯eÞu7}U¼ã ÆOÅí»¯9wÌÖø¿ön{ü÷k[€³Õ;bÞâj˜xþK‘¥¶+¦FþåmÜŠx›€ÿôúg|ÙÚà”ãmVïÉb‚–¨Eœ(ËœHô¢œª(C­ý¿ñ6ƒF®¸êA/wj[gÝ ·QÁî²¢S•hÈ­ê*ÅI8JŒ¼h ¢–ˆ°‡´&"¹úBt܉Nofy hÌŽ~cg–LTF){Üe­ f0“a £È,#L¬RS­T(ðUÊ+Mèpiäèžgiä—MèP:ÖÂâ‹c­ò››°Q¿A­$¬Ñ²J” w®*m®s#í7ÓÎUì4ëdÒƒùq;]—&з†ö¤ÓöìoÛKË“T Á‰Ê Æ&ŸY—±hÝDß(úÞš÷°"/îéìe¼Ðñ |â5ŸVä?ª` ù®<ç‘5÷‘5o¡ÜL+ ƒ‰ ˆQÖé9­^º Ú“K÷çÐöWh8•öàsh¯™vÄO#0ö Ú“O#p Õ„ùO;Ìž ž“LF^2ID”8ÌaIT<…%Ÿö|°wÿÔîȹPø|( üøpWä£Ý}иОõžÛÍb*Ø ¹ØÚ{19¹=¹ÕÀ @’$ŒÿâÜù¥ÇËÝw~<7«ë!s¾ ¤þîú/k/{ê¨7f–\w50±Dp 1‡ðæÞ ^rÕƒC!_W×]uÕßöí¹`Óñ¢IƒMÉdÖ`{_Iño»á^x2H骫.ïyšîºý7=~pÈ%ºæY znán„wœsû¿ªjHE€uŠvuòŠ……ù'y’çN‘/þñpR˜žpêÖ°\?bYö¬ à´20@fw%ŠÄA«Q'Ô²NT±:•CƒÛÐñjlIACv4be´–@Fv°{Çc?ø„€‡ZÐhzˆeAÍh؆ŽV `!Ÿ§Ã« ¢Œ Ïò¸V ×z—lMEý%hÜÎn‡¼vZ¢ÈiûÿcqžLbÎh4ogEÃNr¨‚3‚¨$‘õeÓþì4ëJ¡ýkigZÜN×¾TÚ¹žvåÑðê; ¶® ¼Noµ‰œ˜D¸AsúByQ4}S[áƒ-渧³—ñBÇëú…rø9åHlùËÍÌ!Vö»‚ÿÀ]g2/)8B5*•VþƒÓt?\L€CVÑîtÚ•EÃæ¸m–%H£=«h‡ynWé®â•^µŠ' õln“’ÜÜ“ÞÆÏš{ÏF™ØLííŸÜÓw6Ø5ìºÐÚ;ÝÒ2™þûõUvÇü$&$“L2¹9¹9¹7wÂ@xˆºE@/EXƒ…gp,Çmâ„“Eú?VÚ›”y WÌ0YnZSs«JìøÈ(ö}dvÏÔ¸çÍŽ5ÀÏ-³lÇ¿X}|nuÜ…ëÖ6ß5ºvÅ%Èx,"gØ™™™`xA‘Uú :Íò ,XQ£DÃ@šÐ­zUHŒBIÕ sZt€säK9AŠÙ. ÍIˆDR‘ˆ3J/`dÏBÇthR‡> öÖˆ}'4!Ç šá¬Wˆ.A£Åhb:_&^q\-ÞæHµìN0l"˜V¦ 'Åqœ"A.ç¥kØ<"> ¸Ö„6(ØxA‘‰Š°idT/Îÿ,® M”‰â:majRc ‘¢ ‚ôGÑkÞw£4èA‡[Bjd¨ ü§=Ø„½h°Yì2àB?iAC]¨­g%‚I8 B„@˜!QXâLç?õdÓC[¨/ó™?|/X_2í˦om¦½;Ú¶È a¤2ŽgI*Á§”)OÕð%›ùL£‡¬”dÑ]…a/g¯óƒN@£ ¨³$@Ü€:¹w,ö;AMÍíï© 09ŒcYþøñãÿM‘••À÷«ó¾Ýo`^Žyž0èm=š4 X|W½°ÂUtèL)šÔJè9Ô;¹m+š0 CzÌJÖÁ|‹#œoʉLÎðÒ|…ô„ETÄx):Y,Îóƒ 4¢9þ„Z´ ã´M˜Ñi-š¬iqJ/ZBƱ ‹ØrT¡|Q<ᄲ‹,cÛ†FLâå6£eb—qÍ¿)r¬$lÓ£±R4¾M–Šs;W)2#¥$ž.ð„%œU-Rd¨½çBG;Bjä¨ 4¢ÁF4ÔŒŽ7‹#f4àEGœèð>‘%ÇšSC£×A¡ç H/2Œ’—½S¼þ‹Ž<Ú³)\o×€/‡v¯§½ªcEkcY²8:’Ãiˆ¨.¡šLºSù•&cY›÷\“»\–örö:?èP­ @òµ:÷ëòüÇꂯÔOÔõ–ge¹+Ú|ª)¢Úmó;Ò ±à ‰,‘bEY ó§=´'‡v¦R¿*Щ¤}aÓ=5mJÞù†ÀË0‹9pÁl ŸÑ eúŸ¹;®7÷L5õ]óô_nê¹Ø¶ÿЧûŠ»ë£–¾_·õCv'W¼¾Km½’k;éfÿ/;¯v¼ÐÜýËVÿe· Ó²à5NbA&iMß¼h ??^ÊíjÛ?ëZ,îY£M4ƒÙ µþ‘Ùê|'¸åw¥•hÜ  uþ,Äd,X\÷L(ë°;guÕ%¤Äq<ÁL{ÆÖ»f÷’¡~¶®i¼°Œc†ã¶FF͘ÝsUõÃ…%¶õ‰ñŒ4Ë<?±ØÍ.¨fÞhÇ\íçcnÌV5,Ôy¯ëjXNÔH4&z½þÛY^~Û@`ù»©ãy ðc^ EWèÊò²œÇrL¤ÀÆ1bá>_ŒÆ ˆ¾Wu”‰ê8E_‡†Õh ¡G£Eh¢ÑH z« Šœ £þRt¶8ª4=N¦``>g´ LÖ¹gcÙI³(0ÆH0 L8ÔuÏhЄN ´ÏO‰¥Cç´²ÞY].ê«@ìovl;šØ‚ΫÑp:¥‹Ø—»I!I  4Y6u„L5Ò‰÷>Z"Î|Ü(­ßêæ›€ ³1½»oCïºÑé– 0Bh$T=è}pH³è~´²!{©BÁÂÈYAÎ*0,)ŒÅ#†7igíÙL{T´'ƒv'S_rðcPõ¸'•ö(©/ƒv)iWõo¦½ðy˜óê/Ò|Ú§¢>häÒ® z0îO¤¾"Ú“HfÿT—Ï)¢±€‰Œ˜=1ò°—­×ù¿ Õæ®hr–ÊUÏÊ7S]Ñïó³¶Ë‰ Md`ÁÄ%ÆJ´P^ 3‰v'ÒÞ¬à¢H§}ðNÿÕ°.ºÄõòÊë¢'E\\¹ô@¾¸Fºaä4Ú›B;‹h˜'‰ö&QÖŠ¯0Ð]ðÄ“Tœœ‹9žÁ_‚œa×bnWvÁÇETxýS­}×ZzÁØ}Õ\lóÿ¼ÕwºÎ£`0Œ1Þ@„ߘ<ÿ¨¶Ý°8M¶{æú›ÛC“ó¾ÕsÏä;K^ÊýϬ©~n·ûnuý#³cÉì¾crÍY=¿-·z•¹¹pK<£Rð7jM¶Û–úWÿp^1PD.ð9Q1wwܨj˜³:þj¨]Ë ‘R¼–‹Lމã„H†f¹h–ÈÜ&†¹^Yÿ`OÇ¢Ñdš±ØfkWý9,™ÜsfçŒÅ¹huß4929!Ãû^8þÙ“§`ÉÊ·¶ßáfå_ì×{lÉð‘"Y²´ZV£]­µëÈ „@yÛI„“`ÙNá•;1I#ÇvÂ¥=¯ÜŽòzýçtºGSûOïÚª­ÚªêZmÂã*µ:r:Îô‡¢t'™‚R ¢/“Íjwf¼Þ™ï÷-DŸôùÕ¿”AþÈ¢Xb@ç«Ñ„]°¾H€C  XÆœè¢Àù-h¬²?š°¡þr §…o„Û]Cã,y9tåtÅŽÎÚy™ÓñЦL\6\†id4â@£µß9î"EÀ$‹a0ZÉ“gP‰€µ8UéèÍ*tŃÞu )@KÓÎXý²V4^ƒ¦Ê—ÚÏÄ9+›-<ÀKvf’a‡6—<†Ï£ã±°ÓþX'褊“"gb·C'ghȇN@§c 9¾[‹Ø6¦ÅЬ¤HDÕ.3È 2¸OwäÓÈ&Ú½–öfÒ£… A¨ó ¤A# Øoá¸×D{Œ±}2Î]·×|ÿpÀ¦EæhW}³˜vgÒ°ñÏ;Ìé†Ì'¨‚Y¹J¦-›–<=½ŽW*櫊lÅÔfž¯*øÚ¶~Á¾õ#³9CÔI/È8‘Ó4¬âiïFɦxÿai˜XÌef÷™è‘l’x×Ew.»«,¦yléÁ™ð†…£ù¬Û éQ7Œ˜ýí¡Ì›õ²D ²"Q‘d($9\™žªizï~ È‡¾'¨xnÄn _Þÿ†-+_À˜—E‡CfËmo¦ÑwËÓz³©õ†§å®ÇwÇí›öüßid¶fÏFÿ,LµÉÿ—ßÛê:MÅEŠ*KLnIáU’(àϪÜ÷ç ½uL„G$JϸæuhÒ±T¢ñê—@­Ìpp¾TÅ|­‰âr#`T “M"NÁ—ŒSÝÅ•רñ–,;e'uÆ Y%XÑìÉAïÖ¢ 'ë ºurÁù}~ÀˆÐÂ1N:†ëµf™x™¨z,¥ Ò  Ÿ"KÛ3¸^ wÖ‰ÎoE?†‹-ìúIËÒó㩸hC—è¬MêÈo& 5(w §–ýÐÏDŠx»K´Å­mèt Æ?ò3œéD'¼è\'êÝ­fÛÉË/òI˜° Øc§Û7У™ú dYõ;dTmE4l¦¡VÍÅ»ë2‡B•GÃé´'“7Ð.Ø„ÓïÊ+Vhˆ¨…z¯P'M—R{Ù’§§×ñJżmýü¶uQ«™n/º_U@e÷•S¹©XÆ*Ÿ ã%‘E< ÑPÞ#༠‘³zìß¾Xçºx8PÂ`ΦÝéôÐJ)¤ƒÀÒèZ å.ôçÑ£%ï;W› •**`µBJ%-oR“ºí®÷:‚?ýAÿÕŽÈSyn|Aov„†êvCuÀéeQËê _Ôìúª±í¦»ez‡oƽ²*仞ö%çÇSq£©ý–Ç7çÞÿ±ÍãZ™¦b^"¬¾#D”8PÑA%†ñAóæßW·ü­©3Þþo{ü&ENHg[VeV$§% $ ã$YÑÁ ˜ýBE© d¥(®•åSéeKõ=¾›ßW;;®×í&Ýnð¾ìç0ãòÎ5øÿêñÎÕ·Ì4úß.µÂÜI ……h”þ["ÿ‹I-*ä¿5â´;fÐ,jÑ€B²«zÁa*¨B£U à†“J4eeYu´MT£É Èû\i²ÂñÉLFæ$Y›H 5ùªÓH0ŸÂa­£ãV4Q÷Ø ‘Iëíâ÷ W.RdÜÉ®]Œ9а]käR8M–o˜ZÝ q¹(+Z‰ÇéDªYƒÂhÌ…Æ@&Kmgã |­hÒÎ 7ì$EªŽ`=fšæ]èT÷¢Óí,†ÚŸG#'Ú˜F  +0 ‰/擃è-@N':íOh±K©*/èDädN' ¢^Ö nIúGw ¯§Áu4œEù´/m¶Á|Ø~‚Ù÷#yqk¤/›€]94’C»Òh¨6öh0{WnªkAÑ`É,¢ûõúº=ŸZK–<=½ŽW*ØÖ»­h>¦j5>ªÌ`/¥¶Ò#éj²(ꉚ ƒJ~âH¥ÝLl-ô0œ÷iw{Ãû i(ÎE4ÝÀEzRho(¥=fzx5¤ÒH>8绲-)áu+$½¨ÕBÁ©âjIumºÐvä“®ÁÚƒŸuF~v &yB‘ÿ”I¼¹ ]Á‡>inÉ4jQY ûQñfHÄ3îÖë­sõ{oyößõø¯5ø–œÏjášÇÿsç,ÇcE”1Ö |U– zµ3§äcKý—îöovžõøŸcˆ@¶Qæ9Ìñ೨Bâ…2Rd¹^€Ý[OH™!©'¯äê6÷tSÇŸê½·›ÞijŸqµÞj\s·ÞlòϺZ_ös¸æöÎ5ú¦=Þ[®ÖÙFÿçÎf ’@$"ÚmvF‘¡‘h,b?‹g濾§êÌ€ñâJŒÎÕ£ V¦h_ FÀ­èüVt¥†Qb(RÁ„0ê@#64iASNtd+I“EN£`YÀ t˜ILÔ`’L4ûrÐÅÚÇžéÚØ-ã1i|׸ì★&b[5Ùü YqIXÅ+D£#¼F¢V’EUäˆ$ ¼} šlF—ªÑ¨uéùñTLYØ3œ²£‘Zt¸RPyx—õ¼È'ëÐÀ^t&€† ávf’“1“Ä«pðcÈÏÎxÜ穱“>t¬… úpM%Ñ/OÒ ²ªBíÄ¢ù\Usɹæ›àfÚk‚ýBC¹t  ¶ßÂqïºL5ApÀ¦ˆÙæH:´œ-ˆ´\Ä&I‚:‘µ–:7þ³ªðá¶ü±_/°MÜwÀÿ’%KÖét:u–+ %aM›%$çá$@'±M¼¼ì³~æâh<ä¬?ºYG:ŽoîúØ謨fY6†æ9W{ºÒ1*¸Ç×´Å1eqÌÚjÿ),ZÊÐÑ´2ør”€ë…i!£îKCò‚—§y®2gÐâ’t¼.çN±ærQ.ÍŠÜ,Ö„JÖÜÒåè¢ÑY9OIYCw½! weãÎLÜ–F@Ò™ÛR Hº"Wz—·dàŽòXµÅã­éco®Ù£KxU¯ $*…„f¤,ËEñ\J´ò-áõc Ä¿ÛG|'ëü€‡“-[ß[ÈÎpæ5rª± –O ‘cM÷;€7yýïÕ·kbãÕ4™NÂküÐÚ² VRO§­.ÐÈŒÍ;úÿ§‘»ç\•coÊ*3E†ÍÌ5œµ‹_ZœwªkǬΛ6Ï}{-ü„së¯Ø"nÿŠà¾`q%(/QŒ ¬Æ2…Kâ¶d¬ú[Yͳû’Õ3-xg, HpË.Θ]׫}ÓvqÂâ¼dq^6»fžýy»ΔÕyÅê"+‚è{e¥ÆK3 …3Ÿ}ö52ÿ™›# vÿlPECWÒEn- ž”øa(ÄOO#aê¯@ªPK.¿½‚ d”bBƒ•¨4¨d·U0¶D¹6Š£É$2Ó2$ =‹±ô‡)XŠô“ú‹ˆ"ó™PˆõN96÷ëÉ?)%ý0Jw•«T+‰Eµ8Z¼/DGLè`ÑÂóã±ôÂ5Ò¡riÀÀÂÅcà>a¥J„ ;kQ‡äí´³.,ŠH5â%í€Fvù¾ d»'¼SD{}h=aI· íp£ƒõ¨gÚlçÒ5 ~Š‘Jä–‡¿¨z‘?7î‚;·çã`Âë&q‘kæ}iÄ!m°©9]Ÿ•-¡X%°ç%šý‰Ju­@‹KWÞ5¤ÏfàÒU ^ž^ä¹ ^§ý¦D2h%7uš»Å騍ýšìÔbãʿ䦦*Y¨Ë*Å’X‰Ä‘Ãß~3sp ·§´¦;¼#5Òç"Ôº’À¦ ÚÑÞë\sBH\OÉ)™Œâ•Ê8FÎÑÌâDí]£;RÛþþOƒ 7o9UO(ä8^çÿU]ûÍ[ÕÈÒI'­V£ÕhW³º½OCæé;ã³qˆÁ˜ó¾3Ž;.cû`l7æ¸;À±c71~äaÃñ°Ó*©Ú´Må:uò¡í‡Ô­òÕµâG ~ЦVÜH5núŸs*EH®‹ˆ~ýµì²ËÌìjæÿÿÍÓQ俘™ÿÖ3I6ûpF¥”w!©j†Ê1:çD#.4±©Gã‹U=ÓÞmAïAƒµ¼Äy•÷ ³Å×£ó.ô¾ww@âAg tÆM\£ÑÄ&^y‰æ'v1 O:¸mÆíœ‰í¼„×óãèv4‘z©ó›PÂG,Fƒ$“\*ÙòÑçÑé>ªsp¬W+ ÖÒñ!x¾Øy³œgKÍZƒ<åÅyÄ$êT K£ïúÞêX´èàzê@§ºQ¿o«Æ¹‘°AÒË’R‰¸!¿ï*I¬f±5,RĬ3½kX¬’çáÈ*Öoa}pYÄúKçJY 2s9 ruvŽ}%<÷ÆW³èºŸØŸÕKÂ3ØD)ÍÆé´V2GÍCÛÚÛ×Ìm±<²[gìë–¼<-Çr@Ì:,læ”Oªd ´ iØ`TН„‹Y_‹å³^3¬b½0ÃW±hEjÚ—±Šd¼" '@”x‹•óãÁB¾â•,ba1 ë7³^Ëôþê×k²³¥t=(¡F ›$½*`[‰ùpëÎ_tF.õ þ¾{ìñëîïG‹§ˆÇù0¦+úÉžø/»úÂõ.xåLb0ÞYa¹î Þ‡¢ìkÿ²e÷¤÷ÿN#Sˆàt[x ¢2ƒ’$æŒ|óË•D#²"*„P™`± ã#U›&½¨×sï¼õR×-øG_çOû¤{Ñ´p¯5ø…'ðOH[H0íF¸;@/7Ýþo¼_µ†®ùÂpþµ·¾íbõ;é0€¾0œ\m U)äò E¥¢47÷hî[O°äüS‚ä»’™›½üÙŸk‡Uµjh´M8S&©GÃ64¶hAÃèœסá±Õl‚ê)CýÔË54ý´~}ÐŒÎ4‘–UäYØ?¤§=#èœyh`3iB£N4\ÏÑ2b{rN~÷¼Ù9!ι8¥Æ$5üuF›Ñ»ÅÒ ¼¾]ÔDUTL˜h ¥NÌå+¤m«DGžB(Õë“ÅmhÄÉ[ŒÖ/=?ÄhkÖ睊 b ¿\ñ,:ºTéD'ºùq(Ìãä^ÝÐ+¨Ç§ßjpŠ2ŲÑ$U €Hß±_p—³HEò@>€¬ke½ëY¤Š½Z:/d½ü볤IJþÈú` ;ÇbvIJæòŽ’L-Ý$IÙ‹‚8ð\öíº¬¡ú[åŒÃœÜb†0c¯Zò2´ËÁc‹eÆn™wTÎÛ7|¾ÞÜ”EÓeÁH &‰Ô—h³Ñb>áûK(gk¹À*8E"eœ(‘”ÏûV³^p\–³Á5)´T°Áµs°4¢æì…u¦4,¦…ª’‰` Ü¿RÑ¢M?zÇßýá¾þKû}¼'~¡3úQWôýÑZ#¿ëŠý¦+ ¹ØÝ1ùxÿ¡£;Ú³eJ°lÀ$›Ï·½t¯-t«iî©¶ð’ócAÜñ†¿hk¿ë A}«w•˜Œ˜ÊEX¡"1Z¨eäˆ A rqC~Á]Od5é Þôo4ï¾çë¼å@#‹¦_ç5ohÚºá Ý„/æ ]i N½Ø ¹æ Þó´Oµø¯Ã¥7tß¾¹x¹íp´︃×Rî¼+ó¨¬P¢È˜üõò_ÀßåÄSÿ$“ÉÇ¿NR|DÖˆ¢ßaá…;%Ø…&êy ]<@› ;§ÂI—”‹sʲ •ÈèävtÞÃñp µVf“FTBˆ¸JC]µèüËh̆&ìüø¤öÎ'ËDC õ(aCg(ñw ó-ü½@5gÐ+5zY—/I°€ ,aC6äbc–¤©"ÍÇš ˆb¦io8xk Þ’ócA × 17)¡F°Q€vº èd×’iäXï@§ö S`’vôV7:݃ŽÀ$jY©¨õ²A`ã&MØ[­^ï´¦ìQÀ¢³Ñ¢äa0I%ÈAH¿•,ºŽÅ¬<CÆŽÁ–°ˆõå³ýªV‚A¾;‘ôY¦;uØÖHûìæy‡…ÙÍIûºG[Ö/}ZŽå°¯MÚ­ó[@#f˜Ÿ`æO+W?g/`"éÒ±òfM7F´‚ÅÀf˜êó°âe, VÇZÖ»&…órvÈÊbë % !›EŠþä_íÌÕKŠ@Y&T¦™‚ æ(Y¶æ·C=¿ìü¤çÐÅE.ì‰>Úû¡5A/ÀžK=ƒC½Ÿîíg=±­¥ȵYJºpÚZ3ýb'Ôú¸·}KÎ…Õß¾ák¿Ù´“µu]mñ[UM„\#+ª,ë)N#z‚EÇŠol¨ýÃÖ6xøïžö»-~^µS€™ò…Á$p¾Xã™òø'½ûnÿWîÀ×Þˆ+Í»ÀK€„«n?ªÛÿ¥/|Û¾ëL.âwh ^k €v&[ ‘iwpÊQÖ¡®Ü §jÑÏ=¨k}ÅÛ«¹‚b€•tza•švÄ…ÞkDã›ÑHíÿê†=âH™§oB?mD£­ü-FáV3:ã@#6tÎÁñóf³ÞW,¬¥‚&È„H$‘ª¢!G6):¬d(¸µq¦¾@=z{3:×´ôüX‰:4hÇX—/k¦8׈ŽùÑqÿ’iäÄ4ÔÅAG8?à 9¾êvÔÉ+´LB(P"–6Í7âw6çþk_)ÌañL)d­ãÅóñTú}µŒ³$nfñÒù¾)†mãÀFM/JTJÕ,ƒá³ æ|žý‡ýzi*Ëã~’&Mš›››“{s›‚¢8kå!oÊCèCº@)-¡ÐÖÒFDmiAg7+øÄqðµnv>aÜì“Ì̺³³££8"àcЉ*µgÌ&kâ?;u™? ß47åÞsÎ==÷ü>W›3S’2ÑdÕAíÚ@É¢Fóˈ Vc:Ѥ^V¢%À™%ÁY$ÿ»F^š$ˆ‰^³ ™Š’ Êрѡa¨ã%h¨ êBW@uB›ðéÈ•8Xp²õ7†*@§tè½"n)ɰPhdŦÊÅ :‚Çà$ ±¦t´|®‘Â×·̨@G4Â-€FNl@njȵÔ¡¾R4P‰†ÊÑñ¹Ž¡Ã¥èX±pUVl};*7† (.–†‡ÉÅ´fê-G§+Ñ1 ™Õ†tB•r¬^)É,—S,Öä¢Ã.Ôk[0ìw é±£Ý6´Ïö¹^å° í®C½¨»V\ž—ðQ³B‚9†À2šÇÊeÔËbg}ydg*éJ ±¤+6gâ‡9™x’ˆ7‰xI—òKs2͇ñœLÎDÐf8Cù¼$h•³ªÔçªT H@•öLÐÈš꜅/C‹YŒ:ë'ÕÚ*X™ÉOÕ‰KRˆ.ïÁú܆¥¼ˆgVby$%Ëÿ·#1ØI x•d;˜<éÅŽtÁ$ÝI¤+Žøãˆ/øbÉŽÄi—r÷†Ø$™\ÎDJžÁbxˆX µô áÏÛ<çœ[GÛ½£ïv_hí:ÛêÿÄÝ !Œ¸|`ƒÿF.ÌÉGàÃ{ƱãL›?5r9…x¡XúŒÊxÝh½WÓ2nh\p~¼’ŒöICÓ:ÇwUMÇTRL3 %¸í†ËeucFë¤É>nhþ¾ÒòÐì|`°þÍÐ4fnÃLÃ…fû·†Æq³}Ê2Ü4š¾Ö7Üf MÓ&;ŒpÜhý±¦å¾¡iÒhª¶OTZ€(·MVB!êwÞ!p#ð963Z@ß, ¬ŒÃ,œUÑ1ä§g‰§ ’Ÿñ÷ܸvZ†ù†×U‰RІôh õ—½ÔÈ`‘€‡PUO¨é'4èÃÒ0K*ÍS 8ƒ£ž4¬AGu¸0 +Ca O‡ÛÖ  ú+hž…Lã¼(tX‡†t‚ ^×~Ö¡2á´ÁtRÖ£ Sˆy^D§ñXŸ"j/D‡ÊÑp¥p2´3¼  ÁÀtèýR´+mÉäv–‰úªÐé:a`ë… ó‡~y9XEEŠ¥uù.¹»>rxNµvvø>·g!µv~ìò~âòžsu q¾yЏ|g[¼#mÝçZ¼Z¼—Úºáó³Ö.‡Z5]FcVÊWǧÞ1»®™mS¦UÏPå¾ÉñÁò÷ÊÆûµÎ³Zƒœ’P^ÆÊ®h«Çë\ãfÇM£cÂìš2µ|Sa¹¯Û’ùç²w&«[¦*'«×Í@‚©*K¨Æó£Ñ>¥·üµX?fv@û7 Ö‰*ûw&Ç}ý#³cºÊ:Qm¯´Ü3Ù'Ì‚ BÕï-“unXU%8ŽçåóëhEæ$˜‰`ù±«ÿ Ìkägy„³Á`ðÔ‰“RžçYNÐHu .jú@© ‘5/ë{5rLµÈó6#£€Q ¦ÕÉ’¶b®Ø!æe2ЦÙü•h@Ž ?˜Y¥4šå4+RòhX/àhÉkÛVÏ9¤bN…èxYX[ÅH>XÎK1ÅS"I¤çDHê•@Ô_…† Â%CZ!00 À-÷£AÐ×ÉŠ—ÿP/;â›,$°1°ü(¡&Y·©M›@³4 b¢ªÓšnÙҥѤJë¦îŸ®tš¶¦KHI ¡jš„BøáÛsÀþ™–ª¢PoR¥ë˜×Ͻw~¿Ÿ×vþWÛrÇÛrÓ¼¹kߘ§qÅúñµ]sÕeQJàÜ)Êá2ƒq{†é9oĺï Þ€nëZîyƒŸÕÁG¯˜F>Y€â¸§yÜÛ bú‚0>š[–IxÌS‘ o Fg4¨êÌüò2?œQc1íß÷·wP&€'„¢ƒÏ¢¡4X¾ì5 \‰¢+ «ÐÀ³è‚‚ú=²¬yd•tCâ”P’ (yÉ@[Ðk.©0™£R*+rEé(êCg*Ðë_££­š Üè¬ ]ªBçØ½)“ˆiXæ™`Êò‚‘Ð4‚±ÀpID.Igš‹Ð‰JM —ª5\€k/AÑ24ìBgíhÐÎÛµ¥z²‚âT† I;Y—OµDXž2zJŒT²ŠèŒ+mâÈfµÛ¢íÌ‘œ¹®üÑàÓðdÒDd 4cè™ä/ÏÀö>kÏVë£ÊÂÇŽ¢¥ø+¥H…­Þ•÷å÷ù¾þGÊe}P™§ºJæìÅS•ðpڀʪ+û~¥­&$Žõœ@ ³-“ªóL$KlT#yj7”Y=n¹Ó™w¢Ô°‰$ÈD‘㠈ċ¥OeŸðì½Þ~ô·\ w¾ÛÑõ^{÷Õp×僑ßu>ÿnèÈõŽc×Û{~ßY¬kmàÁ¯¿\;ptteÏ•Îc—ÃG'ï´÷¼yøØÎM?H'"æyˆ›³…öq_ècOCÜùñ5Q†Là Þv7Œ7øc;­©&È'#fJÓӊפòJæ(œ¤ˆ.äj’Ó>ª ?ðïqïŒÔ&¼+¦‚ oLn%cQä‘)eD²–0z÷}­y›nÔ‡ÆG7ëÌŸu˜Ûs ñêGUl·ÊŠÖ ¬ê¬ž™Ÿ8 ês`µûiõùœ™HÅsS–Àrp^ã$,ÁaŠ—Yb5¤Fœž7;{®zá—mG¿]¬H]m}îôžá©Ìà$A´$'ßô‡Ç¼Á»Þ–Ow5ú‚£þ„騷~yÏŒ—FÀŸ{¡[>è'4^ßyÙé+IN8>‰Š2ÇcBÀ@‰À[íH5ýÙÓ2îë€æGêƒ#õMw½{WªŸ±ÚÀíúp‹i/`Q¦ËH§ÔBñù2í‹ÚháV}øŸ¾–O=U_Ÿí ZÃj˜­…êœ:©¡b¹Q§gç4òÕ¤,rð¨9^ÈW]#îv4P‰.Õ2§ªH]Éqb /bŽ[Ë3{òЀ ;Ñ%·î%»n“ÀPÖÄòœž cö…*PôÉó.€$º€Pp@rÖŽýè\-z¡œ´nÖoYo šÌEÌÁΔ£¦°!ÀqƒÅ:ƒ£­èÌÖ¥kŠ@­à",£®=ºØ†]TPÔOÜt#/Š„mÅèdê…ˆ¡“Áø3ãÖO›4>õ¶£¾ýè°—çYÔ3,+ÒL>9•»“àÚð—Ýùoo·>ÑÈéá+aä>°æÌlÛ2çÈh‡3¦e¥Ò!æ4Ï9Ì3öìYGNÌ™sYf¹Óöì˜Rs©®bÕ« ïtXbZ¨Å=^W'%]6Õ Ø³j—mÖQ¹©ºJâÞØ·¬‡•1¸‰N+ dÆ‘¤œsN: ãÕOL)x ØÎåf–ɤI³Ö”„¿…6«ÝYj÷æŠËÓ–$¬‘¨Ã^EE?%Éû¶(ƒ¡Ã¿úѱ·Z»®„»ß>p<îÌø†u}äö£ëSÒ`ç›Dñª£vÔÓ´’º Ôè^}ÛXü4rÛÛ˜ØÝþÚÆ;žàˆ;YŸgä€Q~8ž“E‘ç Ïai}´Ôõ^õÞ¿ºõ>ó4ׇG½Q÷î‡u+¦‚ѶR»ï®78â¼#ð¾«þ•žwÊwEÞ¯mó…>ߥ½ («7ák]õ%ò4g¯Iâ8’Ì‹’,OÞ8­id™‰Í/iäÃ?ý ™,jغaõ5²© Mî„Þ*ÔU®Ûc&…zÉnB¥¨ß^¯FîÄÓ.%qÜq‘_ËÞ,£þZÔ_†4\ýäùK©½¨ È`ºXƒ†kQÔŽ~Sιtårºd$ s’Ù´Qæ$‰#Ьœ"¦`Ì¢WË–Z…yWf^œ<.uAÑVl`Q#ŠÖÕ9/¥Á]£¢RÔ½õu —ƒ¨/üÿ¤‘SmZÛ0x%ˆNCÿm¸¡ŠZÖ1ÕSœ$ƒNxΔª0fN'Ò¿¸¯û˜6Î;à ÉÒét:Î:ËY›¦¼À0¶Á¼„|¾3¸Û±}7ð6„$UÒ4Í´’—†4 /iÖIk–,Í˦J[÷GÿªªMÛšµMhC–òŽ}ûé²ý±T,@O›ôºßÝÏOÌ}?Fcg7¤‹üÆiεÆ-9€„¥j‡).{šËŽr ƒÈe‹\–>[,+Žqgؼ sÜq‚Ïç¡Gô²×ë2e†Ë›´äM²° ùÓ\Þ4kšá À$²¶Èˆ\Á¤Ù4i6€`Ųœ)Ö8aqÉ6O™þqɆ)¾È– ›"ØV0–1®~ÐXÊÄ"A£NN¿o‚€¿#œëõ­;Â×¼y%|ðF}óGMoÞª?r@"73˜[õ‡®íiÞ¶±TC)q‚H¢È}™†Áª0À*uXÝwûïºj½AÉ °D& zý #‰FRÑG=õÍvÇ4°q…'—­Lï*äþj¯ÿæ¬},„‡]¾­þaÀ¹k´ªnD-ÝH¾Çîà/ ÷Fú=Á;ßîР‚u{äÀ´°býžÀÀV߈g ïûŸ3ì W®NW3Pš°Ôï>þƒç^X#sÓpúD4z¶å¸š‘ÐMB± †e×H»õUÄ)bFÝ,¨]ª”Jö‡Ú¨£õ”K¿êdW´;ñmë^" R‘@¦Qh/ðÀŽº­è24rÅ÷‚çâ ¹ÀKi-F7£>3v’S®Â –¨LÄkJ¤7\rbÇKñWÓ O%á€Ñ:•tî3ÒÌó¦çùúÿÝqtÂú°¨§íݤ¢ŠNÂIõ†UR§Ÿ‰ ÐÈÙz»N~f,0ïDâc‡Ð[~tªµ6H>9îÃ…Rì%µ–bT8|/U$x™¤v&8Ÿ¦/)Ë æÌ3À>Ú²d‰Z b\!¦ØÜqÖô”7=µBô³–œ˜5/fÍeõ3löŒE7óÿ«‘iKƤ5[´Âòê%ŒY ³Vã·¥²¶Ø°ù1¾ Êf9b|~lé¾?ÿm`aÇJ3IJ¼OòZš`”j"¾1Ôà+4 {'’”JNdªÓZvìý rèjøÐ͆#¿iwì"_Ú·?ªŠ|bßÞ°^÷>çzì¨ýzkœ"ñ™‡=A€dÙ×Ç:f,LR‚ñFóFK‹gÅÔˆŒ‰‰ãss¡]Õ4†i˜$L…¡EË®©L!<êáQ/´ªõKJÐex…Cm,jçÐ{6ÔQ‚:@NÂB¤á ; ¨¯]°JŒtV>÷úÒoyÔÁ¡îr‰=ݶïæÃtn+`¯þX+õš’Úô2êr n3ú‡z9t¦‚XIÂÖ$¹,ß,!äYà²p5ÈwÈ‘%¼4tÄYÒçÅŠµZ vL´Zãî’¸FBR¿Ÿ¡Öÿœ¨“( 9·GúÙâ“æ¿Ð„N5¡ŸÕ&:õ¸R±žVÂNJ©¤´¸‚f?ÒgÅʶˆVƒn Ú„3}Sš·Tíü˜´äM‚CJ3l.ðCäM³æì «n’Ëšã²cT³Q,Ë@&ò×ë2µ¤-wŒ5NYLÓ–|hp‘Ëšb£ìƒ-2ÓÖܧÃ8«‹C+{Ê¢gõ³|Ž\óL™bEÑŒ¾QÅûWkq c(Ei0õ£’”$É(´*ziůÂG>hh‡|9 „Hi|ýÚîׯ4– Ì­†ƒWïývÿOõÚ5MSJŠÁ±Þ-6(ÐùÌ—Ýý8E…\y(„¹y=Â÷ªÂŸº}cBýWŽš{.¼áŽË÷™ÛÿÇŠðâ—Žê'Û"O«ê†;TÕ8kÔ[·TóüIºud¤*òwoäF‰]Ÿ¢YKM†®øŠ ! ÈG <,„¾ò.ûú x·Ë…d S3*5A;„*q6º(DÅQ4d­Sád©Q$cè¼}Ù5<€~ï`ãõÊ£.8(E=ð³ýœGïU¢6]¢Äk··2ñ Š Ž­qÃpÒûß·|¯F.þ›ž½Øa–Îj·3¹+5¸JÍhhÇt îâBí¯ >jó¤f¼œD1d:ziÈ®ø‰p° d9ri¤æ/—`ƒ©Î¹0-žBÐE15jÞŽN†%´6¢Ô’Ÿ Ì[aÉQ­t2 ±æo­G§ü¨å5tº½HØï‚‡2ˆ+“4 †ð¯b&Ù¢ikQÔ’;Ê)‹ZrŽ/Z²æ²`» ؘ᠋õQi÷š'ZM"o9ƒÈÏJÙ8n1p¥á 8j7ïdpŠaØeԮͨK% ôé7}7è Ê¥‘{Ž]cÕõ#î ´ü=!´rÖN‘»ŽÚQ¡~Dˆ|j«>‘]h_µ&&S5ª}?Ñ÷[ÿlß yäò?tÁ߸–lžQOø¡Ë×g~¤VážH*¼ët`$°G¿'0ì E'¹»Â±nqÕh%A“ Nèt:ÈÜ‹kD<ûš"±T¥†QPøZ õU,»F@¬Ôªã—rtðèd“Ä’>‡Ä°J'Õîð€ µñ¨·µ½‚zËQ— µ[%«<÷åÿš€ $•è¼·êÄõÃ(Hµ=õò ç쨣Tºl[µ6%59`4øŠsÿTÙ°WÌhaÊcSÆWY퉯µ/[úלåS–ìGê©ò©5kÊ”ôÄ’ò½99hÏ=œ³˜c0ü.’Úœ?yûs¾æ M»û›¶}ØðÖù†]g•æsýtã|c+à䬲]ufÌ2—šû·ìè÷m;U¿m‰_l'$Aþ樄€F†]uw<>x…mµ42äª]tT‚FÀH×Ê6=Úà¿»fÃ`yí7k•=†ÜŒ¨Œ™pZB‚Ãûš$oKÎþ‹G¹íòÞƒ¬ÜðÌÙø˽_˜<Þ¸$=†GP(01óFI¹îª¥„s{Aq@‘Îê[åµó=?pu®;ª\ ãC±FGDÈȃû“/­‘Iš+_~& ¤Aäè‚xÔgšw7¡> uH1ÅÆ¯ÊÐÑt܆ŽÀž5¨ÏAqBœÐwQ Ñ{ùèt ê2££vºó×Ö™?:Ï ~è³ÿÄ’ÞRÔE’ƒ#9NÃa>‚A-Ù¨§1£÷óQ I`˜8"3rê*¡(Æü$Ï?êøÌÇïEú,è}3: Ü*fVˆñ^Ïñ¡-!í mðö:ÚéÐæõê3c–9HÉA7(¨SA j÷…µùÐá èP³§Gé ¢¸˜eÅ%íiã–Ô)³áqQÖHQvÐj ™“æªö'.«38M8Ö‘Ã"O8¢åÄÐp‚y&…0þHélZÂM“ñ™4’ªz½ÎS>3f.€Ç/ž…ÅV‰$€IÂÞS}`¯˜qËò¶8m, #„%˜}Cd¼´e©5žI«!hK‡é¾9qÊ’þ°0Ï XÀýŽIc¶ýœÒr©iû¹À–eÛïümÏÒ¿¹å#eû@î‹ »”–Ë­ª3c¶ñoý a+œÅ¥ÆÝ‹$^Xú%û´À ¹¹Nb*«¾ãòBþ­:SîV(WU7Ö*ÃïòÚÛîÚï‡Öy']ÊÇ«=q„cáñˆ°"ÆôÏ‹"Ôh"Kçíò9k†<µßºªçjYd7¿1Q”?Z ‚fzÿÿ«F²EÉÓ‡Y,ÁS-Žb™­‹bÕÏ„yùXQÆØš:fNÚò®älˆ°È½¦ã$Dzå ÍçßÜþ[ÿÛŸ4íV¯˜ Zú7·\ ìêÙˆ´ÇÁÕH—µ_9«Fܾۮšžš[îš[¾ÁòZÕùñ³\ùźÅ,–° ³ÜÎ%i×*¼WÝÞ‡®ÀVÇëZŒ…hÌ+(vÕüË]÷O× þeÐ]÷µ§úfYå“ ÿÇVQÍŠÑœÈj°Ž@ø4Aºêô®UF¦ÿ(¯ pȳ2üâÇ}‰Œº•þü5°@b–G±º²êéÄÄKjäüóó²yÂÁc (côž/œ÷Jí³£S¥¨x`E}P¯Ô]ˆú€(º³×J÷w™ÐqpËÔSÿ½òÚ‡%•÷½õÍk2à\1bFú½U}eusíÿ¾»æ®»ú¡Ïÿ•»jO¢I¯fŒ0¦¡X§È†Üˆ„þsñ_”×Þ÷TŠL þw†óÔ ,<ÅÁìîû-©RÁžRg–”´É—d‘`p2øß§ßCr@0ÑCš`d¨Ýƒz îªíVÔ᱇䇵£s!Võ¯mVÔî@=.tÞ¥þ²Ã>oã¶9Õn/LäB§ŠÑž\Á¶T0*ŠŒ™¢‘³ xgº—aôÜðãÇ ‡Ju@YBDÏó2X$cèÀ6t² µúÑ;þ4ªVÎv̘¥ Z€ÖFtb®WáÊ~t´Z2è!7Œ!"cäJÒš Ã´ÇÏ— ‹Óž„RÑÛf“j8ÊÅ0Y$"ÀÄD¸õ„`XaHFdx(o LæSdGKôԔǹa·×Yê×Éq±LË\„‚5X ’À_ixQûוFœzöšª' ˆb>Š’CFc¸â :2ž:3ž…hä™=9èHYž¦Ö,‰†ÀàÃæJÉü°©|üÓÆŸ…'^Q¿rÇÁ›Í‡¯ûß¼Ö|hÓ WN}Éh…qõ·e>Oõãòú{eU_ûê”Õ‡?fèÓu®hIfœeyì·>ÿ¨{ëßJ+†¶6~WZךéT_ÆœQQ`Ö0…!ïœiä?^ÿ°§îz‘¯ÈhÔS^G©Ž2³ÀŽæ9‹#£tŒ íÎ*ܾóQIå7ÞX±iôÕ zkA ½}žÊ>¨lÙeÑGÉ¡4ˆÊøøØKÒÈÄÔŸnßæ´<¶"ã¹,êô ³ëÞX]¨Ã‰º*ùœ-@g­¨{êòªdò5â´ê¶èlq(’BÔmÏqÛ Ô/¢ !ÈiÛ€N¹Ð™Rt®ulDí.ÔéB]ÔÑφ?f¨Ó©"Üi;Ú›ÇSM$¥2ÏdÓjB~Ñ€Zª››¶õzÔúá‘iö8Ѩ–­!8 }åJò°–%žãM‘Rб~Ê–<áH˜/±%Aj[·%RÂTk B4eމ¢Ä,NÏk£‰vå$^‹©& …ç#†«-’Ó«–Ž8ó!± »½ÎRHËŒ&”£’H%…JZ¦`BÞ_÷¢ö¯+|œš@Œ‰>•HA4 š妇+ž Ó2á0ÛS¦¦§Ó¨5IGÊ—9Ù‹E¬g‚V!í¸¸9ð«]~ç?vœxEõ6í ¹±ã T®6µtÔîŽc2°>•Å8Q¾SZ–úÈ]u¯¼önYíù»ùBë÷N¯–hE&*”~¶áa_u¿{Û?½•+šÊã“9Jc˜T`\~׳}¤Ü×S3×þGË»2¬É:G8YÇ©P¶$îËoùº¢©9Ö¤Á=Ov®Jzà®p«H0­ç=L3ÉB¯Ã¯önIå7°Õ˜Iø!þüÖ­—ƒ‘©‰É_^¹*†žF9ME’êÈçÞ…Ï€±:P‰]uØN¯æ¤í³â²UÚ\‘ÏSDo<Ú›«BÂ¥RÔž3oãvYQO1êq¡v'ú¹UÙ“«iÎûÑ©2ÔV‚:­è, ”‹.ATÑûŨsSøñc†á`ÑN;IQ,Q=à¨H¹ÍŪwƒƒ¿ >þœ@ü?0‚z'€Ž×£“ ¡¹4¡–m4JljÓbI&Ÿ¬eOÚLOìÉóåß[Fmæ[é ã° P†(P‘H”qš=µzÅìŒ뺇ëóúóó/­‰/ŠŒf¼ pûb—LÚ2ƒÎԧΔ°Ûë,õQZŠ[yJžŠL!Œ;nŋڿ®4ò¨0õ·é‰F^»ˆ§Ë˜˜(p·3’§©áŠ'*Çì&’ï©#6Ô'í)A{vÓbp<ŽpãÆÔÌ›;Þð·„'æA·zoÝÜ}äZC˵æC¶eq‚zÄÔxÙéòþ]²­s]EmiUØñc†þá­²Dêô˜ Þ»"á‹òÚOÍ_àƒë2ʘ$‰®%-§ß]9ì­˜;MÕ&˜E1•ÑtLl³ºû¼ ƒew]«¥®"¤¢‹ ÀZ©R^‚J¿·4ª,ô: VÔõy‡êŽ¥­1"(åâÅ—£‘àÔÔá#GQ‡1EíÍG`ÖŽwÕNçÿQD-½ô“æ/Ðid ˜£¬ÁŠ–äèÐn3êqÏÀ¸¥¨%OŸ³„#ŠVÍiiDD¾íËBç‹Q÷:ÔUˆº\¨-„LaÇ™4ZÑ{NÑþ ÛÆc½ˆöoWÙã¹³«â_0lX AÀ è ¨z¦ÐkÐlÊV8B¢¦Õl‹‘Ǭ槶äqGú¸Õi7ÛÓFm©Agú_2Ó–SR‰*Ó3µàÝág‰WSoÓþ› ‘{Ž\ohùx×á…€F(æ%Bë’ÒÁÁ‡Ý5}eÕƒ¾š{ÞʰãÇ }îÙòvjÎ"^ø÷åÅuÅá+!YZi¥Ñèjt5£;šÙÑîbƒÁ®Áج×^Ï®×/`w^ë-›e "€±1æQÔ„h©h“@ÄËæåŸVMQš¢¶HQ¥H}(j‰Ò4Jx°ãçîôŒER"H·¸êèhtguï9wÎÜ=¿ï¸ö.$‹«fέ‘|EP?ÆÏ‹%„~X}7Õ~¹eÝ­Öî'õÿÓzm¾Û-S‘ÔÇQ‘§eŠòl Ü«.>¯¯:µŠIbp‰$ÿ%ÝýÙŠŸ®X?ì1E#€_ÉS ‘ô†©Îë+;ÎÅZ0;UX$aÿs»¾3$’KyLy"@»‡ö'Ñ›ÍèÄâ§!¬€"'cèLÒÕÛÄÄž1‡Ãçey¯›xdì)%"ïÊË+cÐOŒÜ]Êm©¥Äåu³^NöYbˆ§³" hK3]¯k3Ž˜è´…Îæ.n®¬9ê[„^Z̳.™ó(˜pÅ :üƒ)éqÔü•MèÕ)éíF6M7c<¶ÁÎt9÷Ã=è¼Eþq'*• °HDöB $c…G­à=À >W*ÑÊíDC‹ŸW8{*ð"h´ŸãàqçœY×õ%v²Þ6Ê&²q³,c,ŒØÉjà"hZ³VmVÚVµmªÓ.¯i¿W€ å9‘R"ðeæµâ™ß4ÿÿ•Fl+šqä¾Â¶*²Vù¶pܨÊNßw3ƒY£60ª«Y8áV4kÖ>ÔUÛ ÞÖà( K„Ș…«ÏoÝ=í8ñÈovì{¯gÏ/{vŸëÚõë­{mÜ 4"c*q|¥$4·Ýní¾Ò¼îŸ+Û®´N?~©ÿ·bËçaŽ•)  ]'OyìüqÏä)´N¥’›Ù¹0ÚߘükÓjE€ž ‡|iŸ¬|æmÙøarH>xƦ­¦ïL#³KÌåб[ÎCG—£7“èD,gêyÜB}M¨ßBo,ð@G-t$‰ú Jõkè`OêªqË‚B)Gg@ —P:—%’›`N¦–âyu%ÎÂ~Xh9®Î.E§šÐñ8:õ-ª=eàüdÓWã¾);dy|¬ÈáÌr<+Qäàñs0±¨Èý,æpÈÉ$:µ Ö¦?±ÓèÄ Ÿ ËmkÞ¨µàž¼W+/„Š/FJ†4PáÆ -ÉÉZÕàÄ6*jA >ø¶±ð¡1Tˆî$-ù ?€90Ó¬?ô½ß…Jn/ êAX8fDm#d•v2|7^>dM˜Óʆµ;±hLƒïÊZ Ÿ/©¶“¹òŸ«ó9¡W‘ûs]¥ŸË+â¨K E‚çl×ßíÚõþ¶¦¿Ó½ûW;öëyáíÍÏ¿³mï´cÆcÚ[=/¼»u/ÐØùž=?ß¾ç{}…³@b1†š!¹æFKÇ­Tçµtû?RmÓŽØôÆË© —–=³4¿0óy”ƒó”ÂÀÏóÛBõWW´]^»ùfjõôú«éõOêÿrjSoYÔTü²(¸DÖ-Ê/æØÈT_ pDļˆ;4 2G>ZÑa·n¿ÚÒ>jHo¼šþ¯çízºýfKûÇ-mOuT ЬpãBÁYÀ•ù7ÐÈ>dˆ$óyŒG¢rHFG–¡þ8:Û”3õ<µO¢c¦ãÄý¬…ΘèLÌ¡”ãËÀ8±Ôµ¼ÔGgúÜ#»Ñóz=…޵ Ý³PXN„Üèp 1¿òÜg|| !_Ûpz°ôw¢à–—•£Ú±ˆi¤ uó  Î[]‚NhNØá‰ÿ=Ô[.•y€CàLA@Ï®F¯tå lr¼Üâ œñ“Èí|“½Ü…ŽnwX¢÷ütçË2!”(aN•>0 qPù³9íIê•Y½®ÅOYÎM!š z‰Àò,™UŠüIc½ly‚¾pbÂ`ðPÇõà 4B£VxÜkÕ·4õf,òR±·Eá>Úê—“2]-Ë[ äósA…3úBP7ƒaM5á-ÂcZ%ÜûÊò;Úâ“ ?Ÿò³f>5|ÂG5Á/âÃ1uãLÙôy¬|š–”f¿œò‘_K†ãµ‹ª;fû‚/ ˜gÝÐ4)S@ÜÏú®4ÔÙ Í6Mêá‘DÕ]M=,[/‹Íq¥Ÿ6+» j@Yƒ:æ!$'Ûß}ïÕü@#§{ûŽnÚzô{?Üર Ø\íÀ>oõ¸ÖuC‹^Ñ"cáÈ¢óã‘qµyýX¨ón[ï_;•Õ÷f¹ž3¥ùli¿tV¿¯¶] ÷Ì5Eok]W_€¼þT[ÿ¤ó´õ~ÔÐ>¢u]ԺΨá¡Rõ•U®–ÔÌT}6"Áå‘Ç’ U‹"þµþ<¿ÐÔ1ÖÒy †Öþô÷¡ý¦i]ië©K[ dHœœü!ÿm’Çÿœýó!6,‰/VÚ˜Áf椞’´ô®×p¤Žªf+™aŸÎý¸žÒ˜_hÌàZÖE—s¢ ‰Ü eµ ÿµ†9ÒȽ¬r"‚Œ`%Âìt3ojh1T§kä1Z€“þD¡èŸƒ 8Yð ÍHIÁ&‹(Ÿw2o= gaÞnbT«,l#¢\>a`µ~}…‡’§²¤ígéoà)«  ¢ÍÂü$y±³;ÂìŽ1¯Ç™]Q}r0ÉO™"Æî¨a°$¦k¤'ÄóœYýe&ᶯìn:Sô§ Å™DÌ)y³ÁÒÍÙÏ@;O(¼Õ)‚@dQb m¦óenH¥„êšQrg•ÕÿöÞS‹î f•¼Dm~B-˜òÞñ{gýÞ¹`ÍÁÕÙ<á8˜ˆdDˆJGØMLÔ–OûsuE ]ž™S fü… µ¢ÊN%#kÔ»*Q€ó,šÈµÊ5 µ4¡V ˜3ˆ”‡Ö‡7ñ‚µèÕ¹oç5XÌF ƈ¦Ñ^6 ( K * ®ÊŸ¬“Nù f”Ò=+²ô–E &"# ,/b -–Œ°•j!äô$ŠDþ üûƒ»øžR v:ãqÀ,ÀT;˜E¯„[²–¿““c¥ˆÅ\¶hA2,FHGê#+-„sXÐ_]9ó €Ä Û5p€Ä&ªa»Š¦jÝ_½Š]\‡e_kŽŒ†"ïš>|öù‘uñ'ÿ -ãËpÏ­–î+íWš;G ô[b£Züƒº¶ƒ¥JWNAEjzª¤—h(ìàžÛé,ûT‹Ž†»®·ÆÆCŸ­ë~Úûp]ëœhí Ç.µvŲ t D@äܹs ¯A2÷L¯‘_= å×F(Â,ÖV3‡“¬Èôƒª®@ȰÊP–¼®0‡BÌázfŸªc¸«)i¼Ñ(˜>øŽŸ.g†=Ì@¥ôÓõ˜Êü‚FÞôë\˜öFù¾ý¼_ƒd@}¨88¤X1È@Yf?p¬3õ…}¿T‚ÊÎQÞbdê™ÃUú V¿øüxdÀUl®DÄ(#A(-ÉÓµ°7y$èïaötëãÍÍLÿFð˽IÏ·)èµNfÏF0 Ó'Îå)˜€ æöe¦'ê*¡] Î+žDÐy7y I³ï\¿-t˜(–9bÑùK­Ë"…÷xj¡\»]ú“;oÒçžU½ Å;,žVògý+Êê98€‘JŠ#QWr¹ª4GÆB¸ŠDàLh‰‰d™È'e®iÅ9¥æÏ+ù3þ‚„ê½,HÝ£^»„%º‰;²,ç-éˆk_–>¯TNrçn–²T”Óõœ–8*¦ò¸Éžž-S†ŒJ$~à‘•PxMR¡AˆE¬™¢ãÎeÓõî…E:÷dÚ‰H¬zt"0¿L¡‚4}!Ê#³^þ% PœÇPFR1Ø€û»×•P\‰`дbp2ØX §ÚÌ©@&fŽYx²L€®ˆD ¤%ˆ-°ÑOŠ]’YHgÕqÇôrÂŒJŽå¬p˜ÄÃæ'8S,Y10Pd%Ë€•'È.ð[3ì7«J!ë¿ðåM+¸k÷rõ•§™%2Ïb#æ±A†íåqg "õþ‘ÂÕakš6ŠgÒȄϛðçÞ÷çÞS úWfĉ¢hÁ|†$2æþæq%kþ¤=Ÿªç~ÐP‹§|åUv(„œnNÄoñ7{i¤ù{½}§â[ßÝ´ÆÉøÖEgÆwÇ{wœX°Óéø¶÷zuPéDéÙ¶T6ËkÆÿhŠ@Æ…:![ŒµF/4µßjŽŽ·½øÏuñÖn˜ w·t\^i6l*©±Ãû†¸Î•Ž[k{žtþKÍÆÂ‘Ëáè¨Ö1¢E.?Œþ(_Õ¢7C±‰–øµpü|sÇIµe B¯Ì«·Û”ãþ¸¹c¾Š\_»þFKäiïÃxkt\‹] u^jîÜ客š1À6€Á‘a@xeØ>y5s?¦„FÿêÝ}¢Æò(×ó)âx]Å\¬"/ŸùgâáÙX0ƒ™1WÚÎi¬l󄬪¡”Ød% §H[Ê]s™£-ßxËï»\ÁTÍ6WN·†çÌP:˜n ~(‹•ÎECcËœA?*L"rWœnF÷xgU÷b%h`‰Õ\6ý–YuÔWXrY¼„kP]òçH…eFîG‹f›ÖpÅôqæ¡UˆDn•;Åâ,•õ,NrUîÐ 3ªÈLXA58Ø!UêYŸ7ú­æÀ”ÞWœO5¦r{Hš„3uræeL„(!;enO™s…q‰;.†³Q:QòQ¸\VáCÆ–‡SS –rÿ!Ùf~¦iP ¶f #F¶ìuR%K•öçyîÄêgâ,fŽ•[Í•·+Þ+-ö Ú¨¢hh¢lxe'ä5÷pLó$>¬Õ ¸_1|Ti¬8?‹X‰Pz!š±þ“µþÕn¢KàGQ½*VNQ@&F•V†+Ú2îtÀ\ö)ôbEù|¼ÚZWmÅKîÇK_(Ê&ЍªØ…D’=;Y„93Õæ´™5ÃéX™•¨}»|M–ìp/l?ër ßܾóÂ÷^Híº°m÷»Hö‘…“gÍŒïØÞC;JØIì“{V•q‚ÆN@úÙ}99x39x-ùÔSõIÛÍÞaïu Ÿ«Mì V¥JË>mïïÞx£³ÿZgÿ;Ñ:6Ãêx®BÙyã]ÛŸ´ÿ+=›¿èíOn¾ÞÝÿeïЂ+®õ A;=C]ýí'»n÷ŒÜ\?|¹}Óå ©K½ƒ—:7}Õ·c˜ìMÝZ?øyÇŸúRt÷_ëø"¹åÆúᷣݺácÉ÷ïßÿÐéôüüüZ:~¼FºÖµ£æ¢”q]"Ä[ì”?ÍXzž2…“Q[8÷Ó=´¥XRˆS6Dï15º$_âå^u+F±K8Ò*œ\ DZVÞP褒®Sýûk„³m6vk3ã±dÂg¾¡È"KNÛ#Aéu‹ªK1ö€¥·Ú…×ê¤&²Og*«qÙ$ûe¾Ý/Zÿ¯¹?<§z%fpå’Ê…ýýÂá­ÂÑm™ÓÈVÛ!h‡…ã;làüHæúT;š²åóʈpb‰E•åPî‘åç «¥ñAÓš930WÜŽ…f2§‘; ÿTÌoµ6¼,kpò,žE9AÁª+ªF—íÐÖñŠ¡FêâŸ.¥–º>¬þº1<“¨yÐ\9óß_ÈÊùXÅßk*X9²G• û‘¦º‹°*ß×[fÙ@búgãUV"x¯©ºÞ«b÷Dt>Ñ!’§Í«%dūݜêÄP¸¾ŒQ HâC*¤ŠNe‰3ŒÓ-:ì¯À QÐ £•> ø­Dõ?šª¸(²—x‡@d\ØWìu1{Rö¼ðeë‹SjpéƒHdƬ·U‡ý(.n¦*öe$–%I¤Ô Ã6*ÃÜ\Õ‘!’ Ehï²á”¨OãWjçÌJ+Qb5g›Ê°ÎŸ„JW+’$eåj†Ì4öRÜFAÜ£Yé;´jU“ÛÀà©=,e 繕 éo•ÀL­eúASˬ}Ù·Ü#2-`˜²šOT‰Ð7ÊZ·âS©Ka «JIPã+B³Íkçšk®×¯´ZÃV¼ìˆo9¾÷2ƒ@–Óa¼¿D™ê?c‰GæÌðL´ÄJ„4Õ­Àz{ƒ†ýã¾ ïþäÅó©ÝóûÔÎwFv½·cï3gÆwl{x“üqt÷ùmc¶ïùQ¼C%xÈð”‘çýUŸu ÜéI}ÖÕÿÌùñ­v»c#ÿFr(š-Köá¯ë~`õí˜LßJn½žL}œØàŃEˆ,IW;Fž´ÿ¯º7Ov÷wn¼Ú30Ñ»å*V kàVrÑ?±~ ¹²p¼Õ;‚õ¹›¶[ß(þ3µad²}¾ý²7µH¦§Ún$&ºÆ×Nö¤.µmvŠú‚RÙÞÞ¾ˆÿ)ÿþ4T×iŠ&;²KNv o¶gMá\Ós­ðF\8ÎÅ…c-bƒ“hð“dÔU÷2æÖE eVcºÂQÛ°û¢îØJ¹Í'Ý”HN…³ÚláµnáTÂngLál‹M¦Eœy4H`Åö$ r9‘Q-‘¼«DØc /$ŒŽe’&q¼2R!áì´p»Çƒç™´ƒmNî€?u¦ðå¹Â±á•­ÂáÌ©à¥!áè°p|»0Òe¼˜²OðgûTƒ| ¯Ž û¸¡â‘–)-æÊ§Uås‰*”÷éxÙŒ„F¦b¡ùÌiäA,øÏ&ÿt¢*¯þͪ¼zƒ¨TÌcr1×dÊcÈ_SÜ"ª#SÃáQœH”¬ÐÕ±Âü+ua«¥:/ÿ×Úšùxd¾9t׬Of{WEŠ˜ã θìUèû¡€•ˆLÙ LÇÂÐÈÅÊ 2Ç]8w"bmœ¾¼Òm™ w¢‘{fp&Z‡WÅAT5D³‚#‚›ª(qNÕ»øÑ¢üáœì|—ŠÁ­¦ŠGâ"Ák¥{‰‚ã‰Â‚™he:ù$R~Ì·ügË û s—º»°mcÜ@23=®CEV¯8°¢pOQþá"Ïx=¹z>ø0T†üsÙcwHX"ãU¡šª8Uštë óžË1Ü*ý7ñeÛÔuÆñ+UŠdÉ’utttt¯î•¯-;!’B€ÄNìØqLÈ»}¯”@;½7›h«(PŠ4mꊀ–ÑBx©ÖÛ$+[¥õ¬|™4mVFy'hx 4!±ïþ×lÓ„ÄT´°XGW'ñõ9ÏyÎó<ÿß:²¨ª xc#ù\F&ÜrÌ»2:óßo.5^¯½SªëH$ŸÉó© P˜µÜAOV•œÆê—ÐßXÝ/<ÅNÑ Ãp\7W‡¬o»ÇáíJC¯¼ÜXÛæÄ÷lœ)b2‘hÌOú<Ùf¼³l<>ì-ªóJË™ïQ´ÆÐƒFÄ3®®Fˆ¨] ŠÀ]`!"™8é™ o¦ÖŸ©øÌFk¢tOV[Öþta1gŠÈ\áÞö»u¦Žÿzý¶ß¬7Õ|Ö1ã[ØŒ‚:1¼–‚o?>´uÿša—¤H&$³¥î‚‹+ûï'Ö^èì›uüx–Fºú/uöKt”•#œ×·]N ^jYs4Öý_M؟Ǭv»Éø§£«_tý«‰ÞkÉ>hýmÐEWúz¢ÿFwúZWúV",¹ÑÙ?Ú5x-™º¸²ç‹•=_&S·Û{ǩˉþ‡ÝCw“é³=WÚ{F/Ý·ºÌ'éFGÿ…•©` Y´S^RRù7f`>==…ñßi%¿w »)â‘.“@##‘SÏíÂA A£p¤YYné)·ë‹¹GSH@øj!£¨H(±LQ¨Ðàár‰q«­ˆ«Tfyq·°¯IÁ:­&Š`̓OCÏçmü6ò¯q076jEY 2«lEc„B/J¤ é“íN.|Ð.ÂñsÛÁæYÇgFº*_²Ù •dž¬RØ_+¼»~ƨàñþð£>¡Xæõ>á'ÂÞuÿÁFï ﯵ®Š çÜmp-uwêËŒÖÀ7‘²,t<€XLÏzȈ/}Ü\năZø‹eáåsÝ¡@̼Aá™H"w2.Ùh!U¦Š’¯Ì±Ùz ”Ï˘7£7|õ­eãM‹OUùUNçP:‡ÙÀ ÜìôÈ–y™hõ­ÂÐýY-˜V|X¾ˆ«›©œLÊpPévS™ d =Z© #¬’¹ŽMŠ$ŒT(ôdÈoèa ¡kgë¢NÉ"Yœ2wsFe´'Ô*óö|ùF´Òh)ÏD=ÑДzñ|ZY5ŸÙ`N§PÓ2…Ûö/ÌF«§ÁHQßc¸7â5tï”^ñ0Rv&ä8€  n›$ãªÕ.69ØÝú£µn ®k­ùc ¬Z¦*E\Z%‘ðí8‰õoÉ“HhÂ$IèièˆwÑ|bÍö’‚Âi^ÉUF¼„i´€<+GqË¡½%¯1nA)¹½”«"<)ç5×~­•fcU_77y9ÁuH"Nˤ£.çÙ¦#¾l*¶ NF«OU—ÿ¥zÉW‘ \jèåS1œoÄ«q»8™lsâ–)qrf§ Dx:X:SëÏT|NkµïxÜ›Õ=‘Ð¥º&Ôz³vJ¼D´ÿ<ýƧw@Óoz@òÉà–YÇŒo9N®{ëÄÐÖcƒožØðöÑõ[Mã7íÀäØðö×ù T‰1'£—Vö?ìLÿ-Ù?ëøñ̸øþuR;½5ùLb”ú]¯zU·ó<;Ul„S[¾„¬&xžkO½ðý k}7»R××;úowAñOµ®z/PÛ5¯¨ºÐ]Sè^5·xoeÝçñÕïJ&Sç;zo¬ìùª+}vu‹Üí|ù®èì½ ;“£ý·’ÃþüBY•A#²,g2ÓÏ£ÀI6›ÍMþùÁüüùó(2 ³Û ³59Lr8Ô.ìo5™äe«êMøñRaƒŸ½þšêu¸T”¨€KD!ê"›käΣ(ú(†¯ìkq ª7¡â£VáCMØW/Ö„áH[ÞÏ:Is>Z-´fî"’ÝŠ²Ã¬…„’%\Ø>nFš…ý°‹ÌuÒ_ºÚBî÷iÂ-Â6a¤SØß%ìlÞXF:K,U^ç©2qJ}ªðîë56Šã€øH•N:iµF»ÚÕ=ä³±qc.øyw~œmüÜÛ=Û56gÀ6>ûbS"E R… %R ØøQÔªA‰B[%Š"…¨R¥´R>Tªš€i 6%qŒ}ö]ÿsI¥ ÉhìZªµ²V{»3³³3óÿÍDë—?¹Ø,ˆ5‘|£‘k%c9ßbë*Y“!Ë’-K器ùR›\–Jd´•Œd¤žŒo%#dtåûa©c¸I´|Äm %?¸ÎÖ¹0!p‡ËAí"'£äd9Y6œêƒmR¬Jì][#Kò:·ý™Frº¼ŠŸPÝ^áQéA—eÔÈk}äP›[Õ¹;RͧKŸ¥+­‘˜á›3Kà‡„éŸ ú€ŠDcÙC¤L¨ænMù¼ù}ëRÒ²M³É\òp&zž;0Ý$'õˆ¬TÒ4þAqÁ|²´YÅ ÿPNšFí*sºx­¦2ÆTÛÅœ¬DcÍ? ßb0ÿï[Ê2 6€ ÊS8½âÍ_J#H NU¦h9:¿Y]"â/X”0Kc†?fÎÖû4.+"æ*ª¤) ±Žö|«‘£lÎô>±Fü¹:oœ¨Û!Z‹×áÍn xC.Ç¡Ã3_¹ŸVnbªòFØwéHsÅ’‰‡|³FyÎ1Ut#GèT¸gr²e;OnL9½>õå¬Ô£Ù©³¯®_çQmN:à¬Qšœ¢¬Ú˜6Ü7a€Ú°-¢hj6Ê앪rrùôó( Dý™éÌáR”éN¬Ã+­‘8¢ß ÄÍò„˜©÷SïC¬ÄM_Ü,H„`’\ÿª®ü=_Qgº‹i6Îí\U\µ;E~é²&)ô…§<³¢(ï¢U¼hzg ïõš²BIœ»(—UîQ4™IAŸ Õ=úVÞÉM9L¶»Å †ŒcœÊ5N~¿¾b)èbÙCzê•ç7fUÌ*š1òfÙ‚·(ˆ[åUn‡Fw7ɧ<œÂEÐȼé…FâÁXò¤ù#4B%Ê W1êÜxDãÏe=5gΛeÀÛb}˜3ó¿¬÷c§†GÕžÐɶTç\°Y OVúuUBGà6M´UÓá&¦e0E•íMô’KTÄ™&§3fCã°Ö2ˆÏ‰ ‰)é÷‚…â#›2Á7îåº.Ô'# ]v¤Q—ŠâU9‡K™î·‹6Q]œøñ–GAȳiKid¹Ê_®ñù(˜í|]U–|mäÁ“SÕå5N…jªS¦èêá݃ïG^¼¼ÿðÛû_ÞwpÕ9ñ=·Lì@–a`â‹צMuDn·÷®:?;Þ ubf‹}¦›$ý3˜Ó`FÖáÂÀDE裆§'ýŸl뺶­ëNgôáöè­í½Èk€ämÝ8…„»tF—*ÿngôNGäoíÝ·Â=×;ú;Ó³0ï(•S%š†¹CQ›8°gÄôI—…“±¯é-ðÞÖ3¹m׵νwÚ{§Â=ÿས¶÷N·÷ž¨4ÜW!µs¿8_XXŒÅ€……Xb‰¿Xl>d9zô(v(X“ÉÁZ2báÐÈØÊ§íÄV2‘tÂù 2^M.™ä¢)Â÷|=ùUˆüº–\ª¿žE7 ´kz oÂ*]0½ˆŒDCÕKYvnÇü¢Ø,P áï`Ò‡Å^DUÜʯséŒÑtp+šJ™j;¾!5*_J#š"Ö;'Õ,+ªŠC#Á‚x¨,n"ûò •Vš[ù„0žÜŽÐÆ|¡;$‰¶£ýä8#GbYSÁq`cyy9°Ù±z%e,—‹ä¢â7…nÒ×BŽ¡íäØï:[ý‚U/´çSÑ¡òt¨Ré}sMÚÌ·FR\þFùÝ:öü´U‘ÐýÓøÈ "ÊÓf nTLÁ”J?[óNéRÜ”-à%ÑŠð,ÄDÂà‹JÒ*O™ÁV T2Î%Ê*U‘Ò@ÅÞX¢îÓðò<<³F*¹˜ËÉœO)9®ö§a¡Y4"3Š÷вíÕÒV8m•=°Ê“f(mW'ŒU` ”¢ŠÿÔÍÐ… S<00œ•ÐX2Wü±Ê— .1„0OÏn:¸´xÚ,›ÑHÒ¬LÕIö6Ï)Îhß|¬‘)½:aήQ“>‡Ód§;Ÿæ»© Ó+JØS¢*àŠÀD¥f®;“õ»F%¢ÿ|myÿSªG¡‹%0€PƒA¡À¡‰Ú"IÐhNK>»©×&Íš´šM#Ùj?[ë3i”%Ìà#„C –GÜTP©ÓÍXŽW)õ¼Ý÷Ëï½?ðÒÙþÿ{¼·kÿ¹þ—Ö•ú±’±ù(Tø©Õ~µ£wÁùñD¹Û=ð׿ç¿ìˆMvשּׁ¨=T8XûñÆèùŽ-:z®F¢—»bÀ ÊÝ}W0„¶-ëÚ~}CôÓÎÞϺ¢Ÿƒm[fkÿbgïµöžÏ»ûn´më)\¦ÊÌ)8eQ ­ûýúM—:zoGbw6lG/êìùa%;š* ‚cϪʫ±+‘mÀϵΞÿ™F®Á?Ñ?´nÎ(?PÚÒÜ ¤>üŠFROT¾Z‡ÃHŠ»îÉp ]GNe 0fÎ{Úž¶yÂŽEÈ·Ã, 1Æà ª 2'é ‘3ɫ͋Že®d¼žŒésmÑ`wŽâðØpòfŠ“É}F’«óXÛòœÍ>²'DŽšd½À'íd4K,rª™OˆMFN#:9±·òYYKN7‘]r‰=jXsn‰|¿‡“ൠ^É P^Ž’a€d+ê'ÇvKD*"JeUæVœkÉá('ÐkýYë÷•(]ç×bŠì–èPIQܬM«æ[#q¤ªáC¶&rX"¡WÞª/O7!îkâzèVcÕ=£ ,IH¨ò›fyÒ2—1QtâÔ&˲8³gb]!h œà§W»bªaeÚ^-PèQ”\|ke,¤ÐÉúu£¥…ª- Ù¯ä‘(íÌ¥ÓfU’è?k„1žã®õ±F0ÒŒFÌjÓ£¹2ñ"+Ež¯PÓ ªz¬‘¸áŸ«F>®ð2$5˜J‹—kdIÂ(Cò>Š]£sxß yœô±Fð9·rÔ@#I;x1\©ÊNEá|¦J%"Q·,g²UÔ &ᜇËË£n&yøEJH ¨Á£%í´p¿Ñoô§×7\ª ŒùJú =%Œ?ݲ¤äS·*¸ªäŠØÕ„B‘;ŠQl勿/MµàÙM½|6d«ýl­Ï´Uy‹Ê $°>-?LrK¦­Ú&MuS§Ó‹¸¦Ã›vþfàà{;öý¢ßÂsâë•ww8Û÷â.½+Ï+—;¶.8?ž(ŽôÞˆl¿¹aû•®ØïŒŽ‰ÕÖ» mŸmè»ÕÖ;Ù½ãâ·vœÓÛ÷ø‚VqÑ^_ðC«û@Ùz½½g2² ñýIdë¥1$ølí_Ê„ûµ ±ËÑRIÖ½TÔs þÒ¾Dd®à·c—Qéî~ž[²¼=JDöI¤_Xdëµ®yŸ·‘ØŒFPÿ²cÛ…ÎhQf»Rd¥&T ¤S3äH¦ÿý•zôzô~<>C%&ÊZ±FN¶7ëÈ„ÉSxlþÓöT=9!aZ¤9€¥¤©ZEÞ9ÉÁf2Ô,~ó¡s9ÑBÎ4‘‰¹·¿Ï¦.Z$ç2†ÝCÁÚÆq-O‹Á‹}• ’èô2§‡æ¨,'¯H^r“êÈé9YOFëÉD+Éèü«lV4’a›œ\OÆ›ÈIŒ›d¨ ‡H™ËQ‹s9Bࣙ(?–=î%oÀ!;È`” Æz@RÄê°g n\‚äuP¹¦ŒÚFDzÖ[ÃD)-bÂÇᚸz¨Ï»FšþiËŸ²« »zíÛ%?Xùô¥úµz8䶺c„^ hÎ×…— ë©¢!ÁdÁÃ-–¨ò´Y‘Fv€7V`Ê,ãÇX³ê·ÁÒBQr H,‰ AY)-kÎUÜ¢‚ˆåΘ«X”~ä+F²'ÍÐÑN.*YyZÚªK¾)î¨` !ëg4¢1UåÙÊ×7®|¼§ÿK#ˆ0$Ú\5òë`©Jš¨¡ehDshiQÊô'³r“cÖL›¾[z¥ßÉhg£´çºf4’²Szm™*º)ÅBˆ\ø/²CEÚÄxá·ò¿›•S:¿#i{uʬ5IcuÒ¨™j¬JUi;t¿± 3]ôEdáùñDùõeÛÄyÇñGŠdÉ’¥ÓéÑéÑîtç“_’À J^œÄy!o˜Äöùƒ!Ží$”ÛIlØXWµ[ǤҒ„Le£! ð×´u›ÖQþ©4V©Ú´I›ªMb$!@Øû=†iU¥LŠ– Íztº8?ÿ^žçî÷ýü¦€%Ú“ã¡ø—ÁèL{röбÏövNv$o·ÆîÕNªR[Ì˪ÄÏKLŽXi¯¬€Rd|δ·bÉç¼Úº¯jÆP_nÉ€IV®Dl™EVæÌy™‰XAäykÞMf5‘€ŸáÊͦ¤õÝO=E”y|•O¼˜,}ÅLd‘å$ÌÂd¬!ÓÈSp¨×-kåk¦‘êb 3QàÝÀ€LNn/Èø^ÐÈ’§| hÄç¸×ä´Ñ*!î ‘1´)KÞÚeÍA‘Iß­Ù%;ÌFW`¹ƒo6ºVôÚ ÝêŠy8~Øj_å]WÑx]Á} æ]%­WÐMÖËï{ËžyJ3-•³ž²¯ã0Ʊà)ÏžTìoõpá+yÔ¿bå(É$L½…gøÜϨeáj4²^þ×ëù\Ѫ¼eŸ#Óì¼£9—ྥbIsü¹®±”°òfåæM—'~qüįŽþßÓÈG}oÿæø;¿M¾ËB›ƒ.Ëdéf¤÷¥ãÇ×ÖÝ`ì/¡Øl¤wî@׳ȑ/ôÈ~»m´Æ=×yìû¿Qè´³,¦C‹=SeÉñ¼ü/ÂÑéŽ$ðÃ\{òf¸{~Û]Í?Î\ k<’üuÓ~3¬DŒó©»s2›G'Ú»o„c°¦:º'CÑ›áØd¨Wà‰Æ²,¿WR?NMEâ“ûnô>Ì»F  ‘¹Pb>|¤Ú–/ÀæŒg§g2éÌjŸçL’^^›kŸ]Íö7ÅÊc“ßFµoTC|èœo=UuX£×sMôzц=Ù¥¡K.É€ÈH߉³"½"2-5jW+vl5‚ް\.'*p@0Ûu£±þ°YħbNù\NÍg‰•7=ôº ¨‡>”…@9´(ÂAP&»^þ7ú¹l13èøöP¸êúèØ[Ÿ¼l–øï×Ç}߃*>N¾åÚ^ @ ££Ý„¯úA‚»ÇCñ‰¶¨0ÀíP÷x0:Ù‘|Y4r;Ÿi‹^ïìùÛþo.DR?Ù¥2PXó×Îcn[¥‘l²Z %³QÀ÷»½¯Ý‹$o´ž8˜¸ŠÞjl­æÿ^¨g*Ÿ ÆþØÜI0#lÇÜåÆÐ­¶èó5ìz¾n‡bÓ‘î;ád½E…‡Ù$° GåT¤ö @e£÷a:ÜæÚ{'B]·Â±[¡žïWbÚI~õÚWi$^ùêýs;°¹rù›ÍPmd:¯£1º £וFFÀg %ó4ê£7ð%|sÁÍD«UA‚f8¡¡³:Óœof9K©ŠFèÍ;À• ð¡W)#_3Øü[Å q& / F:qÞ"ônéè§~ãIún1êüEjI¾m«Ý°Eß©£ÙŽ5Q›pi¿$¡«‰âÐ0Ðìì^€oÈ—0Z €R²²žÈ‚DOHÖJ#½h(ëátK€IN§(À¿NeÿìOåt‚"€£¨}ð:úQñÀn“"ŠF&—…¡’8QêœäÃhè(Jf¹(ñóˆIŒ!ôàj|:Á(óv¬ØyüOâË56ŠëŠãWB²´ÒH£««««ÝÑÎŽÖv0Äk¶Yl¯½Þ]ÛØ†Ý™]Û`°½†Gñ+±Á¥UJPhDEÊÃy 5ÁjšªBmUª6m>µŠš¨•ªVÔF^y)Øl¯gûŸñ¡‘?àb­¯ÖwÎ=gî½çÿ;Œ× tõw–žFò™†¹Ló‡âO-·(-*2Øji¢¡š hF1ê!S JË…ÒÍ 7)B\/æ÷-Èx‘(Zë§›[ó±5–°„ÆèWh„&¥Ÿ ¿p!ñË”⑜uÓõóè|;өƼžMWçì¸ šÄÕÜ£Êi)£Ý–˜…,¦ëÝ žª÷éͧc½%&ކŸ2T¤€Ð¹g v|.…7Y³`W}fÇo:‘?DÃAî[A=¬‚˜–kTEL<0ÎT‡Þ„ÏÕÔ ­x/ºúfªa&™x?Z‡W )Þ º´(ê"›XUþqÓMnzý­Ôº›©F7ÓàfZŠ™.½S`F-ÂÁ1œ’ÀtªeÞYw+YßÒöq[¢Û’HE—b°˜ôQ¥L£c›ïÅ*A8ù®–k›â¿ŠTe -$¨Á|á_n^kå»ÚRu·:šÀ`Wnol›!Õð½]Yö·øú™tS¾£i>û]Cm«äh;TSHÍo’4+Ñœ–¼Ë!$‚t âD‚HÉ>,ÿK}ngí艪•¸o›k£ñösã/ü|üÀ#lj¯iç÷üz÷ltƒ`@¤ü'íYHsFîŠà•™\zD(»ÐóÌôÎÑ‹Ù]ú?Ý>zp]Ü@Ï ý“Íï÷Ç–Ÿ12Ïœˆ¥«Ñ PõtSújvøRÿÀ…þAh÷ÇÙ¡O³‹/Ñ;xyûȵcïöë(Ìú[í[ñÔåÂ{€®g½™Wzþ¹mpÛÊŠ”œÑΡ ½Ãú‡/ïZr*Ë{‰lÇŽ À@#ÇZ¡@ ØoóNÞý_ÁÏÂBŸ¹Ü< Ü\nâè1ЋÅ¨x乨§¿g v² ÄKUßJ‘ÓžóÉô=»ûýé }²ÖâJ'äD9µU‰š¨Nt“NÞΣ)?UAÆÚ¶ ï‘©ž^w*K¾7jeMו€,èy%K‡ÈË‘)ÄÖDδ’ÉvrÒá¯l!oV™LÒï*D›zd4rªÆiDUØ”7»y%ê¥ð„²Ø$/ Ü£(FÈÑ‘¯H# ŽÃÞ«W Þ&FÉ…Á±Q–j”RˆB-È÷‡Èë{ |“?µE†–Cû`1ÍD°>Döö‘×v“ã£äƒäõÝ‹®‹ Gžófz…u÷##äùÈ 4]Âåf˘±›ç °™Ú¥.é°ùtóGbÉ ¦¨EA®•sYdˆb¦Yœ{$E7ŒKïo‰ê}"ÒR*¡æ,רþU+ÝTûbþçœÖ#U&õ à‡.%åš!”~®a,5ž hùLr6ºhȧëò™ÆéTlÁÏ¥+ÝŽf¦™‚—qU 0ŸIMMÍ”ˆ›vbÖ‰ä zéX.wºy;¶¥Ä¯  •IEB•~I¾cC>‡8æÓáÿx3k>ßet™ Ajà~1îS4„ÀXld ¿n” k&nÙÍŽ58³¸_:Õ°A¦Îù±µ8ßÑ’ÏÔÌÙáv|åÄ,Š+f ¿Ÿ&÷®soÐr!Йp¾£þ‹M5ùLË_cõ!©R¥hf¢2µ Â´\§­sL½Þ 5@-êýGõsi°þù§hõœÓôÅÆêٮ؂»Ñ–hµü>F‘¦âí}Ì/Z-m³%" á[°bÀTT„@§¦˜ê¾ Œ1¬Ë§£H‰ $…Ô ÒD²ËÿRŸÛ;z±5.…‚CK¯¶JÏ}kÿÏöîä8ñ5í{HÞéùŽ>¿Ê€îPù}ë7\ë€ò~²ýY¨ðÅìì ȤoÉÕv1*|‘¾Ö7p}ç³õ ¼\×â *Îgv\Ý>®+ŠŸRæ×ûÆÏ¶n5…WIÕ&.õ\ybørß®ëýC{îÃÕ— aÇÈ•£ÿè*׸B}Rjß­i¹Ñ;öIïè¿zGÿ²mèÝ®§Î´wnhûNUCYEP÷𦉰U|9;öÙŽ±Ï{ÿ4R £¡kÙÁ»42ÕÖ…²Qõµ‰‰ùÙÙûâºîý±Ç!÷¾õìåƒß“šÀ}>òb» §Óžðz¨4M|Ù&»È¾6 ‚ ¨ô™è²7žešÁ¤?»†Lvûž ãú£*’±9…É_aéNò£2ÙO^hW®«Ï2ªC@uKÓ’!rùv‘©Nrf#9ÛN~¼Åc“)2é“ £nr*MΦ|݇G#“dªË£ ÑD'7U RF¹RY¶ìHA÷ÁE “cÏ>0Üe‰ÝÙí?ç à ,ñÚ^rxH©\N!ÁBŠòß¡Qòâ.2Ôå{:úÛY8Ä h—.¤´(§ŒmŽ“Ã÷<Zt]/à1òÆø½˜1ÿ•ek3: ¡ë&£ÇV•Cæfl¨a­ë4.uUŸ±OT–VŸjˆ ¤V•¦À9º¡>F=í“€[M‡vjF¹0%Kå¶X¾³y1ÿùtÓ‡M kuÕPUÜP?¼4è ¶Ò«QRùix­›ÞýšNB¬ësÉÚ™t|Á‰,ØUn¦…r“:g àºÅì*‘w즜]?ŸŠ¸˜i'€%·SÝŦ0<#RhgX*Ë¥š\;ŽÉnGĵ€‡ùdô¥†`ÌbÆriy\$„*x±n¢›ó15 êŠPÏ'êî85®SûûhXÓ¶dpªHð”®\Uz'™sy'œÏD¦Ó͹dØu¢èàT$Ź÷¶G?¸µX¿m7Þ¶×ÌØu³d:òïTü—ëW¯Ö”eBñÒ~ˆixÀ›Ï9èWhN©ÒÛƒj-`qmõ=®ûÞ¬þ/ñeEzÇñ!000<< à 3Ìì²›WíZã[“lö%»Ñ¨ÙÌîN’æe_’xVÍ‹‰ÆxmõŽV«–Êqµ½ëµ4sJ¹£Ð+íÕ”ÒÂQŽr\¥”íUŒQO£gÄl’Ýí÷Ù\¥ÿäÀÓ4á!Ì3Ïó|Ïo~ßÏo5âœo dã¾éH°Ý…'•RbºÔbFéDÅó"ºH§ªÊÀ' Öà!š[uà3ÉuiðnÔŸ±!ÃDQQa“ û¬æ_î¼ÍÇü¹è–°ƒ‚ÜXW ¨ã}Ï¿=òlj§§‘ß½pèøÏ¿qÀ-R”žUºöfjàVz€þIzãfÏÜY)™Ú5|»³÷N÷ Œør¢wlG«[$è8NnüÕÞ…¢’Ò5šv½kd|K ÈD4åÞðÇ ‘îÉdïôÎý× Lõ4S]C·{µ”•é„8µÃU‘Øäy6%Ys"<„Q1¥,! Š:LÙM¥ÚnôŒÜL-{ 4r5Ý{„ÖÕy×îB´À8yüD¾ óósÿ‹"¹\vñ÷ñ#•Hâ  ªñ¿êåVæÅoÄ 4ÒÊàY¹êÙ$gâŒ(ÆQ§p$ðj1ES$(ŽzKH¦"šÇÊ¿´«^òhcªîD#w¾ýˬ;†EmîgfåiîÈ6%äÔ"ˆJG‰H·©D7r/µqç:¸±îM¼$³Œw°ñz„;³eåhP±¹×ãl3ßm”e^“u¸ßð5îGNH“ìc×OJ#ìÅ!î•aÀ@a¶A$'ûWâ^ä^Ø%ôµÊ¦Ž„/©i¨©éEƒ¡"ÍÔ‚S#óU®ÀHõ9ä€j¾€Fö s?)ÐÔi<9¼êƒâ¦27ØÀ™øÃþ…h c×ÎF½Ù姘é-+x¸Â€ÍºC,“i°¡¨²ªMXYdöT,*¢ÃÔ©Êk4âÔ®n©Éw6>hZ·4€ýåŽr‘Ç熙7Øû'Ó¯âtcýý¦@>^÷tóÏF«Úab>^•ïplô¬T,j"àmÅæ‚µ5o³Qï#,aÕÍÙ¾«.åNhn g¤;¨WÖHä‘U—†2–o&V=c…æbÕù¶ú÷õí.‡Â‹€!è-UÜø0ˆ¤pâUr‰‹J TÍY›ó;¿}†$âhÊ$T<¢2+_­ôÌǃXtÞøçÀ9±êùæ0oŠzÜ&xôëÅÆ½¦ðg±êO#Þ|kÝÝHb2m…ßÜ\YãÒ¾ÈME—Dœ& *%ªlRu QÀ~Èv@ O‰í4Þóy3ñúY»6ÛìÏ5mþpKU­*€‚qX¦¬ šìB“Á²Pê©Dd‘¢RkD”I‘"lWèØ&OÞaŸYfåaH€È(Hƒ@È„Øg5ÿrçm.îgžª,‡!9qšñ|ƒ}aøÅlj§¿9ööÈÑwF¾÷«¡×#4©±Z3¯wNu N%ûñÿJ×¾ËÉ>`É®ewÛ¥@‚qª÷jbÏíÃïØ©õ’Dª[’‹ -’jÈ¾ŠŠ‹­»{×md¼úJ`û¿’ýWR{A#w»'{†¾€F>íÞ?™· ÜêÞëYOef/C5¦j1‘"5ˆT¨$øÐñÝÊ<ú( `*­“u‡,¿×¼ërjàÊòÇáfzð*Ž#±gºk@ëF×Ðí{@_Œ‘Mtt.ÌÍ=†lváñõÜ\æs Éd@,vÜfžBdÞ-r¯uŒx‘FZ<+W°¹316'\þÌâä6[h¼‰;›“5¬[MÍDÃ(î4Öƒ̉’d7Z ‚7âO¼î/;¹‰ss(pgÛ¹ÑNn¸–÷ «aýJ·Š •1YÁ0 O4qc ²î|’;$k\9±YÄ΂I,n¬SØíÓ©`ȰKµ¨'Â|,ñãE÷üR42Ìý°@ ˜êôpFŠ»mÓí N—‰ KŠHœ*AâUê@Õ š0˜²SB«(IªÂàU©àPÄvs£ßæ^î/lfh饇þ -ØÀ~†CGž¨¨2i0HÆÞöÀªÉ7ûD} ÑÐrWõl´ .™onø¨Îk²“ð¦ù°Eh¢éd Á6§(”hÕFT‰C!ã*ç­ís–?Ý7)rQ†[Ø4p.ítešÞ\<ð»Õ>h"hšBÿ FJt· EhÁgA(¦*;tÉÐEh=^^öI= qk¾9p/²ñ¾Å¨æ¾¸XWqk¥º\" ¢ÂE£šYB£Œ”1§ª«ëiQºØøsmí& œ&²1oû2±$@ä`§ ±ÏjþåÎÛ…XÍB<ø·W’xÐT ¥kÿtäÄŠãÄSŽ ýf䨝GŽâ¢±l-¾:¤þ.&öþt^Jö^KÜL-éæË=®`'=CWÓ½“©¾éžÿHôÚì#D†Å ™~ß·õÑÎo¾µ5VWâô)Úï#7Òƒ§z'»ú§’½ ©kKÓÈtš‰Lï›L8T *š2š ¹PŽP”Šª“É«i«ËÝVá9¼)ô­êð¥ÄÀ­$âÓ÷ 0Õ¥ÔÞ{éÐÈõî¡KýÅÌÊÑÙÛw€4r¹ìÂÂ|.—{Œ"¯q`”—àtÄ#qc n"ΰáÜ"-<;ùE+7ÑÆKp£6÷S‹ÍŒŸ¸9nqç;¸S1057s:]aÍ`Ø-PÞ”¿Á¶¸·’̎ϵ=ñºÐ2cü]g Î>ÖZØF;·ßG+¥JÖ4b¥’©éÜac’sR+¼¡­œie 7a±ý%h´Â,ùöË<¶‰ì àOBBŠɲFÖh¬±ìXŽs!$!‰ï#ŽsÙžÃIÈå3 ¡±“€Ô•*ËVKlKYHXVÕnÿ Ýª«=ø‡¶[õTµR»l96H€ÍA‚“ØÓïY«j¥*Û¢%*Õz½L<ßû¾7Ïï÷{è•Î ñè½h(†ÎƒQD_ØFN'ð³g3ý¡8€}bC±{°O˜È¡è\‰Ò!&áHºBL(ÁÏAÌI2»¬@bÙÝbCÇ£èL& ΉÿÎF2×a¢xV—KÌÅLÝ®šjX-Ð ˆœÚø3&&š1nhÃ/õ%!%Y¡˱ÀŸR´ç‹“TI-úAÙ¶¿Ú iøXè3ÏèÖ‹¿ÂÎ4ËØÝJ: ¡Hlt" _!ú}•^`õÀÙYl#Õ .}ÚmÁ-yæÖÏ8Í=jEwŽÂ«{UÒµ¬SIÞ©Xvj’n}Êmx+8Ã2[™fu#;ó¨s;TKÙª–’µlÆQ–äL`#«xJkSœnÙU™tCÚ5·kô£åÛ 1ÈW>‘•/¥d’­Yä)-jSÓŸÖÖøª/]¶ßYµmùrwžn6ª©Ž\eP­º¢Ù±ÄèÒœ9í6>g i®f‘Õ®²šï©m*Y‹’jΑtäÐ{UÊ׋ ¶Ôef¸Ñ ÉÌ»ô«œYp[’Œyš±~l´½V\b—c•=€s¥Rç¢NIí,|`7ÎsÕóðj88ÛdΙ¦š4å€C6Ü0hŽ—¹Tà³"lnp"½“¥R™E!ïQç]7•Üj° ¼CàmÏ\š9N9/0&( r (( ˜/‡b_Vü^·I^ K¼T'¦r E>%·ÿ»›®ß²]Oyoà軃õ¿Úe¬%ñŽ"(ògÎæÏüáI_ä‰/ ¿í a”¯7ÉFÆ1Ìbx ²ò†¾ìêûuëÞ.e ŽpÒðäþ±¥gÁßûȻѾ÷”Ùq§=<HŒ²;#ÁF|hëRÞž€N0þÈ?_åTKÉB1±ü™Ó4Y©Rµ—ª°ü¨Šû9ã½Ñ´÷VGè®?>ˆOúǃ‰ÅîExܳo£çá±/‚mÄzê Lø£“ÞØn…‚Ä'#B©ÈI¯­ý«„¤3Ÿ¯î`IÓp®%)`ЏœF£^tõk6réåÙÈ(lF›Ð÷-è°4d„¤½ œuáð W±hE‹Å˜ãã’¾Ù†-b¬µ ‹/>..„Á@iF£­h°*»{G‘½’Þ¥"d¼S™˜P‘xÄ…âVt©È%kBc<žËü¦ÙÈ›-ØCFX.¶fE)‘A¢$‰Nfˆ?’ÀL£øa:õ ô_§ g®ç±`9›@§â[h<¸\•bB,“‚%R2:— €0WEEE´f—ÈëD±ôJHàd†ûÑÉzãÎç~t*„Îö­;. ™Ã Ã½™z·°š¼ÍËÁý¯éJΈwZˆ`Lo¼Ì³¶5Ö˜N²»gyÍj£e™±,0¶ »öúÒ¡Ò‚ã; Nî,ê;z-qøýW¯'Ž|¼vhó5ã?m‰Áû:ñÃçzâ2 M¢”Ê:J5ý÷©`l²}ß½®Ä¸'4ˆo–ÜóG&<¡‡ž÷=¡ñ[+xHÜÆ?÷…áΔ'<ïÏüƒýzmâ¼þI•,Y:>>ÝéNv¢”GÓÆ›$$q^ !‰/çk"œøÓHìØ±ãЊvS›Ò* @0ï“G[©š[Û[Ŧ­´{¨Ú$´v´Mi¬d0 %‰íý¿³4ia´b²"ýuúrwßë¾ó÷ÿÓ ú3w`ĵý¢³eÜérx&]-#¶m@©q§oÎö¾Ï5®LBûÏù®¹ZnÕ{nºƒ£ÿ¸;ô±Ý3ì€F|ŸÖ5ÞtÏ©šÿ{¸@ÍcšI@P_Ù=w¶<·$S$Çbȹ#ÃWc33 ‘ÿ¤H4AZž™ùÓþH8 ÉàŒD} jY¸ÇŠ,X#§‘ؾFÅ¥Œ`üDÚ¼ë=y(¬¢4 ¢3:i¦ö象^E*PÄŒNÁy8£&½ñ_Ó¯¢7jQo-êƒr9íËšEDáuaŒ„ãXVÏ0:‚£ÝóKx–•6KàJ–`g¨¢‰hÞ<‹¤ˆ"³ªÁq¿•çõ  |nMè ‘ýAª@Å>?õÆ4r@»z0xÿÑ­Q$Ònð4˜ælÊb­˜­5è%7zÍC/ ÐÆ“æiÓª?°Çÿ~ÚorT­è•FÎ 9^bIùBñŽ™jäNuδœÐHê·ý‡Œ¸jº-çc1Eá»U-º£äÅTÓ?å츚vcײ¥¢€u"»~2€ + þ Ø¯)œ©Î¡™E.ºe¬KùDǼˆhµiJ)øF-þ¤$Ou"¼R,É{zùÙPÇ9M Px'Ô …ómgÚ;RÏŒ‡ÖÈ/Ûwž‡hëìõíXÄ‹ô×ÂñUK²FÝÛ¯;ý£ ¾/ë·~áöÕ7Û½©ÊÂ`!ÂõÍÁQ'ÈÄä¸Öú³½é†½õrí– Šó@Aùs =+ÖnÊ|º,#})Ãæ`üךçÇ\¾QGóضöa‡çKÇœãu†ü –Øš†MÀ›É-/üÍå¿lõ¾]eß“[r4¿üÝg—íž[¡¿Ø¶¥ê9\µo¶m…q‚²@#7œ¾¡Æ`hU6PÄ(J/þöâÅx,‰éé©YÜ/Çb—~ÿ>fYƒ(±ˆë—S€@z­¨ÿ‘kÄŒÞPÑ13ëXÆHì"½°‚3.¡‰K #z¡l!ê¬D½›Ð©*tr#ê­£$Aî± *eÒà²v=EH_%êQÐñJ4 3Çì¢ÄJ˜1`œÁá'9œÎa`IšgfIlÝu[rÑÊQz¬G'­4zêÐéÚ$EIDª(’ÐÈi¦CË;6œè(6« ¨(šF ›ƒ öi&™+û'ù™´Ñc‚‡´£«•^ knÙëE¼”:GÛБ6t¸MS‡uiÅd]?êòÑœì~Ðî‚hƦk”9IhaÂî^¹,Z]³äOUgE`³…rÊ·ý‡Œ¸ZxÓœÿ/KÑXEî¤9?VWó¾–ׯ-¥•ý@ÀA$¢˜ÁGV2¼œ™>!—Æk ïš×Ĕ¨Rz[6Å”ì”OäqÌ‹ˆYŠfä¼{jÑͪ’|#NÇ,!¼‘ˆ¯û_¦ =ðÊ»í;Ï„^üª}×<ÒȹPç;ÚñBhç[/t¬I_$^d¹UDøØ\ƒ$n§Ù™bÀÙšª, øÌåŠh‰Ø;bóüÎâPÓiö2,‰q¬˜âÂ.H#‡Ïʶa·ÌÞtͶuÂøÄ5§F&>ÐLvØãh‚Z—ìÍ{ 6¬–Œ°Ö"Ïeb¼³ÎÅ™9¼ãîPªžÃhƒw¤Á såøÜé½nk†aïÊ5  <òá¥bѨ†Žè,Eb±Øì¸:Ð×O0 ‰@¿5õ)¨WA§6iQÐéG§‘7­”7½•O„U¦¹ˆÍÎ`Œ„%LNKc@ à,»”èsP؆ŽÛPĆúkQ™VïŠÔ¢HÕœí÷ÛQDAýô6ÐË[µèäfŽçx3«ËÀØ”É4W¢Ÿ8ÐQêÛŒ"u]Ðø Œú*Pd#:½½^AÍ3Kèú=­R¦˜µŒúa]jÙ†lДÀ‹'²n™æôîV´?p"Üö Pø©Xš.j8ª5Bu¡)¥;!„p¾µGÚùn+”%³Ьò5B;õQ¼æE‡B¸t5'ðšFôïÄ- ‘õ3rî׊i~idª:4rW)ýMþªKk‡7Ü–Ë®W f¯¶eHð‹äoôx X¸6 †QÖÞ–×ÅkJ€awÍùÑêõ)ŸÈã˜UЦåœiJ÷’ÀbCfxQÄÙëj‚l~>ØGÐȹ`¤õ³¡y£‘ Ûwý¼@ÒŽ:óâ⬕/Bj[Äâ÷ë=_¹ZGìžQ§g¤ÁwÕéu¤ˆ".Š+ 68[†ìžNÿ{'f,æ%H¬„ç!0rØÙÒˆH§Àâ5,ùYUÝ[Ó¸;pÝå­oræÔˆ½åSg ¤ø1—w¢ÁÅåÛ_–Mx²Däa7a0“Îq˜eê—.Ÿ´Söœž« ž1—Ê_8½vï°Ëw¬¸³&,>ÏLMÅè_4ûIü‹wíÙ+ÂWG$è¥2Ô/£^ˆõYh|„Yõ¸ŒT4hAÔS‹Û˜Ý5úç³¹•É€‡ËI,/qI4 ‚€Y=#§£@±þ`=ŠØÑ›vê~¨n³}Ð x° õ©èH%ê3£Ý ¼½̧ñðŒ®Ñ3ÉbšŒLÃêÞ<´£uËèD :aE‡-¨ßšÔP¤O£<ÞGG²ï£U[EêIù¢4Ï, vÇ·9=Á -Å?@#ûÁmT NÔ°‘„G^¨¢ÃpÕ¯!nn£ç»üÔ‡Ú’uk>I”g5Òý)BåÇ:’}~Ô`³Òá%„ßìS¼~¼â™¸RUrcÊzÐȽj H^Ê·ý‡Œ¸šS‹'Íìé|&Ö8F!Cè²ü¤^·ˆXa¢‹±`àX“Dî)…q%gF^sO]Sá;·`ºÚ4S=oôõ8RQ¥ðž²^¡)KÑO×­±vr,ŠMϘñâ®_oßõvðU@ȹPç¹³_÷±MœwÀ)R¤H–NÝé,¿( Á¡ £¼„„¼’ ò‚cŸ Žíø%¤!Äö›Ķ®ä… Z ¼w…Së4­jµ®@Ó¦Nýoë´iR¥²’2ZV6–Ûû= «´t¡Šd!ÅúɺÜéîžçñ“çûyT™¤óÕˆj'ªH×{»{Ý¥Õz*B× y&{Ç=a¦‘feÌfñ*i׸bħ”KZ‹ —!'åòä³£‘[×NÉ•cµ59†ù–ÍKF"‰` ’Q5<†Ñ6€‹Ä+$¬U`­)è ½*)WNYB¶ŠE,Ö<+i­š‘×MÙÖÂ÷¿¬uÏæ‹ÀîJ(uÂ{?ˆv_íìy7Ö}9Ö{eWwÚ1ÿºí~{×¾_îÙÿë]=¿êì=Ôd»Q´âî5ãžð¸—Åß„'4ܼåMOªá;æW>y‚ÃM¡[žàí–Î?xvŒ{BþÈX 2äj‡óÃȧ͑ë .Gp™É4ä Þó?ó*c^å¯s·ÿ¶'ÚùÒþ›7ݼºÉ£å€eâÿÞÕ:Ù²÷cgÛΕ%’D Æ[—¤kîzƒ7ýL# Dh*häŽ'ôIclÃ$ì²mV#IöI<I"13{®6nuRÂCÁŽ õ{Ð3 â‹`†- ¬°GÜ‚]è‚ ÛŠ¨_f)w£uYí…‚5GZI©Ž)6ò<¥ª‡(”egžv¢·lè€dn@d_23ÞÀã ºèÊ<½æµZ´·*ëÅ2Þ²BWb2.Õ¶•3j´DcäE*éˆ gèêR52K‘Aµï³‰ÛÒ¦‘s³CgC>B3ad4’P°|ƒG_Óã˜j Á‰ÿg€>E%ïTdl7³ Süþ‚„‰„Ùd ¢ÈÙ$ªç)°Ö7j„ÕùâÆ¢Œ–z¶£ùБ{û‰È·ÔH_‰fb,Ñxë€BË ì{h|M>h䪑[åTC)h$e/Iû²?ßt°•|ÙPñIU¥†fÁä2ñ‚cQU %¢ˆ 'Ë´ÂȦš„µìŸ¶ŠÖª)Ëú¤u}Ê^ ]ž´§½‹õ¬TR®ž±Ý—W',…Ór]‰Q„ýUG˜¾Þ¹¼óåk{^y§³ëýΞb½ïw>3 ¹Ûÿv¬ë{z¯G»ÁTo„÷²,`ÇHZ—­œhR@#ŸzÚ>÷uÜö+Ã>%müu·ßñG<íÌžà¨'ôйլ yۡƼÁ¿ûÂwÜmwüá?;ü°¶‚Fòr¶MxÃ7|¡Ñ@dÂ3÷óþð?Ü;Füʈ¿ãò&†Jå¹ú»è0¼Ú¹Öà––õ9KÒ5÷¼!¦¿j ‚ÐX§ØåJT„Œq9ÓÓ™™é'Qkö“L$ì6;ÐnÁz ú± Bð9Ñ'Š,ìÏ…JUˆø³ftÉ‹ú›Ðq7Úg'®âÜB£NOðæ £ ­Æ<á Á,š4D—AtÊŒ~ Ji(™JËÆ¨8Ĩäy5Ç(Øh^%ç’D©l™¬©˜ôÈ~#9RI3ÒR#ÍV=‡KÈa=0⪣÷TG°EäXeäùñ\ÐÇ¡%ý¥d]±ÀÉå¼,l+/šv÷§ñ’nªÈd§—ìh&ë-òµ|Qb ÒUɉx*ì¼CdX•¤£åŒœá8‰åHKV9–eÉ‹(E éE6ÇŒ4â"Û¡#O¼J­ˆXf>/"ßk5ÐÈãðz;×42Y’ê×åL•å=(ʾQõi¦f`ùÏõZâg5iÍÏý{ñŠ ¾ X^€aµšˆü2æt|§Ï”i†ìIª‘ìáôe¬ kÄ–³êL[4ò±¯kØ×93À@å„·ýü†wŽ7m¼èëüÃ[[y6}Ô¢BKÇqß–ÍåæúÜâò×3{jÖbÆKžöß´užoé:×´S£€ÿE#aÿd(ãX=‚U¥µxn›w¬®»f:ì ³#‚¹msß6;½þËZ' pEoéÐ6%gV&.ÉP(0Œšc‰B…ÅÈEáZuÃÃú¶;VÇheý-Ë ëà‡Û¦$ÿÂìøD¿&–áDNH䙿T7Ü´y3\"HσkWmž+åu—KkŽVìÒäïL˽T´r£ZÝaà¾! ‘ñÏ;[‘¢Rã-Œe˜%êØ'~ÿd`ŠRäG™ „ÿü8È2,(B5’¢$ý&2¤# ¤ßøT#ý³ÖUO ›q{EŒB¾HàÃÅ㽑ey‘æq\–2úÒUJv™¢ö­%ûW“A ¬¡4:d ûJÈ¥dhöºü`>,$C0Iy¿˜®":ÒWy~ü§Fð  r{žÀ1¬ÀЭÅ0`»ÃE Ñë¡ ÙÕB¶¹Éî&²ÝI¶9ÉÞ…év‰ÙËyè›áXI Òx}Ÿ´ºBæ1<ÕÈüÆMO¤9›Én8Ç=ízvQ‡Pmµ+)†å9ŽÑÅÅÁ!aŠ<*Ëx¢Âé5:‘æ×§ ™ACN°|E@·â±6çQ¶8˜í7ä„/ŽÄuáê"_ð˘Ã1©Ïx¢ÕøCß%øö³ü¬‘Qp~§…¯&Z×uÁÓ>Òöö9_ÕÈ4IRA'2àÄ÷ë\=u®"CoUýˆcÓ™·º)E|íØz6/HRÊü«4y˜kسBÀŒ¹ØÚ=Ýy‘äR3ÝAhäLKgQ¼a¡ˆ„?WÛ¡4ñ ‹ö¦%2yª‘ZZ42f²Y]£6×ïVU°àyAɉj†‘s¨ŠˆÙW±miê=“s¼Æ~ÓâÀYk!VÅ *I¡^™M6ØBŒi¢Ù霉FÞóÞ&Š¢ ~¤È, ̦ʼnSúìS$´ÞRŠÌ®ЧûËRkS—¥=ѦMiÓ‚ºô pR® èR'K“”$?ļÒê3‚†¬ˆü2æt|«ÓàÇ2¥Õõéßë2ÿQšŸ¬äЇž_*ª~½®ó¼7¤oûðô)B1ÐÒy¹íí“îæÔ\ ï [—µrdýVxãrK×Hk7¬rnCO}öªE’Šçøä¸„Óz0Nñv|ÚÒý‘w 81cœmí¡È”’¥ =WÁ°#Æ5÷Ì.Hí}v¬Ö)Œ"VZø©ñ–É~Ûæ­u^)©‚D8ŽÃSˆ$µ¨€Ó@)Vt1óºÓ þø‹úïÞh¹QSÿ¥ÍK¸av¼(ÿ×&ç絎¯­M·¬£ÐN­‡çFâ¢xf'âQ«Ya1'q"ø‰Þ r–SJŒ$Hh*E4+7Í_ü¹µuÜâ@Ø"[Päÿ ‘ÒWAGðxü@-Báþ› žiäÁ7÷q ¸Q"Ç ¹±”ƒ¥¤}ßêûºÙÔÈ19 'žLÙßj|·ãX1Zú™X &¾\Ò«£68ª'CpB9X@ŠÉÑ r¸‚:M˜é×ÏZ=(æH½Rhä0,TOEäùñ\ †J…"'h¤â•Xò˵3Ô5€‡ìn&ï5=mt{ÀGözÉ–Ù<+gT*•¬NKÞuÒÁ{›É¾&œ"Øô,OŸÕÈ6Ùã%;À lÔ6Ó­‡†‹l·3¦ž¡o/;úz’_Ot˜"ØÿñÇ9²Ì€.+¨Ï„4ôˆæ‘Nó,)£ƒå9ÁŠÜ ÖJÿ¡,}R§‰xÁ/cNÇ?Ù¯Ø&î;à )R$KÖé¯ÓéNgÙŽ¡"[Fy8OBã»3q?i‰çر mY !¥eZxÖð !I¥i›ÖÂ(OM›º¢ncë¦iêÚ’%<â¤<ŠXQž¶÷ûÛcU‘ff!~:îîÿ»ãüÿ~^-¢dK^³¨PU› ©Ÿ—L6fúüÛ Ö/;Á$gCO ÀƯ·ìúE`Çæ•LÓXůÌ[6øþ¥—ßü¹¼íLËv¸ì`ëk¦%EdN&ƒfÞyeW‚[Úá\˜ôÝPÒó?j$1"¯y–ƒÏã½ù޽4’À¨-e¹nóŒ;ý‰p')ïGlžÍ›¬Ìâ™ü,íªE9Mßz±KWyz¥é¢ãj½÷úK¡û[!³48ä[ÎÀðã55f“ÿjóܱûFínϘÝÇó8Q(5<˲ Oq §$˲ŠbÔ˜UÁ>ÏÃv‘‚Ê¥™Ý”óâ_üÐg¢ $lóŽ;|OûùØôÈ1Ї'ggRäQÌÎÎüù£?qDl Ü ·> €=ô踉ä2`À—É¥j¯H²þDÚiàÌùÔbL±éœ>Ÿ_¨Å«T¨óTì¦Å>82n¡>ˆàuhÐHÚÐ „²i.uÔ—èJO &:)‘:¶6õüøZÁŸXƒŽ×dÁÛMèKF~˜|ôƒC¶’íþÔ 9l¤ï  ./:@?ò¡€EÁà…4GcŒ^®GÛÐ9$óVµ˜á¥‡ð| êÜDFˆmà:qÕ$M‘ ꆳ<ªÊ|«@#j6ý…³ñ¥uö_‰Ëaû i$"TÌ Ë'ÅŠ{†Ò/Ö•<*¦ŒåÓBå”°|Z\>)”}©/üRŸ?a(š SÞðóz¦kÂP‰ïĤ¢û†Â˜XÙñ0„"0 ˜ÝN÷©-;Ï:  ߟ@çZ;.…:A#[ fÈ8øn-ÍÉ=êugæí­úš KKŠ2²5fh>–21ó³`ûù¸".ø¶ÿ*ôúéпE‘¬F`v8÷½8¢^3YaùÑBìbܵB׿NDÑHj(B4bq9¿Êô°ÓÃî½fuÃv¸ö¥ÏmîÛ[ÂϰÝ=lsÝ´¹`dÚ¶Èw\ŸZ69Ü@ðÆÜÂã4âð wgqZ]cv8Ø[³0eÓŒcø<„ðΤ™bmÖÚìœ /ä†–è¶æ/ï*[óÓUµg ¶S††ß›'œ¡›ý0×(´êô€"‰zÚϧµ¨*›åX†“\¹rø™ŽÌ&4‰ƒv@%¼ÿ>y…0 a­h챆hBÐ/¡Þ¹ÓÈ@-ÑÎ ˜Ñ@:R—æ)Ññé+yžQkxF…)eºFI‰‹Ð:é@GëбtÔׂõ yÎú»ë3ê ŠhÀ€úבLµ=¾¡O#!bomv®0kY"ŠdÓ?n¸Fü_~ @ Æ÷µTtÉô†UC™Š· ˆŠAI¥1cY 4eÐM‰C¢b9Z_3•GE]Ê~^ÏtÁO#&–L‘ý¢ ¡ "TþdÙRÌ(Y–ÍÀ há¶çü; ÙA°Ÿ¬ Þp4o36ø«%sAùb^£¡Y6]™Ë©a•œðÎàTðI ø¡išã¸5yË`"PÄ™¶×ÏùÛ/¶W$;é£9ê„-ÔÖï©iàh:TPvÛâvÊý$RS§HvR9á(‡üü“C¾]ïºU×4n%€ >¨oên8äkå°Í‡|ÃáÜõÇmþQ›Ž`ó¹ÅÓSµn_Aå…Õæ_¬ öÏÀ9Þ[ÎÀ »üIƒ+l÷ [Ü×mÞ1;\ß{Íî…¹nXÝ#ÐRýfØ'dŠ?´p9Oùù¼¢«^€áíÀš¹|ùr‚ $429=Øÿ݇¿åYÀ âÅ–¥$šû×¢ÞÔ (’°>1géŸÖcFý&tr-4 £Õh nžÞnëjFŸ£Ð(i ÏgµZZÅbÌsXYHÏs¡ã5èméZ:—Ìœ=ôÓ€úͨGDǨτŽJ¤¥”óãëe ^:bâá—¯¤3X^—ºO¢‘}2ÑÀŒ±7. Âí  ½pL«r}¥F¥ž¯¤yžÇÕd°§í÷¡ž ˆF´,› lÀ zu#êò¢C-èPu·J¶Ÿ=2u·‹Õðj&ƒÅL&Ÿ[_…(„Àê*”ÌÙÐ8\ß #7-î«Vð*\sú‡ì2á¶ÝoÈÉ^ÂPgªÄ!kó}‡<îðÁaûc52Vï½çðƒ»þîp_³»î•~ d¸1x¦nl½îp‡­®q»gÌîµ4ÚÉ‘#¶fÐÎm»kÔÖd XXGÖØßsæÄ¾ç7)—5å4ŽØM)׊I»ix!.›’²}K9 S­ƒH„tHŠÔ(e ˜”cÅȺ’qÙ–tà}+F”,¯ü÷-!Ù&è‰!+•”+}°¶œR!ŠEß;½sÏgÑÎc]g¿ š»´TÀ~ÀPnŽ Îcyx™ËP•Hsƒ(ŸÃñZ«×æÕ–¯ý)žàǹÖ=›:>Šv òOZö‚RH$R»ÐšÂ»îPz”7`"gP#îCÞ øq­:dÈ**ô6]÷Öîàmwðª/|µfǽÚÈßý¡7¬å,eÐÒBuΟ+ëF·´À £ÞпÝÁ©Ö‡CnàÙ]up™<‘á@ìOU[¡kè¾Ð—žà-_ÃOQÇ ?xÃWÿemðf 4ä ÝÃù›[<áó«\Zµ¸’?­Ür/Ð:\SÇ‹ÊC@Ë‹îOÏ2#`žpù¼úƒ“§Faì‘ü_Äã“Éx¼¯÷0ǰ¼¢MÄ–“£Uä8Æ}zâC#ïU’£37ýû+ȉäù¥‹ôW’~äª%¿ð±•$º’óš´«‹t t@¸†EV­eøŒ^ƒHÞ©%ï§tT&'2mƒ—¸ä~;yËÁ°Ùy þ¯¶Eäàô§ÿTQ<1I_Œì ª–P†ÑQ¨ZµFä|CD†S#Tl.ÇcgbWéIO³Â |ö@„t7*®˜nÞC¤'Bvû±Ã@#¸®Ø<í„T–ñíý9c¬ÂŒa—Z_–”-%LFŒ?[Êay,[Ç$Ë„211©K“N Ä2žéj_\$%ý¸½8é°Ä1Ù’rZRŽÒ¸¢µgĸ¬O9 )giM“-èÛcÉø¨bÙ4"›KæQ|ÜiŽÛõìÅ#’qªu‰I‘  þ%¦„ÓÀ-W|Á[ÞÐ wý7|׻⟑Ý[‹–kU¶ÀdgõšVý£ºþVmdȬÅÉS*h¦âû&*r0þwGº?LL¤ ‘§C¾I2µÿÍŸ¥)Âã™ì¶’þjrìé„FBÌÜT=YNN¹IË U°œ¯YškÖqEœNPágÃRÊ ‚È‹¹TBD‡Úl6[Ì瘕šYGªÈ»éb’“®Ìóà%Ç{Nåò;Wq“OÁŽJÒ›94‘ ¤¼‰·ÛHÈż^À«TøÉã®÷D*ʱjQШñof-É#MnÒ×FzBäPŒŒ’Þy{úõà³Ýav©ªãD‘gßZ\_ù{U¨c!•bŒŽH%N«2åbLҔÜÄͬl™´›öôܬ|å¯wªH­·MJfð`Òa—M ET04ŸìË“N@½RZ{Œ8Ìæ8Da7¢“À[º¦G²ékÇ”ë E"nß¹ïÓÖ½—#í3¥‘Ë-{.ìü1žg[ ‘=6wªuZ* ]ªÑÜöF0‚= W}áLjÄò…üa}Ž.[ä޳‰êß»¼ÿ©ÞH€àÊUwýCôz zF®~]«Õ©XV–Šš¿xë¿òÖ ¹ë®y¦Z¹ëk¼hºç }åüË]ßb(™ÅÎ)]@… s1¯û[åöûžØ°'z½¦aØÛ|­:ô;Éw°tmÅ‚E¥*–Á€-¤Ô7¿ð܆À@ zÕ¹æ ¢uHý¢ûsNö0œ ßF Ë÷èþ:žÖH<žú¿G2 Àjßj¤³Œ«&ÇŸÌ}‡¢ı™›ª§\¤w#“¤±Ù©,;[G5,U³Z5§¡¬RCOsLÁ,•˜•eÒ°ó²¶-#ýUäDz…cÒ/gž/?Þw‘ees95LÂl*'=m3¦‘Þ(9$}-dŽ‘Cͳ\ÌÒy‹©Z“Íð¸•eX5ÚYá*²?ªœ Æàãû仑ôF¦Ÿ7FzUžï‹ Å£¡ªSú% ¹,ãÛûóNaÙ8!F0fŒ¼ û2eä9ÍßȆ1Ù4‘‘ §mr½mL.YgÈxÁ/(ÆœecƸݔ ã¨ÃøÈ®G’õ™1.—Œ;­àÀ–”Íö'z)IàMY¡È¤Ý˜”LpÎIHæ©ÖA $B:$Ej€2PÌ„lIÉ–¤½4µ¾¡È¼™ñF=gŒK¥O42!Û”¶8Œã’Í¯ÅÆä0ôxä‡Ǻ>ŠuB#ÃtUpº¥óW-o|Øþæ»»\KŠ5 §£ÂFË*üél´¼E.6u`}°áÒ QDÑH¬ Áúˆ3Í ÎÅì³a¯à)ÇÑ›¾Èõ´Fnú#ƒÞŒidؽ]³ý¯6³ŒŠÇ>©Õ¶ém×Ý;îni†"nx‚WÑk@EÕvÈd`Kt—Þ–Çã4 Ç2—6øî{ënyê‡|Ñ©Öÿ¾R³ã KîÕ6^©©Ûo´™´b&(¥ZQƒý™n(ÕçäKóåç犢À2,eñŸ5œr ™¯Ö³Vü¡¦np[+zuÃ]?èÜ D•ƒÜŸK›xÊŠ¼€}¾ï`Ïh*x(ñô‘HÄŸh¤÷çÝêÿr_ï1QewÀO² Éäæææfn.áDwm×Ç*@”¹sï,Â0  –ç ¬]PÔºiDÑí*Án›ÔfSmöî›&MÓ‚âw‰J•÷L¿gÄ´iäet²%¿sîÜ9¿ß=3sŸ«¥ÔDziÏš§Èi#4Ò®x­¥žÊðkÌa"¹àe\h(#øñ"ŽRE† ÓhÖrLz¨ÑR·ü:Gs¢PsÒFNd‘ßæ’.#éô8äL¦ïmðŽAw¦_it DZ,ËlO'Çj¼¦‘cU¤ÙAÚjH“Jš*IkuÂÞmþÛ¥€øVäÃ5lÃj—³[’IÃÏH‹Ó  Þ~ïr–Ê7ƒŸ/pøqŠ\ÀM},žï|~{_dLSuÄÌwCOLɺ'´“ƸÍqˆ)ú±3Nû,¦±>/ø-Å$€!ÅA 6a00Ƹ@÷Êp+‰3RüScÜ´9Á…©½š•tðŒ9Þm6@#S”% Ô$tŸZÇ€Dsž¤HPŠyªÄ=3Åcì 2­ SôùF-2¦@,9ÄõhD?¥DÏJ ¿øi84Âó|õmW„Kj=4òZ¸^{ø½cÏW5ûvoÎÚ±:%bÍnsîÕÏ«uXóÚ®_^ªm<_Ó<`à-\Q)B^ð +_«ÚwQ­O^±*ˆFø`–È+G—G‹¿k³XÊ}¥‘Q hKÑ×ÒÖ`7KÑŸe/KÖé‚ÊKÙ=KÙPnÉ@>õÒùŽQkÅ ¥ô’ =aÙsé™÷­%¬e÷ ÔÈm*Þ5b-ï·”åÛǶ9û-eÉ-®×¥%…j4¬(Ah,žÑÇÅf'.ñ¤`´lLpèѨ”-å@Èã"ç÷9erKZí÷±ië[ß·¾´ì@–¸HhýôÈ4Ü1 ~üG#³³3¸<$òZ- hI£tdP„tÈäT:éV¨F:¼§‘ž­¤QÑþ”m ]¤±n¹ÿŽH]ª[i·’Ž­ä”L:Œä @(›tBG䬙Óý‚IÞ«çÇí0X†&%>Ó`.XxR™åM! tѤ¾×TMŽT“ÕäÔ.Ò\EšìäX%9^CZ«ÉQŒ=iQé ©‚¾ŠsŽ;é9m¯_ÏÑ*ÒªéV ¼€ïªÀúlL˜5ýè»Ã´…Öéþ8ÑÖ f””9u*=Ñ-'c0.oü—DÛ®[‰wÉñãÆhŸü–ÂmNrɆ9³~Òå2aOônÙà6oš‘£^³¦$·’4$Ⱥ ª‘XwFâcI7i‚èâÜðŒ¢WèÖ™g•ä…ÖA O"=’"5 pÑi’Ë"Κè§c6`€)ú|£Øj…jdÊ”è’õr4®·eÕŠ åøC[‹ÐÐ!pâšóµµpɱ÷ÆîO/;êþ´ëð—jÝoö<£îù¢HÅR—ÕúÞª†+Õû¾ªj ~p6^Të¼¥‘>g#lsµö@oí‹;¯¨õç+÷¦¯Zp¸0–ù.k;À$w}§‘Û¶Ša[Y¯)'\ËkEÑeàrKî啨 ÔAk98qßRþ½­ øvK±(Ь†ýP+^Þœ9l+µ–ݶ.¸þPNñ˜Õþd[ÍÇß-e÷ó*žäÙŸZ£LjÕqÓ\t8v£iÙòÈ0QÄÃj„ Æç.ýɯ¢“¿VlVÇU°ØsбÚpnÉ£Â*Tu'§ävNñƒÇÛÞŸ[F‹ Ñà’ƒÅ úŸÌzà1÷_qyþæff m¬†E 5rdéÊ$gÐô¡£G#2{««~.‘Æ)„É_O>ÙHZ3IGȩ́À8›Ez0ÝLNo¦êè?ŒÔBˆü—æiԥΠßóà.ùLk‰ Ã4(Ú\Òì=±“…49æ—<Žz¦`Fs%µÒZEšÕù#-UóVi~yÆëkä¸ñn-ø®ŠŒÿ¸”:kŠõùí}‘á6§ÎH©MŠ;±z¹%TøHË„óš¥Zð[³TФ†p#ÞÿÆ;ž¾>qÉ|^ðÛÚ%qÚD]1)­sËñSJò·‰ºóºè›†¨WFoüÚçæHB{"ÇÌJ142¥Ä¸Ìñ.Sô¤¢"éqÂŒyã}äBë !’"5 @(flSìÍøob¾ÑÓÀSôùF-2ž™âÜ`˜7iÂ7*á™ ‰‹ZÄá)Ñ:Ó2.U ÞH#×Ô†?üüPß΃çÔ½Rä:üZuá˱ÔU¤z@‚¸^{àÆÎC×k^{ý…âzõ~ Aá?4r£z?Ê(JÚÊ ¬–rä–É2h³?Ì+Ê+»gµûJ#´†mê­Ì‚0†a´ZV?O6?°U ÑXËòí÷m´<Œa’®Ô¬PÜÄî}Žÿ³’7hÙ1f³ß.TZÿQú¤@É-ý§¥t(ß>fôjÄZ1j)Å‚ý–Ò~KÙ°µbØê¸muôÛÔd— ZÃ…êP §Ecy¥Ïòíw ʇ íý–bEhIVûÛ‚y½¦µ|u Ï ‚À³|avÞ´kî4ò%nÙ(ÐA‚È3,ù,“ôdS~ Úe €.‰âÄ[]µ{éÎ 'áŠlÒ-“ߥ“®Ò‘F:4pä,,”IN{¢#›t¤“ÎͤG&% u‘LOð9Þq´›¡>w%4Â3"˳¤:›szM#óÀPI[ ¥eVÓ—Z<ÿ)K<§Ñá9ˆ^m­!MäÄΗ编FªI›¼$ä…FY—9ýÿ@#Ýú˜Ò%b„ÆãýGŽþ ƒÙÃ8a)}~b4¢ß:ÑÿØÊð¡MÉ>/ø-Å´’0KÈ:—)Æýñ†¿mJT? åü‚Xþ•¡½÷]Šؘ¢Ÿšã\r´ïU'LQоÏ͆§é:wFòCcB¦HZ)é©QÊ@1 ‘+"¸V`–ð<LqÐçµÈÀÕ¹äõÓrü„”<7c·õWtëq§à¸`N[bH»TÛxÁÓÖ¯U¿¶ `Œ/í»¡À¸b ýµj…”•k)œû±roí^gãEµþ¢Zç-Š úœ´f ê|MÃ…Úý}jCŸóÀŽdc/2Šàn¤eÞɯx¡‘³_¦±MeWR¥J‘,==]]]ݧ÷d;2 Ã@6“­a'~6&‰ã8À4$qìØ± P4$N€¢N 4@é—Ù¤.S•i`’!0t>L?OÕöËŒÂ2{I™ÅîÿhçHcõŒÀ:z¾~ò9w;÷ü÷ÿ ªO3 ঻#ÉÑu2ªÐúéYg=Ãu „Џ}Ãî&´‡@R5}–Y&V¦¥kÚy »á¶Ç÷…÷©4…ÈÃ^ÿPMãÅúÀͺ୪ÆÿŸç< ÃÞ¦áºÆËž¦kõÁëÞÀ5·ï_nÿo+zªm>WÛx­vË­º¦ï–!oÃuOóUOó•Ú¦ëõÁáêFÜþi`§¼Ú¨œŒÅ“i$8OñÓe8‘²È.ü=õ²ûÊžhïWHïÕší¯a›¬ S•öû¥ÒêÒ Ñ*|’vÿTÚáì±? Š$Ð"a= ÐE›xö†¥ƒaÓ[ai_@¼?Ò.Io¤#h'€ä—-Òለy(yl#„iªfeÄ9ßs.‹?ù·£Òyבw×XtoõÂø†ågË‹|33Q(ÅÝ›"ÏáT§„*$¯—uªB:ƒR]¡*×i3OÛs¾^»2n®ÎùÚU0åÈ›pد:JR>Áç´)É£gá”Qx¿â'UÓÀœ¢«”™(!š:“­µ½·({Ü(þÆXüÀ™?^Qœˆ;‹â®¢QGqÜiÇËøº‚)£x0?—©ÂŽøB„B@„EptŽÐ:MtýhçÍ¡¸¹âî '±I~âeÊê9-öÈìS;¦ùÀXrkUÞ¥e 8!²ÆA#5…eÐñ?‡£'Ûº‚ÉRÁ©„K_p¨ ¹l —lšÎµ?´G?ÜÖ÷ÁÄÇ'}ÛºO·u Eýo‚|úÛw÷E¢À•Óáîdû wõ'€¨s²-z2Ò},Ò*Y]V”ÿveÕmohÄÓrÕÓrÁÓ”*ùÊÓ8Z× œhË+²È2RkÕ<Ù_yZ®yƒ·jÁ+ž–³›BŸyšöÌ[„jÀu-ÒÐÜÜ¡ºàÚÀíúà§1UãÑv©>Œû˜EàˆºÞU Ä&¦âßúé%Û/Æ<î:ž@ æøÖ®½•^̈¢pQzؾòŠÛwÙã»ân¾X—2¹ìiݨ \ÚÚ_¸ÔFÈ™¬Zu¤¨¦rQ±rŽê€ê­Ì” ʺòËÏ×G7†¿¨n8W×rݲñ¿h»àö›4™úF&ÿƒ‘G4255¹¡²’( DGe<õ²ûÊžh﯑ÞqÛò3q -D5©LHyO iõ?”…¤_µJG#Ò¡0_¿L#D3¡°ã:ÉÒ)Ëäš•° ®¡‘ŽëªE£ê2ÁO€ŠÅbá²2‡i¦œ×”íˆ FŽ$"ò¾¦äé( mórÊÍ„[Ù>7sÂQ3 R^Þ¿£MEc #÷^EÉ©Â\L€aÓ,¨6(>6ªê\S(•‰¬9ƒ+fM‘Ô4ì ÊÌ8˜”˜æk¦¿ÚsãÎò¸«l¼¢`Ô(ulìñµ¥÷%)ŸàsÚÓh„&Èù†¬KÄ™lK¥iïædÅ]åàP|Ç\ŰqGᘣ`²¢0æ,ÿ '‹²4à \à(ܹö0–Šd~¹hdÜY„T¼æÿµÙD!fZ4+ <Ðß¾ûTaW²T0°cï±¶ŽÓáîO¿÷m_šµÀb¶¸qCÑÛ@k,[€K‹(ºyºÂ~ׯ _P„ ‘Pg²ý†¢x¢úÃÑS‰}‘hOít„ýã„ìÏ-»ü= ‘‘𦻛#çj‡7…¾¬ñ½™—ɘ¢˜â±Ô-+XŸiš T„,BvdüÝí»Xëñø1øÛ›Ã)g†hõ!3. TpYõúªØdl"þd©t­Š@t4®¦^v_ÙMÐH­í?ì×}lçð“"Y²N§ÓéNwò9Š“%d #aäűㄼ±}\BbŒ“´¤q‚“sâd[»å…—2!  ­í¶j•èVÊ{×M›ÔiÿLHCê´u0Â[x+%ÀHbß¾#uüQ$ Bƒè—“}¾ç÷ÜËsÏïóä¥` (1¼ÁÄÇ(ÒwõÓˆCƺÉçlC k "‹· IbhNF,+`Ö&ËUQÀÔ-H4k6‡@&<Ï/ªXF wPã±<à b¬‡ï‰_#AJ[ϓ„זٖ“q­Œ¸ >½?npY§ÜV”¼i¥FI•qsŒŸË2M§È2ÃÐm´óüæô´Ù™?Í]º7+µÓbÀÜbƘ'Ò-)Ð=«nºKgÅ:AˆcÆiZ½2‰ºí ¿À§ŒGi„'cqà1†NÀüÃahñ­&sººæ¾Ë‘UìÓ ˆâÐUûŒ³0ê.ÑëœÍ2VN4þ‰`ÒIE°¤Âú‹ñ4 €Aö¸ì`[Äe·K2à‹°Ô$ÑPÖ!Šãq’q¸gðÃPÿïz·ý©wû‡½C&Ì!âÂtû/ˆ&2Qà‰x&PJ Í~ðævôxªg˱®~’î¡'ÓÈÑ^rÎèŠÆýíÐé‰e\Pvżx;.ú¦‘ëpÅÆÍ½ÐèbKè󆶟¯ª–$ QL¦ 2Oæm΂%Ãe‰òû5ž3ÞŽëÍ¡«~íܺMwšC“õ­Þ„ÿ³Ž«þfÂT<1šõ5lˆÌÎÏÇòF" Öy< ,©F ›ø²û2¾1Þ]MýÌkÊ4¤™c¥<õï"rÀvOúI˜â­v‚“ÝÔþ0u oÑî°¤Vq²ÄÐLú’%TgâÔH¬7æg&ÑF&#™iXC½Ñ‚ƒ©·»þ—vòį£ÑNªk½€— ZÖ°3;]w—E•¢„Oïs.û}w¡®Ø.­ªHc0=›dNbiZäDc²``·¦É,¶Í¨µWMÄYQkî®.¿TUõªÅ”Ì-þEþÒ¨«l¦6?ªGݶ¨»hÖe›qÚæÕÒh]Y¯îéãQAÁó†, M粨h¸iäS–Äþ^U1ë^9ë̸­÷cµUW‹fœùQ¥ü|Me6k4sfx‘”BÒI,1` -’¿hÁ8ÄÈyà²C#¸Rhf–T 8ã Ïÿ6ôÃßto9²§ €c}ÛŽk'ºú?èîÿ6¸ ðBì~“‹Œ§j¤9mæE,mÌ W$¥àȓ᭿ïÛN(Þo§œ-Ú.œ0|"A~(Ýï€Fš´‹¾Žk¾àåÄiäßþàåÆÀmׅƶsÚ¯7i—›´¿¼Òr°\ýÞw ë3²kÒ2ÔŒ¬¬pª^÷ycð†¯k’œpǤ8꺿ç³)”p6<£¸ì Ê W›c¸z÷Z=¢C#ÑHäkŠ|­‘UÕ5’(ÆBâËîËøæXClde#ª¶ÀòÂò,jì (¢Q{»HŒÆ@²/¶gg5Ž!j¼›ÑØ×<¢$ñIƤ,ó¢76QcabfD“ƒ%³ÌhÎ$rj5ÒNíÞLÚ⤋ÿ|F;ëYAHFUà ÃЈR>÷üh$ª8tÅŠ’w´hE¶Ñ¸ØbYÊŠI²Qddšc«$ætU©î©Ð×–¢XD••QWZéjåEgåŸK󿬱êõÕwkóu¥`N±ß­+¹§–Î’¶x¶Öšð |Êx”F’Y–ÁâG I6Òž” 1F¬S8†Ks³¢îÒY¥è®³UU'Í­€ß¬»l_NÏÑRl±‰&hˆæHb!ÁlG’¿hѱuÚ0Æp™ ÙI4R챤™pŸyVf¹{ôž õ_G´£½„Ÿ†·sG†þÍeÓ\šYÆI¶”ŒŠ¬„ó»ÖæÊÚ¶µ£Zp5|Ôõ£O´ÁS¡¡c¡ÁOª‘£ :íBž“ÝC‡{Ç|LƒxЂ@4‚ºÞ@A¿²±=QÕöü«Úu/¡ÅY_û­&mb}ëYoàNs貿s·ù’¿s²%4áïü¢1ð…·ýBK÷U ¤1p£94á \mÖίoÅg4O8žF–še¼¡xlÖÜ<=ÓH4ª?ôÌÏÏå.Ë¡4|›‘–žèšû2¿tB#F!iA#²5—Ú«Q#qW°­ö„büÐÈvD£`g!Êpu— F&“7-Î_BÛ×Cíí¦Æz¨}Ô°f(ÌÆ8Igc}%5¼™ðÀ›±tů‘€!à1rŒ—%G—eèu•3±’ý\ªì4­Øw夦`†äeŽf$ÑÀˆ©xó^7ó·Ý庚Ç™û¥3OW­ÔÂ{äêlºJÈñÀ]<]›7çʨ¶Yg~ÔUˆýÎŒ»xÊiŸ©s$üŸ2¥ Ëщˆ¢Àð¬Ad¥YÔ{Êsê]•ú•‡Têwê•:ˆ-v*ÿŸñþJê½u4·ØÂJ˜MM9Ôxm‹¿ú?:vuR»‚ôŠ N8žOÏʤö}Ÿí!Pî¤ÆÂÔž0e["˜ål#ËæeRãa¢üôvˆÚ"8Ù׿=Ì+%&Ž8Ç2Ÿ9 u·ýA¢çöǯjKçÖ¨bßž›"±(¯r†‘Ç@bd—™=Sm×ëQwþÚ¼¨Zü§õž e±L¯«ÐRAtOɬsùœ«h \©/ý[yá!ká§%•§ŽÓë)‡ã3‡m¢ªX_[Q–Ϲsæët­íŽò_öË-¶‰ìŒã#­É’¥ÑÑÑèèŒÎÈcË6 †„…@‚ãKlǹ’Œ/ å¢Äqh·+'¾$!A‚†„$ì>”Û êV»å©jWË.!ÜU¤ m)mÐö¡Ý]v)$\Z @ ÛÓo’Vâ}`•.£¿Ž>Ϝ˜ã3çÿû† ) ôx×Xù™ÔÀ©®þ¥‚ÑäÎ ½»OwžÙ ÈÑÁÙÞa`ƒ‘Þ¡Oã; >×5x¾{˜áDÏàñ"€Iާv‡±¶í>ßM@/:.49Ù50’êžÔ™'ŸCëßÁ €Ùzßíÿ&Òv3ûǦŸÝŠlt]W7ö?¨)žQ|‘\™`^;Üc e°›.yK—,‚»¢ ©$a uöç›vž*%{LG Wì/°˜ 6Œ0ø‡(Ùe3_ö9 1bHàÍ™WƒÙ8O#F"~Þ½kžFF»v¾(„|žø#Éç·½ÁgÛ5J‰÷‡\è>Û~aëйÎ]§}g“ýó¤úOuBNK¨¼è ÿ!h;×tå]·Ä)\D°PÒ]äü&kŠ}Ù2ÖÒ>ÖÔú\]‹v|מ¿í¸í¸Õ Ù>Þƒò@@tß6Ç®EÛAß6k‚û~sòZ$¶ kÙÖh͇ÿ z¸4ɪSÿ‡ˆ³Ùlf.Ô¼!¨i)XÌ}¼áåÐ'›´ò7›¸O6jÁÑ0÷Ë*nØÇõU¿šê©ÎÙÚ€%fÁLBD8¼@(¢)ÁðHeV+Ò‚ÒÜÜÁ.:õpƒmTñƒkɰY(áËWr{;4Ù“ÔÊÃÜÞ„Vóµ£O:ì~RWòw¿ B'¨ I¼€´ùQ¯[JùŸZåçêñêŠÇ¡šlЫ®«L+®)Å®†KÁß³AÏ“ ?ôÏ}3ÁòkUåv™è0/Ê3b(¢x±ˆÿR‘ì»Ð»ûd¢ï|Ï00ÉHªÿdÏÐÛß;ònj`CKjmC߆–£­Ý¿ïîé:Û;<šÜynëÐh×4<MRý¿è¸ó 3:'mÄ9,ù4¾` ¶msî²kÍ©G‘ÔƒhòþÆÖEÛž«Û›Þ½ÓØz·YÕM[àÎw-`¾mßGboºÝ»é¸ߎÆÇ£cÍí×›Ú@ E;nLn´-g” Q;lÔ™´šQ?C#éyɪðå–§0™AõRÈHÈ3±?M†´ˆPý+)^F¼Mæ‘vkY¥s±æþû~„ûÿ€Žt¾µGc¾©#Ä$ ’‰ÇúåVKß²Æ+ä™àðË£šsý;aî@J#¢})nœ;eJCš×ŒFfî©;pÜ­-Y˜Ü“¥ˆÂž$2`[òØ ÿE52é·YÎ:VMÔW¬yª”NK³$!wFqO)Žì¾,ª^^@ÀO)³"–¾IáëDï/]’®«tQƒŽtÀó(ìMÜÓߪ²Øz$cƒ„E›syºÍ¶x:TO×yêÌl¥`|‹ V*Á7nI¡½èÏdø¾N;˜¸ #+Âfðuè××Ù£¿ö> «aÇtÀ=YëQÃ.5äÿ¨¨ÀDx>7h‰…*‰<‚·ö0Q¦•µ"dB:ø‰ø¾%&ÖûîÖzÖ›(¡ð”!¦9F*¬ÿÒcŸ Ö”AKFŒH€†”ý/ûåÛÆq…á  @`1 ;˜Åî$%Q´˜Úªh‰7I$EK¾ˆ7ÉN¤Žƒ“º–u«œ¸µ%Y–Q£°;.¤‰Ó}kbGñMI_ }h¤è[Û§^6N¢@²uãöRA_übU/rDü †KîÌjæœÿ|ÇóÇlj©˜N¸ý©J1õI&É…ÇÆÖR –8/:|±°÷×1øœÁ-MÐÀCñ-©é`ÀW£›7U¹32ñ¸TðÞà™™Áñ»Ã“ fÇoŸœ~ÿÔù«/ˆwÖ3 2@¼#ÀºùæØÔ‘£¿6àÇ¿ª¢ Æw¾w®†ë ‘š0IFîŒNYÔÀŠºÍ–ïLlϹÖÜD²û|[v:þh‰gÆ“ÙWâ™cßl{.òTÿަ|ccw¨¡jÜ”ŽD¢Á@X˜Ê¨Í˜hj`ËtC”ãÂòzáŽÂÂ2ÝÅewqõ‹ÊòŒT*Ë««+Õ‘©ú•¿ŒQÁø¦âbÊ ÿ]ää§Ö©‚Vfù tœºž m¿<¢]Û0ùñà¶ Ú•ÚôK²eU‡}…¥ öp¼B6×zÂCLšáºmS/k×F«øQep²ž¥77 XßïUP.ûzf­Ôëºcª k"›¸âÒA¸ê¡–®[ä& ðŸÎåÓ•RºRL¸¥„Û‡j[.µWŠÈ&ê¤Ç#IP—ˆrCJ/')›º?çöeܾÄr)>_j]ÊG—K™{ñ*áæÌörýf¢ S-•Ú– = ’†¼&Õ™AüŒv L«‰°„ôÂâ” ¨À{† ¸†“›±–J¹k®7êbªbz%ջߊ†# ]ŠÙ#ˆn'*‘ÌÄ#èÀ1B€3¨ô\å¦C½žjúÛ¾ÌB9¹XÜ])´gëMð’¥X…J•²ÒÏõß§ÛÜR÷dSÙ"`(5[hx§nß^ì36Ç-wý°ÉO¤N†M <«o6×-”r¿íŒ°0“  Sâ}‹Fª:ô;\»Eù»ÃïLΟ½;:ù¸TpûÕóÀ‰;C*¨xïäÔ©Ò³§Î¡ A™bpîà…Ðñè!*ð-~zùpøììè`föäùuÐÈm…k„E>À$£S>&`JD ,è«öGÄäÀT©0ö2©ð†ð´‚0¼#•”©n‰£ÉõQ4† Ì*ðײäÿ|ŒÚB"ou‚fÄ]­¸k$²F#+Puÿñã8UDÁ6‡Ð Y‚ÚG-À?Õ åÉÕó‰”É=^‹"÷ÑK¢6‘d“viP»¸>x”À!ÔŒ1ò¼ÞèÔ`Ï4Md½¢>nÔ Ó"ŒDÚÐaíµa…—ÔûÕ!íJmž_7©”: )·œE ž¾ ´9LÛ« )“€‚Âg ô˜dÌ#YËg„lß#õ™dóçÅìgTÛÖÕBëJ)¹”ouË/5 ƒõ0IøN·.Ò¿éŒ#´A#\Ÿ°4-èz»W ©•br®·«ÇT…âÊL®ÔéŸs­ÿ.t~œŽao ¶ªKÌ$b‹F6–FnŒLÜ8qúîàn¿5vîÊ‹ƒ)HÅŠBCQ‡ŠO¼º2 ¼„ˆ:ÁË/`n?={rúݧ÷†{Ý{#gÁ05¹;:Í Žß™Dä ]BÉÂÀÔñGx-Þÿ?Rœ®É¨ çn±šÄ– »Üs Á(ÔFH¸é°N@·T¶£!C¢dÕ­,}E$|rWªXb"¹ÛR£ˆ7m ±dØH5±Xƒ ‰DØÌìrоƒ9z¤í‰;Ò¢I¡µ@^8ªxD•òË£F#‰kÕÙ~tT{ûûÚ¾Íz;=ˆX<ãà[W ldÚ´Wh׆«øqbíFŒ¯ }=id¾Ðé–ÛÝRb¡7æö¥¿8þE4Ìà‚š:ibÂ量jÿóô1îïäL Û”¢N’ñÎ\±…Ò-¥Wú²Šq·/5Ó¾3`è^—WT$Üaôxƒóe>ë–:*eðOÜ-µÿ)—t,GCÑä©>†P⹸+ìöw»}‰…r|µÔs0 và*ÚFÂ¥4 f ?¢è#>H4Ïöþ½§ëææËä„”`Ñ!j®}”4˜ž¥BÎ-wó‰ù|ÇH}x—àƒ0J›˜{unóÌ&bŸïß÷Ù³m»Ÿo°CÄs*Ô¸Tì¼_Ì<èM¸ÅÖ•¾·œ{Ú'U ©~–€Ðüà©ÿ.Ë·™ÏE¹ð1ª\‹™À úxÔ-¶/Ó÷R­AÄ>0†À°¸êÏX6ì~>ñI:fâ bàFX™Eì-©©ßïTÁ˜"ünŒLÎŒž­"ÁÄ:h<ðÑ蹻Ó7ONŽgLj'€¡ÃE6¼ópG÷¾HKØ@µÑ‰%‰NÅ33¯œ»=8„ÝR·O=£S˜¡6® à¤J#ð Ež>J[ Y¯<‘6Q.$’Š9†¼C'Ë‘wˆ^[\Ý¡4*e6X··±©7É76BJ}¤£u;ëЙ²NH”‡KK5ùŠF*Ë««5‘µ£‘F°9¢½SÚºž×~ZÖÞ.jë%í­^íçeígEíúªŸ<­½ñŠJiš¢-¢]Œl¼>¤]úŽš¤qa@»:†‹äìwµ±oéÏô°C=ÛŽÔ¦_^ûêê°vu@Èë#ÚåãÚ¥êøêк–ÞÜ4²PêZ.tÌ•¾öîºý™å|î/=¹±†–°^Çà”8œy,æµ…Ÿr?ó"Ý€'°lÁœ€ÎÿË~¹ÇFqÜq|ÿ²dé¤Õj4ZíjV÷ÐÝacó¶ûÞgc¾}œ1ॠæüÀ %ÂÆ6RÆD‘Ú´DûW1!`ÞÐHUõ¯Tý3m 4„„’”‚Á{l¿{¤¨j‰„ ¡²ö«ÕîÌÎÎÌogçûù‰mËlÇ}}IJ«‹•'Õ ©ûÌxÍJkuž—`šŠCd¼”{}ùÒz%ÜùžšRËOøŠ9–뢎9ÄIEÉCx§ÌZUe•fÜ7¡SF,âFŠƒŸ›5(` Ô8”kË𠜺À4J̺¥gÃáÅŒæ"ƒ±ƒ@yð¨^šcË¿QËA\°ò›+|f/@p8"È$WáçJdïÜãj˜ôu,x71ë¢×Õè±bÏ×Ë—¤µHʨšÀ˜ >ë?Ôêz¯2K°ÌQ`ÄE¥"ÂrÛÇÑ…w0ñxõúÂ’¦6T›ÏÖ®y¬N«kG—×_޽üÉšW¯6o»ÙÜv«qÛß›Ún6m›ô×–Ö«-­Ÿ5·~ÞÜz£ióÍÆÍ_5n¾ÕÔúEó³ÑÕ¦®¸§ügÏf"I3ö¸g¦ñHÒ*ÈGðç*”’0 ‹ŸÑP°_Ô#U„e{ûþnhÓ3¤‘œ¡.î0.Ú,,ná†Ú¹ÃíÖy(KG;,éÈvÚÉí¶jmÏÖvZ:’­v×[sVU(s Iï‡0µŠ¤xîÛø“J‹fô‰«eºoʈ˜ñ%˜‚Y¾½lññų¼’S$ItRÅ)(/e¹HÐxRh%w|DpœàÚ¦Q6Y1u?ô«P1%6¸¦S¢¬›è s‹Æ´åf¼dB/iÔyóçÀŸ‘ôIÌÎSI‘wå ×V„Aãªÿ^<˜Ö*Wy¬ !Äa' Ïl Í»§–kѤ fŒÀÚpOS ¹LdvÂÜTQ|ñ£rŸYçKj¥i£lÔÿ’Wdy• GÌ“ÁYÂÚ|v/VŽ LÅü™x¦?¥q‘ Kèd‘ <$X†,Z™©‹Ú%B>Š”á¤øCx¡¹Šz˜(- ´s[¯¹£ÕIhe%Vvô/ÛÝ"½&„&hˆæx ^…âµhü]4ò“ù… ¶D¦„¸À- SZè±J‚ú´ ¸nRLhq=i/Ìú\évc‚ˆ¤‹H·÷^éè6Œìì.œNôœììœJôhÙŒDüìýÑÒØHGÏåî½'»ö€:.%z{サÒ$O×·¢üdb÷Ù`‰³íÓî÷\ÇžÑÎ=tZg0Éù, 7nÂ'–©õû|•_4m½Ñ²íoM[¾´ÜsëŒ~ˆjØRY8[ˆ[V°õ¥M =Rfú¤qo¥<ŒÉ‚@d’W6ÿùÛc+¹_®%á!ˆ‹‹,±PáÙЈÅ!GÚ¸áíÜÛ îgÝÜO»¹áwh7ÜÅé²ÎG³gpÈ¡vî@w0Áîø¶,9ÒνÓ=ý~·Øk˜(»‰H&0ãU/Lh¡ŒE 8‡’Føn,0VëKi‘»jYJb.ôš?WUŒ”.üñ,‡ÙЉ^p(NIQ€’€Ö:Ëa•)Í÷O¸§ê3ãkÕáE ÌÕ²`‘*j‹»\)uŤ¾0£/ü¬º²X]à˜«â!2ØæxYÞ}­ÒŒWLiþF £•×ã÷e‰ˆ(.!ΩZˆÆü»Å…£â{Јջ#K#‹æ¥³Ãû_M¨ÁI-ÊJi¡‡™Fð¹/¼'Ô:·×…E†ij;öÂÓ/vö¿ß¹{Ú4’èEÛÓí½ ‘7_~%Ä*‚9¤Á†—»÷þ®{ߙξ“½—º÷î[µ/R§@›7¡í¥®Ñí»/ìÜw*1m z, 5¼6C#/–¾jIDò¼NI’R 8§Ò©ÿ¤‘L:Ì …õ±˜S–­ÝŽÑçï¹3z¬Þ3¸wWŠn‰âDz8¯;º™;ÒùÌhÄB‘îÀ6ÛÚ¥6—l—ÿÅ~ÇFqÝq)’%K–FO£ÑÓ<Íjw¬]»ØŽM øXï½^_žk1¸@‹š*Hx×6¨`°qÒTÀ8(½[¤HQ›ˆ64€sU(¢ý¿ý£­ª¨M£FBQƒÁ×3ý¾ ¡ùƒH^jÉ¡òòcô¼škwÞþ¾ŸÇÐÙÑnq>Yá •(¨j^I!#‘hé…nÇ‘/i˾îtF8¸™Œµ¥â64yièØ›Ï<ÿÆÈø…Çj"?'U”Áhêå¡ïÎdN\Í¿~ôÔ¯2ÇvGRÏ@eØç‡ûF¯¿ŸžW.eD#8ðžFp¶5<Œõá7öoðbMÄ3"º)˜;ðϹ«Œ1ZQ\wÏÀ€FÎ*­~ì®Õ}ë"@2ÈÖkÞRîË>M8÷„p.»b97$LÎg«ön©”Ä:"ÕR=qǃ©T<ù<áå—¡(¾B<ù)TP#Ù]>ŠhVJÎnh\Ô“#¼êm|™å¦£‹z0o%Ü׈ºFŠ@JÞêñ§žÓƒ·ŒŽOü8Òßݹ©÷móAž:É'$0þ_z¯3âš!‡3¦sÑâ@×îÊÖùñ­žžŠ_Å·$«ªø¯¾ä}~*"©=²ì+%+Œñ§Í‰¢™pÍ(ÏM;’·Â®Õ½£qO²Š¼VU&©Z•ƒFÌP$g&¸FL*qº¹žQÂ((¨Ì5çü>š5cŽÑ ®6µD©Æ, <ñ5>*omëv­àÁ)bàT±¢‡³BG¹qÌè‡ýɸ&ªXQÀ·/¤(‚Y§}:)Ùá—îôsïýáYæ-iäts#ŒqßÊë1^ØÍ•N–ài®úÄ[fšæ‘àà“Ø¥Ñ‰_fŽA#¯•«‚·FO^cFƯdO¼:r¼Uõq«*¥Œ1xqÿ‘מžøé#Ovõ£ˆ £Âb5 ¯ Á!ÄQÀ̇Ÿ}0@ ÷4‚{XÓÈCWÿØ{à+2O2Dé¾þBI Ÿ×^x³à8{¶ïô–.ctõcw­¾¨~>¨×! ÐdEå™Y1¼¦2‹£ûE/­•xÆU0d“ò)B¼²ÂeBùKæù ð(D?R˜úÙ>Ø¡ìë‚@£»±æåíE!Ï57ÍÝH™UoãËÕˆ@N-!òÁzØM÷}lm¾oÿ¤?åÚ=n:U(Å¥k%‹Fç춤k¶lÝ®ö!U둉âX–kTŸäõH•9³Ë1‚K÷4‚±?ûÕz$*Ø«„<8óF<4ÇÓΉM6ÕñgïW(Т)U¯„[toΊ/á°âà4âZq¨ –«€-Ÿî>ڨʤJ£^ãW“á7Š1 P饵¸"Îü`ñ}N#øoâ}aá+2ãØòe—¶«=ë–_aÈüZ×û—M¾6|üÍ‘“¯gŽ–«‚+Cc $0“Ÿ9ülfë«ù÷LäBëm¤*Z“Æ'¤ŒEŒVE°ÏåÓW3'Þ=ü4N Ê½.²¦‘ÿƒúౌ_&T–»ìÂ]8w5…8\#ÐÉ®®þ|éšF¾¬õ3Søñ Õ!¼T¾VT…óû„ó£+¦‘³CÂôˆðÂÁª§+kTJˆ¦(^Í«D6*¡flRZå¶&%ºÉÓõô§˜ÝÃÒ½òöq{ªòk½U™Ø%Œì-_#CÂØ·<ˆYh‡’# y³ÇyxÖžùþxÑN:vÄ5;\;ùO£÷BËúÍ ¹븹µÛMwçŒÈ-½}ŸÈNí^w{Ï[©x+”y%ŧªI!LñSéß[bn:4Ë5’š7“®^Ð;në‘o×øª% shFð;Ýâ÷í]WÅ@ Ü”VúrÛF×êÀ…3œ·#y3˜3PÝzÀ[M4‚Ÿ7bÉ'ûÅïT«sfOѯz_f-èÉœ•Ìëm®ÝŽÔ»ÔÖÐŤGàG›;þÃ~½ÇFqÜq 餕V£Ñh´«]íÞÉ67¾Øðãìóù|ÆÇ··{Ü 0Ä"RZT6~ðjªS$$J€%MضRÚ@x(@RUQ+úþ£õ´ii*©EǀϾÛ~çLR ©Ž¬º(‘:ϳóøízŸÑQ½é£Ó}¨)4]±¯/}ez*Í{±ÛÉÈĪÖëõ?Xï­¬›©F&Üå¾×üQg{ÐÖM*,A…NMj,`6eŠ0)×õ„eú«:þå4ú^âói$ÈM]¿§ÓáEW[?0~«¼ÚüÈoZ*ÿ”X|½#2–ŠN¸Í©‡F˸¡Š$—ÑþHÍå>Y߯ àsh¦*x«oèÜîá3ý{ ‘Ÿôí=³{øùíßjZX©â 6díÀ“©K* ÆXýW§z¾y~×ð•à Äù¾=Å…þ¡ïÜÿ¥F¾˜ñÞúÍ!Nå@ˆ®tö~Èß Ó,YÍB¶ÓANdÉIÔ>·i2жGNgf­¤žH“Sh8ä¤Gޝ&#ë䌯8rÒSY2’•^E·Œüþ»Åž#I2ê’QôqÈh†Œ¢ÿì­ç¡ ÜŽµ,f…¨Ý†Möo%G·ÍšFo#G¡‘^òÒ 9Ð#Óß<È‘AI`ü˜¶Ç Å¿Ü*{ÊnÛäbŽÎ|Þ#ۦ𤚚‘ ™~º}Ò­ó×ø«Ô¦tË„¬Œmh,0#ŒÒ)K5],è“%öwªÃ/ÖÔx´z[iY)× •ËŠ¯ë!.â ñù&ý^µøËcMéĤƒºÙ2žjžtc/6îÁ0m ‹RªØ†mQÁM#Ę-ä9t! ÌTõÀSUAß‹ÞJ5L¦ê éØT2âg¸üc§uUžUœZÜd†ÂŒrF}·ÕO7ú«¢ÀÒ¸s"9·ýPuXjÀÒ¨¡Ïǧ°LÎß×;õãéøíN¬§mMEy¥Æ¸P8…ˆxPš„‡„ ñFî:·•£õëlÖ ”®ð"L1‘M|ð´&1v3Õž)1&ˆÁtÜs¬JØe”ý²µ© µG5T“Îò§*ËUSÖ8fra¸˜@á6§ìt¤|ò3ÑIy .ÄåCiòðE18¶ŒcûHR„ -HÎášjS¨Š!,®—j†.ŠBc^’ n™!&±lrz5Ë9-à ¼7çÞ}1á5ä¡A·­ŠÃKËdÆÿÞÑ„ª u!!Ùªº×ž9»}/Dqy`f$@\Hö"Ð>ß?\Ø9|fphS2ÛT6dªä=mYP¹oU÷Ù¢v.ÊÎoR{ÉçЈ­è\ßž7ví»Ô¿ÑÓî¹IñÚx»síµ'zÿ±~óŸ»·|¸~îËî—ñÀø[w¯©ªešÆ([»¦kªàç y2ÿ©Fòù¢P¦¦2é´  µ¸%Ç‹$Púá.9áý0Kq¼h‘Nòƒ¬tÈñÚrÚ•êÀD']9שŒlÀ'¯+Ù8½ºØ†R<ÉHfîyð?×È©u|Ei)g¨.š0ÈÐFrdËìi¤Wººxq€ÛI^Àg¿4Æ1¤Ÿ”‘±]úäðvr¨Ÿ<ßGž${6ÎÿZ2°¡ƒìè&{f<ïQ գ볥!ÃO¯˜xx4â»u(èùlÇo›ªË4›LCgšX@M]è*J³ΧL€›WfØ¥Lç* 'ŽwÝr'Ù8á6åœúœ“XÒƒ‚Û€á¥Ü`š…Œ9ñSµ7R‘¼×ðL¢xy‰5á…Œ–3­†Š0׫™]ÃÙïâ˰ǻ^t<Ù<é5Ov®ˆjy¶²Cœ¡F[aaRª é,È!VÂTed`‘öÁÊ„Ÿ]Yð¢w:—Ž»‰Í%Fã¶Æ¨Í…jX&£ïÄën$ko¹ ¾[?†¹œÖ³ µ@˜jan,a´šSl|¢—éü×ñúñ”tËM7†Kp!.Ç  Êa…Ü26Ží# H‚´ 9Ǫ*K8D&,†žÜä åÞ0eûAÁh¨¡¡ü4Ö8–Œ¥ï¦"sþà}¦FÜxˆM5‚a\^'5¢ë×64&Îí¾°ûYwô™ªà|ßXâR‘—>ùõò®ýzžÆ7çwì{sÇ·Ïトô>óNÿ={ íK;†Ó>™Q`7÷^Ù1ŒövÊÁ!“ÍËÿUB‡F®t®¹†z÷ø–÷7ô\_¿eÎËî—ñÀx¿»×b¬£ÐÓé "ññŒ|¢‘|~ÝÚ.þ©F^JßÓÈHÑR#ÞljäûY9ìq—¼œ&»£Ê“K´gA‘ÇÉH’œö䤯tHzEu’‘.r|5y%C^M“W=2 ¢`y_@$¡‘—âÕˆc%4²ë rxÓ¬iäh?yn9~ôÏ;ÐKl’2Ùÿ 2Ð=k—²1«vuðd‹–¨g‘GYm¥(±¤UnQ—•£ð„Šm[äé¯ÏxÞ#˜zÀ/2 [§¼†+N[Îû¿{ÛVäR5~¦å¯+b5Ó©Z‚7$cª` žn M¾3CŒÙ*\(†¦p¥¡DA 7¸TmâêþªêÛn¼nõݨï6Ok$'©Ó|ÇL¤âÿìhÛ5?AÍàœ…$J¡ £¥,6é´ßLE}¯!—ŒŒ%ǜȸ)¸‘‚·bƒm™RÑÓ,•|/~ǩɹ‘œÛ0éÕû^]!Õr´ªBh=á Ë5,MÐ_Ä—úéZ¹ ·)ï¡óµ ë 6›¥v)ŒU˜F ×PßmÉ$Q¦²r®[ÂR¹(lwEÅõ­~f9–‡y¿º@·¥tÁTIÝ1õW1iž)§}n{ØËµ•­‹tà†Ã œÍ5äÓ¤¢;\1•Z>µ*æ{IB^âÖár ‚¡0 †ÅàØ26Ží# H‚´ 9ÏU…K¸ â­(C˜©ØYâ¡Sþ§3EàÝXÃÝTlÜmºíEçüÁ»ÿ9tòÿf¿Þb£¸Î8€ÉÒJ+FG££Ñ^´k.`sñÚ{õú޽;{±‚ ؆5¾Aic0¥”8MÕ".©i”V"„JŒ•Ж‡ª­úX©jÓ‹Ô4A•BÀÆ»ÞéÿìÒJixÀ­çÕ÷0ÚÝóËÌœïwŒHά³øœžÕƒóFìÑò‡!tgm+Ãà(×ÈI€x{àÈÕþÀ¸ž>üþ¾ã“Lí;~¥çÀÏÒ‡&÷¹ÔýÍ·F®<1Ñð¸>0ZàÄÿ£‘B×S¼í›ƒ# ÈÔб]FA#”JS-›ÿÖ¹ëã®Þ¿nKøD#_ÕøCG7ölLaVÒC2vΞËÚÿõÉÙ{ÓiF×È©fá\;/ðÀkyàz¢}ѪêÅç âLʱmƒ=åñZíú#ÂK–pþyab‹0QðÆFábR8ß.œ³8EÎçã@bäݲä<ørã|‹páëÒ³k=2*6O&ìíÆ{M#/Ã!ý«C·»•à*‡W‘ÜŠäR°›!Pò €WYDEæ9´E‘i%Ó|D.z&¾à~_éN¥ÁFy­Y¡HŸ´ÖÍšÁ%ßÞ3ìöðl"ôÛÆX¢„)¢C!ÄCÙ2Ô|, B‘¨,A>|/‘ø•ʪÊ÷2Å+*TdÎýežÙdCVætÎi‘™dˆ'·Â³Vd>¶­¦ý+ÜNÉ Š2Fæ.DMº°f…j¾&ÉjýY3:k†§õ@6˜7›:ŠA$·ª°R‰z cÔ+Q§ÝÖ”ËWóûÉêŒ^e[Õ9=>¾º #¤(_2î;Éû‚ü*°Û"³zxάÉÂ$máÏ‘3ëWù]8Á¿Ì(gƒÇC[Y–$M–¡&BјJ£e¾&b6Tˆnñ3?~`$˜ Bs¹eòëš*»-š¨¬ð}£jn±êö» u1‚ñkèF"Οl(Ÿ3b#p“µêy“¶(š# R!¡'?rLÇô±X ,–‹óòšµ+ùÀc¬\-S™OÒ4¢<2œŒÊŒ94tï¼Ũâ¶Ì}õ´ Xfôð¼Qk›±ûžPF¯y=°»:U¡Ã­©wúCÐÈdÞ ŠkûÇ.õ¸1xô½¡±ÉôákéCo§N]î;t­ÿN Œ$øþÍôÁËC*ÐR0 ,ñŸ,,F¯3}Ü!HË5x´#T‹Õ /×-³óï]Ý·»zþ²u÷?:—¾ì>‰GÆï;º]Œ¿›D"]]2Y‘ùÏK$—ƒFNŒwáí”øqN‹ g¬‡™°¸F~ÔÎy°XUõBÈüãç…VQ•plt¹}^IR|TÚX& 6 ?èä¿Â!ˆ7ЪY8Û$\håC:×*œK—ÚK á|ʹ-¨ñ¥‚ââØ•Æ{M#§v ¯äMòÒnêR½¢TBd‘ñʤê’ÿ-B±ç»TU8Ù-ÙÁŠQ%ù>)Úi-¸ßqt½GªÝà’™‹(*ý±±&¿.ýÿ8q'Q“MÆí¶wC«ü_ÓxQÖœüèÆ…1¼\¨¿^hEeЀLèSšô´JήöÚ¶SÑÙddNå¬XÆŒÝK†f’ÕY=˜Ó«ñ½ 6¤êzUI"²D)²1É9KJ\äÆhΊçŒà}#2oÄ>K„æõàœ^™ÑÓÉx[‰KR(.ÊzfuÌM¶4d“$gĦ“ §*ÖhQ”¸™Ì$Qe¢JnÆBv[ÝL2>¯×ÛFt&µQÖ­úë¡u]¢&;1…ª¢¦¦È¸dLvi"hFáÙK!Müy`Õ'‰H`uÍÅšˆ¿É×KS4™ü2Re›u™D¶Mˆ´ ¢9:AWèÝ¢s, Çò‘¤ AZ0ñÇ {ö˜Ó6æÈ»ë´üÆž‰!ÆœÖ1§åkC9säQ»ù³R'¼‡¡Ÿ¾x¿Ïˆl›cQ DdÉ9é-¨IÁɧѳýõ»®÷¿×¸õýZËÁŪàVë!J‘Æ}×÷l¼éY8°ÀÃŒ^/qšäuðÍññzKbJ@,¿Ü°÷¿ ÁpÜŒ.BWw¼ÒÒ~#tñn3…ÍÕ݇ìi«Î'& ü§5Á‰-ã›ê?ݼã¥F^ظ^\ÁÐó itïŒD¢3Z4º°ðÌ!QúŠÄî´Ž£Ç8=“ 9†%mnÒ¿‘œCÑWȰJPËéÛ¥ªª#UdÀK.xÉ`9¯R] l"ÇÄ$÷긽žÓ™b’Ob F=ØmLaYÖ ‹Ëàâj­äXéÇddÚpÙyðœc°˜ôûÉžRÁÀ@#,Ãé*ò—R# EGé ’ž iÛJ¾NN„ȉ&ÒÑHº›é=®]±· îO6“ãr¼ž†Š"HÞj¥=,vÜŽzr*hض‘gécdt½kR"˽·/¢ (™3rަÚ"¢#ªhŠ0Ðë‚”‰lhŠgAuÏKV mVò,Hš ا)Ƀü`è9š('>Œæ¸¢!šÇ:Ù€'´[Ù…%OÄ–$ ˜-Ò‚äh>˸h¨˜¾¾¨d ӯ̖Ý_ J††iûòÇ‘4Õù Gyݲÿð¾ V‘ñõÙŸÆ4òÔ[¨&Q‹ð<ŸÂ.µ¶ÿªõÐõæöÑEzàY\ ¶!nî|óRhß¶ÂäxÝÆ \bL(0 ÄððxrªbÛ3\ îGÀ!߀"Pärh?u³‰Êª¹Ü»’°Y˜X>Å$ܯ NT&ªêÿZx©‘6F‹ÊY#yáèuÌÇìñ•W4¹ôö;‹É àÊm±A‘Œl Ce¤/V‡e2T±dUõl)E:@øI9£’>ÙPùH$$'ZR9ygz%ѧ2FÆ(¤ë¸Tà›cx]üú2TM†¯£32ñ“ótÐ>ÿÜ:+’¡XŒ(dD¥‰ û©‘ú …\(§Âpgb×á²eÓÈBúKHÊ1ºD.Ù„L93I÷â«ÿÿŠÞEWém*⎇HO+é®§9µ‹"äD él¡üèm%!ÒQâºvÆ|ÒLŽÔÑç]ß`>ÛÉéV²kk²žÁΩçùPZŠ&Û–}{ÞÕDuÍŠ¨žù0ɼlÍš‚"høò&K³´²‚?yì'處câ œIÏÅg¥†ñyÅ.µheù´4/÷B^ƲDXv‚I³0‰"0!Æ {½¾‹ñµëW¶w7ë·ÞÃ{Û).ø¨9”:`l _k;"j!@ i¡JS¡B[©ê?mᩈr˜Ýí7vµUÿ±ãzÿëÓhv<3ï½™7ïû}^Åol…ƒ~8èƒ=Θ}Ͱ­ ZlÌ×a¯[¡Ëáæ]Ò«èeû•k ‘CÍÐÙÀóXRaÅeO"Ñ^Û—>°˜}dÔ‡±¼5fLÉÙ地)ëiIzȨ‹Xò¿2ìNMŽ…kPÊH–¤Ë‰êÏë‘+¹Se‘Ws¦Œú£.êyQ E#¦ÌG&ý?"rzÈ”s{CHUH| ¡¦ï¯{·YÉæ ÖÈ©@bæüö½Û˱ukÉ«nW{P#_Ö4>Ÿ¹eo¸åp^¯qêpÞ¨U†µjÓgÈ3‡óa­çz->÷Íj×½žv·Æ­~ödbY"‰"!ìé3g"¡È³pøÙk$„¹üûKßjD°¯ÕH±²œƒ F*3±ŽÌæúƒró1#Œ•ºP`>Òä%ÀP9Œ#9*ÀŸNSÔÙãR7ÖÄéV‹h œ <ÅW¡Y³ŠÛb…î-p¸¸`À§œÙß=N8à_ˆFúšàMo¢V‹o9œ.’§ÆÜ¨/ïK!cÚ´Iÿ¬,3bÙpßwµ0Ælˆ”›Brñ”\2©[©æ”zŠËqD¤îxÍ”©à™œõИ1ç<6êÂæèäED%P#¡2ÔHÖ#“.bJ›)˽˜•A –q‚†å6ç• P#˜Ðßoê:9\tMºÛÎ6u5äÔ¼Èð4‘СM³;~ãíøÈÓŽ'¼ØiÍ\'"h<'ôÖ4œ÷w¾ïm?îßyº©EqÆ»ó;jïvp“G¤´!RWjÚœFT{nÛ7Ÿ?ܨó^·o½Uïÿ¤Îó‰uó—v׃êÆkµÞ‡çŽmë¯9?¯ó~VãºWç}Pç¿aÛ­~¶§h Ñò<%äâ¥K¨‘'33Ïþƒ"a܆ffþpé2%œFXR”¬,†‘r²ü4RA‹’[‡1ÑãO ”ãÛ7hEºBE4úx°‚/“YÃ&°@y6™Sf>˲|’ Ú˜V+œw»A5À¸F áJ†a[Ìåàû!k]M²µüZ5Ÿ&‘â$hÌáúí0X©ô3ˆ§”~Ž›· WFM#ȳ +h²(R5G§¦ðóÅ¢ˆWÆ›nØç…}nðCWeÝÀ <ΊDA­áx‘å°äÁ©BD”f,ÃÖ‘"}Ðç‡~?ôùÔ®ö7Á@S\êKXïðTTÕâì¨/ïKsæ´œ5e@WI]aÉÖx©#yÅžU+êcE½Àr„‘ˆ†j4œ˜Lp%Vý6+ã‰sк'æ¬%é93l~î÷"æ"$g‡MYË2ŸÊ³î‘1gtM ¥Œ¢†ì°8Na6($@`fŸ¯ PZwŸõµï4Ù†°’ËsM]'ZºN{w|ܲûWˆœ×»k³ c±¢D\±Ö:ñ ¶ˆú ¹ûÃm?Ãó¿‹Fævº­õX¶`PîÒçáp£FîÏjäº#ú6êÿÉ~½Ç6u?R$K–®®ŽŽŽîÕ¹òõUâ4!MXh¤Iœ'Äöµ—4 vB`¼œ‡8.´ò i „G‚Ȥmm)¯]·þ¹?¶?Æ4­›TÁJ Öñh!ÄÞwVmýÏQWWŸìc_Û绾÷~ßïÌ8­—õ ûJ—&K\3ôeÊBm;&£æx¸»F@gÛw~ì7Ð]_R•2QVZ+«Ïûv´}4rõõ½Ã-ÁKšS([W;/¼¹&zÏ·ë|°¿ 완¾ÖÈù@ï¬F¶W0X ÔºZQ÷©ghúì­†– ñçÁÇý/0ìVcëŸÝ[V”h‰fJ5Œ5,&üë ÏãõÁ·K*~[³áæÆŽOÜ[â•§'íJpc’¿ß»÷\#áð7@0ÉÏ5BòTt²ö¹FB5hLGã•ht»ê¬ ªx?SxõWã T5À5LMIXaFYHEbÂ̱Õ¡‰ZN‘ŽFu²óq¬ó†Ö Ó «:4ìj¿¯hT1ŠfY¥ŒP‹Ì È T1PÉH±™ ¼„7 uhÜ…&œf§lqÓÈx̆F«äÚl’L’Emõó¦‘Cè8¤ .üÂzÝ@Åt*' gg 7ò£á ÚýC©8[eJªÄ X kËÑþ¨(@#ðõ9Ì ÓìBCÔU ç_¤L#4°Ø÷ò¾ÀñÄQvD\¹_T¦ÁÈà. "pD¦IP^o+‚I™”IÅödõ®mÕ4ðÙùÒ¶bÆUòX/Џ ã~ /".1£ƒC ž:f5’ßVš)  {,Ñl5鮞+þž‹þnèéÐ߯vÄ®‘ ɼ¶dÅ˪P© —å–ü²áMþqß[ÝuëWedQƒÑL嬴ŒÃmÛ'ßëê½ðúžºö\öu¿ïÛë¼_Ûé\çsJ¹—åK°QX’ákU§Z@#·<^ÐÈÍÆ¶¸ó`ãoM­pìSceÕ9L1@é`ý"[$É(ã?5ÎÚëWìIIý£gëgMqûôä4L±&É ÆÏ¸<"\#3áÿ¢<ÎÌÀ¢Àr Š^6ãýwV#cµ¼õϯF~ZÍ-q¢…àe=òY™‚Œ032¬@ýÍ‚º‹½T™Ž~äDgœh†N•£S:ÿüÉJ4*€qyì *Cglh¼.á Ý  Š€_"<+K¨Ú\˜pŽÔƒŽÕ¡@©Th¡’˜¡,Æ 8[Fƒ3Ljã·ÇM#! ™'En*À_–Œ‰a½kÞ4ò“Vt8ˆö{ѱN´¿U,Ï¡”$‹– äÍèp'…ÇpPìm¡3”,c^:ð¢á4È ÃIóÔðÅ ìBýë)“ŒX‚¥œ;QŽ{y_à;KÃznD_q¿²Ø,‰TVT‘dP1‘2‹@TB ªl¡½`ZJDwF\+#®¢Ï+–`"μzÉS;´¤øÈ‹ˆKÌjä‰=§õNe‰‚ ËäKÚ…ýtö]êìá6ðwÏA#ºúÀ3çƒ}ËM†P«WIÖL*5 耄Øc–XE^aÛjçÞŠºÑúmïøwý·(2éÛ}%Ø?gœíì†Ì$®%Ëitc”^w·ÜnôF¦Ü[?«÷N5ùâ΃Ž=›ï6wü¡v“[ÕÁ@³HŠMI‹E€(¹æöYe¦`KÆ‹Žº»ëâ§‘ÅKà„I‚ ™‹„#O¦ùó76n’pxÍê2™rp†9Bk¸C&ªÑh: ݰzÞºê8„‚v\h¤ÆÐleʰ–FÓL‚DL"ÑSѾr4±MÔ¢ã.4 &©å U£SN.ÉHìù€aÆ€µRq¢J™òa˜U¦¡“:O ´s¦:š[MÂQª—°l0™Q™y²ø^Hàt5:^?̸ŽöÙ)1U-’*9­h°ÇÁvt 7÷¡hšHüè ¸"ˆ´Ú”œL3Æ k9k1Úß‚Ž8TùÐñN4äUWçBŒ #QQøà‹Q±Ä8ï!?Ïœ'ÜŽSÌf85"ˆþÓ^ø•+?òÞ §õ‚GzÉ—z~ÄùjÜËþ·¾¤-zªß(³Næ-íOSkUœ/J=.VHK¢|*+ùZiöCÐÅ÷„_Äw*8r¨í3ÎåìÙss4‚¡ üe®Ë=—}ïz ¹ÃøRŒ$€øÈ×3è;Þ¾#Ód&|%B‰,1ŽEܳ˜@µ”0•E [îe3ßËà}kJÆ`Í†ßø÷Ä:/P䪿çÝ@÷{]=ú{.½¹/ €ËEŠ—1vÓã…N7Õè½¾®åózï­†Ö¸ó`ã“u›o4xçÚÿI*a¥šå÷5÷Z ‡f,ÜÛ' @5­|0Ð"æ¤b¡¦°$¢´ Ã~t4•IPËJ·šB¨À(Ø‚†üèíwÅ¡9L:«ž¼”÷ЉH8‡ÒWqxDôìˆ3gÚa}`/“„õÿYüÞý(º¼ ;‹ÂŽ’gŽÒÇzÙgŧñرæ‘må´£8ì*Ãg9qOøE|§â!×HéWŽ‚g wGîà÷24(s2U‰ÔóZ#ôôY\ìì™›F€ç½£m;*2²–š´TIÑDª ( ó0I–¢‰¶*Cõàv&„ˆ[$¶¿Ù;éÛë¼-L}®«÷l°÷ª¯ûg»,À ˜B¦¥ZâTï€7›¼ýÕÈíÆ­Y»ùW¶†±_÷1M¤yÀ‰ I“Éd2™L3MKãË‚(.®«òV\yéL'ô  ²§”B[Z_wn½]QP@‘»Þyžoø‚o÷ÿå’ýk³wñÜ]qu7—»K.».-mï÷ Þí™ËýQ"Öl,¿4ÏÌ<3Ï3LÛïça8N+hÎç—=¬vu¤¤Ò,S–¸þO»j?+­UÓ4>ûú­K±Üóyh«RN²¨‘omާ6Ç\UƒNÐàç]j1›C á_‹8yÞ+¬å ͨ98n†‰B’ûS¥0^> bóËÓˆ|fëÓ2ø,ÔÞ-ÌêØÄwõГ#2ü¦ ÎcŸ|˃©B¸`$)Œ='%˜TÙ‡2‘–8LóÎ ,¥b8-ÃÁB˜–È~ŸLR“fb¤q3|bSW¤P:NÇih!F-ŠFÌdJÑÒÞø¤2Õ!+¯eðo£æ7­MÄÿ%´Á(rÌ '=D2HŽAUÊ3L<Í 9 ÁL®9Ú Õ’nØct¬†eWS »q ÒŽ»a @å¸#âq‡F¹Ù]…ˆg²Âº².$eŒ[ƒ²aÁ˜‹>Lá ô“Máïå´gRê¼”êSübÖ¼”îG™ÒBx×"2,#`2øMÛžaô QŸð›z­ê1 5‚nGÅmåzµ€‹…·Xa¤ÖsKIvÔÈuE#h’ˆ5âê¸éê¸ÓúË ®6„ÁyWÛØ^÷pU}M¾ÉœšµcýÆwµ+õ4«g8ô .â"jb3E˰çàEoG¤ãâ„o7u-jä–»óô×J–Gî_µnã“ÊÆ'6Ç£*;jƒ7£ÎƒW\så{ÿ¾ÛõëÂÒXŽÆòå¼²¿ý¼¹<>“¼l݆¹Òš¶Æ8ŽÃCUI›¾ÝízA~à³@Š|ð °ð. §Æ‹`˜0“œxy9ƒœPRõc™˜äèèÉÓe„S&χÑ\¢‘I¥ó¨L$€íéB²sgUB £9â4W ÓUÀq*ŠWdz,œ¶ÁT™É¢sÆ`¡v°}¨Æÿ #Ð|,´ç’sÉ¡ü¨i„ oÁ£V.cÔ«iŽÕ«I º‰FN,"Ä©hÄ9HœÏs´…So¡4\Í&P4dÄCÏ^8³Ÿxã„úbÊb“õ±,E‰†˜ã^rr4/I#.rA¿ <•*–ÁE~wZ5a9oÞ˜ê— !1ã{);,gLéQÿÙ_¦ ›2°[ASz@ÎÀò›P#¸¹yAÜ‚B–È!)#(¦#Ì¢>á7õZ•_Ìʹèvüœü³8+‰£qµ¢Ò0›5q盉@®{º®(¹¥4"UÁÖ¾kîŽçáÙ¦®»ûzî·ô¡ fÚpçeOÇõ–Þ™}Ÿ¸ÛNÕyû*öº Jªw‹É[·¯J\Ϫ×0\2'LìkÇ>‘k¤ 5rÕK@2ëíî-­Ö/jDÍÚšC4R^ÿE¥}®Ò!8WÙu¼jXkP#¿7¿Ïk9=ËÚ“Ó>µ:r×&hhNܰñÍÑ–š£U«u4s$WúÊZ»ÜóA~ckÀÂÆWvÔšä?«Æe¦†p™Yf)U4ü‘ÿ¦î$ûCáþc±&q§ £…äš>3Ñ6P&S!GÇóÜ;¼ž§WÀ™3Áta45‚OI泪åwP#'h9¼V’ã'›`ÐEX‚$8î\ŠFH5‘s‡½pÒCXâ,¥’WÅì)‚cnP.Ž&9b´nžj†îâÜìwÀ0áÊŠ£KtñÊÊкb6ÅãÂGÇò ¬ê³yAi{À˜”2äì°˜øéj$ mŸ—r¾3fc=³ü¦ì „•4íðK9 b¶ KŒé F³¨OøM½V óRVÀˆ1ŒlNbH^ë8žv¾g¼Úܹâé¼î麭hQ© îx{n"6Üw›{‘ȃKîv¼òo=äôq“£7›:‘=×öu£LfqÓÕq§¹ÞR®p¯)âq¯µÜP4r£µ¯"%KÃhvÖh{ZÙøMEý_ªìOIðEŸ¯¸Ûê¾®´ÏU5\Ü)oŽÓQ” ý[‚V ¸$V`XÅÄêეÜÏËíO*ê–{>lõø,Ûê¿P4ò×*ç[=ÎMÍâ’gifdh8´° …Âÿï ß¿{O#jŽ×ÐRçÛ]½a·sÓ^Oðˆ¯ã»]g6ï:îz+° ²œuB–³2Q 5(å¬,8L6/PçÇòå0&ì¯|&šDËþ®²é¦+ù‹³ (2Rãû?ÔÈ[ý ÁóNψݳǰʩy–b°gÓj޶QKi¼A»ð¼#p±6pÏåëzÀ!7Ö{¯¬÷€F®;<w.8=1ãj 0’ÁtßÑcàx|š¸#ÏvpöW¿<e© óŒs)ÑP:.kdH@Qaֺꖵ ‚g24§Ë`æ±ZóY˜ÓѬ†áxn ”Á1˜áh¨žÍÍàT¦¯¢cЋMЈISîW¬N>µˆN¬E¯ØqÙ|Žåáa©hŠiYE@2ó?ƒD#ý•èxŲ°Z˜¥`(ι õ (VNZQßì©,iT¢S"zµ ZÓB&ަ)žË¤iÅ‹%iÝ^ÒÍ €~ƒíɫÀO¶½¡GãDüèp Ú/SaL8Õ+s¬r0 ÓŶֳGÛÑn/:”³'™—¤3ö‚IÂÊšòL øžQîy~Á´É(­Ó™òÇÊ  ;ÇÍE)ÿìÏQ$Äå !"n΃ž2!xˆ†Iqù¤òaÙ >‘ÄbIxª‘§ñO1.¢qR,´çffdÑ%­Ê¥ñëí;N¶‚N‡‰FÞ t’Ξ¼F*^ÞõJ[§K¿r‰J«¥YXíB˘¯¤Wêæoìß l¼îúÉKß|;° ðóý0±ìœmÛ J9ÛÞýf[rI!Þhßñ^ë"¨P'L¡0S  4’Ãó—œÁÝÞ ÎÆa‡—h¤Æ—r|ÁñÐÝò{{ÃÚ–‡çZ}ûÀj›eÞ" £Rc•S¹Ùê=ÆÕ×Á?¹Â7þa{Ã\×3ìòÁƒ\vù@#·]-8{òK` @ò‹Ÿ¿Þ êø·_bæßáœD#Œª4 ØÐ @:xZ%ŠÎZ¦º¬ &]G©i ð–IÑé4§Ô0,ÍRÙðz³ðrsŒí9Õ"µ†á)F©+zEèT%Š­Eà"+1É`òõÄVb<X•Ï2‹•”–£q¡õ»Q_5™/DŸ¬Jþ*´SŠ”£“ÕäÂ\nM™Fúm2× hŠTQX‘ÅòZÌkrsPo ¢Ã€ê 9$M‘Š 3@‡Bdàq4";¡»™®·re%éuê܈z;P$€öµÐëVh4´¹í  žvt EÂÉç ð‚âáЛö­f–¡1ƒ5´z‘ K–UqsÁT…1a.|`ÒÇÅÿ$,… óri]ɘ¥tÜl”,¥’X2)ã‚>©„Æ„üi ˆ7jʇ;&¹#L;úvò šI‰´ Ý^~NÅÀ‡Ÿ—‰¯­‚Ϭ~J,š2é§ÍÅ“©þæÿ÷1)äO˜ò¦ÌEc妢„Pty¯ºùT#‰éiF tQcŽZˆQÌŽ¢ehHîƒ3Ýy¶ºj¬u­Pô8Q¬Em(êHÛ"fh(Ì2´u ê«B¯V zí|.Ç0X™º×¢Á ROìq‹é/'ƒÄ€ÿ ¿ÞcÚºî8€ ©’%KWWWWG÷êZ¶࢑›ÿ>ÿTºmðôëškë½­ý?­i ®)üÒ×uÕ½õ–7ð©/tÚ&ï3W„Ëlî¼±­4iîœñ÷´_÷t}æ Uî] ht.Eâi’ô‰ª‘…h46?ßâõ14c` §Éj" 8!£Q(…dñR¥ê¹d¦C¾+hBDõÏúL–㌙¸Ú„NCô7lœ—a¬]N½È0£å›×¢s„.£p­H`ê¼ã*Hµè’½]‰&a–&ª¿lÙæ<Š×ð¬Ö˜)P«yM« :Ѹ 5«àß`í hÄN>Špêó.U…ë‰F` €¥³šíÅ Ob[p×’L €FŽu“# ÷U0¨b§ûÐ õMû3Z7Ã÷öDÏ lF»"ÔmⲀѡ.4¼SÛ\[•LÊ„¡dÏ'ÔñP7:ÔΘ‡ÝC瘈¸  âx^‚²¦ý±ÿ_V\.]ls ¥8%'u!—Sª{âú»ÒKwëJnKæˆcì±Î)Kû«ˆd^€ÅJ– Ña‹Š%  ‡-.m¸-ZnK–Å’PŠJñÙ’ö†Ÿ±ºo_ŸË~m1ë0…#×гˆôßûÍqòôÊŽþJYÏrŒÀgRL8°ëýÐÀåàžßôüøµÃ£-UÆløÉ‚Fàá0ÒÖ÷nßÞTçýÖêÛÿnp7Päýþ›Ly°'b8œ…ù?¸^¹é €Ff|þwç—ž®©ÿKüÅÓq´¤ 4Èò¸Ñ”óWçÖᲞf°¶t,<œ1Ãò >iñÞâÿÌÛþ¤û™ñtF¦¼ ‘kÞö)¯ÿSo`%Ãð,6ê U›6'$¦Vò/þ%dÃxbWÿN½ 3°FŒµè ¨4)V£|©Rln@“.4 ,©Bçê3ü¹X€ P:éBáVÍq%› µŒhNƒöÔ‡Œ«Œ€ Ĕ煅L8ÑÌnG?ªEç<¯¬fr´˜†ûÅ8C6ÅåP Ãiµ¥†çŽxÑhÒ*ÆÀärUPéÒÈhB „FðT1¥£y´PVøP#Aâ8žH]#C=äM Nö c~t² e´Ù ,—%èu…ùðÎGz™¦Z=E/çõZo-ù·Wy µFŸ‰‹W££!t4õyÁ!0)¡2èFƒ½TQ.@ZÇ0´Žúµä¾\—-³bÑwH#1©4.Û"Rñ}¥8&›ëœRñç겈´1¥J(¶¸RúO¥l¦ª0ù“K#RIÚøxI€®’9¹8=zUÆäò˜TuÅVx|ýò>ÿ·ŠÂ¸£,Ñ`»W».ý ?[5'ÎIe{rM QDþv9ÜWB‹QA!(’¬¾J6 ËVæ­ýYp÷owüUpà£ÞýȱlÕZ;Yké ;Þ»dùpÇ÷B@‘‹=»WszÌqÐD‰.몧‚ïïÍD#‚…Sé¶ÁÓ¯/|úÜ|c#Å|ØÐúµ/ôbNÇq:gѬ‘ãLÎ×ñŸ4µÍ¶ô<ÏÇÝ&¼îë¸án“Lû¿oj3b€,†×¼ÅÌ%Õ1‹Ec ‰ÿI ^Q5òÖßTqk]£^+ ¾sªFHÊK–ªð†gêÑ™4,¢‘*tÁ¥Ýï x-'@ú`ŠÕ²yŒÎlxN§¥8ZÇcNCi‹t蔈¤ vT¤:/\®GgWÿæ¾Üc›ºî8~$$$K–®®ŽŽŽîÕµ|m9! $¥±çi IìkÏVâ8„w‰cÇNxu0 ŒJ 4@ÊVB;«*ZÆx­Ú´imü³?&MÖ(Eh´§íýŽ UDÂ(Ô]­¯¯Î=÷Þóûûø}?gЂEªlNäp6¡zB$Œ)ÏË0ÂóZœYº…ëÐ)¨ùD ¥ EÙXæÀ!CnÖ8Ú@ ¼†DB´ 3ÓH_€ÑH_{¢¢ŽÑ66N_‚ €Fw îµ@s)¿ÈlBBìPÏF-üx"¿Žú6«7Õgc! Ââ\†"ýÛSŽÛ—d§P"ù êõCܹkj D©È \W^NÜaSÌSö"°¹´—ýuÇÒ¸³,ªX،ӵæ¸RvµÂÌÑ4dH)É£×z2åeI~ù»µ0j+Ž;KâNsÚ'ø MÙ$@ŒcJIL);—N¸«®.7-ËtX­VÏ­Ó ](*ˆ9­€giOøû&§é~MÅ2Y¿,I‘ ¡ Á®—¦‘§»çC]gÛò³ !¦X ÕùÆK;Þ>ïß œp.¸Ž^îì6/.€š°@Öçj䋉žÙ¢ªK›{>îì:². Ç”ˆ‚ž'- Bn>Áh3lò¥ ¾}6¶™õ`õ%9y×<þ‹«aר՞¶­¬]0ŸªUzÂßié­ÛôÈzÕùÜñú?_åYã¿ëÙ8ºÊwÃÓz©¶‘|D–4ûzzl0ö`(ÇŸ¡‘h4 '±84Ï|ø!˜¿Ë2åç®+@'œi$âbV8[®ú‹ZæòÇÝhØÂ•(²…×r®¨€×‚ÁêEq¯É£óæq¼Ž`| 6¢aŠ(ÌŽ•—¡‚°p£÷Ý(R ÕrQO°ž×ó’ Wå¡`zýR\¨—0>(Q õU¢…],nÉN¾TÜÙR$ÁQ0€"¸‘i¾ Å@”¨• ¡wýèÝ:ègíT‘àhG‚a`Àƒ:”`’ø8ß@E¦hÿtt3:ÔYÍj ¨•¢^@ˆ(ŠP¦ó"ôóNt¨3u† ² |'z»õìY7§QC1®ÉÁÊï;ŠâË„R‘þ²ÿbºg+;À”‹ÇKÜQw®8k1éÉ\ Æ)I$ŒËT. êß”˜ÆíåQgñ¤}IÚ'ø M9ŠbŽâq»9Êf óµþ³²hoS€ï)SÌ”‰n.§®Ñ ±š¨Òžð÷LðJÜz£TCÕP>¡ò/ÈÈøtK÷ù—€$\Þ²vEÎø~¼[i|=ŠRž¨ û¶' á̶ž¶uÿ2° ‚ÌãJsÉ•àžO:fF.¶ïúdûO!ÄîúÕ©$æbº£¸úv³ÿZ³ïŸ×÷”F 3íxð-ëº7X*gꉔő_Õ4dÈTÿê1•Ü\ôå,4RçZsàíËÕ¯œÖî6FZ7½oÞö¶Þi ~ÙØ]\)P0 A+i.]¸{ OÙã‰B' ôŒŽÜ‚²§!X¤¢¡<…ëQ¤…Áþê3Ì–«ž´¡A סa7ЏÐqèq3Çò¢}5¼×(”e Ez¾6ŠÐa à'óßá:4ä`xq²Rvs'‹r¢»Ð[•Xâ(¬Ú¨€‡jØ9ÇêTëÊ2´TÃqd™ŒÞoD…%|ÒÁ»XÂi¤È¤vÃMS¯1k±`ƒÇòV%h$À¶ý†³E#ýÜ–5òâ…ñÎgSxùyœ­C[Zб édW 0IêHÊ4"8*Xñá‰s§^Ë›P*&œ%“¶ÿ{%Œ–'"€ùe*êI(–°†>_‚5À"‚A‹ñÕr3 WŠÆëÌ.lž²%•ÄP¢âìÅààÑ'øñ¸=³k4â,›°W€ãO8 §ì¦,-üJä±Lh‘X¡”ä\N} ?{L™‘j’Ì´„0n³€’PÁB'}’ÏtâœW=ÎwMSvã#gIÌn™v–?¬)ܳYîÛ¬ÿ¥¾Îc£¸î8€? É’¥•F£ÑèiF3ÚC>0 6q!ÆÆçÚ.6ØxwvcÇöîzâ{OÖ»>€¾p)ªÂípø¦Q’†û %êmÕ´•ª–?Òˆ1ظ”Ò@ìµwû{k HÅQ621]ýd½Ͼ÷æü~žIdU Zx>1»·fÝ'Þ-§š¶Gšþ¼­§ê[7w[¿åœ·åRSç¯7u–-Ë€Ç<ó±‚V¬L¸¢ŠÏ‰O„aa‚y>5!q‡¹ö7oî8íÞ|±qtr¶¾õœ·ÚÀ›¼[ÏùÚ~ÛôóHç(:áo»ÔЙ·(DŽáYáñ_ËkçK##V÷¿-ÐÈ5ƒ¡nÜì2ÙGªc&ç(¨ÃâºmvÃvð8¼qÓh¿iõÜ4»Æk?µ:¯˜WªýŸ™ã„(Ž‹ zŒš]#‘ÏçK‹ïƒÇÓp¨t2‘_ÀoNê•æM#=d&ý%äTÀå€)µ CÀÁ‡R'£}¾0¼á¿s§‘_¸ø¼T.JËò€™œƒÅÑOh#ÈEˆIŒEÍo wšÐ7Úí‡ýÑ[n´×÷¨v†5Ò±FÐfk<ÍQp‘h™6¥ùé×zuH—9ïqð=k6<–Á<Í „‚°Æ˜DÈ,ÅñX.`e,‹—“ý5Ľ6{RÊ›u\Ha½: å@òBN=Ôå|#eÿgMzä©—ý‚d‡ ·¿#µHé!T›‚µ©pÈC«ò–±²Fy©€` PVÌÆ¸wŲû³k*¤Ï = B]N@§~¢ˆ'Ç¿c>sÕÏ‹VpõRn\ÖœûšL8¢{šÌimÖïWf'±Ñ šU1bB\ü‰ [.z6lîŒX#õmgüí§6v÷N@»Û½±0>I‰ B`E f±œå”XXBà ÌÁSŒU忚Ö\RÞ]S’y¿¡õLsçå Û/úÚÏûÛ$'½-§(Î碯~ø¡¯5ž!Χˆâ ›¾4NØ0!l çÍj°dÜêù‡Õ5dvÞ0;G Kì·,Ž/¬Î«6ÈäºÅê6Ú¯›Þ”ŒºEK~¶8y`eÉUèÍh¶¸®ÛEnW9¯W9"ϸÉ~­Úûfjv)9¬Þd1ª¿TÖܨ¬5¿ôrtTTdO@ÈÛÑ>?ÚëEû½d&4âýA:róJ…(Â+"<úïjˆõ~þãà{Ö¬ahÆp²rQƒB”'dJ?³(ž¬À½šÌP—Õ+hÕ!)czöq'µÀöP“ ™ÖçBMDž¶“3ÙGâ/“ÔSŸYuY!˜õÙ÷¥‚ŽÄ8–ƒ|ÄX!)†bdñüÈê¼Pé¬'LK¨CaÍ)€j*ìŠÿýú|ûyÁ*(åNir§ty4YßhÒ'ôÙн–Û¶$A)xVb¡*¿èdãÖ õ-Çü§ÿ_ûiÛñb’›:χe²Ûêpé+W-M[ÈÂ-ËÂm 8÷€œà ,;s—*)f'Æó¢>-Û[¨ë¯m<ëmN 7˜Ì˜ÏeÛoË[Õ.¸{Q”cl})é¶Õ;_!19Æ,ÄÐi\­\wÏì¹mõ„7:n‘¶ß03j¡€.ŸÛÜãf×›oÔæÏZŸÈá…<ל”ü·Êší#V÷ÐZô9nrG>Ÿ{æºk6ç°±îJYõ{…ú Eå0@èÏ6çû¯[+…Òʼnc&÷°¡vx­sÌTých´fs†ÏƒóšÕ›'W³  ™€O;dæ3.øÌ€$˜ NO+ KÁj ´+ÛUzJP?P¤Œ„òœ«„ú4訕ЀD‚¾[3 èH)ê­@ËÐ j.dl™X—,O‰ÁÅÄPtM:êQ¬!ôD>. âõéÑ`:RE¯ÀpˆI´À§ðhÃ*ê@•lŸ‰«X®¢d*SJU›‚•“_õ>ždoaÒ|ilTƒóÖ]ºàÝR¢²3“*p(‹ÚÖ‘ôßå&*˜Cì_,Q ȘMŽÃúüè:=jµGíl$~ì߀:œ²7tt]%ÚãB]^Ôq‘ít‡;ñG<î¾zF›½†åŽæ£w½’’òÿRc6ˆ,Ï&#$U,cQÕ(…×ãÄgÖÊXVŠ*b…šü‡üå´!ÝŠ .m¶q“áx h2§4™A]NH—”">o)‡œmmV0lh>¥œÙS¢?oBRY’6¡K2…^+ø¬0·éå8¥‚V1ѱœ¬.A1´2#T¾:¤Y6[?_i³'w8!8 }ŠP‡Ý“{`:<«çÝÏ‹Vä)Ш:õ„”ФO“$ÌäKS¢Gqª=ø6ÜÔqÂßiúŸñ‡HÎùÚ.úÚ/x¶^jê<×ÐqzýÖ³ Ç6lër4¸ŠK _y5ITª¤É‰MÖ X.ˆ˜Iаˆ€¯ ,ߢ7}äÝz¾qÛŒpN4F6¨OÚa&5kô ÃðrQ¤è½¹ÅcFÇ|id¸Ê1j%º5Ú·@&Fûݵõ÷ öÛ&pâs›sh­ë ›kÌâü/õuÛÄyÇü‘,Y²N§ÓéNgùEqƒAE ÄqÇ!„$~»#&!qÎvh ;ç—¡Ë‹“¨h¡ YËK)M H+CP )††VM“¦U릮-…R /¼•רû=Ýøosjýd=vž»ç¹ÇÑóý<×Eï@MÝW?t¾áj8_åMãXŠ€MjÏÊùÚ]SôÃ%и쬻&ú¯Ô¦®,ñ•«.ï÷¢o¸6xÝ% 9}é˪—®¯ª»ãž\w¬¾[öH—]ÞDçg»>CðÕu]Xe¶¸óñN«•ªœ%ÙqÆÈcÄ2™ÔÈØÄ8n$Þ=â¿nÚMöLÔ\†úÔëÀT蛺TíƒÛZÐz[@»Å=Õ¨µ „s1¹,Y@rœ,–§3¤’ 8š#8u:£¦’¨ÊDïU£`>v ¤TLJì±?nìd’I¡“§+õÅÊeÜL‚“úUøJÓ:NþtžÔ\^ŽÞ- }¥Ó©‘^X7›m/ü"%À*jePФIbM9ÖÈ[´=€ºýS¦‘ßQS-m7Ê}•hk=êj@ `F÷:ÔÝ€v…PWXQ¢‡S©UQÅ9¨'2c[E×¢ "ü uÁM~âЯz`ó!š`È2%}ÏZ<úóIdá|Œ”©ðöͱL¥N=XVãËÆmƧVœ/Š ÅöeÃ¥†qÞçõã¶Å7m “Ž #& 2‘ˆZÇ|RE$«ÉK0lxœ}cO|ùÔzdÍ FxÞ»–ìqÒ?;.äÅË‹c¶ÂÛ¥_šrÿi2 ”‚ ñð 9ÉîsŸÏIhá1„àAã8_¬‹ÿ@"QÉç?U÷yÞ*f3YóÆøÜ [ö8¦)hségÆ,–&ÕAjÔKTºSáNˆþá¶þHÊù8Øx8¹þ50@¿Ôöi¤ã hDj=ê€ö'áöcÁ¶ÃÑCM}á–î5Òz¡Úœ‘5—S3±;J%˲$A,­¥˜Íâšcë;O$xóQ¤ýH¸-ÕùœŠ€‹Z™YTâþirùiGí°sz(¹?ä‘@àhÜv5ü°:ô§ª—/z¤KiÀpúÀ'PC5¾A±Bù¼Û—ÀFà3›GOA‘šûÐìøþÅôùNô]pC7´/¥>ŸZÿ_žž¼’¦%¦7 ÌíYùoåÿ¡Ü3 Âd¤[¢&¹Tãö|UýÊåg¿> ‘A§÷[WÝkíÜÊ—44…Ï_$UU¹ Œ„€:þM‘ILL$–øãÄø£ÑÑžîn–& áÈ&«ËA}´‚¸íç§,U÷–¡Ý‚¢ÍL8n§Ð€çe4=SI°Q3ÂiI3 .RÐzZ¥”ÏœiÑ v´PaÁ@J9Í­h·õ±Fúì3ßqÈÊgËÔr-Á¦Á°£%é4È‚€S«lu6ÚãÀ={A> –¼W5rÀ>myÙœx|nï/Eû´¡DC³,œPJ¹<'x·„ºè­ú)ÓÈžzÃ‹Þ $P@o¯C]A´#ˆÛ€Ÿm h‹Ÿñ°rJÉr岪—çó4(C6¸POwÞú“æ³ÝO.HgA¢° QD¾þg”É4òK’Ò(H‚Áÿo,C8´ô¨½(ÎçŽØ³ŸZ­Ó¸Ppßšpb‡Ð7<ôI‡†¨²BÎæ?âMìw¬y·,ywì)Ï2š‡ón˜õPÐÀÈI®Á+Î÷˜÷ȶ¿[õ8+…¼›|NŒ/¸g)|`__aŠ ú˜mÑXrÀŠM"*ᇇ|þmkî5sÎmsöˆÕ0 ÜóGf<ëûnh䜈tL^žR´­oÒª5 ¼HòW ûEµïºKš.\qû‡ÝÐÈÑ÷M÷ºÓ ïþŒÌÖ¬ü]&ËÁ}¾Æ­6tͼ"Ö_tzA#Wܘƒ®ÀÁ¢rмÔ$ûùÊÕ`P ÜCî€äR7Õù¼o]¥W«à0Y [ŠŠ 4 A…<¤i5ݬ¨©ä¢;0ì‘΋õƒNß³^Ÿ±þ†+pÁ â.qÀÏÆRǰ¯oÚ ‰ÿh'5òòÄ—èöÇsç8†$(FGÑrç ¨¯ís =ßS–ª}©N:ZMꔳHXGFK±ó`¶´’ÈY-­a šãØ9™sh%ÓP,!O_¨‘½î@‡ªÑ¾<¥]•©kG}åØWï ÐÞ颜ŽQÉFIÐ ÍÉV9O­ðšÐnt àÑà“õV¢½h§´L›Fz+P¯õòX#û¡JÐnóŒm«t ì$`3Z8ƒÒ¿§m›:lñÍèÙ€º$´#€zÂðmHhPDÂ8鉠 (ãà·b!m)%ó ŠI—)H%Â"êJf{êãîÁ…òêâÙ40‡ahrÝ\uÌf˜ö8ø?+™F”KÁfÍq/PœšV:âþŠ¥m‹àÌûÔµb6}Œ‡Ð4Þ³Æí…ñ…,I5·'lÄF ÈpYÎ×K3>7Îÿ[á‚”SÏf€ÿÁjø¶h4àãYÿ{¼é®Õ_‘ç³ãBîC>÷¶`±.¾kËŒCt E÷íKG,Y1{Ö=»~/N²uËÃúJ(Àp£,û›¢ÍŸs³t1@1ÎÁEÿSSuŸç­&l9chD¹ÃM—Ý2/Ïde*’“«9‚ÚãÝp$Ò~&¢hï7§šþ'ƒQ`Æ1©õXÓk×E×[*ª2²7òUI-Pý¡è©ÆN° ðpr$ý}¸ãl¤ót0 >/á›ÃQ‰ßâhXj=ÖØq Üj?½~\•êd Ž46|9H$CÓåųçœwÖßt§M#¢o¨Æ‡÷Eé Ñ{Íø³sm)£(‚¦MÎgÙb­60á;æ#Öê«âÚAÑ{Á]©Æ·5w9ÖÇii%xøñ³nиêôþ‹ørâºâø•,­4Òjtu5šÑíx´¼66Á6»Æk{×ïÅ{1ÆöÚBÛ»~ã¶PˆÀ*mc…‡Ã£`ƒ±y4!¢Ú$_ú­©Ô~Œ •g£à8ø5=³&QK¨ZKF­gÆ3÷Ü{æÜóÿqù.œÏs>kÉb<:–³ÊÇóiD€p™)NKMûf]ôfsçX}ìzÓk§¸;õ-›Úo6ö‰µžôU`Š#¡è>5<35˜aÀÆŽÙøñLMM^»vp̱xèL(CÃC JU« î¦FÆi¶2&™‡@ÍV3•ƒ-fCvtXA§jÐñ¦„-™"1Y‰hs¥¢c h¨ú ¤™¯ßÁ t2„†@Ça-*:QáfýFE17Ӹܴq%ÚQ‚‡ b9[Ωè$Ì6„CÿTV‰ŽÊȸTJx,š9V’P B;:ÜŽú;ŒFDQÿVt¨'N1t0ŠÞÛ†öw¶¯ÅôMôdHT&1—È ¬ÄÃŽ£Ða,TúÐ;-èHÁ$À3;¿·Ãþ‡ëNÃvoêwj¦l*eÆ**gƒù ÍzÕœF? Ìhþ)eñeâGjøjI6x f¨˜ÎT#ã'ªÖxÞóJ›P³f5ÎBPÕñà*½*g*˜3¥äëUyï»S4™†ìɵ²3,[UY^cµM³ôêÒQ׉¢‚ÅiF7Æ@jmG]y”2]Ë™ fŽ+xhøá™–w.5ïcͯ«%wËKGÜy~‘bÊYj‡Êq.žër¦üÉçS tÍÿaÖò»°'—;’"²µÜ‘¼mYŠ®oŒ+>X¯.ê]–¦ÚœU6KÈšRosTZK¬=\ §ƒ.xøƒUåV1¸ÔYcKÙíÕ²TkǺ¦êÁòsWžÄò‚Y&ØNŽH”%ÞéDæ²™`¹^U9È6D¹Ê÷ÏŠ½º\zŸj€Lîç€CÕùºæ™U >õæ¶$%™ðf‹„…:yRj±ôgdŽ••èU%äôñ`þÃ`!PÓŒâ›Q €»žk¹ºšµè‰ô’Msu­’AW³!ÈZñùÌ Øzð}­˜ §¹Ïwï$¸ÚÓäðé¶=óU Š?¼Õ÷qÇ®:v]øY_©=ÕÎSHUJiIFÖÎꆳ­½ðÀåö_|ÖÓ÷9Æö½s¼'Úw^îí’ùlûÞùú½Ü¹pìʶ=WâÓž£—?víé,S‚¢±2¿ß•ÿ ¾í˦èbÑÈÝ8Š|½¾óz¤åš»~[YE>Àb‰ðP­œº%ZE8\²£;Õ³/_]mOµh¬¸jgú|ýÞoŒÞlhù*½ÜÒkˆÞmÖÁwOà͹”Û²b¥l‘¬… ÃHl‚H8grdW¶÷fcÛß×Ç5´o½æøü#Ÿ/ë·>nj¿UßÒã·€pÐ¥bü—?1Ç!ÓÓSð;93=ójyq€„£d) üð«$4Ro÷ˆjhñB (0Àp«K¨²qe)8’‹Úò—l/£¿Þ`+]Éa–M§è ð@؆!ÕÄI4cF$¨5טϰ††æïw¨ ¡SkµÀ§5tRA#€ªÇkÑñuhp-]‡†á² .™à–:t~­qgPAçÂÆ+‹/_¾6*ì,PSK z7ŠÅÐ»Ý F#Û ƒ“þt´ ô ›ÙõÚR›J90Œqù)üÍ,eY&‘7YyFñtÔ5Þ:Ðù0uv°+>~ûõ by§CÈ[åd9FÂ21ýÎíÖ«Š+ži5[Ì 'Õ¢ÉÅÖˆÿŸF(dz"À/cÎÆá‰ôA`õ”Zú¹Ú½GMÏ…¦ ø÷•µ_Õ·Ýh\4¹Ý½·n˺­7€ êÛEbç +s ©ý…¹FXH7žò¨(ÏÙŒOC -Ív$lß—³z¾~Çšbàú~sì^¤ívc¸âzCëÜ"ØžYDø\©»µ©—2¬“ÐÕæ/Öl¨°Øa2ëWº?VëœnEZF¢·"¯=>w"m€L7[¿nŒ¬_–ÉÉÊÔ[·ÿ>ôé°ã?8•¼øÏ™i6QXFÇj ý=0b¡ôxhèB3:6©E#uh4„Îj¨¿6Áj"¬IôHh4‚†üè\.G£*N¶CšHAõè€Dý¼ýŽªqR È9 — :Açµø9`R ¬EGkоըÇC*S˜"9PΕ3¬¢³µ‹Ž/YBk‰Ä2<Ï‹„’Jß÷ð°p4r †öÇÁ` õǘ†Õìr;K ü°0f'DJÈ{A0°s°%…ÙKÚÂæ_Qt¡Q_ç±Q\wÀŸdÉÒJ+žžFO3z£Yízíõ‰íás},ØØ;»‹Á¬/zw}Cˆ¡…¨‰¹$\!TéŠå¯Tú_«ôH ¥ ¥Žm|L¿Ï$ ¢4Š[Z«öójµÞ7;ïÍïûùÝ@FúÈK)É’‘~9¾ÀÆ€¤Èþ¯™zœúÀ¦´Ô*ÜqÔÒ æ^ayœhÝ¦Š‰h‰/ŸBMŽÕŒG*ÆcåóßP#2!7®g¢bq^mhû òŽåî-Ìyä) Žç(\Z‹†&íÒ;8f4|Ó®ÞY0¹oàúàWÑáþlq¡…›ˆQ¾‚ ?¬ ¥‘f©š;=‘kŒ.«€Æâ58¦³¼ qško7†Î,\°Ð`iܕϘ&A ©8O&]À=ÊåmÈ•î «'Óï,3™(Ü ¬Å+F›BÓv 4r×.Eb®òY(Eº A_h(Ne"UaÉFíðHa–Un&ÆÝBÆ ôôB^‘‰Y·T᥺€p9GÓ‡_&˜¢QÆ\½~Ïå&€ªäfc™Óžˆ€%¥Sv©ÓRw­>üt~ÐËÜ~uVéòb›¦jz™ì[ºñ*^VLÆ3”_=‘åÄëå¡ñHÉLW¸|:Zµ»k‡œxõ¼o¤‡Æ¸\ýø=«œ‰U½[Wi1—Wf5/1ý'ú6ËLÚ‡ Þ„樂 Ãßkp;hñ“g·ÚmÙw´¼»™ÐÕÙ}kaÛR¢{3Z+ë¶&¾}rp @r~X*âìà6œÀ… Ïÿ'97{Úç7<ç?~.K7-v?ÙÙûýwô]ž?|ÔÕ‹œ½Ù=\N$ït\[3ônWê\¤ãX]|Ó¢ê†@V.3VÜÌ…îŒIœ(BÅý.tÍ«Ð_6¬žë¼×É‹½—¾Lüƒï'’ý¹ÅÜlÌ.üs[òO+×y¤ÛµwâÝO¬;W×­}²äjgÿ_ºún&z¯&R»úÿë—¨£÷J—\øçR{*lZ^)IÝ4<ãŸMOeéÙñ€@¾BÈýçøk[Ý‚šƒ á.²§…œˆI<Æ~-F^Èq2‰H €¯/%›„îÊÔy0[O;š úq=9…©ÛhSVòKÕÈ©vr¬EŽC#Ç¢äd 9ÙLN7KiK?ÔFެ$»Ɇ0kB©.Ÿ‹óôLÕåÓE:KcÛqªøHƒüÈ‘eäÔÊyçÇÃã…fƒ»€r¯*ôÂl² Ž(zlmF’äà09¼‘¬O¸òM0¹î•m/BŽ*B32|]dàPÝ®%/%ÉÑ䥲§‡ÙDö Ãò û‡åa_ì•2ùì!{Sò »’¬  sÍTQÙ{U‹&c‹§¢eS±òÉHÙ ò"R6/›÷˜ø† P$*óÉ«‡¬ç D&£~U1Ø£‡Æ©!X!WÞ •}f×Þ‘_¶Ú‰/Tï-dKu~ÕÀrÈKÄuEU±.š~&ŠEhªTtCe²I£PêcÇæ ;ñŠO› ‘ÚÉH…Ó\÷fé‚L‹¥©î"=ƒ3O]ÅM'„!LƒrŸªƒ––!nR4ƒÔD#ˆª«iY ʬX‘aND«hÉd¬6@n¶|@2Þi©&à ‰ù8Ÿ±Ã3Ñj$þddñ¡¢|Ÿ*á„·!ï+@JXháÑý ná1¹FSÁ<[\ø°^¬*§æ@cvõL´Â‰—5=9³¼ú³¦ºçò‚ÙT^Aµ\&2T!1Ä™Ÿ3—æbÔ­ºWÁÆå†n˜Š’çao•W:Ë«fìES±Šñhé´]z/Vy;RéÄkç}#=4¤[ØK7äYŽÃd¼£jɯ·ì:?¸ýí¡¿A¾?³óçÃÛçªHæí;¡|üì–ìîîYS׸Ðô£é€@ …Atè}„‰¶Ce”nº,»èÁ­¿Å§·_xf'Dñ‹¾-s÷¾=$¢fŸã xoö}oVEýG”ÇÁ»×_lO}Ò1?Áø ±±~£kà¯k/vö]më¹Ñ–¼ÖÙ=ÑûÉêäíÎÁ[]ƒ—©÷ZÖühIì`M}EA~¾lHŧ"—™—Ñ?¬X;×y¯'’u¤0®"ëg5òÇÎÞïfçs*ìÌü±5Ï.mQÕLña{êzûÚßG¾£0%O¥7½WÉ[ýW:þ¹ÚÑ5ý­£ïÃÎÔ‰dåˆrt$U•!gÆyðçA|‰ipåÁWvíÞáÑ ŸŠ¶A!Û–‘còjýãLOØæt#9ÝD΀:ÍÒ$Çcä•(Ù3T”"®<½§F9ÐJÞèpi#[š´ †’’OUÉ!'V‘Ÿ®$'ç>u”¼“3žn!Ç#ä•z2Ò¨4zPh†šŠª»ŒÉªîñ0Ó«è\0×ÚrI&häe€¤•¼<ßöøçñZ·§•šÂ¨ÕdÛ·d‚#ý—F =}’»“îUO)œ(‡: Ž’ãϨ+O{º›ü°Ïݶy‘Ç8Í1É‹³"B†ÈžÙS0Éá!rhˆì’ÿÅã¾=ïá”$Íþ^¼Si©³™à”«ëƒæL¬Þ‰‡Fc¥ãvÉ(’,‰ýßhD—ñÍ<ª¦«h—4D0EQ²}xä` QªYÔý»ªj'¶øž]"#)Z3©YÈÀ*hH"”j xÛ}ª‘ΩKS,MêPPfif®ÊtÊàÁMÜe‹Ædô©»dÒ®T}j×^_*ób6¬õ¹ ¨Æô˜ç“ᜆ¦2´{ÈÓ# !Ù÷Īb»úɹ±}ï9çúœóûüÕˆÇq—3)Ä3«o¶cŠ»áP'1uÂ(q²uÅïÚ×@#G—®ý8Ñ5^оvj ‡ã«&º/í>¸lÝĪ­ b í³óV•µ"*™:ADÄüÓíøÂ©ö5§â]h÷H[×ñŽî'Ðìq´­+Éœ ðÎ"§I£L'Šåýõ‘óAžìž—F€`ôËÚ&°äl(v9»ˆÞÆÎ…ZÏ#œ -èÞ­ÐâþúæËu‹®„ÛúêZþZ»è€;°!¯ÄoµzÒÓñïxÛ…å/5FÂpp=Ó]>#O4 Œ}æåsOȈµ(I¿.÷Ÿ 4½SP¥¦D& Ìo»Ù½Žh¾ÔÐò¬ŸÏÀ˜CÐâ…PôÕ T ¥æ§\WS;2<œÄÆððÐc5’ bì„»z~ñN &™ŠBS.Ùí'û¼<ƒ?­ì¹ËIvWñàçÀI5ÙSKzêIoX¶°·ªè‰Yk.± uÓh‰-5S1c$”GdI ïÉþ¹dÿø5²ÛMvùÈ?éõ’,”²Õ/¤¥h%e”›¸$£42½E¶è±[ÉËô,’('ûjI¯›ìžKÞ÷“_>o{ü{ô©@Z€ªda~Oý›bOM#›Z¸F6A#-ÔW‚œ1Qæe‘yji«!ïÆyscdk‰×¦X¸RR Y"ë£ds‚loçŸnZL6Ä8?¶áû­cÝkãÂùÙåŒÙ#[:ÈÒ ÖOåLÎRÄ3%EØŠïyrQÆVåag~àþ¿ÑˆªÈ’LÍT6Q*°*z$ıÚöña¤&ÌI“$|Qdõ:FÜ3G\¹ÃUECî’“ÓÍð‡¬"›ãÉPÆñA ÄkR—¥VL24™u6IÐ(¢ èqCÐÞ`Ä&¥j¯–úÉ=¯c¨ªlsV†VÕÊ’ËZ–.)ø™µ’†QM¹Aêœhy=Ë6)Ù:fÄí ¢H¢€±PÞVk6rxr &ü"x &ŒR•Á E€aL¥÷]¥Cžâûž‚»®Ò·³³  p C àã óyŽY]™™±l’µÖ¢Ze™¢gTQÀ3UNÓêUM½>·d¨Ê>âAvÎtÛûJ ÌL+¨T'yXËZê<“x©Ü>:¯òº³ð«¹ƒUåщ&ƒ,‚‚&AÕ ‘3ÙFé¯r2‡Üè¶áÓ)ÿž«ÃyîéQ ^vÜuέž»ñÅt$è©¢“WÆä;¹NÇ»>It#•BNO¬¯ >Y¶I^ W‰­8Õ¶úÓD77Fç´¯L8ý– E+Z¨2Až-uí\w"ÞõYç›Ç`˜øÊãKÖŽ·]ìדKÖ&)‚“S?]W9CÕ @é§óô×4õ…[¯=û¬úcÑh¾Š] ¶Âg‘y[‘â‘‚ꛡ”þp&9Û¹4?9\Ä—Ãñ+–ËÈùpüÚ+‰‹áø_B-·Ãmãm^òQ4¶‚@W-C±*«Iœ¤“WÛKþàiЫ*¥4[U…ÅÓÁ7,7Iø{cëÍ@ׂF0É3DÁ(4rCnŒ~8×ÚÔÄëù­ŸýÂxHn’䟱JIB%é‡ùâÏ¿%j €–è¶‘^®‘$žNøÈn/Ù;ƃ^?Á;{ý¤§’6NG=cÔb[ef•éyYHQ|ªZEH)3í~ò¾l/#{ÇߟýÀŸkd§“ì¨$û|ä½5›W•*j>¦Ñ4âT¦”ÙŒei¶"ÈLNSicÙYGz’¡’wø¹óã‘Øá%ËKU& ‚0RUï˜Êsý–Ö§¦‘mm܈·£ÚºÙ¢(˜$¬‘öZ.m ¼Ï[ÜÙ)v5›²Ò5®ÜÔ–jòNòòy¯ƒ¬xU :Ù«~²â'ü’í þ>¤Á¿°øGÛ]6wð×­íä­¨<;IÜÀ§†¸f’m°²xÔ[ðÒ½Û>ÂSþsOÿ¥Fðôþ&ˆ¹R'J6ªˆØADHKylHÌ óå¬=mŸ9T•3â…Ff|ë.vnzÑbµŒß‡ zÆÒ©,PmWFÚç¬{¾ÒxŠïT•îš–m4ˆZØAê…,&”i?wäŽz ¿wMõ• V”ª e¯¨È•ÚT{HŠª™bUöΜ|sNñw¾Š¯¼s¾vý©8'žaÖ¨Dj£˜v"ã‡P­Åô½«݃”0äoqØdÁœ4QAGUóØo‡µ6â*ñ¹rîV½õR†&a­aŒè£ð“…öLË¥ ÀfÖ=Wñmç¬#ùS°˜ FÓQ½¤(Vª9Yìtæ!;?på\«,zc¢UR%0E•$3¦©´ª}³PÜýÊÜacÔ7kôeû`EÁü “^„‘T£b0‹4CkÒèmgù¨§ä—ã¶*yÿÛÿ=`^=ðÜ©Ìé¯p”£ü•T5®ó5‚'Á‰D÷‰ŽÄÉñ“9˜è:öÚ›â+w®åž‰¯H-Ys¢}õoǘ±1Ážl’U{~ÓöžÅËÑâñÅ+Ow¬=öDBð ÛºpÄCŠ|{ݤè0»PãLÓÎcõ‘KáØÕç§$ÙþPk åJ r C$W8?Z¯†ã¡xCZè¯Ü µáüF0öM¨í|}ó…š…_7ÆoÌo¨io»ƒ-} ‘ÁÖ«H“¼í™@ÄgK?Tæ¾ÙÐü·†ÈK&³‰—9ŒéøZfŒ.Ê̆Fn…ÃNW¡‘ùãVÐhäòØóØÖçKФP¾ºóÑG††Fþup†<‹Ñ€ä‡IwïÜ`ªÞ&èQòh€cy¼÷éeÏÞZÒøÈÎ ~[8&öÏ!{teÙY”zZ&Ú˜N¡#SÓ(ÓçYɦ²¯†ì©HÙé'»Æß.šØî&{ªI‡ë‚*l7C*0Éu9©sÈ–jþi¯ŸôÖm‹Å¤HšÔôÔ_§±Q\ÀŸdÉÒJ+žF£ÑŒf4»+ñllÀÆ{ù¾0ÞÙµ—Ëöú|­×öÖ4å «€ cN‹‰Ä¥n¥_š¦ßú¡­š¦! GìrÛìô?K*U·yõdW3ïò›÷ÿ=Ó/9 G½œðì‚óã©r,@×Yx|B*ñ ÙÛFÍòó-ƒ]ä`9&‡#qÝë$‹Œ…À"]ƒû;ÉÁ>2“´$ä@LAoÇ2ÜOÞj'Û[™tK2CãdJ}d÷&òN? ÿ¬‘Á¹Ûê74²FÝFP9D¹]b¯W"ƒš‡^öç‰çÔÏ‘,³,'Á4ÙˆW{†öÌ"³r"+XEúY‘cZÍÓkíÕå·Õ¢»Þü,›Â1Œ„mc˶q\ QºU½B”M«9Qï½¶è¾ÏÓŸ¤$3"¦¯Ђ ŒwçNV;Öäè>×KKd–š!QXÊ›‘-ù d½G¯)Ñ1¯Ôk\÷½åÝ©éBœål•‡‚D’¬÷Ôâ5ï†LwΨõ‹B9 kBיּJpqV ûÀªÂw²Sa ÀHžU(cåX-AzX]¬×èÚR4‡¦¯Wv¦,á%ÎÆRÉ@¨)ýÜá˜4fÛ5­ºn{*&›åÀ$"š²yþ`vÆ]o‰^S<¡:ïyÝÆÝ˜¾>ËËN(º%³¨ «ŠZØø«U+t_9¤Ü>öæj†úz!=Ufü¥·ª–éµ…óÒR8•%Ê+Ë”ÔK¿Üu®û×㽆.ôí¸1òŠ˜¿ vê7¶d9vÕÏv¿Žª 8äÓž„¶^Ø²çØæé8ü˜iI®}¬ošÆ÷ŸGvÁ-þ 8ñb A¹Þ†ò„"GÖ¼†ea…È%iEFæõ†Ð ]ß5v^ .˜FÐ4@r#Øy»¡óN0t=hPÒØ¼ÜYiUdÖl–̼D²¸eiÞøªæ°,Qßön¹§ßî<[îýÓšõàÁ|Û½ÜÜ…vÿÙ*þѾVßqg]ÛÍá« íki›lêøª%ô~I “S’)Ÿ3X"IŸø¿ vNכ÷C—_¾â®‚aÍapñ§ÆP8#Áúò‹?èÑ'ØøÙ ø5ûð˜ã3õjB²ÄZpœ±X2ROFd|3_´è&ow‘C²{£9/M13 HWùÕr¸Ÿí#ýä­ì'û{È‘>2°‰¶¯%=õxÄ´ºçÙŽÏä„x‰Òíîï&û»È`ÏUPŒ@Ã}doŽæ²eY,6#ÈttYöOiÔ¨ÊEZMxK<&žS#/½Bù9Hñæ$‡GÄÆTxVáDD8‹Üùm¡kV-›T §½NÝŸLß—• °¢¨°€!ðÕÞÏI»Sí˜Õ캯%êwNzÝçíFˆóœÅ`€Gð G%H^àáÍÌT…§EÎh–e-{hqÊ„'ïQ ÿ¦ÇõUèªë¡ßÕÜS^×7Î ™a)2A!Ë<Ì×Ù,Q_Ѭšw_-„I¢¾‚Õ6 6"™‡7l‚Ñ5Äâ|¬9©Å²Òe–áQfB_¨óâòWïy—?Ò\Q­d“©ÚQÕï\91b° ÈA^”Ab¥}Y)SZ^Ô_ðH+ùKi…Èad‹qãx™1GÒ2F³²a’=Y‹Ó0ÌáÅYKZS2¬”£¼(‰Š•iPâÇœÀÄ’ûÀãKté¤f_¨õfÃN3ª3€UôHuϪ?…_SþÈ«­N²±"]Äqñ<ÝS»~¾ÑÿqÏŽóá­—6ï>׿ÓHÿÞã‘7.†·~ÞöÁÖßÔæ("^Wš,ÊÜü-êÚ÷"0`Ü6ÜÚ•Ãˉþkü ¨ã™¤AÓãáí÷>‰¼Ž *NLey“Lß+ñLCmhû®µ÷‡ú…¡Ê×M¡Ûõí·;¯5u|ßÐv¥52Xæ·òf#örñ6AÂO­pÂwù×Í=“uá’Äjd‘ÿ½Öø÷Æ®ù¶ûCSè2LÒØyY_ßþmpÓÆŽŸêÛ&ê^»ÒÒñçú ß7¶ßjí=_éß”šY“žIÏøB­™¾ v|ÕÔ @#×ZÂ/{~à´›-=WÖnºÖ.NIEã ¡HòÿRÇœYçX„¼×¼h"ûyrÜûÒSõ8°¡‘S2ê!GäÝ QFÖ‘cAr²‘œ\GFý†UÎÔ7ñ75*fÕ4¶L!ýnr:@ÆjÉÑHódT3„s&@NÅ~B8‡ë…E,-‘˜âdrd óãUF'œOðl$`ÞXHY³ÄKÊ1«JÈ`'9Øc侑øÝFÁÅPñå|52{ꉆzM­ΕIËrɶæ¸Áþ¸½°G9!C1Šl_Ϭ)£‹¬ ^Æâ\2ÔgVa×g$Þd2ÅgZ˜A—C½Fß êtÍ­ ð&d´»/ªC}tc@`Y+Ï‹Ô\%s7ªË§T‡îwÌÔ"ϩAR8üàYEH¤æ¤´‰•Þûj%"þ™Ñ}¥·ª³¾|]sê5Eº¯à®·h.Œ»–ÞSѰ¡@× <ð~êÎK#QÍDÒm2gèÈÂJ²žeQé—`K÷;g½ùÓZùÛèµî»ª3ª–mxÅ*IR2•YRèÿM#hý#göCÍ>íCø–L©nTõXuC#x±Ág¨óß¹ï³ë~÷Œ·è\Þ2ÀÀE§0E1.œX9j²qLG9É$Hf«@­Ôœ„ÆxžŠ# 6–žÎÉŒ‚@>&P÷C#EÓÞÜÓÈ¿ˆ¯÷ئ®;àGBB²déêêèêè^Ý+_[v^@á™—ÁIL±¯]< ‰í$¼ó°±c0µ¼ J)P(P PV¦îU^¥”nÕVmÒ6õíi´<&V äå}¡ü5”è(¹±|ÏùÝsÏùý>¿=În¯é1\üôFz|…)oéeîñ¢¨IñWõ£‘Õ­þŸÅ׺¬õ—Kß<½bÓÙ43N-]sfYëçÉM4­,ËŽ÷!*(ªTh6Só‹7¿`¹17¹óÇaÝI8’È/M#Ÿ$ÖŸK´B#'ãëN'ÖÃ<Ç[ÖL´e+³ILSÙ—¾ÐípôÛpÓÅÚ赚¦ÁÒÈåPóݺø…êE×k›Û´ì(rçË*4b¥˜)l!j£ÔÁVÀt‡Y(alŸÛ÷M06J·RFGiê¥`S;a€ãÞ5·‡›¿ 6¶oÔÅn¤MòŸºøÅÚæ‹¡¦[µKï£0Àß‚ÿ Çn…[¾¬]r¹>v3½n¾Rë5wT7\ªixÕóÓQÓ„±nÖÅ¿ EGHØŠ,CÓó†ç¾˜Eúúïo^³^a ”J&òF9RÍðª«ê¾9äjkš=>lrÐM~>ƒópŠl÷“3äªKq’)~°l"NJ¢\5’ìŸEŽ/ç‡SÉûèâ šÚfI‘òœ™£³T$=–Ë4™Qó4;Ùí!GgC•䃚ÁçÇí b›=dë\Q2¡:ذâólä&²3FvµÀ¼”oO—õÝÀÉ)‚Æ)’öL[Ù¿’¼#’ÝI²-B¶ÇøÅ{«H[Ô´À'åQ»EeÌ&R!ÇB6-&[Eg@Š˜f»ñM²½™wøî2ÒC“<½-åná”jáhÙ—4mj2ÍÈ”U^Ò˜éEãR†«Ë[ð_¿y{Ðùñ5‚mŨ„Y²3~øœc³ôy§öûJ`Œ§¶~oAÊ?¡ß]LèõŒGŸý^çßägiä+W!…Fz½®t E=¾Ò?–?K#)_ñ}crM< Hü4§RÆt\ɦ»ži(ô÷fŽKùKïyÝ=^W¯§‘Ü«œÐï{mG^H `XŒ½, 7Ø©Ç_òX#ÝiüÞU€ÊûX#Xcx ®£8å+Á$oÏËv`·"sQñPªÚ%UÂv`l„¬ñ}¡jbúôª‰ÜÒ¨h•™&ˆvI±ó—"ì“wßSÚï›øÇߦü®>_ñ`­ŸþàÎÀ˜`8Eú¸F&ö]žò Ãª š*š“å3O®jhõÿ¢eÃùä¦_Eß8[s&¶9_w*±þT|ÝÖ@ÝX¼“ «ªlÕ¹Ip•Ur­¢”!«‚ɬëºÊ”\{ÆËÒȯãkϯØüil“Î,ßøî¢X¦Èd¾²hEFö…Ú(*òõpäb¨ùZhp(‚vªi„p}hš²ªÅò–e‰º®!?MÍÉsê6àDÀ’Ò˜(šÜ6Û>·?½û˜?;çßõ‰®øWõ’Îyq˜äÊœE7j£íó_>ó†·¸“J·•Ï8g„:ê—uÎKü}îâ‹õ±Ë5 ¸å æóÆAüzàwg(úU`^&ÅæãI©znÕ‹i$•êýø£ãP¯ÎT&™…y%dŸò¼òªztnzpb6/ú‡d¿´¹ÔàXyªCɨ&ò*DEÊQ1 Èo:e“&˜}²/ÖHå€ÇýÉd5˜ŸU–­C~ŠG–ìºYR·3Ì"UÍCŠÉ1P§’ô‘ÃUƒÏ'Úa9:‹¼–F"ƒH9ÈIJL6Ì{„^ÍÓÅ¥gœìˆ¾ˆF8l¼«½ðL”[îYI¶ÇI²Î<¥PpXðƒU‡£ Õ™¯Cj^äç"ڸزj¡éÍE¦·À$¿wGš7ÛÓ×ÏpÚ›äFp½+ ™(¿¨ªÈ¯é´Çã¾ã)îóõûŸ?P#˜Äϳ:Ï´R C.úŒQ(»Ïhå]•®~?/Ž©×˺ŒI÷QÊy·O×È_Ê Ó…¬ Û(åÍ[€ñás4ÒmLd0¨'³3–)™nygÀ!ù©@ù}£ì.xãsÝòŽï÷;ø§·ææh sH* ÓKÓãé6ŠÀ]iôÅèê®Âï5"ËXßk¤›C®¸Ïpï3œÉ‚¨䲆£Š¬Û™ŠŠ0Q©"AMUT³DûHjͦSª©L”tÎEPÍ?{ÇS†GîòLK`€{³&ÖúéN7P­7­ WVŒIS4›,iºE?ј<™X=ÐêÿÛDëéØÚ³«·œY¹ùó䦳ñõ§–®9³¬õtbÃÉß7Ì/«g±còDAKð~5UÅrã/‘Õ²C  S}/K#÷ìòéÜòÐȉ•#Óý*+xÏŒ®)tµÏ‹_­i¼Ž^5u„£ƒ¥0àBõ’;ó“ÿøÑ§ÝjE$#¬Ìša#ÏÜÆoUÇn/Xý'ÿüæacE+@b®päP*Ú˜Ô6ijGm¤3Ø0Ðq;ëb—æ,ì¬Bb¡È…päXE äÈÆû€UÝ`ç1Êù³)þ[ó—Ý E0]×ëc×ë¢W«®›ÚƒÉ«žŸNŒ[i¯iDxYŠŒDME±mËÖ³HOï×þ+V Æ³>•§ç’UäXà•WÕã³ÉG³É.]Xd9Fžà­Ô. É¢Ì&"_¨Vf³0²R–Cf™*Õ™hU$kž"ÎÉ!f‘ãrÄ7Ðq-UNÆ‹ÈDdMUÕT ŽzÕ‡*f9“É•ÃÉîùx69<2¸‘O´#€¸ UùšhÊI˜"„+ÈÎÄ#À!»Òý‘O¨ÜÈïJ78dwË÷~LV×Ks¦›Çæ ŸcØ)CÞ°¼RdÊ O`¨j“ÆDˆ´5§IƒN–òHÞjLwá}¢=G#ˆ|z¨Ä¿3¿¼-*æç("Ë”5š>)Ÿò•¥Œ’ß Uj„=Ô&MRP,•×ÿè>~ËSÚ}ÃÝï›Üë)ýn¦óŽgR·§$埔2ŠŸ©‘Ò‚ó±Fx'à_|øôîH¶nKW`1:x3ÿÆY”z} äÐ…ø=%wŒÒ”¿ì•cS³Ê»fLñgYöðydE’ÿO|Ç6‘ÝqR$K–¬Ñhô4#|È ×nŒh€8¶cÈáÄ$öŒI„IÇæLb'Ž$°‚mNè®"(›aaIèR¨»"@n¯Ýª]©ÿl»­ ÜGX(”r4q»¿çPínV–žF3V2¿7oæ½ïç½*ð4ûãÒˆ5fÓMkdJÌ[}‘› _ö´FðsˆFmºˆ`:gX*Á)›³)è&ÛUJªb©yð¥àY˜MQ02–‘1¤Óà TQÈ,QÊ)Ž“-Â’^­æŸÅ9±•y1;4 ò¸53i‰CÆŸ}KÿolyÕT†–+%öÛÛÔv:°%áô÷ÿøÌ;?ù¸©µ«¬º£dõpK×4 †ƒmpr2ØöISûÑpkÏÆ€K——ß*MÃŽFö„ ¤ ص‹öVÐL 2n‡ê¿jÙv:Øv¤¥Ý˜:_…9x•jŸ²UÝ„°«ò=t7BØÝv5$K#w\õ]¾îÀpaù”hJCÑë2tWÜþUzÇÝ¡Oàkdž‘µÁ¯\ÞÎ…KaS&ci‹’Á*šú]ùº .ïˆ+a\®òÂï8½#Žš{6]á°hReR‰–†WÁ9K“é#¡$¹ þh¡ý>€­ÊG`qzïzà™.ߟ+.ßj»¡€ªqdÖzüÄËid*ûϨ:5n…µp¡þÒמª½f4ètY(-Å…d?¾ÝV*EÌH`é…¬a3Ó‰FH✘ÖÈ´LÕQA˜ÜawèÙeWÍ,Ã|-ËC¤ÂÎ…Áä¨àK”pš®¡V¡ÎZÔÛ¯îG{›ÐŽz"à´ÝMä&LŸü°Žü¨'Dy„ é@oXZSN¾ )Ô¹©x¢Ä4j3E¬9IçÇ jD K97 Ì0Êšªxj3GDݤ-û{Û”mᨰ„Ä¢Hnµé#‚~ Ò|üyY6ɲÿiNà~œI#Q!B¿±V ½Â°üƒ”h†¥Ök”“Ö¢˜£ð²#v¿˜Ý³›¿ÔëµrV)ƒL'“!»ÃW£èÞç¹Ù0\£VÒ±Q«~R€Á1<¯ö9&¬ºQ«ñ’ÙÄÐ)$¼h¢Žã–ÈÙC™K¢BIL4ÇìÅ1ûŠIÁ [ó"bqÔV?NZó¢6P–éV©9&ŠúÇ¥9Om†§¢á¡˜´ï'b‹Žà1xïð˜¢)"ÏrT´K&Ãi©³Ö5Ÿ µž %€¦Î¡Ð»n£y!–gaþHsI°íT¸ýlSçg-ÛÎ7už ´ý2Üñi¸ýDKÇ–Š5ðÇ…iéé4«S¥9uyû6ÏnÚþÊ4jÿ$ Õ; .ÝãkÖ0¬œåä4mV§^tù¯:ëîz¾©ö@Â:ë’¥‘‘ªºËÕõW+|›¤ÓÐ |ˆKª/µ€¥ëUÞ•µÜ=A8¿o 5§à¥,ÂÏÄì5·ÿkçÆ[ž„5rÕUwÝãÿÆÕðÐÕøU…wí- i¨ææ@:ìD‡èC,'}ƒÖoM¶=¾ÓúhP ÿa¹<Ãðþaȱ¨s=Ú$Q™QÞ$é %¬ÀOã!r¢¾&¸‰¬²æ— “Iƒr°6jx©%m^ƒvоú(N‘÷êPo#Ú|ÆIOü|gi’¾ëNw'"гþë½>CËHh «È%¿È|û©ó“ÎÔ/W2 #å©ÃåÍÜñkL,tßÛböecöåÜcbÁh©)V–ߪ{$èfÒÈMÙPÊMØr'AB\Â3i$"dAèÿu¹)MQ•4Ð’UÃf‹“¿Å2™‹oZ tnÌž]i =±|a2ÖÎ&ûV5¬|<=—¢iù+ÓOá?˜tÐí1›.&æƒF`&l†Ïs³ Æw5U"`$Áø $ßB…¾`¹‚á$˜£1U“ª¼fY[¹lJ4<²êǬÆQÛ"x–©•ò2¯šõãö xoR4E#zbË™ qtc¢>iŸÐ´CàhÕƒF€"O¬†û+²=ij #…ýÖ²3Á­€‡Óám‰¦ÿñ–޵¹E°yÁ žË)6¯tkÜz.Üy²¹s8Ü~*Ðz.ÔñëMÛÏ7u NZá8Üðî¹æ.0ñpëÉM]¿ßÒ}Þ»õ•i$Ðv"ÜÕ? uœoÙXQN¶6,ËÓô¦ÅÆ»îð%—÷ǽº4r«2i>´õs”9$-ÇmÈ4þÛÝ|Çé½¾6øêú ¥*ßwýmÿ‘«¡[gá`ßAìÃuo/ºíª¿æª½éN¸ÿP÷BEÍ5§÷ñºÍçìk20+eÈ=½sÒÿT¾îž»ù¸eµ=}œl(° ãþ\ó%—ï'p mM4r¯Ú?²6ðF4â¿áôT ˜¼J95y9L‘CÔé®RM14)j3“ Ý© è/Eƒ.ºTÃò2>+v,¥j—¡nõ•£h° ¡4(ºü¼uJW«d7k[>:XŠÛSú¯{L@Ûó¥ûÝh°}\FJü¬,BGHÅhHDƒÐ· Ô'¢ý¥ä2éüøV;+! p¨òÞ’óJxiŠF;z߇zÃhG=ê  Ý!’éÖüãÎ8Hà²í HÛë8’h[˜[”.ÙhGÝõ¨·uÐÞz¿ŽÈô’Ù?ÖÅOÂÄ»â°é ?ÓÈõ§ñ¥>ˆw›ˆ(þÇ=>YuiÖH93Ò< õÔb˜ ’ÎÔ©šbxšâ(ìþ4œ|½R-þ—ør‰êÊãøILH&™äææææäÞÜɽ3áíÊ>Ç(Ïy)df(Vy Ì"Ûø€ÁÖî.Úªµ­Va‹ÝmRm]->¢mwmÝ×?ûO³kET*¶¾ð(3û½l›˜lùƒFÃðrïÜs~çœß=ç÷ýü¢¥ŠÈ¨Ÿ´2ƒ¾26Æc0„ÑÂ8€Äžv¦ÍF#ÌJy`ËÂp˜ÀÌ µÙ2/ŸF&àÍ‘7UV+S ^D:“9.†S"(#2Áxa¸hù”5õ‘5žO¤/*5ðZŽaU"8u-<}V4"³ôϹ&¢@#΂ ¬ÅaB<Ï›S¤ñi™´e©4²ÚrÛºòåEñ<8J§‹¤R4XÙˆ£‰!GÖ„3í¶=5ì̸ïÀÿœ¿æ™òEMY$÷7KfØnžr˜ðX2n3ݶe>°¥‡ìé`€{öÜùÚ?¡LÌdÒž Y¹T¦\¤ï[IÒÉG|';6Ÿnï=Ø1WõßéÞL%Žçj)åÅwm|ض¤*8èþ$Ð}Ü¿õ$h§£÷lG/žW†ÚƒG6öÀ޶nù¬kÎãÎfð|¤}Û6?õ÷àzE4*+¼gl0á@ó¦§B³ºùŸ®õ×¼¾1Ïü lԽᢻñ®·€¡U$ìü¾¬’k•Íc®†ÕM×\õ£žÆÞæa׆OÃXïD‘Ö H È}æÒ+këÇ_ô»ëæ:î]WÃH]àkwÓ¨Çÿ¡Õ­c@BÔ¢u5Ôú¯UÖOÖv~¹z]AdŒ†eôTÚdLþ—§ñŽ·õÒÚ Oî¦[ÞÖ‹k×?ïøŒy[þ]UµÚ—,P-«Ñët–œpèçÁHx “á½»ö!qx^âXúRùàù«ê€gÁ[NrÐIÞÌ%%*ÿ“ÃŪÔ®&ƒäÀÍoœ¤ÝDúd°òÉØ Q>С䋼o%ƒÅs÷p9é/!ƒEäÐ áì/$¿uƒ«•b£ÀÉœ.J‰×/l(%¿/'”þùfŸ0;yK¨ ƒ…¤×¢e# T/—%’]3(Ò>Ã!¾”}®42‹ ©lUé®%¯Tby­™ìn!o·‘}vw’>C§zýVçS,Ѧ2’:¥™ö¯Ï}> “]­ÚÅq‘ê&–#^3êCŽ¢I{¤0ìÌ„6MØÌag~ØžY™/5 Ûó&™ãÖeagöC‡é®=ãssZ4ËBçd‹¯ͧr,Ï>±æß·™&¬{ËŽä…oÊêô¬Ä +ÑHž~aN ÙsC¶ì3† ÜâGÇ­ËÃŽÂUQŠÂ+¬,T\QL'iZ ï8,÷  ÝÆ…H1+ij`KÌŸCˆ(„ë¡JÙ ˆ`~ž Fb(UxNMJœZnO2{¦méauæ/,i)‘<²qvdÝ++4ë8è0è¶®  "~Þ<ëϦò ˆû±Ö-mìc|Ú<èù¸k{zl‚,Ëž$i¹lèµUðoCËSþî3›^=ÒÜY×ì/+ïu½Ôïû%úH>iÝŠ¾ç:_ù¨e3\Á'å™ÑH[ïÑÎÞS˜ž¿{gk'TèNy.Uྪi¾ãñ]©n¾\Ý õún¹æFª®V7WÝÆË*ËacÍ%×=;®Æ«^ßמ¦ß÷îf¨ÿX­ÿfUï-NÀ'à°gmUÿ©m÷4]÷ÔÏæÿŠ»q¸Æ?ìmù¦Ú÷ýÚÆ©º®¿”¯ûª6pÕÕ4 ‡5[.ßQG•Ì2£i^œz ¹š.×6ßòÔÔµÖ-[†sÓ±%qñß«nx[01pÈew# eC?çø€Á¾õú•T(êQUÓWWÀÿ0<ýóhä X$¾pîKI(ÇéQÎØÈ@ÙsWUÀÆ{N•(€" ¸È;kT¨^°ÃÁ5äJÅ ÅE­¢Q^0‘ýv.%ÏR>JKÞ-Tƒ%s÷2òž•¼QD^.%»Ö¨Ô_)®Œc“tHjŒ†*,éÊ#‡ŠÉàšùfÿ³+é_CúËÉïä2n!É‹8ËB”žד½U¾a{ å¾{64BvTiô͸ÝÓAö¶“ÞuQVjZ,¤%òɼÍB|•*–ì!"àоµý®Vòf@5ÀÉœ‡Ær:4/: †’‚„ q*Ü? ,a{î¤Õ4eK{bϸo5?±æ†¹SöÌùR“)kΤ#ã!DÙ‰[UM.äš"9^æ…9>H.؇ E!¦¶åMAÇU‘ÊþUr´B9QÐEòš©åÇÏIš¶YBvó#{ö#UÔ̸ÅxÄ©0" 1º #ºÃIxUÖÝR8\qi¥Å­£œ–QD‰êP™R Å­(Ï`€žc"µ2Ï2:Ó‘D*+ ŽÅØC |lÍ 93«„°Â¥`æø~D2EzÒ„l¬©·­)!{N_2ËáMR‰¨H9„B¸4ä¬ËFóB–Iæ š¢˜L’±cÌ´M%½=o•˜-1.ù-Y…".<§ãQUÄJ\¡Lk ²^fE‘Ñ1ÚŽ‹¡4BÒê¶AoxTÆËüL;̪Í+`&áUùã¦=c¢t)Þø´”dŽA¨eQŠ£ÒÁöÍà‡ÏÁ3mÁc=³©ü‰@÷ÙŽí§ÛƒÇ;{Aç=Cí={ê|2(WU-§S^õÖmzeÈ¿íôÆí’w;K–¤) gäE#ÃÇjÙróŠýÚÏnë;ÕÖ\A³¡ö੎ޡ–­ÏŠFNµvÜ„ÿ“þm­ö QT“vêzcâÅßwk†½¾Ë?JÞ˜gÞh亻aÄÓô§ep1?*þ[oÇpMˉ/Û˜¨®4ŽŸ¤‰É$7¹¹¹99¹7çf^2 PÐA¤E˜Þ]`ÞVÐafÐÒ*03‚´±[ëëÖl+ŤB­ ¶›Ø—Ø5[Y÷C»q³ÙÝn÷ÃîfSëK*ëëÆ¨  8³ÿ;ûq× ÉÉäÞ;ç<çÜÿ¹çùÿxýD°óöÆÄåHô» ¯ý‰á:¾¢¯¬r*êÅH÷¥p×]i{:í„¢…¢—Â10É×¶5šV¨°MËVl/©ú¬®ùë;Ï­ßì2[2Êùúƾë:/mŠcU nnÉË3Š¢i#®Ú¿EÒh켓¦¨wmáõ’Ýõ¼_Z£R=סH9öÁ“sÏF#©ä FNþû¾ÍheÑ¢jr±JN,¼ Ÿò’±:rj 9ÝD>l!ûRGµðӥ̆-× ŠCM¤Š Óªœd¬…5fl¢Ä–HkMd¸‰ŒøÉGyÏ;ÖDNù¥æÉfâÅ6²ËAŽ®33n’ øÅ”šjÈB·S2ÒBŽÏ?þ‚Óˆœ\GŽùÈ/›È±&ê±›% ZÛ¥`=9ÚOºu€Ÿ Åuº8ÚG:Ép/y¯[Øäò­V‰bjÙ¬¡°À¤°yn9ðè%‡ãäÈV'Þ’¡­äPOzUó¥ O‚ ô²B$KE¡’U6¼iÏ…ç>ö¹f=EIŸsÒ³jÚ]žj¬ZD7y詜ó:¹W‚fJR޲߻JQ)ht~MÒ U„k©jHù«“Þ¢”¯,åw½»Âʘ 2ªJØo]uTjßTäÏyÊ“À¡tÃnñ¡º¡3†` †#Èü×­*À9q×f(²h0p žB©nX\uà0#‰¬Ü,«B©*½ ‹FYCµ‚±WdÈÖ’`!Ö¶*dòլʹp0†>1“Ò@"«KR5©F@Zqª±üÈrýd…F$•éü Q… Mg*÷JÈ1¿-wh 2БD%#€$â<+¶ø¯ì±×‰†PWµÏžca‚… š,€”p Ì` ܪKE%#ÇÑÎU\Â(8­@Q68$`pHÒ_¾è42ívâ÷v½cV‡ÏÒËk\ÅÜ"á5Tà[×ßÙŸí?@çú÷=Íå¿è݉>¿E‡¾=¸=—ØõEÿîÎZ¯‰©(å, o«X‹' Àéø[Ã¥æLI”¸É$K„2k&A–ê–¯|5~¦W§ü2¾“‡žŒÇwýjÛž_'v"æê¥ùø`°aš,R€ÁM¬ß|¥­ûr¨ë̺µs"[4 n¹Ò»Ú–h·Ùá qMQθ[wÛ÷Âñ;ÁèÍ`×­Hür8ö?\¢qêí¯ÛWÞÞÔ{¤Ñ*è|Zü‰¶n ÍÝP÷õÖèM½ãð2*rU˜áYÉÁÔšœ|ø²MáÅŠék߯¡øíÖø½Pâ¼»µ@þS»jºÐ¹ŽÞlíºìºÑÖ} 4ÒÚy3Ò½ÐúüìxI´ç½„󉃊ÔñÝ·N%“ÏJ#sS:—*-xIPe#Ue«DF‚ îª#^rÒGƼäWXmBÁ’Í‘+$.é$$2ýŦHTP¬Œ÷†Ö‘·êI¢ü@>]OŽ4Ñù¯ó#‰Ÿ:4I´æ2N¶­ Ã~…sõ$*Éí%KŠp$QIHÂ^/nX|üøß6ÚLN@½ôE_µFQ¾*Èþ¦Â猯úË3)e®€F@ p[H¡ Dƒtº€^Äüc…ÓÈD35™˜F®©fXÁÁå3^hëzì+™ö§üeÉÆÚ‹µ®‚ìLd ¨­r³bRÀ8*¨ŠgÉJ>S-²*R£F3m¢Q¥V›ö‡Ê2 È´»t6ýÁè(²Ø4&½¥S^0‰3ÕTóN®E@*¤à5æ´d~Ú¿ûLôÍsðñ¾=gAOwùÏ·íf6trHìߺûó7öÖ­(Ò·LÕy'øêxßžñîç¶ïíÝ‘Í8ÀUûo¡0QaQä`SQj,Zuº×o¶íý* óêüðœhä|ßž¯ð.‰Ç·l[ÆTAgFngê÷Á8øÀº¥Þ EaÖ—FàïÛb¡è鿪Â!D«E oŒü3ˆµÅ®6o¹JÜmã¬;ØnËU…‹½HÙxý†‰–-÷#ñïC]?†:žÿZ8z#»î¹ìø{ËæáÕ ªŒêhºÕ—W¹†ÔÇTŽ£Y¢ðþ|ç‰úõûµ5Fë ¢!CáC+ú"» ÔCÌ+á(ÞZx¹¸aËý[ˬ(C€»&³yrr2õäÙiäaJ§‘öPP6ë@@U‘¼]¿à–z¼I÷Ó±‰(kìFQ\&sð„ø*…ð*Í\ ,#¯W’Câ&cëÈÉ^G>È1Dh™÷¼>Ö,—š)·ÃÄÉþUä“>!¤X”a:†%*9Ó¬ŠIze%mZ|öø?ÍGFÓ87 C~f×}ï‚lCvl$C}:ˆ‘!ÀC÷s£@Å!EÇ’ƒ}æ×šx•A°«Üo‘`,LÖ¸(IXIŽf2‰²!XCâd0¦H“Ì`O–æ9ï‘2Ø þ!‡úLeEªf*š@åW²øµµ«RM®iwá¬E®kÊW±XV¢ÓˆÛ•øJžøk’ÞªY¯ë|YaŽ Aäy5ȨPÐà©Èp­¡ò®§|Úû“)oõû¹Ù .ÿÃ|ÙÇ6qÞqü‘&EŠdÉ:N§;ugËvh ïØNÇIÇöÝ%^8N t)8qâà¼LEB íÄKa VBGaZ)myYK[­Z÷WµíŸmÕʘ #†·òîÛ÷Ÿ“‚@©ôÈz|÷ûýžçù=÷<ßÏ¢Ešf‘u†ýKɪɠ>9E$.üÅC¼‚Ì` 8ÂA zÓÁÂ9¨žR¨©ŽGŠ÷š·8µ,K !D8¸ùL<Ï£¸³3LE9xÃÁ–Á ¯$q& Wkahýndø°]¸ðhÕeÓr14tJ´ehkòF,ùuxK·£8¾rMIÊFuÀ ¸ãõ€I\ ¡LÚhE+ö‹ÖIžâÙÍë\V›n<"qàÇ­¨s¨114Ïr/:?7c­W#q«ßE¸ü]ÏpbföiDKÏ»kÇŽ2¢f1ò"–+xá’ú^#yG%¿’þ†ÌæR*‹¥).bËj– äd)9&gêI?¸àá'çÐ ’>…ôÕwUrV!ç€"òÂiDÿeª²mŒ™§Œä("×ÒÆ ÏšL9³‘ßU¢ÄÀ­Ë!çk<þ§QH?À,LúTI·ál½ªEýh¤Ëɉ.rlŽCÍ[žn%'Ûɉ6€©¼€X+DÊh1ó!鈒]/£ÃJ"MÑ8#KMäÕ­äd‡ÎGæ¡èøN“:îI¸À1¡¯«{«I9–Íü(uZ)ÑïpFê¢ìX,5™–=š-˜’Kf‚®±`þ7%k“K̵vqAm“$Ö™Ù¨EzE2'l¦»UŽ´ý­¼å/:›—[oÂVðmBu–¶›¯z×b¸yaÅÚ!ú.üÅC¼‚Ì` 8ÂA4Õ3r‚CÐ7hÕ%cªoÔï½QQ9°nmÂ*m@†õ¬q›EzcÅò?•`^­¦Ê*Ð4ÅâJ\†ô³<”²e‰ø X’V½“!礜?*:–k«\")6>ô’ø3‹©ÁbÙfïú½e̦dï@ÞòíVS£$F$“jE"$ é´‘:$iD2¿tçEì¦zÉÜ( 5V¡Îj‰ZÅwósgCÅAh·C'œP~:T’‚kµC•΂•¯æÚ¼"k–0€'ÆÆÑÙå³±§Ö/­ê? 5%^h?™ lH«® ½ï‹Û$܆vV`Œlõм]¯?¾ìÜÿiGï'©žßwîÿìé*}<èZŸÚ{Ðȇ;woZï¢ZiÖ»lå‰í©77½ìÏ]#TiFàx» Åܾ÷;÷öÅ»Üö¥8b´Àãm[™<Ü t“€F.?'Ñi¤C§¦ßvíöääŠ,Ë ÜO Ô‡Õ±ûQ]F‡Zn5& ª·£ Hê¿FFëw¶$¯b&±äi¿ªÚ홆L n?+ÍXå€~ŽÑïBŠ]Ó†ÌJ›õT°öÃÉÛ‘øµhó­§SÁ`¬ù:°ÆÄh}˃†ÖÁXòfÝ+ÿÜÿJõW¨ëŠd«}5ƒ±h|3°vG¯ —CQç½*"Û†ˆù}´ùf£ÞÁ“¬ñ¹X4_§ð;Z[ç™"ýl,2«¥5àÈôÜWß|md-á£e}K_¼ªªäœB>¨!çjH¯‰®"Iy»ôÕ‘ßÔ‘÷6“wÂäté ßÁ2@Nt 9=O# ŠS2é—Éyeᤠe$\vŠ)ŠÛæ"~Ñ,BàPX‘þúŸlËÉ´ÒfŽÎhZIúN;/ºUI€œ©!ýaÉÞÞ ldLÂçÚÉÁùÕ)oÕEüyÑÈ¡¤N#o§È›Û3sDAP¢F ¯mÓG<’ ÇÛÉ[)cLÉPœ¢£èˆŸO‘ãmäh›áXòYhäXy«M_Ñá8¢±r1˜ÙÌ ™,½Å"ýÕëšU=PÃiÅ )I/€‹4Å1,˜ º¡•3jÞ#Õñw_édhaM«ö?V¼¤±€o¤Ê­Ué[«qj²û~eéœL+¾YY÷ñ€gÔm…ŽNë(â@ñ¯`3ÃŽpGGA§VS’VŠ&ƒ×H•c¼Ê¡…Ëgd÷Ã*×ý€çì»ôÝ«*},›QÊÓJ¹VS|Í»Žå &ZLâK(ƒ(ÆDS—Û'Cî‰@ÑœâœSÖká¢ë%T6@0®w:T>âÉ”kjQ:”ß©PÉÂÊ~Mõ¥å²¹`1Rôh>]HR7¦ÓˆCOf¸èžß=ªÐԒDzg<䛪B†‹Òrñ¸¾Ñ®IP¨ìЀh!¶~"°zF)˜‹FîåÃþòoKÝtæ[êö§±vÙ5È›æÁë¡êž–Ÿ ܆F°q5%ãjÙùÈ +˜L.ÏŸ¬ßq±³W‡äžKí{ŸHù]ž¦ò È§;{€%èÿ!Õ Ç}á Õ¤ž£ŒÆe¼”e ùL£$I8JšMk/übÿ•Ö݈Ð.oätqe³8!î t÷^î>ðqr7怰ϑF®tô¼k2³º £º%Ëw©"ñÁ˜®¤·ë›!Ð7#ñ;‘æÁÅ£‘‘hÛp$~5Ò4ßnêð×Uü—ýº‰"½ãþ$$$$›l6“Éd&³Yvø‚'õ@^—wVvg†E@aÙEOyÝ…eéÑSDh½\=Ž;_@íU{z§U¯½¶wM®ÿ4ý§½—T=_°¢w*o=AØé÷Ù¾ýÑÔƒåš4y2†}^æ™Ýù~~bh˜†Á¡æ‚ °±ßaÅU:®è«Á0µñÆ6ß½r÷ §çvYí¨Ë3êø·*¸]^=ZV=æô|QQwmsÕ²šÏ·5Ž9Ñ ·ÆŠÌ>›EÀhd˜QïL?àhá†Ú–Oýoh¤#Î%CëÉ)…cñj%ƒ¹ä™Ï'édwéZGŽ•½UD‰"2„ü-!ƒE4ŽÑ}`ý‚çÀ¤ö Þbm8,K¿AŒ´¢‘a 9á"Gì!nE%’W7þ¥¶Ç¿6àíx9‚*&ƒ29™M†aF¼Q8Q¯gµZÒ¾&ø!ØBX$Š õxIO=y£ÅÐé†Ê±]”™ ä`.’#­tÒ¾V~w.ÒÆò1,ǤG“ý5T#½Mt=˾ÏÛÝLbÞÀñ`yµ†[¡cÎhІ¼9Y>Q<« ¸ÓT%y©Òä‰-KUR§i>ZTÅBâ˸…X?îBÎÆ%ó”-v^J˜¶&ŽS1b—ÌsŸÞÂlÝ.:¯…n da©ðƬœì—¢¦­kf”4µ0sFŠ÷îwÊ–öК2%a‘xîØŸ¹À«rê+.Òo‚_Š›–㦥˜9)úòÛ,ª„GCI£J‰ÀØÌ_ò÷'8hK¦¬Yƒ°XDFÇq‚h eù’Ô¤Ÿ5wžkxå]ïžË/ï?]û]8$¸Ð°û)AÿA@ ï¶t ×‡M4uüÈÓcŠ@½Â3¬E˜Ñ‹"-h9î¥ÊÙ¦=5íûØ×yn×>Gfn('à!G Ôµäÿ¸¹ýŒw÷…–Î+»º.{M#Xá¥æ½[³r@–§¸m5[î;w‚×¶6"F¿äøÍ-ÕðɨӽTù“à <ÚÚx§tûݲêq§ï—Êöüè$”~xåÒPËHLž_&è7.‹:c/B;8<×õ7+Üw+Ü·Ÿ’æÎúÑ-U\ טÃýÈÙpµ¬f¢Ì=á¨uT}é¬uÕ^+¯þ¢¢æjEÍ}—gÌá¹ãhüʱóJ¾«-ÎRŸc4\uÖaŠÑÊF` Á8£[èÉÍ篑ûϦ5/†²Ïp+ñãO~£Îû'ÕùgÓºÍùýssOpžm±àë‰aEŽ'½eäh>Î!§ "2¨Ð´Â'YŸfgÈAÃ"¸ŒœŽ7 €hŽÓüÁbQ ³§óÍ~%9®JæYɼä7ø-o_cóíY*HfM›•3çl©D¥LZcçíy?\³š×jhYÁ0«ÄгõOSÇ‚Zoe}º>Ì c!ÉeDyº‚Zsì—[º.zvã8âi;ÿò÷ׇGN+ò&-Ó窻ظç§;;Ï6·¿¿«ó¢oÁ`~ÞÒu¾¾ ƒ\ôu\ðí…C(™ÚGZ;W”6+Yv%Ë|dw!Ú–J÷ÊÝWËi¦•×?„Óý•£öFBŸo¿^#¹o¹|W7׎W4þN©èL·TÆ®Ý^ÕaNÿÐVrÇQ½Xëùcy-3Yî†R>/¯»_ÙôYiÕè6ßuWÕ-'Ú½Jïo˪¯W6>p6€+Ï{îº< â]Gý=§b{®;ê¾t¹oºšÍ¡¡ÀdÊOŽQý~´Ùg³H€"ÿpŒÏ똡åÈ+y4ò ‘a¤^ÍAhd¸hÑR1zÁj hD&ƒëÈ)%¨»TÍp&&”caÜž‰P‹q"£±dÿFrz39!‘þfNÁ$ù ž :šGÞ.%}%Z9Š ç´LHph'ï­§::±‘êh Ÿ¼Š¡"ª À , €D"CK¦‘~ùo9Ðö0{-›Ñ3¢Ž5rf…)h_yÓM€CÍ‹§Œ†æ‚—‰a ^ bpL®„j êrS ´’¦×hÔ²g³!ѨÓ1"¿ŠJLâxþº)[šßfžU,K7ßò†ìóËÉ~%ÅoK»½Á’d`t\H8¯y/nõg–äy)G-\ø¥L¿´íZ¶%7Bdx êNQ¬èX‰erÃÅ[9YøädAÒ¼œúÄ–ê—Rÿ¯‘ÿئ¬àGäüЖ†MS 3ðç„5I-²œIZ“ÀjobðZâ|Ê–K¾ÎÅÒȹæ½Ý5ÊZ³AË„²|8Ã'êMm›*Þ÷¶ŸnnÿÉNÊŒ‹m?رA çi¡ê'#Fšv_öuÀZ»Îûö^jZ¸F|Wš÷]ð¶_ÙÕõ^À!—š÷¡ýÂ×ÙVìÒó¢øöë=&ªìŽøI61™d’›““›“{s'ó  ]PAWäø†™[¦0ÃpgF«â¼ÈÔ5+ŠÒµZqEY ÊCìF·Ý‡Juݦi²4Mk›lëmt󵔻 2ôwFÛþÕl°cðürsfrïœsÏÍ=ßÏQ|xGÆâkϸ˜/Üs†o8·ÝÁñÏS|Ñèßø}ÝÓÂ…žï-·ù&]‘Ïê·>pGÿäðÜs…î8|76Ç®:ŸÛ<£ßèææëMÉÏHƒç«n‡ã¹êúm‹—*é‹v¿V|  üScýø¦ð˜Ã7¦¿Ø›¬oú‡âqz^ôüŒ)>@ȸ⇺Ýèƒ_K·ßo­[3`ãÉóBÖT¬Mhdf꿦xÄãñ'O¦ß;{Ö ˆkŽ#±¡JÁ§ëЙDC#Y©Ê’]f±ù‰ß_…º­ØYHEQÃaÁ’HDÓRlaN$*¾>v wdva-„ÁXæÜï)3#Ç ˆÂúÊq·Ãˆ]+Pl9kGCµìœAõ:ØÀú*XôCw}žÁiÈÁ$Ð? XÙ¨@#Ѐ!±ƒIH¾A#ñ’|J¹­µ¨Ë‡PgsÒ4r `DoÇ€¸"s\6/aBPÔ†˜7ºw ½ÞX;/=•t”’òåè€ýÔ:¼¨;Š:¨cîý‚F:ÃèpB0†Qt4Š^wé :Êöw‚@qgVƬ¼îIMÁýïÒðÛjVΟ1¯š¬Zy׸&ðjÆ-—I '¨¬Z!ñ›Òô'rs>.*¹RTÖ“³#=EOùtBV/ÅLBÕkt:µ$œX‘õ º ’ôëš¼¸¹ð±©xÊ ![4ï7ø²—©pÖ\ôX.ÌÔÌʅߘ Z ªê T%b‰JZL7då|زg82çôÿ_NœÝ¾§ÛÛrÈííÜä ¼~©õàåHÛùµŸ‹µõ{c¾õf ¡ð|)á$Ë*!—"mB­Ã-íLѹwÝÒà¹&aiý¸¥pª¹Ý·néJ^`³‰yîd¹éo÷”ù¡ÔD#dºrÛ¾mܸ“ˆÝ«NïÖÌIá>¨qŒ:¼È_9CŸ¹<÷á›vÏ5‡ï¦™vÇîÙ½£ÞÉÏ}Gð¦+Ü”»”Ò4ž×`XoyXS%­Ideù‘²ê_Éî;JàŸîàXÖ>Eï'³"„Í“Mч÷Ý 6ÈkÊ ÏïØµ3¡‘8 âù42“( ÉôôÔ_®_ç Š@‘- åA#:]›Ðˆ9™ôU¡3ïvÔ<¨ãÖªQ –à Ù"çÈQ·É*ßj©|‘^ÄYXÇ¥`´· ˜P¿1á Ì}<,Ç&VèC ê©C§¬è:%£ýF¾a…ƼLµ­ µW¡Aê¯G`˜5h(1ÐcŸŒz󦑧SÇF’Iâk¿&ŠJj &zL…ÂÔáCǶ£·’D¨£tÄŸ`I…Ô1 Ó,AvÕYÖ£°Cí6é—g§cšÛ*xmÔêÞZ˜#‘ÄåaÔC€Š9wdÇÃÁgé ¡ã@¬g_§%ž£Z­V'pWKÙîòKcÎüÇÍË]÷kò o ò‰€%,¤s”a™“ x‚Aþ”r‘(oÀDMyÈÇ%"윘ÎK)j¼D§YŸ·”L[ò™WÎZ V}]S ,™÷|É+^Sü\úLb)ŒËŪW=2N[J÷g-Ê¢ž‚Hµ:I×Ùüux÷•ííÉÒÈ%ð0`û>hÚu>¼`p>¸ `p%¼çBs[‰~¡žP ó°Ñ ©$uѱ¦@ârx  —?‡F€:?·^Lpú‚Ná8ÙÓ³¥9]ÒRAÐè4¯ò;[Ó˜;|³Ñ;_`id¢€Ø…´½«„n¸‚}²–Bë¶Ô´Ï¶Mºüö­£Nï]%ø³ªú®¢ ç×Ôý¦®éš38¶1|W $k<“®–*ÛRƒžãت.QjDŽ’^Ðc>•<&¶¼–ÿGûæ/7_øü(þIw£N?3[£oRñÃý¾±j@L…wß;Ç0ñ|€1ÿùƒ'SS SÓ$*BÄði<:ncéù·Fú,h >i‘:hE§*Ñð õÖ2çÄ*áUàI¥á ÎºÑ œY‡7pYj=Nƒå{‹ÑIê©B}&ö=Öçéº?å§M¨o:mDCà"+¿³ ç jAEa5X|5XcÉ{åÌÄ'™Y§=2›˼Q¤0.ªf42XËîæðmNUi%A‡ž ÜÎÍL‘¤i¤Ó:Cè­:A?ñc'Pö^r K°²HCÀ=…ÜLÔ@ÝÑg—wxQWuÍ}<Ð#ÜÅSVuÂ1ÄÃ~]n–žˆ¥œÄÿÀ@™Êgå‚y›—¼âr)ÈáVEY¾À©Πii¼ÀzK /ŠZQÔQ O‘›‚*¥RÊv’NÍKzªÅɦê+…³rIÜ’ÿؼ|Ê’7k.ž2•>°”ÍÔ|7ÿßV¦âGrY¼f˜ð¡¥(n)‹[Ö~Z²,rƪ×ai[µuøö+¡]—xHJ}üØñ&HàЈî…c\Š´}ûñ'!¦‘f¹!EÒêÉ›Q·~¿ñâ® -Íû~{óB¨ çϵß÷c{?lnc‰¶ÁíŠ.6· ·´{ÖšµÖZ€/iÎÊuÿªøÇß¼iDñº·ž Wð¶˜pø¯*~%-3•h%.…'ƒ•2peÂøûÆÈp}eF*^CH&¢æàjã\á‘D^'¥FAû’PÈb*n^¼Ü½8^C‰ °ºb­D5A§%ï_]1îò76½ðùq`fàE €mJà®;\™šÉ†{IøóЈbê¹>3 <ûŸµÊµO5BE‚Z«Xâ÷=Í_3ê5£Óöäi¤õT3oôZX/'ͪ-ù @Ž©hႱ_§±Q\wÀÿ’%K+­4=žf5«=´°ØŽjœ|d}‚ì=Y³>Öë]7l³Þ;.lŒ ¢ 6¶1øÀ±CAc áH*”FÍ—ªQ>4­A€˜#© -)‡½Ûÿ[Ú*ß"ÓEæCvÿÍÎÌ;öÍÌûÿÞH=ËþG‹YÞŸnäÜ«xªWKµéáÇ×WÀqÛ_l»ãÆ8clðF%#Ö[x¤öš8 OÔˆ¶]l»~V 5rÀÇšf,‰käh;ø«ÕJ•œ-PDò×~®ÙË–>Ý<Ûµß7¼Ÿ“^ Æ… Qp‚b… e.»Ð¼È‹"QŠ¢$*î rªÆáSñÙ’½ÄÈX†5Äì…,Y,«¬9QKþ‚¹52ÿ“F~,™ ¸Yq ^ú‡)/¶¡üZy‰GCñ’$ œhYi`y<ôêÉö.4@¢4rº}Ï©«íB{ï¬o'ºâ£Î}³]çpÛž™Ž=S¡‚¤àˆŽÐív×{‘®™m=(&¢`*wP‹m÷T„Ù%s6Ðu.´ût°ëýöžw;2—¥jB—<÷;›gÎÕvÅÙ2çZŠÄ5Òz­Á‹¹áÌ1ø>tlJçx Z„¼šSü•Çwws䯆ÆO/çëtJÂkðíE…€Ý;m¬»ÛàŸsµ>íñ¹ö#µ KpçëúÖëߗΖTADS¢”RRRбG óqH<±F-,DÙgI3Ð×φ£L©Ð˜ U0icf˜0¸&§‘Éš8o,,“Nc–¯HjËC¤SQ½RJ®…wípÜS6©â-‘j”„K.S0H`ñQTŠ-.¥EV8j‚ ûk ²×ì²LAPJi8åÊ9¥‚ã•Éš¬%´L-# Y0ZǬ¬ŸcØyÓ¢ÛMظý`‹ƒ€–ÃA@–Œ­‡ý6NÅé¥FP zšà`sÂ4rÀËh1ßò'ê„NO²£XÅããHy*¨QÃcÖ¢üº,èn¾ ôµAŸ#²ý¤žZèGà‘0ìnâÝåê•:Ã~c)lo„þ0ôã)3C¼”¼¾Œ+ÏbÅ‘OÐîëm¬¹á úïÁ!?üº 5ýͺŒŸi‰HJ½\ž¥¥KžnžñˆÙ ¾­x!fÏŽY³î˜Š>/-ygõêÕ \àà×!¸(PSI)HTPI­“$ërå†Ì‡¦‚šóîÙ ³˜ o› 1›!j1D͈“µÿ²äÏ[~ÒÈÄ÷VCÌœÅq3çÆ6”1ô„“KDM9%ÇG¬õ'ƒ];öœtÎtö|ìM”FΆÐÝ´÷¢:0ÐÈŒ í½¿ ïºé¹ÜN˜Šìz;´ñp6Ð…q±c/ZâT`çÅÎ}x1–úm¸{ÑíFz°ésÁî ñ™m=S¡Îô5ø¨á”ËS2²Öö纭·]¾[.ïµ¥¢Hƒ÷¦Û{ÕÕr»1xÕÙÊ4R-¶‰Ê¯é5[¹}_Õ5ί@†HT©„"mjo¾%°ª@ÂÜ!ÑtB¹ʼnêÏIs 9N’¼¾öNC¨45ECÉ/³‹¯Õm¾Þ0¯XN)7]^õ'ü§Ú-8tO{|®x|sž6ôjÄÙzÅÝöY}󴡤@Hª ŽÍÏ?BO|ÿXOô‰F~øA¢ÂyWF‚´\/ÂX Lcú乨oÚ—U-l‹Á,äx³V>`‡R™žW+dT£WÁ>¼ÆÓF–vº`°B¶i%ô•Áx!œÀR:x«jÑíNÙXs£8ŽÿÅ£ ’e 邨" Ž¢¾jaÄÆNq©$‘Wˆ Iá"x»†0î`ýÁGGUÂD%ÓÚ8: ·68²DDa@ª‚#$©“u‚ÈQ‘.WÃfèÂÁ#į¼0ÜÎ8Ñׯû¦”ƒAV[ !Äø 1®ÙO…\ŠŒç·Jüü¢ …™+ÛYÁxqD^9üýAœøa4 nµ^‹ §-!ÍzåKeÌR³ݬȌZrbÖœ‡Kƒžý¸e\÷—’¼Kù/þ›ýzi*Ëã~’&Mš››››{s›–†‚¢»ÌŠ. PaäÕ­”Ò·: mo_´‚Äå!¨ëdUf@|!°ˆãÆG‡‘(êìl²›MæÙv³ËÌ("шË8Œ¢@÷wŠfçŸI¦3ÜdÈ/Í…ž{Î鯗ûýÜ÷S{’eÝÉqSÖ*~9]”:S’>c49 šìyUÔâjïöõ¯MάR1¯T„Õ[Ÿ«p.js¸yá²ì¯J6‡õyco¦s\ K­¥$±$½cSú%~ߟë_ñ5\©k\ÿðµB]ýð$桚¨%“ FÞ µB-—v¾«> Æ\ô7„nú›¯úOzöÊHZNq2Šù…˜û¬â­i›oÒì¼gqCÞ­–F¦-ža‹û.ˆÈä¾kóÞ7¸>.³‹h!GPI¬äPVé°£¾+[›@Є˜£Y9CLTTÝ·x>5;‹~F31­KHŽ:åM.ؘÍsÛìzdæG*vßÛå›±ðw. %Ó¢Àæ´Ž@vl,ÍÒõiùí{ÿnö$ÇÇÑ q 3ï±=0bóžW¼?&~Üæ¹ãðŒUVݱ»'ŒÎ‡ö`é†$?ÁÀÍ—úbxxü°L?‹Š@mÏ/0$+–èâ[‹zt˜"½êeKÏ%œ)Áê3 ³FTŸ ý§b…‚ª,ÔoÁcNÿ »6p^N–£³•è"¤/FývtFõº½ 5®sœ0ˆÞ\·MQÖTìŸÎt^ƒþ¨F:±B.¥¤páQÖdtVƒIäxO‹{Ò_Ž~¯Ãƒ¶ôh°Fà¸o5¢CÝzÔ¡§6âg[ ɉâÄk|ZÔæCÇxL…#<:Ê£ŽŽù–M#ïxÑéZ<'hXÒˆ0ǻąْHcI1'q‰rtÄ…Ú½èíªˆ‘蘿Âàw£_÷˜7¢,?,*Ú­ÒPDÌ0rZг%%¬-zP”Öe…ËO•¤«O¯y…µ¹aͶêmOÔy3ªÜå¶oÔy Ú| ÈS¥4òRt?iäûPdºZ¶mQ“ýL©˜UeÍAë”À’œ¯JRÃ;òæÔy;ãÄëH’¡1Ao‰ï¨ ÜØ{hÐÛ–x?ØôapÿÍÐhÓÿ#ÓÒL €×P Lu5RPÁ`°eÀß8èoº±'êù£­!óPÝ¡+¡ý/÷½mHÉ’Ò¬”d ’Ü“–óo³{Ê‚3nÒä†P^-L™\w!6ÿ¸É=j÷O[¼ÓïJ¢ÉµÇ G³Pp÷´7(®W©Ÿ´yîUTíÆÉ…„P"•ÖF­‘q‡Ôì¾måG­ü»ÿ¾ÿ§¥úŽé×ÕnÅZYƒ‹hRÂqµ›r£VHÌX=iáY½Íü„Ýû…ÙõdWèž=øA±áÓ;GìÞÏ~[òæ5‚’²‰ô‚ Rî3ýîGŽàì5SFçJ÷g2òí“;|Ð+`Û-­MF Ђ²¤ãáGkNŒžkq~ê“ÿDÎEè’ÔgÄAÜ£ÆÑß·|é Á ³õêñäøW=êÑ¢nê×£SZ¬‘¥Âêbg&:X„Þ+Gýš˜=ùd¼ÎjÞM¤­§D"xê"¢DB<*ÎyaªÉksæU9«O¯w=/S<×d¾P¥¿PmYP¥G*sA­€ ýE"#1E^ÿTßUaõV°¦ˆRñBý’"alEXWp+cs,CK¹1 –|ÖöÁºƒ—½¿¹Ø-ÔzüP× Q>ämŒ6ýoÕ µB]«Ù&Y’ÉÍÚƒþF¬‚` €Þ…‘ƒÁ–ÐÊR >ÎGÞø\7‚­°œ3¯DFÑ$Ç,ex#yÊœ2¹îYœ£Vþ¡Õ;nY%ŠX1 mïW:'L.ÐÈ„ÑùØü‹a·vÝ9M‰Å |Q"RÈ0ä[Óþe >±zÿ°ñMi¹2ŠŒei‚^UZ¢OyVœ¬t‚FÆM®ÛþޱzÆÄO›kF Î'Žà#3fÏEº$šÂ8J@‹dHÏ5»ÇLîÏM¸{+ÝŸ«¶1nqOÛ½U£vÛ¶ÿ²_÷±MœwÀR$K–N§G§Gwº“+Nha@Q:F 5y¡„—Çgb…8öÙk ¶ã䜄®# „·¶)PÞYÞ`hl£´ h·þ1MÚËCݺv… B€ è`t@ˆ³ßã¤Ûþ2 JÿÀùét¶sÏï¹Göóý¸@$5"RºûÝVÔȤ"b±§¡ã)±±'ì8:ŠcÞûúf“YeJxq>…¶´c «Ðá`T˜ªôDtÇ5Òù˜krð¾èr‹êl.…3ˆE¥h*B´pËeB’D“ʲ™P#Ý«îÛæ€ÞxwlÚ•}EÜîbã<ÎÂ)œ@Å©Š;SŠps Vd¨`åĤùìv±«˜Ê\,ñ;VAï –þq¡¬ºìÐ¥²»˜.ô© $íùð³u’}žÂqßCð‚AÍ„=5ñÐ×a¦5“§J#­:ì ÃÁzØú†±`Gy+¥QšËS‘ãM„š$Ù˜,Ì"îº&A$Yó¡Þ{«!°¿–M†é(’xß i€wƒì¦$‡ë!ZÂ[噼9ELÔPžJ¿qäÝ_m‹9²Æ9ÓOßñ+Ä…²Å _WmãÎ%ãjÎXaÖc»m Ô±d‚"xþ¿O_Ôÿ©Ç…¯¡C¢âY1g6.ï˜=—7æÌý2/;W!)²DpÃÄů¤ÝŒa}Noú´aç½éT´ñÃMÛ'¿Ú¸-Ñô?[» ½9mþuýŽ 5['F¾ 7\Ýôim 6Ú|º¶»#ÙD8Ža„ð?y½à–'˜hßaoðâG xÃ_kÕcZÍ%w¸z^'ñö´´?9ý•/<7ú¿~ÛSùçâ —J‚_x*–7ô—l¸í¯îGJ%Þ÷Y4¢±õÁ©ÞõU]ôEÈ2ALSjVL>Ÿ¤HlÂ$Ïüøï哉moi±ìcC$ž”ç@O)t­†ã*ºôDØ Bºâ,éF„0'´¯†¶"³k¡LežJDâ’ÓeNæLFBÕùp¸ÞuŠ ŸLHREt» 'ñôGðàUmNhw@_t¯‚cÅp¤„ª©ØSà`²È‹`VE–“ÈÚ¹I{Tès@ÏJF¦£h'ÒRØâ$å‹ Å©°¿úJ §˜Í§Ó>mé,bÓCt@—Ï’3ˈ ¡ÄBˆX´ öÕÂÁ(쎰øžZ‰BkpFµ›S¨d0ZD‰˜DƒÄs+3asì¯a­ÔÏh¬¾?‰bášÔjl&­°¿ŽaI“°FêaW;î©„½U°ïˆ "æeànŠÈÎ̸[˜S_hä)…‰9†'…¶GöLÄFÌ™;î\Ssþ£‘±‰‹¯ä <µÐp•ÔlüìÙ3ñéƒ5¹Wò36ÏJ“(I2rVÙ²ˆJMšï7µÍ¿Œ6M(â´ÞøqÃdÉY½ Oð•DÓÿ#”ÌÆäÍÞ²°ß¶,Ãlµp·6ע엷£êÍ3 ÛÎ=ržµ˜‹ª‘U=ú3gΡ~1ÅB{sí7ý:ÆÜŸidH ÷{Ã#^}º42¤±0j=Á!¦ŽšdPÃ×Ãø®'t¯,:òÚÏ=Á~_ø~@¿á–雿¦rÂòmåúG ­hƒ{^ÿß¼“=?w¼ADNÅwkƒ·ª}¹Å„)ªP5®vwvŽkDbr>&•hLM!&b¢Ð[}èô9';UÉg†…F)FéôÆrè¯0šX‚É ®Í€#U&Û Á‰˜¹Ò0±•2…O”ÀÀØØŽ;¡¿ŽO¼ë¤QÌô'ìÌ—X:Y±bèû%İQ ﹈c.IVÑö¦¥)æYDîuQ7z«àC¼‚ú§N#8h¹ÞÚɽŽÄ¤tª#„Ê žüi]áPE s#tâF‘.?ÂálñŠÙIš+ö¢@P;aY=À~D§ÜÄ¢'3-“©D¥†ZÔˆÿßßÄꉺ‚°õm-5™j’†MÌ5ò?a¶Žºrž”f?q.}Rºd¨tÙhYÁ%yS[o구gŽ¢!{îËöØ>w´Ì6ê*ø$#]9ÓpC ã 9˜ÑWCíÓ‘öx¥ÿåÀ¶Ö­Iˆ!Œš¹f¦#5’ˆBjÙì ìôJdçéðöÏ¢qSÇÙ`Ûň´ÓùÐöñ3ظn¿Ùv*ÚöåæÝ…³Ò ŽCUuJŽ-)š*u¼ju¯®ñdžЗeÞYøãPÄ7Qq¡ráœ9ÿbÉš‡«#½¡ÇnürSo^!£ÐÎ¥+oº›n¯nùÖ+7&œ7=¾»nßõÕÏ¢Ëg̤‚Oç*¥ôÚµkCC/Ð ##Ãx~w¬²j\³R#:JdÎbØM~ªžtÁÁJ}:5rJÝðq-œ¨I/^dÔÏДõy„ü9hª½•0肪ád%ôÿçß±1PƒåOóJ)¼ÇA',„Ojád5©„^O‚/›-Ô„P8•û -¤®•$³„ù4aÝ<8T"‡Õ?éZûÿã·MB ÄÊa NU|¹Q4BuÆÈ3t6ÉÚ‹xhÓBœÒX¢¯‰ðxw |„cgö†${Žn=ASin6áNS(µ(Ä,×9äö$=qOö´Àæz+ ¾HI¬·šï­°}ïÈu¡C²Ÿ:l£ŽìaGîˆ#ÊcëM½–õ¼dé¨+oȾè¥Óö¼tÙWK۬׾|€º,%ípKô|´ãjt×ÅÖö q"Ö™pûj[¾„ˆB›“Ý‹sÝK “TaE’šn´ü.Ú~)Ô~>,;½éˆW¿H‘K›:ç‚ÛÆÏ`{¬Ñv&´µËãKeBf­PsTñŪuS΀W¤î¯ÙøM­¯'¥B©F©.tMW™j¤*ÒÑ(Äa ¤gŸsyÎ8kV37™ÌÒ¿¢ò®Ç/R·áqCègço3Ö=¯tÇퟥã*&ÆÒÒÒž>}:F‘‘q9ŒŒ}â«‘#{÷PʌԈSÄÖdÉÄ¡I&žò.´D YŸÅqïêÃúLØíJ¨Ï¶0êˆè¸§Tͤòò™p¼ú0…« 5R•0P.ÕÔg‡ŽŸ¢ þ•0°~_1'®‚`^òʹè‚›ˆrL7+Uu… I¸‰%–Í€ðòÄ.Œ~Q‰ì}°bÊ4"€½ãl ˆVÀljÊ5™if|(4a½Sà@º}cZˆSúKu´È î±HóŒãäp4ÑW®ÏœN83pjbê\.peAGŒÀ>tHëØEâ8žf8*oSÔ9uÊšÆa\ ¥ÿQ”?Z¶ü‰}á gÖ°3{Ôa{îÈòØzS¯e–å •fŽºÐ$¿øSþÒt]>H ‚ [h´ð…?ÝÔŽÁ:lû<²3^*8xÇ¢P“0ÎaâP]ã¥è®ãá_Í·LG¼¥°•õ¨‘÷½¾¦BÇ>oÓåÀ¶xõ;ΤȸF.ŽÝ϶¶] ¶ÙÒæ1|-‚彬üï‚S΀W¤¾®Y÷¨>øÀŒ¸:r Ó„N R’ ¡rB,”jŒð}Rã)ºÎ)Ut5“k_T¿}׃Bðßv7þPzP×<éñ4Þò6ýÓã¿QÓx¹´_p1-Œ{<žq0 ¿ü/⮑ký3RVe;Õ—˜`Ð Çœ?GªAc¬€ß"H „ÅBTbDª(<‰™æ3³0(Ó’à};[!ªà¨Ž8 ×ýN8U1;ôO¸ßƒèÙøÀɪæÑ9šÂq1ðdEObædnL¡jªF­ Œ†õ9°¿vÚÑ*ˆUJüôCÿX×'*åH¦J#±1ÄÊå<œ²ÃÉ"ˆUC ÇD>š’Ág¤@OPj¤«ö‡â–þÝi‰Caèj”ºèöË^Ð[4[ºÐuCås«0âÃÕk(΄M«ÿÅ~ÝÇ4‘æqÿ%$$Mš4O&“'3™I_BANW`Eåeñ( ¥–B¡e  ®Ð7Z(ÈŠ ¸âª ¾@…®î›ïÆóö.¹¿ïr/ÉæþXEoWs/ÑÈËý¦MÜËýç¦ch¾™tšé<ÏLÚù~h‘“nÏÐ9ôÕÁi/ôzá˜W,΋Q¥VÀ«çÅÁ„O 6½´lxfZ;kN}eÉø§)cÑkk)ïdþmN~Uœ9_´ñ~ža½^àðéͰ¸ì]#h»kÜWšä²¾èÛûe ýzSç _{¤HÐTR«žrRê¦+®Ö;ÍŸV¦e „åYZœ’>Z¿{sìJ½ Qâ6ZﴌԸWýíaŠ IÂ2ÁOp{³±}À^Käz^Hæø?–×MJ‹Ï€·$Óï”Ý…œ˜ªñOUúšÖ&s‚–R5%ZÊè9ªÁ–BÔ„ê%„4¼Ÿz·&0i«{èp?’ÜOí·ö×ȃŠÚIÉõ»ó‘äiIÛ€áE^ËÐÑÑÑ9ù5BÈìÌÌ«È:$üš›}‘˜˜HYž' «QÂñR²†:w[5hƒs…0THR„X¥ c´ñŒˆSˆC2¸¸P‘’£{JaL‚AœÃùäÁH>ŒšawÍ4ɽü ƽd…S%ћФl¯×0žªyÊ^ÅñDˆ¥Œi%üz3Œ @Š¢N£… `Ì Šàs³ìŸÁF‚[M##˜9gŒ0Žw`3œ+“Vv9‡¿çx¢U<¸,pxGT3ôGN#áœjD]D÷4B¯iÁgÅÆÆªÐ±èÊããQÏpœ^å(ˆúÔ Gñ+^èvBƒ¬‘n4IcÄfÒë~Ôˆ Ž{ሇ3¤ñ FÃi4,G¨²+iù¬Ù0oÎxiZ;WœùbKú¢×ÖRÞɼ0¯™/Þø ?Û ´<Ïfáb mµØn¶¹îkÃ\Ûu@ÖH ã–¤Tð±Á$ ¶Áô›Ý‡—ÖÄã3\’DÍ o÷Å@û‡ºxQ)yº³ÀrÅ»7RãþŸL ™d_nÒjžç5”ÇçøþŒ\¬3,ßEgÀ[’¿Hµ÷$×$ïóêÆ¿~ô±).‹;hÊæ¼QXæJIKÑéð÷#pÿâÒù/´¬ g^d¹-+!h‡‘ÂoÕ3%p»µHáÉŠŽQÒüxð¦ÃÀV8e†óåcé”U0¼Šµ&°=UÈŽr$B»Fì0†l°Â ñÇ=g„ 6hÙ¬jV¥YAyi t[`ù¿Πy,rÝ…ÌÄm‘üE¤Èˆ5t žd‘(ÖȰ)4+ šÑ!2pJC6E2ÃrŠ+´ZrBß'‘ÔÈ1¿¼Åê?†ÀðÁa·`Í%«ðÞ³×MWzQ#Ó’÷'»g¢Ú÷·òZäÊ„ä{,yï–×NU¹~¬¨CÌ [žT5.ô+\ì®Ó¹ì‘ae»ö´½ÃììÌÿÊ$²ù×ü«Ç÷'–qj„=+0$Àp9M Þªƒv*”‹õD)ŒT˺6ÀÙ|Ù§Œp¾FòáDCE-©†zQIÑB´Ú±^Õ_ƒG˜ß|hŽ+ô—3¶x6gËä*ÊJ.„´¯‡Îl°Â9 ‚e0Z"7þUæÓ°UÞ•1P´h‘g‹ö(m1[á´E6R°DåÜ$Pºœáˆ@±ºêàXKÄÚ!vÈÏAxø–itJ ¬4BOƒLtH_?‡“èöÀQô„)‚r™!bó ÀÉ8êã~èwÁ~Ò].m –A‘q ‘Q dlmâ|qÎË¢´E¯­¥¼“©_±â¢ ŒBÐJÊ”edÝjh»ÜÔ~;ÐùfWÇW¾}wšü®±óv óÛ¦È3æùd•. ¢åtÕˆËEÍ«ù¼g÷ ‡û=*€«ZKʇ}{ ‘7L‘ÿe¿Þcª¸ò8€Ÿ„„„d’ÉÉÉäd&g2QÑúæ)¨‹.Êc.rõzÄûâ%Zä-Õ®ømU¯´juµ®Z­ÕîÃýcÿØÖÄìn]×jZ«vÛm«+½û;ƒe»¦n¢¹ÛË&¿;93™9çÇpï|?SÓ(EU‚Db ?‰S÷tí£’ê›ö²EkƒÎ€QR·Š*ïÚ_–x®Ù˯-YÙ3waëŒÄ­Éó~ŸkÿÄ^~«Øù…½òKÛÚ;+×—¯ý¶È ¹»¬âÓÒª›æîçEŽOV8ïüßûüÔ^q§Øy» ¬rzB4¥ÆLa¿¹p àñC‡ >152Xø‡ü>ßÂô ÛIDQ˜ˆ¶BÐ/å©×c@Æ!¯•‡«7p© €”çIZ€Þ3PŸŽZ9ÀB‡2Q{ºžÇNeJE¬Jh„ÄBã(:°Šwr õ›–èµ #VÔcNÛ“Åc\ñ?4ë°rÿxáBpE^è^kˆk>ž"G¨ ?î±z¤¼dI õe¢cÀ•Eè`6òÚy[û …‰b¸,GQ n¶¤¢½•<¸Aݦ:!;ªù‘®À© ½m]ÇqÞF vWñâc—ÉnÏH³«úé9PûêønÓ:œêWðKºh—ƒ7¹Íº\hoÕ ÷³É&E²‘NV¢C™ÌywƔǖ ‰Ï’ôÄ’ôØHþ6;屑æË™ûMÖœ ÇÙ«Uõ$'e¤sR†ŒÙ>³†,I_)³üFÊ@všßXðMvƦ‰º¢(žOŠMhéÌ4èë·œvmz‰”ÿa?]ÓrÖÓü‘§åгù·ug›ÌZOV5¹æXRU•H’Be*2 Wu‚‰®ë!S´ˆÎ5î_Õ¶}\Õ@|´¾ãŒ»éìÆŽóî¦_{Z×4'LˆS$ð? '¸+9ýö Çžk÷ ʂ΀QRß9î,«¼g¯=—·*V¥” #ÑòžŽS´âi)ç>(ªû[‘û^‰ç3{y°ú|°¼ì†½òúªš(J5…E`ªarÿá?¬Žçkdhp¨µ©™Qnc8lm<ê[Êrèû˜ƒ×ŒïC‹ÎžLN/pÂÊíÑŸ+쳢ݹ!­¹$/FЉƘBUÆÄ8‚©‚ Ä4uæò«Žæ£ËÓÙ ·ƒ¦`|Ø‚z³Ÿ».P§ÏŠöü/òf¡#¹!»r[ ,%!ޱÌè8,ÂÊú$UØ—,Eýê[„z ¾.`æp°áñ#,Ÿ¬›Ke l ' ?mY‹ºÍô‡êªâèt .´'@ÚV޶;ŸêVñS™˜cÆžj´ÝÁO>¾Ý²«Ž"[ÊCƒ^dž%‰s£d¦Âï]fXUÆx? £aÂL-¢½°ô\ã›'+6^Yß(\¬i;ål@K—ë6_ªÛ¼)o94 YÔYŠÌ®.-½±¼ü/«¿Xá¼_ì :FI}¶¼ìvií ɲªI"Áa“uÔ±`Yˆ5ªP’õˆÆøÔ‹ò¾*v«Ï{vÇíe¿Ì*Ð1âFJrIaá ß÷Ó`d`ÈK]¿ö'øFÉ"†Ic¨'Ÿ';Ïk+Oº^ËÓÝj¤ÏÂ'ì·¢últ$_vÏŒ €‹qʸ(A×± c™JcY’°Pž²97´;õXQ¯ `‰Á‘àÍC³L'˜ˆfÉ–®ÊCoæd’פ„²0•¨á„…k‘š( E†DcA#:±Mö,ã3Ÿø0ïC¯|~ׯ”¨ñ&”Hð6az¿´æïöŠ[ÅÎÏ ËnÛ£§n•ÿµ ¢%q@q”ŒGG•OM„é$«ê‚(R®ÈЬØqÎ_DÜ]VY?=)¾IŠèï÷ ü4ù|$~ߤèJe‚E) 6tÐ0cýû|À6€9¼”‹ÂkA¢#FØ>›š¬‡RQ£`)EÉ¥:•§iÚM !ªÎ@Çmè(Ð(½gEû¡>“"3јڃ& €¨‚çkĆö[L½,Býê²JS˜&R"Š’Æ *‘DS ¢”$Grò ¿þ\uãWµ.¹w]ñ#v_®n¹øú™FÈ4E"i*-Ç~/ ¢È“T>°ÎüùަOý»ëóíå?7ùs¬Ç> \4àÔWýÃòžo-×¼ ×Â5 OFê £[¼õ3¥‘KáÚ.Ê{FênN7p K$‰ð${nüïŠÊG‹Ê–¸ž:\J<t¸F‹]QgÀ,ÉM®‘L+.u*Ž¿f¶ßuº­qzI¶&-zêô?°Ëé “æ 䯆Ò›äÛΨ}n÷‹]­é9„géONvÖÖ…&C“oG#?Ž…Bã¡Ý{úx¾Z§Sð,jD+À1ôçO€ÁmÐà˜>Á1ãÓúgNe3¥‘n+œWØg‚“>;^Ã2ºEÒtx ÎÉÍSâ‚©”ƒ«glKâü'†ôïÍk$Qoï2«2ižÒîG(ò<7åoÆ•HOKÂ*~ž4G-¨­+W¨©jB~\w_­Ù÷«ªfTÁyoýÅÍo¬‘—}ß×€ŠH]¶BMD>Fa]–:䯿P۲Ͼ-#q‰–åuDT1ì*M\mnÁðÎý—WM¿®jþ¥§Çù‡Ú¹ÿ3wÝY×ÎëugJ#çü{ð6Gü{ÛË|ñ¢’|ä$"2æ?ØZõ½Ã}ÛYþ§Â-϶Uß*øð‘ÓuÌ’|ë(»¹a³ŽðÇV¤ÝqºJ'i·í®[Å•ï«ÕJ‘œ7>¶»ÿꔣUç}G¥!>žçŽe%"Ýüúfh"ô–,‚¯ÉÐØäØ“ÿüGhü£Â’$^£Ño´¬¢ Á΋é3Ã`>ÍÀ 6P# „´ÂIKU)Z"ñ£`6§BŸj¡¿úñ] œÌ… eŠÅ Ð] -¢£T°sø°8Fl-‚TŠN›ÂÃæR;½j^ª×Dï¥'N@W'(ШªÅ*:WOáüyì”b‡S($IÉ+¸¢¥*Ù´tH_ ڢΟ&XDåv"†òนµ/ÖòŒÄIŽãÇ;LT ¨ÆDˆ÷%E"i÷Ñt üð±Žà~5x ˜z©Ëó’$á †EñË`×6訂®ÀH.¿pC›/ì™ÀËÁÿûàmqÑÃ>:T'¬ šš¤¼(ª9QÍ <+땳S&Ö'G½ý½Ë¬Ê´F&,kÆ-i¨¤ÈSÃr=añÁµsaÙ «Ò°#ߨj¼ákö5 ?>—wËØ©›Ð'g·ï}ƒFÑåÍvŠ¤È¹³_æ±M%w )’%KO£ÑÓè=½'ÊAX²Þ#$ˆCB9 vl“ß! 8¶ãرŽ]’C°ì‚–c96!÷"¶jC—£d¡⮪n¥þQµ”…]HÈÑRJ³ì6$¶û{•úGù§²Iÿàé—ɼÑ{3ß™ñû}?ãÙvÏb¢áÄ͵Ð~¼¼:WO£ðéϺR¡>Uë¿´§ã‹Pû¥Ä!W÷H€´À6€"—ý­ñ¢‘‘½W=ïÝlî2¼½JJ-<¯¢‚Hè¡ìÜ»åµO­Þ‡Õ pÔYêfª‚c‹çªÿoñÍ5í¦³ôuò©MúÉ —H ؽ5-õ[«gÔdO¡¬ã›:[ØÒð[»gÑtZÜaDNº4Éé€ѹèóÈ+â‘HÆ‹ÎÍ=‡ò|w'Á›iºLÔç@½ …hЄ† ôœÄË=€$ nè¼5­Go'qoðœ} :cDC:Ô½Yzò\¥¼._\³<¶ÈPã&tÚ._Á,ÅòdV@,û¤ Z$°*“D˜b}¾d\x … Ñg¶¤£;èæå„ÊÔó›ÒÑaݯ6•Ã)r ~¥”##‡KQ?x½ ŠlE}4hH8]ô.H,,×yà ì‹ÕAÌgeÒÁ“@nCEhȈú­hO1“­ÄD&b¬â(ä À\º\ZªÑ /: fíC'ãG#/‰c~tz:Þ€Nívl…Ì©`9åSX)bcŒèã D,ÀH§è#/:ê{3ðºTŸžÃ^>ëd9ÇÂËa{Šê«õEQSNĘ÷£® b( Šž<3h¡qÑmñu$4¢¦5°ï3zíŒ~mØ´Øã™^ûƒvN—6­›7j#ú¬ˆA;[Rx!;3S`c?[ K ·3¿èbc €Çí†ÿ…:þkŒ†:fFo5uúZ®¤ž»-u`ô"\˜5f®¶oÜ !g 4 @J9m³ŒÛn;ã¥çMí—m ´] Æ8§©}ÔÿþæŽ}•U<åÓxÁ «æ ‘Ãn­zj]éŸì¡IGà‘Õ3asMXkÚbÆ ·ŽúNß=»wÌê~boXt7¬— 4lÌ–æ?+Ξ5¬ž1æ?×ÿäd¦Fdå*Œá‹¢„ÕðŠ®ü§Í¯…:®B4ÆÇú!F\kêü%0I°Ê+Áƒ?÷·ôï &³rqHX‚Y¨CåMÂU®Ê¯\W‰¾nBíÚ¨û<Øz¥¡%^z?.û[aŽ7š»àÈ$Á¬o4µ_ðï/H_RXL”‚–ŽÖ¡ eè¬ ˜¥WzÊP·õ—¡^“¤sÐ$±ÓK]>öX_lľ­hØŒºíÈÃ)U"e°5 uW“â7T ¯S #6h°Bês(özA‚¨á¯‚Fc`Ö› Ôna}Î/Lô—œ+EÝ•èL)_™·„Oây¶ ÎÀ‚šðå9%ä ’G+F.(ì·¢3Íè+æþ ¦‘#~´·JþnZ*xL€´á‚¬•²ò]ôþN‰UN7£î}Šñ'ÕHa:äAŸ6Kr2$1Éqà_üèÈ t„>¨ç óÔ Q‚L k#×°äbÎê™’ ÏKVE YSÎ?Á†JÖ/¾]¾ŽDÆŒ^;[’1jçõ9ÑÒµÑ2À•?ê3£¥ÚyÓúÇ[64d¤òDF8Ê$«0Ãhå{&óH õF¨ãfs¸óÏBmñtÿ¦ KÁ6¨ŒÛ ®ìíÒi² ÷1”e(á8ê9¢ºiƒáª¿õ¬wïRHŒr&ÐK-0Ò¥ÐÁxé u„|áom_6u™\õµŒÚê·˜”€g,æðiS MIÃjÌq`©j§ä˜t–qg®ºY¶kÚ¹|yÊáûÆæ¾cÙõ­ÝýÈé°ÖM$Þm+Û}wíÞ‡µ¡q³{Ò¸µ­ª·¨¬+¯èZᎯ-î{VÏ´Ó§¼fÊæûõöšâ”4ž§ü…IUrúè6ÛÄNÿ#‹Ø á4bó¦Œ;ꧬžI§ObKÝ×–]o±‚È8Ë.[¶,òÃìüðªhD‚ØÏøçΜ¥,…j·g¡rɸ‡Mè_ì×mLyð_bBBÒ¤™L&“™Ìd¦„‚¢»tQY­¢@)miy*Šˆ } ¥€ˆò *AD@)åÙÝ„½[•ÕÕ“s7Ù÷÷îrçi\]Ýó\Ù;ïv£ ö~ÿ¢/}×Ê›m~išv~óŸçûùêaÌHpª´ÅTE\Ì†Ñ ˜Ò¬f 0‘M—í`iEœ’—(µH©DZ$1FÓ,)îˆ& {˜Î„i-L˜H4£.f‹HX#o0ħðøú÷ž—˜*ȪYS0е¤Q³¢Ù¬ÌàH2¹Ì¾LhÓÀ´…¨Æ¯…I\2øôà3‘#à°|`¯\‘‰h"h!üÛ^)üòb¡âPGI+«¢"i†¡…hFÄGC‚N£ë;º!u×P’R)&o†3ʃ5a×HçaE,º_Pà äy•딨Õ@ zÝ0Òƒn8C¶Œ¬0àä§–³êà”†<!gœ0è蚆pÞ çÈI…‚,‰áTƒ3‹†UvÄǼÐkÆmϳ5¤þœµ}Õãò÷ k½ÈI{cüìuÎö—º¤%cêËÜÔúmK9[ÆÔç9»îÛ•'sŒ"Be’²›¬Šé)·Ï!?Ü­·=×kZˆŽv‡,ý=í7<í׼툜+^ü€>iŸw5û6I4+‘E»EŠjÉ-¹ÒtbáÈ [²§±$ˆYaÆÛríH7îª~þTÛq£¾ëKO ÖõºNìíwÛÍÚŽ‘ƒ ²Z ƒƒ"‹q¬ºÅèpe:7K£h™¥hô+R’22•j5Í«¸S\õÈæzjsý„&)ª¼[RùŸŠšUgC¸ªÄþ°Ü}ÏRuËXjPÇnà¤p ¦d!Š¢Ó%•O£û»ÕþÄæ^´Õ>-ª:Ÿa>¹#c<Ýø—¼ÊÿV6âî3Ö°kä‰Õy¯Ùã$ø±:þUì¸_êœÐd‹øTDÂý„"¯~ |hϯ^ýôè1&G–±Ï‚Ï~}P#˜Å¨‘Ð¥íx$øîˆq-ÌèIÍšä)’ üˆÔL´šx–¢’TtY:ŒÖ c([a:Ÿ¨1g†Ù`ÍËŒï™ü·Qþ^™‰[P,cZ ¼4ôî>V> úlø\O.Ùo&A#ëˆIpÇQŒáŽ…A˜Â®‘éwð› ò  ­…… e‘1SÇv3i*ž£Dšå Ÿ"/²›²Iß\môµj§Úu­vJ Ö ¸Š¡1}# ÷Âô1è=v yÄÏ’Ô /rd:‰1ÑÔ¡8í_ ÖÂ); x¡¿&2o6¥fØH™¨Ð°†k`È9PO6 U?ýNèëvÂ:Ç-”›Õ¼ÌÒ,þõp’áÀX£ø»ûvò2—rR¹«—¿WXk9gçÃÎ×ú”׆íˆí¿i·,go äí}¦Ý÷}ÊöžbJ–dIA¯¥ÙŒõªûª¡ãj]Ç­Æ“7 îÖo›zæÝ­¡Jÿï< žö›uóõ¤V<ð· qÉu¬Õ\Z‘¶¯ÙT2rÈ;S×zÎÑPžš³ç.ÍJ×cc¸ýMw[¨ú¹ííÄ«ûê«é$ºèªý~‰$ih%…ÿè(^d(^·9³¿¨½+¯cÈÜRºµ †Û@QŒÀ²2Ë òYµ°s]ìTºÃîyYÍ“û3ÌÁRû’ÊÕgCxênqõ¢Õõù.]¢(â¢0R©”DY¦¸ž¦Õ2®¹pUhމûb¯ñi¹çÅŽGÅŽ;ÅŽ{Vǯûë~±TÿP\õ°¢öAIu¸ûDÜ_ù\\ý¸Øþï2÷ßÊ=•ë6’Ç))jþÊÕÀËåÀ2qÈÒ‡±Hðµ¼üîloH¥köð,'Ódi;k&±N eb&9;f$àñ[•¥ kjÒ#Î[‚øIƒ©½0¬°oá˶±–d¨ÑÀYÜ,Ÿ°Ä_ÓA`àgÌÄÈ’ñàqÞ« DH6Ùez%åõ0¡'™3“6FŒ9se¤™ è“"ò+nŒ$˜. CA £…©Ð©ì}…#3lrâEð¢F²álgMV­C¿*8†ÃÅ)Žë#ާvimC-¹þö,sþDkÉ…¦j_›ÙßZ4x\Ü+°Òœá9*ý“Èžê°kä´F› ÁÆêv1].ð…!ô{ Ï ÃG¡õ€”–$à4„hÅJ®XCüŸýzi*Ëã~’&ÍÍÉÍɽ¹Mo ñÅ…J[¨<ìKK[n)P^奠<, >œÑ‰::‹¢èŽ›I6ÙìûÇd7îì̺Šàw'»)ÝßAþ˜lô:d›_šRÚs~·÷Þóý&)f•M¼Õ¨¿ õÚ—­¯‹NÝ+¡:cGg%ÔS‰Z+pB´¦Æœ’`݈ðñ¢Rg­|\~¨€Vnêk €$ÉŸïפüG·ë~úö†HÁòHvñºd0Ü\û2s®H ®æñŠ£wž‰Ãm·ë:®J ×+ÔwÝ‘š—+ýÇ='« ãÄ0QŽè1¬`ŒÛ~¾²Øs¿ºí¶£q\j‚•†¡‚ndÐRFdÌGÝdMû¤Ô ¹íò,W?÷\­ã‡[¯W7ƒI`v8ØrWrXË‚ …JbÏ8à5ï)ìôê»Oæ·÷8eêiÖ·”¥—¥G¤F0b$Qއ­À°a …mkÊïòö͘ß[Vž ªßëËÒD°Š'"f¶¡-‰õ ­[Rby®¨Õ˜'°`sl¡*䃾òƒÙö°øàS‹}z¯´öÈh}n© tŸOA#f:ûc3˜ÄñÌâùXGÃaUZ²ÿC¨ üK&ù… >ßÂüüôÔSH7¨8ÂàuAèR¥ÂùÅ|ÿìÝ)ÿ¾5šCap¹€*rvlqðÀ¥lš¼c&t^‡.ëÁûÂY" a"äòp"`N¦ˆ F®t9ŸªàS-Õ s0š]ÔRW|^„Nç¼[#t f×.æÁ/îBÃY4ú¡±«À€Lt9d/MïE>ͧàyG²®:c>-ðh~ H{Bh$aFÆbV­¡áM8ÄîØœßå6m1Œ¶ {@ £žÂ mºáæ¢óõ…#-»ìûBXž•œX–A‡õ×X¢Ï…N9ѹÚ%„ô9) N»QãACl yA(!6PÃAá–%aJ™1‹~~°jÙú9U‹¼nj¤>òV ¾C¨¿u; I¬NàQ˜Ã hG²òÝaâÊÇå‡ dù4)/s_æÆ-h“_j2&’6jDDV…ÂÞnb™Õ¢Ø¨7MÖ›tuLHí÷À!.ÏêÖ/õ`’ÉšŽ«VJ…åJÿÝIë^0Çq¡,Ë‹g÷Ú`Ò• GŽÝ©òÜ«jù¢® ²cý¦1{Ý7îŽû _»Ûo8›®»—§¨ÛRÓDmÇ5W5 þEymÅN c°È(`rFHOéÖ7 wuîîÜÝÓc<Ö•×/Në{ûõ]Ç žâ´"‘…ÛZ` Üâ„°8Q)z“vN›+Ά•q[ò&L¯XΜ1›[g à û÷fû³}Õ'’²#X°y"ð*ÌôïÔ>2š2[g,¶ÇÅåSëƒõ©É6m xŸ ‘'&˜ÚöÈlÿ»ÉñØ(]$0"ìp<þåÍׯçæýþW¾y ß/ÄŸož:dÁ÷ów²²²"ÂO¦€äj…€0¨iÜ_Z>¼«>Ó-%ïˆ`SxÚzÂ*ÖÐ{@ aè2±XNBàd#×.ª—@÷èúÑh˜¨ý¨C´?`¤ÏArÑ‚›ôª¸°Õ˜áÉâFƒ”°‹ÃÁÊĨ互üÑ6@È[+g¸)¸Ùrºq]æfŒƒEX@ªp4èZÕá@=Ôï\Ìkò:iR/[úW"o%(&éw J4P-Ö•«ÖGò¶šƒóȳ æ"B°IªŠXCO8¬],«d9YŪ—30Ž Jè4¦ UÑ¡NB^‰Ž Õ/Ñ‘á@ºmhàýõ2#¸d¥Z)~^X7YQ„’ÛºÁ¯ÛáÏKžÕlû·’+Õ§Ùá×&øu)¯òR_¨gÕñðç‚.qN¿âñú¡ÞZ~m¬O7§K›×~ìË͘W§ÍÃyÔ¦.è¶Î©·-è2§ÔŸt®‰b9ÆpíH99“³y Ä~ÔQÕr×ÕrËåY®”ÿZòLÖ´_•&kýÆé¹#5Ýjê²fé‚•pÝ‘ÁáœÂ’p–‡fä„]‹‰[[|£¶íVeã¤Ô|¿º Ôq\g¾`¶ÝpÔT@ o˜D ±|}Þs7ånw=pµÝ”<­%væít !cb¹õµê*¯áD—Îã5H<}…o­âMºl”Rñ‹é9ÜÚTÑ“¹æ?+þ²_zl¶>7•¿Øk{b©øÎ@£ù™ÅöÌd1V<³8fLö)“í)<¯43þ§ ±ÇfÛ SÅßöÚþºçÀOÇ´Iú£®”(à &«£ŸX¤ú³ÅúÐb*.›.qü©¨ìVVˆ™Èóœ³u¥únöX¿Ýkû—EúÎhÿv]Á,îY@#™ŸýFs¾yß;ùõÏÏpræÌ p;0¬L^¸‘f卿Ð| t:|‚Æ è‹KÚà›øPA!‡ƒ c¹,)V±$ÚR¼<† :ùÿ¯‘+zja¨|ª¾‹ÀørИèÐ…=¨WÏj£!ó–J%êxžÁr.RÈØ¯7÷->×\8Òò.E J/t5Ù¸p;Vp‚‚ƒ 3Q_òVQ0 U£nê³Ó _Fô/:¤ÏI§t¢ U‰¨ å‚‚éÂÆm^‡šKá3²îÃГô|@!ÇD)(b×Ñqz¬è¬µ”Êz«Ð€„N¤=-"þÛ[I_@ÿƒî¥cyïVT2nT¿'Ä2y(fY·†‘‡qrW´øìTÊuœO·}!7ɯÛ>“÷ã'ñþü¾¼ÌÕÉs¹I ºÔÝõÖz˜Tǿ̉„øuép*}¹‰³ eª/7ý›´x}ÇȃBYÃ+¯Å\Izöˆ£îÎÑãàqGøÔt{™"ê«õ×Rã5g#(r¯¶ã˜©l/Âöj#§tïÒÕXlÆ0–¬Áô9œ!GòŒ7«=¿=ÒyÃZ7YÓqÍÕ¡Xªi¿åü/ûuÓFvÇüI•"!YžFO3462a[P³¹'¹ ÁØcÆÆ†%Á_8NÂes.s&„#’¦­´G®Ý„U»Ú?ûOÕ?ÚªÙíæâÈÙlÓn¶ ô7 ­ªUø# ûGÐOOc¿÷æzßÏk„Z¢ÈÒÁŠÔUýEoý’v> 4m‰¦Ø;À›«À|qª¡Ýî5tô:º [{Œ­Ëi$bjóe»rwÄàhX¶xØM1 O¤¶2þ½ßçšY=Ӣ㛢ŠY³û¡Åw¯´ê¦¡|ÚlŸ)÷ýÍìü¦Äy¿ÔûÐô“ÓÈ×&ÇmÑþ@´Íšì7JwÅÊëwå† ,&*6úòþòé÷}·‹m3¢í[³ пš²T]+²ïOŒÆ8†&*aíjÍÿ®É~Ûl¿nvNíÓ¢kl·^Éަaݵ˜K–°ƒ@‘ç?ðàMRd^[šÆÌÌ O³JÂGi4jBg µh¢àÿžÎc’FÆÕÐÔFÌÈ)zÍmÏŒŠ®± Ú>ØÇ’¨£jõ9ñºWUÎhÐx.Þ‡†Éw® Á7ãÒ-D!ãáfðRC0)ÌÑ›´YÅÇ‚†¡~¤Ñt¦Ù4Ú¸œFŠO…Á*º‘†ƒã­ÛÊtK 3ÔïC^ÔíB}~ÔíD}+§‘ˆ õTKZèó¡¾E™øMkX_áæÉVÀ„KZ‡Â¨×‹N$« øÏÌÉè(%¯dX–ÂÒoa† ¥NèЃŽU¢ã>ÔS)©àÔç^Â…º*Q¤ZÒŒòªó\š!t×á›—N±ðÔa¸Ò<ËÉy&GÀWÒ6-èsæ5ª]Ú£Üm ùj™sUsjÕ‚&ý‰&ãŸyo5ò­'y™ÏtY/t™sZÕ\^òsMʼ&mA“úí¾=ë×%ò²(ØâÀ{ñH3qBL$ßúaUíd°íŠ7™ô7AÄ_Z¹”ÿ¼¦ù“êºOµHÈq7|lÖ'§CÊÃÖ/°SûÛêÆ 5áj½ÃòÝC à@R«/ùµ»îRMÓywýÕ@ 8(.b)Wj†Ks›ô†?vþèH“cw®RFA€“SüöwRŠ÷˜:"ùíƒÆHW~KqÇr9aè®t7Uî*O‘oŒÁްÇ1_¾xé¿xöì)häŤÈÿjd±•ß·c·‚‘‚ƒãd¨a¯”›#¹oB#Fi”Ñ=hTÏ ”œ‰QbŒª7£  å ß¨Ñ9=÷~E(Aàq¿Ú–xíÑHÒ;£F»ÑDšÐ¢q=+þÙ‘YbÅEñKx‹ÂÉS%еÛHkþP}þDJw2(ŽÖ-§‘’áPÑXÓîÁ v¤Á2z'sÆ´¼ ›“P§ õ/å² ÷¢ˆcÅ4"ÙÀ+9À¨¨-—mMˆã¢‰L³3™jƒ  ?úÀ)¤½ŠKyKæâX'£¿ZR ´†H:áE½•kºý29á—¾…áàDz<‹>yÅ‚ÓT¢~¿4á'tˆ=f^)'2ØËÉ &4ÏD 8°N>•“1¯Ý± KŸ×l›ËSÍkUó:8H}®N›×f¬zì¾­—¸ñ_jÕ#uÊó¼ä]ê¼6s*7ó»Òs|"C±„&<<Œp‡Ùœ¤-ƒ•Á/kZ~h¹ìªûØuâþó`+d=bÅRÞ¾x8Ü&}ô7´ûã1GXvƒsõHû®†^ãAAFƒC’xùž„õ4a0Ã`š^Kø»Ôg}õ€™/I³&-ÕÊ:d©®Ö´LzBŸ›B¥å šú9\#˜E4I¢ã+³+:Í­]…íýú®>ý±¾Â—Sª[ÛzÜÐ9&)jëŠ)úõ|‚´šqpíiŽ`–Ç*…¼o{ö×¢ûaið±Åùx­Ø~»Ôýâ^tÌŠÎVתóãG5-:+Øî—¹oŠŽsYšhš–†`êdNÁÓÁ{¢óV±íÙ1[ê¼fu=¶¸o˜œ3¢+°Q“v<ܪiäFñA0ÞÑq¿Ôûgƒ]€E—†g¼ŸðýwOssÏ–0ðæ5òƒC¤PgGGiŠ–cšÎV¢³ftRý&4rJÆuè¬1œ öÑp:­G¿Ô¢Ñíh\‹zKdXGJέ>'^³ÎèÑÈ>44¾3Ó­:j§ 4æ±À°ri½`£+ß(3 7GCÆñpᩆüáÚý£µ†±zh—Óˆy¨Q?Ò¨;Ú{ªÎp*l{ˆ’—¢$œ@3tAêñ.&»õV£n׊i Àp£^ꪒ¨Ð@µeðJØÈØ‚Ž¹%®Dܨˉ†¨ËÇg%+h†ãù8 ú"Tv êó£AøÊ.QaÀ‹†¨¾lÍ®©Oè “‡Sè^H’Ï+κ,8¸¨ßƒ>pD5Úä;“â M0'™\ t¾@ÎoÝü½:ã‰ì‘ö\½õߺ”§ºÔ] ÔªÇîÛzi-è¶-¤/èÒ^䥾ȘړÕõ‹¤$–Ž’ZF­e£ Ë+8¹/[ÿ™'ôåávpÈUˆãšæ‹~‰ —}!ø8é]±”?ïA·—á¾ÂÙ÷Rÿ´UÊ÷[ÆŠû%U·ü‡ýºi"Íãþ$&&MšL&“É“™Ì¤/¡€¬ ®àËõ€UE„J·¥”¾"/}aJQP^ -”×òVäýE]woÏ[u=uÁxg6»ÿß%{¹Kö\$z¬îåÖso/¾!÷›ö4·Fþ0²ö›_ÊÐÎ<ó›vú|?OÕ·…çÇsõ½IÒ‚Õþ¥ò_Vç í… š¦à³J É`fî—y–y«°hqÀž÷Œö¿Ùî™…ùBûBqMYÂfÏÉiœ©þoXl·-Î}Ù‹{xÇ^ˆžçÀÀ›}YT€È€°.=~m Ÿ÷ñãGOq²6É­…ox–WâÊPHÐÄ4©}é<“‹¦rÑ©|4ž/‰–’$ŽF¾\tZ>ÈG'³ÐIª×¨x~ÅÂ’!òœxÅ:©EéÄiƒtÀHë%ʵ˜kq ó4'£YÇ©ÙšÉæ¢‘c»N{÷hΟl2Œ7™'<Æ P$eNy5£†¾ÜiOÞ„çà¤?½D'ÁÄ=Òd}•™æŒ–ó¤Ö€ÃbË(ZÍÊëÒó>s·ÎñÿÚqìbo®¶(H0ÌÕ¶AÖϺ½ ‘pè¯NÊ?%àá\Uã9—眻ä󩻥ËZ!ªƒc•1¿q{®Õuœu6ìMM‹cøŒw6ÿ’S ” ð:4vÕÕ!•¹’x9#‘&`ŽcU DÈ5]ueÛæGûÒ–óÒ—ó2#»oê…õCNfpcôV K×(ÌÆR Oa¸Ûönج>©õ©i9_ë;ïn¾Rã™~çj†LŸ«öιZ®T{¯¸}ôÏêi¤å³j±Â~¸ìj†³\­j¾,xŠ“ÓaéE`j߆­³ŽÆÏø‡KX‹1¢£Lè),=/4‰U{á(8ü¢«ùrm@Û„¦ÕêócÛ±4eœƒ$øci…fKî`¡' i*èê»ú´íýúö¾‚Ž€¡j%Ànƒºö€¶µWïèý@—ACw°°§KìÝßsü}»¶V¯ÖÄ0*Š Ž“ÃÃŒ$rTQîΟ7Ûÿaª„Š8?ž«&Û=KÕ|á¡¿›+¿³:¯›ì_[„39Eæ˜$Å”¥¤ð[$†i Hf£h²|“úü^ÃÁØx˜wÍâëÚòHõ¿h²ß²‚£l)éÿ¥¾Nc›HÏ8€¿R$K–F£W£ÑŒf4c+!„c³ 䲯ÃÂÚ;öÆâÚp$>b;,!‡spd±$ ’Ðý°Û]–@ Ñî¢JU¿·R¥–-ÝåÜÒnaÅ’`÷gË—Š­¬ºXFã‘gæ™ñÌûÿ½ ¦38±»µM¦HB‹‹ ¯4²‹ýþ§°ÉÓ<9JÉàu¬JeĦ hB’k̈¦a:jD“64šÄt6£I8ì»hÌ‚N›YJZ‘‹1O+i!"Cðoa•šÄi9xE_%Û….ÑGv4f@Óf4¾ KhÜž2]L•¡)h î’M,_l´¢Q»üuÚˆ.—£‰íhÄ€ÎÛÑpõ†í…pMpi< ò£áõ_%ˆë[Ö¡V ‡}¤c÷X–PU¯!ÇQ·Eɘ¡T4‡)ZáÝ"^õ£S4à—úÃD^Ÿ ÉDhN–R€ ÷C!Ù'÷Ùt!‹¢)†‚×A 1Öd£>|ÆH=ŠÑ@uî'Ö¨Öð"„X€àè4ž³× ¾ZÔïù©±h¢ íÓ¡äi* 7 ˤ ¡®ýD….MEÓÉBÃ4£sÌuú-6n‘bæ/Mú熂%©0f.Š™òbRñ‚¤‹[4qsÔKIó£Yû̬]’`‹&å1ý†V\ʉIóæ’çF]̤‹›KâæÂ©àGóÖySQ\Ú·lŠ[òç-ú?•ég ós5 „ÆEÓ"/ÀÔf3§ª—ìÉJmÀ\c÷M_Ûõú¶‰†£;6å÷Õx³Y5Ÿ7†g@ÁÎ/[zo4„? ¶_oêù\i _mêº.û¡ý³ÆÎ_6uÂÆ]ë·@›ð˜çrb[…£å=×*N`DÒ ŽóU¨kÆ×:ÓÜ}¥¡vLVÿ€.héã†ö«-Ý€™¹Æ.èNaØX"@j²˜âáYÇÛÒ OÚ;*ú^§Žÿ´'{_Ôv"b;JùÀ²dï\Mˆ0×)†ga,¤31]³vó5“㻽Á¿¹¼ž».ß—ï‡ïÃûØxèòÝsÃïm§çNÏ×.Ï·NÏ}G¢R”òœþßX\=…¥¥j5ƒåÄ ÿiÅbŽœÀè¡ä)í{¶hoWצªÏ;îƒ÷«ën;ýëEÌᆓ˜ºýû?¤V¯ý$Œ´¯Æ¯²@À‹Ì¦yur°^Jdë²I.YlEãÉKóñi3éF\š ¡(2ƒa²hœ‰I³£Æb4mCËÑ´‚>m؆F î­rWçS§‘lòrÄŒFmè’M&:û¸/ýÂ*Ûiڎλ°#«a&DXIsh™Q çZ˪£@‘½S}Ήnû…öW•diÄ5Ô¹®t¼´’€/m%§hùŠzÑ` øäŽ$*J„r’"^Nù`Bõè”Gá,e®$0K’˜ÆŠÂµ+ŽÔÈ Ê®8éCƒ>òX—³$f†%ð:̈4«8¼k@ƒ~ñËž¢Èò^þ䵚à\õè\iL ײÞÝékaÁ©)&“dÔ-P¤FÀî,þîvÍKÙ¼mÇsIóÄûT*xi-‰KùK&í¢T²`ygÁüÎ’±8fÔÆLÅ1I—òXC+f)‰YtÀ¼Pfý¢Yÿ6JE1IóB*Z ã–âE“þ·:ÍÁ•"C*À!0þ«‘#±JI:µÛGêv¤7YiŠ€@¿u¸ïRèh^æZž¤ÞÆìùƒ7õ^õýâÐ1ø Àãr õˆTeÈ̼šás¡:_w¡¶iöб¯»oÃ×ÂŽ½œW'`zë1 Ïå±þ†V̤Ÿ7ê~0hŸ5‹&-`ï…©ä™Iÿƒ±0^¡Ÿ—¶Ïjó+y +˜Xž¦iЈŠÀRN~d_àÓæðL}ø!Yi~¥)|Ãwôï-pA¬e„Õ˜>Ðpópßœ¿ýWŽËÍÖ"}/ ï4ä,ËpéU$}@WþqCû\c÷¦î“®ƒoÑIüxx9νyÔsh¶¥çª·„óI¨ýzS÷äõÿycX> °$¾ÙÐuípo¸êçšô,†Tr4ÍaNM¨ÜÚªþªŽãÖp²(²¬‘„F¢'¢Öþˆ½ïTuïqG¸µ2ìÖíÉUåÀ¿†E’àH%E² _@á‘m†¿¸ýÞou÷ܾ».ï=¾;°îô'3B1dz ‹ÄR–Ã4ÿv‚²¹A¿Ø›l+ ¶U/vB^Qyu )(fÚ4K½ùÎjž¡’0ÞÎõV›K@2î&|Î…&݄Ůˆ¥<ÄúxvÔŽ¦½ÈwBP˜B(° 'a™ËŽ&À¦²VoX·ã óyÑš<-‚L ˜½ ¨­Ž|xЊƚÈÇ1ësÌFaÀÈÐ3àÄFNˈ͸N"u>/•qtÆÈ8ŒYšQiRvr÷·ù™!eNHuè…"m³8}S•õL}è™*ëyqè¦2“à$Ú±þ†Ö? ÈÙ • iÒCª”­âƒ[ꜗª¼MÅ{W³RJ€BÈñxN &àE2gÈ›Šu—=W _µž½iïˆTšÿÆÙþEó™5¯_ŸšÃÓ,LÍ£²yIɳfÏ—ÞÞËæ–“ù*pÅ0¢ðŸlm`¼K,5eä­¸;®:}kžŸÚÏP4[Îrù»öÌÔ»¯µöÝhê^µµV›{®†å±þÝ×=þkŽŽ/œŸ{ü Ÿì„$̰œ˜Èié±m¹½e]ƒº3cúþR¤42X~†h¤¬²tj¢40¤í h{Fµg' _‘C“”“$’c².aDÄ3Œ˜a âã.嫟Ժ6ªl_ëŽ?0ÙîHLD&`RÕ ‘GÆèD<)“ùžñä7•'  ™çcT…ù¡É}éˆÖ¸ãmÏ1BÁx¾jÃØøsyC´ú\¯¶ýµ¬n?'’P …ñ6‰ìÉwë?½xev¼fÛln¾ mÚ| +.-ŧڃ.”£ÍÌ0®yZVF,Ð rTh>| ¾¨$ÚwfÁ<*òrV¦5hA:^™׫‚€2Å;ÞšºèL‰–FˆÓÀfKÐöQt>-+ÐGZtQMÔ¤ß/” )LÁzKc9†[–ÆÅ¦Ô¦ó½%ÁåL[Ý…^ýìéÒ`+ʸÐûÒ™vЈ>Ø©E ŒsÝÁõ‚ÿ#©;ZÆ2BÌðœÙuhÔM²˜¤¼ :HE*â¡fÓÜ^"±„—ó”HL±»d²æ|õнuõT÷GÇMw÷5Wçš»ówn_¤ÒüjS÷'nßÇŽv°„iV+Ò4+&WBÞŽÝ—msVo"#"ŒÆXÆàm¹zcáI„ãá=Ž¢wc¾«¼æŠ­˜´foZ<®’ŠÇÔ£µVÿ†·—ôlo‡chf!o:"Öÿo›|ŸENõ€Ó>tµ3òbávãy–§Ä4Nå“;”ÍÃe}ãe£º³à‡HidDûÞQmߤnàœn `–sº¾¡bìçMC§Ùråá΂‹cy‘„åX9ÞIþ½Ú°QãzPm{h°<6Z× –ûó×Fó7ÕD&*ÍQÓH•ù^e=ì7jj¬·õÇoêïÖ9îU4Ü2ZþVã¼QZ;•–»ªñAÅÉÛÕQëónUãlv¡ˆ%«+(ÙX^zzmu¼nûWh ~ ~{³XÄâx¦â˜˜é2´PN̰¨!,6,!Š"–æKá@‡aƒ*´¬ ®DËjôA ¾G’}N‹<‡e¹I"̈)†§p–r*&‘Bþ´¤@¢‹…ÑÓhªˆÔŠ }¨A+:4 Z3D‰¼ àqc)LÖ&9—‘—ªn©ú˦}ÀƒÚù.ýT«a®½tºE7냊€C €%•óÝÔ ^=Û )< ÿ[X>ÙD†î݆ÜF4áE#á ‡&¹lXÊXPßI28PgØ‚&aí¸ˆI‚^¨'s ÛuJJÎËà ’çáòãÄ<òÖ àû&{–𨥊i*l†Fb§IaC¤ú„ÁÉ_ýß?NA”‡'ÿvÂS e±éûxNÆÒ¼Œ•lã¤,ÆBV°—£m qwfÿ¨8¼¥<üB‘ùςԟï†T©¡’w£ëohm†i*É©,s5}ïñ±Ç0bQ@(aÄ,-Ú)‘™óŽ]vz!ÇÿØzöó¦îk¹ÿµ0>ñöDL#Nßj‹ÿºÇÿ•«2]ýö¹4–MÊóBº<åPc‘ìÁPô>‰Ü’«øÀÙ³·ëSÄ2L+¥„Ô¾øÄ›-}Ÿžlùƒ»çKoæcotþg—uÝÝõ™£¦Xu9ÜhöƒO"Õÿ§îÎ5§NËÚûgN)Ë·³<œFVŸÌvVfÉ©™ª+ Œj†´ýƒÚžˆiD×È@ k{G4ý£Ú³cÚ@@Û9PêÐÔxs¨²ËœW•,JSñ˜‘J°î.Ž$Køî¬ü¿”Öo69žV;¾7Xÿ^ÑpÇ`¾[eýÎ-Š<65®W[ïWÔ–˜¬÷M–[åu?“ æu“ã[CãCã“S_ç?m¤gÀ_)R$$KÖèÕh4£[rì†,¹C!€ $lƒø M³K¸lŒ±—lll®`NC‡É¦ÊfsÓÍFmÕ? ¿TêfÕîFÛ(iUí²l€€Ýç5éþPmså®y4z5Œßyì÷ûy-‹\–¨>ÿh±šÓ¶S –³Jì­ÏnCÖ¯DV펟~½*­E£Ë«+Ñhщb?ìO჊\YhB‡®h HÔ `€x¥y"¢™HÖ+\‚¦a~M78 ¸¼Ti •Ä@¢ƒ•yØ Ïó¯Ú/6’Ë ‘Q þ,ÅhZMrADÎBYÞV'É(Ø 2Ì@ìË9nÏÞt¥µJ;Ó]4ë×^ö8ÕakÕM¸µW:ÄIwÕ”w]# 8B`P1FÊ&<c窮v—Oº•Þ::>”d1—J$|îž žPÈ…ÐØcѯ²“™"0ùE¡¹‹­h°¤üˆµžÚ¸…ßÌóœþјJMÞP+¢ `•ZÔgGÎ"ÿb‘4l%S ÅHCš´Æ­Ob+™vØNêÇóƒv4ãÙ(ôo#š‚Ë‚ÕI &k'¬” ÍQ2™„g’°„I¦SpRÃfùïŽù^y|U]´¨œd}[²/á±þ3­¨¦àMiîŸ s§ì?–*€û0C)0µs°HiZàóá¹Zç³ÖÎûÖ–ÇΤ9Ä7„;Èá¡3ðÀѱ¯4àðÁ„7ëÎ=²z@#3u-yiÛå OaœÂË’)¼‰Oxv .¥þ¾+ð¤ÑûÛ&?è(h®Nã Y`m û §Á0ØÔñÄÕù¨Þ}/Æùf?Üh~%Îà!^ýÿºÑ 7ºÑ螪۟²Ú}Ca­(Î(0ùCb×Ýà€Ø7¨tÆ‹"Ãåàó±q÷€®{PߨPe§W××§ iûGõ}AC§_ïÑî)?Àí’IHw&…Tú>…*ÒæNh~_ñ‹oNZÿy²ñSÝ_Lµ/,õ/§‘ÆÚ¯5ÐÆ_à"SÍ?L5 ð+ó™ç–šWæú“õõIû—ÚaüÒR—¨>c8£’तÔÞôŒ…Þ¬­­F#‘D»ã§_K@%ÐÈJôÛhôÚAÊ2›haCNÓ¢9IÞ«Z4YB’wN·4ÞL©I¦OH4d'gTü9‘ÚÃpœTÀ” Å;Y™‚‘Ððƒyây#Å;’¯]«B“ú„izM]Õ£®ãL‘sI¬s°â`ž¡ ¬XYFZVAéÓ^òŸ¾Ôf {NLœ-¾ìÑMw¦Ú¡Ä°Rî0OÖ5±\錗FŒ—}pGíÅ–ÓSíº‰ö£ –…o:ŸK:ƒ%Ú|Ô_‡Flïü0? Û!ÖC|ÔA(rè–ôÔ®)1¶º E)hfæc)qÅ®q¡P3é€*è·¢Fƒ¼Cö¸õ ÈŽ1ì]ý¹i?ª…Ðh aIz;ƒÏ F=>Î`&æÓvEqð}çi–hdøúÞô¿çEË —J%<Ö¦õEaæàûÂNÂ1ÃV„’ 4|Lä°4$ó|EvÎxµõs—ïs[Û[Û]—ãS»çÞÇ{N’àOš‰ž5Å-ÍÄÀp·%pÓæ~v®w²¾%sóvͲ°Ú3,MöônEÚUG; äf³\:úÕÇÅ»3áwɼ §h[¡ê³–±Õó¸¥ ÜrËá…㼓L P‡€¬Ǭr'&“¸ÔÓ&BµkÖÖ¢mX"eAN¯ Ù½)Ûô®¡ÊÀ¨Ø5¤éÒÅÞm|(ÂÓµ=ÁŠÎ~}×±·ßÐÝ'ú/©ºÇtçôP=c†`¨¼·¿¬oX3úÏ–5ì*àX0+>ÃÈhNŽ%§>ØqG©ûÒTûÒÒ@¢ÖT÷ÒX›¨”m¶¾25¼47üÍLšùÊR,ùêdý+ËGÏOÖ¼¨¬^¨²a¬ýÓiûssÝ׿šDõÙ½3›æÈG39Yîs´¬F!í#ÿ·YE" ’è÷ß-lJI%*…¯=G¡@ˆˆfÔ( ù«!ƒéãÿó”i¹d%ÐL K³ œ$Psš)Û8¨¦Ž¥PÔFØQûåô˜]QÅí¾ÓÅh¦îBŒ1«Ca šÁ¸ ÍÁ@ƒ¦ÊŸ®¨Ñì t½ÍQPCUeK·’iF=õÒ‚=S)/aqZú6r>d#mô×£‘fr 5¡K.ä¨Â†ôÁ v×{²ÒÊf‰¡ 8Þ! èÚ!¦²ÆÎØH Ûÿ=Ž]¯þÁQ0ç:“lzœ“_öM¤‹y)Ã&ɉ ïb°gÛö?äGTÙuÎ’2{I™µ¦Î~«ÌZ,Ù· Ì\Ræ¼UæDT9Q5T6\¶¦:´¢:ô2Q™¿¬Ê_Qå½Uæ.+sVÔ¹Ë꼄óà?j%v\ƒ£’<<Ý¢êà¢:kI•»¬:²LNf¯ªEÔä¹V•™+¥ð,yðPunÞ¨ÌZVeÂ[~(Û½P¶oQQŽª¾.)™=˜¥Kf!(yŠÆ°ŽòæYXN˜ù€Kög«w]þ[ööùfÿCg`Þî…œWjßvxï6¶Ãœš:æÛ@9:Ö…sßÀè¸ïð5û;ü7N7oæeÐ*ÇqXéɨÞÛu¯±ýYsàºËw³¾õ©« XòË£¥d;ű@)G^ɧNt´<´û@ pÓxõO&$vòp3÷ìÞ'®NpÔS»û¶Ó¯Ù›/P¬œg,å(¬`SûÊAMç€Ø rÖ‡#ÈjLì½höÿ‹ù:mâLãþJHH‘"F£ÑÈ£±lGP …ã$„+Îá+_ NbÇ$!9|;·CHœÛq. ‹VìR ‚nûe¿í‡Ý[iEÑîvÛÒ² ݪÛmÉaï3Ί­*¡~q›µYãëgÞ8ïÿ÷²aKß 14lî½j5õ²=#–Á‘ª~83堮 =“¦‰ÊžTé¥Ïâë¯ò÷}KêËvÏÀÄ8–NJpš$1†”PTSnÁoÍç?åŸ[íϸ ðþb«}Ruþ™­ê9Wû…Í 0جô߬úØæúÈæxÊ×?³Úñv˜„‡UöOj\Û©XÄÐ$¬ûàáÃ͆Æ¿Ö××6ÖVV:ÚÚI†¤0¬&-òh¦-éQL›LíÔ¥ÿ«jÁL•Hñ4FJ'w!Ÿ E94΢ù2´Ìn0R"#ÓEi¨ý„à‡TÝwàÑ iŠé“€¾À!“hž®.”£Ù2fsU(jÙê8¶õ •Fl… ÛF @"pœ‘{• ¾ËaŸ 𦼆˜ß8ïTTE»_¥nÁ[>Úl˜lçc>Ãd‡a¶Û2ï×Nu°‹~vÆs&`=õE§t»Ì’gï9rpÛ9ÇåGl“ÏÅGÜUQ_eÔ­yT‘¶êå㜗[ ªÆÛ-1HL¢›w§.×D½†©î“ãÖ¥~K iWÁAIÅx– 5ŸF#(\‹Æ.&S>Y怨°SIªÒ†Æ*\L?§Ã¥´(--S$’I%¨ëM4—\- ñÇ[PðQü3F*M“Ò°ñ„I&Å …iò]¨‘GƒÉn.n 'á4úR#®ÿjš;SּпCšüŒ6mr¡‹VY[9AgáTÅdQÀåt ––%ÂKÓ#rž”Lè” ÍÑoÔ…@Ž„NñJñµJñ•Jñ/UÁ×ê‚!Ù šÂUµ²;®Í‹ëò¡Ö5Šuõ¡5•|Óùñ½úV•¿¢†öƒµºÃ‰Êä»®¤¾rÀyøÂ·Ð<€œ™à® kCW¹á Ê6õ…M=ƒ†àUK_X3¤J#C¦Œ òùô5G8Åö\vx”(‡ ²paoÈÄCùÇsõ³íŸ\í³3Møº¿rö/k ‘ëqö§\ݦóà'®Ïy×ckÝ'\íS¾öo¼ýckí›s¾¨ &¼—–(×WW!åWWW6•?ðz©‘D<ñ‡ßýÖR& Wqø]PPV™ùú[JëGÖº­uOxÇg6Ç-ç>äìÿ8ÝøçjǦóà'®g¶˜‡Çœý³êúçV;¨ìyM³13 ÖL(±ˆùùïÿç‰Çã‚I Û/ÊKËH–~1M¦£æch"X…¢åh^æÌ?ºF–4h™E³e苦JÑ‚ Ýd…[Çl„½ˆÌ$HœÚFÊ¿-ëSyk°Í‚N 8d¡-ªÐ’VèaI/_· a£ÌIH’¦·BQ%&)µ+#ÿ¼¹zÂmèT.…NÌz*f݆¨Ï0Ûmšó˜ç¼ìL׫4bžé„ï€"ÔàSó½ü¸·¤ãük{v¦ ZÀáI‚ØÈbØ'RÉŸ–`-öRýº”m8[=éã£ASÔ ªŒz-KÁ¤‚|eÑ.KÌgûóuÓDšÇüILLHšL&“Éd&Óth-*fÜ“WÛ‚¨Qè-”¶¼­/« ÐWª‡´…¶RÑRhEÀò&¬Þݮ®/swÿÜß÷²î%wq/³··Ñu½å¥÷{ï.»Yÿë.×ü†™2Ï3Ó>Ï÷óLš'{fûá¬vÌÿªÓ&—±rñÊ™,Oª Pô(еÿ/v.Ã4r6MQ¾¢‘„Å:И ¸×´›è·7I®¥ â°E*à‡NyuE@ã,Š‘À’® ·T¯­« ä2X„J%$¹1km«%£„ 9±FF:¾ÅÐIú:‹(àÙˆKl·CløÔFEÙ뉲ÍžxÚÌJdf QÅ’<%‘JÖ±‡²ùÙÂü'{KŸU)ÿ¥«x…K%jgú¢VõR§úF«|ªQ>×–¿Ò•§ô¸Vß)Ʋ^ùR·ã.%Ô‚^µ¨W½ÐA½ÔÍk _hŠ æµ%óÚ²çÚ§šÂ¯«K4êMåÃêø–µrøp)øCºÐËK¥2š“”œd6s2›r÷p«ûã‘O¼'ovúo;÷»Â»û®º{Á!·<¡•ð9¤+ʡ@¸þJC·=¡{žðµ¶îv?œ…ƒïÛ{à8 ¼qߎ­è«m†õ P8ì'¶L„Œ“½†d(Èœô™æB5>è h÷d:h¸“§ÃjKUDz"›—IhŠ®©@Ã.‡À…´íÓÖ…5‚3½3miw¾¦Npv"§•Pm!9šÖ©Ð™vü†QÏZï;™x­I)(XÁ\ΰ…ÿò¢h'‘¯ØÌàQFª¶bÞŒ™œß«¦ôšÁƒÍWvcE;Ð9;<ŒÛD¼9‘ÿUSIäÊ9¬)ÅKi¦O†#I<ÍQëÙ ë:Ì’G»Õ)ÝNðÆsMÙcMñ¼fÇ‚V¹¬W/ƒ@ôåózå7Ú²§šÒUçÇwK[²¨+]² S¨ ÛK:Õ?«ò—õÛS†’”¡8e(MÕ¨ôåÏ4;–u{žUíú­º4”—S*{HXšÈ£¨ Žæ6‹†ˆdÑ$»ßÚÐÔ]rô|àò_sn9w]ÁûþÇNŠ9ÄÙÝ'E `ç¶(“´°çA÷ÀuGÈqͼb÷Ýw]“Œ¤7H’0šä4– CRð’ɰŸ5ùE³Ý¡Þðu±Ï’Û®¾×w‘>Pa~ˆÎ¹ã }ØÙ–k÷jr·Ð$EÀÒ&G€Ù£P^à«ñŒÔŒšãæÓß«‚AëÀI­¼ahÌ<˜0Fj‚§mýÎÑ„53õÅkÂIkl¼>¯é?k>5lޤK#1s̪;µRâ‘È 9mkp—Ø$Íc8©œå(IÁS¼„ØÄóÁâÊßþÕÖþ7ÛÑ'MWŸ?r}akÿ¢¹óacÛŸ›Û¾´¶>kñ´å±Å3Y”×íd‡”‡¬_ëÿóõˆÛ¥%èóW_þcƒ"WJrSB§IËž‘*ˆ*œU$'‘²•”ôm’Ý/{ûñ¾Še]…HHöÒe]QJW˜2lOÕ­>?¾]/"ºÒ%mIJW–ÒíHé•)CyÊPñJ_¶l{¨5ªyíίªw=¬Tþºt[]ŽP!cÖSI4é C‰¢Yˆo¬J‚Ü.ÏöîÖ]:è¸îê¹âõßqïyB¿„­£÷Ž£çlWðrW8jÅ!Pp|%ÐÓ•æ` @ÂMGðó‘3ð§÷£žÈÈ!GeÞV9%ŽKo ³sU×}ØÕw·Ã˺ìôÃ~Gy•@R‚X²ðͬçeÙ¥ÎTtkë¯xƒ šÿ ËÇÝ·Â’4öÿzWžPnáö¿™¯÷ئ®;àGª)’%ëêêêê^]ËNä$„@@@`”â‘IÛÄÏ81¡„@ÞvlßÏéît¾ Ê……‚…ùfaTù”ÔRÕ ¡?¦œTž§‚€¾ÂQøG¾°0àIôΦ¾L}tõWý†žaƒ2p´7bWŒªü™ÒHPïÒ¸Ôž€Ö7¢ëŠ@…ô!ÅPPÙ1ƒšÝN…TR¶_GPø=¢0ò­+Z¬¬½ß`ú¤¾íÑñÎ5çÁK®¿Z?«oÿ¡ùãúÖÏÌ¿Õ5o‰"0KŸÜ½—Ž{pÈ㥥ÿ[¤¾¦þ#™@¥ œ`kJ«T%(j@!©«P\ñÂ52¯B‰ ´ DýÌŠ"0£b‚”09€¼,q–@U„|2´Ð„&+Ð[™h$Æk$!Cdh^—5a`½ªÂWó„y¤€#`Í“Œv¸Ÿ'.=kl ÷˜¢þ†Y‡2j¯ˆukãÎSQ·næ¼fæ¼qÎe¸à€ Ž_ð«gìÏÓhA>ùfÓ\ß™°³D^F0°‡Ja¡f˜üÂõS“Óé'’úàÛÕÕäòœ^ºt©°°R¢ŽÂÀ¤¥›Nº³è±aÞ§í†?tqpHsàc¤ªnÞÝ0m¯\ðUlÅ{·Ó-¦i–Q1Lúì• å×´ f€@æAjÇ!]LZñu_šµ¡É.¢|—ˆÁë> ˜8´‹‹ÖtÃ1{¶!÷ꌞ‰òHF@ ‘µ,Ø6f,„PçWÁíwþ‹I2QQí¸Á +š²¡q~r ¦Íhڂƺþýûfèý=‹óŠ}À]wê{\NͰᷖ.*[XÌIÚUÒÕsÞw;zÞ·ùÔÙ«/-hÁs¥(JÊŠš«T—{û®X0o~~®ŽÐø"/^#|wÚç4!æÈBEÐ\ŠV ¹¯‘¨ E*ÑEŠÔ J¸uS@JàeË!IêØvªÁlˆ«ÐÅüxy&ǸÍÉÑÕ+£JÊX’•ŸE“C²ðd!s`Adé\§ªxô oUÔ¡H¸5qjÖ¥ŠzEýúä~¯O#¥±nõ‚ïD¸gŸ¦œ¦…¬€Ý¢HHV©¸÷ÇñãHb~,%—–S«_Â;•J.=]5.¯&áÁ}ñùö†“¹ì:II8!»·H°5^PŒ«‹;j#¸ðŒ@WêbvC´·6ælœrÊçüûýÖ\±8n¥ H m•H0Fù< òTud,ÍGÌX8 ¡ ›qã#p¥[³GÏ¢ñÎWÚ×ïØÁÅA~åRƒÖìF…P**¤XFH•Ò|C‰ Šà(ÖÕÊc©7°ñ5ò ùZ>tHº°ÍÌ|³¼L`ð|ø¯ó®ƒI°åÚðq¬µã» ·¡‰6jE¦šì#[!X†£€!$ÃÒ°‹‘ˆ( CŠóH‰„„ý“Ïû8ª£@ß±ù§û÷¬9?þ£J“Õ»ŸVï^‘ïû[õþß)½¹§8±MRžÇì`…9$üL„ðt„¼·r(‰”ó÷ÅœáZ‰4¯¹ìÈäñÓïØ<ïš·ÌîÛï 3¤3ä©ç†ÉyÕæ¹rÖýžÕuÕê¾iõ@‚/v¹MδFnbœà¿frE¿ïÏTšãî ÐÍ®ëí=Ðl þt©$Ü /[±(gߦm;¥…ù›G±b’–râ¡Æv@Ë/@­ÝwÎõýÀâïÜKs,¼ª"‚ªÜ°í‡¦ÞÛ]îŸY°@àvà.îØ|0lì«'í¨ jÏ8Íì“ôVj6xº-b8XUdÛË öñšÁqep¬6à×8@#éú– Fë‡û•¾qõÐX/Xëúõµ_¦’©•ÔÓ'°$Á¢ô0ugòN¿Öb$Œê™ÒÈ”68¡ o†U¾®Œiž•³Oãóׇ‚†ñpuT7`WY6‰·ˆINDаI¸“¡ûvìþô¸iÍyð’ë±ãn]˧ÆÖµÍ÷ -UëŠr„$Þ¥2ì;—.­&“|ʯ&!å!RÖÚßõ£•×ÐŒD"ÎeYDÛ´Pƒ.(ÑŒü…k:šªD Š×guìÏæ» ô»PBùìúÎ]ÈQB† 4¯Á§±*4·§‡Q¢]Ô ¦N°§^g‹XN(ØÈ¯œðªÃ΢0¿N$°£…U–fU~ËÉxŸ:憈×GzN&\êényüÙä€RDú9Ÿ*â4Ä=uQ·nÆTxmÎnœui;Oл*V>UyøðãÇÓšMÒ\üæ4ý/þÍJ=yòÄï÷Ã:Ï ) &ó¶6 ÷ªcÞƒó^YÌ©Ž9a„†™npˆ6îÔbyµÓv]Ü¥˜é6Ä]2G‹0—âHr=Éæ Èì]›ë4 Y¿Ép'Žà13šHã_Äí|.g*åMØ'AˆlÜe”;Š)Xah4Ü…Æ-Èb$7äÀüÿ¤¾Üc¢ºò8~’I&¹¹¹¹¹¹7w2— 3EpÕÊKÐ*ˆ 3så:OFtò@ä5Ã0À3 ¢¶]­Û¸jªk¶ý¯Ùt·Y“ݤþán£®]ÛÄWåQ˜ý¡5ÙmúÏ.Æxøå—ÃÉs~çžßù}?—RqPé)(°B|mF#5Èï@zÚ˜'0aÌEÁfçÉFüÛ€GXåN°£qXˉe¢ Ã{œ€‹ŒG"uü¸ñWjðV›¬„~'¹EC+XަÃa@˰AòÑŒ’fÕ,¯bä©e‹z~µárê–¿e¥?Ïß÷.ìYÒfþ ÍZÔe.êv-êv.è2õ;–uÉa}JX·m¡`ë‚>åEáöçàµIaqû)a1-¬O{¢K[ÖA'eE¨H]Ò¦ÍkSçui bƼ¸ó©6ý™.c^›´ K^Ô¥-éÓ—ô;`þù‚Œïó3ndì|/)©scÂ!•°îEE‚…#Qþ9Ça‹4Ð Aoåí¦ä¦Òä»õ Ë×»¯E´øµØ§?U­·š{n6z®Ôv€‚_ €ÐέççM}ï×¶½»ã8¤LÛ3+>­wÃÃÙ±‰0H+–™m*ÍxM˵&ÏM» &¹àpÎ59ó4 ‚L^”–*wÜhòÜjÀxóî×*þËõÎ+Ç=5u Á€Õ¶_nvÿÞÞùÙ‰þ]Eå Š%šâ(ž£˜(ú`R[:4õMò<6 úLýCFXÐä÷K½#Æ1Ó ÿ`ϸy`Ð:0 yƒ§m§úuÅõÅõ/Gào9¼[ßùìË`yß Ô=aò‡üÆÁq«ßgìñš{{¿±w\úoÈùŸÍoêõº†ÍÞ}ß´a´_ôHé"ÔJ(ÅPÀ³ó²óÛlÃ_‹¿²ÙïÚì÷ÔÞ±¼{ÿhõƒ¢ò»¶ÊoŠ}[TùÀRùÐVsÏRy×\ù÷£o<½<,ª¾[b¿c©üîpÃÕ\³œ!áÖAµLIIY•‰Ÿ<‘åå7ŒG._¼¥…”ÓŽ‘g0hJÂ:>«å4r&…€DtVB£bTÍvÊ­GÓÅkF#øW^b.Ó£s:ì' s4{Xv<—zG+ «;¯ yÜX®ÙÑøìÉSƒ$‘)ðP†XõÞm%£Ni²Ã0Ûu(ÔnšÆBo˜óüH3›ršC]ÆixËŒ¼vªóèH·^ÁRGP ¦û÷æ<~ôxc5VÛKDZ‰´ÕÁÕ¼ ¹ðÁ¸†gE—³ŸõâÀžçùÙóv¾{÷'é3[7uÄklá§â ’•iXBÉ #'‚9Šeˆ\M±ÀÒpF*’VÔ&šÏ|+¤|¤Ìªi9Üýqk/ÈèïX—AF_u\k÷ž±·šK¯µô^µ;B®Ô»€®4™tA¿QoêQäuÜÅFÐÈ\]«5= Np‹$ñ瀢)u×¥úÎ î?´x.5»á±fÑ2Vá€ÍÞléT¸nw}ÁÌk¸…]€0'P¬þ“ã½·ZúÎW´Œ—Úý¸U8¤(%Iç&d×t }c…¾1É%ÞØ×/öú¤þQ‹þ H}ACÿÔ(ô@Â: Oõ¾mÐÂkíºä~/ü“ÈÒòòR¤&-*š¦â8¨÷PWC„ÂÂÂÛ·o‡áWÂ_þéÏ‚B‰ë-ËËy¢ÐQR>ë5žvë§;ô§Ú C…!×/шi¶PcÉ´ :@&™éª˜îÍÚJP2MG3ܦ ¾ùWøg óóz™]«@àòáÅ‹XXŽgi#ÓìÞ\=æ6ÍöˆS§;L³NñÔ‰ÃsÝÆ)' Zg»!` ÝT{ÉYoÉPGVq¡œ#á:+àN¾/êш뱎ƒ_5 $vL#` ëkF#õx¶‘Èœ'(èH““rt˜¢Èbj¶!¿õTªrvÁ6™(¹jG &á<¨£’X¡axœâãÔÈU¼Õëüh¼ AäÀ$öŸ4 ±fYµKN`b˜›Ójm¶²§ÃÕ„{À›WL#h¼ÂÛ[}‚½þ9ËdU—ÎlÒ° Ž£i0 -P‚‚T²ðñà O3,K“‘6"š’ ”LEËcâ-ZžÊS9*^Òµp$Z¨SÇ´oØp"!>‘'¢¸uÑTT‘’íOH8±q}®FaÐ(uÑlZ™ÃofˆXZ“°d ‹ÃÛ¦XžâZˆ¦%)(…‚"Á`uRW ™0ŠN ÿM}¹Ç6uÝqüH“&EŠd]]]Ý«{eÇʃ€—P <ÕR^c%BbâÄv'('N; ¼ìÄqâÄÄ$ò ¡ÐBW åÑ£k'µë¤j›Äj×u"ÖQÔB‡÷=EHÒ&‚X¯~º:>÷ÞãßïwÏý}??i‘’°A· tmf°h×›åu§ª˜²Ÿ­huz ˜Ñ3Ž¦ÓŽF(þhÕLªóÿdÇ}Õ ë—½‡2MçÁE@‘Ý­x xéí*·qÉ ™ã©Ta°\ªô –Ö.›•†dàH–5s5‰jû•.k°0æ}G`àÝòúÑ=mÇœ'€ 1îB¼ˆ}fƒ½èjÁÊÈ-†ç*=°3å 'jZ"Ûì‹D)ß å°A•4Ÿ&×oruZ¼kgÈàïÊéŒ:!ñÝÆöˆ1Ðmì{ÀÂyíïËïÀü~½/¼©¥¯ 4ø9- Cá,O¯Á,ò~wù[”›¢Ñ[SSwQwnG?>ö¡?¯á`ÿ ¡í VÎjï1‡|›<KÇLÑHÐä êÛö都Ƹh©fšW°3ñ²õÿºùO^½|û*3"çTENxGú¿˜J®Ú?Ïßy³Èþ…Õöí6טÅvÅ\rµØñMaùW¦-vIQ´¼¨FÏÇÑ/¯>uât4¦ûã0Ic]=h$f\ÊbmŸÇ<èym >{Ø;äÎj~à’qÀmö‚@ ‡šõƒn r1Y³ƒÓð¨ê(z4žûô“ß³äO>xâ{™œ˜ÞN1ìeD‚™ ¿CÍ jÔ!dnuöºâŸy ec_}î°'k­åÇÈpˆA8J?ØÏR–>­¿-)s…„ÆW¤IEã¡Ê|‰t–1Å„FOk(Ô¼ûG ‰Ì¨dG@8•$XJÂlÜWCêŠ>_ ð@+ÊË’í¨ZþÙ– ppÛrøôdRiW°¼AõkÑ訬©·$MXœ.+мx.)7“Þ*&÷A;S|@TÃnnâlATÇ«Ôj“(›£j+éq‘¤¬'P$RñEÉ}NÆc}1$CzA}Ès›¸ ózeÝK ‹FB»+Rœc‘õ†Tf†üÐ@QEd‚u‹"*4娖  ,?@*‹T–E”s•Ì–Ò ¸E,À.AÇp’%YŠv •D9AT4¼¤Æ×Á£È3Ä‚ìª êÔ ¯Ì›ŸûjÆv£©k{ù¡Š½ïìñž®õžv4+o„Žäò^ªö^t6_p¸Gî Tµœ‡ªVºŸø² H1PºT8l«yww‹ßZ²iVzغs´®ý”£ñ²ÚÃΆ–ÍÖ‘]5GwT/’5ȇ,Ëktóú{·¬ÊHFW" Ç/צ‚UNV6s4]Úí?ÎVº‘@e4/bŸ)ÿ‘Ud(r¦š­|!–Õ‹µ¾{3ÒæjNHQ.ªçS]ÕÆ]£o~gÄ :CÆ`Øè2¶ELŒ@"f J8¤×ÒÈm…¾k-©´§ªv|r[gbâþóŽb@òÐ7†JÌר½d‡V”Ž—8•DùŒŠÂâ>xØœ9Ԩ﯇‡1i‚K› ‡ÜÙƒu†!ö³`Ðk9àùÅ꥜*NËs©åâã9séŽT¨€swL(™ŒV<Ä’™±JÒƒ?²3ZÀÏP‰T‘êBú¢ŽøT^„)œ@×.#!p…‹´ØØmáJ2°‡”YVT¼€ÁÓDHdJÒlNH樊)6å7­|È!û]$ääW-„˜¢š*UO sxAPD²,‰´–þZÏšFB±‘IfÓIèu2*‹üˆgûpœØÉ°ƒôì$-bÏR™VËk*óS”$5ö¡Vx…˜Håf`†ið Zó’$¡h+@Æ*„JÀv‡HÓ8Œ% @PIÍ \Á;”²[5”S àeNQ©4œ*…ÒµËuº×WdÖn0‡­¥Gmµ§PáÑÊÆ Φ÷ª›OW5C%Ϻ<`H3Tò¬½¢Œ™i%=‡KN4ôbµ÷yÑÈÈ6GªŠ™jÔHTÖ K¬/¯ÍKP°õó¿é¨‡ç8›Wã;_éëRÓ‘žãÌËמ¬h¸TÓêßZŠÍQƒãTë’t'k½ï”ö~XåEàx(`À™1ƒsÆüÿ­«9SÓÊ ®Ò}Êå)­]—¾PQq’È "‡—›'—®)æ{ö3HvÁ¼@È;}Aƒ ÁëÊï›ýàŠ}%ÏÎ~ˆNÜcõ%zsê£ás!c'nè(ðìwuN^ÿó¨WwqÓdtê»è1ÿ¯ÛMm!ƒÐÒ¹ÙÛc Ìtlnä…ŠzsvÏ4’ÌK åUBÃÞº©ÉIJßä8«‚7¿ùg$ÜÇÅ'‹R"ˆš’´¹•jÍ{™ù7¬Ž¿å—}e-»Qäø‡µìªyç ‹íöÇslj§´±­Žk–ÒËÆ ÔjÊjûºÿðñ§Ó21­ÄâÑÌOåx€÷:5å²Ù%Y™ýoæË=¦­ëŽãGª„dÉ’e]]]]ëZ6È$Pòhµ´Ù”!¤ÄÅ`Œy&$‚ñBüvxÚ< 0PÒF­Ö6i $$Y²Eë:íŸJÓ´M›Úµ£k”(S·) Oï{®Y”¦kÿ)YzùÉ:üî¹÷žó;çü¾Ÿ¤Ç°‡_$£EOœF¢z27×’ñ¼UÿZÑȹ<2”MÞ,—t®ß©Ib¥¨AÐëXFøúúú/þòIlye)¶ðUìÁ’¸‚KK‹#3‰€Fä,+lTU…NULœ98Ü )v}?èÆ|Ñg< ñTDûýµrå)MIOJ¹wçvÉ"ålœåñzl]âž……ùG=žB#^#hóQ»‚I9N‘¤w×UN¶çœ.÷•Žù@#°nÔU4îÑ6&¼Q÷Áþ¦ÊóáCmÎôW¶ Œ\%“¦ð V%0å‡Hšè }6J#04¨^›×Rµ»-”F†¤+$fú¡'xCR–é• .µ@RJ á:rÖAµO9Á¤i@N,GÖqÊŒ lª¢ EBr†‰ÉH\•dÐ)=¢¥ÁŸ§„#Sr©RŠA.1I¯BWÏ“§‘o˜8ÙU´û6àa0ˆ<f¥ Ñe#=ˆƒtÛ(Ò„kI°Š8‹%Gqú}IÙY);3“7§)wdð)j†G™(gY—Ìó›@˜JN#•£@Y ‘U"Yó =$0.IvlLÝ•¾eOú–W·í¬Ü} v¿¶IWÚVQ;Z×ø–Í}Áé¿ä LY3Vße 5è5èbÆî¶{И…DB‚-ž‹7Z ÃSjvß%‹w! âSO‡F00Ëþ|l˜©´–ÆS&aåŒTÅ£,:<å ^µfjN(šs å]Ṳ̀ähµã7íS¦Ó>c@W½“1¼rJÆÛ6÷ìÉ–wOœÂ|g-ÞË:A PdJœìÒ×,}­(BÇâ¹êîŒTÛ_ÝüPËŠ¥Å_ŸR•e é}½ú6 HD$të)Šté[» [$CÆ®îÂ6tèÔÛ_ó÷;a-ù¾öš3_ýñd¤±•1#!·|vý¯­E¾½¨8pöHë'×~GdyåßË‹ ¹û±?\ýs°Ð7P  téZ׊F†Œ}áÂ6·Ö¹oÓ®DºseØ«i)©÷ïß§ÁGcý|n®öÈÑ 9«‘3ršâqä”GR·LkËn—Y¿0Ôü½Âr¯Êq§¬~ÎXýÔqâÚßÊLŸUX"YÙ8Ìj¹ •«ÕÆWUùø¶¬üÈ/l- ú£oa1qZ5,#M–$ ”=qñã\>™Š"ç´džÜ5£‘ÉâgzõJ݆•ð2Ù…ZÃ@Éxdìììì›7oÒíë…bKPyÀÁ"=j±ùùUØž¹U)ç5‚J*“¼hÈ)òŽy õ%QïwÑHñ(Å€ü¨W;êÁ¿#¾šáÀúײ@@jN¡”±Ó¾e1ì”E–¿kÃ|óÐ-Çn-qÌÀ¸îÞ½›‘–!æe[éŽ?1¢¤ˆzõã^ð’~Ä•„xã>CÔU2æ.nÒ4ëÆ<¹ƒÍ寷k;×mÛD°§±ü<Ç—jI{-‰8)‡P±¶¬ÒÈ€}͹O”Ý>é¬!qPäèªK‰d¿­D‘P«£¢ 9î5zœÜË[@õ ¦«”Ú½L›• 5’ÖcòY ÕÞ,<ð`’Õª¼=\z2ÐE)g% V‘™F¿ÛR› {EZ´û_5åŸÎãdÐñÿ üö[IÄJúãÓƒ‡‰ôùÌ’°%!$²<½u¤§AœµcÕÀ'°nqÐÖ+¾­_|[¿™ôšHW-õ¯~ÂLBlj§4ÁTÌ Â&†ŠëΔ´CÕD­ó½ÆàŒÅ5kóàwÚ|,A9Áê…ä]u´^±¹b ÎZ|×­þŸ[ü7-þõÞ©ÆÀ%§ï¢Ãº€Úâ‘Y›–ò‰7$Pá¸è`õ^°z ÐhƒO€"èYì%}Z42ÓØÒ}´þ…äÔduBA3€œQ ³ª$¾òƒ¦3çMMÓ'ÏÜ8ÝñîÉ@vÚFP Oγ;&-Í—›ÛÞ´{vj6ÀSþÒîL†¯ÏÉ¿èn¿`v]s1÷™†à”85ÌB£aó­ídã!¥a´Ðe¨*÷ÄyO(g² ¯’©‹¶kÛò]†ŽHAgŸ>MïÕw<`àIXß>`uå{h»¥§¸#TØÔzFŽE¾üôK "´$]y°°YŠ-/,/Ææcï„Îwüƒ¡ÁüŽößõ³Ó±¢ïr×<жùØí_~*ð—õô…׊FÂÚúËÇ÷qxQ; äXnjjê±”øh™†ºî··~upO¶\"E9ƒ²3‰å¹t3ǹŸùcCÍ\…å÷Æê?•Vß©¨ê8ñí¶±îccõ¾¤D†— R2÷Û?{ç!< Ñÿ¬pü××+t5—c …z-Š‚DP¼”˜v=q™Ì%oä’ó¹ä\‰æR Ï£d²F4ÂT½ M—Éå’DNÅñ‰2Žç863Q9òƹùÅ%*è+±±Ø¿–h!›§z/ÆÕ–€>úð×*TEr9]ª’·ÙÊ^ä 6}”DýÃnݘ¯p<`ˆúªFu^ihGIÔsŸÎ-Ѱ¯Æ÷, FßQñ!­î4ä% š¦Ø_Ü ¹¼°ža¤‚lŸë8> 1» þÐȈÇõFO— Ÿ*i.› ¬b9 ”M´íwÒAk”GXFà ĜG¤ß!ê£H#]&ªtk¥ÎC6ÒY'i5QEóÔ!'E.àdÐ! ;è­'i3Q8 Ûñuöh!¤J¡á¬ÀÿôyÚgÐNB2ì$íõRý^I NñÒ6A l¥’³*–GCƒY©ÒPNºM”²Âõ¤óTo=E¬øŸ¨!tôs°/n , „‰ ˜È ™DÌ46Ìô. ¢¯Žôb¨Õ¤¿šDjHO3}Uœp¬”RzídÐFû¯¾_dd¨ŽD8f£à9ÅžÍÏ]t<üSß”Õ ƒº]iB7á™±¦­~8©ŒR…õM;¼ï;<ï;\—ܳ6ׇ{Æî†ó’Ín ‘kxü¿$ƒß+"¥Ä  ‚WíY‘R`Ó¢=-yïdÀ¾O»]¡VË +Ë0Øÿ!¿Üc›ºî8~þBŠdɺººººW×òC$Œq ÐS)i M;¾ñ#ε“–•<œÄNœðŠßvìfÛwÞî;Wá¢x·Ö€qt·ÿå¥j𦓴ZB:¶ëJ_Õ¬Uf€µ©(ú˜Ýu¸Ö s~Y‹Il¬ÒóAmV îuB‚¾3,¼&Ï4_xÝh]`Ôî~¿68RåÚõâ6¹r`iJMN+^QgE̾nc¤‹oi2D€4€:ÚX$qCS‹©)·;D>iæƒí…-»Mhž8=>57ƒKÑôÌÕ?ùðäØŸã6 wJ³÷®Ü‰X¢š–žüîV]sTvVF&®^šÁ-ÛôÃî®F½+®DóZžôð]Þµ”R5Ò¡dd;­oÎ<²ÛTÕüºByïúJl›M ¯P¥Ã‘Ï XRN“¤tËD7m½h.¹WT9Q°kÁqâ[êžÅ~,+WÉÑ2)ôd܆5ë°—=²ŒÇûÖÔõwñ7==5:: çN+4J…% P’G‡rÑ;¼¿Z|EÕäÚDas¯zþy=oU³-ƒôf«z5Ø%@ÂB!Á’È3p€,>þ.X|oÄé;Y±»a‡7E;çjƒ˜¦ö†Á£Uãµ{àöc5ž‘ݸ?ÓîdÏÔ…„-¯šÒGÀù )%ÍÉI·9aÎ…JïÑj÷ñ}! ˜œ¿i+L€Ó“ÓlúpðÕ4gÝ´íy¯ÃÉèÔ#ÁR@<°§k\gr~QãÑmü ­€-%3)h±hÁiWíêë[Mm|S§!ãÃó¹|ÔèoÕ‡Zs’æv`•Á÷ÁÑ÷ç¦ÀÄ¿ö˜üèzé1Dw6ÏA|Ú,Œyᎂ–H~CÌØÔcŠ…ßŽünîîÜGíc±Âp«)ׇÚõó¾w>2ÅŒ‘P“©±]ßçC]¦¦˜.è+t¿¼dK:©”‘ðåÒééªÜÿûÜ7.“·nÝ ‡Ã$I*q!“ÂÛ)#É­rÕìÂ…šë–²›BÙ sÉ„¥b¢¨ò†¹ì³ÂòÏ­ŽqsùU‹íŠÕvI(‡q¼ØvÓZ~£°t¡¨ãR‘ýº©ôŸæŠO‹íÊî åãÖòËÖ²KÖ:mú2BÁ‘N±ƒý‰é¹ÿÒÕ~÷ïßiÃF9'ëDŽÍ耆³Ñ!Ö¡A ™ä,@ À!ZtX‡êPïh 6`2If£w (ªc³Ò &b(@…\õ¤Ójǯ]ÇŸô“oÚ•«W`AäCJ ZÁeÛß´5C~}Òeòòûó“^ý OÛ_Ÿ×ç.Hú‹] 4" a»7 5¨s6/·ŠÈ°GÁ(;=z:v…ÿ퟉‰ µZM$EŒ‚Í«Ýe¿>èý©ˆLóшqÀŸpó^¡Û«ß[*[¦`hRÅqM*8ä,F={P¼û~w ŠŠìñе«°›wÔˆLRñÜ]µ­†]»\EA³Ä(‚`©Ev3êr¢'f ‡h9¦³T¸Lº—TÉ@ -ÁÃ,Z*£ò_CÍ6Ô[‡º«Q{j³aÈiD±aJt@¤ƒ3ªÄ]xœø^ÐÈ)Q)/~äȘLŽW¹Îînx¯6‘~œ°{NcVñ¨„ÿCÇmûXNÔEÆö„Á¬ãœ«pc°qà!˜[ªýçí¾¾²Ú•œ‚%H5+_%SRIRç×2Wº|X¼æ9YQao¤¿ÄùC’U‘@$°l`dì’æWoøùÞÀÿ€FNˆXiB¾pqFÌPd̉ñLØœ¥b0J)€ª »I#³VlÞ­©jµ`séз´šæuÿü @HŸ¹µU å¹Oµp¤JâÅß^ ðžD~¼#¯Ùmñ_þ㕹™ÙSS÷?¹Óa‰tê"9-ÆÆ¸¡©3¿Ù­Ûµ†F -Ãì¹B¤‘nޤ¹â””$Í$´·¬\¦ Y0 PVöF(A-¨QL'îHk°¥5A"ÕX1·RXÒæÀ´³ð8ñ½ ‘Q'Ö#ñNœq`¥ d¤Ê•òh°fШݺë¬H&)¥&¼çðžÛÓ®Ýc)k5þl°´öˆÝ5ºßR§ùûõÓT–ü$›LbBÒÜÜ47mî …ˆg²£Æu‚ÃèºÉ:¨P¸Ð–Rž:@iéãBå!·ïR胖‡0@y(³3³º;ã 53ºq'ÙMÖì§ýàŒ«îˆŒîú`(tÿ§Æ£MFÖì–“›Cï½§çqïÿÿ;Š÷Ò6}PÉ5î‘Á„ÀƒÏ£i¯|\oþ#çøü€ëlCë)€ÞÒUÍe®{ãçµb~I'è2¥c²ÁùÓ« (… Pгƒ¦Îh[`B`PÊ-Û ç°±J Ä¢è2“·s»kr7äôn™/JçÓ²{®³Géëd=íyößÛ? ßœ…`8™…??çõºÙ /×hèïggïG‘/ÇÎûäŽY; ðÛ} §›µø ݘ7Š6?4.÷t«:žW#¸xymÐ&€$(sCËNió›ñ©‰ÂxÐ „²’Šbœh!h?3LÆ’×rT\Œ§×.]Jß° oH%Ì!AKâ)‚\Oîôw¿Vjn—®(«¯©o×Ü.Ñ\Sª'T –‰R ™Ti&KjVK#б—è®Kdû”&K´×K´%ZÍÆŒ„8øŠ‹º½~ˆþßÍÍþ­½ŸØòÅôþÝ{¯§¬’8uÒ4š²Ð‹Fw¡Ñ,4*E£,Îû«¦…ö`ÉÃÿŽæ¡1å¡^e\ÕÛD*!Æ%’d)J¢%°\ÉIë:Áe‡,í€]Ï;?Ó‘…Û÷îîHÏ€ð{!M&ÿj£¦Çž²fY÷öó!sñ€YÑÏç‡,{B¼lÀ"²‚Fdý-²>^æ0Æ1D"~!â3¶n]êÉ3ÿüë…é¸Â˜XåáÇÅxƒô’Š.‹lØ}Pô4 ÎõÁeuÄ’u $PYÕ€l•¢o E¼†ÜjÔcÀ_zkPP·ä‡n@οÈù>L4 ͈ R’œ$bðvrˆF:&G_¾ 0ãW£^ jñÐàÞÎK8l›¶ª¥¾ÚåÕÐ $V9MÁŸ×;.Ô9¾0âú¸Þ‚¿lpáËt<Ô¿0¹Æëì'j[ ‚ÅRËÃÙËgõ¶!mcåŽ÷ÞŒO (¬P9»i눮 ”rªÑõ‰¦é|£ûwF~gÚ&˜6"Ñ&á¨Év¼¦ùc#¯Ëbƒåš‹Z¡©Ïš\GŒ-}•ÜÇlã-màèÉKÐÈø2E`¤§õæs:óE“ëXEõÎNXG$Sè·P@m^›ÆKMþ¢V ˆ'× ½«Ð y†Fz ;Úsœàw¾ýڙˀù……éÈÌ⣅©«S‡›BÞ|Û¡ÊÀ­¯îÎÌÏ.D¦¿ëÕ\ÙfpN§Âã–19´vÉÜAÖDfý2¯ ½=·õy)âgÛzäþ ´ý¬ä•9ÝJk~Z6ERxã&"×Iî=¸ îñôã™mW"*DÅ©H7Žö ¬•$0 ŠK€¶i|²™ö¿“õM¹áºªæŸªªŠ}—Kk¯–ÔÞ,Õß*Õß,­ýFU3¡TO*WM#7ŠÔߪ4WT5ࢩ °ô¯RÃiq*%‡ÀÆ,ž¢&'n>ˆ„ñv4üÌyyu>˘Œ®÷b$àó‚Æ¡$ホh, f¡ÃQ ­žFúv¡¡lôÛ‚(K ¢92™ôD‘„`H’!¨xZ"ˆ0´¸ÞT{çÎÈÏg8<ÿbÙÿQCíÒ—N ¨F"$‰×„q{÷ :òCé E9â,²)z›Ù–œÃ6iÿÁâ»|€Ïí?Xrd”I0!dEævE#OŠâ9×kaå8??·ò½ªPµVÌ$ŠÄ‘€5k@޹(Ä?M#CÖü¾f¸ LµsØ’=â,îµfÖ(ÄÃA*<ïÀ…¸"t¨'kHå©áÁ ÑGSöKÉÚÃ&ä×eÙˆ/Ç4ê4 ¦ÈRŒÈ«FýüKH·ÓðäŠ) Äm ƒ E¨©B˜¹•ÌØˆº¨Ï€qe,Bœ ñÐf´>•M”7±¡½hý_#6@t ¶‡Á ÁýÔ›±@ –ãu¶“&q²Ö[Îê- —³uö“Ú–³+\¢ÞþIÅÆÃÎ^±x¡r )B’Ñ[RRáì9£í¢Þ×5ð½U\’€24A‹‚Ø‘œÚ¦ÜŸ³y+D¼·’Ö3a Àïž^†Á¹zé8?÷<çç~ßÏÃKe '#¨t’Nç`úBtSkXþe’©ÝStª®åš©ãCcÛo]Á ­–½ Š †–f¤Ã<„’2 ö&©V¹8tÁèù\iê\2¾ÖJߊ$~€= ‰}âîƒQ×äïT§Q ŒŽaX H¾tSwIk¯ª½_éƒ="Ã4¢,—þAu ,à4o±«·Âë,;riì#ñ±8<-ÎÅ¡ÀAöOÏÎãj"~yñZÐP{¢‘n…·Oè ]½ª.`O¤Ä&zÂj_På–*oHxfÝÁý]ƒ¥ýX5å=v…%?s£Œ%À„ejk«¡ÔÍÍÍ$jd<ŽW„ßW—NHâÿ<šNŒIü6>‘=-Š_|õ…¼˜—J ’‚GŠ9ÅP2ž-ÏʾVz`JSÿ Êü°Ò|¯¬îïeúë•ÆÛÕ¦{ºUsÈ”N»ÒpW[¯Âø•V·Êzµ¸ò(Ìi,t;a¾žº)&Æ5»ÿ­ý@·¤F`76X†a(È÷Zž‰†Th\…bJ4.GÇ嫦‘±4¡D“º”~ [¹…Êa2…¥( øz ú¼ú³§&ß§1îï‹I~àWäÒ\››}öû‚‰Çñ¯];ßäXJ™„e_ÞúŠ¦Óª=áÛ{Ì! ;kÇÝå1gáh«âx{éP›fØ¡ïü6J†£Ùu/åÌ'TƒŸ‘§ ñ[’Xɱ$ø¯~ú™”áA#p/¶èŠ´ƒ.ŰCïXN#Сֲ“°SAÄ^=é)‰.?Ñ©uÔŒxòêJi†ÐT:Ë¥€$µV‰|u(bÃI¬Ça—Ô a¥S+¼Q‡›0„¢6Ð'LbL€dbÅ–ðèé76fÀú‘¤ÒáqÍ]ƒœp‡ƒFL)|¦õ5¼p¸V’%“$¬Œx’”1 ˜„Ùš‡ÌZÜ61å«m‰‹F>†ÝÖ­·»ÊjuÛ÷nJ_˧Ù·–ÆÀ¤ë9©zÃ/:KkÎ9{N[]gL ||â)wƒl ™’ÊTÍŽ·Æ6_hõ:„ªÀ¼ І²޾ﲲêF…áŸå†;º†»5毫Lw4WK#7upéº;åõÿi 7«­Í¯m£)˜8}ôUÕ#ðÅørw燶%¿»™™™ÄÞoOÝâY. PÎ)²PPŽ&KQLÆ‹ÑľUÓȯEÖ|b3™Â¿DáKKišL“ñþ^ßý‡ß€¿M~5ŸD¶¸h’¤™ŸçÅ1Òfãq˜ÉŸùg†åx’Î`°…6ë ߎ´íŸì.¹µCmÚÑ6Õq'hD8ÖRë(u¼a«&9JJ³<ÃYL&hè€_{ò&Y’ÌÓëìïÿð9”¬tšáyæ5õ›º±.U¬£x¤m9”ÆÚåÃGä1§vÂ]uÌqp¤C=tdoÌQ4êl= aYJy-‘¦pij”c $HÔH¯ ˜W^„&ŠÑ M¨Ñˆ )Ð(œ)Go¡{6y—þùK$O£ ¨…E •†f«ªªnܸ!ŠOø‘œ“Ï eîIò¶$ߌŒŒ@}ƒ*G“›Î¿m®~oÜ£u@¬—Œu¨†ÛuÇowlnÑÅGBR„”¡Ó(MU¢ÄäµEL(Ôˆüï¡°)ß(¡¿ø>lYñ´4ák 4 1;j­e³eé4 Ýe¡„oùõhÈ–À ôÖŠŽ‚^, ØQ CÜBÔ(Rxy™›¹1ÿÑW¢<„€'jBÆÅšð`ahzÔgB½¸ýhSâ†4®¶=þ×5r¥Éý“㜽ótcÛ%sûïÿ‡ûzi"ÏþK.1!!™L&“ÉLfÒÒ°(àꞸ.‹^Ũçè8¥­å¡žò,Ó‡ä1ÐÒR -Ђ<ä±§·.ÑuEX|är—ÿ;7·¹Üºç®ËŠ»>bÌ…¬¬Gï;­²œ‰›hÊzw“_šaÊL¯ù~?ߦ¬µ%{õ›~½T d9 Ž’ÃIr„І¢•¥1‚ã8^5F– d€½5]—šÇŒ5—Mõ–W›wñëWB©û§’Úsb­»H|wùJxã •«|"‰§X—îà„Í9i¶C»|Ôu¡¼Ö›W”ÿ^ª:!I¿j­#ÛÞ8k’`–]_–ú !í9 ÆÆŽ:GÍÒ¸XuÁ"]¬pk ©; ²¦*†aÑÔöe›¤¬£ ŽvÞZ€"/Íò‚»-§ÕŸí ðßÐ5µdÔŸüþg+oïÚ\i´ îVÞÓ&4ƒI|:÷W—þü!T!­ÏÎÌÌŒVûõn¿ Óåø^_;ßâ<-ZÏ«ªãeíø^<ÙÇ7¹óÜiooŽ¡•MCœáy>œ]Vj¯Qµý\ …ÍÇ9rDÎ#P“€ZI@ ;'sÙŠ?ìÒýÃ`üÎ Þ1”ÞÙWr'ßøm¾ñk}Ñt^Ù÷ùâ”¶ða¾x¾ÒßÍ-û.Ïø­¡|A<Ì3}m(yWvÛPx;·´1%¥ŽS á$Ny‘œ7~,Nx€·nÝR‘D IÇ Ì# ¡,4¢F{"¦à ð8¤F#‚ü9&É@Ý;Ð@ê݉Îðè´õ KÚưfIÍbðŠr8ÝbY6uÃÆk¾/N¸ç‹-ÄçΙƒÍ[BEqP½a±TǶ¯«Zè—øþzÝK×U! J€ã@G“ÀÁ+Aì}ïÞ½`í϶п‚¯µ‘à¶fŸô§Ûç‚Û3ù’SõYbOMQæ ú`è–^U#Ú>©`Ø¥éªÑwJ»H'Â|G«ä*“bX6êà9·[ä|ç-B]&ä7Éi3É×å¯Â.~vnùNcš­Q$Æâ2S£9Yód$øÈgDÞ2¹oŽÃ”z±~5±ö2}#õ¨±ùe®°[ÖAÎJ  î ‘·u[QÀ,ßÒi !Ä‘EÆ Œ´£<¤¯rÙ-pÝ["w úêÍóã¿Z#&9 _¨p‚ @#—V95 8Û 'À ¨O1<† V)bÖÅÆ§/OÚýNòÖIq8Ôƒ,á E'q1u9û'+ÝWÌö1QµÙOZjO˜ªÎYê*²õðŸ_bî=ÕÒ-IÉà(Y€8ï$Ÿ©p|T\yõ¨ë¢(MV¸ÆªO‹5g+ÙìZ¤óVûy±ö²Í¹Øóö)"JG.U4ž+¯9k¬¾|¬ Vç’Í9XlÛµ:EËHÖ$I‹_gÞUìÛר®ñ´©›@#~mó˲|“ÐÌèà½Ú·º¦I+ò›šùp´–LG;ï>®óúùf€ < š7ÇåÎs\9ùiðÇàÜS90=…€ò$xy`Ò©¯÷i\Þ¬†€Æã×{Üj)Rñ«;ö6·j<™Ö·éD(î fjj ânóõZ8`Fê˜/TÃÁóÆÏiB´Šd˰«húЊw¯î=0+ÞÊ+Ö=Ô—Né‹nê A&ÀoôEàiCétˆ+@‘»ùÆï Ă䶶pz¿ø¡d*¿ä/ú °IŠ$d8]¿~}áˆ";?oö€ÕY˜çsº dÅ`Á083{V¢-ÎD#éÓÈIÔÈ ìÑ2áÑ€>àÑ0\Ï@òUzxT–F$€Xa0–Àã*–¢b•ʾ¾¾PïåÙÙ'áοvŠÿÙùy‘j=ŠW,s*vå–dc—]ÛQ) Ôoï9¦=Qm´çõÔå׉KBoáKÛ²u~¶_8yÕãéóe wFþœ›ûëgŸQ+¿P4üEHš!gV_]NÏ+käw]µšÎJ~Àž=ìæ{í¼$² ¨K!ÎÃë²Â2R‘W”4x `}ÖrÔRŠZÊ~¢Âbg[F+ÈŠ¼FdÑSikÈ6::ŠÊÞŒ!Htše]lÈq(:%* ¤'HU8TJ»y-²RìÙº”áâh6ŠÀ‘Ï„ºC²‚‡Ë?Q†a–ˆòèà‡| ‘Pƒë€_<`°_@_ÿû¹huŒšCYØê€Ì;$V­çbåNÒ,ì+%Nlˆ[~0mGûañL• x0Vé:c­ë.²ª“Râ0Ј“` b[Òû§mõðÀñ⪫Ç䑆q«£ uÛ[4‹áòF5¬ÛÜ}È4ṟ.&Ê’$¡°2gë>©tNÂ$ˆÒE¸Å\ü€‘>1ÕÁ>…^Y{`>¶ÔÃ$L€LŒµ°(pr¾¬zÌä*©Ø¹2 ‹Z5—Š$$ƒ+”Û—mŠ4ç6´iCIœonÜ­9î—ey¯ÆÕ¡ñvi} GNÕ¨÷ÔW>?Û6Ú¢môêÜ­Ú&¸×Ë»@=ú6?ØFãññΣN¨>Õ4òãýYªà€!Ä¿¼öeCN}§¾¹Gßâάn×;"¦Ácñj©z%NQ$®P°óöÏ…Žù ¹ðÏOž< >íð++SÞ‡Ãa‰ãE@ÈÛİÒÚŸJþ–[ú•¾øAnùƒËÍܲ›ú¢ûúbаPpÀyÄ4’[v¿ù `OXŸüšÄCŒU«ÕÁ™7ÛÿÍ^”…ã‚ó«×þKò*h¤Ç}:t2 mŽ˜Fx4(ÈŸýp®Fƒj™%'2Ñ©,ù¼—Gµ[ÙT#£h’[M.UA/H‚Áñ*›mffFÎæs²F^ؽÁEÐHxé>v||\I*•‡c8ÉQ[ò³Š{ø~i÷ïíÙCö¬ÞÚC= ɻӘPTô÷ À”Fä-ûÆ@ܘ•£GŽ eR@À&°5;×îuh2OHÚW¤ˆ¬‘n)БÑ_÷Û!{ú€CÛ)ikJ©DLG±rÉaQ§ ù,²ÂùºÃJßå¡fü%4Òa‘µêèBØ«ÏÝE®_…¤¨ÿò•Ê]ò›å£ÒSpƒƒ¡èX’†] ’€ËKC$¨€(²—$(¢›ÃŽ*G]VÔeFí"r"³ößì— LSYÇObbBBÒÜÜÜÜܛ۴4UFpG_+ƒ13jVe¤zÛRZ(>F)´° ôA[ZZ(m)P‡‡ èÌúE4:1wœÙÝìšÍÆ™¸›q‡]1cÖQW÷;»Œ³f³Z²c²''·í½·çœï|çüÿ¿ƒt<²|8 `À-e(¢bÏT¤ÿ§‘ÿD#p-wœ6Zû£.|Î`=QnÛ‘±Ž&)Y +\.™6T~jrÀkðô‚ÞrÉhÿì€û´Þ|¬¤ŠOK‡Ä1bˆ²”fÝùΫåN ‘ zk3¿SJâ`¡3@;×Êœý]SÓà$gÊ·D’“ýÑf <.W8¦­$}*³<gÊkúMµ¸;½õ23¤BnÝ^¾vÁš$EBš¡ (BJ¼RºÒ"ÛïÓ¸E0B(êJ—wr¼Èå›rþÌÙ§Óƒ‡ø–·i®¶± ,N@T2«°ê”mÖm•ë:m[Úl»ÃNrÀÊÉäàw›9Û±¡¾,LÿqäÉ0LBs0D„63ô—DåÚ šV³¢ÃÂwü×(UÕnÉl6)»›Û-|gÍŽ#m¸æ—ág+Òh!Y”Ä$IJ…ÈYˆ(X‚B%¨©5M¹³ÓHpöݶÅ0Í<Ð0Ik ¼Å¨Ù€K0HD_›ã*š+¡Òì*FDÙÕT¬âÔ[iÉD~ náÈ%nZ…ÜE¨¥Þ[Äæo,]HI4—D³qb²˜ýE2iç4£‘B˜†éÁ4•þ¯Ùã§N#猶óÑïÀ˜IÔ†vèðº…AK' Üy{€1.•X>3à÷ÊŸW~0Õ¶|¨ƒ„· ]TI¬Ïü¤Ô Aõ¬Ç+lše«X–å8nÉœ29>/µ_+¯õjvCâ€RD,Vòù]ËkÁý¯˜\¿*©:«7CûÓc3Ú“ÎVØOgFΙœgõ–‹evHG_qõùýΓ5maš0™&ˆc0s¬tý¢õέFà °ï ï…êã]õrgc¶ûE.ߨp·¹Úrƒ jÇķÀ"c —㬓ð1:4òû³_>pÈ­¶ Ôn1‡ÕÌüÀ5ø²=ž®[—¿ÁB39VÓÓy²z¿ÂÛ”Û/©ç½þl¯KiÞüöGщ%ºs”vrºLÌP¼xºíðð0ˆðØØè”Ž>ÅwGÆAKoÞÜ^Ri˜Ç0,E hBDÓRŠÖ¦¦õ¿Ÿ3˜³ïnnñÐvàºð¯šé:˜C4ûîj‹ãE#ß©÷ü]µ÷a~imú:šƒL J®ÌŽ<3£±)ü¡}¿îe*Ñ1‹œÊ†ÆÈäåkŸK)VHqø|‘L"¯ }¬ˆd¡êÉD]1ô*Q{6òËXõ2Bš6/¥„©„8‰ „䊌EŸ?³ÿ82ùï¬(N<¿\áËQÜËãÇŸõ…SÿûGËV¬$á¼F³KqËSvùÍù‡ìYaëÎN÷;»•‰Éq ØÜÖ̬ȳÅ#ŒMõ«?ĉۜŒí鞇å:—HX½]–¶Q`i³¾ȺlÊnûÖªòºœòC朎šÍ-•ªW–ß¼ }±€#¥ ì˜ÀH2}12 Föb ‘ .jÊLM†Yw[ŸKQЈ+€A³sQSj¯@Î=ø‘Ou®WŸc&ð^¦–¦"¯u@-ѧåZ*IıÜWá8krôV:Ö§¦ 8š`ÁD8Ïîâ£úªúüÂ4±”äØìôw“Éõo.©Í/8YfêúÂüº08­7ô•ÛOï·/³Îö<>aŠNÈ™òšc¶Jy^†x^MJ9„F‘ EŠ~¹h£/ÛÒ,wxF`@‘F…Û§Ä@ò"—¯“Û[Õþ† *×Í‹7@+AÉGpãˆêÆVÒá¿<ºÒu1lZùjŽ'À×·fƒ Ÿ‡wÔ«]W;~×sÍ£´uÍ|C³ÜPú\Y®xш¯kÖøÜ ÛÚ¤ ÅÐ AsÔo܈Ì8úMsB\ËÓ§?hó_œ¾ý ¢üë/¿Tnã9‚”P4(è0°„aõ?ç:¿ëN®îvnÑúA­n H†ò‹‡òtwr‹à/y¨ÕÝÞ®ÿF¾û-Vˆw1M§ì_\‹ùõ3Ë›|ùiˆ(¶¦Ê8NΤFÎÓøüH‹E4£Z†ÚãG#Ñkw&:œ‰:„_Aìy7qXJp:`)FâB±‹.òxjïO<Š`® G6>: ?GÆžŽD& ґܯk0Ölí7þÇ.*A ba½Ð’%)kT™Z³~W•^ü¦–0M‘`Ú§NŸ|ïcdþc48>þÛ¯~fŠ%š„ó9õâ-¶­‡ÌŠN[N‡Uù‘åeh¤Ý¼µ­`&«É¤î´e…æt;6‡òÎ÷¼eé«—“d"%aÅ4M„`˜Ðk\:*C!CÔ õ˜F‚³î¶ õL> …(dD¡RŽ2‰»ßi5¡&#òàû>ýœ%@5ŽfK’Qi.jС@™ÀgîRÎB~H Ã1)Räý'ûeÅuÇñ÷W$K–F£§ÑhF3ÚYkÁÒ&"T(P&>v±½>°1GÀç®ñÆøX¯ÏõÍacL 4á*W ÒTQ£ÒþSUIÔŠ4倯»ëÝé÷í”­E )HíèiöÍÌ›y×o¿ßϯєg]¼ÃŽF1‘EQL oR°ÅÀr>"‚NŸH*²‡tVDÚ _4{¼ì4ÇÇΕ¹aÄW4âΩÐÊÄ´ñ¼¸…ÌüHÖvƒ@*Î8k™_oh<\\–gµ ‡5?YbÂÈ2va–Õ‚Rð…ƒÅ›³gÏÇ6© އƒDKJThîšbÚ_ZÓœºm`ý”³å ‡ 7áË ³ån|åLi½Á$ÏÊŠkÏ—7œ,bthC}ÑÒ䉈5¸LŒQTVy󻱉Í)5=‰õ;S;z’=(€V@Â27PVÞfkx’Ëwe¶6½ëÚ›½«1¡¦« U÷ê†rÞº«˜á%”˰¼Ê«ß¹tûdﱞ¼Žº¤Êîôµ®3¥¡=¥¡ÍæêBwÉîž”&ôØ‘âéLm+iKrsÚS›2g¥[¨YAàs׬1lh´€?'·EG,¥ ¥–èâ!£¶[)¯ßXŸÃž9ýMÊ AЉ4RæcÌʦ鳾ÎvüÙþhÄÀÃͬBÐȵôܱ¢‘Á̵_f¸fÍ$}×—/K ë6ë1wº{|®ŒKèÙ§ŸýZU jå8Ó-)cF#{ì¤ÏF’I¿TÍçš9S¤ÊERQ1QEƒ»JâjGÞç×¾fcò2 ú™ ë ‹–„Nðžî7Â)<—ï’É÷_ýÑî‡ ]|ðáÀ; çŸÇ‹&€ —€*EFš¨`’åiÓ¦B5úká1ÿ‡C ê~¯÷¯™4tª@ ¡½QÊêú ÛÖ*Û¦%Û7€FÒ÷¸l»jž•Fð"ʲݛ—õÕØúªíýuÉ;6KÒv¹VïmNÜR55~ÔSæ9³$ý€"^Óø¬8†ÝNÒå`„+᨜vT8*' 2UdNUŽnL°]_§>Ÿ¿èlÀ+§‹6Ÿ.q5®Èc GAžCţܿ,ªþ¤ØØ–ÌÑ ѲŠùr"“@Îæ´œC¥µ'œ5*ÏT+qtÖ)Ütº´þxIî{ðñ‹ë΃FÐËó_‡óeîãy•66cš«fÍ›D%LˆWå‰)¡*ZÆímiµÝöæ-)Û“ÚÛmÝöÖŽÔ¦¶”œ$ƒž4Ï“\¾1¹žaCBëŽå=uöªKÿ”àñW_‹£ñTÿqï·^ßC/Ò¹!Ýw_ÆÙ‡Сûúí‹W~Õy¼w¥§;¥~ë²ö.[ °¤+ÝÝdÛÜžRß‘ìÆ`ÆŠFzÓ[Ú’ÜöÖòø²hÍDL¤’À¯_¿~ppp´H>Vÿþ‡Ïç ×Ã’>¬³ÏHô˜À‚°ù÷îÕvvFOœ,EòãˆÂüÂ0£ð,Ævq^ÒSô1–NO²AÖxJ#E~ö; ÈϬdW<ÙGúI¯ìÏ$ý@‹E 0úãÉ~Ù‡Ë8vsw¨ô/&{—’‹H9Hö%°–;ãÉÏ“¾Ë.%¼ÎÉœIdü 0«ÕzáÂc £Iౕgd >Ôý÷Mh8âÇ/ôÎ3O÷'„»@¬Ñý#Œ'ú®?Ðõc'O¾=#ĪˆŠ,Š å¥š@M‚$RÑ# œ‰R•§&E©ó´ …r‘P&Â~(ò¾Àˆ‘¦xýþÇ*x bÖh€ôû½ld>íÃzðÎ7·vµ·GQ)˜Y$‹¢Íou&lß”ºÇ•ÒWÁåYQä)%©¯v)(¥ßmï­›’Ï©TæùI’ ƒAˆÖ…Äã`îܾ–t‘ŽµÌ£»Á$E£*ùÿ JT´0H@]ƒUšsIQ<ÕTQS_– ª&qTQUØV¥¯L13†Gu8¹• @Lhr¡ fRšI:A;NÒ]Fª×¼2A\2“Ô¯!­d{1ÙêäÜ…Â +󆦚(OE‹&¼=5â=+[mÿ§‘[Ž”ÖÚÞš‹`ÆPyQxSwl}Í©r÷±’ÚÃ%5°ì@#Κãõ9s£'‰Y]8þÕÃ宥.P ˆ˜Q–`Ÿ¥3qTe3ÄLi±¯:ê¬~Qó:Yáö`lŸ”5€v0ÌåPYÝ)Gå¹ ÷û…—¼>Ce&Rü‹MT*O^õVZ‡­n»­y‹µ¥Ëîñ¤>³û·¥4·Øê3=¶¦.[ÃÁª¤r°zàÄö_ô¦vnKl?\wðò—}¾!&nAötH¾¯?„˜B=ÿxד=6Èñ´’ÚÖ’ÔØ™æq%Õ,´Ø A¡œ q@Éy³ç9ðÁàí»!00d9ÀØÇÀ£ ËL™.aˆjàQã­Ñ®ÁÌâŸjZ>Ý®]¹š“½B‘d¨þSH™!ŠÔ:áµ³Öœ+×Óro­p^J[ýUöº«+WÀ$™ù×2 þ–‘w#Ëq3Ûñ•}퓨ãzŽóZzÞõÌü+YWÓsïdæÝ\žw)+÷F†³¨ÁaïÅß|Šü‘!‚"HHó"²?™ìZ̨XÒg#VVßJv/!{–’ÔÁ$6²(‚›KÙ£ý‰d¿•ÌŽ8F#û¬BO†°b&÷*'™ʌۤðÔB…˜˜˜òÃqbÄ›×ë5¶Ã¸4¢ËŠÓNŸ™15öË?}n„¨î}f áÿG%È ù׋Ï>¸õmNNŽlRDÊ[D* ŠF¾5Úþ¤³^7Ú/éÌp¼j´\4šHN­^ªœ,‘A‚¥¡b:õÛO°³Ã?]×þ«VÆèˆ(î±BU¯àiÐ_àÂüihW êÍA{—£¾<´Cv‰@²s9Ú•z—céÍÇÒW€viжÔ“‡¯vd£ž"ÔcDîlEGq$Ð&O0I¤B!£ ™¾˜ØÆiœIæñêWüÚW”Bò ’Ó•Ü1&þäùà;ú?ÄGaËÞT-Ɇm"gi%1uðÌäŒ ‹—#KZïBVÇÄ3Z”+™”A³É §H¦h…LÑ››µô÷§?_Ub»ÄEöøÑ5à½#N=<:’¸õû7š#‘Ùó^b)FÁrð­ – $yмÐëPu{‹z½ üÀ4Ò]Ÿ@ˆñοnÚí5=›4½nM¯·x»ÇÜå׸Êét>…•³22E$FI椡 ¯c) ZPãjQÊAí¨Ë…Ú*Q°Eªžº ci$"âtZ«$-kq¿Ot‰é“ ±L"I"G!¦¦N¸ßÆdfÈ9–b$£®j´¡¶jÔlÇ4Ò):²­ ¹W)æePŽÛd4"ch‚pg•F´ IhÃÊç4òsÔï¯n˜£˜ Ÿ (NIҦ̬ýÎú÷ÇU $@&o9¶‹R‚çypg É4éËŠ%Tþ—Bí!{íGÕà–wlTyŽ®m8"Ô}$¸Ÿ•_ÇÖùßqù™`y0¾«ò6ê,4¯ ‚‚ÌùL%¹yÊ™®  HHä{@¦;ŠÃ@-ÚÀO ‘–’-ÁB_[QЈ_Sw ý]Ðr\´Ý‹ ½Ó³±g´8®s†â{jzÚÍ8|:þ×xüf|wm7<Ò¤nxê4¢´ëCaM#ÌÒû*s*~‘š9Jbh’ciØ€X÷¡V )Žæ~6k¶Ýi‰t†÷ù'·‡n/P£Ec¢@àŠíï ?vN‘ÛccÙõ>„$´æ±ê@ƒL<:úö¾}€I@# ÇA±É€ìÐdI¶¼œõµÎú]©ðƒí¦Þ ò•ÑrÎdý³Þ|So>o¬x|c°\ÓYn”¬¾Qê8¯3Ÿƒƒuå̹JȨ$[¬Rßû?…‘øp,S,~òÄ Èl di†!å2äYŽöjPÿk¨?íÖ ^µh¹¨¿õ«Q ÓHŸzìt‡ ½YŒQ(eùóeÙ)R¹$=…¿ QÇ(¹$½Fîò¥[ñ‡Á#ÑFF¢Ã ̸ FAà8z2Ť -%¤„ìíû‡FžGbcmôÁ©!h‡ñ¾ßÌ\0ŸãY,U$£ ¸‰)™¨hjjC]{P¤…úPkêìCÍûP°™H>‰# %,M`§¥Mýò‹/ ª1iÍ8¿Oïã»üJtîÂâÇ?súL•àœ•>`ÍPÙ¹œ¦ˆÔ…³rý‚vgC~w H‚C dòïE0}Ï&m÷†‚5…;ݪí5Å;Ü¥ÛÝykòÔ޵@lp8H’'+ P{5ÚáB5ÙPØÙ UÀ§áÿ€ ¯M@-l@ Í|lû<Ö nªÑy™$G“¦< KÍfÔQ+¤sç+H (% ‚Ó”".ÌíU¨¥ôµºðNBvR½PDJ‘2šb礣ú2ì©w5“ŸÅÓì MDRÞâç4òÕv¸åò•-ÊžƒÚœÎñ{›Ž¯©Ò8Xí{«Ú[¶ðµiP‘|jB"U½øò{.Ï¡þx¥ç(¨¼Óøpº ¤Ê Î~ਇÁÖzŸ•_°XÆÁ5µÀéº`ªêìžæx °•P(XP4¨h–¤¼âÍwtèÃ_Pkƒ` Öaµ¯MãR•h6‡‹CZ°Àýæâ@àuwìêÐèH&gÏ|óýÙ+cò};~xÛQ ––’Í@ mM¯³s‹ÖÝ®kjUoyÚ4¬Ñ`öP@WcĨS¹Ì¯š^à’•§$9ždyñ§“(2ÁÌA,“4ÀÿܳMZC×Ö®ÏN~zkð‡'$œzC††Æ$c\;ŒF‡ÿ±ÎýÑ&Þ)BÎ@AüƵë-¡0”‚‡˜žL‚“as&%õ/Õ^6ÙΚlL¶ƒm dõ“åü ëE}ù£hä<u0пXj¿¤)¿V*üZeH!aC€Ï Ìñ›“'ïÅã÷@¢O*kÿ# ~äpB%cqS‰ž”JÉæÍD}:Ô· õ,C}*´KvjÑÎ<´»sØn5¦ïÉG{4¨'DT¤~–ôoì—l×ÇŸ„)R¤ÓétzºÓüGNR’MaEÝP´”dÄN.¹8ŽI 4ÿŽŸ€c;Žc'¶ãÿùë$"í  ¦MÛZµ[7UÛT1µu@iǺM]! ‰÷{vHlˆ2´‰ÓÓó»çÓ½÷»÷ûý¾Ÿ_&ES”šR™T†¡T¢˜³bÅkçÎ~ú›Ý;y¼„L ‚:¨`c¾eOÛÙ3“Ó7‰:Ü‚Ü97ŸÀïÌç÷Ïö÷úëŸòóÜ#o¹þrËU¹êScÝ_+®ê·]®¨¾\3Öl¬ýÄP(ò;cí_ uŸU¶Ôå¬â ìå8ÊB V¼‘8»ø­ûYñÿ|ÍIŸ™è$'rñÃD–Õð‚ «Dƒ¬fŒjј”æ „ ˆ–0ɰ üÅ$4VJ˜d¤5¯£–3 ’‰9 + Œ’W2ÙJ¯ß=¿5› ²^œ ’ëßá!IIºÙ/Þy7gù3¢@xÈùËrÀ6B«Ìf¦½ßÌÃÚž >P»­JͲ (Üha²Ru[‘ˇcÈ7†<‡‘o…Ž¢Ð:H&ýãȈr y¢@lQy… ›JbG @ò›÷ß'^M¸ëîxIzþ… ‡fñbR;aøà<|v‘"‚8LÏVmÜn¨ŒÚ˸€:äÁýÅÃíp›³/ ˆ®?ÐÈ“ÙÊc©o·3tÐqO 5=røꀖ’`Ó|ƒ1iÉÇH!¸bBîZ‚"žÄdg·,êФ¸ïä°[%ö5Èh`/òÔ“7GLÈ\&px…—²¼†fYÉ™ÜóËÓ* Ķjzí·R0  ¬ò„Fþj›í“M¶c»/.Í !Ák³Ÿ–W­Y¥ÐdÒPŠ… Š4ûMQé­¨>¾§Ì9×â€þ¸Éò&à‡©ý‡ÛüÈl?g²¨ÀË_o¶=.»`c§[:N6YO¶:¼åÛ_XÄN¬SCœ0fy%­¬Z»Å]lëÑ9ýr Zì ÷?ø¤.Իåpë|P•Hî€ìrIö`¹ÇWØ”¼>Ù9Pí‡Ú’Ë—ñøßg§a4Ùw̫﹣’Øc@ßÛ“o,÷z7Ùûô>QÏ£¦Ødo‰3Á!ݾ"§W瀾WêòJN_™«Çàh/Ù³5טŸóâsêåY8]ÁpJP(Ž! ™B§BÜaš0 ÆÆÍoÿü­dŹÔd ØÛPOzÉÁf,üõ/¯ÙøW’”xÄŠˆ#H¼èÍŸý´ð¥|È@J& ‡Ó1^LÓ¦•ß{×Póiyý'eÕŸoiü“±æž4bØq¹¢þJyí¥Š† Õ«lù‰¶BÅ2<Ë*Y¼ ¼ó^’FÛ}(]ûß½æ¦ Þœ†ŸøÔ 9ŽæÆpkšR¬W¥D$4^BØcL‡byh¤êÈí! ÅthȤ4%T€vçQkUi8UAQY,h«™|WCÃõëŸ}Ÿ‰ƒ?LÁéÎ$NšœøôôÔü6æf¸ôã‹—ò7æA•© P„ƒ²s‹°zÑ:]Ê&cš¸L‘Æ(E&M¤ùÊƒÚ >¹À? ®;<< ¢¢Ä,x{Š˜¾¨´ ¹ûQß«(tÆQp…£Ð8ê!ï(òD=1ä>€‚§çuÔ{ ¡µ,DÔA24éWþxyÞ¥‹%Ç6¿úå{M &JÍÐ4f1K¢Œƒèc†V±YëWå™·ÔöÙ }iÄž³í/¶–öï3è d’`@àÒ†¬_#Gí%ûtmÅ1kɈ ––†öëGíú¾6ÝxGÁˆmuµ¬ÌTqBÁ5 CQ슬´j‰(xRAÇ9Ôϯ4ß&F2Ùׂ|5ÈSÂ&ÔgB‘FÔ[OöÖßBzo Š6£hkšqCZ†˜Á‹T%ð„{S4k«CfòªhsŠœ Î÷4ëi6•¦”J%I“п‡8IÔnOhäþ ôpâd³Í.mÖ`žf%æ<à㫜.(H°Æ/<µ,²Íâ>¹«ód£,:±Ëq¼Å·gÍöMVP€Ó€%MÀ*`ïióc£‘3;°Õ#­¶¥Ï«3©O †0"Íe±K›75yKQ¹'¢÷¸K:“.uGôÝɺ,õ>8¸rW·ÜÑ«w$O°Ð tÑ­³~øÖoãSH ßœ?r¦g‹­·¤3*÷úK{`!²(,]ÜH8þûeÛÄyÇñGš„dÉÒét:YgÝÉN”†0RµPZÖµ¥”RHYâøâóKœŒ¥YVòþB¿Äv;Ûç—„$~IRX(+kK[!uý§ÛØK‹Öu菊KÆšBµy±³ßcCè R¤"¤®§ŸÎÏïžç~Ïó{~ßÏ€äÓ 6ô‘wtžAŒ>l¼/Ä‹p'bö ú }nÁî6õ6ÕÕl7î}l϶ìÍyTGàØ†Ø$ÌÃ0fˆy•’ݵsç… nܸqOÎR©•Ät‘¹\áû ¦‘ôÃ_Æ ¸H‚,¦ð”'â…ù´˜’H¼÷i’ÜʲҮ}Ÿ˜þin¸Xµ*\5ýd¶¦ñ~¬qÆÔôgcC}árJÎ0ÐÝÙД!«¥ô§/-Þœ¾ÉGzàw>¹Spk~þ_W.°Ñ$§æ”J ¡£»1€—¡ÉbI“ É$& h°U³”<K9Ç09 J 1cЗøÑû¸ï¥´%Ho-Ãb/-$çWƇ€Y ˆ+kØC­RS$®•iàœ—»µER…£h[G«U Øö²ktkuwE’wV‡ßÌÌ̦œ–¡U ²4ƒŠŠÐðÆß›H:‰ÂÓ(tN ß’€OΠÐë(ü*ŠLã;CÓ(r‰“¨Õ[aã€û V%EÅŸ}:—3Œ"ÛÀóANke( r²Š†Wœš}ÉPVåî4:ø¸sûDÏÞD.nÓG­š˜µrÜ©µÕ³e˜$ÓùQ÷)ØŒÂ(Њb(˜~1ÔÉU•ª(…²›ŠË¦™,PI¥‚С¡v€þ[IS±LQ¡ Ô,Qµ7ï…ï«ór! © Ü€š €|ò-ÜßÎv8Îr¾Õdyópßzë ( “>H‚œÌaUû÷”M´¿›ÁŒVû/»ûO·X~qÄýz—ãl«í½ÖÞÓ]ŽÓvÜUwߎ3­Và“³Ï/˜íã Ý5Ïî2‡ elgܦ¹ß}Þ^q(lð"ˆ²©Øà ñ ý@A­3¤í éú%èÓ ¬Uå#ðbŸTíu”Y#Bà˜.Ñ ÞøáAL#7qñ7÷ÇÙ~Áêçû$¯wÍ¢·¢wÈè ž€Î |"Vö?hôò“n¿Þ0|Òz#•bX;8Té÷•zFõá!$ý@Ge~Þ+U 8KSÑýÓº’G÷l.Ø@q ÃäN’‚°¡(ª¾¾~nnnù.H¬ ‡ÏçK$™ËÛ·o9ù¥ f æÞ“i´YL-%Ἒ•šûü³Þ^¤ë\(H‚–‚dOÈJÖç¾V¬57¯F#—«üÇ|àïÕ 3æ¦ùª¶7ʪ•r9Ë*¡žƒêæêÌÌÍ…y =©åäR2¹VUûf)|$3KpëÖ­®®.5â F*ža× óè„ïCÑ/CS<šØ‹&JQ¢JfØ¢ÈU’9U 08ŽiÚ²eËôôô.M3çÂÝQpxÀ?°Ä‹"K7aÛÀЋɩSÓùyYE6K±E²U(™¿ éÑà Ï4Ž<Õ^źªˆíÒ£$IP"MÉ·æ3}M(Ø‚Ä&¦Õ,g©l31Qþ’ÚÐH;²ÔÒÕ¥äS”Š!Ã)Ÿ,Øø-Ü߀ε;>8è>õJ÷þE”œP«Õ4ÎÄŠ\†}á‘ÂÃ¥Âk­=ït::Îu8Öw¾ÓÞ søv§£N‡ý­.×ÛÝnàŸwºÞkÇ^œê°ží°œk·ö×6ì(ÜBÑ ©dV•ˆ‹&ùÊæÚ3d:(2œý<–~±²O2xá~ðkÝAÞ- nŸàôñ® €Ÿ òž/FÈ4ˆµTî2 мËot έc¤*ÒxVSŸÎó釳q¾Xþb>5sz}’VüÚC'†ô>ø~€Šc&¿¤éÑKá 1 HU¢Kg„M.ìcù`¬rHÒzúApœ‚è=’É+ê\k×8àÒXvÔ•îy\¹QMB¡Š%*Í#Dá†øà<®yS8±<\üËŸ(R®æ”»·?ûѯ~½œÄ©~E°,.f’ÿŠ\d+­ƒwî¤+Ö¯®^5å`! " #ޤó”P¡;ŸØö{]ÝßÌͳÕmÿ65ΚB/Õ4]27\1×_®mºhªÿ¼¶óÆÆýù“¥¦`v»=yOS+íÿÏãî*às/¯]»V›¯f â%©z” ŸjЫehBƒPç‹DÐV\F‘0«ÙÙÙ~¿ÿúõ뙞abÓ«˜ig°µ´¹Œiõ¿ @òïŸÿÝ®â¢lšTÌ£AÄ!ÇÓJežll4<…¤iGþ“(ø3$Ž"V-#r” I3Om}2Óùüü|¦ó Üßå *g¢ñ“?†"—R(Õ ’SªQSòN"é$:Žük§ïz¹#ÞI9)[Ïe{‘ñh~Þ% ™ G/ '§äLW¸ûé:ñp]ÐúèCŸpòñ^mÌÒoޝ EÀ $E €cþX·nðÆnw” áã¶Š¨Å4éÔö€™Æ\|Ôo »9aÛ?á‚Ñ÷Æ«õ¯µTÄ{Kãvxëåÿ±_ÿ1m\ÀŸT É’%ët:ît– Â4!MÈÒd)iB›æ‡Hšæ ¶1¿¢‚…`ÛØÆœ± ) %IÓ©ùEȺhÓþ´iSµ­ÊÖt˺üþ15iû^½,ݨ*!­9=YÏgß{ïÞýø~Þ Ûä±¾[cây^ è¼Xp”â34Ô®íDÜGšHŒ¬’4µ®jÒe&}ómKŸ•xÍLK…|×v™1[^²…Tk¥ý‡[HOqV%-OÕB*ÍÈ*éú"VKÜ ÔÇ^™½R¾WK²Ò©’÷^jä¿h¤Éy¶æÐd­í§}þ ó«4«”SËÔ©Åë6»Ê+G¬¶ÓVûÙFI[lgëíó5Ήf7z?Îá«Õ‰!%”"ÅbÃôNÔ¶NX'[ÍùÆ%JšbRñú­¤l–ðé•ÙÅ H_i7R;Ž)ˆ %BDJDÔÅÜŽH¿W/F |Iчdb¿Ö×H@ç ê:£EÁ~SŽšDXEÔw žN­=jêœ-µÃE]?OâµvÿÉ=|Þúõ—zwŸ¡ûûÒHÄðïpaH½ÆàÌyº^_£9§1gñ–M ×mZ´~½&kW–É_ìö81Lè/˜®·hô̵_þñº:LަC¶=)3ä¶x$!¤ž ˆDZ= ’„R¤”œšþù•+×®§”Šá’Y¨Ækp!E9ß|ç·ú½×K,×Êj¯•Õ|QTu§¬î¯¥UŸî¼¹³ásÓ¾Þµ[3hVdAFFló\ün‰iŸ~fÂý¿’æÔ›Ì²I¯ÉÈÐ.2ZHFtdP÷J‡–ËRc aèUñ’FöìÙsõêUûøñ£DSñæþMü4c€ûøåéôŸþüåîݵ©rnç*4\#c^¾:›4ÙHx˜Ǥrä4é%¡1'ÝLjÏM©2p "X†>oÒ]K¼û^jäÛˇû—Z:&­N ü8Q×z¦Åõq³kÒêšBj]®w\ÞïBúhiÃþùç¹f÷D‹BxÁ˜'[<—Ú'jÛηtØô;—§¤!z0ój†¦)Ö¹©ŒR·bK§Þˆ…Ý@b7AìŒEöåy! $:?¢9TÔ)–¹…ëß5ïÌ**X©-X¥-\­ÍÏÌÙ½®Ìah…L¢eƒèßáBƒ!½w¶ÔŽê‚ÎüÖ_œøÙôÃéßOþN,•¢?¤súÏJ'jt帣ÅiÿŽš·_]à¡`É~†U ÎJ[‘U"–wм0L¯>ˆ³Æáß¡_ ¹‰ZŸ¨•¦'4xQjßÛ»œË@GJep|dt:-•AjIË?Ž¡†âRðˆàùåÖ¾õöù³çrqv @‘iõÍ×çyI|Á‹òÕc)ìnݺÕn³   ,È‚@g§$o5|Vbþ¼Ä|½Ä|Ãd¾fªö¿•ÍÒð‰ÍÊ|óÁƒÏv$µ,Eç—%qLÏLEbžN5~ê4k*³\ÒB³{#µL‘As¼œ’®3'ðûFú²£CÃ÷g‰;$±%x#]úøO¸Ð3ùàÄØ;™™,«P2ò Nah-¼’¾‚ä•’À?Ù/ئ®3Ž )’¥««#ëêZײ…@ $Êšn€cˆ<¿mB ^]çY'~¿âWüÈÓ¯$„G!£!„Áh»ÕTmR‡ªMêÖM¬['mUW ±÷;°À¤L•¢©µ>Yç¾¾ïÏ9÷ügùDz¶~‘àGÏYä=CA8<‹zFIÛWn*+¢i 0ý ?™æ3j±WNgÅŒŒbš† k0æ½põC¡K(4–­5±d $,.2R4PSϽ¸¡¢óè±QGmÒ¤2€•WÚÔÃ&`y6j¢]@#ºäÒPQ'-5 SUÒT9b­±Ê’viÜ*Æ­Gmgn^ù󽿧2éÏïÝËŽñûéÏm7ΨO;+ÆŠŽÚ+ܹh‰$Ц‰5q &RPD5jþNÂ/²ã59a>¦Å|v=+„m#ù åÄëƒM$†Z‘ïØò³ÇÓ(RO)¬'ÿ¡Fƒí(ÜŒü äj¸ ´¢@ï•ê•EÃ"Xß0Î縵4^-àVì-EÁF‚.ßÐÈ3c²Õ2©7N×w_m0‚H8óã7^Ñ›ˆæVÛ6ûÛí8¥É<Õº|:[ÌSzÓt£ñšÞün»ãvÇu"õÝSú®ñúŽº²ò|>›s91H0@8·F¸V÷í:·Ê”:ú¤^ð\°KðЊød0qÂ!J7`I¿Æg|r—_ëv©-†ê¶Š-{·Š6Âþnƒ¹ƒo˜Bˆin-.ø^qyãÞ“pó`-1åˆlQCH}áZ¯»Îò‡·o;u6¯Üî¯vjþøÒÔÜU–€Ê¬u7í}=]Èòøð¥3À ¶À£ó€Ò„œva|of‹î®skÌ@Yå„F"JßRëÂã~•êF´è[èRèIè^§ÒtJªß.Ù$É®±Ä—`KD3ù˜lÿÊ‹‹ô;wm¥y4?2Ä´hàV©T~pëøÓýÙÔܼÌ=v âXóæ5—žÿÍ-ô¸š#†ÜŽIîܹ£R©X5芚 Ñè#ë7¾'õ£CúO_nû‰òÕ2ˆ±P"¢1ž8áqÎGæ5—ù2 úZýžzýTj&“N}17»±l·„ÒŒö%¢òX,.?ÇR4°hsgÛÝÏþ žžIý'ÃB´#yæ ä"ýÞÏnê4ZX?aÆæS¼ŽÉ‘ljWT¨Í‹Q40‘åqäGÁs(|'Pà" AcùÏfÛ?@‘ÓèDƒÀèÃô+äüÑïr%ž"9m¹Éö0•Ú½s—ˆÖJ0‡ôÈõO"ï(Š€€óäp©4Ò{ù'{ £#Ç‚ÕÌpbÇ NŒ{ö ´+“ÝÊáNùP·rÌu8f=µŠ™ÆÍ@Ú„Y7Ê¢K¥MŒ`Œ"a®JZÄM•Q³|¨7  Gjûû=1… `#G `š­/G&ýOXÓÆêS9<:{·¢]¾]º‰)ÉÁ=‰—±,ÃÇàb ‡YŽ =_ZPÌVmØo¬z#¢ „¤‹ºù°*ØSmö×:}µNÜ’{†t¡€ÌþUÑHPêê×y!·¢u»¸t @$à@­P ¬ÕÖþõ/wamùÅÏß_[PHåñ$B±ˆb¶‹Âuž@{@Õ ÿ9T[Rx•V¿ÆÐ“8| aMä1N™É¦3l¬[ňDŠ˜Ï1XÒ7Š„#‡dc·»ºë¶•ˆY ªK=šá{é0þuÿ>Y çÒYkHÏÌÌäÀ'ü"½Ð8þUx‚;öÚQ(#ºpˆyåù×üäΟ8 hІ œW²ú‘’_@¡Q#üÓ»D€ƒPß[$Op€·yHÎP°Î<_¹G³UŽc&uÔP›°É£VU .¯ŠvƒÅЍ“UÒH¬‰4rhĬꨉviF욨õ•‹ûòÈô‡7ÿ‘ºÿÈ2“~0;]3;;C@$C>œß|úÉɸ·fبLZ¤Ã†œ€Åò«‡;Õ±.š   kEÂxxÈx|È p%OØê‚Ý/Öì¡X :V@c1LXb9¥Øƒ<ú•Þ¦åÇÿrsÂþ×QO= ¶ ¾V$€"ÁFÒ†K}-W¼ÇÑÀ)äo X5ÜŠ"Ùg£§÷ 6 ÁæohäÙñ£Vh›Ô!ˆH Žf ˜> ÊU¸¡Í~½Ýí)¸š…åÒ9ÝnŸn2ƒ@‘©ú.@‘IƒóL‹éå]{J8!ìjaKË`¦çc¼X½CÛSgï×yü•VË#wU®ˆÌ(Ò«$¶›c@‘–økl¹#tÐíÖYŽìüàÖ¦ á’€¥…_¶µÂ*7@oô©üÐ •k©uCZOfóËí­ÐŽ$‘9ûÔÞPõ¿Ù/ئ®3ŽiR¥H–®®Ž¬«k]ËŽ•ÇRBȲµÕ*¯Œ`;ŽIBeЄ%qÈ£Ð%~bÇ{ý̃<Í›QJÒ†Ú ÖMcš¨:´I¨°ª@§u•(±cçî;v’ee©”-låèÓÕ¹×ç^ç;ç|ÿßç‚«GèයçéŒ4¬˜’1¸,g‰ØÞ- ‚è²ß÷{~¶g×Ö åó —†Éy\¡izéÒ¥Ýíb\LâÇÔL1;÷ú¸P]›œ>(içŽP—·7/5Š2ZJS2 ¢·’–¾¢PåJ(ÐR©qW~5šÔ!øëä7“¢9 B_ÏF¦#<Ãfäi$'O¦4[·JYZqº”“pʼ¼‡b„Bˆð'ÂoE¿ 3 ÑO~ðÁ½û‚Û““½DŠCXÐeÈŸ¹ðµì¨Ò€‚aB³„: (â;9 !þ· =(Ø…ÇQè$ê<…óv‚UŽ Úf‚Á +ÂaeÃCçç¢Ñ|-é,ýà¹àFJv&Ú´ ]¨{9áz 9Ã(x–üËBi¤ã(âûPð ™ Õ4H”*NÉ&É”wY67t(í3–÷;Šz¯ö›7õAÓÕ½F-1Pü$ ¤ …²°Yßk*9l2 ôüòÖ‡÷â.ÂúDb0eàøë·o»tñ‘›ž,ÛàoGËæ²~‡¦§^, [0æû~y/° q¯°»\…‘¥½æ².sEys¿eýQkQ¿­¸ËTÜo×ôXך^Wrrȧ^áð©X^³Õ—>iöxÌ|ÔQºš·†XG Õ P=aÀŒŽÄWbñþµP;°Šyë¯9+Qp?agÕ3ùj1˜‡ & Žá7ìCuæáç û@&À`InÛ'åç01Ëûõ6ãHƒmè Ý©ÛõjZ6æ0#Å ,À–A£™Õ™Ë÷–ùt^—ÖÅ9ƒ:G—–˜ sØõ3Ú­÷“€A´½DhÁ·yKSá’¹t– C!ÅÒä ³³Ö¯óóÂo®üúÖ¯øÑ/¿Y}€Ôn …•–QJ,[&Í©ß\ý48Äëì ýíZ¿o‹+XÔ*èm‹E#:Ÿc›Q³rñœehZ¢àägO¾EÒlj:ý&:gΜ†\¹ÐßeÒ̪µ»Ce™& ”v‰ëŒöA?‹Cvýôá=ÃrŒsYš„¢eR6S «,§h‚;ZÆ¡*œÃ³ú›ìK„>iQ=Ù}°ŠÇDñ ˆpâeø1&NŒ _Î{é%šz.S†Sá+@6 £T*ÑÎÔÒŽü'f4Nùöž^¨úã{?œRÁÐYX–‘–»ÿ >‰þ+Ö&ÛôO‚‡±‰ÉÜTèôKYšfRXŽÞ"Gù‚NgBIOì!(ùN à ‚O|½¬I¥S{àðjkví<â\ßÕ à ™_ýjúnkI»ÉuþØï?û8Føpj,…嘂Ec¿ûË~Ñ«9büÃr`È ˜°ô{õaǺ^ãÖSy¿µ¬Ï¢Z$öLÙëWK8R¤¨¤l+W2rÈá¸ð;ÈòòW­íOèi- $Ä”=` σuÓÏ ž8®<íö¿A#O›½Óh(ºðá2˜Þ5,MÖÁú7ßm45:_ßz¬ò§{¿¿1CÆPÍ1ÃHX)^TXU²¦ãp¡w>õŠœ.µ½­\àõv—ÖÚîª[;´<¯·4T¯R.g° 3 ŠXÎqÔëõ£££âœÄ•T=ȵŸÝ¹«Óašp²+U®”³\͆}B©Ó»ÍÙVì<–;ÝjkP#,uGyu­ͯ¾²{5öö¿Pè²—Kò‰è+AS)-¥›ššˆoãs«ÚH$RYY™CÃùi/zw´ú¶:ë}¼zÁtØîv«m3@Y`¡">i>Mëa¸êhÑÔ¶±2j9#—0ŠwÔ¿àbÀ+ n1=.Ñ'>ßqë`sÕÚ<Ž‘`–‚œ,ǰªœŠæª^ÛóÉ?‹ãâDLL¨ÜTRÈþ)Ñ(èÝd<.ÎÓæÐ síÚµÒÒRнïfæ¬P¨T´4‘ÐÞýô6ÑÍÅ”ëÿç6‹ˆp5°åîܹ#Î@È—,É'„>EˆÒ%øð£ë×5MlD %çR8u”DŦ?÷ 2{£y’í;Š'ˆîûN!aáêoñÑÙ«Ó%)´T¢äR‹+~,FŇâq'™œ0“W1¹£âðÙdãÑo­X©¤SXÓò4‚">@‘Ó @ÇN¢L#g· ÿ8Âd^»•²Ë2Òo®Óuš ÂV}ØZ¶."ô_þ$ò – Pkb’ìuB%âÐ¥‘=!“6lÙÑmùóÄßÒÇŽUÕiÛÖg+8n×öY+zÌeÝFÝâùh´§óЖêÊ\ÆÀKÑ©¬jLnYº¤Jº€4ö!ç^ÔÑD ¤­ñ•D^Ûš_M¬­µÕ>i­úíü'(r¾Þr¡Á6Ò`ƒÛŸ7Ùßk°¯n¹Ðhi°œ3› Kó³ráÌ2˜RIiŽc!Î Šy9sµ¡ Ê©7{´ ÐÁùÔÓ¢©ç…_±3©¤~=‘Ôý›ªV1¹JŠSÈ 32 ƒóW­ùàÂûÓµÙØäŒ¢Ågs1œâþÞ>LcðS4¼¹‚ÉÝ¿¡€Á«vtîxÍ£9ê¼X4_fh×»}{°¨h æÒVî}}}E¥JÃPÿ”*Òë„Äf=šëüÍ›7—deÃŒU´¢ú‡{‚%ž@‚ ê¯µƒ‡&úÕ®¤uo÷·ZÜ:c~z„…#©†Ö­Ì'(r¸-îqŠîVÑ祑t‚m¢74ZU«{!Ó)„  $nædd…þáçŸÃ`NDyÀª¹ÊÇb•ºKç¬zŽ]¾|Y|8vi`¨fçîT–ó´:§bÓló_‰ôשÍqŽ ‹‰h'I8ч¸N&FO%ìì—{l÷ÀÒ$¤H–N§ŸN§;ÝÉNä$^-PªRJ–ÒˆÑÒ!‰ÇÉ’E Ê#„@ $qüÌÃö_I;ò$ TÐRµ¼DÛµ]é¦nÕ6MU¥ŠýÑòªÔÀ‰}ûþ|ĤÛè–(LËÏ_ÎÒùüý½¾ŸÏàïÆõ›ÇŽÔ ¬(b^¤4ZëhšÓ)Ù›ÐQµ÷ ñˆŠøˆøG‰ ʧKàþŽê,8¯°)†įGNÂP³J&9yC¤vœ,´ø§†96ÑèYágÏç _BEüÃÄ"@E |ÓLFµ ž@Þaä@¾S¨ÉÇ“¥Îð,;?{ØHá€ÓÐÕ`Œ4léj˜-ú_úò bY0Q2 ñq¢`†07&îº.Œ…,Þs'ˆ LÄÁÕz?¿PÜiÙÐmÍ볆ê+ÃæÒÎú’ÞÙIÂØï4Dwö¶”9j–®_ÅêHá0N1<ÏkL?»Yv ÈäÙ‰‚û´…Ž ÀA$íAjâ'ò>¬yܬòcÎFfçU9d«Æzæ€ù½ƒÖ‹‡ìXÎÕØÛ·î)ËÎMxbÑ€(kyž¥…ù8£rM±ËTï1˜%£3X)Û m¢§ßØÒnòøò›C%¾€Ñã)iršl[W—§Q©ó¹t-x†sÐίݺqSIÀ-á!±)eVm‰b ðŠ+'††žh‡Yxà î)›¡®½ÌíʳÁßRgÍFuÉÓ¶#C3tT„Øab&í¯o«Tú|¡À¦²4“ʳ 8úJÍÅ/ÇAEZ›ˆŠø¼ÄFdw\rE½-JÀ«´º_Û˜Ùz!UÄtšui>æ3)þÅg³Ï½wñÞø8‘‘ÄÈ«-©%'éZ<>x~llL%#ÔçO?úäþÝ{‰yøé—̵dK.§²19ñÑ„™Ä¿Wà0yñ6É•¥×cš~P$E^À‚&kÚ^dàõÂë΄Š@€Š‚Ÿ@ò’†‘wúôžFþ¾y¹…zœ Ñ3:!kÑ·Wÿ¬Lng5ÿä‰z5~¸·›íë,R"Ú¶›Xoù‡ˆHG_áý#ÓÎ~ì#2ãM(–t:N+ÀH|æê¥[»ý°SÄ\t|Ö追«åòWŒ*Ñ;Êý¿þðmÿ•ËÝÎÞŽÝ‘.Ç¿ÿûÈïßÿà/PÏYcвgÔWØmùeÅÐk3vY^ëu„Íy³g#ºë úm [¦n뮈óÕªòÔgÒi‘ZŒ…4št: g&/¦m@žÝ(TÂ5Hz¹÷¢¶ZÔQƒÚªˆø>nÖ?ù1g#3´‘wªÌç_ß>d{»Ö~ºÖVó²a•NÏQ–¥XLDky‘Æ|î‚ÜšÍUn“C*pv–È~C‹s‹Eªp? Å€òÖÑ ¸I©È)[Ìd œ–¡‘ãxšêíêL)ejM…ï@±ÒµÌÂÎýèÃß,ÊZÈ2,ËÃfb_ÎXë+k†d@{à_܆¦Ù²‘ÖbG°ÔÈwµåKm….ùW͵^H}V”2–¥uzíÕ¯¿ŒÅ¢ È>´‘$‚ÕÚ{ïúØâÌ…¬À€¤3ºêM¯ƒØÀ;§›¸8 ‘c3¼ÂS"×o¨Z˜º„¢±VYšòçmTÚ|ŠäR\ÍDE *¢ødPÅãwYãà$²¤xd¥#|Õn5¯Ëѱ( O|&Ã:‘ÑVL_}ñ'Ò»¸r÷Θòã9z7ÕAHBnT’Þ‹F£ ý˜t6uâ§åÿó¦ÝC'ŒM@$‡Z}@u<ñÞ¿¼võsjž˜)j*–`^Ãf ¼ d¢à)$ ÷@÷ âè ï0’‘wˆ<8‚:‹ÇîÄHÇaS|ýýw%áÆ’^{~Älˆ4‚0”öØ6GÌë{g+cŸeKwÝ–ã–ü>«±×²óx“©¹úic®žh̰˜ÑBYãXŽ¢¸Lݼ½$ï#l Dò~ä9¬FµÈ·ÿq³þÉ9™IÀ@]<ä¸tØq¡Æ~®Ö9|ØRk()ë)–fu˜1f1Íòƒ×kÛLr°Ôå5ÚÚF…­ƒÛetVf—/å‰X€CÃá ½îü»gII+±)5*YWÕÚ«²ìÁêp\ùݕό±@Áé&]#V­Ûå/u)‘äYRw±èßaôúòZBr£áèÏõ«RiQ«(ZvñÉ•cÊA5|ƧºS,y%m\qZí:³t}ÃÓ¹®R;Ú lÄotŠÀ$ÄmpÀt@’Me-¹ik´Œ€1…YÚôÌò{·"Ù”€ŸxˆÏKTDr+~/ñŸS ÂD¥Eñºân¸JŠßÿù±ºË–éy‹fyVƒ¸òlcƒùöÍ[¤±X‚ÿ šñÉŒ'‡~ÇÆc$¦>ú_@x®‘¦ZÇ¿ü©N÷×®]Û]TÊaç´4#ÐbŠN­ÉEõ!Ôš spyû‘»I $'‘o„„w䊀´ÎÄF‚ý¨õ$ œD‡mi¦Ò`ݳ‚ÃáP&e)©£ Ùä(òÝ7Ó :( ð|ÊòIVD†‰‡T YM7è‘¿/á6£È=ˆ‚o"9ÌòÄ‘XŒ欨ìr€9”öXLsAWìÑÐV©ß6oÕºê ‡@uÊ:ºO÷Üúá†2‹GÉÙ fíŽrÿÔ•K]•½¶âp=xHY¯Ý¶V ºŠz³•©«^ºe°oì<=Ý1Ø úŠ­zþÊ% C p’Á˜c¨o×®D5åÄFÚªP°y«‘gßãýÿDÌÙÈLâüÎ3U ïT[ξáðmÛS¸*'ƒhšÖ`«²ùTnÁæ•ë6VýƒýrâºâøýÉÒJ«Õht5£YíC¶)6±#D¢!´JbØ{½^l 1 I Ìb{Û`ãb‚Ò µU?4UD›~¨Hš&Rj¢B¥Fu*Úì}Ýž;»,î·8²D¤2:½;ÿ½wÎýÿîE»;Þè²…FÂ6I²+D¼ñ†ÁÅÜ3f ‚*-þ°Ã÷ÊÆö¶Êhà1†©Â+­ü[°·|––$­Êü#)…–Ü‚_áHÏÍ}~=«ƒu®‚7o®|Ñ#vƒG(àÔËD#6’è….ÄÛÂ.ñÜîç¶›õ`Õ06 'pc—ÇA׃÷©zªµÈK ÄçŠÞ‘!w?½#<¥ž]Á˜ûÄ®ÈÒuÔAè%Û|&wd_0llß šqE…[leÊÞ?{ŽÄ£D¤RYC@Ž ˆ”W”CB^"ûsr «HD"À$Ñ¡9%öVgç&£`1bƒL„á8 ÅU[S;:T¬¡‚­Ö¯Þ†Þ8ƒÔ!}ÅgPl I $u¼ÔkH£®­\¥@ãžÒÎWQxbÉî/'Pbù§Ñ…i´Ãa1U%c“Ùb±Ü¾}»Ô‹“hÕ¿˜¹&l°°Ì3íH.€Ä$R§zµH )6½d=ônœÞ £Üu|–!ð ãšMkÛ†]Mcn Çh¿˜ê_.÷oJöÙFz[.öc´¦úê/žmJö@Ø“ýžï'>ý+ÔOŽIþ>™;5)íKR hDên»àìÿaêÕØ²éi탇7Œô4§h7©¼KNPØ12°wÂ[ój½ÑÌYYÆ‚9Þ\¦Ó[yݾ`¯(~Io"ùÍŸ¼ÝÅã)|™€ºyvpäÍ®ƒ[v>ËÙ2=þÀô›Ä ‹YóZëú76Š´ ^°Qj’<:Ðè7{Á#¢?a—5Ðf),ú‚­ákø2ÆÄóoXUµòÃ>Èk«h6“-.¹ÿ§sÙ’o6€pÍßg?_UUÍa£³2ü±ºÃ¡f"C¢¹h$*J²¦?àné®_[«º…`Á0 ÝèüL®H"4+íør }6_ô rè@'¦g0éqÛK-@KÕ·IÀƒÎJvŸÚæï«ëªÅF–ÌXøkð}gQÕ|`²G!ET™HÁŠX„æÐ.K”Uh£:'yóaÈ#$ú›ßjÜSΔY0SÎbƒNoâ0¸ooÙúË[¿(zßc¹g®4‰ôçCò„(Mqæñõô(Þ‚-§ã©•R:­©^Å U …VÎ0V†++¯Fû¡PEÀÊ€ÔJQSŽÝ fÔLEg(–PÇ¿†ÔI *@&ÊÒÝŸrÎ}>¼+2^¶bu-ÆzŽaYvݺu÷îÝ[Ø‹”fHîpûA,•˜±0 ê?‰lH0X Ž<œ#PÄ ¢Y&¡ Q#DUHÀKBp—BÔQà‘ábõ—çð† P†ÎÇsì8p÷Ïwþ—uæ8MÒéyàµÂˆo€„~ùü}ÒÿïQúþ ü„ܧƒ£7Gòé,ÉÞ#0ªð3óλïìÚ³¸èq%ìl9CµëÍ5h¯yT”˜Aò5¸ŒbS‹º¶2‚.N#éòÏhÆBÑ ¢IT£—è[HžA’†Ñ)N¡ø$ФÏ¿N‘&>A/€· M#ÿ¿ŽÎ‡Ÿ©~þyCÐ2Ëè=®2—&2Ÿ¡ŸÉÍA>{ï_fÖl€%s-’á7–NA òІ.3TC‘¬@ÿRÆiš¦ªºÜl]É–•cº¹`cå;ÜßkO¸¶¹[S}Ždoûhÿþ¤óÀ¸·5åÚ=ÜÛ0áY.*¨»Üßž¸qëg9­î“\ò½›ödïÁTßžÑóu“n –3Ó‰ÏóóÙ ” ùõg¿eijëÒÀŽ ç®d/ðHjL:—K}èlÛ˜sïhoÓ˜{_Ò³¾³ž­À,g`¸ÄÈQ&ý—°i-:wEO¢X’Ž È ”8"ÇzE£ðë(zBóâcô ÿª…xâlð”FžL@ÇirÂYø qS‹Ÿøi—óG'Ïß„8ïš8~ÎÓܱڴʂÁa z¾Œ1êŒ&l„B5˜­n÷ìîQZ|!Ñ#Û|€’è‰Ø‚KuÏxc0`wÖ­ÙRÎÞÊ«Ê+?úèÃåZ®ç¾¸¿²r£7˜4Ž:Úðš_t%Å J³¿©SnðÇšÃQ{: F…x‚ßæÞÿÍÖŒ¼˜aôÀS[¶l~ðàA‘ˆ´£D‹ù<\ ü’Û¸q£Ag0±B9kvÔ5Ãë.ؤèžP¼ÞÛÜpމ‹Žó0è´ù%;Ì‹8häàÖÖr ¬`4°†¬ûù©£D ‘ à„D‘CK À•p€ž ITͼŸ}ýÕ•@«°$q¬`½~MU•òöÙ,ÉÃhÙ2—OkŽY²Ñ…ãóoöë>&nóŽø#!EB:ɲ,ë‘-ŸlN„º†ˆ&R’¥ªXÛ5i^ª„—㎗¦tä¥!ãÇ÷æ³ïŽðþrÀ)$MÕ’¬[²7m¤“:U,Z×N‹´DšTi´Q Žó~oËÒµt¥BBš°~²ã{üØ~¾?ÆÉúòÍËã‚aÂýçézD²‰ŒsJïKp$ÙññÝ»§ªO`HU:Ý$ ´Àm0Й´”öÃbTÓ€”n¤Ž" aE µ—×HpuNu@”‡F‘:ŒÔ8 M¢®1$ ï0 Ž¡àò’#{FQçUñÊ( ÄPÏ$9Ø3HÎV À_ã:&‘Y_¥Œ¦Ò7‹M3S7o%$ú3òP#™<í3`:‹ë i/#¥Sïà 5Š‘ O dÝŽ¡À0RÀTWHõN æ@Ú3?Ø I&ŠhŒ ´d8§‹´µÍV5â=Üç°µõ6Aè—õ·Dì×GbÉj¥ÿ^û½÷¾˜I}ÎÀ4Œ ¶”ô7UL¸vÛ«:¦gþÓ¢GÚo§ß¿öû_yÞ©îwW ´éo3÷¶X«ÕŸc-–žóæ–‚¾–¢žÖCÞÊŽ†m…/Š kže¡1A1ô† ž{~'rV£pcZ¨yN¢` ŠÚP¤…N‡B"uD,¤]‹:m(Z·Ö6X×ÈÚÔÏëœpíïÚZ¯Õ‘‚ì¼ÙàzËÖvÝÖv³ÞùësÎ)[³§ôؾÜí"Řc@"0ð˜£è JØ“óü¹ÂZOak¸Â*÷F‹ 4²RŠ@A¾ŸÙ{2›ÉÚ˜giæêääÒÒÂjÍÛss³íð=Åcr÷÷æ½xˆ«ßÞ!©xÀZ6»%.µŒì »BfŸËÜj/¨ÛÂälÄLö@‘­[sggg"Ofë7SDû·F“‰x<.p‚‘áMŒ°+{[°Ü-¹º-¡.³ ƒ¬VxƒfWg‰¹~ö–ä¶ÎÊܵÔßt¨~—i|·P–hÊ{蕯‡hDÑi!¯\#jP“}d ñ{H#¬.z\šÒ£çm–(Ö`d肈Ìòü³;vüâæ­T2jpWŒÌ<ÙÖæççS×þ¸±¾|ûå+œÓ-—H$æ¥"lþ! D››™‹zB<–(lbé bCÚ÷ªkDBpB$N¨ÌAchyŒ#%†"—Éñ¡¤Ž£à$9ÞF œ$†¢CÈÓ‰Îʤ]D8þ t ¸2‰<}H"¿åÑ#“Møu%NÖní·ä²4%pNܺiˇü ¡Í%æà©k}îÙnC¶‘3Q:EFõÞ®T#—ɆÇPx…‡PxX7œj⤟Þ³ßÂM†ÉàM›²²%A„¯$Ð56b:›?êi¬êsˆ6–Å\‡{› {›­CíE=ÍÙåm«•þ–¡–s£ÁY-¡¿5‰¿|zïx·vqöµT_r¾7ý»%xK©&‰ùs¹ï»Ò¤»¹°ç‚exÕústØQÔe/îo¶Ž¸$%íÃæ®–ãÍg²woa0•-ðO3lÍfó"Lã˜çÙ=»ÑÅ*ÔÛ€º5„"@hD9ƒ‚µ$”Ã6Ôµæ6X×ÈÚÔ{6ÇOÏ:¦ڧλßil»®õ†­†âV½÷FëjÃ]þ£ý¹y›NbÀ  ´‚Œá3 B¾iwíK§<%N=‘=J©Pá2oÈJÂ=RX©F¼¥í{²ò3àk c¨ãUÕ0µ.$_7·%ùñŸ>ú^V6‡A;\.·©µÄŠøjŠÍÐH±$u½¶ÃonçrŸæ6ñ4 àyê©ìééií+ôøŸ!´ZöàÁƒL)Sä…3YãùWl~K{Ô*‡‹ü0ÈrYG Ø™¢Ñ×÷ÓÕ¶ºCÖŽ@™«0÷HÁSϤcª2oëßÛÜZ8ª¼ ‘$¬Á+Õ1ŒP$Å’ÔIÂj2Сu÷üÃá´¿Ÿ¸ Çòœ†5Aö˜W­•øàɘ?“ÚÜ#0‰>,K_‚/o®/Ë-DOhä_Ñ´‡ÀM”d›˜ÌÉÉaicòõ ÁŠi#6æ¥UœBÁR/¡èR®"9®ë"ŽüãHCã˦¹z™™@ôLp)Wz“¤ùé †]ù<³(fÇ9:}û>TcGî(R†QWœü·\!¤ ©1rNøuøks„% ‹"#‰4Þ{𥻟ß½j‹Úõø; \AJ72›ù}èÔû¹RŠLè—9”1] £ú…@gÞ"°Íð¥ô—Í, Ï-#Ò,`º»¯¾20ŸÅqF–a8zãîÜ7å–ò÷Áî Å£®ÃƒŽ¢€¤ bmؽZéo¸xªßõË;ï/j‹`ޱß\}Ðup°i_sYo[÷x(²øHK&æµÄ½ùÏ>ƒ[¿ +4™ü4ñ nL)ík¶ 6¯VˆC[áœä´ý0ØÞÖ’˜÷@ôüÉQïú׌[D€¤‰Å0nFÓ€^ˆŒùüm¨©Š€$TƒTòÖ  ŽÈâµɧӼ§×ÚëY›úY½4™²µÂ8\¯k“\³µ*NÊÛ ³Ø’•f K‹Þ%>SýÜQpH¸TV‹ýÁ" Äon—­n">Å¢kĺâ”o,<›e0IðCLCâ'þ^©9m55o豊J˜a LŒñõü#²ŽÐ »„p'îø|ÅNµÂ+W¸÷œÙÌšDŠã(&CM&éÎB‘Åù…•ws)™$ —___Ï18 ð^äîóW:AAr»«Âï)v@7¾A#>³;Z.«…Îp¹»á`m.»E€ÛhÄÙ=õÆšzIóÉZЧÉ^Íß¡…V®àÔ“ ñ{È»pk>¦t}ô“‹Çvì`(ƒ ð¬(04“Á`#/ÙÝ®ûŸÏÀíо˜…+]€ùS_ XSµz7ýÿ|yŒÛÿ4ØPbéöíÛæ2+Å06d™,La†¥„´×Œ\!yõM"¤³Žàò‘Œ“„&—MsHm1R*lÆÑ?Ù¯û˜(Ò;à¿ÄÄd“M&“Éd2“ÙìKx´â)¥Ê/×5½ž/U`ew‹g­ð©¼//ûÆììì‹À‚¼S±5©½¦æš^Íýa/½¤1mZÛÆ¦¹úwÍÅËîNÏr1ž ¶\HHZ'¿,;»ÌÌ3ÏÎó|?Opúbàéß|¤Järôñ (Çk&‡Òà²f“ù8$òϾ ¸ö“´af 2ÊÈSŽ¥O‹½MW):»1àÃ/ò¾½wî¾ÿÇß}´#k'Çhy^cÒ0p¶|( <Ãêí\­ZþI&Á3E †õ̓ç&y CÑ·M|f&# ¡išn¼T‡Ãxy9þîÍ[F}…s" ÉÈßjö6ÖŒ¸,Ã=‡†Ú$ÅC¶hGUÔ¾^éx¨¹|¨³nÐù‹ßÿæï©'¨‹Ò¨ýЄÝvÝÕ6;ðhñŸØ,øg=óQôIUÄý£_¿GšTÕäo?û[õ`§-Ú¶n:±— µ­Üã©¡ŽêhwÅHwÉ@û‰1û‘kÍæ‘.óP׫u•BAÍ1è-8Þ) Ÿ‘6IFÑ«ÐRÁ:ÖCð")t†rð2æ2(nƒ—Ù˜ºÕ@^ÙÐó«KÝwÞ!™¬oQÎÔعËı"­5‰ˆ’Ü8МÏmµî)î(þ¡buÌÞ°YZ¼^³ ÓÙoq¥)â–ÍNÅì [¥/¡Ûëe™¬‘cñ©ekkkq@-Äãq5µ^óv<¾ˆ'{ïçwˆ4æûk†¯vÙÚÖÚN¼}¿-÷¥Ý²Í%W9jžÝ'èYÞ êðä,Ë|ðÁ]¼âòÒÒ—i~*%˜$©ÔÇqfÔ œ°“Íi*yÇWN:-„T,½óªýìµz|¥ÎrÉ[f?žÔÄ|ä9¦máX•ýª$Hødµ×•òºÖ¬_úpD d$øJÞ`)i¨àÉCª'p£¦º` ¯a5h!QyŠFbåææú‚ñ´6ŸFêçJ®Ë/þÿ°=×W)BÙô'K©Gÿãü¥:ŠðƒÚ&ÛY.[K‹œaó¾¯CóUèyúç@ž†b`Âã…àÙE*H3«kdÂ(IbLóÐ$„GÁÕ§9ø&cÐé©Í¼^+êØ,ŠËÀÄ$lÓ±­†Ö™ è8(ây‰¾)Mƒgœ´'y”YBU‘ÍÉÕ²:Vägl:ƒ£hFoÔ#u„]E -Ç«#ŸÖª¼¨Šh„4>ý1èKßNG/)eESÍÏœþð[‡>ùôãÅÄ2éÖD266iä2Øõ:Žc²^ßqÚÕøvÔ‰ )wlŤƘ^¯ô/í81l/ 7×NȾ»7«FzJ£í‡†[¾q|ôè¯Ø¤T|yQUÝ?;5ÑûÍáVó”Tìüð/@.§ŸªK¢nËàºiäÄõNóP›u¨ý»#]Õƒå}Í•ý­ÕCvóp›uÙÓa쨌öœTZ÷Ÿ*f³q´³¸ŒÅÒñ¼À²C³Y†Œ…à9J=ˆ¯ä ௃ÐEo¸ ^jdcjîrÇüÅöŸ]ê|÷r×ì…æ^Û™_ÛŸ¥e(FÉ Y04®JôŒîý¶£»Ù7I¶ž¾ ¹Ïê –Hr‰ sY®p*eNÔHÀÒë3»V(Ògó¾ %W«}[÷y2Àqwÿþ} åd2µ˜XZÇ™›}"U¸{ °ê´áüá·I³ËÜX_ ÇwŸ×ˆÅƒ$ðWx"çž~ͰˠåE\0Q®oÞˆ=›é€H=¸/n&ÖÒÒR’¬oT«µŒ¡(l­‰K÷óV:üV©·Ä(ïõY0Ëf‰ºÍ£1l‡ Mœ‚ ºåøÖ®¼ âGAŠÌBM†v;Ô5@ÞVkb´èÑÈ‹ŠŠ?N¨©•Á˜L˹±á ‹(by,†Õfæg!HjF\‡û[lŽ’ÁÖŠèú¥´«bÜU<ØŽ»'¯÷TFí¨;÷?\\™ÐRê'©ÄÙ>¢åÍë-oE›OwË7®'È·ÉE5á¹5Z1Ò½^í!Øsb“ŽEšUc]x³•Ãíßµ#QN÷µžéo¯î95ê°t˜•F]Å!nGËPY¼ <Í0˜¼9¬ Á¾{£`S½ ¤ ¹ ý ¼rÝFÛà¥F6¦~Úä¼yµg´¾¥©´²('ÏD18Þñ!ˆÅ¾ážÕåéò,»‹»Ž_<éF‡„,½r±+h–Bå^ŸÅ%[nsj)²’àXþRþÛZ5ò]&Ï ‚´z£@FÙ2hñTâÅóð¿%qpÆøÇ'yqEÎÄŠßÚYä-u -žåÇ¿ãäÙ›ÅCH*œµÏ"ED:½rc£A?;3“\^Æ–/,,àEãÉIJ’,q<<•H¯Åâ‹wï¾oЉ,Më9._Ìk<|"™øê5“ßbµvz­®k6%Xìl*n0ñ™4Ke ÌѼí!™ Áàq©~YUÜj`Yш,‘“ @¼žÏM‚o$7~•PzŸø{Õ¢ú|ªÛ•þPúS—½î{u´†¡)#ÏcŸ‘/MŸ?þÁƒéTM=›ª/·ÿ¸=eÛÓÇìöíÛ………&ò€ £Íå˜-Œ 5æí H „æ!0a’À?N$à›$üðMƒ< Þ9ðÏA(–Îë±Õ)2 ža<1¸6 =’&£ÐÈf0” )<mpm”[ Å 0›u¦oeeFj>Ž¢I$ÀWð±J¢h`z- e{ÆEÇÎè*_3ꘗh¢BGlІýoV-ßû2ƒßF<°WWá3ƒ3SÞÑÝnÅn—Pe›ìæB?´ÏøÞëãÓÃö¤k½ªÓÄ€mj°~ÒY›ä’ƒ\¼ʽ|söŠý©‚9²êR>wvÂo›t5&û¹TØ`ö7×À!šïןœ_¯Î@¼=‰AbN @jÒƒµ©.íj˜rÚ“ÃÀ€P]Ú½?Ñ_•àç†[&Gþ&iðõæzƒÉ`Ôé¶R–¥,½ ¿û$adˆ×v–¯Eþ3(æ@JÛó¶Á7y>qñT_ïµû+¶áŠ@‘KÓÀhZa·5¼Tí>Ò¥Ø}.¨˜E0FŒ¡L‹¼/Ô8"p^(ˆŠ- q#D8¬h 1f“‹Õˆî5ÒÀÕæ!ùL6§WÊÿͲ–ϳüÕ=’ÖAà|B³t!q£iüGD-!øƒà±¾ƒûØ—Me PD§ßÀÐÔâü¾žAá+fq¾(¾ÿx¾“/d?íð|}ía=Cѱ±Lo«´ˆühÄ šG°F¬â³ú ͤڑq[¨ýÐiRGëMTQê±ðjh$'ªI‚j8œ•«Òˆ*ú‹Öˆ,a@ÀvH[‡%I.È‹>L” _»D$/Џ±ŒÅ’"¿èì=¼};ðÓ—ù‡G£.>å>œruMÿtï‹[Ÿýº6\¨N~~z[“t›“ƒü´»aò}Kr®bžX7M™“C Sî¦éQ{Ôõí¦jb3LsÉr²]Në·Qì‚f í0üA£· I§ÒŽ”iCÑ.íÆ%[îBâ»xg´Ig‘ hiG­|U:Q¼ÿé@áÜ^êxÞÆxQ4rÓá¹Ñƒ¶¡ó?éº?õx®v¹¯vÂþë½Þ›½^Ø­Ë}­Ú ÞèmוNçåþáØÉ¶cûªvèM& ê?EA¥cIŠÇ‚`ݫԮ·_µxúÃ6?'€1DÎ[¬.Рɀ–M a®=Œ³kN«É…iÉz-ùG©»³­Ý„ AÀü‘ß[ç·¹ãMb¨v$Þ*…xOÔŒ5„¢|0Âûe«_â}°°Eˆ7†Ç¸ˆÀù¤ÖàñªÖ­Ì&9Œ`Yjë¥K— ù*“YUWÿ¹ª>><ç¼sçdHÖ@ÁÍ*׺jÏM^@`¸.çD‰óÈ8JæCa‹ý„ûk ø­C‘&!ÈùÚÞ:UAQLéV]©›kÕ,¡QAT%¬J’NȪT¥^‡16ò¡ "sá?DU’µÔT´^ü5"çBŠð@œ·Zõ$MÂkʤ/7úý»÷Þ¼v²ëýür¶p¿Öp.TÛŠ/OàJa”ðäïÅX4šâå©ÿ㳪HþöðÁ¹ö® ’,gi–ÐhÒDè¶ÁËôÊ›¨ãR&2ƒB3(:»n‰Íkå~³!|ƒÄzÂDS†)©®GÑģЛAÌ!e7ŽÎ–iÙÊX‚DǰOä…g_bûAÑüQ¤‘<ŽäòÄð‰ÏkÂÑÈ kÒ€=p\„{5‹Ä$ÓHšÓ”:šGâ>³’F§ß+y½ž w2:=Á0„6d%A †½{÷Þ¾}ûÉPý[YYQŸ ®#:¢Üd$¢ü;;Z‚}¶„§fjØ–ææÄ€%5œ¨Ÿ8g™p¶¤‡‹­æM`ƒIgí¤“K¹mq§ó|äK^ͯærùªú³Ï?ûãßÿ I^’ŸßýmàÆü·>þâáW8{f²ð|\þÝ/ONÖO¹ì ÏÕ»Ÿ®¨™‡jæ/ù³Ró”·1þ¾yÂÝ<ヮŽöð)h.pZ/Æ¡nÜÙœùAÒBt<Á³»LxÞK’,EéµTÆÒe&vƒ‰.­ßº›J$Ð…“ãÉ Nüì¥t ¥ )gÑxŠõh-A í¸e¤ )Ý8ž?3^\×ò±c裞aˆ;†®8ÜCz½àÉåv'8¤€–Ÿv ]k¢x>ìv¹ø£‡víÙH³ÀQI0õÔÈB~ eìËÆ]G^9x®Þ1b›|a~TjðAiSl‚bûÿR¢œ2èIÒ@Õ‡ª ãÜ‹uŸY¯|ž×’Íd`ýé¯nÎõ4`‚­dv¹ù~‰·†³Wà<@¯¸U‚¿![ü7 !sA‰ „ZüÇ÷µn'¶”Ôfišühq±@‘)”OÍdÿÛ~æžP¤°gyyÙn·ët¥›M)ÓvbÓ{uAÞƒ¦˜…x« [GÁH¢%¶ŠQ{w›‰YbO±ÊíÕmF†¶æ%olÞ $P…€©Št?àÉ(5*¨á€&Aü* È!‡ñZ”pc K(¨ŠA¼ˆÅkÎ'‡ É’_ï±MÜwÀR¥H‘,N'ëtÖYv,Û j馦>6¤1ëÈÉã„4å•òp !ÁNü~žg;/;Og ¯Z£cÀ¶J›ª¢®H*-šX™ÐZ #Ž}·ïï uãP*Ôq:~¹üüûýîw¿û~??ÜE¬ÿ3«Ý¿©RA“Zü¥B ›ÍºÍŸ^¾”„»óó’HaZóù¹,–dîÞ¬Â,ú2Å«ïûr䥥UX]…Ç—h-æ±ßz^«')™hGÊXìlš]¶56#.b (þêƒÜ=ºhœ?:…‚iÜ º©LN4‹ªÞĈAñiäê“:=Š¢Ó(víh)Zöbõ¨v' ã>ªýXÁ9 Ó¸ÀK7yé~ô°d•üß ä–X!<‰‚£(2Œc(uÒ¸>ˆ%ì™Áþéñ>W»]¦}‰¦5$¥€D WÐKäT IhYÕË×d2™Â„‹"/°…2€ÄlnFX3Œ IÕÚåMÁ®í#ÞMñÎú´»v̾q¨®è ý[†­ÍS=Æ‘Þê”XÒ<ä:wùO8~aœç>¹ymwŠ›¸xô.Â8óÙYøND!XÊãÅñ·[×÷økRÖªñÞØ©é;P /á¯×¯ûèüÔÅ3ÜtrWÊÛ«ØÆxI tgZ$Šàñ÷Ü2ÒcµW¦z1d­qm÷5 Ø~¶Ë¨)_*£eƒJhZIP,I©ä œ•³,ñòJÙÎj0£D¶G_ âöaiÄ̸<Њ À…÷#n/ Ib‰´Hù}?vËÓgÆ3¡À\A´; y¯ÃqªÓwNì·€C pæ€[ÅÜ×£½ƒ»;ßY_Q®Ö« G*ö¤´ZÁŸVT ¡|E³v×ë[ gr…êÝœÑ2¸À!q#¯ „k݃ó»ÖÈKšTÃ2r†¡þyó&pd>/Ì 9q‘Ž{É]2I~~¾Ö`PAØ&H ÉnyÕ4¹¢ Èü0º!¿Ã$@9^ˆ¸DM(jôM¯É¾m]ÓRB¯!UJŠah¹^¯ýý…‹Òçÿ _,t÷ðÆê1G{/âZ¸zõꪕ+I‚FªIf ©m«Ø09á5kìÁgÈè ƒà%Îà†›Q£w *8Vߪ ºíËÕËœ° Q“¬kÝšÏ=1}, kÞox·èõˆ¿a6¼uø¨è÷b„„91‰a@…_ÃK‘€æ|n‰=~ÑïÆ½ð‰ÛžÀ¥öΆ¬ Y¥QP^Ÿ0±jJá²Ùo}ý <û×·oãÌ ó‘ÅqwAk ÇOò÷ô€Õ[ ÈGøãÚÕ«I†×1òRØYÈEl)ª«CŽ8ŠŽ¢)œ¦!§Qx a±4G¼än £"‘AMÍ@"-M¯3`ù„"Ç$ÆÀÔ9†xÅâ‡P0Š\!d‹¢À(ŠM?ºýaħ±aÂGpS‘cxð¡ÄOá¦àĺ4òÁ53X,\qãÒØ$ŠpÒ}ˆ¨ÍQôz5¡Ð«!÷ÑÅJ‚€(H©HB^ë®nÓÆ©©©[xZŶB¼ÿ Þ¿ ÚÎùsP†•×ÑÖ^ªTkärØß‘ J]¾lgàPã„ Q™²&U#–ÊdWý°µdò¸ }¸§b «)í1D:.œ¼!ÜÅ£™þ!ü«;Ãmo§Ã¾ütN˜a€YpöÆ\nîêŽÃÛҾʡC†d÷Û·îf³B¯x¼Y1ÿo\5wþ‹K]i~û³~¸Õ˜öTv‡zK#ÛGm )KU²»b´·b¾iĺ1i­Hö“½;SNCç®ç_YE³rx)†Õë 3I¸Òô2µéG¨­ñmˆß‹úA&-(¸q{¤;­$| VJTröÉ^¬‘XËÓ6Ƴ¢‘SN0˜ä}sÏéVÛ™v\¡|¶Íqî€ût»ã˜Ù:ÝÖóËöäžN_cóú_^B³°÷T*•Œ‚“(¤Q!×Qª×ÊÖìX×Ô[Ó¬u‡ªü|E7¢U^|Bv6úÁ œÑ ú»ÖÈOW­ÓÑj­ ¦ÄŽ÷ƒ¢ð?ò“‹ ~ø›srŠbE îV­°pµ^PG¢.ñA£‹7aŠÀœôÃÑÆ@wuǶŸ4ªV+WëX5-§JKu—/ÿEÀ@ÌfçzY\Op,äÖBT\höÌû¿†Ñ²,]R¢„|­“©VµœE<‘ÚC5pH(‡ ž„ÁÇW{BuÞw64—)õá—Q)”4S¼~™ö¬¹5¹ˆÈ…Å€O ú16àlp>Œh— QNˆòÿ|È›ãÜçÃ^1ä{l Í°öçv1è.1àx0OH‡omZ«ce,¡(QÒRDRR”^­IIsŠcí|>÷þ ? ˜±oùäÿò(,ŒÙÙY˜kW¿0T`k˜b--#ˆ"† B_ôšÙBÈ7„†>@Ü4 Œ¡ø8ŠO nÿ™øÕ¢i$:†BSX (ôeP§…VéW0²âÒUèP¥ ¯£(V™DaÀ°a—ã3¾ Ê`Zûæïo÷9šFœ5HÞ<ì6XK#ƃ¦”Å8bT%- ´š”žÈ”<ʪ¶5MrþÎ¥^¥”4KÓ°ÛÒ(TeŒJƒw%4 [(’^©“m}ã¹î²P;Šu`ðfLŽX+â÷¡(œû1B gÔŒ+<}f<9Þa?ù®r¶Õ~®Åö¡ÙöÛ6ÇïÞu6÷žjé=yÀy´Ën6¿õã åj† ´x@*þC~Æ6‘ÝR$$K–¬Ñh4šÑX>”“„õ®( îŠ ,Ô,8q|$d , „p„øˆãk<3¾;‰ãÜÄÀR–/»­ªªʪ¶{|¨–ª-­ºÒR(W°§ÿg£© Zi=YÏ#û½73oþÿßc“TØž Ti2l>ôæÞž&‡ßæò›Ýk°×Ž5ˆ½–HŸ-Ük"’Å/YÀ!>ÉæÙÕ4IqÆd2Áësûî½{òì€ðÜÇS « ß¿{oÕòË14©%˜†¥[ùí=Bƒ?i—ü&—Ðìl^Ð &X}ÀøM©×°,’$T••å_~ùy±J-¦¯s†"Ïg’™0Ÿ32Á9hZÎår­RQ š&ªí|Uùö•VŸÙ-Ù±¦Xï¶y£ÖPÄ[ ;ÜÛZµëkÔ,Ch9JMJ–†«.W*ëëêâöí8Õ™ôÊ|l€ùoðYðÉaŸñ?²„\N²À y箑"`"B^ô Êqñ!L$ñy¯[N$îúù„Ñh`HIpZ lŠ#*…ië–ßÿöw°à^ÜzZ§3÷çUÐÞNùæï:Ou°4 S¦Z¥ÐÃfuhÑѱv”Eþ, _@Þ,ŠM¡$dí1E± Hñ/J#Ña$äpÆO HÎ[³¥’T*HZµÊˆœ<†°€"‰³H½L¡Ø9L‘Ð$F…˜CÒг§/~Ž!iÿ¦‹f†0YTÖ #qÏ øËbŠ„‹ýDõN"_/jó*—¬Té* ¥JO)«ñøÕe´êš·6sS·nÞ†7í~ßYÈtáq!0³µJ™ 6sþÞ=Lã»÷‹ÅÂÃü‰ëh\Ú@h`Õ,mÐZŽïÙ—òÚÓnK¦Û’qY;­é޹fóæL7¤o[ÆeMwoNG>þêÊo¾øÔÖßeOwµ º,YÏú§}BØÙÛûh´çâÐþ´ÏïltÛ'ƒ¶´»çüÀmùAñõ)|ö«Ž±äDO`²ÿ«¿_–ó€ü;òÃ3W~µ+ã8™3NSªcÇPϋ҈eÐaÍ8›‹ë‡op¾Ýï€fq™²®Ÿgº6¤N›»÷Ž„Þ»Ö½ßR«Ó€IxLj†Ór¦!…-¤8Ž h K®4(ßÝŠ¼ûQì(Hä †G¼Ë¾–ˆ)^<ø}ãUÑÈ…6×Å6÷'Ç<¿.6X< äâaÇù“žÔ{mm›Íª HFO5ñË ašÆ—ÌVPºÅjƒy™±Ãz8dóÍÞìlDÌþPChöE›¥È¶@ÌŠˆVŸhõâÌÞ—­õôæu–bÊyz­öâÔyˆ½wŸÎ>ÿÏñàQTÉÓ=6wfŠ„MN‘°p•û6ða ‹~HÖ`Èì‹4;% ˆqá¦jJÏ(AsÜÏÚÚšE â(‚Ç«Y¥ôŸ$O&ÙÇZqàá±,§cHRW­bË íæê{×îöX;…o¸Ålö8-§¿Õº¦f…©*'Ô:¼d•þ@(5Á°ZÈM×®§Èe{`íºóMÖ+­‡¿ÓÉd!)„²eA’C¢d>( <‹èÇ ™«FàBk'"â~À#½rÈÇ K@ièGã×NœîúÉ–TÀr¡Ì$54¹HÛ¹çÚŸ¾Î?º-ùYuë—±?°_`AN÷¥^«­ƒw™cXˆÖPHª(}™ú5´c?Š÷¡HÅs8ÝK9”†l2¬C±³(>…"#ˆ|aÁ¥¢F"€Ÿñ¢ÆÑ!ÅÖ))^+¢b>ZnDb Ä?Š©HL pÔ?…„â Ï_ÃÃB' "q…Æ¿Ÿ*¶qEqhãx ”Æ'*á’+Xf²+tuØä€[5¥¡U•r«=¸÷ȧüúNñ~BËç wdù6€_ÆÜ}r#ÁË;Ë$3çK@K©ÿà6IÀëƒR2 GP*…B[¥]¿Ûº§¯ÇšrmNžjóBºŸk6NXûðGkÖÙ>µc¨{G¿û}®úA¥Îy‡º7ÄNÚ2ݶ”ÞvÚæÁNSÖaì;½+áþówÿÄÑéáô·…ÛíãÑã¼ “t¶g„«ÿþj0Øç7þöNŸÛ˜ì°dÝ€{ïœÕô¬ÒØšr”XÕ@p5öu¥6vnIu€Rvg=-)§µ·Ó —9à4øV;߫޴œÖRŒJ©'¨ ’©@yB3‚ÒP S¥'~º¸ì€E—yß/“Ž¢èQþ‰û‹D9ò}ãÒÈGǺÁuâ¯'½gN¸ãûÛÜoïYU>ßÀ¨A’Z‚„«ƒ…–%Y´®'´jÖ´mÜhè×»f¯` FmBÜ*D|ñÆ@²IÛx½Ÿ±ó‚µ'Ðèâ-n È$ÞÈ¿l„­nÛR“–V³,¥¦¨UÖÞüöƃ—e@#ùb´ÀRŠ!Ðo²Ù9šå ü2ýÂ.s»dñ÷6GÅzÔÌ Àæi¯?ºm逭$´j;µ~ýºkùk1šJHx!¥x5ëÌÿ~ÌĽ™ ÷dT„ãÒ¥Kó«jXDÁ@>ÒêùLåaµ~ÑÚŠe«Ë¸ZxÜzF´o¨9ýF]Ý/Ï}˜ÈhõåzŽUáMÂrœ’Ų!8ø)¡£ÉÅ]_]ѾbÅ„ÙþÙ‘“×½¡Iá;áhAŠÈBXæy™÷cBHÁ¹j¤ x帄5âï‘EA‡1opÀ!¶ ïËG„[¢øEk«Q¯«V)áÑ$PŠ+§˜×u•/\¿~ý‰›<›%?ÔãòåË›6¾I$8  =4Ôð.ê‘Æ å?‰Ä1Ë"1‹“8dêhÉ'S8¹ ^˜F&ðÈ1@E?V*NA¶C:¦FG–Õ’óhu ŠÇ‘8Œœˆ]@]nÑÏæ–#1…ç?òl€C`Š ƒVºŠ³(ò!ž f‰AFñ!ÆÏ¢À  8¸ë™J:(' ¬¥ÂWò)–xn&I—ô˜éq&”)@ žSÊõákÐ&ŽÃšø©°x Çerj˜–…'0¬†àã,+è–g¿øüKºÚ)elt$æç¾Á3 È ¥gÙ×8ì€W¦QÇ€„dOdz%9úæUožómÙ¢xýŠ? ø<3Ej¾v@âíTü^Åçòy'>˜ŒÐa1¦»] HÚ¿Ð2æK$*¶üˆ®ŸƒC‚ÁŒ<¯ÎÍÍz´?µãßÙçÿ¥’TR~uÕûT!ÿò·/j5“ɧ®8r¡jŽ âÉJ‰X½ÏTsçq:Aº ë)9œ"ÇH0à8qDÂÇHø(•õ@ª}¶Å{„ì63Ú%¸)Yl騣ŸøÏ‘]„¬ù"3—ÑŠsV•“P‚Î$~@ê}” <ƒ”.B3_O7žg)ºܯõŒVƒüb \œaDQt»Ý###Ê„?‹åŸ)%yùòåE‹ñ©dAÏSvÌ[›÷»¥"f¯ßQÓg/î:PÞo/7Dö—ƒ ú­UÑ–ÙRÿ]=ÖMýÖ‚£ratoë×8@d’’¿¿õ©1b]wĺnÐ^ký ÛöÇÏ?¥4’LÞNŽnI´oŠlEÑ–ò¨y¦óJ19ý„•õÚ °©Ï Â)‰›a C¯ {$t VGÛ)Œ¡í:à¿ œil¦PC){Ihäd“õÔ^ÛÇ0“|Ödjjƒa–Ë&ž° )ës¶s{ígL2*xÒÊ^ûÙ&Û©Ë™FëSËESë“ù7–_7ÈWê-C&ù¢ÉÖ½}ßžÕR~VÎ|^Ðqj¨î–ƒ*ÍåNHÏ óUº¥ÜâÂÅkv­Ü2[´à6X]e¿Á,s„¤ö.ƒ;¸Ñï+öF‹uI¡ ·W:°é1x:ŠœeþOQâ T¹v¼]3)!¨9hÿ»k×|ù÷;“TEi’‚›39>†D$eó—§êZ’Óáâ;‚‰ßí4‚ÇrZF½TŸóó‚m-•ûêJw-_ÿ=M¶N¥Yêù<Ï®Y³rllìɘ6 /º<5 > 16;;Μ6QÐR áhî€oAÑjµÕÕÕW¯^ý×qð 7n܈F£EEE×àäTìŸ0 ¥´ªF•e_Õ¨ -ô¾WtÃl›ðw+N%èMºlJÀ Ò˜ ¸”@HqŸT¾Õ9”pè³6kóÛy 9Ð GF9QäµIº~íO Nv’Rádòab;}ÖãS“€·—ŽQî)ôC¦Rþ}ï›·ß3GCQxòC0Çè2¸Œ¥o‘ºÄ!®Ä³Õùw`@ð(ñ%Î^J ]§Iä4ñ žÓÄ}„ì³ÏýY%qúHôÌìÑÈ1â ./ÙZûÊš­$|œ‡I‰‘ç³TÃè¸Ù¤ÜDœqÖ=Hœ‘Wr~Ì€±ÁÙ<ŸÉ0•••7oÞĦŽ?˜ÞäÁ$ÊH<<<¼ {VÀfdÌ4 ›1oùâ*ïÁª„cCÏÁÒ„\7—Fš«úle±–‚ð^0Élш!ÚZØ'¯‰î¯IX¯ß¹ub îD¯ÄÄÔÈĘíd\ŠZ ·n‰9 öÜ»=À…I~òÙŸ*…1 ~ ©îµ=ÇÔÆ~8$%i2¡LmÁÇ‚@*ryÜ+‹™±Èg BQ$aÅA#†žÖʸ­&n7ö˜·GkM›³ßù‰#²jr‡ÜIÇp b“F2Aê¥b€é,³l1/­&–mÄù!ñ7’‰„(o€LÀ$Ý&n \äðî!žÝÄ‹WOrȤî!¢P˜yô ©Õž/ \®·^ª“/5Pü€¡2T/Ã({4ÚÎ7Ù/¦º]¨—Ï×Y.ÖY>®· 1M,Cu–Ku–_ÖÉ¿mlûUS†n š#õ-ŽM;Œ+VåŠY‹v!%CèǦ2FÈ$nŸžÓŠŒÅêó²–mÍ«l•š:+¬®rÛlÑ`#Ré ·‡K;`©=\íwW¸1K×î@¤±»³ÚÑ^Ü,qD7…$3? ¹Å¶6£EÊ-Dn“è?³ú­•w¿ºCµfbJy(:Te¾•1Òl0ª¤Ñó»€$©T+!»-«ž¯Ö/`2dè_eô ¹yš¹Ü|µ˜©ÑÁ׫Œ÷î"”=‰=ÿ™.é@JÁ,UîÞ½ûQo¿TX—Æ µjA Çfy£¡<ߺukz…Øô¯¦<]Eüì‡wïÜ•ÿfž¨":¯´8‘Õˆ€–åX•^Íf©æ¾Á1ÿ ¾lc›ºÎ8~¤H•"Y²¬«««{u-Û‘6–FYa´+¥c„”·;N ¤i2‚Ç!@BüîØñÛµ¯c‚ã8N !"¼h:´¶c°Ž¶}â[×V݇ˆØwϱ±Ò-›[£GWçÜ{Þï9Ïÿ÷4.ÿþ„¾%n—àé.ÁíÀ|â÷ŒFúù„«GàƒBhà†þà¾e+HÄ$K(Ä KI)ÃR·Ãú÷„llšûé©ìba£ —˜þZtçëK“ª)!?±ø[%´¸˜ Še²b…HLÊ¢·~ŽQÇtÁ?Sûb(0‚P'ŽÇ‘?à Ü1䡾KмHÕ(“bèpG;ꋎFŽ£ð)<޼£¨'Žú/ ‹·hMµ\&f©b)!¦µv!oùN££ã(xÏ!î4ò£ØòÃmç;.0OhÕ4ËD¬œ’€6QŒ´ÏϧséÉ…‹%ÿ{Êö<ëpRù‹yç÷+++•¬Œ‰å™šY,×ú…vØž•Ú­ó¶VgM̸9ÒY(Y7bX7d¨‹Úâ×'†dPä/Ÿ}œ!áÓ©{C¿½ä¹8z콋w“3O‘|º|²1bÓ [¶ŒXêÃÆùŽ ì(KSà¶Ï=€CÀ0„Ãz¢æ¯ šˆz€† 1›ú ³@²öhWÍ ¥i¤·1d®Ò7-Ù°J^¡¢2’o¥ %ÖЬTB*ªŒb% ŠeìšWˆ¦Ôõ3äÝ×#¾3À ¯ÃìáÏs²/ :Äé0u„2ô’«–ÿúÜÐÈ•ûàŠ „´€(&Ø/°u\Ô›aD@”Ëz+Ô|¿£çÝv[`ZMíÖ+¿>Ð ãz#¿K¯ß¤Ý°tÅ"V^BP°Ï%$èC1l6,€` ‚¦h’–RÁ®’®l|y«A}ȽÝîÖÚ<µö@+¤õŠFBµ~ÿ&WÇ«Ý~m¯µÎÄíñýùÒŸ’_$pù…Äç‰÷£—]ußfsê̳ÿ#ZΣ²ó nSmצEU eHÈ’yQY>qömˆÓÓÂLRH¥…é9A/xï,„Ìú‡<¤æz¡g;aòþäO›š ‰€„”¥Œ¢„”)i-&”‘‚îdÀÇaJ=Ýá7F#YÉ.vîËl1‘HÌL¾ø”+Æ= fs?MMMeI,9•øèÆ£‘ÁÖ½-•?Y«·NPÀ9n4I°”¸‡!+Hñþ×Wßáû„^7fÈÄ.ðB0—Cp‚×—¶;²/<Úܼ¶”…8.‚ˆ D GT…B98<”†“‘RöÈ/ 6á?øýÿwé×>ܤRÃ>ƒv—$–HIX’$‹ªkÝú@|DZvó§Pß™gªsÀ#Žñ#0†ësãX¯Œ¡`°°e«RQÆ`—R¤|ÙŒFÂÇ‘3‚¸Äáé#/¼ZU"—E hJ¼t%²º{ÓŒt9ƒ˜" è>ü0½QäFþãó×=Œz¸bù’E$SAK Œ99vj:sò„0Kã©ÞÙ<ý>õFº?9¹£±IaŽDQÅHd ¤+ÛÞlIeJçÄt.„ü«OxJ»¿<¥r·Óíî]´¨\"Æ„„ İûPÔhÔ×®þ.‡"ßz|yÊÉ¿}™þòkÏnNžgæVë!¿@ÈÌÌäó÷îݽúÁ{=kÕê5 þ-£d ÅÊÄD©Tº””\oï8^ðô |¯ÀÙ F#@8œOàyÃLÏ„×u×Õã®ÞPÎâIp5XY)Á.$˜­[óáõßç&Ÿz®>w)=“hÒ6"BÎÊi±DIÈ^ ÊŠ~¸¶¢Þ~ăˆŸE~ ‹Qä=†|'Ÿ©ÎÁŒÄûN!=¨ü↑•GU2JYn…ß.“¿„vïGÁ¡gF膊ÝíJþm²XF(į©Å“ñžÁœNrÙHÓ„lÔ?ŠÁÉLjã™Ï{Üq´KWÂ.’"нÙÔ§<™Êö ´?9?p½àe¼M.8†S8“L:Ì&%ÃÊRÁ"Á¥^kRo to‹÷®šÞ8Ò¹}ÐÔÃ!Är öz“ÂôÕ¿Ý6‡BÆúˆA5ˆ à0`¾ãfñ (,G&ÆšCM?7 ª#Æê˜lcÔôT3· ˜LCÌÖxäð¶p7°Í†ÁîªÁÃÕ1“zWP8jø®Ê®]Ë5UòÅe–"šfY)!=—c¡Ç¾¼9‘­L*¡)æ;¥ò5+©&5ê܉Ü-ˆ×¡q{1côµ¡  H 6(†ôˆoC~ݬåbßóB#çÚÍ¿l·€“\Ô™Þi3¿­ÃÔq¥Õœ(^Ô›Ïï·œí°œî°Œî7š÷èªT/ÿ#/ƒÐfŠ^HÓ°ŸbÖ“RbŒ×e‰XZA•­.µùÇ u‡³ÞìU›¹³OÁƒ×ºu.0È´žBшGëtjmÎŽkã¤ï¦²">5… 23ÂÌ£S‰Ïo}j«7ZÌ»•Нö6c 1Õv©WT+%r–a‹E¢R_&°M\iR$K‘¬Ñh4²5–+Ç’Òd[B Ýr Ê ıã$®nH“rÄG|$N|9lljs°)„Ce¡-‹„Ø.aÛŠªÚíÒtÛ"Zq–Äñ1ûÍLb¥”TÖêÓ§ÑÌó{ß›7~ß÷ÿ}B1…CHa ïî»zeŒ‰ªp˜Sùé{FtB)\Ϭù'.»²îß¿öÖÔU*¶Ë·Xì¦Ï¯Æz`.ü½’e °â^Æ Y›ÍO‘Ww¹…èTöj}Zy_ ó†-‹LÚR¯ªÚ¯+ïÑ(¼-e½†*¿±¬­iulþªœTÐLœO‚lRE ¥•FS“qŠR¨¥„É™¼Ÿ&\µX\°5–#U 2½ xÀ‚ ðÉ[¨ X¥ž1÷Û Ÿ«¸÷#Oï…F6Î5èÀ€CÎ7è/4µ^h2žß¯;Ó ;ݨ?õ®~¸AÝYW°°¼jùÚ‚ìWÄ„^†9®„Œ"àÒ8$X!ÓII0 tùUqöúìUõëöjd-z[Y«Cn씵ûJ,>™Õ¥Mo³Ë[mŠ6«¢ÕRb4—m¥¦DшQ©» Ñ÷B¿wùê©K¡»!‘2š7Aë+Zœ²Ž9/¡dðÉ]l q›]•fC¹fçÕR2MLJ„B!Fb@#!& °¥¯,êh3}ò÷9`‰"ÆÝÏÈÿSΉ²r ‘ sáP$ŠÒ Ó¡É(ÜÄ8R™ª°ÂNé~o~Ñ/¾hVmoÞ¼)—ËI¶‰D"¸b¶dÉ’±±±'f=µ6ü1xpžcqJáДTlvƒ™ë¿¿¼UµmUÃ%”j Éo\·æ±ÛC›m‰¢‘ Gí°1@ã´Ñ.íì Ûvô´ÓDÛíŸ54åg¤Š » (”< ¹ãY/,°v˜¿¿óÝsäÆÿ§Á©ƒ7?¼ï€“BŒÇÇæ­Üˆ¬nä9ƒl#Èìc„»k„Q|ë²ÏN<ÌFÏ(2u¢Ò^F¶”ÉY€OJ³Ñ=rô#ï²ø™1‰¢÷Y–Ü€CG‘i5µ`¸TŒ“É© ‘¡ ùÿˆT6¤¬á S0‘Ô™G¦#E-2y‘ý(²A® rÁ¾æN#î‘ä¢jú4’ D)¹p‘Ë ôô!çÈZ(Jì_öD*˜Š£È AIË_¿~}~zäóDL€-,X]km® ¶mî:(êE# Ý#®¯_¹yp©vˆoÔlènÚ>l¬êÖt´ž ˜Ï©ê5×È|-@ƒ†bß!Ί|Íϰ.,Ía ‡"`[º›ëº´5]š=-µ~}µ¯¥¼[ ðP˜•v*û `રGÅ8é7”t`mQ€Ù§QúÔ@#}Àrºí½ú:¯®¶[»Í«)÷kŠš AmWó{Í®¥Šõ/½œ!Åù¢džÇἉø8œÆ”±Ž‘PÐdJø¯gñ·¬HÚSˆZj‘­Yßb®À'®ý ‡04R<‰B‘_žFÀÞÑsà1Ú¤Ú¯òîzǹýÍ·7ʪVäæ¾¸0G(IÇÈŒ$|J"Tà ¤È!Œ`úÉ1.Y@f¾‘¾bûëJuþ>‹\í*3Xå&—Ò Âm+nuËL=Jk·Òâ,ju)Mv¹Ñ*3“™Ø0,Q4â¯ï¤ÿ†âíþA£'îŽÿÙwºM©å ŠæQç‰MF£¡;a\ã)œ³k©Áª0¾:Km…ÕRl4霕æÃ²ÆYë2ñT‚ÇO•H@r`ÃHÃÅ”èÕœE{wï9îÇ÷pXO;ñ:èçÉá‡èC“‘»·ï~råÓ«]¾|é¯W.ßþúvxb2ŽÎ œä–çÅ!3 £££ð5 ˉ…KÁ¤~Hw8<ž8q‚ûããã3gÑ?¦´žº)ø¦0¤ÇÖz0nœŽ= ‡À)ØŸÎ~‘™ kA, (Žó¬Yst%ŠFh»•[{Ôi;ÚCFÚn¦öÅ@Ûm´QO;\´«³W¡ÈP qßADQüdþÊå+>8s6ÆÒñ¯¬Eà›Ó_Ýú&-+£ …òùâ,TSìÝÈ3ˆ<¬dÛ‘kôuœU4‰ï3sÝÈ3€\GçN#Ç’ÊkA`Ò1Uþ`ëú>m^oóæÍŸV4lê>$ïSË*EŸº´A‹g  Ž@,ñi”ý@‘¥ú]ËwlY\•÷rynvEîo«ó–í•mÒî®ñÌê¿Ä«Vö¶€9{-ôk6{UŽڒ€z”>íV_Ke « ð_âË5¶‰ìŠãWBBBŠdF£ÑŒÆ²%H!ì*Ë#!±ã‰ã„¦áѲ!!Mš‡ß‰3ã±ÇÇ8á%¼»í®úawµÒªV궈ªZTU»l¥]µ,å•8žžkCJ?€ŠÀ:ººž_ß{æœóÿí1|«r ŸegÜRyÆfˆ÷G{¢}ðŒ!f+?íć õ–öÚh,_ùN+Ј:e˜“€ð’T6EgQt&¢ âK«) * VÁRòUôÞUÓ>ÔYœ‡øÁ¡Èk§‘øáN¡¶¹ã}ýþâ­;òÖ®ÕfeZ@™" 88M¥ZY†!¡|ÒOÙcÞ9ieYµ<__Ñú~ÓPM\k—ùA?/5²‡—e£è7ƒ7%âC>£ÓVã ‡B¼,hôÀÝ” Aƒ¸P4â6ÙÿtùÊ,(Qú¯ŸýÅË;NèåpU(Rï¿ä=·@¸?½ð™`rÄ*½¯º¾—·È&·¯Ê.ë=#&¿¬÷… ƒ"oëÙ÷ÁîÂR.ƒÒÒœŽÖ¨I5qD§Ö°À' «¯¬<5»yófZ…ç‹ÃËùáßo‡G‡wíØ¥¡8ŽàÔ$â a“âÂb{ŸýŸß}ç‚:6—å·õIcóršœžž†¦( 'TŠ@`’N.áÉ|ù}Fsó–¾¢ü/œÌOþë´™$¼Ù¹'3©»|IefF™K“»5ûÝE5ý»Ú¼z«dp,E¼ÈD½;h½ õg„÷T ý"/÷ºGkƒþ ÷ˆ) lÜ*ç°q0À{#¾ä=evöÉŒòèÁÜlä¨ ×À ÎÓÖè݂ěùyöëO¿¾}ã__N=æx&">(ñ¢`tÃRQÓ+Ó‘Ï(ˆ¼Ïoò«ôíí8Pl.Ñ•äªrAxÀ« Ä#ø™eiìfPçk ]½¶ܸ™Ä‘|¨ßž@Þ¾±žâù02Á\”LšMµABû©æX:—;óî‰Yß:füŸVsîµÖœ²™ÆúëãÖýãpÅZ³ÕÇu‘ÚÁv®h)¡ âLƒ¦ ä™±i&H‚RÓ„†¢ó4+ËßÝÝýËÆ°µiÔiˆZM㮽‘>°òp·ÿ—e¡öëùÔÇ\O¹›#NÞÕUÚÒ¸î€^·>O“ŸMf²*– R›NÉ ­ì#Qt$­…¦OE¥0/ 'Þž#(8\A®ZJ® ŠW3[‹è=[ÈªÒ –ºÝ¨ÓŒ:jÑñtœG&ÔÛ€‡yZHoëKÁÐÛó ¦;lS¶±æö`í¡á†_Éûøë» Ý;ôm[Ê›Ê*·UT¬{oGþ†’œ5븥+)mŽŠË¡¸,ŠÍÄìNÆnvRQXYÌ„OiæÁ@_’Ñ’l¥Î"5ËÝvEIöÆùeÍ[êÚËØjzÜf››w¼Kâ=A^xÝ4®–Ä*OÀ$M¾0ï•ôNÁì±íž›»ÁvÅ=íýÅ Ëì€-ÉüPÄä®tKfÏWS_@U¿—øÆ[_}k9ùÍ7•ÇXŽdÿ“”ðý03i÷U»d£è®t…ê… q(°Ïõªû" ƒ~ƒ+ÀɦAo­ÍÎ÷õ>4—g‚'³)]6ˆ¯Š‡.\ i®æ8"Cµ©h㥠îß¿‹743‹‡dòá˜/ÿØ&Î3Ž¿R¤H–,^N§;Ýél+vH`M52"ˆPÆBD +PòɤP °ÖÒP JBˆãøçùü3NlœLš50(¬-šVVië¦Q´µÕÐþÙh)°²8¾=ïÚj*SQ“ÒWoÞ¼w¾»÷y<Ï÷óhLt{‹ @Ï¥ûÐHÎt „Ve‡(ØM¡¬ªêÊõk$¼dÕééiõA¶•‹o3úß¾hz4›‹cÐùr”ì \«3™®\YTR"€Fcž^.òØ{ð®ΆÂj¤ÿ¯¶WâŒA7T?uozúnvv2'Æ÷æT…³@¥woÞø¬ªr%¸§~@3meK&½²êëÍÊ=jPVýÒÌ3öL(‘ô–í«‹ E}>ËP‚‡">Wd)ˆ÷ƒµ°˜D¾÷ö}jjêÂoÞÅ6HXU†-@."Í}cÈ}…N!„~ø¡ê¬¤Pˆh·®ÂNIMhÅ^N/ Œ!%M¨&_‹¢ÆV#MCdõXW»…’ä§P EO>2{Èi!¦D†Q>5‚öDt?4Òù¢dFÛûãgPh4¿te ú<#OAp§–¬DΙÌô$r¢øYÔ›&s‰h„ó°qƒÃHA{»xl\ €óÒ"EË'â$õÈdrN”c(Ó÷¾£3ðµÐ{ýúõò%KÁ-’¤ctë÷o·%æLm¿©íïhvÔh:\—ìr°:wô;WïlÖó”Yà,Áâ (ˆ¢ àÑ„@r("rt ™‚›4¦ÈÎguÒbó ëÓ[BÀ$ÍI‡}ÐÑ8è°&;E6¦æÌþ¦ckŠ˜]´ æB¦“tÔ$»·um‰;š}íÏx¡r»­tC•qÙ"la)` °‘cŒˆ}5šM‘QaG&ZŠói,¼‰ÆeFéò¾ƒj,¡ÊŠêqªAEUú.íi/áÉ™æEøG‚×g²ZJ8wfÞíZ´ÿøo nšË9ÔZõRKYÓÚ…«Ë¥%… 5G @Çh6CGkAv*XN+ìƒ ¨ÐløŸÊÒÚp x!§D<lƒÍpEV¤I«Ús4{ÿ=Ï·ë9lÀ<‡á¡b^OóC.áà³ 8$˜°ôÖ\&=¹²¨¢öGk·®Ü¸{ý‹¶½žf‡§©ÛksÈ6@HÌè³)Q«2` öYåp­7\çƒ;}M¡°] ™o Ú\r³»ÛÞ~)ø—±‹ê'Ó Õ“÷¦Áu3jæÎìÄè782„í;êùä¯Ã5NÅæ Úz~“ˆzvöNf||JÓø{ãbg»lûüm®ñ\ƒŸnÃ/5Ý‘’­Gú[¼@0bØ.?ªJc/0 T`’ÕmðÅ‚ýö`Èêî­ëtÚ;ÏÚ½~GÓ²ÚŠ¢¥&J,Ä%À¹À´‰—^Ü×6™>æÜ¦B#'‚z’Í¥iˆó­+ÊÏïn»á¨Á(Q4Ù;ðÞ‰.îÞµ£tñ"^ˆÿ2`ºÈb~ç­·sÁ-§ìšvÌ%Š|Q¾6³ÚÅíÏn¯ùq3(‹¥VHÂÅ}‡T9”õû2^‡õeNµ§[öEjÖYšÂzFäŠ ‹þ}ã&AEØÍ9Í Á¨™]''îFÃaXi²ªÞ³bùTЫ<ªÇ¥F"*Ì?DzT¿SõÂ@Š~p°ýåêU…z R ‹$ßµk×NþÊð>ñ°ÙkãWÁrXS³@ñ‹v´uî;ƒüLjþ†FªÎŠÆ-Á4úyø‚E䤂%¨[&lA‰4røô?µ„By^‰k)E;_A‰ãDýýÀo"÷È#ÓH,M^à^BcÄfWEÈGƒ§;äŠÄP_š3-ähZ\Šä$Úø2'bÈïÐá !wõŸCÎ4| yúQôᨇE Œ{ ùby˪ .5Š\>¹/D½$¹ö±’äÍfþsësd¾ !"#._ø|¢û±cÆ7¥‘d׿!§½ÿPCª«f¨ D|çq¹ºmT=EÑEƒÄð!Y¹ùéí\ªBZÈ\µÎ™/óØ(®;Ž? i%K«ÑhµÚÕ¬ö¯”[1`T7j‚ƒãcgwvví@¡…H)„”£IŒ÷ÞÙcν¼ÞpËA‘©­’H‰¢(½@…zIQ› Qµ!ãk=ý½]@ý£H±j'}5z~~ûޛ߼ù}??µÆØ ?|r£ÿΖnT…Pîé)‹Þh–«ÕIêq˳ûÝßKzéì¨ód¸§ä[®ý3¯»ìeIŠÇYPÁë)ú† ^º8r”¼LÅ”BGéBmÑJ¨¿à4b‹¡áç)„¾úGõ{iÛ~O—§]ï3m[7¶>ÙfikÒë€#dB«' 3©ú´@\üt:hÀÃÖ1Œ"tÈ™P1Bèô¸~4‘¤†Òׂa´­|ŒX€8$ŒÃTmij5Ø:,k·´nÜÙñ]O—ý¥î¡Ïîð²#·/ÆúcLH`""Ã'é„b‹ö˜ìŒ%™ô@?O‡%š)N>Åuó•éh¥i$H¿>ž¸úîU̳uó[¸-85sØþæÔ9Pí0áóóQî=ÅI0\̘ÿô.¸ŒÿRýâÖç—²çw¸ÂȇÀ;ý—²oÂ4·U0õÃSïdèHnˆI F—ºO€7É•AÄ$†—i!I »ð–c%4''1œÈDB.ï}”éXg^k‚ÏÝ@‘p0ôÄj½–e3¼V“yuƒÆÒhYCÃím¿9|äf(¬Ê)UI«<¯ QUæªÉè¢S«ÆåqfÈDhI8!&“•ÀùíüÔ¹™é{“…lîp_ ©Ï9??WoÀíÀ+‡Ì&pS4¡™Ü³G2ªW“ÒB’S³1•÷«iñŽ ïh±Y à4$œ^9šXX\œž›Q—oŸy±–a>ÿç¿knßÔš m„æ¯ NM**Ãt("ÇVœFDnNŒV3©*’˜ªˆw’©Ã’Y¯>­¶›7oª53Z!€ü߯:Ý©µÏ±î¡b‚‡$6mÖjˆ5PXFé7‘te&Pjê‘™Br’hßh"t†ýêÍ[Ñä‹­ú¡nÍ· Ò %dN¨CÏÑH)¢ÔI$å1BÆ’CÊÅ%ÓH`V?‹i„?ijXü$’N£üEÄ_@á ês“–&ѸñUÏë­¤•$Ð1í‹T‹Ž"Ñö¢±ÓH™Bé‹fB%ü§tEúÈua¤4ÆWΠ°D4¶C©Ñ¤kÄIÛ`¬WuC¬³_óµxÿ™óÜÙ)x#MPÜêµ›†wî.¿qÌøŠrUB»*a67žö»*‘áè1ªÍGÔf±(ÊÖÒò«Ë—qUsz´ña®ÕVRY¬>泿ý}<;¾móö\C‹ I\$jMëöu{¤‘=§ã; £Ëµÿ'|/œô÷U|%¯½äðp–GNöžØ8îÊ¿”@ÿ‚tÅÏ–0™`D+åà@Ñ7 G—#ň.…åÀ*žñ +ô¼ðÚ>û±}ý¯ìzf÷@·§»»ÔÍöms>ßÕÛݾý©–εmëÛ:Ì&LU‡µ‘°X +¥o¶h-MdÓ–öMÍŸnÝ´¹µssËÆNÛz{GŸcýû=¼É½oûÞW{^>Ò{p„þqœ &j°!;1<¤ìÑ,Ï9¢‹“]1…§X>Eói»¥eP†AÐ4"8"¼3,°a("ºyÁ Ó‰ÍfS˜pÖ½d×^ª>¹ðKõ¸ÆõÙÙ»øð̪ӷ¦¯\ú퇓ïÿúÒGùø€Ju~~F­NCëêO^óÓÁü.ùƒñ_,b†¹wW¹ý§[Ò÷9¡'0Ag³½‰ô‹±Ï}€§‚‰gÕ ÜæPš‰‰N°Ô}bq%ö¾$— ¸Ä”KäiN°G$: !Í8øô |’sH"Í¥‡i(r{wu»×ÙÖyš,ï)!G5è½ÕØ¢k{zÒyU’U%©*²*$°o‚•+5IUJ€¥V•ô™ýûZM¤†ÔP”QGO´µÿþ굇¨¿ìùí?½²nO` ‚$ÃÒZ ¶™ÐzQNª‰ø|FVÅ8†(!‚•UÀˆÁÃÞ9|džÐh5³eë“]ðícªÕ¹åÚdµFJêƒJ2Ì‘Æ5ÉL5h~~è *ð8°p2Áñ\a‘”;|l>U{üx@M‰ŸÅ"]º€Oxé°±L*õp·ÿÏWݶj-unfvúÎÝÍ›º ?›Œz£†D,Šæ±S'§°ï?ʳgQì “@ûꨵ«ÙüA4i¨f 9A5ëL­ ”þñ-èÀQ”9‡ÄÊM¢°B¶ui¾õ4’s(yjÉ4"ELbLJÃ'ïK>ƒïÂ${ ɧÑÐ^×6ôÚ æÌzs±šÜ°ñy“ÑÃÈCJ‰”ž€]­î¥ÒHÆÞ~äºÀ*Q°ÐL>G½«ÖlhЙ j8ùwW®àã??£úù¾þ7;_­^»vmMÓcP'iµEôÝË|ß8f|UUBlÁ;\ðzN…èJÐ] u:v¤‚LÕ€ÿúõëÕzr¨Vk²øßâ!>â˜IpS»7ûö¥·†]¡³L6Áf€)µæ M½#û]ùe‹ÏÎ’¯¯œè/b ,ûè²o°8 Lâ(§‹#Ðö9€FŠ£î²Xe¨âƒ; È™?î*zw/îb€.úR`ΕÀs'–õ±?Sô3' Þü(,W[Ñ_G¦„潃'9½^k%ÉÕÙÔ™ÚíXoØ€ÀúEw@qEƧ0þ´'”tÀFSÎhÊOréAŒpwŠqK`DÞ)Ä:É9#¼›‹ÒA`ª`ÿ륣iõK|~fjVvãkq'DcÎÀÝ?Þ†ÏÀ÷ÔŸý›ørâ¸ãøH–,Y:é´ZV{ÚÓO~Äáa”T$†BZBU’ðˆíõ=L¬@RJúR(¡ÂùlŸ}¾×îíÞÛççÙ€©AMš¨ u"¤$DmU5‚>¥¶©ÚT (û^Óïì.ýTWvXýtÏÎÌþæ73¿ïg†_Ou©qÌô°þþì%-–ð›ûh!Øá×ähÁà %áÕWêg¢-ŒŸ¨;¬xB`6ÄG•T è!z,âŒOœr+CqtaKÐÆV¼÷rë·?ÿÀç,g3qìÈHVÏm³òóß9J3:¤šJµh1Á/MÆi"N• ¡>^Ò¢9…H1ýyw÷#Àw ]ƒíyêi\]ÛViÕóTþÎSŒÃ;77' VÎÌÕ:ìNÞÜ»óñ¼¦1‚RŠÑMj4‘ ±(MëK?<P}øÐ¦»$@ƒxéÌùó‹ì~¸ª4Rd¢y›FJóóó6I’‡]à#ûžbŽ1ÌÓ©+%ÖžF”0M%ØÚÅUšÔ¯Gú÷ï‘ì"{‡Eضek!÷vº_zô¿?,“#¼Æóâ›oÙ9‹C²ó *«“øBD{•(¯’ÔÄ]Õ9yº‰óäT¶Úû¢…“$ÏK5NÞ$Y¡¼Y’ªöË$”b£EΑÔ9òÕïÕ8įµH–]’:³bÑ/ø9¢Ï²Ñà%†LÓl(ý £#xJ[œ›LVÛük¶e§h1;9Q5ž%#oåõª'Ú«¶¶_/·m¯ÍÜX½sÑ“D;÷Oϰ)`²É<¨ùþ+’£GÕJëÆuë}ù2;Ʀ½_ÏOÞºØÔÔ$ð#C«Õ¾Þq$}¿c%ñŒøŽõB‘¡é{ÃÇLÎÁs¸ê!;^zó§Ô`g;yyK/ÇMrÅ|¹fyŸ—r…Kü¬es‹ƒãà'Ž®ÕÌ5[Ýáã«åÿÁLÿ¡ÑÐÀp`²Ï3ÙöØ=vâ™)k¶§Ý€ÌîÀXOW¦·mÒ×6öŠ<Á@Å=z’Áɘ¯žžôíCå”ô‚š®QßÁŒïÐh÷¾lï“ã¾½~y²´ƒÑ\ž±n™AŽƨfÌ{nÜÿüdï§ûjyÓF‹`±Õm¯ÛÞ€ºe@ Mu«š;ƒ°j²’tÅõöXÝŒ{€ÍK¨mAÀIJ„¥;BI÷`Ò= 3 $<ýDzAeC_Å„¡€ú”KrkC²K·‡™uÄP©»bŠŒ^1½3¾Ö42èõýó·W %z“²ûÂé¬ÚmUåÁao|¸->áNÄåÙþiHžhî_Ÿæ5O(!kzgô‡'3l㕘/~¼àï치~»ð&Í tá&½A¯Óñiý@DÙJ»5 HLW(+õsÌ¥ƒñ\ÐV Ôx¬#bX,woˌ煇ёŽäH[rÄ› ¹{w5í¨·8jYN²òœ¹µ¹ù÷ƒrE©:HãQÈ%Ucì_X,¤ L¢%h4DõUT…°¦y¢ïK"»m!Åá" Fc•C´ªù­ÄžÊ€eé¼rå 2˜ÓÌ‹;'˜½Ö] «8C‘D?'QÎ)Ñf¡DŠi}A 3éo;.šk$AªµØšyÔXèU£‘¼‘pŠŸ‹e?'¾ûÄcôÔ0 …¨¢"z9=°Ö4RÂ2é1¶š°èà‡þ“,ÔW­vÉöþ»ï±•2üì­V>³G–÷:›Yä›9ÎÒÜB”!’º@4(þ ѳD›!I”ÄäXEyš‰2Ô ´³Œ ”,9ì#Ê&G£À ØÕÛ¿LŽÙ è¨Np¨zÇSu±^¬iMõ&[õ–vZ1Ü͘«`•)’ø]‘ üV ÐxKµÆ×àÕË+ wŽAð­ÜEz ÆöTž.ý}iî¥éSÏÆÁ6à·T§R&´„;ºZþcX^Ïà²F0~Ä­ê.5Õª¦½ñ^—÷ûk»À›L6 —¾®‡6~28@µ8 õ1ñÒÕ» œÊE ¡éäM%ôŽ·]à9›Mâ¾¥qýµk×X\–èb~¥úRÉf…ürº+sÈB9›åY ,ÍŸ?ùkƒ]jD›µÖÌq;lâ§áAMAªŸî!Ðl«¢ X¤Œ·çßÁÉ7Òé}úÎ;ËJý¯ôeY—Q™U¼£–çŸiY·€ÐÅ¢¹„Fa(¯1ЈF“ ÒTšF‡Û6=,H¼S0ó<äÈZÁ¼òSüÿ¦|Ÿÿò‘TW['IVŽ3sRu×·H:Kô9&»š!¾‰sL—ñ«Ÿe¢œÌ2ÝGH¶>MÒ3$1A‚ Œˆ()ö6v¤LRÓäX7çh2KA”D“`®ßDžÿ:‰¥‰2³j4¥`ðù韨r& ÎZÁ±ó1qU=IÔ)¢¾FÔ92<Íoogœ±¦¶®fw ŒÌkl(LÊb„sž&ž4fÍìL%h ùæË5’Ãn6ƒm,œµ±¾îWW>¤ÅeѬ ‰ù{^+Ðl™I–Ÿ2—G0,²6¥Ê«›KK£€›Ëg}ƒ(Õó¢ˆcÌ™ù:áñ¯¹^löµŽûÿÍ}ùÀ¶QÝqüI‘*E²dNÖ鬳ìFMÚ¬,é(‚QµëPÙ ÐvIpâøOþ· B¡ëÂ*¶±üñߨ>ŸïÎÿÓı“ØIC“RZ!6Ó&¤ ФIcBLš´®Z'¥”6þ{û½»ÄM@)%Cåé§§wÏç÷~þù½ß÷óëL»-IGï´úδ³+ãiIŒ%Wò{0Ä"¯?û‹ZšØLSP£îرãÓ÷¯|Zþ*R¾²XPn¥’î*7ú†T>ÔÔ„1‚Ô¨únŠ8ä‰ËK±¯| &­é<ç»Î®²ÂNšÔCíÂ05íÅK—”äPÁeðùœðeü¿9(KP]xé<¤ŠdJ³ËA{4NŠŒ"ü¡>üEÂÛ6k!h›iFC’,Ë‚“‹‹‹+¥çÎké¿RéСC:5©¥àøÕ÷=ˆ¸$Öâ¨L#! ‘iÂBÌÏ£Ñ΢ài.Ý&¼ TÌç¡¿ôÏË?í?Ù¸½8„Ì#)u’ÒQõ»m®“½É‘¦1»)ë5N ·Ž‚ šN uOzÀ@(7šRŽæI—mÜÒrƒò*ó0ypÊu09lœptg|¶ñáfñdû©®Œ§5µáªjM;Û”RKÒñÝ#-P—Õh(’¦.¨ü|%w}&>Ëü©B#•ü£D‚/g¿R¡Ç‡]îáƒÇšZ´ LB¨«í5vÇí˜F¦@DÖ±¡¾ ÷íшL€ÐþÁ£òiQ¾y4›‚…‹X‚Qs0fá`íA0PI0y#Ÿ`ñÍ^®ÝÇš×mßÛ¶ÿhOˆÂ/]ÃüŠ/Ѥà1Ÿh‰t|ÍŽP37Õ•ôݿ˾çóHIšc3‘N.aGÍaÁê?Á’—Þ}íÏÉg€XÀ1+¨¢ ˆfʦ “¬‹ÁRóÌÁQkP$ÒÊÁ#\´Ø½Ãû¶î­ÓÖU«T ê(²i{ý^OÙ/+¸È=Ã’ÈËjί¥nXLÃb™óc1†ñ$ÌÙB(ÑyOãf(ACšÌxzß©[¥²µÚ*A_q{¡ƒ öï'Õ„–ft cÐÐÉ“”HHn—âYv)à+…Ö¦©› Á`Ô¾ÿI˜¦h5aw:WçØråîµ¶”™å<Óÿã$”~C’Õ¿=~ pYá†6œF¤˜ ±#Ë=µwI«UZjÉÜ·kÏM±XF¯ÊãÔJy|&þôÎ; øTµJ«fÐOœ(žEcó˜„ÓXë#“X|{ÀY¬=@åù3HX@ü‹(6üÑM?4”¡èŒ»Ì¦ûèyJ¤0W­ÇR>·~4"¯¼$NសA± ŠžEÜy$žCcIÔÝCÕÕêˆê ¡Þr?ê?AÖ×oªV3ÌCˆM㯇2Ø"3À½YLYáùU{ˆ3Ë–Eñ—ʪ:Ÿdôúz†"Ir‹†ùÑÁCŸ|| òÞ²z–¤[2¹ò‚R/,ÏÈ'«T¼Éó2“¿ôâ9ÐP¸ZB±­!¨z—Cz~Wãþ_}|lähšíšðXdìÊzA[{¦þÇ}ùÀ6qÝqüIHH‘,Y§Óédë,;VBšu”?a­©¬X‘؉ãü#£ ©eÝ ƒüõ¿³}¾³}vHpâ$ Jh‹&uR÷§ûÓë¨JÛ•M›´?l“F»n¨‚’¾}ß]HÙ4@ 0Ô>ýd½;¿»÷{¿{ï÷ýüü ïHV5ÐéɳÁÚž&[Å3 ¥õ[Ëš*7hv‡4¦»š3þí§Âþm™Îš¬Ï;â«Ívª2÷[=ÝÙîúlhj^²u½cóy+€ëüùó€:#J™¼öÊ«þžÞª]U¥«V;*86oÚ\_ç C?ýÉËüýò§£Çvzzj>æ´_¾þP•…“c‹×–ì;æsûvŽö`¥À°Ýƒ¾;:l È<Üz™é¦@òà8äÿC#ŠGNÔÂ$XÒŽC4«C°>w$]#¥  î¨ê–ÕZE­‹§¼‰E#i)õßþþ›Ú¬¾¦µŸ=ÿò1O8¹+xzÏñ>W ®JÍé¿}¬å¦frÓ î+;€"éj$ ¹C?ùaæp Î¯x"Ÿ¨UŠXT}Ì` HR‡üÂËÿ˜+ˆ·ER®˜RM§PêÃ1o°õk»‹,%f³%Ÿ Þ.0[—9þMhqKé()èZy{¡Ä¢PƒžRI½@åSçZZ x³]l ¿þ+åSSSóI힎ÞBå…“ˆ#ù‰–kmm{TÈ/¶9LSÀ±íŸ˜–Ãà(’¦ŠDM‘Fsªr·h¢òûNªBg« <\¼s‰TûÏŠïÚ‚¬_¿ö y… Ç[Jíü”š¢9D—‚Ÿ´s¿iDµ¤ú«gÛyÞ„Oãà­NÆòêëoÁ=| M‡.cíÚáßg¡Ñ@_§z×ÖÕ:9“Õb[ê\IºÃ¤ÒŒ¸†|tühPéhî¾ßêY•éjÉöVgiÇYºl™…·ƒf­¶…I Dõ¹ÉÉu_*CB@Ñ&X@H ›Õ¦wܤ±œÃîØº¥"ß½pÞ|0uªÉ­Z±‰¥çÝ?tg{wd»°Þ&=hwë?%H(åóM#‡À Âx­âãuºA”Ýaµ6¢º%Ð4T­–“U±E#Ç<2,êò´©ÚUœ4šë>þðJŸ'|Ì‘¶w%ëŰ·ûw?~ÇH…ø½øÒ…h½¿ÏðÆ.ºcÞd Æ—h”w$±+’iHá_ÉÕ-Õö`½@抗‹H#²'àr•˜ðF”fñÐÎgÜkvæYyÁa²¢aíæ¼5ó‹ßþ–&§5±WKIÓr2P$!ÍFC”.n©æŠ&…uQrèDE:—Š<-ÅŸ(´!O8Q¦2ì»o¾5}÷4òiIu#Ñ'qvzªõðaœÜ"àCž¹Ä!´nxüšÚOg†r²îIJÕ"A (ÞÊÿ¹dD“D-,iêqÏÊ’åËœáÆÇÇovãŽUáíÛ¼¾çªêAä –a–•iŠ¢%¥9)D\§ÜÒÏE35ñQopS!j5¹n¹™=t°ŽÝˆóÜÍèuÏë}PV3¹Ù©¹L]}ìÑ•ÅVk³ÛÍÌ’-nÒ#SQiÄ!¾£Tâã“”:`T”ǨˆSá>CÒDŠOê9ÎuŒ(ý$ž&r‚ˆY}™§)Ϩ§çiD£¿йÎèršvä3”[d >Kdg=cu04bÉ•þËPÏ…­ò?›±a~ofÚ÷ß{ïÙ¶6ÁbåXÖa³³f(B÷ •7ÛØ‡6–Vwíß;ô@³ÝÛ»ÜÃ>÷`OS¶·n £¦ïHãÉ@õ`gÃÀüë lên5‹í+6¬fØ<;Ë ãä¸"AÈç-³çKÀd+U­ßx:jÊwï¬êªéödŽÞoõÜ™éÚ3äß‘íðN®˜YÖ¬]?«Ÿ.# ï¼}¡bóçaÁfhX9†ƒ¡/ð‹·£:˜0,˜—N»cõWH’téÒ¥A×rss»›š‘X Ö& Û=êìqa±:Ô ÞFgà ü¨ö7žÑû:àÒó9¦  x]XöŠ’7 ÖúµÝa¯© D=þ˜'¨è3Nèt„½=xå7ÈvzÆÖ~žz w ©¶Øå_ÿB*vÆe-{°_ÜÙÓ_—P\¡XMK«Å¾9¶Ëw‹ÇêeÜVõ&=¢Ú¥ï¿ÁèEb®à"ú/¹±š Þ¬6H¯oÅÞ ÅëìfN@ª¡õ ¾°5Ÿ1ݸ隒Ðâ*ðCK%´h˜êc\¦(’NhJø–êW(´€C@/É8… .jj:årÛ@;‚#Ÿ³}ï`ûÔìõ»Õ#¡-$@ã ÏÌLƒP5ED!ÇÖ\† D݈I¢t éäL$ É·ö¿O¦ÇÓçvï)Xk.ä¬åååW¯^5æÒpâžž5üÿíû‘ m-y áµ½OÁÛœÔb!ê î6Ô·X–R#Û*Q’šMŒ]°•.ûðÊGssóòqsÍusÿ³Òæ´ëØa4Ö³3ñ†ÕìàYá <ÖZ@ž:Je7ö8CiDoŒ“ä8UjH3d:¡«? Hy‘ Ž’Oó¶G–T6’Á 9KÔ´.îúÔ‰“0^…û“‹F#Ê П ©³t–¸!tÆHd’ ²k×± j‰ü%žÝ$ 9EW¦ò÷ÿ›ûºmâ¼ã~R¤H§ÓétºÓY\"‡4À€–ð: ƒx$¼8¾øb(J¡¬¡´%¼8vÛ±c_Û ‰ã—8 $„•©êÖ•+¡±¾ 1 ›¶‰mR'¡Q /·ïã Ñ4-˜Âõèt>¿ÜsÏ=Ïïû¹9UÇ‹ÖTÍݰ•z»€^‚F:ú ±ÈŸ_˜bÉ¿j„X—_¸jìãÓØûTkßœÝÖ%쥒êUîÿ„^´Fþø^cÇІ¯´”û® aú柳þL_Ækß•—1Ô†£°ßÐÐ`Ôíùb1-¯ ‚Ý”ÖOùüe*’£}3ª ãânÐKg†Òº©ö+Tâc*ñåOQ‰ù)ù41@uŽïD2T{Ža¶”¢]¦BÃT¨œ½þ-†©0s½ÒDµvQÝ?Xæ8±Bñb61"Í•q2'Ë˨w=ä'¸Øz8H:Ö1LÅG¨Îˇp¢M ÿ€=Ä*™xz(ëÉr™Ë‰’@ŠÆº óï?ûen O^“ƪœ"ú䳆Zˆ31Y8þTÿÇßœ|ë2ÔÄI2o21<ÒD8FbÊÖ,Øu´îyS ±X•ñlKž{=Øá°”ˆ¼Ì ‡¤âßo:çZ³j5ØO"žçX¢Ž/­'êt{-)wU³šñ Þ¨}^kº š­ô¬Éºœ)7ÎõF2ÀKl /pg³(äalbâ·7?åDŠ71E%¼Èò‹¸e»–j¶Ä~Q}ñ×?º½qèËC¿Û;x§ºëƒµïu˜wâËW€-&–6óE/‰E¸à–®`il-6Ûoî~e±)£h`…sÆ›ööy«“Z@¯½}3jdg¦Åžj9Üëq¦]Uîí©³‡{}ßú%º9ödô˯ïI·nïi<Ðïy-‰P“^[º¥ã–rÎv5ýžå\{r-»2MJν7}Í–% ªÏzA2gÒE0™#­&å‚‘©®‘.G´ÃFªÆ”’_FÎÆl1­&ÒåŒãSM hª?æy«NY6îÚ²|Ãró’2~ž1KM”HX`³È1ì<¥D`ifUåò†G}ö&­Î×a õØc1%Ò®†´ÙÓÑL ŽÚCm5„ µåþçÁª{”øñèéãQ}t,?Šu¨­œÉ¾èþ`„-ZÜF¯0ªØØƒmÖ–Î:0/˜PàSD EíZ·ÖÔf¯ãµ¥KKY뢄çK9¬b²P%q^Ã4l^¯ýz‡FÚl_¤M3¡Ó›×ý&)̧"á§ù¼ùüøTêMGÞôŽ‘&Æ‘±‰|áiÅ ?Ë?ÔÇFF†c†åäˆ)®_¾ðžß¥wÅôVŸ{îþAuh“a1I0”U,yÔ ‰ejj-õñ'äÖæõIR]¿%›1Æ&&& dš¦Káb1QPœ'íGëiãÀ›%™ÅñÞÖJ-¨¯=<µ?[ã Àf„…møó„>Â̈́׾\Y‚Á£,1U±!2þŒ"ßõ×´©Œ)ôàÁ³Ù,Š¢ÌÐsåRj½…ê¤ÚîƒTw!ÜŸ[#øh€J R=Hð~*Ú?µß[HùÖb†Î!*q‘Š P± ³¦‘Ž!‰îªˆjn+zuÇ`5‹sÔ7¨`Œª›1-Æ-3M’ ñ [Ìó2S¾‘r…¨® ”†.ár„¼1LøŠàŠÂ¹H Ç#ÉA˜ ->D@ReåÙ–eJ‰á˜²…ò­›7ÈjÌçÿÍ礎Ž)Ü ý£>¬\´?“y±”0óáp¾DüÞöµU§^wvyöeüÏ›Jðƒ%×RÛçßß~Vª0 4 H¼tòĉñÑ1œÔØ¢ _ZP^`ž³ ÌåŠï\w Üx¸·à^·5í±e›‘–äY˜ä@®e¶4‚8Þ—ö@#‡“~š+–ОwZU Ó£‡ß,\dæ ¥B+bK·óÉ~R?ô©ýòíªKw6 ßÙzévõ¥[{/ÞØÕK¾í¹iÏ}²ËßWéh–nšËÈ¥¬T"Ðæé"f¡\1ß$£¾$ˆ8Ùþ„£dhvdšê²ØwÏÔO|Méq9“gí}žªl“%Õ»zù1©s¤Ü}£O6^éµdΩY×”»®×¯ô6×f|ºº¤ûxÚ8á:Øãy-P»Ý‡rAµÛ6Ôeñ2°»»ÏØ · o•¬Ç–ób«dšk’3êh¶4V‚]N áØnõ!d‡¤dÂ8¯†Û¬^]Ó©š“Õ¯TUJËæs2-–0’ÌÀ¼‰æ‘I‚p²d‚C0…` Z–æa“j-o.]÷ÎŽÇD"V§½=^§µ¿àèGkW|šˆ«\Ú?¹/ר(®+Ž_ )’¥•V£Ñh4£Yí®åb7)ÄA (±¿Ö»^¯ (4SÅ1ØÆû~ÍìËÏ]¿í5^â Pp•i ”„Ô@ ¥QQÕ~ˆBj¼^{§çîØÒÉ­ý!½º²f®ÖwÎ=÷œóÿGaÝywÔi4öXqð­ÁÊ­÷nö v­i¾í ~‘°D"°Í_döèö¬¶"‹Kçt.Acõå[ÌE5•›÷/'S—0)àRš„ÒB¦§.ÍÎÊÂMÉ-¡èЃè󊆇9SC§MôØE—mø×Ç’)˜DpõŠŸ&jE|šIfšYñ ‘áURÜM D¡ëŠ?œŒ6w¶)N ÛÑ\*Íé_Xú¥ÕóüØDŸ0-볚^@»m¢Û&úîY¬™,¤8ÌÆäðï.ŧD(›¤ÿ4$Y—ìŸ>×LÁ>~è0d¨Ð*YRSÙŒ"Ó_OÐÈaùO¯]t˜&`-!n³N:`Åß’Ÿ½ÜÄÀŸ¿úØ<þeýèF4q:ͺ.\€O¦Õr†¤h5*?ŒÈ—d÷Üìi¤S­'Á!ÈÄ[ mÈjAþ^BÎòô @¹ú‘óÙ´3Û ›3x#‰¯ô¢*;Ê-[[Œ¿ÕØFp?âZLrä’uèõCèW•I×Q´B%ãž[“‹„fä;ƒšÏ &8ÂF¾ 'x'W€Á€(|âèކ¤Y;Ñþ_B¡õ„žäS½$ùýsC¸‹Å$'?NU)àyòQô\däª:$䓌HbS¸•Û7èëïm·—tÙ¶tœÚÜ9k•Ç4ÒZSÜZÿ³z‚#Õ,–§ÌW^}Â’¸”ƒ0FGG÷íÜ ­.D;ta "Êeª¬Ò\CãÉ]M°./x²¨Ã·®¹j®h¤0tÂ¬Í Ö¾Þf#9BAQJ¥R““'>ŠækhR¦¦8.yU‰½ßÐ÷qöÀ›ú>_ßûÇuá[Ã7·„oäœþÃÖþO×öß_Ýw/3|gÝé;Û"·µ=×µ—òç3òö&‘) Å)IœË É*)V‰óšæÒ’Ë ý&8ZqðDQèó,;Uà7úÐÉüP üËÁþ¯£p¹Ñɨ8Ÿz?Ô´Õ¶V•`=¶át-§ü#wÇþöÕ·÷?¾ûYäÊGÍﵿÝu¨ÑZrìl:¥k®ðØÖ](ð ÖéZkaàú`¥ mÖþœ-¸´6`/0‰ÎѤÇRÈk¬ ¥¼ÛPo-®Þ½ZŸÉe$JØTÎ*R©¦ñd)O- E‘ ˜€J 7“ [&ñŒé:…P¬`Ów¾ZbÓ½z—WãpçÏ»ô >µÖ‰ùJc²jÆ¿Md¾¸øOñÖ7BG%F§Æä׺æÝ­ PSŸß^ ):B‘NÖû·öÝX¾¶*<²¦dÓé;Ù§ïní¿¾‘¾žùlMÿí¬þ[Û÷5}·u=#šÞ‘má‘­áøA™çÝÕ[  I@‡ÁÒÜBZ ;¿°>ó@È^ÜnŠ)ë¨+ =ó\šꂖã%ÝõùÁZCsý•¿ßÃõ+= ”Ü)páù›WC ‚oÁnyí&p”¾ÓXÑa¼z;wÿŠ#ô1qêbìæ7÷׆jó<Çs»Nw[ Zjö´š~´î Ôík·išÿŒóM#^ƒÓQhñZ±h–º:siÎŽtEz ¥ð`䤒£IR¦àH nƒd@W¾´²¼¼Üçó ]¾|ùÓ+Ÿ\¾|ù÷Ã0;Û;v”–¥/K#äàp¢HE0iÔ¢ŸoÜcÕÔKæ[ýs Ø*4ÐÛ,…Õƒ¿¿ýå»kg‡½œÆ‚AkqåÝfŸö™þ™C (1„èáRìnÅ¡³ô| ÐÕ”ï YMšjÃÚâT:UAË) u"Áñ4Yg6A”Aºò~à4ôS,K}~ä¨á”Ç!ºæFÜ¢Ý,ú½¢ËÓ»kËÈp‰4•Ÿ›'Õ1\ʦÇSR(µZ’Žàò‡¼ˆ\VVUQ$B±Ð $òÝ//ýÒjÆ(âõŠæz‘w`eçùYÛévÆ=NQpà žoìîL|E«8µBNw7µƒ©Àñ)‚ú÷1666cót5|8ú]EÕ€ÅPÌ.…cw¾˜6î÷áoIS2ã{¯ÿóŒ»xL;.딀oaÜÉ­|INÊ8Alƒ[ˆK"òÿD# ÆbO†Ðƒ^IÏH’%©izÉë³Qcò "ÏÀ¬iÄÓÜý¨ĺ[‘ÿ jèB+6,”) .i ÈìCž0†–¦n,ësE#|â{/‚¼oc_Âx[+zëx A-’'-(ú÷uÓÔ¹ÇüILLHš4''''çä4m /êÝl®ó2ߦ#Ñ›ˆÐJ¥€ :‡à¦›îNÈK×Rú^ÚòN¡å¥¥Âtn7óÞÝ×Ì{ç¼7ê•waÛÝÜuΩÓ] ´çþžV˜Ù 7!Ö<9)§åœç9}žß÷óä!'¸å7HÛ€j΢Ì|’@GEo ú3È~; €ÌÀØÃøŠH€%¶0Q0HzðŸ0^‡+¬?*8ÊI×”(Žæ¤d”˜ýØÔd€ÿÉ‚ñþ.¬PIŠ Ôs$½’Ë;qXÕXù1$÷¨3Û5JWyvcÉ!÷‚S>£µ,ߥÉÓŸŒb¡®q¤@˜¸é¹éÐL €gòÿîe¦‚xzÿðýz­ŽÑ '&i1A%–I¶PnÐtëÒK•핵‹¨ñWE¶«jå YG’Agd¤‹i±” chnÓž¢dÏ?6ž½ÞHñ÷ïðö§¶÷ïòôÉ;0?À$Iþïe¹ïj–ïZ®·?»«_Ñy ¾¶­»£ïúîs£r÷²Ì+¶f ì.Ä%ÈöV縴ù^}zCɾv­ª¥|^4ïëÒÂ×^n«nûÛùq>üÜ‚üÍ©û¸ÖM‡FïßÎkÏ”)ÛÊSÝ0®ÒL÷;û5]ûw2ÇGP£gA>4ÂË”òÙ÷_›ÎwÂ}9û›µ=WþôÅøíë÷¾¾øíHé™&•K½Ô±dV×dpdï1Ú”:{®I­,ß›ÅÐ,\„c8–b þ`¿M±›ù+}µá·çwç»»sedæ1jŸl¸°ßºùMc}ƒŠbÄ$A$$·–‘Ê8éÈ1ÙÒ–<ýë•Õ` HˆþZ•Á®ª2çi>nû£.GmÍ5˜ÚUMÛ3ÃØ²¿Æ ¬XêþDø ú-"ÜTV³ÂP¯²8³ôG$Ænˆá`Ö E k e²ÕŸ|r!R1` iôUðËÆQp .¿ù8kd±(b3Ï8̼ɀãÕQ{WoØM³4ÁÑŒˆãF‡G“ð³ûY¨$Onmæª ÎL>TtüI°Ö`‹C‘éϬ¹¡+ŸE4ÖaŠ@¸Û¬à Œ“kÄÄ;m|ƒ3h¨âvÞj¨9”rohH‰(:Z²rpxGötÓhž×|‚op•ÿÏÃämIì(F '„Ù²§n™Ì¼ÝÊ[ªð}#íIŠ,žFxk ¾šÕÈ›ªø[S†²IÄŠàùC”\½|e.Ghý\^á9óxlÙ›?|_ã3b:JHsèH rt"ƒkÁix5ô¢£•Q‰ r}2JÍB%UHk]–® 91E°Ë² ‘³9Û‘­=Œ‡EÒˆÐ Ñørô"c7f ¸¨®x‡¦c… 2ÈâBfø¾½Ë·*9š|¢‚ãÈ ð𣖈:€Ií$u½aŸøñ›ˆ=ÀQ¶0Qà¼Å‡µV×…ÌdðaÏk„¢•IÆÓRŠlp‡ ‹îݹ©Õ @xΣC#«c㡦ˆ9NH éÕâLõë…ÍÕù­jUã)ˆ'•[½§MíÑäy4™Í¥ zOe^SåÖƒÊð.Љå$Å'Og·5‹ÎMœ)’P(0Ïÿõã ëŸ]‡{Îp"ŠÂU‘!dIò '{ô»[Ê€I‹¥ˆo ķҥݜžÄ± ËqR ž ÍŠbH†“¬yÅó— §‡žíýWZ砢늲»?Ë7 êÌðgt¥xG·u åuɽ}/t]{Þ{-ñôprïõ”Óc©¾ëÛ{}}IgƶúGRÝ—ÖT’’èz9®æ,õôKÏj®‚Ïl«”7•‚‹æëçÞ5 \Õ¤6œë¸3õ‹‚ Ýüò\ß0Àâ>(lÑe¹Ê2ÝéîJU[™Ê£)h3ôÝúŠÇ“äâÑÑï¾xÀO>ägðb›„™0óåÄí¢&ÊSµ¿¶â÷}gpé Þç'ªÞo;Ð^½Ô1+«js,5J=€Ä‘k*‘ÿZžº‚ˆ‹fXVH0B‚%(Y¼¬´¸â›·a ‘Ù;W4Âu#4[O~,&‘7ƒ#ý«VÇS ʔ٭±›«3+!Ž—:ý›TFën]M¶Ùši‚ÑÕe­*­)Gkϲ:”çnk½k>²¨´ælõR÷'2d0 ´E0“r,u{ôV•îí´7“eÛ£I),U{<Š"„àæ#EîÜyl¼ >Úí6X•bX ¤ çåý¼Ý6c5,bFˆÀh5v{ZŠˆˆYDQXp:œþéF&’‘X‡_†´9„Ìádq4qŽw6üùØO³¤” ŠÐÛíöÈ*{ÌÿÙåö3xÍÉŽ@€Ÿý] Ö˜NU’4ÉŽæ„qëPE5²y¬@¹™%&¸8 ±\¶½u ™ËrsÉÅ' ²jë†dë\4Ô$½ªíA?²Â™0!çÁäª$@†ÇÁC¨© Ù;Ñþ†Œ}Ñt *1¢Ú3¨Þ´&¤nÂ×Á éÄÿä¨8¡«^ |}?¾>Î;z¾Õ½‹,~T{µ¼‹Þ.æd›–q±°­€ÛBb玔ÏÇÆ";Ǭ[›w%aë d~!Ú]þêvƒÂ£ÛëÆ’ïÖ䶪•¥‘è—{æMÉy›»¼°E¿eî" ¥ŒèÒÅOgÂ!8ÄÇé`0®pàì|˜ût||\£ÑÀ³’Ò”*ì‘ØU¢Ô#y¯¹ôyÍ ïϦó à'UB²dÉ:N§;…m%¯%4 ªM³5íÄH€@ ƒ1N !K–fí-SB 6øû|þ8ãll>ÂGAéViS¢­Ê¦t©–,@>”6S¤LÊ¢|'€±ýîymª­©”þééÕqÜÉï½÷ÜsÏï÷ìéq6v·ìî±JøôöìS|~&þŽ'†*ú:v1_9O&’ÑÜ/ÂŽÊ®–¥¶¸"j­!£`Õ™¶å•,g4®j†¡eò¯‰.7¤+¤Æ –Öt§ææ‹a”ÉxâYUIft oÆI’è‹ñÓ O+(™ŠáVSš÷ ›<†Ž¥¦W  ï1¸=zÁ§s‡ôîpCÀQiöé=bµ3d”:õ¢¿K‚WgóêíK½Qg‡õ€ŠÀqFE`UÖŽÚƒ† ÚµÊU …˜ƒ%“­Tª~¸áµÓýδdjÞFÒ:uòtN4˳ õë¢M(àK‰.äq- ò¸‘$Ív`âÍÖ–jÍP´Z¥ºqõ¬¿þ¹x†èZ²p|ûöíââÍ ÍôZ´R¡Ð¯_sK°x8¬Hò¥`Ápžô™€ÿeÖép»ŽÔ)avû„”Ÿ9múx#%Wá*1Ê.X±îïûrýw…߯Âyé GVæä‚ìA#¦¡9µ\Þ\\tôÌ'àÅú”‘ù¤mdqUÛˆýq—ã‘O2äÑ,ØŸ)--] uf[ˆÿ÷o[Ð-øóàÞÒ7Þ Y~Í©H†ØXLéa £ª4 Fq®šS+y’ÎæsˆÃQBðËrW.ÏRMÁßÁßÎE³” ¾B BpfˆðÀâû _?v=p,•¥¡i¥r­|UÏÒZ¦!åÄ–rBì%ºŽÎN2¯„¨>˜ª7ýD£X9@?¤1,$ "p &ïÊâ $BŸbWñ a)2;ù¯CnÇ {ø¤×¯Ë›š˜€´omm…˦Y¯âîÛ×ã*ín{;f)Š™¶õ¶UEL†pkSÔº½§½ªèöÂô¯ 7Ðc§–Ãó±Ë™lŽdàý΃¤=$£"ÐÒdf¡ßI¥ÓÓ¸ú¥ _2‡\8sæ‹‚õXŠSÁ€þ–”+TTÎ–× ö‹e#5=-µÝ-[¢mú˜}Wó‡8" ·£(en6'£¨jq¬xôëwG¯VÇÎ6 _܇2ù%ƦþüV´µ1æ<{ëz=Q²©ÓRù|;Z,>‚u΀ޱwSS½Š!i:›¢¦ìÝŠ¯¯]ƒ¾1æâÉé$=FÏИácz¤…$™X Ò7ñ„f±ÇX,m G*yF%gµù[mu¦¥¦°Ú&E[µÍSïõ× *§ø®5Tçuë®Z›³Æ*Ô€„¸àR°ÚÒ‰K½P‘Œ€–€ë= "‡ÞÙ¿‚ÍU’  †•)U$MÉ_]³.à”’Øþ°dÂ;ÇÂcîÞ}†ã<åM^1moG@áE´À:Ìæ¤$@¼ ùü¿,,$y1ž×VTbv§…sžÉM-¨HIIÉhF¥Ÿa(ž«È_½Ã†ÅÃcCñÓ½H‘à„›b¡z  %ÒÞ|¾¤ß=p"Ñ™”¤Á]Äî¤²Õ †g8_,ü]àK¡›7þ©×ÕR$™)×ðË*){$ß‹ü.næ÷#÷[lŽÁ¬+þGÜÈnF¡.Wv%EjhFÁ³ F—/_΄:üÌ~!øßÛ-•H%æÎŒçð*%Ø:—Åó–8úa ¯GÏ!àþñçZs„ÐÕèy^I˜Ý€rÙ¦†eð–W¿IìÝ›¥âWS$aØMûg”ðõž4ëƒz ˜|˜pëŸ?ÿ‹/h¨B„Øþó¬eù¼‚Éå(ž—©)9ToY~!ቾÂ&×¼£æÈJþÊO6®#D÷g„këX 8F(Jû±ŠH0í!Œâ }Þ}³Þ.W¨ò(¢É±dÖ:–êt{„çÏ3åûŒ?Ù€Sº¨¥!Ò¾X”ß6Ðn4Ès”º†ÙQg„î%r÷áÇ­-&(Dð‘‚(@¿šlÕ¦&í^Éܵ×öY¯[ÃzÛŒÝÍàNúh»>b†±£×ª‹˜+ºMú~Ûsm¤·ã½00ÔR³4vw€`Q$iènÔ”‚[_¬˜*:_>|¶lø²®ÿbùð‹­C2ÛF.eþ->6¹e`‚Ôð”|%M*i^+6W´¿²è¢¦¢°ÙÐçØÞÕ²3l2ö˜ô±ÖÊ£cÛ¢f×ç#wSO @ û×ôý]ݶ2xÒ®¶'hæ)ŠÃÉñKÿxï˜`è:\ƒ·iÚÑm¶<Ƙ˜Añá‰S˜©(ÖVÛc;s*Ãô§‹0„Ú®þûV<]Óï<½. “,µ€‡tÖBU{{ýGk•¹©ò()€XAér™˜Þ¾£úe.ýO¿–)õ°¿ýà.ÀLAÒ6'W‘{HÀ­·{êBCÔ»¼unØ{ ØDc»½Úä¯w{õ‚W/ ~± ³{©ma±F¤Vóñêí¢Ñêзz ¶@½[ÔZÅZTë•´n É`ÙSÜX°:âi–Âßϰ<‹‰ÿ«ýû=x¸ðÿß@zÖ°SMó2ŠTñ´³² uú‘`CÀ¥#.¹æ<ävaЋÞÙ—¡¤¹óz#ˆ¥)›%Ÿz%—…„22'ÿxšHwü¦“i'Ò=^õƒ{wËŠ U¸X€ì³jRÖZôÖvòûÏ;ÏîA¹ .³  Ò&#¸’ØÜnÎà A˜1¬`&ƒ»wn\–M“MÒÙ4áÒ뾺öV;Ð:ÈÊ9œ¯Óݽ~óðƒÜ¸¯ûØ&Î;à)R¤“¬G'ët§;ùEyš6mÚU‰V1^!ÁŽcCB*D×µ …Ävâwûîüî˜Ø1y_-{A‚UüÁ*ª•16X·Q„(ê:ª1 ¿Ü~3U{QXƒ¨*a=±¹{Þî¹çûyü¢cx(pl„`¸¸»}ÎãPÂraa*À$¤ÿPF|’½yÀhÊï› ‹3QǬÝ6hÚ±£öÅžoo:uàÀy`-ç|ŒT¼%$fazcar|…9ñ$E¨“€JòAQD(ë|OO9ô^àõj˜CÆ.–¾s? 8åÈi(ßÛÕ GTž0Ï— <ÚïCbŧQ`%§#ƒâÇ‘<¶húC|°B kÔ,zû(:ñ’o®¬¤*aGÂL)¼}è{‡QpŦ‹ê˜"CÊ“¬Aòx'Oˆ"P@P¡1”GÉ4Ú×Uúj#ækXU9®¬E¦·‘GÞãe/m i¼3eZ}I} z£ ¢È4’&Qtù3¤è›ó`OG¦¿sı=vhQ¤û-€”µ9Ó¿{ÈYUW­a`[à5­Wãªuí-mœüíæ© õ“0Œÿñ14òH¾6Œ_ÔßÔqœžVa^õ–©>Ùýú y­§%ã2'{;2¶-IPŠÍ2ælNôt¥Ÿ<ø+9±·²ß]»räìÏÜ—òÝøüÓ,ùU¹~ÿ¶iÐÞ™²µŒôµ uƒFäŸÍ’ÿ*äæç.ýùÊà™ãÒé‰Cc¡¡3'nÞ»­äITßWržŸŽï¶ï:2ðùƒ»9ò*×ÿöܾ}èðW­‘°Ñ1D‹ÛRgà)µVËcL½òòª/(ò+áÿî¹,dÒ¿›$Ÿ½‘)Ø»÷Meõ4³ókZb–@Ôì›EÙ蓌ޠÉ2zd£[69¢dp… ÞX[.Kì’<-¶¯_²À(bíØN¿ØæôD£+j“æü´x}g¯ñ‡MÏ7.Ã啬–Ã4¼M°`•Êljûèòe‚·Ü£^S˜ÉsçÎÁóÕòZ–¢êÔÔ÷CVÎHJ’"rÓ_€¼ƒÔ†¤[júËÅ $±è#ñKw%Ñß´©”V•ó¼NE?SQuçÞ=²táe€¬È8=˜›ƒ§|óÓÏZ6mæ0fÔ€ZV«R977üh*nÜ…Xd©ýÉûAYaÅåȇ%b¤x4çw Üý^%à!ý$8ñÉæýn%ÌJp½¨È‘÷÷íÿV…s4+ð‚ŠC„†õã¢|öäé“Çœ½¶­õ [ OaŒa:yšW•í®©9ð0¡H$D²@hÂ͉€¢hš zI[0À`ð¦Ç³ýY])WÊkØ 5Ùî­[·ÜñAÿÝä¸&Áë‚Þæ=äIä,8("úò @P¥ì¢Ü’ý†åú*x1 ¼µ~󬲨NŸîPä~nn¾8üúµë@±óÒä‘‘<…ÓHA‘#/ôè¢)GÎ4jî,åyªº½¾Y¨©AÀŒF«Ö”•–4‰7À!Þ#Å '4ŽÄQ÷’È(ŠŒ¡`æ‰i: f3Eíd8ˆäŠ !o2(q9â\uÍ2LQUzqk00[Vù2zëp‘"(y‰à1À Øfœt’T~ ÉÇo÷]ä–Ñž]´®œb¹r,0P­€á uœÅÝÕ1ìjIõµŽØ ©žÖTϓ҈!e«Û¾Ž¡U¹@ˆ3§Þ#»ÇÒ×d9ö8² Øì^ &¡Õ€øGÅ⺦u¯y»:öéþæ!kS¢»cÔi¶›’=°æd·9ÖõQÇbý4¦í 1÷ïN»ÖZY¢04A¯ê<Ô8}eýÔ¥ÆýfÃøïS?žFþ·l°¥4ŒV§¦yA¨5­Ju¦ÝM ˜ÿÀ!éÏQëÆáÃ#öm “dÿµO®’s ìÁsYâºBá¡’{ änÌÞ%ñQ D¹«ä;@#Í©nÓ¨}OÆ5vîÔ,Ì:ÌûC¸«0S˜ƒë …ùâ‘RQÈ{–ûÓ?þòFÒeJ[÷¤\3 9fÂå—n|¼cȺûª5B$`ö{¿ÁÖèX­š……©þðƒýìì¬ò/c—Á£ÖIῸ’ÍÂ0•"E`”Ù÷N¬äy-ÆÕ ·öÙÚá¶Pl›7fÃ& JÔ€¯ð£lö ΄%7øbFO¼Íë7XE³ãkgÆ—,ÞV;8„˜¤Ul ÇÁˆAˆmÖþ¶C†•ÍUìr–Öèm«-§˜ïUu+qê4YÙìBì<~…ìCXm-#¯RëY¾\+4×%‰™ì'Áð'¹&’_–¬‘b=P såâKÄn:úŸ«Ôèi\A³ fš6lËߺ¯< =É“£+éî…_ýºVW¥Ãä¨BóŒ–.³6lºår+áˆð‘ a)+.¹?3Qˆo‡’ÏyíŠè†Ñ= Ĩâ÷'žÛ~»2”Pœ®Bxà"Ê¡ ]]æž0Å Ãs@FÃCÁj5öȑ¸gu4ë4Íá936ßñ¸QTÂ2 „˜´‹<“%¢ â=†+/¹‰ÜðUn]^+ÐTKU’Ôൂ^C«·Õ¬8ß×£ˆ!Eç-2Ô#$w>D“Òx¤"iÄ¢m΂ëoh¨X½šYFs5Ë«Ï_¼ bé;÷Óð¼ ûÎ|>wíêÕ ^«¡afX81•4šQè(!Ddši …×$5dtdªd‹™gt[¡W¯ÐRZ=£”4[W Ù­AjM ýJ=¡Bd …§HýP‚#¤­'¨¨0 ÕN"ï(aï'„ޣĻ(üäŽSÕ«YžÔMÑ%Ííh_/µv½ –0£bjW£`%Æ8‰ÂÇɸ@e‘É¢— L‘,Ö®4‰†ÞAÁ²ÚiáyÝ?É/Ø(Ž3ŽT É’¥ÕjµZíiWw>Ùl (H]âeÀÁ6‡ÏâæÑEi0¶Ïö}ïÝÞù6Üùl c×i‹š6´ i«”BS%„JPTÏÔøÎ¾ÝþçŽP©ªiˆÚª«Ñjv´3ûÍ·ó}ÿßÇr޳!è ñÚP³5Ú),‹í‡ô”÷4>-ÙÒãÌ[0CâØ¤^¸qí:ª˜±Ô¿.oÿé522’>úOO½[²f-˜1ldù©F Ú„Å5–š@sMÔe‰7­ï¶eîà«ªÞæêÞæ—cõ¡k´ZŒ)Ðß u;Y‘•XÌc„â}ê²Áß‚FÖ?·èÈù’ã—ž˜FŠžÏt2ã«:OrŒQÈfQœ¶xFew}e«,ÖR£4š*>¸¯ìˆÃÚÛºµ³eðýŸd*Aèë_AéèÐáÌäØ(ˆ”ž tñ™®·|÷h¤¢×V«ßr°ùÇ—~ýP’Z*IISð8–H¤3Œv3y7úÞ |±<ÚPwSU×1åç?°Æ( ~Ñ4ÒaUÝZ_/yÕ nE˜sìòâÿ€™>†€%9$À´G34’Ì0 v5>>Íd6ò"¾"òâòÙK‹òž›WP4{Ú³hè,È/Z=oUÍš†²:—µ9På T´©ë[»ª}êÄöÿ·µŽMí )àG´*.WÕr·ZéöT¶n_²i¾4ÓÌÉ<Ïs‡³¹¯æÏQï½;w)ͦcN{ Ф=9þ 9zíÚµS °ŒÁ`0ó\Ia¡æi×=nX¢¸!£zPMzìTà&M#¸{4è#ú¡ în×Õ€ ½õ]³Ø,Ö(2‚ddM–ën\ÿ4¡%îèÉ÷nÛêg°#(=v(slGÉÊ[TÇ;t§C´§:Ò‹+¾IÛƒY)º§íž_©[±fTÍ™óÃÝ{Ń +áµé!Ð*@%Hº[t·]ïÜt¹«Š x00ò( >Cúåá7ÈtÙ„`A ›Ë³M‹—üÉÖŒxô ¢ÁôÓið‡PÏ€ôyç{ï\úðÊ­?éc÷õÔh&T4ýŽ>väooì²UÄÁ–5Û×/C’A+¸ŸýýÅn~ò—äÈ]=uGOÝÒ´÷®^POö[»êK{)ÿì¿øSXðíO[ãvËÄ÷ÔhÄâu[•Ï[dÆ $£Q ‡Ãéß­eþ>þ{*C¿´LÓÒ‡DË<_пpþ\Àë«Z_U?‹E j01’ 4+sJRg‡Ï’DNf9T=f>/Ë+ÊùÊž-­íÖ6دZ}ÿqÌøwiÄÒ´ø"ÔÀzEÙÐæª¶o_þõ"ãg>Ge¤ÍJá•M[®^ù$ã´ñd2“ráðÇ{@<š8>ü&# J‘ÄP]h¾ÒæÒÃݺ‹Š~ÒÖ uO^ý}š×£U š›QÞLóúK_”%ü*“LHb(Cª,¥+ËÖH87PyÔfY¹g9¶oëÍãÔ»ÂTÙaCÈ—‚=*d}ò4¢´R±v9Gµ4ϘÍ2B^>ËÊSEnßâEw|iVQÛèkЇ®F)Hуí) †CÔÐÕ¦¶]Ë—™$#“e’9ƒ‘„lƒÀʳjšä.^q¥Á¦»t0p®Ã{ˆ"Á@š=\tM:®h 5Ÿ‡ÒHP¡NVÔ„Ï·æ8DîÙµMSÚ½kKDŽ³Ì½¦04ÀÏã×ÒEºWÕ~]qQŸ„ºê§+ÓÕÜt¤ƒ7ì¶_žƒMò,g”MeVä z6Æþ_iÇÖ“4÷&R(µÚ]µdIäžrf“:OZÐûˆ?žÖ÷ T¸k˜DS™î|‹Ô;³MRËdÏÿiö%JbÃdã.¦ÀŒ82¨Å¬¬ÒmÄ®’Î~Ê!ž!â"‘a*ôO‹F@ƒà1ÊᇠAGŽfÍ]‚Êr'ÉdÓ.ùQŽP3Þh0s’i”ͤrÙá!~Ò!‘½Ä{8L$2HBG&ü®{t Ï!Ê?]'ˆ»3{ÙzWdc0^VÖ”e×n Û6ö9Jc°§ƒ"T•®i/8vqÕ±ßXŽ[ÑaÕ±Ÿ  =ßÖϰ’Är8Ôs×-¬ì®¯8@ ªì@#hÄm¬êµƒöÄ=ï_½0šƒ+´ŸýîÜÖƒm–hKU¯³2ܸ-êìúÁà›gßMÇ ¥ˆ3ühK¬µ<ÚPÑã¨í´_}pÒr/™¸pûúΰsc¤ÓkºÒ . 6nê¶—ÇêKÑ_ßòý^ªã)}D׿}æTeŒúEÓHh½ê­v.š¾µ˜šÂ²¿:sVÏHcA3GP:áöH¥ÒøAû£#Μþå¯+×d’E˜`”LŸÛ…'ÁÈӞ̳9Ö$R]À£IÀ›,ϱР™‘_˜þ7îë>¶‰óŽø#UŠÉÒét:Î:Ëv’ÂËXhP…P ¡MLœ„$$@  ´ƒ òê8ñ»Ïw~É‹; /‰!ÚMZ‹J§½°ªhÿìѲÑJL+ˆ‰òÒÄN|Ï~ÏybÓ&³‚˜:ÕzdâÃw÷<Ÿ{¾ŸßÚöšw\ÛþßwÎŒoÛêÀN.±ÑÙ¿­gïK­e¹+ôD4Û‹^¯‡TÇÐÛLÕ¿øùǰ0`Á¤gì_ÍOf[Q2Ms2]T¤ðCe~ßÑ·2c\6lÍ:jÝÃ/Ãþ0vÉX`—Mñ9žF#’~1‰Ç™’ÝJ@$ù+ŠJ`°·|­‘g4ËpŒåŒZn¡ 520PY/ù±KÄòÐŒ[ºÑÝ{ùà›§ÍæÉººOû¼ ):ÉxÓêð~@öŠ„"'9W“Ôê{  #‚»| —O~ ù—ðÙ:šúäÇûotÏåh#OßìîøÚëH¤°Z&k¼¥Ë2!YЧ Ä=ì—±×N¬å´á`ðn Ô»ºŒ¢é<^(àu:ƒáÚW™IÿÜó×Ã÷û5‡Õºf^Q§AÅÿ×;·–-biž#Žf5¥/#ÏÉbt_æöN!Ï( O£DðjjË®jBV; žG){C]Va‘V“%Ь‘[ªeÙ¬]ºí9Œ¼ãhèqNð,òÄž™F\SHŒNHÐgh“H>|'Qø$zÇ!è—púœ¬Ê](ÌEÃ?C]}œð¼‘æYž)ÐPz6UØOÐë]HE!€Öiä‰#_6™ûé›F®¼AÞ'ߌd­­úv’Å:=Åd›zÞ¨Yk¢–†ˆåYidó‘6†g Xxr9Q’øASPSý·Lù—ºóýc·œM„-öPX—/ÿʼe ”I9‚ ¡¡`ÒpzîÓÆg{kÌnµÔD{ =N#cÐÈö({}l`¹y#Ô:ð'lê”N]»äû€»$*.;‘äyt£9Ù3'ú¾‘C–5eã5¦?YÚo^o¤9ëÚ—±ì¸ã²æó†Úâ¥ýolö{Ѯέ¤8UªymªôÜÉÐH¬µm1Mƒ.<ºû࣋æ饒§ßó׌®’!¬ÌÎ'Rxþê§¿á­žá¡h¥uzT½ ŸC¡ È9”1…eàD¹&‘ãyùãH+¬l6Aý’(Í}pñ#uM?ñ²VaN ¶G{&ùÕ&W$URçß.+y^KÑ9¼v+ä±Ekè"¡¤ÍÔ0ØÛ2a3dLÕm£D#æX÷`ɨ¥*ÜûÂ.“ªÇé_êZÿ¬ 42qÕtæ³WâOF‘L¶b×1ØÀó9Þ@ëÖÙµ5Ö{(2PkÖGº›Ç­¦p§y̺5Ößu¾v™9€êOõUµ×Žw6ĺš¢]5§,¦H×µ¯®Ïƒ$p*¡$š£öš¨µbl ãlâ$þ'W?Þî2Oô˜£`z°^"±ÑÎÆÑÎÑŽÚ˜%zåCò)ø>N~m¸kûXïÿZ#ƒ5>wc_YÞrKÇhiF­D”GðHC?–"dU倯þîJueÏqдð ¤y†b%zŽYndëVå{wWœïnùƒm³ræ>wÇ[I;³oæÄžßv®=TUù«ƒth@ŠŽÒ®–YLo}çÌø–m÷‹-« +” gµ­ù¼× !ž”zv—¿Z¥Ì1­i+)¾m³“n˸;ñƒäÇ.è|Ô‘’í÷BŠÏ–òö“/øÕI.ÒÉ•ôKŠ×C:é!ÒÀ^;˜KªC€%`A‘ú°Dt§€: §ý‹ö·ýÆÞY)ˆ}ÃX `QÌ×dÓBn¤©U‘,ï7×h8]°Ú¤ˆA,°{ûþN~ùÇ6qžqü•"!EŠt:N§;å³e„Œð#ÖÊO'Ž !$å‡Ö”Ò–©MÂÛIìølŸ}þ'qâÄ¿HR ªºýÃ6‰Uë:µØ Bê6­EâNc”BìÛó^² ´…ÉÝÝ«Óé½Ó{ÏûÜó¾ïóý<ऄ§óTÂqcg$‘|½Ý¾‘×0Žã(Šh<Ñ8S—8«d§M囵¿ëÍj·“] €a4¤Wu´¥nS‡1öÓCí Äõ1{C´ãð€¤Ùm5÷Ÿ1wVǺ«Z_Æe$ O­«=½;qkGúÓ­™kÏgn“W󥑦®™RŸG¯î¿V9ü릷oîŽÿaõÄ_–­Û €­#i‚%öö¼¾7á8³9kË7þ€./÷;uããG*¹}9}_~/qì¬uOÌ&¿—Äùd*7™Í&û‹Ãý]€ óÙ1ÅzR¿¹„ë éì—9¥åâÐáxW]´%_ ÚXš…EàYí ý¢°Åå­qL®ùÔ3bz-¶ç„2NjFk” ™¹c’œºÞ³•ŠÚf`I|0ž-++c‹hqe!W¦„,lz~iªyÇg¾z%uB?®¤•ÌqÀÿ|eš•¡£Ë 8µˆ‚|ÃkV.^éªïr›º#fÀèö׸|]’Ù2»¿mºYd©Ê3†Ì® Ù¬í ZÄ€âÙ9(ÉUbè ×[ët²ÝÖPÆ”ò K“”–ãa óê½´d©$I<˜ãº™ƒ“{jÅ ~85•}ò”åÀ„ZÌ};cçÒ¥KKãŽ'¡‚btc Ù½›·þ²©é޽S „ɯ€‚ÈJNål@ÊÉÒ#wÐ\Ÿ¬x}ê`Yñƒ¶Ê¸Ù“ùΗjò¥Ž@ûæ°{>ñkIzèòT–®ÓSšbà†YB1z»ä³Ã'Žmb(¢DœæŽ”WLFz±ë™¹rc2ˆ’KTVqã@ý“ à™ûžؼ|õ¶…‹þæêT‚g ¶Y_PG’¿œÖÖ­ßZB³…<ñŧ¦zº1à ˆ6 Ÿ×0OòäB¡ÅZF 鈥iº¢¢âîÝ»O¬ûS·Êÿc›|´eß¾™ oà „UÈ@A a$%PxEÆ0xNÆðwÒX…ghÄŸFŽAJ³Œ-diCIÁ>3òŸÅ:>tÙÏì2-dùB¶mÝ ÒüI#1‚9ìxF‘<†‚ãHN£ XÁ|iŒ(~u};/'P` ÛqÅÑàjqÓÂZ§ÑT‘AÚ@JÈ7ŠúR›6h®˜àÐ#r…UÆÀ¸Æçµ¸p‚Ã0W¯ú bÈ+ßH2Ï@òÐ6Œ8Ímûãb¾êS3Ø¥j™Õ4p¦vÈ âhî‡~'>½M‘TYé25e=­ÞúmN§fk:5ÓÞ¹s§¡±I'h54]Ìñ,A0Ù’øÈøÎ­ÊÁß™27¶^%YÀhtÅêÙ‹»b¶ýÖ#ýùß^=b3‡ÚÎŒ†/|xùʼ5ý×Þ.¶q$?¹t?ûÂò•’íy7Qnƒœ—Fz­?ÿý‡X„¦ñø×â’¥¿£¾ÿL¾þÔ XF`íYš/Õê@@ŸN#¡*Ÿdé2®Ùû…xâ>~ÿƒ©'w ,î\>|E5Oâ¥Ï)ÉÌ8”uZ’ÔÃ`ŠYf{1ékØðy´ùëÔëʹW”s/)ãMJ¦IISƛ科“0`:ýjú ³ž¡YNO‘‹5ܱ^‹#hòôÕÊ>S×ìðV;þ4â5‰ÁZ :¾ªî`M0‰ßä8 ×zœ{¬rè²tÝܸ†_)üBNÇR FãÓ·þ¹œKg”Ü\ ³Çíéçk: „÷/=šýüŸ¦fŽÛ ™@›œœ¼﫦#0;ägL#¥NOÃ>(Z!° kW%Õÿ¹Ë1)‡A4±ô»EE’YVÅQÌIΜߕ º•p0ër`é ɇ;¸ïû¶iDñx”0H6¨¿ˆÀPüç¦M+-A‘ XÂ@Q<ÏmX±ôóînEöÀÈiä~a§Ž¡ÖðÌàqJî|fþ¸JHVAÄ÷P“¼ †‡ ‚öêöÍà™–b‚ŒŠ×‘•ÝŠ¬]±´H\Ã(Ȉ¦ÕåEÀXÕzUªÁ@åVÿ£ôF:¶o)X¶ˆ`XN§Ó]¹ren‡@v}æ©û»ÐrʵÏþ´¬´LKI²”P¸q?’ƒ(”D>PØ :×3Œ| äKÎÒH …Q_*9xèäi¦d':þ&ŠDQ4ƒ5]Š4¼EòºÅPTDÁž: 6þ 䊡p†U5Oaõ öŒà1™df§ƒ—$0,_·})É ¦K¡6W¡nÕÒ"J«YŽÞjG¾꽈‚Ãu'ðùfŠj j8… ˆ C×(¾àÇçµ(5‚\ ì8ƒÿÆÃo/¹z}CrŒÛ·>b;³îèÎW}ªmÕ±ÎjÓþVsÜV=ØQµïîy ’¡†çy–k¨?¬Ìîêg ØSS“?ÎåÆ÷/_þ~y¹–¢õ,@¢e¡)–¤õ܆úýì¡qÀZï6 ÙL}m è5ÃVË`ûžþVË?¸/÷˜¨®<Žß¤I’I&7777÷æÞÌ A)jĬŠ[]ÛºŠ ø@g†ÁAQAP)*ÑmQžÃ¼w^Ìð~Í30PíîÆìncÒ6&M·Ý­-ˆÖv³ûO[SÛЭÀ0ggFXl»ì¢ôææpιçžó;¿óû~NØvÚ×@óRŽJ“ é/õ}P4²c`L^Š€e‡îî þyÿà­áÑm}ãY‘ÏòzÞË®éæ¹@2 –]ûÒúmúÜNp~}QGãRýŸÕ^¥  ; Åmf«¶¤Ót™üGÕµvMGÝ‘îÚ…Æ)î¶|ôÅ=ASÓhª¼Õ¨i­ÑvÖ,u>À0Ã‚Þ»ÕÆÅiÄ­t:ó …[óH Ép\2ËGýÑx2üIÌ$Àcfvë¡vwˆ¡ß¾ù \Q)?Ž&¥ Ú£ýÕWm±«Ð@Šœ@ƒE(t Dƒ%(\º(”£H .Eáʆ#Û ³‚â”d+¿Ù\Pï8llÑzE¥É¡2<qjl¢Úâ+Kᩤ »j qÙ†ÑÂ~ð¼‰9ǽ)„aà <Æ•ÎḲ'*C„ØG¸ú oè¡à(1Høú O¦÷ú¯™5Ûˆâsx]@D޾g´å«X™ @˜–;4D—h!¼#„3ŒßMÀÒ‚ŸƳ…¯ŒÛ¸zñ´ý}„ú¤”‘³4ÉÑì†Ì̲æú’κüöú¥ªÏ¡.[ýŽ+ûºê ¦¤Ã¸áÄH‰`Ãv´µ'2Õò2öã½™ù ‰\°ï…M)ÏK¤© Ëò!ñQ¦à¹g‘¥ª°Ë¸»½VÛk„iïö_RvÕæt^ÙÝ[¬E·rS˲IJÙ´ã-7ö Œî fÜÚ¾½TÙ¼“54ºwè/yýã/÷ÿ53t÷DðÝç2÷*hž•RCæ+Ò6תzô@Gù­uKõÿžšC†ÜÖuÀ¬î6ÂB”Õ$G[kÏ477ÕŸî¶Ô¨»j¡‘üÖ†¾þtÅ¢÷c%-ymÕÊÞ%ǃ¦­–gx–Å4ù hDÌ7/B#^µúTæ” RB†'©ò’Ò©yš»¹Âc¹«-úüÞ½µ«×à8æä y/$Sï ÑÕ‹9Be˜=Ï¢Ði:‹†Ï¡È«(\†K¤‘P))G]ù0_vŸÙ&OJä,C¯”ÈÏg—YUz¯ÒîTš]‹Sù4hÄ£­y€–g“Òâ´+´™•rNoSd¦RŠdNàÁh ÄÃ3ë7\{ã*€xæÿÔ‘«Ø<›Ý‚DëÜîLƒ|AôÌDá°ŽŽ^¬¬\•š SÈ1‘Ppƒ*‡Ó¥ ’ŽmÝ<\Vö…ÞˆD7r¹‘hE^ÐtòX‘•Ì$P ÐÒü¤iÄ 2 aî ]ãïN•å®KÏLN{q%ó¡¡5·öMçè$©Öq2mÝ}›éù›Å„ßõØ0G‰Ë7± ¹<1QŒ{ÀŠ\`ö˜Y?e>qO‹@>{^Þs,·‚æÏ¾²Ð™MÈßþA?^Sýµ®a kñ'Ø#Ž|V\2Ããë`œû.Ï&™@ÁÎ2‰TªÕ Y°œ±åMÝ?ƒÜñ~&‘Qß@ò-ÅáMˉâK„¿sˆeˆhŠMÂŒ³Á|ÑC.®ôb„h &zý‹œN±D94}q¦â`\qDÏỆ!ÆôWa `h¿Nx‚x(ü­8ä8û0·¸–N#Î 60¬7Bø"ošûˆ†s;Ñ!ŠËy^ išþÊ|…hôĉ –Á\䯡háïÂr<¼38$Lt F7¡yU’²&™¤S ƒqÔ.m^E¿9¿õ’ª§z©ê£ìnTuÖ){ê²Ú¯ô˜Ê[BæjHD¤ šùtüÎ,,+c?J˜=äñßh4ñïä!Z¢ØbáHxsÆ¢xJH6…cxRJ˨5Ù[TçUþ:’ü€á@@·«W”²1oÃ0põ IþpmûÞþOv Ží }œ3pg©4²7ôYNäö®÷ÇrŸçŽî¼h…Kˆ ˜¾±Š?n¯*ê6l«.€i, z?r[¯¨ztê^@‘zeGõ±^¦[§ò_)Z´Ýzu·ZOTmU ŽÓk{çã¯îÝýöïo9v2`HÛÓµ ½,F#,úÈ1¼‚b¼³ScYŒF4.Ï!ƒ£°1N…a§V+R¾ÿáŸSS“ö963'y³58p‡x \~­ ÂŒ¦(иMBҘأEN¢ÞB4t œCáŠXè U`& ŸBC§¤‘áSøõ‘ (| Ÿm9ºU  A(’)~Ϻ,Û½¨4yòmž#6Qix 4âP›\ù6¯ÚêSYEÜG-õÊËË¥œ T„‚PN¢y)'0™›ŸôGÀ!Ñ©©„g°Š€ó÷Þù$Îìôôvx4 xc}ðþŸ`1œoÝ{{¾Ñç`ÄV:Ôf´˜Ïwì´é®°5rHƒD‘^)*¢TPbJf/ÖpPìsËsêÄÉ¿öyæg&%$ÊÂ8Cùš¾±Œ¤£‰ØÎ›Ÿ×é5«Ã‚ àHÔ0§Öm^½ãLÝáö†>›¹Ï²{¤ãHı©Ò€Y.KD†[_zjïøuЈ1qckì“ùjdÏ…O¶Ä®o‹þÁxáãÒøGå}ï2ËWeqlÆË8õúª}ea XÎ0@X6ÏΧ· ÒÎ7Y ƒ­û‡,À*øY6l5Ù¨­†ÛJ[wöž1Ú+FæÔΞˆ PTj« ZêÏK;{ß.±–Ì}ý³5Âó¬ÈkA#¡2éÙñ›åÐÉw¨³8§˜g½(Bغ0y‘(+áãHš9O²¶Y‹’oýQ#Š,Èœnµ¸ô=»L%ñºt¬Ž\m!±£$VIUäB-™×”ÏMzä÷ÞlzŽçtj¶âÕú{§ÜN`‘iŸ“À½Pô€„òÃ;kådºGöš ù˜…I É‘†yå>™÷™RóZœ¿û¤B)r;Mî§Ów>ý4??GÃp:^‡—1ª›ÑÙŒ"oõL(!ö1º‡øë‰* I @œjÄAýšãè´ãùe"æ Qi9òŒRÏØ|Kv› Øì¥X§eõZNDÆ ÔæB}Pá$½ÀÞª¡Ô5¨<%ªhD1œ <˜¯F1ÚÂP9HJ ¾I )Nß%˜P}oŸ¸,—å´BQjõ¡$’Ggñ„cÐQR±ÖÜõ÷Dh ýcÈÖƒŒ5X_¤c°3ZÌÀ(Ä '£å‹ï94ÔnˆÚæ}Lkùµ|à»’‘ö²°ua;d@®òÛ­¶ÌÚ¸°íY[šüãëo ó ´¢æ…—ûË/nÓÄ©‡3©§"—²B‚Tȯ¯]3‚F`Y†ƒ¤ŒôtËéðò5ùÛJwW9ZjF¤ZŸmÓ¾Ð~ÆzŽÑ­ÚœÑHÙÄõïÇÿ4_l‰}¸+vʞćeÿÊÝ^ ¹H«æ9†_¡«µ™Æ:÷G¬ãà‡ !æUEì‡G;ÚA `ø¥#Tƒöò1ÇÞ¾VcÄ Ÿþ2ÙŒs×o²Â½Ã6*¸T±—÷µ-@G°ZcÌ€F´ ñ˜ÓœÑÖcrõ›<žöÚ­µ@úpóËk×eâÚãaótøƒ9ý`*(ÝŽaµ‚iì™]+ÉÄqráUG²‰$Ž‘ñ ’¨&ñ*2QM’µÔ$µ”“'æÔH¼–\:N¢õ$yœŒU‘K-5Å:­V‹Eu6#žÚR/›ASltKžñ^‹XBfg_wð«ÛdÙ»r‡žËbF±Z­*ÈÉ ù$øÓJw¥Ÿð Ói):#”áB…ÓÓûË_[ššá‰ÐÉ<øçoܸ‘ù4á<º8MM“‚ô£ð}fîÔƒÙy˜"3éo¾ø2‘Lš«~P ÓÃ'ƒ¡Â±WA§…/Ïò,ëØµû–µøƒDê" Éi'á¿®‘iÄn/ñyR²“xý×Û¬«8&‡Ç"ïÉo¾u:ð¤z‰Ó{åHõZ‘¹ØPóy§x}ëá/ö)jò,žŽ|Dv‘€›xºHw;‰Dþ,¹êŸ_K¶³E">·±ø'NMû#å7h8NϨÞp’BÄíwY".‰x@ ²r hħt£ã|§±%—QâE³ +Ù:` <¤ƒ…LOOefßc[>Éþ¿Ín¾y0›M=üèýßAW2X—%ªµ*¼dw% D¨ zâ &g5"Çû<5 ß ¥ÄQÇ8 ƒL‚¨¾ŽÕ¡“ç¨dzc¨±‹Óo`uVC”Êáy/a8Qe(GŽAÔÿ$_FeÍ*mn>³Õ¶R€Füã(¤ð±L ^¸7JY€ÚFQ(Š<À›IèE’›)\«ÎY‰,vBÞ+(0‰|qäU®‡·¸ˆ¤(eÒ\õ‡~Œ:û©Z•[€Y5¬a0í³9,œ6'7OÈËS‹¹Ð¢ÆÔòFŢϰµz¸½²ÿÜÁᶃÿf¿\c⸮8>R%$$¤Õh4ÍjV»¬`-ü(©íÚ•C]\ǯØÁ±Á ì!Žã6øëø¹ ,,ûš}°`Ëò0˜lš*Š"UÍ—D•¥ªnl'NcÉv«¨JÝÔ®k`a÷ög ñÓË‘*¥W—áÌÝ™;÷uÎÿwzížãâbC:‹@i)•gÑúYBâ<qAÌ@#³¨EL[ûbÎèðÈcü‚P9=“ŒÂjz‰? S“®‰™;·¿8QW§EZ†"YœV¯át|R£1pšÕéëVòZän¢Ž²x6U4å÷¼uèzIôꦡ/J#Û†?)ütûÅ[Û‡¯-=èJy04U“Wkv—v7mí©Ïï­·„­%]ÏB#rÄÆ0wÙÊz,=*Tô5më´Yºì–žæ¢H£ÜeCçoö·”ÐçíóõƒOiÌ=ÖáSyáSE‘ú7•çˆ¦Ý à,‡“&êu®ÕÒòïiÄoöž“•Ö–³ågM’IyвZÝØØX2"6ΜÙL-ÿFøÈÖ›‘N šØ”«¾#dè0¥Ž¡J2|ˆ\¬$—÷‘c$z˜’ H#ZAi„þZ=/\>LËHt/„];=üÞÛ…F>…•RœT¼¼@1;‚²4*õeçw"~Ù ø áZê>´qßJ1ôÅë9-/俜÷Õí/É¡*2OL’]œY_£þ&¦¦ž!³Å‚?øúïAŸIÖbNå= ˆDw–+//2¹˜uj|?ž˜Ï‰Ä·û…=T ÿ')’$0ZUöfÞÿÝššª/`F¬ÄÁ¹tøcZªõ¥ ÷Ýà qÛ‰ßIÆßGgÔ6JŸTúhK³?}Ó†TƒI'2#+˜ÛD®¹¡ñ/wîíܼU«áŒzËqZ£¡úÔ‰‚°KîjضV…má†M}M»ú÷´¯ê;[ÜuRŸ-4ïî°[ºÍ‘F Èëá³…ÝÖWÂVs¯£²½9{SŽ ‰ªÎ ²,'7nŽFž¡Ì¨/ÇTHö355ß¹zó:fÄHEÊZh˜N‚Z>úð#DæXAx†Öiš0Εd'wïÞ­¯¯_´h¨oá*!ÞbЪ«Ž“Òu65Uo0äÕ¹vDo®¾?xm>ê(—oäE?ùâ盯¿ß22¾>úqîÈgrÿí£7rÝýéÚ¥™èß êYAkþYÙyë[½s‡µ4Ò¸«Ó r ,±@õÿŸ«›È‹:žÓñpN±8|g[ἪÝ^h3û=²ÃSêx-§$S£×.´¬ÉhúçƒÇTM㳇­œÆ®RÆœžÛKº_³¬(ö€^°í²«Ãì’€´¶G«¹É'ÛqÛañúm­%à7¥¼%+çÌ ®­%ž¦2Û†e¹:VÀ±—4‚ÅbyR&°»–ßÈ 5Td˜œžŠQ’I`¹cI`H¡‘KKLÙ,¯c ^«1²)&AJŒ—XÍïýJ¥þ\k*NAh¡~­f (ñ‡¾3öKSF&V/±ðcþ×µGˆÛO…ÕÛ ™ ¸¬æ_,躠̠ qÐó´Å?¥öù‰há›t¶¶ÎI—ò›êƒvY®ÈÉé.}ý¯MN €î?°B/fp<+JËŒ™ï¬} º úy^ÔPQÁ¯ &…~WñÆo#!qzˆ³•5ä%®–[ÇN¶íÚ^¸4à hò¤Kœ¤ç„4=" ¸’ç?©·“P(áj¤\¤¸(>yBt|.âE£ƒx±ªç7ggÁk@˜Ë6ÿtçnÒź‰ßÛ’¤ñd¢4‡%¬†Í€wê¤T>“9Ñ„†¨@3 ß ‘V¨s”ñ^¤íÐk¨y’Fð€O} ö_¤¥iáé&6›©±1ž0£œcÎ(œ$ñúlfï¾”œ­Fýâ4½È¦ )«s)Šø#L —öºÌø£ô+¡¾çF#À WCŒ2@kÒFcÛ#¹:»Ð­Àÿ¦õã»Lm_„9z2eíÏu¼>éŒN/’–å ¼ˆ¤ `燿ûmR£oßülY† 'üN º-µû»íoD¬?m?úê@ËîNGeGóîîúåÖêõ§«w8Ž™;ߌ8*:l–îÓ9Cg䈭 Ûjîo¶´Y_=²W£eÁFQBW®\A´IF?ŠODÂÿ¾Äh¬£±¯Ï²èÌÌk; ¼€!>ë%¯Œ¼hä9^ Geëjë¾¼÷gL0§Aó¡zl’‡gî,al=òºÜës×áE“W•F6é"%«Õe‡ÌÃ7Ö^¸)G¯ÏG#yÑñmƒãàmÑOóGÿˆÜî¸t+àæ¦‘ñ¢Ît«òDCV¦(êX”m*PŽUõ;Kºê-¶òÞ&ªã=öï!@©CÅ^Ÿì –yÞÞqtmæQŸC•jkk±ƒ± ŸØ¬x<¦â¥*d3Ó8 øýUºY«Ü²‚  Ñ}ä8¤‚ ¢öhÅ‚i$z€Œî%Ñýäâ>2TMF÷“ê¥F Œ Hý‘v±§¸ñ\‘W17cjà„ùæå•[€XÞ¢f E Ä… Ã#7µZ Šbv¹Š›Q½ÅNÜÒÆb*žÁ+0‚fº,’@¡«Í¬àõË™åÒuœÈiX£Vÿþý9™˜˜ø~”\·ä±OºRò&F—ÿ¦ ü„ÖÄ;c£?^•)²ÿb¿üc›º®8þ$¤H‘,===YOÏz–Ÿ-'Y Ã-m—ÒF=M…;„!Úf@( BJ‰ígûýð³ 4 $v{)Tü1ikÕ•nt°µPúcZé6µÒþhÍÿ¸;÷½, [›)[´iZ¯Ž¬ûçÞóî=ç|?*g²RFŠcÈŽù®cérÖ ¸¸êñÇ´…àF ¿²Ó¹Ì¼›Ïçv&›½ÿÇ{Ǫ,bÍ ²íkŸA‘³X…E0É”´põ—ÃH £P[PS爒•H‘ñ\ O†Eúß:x°¡´ØBÓ+,¼…¢­Fzs?¶»áÏ è²p§½ó+2c¥ÈGèüßöt¢P0#zFlHà3,kð¤d¢dd!­ho}öüÝ®Ó×µ~r¼)g¬&ñ3Ÿ?UßÐæ\W K™T)M_llþ"܇ü^¤ŠøÜ´7Í…$8„i±E0ƒåBJWEE wjìõÿG„&sùöë1ÏÐ[Z}̤ä–ëIêÚÁñ+ˆ™èO`“DH“épŒˆ kŸ"ä/³%ž–ã~É:7¡^"úljhŠ&‰g«Úaáì4OòLùtÞ¦âŒJô c âe¥$! cHˆ\Z4Ñ)¬¡Ø,>…´OxǾ¼Dø† )E¨WˆóW ÿ q&šW*.3“f+M[M”ÕÄ3 žç,unÏÛ×~šÁ}PV?ÍôÔÔí_½GH\ÕÀîà·Wĺ\çz\½mE•kÈb–1™U"ßàp®XÛÙì¹ÐÙr®{Óùϰ·n »Þ{Œ¶A—ÊÀ¾6š9zô(ú—ðãï†Þ@=tï94žJ=j†Í`¦ŒKí¥Î†ƒ–N–ɲ¢AK JÂbtj2Õªì,ÉÌõ óIM<øâ­7ߤJ(ЃñF–Q ™?‘2¾n$HÉÆ=¼£I:PlUV¦&&1íg³ÿ~­þÿX“æÛ¬¸Ü¾uã[Ëk˲S4éXM(ÄÙ$¡Žcö$Œ X#Š.ëºÍJ?ÌkwP,÷ š"êë1føGˆH‚..©ªæ)‹ÕÌØ¨<ÈS½ðGðŸ¢#„ªNä2¦‘P o¤\\4™ë¤>×É$ÔIaðp”â„8D¼ÜClÜžo^ÆæQvÌ!XøìFÎBÒVšÙéÞ¥;£s½Ö{LÅ×._†K§ehL¸e\eǾê“uÞ#PŠp‚B.PVša8eÅQŽò²m‡ZvëÞ;àÝéo39xøF#óHÑÒ{÷îÍ^ÞåaXèÕ#]ˆ k2h£žüvKæ3f†­mÙ“¸Ñ{穦“†boáiŠäyp4¿ü©'o^»Ž2³KegÙffÙlvVîþ:ÏA§Î¬._4/žg*ªí£füÓM£w¾ŠFÊ“w×'>®yosìÝÊø•‰ßTÞ]?t§qä—O?ßM™íl¾a©ÑȲŒóû u¯œvŸëÛuÉÛ0Ô(âºp ¤\ÿüß¶…ÒH]oÐÕÓ·MŠn•"ÛC§Ü/o(ušHàHG(ÂäÛׯehnZ—N¸¼‰©)¤¡éÍ_Üý2³”V¥yŠ5¢Ñ&Fö¡±£˜FFw.˜FÐø>”jÁ`“|Åv¢ø>×3+#Ã2F»Á,zz¢5ÙãƒW›Fj}`a—ˆ›[;·5ÔW‚ÔLྔ¶úûÜ¡~·© E\¹Ö ¢Ô ¢«G©¼õ§–Ñ&h¼ã†õëædDë4œÆüj2·›ÓÿRi†Fr(—¯Z ¢§èì ,FHvÞùMÇÚªQl7>Ûñ¶×Ž8M8„9`»­àÁýû¹ ÜEn*û%°3ÿ˜J§õKÔQ$;5½Ï^K†³Ðåß\ý ¢(© ÂBU>êE’õÉYɇÂ" KHñDögD/ReO”çJl4GÒ uhõšë­'.·´nq¬¼…ÞlC¡5+õe„ÀŽ®«MM“€ݤE£)€"rNxa1†ï%$È¡MÏrÖ|c°2V’¢(3¹ÊF¿~ðÅloŠª˜¯0n‘¨fBÚj~/~ÇI‚æ'KwŽ¢èE½}¢½Œçò)ƒÅfƒx®©®Ö_‡"äëñÏ„®®k³cbb²ipl¸Ðh´A?Å’vš]²z!Ñ¡& i˜PãD4=†u\ŠÿMåu¡‡G]ë[ϰ–Bàâ|‹ðG‰È«˜d„!Þ ŠD“¸åÕ¿@¼r‘8¯1À@dsl|‰‹G#ÍO96ãª>ÑwéOáÝ…þ2rh=¾äé*ð’7s, Ž3™LÑdÖ€A±ycÞ Æ@0`³ëõ‹ øIÀ‰ ØÆìzŸ3û²¡< x½/SõKú¡URQÚÁ8PCƒ ý˜T yÁ®w÷öܰÒVFuŠ’ÍÕÕîÙ½çÎÜ{ÎùÿNó¢ÞÀêr)xCà9†í¦QÌß¼ºöH‹~É £Ñó¼¨P͇׮ÁBÉdBQÿ,ñ?8¼j'ù,±ã•$eñ,xMnñ†²þßm ß_¸>ô§òÀû‹7Õf1zx0ŽÊÒÓ3³!·RLÞ–Ç©¡§Á òá‹gû7¿R[cËAüŠ¡(!§Ôݺ½)2:l ?0Ý/¿tcGäã-#V†>Ù0pgו›;ÎP쨆×ä1TÑJû:,ºªû»¡Š˜Îv„Ô\²ý¿ÒÈIÙb –I¾n©ÖѺµeMÎr+€6ñ(HÑêjbÇl¦Üõ¢Ã#"Çe³†Öun»tsÛð½©hdëà_Íc–È­òá{+£Y¯ŽVMç0¬Nå«Ñ-Ðííí2÷w›/žPÙ£üLôÉqÕEëO?2˜­}5nÐkPö€É-YìΪîÃ%oÏçf(l¦5sæG?M%ŠVhDmÿü 8V8h²š5sÑåVŒq ˆ}(zÅð`º42 ú[FÞF‘zÚ ú‹<‰i„ç Ĺ“4â®°¾„F¾€I’MN` à.·¯Æî®è:°í@ÕêªâùÅ+²—/Ó/];{måªÊÖ­öªN¹€Ä@rÊâíµH’¥vÏ[i—Ë ÙVÖe^²bSË $&“IM€“‘5©)S¤M5̱çC4Âõ¯~yuÑ‚‚ÙìL‘&-HZ+“õzöÌËïY2!áfLw‘¯GñviA±ªß:ê iBÏÐEßSÉô´Ul’‹žüãËæúFx)8kb(rfdžâ„SB’„<6äub& øB§»0€Ö{eÔÛ‹œ.<Àº‰ÂSºÙÑ­!ûLu@ÈoO8!o ³´ THøM‡’^+žî–Q_’ì¯ã© DÿÕшkßvŸÄ«ýÈãBŽøÌHÝo.+Òqú3e&$÷~xø¸öG€-(­–˜ƒÖ?ñß—qœÈ½ü.ܽ®”«›r;$+(âøF4/^%$%ðZ†ÏãÄ;·o£þ¢:$ÀŸYä¿l߯^'n~›A_$­û!cIrŒŽÓ ÇéÑ"ä0áŽr ³„¿ÿ_hDu _!ì>òµµ³™|‘ÖQZF£'ØKæ-"ZÁ!l'8ŒÙÃÝOx#D.£¸"E<ø§W$L8ðˆâ>yi$Î ?a~“Ì+¤8¢x>Ã2B6­a ,SÿVÅGøÍ“äWj- yçéD"™žPRFMJ˜å¾{†µhŠU‘3èJ$õè<l $Có<›C²3tyDC3èWúÂ*Í07òâB6 è‡å4ƒVKƒ›s<<ÉÕØ0Xú&­BHúûòòl9UÃs3˜F”ŠöïÝÒÃÒ Ï°Æµ¦ý¡%¡ñíч¦øxÉà-ññU±1Süξ ¿_WßÍd/%±Rñ,õì|sš[þöè±Z¨ñø1‰"ªkáýIOܹ;J—tG³ú’:sèÖ¦ÈèT4R~ù³-onøsq|lid¼âêã·N}`|½F¤a:¨,ÎÒ—ÉGJ~q´òBgu—©ÿÆ’þn•@vœ>f9 ÷»zœøqiÄk²÷Vºe“=PåôUº=;m*w Rj*Ù3Ÿ6h‘ÖP4Kå/ÈC G'wRcnÞØ^в…9â³(Ö„bu(¾Ea܈.7M›FÂM(ºÛ‰À¸´ p $È-àD+r =–“}&7@ÐH¯Išê½‚&@;@‹«ú¤µæxÛö–‹¶r ´”N¤D^8¥8 Œ~÷ÊŠ÷Ê˵6¿ÅÕgñx+0ÉÀ*§L>•çÝm‡æqFúŸì—yl÷ÇGBB²´Òh4f4«Ýµ|€¡1‰IÌáÄL(6Ø`_Ø€/ˆ!ÚæppY{ïÎîúÀ± ÆxwØ5¥ -Jšþ5ª-GÍ¡T‰R¨P[¥ )àcw_ßo n‚êGQóO~úi4úÍü~zóæ½÷ý< # GF–åÉœšT“g¢þØ£Q•À£¡3ÁŒôeèXÌy¬&Q` /21™ILèÀ†q¥Noƒ@ (eˆvÑÐ^í‚ÁJ¨‚s‡#C5 « ‰lŒ$Åó¼®ÐhĶð;äõä¸òÇËk²²±¹@Kš‰“t»_LþØt|¨ÑfðXÀm!8árÍEP—ñ1Fþ—ÃþöþÃGÁÛýÐåú«Í|™Äîé-Þ4W`=”“?*Û@nzZÁåùiJŠ^oH晑ƒ‡‰Ê»Q«-ê°¢Ö:šÀëÛw¢£ÿN#Ÿ¶´Ö§-¼ÔÔð•Å0HüÍÙÂcQeØ»¦Æ/­–TIg`Ye{éžì¼D càù8Ž®]ôâ˜ÙíÞ1W3øÜÈ!ÄH´Ön#'{e$n˨ËÕ’›‹ÃaådHå<¢ªÏdéÙ‚dzƤë0㦒îñÍøøýD¢ð—ü}ÝŠUqÚl§’˜YÔ¼LêgM”ï4á÷YÊ"ØàîùŠ|}v…(×Iêx?UkõªQ$Ò–‰ñÌ‚å”ÅNuöªA q#r PŠzr?å;EÉý”³Ÿð¢ˆwð{£‘)™š“+=ç(S‡&k3-é%F3‡£c9ë?Ãi¬ûì6ÑYôË8!TÖè8o²@Ù ¢>zHÜ‘1‡ãшú&¨• ÎÌId×kµ(¤¬aö¦×(_§ú±h†B¬£Ÿ2µÌ^m”èX$vßçù¤¸„÷Î_ˆŽODÿ²| ŸY-§ýõØy©¶ýîý÷µ¤€³x¥y!ÏÞŸ=puMðÓ%ƒ—7*— >Lº‘©|²Ø?’¦Œäo;/<¿q;ËòIöØQòˆL$x­(+¿ôáEB8ß °©&®,’ ¬FϋҲ¢RÿÕìÀðt4’Þ}ÃЭåZºr##øINß•Õfš‰#ÄhiZâõÙ;·O¶¦Ÿ:bì;RÞeBÉïm4¾u|c7¹–ŸjËïjøáqâÿK#No¾Õ^Ðâ,1;Š[m…rg¾Œ ^™Qò>^b°%Ž™?þÍá¹Ob) Ƽ  X`‘Šïú¶ƒ·²”ÝெàîÓn mS©f„Þ€Áê/:+´*Ï΀ ²ù`- ¯Í\…¥‹çÙXŽá‹šKz.nV®¯ñ_ËÝ\áÎU>Ê9}³ðÌ­\ÿ,ÿG¹Á×+·6®®l Ò™•˜‰hªžçáô<­eéX½>g}Þ;¿yø C¢ G@MKr>º[žš¦–}^?oQòûdÞ€(RØw¬èD3.æ0­ë;šsâ躓¦Â“䵂>¾€â^Úw¬´·eKoËßnV¼eb‰ÇX‰%ø'#]˜ÝæéT{Ú™owm¶V¯,Od ¨S’ˆqƯZ™ùÅçÿ|³ø»&½]]Ø'8DN}{q ¢\î…íDIû ´gæ4ò: VÁÐë¨e íüCÓ:­¨Ç€‰gÅÂ%9-% È!Î"‹»ØæTíô9|Å6OA›\Ôê->&›p–¬ÎOn±t Áuƒ ˆ'ªTƒÙMF0ÆÉ³!d^Ô²ÂÞ¼]›eß§«Ôb)2u”8¬EfO‰Ëk´µ-ÝeÎúõ5‰Ë„tƒNžŸ0÷Ϻ¡†+¨½ÆòýéÜ„!…E'áÏa0‹xTafë¼Ùçk×=ò×Á™]¨¥ ”j‚dÓú§ {{ÊÒy–æˆã™Œ´›xº,‡Ÿ¬LÛBd8¢M~U¯×J)tÚ+èà äô!g/¡ Îrv£NõÍ…Òˆ¦D¾0rDµu  ¶ ²ô¢ ¹qrªÕëh†ãé×6¬½{ïÞƒ<‹"s~P;3sXò-m.kÍvàƒƒöÊ)AÏpqeã'Fllܭ˜K«©T¤5*ÙþpGߟ*œâ3+´bÔ¸zކÕÒZ(Š<Ŭ]³îò…_MMED‰MEñ8$XphQFÁQ'Az¢ä=?oº7lßÍ g ™üïë~–Mk)p"ÃP Ë“ßðYL ç-y§7vוôÕoë9]z¶ÞÔu¢ôìÉòÞ°m=õ¥Ýu[»OŠõ Éï&VÐS¿µ÷‡ÇŒЈ(‚ÖÄ€ìzJšŸFÿô3‘ad–ã1=^óEo5¾|ªp° G~ˆ"`aUˆC»I'\ƒÃ{ûÖë°YuZÎôr¡ÓÜÔ^êò:|EvoqËÙ¥½Èæ*¶4—ÔŸ.­=¸eÿ¦¹i\J<+dz¨­^U:ðÐ0UVF¦Ófÿ˵ë*œÏ|rçÎÆì ¸Šù+rcs›Ñí25ÛKO{ŒVp‚§ÄÖV¤¸ó[£ÅQÞ´?»j¥n…,êà‚ÁW‰‹þvkt6xgcê1 <.:bÁ@D€saiËë9@k³—ÒáCÙ_¼…/×áˇɖ#{€¾ðPÜ7¯.‚o«¿î¯]mÐÒ"+ ’Žb\ €ê\0õ\,ÏöÇá˜%“°?þî÷+RdI (-äj†a– ‚ß\uz&Ü V‚"îl·Sˆ Ev@ǽÎI¥qÂfumÚ"è%¨Q eYŠ×Ä…·•M»ˆpÚdI_•f€Ú †æE^¤éuï7–ளϓF-äéuEíg¢@P>ÃÜ®X»çÊŽí­]¬¡ÖäK•ÛgQ¸§„4®©y–c…ÓöÛ _Zž¦»Q[7ÛlsaÛìs‘ýÚšq›xŒøžÀ'×Ý3µyI©²VCh‡cR’£cc±‰‰é'¨õE{Žmö¦ã'bðÊ¥Ë M¸Dž¥i‘Ñd‘Ò…¼—;B`c>Àh‹ OyÃH9Îx½ u…Pëòö!OjíÔ÷ž'æ #W2V!QÒ–,i!ÎÀj5Bâ¢l3²¶!; ¼9€\½È½@Îi £Ö‹dÙÀ6žVmÞ.QLä5|§ƒ(>pìpT…Ž9]‡þÿ×Dó´' ä)˜À±Åi ñ¬™‚ô¨ÉIhV[/yUsû )¸CÈw…ø¤úMæÇ« ÀÓ‹PwQ,Ãó,o.2ñ÷ÏIšˆÂlS±i•,žâ¥™G…î·,”€ÌøT49Áî•)JÐ¥­Øv¤,8’θ‘ËŒln†ó‡nå„ng…?Éú8ýü›ún” gùG+B£¥îw’swRRA^Ðqœ,ó ”y óÒªW|Ý}_~õ5L›~óÞŸÄkÒ–X6Q91µ¼û½ÌÀÇóÑH–Ä4t'7|'/8²lg–áuà ^âXF”Å%k—g®,oo,l;¹¹ãdY¿Õ|®±´§ÁÔ}ÌÜ} PÄÜsh¤¢ûDùÙ: ø½ä\}ñ¹†¢ó FèüИñ=­¼­–{šF|EÍʳÐH¼U)³6™ÊnZÊ'ŠD.(žc×­{õ?ÿý*ª^£©É©c‰N`F–¦ºö¾Ž ©Õ8´ ûË𥃠¦‘Ð>bþ 9€#‡@š{*×ðœÈ󼞖díó”::ŠÜ…ÎàAƒRÖd55ÛT“¿,o©ªcd¸N"ÍKŒ ŒÑ14‚ãÇß½©BÙž¥‘Éñ‰ÏþñOIeNdiæ'|Š%¿¾³Äë(²(Ûš…Wq“ÓØÔfR¼&—mk³³ÌÚRÖX“YÌÄ/á „sD.eiB02Hà7E ʵk×$FdÀG—À²iÔ"ewæ¿úáWÚ‹wâàâ´ ØÙ??­Uÿ ½}áh>M#Ó-fô†Ô”û÷ïÏÍøðáC5¬I˜?ª‘¦cxzfl|âC5ËKà#“Âhs—&¾ÿæ1ìmÙ@C•…«|³ª¿*„¸l3ŽY,5·`{#öÚp‹ý¾Ò±yåjð0G³q"ë3oŸhmÅ®Ür »›ÿ}úÔÑìõ+%¢¢Ì”®]sýx-öv1açE#…‰“ðRÌëŒÙÕeÛ¬ä›ý7•{Ruä(%†–hí»;÷aoçy§éƒ#ãE.N ”ø2 ¬·wõª±ÍNÐK±Æ•=?¢M§È¾\ ¶;Ç<Þ¢•É< ŸN¤u< ãí›áirñ¾»F}Ñž©MÅ¢³Ú6+jÓPÑÎà#55‰ZZ’e­ÀH£),G­½Èzy/ÎK#>?A€$‚\¢³í¿$ ãU9ÄPyÀ\ƒ*ZÀûaÔè帴$–Jb5) “ÈñÍ3lÒ¢‚]ÈÙOÆéz5Àçï,˜FìAä$4« @Ú_ÍŠ ‹Y.žã 7¦çæB¤OOL›šV9äû¢~LO}‰ëì×}lçð“"YŠt:=:ît–ϧ8:FiW²òR yâÆy£)­ ,÷Ävûüš$8~‰ÀªUb“:‰I]Gy)„8¼lÓº·NÓ]¡@Þüì÷Ø1u™È„ÔzzÙŽ}÷ÜsÏó|?¿Èo#4Ãh¡W®¥\}d@œ±Áw‚L ?ÐC"y &±†¨¾¨V§*Í ˆIÃ$±q4,®$­|j`hj6¾)E£ÐÝ驸…â›U¼š›››w}ÌÍ‘Êú3ªûʽ@Š@ÁÏ!÷MƒTo˜j0¢—×Aõ§E‰¼À¬Ú°öîýÑx5Ûƒž ô§ÌX NˆgNžpË,¯í—í¦\C1¤y 쀱aÒ%‰ÓO@/x¦Ì~ª;Lõÿ”ÚÛ¤zi%l¬:žÖЪÅ"lVhCNö/ýñìô4ž‰=²oÙãéúßžoôoŸÿUæu°iU‚Èisêíy¡Û™¡‰Œ‘ð(’˜Ð‡oçû'6{Ç Á‰-Á‰MÁÉôÀ$€$-t'säNzð¶aäZ¶ÿzFè÷©ÞÛÇ«FnTº>\_Ý’¼ü „4ɼ˜ÂÒÐD&‘åxö-Ž•VƒXF®Òöì‹$Ÿ™œO#9#ãÞHa`"¥ü¨È 2“À"•–WË‚%$&s¢ñ:VPÃÅD¨R»J÷ýú¼#U»ÝMUƒ¦²Ávý@sîÉFÀIá@³þdÓÖÆâÓ-eƒÍ;N7m8þ3ã9[~s ”šhfo3´» ¥4e[§½ÐÜ_ìr¿E@Ò¾½©pÕ™ÑhYP2Ä=W_¿æÆÔÌìÔLtuêFžåAŽPzX·¯#ðU᱃طsÁ¬#é '€>·¯8U§%©t¢æÝí{U¬)KÓ½¹LX ÙÊ‘ «v}(la«a“*Paaa0¼{ï^|ƒ‚¯›žüq0t+ß7™í»™5üYÞp¤Üw‰YüoöË=&ªìŽã'11!™äææææäÞÜÉ<2Œ‘U'¬šº(Dä%(22Î* 뢲 ¥´õQ†aÞOð¹ 0ÃÌ0¢M6ÛĤMc|l²(*ˆ®mcšºi]kÛàê0÷ôwf„Ý?J#ÍnügO~99Ü3—{Îïœßïûùeûìs{M55’Zűœ‹j^ЉJ¬`EøÇŒ‚ã^b¥…Ê…ë²swWTµj>Û¹¥·#e°Í½'K{Ž¥ícÆ[ZaënÌcIà•à7,8í@#^“c®4âÚfñVÚ‚®3¦€{‹Í½ÝÚþÁ±rC±ŽS/´HDl±œé…ÛsíêMø †Ã*¬Îbçÿ®¥˜\ùKja@ ‰”ïrÈLÝ7?Nâà¦>·Úotu™Ün“Ìkìè6;ü&‰×è€çÀ*þ-v·ÑâÙÙÙ¶õàb^¯d°âÜŽ…CÍÍ/žÿ2ükà(>¿Z©âD­^TœoÈ#CÍd šâD¨ž 5‘h#¥¯X‰$±FÙGáe6ÿÀlt/¬&ñ½$Ô´¯P¯À™Œ|]i4¦s/M()¯ß¼y½8¿sp%Ã% ϘŒ¦œ5ÏížI/¥¤î„×’pœ¤c·c®*?zísÊ.À w E@Öí¤«‹¸»o}|еµüÓ;^{ÉœXÿSvx´èòDé'W Žõi×›8K’ô'BöfÒ|e»à}ó¯C»¢#5¡±‚³ÑHÁÐDnÿHáѳ˜ƒûƈ»r¥­­M¯Ë,*RE}êZöððP·ŠXR‹êLUVY^NÃΪÎÖÎtÔœm7w7?±»ßúÎ1ã-­¨­ZÄ¢ sJV "PÙùÿЈ©Ý»½ÓQÞú¬t¹Ö®ÝÛ¶ö|CžZ!ebÄÆÌÈÈçTÐeòQÝ^@ð¥F©^¯eG} $Ö h1gÚK_Œ×‘Ø2üá7½»Aè± ñ,'p úju•(IPpò¬J#J§äùüÜÜžóçž>}ú*‘øæõë)‘• ÑšáÛë-¿‰5è¿­7nÜÐrs (>øi…ßè8eòzŒ”F*mЀ™€À9^“ëÌvŸ§Âj­8ÞZÞ¼V·J•âIÂùyžýíïi Þew€_ yh¹y×m;I¼‰|²‹ÄÉP¬'ñI´„?¤˜ObûèŸñ³ÓÌ‹µtÛwÿtÝé(Êžãn1’J¿ÔMLimUJ"¸Nb1œŽžÇëD~¸v׿@vΤz:˜òÚ^q»ç¬ò~ñy(„BP–°'»ƒ¶ž0¯X®åÌ3çLFfݪÚnïWïbÌ.U‰z(Q¡q#7 _9Ú_v{_œIŠp^ 'îï EÀ|°»‘#'t,ƒ6X[“ú‰Ó"î(E`ñN[Òë{vÂb\¦‡¤À(1,õnkqûéJ·Àið3›ú ž}uÔ=é´w‡ì¶Ë~ßçmG p)%@S`?uq~þ¿Ÿ¿€KF¦5ANÐíh€"ÓBÞhÜt8LÉddôþ½NTdHX«Õl–nV¡à1ê‘ôô" ^B.à“%“@?²žBûN"ã~T¹ÕF¾~*Êu*‘ƒrŒY½ùO¡®3ÈÂ=€ì=ÈÖ…:z‘7Š‚ÃTÐçL#=ÈG^úT×Ärš…J5”? q“iú eÐHR†ä7Ifô=í‡t®ûX23•ÂêBÈêNE‘Qp’Šæ¯X†NÃ.."UˆB ,Ì {‰Ò½ƒ—`ô„\ S°wß%ê:[:݇ìÝ•õ’8DÙ›e!@xž/**züø1|qr’’ÔL©ø_[öꟀ`k,1âzsÓ–¾?ülè~Áà£ÒÁñòðø–ÐXEd¬,àq¯|øÁ†ÐHnø^IllËÅñ’ðí͡ۑ»t+ÝËßûr]d¼0r¯,v§4|³rh¤hà‹â؃‚¡G%á;æ¾k9-®•u?_µëP~MÛòç®s¿ß¹½&z§<4¶ahVÉ‹<,¼ô`Ѷ& ÇiEêÔXä7¯SŽN›¿¥§¯FR+a{@¨÷œ«:¹}í‹E4 PÂnߺ헿¸µ4© ¢²V—3qfû>ž9ƒ‡ð, ÅŠñ¾Ò…UOFöaYºyñÒf=ì2bÐ0tYéúŸw‘×Aèý> î("‚8(?-™“^‰ þW¶cò×Mã7ò^©€#ƒÞø×/¾Xø„ü·öÇßÿaf:u¨¡q]I)œj¡nC–BI''\¿e>áHÍäŒ:=“«[»mýËü÷v4[÷·o¸ìjòY㞆Xwý`wy´­fع/Þ W˳*Öaw[:jcíkFUñ.kÜmôð—;€l#žšaWy‡u ëà€³¡·sO¼cÿˆ£rÄ _àã]|Ìa9lƒÎêÁΚ¸¾I:Á†È§ÊÚaÀ#±Æ»ëF<µC.~ «¬ý(ùÇ4gæ·Œ¡:W¤è«Zü_j‚Å›5Ÿ˜5™(– X´F‰ðr„ÃÕBˆT^&‘ê]mÕ§Ö³zŠ1û´W¯\Åó„Ï?øñû¹¬”¦¸cÝ ûl̉Sõ  ¡DI“M8u¢´¬¨¶Éf< ¢|,«ËMﺛPrÆ ×SZÊd4UVT ‚pýúõ'Û€KIž~<%.÷› —²FŠiÚe Ø:EÞ 1ñÕöDy¹¯Vy¯PãVìnÙÚ±:z­.Õ~^±x JQÂØã¯õ–•¾žË«±æ[·nÂÆú釽‰5Pœ¡ñÛ&œhÅ3­xºOÁ ˆCNÅã­8Ùš…“ÃxúNœ]1>“M„ñ&Ž‘@M5É|>|ê 3âèÂ\†1Q9ÓrMEZ]yÀ˜4½Ž¢ÊLÜ”ø!~ø¿J¸Cb&è#2’± ÜÊ€X cA$Ä¢(óB`hžŠÑ´*᠓ȱ¸êUÙ´´&¡&-uXîÃbèãKíQKõÏ/ž#¼!JiYzï⹓ßÙràùÂ>¾üÏ'™§D+›‡%,ÈŸžn_Gs–=Ò¨ð{çÃÒ‚àÃðX€PPô—Ù H!¡Ú^{uâ’„ `¹‹2‰*¥C~ìs_ÍΉâç^OÝÆgYƨ7BÝ(ÌÏ»õÉÍÕæç7íëj¼ê–Á³©›­íÀçZ½ù[ÅPï ý) ¤Ž¢Þ$’W¦Ðb9” ž@ÍgúÜŠ¢Ö• !N”:<½¦¢Ñ@Aýe×ìo@áY$¥rùg0‚z(úR® èìªÕ<”BêÒcÔ–Ý:J¢™Ó/U°ùù¹GL’•ôUÃîâò;˾ÆlŒç—wKG×¹ûn|ð¡ÇåÚùêN6›¢º‡¹Ê?‡À ai–Ös ÃP:rGç°Ã:ðÉë®ýšëzÞnŽ:›†<ö˜8E8¬CŽºQgÍ`;ï>)ïïªêwÔza@åå ‚%ƒNà–qWÃ`çÁXWmX]¬ë@œôƒñ±°ª¬™€€¢œ<ìÉ>‚ëp÷¾¶À* O# m,©* Zý²Åû¥&Z{À$k\ë“­É èƒ}¢Õ#,›Xë Ú܂ͦVú‚–îC/Û‹˜0¸€d>ÒH³8sᇧ÷€pÂŒIU¨…gd)–Êgô)Ú±·ü'íísQGeô V¤U¨ ð@€¹,!$ˆ/‘ì¥G²HtFFੇ¤Å€b{f½Îh,bõ¿UÇìu»‹LÏ€SLŽIO ½ÙDÞ"НΤ´¤êà°J¾ðuÓHHšz±ªÞ푪KJÿÉ~¹ÆFq]qüJH–Vi4®f4£]-^l®HcB<ÒT ãà†µ1¶yš7²ëÄ…âÇzí}ÍîÌ>Ào¿Ö^S’öCÕJ-jŠÔD­Ò¨­Bͧ~«T(‚bãÛsׯÔ×\ÑÝ@i¤§i_š1 {šózšõ¸«ºš*:éI¯ˆìH¿g[ªúfZàÜuõw_8Ô¤pЈUÊÔ˼F‰.5 —óê€"ûÛC%m`À!`$Ñ +>x<\  Ò@tµ‚õÇãûBž’‹«¹ÌŠâ³re$Ò#sÚL=&æL}]-ƒZ”eÑ.pœ$Ñ@Æ‘J’O´H—ê>WcÕ[׊k‚ʱ,–8‡Óvû¯S± tëä3–‹xµMþcäPIž Ã‡Èø1’€UŸ£KžDz%™Î!ì|z–ç³x…ÂGê™Æ}C™{v~“¬ÏÍUú@AÊBA…’ÈFñ¥ÓHh&i.v°œ*)‚“a± Ü¼yóy7ž:ð‚XÏ<ž¾3õÏq ÄN ö–=ÿR÷®É©-?½½cèó’ÑÛycw¾uüxÉÞNÜ=8ôÉŠ]•X”˜Ë¹ÎX Bú öž?šœ/ÓÈ<“,Nþv÷îÏ>üÈÓì>PZæÌÌÂ<¶BEåx‘ålX,ŒSR$A°‰â «*±ÆÐñêæµZë˽®ö=WÊe6¶Ÿ/è2vŒLœù¢µ\V20owbË[Þq:~u¦f6v…@= Š †F‰¤ù+h$Í!f8Òý©P‡©R·Ã÷8jÞA4J&)˜*®S¨ w<ôHsñÞ£o®%?ÀÆ­ê“R^.ò[Ö٥ОҪ왬œ#Xï|pö¾×cF4˜ÍÔ¼iY÷›aï+§ˆ@¤_Eõ—ÑY7òÆP|…(þó%«¹6‚]ôí±A.w›,c v?xð`n]émž%ž—¼ÿq@c6ûlææ¹ÿÏ{PÛ©Ì »jŠu#mŽFF(T,Õ} Hëá6©¼ÕŠYècž8O_ýÌssa …}ff>V™«T%Ì 6Npî,/MþiÛÐ_¶ßÞ:úÙîñ©½Ãß9Ù6:u0ñùÿÃ~¹ÇD•Ýqü&›˜L2ÉÍÍÍÍͽ97óÈ ‚VÌ‚ (W­"¨, OE”q@ÔµU—× ó`0€¼" îþÓt·¦‰é®¯´‰nw»k·Ý¶Ù6ñÕmW»2ÌÌéïÜÊùC³Íö=ùåäîÌüî÷üÎù~~uN…0Âj9F‹P¯g‰4–G¾¾óúx´^ä´`ñ×/oÞ¹ëíî©/vµ ñyúL‡y–‰aÕ8U/ùh¹Oœ¶;’׬–ʶgן@ èhìTHÚ^7vذ ž³2qÂ[ôL––BmÜ{›ŽWÊ}ú-”V 4ÿÊ%úãøGhñÈGš‘H'òõ£Ç™û²%-h9è;¢Lµ”w†ò­ìªc”ç2å»Lhìµçå꣌§”êxÅë4¨íû¨ Vª{‚²_~-½˜F±¼€DI+(%å¶½”ÅA¬ùeݼëÕ1Jy®’_OÓÃî¬áÑõëןÓ—G‘}i$2ßúð&Јš_Û£§ºF(× ¡ï™I^–¦®Pý£”é,¯Ô )™UkׯÜûû—ËsŽlВᘟ#(ò«÷ÞW*µZ%Â!KÈrûS§îïŸøüÍËŸî¸úñ6ÿGyc¿ÿÁñã¹Ø3õÉÑßUøï²‰zZÔA*±¬I†\ÃonÜXÎ!@ÅNä·^â±Èˆ¬e -W†àJ`jæŸÈ—`üôÙ³O|öÞ/ßæIKÝ#ªÕ +Ѭ© )TmŠÎi¨*µeö]<9ø¯'`õ`ïH^ÐåÂ^¶Zp§g&²€äKB|wv¸gM¦5Pã"‹àL0Üþ´Œ}õNAh.¹äÿ#HÈpÁ¦#·:éhÂøŸ¾ÉÙ¹N%ONå*$FQÆZª}`e*¸B¹`1MuŽS®!Êí§ºfœøF¨ª‹TYÕh£Zú¨Îiª½—JÍÕrp÷ÑQÊU*8ö*µJÁ0±qTýÙ—vóŽ ÊY½Cu\£ªkYø .E¶®®n¡±Z¯p%b¹P—>ÑÇnmƒf|±Uqœê¥\³”w‚„ûhäò0ÑIjVT!žF¼£Í\ê —ýî’çFlúñW¶¥¤zA&<ÃÆ7ž¹Ÿ8öÛœ«Ö}š1ýÙöÉ{Yã÷~püx.Ò&î§O~œ3þQ¡÷JíEÁn©8ÊL…¤Mñ õ.~þàá`P¦‘Ð’²C…":̇B¡ÅÝ5ÔðÂNÉþš›,Âó¡ÿâMž >üÇÃ6KË–M‰´B‰À±e|æÎ##m™CMyCM@#…}õ@ G-$ùÖœ¡æìþ@‘ò®ú‚ÆÊ踤9ÀY(4’ë'LEŒ’ㆃµ À,2´FäuHTñ,bpR5ÏÁš]¯•”¼–U"£è𻢶¥®IÞ•ôÂØ¹&e«.1A\ÃFihIM#-ƒt,©CHä‹O‚%™q!Y#$ö÷^ŠH<‘#! 4Μª“$øEŠ”Výƹé Ä|'+º­¿O•ãÉ*쯄¸T¶K("«r÷öñÃáHóŠcEn~ð¡ÉxlÓ†x¨s…¦%–(Ìa· :C§x§lëíàõðì9< éÃWá‰R<{²»xP¾¨Õ±4Sœ|à?ì—kl׆„dÉÒJ£Ñh4šÑ¬vÖZ³Üb«6J!44vÀ„€ƒ7ƒñ…‹ TFJ¡¾€1ÞûÌì¬mÀƀͮgwmêVM!ýAó£4¨&Ü …4mRh•Rnkïž~gÇP‚ºR‹’´?rôíhfvfÎ9ï¹¼Ï'¯îPJw™Ò]®xí$åÏ—ÂÁ r<ÍrÒµKçFŽ œ|% "ŒàògØQo>–Ò¤m Ã@„úÔ1M„êRʺlN]ÖÅ † UÛÜkæK˘h†1-Αþ!kXñ``M%B0À‰µ´®=ô$5?¡?ˆ î<îÓâÎÜÙ…].¬(øÀþ/œí7;Ú°¦aMŽwøåæLã-&†þ¾U¼ï• ù€ï{< Ïæ²Sdò^ø¯Ý¼[GrÒ~Š´w‘ÓÍÑ–i¬H‹4dy7nÜ0z“HáVò±dí?/‰”Dø1˜)]¾œcàó¬…± æHíGòRŽ’Æ<§WóBÖ3`”iÁœy¿sß%(2>7ü÷Q&{‘Ú¥}n8A}†µIÖ²ÞÓÅýÇ./>:Vº²"üÑ«¡³E±³ÿsüx"–D.êWE®U„.V;C¶œ%Q‚ÝFàˆ‘\A@rfÎÚÖÐðÞñ·oß~‚*‹1o üˆI@&‘GC‚Pͤhd4SñÁè¨ÍfcYf˱Ù|yWKIû=Måw•õîªÜ×ZÞ³Ëq¨íµƒ­$ëzvÖ;2³L`ñ,@K|Êp~‘× ñЇ O:4É$<Ã@ˆ]R<—ÇÚ¬&ÖÌÓ”DÛÑÊÚÀS`óo@Àƒ¨Dj‚ 0fTMjOa€Y¯x`¦@=܆ªÚÓ¿þ é~"IIŒï‘HƉ:D²’• »ZGCš`:TóñôȺ´nÇ_O<L9¼hZR@ ‡¢1ƒ@òK6ŸX$Z[]3kÆLÜ Ò¦D½Hl¢E4Qy·}ÅüQ¥jb¸°Ç0@B5WãÈF‚:ÒVZqI©³s|& ™(,ÍyÑ÷æÞ.Ç~m¥[-uk¯²Ê嬨½ û…,22&‰_/uξ«ëmæá'P4g/²"$PQx«Å‘õ©c: Ù‚c›‰Dá*rÚŠÃõÞ"5@)ñ#;çši‰•¬Ð-fJßêÕĈ}ì6€`•ø2IZãîÀîvÂ-šöÇææ}¯/«ÍË){6W¯,‹ÃG¼@5§wï¨Î·µÍÍMEøö`Uùb—Ë Úì´‰Þ˜Ÿ‡x澦VÍ™ V]05ÿWëÞÆÚ~,·aOûR\¤yxöà€Œ•ö¾ Žr{¡Æ$¡ï_Ú;fZEZàžÖmÁ©å†ÞòùPùkÊ‚TŽbhÁŠªPPG ?ÎÜaEÔäE]GQWRbHþ9©+؃Ôä;Š´AÔ ìFþ0R¡Q¤„ÉpÚ³?†|=™Ek8†Ïâ2sö–úí†÷LÄÄqòþÓñH2 î6‘$&S’¦é 8Cežƒü(#A4IO#ð¯vùŽ }Ãä­îÃÈ݇:¶ÿ(Þg%NEgЦ÷Nü üÐMÄC”"Æ ¾:ñàÏŸ]·Ùs$b¤¦LNšÓØ•Îý ¿|ø“¢óËÂçK"cK#—F>ž?ø§Å‘?,[¹øŠ~vaôœ„.éW„Ï,94ºP¿Z _}-òQÑ‘ÑâèØ«ƒ¾.) _ºX¾áÐ/­Úw"omc†”#ò¬™e`V@ˆ4EÌÕ"˜ÆÌ15•½>»vzžÊhðC³KqZ  K?9tÉ'.W ¥À0ú,–+ïíXvhϺžÖ’Þæ·ú÷8ú€@Z+µUÜUÜײ¦ooYãQœä%XÚÅB&aXE&ï@ ’"†f&Ÿ$ô“@530† ÷/¨x" H3ž4j|üƒP܇›Ó§Ú–W:~¿ÿäÉ“7oÞüª œ¦Ü¾{oáË?°‚Ós,ó™LÆÈ¶%8 ž[‰R‹C›p¬‡6à(xqÖÄp#Ûñ@5Ž­ÿe[Y®@³´dá¸Öæc,îMÎW@ž; 6Ÿ06ÿIÒžHKì>Æw’‰FÏ´îlZV¸ÈB1vÁ"r˘E^ÜhÓTž†’+R›_¶½ßRŒõâh=¨Å±-i©€$º‰£2Eš—8nþ´çåU>­ÔyÀáô;Ú=å.ßJâðì.iúž9ŸyS£sêÔ)h¡®ëd\`°.ƒÏÍæ©¡ÆWRŸ­KF6ãè­ÃÑx°뵄Lbµx° Öà¡ú´í‰žp¬n¨®À*è0Ó9j–%ësçž{`%îqc8÷—ÝØïJëÚÞŒ{ºÝKf†6Y¹Lxñý­ä-oàS—g¶ÀMÍ`Y÷Úš»þà8|PöŸ¨ßs†­Y£wԸ콰µîÒÛ[á„T Gÿ7Œ²7Aº)<$:µã••65ýMqb¯ û_*®OZ[oµìÆQªòW_ÇáÒ7XÑ’KÑŸ¶ž“~7ÖdìvaŸŒýî¤&'àEHIð8'È¿ !“€òÛ¦¦ç,"ű’Eâ3©çf̼zõ*dyí¨É§ËR¿+ßv!Æ7@bÏž «RÍ,ÍPS碆w¸û h‡Q_”IZ‰!-”â¸Fj/%äÚXÓ”ü9™KK,&–ÿ'ûåÕ•Çñ“˜˜Lrssrss'÷fîLFÅP¢®1õŸ°E® ˆ…®µ¾•ˆ<æýD¡€‚ÃÌÀ®ÍZצ»ij}¤¾‹ÏÖ¶±ûиuŸ*0³¿3lu;MºiÿhÒ““;gîLÎùžßy|??Y=©°•oUr²ˆ1ªØLnd9ZO!ƒÕ6"ëET7²ºiÛ ›‡‚J‹ŸRŠÝÞ¬V¨“´¬c,Ëê Ѭ0±ª@(ôÿl¼Ð¸Í‘„ÉÉßᔂÒ4AÁÌ[ƒl‘9:ÝtvßM#Ž~ªÜâ{©lˆ‰¥4OZ¼<Ë ,¸ÎÛO#0Þpàe' dììX…·oÛ!R q’¨Ô.Ê-ê>ËýWT»¾Ÿ=pgÁ±+‹Ý×sü·r½×7´½7«²iöÆ}É™›æíLßw¸ÜsqûÊ2÷ÕŒÁû‹û¿Xâ»ûšçF~ß­U=7–õÜþ¡h$«ç:ºtÕbЦ/OU *&ŽÇ Ä"‘ãÔCÂð/B„˜¸i2»zÑŒ3ûr´¿ÜM|@B[¨Å{Ëcº? SOi’Z)²¼ZfÉ)–³-·¹5·Ù–×d.Ôœ¸òÌÆü†œYYÛ±ŸÁîëJçÎaEå4^fxöÜÖŠ@kKØl"0ôaW˜ò€àǦb·“æÆgËo‹Kt«‘¹Ïk눡™Xœ×Ô$Klጄ‡¦æa£ž~ûëƒ öPÖʰÍAÌzâP±›žaC('úFªüˆ‹XÄd 6ÛíÖ¹§•Ëk°ÇÍêdE&ÅÏ4ò“(c™KäÒ€;vzR2Mâ8^…9FL@{ ð€9¼H\ßåÂ.`•nd§>‰œ¢jæ4Ž™´"™ŽÄ-ÊÅ4Í™ÔÔ© … âÑè¹ í± çQdoG%%|Â/Ðî:¤ï¦Ôê8>P—‰Ã,Ç‘ÅKiÄä¡O{ JÏQ1¢Ì3«HKKyòì_p BF6: þûëǯÎ]ÀðjKJ…bI²ôøè¯É@%éÛHú«ˆé­ ¾M¤¯œBˆ?BÐðn"¾·VëKóËíh®t;Ò΃£däiä#øùŸœ>ó^CMmæ’åj>N •RTÁŽf%Œ%–˜ç±Ä€ýcž™*áM‹RNlÏù{[ØNŽo ¾RZ{KHÿf $Јåþþ7€ –½š&óJ§`¹)·Éšß|8ßh+ÐSÉ7´¬5¹Ööd¿9]©£c³X–TOž<‰Fæô©wuÚø)Bœ `!°d×kÓHßv:kpj7å´Œ­´á~«$Þ1õ€Z˜EO%¨ºX—£°B©ÓòÌtž¹¿³š8[ˆÃ2j®'$f ±;c¹9ðƒqu&ÙÉ‚"EÄ{Ì{·ªêÃÝû‰ÅBœ6b³³á¡Õ²6M§Vr°(©<þÊb æbo6æecÅZ&[$3_ÜOÇ5B·–°pìÞø£Óˆ‘VGý’€Œ€ghÅ¿5/íªž¦â¼B§Äï”H²³sïâ_²ðRRü©±žØ¬assÀj[":Ðâ´Æ}íÖayd0g%Çs*̰l² «XÞ¢ÿ)Í,'®…Ÿ!ä§Tàêk… $_pG…F%+¤dT]¬]Hì½ÈÞ›FÀˆÝÈîFz†~t¤ /͆פ"Crõ£õo‰bІÃ`7 ] j0Ož5_Jœ~U¤â§bA‹uh‡™º‘³YÝÈÔClÝa ðÀíÍÙªëâtó6ShE¼¹r3¥áP$ ~ï(„€CÂÏ(ýõ/i©)kÈž,NAuFä tDdÌè¥JbÆÁƒœ€.^tÄ‹,H?ˆ\mÌ+³¡+ Ãù××ÖSùûuÅ™Ç|“M6™L&“ÉLf3»„w90ÈéùJ}Á­¬.VA„R­§õ¥¾@e÷äE‘—Ý™Ù]ô̵&íýá%=Ï\U”A©õ»¤É%Å&ž­À²Ïýž½×mï›Ü%lȳÃì<ÏÌ<ó|??¨hgf¾CóÙ×ó` Ì7^äî̇å%–RkY!qG•^º¿Î^#®Q½2š­ ¯ul‘ôþ%)»˜æ8ˆËhÖX+ 4®@aÓ*÷÷þÑà3ìð=ÚîÎulu½)d{mrg¸†s=ã¹Þ‰Íž‰uò—«å¯6Ê7È7KCÙһ囅¯o:jÒmÞ“¬ƒ¡’/@VЇ†@‘QŒlÌÐ,Ïi’wtõÞðÝ‹ÙÙ™™dÇ=¸'Ü៻§°sÀëchf2ä^ò†åÝ 9Ý5;/Šìê<­ï®ÕwÛw©4²ûR튲jYH«bɈÏËŠ98Bà‡¥ µ4ã‘ÞV¦\¸Ýú7ãÙÜÄÄ8ŽÅ++Ð$}åw×pY‰…¥È\û™ü_ls øÜÂ+»%QÐ$ ÇÊ… »‹hê#œ×¦°µpôaB8¯`8ûˆ#ÇÄ&ŠŒšZ¸–(>I7e•"qø$Ñ~•ØsŒT³Ñ,ÍR¸HUêˆUéD}7ÎýV‰pHÄyn[@&Þã„1\&.\%Ì>¢è! ª!©bYÙ:U|> ñßÿ^#¼P?›yáGþ6K“Hª£Vd¸ˆ·² G'añm`¡Â,cl8Ã“Ìæ&ì>Â, nœ ÞÓTŒA§NLˆŸüÇóiH¬¦À pSð­A!92÷Õ£ô%à‹×$cp~–.§L„Kÿel{ð-ïðFex¯{(Y *¿8†äYžãSòÊs϶/.>IÅÿšcy¥‚R"-¿¢¤÷f†k4Ã÷d½{4KÊQî¿)lðNl‘G3]÷ßv îpßËí¿—íÙª<„î6Êcë¼c+•‘eýwaÌÛ”‘]ʰ¡g0íþ…újí¢4–x–Ö²RÇÒPWjYF a±S°j'ffl9\U}ùR÷/n;ùôðL~™Ô0Ÿ×§­Ñ J ,V¯}/ßecÖÅÓ;{j /žË¿x6§óLAO}aW­¡ýLAw]j~†F`y5Uæ­[·B–²=#8èšüúŠ”¯ÿ÷fÙü6ûãÇ¼Öø¡“O¦Cö̆vý#cð§:h¦»::i´ÇÂ;™«þ{ï4PŽú‹pÚzʃé8„¤» ˆc¹ô©ûƒ·S9xsE! æ'`O§YŠÒi´¸@4ðø@qŒ|^¤À©t|4èxŠÖÑêõ ì©ì_}v4óëÖä­FR’Ëñɽe¸/©g}ÿ !ßûH©FJP#žR$…MNRªã(ZMŠ<ý›ØS~£>†æ}½m· 4ÒšwÞ‘×dÝ]w8½$Š×0*4RVV7nnŸ{ïÙ·Ï7mJg DREÃæ%“߸>@ȵ)x s q—!yØñ¸YµOÙ7ê¬Hâ)0X4¯#òfåAd3#[£ßÚˆÌtÞ.ÍoΊbØHŽ?‘¶~¶ÉŠ9Ñä„~MTÓê@VǪ/¢¨žNu@²V“ ¦ò&>:ufÖX‡pŒ9ÐdDç›ðñ8ÍÍÈÚüsk5µ ‡¿år4|ÓT I†…áhJ•DSJyås#ŒÇ:c­E–:|9Öö~ƒþOÇߟ27#‡Ál-0‰ÕŠ,fd·LEà7Ë“†º‚ű0Å¢XATÁC×4Z,SÁ’MO…ÎùЗô—íy›{H¡ –9¨(c4º(†‡@¢Ö$'έoø¸s?Ñæ#l„ÍEØ[!ˆAÀ‘$™È‰ª”4Âa#Þ=±ç a‚ƒ¯¦®ˆ=ïDRl,¯ {–¤-„¥—pöönÜœ¤]!œn_pc Šl ÖtV±uF¬ÞB 11Ž{šanÝø3,¸þ/j›žIàÁÑ% ±ñ4§¥RÐU§‰6‰0{ƒ—ßKXAJxaïƒLXÜxö ©L6AH…bã)Ž£;.u¹„üÓÓø­ †ÃÑüƒÀ#Ÿœœ\œ”$ÀZNÑ$+®Øfûå;ëä‰t)lúg¸†×xÆ—zF²¥;EÖk$·!Š¡„%™åŸèå{ËÝC•¡âž+w14+òÂ.Ao¿žë}¼´l4šse,K¹û¦4‚y£<È‘‡·K÷ôÒ AÔK÷õòPž<²UÎ’F³<³•‰,÷—¹½ø³Yùj£ü8Sy¼Kßfû4­Ò—®'…hÀC“–%,,ˬ–¦àÃP4ÀgXH@ ',K]R´·°¡ö£«ãg¦ mѧ_W/PA¬À‘ÿd¿îcšHó8€?É&$$M&Íd2™¦M["t‘ŒË.œž/貸ê B·HQ)ò¦È"§¾-A‘·¶túÆ‹ Ðé´S”½½ûûî’»º¸‘Q\owÏ?ö.—{I6‹¼´óÜï©JTRï6ÁäþØÉ¦§Ó§ÏÌó|??}êšBçYË•¶Ýýg÷œ· 4—· · _ 4_ÜZ’ #n2ìõëןN‡Hø) ^¼M/%þK+^´‹¬Öøä» .—ûðR^Ú^u*zy êŽEžÏÙù®š2ÐqŸwZ°TM2t¼ 8i ; ²¾’$,hÁgÁW®·­×ëµQ=€o]r¼‚Qsº:Q«L —¤á)XYF¡fYÉtcnúïßõTa©KǰÈ©&öÀ<xäµS㧱Ј¥Rq,–‘n@?@¥"fô“¾Õáñ £²ÂÓ²99ÃZØá5wòf{×þ6ïA«§°£»Àá.èr¶9ÌÍŠ€TÓÒÒ#áÈò¸EðßÿýcažfN-èøü4Ãߎà‰_a$à"ÀÒÕzòbõÇc±•aþ¤Á]¼Y§ŒW±ÅÊœ k±Ý1Ïw.¹m¸Ë†®XinÐéðLÒÌgõgˆ@Ú/`=ìx;†ÈîvÊ-ÍØå™wz½ùùà–8˜¬ÊHpà¹ýFž®l³b;qÈoïhÁ<8Ä&Ãu^·F<½2ßA#îfèó'%å ððœ0ʬ¤Äï:ØíÅ®¶ˆí\ÄÛŽA®îÅŽvìrÂð’üFvtÈ]Öˆ ®ÓA(âr=öôV§½ Õ «Vk(&Y¥«®©!7üEyYýË3qU¦áOÛëÞ"ÑýÉ[.¯ Òò §2* — ÕQjª?…<±5â §€< ¹ÇIj÷Kć+ÑÆí”B§NB½¨;„Ú.#4ö¡v~ ½–aY…NK+ܲÔ#ÇIÿn¸ „Z/#/ÀeýÄ$Ž(THÖ‡gYýhÀZ<(-KËja!¢ÕtjÊú¯¦î…_´ñÿ´ÉXž_?~\VV¢‚ ‚š.ñŒMˆ¿„Ü!ä ‘>xFÉ7D:k! 2§ŸÈÍÚ‡ŒãYNËP4½k7ù–„A¼´YZ‰&¨yN'G«Èš®â¨”ÍÅÂdNèÁnqf¯p'Vú»·M¸¿câë¼Á?dä•«XHoŽKL)ùÌ8|3;0›.>Ü,>°üæ+Ëàï©MùÉ¿°¬):c¾2¹Ë7ý> '8½Û?µS¸½ZÉ•È×|Ï7öØ É¦@M¹â]£ÿnÞèô¾‘;ùcwó…Ùÿìéë,ÿ½ìÑÛÐÆ»ÿŽQºÿþØ]Óù¾ŒÒ_k·™ú qpƒY’pj:–„hHàòÀmð¤²ä%§‚‚WÅr™[·­3¬tA8›™—U"ØA#9ƒM»®|TÞÛtðòÓpk^€Ä4xÞÜ!³4ŸURÉ’e'''ñŠX‡eDùs‘_Ø"σaù#+é²ZÛJŸüˆ…W–Ë'B~Žº’¦)j¨:ûÊIÔª ?Àp´9jqàIU¡œÀà·'o8ë>ÜšÆ §d( r”˜¤bXJÃÄ­ÕÄß¡m¦ô/Î-õŸ!—ÕŽa?ì ‹J8ŒCeX„ïªÅb=6Èã8T‡ƒåX:„ý‡ðUHü*ÒÌWJš…jq°6fú‡Ž‡ÇʵV«ÖAÞoys£ÍdëÝßå(´¹Íž¢Žî"+_`wºx³Õ}°##%UEÑ`ZŽãž¬s ä`‰üýaaétc#TH¬"^§ÑÒ´º,CýÍ`‰P‚¯Ö`±†t5[G'ˆ¯&`âkÇñhñÜhíöJI3z,0qâƒ?Øl¹$‚c§9 >Ö©”ô†³Øé®Žþ"öðäS$»£‘ÝçëlÇ}=ó!~ºÔÙÓ¯­TQ25XÅÈ$҉å©Ö•r½.fîŸ ¡wùÆ­9¦3Ã*;ƒ=O¨/‘Ô”„HôD#”õªª¬áXE›ÆRrõŽ*wxÛЬ¦ì ßôNßD*õ/óŽ”Uû~·58Ù¡’^ÙÇ«­ÞÍÞ±‚ЬfpúµÞ%×çr½3y¾ùüàg¹¡¹’Þ mßÄöÐÌ:ÿÄŽàL¡hAãŸ,ŒíõÍ•ôÏî MøG‹ý ¼Ó…Áù‚Oóm‡ ÿ, ‚n`f¬4ðp¿w¢Ì3®õM•¦€@àmÏ‹jRÕò®5- u­«÷ÖfnÎg T:+U14lß ¥¤ÒÔŒ>øƒ@E.W¬‘ë.©íµv5çwÓõ_¨èlÜ{­©¢ç²öZ\¯•É)ˆoð¡©9·„a¿ä<À~EDw"²…¡7žLÇ’¾„£K8²HºÃKÐ&––àn]•Žtú'Å.eI›Q§q,:Gœø-ñ›DÒ’d !Ç3ÅÄñ1±‚©K¢‡/B{b8y‘¬Ñþhxø·nÛgõ›5 ³ Ü€j  ë(ô  ¨Hà öWÝ÷O©¶ÿsõèo UJ–QQŒ‚–o9på@§]ÛâÞov~è P]å&—Î`+Ó;*,{¶©(…8ƒ•Ý»÷ÉÓÜ(žÊü=yò$Mƒl²à@¾§¿_@¾Ì ܇Îa_ͳکÛÀe2”p™å캄ӈÛ.cs'nÞž°[ ð·Í…ÍÆ]¯l¦8yÙ¦q— ;ù„±)Æ›#mØÞŠ]WlÅ ,³,õöÆ ØÕþÜ(¤Çn'˜„“&A+քͶ بàÀ< ¶`Á‚]z?®Nl´c§  •‰8y¹ Vòj:;zêÄ’ óBƒfM-[A§ý¬î8vvbCk¼Óµ\Æn;àÄBfq¹¢ð—o·-¬—v®€M1ð i–®¯¯_XXøçéy Ú_”oSIF¼€Ï/c!`É Í aÕQC !kF[7z?ˆLþ”ê,xP[\À`¾(µ©cY~9ÍePr .ª=º>@úNtÉNœäØÕRµR‘óŠšÎÌ Ó$ëäHwµ…{5{ÉØCÈ@í!ä;…ëHð!g7ª<&ç²dR)ÍR«nÕšµ#wFÀþÈ"¨¼þÁEcqL¤#žŒí¢0à8°H_ëñ¬Te° g´t%ÅI³s‘Þ‚\¡g¦gr‘Ë‹Ÿ¡¸,9%Igéï¬ÌžŸŸMHòTö .…Å~Pèðð°œaU,äw”T¾bkÿëƒ[ƒK‡æ´Á™"ßdJöïðÏUôL…&(†QÊ(ZÊlw|xp`¦äÚˆ60Y60µ«ÿþ¾¡™¢àØNÿý<ÿÔ¡Á©×­7µ¶PM`¤8pwpª o¢Ð7Yƒ1šž©ß¼Æ?¾{hv›g¶40Yä`@÷!´{‚ÓÀEƒ3äÚ3±ÇKZP40 ðóMÓÈ÷‚Ÿ¾˜Óøföù'+ãÕ}wK?Ê»ØSy^UXÅ®×HÒ×P¬ZÁ)H Mg8šISf+ŠÏÖê2è¼M{Þ?w°[_ÚÕx¨·yßÕ‹Úžæ7­õ´œRP4x{q~9Qp‘€"âDå '@MzÔך•ˆD–žïÒ~õu}‚1H’,A˜$uY 'ý Á׿üù¯·î~2|çîÈÈÈèèè­oݹ}÷ÁØøß¾ZEE2"ô§?|öðþÈí_þüá ÛÚjmi|»¶ê`YiI¡&{õjN.c‹étÃ1R‰’cJ¢’)dn»Ê¢{ùsï)¬ÅÁJì¯ÁÁwpè‚Jý·)0ñ±;ý½]¢6•\)©Êèyô<ó4ófgÞû~j D·°Š#€j಑)€l>Ô 89…Þ.çâ_S´\“yJ°h=Ó2{ñ(EØ'û!lÇ™xü¿í,HFæ97eºNÐêRÐa²¹ãE)âEæóÈtÙ8iÌ9ñº°U[Ÿ÷bœ-s¿3I˜™dôY4îÔ'ß25-œû¤§cLô?ß°÷]ßµW(ÓÝ·Ò×·Ê2x&MùœàÝ%î¡’ÖÞµQ’‰À‹¼’q°µ°¥§,0œÓ9¬ñ÷eœ½’ïï)òwçzÞvýUN+ JjÂâÂE5Þ¬ˆå^vðo lwOAàA®w³Êusµÿn¾¿wµ»»Ð{³Øw«ÀÝ›ç½ç d‡3]ý¹¾¯ ÷Öú†€(ЙL÷­—­‘e®;+}C+¼ƒim·ÓÝý¹çï¯ /?w;×" •z{À'‡[ÞÈ/O˜ù&”x’¨Dä53ÍÝÝTUÖrÐÐv¨8ª‘ÒÖ£°7´ÙyªRNV(Ìí¢}òd||ôÂ… ;¶nK[°„9WRJ ÆÆ Ï›SVX°¹ÄP¸6w}©ÁXu¼±Þ {‡Íü—˟ݸÖèºÖÝùùW¯w_½r­«««³³ó 8iŒ0Ÿéõz­–“%YD…àhá£h…©(ž£D¦<•ª°&"ÏÁ!È"N ¼ÈiàAô² }æ1 5XUR*åeŠáãä5³uÜŽ5KþÞ¼K=¿OuoQåª{›xOíØÍb÷•3ã–ànó;‹áÝ鉔(òåÙ;š v{IMC©ÑÕˆÉPU¿®º¹Ôb7ÔÖŒi3Êœ¤ 3[(tsbb”EXtb€hûÞ‰ ŒJY¯h5†…Rijo¢}£êß®zv¾h?Ÿù?Ø·"Þh„ãâ6Ì_¨:ÚUëqÕ^£«USM4ôM¬b³Dêle3§óTÐ8E"m†Ò¯T†N«¶“ýŽ•$¿> >mJPrëÈ!Ü?–Fb½=*è^¬ÔV1~Äœ±šžs¥¾áÚǾ,5埕ðv8û¨öxѬKf†j³`FÌæw4ªuÕ  8ø Z­ªã”j21½8jÕº »‹Ý†ÙL*°Äj¯«?¶*$¢QˆV‚w¡d¦g<}ø0ö¾~âÇÿý‹N¶E"XDðë'Ì+Iè£ýÈáFÍ¿e*™L–ÎèŽ ²P½›Y¢¡=!j&N¢AGLÈy ÙZPCU¶£Ó¿C[¶Nç•,àxY–¦#[:õ{T PB¡²M¥Q#c .E†QOÑìÏr¸^X#–OQ³3®°l¦˜çdg¦¥ýð1Œfè6]ó>×Hd j#a~ë¶¶6 w„à©ËJ?Íó…Š<ƒòË}½ËÝ=¥îI5’å¹½ÒÛ¿ÞûUƹ볳7óI’äÄyYpʪàýÅN¨€ ýÃùÎ;YþÁÂ74Ñc¬‹›.åúû²ÜCÙÞ¡ü¶ë%þ;+œÐx}G‰çfV{h©Òÿd}§'ßÕëîÏd{ïfú‡—»%9î;PV{ú²3žÞ—­‘·œWJ½76BžÐZW(ÛÙ·Î÷äxByÁAP ”ÿ@y°okóŸÞ|Ï$Ê)TÔ DiήM›Î*j­(‹$Ö’R*Ñ9B\’ áy†hf§ˆ{òg^>«þf¿z~ÜÅ4Ü©ºw1ø¶«þͯž?°xwíÉš¡À#c^Çqûò÷8ÖYêÖ·WÚÊŒuÅ5¶bÓɳ£È±”ÖÎMJÀë„·©ß­PþkBÒÁ‘$%N¥œ ƒ_Dîâ¯ÖªŸÕ¶°êûömÿ¦~Û4!Ž( ðzÁ™þåGªíKg3$²…%>Tæ¦Ó…ùþÁƒóDžOÒi/‹â,…ÏIy'uÎëìEã°f¦€åå#`†ë¦0 ˆ9J›•õ­Þ®6ZÆmÕa»qDZ°3f°öµÆw—Χ'ÜÞéŽæG'j f%L¹%ÿ嶪pØ0©ÕUQ5Õ²}C£j4ªv{ØT¶TGê¡5üê@ck-»²Ý2Z[µiFÏkÁâ”êxqÕ²ŒÇß>‹¾µØâ.ZaÿFgÚðKÈß¶W¶}oTFØ8õº=Š KXÁ'Çëu©¨¢YÜÈèŒzcrØ;5ˆÈŇLSV’.æ§#c+jò¢šFÔt½B¤º¸x~†›hx˜…_[Š>¶£“N0Ï” ƒŽŠÉZ ^Nؑ͋ê}Èv9<ÈæCÖvñú“hï$qÁTÌÇÃlN8*±eNfFóé3—»o¨ücCýo`cÉzÄ@8­žL°(Ð8%}xY]ì‚õ’¶Öˆ£5s—0ÕCøðøäÒȿհúÇmãOa÷x,CK¯(‰2åXb*óvÖ­s^Í 2<äµ÷åû³}E®¾ÉÒ9Óy½(p/Ã3WáºÄxN¸Ö½_ÖüÇ­¾e®ë¥žÛùÓÎÁå®»é¾[Óò·ë±òIÎZ¿õÜÕgEgøûuÛDvÇüIH‘,YF£ÑŒÆ²9 –,%Ý@!rç61$^'$! W¶I ·ïƒB{|&Ð"¤VªÚªÝ–¥°ä¾8¶§Ú?úÏjÅçõ76•V»Š´H‹VZíèÉÏØóžÇóÞ÷ó;‘y¨¥ÒyGœßú«fàA™o:7øt“o!3ô4;ø(ß?Sœ‡ÕžiIÿQqðIAp!W˜.òÏÂ)€A¡wòmk¤(8 ðÈóŒ‰øñMçygöº‚ 5þI0•ãžÉð¾Ex”!Ì”ŽÌ{îï®;M)â •YžO¯*­¹Ñ¢½Ñ¤ëï®ìo-íkÜ;ܪík2\kÉ?}P 1¿I4«ä8lGBt*@)"D€`eD$€Ø8–‚øçIø%~…ae$ § ?™x"‡}œÉ2”” –WŸwËúreùÙý{ŸÒ /çUÚ$†äÅ+C×Ì€‘9.bYZl¬08g ŽÀ³-§èx–Ld¤é ¬nû†ýÛ×]ØŸÞ[›ûë“eÿènÀÞ³8t BààA8ˆýu8p û~†Cb_=öVÿÌø–mäçûR … þ¦8ZÖ­o¹¢·9õ&«®4bÚ×uYo½¼ÏäÒu»ªLç ÎÈH˜·(--¿5±B‰®{a±^y ’èfu8âIXMŠÓ¬¥ð­s8P‹}ÇßxœÁÃxôðµòm0+‹£¹´wÅ\¶DÒ9î¦n1…m–‹QÌ}§õM)<ΔBEÈSë"#ÁÓ¬œIå¹Û G^#$°ug=¹&P†ÍØ%²«]DˆÎZ"cŽ€ÁfÂNcØh*OZCI63TMzÚZ•fϳMꜵǶvl‡+ôD„cĦNì´-áÕ†+Cw¶ž°¹›Œp< ]EŒðs,_¸y;×Ñ< ϵ8¡˜òÝšÅ/žF–ñÊ7ëÇ퇷…¿ùÿ®`Áí‘+y…”äY¨AdJ&;Š®z‘óÖªélw#K™ý¢œ£È| ]¡fsLòv˜Ý¤LŽêÎ sõQc£J‚u›%$Ôú-1¥°°ó#ÑT#³9‚¨¼ŽâUJB¶FS‰ìtå6jó ë r "û0²‚FB¨o¹†ÐÑf:)YÊ+À6P«BM µE,Í&R|+çHqÕ ‚z‡‘%R2ÁPó$e –qx {HìÔ&¼±Fœ}Òm…±$C) N*Ñ8·òÙÊrt}ûÚ—–@÷/áÐâ n<Ûù%«5½.õ€ð È7¥>Κ*¦!â‹GÔžÙÕÒyŸw:_¸§ñÎçÜ )UÇ9–WQ’‰ãIÉ;4Ê-yÒ÷4†ë¿- Líy’éø%¡xWEÑRŠ/5K†§õÞ…¢þ?ò, ëyŒü'Ûl¿Ú"Ì ³Z÷TNàI¡WÄFž0·[˜Íñ/hüsaªÄ?½wh¬tx\ëäû&‹sÏdi`îmk$×?v*ÌBƒA+¦ÔËǵÂ\~àénÿã a>/8[rsfç/†î¾5Ëqðç“J*>>«j6 «û›Ëú›J.”õ7W´,ç$ JA3ðØÈX1ÙARV!‘ůßQ°>M³!5sSZÖÆÔÑ&KL"`d¼<0B32˜,`‚oc€±p‡Á 4I*9¸& íâÒªy!Ê ‡Ÿß¿{— †æä„İ#ÉYéªÙ ­·>×U›mÔgœÜ¥jHa Û••é±Õ;T5éŠãê¤6C¶©®À\_8Ý¥»Xðw‡~há=„uøæì¯Á¾°ÿì>†'°ÿ8„ÔcOÖàÑ<„½‡EŒÇ~Ø?øý3ã[¶Ð©T%IRý=ìy×&%)‰æÒö&“aö™×gžçûyö6¼¹·1©èôâZñÍU,'Ð ßž÷<’‰á©›×®1`A\ÂkšJŒ8´«ç¨P•*†h&°ÍÂÚiöMÆÝm ØÚøB–µZ†jŽ ÖÕ]­©}ênŸ²I„–VR2’ýi„ÀÀ!E¬­³@‘NÏS[Ë—fÛàáÚ^SÞP]-v»É¯N),µÌÊMØ)¿°x¬»Š)ŽO¤¹-+×?‘Oa§7Ÿ Û ®Ú¬a‡Û­36KX2Ïš›€(„".¶X°ËEÞ€¹LòÄ-E–ÀôˆãD7\ÖÆŒ““Ï&I…§f^ê1ü/-õƒFþç–)¢Ïï@YfæfW?LŠ3Œ&¾:†QIù¼élWCAN?²»‘§ ¹‚$â½Hò#ÏEäô"Ï%ÔŠÚTóH=«a8=‚§Âw-#xg«÷ö6ßýŒÐƒtïÍÝÁçFÖöÿa¾tÞ <Îð]Ûæ.ê¿›ÜóÇõð ¥>˜œÊ äyEŽ¢9Ncx§Ü{=Ç;jH\ð@1ª°ÎœzþNÜ¥?åö q« ãsLŒ±ªyKßä®+º Ð.Z\4£×­Îz÷HgAï0Ä}š:ž{a"Ó;”°¯ÝÓºÎrѤÜ2*#[úîf)÷²|¯—"P²ûÆ7+cPŒ}` ÿ8)My˜î¿½90²M½“Õs#»÷ÖÖ ù)ÕÿpufÇÄVKSÆê‚s?Ïó7u5îîüh$»çXá¹9çŸmÚ\Y¤gYg9ø°$÷°¥È;˜9ð`™òû•ÁǃRÕqXÃH ÜKSÆÒÕ{©ÑôÐÄïíÿÝìÐ}£r¤”« C1*ãù½7k¼W„ämŒ ð‚Èrxfvžn‡¿Æßhäúà ÉÊññô"Ké&¬–â`å*±²÷À¾2âµ’”Tü¥XìÃÁ*ØCXD„DPa†R‹¨\†ÕRú+ñùRÂ8Ê_Npìʾ=8TþïÑÈcGa,|¤Z CrGa“³ ÉUè8òÍÎBÉ’ÛäÚinØþ³ÃZ‘†ùœœlL#Lòkn¼ûç ‹tÕoöLÍüåùß GST,ÇþXŒÂÊQ¬/øV‚>xɇpðÈÖD‘çbcú—jLyb…\&M"à´8;a{V>‰]X²à6'¶»±k¨)·Øš°Ë<#› Zì¯A# Ø–í@‘OòŒoÅð0L-¡£¤÷óþ*;*Br€;O].®XÎs‚–ÑSÑñËòì§e%ØÒ‚ÝmSŽ¢PÄŽmÖIg[Ø)‘'r;Ãmæ°Ý>-Ù±Ë=m3“‡r8&­-Í?QF$VÇsl^ú¦g_}59; íEFÕ0~27Fòmcý@‘ÿŸ…´u8|tl‰á †¦µ,éÔ°FÔ é4’‘ý2²‘ÝGb]V‘ò]!„ r«Èé# ‘ƒHR‘;€Ìž¨„5«8-Å-B9µÈíC^r¶v/jEa…Ž[´˜¡¨¤Tt¼y>AnÐB;²!2qw¡N’½È¢"3hä’Î#—\‚ˆB%×m9‹j-¨ðJßM¿õ£t´aÊß‹êå4¹œÇ·Pu ûytZAænt*€œýÈ}É=è=¼ C|Âó¿?¿‘®óÒíD–H÷ùÏüî—¿^Ì ”–†ìa˜„Ìößn L¼ªÔÞáúTÞmô_ßÑ“w"3pÿ…DvVßÅè»eRGsý÷2½c¯[)@…|ß­w'ëúƳ7¶{‡²zÆôb¼À1hJ Ê¤£»ºOæ=ÅÔU¿óô±‚sõ¦îc°3·ëD‘óËhbV˱+Rvú†¶f{o˜CFõÎBïǨŽfùGr£ ë²D–áY>†aæµù,PáïÊ_è8F`tðUxv§|ïqÿºŠZCHSõ½´`)XŠC•$µ‡°o?8Lˆ$›ç<#ÍÅz6f,Íæ¬5IyõrA½'¿¥3ÏiÏnñì’šwœ¨y¯*yñJž¢ 5ç–GAߌL¸¾í¤ÿvy† ®(ݧ£ápæMƒæX¸Fü%8TMMÙ7r"o)Å"´³ž‹ž¨? ) ¢˜‘ÌþS3vX_™.æ-²–]Ø´° xdÀ´Ù‚ÛÛ'­@ –YÙò´ÉònÒJŽA¥g:z°¦KsPqZ±ÜbÝ’©EŠã’Xº!7ÆsšÕ­‹ÿì§aɃ[¡ŽõE[=©o³ÃÉ´â°_÷1Q¤wÀŸÄÄ„d“Éd2™Ìf6³lXP¼O¼æ¤œEw_PQäU•ó¬w¾]9At—}›}ãEXÙ—ÙTšþÓkz¦¹¦zw€ xÚ^®I›Ø³µÍµV„}ú{fOmÒz ‰þul×e½Âé%›VÚ‡VÙr¬›Ž¹Y]ª IaÓsͽ#˾úaäN^ßXed¤84üX†,.ŒŽæG†MÊ­ÕÊ«¥Ô¢èèFel}ïèúè¸)>QÛΨlYAïEà¬X\ßÙRÚÝTÒÓ\Úsº¬»¥úBó6"“ÆíÀ$§÷œ³:VÇP<Ïks×WôÝX§| ‚§T½5«‘—\£õ!ñƒD#€¨Ð9Ø ¶÷ª©]‡/ƒRàÈ=ß¡‘NëØX‰Œ®êíþ­–ö²Ö¶§\ qYÊOU/+Ïæ2S­¨X–ffhhèùœ¦RäYÌýI¾YŒ»Ú;E’Ó1šÈ¡õ84s(ûp\݆jñÀÉw ^ãi ÇêõtJmö"ÜÞ•°[±dKE ë+׈Çe‰HÀ%áÎvè™¶¶`¿w¦­g°!=tÙjdáDFXBS›²Y–óG«Ú°Ó–pµb¿ü§3æ4n.­YÌó÷NÁn¬¦ÆÈsš”9Åiºûg-pÎ)ÇiÜé™´ŸÅNÇðÃ+cÙ™°4aPĆ~ì„[¶ýÁa«X²ÐÀ2ZвÔݵ«úEž(‰ïúŒfË÷¨¨!{÷΃>•c9ˆ`‘Jáõó©ü28‡ÚÃľ0rÕxT, !©€„¤y¹ ýmѾk2—2À …6Õ~)˜²|s*—’ÁëÑñFâðLYUJÖRt° ù‰À6.袎8ò‡ˆy€%ÀÔ£*…ø'ŒrUPá``Œ¬V@ ÞkÎßzŽÜ—NWÒ5gm E  ù!¬1À#JLMauzK¨åÛ'§~DI™@iwH$øDv,8t‹·lÈÏ8õ^TMѱµÊøÚðí ÊĺÈÔMƒ÷àütê"ËY z^î >}>˲"«¥õÆ~¹¦ÿ÷UÁëÙ¦N£Ñ§/H/,_uþj‰KÉ?ì(iûxgì–°a?ÅŠF–áÆ poš+öõl‹ÝÍ‹ÆJ‚¿ÝØ7¼9FÆ%£÷ß5ÇnÄoDF^µF*”aSßí¢þ/‹¢·ÍÊx¾2QêbÄù"ÍéxžÒR¥?©¯êlÚ|þCÐH lÏ7×tŸ”õœlé>]sî,£¥y–Wï]ÏÜY¹·9«‘—\ãûI4G÷> ëZ¢¨ýïàpùkx1Ipï&œ§³z9ÏktZ½‘ÕW«i«´Ë¥¶3•'÷›wçh³_gÓEŠ7FsôèÑ'O&ÏËÿ‰6X6LOMv톖…ùNµZ©j<µö’:SÀˆ] Î{‰ }è=Ñ Z(OãWW¯âÿXf%çºg3Þ³…؃ÞJ_ ãhAËñŒ!§Áº¡ÿæÆÞáU/Q#‘Û«C7Aæð­•G £cD;ö+BÖ `¤Às4Ksœ&MàšÏÚ\[1F¾Ê‹Ý+–ãtæb Åy~Nva‰=\§ ¯U~WÔóiæ–½°FÀ»`iN³Þ4çU/îýØty̳,öù²ØH^ìöŠè¸I¹›ß;º!x³22þª5²52 îZ™€û]/î¹–aª*ya¨´Ü¬}]–l¹Ø²­»¹âBSñù&а¤¢·¹úBsñ…æªÎZ á'IÍ1Õ…o¬ O¬S¾X¾ ¼™ÕÈËÖÈ>Û‹•:ÒØO*4`7zG?…vâp5lÀWÞÇá¦`×J–£h D˜~oa­µ´ñ€¹ºèõµ™ŒÁ@‹zJ+R\†h`IÊÑ„ãÓñ¿/|1ó׿ÁrƒÑŠ Í4¬ÌÀ¡†™kô}ÀÁø§Gäª-E«K:Þœ™þÈíÇN ш@"¿r¸œØãÁ^ {ØçÆÖ Hð:§§a7ár>´¹òpu,cd?ª«Çn™Æå«L‚š¼°ëÁ’Ë6Ò/¦ìŽiû,ØïHØÎ^{ÿØ_v{É¿ø¥Ç.ë¿Ù¯Ó˜(²<à/Ù„¤’N¥R©T¥;}AXWGãŨ#·œ-—ˆ*2²:¬ *"gCß-ˆÜ}7 ³»É~Û]ãèo„Á¸3›ì‡Í~òØEºßþ_µ³c6q&l䓼þ§òººRõÞ«~ïÿ{ØÄ2bPΘÛ±¡wšô¯:ÚÒ×®‰‚iÂq,¬ˆ}¦®6@F~ñí·óÃr /¤+åC.ð7Á§ós¯_>‘žšFÑ ^Î)™†¡#×%#M²! PÁML ŠØÂ_ÝÄ.rÞ lAF²»á*Få9d´¡“U,Ï+d".’B©%È>ˆº¿BÔ :6ZBÇS"J.¥?ùT”–‡¾ì@Æd÷“[Á}เ£‡€Ì™Á*#¨s€„­Ù‘mÙB!–¨è…ÝÌr[[÷ÉÎh1ÍÊ!·³åÇÊ`½þ÷œ0J?öbo œ¯««[Íñ°<òbVºioÿžÊ9åžMðL¼¯ìœã™Ìr?Nsgz'30qpì¯;N´DRì*6RÎ2´Œ>ÐòE½(‘×Ûp ¯øq¤¿4r°ÿò¡ž†œþ¦ƒ}jåÇ1, }f¡ËåýߤºfS¼³‰Žñï’•¸¢‘Ÿ ÷1ì-RŽ]€ãQ*±«»Ë°ó(«Âžã$‰;Obç©wjähŒ|`c¥q«)òÏ”ð=žaäØ,ñ"QÄöí[oݺéùùy8óøç)È´ až·¢`yiéVö×.¹¿þ*ì« Ü ³ÄSú³»£Ä°ÜÑd±ýÅC&€$d*X–]#‹)¨Sÿ˜´D–F-‘‰¦õ_fÃêZPð`C´lØ ÃÚV¬i!×`€ Ö±¡¡ÒN0c6àör8§ó*Vk‰=àAzøIGŽpƒ!h€Ý„ÇéM“õRV±ÇÂj#ÓðîΜ??¿°›7Z¯™À·WÔ•òò÷Jx†0€$31“Ó<ÏFs¬”â©_îD DfˆY\Bâv‘0»H*‡ŠÍOÀGÀƒa]q nË(úR‹>ÚÊD %ñY² QtX˜ødN!‡}.,-"–—KWQ,/ŠÞˆöW"]2 æ¹âD]ð8¿áYÃÈä h†Äâ â!z¥¨XF—¬+Üg]¨Ë…ŽžP² %ψi*.&öûï¾ £ý¿ê†JIø$”›7o2 £`h˜|·.¡áêÏ£ÂÁ齞Ù]Žï+;«œãyîÇ*ßT¶*Óû8Ó5ž=ü0sàÞ6ß³¬¡‡%ÎÉÔÁIUÿõå—ø ;×'æïñ=ÊòMí8×ý«]yìšÏ÷ü¹´ÿFLnY4GUÖîR{§c¼Ov>Z•[F±žå¢v}z¼‰Þœ»¦Ú”ç¾»¯÷zÂ%ßGû«ù„¢˜œª”kiï"׃DÏT¼wÙ5’8<“ï~œã|P4ö4»ÃÏ)×) ¢E›÷%U ë³®œ/jÉ¿¿©¨çrfï僽E=o4’Õט­eCò6P¥‚¥#i®@ãËpO'y¾MuLdxŸ¬hä=‡§âM€@üŸ q{ª°û0…|]Gë‚î³Ø{šˆÅ_ö®ûtI’2””f9Ö^Âòb^DI"Y–fЦÅJ¥¼««óåË—ÂÄ †—¯G](?¹ò ¿åÍˤÙÑMöŸ]ºF Ë'°·’tÇWŠ]GðX­ïLŠ‚IxÀ¿I!ÿg›:¨oÃ6Y—]#:ˆ^Mœ iÃ6Ûx}}Wñþ9u34 h6ésóc8订pãz¢°„ÝŠ-Z¬mÁ†öLd‚ЙÀ¯VîhÆVSH×0í­Ø&˜Š<Àc u¡²¨U/ÀõFl¶ß9~g””’ÀŠ"áÅ4¼ÇßÔ_|þê„`6,âЯéÍÔ /§+å/A!Âenn.\Y p`¡æ\-ÇH•4[Ø”È?F/!µ` €YÐ Ø$°y 4â âCúaduün·ˆrJ%\œlíÔfE>d@i4ùg9*­@¿¾À'¨( §ŒˆøEüVtÑøÆ<Ö!ÂÈÇOìaí !Û0² 1ºÉÑn4Ì(´d©±;mé<¨E»’{1ŽÕk´á1x„+à⢰Ѕ§Rø<KJJX–•’Œ§PdUªœwöù¿M¹ö Ã7ï|oÙò`–{*Í=¹Û5•lÏ“|Ï´Ìõ4Ë?´HšÈ™)þË¡Á[]·v;¦ûg£K›hŠW0&nO|Y£"¥PJE*Y&.!K5p?Öó}Žó½f³”¦‰LÕêWõÝÏuÝOòMæ\ýS\r‰ˆŽâx¸ò/¦¤«¶e&Ô‹¾ßæ_ndN¥ûŸ% =<꼩ؔ,¥˜hžå9‰tKÌuM^W}á`s~ߥ‚î‹¥uaoh¤¸§¡L"h$£¯1·»qOI.¼Ð(VLÓô–ãM¹`6× ã^÷ÄŠFÞ¸*H‚‡x?ÇNøz Ö`ÿåßV§o¤c(´?AöÇ–bü‡z)iÏØØÈ‹/„½á°;`>þÏ®á'^ ¼’`0ôèö]nÊpp<—‹Ý§þ}AýÕØ_‡ðH5vœÄ£§Uñ%4˜biжçå=7¨±®mÙ)B 9`]+6j°Ù8{ñRº„•‰D¿;vÛLXÛÞ]¯€V1\ö†uØv%d œ:°Í€mf¬ëÀÖ»u5×kêFó Ÿ|qæµ¾}¡ÓôÚ¢ ‚OÀ!Æ€®u^ÛF¬[ÍÂs5X§]1.‚¸ æ5µÛdüد÷˜(î<à¿Ä„„d“Íd2™ìd6;Kx^¨Úú ÒƒJ×ey( ¨XDPÀ‚JÛ3*Z=ä±o@ÝÙ™Y@{½ûã.—ËÙÞCEÞøè5½šÜ_½ª½òüÝ÷Öz—Ó„D/é…_~™ Ãïµó›ßïûùÓ«ŒÞklm~<3IæišÌ×Ã'ÓS0ý,_Á×0Ÿñá•\ÉWÏtù‘rŠÒF°,¯ÕhX_zôQ=‰ @&ÑnTT2QÈ—„l>òÄ6‡ Dc3:P†NºQCrt ÂŠ•”–çà TÊÍBç/¢sWPm“VÇ®Ò-YÂóèà1äVH³µÈéCM]ÈY!öŸHê=¤e‡<X\^äöÿÀ´-X#Îd €y‚6åRzˆ0dÅÆÇ¼ùøá#Øâž.“ï''ŸúmbâÉq T `Ì!3,5ÿ‚ÝζõÊ`ªp·gäeEçy"éyt­<ºÎ?þ®2nG,âH’üçlùzjûõ¿Ezï&*c›¤ÞÑ4˜ òš#µÃö\¬>·‘Ϫö„é4Fš6Â̱BÜŠ %‡~ãÿå·ßüƒðczÏ9òÔ$Ù¯ð™¿>Ë’ÿšàLµÚ›.ò4­ƒuKSçó°rpá¿·cïAB‘î",—a¥û³USAñB˜6š gN`k5výO4b¯ÅÎZÒÓù÷† æðV*6ÆOÛ €ýó}ÈÑ’â"õìו'°Ó­vl«›q[qÝYl³>´Öä¼nÐò\¤V+îÊ™r‚a¬ðÛë°­[Ïàs.RÒí"}ÕUÃóYgÝ´«Šôk·ÊyÙ+9 Î5‚Ψ¥ø×VUåGM`ÌÎNá™Ç€gà1?Sx‘"‹é…iz@‚/^h†¸Ì³ÏêtXåíA®‹ëEÔ("[;²àÏnäîF¶.dS‘ÃK`œ$¸}È*£Æ+è‚„óz6Ј­i]ã9­Ÿs1)¼Žb‚bw*ôþ)U¹Ÿì^]pL“ÍëâÓw¶]ßÒ=ºÆÓ›ué÷ÂÒ•¡,ìWÆeuRB[¾:± x°Bx\ÞG1¦tþŒ•;K¶8/[<7ß‘Æ,êk;Õûñ¾q‹8-oö¥$zoÃMº^Îm‹ÜoûRýƒ¦ÎÞMÒPf× —z-Ò0x&×ÑÃG­f9½žáõœ÷ƾ¦…Qrôú·xVÂh8Ž­p­•ÓäÁdiì'£ñ ÜâìÍÇjùt â;©hŠÄñÃØ_†ÕCXyûKHy?– ž¯0ÌûØ÷/öë<&Š,øKLHH:éT*•JUªÓEaQɈ:ƒ8+‚ J; ƒèp‹Š×8®ÇȈ@ô ʨ£ÐGõQ Î»›ýk7»Éš¬Î"GsˆŽ1™d7³»þ1Ó4ýö÷ºÕ1;k"‰óÇ$¼T:Õ¯«_ýº^×û~ªõùñ¹Ëà ¶_…WàA-öîÂÞ½D)Þfìo£b9„=°SO ýÞ¦ha5ØWñï×oM+Hd3X¶aËJ`D+PJ!^\ÁSJµ¾vã?Ý§å– "@RYRˆÈ­Vn&¯PüF‰_mN2D9Ë ÈéàYŠBáèÒùÑÑ·¤c>ü?‰öG^Úåå§ax‚ +ž¹3’ hjáÖ qßNb©ê­idø@ÐÑœÊÇÓ4+ "Eý®µ™„¾-–àæ9«qÞØ züM¿PX-äë0šþ!Ã6vážÎ°ÙÔù¡ó,v˜¡ÿÏ‡Žª”J CMœ<¢xÒqö¬N§áÕ ²WÜ”7g¿ºxæ°`Gß·íÚŒtš¥Šø¦¬uŒpЈ›:‰FŒú§=Ä<{ÈЭ6R‰Õˆ]m6[IQ:¥`( n4NÉ$©Ä‘¯oÇ(?_Hc³ð*Ûb{ÓÁ¡g$p§&‚)IÉ,EkhNÅ ,Í)²6#k?2€†ÈÖq¢Þ+¨wì8\ш—‘]&r°_!x°P_1/©h¤ÓQwÒ»QßoÑ…+ÊÜ͉ gyV•„ŽF篣n/Ú{T±¶tIf ªmEŸ[‘u9†‘-€Ú/’ÙÝQZ,P#V™åÁFÞ9€,>RvÛñD&9U3¤zöÎǯ¿0OC¡ØÎÃû÷R““yX6á¦ùwšLòäׄ60½Õ5¢õL¸ƒZP'ms”ºnïðÞÙéŸ(–F =cpÌÏ­8o‰4¹Å{7[šÍôÞ_뿟˜Í Ì@Ðo¦3‚…¾ÙJÏ-¶JIQËé8Nµ"kwË{ÝRÑàÍÜ“i@3ÙuGªü“céÃËÁ”¬-IT<-ù—Š<3µÿ¨b¨åL<¯ˆƒéÓ0´ .K)SV–ê}5ž[ņ!ÞWî¼™'Mî”Æ·ú‚±XŒ•xÇt©B÷hgD7<µÉ9Rì –Ê÷à¢mLošÞ~õÉïr´š…F1L¢Xi>Qÿåg ÕÈv©A€FŽ^úë2­ot«w*ß7úKÑHD>Jrÿ«ƒ$©]µ8fØ‹½µØ×‚{ñðaò)èÂUƒ]ÕøÚë‡] Cš°« {>&®€ƒAÎjâ“¡ƒ#{Ú´–Š÷CWk±öµaw9ËP ¾ÖL>ˆ½Iû›:|µìñv]ö2#R\Š’ŽÏQçö {Ö¬ˆ§T¼ŠMäâpà(¾~{*V«9JH`YÅlO9–_ÊSOüû]ð¤–|ˆ6V½œâø™ØÃÑOƒì7~|ë‰idþ•(Ä/(2?7÷$ÞU¼ bšŽo×®ÄþÃX®|kë,ï7Wæ¤Ój‘òSÓ¾7ŸÃú³ØnÆ=Ý›)b6`CAúB5b…A dxc³F©`Ðc£ÛóÐ2鵄­ÆgŽþŸÌ ŸéŠA,ðÅéMeËW¨8NɃ¸Üäemùåí•õÚ¢_‰êðÈI1ù"÷û¶V|¡› dp«žøÇlÁ½6²ÓÙƒ“²¡x“ñ‘ÍzlSþ»´’¥• Ï«151ù^p ð»æ/§ 6}/e¸ØÛ¶Pè‡çwz‡C¡Ù™™5«(¢šÔÊ”ÔmEê…X—Ù…z‘Lâ"Ð~˜†ˆ Ç›]’ÑE Ù¾@gŒÄ*}.r|Ý>A¥VÑ*F –èªÑ—>ÔjX²N çJ¡(«\§LYÚ>Edd‘Ñå¨_BŸ_B| Ö|ìa’ êéñŸô‚©ú(M†d”´À §N~‚Ûèõ®Ë³9r‹5VW«(JÍó'¦æhwH#ÅòÌzif“gz»{|«{¬È7KšÊõLÊ÷¶¦¶ºþ,.’Æ‹|3?·F ¤›E¾Û%ÞÑRÏø6÷T±4]äÞ$MH6Jwµ¾yΠNÛxn€KÏáh1ŸÑv¦L]öÑ)XHaÞ©h²×Žf¾)éÿ‹ ®|—¡86aG÷p¶t?ó°e5£¤xqéú²ì¢]`¢ŽË*(MY•Çp"C1lbúæ£æ-÷Oltø&·Hw Ý#ÅÒ¸Ö ^×zÆvá¤Ù<çd¾ïn‰,òý-½t·‚Ô‹$œ%ïÓÆKǪ‘Ûá^Ã2¼ŠŽç…”ý*rOæJ·~)Á^Bì¬"‘ëðäx öUâÁrüU¾ü!–ˆ.n4ãá&ì©yý8 XªÅžjì¯Çrc”й_o™8w7®N¤éĉŽAD)×Ú°wjÀΊygõ¦¼}™šdZ±ŒŽû(g™÷{Z±\‹¥*wkMA&©4ý*<öÀÒÆQjjIC=¾Üн€ŸÊÓº,šÕ$q g].vÕã@ nÁþF¢ؤ:r˜oÿ·ç÷$€iY•šfÒÒÖ~÷ï"‘P,Î`]‚Dû¿2ùiÒÅ{úô)Ì|ïaçÈ'Ç`hžY†Z'Æ=¸|ˆ”á,{iÅþê'ƒ‡35p'¨Jþ‹]åØf !nìÀ¶‰ ÐÍ ×ˆ±;¬ó6SH›¾‹°ÁaÃ6YpÛldXcwØêh{•@qù«Óç-FlêÀ&ó×'NçrLÌ• ÄÁœ± RDVàá_½R- WW<¶[0l€»‘À Nj&öCÍP¼ñ,6ub³ùag×žÌ ‘R&¨T4,ƒ,¿>{ÃÌè,Ÿ‘ù„ÈË©y•…‹m±½y{õ‰#±}0yôïÿàxžaþĬŽN´£>÷a¢ ÷²H'õ’™ìô@<ÈäF=ndþË~ÆFqÝ’%K+­4FO3šÕÌZ»¾08á²cnað¹¾ð…ð`;€qLPØøØÛ^s„øØÝÙïz”~hKÕ/=( ‡lì… ©MÕªijŒ}}cS©¡’¥äC$žžäñhöÍÞõÿ=7¸|˜úã8qZ#DálÅ„q!;ÝÚmdø-©b©Ð(2Õ‘©ÚºzI¿ÒšB ת5‚í_a½îe/É Ï.»@AIÍk5Ÿ "µQssÏŸ¡yôú4£œ¹‚èÖïÿÀ„Žeh ªø5%íýIâ½Ä»9#2ˆ|iºLžÌ¼“5<»ÓûE¼sf‡s K ]œÌ–§³äé×ä­‘$ï½4éN¶ûn¡k¬È9^èÏ÷LÈ Òx8™ãij»=ùþÉBÇÏëM[SÕa±57±²¿!9=O¨Hš[SßqÄóÛâ¾O×Ôããž–RÃØm¸=8/çVˆŠ —ZUîþ¬Ös/¶ðEózjBIòzÃ!)6¡µ¿Äskd¯4“!Ob䤻'2ä€Ò-î‰Ït–øh÷àTîèçEâ×6uá}’ ´A‘;ËöUJVÃå–CgW«‘œÁÖ¸ø ÊiH•†‚{›z <3[¥Ï~2­Y”*Ñè „ÍàoAÞf$· é}4Ü€ûú›ÊCxP½š ¤‰áKXz®JäoüÁ4â¬V„6rÌ<“× ä5ˆeù¿Ûq~7w"sû’í’’îMÝJ–_­FlfdìTªÃ4›ç,–/7Ê‹íŠlÙiÿüð¬B…öE»ýÓÃØ]z†úº½ YðOzŒæ?w˜6lâÕFžç(JƒªVG°TáÆu_^ì˜ÃõYQ'¦K²v-Yº–´(v²ƒÖNÔcFËã óã6@µJ«T*Ì;MÒžÔÏ¿UöÇ`p!8ÿjŒ^QäIÞ”Õ–¥åU¿2sð¢Vˆ»¼–ÑWÏ›Ž5ihžƒŒž& G³1 â]`AŸ\½>%Å›%%×÷ˆÀî6,'°¹‡XñMŸB+~Æl£ ëÉ0<¡æb¶óUåùüJžgudÔGƒ¼jpâ$HÚG3ÁiCö—‡æ×À¯‚œ^qÕ±ûA/ާ_ñŒÕ«DÛçç;¡ð–ŠgRͬxm`n~~­l~ß_p—à.ÊÌØ§ÅÇ ª(V›[_!ÞÉ~€st®ø0ÕÈqåZ>y»®½Øò³l×XþHÀà™NrMíy’)Ϥ8Çö ÿ¸Á5CzŒ]”é™Í–exg÷H“ âx‚4‘?x«TÃDÉ luŽï–¦òýŸgŒ—É÷+‡nUŽ>Þ8Hqï®9γa”š"õ Á鯅À&éØ!Wˆ·µ±1 ¥RC*®õ#üŠTÏÌúƒ'u4ƒ÷ù0}lÊ™ëéç}qPMèi–Í9^ä¼mžI”g ÒDžx?Óó`H÷Ìùéwp¥ùž{§‹ºûbÇÅ ÉrçLË6 CPj¼HÜ>+Ô®{ö÷¯Ðüâò,¬üQúÿ;į߀äMYUÁ‹yñå’_B¯¦ÐÊœz6÷±Å.Ð I87…rl$)€Ç@Ë%àp‚«Ø²¬‘^°º• E2è“CR%`¾ú~ Ú€­ÔÔ º àŒY1ŒcH%ÄĪC´ÇY½£ÀäÉ+‚¤@Fë­>$ÞÚm H:ݫֈÕnÐ3¨ k䊴YCÓŠ¢H^-ð,MïÚ»-.ÍÏ-³>øVͼìó‘$ÍÓ¬Y6bSéÕ_ì–)žÉi2sh2Ýÿ4Ç}[—[J²ºè­›*›öøkä»9Î{)âÃ4i6ÕÝò£k$×ý8ÃHsÏî•föÊwÈÓ»†&úfK¤©ùA²8†}’ãÉžÝ50žê{’  2vÈT²÷IúÈìþ_o.9ÎD%@J‡·ájµ ½½´±Æý»äáÇ%¦Z– ]‰ë.þ4üÒÈ]Éx· ÜUóÁv×t†ÿÉ;e ÃqP«I«þ7ûõUvÆü$&“L2Éäæäæd&÷fA: *®V±€€Ã[A]AEä ‚øÂe-‹@å9à0¼EqfîR¿ÆGAÊ"©¹cÁl¥ac˜æZšgZš½"6Ì´ÍLÏis£èœ–&ñ ¡Ohn¢-Fjª§¦ÚTG篲ó‚8”J–ÀWÀ+¸G-̦uêã§3à¿yï·¾ HïÔãëòºü÷/’wÉ$ßÚ€ˆ/š÷‰hß'‚`]­EQË*‘1r$&UQ§µEÜbôw €pâYjP› µEìèÜ j8΢s}¨í<2  Æ~Ôy5´éX†“Éx_T×…z® F‡h›â:·ŠÁËtD¢Sú òÚ¯þÿ²1:E2uõ/ɃÎ:ÑÑJ†õUa¢•sµâöðtnzþåtøÉ‹Ægæ_èt:žSƒF ã"R rœ7} ôwØF“ì“a®ûqçß#ú`Øù1rF©`|ôëò«3„S\÷¢­‰Î;†[ß·F’…ñDûh¼cÄàø$ÎþI²0’*ŒîµŽÆ ӡΩî»a®‰ûXšut›m$Ú9iŸL¹4o»¹Í5m»ë¹'L$œÿmБS+bâý#¢ƒ2ODµþïšþ‘ýa`A·6™˜[½91Õ5µ\ae•@sšmžÐ« ¶’’}8uð²lÇïÂmîiQ#âFSÛ¬“»„±$ç­­®ÑXÏ„±INtkX©/V…2º¬ íbM¦¥*ñ»±«ž«YdöVG^<©! -æY"ån]yŸÁ:öCÑȃI>ËTr Ç© &¾‰ ö{Sƒ¥¬:Ñ$ê9BYb…¸·qJfÑÁÒ±æÜCXÊc9§ÀC¹+éÐɬ„pœ’hµX†1cL «ÛõäBµ~'f§` ÆC¥)t ƒZ³¨#Ÿ:Nn⤬Š×‘eŸöäPkª«d†ÃR¢ÞBmôò1*Á*…”óYI˜Ï»SE¹9 Ãëó’>ªÝG…|zž¼€:òÄøA’K…l‘ŽÃÐ2ÜzLÉñ˜‘¨`à. Àív‹;£¯Õáõ.|5ÒßhDüŠLMMY,–ìÌ,Â`EÄè$ †èÄ„”mýçÀQqÄ<™ÔžMí9Ô•ýÊ4â,ÍÀÍYÔ]’£—a·p  ck×Ï6˜èÙî…†jÚÑBMMÔl~iœù)\;ÛÜX³5\¥ržðJu¤ˆyçò‹EBëíí´±ž¶Ö½½}7Ïâ`žÐæN@mm M5Þ¶zÆ,c,¶Õ-¶ÔѶ&Ñ$¦%À¹•66,À%FñlG#57[âÞ`À #!ßît>‹‡ÅEH‡…º8·è]Š/4=Ÿ£¯'îµI^—WSàzövŽŽÂëȲ¬–È!”ÑÚÍèÓÈl½av#“C }³]䘤ú<¨Ã‰Î8Äc€J—€:¨y™®¢–A±¶ž“òºå° #TÓŒ:á*7´Kö—b.П•a†C%M¨Y@fµ\C:s u_GÆ>ÔjEÆK¨ëç¨íì 5ÒmÓnC¦^ÔÑ¿lu¸Ÿd%lÁòòòžõ:ø cPŸÎÏ{ÿcé[\,¯¬Ñ²J+WJŸõ;ã~®{iö‘õ—ÇvX>>è¸븻Ú5±­÷ýà…RÌ«ÀlbB.@oxÛ˜~þ†~pz­ãÓxûøwÖï[)¯ªn0$s„Sȉ¡¨6Æ6í¾“p²MÉ0Z«ô›Bû&¶\úShß-­>„°y—¤d…µ˜¤)ÒÜù×cÃ5êì ñ¥;·PËÓH# ÔýÕ4\÷ðjƒž$`)Æ¢øwMM1'ÄNÍQHy¨Ï­;u:n7”ÌaNGÈ{õóÎKÔa¦=ÎyÓêvS«E¥ŽÙH»í·~ø#¸“—¸Ù–sÔÞIÔÚµº–íßiü—¹zlÔÒE-&u¨SÌÞ5guŸË/LbÀëx^Ë’WR3Ó/;tVÊJY®<;ƒÄ?~œ——'˰Åc OàJä5ÈЂœn¶r‘Ýl~ÔRý`Ur5„ìÀ€9ÈBC4ìGFÜ̬/‚=‡°³¥]hGžaÔêdôz"a‰åPY êDƒÈ݇Îu –ó¨Í‚œÔ׬^ä‚¿_Wû\N#@£n¿ `’ˇª X΀ý ÎM™é< Ïà1ÉBüC\ø±gsýý¯Óв@-!Ž*Œ£P…ïü%gøökcw*'f‹†>,ŸÉÏ–‡¦{Ûàùirúk\Y|cAV^ݲ픽fô–pße¤•ØÔï%ÊY•ÖHQhf—ïÞ«{Ž¥ÊZ‰ÍåGß Ín»¿§÷W’,F#kS—(²küþÿ=¸*4`¾E£* Ìåævú?Pv×qDJ%ŒqÚ:}ùt}ÐQØwfoÿÙÃÞ¶}Þ¶¼þ3Ëiä€÷Båày@Ô=qÀµ¬ÿâŽÁÓ…Göñ„gYV’-'i¤WÊ®ý»z0‰âÕœf1|àPŽNÄélbËîÕ_ î8«~vºŒŽ ‘C4x‚Ž×+ÉÓˆÒµê ÔwX•ÏÐ{8'IàÂ5¿™IÇjivâ#KÃ*…OÀx½”ø4Ô £†š Ò-ƒõ23×UFý•ôFóLá³k­_z›éõ³ôz3 Rëx=8¾ì:„ëh FuK 1:yfâTé:)QÂŒÀI[È2æ“T’Áq £YÍ'ê%FÇ&(X¯˜È /bG%ô)P‰È ìúL¶·æO©¹~’FŽ©‡Œ7¨k¬aQ»äT^†ëæÃ-Îú‘Ñ`8¸qdgšŽ:ÝOÔ¹OüçÕˆÓN{\•ßφÞàM9WZ3[¨;Îø¯œÓE»Ôn£nç‚ÍH½kežå±«bÿ¢Å¸hk§.;µ{–íßÒA{»©­“º@¦E«é+«éŸ6Ûþ,}&Ë ØÊ8nMJúìôýèËOœ•²Rþ»,,D"KWø8?ÿôÑ£GMMM,Oô¢¨c/&ò ª1 K/rO"Û0r—´{FU6x"ÈB¦a•"î0ºì@†·Qi1êc¤hײ„y‚W¥ éDbÖàq].²Œ ×2v£œRfUj¢ˆ“%…Y·]¾Œ\!Ô}uù{xY8#ª‹ŒjÛä!Š6.H ޻Š3ŠÅ–¦‹×h,¶ôqiî0_È—Š²r™%²–ç —ñFžàíÿÝÝCw·NÌø¦wDf¶‡>RsÍÿIÞèýâñû¹®›,ÑeËZØŽËÃY&IÄ  sK¿Î¸À„òRýni¤dôvMð÷[M¾ŠÀwg«üSÒ†R–ÅD›\xºç`h&wd¦ÀÐGÓt-ÉÞ”ÿ E BzÈ÷©Ñ¿70U쟽”¸Þed}æSx .>ÓP=Ð^:xaw_kíÐ¥†‹Uýʼÿ›"jõª©¼hÙ?ti·­Ä{©ÈÛV5Ü®ÏY†Td-f4)‚DÄÔg߬9Œa©£ú–õé0„  ëÇ©ÿ<‡7cB$ß‘Â,ŒŸ¡×ߦ#‡ÔÛÂõt²‘úã_i¢ã†þê /&æ|éF5ÐÆÅÐIOàUJ¸ÅH+¤¤¥d x,)E9ï¶l›2~j)‡>c!xÜÄQOm¾Žˆ˜ç ù™ðtÕ“»+×)‰ ˜'Š\—Ÿñë+U½ßX/1x}tÒ‹²TDÀ`zöè›·ë]µo~î©¢áPÓB¸Ea†ZKGR?0£Nm–]‡ƒ0• ‘£0ªÿÑ[æêâ ¼® ‹eXx. j’$"‰+ A1I²(Ão¦,óx-fÒˆ&;9±&W÷ËÖÂ{¨ÝÞhP©OQG‰4¾0‡|­©ø#ÂÇUtù«¡ñç¡–‚äDIHâ1FÜ¿8Aû&ê°=·Fì¦Gf"àNLÈlûejÕtR§CuHO7µ©Í Ý “j´Öo݈ÈK]EmÚcZ»¨Ù¼lÿ00øº±#j½B]NjuL½¸QäÀðñÀY‘Ûž³mþ˯ æ_z쬔•òmRêR2z¨ß+Ð2à ,lø,£0[ÊP›yüÈ9†l~äž@WßAÎ ²Ž ž1ä wYÁ'at¥m*ç4’ÈcT¹ЉKšmoe3’ÄðzQaa ø³Ð©6äÆxQµËY:8+ñ\†„HúFtÑ‚® £þêX^#ad®QŸ/!¿" öxh‰ôú¦Í_üãsðÆÒŒ¢Ñyˆ˜…%–ÄâúŠA²@}ÿ77žW“ˆÇX^µßö“\ÿÇEÁËFïlΖ§7|°=Ìïgî$ w“÷*¼2Ï\M>ÚDíÈ$Ì3„ejCX\„ Zä‰îNØæÁFOÅ)$ùëO>ÅØ€qײeÒÈú\YY~ñ"éíD††ÝŒ¦èí¥¦,÷l†óF¸—+ÞKöÝÊçòø ÿ$…_LóÏõMrlœ‚%9šNlÌð,æ9çóúÆå;²ó'n¬e\H ëùiD#nGÓf©¦J•Ïä$ÅëRY4cD*·!=>.’¤éމ†í`ÂûŠÓÿboGþ:ä¯EÞcØP÷BÇ_‹>‚3µÈS‰|0 V=6†à ‰!c|ÿ<…ãÈ]¦›§ ›¸¸‚Xi7=±5~vRk)ßߘ]“¤6$«Š7ÕîÛb®H³ëS¯¿WðÔª]qеV܇@nT€Ù0‚Ípë¸ ˜äú5ñz L£ÐÑ+¡?Þ LT|0950ó• [d ¦b"d²žÌ 4öÁ’¥™^Y##æ…§(Ž Y%KýõÔ{Á1+@˜"C!EŒ ~ÓÛñ[cýŒ¦;'[ŸôöØHZ2ÓdBý3¸°áóûà9#Èl^±X-ùÙ,-¡9VA±4E±,3<<?”°ªay·¼ô질™7Ç›ãÁP@¯Föò2&1„ö>C=ÍÙ—ù à:@A.ß4é[{ ‰zŸ°?DÂ6EØİ€}2ê&FbØC\óXØ) { ™@èÛˆãg‰w*E,f G‡ç—Bë1â!ÞŸ&Ž‹ ™_Ê¥DZ)qÎB4´ÆÙ·Ä-牱Oˆ~ÿÆá‰K׈!›4) ¾V$ò¼¤:ØXWW¨¬ >}‰ÿZ-N΂F(´]7þ»=Â×ùü#ÐHŠw²8ÕõE¡çŽÆ¹Pà}²×»PÌ߈ٛCIÂiJ¹}_Ñäõ$ßÓ,a¡ÜñûR×—±âŸÖùñ_åµ3ãÿ,‡óÚ©o2ù;IŽ[ć0äDç\Z`1W\ÜïžKwÞÍ <­œ¼^fw¶X =kö€Wé,•tÿü~ÿ"&\©â( K1R³e_BÉÀ)Ý垊‰žÃW;ŠíEW;ò¯t¼3ѳ‘FJí¸h&º1B®võö^ÍP»" Ö C“4¼;Xœ*ÃR¼ÊÜË7$9žÙla.S¼‡5½rm8ÞŸ\#B}(Ê!¾!¼Zàß ×x:;†âÀÞtSò&ôi7rW O òÔÅ:ä©F¼]kÃnqÿ}¼6Ž¥Ô,!“ 3rT¡icMÆîM,IK¥bÃ$êѤZ_ˆï"‡i¾+#Ю¥åjš‹¥Ã‘Ç€\:èÀ‰ƒ‰ÐO !ç"¥”"Š îjC>÷Òdýãþ¢/»Ê V<ZƒB3šnDÞ2ä„Ï`xx«ÀEH¨C‚Ÿôèp£€wîªØ‚¼!„Úæa 4â3"·MÑÌ |#\ïƒi9ŠU32›Ð„ç Z±ˆ•Øo3õ¸0'@ð†Ë€iÄWù*Œ%\¯Å¶Šø Ò€Á&Eý©‘@¨{Ð4!„4â¯û7ûõÓT–Çü$&$Mš47777·9M[R`«Œºêè Š€Šä¥(* 8DŸ™ôôÿÉ`*ܰZÆKT 9´ÊñªXíˆS¤oÆ ÜÕ¡ùׯéæ5r–ÚR[¼ÍͽŽlüƒF‚!ú Äø«Ù¦¦&¹ŒQ1ðÃ+% «ZŽv sh0à@VdXPï2{‘ÁC•rÕ‰~Þ.ÙZ `V)‘`^!ÃJV…5$/[€ŒfÔçE½"2ß@3Ò÷DmH¤ Ïò’íÑåë¨Ç„Ìfd²Ósv[ÕHß꼉šN 2,üšaT•ßÿ»6‚ÁÙ…Ò4B‹Ÿ„Èwß¾\§UÊ1ǰV&WµfYÆtÞélçTªe,wøËLg uô ÄY¡ãlç9ý;Ï]—rx%½1Iͽٮ'›]OËœw×5ml4´ÝͰ?ˆäòßóîÿJ#Ù®‰]Öñ<«Ÿ'a×¹ì§;ž¤{¿ÊÏ'¶ØÇS¼OˆãCþ,zY&¡^¨ú5–Ë´Oå´;×ðR… aùh–•2Ja{ñžJý™Òkç${- nœ?°E Ý<¿°½`°-ßÚ&©ºÝq¸ûôºÂ49Ãaø)ßœxúä),`ø ûáÅ;ûìþ<÷dªëˆHçš„oó]j2ò ²Œn§ùh¯­O—ÉS8AÁ|cý˜ØÃ1:é WHF…Fj‰«’¸JC®S1¬œ‘a0üó«•d¸‘øjK¶®W³ŒB¥5N&öRrçÈœ½þ¤N3\½Íß™ë¨H‰ã¤¼”×i¥á¤†à®z1xª*Iµ™Šf™Ü¤U½% ¡ÑzbßOÄâ-'â!*pRL¼UÔNžC4ÐM€ ¼¢`¶î:"A Š4ÑE¯xC ÿ $C'VM…%‹å”b)ñ•ñ ñ”Šèè€ W˜bDá±~âøIÒßGz äJ1ö£ñÙÅö´Ÿ® Ï+A ACï³³g¾éî"ú+ÄÔ2g»;¢÷‹Ó§6DÃC‹A%<ˆ –MLX?5€[úõÌ+Óðòm©-µÿq‹Øc$¡ð} …÷·àµûçà+Ø!ºDŒ£9ކ+Ò訄\ÔØŽ®Ù©IzÈ|‡ÁŠL`Œdö _8‘~í)Sóq F¦”³?a¤ï±œtC&Ò[ѵÏégãÉŽ‚¨UkQÝ)d0ÉV§h¸(†A%-T8õ ¡kaä,¦‘þ_¢.¿^¦Œ~ÅjVvñlóG…k™™™yS)˜džæ øþšŸojhP€–d Yüª÷Ë]¿ÉpOçØçø¦vŠSÙCwê}Ït¶ø4Çö Û3YìS%±¬³æƒ” ñ·Û­_¥x^ìÖsx¹DÀ1+Ö¥ÛîGr™&»XÉ;gƿطz&Ó…b2}·ûî.—?Ïö°Èñ|‹íËrq,×1–%Ž Ã_ï°û3ÝOs­…ê XèzOÒœ~ \JÅ%ˆl 'áÙhÓÆð<,!Y†Åñê5eYù†û[‹o](»Ù¶¨F®·€Fòn·eY.ä^o)hͬ/‰Â’c†„|rçSÑå•ÉXçÕ<¯=a)´ï~¸Õ1¾M|æ~˜+>γÞ™F\¥Ä{”f.¤°;¬Oå‹«G F©æqsÖjâ;Aì‡É0¤?¤[Ó¯ŽoÿâLñ4Gð#cM¬Z`8>¶3KùÇÁšñÓI›Ôð( R>¶"]KÜ'‚Ž#¾ÚT™ ey¬x×ÈY–°íh~èN•†óå£6äi"âÉ7ÎñB²ŸœñÀ¯5$TQŠ Õ_cÐQJ>ƒCŽÐÉûŽo±ÕPŠ€"|°ÿhà1\C9±@]´ÀÚE¯ƒ}/ñU‘áz 5 ¤–8kh²CÄÙ!åÁ<îFân"®£Tq®j2jª¤ O å̶Çh‡CÀ!ž(„Þh¤’R>"£‹Ïçm;\ œÙYIF‰½ší­'î²ïzkcåRžWa/礟֕ƒñm5BÕ¡¿ü‡‹mJž‰Â8 %q±ãuUDßìÓÿ`êzÑúñùmIŒLÂ+£×Êã¿o藍ô¤·‹tëƒ=]³Ý—)Z9¿·¢øNÂq@xUíÞóòÛ¯ÁKnhòjþõ ÍÒw#èäŸ=Km©½“ÁID,ccc‰‰‰‹aµË ŒZ`¥jͲҟ¡2  x`C}@ˆÔ;ŠŒd° “ µô Âchc=èp3ºÔ®ÚQŸõ[PóY™³‚å¢RQÛ%Ôrc+‰Tu2ݠ؀3ûP¿EÔ/"“ˆô.Ô‡;PHD×ËòË/al\¬ö¯/ÿB´L{¡Š…’æBdnžL?œà9 £ÄRšb8îʯ·[ý¹žG`‰'"!›g»«ó=Ý(>× Ž´X>ÒJÁJ¶µÛ6¸ï+‡§ Ü÷–ï:±„åxÝÊäèâæøÝ&Ýþ½Ÿ';&rÄßï¶OnvO帟åY& Ä'Éâã4Ïtþ­ÀAG@'úSűž{i^`À£m⣠ç£<Ç$òÎYòoöMâýlo ¡¸Añ*R©Ä°cxÁË9Žc¬Â«¶|¸³¦´Üpaÿ¶a~XZ Ûò­íÙ·ÏgZZ ïsvÀžâ[«Í­›vgp˜ýûõÅ•ü%&$›L2™L&/3y“]6 ˆÅ£UÔªpñ¿E  uEAK%Z©iÓ³Ê]`± Xª.ìîÌî5wæ’kÎ#w—ž'P”Ÿji/w½ËÝÅ“&wñä×¾ûôÈ¥ ›xmøæø2afßì¼yßÏ᪩N¸XAW–¶ñ«ú]Ô{”v¿EÕ ­“jÍôØwÖšWr1;Ëi׉š} &Gis:"yµDNÚXK[ìÔÙH­VÀÀt«“ZꨭaI¸êè<'Ú r£y†!¼@ôŽNÙð~Qá©´ì}LzËlÁX-?>‹Æ‡‹6Ø´t8©Í>m·S›•º­Ôu‰Ú/†¬·¾—žÅ1¬QoÀ¼ ëwí¥ú¿«âJ¬ÄÿqÌÌL/Ö‹m}rr²úð –€"<§3`¢ãM«ÒKP½] !°üD./jò ‡]îÑüàö"çUds#×etùºâ×ziíFÍÞU{É‚Q¡“^N@9»±¬c8جCÖV 6î ªU4–ØÔìGN¿f¸¦CA¿öqïÙP|b4&&ÌBÓ»z¹]Û»†Ã0æoi$¼³ÚAh7…ùp„Õ}d|jþEöƳ|ùê$’"u4Ù3œæ©òß!1¯Â-ÅÖ§f¸ÞŸšHM7t‰ú52ÏÊ<–ù5ŒLLð/^sä<ôA­!Þ¸¿»çóÿÄŽž/“ÕûÝ£Ùž»…?JVGƒZ»ÌìLó fùFs”ñݾ±\ÿxAðÁ çÄsfV×XºwPJÌ[-‰ËÑøÓ›—ÜOôz–a ¾%³¬ œ3z>f׆”²ÂÒÚ3Ç[?(¿r±´íbi{ùÚ¥ÊëuåW.µ¿›Qm–ÖY‰ƒ™zŠded~ýdäùë۽Уa±8~½ùÂþ¾Dux—úP—« ÃSÈ]zœËÕijùÉtëæ' ˜"Ü~'¹]ìުÛXÌèb„î`#¯3a€®Œ%™'$^ŠxÐh¦ŠúÞÞª€[Y.–àH>¢îlÙ&CD‚„JÓ¢ih/ ”P¥ò©÷ÔŸÜÿºqš†ÎPµêŠt½Iýå4x\ÓH ’†Þ|ñíû–]ÕaoùŸ}g_‹d`.ÀN-^`¯—”R[ãS[=m²R§CûY_C]ÛR™sÔRËEÚì~jsÔge›8˜ ;ƒÈŬBˆðü™Wõ¢Ï|`àÑì N;µÖѰ‡›6;5êÀ§3Ül£68^ —ýâÂOrã¢L‚FžÕö‘1QÑ]ÁÐÜÌ ]ÁÈJ|¯b±¡CŠéYê¹Ü%JäâD!ÃöРHœ»€Z|èJª»®iä*xÚ{-ˆl` Ÿ&Èf¨ýÈEÙ{Pë-TÛ‚ŠÍ„D%p\ ÇŲ,gŒY•Q¤ÑÅéÕ@Ò8¢½S«›½Zí Î_Áš®1;‹tœ!–ã·#-ÎhÔ˜¥³‹·Ã^ùFæßÁÿª÷gϼà@Ö˜7) ô© ïÖU½Cy7ÿPàíÏz»V/I°oe¤¨×Ôÿ—i‰ÃþÏ6¦—F‚CN0D'çUæì¯z)zƒNˆÉsþ<³ëóÔ?Ýb åx{zú³ƒ÷S”}ÞÁ};”{›ýƒéÁ±üއŠ}öûÇ_÷íé–d«^8'ž33:ûr†Ô}2ËDà0¡áÙg³S~ÿ¶mÛ$Ž3 BÆÑ¢5Hˆ+²Ø$®N^·uoV²97¡8#µ$Ǹe!ÞÈ ¬„1 R$zAJNJz86è„úÙÝ~‚5<ÁÒ+Gêözï‚ô2M#@‘lu€÷]i¦hdvzª­õ# 2œ„¹þšýËîbJÕãk§Ïg¬_Ë3Q‚$ zQŒf8c$æ0ÑÇÊøv}) "*§•o+=_¼õD*±•l°˜Ã¡óÔSE}oÑ@uØg¦ÝU4XMÕÓT9MÕjÍ!²o(¢Vh (/¾wÿðÒWAƒU´û¤çØv 6•LkaU!±k>˜‡XëÂN°A#uØÃŽÚdYJ#S. uÙ©ÍFìSÎVåèÑdYˆ9™çd–øx?–´ù·çÏÍ9¨­–6Z5{¸a›5Üd Ûë©Ã„Xk´ƒë´´}RybK$¼/<'r"œ•’¶lW6e‹ ãJ¬Ä÷"`í]ÉBÀO)½?:²31QÐEhMóFž#r *>„í¨ý²…P½ª¡¥µ„ àB¶nÔÔ¥á,ÑBŽ‘å²u¡ö›È݆N‰HÉÒ‘8–¼ŒÒ‹Ð»ÔÖ‰~ä"§ŠœdŸwˆÛ?/“ØxÐÉK1EòR¬ ÈDúÅ/{µñi™þïøç¾5þ™9úõäßR’d ˰ýÀ†—ß8 Íì±@‘lÿH®:¢PNº>˜b7çq¼'ÄäËŒnêúKŠro¿CDô/Æ '¹X¦ÞÉQîT¨½)ï_1+}™u!%’hN·)sûÉZ³çÓÒÀ£"ßDfÇð>uÄìéËT&rÕ/ |ãù÷ :ïçÆs·ûÆ^8'ž3F²?ê3l?HXÆ$‰'ŸüuVAíôÔÀïûŽ—@š$"CÁƒ'±AÀI°€‰€eÌ—xŒ)l¬lˆä‘á`Å/((züø1,ª [¼&kƒ^"`°ÊÆj7Ðq'CÏ÷d@#£ùÞ%¿Ïåj>N›[á{ƒ æ Â)ì`½yÙ]¬§ŒúÍuê­=p®`sú¦ÿ°_ï±MÜwÀOš„„dÉ:N'[gÙ‰’†¬´JmX‹h3 I€„WHº0ZÈ›¼HHaê`S»–¼ì8öíM!KbßÃç$Ðý5u“VZ””æÍ  ±P4PâÇ}÷ýÙ)›¶1©ƒ*+ÊO_~9ÿîwýßÏ/%§W&›K_f‚6Þ †¤E)ÈE0Pj HÕ Õ‚¿ ÔJPËà#”F ¨Å ÖƒV2þ´¤Jñ‘bÐJB䊊ãIÄ¢§ï§,TÊZP* x$gÇІd†3²Ö¶Ülø [ïp‚W§'¡ˆøŸ)B¢SÐgÔÑ ¢Îö˜ Þ\¿®.÷îþ èMÿî}“?û¹~¼ ç:¸±M tº E!€’ñ­àÆŠ+Ö†:q47ÏÊ1·fÖ̲¸÷WT~yç.üRY*ߪ‚I<YÈéÑhc!­Ï‡Q#·ôØ;·ëhƒ‘7›$È’Tƺ<3—jõP¾³”#DÀ tSî^J”(_h!¼å•)¡º(^b!@uJ”§—rž¢:º¨ŽIK—JÙÑ!Ø@¦¼R¼¤ˆD(âR¨S*Õì2¬-°2lï7V¿ÕˆŸ¹†(Š?¬/”…¥—¨'þÄ.f7h«Í¶ìù[û.f¯&ì±1 ’Ì…&I°d2–­Ng‡®¼ÞõÛW‹Ì<ûJ¾ëlfpöy?¢bøåÂ’$†ÁThz%oSàÜ:m’üËòøÆÀÈ®ÐåâîaÛK;£9Íd£M¼‘INÍܳËûqÁàµmÒlAÏo(—Ö*Ó?þnKh&O›Ü$oÄ4š#/>'3ò»?}sðZÊÖަ“P4=zqèÁó˜ŽÇ3¸w÷Î@¨°¨·òIÏÓ¬E@äÌV­ˆu” b„M6ñVšKfÍ«¿»ªëTOø«)ï 7{6Ãý€ë…¶)c¯©ÓyÉ|yÐê@;2Ô”¿ÊB᱈gøçXÃìÑwÀí¯.Çœ³…°¤£ýQÑÛš±euá]Z›HEt…íè txÀ{:Dhm6kÁ .wØÑ MàuB{Ø›áÞtý±©iË‹«Y‹‰fÐöæ >wg¯è‰ÌÏãbÁÀm0±·cåHKe©|#…¤ïX41i¦nL‡^aÈ!Q:íO2YX3ž`Í´…³ ¶´ÕÔÁÔ¯›ˆ¢S£\½”€ÒPÉ5Qñ(”ÛOê¢F(âÓ(·L€Pù°Ÿê¤D•ò Pn¤K¼.ú THc?ŒK&øz¨²–NFÿ³´1}eúÔÕÙøƒ8þõù/²äÚéÏ®I5=“bXn²X¾×М£M¼*Í$ìéi‹4Žud V ûFr‚3ß—/oUgöž*9u®Hº´N™þQðZQ»Êp|:Mó\zÞ»¿ÈÓ¦7¨³[¤[;”ßHÓÊUL‚Ù§Ïo\Èêy¡ôçpœuEÑþ-Ò…µ=;ú¯eI£¹ÚÙòçë¥Ï×+ãYÊT¶4°3¸øœxÌ(ÇÖ÷L¬©s¢#Ì´ÑÂ1-ïE=ÄÂÑÄààxDãShôýdhØ%zvîÈOK}‡Ôd$,I5™pkGi 3*KÊCƒþÓ_¢ñÉÄLh ° 7™a`ÚÞyn›6ùš2³­o5²QC™Ln÷_~r‰Ýâ¿uÙÄÃá¬7~vl÷ÿ”ÈÊá#C¨ep¦‚„ƒ@;Z”€RC± 9l|Ô:Pj‰[Bõ Ô@ ŠÜÁÕG´êûr©ŽÏ± fÆ·ˆCBq~(û EBµ$°¾øéûé ©” ¢Vݪ+Þ`2І•HcÆP÷Òš¨Ð "ꢼ®ˆè€vû£4>/8ñ°ƒàÑ©;Žé¨ŽN8ÛÀÝ®“û.8yÉ.Qïp€Ï¢ìïƒË ^ï-‡ãWuµVßn`™KJÍ'¥¤ŽœŠE"‰u‡çʇûù›çKe©üßœ´ÿ~ç/Éø÷çáoáH梑±ÑKy9›-Œ…6è†ã 6š_¶se÷RÚ#@ye"Q"ð*”G"Þp©”[¡|uR#ØèP‰4*¹ßÙOuªÔq¼/“Ç}JQ"våw¨Ro·.ËÈDüp,Ã2t§×‹k ¿9Os±ØÂrûjÝ-,;<4nÄ´eaLÉ,›dK-}OÜë?—« 6Æ0þY#yÒx^p*K›Ù¢"0.J“›úF0;zgV–¼Cs( >-c[¹zi“Œp*ß?^®]Ø+žË-]‘Y–]˜ÙÐVv⓪žÓ329Ãr£5¥T~Á?¾+4µî''ªçË”‹?Tǰÿ¬àì&íÊÖàÄitÑ9ñ˜ Z§\-~i`xžãl·:5ùÞƒ0Ùc ;a8[2=ªÇgÔÜÜõë×G.~6tþÜÅááO‡/ܼy3—þ‰Åñá,ÅžR’’mV¤ñܮÞQ/‹þÉ|ylziƒŠƒråÉiDŸ#ä í‚…eMfÚf¢Gšwí,†ŠÖƒT  V@ï^aj+וÐj íq(¨35Ä*¨‹þP*`R g«@ۃȘ=нU’«RþZ Z5ÈU T„ ?0°C¤¾T®\üôý”E-±"Í™j<lªG<'q<Ï›m´á7t·œ- 8ÃŽfð ÒˆÞÖ‰\íàrÄœÄ!1g›noN€ë1sÎÑBx¼ ˆ¤±ãd‰·sâ½÷ùùIŒÑÂ9Ž]i²ZŒLö®ü{w¿„øùL×ÿqFÃõ”XnKe©|+ ÎÞ‡& ‡çLôâçYˆE`þ>þ…ðí{ýiüÕj mͱFŽOþNÆfêm;Q‡'ôwöë=&ªì øMšL2¹¹™ÜÜ›;™ AðÕÅU*î¨uÙÂ" /y®@å êj¶µÛ´Q„að•µ<†ûš; 6»MôŸ­ÿ4­»*ò‡èni›>¶¶1Šóõ;s›íÒ„´ Ù]N¾Üœœ9s盜{Ï÷;” )ÒC8áR(·Ð¢¥›jí¦Îãx7Ñ…¹¢‘ —$ª¹›j褜ê"~ꡜñIs/‘ ²ä¼D@²»ÖL‹«9˲Û6o…§Ï3 SëS,t—ùÏŸ H‘‰‰ * ˜$Ëa¡ä£2K·^ú)LÊ0^3´ ì>IPïÇûsÕ¡,i$UÍÔÇZ¼öYf›ßžgâlŽã®4ß°]Ú­ 9äϳ®|ºv#ká#,&‘ að Â®ŽÈ9±~ó*µÐ᥿ïý]R£e£˜è”­š‹ºnçú>Û&m“FQ#9Zÿ’sâŒ$eh‹w² ëב1›q¶2LËÂD†K£Z°¯PÍ( õ«âì¢Úû(·Ný´æQ¡V^´X,7nÜ0°„oÙü·P’ׯ_ÿÁ›qF’¤Jr‚ÀòbXxùû;/]ËWú·w ¤h“õ‡XOÓ½CqÊV· u(Ãs'Sº»Cq¨ãH£–%zîÆwÞNê0è‚‘%O¼^s:„cl,“ðý½GW&år¢`6ŠÜ¢B7$¦yGÒ•AkúþH2BÛ“Ròbâs·ÝÙùq¢>– ÿ9O6€”¡âï¦é£ Úxœ2¾E»›åÍD·hYòx¶>†ƒKÎÿ¨òŸn÷ÞË–G_f¸ˆHŽæ,´Y°}tU{>õOôÄôììüé Oj¹öï‹57f¬é¬1óåúN?›x€c5ïE[ÌaL¨‰ s”œZ|ž‹Ö!Q`Úålâñ)g­6†í¯Ï^ú²ø5 %({@+ :ê0¨eà¯iÚk¶ÅF²w΀z<»AªN(m/x+@ª?“}%ß®½·gêB%\Í?Z«8H¯ o¨E„ ‹Î§” P‘‹ÈŒrB;Ô ^ŠYAOôV€¯4a)èÕ T‚T½?ôËÞ$š­Œ™µ0,G³6ÚÌ™6ÙØ yYO\-Ðæ†»œ jd¡xæ:p¡C\ÐÒF‰}„M=´ÖCs=8]ÓîË J¢8à "Ïó4M¯]»wEã?Q.·åö-i¤Là‹¿üuoA¡Àñ¤Ö3D#4òF<õã³Ô™rû¨zÕæ§Ú;¨¦Êí¡.ÊÔ%jÕˆCÜ2uY_P#-ꂟˆ¥U¢bâQgÌøÞíÚµëùsBãŠmjjê¿§ú÷/þÖÒÔ¼fÕjÚŒ¨áXšAÐæpvmÜ–-™þ[XÜc{°âçwŽäô'IýoKiú8’ ]Þ! ìèé'NÐF’¥A "ÄÆ;Ò­Øý56AY!®âTjßÃÊDö•Áèuo†!~ö{ï6í躛ÛõnÅ&ܾlšÃCY1ÔŒ0ZÁDÆdöÈÃo«c߃de í?—Öu }’­ bïx†Ò»ï¼åÙ¢ dɃùÊ(ÓRóãKlÿ Œk·"vZx>Om i †C¦¦çöÉ9„àSdÈdn˜t¦§_ÀK±¼bI`æºäÁŸ±â̤»s½äJÐJ®ÏM‰ ‰bB3ƒÇ– ·p¯™M§¶'ÞúÑÉçn$„ Ï@s0ÜÎÅjšÁíB„Ì6ÔƒË ­-„4î³Ðt6àv>hh(Û°n ƒbì"k¢9Ž+++{üøñÜÓúê•YnËí[Õ3h’ÀÏ?¸²*2 Ab¡+mŠf!l5µ«˜º Qí¿ \}” ;ÕÞCµ{(Wåì¢ÜÕ†ƒÚ‚iChT›L8ÎpQ Ë~«7g™œœÃBsk¾–}e3JÂé“¿?väˆhµ¡Nxš±ñ‚‰9{ŠãýËEÊí\u8IMPî9Ôá½ã™ú˜CÈP‡²õ{™jÄ@^±oh$MMûÉE–Â&"6Éþ³®=Ò'ö®–±Ñtdt|²|3KŽ­<ÍÒ‚(М°bcrÁ¶}Gوע8f…ɱ.¡H½™" ¦ÉCñ=ƒ[Õû‰þI¼mVOŽç“íÒÈNu4½ó¦C»ª÷ç©™Ýéúƒ%çÇ—"Ós?]ÿ<Ös7µo(ëò‡¼=™631ϱðÉI©CƒÃÆBsÌL/´a'»™¹ ÆBã">CΠ¨p¿…7‡‹4kaWfT¤ªËùš…Zþ# VŠø^ùT=ÔQºÅÌ3‚%ähŽüU ×Bwù?:O\¯s\Ùk77ÉÄ ¡¼bÑòLw"õ-@¨è¥ –‚|zkƒ© ÂYl>ø-­TLì¨5 WèÕpµ ”âà ë‚3Ë>m*ÈþûõEv|’M&™L^&/3™ÍþÈ‚,Ü!öN‹PŸ xŠþ–¢QÔ+Õó½*°ìòcù¥r*¿vg‡]¶WïÚ¦il®½!¿Qï¼kO®iï’6i¥ËëwvУ&Öò—±·/ßLÞÌÎξì¼÷ý~Þª¦Ï"A—Ò´(bý¦ÈeŸ)Ÿ¬°sçI]±ZHMi¬'õ@ Ë‚5b­&µ6…1¶©šÓSuUŠIjíSöæ_*‹âY­sÒq<ϰF½¡µµõɪ™õ·'ñ@ ´—¼ÍŸö`’‘¡!sj€ä5QG£ ¬eE^GEÆR§ê¨f'Õà¥jT£D5A¿“ªé lª^RÈñ,´x¨:‰²£C£Lz¢YÌbËÉãê/ª«O-Uäy{u¨ Kfɵ«}ÙYYÄÓzž]ŒPÃkQHðêœÕ?»æ¹ºV¾·Î5šäèC©Yƒ’¤îñDÏ=ЈŠo뚟%qò7™]ýñGNÑœ(pP&õXµ¬&-Ò">dç‰ i,³»ß«ÇœÀÑ‘»*w·]ßîXYzBË¢×xÄê–Å;ú2<ŸmëêÛÖr9öDGbíå¼®›Yîñu=Ñ® Q¦c ×9´É1˜#$IC±ž;/œOE¦ôYJçPfÏØ*év’g`ëÅ+ºå‰ˆFð'À?b“ÐôÑCe¾ø|æÑ£y¯Æ÷˜”sªœU.Í<™]ê)t&gg]Ni©´»ˆçiš7lmúðuçx@#/Yty¯RýÝ%¤«@…T2å=vaÚ¯K¿i;Hûˆ\ô°ëP”Ž]‚¨¼†§ƒDQs"}eþšÅ$b-æõgá9ÅÊ×á9žRâÞCäÝŠ%:žž=¤UD¤½Šp~@*$Žâ‚ëûˆk<¶¿"7;:œGÈÈÓ<§lch˜Œ`â„%Z®·¼LÃÙb­$•'I£•4Xgí6R®¨_¨F|¤ŠØ+I]%i´ÏÚ›ÿ~ºº|íº0–á8ëDóF^LMJ¼:xK]Dj>œÛy=/Z ýÿ5Xsó_Ùð*&±Yªa×*juÄrÆ,L¯P9»¨úꜗj”`4ÈT“[‘ hˆò,48©'|WÏrœÈðX[¶|òë?OMM=5Œÿ…"M©'êPݲ¼â+´Œ9#b cA«™y憷Éý¹Ý#‰Îá×xœk,^Ÿ€=T~@€L ÔÓäöÏS½÷ÓW·Øß_¹ã¨¼# {Y^ a5ÂÒÑ­¿]ß>–qÚ%`=Ã!,¬9Ó—æù2VŽú±•eÙ%,cZ½âÒhŒüEð–#6[ð¯‰ZZúJá©ø‹ýIîáÕ)®;Yòý”Ž1è¤zîÆ9n½p~<]å¥á ò@žk0¾ýVª÷®‘­g~iLج´˜fÁ]&7`³lA^~ïåÔwÔPßÈãø‹Š[üßôt¯ìÕ‹Z-bL ˆˆÜ¼?·ë†YþS@#/Y¼Wª°¡{7‘·gñ–©ˆ8 Ïœ/t–Ľ™Fºr}½om_¦×Š0‚uèÒO7ù0Ü“ò*Êñ„ßÝñ#ÒSN\ ‘bâ*&žB¥#í[ø@@£"â)&ÞbH[Ho)qíüå|qqr‹°ÎŒFÄübàfAˆÔŒˆÕ#ÍÆÅâtC£B‘š …"MÖéúÓ³µ¤º’Ô7,T#~~ØH=˜¤‚ÔXIcËû˜—„0¯åE‘1Â^{¼üèää?g ûíáÇp„ô8Ÿhö]hSÓs«`®Ð“¹R2>Пl^Ïb£ˆ ¼hbYd0i–ÿzËBYZ©&?EàØì¡š$Ÿ©»ƒ:YEÂMJ  i‘ïtÈÄ¿Ð`Åù|3þôùã¿­¾'…F½SÙGøk¦Þf1‹<8šg4K zÄ€õ‘KÓ,=éÎÑTïƒ5®»P¼ò¤›*Bæâ„Pû›iŽþÍ=÷2Ú†Óåñ˜ÎÉö÷…•ù‚Æm3½{h½<¸ C„¨ {’¥ñ$çX^÷-mB–ADFŽ ÝPëJ~Ç¡Á:¦1d;Q„XF—ïÊp¤zÆcÚndöÜIìIs æu ¾p~<Iî¡7¤›Ùí}yÒXBûø:×§fçíÒÇñ[öê#¢ƒ ……c‘Nx –††.+ûÃGýëá¤JÙipæ,™TgÔW&*Nfxa‘tØhx%qû…+ë:oæÈ÷yÙ¢ˆtƒ@#»È¥Cÿè,#®2 ÁT[ñ*ƒ‘ báë³;‰´ãöÉ4-Âo\3qæ0q—çAi:œ8deÿ&¿­°ÖÚa‹,ŠÀü÷Aõ,Çê#åäS–ªY¢jÝ”ÅMÙ]ÔÙŽgj¤êÂ"sTŒi-‹ÒÓÕ_U¢twž«‘ÿ ¾ù+F ŽòÍÀ†¢¶Ú²X¯X(bE#a+Äè#¢ Ê77ü"ßqk‹g,Ó1!ª°B­n9× ì®íÌÆÌÝ£I=Cë}Û¯›µe9¯ezFÓÎýFäCuLÎS!Ám›äÁV iƒ@¼Á˜o÷˜]c y¥n0bBÍ;SŽ]™¶ jF(üí÷RÚ®æ:?Ž;Ú²µ©7«íÊy ßyç…óã©HôŒ¤J·³]ÃÙα Ò]@—ÙûiŒÔ¿Cº™ië Í=$„ Ñ ¤U¨èƒI 0‡%Û ¶¾{®uxpP…"g}>ˆë}׎=Á!`6 0Úøz¶Õ»±{$IW4ò’Å¿Ù/óØ(®;ޝd i¥Ñèi4šÑ[í!c6˜Š!sÙ˜õ±f½¾Û@|àÛ±±9 JRÚ0>Ö’ÆÄÞÝ9ö° ­µÿ@kBBÁøZßæ!¥ME4`{ýú›5±ÒHŽä¨R•Ö¿}zzóö7oÞ›yï÷ýü\G‰«rF*y&WØËªL¯¶åD*Dá®Èˆ\¯F+ùà÷Fqÿ´œ»6”G¯àPGyê”\LäÂçâ›ëð’@†Ö#õÇofÂ]ÄY¬ 4â&Yø|„â(Tòˆ­Ðwå—w[ŸJ çX¬¡ÕË1‚Ž9–£ÕzžµÖ7|ó÷¯`‹Nú|.O Ñ cÌáUýçoÿ†44ºZÒÜLêÎ€ŠæÆ…¢ˆRÏ*Hsþªc¦µ”×ð%Éã¢ì¼/ÿñ5lȯž¿˜™™"¾ÙÀë›åâÏÔ~d@_´Eûɚϯæßߌ?“ý'ô€ÔÏ|ý°ÿ¦9a×R„8¬×Ð\½„aqÀf“ª²FuÞ£ºàVYªšùiäH5âBV#¤†Þ?âƒÑ¿#sü Lûý|ߺ½ô„Ê÷ ™y1i!C÷T>¡áõ˜†„–±È€–B¸Ó‡½òÚIcëõò“91;‡Q½³õ~ad=H[Çx´{b·­'Öv7Þ=nZGRÚŒ®ío\R³x3GkC"â݃&ûØ^¡7l_f5ˆÓFÆæJwM¶‡[sOb%²±Tx²ù®ÂÖëkIjúã6q,ÙÝ—iuÐ8DÍ,Ó¦•$·£ä‰ÿ:~|¯ìαÒÈnç¨ÙÞoqFÙzŒî±P×ã(y<«ý³‚&yCÜ^–ÕêXÐ8óX V+Øéïl4v—1,tõì%ôŠøÿE·Xº·^Lú¶9†M®á]®;‹4òÓ*£uyG~T~ãìþUL|å=áxJ.!âßÕè44¥ŽD fHÇ]E‰° ‚h:=W1q¥w¹5-šåyIJGb–¹’ˆ…D˜ÉW€ÄU²ð)UW)‘óIGé_/fÿ:)d€a¾c‘–e ƒ)æØÑ=‚ˆ¡ÀäsâÏfâb¶i¥ai–Gµ1Û¿xçüLc#©­&MÀ!µ?E ÔŸù¢úWÕ)‰«9¤¡è`Nc@ ½‚ Jà‚(;­Ä4Ø–Ï Ö~ú&'_rÈ\š¶h‹ön³§cQÀÎ;Ë0 ÅQ­¼àô*Sªª¦EÕbW]èT˜¤±MuIVY•Õ­ª‘Tç¡´¯ 㵚¦5>ZV<1ãSxä?=[EˆfÏïýû÷Oœ8¡e‰T‡f´ ‹ Á–¬lsëmK{Oªäwô™$uŒíðK°I7Éc Òh‚8'ö™Ä»±;URTÒhïçtç`Ì»]Úc­Á'Û2Åî ßM¤¿ÿ}`p¯V#¼êø»›?èŸØö뚟ÇŸxFc‰8rÎèé6:z6IÃY­û+(d\·2lƒ!$ a Ç¡ ą̈ß^‹è|´E2vÜŠuÜL’î§‹ÞöÏàÞrO¢8šøÁp"€“«;E3·dI#Á =»A—#p#Ì9N‘&¢„¡h©×$÷¦ Ãû„ó©ùnù ›âðîqô§Ûû —ðæó·ýPGÉC;åa@”=¯GÔñ2Yd]ËøWÅprƒhvâ€Ç‡ð4øú4Å"V·„1„Ägg5^ÍpôÄî‰h{/`ÉBi$^P2F]·i‹˜ˆf–g‰c¾-òÓ ©àe-ƒ4ûEYÌ÷_$rqúÛÎâ.SúD*"®\`EÁ= È é‡ˆPF\Ðsˆ8¡QN„׈'—¸s‰” bM¤,"_;ßš·­)'šˆÙÄsDñwñ¼E„LÒYFYD*SFh;@Ü¥_º‹ˆpx²ŸµWXv¬FZZ–2:ÌX6;³/}|±˜8s_ˆUë´ à*M39•#LÚÒ À´&ŒçnÔå÷~X˽K•«Q€¡h¬úÛåRÒYJ„CÄSNäbâ.Vâ,VV'•çëÊz•÷“¯¬],"ž2eíB®ÿ øI&<ÇÞ«ñ6ðF‚£'Ùq7MìMûAévJ#Qò4’Ý£À-àýI¶;æöۙξ8ÛÀö#Y.hÿl{ºã–åêD²íÆÖê«Ù­Ÿ®K9Ê¢eZj)æµÛJjwË7Ê÷ ŸêÖDhc`Ëb–W蘠oI;ÐÜe¶š}éŽ[ÚÆ ÌWîo‘ÖÚú®<‰î&%ÈÝ1r¿ÉéMv ½q4gKŠ{ØlïO´õ™å!“Û'÷Dí¶ Í§æ1²7Z0º¼&×`œÔx÷ôÌçk7;‡Nx'#&çÐ>—7WºwùO{Ý¥§5‘É^C#=¤¡ËÃOËR¤d]©e˱@ ºW"£-§.gžÿ(×åMvŽíF'vçˆ ¦‘Dyæ·‡­Ñ1ˆE|èêuÿ 4ÅSªpÐÈ\Qø¤„EÄ]¡Ð4pô(°q˜È â €L±ˆ9Š|+XRDlÀ*@ >Qò‰§’H è‡ë3‚ZGQ[ƒtäJ±·äùu?‡ØÁí€ò¬+ð”râªzù,˜RGÙ´øzÙ«—° ó_ì—LéÇ71!!!™L&“73™ÉÎE¸õ¢õN)ʲË",²² ø_ ŠÍ=ëUåø¹@í%W•ÝÙÙ™YÐk.¹ØëÙöšóªÂòcYãZ/ÑþÑ4½ÆÞ‰°oŸÙUclhbâ?½ðäÉæ}ßì<ó¼“÷}¾Ÿ‡ŽI¤u©ãàšqž"/ÎÂÞxèä™F¸sžgÛ*,C½‡-©<À7"o½¾Šï”“'rV]¨+ô;«°Ú€={Ã@R£1•k?–jûRa_px à¡Öi»:‚%Ôiÿ”‘*ñ`ÝsûάÙÈ,ƒKg 1Z#bÐÇ#„N: Ÿ‚ÐsÐz¢ÖÊQ×V× NMäÁ ©¸·w´à }@¡Î6üóvÜq÷wãî.ÜÖ†»{pO7†ug+vö„z»æœ€+¸¥èåAGûi›yE'’T<Ã"8œ—ÐßÛ /zÞßE¨HJ/•¯%[²%{É@Ó#ƒ/ÎÐWÖ¬XEÓ”A+hÎ@ Ñú¸˜-[u§{tÝnÝEY×{UwÞ«»èÕiŽŠßLÓ4‹=ËuwtŠ@ˆ5÷,àë2¸ãóóO^@ÕŸ?ý˜ÄÁÒ ER,ÃX¤ˆÐ'­.=VÒÿÉÀY“¶íjÀ¢Œæy‡íÒ]`’·?Ë3¡Þ7Iy¾é\%˜#ŽîðŽª"ïX‰2mëûlã¸jZYr|8²õÜ`RA=¢–ç´ûÖm#b‘@.„ÔÊQ“ïkG›LPP%Š7¦8miì4U¿K³IÉ ODf둲ÁÓåà‡Ã´‰ó‡·K§vú¦LžI³wÊì äxF,Ò]“:f’€Õ; ^ä »Ç ¥±Rqt¿8âp€¾g Ng]›Þ,,¦æö›­Œ<Åßx®wxQõ—üfÉ_ -] ¤{ü&ï]‹z;ÏØ¡1Ìë/odµ l¨=lÝ·â-ëúT……Ä7“·Åæì1Ö¾—Ýﳫ7-ž1ÈÜ움Pða!¸ÕóÊ4bñLDˆéõDë‘>;g-^Õÿ_hÄ[­é>È. €C`ëC 6à¡CÐ\® ?Ò„]•ÚT­ÇC  òسˇ5htb¥¦õ0U€%ª°»häo®ÚÄ8àV­äb'[‹Aôă)%Ø[‰¯Ujr?ÔøèƒJåÈŽ÷íë?<ª±Šz8ØU—@EÁ1NF¤»&sÁûSì{ïbE:G’±Ÿ·VU ¢ºY§Ý€HÐ÷µˆþVlÂjÅŸ[ËbɨJŸO=ºT…¯á›þé>þ­xLÛš(È}ÕO r€]GH ðA-,–j´m/yÊñ0LÝ‚|òNKyõ&j9G±$Åð<§7Ðx0ú¦C÷ïß®õÏëXdEƒÿËW³ÃrˆÞ€cÉ_ÕVá®.Í[[poO¨«÷8±8Ä SììÀ­Í¸³÷´À4Ôz^[ïì¾y´1#ÎcLb ¥Gˆˆ‰±Ûí>„7FJS$¨¥¯·.Ù’ýPí¥Ë  ¾Çxvvvÿ.;C1d4+0,A&SÌJ~­®¨L×Ù¯ëÿX×ñ‘®ïŠ®ÄþMó 4R̆µ)‘Näß?ù_šñÚ’ŸÇ¡Çóaš áßÝøí®B»žåJk€Xš^É£Xš i&9¿ÂÞûéN)¸MΔ5Íô,òd¾2Y u€ÞÁ 0 ˆ Éí×°DlwªÁrŸ¿Ü}³èÒç9˜û35­[‰–EÇÇ'”5f8jX"ÊÈÆD¡ølé–E5×s â9aµãD8{õÁv÷„­U„63ŽŽc€yÊ7)ƒceâçù?ùŦg6”žÌª=¿»S.÷|aS&,ê×eÒxŽë.ñ.éžÍ5iöLZʼnRwÀ8L“ýVÏÀ‰É5™åÒXÅæ^”.ŠE1`€8±Ý5n‘‚6×H‰4¶¨ú+£@#ÀVy:OœÈPi¾ñTq8Ã;fU' Á¥Q9›t'_¶_Ïø"àVë¶m`8ß4{gÒ]Sk¼S›•{[ÜãÒ( |O@Aûª4’/ò”q“$h:ÑÅí*ý!ÐHD‚EÀ#B S À Ðb¨£Js¥ZSgnß1"|µáq†"¾Úï$–Ë5D¨¹û®­¹x“ck¾Œ¤FSÊ­3•xè(V+ë²h¸ ÑÑj]º†1°(Vi¥éÀŒr¢¾“G“ B?N¦±»^1°«qœ°{[þ¨‹ Ø yV¼)D“‚νXvª-XÇ V`Ia <_mÀrCQRÔ¦Xúlîj,Ök,!ÀÞ|­_v a¥BÛ2‰¸¨vö%ÃS@&õØsH£# ±C†!©­5|Ö”Sú#&ž%y’nvà M$ýö±ú<ø+žûîYíZÿ¯²¦ñÉüœ†%=Î.èY ^Q ™õFÜßÏ·âî¾ÇÎvÜ׋;ZpÐH{¼»w·â¾.ÜßržÅm͸«÷÷~ó~sEÚÆxTF!±,"Ib­Ñèp‡žhÀƒÃX˜C–PdÉ–ìÕ,|‡ç_œ‚ý Gªzè×G„ @ãIm XÁhÑÕŸÕ]¼¤{ûlÌòD=%À½$©×?Yû÷ss¯1ÏçÇ‹Õòž -<~òäi;·~³ÄVËqK´Ýhºõ"BYé6V†{ï<M6íÆ4𵯮Š<p°Jý£Ù¸ÉnìŠÃÌÙó›ÑIšV³þc–““Ëï>¸÷üàœïùœì³™ƒišÿ ™.o¦ÖgéìI¡œæÅï.×|K”;Ë´¡D·ÏÒåC†IWzóC¹Ê¾ÆÒ5dQ{Þwôæj=íÝH#©ÚÝW¥‘Lêý).Ãq3(eòÖÂ’``ì%ÙüfÐH?ÐEð4Œ%èÊJlýØëk±MTìÎ;¡ÓîÍà°A!œ›À³çÛ}¹‡JÓRÊ2§Ã|Ã$”Y‰ç8ÌûE¢Ü^‹$ã¬^aÂ>N˜Éó‚ö pWüãdé‹âŠJg·§‚̃¯Ú1Ë`ԉќÀüt¼?zfC¢,Žá[mÐ^nd›2P‹¶%Í †3Ö'€R ªMÝ–„ÅeæÈ–îí –´–>tì… {{ZePµÑ_GÐ:WMæ»Æme¸7ZCO»ªÀSA7èÂc5½Bwºë뺼ÄYˆ ú™‚,býÉ,„º]5ºŽ…dà7s!ægú¤@òäñhì’¥8:Ä Â|ž‘-_šàØhj†c!€§'ŽR?v›BÓ‰@cã©ò’Å3$3£7ð/Š&b`.×jõù|á) Ý?AµèWŠˆ zS6eSö õ÷@dúA=8F§‰±Ñ±?ìÛOB£€D"qœža 3¦Ç'‰‹W Äô–‘ W\€C+ øðt¯µø~sêAà „ÄhlÒŸbðø@0øÝ•ËÖü|Y2à`ˆMI‘Õ›8½Ž1¼³º(o[qû,×ðJçp‚s(Á9€-8Mõ†Ý¢ô#™„á$Gñ"NÄ8‡–tÞL¾ðÃ{ÎÒ´^›r9¶õRlñ¾ï&‰Ä$0Ѧ5[–Ù¯.sÞÌ«ï˜.EDT:±èPûºó÷)CqŽÁ„FŽu& 1žÞ '.bÓáÌ<‹°$":Ñðt’Á %XÓZ¿]m¿³ôü½µ_ §ü鯥Úåž[3œÝ«´þMöžBe0Yñ¥;†sÛ¾OoþKîéKï»®¿¨›¯rÝ]¡ô¯qxS݉j]tÝÅ]¿èyä.<æi¾@ªYó6A&Ä]•‚“-O롱 š›ƒ õÐrš› þ0o„“­þ†Æ?=Xþûy³yF`ôD£ƒ‘åM³ç~}éRdš÷SÙ ÂÓ_Nai¢‘)›²—˜ß?)–ññg"OËÖÔ0:î€Õuý굜„5fÞÄÎ,qQDψ,JD4g$XÙ¢422‚l0jXyþÀëŠ32k„5'n*ô\/;}m½z%ÎÑ=»ënš£?¡ê'ĈRlRöŽÒˆÖŸåî/ÔnØÿV¤\Å…EíNPû^ª/C´tö¥tö¥i}9ÎL¼ØÑï^ãðeÙòÏöœ¹m¥Ðr;YëŽwÜ]ë¹ïX¡ô¦y†3wRÚ½yÚ=„“<Íb‰~‹Ý‹/ĢݫÒH–cc@2äEÁÄ12'äääC`ì…‰ò¦ÐâG˜Fðˆt t{9¸ªÁU ®Á®:pÖ‚Åù áó6z×Q*¶€»î€e!F^6™ÌBëöÜûÇ׃}ÛµC%KÅiz^–9öLeò¸»nE´DGbì;” žÊ·m1AŠxa¢­’ÒNWÕ7Zfq:VÇ®[LàÜÞ‡í»VÈ:†ÈÓ |i¼|­.U©µfÆÇèYg”£n©¦_¨¹ÕTúÔ³œ»‘jB€QICU×#“í[A«Oxj¡c3tm§[ û­ 4¢ÙÀ³ ÔRÊ0x˹×Û¼õ“üeï’i¨,^”9±Œ$ðhaÌ'õõc@h½? &Áh€J“ÿWM>Ò÷ÓQD@ži]òrs%É(³¢p{S“ž4…–&8z š?ƒ ðY#4ú#ÐzjäàáÏó­Q¬~¡ad£ÈÐ᫼bËãŸÑ|£²911Nµ(â¿„¢ÿ]§lÊþO,\ª‘ŽåƒþK>Œ“н‰ÿÀÓÎVeîüwÏDñz#§HxŽ]@È „c“! >G„×dϧžÈ”ñœs?B‚3I¥ib"à§í(è§ +8 à:ðàÁƒ÷ÔqDäxçylRF‚$¥GÅc’W.þâJŽÒ‹ 4Wí³tö “`LS½ÿe¿N`›H¯#!!Y²4F¿<š‘Ç#'!‡0B! dM.ç2IãÜ$8‡“l á(ˆí² ,WÄ‚8–刱Ç3ãcCÕC]µR¥X®\ÎÆ$ŽJÛVtU E„øï›„¦´•¨èJyYã‘güÆžÿ½ïAG®‡,òH¦«·J¼^-öæ(â¥û‰ÛY®žTÿ‹t¯èBÈìí[ë¼Rí»Ÿêú=™È"ƒ‘¤üÃëXcªµú˜Xbx­VÏD¦~Ü•-^G©@8Ö,¯Ü _M{ïgtß/ÜrT@/KÁRµŠ©D5•X޽쳫úÚ±R} S o–¨o°<|ðº+uXiÀî:|±}ÌßñËùöå¬ :JOR1z†…æt,Ø%I+N|qæÏMý¿ÏñT&XÛ/[>žÃÏ_© á©cSÅalbb¦hÀüÕéòµk©CðLÑd”NóÛv>¸âØgª@Ž™<ôiø³N|üØOír£Œ0ÀP,Ò"ŠB,KqË’ú._›zÒž«U.¬RdºML†§5òoiü£|Ͳd6fã­Å‹ñq˜Z7¶°:µØë ` óìÙ³/&f>kñÿaéMןé²p÷îÝíÛ·GEDBÂ4EAþ äNѰcàù¸’-åÇ^¡ô˜ÅžUJ(KYÝC¥Î ÍÕSâ ZÄ`¦4l–‡Ó<ßäÊC –<åÅ5RêVº¯çÉCKÅ;6ßHö®3Ðh–'……¥í{ xk B#Ò€(2R°}˜æ(q_âøeÍhYmÍá‹?ô . |ïr¸/kPGS¥I‘o‡–[+8%Ðsx!–E ]‘ 啦E™ÆÔ‚„ÈX Kòì‚eŸ²Šýd¶g(Uìî-ô @‰žÑlé^†kø½Ìõ:-2£ ÑÌÜ(“yµ­&¥ë«DÏí|ð•g´ìlOfùfSÇgûük\7’.†Ö‰½…Þ›‹¥že`7ìd‰Ap¤—§„^§‹k8r~ 8p7Å\! §ûB™îkoªØÒ¤~«âHÄ!!¶ØjƒIô¿üåïF#r-áµYÝåØ×¨2Ì 5¨G¤2µkw;°XŠehÇÍêÛ@­*ÅÞÕ”]¶,Zx" =õX" ½ïۨƸl#ömRÛ7ts¯‹uOo@tÌ"zžž žž(ÃJôý§g©¦0ª†äÏÖ$O|¹5ðA&BOÖ•IØ[…}Ù±ZO¤ŽkL]ˆÛ±ç¶/&àa‚ ã«-X¬lÞ[ºŠäô,AÇè8ÐÌ|=úŶü_í(‚ô(VØ™‡}MS ©WAöðÖãî:õÖྠU (ÒŒ½ êøqà§*K;öÁg$å÷»¾¨ÏÉŠe ‰(†eôpûERÅ0ŒÙlöûýÓ«øÕòòâÅdÇÆ6ž5ZuIT.5}w¬wÀG:ñþøØ©ÁÚ“’ÔY‹c µÈ!d8Ž;|øðÓ§Oÿ9 ÍÆlÌÆ»Š0þëã'êpñ»Kù9¹I² +{$¨¯®ÐwN‘iÌŒ'Ó#Ì“G;2Å- R­{,ûÒ$O #ŸZ˜±ÏY,]ÍoZÜ߬󌬖雷#iÎþ*]Tð‹St:Äs5†¥†”CrÉš«62(žÑ/ˆI!J¯EqéÖ% »³úòœ73¥¡ùVŽg0ÃÕo‘BižP¾ŒHXÍh5$ÍQ HŽgYG訴¦Eæm§š¤>0ÒŠ_аCë¢Lé5ç¾Nv…Šå{6Q½”­kTüÈRÁ3&É÷ÞRU&_Gˆ<_0ËÓ“+÷¥;oX½C¶¼®¾Ê7§È÷F#’{[TÈëq aÒßþÉîqOö¶b·wo=d{r® Ë-j§–jØU…EIËk‚‰UoÍ@i5:4ŸÖΧ´ Í#JHFóžtµâÀu|`.bÇîjhÅbóˆ Kñ'ësζål*HÎH‚ÒÑM‚ýÃé:ì®úît5§ÕDŒ I†ÏÖ`OóƒS­ Z‰41DðxC¸Û1!oÍ#Ö e„Æ´HÜÝ€}5ᮆà¡ZwmÊɲ…nGò½S±ØúëŽltfÄþ(# »êUø[U_¾Üvì¬Äò”:Ä5Uß”FãÞÍSž•N^È›¯p|bM1Ñs¢éyMè`²¡XŽb EÓtssó¥K—f¦‰é…ü6 Æ¿ý“À ¼^`€Ÿ¸Xg~ø>xô/;÷Xbt¢´< (ÔAJeee###pêØØØ[Kc6fc6þç¿Ü““ðªHr©­ÿ=Þ¹F¦cbb|z¤šÙ™Nþïì—yl÷Ç+Y²´ÒJ£ÑO£Ÿf4£]ùÆà_`ÀËbŸ»öb_øÄñm°ÁÜê‚JhLIÓ” øØcfÛ¡Hi% —" ØøöÚ¤F*¢ MCÛüúÆ«P«*ÿTTi©ŸžfßÎŽfÞìÌïûý¼ï¾ý+tnÐo¤A€9˜DËÓJ€AEV·6¶æp®å÷›äÍö™$ǬÑ1þ ®š!@“l•n¦ºÆõòxœ4ªwN{Ȇ†åðñûO¤Øodôyr­%¿¾TÞv¾ÔÚŸgH•‡c-#…ÒØºÒŸqXëGùhBןø,Ù2¼½ãò#׆qjDáUYÀÙÇÏS,ÌmXã˜t°«Ø2P$Ý6¿.ÿÄùsuh@8ðŒ'@ÏËû`>¾ápõFœ4­—gMNÙ2<“æÙbïgXQ‹|Ó›ŽE–ÔÒ\H­â‘¯èQq¼×Ø;Ý|‰º`Ú',:©Æ1¢wÜ‹íœ4ÉÓ€%ÒDŠu ` o ÅËÂäL²^OwecÌÖѤÎÑ4ç½×—FjˆŽ \Aúvƒƒ¿—oØ’æ18 § AÔ&-Õ²9ðê‘âç¶FÒ÷±¿IäFk}‡9Ì󫃅Ïd<ø€¡Îsl›Þ¯d©«ïV¹„HåŠË»ˆ«žØ+IO±ÔìɈàELa F,†O¿0J ¦.$ >]Õ‰ 8JI_]v¤ˆ1Ë1ÌÕV#éÙµàÜ›B«Y‘G¶HÍ‰Š ™†-¢hÚŸbcxÕÃö "•s€s]5 h9jŸ»w}\‘F‰´KÏž-¤§I¹e…‘êXút/±7×n"U[1‘ʈ³œHU Î ­ÁN¹áA÷¹9+'Bôg(†f k3sJÒ8,dÕϽó§;wÿ <^%‡,ˆ×óùùÚ~ o\>¡T;ö‹ Uõ[ƒýLÑ"ây¬c‘BA«\.×RM{üø1ù¯Q¹åXŽÿÏ€%üHæŸ=ûKþ7V¥¢‹ ?ýÛï-\ºp1'k+¸–€°Æ<«AˆÙüPpD`JAQ›}û™/ ¥‘x»'Ê:/Oe:Æ€1ò-ƒ&i2UòdÚFÀj³Î™[»|ÌY ݘßÑ+MF:ïÆØ&³íSy]ãfçtt÷`òù»q£9î;9§/sëS5 «ÃZL é`øB´ ÄÙW )lëÌ»ß÷+š‚½˜0Iƒ›Óëì}Ït²}¸ÌÖŸ–Ïip1R/D¨ÀÕ -Ç ¤!ƒÝ+Ïd¸g2mÙ–[iöÛ†£gAñ5 ý\h¶åJVÇ@M÷XÂ1 ñ¢ŽQašKh9™d»UvÑ,Ïs‘%û9ÝwLòh¦{.T<é…ØfÈ/CˆëX†Ã/ÏÀŸ–âôdIƒ©no™ymi ×ÙHÜ€ •ßvÔ¦ ? B”æ€÷XÀAKažfEø0ÇLÔxN6‘OwÑ“Ç@ù3¦ç«r#½ó#‰0"ðI4bhÒÌ0 ¡×YM "À(unò7þèçi„tF<І?ìé*I‚w·ždžs&kJnÅR %ìiÃ^0L-æÁ­Ýé+"£HÝ™žl,ïÂ*œÖƒù^<ÜŽ½{ñHö¶b¾Ë{±8€ùN¸sÊm_®úüµ–ß*ùšÿ)VDÒ„…Fð öÂàœ=ÚµrkȤö. 6½R“‘Ëã´ÉÄõðHÂDšhÆl-t:?üU®8m—¯e /8•›Pââåbi ¬’qLùÑS›‚LÍqeÉW3$º´PÍíÊd£8Ã:›YR—@ê6»÷% ãù î’CБ+Ì”IÓ.qÌS,ÍäñS6“²¬ÅPD°ÊH0¬‘!IÑzÆ´µïg…êBÁÑß2ÆÒDÙ-5ÊÕCšŠ¡ÞŸ¿÷ýg<£`Ôwþ{ôã~Zè™Ø¡À'0y!òù ‹óóAÙí‡Í4²$$å þî‰ÕˆÔŠ hÄ…Nu j½Ig¥ˆº¬¸eek°´s-Xyªù{=åV1”-‘e´º/?{²£ah©³P¢ Û³¢¸·½ÝPXM ²°õñßÿ†ÀÞ^,4AÝ×n wc¹Aì͈¦P,aLß`¹£‚úµø ¬viê±Ô‡•æOº2ßèj˜„5ta¾A»\îÃr·f± XÃ4kÇ¥n,4cµsn¬º1¨¾ P‡•6 6| –úñÌݘƒ«à0OËí“ç:Ò³7ÆÄ1Kèá‹°$‚Ïš,f@iغ%ñ¥ÃoÞX€wt÷öÝ{ö€­ÒöÞ·‘±9A½ý v¥•XÝÂ&B‘§kÏZ ‡îÜ×o1‘mõõº¾Iá¥8–CZ*X^ =˜:þ½Y‹µX‹µø¯G8ìUUWY9 í*ÔqŠ63¬ !(Ü t­IFÅ%ïpï<橾tJ“vi._‹sa®„Ÿ-õà8¡H TˆsÕ\`çð´K˜)•Á->»¸#60þ ipâg*D?ü·ˆŸÎ>5šuòr7¤)|Pš+†ün~Œ-h2 ÆJ2)©¹GNÙO_xX)ßþúyg2@£Z÷Â;)]/­+kŠO+d2ëbË÷ä– yX•¯úåFšYdÉv–y.ÖŠ –M[)!‚Ž?¢æK׊T¿sàU«™.Òj¯-ã&Ó=¾2e”òƒÁ´Ý‡RjŸ¯üůkå+ÞÀa®RMSæJ•Ñ<ÕgçÇóÔ¹jáBŽt%K8ŸËs¥Pœ[ÏÏo8{3M æ %b XžÍšvû+Äùä6åT|ÿ3Q;—”öH)‡Q{óX%A(ڶΤÃR/–ڱ؊ÿÁ~½Æ6uݯ4)’%KWWGWG÷êZ~Èq$c%~€JçâB:ˆ —­J“šû]`§§ò›ŠL”Ì]ÿ¹Ðöy_q‹y‰CjĆ€Æs|‡ºHD"ñÿ ÏÛ?üãäûlÚ°Ñpªå ,¯A˜£õƒÕ%ád6«h«ë¨ýôÕ¢a»/l¾8žË“¢ ˆ*q¼Ü7æ"Ń‘r!Þ° cùBÌ"*ð€ê\ „¡Aý…â óÁ!РcóD Á h$>R쟭"?Ù÷¾6-“U«´” k“5[‹—ÓˆÙýk„ø–6fZª®çzÇàqµbÌ) ï>ÿe…ΕgŸ„_wB4›Êñi;[«C±Êþ0`GƒÔ:^[>pÍ.NšåÉÍη´ ­ãùôš^»7\ó§{g.¯ÉÌÂ=¢Q˜Ó7Zj»>ÅôcGúÑP¾÷F¹çVª­%ïƒÙµ}6¬Ð3RyêréÛçK_h†w|¼\+ÞjM(~óOå a‡<úÊhDt=ƒb-·_ Ô?ú¨AÏÑ Öq˜ýfÀM.¹‰¼—ø\ÄÓH|M_½S“Æê@,C)ãPô?탟’c0bUwO6(zñî!¡šGý=™,¬ZÍP?ˆlRH t<;øÁ$äüÖw ÐD­E*›6é‹ýöù Šd–Ë3Ø¥ ´·‚K‡’3)Т¤!ôq?‘ö+sàþþ]Äç^\@¥^IUtÉIüN:ÈñÝ-ðLû¢vÏímÂØ:q¶:8“^ââ±Æ€Ðjç¡bidÇ™ë˜eõê#û†g¸Tš´úº bò˜ÝØñ®Ý;Z빡ÍۙʨŒ4ÊCÍGj„µ|J2ÃkÕ¯¥RØzX.N8½7‘š_Eó˜[eóDwËaCi;oÈÀØPVßÁgl£y¸.ɘ¡¯huž»ºK/”f ¥©|Ïíÿ«£ ˆRè[•šh\ð´dMašaÿ~â§Dl$ž* µoK‹ÙÄpŽÙ`dH° þwÁ×U’•²ŠEFFýÕ¾|2Ø>{®ÝçÞ^™µZôj®R=hS<#Âd „S!°DÚMÝÖÜPwÑÔï›I°—\ê$Þºåól8-&ÙC½Dî&r'‘»ˆÐGD·² Å9à&eŽØMI#Û”v©wNî¾ú‹²ÃÆt-60t2¬~nlà5&)žÇ Þ˜•uèÀÁé‰IØ/Oçæžï —(ïÿ/6ïòGÈÂóxžÌüüÓM*‰HD"–…8H–‰›äÑ“…s¼K.”H©¡c†Â¥±4ø„§y^—±Ú\·­çTÙ©/öÈÑÂÑÊЬ=0“íÍG¥ÞHµ”HÑr!Vቖ ŽB•·‰‹?GHÜ!€xS.Å©¼ Q³+õEê½×+s1ÿˆ\ÿÇëËi$es.Ç(N27-"`¡RÏHÕàHÙ`¬Ú7eÜß$Þ­÷GÙL3¯…S-²½+xo[]Ä™xfmÆ6Òvñn8­Ë®Hç¬í¨§Xž¬ú•ŒXƒ4:Þ´zk¹ã½À–Ÿ¬ÿ‘E‡ød–× *ç˜ ¾Úyvˆã5¤fuÉÅb¬Â{S—·‹US«0…¦8æ FÑqÉëw¼ýÑîÀXž4½Ý3Q"9äð+£(ñR;‘œJÕö :wmÖ³˜ç}ù­22¸‡÷(…^îþæ“Öd5ÆF•ô^•H‹’‘\n{ _ ­É_»>M¿V…µF Òª“ œFǪƒ]Vž½ 'B ‘½DjT,!î!~€Pï‚ÔM0Þ¨ŒÛ—ÍÓïR'·)Û‰nVDäk[w)wáæÐÉÄß Ïý®¿ñó¾â&óM_ªžã~-Ãè4¥%U¯q´:c}VsçÏ®üe(îögOŸÆ7K¼¯”ü—(ÇÀ Æ’F^\®°Ž‘ˆD$âûãÉ“¹—^Y Ký¹yç(x…}ýõý'Žgff`ŽÃ,Ëc K1¨ÈŒFC³ˆfy½i]v®åÍÓ»~÷YçoUÒHip¢À?c¦­Ò½liÂ,OZ凸ؤ‰BiÔ&Ý.õMÄb¢Ð–@Rã­ ÎnöNoñÏšC³Û„1³|Ç*?XN#ŒV‡ÅòFûÁ³à ›Üá/òÍ€|ªÄq›0‘ësyÿJR4˜bÊöÁŸ‹¤ÈFw?hιk²Ëó3é~ƒAÆÌT†R#~çÙ+ÞñŒºƒ ÎI^m®p ×lâ˜Cˆ¸>¼¤ÆÐͱöÓ—L¯)¨É˜6dm¶zGlRX·½š¥TFLá”õæ®Ö–#ظ>UC!ŠÞXÑ^潑¼Sà™¬’'òo¼2ù/ûåÅqÇñ?"Y:ÉÒi5Zvµ«»³ÛÓpC3`Ûœ}6¶± 6Äøuwælc0¯¤¥PJ‰š’”д…”ľ}ÞbÓD…H¥”(j!€ç×ÙÆ¡)ªªHm¥¢øqçéo|`!«R›ª¡º¯~7šÙùÝÎÎï÷™ž6l'zÑZ‰ÒLtoGþ³,âì˜9½cé9ôÀØû‰tHÙ[‘e…„ŽqJ¡Ý4ñ¦>Õ PñâOk'™mÉcJ¢/_ŠxŸcÕãÞ)i/éÙCÇúˆœà!ª‡ÒˆÑL$è§L,MŠ7»õÓ˜‡0£…Bˆá#ø\G ÿüÈͤÛO.첊¾ã›:ëUl÷ç¯ZŽÍ³)›“X†å“*0ÈÂÂç +‚êvþêÝž¹|N¢S‘Èìã«Í'ýŠüoä ^Í=áy\qÅ××M±Hõ(„FÆ1("pê#s3šÿ¢d8>~ô»Õ.p‚(ŠX`16 Ø,"Sª1Û­)¶5›V{—žz¯*0P gËw‹u`ŒÑy4[&)ÒÇàJ±Ú_¢>Î!12)„*»ú+Ôq—:™­NäjùêÐK¬Ã—ZåëFÉË?yÞ{Â}æ÷ƒйX ¹T˜+Ïfi#%ƘçÌ%[x“ (¢²ó6ÀRJÝI@+^3œeŽÕRíI…ìŒkF½3ŽÚ\ K0¤$>¥î¥#¼^/V†Ë•–ÜJ+$)d« Ü.ÔÇ» WƒW8òò‘,©s–Ù!Ó"Æéÿ~i×í:}`EýÑ$6ÁÂàe9Û‹Þþp]plSçðv%œo ?54¢ùˆä'j-ÑÚ($\ðœ­ËâNYìZ™vĽ¼ò[–4ÑlgÌ,cÅ\’Cï*'Æ>J/rÑw¾Z›‚ Ã3+¸„*Gò+5Ž+ûs¦Ïî$Ò."·žýDñÝœCT/¹ƒ ˜±…ÂÜ®ë‰DqhNm[ÜO Ž]]`(àú{iÓˆñL3yÇ{÷µç¼¹¥«EŽy†CØŠJLAH2™1‹˜%#ðŒ§±î½w/ýí/÷É™‰Ð­_øØRD£‘Xevvê` (BæAå¿·gÿ¥N1¯bþÄ$®¸âúÚj>X}Ù!.F"‡Á¢3+s´2õÛ+—[üM©Ë’Y V â ¢óVd™ƒ“$g3[2¸Ì¢Ì†#5¯iþ®¼òjµ¿HÉVGräáMÒ`©4Y8†"€% @·ÜÆàÆÎ~·b´Ïê‡>S^&?oê;\r¼üÀ?ã+ØXÑΚD–¡MÁ˜‘Çͺ|ðùý¹ÈÜß§L8%|ûd.¶s–ýbŠáýW³?ÿÅ dKÈcžÇW\q}ÝôX¤ŠÆÂWL3€óAxj>5FèÁÂqä>!f¢pP$÷#½W><¸«-=9Ìó€"VÛYdg™$d±YÀfœ±ÁVâ]ó3¹o]Ëׇòµ0@ A B C .Bšk[yZ¨\Ÿ¨Ã%]ý%êP‘>æR'£‘9\ÕHC…Ú$€Gip $8ü‚òqU``³Z'm2îºÜãØÚ˜¾Þ\Ô¸98¹AÚqêòR ^* $%vÓô´DÀˆaÄìJ  ·6”×q#>‰5ñ˜Ïj:¶Åg¿qyYV©È0øÔЀÚNŒZ"A}?énì?QMW³,#¤ ¼$ð ëÓ¤öròËÒ]MBÝE‘@¯%2<å'Á&ô ˆbQZ©QrüðÕK;ð[‰î'²‡òÜ‚& Kw‘}YEViXÜÕ6ÚGk¤s)Í<]'yÖwdY(°<Ï"3°‚…ÿdY (Íq85=½¥½ãÒo>øô¯ŸQ䘙~Äß2ý€–ó{c–Ì=¶ÑE×葦§§ÿÝ}ùÕhÁÉ'vw\qÅ×ÿ‡¢Q “‡$333}õêÕŽö½Ë–Óô9‚=bŽƒ& [°.Ï.)Ø}¢ìU­A¾™©Ndªãkõ;ô‰m,G.PF<6K½›õÐfcÈ¥…²å¾l-”¥ fiÃ%òbi¢HžpÉáBe¬Hu«a0@·ú a¥ËÌŠXSÓ3Öl;˜ˆ“æ͵R¯[l8_å²q’>$,Aàbl¢U`8 ²ðÎòmÊ-—:˜Ùø]™0gJ¯?àT>Ù! ¥d•!Ö$Sx\«îü¸LéOmØgƒ‡ñ’ômû*;oæ*á|}Òõv_<ðÔÐHpžTÀ éj$|zÎwÄ™ðfU†Üè¸u¤ìÏor´Q¢0€[§ ñÑ’š‡h^j@,j 1vSÓZ©ÁttF?žR¼Dn&°ŠŸè^êpÀ Ü¥}šˆC5cÿ½Ÿyz–í)ÉÌ´c™­,—ÄÂWÈÉ>ÅJ0ø2W®xîØ±c×®]›¥/5VÆW\qÅõ´(F#PÆ\$pjŒÌÌÜ?ùò_÷1Q¤wÀû— Édòd2™Ílö% XÑÓ ŠñÀC—eÙ–=8À£Êû« õðŒïìéõ®^{w=5õîP`wÞv¬Z/­&5µ¶GD^öeÔkÓ³McÓ¦í),<ýÍîÕ`î¯6‘d¾yÂ>»Ì< ÃÃï÷™wór·AÍOÕ– M4»žÕ±¤Ò¡#§1Ï¡ {²«»¯}ÔþÉÕ–¡›µÃc.1Xæ›-g­þ/öòñ½…N~Æí V3‚6ß´Uœ´r“vnÚ͇«ùhw¶j(g•‹3å\”}¡8»[ž_M#.f–æŠ|QXÐ9pÓ}GÝÞkuï_ÚÖt<§îàξSnï¬S'Gmï]2m)¦Y#45#Eh(:Ó˜¥ÍÒh}¾»mèó:>´»å$x@§Aͯíãôyez±H[ò¶`»vó·óZ^5Q$Åèóö÷7 v)b•çʹ`Z3á»ðI@÷‡·—_ÿ8á?º$õc?z±ï" èÒººjz0ß9X°‹=Êz”Åz,ÀBæ±Ôš\¤Kñ†ØåÃXŸZšçÀ€Eä,5`<†9ö×Á£¿>æ>íÈ.Î"s4ë àC‘pƒX†aðªÑ±Z¸aàd«¥ìÇ§Þ ƒ°iA ©=üô=^þ?þó¨Q£FšÿQžð'  ¶/-.*ß[\¼77?ðɧe¥ ­cÚHQÐŽ3i´^ÃhÍÒ-Aj(†bMºœÂÜúÕoÖüªž³{ÃB´BŒ;…˜“‹»„ù ~ÞáWrÓÕb¨Æ·Ø¼“¥ž +?m—B¥ÜLl|È)Í:¤¸YŒïæg „Øj±{fò½B.¼K˜±Þ³úç7Ní«ä/rwê}Sež±rÿÌNoà…áI§p [|°µ±/·©·äè;ÛôZƒ–JϯêîÆíCSÙõo¦‘‚Õç6ß牔yn$I!d,þ`Ô52W)ŽçÖ÷ë 9²†¼†Wš¸ß•qSf!báÃ6!°f4âïã}ŠCÄ<Ò…6Eàx+6c_Û”¯ €í«/Õ„ý­x¤û۰ܶ Cj,&ù!w)CìR¸"ÄR"©sû’DéÄ#½x¤K-Øó2æ<ø¨ýÚ+ö“öÍÎ Ô&*]‹C³,£§)=MY6“Ñ¢i’ÔÑdVFfïÁž+—.ÿé˰QSCÙ®+öð²’¥ÿƉ5jÔ¨y6“ªÛ©y²˜//'PÞ ©:Ÿš@µÿòïüW>ë8عuó·ibC®ƒV®g‘‘ cP\Y±iHG›6gç[·4uœ8×:p½Q¸íöNìñóÅxž|¯\œ+ãc¥ÞH1*•Â_Ðì ‹“A.n¸âN޽j.¸šFàH7pðÓÞi×p b(è ¿$O¢ŽÑù!h‰çyCN9Ò"~θ:vúe'àœ¨¢µŸŽ±ÅS[4i¹ß· ã%?û½cp¼ê]¯ãËÎ\±+äȦ†Ï×uÔô• þÆ&ÅËù©GΚòKuEÕ;|X'ÜDYäü@©5£°Ÿ$‡Ð„}ÍØßŽ…V̵)QF«Â©‹ '„oXª]Y„kÀ\£rŠÜ¦,À¸Ø}} B„ne°¤{›ºÊaòÁÅ¡®ðûC½¶cÕ;·g3lº–JcIJ,Mëe é ="A!&ŠÑT£w[ì?=}& ¤´ü”CRs5jÔ¨Q³6ôÀOƒäò㯀*Ð_—C¡À™3?±Z-"X KS4"H–¤ 4¶Z‚4Ñ4Íè JKè7hómÏí?Røú9çÙ«/ñ¿5‹Ó¥RÐâ Ù}36)jfËù¨Õ;[,FÌBÄ,†¬BÈÁ*¹@wºÎ3½šFÀ0EÜ„E˜rH!»„Sª¥h5vùï;‡'ÃÅb4_œw ç×÷24I°r*; z>Ìï=[Õ—NgÒHé|g®ù¢Fq¾›9Åq¸B«w ±ýÞ;/‹·š.Ü´‰Aû \Û¬uøN+w«vèøªBšbÁ5ƒ|l¾àšÑˆÜ§hDîÆr‡ˆÐ¢ÌA)~¤†Ô¡ –Xmá–z±Ø£,(uãáfÌcZ±·s°¯t`_+–Ú°ŽïúÃLJ®¿±ï fGÁ†L–Ò"Ò€PBš5Ð! 4üI´ˆÒ!Än.-xëÄñ×®=|ø0‘ÜÃðЉE󓹸¸°â¦.¥P½r‡«Q£Fšg9PÕS“H Œ'+ù×2YXx¼²æÃãçòâÒ×Ï¡ ˜ãÄcü蟋W?»xìØwwlÏÇZ=­10Z•Í@#baÂ"–$™tÄІ,SÎŽMîöâ®7kÈ7 ܨçÆ+¼Á!¶[š/bÅbü1¾KŒÁ€9ÀÆÅVÓˆ]˜syc•óåžH™/^$„-R´” 9†‚îócMþ°Å´È_XOß 6>o¢Ó³©o1Ä:½ÑˆHRC¬ÓRà‘¹ß髽0m•çŠ|÷]Âý*oÜì —z#5ÂݽÁêÑ»¹r BŽìgê¸9³4WG áR92)â¢)æc`•µ¤±[ш éÂþ.,ƒ+Z€.|I`ŒôaX¥ íÊa«­Ã5à‘NÅàrM~(ua¾‹}9èæÉÚ³M…=Åצ4¥Ñ’(“A&š0bi `d2 DÓ­bZD›4ZÇž’½ñÖÍË?ÿóW‰%oßÂN,cØ”0ñòÓ·PÙ«OíÒÿd¥IÔ¨Q£FÍ3ÉjE{Åæ’2_N@‰ÇKÉÆÀOÚƒÒ1€)K<øãèèhG{çÖœíL€"ŒÑFŠÎd˜LŠ2Q¤«EZš61Ût…U^Ýý½s®.6¿uÀ3öoöË7¶‰óŽãï"YŠN§Ó£;å‹’A7@”KC²(!Î?Û‰íØq ƒçIÖitZt¡1k×ijbßÝsç¤åÍ4ši/†º2Jþø¿^ÀÚjšö‰âØñ³ßÙvÙ;^ ÝW_÷(VWó‘]I?\^ŒŠÓxôÇ£Ûw½ÌqˆEˆ¥Oå!#à õ“SšfÊö˜ªÛ¾^ûæÕÖkp‰·[å°M ­G#[§æ+åY^hÆ¡†`´BšsNÅÛ'æ¬r¸Ç+äT­ºœ`Ÿ˜m•-x¹A‰í¹øÇš3’íŒÔpFêòÿ­-«ÆlÔãy‡: LR©&ö*Q§²ª!ë‡óð&ºWuÈŸÛÄ…bÒ‚Ã0¬KŠtIo Ü:9_¦Q¿04¢©øûˆ2Jä£$0@¦Çˆ2DÄCD9Bp™ ØG¦Žj—I뎳ü~ÿͳž÷{«N¹vuW–~-*¡ <,4¬‡ijœ@3<¢y–d„=¢hú»[·ËNôýã7=·Îz?þ™ûÂaËXÛ+•e;Ì\9K™ébX ñF^@H(¦x¶°R Cp‚(Úl,‹ Á$¸ηNVdœˆÆrYPæ¿¶ÇóݺtéÒ¥KW^ ùvîh‘”Ó: '»²òÕ_þé“™Ó'O¹].#Ë“@–!ÑÍ!žçL4ÅmbhˆÂˆ)AˆGÏÄ3¬ Ñ|iéÖmUÖÝ._Eß[;^¿\yNí”>t‰ñö@´[MºåH‡³NÜnÇ!7K!+ŽXp´Æ®ÃÉZõn^ôˆËÎÉ”}"ÑæOÙK­â²MZnÅ÷NœÒ<î;EÍ.)lìRÈ#.5֌ٕ¨ G`äþH7ž; †•ó¬‰fº½Ýé̺4“S4rqüÐH1à TÑ­w~HTß³ €! hûµº€%þD¨èÓŽÀ€ Ð àG? ôiWb¸å5¢#øGDËÆþ~ùÐü/¼3o¸ÞóÕŸ;P7ÚZѱ·t»ù¥2V(ãà¬UlæY#¼ Ãñ€Š]‚øÄrƒ™¡6²-F˜„2„ìÙ±óUo×ø¹ó37>YJ¥V§áí4ÚÊfó+þÍ–È=ÕsÝ{ºtéÒ¥KÉÇ:ÿa-°ò^YÍ.//ÏÌÌ\¾|¹ÓÓY^ZÎÓ¼ ™Œ4]²Ï#Š‚LäYNc†1ÒL¨ÈÄÈ~ÈJ#Íñ$禗vÕm©q~ß;¼»÷çM§?h—]Üðæ=“³®ÀB‡oS›¤d”²(w.ZÕhët¼QÖâP5íU¯#RÄŠcàf9Ú,Ç[p …MÙ”(P \°OÖ xÓ€;”»Ü¿@#®Ü`p;=«ëGîªöò¹Õ,¹tá¢F#4*åØç€:†Ÿí©! 6”~$²O+´–<{|—¤1iGg(‹{éfeÃ×vKž>OMª]»auRƆ2Û1‡˜vš¦M²ÄZ–)t®ïUçaëØº¤M²vkÝ7…–ŠÿˆÎ™'÷¹o~ϽynŸÓ÷›{F^{à'çs?{»päÚ®.n?2õèѱžÑ×¥í ±¥UÌ×[ì~J8^¨l¤oÿ A„àx«M4Œ-X&V(c¡’ã\\”‡ypS0õ„K†Ã,¡ev+'Í”41Ò,¸+k 2Ã…Å•…PèÈ’–i@[ðf6ÛrË»¾º>÷•Þ¾¡ ½1~nâÂ…éòLb†êønä¹Q€*EÁÌìgª|ÁØ:Ò¥¨vß÷ª!Á`¨h4Fó_&N¤ërâ{~VO!ÇU –#:tÑ¢ü¸ÊQ9n#™^ößšœzù—§F‡û{w=º½°á–Õ·6ÛÍHX¤.cŒs&¤ ”ØÜH$Du„”Ü0„„£•\&Rš Cš\JÂTlg…@ôÃ%\Mb9OÜ–“VŒ¨çMõÜ©kú¬$õR0ˆPgggTk^×)©s*%éÛ7dñŒmI!­,%·,ʰM[JG6¡F†p‚ø%¦:3HÆ$Ä<ËŠd¨m:ì] ›ñ›;7::·n}ø±Þ½Ã#£¿zéåñ7Ïþùƒ÷÷Ã(ðg« G‚9à{x.Å0‚7‰l`ε‘Ø(æ²æ³&âÅr‚ªYyƒþJF£Ñ|<ˆ¡$zæ‡Tú«G³A ñ†|?™Š|dãì25•|ÿ£fâ#Ã8ÕoÚu¯]»vnlüôñ“Ï ?³û©7sùBkËJ˜…Ê (¡ ιÉ î!ãJ+ŒSªª¢± ×9 r ^¤ÜbzƒZIënâ™:j·°:“g¤4òùüÇy) ¾ðFà6—' –Ã(ʆxP’E‡Q‹ª*6òU¹ü7wìØ¿wÏÁþ‘ý}£?}þìø›ccg''Çã+òKÓÇu)¿óJÊ:<÷Ž „žºM7tqÑå·¹±&÷‰« Ê¥ø!šñ0•å'©Z¤î‘xH4W3j̤fýû‹i4F³ HÓóÊ•+SSSgΜ9|øpÿÐþ_ÛöPw¡XÌÚÛÖHnÄ%Ð2Bѱ¥Eá°ªD[š˜åñ¬)$±}tÐrˆŠèà£Åó6Íâ«W¯ŽÇLLLŒ-Îäädr„4ñušk4F³LAš§?Gžëž§Ì!ŒÂ ÀêÝK—ßšœ:?~îÌ+¯ž8vüÐÁ?;0x`_ÿðàPÿû¾õøã[º{ò¹\®+‡vs¡XÈ’ÅBãO?õÝ%l$ª¤´³ô¶«7_ÔB¢Ñh4Ír"Œ™ßOH• Gëû^e$@?OÓNõ/x^9}t]wéý`qµ‡ _m í?˜»X«ˆF£Ñh4ˉ4ÊÃ É B=‘€ùåUü zdÁ>*Y™´3år2èzµÆ²ÐÆÂdoK«HT¥IÕF£Ñh– ÿ™Ô(Ç|?I«ø‰~¤’Œ|‚iÑh4æÿ…TBjú t*nƒ¹3GÔ3d#v“ä§|ßK6ý©´³ JXªTLg‰ýskÑh4fY’jÆlš‡‘çºç¡ƒ‚I`"±d$¬ŒGWa¥ÔÏFKúÂ'”–tÛÑ\Gº~Fó¿È¿.Uç endstream endobj 1 0 obj << /Type /Page /Parent 336 0 R /Resources 11 0 R /Contents 12 0 R /Annots [ 2 0 R 3 0 R 4 0 R 5 0 R 6 0 R 7 0 R 8 0 R 9 0 R 10 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 2 0 obj << /A << /URI (http://www.synthesis.ch/)/S /URI >> /Type /Annot /Subtype /Link /Rect [ 142 683 265 697 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 3 0 obj << /A << /URI (http://sourceforge.net/projects/expat)/S /URI >> /Type /Annot /Subtype /Link /Rect [ 206 631 400 645 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 4 0 obj << /A << /URI (http://sourceforge.net/projects/syncml-ctoolkit/)/S /URI >> /Type /Annot /Subtype /Link /Rect [ 181 584 426 598 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 5 0 obj << /A << /URI (http://www.zlib.net/)/S /URI >> /Type /Annot /Subtype /Link /Rect [ 240 516 342 530 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 6 0 obj << /A << /URI (http://www.sqlite.org/)/S /URI >> /Type /Annot /Subtype /Link /Rect [ 252 469 365 483 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 7 0 obj << /A << /URI (http://www.pcre.org/license.txt)/S /URI >> /Type /Annot /Subtype /Link /Rect [ 170 435 331 449 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 8 0 obj << /A << /URI (http://www.metrowerks.com/)/S /URI >> /Type /Annot /Subtype /Link /Rect [ 354 364 502 378 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 9 0 obj << /A << /URI (http://www.microsoft.com/)/S /URI >> /Type /Annot /Subtype /Link /Rect [ 170 317 305 331 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 10 0 obj << /A << /URI (http://developer.apple.com/tools/xcode/)/S /URI >> /Type /Annot /Subtype /Link /Rect [ 126 271 333 285 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 11 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 417 0 R /TT4 421 0 R /TT6 289 0 R /TT8 290 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 12 0 obj << /Length 4294 /Filter /FlateDecode >> stream H‰”W[wÛÆ~ׯØGàD¹‹»ßlÅõI*µi¥º9µû‘+10h™ùGù}è73‹‹(ɉŽ`/³³3ß|3óæælys)­nîδQ+üáåašU¢Ò< L¶ ÕÍîlyÑejÝñš•êÖõÙòݵV÷ÝÙb¬V+ÈXŸ og¼Ÿ ™woé™xÊøÿ½ùñ,çý¹JWAžàŒ0£=| 2é (9¿+³ZEjA\ÝÕõ±îý…NƒÜÛÚ®Ä+Ôõ:õúݹúÏÿüE„^[®·çêú¡ì³-VÄX\ù8 òŠzã/r¼@$kÄ·æè(Iñ}ó½h£3ÖF4yxx|ºJ‰$êèküÖýWÔÆëÊaB–­·,ÿíÍ™V¥:3‰†5µ S<>B£H£Lµöìîì ;Ã8gèwfÍøm°V%ôÂæš<ÁªF£Rg¹›-Œ“‘¶ÆS»¢>}+:æÞƒ¿ «d ó=ø±×ÊXÙËÓ=,-1^­îȸÆkä»ÅçŒxôÅpÆ×W2qI神z[ßó‚Ú: Þã PÄ4·’w·`) Ôû&¡¥~vú©4í¹ ‚¹ç@>ZÔ¤#ÆWŠk‡ép´cçì§€ó½éÆßT]Ûö³m—~ ¿W¥­{Õ5wýCÑZµ±Ýº-oíF•µ*{EcPÙ[7ûc[Þo{»9‡õÄJIʧ^¿uÀ\†ÀøÁ+ªJñêpéè¸M ¾A³¥vÅQÕM¯nG]J¨1;6¤c9Ìhz%ƒØ/k»ÇE:Ÿü«œ×ú¦ ¢¯” «ö2Ü|.7r}:ëØdXɲQ{w~¼RÈ´aª*×¶vÝPã Ø/î$+ò[ù–£Ú;ívoî^tyѲ/ë{ðÊ©ÉÑHkÝÝ›¬ûúúèù7¿Ìø#2#äÁ;æÜ±íûý«å’(„”‹Á º,KãR°-}Ä`åHQꀺNæÓ!ÞG? U@5“6:ZØ8É WÌë #ÂIF¾y IœYô,¿œ2¼÷hW—àîCg;µ/Z µ¹cHÞ5UÕ<™ü½"m'ºƒÙá×t°œIFÈ%z€Ü¾è#DÛdêç+þ¼¤£ø A1,pAŸ¸ Çårç—Ñ% G¾[)¾3ì÷Ñm]ãg8ózÇ >ü®¦ˆ¤‰;Ê(™×ÈÌ=YYÔòÕ/‰¦Œ·ŸËhäã»î;7o¿øšÓu]ö@* 92„jpdŽxáÔ‘EóÔá(.‡'%ÇÒ‹ÆÞ=‹,©Ÿd†Ð˜qµ#¼‹†ãgÏ¿GJßH à¢íõÀýú£=òìœ~sÜ‚BøœR4L¸å}E©þNi‘ïÌÁ[K°^‹ôC»¶Ã»#¥ ·¤ØV]ö›Á“æ%úŽn³šè{bï$–Ë\C$XÀ§Z„rñì¥êùÙ4•ŸxŸJüÈÀìdSHÿIèèü:Ìv9ð#å M€·C@îÉŠ{ž²Œ-ø-–{™uKñu4Ínº£H®×»j1E;–ÓTŸÊ~9V"ˆ†ÝB"EÁ7C)N^,BB3Vof–<ÚÃM)©Ä˜¡xJ9’«Áþ e÷Zæô0ïV[™ë|ÊïÄ$T^¤T¤@8Ꙃà™xî ·Z=ÞüÙ_D0»ûªš½{s«( ȶ™^¤z•Í‘Ìê;Pàu)ú —}ùÙ'ÈbÄyfÉbdW“AHªîù÷HwÕ.Sºµ BޏeÓ !o"³1¾EòÛ€‡´µOuS×5õ¹úáÍÕ¹ºlúCw®®Š¾;t[YÔ š°Iw»Cív=˜*únêWߺމæª{ȽùR›¾‘èZ8¹Ì0£ Âlª¼2Ñ´m -õªâ\ý v Ò“¾?1ÊKŸZLýäG|$Ÿ¸ãu¸P½†©NhV6ˆ\ùÚÏžÐ+ZÔ|šî¶eµü™}äÃÄySGƒY}ê~ªò–Qâç]OÜ¡!Êgž[ËÌžD9‰„.£Iýî–!uÆ nnOÙ& ¢|fZ“<®B?x?Ú¢^TÍa¯Þ¥ÄHu<'òYϤDÑTÈ;1h¸:Ù<ÑFOÓY-Žô”ÊÖ«‚›ÅÁH±¥^o*ºh,Ýb ýŽ#¼„sOñŸ„cîöþÁˆ¼,ùAY:RªM!#ÅmÑYe©Ã¤e¨BüòôÆÁ!8ÖA’i%9ˆâä'~Ù.!JÃ'5ø ú ºøç[ Tg¢ÛV,"£Z¼lƒlì%ØÏõ+_ƒØ öë–ìîQ½‚[CdRîÑlС'? õF‚ ŠŒFÔW阃î ŽIs,òYdêÏ(FÆ´™pì%{Ù˜6£yíšR襧ÀσԘ|üx<À±À¿jpUÄÈî­°yGǤLg($ª¡"‚ºªŠÕE±»u eÅæÞž„êS„¹™j,WšÁ;”H[xP{ñHC„ºcZ-+N-ªoÔย·Ü]¯}¦cnB *Guýý_Õ¾:Ü/¸N.}š­yá6£¯Ã'5qÜÒñ ?6w˜—™í9‹< ä¬W'¼pÚúͲ™cš‹åÅwß¡ØØûÜN´=ú/9»6ôÊIN¾+þis¶þ,SôÕÔ;[÷4¼à±—ÃÃÀËá,>Ò\ˆTìlßr†oäžnœo­=™úÔPs0‘p´ “5¸Ž€Ïì[##Œ’²g»º1g dÏ]]ÆÍX&]]2vu†Ó’!¸_ÑE:âî„–>à´Þ~BiX¨¿´Öv뢲°8OïD`Q‹Ü@½våb ö¶Ž¶Ç ÕmTóØ?Wê„úqN6ñD€r©÷%k׊Š_P¼EÜG62Û°«¿VËd™Ì:zÑÓ <]r5ks¿çì÷Hü»#¾Áï&EEDî»Ye½˜÷•?!°_Ó¯øçÎ2\¨OüÊ9Î%6̽ýL.FïHXü÷¶ån&(xá~/ã–¿î7àkúØ-{‘Ñ4²¦[~Yk6tÑ`b.LÊ•-z@dûÿÓ^%½[1øÞ_AÌI*”Ô’WaN²åE€-¹Z&c —™ íã,ˆÓù#ý½åGòÉKÒsèEz ÉGò‘ù~4 ¢~Ϻ²7Ñvjáð( ú}Íû¸ ‰¾„WØþ"©‡É£®+ùNš»[ʰÊ}÷½›“É]³ ý\p4àÞHõ¿xÓ|¤ˆÚ-yû-á»/úßÞÝZM?+¡§ŽjÏé /G€ôºz¾çlE}{àVO>. €Ø…”Ë{=£ˆGnõeè)³Öu·ä7JA|òôËd'DJjÜNî@ÞÂnZ<¿ð¿Ço²ÕãVõ!7êG,'š<ý‡€›ݹìz”±I}U¥î÷qóôª„<ѱÊÜàɲ¹ËŒ»öD“S‡}¨¾tz<Ý~¸öåθâ³N]`yªWµM–{Á~Ñâ=kÏF+ŠÐ–CÌÆ²qƒ¦ŽEp²a·:½6îg}&l¥šÉ«× ÷>àšNéèUùU¶ }¯‡ÇÞÎÄ“-m ý¿k%½¤Úªæ7áwÔÎè™PÆ×>Ž“6æÅŽ7yŽá2ýºÜïΘM®ÙƒþÎTC¶{ºc©Ü‚³RÆb§ì”åÚÞךûb<~ÎŒï¼gû!0¢ÎQ` ÛÀ00ƒ*@¢­˜ª#h7tB¿-ÖÅêNn6¾¾Ú@.Bžb 7±:Ú«_8°)™Ëpä´ýM“ìÆþ­I¶•¯rÚΤŽðI+£;þÑæ"L)Ä7C·o3ú Ì‰zÇT¥Ì¶ëŽP;ëËVï«ç}{ëáÛ'Y ÅÍGJÙωyv®y83Vp»ßMs\6ƒ„;÷]eÎì4k}½ R™mÇ |"¥}®½M}TšÏ>âr]J¿Õót±ª–Pª½G&UM–*"[I/B:[.éJGe©ÿ\¹jºÌd4ý¼.ÝT”Î¥*\E®—Fž§Û¹h=Y6©›Ëó€ÆMíH󢦥î_ˆWêŸõÉ·OÎP]±Ê¤ÂÖbvÌf¦Sª ´kzõ¿ˆÛ Rê•è°^2 RV§¸ð^%l~nùYK©Í´ð«6yF+kór²8#Oô‘;6^ˆ]¢4 %Û¨Nfs’§4sû¹UÑŒý›ÐZ²/fÉèAËZ…NdšSµ]NdÀ°„e]æÅ›³¤uS®‹jêd‰ÁgÄj&¯ÚNHŽ´ÌŹl`~‘å³R&]/Ëç"eO"üWöÏëKÊòÃÕ’­}‘쮩Z$vºý¨Ú81 ¹ä¾éUeU«ÔœÆfî‘1«=ÉÅ?`hwä\5°Â -·#‰h†äxÄqZ˜JrÝ8gƒ¼êJ^¡j–R |pü¡„&?`'(qjÜÿÎ=t—XÆjÛÊéä€3vî¸Äl<ˆòµš2ea -/ÀgæÌégI »2£Kœ¦›€ÎbjÙªiRIíáþUçÌ#3ôL]hó.üuÚ:u­N|’f]þjÔõ$»œœ×‰I7=’…§F’Éû#w 9‚5Jž©§Vö¯§jà$ uYLšRœÛa¦‡NÁŽ`‡ªWšR¡Y7n®Ä4/4‰"V|ÀÑã,ŽBg60fsÆ¢5)?Á×°*â2ElU(‘#ï#-‹J@ª1žÀïµ×›&Ò²ÖP}èé$ˆ³}3Zû@•ÊLýfÞ7•n#ø;îÈŠ£Úd™~e³®•°0<ȹ»EcM‹âjjê1MTƒ¦j‹õÔ¹B[6Mû–¦@¡B5Æ(aÐuóõœo¡10Õ»2®¿.#0 ȉši€h‰‡7fãŒW"TÕÌ å¸‚ÀPÄ §u;RœÕ€|°ÂÊM^Ûž´4]¹Ã‘ÔÖ¼¯ Û—k¹g¤Ÿ³½ƒªØLƦ]æ–Ô=5\ ¤ÍC´™õ[ˆ|¿˜¸ôBTszE–\#ÃÚ|Ny[NóŠ"æ‚ó' ?1Ìæ+\!Zèš«-ìk¶ª26'´[”´¥§ââÓ¶9b!ÌìH•í¡Û•?ðlÛ6ŠFrö¬ºDdOÂZÉ@Â]ç» 9/YWR³úJ"á-wj%ÝÔÊT2¢o“Ü?ÆbäÑq ’ÊJ…Ⓦ3}AUÒ쨀Ô#Ð+KÄå¾RQc˜>2¹KýÕº¶QZ¯É‚R=mÅ_ih â\\äô¾_LëŸþÇÕÊ‚ endstream endobj 13 0 obj << /Type /Page /Parent 336 0 R /Resources 57 0 R /Contents 58 0 R /Annots [ 14 0 R 15 0 R 16 0 R 17 0 R 18 0 R 19 0 R 20 0 R 21 0 R 22 0 R 23 0 R 24 0 R 25 0 R 26 0 R 27 0 R 28 0 R 29 0 R 30 0 R 31 0 R 32 0 R 33 0 R 34 0 R 35 0 R 36 0 R 37 0 R 38 0 R 39 0 R 40 0 R 41 0 R 42 0 R 43 0 R 44 0 R 45 0 R 46 0 R 47 0 R 48 0 R 49 0 R 50 0 R 51 0 R 52 0 R 53 0 R 54 0 R 55 0 R 56 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 14 0 obj << /Dest [ 73 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 68 700 526 714 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 15 0 obj << /Dest [ 78 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 682 526 696 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 16 0 obj << /Dest [ 86 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 666 526 680 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 17 0 obj << /Dest [ 92 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 649 526 663 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 18 0 obj << /Dest [ 92 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 632 526 646 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 19 0 obj << /Dest [ 92 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 618 526 632 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 20 0 obj << /Dest [ 96 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 604 526 618 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 21 0 obj << /Dest [ 102 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 591 526 605 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 22 0 obj << /Dest [ 102 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 577 526 591 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 23 0 obj << /Dest [ 105 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 563 526 577 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 24 0 obj << /Dest [ 105 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 549 526 563 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 25 0 obj << /Dest [ 108 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 535 526 549 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 26 0 obj << /Dest [ 111 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 522 526 536 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 27 0 obj << /Dest [ 111 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 508 526 522 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 28 0 obj << /Dest [ 114 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 494 526 508 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 29 0 obj << /Dest [ 114 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 480 526 494 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 30 0 obj << /Dest [ 117 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 466 526 480 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 31 0 obj << /Dest [ 120 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 453 526 467 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 32 0 obj << /Dest [ 123 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 439 526 453 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 33 0 obj << /Dest [ 123 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 422 526 436 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 34 0 obj << /Dest [ 126 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 408 526 422 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 35 0 obj << /Dest [ 126 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 394 526 408 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 36 0 obj << /Dest [ 131 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 380 526 394 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 37 0 obj << /Dest [ 131 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 367 526 381 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 38 0 obj << /Dest [ 134 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 107 353 526 367 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 39 0 obj << /Dest [ 139 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 107 339 526 353 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 40 0 obj << /Dest [ 145 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 325 526 339 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 41 0 obj << /Dest [ 154 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 311 526 325 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 42 0 obj << /Dest [ 154 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 295 526 309 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 43 0 obj << /Dest [ 159 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 281 526 295 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 44 0 obj << /Dest [ 159 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 267 526 281 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 45 0 obj << /Dest [ 162 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 253 526 267 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 46 0 obj << /Dest [ 162 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 239 526 253 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 47 0 obj << /Dest [ 168 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 226 526 240 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 48 0 obj << /Dest [ 171 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 212 526 226 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 49 0 obj << /Dest [ 174 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 198 526 212 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 50 0 obj << /Dest [ 174 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 181 526 195 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 51 0 obj << /Dest [ 177 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 167 526 181 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 52 0 obj << /Dest [ 180 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 154 526 168 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 53 0 obj << /Dest [ 180 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 139 526 153 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 54 0 obj << /Dest [ 183 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 126 526 140 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 55 0 obj << /Dest [ 183 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 109 526 123 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 56 0 obj << /Dest [ 186 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 95 526 109 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 57 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 417 0 R /TT4 421 0 R /TT6 289 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 58 0 obj << /Length 2130 /Filter /FlateDecode >> stream H‰¼WÙnãF}×WrѬ…ÛÓ -wºÝ ÒˆÕI0ƒÁ€¦h›32)ˆ”ç7’ŸÈ?æ!w).ZÚN·ÅØYU,RçÔÝÎ=ONæs#¤˜_M¤>üÃÍ$Ú‹”Š( =ûZÌo''³:YM{|QgåääÕ…×õdê{¾ïÃ7²I;ºŸüÛùºSíÅÎuŽ÷ÐÚýÏüÍ$¡÷ù^Âoèß¡Ÿ ©¨ýPÈßù](ß7bŠ·D\>ˆ‹‡²q§2òç&¯ \§/^}#þõ‡; =í¬‹ìæqq_4¿äkØÀæ¥ ?`œ´\¸ÓðIBD¬‰‘’ž4aóù£‘1¡a$÷÷÷ž‹Tjø"~êÁ•p-› (•SíÞ–ÝÐ÷_Î'Rb¢B §)…Žà&`¢•@D±Xç“«É)CYcÄlŒ¸;§Hf{P½ èÀÄè̪²É˦vçÿز{Ý÷½Ð Ï9Ä·¦íŸôÄyÙ¬«Å&kŠª³ùÐðÆùC#„N`M0…“”ݱë[ÀØØŽÕwÄww9Ž×®ÎuWÐäÞª(ñÔXX-`é;!áÿ éÒ™; àÇ ×͉ñäwlðÒÚ¢Âq‰ñ-^‹%ÁG·Q# 'Äq‹˜:éŽVÚ3„U&ÎN_¬ qqöV,ò:[+véŸ/Ä }ú}píк6ÚZi´5ù¡D˜ñ¤x]Ý»Ò`|6•°ÃµKçÛä" 7Æ(Xà>Mz9œÖ9ÍÄj¹¹¦QQŠ‚o(y$?†Ÿ‰}Çr"¯•AÇd൲å£Ä{À® àÎb³ÌÅkä`Zå5£ Fõ\„ á‘´ÀÁð^Î6žnâI3fÕ= âuʃ?±Ø5ŽG†ûHÊ>òÀ%ÄYJhš´n\¤V¡îÃ8å¸0;\ãäŽcl»¸ñ\K)ð:w§‘sÃÎk}÷WòõŠ×V´–—¿Ñ¢¨sÌÌ´qË«ÒiÉ´ÎrÈ»‰ ðV-™‹2BˆNÀt4Ç'ø?­ÝºSæ€Ø\ÓCÞ™.~£’t!jJšÒ±)è¸1Ò„ÙâhzŽj›£rtÏ1fކ‡Ì‘“,1Óñ0Ä ‚½¿”ÞÇh\¼Kî1š§ ¸áµ§±´É[c±©r~l½3@~É(Y­3\°ÅíP„G˜-\NÈ%ctÉÝŠ³yh¶è¨QgC-üËn>å†×4ÉËœý1]’ßõ>Ù´ŽˆÛØNÇ÷ÃÎÃ'Í=n¦ÌEe´¬êü`TÁHIÐ&"üÓÝŒÞÎÎ>˜¥Ë%ªp­ìÿ"ƒYQ[Ú{°ðÃîc~´ã?ä+‚}†=¥º´.#lú‚¾‚]/ÿ¹Íg WѺã2bÚ’¯;æm"rˆˆCHì~G˜!w‘ˆœÓå&'üì‚—@^j,??B£»÷I[.R¯ê#óÜÆ$"G&­¶íû“Ö]ãzYÞö½6 6ŸY¡óJÆ7ññüŽ$$eZ@åÎ o± ~ó ½Ú×±‚wì»Q4 Z|¹Ü÷ç)Õô|­I¸˜¹h™Š¬P–¹5&e,X¸¦uÑÜä<¸xàçe†;pÞaú€š”‘ ¸(Á|I¯óG.y7¤Ã‰ý˜¸ã;oOÅGºŸÃiiº#Œh,|_ê êpë0LŒåÄǺ(¹ƒŽ–¹*ËU1WˆÑÙ²ÈËF¼+.¹b¥|³»™ kƒdΉB<'grfTò ÔÝk)G]ŠV¢“<_¥> endobj 60 0 obj << /Dest [ 231 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 757 526 771 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 61 0 obj << /Dest [ 231 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 740 526 754 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 62 0 obj << /Dest [ 234 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 727 526 741 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 63 0 obj << /Dest [ 234 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 712 526 726 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 64 0 obj << /Dest [ 240 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 699 526 713 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 65 0 obj << /Dest [ 261 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 685 526 699 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 66 0 obj << /Dest [ 261 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 671 526 685 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 67 0 obj << /Dest [ 274 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 658 526 672 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 68 0 obj << /Dest [ 277 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 643 526 657 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 69 0 obj << /Dest [ 277 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 627 526 641 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 70 0 obj << /Dest [ 282 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 613 526 627 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 71 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 417 0 R /TT4 421 0 R /TT6 289 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 72 0 obj << /Length 998 /Filter /FlateDecode >> stream H‰¤VÛnã6}×WÌ#YDŠHÝ7Þln‹ jõ¥Ýb¡ÈL,Ô+¦´†ûGýÇ>t.RnÛ5ÚZLRŽÎ™33ÌEœ×u ê»ÀXˆñ‡´J¢ÂÆ9UÙ2N þœ/| ­g›|ÛçWK÷>ã(ŽcôÑólüªn&Q©î¹‚TÿVT|¾‚"Žª¿‘”t†?ÁŽl1;ÊÅÏŸ`ã8…† n°<ôƒMUjí|‡S„«<¼¹:ƒ_þÒa%j×µë3Xî»á·C‹ 7?ª¦_é°Â ºdDÌšY™4/p]¿4¦d4‚d¿ßGš¨xôH®Úào?¬‘¢±Êw󆘵köY:ln0š’ÀEb•°sÁ]pÁbØ×bÌq*²"*'-ž4”é´*‚Ÿ¯ßKi¤ 7( àvÓµ@è-‡ƒû™· Ô*’¾åD¢)|øBØñ€˜L«5IÙ yÙãXe89WϬêï„Mú$}Á !XfB J""ð;-êñ‘v§·Ûv3±î‡†ÇA“'.š‚ªýa&eJ•åÌ!<.MKL«G!†¡ãK±d~w‰²×ô ~|à‡­h08^®¨¶HßådÞ·¢í⓱sý—ü^^Ê7D¾ž¾]˜ÿ¤›È”'¯“)MÙvµÙJº5ð‚õ½Pr¯i[ç½[IÚ~>„½ëßKÀ¦ÓÓxÓ ëŠ}|ÔÔ$¨[ü+øs–}u»1*2 KÄÔil¨Xð=l¶\ÉF5ÍB?¤&ûŒ7QþüËK›Ñù³‰l¸ŒbªiÙM‘(k’ªP”Fòo@Yú^ÞÄ “6LÚ¦/;¾t<£òbnãÓÕZ’,Iï@›=]/B‹ .w;̵°ÄC»ÅË…WqZ}|ëÉËãwÍ‹ÂAtFÒâ[Y¿äÚN©¶Õèa!¹ÈŠâHjœðLYUþãõòu£ö%} /pif¬rª¤…õÍë·©œ.åünŸ›Á‚­Dc‹ÓúïqzÜØòjþ—çoë¬G¯ endstream endobj 73 0 obj << /Type /Page /Parent 336 0 R /Resources 75 0 R /Contents 76 0 R /Annots [ 74 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 74 0 obj << /A << /S /GoToR /D [ 0 /XYZ null null null ] /F 77 0 R >> /Type /Annot /Subtype /Link /Rect [ 71 474 209 488 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 75 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 417 0 R /TT4 421 0 R /TT6 289 0 R /TT8 290 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 76 0 obj << /Length 1565 /Filter /FlateDecode >> stream H‰tWÉrã6½ë+º*01aîËql§¦<3©¸bå;5Q„ E*eEù£ücé@R‹cW™X¯»_/¾›ÏnçóB˜¯faþâ')cžGAy™ñ¨b˜og·÷º€J›3誙Ý~|a­g~Àƒ @Õlf/ìIx~Ì ¶–ôͤÞïóO³ÒÜ/!x™áqAwÌFP”‚2+爂 Ÿ>%,Žð|lzÏs^²Ô ‡—iøðñ~û×ó3³NU›x>¨þoÙá‰×>0Ñ,=¿ÄŠ4ˆŒÖF£(äa’å8Ÿ?X4aaÐX$‡Ã{¤ŠF‰$êè…ø·é7¨b1­† {¬Úù?Îg!(˜EYˆÖ !Îñ8‰# Dtr¶šÝgDÎ…uF1Ú)³3Ôäkû˜@²{ó?HFædX=³ nÏÉxŒ?î‰HèÔ {lzk®‚µË}Õ«¶1:¼G“YŸ»ð’ l¾Í78¶{XµT›¶ÕªY +¸äiybùàÔòärôµç'è[åìÔy,ÄüôJ1]),†WïjõÈ3 DCü¦¸ŠÒ0&K3lbÝåÖÐCtéé—Ÿa\D'a„Ùýƒ¬ëqbEû6¨ žF»Ôèż[‰› 0jµèDw]d7¬&RÒ¾ŠKêV,Å¢&%1œ†‹¯Œ/ëú¸=×âhyÄÍWÏFÊF¼I;Oз—î|a¢BªéÁrlµoL2°ê&ªÚ+1^»¥VÄtà<ð ªfBÔÐù…õ£Éú‘µþý9ÉÉ"{ek¨D J)3Ù¿S}/âÅ…6!*|ÂÅpJ(aîž»½ÿÁ+o?ÜÀýw5#å§52¹GDc²éòêE^†Óƒ±­šŸÄeÊ” óù#’ˆé1µ"§2“­Í„t5„1dtôŽ rÞY͸ʡ/l݉í–rE-šõž´)± ƒ ™Š©mÊvD\hW†aô̽¯û#.U‚(•³Ú¤£¶yó¨QB~×¼2É×îÚ®&·=Èz·Q¯+G£ðÀº ‰ endstream endobj 77 0 obj << /Type /Filespec /F (SySync_config_reference.pdf) >> endobj 78 0 obj << /Type /Page /Parent 336 0 R /Resources 81 0 R /Contents 82 0 R /Annots [ 79 0 R 80 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 79 0 obj << /Dest [ 92 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 478 541 486 555 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 80 0 obj << /Dest [ 123 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 469 526 477 540 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 81 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 291 0 R /TT2 417 0 R /TT4 421 0 R /TT6 289 0 R /TT8 290 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 82 0 obj << /Length 2636 /Filter /FlateDecode >> stream H‰ÌWÛ’ÛÆ­¼ò+æ-€"B˜ n~[i—,+vŠt¥*’° –„D€ .kýùŒücrºg¹”V•'KUKÌ­§ûtŸîž×óÉ«ùÜ)æ÷©DŒÿø1…Ž2§"+ÒHå±óvòêÍ>Õž÷Äb_u“W?̤Xî'Ó8Šã2ª‰ÿ:N>¿”áTGy°¬é7 Dþ6ÿqRðùBdqT¤¸Cçt†¯`A*ó‚R+ç?BűSú)ÄÝ£˜=v}8•YT«zßàê{qóÃKñÏÿ†Ó4ÒÁ®©V/ÅìØô¿×;ìH°yâ”Ý"œø€HÖˆ­f‹”Œ¤I3Œç·V™³6V“ãñ…dÊIÔc(ñ·ëW0Qª`ßø»­Z±üïç)1Q©šRè ?­i”‹]=¹Ÿ¼fg(çŒÜ:#pÊ4tv@|`±×¤d ¢pþ‰d¤N†µ#æEáÖœü8Òøç6ˆ„v}~~•šZªäCS‡Y”G6åZ´ ÆÙàIiHäÔ€ä9rùJ´åçz/0nväÒêýO¢î–MW‹ûCWõͦ+Ã(®›þQ”a© lÖåÝ:$ïaÛf'ªÃ¾ß´ÍïõB,ʾ¼+÷µØ®ËiÓ9ßNáS=àà<éBsÆö3 ¶! úz·nf~$f›ûþè»ZÜÖõz³mC)ƒºëÅ»¦áQÊJid’Q8ÅNÁìös‡G3*²‘3Ô 9eÃHœàû&6èëjÕmÖ›%V&X¯7GÆÔ3eu¦2Œb ]ñ!hëè7bam`äCGR‚…°Þ2ù°Çþ¦Ãð¾¬à3°jµ9ô|OWúͽ8t ìîA®¦[òÊ¢ž>q1êdœtÆõpë>$ŠBRbÒq vÁO4e×ûPa—”;^Z€€*ˆÄ[¬*·úg'ªìD³¨ËµX4kذMç®9n¬”Ï”d îêþX×ÅŽ 6±`||¿ð@TÛZ– -NÆ«sšMý'¿Ým>ÕUÿÝÈ»‹zÝÒ*³èç÷7âv&€Œ%Tˆ””ûÓÇ2£ÀTÐ쯹ÇF謤!{~ƒË»†È8ík29a“uÿ—˲éÜ”^–aæ2x ÎC¹kjaBºæ¤+-°¶¦r\C˜¶åî36BB‰9/Áp‘‡ÛßÍp_ÃYž¬påhÓ­9Z-?öÛºjî›J|î6!çì#qªËjKM)«Š“Pm÷{ÀN»iîwe[#–>Wüò‰3WYp%ˆ[äöfEÞZ‰ A|7òŸ8îš¾Gˆ‚ü{°w‡ðF-¡AK¼³ÂYJÝòP’#´=»®!u…Ž7Žl- FX¯­ÖÄÖ)@¤€ F û‹PšãêXãÄbcùSZdG Ð…VëÒ ´Äš†”OwìÀñ ¸â®(W¶8â9.³ï¬VÍbY§¯ý´ ±5%‹ŒÄ ”qA!!Ä8(i¿©6°£æä$J¤üU³XÔÝ€"ÀIõ Emo™‡)m0tp (ýG º ûãPcƒ3/µùRgÀÛwßÙzòWßD YG-Ò¸ž:/üˆæÔV“¡ìu œÊ‘rUN Lú´zEYñ¤x3ƒç@856ÊTpª (%Ç•—åè)àãàJ ôXg[]¿}}ƒ»Q¼UЈ‹ Añ13(ïÂàcÈ1Ѝ³(É ÷ »èC®£@‚Cß×HA+·²µuö ƒú|î+ê93ó‡r×Á;jTÍ/QË£ìÌMÉIíƒz¹W<1£®…~}{³m.ìPQqÚw%ãÀÌv$ ä Ëi8Ær»g÷ø¬àŸd$—>ºòlÝ´õ›Dâý3EKV˜{?¯ù€½IÍgÎÂõ ÂBT›v»®ûnÐ÷lÏzLt½KŒ/]gAýÒÒ˶Wµõ•´J¿ÍÚãšœÚ[ñ9?¹ˆüã"ŽRj2£,£?¹}ʘ<‰b|«,rÑcmðÞÊÅzb D9ا“ì|B*2ß¿ È$îE R;þêsÑNT;ÑäV#Ù:Eñ6Wd,ŸàÒœ½¼ŸÉ²z’ýƒp Hñ'‡‰¯•w®mVqªï¨ìãú~½®»z~©J{)ðëe|´±½Äðk…ü9°¿\ÉŸCò"ÕjDTBqlÐyüåTûLéŽAÆo-Þ7¾x?M’™t†k¯~l'ò”¶°áCZ¡à¥”«‘žpñÈ5EìºBÛ,Š eƒä> endobj 84 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 291 0 R /TT4 421 0 R /TT6 289 0 R /TT8 290 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 85 0 obj << /Length 3725 /Filter /FlateDecode >> stream H‰ÜWËrÛÈ­lù]5‹4Ê$„‰Gv¶äqÙ‘Ç®Pc»b§RM°%¶­YûüùÇ,rîm€€HÉ —µI¹,4~Üǹçž~v1:¹¸˜ _\\Žü@xø‡Ç4 Ý8ð"§‘$^(.Ö£“Ó:YÍsþÍ .ú¬M÷ÁNËV¼ÿó‹‘/Œ‘hú"Œñø‚,JD¥G—£gHƯÁa.’Ć)žÎÜhjãÔ§À#ëä_œ‹Ï”ÈÈ.Æ–‘uAŠöK—b87ëBM#ÎYU^Q¶bY!{37ëµ)ÚW Éê²ý˜Ñ/~%.ËÊF§%­û¸"&³Ä̧Åû ÊÓ“Ó'OîZÙ»ºÁ¬]ÆŽº<± e5 ÅQÙۃ챰QOÅ&ß^MLÁn©,Óu-š²ÛåÈ¿Ôè÷îaïÞ+u£hUï“ï&C—,ózÝÖ®I;¢ü4ÀÕL®œ€ îÌ0Þ‚HÍ+þñ›Ê—Jí“ä‰ö-L¿)»Ô8¾¼Ñ‚&¼‹}MøÅÃnyéLQ¶*ÓŸþ(ëˆQ¹”¼R`_“;¾/­Žå"×®…@Ÿ¡ÀE}†¼>0?+†ÎtRL.`“˜ Züþ> ¶QåâìbÜVp*e×r­¶_ìï’×Úß1&ŃÜ$ÿò‚Qäƒ|úQo}ËnBQÐ}XÎáT DÔwhäŒ ¥)2-n´Ö¾* ñÔãzŸœ£OÝ(øÿ ¹-Ô!Ÿé|ãLÄjeºŽâ¸éÀ“Þ‘}ðû¸SÄE WbT‰'‹Ì‰©2(ôíÛïE¾Å?3ê^•®¾AŸ©ld/9ž3ªÂÉs±Ð¬7¹^k´FO ßåRÀèJÿ±m§7}<²Þ±íÑO²=ímO­í_ÿ¡Õ’¢iÂ2pøt[ëoBq¨+²_de;K·³˜€ÅR¯K±TZ¨Z‹u¹ÜæXÔÏSŸŽVJ%¾6úK³\|ë"…4¢S!@EÛíá©~ÝhHcX‹7J´q­ ë|«OæE¹sH{¼_™Fó™ú ïpçž–jÃIhÍó;˜“‘OžX+Q*­WìŒæiÆ+ž«ha(oÔx`s@6ü_l¥þ¨@®ÌÇ·›vDÉN¤(©äPyäÒFe×d(HûJS Ȇ¥)»FÁ'šH…,ŸnŒ¥!©‘šö4x§í\1½§Z(=^ì¡Y(¥-”ßÀSV’î–iÆìõ¹ÈrÜDÝë¢mîøe[Q¹×埨+%ì«-¸X˜j)2•ëb©*žöÞ“CT}”ËrWŸp~ÌX¼VÙ›ù‡“Ó’:eFç&²T'œìrZ.5góÜÛ/'/šë“¹aïˆY‰ž@ÿù¶{³Ü§lr Œši˜’@¾µyüýe—DúÈiäŠr'æì¦ra¿®™”UÞý&/)˜\BBm6¾¸sC5†°ÃäßC‰àóíxÉ¡3si²{ë/éë/± VÔ)fr£³ÆŽ,‚#Ù:„]†&·Îâ”Û‰%³['L<2‘¤Iz¯4ùa ·©9ɲú£|ïL¦,¹È‚@ñ`› Ý4ô)rüà0j؃ÀxNwŸNˆA¨ï´ÅY0(²¸/²˜ƒÀ˜|ØÝ´[Ì“-ÂÖðI4 N¸×ÚaÛ„U]Ù^Û@w«…µ®ûõv³)«°W ’o ÂÍZ»â×’îY²än´­’šq_ ýõfÓ¡³òrC-Ué°è ˆö€›É+yM( ä_•å{ŒKÄ cþO¹ÄtŠ ¯ü ”²¦*˵݀y èè·FÒ'áÝ•0mWQ½ò:ÍQ8â•þ¦²¿´K­±PµØil‡ç;SoQÓóf»4¥7Ù¦*?‹K˜Øñáq,>œÚ†KÇÓö¦›…IJÌ9DþB5ťƒæà¡XÓõxÍT§é™HÚÜŽøæ½Çî!a´ÖÞwÐtÄ]Ã`€ó0nŒ^±^U¼™Å[•¯éiÞ®ÊÂ2µ¾‚ÑŠAÎo¹?-–Ui–„ÙìÙcý}ÀXyJ$¸(k:žHírÛl+}x½ý¹ªÌï±ãŽŸ(HÇ<3jF™*HM’WÔH¥XPãŸÙnZθߦÜmp!\³" +¢}HÙvA":¶‚àÏàŸÉvòžÎ»æ’Ù‰L>¤’ê{£éï£é·:ž†SÏni€«-¿Häçó ÂÙ5þ,ªöK»§²NÂÿìü\|rº„´ïÏž‰§ÖMlB,nPšÛ+SÔ Ù^•z­*}½ÍC™,˜À„.UÑKRŽP}$ki[ƒªµfÒt¨3<¢Õ÷⃠ó³¿ÓQ‰­É‰ xÎW¤ZŽ·ŸÈ¿ÚÐPºÜÖ¢9NHEÔ¬¸fAþ)1 C³uIYö’ÿéžÑ½¡kMƒêÆ>œà1£ó@NŸ«úeW\š«me±c\êàZ!±H¸Þ™Ä$ú¸Æ6Ê$©ÑZÈÙÆ :qcyÑ•Mí “Z½=׈ouršð%®ªÍÊÞB,„ÉïnÏ>’"e£³UQæåÕm{ÃC—³|Ù LmÕ(ÔŠÑ´;…¬¡ð™Æo 05Ü X]ÜY !a¯‰f©í‡1<(`·Ò”JË×Evƒ>N2eL妹µÛ¦–hR•‹œS”ÍcÃÏï-ç>e|­9aÌÀ™MZFr›»Â¶ªèý õâ+JüßþÒ,ßIuX’û[“7",‹îz“PКí›UomGòï)dö²ëËHó[ØOÝijï$È}§y[Ù¹‘?BÒÛqö wˆ»Ãp¶W¶Ù±â'lÇ›Iø~÷4´ÝÞëÇxJÂZÌMtÆMõÅoT£&vÌÀ”MÏùüq P^O.ÏäÊâ½ëÚÔð®–¦ÓƸ×%@=†Cñ‡2YØJ™³Ì¹¥ CÖÝ-k] B‡·"Hshêþ3@õ¯›šqF«qûü›x ÆW× ¿]Tå¶Á‚#ÌìïRûk™IÖV4˜!êˆBwÅs•­D»%ºŠŠKQi°É ¡« E×RM;c›õ]¡Z DýŸÂqØrú«lÔ§:²¶î…P„,´ÒŽÕYì“Ôb‘—„á”bE¾‡„öA3,`îâÚ‡Šñ`´‡{­V žéCl1‡-·]·ØC4$Z9¸oNºánÔaôúaÙQ7kÏ›k€%5ÂÑI~ô`1Ø{æñQ¡¦ÃB‹U« ¨„оSsÿc½LvÛ†0|ïSðH‰)^äsÛCîMa Z¢"Úª%iïyƒ¼pÿ™¡d-Fzé%ŠdŠCÍòÏ7˜3‚´NK œ´µÍw¢I¾Íg¢ŽQü,Siމ‹ÑÿÙ– ×56„”F¤à•:´L_Å߈â# kK Ö0³!{w¯ò¿rºkU¼æŠ—wË:ŸFúˆ¿&õæì%º/² 2ó@ÙSâjJ‰óq&.«´oÃi€a…ÛØÊ“¢y1.ÌB1lñ/~®0e™º…µÓ|yýaÁHàäN‘ú\ºØ¢f}~¨lnL[êøS„²à¦†A­—LZDMc†8MÇƒÕ °7ÜíPêÈ"Š^,0æäî4²¡ð†X4•ÌÖµ9Y€®Ià¶Ï¯àIÒjAÃ&>®œ†îÂåCˆ)®Â!rF}úì«Ò°EtA“Y$ª$zÛ»M»¸ÞÁ åäÛe0»Äº Qdá$'Ïqã1â®WÂ[Öü£;µ‡Q@öþΧ?SÝÊV®-Üé€i(óqã—Íü?T‘ÔHÏÙzÞ^ž&+Q¤OObÀ¿)—'誡‚¾?@ë¡Óù³MP©;T¦ú#Êõíû§¿ÝÍ ï endstream endobj 86 0 obj << /Type /Page /Parent 336 0 R /Resources 87 0 R /Contents 88 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 87 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 417 0 R /TT4 421 0 R /TT6 289 0 R /TT8 290 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 88 0 obj << /Length 2988 /Filter /FlateDecode >> stream H‰ÄWÛrãÆ}çWÌã`k a.~ó®6®µ•S¤ã*K.DB"Ö@“Ôj•?Ê?æ!§{CH¢´©¼Dª"0ƒ¹ôåôéîwóÉÉ|n…óë‰Ò"Ã?¶2i©³B”U‘j—1¿œ¼ß9±ØñšLìÝä䇙7»É4K³,ËÉðv?9—?×ÉÔ¤NÞ4ô,¤pÉïó'ï¯D™¥U;Œ£=|¤Ëá ÂŸó/¡³ÌŠ)=*qõ fÝ>™ª2­äªÙµx…¸r'¾ÿá­øíßÉ´Hܶ‹Õ[1»o÷ÿl¶X‘cñ:ÁVÖÝ2™VxÁ‘,kÍi•*[”ÏO½4ʱ4^’ûûû4!Uv8‘ŽzH~»ý **-wíðÁ/[¬øüó‰­˜èBÁšJ˜Ñ‚$rbÛL®'ïØ:8Ãyg¸h§Ò@æ`¨ƒ¼í )MšÌ?ÓE8Ãë‘ñG¾…ó³Ôà/,ˆGøÓrÒVž¶»ý¶½ºÛ·}'þÒ®›]8á\¢„YùØ•ðÛm¾jÄr|Üm³lkq!»~{[¯×¢éoõv±j¿4‰Xôݾn»€mÅu¿^÷÷m—À¶¥¼+qÍ2ybF™¨KyÐ¥ô\ÈO›'9<óá;±l6M·l»Qèü/ÍvÇI¶‡þN¬ê/M/É·¢ë÷"Šþš—®[¿rß,ƒ4÷-–\5ʶ[¬ï–Íò"ùnp?ÇÎûYˆÙûOùG˜ñ³(ĽP™ø«8ÿ=ËIé!º*SkÅ-3«D^i<ÅzB‘©4&hG l•‡ô+f„£ƒo”«Ò’œ£ó*-ì>iÎ<þÈùçò}¿l~…nNrk¹Ý¶ýö­øë¯å]’á·^‹ÙþnÙö#7èè†âpjåͶÿÜ,öÑrFŠq[ÿÑÐÄ`,HV‰Ã ©á–ìP€€?Mbj-TòÁ£„ ¡`Ù –T4Œ;¡Å…‹&S™KM!°µ,hë»7l0Köe›ñ›²6AìœïxufýÝvÑ$¸e÷ªôâ’°(È·SUØÔ¹ƒôži ¢Ý ÂÒR{v`P´…ð°Ï…$ å°>—MR¥¹ìð[É›6q '?ð.—þy_]”ƒ)…`[̘ȋÚùƒŒÐ$Äz]Ú½$rÍ%–CÒ‡MCĨ˜5fWOñâÏÌý™»‡f»í=k—¼£ ;æoüJc†•ÝGA‡_IGô_É%O6Dø¤ Ý­éÂ6*Ãa KøÀva®1rÁƒËå•Ö‰2rãßÛ„®ÉØ‚,‡(©Èj7>Óîø†{«”;»‰cáßùM·t–mJ«ÝøÄB“ÄÁfÖ ÙÒ…´[/YÝ\Þ&S„ YF“ï‡ézO&*d®ÄI˜éb³9êÏ/ÃùWëþм©É›þˆìÈcGÐŽ¡'ØH bá2£†Ì†]ΞXñ"0D/xɆg_ÖÆÚ!Ü4;ý‰C%Á’è«]Gщ> ‹6ЊRÆm;Þ·ÙôÛ°€”6ÓÛ‹“GqœgÇgPyÒÝPœx©ðó#¹ôk^‰5RP“·ç0<_xðçþ|η£óÝÀ~üyÅäú@~¶èI•…šyÒ‚,ûÉFú™&¡¬qÛ'ZãúåÝš¿ùÙ+^Q'%'|«Â‡tÅ_Èå‹ ¿n^ýsâÅ5ZCÜ †FýT§ƒQãKŠ` ±‡Ê$•uMJ$ù»æ–ÌTÈ>Q”ý2Ž h Ázäï$JcQC$ýº$¼á‰$Y”ê£¶Š‡»´Ò= ìüÖé´ã˜žv¬çÕ¶]rzCÜœSÈ7VLÈS sÀ†Î3Nø° ƒTpÃT1%E#Œ ˜ ²[ê²QY'2ØÕ¡,‰9Õ#ã ë–#™Sãs·ÏûXZý·i_ë ^‰"a+~¿‘õ©FröŬÿ´!§gÁmNüV\+VZè‚r;å/=òÚ³ûPÞ©2¨\?‹€xÍ,\P«ø›ÆµÄ`‹'œàMP>6ÁPKhSxY‡˜Öf°æ!O‚RÁÛ”V‰¸€(B’å¸J§:× Êo¤p²ã( mÚK?>=;K×íU, ÆÀÒ%Ð1Vœ€' TlãÎùGe Ì #°*¯i„ÇkÀ2ÜyÉoý° BŠÃÿ…r22Ò¹üåãå÷””9ÅÕë6!Ÿzãb79›²‹•…*üÞE½§”jeO\¼Z”F (æÑ`*NÍ3 *›ŠËQ¿ö°ô1’Œ)};HHrǃÈDe}±x2^ZÏ!×ã]ò≆´rç8?jòc°G®bÅ¡Bžú…«ô”QÏ¡ åì²æß4á fÓ•¡Ü ñ‚«“ ÏnŽ¢Ó ˜LèÆ*_œÐ':ãx@§åÎî° Ž‡eî{ôq¹5|4á^Ä·e@Ž&t©Ž>n9ŽÜrf5L¼7n=Žp‹Rùãe„«j”‹Nß]~L¨"éö¾¸k¶× ÝÚ£m•ãVäeGC[T$j| àA% +kU2”YŸØZ¥ m•>J…G&ÄŽCYO¨é5ATÕÓ¨öŠz@yüQßEKP&9_÷zà ¡þ´A*Ƥ$^ɳ³ ã.²UÐ[îËPU‡ÙK¿¦ß„qÛw»tõªqÉD°˜+sëVG­«³¦âR…Ö’ñ^0.å<þ±î8;T±ºÕÁ¸±Ñ«-ÃóŠ‚Ù„DÂ3{_ºså[ʯaèÛ?G¥ M”ñ6¯õ&ÓÙ8>¡ùSÛšŠÓ™.ɨaæÔæµà Ëånfà´¡È|dÛ<4¡iJf¡Â6}ELªÿ‰÷3NoÊhNžŠž œBÀ *ø..|,'ªÕŒºB yÁ{ÇÄ4¡ÖØ=Àó,¨õþr…•32uI~*äOÈeü²n»Ðõ|åR#å~h±š¼ÈÆ7B8Í<èøšîÈã·áŽœï0þ¬úãy+ø?ßqOß”l»áðÅñnЗ¤çò T¹üÒîîêÄr~#‹¥_\öo ƒmÿù‘!¬~jˆŠ„TAŒŠD¤¶—EÌYD¿ÝúÉz‘†·Åæ¥"Ð A ÊöA}!w=7\hÿD-ö«f׈떅prÝì8r­|{Tm:<œXø™|ø+¹i:?n;ŽÖJо{ß*!êhÄf]‡™ë zÏ_¶¡¼HŽ'~í¸Í«Öøȑ%9'+QbžNQœ¨/ÍŸ$Iï˜P¹ø<)j*+ Ò j%®õJÌ€êF6RUyÇ!S vÇ_óØ¢\›Ã…ÔîmÖ €@3~ »,²r(¨´>He†S>|­oE€ÅfY ¼Üw &‰> endobj 90 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT4 421 0 R /TT8 290 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 91 0 obj << /Length 1470 /Filter /FlateDecode >> stream H‰”WÛnÛF}çW Зe`ÑÜåòÖ·Ø.‚¸HVB[Ô Š¢-:4¥˜tõ¹Яè?ö¡gvI‘¦ÝF±í’ÚÙ9s;3:Y8Ç‹…&I‹+G*òñE§+?¢8<•ø-nãÓ&¡¼1g|jòÚ9~5—tÝ83ßó}wäN¿{p.Ä»Ì^"® ^#A©ûaqî¤F>¥Ø÷Ò:‚„eŒ s‘Šû‹"{Ïߤ|_ÓŒ—”–;šïêÖÉØKźhJlW4ôòÕýþ;‹¼@Ü•ùúˆæeûGq‡!W.h‘Õ+w–bƒ+ "cµ±HIOê(ÆóâÌ¢‘‰Ac‘<<> endobj 93 0 obj << /Dest [ 120 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 87 478 103 492 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 94 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 417 0 R /TT4 421 0 R /TT6 289 0 R /TT8 290 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 95 0 obj << /Length 2569 /Filter /FlateDecode >> stream H‰¤WÛŽÛÈ}×W4à—fV¢IJ"9y Æ3›µ½ö® ž`Ñ¢ZR¯)’Ë&GVžóÉWäóSÝÍ‹4²½@l`(’Í®êS§NU½ZM^®V ²ÕvF,À\iêi³ä&ö£4˜³ÕaòòN§,ÓfMÀtVL^þð²ž~Кl2ë~'ùáÍæþ‚ï$]#ÎÂÀûûêíäÆlpÃ’À¿‰adžºöû(¡­èWl7ú‹‚`Áft¹aë{87 ÿ†ï¥Vø9÷®ÙíSö·ÿz³ØŸóZeû){8ªæ²ÆŠ%ç ,¸(6Þì?°¥ñÈÛ) ýp'¸_Ý[oÂÔxc=9¾7÷c®±#muòBü-š=ÎF\«î…]–íÍþ߯&!SlÅ!à Ù<Á…áf1ò(eµœl'¯L4"ÔF#íqJæðÙ5a6 Ï¾·ú•öˆÝöyÉÜ;·àÏñÏ- -–C{Ú‡€ÎØý+/Lè­7< ¯¼ÀO¹b÷?²ÔY­*/ñ—¼QeaŽ{Rý!‚¤¶··Z£+o {à:ç’„*X³¯½ HÉÖy™}Òf +·À8åx-™sÕ þàž7^„oŽÂ} çqa÷òIoó²:È¢a?ª†=rœåÑcÝZ³ew”ÔeŽŒihñÞ›-ý—D¯˜oÚ\^àú'#¨£êˆvàS²èâãìÍæ ?LØ „œ÷&½Qþ µ&ÀíG½pdç[Î@|{´3Ks>>ÙØÈ½h„nÊZž›gáè8ÏSŸía*WÅÎg+d(Z»èy1bóIkÉŠ²>ˆ<òV·n%UŠ­U·]áQÇÆd]ö¬ÜÈGÏÔ-t>·`†£èÞí Ÿu¨ºé8o‡Ž‘« â£áyÙoúÀXAìó=t ˜nê6£Þ"¢ÔpiQŠÍ½I ‡“½)Ü"ù·Ô_Æ£†àfÔ´hˆåçy2§w7úB€s4ªôÉEh[Šóv"ì?± ‡F‰g¹ú T°‘‹Ï‚Žô×6¨Zz½prõ«ÕÈs]R¥æÚ4³0öѧ“êYïõg ÑKÖâº+ËÍ5ùpíÓhd@\F}t8äzèrýçLŠâ•òµ’½dEyD šò¿îIÇ­Ò˜šÙ#¶µ£®å4cQÜo¹ÁÐx¤û¨\T{))DeÈ0l>Jý! ¤Ø¨w¾=Šk´üJy~ãYúQ£Ñ×`W0³òýÙ|ä];ÔS+k‘}BBqŽº"¾nw¬l›ªm˜]}²Ïí5"SvÜcz*~~Ö ·ç‰Ù&.é¼³•ä“Ĝ֫Ò2`Ù ™Ôá½9F7ÓÆ³K;Œ?ôt¤G¶Ó‚m޲LQTÅ–Z£‘V-!6¦«¤ey¹3m”ß94þY…à·_c`_1¬1JBC!ÛM^éñ£¥œMµƒp›Kωõ®ÀD½úܸPZ‹kÓ£Ôâ|¹z6FÈùyžÐ++Ü>»Ðka·6ƒÁ‚gÏ Vö=ÑDŠÍÉ‚sµ‡Cºf(»Æ.ñ¦kÀ&°ÌÐ:¯Çí²ïào¦‘ˆIµZ^‰FêÇã1-b¡¯OuAú•éу’9òÙ¤’Ò’Š„ÀŽ;ª±$“µáÊF>)êLJQC¦§l/kê)!êÐÜ´…—UÊ ôHŸ5B[K`¸©“vô#7jù[‹6Ln.Åf6œd|*º‡]bXÖÞŒ\lxLä÷¼ÄAöÎÊïÎ|C¬7³"A#Ͳç%£×ÝgÓdOôþ\GyÒº©¬fdÇêÂÅÐI”´_l¨±ŒŠÒG~tó`ÓÈârr¤þl÷E¡-þÕPª¸Þ‘¶ïúG;JÚñÑîËd7.žŒ÷#¯X‹³©Ò¥âÔºëÆYÕw—×zÉçT4(ÁõÉ (!5-&sS¾Ý7IJëÿ4;JöÈMPaHo•IÛôÂ¥¢B®j%idÄMJ£Y{–™#Ü‚íØ„|Ú ˆñK®³Z½ÔNˆ¨]¤õ ”=hâÛËÃnýZš1—¼)h]¶7U[û¿sJŒ0%†nJÄlý?³aÚ§Žä÷Õ׆¥è hk±tÉwßœóÂÝ{dý²ýÅrP¤ÙE»œu”ÖÎú/w {#ïGÓ˜|&W†Æff6éS`6TÀQœ1·é_±ÓÄoO}ýWw¢k…MAÒ—&ì®» .-_*Z¿Ç“ÚB}aþ Öz¯tUjùóúWÆ^qð?> endobj 97 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 417 0 R /TT4 421 0 R /TT6 289 0 R /TT8 290 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 98 0 obj << /Length 2716 /Filter /FlateDecode >> stream H‰ŒWÛŽãÆ}Ÿ¯h @ÐF\ñN.‚žÛ±³ö.0‚ĔؒhS¤BR#Ožç <_‘ÌCNU5EŽF‹õîbÅ&»»n§ªNÝ,®Þ,¡òÔb}åùjŽ¿ø ÓÔ§óX%Yìúé³kŠCeTeL媷†^;É1ÊÕw|ÿ{QÃÔ›²¶_mpfJ@atVÏÙj½jêÚ¬úNõÊÕÇ z}S[©×êÉYü2 °ç»A&áeÇ“è~ÇG~~ך¼w°Nz×Ô½ù­?¡D¼Ÿ¹Þx yR(“‹žÕÑI(U¥–ð:œ¾Ê«ÊÉ` )ÔºlÉC±î]öFQÊrE!AØœ²Þ\³Ø0fìŸež4Ög¶Iѹ^° Þ 9®¾fûnMezà ¾£ÌLõ§Œ Ï5­•%LC®‰™+\™ê\pUU0” Ï;Çbg]Öy¥Ø|ÊU |"°ÆÞKøÅeGrߪ5Ók{ƒshå’9Ê&0™Ät%¶ŠY‰Ît]ÙÔ”ÿT1P SßM¾Úª"ïó®oZÈ)veÍ ‚ƒçF:wáħ©Ý >ý“£ÂÑQ¡èðD!Èô€.^bdX¦-žû/C¤“)¡¯l†äиú‚3%Ñæ¨ØPþþU92ÛžF°&G':·7áì¦j–ˆMOé |&íò]So~ßu®’\RƒûŸæÏ(D(siLá pa‡$D£„hpœøìà ãkHzfQ×w\iri0û|YVe_"Ï"ªo–SÏ({0]•5¼cÌ®ÕqK8 ½ÔIt©Õ¡mMÝWJ^Pìp÷¾i{S\Šø…€®³-¥úí+©“¨—¡4¹ìò±S=Ùe“>òæJ6 ¦¼à¨§ºåv±“ºñÌ‚@(#r'UÕDiðZªÜµÃs¦å¦‰Æ—00B{n¡]Ö¨|Ùzõ:\Ö?ïÉ­‰½8gM=ýWt–ñ¤:°±.7( ðÅÅLiìn ㉯D’Ú:~Ý;>¢Nu(_Bô2/’>éþ ËšO‹Ç#}‚¯ä"Æ7Edú¿T²1g?úQí­ˆ•)JûrsÑqñè¸ø%´¹ÙPÞz§J€º8vMÂÈàO9¶ÊëºéÉÄ ˜¢À.ÉÍXlÌÆèÁ-û¶ÙÀí;Ó^+”à3÷"p=Û–—5Y¥»}Þ—œA6Urªr§Ò)¢ªM¶ÎœëHS#Síîêòò —š–t¶ÚJ‚¬åE'ç¿^ʪPõa·ÄEsµ"ºX8Òñ`zæÝ5ãi® ÌO") ¬]k€Zˆ ÈpjÉpàFÑe¨¿o¾* 4#]FúŒ¼J'Ý÷U½, T•r]"˜êù[¾ÛWæ­z²)c+i~è·oëæYÝ;t?±Ü ˜FUè¢ÃLóÈħ5»æí­Ùuûþ½ZjîQ–~õx­> aµgßÃMYƒ;!Y—sgæyY‰gCË ÝY :>EAóJ„dª^ˆåí—¹Ÿ¼ž°Íoù1—zöCã‡ÒÒÔzõQ¾¬Yº%¶jg¨…•YSÔ¿÷ä#$N¹›],ᯧøŒD˜âZ•kÕ!ùW[d\³^»ê+dÄ»?Át°Ÿ‰³­•uPeÐzSížkà)¸ìI¿;HáÑFÅY}ßðl‘jA& Î1ês"}2Ìsž› nï[A;…ù'=câ Þ ) =âH#< •Î,Íè®ï5è¸mª§`_•™ñÚ/þ¢È÷=FpŽšvŽzú&Â4'jAßÊÞì^NÞ“T3íL*ò‰„†Ák¡6Õ`«éeV ö½6ˆ…ø#Vü3y·?ÀJÐFÄ$‰…<»ÚJ-ÌQ4hÃÜr4÷…±»3ÁÈP¾½Y”;ñü8M-–=ÞŠ¨8Ë^ZùôµéooG¡¦ÃÏ£àSpéQÚ@ô ~4ÈÎA\gQ’Fç(Ùá'üz^1§ïN~MáטýŠ¢3H®žø5HÚq¯…Çïó¶íÖÏÆóŽm…™qüÂÌA u¬—‘­ôöµ Œ_tŠ_ôZÐ è8 J‰nN-ñÁÊ  $ݼÿ@Œ¯oTǕ™]¶ïBù&>Šû‘¤|nF²A /¤ùð‰åÔÍŽÏ=IsZòú­%¶œIYæ±ÛùKáÐb8¦Æ#% •g#óÌ$½Á““×ühA0#¸A¿êÖn’M›uxª§áPÍÙ‚’+(T]7DÞf µâIg¥3u“øUå¼¶ý~(â®ïË}Ææ”;'&àøò,¾¤…sWkÛóL& TÔÅžåä¹»ý;v¬~Í7˜Õµ’CÛæhOÓ:6·Ä6&ŒÂÅmG¤±‘¬£š€Ÿ•”pâÜ éë QðÙ¾å3¯ýIÿaAEÄÓ_9øy{æN gÙ„½ô˜5øÌ)©) ^óïCÙ;› ðÁh£ºá8FB¤ø‘W磛$ ®[4.­0„`r_HÏûß­°¥Yåy†J581¨”Ї[ô¹)i—¢Î¥ŠCK Y¦,R+¶מ'1SoÄH|E?–UE4BÞ00¶ ¹ÓnøG†»²p_•îËÄfàÆ·e·o:óaùË3®ýµcž_"–+!þ˜Õv • ‰÷²Û¼ƒZàõ¡­P‹@7μp²ˆÙÆ0ZAÇ÷2AðÜèëåHÚ‰iÀÎð4yóÞ9áÓ·e tçÄxæJžÜCœ)9`7Mh@Ü&n<”‘8Ž“³¤ö‡¤ðgZdÆnlãm©“ú[^5+/"nº9çe¾¨èú¡‡Æ!åâîÃê^gT‹´Æ$Õ!Àœw _§I5Ç?g†¸ØUßåŽ2‚Š8!Œˆ–yKÓäÌŽU/úÆX¶Ä¼‡reh0è„Â#&ÆHQãõ–F@¨z¢Ùü r¦à™¾Ø™0ÑLØ#¤òæ D|ú¶¨»×–|I^&> endobj 100 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT4 421 0 R /TT6 289 0 R /TT8 290 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 101 0 obj << /Length 2223 /Filter /FlateDecode >> stream H‰¤W[oÛÆ~ׯX /ËÂdx¿ä;RÔn«(Ф0ÖÔJb+‘‚HJÕyö/¨ÅùçáÌey³åÆI`^VËÙ¹|óÍ̇ùìÍ| OÌ—3Ï.ü‡[˜¦Ž›º±H²ØñS7óíìÍeм¦=®¨óröæÓ­'VõÌu\÷ä3»{<ξÊ/ʲ'”+w_‚dë÷ù³Œd"q,†C‚Ô|´åïýEáSÌ‚þ#|× …·LÜŸÄí©l,ÛKœL®u]Àcà$²ï?]ˆßþkÙ±È}‘¯/Äí±hþ­÷°#‚Í ¥*–Áˆ$Èl2É÷/ŒxŸ_±6^JÚ°&Çãѱ'–5HDQ'˃kÙ¬ÁFÏ—uÑýÀÛò5Éÿ8Ÿy¢3?öÀž¸ x |¥b¯gËÙŠFú4Ÿ’ØuRŒ!첕ü*o~ž[växò£e‡p{KÇ!†0dl*b–±bnE ÷Ìò¥·º¦w¾è>OVåÝ  ñõTŽ·q)–•e§ðËÞ aÛâšnÕB‹-]ZÞÛX>Æà^‹¢›¢Ô‚µàK‘WåÒ˜+a6úoþL¨¶”Ma~`¥rÕUIæÚd¥ ‘ ú(L±‘µFˆø²i Df"˺+“µcàFøQï¦hpSÄ®ÛMSì6Z Jà(#ù‘¯¤TžâW‘«RìÛ Ý©½ÚlôæB´fo¹êlÎõ®Õ<âíf½×j?«†vÜZ=áae~ý“Ðå ¼Öë ûÎødtÆGÔ#›Qd#©12‰ÔK âbž¨%ªù‰bItjMŠkZÿ- ä-Kæ[ÜH”fy]Tåæ$šŠ´ÿå\Ve£ÿjÞ‰ƒâM…å‚Ô=xó›Çuay¸³ µKFpI.¹9U5z.Ùô1{JGUØmÚ• 1X¶eŽ–‰kþÇ(ûS' Fé1Æ dB _Ü]îñX4Âò| ý_MO!®’e#þ@)(àQà±Ð$¿ÜhÔýHÏ» ÿð„€;}¦Z\iðOZdç¨Dˆ¦ÈÇo–ƒÛAˆ¤3AÌ”Ïs§Ô A7„Á ã[”ú ÷"·/Èñ!% €2ç0 µ²R0N×Õ²ÍSàSƒˆÇ Q4ô­ªëv«k@jÎׂë™ZƒØ…¿ TÞ!ð†]ŒPI•˜œHMHËë¹Æ%H9 Ù’`Š £íø‡ ™…2Ò¦R·Õ‚oÍê3ù*?S¦—”{É0ʃdÈ|vsÔºŒv“GüÂWN”>ù¶®ÚÍ“Bªbz˜t>“6[ä ¤2NYµ°‰Ey¯"ññz 3†Ý rÂâ,Õ ÁàX)d»© ›Ó"É/|kХȌùZ•+ý–jOB HBžåácÎOP¸! ¬ŠƒfĈ²‚‚Ppc—Õ^›³[p[•¸&vVÏ9z`U&‘d¢ÞWmƒjœ7îÊ®£´E'êýBaíäΰðçô·ãØËÀÿD ôÍ:¯ÖÉõ³^.ò 'ªë‚ßQiËN¨µ¢Èš 9ßþD|yeVüj¾Ía5ŠcüÁç¶nЧ ¶=°|÷4µó“nn°Á€’¥úhZ<5”Ï!©»¬Dݪƒîd…AÀjygÕzƒSYWúPäú3A/ŒD <ãõ!˜ö³hB¢0]\PCÉV_}˜óâݘ…>Øà†Þöù÷&é½Î}ÞÈfôx,YÛ/„ìx9ºÔãyG…2¡å]\C Ki‚«ásÿ2t‚:Á:"“Ò@ëÎÝO5¨‘4K%´×QâË_£—ààõðôÆðôžQOŸáiÎðЪ0a¥®Ž¤cÎÅðr*ó5²I:¦Á•dÀ³Ž1ã–y)²ÒA§tŠJ_™Çz‡Z{Tbzûù3·)÷ð.!0‘"WFØB¿à5¿' ?žDÆä¬×E&î yp‡ó ôÁ»¶ìÆZ:6I\ãÞôLʽ– ã ÍàKl˜I¦Í“ô@ Ø £aÌ£!ɸï5aƒ0?‡ýÏáS>žô·7P!Ê¿ìöû:À‹MvâëÆ¦©x| ÍÕ´ÂU©j×¼-«Gœ}®©ÌÜá\Ý" Tª”˜ŠMÑû4öAø§Tñ¬3ñ¿YI›aú“®¨ó+w8iਸ਼À18A¥[ ñƒÚw T€ˆ ðq½Nåb[”ï f²”IïCž9u˜‰çÜbu–Ÿ{XÐ¿×øyÁ.3ŽeiÞ0¯ •}‹ŸRq8èh N@~•Ž÷ Rs YKÊŒ´¹$_©Q& rQÝ17ž z¦ ûHÇiŸ#O#ŸtªŒCm>ä_ §â´mÖïà¤Âˆ3{¹ÆB¿òšÀ^òš& ô’äG¾Ì„¬0ûùIØ# ;lû;ê$‰> óUôj6I293ÎÝ@Ë9¶“ç3ÝxÊ?ÒíÆ"Ò¥ /T¹—ß]€“rÕÒgv)NÁÚéuÓ!mG^~gæ¹Öò$Í=…9£:–be†¾{:ÆÙ D`7È H!96Ê=šOöMüÿøæ üŠˆ-õ¡ æò¾ƒ0,B¾Ã@x"°ÝÒû‰7•y?Bý‹:ù…¾oWb×îw•ad¾a˜–ýã|ö¿s3™æ endstream endobj 102 0 obj << /Type /Page /Parent 338 0 R /Resources 103 0 R /Contents 104 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 103 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 292 0 R /TT2 417 0 R /TT4 421 0 R /TT6 289 0 R /TT8 290 0 R /TT10 293 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 104 0 obj << /Length 2629 /Filter /FlateDecode >> stream H‰œWÛŽãÆ}×W4òÔ F6ïÄvgfí öbd„ñ®± HjÄDC*$µZyœ?ÃÿÌCNU7/ÒÈ^'^cÔ$»«ëzêÔËÅìr±ð…‹ÕL¹ÂÁ?üøql;±Š( m7v<±x˜]^·±ÈZÞãˆ6«f—ßÞ)qßÎÛqhO6›÷Ëýìƒü>µæžíËû‚~])”gý¸øÓ,a‰ˆ; q‰›Cú¼‘(Z…Zп…ë8¾˜ÓO"–qw¨:k®";‘ë¢-±ôìH¶âÅ·â‡ÿXóÐödSfë q·/» vؼ±p/Ó*·æ ɱÙl’«l凞7Z³6Z“ý~o[žÊIÔÁRø[ukب\Ù–ý½-[³üÛÅL‰RÌÜPÁJx~¤ùŒl,›Ùy.~s®Âg~»mN畾!’]1ŠÙëí%Þ ²M­5*´b8¯7¢µzuѹðúcx}m<Ù™%Ö{N”­ÈËÏe^䈂Ô"ˆžhwK¬³®D@‹4[÷Äùk÷À…¢‡‹ØÀ…cGˆã©=ܰ!céN%)¡ ¬®ºâKמPb#ÁœÁÚl©QNª·E÷­ê†³Î dÜKa:A8:3Åì6w"Æ+'™®/DpÏÜàÙ^ò 7ëŽ/˜{>Àô«YÏtHÒ5Òÿ/‹,ݵÝ}è3ƒ2Íâ.µíè§ìÞ-EiÌ}Û£šØnv÷¨ˆ‡:ßmŠVÀKu§­H܃HÛ³¹•Œ*™ð½¿y‰š å5 Ž%C–Á’Ç€"Ó·Ùâ®Öêîk¾4‘âò@º':B »>fuBèýJ0–+-1Eíô1ª´hB 1€æléžæœJ¤)º]SƒÑIݧÂLkˆS ]•ªÆ“7ÎP¾¥%_ÓO(ß}2‹jU_ŠÓ‚ï“_©¡ò‰U§–'ß²#>]÷¨Mù³M—å¦ìJ„$ (é®âÊ'P@îG‹:PšëºØ×M.Å‹›·¯ß=ч?¤×u5gæ zþqHhÕ˜k08ð.}(þˆü´Àí¯ n"IÍ1’È Èë,EhOŒIŽ m”ÊÁ% å\DÕ­€á…Ï¡Vˆš°{/Ð48Ù‹£®¸{®6D0f+=圧{ʉmß9‘qJáÎ^®PÃLÞ§'uà\ øû ÈJÉê'n*Dë¸ëØQÕÕÁ ßW©]ฤéHížw êkn…x$È}"‚$u/ÓXüxBÄ ù§á„„_ƒJ%h3Ô+Ðß`¯¢üRxûéZ7„Aš¦ÇáØ´ tî(o›šzmÛ·FêU¹éœ¸¡¶”ŽD²8Uh£ÎtÓC#ÂP²·o„.öÓ–ª]3 9´¢1z_ïÇŽ'=Ì=ò@hã}m;2ÎoýŒþ‡Œ%~sê‰9‹jI+­†~«z]ŒïvÛmÝtÆ‚ÞèÓq!îO½b¿™C¿;¨S‹ˆOÌ}"èÄIÎyv0É…3-ïñXÛ'Žáã‘2O‚ʼ¥dcÎÄ4-"Ý¢(ŸÒaGŒœ‰!i©? „„Ħëé$`Ž{D4ji­¨ƒ‹cnw!–»N€—!¹²¢ƒ«züÏK“k“F= SB Ed–·J´ì¤8ß5}£ËægI÷1ùÀ 1# Ž;柙{ØU¼;æ¶Öú/f¹DÓë/›2Ew¹Û/éd]QÜ.fŒJxÚl,|F*Š€è'ßçÀâùÎ1°<Ç|âЈâÌXoò€ ŠÜw¥sé•ê)]$ßd– pçÆg®sý#2 ^Ýmvuå"ÆŽ«’…JTì$?Œåáû!ùbcì£!ÐÔ?ø´y£7²®F çK0lÕý×ÀÝq €¹³¬ðBïÑ*šàa#è^üÙhFô[ÎÏÒæzzìiŠ*+ÄCZh¹IÑ 2ŒíºÞÁšü  ¹ÌÅà ·æ —Mk%\Ö~´.xýs„øœnvháV­Æû"?;›<Ïn÷;‚}Ä¿ ·ÅëîD‡/†ˆªîh¢Yëää­ $er1LOåýºûs@?EÍPŠõ¤ÂˆRNLÇÕ<Ji*]#:±Üì(ŽbúN”w‘‡ôï4ü•ú›hÒ=2ËÔ$ƒþKþp0bÍØAæöÍîëã™itkMtkEÕðÕz¼¢n£'9NFÚ=ªp®‘œi§gŠÜ‹œîñå^qeGó×jeÞÒí®Œé†.î¬Ó×,¬k²::o´°ñDSê‰@o1ÝóR˜Ð}Òk5A>e­yÌ¥Fx.øuA1=ÎJ¹/> endobj 106 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 417 0 R /TT4 421 0 R /TT8 290 0 R /TT10 293 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 107 0 obj << /Length 2496 /Filter /FlateDecode >> stream H‰œWÛnÛH}×W4òÔ ,šÍ;Å@®ƒÌ:Ù…-`/ñ  È–ÅY^‘Šã}ö¬ç'öçaêÒ)YÉf7"²Ù—SU§NU¿ZLÎ _(±XM”+øƒ?Žm'vB%¡íÆŽ'Õäüu‹¬¥9Žh³zrþÓµ·íıçd“iÿx7ù$ÿ’ZSÏöå­Æ_W å[¿,~ž$´A""ÇNB8ċ͢Š×»n…O!oôá:Ž/¦ø“ˆå½¸¾¯;kª";‘kÝðèÙ‘lÅËŸÎÄ?~·¦¡íÉm‘­ÏÄõ]ÑýKoaF“K ðeZçÖ4Ø’‘Ùd’«l凼/Þ0Frwwg[žÊvÄ­î-ÿ×ÝlT®l‹þOËÖ´ÿÛÅD‰BLÜP;•ð"øðâ¹Åb«'«É+Іk¢áÛ`³#|ÛóâHðkï²(ìØgŸ ñp©ômßv­Å¯¸—r7sÌ>ʉmß9ÚH ³ê{¸š©1ZÉawÙG‹µinÅàðÊrdQƒuôƒÏäoÖ4VH kê»vLîôl%Á‹1 g]ÑÔä¹SìÜ;Á  ;ƒËCšW„!ÍE«io‘Z![–Í]+ºF¬¥FQ¥ÑáçH.KÝÚâîÒ¢´€­s‘ë6ÛÚ$Kk±´ Ü1÷¤X5»:EmH52¹H$‚” èF÷ÐZä¾Î>çËtSØëG[À~òeYŠ­”…nÚuE­y²hV’°f„Œa„I‹¢Ú”ºÒuqG]mº{ɰ6`Vu;~­é‘5¹÷öà£|Äàß¼‚c}ùù]³]y®kñBÎD±"?²×»H3át0 °­-¥$jƒD§ç˜ÐiLììÃ¥Ðõ-8Q)FKQt¼‡y/Wö)«pRéXX¨°;Ðd @Ž pŽ ýP§â.µPIî‘f ÐÙÛ|!Nðtm>6´™ í“5èíN—Ȉ'¯¶{ÇL`ëÚn°7 ËÇ?/¬)îþ2~fGìýLX”úTËÆY'…€8ˆ¿uŒ>ãdY³Í‹úÜÙmïŦ)ê®Õ®í0 [æåbµm*šÿ`çzõ(VE©m‚)¹ÇL^D^‘Ÿ!@—–o\Bš¿ÄØ¿I; ƒ•j,«æ‰vW¨Ü”K¸5ÅŸ@¢fÀàG3úµû`>lÞwf¬êOc=‘o J”5Qݤø¡gWÏÑ,-‘šM‰Ü Z‹ù¦Ü3?çèºðÓ¥¼Í…ŒE¡ó/ÄQ~š„C–Ý÷Ça†€ë³¦^·'9}"óÞw¢Ö:¯ÿM{%;¥¸xØ`ö°)ô  »8«›GÐÁÈ ‹M¾+õç×)­M—EYtý>‹UpÌb9ìÉ™xBáÀÿ…?Éë¦Ò oä¬ðXÚÛ^ndV`âÅê [í/VBÊ‹I8hÎ&Ývâ¶ ‰œ®êr¹+Ên ‚ÃÕoW©ܧl:3e‰‰BíÒ¹SÏ;ÔO5ä /®NBH›€©L/Ìk†„Ц‚ù&* É8Ï+Ê:<ZÄ:@e@òš'žÍ/{9ú‘þÀÐéû‹½§°µð~´µïñ¿µã•ìòÁ½©Ë&CcËü7,ìôØa‹Iì Ø|4°–ÿ÷vÚ¾¡§ÂHùCÐü¡š(tózH}}15˜_0­@#xRÇcœž×]?Ls@)Ó+Øò²’š]çK@†\L,ׯ²‰+ h…r´Ì>VA®2C~‚š(ô¹lá('2X"¸né '¦´b¯OÓ¡èŽk®ò…\±{,ä¡rBnô[~OƒÀÃÒù«Ÿ/o¬Ó5ÃÝååâQ>%ÅŸ„ré(5Gác…ôpåK”©ÖÂVôOæ Tm7Qø„ !¸ÇEÛ<í!DlmÈÖ†l-Ê=²‘)¶1øŽûËŠlŒØ.»Óg#iœè²eYF9ï‘eø,ó㟞óǧ¶‘Aƒ"»½{-ô‡@"¼2â ýÚ,ѸÄòùóoØñc¼ãË[&ô7ùvPÖ‡¯¿¸G¨$v âߪ‹¨ž}mñQ°‰k¤G©°FryìöeÑ dº1uÒÑ”ôD¶'ëv<à4 Îs4þ 1wÌØO7KÂF3G©nÛÇ•{¤pá@ÄiÐeQVTçâá l‹QÇh`&æ -Ÿ‡#› èá®P£“¸Øì+Îàʳ­Ò§æ[µ+;@Pë³S7 wˆ_ŸAwkèÌI>ÅœõŽ; ŒeÙÚOÁ£Š;ØãøãâîÜ+àfÒ«BoÛCnùè盚Dx¾\’5V^˜â{Aul¬¤IŸÄÜ,Hôtֺ̟ èÛ’Q™QûíÆv]p†.D%CIž[8 }OÅ»S8ì&\G-˜ëZ·Vo`-¦v6?wT©K‡^稖BëŽ\9èH/Ó·ºÖÛ´ëïzª’0ØÈAŸ,æ¯aã@^]¾»€käÍÍöæï“ÎW'†ÿ+ª›'Ôæ2Š›µXÁplÀÇÞH± ÀX±à¦säû˜wSÌÀ5ÄšînÜŠI†Ë« ºÐ¸¤fÙ6cå~hŽ÷O¾³|b‰Äu÷û¯üC[Coj|qÍiðE) µî @i:[.ç‰|}ui¡œ¿£È\d4˜Íòü€‡ß±P(ù ûíé)'âµ ±C¯G„I!° ‰†l‰e-M)¿sA´Ì'Ö‚ÄLáU·57µþÑ^e^¥Q§•æÉghèz³Ó¯;G]†×zW-Í!̦´†KT®¿‚XDòì¤ß4$\åÒ]×àÁ‡… z±Ž8ñÈÿt Ø5Å@×”ú(@“ñûnk•D®wÛžž;:AãyXèÆ«·_ÓŠubvtæ±À’¹Ÿä<}O´ë qÁY¬â³ÓÆ}ê+¾3û™n &*D%"RÄDò¤š]Wêùë+˜àÊ'ßÝÙG}'þŽÜ†Á’Úì[tI±Ñb*‡û@út æë²¦^ÑSq+ÌC‰ùÝmiÖý‘¡׿9I0ÆÊ¢¥Ê×½xð|™aZBX)½¡ÖÔyº}vô€WÑÀ+Óª øI@°æ=ÃzvºÜi(Ù"Ù_> endobj 109 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 291 0 R /TT2 417 0 R /TT4 421 0 R /TT6 289 0 R /TT8 290 0 R /TT10 293 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 110 0 obj << /Length 2725 /Filter /FlateDecode >> stream H‰¬WÛnÛHžú+ú±X´H‘å͈ã$ð8É bívãAIm‹ŠTÈVdåÙ_0ÞŸØ܇=UÕÔÍÊ`1ØɾT×åÔ©ê³áÑÉp©@ o‚Puñ‡G”¦~7í&ª?Hü0íöÔpvtòªIÕ¸á5]Ռˣ“·WºkŽº~·KkÆGöuyôIÿœyžé;CÏP« ö~þx4`Õïúƒ‡ôR·i&ûÃ>‰¢·Dý[…Ýn¤:ô¨ÑJ]­Jëu‚¾?ÐSÓäxíù}ݨ—oÕ?ÿãu¿§ë|<=VWËÜ~35VÄX\x8 ÒY9ñ:¼@$kÄf³IaàQÒÇ÷ð\´ RÖF4Y.—¾×óÝ@"‰Zy~K;…A¨›¼eã)Ë=< T®ŽÂ$€;Õëã¡ðÑ i”ªÚÝ ·bÐz§õ±Lܳq=k­]N¯¤ßÐKü@O¡T_õpu~ycͽŒUÃSIçÌæ…Q¹ )s?7c›—^@ÛîT^NÌ}&“%‹ÊfÆ#gÿ@»ýhk/Âç“6Çj${Í8[È>£àu‹e¡Î=öˆ)&³l®Êlæ!}‹0§Ä2/ ‹¤†äS¸ÁUHFê²²jdTc«ÚLŽUSñQU=1u^Þ©ê–¿ÇUy›ß©Û¼0¿7x¸Ó'Æšz–—¦áUlªÊš&¿+g¦´¾7ü2"•Œ]zk,„É>ü4ô:1tíu"¬Çñš‘Jld‡mÛSº±/ûÆÕlžÙ|¨ÙJeEM êél²ärkKv ùõhJõ¿ßx]¼?óí½åÊâc2"†îSø„Cí{‚é–5%c€Uîeë…ñ[h…~·*Á&‚6bœ;å¤6j’ÙL Óð¸g%Ao¶(l^HÂ`ݱ’銷aQ]çÙANÛE]º­Ï_ç‘þø»eˆ¼ ŸCž‘q67…dÑnùæáúºF‚á4sk ÙäHomÈS"xþŽSï ‚?Ð/$ÓødJ6:yОLr²›u§–¾:©˜À¢Z"Ž6Ž1ÐlÏ2„·¯ÇŸe´ð˜jåcê"„ÍCˆRÅ×vêµ;È ›v]¯á;gÀõõãµç«ójAü²¨,’ԯƶ.(•êll)„‰6R¨ê†”°r´ø$kÔÒ…¯ÞT5‘G–jŒÐ[c‰qEä@5!}5u“W¥ª«…e ʬz!(üñ|ŽP/§¨\@¯šgµmé LŽïñgà >IõA@?ñ‡NMmT†ÿvY!ë¬)Iƒ†’"©TÒìþ”iïM¸ÅzT„ωêßé¿8jLÜ"?J„Ý´Ú%ÍÀG­^óžP¦>{÷ÓYsê® 2êod¼Q>vINåeV¯T‘Õw^Šlå~C½R£¢¢Â‚¼Aôôg!tÎV"D fVe±R™j™Ùiˆ"oUx¡f±²F–Õ¦›}UÓt{GÒv(Ò¢hñ§Qd&íì„©ŸÆ»h=@7ù5'¿å$Í=&h¢q¢gHšL”d 8'dž“Ù%tA ^ÊDnbì³Sõq“f´òŒ)EU£“_ÚõÆMT#ÿä–+ÁŒ¢|OÚŽâ¯g|œÐÎOHá¾–‘ ˆôù÷«o ÿÀÝÒ<õü~Å]Å7´LXòbÝ'K¢ðJqí¶|ù…׸íPXI™Áÿ º$á“~Y³ƒèèUsªžÖúp ÊOk!!u![mê JS¦ä…«m_“[%vÒ—,¹^R¡Fà²Ô1a‡O\Gj'(mAüÄR~=d‹sÏVܰTàXêá£É&¨AC¦Ý[ ^O[3{‰ÐèKoVL¢„;,††©œ‡äðjF(ÅéÑÂnþíÙT_¸º¡ŠgóùÏH;í¼´FV¨çÛÒp {g—f|–$Á !÷ž„WÙŸñ´Œ9‘òK©ÝÓ®a{žíJ>G“scý‚ë-7HðÕ~2âò±$ÐdŸ×pVàP¸?”¶PvŸÏºÉ^÷{lP/nY\wV%1PÌ$ ­ß¿S¦Dó‰¦'¿UÃ×ïo^^Ý\¾FøbýZ”èSj¹©„I MÕï«ÉÂ5pt7JN‰ÂÜ¼ÊæT¢cÐqÙ܈í ATO¦ÇPH®GÍMZ®– ¿+M Ö¯}æs·9`7#›Ü°úlV­äš.¸ 툶…¤juù²@¥AF“‡æÅþ8HO FtX÷™¹ãüÌÚl<5R¾(JÁýâ~ ¨Ú¢ñ¤‚oý{ÆL"ä¿0'Wâbš ñ°‡’rŒo$]-zýœÚ.} ­ÛE‰{#Ú‰öÚäˆ8ˆ„G#¿×C˜å³½Ïöú0¦ÛÞg©7À½Åœ„ »+¢ëvÝÔº{Û×ôýGçÀžîíSúë*î´Kêq1ŸÀ7¡Î¬áç¿pËÓèùP¥b*>È„~Ÿ¸ñ…+H¹ O¹W‚PŒ7öǸ3&ÎþøßA¨z€BÐåQ9¬²Ë݇åBË ××Ö!˜#ÿpeÛa^C4ó‹ ä$¬åpSNv¶½.'XJèsu$Ö[Û|î*Bæá>A™Ò9Ø?¥”ŽlÔµ†ˆ²0J6¹ƒ«“Íp¢ÏБ¨kï\`k7\+éh¹-Geuñ¤æSÃxƒÓÎ^™Ÿ%[Ýœ”A”PxÌŠŸ(ª]$ý^4;¼s7!zA‹¢žKòŽº( . r±JøŠ#edø ]}žXpüµ·ïÀΦqnßvå­Ü •\:ç% tãÑ —nýEGI{f´{æÆ–µ)kKÞ û¦¸€#òo0Ž[T¼ÇòÕ.bôÅùAƒèÛ8憎Ú”^ÖÈþ‹öÖ$ñ€Ò÷;÷?iÍw!¨ÚÐyЧËÝ3¡ºïx;ˆ×ÊÅ­¤÷ÕWCʱR1T:è²h½1j7ž³Ô/yZ÷¼h_fËņ6‚ c jðøŠsUòÑôÅ`ã‹A»@–þ>¡þÀ {¸—ègÏžzaã„ÎŽ¼H;5Î8ó©†Äš„%iDô¸',ü3(ÊkឌµÞíW\âí\v“Á.A ‰B Ò®þ`̤ü[KÌåÜÌÐj!=¦:õ ¥ûfB•ž/2hªµå.Bú3ÐzmNËê‘z÷\»o^1[fs×€ƒ\) é1áÓËÀ3§hÿ E¹A…zÙ!eݤÃÞ((-S°Õ2íäwÊÎ5¦¡.]qÕC¥©§ñK`°¾<¸tûïp*‚·þÍ1Zÿ¦ˆÖ?~›A½4{&ë(øØ2–D ë˜B;@#»&°N€)¨ í; Ìf kþƒî€œ iŒèƒ»¦P"6„3ÁY¥ù3”Üí ˜k›KrC endstream endobj 111 0 obj << /Type /Page /Parent 338 0 R /Resources 112 0 R /Contents 113 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 112 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 417 0 R /TT4 421 0 R /TT8 290 0 R /TT10 293 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 113 0 obj << /Length 2294 /Filter /FlateDecode >> stream H‰¤WÛnãÈ}×W°/MCâð&Št.€Çž ¼;ò,ÖJÉ80(±%qW"²eEyöÄûùÇ<¤.Mݬ™El@$ûR]—SuªßŽ:oF£|M;~þã#J×K¼iì‰ÂhÙysÝ$0ixͤì¼yïìéx®çÑšI§×¾n:ŸÔ÷™Ó ÝHÍ4=~ìü}ôm'e) <7ñ0±›–²?(z‹EÐ ð¼zôHa¼…ûmiœž?pS5×M¯¡;P \½ïÂßþëôb7Tu1™wá~S˜éWôqñÂÁ"••¹ÓKñE²Fl6›ø®Åü݈6~ÂÚˆ&›ÍÆuB7V J$Q[ÇÇßÒÌÑF?PMÑNȲɜå¿u|( Ä>ºÓ‡p€À0Ò(Zw¦·£ƒ´ÞÄž›Øì]Ïš v.§WÒoäÄxöÜ ”Þ¦X,`¬aÝð¨ÎÅX x"¸^ –z;UQ6Fg¹3úé¡‹šøÄo#Dot0FÅéEh1°+øíÞ¡Ùñr"Ïá°ó%#Q3G¨0ˆë«ÒNvÁñ=ULáY¦oeÞÑl¢†W4œª{Ùõøø+=Ruiêµô"û¡hÐÇ2dÖu{ â®`#ŸV #Q£@z ЊDöî].†«|½Ð×Ù* VÚºqúH@ Af`¡Ñ}•ɨû›ïaãz¨•,\ËSç.Œømޏ ••£ág½mEÖ&ÕrµÐÆñ”ªIç¾Zl¡ZeÿX£¼cZÕ 7Ù ŸÔj±ž%,Yï“ãŠÚ‰Pêl2„®Ïƒ9žWýOK«¦qèD‚–¬·*d9TVÀFž…1ºDš9éïµù‹“`%Èkýæžœ…#øÑ*=É‹ÞÊ;·#NwÕ%`˜Ž³ÉÏ0]—STeãZ¸Z`ãîÀ ú;¼ñAß}9½>†™1ã«Ë6+vXÒƒ¬@l?«'}kôò…`´ªõ £³‹çâEQÎ`^è:«'óm€œLãê—(“5¦ªuãÂmÉ^˜¬ëZ—žtÝ î»(õøà]¤ØÖþÞì¾h¥oB9Tb5OÁÒZV¶Ú@ÈpRŠÉÏ@%ͼ°K¦:CäÛrÊ>]k4C.³>•òÑÊÅXOœØ¨¯ Ò'µ Dÿ ýÔmÑGj²†‡Ï¡¤…¯ßýÀJü ÙüH¡¢©[ü ÔС*ÿ=<(äÐ{p/%£PsJçnÉÀ¦X„¡ŒÜ0L Ÿm]ƒ`Gmå/¼ì[4ùޱϊð½Ä¼ ì®/î#Q1±îìí‡ò‚å7AS—T!¬È˜O…!†é“~qz ±`0È/ ó_Hiˆz)ŽÞ ¦_ÓJìùnYóéüxq6PDšDy*TöÆN.þÙiJKåL[±AÚŠ½-M=V¤jêŠÌbµº5vjyêDÑ2Ùi™´âþ¼Ê3KÌzÈo}–³<«&Q+!j%ÜhdC»×?ÞÛúè3!±k‰ý‚6bz‡¥ã7a̪r±E6TWzI ?ü^ÊÚ#Õ}t(9¥ÊÏ"ˆ.#…U–!òG!}”|WC‰´m-,UTå´˜¹gñø:_ï´Î˳ Ï!ž5Ûz.š†¬©¿Óô²¬^¨}±-Žì¸'Ûv‡òYúãÎò~ÿ”€#¢ßP]Â+öíG–}ÏW€ûj©%Ë5ßèЀ͟5Yh3rƒ0dƒÅéÉI•¶mà>S‘ÃÍiCàÅ¡¾÷Wãu±0=ÌΓÆ;`ï ëÚ0WŒ1ÌfªH=Køá¯4—ľ§]Vn›4¬oDïdpØÒqS%+aêPRqzÛÆŒÜe{ʉíGíjùøMƉ{g)4þZ =”ñÛ(ôp§¸|ï¿Ö̦3¬è ÷:È[ ‚÷h,™â Íé bîi{]V ¾WöÑkH¦¡úu" £›|™H²¨)pX]Bi牖·dTÂ`—gË}°»~[Gsºáô%­ûhp.×™¡ýÜÊä5èDÍíh9£ŒæîfïäFTqŸ¾9_Äwœàí8áGÙ];W¾^EêB/UÕì¦-ðçIÆìZWB ‘ZI5\Õ{‘7H1Z”Î}õàœWð ÞͪjôÇñO@}“xêââhÿ. ÷5§Ý-¹ƒ"‚Ê ¤)Uö[mÄ’9`éQBÒÄÑÐk€àJ ¿[ÿÃn¾­á–Žb-lÓµ¨©¤B# ¼Æò'á¥Uµ¥2éßĵmã|tMû÷ÿJÖ¬Ì —\£ª©%äé EÃæ\HüƒÒhñ~!N»«ŽÝD5/åšqÍC2ý–wÌm·ÝüV¸þ¦‹&á­FT0z|¿ÅBa·dBÍO¯'{¯¿ºæÛ‡¤°ÇT›f˜6i»OÆÇ¬J6“>oRa±ïÐOH nÍ [3ÉÎ9”ÔZ?ØÔ‘üDQXX²ô'cêNÕbE¶LdË7|pˆÀ-?þŽn±"'×ãõ VkùÄdA€kúážçU×ùI]5E>ªÌ°ÄÉw&|²•¯.O›9Iµ\ƒ½fŽ…­¨—‡™“¶3MLv-ËáyÄBÚÝY>ä—l{Íýt_áf}WÉûæù¼6„ýåZާŽfÀ õà¸_yi½µWˆ¢œ" ¤(¹^ò=;7NÍs‚ †÷Z2î~u×Rü>[l;ÏèÔË•±®|7êüo$=kø endstream endobj 114 0 obj << /Type /Page /Parent 338 0 R /Resources 115 0 R /Contents 116 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 115 0 obj << /ProcSet [ /PDF /Text ] /Font << /F4 294 0 R /TT2 417 0 R /TT4 421 0 R /TT6 289 0 R /TT8 290 0 R /TT10 293 0 R /TT12 295 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 116 0 obj << /Length 2390 /Filter /FlateDecode >> stream H‰ÔWËŽÛÈÝë+ ³*Í÷câp»Û$Ž3ˆå,2 ŠbK´)RCR-w–AAœŸÈ?f‘soMiÚ L6ƒF‹UdÕ­û<÷ÔÅröl¹ô„-–73Ûþðð¢È´"+a˜Nd¹b¹›={ÕD"mx%š´œ=»~g‹M3³LË¢5élÑ ³å‰±pMOn2z:RØ¡ñ÷åf1 ˆEh™q€CÜHoÚ©ýNH¢h(AÿŽeybAX¬îÄ»»²5vhÆr›59†®ÊF¼¼ž‹¿ý×X¦+ë<ÝÎÅ»cÞþ#«±ÂÇâÂÀžLʵ±ˆ1€HÖˆÍf“Û´½ Ä|y©´±#ÖFir<MÃ5Ù@"‰º3lü–í6ÚŽlòîƒZ–nYþÕrf‹\ÌœÀ†;má†xL\GF‘¨³ÙÍì‚£áèhx&l¶„gºn 5í\ú¾yÊgC<,ÒTz¦g†Æòɲ­‡Â,-Ƕ"Ó³&‚¤Ð»ÓÀ†«UjŒv.† à‘­¼µÜfâkZTMfDpÆ¿E“¥7 JD- M_VHÙQ²§Îeco´ëÓÑÊhŠŒß§ ùDù*·J$3qOgóDÇ‘_…ž¤m^•¢6|õ¾ÈýA=¢)ÖIkØ®D ;ôJ}i WV¼ÏÚ‡ÍÂð`•›J±; ;Î$¶YÿV$EAÿ•a“°4i³µØ¶cê;>óN§ê)êPz²«Ã¡ìB僛ª†HDŸ2v$jØd ÜËÚ Ãˆ—8¹Z}‚Gôò:ku‰óÛŠÝ€JKÿôFdå&/3aØ–<æØ³Ê°²0bÄ‘4„ÖúìDÅmGªº}%YNŸ ŽRõŸ—y³Gzüyõé_b_çJsdÊ%æÁ"…gÌN,ð{yŽßW¦\pîuŒ(ªˆ9=<®ŒË¬ÈÚìUU¶Ù—¶[¯JgÁzù¬d0¸VÑÛJ$iš‘©®T¿ÊQ¹ž¤J¶èœ´®àµä¦¥`ÚÊU𾸟 ÌóµºlÎ#šúf0²ÌaŸÊ¯æùÒµ&¸X4ípC¡…¯·z+äw8E Hàº#p¤JO‡!ùèâµJÒÏ(ùHE¯ùfeû@Ï*Û*Ûò,!Ø'¼o&iÙöûªn‘ðytºØeFøMʼÙÍÅq‹nÀé›&%æÐ Siž´œç\¿y9ÍÛQ{ëCÁG¡Rië¼ÍË B½Ûee«¿èr)ª¸É»õ&µ›PŠ7ÕfC[dHÉž µšº¤TCõ›Óvd)аPÈ‹s R{Ñ ÉU-ƒŒÍ^yx@·ì6+nÙŒ[¨]qPK3µH¨Ù¶:kÑE-ÒQ³M?…Þ G}ñ핱 •ÿ PÇCÏþ2 <:âiò ¹#)*â8P¶7_|}ŸV‡ö«J¢¹H®4ñ9‡;ªoûC+𦬸H¨É£ úè±èÁ?–öy×– µ-9q „·Y­¾¢A¨Ô¹§>R`-§ËE5cªcË‚8jr¨GaGrlpTNñÉ~_W0`6¬CT5óHî(v>¢F±s»w—üxhó‚3ðYÝæk´ÉZ†ªõQ´dÝ1EñòêâýõÇW‰¢t‹b=Üh#ˆXï×XE V‡jöátqâºu¡üs—'çØñHÁi“Ç9”ßó¯õž8¢X% :Xñâ k€Ç{[Á[‹Àrе:ËâƒìÞÑ÷ßt“äÕżÊ&ß Evóf‹ê&ëluؼ.’M3g³`¢ãÙ[Ï ¤ I4ý@TÝ“¯(ýA?¿®Fêøæc¸Rë1éÔKzá¦ivÃÆoYТS]0 m%îÔM¨.I$óÖÄú'è÷ ¬‚o¿eý¸FN”g¡íލ§¢]ƒCT¾÷ ìŒêdÚÊ¿9uªi‘0õøf]ÆßªËàLÈÄs ”¸™ø¸ ¡÷mR¼ ^ªõ;SèÅõÇxÑüFòýõïA?ߎü¨‹ñ7#w‚XÃÐv{6Î`¬ž#)0}!nê53eðë‘Þ̘ ’Á%ÕˆK1÷ÔÉ$ýgЇ+vÉ “*1ƒÓtĘx}uƒÀå,éZ¾&eè⧘9÷ƈÏf•–¨9%lÚÈ¿ÚÁ¬Œ>Bqiq¿¡óòÝ„’ÛCÄM'’+5É~: á©ó샡>bŸyR“oÞþ†ŠŽðhWÙì*˜zT‡ämÆ®aU4#Ñš½;8Cj2!‰WÐÖóS¼FÆý¤%k“¼hp‡£q“ÖùžÜTnÅ}M?®WÉ>7·Š‹Z2}Ú†ßU»¬Íw:;ºå€– õ–%YJÅšP-5¹ªAŸf&‡kj[5Ú­h[Ñ=ö6oò’ M¶¬ê]R ”Ì<O+ôŠ0ÍóüòÐÎýGÓÇçÙ—ª%po{ažõò´Q*ŠLA˜]œ´h÷áe «ÿ+:)¥.Å÷®) D¦ŽÉUÔ“«HÃ"9Ü7½SF¦® ãC//ÄCŒ‹ì#;õ¢èÙ.YêƒSQšeq7¹bTä¾MQ­£ï } å—JÑÜ…‚:‰Õ4_Q{yúàžK‘yõär$%M“µß+=Μç>% aøÿ“p3?Œ~-l¡ÓöqºÐgÐÓYÃÈ ¿nÚ`ã^RKeð‰cTvŒè¯ 9<>èê?-dJÛi%ÛÑzªdªTM":áIB¡XSˆ@Qˆ §¦w®)]0ߢ³Å#™ž34 b ´—úŸ#³º¸e‡$ªY#š‡´=Ô@áƒzKëó|ÀS|w±*ªô³ZqmOÃd=iA_¡Þ+Yž¬ùVÓð{æ x’1÷öM%©ÃS½rNš©-—W”ûà4üâ=]mxHM©‡{jŠgX9YrU®õ*Z(‰àE¹:KÍMÅž'Jw6Þ•›‚K#'>ä0ßòH¹I\ô¬qD›ú«G°MŠÀ M#:™!¤ekƒh£ùÅM,òžŒ±d-|Y!4Ìþ|ý&Ëd3ï¡ç‘u—à4 \p´0öŸŠ?É˶­—ı¦9ÔCÍ„DŒÉà_lçT«åì3‰pœ endstream endobj 117 0 obj << /Type /Page /Parent 338 0 R /Resources 118 0 R /Contents 119 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 118 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 292 0 R /F4 294 0 R /TT2 417 0 R /TT4 421 0 R /TT6 289 0 R /TT8 290 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 119 0 obj << /Length 2880 /Filter /FlateDecode >> stream H‰ŒWÛŽÛÈ}Ÿ¯è<¥iŒ8$Eñ²6X_±Éî&ˆµ{apÈ–È,ENDjÆJ7AüùÇ<äTU·Di”Ë;bwWW×õTÕËåÕÍr«P-WWa¤üÃOœe~‰JóIJ`®–›«›WC¦Êi5”ÝÕÍ»÷¡ZWDS^ÍÜçãÕýû›ÍýX¯ ýFZ…™÷óò7W93ÈUøy‚G晽´‘ûQJ¬è+FÿTQÄjF?¹ºÛ«÷ûnôfaêçº6CƒÏ¹ŸêA}ûîZýé_Þ,ñçzÛ”õµzÿØŒ5[P,@Üzx ÖEWy³`ɱڬRúaœ¤X/_‹4aÆÒˆ$¾7÷=€#±Ú{!þvc ÃH;²²fþo–W¡jÔU”„0g¨æ)~óH‘D™Úš«ÕÕËåÄÎ:)ÌYóMÏ’,ŠtKo3Ôi®2]¥úÄÈ´*ÔXo½Ø_hÈ᧨TYtêΨ/5^ ×ÒÕ¢mM¥½t´?Ö¾š²näŠj:áÞó®°ßx‘.ƦïTmÚ{K8öª´¯£Q›þD+ÁèÑBNv^€rÜYÂJµýZÈ|6èÍ[³9Œ$áD›ÁÛ.l9¢â‰úîO‚^zýæåOï>½éªe½5EõQ»"zæÅ«—îó£÷\X.³ó¬q¯'ÈžE4 脞ÿ üÝÒ›-üP¿ñf1~¾q¬¬2H’\"jÓ 3›PðBjØØ¨]W!®¡'¢š¬µoºµªÌÝn­J!£ 2o¨Ûö®ð(SJD&¼õ ßz!]‘‹3U…03ŠXïd—xòº¼›Á‘¾- /cžå/Äd¡ÿ@Éx[±«„º°öjSÀ 0òÐwq]<à‘&qH’Ïã7 ;úMƒÐߪð£§VýV ýÆîŸÁß²LËe°8è¼Yº/qUŒ4kþPÌl:óÝ3ÿæGëo àÁZÙÚ14ÁÈI ´E29¦ WˆÌþ‘â ¡ ¨a¨…dØ­ñ¹é«§d(qè妊 7Àòá´â"Ú°ƒÏl¡ ÎBEóIµjæ¡(ïN]ùQ2í4rgºÐ&4[žJ„{&ª eÓH*ò2Õw„k õ7‘ä-]àò5ZƒG™Ÿåg0’ƒ'µMŽ1ŽŠûBË_#¹»å`ÝxbJCVŠm}FÖB¹Åá‘§Íá[ÄÕ]?ÖÁ ìtuåߣoO¸iÛ?4Ž µ1e]tͰ!ۯͨ†]YcŸë² áKˆ›i±"o÷»ñ@þlÒÛìÙ~å’óx™8ÄraHv÷©ƒH«dM]K¬·;êUŒúò×_I&}EUp8º‚B•°~‘[{ûÓ•Ÿª;~½‡²+¿þŠØ{lÚVÙ}sûG%l–YsÉ+?°C>½"`õBöØ\[¹hý•Â…³z»;æc/&~:ɵ`Úo¸¨¿zI]J횘{Ü|>°cÓšb¨°üˆ•l~Z¹E¾pÍ}:À‹DV|ÞÎ}Ð7Ï~%}ÙB¿­Ü:_û5ñ‰Ûzvs°*IƒØß˜ßÌÍ­þÆÄpF燶A ±Ieܬžƒ<‰,nž¹›Ø¦ZV¤Z5¦­.Háat‘q©Ÿóêþ ç±?|Õ‡Ín¢ó3 çF{b—ÝwÝ8ÜqÙ—´D‰ÿå@Òïºs3/Ÿ2˜¦°, VÒÿˆòüÁfûúù¹û:òŸ(tPû×ÃAG0º>ˆðë#54lJôgÍΜþï,õüãyšûirŒÍðu¡…º›™tÈ¡&ÅoÑä5„ sêÊ”º¦*“ÐLÕŒ מÁÍlîǽ j„¶s‹PŠˆ˜þ§¶zŽÉ¿Û+Úº÷„’úU˽‘§›R‘µh*¤%÷Kô¨­ýÜÀѳ§ßþŸ0*˜Üm+uß7(@kÂÖÊbgCØr‰]oY9Ä=S¦ !0qC .ÈšðJsÊ „ã­Úì¦7©¥mºÒÞØ „aîö*ô/ÂhvT"³˜-ø ê¿_PÝ*ÎZ”˜Wuÿ`ÕðªRE­u&ꤺº£ ãпG9c†4€D‚¼\ïd³”ÍCí»\C㣰vÔÙzÙ{Râ5ËqÇAÄ~àž¯P”¦¶j´È¨v“H¿æ¹ƒT–Ù?^ﮟÅÁ¤ÿ™LËf¿V> endobj 121 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 291 0 R /TT2 417 0 R /TT4 421 0 R /TT6 289 0 R /TT8 290 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 122 0 obj << /Length 3100 /Filter /FlateDecode >> stream H‰ÌWÛŽÛÈE^õýØÄŽ8¼_€uÏx½qÖ—…=›E¶F\S¤@R#+ÏþÏWäóSÕMQÒhfˆ ŒxiV×åÔ©ÓW“ó««@¸âj>q=áà?~‚$±Ä‰DœF¶—8¾¸ZNÎ/»Dä¯qD—דó?¸â¦›8¶ãК|2.7“kùsfM};7Š~=)ÜÔúûÕŸ')HEìØi„MüÄ|´Ôß{1™¢«Hú—ð'SúIÅl+>lëÞšº±Ê…êJ\úv,;ñüÇ3ñ·[ÓÈöe[æ‹3ñaSöÿT-V„X\YØ Y]XÓ0ÉqØ’çÚnŸ¿z¡½qöF{²ÙllË·#ÙÁ"™ÚZ.þÖý1ºžìÊá…^–/ØþWW”bâE.Òé ?ÆÀï ò(­šÌ'\ ÏT#°3{ÆWC¶â0´“@§k,…CNÊÀŽ­«_ÉHdŒØQ4D#…yg6plÿö"uÂ!ïC¯J¼ËUV_Tke%”±sJe‚Є5cù¥MeÍÅðecMbcQ¹ÿº({%²"[õ(¥áÔvay)AN‡Eiwx¢Kòæ¥`×Ndk…R\~÷Èj¡>[®#³åªR¢¤¿KËõìPªºÏú²©°™˜Y.} Lzp®³l‰¢–y•é[ýW|”⋎šï9tyGЉñÒ¦ìd/Ô&ÈŸÒrp{« ؃G¸ÞYÕ›Z%›3íëð>Ê/êfÃi»£}ÊN¬²¶Í\_¸Î?Y)Ù½Q¶  ÉK P’º@w"otYw"«*^QÖÈý<Ë•˜¯ëœÓ‘uâ¶lûuVíùå“_×r©úEStb³@óˆÙ)Ñܪ¶- Us x$0‘ì;̯s¾á6ó§:[ˆnÊ[Å¥JÉÛƒZ¹È*ju/K×ÈeÛY! ±ÛHzž­²YUö[1§¸]©ŠY†§2ÿ$æMË>-›b ó•ºU¶‹äy¼VÍMYï–iËT=|®oÌfš#°%›àéƒ"ë X.t”7ƨ;ÂÕÕõ\à˪¬o„É*¬#m­ÀÞDTÔêsnžeÅ9jÇË”~ÔŸ¯WØW3Øo¥ÐRTXµ^Û0-Ò«3Kïó¦Pöà(ŽÀKM—ÃL$0ƒŽö"â¼—ú)Èú][ÐÜr­_÷…#ê¦'ÄäýFgì A1+¨#R *€McqSâ VM­}ÆÄ£'ºe/¹Úå±S€ƒš“œ7µ·ÅŸT«´çèØL ä“ äcǞ潑àw\Oæ;”: x¬@9S†Å W[}‰·»—B_¯q©¯@Ô`›8Á'ÀTGì—ãïö§)7TÄ <±h6¢oDÞ*T_l›u+šMMÌfYgÒ¥™UWyŠÁåVÚõwƒKº­ÃÁ.‹Œ <9†Ùì^zø&ûnᬶÄO_:M®ÜPQìÅ÷ “½ÒOÑŽ¾ÌW«;îBŽúc PI– ®4¡fÃÓ½`A¼Çê=-ÖûÄüœÍPgh³!VOÇŠHцȶ\â ´RKi@wñ­ª5(èkÇv41É1Ÿœ¢–ʪƒÅ\uhn9Cûb~e«@‰Ìûj{ÆEw[#ÅÖÈì›íóâwgÕZV½1o—Uò%”+œ:Á³uY¢^/gªŽ _BÊ`«úu .êC|CÙæOî57v…tä…OºÄjÃÀ9ÐÓFÖý…ù–&pÔƒzÅ£ Ž$¥YJâ×…>ˆ “=£tM=„à¡28N•Ü4‰–!=¨a.oˆú{Um©´­(Ô¼¬•Ù»UÝLÍLîö€7gÅþ¨ ¾ŸvÀˆ_K?Ðþ=²KÒGÛë ’l .E}‡¡°Ö ¦ˆ*Ö«MÖúÑyVo9òlV²,ÈJ+Oæ¥ZÛ9+# AК (ªÊ ƒ§õÀ8g3g.yPÂE3Þ5Ás2é%Z'àd“·åJ«·þw€Þ‹#8Œ±gGÁÞÑÊÙëèËÌä­TÝ¡ß{h§“JpdÉĪÑ=ÀØMO¦,|RÊÜqð¸Ñ VèpGb%E¾v„ÇcÂÆŠïJ´–°D¿4j¾ÏôõOø|ûÇ8ã•s‹°Ý°qcä7è%Hõñ%Â1?”è`^ÞCÚ½…i—êI:èsÿ ¿N)αEªsqدGήâSÊ;ÃnДLJ˜½jÔ=©>š&&ÇSä2¼Ì¬°rÕ`ªPþƒî×õ¼Yi0ä •ƒh>ÓUŒÒ¨MlØxmÑÐ\ñò”A¬2ýJÿÝçT/(ž­õãáƒòÍ‹P¨:o U|´Ø€~¥ô‡ýZßÖ¬6õÇ\Üïõõ/ö~¢q"ž‰/aÚ]™ÜÙâs¥€п;œ:æÓܵd”ðì¢ÍŸ±“Ð8zò¹fò$Ëæ8w¦\à@šGôu^•èIaLrñ Å}.šʱ©ðJ¤±tF.ó1.Ï ¿—º257ëñîøÈr-‹õr¹µÅÏ)õŠ·QG>C7Ðáö7¤ uê4?tÙn¿Q.[Ü8OZ>£¦tb¼Ä±Hß?2o½q&'68Õ8%ƒ47luÔëOÃHüìÓP¶ƒ•½ù¼ÖÝR0šKÆ"Ä IC`°çSXü­)ì%&×B´æºSý‹¦þÚ‹ZÁW €žfÅ}MhÔ H)ÂÏ[œDw8&44ÛZZmQ.CÑŽÉŽRÅÏn-Š_w†é¸X( M‚¥€±‚+üÒ3¶ƒ¶÷â]Rtêþpœ¸À$î8g@Ã~ÎîŸ[ò¦¦> eyÃ…×”žw/.¸å/qP’œ11‡>êáô }LGÓ=ú J¦Ô¾bæyËêöŠŸÿ@ˆLäû·Ï_#’Xþãù‹7ÜIûKbm«%µ™+ ãè°bÆz¢™³%1¬ÁÛ²\ÿ·‘½ê˜^Ý9ÍêBàÌ(4hWYÛ“èhnZ"ï¶,†>½-Û~ Ù¡WGîÀuÿ„£ýNžÖ÷Áõ’‰ ½!5´Ø= ¬× ºwÖ4‘úÁ£ ûæðt]ðc}ƒ0b¬ÔþÏ‘¦ƒvwÒß}i¯ÿCz¹ô4qü#&•¶-x“Ô“éѤ¡eÛn¤€éMsË8é è¡ZÒÄ/l=À2 0)Îg§Ol™[£ˆÏÌ.±–sn/n—ŠAø¿bà ~zâg\ѺiŽ„126”Ø¡ÍI5 ¾C"ŽÇذ4²^çúCÁNç-1â«4]U•u;åî]¾¨Œ0¬N‹½jÎvM–{ó™íž®ÿ§˜}ƒäöD]j²|TÔ6ÕØz¦Ø8´˜àе¸uý »®ØJWúîЯkúS‡$ªã¿z{`0ØΪ̆‘ yŒ©*ˆMg`³)Ïy6ÂCÆÊ¤"±rú Ø©ZÎïquõ#ÀèVQN endstream endobj 123 0 obj << /Type /Page /Parent 338 0 R /Resources 124 0 R /Contents 125 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 124 0 obj << /ProcSet [ /PDF /Text ] /Font << /F4 294 0 R /TT2 417 0 R /TT4 421 0 R /TT6 289 0 R /TT8 290 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 125 0 obj << /Length 2990 /Filter /FlateDecode >> stream H‰´W[oÛÈ}ׯ /ìEó"Qäf qœ¬»I6X)Á¶qaPÔHšš"^¬ªÏû 6@ÿCÿcz¾o†-«í¢hÀ’sù®çœy5\Îf#á‹ÙràÂÃüŒâØõb/“$rƒØ Ål3¸¼ªc‘Õ<ÇuV .ßN}±ªžëy4' »ánðE~LaèŽäJÑo Eà9šý~ð‰˜xná0¶‹6f}0¡­h™þŽ•ÞH é'ó½˜î‹Æú7‘kUk Cw"kñòí…øã?œa䆲ÒÙúBLwºù«ª0cŒÉ¹ƒF2-Î0Á[²Eì6»ø®?Š&xž½6Öø1[c,Ùív®º‘¬±#mµw|ü-š5|ôYë–­yÿëÙÀZ ‚ÈG8}Nð#ð‚,ŠE¥ËÁ+ÎF`³›lć8MBØluLÂð}9vÙŸiÈîaüðø£°ßìþžâŸ@[ÇŽŒ·Ó=‰O7/aÈ­ã¹c©Åôõb¡ê¬ÒÛF—{x®Šv{“C‚y{›_ßOl¥Ìœ1B¶v|©„ã{½ƒ·Zl«òAã<ž#²²Rbê$È÷V¹±,²÷ïIJ-22&Íu³º˲ڈr)R‘ëy•V{q+ÝEž_×ìTb´À7¡šÌµU0DöÃC@FÖL/±u¸P[U,t±e!r±ÍÓ†ºuDSЬRicŒ£Â@ÍûƸt»Íu–’}µ(ÊFPȲÈ÷f„]‹.Œ± c¸ãq/}°#0Vd­ãh§º)7¢ÞªL/5Åê$C³¹йóÉ™ËyÛˆ4¯Ë®8ìé¡ƽðâò¸3…>B›5h€‰$KÌó–ÂEY|oÞ¿s†cTò·Ù´Gƒz0BDžîUUŸØÀãøXž~`Mck‚+¨l**ËšïKû4WYÚš±2±.T³++g£ïÍkÑÏ¡;ŽBÒh2(ìIB™e ÍQ¶È 2Š›r®s%Žv—ŠÊ4”:SÝÊF¯Ö]²GHÚm®\ù\ TZl’:&àä‡[™šõ÷„b¾¤:äƒÆ+óné Â90ý·OoÊ^é‡`*ßxÎ'L¤º€­E¡¸Ó¨â•yߤó\›! 7cCƲÑK``,µãQè¨hÇ&ci&Ói–©m#J³¸Rì¹#o×XˆÈž„Ö‡t±Ðtþ…yÜ” {^R¹µ/S:"X§=><¢5—gÛ«Þ×ÚÔ芼ƒ1ouÞ *u»Ý–UC˜Bu–H ‹V5¡ W6ÂÒ¯)[1üʹë{›áïg³Öäê\&ÎÐ꯮»5èMlÒ·9'”ŠˆP‹ð¼{·k­ŽZFèdƒÒ<ê€z<ÓÀLÇz`ÿ„VÜ(ê8òßÑJšxä®l 9Äß(âfíÄBNÐtŒ¬<'¤ `¥/c²÷å{‘XâY"è°ýA§†-þ#G‰ôÈÈ?Ò^°}XQ¢ëA¢"]4¶Ë¨¿ÒLu` æ¶7m³/ÒâÌ3­qÈ-ó¥­&2kZó¨cÀ£íì&©éž\l ØÏͺ\tð‡3›aÎøI©{“®Ô§%cË´=ÉHo€EtU7ý°½`Pút#0y$ ŸÑ¨á¦£"ß´˜ºR &êú ›ynËÇÇâútsw…½»)lÙÌÁÝä¸"èx+šX.¶¡%§—œ \ª’Æ!wÌ·öMp |—r±]Ý8xê… -h€ô”œ4_dO'VuQÅJê×Z 35y_´›¹ª°ûuA°žÈÕgóå…XV`GZÈløN˜µ`¯µª¨€ QK  3<§ELĆÝM¡c3B©_¨¡ˆkbðnsm‡tÈ×oO+á€îC;¢­.Ÿ‰÷}´D©¢1ºÛ¡ਂџvé âeé0aàÞ,ƒËeÛ˜'}vi*âM/°32×tÍ9Gn›Ó¦ÝXyýáí͇ë»ë³Ÿþ‰ïÈßlº¿®*@§}¶ÐrÍ!î^ÞÊnÔ+6ûæYzusÁ¦Ð’‰o¨4Š(X€*›EàO `>ö¶//ú™2áí¯Fé›ôcõxÁì1êMÑø/ò9ð¯Õ¼]½ÉÓU}°ÚéFìñÝËÙì§ç'mõÞÂäáæ2Å5üE~øqFàéËkÒc¾üö)·Iµƒj3XHñwõ;ñË©PLüþ²^g?ÊÅôqw£M£Sm÷ƒ¿žô JNt:gÞïSéâ±L›_úï ÿ Tr#þ7¨l@É £“Ö<í¦UK´Û˜ GÉ•0œ ]ÓÝÁv¼HW@¤¸SF ôÔƒ¶MTlЇ®ø°f›3–WÝnm§æù<Íøëýg«xlÏ9tÁx!t§´àvÖšæ¯=­ýðx¥½Ñ ‘£Ÿ£¸]1Ö׆•‰ "Yµ3(Å´‰ )]œîFµb´liB‡œæ@ÜCÑß4$à@Í+ŽÝ‘ƒTl±cB"y,­õüõì.:myƒT´¨nn™¢è²Iv× S…zøŠ‹ߎ´¹ï]]¸ƒ=¾ùÆÒRe³ô[ð- !‚ÿ¾MϤ,Eî,°`êh5Jéþ ´ý_Á„ádtެߋÿRô± >ˆCº¼•­|N€4 '©ñL•ÏX÷tá…²n*³E¹ëî1uÍ#Pr'–H(qyf¤±€5ÌÚDó4¨Å-EU¶«5z¥>m;ÙÍ3 y±Q¤2jº˜Åß— eÑš¥Šµ(T§õ½ŸÜ†úõ8}ýv¶ÛÞMͶÎ0Fâ+0=¡×ià¡ò&GX§Ûc̤뾅"™@†¥ #oD‚?ÀO‘Ý-æéVw“Üõ­saï:Ṳ́~äÝn!Ë[ó„Íæ{öòõ+~Ar¸·Ù²CdƘ. ¢ûk Iò£nø±îÍK &GR‰¾%Õ1«ÆÎ¿Y(ZF¤PI7Û\õ¼ãúþÿìêóâï)=––! bÒMaG1/q…xù‘ƒhî/v>^É$ixMd–ßRÖsy¹â)vZ ˆT)³Øu`ƒ/Å;šàÐa÷j§Ñ«¹&¼U ÝO&ò3 ‚º>o O'’í÷ ¿œQ¸SÕ|æ¥1/„‚gÓcÙÂVØQþSzf| ÷Á‹:Oç z{ŒŽÖ<¹}‘olX(Yàlà;{böÖÝQbG/ÐÔüAd0,wè¤Ô̰ó ôÙ‚„®).¸È^¿'m®^ñ'ÚCóòÅêxÈ–Ý|@  =ºwì$®5µ†”Xƒò>-\ Ja¦¤æäLçºöÀÅm÷¥z¶>ç4Š\ßS”wX"­!`p³O/,Æîã ë|±¸¼*j¥ØLñZý³ðò×iˆÁøÎSÜ$@ µCÕ­ ꀘ"E×$Ð(Å5Ùy^˜ï³/¤´‘˜*Y—«}¶?ÿ\uûB7K£—i˜5rszâß×Öü’jÄ^$]¤mÝ¡½vÌû"ÄR•îÙ!ç¥48gE>eÿül¬»•”˨ˆF‚¾"Ë\mFZù¸Îg¡h1¶ÐÀàMZòKÈԹǃ@«¤s5Žo9)…B™ÇÑÖûKVBˆÊpqüƨN*ë7‘™Ñmó^ ˜GW·³@Na„F¦œxÀk˜¯mÕ#?É«ÐqÎñ‹‹ 1ÜÛõE•=÷œ¦k_“VWV°rBš5“ÂFó¨j0–ЦPŸ{ØIÂîEÂHÈOöh¬Nwœ½›—«ï% endstream endobj 126 0 obj << /Type /Page /Parent 339 0 R /Resources 129 0 R /Contents 130 0 R /Annots [ 127 0 R 128 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 127 0 obj << /A << /S /GoToR /D [ 0 /XYZ null null null ] /F 77 0 R >> /Type /Annot /Subtype /Link /Rect [ 153 130 291 144 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 128 0 obj << /Dest [ 123 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 344 349 361 363 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 129 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 292 0 R /F2 291 0 R /F4 294 0 R /TT2 417 0 R /TT4 421 0 R /TT6 289 0 R /TT8 290 0 R /TT10 293 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 130 0 obj << /Length 2487 /Filter /FlateDecode >> stream H‰¬WÛnÛÈFoõ£ìDqxf6XÀqÃm’ "M»* šIÜP¤@Rö*×íô)ú޽è÷Ï %Y–²7kâœç?~ÿ7¯ÓÁ8M}&X:—9øÇÇcÛ‰EIh»±ã±t5_µ1Ë[µÆam^ Æ7ÁíÀ±‡ÖäƒQß|üÂ?fÖȳ}¾ôu9s…õÏô/ƒD°È±“—x±Ù´ÒûÝˆŽ¢V¨ú/sÇg#ú$ì~Ë&Ûª³F"²¾”m¦gG¼e—7CöÿY£ÐöxSäË!›<Ý7Ù`E€Å¥… |žU3k” #•DJm¥’+lá‡úé-ˆ•4Z’ÇÇGÛòì·8‘ŽÚZ¿U·„ŽÂåmÑOèeùR+ØÀ Ì)˜áÃÐñ\FŬ‘ƒùàuzàƒÞ:‘a™6ÏÞôÊÎborAòñt)Ùç[v¹.X^W]VT-óX+󮨫ö¥•þ:¿uµ·6‚0ééì4äRkÒ44‹l?Ô¶àÌÌôÁbÃ#jFiï}a¼]-ŠJ²[+€3*˜)äE§¬±¤Ï ò ÿd|8~CŽwyUÕ‚¢ÇR>Êu|²‰l[2ÐéÂ?ÈFñÞF±–n"»µVhœ]æ¹ÔM-‰ÀµÝ`§ »WÐÕG¼­6“pu)g¬¨æu³ÊÈÛðºd+Ù-ëæÛ¼)Ö*°†±IåœU=Û”ò>k¥½$‹ü?êâô…x/¯¾+…/#Ž¥ð(š¡³õº,r}åjÓªå’>³Bwafê×U…@dH¦¯g¸“gýÈŒu5[e_­Ä޹Ô[˜>`c9øm,CýL·Äά,Í3lÌI#,3Ø¡Pµœ™¼‡)`‡’ƒTϱ4@tè_H^n_ö›}òÌJãìºêô=[¶®‹ªcs AÌke9=sÚ:žç ôbl"ÔÄW„ÐXJ0‚$°CßÁ© Õõ‡›Û×w×ÒON:.tK'Û릺¦ÿ¦hs-ŽÎá)ïg>ßÞ]Áæw·U?’]½î›S«o©Óï.ÓôÓZà459%|@8ÕÚÉì qy`»OÓ öÀ¼K´Ël‡ -ú‚‚¡ÿÜ’m3Jþüý;FÁ0\Y£(¦ºàûÀª$±²D¡–úP©¡€zWÜ7Y³eE†à¿\[|Zô>+¢½n~‚#ý?ŸÄ¾I,8x^—eýHB®³&[4Ùzٚ̽—*¨EÎÚN®[Ê•.û*é›72ë,! *´‚k5)£#q‚Cå¼,$BQ%¬•ôð'¸Ê]û \2ã/üB•9¹E°Îç’€f8$‘íœÛzÓ°,ï6Qv›µ}œ"º¢»½;\[KÍ 1%AFŸ„·¦ËLß,jkÔG=37ßFY`Ù¯ï›Ä8'Þ…‚AÝù¦,·l¾©¨,’‹cUŸÌ„&¨É#0¼Z—ÒØ­}æg; ¾Sz8[7õC1*g-¹´cõ\¹qòæ¯lÊuRÀ9Âà)`S½€€<{_+ÊŽÞT÷E3¿+ËN•·L­¹8ÀæÝ¾¿Õ¬~TÝ)G-¸ªg-„¶YÃÞÈr½,ŽcaŸQ»äR>T'#ü"BàfdÈ©5dït»ùüçÉ}ã+Ö‰G»q;D èE<ÖÙøçû_%ò ë»âAàÕÔb`lìE [ ^m~Ãa7%ì;¾é¾²+(àó~˜ZöÄW½8:‚/òìàvtöØÂ ŒpN#—pbÛwŽÎ8Æ¥“— UE®ŸÜ~C=…n$¡ÅiÂ+8Ÿ†L>™èE|¾Æ)2z1¹Ó"ŽS­ €ß…)/pí8>†)Œ¢i»áaU* ¢Üw ØdŠ…Žô±ˆŒ°ÀÐ.ž¡‚º Ú«í †OƒËjˆ£°ÒÀ 2–‚¡¨Š®ÈÊâ[”ü ZRW±€˜3þ%@6|!ä««y±Ø4š¥ÌA•†ŠøT‘ùJ"U{3xD Nð®åi_I‰$·aøêºx ´=õ(À{ ¯8Æx*ú¥^ÒídaàeÖcÛÍz]-Úz”CmòBË*+d/˜)tŠ÷ø”)Ù})I×_hã Ùã’ð?ÑÉò%˳ŠÝSºÚ‚!g½G*V&WäÏ•Z“éƒV(F³¬Ë®(9Äp4GƒUWÊ-ºCä-„1Š9ê¡0Kª#ÄH¦Ü£v?ÑÑ;K°4™‚möÍà)¯’¿eÛC»ZYx“)Ó’é !\lVH©pä>è5ªÈŸ†ÃjÍgÒ\f9'¬3Ä•ž_kœýÄÚjéd¨FF€r£“ž{ýð± N ÛLÞo¬¬:L‡ÊÐjRØäÜÛ6°‘n¦€¯7]Ÿ+poDa¨’,¿˜o{f©äTñ¤Ž;™ÏÊeÛÂl½F;Iw¯ÌŒõ"kÚ±eh 5p¢]“™Š©)òU&.4ëi_b+z®§>Þñ»ð•ºä'ÙëtŽ æº± 4³ý˜Ôo#óß Â~ÒwQ¦žLÀv×?·ùû³»{#;êgû¡¼ùôüëôš…S6» Õ=¥ç¯ˆ?ýyÊW[Ó™Z¯Æýø‘yÀTè™ o"Å$93Z'T¼´$ÿ~z“HÀ*Ï_tfúÉ=q¬‹‘ˆ‚}Q}5>åv‰óæ?;InדçÝ~zó÷gû{c° ÿ¼ÛÏÍÃ߫ͩ±¯ÍÁ>AS:kuz,Qrëæëð0YQ ª*ý/tÔP¢Æ»|\^ìê9@p9ÛÕ_ä­~GpSˆAÆAÙgRN²Å=†Ê|!:ówùÔ‚pSG”ÉÌIĸڼàÚxϰEtðŒl©ªÞ™S@€w €õkn ¦[åÒ^Ïæ»“u2ʘwÀÝŸÃË—Dz5Õä‹«' âA•yc9mØVUpÈ3£}¨¾´0+Õ½ˆÙ½R4Ës žK) ¼ÀDÒ©tØù_${ÿï´P‡{ÙCóP8”õŒ˜Ý‚æUdÀ(Ñ£²R×_Õ[F «Î' ð¯*…pSB±KÖRÙÁH®à¨ñØ…½ té{ÝoVÓþ|{w…¸º»­ú‘Ä|n«}¿/3ûÝ»ƒh卨íl»fƒØF¥§+Û¡0ÙÖÑÞ÷ï·}ëJÓÚkÅÛ¦|j‘.šQ$ôáéd{Ý4u³—$û±wÿÿ‡:ÙÙ endstream endobj 131 0 obj << /Type /Page /Parent 339 0 R /Resources 132 0 R /Contents 133 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 132 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 292 0 R /F2 291 0 R /TT2 417 0 R /TT4 421 0 R /TT6 289 0 R /TT8 290 0 R /TT10 293 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 133 0 obj << /Length 2650 /Filter /FlateDecode >> stream H‰¬WÛ’ÛÆ­¼ò+¦ô)‹ûÅ.¹J»^ÉŠw£--%;ñ¦TXpH"†—¦SyÓè+òyÈé™Á•ܵœŠ]¥€™îÓݧϜÏ&g³™Çl6[Ll‡Yø¼(2­È X¦Y.›­'gUÄÒJØX¬J‹ÉÙ«[›-«‰eZÙ¤£Yî'?i7‰n¸¦§-9ýu4æ8úßfšÄbƒ˜…–8ÄÔGkù½ÒV´ äFÿfŽeyÌ ?1»?°ÛCQ놚±¶âU†¥k†ZÅ^¼š²¿þG7ÓÕ¶Yºš²Û}Vÿ·°ðaœë8ÀÓ’b®1ØRx$Â!9¶i{AˆçÙ·Ò;ÞHOöû½©»f UØ‘¶:è6þ-êb´­Êš¤Yºû_Î&6ËØÄ lÀi37Ć×aäQĶ|²˜œ#/m™ŒØHœh¹¦OP…>ü $VøÑôU&l9ú“vv,>”^4ká¡\V¼®³bY5Ïù¡³Jêf½Ù–Ùœ·fIšòª}ªËf•–Å"[6OÉ6Kîs|Ö«×…ŽiC«ø—)Î@ŒòCa ’2”¦ØùgÊý“‚Ýs–YÉíÚÎÕòì=‚¶ásS€‰ ”gB¦YÌ3]7 ™|lãóhP4Ò¥‘Tšob*)llk¸¥¶°­Èô¬ÑS_=u¸ÆBvpúH®úÝKûëB œº îñŒÙ±y=áÚß•´ÀaUÍ7_Y¹»-º®,ØzWÕ„¯RYsV— Ò6½¾b2&›­²Š‰TP­‘ÒÔ¬,z£ÐiˆçDáÔ+•{$?“É—ÿª Q¿Ê‡¢fûä ‹ÆdoèiLþÉ×zÉ­Ì(±¨uQ\éªT¶ÅWÉ—*Q ¯í Y¿SÉ ”éj²QãÈ,7±v¡6‘r¶€ôŽ4°8+’5¾ùð•|ó5‰9âñµ!ðq݆&—@øÚ”ÉK^vF]È}”y‚­VjƒžóLY¥5µ%n šÝiÊ/´¡¦8aF-Hƒœ†½K*ÔÍNX×"5—òÕRwE_Óò =þ™ððÍËGeû]Ð¿íø‚­îtSÀÞäÌ@²r‰îf ¥ý9;qS$h÷«2¼IxÅqY˜³¤bTù0«aVî*6Oê¤éq¿CÂÒà-¶æër{@g¿° ö0ä¸> ±ˆ—ôÄQ¾öãõÕšQühF¦ÿ¿ÐìºÝRÝž0Z’·¶lQn°¸g&s€Ñ"»ÌÝ ^Aï£æË“•ÎQB1Õx&9ÝäßÓð’C¶œ“OB,8ãdr¥…ùâ|Œò££N¡±é¢ã·9@Žàš“B…ÑM€©IGŒ…ùªâi@ÚégVI|+ö»Ö ÐÊüDE­²m äõ÷ ¥jEàr;ÚÊ&?êb‹¤/ ò?T¤eHKLò$ψuÀVÔ`S–-  qˆá€²ü®-ä¶‚a›°Hv9J@)+¨ ÐlY³E&^L7—&C ®pSå%« j!ÖR*°@[1Ì3²Ç¥Éˆ~‹~pdõ´~p¿T?ô÷ømú¡ÿ¥ÑA/VšútA¥Ê¹•Øè†íS9W¿*$Ë6=ï´8Q ‰šÐvÅø6ÉBa¨ ÚÜûtÅRtnDâÍ%µ'*]‘,ø”4½(’w¯Y²Ù䙲ô[a>Jq.ª³sÌnÓ‘TԎǸ ä0t4¥»%;#üÊ×÷|N—ä<è9aµú‰O•¢]o”5izÌô:Q#4¢ZÊÕ©û!+æå^œ¤Œ¤ËŒÞÑÌ4õü¡;Õì©'÷‰é¤òÉÄݬb«„(Óná®)5 X¤‡Ñ–TG«#Èb*š Æ‹T¾Xµô[nxAYȶx¾öiD¥®eÚv¯çƒ®øßàsÜRΆ ?i9l`7„rƒð%H”Q9š±ßT[ÚŽ ÿ3¸•Í@±H4X¹PPˆw }ª¡Dߥ9q§&~Ÿº·ˆH^ñú=í9uP0}±×ª=ÛVdô™1ô™u|V;ˆ;I¬Øº9êü@mãh¯¿}ZÉŠè ‚Aù±ý”'R6àôÀ´8]œ·Ä:·N—GN,„)ŒIõêµÛ÷ÓxªxGImÏ>? äÁùp¸1—Õò™QÒ¯ÁôÙ&ç£l@K¯èV"×…,d%Oå܉jìR©WÔ²-è‡lÎ8s˜BÃ*Q ïg¸P]SÛ'†¬ßa(¢ýÜ FC©gÅ]‡Ç¼¤˜S蘶óx gðüš\£èö@?æÊÏÍMÎ6[¢Äø]½ƒkðl žKAªŠåx"— üs-© ::d¨vÆÁCû¦ähÈ<âù‚ç%ÅgØn»HRÜSJò &•°CZ]NYRØ<Ë»"¥ï #ên€ž6%ÉÛ‘üª§Ðð/–ÍFû,ÏÙN>ì’DK¡nƒ’O1°ß…à«ûAòóc±À`ÙzÍçD§¤axNú͘,•$M¯<'ºþÝájT/Ž–—ä€Ô¹(SQ 86$åÈ^/dx™4‚ÚýÇ.ÃxœG£‚¬îm•/z!t%ÖÝK¥lÒá7pbüUC(…x½œMþ;ÞØÜÇ endstream endobj 134 0 obj << /Type /Page /Parent 339 0 R /Resources 137 0 R /Contents 138 0 R /Annots [ 135 0 R 136 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 135 0 obj << /Dest [ 261 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 730 88 744 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 136 0 obj << /Dest [ 261 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 385 716 401 730 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 137 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 292 0 R /TT2 417 0 R /TT4 421 0 R /TT10 293 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 138 0 obj << /Length 2342 /Filter /FlateDecode >> stream H‰”WÝŽÛ¸¾÷S°sH K#J²,o0’ì$;Ýéfq¶h×Å€#Ócnôcˆôxîå¾A€¾Cß±=ü•d{&[°(Š<OFóÕÇ(‚<Ò<£<ÊÐt–…q%h^Îßð\­‰/êÑù»[Œø( £H®)FîF?{7Ä’0õ¨|ÆŠÿŸó¿ŒfJÀ M£p–Á!In6Uz<•¢ä(Ó‚þƒâ(JQ 3t¿G·ûZøž†3oM9ƒaN=Ž^½£üײ0ñZV¬ÇèvÇÄgÚŠ ,.}8 õH½ôƒ @¤ÒH™­LŠqˆÓl ïóï´68WÚhMv»]è'aæq(Eí} ÿµXƒ8ö8³ô²b­ä_ÎG14Š3 îÄ(™ÂÁK#©QŽZ:Z^Ï{1°Þ™fQ˜›t®W~ÆË±ÖïU诤ڔmÚæ¡%úýãÕÙlî8‚Õ<,6›/ˆ¯›Gð‡@uN‘ýŠ R£{ úøèO–œ…v-‚Ö¡qVNJ¤ƒÔÑq§El´@%ã5+T4UÕÔhCÄZ úD÷¨&åˆo7›¦t‰VM+•A-þzŠ’ÑZ Z?°ÚWN<ŸÄÓª §VͤÂÂN±Ø)6í›jÅfa¢ïè†ÖK0fò`é=Ò–³¦#¾¡#%ZmëBÀ )™ðq ðÝ+ 6% q%­“›º%»oI»wòÈ#a% N:ì8l÷2^”ë­£*ö°2$K¶ZÑV¶j›JÄl íR†¼€À>ôoP‘.CË‘hàㆴDÐC'iR›lr´y©·¤ä*,Ê+VH0-·…à¡?ÿEŠL:؉0ö\j j!2æÒ8ŽHK¿…äœMø^€~?±+ë¾(Õ Ÿ§ñ¯YEmSØ ¬^5_¤>Ùøÿ(åΆTØÞÚD˨Õ0ŽS£!§- ãã?˜„Ø»‚œžy‡Êv¾Œ3{fl˜ DøAæÀ1 ’š°×úÛÞ£ÄðÌÍI¶”¼ÅùNÏ4íRuhŸb%ç—¡uÒ8?… ±nò±4‰aR¹L«Ö€Åþˆ1ýÓ“8‰ëX*e€ñj¥þÎüÈkj­Ôü8tÓ¹·VnJVìדͶ\JØ‹²Ñ“T‚A«*ºd2±à,÷:oV@»5ËÇ€rfÖïXY"òذ%°J­'Í7 ¦Âl‡ü)›âd÷ÉÔ›tpšh¿ û*)*ä5¢Ü« ¿‰žŒãéa(«xí¶ï¤ÜR³[©&ëWიnÜ¢f˜ù(÷cÔ@ ›/¨Úv›:êP¶DI±F‚UGI|’‚=I¯ð>„„HƒKºh%Ë«,†º÷ê>Ð(û…'Í¡D¦¦ð„&Mœ„~æÅò/‘XiqtØJ`(¼Qt(NŠòгj`œŸÖ#î°?1iv …ŠïË/ÉN ˆPæËÔÄ€[erLtÎáLæ òƒP9*ß ÈóÄ‘^&œkP1€g•!³{vžAªy 5Uª»ßzç¨Ïr®žÆau&jR:V†š 5†*,b@DS»ÊÃíQ‰ü¢Š¸šA†àÌ—›–š-°Y§«™€šÇô¼‚KèFL 3ÅD–r¨›€gÑt P¬iñI1*‘­”}YXíÑDhÌ€¡\«²„¥/û/‹M›ºEK ô«ÂV¨–ö’R5%ØåþTrã. °iD¤B:^ú¢¹zJÆ‚&­ü2]ŽË²ÙIÍ‹f©=6“¨ˆ¡+VÕ3²gR]| bàºÑoßêP¿Å:Ò3¯nvå ·€E]GNz=]œö²ìü*AÐðnP‹}!œo+jßÄ€nÆÐê½!eywUÛ™o x¿ªoì;P§ èÓív‚äÊ€¹\´Pñ·mŸq]€úš'ª¥°º¦Kû~¿·£7M]ÓB\ª²½ð¾ m:ÅG"‹‚r'Öv¦NãÆŽ*òÉ)Ï¥¢v¿ÙWOî~ãô¡aÍ›†ÕB^Bøtÿýů¯Ç_܇—VtQ%ܽÿ°cìúב·!õ3™@O Õù|ÅZîRFØSXƒ³Åš^ó:—ÍÈí(Ò¶mÚ.nKS0ÔÑ¦Ô ƒPã!´+ö°mÚµKÒEr×¥˜ºî8üÝo^uÓ™ÖTÐw³û.vL¬Ý×m+/½ìàÔhgîE®«`Õí¸óÒ•[Ûñ‰åg •7Jzæì*ɃËêmœû'ÉǨG• ƒvªÂc¦€úT¸óíñ²G<Ö®)—ÿddNùÎŦ¦»ñWÎa¯›V 3" 3œÚ´²ÕÐT ˜'U´ºeŸ;~üüÒfuÇCeŸewTü$[Ü…gögã-‘˜«a/µÌ¢>÷8ehöÙЮb™…Y’gÚºwTâ3ßÔÕPï§W×ó¿ß\Þ]ý8ǙѮ#‹YYšéXb×% ©Å €¨†ÿ¸úá,¸g]>By8bëÀÚ÷Ñ¢Wrþ‹¡Ž´†›`šÍfÇjo:.(7 z€·À À°Ò¬žÁÝây ÿX9¸2¥Iz¬ï±cGÒ2"ÉéÀI8 ÓÉ4xéÿ¬ŽÃ8JóæGUö•?uEÅjôÛo‡…@ÛêêÏ›·ïn^}¸½ü£UèDå7÷Íçy@?áóí×ߺöM6ø.]MÛò®—Qh8bGy# íã×)Zô§ÈÎuX§R¦w uUâmW$ëfçêD—~¿ôê€æïg¡®'+UŸ¬ìÔãƒ.¡WH¾R±ž¨3OktZ‘îÎùw{U‹ü°zÑ üò”Gž%óÛ!™_ÎGÿ?£=´ endstream endobj 139 0 obj << /Type /Page /Parent 339 0 R /Resources 143 0 R /Contents 144 0 R /Annots [ 140 0 R 141 0 R 142 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 140 0 obj << /A << /S /GoToR /D [ 0 /XYZ null null null ] /F 77 0 R >> /Type /Annot /Subtype /Link /Rect [ 71 169 209 183 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 141 0 obj << /Dest [ 261 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 392 142 408 156 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 142 0 obj << /Dest [ 134 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 311 57 343 71 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 143 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 292 0 R /F2 291 0 R /TT2 417 0 R /TT4 421 0 R /TT6 289 0 R /TT10 293 0 R /TT12 295 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 144 0 obj << /Length 2289 /Filter /FlateDecode >> stream H‰¬W[sÛ¸ž¾êW`õà;Mð&ª]g&'Mã&™XÙmu<4IXÓ¤JRV•NPÿcz@€ÑŽ»íhF@ð\¿óàÅ|t6Ÿû„‘ùjÄ\âÀ~ÙNä„d: m7r<2¿½,#’”rCÊ$½¹bd]ŽÛqpO2šèá~ô•~Œ­‰gûtÍñéRâúÖ_çͤ€™:ö,%^Tt§¾w§( G¡ô/â:ŽO&ø˜‘›¹:d•5aS{F7¼0ôì)-Éó7§ä/ÿ¶&¡íÑB$›SrµÕ7^ÀŽ6§(ðiœ-­É  RZ$Ý–.¹Ìf~8…ùü•²†EÒeÉ~¿·-Ïi QÔÁbðŸU𑹴ú…Ú–l¤ü‹ùˆAFnÈ œŒxSx˜x.A‹"RðÑjô²ñš©dÌ 6*N8`®¯b5 ];U°šDȨùh'Mâ4}›}<µæ¿À† ºã‡è ÝùJ¤¼|ÇP¯í ‘ ·zn ·Žó{^ì Qñ±’£·…v膊Ž#õII“z½%£eÒOÏ/ç_>^\¿}?ì:1Êê—Ê.Tar£™R÷•žAf‚+í†Iž­ÄZÏî㢦;³«Êõ¨äU/å“ZK;¥øÆóU×wÈ'ókßé‚«ÖSÍF©F¹Ú  ±?r;YX¿ï‹ìä§-s¢Y¾71ÙðäÖ(­âjWêY¼ŽE¦' ºij¾*x\™ˆe|ß Y%²µ‘Ñhågk‘a,zþ`C×z0Ivn´+ÜNž½áÕO˜º•¢ `€uÂs q¶'@\ k¯T|z8ŸÙ¡…Ç8¯×¿‹sayf;^ÈŽA±7!ÜÇÈjG‘í96Y`áäFTMN*¾žëE¿VÚŽÑ‚ÆÛíÇ?(ÖI7 GVÇúálËÛ]5hà†¼_`ZH;þO¨°®i ëØ8ÇŽ|Ï Ðê1(iÈAÄ7éq ú¶L£N”NÊo2á?(Ï¡êl¿ÒX0øgßÌùo[(é˜É•ÂX›¸¦<.Í$ÏÌÞå¦òþ.ÊÊÀÂð°j„fyu:\çK¾ŠwiÕ—Ý Q§t¾S¿¶<»ÚÝÜòCSÁ½8}mJ¸þú¤Ö« ·kKÙY|wñêìúí«ë×o?]Íͺ#u=’¯]Î=2;r¦®ÆÔ=?õâú}þ2‡šÉ*à¸Zç?t˜LªîBLôdåæð¿KQ‹÷æÜ_Ÿ3ͺÿל½¿øùúÕÅëçŸ/UæºÉSò÷Ãù凗Ÿ>]x÷ä¾ë>”¼‹¢È‹&EqE5œ0Ó0•†Ny_ò]sˆÙ¥Kóõ¦éä±iµ»’›£Mœò¨îîÐa°U-(8T¶ï²éÀñŠw"C‡zÀjój‡Z”7@ˆ† ëüu˜ði•g2g`wÒÃBí‡ó÷Ÿ//ŸZ™Éx”SK¬aSG/Ó¼D{¦XZ6$NõÎ,h` Ò“U^iž§Atm¬q•5÷\ªÊ”d€ƒ à2WYŒÙS ·¾$ZMæQê©Ü@q~ÇÁ|€e`3ZZ¾=£`÷$å÷<%êj¸+À—¶e®*¶<#©¸åäŠp“#Ÿ?Yº<%HµY|‡Né)ÙÆe¹Ï‹¥Mž—$Fu%è ЈAT×µá)«Y9 ïzM«¸XóJéN&\þjþL%wyÁ!4  4C’Àûe\Á¹×± ±z€F¢ õ°ª¨—‡,Ùy&J™ÜSÂãdsÓ˜Œ!.ÄS ©®_YpÜžJ'.< ²ßø\2vEÖþ1…¯hžÔÑý *hã–DB ÍÝv› '€Þ¬«ƒÜ ÂYcöϺlg²#}’èY’î÷q뺨­`¾±‡¥lwVÉr‰µZXsëµzƒt´ÿ¸¼©[…[.–ÏÀ¶5hÁ¥ ü‡`„"õ£t0Å(x)ðgD-ðD -OMû7¨^ð gkX}¥W‡+HìµRŸX°1l£¹ëëBq‹šóz–%ÜÞ.W=Þ ^ Œ¬ÉSª–M~†®Pû=FšB*cð«Iaá¿Ä .L)¹µ"tõ€™‚®£) ä’XmÉÈ bËGlyðÀ\’*7Ä#í¼˜·"©6…ÆA˜hÐáIÁG«Ñ‹ùK² ‚€¦vÓȇkEdKl¹‹S 4œGÉÍûä YTŸœ­,`—ƒsÍU.†Ÿùª‚€äÕWÈÂÉFÕ æ-K Þ!êg\?Wyšæûz²€+T_ZOk5œ€M ëwФ^ëfã¹·i²Šž~SS¨¶A:B…Ú£,f;ž>°´äVS8’wœݰf*µmu›¹?¯ˆ¼ëÊV  äüo;Qðåi?¢“  >é\’Ä65"JÉÑ7Üàé Cã0܆¿aBñÔÓb]<uyC±E u³@—!4!š%øÉÃÓ[@¡³È‡åR»›çÏP¨þï‰v4½ƒÕM³caO˱ú•¸ŽMÙ°T£3¤[YË<ü1.è› –9¢6®vR‰³¥ä¸q~Ï•–=Êu©š Qzp‘“{¬m†ü€ZÓ´H)*+Ɇ'@’½<>õÄñ†ÇiµËÌ®(ºG8Ž,y™â¤Cªïl8Ù; ÿ Ù±Z endstream endobj 145 0 obj << /Type /Page /Parent 339 0 R /Resources 146 0 R /Contents 147 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 146 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 292 0 R /F2 291 0 R /F5 296 0 R /TT2 417 0 R /TT4 421 0 R /TT6 289 0 R /TT10 293 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 147 0 obj << /Length 2891 /Filter /FlateDecode >> stream H‰¼WÛnÛÊE_õ½”*$š‘¢Š¢@râ>q.°”ħIaÐÔÈbC‘:$eGý£þcºöÞ3’,)i“ž ,’sÛ³/k­ýtÚ9›N‡ÊWÓyÇ”‡ø&‰ë%^¬FãØ /TÓeçì§&QYÃs<ÕdeçìÅÄWwMÇs=æd}|è|tÞ¦½Aè;M¿£‚¨÷×éÏ1o0V#ÏÇ8$LÌ¢¥¬F´=ŲÑ?TàyC5 Ÿ±ºÝ¨É¦l{䎅nr<†îÈiÔ“}õ—ö±:už-újò·×5fD˜\ôpÀÐIËYo0ƶd‹øÚ|¥Àwýa<Âûô™Xã'lXòððàöB7vìH[mz>þ–íwô§Éí€L˼ÿù´ã«\u‚؇;}Žð£ðŠ,JT­;óÎSDãypŒdlbñûi¬s~×›þ"ËblËeFlŒ]lÀ#©h´È­®æy¡›^Dƒ÷y©ºg«ýÏ]ÏåZÞÛ^nµªVºÔ3 ÈË;õ'ëÛÏzóÉùÔëÛ¡uZuÛƒ³xq:*ou¶Xcb2@,kªoMõMZT÷läúŽJïÓ¼ ­b9àÓm¡ÕJF«yoˆ€°õ”dý’q-¢ä; qìh%ßWò–åi¡^ž÷(É~yÿä’7¹¹À–±óìæ9^}GÞ®&SÙy…¿¼ï%¸ÓáŠ×ç×Ó½‹…Û‹%»‹%r±û´X³±ö4¿ùÌåÕgÏ}ÉÈßsÑ6Iê0¾’ püx/Žë÷<ÍÊ^eUÙ¦0%vr*¢‘S6*Uåzy«kUÍU£›&¯JUè{]à­¥@6J®ÒWEþY«n£kÄìÝUo0ÄpPètû'½rÇÄÜÆþ]ÏÃ_3„ÚC´d +‰ t›¹¨sT¨™¤R™€n–™‘G›ÌöÓä…nßÓEXß¹¾¾VÈ5B5ÁG›F¯¯{*ׇé+NíÁH]­áMnfô-ÅK‡ã=‡pÿ`\G»¸Ž¾בD5”¨vÛ´¾ÓmÓ=E¬QÈ|ý‡Vepa@E‡A =ß'/p ÁÉjö÷¼AñRož"*€‚· œi» ¸°~‰¶9ÏûŒv^ùäî¹e¸sËÐä×ã[çì ù¦>#²¸ÔFÍ«Zi©Ü~–¶iÓV5 c½ZUu+èGlppé8+{u©²"×e«ty——‚X–?9í"mUŽjiU£ÕLÏsÂS0vT×´º*çùÝš`²*Ü38ö@Âoç$ÎãÀ»…}¸DŠfó_î0ŸÁ—`h0óÉœØæ›Óò|•~ƒKzD«¨ú!b¨öªGզ̘¶ÔŸf·í3xJ>û³õ#%ïõ+Þæ’—±Weƒ;%olÎÒ©¡ñé`ÇœOía¸’YÚU„ôCóaä9*-äAvT«ª‘w±•hª­˜ùx—´…;ïí%A‘äk~¹£ Lä§ì»6Û¿ø#-Nªì∇‰®ž\Þ\€Ñ.Àc; Á: â286Ú#¢àQQñÿ%é(z{õ¹# ]-ž  ª4ÔosškŽØÐS/êvYÍûC""‡¾ê‡€,–U«áub@V—؆'º/X{ÀgÉ'²äÃ,$33bÆiÿ‘%ŸÈùšÚé6ßè6KQÄA!8Š#9¡{ó®iïÙ”¼ÁNÌÄa>¢3ÃEP³ Dß(Ï ]Ò=˜Eµ¤à~vKnÊ›¢ZhYbÃ_úÌàj™~¶s`&þšº24¾©ÖjV•¿o •ÝÒГ;²ÚÊIÙú3¿EkìËþ1·»¹Ønp²nÆ»”ËÕ)ÿ4)A? <*{™á«&•(ݘ•.‚2v6}ØÅ…µ‘^nD³§ªž!éíX¤L‚¬3_‘~-å:f,™Ô7%r*a<w_n@ùA®Ü]£nêÆØ8#." ª0(µHï5@¿hóU!|(ý5«ÁJcCÃ×R 3§t©Oúõ¸ýhó%®˜1ñâõ+ø œIÊ£ÖKÊáˆ%«3{T£tQlšN-8 \P†a2RòjÏ!šÂ(°Õ¸Ðž¸CQ¾÷xÏlá{‰;ôöØÛ·÷Ñ«r?·¿RÊ*´}¯obtµ.KBxÒКÔÅ‘è1G¢C´™Ÿ *êi#§”ŸÆ:‚춟´·ÇáñÞùÞö|Û@¨X­‰{bGlIUCÖX½šAÓKŸ#V0Åsj­ÕmÚä˜plþxH"m£Ã¾å{ø"’6;ð­Ùq[Ffǟ䀼¤ô“ ¿(o|@‰oêÙè; ŠÌ+Íb\PpMY‚Ë®ísI88vè³Z¾OdÖñ$‡»c`û¸Ñ#Ú¢=þ<.ª EÌiÔ P¯qE,›ÄU9A¸ÈBTÙJCŠÌŠ aCʤ[TÕJ­!Ç ÈÌh×u)ëÕdÊ¿çozõìæÙ›×çÇ­*Ý0þñNu¿¡Ù±µgØšŽœù6¦‰baóéZ?-gØ OÔ¢»FƒóªˆmuÁâ¤ò'ç“ÉÅ›×ÙüüíÍ—/_Nª‡´Ú²Å^hbÆLJÈ•œÄzÃÝ |»\Ë#Ò ú9[èì³@¬ ÁÀ¢V«VÙP­dë2™VÊT†³1Ä,É:HÕü…¹ frI4&ÕI5în` „(«§dÃÈ{TºYhÔΪùû=_XË‹ªÌo©õŒ¦B’à?==Ø)sÞH^ªå~Š=,5ßÍ");ýƒþ+üFæið|V-—y™£< …KZQÖ‘‘P¦#aÀ`Û‹„Ô¸-ÚvÕWožJª\o£q”I’¸Yi¦•8¡ì;1º¯E_hAáv²‘™HP.t^±æ¿|ºžÏÍÄšjø ØS.}ÿbq<áˆàÅ{ñ–(â=¢à0Q0RÅ™ÐÆ:’G†[9MŒü`åž ]ßLÉaàQ%úT1¿ ©@®Ö­äË%Òž@ûewOÊ cl|Žm~NïS•®VE.Áoúª*}T{W´Ítv&‚ú}D:XÌz{å-K”€z¼<X@ @<ÖvS ‰FáÎØ„˜B¿*ùsj(>®efˆÌ*.'*ds«~]ëzc—“†”E$_]žtöq·i€Œà•öyÇÎE¡s³Bbž€ ,Ä^»Yi2w Az»a——âý;j_¤6E„ Š gßN–þqSIj|Z{—YûRo8áȾ/ƒ1Õ*8¯Q]˜Xjþ”µb|ì\ty63 ]Æ“í<«{Ê/A° øG‡YªáÉÿ>I~0?Ž“~ºÐŒyëÒd<8(-Ù½‰¤z¡2 õíÞµÐÅL´öþçö-:çi¶Peêzä Õ;¾©FMµÎÐI‘.žžsÞ¿­«»ÁfÈk.ÊyÅYÞÙçÙâ$Kò¼œQÌ€…+ÙÎ(o½•åFtþkš Òè2=Plgm+Ê…Ä5¸»ê5‚ÜVs,°ÃÌpi¥9¨Mc> endobj 149 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 292 0 R /TT4 421 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 150 0 obj << /Length 1589 /Filter /FlateDecode >> stream H‰ÌWÛnÛF}×WlýàRHó"SR pÕQíÆ‚ÄM£À ¨•Äš•»²¢ý þc:ËÝå]ÎEQ0wÉÙ™3g.zá´Î§‹ ä¬Z†‰tøƒG·ß×ô¾n£ÞÀÖ̾n!'l Iy$=£#âE­³ë™Ö¤¥kºÎÎx-U.÷­÷ÊÄm«–ÖUÖ˜=M™vûƒóSk* ž® l¸Äê ¡Ë›=¦Š­l®è/dêz©ì1@‹š"ÚVž6P6˜ø°´´žBÐÕuýúw[µ5KI|oÓA³½O?áNœÃá  t7Z¶Õ,@ejQêvê’ihF×îÁÞyÉ­1ú©5Ü’ý~¯µ-ÍVhdªmþGt>¦B|ùó6©þ‘Ó2Z¦mœ²zð@°±LÄ,ꣷV­N!ž­k}‚ú#;ŒVqÄ{?Z£!òâ%Fä·m­Ï½ï)˜Æ"›xO˜.ñ=ä‡Û‡8¢.õás‚ßù ^"£d!‘Cä!‚ ÏÏS§Î~48od<4ÜbËÖÎÍÌbí\Ú\òì ¢¤ëÊ!»ó5ݸ”¯ÞŒï‡nÜ#¾æÁnMøÎ‹ÁL?"RJˆ³3ª/$MvÝ%XÄW…¸Z–Å¢š_î  †“^òÝâÀŸÃ8аGGÑÚð\™·¥*S3m HI€$tŠû.±â˜=e‡Ên⻋“Œ“7ç‹,·c’Äë4Ž£UÌ¥¶…7©dzÞÝn'±QÆý‚¯øî’?^¿¹½-È8³Ã(Ib)AÝ‹‚Õ&·y7ލaËx; —%•3g4þüò~x;½vfÎÕÔ‘Zr&˜¦Öç)–ƒ°òBs½•¼TS‘zŒpÞù­dœÔâpæ’ÄÂéb·Zá„d–®_4…¦&Ï$/ªF± K6mܤb7¨`Âû²5.„@Žj=É/Á.Åe²•(V¢ ±ä¯H$õ‡»-Žf\n.ßvN%K:z‡kK­Aëk¦ðæ$<@ ö„üIÙå84oK×2¸ ì•ðòWeQ#§Åœ™þÝåíÝp4ÞßÝ@ú¥üQ#“Îõ5b†;býѧuˆÒ×sÅÖ‚–AE›òg5B)²òŠ<ÓCWVŸ Ž«fW-ã#î‚WUèejå÷Q÷AD?"5$Ì—D_Dnryô³àŸŠÄ C¨îÓ¿BpTg%õ³1„rúQÆhî›Â¡†è O.eYKî¦<ÒÐ EºànNézÌDchô" o®`Iü ™ùè»Ì©ü¤‡!›UʨüP¹E!Œ%3»2[y RjÈ2³\ÆÜc>Kïnž×¼7Ê:w=ªt*¾óRœ–UßÝ5˦FNo:ìÙDÒÔ̇fª5ª[)QŸÇb2½»žŽf³ãˆ˜<ðþ ‚åâɆ´§æ†á{âè{¾H<‰àR¼’º!s\úâÃÒ'ÛÀ“Žà„~mnKƒ†at¤‡-¾¼œŒÞÞ¿Ï&·Wï ]"çV8nNº rDó0/¾JâP¾cŠB0Ç]š¶p>8uä]¢ÞàÃ÷âÔ‰€&µâDÎ&8X6‘ñÈ”ê^æª/i ÒX‰s…ýÛ*ðåUà£ÑXcÚ€n‚“Gé¾$®dW½g®_cúª ÖÌz£–uö--ãRo s û^ Z ¾Ö›Šªl_¼ëíÕ­ón2ºwF¿8jgÂ9 {Ù|܈V~‚°:.G3A'ÃV>ͳp«mªfм@«yû4ŸkÖçUã¶;Z3eƒ³ŸAÙ Y¼²<“ÖîäƒuÖϲéXÖùó¥zÕ 2$ŸÊqZÌ[åÈçScó¸EËç %¬œú‚†;R»ÄÁaܘxù4hÖ„æ·ß>6ÀÈiëœI(‹zC³àºqD8G*í#J*ü}3®ñD¸j-]÷¿ëÇéˆ÷ãÉóåœA· –2"·6Ÿ8ê”*-ÝI`I½Ó¸8½tõXç–ÝÌ]ÄJóŒÌ,ÎÕÔI‘9­£ø%» endstream endobj 151 0 obj << /Type /Page /Parent 339 0 R /Resources 152 0 R /Contents 153 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 152 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 292 0 R /TT4 421 0 R /TT8 290 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 153 0 obj << /Length 1903 /Filter /FlateDecode >> stream H‰ìWënãÆþ¯§˜î„\H4/2EmšÞµâºÝ؆ÄM€®‹bD¬©yQ9C3J‘—È[äó#gn¤HIŽ·7 @!@’Ãs¾sÎw¾™yÎâxŒ<¯ž\øÁeE޹!šLCÇÜÅÙàì‹PÂä±$œ]-<ôÀ®ãºbN2™a=øhÝa{8c눫o!bÿ%þã`* LÑÄu¦!8 "ýQ¦¾÷'”…ÊÐÏÈwÝ1‰Ë-wh±Ë¹=ò&ÎÔÚFa8‹¡‹«!úó/ö(t«¤Éfˆ5å?fœÃäÔc ç+{4…˜”ˆdØ2$ßs¼q8ûøR¡ñ"‰F!©ëÚ±'´X¦v¶ÿ9ß@Œžo1j^¨iÉFÚŸÅQ4ðCÒé¡`7¢•d°¼…j|í©b˜$yïx"K“0pÎ}•&xåœë"¸ÞGëì Âv]+ÃDXUêQRä9I8-ru/@ÊçiÁÈJeNÄ ¦iªFKýyIFÅ–äfæº(Õ 'ßs3ãïa\çr9 ‚@d°ÅÅ—«7{^ °,«ršà[²ÁV# k o@ $Úbq:bÊ›H¦øµF<,âsÞKsŒ“í»LÛøR]ñìîÝ7—×/zÌò £öSc-K‚íøo{†Å;ë óX}::tÙÿ6Á£Ÿ6f7——ñÅ=­á ˜‰Ž—ˆÃ減ä’d'¦À¾ãŸŸ.peÊ{ Y^Æ ¸"»{ëÞîqíŠðoqZ‘öU뗔е I»ºuDß`=Út×Ê%«¾®´Ê½>ëIÎhÜïÚgõgv‹æo4¨‰À Mðm~kÒçJË£¦LF [:vS>òº EÒ¾BÁÒ÷òâùÅÍâîë‹ë÷Gb8ˆàÅy^cšù ;žÿ_Ôæ›ÙìSµ¹¥YM+5½P’„Ð'ѦZ^YÝ\ÙKû¬õ±­ø¡)ååP:”¨1ÉhNº2¢E@AŒ©åîY_QðÅÓݾ 6Ñ™è«öÑKuöPÄŠÇݧ–Jß•”“¾YçÿÚõïÔ®«ÛÓÒåÿ¶tuYZ¶-r¶¿Šö{âŒÿw…kê|šnZu£ý±Oï0É %›–°I¶êWØ×fýãFOœ öX×ô«Ø¶Ù4˜‡xY”|Øå'+ôƒ¬XÑõn¯ŸšÌ6»Á—uHÃ?ÕokÜRæÙv[-O·l•+-ë䣥½}“ÜXŸè¹ ñ/p „ê’AÔ¥€>?>»ø°¸ƒã„"´8¯ ™;Æ"ÃK×™ˆWÿªýG+9õÉiD?žÖI·_Ö‹··óX'µ§1‡-Ô9k¤E¡i^圦G¯Šœé!£‹­È²,Ê~;ŸBÓeµFXõd©§7m}îMø¿ûÒÄ|y{3SŽ?û¬mÄΔÙ|~;¿·Ub¦Î4”¦å Šàß QàN¹.ëêŒãºþXe^å ê%s147yQ›a’je7šbØnhÄI«D£ ´8\ˆ6rÇG£vºô¸SvqĺÎïF_½~Êì½y<Ô~þ`"?‹ã1ä;^<_š†ËÄU~ý °ÍÄ1»žp92ükû Ȯؤ ÊЊ0ú“âz$d‹È÷$©Äʃ8Ͳ=` ClDA0ØÐ*°½µ]¦dˆ`¡ß ¾ÁÑl›’  Ð?ïïåTkŒq‹h¬éµg¤2Œ’”‚  \I'H³¨8’»;„#[\bNÀ/,m+Å‚’bE{$)á€]Â^°hqøŠ€ ÎÑ’ Ø«’‡ÒÒL-°µ‚`úêÃ5ÂÛmJí© ìÏ’ 1Ê0ÌM&R…S9!-j´- ½Õ! E¶jq¯ BÖOƨ­Ï~yÀ>0 ù ©Ô‘…b}ÎPs⊜ÐbèÞJé#?„&[-+i%ΑHVš’Ô1Š…Ôîô¼äKñr–›ÛXÔÙ³ 3ÇpyÓã_àøS#zG¹†®ùO¯Xsa­¨Ãïh¾*j Ó:<QL-(!@šSNqJ 2 9áuQ>‘B'°äfªk6A¬}B£¥FJMuO°Ld¶ˆ†¨ŠªõOm˜ tk8¼LÁ[)¬iɸl ˜œ¹±a 6ü¤>< ®´]ùÉïßɇùõW Íojš¦0â˜ZˆãGŽà&"õ‰ñÑ’Aï}>Dtðìô0´‚4¢ê8‹¿qô*h endstream endobj 154 0 obj << /Type /Page /Parent 339 0 R /Resources 157 0 R /Contents 158 0 R /Annots [ 155 0 R 156 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 155 0 obj << /Dest [ 154 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 121 690 137 704 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 156 0 obj << /Dest [ 159 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 121 674 137 688 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 157 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 291 0 R /TT2 417 0 R /TT4 421 0 R /TT6 289 0 R /TT8 290 0 R /TT12 295 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 158 0 obj << /Length 2902 /Filter /FlateDecode >> stream H‰¬WÛrÛÈ­}åWôã !â²o–´vy×κBfåŠrAä„,­<ë VUù‡ücrzfp!eeSÙµ«(\fݧ»OŸ¹˜Îçó€$ÍW#éÑÿñ'ˆcwOBŠ’Ðõâ‰Oóíèü²ŽiQë5ªÅèüõLÒºMÜÉ„×,Fãöò0ú(Þ§ÎØw±Vü×äÅÎßç?Žm ¡hâ&!>âÇvÓÖì÷"6ÅW¡1ô/ò&“€Æü'¡›{šÝ3–‘›ˆª3\ún$jzùúŒþöogº¾¨²ÅæŒf‡¬ù‡ª°bŠÅ¹ƒ"-–Î8ÁLjtØ:$Oº2#ÜϯŒ72ÖÞO‡ƒëøn(jXdS÷ŽÄoÑl£ôDµ/̲ÅFÛÿa>’”ÑÈ %à”äGøC¸ñ=bbªÔh5ºÐÙðl6b“¸Ã)òᳪO¸G_„®3ÿÂ6BkÃÄ1Ñ/ɾ³ö'®ƒ@'²Ï äpÅL5û½ÞgKe÷>©”ηItœÄ‰×&‘¯»ù&«©Ö&×l’e¼È˜“çîTP¹¢æPÒ6Í ¬]4Ö|¯1<Õ:Nc uéÔˆïŽ#¨¡‰­‹[¶Àº¨%ƒË·êQëÏRèÊã¨Qcþ`ã¸h©êE•ݨšP”u“æyªq\xf Æm$mÙIÏl˨ìòüòÅ‹cGú䣭¦ƒmGÒ@U­Ò…\uf€ì¡ËÄJÆSú]\qWlÌD X0,µv:`’xàEØ»aÀ8Ü“ 4Ú°r¦®™3A‡ÜØWž½¹N× €á{yü£^ÿgÇÃú7¸m`ú±Y—.™«Òé?Ñ9úðÐMdï³ç÷€ÿ˜Þ¥Ïá-ÝxØR¦ÝÚÂ{+{®ŸèÊûíš ¾Y’QŸÈx­À‹r»UÅò ˜8RŠ´¡lE÷åžÒJQ¡cO¨)5=‚A”aÈæ†ß,Þ½¥™ªîTu~™gªhÎȼl€¯'Òª¡F ŸdÅšÀ¢N…eË®`> Ôx±Ló²P“5×zZk¯6éš./É™Î,ù6X™ÕÙMŽŒ±ÓR¨å.Q)ny Ò +œxfˆëÐVJ.½Y‘ºSãÞ³}üQT÷͆'ƒYeuËw«¬P ¡*´— T\,ì¤*H¥¼8Ëïq0ƒ+kÆ•]z3{ùþ •½Ü¥`wY;ßÞ]ÂÕWX’ãovB Ç&{k¥ô{C+»vËÃìžÓøyæ$H¬ý6çóó6-öiþè¶Uß^`Ê µ¯¯ZΞHrÜΓ®þ{Þk§ˆ†íHüÍ)"eÇû‰•ù~=ÏîëFmÑ¥˜Å1Z´tÆQæÇpöy8“žèR\òlŹ3ž">&¿ã&~:|¦ij|‹ß©ãxŠOø`yPæâ¶¦Ëré0~Ê´ÉujÞTšì²²:a:¤ÛrÝñªP”_@ ,ˆÂÑ­ ú$ÈÝ.vŸJÍ2E;{Õh"c†ã-:ų«Ÿæ<»SfɽµWjyaž=OfŠ0Nòé@²\;cž¬Ì¶ ïey¨ObN“ÄÒÛÙsãŠÆÒ¥m@#ÛôÄÿ(Þ²þJ¸Ý¥(ö_ŸýFž÷_HOˆåùé&^ç*¿K?Ï>FU£—DU¡žé~$Eì~`â/®ððš· a˜\ºD̶šô¾B›j7&¼j*޶¿ãux·0û~æ^’bf—¸-z,VºjékT0W>Ÿèpú¤´ÿߪîä|§ìµJJs#&j©ÀœÌ ñ¬Õœ Œ…ªî™ ô˃/ðC&(c̨#î’èXR?™G{¶¤9d™A×5¨5œjJgâÀ»‰”ꌇšf[ÚçÀ´Ûƒ….é ý•œâ|ñµ¡«‹ÁšL]Ÿc °Š/zü§§úù™Ö·–@]Z2µJÒe ÝÌgHOÓ¾Ÿ‡û«Ír?Óõüæ¢Ìo9Ñ‘Ðý©-é&ÕϘw¥=r”ˆ¼ÁéÈÈþe³ÌžÍÆîUd6l´kVbªå71OñfI‘‚~Z¤˜²ãå 05·Œ(ßv´ô`FÃÔôµ/€°G´Àô¤oÍÀ ø<`ÛÀ]‚åxº;ŠëLOÙ³Ó„ çÀi·† bñX9Ü °ô–ùãì›a÷Ùr¤»¼Gäð>Jø8`t†æM‰¯ìfŒŸtÔ`èç»ãS̤£ÎŽ9ZQoŽGÏóäLŸq«%]B°¡ˆÑà\è`ÏùF óÁ'‚Ç}Ù× NY¡Ë/ESÜì×´Uu®•ÆUñù‘cùaŽsF †³çãhP5fûR¥F«ÑÅ|pê1ká›t'Aì™ô}1Ñ}!ªrÏ+hÎ \²!Y–¦Ò7*ß­ö9áLZi?w%f¾Ó¼U¸±6x@µæ¾Óö²jbeÕu•i›]äè©0¿š ±¶ÍÜÅßeYè¾Ù½æùMêDFZr×ÞÂî}0XZØM[ÔZ­`f½{KªXÃÉ'…úŒfÛ›ó;Ê6®ØÛÏWúé#ëo)´#,ÜùÙFÉÀr<7¥‘èCŒ…ùÕ!†6DA9ÃonͰ¬@9 ?ë=[ L¨è"ùµ~Ò1}‘çåÚh=—®Êâ׆¥!=èº[=j¿k>ÛPQ6¹9á€YgeQ0ßÕaÑ«U…5¬û,wøMü>Ëö´‘Þ€wõ€TiÃÄ K ª÷˜l·à þJg·oÜ'Íû‡ö®ìýëNC/^hR´'-îY'ÔI ‘D~sD ¨©p0¢øPêá VÆèý…:ÓíèÖªM'ÍûOáղ ¥ÇœÄ(X â¿DLëÁ˜P•âßwöa-íÍ<6³»3³ffszXúpÉZw«@ó¶~,|[‚‚/Õ5û_ö¶€Ê•ý9òÈ­Sx™›%ÆŠ Jp8`Á«÷#ØIx.z»C¥U¨ôܹ–,r*Ã]ꇺ ËÌ|SNæ âk¼lŠ„•‘§ÊƒÒê€:<±ÀýÙH7«l‘èC±DAØÿò ýáäކ5z´js v2}rà¥îœ,:¹%Š,Q~«ü+Ô´çŸj¾ÂM¾‹°\EXݱ¥‚MnîaÊ‹:¸tWLÙ†W!œ¦%¥øDC“m)óTMíð endstream endobj 159 0 obj << /Type /Page /Parent 339 0 R /Resources 160 0 R /Contents 161 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 160 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 417 0 R /TT4 421 0 R /TT6 289 0 R /TT8 290 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 161 0 obj << /Length 2985 /Filter /FlateDecode >> stream H‰ŒWÛnÛH}×Wô¾5‹")‰"ƒÅ¹o쩪¦(ÉÎ`m@ì&««««Nª~1Œæó‰òÕ|9ðåáI¹^ä…j‡nyc5ß F/›H¥ ËxªIËÁè핯VÍÀs=dÒÁ°Þ ¾èO‰3»½2ô ´ bçùå f±šynb“qdmd}0#U4 EÑTày5¤G¬{uµ/[gèÏÜX¯M“c8vgºQÏß^¨ý׆îX×yº¾PWwyûoSCb áÂÁ”™3Œ1€J¶ˆÍG |ן„3Ìç¯Ä?bkÄ’»»;×»¡n ‘Tí¿e»Æý@7y÷AÄÒ5ë=ø*Wƒ ôáN_gx(LÆ"‹"U›Árð‚£GÃ÷prÔ,ôÜÈF£‚ø,$+¿è?ÏáÔõõkg8ÁãïßÇxìFGg“ Çl¾6ê%4è¹*ÔumÊvžo̵¾vÔrW¦m^•jטL%²E  ¸÷W¦iðíæ­i_½ #Bû «XX—ާ3H¶<«ÛWü”ÙÐFbˆŒÉB6kÒ£j"þB»†š1åë${PŽïé¼Qùf[˜ Ì…i·¦Þ«z—å4w|±O꽫ÞTµJÔªª²^<¡]¨v tÀcC‚ƒ!aoˆE%;¢YW»"S ƒn‹$ÅÞÀ'Y””Ê”ë¤Ä»§b9ÈeýÀèlª†L»=|ÿ° 9ÎÔôšAf”ùžÑ*­Ê%àë|µ«òŸAÝ7,¾/éÄÊÔˆÈíM•-R÷û¦xP¹|QVÀƒÚmU[©$M™x˜^‹Œ]œ#|¯~ºiÍ÷6[<¨,í&m‹ý“|Ì pPf–É®h]õ÷m±[9"™àfº¼ÙTÙ®0ÿ€‘|P:#œ·DäNv&ç âòYeI›4mUU˜[S¸O1îm‰{‡ìàN²M^ª6Y¦áªZ>>ó]^jA>ÄIÛ‰¼ÉÜs'“ˆÑÆ„Ä÷9­Žt¹ûNhkÊ’©;Ež`ù©òÁ¾Hé1Ö?KR^ɲß(mÔ=ý¾w|ýêæý»¿ùEú¹$‰ý.JnHk¤?Ùó>°‚Í®i`Ù>•A«:ãÄUÕ™ýT3J$íaöašF1!òØ ÔNû¶¥ˆ9¶>ìðT¬g~‘/jd±€Ã}ívüXÖœ¸gâäQWcB;M:êì]£º9ó¯´>´ëÝ0ìè_+ûÍêöÜ1þŽKƒ O §O@óºÚ7­Ù¨%Õ篜ált£©)®^¾¾¤:4Ö‰% Á@GâãpÔ˜Õíáé€úáüÂ> .K¾„k¬¯~£Sq¥¡’Þ¨€R}ØXùu†WP,ItD€oík$ž 6rŠÑ{¢ Ë\VfôFÞLôÆ ßÉ£"]ûÖŒ.íš[+É™p`bí.;•?Vp¼//Ê­hó †¼uÒôFç-Êå1çrLÅœT*á!W $7½IªHné¨í@¥r!v4Ȳ…ÛOdÉ×ϼµ Ój³Í‘¢Œ«´HäµüR“ #¬äµ¾[£ÉVkQ8é>#1L)Ë­µ z²sh¢™Î[GÎ…xß¾âHíä‘ÙXèÞx¼z¸vœñcŠ»«ÖeOhùU)z³¤I%Ûƒº`xíø·kÄÑiMŽX?ˆüdYÿ’/:œÉ;S[;Héu ¿ NíËÍÈe§d:Ê^? ögê9ó2´§ßÄa+:•\Þõˆ×š»À™N6ˆå½0ðÞ>ÊÞSÔæªBItÆ©»ÓÓZL£ÎŒ@ÌX:v. ž’»$*É('qÂB:ÃÕ€JF{iPc2ƒ0ÃUs¯Y—Q¤WÈM#)òv. ¯y :5ÞªÛŽíŸj yÛ‘¹|VyËSÔ83±ï#V(v•œ ­¶¶dg>?Ù£„s¹Ožu6ôþI–ååJŒ¥L; %\Lß”Àe²qü 7øed›Ô”*‡+ÄSÑøè:Ú°[‡ëGjÜsèbÛØ¢I®‡—tµKÈ€[ È?PÕ–œÝœW”èŒQÀ™´Sv~Çù‰ç;j6U“–ƒÈO¢69öÐ'¾[ĨۧÎñ¸Y¥ÕâÑb9êÑIŽÄ··ª,ö`£uÒ€{»¼h©ƒÞÚNZš}¾þQÐáH–Yw ÉT}Î8Ë›ö®ŠÉ=tÊ™#P¨L¹xŒ!T"`_çn‚€¤¥2Êœ/¤•XòXóò„®«Ý]å»YQ<È ÚÆí®ÞV²€ &ÕÖ§º¶sh|Ñ×z±kѵ´íD*LÝvWT€æÚqÕ›ŠîS\ÒšÕÖ€Pò[ƒ`ßæuUnà î­Dn´¦. ó=A;![“]`MštS6,/[# d’Çn—<ýèý½vtͼi+±¾]jßÇd–ú¥;â®G€ðÅ´'j:-ÍtHwÃc|{Ñ¢‘ë×wTº ÛmäH‰?ž1"YV”¬3®¢(M¹Ä¢[.ÁÛ£Ú’‘huí%(_a9Å¿ÊâÕBâÿÝ^ÈQ dG@EQ¹›ªú½1Áý³3„›ƒ‡‡â£Yòd ^ž &:u'<¢Ç¤¦a€qo{;öûòð幞0b¦SËPDˆa?xŠx|PÐ`1b|©Dµ£hŽŸ¦17‰ü±ÊŸ3U}´’•©‚€ÐŒ'ú0Q91M`:g—êñ@ljNF¹ØK$ÏŠKwXLÙg.L¶næ‡Ô—BÑ’³³°ï|§ zRN"«ßrº6nÍ~ûDæ÷$ß¡ÞN|v¬•Å!enÚæµEJ1êïÔÆ!ñ@¦Ðuƒ›nŸoHÐ õÏnläîž®~ÒêÑ endstream endobj 162 0 obj << /Type /Page /Parent 339 0 R /Resources 163 0 R /Contents 164 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 163 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 417 0 R /TT4 421 0 R /TT6 289 0 R /TT8 290 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 164 0 obj << /Length 2637 /Filter /FlateDecode >> stream H‰¬WÙ’ÛÆ}çW´òÔHlÄ¢ÈS5²dG¶d«<|pEr¹š`“D ‡yté ̯ð?ú!wi,ÄЉ"—‡@£—»œ{îé—óÉÍ| OÌWÏ.ü?a’8nâF"N#ÇOÜ@Ì·“›/ëDd5ÍqE•“›¯ï=±®'®ãº8'›ØíãqòA¾W–8¡\küõ¥\ë§ù7“”6HEì:i‡‰Y´åõ~Œ[áSÄý&|× …?©XœÄý©l,Û‹TntÃcàIJw_OÅ?~·ìÈ ä>Ï6SqÌ›ë=̘Áä‚B©Ê¥e§ð[’Eä6¹ä{ŽF1¼Ï_±5^BÖ°%Çãѱ'’5ìˆ[,þ–Í|ô|Yçíž–mhÿ×ó‰'r1ñ#Âé‰ †//ТDìõd5yIÙHÆÙhãG®“˜dôI ˆÏÐÆòõ£ÚZ!8¿+ôs:¹Ï®+lð-@¿È-^ñbWÖyùó¶Z }kÅÎL~‰éŠåýßï~xoAdgòÆÍ—A˜Ã>ªÈÎbMÓµ.Th'I²°ƒÔŸá„Df‹À[.¼¿À”@¾¸cy®„£Œy¾q7t Åä1=µNGiÜ!ÐE›eä„ÖüŸ¸42K(jS&…ùf¶uþ Òéúœ`—,²€ÆÁ‚©²ÐâGÄJ¼³ìaûÖ²CÁBˆódfÙ Wå*_öªÉ«rê§©‹à! h…×W‹‡ íDÔb{¨±ÐBeMþ ½ª3ñã»·".Vy¡t{b9ßäµÈT‰{,«R‹Uµ§õµ®k\EpCZe±Tª›j_w ¶ÕÅÉo{è]Š]‹¦‡vÌW+m÷gú}|½¶xÙ±r¯ËFìØ½º3ËDl☺´}ÇŸõµ˜¶›ãnþogÙ3ÊɃ)¡À¡L´ˆ÷»Bn6X Ûén2,|CcSñ¢¶" $*̯hN;ýÅü²¶xÓ±ÔÛªµä9°w:¦ÚÁ%ä3Ì ¾,~òv`Ùn»ß@´–¢ÈÁ¿ý‰‚pq,XœºãCéL >&t؈—S4åzÒâÞå˜]~iaÉ!m†²M™VeMÃS¬@f³1¬eÌ‚´Ðw`°íhkIéå1³/Ò2UÔdNg(¢"/?ÁTêûá·2:Ô%ø ¯â™‹ÞnÑðïË‚H UÔÌÏD™–8T“"€›² ¤Á¦…Í‘×t(¥µƒc _}+<¦y+ڶƒ±øúýµÀJ‰å#Æ+™^BÝÏdw6MÕc,üAjê!6r];â3's~¦Ó@C• { š®D£,ÔE*/Ô‚sY58»¯L\ïmQŽÃÎÁî4œgŒbˆÙ&ž3Œ¸ƒ¯àØ|cFÆîuºlæÌÂ7‡ñ@”½ÿ_*¿¢xZ,5’¦EH`ujDÕŠÈè1mj°ë6 ¹§|óÝ›.((b‰¡Ù]tqÃö1´þ÷ô Òv™¯,Ô$>’¦Ã`ã8qãè;ŠÞŠiA+ Z*+~Ûª2ÓDŒü®±Ö")Ê ëüAa‡/žä¿¦=™…ü»Ac¡ HäQƒ ’¥)%™©Hþ$œÄ ãaø¹‡o$Ÿôó«­Xå4¶¢‹\4Ó6][$¯5_-@Úèºüµ!Q¢X·X¬Âº²ÉWÀ&.ÿÏbØî£9”d7†’C |D¦¦d ¥ŸŠ'¸©dšåÿR)‰¼9Ž4DU)‡>¡ýâüÝÝ;}Í]ö,ˆsR¦>O²ÊæªÇ· ÷³¨}°Æni †§âÈ,˜Rî!#„&ã ˆ2b{"¶J‚$ `%³øLM€.µ~‡âÏgÆ^Bš=|¢ÙaE$['dyÔ•¾áÜP²Vâ!ƒœ­GŲAC³)a<$ÊŽä`™Ù‰_øonqýYêx³º„>Ðs4"É÷RVLHXÿ›D÷Éb*òFó¢ LŽßíÑÕ’m%0ÞRÍ€8j)©,œ­¾¡ã†Ôþù)Á…ÆŸEðŠª}‹Øo¯ƒ‘33WÁȬw¢(ŠïPIüÍì íþ õD0¾ò¾£œ¾­ÌÜâ5Ðâ͸ÅÛ1ª•ê üîh ´%j8£ò£ÚoüÞ”šk\¹Þ€]g x ­ÒHqÓ\/¥‹ùF92í ’rÌA "ÖVUQTGô j{²'×àR*ÈvÞª|~­çsÁÞÝNpDÚVbÍ'¼¯'G¢ù_/ÚÀ`Þ{Ž7˜žM5ñˉi\|Fr–Eq¿üFÑŒÍpêA;9‹U§Ñ³“xKCÔ0â£e*C%ĬÁðþh™Ý ¼Rb«:üQo0FÁñ°Ž×S$c¨­t¥ Ÿ•¢[­ÙøÙb±8C°8Aï¯ê ¨£Îʈ­üE)õ+й§! §¥²•mH>âÉ–³RHVgõ/`í¤@s¡€ðØ> endobj 166 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT4 421 0 R /TT8 290 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 167 0 obj << /Length 1813 /Filter /FlateDecode >> stream H‰”WÛŽÛF}×WT’—æfH³yç 00{}Iì5v#XO`PdK¢—""5òì³ÿÀ_‘܇=ÕÝ”(e²Ø…‘MV×­O*þ8Ÿ=™Ï#’4_Îd@>~¸DYæù™ŸPš'^ù!Í7³'×}Fe¯e|êËvöäŤU?ó=ßg™r掷ûÙñ®pÜЋÄJñ5Jç·ùëY®ä”ú^žÀH˜ÙM³?HYß%FÑïø~D._rZ<ÐÍC;8®L½\¬U_ã6ôRÑÓÕ‹ úÇ¿7ñB±­ËõÝìëá_j ‰Â‘(ÚÊqsÜ@¥öH‡­C ¤'£$ÅzþÌx#3íñd¿ß{Nè%¢‡FVõàHü·Ã1Ê@ôõøÂˆ•k­ÿù|&©¦YH¤SR˜âBX„±GmÕl9ûq>9ƒ1;iâ{™=‚cêµgÁ!å|Ëþ=ÿ\lîuIs‡ã]ûX(Zl ª«•¢¡£×z…Ó ðöÞÉ!YŒ~j³’ÒO„ÈãÄû^òß<ŒR29@y8@¾c¿æœŸ˜1ðºà›faíb ºkxŠÝб’ ·6ë–ìMï„‚ìÞ9æÓ³:?xÙ—>ãT Öb·¤~WšÅÚîÍö»õæ]?ØVÃ%Ô :z>ʵƒµdíÒ²ÛÒp»1þ>3J~¢~ôk qÜìúvuiq‰ fìéBJ&Ðûá®Ù­êö㦫vzúúí«onžýôñSÁŠ¢ZüðäDÄI=)žj½ó¿ü`^* ž!ܽ¢54Jÿð¤ Öê:\aµãsˆß—EÓàŠµªè‹ÔÛWãUMó•ökT ¡ ‰œ .©±i¬ {¥ZÈØ‡\àå-ü³ÃÝ"¬“ t+öV›öiT;¦%Œ)”ò²4!×-]ÿý­C k2‚Iv£HLa¤â^GÎ!fbŸ‘ÂÕEÍ%²p+ì ÷P¦Yk-q&'`]C]št5…ynþéËq¯ñà«1áM¢OàŽ·ºÒ·[À„F°Ü4@JtØm[U]P½€\\ÿ|usóîjþÒ™š4&$,˜l8vi; •{fôÀ¹¨Û²ÙUœÚZÕŒ–L¨rhGÁnáXöªiL˜.DÁa§è‰¦bcê [¹z‹–”![ZBs(:pm&¶NÌ%SêÒˆEa¤Íÿ–(€’b /×—··Ÿ¬û uªºQfÇWC"œV2\ \ó¶Þ×lvCÞh¹ûÊuÝ*F‡1Ó8üÏÉ)†¡Ð+×ÈMÙñv÷1à=’ëiòÿ7s}`ê2Ñç\!¶Ž˜x{ 'qÂlL³RT‹ßN NïVÍOÏ ÂsøA¼ýÛXÏ™Ò/x´ð ½8: Æ¡Ör¼¡÷’—y¿jÖhlÏÔ¶µ%paÇX ÄžlÙµ-2t|‰3L6I“¢Þt[&"`«kùÀÑ4I\tÔãŠ4Ÿ ¼$Àuñ¤\ŽñHÎ×EZÕNº°êÖ¢77èM5z‹7÷å§Uâ«Ä·Ur§QŽLÝå?‘,tgp~kÈ´0}s£tç¬êåRmU;9\ꑹºkû Zw{u¯ts¥÷o¨»ÓÏ©Ø¶î ¨àYî1ÆL>ÙddIZÄ£‘€¢ŠŠM×®4àAcGÚ íÇèfÇåˆÜÏÔè”~£;¶D=º#×GbñPÃnõy@óØ™·ÌÎÛ~ÐŒùH{$¿½î³> endobj 169 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 292 0 R /TT2 417 0 R /TT4 421 0 R /TT6 289 0 R /TT8 290 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 170 0 obj << /Length 1633 /Filter /FlateDecode >> stream H‰ìWÛrÛ6}×WlŸvB„7ñ’7ËŠ]§vš©5I[;£HHfJ‘* YQŸû™ñ?ôûÐÅ…"ãÈÎ¥M§©=#övv±‹M&“\˜Ì®þãÄ1ub'„( ©;>L–ƒG‡M i£Î8ФåàÑñ¹ ‹fàPÇ‘gÒÝN7ƒ òœY¶O²àrôøžõjòt( DMBâdžh©é½H²’³P3ú<Ç À–C³-œoKaÙnDrÅ›§>HÇá§?,;¤>©óôê!œorñ+¯ñÄ +3ËNp‚,•FÊle’çR7#\OÆZ7VÚhM6› µ|’9JV[ËÅßR\¡®Gš¼ÝÐÇÒ+ÅÿÉdàB/tNüÀ…ïÔ(†š惑ò†g¼P´Yi¦f-Zdž«s…#•$! ­ÉkÉ$4Lh¶Ö0{F€C}üÓ{Êm^çÁÀx°X/òrzRZ uɼ‚U]-$–¾ز£Gée ÿR™º/œvª»® +­ú.f.ȬE^äb«ø×l óªÁkH“¼\ÀJ)Ë*[j ò2ã+Ž?¥(¶«o+V ¨æ€óñ·N‚+Öu©¶¥wˆœU–ƒþYrãýîI$.È5¯›¼*£rÉ;Ÿç)òS^"lV­0¥#.yù¸åâQo¨¹AÉs ¡,¤ 2"ië*u¹µ vÍò‚Í ÞwØ¡{äì÷û¸3Xïø*Z_=’wd쬽_†ÄNŠhƒî^GÃØÈ¸¯x¾C£°W¼zåÒÓ öœŸà{S¾×Oøo/ž>;ù óýUÉfÐl›m™¾z{+ÿ^B1ýãÓ⓲€õ5Œÿñìß5ÕF鯲ÿz=Øg/šû¹f©äÿ‰ãvàßU:¤Zj2«ólÁß-OÑ5û”þ+yÿôd´ÿnÞ›÷G®ßÏûÁжy-¸#é7ë.¬_¾o ±wò•{K¡»Þ,ïì߯Ÿåâ.ÞébéE53©F/ÎÔã uÅÒŸÙ‚ïwÍ]þîÇ>îclRþ¯¶ÿ¢jº£ø WÛàkÜ®¶Áa8ú˜jë: V¶¶Ë•½íº¶=dEÉ D . ©–¼ímã–!bÝÚªB膪š™,‡Ÿ­ª¡“-!¶‚õRÖÙçæÒÄ„Nˈ&š¥ªùnWþ]É’À%Ùäâ *uq¸ÉT yƒ7X^rÄÛ—b;+õµ=G¶y»ÞS1K:¾‰âËÊ-d˜2°šÝ²2À§VhWçM‰“­%´eMÓí˲_9“À@… ªqÅJüá®ëš—¢å&õì>HÜЩÚ\¸¹¾´¨ÌFð“HÇhç€xç€XË9B>§µGcR®ßX2í鉼&8dpf>¤rðÉwÒ5!9×d?Xv@à7ù{j¹d<ÅŠô½e‡¸u€ñ Yý¨™L%ט<7›“oÞ*Ë5Z3ãZ4f" UNëU™­ZFžR,l3ƒ9Ð4:3·Žv_†šéz!Eï$tW® „  ãš"ŸÕ¬Þ‚nK^2Ú>ÿk! endstream endobj 171 0 obj << /Type /Page /Parent 340 0 R /Resources 172 0 R /Contents 173 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 172 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 292 0 R /TT2 417 0 R /TT4 421 0 R /TT6 289 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 173 0 obj << /Length 1979 /Filter /FlateDecode >> stream H‰ÔWÍnÛF¾ë)íeY˜k.ÿ‰4;Ü&…+EQ¥0hj%±¥H•¤¢¨Eo~ƒ¬IÚ\§"¯Ó$ÎÎЀ-‰ÑTÒt¹ÊÄ6ˆ)ù2»b2™ZJï9ǵ KƒÛøT¢„(‹8# ?Sw¬c¼³3~›>Cd§W©QÈSt ”ääÞàò e†\ÅwOAŠy¥$su•&{tÉñ1F¿;aÁà®bÈD&¿â˜2‘ v0~릑‡‹"ÏERÀœ¾’Q¾ý$1F —2M†Û 8ý„qñ`PȘ Ú>U‘‰Õ»äò øãRõ½ƒÜi!·™í5FZaKša ¹'!G=Ót6¥ÈÛ,ž­Uå À×ÚJ¼ùDd¹xs)®èî®1z3ˆÚÝm]®“šlÒ,SÎgY‘Ä5z㨠tz0CZŽçšã M¨XpSf‚C§âùZ2†ŒªK/¿¹É²û8ùs—Ó ~˜(eûr‘£,“Iä+{ js!¦ø X`O§2Û8Àëø½UŸ_qEGaC a—?}ÛÚ7-ïK§œÓÓ$‹« ù¶0Oþã6‡y¡Í5ŸÞ”½ñRïÒDlê-8WA'¹ùfŸR#WîÂkCÁÒLÀª~D91Íç}Ý.ãA¤7Lèe–}/?/ èsO”¦7C•V#í‹j›'I–B.ßÕ¢ªÙ4Ë¾è ‡ìðœ@ŸÊ¥g}—Lš? TŽ;ÁžWUÇ ÝêZ ¹s¿žß©²é©÷][kg^$™–NŸ÷M€ CÞ9Ó”ê\l†z»{ëõ™çZ/}Oß§Bßïüi®®Óxµzº«ëÏåêQ½G]•YÓw¶ð„žŸ«cLàø«Îægÿì:¶¦ó”Údˆâ À‚¹^®Š²îá1Ht¾BÒ{ãç~ºxMèj}ŸAÌ¥Ó:þr->ïæÑ“̦¢:$@Ç·ÛWeY”Ç šP}Œé (^3÷:Y ÆÀõu½ÒNêÓiqèŒ8Á4¾xy6iêïVÃ;ËýãT¢bu*ü'ÐúÙ^‰i »8=îjuìSZÀ=…Opä´È›ò„È€>·;æeBãK䤫,žW*“° 1Ʀk³(ôxÿmâ7Ø>žøú³¤›úòý#õßÍø ¦|?=nt8´0ÊäÆN£0èT ÿÔSÚљʉ µ´:3Õ°+{ý”œ“T­ n§ÈŽA¶ë»¦1¤?&Do¡k eïŠÝ.rD¡²¹[híEVlp4òeŠ7‹B·azÆrTß«†—\KèL1Ol×›Ž[1¹Ò÷ÝÌ—/´¹j½Õ—Ýhr§7Ë>V½dç=-r¥ûÚÀ–_ά7u¨#ÂáôI¦ãA?n?ÒiöëGµÃ’éQÇÑÜÔÛ9õÇþAÞæž®¿Öª6gÇ Ý<.E½(¦j½*‹º¨·+ý&ÀTM~Õ0Ñys@·/dgÕamö¹H©×»týñí›»+˜öª‰û,€®©ÛèAú¼Ï„ÿÕÁ¨)û©Í{ ‡ü,ƒ·'ÇÕe¹€ÙV-ê]<ã²ZÀì¤RNæÑ djÖ zº›}÷‚¸Ež×døÿ&(úhœ] häÈa"“º–3ì³w1|´ßxTo÷èÖ§ «Óùp쵨/5ó\%€œuS¤˜Cà‡D5]í‚É#XÜëˆìWÌúêæ…6?H?Ÿœf œB€Úýì¨Õ-1ô(¯^Ccv¼ý0¤Îöa[›úÕn]NT¡é=LafÄ Òía:ýyø”Úƒ«e¸nJ´.¯ÏнþUd¶ endstream endobj 174 0 obj << /Type /Page /Parent 340 0 R /Resources 175 0 R /Contents 176 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 175 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 417 0 R /TT4 421 0 R /TT6 289 0 R /TT8 290 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 176 0 obj << /Length 2951 /Filter /FlateDecode >> stream H‰ŒWÛnÛÊ}×WÌãh’¢D*h Äqšäœcç VŒ ÇE0"ÇÒœðV^¬¨Ïù‚ã¯è?ö¡kÏ EZrƒÆ@ÄËpϾ¬½öšËõäb½™ÏÖ?`þðƱëÅÞ’E«¥ÄÞœ­óÉÅ›&fI£×x¬IŠÉÅ»[Ÿm›‰çz­I&³þr?ùÿ*œÙÜ ùVÒoÀÙ›Gøa¸™Œ<ŠY-'“K]ÀV#6ÕˆyŠæðÙ&j(ÂlÈ>\gý;ÙXZ&O¿döµï¹sü³ ÈÄb(`d¢}³ÅV²÷ªiK¤p±@’: ?tQ퟾ê]\8ƒ‹}Þà—☻\öYþ‘c³Á³1²Œc kT‘HvKÕõ\Ÿ_9³(BîÞV€ÓñùªÍ}ª}À]ØqÄKÈ?‚â,Cí¼²cQùײfI×8 ìÔ:ö)sBÍ14,¹HªŠ!é¿‹G‡Ê«éY~P™l\¶ÆjCrý “ÅVÒ‰89¸¯UÛÊ‚ÝȾð±ÅÚ/ãZ0jö´Ü{Q£‘aE—odMñÐë‚khèû³µ³»\\aŸ!ºkýó‰:cÉo×yÉÙÍG{h'šRvÏ™ü–HéÁ¡ù€Ô‚¬í¾îÞ¥îËÐt¯~—Jó¢=|^ÀÖ¦SYjCÓ‹¦hn®xâÌÙ1óBšÛÊÞ™ÐäÍ‹]qÞ äX¦¡)Ó²TmÏuƒÅ‚ŠA¯)…C¦Ù½ãžÃ:À–ûAÀŸ*9mz¦=\v°?Lpßòl_•©ö@ù¤–}ÔˆÑKSC¹·Oàœ(Ð|ŽòäÔ‚ð óÒÐURöŸë<<˜T…˜g‡)Û2mb‰®`e–âc‹j¸>@fÔµ¦÷Yâ,‰E(/вif½ ¦²ÙC¥"Ò™÷Ëk‘ˉÍ0øbœ¢Ô=…Gòž)´×CW$šwé}.g§Õåñäjwe ®z_î%¡«iVš›#éaˆMÙµ ƒæXñ{ ¿}e˜–ȶ$¹ÁÛžøY¿ÜOçä“X¾¸`I¦Ñþ~Ì-S&Ý­Ëî0¹\‡4“I ƒBuíØ_ê$ †ì=Œf"ê…)uÌÏúîÂÕ+׊Ùë4U”TêβË‘„CÇX 7Ñ>`Ñ{®óûu™v™üòFTB#Yé8´(õ¹Yû„4€W²–«Bå]sÿìT |ØŒøä<&¾Ü94šÍl÷{s5UUtgEø_p(s`.ä­Jô/‚f[•†UúEáx`³ºØNz˜ÚŦë!—!¤ž÷<¸i,­ŽRÛÀ‚+Í0ö“¸ÿÄ FBÒØ>1ëÝŒìúG»GZÓ€ZSi×–%õµžÃðÌ…)©¡¶™»qÚ€>4=—ü+FAdFAà­"Ta}O'‚O†Ð*ˆç½5çr…gA‘èý’¯wzªabKÿ™-ØIQbœ&~М6ß³¦«ª’NPäÒÖ]B*‘D‰št(ÀÇ3~?ËC¡«ÈD˾›x1¾¤Q)#nbîîž0‡¨¾së&ó“ì”M[†Ñ·56´@—ßJ0( Q“_†¢U]û"WŠÂ¬Ë!BŠ犲Ì$†»ÈԶЧ¡ª.¡˜1 iõƒú&S÷´e€ÿ™Æé›ëJfÝ—Y¹9•:Q4*ä¹ì"<ÄÇ èèÞG<Î$©‘“?çÄ* ˜hrøò——F^ÙP-dG.kž7¹!0+[n¡g¤íJBš´øòšî—œŽyèr¡¤ÕQ>=ÃØbâ9;¢ëçºþf›%Eá´?œä:¯5¿¦ŠK2D¯8+ªªË­:–\y>ûüñÉ 1Ñ‘Êç&(¢¸VægÇ«E4"O]¢È ¯t¨˜óö(j%€•¦WÆMR«Jf[ù­¥’áTxÐ@" xí~#0Àáÿ¥1ž.ñ£ò*3Š‚Ð«ÓAÍ\Õ jPþ‚D?Ã06 Æ€øPh]EÐÑ…´Óµ¨ôÓ¤W|ûPj<œ¦oé†cqJHæÂ)78Ú"4+tZÔŒq?µê×0Å–6z² îFÑùh¯É‚x„×§*­¼6„R}pZÜCæO§iÐn>ÏÂ|” ˜¬è€#~:kçTµ!ÈQ”C˜qÑ!msÔëZµ°Ç´:ŸWZÅÑd!£†Ë)1O œ„*Ì;,Á3Ž1à$ª`qœ³Á±±_†=ΖmÌ@ÉE{þåjÔ̧€ä®Ë>´¦77Z®Í¨1'ªÿœì‰ô3×T0=¯š6½mGb#ä–*J fÁ­5UµU¤³äÑåò¸êãµ6ûš]Ý2¬s‡I~‚}Ñ·=w àû¨!$£9î:D~EŽãîoæ ¹¼ÌÀÆæÁñ„÷€ïn¾.s:zxîL5µíwÖ®dßožÌ£Þ€Q(¢5J‡`h›Ž³±ôüñ×åTf¹aqk|J9ÇÆè3÷óùÆà€~"e¬7ì¿WÁn‚@¼û׋‘·%išÔP{o¹Zׄ°¡Øñ‹;ïí“]*UO ºÀ¾Ý™73‡°ª}-sÉ o'ú±§Ï¾ï*·WÄ40mê­+Ú.+ºâÕÛ¡ š¹ˆgüáß_â”ò <ÍÛ«‹v“©ÈÄŒ“Ëɤ§á<]¦{p£uoÒr¾ØÚæ‘Ï8á#J•Ìþh|â½8£¿îô,’9 žd‚$Hÿb|ec|›~[G—|ÕK<»Z:ÌÍ‹íÀ­²U^ÖŽzgržêk–E›{bLje¡8ŠÄ Æ¥µð §Êé–ÿ½e|—ñÛ1¡¬!mHòãÏ ÁKÉMY!ÁÃG|¯ú_Ÿƒr7ëCU ±÷æØ#¶¯Tz—.©ÆÌu›])> endobj 178 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 292 0 R /TT2 417 0 R /TT4 421 0 R /TT6 289 0 R /TT8 290 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 179 0 obj << /Length 2191 /Filter /FlateDecode >> stream H‰”WÛnãº}÷Wð‘*bî—tN€ÄÉÉÉÜ0hœÁ “ÂP,ÚVG‘\IŽã>û š¯è?ö¡k“”%+9=è SEnî½ÖÚKÓÑ»éÔc6›.F¶Ã,üÇE¦Y ãÀt"ËeÓÇÑ»I±y-çX¬ž£w×·6[Ö#Ë´,š3ÛávôƒMŒ±kz|)è×áÌõ¿M?Œb¹@ÌBËŒlâFú¥Gõ¾ÒR4 ÔBÿfŽeylL?1{رÛ]Ñc;4c¾u†¡k†¼fç×'ì¯ÿ1Æéò*›¯NØí6kþ)*Ìð197°Ç“"5Æ1XRF$-䨦í!®§—*;’ѨH¶Û­i¸fÀk¬HKí ‹f…3Ú¯³öš6_Éõ¯¦#›elä6Òi37ÄÃ…ë0Š(b•-FÓ^ Úì„^ˆi*=]êežÃ.塊ïòÂð±ùõìë§»kc!7†‡Ü|Aœ!Ÿ}ÿþýÔ;e!¸sVËÙÝ1#¾N*Lu8U7‚-òd©gìÔ uÑf‰Gvϑܳ9U=¼7äS¶(Õb ™aë|³Ì –Š‡Í’ååÒˆLŸ/‘(üdÅR¦È¶M$·pt¤þw µJjö DÁ²¢©Êt3©É.²†P‰ª¢ˆI%°Ñ"+DÊ Û¢Z#¹µ¨ž0Uî4Ö[!NŸ¶BÖ®.î®gWÏe“Í‘û,¿RÖnX ä'i°*¶.l@HQ°qc‰”£%g“$Ïéß{T‹MÛÕÓétq{P›†tPyšÁ&c;2C™"Wo4k7`àh¯ÈŒmµ@©ž´ :8¡ÛeB¥Ú¦uð[Q×YYÌ>cµ/QÁ6½0¤¡;ƒÝËÖÅ@>ônò”°²Èw÷Æ)±Ã±øW°÷+õøQ4B Ùþ¶Q#àà ôÌmúŠªóUR(duI ²ÿvþƒx?ë­ öÍ ¬ű\7¤uOèm¨ÜJ¬nÔãd)X¹0 IÉ9['ê™ú»%N¸\â<ä){,S¡ž˜mž­«ž õ’´–£–Ù~蛑×2ûPLhƒ.S ß7ƒ •$Îô3½¶eºø×“+ÒL%žØI–a‚T-EÍ꬘ vKRHç¹4Æa~Ý¥JAµù7’F›Û$•.7]ÓÀðµDù.rÜä!-™?1ŸPº@§<Hæ?HBZ₎÷A¥#¹¶G6EÂ]ô6W t‚Ÿl±)æ À[K9(PÚMM€z߬²zrqÆÀj[Æàò8ràùÐZy"Z=zÝ“dê†jÐë–òØäaܑ∕P|j6UDAmøXÉ‘±OozËëH¥«Ip‹I£Ô¬%aŽjʦ €ÍWRìÑŠè‚©ŸRÞËŸ„¾›°µz³|È¡åRÉ7êeêC$~¢%K#&åW³Ì,H½:)‘Åó{0¸zNeGXçâT½ú«­ÅPûÇv(é(Cä\‡¥Ôh½yȳ9:»eñ"i²'¡ÆOe–ªÑ%u—Ë‹{®.3r4P%?QÐ’9N¦Ïzʽñç?Ä8Ùé×VîÿŒz"»¨”nr±_'Yž5ÈÓ1ÊÑõú¢ïw(÷UŽ×6ŒøžšcÈÏ/?ß|™Ý‹òÊsh›Ö@½Ã³TTÐ> û„e KÒTÝ—2†‡E“-2Àƒ‚pÉoCëµ^ï±TÎɪ/éÛ Éã{ˆÎöJ}ÆXҨΚ>fÅ¿¤$ï'Jr¥“€ƒh ›ü‚˜”E#ž›—!V†-XQÌéÁå×,o„²•A>aBL))-ì–|äóg2]¸Ñ 2 öZ“’£CsÓ™öãÖ"{dÃ:Ö›õº$é xE].“ò§9ÿü‰‰íO«a·—Ù“¨¨7²³_Ø7t~†&â×òb,C8¢C…b"5 ’åð9%·r‘‚ùŠw`kN )ZÈ üŽTÙçköÚ‚ ·¸^ïЯ͡Öȟߤfø\ὂikez~ Kg,«¥¦Ê”Q²NàŽ«›j3‡¬)ÿ5&$+;W7Tw^d¤Õ«}tÏÒ‡d ü.ÌÕ‹©V9F‹|ÕéVqÔñînØù:;E‹Àó¦WSÿÿ®©G5ù«Þwp©"YF«ŽÛÏó!ÅGæþA»“rL±âPP2Q-ôîC[“üÔŠ@î$VÌ‹¹²/.?x]4• ßpÕ—I“ÔMYµ|Þ<1ÖóHVdy’¼×U÷zÃÿ†Ý‘œ¸GåóÚ ñQì@ƒÚ÷Ò`Ç?´ ~a+Cò;!jEüI@Q|²˜HÉªæ¨æ ùÉÏ“ôtêõ-Ü´¶þ2Gx´{¼ÔÄ|ŸÚòK'À—B?£PèSOS³Hsj“™¬EÔÎLR˜FUå`߃Îz'àÇ‹RÒÏL¦nª7˜úÙÔˆ[ i í5@Ýëîñ;'|HevùÖUé~ˆõ7Eú¨§c)4'NòÝÄõÕYÁ^£ ƒŠ#”¾0¿ao½8ˆQÓ Ið¸6+t¦BlY$myÛæÔPyeg r,Ú±=>†h…™Aµ›LbÌêï„é&Ù&å’—âÅÔ6J:|rNòûÔ*;àtn†ãè£ „;’O™0.þ±Éž’MùX ÚQ¶s[­j÷[—RX³[ÃÆ/¤¢Å×p6äÚ-ÞIo¢å·PÎàTu 8Î 8P§Ÿz#:s(Ùùy*Ä'ÜP÷MÒ#æQË¥$½e,SÎ ›ëû~ÀÓ¡ÛÑ_«³Iûp” ôÌžˆ¼!T/ÁTxÔÕç{ ç¤H5½âèÍ*í‡EòüUînd\€ô°Faü?ÜD/ª»’ì[WÓÑ¿FÆ: endstream endobj 180 0 obj << /Type /Page /Parent 340 0 R /Resources 181 0 R /Contents 182 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 181 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 417 0 R /TT4 421 0 R /TT6 289 0 R /TT8 290 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 182 0 obj << /Length 2241 /Filter /FlateDecode >> stream H‰ÌWÛnÛH}×W°/Í‹aó®ûGIà{Œ•`ãA“m‰‰H*ŠæÙ_°ùŠùÇyØSÝM]hO²‹}ØMó¢îbÕ©S§ªÏg£g³YH’f÷#铇ÿ¸„iêz©S2‰]?õš­FÏ^¶)å­^ãQ›W£go®%ÍÛ‘çz¯ÉGãþv;ú ÞeÎ8pC1W|õ±óëìo£‰60¡Äs'1>¤vÓÊì÷6Åw±1ô;ùžÒ˜/ºÛÑõ®êœ±L܉X¨¶Ämà&¢¥oÎèï8ãØ DSæ‹3ºÞ–ÝoªÁŠ‹—>Ь*œñ70©=Òaë|éÊ0Nð<›odª½1žl·[× ÜX´°È¦vŽÄߪ[ Fé‹¶ì0Ëò…¶ÿj6’TÒÈ%à”$¸ŸØ£”5ºëlø6¡‹˜µgú®G+‰"7 \‡Txì¤HÜÀ™ýƒÄÖˆÇ}4‚ìoöžàßQ¤ ·ÁŸÓá¾\dÕ\µÔ–U®èšQôÈ©3N7? ¯F )~fT¥Œr \¸­£Šaûhü 3ÍDÃ_N4J¬¡QÜeëòÆÁ‡#/qS¸ ‘qu·™OÏ ù¤)h(Ï–Ë»ÌIDîŒ},ûˆ7xZ.[ÜT´¬çTÕ[êjÂrr¤'T5/+õÏ–ÓÞJé"CcðÀgd´'“ƒSãÔ}¹TT”Ê»åî9=´N„tïì¥Êo ãû øy›; sÏ8ôR77×/€˜Qii5Õ÷ÚÍëéìµk©Šý~´w-:¸×>\e [ñÅÂñð©lùÂ<Þˆ÷Õ*«²¹*fúÅùkå^¾ûåºknœ_i[.—t§hcv¨BÃu_7`ûïš`ÿýðð}KÞ*E‡MP„ÕœcÉVªSùÙ,+»HeGyÉ%›ŠwŽ=Ú•39¼º$“#ãÜ*ûèLص#o‰’o¤ñ†Íäuõ _/ëŠî›zõ é?{ .!c‡ó“RYÁÁ Qîܧâ”ñÞ²´ª4sXf:NE•NN‹`F«¢ÍÚ[mZÇkh HP4Å_Ö `ðž/\;È?SúÁ¼ÚÙ‹!*ºßcHÅF´E_“Š—Œ 0(s̘•\hÄAgÌ©çbG‰w ê¾½qhµi;.tOh~¨Âà4¶õrLJyHƒ”GE¼)³õÚ±dì™…©F0‚ï/ =¸†‘euÑê5´È>! ŽŸõÚ3 Æ¢^q1ê[T$M/õoæ¯6hÍtõ ÆDNÔIÏ+SG‘XÀ>X¨¥šïØà=}‰‹:èŸÍg"aõ 2zéÔéØoŸ\n4 2Z ˆN4àI²K_ì…:ÿT^B¹oeœÛÒ¾UDñq3ÐÖÅ˺ª€è+]×vG¯æÛö¾"EWÌK¤´íëýáÄì8Íj™ŠíÓœ2Lò{Úò[¿¨ZTBˆ>Ðt\Í>T‡;}»â6%uÃ:§wËÍÜŒ#L-d bùãeè½æ¦Û4e|ÒLÏo§öÞÕ[® {û~°Ví»4÷½õÒ/j ž[s¿à➈2·€düg|”‡yJÚyŠÕC @2×SDÈ Ø….^«“Ù]½é  Ðl³LyÈ´|@IH}.ySÇê\vjEÛEÉLßDç@Ái³wJUO’ïq¹lÖEÖ™ŽáÒÌ|…ÄÇøãÒøе˜y]ÜïY¯ýÉæÒf±GM«5uM–y†ê¼9óýjt¿l‰]Ö\¨7B•zD`»ÀªÕ?¬!=ü\©Ïµªå.qã¸ýà’ö³’'2*££¹ðÇ·36÷ŠêsL=…*ë¸Lfìë½Ê@@…ê7*ÛnÖëºa@ïk=Sú¢ƒ :ÕUߦx® âü˜cÅ×NE0¡óñ\äð—™l%JÄsôáÐãO½gªFbÍ9`q4ÊþñÄf¦°üãÏŠù ÝyÿJ“.©LŽq‘{\´ß‚ ž?öPœ¤®k6¹Æ ­©µCaùE?´lsUÙ±'Y}Öí”Û3l¸‹/î©>¥ž–cÚÒë£Bù›º¬ëÅôTcwòuYÌa±àýèp“åÑaSåÚ9Ô.:Ê =BF\1t‰hÔz™!q¨¨ŒP&%kvt1%ðÝNŒŠ‡-íQv`Á»ˆ‘¢9m!¸†Š3¼Ù;Èst£X+Ÿœ“ËÖ¥–­·zÎzùê§Ÿn¹XbÁÝ>€ †zð ð÷ŒJ#qHz‡‚TE?d|#1GmmŠÝ)ž¯U7L‹÷´ /Qàs^^@œ`i¥ªÎLÂ{`ƒs•Û' ÎÎΦ‘éW€iUB ta6ï1l”Ñ}Ô\üM]e¨­6^¾ÝÈϼ«wgÇêo…•¿Œ Ÿð†ãèé1à'ðlÄîé9ñÏ¢~ÂýAÔ?Ãÿ£ãgôo?ý>{Ãã§õ7ËúƒJ‡Î]D €òa(† âÉØ¤ÏC'[OH¹áW9ø½¹C!jÙo0t/»’Vu±Yîe8¿=*Š@æ%Ã$¯ oٗ⎹#üy||RŸ³ÕzÉt–)9/LÃ(²ug]< •ç<Ó•´ÝÿQSöŸ´ï?R>j@‰ÿÕôôɱþ—ýçɳԞ#RZ޼ÍUVㄇßF=»†‹N*~Y`rr‘ï‹—<“úâûïÉæ»‰*˜Í¾;´íÇLEÆGD ¡ÙZ¥S¦HÝÚBq1½ý76FB)rðƒ¡­Y:-ØÞ´%Ž ÷-÷(PM»»q4ÌǬÅQ£|™´zŠâ¹Ò¼==dn~¥{½Ö­éxèF9žŒÕ`‚Xêq¹¶ Œõ˜Oc¹V0Z˜q-¦Ìæñ+°é¯ÇlÐ4%ØÍW³Ñ¿^Ís@ endstream endobj 183 0 obj << /Type /Page /Parent 340 0 R /Resources 184 0 R /Contents 185 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 184 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 291 0 R /TT2 417 0 R /TT4 421 0 R /TT6 289 0 R /TT14 297 0 R /TT16 298 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 185 0 obj << /Length 4410 /Filter /FlateDecode >> stream H‰ÜWÛrÛF­}åWàqF%˜ûÌ£E%.m­«¤äa-EA‘TÔ-´ÿ˜‡t÷ @€okIÆ®08Ó—Ó§Oœ^žêLd§!³þÃE{Ÿ¾°™ 6—¾PÙélðjTùlRÑ7EVMæƒWoNDvY м(ð›É`XßÞÞ³wc>T¹f—%^%Ë”ãÿ9ýç Ð!sE,¢|úÑ,þ^:Ü ïlÜè¿™, ñ²³Çìäq¾âCáòÀ®Êj ·*w¬Ê^¿ÙÏþýÚ\±åtrµŸÜOW¿—KøÂÀÇ×Ðlç*·¬‚q«G.àï|u> ɪiý"~6¹¢ý¿;ˆlš ¤N€K %3´ÈgËrp18 lÈ” ³á›896§@­“0\GŸùœŸþŠ{Ø´Gô£ —Yz—ö/rÿÒ¸…]'ÐGo¸ðàËk>„¸XvÃÁ6ÍŽæ«ryÁCîÙxRfçe5áÞC˜%äyz³š.æä¸Ð9$Žü »ÚëÞ$Wêø‚ýbËÜÚ:Ÿr`¸ö€îttàûÛù„lñˆlqW.輦(£sÁîÉÂWß§í‰7¡<*:†þcÓLH¡q~ËLQ—U®tÐë@kû¼g§`•c'Áúø-–ËÅ2Z?O{ë\JúYPäÒ´)BÜÿGpÊ|ˆîžß^—FËr¼*G HàÇòYmà…o™‘•ýÂ:§šP´¾Ú cG#:гt†ìžæÈ´2gšÌùTòÙÞ ÷‘X×XëlÅÌ€ÙÇK÷ùÐó¬9#™g mÚ·àíZetÀ¤Àã\ U‘œá}Œ2*VuY!DºBÀ)ow pª 8§Ö€SìΨ̱§ß^ƇÓyzš×:y" ¿(„¯©R©5UBæt„µ²u…ö«4½F2ëçÝ.YD oˆ ýN¥8uÉÐYÄ­XÆÐS·œ§V9Z–©®¢Î¦lË”m•²mû³ýkM_¬ ¯JG$[©ì1ë؈Xz† ¦¯+z%ºQkµÅQêÜWµjø|w”M£1õxV•±fªŠlÂ$àh3?Æ>ˆýkÆuÄ%~µ¬d»ÖÚ¼Ð^®ù|¦®=¨Û{Eó%îÝ© ó%¥¤Aߪ‘¬8ÒD¬Ÿjij×çµjç jåuÄ¥$&IÎtzã†~F|´H¬ÐkêÒ×EÖ‚“ExÍÁ¡žxYsáÉOˆJ‚eM”Äþ1«h#’0 ^hŸ’-a߸­BDöTŽÚŠ¥Þžr4N9Wé¶w¼i Ð¯Ïö*âq ¡Í)jÝÖc“>Äí]—¡þ ­5ðÔö·ì)À’'´_xÑQ%èD (,mì4¶¦uFÁVèeqL®Õ_Å•LÂfÛlnÖ@ÜP£kŸÆŠJ®Ó¬)qš"½-Ø[ÄI$—Éøúç1(aAïBÅl“¬l“ìíÒ6r BRTàî–qPfZéÏìQäüóH¬‰Hç«)Ñw`«tšž/ãÇ]E§cKÛ-*£Œ‹n¯¨Û;b2L 2^GWå$Eä·Ãò.>œNÊnk—Ðj^¬µ?/=}˸KN…Ú²¦®Ç<cwtØù"XÝé4íŠô¬6‰ ß_˜6„/$ …!òã‰^Á~HÔRSÎczÞC'À9J¹§¥“Ìk{ó8^Í'‘«ÓäÕ)IK8ß­‚ŒA³mmõ˜t…¥jxÒ›8bvŒºM±ú=ÇE·*]:ëåÆ+ú©i°ošªD*E…éÑ`-vØÜJ‚–aqÉqxné@ êj -õ«€žmàuRvg;×4ÏÖÙ`{BW.¾LÒ­†Œãõ.^H£jv\Õ4¡Ôß„öŸlžëèÒ/¤. w@x»°O“^#¸l—à‚T¦õÔ¹€²;š_DŠ[l[¢"þ&hûV‘¡¢OQYD]AHÕ µv`Ð씡°¿6¶D[ªlÅ9ˆ/L5GП±9ÎF…¤:v)x9qè4»…ùÂɯUZ Â7' U” šL£ðûOQŸ-¤~bê¶ ¥¢±MQÈP=C£uÚ} .eÓT‘U`Ò­(2éS[Åë; Àtપî)³¤Þ|.ñççİ!p2¦_Â|ZôÁÉPØðbd=v58Œ«;"CÀTKTˆƒ‡U'ÇP¤ÖJš¬òv—Ú›Ð䉂d¢ M‰ÆëÛ´¾Œ—)æ#³u¾í£ò¡-ÝÛ V$ßçx°x5‚˜DlÇqµã…`}äÓˆ¿aÝ"[í M«gÖ$Ÿd¿|ÒÚvêŠPÖŒ?U©È–qðS‡Ø ¤”¥/ö16¦k®Ée¡ÛLWøm®ôµ¹PqWéI/eÚZé†È]-ö*(zŠ "©!Ð÷œšÕ‚¸B¢?©Ìi¹¿mõPÁq^PϦ8=Ó /’ÙJ­Í+1¢?ÑÀ‰8G/ˆ£$Î?¤çk%Á­G^tÉÜRõì–Š¥ÖçS•Ó–%G yƒÄ`-;"å‚À‡ï?Ðý[dmЗ‹[zÚ)AжÁû¿OË"•ÎgˆÚE›¿¨m7ƒkuñþOî«`¹mˆÞû>‚'#$HS©žÑ4NfœæÔC‡6ÙV)ei$Ù•ÿ¾ûvAŠhcKjÕ‹a ´À¾}ûžzC4éPò$(XCÈtúÙ†ÛvZ钾ߒaÉÇ• #Cs¿´!’ÏàèLÝÈ—ßBYH§z…³}Gó1“F‚™A“=ˆ'âΡå–L®Ä(±¦J(‘2½À9:ã;Öì¬øyé§gçÓŠ³ƒ(³ž‹ð†‹œJZCô¡‚ è u}ThÛöæ¥4dË÷ÃpÐðSäÔŸ‹ªwåKSffÌe Þ7Lúüý2VŸfÊ+~â<¦ Mâ¶m“FnÚvN1çðywà À¦âθ–I¨³)µÎ½‰œ÷DþÖm˜7aæM¯ið¯ÅQ±à·QgÄÀnÎÇ2®*Q_ÓÈÀ¦,w/—ü‡³¯Îÿ9÷qk²ÙMk5›Õbßg±íž¤iüÓ˜¼¢®/'U]âdÔôú~x£žxtKëÍçÐű"ýÑ«ð¶îA·O'{ ŽFB)ÿ·“ß'·c¾^ÃòŽ3€Ùz–ÒõÖ¶²%èš®<À_Î;GŒ£ª®VÂt`ÃfEóxÀ.¥âø·ìEHRäš4•uq›ìDòÚU(Cê6«j8cŠcõÈB{Ì.ò¤à/¼z±4c›¢¡¨XsÌ4Ø´üëçÜL{Ýa–æÝ¢wÛ„!jlÎÝêe¬‘·¬Ñ`«qŠ~ÁxÇâüTø0§´PE.%¤4R¿™í4¡¤k_G˜èGõ›!ÏŠšÛŽüÛjUÜþÆè:˜°-ë§Ý¸vOø Ï—µÄ¶íùôéz»§{ì^˜‚6B¬¯Í‘¸«"ÈÊŸ›éㅴn7}Ám7"Ϙíl[ï׿šÀ¾.ø>oBrê1¤Äƒ1õÔýÒç®~U÷cð,~Þ¯V™ÝÓ˜no}õ74;“âB/˜œÿùr?‡ gÇ‚‹òÈ59»cJÐM’qŹh2'†2t-Sv™½&µû¢…N+åkHÚÈ@ ãŽj5%ÈÈ!fê¿bÔ=?¬«eØÜ!”Åá¡å÷¾$²†>®Y$ÿ-S'Û'¢3:íQá¤[8éœÀ«Bæ “¹G•aTñ42O¡*K’ýñÒÆWò-o_Ò•V‹kl|`IêÈ( N$¦„hJ6h²™;!=ãpÛ-Ù¯X‘çŽ܈ß«"ô]TIú¨(ëÓ£E#E»´"\µ–Éó¤µ/x™Ö„ Zö1‘¼-ê‹×ÌFX2˜ëȉî£Ôç’dªÎUÕFʪ_2j‰;ñR;­t‰{¢‹;%ÀŽ›èÎ# ΄Ì#¬—,F$ÒäŽ!8*¼¤]AE:†ùiùFÞ?ó¶‘vNUñP}ˆ ÖKQkS\JB…(‘׌xAo92'ý4tõVDïrÚäe®"mY¾QÅEÉ-(Ìó}æ,%R¾O¾ÍãÓÝ/Ç;¹ï67³Y½{"ý=2*^WT aÇоŸCè#Üø?Wüv>æœ[;?K*>2|zHjÈ$ÅšACšíßóvè:½«"ÒDH‘Í#c)×£ÝXìŽêÔYæƒ1:óÁLÇäÁ»#܇L”Ü ¢!OIÖs'Å>œ—åùI}² BB©G‡åɾ Ó¡y{ˆõÊv|Ǥ«e%fi!!êãŠ3À}!§Ð+Ï+n=(v;™8mé{4d÷JÜÜŧ-í¡õuî›OY4˜J;–òz%òïYþ­ÁAÝn4/EÖ ï ‹ºåõÜš{eÀ¶ÅÜaÚìÁeQÀÏ!Ë%ħ…,΃Ö¨ª«UuÅ”@–†9Ñ´¡«CÝû|¤}ôä2—·Ëf-zLƒϨ!í DY´ae ¢ä¨ôdmþ=ôd žß"‚è]Gž=€¼ ´"Ø äIOßßhîŽu#ˆL–󙘵%Wcõùæ[˜©<ÑÙ±EÙJ¯\o@‘)8MJ>ŸG´Z q²u4˜®ýü ªÕÙC³|"ÏK?=óãù´ùr Írjõ†”“zŒt+n~úå‡×1] endstream endobj 186 0 obj << /Type /Page /Parent 340 0 R /Resources 187 0 R /Contents 188 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 187 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 291 0 R /TT2 417 0 R /TT4 421 0 R /TT6 289 0 R /TT14 297 0 R /TT16 298 0 R /TT18 299 0 R /TT20 300 0 R /TT22 301 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 188 0 obj << /Length 4672 /Filter /FlateDecode >> stream H‰ìWÛrÛ8­}ÕWðtY q+™Ò&3•е;U;³ŠÄØÚÈ’J’c;´ÿ¸ÛÝi˜d_bϨvËU&!’  qÎéÓ/ǽã±Êx6þØã"+à.ʹAá “YoÂ2Ÿ÷^o]6ÝÒ;E¶.{/~:áÙé¶W Šß™öúÕíeï7ön’÷å@±Ó¯‚eÒåÿÿµç)€Ïl1ð&‘.~t¾Cá þ‰¢PY/>ûp\/wyŸÛggåv·r`Ù6;úé0ûÇò¾H¶™Oϳ“ËùîK¹74¼¼ÈaÅ&ËYÞ÷p!iE´mڒ஌…ñxVí&¬äòòrËa[ˆˆ¡®sÿ—»3Ø#l;¯„צgÿոdzyÖ†C:y&-\2H‘áŠ\¶){{/á4^‹prò„7Uª,~cB®nΡÀ²¿äãáišÂjëÂFXŸñø¢(¯’] ñû¼¢m@F5¤pFƒ"ü8âD ixòqaÃ×ã³M9Áì[6û9ï‹nâø:\Ž!"$ç,þº< ×ò—U¸¹¬çªZ ¤·&™ÌÓf³ßYµ%Uí¶+Ëtn",êøb«ƒC*¯rH<Û5'Q. }ó©ð Î=›Ó§«eîG‰®tÈ¿ç!`ut}ϤwìÕ£)l ¢?æœð[?þ5W°êM. áóìrH3+ßÒ¦V§CØ–g“ݤ™(¤X~ý(|¡þˆ£8l%A_xº“Ðyz´Îûn Ù¾Öìøl²y×\‘p)’q^­ˆû¸¢m˳SXgÜ4Ï„ÖÅaÓF, ƒ‘Îü0ÄW…¯‡óíš¶ ÙhY c[;Ï9Ì Ø:;)íà(áéFx¤sv•Êa%·ÎD˜%ê%ø)¡Ä0 ˆÊs†pܲ,V&qS¬|ȱܬV‹–D œ’évj€ˆ “Åâõ¼\Ìp{žm»&…Š\c“ÒoÙz}Œz‰_Þuíä± g[¢ø! ŸÎ±ôö1Ç8Pl:¢üx~ùQmE. ðЦÚh%QŠxÃÄ–äXº¯_Ñ`³YmÚ'/„óu¢¦í ІF¹ÿhi€r´¦Ën§©B€˜œ·ç1VÙ{c™ Wa9‡|r¶‚ Þå\á¬9jM™CQó€D(îØV5¶MŠm Øâû¸”! ˆåõ1!㌓¼è€—(ãý©ž‰öÈuì¢/ý °B"¹6¦‰ °;8Њ å–½E¤NÐ~[6,þ>Ù øéÓØ‰ïª|QåcIe@0Yí·±61pZ«oJÑd4‹2„F\/,ÒbŨܴ­¼f-ßCáQÑcdC о٠s…Îê=\Êɬm°”ãþþ%ôKñºqã‰ÅBYâ ùçC–9*åU|[pê60uZÞ<Â[~§šQ -* ¹Jn¸AXÇÙv†cj7 Ç¼p?z¹µ[u•ªlˆ=‚ÑzÛ^œÇ»1i‰+ö´bÍ[¶H A $—{H‚"–Ã÷%96-Í/Áß òwXû’|fõs«ƒî(þ¼´°7´°-Ð:Ihb}¤–tMµÄ©ƒNj€4&8‘i5F{‚ZRI4h¯‘t#ª'Ãæ:e³AjX_ÙáaóX€¹FóU?))®V÷Úä6ÔwZ~´”‚,¥fC½®ª£ gHÛ´0nG‘ÍË]`³D2»®Òcœ±]6EÔš†å É µ1¢aA`$°]ЪAXàŠÂrØ\r_BÍòZ4Kðƒz.ë,Ö {=‡"­È_ˆ¶—¡]Ü?)à:‘Ìì š0¤»L䥦c€®Ð£‘ ¨G„l:±A|S^7×¾Èõ¬ñ]ç7åAS>ú<šÔ'T‡N{ú¤°`áxx¾$ÌY٢ɷý`ÒxBýÖìM¡®ÉR1Pw(Ý·òµ-éCÔfJœ oK4ÈÀß[^šÂ©‰Ú9F¬Oqˆº'q±=Ä :¼…8³Üî½~„*vÊlEûh“¿â¾ánMq¦>aº&è–Ñâ]k»_û;b“ªÙdRÂC‹Eªžy÷~ Ÿ”ÿçåö÷[O ¾ñ> TOï“ k£6aÃHÊ@½Ô×óíÒ£[_Œ/ÄQ ÓXqÊý5w·j Zgoy"’ªjTÓTWM³ƒ„áymïëM{A‰Sbâ ÷‡ ÖÙtµÜæ–ÊþÖB?œ·²ÿ/nâÖöul«ØG7±¼½ãI" &32ý/°YÀ·ŽIž¹Ÿ+ê~EˆÙ+j$[†6´¬ÚQŽÆ*Ò2\Дƒ¾?àO­îô®Mæž­×è}ƒ¾®-è:©nÝ‚…ùeôS‹ ×+bçú_I}Ôu0DžeŸÃóðúŒÙÁAN}U;&À§¼`ï¨1ãUYØÄØ!èŲOèË"Ø¿Fû¥káŠÇ»%Ï=PZvºÌAgËY¶ ájyŠã,¶z¹´2üÿ2¼òé„,AøüKyóã'Û{ÇÓ.,e v¦#ÓÐM@ ì[Sz<¬µ¬ÏÅ-‰Å<$A¼í\¾™O€;§œ'Þ@brÞ""ÉÐ<-W¡ï¨:¢€²û§‹:Ƶ$œÑÿaÇÝä}¨¦ ”yÌó}¡k­Ñ©¯u¡‘ÕU#«©‘ÕÔÈvô <ú•ý;*%C|ŒŒù*Ød³æhˆá¨~…£9Âb"ZÇeõš‘ÇX´Ä£©Ô¤¡ayQ¤3 ODò«0è:-\ù~VR`¡¶.cÙFû¸ —Xr“ÒË-•ÞÖÌP?À´ÐH6Š{E8g*Â)"œ!ÂɹN;Kƒ¹]þó>Òu _ëï{€¯´kÒd@Ãx(äôc(%“®ÅyéÝŒQ<¯#P•DV›…>[–è.sŽHÅ>)Û6Ù2ì÷ ô”Ö#²V Êm] ¢n¹:šN%¸}ÞúótxºVOÔi0’ç ]¬.ürŒáK%û£»†G‘C‡“GrHgö„_‡ø¯ÑS êæéà{A?…_@ª &Õ÷0?œé$¼1‚!g­¹~f6´ðuL[Åö(­êT¼GGoÑ—¢ œc²<µs¢„Ç÷¦w×ÿ»­@¹äbš.0ð{6B€w8Tãìž©?¥9ŠÿßÖ»³ ø¼r­‡jÛÝÈÙ¡Ë…« ›S;»¢Nœ%6,;jJLµ5æÈ¡ïÛUãŤ˜FÊ´p¸•»È¹¸eopã çÇt=#y¬Óã(ejÚš`²éqdð8=ZÿÀ1‹åÃÛšAW‡l˜?%Ѿk´Ä1UZi·³)ÇTä˜L8†ààè޶oÊß䟻¼†‡Oy¥B­ÀJgjE¹œ~r¯t§~â õÕ×°wÇ*â…ò¦:yWXÑvÈuPÏ_ÛúD”{‰œáБÖ^.8‡Ö7rζ9ÇCÒ›”ûS³MFËö3™ÍVŸË7Ç>¦l•3¬·æþüú/ûÕ¶Û¶Dßó|+iDwÉå¥ Ôv #}h‰‰…È’!ÑiүårEÒ²a£FÖ&—K-çrfÎ* W_†Ñ+å¬À_4cÜI_©ê¡§Éˆµ€QNmQå²²dZìž1wL!òàÁ:íéøCbëxÖR,>+$›Œ“ì^Ì”£|ÕR>•sjË<ÃD¢)ç4Œæaµ­e»!Ï@¿Cñ†Qœž±¨DÎ?­WuK&‡ IâiYðŃk â¤ëÑvn¥¦[Â~á.6±VXnÖ_dTÇ´þ*+B¾æ÷ÿªã ›z#{kj0¹;r’‡_Ú 99Ò4õŸqeƒ&<ïß*§±N½,úºàïn6«~úÔ=Á¯„‘‰âÍrk§iÂá§“)àúè/'îËyûå·QIêeÞC£´4OÁ;ÏxZ;ÑBM Ö2 t¶¬È ^ÑÙÒ® |Í‚Ò]7<)Õ¤SB¹©°*™}ößâiÑÅ©hEmÆ® *Õ¡·KpÕ3„nj¡ûz£34fú/ê©>rÞ·KéõPC¡M¤OKÏnPŠ3Ÿ sBqý5x3ìh¨Á<1ìhÚiƒ¸ÆŽP¥A þÏç5õUÑÑT<&ïÁp¦ô1«=c*9ðÚRÝõÉ¥}2n:M³²<ÄÔGk.6R1&HE#Hs •½õÏpùâY¿ ÂL‹03DØCG€X¹)L•ˆÐ…Ê¡!rR=5Ky!%®ñÌf6S*²Uq w9ÔP(hŠao®ü̧û¹C~³–ˆ\huër‚?ªÝàÛ’È››õ¼Yò䬟næ7W0Û$ÒùsªL 0!±Aöö F°"½õçwl»o'PtvU;üõøþñÌûx¨’˜È/€¬Ÿ”Ë ­Ö¦ƒÖsHꑤìudÝ)p¤—–œÓb»<àì(ÁM:Šã7 ½‡›·kCµG—y…9AÕá2•¹»ËR•9KµÐÍÙºI¨è \Mð`·4^…Ä{µv¶`3JžÙЭšåçe½V™wSZ1ºeNU ï܆[7 š²y;2Ç|x·Åe¬p=€Ë[ö—N )G2|‡/ 2s„V[’Ùo=ÜÙe¤ˆ –»€ä~] ²‰Ï–Ù[Õ¢’g׈a)(ü‘&ÕÔW¸$eöhªÃ¬áL3|ÓÍÏ+°¢z!èa6A—NxT ylaÑÄüÙ©%\'ŒTšf{ÃÕá+žp&(¡7[Éõ—¡6(ìŠÑ'7&2ªÀKæØ:X ;®¿†ñ¾ÙÖ4ªñ®±_#ãMæŒs/4¯* Æâ~jï{Ur8‘Éq_8/’V*S?J6ð„Ù1PÔ H/k²6X²ä!-u…Êð§ˆØ.XÈ{WbÀjà—5à¡~é{øÅY6Ýlhz~)xtI#ü^ËÝ"X²«8L ÄÀ9~Þep½ vŠ”ò÷ñ̦{®Qq¼ÝÈuÁ…8Ù§«ä]Ú.·»7cÐôÁ!‹”ÃKÚ«QWK ’²VÒPpzU/úqMÊ\’”¹s4ít÷»º¹Ù®ÑMìP‘l&!+[>5ÍFÁ> endobj 190 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT4 421 0 R /TT14 297 0 R /TT16 298 0 R /TT18 299 0 R /TT20 300 0 R /TT22 301 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 191 0 obj << /Length 5385 /Filter /FlateDecode >> stream H‰”W[oÛF~ׯ˜·Cï QÒ¢ÛnØêC7)š¢,¶ ©’Tl÷í܇=·¡(Y²³ Îíœ9×ïœy½œ½X.Cå«åzæåÁ>ašº^êÅ*Ébפ^ –_f/}ªŠžÎxª/šÙ‹¯}uÛÏ<×óðL1›ÛáÝì£þ;óÀ õm‰_£U9¿/ÿ9ˈA¦ÏÍb¸$H…è Ó›Yá(fFÿQÆóB5ÇO¦nÔõC38s?q3½)û †›è^}ÿã…ú÷y캫ŠÍ…º¾«†¿ËNDp¸và‚PçÍÊ™g0–$©M*ßõÃ8ùò Kã§$ Krwwç:ë8"«LJÿfØ€Ž¾Ñ}e7øX±!þo—3_UjfbÌé« ‚I`J”ª®œ­g¯É~,îð]PšD£ø„Ì• “íµ÷ÎÃ%!‹ûΉAë÷ô¿D³ÄúíK倀ã|ãø.ÕÇÏ\_—$}¬eÚ:þ»<£Öm§òU¾ÅÉP®h­œ<ÛUôinq±·ÌvDÝê¦TyM'ê¶p@£sÇs‘ ÏVªn‘´Èy^×t¥«–›R‘H™¾¦¥¦ø×/ªä‹ÀïÜÞŒGîHQ–¥®Õž›8yÎô,9Ö†YAEæú‡“ê7À#ÒU¿mûòýã°Æ`ìû©›j1`ã7%º å@à$zheЕ¼W—y/C¡Êo™g^5r¶rä‚9Ö’c_ðªýáÁªÌÀFÈ›¤ñ1ô‘«ÞƒÀ7‡‡Jô 2îªF®ìUÁ¢ä̵AÇðuVÞa×5|¸\© ‹MnYˆ<+%º÷ˆþhÚð gœŒ(p„Kç1ÈSò bšáIÆ!g$…„8ðƒ4±àˆ¯>;òTŒô»%& ®~ãeµû©^X´ ïéá>×»í¶íÀå ºú¤gŽ)+¶ñXlƒÐdS˜'*ç‹Ö™GºÁ?`¡'ï‡cÝCÌ0R-°¸—2› pØœšéï“ív±!UÃ@>H¼`€ø±|€>°Y›l*‚¾×Î?Ö èÕ®.i«?–4qýÀDÂ9éO޳üq- ¡Rø€å1ä–",› Ú³»Q<î†Q„¨8ÙLæ¦áYòg¶åî82ÿÿ.J&»ç%;CþÌöh•ÈSÙ…”Žâc½Nï[™ˆ“d_&0â1‡ŒÔÕ%‚?¡ÀÀz×>’U-ï5*ïÿäa˜A€|ލ4ĺS=žô–¦¥PW|¦*”,@Z9)g\U´ºeî».¯nì…O¢Å¨ilÜ ÕÇbírL”`¡Ò1 B‡© 6¢1ô ýË1‹Œ˜ÖM½Ä¸aø[pCæõ%¤Š<^€néJ¦ã÷Õ(}ló=K¢l’”©Íwϰ¬Š º M©Vù÷!ÈŠi×Ár´Ë+å½LŽdŸËm(|ÇöÎ(˜˜æ0A½H€h38±¾¢2²«aXö´úH°]ù{}BŒ0ߟ(äs›…£T×Àð'  £¡¬÷€eTòÀ»vs…œiÞR¹ª  *v¯´¤Ú5êƒ~Ǥl²×ÉS—t!»áû‘˜•À ]ºÞ‰Kò "þ·,¤PäCßòÊ'·©az²y[³&ŽÁS,U@Ž ÷;ÇGç,¢qÏ9÷@¸ïÓ}éÓÙ:Pžˆlbái^pñÿQ¸?ÇÖ‚†BÆv¶¤+(£¹Ð’ó@ëž„AʈøtrÇ,™½Ð*(Ó–ºô5hA¨;´ÐNÚ¥Äó+%™ÅAVr­lJb8<Ê8N±},Œ‰,I.ÑË ^$±8!ô­Pr¬wD²™Oåma‰-ÌßÛ)’Äÿ‰Ø–-€Ù˜_[Kæ(YÊšc×Ü•ÌEïä¦ru¡dh­xÒvV“؉ö•Y€9¿¦ØØaÐH~JWP0^¬i±R#:Çॊ–xF.™’BûNxÔã ʇ~I˜ì»Ùh,MÒ‹~~K]6šáê7Ä£?+»r îJõÃÛŽ¨£‡_Ë͵€£!HÏÓ2§¶8¥Ú‹À»À·œ±4 ì™{@8ñ`±xæ :Q÷¸m‡;¢I[¤m1jA†¢gÀºhz$úDïxþ¤wß?PL2iÞá`°yÇ`ÇæÚ…”l‚pø_§š÷‘7±ô‚ã·E@å†>öñ1뎃wò<„n f_Êǽ¼gBÚË_¶òt»ax®i=¿‹ ³ìžo˜Ï?³=ÞRÈ ±9A}zæÓïÌ(°G¦Îñ£~óúó"¯¥Y¬¡ÙMôMŽ/0Ìgè©F<òUèçÑWTÀK¯-&‹Ý{0A8FLè>÷R~î¥6bðåG½o‰•ƒwhÿ†²°ïëÏœi´Ÿ¡á¤‹óâG ‡2†† ¬0í@:  ÑÿÁ’©`¿öÝÏ$[$ž ŠXðÔ«3 ¼³±rz‹‚¶žˆÐ„OíÙûBŠ·ó±yfÿÛsÚÛLsŸ#_ðy‰qBõ+º¼èRݵ»*BÕ”!­÷ŠœWêZ¶Vjhí^µ&$œFêZï†Y—”wŽÔØ€š°9–Q¬±4Uë–GP2Ë•ðʉAÏxЈXyQð¨ìéMi D|oRfú'Çp?J) È›5|Dîèh?ØÃy]Ëý”/@šî­íIÑ“ejw"4ïÈÒÊ&…§Çý4¼²,ðÇâ É•uÛ)ÇÐ;vSÑ›·rTÃ>{ùm;pÁcƒÁTöÉ%Ða®d^Éqf5T²_Wó /+…â2ǾžŠ`’XŸ¹í•Ú §.'²–Ћ•²¬ÐÃØ¡á@×oˆ%8ô+³É‰¤Þñ¬TÃFÖGmj¢«[f&–@“Grß½:^³*›5]£|)²ö´ÝÜò.:ì½SñAlBöBAÜGȾ§ÞdpÌ“yR6OBæã$hœ‚IÁDºQ§bíÀ云ìƒ5¶´â¹®|ìq"ªÖ£sm<=—,uδJ«®ñYòM/aü×®J·L€f_žnnãá5ÑÆ|c H|Æ‹•æl½Ø°»wÏú]¯¥ éNÒL=±ðÂýÅMô›¾¤K%\6f‚øè>ñÞm–<M'š%rPít§Fÿ©j¬sªß#zÛ„Ü&ê«Q4í/}«é—Bô5®ÒÜ#J@ÿ)Y/e3+¥ïŠ !¤ô}_ôÖç¾m˜ÙtÛÐxožÄj©û£î˜R‘>¤^®B” i6–­žÃBcqŠhé§ÕgR ãƒ-XÌxš‘8’ÍQ„|bSZ±,gÕ“©n1Ç«Æ>~ãEˆ)%¯@Pè?è’âÂÉfüdT^G,¬"jpÁê+ªÖHÃE>ÇûèŽ :l¾ ¯ÝÝ›ä_Nx ¹{¨ —ž J’ô=öÑÔÀ7”P’9Å-%n…â–‚'9|v|w` l74ô;Lã3V’“òß™[ÜÉ9ÊÞ†GùâÅ… é+&V¶™ÛQYW•┡ò˜‰š°é°­u­BÊ~ŒQeƒó=«ë—õ½ݰöÁêÐȰ\+ƒ2/<äÓB!ŸSXÒÏ$å)™#/”LÅq!Ñ-áè“í:÷wuÅßÙyÅÁa®¬MÅ œ= ¨þÞþm˜‚¡rÊû5î:æžq»uÕJûÜ«ËçKÆQgæ|X"}ó/ÎHM÷8ÎޙŚb®Åë²àRËý×+ޤ‚gÌxÞêξío™‹$þˆ¿·wh™yÏÕ!£%T]Ó;£3O©ôÖ»ªk»­£.íóÞ¿ i±ŽÓÀtÅ“l? ({ñà"þ¦Áuýü›œ[¨ç«]Ó±eÅöàV p[‘ü†káEh$jaþ-9ë†ãeçÖw(@y‘­Tüë³Ø ±‹¢­kZT´ ümE rQ£t«öMÌæ§Îšy ¦–Bºd0mw½r©ú£’«éqSM¦8ø~ÔMÊÿ&ƒ(7¿B˜yBV½I¯#I=†y:ÀPîÍwZS¥c‘@,ü°ÝKì'¼P°K€‚3}F²É(²v±fg¤ñyðU—~³À î)€CA¢jíJ6tΣßðEHÛªÎ=˜`×ÊŽ!QœG©úc^Þ‘u):½iVÂ,ŠóïÑ…¸Ï{cáuÓ›…ôÂõ¼fþW=£¡pWâ@~o¬IKØ;¬¬eÁe1kêJšC÷%¨Ç÷”Ž÷gÕ6ÞÜ[‡ç¶xÑÚ˜’Žl%2eBþ#ä¿„gâ§,6ÞpÆG¨õ³Ymcøw -ËÅ ¶Ô|üª¶Ù¡¯HB?ÏGšóŽÅ=Ô™BýõÝG¸j.óÇ? [ÂÓù?ŸeË(x}×Àr9g¬‡FTèÀ]Ã…äT(7K°³Œ‹á%EKíslÕ­¾ätæÕ• Vúò ^ìÃõa<1±M‰;Æo¼+š-L¨FÅÖñßI€ôš&ÅA#p†Û¦ð¾«yÉeðþúÀ¦|\fY:ÈÑ^Wï¹2–bµg€cž'ƒuZ/GÃû9CôÆ€ú×0†–§'&ÃipõÞgøtĢݣÅñHàŒ—aÄöÕ%Xß¾?°N\gšÅâü%D<¿»ù©HÇ“2r±ô¥'G㳩º{S˜å^˜f’ÔwÄY<—é©Åß—ú}å]ä^J³Tú»Ž/C<@$‰M*‘å‡Ç:&¿¼ÙÉ¡Ñx’²ÅÓ/ßãŹϠJÞltRÂY-b‰h­ŸlÖ›Ž4u!Ä2"žÛâ¹'°RsmE÷P»V“Û“¶/3O’.ªg¬uäÇ(XU*o^õ·° û ý‚¥Ž×Â×tæùíR|3”¨Ï‚ë Wuæ:§RëÔTÜVf ™~ ‘E"?z Ó T‹ŽäHáûT5–¼Á殺<"¡#mà‚ì,©{{äãxáK•ľÙÃãpè ·áÝó9Ä–$lMA¬ iÎ*$7µÕ¥Ôþ°’¦?Þ„FûÔ>en<05ÒÍ·¨½’©\ayOP§FrÁ;ÂUÕ¶{˜”é¼Gó±/}—v51¦™àÚ|¡‡¯-:­Î)Ë{"¸OäyvþT5¤Šžüw_ÂCœ¤·)Šh§´âD‚ ï-—èPRM½éQ’M-Oº­ À^;”(FPGÈä!{“ÚÉ5#ô¹`[p¿2áÜÉf ê*(<;ÙŽ3úÕ·KŽ×·Gi_œÿ—´mÞéõ¼\Xy­ñ¶Ú1Ð+@æÖßô/.ÔŽƒqˆF×–Û²g}UB\d¶^œ0wç•sqv^]z ü¿»m)?Jµ¢}/ì©ViT«ì©VIª{ª•‘]i*l@ª•0 |reãÔ†W6w¥¯^爅M<¹J=ùJ=ù:Xôâ'îÓ iÒ|ú¿'_GÙE”‹åé©bzZŠBnÒÓ…üÄò7Ä~ïT’ýŸÒ. ¿cÖÑÅß—ö€L¶Üã»8%ÿ1v!+ÜdË.¶§4¢zó²à€XÄO‹R—Ä""™gíîgÌ*ý¿\Ú„¹¯îk›1¯½HUÁ×s¯§²÷Lg j–Ú;œõ,¡ò«GìVþÌÐÒBî©©ŸÍôµ¾7íòU¿¤Áb%¨½É ªcÁ½º÷³’“+6llÇð‰6‰Vl“†Ö¿t¶d¬ÔP™kê¼dL4Ã&}9둞*Ò¿¯çPŸ©ä'Uq* bH—ú5e7Š,Q{˜–ò; –®¡FÈ쵩°Ùh<#4m;³–•b„cooÆ ]Pm«‹l‚ u >¡Ã±û"Á­ÅFaÞ¤VÀdm_*;¯®Bt7˜~Bã…¬ÊYÛøßtñ‰*Lw[û¯ùZW­ú?v¦;ð­Ž«ô°Íý4JúDG »Z- ,VRdÄ7:xü‘Ƹ[¬ð’ÚÕ®dÕî¢m*Ãö" "¸H„Úl²Ne ÕÍ:¾ü¥ž /UlYk ż"ÿ©ëÕ3czfDÏ丧ÅJŒX±YnV­Ü­·³©UÕ²6m8…> endobj 193 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 291 0 R /TT4 421 0 R /TT6 289 0 R /TT14 297 0 R /TT16 298 0 R /TT18 299 0 R /TT20 300 0 R /TT22 301 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 194 0 obj << /Length 3602 /Filter /FlateDecode >> stream H‰ÔWmoܸÆ}Ý_Áo¥K)J¢N€žíܹ'½E‘^ c³+ÛÛ®%C’ÏvÿQÿc?t^HIëݵkpÀaɾÌp晇?L'¯¦S#”˜^L”1üàc¬bg"/²HÛ8ÓëÉ«ƒÖŠyK:±hçÕäÕgJ\¶“8ŠcÔ™OBß¼›ü"?΂0‰Œ¼,ñ«¥0qðé_&-Pˆ<ŽŠ 6I¬›tÍóuŽKa+ã…þ#tâ§_ÄÙCÕ¡Ê£B^•íšI”ËVüùÇ=ñ÷ÿa%²YίöÄÙݲûwÙ€F Ê«60rV-‚°€,I'"³É$­"e²úÓC>²t>ÉÝÝ]$Q&[X—züWÝب´l—^Àjó+Zÿh:Qb)&:SàN%’>:‰x"+šrr1ùnCe|x‡=… gì­<Óx7ä®á*褩÷¶ð¸eÓÔAh¢T6b('rýJvÈžX^^ÑÜÉ« ‡ÿ.Ð0XÞs§ÞREB·à N¡_ÖÖëÛ­Ê®ôó>KQF—49×mYÊm¿l;¼4+—´oÅbž)ög ¯20ðÑÉy‘7âsÑU ƒ-;8ÔQ®b+ 8s­‹áÆ•÷#ùñüèý”–·òôSZøž ?r`p?5x<ð4ììNŸ»Ž8¤-Àþ&€ùA˜‚¸{Ü÷B¸!-¯1[È3<~pà«øãÕï]Cx»tìò¸ˆò"ÕÃhF2á§ÇœZɺêÊ …Eïé¿{ì"%±­ç}–+ç›=‹ªíš¡p‘òúøpãLà¨45ã´*Æg:&iyøøY–¸à ù9¦ÿÄŒÊ äy’F™”E£\zVšf½Ô¤)æãHžjˆ4³sú3b¿7€If¾^J'cé'Û>ýñÈ+Ú Áïi¶iÖñ:På™Ã'Dó>b4_ö0—WÒËV˜…lêÛ.°“˪D¨R€® ƒÌÀX1sS3Ÿñ¸Óîœô¢©¯UHà,3'œ}á}û9nu½QY¡"kÇ5j¾g ån‚É¥0Shc>c²æDß²i¿ïóBûø¶qEËŽÉ|š\ü¹².Ô®–„t 0÷ñû¦?}æóµÈÓbÈWmz(sµ”`+µ®`E@ðL7kƒ NJ€Ð”˜Ï$ãÀPêDºÍðì¤~K¥GžÙŸ!fÆn.A¥ù8³&6j8>”&#ÈH2vË19µ §æ€ø×xß öx¼?¶fð†Ãñä (?X¸aú]@„ÕAüà*À}Äþ²+Ö58#¿sÙÜ¿Aó(eSV¤ÝÑXpDW³˜«!ů+…Üîë ’›Å ˜IÈ»™Í{6½wåiÙÝ6Ä”s[ödHÙ¹íÀˆÀEÊzáRá­öÞ/Ðã°ŒHð—Ä;ç¶Ì¼ªIsË~îo±¿DcR;þž¥ÇRÞáu*ùÙâGÌÅþéé9 S/ü9ÀÐÝÚëMô%„JØÞbêårÎã>%Ú–”œÊjÝÚpdnž#{}™t1ç2ðð‡ó÷5”[N¹\¾S ØÆc·}hãk× õ.ÄÜßcÓ—©ü«B»ü¼;ìXÉ"y§Œ<ü&P”Aê+¢Ô›ßÁö°Ç~l¸›Ž¢HÔ ^dÕŒéKELíqRÔ!)”‡’G¼ö™Ó¨æü=¡¨S×õܧ¦Eý\7¥ö„ÕJ7iO´eдÿ©k\‹\_»\?Ÿrâ ¹Å+ÐÒuW •]AñEºiòÞG±í!Z=b›©c›iÏ6Sb›©g›š¦e¶i\Ç±Í è‹'H¹î T“„N‰½žxŒx¦äšâµ# ÊPÃÔôj÷®±Aö´ƒ ]óoÄ?‰¾”€¦ŒiO@Ñ&E5]Ãñn¶ÐÏdD?i™¡|K «A{Òi •=E:S«í W»¥Híœt7µÛ1ý±ß;Ë! ¿^J'cé'Û>ýñà•Ý”s«ðe„3Má5"œJo„ÈÉìÆ‘BÇÿ -° @Žˆ«JY-Vó ÐÏKÖøž5ÄaÉz¼"žŽ:@E}XÎz¸K§àÆE}tIc-ê Á¢-:wˆ{ß}M¾?"NÈ(²q$£v £Ž|¦#:jÝÑQ;¸ê96:âKû×HC×É€P¢Ó²PXP³3ó¡¼Þ;ÇÆ[ÜF?‡µÑþžùøzˆEþ.ÐX\–ô`z"…¾ªç³œwo¿)é>S¸J×Zw%Œcù¤ÑŠ&,ÄþƱ–+/¸$zSÝF1´í[QL•÷T'&Ö ˆ6ä™Ê—ªD.øCi„unHÈ”œ^…þ´îr¾×µ‹ˆ}zÿ†ÛPþ°>ç3¨o©üæb †,™{ʧ,ˆº÷ÇÝSàe!f96LgâhàúœÙf ÜS†O³ob “ˆÞõIîÌY0ë­{ŒÏ’V ALüh'Ê{ê/[÷¾Û²&‡·aÎà?O[þzvt(>¼÷Iü²^}ÂËœrhÿD(!öoV·—ªcŸÕù‚ûüA(‰< O4Ø”^ «‚ö€5Ä©Þ< —yáŽpiìPøIF§çà„žø~{?uO‹ÓO<,üÀÉFºM±ä¯‚ð5Vüa~¼í! Çj5wý€Ÿ°¤8$«òº÷nt ¯Ê »ö˜2cbu@QHQÜñ+±yƒQi[è§È16Bú³½Œï–"…pÒÝbÇôgÄ~ïjþz)Œ¥OœlûôgĽW°&ïæ7»ä/£8FA\™űű|ùS ,¤ª :Äwšú¶£H[V%ˆ…kàÀc0\˜¹A€0¹¢q(Æž3µnJç—½háj"9‘Žj7Í›Áz_ Šƒ"¢å‹( Uõ°œ1‰o¾ðèdGÒQDòq°!éktØ3$Å9 ¡>(¡ÓË9Šäy4X{›H²ø F× aKùô[‰ºÔÚO]=Ý_0ëÜá4ÀUÿ{+y¦Ö~Ïzº¿`îv¥ÏÿŒÃ1ä3% }.ü3ìÇÆA¤‰7†!SÀÃOÒô>ˆXð Bø¯o÷S‹xÊòŸ=·b’G (ý\ÃÃCॠȱY›<{’N¸YmýH•öm–Ú÷»Nˆ§ÚØ•Þ3WS/šÓ)ªÂOfñDÊÍ©3fMêr]a¶õ>TÛM¥‹¨­ÜÎk¡¨¨S;¹=£`ìd]"˜{r ²6+s³s…WQþ˜OŸAB°=¥&oß™‡ûÇG¼{3ß‹Åm*Ò16ËWÓfåü㣯³ØO4jù$v§RnG¾Õì4Y;ŽÚ±-$Ñ•zgµŒmÒ :Ûø27ÞR5ÏÖx%“JDI[kËus°‡qµ¢(Pimnó#Ù Êž‡þ0JÏAÿÿÆûÞõ¡NF¾'iÚ…jr°Í·3Jî(d![äR¨ïzÁ=î0êŸJ進ÙX> endobj 196 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 291 0 R /TT4 421 0 R /TT6 289 0 R /TT16 298 0 R /TT18 299 0 R /TT20 300 0 R /TT22 301 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 197 0 obj << /Length 4416 /Filter /FlateDecode >> stream H‰ìW[ÛÆF_õ+æÍ¤aÑ^†¤ápÖn6­]EEVŒ%jAR^oÿQþcznCQ+i׆ô% Îíœ9÷ïÌ÷³ÉóÙ,QZÍ–©~ðIò<óШ¬0A”‡±šm&Ï/º\U UW5“ç?\iuÝM ñL5™ºáíägï]éOã ñ®-~#O%ÚÿÏ쯓‚* ƒÂÀ%q.D¦2d…#ÃŒ~UQ&jŠŸBÍïÔÕ]ÓûS…·²] Ã8ȼN½úá™ú÷oþÔ±×ÖÕꙺº­ûÿÚN¤pxíÉW6 ZÀX’D¤6©é@'&ƒùì5K£s’†%¹½½ ü80^‘Õ¯á¿éW £Ž¼®v|¬Zÿ7³‰VµšDFƒ9µŠ3ø(˜Ä‘B‰rÕÚÉrò=y.$w`¶²‚•8/ÖÚ{‚%ufsøðæ3Ç€m.ÿåOsø~PŸ`”ô¶þ4 ëÕ뺻á¡ìtö-[rÎó_Ðx±§Þ{þ4…ÁÅ…løÓó²ý,6-(…_àgFl[”3›¶äË.Àn \Ó[?y?ÓïX9Û$Aêhä%ˆ §|Äüž±¦¬M zª§GÅAjL¼H"lÀ¥xr³m}”ìî¾qP„±j$ôÞûþìôv–@þh•e¾Š<<ò󣻩v“4ÅXí§QäÉYòG¶ÝÝi@J}õ.IÆ»Hvšü‘íÁ*a`dS£ƒî«ur[RÇH¤iº³šFPÎ8y’(ÐF’3&’¨1 û“`ÛùkžíÔÆ‡<‹o<™m!ã#¯…Ä^e”ï…w»‚z£V¥¯1I:5·–‡ WåÚÏ`¶ÞV¼\2ÓžV内º­iÞ¯ø+´ýŠ/³î²…\Ó—,k—ŽAµ‹ i†Ó•¬cNÙgbÛîÀÔ,ö^ûPPûvÎò:òqCa]U;w7×Ó)”˜4Š†ÄŠtˆ$?Ë^• XÓ]õ>ò¯Qp2tAfÇ:ªnýÌ«Á }Y^@:b^GpHV{¦´Ÿeú]p?Y«é žÉÇØSŒ*À»²¥bIÞÒ 8÷X(44@M÷b¨,‘D`‡YDfHãÌ óŸ½—~BÏÊ*å–2ªøýnÞ¸zWdi1*TÉPî#ÕŒP0öVÀ1ç/JŒŒ0*¨­UÕ¶¡=^[Ñ$¸/úT.ËÎw¼ÜX*†ÞÝ Ó,WR3(©ÃBå0Íðk!3 )ÊÞ. ß ±/‚êÆð³å&¢%õr¨ÂQLŽü‹à‘§)ImòÌÉÁ&'ù½KÛïÚ|5z\,Ž]EÅ|êι ©4TT'‹“bß ¤ƒªùîb€ îb0Pnå âÔxÓâFzE Æ)eNµo^[ðç5FxYƒÓÜ+/)5ÁZ¥\ΗqE…àr~ŒË`æ*ëï ˧Ñ@†¦çLí?¿‹¸#»çqç ù#Ûîî(G¶_½K’ñî’&d{° „hrÏí& Ê¡TÃH)‡À C …ÂBµµî¢HîµÛ”íp«¤êeÐJ ¯›Ò-uPÍ5CUÕB²k _a·l·BE¥‹©æeçx߬d­³êG(®æ+D£¹.»Î:†6¸æ»B µÜ¶'¬¥ ©–0…w«¥ê۲馧ñMïñM;|«Ûëm€ÀºphÞõøþ ´”& e‘X¥÷PÒ0®ƒŠÒK8E ¯–väfm]›Ò` u³›Þu(|k ÅO º7×¼¨º!-¯…Z•ÐFe]ï¬úéíÅ›ËËoÿ†­uá©?Cì}Þ¦9<â?ðörtêß¹Pé|‹H¶m!ø¡óDwmöH„´EÑÿÚþ‰ä©×Ö¹((Ì·!ܘŽ!Ál„p„x_qƒ‰F-< æÛíZ‰¯‚"û«G~·CÉS¯"ûT¶£owâÅiâQXÂÛÕ]žÉ«ºeUú”È7 ‚s&/¶ï°|€-Ÿ º±tÔÁÅcù„ýÜ»m?úìüoŽS„±yÿÓ(}àUz~QVvÏ£ìòG¶ÝÝ_»K’ñî’&d{°JrêÉ»Wëäö—¡RÀ[ÊŒÐ?Ù‡³4î¯|Ìíäoâ}ò©æÑC-$îÐc*€ˆ­)n4¶¢+&¬«“î ÷õZÍùœ¡˜V6¨–Nœ~+ƒZV¬è,l–NIêá`cåä¤>ÐÜq–¯h„ð9ž~¶¶âwçTs¯B'ûÜÔ’›Ûv¥$óàí‰Ð’£§ðëªA(¦æ\cqÛøQ„Ü5£›|îp5Â~’úy¡Q?^º¼,I¼Ü„Z-|ó#^LÄ—ó¿õ‘ÝB± ¼Ö²XˆòÈ|ìA®$Ä”UD¿1Z{ÓZfe›~¬œ`´´Ž¥¶]ìxc-B‘œO@ãTr¢míêbIþÔ|Ë·œnðD)9È}áý¶àÍ1š EAY5OÈèA‹áEŸ'ØðêJ°"–mÿ_ÞJ—Ý`—bKã;FΪíR¬wÀ²Æ~á~› œ¤[p—®¤…”!@5·–É­Ök»xïîì+¼4ë„™Pƒ·¹¶"—Æ7Å«Ëç”_à _ŒÅ{XÚ‘¹Gye,’2¶¡ÞV_]¿/P†ÓT“ê ¨;ª8ü8œˆ)¹q¦JØÿQ<0gw ëK^¸arL)Þ Ž)÷q¯åÍ‹åmP—R8Ó•ê CÒ@ršáæŠOÿ>‰÷“ŽU–·®Et«kvïÎÕÚ^Nîèd+ª¹U¢ÄýDóR¤= µ÷Ù¬2BÓœ}r…ÌÕnö”!'À'b¯aœc€k pñÿD^ „£‹16j pfãª,¥Ÿ‹rNBàw‚—ù?Ó¤'î@G]Žèެýòjëi‰Âïý󶓉âK|Aia‹„Ô… Ò‡U»Z™ÄY\;ëØ[úï÷;—›@A}gΙ™3çú}D@HFA?¸ì†îC®g©nÑCásYnÕž+Jfû‰ÿ~ zÝ?óÔðU¡–˜Fݰ™Øˆœ'6è}r ¥‘ɧôŒ…§éˆÊ$Yê‹(ðä ,ok Žžl¾È¢aJÍuJ•mÛ´hSˆ¾Œù½ÝH;5Í® wæ\í…| ÌñL¸MF½Ç@M·4­!î9ÂCXÏÌUC ~Øó «„I߸•_F.jˆâb|q¥Îy°!l²ø Y gµ”/Ç-£0Í3òÓWßÛ)ƒ\»ÎÕõ’ºo`ß±ýì»X³.76PgªØ¦îˆ DŠì%¶‹ úõêzDI#4R§¨×¥Óã•]¹‚ñ4qY²Ç›èg͇™ËI@=óÉÛkžè€^l…;JO•j͉d¢lŠ ˆìè{^|íRžPŸÎÌY/KÜJU8êÐ@®n Zëq‹¯n'4·ð܈ËÌÇð[#2/¤w””BŒ™q?ô(/&4 T„ݲzß–k4pÓaªÔŨH›¹ò?ú)ªW]'[5_ çèäTÕúe¦ƒÚl§SmvÅ¿=-.sß!å y&óz[wbUêð LÝÖN£xjÃz»™ŽEàA~ð nÊv¢Í ®êÌ·F†Zî|À"Žþ€Ì •ýKa÷KìVÃü! 2²td„ĬSrÂʄĢi@" ×»Aj€4Sl«Y[1 CÍ®ä¼U!÷UäXÒ3E½6z3¢OŒ¡Oç»ÒûI6±â~'?š=îP9Q DÄrý½Þ¢%_8Å_è%¹ý]ô÷;rÍßwÿpÏñ>KÄnäÐKÊ õÕøj½ùßG¡M|dçéÐ=52ݽkÉÐrש^L³òYk¤M¸qñGšKß #äB2\ß se¤ðôoµïÊ\-y²eöæOY6ýeÝEüÊÂŶêJÉ-Ïù[Á[»]#¿;æóó¦vZÂŒç´s(@‘/BÐØø‡Ûß»»C4¸Ÿ²],|Ŭ7¿.õ fi¢R‚ÝÉá“^–Ÿ-Ÿ šŒû@G8*›Ä—M˜Œz(q'Æü4h¸R7}̓ “yÛˆ¬x˜(5`î'ˆ®á|kÝFš# V])Û[³ïeWmèÞ(zg}g¾è§CÕkÂ~,ZNøˆ Ã&šìTgžáØÐUBøäªýlO˜öàÌОã)‘E À’”m̘ÌYŸ¸âÍÓE®EAfzV0WV`¤ §%4¿M L'>lKe™®”úãÀö©Þvȃ‘kN rFn¹Çµ7½üªK–ûgö£1$A<Ø?Ï= FöÇJrGôB&z9·œ‰Ó¼ÙðÆPÙ É TeM†òLH;M¹Í6²ºÁ{ù6l³i{Þ4;¸)ºéeËèbán13¹Ä6c¹‘}…š²Î1*i'_•îÆÄÊíA7HÅÕ6 ÍÆÙ´ÒÃåç`ýûzª>ˆYù<ѱItAZ0ñT /öR¡='#°/¶¨y>¨Ö·IH#fÛ­¸8Rθˆ1`lצ‘MFþ3[0Øà ¡•#ég†8,QŽ…¢†£Ë¹«åxBfP*T<Õÿ hÛ‹zÕm+↶VSÈ%Ë_G É âøîîäœ]w#Þ· ìÊnaOW«ãõú󡱿8ýë5‚8®®ñŸã†¡¯G ?íªŸÐsr{j˜ã%.l\ØøîYë l¹„-°N aCŽø°6æ‰.h9Âã®jdsKì€$[رÕËWªO}$¡®e.uJ|È^b+Ûª"BÒ¼¥•åúÈÈ—Þ4ÎFo|rÓ6c²4JíÄ;-v=I»‘®çj¯p2‚ áIï¶Låê6™Àÿ‹‹:ý endstream endobj 198 0 obj << /Type /Page /Parent 341 0 R /Resources 199 0 R /Contents 200 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 199 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 291 0 R /TT4 421 0 R /TT6 289 0 R /TT14 297 0 R /TT16 298 0 R /TT18 299 0 R /TT20 300 0 R /TT22 301 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 200 0 obj << /Length 4854 /Filter /FlateDecode >> stream H‰¼W[oÛ8ƾúWðm( VE‰ºi€i’¼›^xfÛE ØJ­G $yÜôí܇=7ʲ“if°ƒÂ€IŠäá¹~çœ×óÉ‹ùÜ*£æ·ª~0Ø,óƒ,HTš'~˜‘šßM^œv™Ztt&PÝ¢ž¼øéʨÏÝ$ðƒÏ,&S7ÝN>ê…7|«?—8†ZÙÐû÷üä* üŸU©I˜P§QQ ƒ‚E*ä(Sm9¹¼&kÀƒdŽ´ÃšÂIš³²Ò΋¶v–`NÓ(‹Ø½>7~?Ó—?{Ó Ækå¾\yh”‡óuëÖ á¿ñ¦TÉ õ†W«­æXÕ€z]}õ¦©otyÁrwQ¬Qpav¦>ioÃôôTv…HÏŸË/2a;€ôaÀÒ‡¡„Ö°!P¦hl‡‚m| "ÝÔ}éÅ@ô ý÷Ž”S¤õ£€|[(±žã"½#µh€3cÉ´‘îÕ¬/ï€ÿC¶@qqlÇî‘Ùš‘+†úìãÇIîãÅ:&f=Ù&ÕO¾ùy%;9ÂxxZoî—³3oþËøÍÐÏl$¼xTòðxcj!¾JS£"ùá³»q2ìÚ8F_íÇaÿîõg¶ÝÛqêƒ^þô.qÆ»ßàìéëÏlZ üD6ÁÖqr(Ö“ÛÚ‰xƒ¡uhpËÁmCß$Üè\ÖEt³Ì1ä"½ò À"]uÊ´ÉuÛlz/…­ê¿@ì‚G<íË'F«Bñ©’úÎ3 ÷M[´LQY°ý¾QE-óc ,Ï/O”{ƒ¡Þ_•2+ë¥"DÌô›†oµîÃBî.VåRuÂ@qÇluîÜvPîr§C òY°J “¨Ó§€åqaŸîÂ>emμ þÌK¢*zÕ“b]*bœDhnYÈL«vSû‡‘½Óƒ%J²qRãć¢%LÁ€ZÅ "!9ÐTÕ½@ t@’iH²Y›8ÙÈO>êcÏ‚6€fИI€FáqÇ“ûÄacžÆùSsÉ—òED>‡V)Õ²è‹ÎK€Sß¶$ìÄ=þR~á…ÈúT;à y§™ãóC©ã«¡Ÿ›8ݱ eB(‡:ÖnX™¨XÐcWª_=BT‘â LÙPý`õ-1«–{·@Àœ¡áêfg,c6Dðž?\,—¤¾É“Aj†‘Ô”¸ÃAIÎLo„DÀÀ/ÄÑÍÿ&xŸ¸S6N3Ö"ïÙaÏÆÙ(ý„¡S^J,`þ ôýS+˜ï¥z÷Ï tÆLË n r$]$þ €3EE.±¾í¸€†ôš±;“²eSÞ€:ð’íoò}-r, ŽåÓ½Pšùîé^ŽÝ¸Gk/øxtË ö)b„/%Ê=ÜË-ž7îm$ÕS¢9 ˜Çß7ÊtdÈeƒY8ÿµ¶yïŒ2XÇCØ{I±i!2 +'õN"^`§ƒ]oœù½_eò ëÛFô¤Žå(„ª¯Nq;jµºq÷èbªºUT4Ó¡® hLôû²ïE»§ÈôÑÇ…ÿcc…ÆÒhÀ»3ÉeÙoÚUª¤ä›€š=ª˶mZµð Fh³,ÿHŒþÿÎ`bç VJ€ ®ºßsÎ;e¼<'俼¼ÆÍØmþÃCȃ"\‘»ý*PŸ¼#P>ܵoP­P±£E‡¡ä¡ëèYç߯xŒäŸ³××P9H€bWrC‹ <ª”eYÓe|e!ßB‰;ÅÌwÄ¢ƒ›CUÎÙ ëj*#R™âD- ¾ýƒ"Q?Am+fý²cÖ¿9xJIüWê!ôzx‡lÄ$J¢ßP(`džß65 Kу=XÒCHz#¿Öh_wo‹‹\óÅ™AGšÁ:¬ÄœvòLù<|~ñþôœÊðëwïç³·”?`ª5hqX~É8Ñaac¡‡ÃÆ‘‡½Ê]7Ѝn«š&—Žë B¤¿Ò 4¼™®?CŽgQ|²,—P™=¾S¬¿G0þðÏjð}_!ê¢I)=i¸XT gªT3¢†Ú¾’õ‚Ç· àþ9"êîÊþˆÙBË¥#Õ•C•Jï_ÊäÖu#Úå>îÊ['%,ÉCÖáÌó­Rl#hÇv­R‰Ö²D’&x ¾•ëó—Ê æ©s™aýeÀ‰k( ÛÀ¼´ñpÑõª¬Èö˜œrV µTã’Š{DÅ‚ö*œÖ˜â.T ¢s•©oåf)7e‡ÎŠûŠ‰ß ÑžV+zºT\‹]G@L9Ut„aÌ7Ñ ¡8d£}ã[2oh º»§["‡2y"¾é]q³sÌÝ«,n¡ð’Þ óo •Ì7ž¡¾MîÝ”2¡¦‰Š¼ÄZ{˜×:»-¨–åìºYð' NwZ®RgBý…wÕœ+„,ÑÅiV/Þ^@×ö™W_…â”ȪmµGR}ã9õ÷ŸØBkÙÝ7]ùþ†Éþ"õ‡Qk‡” V¤ãt‡EÒNáÖìê‘|(+pJµ¿sÊtÐpJ5ç4¸E!ôºD­aãkHn6¸©’ÄC®e…†ÏÑð=ßWø øî-j9üûÜ´?éV|®Ù€* ‹Ü8úÅz[ y™ÜÝ?¬¿ÀáŠRš¤9©MA9–ƒtºŸÖ\{y}þ‹ØT_þ x¬¯¯®JêCU>¥ÿ¶œÜ>¿'îA‹{ûq˜û™ýÝëÏl»·iüó»Äï~ƒ³§¯?³=hò¼•]¸–Êõôþëùɾ6Îý0Øe_ׯdR»íÃtÕ ž´Í†³ Ê2:¡ìaGÚ3 »…ªË­Zº”!cW2ÄÇòl) ,à~3\ñGÉ‚À1 …@ѾV’Aj>³tÛÈÅ-Rº…™ŸÅY:ªaÍ(!J0ü ¢&ưÎPß@“§£*8’È„R÷+HÄ&S¸ÐP1†Í݉ڒ¾ªõZÝx”–J:†œÒ3ÓÞŒ!µcJ†$Ú“ý¦I#õTŒdÓp„ê!eµúCñ?Þ«m·äˆ¾ïW4öÅ3€HpzîM 6DXË^H‚Ån ŒÈ¦Ä„ípËŸ:UÕÃáMNƾpØ÷êê:UçÔÌCcOb(ÇÄBGš–ýÑeêÍe›3¬OÅ ·R.“Ì[šÈ¾C·´§¥\ ÊA¹–ºrÎÛøŽ½J¹=OËλ$‡u‡ë ®ý¢’;а¦Ú¨P¤l^;¦|“÷"þ¡é==Œ¹UÖÚ>èfã¡ÒÛkªïcýßè÷Èx*Dé ëß ÜŽñ)oÕø 3cÞ¹ÙZ/)X(уdÑŸ ª¼]†¨1[^»hPc‰çˆŠ‚•lÉUÃTÕåÃÃð}Áx sÓàPù‰7M&—Óé¯4ƒÇ¦Œþyä+½Û¯"{à«„¬½yÆöË(íÀM}¬Ìž“'ıB0SgþÍ"‘ƒú¿ 2k02wÆ1eš'™å½´jÑèÀ¸l=8Ý;Ç5Gà¡KäÖJ\d”$¼Í;ô·ð#4hEÌ^CÑVâHãÀÕ5ñõ ÀOï>uû µ#P“ï©O£Ô{=QÕÀª2 >!òÂ(¿ßGÈíí=S?øSÐ!ó®|;`13ŸAL™Íž%Í*Õ~œ|6ž¤Sû·íu®›çß龜‘펩´¿»§8 ëÕMˆHpõ#ó4‡$5ßÄ yÂ/vÓ¹ç‚~IÒÍg¤öª-’ã„"·äwFØËƒíBç>p1ÛJå]¼uiè;éáS—?Râÿ}«[éÀÔÈŸµTKªµøÎ¤Y/Mů`ƒ•g‡GmŸ¹kZuÚüIŽÚ¤e­ßÿºAÔkðXªíܘSÙKƒéÔ­¸‰àz ÕA>ïÚsäôau­)Ü•+;I!J#3©dõìL÷÷ñ)G8Iªäá°ø›ž÷C–~O?´ùßã~ØRÙç‹Z ³L²`ÍٷצWƒÇ'þOÁǘ|æV5q hd‚3cvN¼û[H„¿¤æ”~¿oֵȣ¥r"V¿ —0ë†ÙF<9éñ³ïtÆj"ßÎOûóô³æMýZ]"”æ‹@]˜kI Ÿ«fa.Ðèìíö-ðKnüE¶xhsqXèÎñn[fø³ãÝ…z-‰”.~äªõ‰?ã2¸º4à…o3'ÏO——(‡|ÍnsbEýUæêÔUù Ee?c¶(å`·!êê˜ÏÝhËmóàL%‹<{±žhEGÖeýáÀOÃjFŸ÷2‡÷¸ÓáÕäæEý£´æX¸Ò9´Ñ匓uw¶6§O4o`~©·™o„Q„¹€‘)7‹Ûâ`Uù<¯7îçýküK™æxŒ0¶ dÊœ3„<©OúÖúLš‘äÜ’§_»³dv]@øÔ,.(|\%6´£mŠh‰3c=JˆíOû*ÛÏK ¹$î—]¶ïµÞŽKß_}!̓Û_ˆC÷FZw!=ÜU Z™., ¶¬ s½ây$üàú¦7˜’œ‹ei‹J÷—Ð"oóà=‘3ºä}Yøþ½ž³’ßïEÿ´:ŽR§ðJÛÏâ¢C¹ã¢CH+„[L´†…Áªq!èÇ ÿ6‡N$†„½KÞÙQ€\bξtú‰À“~9ͱ=kZ›šõEwòæ îšJš“®œ©\þÄ¡Gâå豓Nnîy^*Öaˆi×òz|d@, CwÐùcÏe ÏeÓ4ñþÀÄ€ª2M¹úüCžÐ]"cS2ØP=(Lk÷Ã웃iæ“”ˆ×ÞpjË~‘œ[üú¨?7!ÀüQ6KF_±ëôòo w<‚ãQˆÀìøZ§Æß}>ð¨ ;“.Àwz3Ý8’. ޼( GÏãBž1¶z¡ :æz¨§Á LÓ«gU{Úï– ãÔøŸñ¢ŽaLÁFèëÆfÒöK±[*{å¼×0lQv/¶’Qç*î§Ò¦––ŒjÖÒY;?J»Òì)å\pšùJòÕêÿ`—ºc endstream endobj 201 0 obj << /Type /Page /Parent 341 0 R /Resources 202 0 R /Contents 203 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 202 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 291 0 R /TT4 421 0 R /TT6 289 0 R /TT16 298 0 R /TT18 299 0 R /TT20 300 0 R /TT22 301 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 203 0 obj << /Length 5130 /Filter /FlateDecode >> stream H‰´W[oÛÊF_õ+~ ÷ÀbÈå=0IJOÎiŸ VP¤uaÐm³I¤â¸ÿ¨ÿ±ýff)Ñ’ìôr âîÎîìÜçÛãéèõt*_MoF¾Q~ø„iêz©«$‹]“zšÞ^OÚTÍZÞã©vV^¿¿ðÕm;ò\Ï£=³Ñ¸>Œþâ|Êõ8pCç¶ ¯qTè¿Nÿ8ʘA¦ÏÍb\¤öнœ7 ±¢Q,Œþ¡Œç…jLŸL]?ª‹ÇªÓc?q3ç®hK 7qZõîý¡úó?õ8v§)gw‡êâ¡ìþ^4ØaóBã‚ÐÉ«¹g€%KÄj³JÆwý0N0Ÿžˆ4~ÊÒˆ$®ÜØiÁ‘X=jÿUw}ã´eOm³;æ:ùªT#û0§¯‚…I`I”ª¦ÝŒŽÙ¸Ý‘Á:b)$™+‰±ßZkã 4ð×R÷JGΩN Îù”äƒDŸ¿Ò¢ê§L}\ïkÔµ|ÔYƒ4§ýĹ=t/©]V'DîèO]:“I]u°Câ|§U1-2ž(dŒÿ‰mÃmóI­Ç‘SѼáþâ{×3é­Âr™,}¬d6êÕL‡x{§M)—ËÉ"1u}§ÑÄÿ¤)>vÄâ盡tf(Ý”ŽC2tSg–/Ø‘sr¼+c¤ÑFF/]{ƆR’!%t‚”`‚?„E¸&,§$D6ú*I||ÇË j~Hâ55Œ"м=2™›†Ïÿy}·çÆ–›ìÞK–pïÍÿL¸‡©›¦ƒâ u¦wÊç⾦â’QÄÀìN±ë ¸<í3z1ëB#ÎÈ5ñx6R(µâ•=Qc á h²¡|sŠãˆ&¦„Á¾®dõ–yGË8ù®à~`ú0"®Î¥ÖÓ¿ #"„Lá³^y–Ê!Ô"bÿñû»#XѼÏÐm ŒmGBÐ…Ò”x„¶$Qx. ¡Ard`«@Z—Nï´O=§l•F=Μ›U5Ó\µº²Z¥nePhîèú­(披xŠ2ïûZ”çöõ ´¹*«a¥Ö†úͽö3|sð¯T~]¯d×óêtŠÛïxóú‚†9³Zs¦öÄ”dACçº;ErÝÔ«F-sÙ³Üö^+eѰÌodÖs:jO˜—húM$û K2{{h[!Ôóã Ï*X[µë¨ýÂyÑR7¡É÷Áæ¸Á›à¦ŽÈÜ>„Ä®À9«g9™7v'|úXS¼ÕT©·7ÖT¸ ™@¿TÌON*6§q‹+9ó³ÙWC²D¢%N£AËì³Óùå‚ÍÆB1JRÉ6ØMhë@tƒ0 =ëÛŽñ­Q–”Ô¾³Xiê·ü_Z0PñìJvÌåC€žmQ³‚Ê@ÊTÿeYξeŒCšfÏ|§=z½¹–¿ÿë½¥dë8]É.ƒ`ðŽñѨðM“,Z—e3,ËŸ¨Ã"ÞŠ7ŸªsD9IãŽZ¯Ñœ¦}³.÷¦„ÔK çHÆ}80ŒA @6ŽaãL<„%Á1ô}»7î‘B–DÙ 7¥}\Q›"Y-RÐÇ…cžwy«©›thZÈ‹¦P³ºbª¬ßídKö±½„âµð^20ÍQ.Æ8«å;³óÅÉñŽðȪÔ ¬…·UXçlè6&dÍõ°»¾A)pŒ-zQA\ @,Ô¦}¯¥¶×lIýœ‘ÔÊÐubW`tY/L7ÍÚO{s?í%†ÀŒHoÄs_0šgC¬oX%ŸÅGò¡y(uÖ;]&ÀýQz´¤B'ö¶]­­¬­Ç}XÔŠLÕÕ–™UZü¦à›Ò¿Ù8©¯¬,RCÜ\›BZñ.à—6¡Èu‡¶£¯¬²Û/€’¾èÓÎÉ‹ñŽéNMM„|ü¢t¬“Ö^ÑwÔ£×ä¡Ó@9Y\áOËŸ¢yk‹ò¬¤±²Â.•m8·¢¡Š  ØáØ/äÒ Ý¶ÁÙgÖJ¨o6\[…²óYH¾ ú÷ù©kBDþö°ÕóÄ’Í`§[-1¼›ýmöóÏ?f¹>E† òÉPZüO{íSVK‘º¡ZÀ€!o1~ÆÄ`€À«ŽùÅ>ë}åˆF£ô ÷¯CÂÈ£ÚYH¢€`NƒåÊÿޤ[›žÆ“^ÕwBÂØ¸î!ÞÌAtU,‡€^'dÒ¿±"ŸmÈÒWØ_´opx ;˜IÒî"QßM×`Ú)‘ГwWâÉ«KàAÇɴLJ;5[Xz³ï‹vGk)ÍÄ#¶׊½1®É6Y%kÅ—™ 0ˆ9´‘§Aç†KŠœRGPé\Ð*ù7ƒ]fÓm^ç¾tÐíèÏÆ’Ҏϲ+ÛÇþ®U†Íip¯·B}~}›çW‹ÎRþýƒX×ǧÿó0†!Ç“a¤%g2>"+Äqu‰x<¡£á¸S:8B ¨ëª&¤b«P´Mˆãèñ/×:áí4“íô&Á{$äHbÌûýÁN盟eô{7<6\“?JÈ„D1&qí,ŒÓSôy™åJ^úqU|Ô{2HéUäA7- ~Òó^©KÄ]œ {97Ý“o²Ýáñ"¿Çteœöu¥öéЫÊÑBŒº c¨‘—ˆÃ‰Ä}} SA¼W²rHtÙÉÞ=]I1¦ô–ßÁ'äü~”&²¼R—Ãh8ì«Ëó}qCÏħ¤ÔÉAª8<-âŽ/þñhw.Še'Ñâ#‹CÂíãÁxªx§Ãâ\Æq¬;¿ ‰ k"ÒžBÒLkëJû@ÐFòpÆ ^.N…Å<]¢i³{:cïZ1·ó;ÒÂX^Kè©`Ì«ÀJ"\þÿXÑ(Ù‹x½Z¥p[ê_Ë?‰2=B*ÈŸuÞé‚L;_]ägv ɦ±d.´å;§AòØweç·fT¦ËJ²_P•=Ž¢á~ý´ Õ2ÀFƒÞ¿†'‘¯˜IlŽÿ-Õ˜¨*„ÏBûàs=kL&j’Ú–^’y&Â&ŽšÌ²ˆIßõÛUe^œÛœù¶µ¯¥M­]‘éÞùÊ©hÅm4 àNøA'.ÜÂ&¶™ ›¥~'ÞxïroEkÛ½ÀœÖ›€(_Xÿr-)û¶µÝ]§J6È×ïn{®Oˆˆ¾Z'æÆ1ª“¸ï„/ˆ-ß I_KÝQ`›b°S›+™fà ï^WÛÖºJÞ, ŠžÞ¬uË"$ ·:m«ÓlÈ9Yí¨ö†]Œ˜8Æ)Qö›gïïïnnïßß¼ûÕ_fžûŠ`ÖØm|o&< epñ]/mÃ9+cüN Ì£ËtÜOöHˆžÙn‹²•±µ¢aߦCìùº )5¯(íúÕƒ¯tÀ´©uO:f¤@lª 6ñ•î©®l¤ÎX°p[RÔ c¨ž†ëOUé À\oQïp¥!{ëôŽÆ²ƒSÕÛµ¿×úßúQìžóhº^B Á‹„õ(w`®3•ŒA®:¾]³‹…x÷?·6^¶æ…†Œ—RrÄ+Àº#UöÂÛñ¯”ø*à¨{TΨÁPfÖ„7ÀG[{bÊïœÃàÖ™ "!ãoýMç¹åZÍ)œ~4º@‘„¥v“yt·kúö™$}–e•çó¹~ävd~æÖD‚ÖûŽðÃs;Õ·ŸüafVÏ ‹`3÷Ð=sHîãïj-Š ÅÕª¹4‹»ÌZ°¶\¸³ùœþøC//8Â冩ct0è-îåÅXˆŽl‚Àö3ò•b;­pÆbºÕ~¹at9‹£ìØLïÞ¨”†J Ÿt¡ (à7ÉÔÂR\ñþË_þ3wmd endstream endobj 204 0 obj << /Type /Page /Parent 341 0 R /Resources 205 0 R /Contents 206 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 205 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 291 0 R /TT4 421 0 R /TT6 289 0 R /TT14 297 0 R /TT16 298 0 R /TT18 299 0 R /TT20 300 0 R /TT22 301 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 206 0 obj << /Length 4506 /Filter /FlateDecode >> stream H‰¬WÛnÉ}×W4ü²3 q<÷‹c°%cac-6_6ëÀ’-’E*3CKÌåóS—æ IIN€@€ØÓ]U]÷:ýf|ö|¥ÄÕ˜mM¼Ïȶq_ø|7 mž¢æˆ*yØ0ð^r£·ÚúyPñº£žVéÇ¡}[÷B‚ ]\ðnÆ®ð™}õ‡bjŒùš¢ìËöZ߈˜a¹çÿݱ«Ò óLÙ‰ñ£´Åã´H1‹"ÜÓ{tð*ýÙa–»Ã4Ëè];8Îâ*(ÓǘŸ>Õ{³²Â‹â?%µôôq½aÿÉñÀ#èþrŠºÈòS³:3>hQ¦ü’•{Ie¸¥,å%Ń:ë±M&1Ë›iAíŠVßwÍfKïK âµ`bî–+ÞY)¸ƒi­GÎÑ6j'¦[8¢•µõ\Œšik"J0p@=oä³±˜ÛKÝ*¤Pz´ïÈ‹Éí=H8SëDó–š o¬íT”èäÍÁŒ{Y_vJ6ýð;úÝü@ üBÅ¡ó5å*ªÇ±âÇ;è>`‚Þt~³¬Ì/~„ôð>`æˆ!òøv),ôX¡‘Î]ðvÓÚ¼G!¼ïüÐU )‰ùÚ4è·™>+þ±Úecg²¼R~¡ ?Óüì‚&‚ZVÊôÚögi’àÀ*לºúÈY•zo_òúÍY»,+)Ëd§[®ea‘fl"|3Ñ-ŠeæÒ,•4K)Í>^ýþ¦^“«à…náµVèñ°’óˆc gß:-–k]ÔF3#vDÍF>û;ïêl ºÌ;ò~äè[—:s!Úlfnç¶ÙŒɘªÏ…9s ‰z¹pªWœÝàåGléhÌm ’åÔbFóÞ†]®Òº¹ã1Âùnû¨Á\Ø—_0•½K¦¶+ÛÙ ŒVB¶|¾±–ÄÜwLÊX÷d¢BÕœÛ/öÝP)O¥N†Ï§ºÑiO<’çÒˆ[H" Ý¥#Lû0RJ‘þüôÀ“0ªÐëÃÇ1ÏúDA¼ø")cÁ öi8s DŠÿLL˾ӗG8‘Þ4À‰OÁ 8Þà8ê³³t0¥ÄH%h ‚ß~Pb ¦Ž3SÔ ÈSCГ2û%ª‡Æ –hk>ù&õ>RÅÞä{iRB"”TM§pâ“8ë#•”C8ÕW ê vAH›Š¡MRæƒÇGXí£®o²s²/Šä¡Çþz¢è<9ÉÕÈJ¼$Ⱥ;V¯Š0ÉŸÂWi–?Žs=$ #‡ã˜‡™Ÿ>u÷¦ñçñSVKNŸÐëaöŸ<ò¾zìü¿ÃWi\<€¯ð´ŒJ}1\.[Ê”¶5ŠXá8üâS¹4 6 •ÞÝb9]˜…ÃMÀ[Š¥ÖLoj…cÅ0µئ7ÌdœæžCPÊÛ)Þ³æCí‘ÃC÷úè¤øê½îzhg 8´mÝjk J¼z( úÇ-ÉU›õŠ]zÖ°U™X…&QOäŒÌȼ•ütK+T-v7‡1ó¹Ñ/åC€[‚R o‘’Hj!V»a.Px{}ÔË`¥ˆœraØý‡ýêûmÛˆÁØrëˤ!v¢“dYE ÈÒ¡X»MPô¡@ Ø²-T• Iîÿ~üHž$ÇvÛ‡=îIº;GòÈï«L½PËv\“ÉPOvÊWû ìˆñĉ˜K]â‚÷µã¥+vL. .LI¨páob–„ ³f´û†ÚZè=GÑ$ <á>­(ä+èDNNézhò„3|utQì¾N>y{e 8‘Vð#ù)¯L&Ø´dQÊEw€J>5|BÝFSæÙ×rH¢×ÓÚ 2ºß*;Ÿ‰Ùgf'‡´ìŠü„ŠÄTF#UõÔ¸{ð|À´;n=‰÷‚•zz†(,ʩޓŠîR›8×Ãá©V˜³GJ=4kó1ña€¨>ÎÙØÓ!šå7óL¶V•¢‚—ö”J)<ጆV Ï~Ql e‹L‹Å1䉧¸!ŒÒhhT3×î¬>ÈW+v‹!ÄHy @&äÌ=0î°%ÐÌ-© H࢖ÿJ>Ôç­\úÓr¨ª «ÚWŒrŘ­(*uyÇÓëc[zHFîŽ<µƒL ~º¡‚÷ÁsªÅöa[ÀÒï§ßT8[ÛÜ¢žúè® ÉZÓk¶†J/×c}½7~e”yÀ_”þjy¾é7ð\I¼±È}¹Í£ Ñ(yg$ˆi Ä´@½H€[¡e[ú ¹á²O’¿y%Ý¥Ó5¬¥éed#›Á%ê¾ùR‡ðÖL;'i<<ªÿiÀÞ=&zð“øÙhä¦ËO9ƒHïÛÙ«’ùöûB¶¡Ž7ÁÙ-åeŽoNµ›8§º=8’¸Ò\'L)ÎGãLjÇÿ —a†Böä%f…·,XîÖEu›ÑXD)_ñ”¸0à€žÃÄ \àŽrz²ó q˜pÌ®ñÒbÇ^,³ûì%r”eAç\¥Vkaåv{½á›Gd0T5· ì¢ ^v”FñžYuµ*Ö·x–E’1#ƒOíS ét>S›³}fcczÝÑ) z$BWO“ˆÛ°ÜŸ=(\w°ûø:‘ˆýö¤Ò¾mxƒÕ"uýŽ3‰Yb‚´â–‰>+ ö Hö$JF¹‹"ä €/µ duâ|Š8€þ *MO"5›¦Aœ|„Ú08MO.r xñ;q:ºùû«îÜ(‚ÒÓQ:±þsTϳq!dZTc«½à^šßƇ³io ÐO Ço€!ärtz7`©g¶xJʰÚ2T¡ Lw ;ÏËÒ<ŠpÎ2¦Uݕа9(Ðk @béèwîíÖLŠªéÀx¦ 7 f£¿¹ûÛ1ª¦|\º™ÛKà•xNebÐb¡–µ­[Q[äv 2½_HbLU0å@(!RÑ9'èã¬w¢ì±15¸E oœo˜åÆtûµü°wcojî‰`^ne’긊¡½Y¯zÐ…¬É˜šÑ+¼ÖxiÈ?K`ª+wvÃY|zQ-÷ô~Þ-wª°Ö÷¡XÕ2î=œ«ä¢wa›ËLË ñˆGá`3û-u¦ËT¸Ü)p=uú× ¢`p´bž HÒ>Ï‘å×)¾¨Rž;¾ÇÌ«o^ëT.ŽŸÉ¥)kÝŽÅFÿ’ïEŒãï;Õ:¥]öõÌ<îdÔ™ªvúÜDÝŽÕr»ä¿Šº©ê»ß –ߦvÚ¨JòOnÚüÕ»réÄT¹ ދܱ‘ùšç›CâÈØ'î‘ ~áGKν ðúŸë›·o®_þyûâíÝÍÿÌ çW‚¶ ha¹©W#v™Š¿åE,’ ‹á¼M$A™[‰tãnN.€ÿ°£3íNþ¶Ûºa\CðOfF)‡¶Ç¡áp­}7ïÑûçÞ‹7·¯oÀdCï¹?‰Ôä+¨½1ߥutÑÈ (‡3¬¢Ó­ïû> endobj 208 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 291 0 R /TT4 421 0 R /TT6 289 0 R /TT14 297 0 R /TT16 298 0 R /TT18 299 0 R /TT20 300 0 R /TT22 301 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 209 0 obj << /Length 4696 /Filter /FlateDecode >> stream H‰ÌWmoÛÈþ®_±¸/·,,šËw®Äξ»8­¦Hσ–h‹=Š2HÊŽ‹þ¡þÇ~è33KŠ~Q’ýPwwvggfçå™7³Éþl*£f×ã+?|Â4u½Ô‹U’Å®Ÿzš­&ûGmªæ-ïñT;¯'ûïκi'žëy´g>™öÃûÉoúcîL7Ô7}}­ÂÈù}öó$c™J<7‹qIÚC+9ï'ÄŠF±0ú—ò=/TSúdêêA?Ô35‰›éeÑ–n¢[õúÝžúÛ¿iìº)çË=u~_vÿ(숰¹rpA¨ózáL3 À’%bµY%߸&ŒÌgÇ"IY‘äþþÞu7Ö-8«Çà¿î–ÐÑøº-{‚l›/™ÿÛÙĨRMüØÀœF > “ÀW$Qªšbr=yïabûÆ…Ò,ð&l®„˜„b¯í[°áüá hH«¹ƒó†Á|H”ß>ž/ØÎèWûw2È'Ãg¿ZßȾìkdÚë¹µÜÔ¸Qd/~ül뙕aSuN¢Kò‚L¯~·œž"Ó]q™×$PÊ&…—ÜãµL_ÉöÐê|ÝìO|‰é=ÄjyêÄn¤?ðÿÌ™&úí+åà)ý~½Ø8†¨ŠËŽ ñ4ÕæF–X"¨GÅ›¥º!UCÄ”ýI–ï™oYUv~U¨¹ŒX ·"+áV,Ôk>ð+< Õ•Égþ?ÇR¤-›ëucGE?a‰”½RW¸e]ËrgY±Ó=UÜɰ¨-òZÕkËävÐpº}$‘OÈ#ù¡ØÏ„Y*,k%Žé†ô§è(.+DÌL—­,Šk8I@öóÉû‹ùDŸ§©Ý4["ÀÐheWÕú–B”€qÐïëÖvÐvß\îµË0‚åÓóëŠZî모õ×ÄgYåÎ=%,YÒÒI‡ë–½””+ð)Øœ|‹â¦×5Dka”óa+F;öQ?圣+ÒyYåW2d6¾.\>DqŸJÜgsÉ4è£>Nc7ñÇY’²,IL o4¯i„1¥#r’‘ÆÈ‡í«þ&8‚d7õŸ# ãÞ9Bá{à„.±#ÅŽ`¨@¯‘tC8gñE¾‡ƒä6cE®É×¼Á͆DÞ—5cY–9yA†õùŸ K¡JëÖóiØ9¿¤(øEÖܧzLíÅ#E$%£'8X­©2$º–Ïuy#ªSômìwÕ>Ó ËO’­fáäÌH1J8dšÝVl¢ Ínè¯ä9¹)]ƒ…¹7’ Ü!›Ûï`&òqáÄoX6²TÊRÍ7:>GZþŠIWWòfg”9ä"C>û“CUðp>—]‹ÅoGgi)ñû3 [p‰·®’ ì jÈsS‚UŒ´ð ±GÖò¿¬®ëŒË<·%7Š{¿Iã­y}r¥ã‰C$”Hæ2|ïLSh‰ªœaÉ5?I¬o ÄP®&Gʰò#늂㿳‡âai8b¼¶|ê§‘:¥Ø 2¶Jœ&C «è³¢Û45Boö÷GµýåÈK·neórÑ4(s*\dQ<ÁwãÁõñÊ=‡¼m¬ /ñä©~ËYëtÆZ§úì³,«£OŽMôi¸ZµL*È Á¾gãER›˜$g¿}òB!yØ-_˜Ø©ÁÇ#TªTñs•^¢x€:[ÆØQ·ˆU^ü]Ñ©ŽÑP†4J¥\îG*ꀟêÎÒànm¹®Ý ƒ¨ãÛ,6IŸ~˜I<ä’nç|ðŠŒêùû_Õ}éP~p_—ÿa÷ìC²F8Bs JŒ'Éãe[‹ ·N ïàiYßÈ€€Kgo/­nÃîÆrÅËõJ3FôõOŠfOµk(S,ñR(ý¢•¡é67S2*Ÿ%/ŠÇ×VcÐÀÞd3Ô6çúv€†írÍ0(xaq(…¸ÀZ 'Ñ7åWƒÖh—D×”d³§‹v ¶¤GÉd¿]_ŒUN* 4Ówãõ ¼ÏêSë7p˜¯ñp‡DdB›ˆ×3^¶­öžß«ž…¶µE¹a G&mƧõå§‚Á&cHôL%Ó×õ…V°PC¯ct/ÇÕFÈÕB >íïåª`¶†ú1~¸íwp/c³Õ^9ïIQx †dº£/[_+„UжUDÿBÐÑ×—îÖ*&‘Üô7z¡ÐölujÅÂí±>…QJ~GäB\Ùˆ èwº±Mß•C»‹æPÍû®Ø.ì9i ¯¹›²Ý"z uõ`·và t?ÄþÔjû4›âðqˆû `E9lœëMÍž¯»’«BÐ.pËG@rÛ%¯xOEm‰ë‹ÏrªâÝoø Ácu¡8`t×–|ªPy-ç¤é“–/‘–‘t/rtË>jØ»æ)›{ÚŸ=öSÏíG?QdÂ;_ŠoßlS±µV·¤‰û5ÈÅí&Åž²ÃšA'5?D®*GÒ-æó?xy0i½î:d•$ó²ãÞXH:o)×!fÏ> M¨ø¨[¬è!èñ›Ë#¼yquE"gËÇ…óÌÐÓä†Â½ÔjiBÛµÎ7È·©nš¢æAçP»ª¤jÞñéB…êr‡¨Ü’Qå”Ý??þåR(ŸÞžŸØ3Níâ{kÔ×ràgÉPX÷3õO²."ëj\3›ÇO¶ŒNN?œ]8/9ÿË9ò‰¹ p»·éaÔëìù‚|J"“] fµééF¾+®svOÑ|GÏ2µN%ÞåY»_¾åF%†RgŸ©â&úRõ+çìÈo¹a ay Kò0BN<¡ŽÅ@³«wV†½(Ó' ¬œO†èRdg-Ÿ~Ç;xÖ² ‹± GéÈŒ­”?îC#á%¡ö¬ƒñÓÌ%¥-&6¶RïQUh;uB=aš•Tà“ãg"ÁÓ¢è‘DãÜ’Ÿ°oùúø©ðèÅ`”X·bxÑ ,ê⯟¸ÜÞ²ïfúhII+…Í>¾ Q@:툌ƒ`›è{n0}€+º‚³ ¹ma·JÚöu¡AŒíì­vS©²ÔÝ ÔŽãß wœ÷¥Eò_8ý2-Ôã‚‘dR0‚ Õ%ÜvM†S”îNŽûŒ6¼b$=êã=(MزµZf»ÄÞA"{i·±^:ø5Zo&ÏÐÒn3í _§ ;¸fÔi îÃÊæÆ~¡t#ô׬ Sb«¹¾0Ø"TBeùNö3\ÐåäœXB}"°æØ¡zå–]a~ºnÖvŠ' |ìÆÛ…En|/#Ãè?¼WÛnÛFEÿd)CÄ;8zp]F“4°óX Ð…¶ Ó¢!R¹}}çÌÌRKItR4 Xä^¸³3gfÎé6ÿ>âÆy‡£_M<è›Á÷òŽhš§±#À‚¨k Iy@ëfäÒ‹vÑŒP³ÁËêmÁDs2B™_¦‡¦Oô°ƒv'UX=ƒGÔ¯/L%íéÇ©›qÆæ¤rVR±[XÃDÜrÍNÍÙ©)wM½øúòð2–9R.”ýàLʸ>¨…$.@Zb8&'•è>‚™³£¡ ÆçŒ8šoyÜ•ik(¢n¾P7À¶¡a®–Lƒ4õ8B¦ßÍ`ôòÓ¶Ð!áN'I=½ò¬ y !ÇW¡oðu‰Ê52fdH Cýð^Œù8¹vy”ä îvÃç¿QÆ(Û×–L¬-¶Ûz ÑHðòêu!&\9p€&‡tääßôÈÄ.âT9x‡­ZQgnk­×"íÙo2ŸØãLèwÁñœ‘77ÿ`2¶“2£r`õzFȃ37ÍN(Ì \±û)ä§iî„éó’ªÛ‰s] æ‡Ü÷”!ý÷®¦‚˜!!®¸HÏÛmøg¾Ž(Øm)‚.žCu]òÈ`µû>áŠÂâJ)÷ UH$úM/ •eŸ>9öCÿ@?Ìrëˆ`]UÉUGTÌóë);R]Eï}„Þý¿Y4ÏüºX¦ÜÈL++ s© yñ â=é\Ñ=NM½E°(~\j 0Ñ%¿HÇ2uË6’D-dÄ®¾Õ›•ü¾}#:Ëô×éO͵{u‹ ’øaý‡‘±iŠ®Uòù7úp7J™æºß.úØ-oíEv5}­Žªq3ŸxtTüeÔfQ±XËøE¥ –òóM¥Âë3 ¯ÄT4cÖòÓÅ”ˆ(+©ž®ÇɱM¤¦’4vM ÷@^œ ß¤½‚õ)]EŒ A}~&és|òv ý$W;¥¢ü0t.»¾¡~_{3¯ª—×Gꎒ…¾ËRÆ}Y¯!¢>8 i “Ãâàôæ—gs¡‡ÂÐü Ž f”°™Ãý=±LÅ• L b¯\›³³£PPÂä©‹Ó ‹‹Jóå"Ú"3ŠïQPâYâ€%ï *ËÔzwU½¹7gÔYâcdä#ß…hÚ³†Œ¡@yÕ#_,ón˯ҨŠãÜñà >@¯\0µðKм3ÆëKæ0éYýñCÝÞ·,GH€¯§Ìf®ñÞ/ã—Ì3˺®Ž Fž„¹ëWä,®`ZJ1šCsTH‚iFùa¾‰7¬z¾u†ìŒpšP§´åزàO4¤O˜±ÿ€$.‘–^æúyÙ;BóÈ]NÞíߘ¶é‹Dz)}æ)}]Æíóô'OVËú%‘\fÏ&ûJ¯éóA¸ïÈ>No ´µôz׎å¦ÀUÛ­>,ÖvQûPèSó\¬d–ˆp†­ÌR?)*c³ùí6U}ß[Ðm¨ä½^=êJ’'#4>"Œ ýŸÏ©~P×Á¹¹ÛÖ$ 3dLZëQíb©OM1=M¿øuKÐ`â¸X$Ë"d4’^ì:·[¦'~èmIˆÁM¤R¥}3 ñ]ZoÀÍ¥yG¬I„ ¦¾Ü×h+“—5.Ê#¼Ò.šQÂ2Ð÷êmaVõ†çd¤ø,/Ç:V;‚ÂÔ3ç M'4+•?NÝì´Öï,Þ>ÿÃDÜrÍNe èƒu>!˜¾çtîÄV–EŽ7’Αzc/Ø>|(™’9]+T>"𜗭аˆÎÊizNl!ôÆçÏ,`²©xÆI+û)&à§^qG¤3F}…š ª;s‘èTŒ3?wØLäÐ4­®”}2˜»ñÜC4æ”N‘ÿ%˜{÷\:,DVÕw#úË´¼¢Û½¬ø½^ž[tpÁY|”ë‹êñ}»=q§(ÉÜÎÒN”)û3ï…d×’\MÙ–úIeh!¿keÈMùµ è¢U͘Tó¢%C&"…㣠rX¸æï‘ÑÏÝ1ܡӰ£À W#ºŽœ[!ˆl?å+¾éaÒä=_‘—@5à°bÞׇŽ<Œöêðÿ üS†Jó¯7ì¶Ô{ÞIh_±²""í}.™åÞ“Î=‘¯uˆ Óq8~c–_ä ^¡ìå;Qd¦å¼K0)–¼q yÄG/y°“o×+YB\ »k›·K»u+TQ_Õڵȕ©¹¶çž/+þÄ-Þ‘“€~¾Zç†zÝ Æ¨ßföÏjÔU˰Ó5è™bâÆÞ©5U9áxΠŒ»qëæWtµµ4i¨-?]ÒÅÊYÿ)ºƒ)ÔÖŸíÈyä½2ìÃÄ“ð§ìDæ}øñÖêh£%”HoW(ÖÇû8öìG,b†BÜA!e(`É#AF¾™@¼™s^žëòJglœ›'½ Ù~œbŠÓÒZQ1 0'àß÷8+µ6ê  ]µKK{£Æ”ýfç<óQ Ó-•Žë'%ÐDQÿ²g›M endstream endobj 210 0 obj << /Type /Page /Parent 341 0 R /Resources 211 0 R /Contents 212 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 211 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 291 0 R /TT4 421 0 R /TT6 289 0 R /TT14 297 0 R /TT16 298 0 R /TT18 299 0 R /TT20 300 0 R /TT22 301 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 212 0 obj << /Length 5052 /Filter /FlateDecode >> stream H‰´W[oÛÈF_õ+æ­3…ÅpxÒp 4±³p‘MŒX/m²XPm1‘I/IÅqþQÿcznCÝœf taCœë™3ßùÎe^Î&/f³DY5»ØH…ðŸ$σ03åŠ,ˆò0V³ûÉ‹W}®=­ U¿h&/~º±ê®Ÿ„AâšÅdꛓúº4Ó8Hô]…ßH«$3¿Ìþ>)H@¡\ç²éž÷GEa+cAÿRQ&jŠŸBÍŸÔÍS3˜©uA¡WU_C3œîÕß~:Qÿü·™fA¬»z±:Q7õð­ê`E ‹×HtÙ,Í´€ˆ$èÚt¥È6Éôg¬ÍIÖäññ10qé$¢¨'cá·VpGé¾ö¼l±"ù—³‰UµšD™8­Š|tâH¡F¹êªÉíä%Y#ŠØ ÃHaÆ£å²mCpmMÁÀg¨ê}V"™žµünø[«ÎI8Åf|Jä¡‹ø¾~ìÁßYÍßD·hF§‡r­zƒpÖ&Öß*ÕÞj5¬L¸Wj¾nç꣮ꃽL„ˆ ‘E;ÑæÆL#}¢¥_W©rÍsr’ OTÍÂy×@•_¨_‚éÁªå|]¨*¸£Á ›i£ìèT): sW•¢Ê½AƒÃAÅc?X¦H‡$Û’!Û!ÂìÖ×fš½k<·Ð]? *é.ÈɲPðºÂ;&ú¸êô†zÀDÂ^{Í¢ /@.h¥1 UÒ2³Ox® ¨§.çcµ’¹dœKÒ|‡çq:z]Ê: Þ/Màã4˜/G\OÕesW“–©nü(Q®@¿‹ÏÌ|L1ÍÀh‘©"U¤W4ê¥àB°GÍCÖŠ”ˆ%§¶ ^/Ç á` W˼Ý1'‹ÇÞÔ#œ`²0f8³(ž¤¤à´îåʧ ^á²ïêߩͫXW~³—òpÑk†õ=Œ\(èw€xì(V% âØ%[GIŽ%Ñoäû¬‡²ñÖC솬=äÝÆ8¸Æ`"ò’,ȵŒ<ã%™K™5ùZu››R·õ ®6V…W,ÐKf«ºWð?¾ 0݆~~]2ÕûA=HS œ¤à¾²±¥2Ë&”j ÜR/E#Ãåý9eI1«Füã] ] ö.PñS">fNõsÛÉæ7?ûŒn ÚÁEëõšøžßqf½n‘ı~) ‰šï‰×&)Q2)ϨpËHý¾6]ÓŸŠþž„vôã(õc»­l,_£êº¶S C¬]V’¦Pׯ¤$œÉFµŸ©ƤüTP² q¤æ•_è·0"4]N‰$IKuV^QÎDS¢*ôÕÅùÉYù,´”°|.G5 µ x£J!‹ò ¤R@í 1GIÖyûn†4Éõ¥2tŒýhž”ëÙª’±{C…VÅéMzu ä$@P`„{dC9¨³ùú3]¢h=ç>Å BËì ØA]‚©º:W"|CÂÁ3°$À)Ù´Q|ð‚†‡j)G"s` dqlÍÚ¥ä¶+êUTXÜÈŠfñóU5wÜ«ywS“AœIýKæ’i’ÅcJOG–DBöE¹†žéµú³±4.(XÕýCÛWï¨=7TY}"­–uÚYql—KÞ¶¾ÅðâÎk“PDÄÕ€²âV °¦Zu‹\²®ðfzoW$xAA)¤bˆ:¼¹{â‚ímÓ$ Ä%ºtKéÈ¥¹D­KŒÄ~@(¦ÇB±'¾9]v³Ö€„̺}¬–¼ú„œC!ƒ°‹WÇï Ñ+N´z¦ÏÔõêŒýp@{!´TzÇ;D± À„cÕúŠWjheŠÑC®‡î\f¡ŒU2[í$…Dé!s#C|NÛ4Ëê–,Fü²@8ºsFw†xV¾1µ‰Ù˜- Xw¤¸ÛS|è6,¡âzÛ"ÿrØvaˆÊÌ¿9/û$.,KÔ‚ð?…Ôeè%oÆô·MMSÝèv[FBñOâ ß-xµ×¸úƒø±-ëß‹Ä $Á¥ŠGî`bMÅGÔN7 xÇã52zë‚&±ºÇ¾‚ç-(YYñÌÖ¨ðð—)›– ,nÏFä3æ%ž˜Ó¡€5—§y/s’=uäL…gHs… ®¬Ú5˜ÃÑ{‰>1§Ø§`¨®ÐUjq%€0K6Õ4DN.mÇÐÑUý†(SÈòβF5)˶·{¶ÌÑ–µÈh0ó,ZÙÿ@Ýu‘ÆË‚ ä þ‰šopTq2¯y6xäâ"<º”FY7þ. gX¡7“ýèœ×8Ï+ø=gKüuŸô^¡£’ €„H ’®àü˜B=‘'œ];>ËÆù×Ë·3©4ßÿÉ™ë_•¹1˜þŸ.! T E\†%TS~/Þ…w¦ñ«+Ê÷Tßaó•¬y%[þø…_¥¡ÆÒ;”j¥ Úv,™ã|§ä. ÖQ¯ •¶Á2"ƒhö•F‡Cx …`@÷ƒûáNÔ¢m Î@ErE5‰…p‚õæ‘^Mš&;e ó×+v%¿‹C-ÀÐY¶ûȶ5öZ”p£T?<¼Z•hD=a×\A«¿Pï•F¤¦;±Çk„:¾AñtQr·è3¨Žñq5 âk­„Á£*~Ï!K‚Â¥ÅdɘäÍDá?Y+ñ™ é ¦; ¶]…¡’æx¤úÊàPõ©Fé>ËJk>í¬ÄlãÃïPU`€MÝNü߯Ë=]±$]|W@qÝD“kz;Ü5<·<¢!ä gwÃfœ°PÞ…ÈW|=`R¸z†…6Ì“QOkãQÏ\⺪|ùÅ\ 9²=>]ÔÒ¤DŠ‚Ð´‘4ç;Ã=È…Ý»èŸ\‘Qc/ö#¼˜\1­]H{ïài¥a¶<Ë…H²¤z_ ƒ™¨£!†d޽^ Äo(*©¤Á3 ®T¡Ò)OÔ-ÕÖ-ûíRs•%‹-Q¶²45 ¤dæï·êT5E](/²;y°Å¾UwWW:§€“-A–wMÖ;9dŸt-e.ÕÊ!dŸL\#‰[wI‹KPJ©y= -:…+{‰¥ÙêßôM<*¨ã'úŠ£)"© ‹ØµŒV ³C¡nh-©C*ö5Àò…e'ò* 2η­!Ô̲] I%?ãÄ”‰ —È…?ÒJI¾»ôÚEÚÏršE[©XÆÌI›«ˆ_£û"³ÖTtÌ( ¶ ó˜x9 5‡èµ7¶ÅjQ€@h6¬WØÖL;6½`kV³~’n–í‰æ‚"%Í%`U5óuî[ʹHoýÎÙZøŽÛH#ØítZÖ¤æˆß½!–ïÉ›ˆLÅ÷cÊø«"ï¾:¡CƒÈu·¤{E='âÃ\}hÔvæJ^œ • kjµºF}«!Nx÷j oƒ¥‚; ¯µ\Gý›¼©Ñ7}µFz=bò‚ÖP¤}ñÉôH©z¤ìõH =’x=b!A2Ñ#…6 G2¯F U#ðÎEê(C¾R„“Vã¿ÕúñEÕJÞܨÅV~¼…ÏúqĽɠ±I6ªS LB…Ê«S’#6çu C$Pýîö« ”´¬O˜q|úô!âdZ-!½=g0>> ÕÆÍceb@µ8Ô^.°z§7Œ-H§™õø(³zgõ#Ë_ìÝs~áÿG«O«ÉÌÆÎrCEúÅוþ• “˜s2ÍdæŒT…ÛdôŒÛN/eØïÛ3>;58ê°”ÊW:‚I%æKœb‰ë±ÄKŒÇ’ ðaK¬6€%†bZÑĆÿ´HBÁ£ðBÐø¢ða<|Xú~É1|OKû5àCHÊ…GI`ðƒ’–3$†'ÐÃÄ%áÿ=vRÔäCøp7Ï*ñ¤£û€²ü•P%;"i6ä领 ‚7¥Ç<ý'¤"¸‘'¨Žýf6È É~¥eÅXréèx,ex°w6žB#ÃãIäÅ-ljO"ç³Hf}×Jà’3mhRz¢ è qC@?(ƒYrÇ”s…ÈJ‹íúðULlS›Š_¾£O)ˆö$x\­š@ñ°O ¸ÌÉÆX¼¾—²½Ô°í(FÑÉÃÝÓØ™¬<‡ª©#ÄE¶ñQ…Œž ŠÓË_ö{TzÏÅéa Š¡Z)q¶=q«8HœFÈO ÿñÙ [m7`¸Ëd“@ÑR(ù¤\œ“T|®}w+K™Z:FÕKüÓdýÑr“2¼ï/*™àñÏÝí¡¦5ñ´tÅaTÑùÓÂkÚE‡¸\A‹ÁãóÍ <°ƒÜmÂÇŠ9´ ×u\E¨:Ò`ZÃ4Æ„ ZJ£–%:4__ƒ‡áj¼á,¡:G&£úçÍÃ6â·!h\Éq6:‰å¼U†ßÞS)ŽD,7¶†ÞéPsXÍ_ª)½vSäaˆåö©Š^VM³ ]Ai‚wra3_‹¸ùVf’†TQµ¬2eÖ{o¾/—Öf£K»{PÃ-?m.b‰vZ_óýÈ\¿Ü­n6X_whoQ|?ÉêO;9œÁK|Üè¹e®hC¢Å²f ²œK«îôXó8ÐË/È*±Øºªü5pRÙPŒÈÉèäƒér[÷}2¯»Ûz2ЃQ5Lü8ü$HÑd’0Ž&8¼ÔP¶Qµßv­vÑzé ôÑôäúd›À?âþ+×í†i ¯¨Oâ"i,Û_¢Wt\ ˜fÈUÓ!â~¨:U”" Ó  þÞ°THñMâq}Ù—´§¶\˜á·Ìö…„ÿ^AyTÌZnÈg†ä¹U†w:Èý,.]^p#ë)¢¾è §ç3ry_­¹> áê$®è©?K#><ú…n†|´ýÙ“!VQÚˆ*½=:*±$whûâ·wÖ”Îðá5:¨ƒ–åÿKr ŸZ›(F— 9”±û( Ç/Ãxö¡ÆŸ‚Ó„ôÜNMÏœ“+í”ÝqÒlÐxFƒ¼Ë÷wäãêq¯½®¿ ôŠ¿3XPiš@çÔ2'X>I[쯤ÑÕjÙÏþŸnÿÀ"  AnŠ™˜ý»²ƒ" LcøMtÇe”j‡že¢W¥$ 6•l·Å¤5=H^oƒéQ¬pv–yz,S{,9ÝøúË­~oô÷(|òØæÓA…œ–þYÒd=|τΥ¼E.ùDyYM‚ŠïJz»ÁÛj³©u"…›Ô¼- 5¸3p|©_­ìÀ†ƒªº|”õúsÅ ™…7÷,l 8ÜP%Héûz6»ÔÍôçg®Yxu#“÷×\ÿk?\R.¼Rv÷'z‰ä\þ†ý½t‡Œ ­P/I­Uï` äK­¯´!d©I6QT¥\&~ˆ¸²sT9ƒ>-‘j‡Ú=!U†ç €÷+Xà(ÏðöUIj¯¶¶°ºfÄçøÀºà­þEàô0ôö"/â](ž#‹ÀñuF¼÷ÞŽhE2–æfGÿ¢ÝúYYî9Xèé{Öeù öθ¯~½‡‡ª|Ó¹Ü:Ö!©"|”ÎwÒ.üœß:½2uY ®"ôÓRp€·jSõ›Ê/Ñdÿ¢ƒ›:f¾zU¸ìÞ—Ü©¦¦rßj~GÞæ—æx§úÍüäãÍ3¨q/¾¾Ÿ@µî©®óTzq.OIÄiC·ÎÅJøIP3µÑêJF2âF—»¿ßØüÿé·ó€Û÷«N'ç±áÇ¶àø€ì»„3L(OTq†WØ0%WX¸t‰!€§wÁV ª©V ˆ}ñI1‡¼ûé›ÿ ü„gª endstream endobj 213 0 obj << /Type /Page /Parent 341 0 R /Resources 214 0 R /Contents 215 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 214 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 291 0 R /TT4 421 0 R /TT6 289 0 R /TT8 290 0 R /TT14 297 0 R /TT16 298 0 R /TT18 299 0 R /TT20 300 0 R /TT22 301 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 215 0 obj << /Length 4515 /Filter /FlateDecode >> stream H‰¬WkOäÈU¾ö¯¨ì—u­º=®²Ë„v±É<HÑf'™n7x·±‘í†ü£üÇ|ȹ·ªÜ††e!á®×}ž{êÖO—³W——‰Pâr=SZDøÃ'Éó0Ê£TdEê<ŠÅåíìÕqŸ‹eÏ{"Ñ/›Ù«7J\÷³(Œ"Ú³œ-üÏûÙ¯Á‡R.â0 ®+úê@$™üÇåϳ‚"‹Â"…’8w‡níy‘(ú•ZAÿ:б O!®ÄÅC3È…ÊÂ"¸©ú?ã0 zñ㛹øû¿å" ã «—7sqq_ÿ¬:ì0ؼ‘Pe³’‹? ’-b·Ù%­B•¤Æ—'Ö•³5Ö’ûûûPÆaôH¢¤Âÿf¸J}íì¶å Ë?½œ)Q‹™N©Dœá#0ˆµ ‹rÑU³õì'Îr: DÇFŠ~ #¬ÌD¡Im´v™à°'dhp^ Û®éäåo,-uÉ ó(ƒ6ò/IÉ;uêCM§ÉêëÚN,¥Òˆh»ªæ¢^Kx¢‘9\jmRÑþÎãP¼kŪÊ^+A%#ì@¸£íÖž]‰Ú-”2alya¹¬Üد»/E5TÁ½D† '|³ñÓæè*ÂzÎ!ÿC¥M¨*Êdáœ5Ú9ûJ²à=ÿ¿$ØäÁé ›s?¾¡HäA%n¥ÊÙ„/»a‹üA÷`w‰5bwXžIU@â Ë=€Ûn¸Õ$Æ·{Jø¥‚¡<òZ¶,¶k+‚«Êÿ*¥Rˆ@k.ËA¸•Ø´K·âL ÅÎÒçÏ_¸õfùö¯R%˜ñ+Usm—jkbS¹Ú ̤ñ™±:síŠBf¡ jJ ʇŒ‚%øÒKþž\Ïá+ïëïÚ¾zÏ¿¯(­ið§sÜçNmœ˜¡²ßÎͯ[{ʇ;®z·ÑÍ·^zµt‚È/š@Ì0l%A•ç¬uß²¯FÁœuʯÜÀ¤œ“xQRü‚k;*ë&gR£H½>ÑTÕªq¾ bhÅ•×PnØ—<öueåÌ'±OÔ|[ã‹iÁÖkqi™º¼€(”Ö$ÆLTŒÂšçÝPœW¥,0^I"«3B&ƒŒ›¾ŸNß¿wv˜$6£–Ce”/¥÷À2 è§Ò -«j|m÷ÖV_óˆ°°©‡JM©£MvàwPëA|t¸©¿²´gç6ÕL2êqjý‰ïÎí-T®ÿËf»K|¼Ï°Õ—9™Q;F΃ƒr³YCÀW9"ZõôÃßÑ>äŲ¾·|},éîj›B/¶ww­½?»Á­ ´!76?äN'2ÛÄSÆ68…ô{Õ}”¼dkðÅÎ +ìu—½ú(¥ž^îŸNß¡J] ç¿È¹ûIø™ I|8í¨72Å·%JÈÜ@œs§UPxíü;[;:ø2Ðõ &q_Ds¡3ÄöG©µ£!Ú÷€¯!æc`;ÑÇNcc?^œ—/|,tdc¡“Ö¶a#_ãi¿V"/dÇÀeǶ†_xvxÖ$Œ#5‘4ii‰ æâl¨nÏN„ë­¼ q˜*öŒÅÔ†3vM£öž(§¦¸XG…Ä6a…²gç@[Ûïî>0}·5;AØér{ñHѸ'™QúÈB-ßg”ÏÛ…ïN³Ç”H)e¹àŽtÒ—~sÕ¤ãjb õ¶“u£qñ%/ÿÆòD·v‹Îs‡ŸYFCýB­DS>©&ÀóÁ÷ÍcŽòXÅû¹ #kŸ¤þ¬!xò•Oôƒ•ö2ƒ«5*Ò]fõ¨‹HÌ6””´íŸ¢mNÍî¼2#<µvø¼jÛÍSt¢Ì dì<ÐS½¯ùþéú½‚…ÅIá4r|ÀH>L¤Ñb¿˜´W0võ+€yþø7–½nô¶Ù×óÂú‹1 nu½{Mè]+»jý„ZƒSné™hc ϱÓ67çJþ¿¢{[ãb/z»ô…ÿÓóEþ,¹Ýw þq Ò<>f:Û;°ÏÐ`á7™¦ŸèÖÙKµSí1꼘ãyj¬2Õv&Œ=Ù34iL2³cɬº_x#©þOpLƯm¡ÖŽ“;ɭ䀾1à«—Ð÷â"ß.¾Œûç}ÕëMb¨øïWÙ,»ú»ž?þåIDÔXo¼sÏ­çÖQ”–ÔB…Qµiå¹+Nn>Ÿ§{žDifóþ¶¼ó¯:ꢵí²4?@n¸¿TA³¢ÖR55•´ãÀîo$õG7­ÃîqhOáy÷ÅnÜv꩹ÅÖÁ[n½Ñ®ù݉þV¢KæŽ/¤eÛ<:<Ê¢W$¿×®°ݘ_$„Øš¾G’ÅØI4YÔò;==¸­æ“÷l×n‚Ú)u6_ {O—±Rqa£Úã®RÚêb ôºuâ:~8!H´­äæ®køù°®±F>اÓ0yO° žS ½Ú|ÌÏ#"hš¶¿zZ÷ÊŽÏØ¾Eo‰b~ùQä3z2#À¦ƒ‘¶ôHDn F’¤ãíM ¹=ƒL.3‡HвLÒ÷h´>õdZd¦˜4}ùØ¥;.厜Rs#sè /ÒDo  ì*­ÚÀƞؾpÚ8“éhüäA½Gž{SÏÔhnÌ”ý<Ëâ$ïˆv· jŒ·@¨_ò=€÷':–IÓûœlòߌþçÿG¼—¤6ôÞ´”"÷Çá¦]–Ø;?ììCM,©C܇ ó¢t³ X‰Ã5a_¿pÍ Mø(ý¡ÏV ¬IÈì52m¤KMðmÂ^†|?ì¥Ýva&w§ã’Àî^“tÿÒC©ì¨2‘·¦’ Á`PÁ½-ךw ôFËÞñh„òBuÅn#jlAä5Œ·±Ï`ÕORy²üyŒ|_i×…âo%b¼”ª»áXvUÉ>,]Û¹x¶vÓÚH Õ<7ÌAV†ÆiLá#mCØ`±y)N ·UX°ZlµS´xþŸÆ ÏØÄdùÿ)`\Ts*ªEXà“'5¼ /TŸí=ÔðGXÿ nø~¨‰ã t÷’ð3‰ºŸºg˜üˆaû*|ʪ‹ ÏM͘PÅy5l» I\ðZ’ŠèÎF3®v¾ýÉFêùb¼‘LF.I³ lë±Óó”8HjÚø–Ép£H‚…ÌŠð}Óú °“qÙPIŽkü$3\h±Áœµ[(ÇûŽ3š”éÄmôcwšìçrñ˜ÅŒg±’À[Ÿå‚ààFõæ?ì—mkÜFÇ¿ŠÞEWœã´’Vº6ÒØPƒIC㣜t¶àNg$9q¾}þ3³+íéÁ¾>P(ô¤ÕjW³;³3¿¿yø¼+èp$L€Cüõ®ÜÀ;|½ýYM`jý÷Ù|n§mšò–»4–MUÔôç’L¨¿B•ƒÊÑ>¬—“¬ëèå*ÔœëT’ôÞ“uÿ ж•¼i²Á6Û!*Aâˆ!rÂôfËgŽÒ|*©Š²ŸœÏ½JŠ+_X/SóŒï^\/µVÉ_÷dZOF¡Ícï”a‘<îJ£êª%ã[8ª¡cH ¯XCì5öÃÛʼÌÉ?¡o‰\ŠÊKÎJ|r9ªs´­p¼SuVAWCÍnÿþáâÜûõÝÕ'ÊÁ‘%p’âãZ*ê/ 'Þ«ûÝÃ-UHâJ‚¿ºÉ¥ æX¬ ))—¶yY¶Wà24R-«×OSZ²ÓC‹ÓûíF/›~sñŽ(ñû„]÷o˽ì5öuMÁŒÒaFõŠ‚M(!%ŽîÌ¸Ì °½LGV3†ÊD‚×Õ!#…s¼ Ž,²_¼¸b¡wp–hþÿFþ3Ø™ñ%;é¥qÍö;uªLÑÁÍ^,ø,²žÔ :MžÕ NªêR9±u¯GG 3E]#+ q¦É‹3¯Ü †pü#à„g;|êçˆj]°gÀ2Ž%p.€|ͤ祿XÞò›åp\aÚ2ùíßìæïÑJÙ=t"ö"ýÌÐÚ°ß7z«¨8Jû'¶Ç¡3¿‘d#Øl Ós·T†•ï®mGô¦01›²©‹¬-rqÉ\âW1€Iÿ'aQA ©• ‹½éÑ,jü…p‘¬`¤7@FÚ,Ƙ91hLLÃ@#í{°ÚàÕ™o*¹Ý`Yä>Pf.o³{¹3$EØ1ªè¶U˜ùö-#‹–ݤöÃGó0FK£Í¦Ñ²aˆtÈ’IóD´ìkÿJ…–-3®„”™HÈš‘ò=ÍŒXû[d©¢ÀË•[Y›Ë–3USœªõÒÌ‚1R:ÍHyvL”Š(h–æ{‰ÛLï<·Í ¦Ûùw‡ejrðD7¨m&èWHÖijáº×Úê doã*zöSV€Žé \R¸NJ†NŠM>ÜŸsªŠ…ýýLMø)Z»z'²'2Y÷‘D9ÌšŠ*IؼɊÃ~¾X9ñèÕa#Ù&ãæs®ýÒ¨™mšç¬TI·‡¡S䨥—U.Hÿ(¾Ž —¨“ÎáQÇã]R~Añ-¸Uµå¶”Çz|É&•“ZEË(šµÙ^Žsé}"Χ‡?ÓmÿMÉ[=è3ý§é“ EŠÖNØ÷š2u Y±(àš+ê„ ©“ȯ@‚™¼¹çÄØB£TfKÔKÅÀEøb½Bï9"hÍLÁž¤$ì…=œÿ¶’h˜âN–i»çtLUFKh_ÀÆB’$‚#)•óÐ2ŒÐÏÇ¢‚ÿ;XÇQÂ!MAs_¶ÅþÜ<·æÈm´-”ꤰNQY,-Áþ\ä¾!D<Í­ÝGAÓ¬›‰e£ŒêªÆJ;ÁHEÂXiµá}áV¶ ¥ÖÍ„í<ïÐ+áÈ+‰™ËPÏwNÒõ„b×+çÜ¥ki$º‹ Ô\$b‹š˜?!,·ßøáŒ’Ž>V€ VI}E] $1¼Fô‹Ä65 ièLcEifé@cQ¥…ÆbP–¾˜ëƒµ endstream endobj 216 0 obj << /Type /Page /Parent 341 0 R /Resources 217 0 R /Contents 218 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 217 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 291 0 R /TT4 421 0 R /TT6 289 0 R /TT14 297 0 R /TT16 298 0 R /TT18 299 0 R /TT20 300 0 R /TT22 301 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 218 0 obj << /Length 4898 /Filter /FlateDecode >> stream H‰ŒWmoÛFþ®_±È—Û ,†»|ïù 4VÚ˵—µ‡^rhje±¡)¤b«ÿ¨ÿñ>ܼ,%Ê’ì°¸/³³³óòÌÌÛéèÍt -¦‹‘6‡?ø„iêù©‹$‹=“ú˜ÞÞ\·©(Z¢ñE[Ô£7?Þhq׎|Ï÷‘¦ûáÃè³ü”«qà…òÎâ×H`«þ;ýÇ(#™H|/‹á’ u‡îù¼IŽbfô‡0¾Š1~2q»7ÛºScx™\Ú¶„aà%²ßÿx!þó?5޽@6e±¼7e÷»m€"âJÁ¡Ìë¹g0–$=›žd´§Ã8ùtÂÒ蔤aI<x±l#²Ú* ¿u·„7j#Û²ß`²bIüßMGZ”bdb êÔ"Hà#`¥¢±£Åè-YCÇÎÚƒG“h4›ºd²¾ö¶ Åi§¸$dq?¨^ý‘~§¨–X¾ûN(p7_*H+î•Î<--IK7])¿ÍiÄbÕˆ|ž¯qÒÙ9­µJÁ²MIŸúÛžÙ†N·¸µ"¯ˆ¢Z ^cd®|Ùðl.ª-ržW]é‰éÒ )“7´TÿüYX¾ìnÀìõŽäʲT•ØssFƒqã-K†íÝ,§"uýE¥r<"Y¶ëUk?Þ*m@¿‘ƒe°¯S/•NUŽßÑ\Ž“Ènåå½Êæ­ºSùóÌËÚÑ–*A.# -GvW%hVÝ t„¼I®‡Œ<ñ4¶9$²hdÜ”µ»²‹’3× Ã×õòv›¦fb;7,–yÏÂÉ3îíí@³¡Þ©6<ˆ•ÑÉ á=:yÊNžO3à ÉØÅã,‚ @‚zHè1aöîÃ!@þò+IJœ žÝÀ5Ûw †7jÊ€“­Ô8Ä'ÒDP˜ÞX SŒÜV¡»—ަæÏŒ¯—<³Ž´ø:QˆQòÍ-•…_¤GH~}Ȥãeû袺ñùé&ò‚$ˆ†P“ ÔÖ^ÓmhP8![üt¶†Ø>Qeè>A¸3Bö:Kœ_€ŒÉ…¿W&†Ïz}½ÌU„hù œ%920eÃŒù„•Éoî[¢ƒ$²°ïQÑ0š‹™úI/&ò’júBdBÒÑbSA°8Çw£x·Fì`?2™—†g¿°½» ™º]xÝñéÓû€ëgü< à ƒr4Y¶K¢¡ós4ÏÞP) áM¼{EÇöBÒÆËÞ§& ð Ø ’üÉnÍcà%;'ÒñN"ô^”Cn‹œLㆠˆfä'tM¢áì„+p†‚Õ«ºÀÓDÛ ¨*ȆþòE:LœB¸ž³ÙÙMtÞ<ï-§?¿Ûß›ð=ï+çöÿ\ Ç‘—˜½ã@ˆºXÏÖèõÒ_´uŸy FsÂmH¼ù-ïQ*€ÔÐ'[cÖ0É`ôn‡ÕB\rG,'€´UbÞŠ)àu&'WŠ+Áé$Ø¥àPÛŽ©[qéÖÁîŽöŠS‹h!]d=a“†ŒGw-XDq™ŸÏ4e+êov½ÆòºAÙyü>µÃÍœØÃÛËŠõ–b%iP]}VïJ^lîx:Æ¢(ᢒÄ(©ÛðVS‹W ‹ÙW¼) A39ä-Ô”ËùÈü³¼T˜![x¤Dxä_p)Ìc˜²ð»?Þe„( È ÷­„fi)»*W©L/‰©<Âú®eÙy©\ÕD" 7è¬Òa¾ìŸ1v÷>y‡+ ñ^I®Iþýä !g 3àl–¦™Û'sH2c·TŸ¶®J…ƨ湘ƒãW¡¦x?LÃâzœJ&½;z„„œ8Þ?"˜ú²UXÀS~RT’l]n>a‰LGÉý{T1ƒ'¡ — ”/ ‹Š8š2H(èÛšr¿øªç>[n¨ì¢f_Cñ^ÍüSÝY…¢Æ­„ÒývÀYlp‚oÀªÇ\AxÐRδ]Þv¼ŒH@J/ Û¶¶U…:¤Žc/ 7?Qà°Êa—Æð³Gƒ¾3Êö Ûu`~ßS.ìµt@Þ›’÷Öô]¡ŒX/â¤@ŸŽ°‡P %–°ÆmÞѯ€:Ü˰èzfUNŒŽµ?ï˜Ùƒ-þ-‰`ÅœÅ{²hÐsx<`'ÑJÛõ¦ÜòõP*XˆL9Ð}”•u‡»î•«œû¯à{óó]Ö+…>f5Ÿ²ÑØù)á4$šÛ4Ð+šYȱOs<€°8Mz†«Ë_,&/¿Ã¸?}&Ý™ÝEŠ=:“+"$Hlø"P\Öã‚0`ûm9§éõÐ[Ó싺å øüºÚÐâ“”L2CäÀAI5Yaó9ESˆžq=žRó@k‰¨vi†v‚7ù–õzÕtvþWáD@X‘ äÕ–»Gºaž)þ\…`óAã§{ MYÿ"ÀºQýï&4éó~V¨ß_yãßÎù :Ha>Å4–É¿óæ%èï)¥àPÖ³9ϰv UÔÝ½Ò ))^ȳ}ùÁ“f5~ }³ f¡v¾®a…¾.á¦üÚTîø ûÕ„úÕ€úÕˆÐ>3Zä~1¤c6§®³o^ÜDl=<×Ó<ºëe3îeŸ#$©^·´±Çf@‚tØ}œ\ƒ£b€w þ@>:Ôz¡›5û>$t³áºYÌ»†DSCCC‚œjDÒlÏZ»4× ©±ôŸ¶-¹ä]©˜B?@T…2¿‡ú&9îU R=ÓÛF`¡óýåù]lVÜîùnåÌñ¶wwÏö¶çöÏö¶a¦q@añYNÞήóÊUœ•Âô6/¨Ðò+º'ìúÄù°—•íõÛ•ûñ¹ö0¼È>óîó»¨s·{^çgŽ¿°ÝëÜü|Få§·ÿ\‡&Pö†{p5¥ ¯Oß‚C,Щ]û2·‹|SÀ‡rßÑ0Ô'VQÎn[lC Ð¦‹{Ì´õ¨e:ñ€8šq³IfXñDÜZáXæ sE=çYuðm/ÎþÖjÐÊÑ/‹|Ía]B_|-qi°–…õ^4E”ÁÜP9H¢ó‰Á3XøÑÔ|¼cií£›ŠÕâ‰B ™žn ¹Šð´N]1€©‡Ú?LÛâÓÜ6ßTV<”¼ U 3$åð-›ÔÁÃU]m¹4¾PT3•tdbfkE‘m¾1ÕÍzyÝáµýÛ«5ÝmÜšB:©±ý ¡ð]­Ž°—×sÈšîÀŽ”OÖ³á+®ú#,X‹÷';>ó©ÔölàsPÓ׬<ãÜ4 \Qç7Ö+t*î/7îré:w‹tO,g«Å¬S˜_—v¶æóGŒ.ùì›uE”j'Ÿ½Lð‰/Êc*7¿@L™à lÀpæ©iÙÌÞ§&Žu ŠçjÛc†¼µfáV<ð®DçW²˜ˆË÷;ܨ©/òg͸-]Åžvæb˜v"êË\^ 9ªßõ½Õ“ìïœÞ–Êi+`E4”N¯ìCm啪fâ‹iæQff¨,ûe—&eϸ,ò” håY2Tª×R?ïÉåô)÷|Nà'›ÛQ3"çô(R§_,ØË‘wO¦Š‚±¦\ª"-ê<äËëRBY5Ã8J–½ é¡£ À›÷ŽÐÀû’ÎèÈÀ¸VhŒÂ!~b‰Dð‹zÌ€ùú„G„YbÉÿÍM °%%̲ã úV6ù'ÊœRe¦e„ œ8&_·\v—H¢2É´uÒBæÍªVzãìCˆœÚV0~)ÚÝòµ©ú‰Àz··¥ž°Ö·»…˶Ÿ…»$+nGb5kJõçž?œéÁ@ˆ¬¸¢hšºAßõ©ó‘LŽ{ÐÒ˜"e@Ó[~«x:7²¨–>Ò¡o.b=ÜPŠÙ-Kg»« oE~Çÿ®ÜO2-hh²2Ò g^J`)@gûó1ƒu¿³»…óSOŒ_. ëCu¸«QvP¬=‰YzŸ7üyŽÁ¼Ðf³$Á¼ORôñ©ZÜ¢P¡!ß,&\Ã;Óq­.ʨðŸ/çúF— ¢F¦{ͪ¬xÀ“ȆTKý§àPKɵ1¤’’ªCýCc'v9i£$•¶+ºè¨âiQÁȾԻåÿR*Íš×yñ ³!M.‹Õhé¯é´¬}Ïß/òžx$_M òãÆßüÔ!/=9UoÍ?9™ïR:žœ#ÿ¢§V%zÈ kÆ‘KÖ-ÿwºs¨Ó÷æ4«ÊÝ…¾cÿÓ©aå.úCÒ®@sêÉÉ t¢£\_.ø¥PsÆ¢Èab¥@º?KSþû$ˆùË@k%ݸ’~NeË{åà"Ÿ=õ©+uvÇ€§¿*¶­í}íÛ>¸Ù[ÜáÎù3RƒÌ@X0ºCMžÎô¿’÷Öºn!BUÕ‰Ž;½‡,'ĨÀæw¿ón2€þ_(~q†6á-¯E À\ {QÑõ×Ë 0ÕMþ¥ž¶fªF‰õïEÅNã9:SÚÔ_7bÉÕƒ°åq~8sl<|͸ϪÞlAÄp”á¿dÌ!VÄlE¨6Dbz—<;^ªªFñœªþ^.H4ó>9¨çQ×'’àÛÈÐ3 ÷2?TsÍn8c®wqÅGGÞ·?eÚ¸‰K–?Ö6 §R-¶YW¼ª•@hyPÖkQx*¡$K*ytò8!¦PȦG™§w"³ê$ÂL͡˹\8 œdÑxa:ʰ"!BrXÈ1!kLHãŽï}í Nê”ågW¿%v6O}„ävª3›š)ÿ7Åo«×¥QÜKmá1’GA6KíÑí¯ˆÝÙugûóR¶L¤/Xvxû+âÞ+„nUˆˆw¯uPüñêYq=‚›‚9Á»nò÷‹îiQ†'Œó@¹€¹ùs‰X´XŠÕ6¡r0Äp$ø*Ù¹¨ 1ÎmÚí7r@-剸̱ýï U·Óïªd€ä–Óózí^+k]Ñèq/ÖDÜK­XÈ­œ®~åœÛüŒhB9™crùuÑ0^ ¡€z)"Æ}š״ow©Þaâ`…˜½#g'TNø^”‘kå¹GWí,¢QS ýÀøJǤR ¦e’Gƒë1Û.S%_ ~Æ%l‡ïÑXÐÀ¯bNv0Û÷w¨“§cêD.`*ᣬ.¥}ÀHËFŽGL£x\ñ<Їè2ˆYE•²¢`‚ÐÞ´bqþ<åÖa ‰Å=Fµqœq»€K¿ý)dçÚõ£½¨”‘TŸJ½^•·û'ÏŠœ!ø­û‰¶ð7@Sÿ pêm6'w Æ ÍWʳdß'ñ¨Ç‰K±K6BLÄ¿Ö[N6Ê)kÚ R¡ŽüãR4•o6G¶¿"=w­ˆÊ¡݇äÔnž—Ê$ÓR‰B F*Ð_Þª\N"ï3Wà*“;Ÿx EÎKh‚’žG¯rTÊné n<¼ý±;;˜£wãùuíŒ\3\Dס«éÿnJêœíg»/Œ„Û7Z 7U©‘¡p^÷¨CSËË å_T•vѲcõÅýÄϨkRÿ®M~s+›L½í6[§i£{»;Ý{¥ÇS–‰¦v‹Ëµ³¬l'œÞ¦Ô#6•;¬ š›5 KÅ»1¹ÞðfëlØl›^0eÄIPt4uçq_š•“Ôë …Ì ÷ Akró½ÔI}˜‹?ˆbyW@ä´äã™9ùp~~vjnÜ®NÞZ›Ì¥ ÖË/ç¦ ßqÕ„ìV¥lX3s²p(ŠÚÎÓÕczlÔ€BÇä À÷#î¥|Ó¹Ëüª‰©‚¿ ÔP–þ=¦|å† endstream endobj 219 0 obj << /Type /Page /Parent 341 0 R /Resources 220 0 R /Contents 221 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 220 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT4 421 0 R /TT16 298 0 R /TT18 299 0 R /TT20 300 0 R /TT22 301 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 221 0 obj << /Length 4168 /Filter /FlateDecode >> stream H‰ìWÛnä¸}ï¯ ò²Ô­)ê63`Çž5f‘Ì Öý’¬Cî¦ÝZtK†$OÛù£ücRR-÷Åž]lhñR,V‹ußÏ&¯f3#”˜ÝL”üàcò<Œò(Y‘†:b1[O^v¹˜w$‰n^O^_(qÛM¢0ŠPf>™úæfò‹üRÓ84òÖâWKaŠàﳟ&)(D…E ›Ä¹[´æõ:CUØJYÑ?…Ž"#¦ø)Äõ£¸x¬û`ª²°KÛUÐŒÃLvâ‡óñ·Ó4Œe[Í—'âbSõÿ°-H$ ¼ `#ËzL h€J²ˆÜ&—´ •I3èÏÎØ•“5lÉf³ ƒ8LeQÕc à¿î—à£Ò²«ü‹Í—¤ÿÃl¢D%&:UN%â >:±hQ.Z;¹™¼§ÓК£€èp¤°¡¢”£•¥φµ= ´Ô ¡¿È· ˜Áþ§A¡h ZdøûŽŒ‚­TÊ[™0OÃN£¦XmS±çb†‚ÊeP€z+º E•à¿Æh$°UMM"bî=„"§ÍݶÞéÛwŠA7éò(…üm‰ç™ÈÕêÇÊ®Üé¸P¨$ÛºÀÑ trY$úö 4 tˆ×¢\­¹¥ä DJÉ Üçp›„NÙÈêî K©–Ê5DWÉ;íéÈ Ì…õ6”š™¬y·îÄï± ”ÂÁ®×¼Ô›âöãí;§wUºÝœb'ìdßìSóK–XuöõŽ«_òZ¼}'þDÛ+é¿bhÔO$`Öý÷»'`Â8"ð X1DG³¾"@ˆï÷,ŠC¸ñÖ ‡ƒ¬` YÁZ7m€–=î‡E§n5åe€‡ Ø“@ %Ò¼Aáf:/M&©Ÿ4I‚°5šNtææØâçgý¾œÎï˜%³xö»/azß¡Á±¼`ƒ®«¼Ü¸J«Á_ûùšGá‚+ ïÖˆyY;®F`â¯É–¬hGVšùü¾  —½ \YCx@K_aµ'Ë7TN+tªP-Þ2FuA×>%ÒD±~àﻃî^»§,m8ÝïN[Œîò—²uÅŽ‘Ø–y,[0ÕBÙÞÌuûe~z Mž|ñCÀ\‚FÃÄì‹Ë-¤Dùp’(6zª›°køçóˆïp~m©¸ÉÇV&Y>®Œé`¥qVžUˆ9qP‰äà0¾™—½]ˆ5¤G)û:Њ >QZ±FøÙ;e0{§ü€vð4ÞÁÙÌál8ëGàf!6|hù}ÓÈØ sR×!v"×èˆeTN¦æÏ ž3Zêôœ¤gïýVÕÚ:ð=øë°ßøøÂ‰‘?³Æ¤;¥ËŸÉ†Á»æOéñKâ–œÀe€,ëîîtÉ­ö Ýk(Zîƒ1l”Äcûâ‘}ó{ô³-Å®WÍýžI0 ûPlðá‰rÇàl«þ0X'€¹9†MÇgÝìq\<²ü…i¿·IÃü7O’]4ùŒY??; HœëcóßÖI¬ÂBoÁšëÏtüº<2zZ"Hô„1ÒO©B-H•ê^œ‘èû %ZJðä` «hn‰4dfGE°(ôh”94Êö_‡q(§Gdþq(Þ‚z¤F@„%l0€c‰•D.:¶‡ŽP„à==îFuã˳‡$¼èP9[¼àXÖèmò~V!Wfß ð8‰ÒÝ:4¼ 7 |äFÁRP-±550BP§ùS9Öi‚° õª¹A¢B4çõÜ­hÅý-±ÀÕcäRßrx qgÐÑ~Szð^ÊÒ¼ ²ø™¦óÂî6jXI %K¶ì2ØGIÀê?æ9ŠÉšï>£lÛ6­˜ãý(d³°Â@zåüRþ0bàæ5¾áÁ‰Ý:«±Lcï28Õ F¼¾[ÝÓà-‹T,rµ°_©Qxyç¶\P%åš®1‘ Ä%”¦ahE>K£ +ìOò.wwM \ä0”Kù)PxSšÞÛNKX´[þÄäý%å“–lpY­Êë•S~7æÌ[â¢2YåhT¬ o“°õ-µ*„6Ì ÆçäÞ¼µÀ¥º€@½êYÄu"FnOó2 Û,²fîè´Dä ïI|>·®Ï*o0ñR7¹Ú˶}ÆDW.®œqYsÚŒüjrù‰«ˆòÄÃÂ\ÐüãHjv†ÇÃÇœhÆ’Ëþ,:¬ðœ'ûOM=§–e18oàIø(ÂÁˆäøÜMxþÇø߬©—'H¨ EM4<‰ÜÿÞ%ù>Q|ÝV¼tdgÍ!Höù¨O ý 2ð„Ré1¼?>‹DÃÍgG–¿0í÷Ƥþí³dÏ>cÙáå/LQû’gAÇæ¿AÍ‚³Þ² åߊڿMÎmO„ÊûÖXªc¾ùPü(æÕ' ƒ¡Å«žÈ€Ž’ýÒŠEÉ2}yíZ ÅG$JškC‚‚ÁW‡;@ÅiÞñ¾§áª¶nÏÖ:m€?,Ò‰²v“¶e+šöÄ ܺxdñzþ—?Su¤^ÅGPõ.óÝmºâŽp>:߬wÇŽk20“ÃTXž1žU߉fScåA–Ha#°ßƒÞÃô/Π˜¦ÿ§ßBÿFèhÆœÁÈÛ=«x’bT£“Usw€â‡„âk‰M13ˆ<$ìzHØ‚c ó<‹hœœ9­µüñó#• 4â³Ëi0càŽhéµ´4‚œ1Ž…žŽ έ"…·µ› õ 7þ•ÜØ±í#ír†8d°¢coŸ&"¤i¼õßMã-˜ázÂã'ÈéJˆtÁÉ&ÀÆQMÌ« šU0óÒžy‘$±a¢_Ó/œ†·Ú”nµåäŠXR«¤iM·*µµ,!nécÝtíz %[ƽÅêgzbF)¾ºPl…HYˆ·{測YŽÖìÙädnGƉF™i£B; Vw35qVõÌnˆIì›wïŤÙ»#éšË¯×fL¶LÆ„û&Ã!½*?ê—òæÏ®ASþ•& DîÞÀ`/n_zÜ~ÿô#Ývoz‡n ÿ4¸7yo+`K½ 5šTÿPàò©,“ž“ö¹¹b¸eƒàX@×1>‚œS÷Â^/œfü™ ²»šý3Ýàâíyuç!ÌÐÀ†—Àî°& :pó ‡b#`]¶¨°b¥Ç¡ Ä”-O¡õèï‰m¨hò£ÿ!úµ½OÑ\£¥!n쓉Åàî¹¹‹Øñ(MÆq#“Im$ñÍ ‘2‰M¯pvx³q áZªÆ2>‘,1LŒòïh4ꣶ„9kÀJS!wd¼jÆ«Ÿ×ÒPæòî'ÉÒt?0žYü…—”2 y§H“;Gƒð•"Yâö¤w-KoJ¶ÚlÖå¶ÈuüÖ9d† ˜Ï Ýq±SO>Tà!…±6/ûq™bÑÛäóûKçöæú+ Y¶¯+®FCöPÞà¹kX²Ì«KÉÀ«)»(™[%om^¯dÇ׉mF’6h÷¨g×»í+ Zª;¨d,h¹tmÕ³¨oO)h{ù?ðÇÐa?ƒ÷2ÿkï0ÿL?Ò­{gäæÕ|.é>Vÿäý-…D¶d!“®H}ý§%dÀ–¼_Ö$u®'[šg‹ZP˜Ò4û ­ËÊÑJ Ð"¢© dä6C%%häç“j‚„K­«$ ãûgñl\ endstream endobj 222 0 obj << /Type /Page /Parent 341 0 R /Resources 223 0 R /Contents 224 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 223 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 291 0 R /TT4 421 0 R /TT6 289 0 R /TT16 298 0 R /TT18 299 0 R /TT20 300 0 R /TT22 301 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 224 0 obj << /Length 3957 /Filter /FlateDecode >> stream H‰ìWQoܸF_÷W÷rUDŠ¢¤\àb;¹±ÄÒs±Xïʶ [kH²×é?êìC¿™¡veÇk'm¯íŠV$gH‡3ß||9=L¬Òjr2ÒFÅøácó<ŠóØ©¬p‘ÉãDM.FOwÚ\Í[Ö‰U;¯GO_juÚŽâ(ŽIg>÷ÍÕè—àý,'‘ NKúš@¥qøçÉG/P¨,Ž ‡M’ÜOºù&£¥¨åd¡¿)ÇVéS¨ãÏêðsÝ…cEEpV¶šI”­úñõõ§¿‡c%ASÍÏž¨ÃUÕýµl ‘Bù<Ä6˜Õ‹p\ %Ù">6ÉèH[—¡?ÙktÎÖˆ%«Õ* “È-V¤¥>‡ÿuw†3j´U/µù¯¿7iU©‘qîÔ*ÉðQè$F‘E¹jÊÑÉè%߆1r¼#ž¢†Žx+s†î†Ýµ¹ ²Ô’¡¿ÏCi˜aÿ0‡+–ð–…ƒÊù¾`£°•v²•ò4µrhZ)Ñ›ËÔrr5¡bɳ°Àò¥jCGKâü†¼‘bª–5«¨¹otpEΛ÷Ûæ²-îÉ9ÜöNOëw—ƒ°ÇƒewÕÔí³pò—¡Á:ÊãÌðDk×á͵ÙFÌ.›fÙ¨yˆ¥²0ÉpßQð*LaÝ’(BÐ9®ÜE|²¹æÞQøDU'!îµÔåùžŠJ%*S:;&ðíçôä¿Âñ l3Ö_QŸ]ugÜPÞœ¯‹T•H—²t§ZÙêòrÙtåâì¢0Ÿ—~Ç8gWkÅVrš[Èj !“FÆ2.NûŒ£ùíãáÞ®zwðö“ú™³ËoBä[L(sLð) Ôsxã4䀯$jx"‡BÙÊ×#X‹έw£áv¼g…Øêrçô|dN÷& 6øðIòzªÚ7µl œpƒÓóîG“ŸÚjéí•ÏÔ ³¼Æ -¾7’7ˆóaA¾ë±9,Zȧ cºÏ£€6ÜÙ¹½<[A€ênb98nCǹbŽ`NËkñJ´NêùŽ÷,¥0>…i6¢–’ГY†V®H in ó¨4uk©MS®<5E”Û­Ó÷{çQûíR¶L¤XvÿôGįxr u_êK¡`ø§¶d s3<ˆÓ…oK{äz]vŠrÅ0Ú^Î(k Ëeb,ÔE¨)Àj¡s¥g‚ãRtbJc&óJ5¿’U›Æ+Ö<« )¿Ï©V;ªk¤¢¬ZqhÞ ­†Ðó«Ô¢ÃZ NA%€6uCÃZ%Ò+@˜ß´ó›.xÓèaXû+Ցˇ¡dÈûYÃY›”½ÁEŸcª=ð‹á6‚:Òçžy¨üî+é+|Ü( Gáf“"sìøƒ¯·þTˆò4ËåTÀ/‘ٵ̦ù¼ˆµ @'®¿FÓ¶#<ˆž9\ÇnSu;¤æà@’ Ø$‡#cü#}UoÔ¨gê;Y\]\Ñ´4h;åðó;/ð£5—?r* Ï ÖªÞP¯ÉÎ ´¶ža«{‘êÿ÷r"o^%zý*‘„–ÿ•ÄßÙM‡%b²˜î‡tôÝ—†D~¦ï>NBr zò)¿È‘ø SzˆèBŠ[”iˆ¨©yiukM$4.Ê…ºäÖ,ŒDÅ2ÜUJ±ÈFýÇBñ›wá‚ÝÔw(Ï2à£Ï;Ÿa}.p²f"ïn¢îûÐØ•җ·ⱿK]& yp\µ~VóìRòt&ÂÀhM{x.ÀàZ:·ƒþôÞV®ÓÔÜ.?ÿÄ9…£Aîí†0Ûµ­ÙƬ=cÖ`ÌýÈ!€°>ï5$€«C#/’Ô7{&ÝrÉt„t{Õ†£N½àpví[%«ì–}¿’«ž—¾Ï\/Ä4šz;÷“_A¯/ˆ4R,µüO²çˆ_â²Â£ÆÂ>C ÿÇ|ÝâM¶s6“·[¿G‚'_Ú„A¢týÊ:ÖâRgøTÊë*ä°…W4Ä0¡ÆIHẼk4vMc÷åO îÒl#·Û¥D¬½t;±Þ2ýq¿w PÙú Ø.eËDú€e÷OD<ðÊúApëß&ÿ:âo K‰¸A’býœ-|vRý,‚™OŽë>KÂW[&ùÈÌ,X/n÷¯+¯·Î/UÕ¢rÂÐÄ XpñÃàÎhã»^úœ $Ûs¡y¯Z÷&õ;Ýø—„Œ>‚XkŸº´ùuÉ}bÒß¹ï1öûÞ!÷&Û”ýç3 k5/ßÔ'˾Ì÷V;áTñ­óKeð6ï/›RU|fª:­‰ G~7ô˜œ‰kD™x†š/¯¨!bÅ7“Ðs4†À"ØÍ2ë”g€ù,PÐ’Ñy Ìï7nÔ.ö—Äΰ܌§,Ô¹l{zº™W“ Ü”óþU”G¸ÿ„çòìÑWÑ }ï}múJjÄueÓÀØ9=m zï*YB,¯¼r®¢cJãjÁÝ [sï(|¢ª“Y?àÁSQ©DeJ¾¢F¿Pfϰ„¦`º@ìpE%®(ʪ¢³R©X2º”;%BÙåòrÙtåâL*Ì=ˆ˜@F[ynxÕ+Yóœ¿òt%NÒ›}—o²&÷ä‰+(1ìírG½ãÏÿ¿eNòI?³A•È\ž4—?‰Ðó+Í1ŠÇ^=]HbGÉwDÍr¯ñ•¼*Ép³9F²yZXO«`‚ ö8Ô&>o>|’aÕ²üó@·iàÚ‚ÞFôñüŠ%%kµDos|¨ؘJ_Tf|]˜î1õ"&õáÝHLÕµO6øßÒž ùªÃ²m½¨ò²Z>SäKô+É`ÃWN­}¼:f_ÿ`¿lzÜ6b0üWt´‚µáѧ4ŠMomds/d[k»u¤­,§»ýõ}_’#ÉXËÙ=öbKâ ‡CrÈg8ì…¹·BI›»a°ŠLÝNÿü¡ÿh‹ý%ü“ò2¦)9íÂŒN?³BÉÃkbÃÇEv»S—Œ‹Ô‰ú˜“øéôªÝÀjѪˆnÑQ”"ñ¦X`RH Qá4…\Ÿ|[ê×M"\,þ½TÌRé »®Oÿޏ÷Ûë4MÉßFGQ”câp˜ýH#ë.D CÄ.áXøA0aÄ£Gѧ²ÝìµfPe¤³3‰É@ޝg2N!ÜÑ™g9û "[)xÒ…ªë¼ÓW¸æ+‹.ºÚö|¬‚-Y Ù­G 3©Îæ÷hº~QEððíf%΋ýÎ[¾Ic”qE0cùÓ[qÔØ·‰ë%–ŽYdåcHdlBAZFÿåñ;b÷Þx¨õ«Žö¨\Om£‚µޕ鹓W€ÿ73]a)M^áJ.…|> ÁÒ!X³ Ð Ç14—Vègº%¯8Ö^*¯¬\7gÒ’Ï…ÍÚë®%cSf¬I7¶zÉs3Xzòr„ù‡Ó½ÐWSÏÅÓ_Þiò­Û™ƒ»ê™Ê%ïf?.ôJ ÷ÀnÉÜP;ƒÃNGÖM[mõÍ'xOûôR1“ô–„ÌmqôJZ×rVSÿá©{Ñùès"éÅÜQ7>r–3…$#~mVm«ío+eÕ_ÿ¿­¼îßól‘e¸dü'Œ-ýîÇù4RD)Éã¤`#ëù«¸à¯Û ñ°üø/¤KTúŸ°% «vÉ£ òìA0'ªµ‡øœ°bxÁgoê3n*”›¨¨Ö?kÜT\á&·ÈâU6 Õj”ReHRºY8täâ³|½BO19tÐ÷AOTÝ 3A¯˜ýÄÛ^ä¿ßK$²öÿIÒì•™ÙH÷Øáª÷XJâãBgÛü¢»7_üþÊÖl•僭£{€KGÆF¬0dc%pòž'v~½:”°<š¢¡i)I̤Ó$61ý;âÑÚ‘'H:üÊìkr%1†ë·‘%ýâ22ŽM[Ά¯ÕÉÚ+qÉ©[¹[ŽZ÷LìrRH«pÚ¿×'ß–zï.AnÙ ïNÈ߯¹y¼H–#ÌM{°ÈÚ¤‰&€µÚÃIIÒqq¢µ1A©ß‡¿õ¡oá¼ÜdL*•Îv:/xla”¤â¡m[ª:½ä­Ë•EÒÄÑÜÐâ™ \€!>„ ½Ÿöø0ð€-q–¥O=D<©¬—${-Û*0Ïf~èÖvÖ•k{:aTãÅm5¿ÊÂQä+€‹­E±SÈ^›5×s³ßõRëaD)Êi^Þ[¢då–TO™ûFR˜ÙH¾~ü3î(:Ÿ endstream endobj 225 0 obj << /Type /Page /Parent 342 0 R /Resources 226 0 R /Contents 227 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 226 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 291 0 R /TT4 421 0 R /TT6 289 0 R /TT16 298 0 R /TT18 299 0 R /TT20 300 0 R /TT22 301 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 227 0 obj << /Length 4032 /Filter /FlateDecode >> stream H‰ìWmoÛÈþ®_±è—…Åp—ïEz@Î.zi«8´½" ¥µÅF¢\’ŠíûGýýÐgf–eIv½ýp îîìÎÎÛÎ<óílòz6‹•V³›‰6*ÄŸ8σ0S•i`ò0R³õäõy›«yË{BÕÎëÉëï®´ºm'a†´g>™öÃûÉß¼¥?‚Ø»µô5žJ´ÿ÷Ù&3(TEŠK¢ÜZËy“+¥Âè_Ê„a¬¦ô)Ôõ£ºz¬;ª³ ð–¶­0Œ‚ÌkÕÛïÎÔ_ÿíOÓ òšj¾»itÎÒˆ$÷÷÷©×‚#±zô5þën µñÚª'ȶù’ù¿›M´ªÔĤæÔ*ÊðQ˜DF‘D¹jìäfò-{²; XG,Ex„•ál­'ÄnIJv'}Á܃´·ö§ Æ$ «ájÃBíïX:ÜiŒ 3È+D&!ãXø¾ñã@Oãû9Xnà…†·òý¦g§SaE–bL–0î=Û»VÍØy‘·ÇسjQveë§4Âe›Æªù¦f𬨙OEŸºËHö$MÙÓ‘ûÞ°˜+Ÿì[r˜¢ãÉÌOƒÄÛ|¶õI`’h§Bïâ<é`X‡‚uøÂß¡‘à22ÚÖQx£öî}M‚,aJIÅ[æ8©c¢–އ,¶~æ©kkk!6¶±mØ›B² u)qô  d«ð«Èÿ…°s²¬}c`‡Íb+¢ZUʉ½ƒV­zï¹m¿á%í½£Çeœ QíÂ7D,Ñ94þ¡¥eÍòZÏGÍK¹KþÕ½oÒ wVZ‰ŽtmÙ[SñÑÏSüº`KÄQ·ðxF”Œ¾ðØòCI¼šgi‹]v#GEt÷j…»XS 9qw¦my„©°‚+:GìÙÝøšL$4s2êà•œÖ°½M²o ÞoدPvMŽDÀ®d›ûÀ½´^âéÒéÆᬺÍçcÂUŽ\ºùå5õþ”§¡VNÆ åìÄkúË»ú8‰E|wW}Ë>˜ý–M­uot]¸”éCõ˜bÔ«æl äm?#{'„Fj„mãDéZÒŒE‘­v°‘¤s ªx´eeóWt')½Õ_)›š¦¿~Ì=¶>_³ÆjN¶ iùG¨Lþ“«¯å²žÿ-/WÌ Rí–„—[”}ʉz㓽T©ZÛ’Å#'`µ³øÑKûaH6ä0$a1·2Fv!38Þ Ü‚W‹ýsxã#¯í*n_»_}Ä·åâ=çÛŒ}{—u•eͯüÕ8¡‘‹)“[ŽúŒ9÷èÛØù¦Y(Y.y™")r)-g'õTá_ ¯Û§ÅAÊï¥7ãß ¡Ã-¶k;;šÕÓ -ò|—Ö“!«›QRqù†êæg_Sš¢TÓ^‰é‰º‚6_ ´w–w,^ ùCEîh»EìjVˆ¦£ L‰d³°ƒ†=À KP*Ÿd6)Ȭ°÷ÑvÛ¦F%Ÿýc¬ß¨Çñ®惚kHOÛ4›ODSt@„  ¦swdQ\ì`Ñ2Z}z÷~Ƙ,ö>þEàÕ'Õ¯\ùôß5.Ç7x:ü„©øÊ„­á]áѧ^Ùðç‚+Y‚—È‹?× ‰‡§†Þ)MÎϯZ>nÅRî=ðN^RC…¢’Û.D±xM%óe®Ä q`ç‰b ¹Â¸`¢ÓôˆáÀ¾,Ö*cÅPoø^¤&é@“„@㈞˜"Èã“Ç_ ÷wcWú³‰,Ÿëèáç©#ƒèžŠ˜¤‡*£;Ý¿à¥0¶çQ¡S‚GÆAh‚tfx‘{ý³%=äóVQ9DyÚl;~ÉUm}{ªªÝG(e}Uý$Û"äÝ!WÚÔU(—ZÐÕÆ±Fï€<­{pD@·`ìNãkÀT­9q? ºãíAR…ÆÍT1 ç_¦3'”ÿçÎ`Haiå‘þŲ¨€¥NvI”ê+ð¥RäÏÍò±Òxž©ê†Až¢ZŸô›:åŸy9Í·< (Êhð…ÿK®h**ÇPbeçÃù;ǯrs9K¥qÅצö§`À¥v˜‘S;•äOhr(’´è€&f!_Õï\ʼˆð©|舸¥¡ xF¬Lõn§j™ÜÊǺKÞ»[î1§øâ´O±Ë‰Ÿ(î\çBúÁ >’!EÛÿ8á'Qq*¹ QJ%Òé„zìàs´þ>sªø¹TH¨ÏÈtüø äÁ€7ætš?Eÿº4Ÿ »†ù.ÍÖ‰qa}áS_¹õ õš &ådC!I9YFedÊ ¿BzáÔ¢Æv³Ø®P$ÊM‹ÆYÛæîöÕŠù ±½~”°ç¢º¹‘Š#›2Ù0«Yõn¤‘­å"Pï7Ít¯©êóhº2Á«æDœ°âÇÃ,[ …¨ Zî É ¨`SspM“•u,Î|jTm¿Ð²e†‹9Dº-]vÌ{É'Æx†¯!å2O®¯y‹…rDVoD™ÈM­*Yøh0Ë ;ôá°,)Ô£á„,#bßH $F8G='¬À¼äû w{ãŒu4„äaÃΗPòÄÛVU·ÒŸÕ€ ¢d¨ßÓÝ1½‚H‚$GÉ$íØ°4…¸^Ý!"ú…»îQÎ#ÃOÉ>TÃ60ToN[Ê€" ÿî dvq€HŽc·8ÁãÊÅn§°[šgÿvãJ=í÷½€‚ÂbÐÊœþ?r¢P›§ÁÍY!ìÎv§üJÞú†jéÝÝ92;Åeó!;”/1ö!³“L 3J¶à±¾(eZŠÆ¾DƒÂCVˆÙ6uÛ)æÈ0n}yqDœAÿ:@%©kÊÄâºØE}14z‡Œó½jÚJX ÐS0{IƒNp ª&“ððP¥Ûå‚Qên…%grÚÙÚî—!ÑË6ªîšÏËèºt,íוÂ(Ö\ñ¯¥p'úÔ]Æ =dßK oJ²E̯ðÂ;÷=> Ò$LG›Aø|Oø„…7Nø3uãäwÂîè%Ö÷^Ùh‚b ‰OÁMŽ¡6cËgÑü§÷*Ùm ¢˜ë|EßB– n¢,(:²a¼Næ43(ªsÌI%ÐßçÕÒ”Hg OdwW/õj{5&æš¹ü”g„Ò¤éb»]‚ â®znì݈Ã\³MVY¶Øíþ€¯ DV½ÀJuØÙX¡x›õ dàñ~œ ë c¤½£Am fÇ#'$önÍ3HÄù0i**b0€´‘ó]pDR[ɤٞ|™ÊûÜËä`#ˆíPk}÷ÀC➇p±—Ä ‡r^q­G ާ!ãÄá)ÿ¢Izæ¤ÀUç‚çr}Ô­Eñü¬¤žÜ*V"µ)©QóöÊVpÐ…¹ûý†wîéÇ u±Û¢Ëkà0~?!} È‘/ ã$FÔæU™G]Ô; !ï­ù¢ó….¨8,`–:µ×“6뉻ºU±Ï+w)š¥î/6’‡Ï¼5Ý¢“áT+žn®IÞwwÓQ-'425G“¾QÆgVI¿3‹Ð”Ÿk›{g”Î:œÀœ "j#;ÈœÖ'$T½v`§Áª~·Î|î¼gý9êø±RœÌREª£9ÀÙížÊèb4æä‚~ ¥I…š”£qæ}v3}/:]ŦÏÒ¦kÂÉÌbCÆ “ðÇZ*>/[Z[×U ríS„V;ûbôÇÁ3@;~é{÷”é#ÔDΗWœ‘>ÒbìQÊCãâ’ÿÛ©ùstð± °ÖÄËÈ¢ÝÇʧiXHEŠWp~×)ˆº¾Öêõ»×ÕH4€n[äð tm;[òt|†—މ%\ˆêp³eºÑÊNý%9üP¥X™,•Ýo\"R˜ä +µl°‘_\zÿ³øgâv8$wôŒ˜U¡L¡{2w(ù³S"Å!bÆAEžK²¯Û÷•`’<à8óÉ‘6_"WRM[½’é§—]=÷O¦?…è8×5¥¼™ ›ÙÞø@F ½OOðÞ½Z~ïÒ»¨9™L eU‚Ü(/DùÁ“ŽBœM%•(ñ$cž“~¯e&ß[N‡¾œ~*>ÔíÕ-2IÕÀÓM¦±cçûôçÑêfÛ¿ÖÉݺ×sÒâ¹äñßÍ”Ï{ÍÔt®PÍgZ ïî?Ð]—ÞÕ€â"<—D›ˆÔ¡¶¯ ‡÷$×§bsѠ䣙4CÌ’krø‘|Ƶ¥T—òZN¿%Õ­S¥ŽP]vZÝ‘Ù~ÉëFÔC[=ñÕÖ4Ø»–ˆÅÇ•sb’wsvY±£Äô8ߥÿ/ÕG†u*Ì’HC?…úÓDy1j¶YR(P]Â2`QèFèzêAˆL\,ÏW÷)4mWFEȹ¥V’©ð”Ët1¢rST±~ÖsÊô„fUhgD¨â3²T$‹â(GM´Qe»RGæsGö^—ËìöF%¬ô»!™ˆª[iÍ×\î/TätºyC/-9bÞŒÏÀŠ|Gbja ¢}ÕØ{Uîoå—z‚)Òž>5ß5gTåoùo¸š´ÜŒîåì«ç„ùmÖr8oÍ}®^'àYtqþ”ó—ØÀÇrr= ÎuïwíÊqr«üW N,Hpk948 æ*ý{Ê-ý„R©/í2~7šÍŒ½Å™—*LÎS éŒÜTV"Û‚£ìåw_,>µXÂį>üú ×3‡É endstream endobj 228 0 obj << /Type /Page /Parent 342 0 R /Resources 229 0 R /Contents 230 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 229 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 291 0 R /TT4 421 0 R /TT6 289 0 R /TT14 297 0 R /TT16 298 0 R /TT18 299 0 R /TT20 300 0 R /TT22 301 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 230 0 obj << /Length 3871 /Filter /FlateDecode >> stream H‰ÔWÛnãÈE^õýv`qØM²I ãËî:ÙÙc-‚I&Pm3#KI¯ÇóGùÇ<äTu“¢.´Íæ!°!’]}©®ªSUçt2z3™DB‰ÉÍHià(Mý ŒH2ãë4Åä~ôæ¬NŬæ9¨gËћﯕ¸­G4g6·¯£¿yW¹‡~äÝôÔžˆµüû䣌7ÈDø™Á!aêÝÛõ:¡­èÍØþ)tDbLLLŸÄõÓ²‘c•ø™wWÔ%^C?ñjñîû#ñ×ɱñC¯*gwGâú±l¾fƼ8 òòå\Ž3¼`KÖˆ¯ÍWÒÊW‘Ið=9·Ú¨”µ±š<>>ú2ôWcGÚêI*ü.›;ÜQi¯.[6»ãý/&#%J1ÒFÁœJ„ ¡¤Q*ªbt3:eoà@vGëXKÑK’Yc%óµ6ž°š¶fkðùâ§ Ô1°Í‡rœâùY´#×P0ôž.*kŠJjè»’ãû!~^ÛϹ}äó`ø é¾°•wÙ~ß˱NüØ{'µÆ~µ“ÿ©K…žøäÙégì³Ô;s'.í£Ýì«{±îQt`¢¡´ CëºkØwO.cÜì 7SÞjÙ6¾òhÓnÕÚ7òÀCÞí¤uÁ:³û‰\FØk½¾’w[•¼)Å]…MÓ}ýŒ$º§žsŠSŒ¥ [O{÷lš†ÙS,2Y¶ÙCeÅL«ØL’ùVËšŸMfIà*‘$ OÁ¡Õ °¥±é¤QSöä±Îü4\þ‚¸;;ð*}`ñA11‡(õS— ØÞIgo„fqy.ää}!€Â$êœÍKÞá˜ÔÞù®CìbúN;‡ €œCø4Š ÔûÑúYš^ÈÅmÖóËs§k{°†MB§k@S½O’¦ôž‰=(eG[é3Ž>¼üq{vœú¯AOÈ]m²ùrãêpƒ×Ðáõ3@©¼ IyˆSŸÆË‡vX´×,êÍ­*Àh²ä½yÎR€ï±0ƒ?íàúÒ ß#›qž¡Ï¯v æÒa{‰Kû*ƒ™‡gª^梔õÊÄu0¡3jY†)¯ {Á˜ÆqÔÛ&Ûãý^(*?Í”y6‘ë†bá°ˆƒ¢g"ðÀÂçdî<“¡ÿTJ 9é°NË_w–ü¸‹ú'î^ê°ÜµÆ96²Í¿¡]³I4õmDT´‰ŒÈFÆû|-¤âBžO%ðRWDmZ!îr’ÄÞr¾`X”Ë[;ã­aÁSšB¸7q/UJM•í­Ö¢D"´Cbu#š;»EY»cgoÞŠüNdo¿»UŒvi«AÌzйÊ+î0BÒ Ü´'„E¬äwôƒõÛº‹iTkA€"Óâ ²åà˜+?öÔ€eŠ-Iïx$½éyÒioZ\fIÜ«Û:í2K—‚еbÇŸçM^#éDÐ5¤£* ÄR;R|u;ºÝi¤<ªS×+DÅ'-ŒM z¢êô`ÜÖGåX W¼©uÚã=œ ßJN)—RSo{¾{ÿ­½éþawÿÄÝÿ“'¥¦¬†¦!xÇ–Ç‹Õ,_@Û£ãÊö‹ I½¸·j Œ‹Ü.yÁ\ß š¼E;|Ëõ¤&ÿD|’¾¸ä ¢¡cì)l[Ú)"_TE>gV¢hŠ\‘w)²µ…FR6*Þ¶FÐéW˜„5‰vxÅ‚ã 5Ô‰KZaÁ±¢¼G©èˆ’{‹„lF‡ŒC´šJ«ÝèíH€ ¹ìØcëš›M5ÚL¯\,Ä”&„^æA&¸æô“ÛѦ8‚š5BVk ù»Ø÷ÐdÒ¤»q/ ?ÍCµ·cò0 UÇ•£3EU1[–ÑþÂ(©ç¾çöQض ÷¼‘Lï`«„b­ÞólbQó›9ÖáŽÞ\‹.f¹#5¿—ŒùF’áÉÜ4ȺÆlpÊš;Dkls¬ûl ÿ–'úbÉOG›:>QìÄí®@Ú i„2¨÷šÒ©c7Bõ“VÖC%NÝK½=’©ì=¾¾8þéÇâ/¬K ›)²ú„gêýÀÉR¯·’»ã’ôȼåç¹ýF”¤#ôÑ^³²ƒUÑJ©¡Ê¼9ÐaË“ç«FÛ.ÆèN£´§ºÒê±k/¸I¤m?|$m3ï³hG®¹{º¨È„|O·fOÝ]˜ÚBûU2e… N±Aĸ£©SûpÄ7¦†ÑŽ,í£]õÕ½ìµi”âäÓ8&{íÁ•ŸºÌTiK¡öXî¦uìq¨Žæ¾–H…j’lClÇŠâæÔÔŒ¯×gwÔwôW æÊlßJë-ûP?•8™úœŒ¬4½ÜS,ô“,Öý²x´ÝÜÆ±ñÕ`W7,¥ŽÒI‡;Êå/ˆ»³ÁÂÒaž5$äYqfõÓáÆ%â_¸êª6 •sñ‡ì¢sÊ9]|¡dá]5¿¡=‡Äéù´ TÍ­âäa±ZÞ¶ÍËæÔíK¶O•Ô.Ð ï *Dê]—üñ­Ø‡ÊN/ó+ˆÌV0„ádÕ°ýpºL¹°St¿¬‚ÚÐ<­ÓÕj±«²z¬Òžé·ððÎæšXÕ{ùAûIe¿Á‰ÛÎþ‘DY;t¢Ñf«Ýe•qøÃ±?$dرðÔ\ü¼´=7Bx?‡¹ùëX\L‰W?Ëâ&ÄlBo—[U«‡Æ1·Â±³Çªä‘Æ‘¼šÆ•×ñ²BÔk7wfœCå8vN"¦ös™WOvµX¬E,íþ3§ÉõÇÝÒ/nþ1ÓKjVPND³‚"­ª·Ì§î­.öÚÌÃ1zùÿ£ˆ] L"†ìÛ”üÕRD¦ƒªG#7Âþkb?ç¶ !¢¸£*@­âä•L‘mk–K6jÆF%ÜßÛ»<ÔDiÔ³FÇŽ‚hC74(älIÆi¨[KØFhËÆ²FâPÄ'2ÀïÑñ:¯Š%ÏixSÃ=;¡%‰ÚµS”ôí$£¶ ½Ó2vdûˆèS•õKÀ¦v(GÊMVÔ–Ü‘y‚nNpŠý-%õÈ·K'œ JV7–Іgt«§ þ^Mk´sÁ Þ j?Q˜¯šÊÞ)Ø£d™‹{ªß×å7Éë!f‚!J*®\#F<².›’_Àk<‘Ó/óKQ—ß ¸ßÒÞЊ§QŽí¼EýI ^}#)Dãfƒ÷‘IH²@ï—Ø³ø{otfIî,9hºÿÎtã­[¶3ˆ±ÉÊ>›kûÄ^´»O¶sºø|!Àßlè£Mà8§œ¿)£’¡–ü-¦ORSÆuH<»˜ùê÷™4Ì0iJ»¡·°³Ü™"8¥=Æ¡ÏNmUù/ü—‹|º(ŽÑSðÉ–I·Š·p‹*‘»{‹ w9 úzƒ«]ƒSbùŽbVSˆpñ«gîït› 2JJØ‹U—Ç~çò˜igmøU—ãºEñ~/åw²©H‡Ì{°}laˉx ÷ *ã¿q^¸“º'¿)Ý:”cJg„^b«™ð^æÊh§;sRQgL*i3û¶ãÞu)Ÿµ÷e£ýW—»[áÒ>ùwïU²Û6DïùŠ>’€eˆ‹HÊÌÈöIHCƒA#RŽ`Z4$:ñç罪"E-Ž1sÈA"{a/ÕÕoñ,ñ«]I<޽+HÛ¼8È[4ÁaÜÆ^^¸eÁf9?¿`2 H‡èL’´¬ Ia';Ø ¥ƒ$‰½¹=ÿDv¤2d]~<—«£œ h÷y1Úö úXc@áŰúáò°Ó"‘±ï*—“…ÄÉ’ªÜ#ô‡Vv–úú°ë8z]UnUëb€ì`¨¨‘a·?…¿NÀ! â‘f”F;íÏÒ»+›çíâÌôG«ŸÏk³Sº-·Ûzë–~Àlª à•²kˤF²5³7ó”W]ý µ” „7)\" ¨ÒÏí³úÈ} ÜŠÉ{n’mO/HšÆÐm/³S –×A8Æuö±F†&ßXhšß\¹.‚ñS#*=”³úÖzH"{{ªwt*ÝÉŽÒ¹Ò‚41)/U=h3i? y”<\lœ]Ø4š€0ˆÛa»#G¤—ÍãlZkw»Rû7ΓÙIH“v¶Ñ)²ÂÓ1Ëž€Ñ»ZR]nðU÷Ï|ޱó[ 2¹$Ùø„ò)³!¤$),^“XBã(q£¼žkBTЉ  œžÝœ´å¢2ïù-/“Ží°c¸“dØje:…ÍE9zã“Þ/ä¶eÞÝ'­v?”5jåâuáþÝb!ðrì0¯ï¯sy#!lZ@¢Ïfp0Úé¥ßÁu<´«7¾äíêdL”õ7÷™™úŽ’ˆ0 k›ãàJv#õ™žG4Öñ.Üò/4õžDþE|’&fß­,önè}…¥@GÁ6­ÁAHáœûÉzîCTo_VJÁ{ØÇûkŸaÉ)ægÖžŒ†I@+mÕsY=£wïó‡˜8+Š|Äø&*©ºÕ„l$øîQ§d.À3=çuæ‹€©7H/Ö»¼Óm,ãUͺêOÍcfÞåùÕ7¶Ëß„ y³;¦BêÍo§Ëå• *ŸU·OºvÙéíôˉöKT Åûÿi?èáó/źáÿ endstream endobj 231 0 obj << /Type /Page /Parent 342 0 R /Resources 232 0 R /Contents 233 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 232 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 291 0 R /TT2 417 0 R /TT4 421 0 R /TT6 289 0 R /TT8 290 0 R /TT14 297 0 R /TT16 298 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 233 0 obj << /Length 4013 /Filter /FlateDecode >> stream H‰ÜWÛ’ÛÆ­¼ò+æqÆ!Ìàþ¨]í*IñVHW¹¢M¹°àDL4jµù#ÿcÒ—^;UªÊ&R-q™™FÏéÓ§{®æ“×óy(´˜/'ÚþÃ%LSÏOýX$Yì™ÔÄ|;y}ݦ¢hiŽ/Ú¢š¼~7ÓbÕN|Ï÷qN1™ö·O“Oò>WÓÀ åÊâÕHêoó?M22‰Ä÷²>¤nÑ–×›Má]̆~Æ÷C1ÅK&ŸÅì¹êÔT'^&×¶-á6ðÙŠ7ï^‰¿þSMc/MY¬_‰ÙSÙýÃ60#‚Ée^-Ô4ƒ0IѶiKF{:Œxž¿eotJÞ°'OOOž ¼X¶`M=+ ¿U·†=j#Û²àiÅšìßÌ'Z”bbb pj$p𥢱“å䊢a\4RŽFzÀ) ÀgÔ„逾Ì<5ÿ;Úˆ Þ‡OƒÂ9û¾À?7M„Cîßß½QS@$•;åÀ¥¸«:Û,U[Ë +¶-šr§ØpWÖmV‡Ø"ßé®w?Î’‘û=¦à³>qÚ‹ã>ÿÎivÕ°«·ûª@ZQª¸V×(ð"°4Mù=Pчñ;Ú˜–?bØ`ƒ×0_Ë|³ùñ®\§e†2)Ú®ÙtÛ!{b¹o,íóRâö 7IìöŠ$2pµóx®‘kàO$­XªPÖt¿ÙÔOeµ ÎèD]mž?¬ë'¾ÁÑ¢=8žIÞ¼Ø5*„8Õ]Ý=ï,ÏôÄÑ—ø¥9OµÂ]ìç}yô¼Ok[‰¼( Ƈ·lƒK…p‚¿5çÒ€ ´Š/ÑjWŠeSoÅn“—•¸öÄÌ›ÜL±ßÚªËiGõ’vÚžö¹áéˆÛ.;ç7Õª¬ìG”›HÖ‹ýÆ^å-?Æ h§G<2q¯9Æy)Š ®¢³ž´­ØZ¼Õrûèn¿˺\àw›_òjg¤UÆœ8œ¢z~˜ŽÆÀ8£-Z½ ßv œ5ñfõ±^¸Á c/Œ³‘p…ƒpéà˜¹aC¢_H„™°(W{žyç`®ø±ƒuðÅœ'¯ù%¯ofÔmY$zBGF|YõK?`{<:£ö†P ûgäÌ€­ÚWâ±®7Ô ¢P…½¸zųoúUø.w硇S©‰¾¶j}Ðsœ™»ªì0õ0HÆbLE5©^b肆ñ§g¬xÜ+F?ßíîÝÄŠ§uô`.´[†{Õ\'S<ËÒ/0…çcˆà³ñGÅÖ÷üxç;ú°6wV7üÉ‚ê†Øë²‚Þ£\¸E½øë|pöÿL_ç[æ¯süYDð%’ehå+;…\±]fü@ 8tµûåÖ¾æIïíóyË:$LžÀ‘GÅ®5ëû­Û( Pá 0T¨Tò¬ºBz$ù.-=|ßÓ|Ë><óÌÞÆž‰bÇV°oÃvì<èÁK¯®£îAV³ŽO6vw¦ £z=ˆ‚9Í¢ Y"…qé¨Tº#.ÝÑ8<¤ š27bm€È&œ„)%aêqt9 5I•…yßlÏCÐYŸš„Ý\rhæ>¸»Þ*ÊW+ldLà‚³±â 5ºiÉÂ}S»ÑæÈY絨^ˆ*ÐË}ÅñpÆÌìø$¿¡C[J„Ó¤iS2±¬ÝÍ=\“ Jã%Yt.4/@cúÜ;Lžx|‚{æó[ ±Fd?t†Ó?…`âØri›SJ¦œ^ƒ›áP¬~]pŽ2þ‚Ðü‡s¤ jîT£"¿eÙjÜbú¦[B¹øw¨Û¿¨/ŸÞ¶ Šßû)|¤ÛÐþ!—<ÖIPNP£2ÚCOLL×BlËP- Ê§ïÌ{»â’„œ ù"‘ËÝárç73o¾‚ZóELG÷K§-U¤Mås¶R—ûU¯Œ«y2Oò P ¸^ÊÚß;y_ Š›³å­ð:©ÁAZ™¦Ÿø£èBºžV~ï€#v.a§c Úœmñìvá² e&‹3êÐQ…„œ sD.äÂ(Àñ-!‡œ¤Ê£*øËy€È9E.§O8$ÇM\Œ7bºàf{Mü¤;ªãóxÃ%+U†®ø®ù¯èÎ æE‰ëž;î-ÍÓëCHÐ:ãN¸mÝsÐî»åŽÏЂՏúíÅnDbMÞsŸB/щӜÌ<Ð6ÄÀþ"±…¢™'¶MªÌ[|Z}q_Ÿ1S»O. Mü]a|Óç.bROjâ€õ-ïcá_‡a“S¢_Îá')Ú* a}Z%îYCJ[JrèÓQÈx¿OGrB1y—Ò:º™âcãÝr¦ŽeJªâ É®þh—o0ý˜håÏÍêµ[îÀš©ÁZIÖ´ômº¦Î™ª÷LÙ SuÏT™²ho 3[3àªeÆ•/ø»Â8¹rçf\¹bj ÚßbH•鯃 ‘UÁßþnàoV‡·â䋈ãAŽ*Ú¼êqP/¾ä-­¼ÇÁ±']³¿ìŽõœcA~é}Y7w‘PËUyMTQa8T$Ü·ˆ0­H +’ÉE£© EÜ^•”ã¶à/g®ãÔç46å(çÆždQ€•šV~{‘å’ÝŸñ'­íÕîf†”Ô¾>L…€-]f#ôCùxò>i'_k#„sÏOÝóÔNÝï`Zr=óìP;Ô ÐñõíM»éƒ#0#RçDC|僟g¦*^^t‹\Ë lnÔ íÄ)Ù‹oŒsãdïËþ\JžË–YA›#Ëí–Ø™Õ­ý¼¾;šÝO  ‹¾¤ AÌã/3µÕ=/·_ÐI6Å·n7 áÒÔy3=©DPI‚l"Hc÷¢‰LÍàµ9£sM1æ+!ÀAÿÁÆŽ3;j£G) FC;& ˜Î4?˜ØÀ6CSΞµ¿~È'C‚xÉNC=¡Ëeu ‘ó ÁE’„jæC÷(ÚZŠgE]i‹„/¾iú iüBµwÙ΢E`Ó@ ÄŠûN+®¡"€pÔ±‘ɨëu½AUg‡áw¿VW«¥Å¾˜«`¨àg”Œ´˜>>T *•3§è2–æ_:~ô+ãã¾€<ÕÑ]T-ðÈÒ86¡Ê¶•õ†~ОmŠÜCV^¢ñɰ ëAu`7'«_q£º¦«v\¾À•GÂ/v¸J<óŽ÷|"1¨ÚsT¸S̹°bhEV£“µÅëíLu÷¯~¸ï3ä«ÄÁ¦Lb'HÍî͹ÞYnè,g¥ÜËcóðQEå˜gíô¬÷þ©¢<üSÁ?®Hžßrä¾|­–Â÷¼ç 7zN’‡õéùÙ~ŒV~štO‚lzÔ}Œwª¡Ðly~öe½~L ¶ž;N°¦Ùûü¯ÝžŠÒ¿%ƒ4…Ô¿»UË‹íÉNžÄŽ&^±[ÈØ"ÝICb45v P£]8_\ÐL!ª.çÖ›±º'EvH‘UŠTÌGŽèVŽJrTöùT3kÜ$–Je ã Ü)K6P«8Ì i¥òÀÓ*0â°Ò’†A¼v²ao›Ø?=®ÿa;r=•V²(X÷?7FÜñD?Þþôßi‚'8 endstream endobj 234 0 obj << /Type /Page /Parent 342 0 R /Resources 235 0 R /Contents 236 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 235 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 291 0 R /TT2 417 0 R /TT4 421 0 R /TT6 289 0 R /TT10 293 0 R /TT14 297 0 R /TT16 298 0 R /TT22 301 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 236 0 obj << /Length 4208 /Filter /FlateDecode >> stream H‰ÔWÛnÛHžê+ú±9°ö…·‡<ÄŠœxÇɱ&vf1 %Zâ@& J²ã<ìÿì?îÃÖ¥y¥™\f³H@f“ÝÕ]U§N>žÌfV(1»)-øl’øAD"N#_'³ÛÑ“É&ó Í Äf^Žž¼¸Rb¹~àœùhÜ<>Œ~‘—™76¾•Ëÿj)Bëýsö÷QJR~Á&&q‹ny½ŽÑ>ElèßBcü“ŠëGqõXn½±ŠýT®òMÆåF<{q"þñoùFÖÅ|u"®Ší‡¼†!L^{°•Y¹ðÆ)<€I:¹M.iå+Å0ž=çÓ¨„NÃ'yxxð=ãGrÑÔ£§à·Ü®ÀG¥å¦h>ð´ùŠìOg#% 1Ò‘‚p*abø#``´À%¢ÎG7£SÈÆ™æd¤Ž>4¡ŠÑ€åXuyð„òoÞìwÌfÄÀl'ìˆî›rag›ZþˆNÚMü"gpzˆ€¼ò"?ç´†¸N=%뺪9VhÅÆúMt/VÖ°™9æ@KHRQxëC™Q` æ#³Ë[kQk- tïLªE”R~ñ«¼÷ÀŠ’UáY?‘ a‡ñxT ›àïÄK §¼Ñ‰Èîî.Ýü’Woi×"ûÑC„æüþ%N< ˜?ó4VÞݱ½UV_Šì-MÉÖdá5L©¼Å#¤2§#œ4Û±åsDžÞßß7ÇÑ8îZÞåvv „Wé c„-&‘C§USAP/¹ ¢bØÁ%o¼1npã¥hÊÓÕí‰Á€üÀà[ Lºò¬,>䢵Ãk¯ Á²ùNËs¯l…ÈhÏ·à7„N7s~õM €Wqjô.2 {×ã7wÕÃ;£Ý"Ú1CŒwÅx·ˆw˜rJû%°<>¬‚hxRÝUÞ¯ÍUªÀPª‚« ìWAÊHÒ„¤´­‚«€–¿¤Vp¶³¼ñb86¡Xí¯ ËÀÞ’?ŸKUB€©lé6=§t3㔿çá‰ØñÃ`›UolùñjäͨkP±½bC@WEI(ݰ1@ƒêÁsañ@ÓŠ÷«ðªÀÒùãõ©«20ð¥Å££ðX<®v6€û`:0z‘h¼°Á®S†1a7bìÚ»š'—¼p n#ÆmÌ>[ÂmD¸5Ü]S@[Ð_Ù6áOcË„¹¨éÂíN½ù ®lw’÷üÒ¡ÝðD4Ù Æ+Æ|¢MŽ™ÂˆÅ]¼œ ÁhE‡Ñ‚z ¢Ï–eù-ö¸®ÅÉIU–ù|;ØTG™žÇªóXµ}kC¢}[“ÐUrI¿"›bañ[PˆUåNÅâõ„î@-éîè{ɳÙr½!‘K·r!ÖUÙì/k½Ík7¿â©OÏ@Ãáñ†34Ç‹V4¬ê­Èžç×»ž'ãF<ÚÝÇÑ.Çâl-q-7OŸŸrá½øß\b4ò‚TÔÏ/Î_»÷¯z=ýÔ{×_‚‹nDàÄ=Ý, Ò–õvG#nj mÄŒÂ-/æ+n °cL" ¼Uaܯ¿¸úyY Á6´=$š°WØ•ÓÓà€~t«¯PPÿבÇq úЦ@-Xмüíóˆ £,ùå;Õò«‹Ï)#“€ºWFN¢%âK£ÐC8ˆê(Ïç¸UûúDTˆY¹åÉU 5ëGÂ2!ºü†EQ.Å;¦Œ¼¹ó §•7´ªXŠ-=äZw=íŽP”â€Ï×Wü~[ÕŸ‚L%¡ï™Á“SÌ:ñ:Ál‹ñ(ó³b}¤‘Úíà×id•vðC1¤ä3 °F’*Z1/fØ%b0¥,ßx$# ÔS–Ñ—Ê3mì†k׼̶<Ë™ú,l†À}Ñ›{…ó•`š¹†PÝŸ1fÏY_L£µ¢Eµ¨Y.3$³ÚCdNõ#‹JáûÄé_dÐÉ麠N"ÓÓP†$76\çµmB¦AÿÖÊw¸ˆ+ãá/ÈáI…`L0-cìÖÅ’ÇoòŒ”Ô3ol²»r><vlezYÇ.À Å“kâo< ªl‘×gè-Xó*ZüÓ=èDÜÓ¨Bÿá´?xtØŒ>OÀ@Unó÷4iûY•£ ­Á©¯šæÄ zϯÐÉ%R˜03_¨Ú]k{]a÷È0°Ô‰’D*ø×§_w ‰Mð‘ BÒLϨç½×¯I8×2Çu™ EbeÎ`Ïý åÎ@Ù5ì‰ö „?ü!GإϬ)¡ÄsÙpö³õ[DxUA³g ü‘]Ì èR‘±éõ*ým³ÎžA_…>”hÔ½|ê+iDþ µ~Åx&™9eNû‰ÌÛvrv/úÙfw¡#'8fÁtpep#F—öÙ³;LÉâ’ÆÜ‘½­°5 û®éÞ Ê}?à,=îI:A«î´¡lêßü¬.Ê»a?€ýAlTž„®?x¬¬_ê&1ã׋6­ˆ§‰Ù Ç£}+bâNRŸ3Þ^®qFGjq‹Ý?rȳ[¹œ~6¡}uLÕ0i³¯Vü+*KTž«—g~‘Õ¶1UÔ+64’ s óˆaž¶0æ±ÂœôE†ùÝ1Þ“ÛÞ£ïæïT ‘E5R— è³)¿¥Å ÿÊHÚ€qíŒ{ÞV_ºBDýEÀ›Æ?YЈ'y-¦xý¥ûlw&øVž= ³æ0>}{öDÍëG ƒHg»–*jó¤õ‹=O%…£Ò[Âgó'EÁ*M´`Ò®f*ìå6¯åÉÚ–}‡†ÖËðÚ—åŠß<×IùRfTbª‚Ÿúþ"·o­£/¾vrŒ;ä 6TB Œ §µÈ ßœ ?¿ßyÜZfkxPÀ©§@¤¹æ¡@ÀrȯŒ+tà}Ψ߃<¶"ϯص¤]ÝH§J-íwªëp{A~Aª9ȵy”r2vDŸqì¸äc¾Ñn)±d"—+)Œ9mZ—²X–eÂ…òû€”‘[Ç9»uDªa”× ;ù{3¶®¹@vD:±nQø‹‡w=<{þþøHÍuUûrvš1µMi‡mÝ0Z7>ýãg[i¿j_)ݪ]ÎDLC*(•§J¨»b#Þê 'vû‡—)e 3vª13öd`·šP ³×ePómÁÖ!ð¹¦ZN"â/öxÜöZWˆkÉé!°3(RΧ;ù“Û…ó‘;Þ Ô‰}íg 'ÍÅ£W%4žVŠÄ ;poӬݢÝR B; šµ8«œÖìÙXÙP~‘Œãý=‹}3µ™Ä#0sýÇÎS–Z.j¥<û«±7bBŒa¹Ó ¤8†,s(©=ŒuïkE /åÒQ·"p®ã¦$Øa,_¾ÆìG§+Éâ;öÏ<Ã%¸ÉäÏ.)k1êòòüpø>Hön“ðbÎ%öÀü¥\6æ™p¤ÎáR‰O§XŸaaÏŒ4‡g¨(w ‰Ò”‘Oß~ûwø0ò endstream endobj 237 0 obj << /Type /Page /Parent 342 0 R /Resources 238 0 R /Contents 239 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 238 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 291 0 R /TT4 421 0 R /TT6 289 0 R /TT14 297 0 R /TT16 298 0 R /TT22 301 0 R /TT24 302 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 239 0 obj << /Length 3626 /Filter /FlateDecode >> stream H‰ÔW[sÛºž¾êWà)f$† A|ÈCì¤Iê8ñiÒ™6-QÝŽHÙUþQÿcºð")çÄžöÅã‹$€Åb÷ûv?\L/'#´˜Ì:!üÁq.]hEšÙ ra,&«ÁËËʉiEsBQM׃—ïÆZÜUƒ0Cœ3ŒšÇ‡ÁßäM®Fq`ä]¿‘I¢þ>ùó #™Hà ³°Iìü¢¯R4…O– ý[DahÄ2q{ãúV#™\U qÊJ¼~7ýÙ –»rºŠñCY/v0#ÉK™¯gj”Á˜$èØt¤HÚØÞ'oØíÈöäáá!Pq`eÑÔAiø¿®pFɪlxÚtAößNZ”bY áÔ"NáGÀK ôȉ]1˜. Š8Ćã„M¨R\c9V]BôPþAMþ‰Ù´lÌ&©ãƒHáÇ´+&30©\OñP‘¼þ(V¬ ¼AlËü®8’ÉÛý\%¦‡öò'Ž:¶‡-žxy‡Ë冡S ’(c'P:lÒ;ºj¢.3=ÈXlÍá¯é… « °[J©Hé„8¸ñSßÓÖ_žDË'€Áj{ I;×Ò BY)*p‚Š\Åõ´ÜðÀúQ°™é0ú€Ùë—¯Ï[È °M?WÅáâp“׋SUl¢{N·m®i˜Žk®Ð“íÜN%U"#7ØDcIõ(•5 â…ÊÚ¹Ÿ¸ÄòAi#¯TSYb>ÝQU3¾ª¥TÕ Ëä»Â\¯Ÿ¾Þn/ërASxã_Ù™¨yxHçiè ò3ÂÆŠaóìä‚ö§ßãÙcùA…ŒýÜK$D/¿ÞÌžT­M[Õò€Þl‹µ¸÷šÙ´¾c{X‹o~ü€šcËcÀ ÏÂ×Àj[LyRI6æ¥ͽͦü„& ¬yÞœpÑ1'4V¡B¡[ó˘ö·ßTQó³°³R™h×#ŠIºô%G¥’*.ÔËŒ­¹×ôBì ƒå ³ö íLŠ$ðvÕÿvàÕïéÛPaS¾ÿÈx~CLé}<±á®GÖ*ˆ·FtŸš ˜xÓŸºçáÌÕÖ³* ŒIÎX'v:Ö0N~JpÙ„=Ò˜.êæŒ4 “&iH3iR8çþ–?|+ž$ÝðŽjQðlxÖÎ/+ÉZÍ7¿…ËÛšE÷6˜/il‰Û~ó*Ìç²zñB8÷|‰×^¸Zæ½)–E…çi6†Œð¥"„%ÿýÄs&î„Ìvdƒò®©udÔ8Ò®qhn¶ü@³@5dÂ#Müo–0ØŸRÌ—Ák‡Ë¨“´‘—´382³ô,™˜$7ö‡ßÀcøtW‰ŠK3 ÅO?Ð4Ѿbg\Jž$ÕÏZÊP“~Ý~Wp>k.dW¼ÙÐ׃߶‰Nw ÄYjÿy{Å7,*±×²X#,ØJ?ÐI£ã•€§¾(\G…Eð–€zï«…¬s=óQ0§*ˆ ÃEúJ–úJFwAL„˜îù}G"¢Ë£“˃ØlùЍ7ˆO [X2šÆ{|\äµc½(Ä•ÒäC·m©ݨuaMv– ˆ—›)n“óWt‚]<ˆ½÷¬üÕ;ë÷} wÐr½(×íö~ŽØæ;ü•e]wµýQª?‰]GãgHµî1®c5d= iý‹åM} û$x/›Ñ”³"›š>ý´îÓƒM0I\£›jzáÍWX‘89â´ûy˜õ²Ðð™åƸÞaÇFŽÞAÆKŠh[¦eÇÓ,­Á€þíˆe D03 :òûåÉ88¹í•§çU™ôi°cÈÏ„pTR åŠCZ`u‚Ú¤F °•ãzR¡lF¦wÿŠÒö4ñQ­r`á-!qø±¦†^ÐAªÁ¶.á(‰B+ýT*_XY0`a¥"¼íõå‘l5Ö׉­ѱîèZÃÿùf‡9*b’;xa+d)â(îû†ÄdìŸwÕ£zž1P#ÃçÝ󢬭Ëåu=d“{&Ã4Š{+Oû Ê€à lÞ&ðAs-ß?)ó1T©ž€ Ó®{¤ã´RLTÓrÔ`øu?­‹™¸åÆB—úéIM UæÇ¼ûLÚ :8¨£+–µ\Yôv¸ÉQIá-ŠØ(þA &¥.îÕO‚oÓ¦‹úy[¬¹€Ãå¢-WEüy8Á× ²ç„KJ­‰O®-–.++¿`uË}᣶eåþ¬Î`-xÛ]w»›åf·XãøâK¥"F1Ö nêó«,@|{‰ ÏBÍVà ´ÈŽÈ¿äËO¹ŸOÕŽP}e^|Å$¾º ±BÂBŽ”vÞCñÛ^°ltŽxi;0nîÜ©îŠÎêÈcnNz «H‡¡@wñ2Ytà»óÔ²üŽŠk<î ½XîyéûC8Àl/~bâ½ç´ÝToèy;ü”¢;ؾxë’Û(î_Š|ºHà]ˆR¤å JÀ=ʹÜ|Ïí=¨ÚSþV¢ºƒ’_ õðúÕWy度 VåÛ¼âÚÖWÅŠgÄ-*59g[ÅîQ¬m„îÿÖR(‰i¸ë¼®½/9)ŠÅŒz4½í´ {Éï¢úÀãk?!¦¬ùß3'l_£ݨˆÄLaƒ6¾b` õÚsÀÁÆñáÍù½J»°×¸â¨cstÂf,’L—ˆè’µ|Î<‰ÇIÃã„xÌ ‰‰ÇhAäžÆˆãRø$|&qõåJÒº‹èîÈ•{‘Qx•Zî±}€êÿcåaHÁ#B ŽìľRTb ñ½š«Â‚X/Ä;š‰LNIËXùEO ªˆ÷¨¿ðŠ--yp_\(t>ÐB¿´ÄAÓÀ~Ùø¿ÜWKoÚ@¾÷WpаÔH¶÷a8Ò‡”ªQT‰´=ô„‚¨`¤˜Jåßw¾™Y³Ænmz 7?Öc¯ç{;0ñSÐ_ÕߨÌíõfµþhgÆPk;¨ "4 MŒ\ȶ4çŠy ãUĄهwÍ]ìýøöD†ƒÇGÙ†ú‹k›KF¦AgâU¶çu-§2¡9•:á¾(²ŽõØÆz4³aÓ[(,“”·{ŒáyÂ’G]ÃC:Ç&˜aÕ«@î'Š/1·2p+~šíª` e]ý¡Ê•ú;ÞɆüÌœmX)ÍMQ†•I7ò gL~"2_;L”½Ö¨fz2&2¶‰¾Ýv»øí‰Ü ¤¤(îø„)ž°êÃlÇøþ&Å×^K¿äÖR-á¼XJxÂ'±’Ÿ!”¢ðœÈ“ ‡%/µE®°«önC+Ü+'ô‹EšOøÔ¿™&}’t4 +‚Õ>М\ˆþ,XjJù4¡9ÈWªÜlxëÓ‘?¢¹†I?œžIËÜ›öp9>´fä¯ EKÀÛjW2Ggð‘ThcŽÂ ˆ¥ åÄO,G ¼×†E¬‡Ä=Y¹ØSåñÜR‚z&hSN˜ŠeÊU‚­'sÕºx$¼P®æ]²:!ë˜ÉŠ÷  ãp½—Ë}öœ™ÜýoúÖŒïÀ¶øq±îÓ×¶t€Ý%¬ñ¿ƒ\ÚŽL°oZ~’Ó3f²áVM wÖ\ýl% –Çå‹V‚4{Î1“©ãQ盺ãy¬ èÄð¬ŸÞ–:0ÊUR+UÞ®·í;!j!óÙ¤šß}¾½=¦15®°Ñlè‚ϤmƒæYúaôƒqØDÎ+üD¸= ó‘Aê`¸rÃWÂ@ô4˜²‘k=`¢-ÖŒŠZàDPúÎçûÁ¬ Í®~¬©«ë0î–å`©©æ¸UžÔïÌÏÒþ½ßò7\ÔpT¨E¦e]¯ôR¥C‹t’ž; )e±èG-uaàDüF  0ç©1o§àÀD9›Å©#)tðò­ôLKÜð`t:50 =³@@½ø:šs ï«mE@AbŸ&0¾(:-, L> endobj 241 0 obj << /ProcSet [ /PDF /Text ] /Font << /F4 294 0 R /TT2 417 0 R /TT4 421 0 R /TT10 293 0 R /TT16 298 0 R /TT18 299 0 R /TT20 300 0 R /TT22 301 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 242 0 obj << /Length 3556 /Filter /FlateDecode >> stream H‰äW[oÛÊ~ׯØÇ%`1Ü —d€>;vpZ;1b¥ê#ÑdÊ ¨Øî?êìC粤¨ å´EŸ wgwvvæ›ofO'£7“‰JLîFJ‹þàǦi¥‘IæBFFLFoÎV©˜®hM$VÓjôæý÷«QF®™ŽÆíçÓèV^çÁØ„VÞø«¥ˆ]ðmòçQF 2‘Daæà“úM¼_'¨ ¿+ú‡ÐQdÅ2ñãEܼTM0VI˜Éy±*áÓ„‰\‰ßÞŸˆ¿ý3»ÐȺœÎOÄÍSÙü½¨aE ‹`e^Í‚q ’,¢kÓ•´ •u Œ'ïØ•’5lÉÓÓS˜ÐÉhDU/‚ÿU3‡;*-We+àeÓ9é?ŸŒ”(ÅH;îTÂ$ð#``´@‹RQ£»Ñ)ECûhØî “&‚‡­Ë’8SË>ÛÄ#BKeêP“?P—ж•E^ŠÒÐF;Фð»ŽY ÀÕ ÞN»ÆãoåUñð£¨ÅÅ:H!(Õ´)—è~ŒPŒ¦pÐØX@Ä; ¢–°ì‘SþYQ¨äCQ59ì­Èƒx—”ÍÊÀŒ üH2ïðºó(¢°upT Çn‡Y0â&ˆ¸Xž#TY×K/«Å ‘¡@¬/ÝÖVÓ·o[礢º/«â*k„Àr¶^§ùªxûölYUÅ´_媩Ëê^´7Ð>|d1ƒŒïzË’i1MgÐÄ–öâ‡b×-.t&u=IçcYó‰XW˜+p/ à,ÊNÒïäL,–lMB—¥i/P™·Uæ×õ1øN€ìD#Âaº‡ìW¥±ë¤€¥·ä±ÎjƒÛ_wgGa+TúÀæƒbHÉÃxsY†y°¿r ÿ{ œ–%’˜'ZXòì˜! ÒLo¢ælµDqÔÄŸ|P.Zžвm¤7ÁˆÚœ÷ª1´í"ÛÂmXHeÉ0HLd4˜/ëÀÚš=X`}°fm=;JnLd†×õýÅ‚÷Ș\{6‘Ò=¨Åm!hSø¸+ÐŒ8ß¾ÿ~}ùùýï¾øøá|Ç;=˜Û8Q~ ¶¡ì0Cci@„ FÑ0‚m<&k±‹tm[tüÞï€|½ÖtuÀ«7t™±¯"g@ þ×Í:_¦¿˜4–/çôG ¯ 0K"PÜ÷ä¢d7PŒ~Þ?%YK§±dELu´IU÷I•Ï,þm¨ Ã©@¯›ÅPîú÷ªTÜÅ«§hµU×M±gó`lÁÒjÃ;eT) œ¸Ÿ²&Kz˜ãÄçÎÅty…fÀ5céÚ ÅTB ɲ¥.–Á×áí¯ˆ{gÛ#9$÷mKt¬<;£B×ïTÖwÿ%Òc,ËŠ‹sÿ1£Á ”BxmÏîÕÀ$TFÇÿ›îPÈåùÕ÷³›É§¬G~*Þ @ÓÆñc¹\týT[÷Ã,Vé iBYyh ãóš¥Y‰Ùã<î•ððeѶm› Á®ŠônºåÞMoå]¾ÀÖUa¶¸²Ó tn²tWó­¼}\×ÐC‚›ý,‰E¾íæƒNÛƒ˜”R>°ôH>ÞþЏ=ï`S–?ò€^ ñ¨V ùÝAµNñµâ½H޼M<úõuî×çXƒG Þ²Â!ôå_åÓœ·¼ Uñsk¦SÖåU,è,oX1ãµ'‚Š&g/¾Ë×þM+zä ¯¦³¬5ůÊÙÀ¢ž\Œ…]yÚNÁoÞ~Ÿýƒn h1}Ц›—²“WÍ Zíp^ë *²:“¢¨f¼†¬2€ûðøs¤qœ$·µ}¾»Î±/Txê ­t°ÂÊ–°³¡O¯Wo»BÖ>ÊÂ4J4]iË_/ö —ŸX¸æ ?CA÷¦ä-^©¤Ï*ЦoÝ%\Ë%&1}jèM!¹qÂ[6…½y½"UUÊf×¾±WEþwwè>Ážô ¯©K<¯fW²ú1ãäm+ÖvßÞ$L¥ví¥WhkîŠ Ú[@éc¹¢•Ï•¯€Ì»€Tk0‰oSÉ÷gܲyÕ ½Rº|AAŒýÜÌï[z½¢™âq‘7~¼äÁÈC–Þ°$_°êˆ,c5h§ŸXŸRð°:ÌŸåûòâk”¼ ï¥]¬lUSt³åžÜÈs,:ŠÂ\Ýú/ÂLº·ƒ8ÉÇ m!äkl¬ Nk œL_J4rKA‡ð¯DA—Éü„߆í'ܽâ‘_˪V˜)ü–MÀë¼â.@—‰ÏÜZ:y¡xÞñhŠgÒÑ^„77Pºh¼q+ÑxÅ€§¦Y¯X‰sPv·ïÖ‹Ö¼1°ë“zº–T ð òœBçÒ¤uqÔëM>ͺ®€ |oâŽñƒ5úó=ê%ÛGY,Ïì4ÎÖ‰üô‰ß?þE,+Ä. tµæé´X­ˆ(O¨2‰Ì’P©±ÆWÓ+u¯^À‹àõ“žŸŸý9E]ÃŽ)q€… îLy€§” oM½×ªŒá$AU6ablv€þuÜ{ß /jLÊî}ƒ©yCÉïü9zÄprû¾1ô¾Id7P1qŒß78fEÝû&¥÷MDT×½o~¯Ê¦¿Žô~¡‰võ%Àuʂ߃Uâñß-tFNgzc¯=;ì>‚bG—²Æm5 1…ѽ¬îÊ{O._ ùÆD»Üo@Ó8¶ûmᦷ‹#Àˆꯆ¥ØÛyépo7°ýqw6dž~ë ɱÃk»ÞÃ/›‚g{ÝÝ¿Ó Ûd°¡§P4ì¦CÉÚó “1nãøÞÞ: ÿµØ:à'Ýs’Ú䧨•UIP1ɨƒòbŠOÁnúD,q¾áÅË*gñbñ‚ÓÐø])dYj†as*ƒœŠÐËô)Æ@å#‰—¼ª)XÏ3´«Ô –•xà¾k¿‘~° 0Eê—_ë -8¯ÅÆÿ¸+$õ‘óm!ÓÂqÄ’ÿPžãÇ—«Khñ¢˜îzD·óê5¬[|ø|‰¾²Òÿ åSgÄ-N*›–%a¸iZVÔß5Ì[(²%¯¤Ž b^Á¶MPž¡sÀ!Ð4Ì/ðËi+ ‹bVÌN(¢Ô`@©î“EÏðÍ'Še3ÇbŽÇW¶Z–j˜_"Žš¼ýÚì´‹׿_(Ë+ÐÿqY¶Ë”ÝËzªÊ UeÕ«Ê•¨O Vå˜ þ‹»ŠœPE6²(¬×•ß;%Wd³’®"[ª±j¿w«.JèÆ3êÙ wíSªÊ)”bmäPŠs>»¾ÆŒ2ë¯Õ*é=[ôVýµpç³›|ª¿pfyŸQ=ý€íŽsáÑdRw¬ýä`-–buñÒá3°ýqw6X¤É_¯ÃÆaý‡uØX¦ƒ& É[$<⬃›KÛsA©:R‘‡ä¿V‘ õ*²Š7Ôo*rB”=¦ÀŠŒN¤šm\“QÒðªÊÿj¿ z‡(üWrlW jœØ¯[-ÒJVœ8…6Ý"ªUñó÷½ÛI²iʼnKìdÆŽ“±ß7C¡2 ‰ËF¹,ÏjŒkÔq—]ý"`‘uþÌÖ8ã‡`¨W­¿€›½5sK¥?‹ÂÆ;êõgPXÀ0OæL Š–vwÚ‚ÙáÿÜpÌ¥½ã;)ˆ”ňœeê€ÍÀ•±6›@“Œêü¤3ñs˜8m & À1,¿1®†Ï×þr¢¬YÅ7<Üu^´¯Bõ?ª®EbÑA¢$=$æ‚D¯HôZûUR¨š„E+X´“tÚ¹€Å\°hó‰N”°èBéY½Æà·ø!§Å‰qš[ìÒ4ôz!0»iêÕÕóny¢´Lœ•c’7n¥Öë¸ØŽ ÇœÞÍ·Œ“iÌ®r‘ÿ6› ÷YGl ×Ë,‚rƒp3Û°~^W(Y.tSêPúm…¼£ô¥ –ªmìÿ{ö"¹0Ž}É}µÊ¾ 3•K;¯ŠÎ4yÙ]á‚’!òEMd’„üüt)(®*o†iIâ6ʪÂWÑú¡Í¬jó‚aìF­²oÔú}óöðwÌñÝЗY„8«Šòdôˆý öEˆ £m]í¢'mˆ63ÖãÔ‰¨i¨5Ðå0ÐÌÙѰg¦@çuH˜~A(|š¤{fË,Q+I™97¯z“=ízÏ<‹²ãôÚHV²Êîyôè׆’ÂqØQëÑzàÜná/G¥Ä>:MHðwró•È•ÈDm; J endstream endobj 243 0 obj << /Type /Page /Parent 342 0 R /Resources 244 0 R /Contents 245 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 244 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 291 0 R /F4 294 0 R /TT4 421 0 R /TT6 289 0 R /TT14 297 0 R /TT16 298 0 R /TT18 299 0 R /TT20 300 0 R /TT22 301 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 245 0 obj << /Length 3957 /Filter /FlateDecode >> stream H‰ìW[oã¸~÷¯`_¦T+¢DQR€}عí¦sÉ`ì}ivPhd%Q×–IžLúú÷aÏ…”å‹âAÑ-Z`aÀEžCòœï\¾çóÉù|®…ó›‰ E?xè4õƒ40"ÉŒ¦A$æ«Éù‹6EKkÑõäü‡™·í$ðƒ×“©{}˜\˹7|-oK|†Rĉ÷iþ×IF 2‘~f`“(µB+–T…o†ýK„A Å™øü(fuçMUâgò®l+xüD¶âûÎÄß~õ¦ÆdSwgböPuÿ,XÃâ¥h™× ošÁ ¨¤ѵéJ¡ò•6 Œç/ù4*¥ÓðI|/òlA#ªzôü×ÝÜQ…²­Ü/+îHÿ«ùD‰JLB£ÀœJD < ¢Pà‰RÑ”“›ÉsòlHîÈÀ:l)|I26Vb`½µÖÖtа÷€Êø¸_¼i ×®à™lºM¾s8Ÿöc9óbø|E°œÚOåº-Ë=”ì`ÂPÖV¾ ¹‹ §Õ·U]òÂwÞŒÊõb³,Ÿçmyqqu_Ö¼oÉ:Û¶Z×âg™ßß[5hz ²`êîÊF<ƒ)¶dW€ ?ˆŒø*¸*_>€dP˜‘sð*°Ÿ7AYÍNgôÄW¸†T¨Mžyó  !¡D’(x rÚÀu'gcÓÏê8F÷æã0óS=*~bºß;ð„Û ÌM§>€ÖGåµÜ\Ö]@12¤ÿC·øa˜fÖ„~ Å‚ùÌkð=ÊÒƒ(IeYà §îf’œòDqq<ЈŠVªùñžr›‘ùª<Õþ–ÿŽaЧzk÷?½}»g @I í(öh‰ÓG޲t_ßµ¼¾ß4p%0/\áKE™ç“Ë„®Ð3æÑY $ž}"Ž‹Ÿ˜v{Ç©ŽãPçë=é‘y›¾µ5Īæ‚JoPR9®PK°+µ-œÊÎ+ˆƒú ËZäU€ *- oúû€Øc·ŸÉ?M‡å5ÀðâWáFH¹Â´!*©(à;TÓö¢ÇwèÀ” Ô/ * 8´ÑþÞËØô˜•­—B¼´Ü TVãuý£‡9ÿz½é¼(Ÿú Y‚™ƒToá¥úÆÀYJ`úhÊ¢¬¾x ´d#(ÃÞBðcçÿWsM±Œ¡†¢âŽ9•ŠÈ~\`FrYŠ/c7"_.·êIà¤þò+±°vàIž/@'ç’vßÔSk ´ulz[ë„2+—\[‹Ž‹h&×òºâÊŒù+;´17‰â­m’Bœ„ÖÆm¹˜žSì0_‰"ÑAyëÞð„°.µ+*ÝÒ¿XóGþ&\YtÖðâ˜óªÝEåÆô`+_¼¶«§mæŒÁº(¼tÂÕŒ;a{ +yCS8¹Xºå%oîÄÛ qBôò¥èìGÁ{óeÊ_Z‹ïù2Ö»¾l=¨ön˜ Ö5† sJC×üœŠ‡9pjâë(JNí't“sÀÒ ©‘5 rª:™R³©Cy^-8;؋‹ûR²XW‘¹Œ¼!_ö|àbòqb½I9ÃN/B“M9|0¼Êü–&K±Øæ#.¾ƒ+°+ÜÎü‘ÅÅÎN{`Kì^»Ç±`3Ò^`wǃŒ ÑBA@Wš4é­=¨ªËnÓÔ~¤Á߯ÞÈ phLx~) 47Ò£3*"b†÷HáV!&¦ºxG× z=ÿé¾~ýj÷)›$Šõ¢ä–n{‚LÈ9¥¿jiOÓ´.àóš€PJ"õùýÿ”Á¼) ]’˜LOaH+ŸœˆÌþ’š$Þï”ûº–‹>–MŠYn”kú? 0±¯¢0~‚Àˆìt´÷ŸÅ¾ËÎŽ÷]#â'¦{ëq32=J`âLÁ¡Ƹ$˜&ÎÄè!ô¶ôk¤›ô¥1¤ñgGZú=.¢âÆI>°é™b\XîzÌM[ž‰ŠL}—¢ÏR-EüÀÐÿª•¤‘Új‰ÌÃÀ¸}ç©…ÁºwÀ?¤¡ß©¿Ó}4âëñYÄ™ÇÙˆø‰i‡³îõD?6ÿmý}œ„À+°S[Ï*ö̲õô€‘ÒÃÙÚ$7qïaµ‚nQaªn°(·[ͦî 'Ãç•§2\&îó&wR X&ÉæœV¶%KtXp¡ Ó ¦=n=…•7â|cñÇoc±†j™ØL2`”ë®üÆÂoÌ6úţƫĎ8æÂeú~Ç“Xg°äÓ`5:–ØcwHËן;æ•Ç™ßêÄÉ…Sö€Ù>•¼¤ãȵˆÝ!/A&£¨]§!ÿo›O2ú†ÃKù â3õ—øºæïåB<õÚCŠpñÊÄ‘°èfX²q‚3\ò²÷ô/.ù£xA•;ãÊI+÷’G:(½Øžå¿À ²¬[j¾2B!Zy`ÌL‡J ;a*©Ê¢m2ÒÙA· ZêÇK/’üÆÿè7#¹GÉèÑ3÷"i?-˜L,iJ[äFŽqëpjˆc¹¬aÜhiU‹+Os¿Šj±e0êèƒ9ºtHèªû!Ý-6°•ÂZCÏ7vØÀNgŠáfUòz½é¼›Ú“ßÄä÷ž'Ž'4eQV_àÐ %¤5†8À˜ÌÓ H"ÏÎŽ÷y#â'¦{‡é8¡›ç>ÏÙý8¹Ð`b­¹ï™îÅ1:\¬ Ø@Ð$”ìW‹}?h?V±Ÿ„Ii¤æTo_ywP„µüà%ÄU ßÜòÓN´P~ ¢—à7óÍZü…óï>²¡˜0"+^æ²ÆËdòÄU+½È$©Ay6ÛøLl|ŠïìÞŽ_ØŒ¶Ç/l÷øÓÛ·.Ú-ÀEAf~'¾¢`IãX%óì8>.~bÚíBa§+#Ó߯V¢ q?èß·<_Ñk¯¾–t g4,­¥!í#–J„hË–ów‹Kb"2¼rìš—uXã¡l–8ÈùÆ6n¤I›å<èìò…È ~ë !¹ŠÖYµV—h;È«Ÿ·#>ø½ÿm|&2Án\ÿÑÿoöÅ#îöÅz ÞõþwÄ+j‚dÄ‹!‚êœk åh{ 5±ÚZ6J{ËB?â,‹9¶ƒ{ážÐ欸\1cÍkp(vÅ¿±_-»mÃ@ýž ˆ]‘¢héš¶é% 8·(ünÈvæë»³KJ²%5)Ð äâD|s9;;sÍ®;9 %C:d+xõéû|’?7# ‹Fæ&Ž$]ݤIM€B•ïTå-†²œü†áæ§ÈhOÂh/ŠUÑQ›cR lr{}è›ý# ÚÜß´(2×ùOËÆÏ‰ÿd¨!ª‘}´“Yð &ª?´7o<É}ÁƒÚHª=h"träB¿û™”ß°Ø2Œº”8?¬×”Eµ uâB«®ùœ’µMRêX·3AœIhé!7#É_pñÛg>åÏÈ;ä9nBfH÷BŽûÞa9>0ý…îÖÞd,måP? ò~/i4Iˆ¸Ñà&å€,ÊrjLxz´|Ú2L6óú‘¢<.JÈh[ÁŸ÷=VÓ‘¢i¦ëVJƒÕœ3_xbÞi²R'5.laªÞw€2=qö'c³ðFÈ„Ž‹Lu¦[Üs09…þ(Hyë” — ÙžrR_\!ºG¢[ä&k-IÅ«u¦s^ê „³–¥fX3c9߉ ±ú9PCN†a7ØË—Þß@¾ú ÝaoCxrÃt¨ÿuTçYí¹Nh5”¢2oÿˆ Ùj’ ¥â?cŸG2Å÷]]*Òß™˜2ÈðÝn~+C|ƒZôFYÓP½Òjçê,}s†ÿ£3=æLÄŒìüjSh@q=ñK-íÐÐe?‡ø­6äaö ›#Ü”b˜rLãHZW:úÀnçÑÛ•î x3Ü uÍ ÜWÖ#Ç"Ñ1º„Š©ÜDßPÐ âemß]âÜÙ–F5—õâ…ùÓŸ1gÄÏ;~ %Ê›Z!gs¯½nZˮÓcTEÁª-£l0ü´8áĪI‘`b†ŸYÊJuq¦üÙp+‹lù(êtöÎcG6—S¯¤“غwÌIÜéÆ=§ºÀžiIl@N%úV ½ ðºByl»Ö Ü遼¨—?~×çB•Á à. Ð>ìEúÿ±”ƒ^ÃOl·jZÆÖ^ÃO.:5&*âͼà¨4ÿ¬îÒ: endstream endobj 246 0 obj << /Type /Page /Parent 342 0 R /Resources 247 0 R /Contents 248 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 247 0 obj << /ProcSet [ /PDF /Text ] /Font << /F4 294 0 R /TT4 421 0 R /TT16 298 0 R /TT18 299 0 R /TT20 300 0 R /TT22 301 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 248 0 obj << /Length 3084 /Filter /FlateDecode >> stream H‰ìW[oÛÈ~÷¯˜§bX çÂá0oë$›M›‹ay±@½Á‚–(›[™2D*Nòö?ö¡ç2¤(K´ ´MÑ6 rxfΜûùÎÉùѳós+”8_)-øÁÃz'>q"Ë]¬}bÄùÍѳ³†ö$¢™ÕGÏ^O•¸jŽ’8IpÏìhÒ½Þ]ÈÓ"š˜ØÊ«ŸZŠÔGÏÿ|”ƒ\dIœ;¸Äøpè†Ïë Yá›cF$VLð‘‹Ë/bú¥n£‰Êâ\^—M¯&Îd#~x},þú÷hâb#×ÕìúXLïªök¹†)l^Fp•E=&9¼K’ˆÔ&•´Š•u¬Ï_²4Ê“4,ÉÝÝ]™ØÉ8"«/‘‚ÿº½•–MÕxÛìšø¿:?R¢GÚ)0§&ƒ‡€…Ñ%òb]-ŽNÈp!¹#ë°¥ð%ËÙX™ƒýÁZ[O º÷€ÊYÜOÑăÚ™Ëu»)–âä³q*§Q ÿ_^ÑìÁÃÆ^®Ö¢ás_@%û˜PË:œŸíùóŽ3ª¯ªºäï¢ SËÕ|³,OЦ|þü¬l§èœô0³îÄ[x‚O6‹E¹¿Êâöö”¸¯ªº…/dR0”NØP`ÍÄ8Å>õU¢.+"ðË4‚{¬,›W`P”šþê˜vÖOcetx";yÿŽžÌ,ä†Y¦à)È{>JM]OµiŠq0 §:½=þ¹¿;‰] *}àðA2ßHÄYCÔqÄaz¦dŽËÕj)Ð$OèØä™ë‘XÊôƒüüqµŽÑâ·œE {³á—Ù  FÁq„CL±Zx6›Å G`RwìÑ"ßôùóçpO¹^ÉÙj^2üÙJ°@TDxKµ Ò¬Ë=»ÁM z0ÔÇÌ`ÍÑ¿U?ëqfN•TCœ™Î4Œ3 ãLK8Óœ‰ç@_°A¿Pi†D4R:”™IfÓ¡Ì€í.Æ,æýÕÄÌpÖí%téöÐ¥y]z—¥ß]:È?Ú‘Ç©ˆu Œ„<¸ÛŽ£Ëò(ºLsBoÛ¿éÚ]”Jô Æ y&Â1ýyç¥Ê«AÝêY€›#œ@Ñ×°Ø+ €“\MÒ71è·psÊ}»úzbæÚ§E7 Ž“ &´– ˆH/§U3j“{ÀW[5Ľk×ÖEЀ¥û†X(Op÷O{Ò¸ûÒh,ñŽQ­‘WðÄ‚CŒ:íÉ’fÞü›@nê3 ‰‘ЧbXêxX„Ü…uz=rÇèO¹i5gr÷[.1/°xXÙ¥.Ö+¸¦¾z| ãÜ´¾ºû€íBžx­ŸˆkS ù;®ý¯Áµ=0¢BtÄ Â> WØæ.°µ:B~î¾…Ë)n;;f{-^`k»]UäÒ=“-- gò Én0ö˜Œ >‡Â?¿-Á½báî{€Ý™Ý:ºˆ ŸWð÷¢­n9:2Ž {(6’Ü t2¶× ‘_ˆ 8„äXÛAAF°ŠtÀ aÖåú¸óñ ‚3MY€#ægÚW¡­s )„¨†a%`ä¼, Êð* ù òï"O¹‘Ë«} ¬G”ð€þ¹Î²ûešÔw½úÐ I}TÄP}ŠO”b}Y\.K‘ƒKÑ^Ó“àvØÓ DïZ„%Ýtóþõì·Œ‰~~ùæýkñ;vž­„;Qˆ–„€#í†øc©Á(£»æ$Ñ^ƒ(½g;•mQýûU[> Ò‡4·Ðùß,"5¦â&ŠÌçÅÆìbòAAE¡ @$€»yGx ÈE7‰,–aï²ßÆZãŽuMQ,—¢ hóò}"7ðöe„CN)æ¼,°ÞgØ/ÞF˜â¨H;ùâÕ‹{F#èo¼›a4|üüBä09Óžðêå ”!¡YÂÍ%_µ'oD9à0Oî{F›>CM¡h‚&"f 2”‘YQÓ¸â¶,ZúÜ€ü9åÐD”âbNx §$ÜËC’æ! å;ÁÎd9º¨%ü‡q ‘…œ®øZúÐâ$™ËN’:Њ$·§ñDš…O¼qSÿžûQ9ˆ¯ï³æ¿`Ö ›~;lÒ¨éwFMG£¦åQÓò¨ihÔ̺Q”52¼ªVaÌt0fš~Èt’tC&lãÑÑ ÇÌ_0}r¹®Ú’ÆLG¼»)Óð”™îM™ö)s§\›)ÓbÆè1H:g€¹6ù_˜3áœÖz!,’ "!#Ã4ÒŽP%¤w˜€é·öŒ·±õð8£+PÇ£käø#äîîÀƒöÆèOöŒHhÃÞyª€<Y’÷´Ø¥O…¡£hé3uuKPb»ŸýÌ`ö³Üm?û™îb3jNPyž8ú(?©Æ&õ}ôû>úý§G¿ìÞôƒAΰ X~åeI€û‚¿Q øCbµÌAIõµïâKîŠñЂ0æXÎa ß ÅÂÖVwlm8³M³,)Úr»°.E4²‹øº Öl¾5ðÝkèLíóT"ø•¶·›Ú‹p„”à•Ù¨ÌT•†A¥%Pé:P ç@]j¿a¡Ò,3–Hé e&™M-°´C`ùb¹jJæÄW‡EÓT«šdàuJäMÌrˆz·É5EÞ)©¾C W+.î5?ž€(Ÿ„\ØÁž:…\±czœŠè PÇÑÁÈñGȃ»Õè`Œ>Š=µQ= Ø‚¥]kh˜VܨD£T²S°Æáã»»Í?Ú/ƒa ¿ÊŽz DÏž¼ø(M$AFˆßÞõo¦¢!ñ`b¼m¬[×­ÿ¾mFNgÎ(¬_üŸÇJì>ÅJ™UiÚ✷BJ>9Le *>㈿àÜ6¹n&ïdëôžÐƬXìÝ…ÞÈh„1«ñªLUHv—%tª¦ž:@MÍùɯQÖ/n4R%> endobj 250 0 obj << /ProcSet [ /PDF /Text ] /Font << /F4 294 0 R /TT4 421 0 R /TT14 297 0 R /TT16 298 0 R /TT18 299 0 R /TT20 300 0 R /TT22 301 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 251 0 obj << /Length 3668 /Filter /FlateDecode >> stream H‰ìWÛnÜÈ}×WôSÒ4»y÷›miwÙ² )W­aP#Ê3±<#p(ɳ”ÌCNUus8JF€ ‚d!@Ãf±««ërªÎ›Ë½ƒËËDuy»g¬Šð‡Ÿ¤(¨ˆ2•—Yh‹(V—_÷Þ. 5^ð7‘ZŒg{?^õy±…QDߌ÷FþñiïJŸUÁ(ý¹¦_«UZ/ÿ°W²‚RåQXf8$.ܦ¯²ß椊ž2Qôe£(Q#ú)ÕõR],gm02yXêI½˜â1s½P¯ÜWûg0ÊÂX7Óñd_]—¨`ݼ¹—4L […ÅzgTz…®šzF!ÉuK¡Oô 'S©ëíȃ§‹Íéò<Î%Ìû”Y±Vcè(4¯K*ïïßN€A9%?ÌÌ4™o‹Ì‹üÜEÙO!À2¦€ TL6³ažä«½&[U¡ÃÁ}õp~Bó“2 -Ѫ ì*²—9PM] ¢"‚½F·m€õtö9@¡•„ŸÖê‹,ë Bv.eFæî+ Þ⾋’é-””z:®œÒé\>œm†}½|½ÝY™‡EÑo¨ý|>«F^Û‘Ñ_)£bM°H•ˆÆÄÏ蟋W]–Zç(¸#GÇ¢™d>•ÒÂUö)Õ‰Ñõ“üž¸%üSâΨP«¢}5hƒ˜¤?v7Ê|)fi”õò´›üTŽëéc@­„üYÀÉÔ:T;‘wŠÂÒßÀû²’k/yõ{ôDë·ÊÎÊ} ›ohh‰õôÉ êŒ„W¼kÙ¼ØôÒÈÝÜ”fÙj­0E©žµ'ŒI@½+©íi@³Ì, IdÛ?y•YÒóOÜùÇa¡:ý㻀[œûQ˜J}‹…dZÀP‰A…ú¡ª®åaN×ÍiB*ù†èµ¢™Vð^d¥¯Ð¼ d ›§šù¼ÝW¢² "žèùÆi«U;W•¼óq‰5$vÉ9 xɧ83Dù®jÙòG÷1iWû=åÒÚô»ó͆߳u¿·Ü¯&WÓÀ¸üœìò3r6OË•Ÿ£ÎÏÖûž¤ø×ê^ò‚Ò!u¯QÏòºS=#¬F+*e~;“*?ºr‘¨™Ï0ÞÝ)ž{LR™bŒ“M~O õìP‹¶™ºÝŸ·ã.³é³Öb†F¶žÉ¼cì¶c0ïåqºrL’v¨hRç ¬â£["S_“ü¬;TX8jÎP9ÜÆÈЬÈ;ß'¡ú¼nš ‰š[ÂWÈÛ´³m5)‡ïIsýà(Õo‘ZÆW*“ós^|úpBS)†ò@I·ˆnì„ý•Á2°Ô7gã÷ôHSx¤IÓÄn(ÂF’É´›ú‰4dü×ÉeÚÓ¯õ*ØKjÞ&ß —¿êПæÙ3„sXJYî¤ÃY>°ý±?»(Ãô™¡Hþ}C?ìmoè7«øš¼?ö׎¶Ü8ÝÄŸÉÄŸPë¸þ"oê¥ü*¿Nàß^/7Rs[8D¥ÜA¦­;£ñ ´;EͲF9!Æ…€ÕlŸ¼ø>Þ@ôÕþoøßå £ÕXvÀ©&E$ó† ”ˆ€‹/½T­,ç,ó«IuܳÄéh8£»Ý3÷½¢o#xòûFwTqïî€bÀ‹¾"ÿZ\—P}&³äŽñ3­KcüuMÙR'p"RM*\ºfuÄ^u’]!Fðhy-ß|™k5(²y²Ô:E^á½üpÕÓXM[©Kõ>iäJêäè¯zý.|éO"9É¡[þp|~!óU¦0‰𶏯öšŠ=ÑÏí?=ú‹ß®:;3M²çÖr¹†]:rŽÜ(] T]FÜYƒßJ=]0zµTµ’’F@I¤\¥¾þÂ?R[†k«Ô‹úäZ@' pq}:>ützôgÒaÈx5nj²ºR³5MOúõìiùýŸp£^c_önB,…f±·Œ)G”ª™>§|[áwŽù0&pl)XÆ«£Ò>ð@¾‘}ŸN碎·µ@,_!ODr=\D4ë¥HÁ¸+¤¯e…¼kêþ¹§ßº Jw¸Â é·Þ’;s= ¥7çN[:™RlÄNÞ ¾):°p´‰ª’ùב¥²²ס[¢,eȼ` ¦£ÞuÐG®¨ŸÙîª2îÁ"Ъšqê1Ĭ¤-+ž°ÈM QÒ‚»TÎ:NÆÂ÷ï6õ:{>ToÜéîçð§ñ¶~ó?¤Vþ3]uú@ZåéF~œ9þ<1,–0©ñXzû<“²‹ÇÖöHé Má^ŸÆæLcc¡±1]—(JÃã·ÐØ’ëß2Ú¸…ñ$Ý™%žÄæZÔxË–Ê¥Ga뻚Ø)©’³iüâeÝ;@ø¬Óz¸^JÃѧfŸ]ÑБo\½A€tg¤ÿŽ wz|UÜÏcéQ$í~œ’4B̉ô“:@Ô‚7â‚7³/·_9Ë€÷‹ê pçÕœÃ1`Æ5 ³LLixàN1šóÐN†Ô†[—#ÛïÙ‚ü2¼[^ ïR xÁ.€'è½OZÊ7Æñ v¾$š0ïøÄ0#¤Â')r;æÇö Ÿ`ÞŽ˜ZT½Òù9YB1#1d e*Œ‚;¨Ã(E3/ÞYûÄ‘}Ô‹Eàä[ªÁ#ò®„u¬x”¨¡™ ¢É\)‡®“þ ÒLãw $ÉP±¡géN -ÁJÞ«&4Òö>EB^¢¤GØ&<ޏæz+¼³È o«ž&ž±¼œV°áQ¨§Ž«çÀô ÃÎ7¼ ÏÐ8ÔÓrÅiò1QHw@G9o  fg mx”×KFϬ×é醭ÿv=¸7{`ü:Ú0†à¡K‰*B…’Åc\ôÀ„lDu¯#r4Òðè ú(ù}}±^êC¾Ûn‰êùÍfm§èK;rÆü”Ž9œ¯l½æÁOCòàªkP"`ÌŠÇ 57/N‡X¾ÒµébY×¹ÚZ»¾]Uþ–ÇZ|ã©%{iV¥›tQBö6j¤ýZÎ4_D·ªœðÀïÞ4¿¸¶!‡éu ¤Tt)_@ë0–…,UìÈ %k$\ƒásœå*‹U@TÁ'A%ËF-‰<‚èÙǰ>1©ãˆ©’Þ'>çQèŸâ¦8L;ÜdBû9*èÌåEù‡òBš7cB\I³©³ßéâÄO™u"vŽ’€[wˆ(qõ&é´BÔɨÌň—/t’ZúQx;~ÿÅ‹×ÔÜž01YëG§Núq| Ò-á" ¢F*e#™[ªã]´|Öôf±Õ¯C§uÐgTò=?Ý’ë?Ñ5ï`ÚÝÉÇ 8h2&£•4žåoG1œî18xþ>"äÈ –}:û"ê·g¶ vˆ3×¥”w÷ŒÒ »dôôÄ %N.¸`Ã6 œ™Q&0Ú<#éQžY• AkÞäYO{BHñÓÒ#*HÚfÁrÌ5 ¼!¹S’ó/Ô†| endstream endobj 252 0 obj << /Type /Page /Parent 342 0 R /Resources 253 0 R /Contents 254 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 253 0 obj << /ProcSet [ /PDF /Text ] /Font << /F4 294 0 R /TT4 421 0 R /TT14 297 0 R /TT16 298 0 R /TT18 299 0 R /TT20 300 0 R /TT22 301 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 254 0 obj << /Length 4126 /Filter /FlateDecode >> stream H‰ìW[oÛÈ~ׯ˜>u°Î’ú°q¼ÙÖvmØê¨´DGldI éØî?êìCÏe†¢d1Ê"»½@€Èá™sæÌ¹~çÍdôj2‰…“»‘6"„<â, Â,´"Ím`²0“ûÑ«ã&Ó†ö„¢™.G¯Þ]kñ©…Aâžéhì_G7ò²Pã(ˆå§ŸF ª“?r‹4 r ‡D™cºg~“¢(|³,èŸÂ„a,ÆøÈÅí³¸~^¶j¬Ó —ó²©à5 RÙˆÞ‰¿ýKmɺšÎÄõcÕþ£¬aG› ˆe±œ©q/ ’4¢kÓ•ŒtlSXOÞ²6:#mX“ÇÇÇ@E• HDQÏJÃÿ²Ãµ‘Må ¼m:'ù'“‘•«ÁœZD)<,"#P£LÔåènô†¼’;r°[ _Òœ•ZØï¬µñ)ºñ€am¿¨qd²RFÖíC±P.å®UÊ=ŸÐŒ“1XhU‹†¹žú¬[€ý"¹tüS¢½~íå± å§jYòÆs5FKÊÕìaQ¾)šòõk>³l=OùÔnv•â½,ÖëKÚ³ª–mY³gÀ&d{DqÙ4é»&깦8-ŸA4ºã'ÏêMÚ„Ž“íÆT.XÄ×­†‹%Òz§¥1¤iªá)ÈQ=w¤&¶£ÆI‚.ïÑ“Y<È~€ÜÖµÙü—Ìqæí:gq@¬m²rÛØÇs5Æx)TÈ!”C^«¼kü8ˆòÔ~“ñ!ÖÐú胗îÒ<11[êPìžav[‰AH}¢RŒÙf&hw®´…Û®†°92ýÀJ|Ò) þàôùÑ×J(qïR&î©svrþñ˜NÕòzrõÒ YÖÜ$Ù„2ìq»Z-„šü½oä ÈèÅÞ·ÁJ¬TVŸÔ8 ž,ù9ãVIHÚb¹«5„R§Ž;uRý˯/ïŠES:Õ7 jãÏÀ­ò½¢-^ ´‚(ÏvÞÈ›õC î´!D¯üRQû°›žqØá¤Rz2õ+鹟ýÙŸdvUN@è…ñ÷Ý5ëŒ  æÖLoМ9EQŠo\õ1hu¹¨½.[Ñ*8B–¦F>ñBÜ­Äf.ë{¥!…[±.j p6I_™êp#4´\¾—ór)–ÌÊä/ýE-¦…ÒXÏ >tv$¨fƒ½wÅ/y[ë7­{] ¦3hë¨E]Šv¾jP›T–þ3„1uR+–:÷>ùÃÆV«[¯dWa´‹AèÊifl/JÃÎŽPíä˜Æ~¤“N0aûY ›Ûº#ÅpQ8ï+ŽÆÊô£Þj}öA•Í{e-wéì¤Ðv™ö1`³$Ðý2mrV㲨©FàÔ±ŸŽ±/#J‘-–GC×]¥5>¹³05t?Lr¯XÄ‚‹S(«ÐÈŸºA™ e°ñ~ؽÔ~«ã^ɲÚ宲¨LB)V„¡Öô_ºïâ3¼™–S1/hÉUÊ×Ú¹ÂØL>²Ý’x«‡)lZs0TN.¶ îÁðî„èÅàÀ4ê Ó•o1@·܇­¬¨UR—l_héDíX:Ù*ëg`îŒT²ˆ¿0%Ê“å으@¡eå'›=>€pMu¯¾ã}¸‚Õ]@Äf¢ä—™¸:`6+ïÀRPˆ¶h±ÛkÈÏíJs‡Ó®EÅd'Ñ t»W‰³DHhwîzQ8±LYáÈ!° L"m#.xkçd±èV‹Ge@bˆD„Z3†°§×Ï8È !Í6ÙyÅl7vÒ­f‹‡ÑA«UJ“Ç—7îÂ'{é»>p’s‡ö9¡Ž];¦Š9Æuk"|¨¨ª§l ”AøÁ±X2—¼r{YTƒ‰Á±ú#&w ÊapÖÑüÝòC´åÉhI.Æ„S!2Š‘AÊ5ŽsQµí¢< %~Œ±}·¶\xõj ·mR÷Š©«‘€5Ô.rÍRoâ°‡N®Êö¡^BÑsÕÕ~­æÅ›‘J;¨z¦L^0V=†ë[𨒮®hññâT¬–d‘Í¿L§eÓ(,hG k²¸Æ”Á5l–Óswu'^Àvø¤§§'wNY×À1¥r€ÃÕFƒ; ¦Bá)ÕÂiS¿@ÀÐS åÌœFqÞÅæÖH‰ZÝ—¿pªLzPö7›*Ý`³[“ úÂŽÃTÄ­Ž:Œ[Ø{g›lx®¢Ë`™Øpnµ&;ƒ\,ÑŸ,î XžÜÌ¾É ÚNh£±"±€ˆA RÉ=LýŠ{ö³ û³SdÃSÅùÛ†Š$΀±(¦¹×D„dRÉc…Åfdà#µ¦ÄÑ`º¨Ýš,m[‡é»M‰Ðæc¨ ¦ vݺë&>rzXׅίx#¼îà5ýäšP_­‚¦{p'xã`LŽ™uß µD‡QËÙV„ÊJ´<‚< ÐÊ’šbêsìàF^¼=ùøDí‰{À&ã½V!x•C‘ˆp"ޱ¿wÛv ¨¢ÞW´•Ç™I#ù±õZ?*ÒÐáRŠ¨Ì x10H•$핈ߩ‘ÐÔ„†:6ÁdIØòcqUÛ7Ž£8È"èE; ;ÃgøªKEõ‘1E+ø¥QhšrÆ«=h©÷ÿGKß–Âlsÿ¤ƒKyÐM¶SN€I3`Ò ˜,¦Ø&äƒ Ãºðe0å˜æS.YL¸‘qí¦ãŪ)O}¹é e ä$]’¤Öv@zûQSÄ@»‡š¶†ÖS•R8$Ü‹ž°Ø~ïïôí82͆zç0û¶£÷íöäÞÙf¸o¡oïGR±»V-Á€ýz†¡_ê2D$3ñ+VØËüuª?Š^ëµ”ïÆ`äù´k™‘aØ1S`¨áz£(™‰hŸéA s¡Ä©UÌéká¾òÖ³/Ê@ü¯ ±·[BEÅ{¿tüŒnÀ1–úCìÅôÁ–N³iâkhÍ´¬—Ì×l1²ÈÖÀbü†3…øçªòñ …éh ‰üÈ¢.NñÖÙFð¡nÕ¹c…1͇7^µß½h’–QÅw¡‹ÿŸDqg7½¹¾é°Fd¥Ì²ˆ YXF–‘…&d‘;d‘Ñe#¸a·Ð EóO‰æ‘E,YC¸‘‘…î#‹weû3m+ˆnǼ%#‹K¢­Lð‘¬ÏK\0ßFùa\ñ¼O˜0ÙÍz–3û‘˜’æ‰üA,¬k_¤qº8ÆI ‡Òš&ÝËXarp½jkÃTì§Ž:ÜPØ{g‡ñ¦eîãÞGç–êM¿c˜Ô 0i]½û#Nñs±p5åÏÅý¿©¯¶Ý¶ ú+ûT…äŠQâcØ@PÇ.,9¨á#­¡²ä’”¡øësÎÌòRvýÚ’{áî\ÏœéE2<•Rì:†›j\!ñÀì?mËÀgϕȳ­S†Í1µJd³Íœi,d³Bt–›žHQ:iΨ.œ£ÈõSF(;2r'¤ä¹[¤8"Žšcã -"Ȫw åš«•õ™”½àðd££33¿‚ÊRö‘ñ ífb©õ f‡×gÜeça›šd§ö®K\ñ±7ãiÓã& 㣢á{Däý&5"9f¶pOÛrv¢K‚+•:É|uBN ‰’õ»‰VþNÇ 5'¡ ;YòÊ:³ä<~3GØqÚÎ×¥èTIPí^Mì×Sdñ H9úóÛ«Õ½xopô×ÖßÇÑÃ89I[=lR° ¨k›- ðr_øë6{ô2+©½4Ï~@†ÉÁfoÁ¬ÜÆâÉ.ÈÕÁ~V~ê­­–fµã¹;&+IÆ0QîÌS¦{ŠÂ.9eê«”8¹áÎ'Æå?dË7fqþNÂ"p§ÿ#Â,2&ø¤_¦0ð(#93rúIžÖÍ›ðŽÈ$h(ÃRŠáv)»6•Z†îbê0Nj’¸[bÈ`.é㉸=†¡ÆB‹‘ ÞÝZÖ·,éã¾rÈÍ mA³³ YÁpµÿ¢`! v+_BÀ”ÚÄ}—]ÑWífð!†rDkO5wmGµq¯z{çP`"”,õž,ôá$ôáøˆ>qMZú4•¢jýˆ¹K[àMÁãÑ-í‹t BÀ¶:Q*¥ùÉí£ÿYk¾0H•¤e4™;@¾ýKûœ³ûƒS=‡$‡#Æ™[±:lºÖ¦JÒ¨M$x{1ÑîXàQR¶:õÇNßnGI3MúfJÔî™ê&pµÌôÖ˜xâê¸zg`¡V?¥ÞG`äâqšð!%}Ç)·j–Y™õ´w¢t£<ú¥$ïWþõ tg©Äv,±­‘}$mÇ'£4iõ¹AÝæ:‹õ‹`6oPŽ2J[ ãAç•S‰h¨ -úC!¯Tä)@ॴLj".›ÇØcŸë}¸™µ%›‡cG£Çà?Tý~ð‰™ºæû™˜Ò|ÑSqAäÝíˆi¡·‡»ƒcN§£–Â¨Ž³Iž ɹÈa×á3Æ%ÈLþ˜ñUêˆxO±'æ]Û— s¡R±w‹Ö5ñ$ §hІ,!÷òGµãìo_HW5Ð\0ø/—¯uä&¡¡[>È9fcÝWIq¾ëäWïÓ¥9%žW2Ô÷©³¯¾±ټبK„ ÌуXpèìÖñJSyB׳]Þ\ â€S6—0œ£‰<LŽ„]g¹S™r½Ë\ºq)É©[ª¯êWFVèµ²<ÃP‹Û²‘‘äŒà‚¨h [šlS¸+:èÖYEÅSØåW¥„›VÑôÜêRÝIçTGÓWòzÏ®ù®!~ §‹§:ws>— ïêjöYdH‘·ð<á)À—8`þ»š¹6øÈ\Ü”xËõ"+²Q˜Üþ»—Ï5j‰P _Ò“X‰¶H 1”jÃÀêr£a‹­´ÝÝTzp¾rŸoÁsÀÚÛ,ò(͉£š3Î/˜¦š‰õì£Èz&Â]_ËàþêO³ÛªÔ¦ØëÇba‹Â'‡¨«gÚ¡’µoŸÅ)au¼A2þ÷M‡ÃÁÝcó,vKP ‚x#ÁŠÀœù¼e½qÒä¶j~À‘{ endstream endobj 255 0 obj << /Type /Page /Parent 343 0 R /Resources 256 0 R /Contents 257 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 256 0 obj << /ProcSet [ /PDF /Text ] /Font << /F4 294 0 R /TT4 421 0 R /TT16 298 0 R /TT18 299 0 R /TT20 300 0 R /TT22 301 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 257 0 obj << /Length 5345 /Filter /FlateDecode >> stream H‰´WËrÛÊÝë+f• ªD3x{'Ù²¯b]IeѾqä[.˜„D$© dùòYät÷„ø°½I±ŠæÑÓ}ºûtÏñøàÅx)£Æ7ƪ?<¢,óƒ,HTš'¾Í‚Pï^¼j25ixM šÉâàÅÛ+£n›ƒÀZ39u¯×ú²ðF¡éÛ’žV«ÄxŽÿv³€\¥Ÿ'8$Ìܦ;ÙoSEo‰ú²A©=rõõI]=-ZodR?׳²©ðú©nÔÑÛCõÿz£Äu]Mf‡êê±j¿—5VÄX<÷p@¤‹ÅÔåxHÖˆÍf“¬ñM”¤ø¿mLÆÚˆ&¾ú‰n ‘D=yÿ‹vÕMÕMȲɌ埌ŒªÔM à4*Lñ~hi”©º<¸98foà@vGt)zIs+M°Þ¡µö+Ú;À¤¢íYitS]·«b®šÓE‹CEY™† ñúݦÅäåË1–DØvâÅsq[-Êß´åt5/‹¦|ùòmÙ~äùB¶ÏWåékõY÷÷nû%O/½‘Õ¢-kAvÚ@ì ­'I8„<@^¼+Ÿ Œ`þ­ÛÚAú&´ñp§‹c] ªÉ‘‡„š4J žty5“gQ‹U—£Ò¡oTš<;gà¢ŸÎÆI?Å1¹y0ÛÜÏ¢½Û2ÝŸø‰›4vÇæÓ[æ{b+Ê|Ä×:Û;BçÅ]éÿù ]ÿ€–êÏ/yã(æ™[@©Ѫk}}¿ª‘1IõCűùç¦"øg? {gÙ2ûìÞþ“éîì8ó‰,cP\´±{ϼËïÄÑ-œ ãò8W¼@Rº ïé°gFŠê[Ï»”ðÕ­zÏ‚?‘ƒõ D€™‹r}êÙÀõk/Å¿ºYÖjÕ”ê‘?+/ÃÒv¦ÞògéA|¿¸ò¢Á'/úXÈN8öø$çžz9þEúg3Áõˆƒ\}r±IžúY¶66ˆÖ÷¾lWõ¢yÙ]‡ÐIÁ›ÄÔQÒE–鋆q©ÿîäÓG&£ÎˆŒþB9Ba¦£×îóÃù»ó‹?¤jœê™Ì0©ýÁ¶T+y,eNéŠ)ܲj^|•ɹG]ªSk' [~T#:#`‡$Ï-”]ªNós¢©D¯x¬ìV¶|ÎLea혗í¨dWÃ,\nº(¤DƒêœFi互۾Žÿ+Ϻ*"Å!ÒW‹08áNqÀÉ5b¬‘]OÕþþÃp9qû'<×›H‹ .6²%‡*òŽšCáN›ç+·1IÎŽ»3ôˆI’’tÉÛ–T…DQu» 4âa=¢>dX8­R®ýá΢dƒxÍyxï ³íªR#Ž9õ(Y¨$Ë÷¶.왥Q§¯7ø¶Æ‘òñ!­XsjCíãµý³Ä©nv?§îÙþ“éÁÙáÊÚ¾ypêîb–„kf­âZ£òF1'Ï(ÑÔ man’lº e§$n¤ÐÏêºvaP<‰À\OåQºeß6##æê#Ã$ëLëû•:4ƒÐŽuBQ<^‹1®ëqáùÑãtWi@ÃLÁÖœ–ºŸ˜+džjØ0Š?R­`µ ‚åàÃý]îrŠ&k|Ûm•†‡kñÑ3•ÉÇ]V77¥GT²•S±ÉÌÚä¨Ï)w9Ei£Ñ¤ Ï‹ôÝ•g„µxü»—I=£¹-ýbßä6æÙ³”?^lÄ<2™¾ª¾ÕíDÑFfHYW”ÈGâßEˆ‰ØîXX=KW¬Õ_6ú „@Âùm7Òb×ä¯ôz‰Mˆ§·®øYs¾U9k»-k4pÿ§î/±–Û£=l±w–™JfÀT»·ÿdº;õ!Êöwûæ­ûKÑdÐýmã÷e1mT¡<Ž–Eq‡f;A«§Ô Ò®àOôiªZ¸…Í}9ñ¸¢ŽÏp(c¸*epжPöÖ,°h±UÚ¥º/dUÓ”STƒcïXà’ºƒ'7û•¹ö­ŒÓ˜B1Z‡b>ÅKº¡#—L$Œp7e xŠóé|ŒF±Ëjû£N1ìØüÇIüôÛ5É$`"t&–nšöš']¬‡‰‰©t™‹š G(‡x¦îL¸Ö°v<®þ…70 ã05+øs1åUóά Fîà b;LVôԬà êˆ*¦dBà–!¡ÈYç¤í)*s–P f”ÚPø²Á¿°ÁEOŠ­Ú.DtÔˆÈ-½Ý9¤wœ¬±O‡zÕð<Çÿ(¦ÓòÛ5µ·)q7U.vJ¶m î q0°%\wZÔtõÆ# _«¿G-*Qo‚/êºx"Ùh¼Ê90´Ž…c„™¡Ð.À F ÑœªÈ•™–1hÉOÅÕžŠÏX’¨ƒÏ„»%¼¡àÓç"kÅC¥èåo¡è,Ü@1Î6©šPó-€Úí\ߗו砣ï-è@Qa˜Â`]©ì¹)4£‚YIqGöSI…ÇÛ¿Õ h¥D<ÑE“N§—ö•¥¢;X€–‰8ŒÆŒG®?]¡>ùòÅtÿÆß¶Àp:ÀR½ÑK’Ç?+ù".º¦×Ý… ½XÊÓ­h ¦tW„ñQk˜ú[f`úJh¤`ýîAä„:çã>F75ZWÖœ7u¡Ôø,iÈͪiÑ;BUÙ…$|Þ§Üx)*6þ¾sò–õ‚×4€Hˆv1[ì£ñ‹_gaMõ½d+Y ãHGõ•Þq¶Î$ª2aQÐ\NÀ 97¸qßCÍ3ñÇ_qÿúúèÓe– øb¸KDs¨D̦K^Ómpêô –RP ÎI¹²_×$âêÔu5aS¨]§„箫iëŠ'o±}Ìvð1L›ðÛíLÌÉô dì‚P_suµzw›]Nˆó`à¹qpœ¥]}™pÎ…LÀ‘ž#|ˆç‘™þYRÐi¦è~"^Ë–ÒWo–µúxtæñ•e̽]¤?1] PGê/¼£[qòwϤÿ>$¸ø³Ã+ùrƒ°PË[–£æ¥{kI™ ~Ö§çê˜J^§Cž(qõÙSå7^<™‹ S¢…”˜¾nÁ‘Ãm£:®‹3uœ„Þù‡3Dxª¬9 3<1Oåîp 8,AÓ³j9K»ï–“S–toÝÖFjÃ:˹­òÈŠ¹[2ç/Îæ6Q5e«ŠyãŽØ g”QOh—Þ:#Üøƒ¨&r»Ce%9§M\ð»Õ¯NÞ ó½‡ú9œÎJËØ‡7c>Àè‹‹«ßY‡œ.½ !)‡ /v@°™¶‡>pгÃPm«IÑ:Ž#µêòß+~­PU¸_ô8Q‰5S°&‘£åºC!¶ÙHŽ­]’¥½ã£>Ñ'·«z¦n$ƒ¾{gO(7“.vHmΔŒñ¢dzuR‰N ̸Y{Ïc_.Þ©%ÙQà&»â÷ɤä/p×ÙÅzwØïs»)Ò}ñaì&/Þ8éGçoOAAñ8cÉ%·Ã‰vgRŸáF¸üÆLŽ·€´`Êy„…„%»5u*¶ÂÔŒÖÅÿ¨¯ºÞ¶‘$ø¾¿b%Àøý‘·dãàŒ\öŒÄÈn`, Z¢7ÄÊ”@Ó_]ÕCrDRöÞãÁ­á {zzº««X¥bÜ|A€GdL<žÅÚÿdƒböÍüíGYOÀü¬#º¹Ä1“ ÏÏ—ŒágnžžÔ¦ýgʦ¤Úì·%¢j·kXb9>‡å’2ÅÜQA§Vìø|ÔuÍ4k‚uê ÍEq‡QÞw¼dÐX¶«ÿP>S-AI©O .(¿äžÏùO 1ÁV2þˆ¬µ<t©HÌq]úý†soÞtöÔPýWU—ºðtÝowå»â¡|óF÷,Û¯ØÎ—#ÄÈ;Ý@à´8.¹f_Õ­}­N™¾“yVë,Ž])ã»rKTüJ¡‹Æñ !Óâ¡KyépݶÚÏŒ$‹ÞŒǃŠñÄ-ý Ñ“`Ñ/¹ÁùÕ/i´ö2ßD®ÀH½ÉñÙ”¿Ü½>'ýlË¡æã@ºptòóW¦½#tVÒnîë¹ùwWnè©z=ùãO›0“#Ÿ¼·ÚeBï~+î')-7•‹ô^Èå3óxQ·>s&ásšŽ•Õ`¦w—&´bwh $£Ô̸æéÀ™}?ì\ò'I|M%D®(] í‘dË`ÏwˆgÍŸ-¢I#\„c|ŽDÁ½F4’‰t8ôSé6åmt’à±/·=ÄÁ &ŠòÌÜw"@–.î ˜‚@?Qœ‰WÒHsÉÉÁjàO¢›-xÍpî ,e”©“ÈÊéB{<˜QE{ûé i˜gd[»^\ W‰'™¹øQÐþ_˜ÉÅ,€Ó³(>;{ºøN|þÊt·w.ןtÅ%!ŠF_Ÿ˜×âë¿¿&ÖKá/©:-¿D)Òòc̆+l¾þÞT… ÈÊ|Ÿ’‚­³05’Ò·¬û¢% ‘Þ+Ô̙ĕ$M‚¹X‚ˆ•µVݱVB†túnßX[Â9®™k@–Vvos´í=½ÝÓ~ólW€b•ÍzœSǘÔ%L×q:e1)p{ÄeÑ„䜲 x B”ÒȵFØ×HGÍÓ¯0Ô<•æ“"ÀÏÿº†M ÇDúÉŒp•”I|·õÔ3ï$“Vf½eê°Ñ;¾7—èµèÐÀWƒî$ÃzËU»îXc)h7KÁhŒÚ Ò¿©àêr#&lHÑ,®+Î×è’ñœ ÌüñƒÎ¼hWóúNO*KCW‚s °ô@R}F‹jg½ùçš3X†ïhΔéáiΚ3UÍ™ñˆ{½© .úÀudõfH½öz3\¨‘^oFÔ›þXm¦Ú ©6ÃNm¦€&"¬Ýæ‚î¾W j·¸¤=pPð¢fš¥3ª#Ö”pd‡“NÅG(P›Kƒõ²èX€*' W±¸³âÝÊéc8"ÌrFðDiO¤±ÛÅûÑ^b-Ž—lŸaÅ@˜ƒPág=9 º¬“§ÙòüÇ/Ï:ûúÁi¡zj^¸ò¼: <‘"‰£NýT¹ÚÃE­©…®š1‘‘=ËãE¬+©˜†õ)­úY æ‹­þ+í²§qIÅ#•÷ªæe™¿(z!N½‘*c¹K2Añ08cYŒI·& -òòÄqm@¹>U7¨7)Œ·ÚÏlÕ¤‹Ë}W*€™ÿQÚþe빕ÖóI¿ƒѵå=©ðSE›ý_(ÚÕHÍ>ÌçÒºŽëàÄüÉ:ðs E¦u°8ÿyŒuvª*ON tò4ÌüòlOn*y! 'æ% n÷×d–rùüÕ‰D?Íd¨!ˆ×Ê)¿7µh‹^€z¡j|^+"¥0µ+k$ìVˆ™3'ÝG´®±Â÷@e[nÔéHÅrktúnßX[Ek®™k@–Vvos´í=½ÝÓ~ólWÜ¢¨šõ8wó¤J” ¼¼ r§4.‹†*$ÊvVbÊïV¹>~ * ñçyv˜úq õ"-ó6}pv0fŽ1[;”oÒ1æÜæBÙm½ô¨%ñ|zÇ÷æoùxC„è{Áa½åª]w¬©àÆc¹x$€¤K],®Av¡6bú€ƒL:âõZ_¼7Ýo¿+ÅŸåý¦ÝKþÛ‰ßvŸ‘ߪI;¿ß6TŒú,TJKÛ–O×s v¾U¼œ“³$뤇hZÅ;‡ñVª&n©b}ê×Z¡iŠgØN„´î–‘Í%O¶¼·â Ú6¦´ƒ@ÀUf }'^ò'îtR¸Xt¡kÜ.ùÁ î¾S[|Uª_ëIí Ggc˜P:¥–×J¹—¢ÿlè0žQ€Q¦NèÒ!t©º–bòY/àP")He Î’ò,™ž%áY„S˜¥Ä¬”)%[ ^Âà¥dŸœ,ÍW•Vo—¡ê Ÿ0X|[‚K"QŒOüª{2Qž&Á²grRNiÄQ­(d¼C~!ú«®áF=')70)°Üsxt4 ·8»}ÔÌaœòî_¹„ËEµN#®9¼É)o#V,g'QŸéÐèÊï6Ͷè>"=U\Žs%r!Ÿ¬î’÷{µ’«™T~æœ\9éQ¦<r*¹±Ÿ%£€4ñDŒ°ïG”kóATØW[goY ÿ^’Ï^YòóíR‹ãü†Ÿt¯Ïå¿ ÿ@Iú·gÚÒŽ}Ø5?5·šŽ˜Òg×+íK³‚£>SäV¥nÛrÕ­Xl*¹Ú«ìgvI­‡Úí i¨Rt¨iÄ“·åv¢n%½¼Pkd¿ÓeŽŽû\¶M-ýLéÒ Tò endstream endobj 258 0 obj << /Type /Page /Parent 343 0 R /Resources 259 0 R /Contents 260 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 259 0 obj << /ProcSet [ /PDF /Text ] /Font << /F4 294 0 R /TT4 421 0 R /TT16 298 0 R /TT18 299 0 R /TT20 300 0 R /TT22 301 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 260 0 obj << /Length 1414 /Filter /FlateDecode >> stream H‰ìW_oÛ6×§¸§bE$%ŠÌ[Ûe Ö´ j–ƒk«±VGLIöö÷°»#e;‰t/{Ù@"uxw¼ûýœ—£ìp4*AÁèk¦4ø‡¯Ò¹¼p……ÚÛ\»ÂÀè2;|Lë&]vøz¨à"dE^¤3Éýò&;gc90y).zkVËÏ£Ÿ3Ï<ÔEî-b\2ºŒöº&W´²ÑÑŸ ‹¢„½<|¹ƒá]·’Uç^ÌšÐâÒäµðâõüú—ØÜˆe;™Àð¦]ýÑ,Q£Bå¹ÄJ1î¦ràq.9"N›SÒ*W¥­q?ú1F£G#¹¹¹É¥É­è‘\ÝI…Ïn5Õ¡íQm2cÿÇ£LA ™¶ Ë©ÀÔøÜ ‘ƒe“}Í^òm(¯Ãcub¥h¡ «U[MwÃåÚ\EZn®@¥+8•JceÞËË+ñJ:ŒéXøéÃÞüöþ ,:‰!á:.&“&IÕ=ÀôP0”ƒ*w˜¬Ö”íä-'©{÷°XÂó'ÝÞÞ¦sšå-&‹i#UI×°Žà+zcI§´óͲáRe\¬ÌOR…쪺òtSÜvn“~Óaœ%¦1”U®è®JÌâ˜úà Œ!I—¨ åGmÔoX»›õnŽÙMwÑv V[ÅŠÅôzÞ¼‡æèèÕ|š7ÜMï‚_/¤.±XÝôÝÇÓSø$ÆWWÉá;Ä84žÔv«f lÿô)ë"¦lª¼2…ÚêKŽu_Žß4|%57¤'Kfr¥‹*šd(>I9ú=;ü) ?΢ñ.)Ж¬uÞvsL÷3éb×%öž‚šÂÁæ¤ÎÝêßg¥•]K˪¢Ø’WÚç®ÜkþŒ¸?[¹uÿ\Ê‘Eé‘í6F¼U•¢—RÛ?Nk‡ø>$(•#2Zñ a:bBã™ ”û_oFAÇá€1|£¡UÔ®9µíáºë9€ódä"ÌÆÑÂ'kΛüaŸÝ­>>[›Ü¹mˆ÷[Í{6&|¦¶EÂPâ’ÀÆPPJ Ê#Tò ­ÇB§‚`Ú5b(¡viûÞ­¸wi*¤Ç‘hîNd‰ïóVZšßC~-®WÒˆ}^窌L¡ëz3 ª§£TJ,$ÐÃr%Þ~ÃGŒë詎4Êøž¡`KNŠS2ÁÊÁ/˜¢Ü¾°“t)¡YÁjA_àÝG.‹§§’ÙŠ?óaÍ->[yƒERŸD²Kç^R®?:…Çg$„ûÑÚô®Ê  3Ø× »p€ð] Ò 1?Îáã!*×ymJÏ—a]½†år}ÕâC³º^vx„<[m½óÿ“tFìÛNmòwÛ|f™Ïø·Ñó™]ó™M|†bußëm˜Ì2“•ÛLf1YÆsšÞQÀE‹É 4È´VÝ£µ3Öïãh%5/³ÚB«· sTiÌŸQᆱœxy-•ΡcKòóÃU±y1܆µ,^©×ûðy¿”¸!I÷sÃógÄ[g—eþz§õ.9±COà÷‘·öy+¿R܆ž¤õÊÕù^fÝ+¤òDáþêì6~ZÚŸëcf}îÆ>0Þ#ÿ>æ¬j>½ÅœîÑЭ™ÓGæ4Äœ>j"¤5NFâÊH AæsFž«Yü@4ÚÅå”džœ'—Ve±¾ÑK­J\:l³i|•â@v'<ñçqÛź;Õ)o6„ZúM‘}âÔ ד †VñÙ¢{ü‘ÝÅ Á,ÕµÒ'ä"E¿DX¬añeÅ›q´Mz$šöÄw#þ[›œGíYôï%epwM7ä¼8ª{Ey·ƒ­¶×°²ö |’xþ¨ÃªÂ endstream endobj 261 0 obj << /Type /Page /Parent 343 0 R /Resources 263 0 R /Contents 264 0 R /Annots [ 262 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 262 0 obj << /Dest [ 131 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 227 694 252 708 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 263 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 417 0 R /TT4 421 0 R /TT6 289 0 R /TT8 290 0 R /TT10 293 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 264 0 obj << /Length 2786 /Filter /FlateDecode >> stream H‰ŒWÙŽÛÈ}ﯸ˜—!›ûbÀñ#Ëăie¦‘t`°©’Ä1E*\ZVþ(ÿ˜‡œ{«HJ²Úq°Èb-w9÷ÜSo–7wËeH-×7žO.þá'LSÇMݘ’,vüÔ h¹»¹{Û¥Tt2Ç¥®¨oî>Ü{´én\ÇuyNq³7ÿ°~ÎíEà„ÖFñ¯oQØÿ\þé&“ 2J\'‹qHšE;½ÞOx+~ŠõFÿ!ßuCZðOFOGº?Ö½½ð'³¶ª+ñ8‰ÕÑ>ÜÒßÿk/b'°Ú²ØÞÒý¡ìÿ­Z̈0¹²q@håõÊ^dxÀ–b‘¸-.ùžã…q‚÷å;m—Š5Ú’ÃáàØ[vä­Ž¶‡ÿë~ =ßêÊñƒžVleÿ÷ËJºñcáô(HðCx |b‹RjÕÍúædÃ7Ùø,–ÉÓ­‹ÓP‡kN…ËFZ™ØËßy“ØlâÄñèEæ›9ÀuüzêqG”ÅÝ{Õ÷e½éè³:vÔ ÆnííE’ âø '²“ŒVœ÷­^­¨¬9MÅO¡·U©êžÞ×›²Vk˜›üó<Æžö­ '`ñ#›µ´cdz¶}b)êä ñ÷ñ£í•1Z?!áôœWƒß‹Âf{Í"=ªÿ/mÎÞS¥¨oísša³%ä—>îUýgu|x°3¸øðpKTÿ«"¼õ<Œ¨Ùž¥¿" ·jX˜á®"às¼§Ð³gêááôr€Ç¡§ª)>S³&¶%Fœy¿>“ÈI-z´ôƒR9¾<Ú´Ëd{®õœëEGvX_©½íñz¥êBEM-Î=+=YïVb”cÖ÷ŠOçhÅ–¤ñÄ‘`tÄqÅL}jóöèÐ{w=öÊÛæ#ð´ß7m߉릪š[ÔnNÝ«søŽõÆirQ$qc¦"ë—ëÃñÌ6ž{½Î<7uB÷bËÚ¹z¸Ö<]ùBe}¨š§¼2¾"º©µanJAbŸÇ*CžRÐ/'0Èø>„Ì£Çç›`Yu nè5IÒÅqÊI ]/™ ÜŸ#aÀüæøsÞo­GÛø—¾T–‘n ×|Á{§¤ÂËz >ˆà+Êi£jÕÂQ¤ü©‚ð¬@F±’^AâÉ£Õª|žeðÚÔÕ–3ÆEi§ã#ÛAŒæNŠ@F7Hü $Å{&H‰i‰ÖCUÍ#ýÔ «´c(O®Ï§L†ãiû*ï×M»ÃI^ÊmeAu¾“ÂadOŸ¯PÀUëy16Œ´±ó½¸ñqÇëFn5Ü·Íj(¾*N½q4™GìòzXçE?´Üà NpP«ð^wÓ!ÈŠ‡¸q[ýNú"*šÝŽYb¥q¡6hèËN‘×ZØÌ™@@?ïe\%ps¶°R¹a;!8sé±ÞfÎÔó™Ä=«ÞÜÒa @»r³íÁU©™,çýb´)úêDñ£ Žû:SOCY­:ÐÙgEê˾dЀew =ÛÒ[8mluàôÂѵ9ï=£àkí çm™×}ѬWSÌ Š!ŒX‰2SÀ«yוë²È{2/£ññŠ\XôZ˰¡þ\7‡úöEOÓÙšT[ã½¾_"P‘õî–ü×?ÿòñ–‚׈d`C'8úÕìF›nÁ£¯ß½ÿéãX½†XF÷}Çf„f—ôxW4õºÜ`3^ÄtZ…nÖòahóž™"”TãàZŒ¾<‘u`&¹EÔJ­Y~@¥!«[znP—%úüa«j:´%KÂBÕßâœÅ †óªË\Woè¦,IÏ«·Ú–{…NÊ5žöŽ/÷¾Z„±Ëbv!ô%ÌճힰÖwœ5ãn–V3›mЙŠõæÓg…aÆ,d³ž‘oܵŽ]¯v‹C œéDÏf12 ÚòŽÞ¾z|´EÿÆé,Ô^sè¨ié¥`|!#® P±‰dÖdR–êö'̂ﰈ­I'¦Hek{4Ũ/h “U©YÖèßÁ°Š~ýÑL§ûmæÆš¡íLÝ“¶ƒOùPõÚº¾aÀõ W>F}=dF|ÚháÓ “-aËýÐãÞóRÅzs_7Çp7¿Æ4ÞÌ4ÞÄ4ÈåÞØajX[Q&݃áÝœëEÆØZ^Nk¼z¦+Î| IW¢ËTó‘ê‹ÉBbMYMR‰—Í¥q’DHžŽ£A,ý±Í÷¡†ÂX"j¾ê1Nf&†¡êU÷Ýì#>‰n1ÇÉ G‹¹ö®ãiÛìÔªÑ!ÈsÒÈÕÚþ‘z÷gÖ†¯Q盦¸û™Í-¦*õUÈŵ°ÞØ|¿_å}>æÀÏ®ä`ò(³LàÔoP:ÒHþøIÕ…ºš5žÃ.F–Á¶¥ÙFT¦w}•ž ÙBƒ­ZwR³Lö*¦Ž Šrè;FëÉîz´ÏŽ™ëѪ›ž~ºú V/pÒµ‚Y©ç²PŸS0& Å]6ûåp,¿èªê5ÂK¸Ç C]þkP¤§¾“öyËqŽ­¦ë+\NÛ\²’.v0o¦´ˆg›çÑ®<b=ìžø¶sbÎiãe ³@ϵêMûö¶å3nšë¥éKÂâšdHæ’‹(Aåy,¸Kúb䲄YÐ_Oú¢‰ÍvœÉ­l_ÕIGÉiYÇN&íÔn>CÌЩö“îÈQ=­é8²®µeÄÄ»Q«EYËBbøû¶é^îÙ/öQnIªmGvËNÚ(ãNË‘X}l ·Täv Õô¤øfȨÎiÍE@ÎˆÐØ~€ò×÷ÅÜÆ³IFFìYLEÒ‹7ËìnŽ2”o”~ C‰ºÁù܉ …`ƒCo¥Ns-µu2Y ‡+úìÑ£M¥~ÀÈuqLâÆT“in³GÄvN&²†K-¾šAÒ2$‘NÖï( ß:»~…}ÆÎ_®ÍmB s mÇtyu…ñ…ÒÑNÊ®ïÆ´ÿì£9ÈÓÕê þp{K|(Þô™ÇÇ|Ï2•?ÀZî¦y¥_”oj‘YÄ5#±m ôZ¦¬QD<çÕÀM“ÄMÍ?/AÁ›‹Ó“â´Ø»ü »j×þŸ:O¦X™Ú¾¡ªZ„¶/”á®…”Äi†Ó\Á£Ð¾…RøÒßÉíd§µù ÁÌålÂyA—^Œ, ¼ü‡<*Q²`s*Çt¶2—ûj&DØÔêÿmf7¶O¬Ê3½»‰Ü¾„Þ/çˆ[W%b6Ã#»8!  ïvžÏ—ÑýÆâ¯©«ã+žaƒ®:NÕV}µÓÚƒ}ÏuRöºh[%K ‡ G !&²!ïµnãŽÈ©_7UÕ°ôE=9îÃá¯\€rý3è1F4ÌÑ71°„`;žuó¥ ]̘œ!É‘i9ˆç†y&³îÙeÜÇrÅÇ-b7à.+Eò CHd/’Y!Úä‚!ÀAÔ㯸ˆhy|¯·Úë¦M9@><¡BOÿßòAúÆ@Me.¨L)Ð9@ÝP PmUR *Gš.4ç‚A *ÀVgX ‡"Òý½þ²0¶„¶Ã€ŽJML¤ P$ ·’¢R`f‚'$SHê6©2!\…ül¬ÉÑÌ50D4©òSJ“KœÁ)ØÙ3·þÁi-”¹,ÁÅ(Ò¡n€j€t@©1­(?êˆG]C¸(ÚÔ® endstream endobj 265 0 obj << /Type /Page /Parent 343 0 R /Resources 266 0 R /Contents 267 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 266 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT4 421 0 R /TT8 290 0 R /TT12 295 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 267 0 obj << /Length 3063 /Filter /FlateDecode >> stream H‰”WÛnãÈ}÷WÔc0iÞI-âsÙÙÍ\Œ±d4Ù’˜¡H…¤l+”ÌCNU“¢,Ë“ XÝÍîêêªS§ª^ÏÏ.æó<š/Î<Ÿ\üá'LSÇMݘ’Yìø©Ð|}vñ¦K)ïdK]^Ÿ]üríѲ;s×å=ù™=Î~WW™eN¨–š}Eqhý}þÛÙLÌ(qYŒK‚t8´6çý„Eñ(6‚þM¾ë†dóÏŒîvt½«{Ëög¦Vº+1 œDuôê—súÛ,;vÕ–ùꜮÊþ_ºÅŽ›+ „*« Ëža‘¢‘<[žä{ŽÆ æó·F/mŒ&Ž8±ê ‘Eí,ÿë~…7z¾êÊñƒÙ–¯DþÏó3J:ócæô(HðC˜>±F)µúlqöz~àƒÑ:Iì:éà‚ÉôödóC“mÚ¦Øæý»*[B•0œEPæ/–Á(â‰TeESW»ŸÆÍ´¨2‹í³´l߉`ÈEÛ¬©*s]wz° Ël¹/ž¼Wÿs›Õ}Ùï`ÿ0ð!Ά <Åw‡°ˆfá³ýÝ–çªá†G1…~ƒ€éF¼Ñ ÷7òÐÜhÎ[1néžšËdg&,F®ÇCVeUôóëS¿ÛXž0~¶?=Û•(²]WéÇnŠGØ×ÔÛõ?-Rº¥f!›‰wóD?nʶ¬—£¥©i©Ðë†ÖM¡éFÙž(ãqôÔn2)’°"ê’ê¦ßK¼±¬ù?8´SÚö ÃwühB¶?ÂÇs@,ÊJ9q„0ÛªÔuO %1 $„ªïqŰÄZ š”9&K7°|;LJËUðG¬‚uíø]ó˜Ù0À^3oæŽÉRúÒÐI½4¸êºDC<Î&j+°˜Ü¦ùµÙ»3g柙j[ÛxÏp*3_ö2Ø=Ô|Œ8¦ÕË 8†çèãW$j¸tnq0™Ã¯‡«é ³ÓL½ÂT}ø0¬¾%™ÆUYÛËúÃHøüéÍÏt§M @mtÍë¶wßõ®cPØ“ ×ÏÉ›¨¹×íC[öüìtÆJØÐ/e÷Þ7UÖÃá7Ý5M¥³š)di¥!‡Þ×”gÝÁåÚ†šmUPŽ€K•䆖ր|eÍFròï}ñµÑ¤hd-ë¼Yo Î]¥áÔXÐRžŸ¯Â¡¥Y ñQ =©T.¦ï?Š£¾!ÏÅž™ð Cß—]ÙðÛ»ž£Q…>¾±|C ¯ªªyè(o5 ƒ¤òzB‚b(»'öÛv2mì<«*]ŒAó˜ü}Â^³É^3£ Ô³B ëÿcÅŠÊ”µµ¼4è,õ(NQ ©QXc‚ž—á1‡je‰ÙÀ¤©êdESÖk’Yè-v¶YIà6v¡‡r70Tư9–>ã –ZÀ²›MÒl[ãQð)´§¼áycÑjM†ØÞ4õ¢\nÛ¬#ô€2{y“åßH_eK=¿¬)#Õ0ÊúA»ãLõ;ôdÐx Ã»¼‡$¤—Iî³¶l¶f‡3C‡ røÌhâY b#’ßhë¾9•˜¼`A…4°ÿNxè7Þk€ ƒh|f0ðÔû ¿à@Ê-O ¥ðºj«C2‰“cñTͯtþý]Ó¾ƒ·-G8ŸK‡)Rú¶Òµ$l¶E1Šº{C[ L$')79“­*ÑôêêêöÝ\f_na»#V ~P[èzYÖú¶Ð ØÇW¦HpV7Ö9;N‘ a®Ë™I6$GD¾(«¡äð‰Ìy9øŸçZfú^š ø%3y‰@´Üge•Ù§J!ã@{ÂòwBÅ€p«!¡îP(‡ôöõí§ï9ƒóMÆÆR(ñrΡO H^;ÕT팂¾øL¢Á‹"Õ †ÌŠÞ0 ÁÀµ°AV™9c4àÒÈ7–‹ø#ýŠ+0L`R„ú"äò‚cSî&^8¼Z†ûžÛ j?UiTˆOÉÉ\"Lò@FæëFÄë¼”Ë-V3¦óts¨qŸ™ |}Jï^ `î­~¬x¿µOÆösšmǼ4ñëÀª&^QwZÍÙnÙð}dÚÊèÊb–L>P¾wÆxÿQÑh2ÊaB!ºø“)„†êñ=ÏPÔüÑœ$üáÊ| ñ‹Å ™uæ ƒá‡µ Ô²i¢Û3±ˆ¬ =¦–Br¨sÙ“b@öMÞ õŒ’õmVw›¦íiÃ]hor%dvýDî%*šj[˜„ñ5U¤¸{SïÏÉ»\õýæœ|ùíÎ)¸|è6ç/UKÓ ‡†—Í~¼-Û";§™)U—&ödý®?§[ÍàÐÇÛ>ßœ.xN—büÜN·(£¾~yÏ­WqnÁW×»:ÿø®å+ñçS=ÞÂ.áÝœ 9$C„É ¢ã0å¾–‹]ɰÚ€éJ¯™ó² *P6$àš©fè Ce¤üù`ÚÂkáéÉÐv%[Ël1ª¥{ao)Õ-ÖÓ±‚“fØþ… ¸™Ž”ÝKÙÆTì&W¯²¶àÄU˜†Í>åÄt2Jz`g)…áƒÚ›>S&_‡ -PYhaÔ U;žçÒ šÇ‰9ÿ ‰ªkòïݯM×säz©qgêëÏoþrÍ<öˆôX­îºÿrΈgÆ'lGP·zQª?IõöR½#©_ÅÓÊIá‰Åco÷#W?îN+ïÅÇGâ€ìȱ¸föÜ5\cÞñc'Œ›Oùâ儤ÑßÒDF‘d?{Œ¥ñ .ô.-¶Á7Ff¬^ÿõãNø!›Ë=mz.üº,—æçA½àÈ»mY©ºíF²×7¾Æ²`vxÐ)ú:Yõ™2]ؽg¾®À œÀ“X¨j|¢¬òN.ªÁâÛ¡¼çq‡¦i#¨›6ß(÷2ÛöÍ:ëËœ3§ç¸çR—ûzÇ9ó¨Ú2ì`§š™÷ e¾ï2ǧW7vX ½Ìû÷‘¬´ÇýC $xRí#—uQæ#-éŽ}Å9ŠSI>4©‘™áYÀ E·j¶U1¶¢ÿ#Ý@µâ¥<ãNýÜTÙ‘±x¬4úˆšë䦿lJýjjY_ñ[g±?$d!êOîh8;$æÿ6^>­ A¿÷S,^š‚Š¦iiz 6J!XQiÁKYÝEù#1Rûí;of«¥šÚK !»;»;óæ÷Žû—ïnã´eyå}™É†ºù ™ˆðÏ´q.7ñ†WgÜ忤{;L§àö©mîÂ'&êp’ªé˜þУ:Í­á¤-—€ÂŽï‡€’Žïò%IAcž;Ü/”èU©œ–Á Ùº¥8u‹²°§}…W=º²ž&€A¥ØªL”Eo C¬Ø gm2ÐÒ?¹TßFk[ 3½FU¾È-Òyjµ<Ü*ºE#vèѸŠ»Þm¿Q»°{ªt ¦­Ò®írâ0sQöP:4ÖrpD'W d" eSš9ŠmêKŠö=ùr‚ýž¢ñ(žÁL¾»oôþÚ ÜWy. £ ÿ?‹§ì»^eD|¹dR¼'ÕT¥[ä‡ _>ßCDI„’dMÉs<ž³úADqÿTI–n£Öê#Í2d÷ŠbèKr÷Ô$+g]çoï°*óMfkK*ª £*v™Vù#ÌL" ÇÅ•î ïD P£= èZ^PÑ5@º×ñIwN'÷ÀpÆÅó«/4`¾ endstream endobj 268 0 obj << /Type /Page /Parent 343 0 R /Resources 269 0 R /Contents 270 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 269 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT4 421 0 R /TT8 290 0 R /TT12 295 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 270 0 obj << /Length 3076 /Filter /FlateDecode >> stream H‰´WínÛÈýï§ìŸ&Ã!EŠêÉz½p‘&A¬tÑÆE@S#‰5MªäÈŽú }‡¾côÜ;C‘’ì4EÛÍÂâÇpæ~œsî½oæg¯æó‰Pb¾l*o†ÔèÜæ¦lêNtëf[-\\|Ä#¦Xp(&ûóè’Î+Öº¸p¿óÒ@I-îôÒ›`Ç™Ê×3‰ØDx)ìãEx–ÛW¦¬W"wovv]]O…”%ñä–Õ¼›ØºSìC{#òÍÆÞ7î·Ì®vx×=r#"7>K³ÎÐy±Æm¾²!0b÷[VöÂ:ûx0…òÂT  ŠF<ad‘c¿©¬WØÛò­— Wü¤‚ÿ‘ÌWýžŽ}€ËtØQ tRŽNâi H‹"¯Å§ö㸂WÝrD2Yz!L›F¬à…‘\壈$ÀÞ>£–kiϵ(Ý›þL¤É-Mt©äžŸàM'–1:•néÊóét@Ç-ܸoÛ~/÷Ü}¶³w3+ ÒdÈ£9€8ïñƒíªi¯tn¶dT”„±ôůmitSSÎ]ëšÝ~Â3ƒkð.µ7•ü•(š…·@OBéÑâõ‡_®æ|÷ñËׯ_EY³aƒ]ß"€®We­¿,ì-n‚õ­wN¬O’F‹fãp›SÚ°Íf&ºWŽ[àNÉ¢Ðzáy+/ìðƒ¶€'–Z"ÌË*÷αSC™+!·ž€ ´;€ìQ8y%.ß|y×üÔÔ†4N²ñucÜöücÔü/c]°»ÏFøÁ)ˆŽÊSîÓd¤¯!«½<Î-N¸‘I<âÆ€Õ££$AO8üQÏ_+B™|@j÷œÆS±ÍEDü$‡à-hö9^&ïE=vÑ*÷€Àg³Hh™Eý0§E±Ûè¢\–ÒÔšDˆ˜Jb8d6m³,+pd$ ˆÒÕÐVTúQW,嫪¹Ë+ÿY¥>•÷ /ÂóýÆLC ËØõTZ}ùHFLƒYãÅ{êkLôù0ÒêÑ3´t/Fܴܦ ú€ƒLrAr–¯Ä#×{^µµìM‰»ôüãåûwþKŒ ³!™ ÄÛ?:– æ.I©²R:•Äc†ä€Â={¹@ KWa—mab¦Âx€‚èú=<ü,Á2RíZÝiCU°/¼¨ â!‡DµÚ£$\xÜUhñéú€ÀÇÉ—ÏúGéEizjP³g÷`}:XïjaÕ@p9Í ³Í«¹ f‡ëeIyU}çµ ¨Å¤n@ɲªÈ£‹u]¢|¢sÊ«Š/vÇ.~fmg›·´ÇDRq£ÍrÞ5y±Üê[‰Pýý¹ÚFƒšXކ£v*ô‘Œ€®“ ñÃrò6«Ø¤¢‘\hüo«0y3‘šƒk 7 BuâS”~ºfVp‹6tg È8#8dTéËzÉfÃ%£eqz°fÛû^;¸ÚUZØJ jJµ°¯Iñ¿SNö¸±T«‰p»&]kœäad³ÿa¸‡Ù›íÓLLûŠ0…á*ˆ/Oª‚KQz"åjà°r¶ýcJ…ƒ%d_8î9¼3ÊDÚEÂþh+b{™£eÔµ)Ö¿”%OYšPá2ËÓƒ æÀUÖoWhù €§3 <‰ …óªÊWYâÉ$ÁξG"(æhç‘XzeÛMMÊ!Ùv 9ìÆ®?–òãµ?ŒuÇŠü-14-¾ødíÁZè–*Ÿ¨bšN4Kšz륆üðm¹Ñú9ìÚþbßjÐyT1\@µbòÚØ«}eÐ}5À4·Ë; Ë1éDóÇÓ@SÿØ $zߘ˜Öå]i¸¼€Á÷½wPMPò\ÜmÍHªŠ?ëäq£!‘¢O×¶×ÅÎÛŽŽpMUO@4’}WõßÑî¹v%˜Èï*J#ŒÞ çR­}[ˆVtˆ’hp(rŠó¨[Ë K±c9“ÒQr€\‰\[RÉþƒW¨ƒA #þ‘— 4x9¼œ¹ä–-°‰Ý¦Ò¥ ¾âN%[´Xè ”‚ïÄ›…†Ñe}Ÿav”ËÓ®}["\]ó0j \(0ÈÖ‰‡rµÆHûµì ·TÍÖÊFÑ´èô6Mí_Ug3 ÐØkS¹2L®ÐüRõ[Û'†UóDÒ“,Ôô0 ]8ú4l!úÈ ÇŸ;÷ÃØ£fL÷àÄ|øu<ÂÚâ9®$p¦å)$‘5Õ8ì¿ÔÙ'QŒµ¸Nã”EOQî@¢ãᪧ¦] ænQk©é>Ý·i=Ÿº?ƒ…ýÇfÜl-Ç[âÀ.ø–`ñNÝœ8O&3 <‰s2¶sujÝJ×hS«‘ôµCVÂ>ü*ßš¦ÛÕwÝ@óø 1uì˜ žâÓß”‹ßâÔlB-Èk¨’n77c^_ž‹0"ü½X–-ÔeÓ– ÊÕî\D•Î÷O<ÈX$Íq•ø÷cµåEÁóÁÆâé‹×½ôÜ’n¶Úu+ËëÎ…º0åƒ^)Íry.â ÎCûÒ$8.yŵ<õ¨kê«Pn½ã6j`gok‡fÌ\æ»9:£„6ð¡Áõ–¦Ä%+ïãͼ4‘Dy"q^ñ·z·ž%äd×AêPP’0fz|À”§TÕŸÏ_>}èw‡ÓÕÁéOZßcüP}‹åî÷Pð5äôF©ŒšSŸ»[ûà©ÜÙ%dZËß C dóÓí¦$,,Ý2]çwtÒTV<é°ÉöU†7| ]/n¶õ9—Wua jXØë—¡†ÆPqc(ƒ@¤7¹áRó\ëzÚؘkšvßÂ&®ÿ˜@ãYrm!H 0½ nÅ ºËÑíŽmµ_¢âµ›uMnG’§¡iÜÙþ Pž§°X…áù‹½¿r½?–_P ^{üWßÕ²Ô ï~Ç=˜˜ð {VVyäH‹* ”n ù{{–DÔ>f§éé™~Öi”î·Lkú½žfŒ¿Êá¾ÒR®>ßù·3¯ÐºÀË0¤ û˜+Âêde?£ÆH-““®à‰}x²é°À³e´ƒ‹¬5™yLfyL–yÈ\¿IYÂLú!Oîë‹CmŸ ó †ìj%Ú»«^ÿ#ÆOŽ8ਤ¬Æ¹|#­èX|£÷c·J¹§î1€P•sËñò ¯‘íÙúm€”Ÿì…|£k^ÀƒØ ;D»˜sb à¦-·‡J•ϳêè]åÑ}Åí…—Šiìæ^®dBÍ,Ï V#ƒlu¯ë¾ªéü‰&Ø;úe³®›ºùP‹ûMÓ+â[?8É*Á $‰åy+u‚¦ÔìÉTïˆûGÑ"ö‹%?›M$F´º³î†Ð·¡i[2o šôYîÈX1çêÇéÕ£\}>­9:Ó±ƒ€ÈüÝvp9ØPëj??q1›Ëç‘D°TÓƒ ]i©DbÓ ëü–×üáuXá§ endstream endobj 271 0 obj << /Type /Page /Parent 343 0 R /Resources 272 0 R /Contents 273 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 272 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT4 421 0 R /TT12 295 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 273 0 obj << /Length 3154 /Filter /FlateDecode >> stream H‰¬WÛŽÛF}Ÿ¯hä%$0¢Å‹(*ˆ Œ¯ðb21ÆJœµga´Ä–Ä EjÉÖÈʇì?ì?îÞª"EJ£ñz/60¤š}©Ë©S§ŸO/žL§‘òÕtqájˆÿxDIâ “a¬Æ“Ø ’a¨¦ë‹'/êDÍkž3Tõ¼¸xò潯–õÅÐiÎübоî.>9ï´;½ÈYzŽŠc÷/Ó?]Lxƒ‰½IŒC¤Y´–õÁ˜¶¢·X6ú‡ †ÃH è1Q³½z¿/¬;ðÇÞÄY™:ÃkèZ]½¹Tÿéb/tªl¾ºTïw™ýÃT˜1ÂäÜÅ‘£‹ÔLð‚-Ù"v›] |Ïâ1~O_Š5~ÂÖˆ%»ÝÎsC/vjìH[í] »‚~àÔYûA¦ÍW¼ÿ«é…¯2uÄ>Âé«pŒ‡Â0PdQ¢*s±¸x>íå Î8zI“‚.ô„\ñ¿z_Ì×e “¢xD‘ð¢±Ôð©Ý•;7öGï/•ÿtQ•kU›êÞTª,rŒ26Ï3SXs'ˆè¾‰Õ1 )>|²ßá÷ȳuf}ä"Œ|2Á ±£ÒÅÒÈuçÔÛùJéZÛõŒ,X¨Tïk• QU]ÛK•š)Ò¦àã€í@”ãÛr5ìçÊ~‘7rj[VæÎåEƒnÕ7züÏ,¶v[™¾çìïÊæ;©¶ºµ|ú׆:Ën¾ØJˆqŒÅZäzY«EYZ_“ùGÁíNí’Ýw¡ŠBUÎu¾ÑvåFÃpâùˆVˆ¿ò·¹paâ0'ø¨Ÿ„S´†d ¥‹ý{©l©Òl±0ð—ikÔz›Ûl“…]œ¬åñQÍs#¿)òT‰ÇáíâåÇm¼üÆúæÐʵ¡'ìM›ÛÏŒ:£¾‡éŒ¬C‚¢ˆü¨[ TìN‰Þ~PìÒX H¹opƒ$äÚº¾/îÒŠTýxpâ!TJú·Ÿ®):‹lùH§fÁd"ìä­X9Ž;á Ø§ÊMÃPZ‡ª†M}Èn[—z:Ieö>•àmOxQú^g¹|Ó…À™å†IìÀäÁ0z¢^>ÿ|S¾*à“$¾ª(m³=¯“R#ôžð‚ßñ‚ßð×£äË¥ a FL×cGFLãÃX¸.£” ([~‘5buš@"7"/DÑS§9Tô¼Q‰9Tüè‹BC4Ð?ššó‰ÙCú¦X4ªVCÏ…ÊÀÍ µ¥±í'ZYô9¨ù›{“³â_æåLçƒÜ0¡cô”dùØ èÕá‚Å.%5‰%†> Ö.EÃ{ô:åwÔé‡ iH8:1G'‘67fˆ%-JÓŸQW “aðŋ֠àxþ¹ªk>ôJO†šMYHP˜Â†”†¥ºç–%çå[)ΘJ“Æo_þ|sV©>B3×nŠXqid\ϨL…†úÚ'÷±Fk(™¶…‰#"ŒµR5~K™QÇú·­©24ÞÚXÌ¡?¢¡¯uJ¢­ Fƒdnîê—·Gõy çl½~å(“fVê¥W¼_<Ñï«zn·¸„´­•.ÐW‹ÌôÅIÚ@~­÷ª/l„Œ5óUÑêÀ<ç—ý©‹Ÿ˜ºÙæmÍbÊí½±¿jPáDŽ ­¹#áô÷MÍç†2<–M5µ „ï"tŸ1É?îf±ö5Âán“Õ¤eq«B¸Á2Kò&B).»È  à8ÄQúË[®ŠÞmŒÁ'Ú^$$Û²bá’ô,¹#P)á–$fË‚ÁþÝ4p•Y¸EÉ"Ö“hyÚô^ú9]w†'¸‘Rí³‰PzbQ݉ã=ÈÃÄK&ÿÇ4°qãÎÎñ!!,×¹iÐKéÒ2äbÉ­K$±ELðM+Lã¾Am¿4©ƒ¼Iþ …:\Ìé ¹s¬t*Y[ÞÍê«¶Âõ0 ™R ê!jY~üEÚvQƒ?LUªLî[t_¨-im´mÙ€&H‹;ÏÌPAc§^½:?[ »'ÔŒÑ_¸à”U‹W“^ªÙ=ž›¸ôבðìrSgyI¼9r~§¹Æƒ9‰³ô`‹ ká䭜¤šwÙE¶¼o@\=@nQtQiijÖ,õv³)+«¨m9´­ÝoX¿LWݧE×°å}v^P`+U ÈjÉáAkšn¹ÊF*(SÝ>fžÉKæÅs’àgû·ŸXë]CêÑ—EáRÔÈi#270 –¹>9hžyê-3Í=™$³Qžkóì SiüÚJ{yбGÚÞ\3êó. N ²bÜ![R@ƪöÌ#ÁÜêç‚îáFuîÞÒƒ”ßÏy®iã„‹õ]» AôÞ¯àÖmRR‰HjoM[—^ꀮé&ˆ„]ŒôëûffATðb—éðfæ½7?M±!"µe!Á„Rÿ†1&+WBš²Àt=ñvÑ §+‰Ío‰î‚Q#„¨åjš5}@$Qý ò¾á1RtfåÁZ“a~SbTdPæ5Œ"ÌÄÔç)™8ÕJrÒ¢à€hç°'s7Ä_é=ÜÔ§±å7bÅŠ¦+š½Ò\…Dýd•˜àÙwÃH çö ½8#"à§­Ìùš4 M)ˠͥ­hÊèS8Š.¿’Ô‚•ÿ^> endobj 275 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 417 0 R /TT4 421 0 R /TT10 293 0 R /TT14 297 0 R /TT16 298 0 R /TT22 301 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 276 0 obj << /Length 2597 /Filter /FlateDecode >> stream H‰”WmoÛFþ®_±è—.ÍwR‡ @jmÚ&6l8\}8PeñL‘*_¬¨ÿèþã}¸gf–”,×9\D$wvvæ™™gfHgi(W¥ë™ë)ñ$‰í$N¤âEd{‰ã«t;»¸ì•w,ã¨.¯g?޹ꡛ9¶ãL>›ûÙoú&³æ¾臂~=­¢ØúGúólÁ *vìE„CüÄlÚÊ~/&Uô‰¢+Ïq5§Ÿ…ZÔݡÛ ½)º¾ëN½ÿñúû¬ydûº-óÍu·/û?Š!„+ :«WÖ|¨d‹ØmvÉsm7ˆb¼§Wb›°5bÉ~¿·-ߎt¤ê`¹ø¿î7ðÑõtWŽ "–oXÿ‡tæªRͼÈœ®òcü(¼øž"‹Õ³õì‡ô$#:q䨉 ÁzÆ9:BnRüg]V}Ñ^f»«¢³B`‘#žë9Ìrµº-²USW[Y®£o| ™ö©X©uÓªõÐm¡³ªîõ¾¬*•7uŸ•5oÍÔêxo.w}ÙÔªY3@…jp}–MöŽÖ{b}ží²eY•}i-/œ6>  —e%of –¶liÞY_ÖêËGU•…Ú5»a§¶E=˜íìÏÑ ‡ñFc\ÿ$Èy‹-‰&M}oÙ¼eâ™2 l$££Û÷“XÉë­(YØI0F :õÂFî[é¿Hƒë³3áò›7z-Ø9’jÏu~§²Ž½Iÿb<'Bñ€¬0}3œÀôLÓg0ý̘ÁÔ^HàµdHhä~GQõ¨ÈzUÖìV¨Emá÷Á|HGÍê¦L°„pÁ”‡–ê‘·fdŒçžXkå|&Žãœv›ÿi“s ™ró§¦#ºcä¤J)1ðÚ`}¢+˜š1ÄzµjqQEx\}YÛ ¥³U`ÛQ5y¥s‰ÄÇC7“ÐxÔë‰7ôÄ›R›ê¦ÝfUE]agH‡!æ0¸CÙ‚Ó€1ç(z Eo U”AfÄPb .‹B ´£ž~ß´cP˜ŠÃ“î‚L¥vù$?Õ·ð‘ƒþWÍLpCB96—; ƪɇ-ÕÜíâÄÉMÐÄI*¹¤ä ¡ ]û f¨gàyD ‡ÿ£î)GTwŒ6jæ˜'@úSšÞ¨›ë»ô˜ì JöoMÇD'Àôpµç'à@ïX_DóB`–M& ~F\½*Ïk×·¦"#®È`¢Z'LîBZœ ¶‰ô%&‘ýóô`ÙA˜ÿUDÕ¤ [O­ýœ‡‚ÉÕ`t•¸i©fÚäÀEú g‡˜%¯-Š\O-?2‰$Ôÿð ÐãîCr˜Ò7—Ÿ®þy‰Ñ£´'éÕŸÓ»ôýmŠÑé™ÿîT†®)CN2_C‘<\RÞ„úÕŽ¯¡ZÞå‘ '¸xù`:Ùçôý—Ô<_ŠÞßÊŽ”ú’e“u@©­ \zhG¹´z:`mÑ—¡">Œ_ œ. 'I¡¨æ'÷²`º—¹'°ÑUn5]ÈÆÄØ$pªwl/òA© “OYÛÑøâPÂÝ‘Ôr8;¸1|æt“EN´e¶¬ŠE½–ìó³ñ7£sËèµ*ê\:µ—ÖV ÊýÆhïIgôs6 mT‡ã )zî6ù“îDZc*üy ƒéþC`ƒÑ-ê ïèb·ˆ©+0ÐõÍ0~G~µB>hB.Wâó2h‡Nž#= ]"C.XŒuO ™ +µ*ÖÌ+.ßÁˆ¨WÄ*cØ–MW»wHý`2­è,s–ÝÜœD®U<í!@¼Îå£,:û¼h’_œQÇË‹ÝYvÓtk2;ÑÙvWÉÀKy»¿Z>ª”RÌ|  Áã\CŒ·ÙcÁsrcV׿Ú×6†çG«Ž,«¹»Q·ŒuÉ7&´ y­är’=PÊ Z%0DŽÆ $Í4"bÍ«œW›Úh5¦‘ZÙ¼²èÍÕðKËϦQûÚ#Ú‘Y©ùS?Zs20HgÿŸù×ç endstream endobj 277 0 obj << /Type /Page /Parent 343 0 R /Resources 280 0 R /Contents 281 0 R /Annots [ 278 0 R 279 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 278 0 obj << /A << /URI (http://www.openmobilealliance.org/release_program/ds_v12.html) /S /URI >> /Type /Annot /Subtype /Link /Rect [ 378 640 758 654 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 279 0 obj << /A << /URI (http://www.openmobilealliance.org/release_program/ds_v12.html) /S /URI >> /Type /Annot /Subtype /Link /Rect [ 71 626 388 640 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 280 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 417 0 R /TT4 421 0 R /TT6 289 0 R /TT8 290 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 281 0 obj << /Length 1995 /Filter /FlateDecode >> stream H‰¬WÛnã8}÷Wð‘bE÷˼M§{{›^ Þ—í d™Ž5+K‰v&óGûû°§X”ewl'6LJ¢TŪsN?,f÷‹E$|±XÏü@xøÇe™ëe^"ÒLŸg_å? gº‘|R4R$™óóâ/³Ü| ©çæ Œ„™}iËï)}Šf è?"ð¼HÌiÈÅòE<¾4Ú™û©›Ëê+LC7•½øñóø×y↲«ÊÍx|®ôªÃŠ‹k"Y4+gžc‚O̶͖ßõ£$Åõâ#{ãgÆöäùùÙuB7‘=¾HŸzq|ü6zƒ=úì«á/+7æûŸ3_Tb$>Âé‹0Å p‚<ÊD§fëÙ“Àf#ãldÇ8¥!|¶“0£/aÙYüJIìGÜ$vã™%Â.°V<7ÄßÉv½€wú 1‹7“;€@¶ŽGQe»R½ÙÕ%ä} °­ÈúJQôð )YX81>¿1DØèBð J]µ¨í]m"È©ŒWþmÍ»<·~Ù……eш¶,÷öñ7Ù´<Ýuý"öã¶åËe­DÕ uûd?c׋–”mÃÚZ}sÜ!Cº"5Q0³! &Ñ)º=ÿˆ'Ê—ž°à$ïK˜lñ-ïÀŽòïºÐû^<öc¤®uæi†½ûQ2b3Ü;™ ֧ɘLÂHy—x¨8¢è”X©uÕ¨‘•b÷èä€Ð é@(w½ ‹nåŠ?µ–뢪û;Ñ+õ#=1'C2˜ŸÐq£õî‡û{be»SͶ]V5,™½H2]™ë¢)•kò 9ºçÑ®92œHõˎ״O<ô8—Ûû/øåàîFo룳LÆL9%S2äf2WüÔjEE øå„ت'¼k±iõ cL.|‘d$B€ #ÉQ:.ä Ä=æíè£q'3±ge»ÝÕJ«;±Ük`q|·¤¦é-(¿†^”äj»k;äQ‹5rhòÌÐSͲ¤Hf¡+Ä0>B›9àY|[ô%n| îènëæO­Pº\vznaNo.A>À%HNÙæ_±5æj~š¬GÕT'ŒR„qáÉ ƒ’Âתç±âêb”k[i$¦(7jõÍyÓK?½D»‘‘î1{ùå¯wä©ç¾tæ±4?Š~ú~½¯éa Û™[€ƒ‹ºâûmsÅ»ð²s7C!4ÎÉ?kµÅj¥Vöµw† bå«|h›u]•rJ«LÖ(€ØªîIMLCöÿóa.ʺRàÉ3˜4Ñü–ÙèFvÑØIŸÝ€¯ö;®×ÔŸ ÷¾I*k† ‚í’š¾7<£ŽYòܼÉõß$ HY3G3QÔbWÐ]mkîy[ðZ½Ûµ(ĪÐûmªÖ¦´\©Fð|gJp]éak,ï]Ëí Û}­+È¡ÄmÕécsÒñqÒáË«’QT£ÛŠ„ƒâ¶Áûs Ü‘¢ÃãßövÒëiv¯ˆ+míþÙ@³ižRYý¡(±Ëb%J¾"ù>¥°-jÚ~}ÿ–ÉÖüU’_%Ãe…ÚÑÀ rŸ\£°¨‘κÏ]EÍTËOPQryÍÊñäÜ41+êb†7í¸,zõî² G£[|yÝ YþŠ#ŒÑðÛ‚Xîq蜢ü‘OëVÚí–hHfÑø¶ÏFt£yªíäVjä—ɹV 3:A²ÙïwÔ¾·ÔÃÈÍ*ÿ¦¨žiäoûsÍ\™c44¥bº]u_7›Íp†ÁAÅpaÚÎoòí{–C€G1XU…Ð/;%pBñÚzší[ͦ?îôØós”‹ºs¸1…‘áqV¿£°&Tm¯µš{œÈ¿‰·|Ü>vš©)·› ZÄìKLQdj'M8ßµKxýLНLµž&TÁ-¸ú£Ó~>4£‡ªTà>•®=Ld]O2_­ÖWúßW)’åÙrršÉI׳JP#¶¾iG°øzq¦•ã.}»ËGÕ™Èî›â@Œ%öY,kš§ïèìÏ_£â|Äâ)?.>ŠƒêzÒ<Ú4w”Çz4A×ã7t=LÓÌì› í<‚Æ‹þ…'MioPF*Nv:5ñ79ùZÇI$ÀJexÛô©ÄW ÁI;cVA%.1=K3â¼bKŸ°cס•œæÉÍ6õ5M¬aé0LR1\ |ZÌþ7Š›ý| endstream endobj 282 0 obj << /Type /Page /Parent 343 0 R /Resources 284 0 R /Contents 285 0 R /Annots [ 283 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 283 0 obj << /Dest [ 277 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 447 630 469 644 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 284 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 417 0 R /TT4 421 0 R /TT6 289 0 R /TT8 290 0 R /TT18 299 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 285 0 obj << /Length 2195 /Filter /FlateDecode >> stream H‰œWÛrÛº}×Wàœ±h‚¤(ò±IÜÓ´É9™ZÓžiÜš‚$6¨òbEý£þcº6’’mÒQ’‹$.{a_Ö^x·šÝ®V!lµ™ ŸyøŸ0Ž]/ö"¶L"×½€­ö³Û÷u̲ZÏñX©Ùí/÷‚më™çzÍÉfóîñ8ûÊ¿¤Î€}|„v/Ù^¦*WŽ Ù[–ša=S磂<>9 ƒû&mZ;üÞ‰àÝR›X[ì[c’¸xpnØcÛÐVΛœ,›àä„ôÃlpÝüÜwiå„r¹ÁƒÏÍß— 1œökJ¶O¿I–Ž&iÂ`ª­žøQvûmI:9†@!Ÿµ•bHQ»!×ee‡ =U6Íõ bŸõäúTæùŽ6JøÜÑÑs|’(ùà¼ÍÏÏܺ;¬éœÔˆ*¤w™ÉºÎÕ¤‚ü¡Ûâq¾:ÝÒI7˜(¿§ûC!1ë ½,6éó"_³ß1Ùö3Â1Ñ}Ó±öwg¾ÀºwZ\ÑJl¾O© żi`~ô¤£OE5¢]dRV”µJf ‚IÊý©’I&)¯wCÇ3+Ëq¤t#Þ°"=ÉŠ¥m³+«NÌ=pén]ö§Õê‹yp:}÷8ÿ›˜Ö½ÂV° ÜdGª)=È5 Î~7¿Ÿê ŸXfWªMÞÍØáµ'ûÅ˺3V5ÄJK]ô Z È-à€„Ñ€0˜DŒí!¦– ¤2m¡­¬/[!:|Z7ÔÛ(ã¤*Û펨ÿÝÊšZ9ˆ»êÂMĽ@IdÆëýÒ‡ÝdËxIשöP·…– ìQÐojøKÇLvŠx0›È}ÒeŸÓ%Îç™TÄ Ó7—h¤ß9±gÐ}Y™‚˜©’ù‹½)<Á û•i7Ýx¢>í¢AÈ{A(* à*ŒBE]š÷¦ûκ™Êz Öd—zq$ñ´ƒèCN_ºÑþðì#̽º²4}ÔW=R¸m uóªÍ±2šdê—ý÷£zJ©Áô‘'{¥3ÇxÙVî§|ŸÓqš*‡Ø{­Vß%~¼Œ`õa–ù–]*™éšoò½,ÛæJÅäñå«ö¾ž¼¿'Ò^vW h“oò,m¤©¾h.ÏÁLé럙‘:K’WãcѪÎM +j(X—miÞ x̨­æ®þY}2*ë>؉Y¡ ½.÷ÝŠõC„¼nʪ[£o7–CÂÐ¥åõñ;Ûòǰ®¯Tþ4/öÔókqùØ@,îËêtmO2ÝËîq–:ùþPÂ׸•u2 BÉÆ>|q4ý¡¬¾±ô ’ÉIŒb%a%?Ð\Ÿ#$ËÅ€taJݤE^ïHOg샶îqÓE&¦¨!9ŽZ©¯?T¬(·¹^a·ÕÏ Ÿâ]1”¨°%*q×¥‹N^C„"¦ùê*äHºì½'T©™Ñ8¤›¡u,}¼¸õ`.37¸å£h€÷iCºL¹»ÙåµFÈÛ‚¦{kJJŠ£–\˜øáÞ³§Õw«ÙÿçxpÌ endstream endobj 286 0 obj << /Type /Page /Parent 343 0 R /Resources 287 0 R /Contents 288 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 287 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT4 421 0 R /TT8 290 0 R >> /ExtGState << /GS1 426 0 R >> /ColorSpace << /Cs8 416 0 R >> >> endobj 288 0 obj << /Length 953 /Filter /FlateDecode >> stream H‰”VMÛ6½ëWÌ‘Dc®¨o“¦X´è¡À*—nŠ@–([L©$µööõ?öÐ!EÅ›fmÄ0 ’âhæñÍ›¡ßUÁ]U%À¡êAˆ?’¢`af—‹Š0†êÜý¨ h´³ A72¸»à°ÓAÈÂÐÚ4ÁfƒGò[M71KÈNØ1"‡ôê— tJ\²2à qá?:,ßG¹uegÙâèˆÂ0JØ>Ãó4tÃsV’½Ð=Nc– oïßÀïÿÒMÆb¢úfÿ޽ù[(´HÑx  !µlé¦Ä ºtˆÜ±Ý‘"Îx’帮Þ/hxáÐ,HŽÇ#£1ˈFÖÕ3åø”fgäÑýº±˜5{çÿ§*àÐCeéäç8.â,¢”ºàËFñÿl¬<åYȲd!꜇ёOž8£ÕŸ/rš±t9‹KLvΑ£– cSÐÖ¦ÖfTähJÝ>{/ËÆºÙ öruµDt¬¸°ù…°›sÜsØG¢…Öý(Á’Eô~œ‡¶CkS+#ZèÔxð»ªçñDÅ5"’3É‚¨—F(‰dLý$ ‡Yö ÍP5^ÆÆžÔ¸Äáf4å5~0Çž;³h¶sס¢Tµ3Ž ˆ"%Ãݨb”7økömüÕÍm½=Õv²G‹'á5ú¾­õ'O†£fÙ¬¤a.Í]o¶1´7ƒáWÀð/X¸³ßÖ-LµªúºŒãKq¢«*N¾¨Øi†Œ³±UKìp·ÕK_£7:Óëô@ÄÉ‹Ó`0=Ê@W÷ÃŒû‘ÈZap©á³‰!w½é­°’kDg¦‹%ëÍPk,‘”,Ï¥}л¯m‡¨Ä]¿ìì†øÒï½.€ˆ¥ùWI]a¥aÈå¥"zµ·=’ÊEÛSlŸDè%4¶˜I­ iàágš`Ÿ¾ÿt:°ê[¿e9üµ—ó ž„Z^aõû½Ñ^œtÔ °õƒ^Ïa(…Ÿ0­ <¾ ÔGòAŠÓ$[# ±¤ɱÇJßÑ‚‹×”HmP8»„RØ,\+À(¤%"M?X 9éiHv(—O”sÒ,ߣ-»Dû9”åµúÍi,z‰×aLlá%l]¡lgùÙ Sœ1Ù6zc(¯gþŒÄ·€r)GÓk%ðÕ™Ó÷{ÄC+6ñ™ÆŠ‘=ÖïªÔGòïÒm­LÃŒ5pÛy@‰L+!·é°¥Ðw}ó"zý›ðŸ—šN½ endstream endobj 289 0 obj << /Type /Font /Subtype /TrueType /FirstChar 32 /LastChar 148 /Widths [ 278 0 0 556 0 0 0 0 333 333 0 584 278 333 278 278 556 556 556 556 556 556 556 556 556 556 278 0 0 0 0 556 0 667 667 722 722 667 611 778 722 278 500 667 556 833 0 778 667 0 722 667 611 722 667 944 667 0 0 0 0 0 0 556 0 556 556 500 556 556 278 556 556 222 222 500 222 833 556 556 556 556 333 500 278 556 500 722 500 500 500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 333 333 ] /Encoding /WinAnsiEncoding /BaseFont /BAAOGA+ArialMT /FontDescriptor 311 0 R >> endobj 290 0 obj << /Type /Font /Subtype /TrueType /FirstChar 32 /LastChar 145 /Widths [ 250 0 0 667 0 0 0 0 354 354 0 667 260 333 260 552 469 396 469 469 469 469 469 469 469 469 260 0 667 667 667 0 0 656 677 677 781 708 615 729 865 396 375 677 635 917 844 792 615 0 698 510 688 760 667 896 688 0 0 0 0 0 0 500 0 479 552 469 552 469 302 542 552 281 260 531 260 844 552 521 552 552 344 417 313 552 458 708 500 469 469 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 250 ] /Encoding /WinAnsiEncoding /BaseFont /BAAOGC+Garamond-Bold /FontDescriptor 313 0 R >> endobj 291 0 obj << /Type /Font /Subtype /Type1 /FirstChar 1 /LastChar 1 /Widths [ 460 ] /Encoding 331 0 R /BaseFont /BAAPEO+Symbol /FontDescriptor 305 0 R /ToUnicode 332 0 R >> endobj 292 0 obj << /Type /Font /Subtype /Type1 /FirstChar 32 /LastChar 181 /Widths [ 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 0 0 0 0 0 0 600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 600 0 600 600 0 0 0 0 0 600 0 0 0 600 0 0 0 600 0 0 0 600 ] /Encoding /WinAnsiEncoding /BaseFont /BABAEM+Courier /FontDescriptor 303 0 R >> endobj 293 0 obj << /Type /Font /Subtype /TrueType /FirstChar 32 /LastChar 32 /Widths [ 278 ] /Encoding /WinAnsiEncoding /BaseFont /BABACL+Arial-ItalicMT /FontDescriptor 315 0 R >> endobj 294 0 obj << /Type /Font /Subtype /Type1 /FirstChar 32 /LastChar 181 /Widths [ 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 ] /Encoding /WinAnsiEncoding /BaseFont /BABAPM+Courier-Bold /FontDescriptor 307 0 R >> endobj 295 0 obj << /Type /Font /Subtype /TrueType /FirstChar 32 /LastChar 121 /Widths [ 250 0 0 0 0 0 0 0 0 0 0 0 0 0 219 0 0 469 469 0 0 0 469 0 0 0 0 0 0 0 0 0 0 0 563 625 729 688 573 708 0 0 0 0 0 0 0 677 0 0 625 500 0 719 0 0 0 0 0 0 0 0 0 500 0 406 0 271 406 292 0 323 417 229 0 521 219 0 427 354 406 0 302 292 250 427 344 0 500 333 ] /Encoding /WinAnsiEncoding /BaseFont /BABALL+Garamond-Italic /FontDescriptor 317 0 R >> endobj 296 0 obj << /Type /Font /Subtype /Type1 /FirstChar 1 /LastChar 1 /Widths [ 460 ] /Encoding 333 0 R /BaseFont /BABBOI+TT1D2o00 /FontDescriptor 309 0 R >> endobj 297 0 obj << /Type /Font /Subtype /TrueType /FirstChar 32 /LastChar 126 /Widths [ 250 0 0 0 0 0 0 278 333 333 0 0 0 333 250 278 0 0 500 500 0 0 0 0 0 0 0 0 570 0 570 0 0 722 667 722 722 667 611 778 0 389 0 778 667 944 722 778 611 0 722 556 667 722 722 1000 722 0 0 0 0 0 0 500 0 500 556 444 556 444 333 500 556 278 333 556 278 833 556 500 556 0 444 389 333 556 500 722 500 500 444 0 0 0 520 ] /Encoding /WinAnsiEncoding /BaseFont /BABDEC+TimesNewRomanPS-BoldMT /FontDescriptor 319 0 R >> endobj 298 0 obj << /Type /Font /Subtype /TrueType /FirstChar 32 /LastChar 124 /Widths [ 250 333 408 0 0 0 778 180 333 333 500 564 250 333 250 278 500 500 500 500 500 500 500 0 500 0 278 278 564 564 564 0 0 722 667 667 722 611 556 722 722 333 389 722 611 889 722 722 556 0 667 556 611 722 722 944 722 722 0 333 0 333 0 500 0 444 500 444 500 444 333 500 500 278 278 500 278 778 500 500 500 500 333 389 278 500 500 722 500 500 444 0 200 ] /Encoding /WinAnsiEncoding /BaseFont /BABDGD+TimesNewRomanPSMT /FontDescriptor 321 0 R >> endobj 299 0 obj << /Type /Font /Subtype /TrueType /FirstChar 32 /LastChar 122 /Widths [ 278 0 0 0 0 0 722 0 333 333 389 0 278 0 0 0 0 556 556 556 0 0 556 0 0 0 333 0 0 584 0 0 0 722 722 722 722 667 611 778 0 278 0 722 611 833 722 778 667 0 722 667 611 722 667 944 667 667 0 0 0 0 0 556 0 556 611 556 611 556 333 611 611 278 278 556 278 889 611 611 611 0 389 556 333 611 556 778 556 556 500 ] /Encoding /WinAnsiEncoding /BaseFont /BABDND+Arial-BoldMT /FontDescriptor 323 0 R >> endobj 300 0 obj << /Type /Font /Subtype /TrueType /FirstChar 45 /LastChar 122 /Widths [ 333 0 0 0 556 556 0 0 0 0 0 0 0 0 0 0 0 0 0 0 722 722 722 722 667 611 0 722 278 0 722 611 833 722 0 667 0 722 667 611 722 667 0 667 0 0 0 0 0 0 0 0 556 611 556 611 556 333 611 611 278 0 556 278 889 611 611 611 0 389 556 333 611 556 778 556 556 500 ] /Encoding /WinAnsiEncoding /BaseFont /BABDOE+Arial-BoldItalicMT /FontDescriptor 325 0 R >> endobj 301 0 obj << /Type /Font /Subtype /TrueType /FirstChar 32 /LastChar 122 /Widths [ 250 0 0 0 0 0 0 214 333 333 0 0 250 333 250 278 0 500 500 0 0 0 0 0 500 0 0 0 675 0 675 0 0 611 611 667 722 611 611 722 722 333 0 667 556 833 667 722 611 0 611 500 556 722 611 833 611 0 0 389 0 389 0 0 0 500 500 444 500 444 278 500 500 278 278 444 278 722 500 500 500 500 389 389 278 500 444 667 444 444 389 ] /Encoding /WinAnsiEncoding /BaseFont /BABDPG+TimesNewRomanPS-ItalicMT /FontDescriptor 327 0 R >> endobj 302 0 obj << /Type /Font /Subtype /TrueType /FirstChar 40 /LastChar 121 /Widths [ 333 333 0 0 0 333 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 667 0 0 0 0 0 0 0 0 667 0 889 0 722 611 0 0 556 0 0 0 0 0 0 0 0 0 0 0 0 0 500 0 0 500 444 0 500 556 278 0 0 0 0 556 500 500 0 389 0 278 0 0 0 0 444 ] /Encoding /WinAnsiEncoding /BaseFont /BABGLH+TimesNewRomanPS-BoldItalicMT /FontDescriptor 329 0 R >> endobj 303 0 obj << /Type /FontDescriptor /Ascent 629 /CapHeight 562 /Descent -157 /Flags 35 /FontBBox [ -28 -250 628 805 ] /FontName /BABAEM+Courier /ItalicAngle 0 /StemV 51 /XHeight 426 /CharSet (/quotesingle/I/H/N/x/v/underscore/four/E/dollar/J/F/w/five/L/ellipsis/y/\ six/d/M/b/ampersand/seven/z/O/c/braceleft/eight/e/bar/parenleft/R/f/nine\ /colon/braceright/h/S/parenright/semicolon/i/U/asterisk/V/less/j/g/k/equ\ al/W/comma/K/m/X/greater/l/hyphen/o/n/Y/period/Z/p/slash/P/bracketleft/q\ /B/T/zero/r/backslash/C/A/one/s/exclam/bracketright/D/two/t/a/quotedbl/G\ /three/u) /FontFile3 304 0 R >> endobj 304 0 obj << /Filter /FlateDecode /Length 5964 /Subtype /Type1C >> stream H‰lU{TçŸÙef–×;è®Î®âÁâR`A[©‚€¬€,*Êòvy òŠQA¨4ˆèŠÈCt‘ððÅ ¢T‘µm’ªi8UcÕx‡ó‘¶9ý«=g¾ß9ßýîïžû»wî÷ᘕ ÃqÜa¹ïrßsüÒ²LÆxÓ˜ÉGTcâd\œ"§ÈE«r;eÚɯÛY‰SìœÓÐÅHÁ™ñ—•ýŠvd8ÀQ'a²jž“ã¸"»@§[à¡ÓéüÒÒsMÆ­ ™Ú™±³´ž‹½»K¸X7Žžãø›qœ?Ž‹ÆÑk½µ¾qi›ãµks32ãS2´©±i¦ô4SLf|œ‡V뛜¬ ‹œ¡ ψ7eKÖÿªÀpL†c†Qf-Ãì•Ø4l¾-¶ ÖOÆ0,ÃÂec^Ø"lNáGð>|Dæ) EËòeGdÿ’O“gʇ­TVÉVˆIDI‘>d2YFž%ïP“¨v¡Ø 8¥ø«õ"ëmÖÖmfÙ¬±9lsÇÖÅÖdûÀ.ÕÎl÷Ö~ž}¾ý·´–¦“éÝt-ÝîàåpÔá™ãÇŽUŽÏœÖ:}î4¨tS(«'&–iœà0!sÏ®d÷±ß8OtÞì|ÃÅÆÅÛå„KÛÄIçM̧‹ÀNŒËQÂN˜2³Ÿ¹¯Ä{ìR²fTMt̳.4‘=g¬OŠIMIIiJ±´544s44Cg™ÄYµÌ&1@bÌ%s-ê$®È:Ù9䨿*IWÀ|äÎÃ+˜У|ÇG÷.¼â{˜(ŒYW,î…%lrûŒ3œÛ"ô˜¡îºJxÐÐÇIÇ]ÝùY “„x˜­§˜p,šJ®NªJ8¨x6ZµoV¼«j•UòCǬ/¾mú²ôO©Š†BóöxÕRϼ€õë+Ïnå˜j¬Wæó”òÕšs¡è‹½ 4GwJJ¬ŽÜºû•Š.6 °‡$^9$ ì™<ñ޳€)Ó…ú Ç;´OzÊ#{2&]zÇd£i°(ý,é’EUߨrÃr1/«‰;ÙMÔÇEŸˆP/ŽŒ¯1Ö&hÊ*Š–pL·6¤dQ²*䂪íÇäµDL÷ªa6+#55LÕ2x¯»õâq ={¤‹ 7Lfõä „‡#w7šq¹õyr=¤áo~ÀÁtÐm?÷¼æ~%T r¸öM8¸¯œÓ“ áDÏ̶©ˆV¡é~ˆ3xIÔ¾ïoƒÌPÑðÇlx‘ƒCõ]¹¸Cteóî£éá‡Àƒð#!äv}‡?Lݲ9öŸ€Í#dÓ~!84bá°ToÁžu'}Ñb€¤a›€ƒÊŰÐÃ0Júµlq(N.*ºØ³iM±ñIé‰)©íçZNŸçhä:ò ÿQÔÉÅò‘XƒyÿåNw6!5CÌ“‚Y ÐÀËÅ]pí*ý.n€»™°±a¥:'gÏî\·i«®x±¢4yφBÕœ“(–A`$súRv'å–‡¦"›ùéN—pE]»®^UUJuX2ãÌ\}Ä¡ ò ]&ˆg¤œ—j}Pêµx†B;"ˆ0 ü[‰ÑÈ_!ù¤ñø+ê¤dLΠÔû£Z |@Cüü¼ûÊSUã§M…§¹Ÿ† µïêôðH?O >h¼ñøÏQKòK vpE‰ùoËA™Èb°T’¥WŠøí=̘ 웥MÆÃóÆÒ`i|¢jÞYW|’kÏз®T¯ Î4®ÓÔl$>?uëü€ú¹e]Ddl V³'¬šd†÷îjд켜¦ øƒÁ#dMMMW`h- 2úï—œRèB#Éø À­Ë8|'‰Ýî,Ìý0,ÌXB¡ýèb=Ôk‘LÒ-Í,º…ŒãYJƒð[©˜%í{À‡^ù9EŠr·pzú(ËNââíž²cê×üêU~Aú©A5æ0Mq‘Ówû |:A1¨¡ Ø)€¾Wù’‡S_†ö0ïQ,O³7ü©ßí0Fh¼×/@³UHA/8æý»Gùihõ×H¶Ð`ˆOÕ”ÞýÃ× F4[®Uuî/ß»_]f.7sG+ËöUh˜÷¡£rVo\534²ùJ6WRõIÞZŵú›mꎎܭµšÊÜ S¦Š6g‹Uþ†‡ö›r±L¬dûFÝÐþh§PÄhÑOÒ…½Þ [z¥K+N€}üVžy+ƒŽý{PËÖ*ŽyÙRÓÑô­j0v©\?q lˆ¹l☷YE¿‹õT-º·œ8p¸ÿxHüô3»:<ÆÏ8¿òÇ×C‡_6„H®5¨Ž]¼4=Ø0çØ÷¯þq¼ý«Í+8ºðôB¹TwkÎKu?OÙ‡;^„\皣ª£ÔH¾Ìk®®ÏìoÞ©ïiÖ|‚¼–¯Ö™Ÿ¦&–&î*Ù¿K:H^´|vÄ¢›ÆaÀ XµÖÂn)XcðW/0÷WŸX:òusjuty¬‚.[˜>6­Ÿ€F.ÚÁmöxÞ¥u[¤qMjN¿Øz®®•CÕVÿc£aÿéÀiÒÿ#¥ é-𓮈;$}2ê’‹EûXBïaH‹è¥F§!ob)EƒŒÿ§€?}åb%œ`…Qß0JôE:–õÕSRÏp1]¢Ÿ/ö‰D¯±9}f iム¤]BœEY  ñÌKñ'gAO¡8±Š@{ÃÀ•D«F7a èÈ/€$ ý?TWyPWgÄî&®+ÉôΰNkw¡•’."¬â HÚkQ@9DŨ –(j\k#^Á‹  (**"Òc%A¸j\ÍjÌZÁ|í~ª}ƒGíVÍ_Sï}ï{¿÷ýŽf/#ËŒ–Ù"XcÀ],BÑÄØª…×A ÑÃ@gÈÂ÷ªàjè-9$òjNö™£‡óŽœÜw攩p[Á–â­¸ñ{' ¸_îÖ¬2´°|ïõ¿¨¸ åå]\lâÕÏè$mIJ[/&ÅGî´ø{ˆyÄžÛU!Ue•Ä.2ñ½1ϸqåŠtqòe_.Ð ÂÁ…­¬Ê\]"L?œœh¢DRÓ]kêHÇC¹nX]Å,]0#eº€z×§0fÃÐÚÛÍ+-’Ÿñóçp‰Ç™‚%æÃ ôŽ&tÃñÿÄr§ëÔåë6mP­6ÁUà × àpgØ qobÂ_– ˜õîF lEÙžìRéõñîÇb’3 a›ÂR"ÅY±“2ì§Z_²KwF_•Î${™l Fˆ¦ QÀ‹Ü"fÂküÔ Fø\Æ!x¢Àk2H9½ šã5(Ã!>×VË÷4«¿Ì~(¡7êÐä6m°FÕ LK•»4ëDt¢uƽ«3¢¡…>ó%KtÅDåé¶ï!†úÒAÆ —²|³, ÷Là¨-Lûö—7®Ç…WH“ÄË3¹KáÓÿFñåL»ôAç»èѹùßJØ7jf±´)ôZ$@µv\&wc,@ì‚qòÛè¬ùX4¼µÖù´¡ÍÔr|T+øM/ƒ¯fE_›i*j2ÑÕ(¯µWo©9”Ž2˜±‡³ì0[“Åô5ÉÛ“„U(eƒ£ôo×rçÓ™Õõmi­8=¾/~8ÅY¡Nm±WUzÇÅṵ ÕawʹMGDÊ0¦“ Endqf2I[Ž—ïjÖ ô¥ÉðàzzŠ#&Õø”y~_q,éK&5F8 c$–Ðö?!X"¿Ö¬În×Nàºè–‘XTk%Áñþž18J¾¢YÃéuÉÕºŸm SÆÂpu sP³Îë{q[h 5zlàVùWm‡Õí zØ&ƒ¶¸ƒ ÂB©¶•éTsX[lØHt%Du§ûê¡Ôðã"ˆF+NóBOš|{Q Üð~øŠò.òS‘C'4úÓàPÀÜ`Âôÿ³h{àÑÒ #PLë]U ÿ„cDüæJåæhpb[ÚrêJ¥¼¢C—.™dãªm©›×‰ WÎÎ ƒtR“a>M½ç«Ukú8J€>1 z›)ºŒÄ…K ó.­vh9ø¸ >2=´ÜÄ߉Xù? {1ü!ê/9ìT= ØûgÍGB2 c+ªwDçIû7ìý"Í–e£`F+y³)ñ:H’ÕJ<áÏÙñE[Ô\ø“$”[‹AEîA§–KÍ¿bjn¹úD¤K®Õ®;/ñevc˜MC÷»D®p邜…Ÿ5ÚgL÷Šc™v˽8°+l•r6}•–f ž³dø¬c¥f‘O´ë–qáh­R.º©+³R ÇBÿ— |ô^hªL±ýþà«6ªœ"´CAh,B)@g]!èHçj ºØH¬&ÝÝF‘zÑ7 ™òk¼É¡ã¤¿e±û¾I#Îf6(&°}ZàNù–s“ÿØ`W”ÖoR„«M9Å%Ò¥óG¯7› ƒŽhµGô SÔ‡ñ|;`ÏûJÇË?r Åa Ç<%˜"ÇR1Êaî²0—zÈ Ý/lÑAŸKEÙ,üjwßF‹ü3gÕ¼p¼fbXþ2: DªÞÌOÃåJ¶–hf¡Ž7{i¼¨ë+fCCŸ©I5‹e¡|'ße““§Â.†ïOHdš †ÊM,ò8õ0™¹M0ZneÁþá.&X†TâÆÂ(ˆ€Áø| R1˜«ÈeXh¯vô5»Pnçp%ý§°ùŽ Y¾ÁÂ4¼ÂàüXBá§¹á óžö¬u”'Œ(£7ÞàTFe®iî©P#/æ´þZ C]Ú•¼q¤ë›èâM®ô,ýGМù[7‡½y@ó¾;\8È éÞ4G¬SiægÞïÚJ?a*] o2p¦ úßQO%÷Ôèv«/èëãCöb÷ökml ªÓ7ÔQøtµÚHÆÃv®`WazX’¶ø´·0=hÝêyRÎ|æpQGÁ áÜÙëOIù³ãL+¹ì(s6R¾ ¼B%¾:¸~Ú«ïÛËk‰È§ûp_R›ç«ç.žañæD_ºXp$/7GÊ¿ ì©*ʶo+“Þvð„PíÓÿªÀ3§óÕj-$À™»#œÃf§n!‡Ê=Ÿ®åøÊ0”ã«Û¹_—Ã'8=€ “dã¿)Þþî 8ö>lû°×ÜüDjðªN×Aà)…ñT›a-aÖ¦ÌóЃÎIË÷­¯ÍX^.QÉá\QDøÑyá`ö^ vóleãÿ5J-å¹ ª»F2AmÇ0†`×dž~d¾€‚ûH4P$С ©(ßl9ÝPBÁ˜ÈeA*Ã9hòHìúøÑÓöû?ÓÿA8ç$Ùõ' ¯Ó}[¿Ð(}¶Æ°¡–‰ Xo,‘{OÆJËO$*µ¦}êgÔfg€=ŽÃÁÎî(â€v´‡)÷z ηˆÁ`ÀWlã¾Æ6`‹\þ[uùEu]q\Bvß6q ò\H÷É{¦Ö8U¢3´(Ô…‘D#‘ÇO51,  ‹«F†™U!«"l4Q!€È h@$·{!V­Ë ¬ˆ4F†šŠ“ÌÔô¼z˜NÏ[b¦þ{ö{ïÞó=ßû9ÛT«7ƒ@Rņoåcå?úªì¨ƒF!ŸÙZ YŠÊwä’^"/p¿$+> sÀMcæ8¹ ûÏ‚¶•• b¢K5›öó;Ã]Ä„W_R¦ŽãGÞæÚ³V´,%ÈZŠš ù7fCpßÍ:ÇçÎà&›pzLì±#‰bI‚æç7£̸ÕCU£5‚({ ŠúeoÌ›Ñ?2þ÷+`vëÙóvx.Ücð'ɶ†UmZ¹«y7Q÷zlæ;É"ØP’¿ñÈÂÌBá×Ù}ùü5áŽ-E–°(l fÝl|ýÀ6 3þ>ÿÜUõà¾ì™l$†¦ÆT|Ѩ›fU­&¸ÛTÚ_6yÒŸŸÓøûã“ôJ2öÉP=éÇ•o³‹¯æ¯Þ“%|¨Ý°ÎjÍ’J5%_tYBƒ½ªú¤t¹é³/î~*†H7Óþƒ‘°‰xø¯4FréÝiÝÎEõ¿È+°|4¨dyEÿóÿ „Õ\o‡†t.ûΫŽU:yÊžh ƒzRù^"”(RåÂ'kñµ'W°¡Çïk¦RG0›9‹Q&üYب•:?p¤×‰Õv Éé›6n‘ÚŠ³ìÉ»¦-¦-?Ò5[vNúþÈ’é[øŒkú´ÎÞ%ôˆø“„_ýÛ³ÆáÊ3טP]½·ìÔò~yfºÛ=»õX@§¼xP­Þ!ŽïjÛ}ÞT/ÍË©Y+,_aZŸ,ñî«?ŠCSu¤oà w¡£¿õ²ÐÙóÇåTKIJs“)³Tp"¸·~…2!ɳ¿Ã9øË‡ ˆ<‚<„QÞ§Ÿ·4 µ(¬üÇÈýÁQxBìè“ ê˜Ï`LÕñ÷.øŽ‘»a«¾­´­¨YäGF‘íáBÈêë6’<ÿ¦ϤŽÕ©BJ:glfiãøL<.‡öAïűa — <¿v‡&Ä;jß~zƒïÔvÆD= Ul£ ÉÃFb¸SìÙ0!|YF¨Q*Ê)ÍÌ4 0ñð¹Ò_ßÛ-þ¾BƒÙ+*£h­ [ÜÞ_ÙA 0­éBqª°i.?XËèímS®ÁcýžO-ÇJŽêê ·Ê‚VFÊoHüuÐá f¸gÈÊs a=Ç·ý ¦uµ8…ú“eYViêvýî³u.hu娒Tj @?w|y•¸¼jÑžõMº¢Ã%ÇŽ®Ü«éy7c»ÌRœ ‚Œ\Ã; 5ñ4º¼–²Íjþd—ôçµîÊe:~ì¼ÅimÈÐUí®(,3Dâ3¥™+åOÚÖŠ—d g]ÜûÇŽÛ=ÏÞýw=Ç#)Ï¡v?r^_æÒìLúæÁ¼µ²Ö,åÚJ[› PB@‰Õ O@}´<€5áá´ç›M WUÓO½?u¤ áå«FííyBºÐÂ¥“Þ}S0ç~dË“L'v·¶à”ú+VpiGÒΘÅíÍg?<'œu~48$ñù+HË®ì<Å—ùÙ æ@&­9ê±¾LyP]r.Þ¢!ð–æÃ\ù®"&}UJ‰P|éÝ’=©õ°,L©w=©Áò¥.ÁžhЬÓ.Áúp©sÄÙ®…i´ÂUí0Tc%QÎ#ÏJžuÒ0RàEx ß#ï¦2 ù³Ã!Rûa.,и¾%®EoâògÓ|É0EÖÂ<œ¯áÇ0£4‘2¤1¢þY ‚EÍ*Õõ¹žßqˆÇ—Á:1ÄsßzN#÷pø{tR8U†Š—¿ÖÂJüq>†Ñžè%ƒ•-ÖB—bûéœ^jÛÛ©OøÃ> endobj 306 0 obj << /Filter /FlateDecode /Length 251 /Subtype /Type1C >> stream H‰bd`ab`ddäsrt põ×®ÌMÊωXüfø!ÃøC–é‡,óq–²> endobj 308 0 obj << /Filter /FlateDecode /Length 3736 /Subtype /Type1C >> stream H‰dU TçžÙÝ™EfSwuv1 –à°*È#’€’(55€‚òyŠ ÁÀiÁÄà+ŠÔjD†žÚ QA,Õֈ̯§ŠXôŽÞ­é,{zzΜ{æþçÿ¿{ïw¿ûÿ4¥ÓP4M{L Ÿ5íI™yÙɉ٣'f¦%Ø×Ã¥ ¥•aEÔ*ºÎ4æ:k›uŠÙÙ€ V>_ûü8#î ®¨xe9øÂ.º]:ØèN14íµ²¤Êjõ—¬Vë¤Ì¬Âìä¥I¹–Q‹mì«Ú`ë€3`Ç Øñ6pÀYÂ2%Zb srÓs,‘‹3³³2³ãs$‹%<-Í2ÓŽ™c™™˜“˜¯®¾®Ãb¯ãõÿÿ”FÑ”£†rÑPn4õE ¥¨á,åCQ£uÔ8BQ(ê=Š £¨‰ÔTšš¡¡btÔ<š¯ÒEi¨@*“ÚM¡Ú¨^:žK·Ò/5“4MZ6J»EÛ¥›¢KÖUé:Wf.s˜Õ³•ì9nÆ•r»¹fîªÃG }޳8¾”:¨iP·ÓX§(§N=Î8ouñt™ï²Ç¥Kï¯_¡xžNCí#­²<@˜Ûa¼óÍã†ïÅúÓ[vì;ï0– ÷ŒF º£êÐН•<ÒB~( R(JìÙ±WÑ€#Œ™^1böüâü´ÙÝlûÓK`£^™R@Cù¿´J…"ɽ¨ÿdÔ°›ÐˆƒÏ$yGJ¨çíé kGíí?¾×Ï轡–†Ñ°R«(àHÖkаz˜)Óà ×´JÌd¼æÇéWC0 ‹ Z«˜ޤž˜½$>~Yý¬kÍGŸõ«eeªL?’!«G«”C³ð´c$Î[‡%aþ5˜3`öfXÛ.ZË„w‹pèhïÕ0¤S¬ç.}± ¼ûLO«0$Ú¬¯ 4Ô­òµ`¨ò‡5s+¡›Ã%5H `‘׸?þ¤ôðÝüu¥Ly"ðÿ¬Ì_Q™lòµ, ʼàüã¨dŸ,Kêö—ì6õwö<~Ù‡úy«óÌ@íºðp®®.¯6u}ÎHøwaJÜ’Ùññß-‹ëÊv•ít¨8ÐÑÕ¹{zœ¨‡âÿÖ×ÿŸ€µ8æ ƒZV-£•@¡«Ôs.P¤UˆÄp8WÉap½®,Ú L”Å$€mhe`%Û0™ ’ØíP- •½ Ó¬†w`eÈ퉖ù~¥Æ § ÿ°¨^ä•Ô:¦qïWÇN¯,ìÆQ"žnÚ ¡Übù~p½Ò~×Ì+èUÂÔ°’|=` a[w-M7óýpƒ0ý£¢ ƒÀ :ö0P!f{­=t3.Y«\îbZ™¼Ôˆ¸wMh˜ó¤_‹æìÕæ³YMf_Šüâ¹­«æî2áXäp0¾‡ÜŸq:¤—º¶öf*B÷˰GEkï„)ý¾gĺ„O7Åšð ôW›a‚[Y¿j…B³_©0yù¤è%b~râ†8S°b†Ç#íXwö’w5ÝPéàå§ä(á{•ÓH”ÐKÀ÷i$áøŸ!WâøÞHO%ª‹N’l¤N{ ÎN¨©?Ö©Bˆò3ùáoó/• ðo–ÚŠ¥v›!L‚&‚®|žýFæø—ë§z‘xV«.R%¨†‡ä÷c÷áJOQ»r ¦ ÷©±>–M.aÖedlH7Íšó»¦DsJãªóçŒ`ùéGYäû[æ§Ÿ1ûX%-äê’v|`B_tFœŠÑ0Ì |ԶɽM›ëÌàͽæ6?Ð*[Ô™¯r2žØB$¶0Xz³ÁK†un.`§„X îs&Ø"=°|ßìj'ð­Ú EÉQÓý˜C G@#ƒó¥ö3U³$(%¾l-\{ŒL ÛßÖ`#Ùu:‡-R Ìk {2T«@}@5Á‹–*ž N–nØ ïKð{â­,l³ù2w•V[ÅЇîÃCõ~ø4 à9ƨ‰†xãHôà ú‚Ç#¾y¢µJúyô@næ³Þû—@,¼u ¢¿@ŒZ°Y†l5…㊫pzÕÉ´C♸ˆšHþÖ>ª¬NÔ÷# N7ÿöÄìW),ÌÎ^^,¥'U$›&@Ì=¶~_ÙšÝæý+ëR—íÚ0§»ÉjsµJ‡„qÈï‘/™æÚã-W?,û~Î^±.)¶r‘ 륎0H8;Ù»¨ß²sImÒ"Å[˜0¡4Vã`0[¹l¢Y¿J+Ù½]~ŸÀZ9¢‡'ê¥ÕABCÉÞ•»Äoz­ ùÒaYUä¶cÓ©Ó·D¾³±qÍgÌïÈê—ËÕ¤,޼؄o‡{/Ø{4ÍÌw_Œ½¹±}½Ãw¥ûVÄ?IXê3oAm}¼xÃåC\qÝɬv?¹š_&ñ(½ýóR§ñ™¶:Ì àzUKÎüDÐEÕÝT‘e8¡ʰN%ùÁë>ßÇíœîo¤K.Ÿá l_¼‰õܤêÛbÅŒSÇ>?mj:¶u{£ùrÞöV#œâô;ò•B—C9ÐP¡U`UH÷8Š/ÔwïÓI°\jga†-‡!,Dª·ä«ŒÝ¿†I%¬àÛx¢t œ\!çFb¨„2Ív¯ƒåÛÀŠÛU..Ü!øšË>*Šó ãA™ˆu'c•);˜Ó£†1MÔC`ù(ViP# ~€Š(Ÿ ¥°‰Á”ϲ‚)ß  E0²ˆMaiÊA) p €¡–"u^,LúÇžKÏéݘþ;_ïûÞû<ÏÀ ýkeœû¦µQOÛÉo¡·]µ6pe˜ðßTþÿ÷ÒÙRÜ"þ'+à¶Ø†nä´Ú,ÚüRm­¢}q>ÂQ_öƒú5Ó÷©`ù§`ÖúW±ðåm–6s³á»t¶œ–‚ƒ2ÓwÊ-~Üå¿ôÕÜ•®ŒÛ#Ÿá‹’âΗ0ó,zfËBWè=#8wtWÖ\3fËõKU%†Ã¼Ð¯9z')TŠ»ØÜ5VmïµåŸkt„²ƒ*öÓ?TáÌB—Ö 'DpÝÎø‹9Iñx•û¼`^ !ÐçZùt[Ë»#xÍ‚ ð²R(ìÞå{lý§°d´}paáöÖH¸¡Quº«Bi¾mJ<0ÂÅî=(ý;Õûý÷Z[óÌM²ñD¼šÍW$%^Hð×~WN¸ž÷åêô­/åËól— l*Õgf Ô0‘ªŠ"#a_õ~ =7â\NEÀ kÁ³Ç^Ý|‹ªÈŸ“HWÝÐ)79 ôÞää@ß{ojL Ý-9]|ò¤íõ_lš9}Å “DÙÛ/çLomÏ–pYÊ_?ûHÖVê K­7ë<ÀýŨ'(ýÜ\öwtŸ™‡Mí#/ˆ±M×W;pµOê½gÞû©Ã`U«–ÓzˆUÉ›Z‹¶ ,°Œ+:a:o’¢~˜•,M+ˆŒô8ñʦÇh}EÑÖ0<V8¢â‘›|«õòHGgÞ‡íwÜ5÷”Q`ú2}óØ óÚ·ð˜´gä…)=á`E$yùå èŽ+žxÃÚn{åõV9Ž+8Œ|ð¦+eñ†,o.ûÁHëžÀs²0£ôö«È‹á‡·nûýÛÑAûäÔÝCFG$B•:EJvQ!‘ 3íÐåÛ|óÇMï_3Tä›ú_’Þ9r*#J† ô'†(PÀ‚à(ßõMOÉU©§<9YƈÀg„,dwa½”’+~ÐòDX¿×óP¿˜G'ð9|O¡¡´ýž=meŒhºR‚Œ†ß ÇW±—ø˜nãXÌ ø™ºZО2,Q.é^‹ªñ!„(ë;xšBêo¥´'|·&CqÌLZ¢„¬ZN¤ó%é)ðÚbÈO˜£Uý÷”ˆ*uh”â’x¡³)¯ÑÜ`h7ª< í ÿ]zŒ,L4;¼€…tN ó§g –¿Óõey£ôõSœŒ{G=Ãà*sꘃ Z°ÒDàÞW ¢1[0¢7úƒw%ßÀVƒb7øóó"óLüyÜ:ƒöP¯w²I*˜‘é ‰¤úy'2DaŠØæ1´aÿ¾œ”xƒ0ˆJÁÄņ/R<™k{ŽOH°úñ¿A”…©MçDŸðàè_^gZñ¹Ú¶±ÁC› ?š ¼ CÚ Ìˆ‚íR~M~µ¡álªm‡´cOtl¤, c”Bÿ…^Цg ¯ó‚­åz˵Ûõ.eµWÊ.K Ey™çU ì +L?£B–º}V¨Jµ:X-ކwì,6àÊRî¤õ·l·§‹/„ªÛg DBS8MCeL4ªLŒ*‰–6¯‹—ƒWÞp¾,T¶t7帔åŸÏûÀ#iWÎþ7V—d„ƒÃ4>Ua˜ÚÈçܱŸ±KB),í}èH5¨¤vÿŠªßñ'1Wår×E‡JAuÜ‘!˜üƒga‚kv)Á£ç÷§‡Ç'š¯}E‘õÈ訋~á$©B¶6ìÐûœCZÔjŒâMÉ ©{$¿‚/êeh"ÅOâN>¾(ëBŽáÍúñô©»óbƒM²M6Ás*ËÈ%ãÀ‰> endobj 310 0 obj << /Filter /FlateDecode /Length 114 /Subtype /Type1C >> stream H‰bd`ad`ddprtrò÷Ô 1t1Ê70‰iüáëîþÙõk/«Ü¦ÆÿÝÝpû3þ—‚Ýß¹…˜9Š K‹RMà000¶ƒd˜Eºù~9}·ø.úã×g~ýyÆÎ`ÕÍ'\ endstream endobj 311 0 obj << /Type /FontDescriptor /Ascent 905 /CapHeight 0 /Descent -211 /Flags 32 /FontBBox [ -665 -325 2000 1006 ] /FontName /BAAOGA+ArialMT /ItalicAngle 0 /StemV 0 /FontFile2 312 0 R >> endobj 312 0 obj << /Filter /FlateDecode /Length 27443 /Length1 48444 >> stream H‰\T xTÕþçœswC^’lîrI„<‚È+ d$€n(H6’ !ái¢á%Ðå!òa A H‚74`xµ¨héI(Xky©üD¨ß‡´"{;»P ½óÝ{gæÌœ™ùÏœÃ"HŒ3®Wr~…{p¤‘µ£ Ê<ÛËG–O´©`Þ½6þÌ<^û°õžZQ\vª*·°‡²<£xzÕÔ‘ï½$³ýô3%EžÂ– q뀣Š}ž.aEû¾í-XÍr÷’²9•áO¹ÓX~ pô˜^^à{ZJ€-›XN,óTV„ ­ç|Ö³½>ÃSVôC›…]€ÃK9ŸðŠòÙs8o~ú×+fUäøŽ_žàøÁ–vÑü:´ˆVqˆ¬+ü^õÿ}¥ÖUÿºÿ/¾eï¦û/P=TŠ=ø#> ›ìõ.¢'‰ lB5Ö£6Ldͯ‘ä±~=E[è…­œÏV4³ísX€CèDQÖ5,Ä2y–½–1ÒÝ0cQŽÕ4Êš‹I¸ – ?Fa*h‘å¶ÖXë¬í؃ò„u!p €©Ùú^ûÜúIìñ:6â­k³ie[¾‰Y¨““YÅÖOœ/r Yh¦c"w/Š¢j™Î»l³Lë8[uÆd” ‡¨ Nm’•e5£Ǩä]7b05á(¾ Pí¦µÝº‰h$â®§-tLúî.ö aÄ4F©'òJ9þ€?á4ô¾(×Bµd-M{ÉúÐ8Ûìùº-0-”«Lk—×ühã#\"õ¢1ô¬è)ÊÅf9 A±S!Jï ¼ûyJ "T´Êmj·ºc{ÜwÑ ç‰ÃxïSWªÓlz…>¥¯Dº˜"Þ—åzµK±{¸êçQ†ÕØÛÔžP6ýŠJ¨šjè5ÚHÍtš®Š¡b¼xAÜ%r¦<ª†1S³Õm¹¶ÒvÕçö÷ýÅwÛJ¶–#›ûa1gÿ:6seÑŠsLp™4 ¡p&œ4^fZ@«é·TO»¨‘£œ¦Ët~ [tG€É&b„Stc2Ä,ñ¢X/6‰V¦Óâ;ño)»ÉÙO¦È\YÎYÕȵLûå%åP­Êbœ“µZm‹V¯íÖ>ÐnÚBí¯!èÔÏÛîÆß=ïƒo…¯Ö·Ï×h]BG>C£Ð)œ½‡iŸw-wÜ»8K¡Œƒâ)•F12ShͤJFr)ÕÑŽ@î{é£ôÝàœÃDç@ÎOŠ~b˜Ãô¼(3ÅZ±N4ŠOÅOÒ.Cd[ÙQÆËár²,’sd•¬•¦<%ÿ./ËåÏL– V]U7§Ôp5EÍU›ÕuE›¤Ô¾±ÛÊlËmM¶ÚŸ¶§ÚÇÚ³í“í¯ÚØ? Êãîüûñzè¢\,]r?Öˆ¾*Z´ˆîç)(”Y‚;UÔÓ 1ŸEw­Ò6X ¦Ñ¸©âëÅñ£,³h$Ã4ÑçÞn¶êþ¥¨q]áÚZxçJ[(-7l¡ØG9æG²·J'ñ…¼@vµSÁI×ÅN9–»à¨JÕÜpÊMØ+gÒ|ì.žNw‚Vq¦wx.Œ§dú—´ Åhî¢þò+,Á âs\ç{¼¿¡BUŒ5èKÕ¸‚·ùVôÔfØâméÏ¢TyÅcÔ¡vqu©;I­–ÒdYg»!Îa.ZU0ÎËßqö­b¯ÌR7µ*á0Ë1ÓZŒ*Í­ÎP1$=‹Xu‘§[µLVNþ/ä©2‰gھ݇x •Y¬‰âÎÅ}1'DÓžŠ;¨”ïøs<ÅZÐh/šP¬…O@ôå`¢õ66ZŘa­Cσ«šw¬Ç7xõ´Ì÷2*Ð…oÎy¥eŠV-ÓJ^qNŒµž/£KQø–i/ ©ÚaxÕg‡!Ö*ë¯ÜÝ=xÂnD>~‰¯¹Êï9Ây }}£Eƒ•)+¸Þ ȶvZ])%ÖtŒÁì°kðØÒÒ'Œš6$õ)ƒ пßS}“ûôîõdRbB|ÏOÄÅv7º9õ®]ï㈎ŠìÔ±ÃcíÛE´  nd·iJ B¢ËÈÌÓ͸+À¯ ðaÌ;ì »¢J2t“òt—™9¯ÄëÊËàíB‚Óô¢à¤D4‡0œiT4Pd*éÔ ÆI™#ÃeFþ Lëòšc³Ý®Œ§37)Ѥô#ß„1Ìl›0Az ŒiK7í0z©¿¬ÔyW5E ?/!´Ð(ôLr›Ò“ëÑ.ãf˜‘/}õ?‘7oŸî®yx5Fz]Q¥º_ôzktó­l÷ëNÿ77—÷`_›™çÍäЫÄ‘ãtŽ&–åºMZÆ!u%þªîÕWd¸üš¼iºÙÆf”x§åñÑ8¼&rªœûŽ´ƒÖE8\ºw¼ÛpšCbŒ\OFç†ðæTý>:M~t%)±!¢Ý=`ÂÛÞgBÃfЬ¸€¹Ÿ™óYògd<à aê:gâ6¸¦þOÑx °?¹Ä^f!ŸH©Ù&=Ï1ȯ÷û›Zl„¡{o;À¸þÝ£Ï}-6âü¬¿O´¯ÿ—7Ìøx‹ØÓùL9ÇÔ€Ü/)q^“0ŒŠ Æ2¶žÜA½~§ÓÀ+›ÒÏ‚¹(Û}OÖ‘³ÿá¾êƒ¢º®øyïÝ÷v5ZWqm”1BÀ¯(Š2øAnD¡š _ ±?šÚš4호p…N›V‡¨±@Mµ`ÇŘ´Agj:‰ÓL1mc?òÁL:m’1éD"¯¿sß{ëîà 6mÿ)³?~÷œûuî¹çÜ{_`á¼òˆZÉ5½N¿„kBNM´{e "¹“ø)ëxgE|SrvdE”)ŸRý«¾ (¥ °"˜”®´}[P'YõË¢uv)’ÔU»¤&j²A¹)Ú˜…จ˜‰Ÿ!ƒz{—Ç‹¨”%)7â«Ì³þ—MN¾ÁN]æ{ÜKÒµn¶™‘¬yñòâä8óÆ…5Œk° ¸"W‡P³&\g"žŠƒÉIÙ*AfÎįËì]Æ(OŒà²ln€ø³T¶×0Ñ.—ã£3m~.ºp87%)7\ÞÒe†¶¦$ùRÂÝê9õ\xWN¥8]fÏÄHnC9|µCÉBR¨´º#E©/ì(õEÁn¾ꋃgTEÍ®\]Þ‘Šº`wQ@jUÖ²’…$¨@Á"Ϩ^Ù>±_#!Y+¤BÊÛº’:¯£Sh[—jé|ŽN…NXº€ÔñŸ1ÙÅÁØè‘)YžÆW¾œVo l]9=<Ë'5±FذUüΰQ_£/‹jòë<Óé[z)•:ªPÛh7C›NqŠ@Û6Èw€{¸/Ú—V¥À4[·Ø±Œ¶ÝÜcìâq$WS…wݯ—šW1ß!½îŽ¡Ü*Þ¢“ÆrÚ ù8ú=½¥Ü}mÔýQÔoƒî8¹åMè—n—Çxñ­ èçbœözgkgi‰¨6ßÀZÊ1f>P‹9îçh“^ Ô)}T¯ô™­¨S æ¯c=°Ææ<Œ³õ«Ð/r ÊÓ`‡ž$sÔS´\LÏbýeÖº>ÚÁkŽ® öÛ6„ecA,0ç/€u¹9c›5.¬Ó2(®BõeÚ)¾H üõ„>@ÃKÄ~úp»ØN +°³Hï¤Ã,ë%ªÍ«â(5k—iê¾cÂ:¶ÃßxùªÑBõo”f̤=ˆ¯5/p cþUÆÃv*Æü Àb@ÆP-Ѐ¹þáø‰}y/öu#æúÄË1ÜFEÀZìK¸íÁü Ùç¼ïJéðr´}m61 ÿ¼ÖÎ1É}¸?ÆšiÇaë5¦V´i„_ÿ€Ÿmp ãÌê^Ä8S˜,€V  Èžæ`n¼šŒWÄ Ç¦ŒĆÞÂ6³ÖŽÉý´r¦Å‹çI6NQ•d“ó…c¶t8csNqÌ8,㻊ã^yŸ×É1e䞤µlƒÌAĖÜw°™óáZBõàÈãŽY¶Ïaö Çšô rÂæ1kM—9ÖˆRìX¯qØñE”wÐqŒYilÅ™ÒLyâ›x{Ÿ¶Š÷h6—èéÐa=hQi£ïrìåŸpqÃӯܫ÷bíðg?= Ÿ~Cô«·Š~E×ÛÍwtRÎëíꣲ<‚ÝPz­:fFlÝ¿«ÿ,P/êí83ÛÍwõ~ÓÄzçœð *é@’ÃПBÀmÞyJ“·Jéò”Ï º Ü/”¥h©èÅþøqÎ# /Ñß çµFÚ/úÍß+! ©ýTëñÓ|?Mà¹Ô‹TÃàñÁ»bâ(.æÜ±ä°¯næ3ߎ©`ù÷Š·m||ˆ8ú±bͱ”Ïgy?àŒj­x5¯Dãó<=>àħ+N«\ñ9Ηn–w Îw'OaÇ~gý|>òÇg$Ÿs|Î8íÝÓ?¬¶!Žù~™*ì¼¾ÕF>l|ÓÎ}œÃØï2Ó4rÍF§yR›dž4£ü;@7O`ÝGïÔ 9lß§s»ÔÒÓMÎ=ªgÐNû<;.Ï›è‡ò-•ö1NÓ}ûŽ3PÚÛlç ü »«D%|~˜°Ž©Zòz`ûDîÑÍ|/𨄟ù.j¤íu¼¸oM”÷Å**ƒíç¥w*3ëô2j5i±(ÁYÛKÛy¯xlï½÷Aïõãœè§Eâ§hã§±h×,} 2.¸oû³<ˆÙ hÃãµÈ>šdûã¸ô…ì·Çûc~Ú(߃ô#½„ÊC-žµ%È9?ÄO¡_ Û‚~Óä}}îF~ÕãlªÇ™C2þ+Ì!­ëyç: …à£vºYÁ‡Urík„uÆÖqþhm4‹cÄ8ˆs˜ß),æQŽQEÐ5ê8'1ïèCþ¦#w÷£ÿ ûÜ&̽zß2üFà|ñ(ÁÉwIø‚ùµw¨E˧zÄñÞƒðÃ>JÃ}¡ önYò£6,HÏb%YóÑ#RŸA¯ªmÚMˆ[¾C»Å^úš(¥ÅÚ"š*&Ršø rõc:¢M Íâ%:"º¨e‘@s4¼ÒµN¼-Yîb½ú*ä&ª+пž¾.6SµÖØû-÷`¯ÑOÿ.â$ý?À¸6”·¨B+EnÕ¢ü±yŠÛÉ9:Í2†È£4Ù/ÒV.›Õø-{ {¹g/lÚéØxûä:y\ôã6â­ 2/3-.T©hVÿ@ÙÚzú¶rÒìQŽR®2µñ3Ê“ÜâŽÏTv D&= ìEy>ø—ÀiKÆÛ-“^öaì³à§ù»€¡®¦%ÌК€_;u±à¹®§…žhöÄÉÏà®”ËXÃåø:9ç^¼Ë3ÛÍb1Ÿaì¡Éž‡h²6ú[ÐÏ%ë‰È§g(u4{FƒrÒ¥-b×èìxÊ àR '1ÛwÃdßgöwð%éß¿“ߊ!úœrѼ.U.’O{1@NƒœàøÓÙ'è õ®ýC¬Fæ?Ýz·ìÞ×ÑdõiÚ '¢ñð8­dˆUh¸eïyZÉ0^@Ý #eqbTÐmÚa¶ 18{¤lÜI³j*lÆ}s@T¾€3à¶²ÿxZ˹ ¨ø^¢õ™”Èñëö«vتwöÇÙ÷þÀ¾€x…Ög—ƒ‹ÀùGãÛ>/âb¾ÐŠ÷¨ÌgÉ€«Íµœ¸–ø®¹þ˜ÿO@î¼ô/þ¯çR± øãÞ!«ðŽìÇûänª!ºŠ³ä“…ÀOpƒ_ƒ·÷ð\`<Ê¡û*øI¢¡Q~ú~ ¦*©Ù~WN…îçv_¯=^‘ÕèWDW.§­þCmÀ½(¿<‚òÁgÁMhÿ.ú=>gÕ_Ý ù!à9ȃï‚(ìÏ€IèˆÁï‘ß¡ÿu¾þ÷Ç2Þ,Û`ç px·ûâ†ÙÙÏQØý­áìÿh¬Ûß#Ùò¾™ÞÄ»/ûíóiß8c?‡cñ/ÖË>¶ÉãŽãw÷8~IpüB»ø±;‰ Ä”P–@(yìjM hœe$¼DbÐ && ¦¡µÄ$¶1©Ahš¦U¨Oì58P)™²•5+P­Œiôv“¶þÁRªÑÎûÞÙ@Ýüøó{¹û=wçó=w¿Ç°>÷rÊY<æ¹,ÏŸEþXÐâýMä±è—Š¢Æx,<å¹3Ï_¡yûÏKÄxÖc\½b\…sãþ“¼ìÀSÐ;s‹ÍÍ]ÄÙdÞz¹æÏ8âlãçÀº¿$ê¯äFy ôø^è›Å3­¸·Þ·ÇÎp¦ý¿ýG=#¿Ä™)Ð3‡•i,°š3ý,~Tf:»¿ôYþ3úîsúõ‹ç|‘™òÒûò€ü™Ú{TzÞñÈþ´¼¤èOç¾úék¯˜ÏÌ!s¦˜öÜ=*üÝÂðÊÜ¿8†éÏñÔóV|GØOâwƒ}`^á =…ýbðœQ¹c(Ûg¾M"æÓ$ÿ€sóßס·ò:èAz˜öiî øßƒo7\±¶Î´ž§¯[žŸ‹üs&öÁ£|ü¤4'ß*þ×ü}ÿ™áÔå﹆®ÜMÃE0-œQ/!ß§áÛàÛ†:lÑjÉE&AHD¬m  €A`$¶BÉN°Œ‚E*¹ÒÇžT³PÏ •ÙþlD¸›òn÷7„›y&™×_[“×±Õù°eù°'ç‹¶äõÜyí F4®K­‘±h•TEތ삤ì7Øù)QÈI©’è€IÆB‰*93µ¡Èà¨d Tb%[‰’“hÚêˆDKYŽM'Îü°ëùv=Sîˆ FŸf’—Á(؇¸>`àër7;d3£à˜Fv ×û¸Þcï{—ÔƒfÐÁ(˜&ö.¤½Ãß7…äv3`ìH;{?ëmH» ë*»Š¡½•nXF¸¾`(Á‚áò gU$Ëþ¾5_ɲ¿düaådt»LtÀÐÙe4~™øA;軀ÖXWˆŽ‚“@F܃7Gàgà p…,*hföfÝdÙ¥t¨E‰V±‹ìV]JB4ÝHRÂ_Bd3׋‰Ì^‚Ž¤å ¸Í–-PÎÒr~×°rKþ«ò‘œe0ÿ.ŸSþäÏhZù#J^V.ˇ”×ë³f”¼ÊR¨³~:"7*§'DèTœH+û¸V¾+·*;dQÑ—¯Ø˜‚§Ú”µ¡.eÚ‹É›5…6‡•fy£²<µ„ß3¬,ÂÂy³ƒ/‹Nk|¢Áõ YºM]`:nê4µ™¾bŠ˜˜&Åä5yLf§Ùn.7Ï2—šÍf£Ù`ffb®È殩a‚¿®Âh犿|Pb¶q !ö5jfäi¢Ï–,±®…&ô±-$±Ù¯º®&KK×té%5-Tw&H¢£Eo '²¦ÜZ½!œÐMí_ï¢ôH¥:ûA–’ŽÎ,Íñ¢ƒݹ²s„Pê8xØÃõ¼ƒ‡“Iâ®ÚÓìnv®p,ýj좷 Ãw>î{l¯~<±®Sÿ¥7©G¸‘ó&ú×ù»;Gè'ôãxl„Þà*Ù9"­ ŸÄ×òriE,™LdéGüôâ°bnˆ8³øyñ›}ù¸ù¸ îG\-Wˆ³XHPÄ-g Y„Ð9D!2#B6Ü ©/„š 9$z’è9c½VŒ±^CLø¿ýôµ„Ã4Ó”ÜÒ韛÷ÖÄû@¯þüžmn]Ûì÷mIò ¿.…z7oÙÆõ¦>=YÓÓ·ÔÄüCMݨîæÕM5±!ÒïèêVûbé&µ)^³)–Ì´¶/n¸§¯CS}-n@cí¼±Å¼¯Ö†T7ðêVÞWï«÷Õª¶Š¾ˆXãíCfÒ’\Ù×VVŠõÚë $[ªì»VˆÅÛpïóœEBò RNê³jZt+àUGò*ÖØ¿ô›Y„S©¯3Z’pFJ"ÎÇî„;ÊEÜ.êŒpΈ3òtMûÅÆm\X³¯Ï©Ù_ÓñÛ‡±Çø];¥Æ…šxöÃÆoüøx+®oÅÆãìn5Z[¥ø¸±”TâzH¢ÉXLž„(š«ËùvØ“R¥iœ8Ûr Õ5é°í ÄQ.ÌqÜ í7ÍŒGG²t$ éU&Y´8F´â²Ò²„(Áå¦Úúûªå}Û7çÏÆqÜX܇ïbÛЕÑ{¨Ý½¯÷#Ïÿ—ÿïèÊt2‹L1rXXòaCÛŸSOØÒcwº(%ÕйÛe·›Á.U5;ŸévY&Õv[€uÂ1##í—âtF‘Vœƒ+áñzÜ”ŒnÇñøÔ¹ù[¶÷-¯úØXŒ¯á¿öÝ·{ùŸî^2þaä@”Ï¡,?›YQ¹ž‡ÖYÈç9Ü:A-ëd^þ\Àë*É"Bˆ_©Yî‹?B‡SUÃÉl’&“¨pОY4M µ„j xÏq¼ÇhÈâ·Ž±ö˜±ü7®âWPÉè‘nÊëçÀÕGõæ’„`'‘ ßd\‰åÒìE¨­GÛP”b›õÈÈx85vðŇðYçÝ?Œ|ãg¿zwE¨£c^rå¹—Î__]ÿ£C»ÿùVDzã}Gw=5˜²tìï¦ÄqípV¿Ogëï "̨Wà.ˆÊª]±‡d¹À ò¡‚ P FUÅç‡m6LùÃRŒ¡È^2õɲ 9**+aÉ~Ù ô‚£‚žÏb7Ãoº zÔùêN•Ÿ¯Õh›r¹Ç<ÏÒµ®Užêf×Nu·ëõÜŸª²æLÞXÕÆKüb‹ ôb*@*.éR7ïë!G‘Ÿ¬Ñó!JÂTuáõaö1&‡_–c¦6Å0ŠÑˆ‡Ï°'±–¯úÒ¸¼Ó?€{p9l$çtëjõ@¿ujR°L™f ÇSãº5:ÈÈ û$ÃsN(Uª7Ô:ËvÙ \.»ÈC‰¸vof3Æ(´ÆÇÒ®¨1¢ D›Ö`1JÄFœŒFÍ£êÄgCtŒMK´mʤ©ŽQSÇvÊØj»É$°ö?‡]ÄNËìî¹Ü³wÏ9ÿÿßÿ}„>LŸ‹¾Nú 9-uáéû1"|Hé%¤ÜV‚îñKƒ 6äóCºÂÍüz¾#”sŰ9ÿØ Ç§§‡èO„!ð#Y4lAq}yP4²ƒ¢? ƱAƶa0 ŸH…¬r*&»›È»o^¼Ø+Æ•‡¸ÎçŨw RÍK{¦é0pìœ!ät# ç³Óá4)Is¹Ò”*l2Ïkiv #Á ý‚)vÁPF9¢„ÖÑ` ƒ#ÏÁ¸WfŸÓ}?Kßš¾ÛyÄùñªøeªÅêôJ£}œµÐTh; <Æ:g’Ëátþ^’“%g²$Û"†“nÄöƒ •dÃ…ã›:#óø2…°š¡Óí©•ÊJ¥QÙ¡ð €ÄË@âÅÈ«x‰7o«î8‡‹‘ŒwAQMl—Nÿ/°d< –Çp‰PE a€ƒ‰-ô5[ òMEĈq®µõl+NjZ/È•,€Èžý+×Þå:ÚZæ¶ä{ƒ\æLä‡Ç×§÷àbÀðÓ›tYú¤‹Ñ™‹ôñù‹ÁZx\|‰7EPi±ç¹§¹§eß…xZ‡øÕ–:Û*q}­gÚŠ[øM–×lMâ&ûvÏÔ‹N‡Òž¦ûè ëãè0VϦðÑòti^$Â6öà‘®?oÅÖ.Re(ùõ²¡vdŒdE&rÞÙ9Þ[’ÃÌ·gÕ»†-ËpWëSÖæ!`ÿáåEãg‹°ÃѦG ã¹Èª:Tãììâ q9—Pî8“G e$tpuíòÛç/Ü­YѼ=Öýz¬ç¢M5K_ß²¤jó¤i­³^;Ú¶¡ñ—š·§zÿ[û—¼•7¦gó¹Gã ;>Æ/,mÚXùbsÓÀ£­e‡×o8~4áeiMjÀŠÆómË€0J…ÐÏJ;c'/µ8¹4£^•¥TeNGõªcòm¹š,eHe'Iɨc&#í ¸ L;ŸŠh•žüÈxF"ãY` Û´üÊ¢7?v#6ñ¸w£YóTYÿŸUŸ\ë¿–7r!cÂ$ßón#ð#÷ÜÀn¹{…¯*°Ö·NkñmÓö¹ùÎùîºoëýºóûî÷ÜmnnRÞb3É¡}7ÅäÍÔÍz®V&UÒ&›F—ėˇ(¹ƒn"ã,"0²úd[mCyºƒÒ´:\Kª¡µ5ÿÒHµIK):²w&hEêp$ï”O“â 9”maDPLU!´QbV2.VKµm³Ö•—à’Vt`áâŽè«kïüàùôÐꟶkXwÏRÖ¾ü|ãµZÑ;§[®ÝÂʾØßb_Åþ;õáynÂÛ=ï´åBÍtƒýÙÄg£ h"è2 Vbñ\›ù$]ƒˆ±8`9°N¨ ü n€åÁÁY\äâàÝÝÛÛË…{{ŽôöÂoWŸ‹¦ËP~ÔdŒƒ\¤’_C*Yä{)•Ôˆ %RV”HS$’šbx¤ä¨*²ç%c bÂdú3CI!¿_efjh¾örÒ|Ou–2_CW˜[Á‚ ¦a)Ñ2a)ý!ç>• ùü¡HHKKJi˜«wžBV"=¾†5÷SYM|ÿ•ú}Þ?ý£ŠóJ|¤«/ËrTϘô½üC‹&-ûEë^wﻇ\=ó¹ËcoÑ?DÈÅ. WubIV˜4þª#~ñ ƒ¡\f4Ì(ÕÄ>Ç)…J•e©u²™kU~gºh¾ ÜSlSÏ!åÊRÛIåøÀþ@²ò"oç%Ζd5ñ<ø)‹YD¸¶˜E#Ë2EÒ1¦ÇÑ{.zÓy1ž²j&“E3sæ.RkX‘E¼cLÈYlбQG/ ÜËùÏø[<×Êc¾ cÃV.^n‰\«ˆEú¿" Ÿ ¤QX/áMùêCõ‘oxy¡F|) Ô½wrÈÜÇÒm6äçƒZl.𲑕øf¥§Gêéi6 µé'm³¦ŸÔ~P1¯ƒ—9‹pöÑ=PªßPØ„ñ*ª0é_á—É93¹ì³À‘¢Ïɼ›¿|ûÀu|ïTZ‘éì·Sñ¹ØRww¿²}íß»¡6ï@¦T¦!݈‡œ;gO}ÅÛ] έ¦zC Ú'<_õU·bŒynüÔê ¡w>‘V@͈¢¿šOE väïSûÛ̲Ð(s>Z‚–G»Ðšè&´]z]xÍ<*ô›0O£‹Ñ/¢^—/êF…j¹Ò[]l•VÚÅþÖìï/]ÍžýÕ~Ü6ð1Ñ|¼~à•}ÿœ½øòºßüƒºÏ¿:‰¿÷þ%ü­ƒÞÙýò®ìç›ßÊ~öÒÛ¬’ï€Ú3í†Ü]²k¬ÜFtz=17¢à²ŠKl®>9¨T!J-äw8ôxI —D= ½/ó땇^ìAèåìÌ=ÈÕÕ¶½`7 …ÊT¢"å¢Âp!‘u x  r0ùC‚ âØç‚¥ÇqHóÆd1•ª†Ï*œa-„`D!€ÏD|T£P˜_â;ð¿_Ÿ¹²cù²É?Ú|jmö No~­îñö_~wroö=éX0úä3Ù?¿³7›Ý7oTocÝãŸí¹üeu ¢Þ•áSÈ£Ž^µƒ²£TQ ²DjjLGTaèˆz| Ê4a¢¥Y&Ѧ¨þt5šg9Ê%­6Ó~ãbêAžÖÕBÔÁxîØ%–íRCk¤c½ÙqodÍ^Æ"ƒâZˆAE?·S<† ¾„ðk‹X:!aýü¶u#aö!÷µæÙ÷¹ŸÿA‹é}ïþ6t‰žÂüÛ;¼|X Ü? ÜO`¿Ž"A2·Ï¡~ìÊËQÜW@(F89-æÆrAÌ%€òW1NV$Ê-A€¸*æÂTè 5¹îË"ã¯|x÷°ÿ'K»*pE4iiXãâW+JΟu—ÊížÌÍ\<à<Çš»#U ¿fõ6B Ë"Åáâ¢bA6’žD0Y’¤ 1Y–(4£qrûãðpÀo)pU*%â¸Xd¼°ÄÔx• ° öƒ€p2-©ü‡aeðè„÷¿ªG¨@ùò!+ }"&¯ð$Y¼1{ºû\vgžòÑNŒ_Nî?søùµ?ˆy“Í+¿Nƽ‡/,]vÏ9w/ë_xäµKºÚ¿¹æ©õ;ßÉÞêš×„½°»¡¢”r&œ;ŠLÈzØl…˜ªuk§5¢I„èl) ´¼k<ß`\·uÞõ<¼ë±a­w>Ì;_¦ËÄ&ÑÔ±­Ôà¥?šƒß}'”cebËœbÎ5—˜bsGa*Ó™¯?¹ äìcŠaø4®f9^†049€$e°î ·†eéØð2óöxÒ7Ü>B­‚,è½CŒ;D¯ûÆ´6ðs}ƒsYëœ+«œsYÂ9Gcι0ÌÏ0õx,i“´_¬‚XÛˆºÑ$Ö MAGƒHòYpsøã<“0k8ÙùW>;×òÙ¹i{¥Ç³³K<Óq_ñm›ýô›] ç2K[†3ù”@Æ1*Ö{0i16ÝùD˜ÇÕÐ>Ûó,Y(/'ߗכ뽲ÊùÖ¯3ºÁa[cnUMjMêlœcžqƒ9¤;ÕNÓfwìÛ1=cù±å·ýSüsý¢'Y?Ï—Ä+ùMý8WS&ùç#¹êÉt:1õ¼š÷QÆ™ ÞC 64%›÷+KæOXT9ÐqrõÉS¸»°ç'mËV ×‡ŠŽüiÑyVAõIS¢qÖŽ ¥MiªŽ­ÐFËÚÚ apVPVh BbU‚·ÆJiƒø’ô[ñ •4ψDe V}ñÁb ˆ†>#ícwûàšæÎ";GùùDŸ/Ä[‹à7‰VªµuUM¥š$ˆ¢%iI‚+ “ ª]Ö4$E§ˆjÑ1±¶»VÂÝÒé„tA¥‰”ÝÓkl ? Ê²Î6tëmF×ï5£&ãs‚‰µó*›ùXEjaôiiaTA&ä]LÈK äE0êi¡- Û A¶G@¶3U}nLÇA™´Mãƒ}†—åkÐ.Cö¸¼ Ôãò4¨ÌÒ<À äün×Mü(¶½j)ämDQZdGi$ ä88f(-³´ê¾4- ¤E;fi>”3˜NÝût°ãÎ¥™bƒC?ŽcøS¼[È9¬ o#«ï á›ƒ@ÿ*rvøwC[Éå+YÑAX ¨‘ÐbÛÀ* „¨ÅF"²×v+DxäÖó!¹$?$—.gœžïP4÷Þš~Ñ ?±!Ù žxÈŃÄI*…À+$u™^ÞÝ 8€ºfW2Ëð±¯%·!¨ªê.DU¢é2ç®'GÜÛ‡9q=àÜåþ\$·ò‘ 9‘Ô€§ø%äÄ ÏéÓ'¼00¤RÎn¡ˆ³Óv‰Âë‘ÌW¯"_%¾R†¶2f.* a²nìâò“ÏG_æKe +aVR†¥ùÜ|‘ aH2 ÚŒÎÞÆ þ’·Ètäƒ\M·Íœz‘óéç¯E˜År£°ÎÛB‹LæöR#öOqÓ‰Pq…±Îø#¤Ò˜`Lp UbÂázZ˜%®0èzѤ:‘hÚlt=E& )6m7¿áÒ¶’mÂe íö*²¸]®Z‰Û 5L³V¢`Rcê(¯Öà&®+¼÷jWÚ÷ËÒj%ÙB²¥µ]GøýPðÔÛLy»åa[ƒ[pÒHìðL†Æ™„‡ Ií˜&m¦hË”à`<¦m¨'“ò`¦e ™”i›q›0w(ñôíuÏ]I„iþ´–W÷ì^iµ÷Üï|çû”¯"a̲/ï˲Jö©GÔ±>†OQª>ÇÄØQTmó"ÇÇlñI c°H 0ƒG‘`s QéS‘:Š×]ˆ1=Ì ­ŸÖHk ©S™©L³ 8› ‡T¨ìæð½“‰ e‚`kVï{…ÕÉIRèû÷¼±ÊàÞeg¨ð(Tø/(qn0xÂs×›šš:¡úE˜+s«_šû׫2O®B“Ók#ñ´ü@<-Bؘ–kÝð| ®¦råÚùxjºV'ÀÁ†F‡Jv %PW•ªGsÑY÷3§ƒ›¾óâ—۾뙹ÛJ¿=]Oÿq:nh#hÉ›Ì5J¦"Ô»-¬ ¿ê÷G‚‘M«´_ útpD~SöƒfÇŠlmUÁª î`:¸vu­¶¡`}pƒ¹.Üy6x«¡¨Ç£G.`Å@J“ÞEŠÄ—ïÅÜv«ÜGºS.Ì|DÄÄ]@‡‹P‘b¶ðÞÈPaÞAf-d&Ï+²>I$ØÈ•Š×ÐÄð¸J°Q¥jk(­ƒ¤6¢¨ámÔú“ל‘ׯ:c§.£¢ ÈÀ­ßsnà+h+zeÜùáïÿàüàüe´þ—Î?«¨E†‘ðmçÏYIÏ»H”I³èÕ6ûñ2u™¿KíòÓ‚ÜRA3ë t‹åɺY5WÑ9M͆caÿaSúÅg}Qè~rtÙq¥Úï&‡$&ïŠ\%ÙµƒQ ¹‰Ç5ˆï9A\~dÅ–#sÞr '~þ½Ìòêgœ!fLÖ{G¶^tfgêA‡žì~: Q… Î@LªÍØq]‘ÞP¸~ÞCìÖy4§º|ä¾ûÜ÷‘GdÙoˆù@Èúè܇Ãz¸ÆÛÃÅ¥u9/*­Ss£’aþwÃEVv>¯æF2o/ )/-\[-tn-|œÛ%({ùÊKÒieTùXþHQCcšâ×4ESDNàxØà½º¦J"crœ ‡¢A",C$éÁ /v÷Ó4Ef£–ü²—@;§ä³[åJøbWÌ{ÉŠ½™X¢/1˜ð$ŠÍÿu½ŸUï¹=.!rã¿Ìc®B&l³KC¹½®€¹æt%Ð4Ò‚éýòü tÙþŠûÿ¨œúµyÖVÒŠú ¦?H˜õ»<$ƒ`‡Òh Ù.L« ÔâypÜS „}j #à÷úŒ ,(ñÌǧZ[%ñøàïì¾òÛek—ÏM¯}´=_ö'tbïÑ•/tª˜±U—^¾^”L¬Üáô£êg5 ¾ÙžÚÆÅߨGôh÷ÜGô_ÁñVá€]ºÑ³‘ÞæÙNÓÉÒzOºðKž%¾åE‹æ-L´–®ötúº‹Úˆ äbhI¾ù ™¬|PšJÜ­È~8$ó•J‰‹h%Q™d%pÂSšlPêJ&U®­+Y›Ü"|SÚ,?äï5„ÝÒneº#±-¹ÏsP’*Ï©{O'HG•£h®ÿ§â–±ÂœU2Ÿ*ëtMµEõBqI©ÈPG’†”Š–&Q’1Ân¿g¢).5<.çUhz:GnÈ Òœ+'³¯ˆJ&dI`â…EÑëóÒìEÉD1\ó2ÑH*lؽ<4iP)balW©(†ÚPêC‡‘ ÍY» E~’ü4<ñR΢ÊQ9¡pYÆkËÉ£Iä{åáX²tbÂÈ”ž¹N°¬¸U¾†ÔB¨zc— èÌŠ ×½ŸÿÃ¥ò©,™«àÄ&ÈÛYÀV—FvWÓÿ)Šó £¸6‹¶R+QjYõu µ€Ê ÏÊ÷üAƒº ”°º/H.ïyìǫۺ8[¾òÈÃߺó“ÿÞÇŒ)gNŸ=‘nBïw îÞ7ýʯOŽ£ê£ÏµqÛÂE—¿VÑx²÷±_mzä§ägŸªkUmíæ²çwmû-‚Ô*è cÀŠ>jÈ–…„Sw†æFñ¶aW #tÁC¸Òƒ<ŸG.5›Ø‚KlŽîäÅð‡y’˜É“‚“•eäŽìÈñûu1¤³YÈü…A–ú««âZ¼>ˆk¸À)¢:F:sæî'äiO@÷/†§õSïÛ¼¥tÐì[,mº:zÛJ/ew*?b>V|"…µQ|ñ5/ç·0Ù`ò¤˜ˆT³çú36óêMgæäóHºåY5sîõó_G~’#ú\+äˆGŸÏz [gźÝ¬'Ç23•7ßUo¾«ÕÖBÎ[¨ÕU;QÉ ÏQež$_)V‰=â;Ä/‰·ÁuŠm"¦±Àâ,\àònÙÒ‚ÎáÛ<ÇÅXÆÏ² ÁŒc†ƒŸºãAïö²¨³$•BYºEƒìaβ%l—¥7`ôþ>Ƙ\ÑbLƒ«@ãf.1·tîa¡çTVçöO@5‘ÃT¡ ¡‘„C“fK3Q³Äµ‚š…eµ¬ôê9Jøû9NGd¹â®Éý#²¶ >ÖàÊZjîRSg§+Ê@vtÆQmV¥Ö"ü…ÙË¿A{æÏ+N¡CoÎŽƒ8½1Ø·k]~·•äP˜ñC: ¥†Ý}liqw-è²'I~ÔCƒëðú ù< ‘“dEýº0‚¦kf(3FFQ×Èh¯°\Œb0Ž!Êe2, ˜þ@ÀÔEŽ‹tuMT”ÿP]íÁQUgüžûØ{÷¾»{w77¹›dó\ Ù˜ÜL0y XˆtK°"&P Q¤¶€ZB§Ð?hgdZiKíH©VZ2š¡C&ŒZZy´ B cqZ”lú³‰Àd÷œ/gÎì=ç~¿ß÷ý~ Ýéºae!æ4C^Á‘8&ªkZ0(4œ)jš†A qÛŽëSƒè1*AÉ0†áëSz¬7‘@Åb}hÇ¡œ0ÈÄc-#`RFⱑèü+¦_ùZŒ›¬à~Æø×ó¶¶ÜoYœ€I[U}`†¦ñèþ’­A² Œ SŒs(ÅÊ{³A*¬–}ÎoÈ¢;€°r€°L˜¬Z°.¥e¡Ÿg¿ÿç‹ÉxƒˆìÏ>XPìL¼ò^vÍ;Ù÷Ëx;”=\mþéîëIæÂH<{ã?;Ž0o§Éü0±bÖW¿cì@Eõ+ ÅPD¢+Ì «Õ3 BC°AiTëÌzK4­„Y˜6ñ BÝ: ³26Çf׳Õ°xƒ‡ hƒD—²|¹T©–š±B£„q¶°ˆÍOJKÕEæJ´‚íVIê s=û=k‚ æk »ß.îfû„cæIö”ð7öïÂÇêYó*{M¸¦^1'€ŒüÌ7dšp’€G Úÿã` ç’L…CzT4Xw^óUéŠV *ÑiH;Î1´Ç¤3€æ`A'bh4–¦* ÒuÅ0-K‚wF+#[¢„:mEËJPA¨A†V”„Ì„d™ŠÄ04m)Ðê)¡*ŒÂ€Î„ì˴܇–Kˆ»Ä~‘ûPßÑecŧÏG|½UÔ6ùb‚Š…Âïâⓚc6Š g†3ØfÀíVîˆRø6ž§i•MÂÀýS•Kˆ°Íy4Þˆ •@ÐJ1a1Íó@’\x;ϳr ¯±7ÏŠò<È}ÿÛŽ§àòê:ž—¯¢Fì&ËŒØSpM x— þ$~Óô$9¿p ¢ò ›$G4Ždˆ5ˆ5Ñ= ÁSè¾”7ËZt¯RŽS"H×gå«H\X\3 •}82B§newº…5áì.ú.ý§ì¶õÍ­‹Ñæ‘–»whib]kAA%ýG¶ZþuŠ¡@ê¡fŠŽsTŒ6—ŒËúªªe¸¦šyà²of;^~;»GG¯±û0UNÕÓý A%XSâ•Je¥§<®Ïk¬œS™Q2•JGe{õveKÅk‘=ñ7•p96E¸g—aLïôFlyoìòØ`ùáóåÂô*ÀzÑÀ-Ý4‰ %²¶3­ G®íFS*ÓëM˜ÃΞð¸°$õŒÐ‘zAÞ*Ÿ’ï(wRF}ZE¬^•LÛ“ CÑek+è §JmVwª¯«£*÷ºÚ£ÞTUÆÒBÅB‹ ?8¬ë6UÆ:B hŒªÃØ}ôþÞèîãðÞ'RkF™8Ùa¤Šåúr*@TXIa+Ÿ1cq#§|’,V+ðÿe¸< n“·Á'XÕAD”×pÉ>ú _-ó©R½4QZ]ÚSÊy6¢˜Ápœí%A ^ó•‚âtµ×ïÑ{=äÙølSñ/Ú%Ñ¢ªä‰À`€vÍ: 3*'%.TƇÁ#Ô•8R?ÚäïAœ¬%¹:nÇ5»]Úu‹œZçg»Ë 4ZM‘¦ø¼È¼xFÈ(ßÔ2‘oÅ;…ÕʳښȚx¿û±|Î>û§uþû4ÿ’;êÆ\•Vªæš5Ÿ›§µrÏpçò¿`¿Ôe=¬²šÊs€ÁbØQ¥hòŒ„tÉ—Ú¥Mëú8[Á¨%1Á8yÜ"’0˜0x ¸DÀƒWü*œOéydÔR|K,A-SBÓý\Û^tÝB¬‹šÑÄ l0h!¸ëçcx!DD;21T î4G0ÂÈÖ~4Šâç¢~Š̪@zcTt7µè#°†íÞ"‘áð1<¢ˆ¡ÃFª«°t8¸³:¬SÅEe ˜3x7€ šø›#݇žêéò³Ÿÿñø*:Ýöãüzý ¸?Œ|±sÁο<—½™=û3ô“m;N¿æäiè÷­£×˜a¨Wq´tL¡§ÕÒ$äS­Ô:¨}¬éH|Ôa%¤†yßž'·çe|{^Ç·ç ÂOt2ç>2“ñ ùYA¹Î4kš½ÐZh·[íözóš²Oß—%&vÒL'·^^§lRÞ{Å£²‘·ÈŸÒŒZ´L[«mÔ A‰ñ_¬¦ð¡ÚáX»¨½Ô%êÈM“¨{gtàèIU õ©(î—”R.(JÐ{>IO²3›ä$Nr2Ç 'yäòÍ<Í«x/âM<)¯|M^z`Ì%BVräÏtÏ]X<—¨4„UÚp÷íÔp7¹;ÝðªôÌeøà´áž´Ù˜Û”‘6!u›/ÅÙÊQ˜i:”ó­sÙÿvÿëÕß}âöÄ6.ݶß:„6ÛÇQ> ú¥ž_ä­ZýÞ‡gß%=f&äì"0ÒF¶ùûDšUJ”´2]áêBuÎbz‘øÐBg%ý4·"øíP»Óï~ÄýÕ:²†B7íë±!¼ˆë¦â˜®s㘻ü$:©LŠ4ÒuÊ\z†234ÇY,>®¬T†W#_¢ÛªŽÂŒ*é0Râ (ÉHÑZD•Z‰®Ÿ1nøF»±ÉjbLäj˜˜9iZ˜ªF#È „…ÕÏa+¼qCÅoþÿ7a©Íê#8;Æófò?È_äGy§hÏðr¤Nó9(’´‘¶Ä“îÃÇ Òÿçºj`›8Ïð÷Ý}÷óÝÙ¹³s¾‹Ç NöZ‚?f5Çh‚ZHBha¤#]?b ­¥Ð´©hmtŠº•­[ÂØíÖ5„¨+™Š˜41¶2i´¦FtKm]'{¿ïÈ*Ë÷ýØçó÷>ïó¼Ï»bÓÚ:G³³I—~-›áÍ.{ßçô[±J¦Å Æ`À9lÝç™X³ñÜó—wnyo_û<•-úÕÎ]¿8±w÷Ñý?=tçX¿Û²XÈ™h‚þøûóW.œc˜-< f¹NEBÂ*±Mj£«ôâVé)ºQWC¬ òcÃÄ]Éf…v- þMš°ÆóIEpQ¸"²8ؘ¿8Ò\^YüVþºÈnywh\Ï3‘ ¿ã¬°Ûím¶hGŒn³×L“D4 o°ŒQ³!`ÄÝv¼’ ìq\°m °úìÑ~VÿYH¹££eóÓ}~ìÏÂêT¼4ÍFw1+³QµSæ\Å;?=ƒTÑ,¤")`Ž‘Íñ¤fkb[¢1;Òdv$ãlÝÈ”0 r„“«-“íÈp[Îàb6•WÐí33Qj! XJÌfxáX)/¢â“ƒÉOOßœü [\Æ9øî ­ÿ¥õ‡²W„_Íêï<û:^íÀQ{.Ÿ¼:yÛ,zkp3~eÿ’ÍÇAErÂ.é/ÈÁ~wŽE±~0¼ 솷…ì{Íÿº_Í÷—ûûÂCafñ(Ϧ U¿è3" +—ˆ2Òz,lMåºÄ‰$ ‡A–X+jÒlt‘hºá°Ëhvý@d1 P9ÛAÅŒ8(É'/]‹'ò<Ÿ|Ì L&~Ãmر¼ð<ˆbhkú†ñÄ,€Y1?‡FaÔ…Ö¡.“ÉdÐÝV,XòŒk™™*² ɤÁ ¦{þ /àðd{*PR™ªLWWM@Ö˜ª…R¡’@OOnþ¾]Ë×Ô,\ùðð°ø£C[Ó _ þDkhÿÆ¡»›€_™l?FÌAóñSn»®KVR[ËõzK¦…á¤^j%Kjõ*ëQ½ÁZ­¬Ñ7ëÚB9”$Ë*y¨lyYw²7©TŪæÕ%ô†Xý¼ÇcÏû¦²>¶~^{²+y¥ìFìÓ’ÏÊŽ-‡ÞN”Gr^IÌ"´€×‘.4„."°­B§»PŠD ­¾8âÓìP*žÒâyyl:®Óît9$ !V%¹¬9\Öœ{²æpYslþkB¹¬±oÉlíÉšÃLÁ£,鎣âèܳưq͘2HÔ¨3š¡ÐqÆù [£˜ýša¿dpm3¸¶áDrGŒÉ4÷åíóQó —ÏyFFؘaŒé€¢ä8¶ãÈ2`àéœS™ XÜ„æÎ»Moé —ìè<˜—ƒwõ½?öíK/ŸÙs|ãû½¿ûäÈñÎgO¼¹g÷‰5ù-ñ…ž¨îûÎ|ø*Ƈ^íº»åÖðî_Šó/ ½ðîùw¡›Bo@Õ²ðºÓȆÄ9i‘µ-Ü^ÇI¥X/ú ßZä„ÓŽð,QÂȈHŠ¥k¾8uSUé)Ї(¶y±]-çW‹A@Yc`£ÜÛÑ|ö=Ø÷ ¡ƒ„²£³çRÑ…}þ6‹-m²tUºÏ³…mv¯ÝgOÙĬ8ç«kƒó "Èœëˆ0ªqAe×á,õl¥ÊÈ4C'öýÎìo“(ø\Ÿ‚þä>I«Ø ši7í¥}tˆ^£cTA4J·Ñ.Ú3½uNQ-JÁc)D©,>‡‘,ÉD“•¸„Hé%}dˆ\'ò#"Eä"¬ñ¼²°ŠÜ‹áq#{*áÊFf”0ÎbF‰4CÒ¤~1zÛ!zLÆêFy‰`o–òÛ;¹•©Q9800@þ1<|'DJï\YŸúÙd ^ÄÏD—Ýz"Å¥/“”´_’U’B"å"ì×Ñò‘€¤+섺¬DF7(ºã+ýqMëÖqT¯Ó›uQg'ªf'ÒMÞ™ðFAç=¥>‡w&>v(]å= ç¶εތ-ÍjÎbè 2MfýƇ?î@u¬'€Skï/J0ÕŒ—ªi”ª¦V€iŽR€¼ŒÀmì츚S"`)@ñý“›‹«¢ÕU©Å?|„ܼtéöÞ#9&kïôžkÜÀø ¹ Þ‚¸èÂ:·@ö¼•¼Z~‚ІÿßÒ¸,RCOf=;ž63¡3 ò ×d7®ŸÖ„ \”K«Ðœ –¥)kÒ` J|#Æ7ÜaG&D"r5] PÈ_ÒÖhO‹;µ+âG²r\Æ%r©WkåZçoö·’VyÒJ;É3Òz^þ3ù«<"ßTþ+ßVCAM“D‘²¬PªÂ‚ªj\‘-E‘EBâ’fI’¦AÂCZJ²¢c‘FÞÁ†K%°‘ŠU¶ŠñîÀä¶%¿ GBzE„ëP30ÒÓ­àÜçˆ#Ž8♌‚\x;xk‚Â>ÿßcK7ÍÆšC u¬Ïx¢ äœSÞ„¤s&àÔHNóŒy‰˜(»šùõ¤Ì{7ÿ2Š£ôEQ yþ@´ £òÉÚ5®F“…µT-,Ì`Wû kax¯¿ˆ'cµü/´‚óÿ‹ ¸ã4’§†úcµâP¿Í†«ýf­ì |åãÃIÝ»9Ñ ÉÆntƒ¬Z6<Ͳ2üw÷ç±›ÿy²Àû:nkåÖÍ:¸^áÆ%X†â7nNnÁg¯N}^¼{÷MîÊn¢{&¿Æòr\ª9_?z[â%1U]“æcºÒTxcqœnÊ!E¥éšDšá2&‰Qi›Ô%MIÔ\DOàÙ/q¡³éAxÚLa¶Úߺ¯ö…³ÔÞÃÚócê´ó$ &SÜ {Ú…šÈÿk¯D“/^¥·{Û,2û¤Á‰†é*—‚g*Á8ü@³ÿ±]íÁMwøötzÜCÒž§;‡žF2„ Å“[ 30…½ 䆢 'Ú¥£HÇlш Il2Ik¸›ò$±¹ð1£=ø‡Š4ÉmDÆ-´“ÌrïAz›H1 § r´G*™N}0J¦Cçßè"žN%]Råðt*æiΪ€'Fç÷ÉÄ*žO¢èá(¢÷ú(:HaþÿüßáQ\JšèÀ÷KùŽî"­¸…­HÉHôè<ö¸“¦‚ ,»2ZÖœs…z¢Ím6Ϩõ#º"ÓEY\ΘKUà°ºKz"º |Ý3IÈćb»&>º¼qïKlÙÒ|õÜo gçoúùà ëžîªab{ë׬}áÏGŽâô¯7®©ÙÛ_è¥:;Ÿùå;…k%Ïuí ìÐFƒÉIÿž€Ÿþå¼m¸ë41Xrç¢ ³‚÷à|C—Íâ²¹$ò\À$Y9«M°Edâ³dâ¹xâ¶xâ¶øn‹'$àCä¼ÂÄmñÄm¡óÿå‰Ûâ±#rÈCÇôâëeL:/v^òm™Þ$÷ÉGåS2#èn‰póî (™÷ÿ ÷˜áË 3ÁÄSºãqWïwsù‡˜"Þ!&ì‘«èo©1öa¨?pa’Id9 gæ &M6Ø9Çȉ.l·Ñ"(c?æyâîý›¯7í{rƒ‰ ‹Û1±Þ# 7-Kí(´Óoü°õ‰= A…ªÿ’‰#­”6wËø—8 É옒í¸RÈ3§‹L‹-+M«,/›š-–4¬qÔHÕòBX稓ÊYc–]sŽœ´Bn5¶²ë`«£UZ'ÿ¸Y“ѺÚðœñ9nµ°Ñ°Þ¸žÛ(pc‘d¸"*É>*ÙfœrHö1ËøªN\½=ˆ×ŸÄ3àã@ Ò@1ÎH4=Í (34kfƒyú0Ò|}I œž†j[„l8ö:‚¯àk#øYKô‡’Â:šËMM÷¦gaqÍ=D擹»¹\–(eF‘Ô¢›Çm‹m06°kkY÷&|‹ÎB QnЍòPTÛÿæ™O´íÖ[Ãc£è~càØ®îÚ â»·Œ}V¸xëÇ ¬Î_øû™óçÐu53“‚*Öê»8΃uÉhG5:¨MÂþ”;å_àߤõh–OºÔ³T]eY-d=YµÅ²Ah†­ž ê)í²ëº|Ý{90â ÜÐÆ5)Ì$aÒ]ÍÔÀ§˜¥°~ÁßòA^´$Ÿ«¼ä³ñ”M‰ qr:×Äíä@¨8‘o»©óHNž8¿W2tß,‰³Ãrx¯…ñbsÀ9ƒžáˆRÔ)ä‚@8 n&2`90Ü爢ƀ¨1 ;xJ€ÉŒ±#·’`<1’H„+P‚‹fÉ YbX¸3ò0ææòÅ ñÄDk©nœTÞYUÉí¢q ‹†2ôºûköüà'C-›‡·5¾]%ÜÒùþ¡ŽöÆš'úì³?ïÀØ·o=]SøÖÐñôù«çÏý³pñX³áÂR>0SßÍÓI:!Ï¡ëè­‚)ãÎ(uJO /`L;Ój&Pë¬Uœ êKΗԦÀÎÀÓUÇMÓWÂ×2œL‡„¤{6]-,¡Ÿéfúšð©ü¹ô•rS½OÛcuy}¼ÙfrùœÇ6ƒŠB8dЮۛì;íL@çÑrzvVB;V\BF» /»]"Ÿ‘FŠ—Þ.áµÆRAHnÏõè#š/™‡Íãf&ˆLîrDÆa²4‡·¥¢ñ%|VüŽIé².™Ë/-$Ëpš‹Pšû]`¨< “Ä4ÇS<_*†ÊDïó'ÇþýÊåWÏä÷&ý¾³ýà‘-›Œ5Ó–9õ  ˜ûÆ^;¸ûÞ“†?\¼ø·®|òîp»4g*"õ±>gª@„™4ó$ÓÀ|Ÿé`L¬ha-¬Õ)²VÊ`<¡ű=` iNà¤CbÑøéðñÆPæõþ£‹eÆD„èGAö0e*3ùõŽE§§¨³ŒÀܶ´8xif£ rü¸Û¶ã4^¨6+y¯‹5Š]ûç7gV¿8Á‚9/ºLl_~qÍ¡ø¢LS[á ^…Ìø—†Ð*L3xômLȪa—²µ‘•¡õ¡íìnöõÈAçû•5XYWöL««üÄcTéçi¦'g-Y6Ëeù¬µ¶XZØ®…oZ¬ƒ±Á¸=‹Ä#“gF¹UüºØºŠŽpGdgä]îWžŠÞʽÓú¹ß âýÇbgbREɉ†JE¸TDJEE1N܃‹p©ˆ” ?ʺ#0»Ñ ãÕbn†¯ò{OЇõR‰?¨d”åÊåˆrI1Ù• òŠ2¬0Aåm…VN"lÜh_¦BÕ…o‡@4C(èh€}¾KJ»MLP•õoôÓ~ŸÛÌàÇÀƒPq“Œ ݉f|U|Ð ¼EwÊé>ÓN‘‹GÌEÂ{DÑðHEã‰téôês$†þÑ7{(ø[ðˆ¦'ž&Qâ)*¾>Ž%¼ä«&Åé¦Ô©IíLÑ)ˆPrÑï’-§WI;.ðàBWðCh;`;y<»6¡÷t膃@D!4\еÊtÜI‘ #’OHñ(ú‡è­­žX$|)Ÿ\Væ‰G‘Æ7eFóŽÙS‹É‰6yC›½Ðž÷Ý“Ÿ]•1: L!«¦Rl…YÆ)èp¡ÓI¶°J…ÂVÁ2™SAEœåLIF¥‚Ð}V"WV<àšL$»ºº¨29¹¶|Î9K*JM<¯¢«Ó3gâñb.òfž]lö±Ì€ýÍmÛ;«£ïžýÅò'¾—x§aÇÉFñ¨ÐÞ¼½E’¦ª¯Ø»²ùìŽK×À<߆¶õµóÂr4µ¤«~ÑÖŠ`rñ¶—åÙÿ‘]-°qexfö9³Ùݻܞïìæìäì‹/ŠƒîçRƒ·„*“ºyÆi…—«Bš„‡H‹Ò4Q–6PÚ„‡RZ‰4REãØŽí%BÔ†€’´"‘–PÕ¨T&‚Ïü3w1-øngg÷¼ùÿïÿ¾ÿÛÔ±¨¾!ÆnÛ¿cûñ»^uºxî=ÒªC!zc 1Àà¢æ"™½ &ë0¶ð‚ÍsÒ­XÜkBMØ ²6ž3ÌÛéí;½ÆAã[†Š szÆ8eŒ Ýb-¸Ê¨Šµœ¼7$8˨ú±ÚD²zµƒ®ödBûa¦×Z³jWiœ%ŸGI¼b ïL*Èï4ôÇÞUÁðÓ]0 ï Þ+¶æóÙPį¹Ý_üÞL¶È‹Ð/õñÎOïZzèÐàðp,Ÿ»å‡Ç½|îYò™Ç±±«òÄã³ßÙ°4%bôuà²)µžÞ3†Rº ,’L,Qäâm A¼˜áÅf,aãXÂ2÷!L¨È&Ca'RÒ«„Ò¥„@(m§ˆ@(é;œ÷'¡ô'¡ wéOBi8CáO¹‡8¼#%r´@X“Ô»)²7õLêTj.¥¦ì,ŠÍÐ tŠªô¦pÐyá òÉ”‰§Rq©TzJijéuÂ{ÎGŠkúÿM(ˆˆ{WgU9d¥TÏu¸CtÃÔMÍ#¢Úiä˜~ ÒÚú0è/\ÛØ.SÓÉ)øxQ+Ä\éÚé“ÏõxÖåïÞ¸ñÈ­CßZ{_Oû—É·gŸøÐš›¿y˜”nLBv EÊ5ÈÃo²z˶(ÔLÄLë iÔÔ0Ñ øimù+Þ• €†P;ñªé‘v £&¿Ä¿;~‰‚Í,šb Àtƒ°Çµ=üǽ¥±ˆr0Ⱦ“6e‹(MFrËŠ(·— mf%ÔÎÖ¢5l+ÞJzÍm´÷‘{Í{éýhÞG0ï§ûX?î'(‡ÍÇèÐQú${=Ë~ŠFŒö ú›D—Ø;èOìšaKa9,‰,‡šYëA£Z$Š@¥8 ËµSXX:-rÄE’*b!ÎÉvVDEž%šf[¶¶+yˆ lù‰&*S}&ü›DçƒêLLx—'¼‹ù >`¡85Yņ ŒãVu #ëý»ý#¾âgdþFç¦$ª7'¾ º°±èÕ7´º~7Y¸¸¨ê6éiZh*Ru‹Z®x(¦Äz3m5€ƒÍ­fÞ-¢vc•y«û1eÌnk5_ã¯î曂/Ÿ5ï пf|ÅÓÏò3Áßõ4gù9”sZÜo Úâ+QG°Ï|Ä<ªÑïñò‰/Ž,OÃ;µ½P\ ׉a|=v½O¶DufÊå$ô5ðEVN¾5_Y^íKǵªóåØ¿áý÷Á ²ßõή×)61[÷©…›· 9;C~27=írç. ¡å<FñÊÚ_o÷©âf¨8sË›»O6n—g§ŒLõlgo‘gáFg „{[]8m,wR»øÅÁŸÝ`CбÁ.`×q ·p¨‹$¨¤ E%¢HIjúP¤%&¸% ¡*TQBÓ4Tµ±„ÓÒ‡Ô:U)=®¿Ý;- TUûßÎêÛùæ±»3ßoö7¿é ôê½ÁáÀ°>ÜíÞåß¿ÇØ<à?˜(pHÊxÖû=ßËÚéü¿÷þÖøÀŸÖ®™è}³+ª@÷E#.õAõ ª Þ¾=>²Á@n5©ª¬‘¯¤È¡ÐÐõ²€× ‚*“3,óy ŸÏ«²ìs[/@T‹òšè™(Nðæ“*i‘4&xOÒ×Hø`àL€&XëK*+ÁÒˆ×j²ÕJÆäZ¹SºäŒÌeêñbJÚðæñHl”#‰—NÑq‘Ñé°63U¨M ¤¦‹ÂڴͶ³+J¢•Dy8®ä–ÔíõC^O!o&osræ |™+ìv_cd~ýRSÂ[Ò”Pè/;Lä—¹ÕCž†bZ>z…ã6Y×­†¶*Šƒ3Ï7—…òËó|7>sþWñ’¹ñËã7FZJkG×Ôߨô}­²4²EãªLm磻ø–믎µöv[QN%ùž·h])l,éLð‹°P=ùÐד"l E­T:Ÿ|ˆH¯ôÔh –ð.gm¼MZîéÔÖ³Þ#õyº´öDÚìÙËvH{=_f¤§<ר Jå¬JŠ{ÒsÒ/˜hý-§´`='÷JAÈ[Éyã‹<^.y½eŒÓöÇí‹n>”§)z‡üð[!¨ÇÞÍ㊗O0uœ6Ã<÷iÞ@¤Æ«Q,ñKaP’ÊÃÊãÊU%O±ž+µš”ðîcl ¬[‘€°UBUÛQl¹øÊòîf‡6­¥-2×f,ã¦é˜7µ÷èˆø^¾µççBMM¹'Ú;Ž‘5OV±r‰³Yõ$KK*?e©hIiwd©^6`Û^"÷¡Z"ä²+§" TyÀ Î^%ìc—· Á BQÁ-ÇR×ÀÜ󊊃Ll¬+VòonÝNáÑô¹­»7³?$÷‘ϧ?¹×ó Š$Ð-ü™÷åý >„ðNrý±Â±Bþ¾ø¾ÎßßÕùâ:?#žÑù˜8¦ócâ1ë|Ÿ¸Oç×¥ë‘F Þ'õ\–dƒº$Ò ÓA½¦׸âçL6ý0ýl‚u%kô­âcâaQ™¾Ð0¿lRÀ’ Õ+;™¸P29ƒ)‡9ã…áÔwíd€„O“ØStl4³ ÍfÚœ&{Xf œec.hµ‹oO¥R,•Kl€ç5ÔÓÿr»ÅâÛ83ÎŪûç7Õ ìè,s]øésOš]Um¡þµ·)Õ.üŽ¯Ì»h+õËäJ[©«ÒUƒ3‰|RœÔù%ñ’ÎÏŠgu~B<¡óãâqè|¿¸_çÛÄm:ß m0x·ÔSJ•}ŒçuKÙO’)$“ž­ŠZFr˜Œ)ª)“^þÐYö[rùwr.˜ É*cŒm¶Õ¢ýÍœ™²4²¤šÒlN‹ÔÒ(==›ÿ³X7uJ¥H76 7Ô Ñ-V466ÕÝÆ×ž›ïŸßØ ¼3K\%¯ªj/ì¾Åp3Uÿ{°×î_AøSBáMÀ&ô.îÇéW^OáÀ“€ïa@>KÑü@ë"üП‚Ô¯ v'B,Â/Eô¾ÈW€èÛÀœ¯÷Ñós'Øo€âŸ%/¥W€²í@å7³¨ºDÃ~;‹û[š?µôìG_ê Û€…£wÁ‰,ï ±7SX“|h¥¹|ŒŽ”Ké»íŸ–} XNsZAcíP€Î%À*°úÇ@ÏA` Íem9Ð÷:ÐO: М> endobj 314 0 obj << /Filter /FlateDecode /Length 31297 /Length1 43280 >> stream H‰|V pÇ}Ý=³«Ó’`9fiÁÚ²Äa!aXÐî¢Ã€$´å]ì]Ý °"°p–!2•„pT0®r(JÌ,ÆDàTJ©Wp‚"ãØ@¹â$8Á‚8æ(C´ù3:"|dzßôÿýÿï~ÿwwí€HD;Ê–-Ïέ9XÙA£Kk׆[n]Ü»8Ô °ÎÚ ­Ê7N7~l—É×ÐÒ¸öÕ'r¦r:éßj\³±¡ãÍSÏ6ðìÛMõáº_}à§ùÞ¥˜9M44:VbžÞ´¶µ-¿ÿØ=ÒÄU®yª6̲>.žO#½jm¸­Åòºtƒâ›È_y2¼¶þÚ½»‰Àa…øøZžúz+ñ¦ç°ñRZÖÕ·\9ùÛ]À²[íò y2d+2ÄldÑKCè‰~*§`Eÿl@EÎÆŸJÂô1úÏ—D}îá·ÿ+8þ„Ñ;–°”%£B5þ*–ŽÛ8ÇÎÒøeäã즌KØT‘}Vc'~†—ñ*z™`v,@)jÑ‚ Øyã£ø¾M,’¤KÄ‹C¥Ø¸i• e·Oâ<ÞÆ‡¸†OqwXÇæ`ó™‡}`gØYöþ¾˜*ˆâ-É.åJÕÒ›òršO¡–‹…ð¢ðcV¢2l&þûÌ ^ÄAEŽáñ;KíÞÃG¸Ž›¸C« fa l,SÙ\¶­d!f¬‰­bëØÓlµÃìÍ‘‘®Nµ+S&Ošh›0>mÜØÔ1£G¥$'=˜cµÈ’à .¯ê )º#¤Kµ¨(ËÐÕ0 „G „t…†|÷ûèJÈtSî÷t“gÃç<ÝžîaO–¬Ìü,—âUýœGUºÙŠòÉ;=jPѯ›òS–¦’HŠÝNŠ7­É£è,¤xu߆&ÍòÐ|‘ø¸Bµ°>.Ë…H\<‰ñ$é>µ%Â|ó™)pŸ7?“H¬ôÕãÕ‹UAAÞp^Vðzlv{0Ë¥³ÂZµF‡ºHOrš.(4—Ñ-…ºÕ\FYe¤ƒ%âêÑ:»“Qr&Ô©u᪀.ÂAc§¾Xõ苟ù[Z–«›ý¸2 Çv3TN¡$Ú)n÷x‚Æj£ ÛGºÛ„æM[¥ª¦mWôË#­vã Ò¤Y®ÒŠ€X«ÞNÅH£"`f@“²´l"iŒi$\¯z‘ÐjEU©MÚêmÖMGÅFûñ %îSÑ?£Ä«h•Õ®/°©Á°gbd ´Š¯»•âû-Y®HrÊ@¥#$ ‰#…úa›)™î†D¬‡JÍ Fj1]©UˆI@ÕyFžñªÏƒV›GnôUtÕ/¤%ç!g$«ŠvtÔë×î ŽX2’oÃã2|äÈ>$ëN§ž™iœk!m-1›oê³³\ôRµ%YÑK©d( PP0?›Jn·»ÜÑíF )z{y`@WPc;w¶3¨óa鲤ú Kûe8<¤Òq>ãó&Uq ÿ’’ÇŽö6åëlìÿ1רéúx•ˆ$gheGXë°9BZg¶ÆGWQÓ|ªâÓBZ¸;Ú^£*ɪ)-ÕZ¼¡¡”º£§;lº¯3¨'‡šÕUŸ9PÒåjiùŠ€âÕBCWbta@Øø Äm"8ì•gzL-Wî]¡o¥Hoÿ{±“ûÈOˆÝ–á‰A¤b³Ô ]öÃ/zPnéÂBK3ª¹ü‚‰4чEdÿ6ùVó.,ŒYOþs…³¨ŸF˜DÈ!,$¸iþ èwÈ>GNÅ4«Zz`µÐ?5ù=dôò”K©hÛ£ý–T¤ËþèU«3Ú/·#Žæ¿Hëeñ>|FœÛ¨Ï”º°WBôå²Q\@gÏeÔ/¥¾ˆÓZ’¹¤;¨“‰»Krc õVZ;“ƧKN”JÍÑ{$/ã=H§|VðvÌ5çêŠÞ»¢7é#v´è‰~bÖÉC’Ÿ]¢~%ñÑ̼r¯6rÊÉàopúRGƒßH?û IÃÜ>f“÷ÿL&.Ƈ镴×K(oFH§sR` Ñ{T§>‚ר7«?ú’Yó.äg‚°ÝÕYtaÍã—OÀiÙƒ’Qw'Åÿ—órâºÂø¹wfwfýÚ]Ûk¦mð弘Û]øf4á½`)÷§Ü¥*¶;ÏI ßÿ~ð&lSæ«ÃØÛa¬“è1öc´Y‰öët“L{ÌsJíÓ°÷( ö*½'©€çÀNpŒ‚uà[©rÓET(‡“¿bŸe¿aÿdaÿà€}šm{b ìãìg);[ð±P æ"V£ TÃ&‹9fØoyžS}ÿØoÒÊ>Î1ìø¿\ˆ~ñzÙ¿Òmynð‰é8eÿûššÓL娿øJ+æüŒ4“7xîlËZêæ5 Ãg‘ d±Í1Š˜T5q^àØœ®ðGM;f5Ž‹‡Ô¤{e¢ßMv>AœÌTÎ-ß35mß);#÷pü³Â·¥ŸÙ78Þþ[µórGzÿÓ¾‘VÎMéýáXäxJÍu9öõ²<™ü«>9Á9×ýZrB;—œP>JN¸-°\NNˆëɯ§ó®ú>=êÚcǼÜÛÝιuÉ›éœëz™¾dû=ïüÒ…_’¼N×B"­–žå|«©”å¾@«íö(WîS³Ò½óÒlqz•CTo—ý•ïRö/ÄõÊ2Ä$ÞQÞ¦°ýÞh–rœJÔ/"G·R®²‚ÂjòØ ªcU*(¬üù°~vu¢®±RGK°ï!¬ñv9¿ å2;ÏZØŸ‹X3|ÚÞ»tlï´’7õƒXÿy¬éMÛοæµN;£–q[w†c/ýi"õÕÙ6ã÷œ6޽Rvœ²çy¶úÔòh7ÛÊnóWÊòžâ0˜‹÷žÑI¼ÄÀg}ÈíwÁn—Ig@-a»GP¾&}v"ϼ#¿Í§Z1N¦4âùEãÉ„,Ž{2AºfcrV¼+h4¤WfÑf|AåBWBý)ÍIivJ=¦çÀfãZ÷ny팸EwÄ­JêöuK:‹G2…» c—ÑgŒ‰ éUŒ6#btƒªw—·ÏËeÅÛæx»¼ƒê€{@“ïíµÖY1_Ä>¾Šùff¤ÔØÚVjì,ÀL³¢ï³FíñѸ¬·Æ;ãÊÀú¹ÆbŸ—Ƹ ñĸô6|Aܦ ¨&ƒÃ 4û) º§•Ž€„]K¸ú€DëI´žÄû“ø±4‰úIrM•ޤJUŒ4i—ÂâÖéR,¡¡ &H€ pͱšRÊ8AP L»4,]øbp¡ùU\“öOºâ³û Fq+Ÿ¤Cb$`{©¢¡JÝà0ˆàFS•Rï%À¸&Õ¸ÛCgq+ìNî €;-—<–D– LQH€ û-.•T Ð :"I$OgµÁ¿HbQIêï€ÀUð H]$Íy}ÙFmõóJøJôŠ>(Þ=ð‹òÀ†bcCg±ØŠņ&†Ô‰¡ä¬j(÷hÄÀPé \à  û{XO½R+è ¼ªª­Æ¨}5.úº¶m 6ÜõA—¬êªïz§KÙÓYi¬ÏWÖ‹oGÆt2±_¬_îŸè—c2?>8Þ–g~np¾Ñ©1vÁÈ<£ÖˆˆªÈHDV¹«4IK—"€sýºÙýñ–>Gv;²Ë‘Žìpä9GºÙäH‰#³)4·B ®«àgà§à'àÇà<àwßß#à50 ŽWÀÐzAØ ºÁvÀý·Ùct†üŠ#/8²ß‘^Gzévd»#ÛÙâHÔ‘GòÉs$׿#™f-ôxœ§€FÁ÷Áëà›à%pìiYíÉöÄΉDhL4Ù×:óóZì¸Û¢Å6i±¨Û¨ÅÖjŸÑËõ ^ªÏÖ‹õ"½@Ï×suŸž£g麮»uU—:!™ZyJH†V5†¬D…6­{«*ÆDÆ—×Y®ŠFaå†(´ºÑZ\‚¬´j+C–'¼¾ý”Ç;PjÉWÆ­ndžqÑ‘+wIû82ÖÂ#ÇJX·9ÖÑA•ÿM݉PøœèbóiÍøšVYZ…Ç?Æø±HÄÃ4zöhtý‹~ü‰[;õVóöU²ý”NK"Žž–™˜z´¤¬£±À×ý´½Ž§ÊŠ•œA²x‹2+;¬¬ŠF+pÕ¼†y \…ㆫrPìMUzª¬äŒx+UåC±¦¤ÑÓ[yÊŒ4G­Áæ£Ö`E“3ŸÞ}陡žŸí²ÞžÞŸæ2Jsý~·:{N^~¾"ŠgRóùöúÝù(Wòó÷d>Ê„êÒ=™Æì⌒Q/2É@A^®7';«tάŒ¢ÑœÂBéóç4·"}nMñùƒþj¿â÷2rÆÄyÓ_˜/%(1 Ã…²°°,èÏ}²jC]MUaïu~ÜÖPU]]Ý?™®ÖØ(®+|ï™]ïÎÎîìcvï®÷1xÆïÙÙ‡7k¼Þñ ³À1ØÁÁë˜:"`!ŠDy™Gl§E„¢ (J ¨8<”FB-j¥¶y¨%mÚò#¶Q9¡Š„ª]zfLªjöÞ;{çJsÎùÎ÷3ú€Gíó¾¬qÖÃLKã^þö῱ðpâómXŒù¶wGÝIJIA¤¢B”ÝúÓIw=†ƒXš³k§?ü¼€£•Ÿ¯¬l˜Yó០•»øjϨ?áã•ú˜®¼=]Ù_ÓÇ4­ü€ç¯Wäc¦ùP¯æ¶26!v!ÞAíX~ÿPóT#OÄ÷ô{häÑ<ÄãYä×½™,ÎÏ;³Y¾ˆ¹²Y5Ž‹Øë3™í˜—¯ý„H:åBäD¸ú™úå½qÕŸª7V¾:ýìgZbnÇ»•ò³•¯wŸ¨®Žc ?ÿë¿à!…ü`áXBK5ŽG 9”C@ƒ¼n[È:Ž„ˆ(M. z¿0#Ükòb±\.yßéîÀ¯nœWð؉Yî ®tJ’Ë_UÍm)ž)Gÿ>Ø6ðRA ‹&Wë¡(ý»Àç—O}3ròûÇþ㯙֧.ÍaúâѣGb`éš ?¡ßC,Êj9†‰=o1§ªNËyÄFØ8{™½Ï2ˆåYý„¥Yáƒör{ )Æ¢ƒîL:l§èŒNá;gð*õg*MäsüûJÙJ þ­“beÿ»!&š,_mâ÷ð’»0ïr߀6OàáÜ`„‹s×ÏÑ3æ¸pÍj¥by)å"€·ŽÖLk:%·R­É„l6™MbL#ÖPV–m܋ҚÞþõ¹.n”ã¾Ê«ªÁTJ ò¼–nήžÞš;8¶&L^ݾ>ÜC¶BWäF±9“çÑ ü¯k6øìeióMœFvx” <¢™„φW†0#¥S`‹ü$^r.¤(Lãò—˜`L¡Ÿ3es¹pȱ(Ì›ðžï>úŸÅä@1M@Óf–z9b[5ëYëe+cµ:ùÒ¡ü<$§î™á•þŽL+¶äŸÄ{´£Ù…ýÉîhv _­®átvWþI}ü º¥hÞ ‡‚0|6GôFí&¾Ž(eRKôt^Þ ÄÅI,Rýʵ˜7ë˜}t:È4‚^%Ñ:-0ÌnfwÇŽØÞ²1Íû,‘}‚…8ikXÆ2tñW9ukPïæýˆS8ÂÝ™AçÐt }Šî#ÓY0MÙYœ/–K|¹¨3ŸçÁ;Ttë^é`„.ð@´c1ÖBd©ÖSƒ“ ýYZN§Zˆ³cÁçÍr5Á¦=«Zž,^9&ù‡C‰—k·íܼƵSÁÕMÍZ³ÅA•ΚÚ! ü=úBljî‰QÏÁÊg_^üÞðÉÚָ㽧&ù»§WÆ7mÕ¡7žûñŠPág÷ú6éL!3ù7S‡úѽ›h~¨u ¤·¯°‚FA÷ú†õ¢)†¢𸆥á a‚6Ÿ[ YeBö¶î|oFͶ'¥†8¥Ôå3Z{§ÿ u£$Ì*ê†YA&˜í(cÜ ØìвªðoÜ×a¿Ö„^‰(qESv(û•åŠò©ò…r_±é[ý°q_aô3ý ¥(;¥öÛëA;ßîtÒýø—ÕÿZ—@TòÙ<ß΃ Â6dš‘e™06Í}”àñú¼ºÐ˜Å˜,‰1³©Ëf9f^ÈÁœ–3 NôËÀ^ËÆ=°Ï,É­Fšžfò‘<”M 9˜ó/#¤±imÒí?åd]¡@Â&¤.]ˆU I)ø¼Á}ë­ýË)_3(â`ªíœϖ‹Ùšj ÅY-l-„_'åµ±^–u„ü=Ëß’«RëÉvÚŽE=aAŒ©é´IŒû3ÕM]!@UFuŠYŒ4ô­‘S¬*!nâ!K’Ù”3a±3< ¦Ô¶¶@Ö2ÅØ˜²8{Û¢N% žãm¼)í®f—“ µ-¡r ª/G†¯çx^tø°O'BCCºÛuZ$ºåpîN\ÔÄ~qLÜ!îgÄsâñ–håE,„xP†º;_t&~Þ@˧×/?(a'_ÒÕ€oׇŽëcLºU¬52/€$Êf1 t|R-À!Ñ€ÌG³¡¾Œ/øä ¦&&j…¨¹Çå£ýRÕÆ·µãÓ‡Fz·iþÚªµâÅß]ù•;°òÒÞŸn¿¶emÆÇp]cå7J‡Œž¹é ;纖¿Ô£©}+C†ýòd{zÙ–K{ß%4YÜÍGhºÊÌÇ_BJÔ~À!^Ó¬Õ^̲Nh¶ n¯GR8•r†¥°€š‘;5³y_ØÉ„9ŸŠk£ÅLØ!~ßãùHŪ®6¬˜ s[Øôiìvñ¬Hx8øN–'‹åIˆï¤S'ÀcÙáK úšT’°õßÈZ¨§Fù± “ùqYу¼PdtZè’dÅ«kÜ×ru#K^y./unxõøwö Sï<[¹yu´½­YÒ2Áê!½«gO_ŠŒIÞCkÒÚè‰ØæÍµÁWÇWM~üʦ/NåëZ¥'ê–.¶º—]ܾ種¼*(ï,hÐR4Žh뺓YoýlœÝÞYYÿÌ𺧇×®aÿÿ~`tôYõȲZß ¦[Ö­¯JŽŽw‰’LõD˜E1 í<Ç nÎM ]h|*¨Ÿm˜ƒE³Dz¦PdŠš‚¢çÔVa,$AÝŸH·¶esyªSƒÖ³‹¶šÕÕÿe»lcÚ¸Ï~ÿ{5ç—³}w>ÛØø ÎØÆÆ/Àu ¡ …BÔ¨U’-dŠH"U i I» Vmi;µM÷i목(MhÖHm4ÑnU¢4­¢IûÒHYšOcɤ$_2`Ïß6Q*Í/œÏw‡uÿçy~Ïï¡LCÛúlÏ—r¤q|×F ú!ªÁÏó.F¹L¦+—C…Žm¨O›êz~ªï2ºwQîêB|øÄ¤LÉàDëRpªaÊ/ãˆzL7M$xÛŸ\õßô?ðS~u…ùáÃÕ @Ú#(óC ·~BØàeyúVÊu„ìË>ݯ0°¢Pêjùòµ‡«wËUÔ‰1øÌYxƒ{! v‹ aÏd.¬¬`·-0…¤‰ ]8ÄÊ §'¹ß§"— ¥2ì&'Cx¦3U9Ái‚çTñ†K(ÉDçY+>_Èbâb÷äÒI%©P¿J{êš(hH¢±VYoᨡød÷èþz^ðÀש¿ß¶Ëê’=5yALÁaŠTâåOÙÍë°œ†Hdª ÅwÍÎ~‡[ß{ÝýEÙ™‚3Äi/ý—W\†HcÑÑíÑÞ£3uMµ!3E¶ÖF"û¢m©ÒsƒPÇ ŸÑ ôüiìŠ>^Z”œ±£i¸ªº òõ0ã#vÂ\)•>”a ‘-¶ –jœ—í]=%ª êOóÛiG·ùûüOñ—‘KÆéq$ÐíÂýÂF*\F³Ëƒvd·#õ2’5Wël1a#EÔ[²]²8\*Åz{bÃÃ##àŒ;–  XÓ@ êQýc56[Œ-ÅèΡU<׬fÕJ®TRwÄJ;\{X><1 é;1p&mæNuìèƒî•ÃE\µ)Êê@U(ThÊ=Ê ¢åò!1UN޲/b2É{®®Q4ŽsNÍì}1¨·^D'“ý épÐIê4=wþ'ó»ÒÍ¥¾¨ÍÍ..ìKÅTÔ xÎ@—ã íÒ²p/ãaêúÊ+‘Ð&¡æ ?Ý#˹ÖpOÜ>Îl›}ÇÝè 壻2±ø‹öoX¿‹ÑqÔ.{çë¢.I4²…g(ƒ ×N¹³’l3Ö½¿<¼þŸSç>Ôò¶Ú–Ÿõ^:ƒ}q ¬ÐQ†#:‰šÍÈ z‡Ùm—#Ö¨%ƹ\Ž€Aî6¥5T)P)Fg ‰dBm©WÚ0¥Ñ,I{ŒK’¦ÛÀ64‘Hz“ñ¤–¼¼ŸÜHrB%q™ˆMøIÚoTn—Πr| é¯ÙóD> ø½ü¿Èß„âñd~)OæqZã„7¯V¥RÖû.¸ØF`Y q%l³ϚMÚËMQLd@ð”³é8‰áËŒÕ0Ä9'–i‡=Äg"+“JÚ}ôõLÄè "uªÁe¶È-ÿµÔö³9‹ÑImý7ÍŒé¥ößÌ´…͘ó \ ƒõ´"`¯ûñÀÞÞÖHþlÃîïl³Ge +÷ ú%úvÆ Iz†dIŒïKLÂ̳bq8ÔHäˆ^`QÜáGÿˆ—µ“½gÐéØŸK_•þa~ÔÆ³ÙbŽD–‘ï-•P.Ì–lÎb¹LRÚK%$Á—'ЉÉ—P)O !–ãºS³ºîY·ŽA+–h9äɨ™ÎÌ`†Î\ (O'ê¼j¹ ×{‹ñ¢V¤ŠY•çd꼌äÇñÚZ -…¾ ±!'>8­ 62‘ÄúW‰¶0•é‰ùr,æMÐ}V`c^)¬ ææf(†é ЕfHï²R‚¬w£§1” U*$“¶*™M±ÁaS,[ÔH+"9v84ùÖ‹ïýu´©ïpZgÕÉÝ…¾±þt0—°ÚG[ÿ>'…ÛþÁÁCévsK÷«;öL•®‘GÚ?Þ’_˜*]<Õõº=ÆäG ÃÚ^Õ5%7ú«ÑíŽwwoCl¶ 8r ¿u¬qýû¶mÓ'Ïܽõà,®œŽ;Ôk`9]ÄAÍͦߎˆˆæ;í™D4q6ÍhF’T€"`ªdÍÁÖj Ń,e?¿5—XL¼ŸXJ\MÜL° Èù*Q*@©¨´º†ç41¡Tgª²0U’KJUí:Q(Ϭ"f¼ÕËKù}—Ì<ÓºÿÜ+Q騵¨5µt.«9r8ƒäÖúUÃ%×.ˆSW¦>[K_¿Ókt‰V ÏIáéß]I[‹ÉÞÉRûÈo'G2ÍîQG)¶ ÞNû,ÛÛ¶öÏ\{eý»õÏ¿üæÃ!ì‚Ç6¨}„™ð}ZJ6Ê&Y5ŽšF–_PiDs–§ž•¯£^wÜ­¹)ÂmvãGÜŒÛÝàÇ+…¿v—è\휀q8*–o«‚ÓòŠ•:/'n`™ô1__432\ÒÑÞáZè‹;Ž 3•~!Ô(’ߺúbcí=ÛHWÔ¾>–u'SRØ&Œš:jõÛ3Ä úý.Áã´o–=@ ‚N24}€"%0ð–e±Ì²— Xš"PÏ­Ë ^heêDá_ð¡Ö:V³À0hÅÍöèü«+ÕMK<€Z‘\ƒèO>¥·üwš>®ý]ûãúÛëoºACô ê  Gø4‘úˆ ?âHö ì{9òkq°&…5ø…U–D¬—ë-ð>CoÁÿïɧÔï®ùñƒ{Ù¡þÿ½°ˆXfHîÐõ?¾Ë-¸‰ëã眽¯di%­$¯K¶.^KHZ[²- „,Û ÆÀ8Â[I–!áVl| „P¨1:¸´ô$mÚ’Îô’’¶0¡4¶<0m‡)t¦™Ì0mòàB'­g’ Cûìž]›¶O•¥µv%Íîÿ;ß÷û(„/$Ç“€&ш£Y©¸õ«ùã€NØÁAã׉©O¿B~g©ãüRǸîÃ*X~j?½@…ÁÜmÊD™%V²ž1}ÁL›Ò°=Nç[ãªÒ¯ªQ–?©²¦F“(ŽGU1UYšžŒ«b<®Ò¦|¿Jñ}b4ž#•ƵÍAŒÌal_´€Öȶ¶öU'•YåšrK!°DŽå£_Š"Qjh^UúÙz“zN}Uý»JòjXUÕ’z@¥X“JŠqH·ÆÛ×fsyõ™/Bh­ß®×³F0 ®[8Ç@H™2JÏzìyÃ÷° VVp}Jg¶®…ƒçÓ Üñ§´®'•E·G ß=üº†2&“¶Ud¨È$ë¡kt;üž“q»6¢Z_wÈB²ˆA,ÁÇ ñì—Íf~Mn³æÝ³)Й|f÷+ß•ìkÒ'&SÓWÆ.†¡½¥óÒ·¾þpæíšîÔôW{ñóç»jõVµ•¦8›Û™‡?îîMvš4!È÷S&½¬Õ²‰Á]Éõ;CbÌwc¢§Ð[Ÿy’Gè#zâìè¬É½æÙo¹žì¨ßp¼2ºvk’;vá€ý¨²ü ¦â ^ÊõJüýšü¦LòüMë»"¬[òоs¤îE¤{>¶«¾ñžú8@¹½$IJæ9Aš”nIÄ5 Jóðöõ?†`èø àq-`6Á‹R'’J—°:‡)cL«««õ…â7îmûOxêsÑ)é5‡ ê@SÜEÞ­i±ÃÒèf^«žt’áüðóïŽ3$GˆœeýŸ¿wìþ–éS]p¶¿OÏ—s…³GŽ~éþ•Âa5Õ;ËÀæ0áQ%/¼ñÛc0 _–ôtŒc_\ Â  €›¹œäöhMšzC¢‚RŸ„B-¹c³€J wÉ¥ ÑS•µÈæªðÓz"¡ý+#ìúºŽT†È¦Yž3é*wšÀå¢Ýn:=œ\7œåùd¶ÌéG„dÙl¦ sŠzñÝ|—Ö¾ExüdzJ§ŒÅG‹X¼XÜ XØx/“ÖÛäÓ*‰oæB×â¢.ñ4~2JÞ0 U?µCNÉU(Á›N×MF“´;E„•¬@Fft93>¦“¸›ÁRvëŠÆµ'‹:ÚþhªTì8Z!$¡…i¬óEüt \wðÿËÞoï:}úÚýînf[íÐ=ÚØÞ( øW¨(¡žzNÙõBæä_Û3L²B½­Õ ƒÏÀg[ê,¸bÑ ;ìIØ»ôñëw–Þß‘å„dpýt‘½5W.:«—w͵õ9šg»ÁI¬ÙÀò25B9Á Ü’3í)íÆƒ”7Ww6Ý„A=|ø¶·Jš€Úçá¹\³¦½é‰ô‰4™¾Ð bBl46#cäã%N#‡îU€FöÎÇ9‹\íî&+Únm'K¢Ò<,æøíE›U2YRb7w+è‡pˆâý6†;r ©¦BopÃÔÁ±&?;ý"‡v[,)«Z­ÅTÛM|v;žµ¤&S(•*vÏLŒÂã¿>sxº »Þ†±±ñ Þy{CyrrÜ_žÆûo?×ÕpBxlÈ@x‚}ÎЂîwÝÕ*Œ—§]Wo·+醡¯±CƘÔpöá³°].è‡ð£¢?piÀ_½r¦"èܲZyzQk€nÑ }º#®Z£A·n§áuÉÎ.#üôÐýÿ{†øTC† ±“ÒV C|ÔÏtt®Â2§œ”ÛåÕÊ¡txp_àâû?¿±þˆÁ[ÇY[Ü!I敟%d¿þjÀÂÕÕ¬% ºŸ4‰‚ùqö•ÍDõ¡?ÛÙ›ÈG½¢É… *hïnN}òæÇ/] u¤÷µ˜ôªGAñ¢É‘îpH”“ M4‡¬¢ï^ˆ6#$ÊýQ…Á"gIé'oÌÉëú<„ZlÆV¤Á%Ä+n;ǰuì‘Á÷š-N§µ½÷(%›çWÓÏðäŠ6‹ [È N½>uœ²š0–š$°b3ËËäUªu¹V»«&˜ b²šÎg¶Gˆò­äxn_ •@¬ê²y‡ÐÐårAy!ò—3º8cÙj¹ìš² OÊ„¼Ø¨94šÐ€6ͪAÿ¦íEbk>‘Ù?NíÔ ¦5Éñ$eª!ÍzòÚí‡Í¡ ß°ÕïõŸð_õ“þ3]¾±Mœw¿çþßÙç³}ç;Û‰íıãüwbÇ6Nm  4Ä [r‡DP(BiYM!JIBh€-QÄ:¢FQµl…±Q„D«®Z骽Xµ UÛ‹7Ѧ½`Ú‹¬š*öUŠ-b¨ÏG¯ 0Þ>€žðTŸñn•?…+‡¢‡Ü,öËÕΙ“ÿ*LJ-rÝoÌ!‹tÀ&›i[Ýæs絨É!ÃÑÛOÖìN NE)ÊTIJK2±>Τ–5¯[ ØL¹Ñ_F’ï’óëD¤—ÙÒEÉ‚¹¦ŽþçþË+ ×b!Ít'e†v4 ¼ÞO½VŠ£Cƒ$„•Ucov¢ƒ<ÃY[†!ŋѠŸç$-z'S—X¸[2›q‚§ÝQ€4‡&½OÿMݦ±AìƒL?èêsÚ¯Ù(¨¤×/Çs-þ\]‹^§75ÉÔ…áÝòpÇn¢ƒ‹GZSÞ@ Q^ÍŒDy&“«}Õxu¡<ßzìÏØRÖ9kê·)üQ ¤¾ý¦ô °×`Ø?†EÛ GCCKÐ7Ï10¢åÒMIMżF»z&Ü&ÛŸÉÃhT†b­ÆU¢ãÖÂ2f1jÚH£"ã´—@žQ( cg꽯øÚrÛ?ZùjvKwPµR° ~ÝÃàðð±lyå϶™€±õS, H¾|ýo_œû}çÞÙʦ—#Ÿë¢Üxê!ù…ç!QLÁ»)äY¸þ— ëß¿ocÖŠ¶£‡C"Ç;aÛ¦-.šEñE¸í& ï¥Xÿ¡ê>È•o¯¯Û´843}uþØ­ÃT;¼;Œ£?€Íûwà'™€õhò5X^¸~>’kx-7Ûs%wñ&2Âtnö§KÎ\åõû0Ü–°Ðr×°¸4¹ôh‰x´––>o€%¥IÂtHߣã³úEýcN¸À=ÐBpqQ^+NX††°0Ê,ÃHpÍŸDZšÕR;n­¥ ½ƒË‰ôP…VéE#À•CõD6þ­áCFuŘec­ð”C5>¯ZUå˜ÊN7-P.žtYl•8±C¹E¢aªº¶-¼ëÚŽÎW»#ÍO;%Æéßµ9ÞR.q›w‚1¯½&ø×{[wH” ž: ˜ R5 e<`ÔþºáÝg:Òó÷ÿîmìNØë„,Ç1šº óg|–ùÏ'mKbm˜ŽåÈ©©·æþ’L§_ÐåýÃÅ¥e9™Þ²u@™{×Ôó£ÎZ'Ñ—ËbGˆ«¹å¬Þ­÷u—îÓéǯëËúbîų‹ì±#G³â€wvŒLÍr}?î ëwu\¯ †Þ}˜¿|e.šŒ',ìœIäe§‹d–EÆNb! χÙìѾåe«˜ó… XáBž‰jq†1ŵ„I»œOä)Š»Àå®G]8¼nd”¾>q<=>:~cüÖ8uyüÑ8~cŒßfþÏtÙÇ6qÞqüž{?¿œïüv>¿¿‡Ä& 1BRî(Iì,%¤%!¹Å"!€ó¸Ô„@Q¼Ñ˜JëiZ%ªIõF·?ئ14ZþͲJ ­Í¤¬ÒX5þ LÝŠ¦i´Ú¤‘îyî’¬gûñé¹ßé$ûûý}¾?îã‰Là¡ 0q|€‘P$?Ù·˜úb1SM1™ô S Ð™põ1ÊÏÖ)µ&(q-çBÇæÑ*µäW£ GËËkïGÂS©}ôꔘškHœæ< ~©uHóy ~ôÔ Å¸ffH¦Z]™ÈßH‡îÔê¶fñpêç.èñ´±¶Ákë¶Õr¤R.zRÆÑºÞ Ä™ÚÕž€0h<ÝOèÀƒ2ÿ‹¢¨>}xÓ‚(ûn«Ù×(3¢ýù×^>Ü]´X‚P^b­8JNÙÓÛ#ÖrÁî ¹q üÿléâæÓ}}Å+A‡/ÂY—®a/a¸°ØŽ“Çõ#®ï8‡šV È䦨›àÜì…’8Nú³õQoôú¯üä/Í}í[Ü–º‹Ž­ž¥7“mÁ¤Y”ÆS>—Ŷ·S€"€Éä%'kñôñVɶå¹,Åí<ײÎmç3¬BÂÊ‘4µ—4Åëw^¸Q“í‹?Ç­v7IsdÈn²È°iÁÉ@0Y<6í¶r´ä简À†MJ’;34*;Ì.§‰õn GDèÈZŒ¤lTÇþ­ÆNöŸïÿ^ÿÕþwû©ÎN,Kuf÷‘½¬ëÈà:˜t3(áµv8ØûQ.®µ>¦å´ƒì‰Áò`e°:x}êÌ}ÙÍõ)å`»™·pëñ“ 6v„ðvïBm±ãàÊ`ípU0®<¦€G7ÒÞ¿ „éúRê}¸†Ý“kÍñ½Çû %‘i6ÎF›'OŒÔ¶þÒ•‹fA±eMúHíÆ,hðI@óŸ}^ö`€j'H ‚rVÀV”¹VåiÄÿmÒ×ú+Ì\pÁQ`ÒÕ§Ç.Âza%ÚDy ƨø í6„ЦZ+Ó'cMQÙãaV2yÞ|c¼c2LÙhÖLÇ_¦,¤Ñ q7Òt Uùa®ÃMøÂž a$ºf w̹ríß:b£­¸Æ‰ÀâÊßÞ7rôÁ_p ¸ÕDr/Êœ#Xs@²0TF,ʯØÍT³Õ*ÄÛ6mÙ-o\‰9¨Ü¿?Øù<”ï¬@Xh‚f¶ª¤ØZJÆ^Á¿©~\Ž*|KUOU®z«¾ª¿¨«¡j¸1W£Wcw¤;ž;òï‚oÁÏzÇ¥EÏ¢¼è]ò-ùS=™0ÓÇäCðŽ×*RÅS‘ÿäe*ÞŠ¯â¯*ÁJ¨®DØÅÃKG–Ž.þ0¾8±8ù—)önéÞ©§ïž^:´4FÏû ¡…ðBä^‘¾tlÞ9ïž—æ=ÀçÎûXUR=ªÜá½~5J—¥²§,—½e_Ù_”ƒåP9\Ž”£å˜•›²Þúê²:›š Çø© F#áP0à÷ye$ÅÚJêäÀÔ¬šÍNåF¹Ü¨<35õy þm1yæìÌÔÙç¤(î×3fðØÌ¨œ¤šÎwkÚ¬†°½Ú~í…IÈž²ö2NÓγm?äHkM¸C“ð»105K’£3” xw)k ड़zìDzØ(xt3›ûEänÏT…Í ³ŸÎ³¥³ Dñ%îþ ˜Aiã¬n©³àoª R½Ôj‘"P Û =ò:- £ä…'ùÇŒ3DÃ$ 0È!_Á8‡ü¥_šã,BY0ÇŸ[€ž Ð}=Þ;¨š“£““?‹%á/’\/Ò€ºÌ#,Ï¡Jt´éf`)±k@0Ѽ~`ù¢>žlóÈÝ}Ï€tŠ2P·Ä z8 ÇÒ)Ãlº+ÝmXã@#E"ÐÌÿyA `0Æk=½Z3pÂ'¸`Lª#ÎEÝ« œð xM3¨1ÙD±æó(³-xëÆø³Eû>’ó™\[º ³¬‰‡ét¸µN$¬„ Žkøîøî%»ˆ×µ7yaÈ ò?œ]b÷YaOÚ³#êàH À¿?Ä2-ÃM;^=&1íBÌ3ñs9é¢IY &È.g¤ë²oåçiîž 'Ûsx6Ý„–†‰×Œól³ó~gжòQýÊ¥¾o œ‡O ¬Ë%YpÐ!˜Ùø@D.Ü»OœñÍö÷FäàJÛ™LÒÎÉ4 výf¥vå÷Ïí’,]À†xÀ|õ~…’°¸¨–|‚0úÕS*å´]Qê»QO26êYj7ÝNuÐtZlÉtŠûE2ÓÞ•Ñ2DH:…Ì—â3Ô}ßãÄß3DA|ëä;"á$±M$xëÄ2„˜ŠÊ‹ßèîQEžÿ<£:3µ_V4õØû«ýÃÐ9ü Aãı!P£Akj|¯186ýÆôÛÓD¼Ô*Éý¥ž‘RA†è¸É…DÐ"Þ‚F¨Q%¬t(û•+·”?*Œª\Pn*Rù¤€•ŽsBhéA•–ミÀ'à.€¢Ì)áKhšå§Ãùa(󣽃ïÁÁëѲïÝL¦Ðƒ¢–†z1¿v±I¿ØÔ$*ÆEtã:™ ½ž,+“ftÏ=óC·7kÐ4‰¹s @S r¤¦›¢X/æóŽÚ”ŸT3ú °µ¶‡<1(¥é”´ªkH( 9ô.L#Uî€&»ÈÈLKh&X\sÍŽ5ì™Éþ@›dÙaå¸IÆì|k%¡´i °ºº¡A½¿ýÔí’G5¥H‡‘jyrú_×Î9t•ƒsÁâ4W{žÉÚðµ·Ç)‹ ~;é á({ð´KxÉ;õÑ ¼vïéä—Oÿí²mâ¼ãø=ÏÝùüzwöíœ;ñ[ü’Äv|‰;9Ç6y#‰Á ‰ãC:B;JHŒòR…¶ŒmméÖí ¦µšJÛµ”ÚµllZ×–N{Ñ:‰UUÊ4•ì¥cÕþÁìyì õéN¶ï|þÇ¿ïïûý|_Øp\̲†í!U*Õ«8•C¥—T^SîéI»»ú÷pg<¨î¢þç¹G–¾Sý–Û;t|b»Í,² ¤ÇÕ”Õ¨“h(%Îx`àÝíV£×¤#HÌÞ½Mÿ›ŽvT;&3ÉYóNç³â3sâó _Q¿Ô\3hgá¬ôQŠl¬0d¤Âi¢½‹½P>ÉëÁ=Ð_vŸümÉep‹èá¿Ø·†4°†æ»Ö·†I‚( ‰4)Ç(4žp¹kÿg'€1ózË­ CŽag³QÏÑ·®ºb3KÕcÕ§FºCcš=†¥f3|qúqw2Ê@”è­&gs)ùàå½:šd|Âï>2û½eùôc¯¼Uý´ú NÍJTze"|0¿;Þ±åê[}zLjû˜SŽÙZw~þóÂIAízþe¼ëQ‚ Î£6¶…x/3½¥,ÞÒ-JƮԆŽRÂ]QŸ’ÎJ¯IW¤ëÒÇÒ?$†€tÕhL©‹ HÂD1]L©û¦ SPìè"eo{”´´üCéÜ9š€°XÚo@ÁÝf´˜û ÙKà³óÄòhZÕŒÁ?7::”‘—Ãs™å!¼w“ˆîî¬âB´¶ºVFÜfD GŽÜk55È«SÝÍUôÜÚÒ>Ìv±:óY“<„à·&ä:²9¡YD¥³þ¿õl©ƒ€6/ B·õêP¿–¢–D83ºt >¿ð÷Ý~eeD8š™ß¿åO?J=¦üÜT*¿!œ)Œ6«)¬jU¿ hÉÐôòC‡÷ A *}a´ ¤Ž¡w` õ›104+ÎüpðÇlltÈF”“óG,N‹A_ B¬}âøiW·ÔÀrvŠãIè`5‚(Ø ZCS7€ò‰ÉábX¬åq‚¤_¥›‰íÈ«‡3ïZ<€oöB]Дå dΛóåZrþ\€6yM>S‹Éo A1$¶ª}-þå o)9QQrÞûÁÜð=8.@¾dÙS±ÁÒ_²ÝWÑðƒ 98h›–‹J±[mAÄoƒsʼnâ´zбN2ê Ê•[˜(,ŽîÛ¿4¼wÇØˆÆÀiIµH2¦2!TÆdmeÇÈÞ}3ûç †íÂIÎõ”ëŒëmÕäÚì‚.WT[X™ÓF«•eíºßÆÌ޵€v¬.‰ÞzÏŶÉzµÅ¨_¿JÖ¯¬_t⟠?^ã×£,׉·Önq XÂÕwD½ Ô:-ÚÍH6,2*«HNLÍ`ë^Š„ãaüž.¨Ìÿ ëÈl­='2-tºQmhHZ»ø:à໨¼ª˜IÛB•T@ATV{ÆíŠ…¬ƒÃª®#Ë+ï}~üëz1d;ÛëKµ7¨€]ì 6G¾¢ë±óî±mwLtn£$E7¶oê¦:ø‡€M÷¾ÎV®F-çžôØ|½m;Â.$Ntô³NÔ°>XŽï©\OéiºW§Fv­Òxbç !sco¨zg—Çl4 ©0$ÌúvüvÞ`†ŽÀ7ÞÒ!( #¡rú<´Ð·h÷‹-œ˜ØÞˆœeáî¿Èë´ŒB“Ì<§m ÓMKº+ýûf'rfÎÂY)Ÿi -‚p+­ˆé´^iVHsz@™Rv*»ÓôåÙô¹ôEåršÖ*6åwÊ_Ó”OI(ÊHšjL%m!…¸ßopsDAE’ÚL,Lj§Š ú Ñ÷ÝÌû†J?¯¸5W6‚´ X([6ºÑ,RTê,a¶KàõŒ-œ‰Dø³§²¯e?È’D–ÏîE¯dé,¶ùaþ‹ò¾µdçýÃÉHVP]`ÈõkÉH¹Œ_ñí¥ÏbjÆä‹‚]ƒšP8PƒN»–Ò8‹ ÖYèq×y[ŽuëÙ€Úc½ÕÒŸÌkÕzJ;¬okÛ5¿?Ù}Qy¥½·Ý#„œGO|upÇÁ˜¦h8e›FïWâ+›BÕSON¬ÞˆnKRÿqìJšÌ$ vezzâ¦B$½ë¶R´Õ9îE5TGq:ÝѬ½.Zå>_øÞ‘>ÿÊÂK›ÏÜ0j p·Šü&Gˆí@ñ˜ùÌ #ÅHù!’4›VGÐZ}¹Åk/9º•¡X)å*¡ÆsÁASœüåüTEï¸b™PA‚ ‡©b¶¨¨ùùç!k2Û)sKk¸³›Ž·mÜ”%Mö—M¸Ú8À4a&fÁt†-g³›úã«¶™Pÿ*B·›?ÉùE30_k¯‡æ yGŸ2ñ³ær´üj™L•3eXFº}»|gµŒ¦„á x`89nþ¿h‘#e4ÙÕ:ÀõÞ‹—äúk Ñ"3¹år¬Z]Ø7úî#ÖZ!©Ç~Ý Œs/ø¿”5ä.]µN“ˆÉÎZÒÔ2}ãG÷v§²‘3Î÷Š_ûtõ8ŠiÓŠ*ØdSÔz¾áÍÆ ”žoUçœVš´°»NýÔùí¤=dQîh!C« VÓôÒ¶æÖ­’>lhJðt^GG9 j4~ ÀÀ7‹²M0þgÔЦüÒãÕªï¬ xàW­1NOqj«ÚÁJ¢Ðt¨À¡Ó.P&i±¹Ë¾“ÄLá½û)ý6- TúuffÀ·uââĵ ŠŸ?4 ™!ØÙÁ+%PÔ!†gâ}ÅŽRÜU™ì,vãpR™ÝI…ìÉÇÚ;uz‰dmˆ#Ä«m(¿X.ÙfØå†9¤¬›f;gäö7.=êÍÀ S­E ½þ¾s^çáKe+ù×Q}ØL“æwú.V€«V½®òØs qµÖ 'ø´ÖÎÇ C¬)t”üÍ À%Ee4:’µ8QM>ÜÛëJ­ƒÎƒ3;êôV Wät^£xx{½‰³¥ží=j˜‘ gÍßj°¼íðC`ú@ç°ÒJ>ßÿ3sˆ2wáˆü 6ås`•¼å´I.aÊCT¯|#qñõµ3v'gáaþáUa 9kÊj]¡òéÝéè9é?™.ÐH"gâ7줜ÈJ $Å¥xB’ìGâÃñáhNº!Ý([¶Ûã«Ûû÷~j_-x¶÷¯Ë“¹å%OÙòò¥\TÌ墷WW/ÙÑn—–NåÆðؘ½Í.´å âà`LÏÍ“^‚×ùÚûú'µAÁ.•E㉶#ù±Óã‹7n›–V šÂªfu¹q„›ËÎdg{± ÉúL¶‹Ë¢,Ȇ²ÁÙ°ñÅà[gºà²fn~åûÇ&ÆàïÇÀØøä4yzª·o(7»•û0G900˜["ûmí™áeZާkí@kï²Cü¡Ú†æèª6È ÓäxI¸M„a_ßTxïb·Á?ëÿ­ùý ýD–m˜ œÝ{Üde­,ù¬ ÿ€h’ ó,}‘wz¼ûöÉ?áí'[®Ê!$ömàãiŽ"¡™/¯ª®ÄïNÔãgÔQZƒÀi­lå.ó ïýMóÆÞ~¥t‚'ÇYÖ¤Õr^–ÕAšFf½YËP¢™þcïØ^%8Ž˜!») µ÷ê<˜wÎ[Y RܛÌw™²À'ò vC‡Ó^ÞáNߦÏNÏlÜ{ã;o~÷{omnNÙ’ÓéJ¥’_nïH§mS£©”-šIÍ$çœëë® ×úÌÆÌÆÔæ\2™w­‹.×úæÔÔ\Ú&âéq#ܲ؜.¯/™JŸŸš™;w~}cS¨ì:yñ&YèÏŽâsk„ÏY®r$’ gaaäjv){™ƒ—Ù®ž^Ô'Ódì/.àsyƒá¼ =QëLD!ýèÆŒÑvñU´ˆ—E–wÖ­ÿj}óæú&¹°E\@,áâ……mPó³ë×··Á¬l´¬mm>¨6„Ü!ºàÅweG,Ö}gôþèÃQ4zabíÓn`ì¾Ð »·ÔïæTœÜÝÉ=W«SµÍð„êMEZ, ¿Ï©šÄ24>ßQëŸX‚J¯Žé²d]%½½¨¯ýÿàF|ú”Ň÷ê'õ•xª˜›€ÙÅ Táâ‚¶ÍJ!ˆ‹ZEB¥ºË,‚Ugõ6iG©Yô (8[Ñ Uzµ1¾z¨Ô1Øíš#*ö*æˆaVuN7(n`)Ú!ÄÓA$Úò…C­TíT±Õf>`µZ”»õ쵯h Çy @ù”6¶\Ç“Häw¤A ÕœR •æD l á3w^!ûuO¥sQ(mK-é,lòÇA)»kõXbÖÚ®K¶µÚrè*æ4tqÆ^gGýçLD&éXÈNǼBót\öÇ}Ú†£ŽcÀ¤,˜±…Ñz½ 4!Ö̾6pËØñ(åå4F-F.Àˆ%0F@b‘‰FÎêeª¯}ä«6Zzz÷>»à,"My4b!ÐCÉ,ˆ:†Ñj4B cü¾ó—‡+8ÖlòÓaJK²x=ÔiL8kY4‘c]µÖL!ÛlÕ·MU(ƒ–ÏÞÙ'H~’@„ù}¬Wú'¢×þËsÕÆ¶Öq?¶Çq;oŽ›æ­M]'uS§Iã$mZ§k³fMÛôºKÖöš®#ÝtÚ²uÝË¡vTØq|ØvÜ ql'´‚Óö“Æ`Ø Òø‚&¾Œ>„M04]y§›?²c;žßïÿ{QÖLiôŨvW{ )|ùÏŽa0%­ì~Il³˜†McÿÍÉ"¤óô[ý› _Kþ® ÏanàÆH³{X3²‘ÑÕȉø²ß eš¹B°+ä dáNç<_5NYlX#H5eÎLåÜ­‘<7Õša<×ÓZQÿœ|0ËùÇÉ3$ É™ûêÕ]•PÔuž’š Ô{ài®3(çä21#ß•ñeù´|U¾)oɆ’¼ !XY‘qY9³=dç ò2êle0¹¿ìbúXÁa‚ipíÙzÊ ´Ÿµªˆ’¶Àª%ék²tHxD9È^Ý&—„ïѽDÜY ]H·+ÝÓÏõôGüÐMã@˜,‡äëko~Å7R`FžíÎxüu‡ª2[²ªA«ÐyM«¬Ïœ¸ÛΘü/d®xýi)iÿ-K™ ó£#³“S‡ÆÛÇFÃFïJ—t¹Ïßåç‡z(G€ò´ð™ÈÀIÞ;xîû·.ºFå‰c>Ú“ÓA9q¡âÚ½û„ì0D±$6ÝÎIï\=Ôùd{Dt»Z”).¬Û©Áj!°0£Ž¥#Ý)¥G–ÃÉ Å\fR¦¢°c1|¬&\ #$½˜Tn(Ä宂_Un*[ ±‰ÎY(M@ží4ª\£ T¼Ì^‡‚(h E Á“°%¸gè E” uA¡”új«‘˜ì!uBBJӵꑭI 8?@A[möª^ˆ¢±»¼Üc³`¾˜y¡-&Ö6V»©'x~2~qõNÎÙGÇ °Q8sLÖz¶gβµQôèÅñž¯’Ÿ[ÆqyñöÕ`ˆ’LüÄòÐ\æÊXß’×1Ë›|³ Äù Æÿz N{ç æú‹cÅN¾]ˆí“f?,Å¡W–vŸï‹˜ŒÌÅ¿Mÿ…Æ?§Ÿ·ã±¿c8‰‰Â•@Õ.®Sv8ô˜«£¶å˜kÓ…ßt=uá®Û–_ᬇû¢Q…FbÓ ’¸,íX µm²·²oOÄÑv¡ë.¾Mf¢Ý$æ8“ÛÚ¶}cå³h4ýÍ?\úèíT,’wÛ½^ié½Ïf­23µ“0³+゙O~ ŽÜz·RW“Cj®×åüð»?ù½…ö›öCvMïþ‹\0¤± VÇþ“;ÊOk}ĉÅT-SœÏϯÏÔê$5Ãdê3Ú²vZÛÔȻږ¶­š–')ä™èÏäP2 ‡1Á[?°¸d‚h{<¢7ÐÞ»»cÑp9i½Dy>‡l¦àz‹Aú–**C—’Øqî8~¼–¼(­\*.ß(“e´q'¹/ªg†Pö>Ynï³…¡Fè‹nÈ/•Bƒ÷ªÕ†.öŒ½)"HU=²V$'djJJéL oz!S©Ë Í%X—¾4ì4ãê«ì ÙŒ4Q[ïƒÉ~ ÷E5ÉI:‡›1˜¦¾7¦O®à€ô°E·#{¨£æ§ Œ@7 p.®¸}?o3P‘èw¼ r4–=5~©¸Zÿv±íÅn@·Ô§zJ­¢Ãóaèð›ŠÂ艟EÛH&fÈ®q—™µ{/ª¾ø›Cን9ëM¹|‰þn›µØg €d)Ún6Øn7Œ9LˆÚþÏÎ?ØyŽ{ÛÚM`häÐRÐß“žûñG%…Ý'Ä:1õAw¹úK–³òßî>ÅD,´»•› -™Ð#¿µ|v8N 8\.¾:°Á`^¡üëaµJQa&dóA‰ƒxÍj35¡†‰›âMq[$WÅ'".ÞŽ!¬spHÖª]ÿ›Xb{ð­)w²Üc›;¿Üÿäx:î‹9^J ïöãn© ‚;îljyª9Y¨{@é{q„‰;Ž^©xœé¯'öE–ÎIé1_í½>ÀSG+¸§*20å‰èïæ~}¾­O;Zñƒ {.:Z§óa_ eïì"ëðµI3õ)œ&Õœ G^›[4,ÌÎL”Šjê ‘¤[,Fçá½ÂذXhc²XZؘ5~ކãfæfËE­<ô£¢9€­Xá8Vº*mKDNú›„K÷ÀÏsL w…§ÉÁ“˜@`¦°%l£ëmtk€8AšÅR_ö†ññ³f ¶¿4‹fBÆ`îÕ6g¦Öh¶Rý…½GP"Ö­<%!@‡u+ •Tð)´× !œZݺ‘<êm0ÔK$ÕŒ¼hp)£ S¨ê`ѬºÐ¿ÙL§”1¸U#CÂXg„ÒŒ °úçˆqÕ³our∸/ì÷93ç ôÚp\ @Ð-ô¤ÃL›À9„Ó·h³’d®«Ó²Û1(ÆÉWšk±Ð¿ØrÀGÚ8¯ºð'Í—ŽÆŠÁð¨“=li‰-\>åƒlh19ÚŒ6Œž}›q}ïDå ‡Ï ŒüŠ$ ˜ûâ;»äk0ÕMcG°óØn®»Ëò­•[B1–d,[ïܼÃßçqþ§Áu‡gë¥úrýJ¼Rõ{8È•7³÷³x.»™Å³ÙñRU–ÙsÕñr•¥ÆÙN¾K™5b‰…ffs‚8}vr’àÿÏtÙǶqÖqüž{÷ïÎowvìØçÚÉ9¶Û±c;N𨱛w·IÓØ‰Û:¶›,íZwi†(Ð%[%62Á€R`Œbb¼ˆ©“¨0¡FZ™Ð@ÚšªíŠJ“¢"öÏ”ÀóøÒRùåùÎ'û÷û=Ÿï÷+Í©søÜ²¤EµÛ‘Ó€¦­¾‹å½y<ŸwK 5'nátΟsƒ«nàþР “%fˆ±F¼ -(­Â%þŒ»Ñõ§«KÕ%´Qtªîe¢h ½BY…hév"ñp‡GÑ ]³¾.pììVwt´Œ…èšJë³€¦y>Åžjí~}´@ËfèK¼¨ó‰ÖvG â-Q…÷q8`pzÓ=¸õÀxÀ‘ ÉE~Ú:{g¹3æìçÕá¹WKhåd§Ëæð˜h÷‘ £4uölÞáÏ–|f“‹üa³ñA½Vxúïϼð·Ã‘£à‡…Zé(ŽÍ0„ÑÜU8õ¹>%Ó‘˜æ'kÃ×çW}§àt¬ ¦'Ʋã«O°¤EôúÌÞ—M‡Ež|!&H1zȤؼP.H‹O ®÷÷ vÇ{‚?}îK¯=E./»f}m°k¯×œ v)¡ Ëá³yÿh䎆aä ª;}’³6•»îêlm´—À›«©å´Ç=»ácÜØ¹Êre•ËVÒ•A®7” NŒNœ®- {‘xöœB[S©Dðüy«ð6$ y DL‹ÖMz¾Ì²‹tb3X(ÜÂñœg: {±F®A46Ë´4­NãÓå‡Áûa¾>}k›ôï }º`út}õÝ´w¯ Ç£E4;ºÖÃWyóc`ÉdZ\ÏìNkRL;vdZ¯{É!(ñÖ¤.ò}0´NØ $HÔíŒrÀ83Œ."­ÄÐÃB8Ò_ôyiYZ^Ê “fšô²”rœäèžø|›½¿$ )üÔËÇ® @‘”1ê’X€Û¥îùLçp÷æEû FOG1•ýBˆ€*béì•pr-é Ç’,ÉIýãÓs¶¸\hÿ}·Ó#È’ba(£f É½7&§Ör_ÿ‹  )X^ðk8áX‘gH+uý?övݼ6æGFø+É6N´QÄ¨ïŒÆ5*„±~ì•\(*z›‡îv2Ü}Bl «•‡ d. a­«3¨8,^/&¸Ð(Xœ!ˆ-Ót0VŠ %Ñ‚„EV¢›Á²¸i¸©€Ì¶¶•!©P·3ÐέC0ÜÛ;°ræƒF£?Œ{º\ —œ…ÁfŒ¨LšW$ $œÓ…¹œ½ÝCÍt%Vé;V™¯Ì'Ÿ¼T¹R¹ÜG_æœØ§uuÇ2ƒC¹‰©cÕšP¬DÊóù…‹õµKDÓÕîm8Ïp”dQHö ¶a³mD"óóÒÂû - íî.THÓnUwQÛY+ØÚD6÷ÿ¬3Ûõ6·V(Þdu…Þv÷âð\Ö¦={r+Þ4ÝÓovÌ.æ¸z­vy"o›˜ÈoQGX„§*ºñkºÃÞÙb³wÚiXuT«Õ÷àÚL›ûZËjAÝm‘ÓŠ ÈÈ:G[a5Ž‚.³@¹GQIÝvé@…v®ïàrT:se;¼\Ó};`à­¼–vÀÀà4`mÓ†øM<ЅÄÿQªÐ.˜$- ˆ)C)ìN2y93â;ñG‡Ó9õú’< ŸRí|T[Èl“”ý½6Þx€3§Sn³ÁŸ);ɬÆiRî¿È„ºÚÃ+f^b¢ß?B ÊÃ/Ós®#¥ˆ iE†“Åâ<ÅYÚ¬ÖèWÚÚS?]’ÚÛ)Ö/±#Á$@¸ìÀæþ«ÁÑ)’4ˆ6 ʼnf‘‡;‚Á\¦"X{>WÄC͈¹)ßmÃ"•d%ÎeÓ3éÛéi2êîp9¼´`– Îjåܾd ó–|\‰î(ùèÛ½é+c›Û,0`,ÈÂ#‹¦*õ¶úˆ°&Ýkg¢é¦NØÝH”‡J™4CÁƒHÕ:[ 6Õn ”íf»l{d£[ vKé…v˜ü]™ÀgÞèi7 C Dc@¦ð™üJg¦9—HVpÎgá½û]s™j3²œ!{€ýŸ_Õì´uôº#lœ•ÎBRðß,„1ô â ö=ðë\1¤N©7&ßžüó$åôFó3žûòó†ËOb‰d®röEÿ–Ø”îÊÅNo~£¿2T\úÙÕÓÆuÇï½wöýö¯;c þÛà`ã6˜_vpüƒíä`Aë%U¶`%Õ¢’Ñ,-k”,U¥t›Öý³©Ó¶vé´©™4Mš6)ëöפUS%´I“P§ eÒ$ÈÞ;›dÕ,ûùqöÑ}??µóÚâm펶{fvmc÷•-w¿Ëû™ ûChM ¹™üì"¿pÿG÷ÝG­ÍñPOª &'Óg´¼a®&³y~ý*¬|íÆÍ[ôN±ªòª“³_CþÅ3&s7 Çã±ð±:>sõÕÍla> ’$øT ÆŠƒ¹a0©ðã0äÌa †qàI… 5;ÑÔÎÔÎÂŽa§øjÖQ3KÍMÍ-ÌæŠgÖQÌ9rÌJv~¬’‹¹Íorœ™êƒ ˜Ï€Tæq_3Ô ¾æÏî'™7¨ËÉ·ðà÷ñèKÑû0pqϲ¯›k«ÎW¥ÏHýºH QR›’‹`ïM|¡²•÷Ög;3Ƀn"<7%áÑŸ¸ÑáÄu|ÑQ½zôÂ1»äÎØŸ±ÿ8Hì"±½áÝë -ݵ‰beD¢ÂnÆÍÎ(zÞ'ðó¤Ç5—“\»ËÚ°$±¼•‘*`±sÄ“q+ §Ð6µ Â)ó ÿ?Æþ3†è‚§ÏD>ýgʇêÓTsK’Ö:lò§mãl\ëÒ:ÎjËÚâÄVƒgÖûJ©–f‘ïà›[⨭iTíJ£‘ž¬–Gs¹ôLfÚ[_ÃKTÇ.SòŠÍ&ËÂÊ!M•Êf…\v&›)QͽY,mmÅ&+ÃT„¨™\]N ³Ô0>ÉdV½*T ¹ã`DàŸÉ­uïEÿ}Ü$±›”p7:øæqbr”ŒÔöêúJlõ ô1°aH8:0®7KÀ.Õ ]+ ËV'EA¯z'õ=Œ–1‹åÒwl zÑ ¶Çõ€JÀSÙ°Š¿ØXUÑΙ xªØn1¢ÙŠAf´©³·›ð`Ã'9ðëÎÈ:Mf›‚plÕ±Ž+)ŒTVåãµÛÃëS÷è„HsFNRN«kÉdƒÙ¬ÈQÙa´ØÛèM+φ\þüW?:ú¹ÃÌ2œ$‹vä%ÆfG 4°¬5š _úSÛh¢Óšì×ùÝÓÊŠN`„ /°8 >ý}†f)#ìRjæ.w×ú÷ž•fx£7ài÷oû ——ùóO¼t}^våÙ›2™mGœm²Ké® ceÌZÙF3õµê©¶‰ßüf//û-ÆjÁ }h¬üV^¤ F‘l‚Jÿ8 /#r½hmò8 ;qæ;…É@ð§¿b0‹&Gß Tjžú8{;~3&¨\ËH¼Á¹áÖú¡¢¿æÖjsù‘­¸0À c­Ér¸Õ˜ˆÑf.£t¤º(~qÎø¨(F³‘‰œ,Fr2ùš"RyKæ—ÄÝd÷d÷|÷ƒnº›ðlól£„@„èé“}=J–“C9àǾ®˜¤à×3ñƒ< ªˆ57¢Øñó&Å'G&G`¤½uÇÜ8ÓTÓFÓ)ʬ¶‚Ǩjð·f³IuùuÄL&£Ú]´Ä@,×H&×o üö ðqàqÀÀ™Þ@!ð~€NX ð=µøÈŒD†uÛ$QwÎûK«eï¸z&%§$ãþ/ÓeÛÆYÇñ{ϱïüØg_çìøåâ¼øüÛI.±/q’ÅM“¦SÒΦN»¶¡°Enm¡T- £´µâ¥öG‹6!@H-ê¡E´BTb ¤*b0A`ÚDUi-”® ÏÙM:Ÿ}ÖéN>ùžïïóý~ï7C¥é±Í¥Þ. ?ÜrÄBÃøžØ¡¹†øÐ\Öhˆmä4 á醿l›e¢azj‹;çxÒ.w»(¸ãx»`›0 E q=Ý™=Ù­µ‰¬[l#) ÎÈ>³pcRÙçaާy¿÷›Ê‚­ÅJ‹ëî. z¼òð“^>*OjÚTX¬’Êúv<¾+Ëv›ED¼ÓÊЂÅb®Qeó.ùî%v‚?wHk?î…‚®:UW`0 †ÚMèn·0 ÒÜ@¶=­§‡¾7LûC Ô78Ýÿþ óòðæU팾®Ón=ãÈø¡cƒ©Á´1Õ>nЃ<"ÂA9Ñ:Œ¨/¡ŸI”`¡«è¯ÒC‰þ zWúúPº‡è·¥ß¡[Œ¡˜4$A‹äF%´C¢"è z½/QФIÏ¢o#Š;ˆŽJ—%808$!ª%Õ[مخ‹©J‚0ˆKÄ‚ZÅÿ”MUƒlKu”??@_Çl ˆ^À¾„j¨³ê1•ZUÏ«—ÔÛ*uSªzZÂx|õ¢Yt@áê±,Èâc£Û7ÏiH@! Ä9â<¾½‹X%>  yÏYÀGWHüì#¦1SªõúòB}áþú£åGõ“ZÝ[¯cˆˆéjÃb°úêM)Vë¦î°:—ëõzÕ|5“˜º™}ΰ ®HÈ%Iè¬=Þm?%ü¾,¦“ P­ÍËAañ)Ÿ± ³‘ÄùÆškÓhšùKªM¼lÐÙ6N¨ÑJ»µsY1ÔáI#…JGZ~Ç­•PkO§ÿåâþó)F‚­¢qŽÄâè¸ÖíýZ¾Rºü©Ú5`×yŽ@;¬û]1Ym»µ@¯Ä§,N£s ¶óùH[¼µÕóck±ö¶r©ÓŸ v„œ~×òÔK¯[i%3âÔ S«›Ÿ’/Àÿ9â»F+ájí£xY‰v&))ì‘Ò¾tE®¤VùkàC‚' ¿ÀOöð‚+ ?lKé>¨eÛæ¹k˜* ø÷¯œÿ|À·'©òËì©›ÐLDô›ˆ¸á°±±ñ´"š ÚÓˆøÜÆÆP#9ˆ[a¤ñÈ;îb©\*÷$ßâö†jÛ¿q>6³n|¢Êšë¡¯|q¨Ÿxè2;ưAÑâís&HÀ;=m¾V…iñ:¨ÐéÉêK”2ÙŸ¦,µúûü:íÄi×çö(6ƒÇ_=š“y«—æ²å +'¯?æ2gað“ëÚ¼KMÁ,±ø‡192APÁH'Ý¥¸Ú²¹9º=C2J¥}©Ë~r‚Ï|aV? ÓWuJ× ]L/¤UׯF¡¡°†4é$¦Ÿ(­g®\>‘Õ]Ù¬Þ^©üŸýjmÛ:£ß%ŧH‘EQoË’²$K¶ÄP‘-ÛÌ£‹ãG{Il%–“:Îâ$ªóðêi“fA¶E_?ÒnÚuÚ,Ù°Íúp‡ˆ ØþlÃÐ †­ C (Ðí€8»¤ì¤Ýûµýò¥ÅǽïåùÎw¾%³uûÃá¥#G}GÂÑ#GÃѰ?znæ°ofæ°Í@Ö¦ ‹9HÝçâ§)™û-]©Ú9ß&'Næ8µï1oþFö7KkÒµ©‘~zV6|“üŒ}u¬j±€ÿÖÆ7hKâ[vý)!\ɶ­™·Wb1RÏÊb€pI¾¬B‘,7ÛÕâcfº:#1¯ÖÚ4î¬f/zºI÷®XAN´¶wqQ*¯ÑÛ»JâÙWù²ET\Aœ•’sñ‘{U²e‰3hæÃ+ËÄÄ'Ïh/i?ÔHVûªFÔ–?cWEwj8¹Úa ó·•rÿjk/7ö¶ÞÚ¡àœÀgÂA¾õÑmÜd{·æ\S»§~4šN¯ »–,Îûð2 .,œ£²>¼ˆÿ$¼ùæÍ›Û{{WÁ›Óœ+ëÝ]Øë";^K¶ ì¼î¤ööµô^ÂZlÛ°†l;ž¬döÙ=ú*ºÍw½x/bh¦!éQdl¸>£“k ¿EŽöã>MN¡×èGã2N-$õæÊ"}ZÌ|„Ù #áÏÏÊLT2F"ØŒ×%|û)E·\^oçö¼je½ZŽl ræñâ«ÇcÚ¯\* ñøÎœH PXò’Œ;á®šÎÆT=¢Š"ÁH‘¬92\"CQÅHÏkuJí {ǰÕq±~>Àº°í HFâE̓#Møþõ ŸiŠLÙƒ$EåXU¦K ý¿¾Óâ7ŠX’E*Lj²À ~·’àvFb';¸ääišâ)·ÏEÑ$òr8c|¸$N0 w­=…¤i©³¡ý‘iНJû¥¤Û/Yî)\ìI¼¤‘Áj°žœ®V—‚š/X j•-[ÎMF}““QU F›{*ÕinÜlÍ Ö…:»eï$ùØø3ãÄø :oíØQ¨f«9¢ÊVéMÓ;f~Ë\6É‹&¦‚•šè]™ùÓg0%°wÄ­Rñêë²VÄ|¸}K®ÜÂÒeg~ùNMq(SSÊ÷ÄÏëãñó7.@ 9*€“¤óáK޶øšˆÖuHØJãl:ã!ð¥Vª}“9@˜Ä6cì‰ÎmÑmˆóç$&†(Ä E"O¡'ÃO_ó%’[^¶ÔÀˆ‡³x—˃{ufõ'­šç­G‰[„žjÇÖ¼ô’ÙŒ|¸F‘î€Hy¾ÛzówzŠÐXQ>Ñž–tJ‘pÁRŽzÿò«9ü}fˆÑ/©8a›%7qM|žËó¯hâ_}+¨ï š\ȵWYA9Kt/Æõ.ÝÒI]‡§æºs GŽPöØFCû´1Ö|´]Þ&º"0~‚oé$vZtª2ñ•·¨¸KhWY&Jä² =˜H÷L^9óÔŸ Ñöü{ oþ+ ãƒH܇üÀ5±@¹0þÀü€›à/ˆ9‰ÓÊëê€ï ÍZÃÏüƳ÷ø@è€ð5€èn€8XhÁEVû/:>¾kè0L€¾·9P~¯Ê£ýx¬…Çmݰ=0h ¿ýŸå`ô€±C»ñs'ðÜ>ßcïï¦ð3öWàyMãµ8¸ pè·s€/à9½p ÏýÄË œÄksÏ{x;ÀY|íü>çñÜ«làŽ·7° l`ØÀÿ@`ßk7ö aÐð_ àôr à‘dÅ«ú4¿†Â‘(4Å›±lmkOu¤3ÙÎ\¾«»P„Mfis¹§·1|+üc.®nîž^Þ>¾~þAÁ!¡aá‘QÑ1±Ø-ÜFØMT, @R‚AèUeM+;†††x†*†‰ ÿÿU€d4´}:G†  L"DæÿctÈ ú`4¬±f‚nâ`HƒšÀ Œ/(›È²Ù€, PL²pE䀮‚°™ø¢ lf Š (›Èže³Ù;œýݵÝ‹sóóRtòsRˆƪ#ú3¸38CÄE@œËÏÇ T†t†R†°8~µº@ù| JBf’®jLÓ~Ãæ"+0dô1ËÀ<Ÿé;$°00NÊp°Y ŒfHcj‡ôè±`Š˜È4–á ûæŸÐXb’œY{û±N<¿ÍWi°êµ|ëþ‚ér§Š—ÿ²qF°ÿrAñ6G“²( endstream endobj 315 0 obj << /Type /FontDescriptor /Ascent 905 /CapHeight 0 /Descent -211 /Flags 96 /FontBBox [ -517 -325 1082 998 ] /FontName /BABACL+Arial-ItalicMT /ItalicAngle -15 /StemV 0 /FontFile2 316 0 R >> endobj 316 0 obj << /Filter /FlateDecode /Length 5554 /Length1 13384 >> stream H‰ŒV{põÿ|¿Ý»¼ È e%!r‰P„Â+\&Hö’‰Î]È\!b ‚´C{¤<Ê´S)(òu``DÀ-…‰RtZ-èŪ™–Û~÷"ñŽû½Ýý>ß÷Îôà H”þxöÈÑÕ~xâsKæ6ùü˜­NF} ÐĹK›µ ·œgXö  –Ôùë›Ê7e¶L¦ß«_ÐZ÷îÝÆ7çzÖin¨õÕœ¼±éQ`ŒƒéìfÄÄF°~ô™ÖÐÔÜ3Å–Äh@ÿ Íõ‚£€¡ Ó·›|-~ÛÆˆ(Žg+ëk }Mµ{Õ=³€ÑåÏtÿ¢%Íæm–`ôKî_\ëɰÎKe¶çÕ#HßíHQÒ‘˜ÿäûšõ5š×-Yh‘ù¹øœ­öÜÝ×QG !)¨A+Ö0¼!€mØ@X‚eØÁø›ô–𣒫˜?þ„Q$ͳ؃ç©l€¿  Oaƒ¹Žâdäc1ËSòïæu*¤…HEfἎó¤ˆIj’ºÄÌ‚ŠH¼‹.1ƒãŽÃ@ŒÃt” ŠcÚű¾ƒ ”¡æ›áDf³çV¬Åvœ¦u¢V<+vÈSês“É^ø¤¤£¬µÏaçñ EQ<½MWd’²9t+tÏÜÁ™ÇL…Ïr6'qá ¾¥9T'\¢\úU©7™ó#'fb¼X޹b[Ûe[èdè.ˆgJ"‹£‡\ο’kÕ…)Ž’)†SͦFÚJÿv1^¬;Ä]©Ê †l¹]”ŸÊ‹ò¦R¤´(WmÑf†Yl6˜-æ«æqó3®éd`ŸY…gà㬞ÃJ¬Â/¸[›¶àUìÄ!tâ0Žà\Äg¸…»ÔŸFÓšHu´€Zh/¤7è}:'ž>±MtI]V²ï ”¥TY¢œ !”j Cï™ýÍýæŸÍ¯Ìû\Í!\ó4®h<¨eÏ?ǼÌwc †#¸À;òW.’ÁA ”HÃè1Ê¢‘”M¥TF•TOÍÔJ/ÑZZO/Óf2èGsŒÞ¡éÝ [\.³ˆ±bˆ*2E–x\”ˆz±Z¬{ÄAq”á¬øPœÄqSÜ“q2a¨L—EòIY%ÉÙ*_»¹žgä%EáþÅ*J¦ò3e§²Oy_ùR¹§F«kÕêïÔ+êlÛ$[©­Áö[§í#»´—Ùëì/Ø_´¿d?=böóv9Ó‡.Q…×ðÃ?¨]&ˆÝT*vÑo©¿LÂ|ù{ú«ZŒ_Š‰Â ™bü7-¥¥(_§Û¸CBçɥ좭8Ê›Ô&æ‹%–~¢¼®Ü§fåœ"Åe´‹ë–[‚²‹½-åýo¢ÉŒÕ£ ¯ˆœ;¸ ?ÅñŠ-R¬ç¾¯Cº(ÂXšnõF|ƒ/y;âh æñžÜ§íj³x–Ék"OÑ}q‘&¨Í¨³9°’ˆy†.óæåy)¦1žªqWi]s0S¬Âv¥^ý>%•¨ <P.Éé²NÄ‹7ñýk:xº0CžBýš·¿K¸0],Âù}Z®ÔË޲E(´ŠwaÈ"%ÓÐ!;pŒþ ÿF.ìSZh!m4Ý÷ŸÆ[»²WÕle°y:ô í¤³æqãÌÓrN¨ž6+ɼ—Ëy{s…¢±›í7󣌥ñ>®åyÈß¶HÞòBþrÍÀ3t‹7fW)›2P"†b¾˜j×l €}87µT·<§WÖƒñù™*z0‘*ÃRžÄª^e‹ðÄJÿláI®é´Gð(†9¤oQ÷³"ÊéüFæ Ë*üúά'L#×Õ—žÐ‡î^L@rÀJº(.¯ ¢úÈ ù»êZaÀðuš+ªuÍ¡‹bgÀïö>èh§ydMêÿX¯à*‹+|öÝcLyXÊl°@émÂ#yJ.’ ’¢„“”"y¤Ð „ÒJ,yTJÀ– © Ü Ü•Щ¦0Rk€Ñv¢(„¿ßÙÿþ—Ë…QÚi2ß~»gwÏžÝÿì9{wøõDlbšoÕèÑÝßeãvûEÙS¹95x¥&–Ï hB>åщ»»¡/§oa¿’ja)·¹E£<= yUWç?Q©ê5”@µ ‚‚”ÌëÊ5G– døKÆ—Ç×÷ ½1–†{k¯}Ú:Úû^5žÈÄ¥°”‹ Ï £H;!b"Êžót¡:3‹^+ðn­¤7µJ{½Þ…šÄؾåhí¿Ö(½ÁÅÀ`2°¨®åÀ¯0~>Ïea Ã+i¶™eŸÀzÍ:zxõIÆišl „u”Åsñã!ò§¡ëI«’r!/Dÿ~ÈrÀB{ êk0ÏFý}ÔoxV ‚·@ž=qÀ[°»L?„±EöR­Rø 3HÇEà™ÀtŒã}ôc¹¨£GDíEÿÔÆúÃÕø"*„Ž&>3œ ÏËg‰v)ê[aǃìVÔ è‰À ¼jh;ìñØ…³o ŽðžÃ{‚ý!›n‡cãôH`Í%‘¸iÛm(Â;zªhÞø¡ÚQšeŒÁ÷;M£Ì³ø¥xItÂ9åbŒBZì%ûMØù–¹óУˆF¯Ò½ú%€¾¬ ô%ä¤õþEohÍô²Õöÿ²¡¿Ø ”/ÒxÌï¥ôœÅo»"z àµ{¸çÄgã%ªð¬¢e8÷ë^öáJ: u æ—býb>sþî"«µzÆa̳@WÈg+Q,ΪßõKø÷Iè* ùᤛL“B~ÛàBùYêì+ñ¬¤Zà0ð Îl50õ'€]Æ/Öî?ê¡ü>ƒsè¡ü¾ÁþÏßJù¬³‡åcêÎó;BÏF`»µƒUÀvŒiàûÂ>ËvººùN±Ï¸¬ü{½­UjíxŸìSaæ»G4'|á[.ó½cßgÖü4œ¥§Ò@öYö7—ù\”ý¸|'Â|s¯6ì{Vq=Í ùz©Ë|Où,¼†²ÕyhêSy”¯ÿ‚2Œ¿S¡vƒv™ð-gØKyoZýÌ[Kà[f¢]Åžz1ݬ¥‹ê<ëéwà¹F½ö Q/L³Ê>o’8lViKUý6ކ¨uú˜‘}ÿ­üvܬ¢©¨7šõ¶ý¬ã;ái}€D—!¥€ÏûC±Ñ;C=(Á"ºdñ]ðÓ ÓOýZJ3Ú#u‡|‚ùÍ×WÑ`£‰~,J‘ êE¬§=rÀz€×ÒŽÓrëωð£[|.Ú—\vý5š9æ‡|Jqèî-¹„O Î ŸU~@ŒVPþj?öÏÔ~ÜõÏ[ýÔ®‹ðÏfèíí—Ѭr â»{Oùn¸ûçøÈ1Žc$Ç9üÒìéŽæ›óE*îI¹ŠÃG)7t·¬ Ð×vþ÷Ç2¬õ±•IÖ{4Mÿ.å[¹X¯™¦X©Ôû¾Î©ÏØÍ¡|šâæR>'ô7»yÔìC^Ï> lo> d•GaçOëÔju Ohn ßCuçRçFc*m0ÖÙç±ßëoã¼!7²éçªhˆþ…}ÔÈ·8'êëU *4^±Ïègà{<÷{–ù½j ¦Â°>fÛo½Kç ìÑÜ®rþ7ó·÷®°=§°ÿCtÖØ‡1]èœy„÷‚3è§ö4QÍÝj—°.O–½Ï8Of d€š³Øn GVäY(æ³€Nk’ÊÙÍcè+ O<“)Û“uçÒ9OGÈx­Uøþ½À?µ¨|]Šü–L…úWð­™Ê§›Ëì÷ô I7ëu¸wËí“æbðOÞ»bÄ}ÜõÞ€X;ñ>ã÷Äzäønô[«‚ZÒBã -4Oc|?JÓ[p ÔGØ ¡¸¡[_FÌ…;oç=ãiŸ´¶¨õ2” üN)¢%ú”­í£4Ä’qÞJøÊ$•§WÂÿþ\t@ÒBxÜv/úŽÁG_@{‹ž A}ƒ–JÓ*ÅsÎ5–ÑsF¥è}GÚàMqŒ¶Š«´Y'Û8B› W‘'ÛÑ×ú.zJßCוüCšqéÚG4ÄØˆø=gXF F•è»éšþ1ö0±óÌÕtÑìFÉ8÷ÍúWÂ˧©QÏ¢FëEÚÌëñ8àôç3Œ‘”¬æE@Ùê"Êfm4ë£è—°÷sÔËo±¶†í,£Ï•w°OÙÁz1Ç›i9‘} èîðqÜá.p*‚™ñM+8/XKóŽ#öMÄ›¥-•Bç%¢ÖaÀ>ŒË7C6õ^ÀÔc [®ßL…cì¿@–ntÆ]qâÔ"Ȧ£?ùð_ÑÆ¯‘Ö:¢ë€û´Þ^ ,Ö#røÚ§Ž=öÀK!ƒ¾ë¯`Îe´SQ/®-À`%æ|†þ$`4ÚÅÀ4öíÛÞ5ÿw¾s>»[æ¸Åv‚à6D礻f÷{~ Gç.÷ûG¼A£Ø9w¹ôs¦ËPÑ'ˆÍC£†p\æØÈñXÅ£«w€9‡€W ^âXÌñ±ø}ÄÃeàù`~ƒ˜®]»Ç— k£½N;ƒ@ `P”™@ “_{=ðrª?ÊST=v\J)ó˜'RTÛ?Òá{âŽäpŸTWQQÌíŠê”ANÛ××iwëžR2,A« …¹ŒGÙHJ‹WT·ïâL‹¹Ÿ§m«þNç”øƒÚ6ŒØ†yÛ”‰Ûü÷ »m¦•éÑZ†õMжE•%ªÌSeš*{«2>ÔÛÈ««ò *wª²·*ÓT™©ÊÙªTãÅü7ã¿ ÿ¢Ñß–’I‘$¤ð' ¿5"FÄ’kƒ"Ößÿ!Ù+q¸LR“I` ,ò”É@W_ºì/ —b„F^êØß¾m¯?(vì»±"®uEÅEZÀ7F‹ƒwy¹‡M€ðÍ“ïbv¢j%jUy-9(²òß2èyU5áo'¯È3ò²Ü/¿–£äa_•¬Á¨M”A£þà jUþx¹R> ãÎÈb9S>Ÿ¨ºfvùce&åúreNbW›¨VyLBÍ^™Ît_Pˆ½Ò/_’©Éjj OÝ+ûÊy²—TË%9ËýÀ±­'Ó^ù},ö Z%CNˆ‹‰‹ùûåÚHðïÍ$ó^ÿn»ÝÄÐ&aXNÓVA«4všI²°;ÛÝnS1Ó]pkÙ–@Ò¦‚{+xYÔ»¸qË‹ë.I-Þ„=yèI¡ xñ$è^Ú¿÷fšvÅu<)ó%ߟ÷½_Þ¾ïM2s¤î&uoQwº9êŽS÷ê>OÝQêŽP× îYêöÓ^eÖÍ:Y;cLc!¦0`½õæÞ¤Ð«E„Ãß~´!Gañt  ¦ÀàO©¶b—,bó°_Oñ%½NÚ¯Ìñ°nµÁžµbüEÃ®Óæ 3lN§¯–k„¼ë`–+ïÔ Ì–ë$.R Í—ØÕøÆÍ„ðÍ›Ž}oš13:ÑóÒ¹Âߘë¾5Ž%f<$öô[ ìrùM¾LqX¡+†®Æúùv©Ì?ëwøs"hö;6¿”ºVn-òy±Ð ·…sÊ uˆlgD^*8Ž­‘û-Ám ‡ÛSpøØ³+¹ñ8]rxì<®/ºäô¾ÔCܹ-¸Aá;³’8³w‚«mëÅBM×Öږ̶·ÏJ$™D$”Þ*I‰$‰"‘sÇHÆG†[ȰÜI%ÇLÒcºRGL—ØÉx"¹aF±"ÎÊt¹ÆÀrò×<ßycBö½+>ñIb~P…ÃáíºÅ;t L3fD²dDëä¦(ª ÇÓ±õþ#$›’îÄt—?•Éerb O¯˜êÆô)*¶>žNl“M*‚éÜãÄuV«k(+V ­÷ª/k¾¯‚ÍK67¯Ì•k”ùäõ‚ƒ¹Ñ£\GG±ÞÜñ’Ø̊¤ª¶ÀV®­Í±÷.‘ËI2†—à«x)¸ÑÉ VWñÞ÷žøÕÄ~‹S¸PSÈWØ4 ÿQ}áP ©B;Á]q¦…ż*Éßi»ú óAö0{)ò{vê0 &Æ‘4ÏŽ¦{Ò=gÑà)uç`2 û í€/Õ@ 4Ð@ 4Ð@ 4Ð@ýª„ô‚*"ò4ªõñÈ[BðŒ´!YŸT³éÙæÏ~½d š¿ýã }Z…Óh‰¿òi|y±†Ñ ¨|¨ 310ýXnxÕU$nøqã÷üXøaå¬\þ¢‘[©Ì/gÎWç—+ S³Ož rRóp ô+PyX†Ür Ö0šÇÜ£¨ œÇC$¢ ,ÀEïäÊ 0 j' endstream endobj 317 0 obj << /Type /FontDescriptor /Ascent 861 /CapHeight 0 /Descent -263 /Flags 98 /FontBBox [ -217 -315 1129 993 ] /FontName /BABALL+Garamond-Italic /ItalicAngle -15 /StemV 0 /FontFile2 318 0 R >> endobj 318 0 obj << /Filter /FlateDecode /Length 18472 /Length1 27236 >> stream H‰|V tÕþî{³»!? šY& ÝMB 1’Ý…$IÀ²‹Ñîæ?1‘9©ø‹`Jù©çOQü)­ kƒ¤¨µ‚µ-§T[Á?¤*è±U2½³!hkçËNî{÷¾÷¾ûÝ;s ]¨Z´¸ ¨®6ø] õ-ž]X߉¾Ô•þ>д  }õ«Tg–˜Ê>öÛ‹š¢ÍgfŸ*É€rOsûê¦îõ+€¬=Àìu-‘†¹Hm^sE OŒ¼2Î $láqvKǪ[ÍŽã<îâ—´/¯ §:PË¿øÚŽÈ­QGò&óù Ç«7G:,~ûÐÒÀ|‚Ñå·¬2ϱ->Ë]Ù}뽂׀´D`ÄN[`›Uùyršgž0?ˆýÿàü×ì#ô º™Í¶ÿ}Eùw×i~Ë5j®ÿë/Y‰v6Û¿-‚QñðâZ,C=y‘‡VÔò½‘×MDаóäQz0K±™^Ã8†l,Àõ\ÁDŒB!¶b?ŽšOó8Sð69Íñî³Ð†g•"žME&Ü|ÊvJn^›‹|ÌÄ•¸ X‹£J!ì¼Ó$Ž_‰ð(c" 1ý5ˆÒi±Ò\gþ£’y¶šy¬‚ÎŒ^Àå“ÏqqŒxî«Ld1ó4c9GmÄã ´UøÄëæqf•ÄlÒ9ÊbäAf Œs ân<‹~ò±,)âSælƒ ï4…£¼¬ÄL3ãk`EÚ[ñÁ/°×Â_ð9 xª¤¦/Í:óŸ >-8Ûi˜Ç¬-Þ7²¶¸—uý!¶sž{ð~‹×ñ>œ§$Êå=úE¾¸S¼ Sä5ò&Ùg˰;Ìcœ¥ƒ÷ËŽ±rc*¦cÃÇŒjpW®7qÎk°>¦ÎfìÀO± {ñúñ2þŒ¿ò)§ùœÏçI’9§ÐšÊ ͧ…´ˆšh í¤ýt†Î‰±âq£h»Ä^±_¼,'ÉíŠ_yRé3Ç™Ýæsææ ÎÑR>NV]åÚÌ`3§2”sí*¸æ5Ü'7pÞßãÌ[¸“Úq3V0Ë[qwúݬÅÚßnlaE~ÂŒ‹áqüœ±c0ð<~‡—pÀ9›wp ÿÀY|Ià\\”MyŒ|*ä|Z©Úi%éÔC;èaz‚ zŽèz•Þ¤?1Þ¥¿Ógô ŠÑ"Cd2²âjQ!ªÅb±T4‹[D'gÿ±8+çÉò6¹Vî’»å³ò¨’®,V¢Ê‡¶€m¡­Á¶Æv¿í {›cœÃùÍKƒ¼jðùÁwÍBs™¹Æü‘ù´yÈ<ÂJWo ÷]6wÿtî¥9¸•Ü×!ÄY Õ¡MŒf~[ÑÁoƒüDÜÂju²V÷Ä*Ûƒ3vâg1ìf<Æ*=ÉÚ¼ˆWp‚qïãc|‚O¹Êgñ5Åq•¹³Rh,¥Q:M¢É¬Ñ•1Ìe”1æQ9]KU´”–Ñõt#£¥Õt;ÝÃè^ÚH›èÚFÛ¹Gv3¥½ô ƒtˆÓzu=JïÐ ú˜ÎÒ—Â!FˆT1^¸Ù"GxÄü†D­hb¬÷ˆ b£Ø&¶³Ê‹~q\|(ã¥Sºdžœ,óåtY"¯’mònÙCŸ¯ÈWåqù‘üB’ª¤)ã¸éJ‰Ò¬´+ßWîPvp‡š6²¥22l¶r[•íÛ‹¶ßÛ½ö™öõöMöG‡í§ì_9RcùŽ€ãÁ¸ô8Uïaý/»h‹x_èâ m¼Ÿ£ÇpLfÊå¿wªè+q¿2WÜ·ü¥²–>“È’ËÄfáÅÛxžuñ²"wÙ ƒ9ˆS¸I¢NúFlÚ,2¸ãû•k€ÒY%³ŠgNŸV4µ° ßëqO™œ7)7'[›èR³¾3!Ó9>#}\ÚØ1©)£“GLJLˆç°Û)¿«FnØPrµùó½ÖX‹ðDä’‰°¡òTàòC ÇÂÔË#K9²é?"K‡"K/FR²:³½Õ¯©Æ+>Mí£eÕA¶{|ZH5>‰Ù b¶’$ñÀåâª?½Å§VýF ³E÷‡}¼_oB|™VÖïõ 7>ͶŒ€í¥ÀŠ"à/éˆKbVF…æóåšÏ¢`ȤÁ¨ªú}N—+äõTV¯ÕÐæ£Ü±”ÅŽ1ìe†#vŒÚj¥ƒ j¯ç ÞÝ—Œº°;±AkˆÔ  YgŒvó4Ÿ1ï¶÷Ò½ž>Ú½$hŒ(ë#, >ƒ ³«·¼Ëç Y§¥”ï»4Ü)uz«j uý>Õx¨:x©×eÝC!ÞÔ멬 º˜µæïV­4j‚± xSJ/`’Öœ•æPšߚ ·©Æm®Ö¢·…¹Xãu5«]{ÇW”>ï㠿ª/ j.ãj§Šø2{Ç@¯Yý«òRµür×Ó›/^?žO=÷ýÇD”V¨bêÕ‹©IUÓ—°þ’'@íø¤â•wJf9eª‚~õß‹¨sEfÐÈ,ш֫(ºaTä€Ç“Ñ€¬ŽO³°)@Ðq9 §?yŠ©ÜÈpviÕ4\'Ú­Çhœ^íüC«£4=L{Œ,-ëÈ/ë¿¥{õ ÒŒ:çm#à|¨WP“ {°d„=³µ0íÔ£ÔmTÐ-O]ÒãNïó½ZŒŠe•cÏwd…3 ü#œ»T€ ¸ë3à'd1­ÑÞqf>üòˆˆÑ"î£eQ>î0gMƒ?JeŒB*Ð{ ãBèAî~ø³Èý¥JØöÎI—áÞèÙ bb„Fr$8÷¿Æ÷f¸÷Æ“wbûûlú ‹lß@À¾ÂHÚ6l×§PM¯©,ŠÁ7aCžªvnc_—ªsn©âÞóFaxb´~º TÁ §Ãµ3L9'€K.ˆJáÓ§J½•²Œ:š äÂæO3x­Ñ‡Ð·ë¹8§DÆ9ŸXV[†|Š;œƒ—µ÷è•A•*Ãù‹—èÎÑ~_á\ØsX…á_ÄÏ ¨b± ˜‚|­f²>ÕCØï{Qíz^MqÚ"âÎEÜTVï'ªØ¹,cx1G) ñIEÎïqÏàXô1#‘ÿ†{÷$«$Ø÷ðQ0Ø–a¼½Ãâw2L9à3`Ø%zurþ.«é(ç,ç ç'çç|4qÙÀ¶ó´ ÊæÝ:ççv’ÝG cíÛ=+ø¾œ_ƒy°,×'êù ¶Ñõ òï¿rŸMƒ™k›ë+Él³ëÃÿÌsôIäGÜ ¹¸õˆ~À5©®£¯ /¸µé²s’g»ÿ!?Ÿk‹ëb0ëYÈ—EÎõ t ž\'Ÿaô®ï>Éÿý±K2z$'άдfªå~àÖ3êíeî[Ü;úãŸÌ>æÞ”Œ×"×SŸ­%ˆg6ò+×Q ¦ÑH<ýSýA(âÛú8zÇ8FïˆzZ›ì»xzÌ9ëö]œÁñÐ×ÐQ7‡¸çÆœÇú{îFúŸei<÷^í4ŽïªÕïÐ[n¿‰:Ê¡9,Ïóªýç2-PTÊç*‹~Àsj…sEùé›jTb]žÁö¨Bêp÷Í£råwþªžs^—7i£»Ž½j+U)SžÃx dAu¬SóÑ.µÀÙ ¥ —¼J¡þ³X†×1çÖôŸ©VËwî žÞtc×_ÛŽß³ÝyÌSƒûÿ{ºPëYÔjŒvn¹¾jv>výŲͬËÓèÖî£UF!¥3\™¤¿Ø|Å5ä~Ÿ S¿ŸÙWÆD’ú0ú‰w‘÷eŒP£ñ3œƒ³ô<*ñæSŠÖå¼âöþU㛹^ öcTéÖÖç¦Ì¥ È›ç]Ì…ÿN:ïj·œwû¿Q`î}u<Íí‹òð· kÛ‹jÌ/`¨L|³Þ¤œÓ W⮇pÞ{Îv>Ë­Q>{iâ[ç~ù›Ãµxg–áœ'Q°ÁýæUÐ(u =à5ZžÌéÁœÌq}ýü:rv!¿;ÐÏSQC+TÔ9Ïý=ê<£ð”a˜ [Fùf¡ÏP zß1 H–z¹öˆêñË OL¬AEû· [ï~{brŒºvÞ×ÃrKÉñ@ M¬13®}ÞùÿòÖ6Š`Kì““}ûdf^’“ñ‚Ñn*íX«•–¾#Sì€öÞ%f›ØŽÁÑ8fKKÍñÀóíP“õ†È§ú”·]5³±£q:¶ÎLXÔ&f$¹<:ÒÌ.¦S 6[bÕˆ1tb’ïZ6 M„-K“–XG›0“*­ÖëEfOÙ¯xnJ«ewŽy#‚éÍÍxI›ê’ ¶ù~MD6üÒºšd]iƒð~ûóD‡8 C¨·Ë~ýªy¸æR“¹¢-cÍ:Vñ¤eî+i÷âÃñÞ°Z#˜µ5}ú ë‡Pµ9Ô¡{Ù-ô]vvK§YЍ±v“¹¶uÛVeM›ZͬªO¸JpÏeeíìFz¶´ÛÖÓ5¼ ŠÊ¡èUûªYÚ³ÀÒ„{#r†¼ áαƒ#@ÙvÐM±ƒ_Ýg¶ƒ[¨ødÊáàÇ]6ÛÁ4ÄúX‚ŽØA?¨ÁÞ Úïê?¶ƒV»x‘‚ìñ}»;ˆÙmvw'h‘ü"haB~®šew¯´:qÿW"k‹CÌÛÁtëoAÓºÞa'|ô/Æ«=(ªóŠßw÷>öîëîƒËÂ]ؽ»,0,q°Ë²@ÌA;ìê ‰JÄÖAD¦ÖD 1 1ŠK;VдvÒ±1Ô˜ ¤3úGÚ™f2­ý#Nü':ö1#iêi„ž{—Ö™ÖNsßãœß=÷œïœïÜsaŦ×3 ÷›ÞÎéÞ9ŸùDœJ¨œ·*îüÐr"G¾ÿ>ìÿIÀ±õ?¸þxTmñ,ë¼Ì:ßfUD¬)R)ºÌ¦Vö¼ôþX{Gz^<]¡ –óâ±´«Ýµ¥cžÜ"Ÿ4GçÉM¥‹ƒŽÛÉ­æg:Ú¬5+rTAßÊÀnRVŠn¨°§U>Kn 2øM†#ø¬ƒ QaW2Òœª4Ôµ"´§*ÍIÚDŠCðxTyú¬Š£O  ™ãàP,íVpS‰Dstª7¡`¦Ê€˜J”©¯{ë{1þ—aß˼F÷ˆ?”Èh<Œê+x0{ôU{Çt‹ÜÒüz¡þ¢ÌžSg P*ŸE-Í;=Í]Ñÿƒì"Îo‰œ€5]A>.@þÇ¿=ôqÇŽHFJsO{"®cŠC‘xÓ–L?Ct<Äo—$Ç#¢°§A fý©†«Òúué|ñ4už …ì>¡û}š ·‚^-Û¥ ÂT´ȆÖO4*,¨”–Ȧ–}pµ,-à +,ÈfØ„³µØÚ¿õ±—Êï÷ ¬ 3ð”&Í;Ó.¸Ã¯w¥]žhš™{…âöD‘R!Ð jh ¶VSØÈ°ç &´æ<…xBÁr–¡iN 5 ¼ŒÑî½yBÝ·V¸WÿÌýz³¥Ö_¿… Qîò²r³löÊfYƒ¾qQW¿ ÓèÈÿ‹0–?Åð™×!9œEÑòÌÁuè$º‰à/¬4× öö-¢ÐbyY°²:P!fÙ»pc£¯¤îI_IÆÒHƒßn„ S 7ÑFHe=Ó,ÇÍa[X‹ÔÚ 3 *. (Žehé9ÌR<¢(­Ö„Ö!rN©1W£s`0š#§´ZßáO8ÇŸÜÛ糃9ØlÉ®ƒBõ0Y´ÔÓ«|…÷ËËd̰EÁ†‘ªŸ]Ôà곑¥1ÍSûZkRó_ rÝ Õ§´ 9ÐdØk¢2õm½&Sá¢NRç¨w©+Ô×#å TŽ#7w׆õ4e£iŠ"t®CX€Ï ›µÒHp`|óÂ:Lô”ƒÎÕˆÄ4GÄYA `‚vv§H–º—É5B²ž2O–Qž²Šþ€ô_1æáÞúÐ⢹¶ì1®ò û¾Àwåe(éeå V««* =n†õ4`uéY#f1eV3øô±·«Üßé W×|pà䛢ãøÝ¥3ƒƒJM÷6'¶íxáµ ?ã`kÍšs\º n@ýËÕèi ªFCaÑFe$å5øü•T­?JÅü|Þ~eá@¸Âe鲋Å[EoÒaÝu¯á98'‡3MÈܽb$¯“OÊ”SöÃ`½Ü%ï‘ù=üKÜbâ "Tcø…? ·“}¢Fú“Cɸ/y{Q1ƒ)Œ†ÇY61PQmY1Ô]TXU„8Ë«Dš2µ(K¡œ ›ò-Ýüõù5å±™¡z¯½1¦XGͦ²-™‰7úY ν”Üwª«‘·2í¾Ûÿyô~Õýžo¢a¢úíõQ¯ÝníUÑ·l@£ád2Êã:ÛÛZpJä|xy#\•Ý "¨ :ƒ¡ L¹ù”.þIìnìA cc¦XM¬5Ö#b©rÙ´{º±6Ò‡¸ßq7¸[Üß¹/9RËÙ¸f.Ä}Ÿ{#9чõQCÕÅ÷M\®×Ç.ÜåZ„o‹ÆHù©j„£~E-R·)ÚOŠ’6ÄPjèÿö :&ÿ[b–©µü&µ¤Ä-òJîKÅIŠÓR'«¶,ÈH@B .¤…©‚ EB”‚"%šýúÇ„òü(© ˜‚H¸­€ M6a9Ó‰I7ov[¥œU3„œß¾W ûxM)¤xOP¥Óy¨§Òç&F.ñÙ«Òïž~fýǯí2hAŠ™Â­ Fcî8%í_zíhYóŸ®ßf›Ü& áQ§Àú„Pªäu 8šGÚ?9ào;°þõJ¼£’_Ž7X¾^ãê›ÜZëâ4Ã?º{yüоg“÷ˆÝ„Qv\ÓÞÉÐä¥ðåìRøìâÍðGÙO·³wÃ÷²ÿodUŠ0žVeËÂåÙšpC¶5Èö†wd¿V貎¬7ÊÆ³'²$óé8pŽïÿå8ÖÂól«Ê29‘n tv´3pÛŠkæ"oÁ5Y,×ĺžÕÑÑàª5=žI_I_O/§¿HS|ÚšÑ <žS¥4V‹Û"Z0Ë"xSv¥ôÞ”¨ŸÖˆ³`vynæÐêÙÔËÓs8G.€……gÙçÙSìö ö*û{‡ýŠe¤ t hœe v_+ç«YÈ×î;sŽøhÆwµ7‰ÀÙÜéE í'Oš¬9KÎdº`„cp¾&×{ô£J—Î3ÐÏ?’äI¢²s?¯öm0®ä¥ºú0“Ï|[žM …®åó&)KWLH¤…$*%óG[Œù~¥(Ùj)b÷µ¶N²E,üoÄ~K±H®»2É])e}~Á¯A‰º©×tôø )S%dI W :å"J:émÛÄ™JR,åóÛÏ€¤mN[Us±‰J(¬,žÆº¥D–Ö CÑ*È$FÚ K6ô,·qÂ'tbŠ †•ã" / ÁëFÒ5r•Š•#¹¢DRhô¼ÉŠnÕ:yGÉn“–5BʨÌ$€žÏ€I¨ªõ;™ ‚À•$HA 0¢¦§ûéÞSÝš2­æiÝŽQ:§ŸsÈÉW«Lm½óÌîÞz%ÍÈû&>LOG„9áá²°(|&|-Ð ¡Dp ­BXø«@î|XµÍ™j壹Ñ~Ð<#Önω‘±Èþ‰8Øú\]ÎáÈÙQTBÙ÷ÙÛ,ɲK3’ýfÙeY"7ÂíýB"'ók™Goj(‚|E"¸ô™Ì rtÍX(¡<òŸ õ={ö³‚–-c…“µ[j‰‚E6a.UP̤¢ ÕKrA4I•Òá7x È(…F‰&ÊB´Hí˜Ô;=~B}S!çÛÐèŠ Bá‚‚{$?l–Qt-ZM.¯ 2ZYü¢"X{{K5Á0„²«”*ãñJÝÖ+{Ï6€ñÁ'êxõ „l * C«+†×_Úß„†.ËüÌÛàlÒÚk%ÇÝ6Œe|d¯=þ|€gTVF‰rBAîõÉõÓÊéRR·­¬EžíªŒŒA‰tLBBc ×óÔ¹×ì:‡œ¢+ÑIIÚ8GòüiB‡m©FK€Þ[Ï¡¨Ïf§Ã[Ö_§]ÆB1¨Rb0ö`Àì–›H4å9AqÈ%,FâHÉ/müø5Q!;0qø'Õó®ùÿ]¶±iÜwçw<ÜÜù€0>8b0Ϙ`ÀÆØuìœù)„Ìiˆ»Ôl‘:i¦:Móäªq“6i݇ÅSçdí¤uÑTÍY_¤“ªIÉ›lÒ¬­/¶´R^¬Óì=¥‘ú"Éþö2ièàøŸ¸ß}¾Ÿ¯óu×›žeû²cÙ¹ìZÞ¶Üþ{%¼Yé¤ N>$Óä„ëxG5"O'ÀèèÐP:•. Ã]ÅÑÅ]£»öÐæáÂ0:<\d&'» «`4ÙÇœî]Åë+BXwXëIFƒ0hOOPn0µúc M¥8\êKûßL•ã^¸WW«WoUïVïUÿ^•Uoµä(ó _ÐfU\pW¼Љº:ˆöà÷Ôô~¬ÖeŸ‚™*LN–SiMjò@*}Vñ´ýè=>O](óêÚÜÕËDa­Öpb`õ€:ŒáŒ¨ºŽ\-üÖˆè6ckPᘠðt¨ðã_§Ý„s­ÔÔêm³íØ‚oQÌÂRCgÃ{Ÿ¿´ÿù~ü|¯Aá²jZA+ØÖ~²”{á½¹Z ŽH”»SàNïÆý&–pêc®¤’¥1>³[?ÜÐáUf9s”æ†1üag˾ý9Ë‹®þ†¶&8H$‘TfZtÓ—mI«ŸT"J®§4ì³úD6ímÂHL®5õ«í–Ä[{ q™²wvL0’ŒNÙªi{wÀ„ëÞ,¦)Š¢&™TAë#ݯøP˜wT;çkÛ£­î>‹è»×ŸÜ—”z%M’NÉäI¾ó<¹"½¢\A®I¯)ð/Qâ:¼³ÉÆG8;ƒÎ¦OU³=N(ÌÚûû«×Œ…äFÔ½á‹ÎOÍsFõ†aθ§8†Ÿ›+‘‚"¨˜ŸSS§Çèúú#ú&}›þ‚–h@g÷'iHóžžù“X­gp|¬Þ8oÈ‘ü£NDÅLÞ/¾©¥–fPüÄ­v,be½³³Áï©ßmµÓnŸîïÑô÷÷d.Ó¸†¦ñ-ùƒ{ýjÄÓê9Wßòõú’3yøøïP…Õ¬ˆŸÀ&"b{áüÖpÈI&çÔ5ä@ÈØÚh X (†Ä%aq9* ñT÷=1ÞÄO µàNäR0$Æ_ iO©´¦Œ©F-㎘H©ž7!@!£tG8¹Œ"{.РÝ1rlézÓŸµc»bÍ.Lˆ‰^L$ÌBÕ²ÓÒHu“ûnõïRÙÕP™‡Ü0*UÖ@ òZˆa¤¢XÝ“©P«0ÐizÆq aYKÛ©Ë#°ñ2NNý ¼ÀP£mŒ¦¹fŒÄ0 ÖÑé¶7F¶=þIë¥N9†;1‚ŒÐ¨\me.<~ðK‡^*gÔ .“ág"„”Ä>g»Š~î`q%Þ¢µÆ Oɹ¯*ºÜö'_aR‡¤WòÏäìï-r¬u¬y×|kAÙ~•|›z_ù¾j‰¾Êü°a©ñM÷ž+Á·C—;/EéAÍ;(G¡$½N^Ž.“?m_‰’%óñqÌÐ:üþ2«Õ°¬ö5ö.‹Ð¬‰u³ 6ÃJýZãÍð÷?Er’˜„‡1ɹN¡ÖyQ1\ò5ò8ÿµM6Ú¬e;ü˜^5“‰Ü ‘U乤Ò=ó™èõqóbÄ=yOÍËå×á˜1Öá&I̬Wëð0_S´­™„3Qq¦®œ p[Ùåµp D€‰íΊ¥ÖCài5¢3ýÏT‰£åYFÑï[ã'›­m4¦pYö7¨žžîÁWQªU«€N9º½|†qqR"=xþË ‹$FA Á^Í´Jêj± šÃ­œm¶ïv`ÄÍœÈÓšíÑöd;rÅÏTâ՟퉒—˜fþÂp¥]¦iŠjñê­?ùJÖ'µHÆ€9ùáØé@4Ÿ´";‡ãn·@IN­Ñ”³9M6›‹wwOò‚†ç…¬†ïΩ…¸3J6UT¸6::7Bss>D1æ0Äxý< $…9aUøµ°&|#È ¡O@º…8:1žû~îxî\n)'Åsý9$§Q£Ö,?nÏeFÍ'ùyþ3þwü¿xÙx~¥“*<˜Mg'²‹Ùßd¥Ùì*èKãxVÇëày¢fCÏÞ$RÞuüËZ=uÅj޽YFÙºgCǾ_—í-Åù?ØljM30¹*’|Eæüµæ'^¾º×{!·)0qDÔm1¶ ¢àj_øu›ÂŒÖ%FAp£A˜›K×i+ó‹îÙ è÷ªkJ·P Îèš)t[Ïæ›þÃt™Æ¶mŸaœR¤$Ї$J¤ZeË4%ê°uزb“²å#–_YÓ(Qb/qÒ$F’-X[{IšeK CÒ¢M†û 膭ëÐzœ(ò¡é>®Àº X‡î@»-Rìð² ƒíý)Úí Hâ!Âû>ïóþž¬<0|åF×—Lº¿Ó&“¾1©æî>ãÍ~åñÞT{ ¥lì¸ E9'îÂ;nï¼½ùÅûãq]“SR¯=4uþÊa0òçSÚ€ÓfsP¼‹ æ¤"Rvßæn}ï©}ÝeMÇÑ™kù ýŒÇGÚ°µ¾…ب­c‚Ÿ!'1{Ãæþ ƒd6:³vÙ/S¶À?zé˜É-{¶>ÄN`AdYãœgq79Mγø`>roüÞv% üÌñ¢{œ­Åkí5¥Ö1¦îÎNÌLÌR˜›î¡K*r™ˆDŽ+¬‹eh—ÍÉu$SÓ3*NŽ›WPŸ¢ ©½aG¯¿]Õ*A]-Yˆk视Ư¶’° ˜OiS²Ê 2­UžT.+Ï+/+?QÞTÞŠdÜÊ%U”5pÄð:ççœH JåLY/cåw¹55=L.ÿµ©&!‡èïCœÑÏCt<ô|®k9Á··hò³·ÔÌbMâð!M¬– ŸI²&ûkyð‚©ˆ@Кì¼Í»öÏöW·e'<Ø!'“®›¨¼È ·äºÐ‘E‰´ÇáéHèiÎæJIS¬‹¤HñµMÈ ÏCJœ8}"p0–Vèë³{_:0Èwl^×಻U£”#°1EÔó×Ãñˆà@ßñ'f§Šˆú~¼ôÜÍ(̹Á–š—v‘.åªè÷¹™ö„äâÇøÓ´ Øiѯ{®g.G:O.¢ó«^¥ê™êsŠA–ޤõRñ6èEG¶>F_ÅòH9m¨5g­í*w5dƒ$Ozczv„vMr“¡á˜ó÷lðF‹ Yî:"")ðº°×½*º|ŸÜ€ $Yj΀h{Ü@2°—f¸{hZtõ‡ «A `´UÌ&jZkÝ]sùC;G›õ‡øÐC÷³\´StkÇØ·h’S2z…#Y[¾v±Ê·eÔDEòÓè×(Ò®Û]ÉÉÍŸNyéDÏQðNœÞ''SùMCvwFd81¶~kóáÄ@faŽ<%!ÉáôpÖ&µH’$K1©UèödøÜ„¡QK%ÓÉŒšÕ[tI—õ˜ÞZSk‰áÉ.R”Šk#6V‘DY‡‚¸nì^^Ž«¢×ÛÀU ƒÐ mnRmZ(&˜CXTfÚhsT¬“î~Ì À´â&Á†òèG‹vEýtØð;~ÐÁÚŽÙ£a'í¹Žµ½èvÌ‹;¢J‡óGNO­¾¨Zº¹Ò”ùÍ©ŽÂü+C]þø‰^ùÚ@} ìç»HbªÞÏ¢lñïÍû3Jo׿>‚¸cw]˜è¶9í‘ßu{ÏŒæÅäžùãú[/T|ôÆL¼ú§?ú£½y½õ½ÛÉDöþ‰­? +˜Š$!Å|ň‘A¦ ­gë'²ç³ßÌþºí‘ò·Ž$þY"-R¬—f5IC5ë®Çb•#©OXÍ_g!Ÿ¯c«èœ`6¤ÏýÍÆyåKõ¦5m\0ÏÍŠ—Ìr‰#¶EUn1ËNmM›i¦4Sù,`€Â›fd׬ûß娿÷Ä ½^†b#OŽMâ-\$>Qs¶Ž´wŽ•äYfy2Z÷AΊùÃñþjœ8Шª¢“ËïÍ£g³ú™ìÕÔpÿÙ)GDšéï>,Úã1ª{bVki—ŠÏÌ#¶5°iÇ(è5ä ò4ò†!óý“Ëh©Ph ‹>Y,,ÖK'ˇ¡“Î.–ðÇ8,ÕO3a)Ñn-Ć¥0?Vˆ…z…}jŽ££KgÛðî\ŽÉ8fësãf¦ŒY «‰ÙØ5¨Ù9M[Z>y½\^Zn™æÇûÞ,¯†šRfÃŒ6 ›en&"+ð@q7ÌZÃ_}Π!ì`"Txì8¿ÉŒ°ͯè¡À#Ô,öj˜!Æâ`­`-Kò¦à¿%ÛS_;{âÞ8ïðOtÅ£” OªbG2—““žŒÓáÆìn»áXñ_épçâ·÷ìÊÛîÔ®õ¹÷«eðý|›gŠÓ ª6s®kó»= 7ãMêZýNÐcd_H ž*•1ª³?LRl ¶‹QZù±ø®žÙsQžáƒnФ ¥q[ߨó[H˜ÿBV£Áâ`n_º&óqZèj‰hr¬8"ôJñÂT±\Ûüýt¢ã‡9Á†ãÖ+ù¢ÝÝ=!/ß+‰@0i’ìèÖ{Ø<ÞÕñÀ8„À+Áª419q·@ é’”ê¹Ó0*ƒUÛNXÒKÚƒã!Ý74¤÷ôÓlçÊÈ}ðŽdëñ\ìv ½©ÔËa25ÏòŸá'ùK<ÎókèdžäTuCß«Ïé·ô×õ_éëºÑßÖÑ)èú»ãÎm…9!¹üÓ¡0vYð°n1'¾M– dÎ›Š l»  X´Ù·mx0•°³’ÌÓUeÍ£Ù_´© xÛœ\KJ;xÉöj›Ë‡ËL0½ ¹ƒ×ç*zn÷—¿s&¥ø"Ñ/ô¸8¹2]‰„oñâµÈ³A:ð?ªË>¶‰ûŒã÷»7Ûgûîì»óù-¾‹}vÇÄvìØ‡Äò†“‚¸j %”òÒ‚Sè [[*^ÆD5Ô º•V‚©Œ©¨¢ ¶m*šº÷ªeÓZÔu*b´*Ò 6Ö¶„ýÎNB«œœ³Ë÷½Ï÷ù<¼‹c—“ðµ°6G3A àzYylö¯üa¨½Tžšûý¯TAjd|Ž0ÛZºùö™ˆÅwà—ѹ»d'Ë8"çìv¬ywŒµÙ13캑»×Ñ1ü6bC È«Z¶ÀžcyV𤑃o¹?Í_ä1žÏ©mJ<ÞãW”ŠšãU5GýWÂÀ> `üy0ø–}F$Ù6ÐÏ5{ËLšRs@Éù1•<æ5'‚ôh¸êU·«§U\U¯kF7b¨Ã[NFw>W*³‹ç†ß:kàV–V…i”®ßúš£aµÞcÀ|+š\­n`‡©{6ÇÕ²¯f”`"àLȱ&Š»–4çVü"#ŠªÉÛÙçòÒVÉj¶ ¡‰pKCuy&*ª?ñP$~2”MHÍ\lnó8CqûC‰ÎäÛ¿'’ösiÉjã+™ç¢²Ïµâˆû$ïò²»—pÑ[r;iÇ=¢ÐΦØ4Ûá̼c7uL€²¹l§ÆWOçÞîú­ýÜ»Úß:?éú¨ûîÄÍ­´¯Ó×åëöeï„ìwÆ»âÝ­…ÎBW¡»PмšOók Ëš4ZÖ¶Šˆˆy14°$€Hˆl.ö/Ó¬ˆWÅK âøÙÒ(_*V¬;¾Eónw»CÄð+˜Æp°e§ƒlI_@#Ðáß ç©"•¼^G" ýMU}øÁ›‚pÕ;,òQ`=5ŠŽŽ~¼c1Òj<O é0ÆÛ, zǬ¡·fŸª15 Ëù[ÈÕ!«Öõ<ÛžMA³`i‚ÏHV¬«^S½Gð“yÆG£kþOîUë= YnžÊ¦V*ÿ²<³-lq^Ø’"°÷܇ =jø×3.*ª ÍêH$3è0™Â6ÆÇÓ±˜*îybfmr)+áaq£‹ö9D?Ó%½Ø©u[xEL,mzeo¹¯±Qëü§ø ¯ä Ïíø¤j¥9ö€Þ•³ëNÛ‡†[J±P<˜Øœ é° Þ0°yÉöUÛ_5K±ý=g±š=û}Ï÷‡^>â÷8\ùõ—L¬qMÄáu5MÁ»_¼ûús"…Ä‘—µÈ•$€ÿÇ‹FY ƒ•`ÀP¢ív' š>«DyE‰Ö‚¦@GXQ†¶nðšpÌÈ%0Q + ESV*•ÝÊå¸òŠ2­|¨ÜPìˆrIAY(ÊljotéÂv벎šDÖ5€…¸Vaïå`È"idJ õEËúy[„1q Cöão°½…˜„~OÑCB#Þ˜éæ­¶¦%ƒ¾Îl(ètžJvT&E”v´ßBOàoÌÚôþš /‹Eó÷ã Ø¶œ‹‰Œ“ŽƒGvýò/c’±³Æ\ªÜ½†=‰å‘2X©'¸^[?7è.z‹¡µCesâ ø$Vö·HmRBJJíRÊß%u‡‹i[ªØoë—WËÒæ¡ZþÚír¤uC¥¡ƒ2qyÁóB³Z–£=1m¹hA-DOĤdÿü÷ó/æ—7¹óqxŠåÏ£×µ«ËzR×ôUú„¾K߯ÓOéèÿÑm¤îÒ÷é—t\7„tÜØ>…9:dD9U…°‘Â"…¿Ýóكш¶ZYhå¸HLU*U(NóHÖ÷³ºÕ2¯‡[¯h0(ñ^øÐ& |ž^Ø`j"ÒX ’6lO°v¸ƒæ½”çÌdåò@û’`7%œÄMê®i0[5»Ý©çUÎL[Ya¨¼/ºuÔæ¬vN¹J"ú†™< @tߘ`NÎæö”BÇRK)ËáÛQ)ÜàtD_ûÜNÚlg€º¶7,ð¶Ž ë`,è°3öØö½g^÷Û1ÂL˜ý=ÊÀ†Ÿ‚sô2–BX¤¹©ýZ¼íþ¢áßq(pB<ú§kV¼¸*]•ÍkÅ’ô¸EÚ>åÚ8â2÷¡Ë]#bŸÔ'”hq“Rò‹7à%óKâKîcÒ1/úœ&à€Ǩ!ðüÀ `Ðxé5^rÆK&܇œDî"8ƒìBPÙ‰L#D~«ìwÇÆ8Y Q Cׯդq! 2 Hãy²_TÖWÖ/ÕÙêˆù7?š­B£®Âöõ,ìJðH-Dêڵћq.Š^žûüG«&G»igÇG6Þù_k"ž(½õ嵇ïÓPõúÜŸ|v͵a‡»ýž;çÚbm:8ñX4Ù¿ûÝ3:wåÎWØD6#Ï"ïk]ò”¼û(rtòèæ‹½ïm1E"²¡Š{Ÿx´#E¶ [í¬“DÅLE†''©¶áá á)*ÒÜœm06!}bïw‰§•ŽêL–,>=>`] «ñÜxy}­"éMåõÌÖÏbäyôs…¤¾¢P+5L¡”¥R0Usɪ!“·fÙ[ƦQ¨Ï6ÃjRñoµ¢Œ£n—Æi[Ýg@­ k?óXÓ”ì<q^ø¾Ô<Æx€ÀÓh ¢&£ ]àMðÖ3 )hŠ´‚¦40読µDê-\_23sŸ…;%;KÓ¤•Ý$p¶”Ä+Ä€àì°òa‹Ù²É·ÃÙì´ß£VÒî5ÅV&:r«†ÒÛw<ù?ÙeÛÆYÇñ{îÕ>ŸïÕçóëùìÄ/g;¶{qlì8ñ%nÒ¦qç´iU%7CºŽ¬«Úfãej™2¡ml¬STVbUL]º±¬üQ hƒ CRA  2„D+¶„çÎq*@¶|­s"ÿ^¾Ÿï74©§Ú¢¸‚Ó!¸DRf¾µ]¡>`“íKy#á´¢gfi“Ô¡B6¶vRŠCGíN|p4¹Ï¥ÐãÞexˆ ÊÅÒ‘äçj ŠŠ.–ЕXCÁÐPꙹÆÅ—Oˆiž?°ywhu:8cÍy -½–0ÊkVþùðYÑ7 †¦Šš_ÏE•p5 d6óoĉó–@à·aG[½Úú}3 òS3Œ8þ&ÓŒ>Ç<%sL.ºÀ,D—˜¥(Õ´5ðu3àvyÜn—KsGq¡?ªÅ\nš­+-Û8½h²¡yä ) &‚CÝØó:9Ÿpù×Ъ©yáV|~ß®ÌWÃè»õ†q¬› û0‚—ÞV|@£2bó\囤Ms2ïŸ%œ²'üp,NXs|ßÖûØel™…4;9¹DǦs‚›ðì—[ÁV¨¥¶û[®H#É7°‘QSÃc5R£ JQ3MC ‚ÁÁà =¬·k1O­d¹Ýœñ4›3MyFÐk±Äˆ“)›£Ú¸"‘l?™ŠXî´\(¬2¤f Ô€oË@Wê[ƒž5´‡Ž%t¬6#ÈØaª¬åkõûj'jÖ¨ÚX4y²y¨Ùi>Ö|ªùë&Ù|ïtëm ‰°+¶õìN|¦ŽtA©ü·ÍزdYÏžµn±iu² Çä=¯i°7v(jwS1ì÷Ê=§)Yе’ã¶HY©q¨žÖ’1Å¥ñ—f’š0fàÉÓ ý|Ã_ž˜ I #W¯ EªIÑ­–ëýnYÔ¿H¢âÈù_~&b%Š×¯LJèïÙz´?@SêwrJˆ—ûÉÐÒ‡¿ “xâÔ´3ùé“cW0¾þÂf¡B¼Xò³ÄÑURŒ˜¢iÏäw4Á{DÞ7ؾ¬²œƒG¶þˆ9±q¨?Ϙ@:®¦±2‚¢å" YQ,{ŠÅrœ„bsõõ‘Ÿ¤×Ú´<Í—i¬µˆáS€KER­–J­ã&íD‹|Ñ,bÅâxáµ±^Økgl«Ó>³!X¡ÏjTý0Ñõ3’½K]‚>>m£Ñ+?T©âNsÐÚ‹]ý²Víûš³ú‰ü@0ëI̧(ÖK¹ˆ±Ïj£­„—S|¢GÖ÷8[÷„¾“³œ“rzƒª _ûx>¯g.þé~9Uö"Òî3ODzÅÇó_q×ÊÅ›w÷Å]^Ÿ> è¿dÃ"ãìƒ5·þ†?†å‘‡;¦y=úï(:7?ßfšå¸#ý MÇÇæ̱þX4Ú0¡ãÐLÆÑh›;â÷pÑ# zÁŒ;:ªq¼ˆTÑÄj†T¬£.­ªä´uœ€ÇC®ã8†¨S×η‚Smµrò?NA0˜[,¾[úÒí@rZ®Ãr¹%äÞ¹½óË­C*´­‹Å “­^ôžÿ·0ÝóæMŠåk5ûh½8àƒ­Y+ÛfÐbÜ›DlãšJlóÄŒÒ[žm¤'wÚeÑ¿G d¹Ë|8Iø§î%<øÕo˜äåX&³>ê<$ #¸ÂOñµ¾¤^_‘?~v,¨²¬V\¬œb‚ö²Åûž}" I«à¨Ûáç]†ßŸ/9îso¶*zª8ÝϼÅRyŽõ’ò;cÕÁWUÅ®H’ÔWüdräÏ ÷«g³Mĵ¹Cþ‡ýª‰i"ˆÂßî¶Ë¶.»­-–¥µj"X mQ@i ÀŸÐFAQD%þ@L8¨ñ¢‰ ‰žŒFÃAMŒ‰zR/r2<˜c4ÞüÃhôBëÛîÔ¨1Lßä›y3ûvfç}»³ïU[L'è=µÇÞ;sM¹ó ú‚zK¥§xq$ûâ*©áfe¿Ð×F§l¢)!±-´ãtp×Èøü¾p[ÇÿîÐ@˜o(«àjŠÖ<Çyéì{wÇòÐÍ×ñÞV…a·¹Yji‰ÚrE‡#*ÖÄäzg}EX:Ê%ƒ&Ñ[ƒY—Ȉb´#u”˜¢ÿÖ¶·êª–¨V˜¥›TV™ôAw€büÊŠT¶Å ¥L:¨'V¾Ë¬©E¬à¡á1§p?ôÌtµöïÆ ‹–,-.Ñ:eU£fúb«ÑØÔŒu-´¶¡=Ú 7uvaËÖ¹×þ'¢ÃEªÝp‘ÆR]J{¨FÚ@ŠnÄу>ôc?c8™$[ÅÆO6a²‰j6Û±{0€A %“ÉW³‰¹„\ŸœœÕB@¯6‡T3ÚŽPQuž´e ã:äÓ3«: 1MçÈb@Óu¤_Ðtžôñp(ŠD¼MñÁøÞ};|kÆûû¶ÿÎ(­J!BÅKž“—âØ‹}´êò`ùîyXŸÝÖ‡µ8Hý~bd®yÿÜ–<ÇŽâ#êðzò” e[w²OÕoGæ,]t¤)½t‹^v>‘0-?ÓUO‚ ½?ÃM‹GY“Ü 5Ö~þÃDàr·\÷yj6x] ¥Ú#á{‰ÕSG B–ò6(<¦fþ&ÀñÜ‹F endstream endobj 319 0 obj << /Type /FontDescriptor /Ascent 891 /CapHeight 0 /Descent -216 /Flags 34 /FontBBox [ -558 -307 2000 1026 ] /FontName /BABDEC+TimesNewRomanPS-BoldMT /ItalicAngle 0 /StemV 133 /FontFile2 320 0 R >> endobj 320 0 obj << /Filter /FlateDecode /Length 27724 /Length1 47524 >> stream H‰\U tMWþþ½Ï¹7‚i$"¸q%‚h<âÕ$ÜD¼cF‹`%‘„ Ñ Ë{¨ SÁ4ª”N©0º&WñVLuÚša,,‚ÔÄ#ef•ÎhrÏ|‰®i;ç_g­ýø÷¿¿ÿõm€æxÉc~Ùkêˆ ‡ƒ¹::#7=¯rhëÀ"@Š3æç;Ò jª¹wðòš–7=÷Ó¤Ü^sͼ:=gÑ´‚9¥@ÿ2 mOvVzfÅœè1´—Ã3}²¹àg´zøã¼SvnþÂIÿônÅyžózFºJ½É½­™œGä¦/Ìó9æçÊê¨ï˜ž›5dFGàÐ8âÙ•÷ú¼|âæw(ªa?onVÞ¬¢±@/ ¥Ûü:˜#ÿ`½më6bµj<í:sœž™V•ö£µN/þ¿P¬B'Ô`Nb ¾R ò2&À@´’~!¾€)Þ‡#  Ç7Ò%艒ˆŠ1؆ŽÖˆÇ;Ø.C­ûXJ™½<ý±Ä¡3FJ’u c‘lâÀ¼‡÷Ÿã-Në&-ÌÃoqW`!›Íí´’Œ_a¶u“qIRd’Œa˜eØŒ8ŽjyKN¦•†hLÅ\±‹Ÿ„ëëcĘW›°ÎZáKý´úHu3­o‡C¬lFÔ½)³ñâ†J´Dñ®)XŠNŒIXCߎÈ)Ñ>V1½é‹ ,G•,”S*ļj>±£ý‹"ÒBã3œÁCZK”q:×k†À ÝÀ›VáMü™‘;M9+-$D†ÑògrSnëÙú-ÿµx†K¸Ìe*V˜½êWXFãhcÆ#ŸH˜ÄÉ$žÝ¦¨ej¹>¨oáÆc+Æ:"©[€=ôë*ñwæ+QFɵLï7ß´–o$²éÅ*ìÂa<SšH3yIÒ[úÒ³%rJn«vÊ©&詺Ä\g-²Ö#„µ2Y<9+±‡P;xˆZ âÉHžŒ•dY/oËYU¡ÇëÉz“gl2ö§:³¥yÚsÉSŨ7ØéQ”)˜†ÅŒuå ®‰–¶Òž–ÉpZJ•i²TŠä]Ù)»å œ“‹r_ËT Z§6ª£ê/ªB]ÔítWíÒêr#ĸfü`O¯oç9éyl5µºY½­"k›uݪmÌB0+>CX]³È«P„wñc^Šó¸Ìº»Õ(ÕxÂü 6VS"ê(Né,ôn¼LR(¤X>—ÛR-u ª™êHéªú¨áj²*PTöÖN¯ê÷ô×ú¹±ÈìEÙk0ŸØªí¡^åu[ëozà™áÙäÙjE³m¬²•ÙjìÞö>ödû8ûûŸìGí7ì–WgÖÓ(¢ï‚Ÿ¾ 2ɈTEb©2ú}Båë¯ÔFÙû3 ˜…D‰TU¦«–é;úU®ÆíAd±rC¹Yiø›58§‚ð-ùp£NW'Ô(}ôcµQNÖYDœ;Õ-eW%ÔxÈl¤âUiƒ¯á1ã_a2¦‰ê¦ìUŸ«á¬ä«(VG±Û‘%}‰.ðïÈa탬»å¸ˆG¨ú ­Y?XÅÚÕ|[fè°ŒµÎ©.ÖCvýmYëú9kÿ5-‘Ø»Ìúe‰’†Çh‹Kd¾öØÊªýö³¿4:±ƒžâ°ŽBŠQÅœGÖÿÕã2óõJy¦â™Î€FæÓÀÆäàÍäªõA +,ÒØÑq^øê˜•¶kxoãˆöG¨Þ¥ÞP–þÂpà÷¨Ò#yëoÈOÁEK¹˜A?Ö=O1-ÌD bdª¤ÀÅ$´·r‰|7¹(Κlm1'šÝpAFŠ?N’½ÅMfO-5Kهב$k±ß“‰S|W%Tz±šjÍùf‘¹Ç,5O˜çm=±]»•Y¼ƒïøj8$ƒ±x€ïYëƒÙ=ìŸx¢Hâ–£&êã"AÈ#†“·3)ÌäH–}|“¢_J—.Ç7èÄ×u0{´˜çÒX>h‡~æ]QˆðŒ¶bÔ }\Zó5ôaUãË>HæE úQƒhÏPZÛK.K6wÅÅ‹‹}eÐÀýûÅôŽêÝ«gÈ—»GtëÚ%¼sXh'gÇG‡öí‚Ûµ híÿ’_«–¾-|š7kêÝÄËn3 ­ ÎÄ4‡;,Ím„9“’º7Ìé\HÿÙBšÛÁ¥Ä_ê¸ijŽ_jÆQsÚÿiƽЌûŸ¦ø:b`÷G‚Óá>ïr:Ê$eìŽ×»œîÚÆñ¨ÆqQã¸9Ç!!<àHÌv9Ü’æHp'ÎÏ.LHsÑܾ¦ÞCœC²¼»G`ŸwS›räpæí“€W¤q úïSðjNPî §+ÁÝÆéj@àÖ¡ é™îä±\mCB&þ—õjâºÂg;»¦ ^›˜‡ a–Á6öÚ@xįP¯m°ÍËÈ®KÛõ X4P ZJC„LÓ5!-"(jú0m;QbEŽ’öêÊ(M5I ¤Jª*U<ýÎÝ™em¬B«">Ÿ{ϹsÏýî9³ÅE–i7Ú,2*­ôB±¥E,¯ØFßΧ¡£zÑÙ; ¶xÈßat´nŽZJkŒ÷Èaß*kúwß›q»‹Å3#ÑéÖŬž±]ç®iÖ­Ó ÑTkÿÆbXsåÜš¸Yƒ­{Äú&»É‡bQK:„-u> Ÿ*q¾-F5kâ;t+ͨ4¶™;⸚lÓ¢Æ}Áììð9ûÊ®ÖÍæ¨´Vä±ÖªYý÷‘Ù¸ïÅ™a}æXKqQ #Øþ)éNÃ?9µ±%i-1œ[õÉÈJì‘Q BXz»O¢ÎTʶ”’Ù^Šaø“0ËêÀl·Ò"q3PÎzžoyr†n~F`€qóÆXM«£ÑrŸ7™'IªÁî¶­PÈ*,dŠx#¸SøøeÑ_V\´wP~ÖØÐ!>ڀضÆÊ"üÁ _ðÑÁ0µ¡cu7D}Úr(¼0³ä8[†\KÖF¶t»–äô¸&¿Dü%Ëòå%ÿ§¦M­ÞVnIÓþƒyKÂ^ßdÔ7´Dõj3î;yL/a/MÚœ–55Urd§%ç( RnNæNÔo©¹ø¯ Rw z}`¥ÐHzˆ¯NüM ïqÒ ý1Ïâö4ÇM«<4¶_1¦?Æ=¿©Àa5O®on1ÍIcl5È@¦Ycè5fÜl´»Û =`˜çð¹’o»7:hŸ?šcÕôÆpˆmR9Ø*Se¿!õ4ô‡¥ž¦–è¹~võ4GdIŽÄ+cýó`‹žÓ‰ÂB+'µÜÓ¹‡N`ú€ì¦œsa¢naU…BôÛ%:Ÿ«“¨}PNèB‡Å|÷Þàh5= ̓3ù§™Z™Ä¿eQèôÑYu7Y*Ñ|`=~(þHë£F¹Œze–}4úo©Ó|Œ¯D1d ì2ôuÀa`1–ÕÀG®VðÀ ¬QÀëIô¨w7mö¼NÏ& A69h¨ïÒ­Œš€2[Œ†öØò¼Ç¨ãf£¿ã–²D?Oí¢°×¡½ˆ×Ä92!§™Ð±ÿö2¢þ‚žTɾ‰vÖÞŒ¹!å­ƒ\¹úJè×¢_ƒ9…rŸý:ÚUh‡›5¬gï¢|`æÔÃϱ^­€m*öÍ€\dÀž¥äÓóÒ%zò+jùŹ1Fœ{Óí3A®>Mö‘ýKû$—ÙŸoï:¾ÕÞö+Díʪ€ì ^_¾Œ37’{¹çsª`øÈþçz˜¦vP:ú×ágƒç%ZÆ}`Чž„OŸÒ:ØBÚS´ú¥òàØVZ ÿœJµ\JÃùZ0¶ èÜc.tP3îÆœ¬¾OÙ°Íòp‡g886èóýâ|öGðãÆ4MÌ-Á¯ `Ž9ß}†´iÜ´¯ÃöUàë8Wð ì߇cbæcÝ ‡‡I 0÷R0Ÿ}pÁ÷ä"ÁÊîs\O»€­<ëb<ó¤kV£?—ùÁÜÀZ|uw2ÀïÁ±Ä›ù)âXÌÒ5¼-“16‹ß sV¼¼æ#s‹9ãJæ·àýé>'ßyŠÌñ\¥&öAœÜJ‘yÌ3–Ê YHó™³Ì7WŠ7™ð?ß„+“þà}òa©†(—ß*s1)ñN9I9 °æZí9øþmzXͧ:¥“Vª-T«XÈ?£¼Ÿ}S¦äßSÈ;$8ƒ3Ò3ã$ßó ï°´Ã3D/#–¹êezÒP‡å¹ê°äñœ±¯{ÎÈpÛ©r<¤¡„%#ÕößêÿÈWÖþBÓkh¿ÜW¢Þ'ö’¯ _¼>äÚáÜ\Òåë2äpIHæ3òÚ›Ž|Ë‘· ‹ÀÉ|® œŸ¹>pŽV'ùêò2ŸŠ ë]~Žç©ÃÏu?ïäåm¹2âÔÎÝ™üN±—×y³›9?rŽãÉyŽsœ;~¼LÎq†7D¾Œ¹‰w=E°ïsòò°}PäÃ{·ÆÞ£Û{´2»Gûr›½WÞoïLÖT•prYЭ¥¢Ž^ 4·Žz:©ËÉi\w—z*P›uTÔOm9üØ&ê[úÓøŠ7x”2åýˆk>MRKh«r‘eê&ôj1r2ÛvÓ<åÍR ×=ißPž å¢n®¦-JœÊx®2@éžÇ(èù3jÙ~ûc±×+HÖ±ÿÚVZɹÀ³SÔÞN>.â»÷iä÷©”/Æ\Fn¡L>‹ˆAÍqà¹ñZÞë4G-qÐbÎ?ÈÏñà‰E¢6׉5GD>›"ÖÁž M mÕyßBÎä½vRá:Åß ü^–“_‹c>Þ…ðë ¯] b[ Ž®ôMBmi£t¹O’À½YâÛ¯÷Þ'ñwÔã)ø±£›•RP¾&ê+ÛnÉå³òE»SÔû*R~ƒúørü+àÃLZ.·S©lR©š†o³‡Ðþ•*¿Ž#ûíu:rxô?cÞŸÏtØ>Á˜_1÷~´ß¦ˆò2•z~€~.¸úäðOÌûõ*/P¯ Cr»}\¬ÏØ?úw¯Çó€…®d_]Lèó/É?¡¿U·ýLú8¼¯+æñ˜{„Èþ ›£ ò1:œ–ßÄÜ!: =eŸ—pOÒûÀI¿¥ÕBö ¸ÃR°PÕt ²ò`8 \n©Ë‹cô*ä‹~*0ä‹e ûóÀ®-¼×DúT¨³Ï§ö=‹©Œ!ÙçwŒ?EKÕï ×.²Ï3”½È€6ïÖ‡¼ÿWè7aÞ¸¾g>=­>B÷ßÍŸ»Aú#-1L |/g¼Wð7×çÿ×z÷ Üï÷oˆøŸ¦‚C×ðMîµ/IèkÒ;öçÊIÒ‰>e‹xžB]rî ú¡wàʃJ#)ãõh?Äpûãïõn}¬»=.\xS˜¡^Åx`|ß×Mÿæ¾ZcÛ¼Êð¹8N糤M»ôòy¶Û¥nR{_²¦‘|îe”Û´ŠÄʦ&?F¤mЄ"VºÙB€T­–†IÑÖAË4=ß n³Pÿ€nPMÉ*¤¤ÛhJ/l[ʲÑ[ÂsŽí,sBûƒ¬ç}Þ÷œ÷\|ÎùÎûSÂ.ÏXåt{rÜ™ÐDj°NwÛš0—sÓmÜ!! ÖûG¨ÿ+ò`ÒnBühJŸO ¬­_k}L‚Ã{à›Q·Yù×KLY×{åºò”l«Ú«ýÉžóÜýA[bûâËâƒ^žË“ç;s_|äÌoJŸ÷I[Þ%s|>ü&>ü6ð­ÌÔçÿðíüx 8ñ‰ŽƒsN Î*àTŽº ¹êV|¯BnĹvœë)è×Áýà.Ĉrð¯Ê~^ž¼ŠºG²·ÚÊÉS™¼uãá÷L÷3^½ ýÿ Ø|åVÀ H¿{2ØŽú7ÒmÇ¿ þì«ào'Q¶>B¸ú0ðOài ”îïü®‘ùÈMÞ¡ÿ[žáýñŸrú½A‚YÎ}CÜo›sßÙýŸ³o‰›°Z‡Ì»é­)oŸ™Þ8aœÇT —ö#§ôÉSŽï-‹œïîVïtµ­mâtö{ÍÎ!ç;.œüÞ2¶=FÖ벌û£÷È2`wæÝ凎x6±¼¥à:1 ~I ؈±¿‘wx‹¬ï¦/ —F”…ýØù¸‹¥ï½l™í<çž[™Ÿ«ük¦æžÀ^¼GBÀ§à0ðÕɽÆÛc¿Ê‘âË/LŒ¡¯±™rÁ™ï¼íò½Û Û}Œ4M¤lÜZ·Î0“àå+‹ŠeÆQY!ʽ6Î:ÈDGe T «Wg”•«ÒЬ2†"…¸ÞGf#6ŠEW­¬ŠÆèqؔ㢦²”_·k¹=Fãí‡û~þY†êŸò8:?È# ”ÛiáJsZTH!?Àw*—¯ó¯‘ðWøÃÂн=üYÌÔäïX§œß;Â3×èå—øÃd¼.ÀkžîîåÛHÿ$i94#)âIüÍ$–EÇ)Ù§¤ÉO t„ñ~Î㤠u}|™ ~Ž?.æê©þr{_ö‚ñžÕ’,Íe¤"DyŠ¿Œ¿¬F{ÏZºÊ ‘¥|7  ‹zÚyh> mÛ4Œ­ÆÖ cÃÈl 5ïÂ'ÄÏvþ:Iû ÛÐå#+xT) ã(”ïÄJxz°v¥Y—œÙNQRªÜvZE.£¡— 1@Ÿ&´æÍ7Úzøê¯$¬ù dƒ? G–î[é½@Ãrzyœ?®Vb—ZîߤÄÍ¿­OXEÅF »ß³ rÐŒ6¸5á?4‘f€Ã½Ñr¹ wÿ’jü9áªÖ{ùzüõõjµÖ‹¹>5çÏZP6õðÏãläÄ:&¸I ±¬Ý`­ª3Â=|ƒúÄîO‹ÒÛ”r·p¤Ï«°X·V9..U¼<óÝñ 5gž¡ã0Ö©¿T Ix-ö¨ë_‹¡Z­¸ayJpÄà†š¶AZ€. °a# ¸ØHƒœU%n¾ÿi%ž+ñ·Û!G†ò;I°8œòTi ÀPÆ- €¡Çl¤ ´q  H£@>éãU§ ÞaÈ8Ð 6lH%æQ‰ºî%7 ÑIŒu˜u4Fb4Æbí >ÙUñ-’’nUr¡9Ï«]÷jñj'½ÚË^í'^m‹W«óÂ^FÐÔè•|JÉ»ŽÔhz¶¨F;Æp3Ñû„›8z£÷Š`½žäEìv]Z(¢ÐÝ *Ñí R}R8˜›FF¢3=\ ¹Hw¡Ú™¦Ü ÊÁOéI:.‚~Ð5ѺtU´.½/Zk@c’^¤ÿÀ« Ýп‹Ö§Ñ=}›TÈné›d)û8)¢ ð>’ e=]‚b¤Qº=/‚˜=(‚ "ý,Mÿ"¾ÚcÚºÎøùε±Á6\ÛÄ6ÏkãÄßBÁ°/Æ&K=“„öÔ·]Ç„´ûCa*R.¤Ð±d¢W¸‘P4¼çB1Y¸æNS@é×_.{Dá;®4óá‚O1¨hÒsLxÁuRÇGa,rFõ” G݇„çÜÌUðt ýÈa”éKz<¯Ý^ÅãCž;Â^¯C8¡D´Ó§0¾–èÚÑdø=ØŽÏeŠÖx?d9"ÕÐ6uGØß8Gñ+ '°SªÑüHs\Ó«Ù§ à÷¦R³IãДk µ&-¯Í×êµyZ­6G«ÒR-ÑZ˜^]”D‚o¯Âž‘UÊœ§lÄÕ$´”Ãõ®G`Âå`ÊçË‚vAŠpÓìR@³ ¶GAÜYhS@mÜYt5kЃ~ A‰„©‡ˆG1èQ)0ƒ¥\.Ô”p1HªÎ…€”«NaïYg»³ìëYöuÆN¬ó½®¬·nâR,¸¨1âÿ±õþ!˜j™8 õ9CÝÎPöîäÙ‰~[òD¯Ýž:2Áö$çêî}¶ŸÑž¾ä„³/˜<â ÚS-Ñǰ£ŒÝâ ¦H4´/šŠJ}A¹Ej 9{‚±©Ž“ÛF¾bëÌ—¶¶|Œ²“LÙ6f«cä1ìÆî`¶F˜­f«CêPl…;ÞMiI ÖÖ•¥ST—‡»¥»Ä Xø£>eëlwØŽ—ÜT¸Ftb,©w’ìŒUÝZÝÊX¸¥+— ÖX¶ãÛ%7áÚ‹Çe£3@Æl¡ þG±cÃŽfsmË2ÆÄÂGÀÎÆ”†Hœ³>ª¬®ñÇÈøzÅ,–ŒŠmÑT$² K°ˆŸbu·%¢˜5(ŠmbÔJ¡oQ }]Žeë¯"Œü+ÂÍ+þöE¥ÂŸÇê~û"VøåܼoÁ·èãæ# ‘EÄÞ[¸·x›¯^¨^¬æ×<`¦b€®ÿÆÅÑq¶,‚­7^މ£" ù¿9À+‘­²¬`Ë®+r"j¿”×'£Yæ¸"’]]€ñ½ZJˆºT§>"œþ#ƒÙ ×#¶¶°@ÃŽBœ&M/J¹üóð%f6¾Ǩxü¡}ÿò–Z‡8lÈÑàÏÈ›¬ë1ò„^èßtÕ>®ÿ#“‚õ`M°õ๙Ÿe~I÷µ{ëöÀ?±~‘`}+BßbŠoREƒê”útAº@u‰¾šû}+W…Þ™Ñ;Ì>¯±¯yeÜż*ÄÏ‘^o¨5wžAïî+Ž)N>âÙÛЈ?#O+]•^ ó®¨K[eÖ9Ø•Ie5¡Öƒ/%áIpÃŹŒ!3—ùIÆÌ2WÃôõáÝ/–ôx”#Åj(R]?g;ø%þOds-Ãë ÇVféþ”I\ý3¼ õDG*¦ÉΗ³¤³çÖæÒÜ"ýð&ý0a÷¥ÙÍËqV° ¤½§7êéz…„B½ÊG~õwÔ9âHƒT†aû)WHñ€ÁPwƒ9uƒ>¡š ±D,wð˜êfó)uø-þ§hœ@ý™¶pK=øù„úE%6|¨¿§î'¥ä/ÒÆÓô=ú.ÇUê/r4O—§¢.1½n™¶PK)¥VÈÓiKÓÐ=cÚlMZ©5 2˜´ìý 3ÔkÓÜÆé|5è1ÐûR Qójª¾kú¬ n•BiqyÀ-(*» Q8O”ìÅGðnDî¯Ä—ˆß¿ÌÞ(’Y+Y ~­dÍÇ¡¨CÛ‡1~%ÞÆ>ÁV4ˆ+3Œ …–ð •K~»dljÂÝÁvHÜØdjÂKþcÌAœÄ/1yë]Î MeÛ6lß䀣®¡¡q+·ûáïaøµ]Ù¿©áîùÃow?Õ—y6 µz*6Zà}¨9?pöŠa>ÝýæÎÉ3³™÷MbˆåѱúîEÌ£H>•Mµ _<&Nn˜´|×|Ñò–é ËM³®ºÔ_J µ¸£qS³ºÍ¡Ãºë<ý~á?!ÅD‹áŒõJ^MÒOf¤|u±âAjڠλ ‰ŠgʳiNsy?#U|­Â¹d,°‚µø?ŒW{lS×¾çÜ—ïM|}¯×k'ö½¾×I®_‰“€©ƒ 6mg PÔ$`èÊxˆy„…v+¥4Y`k(Eã1Z¦©Œl« UZ´jEª46QitlÒÔ‰vCª¥MÚn4fçØa¥ÿL»Öýó;¶¬£ïw¾ïû˜­Ôå®Ö:oôÌM„y1_*L"*ONIé„×WÊžlÖW2Mqê¦xÓžNJiAp¶Ùð^´Ð9e1dDHTuÇ-Ë©–vôØÚ“ìûÑãz×}?>·tÙŽ'Ê¿/—_Y˜žk†â»KÚpŽi¡ôŽÌ’‡¬§Æ^Ùöðþ¶ô©\+_O7dãsˉ}#Cx6ç©MÔ~‚!~˜3dº~”&šÎ¢.Ш³¦Ð€f I!XtìÌ×á%p‰F“sA‚"I‚`°198kkŽŒÏr@/»xb²ˆ¤¢hVÅ Ÿ*•°¤ºÓָǤiþ;ÁPè  ¸ 6Ý~‹š÷Õ8™?Þîïî+Ÿ(ŸüÆŽæÂ3éþ¯ý² ñÍý’_ï—ì­ŒÛíc¬ø*go…n·×RÝöüÕó>G›FÃäÿ¿wÚyÔ¼Ûo‘ù¯Æ©ýåÎÅåŽýà1° Ct— Ï Ó" ™{AkìÙ5‸S‡´_YωìO¬ãVÂ$TM ñBM€w‡<w 8h p²ä È Ìª¼M³‰A‰!Ò`(&‰NI5¨…`ƒ`s ‚ @àwI $‰6JÖB’)àÖlj¸± €›bN´‘è`ñZ*ÖÒÙ“ãl|=ù¼×;‰ =^•zˆ…Ï ù›•¶ ‘ëÓID¤Òd‰À¦üð’Á×Z,¨¼aÙÏXkQa-ËAF1¬2¯Œ… œÖAµ˜M¸” P$ ÅJm¤¡© ¦¢We†‹AýTY—=Œ- /ÑF¢ÿ8òÔµæìòËÇw0°õ‹“.Ÿ>wô^=±ÜL°ôÆrÓÄ僇ϟ-p´dÇί‚û'.åg‡)i¥‚øW¬ðÏ5¹å¾Ýx ‡µŽužµú±Æ‰z­´%‡¥#òËf•À„ªZ‚AÕüq›Õ6E!,ö˜ß¨ÀÀlK’‹XÀ~?ÚñFŤ EL¡Lƒ+†h@#O8EgÒI:Û¤ä³F>镬Ô;M)dåU`W``ÒLÑgwHÈ4D#M’ù:ƒŒìr»<.¯‹bº):hÂAó¡qøq0Ñš©»Tý:5á§Ê&œ¦Ú0ÄÓdÁlqËv—S€,£‘’SÆÀM8’CC‰Ý—µqrg:W~vè7—|g_Ç3}¢CIêùÞâ9kºt=èZO>¹®5¢Ïí.O\ýç‹+}µÔÛ>bð¶­ÇÐÍ>¾+Z_ñ]‚ú7ªG3X+É”—ƒÁT2ÕŸ:s_w^wâþÂÍ òÛ]OÆGȃNz„?Bá_p‘c<tÎwåR‹Rƒ$Í“<S9gmöuœ{™z•û…“®Û][{Å`ƒÁ€GUÍîææÑ€Étp…0¡` QÕCÔ²VÂ%º K6.™t³nyÜ÷474‚xm­§z, kc²0‹Â({š½Êþ•elì²-©Óæ;&L˜Ys¡¹ÒÜb>eŽš'L‹ùŒ(÷ËdRöåR EجõVh z[¦GåpL“«PÄÝnqkÝͲXPEô)e¦ýõÁa5ñ>%Ä©éánJŠô´¥™Åzˆ"pAS’‡* œª¤dÕ×*…ƵĥÆÜC3WžÞ.Fm~Í·­³ºßþ¸Eï¸ýÝØ}aŸPCóŠ17Fm1ë›yŒ*Oýéç/MÍÚ~(UÞÓß<óz¹û?|WlÕïù×ùÎç;ÿvlŸí»óÙŽ/±C;?ì$VÓõIײ–’¨0Qšþ’lk]Y„JÝUbˆ´P4´ ¦ê‹Zª¦RÙ‚hY7Cã"´iù+•&úGÖ¡5qö}gg¤š¢»÷Îw¶.ïó>¿4ŸS >iúÁO…MW}æåɨð;çß&,—wØÌv¶É¤p[9‹Õbe ¦¤9É&¹¤cÀ´™àžd±§XçsSÙKæKìæØEó"{Çr‡e†½Iqɧ(ÉMMs$]>œ’’ƒ ²]bPo'!Z%[4.%•±Ù’Ä1À“œü†µÐlgægÌIœ=’€b  =ѨÔÐìõ5¥$ÓžOxR'ý@Ci-A|Lsö*&°º± ´R„JŸÒR‰º^é ㈊ÌÕR W¸^‡êXýsø¾‘rja 23ÊÁh¾u€%ï«5µo|À¡ªž·¤@Æ•b *JLó³Îï>Uz€ú´0ùÔÊž÷ŽW§t\C‰Î«Çt2,F»V¬ ËQÔŠ–ý¬hI˜4gã³±Ó±“‰“ÚK§3¬Z÷*Ç}Þ•¡ÞÕ“Û7ÁM$®˜~kž³^N\N^ΰ›ÔÍåL¥ñTÆr69yÓú†í-îºöa£m«3X†Î7ÄÑRpH¡å¯ì…O~À®R@Q[×Ù—‚öµ¼­GcXŒñ`P±äuŸWìÈ%ºˆ«GCyú}»ClË»Ó mù«x`õ4^@FŠ¡éE°ÇìÄn¤»ahúÒaÀÑ(8îÎN ×¼M§ºŠ q?â ñŒUà`ùµTDئ9T»†œ²¸Çc‚hÍÀ›â5$Äùˆi4üä–FXÃõ ½3—­&`zdÍóÖï#tYͪB¡Î‹H®·´vË‹Z_ué—¯üq÷П^zà`Áßÿ€J^ÞVí/ToM¿·ú~ûf –w`gÓuw¤Å †¨\ûè|õã_½_ýüŒÏ‹Cƒ¹¤¦Yb ÏÖêbWñÐù#gÎã øœÈlkìD5=&__cèL¹Y.·GzÙ¸D%—ÜŠŽK̸¸äRT·‹Ì„„p,LÂ=K!nV{XÜ–ÙQvž5ï‡aâ2½Km 2•çeÒ"—åýò¤< Öîc † |:õËqÝE0Â^ºf”`]ÿÃ4Zc•(KÈ—ë7?¹Nç¤ÐîÙðµùòI˜×”É:ÿi?~u¯Î_TÒmÝô=!ºÚÌò\Ž+nÁ[ø§ùc¨‚^ůò3Ýsø]ǹ8Û½ŒÜ3 Ù@¶ˆ{ø]¹ÝÅÃø`–AÎbQ„b6›k@ŽxÆÐ"¿¢4Ç¥äÒ^ìÚ­¼G%RcqIST¡€ ¹¼Tø}ç²×‹8›Š^øŒ´;‚š</!,Î_„E.Òí “ä#¦[üïÔß^HjÄï³Yk¨Ü»›1&±'6ÅцR÷U²Ûв†?ÆÖlhV½T¢ÇZÉÒu¦²#«;¡c™+бŒÙp½]ÁF^W¬êÃ"SbJFì7 ‰nwL#y«Ñ° Ra›Ú7€ZÇ׊W ¦‡ñßlÉWzúRCÕ?lnÚ¶²{ÚoôØü¯Cºq=¸óg¦þ•óÏ7Ç5Íõg¾‡+™ê·Ý·¼N¹á`už~¸5éçL@‰Æc°'’yØúI¹ð<«£)ó”:•8—0}M„íJÀ^SXM ¤‰Ú¨6©Íhm_)‹q9M€˜!Œöôž#¿)û¿¦JC²%UNͤL´f=4\ÏKK+à+WJKÃ%Ð#]½^TMÿÃÞAøÖ»Û׭ͧEƒ Aµá±±£S‡rø¯ÕÄ70bf¤Óißþë™ÿm#°߃ìpè>ƾK¿ømú2º a¯ÏϘ)°À ¡x:°6±6õ½H ¤‡¹³âÙôåä?üÁ¥áp+剷úÑ`Bî[î€8'A%y8"óòHe¦‚.*Gq¸ŽÐv?á;‡»ã…èü±ê¯Æz]Øk*œ[Hp®ÕñFÚ¬5m&$Q ŠP§¤b~Ø ì"lØ@¡†ÕL‰”ä…Ų:àã ™uÕü‚./Áq8ãg¢6=21î£6£6 ™øòtÄ€¾_4¹ Ù¸;²)kò§ÝÞÁÑBõÀ·>¬* f„§hpŽ>Žmå!9 ¨ ½8|±òBå'_FGÐôó«»w,9¼nöò5ß9B¯d+}•+• •[ÿº€B(^˜÷ë—*ª=öØ4%>‡gÁ>€=ªÚQè~ lúƒQJîgm…tÿCA»ÛDÃâ á†òµæÍúSbè| )iFÓCÄÊõd>JåS)¦&Š8x©Ÿ®ŠïŠÿ bツ‰Ì$‡d„Q.D±<‹{ØU,fwæyŠØ­k±n·»\­n ¹ ª1™nA²:Y¯•D!!`F¯U H–`Ñbõ¤uŠ"´me]Ì.‘›Û 1­mÒQ[U%«öDP·¶@’Ê$g?Tîþö¬d²«I±¾òÚþÕU#;††žÂk+ÏôÙšaèÓû<[ÉîÒKCoi">T>‹~ŽTPá‚:•CO83—HÛ¤C1_õû¥9©9ÚêÔÚ/JÑÃÓ<ã-Ö%·'·kÏèï'§_*øÇ?’¾o&nJtÁÏŽàϸ5v7¤Ì°qlRj†nät­V×µAýYëT6¥&wiWµqÍÃk=Ú%ÍsICšMiºiä“#èsGÐvësùIùPU5 ÀÊXŽhˆMT–Ïâì§Âˆ;q¶Þ€¡0©ËöŸÎß=ê²"ƒd[âÁ|™ä\ÂéîݘË-$I•;À–‰?÷o+ÙâÑ%bÒ.9ŠîT!•†©µRÌH˜ÆÔÚl5H°Xñ\eD³@II’˜ªíPU“tÖ(ÕÇ2ÈÚ–ŸµSbM¬UM´oü©§ÅAk˜¸„>…˜Š<BI®æ h]ž;©ùÀ«û7Íþº×IfÚ*K*÷÷ÚÏîë>ð ÞPºSý®sO\Ó)WZ{ã²ÇÀðáòÉæÝü”ÌÑ ŸyUpZå[,.ËlW=L8ŸÅEN°rœÅg"M±ê§¶eÛ¬u™½™½Ùã-#Ùó-5öï}NŒZÁµÉm¸íxPÏ %-+2’GàtÝ[·‚’x KÇc‹ó›\ãRÁçà2G¸£Á7ƒ8ÆÊpA¯N·6yôÖX ­D[Ð zÑheò&6Gï„£Ò 'j™ÁùeUxtFnÊ'ÚG}jÒs¯Ž¯Z7 !¯–\÷$-õmm›â¯•ÆÇJˆ«îÝí)ÏZ¼ÜQÊí~—{:³Ûz‘{=ø«à{Á÷¸Uêï%hÛl[£ƒ\ª~bµ^]3ÈCŸiŽO¶ªÙÇ­-mÍÓ÷É]žw‚™ôCk·ÇÒNáÄõETþù¾³miQ–Ú£†1õæ­»›×¾ºìú›ßê,ìIJu!zc¥ãÄ›çäôB^]üøúõOŸøJª¯mÌ`êÊ;W,¼çÁ]/¯|õ*ÏÞ£ÜMT ÝÍBw+Ô룔ñK”Z4Â3øh‹¢9ÐrokÞ"l0úÄ绊Jš×´€’æ€n?‘¤[uiÙ'5R æ9?µ‘³Ž4$p 3Á‹H{Äý¢GTx)r<(ï—½òy”¥D|ò • AþÆx©¿ƒ‡‹„…R‡ë‘å¨ú5Š/C·T7näŠ@Q¡‚úÿÀ¦ ¡z„fë•]æÊG„Yí¹r{ÎM köv.Lz^åÀà5zóoß ¤7Þ¾ð ÚB*RœøŒ~ *’Gç‘KhXœÒ eõ'õ…¬ÿBÿ½>¡à=Lyx¹Ó³v0>(Œ†/6^iü²1Lë±0¯)ª©7©+4ß;êW:>>ÆÍ~Ÿ’Fš&+iQÓ²J>Miõœº(þ'»¡>̨ Êh¥yg\À †‘Ï+‹Êå¿tºà\<Ž=nkˆhÁÝvÙ==Jép*Û¥ú–K:jöÇ0¯£é²…G…ãˆà BLL$ŠFi*Æ §C¬?˜fÕà»32ñœÓ&øÅOù€<|¾œ-)Äh†i°KÄü>ÆËÒ À1?MûÔKÁÔ@n{û\î¾]$ê<ÊSú¡UXž­b›ÐôMêó›¿ W–”˜_.‹ f?ÒõË=Ȥ XÌžùy‹L š*Ø”.X’H¹pÿßk©úµ‡w«ê<çDÅiÊB'"A³PŒ!ƒ@G„©«A,V‡å΢}zn{vQ%§V ‹ín¼/¾\øûîlçüø»óËçl_.‰cŸóâ8Ø 4 ИM¨¥šGª©P@£ØtQGEC ˆ¶ë ݨcTÐ&P™B ê`ëèŠTüƒÊ&uC«Ôni™HÛmÔÉž³3ûc‹äçyîî±-ç÷y¾¿ïwû Å7„)á=ñcñc•Î nãºÁhf]¦¤o& !ƒuC/é[õú~ý¨~Fg¯fþ nƒùŒu»M|2¹‡Ý%'ügÀ;€D•šÒs`8²<]UÈÄŲ¢H³¬]…@€q€ 9…¡H½‰™t#7ï »#I’Ö9™NWË¢MéÖÎpÚ T 8¦æwŸvâÿž66ªä4ƒIw`ÚÕ¤OU“NàÀäp´ ¼OxÖÎ2ö¤ ’µh£é¤ÚJ6µòN‡ÂÉ€È^ÛrÕV•\ ¼“$G:"K‹v†fu™;|›¬ŠúA¯HÖxþÒ$vg±˜Ñ§Ð†³÷ÒS‡' ÔâAÀÄÇ|ý¢ªI‘ç¿@bî#ê¶4P7,¹ÿÁؽŸ—÷b¦Ÿ1ãe?,k صFئl$¹€ñ+åJT‰÷ÛÈ» ŸÍìtÐKš™©ä©yíõ6Hì¢?g}¶ÜÜC‰¹3s/+sK–uhå©4´_ëíÈ Ñ+ƒ’_hÿòÃî%TZZç¾;¯Y6}uúú‰å6EA‰püéÚ„ö÷ítÔÏמAƒ, ©)T'•#}íì“ÄN‹ ² WJ†AJNÙ:S0-É.-¹"\ƒ,bG‡m¢‹û0‘J†¹b_8g…TØ (`>,Ä#$…õ¦{½² PÖú‹'¥´O’Ò0õS…ç‹N§"æ c½»Š‹„"ëºÜ/F~Ús Nfi†K\o"ŽDÁfeŒ)xm¤VBÒ]l éufgk³³ œÜuŠ>á§L°!þUÐÈ|÷Éÿ#¥1Âûî¹È_ƒ `šYÃ'cÑUäêC’óaÄ#a#ÂE¦aí2‘HÄ–†XÕí-iá=ÅZÐ1“ÞÛS·GuœLÚ,ÂñòhwmóhÍõ¾{µÜ™òÔ¾\«/} 6ÍXã f;ÐkÍ}ôàëû¶È}‹áíüxܬ]{1O²µ<œô5¨Ô¶©áŒƒÜiŠuüÁ;;¸hˆV%´?>NïívbAEØAþõó3sË)ïÜ`à Š°‘4ÛðMüH­šIwZ¢þ¨—ŠßùýÜ•]DŸ¾1ÛòË; úшá·aœ£"8—1ú—e¿×õCúp—¥`®GWtMæà3ôñöSýçÚßm¿ý ýz×Gíl=HxGøá®‡ùõÌp¸ëœ„“ŒS§áΫÔÚœ¦@¡TøÖ¢±B•?è? õ]„7 vfQ©ðdÞ2Ä ¿Çòæ·üšÏ}–‡!⥵%µ6EkSûõ“ú[º…Òë«ôú÷õ#úÏô·õßêê3ºc«õ¼‰21ßa(Ä䙕ÌvææsœyùÃ:˜ ³•±ø<ŒEhŠËùDu}*?„2‡@9•B‚¡jY— ë„'„#Âiá¢@ÿQø›ðq„‚Áᬀˆ­q¸Úä¶T[±j[¦.u)²‚”OH±Ev‚½ÈR2!Àbâ)§à[6 ; È(ŒPáu?ôÍ_—,%‹óAÔ@îA=«S²OXoYQ§Õ°–¬cVÊ*.î]CŽHzOÝ:U´U3•ÙŠöË2±ž³årÕŒ€_˜y èÉi)òœø¨Ù<ƒk³7q#!T=æàÎÕc`_ap?×ßO¤Vrùs§(¯­{¯Lo_(fÇÊE„ ª8â¹8'¹%àŒ°lŽõYz$€CM´7“¡—ÊK€˜1^¬nÇž}µ­+nErO!¶+Nâ‚R?õ†o&‹…»$E˜A£áÚzxÓ£Ån[c—žAÃ'Ÿ/mš‚]¼‘h „âÃùâšêû[öæ9»¯)”2›—•±7ŸˆŠí™mÝ|òåonêQÃÁ/kÉôàJ}h×òÊ’ÖCsŒ(V„‘¥+ÀÜ«»{:bA@¸×æoRA¢ÀœîN,!v¼VÛ^™~þÕíêì~Œ:¶Ú "¥ö“¹±‰X~¸ïÔJ}f?}pþ¦eQ±ø»ñíÏm°……kÙãÒet9v~ÿ„h;ÛP«ï!y=»AgÇíUé÷”÷”o ]ðMJb—¥«Š@¿X¸Ð4¸A™†7 ¢ "õ÷.ÜrC÷_…¸ƒŽQ9 š…ȈEs6‚¬;ë‚ð(ãøýî’³Üùî|~9ljÏw~‹}¶ÏIÎy5ö‘44¨h)°ºÝEiÓ6/¥´ÛxiË['FÇ&*щÀ¤Qµš` mÕÓD%¦J5„XùƒJCÓVÉ-hPMjöüî¶Hþ=w¿œ¶Ÿçù<Ï÷qc½‡¬QIƒÙq´V³F%¸¼9ƒg¥Zmš/ÏpÝ7pä/ãfžîâ?dÁèÁ>·KbU­.u®ÎnÊ”/M~ôÅÖ—¯½ñîpïÀ¨‹ä¼j<òPÏªŽ ·¥Ÿì@-_xãô/7õ=0¶¥ võö€–ì¬V†•0‘E/™Ñ7Ù·Ùsì‡þ§ÇI„ù0³.§tR_ŠÚ3 ðs¤e¸øÞ‡NíU&y=i;”„×G¶¶M/‘RÚr <Ä¡5ˆ<ƒjÑmʰ™Ȱ5½à¯µzU'§ôYÔåJ˜˜ӇߺDY•oàƒ¹ÞÝÒý"Š} iߨwµJ³R»ƒ'Ñ·öº[±‘¹M»šfÅX<'iO¢=™J’´;®Š‰$‘fa‰ ˆ*N³PA%i‹}Š§Ô©ôý¢NO¹wz^ìŒN¥^Îî ̾ÉõËüÎÿnæ|ƽ‹; 8Š•ݺM·^§[¯ÓOßHTlx`$,ØCíR!µØŠD+âK!ï¡>£ÙÞÅmN®˜düýñ¡ñ“Ü·r".Åu#hß0Ö¸úÛOžó*‘eôWëK³{þxôë—Œå¨eÂßÖš^Ø{È+¿uâï$ăvP`ÌGDPÁÜ@{Vy+ÞIï¸ï)i‡×o:E~L^®W¨kì5ß¿©ÿ°M;}P/EŸ±žÚJMªÛ©ê+Ô^÷—ì?}®´óž9]. §AÄI9+?VøçQûÙPBt4ΣðÓìòãè6CtýfP5üO˜ lÀû©Ùm`kJBhÑÕ²ú¤úµÚ FR’ÃN¾NžeÃÛ&ò†•5 ¤S¦± R'°‚ëÝèBå&fPÓp²hZÑ¢ðÎB7ÛÊMÄ_ž¶2Úd[\ $Ýê‘ÃD‹×Fa!F,v^¤µÝ0¨à O#ŦÑîx8€ˆŸÃX‚ÕGUî¹6 ÿ ¸¹W]=¿£:±~áCW¾ŠÆ}QC@wÏ?»nè1ÿ±Ý³»/|‰|ÿ:yâEÙÓµñX\1HÔ`㪙›:¢E9Fr4áiÞÑÖ„RÏ2Œ ¾ÆsLLv\RQL¦Ù*‡¨Ó M:{|(ë~%@?nÒÍ€» C†~C§tÐùHÂnËC†N©&XõpJÿüFe¯Dªîô4Såwµ ò*ËzR ö9„­©§:SeHLžÙÅffš`xæûÖe•¹Å8˜`DÏëdNÿ‹rmA4!A0Æ€å\¡ÇMßœ)d]ýƒÿF»ó'ˆž*šÕ‹ÅÑໆË(òÀv`[_1â”T(ûY¢…®BÒø_ÅÕnS´/àëò¡ÞÈú…¿• ÞýûÑ_Ͼ¼}å2cÝÀÀ•$Rà ۟` Œ¡P~5y`ó°~øâã½ÙÁnÅÕ*p¾&._8½}3„‰]\A]’òÄ2b5úÄ|8Î7såL|ŸköHêý†s®÷RänÅî>ÐÔÔå*Ð}ô@d¬Ñ ئ\)¹W‘î|-}Ìu*{j¨Ù‰ *lJâ ªßó–R¬ÎXн’½dzúJf"i”̰ ‹O2ò%„ÿ=瑌Ò<Õ`ú¼^Œ¨·­ç(ôé$eê5Oµš dpÇQÝ1œhãF,Ôˆ¸AyQx¼É[›<âx™'ùyªÑô&Œ<Eˆ3dƒ4L%¡eðçɰ›1ÛSF f.3™ùE†Z›©fÈÌöQË–’noq¼ùZ(®¯ •éï GjÖ6ž:1ÈÅ­ÚX¯a ]×Ä^SV mcM³*€fïž#Jð³ãà>\‰Ûdê0ÕðBu‹_BŸ•M €5c¡?P>I< ú»z:­ Î)\´{ì¯]û™N+Ó(»e×ïäoÐÀ\‡(M^XIÏd—õ”~ÿÙšéñGw¿ý³ê¦á'ö<ó£½/~q¦²²íšîâÚldÛV¥ï…ß¾~œ =G½õ|G{÷À–#ëR±™3_{ôu¥£ã±|î¡ 93¼'ß1ûôË¥mó¿ž|þøÜòü··¹ÐµnåPPû±¢ZA ½Ðó3èÆ9‚¾wë½æ¾œE廒Ѹ‚$׿ª9ÒÑØHûéÝÀ±„Jdd–Wù í9í¾à&Cˆc²{ž¼n j2&«QÕ“Ùh´5&+óäçæ£í19¢¼•¶68TEq»Ù&§ìB®´W4•åeÑ~ÐÍeÑ‚W_?Üä;`I¶Ã¢eaQc°@v‹&/ŸŠˆQDüT$y‰xó\Ì!9w&Gê¹)ì‰Rÿ98ʲpšeá@ËÂI–Íä,kºŽa˸t{ÒÚ‚/v+‰ôäÅd5Iá­¹ž~òÀŽeáKYºÚ#ÌŽÙRgd(Ô¦J‘¯OOPÒ`°ÃuíþýPÅ Û@ +cégmS¸t¡Š¥LpsY±>Ã˔ݠŒì;ÑÏÂ[·ä` ñe7Î^Å[^:#.¨29«AÊ Ý¶X‡q,¥°ªž`Mm´—ÇÿÛÿçÑ]Ã~šj_¶˜è zÁÐÕÊν’ã|˜ ð\Þ+^çžó?¿aÖ)ØÅò|ÍEk#gmTú6©]Ôæ5WA«js0hhËši€ðÀÁÝž`âÓ:6²¶Ú®@ÕU¦$ÌÕÚ¬)Û:ï÷3ø4[?æ8ããïç÷4=»4%¿Û}’M8αæŽuõø Ë4q&rg`~»óns­Cµ¹÷wÚ@~êh]Ñ2·M§JOŸ*ýPy¾ø|i¾8_jl]Þ*ne´ •¹)á~S/Ñ7hD?Éü\–J~:~s*ë×®]«®_«®Ò¾UÂzEuNs&—'&É ·$‘d2¡iA„0\u_PÔ}]‰ˆÞÕkê&è.†]ÃDÑú©†ÑgêyÃàÝoc`µ<5¬xHÒãÉ„{I-™ R#oQçòœ¯Cž’€È/%i@èNÔ4®°ï£â¿‹ø\ Ã{}诋hz¡×‡|‹èµKÁSäw(ÈIHsº£RROâä3š¦KœNs¿¯¯— ‰,ô6z—z—{]½±Bñ-Äsin­Pèæ½„: w{be}emmbýŸdm„ÂT\Šz±Cdm-º¾BÓQ7y_Ê[ÁçÈ;®—òQk‚Ž&¸ÐP”R" Ž]ïoÅ[y‰]¡ƒÐƒ'@·AdAH¥Ã‚àñtvµÄ…ï ?˜Æo¸'Ýï _VÆ_˜úÛ÷ Yi&Sɾ7+=»šÉ¶:~þâµ/©ªéíîæ·Îžhþáhr;ŒìBÒŽ_3ͼG !ö,PHbp k2ÕÇIÍËHrsGt7DÀx¦’Àón¦’€÷„fx—O n·æ"Õ@±¥Ô,Øå²ØÖBjÄp^Ds"âD"bñ¬._”çe¾ Wå9¹!/Ën™þ¾T.Sû†/‡˜ÒRvŸ2Ü@˜G ߦàüïwîÊÿÞ7¨ÌÁÛä8ái åa<âèû0’eÝñiƒ^©“«pÃz'”ÈamŒ™º²ˆÿr9c›z %S3õŠ‘‘L½Ó0œʘznß¼b8;Р©ï€±Ógì6õaÃðdìmiri•-S.mÊçsy¸a¡²£'§túêÐ'ÃÞGµL™«_¬Ï×uW">(Iº„¥¾x %FiäÕØÕØõïÄæb8v+éËÛ°d³%ûª}Ýæ{ÎÆö-NÔñ`ßîCõd¦Üþ#gYOy;R^-çÖ;Ò9.•özåà‰óç÷<易õå:ü¦¿ìwê7D÷a÷aïHÇa±QwoLJ…ÃþÏíÀfN1 ©CHu%™£H¸ µè? €4Ìè@çøé] ´æÁ²{IlÝKíuÒ~,½ÿ­8ÄmÂþ?3è‰üô¡!›òйøÏ‡^6=ú“Ñ'NÛ9Èó!UV¬¤õ˜ŠÔš‰œ-)µ']€5iÿ«³Gö9:>:öƒ Íó'Ë@Dîœúzå¹½éjµé{2ÞM³À(}½rÎ1Ãú¦ïxU`²p& -:„¼°°‹Òùǯ‹C²i,m?00j#7y·ÀˆoðÄù°0ÌÎß@©X–‚ ®–$ib½&]•¼HM(¦.µH= tnd|@îŒÔS”ÔÃð»eéTJ’‚¾Ø”›wyÔEôõ…%„Ðâ×£Ñt†ã,ÁÇØ=V(¼+û’‚RÊu+ä€x…B¼â lƒ °·BsC¡8¯P’W(É+”䉂Šï’nÏÛ¸`OCÚ»Ûmvg6±Û o·™Ýn³¼Ýfyæ ÞN´ËN.—½ ñYTÈ6²KY>Û†ølâ³-x7ËÙXÿ&¼3v'÷À;̬MlÆKGÒ¦÷5kིÚù‡>Õ"øÔÁK”àS/Q‚—(ÁK”ॠÎSÐqÄ[(k;š¿ ŽÙ?Ö_’hæÚáyfdß“†~ÑüéIðݱãèâéJúlSüævÏ}aÎ|äÎ â0À¥Ñ'únåüHþš7˜ ÎÉz:¼bÒq1ƒŒºœ¬U–\È7è `f_ËT™YÚY¦Ö1{¬rÃX20g8ƤA‡nÇxÕÀ†$ë2–%±Âû2 [Sû†?XcØcörn`û UÎÖáZ!Öm8ªC«\ë€*«L÷¢4éÆÝº–Ò° t†;± dÕD<Kð‚sð–I uuÈõ$s(俯5Ôé‹h\ÂÉqm±¬>«¯İԃ†Ð~´Ÿœñ»§…sþsd:6+ÌùçÈlì=ü'ÝwÎ3˜–ÎEç<³Yi.êEÀ3c€!ˆªp®‘ÁeùT—lgÇß÷ì;;¹ËÝëóÙçŸwöÝÙŽí¤¶“K· ¾®[Óv4MùQˆ†—R6µüHÊø£-]` +?FW&Zè*Ä(ÓªVBÉh³ ‰TÛ:†±¡ FAÀÚŒFƒý‘„ç=_GI¤÷¹×~îõ{÷¼Ï÷ù<ªÁ¹Ä ÈÛ¥ñÌ㕃¿ýüžƒo¼¶ð«½[U‘ß²¦[+t(ù\Â÷âÃÿÖ+žÁ/¾ŠËCÛÿòë}Í¡mqcp gÏO¦#4‚…•m~pDªà‡œ¸\ J  Î‘ qአ•¥(Lð”/¸—M¯s’f÷”ÉÐwq¹¼Îs‘qÑI&äZ+¾Ô̬´©uª…#µùS­9µ‘ÚxÍ_“=,éWGæ„yâÕá ·K˜p“E€eâYªæs3±Œk§U¦Ã¨[þH“FÕu­µ\kžkí6×÷àP(Ylõg4!EBë¥W3ù®˜Ï•óé|!×+p^ƒ¡”è.àÎT®€Úr«È­·œÆmÒa26©Mæ'»ü)“ññôWÌñÂdùëÊcæIåû±SÚ)ã´õŒrÎ8o]T~aÉwF0‚Ø6a½Ñ$h´÷ö ÍFàÒ-K ív ³qãM{Èg|A­n^¾îRþF­wë®Î}òžŸîݾ©§קךv=ïìÙ8¶òô;–Ë1Yõ>ßi×xhK¦òÈ_§Ž]?d$ž>XÿØ®‚2ÖÝù¾' ˆ N;Ÿçë¼"VJ ƒýÛLR·Ëóýê´ÞçNÓZëc‰¸Ö)(Q›”ñIþx™áã![J# õ4ÑH‘Ѩª"㌮¹¨ª^ÑÓ.ªš–^¤§)m¶÷H޶/Õß E9-Ý.5Qû x ùñØ¥ãùÀµ€Îã Š’ª«ŒZ2Öy3Üj`Û®Mf\ë(rÔž3ð¸‘A ÆøCiøã·:ЪBO±¸H\`¥jP.ÓÃp=Іz\ ˆU¾%·­¾´ÐB.QifºZKYÈ»€Ð|lãÀ¦kú†íéD1’Á¡2°,ÛóUßÙ׿;vWcÓ¶;ý\ÔhÜÿå7ê$÷Ô2ìH4•`i½ß¹ºÀ¼1êaŽ:Ÿâ«Ò𓎢BÒE?§D•+¹+ùß“·Èû$P$¹ÒY[:ÊŸ0OXçøŸ˜³üs&Ï lG°†ø»Îá‘{ttšÑ1¦u;¼Üø-æø.'ŒNËøÀ®Ü,Çôøé¤žHPa—ã œ˜Åû3~:zS–Ù|9 ky™÷òØ‘#6¾GFY’e²ôÕó¼d·f†Hçk@¬u‹ ÉÆ{‡=fÑž´/Øœ-KA=ȸ¡ue$ŠôWá©wºe¤½3ÞK5JúDyûÂb³LâçÁ TÉ uRᆠ£dÁ †h¦°u¯pÒ ðÞ~~ïÆlözÍiƒ²÷ÂÝtç3°€ka ×Â2ÔN°RytÁ]Á‰c§3o0‚$aU:¢-ÇQÔX¤?¤išÔÐfWÿ<#(- ÔNƒ»ëèú=Xà)|Y Y ¼Xå– ¹±Çdqi‘Tð©â´‡§M‚ž…ºQ§–ýå\7l òx~¦eáQ+rÝ@0{Íiƒ‹\7@GnvõÝÐJ° —¨Ì¦@Hÿ‡Î£hRê›.'Óräÿ@© L_/­O W…|Ÿ ©¢Òú™ïIÆà‘ÅuJç›ÃÇvm×øl4KŒîn®nxðT÷'¾óá¡dHŽÆ|—W.{°ßJÆ‹¯|{×ðÉ‘߃G¦¦Ö—ª›‡ö|d÷ç.ä$ ŠʯÞdNú—QýÀçwàŸÅ!<~EñEŽ0˜ËðUÞá}üþ¶="Ïøf±è¤Yþ¢Hb¿I¬Î2l)P”°/?LÏÞ¬ž χ}áx‚*œ=x½‚K.ëÜ (-0Eå…f3Š|K0y:ß 4C½ÓÕùž~µ%}!t¢Ͼù¦”'×i;/Ž µ|øgwø—WÎï^þåÎJzwtn÷ q¿o޾t€jucuÁ_óE~âydÁîžÚ·æ-¦MH %a«à¯ O¦Î¥fSþÞ2†ÃwØY:H, ë, ûÿÀ« …œ5MÉÒæ©Yºaš,ǶÇ÷´ñí<2 xâJ^uÖ8 ïÐ<ÏQ€ç(»sÛ9Ší¥x޲;GÙý*‡%g¸«ƒ8Â1ùv‹ö0¼å1¼å±»å±;µÓ¥Ö×°²å!<µNàaκõ¬ÅT¬q‹±=‚#%‰êÊ ,,z/z/¶se' ÿŽˆ+âœ8/úĸé!½'ê¶S¤¿E†ôo©yûŒ–ˆE—éáß%F—ç›´6¸9±¿Œ=Ô¦©Ï{µÜ‹úÚ~wêûMçàÊ‘M~tÇ¡RáCøp¸˜´Ò”»—­}܇G¶ÞÿÈü% ØË_ûÌ:-œØ—¼®/ ´ý6D?…§œ„Ì ËHÆþª6ªŽÆF´KÂ5í- Ñ ÝѧÑϧt»ÝÝÅùbPøU¬&cºÚŠ fu.J"ztvõ›Î^ ¥2ÉTj³DI"¡{%®Ä”ˆ‘Ÿ#BŲJ¤*%‰$b6E/à¸â“ÿ&ª’#H>©)¾…¸Å-/üfèaºŠ}x„îlfÃÛÝaÒ,ØšÓ!ÙD»O{J»¦ù‰†Ÿ…ç`ÒÀ ¾™ìeȸr+KwËñ¥æRlÑ­Õ4²ZÇ!¹^‡¯àòèš²x˜¼t”]s/Ê1D1™kÍÿ7nðš´s"ݬF7ËPªégçÚ´RwM„šÿLóRß’CS…\ƒú2»šsŽƒ»¾òr=£vãw+¡Xד‡úºë¸§k``åW)æwGÌD[.Šj¹Ï®üWY«˜\Ž[;µlÐ,­.°Óç.æÏÉ(„»à—³²b#òóÿ¥»ìc›8ï8þ¼øíì{|çóÙgŸcŸƒßgûHãbLí–Ä0²)…Q3ªòÞº6ZmtÒ*˜(tšh·jE^ “*­«Êº?ªîvÒ4†º–)ˆ!Þ6H²ßs†Œ©íI÷üž»‹ŸÜ=Ïç÷}¾¿°O“‘Le‡ÛR­°¥UÕj¸ª-V‡kËË•e‰ÍÎuÞ5¾ ÊÓá§µ5‰uÆóò÷•áÚs‰ï%·ç~Z<`~âú }꿜¿nxoønúïä³.¯Ëçò;dgÀ‘¨—WŒ‰¢‚Aä•}†¬±qäpÎl3rH"8<† “ðfÁ°¡e“#[|þD€¨dŸ«m4P>iæóu#©F2ˆä2Ze$à2á ÅtU@Vt‘z@¾";(qùDPÁÈð%ñ?“w’$iæ 3iÀÝ€ìÀÞ|.Ѽ‚+O ò9óù΢­³KvL¶Ú±‰ê¥bÍç/!ø&r¬ˆ‹š¦ç†’Æ(.œ®­< s¸€’H€¿q¿!¼ L t¦P–TˆŠ£d™Mâ(οõ$= ª¡GÆõèxdQïÚžOMÁà%% 8¦Ð„^àì/š€Ò9 tú¿Ø³‰5õ™5¿Ýf;,{*ž ßb !Û=$&/ž"NÅÛàºÃµ[ƒßG—¦è}z›ðÚ~•³û”é¥It§ôïÙ¹hþdf:¹{—7Q°ð…Ù‰ø®ízv»Ì‰ÿ´£ãß$¿þ¹•ôg2-J౉}xs¤oº'“¡Q-Ü—Kè¹´HïÜ1å¤[P{\ÒËäÝZ_.~Ð z‹\&Ê[ \fÛgž)SůYcÙï­ý<¾Pñ@Yê‘59âˆhw ¬‹á^â¾ Û-uf3r§Ó¶]•ªé®”‹#ðb0Z}­ël)°OÌŠû V–P—%7aŒÆu#š.dŒtWy–ÑuÖ…muŒ@}IÓŒT§U2:‹ ?H¡Ý¦¢‡¬#yÂÚc½mQ+þªt¤üv™>QÞS¾%ÑÇ¥aéP™ÆëR$´\à<X߯ýLòß xiáÅ‘Ÿ ŽVX¤‡poÅ»°s7û½qË Æ}ÆaÃñ+öWv“ÑŸàƒø¦Ÿ¾Š*cF¹¦¤ª–˜dIe‡ fXFÙQ¶ F\bØãšêE»:Ó)W4âvy_¯¼S!x¥ßJR’ÏÑipœ°m»Îb?Â81b½ÿN Ù†æ  ©Ÿh½Æ…øúØÍqp?6ðfcŠu›t­{pÐöä ~ š6@„UÂH­ÐŒj[3J ;Ž€×jr üÊ0$ a_¢Îÿ“ò[Üøª' ó¸‹ÌX^S㯿$ñÆÏ›ol{»rÕÜi5"•Êß*Ðßa5ÌtÁì"{‹Ð;Í^“lB}뛊oá#Æ‘äãö9óBu¸^¢ƒaí~XÊåì²ïÿpüï,ÚL1·½]„5mÖYF¶ür =fßšO~£×ry‚­ù‰½=ƒÏô¿±xÑL⊕Ñ0ýœÞ¡6:ùYMHeJ4©ÇKüêD"ÉãÕZ_4V*“…d}‰/“=t?»Co3o­‹=l%]&ž£¤n"ÃχÄk„XKH’Ê2ñcñâ-Ñã#1FTÑq/ÛD¢½D';ÉËäq†bH_ÏŠN‘ziÝëbuìEUX˜é?í4v)°îÝoÕ#”|‚È”5ì»lû{“dï±K •[E¨J%˜2$ˆªø1­û„Qš­1Ÿ)²Þ{] ¿ÓÆêˆœFØ«Ö@¥‘ŠUîT Ëç9-Þ•˜ù¦+&² BµÕ@¯«h‘ïÀ¤Ž’ÌÂü™—»çhPÅ}SÄ šýãv±qý:/å±E²Þ w P9Ž]©*ÝVC®\‘ÇîÑÅ¿Vávv«­¢ Ô’' WMPKˆgùön_Ë¡f”ìûGüÁê=‡:¼ó]>–|^>¸È!®Êx«]õà†=0… RUäk-€ç%h`˜+ǵn03&6W´¶vâÔ4à5h áP²:ïîG„ìr Ô’¢Á R{ç7fK˜¤úŸÂrìîÉ-{9m9üÇòÒÑã§|rP+éð_NB„9£ù,GbÄ!2¸ª ‘cñ(CG퉥„õ}ØËKµKòM“O²Æ`þîŽ_‡ôéÆv±•ËÂû¹S]GÚ½DêrXÝ®ƒ[:·}°÷‘ž•²gßÆÎŽµ#«;©ùO’?zsÚcs—þ—Ýr‰i* èé‡úD䣈¤XAþ?+‚ˆ´P°Bk¡ü‘ÖJR¨( 1l41b0qáÂDC\¹rc¢{WêÖ1†„…{W~p^ßC‚‰TŒººórîéÌÜûîÜiÚÈ£éÎÎ’tí«ûM^È#·õX ×…·kØåO}ÊTr&Kkhó: ii°ý>d\…,ì,3ÈÎ1È)ÝbçŠ/OÞÙù×EØ×ûCPð åý‹%§4¶ *îA•ühTËyk_‚[֪ˆúgÐ({ëƒ&ñyšÁ+{øÄn~ÉíX4´Aè> endobj 322 0 obj << /Filter /FlateDecode /Length 39736 /Length1 63704 >> stream H‰\U P”Gþ^÷ÿÏ †àÁÀp ƒAE4@„AØ£’¯þ©×ݯ»¿÷úõ× žX‰¬ñ“¢ãò3s*€'YÜ;nF™ÝÑžô¨ðÈ  53*˜±^^ÎcWã±GaÙŸ?ìÇ+¸ý0Ä–.*Ø7¾â' !ر£h–}fËËý*y½mW‰º&½yöþó!؈ŒvŠÅ4c4>ÄKÈB F¢Ÿ¢;ÑIh° »BH‡‰tÔâ^Á<ÜÄ5„#WɋױÁ_ Uwø?«ÕörG*vã •Ò$D³!¬É;¯WÍ0!\R¹µ7)X5!ƒ­Ñ aXŠ÷à…œPD>h ÝA òP­ÅkUj6†a/ÎQ&[c±H¿Øm/JyÖN2Q³jS·ð'0‹Wz«™ñ4‹2Uß3Bñ"ÆÁΣ¿Ã%ò¦X™¢ÂÔU˽ x "Å1id‘…éX‹íœó¸GäAƒh+52Zé¾Þyº™x‹¹®¶röð P,Å “0q¶L€l[zÞÿ3œ¦LÊ¥f:,ëõW²ê­|Ô-¥føó)†}x$hýµzܳåáLlÁi´2«œ÷GxBŒëâ-±TMU»ÔMæâ†$`¦¡x;øTàküƒžŠnìÙ¢Õëíjç6#˜ûxöžÄkWó)íÁ~Æy޲™9ŠG©ÖÓFÚO—è’0ˆ@1WÜ•NyR^ÑëºJä•|ÑŸ÷µ`*ŠøÞâloàxwá(Ž“…RGtžç?ÃDc§hWå ¹^ëÐWº®¹~r=UU0r•ä<¼Ž9 ?“/s@%4Ÿ~`æïŠÏewÙSZä ù’œ,såjY#ÿ*¿ÕæiÚe}”n×v×W«ÊTïp.æ+â1„ë§€«i6ós0æa –£ ë¸^6`9î¯pçð=þÎ' dÎż{WÝ ZǨ¥Oè0¥ãtwB1ÂÅ`‘,REº(+5â´8/n˾r†\*—1êä>yIƒ¦iJcdèÕzƒá¤1ܘaÌwû¦ãÞ³ˆg¹Ï®ºàòw½ìÚè:캥¦¨EÌ?QÈLW1ËZ®ÁzÆÇ\‰ûp ßàB×$HçŠ÷# Wƒ•O-™FÒ(ÆXšÀÈfL¥i ;åSc)-£·©’Þ¡µô~6slõôíc|Aç¨~¤»ô@p ÉÕ"ÂD´Ê‘¦Š‘b¼˜È(å ‡˜'*ø„Ägâ€8/½eˆŒ’v9WÖÊÝòˆ<+ÿ© ͪEkõ)Z¡V©µh­ÚEí© Ûô"½N?bècˆ7dJ › Ÿn:Œc–1߸ÄxÖ¨ÜBX­þÂqïůцš¯÷ÖŠ6¾~Ò¡¯¢lΘAL–¥rüN/ vi¦ËT%‹ålµS¦‹'²œ¦ˆ¯(H色k ¨Q\Å-͇&‹;®½G_ˆr™* ›èg4­R¿ ˆ HoR³8*+e¥ú#õ:jÓëD+ÌÚ5á6¾Õ«Ä&žô­(ÕÈÑâõ§(漤/ä|'‰Õ!Ïju¸)-âj§¬§h´,^C©‘÷õÇ=š ½ú’¾§ý Ú%hŒxŽOË)ÿðç3äŽÇùóS~l \8ßÅ`šÄؘ;×iÎ`"ÀmBÅOD£ˆŸ< -iDBI„pžMÒž©„ŒªµM«Ê $´MIhK›@„ Dòë7ûîç -´ªåïfwfgwvvfgEä2¦;bzä2u¼Úè«4ö¦|´*Y•×¥wuvÄMµ3ÁkVaÝsÜ·>§‹É‹"ñ]ÙR¿jDǯ p×0vÌ#Íñli ÌaŠP,iİð^¸°©%€µÄŽDÜTv`Áïƒ÷dïneNr}À|@_¬¯5Ö'q0¥†IË·ûKKÃÖ‡T ­q=h.òë‰Î†²¾2–o=9!˜0RRSÝç+´ÝÚ7º ÝÈËÏn¬ÉÈdKçVÓòŒ_¶H_‚p0«°$®cOóøgÍ<2VÏÃ0ü%h™]8u摤á«ßÇú¦+äÓÆMÂùëŸ~2’Ó™æ¸C¾›ÄMŽ’L Aî´Íª*³²’ÄÁ‰ÂÆ…²?»¦zKJ˜ú_î£ÇáÛÎD}-œ òñîI…i:fOsÜîh•¿ŸÂµU S$Y2èHƬ`I#ɨ'uÄñ[ÄßcLoyæ¿À7¶8º¶ÞTÆþñ[ÞÔ¢75·ÇQ#™ömS눞-Ÿ—‘¥[Š-€ÃM-O-ÑzËÛãÌÀ¿+Ó£ë’H5ØhGâª_$ì–ð«r*ÄoGffîÄóx.-ä–ñß•òxÀ’£b¦/Ùhÿ&Fƒ÷©”²>c-I÷dÖWìÏÑa^ž¡Â`­\4µ¶ƨ².+È阑4:SVÏ*=àÓ5®Æ Ѥsü)ëÔ¿Û›À&Ö*õmA‹ûtews_XÙÝÒðákwk¼_("’\œè›Y| €ûYrs™ÉwPßýÂ+ÇûÂD=RªI†ì¯N)$y^‡§Ðê”°y>‡'ÀÓl^XòøoŠHk<;db%jä_¨Áá(­ôÑ盆Ë}’“ýç6ÜuJ·„¼°ÕÚ¡áøºû85ºë°‹oR3d­À4ð÷k/PãŸF¿t¿¨#ü¥Àg@5ЀU@X<4c¬ |‡çp î£ÏרÓu–|®6š ,E[×>¢Jm#Ñnä>Ö›¥N¤J´'CVᙈ±g­Ë,ǸÉr\ô6Rä Ñ(òì#?hP ~)æ9Æ6ƒ6©gx¯Ö5´·ÀŽ%hƒ­  ËÀ í@>t¾,ê¬Õh¢½¾)D;ˆBïë`|>l삼}Ác±n>¨ŸÇbÎ õ‚âWâMuú´V*|´öÍ{vöÄö³Mÿ1¶/¶}l«¸cÛ r°F%Ïj{z¯‡Ä9Ú ±®£­»K(Êð\ IØß'@ÖE<­¿ÂÆ%®·h6ú^`¼Ïyˆvª7( Y•ûeÄM-3 ˜mÝߦ‰î=‚ýÂß4¶'8ö S0®EêwÑ$í2•¢fx‰þœñ|ƒ³oÀïW½d}Š9" Ì3œþ8¬_Ë>àsWÚ†{1ö dÏ#€qï‘1 ÖÇ:óö9OÆ À±Ìt>:þ?.1ÌxÝ—Ÿ?à1˜w,ÆO‚ÏsÌplr|plÈøG<ɘåsÜßpŒÙ9óºxŠv%@5>Jv¦Q‰±2_øÙfΞ›c‹cÆ¡—Ûq¯\ã}rLeQÝU-×–9ȱ•E+8ö™ªa¹‡ 1Hs8fm_;TÚå|äœp¨cç§ÌPµ›ŠÙw|îu|‘¡G(Ù2×{ôˆ6ƒVªï þ;Ð~t.üsXæà5í‡ô±ØAÂ3HÕ8KÎÝWrè†gHYùáËrí½"阬 ).W¯uÅÕ+ž·á´³i.”A[Æ”‘-ûoùÿ ÄyW/=…öß\C–¥ ÑKØ+yþ®L¿è*½UÊo·’ò¬ âæðŒÆ÷k˜æjƒ´H#ó.þ Ì]«uÓ|è©øR{Q]AGݽô%u爵ÄyzÁóƒnÈÄQnÌ}1–$uâõ.”s ß¡2§ê¬?ȼª³þ(s²Î¶)ÕqmàûYÖ’ws¡¯™¸|•ÊÕ›Yñ™§Yñ9z¾Ü¸Ì¢£™¦kK¾“§Ð˵†÷/ïÇ6™Oòžƒ¬ßŸK3úÇ)%Ž[È{øµ;y ÌBÿ<}àÆysÍÜgu¸Ÿµ:Ô¥Vöù÷.ÐëÖI1ÕêËÔÔÍLße¥N-e?¹ÎQY¦Ž†è±ô}âzªC ·ëh±¬Ÿ¡ñ®ëòn›)íå<ä¬Å½7uüÖm­ˆžV_$R‘—ÌGŒ4³LóÒõO¸s—Ò&õ°õ;u¿¼ƒ¢ê0%Ô*ä0tá³ñ.Ae®j‚Éùx (óØ~·†øä» }œ•s/óÙ»oS>0Õu÷QÆ—{ É{üMa?HÝͨ+˜ËSEEš ªô˜ÔùÞ Ò¸³|‘®Í yN÷r³Rg–uÛ[Du ×4ë‡äZTï­£rW›uU¾+ŠèQõ,MWé!´KeÜïBª@½lD}Ô€aĦÏîËZ-©uKÖûm²žç¹ji¥|O°ÌM“Ü4¡é%©F}ó<ƒ¸ºö›–%ß¿§B^üXú}Âï!óå·ÐûÕpޱ ²Þ°=oïÒC\=GáÃQœƒŠ—¥ë`úô»Yø^šWfS%(Þ£6)k¥ÅiqBœ¶ºù¨¾OOª¯áüNPPmGý~µq>jøRøê7Wödð[ðöÛDZu©—0n&d ws…œ±:Aߤê/i:ˆ÷Á%~#PPÛ úÐ@åGÔ-nQ·{jò|ëU9?c“õU‰£¨›—ÒºiH[ÜÍæ­xÛÝÅ^ik¶lã]ìã9x^©‡1šFDÖE dÓáf±z#â}Œý mUŽY§”CS.‡Òø15JÚ4#Çf+ÏÓ´ÙôS`;ÚÕ §vŸ;0÷Гn|*0ÄbÄ3(x‡À¯Y6x­»ñ³áò[§FôßF­”ØÃ‘2¹ævšƒõæh ¬S õ jàÞF%ž-T¢Nôrú.?î¹·iʽì¹”wiºô¡ðýìñ~Á¹Ëõùÿ5ßýç» xBÚp÷±Œ!­œ·.‚¶)çQ·7ã.ЯA¿Øñ§sNà_òsαB*YÿÌåçösÏõ^}q’žÌ†™xx‰2´Eäö½ÿâ¾Zc£:®ðÌë»»,×»,†36ëÅ6^b³”˜À6¾KLˆІq¥,å$²)´QU;†¶i!Mk7@ ÁÅMTÛõr“åÑb©"Q®TµU¥‚i©ú£ªê< ¢µq¿™½×˜uã4ýS­¾óÍ9g^;wfΙ‹ä!í|Æëê 9Êa1'ìÁüñºVCò”<Ì5S´Á™Fõ˸WQW¶×/yvå$b10ê_Œ;³®ˆue‡“~ûûØß%õû`~†z ¨C>{‰”€ŸGlÝßÖ}qמ<¹ßGuq—ü%¥Î3qçlà¬Ü«Ïÿ'àì¼ ¼¼ý¿‹ìUÀ ÈuY¡-Fà¹:ü!Càéˆ 8yC(ÿåõ@ÊoÁv¼Œ«fè6ì#ˆ# |TÍDþNÈ^}ÜnH¶¾ <“ìcø,!ÿþ½…]ÉöC/À‡Ìlè$ð&ðs mì~~ }øWÐW&ûByøð}  8˜ä¡çáwaŒß‰|äÞ¡Ÿ+ßëýñiÙzg„m÷†˜ /ûT|×›Ãþþ±ý–ø–ë`Í_3Ÿ{½qîbì×X —ö‹œRäÑ"—MCþ,òÇQï¶G%O·ú±Ù#b ÈEþš¶9sòW4æ=¸ÂŽcïVú19 x,‹·¢Î-¼u.!6yp§ÞÀÿ;. c›ˆkæ{Yú;r^Ô¿=|ÃŽiöÝ:îŽ ¦}Þúdcägˆ©! ÑÜËnc‰… ÔX΃}øuè‚Û,ýXø[öW Ï²ø ìYà—¡ ~ÉÒ¿m-Úí²¸í4çpodü9@ ÀP:€Ò,Ýh’²ï°mr¤àx{’±\Mf®_~£¦ø}³BíXÒ&,}V® +×DT¸í:É: X#ê4¢N#ê4bUJØNŒ·S$ ^ `X÷XwaAöýÒþ]ÈV ]hì¬c!fµm1 86ÙæøƒF¨ì,{Km°§ã³²C-w4×±Áé{DÝMÒ»)îš*¬›â™ÙIF­­‘t¶| Pp5n yÀ€r@e̼b~†=F¶;‰‘Λ•fÖ¬6§©%åÔwž…H-2iN|l £B!†ié:Wƒk·‹y]9®—áªu¥Õ³fÖÂgŬŒÕ°(KKŒô™Ž¥‹@ÆJmé¢Vw»;æîs÷»ÓbZŸÖ¯ hƒZZŽV¢Z­¶NkÐvk­Z»æjÕZÊ:wƒ{·›yÝ9î·á®u§qm<ÇÖãoH/д*Ö8 {{ ˆâkD±OÁN 4/Ðò8 šõ<¨çÕ«V)<µÀ: Áòj£»¨?(<ž,Öt¬íä (•Ðth:4µú•!ÌÐ ™ÔLÚìHÛWbùךôÊ:¶Ïm•!ã«ù}…4VHÛ ik!5Âe‘1ÂçóEýÑ@´ Ú¡Öûëõõj¿&PSPÓ¡–ùËeej±¿8P\PÜ¡r?ðÞ¡¶T÷TŸ¯¾\­F«ë«›«Y)>]Ü,* IžÜkÎÊ •z"Ë”ü(dp`„Ce@= *=\醵ÖnRD4´è× $·|ÂÞ&}¢$üÊ]~†?Þe.]T©Ä•Ú†¾»àï’µ“¥iAH{U¿]Ú9¤Ý†á‚«“×\Ž_)¢@F.³5ä*€ž!9Ðô*«Ão [£tã×¥t± ¡/œÁÉÌ™„ß4§7âU¦bè®B’rŸ”eRæé•úÍJý—•ú÷*õ|”〔¹†;¢ŸŒè5½0¢£·ûH.Ñ•RjBÒ¿Iù˜”A##W¿•«”««¿–«ïÈÕ¿˜+ÚÍÆÙÕ• )ÝBÒ—¥¬”ržáæúÛ\_ÃõR®Gtz”bt²\Ê9Rf I?<é)÷×Yú!)GOÔ ò„B$Ñ3Ý6Ã+AÃfø(è_fx??GoQÒèM3ï:Ì Ó UèYü­ àAðfðOI˜ÀÇÍðQÿ'hú12×)ê¿Nje»6Z!í¯Yí^5ƒë1ê3øMŒz˜å¨ÍàuX÷›Á} Íà6P‹Üb†çóÈ4º™ä)¢îPÄLª­EÏÛÀ+“W˜AѪ\  ›þ… |1ËsÔOjåpÜôË?™Mü²‹ÙÄ/'E’Ó©GN^'s%;Mÿô¢ \çÿ ŸœÜ ó(ÿó9ü¿ÕPÿD+ÌNþëÓb¹L~9˜ Sü’ÿ,¿— «MÞL8á8L(´—ŸÀ"ÇPW¡§xOp3ïöKo‡^|ê¶ð~Ä_Ç_ @7ùžà91 ²ÿx5ÜOâÕáNþH Aá6Â̘—ú¿Æ„yI‚VÄ;ù¼„˜J úè<ÅçcÄy~9•/—žQýºtìr¬w¬v<îXæXäXàÈqd;f;2œ>§×™îœêœât:5§êTœÄ™‘0ŠNa†æ¤©Bª²ìU„„·¾B ÎNl:«RªžXNc¾*Rµjy¬´¨*áùRlIQUÌYû•µ'(ýÑ“ÐbÊÞ%«Öbƒ ÓsY1ßÃkOJÿÃzÕÇ´u]ñ{ß³ŸÁ_Ø`Œ¿û›ÀÃ|Û|üŒmb`á£+ÎBÂGHH¢ˆq;)i3²…-M³†¦¨™¶”t‰´˜8NÒ•(YÛ,Ò„´5ÓÖEû¬ªªê¦!­v®’TË?“võÎ9÷Ýó{÷œûιï[2yJOäøä©P£7ûP°×]i‡uˆ[·G…æz R¿àÑxÒë”U þg°î Î=iîé¦ÉŽNÛ;£³CQ;é¬g‡‚ÑÍíÆרaj0à¿F 꼆Ǩá@ÇcþÐcb©!€!7C,!ǰ¦ Ò” øçX6 º… ÒçV´79W˜€¹¶0*å%æÊ£r ò!9YÚÓ“INKL–&E‰É 4g±¤ÈB sÌY*êKOÔfKÒ²$ìXp(aã'˜MI dÁ†J ÷ÿlýõÿÇzîïî ô›Ýæ@?Pwôë/ h¢ÇzƹÝ÷‰Â¥­Ý½}DöôGï›ûýÑÝf¿q®§ïê>¢î1ûçP_ £s®ï÷_éá{æ(6;á ~ÎÖÉǶ|Ϙl‚Læ#¶fƒÏP‰z–Ø [Abk–ŸMØ ¶Õãà¶Î¹TòíHÊ%Ã~èÖ›BõjÅP]bsÔ˜4/é¯ ü¶$\(*5×Ge@DeóÚ¼D»“¨ä0œ¶¡Ò¼TcÒ_Çon¨0¬4×#iûü¯p8í>ç¾ìF"!N_`Yj;ÈN°§Ùsìe–!Š?åÝçØOY:Ù„G ü ›p‘Û‘H˜4Â@Is\„óuzYÔÕ.†Ê܆2€Ì@å@í@Btø¯þ ô/ :ü[@?Š‘ÚFÛš}~b1đކ¶ÇJöÊ8Èž=IÙ¾=)-IéöÚ5 ¯xÊÅÞ4(¼1ºü.Ð@ŸýHHÛi{bòH2kCaæ0¸àf„°07‚9è`òºG‡‘‡”ßÏ{„ï@‰Ñ0y,Bä |ƒ  ¤ZF"Ôâ…è3dÜ„ç?\ÿ¿+<€¤HƒnP‘¥ÂÁ"ÕUé@<ïu¤c†*ÇäëÊ÷º_èt\@óàoœnœ—‰hŸ!¾“—!$(xµCÌ j+KËKÊôª’%äYò(>*+ÅÉ•r¸ÁÍ´Õép•ÛÕ™*M8cfɰv2¾’¯àP±×[ „÷Ò…N§©)¨á•zmdØæ…÷…&i3õx.ƒ#ëÙù¸öŽö”–Æ×ÆÌGBÚJ8¾þq \Fñõ;|6t´`ºJ`¤X$Í’RbÃ$,L†â¸#&¢urWT4‚%]•ÉÄ9Y›Z§ËRŠ ngDJ¬œÔ¾mÚ??¦•®Õ•ä27ÖºêöWÎáá®oßaLç?µZÓÓK§x—šª,æª2ªÖz+ÔN[QµÎE›qÞ¨Vë©®.{®oí÷xÓX_]S–ÿêÚïHv×ÿ,ü Ö]†jQ#ñVüSR1#OÕKŒj¹Þ¨õ2› õp@)¬Ó3;’³†Jí ’/’§; øòüÒ /¿WÔmè.è¶÷×ÙGj?0J¥2.ƒ©³{ RUÈ0qÜijuU]ÛJKD¸ÜPÈquÞÔÔ²DÍ@‘§[¯V6˜éÔ85ÁK›Õj…¤Œä .¡€•ù”˜uø=H°êÝyƒ'7˜•¥“Åñq>C›kÅÖ—»Øy£fn0w(—‚âÍÆëýî]ÚAí„ö´öœö²vA»¨ý£öS­X«Ý ÿ»ã1SÇvAËrWóÒr¹+V[ýþšËKäZ-@v‚bI±äYZNÈô¬* ôUy1wTñs aƒ+AŠ_@’BÔÐpî:<ŒM™ C‰Ôêr»«"‹!šÏläi…xE2ŠŒHår:ò­ùH«™e2Uê +ACždâóÏ·G…¾±9Э²XÎlûÑîñ÷†ß¸õã”°/õ}qúL|b*š£.X{eüH¨þùû˯ì©ýòèTÄ¡÷YDžµ[SíÁFý©¡ý‡ž‹ŽþóåÉÚKÛNíÝÿý]yëW¯çé…’šé[vŽV—®j¯Î Ìöø”x­SºÄ.oåõbù±œ½. ÙR²â’;’ßJ>–¤dÌ3´“J6/–JSÒÇdçÉ×e 2¼EA^0ò4“,LJ!Á3žNè×]Y›­&‘Ä›Žp·¥–3$o¡^\ÛJ _E¨š7O+/(©Ò“JJ<“ªD38êPqê›rvƒ™cªŽÄ`×Òª;Aˆ^Y)‚°àLk¾•r*P N¦*+‡¢Æ¿ÛÿÚYl_9òz‹I·õèÚ ¥iÏ<õ>váõC…þ¿¯M¿ó›ËS¾>ƒ_LøPÅç S¶i0®'2 nMƒF¦”áš9–Ùyþ¿À]Nu–:=SDN—+_LÏôŸ>»¶øàȹf“68.Ü]Üó͵ï­Ý]Ç,¿áïÜ‹NÍÎPÛè!ð  }ŸÊì˜Lû’ëš|Ak˜o[ÔÝnøƒîý†” a¼2­ZWcuV¸ÊÛRTÙ VáVyUõ*_‘¾(P«¯ ´è[»ô»£š°!ìÝò5Í Ã¤ïä–Í´á;¾™-5³†7|—ïZïV[}U{“£Á%ÐqùyÙY A®X†ò]v˜äzŠÇY8“ÌóætÇÆEÍÈîe:rïåϸîy<ÿaºÚcÛºÊøùÎ}ùÆkÇÏëÄŽ?òô#“4™—œ¤–GI×¢­™¸aj2ÍœuÛ¨’¢ŽRimZé ¥É@­ØZÔmÝD¨P ¬Ú©š5F ŒŒRº¸|÷&e³åï~>÷êÞ{Îïü~ßï ô%ûæúnöñ}¯nÖD—$m]ZZZ\B½[\\JEîéLJ©Ž !D?Q@Qjni~˜jÜq­È?ÿè¹~us‹vþ!á´¯vÉÊ}\ðwÞSÙ®ˆ7‰-õk»*ƒ±®}S½/õÆüþîöšG©3œ,‹øq“ðH}wÄ[^™¬©)˶?ÒÜûŠ/ó{vñŽuk#ø¤U±7׆VõGc‘6ŸÍUfquUùëk»êZ×¼XWÝâsÆ“ûWU%7¹¬ñrµ¥Ôä0«eŠ×L”ÅjÇ´Ý!ùíüω‘L1o‚&¸€! ó bÂ8BFŒbw6úljÄU‘<ÑUŠ!ÌdîñKF#É üÑõi‘«º YfEcž«b^!‹› Ð$eØèܤB€}Ê´e™1¹Å ÖüB†$ ÖBÆš^‘ÂÅ¥Bf™B[°)hk´Au-ðáFX,š¿6Á?‹Ê¦¢Y›Ï®â)xƒ¼CÜd3«ÚJ·º¯»8ÙUoªœ DâyÅPJ.•2“‘oSœÎq'çÌC-6»Ê€BÕs Ƀ^$³a)£Y€Bi+,o $qÎÞÔ¬Kf¨ò!ÀËb×PN–$c¤ÔÑÐÖÛÜ54Q‡Â•a*Rà€ŠR¤¼ÌWæ/ãD{T‰£Õ­R1ÈÛI…è‡3— ³0¡Ì€¡Ôê$j Ý1i¡VÿÕÖîµ§JµBëvÙT—†«[/ÉÍ6­æê[ˆö¼¶{[öØW~ã׃×ö~ùúºÖ\ón<n­i[ÛôXŠ¿ ý›:§~Q<ó·â¥Ãïÿìnñö¹Ã;FOCëí£Ï'ƒn.CŒî áD\19ÂÌ“õL{æ=<ñ0}‘|PK§žNôÛÓ¤·–0!Àÿ! fçíy˜á¤¼$Àã.˜Ѐ: ÷gf`Ì1@Gè Wé½EÿA T­˜CŸìçBzyGg6 ­¬±–294ñ¹s"]ó¹-—'d¸*ÏÉ”dr[ë +N³­Ôº|É÷¨U<¿Õ’Þoö\·\×šÑ "¶ÜðpÁ&B–¡Z©}XÚ¨\…UŽ;5ðñ<ì€Àñ]OOE#êÜÑHöœ¼×ƒÏ>¹Þ Bñ~ºà·öž|!wå—¿™úþÅâÕÖ†˜¦„Èò'ÏUÐw…”<˜?oj•5‹Ÿ6µvÊëJÖ{+ù9jjV×°T65—šOÝ-‘H :å±ÐËñ·ÃWÂ3ññ[¡[‘ßÅÿZù—ˆ©ÛP“‡×.TW[Iž.ÜLB2Ï¥.r‚Õ®¿¯h줦ádëD·»Üß²j—²ÎÌŽ)Pk§„‚ œ,ˆÀ›Œf›̼h2#«ÊY©dpH’ÁÀñ’h2 3˜gቦ˜YQ6ˆ¢AàM&~º‘/ØÉŒ²¬p0Åá(—‡»Ì:½È¢^Í+œ"2 $Õò)åÒ:Bi$¦¶.!@­ tZ¿µ4š¶µÚtÂì×ñ+-—¢(¨h£èFr£à ÙBèI À]¹tbé}a׉b¿ ;ÿGyµÆFq]á{î"vÙ¶—Ø5{¿=k7ؽ H”iœ·æ4ŠNHèÕúÉv #<ˆåkù¢_¤z‘?¢&[0 ¨hšcQSBö7Õ‚WóòbM°…›HaväžFa¤¡S8-œá¯3b-µÍ+KètÜ8’?wâàÙWZæõÿøèøŽýãG·]y¤¯ZfÆmkפÖU9| V-쌚+þ»#OÞ¸xþØùºaŽÀ£³53«{65þ¹"yú¥ w¸W÷cä{1ò^#)èÔÆjѼ¦B©D¼5ÕY˜ÉÏd|w4ëMóœñ¼æ{#öfü¼wòÿ`vHˆfê3Å]f·/jŽZÖÃ1ø‘ù屬 Ëa=Yëæ7ÀÖx]ª™4Ã.º#Öß™zöÇ÷-ÜŸêãû„Œ!cì¶vÛú}®—øÆ­'l®_Ä^¿šåGŒù-˜°LÄ'–,0˜Mñåd|k‰°ÚH |q^ïd·®JEaìæà*2œ s€µ¼–‘•d’ÖÒTK7¦³éi>¹Œ8̆fC^‰[s÷»9··t >ŸÛbL¨NéÛkòÖTN«2èù„{IQR)´ºx£3ª ¦†`,t$šH± kC!ÅBa´ȵ¨‰$­‹r Ï¡Î*Ûvx¶c?0¶_³¯Ñ²9ÔYØE6ÌÕ 8òrýø¹Ó×v_¸¸lßßÞ½¥?«íÛ¾=“^\¶©êøS»»cké…ƒÙ-=Ô¾ádËáÛ÷ô½ß±mïãƒí>P¹ë™}•¥;“³Ys¦ñ‡Õ.kfÎK?w‹›T rÞQˆjAó޲~o¸F ¸©$͉†¦´ß™uRçeˆâÞýÑ­ã”®tYƲ4ö‡íÊL ¶…ÉUlä.æ|Nñª{E±Ãóè G¹A\O„<©ùÕèÛÖe¿•®Ò³ßî”M#ž¶.Ç(·Q )š½–d ¡Á*óËË%5¤fTN½æ÷Îcv AeVRÖÝÏ ®2)ßÒežŒ¿¶`î¿øKðÍ-þ‰ÿ4šÜ –[»vçÎ7-'8y“ßÊ¿ˆõó‹7–rà&‘αr>OŒÐLæRH2Y¤¯Ê?ÄcqA{—/ ‘£¢@s÷&ÂñÄ1ãÄU qaŠi¿š ’¥[˜ð°Z+ÖX)´ ]BFà ÀAh¿UB£@qšjB›@‘>*ŒÑM¸)þ¡¹ˆ$^iƒØ'ÒV±K¤b¡æ Dxª ôät=;ö”cy&Éú=“>ï̌σƒ<9‰5Ç£×èûµ¬LC½œ€gœ/nâNÞ§¿«g0Ûü8|İŽÂ'|·™É@öŠüС’oà)…Û€¿Àqq "ùWF[±Åp†Ð*ì²ä:¹SRà:@ hŽ€ a4”u&‘$uFý¾,×uÅ—øíú%YY¿§¨|¦ÈLùâ»êÔ¢üÒ»ï²Æí}lê1ü×Qį–á¼–ç!n‘q˸ûÞh„ü¡¨CÈÏA(܇"„EÀJh….ÈO%¨Êîûàð­$qªŸÞÃo¾ˆ:ç-Œ ÕH#éÇ ñ2¾®„T¡ö m¶ÑÈA©cŠˆþ€ã-H³“¯½;ÎšÞÆ—Òã³Å[à8±u6Á• . -$@BÔ3Hõ(Ù ¤P%H°N’`°Z:®p7‰›[wSsi@á$cÀ$¡6üjL[£D$¹’Uá®L2&Ƶ}þ$s‡| çêUÛâ¿æ7Z$É,ç)¦P•*:%»ì³úüþ€'(ªhl†¢i6 —Ô”êcQ±>-ÈM‡c¹iŸ’›vëÓCN}Ð~*ÛKÍR>¾|™ôi¼N©Tk¥jy³£Fi–vÈ;•}r†ï±ôJ=ríˆr84 È?³(—¤Kò¯|—”÷¥÷äkÁ÷”O¤?Ê“>•?UnK_É·ƒ·•…&i½Ÿ†P‡`HPQ&Kžßä ¸ý.#5øN«Ãï|V‘ä°¬…VÙam³‚U–,–Qú®f¥ŠƒR%<ƒ ë…×µ£,qN—Ëh4£pG3Iø7ôŒE³ŽÒ’áJ”Qú™f k–*Ëß-œål¸¥WÏ ¯ÙÒãc"“¹Z¶W°ŸBÙ9SÞcÉiËžz ¦EzÖ"‘'A~ë›}|àj¹¡O]lÝ; U¦jÐË›SM—--[ )pånùæSîÜÌu…+šfÿMvÙÇ6qŸqü~w绳ÛçKüvgßù|wö…slÇg°2r¼ŠÂhÒ•dÕ",ÐN+Z„†—Ž%LoZ•¨h˜Ê¨«<•—ØØÚ?*ÑI›Œ{i S·et*‹Ùïwºi’ýûÙeËz>Ïó}¾OwwØœþ €«sËÏOß}n®þõ‰ûàÃ+I)Ckš7”ÝK¾ðpÿ®çšF¦åÔàÆÕéßCuÄâFN@¿/b6ßfe{±^q7¶KÜmàßJVùjò.ÿ—äÇ™Æ9ØÖäó`î€yT}ǼÊ_M^Õ]d©†|ÂûR±„ª"Ï£Ûú³?˜7-9°˜ÏYŠ!š_¤.Òvó×Àõºy[£IhîKø)oj@÷gÓ¹Åê²ü—Áªporîc1¶Ô zÕ¾R¥4Z:\bø,Ÿë–æUQgH 'Ä ØiîRª×L:V²J]¥~¼ŸèsôQ}t_v˜â‡„ЏQJnÕ_§v;Ä1s´ôQæzæžú™^Íx%Á)ÇYIÈŠ©BåIaCR‰xËœ”I¤ãz¡à ´èÁ`Oë¨RÆ¡·Fe_*Ø×tžè˜ŸGoO,\bßV3ŒqM¸Ält“†4'Õ†>`8‹›·JÀOŠ ^øöú3ÝZQ$6|SNi!õ½M/¾í¥éŽo­Øt,ððáÈæÎ7W’8+°eþäðB­Vn-pŠÁ3DFÚç= ñáN{ßãþ{¸’½æßxƒØx‹ØÇW‰s„³‘ðxt)±špdÖ§ X 8Nág±±ütì C †ß8å3޳€­óO¹¿ïÆÝ5"cešxäØê»> ù:|¸·`:Ûc!à I!>p¬ùÔ±ÏÎþû—`å¹¥&!‹¦¤§ä¨NL„µºAhˆî`¿Ëþ†u ³ÃÍ;ÙýMü„ ÑË,òqÍQ‘ ý`'¿KÄu†’LŽÓ’à–• –tLJõ@c"íÀ8–‹qYÎâ\íÑO£rÏ(¨çu,ÄPQ+7B‘ƒv7ín ÚéBëÛÈÂn¤ì Å£ u(¾ö1Ô‹Óö פAã åó–›û¤Å"¼èõ³ZsBôFzï‡GÔ'õ¡)Üó$ýÛ·c¨cÊæÿ6FŒäü,MÉI˜u j%ì ÅìQÔ:´z_x¿ú~ýÕßôܹú¯>éÒfËCĆ‘XJÛS?©~ûüå¯DÀa°(Šjšò$̸ ŠV‡Ux)²)ò½ìCÕì¹ìÍÓ®Pz„qŽR£ô3ætª’•ãš$²ÂX(!ŒìñHN¡Q*e¡e—(ްè?¢&vÔHc­l+ÞZÃ/ÁQ‘2`A w"‘(ã¬2 Uí Gh£Yº“&àoMX]öo §«)CjÍÀ¯nà«1èhn„ð|W¡×W¢€±6*Ö¦Âڨظ¦Ú¨T;¨Ú¨ÔCù›gÀN{5C˜lV°gÊ“Så[ÓWy²µÝ‡^u{´C©„FùWvò>ÆþÓo„JXødÔ¦OI$a£È¾f([¨O`Œ˜¶Ï¢^‚¯@ÌÚ˜ÌSšæñp_ê®_aõ9C_ÍΛ¯¿úð^6kÄ‚¼º2Kú½I¿™Ó×;ðé;Jzc]ï(z}~o2ËÌÛV¯jAÖê'¶‹ºVÿíË]~/"*C¢$Ú fýXÏÔ€hÍÖÖ¤Óu„ BLãŠâkÂÉdšþÿšKOøÁÏÁ‘O»;Ýš’‹}êvÅRÙ¶é³Ù•‰Û%Á¢ þæVøÅë¿¡Ý[þJ½Ð¹L«÷¼$‡¹¦µÅ¶f^ׯ¬Y­#^Ká´yN›<([+]ä’4Nò:ΆØ0+Zžâf¦ª„7χ‡Ž‡Z3à ;ˆP1Íw+Åï?"oÉFbGÃ/ŠÄRr ý#Î!jJÞž?'ìùN@¸ÜZØv0 …┞"·HÕë×´,[éûSøê€i7™p »‚'‚d#Â_C[É®à6{góã-'ýÇÒ&„ËÝ=iHÁò ù%{œ§ÈçpàHðxÓñî?ÞÊÊK±+H¼Ä“ùÚCñxðw©:DP!•–×u_áÛø æ|ä¨èsýŒ­B¾æZsû×9oëîyΧ¤o¼(ªP•! *Þç*ÅÏ¢,E©_€af1E \§X’¦ŸRXH=‹{Â=æ•Ó,㜇Ê݃¦ÏMÿäSàœ~°ÃcE­˜ýÀ¼ËüUdGz]ï<³'[Or¦Çá v °¦¥‡ŒŸÜbõ/Š2y#†cbŒÆèŒ™é Óþ{K±°Æa÷"γb—5jÅ־З¶ ¬ÖVÕWq#Ê?hAlboݰ†] ¸’¶T0åI9íîÀŸ/Kª63©¸VG˜,¼Å—Cí&²Ü{XÊ>2ÀDYÜŠÓuA¹–›£Þ‘ws鮃žnìn|Üø°ñôï¯üóü£ŸÿúÙ+ÿ>ø( ½Cß6Þilƒça,ýÕë}cãË7΀,<O ”DÛ¤™¥v]D*ù«ßî.åÕþíÂöÐ7äaõÅû„ÿ‚tI¾!ܽ/µÒœ*§*ÉJºGÖÔ éGÒÃê¨j{A0” õ‡~¸!˜Çeø¥ô^ûûÒ{éëòÇRKHòÅI©4Q‹„h}q…cÙ°Ü+ˆXY_Vnkóa káQ jA=84ûTÚ‚%½%¤‚®þXÅ'Ô)õšÊ¨`$R†@BÂå4¦ÍiÜtúè<žS'áñ³ñÍ[>ã£ææ­ºj)†“ûH0¶úz#qubžòÕ:ñ˜|SAISCR¦=äOÊ©L{ªRˆ,é@¶IA, ¹æíÛ‡úI4ˆú{L‰H¬‡´0Š€’6‚}†ªAŽ£ò?–ŽF9 / é6#, ï&Xx%”ZUœy“è³W ú ;ÿ›nü¢³ö@é‹ámGVì,¬Æ{;F£DŸF·3_£Uÿ™Ý¯]s.omýÁèº#ýÒy‘ä†m¤ó2*b¬Ÿ‘üô¸’Æ¡%€ÿfêªx5ÇôI?Êa´]Ý*1V°&SÉåh á!iìÁE‹íLìJ‚±ØÑÜ)8•¼ºœ›•|-±ýðœ´?}Lz^Á¯I§sWr×µ[¹ÙœƒGmļLºÛÙ­vk[¥Gò­Y …À\ñJÊ"ùÏI’_TÅEw$%)Á‹1H8†ÙlæU–b¢þ\–cW³³Ì ìK,f‘0*N·tW—‡°Ëé$ñÅÂÇ©]W¢›þà@ ÅOÇñc?Ç•A/—¯•™rÑb ÊbœƒÅ@”%Ñæ3å3nú DùŽ—6_4lù¼é2àÄUkwª#ŠBÑ”o¢)?‡¦9Ñ®×9§j-¯Pwrõy'|%蟳ÞÊgÞûóNÍOñ–댈ÑdNÌ 3B5ÑQ@¢¤Åº €‚'05‚©š!õQ’øo;õß·Ïx+2õç^ƒ¨IyûWÑ8¡fh22‘yE‰ÇÁ€Úÿƒ"Ký:tÍ‘`Ѽ­ñÝF©sD¸PjeÉ¥aá¯×}ø‡§Àÿð¡¡éÅžõgWO<ݽïÆ÷C³÷䎽“©ÆžgÖÙñw`ü©'Oxh®ýÀd&¬½¯Õü‹à¶1Èe’QƬ À¶º»'a™~­¼°dÓ&ÿ¦À¦à&¡Åì0;QvªÛ´Ý¶Ý±Ý¹Ó5Ž燵ƒ–glcŽ1ç~ט2n/p¼£à(:JáB¸.ë†s¦X$Ídr…%°÷š´€Ñ¢Z|qqqi…cEvжƱ–[“Y£„£ÅB!ZʃþÁÀ`p}×ÆÂÆâÆÒÆò†NÆfËxlBF´Åº{2Zw¯yJGÙ£ùïiãù)ù­ìÛÊT÷ínï, 4„…Óð.`x.¡I¦_w”Žu†„ðPTˆD.…ébà˜7K0fwzív§bÏ:M)«±µˆ0Cœ·ÜɈ²×Š'@$ŠÑ¤&AÔ¹¼ûŠßtCÌ}Ú}Ó͸'ñØ…èDDáÈDÓDO¨pE½¥ÎJÕ——tõ]rÁ 5¦j„hMêeX†*° üM¸W«Ê‘¹Úú M¡µJ^ijžÁ—Ô’ÎÅLg3_~r‡@ºNÒ­ªÀÚ`Ò²¤±9eë°PÆEÉÔCV#—­9{ÙìJš#Ôêrf²IžÐ«%ßB1¯4j,M­$è'دҜºÅ¶Õñen‹Bs*nG#Èp¿v›ßU1i®JAs¶d=¸E‹‰Ílp-õ¶‰Vt"¸ ótJJ¥JÅr¡‹Ênys*ÉW'6n; ,ùè§Ïöÿ—îjÚ¾ã¶ÏÏóåÎgßù¾øqŸ}¹\ì#w')猲R’–°E"@°ÐÐñPÆ 4€ÖÒ”ªRym+L›¨¶A[KHT*[ÅÖjL¢›*¡ý±…‰Q¤®ÕX5Iöû9á¡M;ËþýüóCçßïûyýý½Ö’òA2QKéz²çìÆ¡ ZŒéŸêœüÅÆͱ¤æJœ>¶j÷ò…MCëŸ=¼ü蟢"[èǬy±wÞúùƒÁW»þ¡œP,Xù &Ÿö4ù ·¥íÅzk{åt¨iK«h˴׉J'‰ã…¡µ²³dšì™¡âDÁ¸­M`]Aóˆ Vøx]ò6‚#˜é&iÆã9Æ£4Æã9&•¼ ù1Ÿ@dN^-“qù¦®¡“fõv$<,[†/x‡ •Àç¯sm³QÔ[ÄeË`¿é†'±Sm@2¹¸`Zj(d²p 2ÿÅCÐ%‚eð7BYVP¾Õý>p‚ÖÔ/¡-üéj³´”ÊrDçô¯ºëZܽ}ßâ °ñèB8«ìÌ$1 fµ}áb»[o•lh{Õ:¯u»ÅTÉ$[ÈNrG×3º1/3ÏXœYl¼iP9Ã1°.{Ý:j¼oü+K¶DaZZQ¤„–®W$TËŠ×2 Ât³†©Ùà‹3pÖ@熼œÁLÃÐnÀ¡]`/i›Æh+Üp$µÇÓ!> GÇ=AJzÿôñJ™³ÑÍö1û´=iã¶¢z‹©z‹©z‹©¦y~·€nPÁÓ.!¯ 2¼&$¬ÛsÌÞ"= ¬—<ò}ž1ò!®=éš ”ËwŒ. t³šé§µŒ†‘!ÝÐë‚jáÂÙ@®€²~Ó ˆÉêÐÍ¢PÁÃõ£‹ÈYôóžîdÖ<"þæÈ÷1:ÙÔ•.ÿüòŸnØêâ§š°¥¥îºDmçký{ÿPÂÐõEÊ–©?^¾öÆÑïUÿ‰ñCOëz¹nëÔè²Ë[—ž½Šé»ÕPv.~!yZ»C#‰Ÿ'ß#ÆÉsˆ±'ÈêTô„HüˆÚÚÏ÷kĆèÚØ ¾Ã¿G#zű.m¹"VRUz¥U°%\­ éö­ ¾NªV›£_Ež :™£LÚŒš",¦fkk´+1JÂrSHPSýbR¬}"U?Q §h%ˆAüõqS—.].·°¶ãHn!P E9)¤ÁÍJL–”‰™a7,R¤JSpCà’„\cà,¦„€ÍB0ŠdîÆÐا¶èŠûÅ[".Þ´£n´+z:z+J¨Ñ5ÑÍÑ=Q<:}6®j?Ð^‰CòèKÜî»Þ‡Äç’nÛ01« {’˜ž IÈÅHBu@ÑY!0ÊÄ[KôrnÚЧqƒK<¹«_Õ܈VQ×jYLˆN½F+®»» ?ÐQ2„®3uóž¹÷W_x°P[f)@&’f®QC Ÿ<[{ã ÚœËF úÜï`–bl gyŒ¥ ”aÌ©x…ø  YCh?Cùý6éP|0.8°K°i¦Ú=°MÖ½ :ó™²µ”©â=Ì †Ì’yº5¦`&sR½iç“N²d?A>Nu°K¤n²‡ê¡«þž@O²Çî.n ×RÙþd¿4д ßFn£¶ù·³;;“Û¥¡Ôvõ;Ö^üUú•ÔËÖËö¾âAê{H8?’|]:l~ß:lŸ¤O1§ØSÉ“ÒHêTí kŒ£ßõO$ÏØ¿±ïÐwØ{µwÔ¥ýÖ:»¿¸Á›¥ò&åÛ|µŽîg|L§²Äì°ðª´ÂZnûº¨.º—õáâ6+%Zõ©œR¤–™«úZ„om‘l&…³áÙ™•xšbQ–v –=¨û6¯ðaé{†–~“JÑ ãOß%Ë4B Ɉ$˜VN2ùx‹!g%Ã)6KÎÄÌæ1‰õ«3›ÜˆMSj€eÓ¸[J¦R2ã÷CtD¥HYµ4¶­ˆm[E’¢à•”]§E7L„Kcý~š¦˜ÖŸoÁš½ã–‹bZ¼ÆÍì’]ÜSÜ_ô-+®.®)nöN&‹·Štñ&ý)ó5V:›dÏc*’Dÿí²n +p%à œhiÀž›Ú—}Ÿ_Op×ãÜÔm/¤ä§n<È%^3‹¼áàÐ,òvè¡G°øÿÁøè‘â‚m4Ø(® bô>>ÿò‡® 4bšbME†Õ%γïJªh4=Ç9DÎʃIÁ0²³Û#ƒs8Í”©¡òWäH~ú%sú·Ó¿«›~¶ˆ,nE¿Œ—›Pöš©‚'$BãêšKG±†Z1û@p¶”yñîß7ïý_¿+–ÕuÝNgvMQØðÖ•ó²B O“`(×´{JÁ>{ÞŽ™tÐCuAˆ·ª+¾†9E ãT\˜>C¶,0un.ÖF<›hƲX‚&i¤~°=™áî=8·#ŒÖ$˜l ºù®Fð€‚'Ý`ȱ¸ˆÃµ»y·Ý× ã5%SÚ†l?—Þœ®p4}$s=Îh#é‘Ìñˆu!sA¿=ß<^ù»$]R?t.¶Â¢Þaoµ§x‹Sù´Z—7-ë1ÎæmµU›oØù'iWÛíö+íø¯ è`áyko~Ÿ…/ÊWUÍÇdqa¥½#¹È ùH#Z÷Æ«7¶mãŠßÿ‰mS´%Ñ’,Q´Iɦ%Ñ–e‹Š1µ“Øsâxù×4«M“%EWÛÁ†eEWeufdÙ†+ºb`] (Ð4õ\gÙ+C€¢HíC‚ úa˜× p‡®å½£œ"ë¾L6ïOÇÓ»ãû½÷ûåžN½žz=Çn"Pg£ÛÝî ™#A”ʱ1ƒE,ÊG}ô(bfɤ0ô ¸iè!<¬Aã9-³)-/ëAYWªg•*/ 1>ªÁ*él@X-dz1®]Qcí¦NWÍÅJY]–uœmÃ8 ™S¡`Û¦åÛ4-ŸKë5XwJ% moçyÎ÷*®ZƒÄÔ°ŸÄÓx_Ã+ø~€ýx™|æ¶Œhûµã£õ#ýŠNôeòû%wû+µ6RJØC8ÑÖË, !ä!©yRÿ|m[àBSÀ¢¯ÃÉ0(”ðìðá¥<îÖóÛÐ:”aŸJ·žËOo§Új …<”µœHŸ*‘Ö)79Š¡Û*9jÀÉÁÕ9vL;LÇW–ÂŽž ÓÊxïzØi³pTY¡_>pŠ“õ)Ž®)N ¹Þâ¤FJ Fk«a¶ýwyý⃼ÖÛ‚}š?8d¸^šÁ´æ~16„ñ#•¸µµ1«1B%3‚;Ï~ëÈúoËñPLìê÷³Êàîz²`l›Åný“g_}Šœ™Üb¿ÿžV©%7Šÿât ÙG>®O,ƒ¢Ñ‰wá'ë/—Ó!­‡1 NŽþ~/\~ î˜\ÜØU÷ fB!9Ä0Ô™8Eqß ¸ÿµ§+>\äV<†~µZtí£êÑöI›í<9kžM_Œ\Hóí\;OBÍž´9Žƒ]dB„M! w ™tWÆÈÙöNìÚ_Ň…#‰Ã™Iû F8“9Ó3c×pŸæ3µžš}¹ç5ü¹b¿ÛñaÇ=[;Ï/  $†‚0ij±$Êäb¨! jG,Ñeª‘ÈÜ6Áç£ðÐӸ˨f$Ÿl_FH›*—”1BÉd‚JÉHxyã³E*1 ³æÉÚq[<%¨»>‘x2ÆÞñ”äZšž‚ÒTÔÒvÚMO¦gÒµô¥´^&¯¾§ i—צ¬(hŒJTÝTâ†&z-°›TÝ,?Xq6d=‘F¿‘|Ëf9M ´¼²3;‹@tà9L¡pq4p†VÚ¨4„%Ê ©¡ý–äÐ¥K)¡W]  }I‘Ò°üŸÚRå}üçhôø¾JýFÜÜ×»¾BjýGå¿Òf’‘D~ïVÃþJÇà Ԛܡ¯¯¯×ßx(WñvR:Þßé7ŒÞÞ®£õqüË£¹xo;²«õÓdš{ 蜫º"F‚ȰœÉYàMˆ:1‰2”0¸E¦ÁÊü:‡Š2£13LakÌ%†\a0³Àñ×0ž$Ó„@—qßÛ©Ž@›X›¥º¯ì`6?±ãéÊö¬Ã›Y¯x)NS!¸Èt}/×ïb½~ZÀ{ÿõ ðs¼~Š0žŸón—+^É´ˆÁS^01’9Ö$ŒR1ucrçÎRã&ÀYNãf¸ÇÖ¸K¹ÂanÁFo"‚ÀÏßá>”B ,=W§ö4ÜÏ&dêéÔ#®6ˆÿ°@”ýƒXÑ’N­zU\ò3Š¥¼€^(ü] \,òJ¸,WkUVŒïævó;´úî²[½Ðáó7 ÒÇð¸,0V.m}¿ð)]Ó _ 8 v´Æ‘ÒÚ’lŠc½s çÄQÉ7 áâ@@‰ËqܬCSæ+qšàÀ HrÐÀ¿ÕÓÓsîÜ9È“/ñì¢\£ªxUÚBs;û`§9J dÏ,5;CZ3­ù4oj”Ÿ€+h'WœF{4àøáUe¨õƒõƒÁŠú)xöi@)ìÔÍâ-ûL;uEÚcƒ…þH8ÛÂaš€‡Bt<¤$èB¡Ÿìúq×àÖcÏ'ºÿø·Ç÷W “äM#íòw'¶Ä¤E–B•™}eü³Þ½#‡J»çŸ ¶ÿôpßÈwu]8¡ë½å\ÿ@öÐ¥îäcÖùú{/miš*¥WF~Ч*í½ÓÎè1@þÆç÷™ÜOPuáÈ+ÁQËË\›„T?E¯ ü‘W3%ftÈëPœKt~/Ij±Dl¥ê ØæŠ0­-„b†H=AÈ>ðwÇZõj¢‡Ó;ÖŠü-ˆ„M® 1°Û;öÙw8Î/Çq( Ä@›cN KÇ’5„&¥n,@íþèÔ8th­ZaÄ t#ë´ª Ò@G» ¤‘A€¤ÚTw¥À‘²êR4D61m+²”j0Ubû¾çPT[wï½;?ß÷½û|?ŸÏÔ&ëέ4j¿Íï¾ÇïÞåOJ¤‹àÕ’¿Î½Îõw«\HkH1ñ‘,Q&ϧŸ²ñ¶[. è»ÆåRܽîa÷˜[(ÂiÂÍ#·â6Ü-Ð-¹gÝÄ Ù~m›;ŸøÍc,‘hò0m‚ÄYÌ”Y¤#ÞªÌòñ–õ!ƒw’Zƒ¸ÚŒ PÐéŠH0Š ¦CÎpébØ@u§IÝ»ð€qðƒƒ`¦ü¤‚-ªçËH]b…×KA·r “xÍÞÃßÿÃÛNö¾³Ùc#2ö¥V|+³åÈ‘ímmõܦ?ûýíW¯æÏ¾¹¡Z‰/Ö/þå¡—ߟøuع0Ô êaâ;§%ß×®ZtQLˆ.Š‘i€¨%?×+稢èËy x ïd®ãB™eæEˆ§4º£1ÕŠâôíU¹Ÿ°qß&¡ÏÖ'n"áyÖ¶ÓVDEsÊÃYcýÝf_…»ðæ`d(žæ#;ƒ#‘ýê|cÞ±à»ø8w*~€/‘K¡I7#Ÿ·qPäºÕ'Ô±F1¾'^ÿêÞ<2àˆa Qn\äÍ¢É!S1 ³×¤ë3šfÉœ5çÍÓm>£ßð`Ï%-a':­#üÚXíjé4¯Æ\¸ÇuÐÅ¹Ò jAÊ£a4†&P Í#;½À¡;ª÷Ts½Õx¼WOa—¥.ˆ‰Šhˆ-¢%ÚÄì²ì4÷CÄ€5RØXÎ ¹›«d²£\.0꾩.¥˜£OߦïÐùéÀÇ…AÈööv܃ÂeS‚DJ0Þ;çËØ%ƒ©µQ(3–~©T'b(pâ˸¶Vİý:f%)Ûù+ÜÆw'æö¼ùOŒ'÷ýbyÓš¨×?²ýáoÝúõU­ø©³bñÆ–n¬M×vÆ¢Ý[¿›m~Vßyï¦`†Š¡÷ضjÓEVƒd ’*c`C†®1ÂÒœ¥%/Å“á¢@3دáê烤¤3ŒÈ{üßN…FzL¥Ô¥ø,»Ìõûü(/®©‰gŽƒ2W¼ä0®ƒ¿(1p‚ǸO_«0 Nž§S#Ã:¶ô¼Îé1'üSc¦ ”° B?m Áã3GïFº¹ý†-NìÅt3cµ™d…Ü’¥¨9i0¹ÜLG˜ rc¥ï•Îtuµ¦iŠ|%ÙÜšO¿,¼lÛ/Ó§Ò¥4±ÒÅ4‡ÒZc Ùoë—6%_'dÁFz•£Ë±Ùñ†ðÓÆ£iRJ/$9Ã@†ù Ý *øèZ£ÇxÚxÆñœñ’1ŽÆdš\ltÖJ¾:×:5êë èuÚºHTïŒÁ4§Ð`»kÂMM1ÞCNÓePƒ¡òZQ;¥ñ1mLã´[ ½"Äz¦¾¹•¶ç»ÚÄlsvW…Áe,ŽäÀûÒ8a Ç2¥G…ñ#RÐdumRêµRƒ’œêIÂÀ¶&FŒ¸B‰¹vŠpÀwr Ï Î!VAˆÛ0cEŽ«lñ6o3÷†¹KÙb÷ëóŸøb0duÒ½)©…SÎÿ-4‹k·¥Ý2ñÜ–g×?|÷£pׯŸaDy÷ú±®ˆ7^ø-žëÎô|óò•?¢¿|ÙÇO ?ÒùW–]/i w.@ɬ‘aÊ a¨CHlãJÚ±¼^/ô3œðDÂz›Î&Œ]áwD˜º÷1›+çi6ËNF ÔA‚(ªr¹ƒ5Èqz¦ô@Œõ@:â ÆN|%ˆÊ%ú«†BX!™ <"y0ŽG‰@^ÞN <}¥ÑL¬¥pöûcQX'íÂjötµÐ@ —d9ý²„'gf©Šç.ärɇX¬)…»R‡‚¹Påýó¶›ÉhV$£Q9²Ý­RŒJDŒA¬¾•]îkln ‹!û€ïim¨êÉà–j‚y»Hì’Ëøª8ʽ*îsíWöê?áNÏúþÄ}â¹¦ÜæþÍûÔ<ÉKðºQûä²g€Ò÷w9ÞNóD„<é^i_ÏuÙ{b›¸Mö­Ü7ê ò·wLIgíŽKÜ?¸y×m‡_š%Pðή@[ºwc°iD$¯~Ô¢h¨>5£vÆ7B þ£€á ΂€Ô¢úh3gmP3tŸ cúFÈUI«g<~^Û¥Ôxí¶ß_”p‹4&q-ÒAé†Ä+’%ÁJ¤ i^¥r@@£W|“¥¶È–Ü+óHVdCæd,ÓHì°—r6š]r.Pl\,PÛRÈASŸ¯P¡¡JŽxá×~>^›³ < =´|Í¡övTÈáìÀ¤ˆ0ÇYq@?Ì‘O#OsÆ3.+•qÃ!QÅ©ÏJC9ât¸2 Wî-•‘£2²³‘%Û3%” ÞŒF_r郃ƒ>±Šú UUK ¦RK˜ ^@â5¼}û¾'÷¦b+o¼së³s‡/.îÃ?³)¡m+ûöpk®¾ð¶ïøGÿŠñ'·0ù݉Õ5íÖnðC=ñ/Ù^EINZÊîDŠéUÊ¢²“²hb‡“X‘E,É X¢c¬Â^j©4Ae•¥>)Y¤òdMrH5‰hBžÏŸVE ¥;Ê%¥Ô1SVÊQ*Q;}A¹H¿há{_–¦‘‡ÍA0ÕÒÄø'©³DÄ"Í@Ì|5 cÎr²ld×a|ùkYN5Ý— ëôŸ™¡¾•¦ã#ŒCCµ|'ßéÚÚËïuÙ 8Úeމcd\·¿¥¼åHÙxj¨q(ÉE$y2*½¶ OFÉ/Y±xt<ú~”‹zkU8Ù«`¥¥±AõŠq(ð)üøÿ™®Öض­+Ì+J”EëA=,S2m‰6õ2MY¶EY~$¢ñR9ޕĉ“hN½¤ÀЃeɆüX¼v¯n@mtH‹ Ec`XVl?šºJ¢K› FpìG0`K› AÅCÐưÕÎι’‹(!ïáá½”.ý}ç;ßûË`x«¦­5Ò©V‰`8â âq¹…×].¢ XߟŸOÓqp°6ærµQé¡£á—äôŠ“ ÄŸw–œ·œwœ3Ðõ!˱ÖZ5WåÔ&@—:Ûa¾˜{XÊm—‡sÛàláEPýñDb>4Òøãó)©«J 4In ­¯IÖnÝÝ¡÷¤vLµ† œ_S_¹"EöÙ¾ŸˆÖÖŽ_[|ñø`º­¹/ E“†ôˆ=°}e©½KQâã§M'÷¿úÑÙq-Û¦Ëßõz{¾}ot?ÀÙ³3Áþ zò!æ9æû¦ñ²Ç_x3z)Ã2šP4ë{G£ÑÓ˜»y7òq„TÉÛ׎«K`¶`ªáÀ¹žËò»òÇ2+××ЖÈ0×Wò$o@6o@*ß…ÔÉ|ÄW% †w¡\h€À iйKcd¬Êöö@žïB`)` Ü4ý…á€\SÌ0Üâ9kà9ÔÕåšúˆMÞµÁy€™bSFHH‘…ÔrêrŠM‰¨¯);R"¥$Ù¥2ƒ{s[!øsEðÑà³ Nà±Á;€H3‘PœÄ)›ƒéå8™Ž—â·âwãæ¸g­'¤<ÿ2ýÒpã:¿?ýþªé¦á½”#¹ž[`M–0¬ÀšX|•Ö4á©,~=¶ÉÜÀ=²/ž,~H¾¾ŽïUQU·PË7ËÛ4ØTËuq‹^¨e¬þê¢ðz70´Âf]¶¿@‰È ›et½s0à|˜ *Q¹#.›@'ÊO6¡)S1ù<™2Ï Í-T<ŽðŸ2îüäìà>E—Z›Eb‰Fz{úzÒ=,7Ž&#Ñc‘‰HCm3©O…™Q’ 3{,9‰)hSsX “qqB"Gc³96Û:ØÓ[†˜=ù0™ÌëÃ4†:¾×<,‘ƒÝ‡$æHâP˜Ù×<&1TA„aÞýëO'?¤<‡b·H¥Íà“`T<IÄ{êŸN(4 X@w°XA‡:êŠÃγ™þ£wÐVéi0S™~ºŠ´Ã*_z:%ܳWp­ÏœÜX}eþOª“å,¬Ký^vý7ãßè É)©t{ÏÜÂKoýï?žltëÖçÓêiÊ¿0ž.8½¯oç?Ý©ÁnV~ß—þÕ?ÈÁÄ/Oülݰp¶æ oáö—–®û¢>wØjf-6Géðâ™×g{3¢µ õ„:N™~zîüÛ³£åó—OŽ~õþ㑔²÷Âþ´ßoÑgPœþ n.cZ®kckÖ@â ¼›§BÈ‹ ^‹A¼Á¬QN@ðÀ Ot"HÅ(ªeQ9­Ç4"›ívÓQ™>CÖD|†V}úß f!تà m—c<2\T”éó4.l„©õÀ#GŒIƒðºtÃkõ s·v™­ëînô‚ º(ë~6­Âú'½ÂºZËl€A\ÆO{’:=Ã7ÆÒðP|¤;ÆSùå©äòT–y‘¦DšiJ³ýD¦i™¦eš–a7iµàË Þ€à«xOÓ²ýuÕ¦¢]7°é‚]€ÜpS^ˆ[Œî¬Ñ©óÙyè›]Wt)»’5_ÍÞÊÞͲ*G Ùùl SF–„ÄD›»Êº w»–h‹åÛùD›ïmÑ*ë4’z,9’nÓÇI8–aè.¡­r»> *¶ž\剋/ñ—ù;¼™Ç"ÑYI†´‚6¯•4ó’¶¢™®jK»¥ÝÕÌÚ|ÿp‡Â6”ØYn×FÐed"ìeØ=0@!¾|Z*|AÉÒÀEZ¢’% kCÐÚŠò ¤¥½Xfæ/%õiˆZí¯ku?ˆ55‡œ•ZCÈöögv“àÉÔÂË#K-^'Ÿ2vö6½<Oõ¼”o˜ØÜÓá]¡`S·“x,¯mŸ>¿ïØ7ßíüa6,JŠ‹ Éø§ºÓÓ;Ò©dHQ¼|ö»§æhˇád¾42í¦çjŒù€Q@ZÎ…»CɲˆÈ–½"k¡µ‚ø6tx‚Û×q¶Í!îV|þY©ÓíÁ.Ýî]£l WÍÓò‚|d¸}8<ÏŽv²Ø‘ßÀp휺Á{PÔ7æ„û5+ «P3ÕuÄØ.aÊ™žñ9•ÉÉz02R Œ@?wÔàír&üR† ËíV/noËp¥Í¦t8(&„½ƒòwVトħüÌ…”Žg8Pó˜ðÛïoä6権S!°¢y¥¤¬(«ÊcÅV ŠÉÀ“‚‚ÙÛ›¦cv°6j©ÚØ¡£‘ Ó@o¾Ý‘hó-b‘p›6@%ߺظ”czzfg‚,[–µ ²^¯óq/5AÞþýžT°@Ó Ï»ðü«á­á³†mÓŽPõé]Á#º‚¿Ó%!\bÃ%!†Kįö8$ }Jø[n L÷æF7Vë{uXªê.0ÕOÀ»\+H¸QñMçúu‡ºåÏP êŠúŽóÖU• ÃÅÒÿÙ.»Ø¶­+ŽóR–(SW"iÉ¢$["eÉ–eº”d[–«•9vK‰—X¶ÕÁ‰7dË€}Ä6°¡@2Ô{ Cæb 4ÉÓ^—¦i§bØjE°‡Ȱ ÃöP [‘åËk0¤[Ñ%ÊÎ=”œ¤!^Þ/‘¼çþÏïjnŽˆ{8¥WR±á™0{%WÝé ÷éi*›ÄgyeŽ£ü³tÑOüMrÊ*ØËlÍ妡ªX_Ûk»ÐkÝèµIMÛÖ‰¤“5ý’þ@wè:ë¢7Ÿ|#tЯŒ¿‹³57?D+Õd†b¥Ãò¯Îܪ=„ÕØ‚øT.Ûûì²ëFßUô·Ý͆ YT¥zŒ"‡¾")÷Ç|Rt°_ÒúIÌ×Ç(‡tòÀ|ÎaÚK_‚ãŸó›a£T2À=¶~séK+¹x¤Oùr¡œÐ¾)ŸVNkøî{±]ßêþ¾ïºãºt‡¿#í*÷¸ËJ9TÖ¦ôrqVÚ¿#¹3üˆ¬êC™â™’…^¹NŽÊ‹zWB^&ËÒ-ùÙù²rP»Ö}Mü»èT»ƒ²Õ´ü~ÉåQ$¿7B£Ŗ¹Ž9ê]Çœ yQYô»ÂR4ÓŽñ]mÙÏL†Ð§‰ìSyøFg)¡g`oˆ®pŠRøë6ÝP¤øè·PÇ4£Žƒñê¸i§žr b 㙀iTDš>«.K„Wzü~9¬EbaP%5 òÝ1‘‘J*1™ÊTò±É.Ãy@w’ºÐ ¯kÀ†YÂá‰Î隟t¥xI”åXà8µIî[Õý­Ç#ºÀóÃáèÉÒ-Ê? ä&ý+å×éåiFU/†H(¢IІKf2œ)›—Íó¦é\0É–¹mòæÚT±I^};þ³oãÖÞØ\… tyXÞü73®ñìaN‰5•KaöÊ,)Ç‘K¥s>3dø¾'pÎÝ68èjGy—È;vy޵}  ø>››«Üê&YŃÛà6 Yy“aÛ _ц!ó‚3jã KEžÅ)OÑÃ.JQ²/Ýö…Âå-P欗m…å,ù‰¡T>Þër ‚sq&Y²BXüQm®*< VGî¢îø9ô[•{÷¾2M†_j}a¨o¸õ°Yk™³‰^äÓ#½# ‘ç­ÿq¦‡Ò@”×uÞœþsëOg⟘L’^¿:NNµn6¦B$™TP*£—òì»ZûŠÓD½â=9¹ K]P×Ôuu[½šŽ ‡H:æJ%)oÅ ÌÀ# .‘#I/mOC[òÓÛ”,P²F×é6½DP'½|[l|/—ž‚Ê*Ù LíSžg“Žgœ O̵Êe3âÓB‘a…(Îóÿ­,ME‘CÖ…9›ž1Џ²ŽŸsËŽß·£ˆÚÀl³a±µR\Z¥^Ívô>Ë”-«±$¶ÆY{¹Âl§×l§«±â¬×le®‚ý*è(t”J5Àþ­ÚWíÄ—jg0>³Â¬oUdÓT nàp£ hyXEAfÃàþ–‡+ô³‰áþ®¥±®Ûy6GAÁ9œCÑY Ä9ô,Êæ“köú›îÿbyXWo·?…yô`83và *}n±n±>™:9R?]­î¨/¹ær¡ÁQPu Œ9v3,¢­®X=ÞaG' í×sfÛÕ¡7ðz³cÏóK0=ÌîœÂb}IåæôxEïÂ0b¸˜›Xg*xWÁ»JÞã.:¿®¯Àwú·¬ÿÂÖBa¥Êb<«¬vvŸbkµÚXioe¯”áÉñ„Wàðo”ËL”Á{/{çWÞçfŸÜæÀ™3ûäö;‘P8 MÙG£ÏêŸn6>:¶ÀÅk€›†—l7ˆîÖÓ±P“tu ŽåÀ°<ÕtlîЀ’Ž©M‡ïjÂHDzM‡÷j¢’ŽÍ‚a½”¨§j•ÅX}Æ.Ô¬bzØÍ ƒsKËlaG©è\]Nan6— ©bèSV’ñ¬NÖõË:¯7IÞ’ iÓHNe d½p¹ÀX]°¶\IV«Zm¡ÆoÕ¶kÇwçøå|ç$Nì8`šƒ@!I!é˜J¸¸µZaË ¢,”’ˆÖnívR+ Úè¦N]‚4VèÖ.kZµ¥d›Ôý1í¤‰µÞ¤©Œµ˜ýžÇvèÔ(¾{üÜùò<ñç÷ý}¿§$2%ñxJ’нTŒÜ#1r1F6Šgͦ\˜XLð¦Yì½gJë®t­çæ`[Ø™–ˆ3Åv~CѶŠ|×wq¬X)NŠŽNÙd<ï–ŠÜRqµH/Q&–‹LŒ—LU¸Ì¶¿Ý4Õäp;oª¾áDÌT vW¢Ç°6u«=[Ú¨D¾@vœL$Áçn•’Î-ñHà§øsüužå/ÓoÛQ³KZš9fVÌ)“7Ì%“¡LѤMÜÇ]Pðf¥JÚ6©r¨ñ;õsÓ•â‚.•ÖJ™r@Ž0›Š0­mÈÁÉ¥YÆPÅåiø¥Ê<®ä/pà BE~~òž ( ‘W¿7rX—|žžÍµþ ]p³›v{ÒãÃ…º¿GКuX}wä¡'j³»µH[2i¤…QtìééSµXYŠA¥m;ˆ¾ra»‚ëŒѾÉ\:¨ímTZØ@âè¼ÄÎÕ3èñÀQaqíà‹x`ñ$Knc[S¼GLQõÎHø]!à‚ïjrêÂ×ñ} þp3¥°!B\È+'ûÆ€‡,«z½šŠÁ"­Ã½ˆüx°½50F?’~.ý½ïºûÐÅþîFÛ][¥ÝáÓèy×s‡Q§f独6ØÓеðû mkhˆo®&Àâ/= þPdÑ*>ޱvŠ]`—XŽýØkÃEÛ{"Π:8"gwŠŸÌdwTËØÓ,ev,=¸ç¢Wº¨±C_Þ3þ6å½»L±ðÒî.ã88þKJaòK…˜ü-ñVôso¡;L46õ¡X åKÓ©¶´;Å¥ýBH§bHё䂑ì„Q°EÔQ”CØÓªSêdíÚÂ~¨Cƒã¶ÿ(}”;î>î;ø†tT>ÚÆ—' Aø±]m¢¿…Wþé=%ü¤ @4|†8.Ñn¤‹½}}­í0“Ð9hjõä¡'¯Ï]?þøÓ¿ßU<´ùÜ©GN~u³xö[‹O}6á;oœ¼}lÓÀÙ¿­ýõü{Ÿ<_Ðq÷vm˜y X3¨ÝÞ`Íì·±ªæÝ>¹9Œ’[F(1ƒDƒƒºD̈ëÏš~讎!j!ÆŽÉd¬SÞmmÅ‘ìGWÊ×7Á9 ¢ÂQa  °àܪDpIKÎÕ…vyY¼š#Ä6¥õ •¿ûÙ% bÞ™”ñÐíîß«#܉Fõzàð¢þiG‰YÓá® ç3(ñÁbj¨Ô:Í0l—؇ðJh'^SDöå{4÷‚›®¸çÝ‹nÆý‘N/£Çí¨®Å§âô|Qq1¾_ޝÆñʆwGaf£HTq¦ŠM¶5ão-‰ Ed|"ö?„h=Wt¶ð©Þ´7Ý*:ó:ʵÀ¡àêÓQ§K§¨5tA(§gÊÔtdR…0v:˜C'áÐh˜‚´î^@rÔ,P±ath¤¤·½0úí}ÓÏN½>Ü—É·–Fjzd ‹ UN¡^—ïk»Þ÷à>{¼;—dJ3ž}äð37ª/Ï……ÎÚ­‡ j*…$OÏAæÀD·ì›«½>™Ø0¾ó±+œÞ)€ejKm˜¥€å•E7,+i"•é°„Oa9UDF>œIüØDøˆñ³#Z ƒÿ\ÂHû˜`ˆ1NP‰”Ì™ÓWçç]m؃•ì2!¶ÍrÔµ0‡Q 3¨ŠúÈ Nb¹uÙë¤íÎùÎfÎw²ÝJw|ÀZŸmÅŽZÛ³ã˜2¡ŽÅ÷Xû³“âå@|Ò:!N+sêt|.{ZùnöáEåõÅø÷­³ÙK¯)?i{#{EzVð—ìÇÙO³–Þy$u$óBð¥àK¡åNç® jç}¦ê4Ú‘©rF"* ªÆ$ám%R1Ùéä|Ñ(¥i>Œ]ŽÒТ+h-"ñxè£t Ó¿ _ÿ+Ì„E<ìœ#JœžÙQ½“-ãöŒ‹ó¸±:pó(5z³œÌ[“­iÊá’:2B¦^gÛlÐC€o}–šÁ ˆÖXËÖ°‚Rįcêì"x}Ì!¹0\Ë×ÇBòÞg‡Nÿ…Þ+UÒŠß4LÿÁ‘þ}Ìâ§çÛR)ÑSë{xôß¿»…RºÞ–¼“C?…~ýί¯,(p¾-€×›@V]jp•±ˆFrZ«ß æÔ5ä'dý_òÕš¾Vk:R «‘#¦…0}±°I¼äF$2²ù@'SiÀÎ7jLscdœ²—±ZÁ · ùö ®T¼z­éD›ý=—†ÏNºæ\´  s°R"”~’`ñÿK„ÿ !ÞÄ×4Í2ï™Ix>•XY)¯yȨ= ñMÈÓyÁ¦máë´-´ßBV9’Ï$ Cß”V-”ÛcùCºˆXyÞ…\%Ñ‹¼ C9!îçÍ!®K³Eù“š¦éh^_ÐiJ!!.뫺C¯˜¯}Àµ–ñfnNϲÄêLµì¯g¹Õ<ð¸3àï q†±¹ƒÖ ¼4RWÃÏ5CZÃÑ¡ŽÌ®ÛÞ›LìÂÝÁ–Í÷Õ²÷·GÜŽ–„¢nf?ø`°ÃèÛ2® =`€yKJ$O=zþKmØÀ/ïÞ¤ÿ¼ô°½ ^Œá¥`cwF#ÿHÆß7¢ oxñ¼šò#àFšÇ×…'oq6u Y:ì@ŽT!d9#ÇTô¨ŠÔ”® Š2¥ÐJÀC \-—Áåà §24ÓŒø¾•+âz']£# žµ$5Ðå ­gý1‘Àˆr<å )Ëù?¾«6¶­« ßs¯?î‡íûe;÷ËÎõçµkÇNã¸ÁQµÜBÓ¯QZ¢õÀ$[™D 40˜Ä æ+ ´dýåD¤/˜HX¿xjüÀ“ë˜ûÖ–½YRÌÙõ7N~iÏÀGrùÒÎC§ÎÆyí|ᇟ¬~f´vàÈOûÄ5,üðßôVÏÊDk½–‰¹ Ô°˜‹ ”Ð0{"*òª$U ‘© ›ᩘùˆYÀï"€£ lQŒ†=mdÎSÈL¶v}¥ÜYîqØ-Pûå×'½/€i(JúÈ#9|»¯9µ‘èXÏ…q6% A4Qäpí#²œ P„µy‰9ð²˜æ¼„½°ÁwÈx§„ÿ ùïb%Ô˜õÿ®¯`O¸v½ÑX’V¤å Ù9|Vó"„ l Ô&ÐMÅfåYýrär´­ßÕý­:n }}Á‰ÀDð?š×§E4Gc¢M7„»°ùb"ƒ½Ý2ƒ4|*ÞtôZäm¢±ž›oRBÝs‹6g©;£cB7Þ¯¢¦Š(URÏ©KêuõïªO´~}|ìáÓ¾Uj¬‚vè@ØJ­ÝÆÔ)uàÑmôIu¶yÄ>ÑüÓ ÆJ$%M5R!Š+[•SÕ-À›#hÏÍ›•\â1ÙI5·—núÑÈ×úòž+ëÚ±ö›úcùÜS‡*‡è/&¢‡weŸÆÌH?¼Í¬1§¨ =ØCUÔq1zØž,ì¾´ß×Cv¼ç0o»*1–h(§lÀMÙ𢬞Ç•ô†õ iŸ`‡4_¬ü,œáóØz²bLí,ìö=‚=ëCü'{Šâd{Ø“q´¤[Â@!zp3j9ØUØæ‡sŽgXéµwõï²½«îÃÎ3±/žqR¬ƒ¶ùãìv[ÈÄØ6wUžÊd€’ðÿ'Ä ¼ $l¬ýCÔ9„D4…Zèò 6½èfÝH+Ê~uF¥›ÐS :»;]öõï|X§ü}ÆÛXˆ¼ó÷•P‡dZ¢l‰†EI²)Å,°qÒV` ð Ä0±”}ÞTu‡ ÛüÕDpåT™Cb"Úï„ÖßøÆsã{­‘]h[}¬ð•ÇkO0§Ön´vZrêÈëÍÖ_h¢ÙmC&ʬÍ5÷où8íÿČʀÑ`Ô¦¯t1ºÀq”¡øÂ¯ždh64šùÇË”°NçÞ½±20B>@+›5ž3YŽK&àwB8Š¿oXõÉÄÿÉŠ&wà|Û$±ñ<+…þ¢cË·V¤[ä³rʧøƒÚgujÜ[óB5‰YèÉH5¬‡—ä²­¤5[·Q®Æ*5­ª{ØÝÜv~\×w‡ÙŸ±³ÜÏÍVòWÔö—Üiý´qÆ|=Ï-ð ÚýUã’¹”¼¡ÝçïkŒ‡ð*¿š&±°¹ãùnܹ³§S©n”e]W·†ÅäsÔ4𦧼ÏÙßõ~O>‘äFÙa~X«™¿ó-%Þ2üßçkÇtfD٥ѪŽ«”iÇ)…—ãp žw‹œ¡Ûš®r|˜ãxÓ0Ò ë÷y=$™ª€l¢|†.hmô4Á#‰Oó-~ÿ3ïår&±äúÊ/±Ù?Âé=ÊéÏ—IÙû•aï[‘8?TÅáB JqK`—Úèò‚”DÍd÷mÀ(Du8 «.Àè®6p½0Ö´;:`^[5:8Nk®5!XÇÕõXWNó–4’@Wu´ôhŒªýȆ" Ð/ iÐ7çy;ƒâu÷D. z̨‚Ë«5Ö™ u ‹‰z]MDºBBUA58 +ª‰ˆJ¡lÖÉ:2:k9ùÈ›}¬F…ápÊZ¿”_¿ÍõËCÌ©LÖN ®ûþGw¹ÅÆq•q|Îì®ç²—9³ÞÝ™ÙõÞ²;7Ï쌳7{ÌÂnÕ\IܸUHÐ*•Ú@‚­#B’ Ë–PkGY**^RñÐUÐ$¹`U¸’‘òÈ T…·Pƒ‰Š vøÎ¬Ý¦@gu®sÛ™3ÿß÷ÿèèH6Æ aU йþ5]̱ –èÃåÐ%P‹¸±¡­˜c´}•—â4™ j¾Oè#Ÿy»íº’‡×n¶øˆf®QDÏm„{ò€ŸRø5äI ¶Wˤ ÿâ§mdS'T¤†OÈ÷®nÛ•bÑ©é+ɽÚÝv¿ßõo&úY‡ÿV3âùHÚ” ¦¨êç°sŒ{ÁùHýȸ¯Þ7"䀋ý ÿ¸ë™|½è8æsͬ¢ä3%ìy-«Ùš§í—ÎIçäsV‡ËÃú>j/cv³;Ë;ô1cÌœe¦ñ´ø}uÖ˜5§Ÿà’ƒÕ|M½füÚ¹®^7ÞSß3n:y*dú’A‰S3ú̆ô8~\=ÅŸ2Ï„çð¬|F9SšUgµiGšá^–f´@”;ˆNâ“b4«©ª+ž“´\,$`Aì<΋yÛäMÉåñè~îPs|4¸áÊð¿O ò ßv‘ëhu™Ry†œ“ÍzŽ3êmÍuÛmò$>Ñ{5y¦Ÿj M)•ÒëõŽDj`?FÑêz­¡ÆçR®ˆÄØÒT$;©ŒçPÎUŸ/M•èÒ\ •Õq¼Zå®iêµqxÛ“ Ô…Ua˜rCM4j$¥ëCµH¢V‹ÀÊË\Dªéªq5™DêLC@yX ×!Ë\ITv‚T©ärY>ó—ϧPÊQ¯¢Ø|AA áj7:Êyåʪ$$+ t“ªQ úÚņ£æ©ª-ÐïP5JÍo€4­vWî­à5«kM¬@>ÓÓ^w3Ú‚Õô+Üê#å'6Dz1Çš‰Mö„F:HŽ{“®|/wÉ;^ö_tÜëº]˜Áþçô·b­™nM.-‘f‰]b aaö (ðx·KBõ5â»F…AS¼†Ôä çI…\¼ ý?ÏC›$I*7 ¶£ nËd¤íôK±v¨·ª&é+­iäj«—O-$àÿá¢à1DÈ‚W…ærvDý™Ž÷´)"̉ä<°Œ¾I¸ï5bÏ2d¢† B‘:qcÁ¡Ø¤×ߣBª×ÄI(Lziuú“^“MzÆPÂ3¡ˆlÊãü‹¥<³#BIzURàι;rúñ¶|z£þkŒ>µÃÇï_R’4LÀ³é_˜þTJJU2«ëMþ˜¤¥ÃÄçdÐ[f±N=¶g× 5·–·îŸ\~z—·>^Qú;/ÿ`[¥²þûrF;´ø‹/>ùyÓ€$Wñ–£GŸM'³€%yËñsëWOo ”ˉ˜$u—–¾"Ê:].‡Ù“|c´Y߸dªÒ[6ÈîÔ P§t¤g!cI"š `ý®Hº´ß¥I·êw«W7“ kź¿¶{£»‰¬ Rä8‹Ê&DúÅ*ªRqÀCéEr!‘¨QT½ö±éy¿»y¡Ï’_m:÷<ýå·©ÌÃû”òp•Jèy<ÛÁLçMÃç³^5éþº“z®ùÝÐK}4Ç…â¬Â¦9+‘Ö¸r¼œÖ¬ÔŒ72;ãG¹£ü1å«ég3GíSìiþ´r2ý­Ì)û FyzûqúGÖu³þA_ <‰eÙƒƒ<òºBì½]ݰ÷[PÒé¡A>Ø–å{kNLsAžµ¡UÀi°¥ ‹¯`ÄàßênÉË uIJ+Ä-dæxt›_åégøø¿ñ~²ÍíãsnÛX'k½+P8[  s‡mäÚm›¶•ZýgÅ7 Kµž§>¶ÜX^»×½‘tí‰íG¶}HµÇÖ–­NÈBøø`‰Üд|f þ$8£ ‚볬¸ïÅýt¶QoÖª’ŸÉ#ͺôf²R)Þ¾!2ì ª†Ì)ëßk¾õäçö=ƒÏí,?¶~E(*XªÁ7¬gõíëUô/Óˆsá(˜u¹k?øæK³ÛìÁZJøÂÁ³ô|Þ)Epä?ì—_LGÇ¿³3{Üííw·œF¼“O@X( g/°Tªr^"T0+±"ÚXmš6ÕÄ‚ML“–ÊSMúÒÆšš¦1MÓ4} MLkZSí‹/ “ ô·w« ‰ñÁôegó™ýîÌìÎo~óo‡FïZÚW÷Óè ° fEž[ˆI1©Lú.ˆ‘5©3ES*kSèTS¾\è¾|u·hU³j–=*cŒëA®J>Ù»Mf¯Ë,%÷É’lx]M*;¬²^uD•TCÊAý<-’éÈZ‘3'Ü8mqWÓ…ð̰¨Y%Ës =§ªQ.üœ ʼ>]±j)™É†âui½*S &å¨_JuðAHufgå“Ô¬ò” ÅT*\YV¡×ë;t®{Ë=5˜ êç3[HrîÕ–¹›I­ç. €¹ž›]´ÌJ¤£6Zftv;u⛦ݦßÜ;ö-½ôãP)ÒÒë¾oqÖ̦Už kÀ*$TÓzŠãêÌâµé`\Äü–¼:틃y–œ˜Î‹‹‚€%ÿœTÓòSué¢I+bã‘Yeš¢õ‘‹TY ïöÜ¿*õ-\éOä/1Çüû,¹o›®yXhá(/ Um]X}ÿJQYx¯õOu~a3æäqp´™^ÈC¹¯ÔN° I’fØ/f6‡Ló‹ÊÍð5¦"Ianp“sò%¶ 1 3y-´Ó&5{ÒÜ®4¬ÁžŸ[”;×&ß›ÉjÆÃpd)̤ØRD7q_"nY_îq »Œ8Iü ä¤Ï[€wðÕšÈ-ò>üe‚¦Í, H¶^B»eãÿ²"„7‘‹@½½ Ħ€’k@é°®0¾*©Þj*[{X?ÄOgH”õQÀ<4’M›Ðü3°ýG`Ç›ëR§m¾ÍÐþ5°“Êwíº«>jÇžsÀ^òËP0Löt£—1jñ—Ôž7ÀÛnàzïÔ»À™`üà,ùå½7€sT×dÏGT÷TµÍ”ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒÃÿ$0XÁn)¶Œpá± ™âìWñ©Zn^¾?Ô BXŽ…+à ººxMlmIiÙºò £²êÔÔ®ßßølu0ш¦M›·4?·uÛö–äŽÔó­mí/tìììzqWwz_ýÓ¯Q\üâÆ*ÔbYžBvÁ2ñŽ/.R‰0Š)g#Ðjçô[9‹7uÙ¾~tàµÉAû œ,ƒ­é[»HVOŠlJ1Ðlk >jOFsJ?ikAzÚÖ.Ò·›¶4•¶ïMmî?jkiÒtêá«—±…(E;öaE’â£ä«zîÇòhZ(¿•Ò÷b û)õпý´Ë“w]§ñ8‚,ò¦† tò÷j>yO²:M@†[²žÜ1(åQG= ÿíÒz 4Â8î¶>óƒÛÇG힥ñðûX8Ò«&î¸Cîté©+.[÷/~ú<ö÷áù3Ü>z´ú:ýåÃz“S endstream endobj 323 0 obj << /Type /FontDescriptor /Ascent 905 /CapHeight 0 /Descent -211 /Flags 32 /FontBBox [ -628 -376 2000 1010 ] /FontName /BABDND+Arial-BoldMT /ItalicAngle 0 /StemV 133 /FontFile2 324 0 R >> endobj 324 0 obj << /Filter /FlateDecode /Length 22514 /Length1 40524 >> stream H‰|U T”×þî{ïŸADDY5ÿ0J¨€•e@©Š(FÁ%0à‰ÄªI$‚ÖI#ÑØ4.U£Ñ¸¤?J£Ñ¨˜ÆÔX—p4ÆX“pŒÆ%rJµFkdþÞÕžÓ¼w~¸ï¾ûîýî: þx¹#óz'N>›ÿ°ú#ææÎp•צYê€7×´­pv…þÇ–å»s€µÿ”ògfø\Þø„ÚçÏLŸ;EÚf@ò6`Èá’bWÑñó¶ÍÀš`~Ó·„AóƒL6ØÊçî%3*欵$®ø>Ú{x¹‚Ïq3\sÊý«ƒ$ãÙÀòúL׌⿎û¾X5ñ$•—ͪ`ܼV ÷Ü—?W\žf+bNL X¦íA¤÷Û„HHÀ¼ðãç.5/xî<ÿÅUÖÖõÞwíÀ6|N1¤c'ÝAnS%  ·ØâŸÐ†×Œ1XAAèŽ.x Ù¤X&µ´Òœm^Á@¼†õæ.ª2·ðý«ø·ÁWŠ„– Ÿ"/¢À|>XŒö€ÑÔ.œæ}“1,Ãrì§ÍÛl5U¬/iH3šwѵj©v¦ÝŸQ‡½d1 ÍRtCjD¬yÚüÑ(À[ØÆ˜b©Q … Ó°oP˜ü˜©×±nò“d†v€-ec,fâW¨Á¡ ÊÕÎh­æ æ%XÐ 1Œ©W¨•Ÿ9È<‹ x‡Ù_ÏnTÔ&m‚{°¹Úü±‹|é:¨%j¿k[`®3ß…ãIàˆä°É¨ÆA|‚⺨4+1ylùu%¢9â§E˜˜/æË“èÅÞNb´Ïã08#{°û86G3.R0EÐ/h2ÕÑuá'ŠÄ ¹R6ÈSŠÔ;o;zpŒ*°ïá(Žái¬ÿ Ê¥©TF¿§ÕÔ, qMÜR>ªZý Ú´hw³û3Ǽ‰P„c8æ¡’cûv¢Çñ®ã¾§@J¦ZG5Ó5ÑND‰‘¢\¬Åv™#ëäAÕG¥«iê˜:«ýZ[buYÝwßv/sow7™»Ì&®Ö,Žè®Š8€“¬ý |‰óžúaýh<=ÍVfÑoh9m§CÔDWÙKxw” lµL<ÇqªËÄr¶~‚÷§â¬øR|'nJMFɾòY¹Nr·üT~«U´ê¥ÔH5^™œ™Dmˆ–§mÖ¶jj­–K‘¥ÜrÙZe]ès´­gÛWn¸K܆{'×®WÒ<ŽÄ¬çºoàáˆgÄÍøg!œlô8ãîGY4ŒFÐ8šHÅTE‹é5zƒVÒzz—=`„•±ÇŠ4‘'\¢X,‹Å+¢÷ñ‰8-ΈF"í2V&Èl9^N3Ù‡ 9_.äÈÖÉ-ò„<)/É˲…³¢º©çÕ<õµI5¨&m¸6ƒ÷zí€Ö¨5iwµ»a ·DZz[¦Z6[Î[-Ö¾Ö\ëo­§¬7|Ê)’z2r-Æ=ØMlÁª’Z˜Ñ•:°ç±œ‡<îŠ,Ýœ—Ï=cë,ÂT'ÏKKªâ™'*h/úÐ!TZ„䩪š±ƒÎ‰fõ1Ÿ‘“ÂÔ&9S;"lØÊÓh©ø@ì¥t4ˆ1V¬’ ‹´¹Þç`9M£YØJ-ÔŸ^¢$ªÄ)ÑEæÑB¤˜ë…¢v”M­`X Šð4~rQ?žÖWÜk”¿z‘çÓn¬àŒnÃ×ôîf^ãé&y¹xÊÔr½/‚gêMâ>«ä~ ã 2Ýr d቟d¤æ¡ÿÆmWT:OÒKîRµF}c&™ñÜaÜeØÌ}W‚!Ü1¹JöñÙsšÈî˳$‘»:ãQ„—xêÕ™†¹Ê¬6çšeø¿½Cqt‡ÖrGìæ)8ÌûU|AK¸‡ü´Ÿÿo¹‹Ðˆ«J=(‘û¡E›­-Õ¶h Ú~í˜%£½+¹¢Ïs5û²…hÂUÜ"ÎMâð$ãMfìù˜. ä>dP8ʹgcxާß÷dk©âè­â~ÞǽÑÊsb"öã a Ù¾ëÆqþ%K¿Í¬¦Ì)â©Ý߱ߔ,*Ø^*kZÁS«‘1÷mÓ‹+Žç‚ƒÆ²®[‡"¶Ð¹TÏxýx²:äQŽww D:EÑ~çä @WôÓ¾!8wŽ™,Jå>þ1™¿–½"0žeØ6t¦‘èãÍN©icR˜2 ¿ä¤>Oþ<1á‰Þ½âãb{þ,æñèÝíQ6ý±n]##ÂÃBCºtîÔ1°C€¿_{ßv>V‹¦¤ ÄeÚ³œºí4T´}èÐxÏÙîb†ë!†ÓЙ•õ¨Œ¡;½bú£’©,9å$SïI¦>¤@=)ñqz¦]7Ž9ìún?*ŸéWöÝhñÒ#¼ôR/íÏ´ÍÆôÌЇnSÏ4²f—Ôd:¬®¾½o†=£Ø7>õ¾í™lÏ”b/¯§Aä%DHfÿze„Û™F˜ÝáA`È™®"#wT~¦#Âf+ˆ3(£Ð>Ù€=ÝèëA†×ŒaÉ0¬^3z©Ç,Ñëãkjwb²3Ö¯È^䚘oHWÇFÇX¶ë0Bæ]ýï‘•eä/~ø6BÖd†–êžcMÍbÝh•ÿð­Íó· €uð[Ñ#ËY“Ŧk9ˆÃòt¶&ä´ˆMêO<^Ýó¯Øžéá8§êF;{º½¤fª“S^c`ô\ÛŽððÔ÷Íf„gê5còí6cp„½À刬FÍè¹;ÃRõ°Goâãê;Þ l}@‡û„ŸÿÃDñƒ;/å÷PÃF?ˆ,yÙ³¹ ½Pg$ùÿá¾êƒ£ºªøyïÝ÷Þ’b»!™–Mפä´|„… Í4%„M`Ú>,D›)SœiŠ•tC”@bkK›PÝPþØ$¨‹8ÒPc;Ó¦v°ÓÁ`*pìlM Ïß¹ï½e³€X;þãN~9÷žsϽçžû»Ï9Íà«gPhå 4ïBWxVdmxTAUÈ›Ïzöë^¿/t™ÀÿÅ #5+‘á½L\džÄ¨»[ç䄳³™"fÖ1Αõ©s7FÔiþ ^ÒG‹ÛùyHz:/pC$@Õ¨„7—íºªÓS /§"¬V±%êZ’ËØ²ÙµÄÜ«ü`òâG}rØ“û»Ã›2fÁ#ùa%åߘWÛö¢%þ¢’Ê oA¨ÊÉmQ鈚mŸ³9¥ð˜‚ –¦:%5M“Vry¬1W‚£Ã"†$õª°RJ…â+ {«Úÿ+’ÒÓoê1=qNëïì%Å57'Êp~ÎÈú¬õÑiˆWdªE¥•¡PÒ[! P¨Ðï+ U…VD¬ÍÕ~Ÿ×êTªCT¹ ±ºÒÂ…[+0‰G”|U¥ù~¥¾¤# Ô/© vzñ¥R_<¬*jAÕüŠŽ/ÁìÄS$ µjLË5רHÑ«iJë àIZ…TÈúʈBRçqu ­Œ¨¶Î+uøM$^{sÎÕb*ðÒÐÐÕL¯ÔÄÿŒá¨Ô™Ú(¢½FD-}(4ï¢ ýU*¥å°ÕÚ]øÆ:Dehÿêµ;Ô™Ö´/žî2eÀRK€yðéÚÐÇÃÜ”ghÙK_ÁXìVÏèåÔ Û.c&U³cmE~”wC¿Ïh£&”[`¯à¶R²9}ö\”wèå–e6’ ¡|úŒ¿c†ÌÄøµ¢Öºˆr6úþì[ Ë KxÇÊòö‘så9>Íeä§ú&`1Ð,C~ØüÆ£ÞˆòmˆkähàvAtÚÌÆ[1 9ã8ó&9oÌ#6'Ä/cº18§óâ˜x^ç€^à¸ØÑ8µxUÜ'×çü9`–ÚKó‘—«Ë&ðtŠÅ)*ÆK¸Xß¹óë„óø¢ÐrèAO”²°–Âww‚la˜}Ê:ŒõcÑŽ\ôÑ>™×>õѧèz»uN'¥GoWëdù:™%jÛX2âmŸVÿß@}[o§5(Ÿ×û, óÙÎ{ÂT&>WBØ d{r”O1ËÈ‹O¾KÀz |=@ÓE”æŠd OЗ_•çî6ôB¤F¬×Ídòkçp6b,õmÜ÷ù@Fp.‘K®tùš(™3|îBêã°ïº€nà”ƒ?ýàã·åþÅÝÀç³¼pF6_­‹1~öP+ä\~&ð4;Ÿf"/%ß-|¾Ë»ûq4ºóçó‘Ï8>#ùœã»ÏmŸ(ãü›qvüQžÃ½Téìë,`‡>Ž:çH·±.až5Þ´ºÍ¹V·vÒê6v[/˜5Ö«Æ«óΊݩQû,ãýäÞ¥œ'¾Ý{TϤ5Îy¶G¶Åøò-—ç›°ÿÖQ5úý=ß«¼µVì;äý=%^¤oŠ~Ú†ØïÐ~aëÅ*æ3QlDzœél¿MÛ&í‹Å‡´Qd¡ü"ä^ºÓ0i£ñö±z¥îŒmc^I»À»<ñ4ýLï  ¯ÏCjäµÇžOõl¦}&Ãý´G aÎQÌñ„”{%ŸØ÷kˆçg΢/êæÇmöÑ÷‘ÏÉÇN™‹¨ÌQ³ä0rÁ}oÉ÷éï ýOè OíñÜ‹óé2¥š8KäX´Ôyò¾þûc+£zý Ö?%ÿY–6„=4ˆýÅÀÓNO¦qú íÅ^ª—ù±eïm’™#˜_©|O ‚ãÏÓ£F;m5¢à]î‚>¬Û æRC3PníÖ0Ú.@ÄcC_"ß'|O¬7x¿˜Qk0>Úp òý‡qµÄ»ƒêq–Ìó Òs†ß5ŠîÝ L¶!ëOuÀVRçµ¥’Ž>žúÕôªÚ¦©à7Û{ÄKØ{{ižv’ļÎÓSjmÑŠÁ»‹¸34ø¡.ri‚v‘Š´åý³EO¢é²] îñ³´HTÀ?J«ÄaZ¥Y(šÁGøéªÔWâõúq NƒÏ(Zd4 œgâvrŒ­†ØDS¤_d¬.8ægãbnFn¿>p¼(ÇÇ˱Æâtb¼Q|ržÜ/üd›?Ñ<"ë] ÖWKÔFj¨§ðR²ÓêRZ©PZ¼L ¥ìJ¨PÔ)õÀ"@ˆ:Ú9ò<дG¿‰©ôô} òþ.`¨¿ÂÙ ûóÀ/÷\[v‰õhw‹xnåuš$sh#?Gw= Sþ¼'},±¿&òýüYcü´Àú> |Cæÿ}Yrè,Þä¦u\9J)§­!œçîSªÌç~ºÓ]'èë¥>aýÀ•iÚbÒõ(Ïf¸õÄu½Uý®‡Ëæ 0Ä{h$Öqs,÷úzlÜ›¡”îGž E)b鿾nx)¡n@½ö÷é^F¬^JY nË@ný 事¡öS:C[ ÛbÙ~#.¯AΫe_é/×ÇåyâúÀ—ÄoqýoæRJM”1~;çÅΗØ|Õù,HhsmO\ÛØ+7ëóÿ Ø;'Àïþ§ã€ç «€—ð¦{ï0ÞªÏáó5j$ºRO4|Œè“‡qM†|º2”3!?ÆB··Ñði”7ÀöÐ iô¸ó®‡úÛ÷Ê N¶?û áµ3<ÍöÞìEùX6|ò_´—ol“ÇÇïñó$Mb‚q áž&8&i<7Ì0¤äq Tk6Å…%c¨m'mÓŠ5’²AKR¦H$”Ô]7i]§Æ›´‰Ñß»ç¹ÏÝ=wï~÷Cø ”·À ÀâÞ1xòQh'ò¿G¾bHú„~ÞDs³ü«ÐÓ2ù˜sèÿÖïrþø´Ž>~Ú§bNô·ü ñ©½4ŸKxùY£4ÿKyé,q‡Ç1ß;R·}>ñŒSrÌ翊úºæË„˜RSq4bYsËø±è*Þ~_Å“TÅ”EÇxÊ~TÉØYƯðŸªsÞEôç ùúµGõ«´Ü¶¶²MäIÈSÖ=²eÞC®ÓSÄEOåo ¶LHɽMícöÝwá.¬¹‹t!~ùìe¥=­´¶Þ±ÆÞ¹§ý_óËÝ#?ÞÚ[Ô7ÊTºÿõ¢ÊŸ·Õ(U¾/WKíÝŸy/¿Ë}û>ýßæKû|IKÅ¥åqÀRù¥ê[n¾<î¸-?#õ ÏU¾<.)åËuÇó;¿½B<³ÿ·’ÊþwËþ§ÝŽùË¥ÿk©åÿã[ÿ·Òa˜ì€,9ÖXGZ ç‹ç®&¤±æËýM¿IBúBþ,4+×ø@aïË?O_G,ýOöäߣÈkŽ ªlQK}Ïåß­ŒÏU|ˆ1S}O`.>$íÐ6¨š¾}k®q†DÛç9v^yÎåWò7P׻łwsœó¾#Ï{È»wýšôñŸ`é¤Dä3üÇ)w]ÈLó—S®U!3âæ?"Qˆ‹™d FðÉ0ÄP¼Çnû\hN&R•5!7ÊŸ 4q’Ä•ª¼ Éò'R«<²úïÛ®•Š;b; ‰”ÛŠFêøw åOò§Hü(|=üqx|?‚T«~š)—;4‚öºP¼‹¯&-xá̉à;ðÝÕ«bCvM¡!{c ©äÛ¹WqñjÒ×¹f‡„1ÏMôÔäÇS÷Èþ·Ý«Cçø(×HJ Ôá:Ç+I;$ߤ/UQJDªx^³Ã"ÐGJ&ÕÕäOÙ¨í=Èמ}‹7Õð|½½ZdæùKªØd-h¯ÓÖ–ª® e"¼O->ŸP­%RÍ[B$ÒÌ7’ Ä0¨ÃH #åæãHcšÆ15㘚qôb±&ácx2†2íü0‰óC$M"í@•«mŒàœJlØšã÷r/FÂ=±£¸»6UQ#{æµkW©bÞTUM¨ë?Hz!†Î¦ÖxCæy@½Ê¦”·^q»¢ C·¦0=rÎñu|½‰5VD O‰‹ BÙ;,+G‡ý½/ç—]D^ú»E¿Pôß<ŸaÙZ1Óì=é¹È:öWTöû3™Dбyö øKË^°ËlŽtÁ/!ÿ|þüWö}çEš¥S0ôý»Ú#_–½e·¶ÂWL¬©/&j=¡ˆý†½IÖ¡Š?Â7ÀßdÒ_„{á6HÎÃϲÍdüõ¢ÿ–-Èoš½ÁfÉxÊ®‘]°lMÚ´í”öšM ¹h»X`¯±Ód-Šž±›×âî©TóášG}”ý‚ Ú ¢6RÉ~Fû±\–$—¤“Zös;,+IØ †˜c –0½aÓg¶™S<è ¶§¸á3ÚŒ°1eDÜl‚¬ÀàáËNà&Ã×™P‚ÙŽ°ùï$ß‹‘\“*Ã5®RW÷­§×Uª‹"äE*ÁŽBÃÐôqàz:==«î BCÐ!,qqqqEÄAÄAÄAÄW­A’ˆˆˆˆ)""""¦Ù߈˜"¢ ¢ ¢ ¢Šˆ‚ˆ‚ˆ‚ˆ*" " "ª„ Âa*Âa‚0A˜Š0A˜ LEAAATDDDP„ÂP„Âa€0a€0@Špƒpƒpƒp+   ­·šŸ!H9999Eä@ä@ä@ä‘‘‘c‡fx6ò6,,¬B²@²@²@² ÉÉÉ_}P Ãgs†F ÉfÀfÀfÀf›QŸ×$Y „Âa)Âa°@Xа@X ,E$A$A$A$‘‘‘‘TDR}¸C$–ÿQ.{jØs´_ÇæÊFh‹òarUùQrIù³dFù3dJùrLùaV~ˆ4+G}ʉЩ-®ˆK@/ôtš„¦¡EHS©‹Ð_ <Ûl6:\Z¯6©Mk‹ÚŠi-§1—³×9éœv.:WL;sNfDêYµZG±´Ôu×k6\»Tª‹u Ý¬³›ñë`æÊŒkz1@t:@_ÐH{ˆ:ÔJg0CÇi¿YÕÜ).Aáf'V¦‰Ù«k„Ýüy‘¦ k1[áW¡h :…¡Ôù ¡îP¾ßl,V¹ù¡û C6A<Äjµ+usŽUÓ©ÔÛÕ¤B¶ãßnÞöaiÛß {Ãöï‘ :Kü2 ¢g1s§áÓ¶¸‚Çg öK[ÌÃNÙ¢¶ÏößÛkû/ˆH5}”‡Dûоï-}—-ö Ø#¶hµÚþfY:€†|xÚBûɸ¯Hm(´Ôd‹m°F[l•¥uâ—O¤Muo$§Ð¡ks´ßAÍ{Äâ%qøß1°ø<.iì¢/M÷˜•b¡íUŽ;R)Ëc˜)º%ý¬˜ò‰WPõÍŠ—Åýb¢-­ãöIô{L5a‹cFš6W‰ƒmWÄAñ°øšØ%öùpß_ ²›d€ö³Ó³"Š ¿ˆ·ðÙâ!_Zuq§øž0…_l5äø’-…zÃm rH¨Ðú&ŒoÀ—–ßø£á4]i´ëZBÛ«ukÛ´&­Q[¯5huz­îÖkô*½R×u§îЙNôºt>g¶|¶u8ÎÁœyu¨´›É+.¸FuF&Ö*ÞÃzvwÓ+ó8éÙoXÿØÝ”¦•|ÅZÑÔM­ÚÒÓ×mmiíIkù]V¸µÇÒ¢{ûg(À]‹OSÒן¦yyk´ÞªÝއdôdý¡ôÞÑ“ÄëyºËÛUÛ¹rëÎs‰ý‡ôªnâ¸â»{§Ó§¥“?ä;Ig8[Æ#ɲAXgK Nl“¸"Ñ(RÇ|tÀd’†4SÊW’©§CÂ$¦3&-æcú‡l…Ħ…ºñô#mÿ€É4%í¡3&igb:-.à HîÛ³ dÊݻݷ÷Þo÷½{ûîííbëP„‡»RæíŽžDæ¼”ÌÔÑμ”ìȼÖ#?“˜$6RM+%ÉÄ$»›Øâß |vw, ° Ñlª¤`†6$Sä“6 ƒ5ZÀù`8༔ÎT€|Îg*Ðp,¦¸±kr<6&ËŽQ×4̵ ô"ÆÆÆ|> ¥È8AQ8¡ÈšaUÚD@ª=Ã6‘kÊ2ŠEHð>$¨ébðŒgS¼| S¼0þÿ³ôµùq¶6}`:Þ§Ä{•xÔÞÌëû¶ ™ïm“å±i*3Œ¯wÛsÛ)ÝÚ—I+}±Ì%&ÕN?B»(âmWÚÐ’kud‚ÝoÏæ •ŒºõÑk6@‹&P|G nxÔ*\#ÑÀ#Ëà£J: MÚ?€PGfEOG¦±,ÑëAUo, ¼UK<†ÑxcFc|b~ „~0Ru´çÇ~ð j‚S—žŒp#zB ƒY§T÷Â%ØÁ_… ç8²¥tÜé­ Ù ¥´bªöjè U U…F*FªGBp?¦g”n¥ãQ ú–ÝÁ$8Ì¢úN»%MñíøýIÿÖüõ¿ÎÆKN¿ïØÅY´é—d?€À BziPzqˆ&LkC4…z!ëà‚¿)=j{Ÿà<§Ÿ µéØ<ƒLz6‘hàtyÂüûg°€?;œ ¯ççÂ]¹0Š@Ÿ¿Mm×îµW@‰Ý“™©{ªÝE2;E5lžÿ‹nT÷ ÍVÁ~CÔÍvSÀi!O¨æÇå£Ösâiù\ùè*‹‘å‘-U*˜’ÏÛTs\™e¾pšÝn§$ˆ¢ (r PÓÔTPPPDfe“Ûɰ>Y œk®) È’Û)ƒU[‹ppgÆfä\íæqLàƒjiå°÷ðCüÏò¸LµÕ ÛLS‰1‰Í]ßüð~©®\.5ËC]Ï"‘®ÙȬ½´¹°¹Û –6kO‡yCX•Ò1ŽD7$²3 V` Ì­ N exh襒µ5(…Sz_%Ç)r¥/ØÐòѶ¾ÎQRÌé‹C¥§w8p¨1ØàS–q%Å¥ ­£¾®1¤=ÿÊ@òwÇò7í:{¦£óO¿¾üéÎS,wæ}Mrà­œ¯sCw<Ú©VmíÝÿ­¶—Ú³Ÿ­ÝõTç»û‡ßü[OòTû&?z#9Ò—¿¥ö¯>üÊŠ•;ËêVµ±3º²á‰ü«µÇÚ¿9Ц{ó®|7Ù+Æ£ÇTërÛ†ŒyTh¸„—!#l¬Ë ŠŽ«&ã-˰ÌÖ°„ ogí§wÑIÍææfùYðæ!:p +>äáíê )).,u¾_½3òܦƒSGûו|÷—øßÿÀ^L®_Ê_Í?}ó§ù³ÃÏSK¢`‰ªYò¸*T’JS?é7 gÈY«ÞhàÜ…<µ AŒj6½o¸¥¶Pk wF©5³¹™¯SÔÂSï(,)Ö&Þ[í~þè/OœiëøY¾{üòÏÓ7ñ9øs¾ìÎÕæçòw©%nF ÿKÊÐÔŠ£Ex£´©ŒÄ¥Çʈd1ëÍj¶˜Ä8ëÛá ìS‹Ž%Æj‰?c¦#6+*iqÐdRi/jp´¸öÊnÕénxÒ½ÅMÜ-¶ªU{´n±k Ú+cŠ-,n1µØŒ8bü¡‘EÏ{‹qºGìšæüN17—ò;…œHI8â "á¹ÔŒó+~VäoÏ sâ ]ûb ÓPL¥Š*C‚•¾Ê£Ô¬/ÖÓçRN_ê(ÕWrÿ9ѾÞc÷mt­ù~¿0î*nÛÜ|áG/–—¼sx-#¤»Ÿ(3°R‰)TÒÿø´ÁS%]…ÃUξϿ >Kç'ñi,"3Š\0ÌœIO?8w7™M¦½Ø§/·Á_§Œj oˆ–þ}‹ßLÖ«kv.‡íÍ ®­)òÂçÁé+CÊX\‘ÞÚØNŽ`ñã—ÞÜ-º·m¤kô¤Ÿn t“jÜE^&¯"We·è°n‚<û¡Á¨ÃÈbD?‡¿#‚0I©:ÄzX™Í°,+š.â3x-˜î¢ÙÒõã¬æ0¯×Îéƒå¡zÆ—ÿòÝ«ßÁ¤f†U†âóå¢Ô#ÄZÀ GÔ-„œ“®ß³¿®WÄ+NCÔuG¥Mâ0û–pžu8§Œ–s!g;¢bÔi(ÊÅr'ãð±›Ø#ÂI×I÷Ié¼û¼d(D/ÉR­´O:( IŸJ‰††£¸¤A"¼Å&ñàFB=©BÊ¥ÛV¡£MSY‚-6zQ<–€…XTà[F‹tÆkež“Û5~?Ë>ùH{ï®9Hz·÷„Ã]ô«Éù÷Ì@¢÷§ö„í…9õþÝÏ4?5no¦6ŒÛ4¢ZùfÖÀ7ë v öæ…-(¹U³Ñ%ºˆ«³EÁDpÓlˆS݉KÈ5¹¡Jó×›šš’xD&¶{ !ó ¾¢±|1Ir,§g-÷*ù‘¯.ûW÷%Û ù¿‹Øð›Ïî¬ëªÏß^çÀºüÝãØø×±ÈÓŸíÛùòÙ® (Î;¾ß·ûíãÞïƒ;`wƒóã§Àxõ6j•">1jN|à#ŽMÄÆ÷‹N@bÕÑN£Ö™Ì@¦6˜ˆ ‘"j}Ôhµ“šªÓÒ¤im&øšÐ0-U'rKÿß¶Î87»{·ì~ÿß÷{ü¿Œ;Wî]ܾèùþ©yt•*os~X¥Ì_´â&÷e7Þ”±3bß#‡]lép}žöeºèq¡ÝžÝ^¬BÎ!¯Ó£Êf›ÉЉr5S•iæ=fl6#¬Yeg‘;)¼ÎC~ê¯>n^ÿœbøš;”o>f: k`òغ·É{äf¹M>#ù¦Ð]•‹r}žnï:Ôͤ‡¯EïÐbÀ˜èµ—%†„žèe]/¢`–CJQP>&á xhf¤ÐJ=O`‹Kн€#„ŒÛÅädçV"›yõ´ÙëVO]!¯^ÿÒ¤‰KzÒÿÃßn¸ºeÙõ­ô[×.éß¡Fuù« «Vlv÷°¯ÌžüRí‚‘ÍóV¾yîGþSçô¾ÐÓlÀ5¸z™æ´6f…qØ$H?L‹ïYZ',öÓγö«N³›Œ¶O°môÇ×lŸ¹„“ÌUøw i›_¢P̲3ÿ!«YV‹T¬R`ÕCq iÒgÒ ÄJ¨ª½ !ZÕ²e®ÖR(» @¸.«»Ê„L¾@Z·#=÷ œÃ`»?q,¨‹ÃAqd†ñôÉKÁÁìHÁÄØm 𹞀ÊsV½Ï0süœM¶WÞ>öHxõoúW(ôÏÃ_$ßÙ:mÊòU3§­âfd͜ڒܬ÷ßø‡Þ‡æ èg¨öäÀÝû6îÜÓ¸ о „üŠËKubaÍÏ–!ž/ã R‹1Ÿ‡!˜´‰ŸI%+m¹b÷™8ô#`ŠÐuLì—Qº~¥³f:ü›ž! ™Yèup‘âÔ“«µ Ž0¼ a!ÎUT¥<9ÊÆ™*¸¯¥Lv~TA¤!ñØ'AÿW9žÂö5mÐó%bàˆ‰ÅŠöBÿ›Á,=äAX×õ ˆÕ“t´Ë8R x²»Ê#î67v»]9Ù‡ST\Ä`þ*¾žÇ|E0¿ tDE2F¡¯Ú¥©‘°ž^^®ï ·„E% ã°+[agL°ïl/|nÆãMB”$êî ÙXjß@”¥ÂÄ=XÿQf¹›†‰õ:i~Ì›ëò VVº4(€ 59µ8 ÓL fýOTˆ¨âÒÑT¢ùy9¬]¾ÈËÙ'=Ò4÷µší{שּׁ÷èf<ÿAè³+&üc+r´Œ›¡m¸Bº2_>X³ìý‚üSÛjO×™EÌ]Ô? Òì'Ì’Hò„¾^2%¦Œ{9D“dáàm2ºBó'mÊvi‡k‡§™ù9IºÁÞ0þ‡•RÐ4pð¬!k¤íDœ‚×ëôzGà B$¤Ëì'FGU£é6Ýdú@<r{Z45€/h®æM+äD‹fqD-5VTeEVÍ…|jÙŽBkýÖRÍ|ˤå‹d  w~‹€¬‚,D¶x»Úý[‡×¥Žº!8à°öCÄ]@GúGbh§1Lx.G¡î§*ÐÙ¢ÝF]‹#yœþé7ú_õ7ÑFEæ_Õë_øÞ]û‹ßÿ®em+öÏ뻋ö ¹èU´¯yþ±V7ÜÓ¿Óï}³ŸzÃ[ÀÐ…ÀP4€Û´’ ÈýEïn‰‰„¼åÞ‰ž9žåRîíoò$ûD¶SZ:«MLÏo0ÌIZ•æ¬W‘¢F 'ì`¡-bÃ6ÊBå™,|BAZe¢4òzRÛž~r†H4SÞ‹Þ™¿^ðãÎ…¥K+ßXôËäuürséÄšXl匱ÇIWFÞyýöŽ¿Ñ²¸"$sçFYÕŸ´¶v,uX(GöAOØ•™½Ú÷D b€wÈEHX;‘X.€6H## |‹'ظúsĬ™Y3')ˆ6v@ ¨Èôÿ¥0VÙë=CVô”YN@O +ò”¬XŽô\¤Ä®ºÕác¸‹o&¶„t=ÔO>ÐëÀìÀì`ö³Z‹Ãìy1"žÿ.rEâ^‹"3T‚óóUàÓY®}Š1bÄÆ§çoxÖüCmv2æ “Öü°½É1¸6ù6Û»“?¥È.õõ)àp/”eUdU kŵ¦F±ÁÔèmðK¼—÷;¼ÐL ú‚YâDã{iV«³ é nCÕúðåFøŽ]Àï¨:AϹIn PHJ`BØ…\ê‚ É‡Ð!7ÇŒ0cQ _B×R@ƒ—D˜2 ý>L3MÎ8ÂßÐq0nˆyE…-l~³¤¾w’ •žx‰K]–¤ :Q¬NƒZ{ù†–—ÄeÝK·‹½ò=qLžÂ§éIqFžÇèßÅ?¤Õ-zä3x}Fl“Û1[a¶ãºR¬’ëñ”-ÄMt¡h’òÅ Éâr†]ÀsiAÌ“ 6#ØG !d'iL°lÜJ”º±¼aûò åóåÜ*˜jñ¼´Yܵ³S-pë7 NLNÌP˜I+ì6Ô+Ä–ÙŠfŒNŒ©0[Ískà-iÊ…È&„bSÊ<ÁpŠá1ÄG1öAQ Æ+md!k´Æs<‚x¨µD ±æû zž¹ì)Žø[OAÞ2Ó¦á9nÁ…š ›´|¥‘ðkÖ:d.ÂØ• Ô¨O&ããõÉxd3Üœë„x•W*¶›tô¤f.kÄó‰ÑƒfZ äVïç1JNƒŠØRKˆ >‡~‡$bèHq¬øIñlñ¯ “ãäÂåFúô• êLíæqTCrmA ž 1NCÀk]MÕ*¹­¬{+xDòŒqÂ1fD@¼ V„*©ò˜æ`fˆ» ×\n¶™dÙkâ~sÄÄ¥¾ÈÅäC½š·›› "ïUÆPq©U®»^0R€|'/M^yLêMb›k•ó¡ŽÔ01ê @O—02rH(ÔxƒGΣ£Þ®Þ7Íټלí96?Y[àͰè$JòÄ%´‘l‚ßÏø9b¼K>àá$Mfð™Çïæ?%{y?ÙÏßs³4ÐÝ6»€ÝÛ¼nÔµfä 8­ž wv¸¢ª¶€ïƒÅÛÝxK®`ᘱ8&16gÙ<|[†]ö]üa\Ζâ;Ùnöû#>ƒ/àóìklfq5[ÂzØökl¨nÒ•»öÓ®A¡Eó 8w¢4^ÊŠ§Æjȇ—É‘« •mqT„_+×^tïß¡ïà;};mʳ¹ŸÅ³ñÑbÝÁžHÝÊ·úúìM¡­á-‘-±-ñ¾¤… ÉH(NÆ#IVVc‰D #Ñì~‰4é’pÓ3Snª-µ&Õ›êOéÔ—)œ dû5ä <ÓËù¶ÁŠ ï\ ž^mõôêXØ"ÄÖN˜y 0Ñ(%På +!RDAË‚üoVnD Ѧâ†â[ÅÃÅ hÖgžýäСQ|btçšÜÜâãÅÝÅ=ÅÕ ÍW}]œ˜˜¸úÕ¥S¿‚*Pqèv§úáðá8¹KG+õ“:§Z¶­•”Òók<úU1§ïµâßPÃk-Uã/eSVܱä!Ÿ®ºñ’‰Ïè¿¡v¦£ãîüÃÁ¡Ô›ÕïM§0äF`ÈÄsíz{õZ£ÇZ[}ÆwÒñµÈûíû3-Î*ߣ¡•UU¯œÞêK=_å 9ªcßRYPÖmO$ ÷dîqŽfŽ:´3ÓélÌlt>Í|ê9y«5%3Å©³ N“l²f8V»ó„õÃÌVëG™_ÉW¬W3e -#c8 ™°¢–q¤EQ츛HVÇÑêøÞ8Žãv­XÈr¿•ׄ‰¶)ZZœLf"-Gmh;êGÐâèsê&ëÑš[Eü‹‰йe±B¬‰e§%k+³ý0s6¡/‚¥&jþ<‰ù¦æ5wNËR•½eK`s]Fú[sçJ¶+wº]‰ºGÇäZÃÏ•»äny‹, ˜'å”#"’ä@À ëßâXŠ †q ZǪ¶®`.é"Ýd ¡D—2Îg¥}á{²â¸ÏL3 Ó–M½”ïIÍŽüâ¨cÞ_´Ûè«ölzüæÍÛ“á©¶cDà©t´Éj%QÝÐDäÒ Y\ w¸·»wxvúzýtø?ó]® ªKÓ0"b¹WÖÔ°ëU Ê,s®¹ÄäºÌn“„ÍóMsؤ&ÖkôaÓY#0LäU@3ãÖ Cå-õ@JüNiç¹ Èè² –·mxŒê}íWk» <¦æ…Ïž>·¶8$xe¨qѳ˷ä¢wlûæù퉥½ó×^‡¨g³Ð9çÁû ¸ qXÕ hsÄ癌Gî©Ê‘‡5å}Å4ÜçÎi¥~Ió@L'¡ÄÚhBÉÒœ"jæ{üþ^Ž'fþ˹ý!!"$¾ÂÜ ÎZEQ.*„Õñ*…@ªÜYwÌÜó!½ôßUK6BqE‡A»»Cldz~˜ð‡â4 ƒ†AÐ ä“«P¹,þK¹ªÝo)74þ$ÿ‰rR;΀?9«]C—eùý@y[;Jûø£J¿ö1•ÇÒ2>¦„µ^ºïU~§I¹—_Â.qyAiNâʰ{QÊyO_Îyì±|̇<ÍvªÀ!,‚Ù¯(¼ï5:2ß?®R>œÎÖô `5ÒÙZëÇÒ @x¾VUŠUU‘Q Kr±$ÉTÕ´¼)Âiˆ`ªq¼¢Š²$H¢ÈçAâØ U¨ü¸4®±”°0¤Y1æa«…¡ €÷Ô]wñ`èm™¤Ìd =“ Ά‚¿rîüÇyzøñ8#ò0 Òö ^žrZÚ± ©¼þdCŠAÅ Pñ:ÁËìßãØ¬£à¯ñ£öû„ý¥}ªÐÃ}{Q~dæí4 .þG€ 7Yoy¨©´ÓE =ÀïÈûÔ/ðQX¯îÄ=Ün~‡¸[îQÿ„÷q²}â\!&p‡¸žÛÄo’å8n‰®„iL™Jg)‹•éfe+Ý«¼IÏÐ(®Ú¨l£½ÊIú‰òw**DT‘“•r ³<’Á † hpتF|1<¤ ’ÞQEÐo –×ZeX÷I† Šñ"PDpJZU&zÔ<%j,:ËD‘à,¯çV(–50<\…på@Ú W§L'äæOdO\©‡á®¥qx+•J¡çÆá\¥:ÁÿŸ=/Â8ŒذëµÚGH† ÙUø³Lc¦ß¶™šÉfàíBì%ôÑ 4 ¿Z“ÕºaSŽòœHyÊñ¹u˜`ˆ vN‚ÈÄ*¦"øF¨Ž€D¼"A&Òd9ô5/’”£$[ ~pŽaDÒ$0€ï ¾Î>™ÅÇ ½]w_ º3¹ 8)Îë—8‹&xX²‚c±’@ôÁt `›7Jî¿1H¢(P—ñg®âÅ8ˆçg.“\{æ™zç/™]ðÖ#öJº&[ İ4|ƒG:g5sÉ}ÅÚÀ{pÀ„^ºÅ^yø0ó -ÙoèX:Fµ8e=#R òO˜3KZÊ¿p_ôÈõút}AE§¾¼bCÅëú6c¿1hž4>65Apùü‚| ýy²ìú…‚öAüœ›„"µã<Õ®ˆXec`ÐCñU‘;™b­©¦ 0>)„QÈz7t+DC¡j<YpÊ|AóK­Ï”RËtÃ4â¥iòó~*j.¥šu8øÎ™ákg†;ªáË*VG«ªä1®Ä#Ú^<=\ÚUàkÆœ8Ž/êü-#˜ñU¥OðÅžx*°*Àôñ+Ë»¶çΩ‘älwòz4·»äð4Úd&¦ùåÍáúP,„S‰‘»4ɘ¡ø¼ÈÓ’Œ&€‚¢t®À%©$y%H1&ë¹b ”©3A²g ­¡¾!g1sP¾bÐpT_‡—e£§OK·rf¹}Mu‹ÜÌ}É}C½¯4kîªÖyøÉúk‘†…SgMïVÉ?ÇîîI¼<`§7¯ŸUÒ KÓ§ziÑ«­%åá’öiMöé¢Ú`esSGmECd„|# ¡ÇqŽ%èAT”½iS'4˜3LRÔ!t(þŽ`¢ä†(ÔÑ&W“·ÎœF[]­Þif¸KV´hÒÈ€$âÅb– ¯ª"%P*]£ð(wá* Ó¸ ÐÙ…ºY# MÉÅ;ÕÜ6’i¾2eÎOŽ0E •ÄÉÇZj§Ð©tú;ƒ+JødøìBWäq#X¥Ï ’)'r!d±þëCÇm;3¸ø=«(Þ²:ù›—/ÛÀÉ|×c_µoÙßÙç'öGßžÓµ÷Àá·Þ`Œ?Þ} T‚޾¶Ú&Šþg W­ð¯ ®ÖwÚ ÷ÿÉ®ئ®+|ïûÏ~¿~ïù=“8qœ8.rƒ àâ¤)…aTŒÀLB·BS6þªÖ•–µ%°®[¡t„­-¬c‚H¡mEª¦±VcS%Öj¢CˆF -0ÖÄfç>;e?Šœó~®}Ï9÷;ßùÎo?i—œkÜ5áZèšu‡ M M±æsìV§=Øä§“íɽ‘ݨng·©;ÝÃÆ!{Àè·EÅG踌âK3£¤eòÄf|«êy3H‚œzy°y°¥wN¡É2ðª:ÌcòÇPJ&rlÐÈ8>fº‘%¥TÎ#£I~ÞPrx( ³Épþ ¶0œL‚-1+äÔ×þ%TMšÌÐ!È$@‘i,^W¾± kó–Õm+-l&‡w­xÛCç?£>Ÿ¸èÑ=ïžÙ¿lmêWç†Ìãñ‡‹< ¹[QÆÍno‚ÑεKíF -¯4îˆâºhw”šJg‚S­Œ;‡n αZܽ¢húp ÔxJ€WT8 )œPä8&HQUé!؉ nå’ì—®¿]BŒ¯YZHh`Eî⺤.£„.ß‹5•4ÒÃz ÿ'T˜Å‘ï-=Y)žï{»#ÕòìŠ/¬úæöýËÚqÌ‹ v@i£ëÞýÊš·ß:yðÄ;â­¬˜¨ÿtiP'­æ½â>ù‡ÚaötZ<-ŸŠ‚‰gSs­Ò‚èa¹Ÿë¼/]^’þ¼ÃÿS–+Ô Ë†°gS6Á„ÌØnxÓÕ…Jg”:š-dGóÙá¼{9P&ùõÙ|rð¯y"då>J“ŽÅÁû¬`¥­ ×góÞ§7=Ÿ5ýÁ¦?,^ÝÏÄÛ¶½°¨ö×Zó¹—GOÒøµ_\Ètú "…ç{m¬Ü^IAy]ã6¹»‘©Æ5T ýNSiÚó¨Yô2µÝl¿8±ŽjµzG¿2¦Éi{Z}úþ¹r‹=·¾åþ›ÁBXÚ=;” A¹N±ÃÖ9¶§–TÀ ¿| +º’ã`ÉÖ7”  f|É6fJ… ZãüÆßÁ©RëˆQ¤ $á‹w\®!ˆGB:¢ëF"=¸(è”'¡tmÌpø’}†Ëü£ i…+cͪ0¼¡46Œõä;çoÞ‡ãí‡È`B>Dã•[ÜzŸ·Ô.³küªÄÊdWŠ#].ÌÚá±¾ßVp¸)¦› US B!dÞã²ïàBeýâ5“LJäçÎ]ÚüÆgÓùéëN÷ÿþ×Ñ­«víxâñ­­uS¬hÌn¬YþÆ‘=ÄùÅk£ÿrðÉìÀ.…Úú³7þøíÞ7!YßGˆi^·QŸ—Tqn&©ÍÄ3õ¿àa‘gm¶–Z¢?¡³S!S7B´Ia•$µ’æEI2-ÉF( ÅÑ«®Íñ]‹f8û¾ÚÌn§×¡Ö97ꆃdÆm˧-XÛká›¶Üp®”øõ’Ùy…,0\Ý.ß•fV˜8† §a_^ Y_4ç1QÊ(güvÇ‘KüógVì_PY¼Z½ðÁÖ5éâUŸ˜½nGOaÕxhiSËÎm…Ï!hÀö«PˆGà’F<Ú8€Dð,§K9Ol©nñ˜xN¼(ÞÙ*±SÜ"ö–æxÓt1]DŸÂ7ó ‰8–ã‰â¡gúXŒÕfW(Çu/Žœ_ž4«‘ˆJ"qC2Dœ†Ï«Ø-^Å.Ó™âèÈ&>ò1Lg?).ÄïøZè%ožÍÇùêð$¾_`»ÃFd™²ÔÄÿõˆ±¸ k»D›qJc1é!:‡å´•çÚvxZbԓ&vç]qHöa®ñ=ʹ hÖÓÿå7ñÚÒM_ÎÖMöùvR“þ v›~ôtÊ)fšœl”‚Ù=2òÁ¡åªz“aÇgž§oVÝ È뀸舾{ù¸¬çh’»Íî„ Oktˆ«WrG¥³ÒñécIZDwÒ”Ì;b+÷5áŽí?a†˜QæÇÎçç +¹ÍÌËÌÌ~v·ß'HUŒÁ%™$ÛÀ5ð BJžËÌe%ÐÚ¢$ +‰4ÇX†ƒ\¡@@à%Z’Ì)êÛ^„M ÍU<æ—©@w#\»ÁÜwˣɎ«Ý^ïSy• dÒ#Óc úî…>1ƒo;mºÕ˜ˆº-M|¼¾»ø¼´ø~±ø‡â­­ìàèmüLñ{…åøòÎâØúJ r” eÛXª›=Æžc/²7X¶Šíd·°½ð€…hšt£14œøh,ã/]Â;øE+ìõBÜëÀöuxÚJÀ·ó°t× ÅÙÁ 2N¦¦…zHxÈi© VÓ©Ä"±3Ñ8x‹;Ä¿<ÁK\L|šPP"•hƒgŸ$¸„©Èäà¾ÛÉò1†T’vØ'ñ1¿+2¼¦ëuã**âu””ªÅ Ý[ÚÔ©ãµÿæ»j`›¸îø½wç³ÏwçóÙgŸMœ;Ç>'Ä4v‚CZ%d@J>B #KD!ÀØ€tccÝÔ¦]-éʨ–-šDʪ5%lKö!ek5ÖuS«µ•V6­h£ Š$V‰8û¿sBaSwʽwÏ~÷âÿÿýßïÈ8n4Ýj8±(Ÿí ÎŠÀg≄A”äyŠ2,qÅåIoÖÀï6`ªa®€»î2#c˜u÷fªŒ7÷ ÚmDƒ¦ŒR#mÌŒJþ½~Á¡>Uä€úÐ1@µ3Ýí¤[€$KùkúæC>IºE)Ÿæ'¾O±ÜŸ° ʸ QŸ¢Õcˆî›ìH7žÙvðL0k‘±~ùî%…©’|ÍŠÝ‹ SLâø‹›Z[7ulkšmÃ/,©_Ý7PÀ¸ñû[+{OÌÞ‚=;NPö,@6ƒvŸâÛêØí`Æ»åip4¸?ôØX ²½v—È <£D€² ›Bs°ÈgA¶“O.’_Qn#·€¦ †Ü…ÜV¦þ¼‹cA½kwAµ•$p¦­0U¶>·æ«)@[ßÛí'›£¸ä¥ËZzÏ¢LâÔ…•»{¿Iðzèò“©.nÐ\}M9núnú™‹øª K![ˆÃmžÍ¾Í¶à b‡ƒÂ8÷.þ³í/ܻ”mн*zÎ:ÞÀ¿g_uüF°t<Íö:h¯U…¼BR$3v9gW;ÃÂ8ìÒ¨»lWѼÍÈ«s{<]àEöD(µû2„¸ Ƶ,¿ƒ¿7=ue ¯ô\áæQT:°o_ÿ¾}X±G ?¾^xµwnä…‘‘áS##$޾—˜Aˆ×¾ë¤¹d™oµK:'æ|™p½F\ãkæ6³›oû±û'aœÕ2^vâ¿ÌÏ{Ü.Es¨ÀkyË].wÂã± €êÿZ”/ÆÙ½îZ=l¤çÊB¸Eù³À¹DÇt±]wú/З°“$f°˜„ˆû4ê>ÄVÿè‹nMl9Ö [x¶kû“‡ÞõlmËŽÂ_ ³…™Â{­³Òc?|~ìì™ÓPG(Š®µb1“ƒ6ĹÐF[—í ®’¶¸v»HŒ“s Q朚,Œã¯›åv;Ô7Yg’â<\š;À1œú¸tZÂÒãÒËÒ[#y¨¢­ø1îAã7?"EqÝ}G9Ï^´ä5dª;wO1ÝTÓ¨²±i4»~ë–Wœ÷,ƒ$~OMGg5]F¥æ½ UM\˘²8æ­5ÖãÒ›‹€û(”F&jAL'êAÓˆ¦Fˆ±fú0!sÅ fšÁ$„€ KªÖULXT1³µÅL-&^ ¬ëV¢J‡²_a”VÕôv«¨ESñ|ðÝ©íE.»’"éyv»’*&£øe[Ñ)vÃÕÞ¾r—²¹×MŽ—òî$4‡~"æYÈ‘ÇóB2ôÏWøE^Fð>à¡/°ÌL¨Î€¢ÏIØÏFßÎúepw@…2QŒi¤Jûþrm\ö¯)¼ôùÇ.}pédᦷcËþti$~Õ¶åÆÇïÍ¢ªÔ†Öd¤ªÔ/{›îÛ|âè/ží[zßýÑ@¬ÄéZÛtø¹?ŽÂ)ŠÎ]ÅÇmÏ'üÁ,/¥À’:ËÝu®µ®6·=ä§‚tÀO)’OFŠ„e¤9»Ó.IºÝ”2¬Œ*t't“ ­Œ#æ¼È£ü¬@§Kà¹*gEU¡@ ˜a&ƒtB‘Zýyù´ü²LwÊ=òwå·äiÙFɹTNËŒR /ˆ‰¦ÑZÀ‰å€”<7¹¬­~Ý-Ð7Úë=7BZ^qaêKh»á"ƒü1¯låT!IK@J½±lu6îÅNòFÄXÜþ­ÍñÜO •I\.lz2 _ª¨^¿ji?zóòÛ?(< ùù ÌF&úà”©<äÝå°Ñbëq½· 7y§°Ýrt^†PN¿,;9Ö''ü~Ф+`©„šƒ3ÿTç¸-hÚŸmìŠó_ê ]ËZn‚ÔŠaG¡yéë~¹gï¹P(º!¿ú‘ :ݺý çðp!xyçòæƒWÐ$X%ˆ“´âäQØôÛ’jUÆN–4Ò€ÁøÓô–I+Uë2'ÄÒ¼Ãáxp¢X¢UNuêÔbþ"/ÀÙž6‹J3NÊÆËTˆS|†ªãP\’.8‘(Xkñœ’aÅ!–rRù<ñK)" saSâ)'Ã;9cÄÂ3—ÉÁH2ËQ1-š"#*ŠêqæÍ`BÆqÚäœã™<ÓÌÐÌÏpZé²*¡QHx j+DŠ+\w­˜ª=ôઠÿ°Æ–>%âTÊ!ø ÖÑNa‘s —†4ŸRS[SëòÓÂ&dü¶Na]žß!­Ù›ýÛW/Æ%Åœrà–ANl˜K!³NŠÅN» S\Âxmª]æJœ^ARtŠñ9ú?ìW]l×>wæÎßÙÝÙ]¯Ùݲ`¼^¼Øk³‹Íºc›Ÿu€ò·m"Z(Ø-ÅJ9ªÔR©I¥¨²Ò‡(}I%š§¶i¢%AíCªÊP«µ+j‘P-DCÙÝž;35-¡êCû2w÷;çÜ;w~î9çž{N^îûä1qLÖü|¥Ãk{Q…:¥ÕtFG N«¥*-Æ"†Q)Z'5h)Vg4C«´Ië^¡WêS¶hg`˜ž‘†µavÆ…³tT:«e£ÆU¸Jg¤í*›1®Ãu:/Ík×Ù¼qnÓEiIYÔn³E£AšªüÁÒiËÑ$mªrÍî1Þ3î]Þ“y޵q÷xg¹n!qM¬̘ùu,âìú4‚‚nñž.cWЃ4nt^ðˆÊã¡mù‰_ëTJLU d¦!ßn­ÁHà]¢¡†(1]ÑTYUI¢”û‡ÁÐQ€eü~ÁN¡vjÄ Ôù ЈÄ?‘ 1ߥiwr•x¬PŠGK¥x¬uœów¸5ŠÙnþƒ6… ý•èào;†ãI<òOè–/+^÷åqÁKöuËà# öE‡aon\ç½¹{‡€}Šð¼ˆûW˜ÿÉJQ$Åò$øÞ$ ¼ù[)Ÿ/ßœœ@ë¦8þ~M8_Úƒ^fàÎ=hïÜ1ë‡)å}*Œ)Ód–Ì( >IUâ4*§äVØ ö‘"ù9­°$I+-¤Mé![•1}I^R´ZšTêY޶±Í´Ÿý†ªÛÙnZd‡é 6Lže/ÓŸ(Ù ew™O¤Š¢±jš õ,K;XÕ"4ÆÚX?û{NÒËl‘j ®öB(ÊãÅ• ‘eœÏY#˜#”)”™ š*rMürMC®".ZêÕ91)hU‚ I²®»—tÂEk^Ö“ UH²$a®ªjšÒ”pb\ÎjÈ,]=ò„ïUßœOô‰|XÈê|8´€êœ8M@áÈýH0ˆ;ÿÖXÁX´%È8ÑɨԘN¦GŸ½4Úu%Â}8qý-–@Ÿæ GŸ¹ÇÀààá$Kl»nUƒŒ”Lö½ý.ÙZ#çʯ_¹&Ôby–¬.k¥ß“-åI;üåtZ5Lr¡”DÂ|éQ#S«}œÂ‰Ì‰Tcß\aL–d™út¿l –iX èEX΄b*9E~5àËøSˆ4EFÄ Üv®•Ìqn…–¯ÈEpëмhEc¹nRgi‚݈À{!’kyKŽkkŸªKîY.”bHy\-Ù{ µ5T0oÍcÕ7q6ÆÔ ל³¡¿ÙÎ5ål£mo˜xÔ·áQ?NM¸XAkUÞM²[ÑN¬¤Ê_,¿/Ø6Ã1$¡h‡ÄÝ ;œcßyVÑÙDŠ_¬YUWÇÃV?I——HMùÜæÚÍûFvììu­?ôd 7”_¸yW˜8´qUpÖ÷­"×þ*¬Ÿ>D훤0ºL 晫٠æA¢• Ÿ’%&´ê½¬×ØOö ÇÈ1a$¤þ™~`üΔeèkʯ„oƒ ŒìÆ|ƒÉ¯ÙÉBÀ4½H_ÅT5‘lDÏ!é eÍ€›êsnÕò\?`¦€ È8êþ¬À„¢fá9ã%^´¡[hø ÅXÆ{$=Žÿ÷ƒCpø»÷*^¦ ¤‡Ì[˜\ -ð‘[í7ÒC<–>™Gzƒs2èxù4šã˯Es$¬ 9STnË4GÑ-ì0Ú¦0`z^7 „ÏŽsEÈ®'-­²"­_!JKvedùÑ¡LóŽò9ñ›å¯¿xz9¹ðGrùTF$Â_ß+¯ý©ò)¸íøÃ!¬pñs´Þ:ŒŠG]|ø¯öãÙ\P÷Þ‡öÂç0ìè?CŸðõø¿Àw›õˆwB†‹—T=‰¸°ÌÃñ8F­ø¼ƒåxÿ üÖÇ6$ð»Wâ7Õ¼P[ 4ËAª`ÍV€úçÒßhÀïhD4áûš¸|Xw G§ZV´â7´âš7ÜqÿÀFßÔ Ð±Àz ëc€î·zÚzß÷àÁƒú¢Ÿkƒ/nâCg¨pÔ}’a¤Ä]IŽ,£”ä–¦ŽD!ïÊøa§+‹8ã€+S”àÊ2Êç»:»ºû»ÓCÇž:ÞÐuòøáÂîÿlMÞÉÍýˆ4ÊCp UsUtž†Ó(¡¢8«GO"? xð³þ›Y\3ò pÚqPFM˜=8ÖožÄ• \ä%@¥¶+P¸Çá¨ÂÛ?kŸ7G6°Ð3žQùc~§F¨àZEøøé{§gÚ?Qcª=ûgµ?ÊùôÌ[á;wî–LP#À·ql÷Ÿ²ç endstream endobj 325 0 obj << /Type /FontDescriptor /Ascent 905 /CapHeight 0 /Descent -211 /Flags 96 /FontBBox [ -560 -376 1157 1000 ] /FontName /BABDOE+Arial-BoldItalicMT /ItalicAngle -15 /StemV 133 /FontFile2 326 0 R >> endobj 326 0 obj << /Filter /FlateDecode /Length 20798 /Length1 33148 >> stream H‰\V TTW½õÞûÝ€€ (›Ñ­H¤q!JpC;hðíVT\@ŒŒŠqâ–H$hÜ&ãšËIdÔDÑ(Æu<W—1‰Lœq9¸ gûOu›8:ýÎï®÷^½ª[õªîo€Ì…ÄÁCÛÇþ%s<0÷!¯“ëÊ¿ÆuÀï+*3½@XŸ½‚÷®–uãòÇç¾õ§¸>€u& =?¹pœ³Å¤N@L¦rƺ²4þ<˜—ÊgrxÁ?Ãg/;,ày«œÜ‚™}òŒ}¬k'Oãƒe‰@Þaž?ÌuÍÌ÷íÀ¶æ^`}=Ï•;6n~×¥ÀœlÆ“›?eZéAŠ9ûzþûcó³Ö_­š}ø'h•ˆô>[©¢ ˜5¿=îIfgÏ=Ù¬¿°µfÏŸ_?³p‘ÚPê¨vÐk8¯q‰Úb6NQ6š"õ¢tÒ`A†a+NY(7ÿ…/ñ.n+Â2\';ÞÁI äì¾õDMÌRÜ"a^g ]1K)D›®]¢ùÐHŠÍöà“ ‚$¬Ãyší»Ë¬Æ›øF 0ïa…‰¶D>þ‰ZÆ'Å{f.\˜ƒƒd‘)Ú ÓŽ<ÔË…æFFbÅPö; âì5‰ªÄ-ÍÐ}Ñï![°MŒÓjAˆÆdÆ~ 7i]–7唩J´Öîžì³%Þ@"G6 £1 %X…ýjA´Z‹6s¢³…ެ3ó±å¼HÁÔ„Þ¡õâCqZÜU_i—ÌÓ¬Õ ÓÓÄÜÂ}²P;ê@ói$ Å©›0÷!}˜yXŠÕ؉}œÍƒb L‘3¤¡n©§îÃðÇpÆôÊñ7Tó½5¢f"ZÜ–Qòc¹Qž”uIcµ€u¯sãC9þi|ÏEX‚ (ÅnT2ž38‹Ë¨aÔ‰4‰fÓ´—Ñ%ZŠîbŠøƒ0D¥øI6•ér˜œ*?—käQy^«Þª¿Z¯v«,q–›V—{³ûgs™iÎ3—›{ÍoÍóæ]ør§µ„ vLà\O叿p&·c?ãø;¾ÇÜY5\u ФÎÔ†ÒÛ4™Þ§%ô­¤Ut„¾~"X4ƒÅ1^,ÇÅiÙEv“*FÅ+‡®&©µP‹ç1P+ѾԶj¥Z­VoidÙꟓÏÚ>»æÎqOw_5ýÌ@³¹ÙÁœ`ÖACs¾=ÆsNÖrN6quüU8Œ“œ• Œî ®âþÁ žB¨)…ñˆ$;×Ö šH3ißâ*ZKi7UÐ>:D§è ¥st‰~¤Ÿèßt—j…ᢅ°‰X1Jäˆ9<ŠbµX#NpœgÄEqSÜ‘A²¥l/yt—½doY,KåÕD…r¶«ß©Yœñ-ªJTgÕÏ´ ­±ÖJ³kýµOµ*í˜7æ@K˜%Ú’gY`ùȲÙRaUÖ¦Öë|ë"ëZë럛ϟ}ör1NxéC™t;äÊ¢"FTLY±Ø ¦Š~jøL´¥MKex~åWX"I4TKå2Z‰]Dè†( 3h9ßôQÊçê²c< Ý"˜h%â‘<ÍœTÍÙêD©ú‰ãê;íØˆ"ÑJŒ¤ïÕH‹¯:Šb¯rªÎŠ8·…LÛŸÈÅHÀ]9MÞà®ÈUK¹#g“BÑ ù÷"×PµíГޒá4DŽ£ŽÓs¶šYb‚(=q˜VŠI2†> xÔÁríVkªÚ¤v™:¯Ìò&c+Û1´ÒFà3š颒à<óé~® æÜm*»dj¥STˆgôX<ÆØÎ,¼C´¡Ë"w,£Ôuª™HÍå8æ4ÍÌÊ£å]ô2D *0O›(’û¥’yéžvHLÁræ‹ýÌ(2ñ;‡»ÑŸ ¹y”síßg~åëјCó¸O×0_V2_T3kÜäý+xĽ»—aˆe#¯Å·ßòÁÄó;#{é†ùHãÜ}E’pÈÚØ’¤âí€5)¹÷°äžI=ºwëÚ%ñÍ„ÎÞˆïØ¡}»8{lÛ×cÚD·nek¥·hþZ³Èˆð°Ð¦MB7 jàßÀÏ×ÇjÑ”dÇv‡-Í©ÑNCEÛúöóÌm.^p½´à4t^J{UÇÐ^5ýUÍdÖ÷šÉÏ5“_hRÞÝãìºÃ¦§Rmz OÏdyqª-K7îxå^YE{'<‰Šâº#,'U7È©;Œ´é9Åg*Û+kà—bKëgG™_°d„ÚòË(4‰¼‚ut-ð `TF„-Õa„ÛR= ÙÚáÊ6†¤g:R#£¢²â쥌±6`ëm4Œõª ÅëÆ°¤V¯}‚'|ª—Ù«ŠK*‚0ÚëŸmËvÈ4¤+Ëã#8–ý¦¡³n„ýoÊÆ¥d½¼)‹atÏ´¸¸H7ªÒ3_Þò|ge± >+Z§9‹ÓØu‰'‹a툾'”çAµ9<+ΉºákëmË)žèä ‰(6Qµ3""yÿoˆpèÅÃ2mQFÏH[–+µYYŠ3 ËÓõðWwâìeAÁϳYØðWÁ?àeaì‹=¯äU÷Hý3^¤“<ˆlÿe½Z€¢¼®ðù_»‹HUh¦Ôva%¶®vªAeAdXbë*¢&4Õt;‰GÌ£Á,1±µÚ˜h­Ic×h°éš‡¢íŒcÍtt•i3CÔ&UWª“¨Í(ò÷;÷ÿÿe›Ätº³ß~÷žsçÞ{î9wKáag½–Ôº°<þiÈ£`}šáã“Ð+¼Çð`8¥ÈLÍg9÷kÙ©.gð:áØ]Ý—“%‹L‰-;õ:q‘#î`Ð[å°Û=šýÂ^„ƒ„SE}ÂØ1Fä×ÊT'ÛGskÑÍ—ïÁžgfò©¶D¼´•ðúyµFÝI‹3ÚÈëqû²Ÿ5–&m>kÖ[šxw¿ ø­œvÜÿIMV¼/®3K’¡À†‡ÕlìT© WYWË|µìWñƒþ™¸a°1<¬¨VÉ}FIÎPÄPpÛñ‘¹R;ˆÇR³mÂí—„¸­HÎ’pª¦ñë™ù¹}"vGB§ˆ~•{ êëf.)œïN®ONª'Y7(¨À^õ>¹¼º.¤+AŒ K\Î’ ?¸(¢¯_ìr¦º‚ð, ®,ö[§ÑßhÉ—<çÃ"–Kùðl™ []Ò†y­^iCU]íTü[ØP]Û†×f‘¿Ð×:ºÚN"¯Êq)ל\£r ·¢MvUÆ/þ”­*¢^‘HÈ–L¢úˆlÈR… Ÿ±ÄŽbŸÚ;‡ŠRÜ·ž¹Ý22‘g>Ê[6áMDò$!Z§¼+yÔ-êì#è í(…¤J¡k–Cº_AÇÔ×è´Oƒ¬\'OÒ_Eû§OµÀr xøp hæ:úlª0ÆxÁç©Ç~œ~¦Õ/b¾JààÓj¨º¹¶IôG®c®c2Êó _`Ã8(/€¾m«¥:”×Aå7Q¾`ßHWµýÊ1Ès1ÿpŒõ¬çyÌF èÝrHб@_~¼üÚþe/Pƒ>•X«òÙ(ÏÅþ”²X«ž×¯ƒ×` ¡‹~/¡¾ åm°k3æ8‰ò`•( mjä)VF蕘ÿY¬»Û\;ÛX_ì6%cºÉkؾDöõ¡Ï¶;°) Ú«äÒYð*`40F>.έú™ÚG8 ÀAÒw°O«°¶½êzÅAúAعSÛOP2ŽW·ëû•k´ºwl[ñš]ÿÜ Ýòeú¥-›š±ÿGÀýó^áKpæý2x…úìÐnà{¢ƒÆéyoP߈sźõ”I…/v¬» ¸Ív`þgyÏùÜ¥š^ežg Ÿ?æ| ø)ú÷¢ýfögœcµ`ŽOŒsÀ|Ìû^"Ø ÂÏLˆ½Q@æ×eˆöñ^aÏæßGù`:Ð|ˆù¿…öS„¿ÂgØ7Ù?Ø70V9Ÿ•ðYc Uð±nóμþ1`7°ÝöíÞ^Æz®ò}aŸe;­±Ù·Ø¯-þÝHÏÉ!9•×É>ÕÇ8ï­fÄ„oYÌ÷Ž}ŸYqÓl°O‰Ò,öYö7‹y_„ý¸|'âÜ·Ö°}3úï¾_´ØÚ‹8Ÿ%ŸØoüãQoÀ‡Ï!V¢Z­‚Ö*Å´KÛY#ö' ¹›V;¢4gY¾Ûúñ‹ {TzsEÕ=ØOÌ/ö5*g©QIÓöàÜI:¦í‘׉òÜR‡¡cf$꾪ü|ZÛCKQ¾¤Euëùß {L8-†¼ XŒv¸¥RÄ>ŸRmD×€ª—ò5/ݯvà^¦!æeC>ßV(âîBÌQ%Ť‰JTòØÓh£šI‹x.ù4|àñÁ+ü(Éçúû’Å–¿ögöCÓ§|füaƶþ<øçŽÏ"? F•†¿ê-qÿûE´R'îd@me[pO‹|} ï£(rc1ÞŸ¹[û‡þîÙ7ãyøÄü›ú ÄÞ¹h;ÓÌÕâmû#ÞðûpαúIÍø¢w!ßd>¹›Z`C%îï õ!*·ÅP~]ï4ãvrc>AO‰÷Iü ;í‡õðã½À6ð;…íy ±ý-ÊÚf¥¸±–6Úÿkßuÿ2@G/P”A÷Wø(çÚÊfɃòV¹¶Ë!u0dÐãù{z@}™æ(¯Òu)òá%z^öP³2gÜMÍšB¢SÇÐ%¥í>£+°«Y@Ë!§¤ã}rïG ÄšO«m´BÑé²z/Ö¿…ÜèÓ"tV«Gù!b y"uª)ÔikÁ›óñøÀŒŸÉPWSŽè—a«¶ù· 6o¡Uʈ{lïì[‚½lkÜÎ:Ç6þ7û„<.ú‰6§Dú@¶Á½ó8ý.ðA;™ù ÎyÁÖ¿^ˆØ· o–×iÆü”¨ínóœx©ÝÞÙ”'9(gAöøçhwåFÈO¬PÍ ifœÚz/ôàøa´ùm{þDtëŠÛnÔ§.` @ÞÎ3¸÷cô+Ï4t=mèsxÇDº!ë™ÌAŸg +¦ Ù·ï|×üŸùsòÙÝr_þÒo2ú礻fë<¿„ûç.ëü¿ŒÞ ÉlîƒµŽ„\ú…9Ób¸bA"›'!Fq™c#ⱈG&‹wÇÅî]€öx¿Ó@ŽÅ""sÏWf.¸¬}àX¯Úئ®3|ιö½v>¯í4qéµ›°›^C>œâc'é(.˜>bÀsºŽM®…&P!±vûÑ­HkqÕ}hTk ‘ÜØ%8©´Dë~Ð2¤Š¶š&1–銢Vâ£+#dϽÇ)LâÇ~ìÚÏyÎ}ÏsÞóÞsÏ{¬®ÚU¥õp¼Ö#\«¤è²n×ÛÝÖçÝê*ïÄÂ4»šãÑU¢Ò±+×ò‘èªÏ¢µì:µ²«HWÉf`ø˜¾ü9¼J²À À„G{6ú»„~Yv%·ëÜ®·ÚõV»°ë¢æ4¡À!ô9O§c§ø²ôŒ<£°)yJaçäs ‘G– «”+‹¶ÊhJŠa‚b˜ ž2f¿ÊfР¥£n© ç›.ü»ðï"©3jö£,Û,Ô,Ý,Û”ç€)@ú®Iáqø=ÖÁøµãå;”¼!´]Ð6Au|ø.ð%pxØìžz€. ´Sâ¡_SæÝOF³T¢”¸)ÃO ¦;¼×ãâ0änâfGsüŸÏ5ýO@ß'MJ4š§i›M’±y”ètø,x;ødÎxÝF°ú@À íÉ5Õƒ~”k €^È5µ‚žÏ5E­yÎéïiQ7ÝAt—åp;1èqð¶œqÍ[õçŒ&<<žkzG‹–Òz’a£ÐÖÝæZb°ÑœvW/8hNûV/°Ñqí#¡}i\t\»nÖ>o*0Ê+µÏš/kW‚—µ›Z´?g ä¥Útæ²ö'ÈÇmÇ Ì6Ì¿7:´· ,†f˜qÿ º2Fµýp…á^Òlõ¾`Gë^ýmñsmPÇý¸–6 mGs.Ëi[0 „Ïânû¸ÇàÏþ¾Òz1xgN‹6Ù97övL0?«îë`5%&yæïÛbÙùÞd2ŽWlëÝüБF‹ «p‘€¥# —­c£B§±K×dtþÓD³ušÿ´­sPK7– ôõ޶gðŒ­É4‡44M¡jlª4m©hºá„¥2C¶#]‡¤Y·%t)ÑmG:]jKÂ$Á¢$ý$mK~õ@b‰tvQ"…$ô¸öÄú2ý1ß<0æ"±dÏnÁÕêþuöÊ(¯]wºn’\‘nÒPÒ,iˆ™¥ HüÝþ¡-)tȽFi*i×¾²jr™)C¦–‡µAÿ«u“BÏØÊ`./6­ˆ®ˆZMXóVSÌ•Å&ÿ«kƒu“ôL±I…ÙƒqõCCᡇ Týoñ÷ezÅ×_Ü´1<4l]C}½ø“¸iôÇÍŽçvŒ)JŸÉ{“°5/Ú$ɶ¹Ýàç{“CÅ+4|pa¶øJŽSÇ‘ã¼ÀqXà8)p88GöæHÝy›#isdìÑûÏØõ¤ÏÕ”ãTÁq¤àHèÙœã˜À‘9Îiã€Ázœ u»®þ¯I²{èJ’žØj‰¦ƒ!:´h^œ-k[BáÄÉT!‘÷½ +v›û‰ÓqA"%Šã%µ.ÙyI¦{êÖÍÈ|d“z+²q>BºQWï¡XÙô=ËP`û#÷Òô=î$ÿ&Ç´µÿ%è/Ø8{£¬á 䙄D%vÛ•J9eôEé !*™"_¡ïÇÓË­QR³ó©³¤%5·²Õ”‚GÙŠ§æ?eïÞ¿7 qT;?$nò^'Ýi’¦i·s¹Ô)µ9ÛäíÒ·nÙáthT%ËŠB&Ù>B¥^*Ih‘ËY• Oý1Q؛ĉÜ,³ƒ8eàÕÚµ»I‚ "¦Ú¹¦ UÝÄæˆGOØ8{gîÖü~D˜‚îˆzk¾ó—ÎæÐOÕ¿¬l¥)’òùÛWÓ O–o¶Ñ¡Kçî_ºÿÏÏwÞ6Pròow»¤=5ÿGðo;§±Ánà»ñ,%¤””‘râ“WÑã>êm©lQWÔ ß‰§E£M%Å>I–˜$9sIs´9™^=E"æGS®üãÅE+î7'!|#z£×óð¾7öÕ´E Z¿FÿSûÖ»{%ñjWëµ5MæõîÓ/Ü^–®[²öëˆLþ êåaž…jQq‰±rT`Ã…ƒ®×{ôÆÚ]ßb§\#®K.>Ö²è ê~öœ* \‹ÑRi‰b¸$¤«B.ISdá“eÁ(B„!IçSTk²ö@PÎðK¨" ’†”·Ë$.®œÄÅ€ %† õ¤‡\ Œ ’cF†è#‚!¡ "†p#ÒÈ9Žüá2 à+Iÿ¸}ã‚c:@ìm©·ªy<òÎ:¿d=ÛùÛ˜³‡†.ŒÂ²ˆ W¤]`Á†½DIÐÞÞÏd §Q ƒæÀ~¥˜ùr'ûÍ3tnÿÄüGÇ*óEÜjñìõ62›,Ë X¾³ý(êE•(„rÆÜ`-îÐñKøpà`íp-ÛàzN:ŒFjY¢(èÒ.Õ²°Vãj¨¥E¡@¥æ«Ñe @ØNã+²d+­9¡`h4DêCí¡þÐpˆ…•ðX Ú§–™^s³î\¯l†îìÔQ‹‘G÷= ž.OÆsÊ#{ÖõÔâÚÊ,yF©Fá0A¤(ÿ{ì^Tš%/“èjUA*7¦'¯$Óã lÞr1k¶$Sõ)¸É«këK汘eðcÑ žÑXZI,xK,„Y5mj´Ñ­™^]M«œûꪸ _þÉÝ}ËvíImï3?ûçùŸßÕjÜ_µíâ9\}|ëÒîmæ~žU V÷­Ùr¤.ÙðñGè7flh™½È%ݨ©ïŽ-^o9óo&?äWùŸÑWЀQ×FmxŒ&—––†EX ûñö‚…¾%þN²š®võ 7´O{ÁúRÅ?G^rÖP5ZVi€Ö£2xt(´ŸÂ¤¯Ç8.}» d KQz¦øL‰x½yꊼY…H©´É*Æ€¬²Ru•¨åFVáSP!ÀÈK¦Bi½¥ *$/¿Ö˜'i,7¶LO¦ÒW’ÞFÒm}Æá…ûˆ vW]y7G½y\:’ïý´nÍÓ¯ª;º{Ó¡u§8ôƒ¹[6.‰ô¾Ê³\ÌÞ¸çÄ£ãæ3Ý+C%ÿ¾wörì9þÂʽ+A7@ }l„"C3rFcQaƒ&SpP j͈qE0&D^‰[ùÈJ½Ò®ô+ÃpN”åËNgûý1Í®:9Kæ# Œ<:K²n52ÿ¨¡vZV¡Q2ß(Šƒ†D[‹–—»™¥ž¸»z.G½î/ªw%™L?86‘›ÝQŒõ·””oV ˆiµ {­Äl^ÓOÛÈÕ¦œXKWExö²yä²™¾l©uzAŽe N°„òWÁÎÄZ••¼† 9'ùA2ÿ؈„û% É/°ÓõíuÒ&””5װƆ`é¼[¾ªm<ð‡nÇ劓qjìæhbeûådo¥ÇMŒDr3–7›r÷í°²C6ç~}£—d¯™ó`/׉Ã"—£º Œ§¡i4È‚<Š¢t3xý*‹óͬ‡õðôàŒÚÆ‘âÞž…˜ÎºX†g£LbåqËÄò,š÷èÿó]%°Q\gøýïÍÌ›ÙÝ{í]ïØxwmc¯°ñ^Bê!±Ml všRlšmBÂjÖ­h s&£¦j”±¥´ jiËaŠ×á¦âVÀJU©JX”r$2XÅP¥àuÿ·K¹RuìyïÍ›‘fö?¾C¿DåQ”D+ ÂC8õ±%„ÂÓó¢Çèrß'ná÷?Gçøý:}!»?`gö^ºn¿M¡ø•ë¬Y²IN‡Ð•T ¼wl¥«¯’êÕ4B•$Ud°=Š7ŒuŸH`iÅhEEé.K+*&•eZŠÆ5µŽÔ±zÛ÷ÕÊ&ò&lT†5]ø¨'sqM/ %z#¯×;øV~D×|š©ûù¤H+ÑNÎìL¿L¾P¯êÃNEÁ&rQUÖ¸¢2?JΪÇmÇì'tù}ÛÏõrH= ԕͶ·õ ®º]SVi«õNåÞ©nÑ”Eú|çJÒ¡tðUªÒ ÎÐ[´½My…+a­ZoR¾É%¾¬r$:¦MGxαëÏ:–z£Ï”Ó’ ÷£Ü:L7|®G¢©íqz½¦MÄ0ôâ0í@(¦.;Üs—:íпÀÞ&výö& | ˆ‡}–§…Þ`.è ¯:a $8Œ·‘¨µÎ*픎Hc+“,©Yj“:°vÉçxîpHºŽC1;’ZèNjÄ!‚ÿÅų…c™5tI´a{üv$qD£í£³ë^ª½„\qòάÌQ‰ý»^ê'ÉþRL¡ h‰õKà&Ú9B±ê4Í„tê•M®¦–Ðt îà×ù0ç(va!„ÐÍ` J³},d+è«üuº™¿O¶Ã{t›¼ƒï"¿’vó]ê.ícã1µO;NNÀqv\:%SÎ×ʿÈmz—篵ƒFH¨iª‚®R’Ó$DÙ„îD T™¢×¢ª KéÅÜÕ\Ö3 •`M«ê„³ÉD–bF™XS‚þB"Ÿ½°¬ÇBi’h4w¿4 Ñd2™4Í^)Á8£eÁ-·§ecèq«™ìèáÈ”Úø‚JjáÀojÙA¼Â¯º-ÍH­¤óqHÞÓx¼Zk¥Úí•t.Ф1F‡9%‘hñýC@ëÌ=¾çð|v^â]göÒòêêVÜ»_Ûˆ»ïíöí¥õÉÝrÜ-t¢Ò.[ì [^{˜f¤…ÁH Ë8ËÞt²Ư<µ7ãâH`9‰±ÄD¹ƒÒÕø•øÏį`©™ðΧÁÎÝ-û §#þÉ`}¹ˆIöZ4ê‘Cî¹®V÷\³-ëœûBÖ5·­ÊÈ¢a |È$Ä+¦B:].ð™ÊýÈ‘Œô0^Í|K|]i–•5?‹e™Æ "M" - šÑÉMË„D–<¢<Ø”ÿ­9#Øaø3ƒåÂ×:Ñ®äæN¹gmѪÀ:!¹è·»b¯|gÍÖWgüéå‘ÝÏ—ÎùÙ_å¾™¿ýqÛg¯MO±Ýœ¶±©ªÖq˜‡q¸Žqð û|ÀPC$ÏÈ£y·wm)›½dæô Áw_ü`IläŸ'‹—·<]SXÔ°¬vÁÎOâCEîoc§îÆNå`Zß[®‹¹$§ìTÎñ«T9G¤™íç'é Î>¤òʺ¤.ù#¶зø6Ê~D6’MÀ,e!Ylº¤ƒPê®Y˜Öñ¡Ð5L|¤ëXKIHU Su›b£åSác…ÀÒ± u D4u”AW¨%Ýä%¢i+FpöÜÙ¨“6'¹÷µã‹âçý?ÿÿïoŠbðf˜ˆ†Šà5Ôd¨.^EŒˆ&JDiy÷ÒÁn”"\6—=ÂQa\ „^rÒˆ0%ýÚ F*5C[ -Õh­6À  *A Ø“7LÓª­-à~`r[Ö"2¥¿¿`]ÙNé‹Í`õ6Ê<ò‹ebQйšB®™æŠR6BOÐcS«§ÕLøü­ÉôOÖ?·u~É~\þöÔîÜЕq”ai(ÛØ­Ÿ¶$³hï9*:öñƒÜèþûç'Wê;Mm­¥¡²6tÁH¤¸4z?M·pËÑÀ®7™³œ]át®‘ûÓÈf+fè"†¡1!Цé^²1L>KA@/²Â´0{Jg¶›­ÊüŽüÑ`ëéw*¨ÊP~f8ZdÚCÓæuØ©_C,ÚL…@G>rG›½YkãÍZ‘jÓÿÇ%¤mÍÐöÀ Ñ<µRSrïåîáò3¤—¤¢¿ðø9øÄõð‰Ý¸Íèö ›¨È³‚¬ú=ôJ‚_å±®M'ÕT5]Ã$+éeÊÔáèÖ¸»énæ5ù9$tö’£ž÷Ñ€}Àq^¸PtÁí/% Ig‹‡v!‘R$$Ò2OËØh†¦%"ÓE²L ¢Ù±t¬ MYQ p€&±¦=Ÿ9A ; —Šý"…DCl‡EZôïö]öABRø$åNÃ] Ó^ ³Æn܃mØ\o±0)Œf-4ÉäMýkø4+Ùùc«’°ÈðÈWÓw7ø_H¿tÑ.]òUó¦ãó°q0Gò¦‹ÀjegsÚjbÔ 6›±¨Ï1~õ¸’„¸jØ•¤»DI¢’éåƒÆô[SÁ°OŠÛX<;·tæÞÀ3·±ß±±šîàŽßÃ+s‡¸8ßK>%ä²rŸÝ¹£3ccþÖóÄÌÓ@@όߡë蚀¦à·çÖ•lö¿x%Ø]¨4eÓQ‚r¨ûësâ]þ-ñÓþ?ú¯û¯Ç¿œäÐ|¸"q…ªª¼™+û¢â‹J.曡¦Õ•ê _‡ï4:å¿Fþâ½âòÿ#þÏé)ž Ra‰ubáX/Ö °P±-8¼d‚QI¶Så®r2RŽË¡J'ª|)k-)ʯTk5‚a9U/r€‘áR†ZÐóh€þ{©˜19jÀ½QnŒpWÔ€;ä(Y—Ò,[ c%¬‡I¸—Ô~a‘3à ¤Mîä—Y—+åq™ßJö„m“Í …w{Këf’0d2†ß}muøNn¨røü¥g¢Ô›ûÌI§~Ó´éð»Ÿ_ªWæÌKcì/»úXÅ왳V'5rÏ»uϾµ•«>}¦>>÷H×ÏOºœÞÚØ#¦r}¬Í_ûFU}êû+A?  ŸAp'œÁ‡FfŽ‚'¡˜£Xˆ*Q5êÒ‹bžYêj?ÂÂ`×Ñor„RœŠì$Š[¢‚6J!ªê$DÇÚŒ‚¥6Ö—NdÇHñÅx£´²º‡¿Ì“·ðÛøqžB¼ÂëüOó½xîou8SÒKôãεp>»N5ÂamÕ‘§Ÿ>6/»íBgÚËŽYøz˜£Ø›¬p&“¾;9xIÈÓôel°PqbV:κòuµJÍÚ`ÈÒ—7nY¸ÿBË·Z'¾¸~Ñì——ü¨iÕüVæLN«M|òáë¹áCMï÷àc­›WÜZ“ùé³[à¿ì€êm‚î  “Æô@— i’¦ZI+ÕA:¨ L[¨+ЃƒÔaÿÀqü9å<r•Ù§“Ù„Â>$©2`F±áðÅiGDÆg-8-6RjÜÁ¢¸Úó˜Èðfã xÚh™ÜY09¹IФK”äi1s’ÐYÈ:övpòb¯Y³Æ&AÆí¦†o5·Ã%_#Ë´p;fl´%=5õ)ð`AvLõ¹»Çÿô¯í¸øHßM)7lOÏnÚ>ï™úúx{ù™sw?8‚« ì ¥Ÿ|á«Uß]ö,82Z”Ÿ¶fÓ ú³±kb ‘ú¦ÐXÔàm® ²3í3¼3O¹„7†ßBµ? ;hHú }NݳK¥ö÷Zµ-L»)èl‘`,‰~q1Ä#RF²¬K¸H‚¶»âŒÃE’d(Z„·c¬ã6¼ÑD³£˜°†0\ £ƒÃJ qf„p4w;„=“/åU•U“ÍPŠlÙÿ*Ê ýPO’R;`…*Ø|4:­Ð­(Qåÿ/):žñÎßÕ²ïÖ³WZWãÈØ´ÕOÎï\øÂÂ÷®ž;ë“Æñ¯’‰÷¿lߨúÑVoÍ AÅÖ‚ŠÚ@E¤ã«Æë]jw„x"X}•ï7IYžvq ¯Ù© ç·G^§Ï튨zšãº•ÎÈ»üIé"ÿ;Ç:X»ª`…(¶JX‰ÔEêuûbq™¸]§®‹lawè¿æ÷‰}ìYî2÷WnÐ~Íñ;Ìý›½ÇÝ-ºheÎ.•,‰,ìµS:ç=«ãm:Ö{É0D1V ˜dYfŒmj(îbù‹œiêKªÍÕpûÂÕ 8ÜÈá|¹¡à ðä·Œ„j‹ îþbÈûš—„¼Ø[P©é¥m,Öc/ߌå]{D¦åÛчÎdÍk{fÔÔ¯•®¶|ª˜¢Ü“_!$l…t1×ãe–ך®Êš~ì ™‘2à®Ð˜®Ø&Î;þ=ï»—ïÎvRÛqHl‚óÄqâ*-†¬IXFI³B`*µThTM¤ÑB·5J6ZhÔSW¤fª •%¤# 餦[¨­[#6šhMTÊ«C0 A $Ùÿìd ë|¾‹/wþ~ÿßËö•9¶¯Ì‰ÿÿËN›)‘òÉ åx† @BAÑ“·¶¦¿íRcI÷Wcrj—Ê©#%ud$Ž)½O¹>ü›`ŠV¥ÜdgÖ ­H¡ÁlýäB¼½þuXáš;¿˜º±ý.þË…©Ûx˺uû|¸×©lÙùVÑ»ïbó˱£þ3úÌz·ºmÛž] CÏ"Dûù?oŠ¿/™_`ãb_ÒQÆÑʆЦ#œ%h‚ ð>Á:ÅI¥ ÖŽáß鈽 ìÐ_Ó›2Xè¨R’^IX.É奒o¦[t©Âz$̳ì?€˜nü„O»±Û^Gwž½„z¥^™3¦8-ä¡4À”48ÀRÒ¾%< Æ–‡„=->¸ ê (Sf! wXCÖ8 /LLú ÷’˜çž uL|&õ’¹ˆƒ2ú–²'‰0l²Fì} ‚ó‹>æé%'É)”b6Åç­ÉóðÖrŒ†¢rÛÇ“7R ¨%°‰òrä]:YˆÇj:C?¬é|è±­=îÌGeÉ<Ýp¯¦‰tç”.¶Í\Å#’&"Îÿk×ÔDWëüVO¦onóÖÝo”mŽ/ò‚]²ÜÓw? ŸÞº'¯Yø·œì´Õ5¶VƧcw€ù!´×Ä_ Dq³gW„DsuÔÌ}´åzò.B‹1󙹘TyþëQº7Ò=¶ =Âj£Ïç?ÝÕœÏ\På¯Ìªž¿ÖËóŠò”¹Ë|±"v¯®i>Ì‘îÕÃ^êÓ2üþ€æKƒ“~­ÀÈðI ÓEAž¡Z(„ìE½tâ)jq-ðã…AS+É÷iVÆG€†ùÈ÷ãÿ2¤E´šZ@ëÓ(ÕÜð¡VkÕ>Ö®kBëÁ§âþ(Ð{î<ä´œçu's~]¢y´õµ…Éf˜äúÍ«Ö¤Ý Ï[ç“§úTâ²u°ŠÍÄ”8Çî׿6ø 5x8TYàš¨JSjí²€§4H”áݯ۴*p$«âÁ—dX>õí÷üòfÓ–ÎEùØÑ~¸vÇáMðê­u5ûjvÔ®|¹0P6A$8/óá¼]Å?;÷ÏpYësOýéî«gº²"ð›ÝÄ»ý¥ÆÓO6ìÝñÒ“ÀÏ5±^ðÄ \ dbÇÊQ×9eX¶Fœÿv‰4†·N¯î5C8¤‡ÌyQ\F¢rTšÑŒJ¹R¯gõz}Æv}‡ùŠÚ†Û•6½Í<â<âjË8¡vëÝf%ðTŽAç kèÃŽ³Ö˜ó¬ëŠuÅa –iNMw¨^ŠT‡#`8ÁNóÈo„”V(„ÃöXÕil9êZ 0>7®Ô4"ÆRcÚ`ãç1zHq\Gu«@¼÷û (fv`ƒòÖ6 í°–$ŸÝ¸î¹«]¸fØlô÷Šýý ,·¡D º vm7›Öà…:5ãìg7µo|ù@æÎ©‰WҗǪ—¯ û xïäÍT¼õB|Ïä›dûæ9%ñâåKúm¶ÕÁÛû€µe'¾7 TÓ¥U‚ *=€½PC‰I dîe^Þ.:”–bXºJ®ÒKÌ‘ÃrxD‰JQ±†×KMÊé€8$—¨ÀƒTK;I'í#}tˆ Ñkä• È=¦PXá¤n-IÒì3-´•vRJmïòø–Њ ðÀUB…Lgçá.©2â¯ã¦€ÒÒ"ð*xúý²ðô“Çg‚LC䕃—u³¨á¾ “$ʬҕÏÄblV¨*A°áÝ8;:5‘…³ÿ55™÷nË1“»æ ¬™†oÆ?‘9—¼ŒêÔT3•l•¹ªñ ZÍVÈ[Ù>Ö¬‰*Z¥<%=OߤoK‡éè)z†Ž)cêWô¢r[¹­ZUE­ t'=«œUåtzP!!”'åˆ9âˆJ‹Ä"¹RªËäzºF}š?-mÏÈ{¤&ÇúŽxGnCí¸]jSÿH{D‚ˆyá2JGÙ0?#ŠQù mÈq _¤_K—Åeù¿%}'ßTn©KXÙ_g¯­¢*²ÊU•Sʈ¦*€ “‰¦AOLƒŸM%¬”«iœÃU “$—jB–5¤r&AÛŠ#×e ü€ÒCªã®lŽ_çÓœ nñþ1g*g÷*Ç—´6ŒªV—,8:òôâ“ø{3ŽgC²qnh¸zI  vÆœDc6žv±½÷ÞØ#[ …\.—7ËV¿ eȺz\"¯=¡´ ŒÕôx—\qd]Š^€~*ÑÐéñ¸K‡Ñ°b 6Ù2aoưZP²ªn°Ëbw ºÒ&]+Þü[ýÕÔÄ®¶q¼yê“ëñ7L}bOL-°ì·I–½w#à-¼•ñq~‹NŽ“nòPEI„×Ó&X¡À :‚‡é%|‹jf0€Å¥HÆ­ëDãÀ„“ËÆR½pvðg²ûì¸Û?5Úâêbœ5õwÞ{»®\ô_ðÚ""⮨¨U>*#Ù!§Éæ ÛÉmy‰½‹O/-© o “\ù÷ú±ô#Ásúˆ9œ&"aûl_x<ÌCfÈò‡æää•¢˜‰v•ú£hUf•«Ê_•µF«7ëýÍäíW¦ðÔ®6»Ž¤ö ´u„Oh:ºÍnwVgx ê k0ýÓÌOç …‰"¸Ÿ5êKÎ œ ^B­Ëé3¿ \^,ü}«/Ûƒ?ÿßUÛÄyÆß÷îõÝÙwö½çØç»Ø—Äö%¾ÄA4MKɵ*„Òx#)BͤÒ’ª #Y? ­ m L0:º‰@ Uå¨a…BÔj+ˆj4ZVPYD¤±­ÃÞsç4cÕ4¼ïùì“íçù=¿jfC5f¶2Æ™RQPQB|9cV²iì§ÔPB!8ÅŒxI(/Áé´a¡4—*J,O[¾HÚç+O#.¤”Ä‘E©ík­Qò sIÁÊ0óž-ÆZkâù8s)Žãg˜÷ÍY8”vXi±šmá5n±öZŒµ»J‰Ä#–KM®zäD\Oc{Zš&çÒIâðø–0¸ØÌH½«óÓ2á,ÂÈ=öܲ\,ËùC´14ìnþÂV<œŸ‚- ÛÛ´ÑÐhÚ3–œwMÁÿ™™cŽs_a¢oÝüb°áâ†ÞݱþÜx¿^W·~ÙCÖS¹ñ‘Æ95ë–D¥hWnœ¤~¼]{ö™þ ;ïnb^}VÝ×ý‹¹æÅ ¥éúû×.Môæ´iWp©ãõöI`#™ΈfVgðQú,FÉ tCþ’²ÒQuT»JÉIé´ÿ?*’Ãá!á”ï¤Hê# ¸Ã¾Ã~’Œ4øüõ!’D _ÊÏ^ö}*^ °oÉøwüï‘»…ß*o¡ì_³¿ÍÇ2Mÿ$É^Ÿ(„±&JrN`M3tÒu$J’¦û‚iYB:[%gXbÍu{%|KÊKŒ!]’Yª‘š$Öz%Fr‚ÖÚ¢c}w±Ñ]`,½×!@>›ñM4ü?à,sgìÞ´ésÜ‚ Áí¶<œ¿ ›¯Ð{@ÂÔñé¾ÏtýÛ Ÿîq-¦±®ãk_ÚWú£ÜøöØÃ4í¯2*V:-}­}ÉÀ¶ûy÷MfåÎ↦§Û潟{ <Ŷüurz(¡btÔ®]¤Åîè_“óú‡ÅL%c ASo.Ò³±.²Yï×§b"ur(u"(5YÐñB¢uv{6œŒ˜^ÑŸàìôìZÎn®ãìùuƒÜ%Žéäöpƒ\ž#ˆ£œÁe¹)Îà CnPÁQÆB ï>´ù—h%TjÜ1I» „??‰š&-ËyºÙÓ]DQ醵,•¬"jý6¼Ë7±;•»9p£‡³iuÇÞì¶Õ?Ìö€d™¸3w÷j.—ëßü^Òµõ¹««zv<µ1ù¿çÖ“ËP ŠJÐû'Ký ƒ Ôù±® §˜1kt7¯£òútX>%ŸþFéu™î’wQ&áK¨Œ>J.êRÆ £dÌDq $X– ŠBÔù«\À2%Q¦²–.sj¶GÈ L§àœý ‚!d…‚G€J6 Üg`ÃuUrÁU9ÁsŒb KÚÙSŸ5ŒŽ/׬ÇÆêYêPW‡SÂn«g²€ÑÿØX¬7<§ê³»Èo0FyH&@ëÞ´ÁAi¤íõ¶7Ï|ôÉ3Ï›½¶¥µùå¶žöÖ‹Iê ç}1‘ÿàÈoï^aWl{õû·º6õ>ÿgG]ïàMFãvG’Iúj½£ìUé¯×ÊpRDJ¢”¿Fið/áÛÄNe¿‘ۉϡQÿ¨ü©ÿº?ègUæ¿/@¾Çð ȇ?€9ÆK? …ddŸwµ½®. ™rn|¨.ËaÊa€ ¾ÆV ¯áûx†ß=jp5át‹ŒåÝTŽ¼Ë¼ƒÕi31I;þÑÑ3á‚qfÜ¿)d£[G§Š.µƒCqB€ËϾÀÂPDKÖÀà¼ægͪſXž^à æÅë³n6ž9Ÿ;Õ©†i|ªS…‡ÞAå`n¼[5–äpþ«!oc9lö.±‘fŒÌìŒÉf<¾€PY/6K›Ê¯úÿ¼áørOR-/J&’ |óËy¨MñX†52µeõÉùeÍI;ÓV–…³jk¤-±,ÕY•Íl²vXûo…Z«Že·ϫg­‘ª¯‹£À«`/Ò²òD2å¥Á‘Y–µYZ§¶rÆ0›°ƒÁX:fË|ŸÅ³1[’tZÔ­‰4EZ",窷…ʉM§¦X‡LjælÓ6=æî̬G)NÔ Ü‰6 &‹Ñ%t hH™-µÀèÐ1Ê€ôa|èDõ#˵‚6;(Ÿ¤“pl9 ¿ër))°qØ©:RØœœ}¨<6ÊáSèfÁiž$8„Ôñ„{µŠ9³á˜Ãs1{æø¾Fwd"u#0£=î[EIÕ%ŸºZ3e&ÌT]mC})ȳ'e:‡"ªs‡`¤RÕXM>Û¹öÁʰúdî_óž\ýf>ú8–ûg¸Æ^±¢¥Bïÿ¸y]îúwpeUû¢ª+Qåsß¾}eï@_æ¸9׬(¦=øÝç÷ýé`gþ:kx@/Øka÷°×XxàÁ?~.^%ìVò yYxE'Ë|=aýìì9ör… \Û˾Ʋ ÃF†ç¼œ¦2ªGá°×ªrCøœ~©Oqʵèçx‚ŒsäD•kÊŒp#ôüGBN ï+#x”C¯½‡µCú1|†çú”¾èÏÈ€0à=H¸vm³w‹ÖÇõñ}”+Óç“fo;Ûî}"Ì• )¯AJu8¥qÀ ¬A O)W ¿D‰¦ª¬ÎªˆˆˆxaæYÃ{$à (´ˆuÒK%!"aECeCðy^F8•19ÌKNvÌ"Q¹pÌÓlû¹ <äÑ&ð­N¥“A“Œif:DÆ:ÑšáÒïÜ‹NïÝÇ9w÷Þ½»ßïû=0ê„‹ Ч±‘Í&ÄM1²ÂVøÐÌßdÃ’¥Îì¬K›^~eVŲû¦Õ²šÁSWâíƒñ—v†²¦‰ÁÀ¶ s?‚Óx?íÈ.xþï o5‚±ùæ¥æR縦…­¤†ë’47ä¹ÑŒr·1£#c Ã"` Œ€L£n0-}ZÊ´PIzyúJÿŠÐzßzÿºP3ÝæßÚê×®¯DnÑ»©·ÓG3;ÂvرŒk,“Âþ€údü)ñãÊÇÿCÜñQoa¥+`#kÛÀyÔ%þ ‚ ê!ÛÓ'Iwr^À&n0ÔÜbß´i¦]fWÙ OÚ-ö›Ù=ð¹—ŧÚÝ·Óís\-êæ»Ô5íˆq'[5«‹—b—ÎÁAÒº%ÛŒ`QTžônX)m¼)^/Á—*VB%#1PQ(' ˆ¢ø/“…Y@‹‹Š1ffOfCf«»h^NŲ“é› ó«ø£:o¶~0…çŒýº)cöÂïÍeÁì ðô»/ÛO~ð«âãJ!¢«~ˆU’ ωleÇHÏøU¯ÖŽ-GéòýD¬´'É!Ù0C+€%ä%XEVÀ:øì4Záä0¥`̓ÖÙî;I:}׬«rÀ7™øÂ°ì”É!8ENÃ5ø,Âí^:˜†Ð-®é:#–LZè¬u–ÕCŸxv¦,“õ’K 2(£’IÕáj_ƒ¯ÑÇ|ty&kgô¦>—ÕzƒÞˆ¿„w n’Ú /¢¦)S‚‹‹¶.AÜdâ¹Ã„ y3á‘Kû±U‚# ;¢šÍoV6š]uŠ!‹þìñ ¤WfêÆ/ý`@ωϽ´ ôôáóÛOˆ~Ÿ_ z½~$4jÙ±4 cK3¸MRæ?_ ¸£ß1î˜Ãÿ+ÿ›ö©~ͺ’r‡ÞÑÄIÙáï$gàœ¸h—âm¾G!G´#úAyB›ÄF«…¿!v-þ6&*åQcT›+¬×éF&æ‘">W‹Y%²Ì¿˜ˆ<2‡ÏÔg‰éÆÔ”¨_ä"4B‹õE¢Bzþ·ekÊg–„Ô¤N¬TH“‚j\Xª2@[̸e†Ž)=³a2AÉEš‹w›BŸtï’0„hé¡Q/b‘å›Q€‡€Á»X‡ëÍÍ&5?¡åhö9#‚hôOžU¯oÖ[ô:Çê¯õ2ˆò@Q‘/<шœ8„yâ6¡QZFí¡ÿ=ã«QD÷¨nL•OÉíHÝHb„Uĉꎒ¨¤z'c¥øqR^Ïk|èŒ)=ãCçpO£¸QªY«ŠÜôœøš9'!àø ÏŠÄ ×Ž‰ @‰ü“•Űç Â… ?X¿ÿv÷xT‚6–@”[‹VB¯ª{jü3ì©ûª§h‘÷…½Ÿ›/Hƒ,¬‡EÔ§0lXLÓ¤Ì÷y¾µd5Ô¯š«¤UÊÊY¹¾žüœí#GÉ!¶_7¿ÏfñYZŽ˜j̲¢¾"ZÄŠŒ"3ßWI–@9]Æ*y¥¶T/ËÌZ²†Õš¯“ðkàëôŸÊm|‡ù†Õ,ß"­°× ’^@=H™>ÄÖáG#uÁ1C]P êÔT5v j‹^IÁR£t¯Ú¾Ù¯htbÒ¿7ØŸÄHñ‚‘„Q7q@òÌ€š}þ1î“ÖKÑ.f¥‹MÊ¥…$â‚áÊ=µÇðôn#Q³zÆG»C1f„bbîã"Ñ&¹ô!Î üeuÜ ªã}žˆI7€ó@i/¼nbV  Àá–Î?‰wÀ¿ãaîaðA]< )ñ›0=~ Ÿ˜ÿ;Ìû"ŠË}ñþqçÀWÞÙ6I}ÙØm ¥ŽZ¦ã¥Ò…¿Õé%¿Gï±{ü¾äW´Ëúm:ȹ֭uéWèev™kf§D=ËÎrm?{Ÿÿ^Ï8Fµ]löNx·³ŸjÛévÖ¬í ï¥Z­Qb³ÉÜìh‹yex­a¯ m+1bæËtÓÐ\ñsåeæÞp;g:R eœƒÙ Ø>sxÞì(Æéz/WpG<Œaj qB„†(;×x˜;icÂRýØsãÅ]’LRLÒ`­̛ÉÉò! [ù×ùŽçìrÚÄÍ€3ä ¤¨ÓàôáTw.ÐoÈ$úéG™@ÙØs¶A»5œPl¥×ZÒYáÞáOX¬²‘&ÅG?€‘grÒßÿŒ…t ÒW¨*~Æô&€å{FDˆ­ÿ3au[š<¤"lquÛ1-/3q؈9ÁgPAZ 'Ä åü4{Jn±2j§á…òɬäµ8ä5ÖÔµ®]³%­pnÛJ¤¦7–ë‚ÛßmyoëÂè­€â(29*±bB¸KW‘ð:^-°Ei£Þ(øû®h:Ï*¨bU¼JTUf=­Õr]/d£ü-yÞ¡ûÄq‚ž½¤—ö²NÑkÞ ×Y¿Þ'®›ú€ø†dã =õLª3êá%(vNW$Fs¹ê¡s‘˜ž‹:#Tg¤âa‘‡œkB.±Ì™F™A‹t1ÑþÇ~¹…4Çqü{.nÇÛZe²^–­ãÔ9Gsc›NÛ¼”—î M-L±é)¢×Š è)H’ ðMñ! | _{(‰^»@®Óï\ -¬|ûÿŸÿÿÇÿ÷¿œÿ÷Çáÿ?àI@‹WÏ©|“'«(Wœ¿)Üxº4OÃÜa!á(FêmÑž3Ym“Ö呸ò¢zœ,$¬ŸuWK©?#ËþÀ¢¬Õt÷Zýà)?:÷ë‹Í\±¹ÄÉG¿;ª„`ifšSÜsüõ73>@·Ádf-ÜU:{«ÿñÝFh*s! ѽ6Û äéäÖy%:ùK€e ØžvNéÌè¶³€ýP´ì^ÒÙ3ûgö}ŠiÍ’V ”öâx ”_œ§ƒ @…M§’â•o÷àij£@Ý#ïsÀÇe€ÿ%p(hÚ „îá9 *2 ƒÁ`0 c«Nûï-€ zýWr&lάêø]kÛÊûË8!W ²ªÚ ê¼õ >4®ÆÃ‘hsK¬µí0í]GÐÝÓÛwìø‰“§6¹ø™ˆ+TÚho$¸Pƒ(bH =èC 1®(ÔÃ7‚hAEº(’ÄyŒ*Šòn½ÇÐz}åãoßI 1ƒ;•œñ¦vztßD^šI1›ZlôVºÏÂ~èLjá‹äO¾‰üW¡`(Ü‘ƒ£©dÚNÄÆ’éTüèæ‘0!„ÑŽdòGI¶$Ò$Ó9 áyIjÛ¨—‹Z‡© ÙÇ´–m!ŽçýŸ#tu…'TЋ,RЊ*t“ܯ󼤯 ÏÝ¢ˆ$BÔÒ°ZcßAÃÚ¯i ¡‰—Ôiæ%Nälòï‡Þ¹÷åÌ6ÿ'É.i½':ŸyÕzúÅäío7V2ÙAIí©æW›ù‡s3` endstream endobj 327 0 obj << /Type /FontDescriptor /Ascent 891 /CapHeight 0 /Descent -216 /Flags 98 /FontBBox [ -498 -307 1120 1023 ] /FontName /BABDPG+TimesNewRomanPS-ItalicMT /ItalicAngle -15 /StemV 0 /FontFile2 328 0 R >> endobj 328 0 obj << /Filter /FlateDecode /Length 26556 /Length1 41040 >> stream H‰\V T•Uþö>ÿ/"†‚ϸxy(‚$ñ‰(\!‰Ä× Ì.ÈC…B—æŒ/|eŠïÌšÒDãâ[«‘ñ1šæ2sTt\¦3£i¦©eºî™ÍmÖ¬š»×YkŸsöùÏ·÷þö> %* 6rLÏ謔ô*`Ó Y})»ÐYTüõ”ÉÀ†€6dÏ,±éÄVËÞÀZš[”WHã?[xÌÓySËr× 9}ÿÈ9šŸãœt¬ÍJ/àývr¦o¾,´(·¾ø†È<$¿°¤´õêÌ2O–áš:=ÛI¯f­–TÈ|w¡³´ÈëR‹4Á³UìmÓœ…9É•ÛK€÷Ͼ¢é¯—èŸe¿nÞ/z-§¨¬CÒ ÓÀûˆ¹TP½ˆ T1ƒ¾.ãVópÐæØÝùúŸ*NN¯úïøõŠ­XJ>(ÇÛp ÆILAF¡ƒpŸ." †X½nˆGȉá+³¥Ô'eç}›o‚±sð3pÙø,XG}‚~ø ƒuüÍzôÅ<¬Òÿ€ÕˆÁG¨×W´Éøõ4ˆÆ¨ 3/cfc1Rõ£Ù ¥øuì÷Ì´@*^ÂX¤#» ’;M¤¡†Î«¹)•ô<Õéí° ª0Da(õåîú žCb0Cð'¬Ä\¤4Xõ6 P|râùRu¡Cz‚DR1A.F¶áNQåž*ÓüÄ} ¾˜.ËQ‰óx@Þô2•ò~µÃ=Dè]ú¨œŽ•{1Bp—cµx·{Q‡¿JLê©3¥Ñjºg”˜ÑMsÜgÝ×t€~€V‚uò1 oa¡äæ=ÆeüOÈ /jM‡¹_V¾Æ{f †žßÌôÄP‰V)æcÈ9qŒlÔ•úP ]`_nÅSùM®æÔBU«þe|§ôV}Db~VØEÂ0Z²Z.Y[&¹ÛŽO±ûqßã>~–HP%ÕÒzÌmxŸ7Ízó¾Þ¨á#ÑE$z‰ô‘&áÁ2 ë$S_â´ÔÌS<¥ŽÔŸÞ¤ù´ˆ–Ò*ª¢oéžÇgøªªRŸ(—:am˜•æ5Ë(«Ó]å^§SÄ;ùvŒð&Nb˜#\|]8±Aâ¸ûpH°=FƒÄÅ_¼ ¡4šJi6Í¡eô>]âd.àé\¤HuVv®AFµqÖ¸lÎ2+Ýaî Ýͼñ6 Üé"@®Ü2K¤RâPƒÏ%[Ç…µ·…ÍÐ ·±äÙ‡ÚR0…“Cdœd=&’“ò©œ>¤jºL÷ØÛq^Æ+ùCþ†¿SÅê]µ^íRç”ÛЦ-’bfˆ¿ÕæCË8ËBë0k–u‹×WMM'š®º[¸ÛºÃÝcÜt¦ÓõLý†Þ¬·èºF×y*U w; ¿l"áè!•“‚1QðOA±pr–ã‘-âÃ.ìÆQaÜY|ƒ«øVä&nIfïx|z„Fñ©Ù©·ð%–&PåRÍòÈÛ´†ÖÒzrÑ!ª£“tŽ.R=]ù…Ó~–ý¹'Çr"'ñHÍÙœÃEü¯áõü1ïãƒ|L²|/ò v«N’ ‡JV¯ª‰‘25GmVûÔßÕyU¯®«'CrlØPc€‘gÌ5®™]%N“Ìs“Èa‹¥ÀRcÙe9e¹eµX»Z“­iÖ­;­Z*¥+¤JóÆm¥nüŠ Tt„wÓ»tšwwÙ—2h–G‘ÂñTÜä…*”âT)u”:^‚XI }y#'!Äó©ÑRÅ}„‡cÍsF[Úð<Ê—~sFø“"6 p¡º­ñŽž‚=(•£×J-TP ÕI åq1o4*?aèuuIxsSj?†ª,§0» ÛcÐ_òyedãµjd:íaL5¥‡ÓCµÛ¸Šòný%?Hßo$ŒkÒ÷#Dwð©`;Éçx!í1,´™F †NÊKøq!¼9j\Á?õ¸Äýy¼Š¤‡Fo%¯¡äi.2èya;Uñ Æ*ªïoоüDš›Ô2Χtœ¸; S½àæë”%hBpÏ $/Ž•:²¯nò6•KëqÎ<¬®©j/ ú År£²q"¥ª~ú.B-OTK÷y€DÖz…áÓô£D§—ôQe8 {Îp ­P…fº~è.7çrrÍÛÖÁ(ãégä-ªAýÈ$îA²2@"h,ohàQèÌ÷éJi™TGˆx2V:G òh«Øšò6 ‘Wà)WK×LU3¤ÏìÅQaûléíþœ-ïL>Ë+axÞƒu†Æd”É¿‡4|!¯iµhÏ™Å?$nð ú÷‹}>¦Otï^={DEvèÖ5<,4ÄÞ%Øô\çN;´oжÿ³­ýZù¶láãýŒ—ÕbŠ ‘ûðL›+,Óe„Ù““£šçv§,8³é²ÉÒðßÛ¸l™3Ûï-ãÅ2÷ÿ,㵌ÿŸ%ùÙaPT¤Ía·¹N'Úmûiü¨tÑ—$Ú3l®»=Õ£/÷è-E–6G»üD›‹2m×ð™ù‹™‰ò¹Zï{BŽwT$j½}DõÍh/ª¥À8ò(èPËðj) \ì‰W{{b3— u8'¹ÒF¥;;gDEº(!Ûžå‚}˜«Uw <׸, .«çÛäfoPi«¬[´x¿ßh¯ ¨®+|Þ»ïín *ÖðgÉlDŠ”ªH´®?P•$F²PbDkÄÛm5´Æê¬ÿFSš1©I;tâÄÅT‚AÛ¢Õ”8cªÓŽvkQë¨)áö;wß[w1mLgÊðqî=çž{Ͻï»ç\¨ÌŸWî)/-ñEi¯Ñ#ëN ö]z¡ßí.&ÿÚDߪhk¢äô{ÂÍÝ@`•;¸{º/ښċŠ0|õä\ K¯åCì—Ž@8|ÞJxSs<9¬ñÏwïñLðÌ Ì÷ã{$‚4cIR]B‚·^þ™rÜ|Ÿ')8.ÑST:i@m/ ÌXòv¯»¬%mXm|ðiÖvën5âºF7æDlª¥†s+oFä85ŽÈ3,ºg»‰ÏƒdñŸ9Y˜…aø)Òà,Çgx"xÏD >›õì4“ã=îÀ Âg÷´ý=VSjiÉñ7ˆ›LŽ¿`·ÛÁÔÔàÐ¡Ì çD|HÄømÕ‘6ìÙ~Ù³0Þ ã£G}p+ÊNÇ™'%ñW]òR:Áªé¾pßMe‰uäMO- ê~¶4Ú–Þl©²-w¿ôÝKü_@ï +%òÛ=¾OÏœyÙA­Ï1Ï Ûófzò¦ûÜ9¿u¶yù1½°=+b³ZÁž}"Q·Zz¢PV0±$2˜;¾¸ ‘Œ_‡bryÈé•Fsçãý“˺$%Ý¥SH^e/%n»Ya³ScûÆôc‹ l¤èyùÅ@—[.ÒN ëqçüÒ¬*ó¸ã=z¼ñ‚…9~û‹†äþ5‰ÁܵEØÄ<-lÕiB­G[=½Ö«­žYì«ÇËvu¾¯N×ô‰þ Eµ÷Ãæ«wy•Vh¹çæåi`zîR¦Äz/Q•²J¡ú³C)ËÖi4;¤‡uñJ‡Ÿ4õ|À{I9ô˜«¢ÝlïpÝÄÿRÎè÷…xÓ1ZÀ-ÝF5½,J´ƒèE ÐQM£©L{Gë ÛZ½Z&¤ÝgÎ¥ä%èFÂ/G-ßÅø¥À2À L¼Àà'À'À#ÀƒðY Ü9^޲„¾ÉYB¥Æy¹8iRÀl–‡Ñ>7›i=ú¿ÅúbÜoÊcÆ"ÙਖÐn†})Æ€ä9Nb¾nÆ"Ú€þã¼FØÇ-èC‚_»H]õÑtF ”™ÂOYÉ+zµ6~Ñbëh¤Wݱöcè?ú»¡ï…ö4ÌïáqÀŒ™†¹‡bÞ6ØóY±Ã°â%°5‹LZ§gR›È”ß7ò©—µïWxß¼g{O*þpLwóòÜÞh„ã»Û±})Î"¦?B>d`/íz ½e¤Óƒ:ö9zцó4¾{µ¶ˆ3Ê©¿s Ü‚'›{iúŒY@1ü¯;å)q¼°¥:^¢ÍÐOÖ3À±T§ÿˆ.8’黨oÖ3™'8·Š åêÜtÈAÆ_åûhs?Ù9PëbÓN>ç:JƒÿH¬uq´‹´ðCÄVlâx°~:ÎÜï¾O+ì¨Á<=À½ßÀ¾–…!σÛ qƒ\DÏ[뜊’§˜{Ѱ¾36ÔÙWãEYMMÀMÄ’–Áï#Ètèœ.6a|&󼏿¦|‹¹¾ÿúQ»ÚøÍ ßm©>—~T/8ˆ^µðSŒQ÷…9ËqZs·1·˜3¶´¸qD¯Á;ž÷ɼ²¤º{çhˆŠ{gnE$îs_É‹¸Ó,·Òæ,Ï‘Í*Œáûˆo›‘V<|?‘7Î*y‘ -®±¥u‡#r|¶e޾´ËÈ÷C¸C¨¸†tgø$Må{ll¥—õ•ÔËy‰Òñ-§a®íä6†³U›ùqžMF m‡Üf´ê÷­šiÖÈ‹F›ÖhÖè˹}§ì {,KF´í«êÿèš5øŸ¢FþÍl•Òh¥ÍØ+9/i÷-¡¯ª€¡®Tm›«B 9 (¼¹T^Ê6½à\#3z«ü }ƒpþå¯Ð"­Që* ´G -¸£XKÿV0x~È……¹–mË;¸dI›¯äQÎùœwm©îòª%}1ýlú×ÎÏ\8G3Â|•¯Ex¹5ä£ÛüŒå©¼ÅÏ1gFg^FÉs,¹¶p~çÚ‚õgaý]˜ëuÞ¿ÊÈqœ#9ÏáÎ?lï,#þÕÚä‡}*·P±}¯¾çŸÀö•G‡i¯Ê‡•ô¸£ŠÄ(zXå£É4ËŠý”Ñ_°—u!Ù¤Î}ûÊ4> g¾Ü(nÊŒù½ûTÈzu8£è³Pµ™ß˜ÓQI[Õy°Ï úØå“æ¾ÇaäÒBä’ñÎ5òW†NßçF༧s€«ÈÂá0´á1š{¾þOjC»íïé âÇzâw ø@¶Šçå}“\.£â¸<© ÷tâx_~&> "í 5‰*:(¦àÝ´šÅQyA–çô{iª>FîµT!VÈñ MOa¾tDü\^ëå±½A‡ÄïäJ#‹Þ3îÅ\ç¨IûíÐÿA;Q<֯毢 ˜¿Â ð~ÑP±Ú¸3æ2=™â¬x‹câåXí8ííøÖ£–Yññ¾y^å‡1ÆdšJ$ÿ$‡eÇt|“bÎë*gå ÷¸‹§1°'}~ Ø‹ö&Œ½ \@û9 €öjà_ÀkÀSwÓŒ£ÿ#ž³òL%ƧB·€ßç§Ð„vÚ-@¢ö!ŸÆ¡} €¾Ý´Pt‡ÆI^+ÃÒ]ÁøÀ´_…œÖµ¿vWKî¶ËáêýÚé]ò_XîVvªCkÊW’9w%cjýý¿LZµ¥äiƒ½¨xþSÍ‹‘àOC48·r~ã¼Ê¹óé¿Y¯úØ&’+>³c{m'›ØN‚@‹X¸ÃöR¶Ÿ±½”ígö×ùó~¥ý,ìgPí¿®ëÚýl>Vu 0ÒÌÑl\¥ÎpG¢žHVYtdä6«4 ŸY$Ya­DÈ3æ²Ze™©ÔR£­½ØÈ7­Qï$ÝðŠù!ˆ@,2ƒ‹QùÆfõ£d 0¤F„À’’«dÄì åI?É#1Qd+Èa» ¸˜<ºò!HĆ|dÌ|ï4½N.àCø$ùzˉõRš³åìBNÈapV0.ÜÄ~³ú€jnæ÷×€Ë<‡˜á—ä$ö³úp'̨¦[Íò0-••E¬“‹¸<ÄÑ ÙÕÚç`Z »ÂÄÑIÝ*(ô·|‡Ò¥Î‘ר‰:œhŠêòn-hÁ8w?„òr³V ]v^'#0%£\—1[‹êa¾m»ÔR†›·©õ 7ö©e,E¯æÐ]ÊFÕ'wp’©j,ÆlÒ|ŒïR}³° i…õ*¹K Èkw©Y‰©¹I+…úVá±Þ ¯ÑJ;Z4õûòEùšüÙf—ÛÀ«¶«Õ«:Ú;H@öCÂ+r»l›##ìD²éZNÙÅÓ¯S¡„¶j0ª¿æ)ö v" ¤*'DaÐ1áê/ßu© ¿«»/Ñzµ>ÙΆ”3WiêÙ¤äÌ`²ýi:ÑÔ L[X¹«ŸÛ¢ªÊj-é.|@r>ý €À¿@H‡‚È|¢W 2léP},S³Æ»°(y~E³±îg7ÅÂDr¨Ózé ­^iUÕzEk‡ú º[â.¥¶N½¥0ɱ)0°f§ŽGÂA. á¶`»@&È r›Ø^ÖYB(i! ²… {yr­pnî è w@jy‘÷&` a´4dDx'ÀËZ ¶Š¹gðöÿÀÄ$¦pNNÈ¢×Ä1jÅ:0F., 'òûa‹ñyz²DxU£’p×q®kõš˜t6&ŒIÏǤlLÚ“>“VǤƘ”ôkQIB-Óø׿âz+׫õšôQHº’¾’^ I_IŸIƒ!©'$%%¼·# uqÝÊõ ¦ñâ•ò¾räºQ’È$Lm¢B•©Ä¨%TšJÀigi²ZpÀ+!¯dĶ„Q³ce»~ˆÂøYÀ˦ÒD-ü‹"Œ³œÉ*<†…†‚Xü)çý·Q”ãO–ðGføû!ƒ¤ ÿ¾1 Ðx‘—M¥Ü/˜Ñ—hÒ‹AMf~5pZ–ÃÄRXØ ž§s¸ÖEW”Wè"ÄË&ý‡f9±IÿÞ` ã&ý³baèý|çLz/ =½„¾½Gß‹ž¦¿S,_¥¿UnÑ[²eât”/+<É¥ >º—~W9Oß*æmà¤×a2Çõ ú i8|†4Ï…_¢{‹©ö„ù<3Ï{ýp=[4nܬ°ÄtcôK´W§ÝÑ[tCx/í `¿J×5Ü£ñ0¯ÕæáMA\ɪð8]§ÏÄç𯑈GA"z³˜¿*ˆQÛÅ6qX/Ö‰•NŸÓã,s–:ÝN§Óá´9áeÖYiîêðZ…Q¥ÃÃÀacÚÆÛiPì‘"`§/~FÉ™þ”d,±°Ýhd ×Ö]“¿™ÅãæQæ !ãAØÂîm; {8… _ev¤@6„7,Œv X¸À"NÕ¾îxfaýÔ™Z†ÙSg²Y´ìåD áÛà]×Ûó)jß’Ž<=‘ÿ<+ŒïdúŒ‹+²†Ê…ÙŒ±±?´{`F8&¼šî™Ž2ÈÌà^áXz;³ãÞžì,¨£@ƒE}´HË¡ £ÁêÎqÚÞ"B4ÐdŒ6†(§Q<Æh°Ìorœ¦{&)åÛa4Î9ã¶ÃEŽÌ9óÿƱ{Ð<çÌÛ=¼œŸS€m`”Éú L6Ôs÷¶§îpÑ}¬è>ÆÝ_yêÖŠî‹E÷EpGþOÇþÔÿb¤ö§pfëÀ¤¥²Ý»‹¸Ìsx_Þ©®µ×ðrò*‰d w8e”„S(‘D<¸e£Ôp€Maôõuãµ×l¦œÑKÁ,-¹Ö$×$™ –3s•¹|É8¾¾ŠŒ-¹<`öBXÇÍý°.¥¦}áž, ¤öÀo †à:2ÌPú3F×¶“Š’6ª÷õd#éÀÁž#ÿeü(c4AP‚‰bÚÐ!hh(Âã"‘ábr³æ'#E§¢ÈÐ;fy‡X–†)µ È—ó§îTD (m¾êF&}#gñÐ ¹Š†ŠYÙ?œ}ÁÁ ÏK%®xÁ!Z½Ùm ¹EÛFÕN‡}Þ<ñ¦¼ëíwá¾<è\ìÜìù¸³o±% íy*ÚZç­óÊ `3ABäæ#ÝŽ¢í&üÇ%üöC¨ ÅuwIYmY‘2²ðÉ«âñûk\6¦PuùÜÃ@r÷-nNïï™G‰¾ûØ».ÚŠ÷àŠ¶x[›¦.«ª"Á•¤Št¤¡É-u’0n<¾:o¤þåÊÈãw`ûúÆãMdÔþ&ò Îiщq…Ëë³ðH¾ý[8·»×CÍg§Ê»íÕÞÔŒàAÅÂ÷ïyï{ t‚—••ÊZO܇ýÑ!TUâ‘ú¯Å¿=Ïf†¿yíñNÏû—ßÅ©nÇáÓ¿8ö`Þ’ëo(¯ß=í‚ú^W…÷Sêëîòîò’]­ÁM\Wø>vWokõX=V’míJ–ä•%aËÈ Z d&PC›ÀñlJÛð(©ór¦†ºžÒJSÒ4ÐÐ)m^NS@±cOë6 “fÚNšvú#m‡@@ÃLkœ& ¹ge“dÒÙÕîÝ3Ú½ßýÎ9ß9—m` +¼Ë§¾ £˜ÒþFÎãõ¼àÐàlÏâf©¿-qd´º¡ƒÝíúÀ¨ž¯V_®þ­áÀ3on€8®V§1^@n”V­Èí¾^¨Ãß®ÃuŽÞ2ü"Z`ñ ½7fVm¢ŒÒZ_™uNÆ3µgcM:Ùæ9ƒ°,ᘠ5Ì'  ¼-eãQ§Ý˜19<Ê‚E­Ý#­Àý\üM²OCT‹h?Á£Ô1Â?Ó{PŸe¢‹Ÿ@é ,ËΑu‰ÊG <=0ï-™¾X‹È‚êÏ@L>ÍY ìv ›üÖۡŃ7s50²¤{V™Ÿonž?¿8_¿ÂO_õÙé·© اèUÚ€ O!J!„º ч[¨†Dk¬„¯³3ÿú4ùB~M)ƒ{ÆkÀ2¦¶ ·†L³?úû+½Dî«Ù(€.ª¢AīȲ‹ì çm,TZÞ‹½vÆh7wÌ-´@Ÿf@">…¶¶q~xqÒ·cŠŒqÞn¿…M O"‘ÚTS €X£ÁŠðY‡h‰¥Ø`ÇöQS-<‚ {qÐ\"qü,dSQò ?†•)m"#_[ ?Y¬K){øqÅáôvú£¬ÜÂ7_ÆüØÌU_¦†ú0æ·Ç ¾™[;\µ0h’%C,JWW_ ¶Ýk®Têî›…°tY ´),ælø‹ìƛǿ–ŒÆ Ñ(±8ëSý4z§Åí’ãÖȽÀU#p5\…а>dü®å˜ñQósÆ!ëcÉúºñuŸù:}Ÿ¹ê¹îe,ÖÐyàÈüô£ îP…õú éç¢NŽzƒ-£„¨VÓõû.7¬Ö Ä ’öªG4‡!BN;ņžÂ×k®êš(óSÀ_É*ÀÖÉ€3U¾†ø æ_=Å‘Å+ר&;µ0 4À0Hëž“AÖÂáväºMÄ'B3µÎ͵‘ßV4Â<Ùõàú‡{ä¶ñmûN6döWÏà•wmòÆ£xãþý÷òûÚ»fÙÎÃoUÿñ¹N]w—O_¦W€/Š  útÓo©_ç; Žû­Þ?ãgçÙ:cwÚ–ÆVâûðVvgdwf?ðí 4H·µ=<Út¤ù‰Ì³üPðDä™è¯3'ñ9ë9[‰¿¼šlŒú¬ˆ¡öÚM©ÿÐÉ*r¶ð²óvb/A³Ç?W-vSƒ‰˜üsRC´„ÿ`³„µÂƒÂ?F[_9ƒ=hVœ*S$“ú]ƒD)ÊŽY*õBš‚=Ÿ¤g®éSê1w†@0¯ÇÀéqÖÖª›Hqm÷GNüá©ËÝ…—üƒ‘G.~£»Ö½9Ô:ò“ÁÍÛŽõ6ŽôœøÏï¿Ó÷÷u½ï{rËæøèÓ½ëwní^ܹrbÁÕÁÞŸmY %Š¡³Ló#ġ爫í§ÄKc”0”&8ÖÍQ±  „݈2º°ÔÈà—hòKÄÑçA,ª¿‘¥ïrvøžßÀ°,!vŒ±h\4+Ñy^?&µ<ˆEÚ/VÊårƒAcʧ0i€•>Í… gŒÉÞú*}âækä7øÏ««›«›îÁoêZÌÝ5̨ɋÇéôJãSB’˜‘ÊÀ2,çfYŽa15V‡­CÖ¡ë°ë1}!;×ÀN4bBf¦Âø 3Ø'g±ÃºøÏ€g³Q{P¿ ãvýdºo¾Fßú “%WS«ðñ£=ÕfD¦!Ĭ…ú.¡(>¬î£ò0>6Jf™‹¬2NËy…üey‹¼W>(?.Ÿ•ßkœj´°aVf#™p›”‰, -‘î–zC÷Ië#»Ü;¥§¥7„¿„ÿ*¿q5IwF˜b(HÓ!&¦úçe›T×¼¬+*;ÝY5’ÍNKÈ ‡GI@]*…ëC!6†LA! Ê‚ ‡%w8,ÉNYpÖÏ0‰º£²Ëe’ ƒf³ÉH%‡D$$‡w„q6e,ŒN-ó²Â(]ô¢¼WRý¬4k“Fé‚a¤[ЬºšEª «ü¼¬§ñ L¡.nú¾,¡Æ½‡öÔdzRS&eJQ&/)šÎ½ÃÙ©éâG!ïìL—a ‹vÍu³±äû´bÃÕxíã'CŸ7°|>oÈC7-¢r® z¦µŒó´¨·µÖT=žÉ¿šÎÏÍÆ0Ó°Áhw-ì²TÞ·x&B¼ÅÌW¿u íËæ-Õ-–¥}[ió‰j?¾›½ÿæc+üq!ŒFƒ®dÃöçÎr¾Æ‰F©ö³¼Z¬\AtúOgØÏ£0J¢>ªî2€lg2Sˆ2+2=ÙMm»Û¶v>”9bþiüxææçC™"3l>½q­JŽ3Dʵ´$]¢;äÂÂÉ––z1àÅ€©=’N¹šS8—’"mí©´t|&¹0q¥\²EìˆDÞdе´BS\,X±µ„¡4Èœêpf9ÝW¼îØ;Ü™<ßòN`”.Q뜢îÉ“â˜øG‘Šð§aG{FÄâ(Þ>Òa½b‡¹„·cáv¡Õ“IÑ”Åú®P„Oý­b“W¿?XŒûjÏ#-ð¬::•™~¼k¢2¢(]W&û®øÁñiýkP³a؉|…X4hÿjØôFä³Î7ð57kËNÆa{±¶§³þèèô{ݰçPÀ¸ŒÃ‘¸—â`ÅàT­™ÿÑ]6ÀQ”gßw7w—½¯½ÛÛË}í{¹ÝûÈ]î²¹KÂÅ@6¤(ÔDlÕ2ŠÑ`ÆA0JDC$£Ži­µ”Z¡Ñ±È*…Ò™Ú–2­c§¶EÚIqš:Ó\ú¼{J@o&ûîíí}ä}~ÿÿÿyBÎ\u(˜‹ÂŸös » Vk–mÐŽjáÿ§¿æØŽ¢QCø¡NÓV4ÖõÁÃlÚ°úõ_ÿiž³Ü%ÆìîØ¿ËëZíG›ðé_?Õ+ÍÉÿè›s¿ÿÙË{)]Tnémyü½ÊÔ+K;FWºí2m±‹‘^¦fu…œ˜:Eõ®Zo¾ºÔztϦ ñÅÓÓíg‰R/ª’dk65ÛÔ¯2m0všžð÷ØvÚöQÃÔ Ù²—ÿ%Oë9D¢V•-•úK3Ñã¥#öv7K3þt/tßóD{‰Z…5i@T^Tï¸3+ªBn·ˆÄŽXÇæ‚Q’M%Æ'ÇÇ@šSc ã—lc¤!X»Æ„£)¶ö«du}I8$AàñR¦Ú¥]ÒíéJtÒÂ5Í{Þ^v÷¹Ñ¾?µ¥×ä'ì¦z.£ÝX±©Öí–*tä­ixhAtùæ±£??yñ©­?{³ïÚKgÐ'Ò‚=³Ú '/UI}zˆ§/¨;³Ä·1Ú•è‹ùõÁŠ-@'F>Qô NAœá”%™B´¥THÅœ‚-~˜ÙBé ˆê#•ž>¦²ŽÜÚ4Jû>3ˆr2 yN@¡>Å .!u õë4ä@>G(¢NVÕ¬ ª;'ÜÌ{˜]ë?  ÃXdwÓÝÌ5a:DJx§`¥KnBQWhOao%mQÒŒö#b°týåü¿NO·,öÅXš³-¨5ÿIÐÉ{ë_G–otõŸýc 0øíüg¯={u×ð™6ÛqÅ&»¬.Z¹Æ>æ³ùul“Ú†n?}ñd’ø=ì:»^‡Ô½ªgÐC?ëyÙó¦‡Ù.öDwŠ»*÷ùöU)â‡Ä‘Jã*±Sì¡'p‹O!›¿ úÕiÝÙy¯dÈ>1 «•BPoàÅb!¼”a.‹®N§—Åpt†''`g‰Œd¿„eŠãüØ/`ìO§d:e±Z2]æ,ÅU1?V(ƒj gøÔ@¢ýT¤*¢Fè"^…úˆ#Dø!Í<‡Ëq3ÝaBB ß\e„Óý×n¡€.”ËgLCýñ-¡·®J¿îz龬ôÔ u¾µòÛ¡ò›¨¹EbVÁ õž5Áj+­ú{?<ðä‘çcÜ×ì Ô=bž‚ {cŸ|{3-æ±=bZ”‹õéJ¦ÎucžoˆÎmίú–$ÇÈ€ ®ïf”s¼2/çæÅæ·ÚŒV/LŸÕýÒª–:¡¶8 N$KNÈ)‹”ø•åØ –‰gÌ;ˇ©!ö°óãÇ1»/(bŸ—÷`oU5mâív((„ì\(èózÓ2G—Ó4=ÊÀ°kÈdúkÓŒµ]f}$ÅŠaVÛK#ŸC™ ɸ8|kœ¤Y¼£®ãA-ÆHŠÙ>')F´Öpiê\é9`BIX‰|HÛq“ SÄ…‹`ôv'[ìФBTc m‚ÑØ'Ñx°Ñ×#ïxG„}ç•ü¯N¾~üÃêûXáôV<$šè¬±õv=ÒþÜOÚ>ξå»}úàÉ—O—yÂ"¤ß}wJËwåÿr>ÿ÷÷ó—ørÔ¶0!9p4ŠBqßÓùÛ¢{»í]4÷ÏKª®$QÒ‡¥ß Jj‚nßÌ»Cœc^œ¸Ñé3am„U}N„–ÏWÓ=Æ!aØËÜÓØiìŒ3÷rk›i h*ÔÔfÈh‡ùÁðbO…’Àl=ªoº ׳4 nÞ…Ýñp ÇsÕs0´ë¼?@ ðæ¦pدT ŠR¨P0œ(w}.Ã]{<îR%0?Fªßd‘Ñ´ƒ  ç¨0œW3 (žRÀ³3µYE•kˆL¤²Ú‹k«ê ×(¤5íVÞUŽ)§•³Ê„¢W@ªq>p)®€2_Ó磚>A E«&颖ÉÚG±àÙŠêçÉ3M¹JQ¹…W9£ÒÍy´«# c¥ÛÓ~ŠI{DZaÞ1O™‘uñAÔ=>96ž à èúØõ9†µf¶8ÌXg†ë 37Û¾à’¡èød.³oC3ÿà!Š›>sÀ–#5‡ÅË~G¡¿ ^7CÄP v¶?¿Ì0Š÷£ÿÒ­=Ù#2/U¹‚¡+þšvÓÔ„<ƒ÷Fº¦ú6ál{éÔ%Ëb0od{jZÍ´ËÔH—ù%ú Z¼¼–x…Œ8g0Ýyí·+“‘¨æ$¼݆vç—µ§®_ˆoe2íÙâíB0Ù¬£(f!°îGßD!.WFØVmªœ Ð÷¹^uô1ÝD³ ¦Yñnæ‘ZA»Ñ†ínÇÏ–5òvšF¥lyÌÈÚÜGD@h¤0ql9›f·°/²:ªÎBµ$jÈ2’©aÕH4KÎÿGyÕ9QÞá}wó±¹d³»ÙMv÷ÝÍ×&›ä’p¹ÜÁëe­ÀQùСwÊ—€­LµV°*-ŒŽ3ŒýG°­ãŒ ÜqžŒ í€Nÿi©µíÔþ-ÎÈØµ±e¸ }ßMîƒJvæòþ²ÙäÞçù=Ïós»kós¹È|‚îD\`dc v “aÆt3ƒ8+3 gvÂŽáDGàêŒ#Ð"·¡E Ö™)j2˜šøh8.âêR”iQÔ=êþ´l­ù¡HªÎ`Æ2-–¶jŸ[Sîñ>‡ATf[r¯žn ï,OÎr¦iÂÞ„§ƒ3aupG¡`Ýœ;-ªÉà*7ùnp…ÖI¤þf¨˜Î1‹eë£x¬Çr Å(ï¡*›ªjZtQ¿}hâ×;ÌXJDØÿ %†÷ö}à¯%œºzê%¼\­„i`µ…úv{B;KJGËÞåí+{¿Çþ¤òÌ-?'^eϰ#â‡!V(´DÑÁ{¶LKU}A?ô)F*Ù"Êsûjp®x Wæ#PΘÌô”»a€ IÁ`¨ R¥²T"@©,÷À렕ʄƨùN¡Ä–2ÞP(X*•‹|¥VÔÐknOO6›!Yöù¼´Q·Mž£€# †ce«!Ã4ÊuÑøÄ WÏꌡuvóTÒÀA£ÙáF“ F‹ FK¡ ÄUo‡ä–fÛ»xŽZXΈѴÑçès2¾B”'¥ÐkÊÿW…úüêÆPôcGÊI¾†gÌa£·°&øKÓT,Bqd¹S¨™DÁÍô(5Ã)€Nâ 3åÂä!pçš]ë¸É³Ì‚KWãs¿ÁOº¡©ÑÇZçíRL²u³`gïYgV†'™þõ¡Šš¼úôRËòW†.-ÇõíVÆž%FkkvÞ•®/ïoÛåÕˆôZV ›dŸÆN|– œ9˜=h#^#F5Ö4 ›²fZŠD3M3©¸=|N"^HœmgS„'Oçl†æ‰— ›·ã6eŸËÇÎ ¥b\»¤‘ÔäZ¡s®é›Q—(t“(´ë Q\݉„ÞלH\»jfÑf·cìÑHÚˇk_Ðõî˜1ˆíÍIR_lìú‡'õH«³°$ŸDµùƒ‰áKb¸’SöãŽ#îU[_™ƒwjyÉL}lô, ³2G.S…ÜGšî}üðŠ¾ªÞ¯"88–vSµMs2y`Yéœöý‰ß¤£r(­u1g¿!ÑAêÃ1Üí½HiW‚5)$é.د-„wë«àfb$ñGøOÈfõ·!¹ >G!• ˜äÃ}Ä´øÝ yÛŠ»,ÛÞYÑ`Gè}¹áF‘šÃR: 3ž9°C„šê ]áìå'Ï£¿óçÃhcqÖt¦æÜßQDwRŒR¢*A1ÓŽ>,°a(X&ž^Òàé™k¨š¤ªú'Rº&éºVloO™†dš† ŠzƲ Ôé‚"I‚„: TS­Øšj˜õ8‰[ë4a¡e Ëƒ¯yœX—g (£¦Azã@´À~æ‚s…Çõ Q¯£NÛqª *I¤'•ÌdºªBwZIbSFØYA›' Ý¥>ýî…]“-ïÿøw_k€ø¾ o¾±xàÙ#_?~ÏC/>ëݶóƒGÞo$&^Þv|ëêÎ}—F/¾sèÏkx ¼<öäo òúo¿þ õ„޶êÄ|¤Lö'ž´žKüÐzÉÿÓø¨ÿT‚õ± wOl^•Žæ·$zWÙXGÉW£m§g-NF¡$œ ñ}ÐfYhÛœ #;&ay²Íq†¬ ÞPXš™Awšf˜ …0Í”œ³™O¦†P†óö{ÜiäÈ )Žûd ¹¦,+rÓ”›1åAוå¦+Ë-W–[ñMv¢nëœjòô\ÙÌâÈ£—^™²èVÍ:&ÇyäÒ‚ëÓÿ…÷þ j*°×ÃÁ±c$*%B);MîJËš³"†ªÙ~àò»ö7&ެ}f{¦{;ù·uùœ‹vmýÛ;<0¼ñѽó×{—œúÎæ_îI6íÏÇó>ËúÊK”çß„W}lç~ß;Üùìó}9þ<ŸïŒíÄÎÝÙ±˜˜ø€‰Ñ$ké€Ò™}––…AKiJZ TÀDÇVÑ@G¥uÝˤ„mãub´ª4u“&*U“uÚØ¦m$ì}Ï_Ó¶\t¿÷ÎoÎÊ=Ïïù=ÏkfÒpNŸ‘לÿú“;yÄê;"ÔÞF¨¥A´†¨&:SÉ.=ٮܰ ìÏ*»ô︎ë?Ê^ ^Í^5øw\çÝ„+Ö; “d¦PpxEŸìe™‰Ha9’Ö+/8qQ’DQR5- „TS…-¦i1 "íõ2  4G«ØÖ,‰\+F-Ž_¼^Â&ù\,^¯bUÌô",>v`@%BœqDéK´‚L´üáN±¯Ä~â¢Pß{O(£i/ñ·ˆo±?Bß2,B3¤  Øö°m«ÝÄØÛ=wÿ{S³Áá®U³‡åÿÔÀW¹Êе†æ©¤+SŸzYl÷¼:KÜ"ê7Ĭ¨“‚ìÿ¤§oGPnú=ý¦+Ò"&’S¡î¥^xé÷×>{%ÿµ§™éÕVÛé_ %Z‰×!7óTß¼lH R)ÒËËæ³dq…nX0õÈ3Û®v¥ˆßÑWî¤z€½sÓ±é_ü²µo_ëK&±Ö·–]ëßädýƒÜo»Ç¿›Ö‡Qß vÔÏ5ƒ¬¯¤?¦¯Wô¨Ýì6ãµ?»_Ó{œ=Î+¾ ÎxÇØ1ÿiîûÆÍ‹ð§Þ+ìUîœñžyˈ7Ë™>o¿ï ý1Óå’‚R—wÛŽb¸üºÏp¸›åI2nyšÉÏU5@—¡(£›¼»X*šË žÓ‰|>OäÑ։䈖Ñ&áâ E½¡j}"âr.-ájEµLÉT«ê°Jª‘…¹Ó‚e´ ׉Ø1ñ¾n I€v^@l—à\PsÏ…0EP'#ÛÎMÝÊaïŽ Ó¸®a*`nLý‘›Â-°ñÄpoƒ5°n ŠÅ†"Û í¥¹Å6Ät`.’É:ÖxÀ$p!AÏ`ðÙ-š{ìÐÞż¾.f|üÎü6eÅËËÙXzƒæøÞÞ /÷ÃÜêÍ×wU6lËD:Tþý‘üÓ§6~a~ÿ‡…åþãÒ‚/ÌtVR»Ž?ß·tÏÌÍSO¬ÿÙ¦¦œ¿ágR æ¬$‰{χ¤zÂm›,0È!;É"1¢tAx™¤€¨Ø¼òe•y°¿;’²¸(çA*^·ÎtÌ„£–õ}(P­9Ê1 ¶#FPÚ5gÔk²¥^ã‰R݇"¥=‘·"cÈOñ  F4Ïú‹dh4o ;ôND,ä1mk,ן'Ø—±3‚RCÛ§r¸¥d¹jå6 •JeVÍsÏsªÁ™Ã«h1?w "H§Ë÷·3ŽaH'T5„RÚðÞ3±0‰§p¶:\ƒiQ×==s«h-7¼ÓãLäѬlfaxùŽ#«c)gÏ̽¤b·×ü¤%]H¥Âüãß"QÙ¶áò[äE÷"\Ú`ÿE Ôcž“Íhq,yÞ;á»Üäèw®P¶ûö%”A™e¡#ã c¹ ](ðF19 ô6Øî¢éxV—²Y=¡iIA’AŠF"H¶ v Eû9~NÒ)d…b³ž•8mD°ì ¶P‡;qµ||9/XBŸ@r®iv½óp{ÖÆ®¹dלnWK(,(%²0û\‘Î… z¶g’¬ž¼g=ëBÔI5;©<T¦ò³¹ä¿Jm#0òRˆæK>I‚–p°a€›2‡­'Äùãçf @n©“hÌcdE1z$K l/ÍÊsz‰…Ìêîvùµ”Û{þ»ëF¿’|N_XcàÓ³¤Myý‹/~~öú?JÙ+owö¤¹k`&1ÜlÍÛõƒîW?Û O¾iª¦Çîgfè¿þáÄgÇ:–´>=`¦Z\(1äC?°û°fY€OITÔ¥º¼ÅÂ|~a #\N”Õe\?Ä¿ æNH£÷ì“Ê@‚åÌ_áI”€’„„VÂu\n·/#Qûòœ±À®Vk¶ö{d:’ˆÊ ºe*̇䰟ãì¹Îñò—T’ª&&ïì´¨‰H8LÓ¡Úä!?Iç^T/‘èX<0c°ŒZ2‚~Fâ0  ¬Ñ“äò³?ÍÎ[4eÿvëÓ˜M9”=Œÿbzÿ2ÿ6?Î;@­<ïFO»]ÆÑ«š´ ög¥r=š³ž:’il–Ý$DC¸½J!œ·…Z²lއ2«‰¦àW6ùª¾á)Èó6ïœv(Ž+ãz ­¥iýíßí0”`´Ù‘J9ü‘M§þõgÔÁÿ¸sÓ}!Z€7,ÞÕ }ÆïãYÑ/¹ —cÄÖvBŒ¿„¯-- æ5¯¿ÄZèDc™v 8Å´‹Ú á§:áOyt§á,˜)*` ½j¯Ö›éÍõêk•µú.v·vP<(OJßÎçøªÞ«ô&Èj¦š«¶’U­šª¦ÉªRMTUÒÐ<Œ™¬¡~I‘‰e‰£ å¥eŠ À@´Idôf9ã†.ÙíO›i"­ K¨ÄãIC— CÆãq3/™qÅ̳>_²— …¼×ç³ åcG¼¾<ÉqEg@&$‰¢ÜDÁ4gãQEw™h Š“äÊqcÄœ$FÆ #6§˜p │†M¸í|Î6¾4ukêS>XD¿ˆQ•§ðš1*7Ä9¯!†…ê jv1{§ÁµÚ’­ö`i¨G]AðØŠÅk+hʲ6£îç“‹@7îÞ©Ç\ÂÀ÷â• ¼Í<ÕÍv£-‹7SDŠùªR=$z虥sò (xÔÓ¾b~b`zUê›Ó«ǦEÉÑ®ûèôœÓ]õ±Mœgü}ïÃgûr—‹íóíØŽ¿Îç\'±Ï®ÁÄG ¬BÊG4dY[ŠR ]öVE¢£¢(" ºµÊÊhE¨„Úul*$ÐZ˜„öÇú›ÔªÚ´.C–uPuëâì¹³ª¶Y¹÷yï+÷¾ÏÇïùýÈ€‡ È˜*—íXØPYS9Hxj}¨QY@µtÅuòuXÞüsÐåg!Kx“áßG½N§HÙ»^Øy;s:CÛívo^&u³¿,«/,6|íYÃ`½’ä•eZ’dUM¦R^›f ËéºCUS°¯|>‰iè6õ^!Xߦ§ƒmÕ •qÀx¼P "ÞÁùˆÜŒ VÜšj ¶rjB²Ù0‘l4ŠêК¼)):ŸLÆdÚ_Ìë)ŸìuÐöÅL̓¢‰wbéh[+ô, }ÑH=o?‹o>H+ô& +qúδ…øØÌö1Ê襁€–ûwþoàïþ\`{Ñ^ì».ó—­Iu,Ú/WñgpàÅŠ0v{¥Qcø@Hlõ™û¤“ʽV—ݵǔ$Å¿fýÑ®ÊÑÇyEnïYÎÎý…]ø‡* ºØÿ geÛŸëÛǶuô 8ñŸë–¤}ò¦ß¾np–Cßá7î­ªŒg·/[&A4zš‡påÂPÈÕrÛ‰„=œ>€àÑSk!Ob^yCeòÚ ½Qâ\$àW&¯€"`ЯÎsTñr?=m׈6QC`(?C^"÷!éøcCv4Ù#:~ ¿Ô<Ž^m>ÔöóÌ{Ûn¢‡Tç)óë rÍË›ˆº¨O¯ã£j–7ï`R’ú¤!‰\ÔŽë 8­3|úïÇÊŒBb‚¢×+% /ÔqÞdºSIx©±%TÊä¸áFÉx4ŠQTXT<¢¨¤ËóŸN…\¥t™l38¿_`Åœªˆ7Vw/AA"ÖO¾¯üB4à9Ñt<Kd‘(ˆí"ùCèk›ÉµºxžG-ä‹ÄA“$e³AóYIIfƒ»×êÁσD°3'JbÎÙùaÕñU.£YŒÃ|éaµd¾4bòrí\ŒUm}í:,$X¥Õ–=i2Óêocï;Ú 4•; :¾˜Õ„šVfµ{$X†eêÌiÜP€,l(À Z WGÍû€I¼pÙ„¤A˜´ÃB&´âDóÚ'¬~däÏ_CY8Ôù”œŸy~@Œ4ȲŠR¦ŒÉK– œì²f®<ÈV¯”g¢ÐÒ,Ölñ&òÒ‡^Òi¯ãÄäâèÒWº4Í+îyºoeÏÖ ¯~wË¢ÕbüŠñЖ‰î–í»?Hî›{d€su!8 o×R¯8ÞÝñüÖ üèÖuÆòÅþÊähwß›¿ûcÿJ3÷rfîÑ!ëã˜6„¶;1ãX¾IŸk¤Ó‘¡¬i¡aù³ 4Ʊ¸,#i)Sõ¶K½2‡#~ÌCE"¸*‡9ÞÃq|$*D’ÃMûã,Ë%TžBeòE£žx¿Ìü†! f“ I$á8âàCÍíO›TuË(–1?ÏU Š?{‘ûˆûGre¼ðt‚“¸„³L„OÖæž^žƒº¼q/¼³€(V|íÕøb—QWáî¬ö/|âY,î2#:b†BJæÌHˆ‚ŠE“¸*C£ŒNBHr.“ÜFm ÑwåÛ/¯zú@¹rsôµ ܤVQKm^¹áüþ®ÁI…>8×»yù+»Þ¬\š¡¤çE?çb”~™w¾±ix|/t‚"ø~Ô½Š9c2$¾¤šCjÁZ²MíB]xÝ•ìRû#û’ljcñÓ᩸F~ÂOùh2¬Úö*xgr,ùV„ôÒØ”…“ –ZœôZêQŸPßU "Äùʘ:Œ;™ ÆT@(ýÔˆ† ‰$É¢«žg|I”æJ\7ÄQõ\˜#8sÔŒ]È·J¶>Ûí;6j·í¨í„í¢í#mó¥´õUº8¢õÞX%TL;;; Þ×4ˆ€‰èáê`µ•˜ŠiƒŠ9rb…ÌJÙˆFðÄ0Q+WÜŠC­@ºˆj$î‰Ê\ž _{öàÄqÙ¿}›Ò˜ §êÓNwPìb÷šïmî}í[ŸìúþÑÑŸ`õÌÀƒ]-Q5änjõ°"ïûÁáÃ[žë}òJ”ZùŸF ñÆ&„=Q_}‰àtÂÁ¹bÖi¬œÕ³¬Ñ™ÓN=púÙ'O²pþžµ•Ä>qHìÏP÷_‹.ÈæôžPÏÂþ¶QýÇøuÏañ-ô.;OOe§t~ Ʒu\'ãNóyë¥EFB_dÄâ0iÔ=1W÷6'v²éŠRÆ· EmkO÷Æ<™B»X‹yH·Y{$J“a·âq»•L¼‰)”ç?™  &r³²Ì³î¢ª¸T&É)å]7kf†3ëì<’eÇœpú~V¾äHzßÃIN§Ç‘[pî*€»Ï€ç øä@0‚ñl Z®K]ªÀ_Ñ-¹‹Îη¿^•½#Ós_hd„ðoº«¶³ ßwçäüs¶Ï>Ûgû’;ÿíóOb'>§¶[ûêÄi'ýËš.i²†µë?¥i kH[ctª ÍŠÄ4VR~×i¤kñ 4ʤ±M „¦I¬1*k U•&Ã÷Ïi@Bò{ïåûôù{ÞçyŸ÷î‰o©¾–ž¨TìH|K5’ÂÒQyª?s«5Â*šA?Ž·:DЮiçÿ—XFóƒ*©1õL÷@ãû6ƒÙØZT >òõG·WGç^{navsøaIY~VæFrg•»@z^ø×ÞYÞh7»g{O§¹ÙÓ·' çN^ÛíHô‚iÑõ:-6R\9¡ln̾VÝ^Gº«@îÏAî{1k(Y+mÝ´[ÔazZÛÇõÛ xÔ× ü9¬6 wéwÒ;ÄEÝ·uW™%ÝM‘Ž cß– [I€ã®Þ 7´q˜Þàôaç9Eo,š¹N®›#8Î ÙɶˆÉäË[‚wz#Ø0ŽhÍZ ¤–/F·–, \è²X<áø¯Ü­<öñòfˆâX]5gКÍÄëJ˜ ÑZ3èØŒÚ« PXàV H`lÆ’^Ë$ʪˆž—`nvdˆØ Óâ3û?´'Û#ªlSrï’g§†žxÜYÿãÅgjÀµxh_yçŽÝzffaANïû ˜ïñOž)<Òy§ö™K`ݵ‰Âøèž ’×&õ}³˼ ýcãrcxr½ì{#àv¦’%!³#^jWØl9‡éì%*e‚è{¯'˜Áx©@ÊW 7 © ga–5#KùuºÊ*p` VèPkï½´!”ÄèK\È`ÅJ+ËèÝ!t×Èß¾Ã)q ¼¿¬ †tÞ)Cï%D0àkÍ÷׬ʠUÑjÂ@4"ÐÙ|.ªá%6m®á„B§öÚ€À Æž÷4þÝY©¯ÔW Woîn†^n¹€|ôÜ-8|k£oYTƒß¢• «žÜŽœ&otõ| WÖ;J@rªäG—ŠÂ´ÌÖ$€¥È “*ý"ج†kÓeѨÆûš7ZÏmV@‹žðMßc¿xtxäàüôôú˜Ð+r¢“& L|÷ˆß²á¥—,ãå¾D!;rehtº+$D¼³§ÔÓ/sCÄ\¹Qm¼ÿüû;6†xDÚ˜ïø´GPz1 jmL–PaZÃÑ -ßI@zuì­Q7RÙ9¤±uyÛéha¢j4“ÊÞ»uˆ~27ÇæZè§S*soTfWÉŠhÚÊVºH#ºÂ¬a Õ¨©va–u±5 ©¦°†6KªÜUù]ÄA{ zHéHXïüslîׇdGhøõ2½ó~íôÛæâÜÙ®m}ìãßVg“c“Cs‹õË{¢ ÿ¶ñõß}ê­ê‘Q=íþòþý&_‚¶9ü¶d8#W¶?9VØ+ÇgxfS(Ê:/ì¼p›÷}këôŸÆÎï{~å³âÉuåxñSc‘A˜UøE¨Y°Eù´ýrBº"ÛóG"ó†y~!¼Ñc‡Ãø¸ŒœÌÀÅ Œqd+]SQ9•Á$èÂ0’¢Îçà8–À² !ÙåH&»‚i™LÝ&®/ê㺒´ã<»ìuŠ}5Z¢Dµ×N,eŸDžZ]”—Øœš:dõ[è Ô˨Y±çå’ ééãØ$Ëõ{¾¢¬šp#í^†Ã’P§MJëaÃmk6\Xn4©b«¾¸ÕpÏÑ–3·à¼£êlµÕ—{ cËBÇöc_`,X2Џ©\ è þt“q¦L`×èNÜïȼّ™¦¦7ˈ$ƒ O}$e|²ñÁÍ·gRJÇçY›ÉlË­ó;bwð„Ëãè&ÝOÆ8å`8좳íÂ'2°¿Rî+?Ô˜Õ[ìæÄfFþBº[LœOWã·+v\xopüÝ©ÓÞh;A½÷Áÿ ïjsa&L!%ÂÍË®Ïåe{\±ËqÅÃe&)à +UüSÑhJ£°cí5â9ÅK‘QÊJIV÷;xÞÏ™øXÔÏÓìyô«áAÕÀ¦%bÖZÁŸHGì¼ÂÉ<-_Èðx(+ˆ&¯¾æø2)þ)ç=1žåcÆG5,ïC‰ÎÛÄ£Í+fxA‹¹ÌjÖfÜɱå•å¿ÒÚ*ÖkŒv¯N·ÀEÓÎŒºä V¡%³ _Ž…è¡ÛÖ«XsšC_#ÍÌ<[ÆjPü&–/HR!ß÷†ƒ1[¹|p`z (e<_ò œ«ÒæÊǤBAŠå'Vú7Yhgl’Ó¢8~y´ÃÕaB5¾ÓÄ‹mNˆQ ûঽG±Ò™ô—¹ˆš•N³¼Û¼[ÜÞYLµy%ª„§¢Ý©Ô*X~ФÌTÊ,ˆa‡(†]µ@ˆ¶Šð‰éhX¤!Vê|“Ÿ&€Bl%pbgU#â×·„´Ú—o„ùe&ï­²b ßI‹¬˜^¥}ï’Ø™º:òhÇG]¾uâQ«®· ¡Ã w`A»€AÁß?éµÇ 4û YÄ6»&ëR]Ò}òÈàÝX¡ƒ‘o¬TþùÕÒÆ´¯Óe÷Xp‚¢¶HÞöÇýf›ÙÓæT£qò“Çþñ‡|Tèf¬Œ—1‘m:Ýþg lŽr‡ 8ïB—„¹¡&ÞšØ n()*àÈÉŠÙš‘§,+´l4)·ÉCmÇž°]¥É>¶$²¬Ž=ao’Ð ‘"p&‰ p$ƒ­„ÿÃwµ7qás´²ÖZ],­VZ­dë¶’v×’,Y–l낵$ ãc…ДP.†$@S iÌe2M é4PÈ@È€14¨04e&ôBûÐÌd&ÎôÅe */4i=»+§Ðj¤=:gwu9ÿ÷JÍëã±¶~ôžðé årÿ¬˜I:%;Éè½6ipŠújh¡(;?g†PÍñœ™.·ÁlŒôj]LßV •a£håå¤ìv·?HùýA¨†@-¥¸™£Ìfrè‹õä”ÚÐÏ Q‚2è5O¸Ž88Ÿ.$˜ Ž¤ë€» ¯]µÏúËÔlðS,Šxð* „àõKñ/™“ A!cyŠ<¢PëgY’‰tR`-çÔµ5ú}xçkDÀ+Ï˜î ”€\¿äsÙ9Vˆ1¯¢Çóœ, ³ÔðLˆºY>šnãõ¦l}öÇÒñ ɯM·nÉ“™Â9àƒ,ÛáÅ52ÅÚ$¡~‹¸ †cˆvçÚVõLuvÛõNRφY¼B7µ­óŒÚ<í e¦vÓ+±fš/M®?—7ÖX:ލWXû‹åŒAk"‚A5,6-Ïïý’çÍÁ!fr•7¾V=®Þ¾–±Ø=„Œ¬ˆw×"d5AAìÓH7t‹Žä0n¼ïþ7­&<º˜NÔ èÔº¦^ë8ßkBAÙ¶ s“VŠ$­ :ÒÅ[IÓã 73ð:úH¿¨Ç$ áMòsRE–aF$\Z’&]ÄkËkº(¹$ÙÌ’¨p´1GÊDgr¤ÈSòìrÀ¦¬ZX+Zõ¢UQºP49•ó Lí.#V ÊÕWì)R´ÍYß9\™}p¯ôßDŒê=WÓ’DÃ¥Ü*3»NúB:@ÄÀ³©šá‚O¡[8_·µÕsŒÅˆÄ#åZ3IÛ<°Áäé( ¦ãcTeFÝo&ƒ ŸÿeìÜ÷Ív7@•`}U·ùÛ!U¯¸AZÝcÚ ýÃ*jug)]Ê<›|Ñò’mCx‡~‡mgøõì$v0|0;¹ä8ö¾ñýöãK>‚S†:Îv^L]L_Ì\Èžë9Õ{¥ójúj>ð½ö;6ô`ƒ`¬gp›l«çg½ØºÔÎöíé]=¯æO¥4< ¤¸eÑ‘-Ãu^ßPµ(õó0?ê†4 Ý" A1Ñj6w·âøÐïN1Œ[ˆ¡Žé´;ÓEe2] †òîB‘*ŠA]!ŸGTHÃH²»2Å‚ÉwÀ+ù,† ÄÊ@˜€ “Ï TBY•¸º% /¦aZ OÖŒÈ&3¢³1±%3$]Ó™xäUØ'ÅéÁÛÅÉ›”·<\F7ÉSF™6‡å©HG‰-…ûUè ] …áÇm²K4Qyð R2!_)mEë <[ @ò»Ü¼o««qÄ7›5!w_‘Õ¬x9ô\(ù%ù¡àÍl@®-‹^À§Oõ¡±]ú ©Ùï§ÔÊ”Å!e k&Ïç³,Äú(ALÎpŠáÃÉŽÖ~Âûu,Œw켜¡ ˆ±–9Jâà­Z´f<™Ž/¦—zg劖 ¹Ù¯Õ“Š{™ÝãA6*L¸U˜NßÐ=ðúŠÞ÷¦m&o ûëóìO¯ÙqÞmÈh±Éê¢?èôˆñÖUغ«'·8Ý]ݵÛh$pK8oåÅclì'°{‹Þ‚¤ÓÚý÷÷î©Jßñ:vîØÞQýRõÖ°EkcõRçpH§Qç´Ã·÷©¹_ñXÍþÖGmÀ©rFÕ+ñAí k¥gÜ™táNó3ª™ n5\ÍÿbãÚq׸G\JÔÐŒ6¯Ln ¢¾ùvÔÉI#¢$ Ù0‘,D±B ð‘#ÚCîp„ ‡#áÐ\܈„Ÿ7¤z®N:˪#—’·#RÀ !± Ë+'å!-’Æ…k$¬H`XæHSî‡aX áÿ@Bý•ÙÙ¡'3ÈSï6Xƒ®é[9äÿÄ>äÀ$ÝÞ’8žp¨ŠΣáìÖþë¿_ïnÚi5iõædÎ]J·¾WlK#×wr,ꎽêazWPƒà”‚ô/'³ß­NLF‹¡yÔ²?ÅE‚±íðb3ÅØ#þ`d݇ªm[i›W­ñ£¼‘E˜¹Œ0c ˜»ëUZLC`§-ì'—ÈK¶Oíš û³ßrÈ~ÄrÜþ!‰·[ÒÌ2KYU?J[pB¯7ûu8VWGûÕ:ªŒíI|Oq(ïY’|?«pÆa”–9 )Ñ9 .I1Ž^®$ä£EpÔÏœ¡Ïì¨B_+ê¿««ÿ.ÈU$Š‘ Y ­¥)”öô£­Å¥-SÉ{Kb—OTgßœœ> ûöM™È¿ûÍs…ÃߨŽVÿrþâÁw!þÂÒÒóÕ‰Ï׬‡§Ÿzäªöa@»À‚8‹#ð°þ¸~ZÃP—²ÁRãRk¾yD³Î¸Ý¸Ãqž¿VC¸Ö|Ûa\â£F,>`ÐàoÀæ c6«‘ŠYÙ^g~$y_Œí~ BàŒ–±Ã¢Ojkt;œ”Ãá ú º«Ám¼Óa Ï`{ŽÝ’Ä%\ ÊÀɃhõ$qÑ\CÀ_ÆOâ7ñ:|Ë GúÄɲeºìWñ¤Ct‘9é½H6¢‰³)qßL›ƒv´e,ýñh-4(M±ó+{ÔTy¨ 6tWq[Ãç* ãZÊ¥fH=Å"Û—E7nÍ× oWðPÅ8¹lm¸·£ýqdHZPéº0y¢Ááo{7Mý°úóÄûcè×V¢ÔíH»=M‰Í]/%6®ì.´nü¢›¼³ç…Ã[ÿZMÙ«Õå´ÍmÔ»±C”Ó…s-}émGþøüÀȿΠjƒªöŸPµ½ —Š„Æ©i\鋨9i›JÈMÕ;ªWá9óYrÚw&xš;™j¹Â鎵L9±àÞà¡,Ïô9G!–Šd¢K!ö¶«=¶‰ûŽßïÎïsì³ÏöÝùßïü8;¶c;±ÇÁ!„QÈ ŒÂ¡´+4¢e°*Z_ˆ2ð4@«E”ÁÖU“(mE#D`ZÇÄ“úO5©ê´°ŽIÕìÁ’ìû;›—4Y?å»ÓYú~¾ßÏ£ÕÑšëH0Ç(”Ã*çàØ¼ÃŽly»ÇÓØÃET1ÛÊ%ÕIæ¨ÎSñXs3!…S}§¦'™¬îô³»‹Ë'UŽ£>ÎSÑ* ‹Ã_ænq4÷êp‰Ó58J¤ÈÕ©ŽáZ€‘HÐÁ¶Šº\·ç9Ë;Ú/¡¿R÷£! Ú`¿‘›·gî;À¼®‡ðrÓFø!B]iàü(¾ulwÖU;M5¬ PÕ€õ>»ÕW( J5ÈÏËüvîR@ð)íŽ9Õ±EÔÚµ}»V}é™g§ÞüÖæeeÙ`eÏÜ?–仾y’9xïƒAµ9ãq›ÝÝû<šùÅ`ùíÑc¨lxiÿ×~¬¯žÛ8Õ7Ø»-!^^ƒ%¨¾-Ô¿õE4h  gZËl²or¬n9ÜuŸß Ú_ Χ™ƒ¦ã&:¬(ˆZªþ=Ù’§íôB#5ׄš&Ñ)=â‹[,ÈšDð¢`Õ‡±ŠGRÅ\Þ®ÛWÚû­S øã-×0%+T°^ì.b=SÂz NŽ‚áB¨¹HaDáSø2¾Žoáylí;p!…v# Ün¬_:==;m¸ô‡’T‡.VêQ9úA¯-O4æãÌ«C€HhlÍC•1.mEë|pxUAÕ"b« šh«õ¸ƒ¥á§Rᔿ„Ý>ÕßÉ¬êœ ¢ôîÞD|qµ5¬ð›Í¥oykñð.áeúùíY¯“³C÷çg I}ÝÏSõX;BBDæzl¬É-²~wWœd£îã “C=h"šD&Ý‘½Jå­æX‹UšDô¢ÿª(°Í1Kר«H÷²=+B×\]×ñgø ̼‚Cÿ®`>mëÒŽkÒUÑý"Œ~Ž)ž¯ˆ´øí¶)Ô‹žàîÉ¿ r{ddønzd¥§:=Sÿ1ØŠ 3Õ  4B)t*Ê€¶ÚIã²t©ÝÈï2ýywܼm`áòæ¶½ýïí{b“êmâÝqË®§û×s¡‰Â÷và k«'Ý ýûý{zójµãÐ}Û"Î,ê}óåµ “‘êÇc¥§ö›™D&xôðYÓkTY.Qf0p;ÁýêîÊOÌ·è{.f­\£î"&ÖÜE}ÅŸq3¦_A¢Ã”ËLf«•j…e 5‡E³dB6Ð$I2™˜7¨Ó4²ð,X3%  K%)8z¹›QzžAÌvL}`u×\SQVNo@隷®耑\;´Ey,¹¦‰mwHR è!|!qö.P ™èé:ך1×-ô|ÖH0ÊB=T*Æ›«UÄ]«çÂ1Ä@¬Ñÿ뢄mhað¤ç­³!Ž•ZÄauãêÎJ¦ÿô˜ã…ïo0½6÷EÏìøhÈãú¶JûËZ9ݱƒ^’ï~ƒ°q@Á¼VÑ1}Ÿ­Kꢽ¥¶emkªcý{gý¿¢þ㷯ͮY0fgúük¨ ~¦ƒªúi5ÙR¡ßµ£ŠÖ“JŽ&ïøïîT¬¾Õ*owh‰ÎJW@0üU^KÈÝÙB¡á…ÓÖ*e¡Fá«>ž¯Š.Væ»Á WyÎQ³ofHä“«ïñà‘x]”мî/)ü?ÊæOñfÒ¡î,Äe=‹²q|Ô+×Ý0)ð¸Q}þzͪKÑd1/ëòi™‘¥n»,ðü©c÷/ ‹|åYz{ŒÀæ‘z.P1à IpÆxbáÓL$äd! 6Ô侈ÀPb êU—26¢_d+þFÚ['' §‘àìcøGqÌwÏk¢£ü¸É^H—ËÌGï'šXOËpxh¸\Hdš¸¾37¶dõÌ:ìqøS+”¾5zG<—Ü”üêØ¹¯/ 0;gϾõz”íÂK ´L4Ò¹â_s7?ÖÛúN ÒÙé o|£œÎÅ;¾;÷ó}Q^Xü—_ÒO&)“TƒIÒ¨{ú¢‹%u®”Ôp\¥õô“ÌÏLŸ¨¦–ЂÐršéŒ ›ÝœM.«hµ"žó#«‚YÅ›óöx/èÎEwB$ž™PÛxªd0œ¬•n‰ó"E]|U<"þA4‹Á¤RÃÔrÜwúJ=Ú6ª]ÖLÚ‡L”,1…É(d‹¸þC ¤x h¼|%~Á§Jqë˜Á“th"Ñþ©HÛ‰Xðinf°ñ{Ô‡X†êí  Í!·nà&5ÂÇàÓQ6>ŽA•†é‰Ò™fªð²ÇæzIÜçS›Ø‘B4¥sÁC?ôý&.öK]R–é[¸b`ç‰ÁÿÖÔ ¥” ËÁÞn_Z(äúÿ4)ü‘~ñdÁ]ÎÿÍÜ]O£:+ú%™¶ùí2"¹7álZ¸.8œújpsê³ 9åÏÉÕÀò¨¼1õ‚¼]y.ýNâ|šõ¶’IÏwI¿ÝZo“Q£L„ë7õ¼*SשH-~5­i`ø­!Y–$‘¥“ÙböHr:RØÛÃ2, xÁ¼×íAžI¦¬;Ñ ©&î ¦kÔà$}HwȵP|(6£c“Lnz0û/³_ÆÛr0w·ì\;É^+ÞÞmoJ»ƒä¨¸–°$Št³·4ÚŽ¨¦ƒÿ!ÞÇͰ ñÁ:؈§¿Â=¢TÀ}@óø¿†ö—ŸFݹ tÃë0ì0½À_¨÷XOØÇ?®ˆ—*h¾îŸxŸð}À eo!,·"¢^€€6üVù@Ç7Ö‘|²‚ÔÕO#èú@æ½r€>ü_65 ^îÁ÷ni›؆óL<0y`Ç>€¿˜Æoß…k³×fï(À>ÄÃ8çÜïæoÔPC 5ÔPC 5ÔPC 5Ôp? LùÞêB-Æ…ÐÂ}©d£ ï•« ÎrE#Â@ % ·F¢1h‹'äöHu¦3]Ý= ¨Øi`ÓàÐp~dó–­£cãÛ&¶O>¸cçÔô®Ý{fîÿòÿGâo¼Ðü«&ðB+Ä¡2ÅïÏÃ8LÁn˜S¥öòBb W[û`3L”[gK¥Òo?ëW]÷ÏN¸Ä¥ÿmì¯ÎBpÑ¡jsh{ª¶-…2Ëé±&†ßT±Y0ÃÙªM°ÇóU›CûU[ cïïëŠN.ž?>:ÿØÄ#‡gŒoߘ?1{hanëä× ý¸Xý0€Ë9Q˜„8 ópFñù.â#Xž…#ؾKópNÂ!¬9ö¹FnDÂN`éöšƒ­ðùÞû¿M™!WáO¸W‚™°àÎzi;cx Wž¥2ç±EÇ¡EKwsØÏÚpø½ôÏÛ!‡ }Ë §ttšwt r¼º+ØåÙ­§ƒÕg?Ö‰ºrï—<…ŸÐü¥+­ŸhÖžÔýE—À"Ý'å™ÿ>Úò$ endstream endobj 329 0 obj << /Type /FontDescriptor /Ascent 891 /CapHeight 0 /Descent -216 /Flags 98 /FontBBox [ -547 -307 1206 1032 ] /FontName /BABGLH+TimesNewRomanPS-BoldItalicMT /ItalicAngle -15 /StemV 133 /FontFile2 330 0 R >> endobj 330 0 obj << /Filter /FlateDecode /Length 13494 /Length1 23244 >> stream H‰\U T”×þfîÿï.£ êâ¢>PŒŠÊâ+5D”E| ¨Ô(ÚœHˆ‡úФø &Zc­¤š¸4ViJ5k‹4Qj}?ª‰&ƦdÿONÒs÷̽ÿÌ™o ^†BÚs“ûGçLNßLsÈéÄY΢3õ¥&à…2€~?ki±ÕÒxO¾]ÌesŠò hζ×K6 ŸÌ[°|Ε SûöoëÅüÙÎÜc3·´Ê}•¢3$_|[¼€ödš_P¼lçk!ͲŸ"˵ p–E3J€”3²?Pà\VdÙæó’臊¼u¡³`özß‘ïécÄŸ.)6Ä’ì{·}/Z<»(ã=€îàu_ß ^GOYÁªA€q]Ö-YwÝcV}>lîyÆ5ÕI´[Ÿ®axDVÌÄT|‰hã´pã°Ÿâá…oÉ» @SÀè‚ZœCÀf|„Ëø1ÆèÈ‘Šw(•ÒѱX-:6Äc†c"nÊ=#É[îZD·ñ(Å›8Ž&øË÷5IoBo¡z­Üœ+§)“VG&‰·Ê0ÐQø'S±–,÷-†Xöú3†Šx‹%Ö˜Ž¹(A5ê©—ñPr¼79B‚ |£‘vÂØo1>G¤x‹8Ñž*ìF-æ•h¬Ã(9›‰7ð|DÞtIõP&™È}y7–¹YÃsÔŸT:ùceñn4ºoKjhšÚ$ê;ó+*kµ,ì$‡<Õ8àþXÕã®:EKÔ¿©÷Ò6ÉŒ² öµ’­Rg“ÕªÖ[LT_ã$ÕJ©ÛÑКÒZƒ2ÞÓú-—? <""c$ùÊ—¦"È]hÔs* ä¯ÝËÝZ£Õ»­í[ª¯Ì“ ì”é2L3¤ÓWK—daœL–Z¬6ŽI?,–Ù–!/RÅÈk4RæQ‰Lžó2íÍ2‘oÈœª£yhæbd¶YÅ^™¥iúnlL5%!>näˆØáÆ>3xPôÀýûEEFôíÓ;ÜjëbíÙ£{pP·®]ü;wz¦£_‡öí|}¼½,f“®)&D&Ù’³­.{¶K³ÛÆŒ‰jÛÛœràüÙA¶Ë*GÉ¿”qY³=bÖ_J&ˆäœÿ“LøQ2á'Iò³ŽÀˆ¨Hk’Íê:é°YkiÚ¤tá×;lVW³‡Ÿàá7zøv‡„ˆ‚5)0ßauQ¶5É•¼4MR¶C®«ññN´%ÎöŽŠD·°>¹lE5G†’†×0,íÄ)W7›#ÉÕÕæhóÀ¥Â’œ¹®´IéIŽ Œ¨H%βå¸`íêáA¢ÇŒË”è2{ÌXç¶EƒµÖšÈÃkÖÕú!';Â7ז뜞îRÎŒ6#Ä®ÃPr+ð¬W pTÕ>ï½ûÞ&Êφ’„Èf–„ŸQ~„ÄB–„ì Á’„› CHaÐPZ+E4­?0KÒP ­‚ 3–I¬n3©2Öq"ÅâØŽ2Ô"-¶áÇöö;wßÛìÚb§™|9÷žsï}çžûÝsnz»X|pI`C¢5Ó•{ÐÃÝPhƒ'üRE њͫ«±æê9þ`ÈO7r‡‡#ì>o%¶©:o)k‚+<áTo±wyhEç‘ SåÚì½¾vùGÊ(õ„ªÞìpQ¦·zñÌá­·Q¨ríëé>Oz²%\«{P,š­Ú~ýuq›j©áÜ*«Œ‡Sc¼÷‚aÏR< x±‘©ü§n*…–NÅ0üTk˜®Å1<N- †Ü…лy~ØÌq{=¡‹„c÷žÿ2Y³ØÖX9î‹ÄM&Gœ_°;íp^^xìXæ…« §«þäüqDôO½õnÂGåL«.˜ggó©nŠøh :ᆊ@¬ï¡%™{É7>¯:¬ÙÒéXÒæ±¥Á±Ä§½ ï>âÿÒÂ)¹ñßî¡CJ—†µ¡ÿÁ\³—Íõ–UÔ<¥¡ Û²ª¤^Ì>5n³[á!%#S·[z¦¡¬`âÂø`îú…E~-ÅäÚˆ+TTÍ㻃³b«oÉξÉIyg)Ñ;Ív3\˜—Ü¿'©Ÿä^¿‡E®^VU Ý’dó#í„B~¯Ç †GdïÇí µŒ¡úÒ s¢ùæ¦Ì°¿±›X®‚­:·zµ­>mãÜš@»ÿçl¬ ìÅ¢$X\Ý:¶@»‡È§´z\Ë=÷ÇÁô½zŠ2e¶ûˆ”U(…ê/h¤t)ŽN£¥=¦s+~òI½KÉ•-¥©úÕ=ÑÔ—ñªr%½*^± ´áªâÛ0²hµX­UàŸ²r`ŽÕLŸX´HÇ{Uo¦ôf™ý%ñ3*× Uª™úCžÑ d ô«;€Ç¾¬¾f 0§Ðx8ˆÞ°öÈ+æ|Ù¼gΧgÌc² íÚd£ŸZ²ÃÈ’Aòôâ3ÙáÊ’û1®öUèa Û!±F~(>£Ýèwbþ?\YÔýSÐñ¼w°·õz 2 ßÿÖœ ŸºáÇh`ˆÑDwCŽÌ×›£üÍçÅJÇœ1zA´ ¶~hߎØÜ}ú0Æ‚…zá§„}l~¬Q `ßm4Ilçôã´@;B;õãr¾?ÊÞw“Ú7ïÙÞûoût°n!pW"ðÍüDàûCc¾õÁ*NQ«1‘öA®î…¯Ÿë'¨ò÷‚¢»ÍÒCŒ’×ôfm bÕ.ji‚« >£yæ>¼kévÖ)äý½|R\»»W*å_'m¾ö•œó9ï:’ùÌ÷ër?ä·¸6 ?GT}@ŽV@Ïټ̰Jå~1—†Åù™ÄSð,ÆO ^îÄšÂæ£ÿò(ËXm÷b÷ÔÇõ‚s9ïßιœ#9Ïáñ}eï|­¹a¹ÊÃ'¨Æ¾×ÀQØÆÙy„ó°ŸcmM!Ÿk ΫùÌSäÃ8Ÿ5‹¦cßã5UÈo¾ON-å8ëãuÔ/?àxÀÎ㎈nÔ=¾Ÿðë§µŒ.™Wä_U^áZŠ{¨î r­:‡sð9]VUTdl@>å>Š*T-šF™ØßVÄ÷'\mœ»a!ƒÆfÔIÌ5"²Â ÐZó8݃9cÕzÃ’u쿵‰¶p.0‹©Æ>«ˆó.pÍ”]ïËk=m1Wa›é]ìå ŠAšüÇAÍý¡Lãµ\Ù Ë÷xŒÇsÖË ŽQb,˜ÃêMÁkž ­*X«‡.¥êò ÃJ£Ó®·äÇæ`yÊœL))käëæ“òGª^Gi†±•&éÝòœq…î`Þ»vÈËÆy’y¤0ï¦LœÓ:¹C¬¶ßê}!-¾?üÞ`Ž˜oÆÞjÎDZŠwÚ} 1…¾m6Qµ±¨”gÍ“Xo„Šw¾OÃŒyÚ¨T÷EÆÞ2üNˆ¶áÜ_DNç;Æ>àEhO3Žà^uSrÉ W¥üXDÃÁ¹É±ú%ÁSYj÷Û8ƒö~lŒ¦Ã^…úpí…hO×;ŒÇôšÂï@1R¾m”¯¦\g~ð Ú“L‰â•}XàÍí–©rÑÿžÈ Ávž©Ãx¨£€%×ù[ÈϬÛsÀº×÷£ý€ã½z0ÕÞ‰9OaFÈ,[ÿkŒGûÚv´ç@Þ ¹(±1ºû€þ1Ùs†ùyÝ»äÿ/o\nRÚõgLLʯ¯«)ßD–Ý”LªAÎùÿ7éÔ–¾Ò‰ƒSGüùw5/I‚(‰àÜÊùó*ç6ΧœO©ê8ç5®xÓC†‘ÇNü‹øj Š"»Â÷Ñ3Ý<Úy€0,a.½ ‚/˜†•œq³;¶¸è*è¢F#ƨÁZÑ­ZÖ5 ÖÆhÕ&Ùd­’}E­-†Vdy¸I%jvó#[µ1F*EU~$ÄM­ñGV!çÞ!k¥*?ò/=s¾sï9ß=çôéî[ÝâÛ ö3¾—òýÌòîØ÷ Ï^è3ùw]ƒë_ ¥ÂCÝ22"ÍOÒÉK‘H¥í-Ú,^Z9ÂæSK*Çè$¼!†q3+WxÆÌÆÆ…¿&9¸´¬´òÄC÷A£ã¨8¹êRqYågq:>„ÏXÏÈddþUrÃ\îÓã䯥¯ø*í¡\Ȱ d?E6À‚b€Ób´ðm1*li"7ô‹#DõDM°R7Þg—Ù$»Íf˜e-û:ëbße’Ä2™‡U±0³Ì°Œô³QöF§wäõÄÙÄ@b"!% ãŽA^7Îc†dn©ÛBºI7%6Чè=zŸÎSé4í£t‚JMt+í ÝTê#d‚L)阢RÒqšJŒ–ÓÚD¥î›¶#Œ:nØ$°A`¹@&Ð&p^à}Ž´ÝÔ¶‡Üåkû@îPèÅ]èÅ]Ô!f}ä&ØoBl€ ¤d+ˆDîÂï&ün@×21|¸ L‚²³áÎs:=ä ½øj@*~F`GÒŽfsÄ]ÃÇÔÏ©‡Ž©!•T#8\)Gü5z¶G=ïQèQ_ó¨u³G]åQŸöðEÏ!7ÐqÄ×¾'ð;zž[}èVÿîVÿäVïºÕÝêA·ºß­ît«Ínu”d¢ðÞÖÓêµ4 æÔ8Y|Ù¶¡”Q²…!p½iä±8©3 *`ËØ5R‰ ½%e&{ƒ…RH b¸æ^Ð@/v•c†9Ãû„Ý|_—gúf Z®é Ê2µRÇ¿0 7¨ ÓxÔ¸i$Ø5<šÌ„‡M¶ "â+ñ$ÌMäç‘ð òã·@ÇLÿ(¬0ýýPþïC»ÀüsÐ@Ÿ7µpÿÔÔªA½ojAPïšÚHñ¼-ðP/óÄ×ðadˆÈ‡x¡Åø`òÜp'dÞ zÿBÆÐܾ'yNx·é;ÊS·#MØw  ÐÏšÆÓ¼ò•0æ¼ ò‘~ÐuÈ'浦¯ Šñ›Zd÷Áç+·VšÁ~˜2Hz¦9Ée›Ú³ fu”b‡AYMÖÊbú€BÃ@ù<­F°®`=ƒÝ÷•°¿AðYm5›†sºgÄ16Ù€\8Äî°û½ ^aŸúO²O´8Þ`²ß…JB}dŒòZÑ-¬›çØÍ~9Mök_¤±}AvÝWÃÆai¡ÉFƒ£ '_Âû€|!Žõá½ì=-ÁÞ­Žã·t{Ní'ÐúïUÏÀf— óQ­†uóåWØË¾Õì0g^aß6ŠØ·  ‹ÚçÙí$Ûækf›‚£ü Èp€m„r<Ä^„slJf[í?Ç¢ÕÙdÏã„ùÕ`‚E´el%Ä+Ô³X£ÑÌBÐ Ýw’Õú÷²2­‚•Àjó0óB;xQÅp“ñJLöbàÙˆdü Èq½Lþ£|Q>'oWÈUr…¼T^"Êùr¦âTìÊ"%]IUŪH Q’ŸŸÖKl4™V;WV‰£$Æv¬ô<ê#½°Y÷¢ Ë Q]× x£qy¾9VãÆäµ›[1þ~+ŽÆ&w èöüØÃuqœú¦˜¥ ÇœQ]ßèrŒœ€»b}KÏó=¹1çÊ–Ø­j{Når]ßsªµCøN”u¨ÁÕà\á¨]þ/°m½O—÷?—7/ö£èº–ØÏòZc•|0Ÿ×­Ë©e„œ ½‘ð9ÎUkËö‘fnÇžp+Ð* ïs˜³O$iÛñ>Nƒ{n» ­4ØEŽ ¶‡ã‚F¶ Æi`ßÂip•“<¿‡êÂ)o"¿àù•7OÂÉ´:ª‹„ëêË=u‘TwO‹¤éœ4 Åä”AgƒA§p/âÖ’îµI÷Zá®}â®NºÛ’î6p{ÿ/ÇÎÆÿ™Ù½®G×¶ *¨±uåKIeß¿BÜIŽóÏôä^ŹôS”æm¥4ÆÒ QCƒËk¯Çåјºžßnó±ÞÆ/ÇÖô˜¨2Ô\¯ä^•¾(¢¤ƒY]p•†JCÜO w-³mÁåz%¨Aî‹ .;˜ÛÙ†?Wpty#á®®ƒ âÐóÎNoĵ|¤[Ð(_š„Ía×ÜzIJÙQ“ž™)•*UÅJ r¤dàò Œc¸HÁ;¡˜Ü©§Y7nMëH#i9ŽFð^H ÛŒÙYûŒýqÛ \ gmíò ܆e«l%ŽÌl9ªþ€ŸqžÞrf¨É1÷ù¦oÞî³ì ´¿ý¸îŸ®×áoàöoýu>¤ð|ÎÜR59PT·åJ)A‰¦àT”‘êH…Bd”Š;¯¤ãò¨/N¶Ë›Òqú©Œ«8?ãxÐ6 µØ¡¦'õЀßï 8««Šȑɋû³³³ïbu¸ÉŽÕM»Û7w$ÐüK¼ùWO_ø°vîÇsg§nýET¯3­äd)\›=™¯!h ‰Ó“C4Gêí=0fg ]ùìòŠ MÖÖU+“¥·ÿ®ìRËj”ߠإ÷:sòƒO—P¯ž’^U^¡g,®Bº-³Ê]T\¼Ä™‘çD®¼<”ý/ÆË5ƉëŠãsïØ_3Þy®×c¯3~ ^³^?Yƒ „W`Y`éf—ÆA<—ðÞ4)%é—„%! 4•h«µ„ !@t¡qD(D´j!(•ÚT­”’¦RUA…£(¢I)k»gÖ€Ô~iµö¹_Kë3¿óÿŸÄe-jóE|Ù–LhѨ_’y¹Ì;J’$Ç#máeZ„ˆú"D„àH¤ÀmV©;*Kl¢Ïy&Øg)ûRiÂrÌrÙBZ<)I’ºmùïÉHª6¿x×/%¥’DJîJ>§CaÁùª¢÷ݾ{ÛX°W¦Ò—¬Ôt¶N@>ÇÍ]HןgÜ…¼w[Aw d‚­!øÂT‡#2è® ¹†^F›·&œîR´ £ƒ-Õæ•Ÿ2OµyçS0Î £@JE·X¨ÖäRÙlŽËfÒZÍÂ0PIŠ=)cGC3±<Ñ·aÇÐÙ ï¿~øóÆÕú 犺ò¥Ú»Í<ðæêµ+rçN§Úÿ|fîfóN>8´ðÈšXæÄö‘kÕWZOÎùŽê2Õ?Â+.,]‹qý'õwð½×{:fP÷<ó=xj½ØRÞÙ¦Z5uPÌ™â(†ã°Ð5}šžHvé™d6ž›eÎ[³tV˜!çs3 ÅÞEÔz0L ËCÞUÚªìæÄ.q\<æ=¢¼‘8‰ßqýˆ9é>é=®üØw"q²÷²û²÷¼rÞwÝý+ñ—ÊŸØSm~<Á´¥]0–gÁ¤ó ï#íÈŽi¹™…Ä n…UÂ>EIf§+I"ß« íR¯Ø¡x»´„Ò•ÍåªäÆrFÕx5—Wµ\>—Íû)+OQVJËæòæ™IožR­ª—€þ‚RU-L‡iA¤#ì‹§i¿ ò¢Aœ ˆÉ®.Eñb–a u³ ŨÈÒU< Z) gŠ´ EÛøòMF%¢šÞ"©ÈÂ_+Ž» Ž>îP(kÑZÔ †x»¥‚7œu+|:n…‰qì?ûâ9 žkø‚ œÛ\i+ ´w؃ pIL‘yAvŽBµùeY‚‰]¶3%Âø­ØÈ-•³^„$-/JT 7 ?€3 ‚†¢P$¡{°k ƒ9Q”L·êì3òþÇä9ƒöú6{ÿҮοFJCvü‚½Lx¹À“h͈ƒÕ3vÔ´÷ªÝ/Ì®üáí¥ƒóTs!žX‹>j¸ÔxRU¬-%…j0Eª*çIv7ÞG­æÚ½¾iðè̶/=øAÃñõ*0½æE‚ >†cèÆD;bÕæ˯C¹á¤3Éq‘*:áið=BFÌ«}x!µØ¹˜égçç ‹Ôb ~Žû„úA|_ ¼íÜ5;œíB»h¢íNZ4‘”I!ŽU¸Sñ»¬NÅåíò©aYâ9+eú£Ñ˜*CSè%^D²gµú9žç8#d êxžo1Æ«áðÔ|]2¶dYBþh•|³$HŒ ì÷ù@"†qYe.å9É/'å~™”YëE¸6– ®yågmö’ŸC\ç/ ZXЉªèÜ»I±$ö‹¤X%§—é8'É'ÇmU9×b m ”kžöÚ¾:òÈ0«§ñ!ÇX®¹ -š FÇM0“u³1u=àv `ó”fÞÀ¹Tø(·À-ÛíèZºÈ_’ÌD¥…mþà–CÐöĨ$ ‘èá Ì!M åHj=~ }âX»1ü/¹8D×¿éØ¶)Üœüglo£Îΰ5Êôr}I©ñ¹ýó’É'ÉãêÊ}“GWDÕVÕ1rÇý·L»'Çrjj& GúóÏ’ïòªÐ{lk~f¾lÞ ½C€+Û•¸Í‘öªé‹ »# W”åvز ñ›ðnç¸ÏìÎXIO† ¥>X8^ ·"S{ÐßW‡½ OGÚË´$§žÐÞ­†¿~¥ë£}·ÁgGøQª•jFFŒÊ45-“n#zR†o”… º0†Tô¤rY0| —_ßÐ@g;vs¬ñók?8Û¿c÷¾m›¶÷ýðƒ‘Îý·¶Š®"fß§£õùÌ7Ì3 ûï5VÚûü¢ïâîO^ƒî¬yÜ@ƒJòA-qåu1hÅ3…PGÈ›w÷ó±h‘wap„Ú$ì^ŽÒG…Óôiá=úCú&ÍþX Y]´b¥E¡†WäR¬L,â…ð31¨Ã3ð.¹Dn$ÂV ÔB*  µäŠGîóç­M¬”ÐoF~Rú‰{Ý“Z ât •I ߪE‡_d=YÛ‹ñ*ŽMd.}m4ä5·¯ÖÒ Œ­­pçn­‚ØJín`ïTîB"aÚªùótw{7~Pì„QídH‹@!§²Ûj‹BÁ0¬©×ãí¬à?ÛɆuÎtj4`÷Æ._úÜòïïxö櫃ûz0ìÑœ+®_÷ÒâÆ?zÔϯ<ñÚ@Péò›·4Ò[g?µq×âÇþÖ‰5Ûªz6ø7ÛåÛÄ}Çñÿßç×ù?Îö\¿Îg;wgì`çÇv| y§„š¸´°BDÛ”¬¬a¤ˆÒñk:©ŠÐ‚”%ÚDF;0£[5­Ò¶J“26©bS&EÕÖ6R«Ehtàì¶ÓÂ4YöÝù%ûÿù¿Û#¯ïè< µûº¦îi‡¬ùÐÚ2vû`AÒÒ B„ijc§ÿ:£Ä<Òó~.6¨Ot€N¸%0L ëOÚNŠçÙ·ãÄyלÛ&ü6%Kú½½FiÔéP¹™J%O²V’dÙ<ö³ë@͵y5›òX³D:FBBŒYbMì/á(PÂkÀȵ_ýÜ’¼JB2¯è('Ȩ~á„N¦–¤ÉZ³Ï^î·«¹Ñb!u"§q³Nä4×è(kèή¢ëó•+Ë¥ÚbÏVŽÿ3g”f—‘BJú°ßCµ˜L‚¢: lë2´Q…˜F]vŸ-óBt TŠgd‘¢è„&”å ^7*4 ÝùÀŠ™q‹l¥õr.™öØÇFê[†¶ýäûŸ«m2ù{¤ÛíÝ|‘±…76Ö<½õpoQ£'=[Éc‡Ráàþž{£S»ÎÂ/5ô^èñ;\õ…7N×Dâ#ï#UkËÊÒ‹Ò°Všª²V¥2ñ÷ãù:Uú‰P8D˜e³\–oÈÑØapÂvŒ;ÆŸLJOr“ü[uWàœeš›æçêòð†â¦e[ào¦~gùØô©qÅÄèYˆ§!ãC1¡ÖU¤Ã-4±ø¦.è nã9Žc1x–´²²±,É-ò‚@t³[S+§hZ'¿–ÕI:…n¶‚ 32ôÂ÷ñŠ%¼e·K°0þfR™+Ür›p3ÅÖøÏÎ¥*]G†Z;÷ÿé¥'ƒ™`Ç¿Ë`ÓÁöÂñ¨Çö^ôÙ¦ïǪ‘ÿ\¦“Ù¹År/[xþ¯íâø·ß†¾z=Âý¡Ý‡3¿—©õJ…#Ç£=Oƒˆw5Òë)¤W'O¥tÚ=èý9¤$*4Vƒ©Ý0 a´ ÓÆð“Z¡Uखĕ¸Vÿ„OñÄEe ±@ÏæïÝ,¨¸Í>£Ê£ÍcÓÚE\"*âøgzô%É£¤ŠÁž£ös Á(ǹך5£>dÍÞ6Â%#42UÌ~9ÔWGåìè’]r}N¤Ð; è#Åyƒ’óMþÊkè³|Iž£«<2Ô¤J{$[¹B&s‘¹Zɤª£È4G!úÖ oôGú›Ur:X•à¨a>ÐÞr6ç:øññÙ£·aû•íý\ÝÂö—w<›krÛ£é࡮󩦾 g^™žm¿íδ7?}Ðeå*Â{¦žÍã`kç -JZç8hÛ YþŸKõD²u„¤>U¥À·êzží"5£YÚ®D¿‚¢4$å¡TÍL§žËàͦ ÀTx*›ÙšQd2L5–‡û$/œ¨Ù\­aˆÎ”ÓØÜÝÍÛ,V›Í²%速eБ‡v)ØX§’×K%¯—QåV¡3Õ.•ʃ–Tk*¥ªrû‹m°íL#·4Á´ä ÖÕEƒo¯±à„çš1ì+ÈÅ4“‡ªu¥Éz‚å«b¹`v¨óœöìùõ+îN¡Ñ¬7VÆþаsð“/ÿu°÷À»Û#»†?z£¯Ñ7Sí{’\•+¹],ÝÕ|êÜ‘—öþ° ÛýBªfð!\볌dMرmGnu×ugö…|Î@Õæç7o¸´Û¢³zª?Ù[t&¾Ü-ˆö±ý›†3bKlk«JòÕøŒô{Ñ[Ïmóìñ¼ª<©Uk¼°Ÿëã»°^“Ýo:BÞ$HE²±l¼´{Z¹f¡#ü>ìaƽßñ$ÎxÆŽÆ/ç=½“±Éø˜…óÞyß\ørâ†a!¶_J„4÷jÑhâ XHh6†!Âñ<š³o6èìì‹ ¨ÅÌâ\,6Á ÑÅXy§¸\ €¬ù2b‹ñ‰š1µFàut––h-ï.ƒyáCŒ+"˜ ³®_`(æá5©"òwÁ!ºhDÝ·nbíåz)ëºkí Þ”.÷ËqÓŠPT3µÛÒ$ÏKï @­åª«%ã=a(™ïhîey;A”•bIÎØ×FüHÔZÊÞ«Æ0¢ó`Ù°âRáÁ‰ÌàëéX»ý5³×ë=~Üì§¹¾Åþ]½™ðgÛùoØfµVŠØ¥ypøÃ–çZ»$±§Ð_kÁ:GÂà¤~°_Š =p^°æôáÂýÂ_”ûÛ܃ ¥ß†×–{Ð> ßþé=½Îœ¬È¯Ý“jLæzŒ¶Ð åZ݇ܯqçõóúijš¾Ê]wå2Ф‘rè°»“8Äq£“^œ”½“¤jc ƼF½ž÷:­^™–×ëTß(‹Á‰šj%j’š¦”T^ÁK6êagUÈkêF%ˆvV}‡£üzç/õšÕ•, Æÿ—€eYËj9ëESI²²H-ß,?­x|íQîý±¾¯?“îï;ü‘™Ô™Íá¬oj¾¡Ë|Æðm°W5ÒŸÉôË÷Büa2c!,FöYká~{-›„kf( %ú‡Ò&{+¬—¦ÈLÕ«JÅO/×-b„‡¢âK¢’µ'ô­ú–ª¡MC±½ÚsÚ Âí¼pð$V(íVûÙ¯úØ&Î3þܽŸ'¾³çîŸíØ1NlâÇvìàk€|ò¾ $+ ÂWG?€…–AûÈ„Z¤­jm‰ÔNÂÇ2@£Zë4iª”Iø££@'Š´u›VÅÙs>éX;:µÿùìß½Ïݽwö=Ïû{žßC—P>; ™{.UF•A@ÞT!{ <ªSeÙ@F„‚!õ0 úªt:Wí‹D€ 4J ÇF±åh)ªç 2âªLÉc$ X‚Uð½ÐhPŠÊBP£±b³çdçLbÜÕx¡²BU˜3™!>ˆx_„5šQ)‘ίÛw@¦ræMß<Ë™ç¹Æ°òph;͉r'Ÿ˜íL+[,žù"æ­Kµß£‡¼È’s…È|¯úò«¹D+¡¬+­+ Û„ÝŽC¯ZYRáyšð%³™ŽT•¦Ò)á C›…@aá=³¤÷ðzïÉ´ÙsȲºâÙ;û(Š®Dý}N§£Y~ŒŒ*1ÿü|£4.Ž‹‚É-•|ùlƒz‡AuѰr* Š¡Ë°Í0l8e¸bÐúbôEêȤé|³O4wŒ4y$È5Ok’"˜¡B-*äÔ'H• “éÚ µZÏóÿÄŒ4sŸ‘沯­­Ý{•Mj(@ÍRV_«­t>­ËýéŽL`‹1Õ™¥m-Äð<”‚쪵¶¼ÿ`ýºÞßžþÀ©ˆ8f/3Lý%WYá›,âÝñ'êñº5áj¿×U^G6Æßèšÿ“þÔÇ]5‰ç¾]åöåû|ô’ý¤yß,äNùç{7ïZÜ`±7bó¢LŒc ‹©e¡¥4—r»*½«É*©ôôöJϒݶ1ú=x¯8¿PÀ.Ø‹DAˆ‰R¤ú[¥bXW^E^2ä‘ âkr\ãœÛår·ÄâVÌ•DÞ2¬§Öë¯èÿ¬ŸÖ3úÚg€Q,ç£JèTºíº'½%JQØP§Ffòödçm~êvð6ÅßÆà ”½R.$õŠÕ;“jÉ®yéÅaƒd²V+üÄDg2ù0yQf!aÆ|uȤµLZ~‚é;gg IÃ)iKÚh´Ñ˜9/«Ž¬‰"…ãÓ¿˜É`–êLSêFÎDØGÉŠúäØÅuÕuH…ÓWZÊr…}5‘Oß²X‹#*D†§þ@ýl}¼.Þ]hÉ×åu^?öGúX‹Xä4Éõ¥ÖïýÌQ©¿‚œé›£ÖDÎØôMå—(³Çì´›vÉÍyøG‰\IW’j^¡²€›Ï/•–ÚëåU°Z\+­µ¯’{¡‡î!Ò€½ËÑ+ï¢w‘¤ìßs ïsG¤#ö!zˆËù©ýmrJº@_ ×à*¹&ø|‹¾EbòÀåš,E`—DlRZísbiÃ.j\9j:n¢MªLp²],@P´ˆÚJ±%MŠi¯3¦‹t‘êBõR2ŒQõ OYŒØ"9KEϼώØTŸ[œIoœUGÔQáœs"¶‹NƒM°9ªl 0?)\&Þ&ùI¤¬Ú&ÌÐv‘OuÚ§:Ãöçù;b®üf:ƒC*§¯>¤*EªXï !ñPÅyU®ÒKÚ^òîá-F³%Tç]x²mA«ýõ— OïaަþºsêrÌ‘o5yW>»ma´f--·Tìûª†é©ò#ä[n(QH A±ÆP#&ì‰Ðb±Á¿F¿Fì{üωƒ5§k8g+/cEʇ{Šõ”Q#ŠËÅI¬ÑÆùK=åM˜nNeEˆaʲ¥\¥žäÚ8:Éý˜âŽs§¹w9‡a9Ç.õPž1ú¾"•“á§Âtex ¼-<>Î Q[Ï&¼›´–kâ>¦¾ÛZrœèT3œÈ´Sè¾ä èt»…GT¦Å‚N«/ÝKY±–«<@e–¦ˆŽ¥Óý®&ÖÔ†J«÷¨ˆ öOÈ8ñqEF›þ;‡Ýbs¤zYëá3oo9Ø $–5Ï©«òàc1Þl(q”›mdášPYãÞû©»?¼Ó0Ïßàw…[–'æŸù05ñ»ÁíÅÖ¶êêEJ0Ÿ¯Ù«¬|ÚÛòx°}÷ÉAå"^û\ÿúA†þ7tË5èG5^0Æ!ïäÿSï#ð+Ì¿Ö`EØ®öÇ!þ Àî(º¡A>¨ÁÕö8Ü׳È"‹,²È"‹,²È"‹,²x Tºo-¢Z”¡ƒ'ÞŒy¸ãÿÛß#•®ˆ}îò€Æ&hi]¤,kJ5¿õä¿ýn áÞ‰ïFÀePõÐ ‹¡ : z ¶ÁØÏMOã¼Ò‡×—¦¯o€°õÁõé[_üÉxÿË60ý·/¡‡ÞÌsxqOeÞÀ‹ÍÖ¡Õ F˜1à™Ùøï5›Æw{%cœñFÆfо›±uÐ@UÔ?U߸¨)¸¼KÏÎ%=»Û¶tomë(¯ؼ¡yW÷æþ§/ÿz¦ ŸB4Â"h‚ ,Ç¿ºݽ–à~7´Ãw£sÕ@´ã¹ð lÆ3;¾Òj¸ð¾ ÐŒAêF«žÆð}µßÿ¦Ÿ¢Fü>…ZØ9-*(À,ü÷8ßc‡ ÉŒ€2,@ˆ£Ò˜„€Úá=ÉØƒ0ÝVr€Œ9ÃáÄ\ M9LÏÒ»6'÷ÄóÛ|åä«^,¿g ˆÞzr•Êïù{8—q8¹ ´6¼åo+ endstream endobj 331 0 obj << /Type /Encoding /Differences [ 1 /bullet ] >> endobj 332 0 obj << /Filter /FlateDecode /Length 208 >> stream H‰T½Â0 „÷>…GCÚÎUX:ð# ìiâV‘ˆ¹éз')ÄKöåÓ-öÍ¡!@\Ø©ô†4ãè&V† (AÖn©ÊJ"Âí<´ õª*×(ŽgØ´³íÜs—oAœY#`s+î8h'ïŸh‘äP× ±ÏÄþ(ýIZŒòŠ.ób5tG/²¤¡Ê‹ú]ô¿ö!ºþÝþ¾Ve^–u‰–à´É×[MÌ1Ö²î’(e0„ß‹xç“ezÙK€CÈi? endstream endobj 333 0 obj << /Type /Encoding /Differences [ 1 /square4 ] >> endobj 334 0 obj << /S /D >> endobj 335 0 obj << /Nums [ 0 334 0 R ] >> endobj 336 0 obj << /Type /Pages /Kids [ 357 0 R 1 0 R 13 0 R 59 0 R 73 0 R 78 0 R 83 0 R 86 0 R 89 0 R 92 0 R ] /Count 10 /Parent 337 0 R >> endobj 337 0 obj << /Type /Pages /Kids [ 336 0 R 338 0 R 339 0 R 340 0 R 341 0 R 342 0 R 343 0 R ] /Count 70 >> endobj 338 0 obj << /Type /Pages /Kids [ 96 0 R 99 0 R 102 0 R 105 0 R 108 0 R 111 0 R 114 0 R 117 0 R 120 0 R 123 0 R ] /Count 10 /Parent 337 0 R >> endobj 339 0 obj << /Type /Pages /Kids [ 126 0 R 131 0 R 134 0 R 139 0 R 145 0 R 148 0 R 151 0 R 154 0 R 159 0 R 162 0 R ] /Count 10 /Parent 337 0 R >> endobj 340 0 obj << /Type /Pages /Kids [ 165 0 R 168 0 R 171 0 R 174 0 R 177 0 R 180 0 R 183 0 R 186 0 R 189 0 R 192 0 R ] /Count 10 /Parent 337 0 R >> endobj 341 0 obj << /Type /Pages /Kids [ 195 0 R 198 0 R 201 0 R 204 0 R 207 0 R 210 0 R 213 0 R 216 0 R 219 0 R 222 0 R ] /Count 10 /Parent 337 0 R >> endobj 342 0 obj << /Type /Pages /Kids [ 225 0 R 228 0 R 231 0 R 234 0 R 237 0 R 240 0 R 243 0 R 246 0 R 249 0 R 252 0 R ] /Count 10 /Parent 337 0 R >> endobj 343 0 obj << /Type /Pages /Kids [ 255 0 R 258 0 R 261 0 R 265 0 R 268 0 R 271 0 R 274 0 R 277 0 R 282 0 R 286 0 R ] /Count 10 /Parent 337 0 R >> endobj 344 0 obj << /Dt (D:20090210093019) /JTM (Distiller) >> endobj 345 0 obj /This endobj 346 0 obj << /CP (Distiller) /Fi 345 0 R >> endobj 347 0 obj << /R [ 600 600 ] >> endobj 348 0 obj << /JTF 0 /MB [ 0 0 595 842 ] /R 347 0 R /W [ 0 69 ] >> endobj 349 0 obj << /Fi [ 346 0 R ] /P [ 348 0 R ] >> endobj 350 0 obj << /Dm [ 595 842 595 842 ] >> endobj 351 0 obj << /Me 350 0 R >> endobj 352 0 obj << /D [ 349 0 R ] /MS 351 0 R /Type /JobTicketContents >> endobj 353 0 obj << /A [ 344 0 R ] /Cn [ 352 0 R ] /V 1.10001 >> endobj 354 0 obj << /CreationDate (D:20090210093019) /Producer (Acrobat Distiller 4.0 for Windows) /Creator (AdobePS5.dll Version 5.0.1) /Title (Microsoft Word - SDK_manual.doc) /ModDate (D:20090210093019+01'00') >> endobj xref 0 355 0000000000 65535 f 0000662609 00000 n 0000662831 00000 n 0000663000 00000 n 0000663182 00000 n 0000663375 00000 n 0000663540 00000 n 0000663707 00000 n 0000663883 00000 n 0000664054 00000 n 0000664224 00000 n 0000664409 00000 n 0000664586 00000 n 0000668955 00000 n 0000669428 00000 n 0000669586 00000 n 0000669744 00000 n 0000669902 00000 n 0000670060 00000 n 0000670218 00000 n 0000670376 00000 n 0000670534 00000 n 0000670693 00000 n 0000670852 00000 n 0000671011 00000 n 0000671170 00000 n 0000671329 00000 n 0000671488 00000 n 0000671647 00000 n 0000671806 00000 n 0000671965 00000 n 0000672124 00000 n 0000672283 00000 n 0000672442 00000 n 0000672601 00000 n 0000672760 00000 n 0000672919 00000 n 0000673078 00000 n 0000673237 00000 n 0000673397 00000 n 0000673557 00000 n 0000673716 00000 n 0000673875 00000 n 0000674034 00000 n 0000674193 00000 n 0000674352 00000 n 0000674511 00000 n 0000674670 00000 n 0000674829 00000 n 0000674988 00000 n 0000675147 00000 n 0000675306 00000 n 0000675465 00000 n 0000675624 00000 n 0000675783 00000 n 0000675942 00000 n 0000676101 00000 n 0000676259 00000 n 0000676423 00000 n 0000678628 00000 n 0000678874 00000 n 0000679033 00000 n 0000679192 00000 n 0000679351 00000 n 0000679510 00000 n 0000679669 00000 n 0000679828 00000 n 0000679987 00000 n 0000680146 00000 n 0000680305 00000 n 0000680464 00000 n 0000680623 00000 n 0000680787 00000 n 0000681859 00000 n 0000682034 00000 n 0000682213 00000 n 0000682390 00000 n 0000684030 00000 n 0000684104 00000 n 0000684286 00000 n 0000684445 00000 n 0000684605 00000 n 0000684794 00000 n 0000687505 00000 n 0000687660 00000 n 0000687836 00000 n 0000691636 00000 n 0000691791 00000 n 0000691968 00000 n 0000695031 00000 n 0000695186 00000 n 0000695337 00000 n 0000696882 00000 n 0000697057 00000 n 0000697216 00000 n 0000697393 00000 n 0000700037 00000 n 0000700192 00000 n 0000700369 00000 n 0000703160 00000 n 0000703317 00000 n 0000703482 00000 n 0000705781 00000 n 0000705939 00000 n 0000706143 00000 n 0000708848 00000 n 0000709006 00000 n 0000709185 00000 n 0000711757 00000 n 0000711915 00000 n 0000712119 00000 n 0000714920 00000 n 0000715078 00000 n 0000715257 00000 n 0000717627 00000 n 0000717785 00000 n 0000718004 00000 n 0000720470 00000 n 0000720628 00000 n 0000720830 00000 n 0000723786 00000 n 0000723944 00000 n 0000724134 00000 n 0000727310 00000 n 0000727468 00000 n 0000727658 00000 n 0000730724 00000 n 0000730911 00000 n 0000731092 00000 n 0000731253 00000 n 0000731482 00000 n 0000734045 00000 n 0000734203 00000 n 0000734420 00000 n 0000737146 00000 n 0000737333 00000 n 0000737492 00000 n 0000737653 00000 n 0000737831 00000 n 0000740249 00000 n 0000740444 00000 n 0000740624 00000 n 0000740785 00000 n 0000740944 00000 n 0000741162 00000 n 0000743527 00000 n 0000743685 00000 n 0000743901 00000 n 0000746868 00000 n 0000747026 00000 n 0000747177 00000 n 0000748842 00000 n 0000749000 00000 n 0000749164 00000 n 0000751143 00000 n 0000751330 00000 n 0000751491 00000 n 0000751652 00000 n 0000751856 00000 n 0000754834 00000 n 0000754992 00000 n 0000755170 00000 n 0000758231 00000 n 0000758389 00000 n 0000758567 00000 n 0000761280 00000 n 0000761438 00000 n 0000761590 00000 n 0000763479 00000 n 0000763637 00000 n 0000763827 00000 n 0000765536 00000 n 0000765694 00000 n 0000765871 00000 n 0000767926 00000 n 0000768084 00000 n 0000768262 00000 n 0000771289 00000 n 0000771447 00000 n 0000771637 00000 n 0000773904 00000 n 0000774062 00000 n 0000774240 00000 n 0000776557 00000 n 0000776715 00000 n 0000776921 00000 n 0000781407 00000 n 0000781565 00000 n 0000781813 00000 n 0000786561 00000 n 0000786719 00000 n 0000786929 00000 n 0000792390 00000 n 0000792548 00000 n 0000792783 00000 n 0000796461 00000 n 0000796619 00000 n 0000796840 00000 n 0000801332 00000 n 0000801490 00000 n 0000801725 00000 n 0000806655 00000 n 0000806813 00000 n 0000807034 00000 n 0000812240 00000 n 0000812398 00000 n 0000812633 00000 n 0000817215 00000 n 0000817373 00000 n 0000817608 00000 n 0000822380 00000 n 0000822538 00000 n 0000822773 00000 n 0000827901 00000 n 0000828059 00000 n 0000828307 00000 n 0000832898 00000 n 0000833056 00000 n 0000833291 00000 n 0000838265 00000 n 0000838423 00000 n 0000838618 00000 n 0000842862 00000 n 0000843020 00000 n 0000843241 00000 n 0000847274 00000 n 0000847432 00000 n 0000847653 00000 n 0000851761 00000 n 0000851919 00000 n 0000852154 00000 n 0000856101 00000 n 0000856259 00000 n 0000856478 00000 n 0000860567 00000 n 0000860725 00000 n 0000860959 00000 n 0000865243 00000 n 0000865401 00000 n 0000865622 00000 n 0000869324 00000 n 0000869482 00000 n 0000869717 00000 n 0000873349 00000 n 0000873507 00000 n 0000873754 00000 n 0000877787 00000 n 0000877945 00000 n 0000878153 00000 n 0000881313 00000 n 0000881471 00000 n 0000881693 00000 n 0000885437 00000 n 0000885595 00000 n 0000885817 00000 n 0000890019 00000 n 0000890177 00000 n 0000890385 00000 n 0000895806 00000 n 0000895964 00000 n 0000896172 00000 n 0000897662 00000 n 0000897841 00000 n 0000898002 00000 n 0000898194 00000 n 0000901056 00000 n 0000901214 00000 n 0000901380 00000 n 0000904519 00000 n 0000904677 00000 n 0000904843 00000 n 0000907995 00000 n 0000908153 00000 n 0000908306 00000 n 0000911536 00000 n 0000911694 00000 n 0000911903 00000 n 0000914576 00000 n 0000914763 00000 n 0000914972 00000 n 0000915180 00000 n 0000915358 00000 n 0000917429 00000 n 0000917608 00000 n 0000917769 00000 n 0000917961 00000 n 0000920232 00000 n 0000920390 00000 n 0000920542 00000 n 0000921570 00000 n 0000922134 00000 n 0000922702 00000 n 0000922891 00000 n 0000923582 00000 n 0000923773 00000 n 0000924565 00000 n 0000925007 00000 n 0000925178 00000 n 0000925687 00000 n 0000926229 00000 n 0000926721 00000 n 0000927164 00000 n 0000927674 00000 n 0000928085 00000 n 0000928698 00000 n 0000934755 00000 n 0000934977 00000 n 0000935320 00000 n 0000935759 00000 n 0000939588 00000 n 0000939804 00000 n 0000940010 00000 n 0000940219 00000 n 0000967754 00000 n 0000967970 00000 n 0000999359 00000 n 0000999576 00000 n 0001005221 00000 n 0001005439 00000 n 0001024003 00000 n 0001024229 00000 n 0001052045 00000 n 0001052264 00000 n 0001092092 00000 n 0001092308 00000 n 0001114914 00000 n 0001115138 00000 n 0001136028 00000 n 0001136256 00000 n 0001162904 00000 n 0001163138 00000 n 0001176724 00000 n 0001176794 00000 n 0001177077 00000 n 0001177148 00000 n 0001177180 00000 n 0001177226 00000 n 0001177375 00000 n 0001177492 00000 n 0001177649 00000 n 0001177808 00000 n 0001177967 00000 n 0001178126 00000 n 0001178285 00000 n 0001178444 00000 n 0001178509 00000 n 0001178533 00000 n 0001178587 00000 n 0001178628 00000 n 0001178707 00000 n 0001178765 00000 n 0001178815 00000 n 0001178853 00000 n 0001178933 00000 n 0001179003 00000 n trailer << /Size 355 /ID[<249cf20073e979528f301d5873119c5c><249cf20073e979528f301d5873119c5c>] >> startxref 173 %%EOF libsynthesis-3.4.0.47.1/doc/SySync_config_reference.doc000066400000000000000000053420001226375725500226770ustar00rootroot00000000000000ÐÏࡱá>þÿ  Å þÿÿÿ¬ ­ ® ¯ ° ± ² ³ ´ µ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿ À Á ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿì¥Á ø¿åÖbjbjààj ‚j‚jæÐþÿÿÿÿÿÿl^^^^^^^tÀ0žžžÈfüb&¼À0à~*-´IÞvL*w*w*wbxÞ]@ÖœÜñÐ ¯|šI~I~I~I~I~I~$ø€ ƒ¸m~-^¬ÿ^xbx¬ÿ¬ÿm~.^^*w*w4š~...¬ÿ‚^*w^*w¯|.¬ÿ¯|.ž.Ì ÃfÈ^^#z*w- €|9JÓqÊÀ0Þìž.‹ub#zŒ°~0à~ív6Ѓ.Ѓ#z.ÒH (¦^^^^Ù  HYPERLINK "http://www.synthesis.ch/"  XML Configuration Reference for Synthesis SyncML Server & Client 3.4 Products  HYPERLINK "http://www.syncml.org/"   © 2002-2009 by Synthesis AG This manual was written for Synthesis SyncML Engine Version 3.4.0.0 This manual and the Synthesis SyncML software (Server or Client) described in it are copyrighted, with all rights reserved. This manual and the Synthesis SyncML software may not be copied, except as otherwise provided in your software license or as expressly permitted in writing by Synthesis AG ( HYPERLINK "http://www.synthesis.ch/" http://www.synthesis.ch/). Synthesis SyncML products uses parts of the following software: expat - XML parser - HYPERLINK "http://sourceforge.net/projects/expat"http://sourceforge.net/projects/expat Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd SyncML toolkit - HYPERLINK "http://sourceforge.net/projects/syncml-ctoolkit/"http://sourceforge.net/projects/syncml-ctoolkit/ This product includes software developed by The SyncML Initiative. Copyright (c) 2000 Ericsson, IBM, Lotus, Matsushita Communications Industrial Co., LTD, Motorola, Nokia, Palm, Inc., Psion, Starfish Software. All rights reserved. zlib compression library - HYPERLINK "http://www.zlib.net/"http://www.zlib.net/ zlib software copyright © 1995-2004 Jean-loup Gailly and Mark Adler SQLite 3 database engine - HYPERLINK "http://www.sqlite.org/"http://www.sqlite.org/ PCRE Library -  HYPERLINK "http://www.pcre.org/license.txt" http://www.pcre.org/license.txt Copyright (c) 1997-2007 University of Cambridge Disclaimer Use of the Synthesis SyncML software and other software accompanying your license (the "Software") and its documentation is at your sole risk. The Software and its documentation (including this manual), and software maintainance by Synthesis AG, if applicable, are provided "AS IS" and without warranty of any kind and Synthesis AG EXPRESSLY DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND NON-INFRINGEMENT. IN NO EVENT SHALL SYNTHESIS AG 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. Introduction All Synthesis AG SyncML products, clients as well as servers are based on our platform independent SyncML engine. This engine is configured using a single XML config file, which makes replicating or migration of client and server installations very simple. If you already have worked with a previous version of the Synthesis SyncML engine configuration, please refer to the (new) chapter " REF _Ref182744145 \h  \* MERGEFORMAT What's New?" on page  PAGEREF _Ref182744145 \h 12 of this manual. Please also consult the product-specific manuals (like Server Manual, Client Manual etc.) for product specific news and step-by-step migration guides. As both clients and servers share the same core engine, large sections of the configuration is equal or similar in server und clients, different platforms and versions. Therefore, this configuration reference covers all Synthesis SyncML products that are user-configurable with an XML configuration document. This includes all servers, command-line desktop clients and most versions of the Synthesis SyncML client engine that can be used to build custom clients with the client SDK. Only ready-to use, device specific versions such as the PalmOS and Windows Mobile clients have no XML configuration). In the description of a configuration option, the products for which the option is available is listed under the "Available" header line if it does not apply to all versions. Please note also that this document is a reference manual. It is useful to get an overview of the entire functionality available and of course to create and adapt configuration files. However, it is not a guide for creating new configurations from scratch. We recommend to always use one of the tested and commented sample configuration files included in the product distributions as a starting point. Note that this manual makes heavy use of cross references (references to related parts in the manual) - which are active links if this manual is viewed as a PDF document. You can just click on any of the cross-referenced chapter numbers to have the PDF viewer show the corresponding page of the manual. Using the "back" button in the PDF viewer, you can always jump back to the original page. Contents  TOC \o "2-9" \t "Überschrift 1;1;Überschrift 4;4" 1. Introduction  PAGEREF _Toc247362773 \h 3 Contents  PAGEREF _Toc247362774 \h 4 2. What's New?  PAGEREF _Toc247362775 \h 12 2.1 New in this manual  PAGEREF _Toc247362776 \h 12 2.2 New in SyncML Engine 3.2 and newer compared to 3.0  PAGEREF _Toc247362777 \h 12 2.2.1 General changes  PAGEREF _Toc247362778 \h 12 2.2.2 New Features  PAGEREF _Toc247362779 \h 13 2.2.3 How to migrate from 3.0 to 3.2 or newer (up to 3.4)  PAGEREF _Toc247362780 \h 14 3. Overview  PAGEREF _Toc247362781 \h 17 3.1 Basic Concepts  PAGEREF _Toc247362782 \h 17 3.2 Configuration Structure  PAGEREF _Toc247362783 \h 17 3.3 XML basics  PAGEREF _Toc247362784 \h 19 3.4 Synthesis Sync Server Config specific XML usage  PAGEREF _Toc247362785 \h 19 4. Configuration variables and conditional configuration  PAGEREF _Toc247362786 \h 21 4.1 Sources for values of config variable  PAGEREF _Toc247362787 \h 21 4.2 Using configuration variables  PAGEREF _Toc247362788 \h 21 4.3 "expand" attribute  PAGEREF _Toc247362789 \h 22 4.4 Predefined Configuration Variables  PAGEREF _Toc247362790 \h 22 4.5 "ifdef/ifndef/if" conditional attributes  PAGEREF _Toc247362791 \h 23 4.6 "platform" conditional attribute  PAGEREF _Toc247362792 \h 23 5. Time zone handling  PAGEREF _Toc247362793 \h 24 5.1 Timestamp representation  PAGEREF _Toc247362794 \h 24 5.2 Timezone contexts  PAGEREF _Toc247362795 \h 24 5.3 Time zone specifications  PAGEREF _Toc247362796 \h 26 6. Scripting Language  PAGEREF _Toc247362797 \h 27 6.1 What can be scripted?  PAGEREF _Toc247362798 \h 27 6.2 Embedding script source code in XML  PAGEREF _Toc247362799 \h 27 6.3 Comments  PAGEREF _Toc247362800 \h 28 6.4 Statements and Statement Blocks  PAGEREF _Toc247362801 \h 28 6.5 Identifiers  PAGEREF _Toc247362802 \h 28 6.6 Data types  PAGEREF _Toc247362803 \h 28 6.7 Constants/Literals  PAGEREF _Toc247362804 \h 28 6.8 Script contexts  PAGEREF _Toc247362805 \h 29 6.9 Variables  PAGEREF _Toc247362806 \h 29 6.9.1 Context Variables  PAGEREF _Toc247362807 \h 30 6.9.2 Local variables of a user-defined function  PAGEREF _Toc247362808 \h 30 6.9.3 Field variables  PAGEREF _Toc247362809 \h 30 6.9.4 Array variable references  PAGEREF _Toc247362810 \h 31 6.10 Expressions  PAGEREF _Toc247362811 \h 32 6.11 Flow control  PAGEREF _Toc247362812 \h 32 6.12 Macros  PAGEREF _Toc247362813 \h 33 6.12.1 Defining Macros  PAGEREF _Toc247362814 \h 33 6.12.2 Marco arguments  PAGEREF _Toc247362815 \h 34 6.12.3 Using Macros  PAGEREF _Toc247362816 \h 34 6.13 Functions  PAGEREF _Toc247362817 \h 35 6.13.1 User defined Functions  PAGEREF _Toc247362818 \h 35 6.13.2 Built-in Functions  PAGEREF _Toc247362819 \h 36 6.14 Global built-in Function Reference  PAGEREF _Toc247362820 \h 36 6.14.1 String functions  PAGEREF _Toc247362821 \h 37 6.14.2 Regular Expression functions  PAGEREF _Toc247362822 \h 38 6.14.3 Date and Time functions  PAGEREF _Toc247362823 \h 38 6.14.4 Time zone related functions  PAGEREF _Toc247362824 \h 41 6.14.5 Debug log functions  PAGEREF _Toc247362825 \h 42 6.14.6 Other functions  PAGEREF _Toc247362826 \h 43 6.15 Debugging scripts  PAGEREF _Toc247362827 \h 45 7. Filters  PAGEREF _Toc247362828 \h 47 7.1 Test and Make-Pass modes  PAGEREF _Toc247362829 \h 48 7.2 Basic filter syntax  PAGEREF _Toc247362830 \h 48 7.3 Identifiers in filters  PAGEREF _Toc247362831 \h 49 7.4 CGI Filter Syntax  PAGEREF _Toc247362832 \h 50 7.5 Special options in CGI filters passed with database path  PAGEREF _Toc247362833 \h 51 7.6 Filters in the configuration  PAGEREF _Toc247362834 \h 52 8. General Global Configuration Options  PAGEREF _Toc247362835 \h 53 8.1 , : License  PAGEREF _Toc247362836 \h 53 8.2 : concurrent sessions limit  PAGEREF _Toc247362837 \h 53 8.3 : max SyncML message size  PAGEREF _Toc247362838 \h 53 8.4 : maximum object size  PAGEREF _Toc247362839 \h 54 8.5 : text to identify config  PAGEREF _Toc247362840 \h 54 8.6 : text to identify product manufacturer  PAGEREF _Toc247362841 \h 54 8.7 : text to identify model/product name  PAGEREF _Toc247362842 \h 54 8.8 : define configuration variable  PAGEREF _Toc247362843 \h 55 8.9 : define configuration variable  PAGEREF _Toc247362844 \h 55 8.10 : Global scripting definitions  PAGEREF _Toc247362845 \h 55 8.10.1 : User-defined function  PAGEREF _Toc247362846 \h 55 8.10.2 : define macro  PAGEREF _Toc247362847 \h 56 8.10.3 : maximum loop execution time  PAGEREF _Toc247362848 \h 56 8.11 : Debug Option Section  PAGEREF _Toc247362849 \h 56 8.11.1 : Directory path for debug log files  PAGEREF _Toc247362850 \h 57 8.11.2 ,  PAGEREF _Toc247362851 \h 57 8.11.3 : select log file format  PAGEREF _Toc247362852 \h 59 8.11.4 : dynamic folding for HTML logs  PAGEREF _Toc247362853 \h 59 8.11.5 , : show timestamps in logs  PAGEREF _Toc247362854 \h 60 8.11.6 : show thread ID in logs  PAGEREF _Toc247362855 \h 60 8.11.7 : show timestamps in logs  PAGEREF _Toc247362856 \h 60 8.11.8 , : single file log option  PAGEREF _Toc247362857 \h 61 8.11.9 : append or overwrite existing session logs  PAGEREF _Toc247362858 \h 61 8.11.10 : select log file format  PAGEREF _Toc247362859 \h 61 8.11.11 : if and how to show log output from subthreads  PAGEREF _Toc247362860 \h 62 8.11.12 , : text to add at begin and end of logfiles  PAGEREF _Toc247362861 \h 62 8.11.13 : string to be used for indenting blocks  PAGEREF _Toc247362862 \h 63 8.11.14 : show traffic in XML  PAGEREF _Toc247362863 \h 63 8.11.15 : dump SyncML traffic to files  PAGEREF _Toc247362864 \h 64 8.11.16 : generate session logs  PAGEREF _Toc247362865 \h 64 8.11.17 : No longer supported; use instead  PAGEREF _Toc247362866 \h 65 8.11.18 : generate global log  PAGEREF _Toc247362867 \h 65 8.11.19 : send session logs to global logfile  PAGEREF _Toc247362868 \h 65 8.12 : set timestamp for config file  PAGEREF _Toc247362869 \h 65 8.13 : avoid PUT of devinf  PAGEREF _Toc247362870 \h 66 8.14 : override local system time zone  PAGEREF _Toc247362871 \h 66 8.15 : define custom time zone as VTIMEZONE  PAGEREF _Toc247362872 \h 66 9. : Transport Configuration Section  PAGEREF _Toc247362873 \h 68 9.1 : HTTP 1.1 connection  PAGEREF _Toc247362874 \h 68 9.2 : buffer last answer for retries  PAGEREF _Toc247362875 \h 69 9.3 : communication protocol  PAGEREF _Toc247362876 \h 69 9.4 : HTTP and OBEX/TCP server port number  PAGEREF _Toc247362877 \h 70 9.5 : listener IP address  PAGEREF _Toc247362878 \h 70 9.6 : OBEX service name  PAGEREF _Toc247362879 \h 70 9.7 : Max number of session threads per server process  PAGEREF _Toc247362880 \h 71 9.8 : Max sessions to be run by a process  PAGEREF _Toc247362881 \h 71 10. : Data Type Definitions  PAGEREF _Toc247362882 \h 72 10.1 : internal data field list  PAGEREF _Toc247362883 \h 73 10.2 : definition of an internal field  PAGEREF _Toc247362884 \h 73 10.3 : definition of a mime-dir profile  PAGEREF _Toc247362885 \h 75 10.3.1 : root profile definition  PAGEREF _Toc247362886 \h 76 10.3.2 : nested subprofile definition  PAGEREF _Toc247362887 \h 76 10.3.3 : property definition  PAGEREF _Toc247362888 \h 77 10.3.4 : property or parameter value storage  PAGEREF _Toc247362889 \h 79 10.3.5 : enumerated values  PAGEREF _Toc247362890 \h 81 10.3.6 : property parameter definition  PAGEREF _Toc247362891 \h 82 10.3.7 : control storage position and repetitions  PAGEREF _Toc247362892 \h 84 10.3.8 : VTIMEZONE generation mode  PAGEREF _Toc247362893 \h 87 10.3.9 : handling of floating timestamps  PAGEREF _Toc247362894 \h 87 10.4 : definition of a text format profile  PAGEREF _Toc247362895 \h 88 10.4.1 : mapping of text based formats to database fields  PAGEREF _Toc247362896 \h 88 10.4.2 : Number of lines to map  PAGEREF _Toc247362897 \h 88 10.4.3 : header lines  PAGEREF _Toc247362898 \h 89 10.4.4 : empty field handling  PAGEREF _Toc247362899 \h 89 10.4.5 : tagged header handling  PAGEREF _Toc247362900 \h 89 10.4.6 : type of text field  PAGEREF _Toc247362901 \h 89 10.4.7 RFC822 email body options  PAGEREF _Toc247362902 \h 90 10.5 : definition of a datatype  PAGEREF _Toc247362903 \h 91 10.5.1 : MIME-DIR profile, text profile or field list to use for datatype  PAGEREF _Toc247362904 \h 91 10.5.2 : vCard or vCalendar version  PAGEREF _Toc247362905 \h 92 10.5.3 , : MIME type and version  PAGEREF _Toc247362906 \h 92 10.5.4 : Enable/disable special compressed (non-standard) item format  PAGEREF _Toc247362907 \h 93 10.5.5 : Compression level for compression  PAGEREF _Toc247362908 \h 93 10.5.6 : Allow unencoded binary in content  PAGEREF _Toc247362909 \h 93 10.5.7 , : Unicode content  PAGEREF _Toc247362910 \h 94 10.5.8 : Initialisation of type-specific script context  PAGEREF _Toc247362911 \h 94 10.5.9 , : Custom pre- and postprocessing items  PAGEREF _Toc247362912 \h 95 10.5.10 , : Script-based data filtering  PAGEREF _Toc247362913 \h 95 10.5.11 : Custom processing for incoming items  PAGEREF _Toc247362914 \h 97 10.5.12 : Custom item comparison  PAGEREF _Toc247362915 \h 98 10.5.13 : Custom item merge  PAGEREF _Toc247362916 \h 99 10.5.14 : MIME-DIR conformance  PAGEREF _Toc247362917 \h 99 10.6 RRULE field block  PAGEREF _Toc247362918 \h 100 11. , : General Server and Client Settings  PAGEREF _Toc247362919 \h 101 11.1 ,: SyncML version support  PAGEREF _Toc247362920 \h 101 11.2 : Timeout for unfinished sessions  PAGEREF _Toc247362921 \h 102 11.3 : max time for request processing  PAGEREF _Toc247362922 \h 102 11.4 : artifical slow down  PAGEREF _Toc247362923 \h 102 11.5 : specify URL used to access the server  PAGEREF _Toc247362924 \h 103 11.6 ,: SyncML Authentication  PAGEREF _Toc247362925 \h 103 11.7 : MD5 nonce generation mode  PAGEREF _Toc247362926 \h 104 11.8 : constant nonce string  PAGEREF _Toc247362927 \h 104 11.9 , : RespURI configuration  PAGEREF _Toc247362928 \h 104 11.10 , : single user mode  PAGEREF _Toc247362929 \h 105 11.11 : Allow multi-threaded execution  PAGEREF _Toc247362930 \h 105 11.12 : Session init script  PAGEREF _Toc247362931 \h 105 11.13 : Session finish script  PAGEREF _Toc247362932 \h 106 11.14 , : Session level status code handling  PAGEREF _Toc247362933 \h 106 11.15 , : Creation of custom SyncML Get and Put commands  PAGEREF _Toc247362934 \h 106 11.16 : Custom handling of SyncML Get commands  PAGEREF _Toc247362935 \h 107 11.17 : Custom handling of SyncML Put/Result commands  PAGEREF _Toc247362936 \h 108 11.18 : SyncML command flow option  PAGEREF _Toc247362937 \h 108 11.19 : Add resending policy  PAGEREF _Toc247362938 \h 108 11.20 : LargeObject chunk size limit for testing  PAGEREF _Toc247362939 \h 109 11.21 : Handling of delete for non-existing items  PAGEREF _Toc247362940 \h 109 11.22 : Set user's default time zone  PAGEREF _Toc247362941 \h 109 11.23 : end date for allday events inclusive  PAGEREF _Toc247362942 \h 109 11.24 : error handling option  PAGEREF _Toc247362943 \h 110 11.25 : show field support details in device information  PAGEREF _Toc247362944 \h 110 11.26 : show size and type in SyncML 1.0 devInf  PAGEREF _Toc247362945 \h 110 11.27 : enumerate default property parameter's values as property names  PAGEREF _Toc247362946 \h 111 11.28 : Acceptance of server alerted sync types  PAGEREF _Toc247362947 \h 111 11.29 : Activity log text file  PAGEREF _Toc247362948 \h 111 11.30 : Activity log enable  PAGEREF _Toc247362949 \h 112 11.31 : Activity log format  PAGEREF _Toc247362950 \h 112 11.32 : Activity log header  PAGEREF _Toc247362951 \h 114 11.33 , : Pre- and post-login scripts  PAGEREF _Toc247362952 \h 114 11.34 : General Datastore settings  PAGEREF _Toc247362953 \h 115 11.34.1 : alternate name for this datastore  PAGEREF _Toc247362954 \h 116 11.34.2 : datastore type ID  PAGEREF _Toc247362955 \h 116 11.34.3 : decriptive name for a datastore  PAGEREF _Toc247362956 \h 117 11.34.4 : read-only datastore  PAGEREF _Toc247362957 \h 117 11.34.5 : delete overrides replace  PAGEREF _Toc247362958 \h 117 11.34.6 : try to update "deleted" items  PAGEREF _Toc247362959 \h 118 11.34.7 : transmit updates to remote  PAGEREF _Toc247362960 \h 118 11.34.8 : maximum number of data items per SyncML message  PAGEREF _Toc247362961 \h 118 11.34.9 : send localID (GUID) in all operations (not only adds).  PAGEREF _Toc247362962 \h 119 11.34.10 , , : sync conflict resolution strategy  PAGEREF _Toc247362963 \h 119 11.34.11 : datastore's supported types  PAGEREF _Toc247362964 \h 120 11.34.12 : use a datatype  PAGEREF _Toc247362965 \h 120 11.34.13 : enable SyncML DS 1.2 filtering  PAGEREF _Toc247362966 \h 121 11.34.14 : enable date range filtering  PAGEREF _Toc247362967 \h 121 11.34.15 : check incoming items  PAGEREF _Toc247362968 \h 121 11.34.16 : discard not accepted items silently  PAGEREF _Toc247362969 \h 122 11.34.17 : filter subset of datastore  PAGEREF _Toc247362970 \h 122 11.34.18 : filter invisible items  PAGEREF _Toc247362971 \h 122 11.34.19 : make item visible  PAGEREF _Toc247362972 \h 123 11.34.20 : make incoming items pass  PAGEREF _Toc247362973 \h 123 11.34.21 : script called before accessing database  PAGEREF _Toc247362974 \h 123 11.34.22 : script called after accessing database  PAGEREF _Toc247362975 \h 126 11.34.23 : script called when admin data (targets, maps) are read  PAGEREF _Toc247362976 \h 127 11.34.24 : script executed at end of sync  PAGEREF _Toc247362977 \h 127 11.34.25 : script called at sync alert  PAGEREF _Toc247362978 \h 127 11.34.26 : script called before sending sync alert  PAGEREF _Toc247362979 \h 128 11.34.27 : script to handle status codes for sent items  PAGEREF _Toc247362980 \h 128 11.34.28 : script to handle status codes for received items  PAGEREF _Toc247362981 \h 129 11.34.29 : re-send failing items in next session  PAGEREF _Toc247362982 \h 129 11.34.30 , : type of database timestamp  PAGEREF _Toc247362983 \h 130 11.34.31 : timezone for database timestamps  PAGEREF _Toc247362984 \h 130 11.34.32 : output data in user zone  PAGEREF _Toc247362985 \h 130 11.34.33 : character set to be used for database strings  PAGEREF _Toc247362986 \h 131 11.34.34 : encoding of line ends within database strings  PAGEREF _Toc247362987 \h 131 11.34.35 : always update all fields  PAGEREF _Toc247362988 \h 132 11.34.36 : Support for "one-way from remote sync"  PAGEREF _Toc247362989 \h 132 11.34.37 : How to determine "time of last sync"  PAGEREF _Toc247362990 \h 132 11.34.38 (or ): custom "time of last sync" identifier  PAGEREF _Toc247362991 \h 133 11.34.39 : support for resuming interrupted sync session  PAGEREF _Toc247362992 \h 133 11.34.40 : support for resuming half-transmitted data items after interrupted sync  PAGEREF _Toc247362993 \h 133 11.34.41 : mapping datatype's fields to database fields  PAGEREF _Toc247362994 \h 134 11.34.41.1 , : mapping a datatype field to a database field  PAGEREF _Toc247362995 \h 134 11.34.41.2 : auto-map internal to DB fields  PAGEREF _Toc247362996 \h 137 11.34.41.3 : initialize accessing database  PAGEREF _Toc247362997 \h 137 11.34.41.4 : post-process item read from database  PAGEREF _Toc247362998 \h 138 11.34.41.5 : prepare writing item to database  PAGEREF _Toc247362999 \h 139 11.34.41.6 : finalize written items  PAGEREF _Toc247363000 \h 140 11.34.41.7 : finish access to database  PAGEREF _Toc247363001 \h 141 11.35 : combined datastore definition  PAGEREF _Toc247363002 \h 141 11.35.1 : Include a datastore in a superdatastore  PAGEREF _Toc247363003 \h 142 11.35.2 : filter to direct incoming items  PAGEREF _Toc247363004 \h 142 11.35.3 : prefix for item ID  PAGEREF _Toc247363005 \h 142 11.36 : special rules for specific remotes  PAGEREF _Toc247363006 \h 143 11.36.1  PAGEREF _Toc247363007 \h 143 11.36.2 device identification tags for  PAGEREF _Toc247363008 \h 143 11.36.3  PAGEREF _Toc247363009 \h 144 11.36.4 : device has short fields  PAGEREF _Toc247363010 \h 144 11.36.5 : do not send empty properties  PAGEREF _Toc247363011 \h 145 11.36.6 : update client records during slowsync  PAGEREF _Toc247363012 \h 145 11.36.7 : update server records during slowsync  PAGEREF _Toc247363013 \h 145 11.36.8 : never update client records during slowsync  PAGEREF _Toc247363014 \h 146 11.36.9 : ignore maximum field size reported in client's devInf  PAGEREF _Toc247363015 \h 146 11.36.10 , : how to show datastore name in devInf sent to client.  PAGEREF _Toc247363016 \h 146 11.36.11 : allow client to send the same message twice  PAGEREF _Toc247363017 \h 147 11.36.12 : allow client to send the same message twice  PAGEREF _Toc247363018 \h 147 11.36.13 : always send time information as localtime  PAGEREF _Toc247363019 \h 147 11.36.14 : always send time information as localtime  PAGEREF _Toc247363020 \h 148 11.36.15 : always treat received information as localtime  PAGEREF _Toc247363021 \h 148 11.36.16 : always treat received information as UTC  PAGEREF _Toc247363022 \h 148 11.36.17 : prevent folding long lines  PAGEREF _Toc247363023 \h 148 11.36.18 : end date for allday events inclusive  PAGEREF _Toc247363024 \h 149 11.36.19 : set default output character set  PAGEREF _Toc247363025 \h 149 11.36.20 : set default input character set  PAGEREF _Toc247363026 \h 149 11.36.21 , : use relaxed conformance modes  PAGEREF _Toc247363027 \h 149 11.36.22 : reject sync with device  PAGEREF _Toc247363028 \h 150 11.36.23 : max time for request processing  PAGEREF _Toc247363029 \h 150 11.36.24 : script to execute if rule applies  PAGEREF _Toc247363030 \h 150 12. , : SQL/ODBC based Server or Client Config  PAGEREF _Toc247363031 \h 151 12.1 SQL Statement processing  PAGEREF _Toc247363032 \h 151 12.1.1 Placeholders for all SQL statements  PAGEREF _Toc247363033 \h 152 12.1.2 Placeholders for SQL statements within  PAGEREF _Toc247363034 \h 152 12.1.3 Placeholders for SQL data access statements within  PAGEREF _Toc247363035 \h 153 12.1.4 Executing SQL statements from scripts  PAGEREF _Toc247363036 \h 154 12.2 : ODBC data source name  PAGEREF _Toc247363037 \h 155 12.3 : ODBC database user name  PAGEREF _Toc247363038 \h 156 12.4 : ODBC database connection string  PAGEREF _Toc247363039 \h 156 12.5 : ODBC database password  PAGEREF _Toc247363040 \h 157 12.6 : prevent setting connection attributes  PAGEREF _Toc247363041 \h 157 12.7 : ODBC timeout  PAGEREF _Toc247363042 \h 157 12.8 : Script executed whenever new DB connection is opened.  PAGEREF _Toc247363043 \h 157 12.9 : Transaction isolation mode  PAGEREF _Toc247363044 \h 158 12.10 : usage of ODBC cursor library  PAGEREF _Toc247363045 \h 158 12.11 , , : outdated - no longer available  PAGEREF _Toc247363046 \h 158 12.12 : plain text password in database  PAGEREF _Toc247363047 \h 159 12.13 : MD5 digest passwort in database  PAGEREF _Toc247363048 \h 159 12.14 : MD5 digest stored as hex string in database  PAGEREF _Toc247363049 \h 159 12.15 , , , : Device management  PAGEREF _Toc247363050 \h 160 12.16 : query for user authentication  PAGEREF _Toc247363051 \h 161 12.17 : custom login checking script  PAGEREF _Toc247363052 \h 162 12.18 : query for getting database time  PAGEREF _Toc247363053 \h 163 12.19 : SQL statement to write activity log entry  PAGEREF _Toc247363054 \h 163 12.20 : SQL and ODBC Datastore specific settings  PAGEREF _Toc247363055 \h 164 12.20.1 : get data subselection key  PAGEREF _Toc247363056 \h 164 12.20.2 , , , : Sync target management  PAGEREF _Toc247363057 \h 165 12.20.3 : format for timestamps in target table  PAGEREF _Toc247363058 \h 169 12.20.4 : modified time stamp type  PAGEREF _Toc247363059 \h 169 12.20.5 , , , : Map table management  PAGEREF _Toc247363060 \h 169 12.20.6 : SQLite database file name  PAGEREF _Toc247363061 \h 171 12.20.7 : SQLite database file name  PAGEREF _Toc247363062 \h 172 12.20.8 : how ODBC strings must be escaped for the database  PAGEREF _Toc247363063 \h 172 12.20.9 : use filtering in WHERE clause  PAGEREF _Toc247363064 \h 172 12.20.10 : commit at end of SyncML message exchange  PAGEREF _Toc247363065 \h 173 12.20.11 : no longer supported in version 3.0  PAGEREF _Toc247363066 \h 173 12.20.12 : commit each item update  PAGEREF _Toc247363067 \h 173 12.20.13 : combined date and time for modification timestamp  PAGEREF _Toc247363068 \h 173 12.20.14 : read IDs and timestamps  PAGEREF _Toc247363069 \h 174 12.20.15 : read record from database  PAGEREF _Toc247363070 \h 174 12.20.16 , , , : write records to database  PAGEREF _Toc247363071 \h 175 12.20.17 : Ignore SQLRowCount  PAGEREF _Toc247363072 \h 175 12.20.18 , , , , , , : local object ID management  PAGEREF _Toc247363073 \h 176 12.20.19 : SQL specific field mapping features  PAGEREF _Toc247363074 \h 178 12.20.20 : definition of master - detail record structures  PAGEREF _Toc247363075 \h 179 12.20.21 , , : detail record storage options  PAGEREF _Toc247363076 \h 181 12.20.22 : detail record storage filter  PAGEREF _Toc247363077 \h 181 12.20.23 , , : detail record SQL  PAGEREF _Toc247363078 \h 182 12.20.24 : clean detail records on insert  PAGEREF _Toc247363079 \h 182 12.20.25 : prepare SQL filter according to options  PAGEREF _Toc247363080 \h 182 13. , : Text File Based Server or Client  PAGEREF _Toc247363081 \h 183 14. , : Plugin Based Server or Client Config  PAGEREF _Toc247363082 \h 184 14.1 plugin module: global settings  PAGEREF _Toc247363083 \h 184 14.1.1  PAGEREF _Toc247363084 \h 184 14.1.2  PAGEREF _Toc247363085 \h 185 14.1.3  PAGEREF _Toc247363086 \h 185 14.1.4  PAGEREF _Toc247363087 \h 185 14.2 : Plugin Datastore specific settings  PAGEREF _Toc247363088 \h 185 14.2.1  PAGEREF _Toc247363089 \h 185 14.2.2  PAGEREF _Toc247363090 \h 186 14.2.3  PAGEREF _Toc247363091 \h 186 14.2.4  PAGEREF _Toc247363092 \h 186 14.2.5 ,, , : Synthesis SyncML Engine library only configuration tags  PAGEREF _Toc247363099 \h 189 15.1 : Path for persistent storage of client settings and admin data  PAGEREF _Toc247363100 \h 189 15.2 : enable binfile based admin  PAGEREF _Toc247363101 \h 189 15.3 : enable CRC based change detection  PAGEREF _Toc247363102 \h 189 16. : Command line client-only configuration tags  PAGEREF _Toc247363103 \h 191 16.1 : Set default SyncML Version to start a session  PAGEREF _Toc247363104 \h 191 16.2 : Set default auth method  PAGEREF _Toc247363105 \h 191 16.3 : Set default auth encoding  PAGEREF _Toc247363106 \h 191 16.4 : Set default nonce  PAGEREF _Toc247363107 \h 192 16.5 : Use a new sessionID for retries  PAGEREF _Toc247363108 \h 192 16.6 : Use original URI for retry  PAGEREF _Toc247363109 \h 192 16.7 : Use smart retry attempt variations  PAGEREF _Toc247363110 \h 192 16.8 : Always send Device Info at Slowsync  PAGEREF _Toc247363111 \h 193 16.9 , : Login to local database  PAGEREF _Toc247363112 \h 193 16.10 : Prevent local DB login  PAGEREF _Toc247363113 \h 193 16.11 : SyncML encoding format  PAGEREF _Toc247363114 \h 193 16.12 : Remote SyncML server URL  PAGEREF _Toc247363115 \h 194 16.13 , : Login to remote SyncML server  PAGEREF _Toc247363116 \h 194 16.14 , : Proxy servers  PAGEREF _Toc247363117 \h 194 16.15 , : Proxy auth  PAGEREF _Toc247363118 \h 194 16.16 , : Login to remote SyncML server  PAGEREF _Toc247363119 \h 195 16.17 : Request to sync a datastore  PAGEREF _Toc247363120 \h 195 16.17.1 : path of remote server's datastore  PAGEREF _Toc247363121 \h 195 16.17.2 : Synchronisation mode  PAGEREF _Toc247363122 \h 195 16.17.3 : Force a slow sync  PAGEREF _Toc247363123 \h 196 16.17.4 : local datastore options  PAGEREF _Toc247363124 \h 196 16.17.5 : define SyncML DS 1.2 record filter  PAGEREF _Toc247363125 \h 197 16.17.6 : define inclusive SyncML DS 1.2 record filter  PAGEREF _Toc247363126 \h 197 17. List of built-in timezones  PAGEREF _Toc247363127 \h 198 18. Error codes  PAGEREF _Toc247363128 \h 199 18.1 SyncML Status Codes  PAGEREF _Toc247363129 \h 199 18.2 Internal Error Codes  PAGEREF _Toc247363130 \h 200 19. Index  PAGEREF _Toc247363131 \h 202 19.1 Alphabetic Index of all config XML tags  PAGEREF _Toc247363132 \h 202  What's New? New in this manual This chapter – intended as a quick overview to see what is new in this release. In particular, paragraph  REF _Ref201664889 \r \h  \* MERGEFORMAT 2.2.3 " REF _Ref201664889 \h  \* MERGEFORMAT How to migrate from 3.0 to 3.2" details the (simple) steps to take to upgrade an existing installation. An overview diagram " HYPERLINK "SySync_script_call_flow.pdf" SySync_script_call_flow.pdf" (not in this manual itself, but as a separate PDF document in the product package) showing which scripts (PRO version only) are called when in the process of sync session, and what is the typical use of a script. This is intended as a reference card to quickly find out which scripts to use to accomplish a certain customisation task. A separate chapter (see chapter  REF _Ref185238094 \r \h 5) about time zones and how these are handled in the SyncML engine. We recommend to read this chapter, as correct handling of timezones is crucial for a successful calendar sync. New in SyncML Engine 3.2 and newer compared to 3.0 General changes New Version numbering convention (borrowed from Linux kernel numbering): Odd numbers are development versions, that may be released from time to time as beta or for solving very specific customer needs in a project. Even numbers are official release versions. Completely revised and greatly enhanced handling of timezones. Apart from a lot of new features and script functions to work efficiently with time zones, the most important general change is the internal representation of time stamps. In engine versions before 3.1, the internal timestamp value was always represented in UTC (Universal Time Coordinated) along with a time zone offset indicating the time zone context. In engine version starting with 3.1, the internal timestamp value represents time in the context of the time zone identifier that is attached to it. This is a small, but important change, which allows to handle all aspects of timestamps, including "floating" timestamps, in a consistent way throughout the entire data path from backend database to remote SyncML device. See chapter  REF _Ref185238094 \r \h 5 for more details about timestamps and timezones. Most existing setups are not or only slightly affected by these changes –only configurations which were using the LOCALIZEDASUTC, RELATIVEASUTC, UTCASRELATIVE, LOCALZONEOFFSET, SETZONEOFFSET, ISRELATIVE and SETRELATIVE functions in scripts or a "zoneoffset_xxx" conversion mode need to be adapted – and normally the adapted version is simpler and much easier to understand as the new timezone system is more logical and consistent. Our sample config for the PRO servers until 3.1 used RELATIVEASUTC and "zoneoffset_secs" two times – please refer to instructions in paragraph  REF _Ref201664889 \r \h  \* MERGEFORMAT 2.2.3 " REF _Ref201664889 \h  \* MERGEFORMAT How to migrate from 3.0 to 3.2" how to update your config. New Features SyncML engine now available as library – Starting with Synthesis SyncML engine 3.1, the core engine with all SyncML functionality, SQL/ODBC/SQLite and plugin database interfaces, complete XML configuration is now available as a dynamically linkable library for various platforms. Using the Synthesis SyncML SDK, custom SyncML applications can be built in native languages (C/C++/Delphi etc.) as well as in Java or .net. Extended support for symbolic time zones – which can be referenced and stored in the database by name. These symbolic time zones handle DST rules automatically (not only for the system's local zone, but any time zone). See chapter  REF _Ref185238094 \r \h 5 for an overview of time zones. The PRO version also has many new built-in script functions for working with time zones: ZONEOFFSET(), TIMEZONE(), VTIMEZONE(), SETTIMEZONE(), SETFLOATING(), CONVERTTOZONE(), CONVERTTOUSERZONE(), USERTIMEZONE(), SETUSERTIMEZONE(), ISDATEONLY(), DATEONLY(), ISFLOATING() – see ( REF _Ref204925451 \r \h 6.14.4). Per user time zones – using (see  REF _Ref204935552 \r \h 11.22) and SETUSERTIMEZONE() (see  REF _Ref204925451 \r \h 6.14.4) it is possible to assign a default time zone on a per-user level. This is important with client devices that do not support UTC, and must be server in a specific local time zone. Per datastore time zone – using the new (see  REF _Ref185246110 \r \h 11.34.31) which replaces former (still supported for compatibility). Record level or field level time zones e.g. for storing originating time zone of a calendar entry along with the entry, or to define floating timestamps (timestamps not bound to a time zone). To map the timezone of a timestamp field to a database string field, use the new "zonename" database field type (see  REF _Ref47173451 \r \h 11.34.41.1). To create TZ, DAYLIGHT and TZID values in vCalendar/iCalendar data formats, new conversion modes "TZ", "DAYLIGHT", "TZID" have been added (see  REF _Ref182995906 \r \h 10.3.4). To include full time zone specification in VTIMEZONE format, a predefined (see  REF _Ref182997657 \r \h 10.3.2) has been added. PRO only: Support for maintaining relational links between items by providing an optional post-processing step at the end of the session (when the data sets are known to be in sync) trough the new (see  REF _Ref207618734 \r \h 11.34.41.6). PRO only: Support for regular expression search, replace and pattern split (using new script functions REGEX_FIND, REGEX_MATCH, REGEX_SPLIT, REGEX_REPLACE, see  REF _Ref204937964 \r \h 6.14.2). These can greatly simplify value conversion scripts. PRO only: Script language now supports the WHILE() statement in addition to the LOOP statement. PRO only: A lot of new built-in script functions: SYNCMLVERS(), EXPLODE(), ABS(), SIGN(), NUMFORMAT(), DAYUNITS(), MONTHDAYS(), PARSEEMAILSPEC(), MAKEEMAILSPEC(), SLEEPMS(), TIMESTAMPTODBINT(), DBINTTOTIMESTAMP(), CONVERTTODATAZONE(), ADDTARGETCGI(), SETRECORDFILTER(), SETDAYSRANGE(), TARGETSETTING() - see ( REF _Ref42673942 \r \h 6.14). Enhanced support for calendar content formats – new conversion modes "valuetype", "tzid", "tz", "daylight", "autodate", "autoenddate" see ( REF _Ref182995906 \r \h 10.3.4), new script functions to detects/generate all-day events: ALLDAYCOUNT(), MAKEALLDAY() and to generate and expand recurring events: RECURRENCE_DATE(), RECURRENCE_COUNT(), see ( REF _Ref204935761 \r \h 6.14.3). SyncML max message and object size limits are now configurable using , (see  REF _Ref203479102 \r \h 8.3 and  REF _Ref204935780 \r \h 8.4). Debug logging enhanced – now shows timestamps with millisecond resolution. Blocks now have a "enclosing" navigation link which allows jumping to the beginning or end of an enclosing block in the hierarchy. SyncML message dumping enhanced – messages are now saved on a per-session basis and message dumping can be switched on and off in scripts, e.g. based on what user is logged in or what device type is being synchronized. See ( REF _Ref203482186 \r \h 8.11.15), ( REF _Ref203482205 \r \h 8.11.14) and the related script functions SETMSGDUMP and SETXMLTRANSLATE ( REF _Ref153590626 \r \h 6.14.5). Script execution logging enhanced – colorized to recognize comments, executed code and conditionally skipped code at a glance. Condensed output to avoid too much detail by default (but new "expressions" debug option still allows in-detail expression debugging, see  REF _Ref42675268 \r \h 8.11.2). New script functions DEBUGSHOWITEM() and DEBUGSHOWVARS() can be used to show the contents of a sync item or of all local script variables in the log, see  REF _Ref153590626 \r \h 6.14.5. Optional parameters for built-in script functions – many of the new 3.1 engine's scripting functions and some of the existing functions now have optional parameters which can be omitted when no special non-default behaviour is needed. Config variables: These are variable strings that can be referenced in the XML config using $(varname) syntax (see  REF _Ref184459487 \r \h 4.2) or for conditional config sections (see  REF _Ref183001062 \r \h 4.5). Config variables are either preset by the operating environment (with values like engine version, device ID, file paths to standard config, temp, user directories etc., see  REF _Ref184460000 \r \h 4.4), defined from the command line using the –D option (for executable program versions, use -h option to show syntax options), via the "/configvars" engine settings key (for library versions). Conditional config: All config XML tags now have generic "if", "ifdef" and "ifndef" attributes (see  REF _Ref183001062 \r \h 4.5) that can be used to make certain config sections dependent on config variables (e.g. SyncML engine version). This simplifies using the same config file for different versions of the SyncML engine, different platform, different operating conditions. How to migrate from 3.0 to 3.2 or newer (up to 3.4) Existing 3.0 installations usually need some changes when based on our 3.0 configuration sample to run with SyncML engine 3.2 or later. Some configurations that did not make use of time-zone related features might need no changes at all. Please check the following: Obsolete time zone conversion modes: zoneoffset_secs, zoneoffset_mins, zoneoffset_hours are no longer available. These have been replaced by the much more versatile "tz" mode (see  REF _Ref182995906 \r \h 10.3.4). If your configuration is based on the sample configuration as delivered with the 3.0 version, you'll likely have two occurrences of zoneoffset_secs for the "TZ" field. The way this field was defined in 3.0 and earlier was not correct vCalendar 1.0 usage anyway, and almost no client supported it, so it had no real meaning. If you want to be prepared to save the originating time zone along with each calendar item, change the type of the TIMEZONE field in the "calendar" from string: to integer This will cause your TIMEZONE field in the database store a minute offset to UTC instead of a seconds offset as in 3.0. Then move the first occurrence of "..." one level up (out of "" into ""), and delete the second occurrence of "...": ... Alternatively, if you do not need the TIMEZONE information in your application, just remove the two ... definitions entirely from the config file. and should be changed to : No change is needed, but the SyncML engine will show a warning when or (see  REF _Ref185245663 \r \h 11.34.30) are used as these should be replaced by the more versatile (see  REF _Ref185246110 \r \h 11.34.31). PRO only – script functions no longer supported: LOCALIZEDASUTC, RELATIVEASUTC, UTCASRELATIVE, LOCALZONEOFFSET, SETZONEOFFSET, ISRELATIVE and SETRELATIVE are not supported any more because they do not fit with the new enhanced timezone handling. If your configuration is based on the sample configuration as delivered with the 3.0 version, you'll likely have two occurrences of RELATIVEASUTC in the of vCalendar10. These can be simply removed. So the line that originally reads: RES = COMPARE(DATEONLY(RELATIVEASUTC(TARGET.DTSTART)), DATEONLY(RELATIVEASUTC(REFERENCE.DTSTART))); can be replaced by RES = COMPARE(DATEONLY(TARGET.DTSTART), DATEONLY(REFERENCE.DTSTART)); Overview In order to understand a server's or client's configuration, an overview of the basic building blocks and concepts in the Synthesis SyncML engine is helpful. Basic Concepts The Synthesis SyncML engine performs three conceptually more or less separate tasks: Running the SyncML protocol. SyncML is an open industry standard and therefore there are clear specifications about how the SyncML protocol must be implemented and run. Therefore, there is not a lot of configuration needed for the SyncML protocol engine itself. Encoding and decoding the data that is synchronized with the SyncML protocol. SyncML itself is designed to synchronize any type of data, even proprietary, customer-defined types. However, to make a SyncML server or client interoperable, it must support some standard datatypes. Today, this includes the widely used vCard format for contact information and vCalendar for events and tasklists, and a number of RFC(2)822 based email formats for email synchronisation. Synthesis SyncML products support these standard formats, but they give the user complete freedom about all the details (you can define a server or client that can handle 37 phone numbers per contact if this is important in your context). In addition, custom formats based on plain text, MIME-email or MIME-DIR can be defined. Covering all the possible options of the vCard/vCalendar formats and even allowing to define new formats makes the datatype configuration quite complex and big - however in most applications, it is sufficient to slightly modify one of the provided sample datatypes. Interfacing the SyncML data with a server's or client's database. The complexity of this task depends largely on the type and kind of database. Our text file based demo versions need almost no configuration, because the data is simply saved to tab-separated text files. On the other hand, our ODBC-based products are designed to interface with existing databases, which requires very flexible configuration options to handle field mapping and data conversions. In most real-world applications, configuration of the database interface is what needs most attention and customisation. Configuration Structure According to the basic tasks decribed above, the config for a Synthesis SyncML server or client is structured as follows: client and server: General global options, (see  REF _Ref47775300 \r \h 8) such as: a section for configuring level of debugging log information a section for defining global scripting functions and macros (only in PRO versions) a section for entering license codes (not all versions need license codes) server only: Configuration of the transport, that is how clients can access the server (see  REF _Ref47775275 \r \h 9) server and client: Datatype definitions (see  REF _Ref6129297 \r \h 10). This consists of the following sub-sections: one or multiple sections, which define the internal representation of a data type as a list of typed fields (or array fields). one or multiple and/or sections, which define a mapping between internal fields and a data format based on MIME-DIR (such as vCard or vCalendar) or plain text (such as email or notes). one or multiple sections, which define actual data types based on field lists and MIME-DIR or text profiles. server only: a section which defines the server databases (see  REF _Ref47165113 \r \h 11 and  REF _Ref47165137 \r \h 12) client only: a section which defines the client databases (see  REF _Ref47165113 \r \h 11 and  REF _Ref47165137 \r \h 12) server and client: the or section contains one or multiple sections which each define a database. The definition provides the necessary mapping information between the internal fields from the field list and the database itself. For the ODBC based products this includes all SQL statements needed to read, modify, insert and delete data as well as a mapping table assigning SQL-names to internal field names. For the plugin based datastores, the mapping is between internal field names and the plugin API data format's names. For both types of datastores, importants settings like database character set and line end format can be defined here. client only: one or multiple sections which define what databases should be synced with a server when the client application is started (not available in all client versions). server and client: optional sections which define special options for a certain type of remote SyncML client or server. This is normally used in servers to control device-specific behaviour. The order in which the elements appear in the config file does not matter unless a section refers to definitions in another sections (like referencing s, or s referencing ) - in this case the defining section must appear before the referring section in the config file. Generally, we recommend using the order as outlined above (and also used in the sample config files). An "empty" server config file looks like this (a client would be similar except that there was a section instead of the section): We recommend to use the sample config file as a starting point, because there are quite complex parts (especially datatype definitions) which are hard to create from scratch. In many applications, modest modifications to one of the sample files is sufficient anyway. XML basics The configuration file is formatted in XML, which is a tagged text format. Any text editor (including Windows Notepad) can be used to edit XML files. In addition, there are many XML-aware text editors or specialized XML editors. To view (but not edit) XML files neatly formatted and colorized, they can be opened with a web browser like Firefox. We cannot give a real introduction to XML here, but here are just a few notes about XML syntax in case you are not familiar with it already: An XML tag consist of text enclosed in angle brackets like: XML tags must always appear in pairs: something in between the "something in between" can be plain text or other paired tags: some text Instead of writing: for a tag pair with "nothing in between" (tag with no contents), it can be abbreviated as: Tags can have attributes: Attribute values must always be enclosed in double quotes. In Synthesis Sync Server config, tags with attributes are often tags with no contents, so many config tags might look like: (note the slash at the end) XML allows inserting comments. A comment starts with : Formatting does not matter (except for string values, see below), but it makes XML much more readable when nested contents are indented like in the sample config files. Most XML enabled tools do this automatically or have an option for it. Synthesis Sync Server Config specific XML usage A few notes on the way XML is used in Synthesis Sync Server: String values: They are used exactly as written in the config file, except that leading and trailing whitespace is removed first. All other contained spaces, control characters and line ends are preserved. So when formatting the XML source nicely, make sure you don't break strings into muliple lines that should be one line (such as directory paths). C-String values: These are strings that are parsed like in the C programming language as follows: Actual line ends are ignored, but the following escape sequences can be used to insert special characters into the string: \t is used to insert a TAB character \r is used to insert a CR character \n is used to insert a LF (linefeed) character \xXX is used to insert the character having an ASCII-code of XX (in hexadecimal). Note that the octal form \0XX available in the C language is NOT supported. \\ is used to insert a single backslash character. Boolean values: "yes", "true", "on", "1" can be used for true, "no", "false", "off", "0" can be used for false. Configuration variables and conditional configuration New in 3.1: Configuration variables (or short "config variables") are a new concept introduced with the 3.1 SyncML engine to allow parametrizing some values within a config file from "the outside" without needing to edit the config file itself. Using conditional sections in a config file, the same file can be used for different setups controlled by configuration variables. Sources for values of config variable There are four sources for these "outside" values: From the operating environment – these are values like file system paths to various platform specific directories (like temp dir, application dir etc.) or other values like current user name (see  REF _Ref184460000 \r \h 4.4 for a list). From the SyncML engine itself – like the version of the SyncML engine Supplied from another program or the user: via the –D command line option for standalone SyncML applications or via the "/configvars" settings key when the SyncML engine is used as a libary with the client or server SDK API – see separate SDK docs for details. Finally, the directive (see  REF _Ref204511965 \r \h 8.8) can be used to define config variables in the config file itself. The first two sources are predefined by the engine. See  REF _Ref184460000 \r \h 4.4 for a list of commonly supported configuration variables. Depending on the platform or engine variant, there might be additional variables predefined (and documented in the specific product documentation). Using configuration variables Configuration variables can be used within many string literals in the configuration using the syntax $(configvarname). This syntax is generally recognized in strings that specify file system paths. In all other tags, the $(configvarname) syntax is not recognized by default, but can be switched on using the "expand" attribute (see  REF _Ref184459204 \r \h 4.3). In XML tag attributes, the $(configvarname) syntax is usually not supported, however there are exceptions such as the tag, see  REF _Ref204511965 \r \h 8.8. By default, expansion of config variables is recursive, which means that if the value of a config variable contains another $(configvarname), this is expanded as well. To avoid recursive expansion, the "expand" attribute (see  REF _Ref184459204 \r \h 4.3) can be set to "single". Note: before version 3.2.0.11, expanding tags with pure numeric, enumerated or timestamp values was not supported. From 3.2.0.11 onwards, $(configname) expansion works for all tags (but for most tags only if the "expand" attribute is set, see above). Config variables can also be used to control conditional configuration (see  REF _Ref183001062 \r \h 4.5). "expand" attribute All tags that support configuration variable expansion (see  REF _Ref184459487 \r \h 4.2) can have a "expand" attribute to control if and how to expand $(configvarname). Possible values for "expand" are: "no" : do not expand "single" : expand once, but do not try to expand result again "yes" : expand recursively. Predefined Configuration Variables The following list contains the configuration variables generally available in most Synthesis SyncML products. Depending on the platform or engine variant, there might be additional variables predefined (and documented in the specific product documentation). version Version string of the Synthesis SyncML engine, like "3.4.0.0" hexversion Synthesis SyncML engine version as 32-bit hex like MMmmssbb (MM=major, mm=minor, ss=subversion, bb=build). manufacturer Manufacturer string that is also communicated to remote parties in the SyncML device Information. For Synthesis SyncML engine library products, this can be configured using the tag (see  REF _Ref206385571 \r \h 8.6). model Model (product name) string that is also communicated to remote parties in the SyncML device Information. For Synthesis SyncML engine library products, this can be configured using the tag (see  REF _Ref206385661 \r \h 8.7). platformname name of the current OS platform (like Windows, Linux, iPhoneOS…) platformvers version string of the current OS platform (like "5.1.1732") globcfg_path global system-wide config path (such as C:\Windows or /etc) loccfg_path local config path (such as exedir or user's dir) defout_path default path to writable directory to write logs and other output by default temp_path path where we can write temp files exedir_path path to directory where executable resides userdir_path path to the user's home directory for user-visible documents and files appdata_path path to the user's preference directory for this application prefs_path path to directory where all application prefs reside (not just mine) device_uri URI of the device (usually unique ID or URL identifying the device or server) device_name Name of the device (like a model or brand name) user_name name of the currently logged-in user conferrpath for Synthesis SyncML engine library only: path of the file to output configuration parsing error messages. Can be set to "console" to direct the error messages to the standard output (note that a usable standard output might not exist for certain platforms). "ifdef/ifndef/if" conditional attributes New in 3.1: These attributes are available in every XML tag and can be used in a similar way as the "platform" attribute (see  REF _Ref184460158 \r \h 4.6) to make sections of the configuration dependent on certain conditions: "ifdef": used in the form . This will conditionally include and all tags contained only if "configvarname" is an existing config variable. "ifndef": same as "ifdef", but condition reversed – config variable must not exist to include the tag in the config. "if": used in the form . This will compare the config variable with the specified value. Allowed comparison operators are "=", ">", "<", "!=", ">=", "<=". The comparison is a string comparison, except when comparing the "version" variable, which is compared such that "newer version > older version" is always true (which would not always be the case with string comparison). "platform" conditional attribute Usually, a Synthesis SyncML server or client configuration file is largely platform independent. However, some specifications, such as file paths, are always platform dependent. Since version 2.9.8.5, every tag can be made platform-specific by adding a platform="xxx" attribute. xxx can be "win32", "linux" or "macosx" at this time. Tags having a platform attribute are only evaluated on the specified platform. This allows using a single config file for multiple platforms. For example, the debug log path usually varies depending on the platform: C:\logs\syncml /var/log/syncml /private/var/log/syncml Time zone handling With the Synthesis SyncML engine 3.1, a completely revised time zone handling has been implemented that allows much more flexibility than before, and allows handling time zone association with timestamp information down to the single field level. Note: For setups designed for SyncML engine before 3.1, the new engine behaves fully compatible when used with existing 3.0 configuration file, with the exception of a few rarely used scripting functions (LOCALIZEDASUTC, RELATIVEASUTC, UTCASRELATIVE, LOCALZONEOFFSET, SETZONEOFFSET, ISRELATIVE and SETRELATIVE) which are no longer available. In config the 3.0 engine config samples, RELAVTIVEASUTC is used twice, which can be simply removed as the new timestamp representation makes the use of RELATIVEASUTC functionally obsolete. Timestamp representation Timestamp fields consist of two parts: The timestamp value itself (internally represented as 64bit integer counting milliseconds passed since -4712-01-01 00:00:00 on most platforms). When a timestamp is converted e.g. from a string representation into internal format, the timestamp represents date and time exactly as found in the input, regardless of eventual time zone information. This is the key difference between Synthesis SyncML engine 3.0 and 3.1 timezone handling – in 3.0 and earlier, timestamps were always converted to UTC. The time zone context  where a timestamp value belongs to or originates from. The context is either a plain numeric offset from UTC (like: 1 hour east of UTC, which applies for example for Zürich local winter time), or it can be in symbolic form which handles winter and summer (daylight savings) time (like "CET/CEST" meaning Central European Time and Central European Summer Time, which is 1 hour east of UTC in winter, and 2 hours in summer). Timestamps that are not associated with a specific time zone are called floating timestamps. Date-only values are normally floating, as they usually refer to a specific calendar day and not a absolute point in UTC time. External string representations for timestamps sometimes include time zone information (like the "Z" in ISO8601 UTC format: 20071212T110000Z or an explicit offset like in 20071212T120000+01) . Sometimes, external representation does not include time zone information directly, but timestamps are still implicitly meant in a specific time zone context, like the system's current time zone for example). Therefore it is important to understand what different implicit time zone contexts exist within a SyncML session and how timestamp values are affected by "travelling" through these contexts. Timezone contexts The Synthesis SyncML Engine 3.1 and later maintains the following time zone contexts, ordered starting with most general and global context and ending with most specific context: System time zone context. This is the time zone set in the operating system which runs the SyncML engine. It can be referenced by name by the string "SYSTEM". Usually, the parameters (offset and daylight saving switching rules) are obtained from the operating system automatically. It can be overridden by using the configuration tag (see  REF _Ref185247389 \r \h 8.14). Datastore time zone context. This is a per-datastore time zone context which is used for all timestamps stored in the database. This means that timestamp values are converted from their original timezone context to the datastore time zone context before storing them in the database. Vice versa, timestamps read from the database are implicitly treated as originating in the datastore time zone context. An exception to this are timestamps mapped to the database using the "f" (floating) mode flag in the tag (see  REF _Ref47173451 \r \h 11.34.41.1) – these are always stored as-is (which can make sense if the actual time zone is stored along with each timestamp in a separate database field using the "zonename" or " zoneoffset_xxx" mapping types). The datastore time zone context to be used for a datastore is specified using the tag (see  REF _Ref185246110 \r \h 11.34.31). For compatibility with pre-3.1 configuration files (see  REF _Ref185245663 \r \h 11.34.30) is still supported but no longer recommended – use (see  REF _Ref185246110 \r \h 11.34.31) instead: timeutc=true is equivalent with datatimezone=UTC and timeutc=false is equivalent with datatimezone=SYSTEM). User time zone context. Each user of a SyncML application thinks of his or her calendar entries in the context of a time zone. Calendar applications and web sites use this time zone to display timestamps, and usually input of new calendar entries is meant in that time zone as well. This general fact gains technical relevance with SyncML devices that are not capable of receiving and sending timestamps in a time-zone independent way (usually UTC). When communicating with such a device, the SyncML application must know implicitly in what timezone context transmitted timestamp values are meant. By default (and generally in Synthesis SyncML engines before 3.1), this user time zone context is the same as the local time zone of the operating system. While this is usually correct for single user mobile devices, it might not be sufficient for a multi-user server. To allow individual time zone context per user, Synthesis SyncML Engine 3.1 adds the configuration tag (see  REF _Ref204922935 \r \h 11.22) and especially the SETUSERTIMEZONE() (see  REF _Ref204925451 \r \h 6.14.4) script function, which allows setting the user time zone context based on user-level information retrieved at login (see and in  REF _Ref43727925 \r \h 11.33 or in  REF _Ref43727928 \r \h 12.17). Item time zone context. For each item (such as a vCalendar item) processed by the SyncML engine, the item time zone context is initialized with the user time zone context, which means that timestamp data which has no timezone information attached is treated as related to the user time zone context. However, if a item carries time zone information (for example vCalendar TZ/DAYLIGHT), this modifies the item time zone context accordingly, and any timestamp found in the item which does not have its own specific time zone will be subsequently treated in the item time zone context. Vice versa, the item time zone context might be used (depending on rules defined by the content format) to represent timestamps when generating items like vCalendar. Field level time zone context. Each timestamp which "travels" from SyncML end to the database end trough the SyncML engine has its own time zone context associated. When reading a item from SyncML content formats like vCalendar, the field level time zone context is either read as part of the timestamp string representation (e.g. TZID parameter in iCalendar) or copied from the item time zone context. When writing the timestamp to the database, it is usually converted to the datastore time zone context (if mode flag "f" is not used, see  REF _Ref47173451 \r \h 11.34.41.1) Vice versa, timestamps read from the database receive either a individual time zone from a "zonename" (see  REF _Ref47173451 \r \h 11.34.41.1) or are put into datastore time zone context. Before data is converted to SyncML content formats like vCalendar, timestamps are converted to user time zone context (except if is set to false, see  REF _Ref204936212 \r \h 11.34.32). The built-in script language offers various built-in functions to access and manipulate the field level time zone context. Time zone specifications Time zones can be specified in different ways: By name: The SyncML engine has a built-in list of world-wide time zones which can be referenced by name. Well known timezone name examples are "UTC", "PST", "CET". If a timezone has daylight savings, it can be referenced either by the standard time zone name, the daylight savings zone name or a combination of both: "PST", "PDT" and "PST/PDT" all reference Pacific time; "CET", "CEST" and "CET/CEST" all reference Central European Time. Some zones have more descriptive aliases like "Pacific", some have variants with differing daylight savings rules like "Pacific_Mexico" etc. The TIMEZONE script function (see  REF _Ref204925451 \r \h 6.14.4) returns the time zone name of a given timestamp. For a complete list of built-in time zones see chapter  REF _Ref185261956 \r \h 17. A number of special time zone names are supported as follows: SYSTEM – means the local time zone of the operating system (eventually overridden with see  REF _Ref185247389 \r \h 8.14). DATE – means a floating date-only value. FLOATING – means that the timestamp is not related to any time zone in particular. USERTIMEZONE – can be used in script functions like SETTIMEZONE (see  REF _Ref204925451 \r \h 6.14.4) to apply the user time zone context  active for the current user in the current sync session. By VTIMEZONE specification: New timezones can be added to the built-in list using the VTIMEZONE format (as defined in iCalendar, RFC 2445). This can be done statically in the configuration (, see  REF _Ref185262282 \r \h 8.15) or dynamically in scripts using script functions like SETTIMEZONE (see  REF _Ref204925451 \r \h 6.14.4) which can accept VTIMEZONE input to specify a time zone. New timezones are also created implicitly when receiving vCalendar items containing VTIMEZONE specifications that do not match one of the already defined time zones. The VTIMEZONE script function (see  REF _Ref204925451 \r \h 6.14.4) returns the time zone of a given timestamp as a VTIMEZONE record. By TZ/DAYLIGHT specification: New timezones are also added implicitly when receiving TZ/DAYLIGHT properties in vCalendar 1.0 items (using the special "tz" and "daylight" conversion modes, see  REF _Ref182995906 \r \h 10.3.4). As numeric offset: This is generally not recommended, as most time zones do not have the samm offset all year long but change between standard and daylight savings time, so a numeric offset only applies for a single specific time stamp value and cannot be used generally for other timestamps in the same zone. Numeric time zone offsets are accepted as part of timestamp formats like ISO8601 or RFC822 (email time stamps), or as input to script functions like SETTIMEZONE (see  REF _Ref204925451 \r \h 6.14.4) when used with numeric arguments. Scripting Language The PRO versions of the Synthesis SyncML engine feature a built-in, highly efficient, C-style syntax scripting language that extends flexibility in adapting to even exotic database layouts far beyond what is possible with the standard version. It allows for example to code value translations that are more complex than simple 1:1 translations (which can be done with s, see  REF _Ref42506966 \r \h 10.3.5). This chapter describes the script language in general. Scripts can be defined at many points within the configuration to customize many aspects of handling data, database access, data matching algorithms etc. These places where a script can be used within the configuration is described together with the related configuration section. Note that this chapter assumes basic knowledge of C or a C-like syntax language (for example JavaScript). What can be scripted? There are various possibilities to use scripts to customize processing of a synchronisation operation (a so called sync session). For each possibility, a "hook" exists to insert your custom code in the form of a configuration tag, where xxxxx describes the action or process that can be customized. These scripts are executed in various different contexts (see  REF _Ref42517152 \r \h 6.8 for details). This is important to understand as every context has it's own scope (local variables, lifetime, context script functions that can be accessed). To get an overview of what scripts exist in what contexts, please refer to the " HYPERLINK "SySync_script_call_flow.pdf" SySync_script_call_flow.pdf" diagram (separate PDF document). Embedding script source code in XML All script source is embedded in the configuration file as text between XML tags like: // this is a script integer x; However, as scripts often contain greater-than and less-than signs (< and >) and maybe ampersands (&) which have a special meaning in XML, we strongly recommend to use the XML CDATA bracket to enclose scripts, as follows: and & integer x,y,z; x = y > z && z<100; ]]> Comments The script engine supports both forms of ANSI-C style comments, that is Any sequence of characters starting with /* and ending with */ Any sequence of characters starting with // and ending with a line end Statements and Statement Blocks A statement is either a simple statement terminated with a semicolon (;) or it is a statement block. Statement blocks are multiple statements enclosed in { and }. Note that empty statements are allowed (consisting of a semicolon only) // simple statement a = b; // statement block { a = b; // first simple statement c = d; // another simple statement } // empty statement ; Identifiers Identifiers identify language keywords (such as IF, ELSE etc.), symbolic constants, variables and functions. Identifiers always start with an alphabethic character, and otherwise consists of any number of alphanumeric characters or underscores (_). Note that identifiers in scripts are not case sensitive (unlike in C)! Data types The built-in script language uses exactly the same base datatypes that are also available for fields in a definition (see  REF _Ref5625615 \r \h 10.2 for details). All datatypes are either integer or string based. There is no floating point data type. Note also that despite the similarity with C, the basic types known from C are not available (neither char nor int). Constants/Literals There are three basic types of literal constants: Integer constants: an optional minus sign "-" followed by digits "0".."9". From version 3.1 onwards C-style hexadecimal (0x...) integer syntax is supported (but not octal (0...) integer syntax). Quoted string constants: Any text surrounded by double quotes. Within the quotes, only "\" (backslash) has a special meaning: it causes the following character to be added to the string unprocessed, for example a doublequote or the backslash itself. Note the following special escape sequences: "\n" stands for a line end "\t" stands for a tab "\xNN (where NN is a two-digit hexadecimal number) stands for the character with the ASCII-Code equivalent to NN. Date and time constants in ISO8601 basic format such as 20030604T164922 or 20030604144922Z (see ISO8601 specs if you need more details). Note that if the ISO8601 constant expression contains + or -, it must be quoted like a string constant. There are also the following special symbolic constant values: TRUE (synonymous to a constant integer of 1) FALSE (synonymous to a constant integer of 0) EMPTY: This is a special "value" all variables can have and means that the variable has no value. UNASSIGNED: This is almost the same as EMPTY, but for data item fields, it has the additional meaning of "this value has not been assigned, not even with an EMPTY value". This is useful to distinguish values that were transmitted from the remote SyncML device with an empty value (==EMPTY) from values that were not transmitted at all (==UNASSIGNED). Script contexts All scripts run in a specific script context. For example, there is a "login context", a "session context", "datatype contexts" etc. A script context can be thought of as an execution environment that is (mostly) isolated from other script contexts and has the following properties: One or several scripts that belong to the script context and are executed within the environment that this context represents. Which scripts belong to what context is described where the script's tag in other chapters of this reference manual. A lifetime. For example, the "session context"s life time is the entire sync session, whereas a database mapping script context's life is only as long as database access takes place. Context variables (these are defined by the scripts, see  REF _Ref42509834 \r \h 6.9 below). These are values that are local to the script context and can be accessed only by scripts in the same context. None, one or two (but not more) data items. A data item represents the data in an object being synced by the SyncML engine, such as a vCard or vCalendar. However, the data item is not the vCard itself, but its internal representation which consists of a list of fields as defined by a (see  REF _Ref6030571 \r \h 10.1). A number of context built-in functions. These are built-in functions that do make sense only within this special script context and are not available in other script contexts (as opposed to global built-in functions (see  REF _Ref42673816 \r \h 6.13.2) which are available in all scripts). Variables Variables in scripts are technically the same internal objects as fields in a (see  REF _Ref5625615 \r \h 10.2). Variables can be assigned values (using the = assignment operator) and values stored in variables can be used in expressions (see  REF _Ref42671142 \r \h 6.10) Within scripts, there are three basically different kinds of variables - where the difference is in the way they come into existence (scope) and the syntax used to access them. Context Variables These are variables declared in one of the scripts that belong to a script context. Note that all variables must be declared before being used. Variables can be of any of the basic datatypes (see  REF _Ref185238839 \r \h 6.6) or dynamic arrays thereof (always with empty square brackets, specification of a size is neither needed nor allowed): // declaration of simple variables integer mynumber,yournumber; // two integers string s; // a dynamic string telephone tel; /* also a dynamic string, but with telephone-number comparison rules */ timestamp t; // a timestamp // declaration of dynamic arrays string mynamelist[]; // an array of strings integer l[]; // an array of integers Note that all context variables declared in any of the scripts belonging to the same context are accessible in all scripts belonging to this context regardless of when (or whether at all) the scripts containing the declarations are executed. Therefore, it is sufficient to declare context variables in one script belonging to a context (altough redeclaration is allowed as long as the type of a variable is the same in all declarations). To explicitly access context variables in script expressions when there are field variables having the same name the name can be qualified with a "local." prefix, but this is only for documentation purposes (as a context variable always override field variables with the same name): // accessing a context variable integer a,b; // two integers // normal access a = b; // with qualifier prefix for documentation local.a = local.b; Local variables of a user-defined function Variables declared in user-defined functions (see  REF _Ref42511232 \r \h 6.13) are local to the function, and not to the script context where the function is called. Otherwise, local variables in user-defined functions are declared and used like script context variables. Field variables In script contexts that have associated data items (see  REF _Ref42517152 \r \h 6.8 above) the fields of the data items can be accessed as follows: The field of the so called target data item (also called new or winning item, depending on the context) can be accessed by the field name alone (if there is no context variable with the same name) or with any of the (synonymous) prefixes "new.", "winning.", "target.". The field of the so called reference data item (also called old or loosing item, depending on the context) can only be accessed by using one of the (synonymous) prefixes "old.", "loosing." or "reference.". /* assuming there is no context variable DTSTART we can access the DTSTART of a vCalendar like: */ t = DTSTART; /* to make sure we get the field, and not a context variable: */ t = TARGET.DTSTART; /* if there are two data items involved (for example when comparing or merging items: */ if (NEW.DTSTART<>OLD.DTSTART) { /* do something */ } Note that in some contexts, it might be that data items (one or both) cannot be written, such that assigning values to field variables is not allowed (for example in the ). Array variable references Array variables are always one-dimensional, dynamically sized arrays of simple variables. The elements can be accessed by a zero-based index expression in square brackets like: // declaration integer a,myarray[]; // accessing array elements a = myarray[0]; // first element b = myarray[7]; // 8th element In addition there is a special form of array index that can be used to access fields in a field list (see  REF _Ref42589436 \r \h 10.1) by index instead of by name. This special form of array index starts with a + sign as the first character after the opening [ as shown in the following example: /* sample script to access the telephone numbers by index instead of by name */ integer i; telephone a,b,c; a = TEL_1[+0]; // this is the same as: a=TEL_1 b = TEL_1[+1]; // this is the same as: b=TEL_2 c = TEL_1[+2]; // this is the same as: c=TEL_3 As this special form is dependent on the field order in the field list, it's use is only recommended when this can be guaranteed. Expressions Expressions are built as follows (much like C, but not all operators of C available): An expression consists of a single term or multiple terms linked together with one of the operators. A term is either an expression enclosed in parantheses, a constant (see  REF _Ref42588386 \r \h 6.7), a variable reference (see  REF _Ref42509834 \r \h 6.9 and  REF _Ref42590185 \r \h 6.9.4) or a function call (see  REF _Ref42511232 \r \h 6.13). A term can be optionally preceeded by a typecast. A typecast is a type name enclosed in parantheses, like: (integer)a. It's effect is that the term it preceedes is converted to the type specified. Operators are the following, in the order of precedence: Unary minus (-), unary logical NOT (!) and unary bitwise NOT (~). Multiply (*), divide (/) and modulus (%) Add for numbers or concatenate for strings (+) and subtract (-) Shift left (<<) and shift right (>>) Comparison operators (>, <, >=, <=, ==, !=) Bitwise AND (&) Bitwise XOR (^) Bitwise OR (|) Logical AND (&&) Logical OR (||) Note that all operators except + need numeric (integer or timestamp) operands. If operands are not numeric, they will be implicitly converted. Flow control The script engine supports the following flow control mechanisms: IF (conditional_expression) statement: statement is executed if conditional_expression returns non-zero result. IF (conditional_expression) statement1 ELSE statement2: statement1 is executed if conditional_expression returns non-zero result, otherwise, statement2 is executed. IF (conditional_expression1) statement1 ELSE IF (conditional_expression2) statement2.... ELSE statement: Chained if-else; the last statement is only executed if none of the previous IF conditions were true. LOOP statement. This is a general loop mechanism (there is also a while statement, but no for/do as in C). It causes statement (which is normally a statement block) to be repeated forever. Therefore, the statement (block) must contain at least one BREAK statement to exit the loop. It can also contain CONTINUE statements to jump to the beginning of the loop. To prevent the SyncML engine to hang in case there is an infinite LOOP in a script, any LOOP that takes more than the number of seconds defined in (see  REF _Ref153285595 \r \h 8.10.3, default is 5 seconds) aborts the script execution with an error. WHILE (conditional_expression) statement. New in 3.1: This causes statement (which is normally a statement block) to be repeated as long as conditional_expression is true. The statement (block) may contain BREAK statements to exit the while loop or CONTINUE statements to jump to the beginning of the while loop. To prevent the SyncML engine to hang in case there is an infinite WHILE in a script, any WHILE that takes more than the number of seconds defined in (see  REF _Ref153285595 \r \h 8.10.3, default is 5 seconds) aborts the script execution with an error. RETURN or RETURN expression. This statement can be used to terminate the script and optionally return the specified expression to the caller (whether this makes sense, depends on the script's purpose and is described in the other configuration chapters). Some examples: integer a,b; string s; a=5; b=2; // exit script if a is equal b if (a==b) return false; // loop 5 times a=5; loop { if (a<=0) break; a=a-1; } // chained if/else if (a==1) s="one"; else if (a==2) s="two"; else if (a==3) s="three"; else s="out of range"; Macros Since version 2.9.8.12, the scripting engine also supports macros. Macros are texts (usually consisting of one or more script statements) that are defined once in the section of the config and can then be inserted into any script by name. The sample config makes use of macros to avoid duplication of some lengthy scripts required in serveral different email datatypes. Defining Macros Macros are defined in the section using the tag. The macroname must be unique among all macros and is used to reference the macros in scripts. Like with scripts, using the XML bracket around the actual macro text prevents problems with special XML characters like <,> and & and is strongly recommended. Marco arguments New in 3.4: Macros can have up to 9 arguments. Use $1, $2 … $9 in the macro definiton as placeholders where arguments should be substituted. Using Macros Macros can be used (inserted) in scripts simply by a dollar sign followed by the macro name. See the following example: … other config tags … $MYMACRO d = c + 1; This is equivalent to the following script: integer a,b,c; a = b; c = b*5; d = c + 1; If the macro definition contains placeholders for arguments ($1,$2...$9), see  REF _Ref247357288 \r \h 6.12.2, the macro invocation should provide arguments in parantheses: … other config tags … integer b,f; $MYMACRO(7) // macro call with one argument Functions Functions are called using their name, followed by a comma-separated list of parameters in parantheses. Functions that have no parameters are called just with empty parantheses. Some functions return a value, which can be used in expressions: integer l; string s; timestamp t; // function that returns a value and has one parameter l = length(s); // function that returns a value and has no parameter t = now(); // function with more than one parameter l = find(s,"x",0); User defined Functions User-defined functions must be defined in the section of the config file using a tag for every function to be defined. The function definition starts with the type of the return value (if the function has a return value), followed by the function name, followed by a parameter list in parantheses, followed by a statement block that contains the function's code. Functions can return a value to the caller using the RETURN statement. The parameter list can be empty for functions without parameters, or contains one or multiple comma separated parameter declarations. A parameter declaration is like a variable declaration (see  REF _Ref42672298 \r \h 6.9.1) and consists of a type name followed by the parameter name. This declares a parameter that is passed by value (which means that the value specified when calling the function is stored in a local variable of the function, which can be modified by the function code, but does not affect any variables of the caller). Optionally, parameter passing can also be declared as "by reference" by preceeding the parameter name with an ampersand. This means that the caller of the function must specify a variable (rather than a constant or an expression) for the parameter. If the function code assigns a new value to the parameter, the caller's variable will be changed. Built-in Functions A number of useful functions are built into the script engine. They can be called exactly like user-defined functions. There are two types of built-in functions Global built-in functions: These are generally useful functions that are available in all scripts. See  REF _Ref42673942 \r \h 6.14 for a list. context built-in functions: These are special functions that are only available in a specific context. These functions are described along with the scripts where they are valid. See section  REF _Ref78023979 \r \h 0 for a list of all function names (global and context-specific). Global built-in Function Reference This section lists script functions that are available in all script contexts. Note that there are many more script functions available in some specific script contexts – these are described with the tag they apply to. See section  REF _Ref78023979 \r \h 0 for a list of all function names (global and context-specific). String functions integer XE "LENGTH" \f FLENGTH(expression): returns the length of expression. The result is the number of bytes in the string representation of expression. Note that due to UTF-8 encoding (multi-byte representation of characters outside 7bit ASCII range) the number of characters might be less than the number of bytes. Note that (unlike stated in earlier versions of this document) LENGTH cannot be used to determine the size of an array. Use SIZE() instead. integer XE "SIZE" \f FSIZE(var): returns the size of var. If varis an array, the result is the number of elements in the array. If var is a single value (a non-array or an array element), the result is the number of bytes in the string representation of var. Note that due to UTF-8 encoding (multi-byte representation of characters outside 7bit ASCII range) the number of characters might be less than the number of bytes. Note that SIZE cannot be used to determine the length of a string expression. User LENGTH instead. string XE "LOWERCASE" \f FLOWERCASE(string str): returns an all-lowercase version of str. string XE "UPPERCASE" \f FUPPERCASE(string str): returns an all-uppercase version of str. string XE "NORMALIZED" \f FNORMALIZED(string str): returns normalized version of str. Normalized has only a meaning for string-based types such as simple string (New in 3.1: normalized form is spaces trimmed off at start and end) telephone number (normalized form is number without all separator and spacing characters) or multiline (normalized form is text without leading or trailing empty lines and spaces). integer XE "FIND" \f FFIND(string str, string pattern, integer start): searches for first occurrence of pattern in str, starting the search at start (0=first character). Returns UNASSIGNED if pattern not found, otherwise returns the position of pattern in str (0=at the beginning) integer XE "RFIND" \f FRFIND(string str, string pattern, integer start): searches backwards for first occurrence of pattern in str before start (0=first character). Returns UNASSIGNED if pattern not, otherwise returns the position of pattern in str (0=at the beginning) string XE "SUBSTR" \f FSUBSTR(string str, integer start, integer count): returns substring of str which starts at position start in str and has at most count characters. string  XE "NUMFORMAT" \f F NUMFORMAT(integer num, integer digits [,string filler=" " [, string opts=""]]): formats the number specified in num as a string with digits number of digits or spaces. If digits is negative, the output is left justified, otherwise it is right justified. If filler is specified empty, no padding will occur, otherwise filler is used to pad unused space to make the result digit characters long. Opts can be set to '+' to force a positive sign to be shown, or to ' ' to force a space to be shown for positive numbers. With no opts, negative numbers are prefixed by a '-', positive number have no prefix. If optscontains 'x', the number is formatted in hexadecimal. string  XE "EXPLODE" \f F EXPLODE(string glue, &parts[]): returns the elements of the parts array passed concatenated as a string, elements separated by glue. integer  XE "PARSEEMAILSPEC" \f F PARSEEMAILSPEC(string emailspec, string &name, string &email): Parses emailspec as a RFC2822 email address and puts the descriptive name into name and the plain email address into email. string  XE "MAKEEMAILSPEC" \f F MAKEEMAILSPEC(string name, string email): Makes a RFC2822 email address out of name and email (quoting name if required). Regular Expression functions Note that regular expression support may not be compiled into all versions of the Synthesis SyncML engine, and therefore the following functions may not be available. The pattern string in the following functions can be of the "/rrrr/oo" form, where rrrr is the regular expression and oo are one or multiple options (i,m,s,x,U supported). Alternatively, a regex can be specified directly without delimiters, as long as it does not start with a /. Please refer to general documentation about regular expressions for information about how to work with regular expressions. The regular expression engine used in Synthesis SyncML engine is PCRE which is documented in the internet at  HYPERLINK "http://www.pcre.org/" http://www.pcre.org/. integer XE "REGEX_FIND" \f F REGEX_FIND(string subject, string pattern [, integer startat]): searches for first occurrence of pattern in subject, starting the search at startat (0=first character). Returns UNASSIGNED if no match is found, otherwise returns the position of where pattern matches in subject (0=at the beginning). integer XE "REGEX_MATCH" \f F REGEX_MATCH(string subject, string pattern, integer startat, string &matches[]): searches for the first match of pattern within subject, starting the search at startat (0=first character). Returns UNASSIGNED if no match is found, otherwise returns the position of the match. Additionally, the matches array will contain the entire matched string in its first element, and paranthesized subpattern matches within pattern in the subsequent elements. If a non-array is passed for matches, that variable is assigned either the entire matched string (if pattern does not specify subpatterns) or the first subpattern (if pattern does specify at least one subpattern). integer XE "REGEX_SPLIT" \f F REGEX_SPLIT(string subject, string separatorpattern, string &elements [, boolean emptyElements]): Splits subject into string elements and store them in elements. The string is split where separatorpattern matches in subject. If emptyElements is set to ture, elements consisting of nothing (i.e. two separators in succession) will be stored as such in elements, otherwise empty elements will be ignored. string XE "REGEX_REPLACE" \f F REGEX_REPLACE(string subject, string pattern, string replacement [, integer startat [, integer repeat]]): Replaces matches of pattern within subject with replacement. Pattern matching starts at startat in subject (default = 0) and continues repeat times (default = 0 which means all occurrences are replaced). Date and Time functions timestamp XE "NOW" \f FNOW(): returns the current time of the SyncML server in UTC. Note that the database time might not be fully in sync with this. Use DBNOW() if you need accurate database time. timestamp XE "DBNOW" \f FDBNOW(): returns database's current time in UTC. Note that calling this function will cause a database access, so use it with care to avoid performance degradation. timestamp XE "SYSTEMNOW" \f F SYSTEMNOW(): returns the current time of the SyncML server in the system's local time. Note: while this is usually a shortcut for CONVERTTOZONE(NOW(),"SYSTEM"), there might be implementations that do not have time zone support at all. In these implementations, NOW() would not return a proper value, but SYSTEMNOW() will. XE "SLEEPMS" \f F SLEEPMS(integer milliseconds): suspends the current thread for the given number of milliseconds. Accuray depends on the platform, not all platforms support millisecond resolution for sleeping, so actual time might differ. timestamp XE "DATEONLY" \f FDATEONLY(timestamp ts): returns the date part of ts as a date-only value (which corresponds to a floating timestamp with a 0:00:00 time part). However, a date-only value has a special flag set to differentiate it from a timestamp, which is used for example when rendering time/date values in ISO8601 (for example, in the "autodate" conversion mode for vCalendar items, see  REF _Ref182995906 \r \h 10.3.4). timestamp  XE "TIMEONLY" \f F TIMEONLY(timestamp ts): returns the time part of ts as a time-only value (which is the number of time units since midnight). integer XE "ISDATEONLY" \f FISDATEONLY(timestamp ts); returns true (1) if tsis a date-only value. timestamp  XE "DURATION" \f F DURATION(timestamp ts): returns the timestamp as a duration. Duration timestamps are rendered in the ISO8601 duration format. The timestamp's internal value will not be affected by the conversion to duration format. timestamp  XE "POINTINTIME" \f F POINTINTIME(timestamp ts): returns the timestamp as a point in time. This is useful to convert duration timestamps back into timestamps that represent a point in absolute time, and are rendered in ISO8601 date/time format. The timestamp's internal value will not be affected by the conversion to a point in time. integer  XE "ISDURATION" \f F ISDURATION(timestamp ts); returns true (1) if tsis a duration value. integer XE "WEEKDAY" \f F WEEKDAY(timestamp ts): returns weekday of day represented by ts (0=sunday, 1=monday ... 6=saturday). integer XE "SECONDS" \f FSECONDS(timestamp ts): returns number of seconds corresponding to ts (which makes most sense if ts is a difference between two timestamps, that is, a duration). integer XE "MILLISECONDS" \f FMILLISECONDS(timestamp ts): returns number of milliseconds corresponding to ts (which makes most sense if ts is a difference between two timestamps, that is, a duration). integer XE "TIMEUNITS" \f F TIMEUNITS(integer seconds): returns number of time units (normally milliseconds, but can be another unit depending on platform capabilities) corresponding to the specified number of seconds. Time units can be added or subtracted from time stamps. integer XE "DAYUNITS" \f F DAYUNITS(integer days): returns number of internal time units (normally milliseconds, but can be another unit depending on platform capabilities) corresponding to the specified number of days. Time units can be added or subtracted from time stamps. integer XE "MONTHDAYS" \f F MONTHDAYS(timestamp date): returns number of days of the month date is in. integer XE "ALLDAYCOUNT" \f F ALLDAYCOUNT(timestamp start, timestamp end [, boolean checkinusercontext [, boolean onlyutcinusercontext]]): This functions examines the start and end timestamps to check if these represent an all-day event, and if so, how many days it spans. This function is designed to operate on vCalendar 1.0 and iCalendar 2.0 DTSTART and DTEND values, and takes into account that in vCalendar 1.0 All-day events cannot be represented as such, but just as events starting at midnight, and ending at next midnight or 23:59. If the result is 0, start and end do not specify an all-day event, otherwise, the result is the number of days. The input timestamps must be in the context in which they are to be checked for midnight, 23:59:xx etc. except if checkutcinusercontext ist set. If so all non-floating timestamps (onlyutcinusercontext = false) or all UTC timestamps (onlyutcinusercontext = true) will be converted to user time zone before checking for all day boundaries. XE "MAKEALLDAY" \f F MAKEALLDAY(timestamp &start, timestamp &end [,integer days]): This function is designed to adjust start and end suitable for using it with the "autodate" and "autoenddate" conversion modes (see  REF _Ref182995906 \r \h 10.3.4). If days is omitted or set to <=0, the difference between end and start determines the number of days. If days is set to >0, the input value of end is ignored, and an all-day of days days length is created starting at start. On input, timestamps must already represent local day times. On output, the timestamps are made floating. timestamp XE "RECURRENCE_DATE" \f F RECURRENCE_DATE(timestamp start, string rr_freq, integer interval, integer fmask, integer lmask, boolean occurrencecount, integer count): Returns the date of the countth iteration of a recurrence rules. If occurrencecount is true, the countth occurrence is calculated, otherwise the countth repetition of the entire rule interval (the latter is relevant for vCalendar 1.0 RRULE #n repetition value). See  REF _Ref36890908 \r \h 10.6 for a description of the start, rr_freq, interval, fmask and lmask parameters. integer XE "RECURRENCE_COUNT" \f F RECURRENCE_COUNT(timestamp start, string rr_freq, integer interval, integer fmask, integer lmask, boolean occurrencecount, timestamp occurrence): Returns the count of a given occurrence date relative to the beginning of a recurrence rule. If occurrencecount is true, the count returned is the occurrence count, otherwise it is the repetition count of the entire rule interval (the latter is relevant for vCalendar 1.0 RRULE #n repetition value). See  REF _Ref36890908 \r \h 10.6 for a description of the start, rr_freq, interval, fmask and lmask parameters. If no recurrence count can be calculated for occurrence, the function returns UNASSIGNED. string  XE "MAKE_RRULE" \f F MAKE_RRULE(boolean rrule2, string rr_freq, integer interval, integer fmask, integer lmask, timestamp until): Creates a RRULE from the RRULE block parameters specified (see  REF _Ref36890908 \r \h 10.6 for a description of the start, rr_freq, interval, fmask, lmask and until parameters). If rrule2 is set to true, a iCalendar 2.0 style RRULE will be created, otherwise, a vCalendar 1.0 RRULE is returned. boolean XE "PARSE_RRULE" \f F PARSE_RRULE(boolean rrule2, string rrule, timestamp start, string &rr_freq, integer &interval, integer &fmask, integer &lmask, timestamp &until): Parses a RRULE string into RRULE block parameters specified (see  REF _Ref36890908 \r \h 10.6 for a description of the rr_freq, interval, fmask, lmask and until parameters). If rrule2 is set to true, a iCalendar 2.0 style RRULE is expected in rrule, otherwise, a vCalendar 1.0 RRULE is expected. The start parameter must be set to the starting point of the recurring calendar entry. The function returns true if rrule could be successfully parsed, false otherwise. integer XE "ISRELATIVE" \f FISRELATIVE(timestamo ts): No longer supported in 3.1. Usually ISFLOATING() provides the same functionality, but please read  REF _Ref204926421 \r \h 5.1 about the general changes in the way timestamps are represented in 3.1 vs. 3.0. XE "SETRELATIVE" \f FSETRELATIVE(timestamp &ts): No longer supported in 3.1. Usually SETFLOATING() provides the same functionality, but please read  REF _Ref204926421 \r \h 5.1 about the general changes in the way timestamps are represented in 3.1 vs. 3.0. timestamp XE "LOCALIZEDASUTC" \f FLOCALIZEDASUTC(timestamp ts): No longer supported in 3.1. The functionality itself is no longer needed as the new 3.1 way of representing timestamps (see  REF _Ref204926421 \r \h 5.1) makes it obsolete. integer XE "LOCALZONEOFFSET" \f FLOCALZONEOFFSET():No longer supported in 3.1. Replacements are usually USERTIMEZONE() or TIMEZONE(SYSTEMNOW()). timestamp XE "RELATIVEASUTC" \f FRELATIVEASUTC(timestamp ts): No longer supported in 3.1. The functionality itself is no longer needed as the new 3.1 way of representing timestamps (see  REF _Ref204926421 \r \h 5.1) makes it obsolete. XE "SETZONEOFFSET" \f FSETZONEOFFSET(timestamp &ts, integer zoneoffset): No longer supported in 3.1. Usually SETTIMEZONE() provides the same functionality, but please read  REF _Ref204926421 \r \h 5.1 about the general changes in the way timestamps are represented in 3.1 vs. 3.0.. timestamp XE "UTCASRELATIVE" \f FUTCASRELATIVE(timestamp ts): No longer supported in 3.1. The functionality itself is no longer needed as the new 3.1 way of representing timestamps (see  REF _Ref204926421 \r \h 5.1) makes it obsolete. Time zone related functions Some of the time zone related functions have a timezonespec parameter. This parameter specifies a time zone in one of the following ways: when a timestamp type is passed, the time zone is copied from the specified timestamp. when a integer type is passed, the time zone is set to the given number of seconds east of GMT/UTC when an empty value or the string value "FLOATING" is passed, the result is no time zone (i.e floating timestamp). when a string value of "USERTIMEZONE" is passed, the current user time zone (see  REF _Ref185257870 \r \h 5.2) is used. when a string value of "SYSTEM" is passed, the current system time zone is used. when a string value beginning with "BEGIN:VTIMEZONE" is passed, it is paresed as a timezone specification in vTIMEZONE format. when the string value names one of the defined zone names (see list in chapter  REF _Ref185261956 \r \h 17), the corresponding zone is used. finally, the string can specify a time zone offset specified in ISO8601 format. Script functions that return a timezonestring either return: the name of the time zone (see list in chapter  REF _Ref185261956 \r \h 17) as string an empty string for floating timestamps a time zone offset in ISO8601 format for fixed UTC offset time zones timezonestring XE "TIMEZONE" \f F TIMEZONE(timestamp atime): returns the time zone associated with atime. string XE "VTIMEZONE" \f F VTIMEZONE(timestamp atime): returns the time zone associated with atime formatted as a vTIMEZONE entry. XE "SETTIMEZONE" \f F SETTIMEZONE(timestamp &atime, timezonespec zone): sets the time zone of atime to the specified zone. Note that the local time value of atime does not change (which means that the absolute time value changes by the difference of the old and new time zone). integer XE "ISFLOATING" \f F ISFLOATING(timestamp ts); returns true (1) if tsis a floating timestamp (i.e. a timestamp not associated with a time zone). XE "SETFLOATING" \f F SETFLOATING(timestamp &atime): this is a shortcut for SETTIMEZONE(atime, "FLOATING"), and removes time zone information from atime, thus making atime a floating timestamp (not associated to any time zone). string XE "USERTIMEZONE" \f F USERTIMEZONE(): returns the current user time zone (see  REF _Ref185257870 \r \h 5.2), as set by SETUSERTIMEZONE() or . The default is "SYSTEM". XE "SETUSERTIMEZONE" \f F SETUSERTIMEZONE(timezonespec tz): sets the user time zone (the time zone context used to evaluate local time specifications which do not include an originating time zone information, see  REF _Ref185257870 \r \h 5.2). The default user time zone can be configured using (see  REF _Ref204922935 \r \h 11.22) and defaults to "SYSTEM". timestamp XE "CONVERTTOZONE" \f F CONVERTTOZONE(timestamp atime, timezonespec zone [,boolean doUnfloat]): returns atime converted to the specified zone. This means that the absolute value (UTC time) of the result will be the same as that of atime, but represented in a different time zone and therefore having a different local time value. A special case are floating time stamps – these cannot be actually converted to a different time zone, as they have no zone to begin with. If doUnfloat is set to true, floating time stamps will be made local time of the specified zone, without changing their time value. Otherwise, floating timestamps will be returned as-is. timestamp XE "CONVERTTOUSERZONE" \f F CONVERTTOUSERZONE(timestamp atime [,boolean doUnfloat]): this is a shortcut for CONVERTTOZONE(atime, "FLOATING", doUnfloat), and returns atime converted to the current user time zone. integer XE "ZONEOFFSET" \f FZONEOFFSET(timestamp ts): returns offset in number of seconds, east of UTC/Greenwich of ts. If ts is a floating timestamp, this function will return UNASSIGNED. Debug log functions XE "DEBUGMESSAGE" \f FDEBUGMESSAGE(string message): writes message to the debug log. Note that these messages are only shown in the log if the "hot" option in (see  REF _Ref42675268 \r \h 8.11.2) is enabled.  XE "DEBUGSHOWITEM" \f F DEBUGSHOWITEM(boolean refItem): In scripts that have access to a data item (a collection of fields as defined in a field list, see  REF _Ref47156991 \r \h 6.9.3), this function can be called to dump the contents of the data item into the log file (if the debug options are set such that user data can be shown in logs at all, see "userdata" option in  REF _Ref42675268 \r \h 8.11.2). For scripts that operate on two data items (for example: , see  REF _Ref204932692 \r \h 10.5.12), setting refItem to true shows the reference item (depending on the context, also called "loosing" or "old" item) instead of the normal (sometimes called "winning") item. XE "DEBUGSHOWVARS" \f F DEBUGSHOWVARS(): This dumps a list of all local variables of the current script and their current values to the debug log. integer XE "GETDEBUGMASK" \f F GETDEBUGMASK(): returns the currently active debug options for the current sync session as 32 bit integer value representing flags for each possible debug option, see  REF _Ref47170147 \r \h 8.11. This is useful to temporarily change the debug options in a script (see SETDEBUGOPTIONS and SETDEBUGMASK) and later restore the original options. XE "SETDEBUGMASK" \f F SETDEBUGMASK(integer mask): should be used only to restore a debug channel configuration previously saved from GETDEBUGMASK. To enable or disable debug channels, please use SETDEBUGOPTIONS. XE "SETDEBUGOPTIONS" \f F SETDEBUGOPTIONS(string optionname, boolean enable): This is the equivalent of the (when enable is true) and (when enable is false) tags in the section, see  REF _Ref42675268 \r \h 8.11.2. The same names that are valid for the "option" attribute in and can be used for optionname. XE "SETXMLTRANSLATE" \f F SETXMLTRANSLATE(boolean enable): This function allows switching on or off writing an XML transcript of the SyncML messages for the current session. This can be used for example in the (see  REF _Ref43727925 \r \h 11.33) to selectively switch on XML loggin based on device or user name. See in  REF _Ref203481904 \r \h 8.11.14 for details about the files created. XE "SETXMLTRANSLATE" \f F SETMSGDUMP (boolean enable): This function allows switching on or off dumping SyncML messages to files for the current session. This can be used for example in the (see  REF _Ref43727925 \r \h 11.33) to selectively switch on SyncML message dumping based on device or user name. See in  REF _Ref203481972 \r \h 8.11.15 for details about the files created. Other functions integer  XE "ABS" \f F ABS(integer value): returns the absolute of value. integer  XE "SIGN" \f F SIGN(integer value): returns the sign of value, that is, 0 if value is 0, 1 if value>0 and -1 if value<0. integer  XE "RANDOM" \f F RANDOM(integer range [, integer seed]): returns a random number between 0 and range-1. The optional seed can be specified to seed the random generator. string  XE "SYNCMLVERS" \f F SYNCMLVERS(): This function returns the SyncML version number (currently one of "1.0", "1.1" or "1.2") of the running session. This can be useful to implement version dependent behaviour.  XE "ABORTSESSION" \f F ABORTSESSION(integer statuscode): aborts the current session and reports statuscode as the reason for aborting the session. Note that statuscode can be 0 to abort silently. integer XE "COMPARE" \f FCOMPARE(value1, value2): returns 0 if value1 equals value2, -1 if value1 < value2, 1 if value1 > value2 and -999 if values cannot be compared. integer  XE "CONTAINS " \f F CONTAINS (&variable, value [, bool caseinsensitive]): returns 1 (true) if value is contained in variable. "Contain" means that value is a substring of variable, or in case value is an array,.it means that value is a substring of one of variable's elements. caseinsenstive can be set to make the comparison case insensitive.  XE "APPEND " \f F APPEND (&variable, value): appends value to the contents of variable. If variable is an array, appending means adding a new element. If value is an array, all elements of value will be appended to variable one by one. boolean  XE "ISAVAILABLE" \f F ISAVAILABLE(field): checks if field (which must be a field from the , see  REF _Ref42589436 \r \h 10.1, of the item processed in the current script's context) is explicitly available for the current sync. Explicitly available means that the remote's device information was received and contained a list of fields supported by the remote party. If this is the case, this function returns true or false. If a non-field (e.g. a script local variable) is specified for field, UNASSIGNED is returned. If a field is specified, but no explicit availability is known from the remote, the function returns EMPTY. This function is useful in and (see  REF _Ref206062819 \r \h 10.5.9) to format data differently depending on what fields are supported – for example including some data from unsupported fields into the description text.  XE "REQUESTMAXTIME" \f F REQUESTMAXTIME(integer maxtime): this allows to set the max time in seconds the server should spend processing a request before it should return an answer to the client. See in  REF _Ref70164511 \r \h 11.3 for details.  XE "REQUESTMINTIME" \f F REQUESTMINTIME(integer mintime): this allows to artificially delay server responses to be sent not earlier than mintime seconds after the request reached the server. See for details ( REF _Ref207622654 \r \h 11.4).  XE "FORCELOCALTIME" \f F FORCELOCALTIME(boolean flagvalue): this allows modifying the flag that is controlled by the directive in , see  REF _Ref54091188 \r \h 11.36.13.  XE "FORCEUTC " \f F FORCEUTC(boolean flagvalue): this allows modifying the flag that is controlled by the directive in , see  REF _Ref54091192 \r \h 11.36.14.  XE "SHOWCTCAPPROPERTIES" \f F SHOWCTCAPPROPERTIES(boolean flagvalue): this allows modifying the flag that is controlled by the directive (see  REF _Ref153773639 \r \h 11.25).  XE "ENUMDEFAULTPROPPARAMS" \f F ENUMDEFAULTPROPPARAMS(boolean flagvalue): this allows modifying the flag that is controlled by the directive (see ). string XE "LOCALURI" \f FLOCALURI(): returns the original URI used by the client to start the server session. string XE "REMOTERULENAME" \f FREMOTERULENAME(): returns the name of the active (see  REF _Ref42941679 \r \h 11.36) or EMPTY if no remoterule is active in the session. This can be used to implement device-specific behaviour. XE "SETREADONLY" \f FSETREADONLY(integer readonly): If readonly is set to TRUE, the session will be read-only (clients cannot apply any changes to the server's database). See also per-datastore read-only option in  REF _Ref45368759 \r \h 11.34.4 and per-datastore version of SETREADONLY in  REF _Ref55271118 \r \h 11.34.21. XE "SETDEBUGLOG" \f FSETDEBUGLOG(integer enabled): Enables or disables the session log for this session. XE "SETLOG" \f FSETLOG(integer enabled): Enables or disables logging this session's result in the log file/log table. any_type XE "SESSIONVAR" \f FSESSIONVAR(string varname): Returns the value of the session context variable varname (Session context variables can be declared for example in , see  REF _Ref43008951 \r \h 11.11). This allows to access context variables (see  REF _Ref42672298 \r \h 6.9.1) of the session's context from any script (and not only from those running in session context). This allows using session context variables as a kind of global variables. Note that accessing variables this way is less efficient (access by name needs string search) than normal variable references (access through precompiled index). If varname does not exists, UNASSIGNED is returned. XE "SETSESSIONVAR" \f FSETSESSIONVAR(string varname, value): Assigns a new value to the session context variable varname. integer  XE "SHELLEXECUTE" \f F SHELLEXECUTE(string command, string params, integer backgroundflag): Calls the operating system's shell to execute the command with the specified params. If backgroundflag is true, the shell process is started in background and SHELLEXECUTE immediately returns with result=0 (Note that background execution might not be available on all platforms!). Otherwise, SHELLEXECUTE waits until the shell command completes and then returns the exit code of the command executed. The exit code is operating system specific. In case that the command could not be started at all, SHELLEXCUTE returns -1. Note: using SHELLEXECUTE often makes the configuration file platform-dependent. Therefore, using the "platform" attribute (see  REF _Ref153284855 \r \h 4) is recommended in scripts using SHELLEXECUTE to make sure the script only runs on the right platform, or to provide multiple variants of the script for each platform. XE "SWAP" \f FSWAP(variable1, variable2): swaps the contents of variable1 and variable2.  XE "UPDATECLIENTINSLOWSYNC" \f F UPDATECLIENTINSLOWSYNC(boolean flagvalue): this allows modifying the flag that is controlled by the < updateclientinslowsync > directive in , see  REF _Ref45001933 \r \h 11.36.6.  XE "UPDATESERVEINSLOWSYNC" \f F UPDATESERVEINSLOWSYNC(boolean flagvalue): this allows modifying the flag that is controlled by the directive in , see  REF _Ref54091553 \r \h 11.36.7.  XE "TREATASLOCALTIME" \f F TREATASLOCALTIME(boolean flagvalue): this allows modifying the flag that is controlled by the directive in , see  REF _Ref54091119 \r \h 11.36.15.  XE "TREATASUTC" \f F TREATASUTC(boolean flagvalue): this allows modifying the flag that is controlled by the directive in , see  REF _Ref97961473 \r \h 11.36.16. string XE "TYPENAME" \f FTYPENAME(value): returns the name of the type of value. string  XE "ITEMDATATYPE " \f F ITEMDATATYPE (): returns the internal name of the datatype of the current item (only usable in context that are processing a data item at all). The datatype name is the name specified in the tag, see  REF _Ref231887961 \r \h 10.5 string  XE "ITEMTYPENAME " \f F ITEMTYPENAME (): returns the MIME type name of the datatype of the current item (only usable in context that are processing a data item at all). The datatype name is the name specified in the tag, see  REF _Ref231888133 \r \h 10.5.3 (or implicitly set by the basetype attribute of , see  REF _Ref231887961 \r \h 10.5) string  XE "ITEMTYPEVERS " \f F ITEMTYPEVERS (): returns the type version string of the datatype of the current item (only usable in context that are processing a data item at all). The datatype version is the name specified in the tag, see  REF _Ref231888133 \r \h 10.5.3 (or implicitly set by the basetype attribute of , see  REF _Ref231887961 \r \h 10.5) Debugging scripts Scripts can be debugged by switching on the "scripts" option in the directive (see  REF _Ref42675268 \r \h 8.11.2). This will cause that every script line processed to be shown in the debug log along with some information about the expressions evaluated and variables assigned (see "expressions" option in the directive for enabling more in-depth expression debugging). If you use HTML formatted logs, the script source will be colored gray for script lines that were skipped unexecuted due to flow control. Note that using this debug option not only can generate huge logfiles and degrades performance, but also needs slightly more memory per sync session as the script engine must keep the script source code in memory (when debugging is off, scripts are stored in a compressed, tokenized form only). When the "exotic" debug option is enabled as well, the script processing is logged in extensive detail – this is only recommended for hard core debugging. The script engine is designed for efficiency, and is not meant to be a general-purpose programming language, and therefore there is no real debugger available. If your scripts get too large and complicated to be debugged and tested with the simple debug log feature, you should probably re-think your application design in general. Scripts are provided to add more flexibilty to adapt SyncML to your application, but not to implement things that should be done in the application itself. If you feel that the adaption to your database exceeds what can be done reasonably with scripts, please consider using the plugin API for database adapters available in the PRO products. This allows you to separate all database access code into an external plugin project written in C, C++, Java or .net. See  REF _Ref135023442 \r \h 14 for details. Filters There are three types of Filters that can be used: Inclusive or Temporary Filter expressions: This type of filter defines conditions for content to be transmitted to a remote party, that is, included into the sync set (the set of items that are being synced). However, a inclusive filter does not exclude items from the sync set. This means that if for instance the client already contains items (from a previous sync session) that do not pass an inclusive filter, they will not be deleted on the client (in contrast, with a dynamic or static exclusive filter, see below, these would be deleted). In SyncML 1.0 and 1.1 terminology, these type of filters were called Target Address Filters (TAF), and can be specified as part of the database path using a CGI syntax. In SyncML 1.2 and later, these filters are called Inclusive Filters and are transmitted from client to server using the and SyncML elements in the CGI syntax (see  REF _Ref153291752 \r \h 7.4). Dynamic exclusive Filter expressions: These allow clients to request synchronizing only a subset of the database by specifying constraints. In Synthesis SyncML servers dynamic exclusive filters can be specified similar to TAF in the database path. This is a Synthesis-specific option and not part of the SyncML standard. An events path could look like "./events?/fi(DTSTART>20030630T000000Z)" which would restrict the sync set to events starting after July 2003. In SyncML 1.2, the and SyncML elements are used to specify exclusive filters in the CGI syntax (see  REF _Ref153291752 \r \h 7.4). Synthesis SyncML servers still support the SyncML 1.1 methods (TAF and /fi, even for SyncML 1.2). Static Filter expressions used in the config file: Filters are also used internally, for example to split a common "calendar" database into "events" and "tasks" or to implement visibility control for records based on a special database field or the type of device connected (as an example some devices cannot handle dates before a certain date, so these can be filtered out by setting a static filter. See the sample config files for examples. The inclusive filters are simply applied just before sending data to the client – only data passing the filter is included, other data it is just ignored and not sent to the client. The term dynamic is used with exclusive filters to specify that the filter might change between sync sessions and therefore some records which were filtered out (= excluded) in one session get visible in the next session and vice versa. Dynamic filters can put considerable load to the SyncML server as applying them might require the server to load all records from the database instead of the changed ones. However, if the dynamic filter is such that it can be translated to a SQL WHERE clause, the performance penalty is much smaller (see in  REF _Ref69052620 \r \h 12.20.9). A static filter is a filter that is guaranteed not to change between sync sessions with a particluar device, such as filter specified in the server configuration or set depending on the device that is being synced. Static filters are much more efficient because only those records that have changed or added need to be filtered. There is one important reason why the Synthesis SyncML engine supports filters in parallel with scripting (which might look like the same thing was implemented twice): The filter syntax is such (much simpler than script expression syntax) that the SyncML engine can translate most filter expressions directly to SQL WHERE clause expressions. This is a huge performance benefit, because this way, only needed data gets fetched from the database at all (while otherwise, as explained above for dynamic filters all records need to be fetched from the database only to be checked against a filter. This might be needed for complex situations where a filter is not flexible enough (see in  REF _Ref46904847 \r \h 10.5.10), but should be avoided whenever possible. Test and Make-Pass modes Filters are used by the SyncML engine in two modes: Test Mode: This is the normal mode, and means that a filter expression is applied to a data item, which gives a result of true (item passes) or false (item does not pass). Make-Pass Mode: Sometimes, the engine must make sure that an internally generated item will pass a certain filter. In this case, the filter expression is applied to the data item first like in test mode, and if the result is true, nothing more happens. If the result is false (item does not pass), the assign-to-pass modifiers (see below,  REF _Ref46823382 \r \h 7.2) in the filter expressions are applied from left to right until the data item passes the filter. Basic filter syntax The filter syntax might look a little unusual - however it is modeled after the TAF (Target Address Filter) syntax proposed by the SyncML standard for the temporary filters. The SyncML standard does not specify dynamic or static filters, but we use the same syntax (with some extensions) for all three filter types. A filter expression either consists of a single filter term or multiple filter terms concatenated with logical operators. Logical operators are: & (and), | (or). Note that there is no "NOT" operator. A filter term consists of a filter expression enclosed in parantheses or of an identifier followed by a comparison operator followed by a constant. A identifier is usually the name of an property or header field in a content format like vCard or RFC2822 email, but can also directly reference internal fields from the . There are also a number of predefined special identifiers. Details see  REF _Ref153288035 \r \h 7.3. Comparison operators are the usual =,<>, >, <, >=, <=. In addition % means "contains" and $ means "does not contain" (for strings). Comparison operators can be preceeded by three optional prefix characters, only in the following order: a colon, called the assign-to-pass modifier, which means "assign to make true". This modifier is ignored in test mode (see  REF _Ref47262189 \r \h 7.1), but used when by the sync engine in make-pass mode (when it needs to make a data item pass a filter and signals that assigning the value on the right of the operator to the field on the left of the operator will make the filter term evaluate to true). Note that, obviously, this makes only sense for comparisons where such an assignment actually makes the expression true: "FIELD := 2" will assign the value 2 to FIELD, which makes the comparison FIELD=2 true. However, "FIELD :<> 2" will not work, as assigning 2 to FIELD will obviously make the expression evaluate to false. an asterisk, which means that the following constant is a special value (see below). a '^' character, which makes the comparison case insensitive. Constants are string representations of the values to be compared. For strings, this is simply the characters the string consists of (no quotes around the string, no "&" or "|" or ")" might be contained). Numbers must be entered as decimal integers. Date and time values must be entered in ISO8601 format (yyyymmddThhmmssZ, for example 20030724T120000Z). If the Comparison operator  is immediately preceeded by an asterisk, the Constant is treated as a special value: E meaning "empty" or N meaning "not assigned". A few examples: FIELD:*=E Means: test if FIELD is empty. If the sync engine needs to make a data item pass the filter, it will assign an empty value to FIELD. FIELD:>=2 Means: test if FIELD greater than or equal 2. If the sync engine needs to make a data item pass the filter, it will assign the value 2 to FIELD. FIELD^=a simple text Means:case insensitive test if FIELD contains the string "a simple text" ("A Simple Text" would match as well, as the comparison is case insensitive). There is no colon prefix, so the sync engine will not assign anything to FIELD even in case a data item needs to be made pass the filter (which means that the item cannot be made pass the filter, if the shown filter term is the entire filter expression). FIELD1*=E|FIELD2:=4 Means: test if FIELD1 is empty or FIELD2 equals 4. If the sync engine needs to make a data item pass the filter, it will assign 4 to FIELD2, but only if FIELD1 is not empty - otherwise the expression is already true without modifying anything. Identifiers in filters Filter identifiers reference values that are to be compared. The following identifiers can be used in filter expressions: a property name: for MIME-DIR based formats like vCard and vCalendar, properties of the format (like TITLE, DTSTART, SUBJECT, etc) can be referenced directly by name. a header line name: for textprofile-based formats like email, named headers like "Cc", "From", "To" can be referenced directly. a filter keyword: textprofile and dataobj based formats allow defining keywords for some headers and content fields. a field name from the : This gives direct access to the value of an internal field. This is useful e.g. to access elements of multi-value properties like N or ADR in vCard. To make sure an identifier is used to access the field list (and not a predefined special identifier), it can be prefixed by "F.", like "F.N_FIRST". for vCalendar: START, END – these are aliases for DTSTART and DTEND. for vCard: FAMILY, GIVEN – these are aliases for the lastname and firstname components of the N property. for vCard: GROUP – this is an alias for the CATEGORIES property. LOCALID – this means the local identifier (e.g. database key) of an item. REMOTEID – available in servers only. This means the identifier the client uses for a certain item. GUID –available in servers only. This is equivalent to the server's LOCALID. LUID or &LUID;– in a server, this is equivalent to REMOTEID, in a client it is equivalent to LOCALID. SINCE, BEFORE – these can only be used in CGI filters and SyncML DS 1.2 , but not in static filter expressions in the configuration file. These are pseudo-identifiers for defining a date range filter. SINCE&EQ;20061206T120000&AND;BEFORE&EQ;20061231T090000 for example means the range from December 6th 12PM to December 31th 9AM, 2006. See also /dr() below. MAXSIZE, MAXCOUNT – these can only be used in CGI filters and SyncML DS 1.2 , but not in static filter expressions in the configuration file. These are pseudo-identifiers for defining a maximum item size (in bytes) or a maximum item count, resp. See also /limit() and /max() below NOATT - this can only be used in CGI filters and SyncML DS 1.2 , but not in static filter expressions in the configuration file. Setting this equal to 1 (or "true" or "yes") suppresses attachments. See also /na below. DBOPTIONS – this can only be used in CGI filters and SyncML DS 1.2 , but not in static filter expressions in the configuration file. It can be used to pass a string of implementation specific DB options. See also /o () below. CGI Filter Syntax When filter expressions are passed in the database path for SyncML 1.0 and SyncML 1.1, or when passing them via the element in SyncML 1.2, they must be formatted like CGI parameters. The Synthesis SyncML engine also accepts most of the operators literally (useful when entering in phone clients with difficult input methods) , however to follow the SyncML standard, the following entities must be used: &EQ; = equal (case sensitive) &iEQ; ^= equal (case insensitive) > > greater than (case sensitive) &iGT; ^> greater than (case insensitive) &GE; >= greater or equal (case sensitive) &iGE; ^>= greater or equal (case insensitive) < < less than (case sensitive) &iLT; ^< less than (case insensitive) &LE; <= less or equal (case sensitive) &iLE; ^<= less or equal (case insensitive) &NE; <> not equal (case sensitive) &iNE; ^<> not equal (case insensitive) &CON; % contains (case sensitive) &iCON; ^% contains (case insensitive) &NCON; $ does not contain (case sensitive) &iNCON; ^$ does not contain (case insensitive) & & and &AND; & and &OR; | or &LUID; is an alias for the LUID identifier. &NULL; can be used as value and means "no value" or "empty value". &UNASSIGNED; can be used as value and means "no value assigned". In addition, in the value part of a filter term (the part following after the operator), a % sign followed by two digit hex number is interpreted as the the character with the ASCII-code or UTF-8 sequence element corresponding to the hex number, to allow including any char into values. Therefore, the following two filter expressions are synonymous: FIELD1*&EQ;&NULL;∨FIELD2:&iEQ;test FIELD1*=E|FIELD2:^=test Special options in CGI filters passed with database path As the SyncML 1.0 and 1.1 standards only provide TAF filters (temporary inclusive filters), Synthesis SyncML engine also parses some special options in the CGI to allow for additional flags and for differentiating between excklusive and inclusive filters: /dr(-before,after) This specifies a date range relative to today, starting before days before today and ending after days after today. Note that actually implementing a date range filter for a datastore in a server needs scripting (see in in  REF _Ref46821357 \r \h 10.5.4). Alternatively, the SINCE and BEFORE pseudo-identifiers can be used for defining a absolute date range, see  REF _Ref153288035 \r \h 7.3. /li(kbytes) This specifies a limit for example when dealing with possibly large data objects such as email. Note that actually implementing a limit for a datastore in a server needs scripting (see in in  REF _Ref46823145 \r \h 10.5.11). Alternatively, the MAXSIZE pseudo-identifier can be used for defining a size limit. /o(string) This specifies an option string. The option string can be parsed in scripts, such as the to archieve special user-defined behaviour. Alternatively, the DBOPTIONS pseudo-identifier can be used for setting database options. /slow Server only: this forces a slow sync even if neither client nor server have requested it. This is useful for clients which have no GUI to force a slow sync (such as Nokia 9210) /na This specifies that no attachments should be transmitted to the remote party. This is useful for clients which cannot handle them to reduce traffic. Alternatively, the NOATT pseudo-identifier can be set to true to suppress attachments. /max(items) This specifies a limit for the number of items to be sent to the remote (for example how many of the most recent email messages are to be sent). Note that actually implementing a limit for a datastore in a server needs scripting (see in  REF _Ref55271118 \r \h 11.34.21). Alternatively, the MAXCOUNT pseudo-identifier can be used for setting the item count limit. /fi(filter expression) This option is provided to allow to specify dynamic filters (rather than temporary) in the CGI. /tf(filter expression) This option is provided to allow to specify temporary filters mixing other options with filters in the same CGI. If only a filter expression is used, it can be specified in the CGI without the /fi option. So the following two examples are synonymous: FIELD1=3 /tf(FIELD1=3) Note that while our own SyncML client products may provide user interface for these options, they work with any SyncML client that allows entering the database paths. Filters in the configuration Filters used in the configuration must always be specified in the basic filter syntax (see  REF _Ref46823382 \r \h 7.2 above). None of the extra GCI options are allowed (nor would they make sense) in filters in the configuration. For details, see the description of the filtering tags (such as etc.). General Global Configuration Options XE "licensename" \f T, XE "licensecode" \f T: License Contained in: Can contain: nothing Attributes: none Available: in non-demo versions These tags are used to enable the server or client according to a license purchased. Please fill in the license name and code you have received with your purchase of the product as shown in the following sample: joe tester joe@company.com 2HRY-23LU-45AG-ORN5 If license name and code are correct, the product will work according to what you have licensed. The license information affects the number of simultaneous connections a server can handle, see  REF _Ref47451551 \r \h 8.2. Note that there are permanent licenses (work forever) and time-limited evaluation licenses (stop working after a certain date). The license may also grant or deny access to some features, like using external plugin modules etc. XE "maxconcurrentsessions" \f T: concurrent sessions limit Contained in: Can contain: integer value Attributes: none Available: in evaluation version only Default: off This tag is available in some versions to specify how many simultaneous sync sessions the server will allow. Note that the upper limit is defined by what your license allows (see  REF _Ref47451589 \r \h 8.1).  XE "maxmsgsize" \f T : max SyncML message size Contained in: Can contain: integer value (number of bytes) Attributes: none Default: 20000 bytes for clients, 50000 bytes for servers. Usually there is no need to change the message size, but in rare cases (with implementations not respecting message size limits, or testing message size related features like chunking) this allows to set the maximum size. Note that the engine allocates twice the maxmsgsize per session in memory, so setting huge values here might cause memory shortage.  XE "maxobjsize" \f T : maximum object size Contained in: Can contain: integer value (number of bytes) Attributes: none Default: 4000000 bytes This tag determines maximum size an object (i.e. item, like a contact, a calendar entry etc.) can have. This is set to approx 4MBytes by default. If your application has larger data items to synchronize, this should be increased accordingly. Note that unlike with (see  REF _Ref203479102 \r \h 8.3), a high number here does not cause any memory usage per se. Memory is allocated only when actually needed for a large object.  XE "configidstring" \f T : text to identify config Contained in: Can contain: string Attributes: none This tag is useful to specify a string which is output to all debug log files and helps to identify what config file was in use for a particular session. It is recommended to put a text here that uniquely identifies your config version, such as "Config V2.7 for myserver.com, last edited by ME 2003-11-02".  XE "manufacturer" \f T : text to identify product manufacturer Contained in: Can contain: string Attributes: none Available: in Synthesis SyncML library products only This tag can be used to set the manufacturer string which will be transmitted to remote parties in the SyncML device information as . If this string is not defined or empty, "Synthesis AG" will be used. The actual manufacturer string can be read as a config variable (see  REF _Ref184460000 \r \h 4.4).  XE "model" \f T : text to identify model/product name Contained in: Can contain: string Attributes: none Available: in Synthesis SyncML library products only This tag can be used to set the model (product name) string which will be transmitted to remote parties in the SyncML device information as . If this string is not defined or empty, Synthesis' product name will be used. The actual model string can be read as a config variable (see  REF _Ref184460000 \r \h 4.4).  XE "configvar" \f T : define configuration variable Contained in: Attributes: name, value This tag can be used to define config variables (see chapter  REF _Ref203380577 \r \h 4 for general information about config variables) in the configuration file, and use the defined value in subsequent configuration sections using the $(varname) syntax. has the following attributes: "name": This name of the variable to define (or redefine), without leading $ and paranthesis. "value": The value (string) to assign to the variable. Note that if the "expand" attribute (see  REF _Ref184459204 \r \h 4.3) is specified before "value" and enables config variable expansion, $(varname) within the assigned string is expanded before assigning the value. Defining config variables in a config file is useful for things like base paths for logs, binary files, sqlite files etc.  XE "configvar" \f T : define configuration variable Contained in: Attributes: error, warning This tag can be used to cause a configuration parsing error. This is useful together with conditional attributes (see  REF _Ref203475251 \r \h 4.5), for example to generate an error message to the configuration error output path (usually the console stdout, or a special log file for servers - for syncml engine library also see "conferrpath" in  REF _Ref184460000 \r \h 4.4) when a configuration file is used with an unsupported platform. The available attributes are: "error": shows a config error (which makes startup of the sync application fail). "warning": shows a warning on the config error output (but does not fail startup). XE "scripting" \f T: Global scripting definitions Contained in: Can contain: , , Attributes: none This section contains global definitions for scripts contained in other sections. XE "function" \f T: User-defined function Contained in: Can contain: user-defined function, see  REF _Ref42675038 \r \h 6.13.1 Attributes: none This is used to define functions that then can be called from scripts in other sections of the configuration. See  REF _Ref42675038 \r \h 6.13.1 for description of function syntax. XE "macro" \f T: define macro Contained in: Can contain: script text to be used in other scripts, see  REF _Ref153282321 \r \h 6.12.1. Attributes: name This is used to define macros that then can be used in scripts in other sections of the configuration. See  REF _Ref153282321 \r \h 6.12.1 for details. The name attribute defines the macro's name, which is used to reference it in scripts, see  REF _Ref153282518 \r \h 6.12.3.  XE "looptimeout" \f T : maximum loop execution time Contained in: Can contain: maximum loop execution time in seconds, 0 for unlimited. Attributes: none Default: 5 (seconds) This is used to define the maximum time a loop statement (see  REF _Ref153285510 \r \h 6.11) in a script might take. This is to prevent sessions to completely hang in a scripting loop. XE "debug" \f T: Debug Option Section Contained in: Can contain: , , , , , Attributes: none This tag contains all options for debug logs. Since the 2.1 versions of the Synthesis SyncML engine, debug logging has been significantly enhanced. In 2.1, debug log files were simple plain text without much structure, and therefore somewhat hard to read. The new 3.0 engine has the following new options that make debug logs much more easily readable: Logs are now hierachically structured in indented blocks with timestamps at beginning and end. This groups all log output for a certain operation, item or message. Standard log format is now nicely colored HTML, which can be viewed in any web browser. Blocks can be collapsed/expanded while browsing (built-in Javascript). Links to jump between SyncML commands sent and status received are automatically added. Log writing is much faster, because it does no longer open and close the logfile for every log output line as in version 2.1. Alternative log formats are XML or plain text like in version 2.1, with or without indented blocks. XE "logpath" \f T: Directory path for debug log files Contained in: Can contain: full path to directory where to store log files Attributes: none Default: none (no debug output) This tag specifies the directory where all debug-related log files are stored. For the ISAPI and Apache versions, please make sure that the server process' user (normally called IUSR_xxx under IIS or something like "www-data" or "wwwrun" under Apache) has write access to this directory. Note that the "platform" attribute (see  REF _Ref153284855 \r \h 4) can be used to define different log paths for use on different platforms. Example: C:\sync\logs /var/log/syncml XE "enable" \f T, XE "disable" \f T Contained in: Can contain: nothing Attributes: option Default: by default, "normal" debug is enabled The option attribute specifies which type of information should be enabled or disabled for logging. There are a number of separate debug topic and category options, and some useful groups of multiple topics that can be selected with a single or tag. Separate debug topics: "error": error messages. The standard HTML formatting shows these in bold red. "hot" : most important information (of all topics). This should never be switched of (except when switching off debug logging completely). The standard HTML formatting shows important information in boldface, using the color of the debug topic related. "proto": SyncML protocol related information. The standard HTML formatting shows syncml protocol related information in olive. "session": Session management related information. No special formatting. "admin": Everything that has to do with administrative data (anchors, targets, map table). No special formatting. "data": Everything that has to do with handling user data (data objects). Actual user data will however be shown only if "userdata" option is on as well (see below). No special formatting. "remoteinfo": This shows information delivered in the remote party's device information, such as manufacturer name, datatypes supported, fields supported etc. The standard HTML formatting shows remote's device information related messages in grass green. "parse": This shows information related to parsing and processing incoming data from the remote party. Actual user data will however be shown only if "userdata" option is on as well (see below). The standard HTML formatting shows parsing related messages in dark green. "generate": This shows information related to generating outgoing data for the remote party. Actual user data will however be shown only if "userdata" option is on as well (see below). The standard HTML formatting shows generation related messages in dark blue. "transp": Shows transport (http and TCP communication) related information. Note that this type of log messages only appear in the global logs (see  REF _Ref153336229 \r \h 8.11.18). "syncml_rtk": Messages generated by the SyncML Toolkit code. "rest": Any other debug log message that does not fit in any of the above topics. Detail categories (these are combined with the topics above to determine the level of detail to be shown for the above topics): "userdata": Anything that is user data. To create anonymized logs that do not show user's data, disable this category (and, depending on the database interface, "dbapi" as well, as it might show SQL commands revealing user data as well). "dbapi": Information related to accessing the database. For ODBC, this enables showing SQL statements issued to the database, for plugin datastores, this includes all communication with the plugins and also messages generated by the plugin itself (see "plugin" below). The standard HTML formatting shows database API message in dark pink. "plugin": Messages generated by database adapter plugins. These are messages shows database plugin messages in mauve. "scripts": This is useful to debug scripts, and shows each line of executed scripts (but only for enabled debug topics!). Switching this on can generate huge log files, so it should normally be switched off in productive environments. The standard HTML formatting generally shows script execution in brown, but colorizes executed code in bright blue, comments in light green, conditionally skipped code in grey and expression results in red. "expressions": (New in 3.1) Together with "scripts" this causes detailed step-by-step logging of script expression evaluation. "filter": Information about data item filtering. The standard HTML formatting shows filter processing in light brown. "match": Information about matching data in slow sync. Note that together with "exotic" this can produce extremely large logs as matching is an O(N^2) operation, so use with care. The standard HTML formatting shows slow sync matching in a brownish orange. "conflict": Information about conflict resolution and data merging. The standard HTML formatting shows conflict resolution and data merge information in dark red. "details": Enabling this option adds generally some more detail to the debug output. "exotic": Enabling this adds the highest level of exotic detail possible. This is usually only required to track down device interoperability issues or bugs in the server/config. If "exotic" and "match" are both enabled, extremely large logs can be produced as all slow sync matching is shown in full field by field detail. Use with care! The standard HTML formatting shows exotic details in orange. Groups of multiple topics/categories "minimal": Just "error" and "hot" "normal": This is the default, and shows "hot", "error", "data", "admin", "proto" and "remoteinfo". This gives an overview what is happening during a sync, but no details and no user data. "extended": This shows extended info – almost everything except "script" and "exotic". "maximal": Everything switched on, including "exotic", however "match" is disabled because together with "exotic" it would produce enormously large logs. "db": Everything related to database access ("data", "admin", "dbapi", "plugin"). "all": Really everything. Should not be used normally with , but only for .. For compatibility with 2.1 version: "items": alias for "data". "cmd": alias for "proto". "devinf": alias for "remoteinfo". "dataconv": same as "parse" and "debug" together. Note that enabling and disabling is done in the order specified, so to enable extended debugging topics but no user data, specify:  XE "logformat" \f T : select log file format Contained in: Can contain: "html", "xml", "text" Attributes: none Default: "html" Selects the debug log format. Default is nicely colored HTML, but XML (useful for post-processing with XLT or other XML tools) and plain text (similar to version 2.1 logs) are possible.  XE "folding" \f T : dynamic folding for HTML logs Contained in: Can contain: "none", "collapsed", "expanded", "auto" Attributes: none Default: "auto" If not set to "none", HTML logs will contains some JavaScript to allow dynamically "fold" the block structure of the debug log. Every block can be collapsed or expanded individually. Using the "[++] and [--]" buttons on the right, a block and all of it's contained blocks can be expanded or collapsed with a single click.  The mode determines the initial folding state: "collapsed" means that all blocks are collapsed, "expanded" means that all are expanded and "auto" will have most blocks expanded, but some possibly lengthy, but for normal use not essential blocks will be shown collapsed. Please note that the find function in browsers only searches the visible part of a HTML document, so messages in collapsed blocks cannot be found. So if your log debugging mainly relies on searching in the browser, "expanded" is probably the best mode to make sure everything can be found. Alternatively, there is a button named "expand all" at the beginning of the log file which can be used to expand everything before using the browser's search function.  XE "timestamp" \f T ,  XE "timestampall" \f T : show timestamps in logs Contained in: Can contain: boolean value Attributes: none Default: true (for timestamp), false (for timestampall). These boolean flags control if start and end of each block () and every single log message () should be prefixed with the current date and time (including milliseconds, if platform supports it). This is useful to see where a lot of time is spent during processing of SyncML messages. Usually, timestamps at start and end of each block is sufficient (the default).  XE " showthreadid " \f T : show thread ID in logs Contained in: Can contain: boolean value Attributes: none Default: false for session logs, true for global logs. These boolean flags control if every log messge should be prefixed with the ID of the current thread.  XE "timedsessionlognames" \f T : show timestamps in logs Contained in: Can contain: boolean value Attributes: none Default: true. These boolean flags control if the name of session logs contain the date of creation in their name. With this option, session log files are of the form: pipe_odbc_20061211T150022_sXXXXXXXXXX.html (where XXXXXXX is the session ID). Otherwise, session log files ar simply named like pipe_odbc_sXXXXXXXXXX.html  XE "singlegloballog" \f T ,  XE "singlesessionlog" \f T : single file log option Contained in: Can contain: boolean value Attributes: none Default: false. These boolean flags can be set to true when all global or session-related logging should be written into a single file, rather than creating a new file for each start of the server or new session, resp. Note that in case of the session log, the flag (see  REF _Ref153612150 \r \h 8.11.9) controls if the file is overwritten for every new session (erasing the previous log) or if new information is appended to an existing file when is enabled.  XE "appendtoexisting" \f T : append or overwrite existing session logs Contained in: Can contain: boolean value Attributes: none Default: false. This flag controls if in mode (see  REF _Ref153612128 \r \h 8.11.8), an existing file is overwritten when a new session starts, or if new information is appended to the existing session log file. Note that the global log is always appended to.  XE "logflushmode" \f T : select log file format Contained in: Can contain: "buffered", "flush", "openclose" Attributes: none Default: "buffered" Selects how log information is written to the log file: "buffered" is the fastest mode – log file is only written when internal file buffer is full, that is ususally a few kilobytes at a time. This is the best mode for normal operation, but to debug crashes the contents of the internal buffer is lost when the application crashes, so the log will not show exactly where the crash occurred. In this case, use one of the other modes. "flush" is a good compromise between "buffered" and "openclose". The log file is kept open, but log information is flushed to the file after every log message, so even in case of a crash, the last message before the crash should be visible in the log file. Note however that using flush mode when writing logs to a network volume might degrade performance significantly. "openclose" is the slowest, but also safest mode for writing logs. The log file is opened for every log line to be written and then closed again. This mode was the only mode available in version 2.1.  XE " subthreadmode " \f T : if and how to show log output from subthreads Contained in: Can contain: "suppress", "separate" Attributes: none Default: "suppress" This determines how to handle debug output from simultaneously running subthreads of a session. Subthreads are created for loading the sync set (reading all items that are required in a sync session – in a slow sync this can be all items, so this can take a while, that's why this is done in a separate thread so the main thread can continue communicating with the clients to prevent them timing out). If is set to "suppress", debug output from these threads is discarded and not stored at all. If is set to "separate", a separate file is created for each thread, having the same file name as the main session log but with a "_xxxx" suffix (xxxx = thread ID). In HTML logs, the thread logs are linked from the main log at the point in the log where the subthread is started, which allows easy viewing.  XE "fileprefix" \f T ,  XE "filesuffix" \f T : text to add at begin and end of logfiles Contained in: Can contain: any text Attributes: none Default: standard prefix/suffix suitable for selected (see  REF _Ref153557607 \r \h 8.11.3) Here you can define the text that is inserted at the beginning and end of a log file. This can be used to use a custom style sheet for HTML instead of the built-in, or to reference a XLT for XML logfiles.  XE " indentstring " \f T : string to be used for indenting blocks Contained in: Can contain: any text Attributes: none Default: two spaces This string is used to indent messages contained in blocks visibly. For HTML and XML logs, this should be whitespace in all cases, but for text logs any character can be used. The indent string is inserted at beginning of lines once for every indendation level. XE "xmltranslate" \f T: show traffic in XML Contained in: Can contain: boolean value Attributes: none Default: off If set to on, incoming and outgoing messages (which are often in binary WBXML format) will be translated to XML format and written to the path specified with with the following file naming scheme: xxxx_sYYYYYYYYYY_trmNNN_MMM_outgoing.xml xxxx_sYYYYYYYYYY_trmNNN_MMM_incoming.xml Where "xxxx" is an identifier for the product being used such as "isapi_odbc" for Windows ISAPI version, "xpt_odbc" for the standalone versions, "pipe_odbc" for Apache based servers, "demo" for demo versions etc. YYYYYYYYYY is the internal session ID "trm" means "translated message" NNN is the SyncML message number MMM is a sequence number, which is just incremented for every message translation saved in a particular session. This is because sometimes messages are resent due to problems, so more than one dump with the same NNN value might exist. MMM ensures that these are saved in separate files. Note: This option should never be switched on permanently in productive environment, as it requires a lot of additional memory, degrades performance and can lead to problems when completely malformed messages are processed. It is only for debugging problems with specific SyncML clients. A good option in the PRO version is to use XML translation selectively – for example only for the first sync with a device. This is possible using the SETXMLTRANSLATE script function (see  REF _Ref153590626 \r \h 6.14.5) for example in the (see  REF _Ref43727925 \r \h 11.33). Example: on XE "msgdump" \f T: dump SyncML traffic to files Contained in: Can contain: boolean value Attributes: none Default: off If set to yes, messages received from and sent to client will be dumped 1:1 to files in the path specified with with the following file naming scheme: xxxx_sYYYYYYYYYY_msgNNN_MMM_outgoing.wbxml (or .xml) xxxx_sYYYYYYYYYY_msgNNN_MMM_incoming.wbxml (or .xml) Where "xxxx" is an identifier for the product being used such as "isapi_odbc" for Windows ISAPI version, "xpt_odbc" for the standalone versions, "pipe_odbc" for Apache based servers, "demo" for demo versions etc. YYYYYYYYYY is the internal session ID "msg" means "message", i.e. 1:1 dump of the actual message NNN is the SyncML message number MMM is a sequence number, which is just incremented for every message translation saved in a particular session. This is because sometimes messages are resent due to problems, so more than one dump with the same NNN value might exist. MMM ensures that these are saved in separate files. The file will usually have .wbxml suffix (WBXML is a binary, space saving encoding method for XML). These can't be viewed with a text editor (consider to save a XML translation along with the dumped original, see  REF _Ref203481633 \r \h 8.11.14) If the communication is in plain text XML, the dump files will have .xml suffix. Note: This option creates a lot of small files for each message of a session, usually dozens or hundreds per session, depending on the amout of data transferred. A good option in the PRO version is to use message dumping selectively – for example only for the first sync with a device. This is possible using the SETMSGDUMP script function (see  REF _Ref153590626 \r \h 6.14.5) for example in the (see  REF _Ref43727925 \r \h 11.33). XE "sessionlogs" \f T: generate session logs Contained in: Can contain: boolean value Attributes: none Default: yes If set to yes, Synthesis Sync Server writes session-specific logs. This is the normal case under almost every circumstance. XE "sessionlogs" \f T: No longer supported; use instead This tag is no longer supported in Version 3.x. Use instead (see  REF _Ref153612650 \r \h 8.11.8). XE "globallogs" \f T: generate global log Contained in: Can contain: boolean value Attributes: none Default: no If set to no, no global log is written. This is recommended for productive environments, as for one the global log can get very large quickly, and the information contained is only useful to track down very low-level problems on the data transport level. In addition, writing the global log is slow because it must always use "openclose" (see  REF _Ref153603854 \r \h 8.11.10) as multiple threads are writing to the session log.  XE "logsessionstoglobal" \f T : send session logs to global logfile Contained in: Can contain: boolean value Attributes: none Default: no If set to yes, session logs will be sent to the global log file instead of creating separate log files for each session. XE "configdate" \f T: set timestamp for config file Contained in: Can contain: date/time in ISO8601 format (yyyymmddThhmmss) Attributes: none Available: server only Default: none If this tag is specified, the server will assume that the last modification of the config file has happened at the date specified. Without this option, the server will use the file's modification date (as set by the operating system) to determine when the config has last changed. The date/time of last config change is needed by the server to determine if a client must be sent updated "devinf" - which is always the case when a client's last sync date is before the last change to the config. See also ( REF _Ref36888765 \r \h 8.13). XE "neverputdevinf" \f T: avoid PUT of devinf Contained in: Can contain: boolean value Attributes: none Available: server only Default: off If this tag is set to on, the server will never send its device information "devinf" to the client if not specifically asked (client sending GET command).  XE "systemtimezone" \f T <systemtimezone>: override local system time zone Contained in: <sysync_config> Can contain: time zone specification (see  REF _Ref185246210 \r \h ·ð) Attributes: none Default: system local time zone as retrieved from the operating system This can be used (usually required for testing only) to set the system time zone to a specific time zone rather than retrieving it from the operating system.  XE "definetimezone" \f T : define custom time zone as VTIMEZONE Contained in: Can contain: time zone definition in VTIMEZONE format (as specified in iCalendar, RFC 2445) Attributes: none This can be used to extend the built-in set of named time zones (see chapter  REF _Ref185261956 \r \h 17 for a list) by custom time zones specified in the VTIMEZONE format. Note that not all exotic features of VTIMEZONE as specified in RFC 2445 are supported). For general information on time zone handling please refer to chapter  REF _Ref185238094 \r \h 5. The following example shows how to define a new time zone named "ZUERICH" which is one hour east of UTC in winter and 2 hours east of UTC during daylight savings which is active since 1987 between last sunday in march and last sunday in october: XE "transport" \f T: Transport Configuration Section Contained in: Can contain: , Attributes: type This tag encloses all transport-related configuration. The "type" attribute is required and must have one of the following values: "xpt" for the standalone server (all platforms) "isapi" for the ISAPI-based server (Windows only) "pipe" for Apache/pipe based server (Linux, Mac OS X) Note that for SyncML Engine V 1.0.8.50 and later the config file is allowed to have multiple sections. All transport sections that do not match the server type (isapi, xpt or pipe) will simply be ignored (before V1.0.8.50, this caused a config error). The advantage is that you now can use the same config file for all type of servers - simply include a section for each type. This is handy to test config files for a production ISAPI or Apache server using the standalone server first, without the need to modify anything in the file before using it with the production version later. Example: HTTP 80 yes 0 200 XE "keepconnection" \f T: HTTP 1.1 connection Contained in: Can contain: boolean value Attributes: none Available: standalone and ISAPI server only Default: yes This tag is used to enable or disable HTTP 1.1 "keep alive" / "keep connection" feature. If set, the server signals the client to not close the HTTP connection for every request but re-use it until the entire sync session is done. Notes: Supporting keep-alive is important for synchronizing with mobile devices – these often can open only a limited number of connections in a given time frame. So it is essential not to re-open a connection for every SyncML request, but use a single connection for the entire session. In the Apache version of the server keep-alive cannot be controlled by the sync server config, but is a setting the apache configuration.  XE "bufferretryanswer" \f T : buffer last answer for retries Contained in: Can contain: boolean value Attributes: none Available: ISAPI server only Default: yes If this option is enabled, the server will buffer the last answer message sent for every session in progress. This will allow the server to re-send a message in case a client did not receive it and re-sends a particular request again. This can reduce probability for aborted sessions when the connection is not stable (as sometimes the case in mobile environments). However, it only works with clients that can actually resend messages in case of transmission problems. A few recent client implementation will do that (including the Synthesis clients for PocketPC and Palm), but many others don't. Note that switching this on will cause the server to require around 30-100k more memory per session in progress. XE "protocol" \f T: communication protocol Contained in: Can contain: protocol name Attributes: none Available: in standalone version only Default: HTTP This tag is used to specify the transport protocol to be used. The following options are supported (attention, these are case sensitive!): "HTTP" : This is the default and specifies HTTP (Web) protocol. "OBEX/IR": This works only under Windows 2000. It defines that the server is listening for connections on the infrared port. Note that most existing clients (even those devices that have builtin infrared) don't support SyncML over infrared yet. Synthesis Sync Client 1.1 however supports infrared connections (under Windows 2000). "OBEX/TCP": This is a very seldom used connection mode. Don't use it unless you have distinct reasons to use this instead of HTTP. XE "httpport" \f T: HTTP and OBEX/TCP server port number Contained in: Can contain: port number Attributes: none Available: in standalone version only Default: 80 This tag specifies the TCP/IP port number for the HTTP server or for the OBEX/TCP server. If no other HTTP (Web) server is running on the same machine, the default of 80 is best (standard HTTP port). Note that some older SyncML clients might have problems accessing servers on other ports than 80. For OBEX/TCP, this should normally be set to 650. XE "ipaddress" \f T: listener IP address Contained in: Can contain: IP address Attributes: none Available: in standalone version only Default: 0.0.0.0 (=all) This tag specifies the TCP/IP address for the HTTP server to listen. On machines with muliple IP addresses, this can be used to have the server listen on only one specific address instead of all (0.0.0.0) XE "obexservice" \f T: OBEX service name Contained in: Can contain: OBEX service name Attributes: none Available: in standalone version only Default: SYNCML-SYNC This tag is relevant only when is set to "OBEX/IR". It specifies the OBEX service name. This is conceptually similar to the HTTP port number. The default value of "SYNCML-SYNC" is the official standard service for doing SyncML over OBEX, so normally does not need to be specified. XE "maxthreads" \f T: Max number of session threads per server process Contained in: Can contain: number Attributes: none Available: Apache pipe based server only New in: Server version 3.0.2.0 Default: 0 This tag is used to control multi-threaded operation (multiple sessions run as threads within one single server process): maxthreads=0: single-threaded server, one process per sync session (default, and only mode available in servers before 3.0.2.0). maxthreads=1: only one session at a time per process, but after session finishes, server process keeps running and can process another session. maxthreads>1: multi-threaded server, can run the specified number of sessions in parallel threads. This is the recommended mode when starting a new server process is expensive in terms of memory or cpu, such as with Java based plugins (with a multithreaded server, the Java VM will be loaded only once for all sessions, in a single-threaded server, each session will instantiate a new Java VM). Note that for multithreaded operation, mod_sysync/mod_sysync2 must be updated to the version included with server 3.0.2.0 and later. Otherwise, the server will still work, but will use a new process for every session (as with older servers that have no multithread support). XE "maxsessionruns" \f T: Max sessions to be run by a process Contained in: Can contain: number Attributes: none Available: Apache pipe based server only New in: Server version 3.0.2.0 Default: 0 If set to >0, this is the max number of sessions a server process should run before exiting. This can be useful to make sure the server environment is restarted once in a while to avoid eventual memory leaks in plugins etc. to accumulate too much XE "datatypes" \f T: Data Type Definitions Contained in: Can contain: , , Attributes: none This section defines the content data types that are used in synchronisation. Most SyncML clients today support vCard (versions 2.1 and 3.0) and vCalendar (version 1.0). Of course Synthesis Sync Server supports these as well. However, it can do much more as it has a fully configurable parser/generator for MIME-DIR formatted data. So Synthesis Sync Server can be used with most MIME-DIR based formats (see RFC2425 for details about MIME-DIR). This allows you to customize existing formats like vCard and vCalendar exactly how you need them (they both allow a lot of variants depending on what information is required). In addition, you can define your own MIME-DIR based formats. To change or create datatype config, it is important to understand how Synthesis Sync Server's datatype architecture works. There are three basic building blocks, that are needed to build a datatype: A field list. Field lists are one-dimensional lists of data fields. For every possible value in a vCard, vCalendar or other MIME-DIR type, there should be an appropriate field in the field list. For plain text types (see below), a field list is also required. For example to store the vCard "N" property, the underlying field list should define 5 separate fields, as "N" contains 5 different name parts (first, middle, last names, suffix and prefix). Of course, if some of theses values are not relevant to your application, the field list does not need to include them. If your vCard should allow to repeat some values (such as 10 different telephone numbers), the underlying field list should provide a separate field for each repetition (and list them all in sequence) or use an array field (PRO version only, see  REF _Ref46747184 \r \h 10.2). A mime-dir or text profile. A mime-dir profile defines a format like vCard. Such a format is not just a list of values, but can also have the following features: it may contain structured values (like the "N" property), certain properties (such as "TEL" for telephone numbers) can occur more than just once certain properties can have attributes (e.g. LANGUAGE) that need to be stored in the database as well certain properties can have attributes (eg. TYPE) that qualify the contents of the property itself. For example, a "TEL" property having a "TYPE=WORK" attribute should be stored in another data field than a "TEL" property without an attribute. a profile can contain subprofiles (like VTODO and VEVENT are subprofiles of the VCALENDAR profile) All of these cases can be handled in the MIME-DIR profile configuration. A MIME-DIR profile always relates to an existing field list (see 1.), as it specifies which fields are used to store the information contained in a MIME-DIR object. Likewise, a text profile defines header fields and types in a text base format like email or notes. A datatype specification. A datatype specification finally defines a complete content type. It usually refers to a mime-dir or text profile to define the structure of the datatype, but provides some additional information such as the version of the datatype. It is a common case that the same profile is referenced by different datatypes: in the sample files, there is one generic "vcard" mime-profile, which is used in two datatypes "vcard21" and "vcard30" to provide the different versions of the vCard type. Datatypes are finally referenced by datastores in the section (see " REF _Ref5709751 \r \h 11.34.11") to make them available for accessing a datastore. XE "fieldlist" \f T: internal data field list Contained in: Can contain: Attributes: name A field list defines all data fields used by a certain data type. The name attribute is required to give the field list a name under which it can be referenced later in MIME-DIR profile definitons (see " REF _Ref6058882 \r \h 10.3") and mapping lists (see " REF _Ref6029952 \r \h 11.34.41"). For each field, the must contain a tag (see below). Note that the names of the fields are used internally only and need not to be the same as the fields in your database. To associate fields from a field list with actual database fields, the tag in (see " REF _Ref6029971 \r \h 11.34.41") is used. XE "field" \f T: definition of an internal field Contained in: Can contain: nothing Attributes: name, array, type, compare, age, merge The tag has the following attributes: "name": this is the internal name of the field. This name is used to reference the field in MIME-DIR-profiles and tags, but it needs not to be the same as the database's field name (but of course, it can have the same name). "array" (PRO versions only): if this is set to true, the field is created as an array and will be able to store a list of values of the type specified in "type". This can be useful for storing values that can occur more than once in a record (such as EXDATE in vCalendar). "type" specifies the field's type: "string" : string field. "multiline" : string field, but intended for use with strings that consist of multiple lines. Comparisons of multilines ignores leading or trailing line ends. "telephone": This is like string, except that when comparing two telephone fields, only the following characters are compared: 0..9, *, # and +. So, the following two telephone values will be considered equal: "+ 41 1 440 66 00" and "+4114406600". The reason for using telephone fields is that some clients do store telephone numbers including formatting spaces, some other clients don't. "url": This is like string, except that it is intended to store an URL. To allow the widespread habit of entering WWW URLs without the "http://" prefix, this field type automatically adds the "http://" if no other service specifier (such as "ftp://") is specified. "timestamp" : date and/or time field including time zone context information (see chapter  REF _Ref185238094 \r \h 5 for details about timestamps and time zone handling).Standard string representation is ISO8601 (useful for all combined date and time values in vCard and vCalendar). Depending on the context, other string representations are used (like RFC822 in emails). See chapter  REF _Ref185238094 \r \h 5 for general information about timestamps and timezones. "date" : date-only value. The only difference to "timestamp" is that the output is always a date-only value. On input, it can be assigned date and combined date/time values. Standard string representation is ISO8601 (useful for date-only values like BDAY in vCard). Depending on the context, other string representations are used (like RFC822 in emails). . See chapter  REF _Ref185238094 \r \h 5 for general information about dates and timezones. "integer" : Integer number (64 bit for servers and most clients, could 32 bit on some limited client platforms). "blob": This is a "binary large object" and can be used to store any chunk of binary data. This is useful for contact pictures or email attachments. "compare": This attribute controls how fields are compared in sync conflict, slow sync and first time sync cases. Note that in slowsync, only actually assigned (that is, transmitted) field values are compared, whereas when resolving conflicts during normal sync, all fields supported by both server and client are compared. "never": field is not compared at all. This is for fields that do not contain user data, such as "REV" in vCard. It would not make sense to compare these fields, as they are not relevant for finding out if two objects have the same data or not. "conflict": field is compared only when a sync conflict occurs (that is, when both client and server have modified versions of the same object). This mode should be set for all fields that contain user-entered data and which do not use "slowsync" or "always", see below. "slowsync": field is compared in conflict case (like "conflict"), but in addition, it is also compared during slow-sync to match client objects with existing server objects. Therefore, "slowsync" should be set only on data fields that are important for identifying objects (such as name, company, country, but probably not details that might differ in server and client like telephone numbers, notes etc.). Setting too many fields to "slowsync" carries the risk of creating duplicates during slow sync, because the matching criteria is too tight and small differences between client and server versions of a data record will prevent them to match. "always": field is always used in comparisons, not only in conflict and slow-sync cases, but also in "first time sync" case. This is the special case when a client and a server perform sync for the first time. This is different from slow-sync as in a first-time sync situation, it is often desirable to have relatively loose matching criteria (for example only compare first and last name) to match and union server and client objects. Use this only for fields that are absolutely essential for identifying an object. "age": This optional attribute can be set to "yes" for fields that are relevant in age comparison (i.e. finding out which one of two objects is more recent). If more than one field has the "age" attribute set, the fields that are defined first have precedence when comparing. In vCard, this attribute is normally used for the "REV" field, in vCalendar for the "DATE-MODIFIED" field. If a format does not have a timestamp value that can be used to compare ages, no field must have the "age" attribute set. Note that for fields with "age" set, compare mode should be "never" normally. "merge": This optional attribute is used to define a merging mode for the field. Merging is used when resolving conflicts, that is when two versions of the same object exist and must be unified into one without loosing data. The following merge modes are available: "no" : do not use merge with this field (this is the default when a field has no "merge" attribute. "fillempty": If a field is empty in one object and has a value in the other one, the value is copied to the object which has no value. Note that this implies that "more data is better than no data". While this is a sensible strategy in most cases, there might be cases where this is not the case. "addunassigned": This is like "fillempty" with the following difference: a value is only copied if it has a value in one object and does not exist at all in the other object. A value not existing is different from an empty value. For example, a vCard that includes an empty "TEL" property is explicitly saying: "there is no telephone number at all". A vCard that does not include a "TEL" property is saying "there is no telephone number stored yet". So in the second case it is ok to supply a telephone number once one gets available, while in the first case it might be unwanted to fill in one against the explicit statement of the sender that there is none. This is what "addunassigned" is for. "lines": This is very useful for multi-line fields (like NOTE in vCard). If field values differ, they will be merged on a line-by-line basis as follows: the resulting value will have all lines from both objects, but without duplicating identical lines. So, if one object has just a new line appended to the original note field, this line will simply be added to the other object as well. any single character (for example a comma, or space or any other): This works like the "lines" option, but instead of operating on lines, it operates on values separated by the specified character. "append": If a field's value is different between the two objects, the contents of both fields will be concatenated to build a new field value for both objects. For example, if one field contained "this", and the other "that", after conflict resolution both objects will have the value "thisthat" (or "thatthis"). Example (fieldlist for a simple vCard with name, private and work phone number and a notes field only): XE "mimeprofile" \f T: definition of a mime-dir profile Contained in: Can contain: Attributes: name, fieldlist A MIME-DIR profile defines the entire structure of a MIME-DIR based datatype such as vCard or vCalendar. It must contain one tag (see " REF _Ref6042344 \r \h 10.3.1"). has the following attributes: "name": This must be specified to name the MIME-DIR profile. In , these names are used to reference a profile (see  REF _Ref6060179 \r \h 10.5). "fieldlist": This must be the name of an already defined fieldlist (see  REF _Ref6030571 \r \h 10.1). This fieldlist is the base on which a MIME-DIR type can be defined. All field names used in the definition of the MIME-DIR profile will reference fields from this fieldlist. XE "profile" \f T: root profile definition Contained in: Can contain: , Attributes: name, nummandatory This tag defines the root of a MIME-DIR profile. MIME-DIR profiles can be multi-level, that is the root profile can contain several sub-profiles (such as VCALENDAR contains VTODO and VEVENT subprofiles). To define sub-profiles, use the tag (see " REF _Ref6042851 \r \h 10.3.2"). has the following attributes: "name": This is the name of the profile. This is the name that appears in the BEGIN and END lines. For vCard, the name must be "VCARD", for vCalendar it must be "VCALENDAR". "nummandatory". This attribute is an integer and specifies how many properties of this profile are mandatory, that is, must be present in a valid data item. Normally, this is the number of properties in the profile that are flagged "mandatory" (see " REF _Ref6043386 \r \h 10.3.3"). It can however a lower number, for example if the profile is valid if either one or another value is present: then, there will be two properties flagged "mandatory", but "nummandatory" would be set to 1. Note that this count relates only to properties of this profile, not of eventually contained subprofiles. XE "subprofile" \f T: nested subprofile definition Contained in: Can contain: Attributes: name, nummandatory, field, value, showlevel, showprops This tag defines a sub-profile (such as VTODO, VEVENT or VTIMEZONE in VCALENDAR). has the following attributes: "name": This is the name of the subprofile. This is the name that appears in the BEGIN and END lines.. "mode": This defaults to "custom" for subprofiles which include tags to define the supported set of properties. Special modes are: "vtimezones" : This mode automatically creates or parses the VTIMEZONE records referenced by TZID parameters (, see see  REF _Ref182996929 \r \h 10.3.4) of timestamp properties in iCalendar 2.0 based records. A must not contain any tags – the needed properties are implicitly created. "onlyformode": If set to "old" or "standard", this restricts the subprofile to exist in pre-MIME-DIR ("old", e.g. vCard 2.1, vCalendar 1.0) or MIME-DIR ("standard", e.g. vCard 3.0, iCalendar 2.0) datatypes (see  REF _Ref182997376 \r \h 10.5.14 and  REF _Ref182997381 \r \h 10.5.1) only. "nummandatory": This works as described for , see " REF _Ref6042344 \r \h 10.3.1". "field": This optional attribute can specify the name of a field in the referenced field list, which is used to control this subprofile. See "value" below for details. "value": If "field" is set, this attribute specifies a value that... ...must be contained in the specified field in order to generate that subprofile when generating an object. ...will be written to the specified field when an object is received that contains this subprofile. "showlevel": obsolete since 3.2 – no longer needed as engine automatically calculates if a subprofile nees to be shown in devInf. "showprops": obsolete since 3.2 – no longer needed as engine automatically calculates if a subprofile nees to be shown in devInf. "showifselectedonly": If this attribute is set, the subprofile (and all of its subprofiles) are shown in devInf only if the subprofile is the selected subprofile, or if no subprofile is specifically selected. This is useful for vCalendar profiles, which contain both vEvent and vTodo subprofiles, but in a event-only datastore only vEvent is "selected". "useproperties": This optional attribute can be used to specify the name of an already defined profile or subprofile to use the same set of properties without the need to define them again. When this attribute is used, "showprops" defaults to false because normally the same properties should not be shown twice in the device information. Example: skeleton profile and subprofiles for VCALENDAR (the field named KIND can contain "TODO" or "EVENT" depending on the type of VCALENDAR that is received or to be sent): XE "property" \f T: property definition Contained in: , Can contain: , , Attributes: name, suppressempty, values, mandatory, show This tag defines a MIME-DIR property. A property contains one or multiple data items and eventually some parameters. has the following attributes: "name": This is the name of the property. This is the name that appears at the beginning of a MIME-DIR object, such as "TEL:" for a telephone number. "onlyformode": If set to "old" or "standard", this restricts the property to exist in pre-MIME-DIR ("old", e.g. vCard 2.1, vCalendar 1.0) or MIME-DIR ("standard", e.g. vCard 3.0, iCalendar 2.0) datatypes (see  REF _Ref182997376 \r \h 10.5.14 and  REF _Ref182997381 \r \h 10.5.1) only. "rule": This is the name of a remote rule (see  REF _Ref42941679 \r \h 11.36) that must be active in order to activate this property. This allows to specify multiple property definitions for the same property "name". All adjacent definitions having the same name are treated as a group. The group can contain alternatives for different remote rules, and it can also contain a default property definition (specify rule = "other" in the definition) that is used when no remote rule is active or the group does not contain a specific for the currently active remote rule. Properties that have no "rule" attribute are unconditional, that is they are always active (this is the default). "suppressempty": This optional boolean value. can be set to true if this property must never be sent empty (without values). This is the case for most vCalendar fields, for example. "delayedparsing": This optional integer value can be set to indicate that the property must be parsed after all other properties with a smaller "delayedparsing" value have been parsed. This is useful for example for properies like RRULE where parsing may depend on values like DTSTART. The default value is 0 (means immediate processing). "values": This optional attribute specifyes how many values the property consists of. For example, the "N:" property in vCard consists of 5 values (first, last, middle, prefix, suffix). The default is 1. For each value, the property can contain a tag that defines where and how to store the value (see " REF _Ref6046402 \r \h 10.3.4"). The special values "list" or "expandedlist" can be used instead of a number for properties which contain multiple values of the same type, such as the EXDATE property in vCalendar. This will cause the values to be handled as if the property was occurring multiple times (allowing the use of all the repeating mechanisms for the values). While "list" will generate a single property with multiple values on output, "expandedlist" will generate multiple instances of the same property, one for each value (some servers expect EXDATEs in that form). "valueseparator": This optional attribute can be used to specify the separator used for multi-valued properties. Normally, this is the semicolon (as in N), but for example to read CATEGORIES into elements of an array, "valueseparator" can be set to another separator, like the comma. "altvalueseparator": This optional attribute can be used to specify a alternate value separator that is also recognized when parsing properties. This is useful for properties like EXDATE or CATEGORIES where many implementations use ; instead of , or vice versa. "mandatory": This optional boolean attribute can be set to specify that this property is to be counted as mandatory (see "nummandatory" in and ). Default is "false". "show": obsolete since 3.2 – use "showindefinv" instead. "showindevinf ": This optional boolean attribute specifies if the property should be shown in the device information. Default is "true". "groupfield" New in 3.4: This optional attribute can be used to specify a string field (usually a array or a repeating field) which represents the vCard or vCalendar group tag (a prefix to the property name, separated by a dot). The group tag can be used to link properties together which can occur multiple times. For example, some vCards might contain more than one ORG and TITLE. Now each title belongs to a particular organisation, so the group tag is used to represent that: A.ORG:myOwnCompany B.ORG:myEmployer B.TITLE:employee A.TITLE:boss The groupfield mechanism makes sure that TITLE and ORG repetitions will be stored in the same repetition index (array position if ORG and TITLE are mapped to arrays) according to their group tag, even if occuring out of order in the incoming vCard. XE "value" \f T: property or parameter value storage Contained in: , Can contain: Attributes: index, field, conversion, combine This tag defines if and how a value of a property or parameter should be stored, and defines conversions that should be applied before storing it. has the following attributes: "index": This optional attribute specifies which one of multiple values (see "values" attribute in ) of a property this tag applies to. The default is 1, so for properties with only one value it can be omitted. For parameters, "index" cannot be specified as parameters always have only one value. "field": This optional attribute can specifiy a field name (from the fieldlist referenced in ) where the corresponding property value should be stored. If there is no "field" attribute, the corresponding property value will not be stored and an empty value will be generated when the object is generated by the server. "conversion": This optional attribute can specify a special conversion mode to be applied to the value. It can be one of the following: "version": This special conversion mode means that the property value is the profile's version number. Its only use is for the VERSION property of profiles like vCard or vCalendar. "none": This is the standard conversion (just copy). This is also the default if no "conversion" is specified "emptyonly": This is the like "none", but value is only assigned to fields that are empty. This can be useful to only assign the first value of a value list. "tz" : New in 3.1: When used with a timestamp field, the value is the standard (non-DST) minute offset for the timestamp (indended for vCalendar TZ property). Together with "daylight" (see below), this can be used to represent time zone in vCalendar 1.0 formats. It can be used also with a string field (representing a time zone name or UTC offset in minutes) or a integer field (representing the UTC offset in minutes). "daylight": New in 3.1: Intended for vCalendar 1.0 DAYLIGHT property. When used with a timestamp field, the value is the assiociated time zone's daylight savings rule (for FALSE if no DST defined for the time zone) in the DAYLIGHT format. "tzid": New in 3.1: Intended for iCalendar 2.0 TZID parameter. When used with a timestamp field, the value is a time zone identifier. Appropriate time zone descriptions can be included using a (see  REF _Ref182996673 \r \h 10.3.2). "zoneoffset_hours" : No longer supported in 3.1. "zoneoffset_mins": No longer supported in 3.1 – equivalent is using "tz" with an integer field. "zoneoffset_secs": No longer supported in 3.1. "timestamp": Forces the output to be a timestamp (date + time), even if the referenced field is a date-only field. "valuetype": This is a special conversion mode to be used with VALUE parameters of some properties (e.g. date/time fields in iCalendar 2.0). For timestamps, if the referenced field is a time-only value, the conversion result is "TIME", if the referenced field is a date-only value, the conversion result is "DATE". Otherwise, the conversion result is empty which causes no VALUE parameter to be used, which denotes a timestamp value. "date": Render and parse as date-only, even if actual value is a datetime. "autodate": New in 3.1: This is for properties like DTSTART that can be either date-only or timestamp values in MIME-DIR formats (like iCalendar 2.0), but must always be timestamps in vCalendar 1.0. A date-only value is rendered as timestamp with 0:00 localtime in vCalendar 1.0, whereas it is rendered as a real date-only in MIME-DIR conformant formats. "autoenddate": New in 3.1: Similar to "autodate", however a date-only value is rendered as a timestamp at 23:59:59 localtime in the previous day when (see  REF _Ref231889747 \r \h 11.36.18) is set (otherwise, the end date is rendered as-is, which is 0:00 the next day). This is useful for DTEND properties. "bitmap": This is a special conversion mode for integer fields that represent a number of flags by their individual bits. It converts an integer number into a list of bit numbers - for example, the decimal integer value 17 (hex: 0x11) will be represented as "0,4" as Bit0 and Bit4 are set. This is very useful in conjunction with s (see  REF _Ref62467260 \r \h 10.3.5), as these allow mapping list of numbers to list of identifiers. If the property had s relating WORK=0, HOME=1,FAX=2,PAGER=3,MOBILE=4, the above example "0,4" would correspond with "WORK,MOBILE", whereas 6 = 0x06 would correspond to the bitmap "1,2" which would represent "HOME,FAX". This can be very useful to efficiently store TYPE attributes of telephone number or email addresses. "multimix": New in 3.1: This is a very powerful conversion mode including the functionality of "bitmap", but additionally allows mixing bits from more than one field and also using literal values mixed with bitmapped values. This is useful for complex TYPE parameters like that from our iPhone client which has WORK, HOME etc. but also custom labels in the form "X-CustomLabel-xxxx" and IDs in the form "X-Synthesis-Ref-y" (see example below) When the input string into the conversion is of the form "Bx" or "n.Bx", multimix works like "bitmap", i.e. it maps to the bit number x in an integer field. When the input string into the conversion is of the form "Lyyyyy" or "n.Lyyyyy", the yyyyy part is stored in the referenced field. In both variants, the "n." prefix defines an offset in the field list relative to to the main field selected by the 'name' parameter, such that more than one field can be targeted by a multimix conversion. "rrule": This is a special conversion mode for vCalendar RRULE, it is available only in types based on "vcalendar". "rrule" conversion mode requires that the "field" attribute references not a single field, but the first field of a so-called RRULE field block. See  REF _Ref36890908 \r \h 10.6 for details. "blob_b64": the contents of the associated field (usually a BLOB) is represented as a base 64 encoded binary value. This is for example required for vCard PHOTO. Note: For converting enumerated values, the tag can contain tags, see below. "combine": This option can be used to combine the values of multiple properties into a single field. It can be one of the following: "no" : do not combine values. This is the default. "lines" : combine values by storing each value on a new line any single character: combine values by storing them separated by the specified character. The following example shows how to use the "multimix" mode in combination with the "prefix" mode (see  REF _Ref62467260 \r \h 10.3.5). For each telephone number in TEL_NUMBERS array, the TEL_FLAGS holds a bitmap coding CELL, HOME and WORK in any combination, TEL_IDS holds a numeric ID transferred as "X-Synthesis-RefX" and TEL_LABELS can hold a custom label. The 1 in "1.L" is the offset between the value's specified field (TEL_FLAGS) and the field that should actually be used to store (TEL_IDS). Same for the "2.L". Note that if there is no field offset, the value must be specified without a "0." prefix, like the "B0", "B1" and "B2" values. ... XE "enum" \f T: enumerated values Contained in: Can contain: nothing Attributes: name, value, positional This tag defines a name/value pair. All tags contained in a tag form an enumeration list which will be used to convert values contained in the MIME-DIR based format into values more convenient for internal use: If a value in the MIME-DIR object matches the "name" of an , the "value" of that is used as value to store into the internal field (and in the database, finally). has the following attributes: "name": This is how the value is shown in the MIME-DIR object. "value": This is how the value is shown internally (and stored in the database). "positional": This is an optional boolean attribute which can be used to exclude or include a certain value into the set of values that control the storage position of data (see " REF _Ref6049927 \r \h 10.3.7"). Normally, this needs not to be specified, but to have lists with mixed positional and non-positional values, it can be specified. "mode": This attribute can be used to specify special enum modes as follows (the default is "translate"): "translate": default mode, translate 1:1 between name and value "defaultname": when translating from values to names, and no matching value is found, the result is taken from the name of the with mode="defaultname" (if no such exists, the value is passed as name without translation). "defaultvalue": when translating from names to values, and no matching name is found, the result is taken from the value of the with mode="defaultvalue" (if no such exists, the name is passed as value without translation). "ignore": if a value or name matches an with mode="ignore", it will be ignored, i.e. the result generated is empty. "prefix": this works similar to "translate", however the translation is applied even if only the beginning of the name or value string matches. If so, the remainder of the string are appended to the output string. As an example: a would translate "X-BitNumber-2" to "B2" or "X-BitNumber-3456" to "B3456" and vice versa. See  REF _Ref182995906 \r \h 10.3.4 for an example using prefix enum mode together with multimix conversion mode. Example: Usage of an list to convert the STATUS attribute of VCALENDAR into an internal numeric representation: XE "parameter" \f T: property parameter definition Contained in: Can contain: , Attributes: name, default, show, positional,shownonempty This tag defines an attribute to a property. Parameters are supplementary information to a property which often defines things like language or type of the information stored in the property's value(s). There are two main uses of parameters: non-positional use: using them as additional values and store them like any other property value. positional use: use the value of a parameter to determine in which field the property's value should be stored. An example of this is the TYPE parameter of the TEL property in vCard: If TYPE=WORK, the number should be stored in a TEL_WORK field, but when TYPE=HOME, the number should be store in TEL_HOME. Positional parameters must always have some tags in their ; these will be used with the tag (see " REF _Ref6049927 \r \h 10.3.7") to define the rules for storing property values according to parameter values. has the following attributes: "name": This is how the parameter is shown in the MIME-DIR object. For example, the "TYPE" can be used to specify the type parameter in the vCard TEL property (which look like: "TEL;TYPE=WORK:123456"). "onlyformode": If set to "old" or "standard", this restricts the property to exist in pre-MIME-DIR ("old", e.g. vCard 2.1, vCalendar 1.0) or MIME-DIR ("standard", e.g. vCard 3.0, iCalendar 2.0) datatypes (see  REF _Ref182997376 \r \h 10.5.14 and  REF _Ref182997381 \r \h 10.5.1) only. "default" is an optional boolean attribute. If it is set, the parameter is treated as default parameter. This has significance in non-standard (pre-MIME-DIR) formats like vCard 2.1 only, and means that the parameter value(s) appear without the parameter name (such as "TEL;WORK:123456" which is vCard 2.1 format for "TEL;TYPE=WORK:123456"). By default, this is "false". "showindevinf " (also "show" is allowed for backward compatibility, but is deprecated in 3.2 and later) is an optional boolean attribute. If set to true, this parameter and (if any) its defined values will be shown in the device information. This should usually be set on "TYPE" parameters for properties like "TEL" or "ADDR", to show the client what kind of telephone numbers/postal addresses the server supports. Some phone device clients will not send more than a single tel number if the devInf does not contain this information. Default is "false". Note that this option has effect only if the containing profile/subprofile has not set "showprops" to "false". "positional" is an optional boolean attribute. It specifies if the parameter is used to determine where to store property values (see above). The default is "false". "shownonempty" is an optional boolean attribute. It specifies that the property which contains this parameter is to be show when this parameter contains a value, even if the property itself contains no value(s). The default is "false" which means that the property is only shown if it has main values(s). Example: make sure that the value of the LANGUAGE attribute of the NOTE property gets stored into the field "NOTE_LANG" (non-positional parameter): XE "position" \f T: control storage position and repetitions Contained in: , Can contain: nothing Attributes: has, hasnot, shows, field, repeat, increment, minshow This tag is used together with positional parameters (or generally with repeating properties to define how and how many times these are stored). It can be used to define rules how parameter values influence in what field the enclosing property's data is stored. It also handles the case of repeating properties, such as multiple TEL properties in a single vCard object. Note that while this is a very powerful option, it is also rather complex to understand and use. So we recommend to look at the sample config files distributed with the server before defining your own . They show how can be used in some standard cases for vCard and vCalendar. can appear in a or in . If the position (field(s) where to store property value(s) depend on a single parameter's value, should be put inside that . Otherwise, should be inside (especially when the is used only to define a repeat count for a property). has the following attributes: "has", "hasnot": These attributes both specify one or several (comma separated) name(s), either from the list of the enclosing , or from any other list of a parameter in the . If the being referenced is not in the same as the tag, the name must be prefixed with the parameter name. For example, to reference the "WORK" from the "TYPE" parameter, you should write "TYPE.WORK". "has" specifies the attribute values that must be present for the to apply to a property's values. For example, has="TYPE.WORK" specifies a property that must have a TYPE-attibute with a value of "WORK". "hasnot" specifies the attribute values that prevent the to apply to a property's values. For example, hasnot="TYPE.MODEM,TYPE.FAX" specifies that the property may not be of TYPE MODEM or FAX. "shows": This attribute is like "has", but can be used to specify additional values that a parameter should have when the object is sent to the remote party. For example, on voice telephone numbers it does not make sense to specify "VOICE" in "has" (because not all clients tag voice numbers as such), but it would be a good idea to specify shows="TYPE.VOICE", so voice numbers in outgoing vCards will have the "VOICE" type set. "field": Simply said, this attribute defines the field where the property value is stored when the applies according to its "has" and "hasnot" attributes. However, this simple description is only true if the property has a single value. The whole complicated truth is: The field specified is used to calculate a difference between the numeric positions in the fieldlist of that field and the first field specified in a of the enclosing property. This offset is then added to all the fields that store values of this property and all its non-positional parameters (so the entire block of fields is offset). In order to use this feature, you need to make sure that the field list is designed appropriately for offsetting fields or blocks of fields. "repeat": This attribute specifies how many times this can be applied. For example, a database might provide 3 fields for work telephone numbers, so the that catches work numbers (using has="TYPE.WORK") can have a "repeat" attribute of 3. Repeat can also be set to the following special values: "rewrite": this means that if the property occurs more than once, the last occurrence will be stored. Note that this is different from the default value "1" for "repeat": This will store the first occurrence, but if the property occurs again, it will not match this again, but eventually a subsequent one. "array" (PRO versions only): this can be used when the target field is an array field. In this case, all repeated occurrences will be stored in the elements of the array (instead of using field offsets). Important Note: before version 3.1.x, when an empty array element is encountered when generating properties from an array, this stops generation, even if subsequent array elements exist and are non-empty. For properties with parameters, these are not checked for being empty by default, but they can be included by using the "shownonempty" attribute of (see  REF _Ref182740974 \r \h 10.3.6). Note that a specifying "repeat" (and probably "increment" as well) can also be used completely independently of any positional parameters (no "has", "hasnot" etc.), for a property that is simply allowed to repeat several times. "increment": This is needed only when "repeat" is used. It specifies the increment (offset) that is added to the numeric position of the field(s) after each repeated occurrence. So, if a database has 3 fields for work telephone numbers, and they are listed one after the other in the fieldlist, the will have a "repeat" of 3 and an "increment" of 1. For a setup where the database has 5 blocks of 2 fields each, one for the telephone number itself and one for the TYPE parameter value, "repeat" would be 5 and "increment" would be 2. "minshow": This specifies how many times a property is shown minimally in a generated object. For example, in a database with 3 fields for work telephone numbers, you might not want to show 3 "TEL" properties unless they really contain data. But probably you still want one "TEL" property to show in all cases, even if the database has no work telephone numbers stored at all. In this case, you could set "minshow" to 1. By default, "minshow" is equal to "repeat", meaning that all possible repetitions of a property will be shown in generated objects, even if they are empty. Please note that if the "suppressempty" attribute of (see " REF _Ref6043386 \r \h 10.3.3") is set, empty properties are generally suppressed. There is also a device-specific setting in (see " REF _Ref6055322 \r \h 11.36.5") which overrides "supressempty" and "minshow" when set (it causes that empty properties are never generated for that specific device - some devices just can't handle empty properties at all). "readonly": This specifies that this position rule is only used for parsing data, not for generating data. This allows specifying more than one rules for the same values. The parser will try to apply them in the order of appearance. Default is "false". "overwriteempty": If this is set to true, the parser will overwrite empty occurrences of a repeating specifications with subsequent occurrences. This avoids wasting storage with storing empty values. Default is "true". Simple example: a vCard for a database with 2 fields for email addresses: Full featured example: a vCard with 8 telephone numbers, 4 of them for specific purposes, and 4 more for additional numbers (note the comments):  XE "vtimezonegenmode" \f T : VTIMEZONE generation mode Contained in: Attributes: none Default: none This tag defines how VTIMEZONE records should be generated in a mimeprofile which contains datetime values specifying a TZID parameter. It can have one of the following values "current": VTIMEZONE is generated for descibing the current time only. "start": VTIMEZONE is generated for descibing the earliest date used in the record. "end": VTIMEZONE is generated for descibing the latest date used in the record. "range": VTIMEZONE is generated for descibing all dates used in the record. "openend": VTIMEZONE is generated for describing all dates starting from the earliest date used in the record up to the latest time zone defintion known. < XE "unfloattimestamps" \f T unfloattimestamps>: handling of floating timestamps Contained in: Attributes: none Default: false If set, parsed datetime values that do not specify a time zone (i.e. have no TZID or no Z suffix) will be assigned to the item's time zone (which is usually the user's time zone). See  REF _Ref185257870 \r \h 5.2 for details about time zone contexts. This is useful for DB configurations that cannot store floating time stamps and must interpret them in a fixed time zone context.  XE "textprofile" \f T : definition of a text format profile Contained in: Can contain: , in PRO version only: , , , , , , , , , , Attributes: name, fieldlist A text profile relates internal fields to (header) lines of a plain-text format like email. It contains one or multiple tags (see  REF _Ref153617304 \r \h 10.4.1). has the following attributes: "name": This must be specified to name the text profile. In , these names are used to reference a profile (see  REF _Ref6060179 \r \h 10.5) with the tag. "fieldlist": This must be the name of an already defined fieldlist (see  REF _Ref6030571 \r \h 10.1). This fieldlist is the base on which a text type can be defined. All field names used in the definition of the text profile will reference fields from this fieldlist. XE "linemap" \f T: mapping of text based formats to database fields Contained in: (or , only for compatibility with version 2.1) Can contain: , , , , Attributes: field Note: In version 2.1, were defined directly within . This is still possible in version 3.x for compatibility, but no longer recommended. Please create (see  REF _Ref153617348 \r \h 10.4) sections for your and reference them from via . This tag is used to map one or multiple lines of the text based data format to a field of the fieldlist. The "field" attribute is required: "field" specifies the name of the field from the fieldlist which is to be mapped to one or multiple lines of the text format. The tag contains further tags to define how the lines are mapped XE "numlines" \f T: Number of lines to map Contained in: Can contain: integer number Default: 0 (all lines) This tag is used to specify how many lines are to be mapped to the field specified in . If the value is 0, this means that all remaining lines should be mapped to the specified field. Note that for linemaps with , is irrelevant (a header is always decoded into a single line – even if present as multiple lines with RFC822 folding). XE "inheader" \f T: header lines Contained in: Can contain: boolean value Default: false This tag is used to specify if the line(s) in the belong to a email-style header or not. E-mail headers are separated by body text by a single empty line. E-Mail header style lines can be represended on multiple lines using header folding mechanism. The folding/unfolding takes place automatically – the referenced internal field will always contain a single line. XE "allowempty" \f T: empty field handling Contained in: Can contain: boolean value Default: false If this option is set, one empty line will be generated if the mapped field is empty, otherwise, empty fields will just be ignored when creating the text output. XE "headertag" \f T: tagged header handling Contained in: Can contain: header name Default: empty This option is used to parse and generate RFC822-type headers (for example, email messages). The header name is the name of the header including the colon! If an input line begins with the header name, it is assigned to the field specified in the linemap. When generating output, the output text is preceeded by the header name. Note that long header lines are folded according to RFC822 specs. Example for the "From." header of email messages: From: true  XE "valuetype" \f T : type of text field Contained in: Can contain: value type name Default: text This option allows four type options: text (default): contents are treated as plain text date: contents are treated as RFC822 date/time specification body: contents are treated as a RFC822/MIME email body (that can include multiple body variants and attachments). Note that this option is only available in the PRO versions. Use the RFC822 email body options (see  REF _Ref45025338 \r \h 10.4.7) to specify details for storing the body elements. The body text itself will be stored in the field specified by the enclosing . If that field is an array, multiple format variants of the body will be stored in subsequent array elements (also see and below in  REF _Ref45025338 \r \h 10.4.7). Otherwise, only the plain text variant of the body will be stored. rfc2047: contents are treated as RFC2047 encododed. This is the encoding used to represent non-ASCII characters in RFC2822 style email headers. RFC822 email body options Contained in: (, only for compatibility with version 2.1) Available: in PRO version only Note: In version 2.1, the following tags were defined directly within . This is still possible in version 3.x for compatibility, but no longer recommended. Please create (see  REF _Ref153617348 \r \h 10.4) sections and reference them from via . These tags are used to control parsing/generation of RFC(2)822-type email bodies and are applied to linemaps that have a valuetypeof body:  XE "mimemail" \f T boolean: If set to false (default), no RFC(2)822 email body parsing/generating is done at all. For email format support, this must be set to true.  XE "maxattachments" \f T number: Specifies the maximum number of attachments that will be processed  XE "attachmentcountfield" \f T field: Specifies a field that will be assigned the number of attachments in a parsed email message  XE "attachmentmimetypesfield" \f T field: specifies the field (normally an array) that is used to store the attachment MIME-types.  XE "attachmentsfield" \f T field: specifies the field (normally an array) that is used to store the attachment contents.  XE "attachmentsizesfield" \f T field: specifies the field (normally an array) that is used to store the size (in bytes) of the attachments.  XE "attachmentnamesfield" \f T field: specifies the field (normally an array) that is used to store the file names of the attachments.  XE "sizelimitfield" \f T field: specifies the field that is used by Synthesis SyncML Server and clients to transmit email size constraints with the special "X-Sync-Message-Limit" header. Note that this is a very advanced setting, and needs a lot of scripting in a config file to make it work with a server database. See implementation for email in the sample config.  XE "bodymimetypesfield" \f T field : specifies the field (normally an array) that is used to store the MIME-types of the possibly multiple body variants of the email message (such as text, html, rtf).  XE "bodycountfield" \f T field : Specifies a field that will be assigned the number of body variants found in a parsed email message. XE "datatype" \f T: definition of a datatype Contained in: Can contain: , If basetype is "vcard" or "vcalendar": , If basetype is "mimedir": , , If basetype is "text": , , ( for compatibility with version 2.1, but these should be moved to a if possible) Attributes: name, basetype This tag is used to define a datatype that can then be referenced by a datastore as content format (see " REF _Ref6058085 \r \h 11.34.12"). The "name" and "basetype" attributes are required: "name" specifies the name under which the datatype can be referenced by a datastore. For example, vCard 2.1 is named "vcard21" in the sample config files. "basetype" can be one of the following: "vcard": The type is a vCard. Note that a vCard could also be defined with basetype "mimedir" (as it is a MIME-DIR based format), however using the "vcard" base type allows the server to optimize some vcard specific things. "vcalendar": The type is a vCalendar. "mimedir": The type is a generic MIME-DIR type. This basetype is intended for defining custom formats which are not vCard nor vCalendar. "text": The type is a text-based format, such as notes or email. The tag should reference a (new in version 3.0) containing (see  REF _Ref153617348 \r \h 10.4).For compatibility with version 2.1, the s can be specified in the directly, but you will get warnings when starting the server, recommending moving to a separate . XE "use" \f T: MIME-DIR profile, text profile or field list to use for datatype Contained in: Can contain: nothing Attributes: for basetypes "mimedir", "vcard", "vcalendar": mimeprofile for basetype "text": textprofile (or fieldlist for compatibility with version 2.1) This tag is used to define the MIME-DIR profile (for basetypes "mimedir", "vcard" and "vcalendar"), textprofile or fieldlist (for basetype "text") the datatype is based on. The attribute must specify a name of a previously defined (see  REF _Ref6058882 \r \h 10.3), (see  REF _Ref153617348 \r \h 10.4) or (see  REF _Ref6030571 \r \h 10.1) resp. Examples: 2.1 text/plain 1.0 1 false true 0 false true XE "version" \f T: vCard or vCalendar version Contained in: or Can contain: vCard or vCalendar version Attributes: none This tag is used to define the vCard or vCalendar version. It controls how data is interpreted and generated (as this is different between versions) as well as how the type is named in SyncML communication (for example, the correct name for vCard 2.1 is "text/x-vcard", while for vCard 3.0 it is "text/vcard"). For vCard, versions available are "2.1" and "3.0". For vCalendar, versions available are "1.0" and "2.0". XE "typestring" \f T, XE "versionstring" \f T: MIME type and version Contained in: Can contain: MIME type and version strings, resp. Attributes: none These tags are used to define a MIME type and a version for which base on the generic "mimedir" type. This should be used only for custom types. Example of a custom type definition: text/x-mytype 1.7  XE "zippedbindata" \f T: Enable/disable special compressed (non-standard) item format Contained in: Available: might not be available in all standard products Can contain: boolean value Attributes: none Default: false If this flag is set to true for a definition, it enables a (non-standard) per-item data compression as follows: The raw data (for example a vCard) will be compressed with the zip compressor (compression level can be set using , see  REF _Ref103576461 \r \h 10.5.5) and the resulting binary data will be sent as "bin" opaque WBXML data. The will contain set to and will have a tag which contains the original (uncompressed) size of the item data. This will happen if and only if the SyncML communication is in WBXML format and if the SyncML Version is 1.1 or higher. Note: This allows to define special types (in addition to the standard data types) to optimize network bandwith usage, such as for large emails. Of course, this does only work if both ends (server and client) support this non-standard compression scheme. Synthesis SyncML client for Windows Mobile for example support this kind of compressed format for emails as "application/x-zip-message" custom type, and therefore the sample config supports this format as well, in addition to the standard "text/message".  XE "zipcompressionlevel" \f T: Compression level for compression Contained in: Available: might not be available in all standard products Can contain: number 0..9 Attributes: none Default: empty This tag specifies the compression level (0=no compression, 1=low compression level, fast, 9=high compression level, slow) used when the feature is enabled (see  REF _Ref103576458 \r \h 10.5.4).  XE "binaryparts" \f T : Allow unencoded binary in content Contained in: Available: might not be available in all standard products Can contain: boolean value Attributes: none Default: false If this flag is set to true for a definition, it enables a (non-standard) format extension for certain content formats (RFC 2822 email attachments at this time) to allow more efficient bandwidth usage than base 64 encoding by including binary parts as such (plain binary). This takes place with WBXML format only – XML cannot transfer unencoded binary. Synthesis SyncML client for Windows Mobile support binary parts for email attachments in the "application/x-zip-message" (1.1) custom type, and therefore the sample config supports this as well.  XE "unicodedata" \f T ,  XE "bigendian" \f T : Unicode content Contained in: Available: might not be available in all standard products Can contain: boolean value Attributes: none Default: false New in: 3.0.2.0 If is set, the content of the parts is interpreted as Unicode (16-bit characters) rather than UTF-8 which is the standard encoding for SyncML. can be set in case the Unicode content is in Big Endian order (Motorola style, MSB first) rather than Little Endian order (Intel style, LSB first). Note that this makes only sense in WBXML. There are some clients on the market that use unicode encoded data in special, semi-proprietary formats like Nokia's VMSG (for SMS sync).  XE "initscript" \f T: Initialisation of type-specific script context Contained in: Available: in PRO versions only Can contain: script Script context: datatype context Attributes: none Default: no script This script is executed once before the datatype is first used for receiving or sending data. It can be used to initialize the datatype context. Note that because it is possible for a SyncML session to use different datatypes for sending and receiving (for example vCard 2.1 and vCard 3.0), the context for sending items is not necessarily the same as for receiving items - although it will be in most cases. is the place to declare and initialize variables that are used for processing incoming and outgoing items in , (see  REF _Ref46895327 \r \h 10.5.9), , (see  REF _Ref46895428 \r \h 0), (see  REF _Ref46823145 \r \h 10.5.11), (see  REF _Ref46895473 \r \h 10.5.12) and (see  REF _Ref46895489 \r \h 10.5.13)  XE "incomingscript" \f T,  XE "outgoingscript" \f T: Custom pre- and postprocessing items Contained in: Available: in PRO versions only Can contain: script Script context: datatype context Attributes: none Default: no script These scripts are executed for every data item just after decoding the incoming data () and just before encoding the outgoing data () according to the encoding/decoding defined for the . These scripts are the place to customize the endcoding/decoding process between internal field list representation and the SyncML datatype. Note that this is not the place to implement database specific conversions, because this is better done in the and in the section (see  REF _Ref42944330 \r \h 12.20).  XE "filterinitscript" \f T ,  XE "filterscript" \f T : Script-based data filtering Contained in: Available: in PRO versions only Can contain: script returning boolean value Script context: datatype context Attributes: none Default: no script With these two scripts, custom filtering that cannot be represented with the standard flters (see  REF _Ref46752884 \r \h 7) can be implemented. For example, for making the special date range limit (see  REF _Ref46896711 \r \h 7.4) work for a datatype, an appropriate and must be implemented (see example below). The is executed once per sync session. It must analyze the filter parameters (such as STARTDATE(), ENDDATE() and SIZELIMIT(), see below) and then return TRUE if the must be called for every item modified or added in the database since the last sync session. In addition, if the must be called for all items in the sync set (not only those that have changed or were added), the must use SETFILTERALL(TRUE). Note that this "filter all" mode is required for filter conditions that are dynamic, that is, which change from sync session to sync session (like a "10 days before and 30 day after" rule, which affects a different date range every day. For static conditions (like "only tasks that are not completed"), it is sufficient to have only the new and changed records filtered, which can make a huge performance difference (with SETFILTERALL(TRUE), all records of the database must be read and checked, which might need quite some processing for large databases. If returns FALSE, this means that no filtering is needed which is the most efficient case. The is executed once per data item read from the database. It must return TRUE if the data item passes the filter and FALSE otherwise. The following functions are available in the datatype context only:  XE "SETFILTERALL" \f F SETFILTERALL(integer all): For . If all is TRUE, this causes all records of the datastore being passed through the . integer  XE " DEFAULTSIZELIMIT" \f F  SIZELIMIT(): returns the size limit that was set for the item being processed. This limit defaults to the size limit set for the datastore which can be obtained by the DEFAULTSIZELIMIT function (see  REF _Ref55271118 \r \h 11.34.21), for example when set with the /li() CGI option (see  REF _Ref46896711 \r \h 7.4). If no size limit was set, SIZELIMIT() returns UNASSIGNED.  XE "SETSIZELIMIT" \f F SETSIZELIMIT(integer limit): sets a new size limit for the item being processed. This can be used to override the default size limit on a item-by-item basis. If limit is UNASSIGNED or -1, this disables the limit for the item being processed. In addition, all datastore context functions as listed in  REF _Ref55271118 \r \h 11.34.21 are also available. The following example shows a and a which offer date-range filtering for events and todos (if inserted into a vCalendar-based ). =STARTDATE()) || ((RR_FREQ!=EMPTY) && ((RR_END==EMPTY) || (RR_END>STARTDATE()))) ); } ELSE { // Todo pass if they have no DUE or one within the range PASSES = (DUE==EMPTY) || (DUE>=STARTDATE() && DUE<=ENDDATE()); } RETURN PASSES; ]]>  XE "processitemscript" \f T : Custom processing for incoming items Contained in: Available: in PRO versions only Can contain: script returning boolean value Script context: datatype context Attributes: none Default: no script This script is executed before an incoming item is processed (that is, stored in the database), but after an eventual . This is the place to implement non-standard behaviour (such as rejecting certain items or ignoring updates etc.) for item processing. For "standard" datatypes this script is normally not used, but it is needed to implement special-behaviour datatypes such as email. This script can influence how the item will be processing by using the following context functions (note that the context functions described in  REF _Ref46904847 \r \h 10.5.10 are also available):  XE "ECHOITEM" \f F ECHOITEM(string syncop): This will cause the incoming item being echoed back to the sender with the specified syncop (which can be "add", "replace", "delete").  XE "REJECTITEM" \f F REJECTITEM(integer statuscode): This will cause the incoming item being rejected with the statuscode. Whenstatuscode is set to zero, the item will be silently rejected, without returning a error code. string  XE "SYNCOP" \f F SYNCOP(): Returns the sync operation requested for the current item ("add", "replace" or "delete". string  XE "LOCALID" \f F LOCALID(): Returns the current item's local ID.  XE "SETLOCALID" \f F SETLOCALID(string localid): Sets the current item's local ID. Note that this is only required in very special cases. Usually, modifying the local ID will lead to messed up sync sessions. string  XE "REMOTEID" \f F REMOTEID(): Returns the current item's remote ID.  XE "SETREMOTEID" \f F SETREMOTEID(string remoteid): Sets the current item's remote ID. Note that this is only required in very special cases, such as clients requiring extra information (such as an email folder path) embedded in the remote ID string.  XE "CONFLICTSTRATEGY" \f F CONFLICTSTRATEGY(string strategy): Sets the conflict strategy ("duplicate","newer-wins", "server-wins", "client-wins") for the current item and overrides the default strategy set by , and (see  REF _Ref46908455 \r \h 11.34.10) or by SETCONFLICTSTRATEGY() in (see  REF _Ref55271118 \r \h 11.34.21).  XE "FORCECONFLICT" \f F FORCECONFLICT(): Forces a conflict even if there is none. This means that the item coming from the remote party is made conflict the item already in the database (if any) and have it being processed by the normal conflict resolution procedure.  XE "DELETEWINS" \f F DELETEWINS(): Normally, when a delete and a replace operation conflict, the replace always wins to preserve data (unless datastore-wide option is set, see  REF _Ref169607904 \r \h 11.34.5). When DELETEWINS() is used, this makes delete win over replace.  XE "PREVENTADD" \f F PREVENTADD(): Prevent that the item is added to the datastore. Note that just checking SYNCOP() for "add" is not enough, as clients are free to send new items using the "replace" command, which will cause an implicit add if the item does not already exist. PREVENTADD() prevents this implicit add as well.  XE "IGNOREUPDATE" \f F IGNOREUPDATE(): Causes replace operations to be ignored. Note that just checking SYNCOP() for "replace" is not enough, as clients are free to send new items using the "replace" command, causing implicit adds in the server. IGNOREUPDATE() makes sure only "replace" operations are executed that cause an implicit add.  XE "comparescript" \f T : Custom item comparison Contained in: Available: in PRO versions only Can contain: script returning 0 if target equals reference, 1 if target is newer than reference, 1 if target is older than reference,999 if items are not comparable or not equal but age of items is not known. Script context: datatype context Attributes: none Default: no script This script can be used to implement customized comparison rules. Comparison is important when trying to match existing items from client and server in slow sync, or when a conflict occurs. The fields of the two items to be compared can be accessed as field variables with the prefix target or reference (as described in  REF _Ref47156991 \r \h 6.9.3) The following special context function is available for comparison (note that the context functions described in  REF _Ref46904847 \r \h 10.5.10 are also available): integer  XE "COMPAREFIELDS" \f F COMPAREFIELDS(): This performs the default comparison (according to the compare rules defined in the for the fields). It returns 0 if target equals reference, -1 if target is older than reference, 1 if target is newer than reference and -999 if target and reference cannot be compared at all or are not equal and no age of the items is known. The following example shows how to implement a relaxed comparison for vCalendar (only comparing dates, not times to avoid that time zone shift problems will generate duplicates in slow syncs):  XE "mergescript" \f T : Custom item merge Contained in: Available: in PRO versions only Can contain: script Script context: datatype context Attributes: none Default: no script This script can be used to implement custom merge algorithms. Merge is used when resolving conflicts, that is when two items need to be updated from each other to both contain all relevant data. The fields of the two items to be merged can be accessed as field variables with the prefix winning (for the item that wins the conflict, that is, contains the "better" or "never" data) or loosing (for the item that looses the conflict), as described in  REF _Ref47156991 \r \h 6.9.3. After the execution of , both items (loosing and winning) should be equal. The must call the SETWINNINGCHANGED() and SETLOOSINGCHANGED() functions (see below) when it modifies one of the items - this is required by the SyncML engine to know if corresponding updates must be sent to the remote party or applied to the local database. The following special context functions are available for comparison (note that the context functions described in  REF _Ref46904847 \r \h 10.5.10 are also available): integer  XE "MERGEFIELDS" \f F MERGEFIELDS(): This performs the default merge (according to the merge options defined in the for the fields). Calling this function also updates the WINNINGCHANGED() and LOOSINGCHANGED() (see below) flags to show if either of the items were modified. integer  XE "WINNINGCHANGED" \f F WINNINGCHANGED() and integer  XE "LOOSINGCHANGED" \f F LOOSINGCHANGED(): return TRUE if the corresponding (winning or loosing) item is flagged changed (which will cause it to be sent to the local database or the remote party for update).  XE "SETWINNINGCHANGED" \f F SETWINNINGCHANGED(integer changed) and integer  XE "SETLOOSINGCHANGED" \f F SETLOOSINGCHANGED(integer changed): used to set the change flags of the winning or loosing item, resp. XE "mimedirmode" \f T: MIME-DIR conformance Contained in: Can contain: "old" or "standard" Attributes: none This tag is used to define the behaviour of a which bases on the generic "mimedir" type. The following values can be specified: "standard" : The type behaves according to MIME-DIR (folding of long lines, encoding of multi-line fields, escaping of characters) "old": The type behaves like in the pre-MIME-DIR formats vCard 2.1 and vCalendar 1.0. Using this setting makes a type not to conform to MIME-DIR specifications, so it should be used with care. RRULE field block Datatypes based on "vcalendar" can make use of the "rrule" conversion mode (see  REF _Ref6046402 \r \h 10.3.4), which requires a special block of subsequent fields in the field list as follows: String field, containing 2 chars to code the type of recurrence: First character is the frequency code: (0 = none, D = daily, W = weekly, M = monthly, Y = yearly) Second char is the frequency modifier (space = none, W = by weekday list, D = by monthday list, M = by monthlist) Integer field, containing the interval (expressed as number of units specified in the frequency code) Integer field, containing a bit mask which codes the frequency modifications as follows: for weekly: Bit0=Sun, Bit6=Sat for monthly by weekday: Bit0=first Sun, Bit7=2nd Sun... Bit35=5th Sun for monthly by day: Bit0=1st, Bit1=2nd, Bit31=31st. for yearly by month: Bit0=jan, Bit1=feb,... Integer field, containing a bit mask like the previous field, but coding ocurrence from the end of the interval, not the beginning. This makes sense only as follows: for monthly by weekday: Bit0=last Sun, Bit7=2nd last Sun... for monthly by day: Bit0=last, Bit1=2nd last... Timestamp field, containing the date/time when the recurrence ends. If this is empty, the recurrence has no end and repeats forever. Timestamp field, containing the start of the entire event (this is normally the field used for DTSTART property). Note that this field will never be written by the RRULE conversion, but is only used as reference context for parsing/generating RRULEs. Note that this scheme covers most, but not all options possible in RRULEs. However, it covers all of the RRULE implementations commonly used in real-world applications. Please also note that not all combinations of frequency code and frequency modifier are valid. See sample config files to see how a RRULE block is defined and used. XE "server" \f T,  XE "client" \f T : General Server and Client Settings Contained in: Can contain: tags described in this chapter (see also  REF _Ref47164085 \r \h 12 for datastore-specific settings and  REF _Ref90895285 \r \h 16 specifically for clients) Attributes: type This tag encloses all server (or client) database related information. This includes three kinds of information: general (Database type independent) configuration tags. These are described in this chapter and can be used in any type of or tag. database type specific configuration. These are described inchapter  REF _Ref47164085 \r \h 12 for SQL/ODBC or SQLite based servers and clients and in chapter  REF _Ref135023442 \r \h 14 for the plugin based servers and clients. Note that the version 3.0 DEMO server is now a plugin-based configuration (see  REF _Ref135023442 \r \h 14) with a single, built-in text-file plugin (see  REF _Ref133810323 \r \h 14.3). For clients built on the Synthesis SyncML client engine library a few special configuration directives exist which are described in chapter  REF _Ref207626203 \r \h 15. For command line clients only, configuration of the Sync Request (information about the SyncML server to be contacted and synchronized with). These client-specific tags are described in  REF _Ref90895148 \r \h 16. The "type" attribute is required. It specifies the type of the server database. For the SQL/SQLite/ODBC type must be set to "odbc" or "sql". For the plugin version (which includes the DEMO server), type must be set to "plugin". Other values are reserved for future versions of the server with DB interfaces other than SQL/SQLite/ODBC or plugin)  XE "maxsyncmlversion" \f T , XE "minsyncmlversion" \f T : SyncML version support Contained in: Can contain: SyncML version string, currently: "1.2", "1.1" or "1.0" Attributes: none Default: all versions implemented are supported These tags specify what SyncML versions the server or client should support. Normally, the server allows clients to connect with all known SyncML versions (1.2, 1.1 and 1.0 at this time) and the client tries all SyncML versions when connecting to a server. For special testing it might be useful to limit the range of SyncML versions accepted. For clients, also see in  REF _Ref90895208 \r \h 16.1. XE "sessiontimeout" \f T: Timeout for unfinished sessions Contained in: Can contain: integer value, specifying timeout in seconds Attributes: none Default: 300 seconds (5 minutes) This tag specifies how long (minimally) a started, but not finished sync session will be kept alive in the server's memory. After this time, the server might abort the session to free ressources (depending on the platform and version, the server might however keep the session alive longer if there is no need to free resources).  XE "requestmaxtime" \f T : max time for request processing Contained in: Can contain: max duration (in seconds) of a single request processing, 0=no limit Attributes: none Default: 0 (=no minimum) This can be used to specify how quickly a client request should be processed by the server. This can be important if the server database is slow or the number of synced data items is large. In these cases, request processing could take so much time that the SyncML client would time out and abort the session before the server sends an answer. With it is possible to indicate to the SyncML server engine how long processing of a single request may take. If normal sequential processing would exceed the specified amount of time, the server takes measures to answer the request in time such as postponing execution of some commands or executing them in the background in a separate thread. Note that cannot always be met exactly - some datastore implementations or server platforms might not allow multi-threaded execution, or might have uninterruptable operations that could prevent from being met. By using in a (see  REF _Ref70164454 \r \h 11.36.23) it is possible to specify different request processing times on a device by device basis - however, as it takes one or two message exchanges until s can be evaluated and applied, make sure that in the is set to a reasonable time. On the other hand, operations performed before s can be applied are almost never time consuming (usually only a database login). Finally, using the REQUESTMAXTIME() script function (see  REF _Ref43008774 \r \h 6.14.6), maximum request time can also be controlled from scripts.  XE "requestmintime" \f T : artifical slow down Contained in: Can contain: minimal duration (in seconds) of a single request processing, 0=no minimum Attributes: none Default: 0 (=no minimum) This is only intended for debugging purposes. Setting this to non-zero causes the server to wait for each response before at least the specified number of seconds have passed since the last request arrived. This can help to slow down sync sessions such that testing things like manually aborting sessions in the middle, disconnecting network etc. gets possible. Using the REQUESTMINTIME() script function (see  REF _Ref43008774 \r \h 6.14.6), such slow-down behaviour can also be applied to certain sessions only (like depending on user options). XE "externalurl" \f T: specify URL used to access the server Contained in: Can contain: fully specified URL Attributes: none Available: server only Default: not set This tag is used to set the URL which is used by external clients to access the server. Note that this is normally neither required nor recommended, so please use this option with care in special situations only (exotic proxy or redirection situations). If this option is set, the server will use this hard-coded URL in its tags rather than the URL which was used by the client to address the server in the first place. XE "requestedauth" \f T,XE "requiredauth" \f T: SyncML Authentication Contained in: Can contain: SyncML authentication method name Attributes: none Default: md5 NOTE: in Server versions before 1.0.5.3 the tag was misspelt as . So if you are upgrading from an older server, this spelling error should be corrected in your existing config file. These tags specify what type of server-level authentication the SyncML server requests (or requires minimally, resp.) from a SyncML client that want to connect. In most but very special test cases both tags should have the same value. The following values are allowed: "none" : the server does not require the client to authenticate itself. This is not a common case, as on a multi-user server authentication is needed to login to the user's data. "basic" : the client can use the SyncML "basic" authentication method (or md5, see below). This is not recommended generally as in this method the password is sent unencrypted over the net. "md5": the client must use the SyncML "md5" method. MD5 is an algorithm that encrypts the password in a way that is cannot be recovered from the data that travels over the net. This is the recommended settings, because all compliant SyncML clients are required to support this anyway. If your database does store passwords in MD5-digest form (see " REF _Ref13981914 \r \h 12.13"), you must set to "basic", as it is not possible with SyncML 1.0 to check MD5 digests (it will be possible with SyncML 1.1 and later). Note that should always be set to the same or higher "strength" method than (none < basic < md5 in terms of "strength"). Otherwise the server would request something "weaker" from the client than what it actually requires for authentication - which makes no sense and will block client login. XE "autononce" \f T: MD5 nonce generation mode Contained in: Can contain: boolean value Attributes: none Default: on This is a special option that controls the behaviour of MD5 authentication. It should be set to on under normal circumstances. The technical background is that the MD5 authentication scheme uses a so-called nonce string to increase security. The nonce string is generated by the server. When autononce is on, this happens automatically. When autononce is off, the server does not send a nonce string or uses a constant string that can be specified with the tag (see below). This compromises security, but might be useful for testing or other special circumstances. XE "constantnonce" \f T: constant nonce string Contained in: Can contain: nonce string Attributes: none Default: empty This tag should be used when is not set to specify a constant nonce string to be used in MD5 authentication.  XE "sendrespuri" \f T ,  XE "respurionlywhendifferent" \f T : RespURI configuration Contained in: Can contain: boolean value Default: true (for both options) controls if the server should create a RespURI including a sessionID CGI string or not. Default is true, because for HTTP servers this is required for session tracking. For transports which have a transport-level session context, this may not be required so it can be turned off. By default, the RespURI is only generated when it is different from the URI used for the current request. can be set to false to always generate a RespURI. XE "simpleauthuser" \f T, XE "simpleauthpw" \f T: single user mode Contained in: Can contain: username, password Attributes: none Default: not specified For single-user situations, it might be that the overhead of having a separate table for authenticating users is not desired. For this special case, these two tags allow to provide a single username and password. A SyncML client trying to authenticate with a matching user/password combination will be granted access. In this case, the (see " REF _Ref5614672 \r \h 12.13") will never be executed, and therefore there will be no userkey value that can be used as parameter (%U) in subsequent queries. Do not use these tags unless you have a true single-user situation. Example: test test  XE "multithread" \f T : Allow multi-threaded execution Contained in: Can contain: boolean value Default: false ( for Linux ) / true ( for all other operating systems ) Allows multi-threaded execution for the server, if set to true. As there are problems in early 2.4 Linux kernels, multi-threading was switched off completely for Linux in the past. For compatibility reasons the default value is set accordingly. When is on, the server uses a separate thread for each datastore to load the sync set, as this can take a long time for large sync sets and the server needs to continue communicating with the client to prevent the client to time out.  XE "sessioninitscript" \f T : Session init script Contained in: , Available: in PRO versions only Can contain: script Script context: session context Attributes: none Default: no script This script is executed whenever a new session is started. It can be used to declare and initialize variables in the session script context (which can be accessed from other script contexts using the SESSIONVAR and SETSESSIONVAR built-in functions, see  REF _Ref43008774 \r \h 6.14.6).  XE "sentitemstatusscript" \f T : Session finish script Contained in: , Available: in PRO versions only Can contain: script Script context: session context Attributes: none Default: no script This script is executed whenever a session (successfully) comes to its end. All variables of the session script context can be used. See also for details.  XE "sentitemstatusscript" \f T ,  XE "receiveditemstatusscript" \f T : Session level status code handling Contained in: , Available: in PRO versions only Can contain: script Script context: session context Attributes: none Default: no script These scripts can be inserted in the session level as well as in the datastore level. See  REF _Ref45371286 \r \h 11.34.27 and  REF _Ref45371414 \r \h 11.34.28 for details.  XE "customgetputscript" \f T ,  XE "customendputscript" \f T : Creation of custom SyncML Get and Put commands Contained in: , Available: in PRO versions only Can contain: script Script context: session context Attributes: none Default: no script This allows issuing custom SyncML and commands - custom commands, such as Alert 100 to display a message to the user) are possible as well. The is executed at the beginning of the session when and for device information are sent. The is executed at the end of the session to allow sending custom session summary or status information to the remote. For example, a Alert 100 could transmit information about conflicts etc. to the client. The script must return TRUE if it has handled the item. If it returns nothing or FALSE, other handlers (such as the default handler for devInf) are checked. The following functions are available to these scripts:  XE "ECHOITEM" \f F SETSTATUS(integer status): Sets the status code to be returned for the get/put/result command. If no status is set, the engine assumes the command execution was successful. string ITEMURI(): Returns the Target LocURI of the item. This should be checked for known URIs to decide if the script should handle the command or not. SETITEMURI(string locURI): Sets the Target locURI of the item for sending a command. string ITEMDATA(): Returns the of the item. SETITEMDATA(string itemData): Sets the of the item to the string itemData. string METATYPE(): Returns the information of the item. SETMETATYPE(string metaType): Sets the information of the item to the string metaType. ISSUEPUT(boolean allowfailure, boolean noresp): Creates and issues a command using the values set by SETITEMURI(), SETMETATYPE() and SETITEMDATA(). If allowfailure is set, the status returned for the by the remote is ignored and will not cause the session to abort if it is not ok. If noresp is set, the remote is told not to respond to this command. ISSUEGET(boolean allowfailure): Creates and issues a command using the values set by SETITEMURI() and SETMETATYPE(). If allowfailure is set, the status returned for the by the remote is ignored and will not cause the session to abort if it is not ok. ISSUEALERT(boolean allowfailure, integer alertcode): Creates and issues a command with alertcode and one item containing the string set by SETITEMDATA(). If allowfailure is set, the status returned for the by the remote is ignored and will not cause the session to abort if it is not ok. < XE "customgethandlerscript " \f T customgethandlerscript>: Custom handling of SyncML Get commands Contained in: , Available: in PRO versions only Can contain: script Script context: session context Attributes: none Default: no script This allows specifying a script to handle items of SyncML commands. This can be useful for implementing custom functionality. The script must return TRUE if it handles the command and produces any data to be returned as to the sender of the command. If it returns nothing or FALSE, other handlers (such as the default handler for devInf) are checked. The same functions as in (see  REF _Ref153699553 \r \h 11.15) are available to this script. < XE "customputresulthandlerscript " \f T customputresulthandlerscript>: Custom handling of SyncML Put/Result commands Contained in: , Available: in PRO versions only Can contain: script Script context: session context Attributes: none Default: no script This allows specifying a script to handle items of SyncML and commands. This can be useful for implementing custom functionality. The script must return TRUE if it has handled the item. If it returns nothing or FALSE, other handlers (such as the default handler for devInf) are checked. In addition to the functions available in (see  REF _Ref153699553 \r \h 11.15), the following special function is available in : boolean ISPUT XE "ECHOITEM" \f F  (): Returns TRUE if the command that called the script is a SyncML command, false if it is a SyncML command.  XE "waitforstatusofinterrupted" \f T : SyncML command flow option Contained in: , Can contain: boolean value Attributes: none Default: no This is a highly technical setting. If set to yes, a interrupted command (for example a command that had to be terminated to fit into one message and needs to be continued in the next message) will not be continued until the status for the previous part has arrived.  XE "waitforstatusofinterrupted" \f T : Add resending policy Contained in: Can contain: boolean value Attributes: none Default: yes This is a highly technical setting. If set to no, the server does not re-send commands again until a subsequent session has successfully completed. This is to avoid duplicates for clients that do not reliably re-send unconfirmed items left over from the previous session at the beginning of the next session. For properly SyncML conformant clients, this can be set to yes (the default).  XE "debugchunkmaxsize" \f T : LargeObject chunk size limit for testing Contained in: , Can contain: max size of chunk for LargeObject in bytes Attributes: none Default: 0 (disabled) This is a highly technical setting. If set to non-zero, all objects larger than the specified number of bytes will be sent in chunks of no more than the specified size. The only use of this is to test LargeObjects implementation in SyncML DS 1.1 and 1.2 remote parties. Usually, the reported by the remote party determines when objects need to be sent in multiple chunks.  XE "deletinggoneok" \f T : Handling of delete for non-existing items Contained in: , Can contain: boolean value Attributes: none Default: yes This is a highly technical setting. If set to yes, receiving a delete command for an item that does not exist is not considered an error. However, some implementation (especially the SCTS test tool) requires an error message for that, hence this option.  XE "usertimezone" \f T : Set user's default time zone Contained in: , Can contain: time zone name (see list of all time zones in  REF _Ref185261956 \r \h 17) Attributes: none Default: system time zone This defines the user's default time zone. This is important for synchronizing with client that only support local time specifications (rather than UTC). For installations supporting multiple user time zones, the USERTIMEZONE() script function (see  REF _Ref204925451 \r \h 6.14.4) can be used to set the time zone specifically for a sync session, usually derived from the user account.  XE "autoenddateinclusive" \f T : end date for allday events inclusive Contained in: , Can contain: boolean value Attributes: none Default: true for clients, false for servers. If this option is set, date values with conversion mode "autoenddate" (see  REF _Ref182995906 \r \h 10.3.4).will be rendered as 23:59:59 of the previous day in old formats like vCalendar 1.0. If it is not set, "autoenddate"s will be rendered as 0:00 of the next day (which usually is the first day not included in the all-day event when "autoenddate" is used for DTEND properties). Note that this setting can be modified on a per-device basis using a remote rule (see  REF _Ref231889747 \r \h 11.36.18) < XE "abortonallitemsfailed " \f T abortonallitemsfailed>: error handling option Contained in: , Can contain: boolean value Attributes: none Default: yes This determines if receiving an error for all items sent in a slow sync to the remote party is considered a complete failure of the entire sync for that datastore, or if the failing items are simply marked for being re-tried in the next sync. (Note that before 3.1.x, this applied to normal sync as well – which is no longer the case as in a normal sync with few upates a failure of these usually does not indicate a general problem).  XE "showctcapproperties" \f T : show field support details in device information Contained in: , Can contain: boolean value Attributes: none Default: yes This determines if the list of supported fields should be listed in the device information sent to the remote party. Normally, this should be switched on – but sometimes if a device does not send all fields one would expect it should send, disabling sending the field information might help as then the device cannot do (possibly wrong) decisions on the fields it should send based on the device information. This can help to debug IOT problems with such devices. Note that there is a scripting function SHOWCTCAPPROPERTIES (see  REF _Ref43008774 \r \h 6.14.6) that allows switching this option on and off on a session by session base (for example in the , see  REF _Ref43727925 \r \h 11.33, maybe depending on AUTHDEVICEID()).  XE "showtypesizeinctcap10" \f T : show size and type in SyncML 1.0 devInf Contained in: , Can contain: boolean value Attributes: none Default: no This determines if in the list of supported fields, the type and (max)size information should be included when sending devInf to SyncML 1.0 devices. By default, this is set to "no", because even though type and (max)size is valid information for SyncML 1.0, some of these (old) client implementations cannot handle it and would crash. This option can be set to "yes" in the unlikely case the type and (max)size information should be included for SyncML 1.0 clients. SyncML 1.1 and later clients are not affected (and always receive type and (max)size information when available server side).  XE "enumdefaultpropparams" \f T : enumerate default property parameter's values as property names Contained in: , Can contain: true, false, default Attributes: none Default: default (automatic) This determines how the default parameter of a MIME-DIR property (for example TYPE for TEL in vCard 2.1) is shown in the device information. If it is set to true, all possible values for the parameter are enumerated as parameter names (propParam tag). This is required e.g. by some Nokia DS 1.1 clients. If it is set to false, the possible parameter values are shown as valEnum tags, as required by DS 1.2 clients. If set to "default", the format is automatically chosen depending on the SyncML version of the current session. Except for very special cases, usually in debugging new clients, this setting should be left at its default. Note that there is a scripting function ENUMDEFAULTPROPPARAMS (see  REF _Ref43008774 \r \h 6.14.6) that allows switching this option on and off on a session by session base (for example in the , see  REF _Ref43727925 \r \h 11.33, maybe depending on AUTHDEVICEID()).  XE "acceptserveralerted" \f T : Acceptance of server alerted sync types Contained in: , Can contain: boolean value Attributes: none Default: yes If yes, "server alerted" sync types are accepted by the server. They operate exactly like the normal client-initiated sync types, but indicate that the sync was triggered by the server (for example via SAN using the Synthesis PushAlerter tool). If for some reason a server should generally reject server alerted syncs, this can be set to false.  XE "logfile" \f T : Activity log text file Contained in: , Can contain: complete path for log file Attributes: none Default: none This tag can contain a path to a text file (which must be writable). For each datastore involved in a sync session, a log entry as specified with (see  REF _Ref47167783 \r \h 11.31) will be appended to this file (usually a single line). Note that in addition to this logfile, you can also specify a SQL statement to store log information in a SQL database table (see  REF _Ref46754571 \r \h 12.19).  XE "logenabled" \f T : Activity log enable Contained in: , Can contain: boolean value Attributes: none Default: true This tag enables or disables recording activity log information in the text file (see  REF _Ref47168251 \r \h 11.21), in the SQL database table (see  REF _Ref46754571 \r \h 12.19) and in a eventual database adapter plugin (see  REF _Ref153681044 \r \h 14.2). Note that this setting is used as the default setting for all sessions, but using the SETLOG() function in or (see  REF _Ref47168523 \r \h 11.33 and  REF _Ref47168540 \r \h 12.17) activity log can be enabled or disabled on a per-session basis (for example, prevent logging specific test users etc.).  XE "logformat" \f T : Activity log format Contained in: , Can contain: string (C-string) Attributes: none Default: standard logfile format, depends on server/client version This string is used to format log entries. It is a string in the C language syntax (see  REF _Ref47171157 \r \h  \* MERGEFORMAT 3.4), To actually insert useful log information, the following sequences can be used: %T Time of sync as plain text (synonymous with %seT) %ssT Sync start time in plain text (when this sync attempt, successful or not, has started) %seT Sync end time in plain text (when this sync attempt, successful or not, has ended) %nD Datastore name (the name as defined in , see  REF _Ref47169243 \r \h 11.34) %rD Datastore remote path (identification of the remote party's datastore) %lD Datastore local path (how the remote party has addressed the local datastore, this might include subfolder information and CGI options) %iR Remote Device ID (URI of the remote device, usually a IMEI number for phones) %nR Remote Device name (if a is applied which has a part, this shows the instead of the real name sent by the device. See  REF _Ref42941679 \r \h 11.36 for details) %vR Remote Device version information as provided by the device's device information in the following format: DeviceType (HardwareVersion, FirmwareVersion, SoftwareVersion) OEMname %U User name %sS Status code for this datastore (0 if successful, 408 for timeout, all other errors are SyncML status codes). Note that other datastores in the same sync session might have different status. %ssS Session status code (0 if successful, 408 for timeout). Note that the session status can be successful even if some datastores have non-successful status. %syV SyncML protocol version string ("1.2", "1.1" or "1.0"). %syVn Numeric code for SyncML protocol version: 1=1.0, 2=1.1, 3=1.2 %mS Sync Mode (0=twoway, 1=fromclient 2=fromserver) %tS Synctype (0=normal,1=slow,2=firsttime slow, 10=normal resumed, 11=slowsync resumed, 12=first time resumed) %laI number of locally added Items %raI number of remotely added Items %ldI number of locally deleted Items %rdI number of remotely deleted Items %luI number of locally updated Items %ruI number of remotely updated Items %leI number of locally failed Items %reI number of remotely failed Items %diB number of incoming (received) content data bytes for this datastore (net content data excluding any SyncML protocol overhead) %doB number of outgoing (sent) content data bytes for this datastore (net content data excluding any SyncML protocol overhead) For servers only, the following sequences are also available: %iS Server Session ID (useful to find a corresponding debug logfile, see  REF _Ref47170147 \r \h 8.11) %smI number of items matched in slow sync %scI number of conflicts won by the server %ccI number of conflicts won by the client %dcI number of conflicts resolved by duplicating the conflicting item %tiB session total of incoming (received) bytes (SyncML messages, not including transport protocol's header or other envelope data) %toB session total of outgoing (sent) bytes (SyncML messages, not including transport protocol's header or other envelope data)  XE "loglabels" \f T : Activity log header Contained in: , Can contain: text (C-string) Attributes: none Default: header for standard logfile format, depends on server/client version This tag specifies a text (in C-String format, see  REF _Ref47171157 \r \h 3.4) that is written as the first line in the file specified as . This can be useful to write a header for a log file in tab separated text form, for example. XE "logininitscript" \f T,  XE "loginfinishscript" \f T : Pre- and post-login scripts Contained in: Available: in PRO versions only Can contain: script returning boolean value Script context: login context Attributes: none Default: no script The is executed before testing login details with the database. It can be used to pre-process the user name for example. If this script returns TRUE as result, this means that login is granted without any further database lookup. If the script returns FALSE as result, this means that login is rejected without any further database lookup. If the script does not return a value, this means that futher checks are needed to validate the login data (such as executing , see  REF _Ref43727921 \r \h 12.16, and , see  REF _Ref43727928 \r \h 12.17). The is executed after database level authorisation is done (regardless of the result) and has the final say about actually allowing or denying access. If this script does not return a value, the result of the database level authorisation decides about granting access. Otherwise, if this script returns TRUE as result, this means that login is granted, otherwise access is denied. The is a good place to apply user-specific parameters (like setting the user time zone context, see  REF _Ref185257870 \r \h 5.2). These scripts have access to the SQL execution functions described in  REF _Ref78024414 \r \h 12.1.4 and the following special script functions: integer XE "AUTHOK" \f FAUTHOK(): returns true if the standard checking thinks that login is ok. string XE "AUTHUSER" \f FAUTHUSER(): name of the user that tries to log-in XE "SETUSERNAME" \f FSETUSERNAME(string username): sets the username that should be used to perform login checking (can be used in SQL with %U) XE "SETDOMAIN" \f FSETDOMAIN(string domain): Sets the "domain", can be used in SQL with %D string XE "AUTHSTRING" \f FAUTHSTRING(): The auth string sent by the remote (clear text password or MD5 digest) integer XE "AUTHTYPE" \f FAUTHTYPE(): 0=anonymous (no credentials), 1=password in clear text, 2=SyncML 1.0-type MD5 digest, 3=SyncML 1.1-type MD5 digest. string XE "AUTHDEVICEID" \f FAUTHDEVICEID(): The device ID sent by the remote integer XE "UNKNOWNDEVICE" \f FUNKNOWNDEVICE(): returns TRUE if this is the first time this device tries to connect this server. string  XE "USERKEY" \f F USERKEY(): Gets the current userkey (as set by SETUSERKEY() or retrieved by the query, see  REF _Ref43727921 \r \h 12.16) XE "SETUSERKEY" \f FSETUSERKEY(string userkey): Sets the value that should be used as "userkey". string  XE "DEVICEKEY" \f F DEVICEKEY(): Gets the current device key (as set by SETDEVICEKEY() or retrieved by the query, see  REF _Ref68495073 \r \h 12.15) XE "SETDEVICEKEY" \f FSETDEVICEKEY(string devicekey): Sets the value that should be used as "devicekey". integer  XE "CHECKAUTH" \f F CHECKAUTH(string user, string secret, integer secretismd5): This function allows implementing completely custom checking of credentials in the . It checks if the credentials sent by the remote device matches the specified user and secret. Secret must be either the password in clear text (if secretismd5==FALSE) or the b64(md5(user:password)) hash (if secretismd5==TRUE). Usually a custom credential checking involves getting the secret for a user from the local database (EXECSQL etc., see  REF _Ref78024414 \r \h 12.1.4), possibly converting/decrypting it to obtain either a clear-text password or the b64(md5(user:password)) hash. If furthe database accesses depend on a user key, SETUSERKEY() should be used to set it appropriately. Finally, the would return the result of CHECKAUTH() to accept or reject the login request. timestamp  XE "CONVERTTOUSERZONE" \f F CONVERTTODATAZONE(timestamp atime [,boolean doUnfloat]): this returns atime converted to the data time zone (the time zone set for the datastore or the session using , see  REF _Ref185246110 \r \h 11.34.31). If doUnfloat is set to true, floating time stamps will be fixed into local time of the data time zone, without changing their time value. integer TIMESTAMPTODBINT(timestamp ts,string dbfieldtype): Converts the timestamp ts's value to a integer representation. Dbfieldtype specifies the integer representation type to use as a database field type (see  REF _Ref47173451 \r \h 11.34.41.1). Note that not all database field types can be used, but only "lineartime", "lineardate", "unixtime_s", "unixtime_ms", "unixtime_us", "unixdate_s", "unixdate_ms", "unixdate_us". timestamp DBINTTOTIMESTAMP(integer dbint,string dbfieldtype): Converts the integer representation of a date/time value dbint into a timestamp value. Dbfieldtype specifies the integer representation type to use as a database field type (see  REF _Ref47173451 \r \h 11.34.41.1). Note that not all database field types can be used, but only "lineartime", "lineardate", "unixtime_s", "unixtime_ms", "unixtime_us", "unixdate_s", "unixdate_ms", "unixdate_us". XE "datastore" \f T: General Datastore settings Contained in: Can contain: , , and server-type specific tags, see  REF _Ref42944330 \r \h 12.20. Attributes: name, type Default: not specified This tag specifies all the details for one datastore. A datastore is the SyncML concept for a collection (table) of objects (records) of the same type (e.g. vCard or vCalendar). A can contain multiple sections to support multiple datatypes. Note that the sample config file defines two datastores, one for contacts (vCard) and one for events and tasks (vCalendar). A datastore must have a name attribute, which specifies the name under which the datastore will be accessible from the SyncML client. For example, if the name is set to "mytest", the datastore will be accessible under "./mytest" (some clients allow just "mytest"). Note that the folder concept (see  REF _Ref42943895 \r \h 12.20.1) allows datastores to contain multiple folders that are addressed like "./mytest/foldername". A datastore can also have a type attribute. It has no relevance in SyncML engines that support only one type of datastore (such as textfile or odbc) - which is the case for our current standard products. However, future products and customized products might need the type attribute to select among different types of datastores (that is, database interfaces). Note that this section only covers the settings that are not dependent on the database type. See  REF _Ref42944330 \r \h 12.20 and for settings specific to ODBC or for text (demo) datastores. Example (skeleton for a contact and a task/event datastore):  XE "dbtypeid" \f T : alternate name for this datastore Contained in: of Can contain: alternate data store name Attributes: none Default: none This can be used to make the same datastore accessible with an alternate name. In scripts the LOCALDBNAME() function (see  REF _Ref55271118 \r \h 11.34.21) can be used to find out what name was used by the remote (client) to address the datastore – and possibly behave differently depending on what name was used.  XE "dbtypeid" \f T : datastore type ID Contained in: Can contain: 32-bit unique identifier number for datastore, must not be zero Attributes: none Default: none This is required for SyncML engine library based applications. The is a 32-bit number which is used to identify the datastore when accessing its user settings (see SDK manual for details about accessing settings via the settings key mechanisms). It is also used to identify datastore related progress events. The must be unique for each in the config, may not be zero and must not change once assigned (if it changes, related user settings will get detached). Otherwise, you are free to choose any number for this ID. XE "displayname" \f T: decriptive name for a datastore Contained in: Can contain: string Attributes: none Default: none This option allows to set a descriptive name for a datastore. This descriptive text will be transmitted to the remote party and might be used instead of the real name in communication with the end user (to select a database from a list, for example). In Synthesis SyncML engine library, this string can be queried as "dispName" value. XE "readonly" \f T: read-only datastore Contained in: Can contain: boolean value Attributes: none Default: off This option allows a datastore to be defined as read-only. This will cause that the remote party cannot write to that datastore (attempts to do so will simply be ignored). Note that in PRO versions, it is also possible to switch to read-only mode based on login information; see session-level SETREADONLY() script function in  REF _Ref45368706 \r \h 11.33, and datastore-level SETREADONLY() script function in  REF _Ref55271118 \r \h 11.34.21. XE "deletewins" \f T: delete overrides replace Contained in: Can contain: boolean value Attributes: none Default: off New in: 3.0.2.2 Normally, when a delete and a replace operation conflict, the replace always wins to preserve data. When is set, this makes delete win over replace. Note that in a function DELETEWINS is available (see  REF _Ref169609101 \r \h 10.5.11) to set delete override on a item-per item basis. XE "tryupdatedeleted" \f T: try to update "deleted" items Contained in: Can contain: boolean value Attributes: none Default: off New in: 3.0.2.2 This is a special option relevant only for the case of a client update conflicting with a server delete (and not set, see  REF _Ref169607904 \r \h 11.34.5). Server deletes can be caused by the item really deleted from the server, but also if a item falls out of a filter (such as a date range). In the latter case, the item still exists, but is no longer visible in the syncset. If the client tries to update such an item, the update will be converted to an add, because that item is not in the syncset. This creates a duplicate in the server database. With , before adding the item again, the server will try to update the item. Only if that fails, this means that the item is really deleted, not only filtered out and should be added again. XE "reportupdates" \f T: transmit updates to remote Contained in: Can contain: boolean value Attributes: none Default: on Setting this option to "no" will suppress reporting changes to existing records to the remote party. This can make sense for datastores with objects that cannot change per definition (such as received email) and will prevent updates for such objects in all cases (even if the modification date is updated).  XE "maxitemspermessage" \f T : maximum number of data items per SyncML message Contained in: Can contain: max number of items per SyncML message (0=no limit) Attributes: none Default: 0 (no limit) This can be used to specify how many items from this datastore are sent to the remote party in a single SyncML message maximally. Usually, there is no need to set a maximum, as the maximum SyncML message size implicitly limits the number of items anyway. However, if a datastore is exceptionally slow in fetching even small data items, setting a limit can ensure composing a SyncML message does not take too long. XE " alwayssendlocalid " \f T: send localID (GUID) in all operations (not only adds). Contained in: (in only) Can contain: boolean value Attributes: none Default: off New in: 3.0.2.0 Setting this option to "yes" will cause the server to send the server-side ID (localID, GUID) to be sent to the client not only in SyncML "Add" commands, but also for "Replace" and "Delete". Note that this is not strictly according to the SyncML standard – however it is accepted by real-world clients and helps avoiding problems when client items addressed by a "Replace" command do not exist any more. Without the localID, a client cannot add items instead of replace, which can cause sessions to abort. XE "conflictstrategy" \f T, XE "slowsyncstrategy" \f T, XE "firsttimestrategy" \f T: sync conflict resolution strategy Contained in: Can contain: conflict strategy name Attributes: none Default: newer-wins These tags specify how to handle conflict situations (an object was modified on both server an client). defines the strategy that is used during normal synchronisation, where defines the strategy that is used in so-called slow sync (not first time synchronisation after some problem or data loss in either client or server). defines the strategy that is used in first-time sync, and is normally set to the same strategy as The following values can be specified: "duplicate" : The conflicting objects are duplicated such that both client and server will have both versions of the object. The user then decides which one is the "right" one or to keep both. "newer-wins": If the objects in question both carry a timestamp when they were last modified, the object that was more recently modified will "win" the conflict. If no timestamps are available, this mode works like "duplicate". "server-wins": Server's version always wins the conflict. "client-wins": Client's version always wins the conflict. Note that "winning" does not necessarily mean that winning side's data simply overwrites loosing side's data. Synthesis Sync Server has powerful merging features that will combine data from both objects. The merging is contolled by the "merge" attribute of the tag (see  REF _Ref5625615 \r \h 10.2) and can be customized with (PRO version only). The default setting of "newer-wins" is the most "smart" mode; it reduces unnecessary duplicates while still avoiding newer data to be overwritten with older data. Note that the actual strategy used for a sync session can also be defined in runtime (depending on user settings for example) by using the SETCONFLICTSTRATEGY() script function in the (see  REF _Ref55271118 \r \h 11.34.21). XE "typesupport" \f T: datastore's supported types Contained in: Can contain: Attributes: none This tag defines what SyncML content data types (as defined in the config section, see  REF _Ref6129297 \r \h 10) are used for sending data to and receiving data from a SyncML client. The tag must contain a tag for every data type that is to be supported by the datastore. A datastore can support multiple (similar) types such as different versions of vCard for a contact datastore. XE "use" \f T: use a datatype Contained in: Can contain: nothing Attributes: datatype, mode, preferred This tag adds support for a datatype (such as a vCard or vCalendar version, or any other customer-defined datatype). The tag has the following attributes: "name": this must be a name of a previously defined datatype (using the tag in the section of the config file (see  REF _Ref6060179 \r \h 10.5). "mode": this optional attribute specifies if the datatype is to be used for receiving data from the client ("r") or for sending data to the client ("w") or both ("rw"). The default is "rw". "preferred": this optional attribute must be present for exactly one write-enabled and one read-enabled (or one combined read-write-enabled) tag. It is used to specify which datatypes are preferred for reading and writing. The special value "legacy" can be specified instead of "no" to specify a type that should be used as the preferred type when the engine runs ins so-called legacy mode (i.e. when a not fully conformant remote party is detected automatically or settings or remote rule (see  REF _Ref247361819 \r \h 11.36.21) demand it). For example, in configurations that support both vCard 2.1 and vCard 3.0, usually vCard 3.0 should be marked preferred=yes, and vCard 2.1 as preferred=legacy. So fully compliant remote parties will profit from the newer vCard 3.0 format, while bad implementations that might not work properly with the new format will use the older vCard 2.1. "rulematch": (3.0.2.0 and newer) this optional attribute is used to define device-specific data types. The contents of "rulematch" can be a single name of a (see  REF _Ref42941679 \r \h 11.36) or a comma separated list of remote rule names. The names might also contain wildcards (* and ?). If "rulematch" matches the currently active remoterule, the specified datatype will be used instead of the preferred type and overriding normal transfer type negotiation. Example (a contact datastore supporting vCard 2.1 and vCard 3.0 for both reading and writing, while preferring vCard 2.1, and a special datatype exclusively for a exotic device):  XE "ds12filters" \f T : enable SyncML DS 1.2 filtering Contained in: Can contain: boolean value Attributes: none Default: on If this is set to true, the sync engine accepts SyncML DS 1.2 style specifications (see  REF _Ref153291752 \r \h 7.4 for syntax) in the commands, and reports filter capabilities in the device information (SyncML DS 1.2 only).  XE "ds12filters" \f T : enable date range filtering Contained in: Can contain: boolean value Attributes: none Default: on If this is set to true, this datastore supports date range filtering (see /dr() option in  REF _Ref153732324 \r \h 7.5 and SINCE/BEFORE keywords in  REF _Ref153288035 \r \h 7.3). Note that actual support must be implemented using appropriate in the datatype (see  REF _Ref55274563 \r \h 10.5.10) or in SQL (see  REF _Ref153732596 \r \h 12.20.25) to actually make date ranges functional. Setting this option only makes date range filtering keywords appear in the device information (SyncML DS 1.2 only).  XE "acceptfilter" \f T : check incoming items Contained in: Can contain: filter expression (see  REF _Ref46752884 \r \h 7) Attributes: none This filter is applied (in test mode) to incoming items to check if the datastore can process them. If not, the item is rejected with SyncML status code 415 ( unsupported type or format). This filter is also applied in make-pass mode (see  REF _Ref47262189 \r \h 7.1) to any item sent from the datastore to the remote party to make sure it meets the conditions. This filter is useful for example to avoid vTODO items to mess up an event-only datastore and vice versa. Note that more complex filtering (or filtering that causes items to be ignored rather than rejected with status 415) can be implemented with the (see  REF _Ref46823145 \r \h 10.5.11). To simply make discard items silently instead of returning status 415, use (see  REF _Ref247356244 \r \h 11.34.16).  XE "silentdiscard" \f T : discard not accepted items silently Contained in: Can contain: boolean value Attributes: none If this is set to true, incoming items that do not pass the (see  REF _Ref247356327 \r \h 11.34.15) are silently discarded and successful status is returned, rather than 415.  XE "localdbfilter" \f T : filter subset of datastore Contained in: Can contain: filter expression (see  REF _Ref46752884 \r \h 7) Attributes: none This filter is applied (in test mode) to all items read from the local database. If an item does not pass the filter, it will be simply ignored for the synchronisation. This filter is also applied in make-pass mode (see  REF _Ref47262189 \r \h 7.1) to any item sent from the remote party before storing it in the local database. This filter basically does the same thing (actually with reversed logic) as the . However, while visibility is something that is also changed on a per-item basis, the is meant to implement a first-level subselection of items. An example for this would be when a server database that contains both events and tasks, but we need to create a for events only. Normally, this can be archieved by appropriate WHERE clauses in SQL statements directly, but with this can be implemented for text-based datastores as well.  XE "invisiblefilter" \f T : filter invisible items Contained in: Can contain: filter expression (see  REF _Ref46752884 \r \h 7) Attributes: none This filter is applied (in test mode) to items to be sent to the remote party. If the filter result is true, the item is not sent to the remote party (it is considered invisible for the remote party). This filter is also applied in make-pass mode (see  REF _Ref47262189 \r \h 7.1) when the SyncML engine must make an item invisible for the remote party. For example, when a SyncML client sends an archive-delete command, the SyncML engine will apply to the item - which looks like deleting the item from the client (it is not there any more - invisible) but still exists in the database.  XE "makevisiblefilter" \f T : make item visible Contained in: Can contain: filter expression (see  REF _Ref46752884 \r \h 7) Attributes: none This filter is never used in test mode, but only in make-pass mode (see  REF _Ref47262189 \r \h 7.1) as follows: When an item must be made visible for the remote party, and test returns true (meaning that the item is invisible), then the is applied in make-pass mode. This happens for items that are added to a server from a client to make sure they will be visible when they are read back from the server database later.  XE "makepassfilter" \f T : make incoming items pass Contained in: Can contain: filter expression (see  REF _Ref46752884 \r \h 7) Attributes: none This filter is never used in test mode, but only in make-pass mode (see  REF _Ref47262189 \r \h 7.1) as follows: Before an incoming items is added to the database, the is applied in make-pass mode. This primarily makes sense in a server that has visibility control to make sure that items added from clients without a visibility level specified in the database path CGI are added to the database with a defined visibility level.  XE "datastoreinitscript" \f T : script called before accessing database Contained in: Available: in PRO versions only Can contain: script Script context: datastore context Attributes: none Default: no script This script is executed just before the datastore contents (that is, the sync set's data itself) is accessed for the first time in a sync session. Note that access to administrative data (like targets and maps) has already taken place at this time. This is is good place to modify filters depending on the remote device (see remote rules in  REF _Ref42941679 \r \h 11.36 and REMOTERULENAME() function in  REF _Ref43008774 \r \h 6.14.6) or depending on options passed by the client (such as the string in DBOPTIONS(), see below). It is also the place to apply options like readonly folders that have been detected for example in (see  REF _Ref166651506 \r \h 11.34.23). This script has access to the following special script functions: string  XE "GETCGITARGETFILTER" \f F GETCGITARGETFILTER(): returns the current temporary filter string as sent by client, see CGI options in  REF _Ref46896711 \r \h  \* MERGEFORMAT 7.4. Note that this might change during the sync session, depending on the client. The complete filter expression used as temporary filter consists of GETCGITARGETFILTER() and GETTARGETFILTER() together. string  XE "GETTARGETFILTER" \f F GETTARGETFILTER(): returns the current temporary target filter string (as internally set by SETTARGETFILTER or ADDTARGETFILTER, see below). The complete filter expression used as temporary filter consists of GETCGITARGETFILTER() and GETTARGETFILTER() together  XE "SETTARGETFILTER" \f F SETTARGETFILTER(string targetfilter): sets the current temporary filter to targetfilter, overwriting any existing filter string.  XE "ADDTARGETFILTER" \f F ADDTARGETFILTER(string targetfilter): adds an additional temporary filter expression to the existing dynamic target filter (See  REF _Ref46752884 \r \h 7 for difference between dynamic and static filters). This function automatically inserts parantheses and an "and" operator such that the resulting filter expression will be true only if both existing and new added filter expressions string  XE "GETFILTER" \f F GETFILTER(): returns the current dynamic target filter string (as eventually sent by client, see CGI options in  REF _Ref46896711 \r \h  \* MERGEFORMAT 7.4)  XE "SETFILTER" \f F SETFILTER(string filter): sets the current dynamic target filter to filter, overwriting any existing filter string.  XE "ADDFILTER" \f F ADDFILTER(string filter): adds an additional dynamic filter expression to the existing dynamic target filter (See  REF _Ref46752884 \r \h 7 for difference between dynamic and static filters). This function automatically inserts parantheses and an "and" operator such that the resulting filter expression will be true only if both existing and new added filter expressions are true.  XE "ADDSTATICFILTER" \f F ADDSTATICFILTER(string filter): adds an additional filter expression to the existing static database filter (defined by , see  REF _Ref54100850 \r \h 11.34.17). This function automatically inserts parantheses and an "and" operator such that the resulting filter expression will be true only if both existing and new added filter expressions are true. string  XE "DBOPTIONS" \f F DBOPTIONS(): returns the option string specified by the remote party using the /o() option as CGI parameter in the database path (see CGI options in  REF _Ref46896711 \r \h  \* MERGEFORMAT 7.4). string  XE "DBNAME" \f F DBNAME(): returns the name of the datastore. This might be useful for example in the vCalendar datatype to check if the vCalendar item is being used in the "tasks" or the "events" datastore. string  XE "LOCALDBNAME" \f F LOCALDBNAME(): returns the name of the local datastore as used in the target locuri specification from the remote party. This can be used in datastores with es (see  REF _Ref247356737 \r \h 11.34.1) to find out how the datastore was addressed. string  XE "REMOTEDBNAME" \f F REMOTEDBNAME(): returns the name of the remote datastore as used in the source locuri specification from the remote party. Note that the remote datastore name might be a path containing multiple elements and even CGI. timestamp  XE "STARTDATE" \f F STARTDATE(): returns the start date if a date range was set for the datastore (for example with the /dr() CGI option, see  REF _Ref46896711 \r \h 7.4). If no range was set, STARTDATE() returns EMPTY.  XE "SETSTARTDATE" \f F SETSTARTDATE(timestamp date): sets the start date (as it can also be set by the /dr() CGI option (see  REF _Ref46896711 \r \h 7.4) according to date. timestamp  XE "ENDDATE" \f F ENDDATE(): returns the end date if a date range was set for the datastore (for example with the /dr() CGI option, see  REF _Ref46896711 \r \h 7.4). If no range was set, ENDDATE () returns EMPTY.  XE "SETENDDATE" \f F SETENDDATE(timestamp date): sets the end date (as it can also be set by the /dr() CGI option (see  REF _Ref46896711 \r \h 7.4) according to date. integer  XE "NOATTACHMENTS" \f F NOATTACHMENTS(): returns TRUE if the /na GCI option (see  REF _Ref46896711 \r \h 7.4) is set.  XE "SETNOATTACHMENTS" \f F SETNOATTACHMENTS(integer flag): set the /na option (see  REF _Ref46896711 \r \h 7.4) according to flag. integer  XE "MAXITEMCOUNT" \f F MAXITEMCOUNT(): returns the number specified with the /max GCI option (see  REF _Ref46896711 \r \h 7.4) or zero if no /max option was used.  XE "SETMAXITEMCOUNT" \f F SETMAXITEMCOUNT(integer maxcount): set the the /max GCI option (see  REF _Ref46896711 \r \h 7.4) according to maxcount (0 = no item count limit). integer  XE " DEFAULTSIZELIMIT" \f F  DEFAULTSIZELIMIT(): returns the default size limit set with the /li() CGI option, (see  REF _Ref46896711 \r \h 7.4). If no size limit was set, DEFAULTSIZELIMIT() returns EMPTY. Note that individual items might have a size limit differing from the default (see SIZELIMIT and SETSIZELIMIT functions in  REF _Ref55274563 \r \h 10.5.10)  XE "SETDEFAULTSIZELIMIT" \f F SETDEFAULTSIZELIMIT(integer limit): set the the /li() CGI option (see  REF _Ref46896711 \r \h 7.4) according to limit (EMPTY = no size limit, 0 = only header information). integer  XE "DBHANDLESOPTS" \f F DBHANDLESOPTS(): This returns TRUE if the database implementation does handle the needed filtering for date range and limit options automatically. For the currently available ODBC and text based datastores, this always returns FALSE, but future implementations might be able to handle the filtering natively. integer  XE "SLOWSYNC" \f F SLOWSYNC(): returns true if session is a slow sync FORCE XE "SLOWSYNC" \f F SLOWSYNC(): can be used in (see  REF _Ref111000885 \r \h 11.34.25) to force a slow sync even if the sync engine would do a normal sync. This has the same effect as using the /slow option in the database path (see  REF _Ref46896711 \r \h 7.4). integer  XE "FIRSTTIMESYNC" \f F FIRSTTIMESYNC(): returns true if session is a first-time (slow) sync  XE "SETCONFLICTSTRATEGY" \f F SETCONFLICTSTRATEGY(string strategy): allows to define a conflict strategy for the datastore for example depending on logged in user or device. strategy must be a valid strategy name as described in  REF _Ref46908455 \r \h 11.34.10. integer  XE "ALERTCODE" \f F ALERTCODE(): returns the alert code for the current synchronisation (see SyncML standard for details). This can be useful in (see  REF _Ref111000885 \r \h 11.34.25) to determine what kind of synchronisation was requested. integer  XE "SETALERTCODE" \f F SETALERTCODE(integer alertcode): allows to set the alertcode to something different than received from the remote party in (see  REF _Ref111000885 \r \h 11.34.25). Note that doing so requires knowledge of the SyncML protocol - arbitrarily modifiying the alert code is likely to make sync sessions fail. integer READONLY(): returns true if the current sync is a read-only sync, that is, data from the remote is ignored, and the local database is only read (never written) to send updates to the remote party. Note that the initial state of this flag is determined by the tag (see  REF _Ref131305143 \r \h 11.34.4) and by the session-level SETREADONLY() function (see  REF _Ref43727925 \r \h 11.33). SETREADONLY(integer readonly): sets the readonly flag. This is useful to force a read-only sync (modifications from the remote party will be ignored) with this datastore when the remote actually requests a two-way sync in the (see  REF _Ref111000885 \r \h 11.34.25). Note that there is also a session-level version of SETREADONLY(), see  REF _Ref43727925 \r \h 11.33. integer REFRESHONLY(): returns true if the current sync is a refresh-only sync, that is, only data from the remote is received and stored, but no updates or adds are sent to the remote party. SETREFRESHONLY(integer refreshonly): sets the refreshonly flag. This is useful to force a refresh-from-remote sync when the remote actually requests a two-way sync in the (see  REF _Ref111000885 \r \h 11.34.25). Make sure that you do not clear the refreshonly flag when the remote actually requests a refresh-only sync, as this will likely make the sync session fail (the remote does not expect data coming from the server). In SyncML client configurations, additionally the following functions are available: ADDTARGETCGI(string cgi): adds the string cgi as CGI to the database path sent to the server. This can be used to add TAF expressions or proprietary server options to the base server database path. The function automatically adds a "?" delimiter between the database path before appending cgi if the delimiter is not already part of the database path. The function also checks if cgi is already part of the database path and if so, does not add it a second time. SETRECORDFILTER(string filterexpression, boolean inclusive): sets a record level filter for the alert to be sent to the server. If the session is run in SyncML DS 1.2 or later, the filter expression is sent to the server using the and tags. Otherwise, inclusive and exclusive filters are added using the /tf() and /fi() option syntax, resp. see  REF _Ref153732324 \r \h 7.5. SETDAYSRANGE(integer daysbefore, integer daysafter): sets a relative day range from daysbefore days into the past and daysafter days into the future for the alert to be sent to the server. If the session is run in SyncML DS 1.2 or later, this range is represented as a filter expression using the BEFORE and SINCE filter keywords. Otherwise, the date range is added as CGI using the /dr(-x,y) option syntax, see  REF _Ref153732324 \r \h 7.5. variant TARGETSETTING(string settingsfieldname): Only for client configurations which are based on the Synthesis SyncML client engine library, this function can be used to query certain (not all) fields of the target settings. See the  HYPERLINK "SDK_manual.pdf" SDK_manual.pdf for more information on target settings. Currently supported settingsfieldnames are: "extras", "limit1", "limit2", "remoteFilters". Others might be supported depending on the client engine library version. This is useful for example to use the limit1 and limit2 fields in the settings for user-settable date range, which can then be queried in (see  REF _Ref207634778 \r \h 11.34.26) using TARGETSETTING() and applied to the outgoing alert using SETDAYSRANGE().  XE "datastoreinitscript" \f T : script called after accessing database Contained in: Available: in PRO versions only Can contain: script Script context: datastore context Attributes: none Default: no script This script is executed just after the datastore has been (successfully) accessed. See also for details.  XE "adminreadyscript" \f T : script called when admin data (targets, maps) are read Contained in: Available: in PRO versions only Can contain: script Script context: database context Attributes: none Default: no script This script is executed when datastore related administrative data (target information, folder information, map data) has been fetched. This is is good place to implement folder specific behaviour (e.g. making a folder read-only). Unlike , the has access to the database context specific functions (such as those described in  REF _Ref153776689 \r \h 11.34.41.3 or in  REF _Ref78024414 \r \h 12.1.4 for ODBC).  XE "optionfilterscript" \f T : script executed at end of sync Contained in: Available: in PRO versions only Can contain: script Script context: database context Attributes: none Default: no script This script is called once after all operations related to a datastore in a sync session are completed. This is the script to place special application specific operations that must be done after completing sync with a datastore. Note that the syncendscript is executed at end of both successful and failing sync sessions. Unlike , the has access to the database context specific functions (such as those described in  REF _Ref153776689 \r \h 11.34.41.3 or in  REF _Ref78024414 \r \h 12.1.4 for ODBC).  XE "alertscript" \f T : script called at sync alert Contained in: Available: in PRO versions only Can contain: script Script context: datastore context Attributes: none Default: no script This script is executed when the server receives an command from the client. This is the place to install custom behaviour (like switching to refresh-from-remote only using the SETREFRESHONLY() function or update-remote only using SETREADONLY()). All script functions available in are available (see  REF _Ref55271118 \r \h 11.34.21), but not all might make sense at this stage of the sync process. Note: Don't confuse this with (see  REF _Ref207634778 \r \h 11.34.26).  XE "alertprepscript" \f T : script called before sending sync alert Contained in: within Available: in PRO version clients only Can contain: script Script context: datastore context Attributes: none Default: no script This script is executed before a client sends an to the server. This is the place to add extra parameters for the datastore sync like filter expressions (see  REF _Ref46752884 \r \h 7) or date range options (see  REF _Ref153732324 \r \h 7.5). This can be done using script functions like ADDTARGETCGI(), SETRECORDFILTER(), SETDAYSRANGE(), TARGETSETTING() Note: Don't confuse this with (see  REF _Ref111000885 \r \h 11.34.25). XE "sentitemstatusscript" \f T: script to handle status codes for sent items Contained in: or / (see text) Available: in PRO versions only Can contain: script Script context: datastore context Attributes: none Default: no script This script is executed whenever a status for a sent data item is received. Note that this script can be specified on both the datastore level (will catch status for that datastore only) or on the session level (will catch all status responses). This script must return true if it has taken all actions required to handle the status code, otherwise it should return nothing or false which will cause the engine to apply default processing for the status code. This script has access to the following special script functions: integer  XE "STATUS" \f F STATUS(): returns the current status code. See  REF _Ref47451048 \r \h 18.1 for a list of SyncML error codes.  XE "SETSTATUS" \f F SETSTATUS(integer statuscode): sets a new statuscode (this will be used by all subsequent processing of the status instead of the original status code, including the Sync engine's default processing. SETRESEND(boolean resend): This can be used to override the error case behaviour set by (see  REF _Ref153774103 \r \h 11.34.29) on a per-item basis. If resend is set to true, the item will be marked for resend in the next session. If resend is set to false, a non-OK status will cause an error and abort the sync with that datastore. Note that marking items for resend only works in datastores with (see  REF _Ref153707807 \r \h 11.34.39) switched on.  XE "ABORTDATASTORE" \f F ABORTDATASTORE(integer statuscode): aborts syncing the current datastore (but continues the sync session if it includes other datastores) and reports statuscode as the reason for aborting the sync. Note that statuscode can be 0 to abort silently.  XE "STOPADDING" \f F STOPADDING(): Stops adding more data to the remote datastore. This can be used to continue a sync after the remote party signals that its datastore has no capacity to accept further records. string  XE "SYNCOP" \f F SYNCOP(): Returns the sync operation related to the status code being processed. Possible return values are: "add", "replace", "archive+delete", "soft-delete", "delete", "copy" and "map".  XE "receiveditemstatusscript" \f T : script to handle status codes for received items Contained in: or / (see text) Available: in PRO versions only Can contain: script Script context: datastore context Attributes: none Default: no script This script is executed before sending a status commad for a received data item to the remote party. Note that this script can be specified on both the datastore level (will catch status for that datastore only) or on the session level (will catch all status responses). This script can return true if it wants to mark the status code as "regular" processing (fully ok, no workarounds applied) or falseto signal "irregular" processing. This script has access to the same special script functions as , see  REF _Ref45371286 \r \h 11.34.27.  XE "resendfailing" \f T : re-send failing items in next session Contained in: Can contain: boolean value Attributes: none Default: true If this option is set to true, items sent to the remote that receive a non-ok status will not cause the sync session to abort, but will be marked such that the items get re-sent in the next sync session. This is new functionality of version 3.0, and helps to overcome temporary failures of writing items to the remote party (such as outgoing email that can't be sent at the first attempt will not break the session, but simply re-tried in the next session). This option can be set to false to restore pre-version-3.0 behaviour. Note that resending items requires that map entries have map flags ( turned on, see  REF _Ref153707807 \r \h  \* MERGEFORMAT 11.34.39 and  REF _Ref153731855 \r \h  \* MERGEFORMAT 12.20.5).  XE "timeutc" \f T ,  XE "timestamputc" \f T : type of database timestamp Contained in: () or ( or for version 2.1 compatibility) Can contain: boolean value Attributes: none Default: false (operating system's local time) Usage: deprecated in 3.1 onwards, use (see  REF _Ref185246110 \r \h 11.34.31) instead If set to true, timestamp results returned by the database API layer (ODBC or plugin) are interpreted as UTC (former Greenwich Mean Time, GMT) and timestamps sent to the database API layer are sent in UTC. Note: when used in context of a , this setting only affects the actual accesses to this datastore - so it is possible to have different timestamp settings for different datastores. If used in context of or , the setting is used for all accesses that are not related to a particular datastore, such as reading the database time (for example see  REF _Ref153704184 \r \h 12.18).  XE "datatimezone" \f T : timezone for database timestamps Contained in: ; or Can contain: time zone specification (see  REF _Ref201668435 \r \h 5.3) Attributes: none Default: SYSTEM (operating system's local time zone) Usage: New in 3.1 onwards, use instead of deprecated and (see  REF _Ref185246112 \r \h 11.34.30) Timestamp results returned by the database API layer (ODBC or plugin) are interpreted using the time zone specified, and timestamps to be written to the database are converted to this zone before writing (except for timestamps explicitly mapped as floating using the "f" mode option in the / , see  REF _Ref47173451 \r \h 11.34.41.1). Note: when used in context of a , this setting only affects the actual accesses to this datastore - so it is possible to have different time zone settings for different datastores. If used in context of or , the setting is used for all accesses that are not related to a particular datastore, such as reading the database time (for example see  REF _Ref153704184 \r \h 12.18).  XE "userzoneoutput" \f T : output data in user zone Contained in: Can contain: boolean value Attributes: none Default: true Usage: New in 3.1 onwards If this is set to true (the default), timestamps are converted to user time zone context (see  REF _Ref185257870 \r \h 5.2) before data is converted to SyncML content formats like vCalendar. For cases where the original timezone as obtained from the database must be retained, this can be set to false. XE "datacharset" \f T: character set to be used for database strings Contained in: , or Can contain: name of character set Attributes: none Default: "ANSI" This defines the character to be used for ODBC strings: "ASCII": plain 7-bit ASCII, ANSI/ISO-8859-1 characters are converted to nearest ASCII-equivalent, for example 'ä' to 'a' etc. "ANSI": standard window character set "ISO-8859-1": ISO-8859-1 character set "UTF-8": UTF-8 character set "GB2312": Simplified Chinese standard character set. Note that this character set is not supported in all client and server versions. "CP936": Simplified Chinese Windows codepage (Multi-Byte character set). Note that this character set is not supported in all client and server versions. Note: when used in context of a , this setting only affects the actual accesses to this datastore - so it is possible to have different character sets for different datastores. If used in context of or , the setting is used for all accesses that are not related to a particular datastore. XE "datalineends" \f T: encoding of line ends within database strings Contained in: , or Can contain: name of line-end mode Attributes: none Default: "dos" This defines how line ends within strings are encoded: "dos": line ends are DOS/Windows compatible CRLF (0x0D followed by a 0x0A character) "mac": line ends are Apple Macintosh compatible CR (single 0x0D) "unix": line ends are Unix/Linux compatible LF (single 0x0A) "cstr": line ends are compatible with platform's encoding for lineends in C strings (normally 0x0A like "unix") "filemaker": line ends are encoded as single 0x0B character (which is used by the Filemaker desktop database) Note: when used in context of a , this setting only affects the actual accesses to this datastore - so it is possible to have different line ends for different datastores. If used in context of or , the setting is used for all accesses that are not related to a particular datastore. XE "updateallfields" \f T: always update all fields Contained in: Can contain: boolean value Attributes: none Default: false If this option is set to true, the server always updates all fields that are ed when updating a record. If it is set to false, the server might update only those field that have actually changed. Note that this should be set to false for efficiency reasons except if the database really does not support updating fewer than all fields.  XE "fromremoteonlysupport" \f T : Support for "one-way from remote sync" Contained in: Can contain: boolean value Attributes: none Default: off This flag determines if the datastore can perform the "one-way from remote sync" mode. This is the only sync mode that needs one (or two, if is enabled) extra timestamps to be maintained per sync target (in ODBC this is in the sync targets table, see  REF _Ref43728908 \r \h 12.20.2). Synthesis SyncML engine versions before 2.0.7.2 did not support that extra mode, so some existing installations may not have the appropriate fields in their SYNC_TARGETS tables yet. XE "synctimestampatend" \f T: How to determine "time of last sync" Contained in: Can contain: boolean value Attributes: none Default: off This flag determines how the "time of last sync" is determined. This value is very important for subsequent sync session to find out which records have been changed since last sync session. Normally, this should be left to the default (off), meaning that the "time of last sync" is the time when the sync session begins. This time is used as modification timestamp for all records touched during a synchronisation. For some (desktop) databases, it might not be possible to set modification timestamps when inserting or updating records, but those databases always assign the current time to the last-modified field. In this case, the "time of last sync" must be taken AFTER all modifications have been applied. This can be done by setting to on. Note that in ODBC based datastores, SQL statements (see  REF _Ref6030156 \r \h 12.20.2) must be formed according to this setting. Note that setting is only safe in true single-user situation. During sync, no other modifications (neither by another sync session nor by another database user) may occur!  XE "storesyncidentifiers" \f T  (or  XE "storelastsyncidentifier" \f T ): custom "time of last sync" identifier Contained in: Can contain: boolean value Attributes: none Default: off This flag is provided for plugin based datastores that don't use timestamps (or a different kind of timestamp) to determine modifications since last sync. If this flag is set to yes, a separate datastore/plugin dependent identifier is saved in the sync target administrative data. In case of ODBC based admin data, the SYNC_TARGETS table must have the appropriate fields and the SQL statements to read and write target records must be adapted accordingly (see  REF _Ref43728908 \r \h 12.20.2).  XE "resumesupport" \f T : support for resuming interrupted sync session Contained in: Can contain: boolean value Attributes: none Default: off To enable SyncML DS 1.2 Suspend & Resume feature, this flag must be set. If this flag is set, some additional data will be saved for each sync target at the end of each SyncML message processed (for servers) or at the end of the session (for clients) that allows resuming interrupted sync sessions without starting over. In case of ODBC based admin data, the SYNC_TARGETS table must have the appropriate fields and the SQL statements to read and write target records must be adapted accordingly (see  REF _Ref43728908 \r \h 12.20.2).  XE "resumeitemsupport" \f T : support for resuming half-transmitted data items after interrupted sync Contained in: Can contain: boolean value Attributes: none Default: off This flag is only meaningful if is switched on (see  REF _Ref153707807 \r \h 11.34.39). If it is set to yes, it enables resuming transfer of partially transmitted items without re-transmitting the entire item. It requires some additional data to be saved for each sync target. Especially, the already transmitted fragment of a partially transmitted item will need to be saved. This is a block of binary data of arbitrary size. A BLOB database field can be used to store this block. In case of ODBC based admin data, the SYNC_TARGETS table must have the appropriate fields and the SQL statements to read and write target records must be adapted accordingly (see  REF _Ref43728908 \r \h 12.20.2). XE "fieldmap" \f T: mapping datatype's fields to database fields Contained in: Can contain: , ,,, (ODBC only, see  REF _Ref153765172 \r \h 12.20.20) Attributes: fieldlist This tag defines how the internal fields of a datatype's field list (see  REF _Ref6030571 \r \h 10.1) are mapped to the fields in a SQL table. The "fieldlist" attribute is required and specifies the field list containing the fields to be mapped. The tag must contain a tag (see  REF _Ref47173451 \r \h 11.34.41.1 and for ODBC  REF _Ref153764303 \r \h 12.20.19) for every field that is to be mapped. In the PRO version the tag can also contain scripts to perform conversions between internal field data and database data while reading or writing. XE "map" \f T, < XE "mapredefine" \f F mapredefine>: mapping a datatype field to a database field Contained in: , (ODBC only, see  REF _Ref153765172 \r \h 12.20.20) Can contain: nothing Attributes: name, references, type, mode, size, truncate plus database API specific attributes (see  REF _Ref153764303 \r \h 12.20.19 for ODBC) This tag establishes a link between an internal field as defined in a 's tag (see  REF _Ref47173292 \r \h 10.2) and a field in the datastore's user data table (SQL database table field or plugin data field). The tag works exactly as except that the field must be already mapped before. This makes sense after using (see  REF _Ref247355579 \r \h 11.34.41.2) to create a 1:1 default mapping, and then override some mappings with . The tag has the following attributes: "name": this is the database field name of the field to be mapped "references": this is the name of a field in the specified with the "fieldlist" attribute of the enclosing (or ) or it is the name of a local variable of the database context (see script descriptions in  REF _Ref153776695 \r \h  \* MERGEFORMAT 11.34.41.3,  REF _Ref153776692 \r \h  \* MERGEFORMAT 11.34.41.4,  REF _Ref153776693 \r \h  \* MERGEFORMAT 11.34.41.5 and  REF _Ref153776694 \r \h  \* MERGEFORMAT 11.34.41.7) "type" specifies how the field should be treated when accessing it in the database. Note that most fields can just be accessed as string, even if they contain numeric data. Other types than string are only required when there is no unambiguous string representation (such as for date and time fields). The following types are supported: "string" : string field. Values are copied unmodified (except for appropriate character set and line feed conversion and truncation to the maximum field length as specified with the "size" attribute, see below). "blob" : BLOB (binary large object) field. Values are treated as opaque binary data, and are copied byte by byte without any modification (except for truncation to the maximum field length if specified with the "size" attribute, see below). "numeric" : numeric field. Values are assumed to be valid numeric strings. If not, this will cause database errors to occur, so use this type only for values that are really numeric. Empty fields will be stored as NULL "date" : date field. The referenced must be a timestamp or date value. "time" : time field. The referenced must be a timestamp or time value. "timefordate" : This special type is used when a referenced timestamp must be stored as separate date/time fields in the database. In this case, create a and a referencing the same . Note that the "date" field must be listed in the before the "timefordate" field! "timestamp" : timestamp field. "zonename" (New in 3.1): This special type is used to store time zone information from a referenced timestamp in symbolic form (zone name) in the database. Unlike "zoneoffset_xxxx" (see below), the time zone name identifies a time zone including its daylight savings rule. Therefore this is the preferred way to store time zones, as it is not dependent on the time of the year. Note that the "time" or "timestamp" field must be listed in the before the "zonename" field! For general information on time zone handling please refer to chapter  REF _Ref185238094 \r \h 5. "zoneoffset_hours", "zoneoffset_mins", "zoneoffset_secs" : These are deprecated in versions 3.1 onwards of the SyncML engine, but still available for compatibility. They should no longer be used as a mere offset from UTC cannot specify a time zone completely. Use the "zonename" type instead (see above). Note that the "time" or "timestamp" field must be listed in the before the "zoneoffset_xxx" field! For general information on time zone handling please refer to chapter  REF _Ref185238094 \r \h 5. "lineartime" : integer representation of a timestamp in the SyncML engine's internal time format which is milliseconds elapsed since January 1st, 4712 BC, midnight. "lineardate" : integer representation of a date in the SyncML engine's internal date format which is days elapsed since January 1st, 4712 BC. "unixtime_s" : integer representation of a timestamp in Unix Epoch Time, which is seconds elapsed since January 1st, 1970, midnight. "unixtime_ms" : Same as unixtime_s, but in milliseconds "unixtime_us" : Same as unixtime_s, but in microseconds "unixdate_s" : integer representation of a date-only value in Unix Epoch Time, which is seconds elapsed since January 1st, 1970. "unixdate_ms" : Same as unixdate_s, but in milliseconds "unixdate_us" : Same as unixdate_s, but in microseconds "nsdate" : integer representation of a timestamp in Apple Cocoa NSDate scale, which is seconds elapsed since the "reference Date" of January 1st, 2001, midnight. "mode": this optional attribute specifies when the database field being mapped is used. In ODBC datastores this influences the field/value lists created by the %v,%V,%N placeholders, see  REF _Ref47173394 \r \h  \* MERGEFORMAT 12.1.3). The default for "mode" is "rw" if not specified explicitly. Mode can consist of one or multiple of the following flag characters: "r": the field is included when reading values from the database (in ODBC usually when executing a SELECT statement). "i": the field is included when inserting new records into the database (in ODBC usually executing an INSERT statement) "u": the field is included when updating existing records in the database (in ODBC usually executing an UPDATE statement) "w": same as specifying "i" and "u" together ("iu") - the field is included when writing to the database. "p": This flag means that the field should not be literally mapped, but inserted as a parameter. BLOBs are always inserted as parameters (even without the "p" flag), but for long strigs it might make sense as well. For ODBC, "p" means using the ODBC parameter mechanism; for plugin datastores, it causes the BLOBID-mechanism to be used (see SDK docs). "f" (New in 3.1): This flag has only a meaning for time and timestamp fields. It means that the database fields represents the time as a floating (time zone independent) value rather than in a fixed time zone context (as specified with , see  REF _Ref185246110 \r \h 11.34.31). This is useful in combination with the "zonename" field type, see above. For general information on time zone handling please refer to chapter  REF _Ref185238094 \r \h 5. Note: do not set the "f" flag in a that maps a timestamp's timezone name to a DB field. "x" (New in 3.1): This flag indicates that the value of the field directly referenced (with the "references" attribute, see above) must be kept for later finalisation using (see  REF _Ref207618734 \r \h 11.34.41.6 for details). This is useful to create links between records in relational setups. "size": this optional attribute specifies a maximum number of characters for string fields. It should always be set to avoid database errors when a client has longer strings than the database can store. Note for ODBC datastores especially that size is used to specify the maximum column size for binding SQL parameters (see "p" mode flag above) - in case you get 'HY104' SQL state errors, this is most likely caused by an invalid column size value. "truncate": this attribute can be set to "no" (default is "yes") if the data field must not be truncated. This is usually the case for binary data, where truncation would mean corrupting the data. For string data, truncation is usually acceptable. If "truncate" is set to "no", this signals to the remote party that it should not send truncated data for this field. Note that this mechanism is a new feature of SyncML DS 1.2 and therefore does not work with 1.1 and 1.0 implementations. "set_no":This optional attribute (which defaults to 0) can be used to assign this mapping entry to a numbered set of mappings. The default set is 0 and will normally be used for accessing the database. For ODBC, s that have a set_no other than zero can be used in SQL statements that are prefixed with the %GO(set_no) sequence. See  REF _Ref47173394 \r \h  \* MERGEFORMAT 12.1.3 for details. In Plugin datastores, set_no should always be 0. Other attributes specific to the datastore type: ODBC has additional attributes for , see  REF _Ref153764303 \r \h  \* MERGEFORMAT 12.20.19. Example (fieldmap for a mimimalistic name/phone number + photo (new for 3.0) datastore) XE "automap" \f T: auto-map internal to DB fields Contained in: Attributes: fieldlist, indexasname This tag automatically maps all fields in the fieldlist to database fields. The database fields are assumed to have the same names as the internal fields in the fieldlist (unless indexasname is set to true, see below). All fields are mapped as "string", except for timestamps which are mapped as "timestamp". Note that (see  REF _Ref47173451 \r \h 11.34.41.1) can be used after to change some of the automapped fields when needed. The "fieldlist" attribute is required and specifies the field list containing the fields to be mapped. The "indexasname" attribute can be set to "true" to make the database field "names" to be the numeric index of the field in the fieldlist (0,1,2….n).  XE "initscript" \f T : initialize accessing database Contained in: or (SQL only, see  REF _Ref153765172 \r \h 12.20.20) Available: in PRO versions only Can contain: script returning boolean value Script context: database context Attributes: none Default: no script If the tag is directly contained in the tag (see  REF _Ref47172480 \r \h 11.34.41), this script is executed once before the SyncML engine starts accessing the database and can be used to declare and initialize variables in the database context. ODBC only: If the tag is contained in an tag (see  REF _Ref47864390 \r \h 12.20.20 for details), the script is executed once every time before the SyncML engine starts accessing the detail records for a master record (which is always after the master record is read or written). If the script returns false, the SyncML engine will not read or write detail records. This is useful if the master record contains an indication if there are detail records at all which can be tested in the to increase performance by avoiding unneeded SQL queries. The of an can access all fields of the item being read or written - as the arrays are always read or written after the master record is read or written, the fields mapped in the are already read from the database when is called for an . In ODBC datastores, the has access to the SQL execution functions described in  REF _Ref78024414 \r \h 12.1.4 and the following functions specific to the database context: integer  XE "ARRAYINDEX" \f F ARRAYINDEX(): ODBC only: Returns the current array index (zero based) when reading or writing an array. In the (see  REF _Ref153776724 \r \h 11.34.41.7) the return value is the number of array records read or written. string  XE "PARENTKEY" \f F PARENTKEY(): Returns the key (localID) of the master record (same value as %k represents in SQL queries, see  REF _Ref47173394 \r \h 12.1.3) string  XE "NEWKEY" \f F NEWKEY(): Returns a new key (localID) for the master data table (same value as %X represents in SQL queries, see  REF _Ref47173394 \r \h 12.1.3). Note that this can only be used when is false, that is, when keys can be generated independent from actually inserting records into the master data table. string  XE "LASTKEY" \f F LASTKEY(): Returns the last key generated for the master data table (same value as %X represents in SQL queries, see  REF _Ref47173394 \r \h 12.1.3). integer  XE "WRITING" \f F WRITING(): Returns true if script is called while writing to the database, returns false if script is called while reading from the database. integer  XE "WRITING" \f F INSERTING(): Returns true if script is called while inserting new records to the database, returns false if script is called while reading or updating existing record in the database. Note that even while UPDATEing a record, it's detail records may get INSERTed.  XE "SETSQLFILTER" \f F SETSQLFILTER(string sqlfilter): ODBC only: This can be used to specify a WHERE clause expression which is then used as part of the %AF and %WF placeholders, see  REF _Ref47173394 \r \h 12.1.3. string  XE "LOGSUBST" \f F LOGSUBST(string logtext): Returns logtext with all placeholders which are valid in (see  REF _Ref46754571 \r \h 12.19) substituted with the appropriate value.  XE "afterreadscript" \f T : post-process item read from database Contained in: or (ODBC only, see  REF _Ref153765172 \r \h 12.20.20) Available: in PRO versions only Can contain: script Script context: database context Attributes: none Default: no script This script is called after a database record has been read according to the definitions into the internal item's fields (as defined in the , see  REF _Ref42589436 \r \h 10.1) or local variables of the database context. Note that for ODBC, the sync engine may call before or after reading all detail records from s (see  REF _Ref47865711 \r \h 12.20.20), therefore any scripting that refers to fields should not be placed in the (but in the of the array). This script has access to all fields of the data item just read and may examine and change them before the data is processed any further. This script is where custom data conversions between data in the database and contents can be implemented. To do that, the fields that need special conversion are mapped (with , see  REF _Ref47173451 \r \h 11.34.41.1) to a local variable of the database context. Then, the reads the value from that variable and stores it in the actual . The has access to the database context specific functions described in  REF _Ref153776799 \r \h 11.34.41.3.  XE "beforewritescript" \f T : prepare writing item to database Contained in: or (ODBC only, see  REF _Ref153765172 \r \h 12.20.20) Available: in PRO versions only Can contain: script Script context: database context Attributes: none Default: no script This script is called before starting to write a database record and has access to all fields of the data item that will be written and may examine and change them before the data is actually written to the database. This script is where custom data conversions between data in the database and contents can be implemented. To do that, the fields that need special conversion are mapped (with , see  REF _Ref47173451 \r \h 11.34.41.1) to a local variable of the database context. Then, the reads the value from the and stores the converted value in that local variable. As the local variable is ed to a database column, the converted value will be stored in the database. The has access to the database context specific functions described in  REF _Ref153776799 \r \h 11.34.41.3. ODBC only: when used in an (see  REF _Ref47864390 \r \h 12.20.20), can return false to stop writing detail records explicitly (before any of the implicit criteria - maxrepeat, sizefrom and all-empty data - stops writing detail records). The following example shows a , a and a implementing a custom conversion between priority values in the database ("low", "normal", "high") and priority values needed for the vCalendar (3,2,1): 2) PRIORITY_TEXT="LOW"; ELSE IF (PRIORITY<2) PRIORITY_TEXT="HIGH"; ELSE PRIORITY_TEXT="NORMAL"; ]]>  XE "finalisationscript" \f T : finalize written items Contained in: Available: new in 3.1, in PRO versions only Can contain: script Script context: database context Attributes: none Default: no script This is a special script that is called at the end of all user data accesses, right before (see  REF _Ref153776694 \r \h 11.34.41.7). It is called once for every item written to the database (inserted or updated), but only if at least one of the field s (see  REF _Ref47173451 \r \h 11.34.41.1) has a "x" flag in its mode attribute. In each call, the script has access to an item (like in the  REF _Ref153776693 \r \h 11.34.41.5), but this item is empty except for the fields directly referenced in a which has a "x" flag set in its mode attribute. This mechanism allows to create inter-item relational links, for example when one incoming item references another (such as tasks and subtasks) by a string identifier (like an UID), but in the database this relation should be stored as a direct relational link from one table referencing another table's (or the same table's) identity key column. In such a case, the key of the to-be-referenced item may not be known when the referencing item is written to the database (because the referenced item might be new in this session and thus only added later in the session's progress). By setting the "x" flag in the (see  REF _Ref47173451 \r \h 11.34.41.1) referencing the string identfier field (say, an UID), this means that this field's value is saved until the end of the sync session, and will be available to the . On the other hand, fields in the item that don't have a "x" mode flag in their will not be included in the item the can access. This is to limit the amount of data that must be kept in memory down to what is really needed at finalisation (most data content does not need to be kept, because it can be stored right away when the item is arriving during the sync session). If no item has the "x" flag set, the is not called at all. The has access to the database context specific functions described in  REF _Ref153776799 \r \h 11.34.41.3.  XE "finishscript" \f T : finish access to database Contained in: or (ODBC only, see  REF _Ref153765172 \r \h 12.20.20) Available: in PRO versions only Can contain: script Script context: database context Attributes: none Default: no script If the tag is directly contained in the tag (see  REF _Ref47172480 \r \h 11.34.41), this script is executed once after the SyncML engine has accessed the database and can be used to do some cleanup work in the database context. See also for details. If the tag is contained in an tag, it is called once after reading or writing all records of an is complete. It can be used for example to store the number of elements read (ARRAYINDEX() function, see  REF _Ref153776799 \r \h 11.34.41.3) in a . The has access to the database context specific functions described in  REF _Ref153776799 \r \h 11.34.41.3.  XE "superdatastore" \f T : combined datastore definition Contained in: , Can contain: Attributes: name Superdatastores are a very simple to use concept to combine two or more datastore into one "superdatastore" that can be accessed by the remote party as a single datastore. Most obvious use of a superdatastore is in any SyncML server that supports events and tasks. Some SyncML clients (mostly those based on Symbian OS, like Nokia9210, P800 etc.) do not access events and tasks as separate entieties, but as a single "calendar" datastore. With superdatastores, creating this "calendar" data store is as easy as grouping the existing events and tasks datastores using a tag. A superdatastore must have a name attribute, which specifies the name under which the datastore will be accessible from the SyncML client (such as "calendar" for the combined events/tasks). A must contain one or multiple tags (see  REF _Ref47260717 \r \h 11.35.1) to specifiy which datastores it groups together to form a superdatastore. Note that the grouped datastores must be defined in the configuration file before the tag. The following example shows a typical "calendar" superdatastore, grouping "events" and "tasks" together: F.KIND:=EVENT e F.KIND:=TODO t  XE "contains" \f T : Include a datastore in a superdatastore Contained in: Can contain: , Attributes: datastore This tag is used to include the datastore specified with the datastore attribute into a superdatastore.  XE "dispatchfilter" \f T : filter to direct incoming items Contained in: Can contain: filter expression (see  REF _Ref46752884 \r \h 7) Attributes: none This filter must be specified to allow the SyncML engine to dispatch incoming data items to the correct datastore within the superdatastore. In case of the event/task datastore, the filter must check if the incoming item is a vEVENT (for the s of all the contained datastores are checked to see which contained datastore can handle it. When an item is sent to the remote party from the superdatastore, the is used in make-pass mode (see  REF _Ref47262189 \r \h 7.1) to make sure the outgoing item meets the criteria set by the filter for incoming items.  XE "guidprefix" \f T : prefix for item ID Contained in: Can contain: string (normally only one character) Attributes: none Each in a must specify a different . This string (single character recommended, more only if absolutely needed) is used as a prefix to the contained datastore's item IDs to form an ID that is unique within the entire superdatastore and allows the SyncML engine to find the correct datastore from the ID. XE "remoterule" \f T: special rules for specific remotes Contained in: , Can contain: see below Attributes: name Sometimes it is desirable to treat specific remote devices different from others. A common case is when experiencing compatibility problems with a client. Synthesis Sync Server provides the config option to specify rules for certain clients. has the following attributes: "name": This optional attribute is used to specify a name for the rule. The name can be used to check in scripts (PRO version only) which (if any) rule is active using the REMOTERULENAME() script function. The name can also be used to define device-dependent datatypes using datastore's rulematch="xxx" attribute in (see  REF _Ref166648484 \r \h 11.34.12) and in MIME-DIR based datatypes to define properties depending on a certain remote rule (see  REF _Ref73442286 \r \h 10.3.3) A or tag can contain any number of tags, one for each device (or set of devices) that need special treatment. A tag contains none, one or more tags to identify the device(s), and one or more options that control the special behaviour: XE "finalrule" \f T Contained in: Can contain: boolean value Attributes: none Default: no Remote Rules are searched in the order of their definition. By default, the first rule that matches will be applied and no more rules (that eventually would match as well) will be searched. This option can be set in a remoterule to have the server continue searching for more matching rules after applying the rule. device identification tags for Contained in: Can contain: text Attributes: none The following tags are available for matching devices: XE "manufacturer" \f T: device manufacturer name XE "model" \f T: device model name XE "oem" \f T: OEM XE "firmware" \f T: firmware version string XE "software" \f T: software version string XE "hardware" \f T: hardware version string XE "deviceid" \f T: device ID (this should be unique, so this can be used to make a rule for one single specific device) XE "devicetype" \f T: SyncML device type If all of these tags appearing in a match with the connecting remote device, the rule is applied. Note that , and might contain wildcards (* and ?). Note that default rules can be specified that is applied to any device by not specifying any of the device identification tags. As rules are searched in the order of their definition, such a "catch all" rule must either: be defined as the last remoterule (and will be applied to all devices not handled by another rule) or it must have a no special option (see ) to allow subsequent rules to be processed (thus applying the settings to all devices, even those which are caught by another rule)  XE "descriptivename" \f T  Contained in: Can contain: text Attributes: none This option allows to set a more descriptive name for the device than what the device information provides (especially old devices do not even include the phone model name there). The descriptive name will be used when generating activity logs, see  REF _Ref47169796 \r \h 11.31 and  REF _Ref46754571 \r \h 12.19. XE "limitedfieldlengths" \f T: device has short fields Contained in: Can contain: boolean value Attributes: none If this option is set in a remoterule, it means that the device has limited field lengths, but does not identify them in the device information. This is the case for example with the T39m mobile phone. Without a special rule for this device (contained in all sample config files), the limited field lengths would not be detected by the server and long strings could get lost during sync. Example (to switch on limited field length handling for the Ericsson T39m): Ericsson R1A yes XE "noemptyproperties" \f T: do not send empty properties Contained in: Can contain: boolean value Attributes: none Default: off If this option is set in a remoterule, the vCard/vCalendar (MIME-DIR) generator will suppress sending properties with no value. This is because some clients do have problems when encountering empty properties in a vCard or vCalendar. Normally, this option is not required. XE "updateclientinslowsync" \f T: update client records during slowsync Contained in: or (settings in are defaults for sessions without a remote rule applied or with a remote rule applied that does not specify a value for this particular option) Can contain: boolean value Attributes: none Default: off If this option is set in a remoterule, the SyncML server will try to update client records with server data if comparison shows that the server has additional data that the client does not have during non-first time slow sync. Note that this updating always takes place in first-time sync, regardless of this options's setting. It is off by default because many clients cannot store some data but also cannot inform the server what they can store exactly, so turning this option on will cause much unneeded client updates at slow sync. For clients that store everything they report in devinf however, this feature can be switched on resulting in better data consistency after a slow sync. See also corresponding function in  REF _Ref43008774 \r \h 6.14.6.  XE "updateserverinslowsync" \f T : update server records during slowsync Contained in: or (settings in are defaults for sessions without a remote rule applied or with a remote rule applied that does not specify a value for this particular option) Can contain: boolean value Attributes: none Default: off If this option is set in a remoterule, the SyncML server will try to update server records with client data if comparison shows that the client has additional data that the server does not have during non-first time slow sync. Note that this updating always takes place in first-time sync, regardless of this options's setting. It is off by default because differences in client and server database layouts often cause uneeded updates which will cause other clients to be updated on the next sync as well. For clients that store everything they report in devinf however, this feature can be switched on resulting in better data consistency after a slow sync. See also corresponding function in  REF _Ref43008774 \r \h 6.14.6. XE "noreplaceinslowsync" \f T: never update client records during slowsync Contained in: Can contain: boolean value Attributes: none Default: off If this option is set in a remoterule, the SyncML server will never send a REPLACE command to the client during slow sync. This is for clients that cannot handle replace command in slow sync (some older SyncML clients had problems with this) - this option should be set for those clients only. Note that this overrides (see  REF _Ref45001933 \r \h 11.36.6) as it effectively blocks any updates during slow-sync, including first-time sync.  XE "ignoredevinfmaxsize" \f T : ignore maximum field size reported in client's devInf Contained in: Can contain: boolean value Attributes: none Default: off If this option is set in a remoterule, the SyncML server will ignore the maximum field size reported by the client in it's devInf. This is needed for some DS 1.2 clients which report wrong field sizes, especially a way too low value (like 256 bytes) for the PHOTO field in contacts. This would cause that the server can never send a photo to these clients if it would respect the maximum field size. So for these clients, should be set in the appropriate remote rule.  XE "dspathindevinf" \f T ,  XE "dscgiindevinf" \f T : how to show datastore name in devInf sent to client. Contained in: Can contain: boolean values Attributes: none Default: true (for both options) These options can be set to true or false in a remoterule to control a special workaround which is normally active for all clients as follows: If a client starts a sync for a datastore using not only the datastore name alone (like "contacts"), but includes a subfolder path (like in "contacts/private") or some CGI filters (like in "contacts/private?CATEGORY&iCON;Family"), and then queries devInf, the server by default puts the entire string as used by the client to address the datastore as the datastore name. This is because many phone clients will fail when the devInf does not fully match the string sent. More elaborate clients will accept both the full string or only the datastore's name. In case a client does not accept the full string, can be set to false to suppress the CGI part, and to suppress all but the datastore's name. These are highly technical and only needed in exotic cases. XE "allowmessageretries" \f T: allow client to send the same message twice Contained in: or (settings in are defaults for sessions without a remote rule applied or with a remote rule applied that does not specify a value for this particular option) Can contain: boolean value Attributes: none Default: off This is a highly technical setting. Some clients try to re-send SyncML messages when the answer from the server does not reach the client (for example, on unstable connections). Normally, the server would reject this. Setting this option makes the server accept re-sent messages - however there is no guarantee that reprocessing a message is possible in all contexts.  XE "completefromclientonly" \f T : allow client to send the same message twice Contained in: or (settings in are defaults for sessions without a remote rule applied or with a remote rule applied that does not specify a value for this particular option) Can contain: boolean value Attributes: none Default: no This is a compatibility settings for clients that expect a from-client-only session to work exactly like any other sync type, that is, include a (empty) from the server to the client and a phase. To conform to the standard, this option must be disabled.  XE "forcelocaltime" \f T : always send time information as localtime Contained in: Can contain: boolean value Attributes: none If this option is set in a remoterule, time information sent to the remote party is always specified in local time. Many SyncML clients with bad time zone implementation need that this flag is set in order to avoid time shifts. Note that with SyncML 1.1.1 conformant devices this option is not needed as the device reports wether it supports UTC or not. See also corresponding function in  REF _Ref43008774 \r \h 6.14.6.  XE "forceutc" \f T : always send time information as localtime Contained in: Can contain: boolean value Attributes: none If this option is set in a remoterule, time information sent to the remote party is always specified in UTC. Note that this is the default case for SyncML 1.0, but with SyncML 1.1.1 conformant devices this option is not needed as the device reports wether it supports UTC or not. See also corresponding function in  REF _Ref43008774 \r \h 6.14.6.  XE "treataslocaltime" \f T : always treat received information as localtime Contained in: Can contain: boolean value Attributes: none If this option is set in a remoterule, time information received from the remote party is always interpreted as localtime, even if it looks as if it was UTC ("Z" suffix). This is needed for some Symbian based clients (P800) which send local time suffixed with a "Z" which would make the receiver interpret these as UTC if this option is not set. See also corresponding function in  REF _Ref43008774 \r \h 6.14.6.  XE "treatasutc" \f T : always treat received information as UTC Contained in: Can contain: boolean value Attributes: none If this option is set in a remoterule, time information received from the remote party is always interpreted as UTC, even if it looks as if it was local time (no "Z" suffix). This is needed for some Nokia Series 80 based clients (9500, 9300) which send UTC time without the "Z" suffix which would make the receiver interpret these as localtime if this option is not set. See also corresponding function in  REF _Ref43008774 \r \h 6.14.6.  XE "nocontentfolding" \f T : prevent folding long lines Contained in: Can contain: boolean value Attributes: none If this option is set in a remoterule, lines longer than 72 characters in MIME-DIR properties are not folded into multiple lines as requested by the MIME-DIR standard, but transferred as a single, long line. This is for buggy SyncML client implementation that crash or misbehave when processing folded lines.  XE "autoenddateinclusive" \f T : end date for allday events inclusive Contained in: Can contain: boolean value Attributes: none If this option is set in a remoterule, date values with conversion mode "autoenddate" (see  REF _Ref182995906 \r \h 10.3.4).will be rendered as 23:59:59 of the previous day in old formats like vCalendar 1.0. If it is not set, "autoenddate"s will be rendered as 0:00 of the next day (which usually is the first day not included in the all-day event when "autoenddate" is used for DTEND properties). Note that there is a session-level setting for this option (see  REF _Ref231890048 \r \h 11.23)  XE "outputcharset" \f T : set default output character set Contained in: Can contain: character set name (choices see  REF _Ref153700641 \r \h 11.34.33) Attributes: none This optioncan be set in a remote rule to use a non-default character set for output formats, such as in vCard or vCalendar. Usually, the character set in SyncML is UTF-8. However there are buggy SyncML client implementations that misbehave on UTF-8 strings, but work for example with ANSI charset.  XE " inputcharset " \f T : set default input character set Contained in: Can contain: character set name (choices see  REF _Ref153700641 \r \h 11.34.33) Attributes: none This optioncan be set in a remote rule to use a non-default character set for interpreting input formats when these do not implicitly specify a character set, such as in vCard. Usually, the character set in SyncML is UTF-8. However there are buggy SyncML client implementations that send data e.g. with ANSI charset.  XE "legacymode" \f T ,  XE "lenientmode" \f T : use relaxed conformance modes Contained in: Can contain: boolean value Attributes: none These options can be set for remote rules that handle buggy and ill-behaving SyncML implementations: If is set, the SyncML engine will use different data types (usually old vCard 2.1 and vCalendar 1.0 instead of modern MIME-DIR, but this is configurable, see  REF _Ref166648484 \r \h 11.34.12). If is set, the SyncML engine will be more tolerant to certain types of non-conformant behaviour. Especially, with servers which do not handle client side anchors correctly, can disable client side anchor comparison. XE "rejectstatus" \f T: reject sync with device Contained in: Can contain: SyncML status code Attributes: none If this option is set in a remoterule, it will abort any attempt to synchronize with the specified status code. This is an option which can be used to prevent sync with some specific type of client completely (for example if a client is known to have bugs that could affect data integrity).  XE "requestmaxtime" \f T : max time for request processing Contained in: Can contain: max duration (in seconds) of a single request processing Attributes: none This can be used to override the session-default for maximum request processing time (see  REF _Ref70164511 \r \h 11.3 for details about limiting request time processing) - for example if a device is known to be especially impatient and timing out quickly.  XE "rulescript" \f T : script to execute if rule applies Contained in: Available: in PRO versions only Can contain: script (without variable declarations!) Script context: session context Attributes: none Default: no script This script is executed when the remote rule is applied to the session. It can be used to assign values to variables in the session context, which then can be used to control device-specific behaviour in all other scripts (using the SESSIONVAR built-in functions, see  REF _Ref43008774 \r \h 6.14.6). Note: it is not allowed to declare variables in - all variables to be accessed must be declared in the (see  REF _Ref69047370 \r \h 11.12). XE "server type=odbc" \f T XE "server type="sql"" \f T ,  XE "client type=odbc" \f T  XE "client type="sql"" \f T : SQL/ODBC based Server or Client Config Contained in: Can contain: tags described in chapters  REF _Ref47164085 \r \h 12 (see also  REF _Ref47164079 \r \h 11, and  REF _Ref90895285 \r \h 16 specifically for clients) Attributes: type="sql" (or as an alias for backward compatibility: type="odbc") This is where Synthesis Sync Server can be configured to work with almost any existing SQL database. It requires firm knowledge about SQL, your target database system and your database layout to do these changes successfully. Please refer to the sample configuration available in the product distribution package to see complete configurations for different types of SQL databases. Example: SQL Statement processing In the 1.0.5 version of the Synthesis SyncML engine, SQL statements were generated by the server automatically from a few pieces of information in the config. While this was convenient for database layouts that resembled our standard sample layout, it was not flexible enough to adapt to any database. So since version 1.0.8, we have changed the basic mechanism how SQL statements are generated and processed: All SQL statements used to access the database are now fully customizable The engine provides a number of placeholder sequences (a % sign followed by one or multiple characters) that are replaced by variable data when the statement is executed. In most tags, where a SQL statement is expected, the engine also allows specifying multiple statements separated by the special sequence %GO For backward compatibility, the engine still allows using the 1.0.5-style configuration. However, for new projects, we strongly recommend using the new directives. The old style configuration might get unavailable in a future version of the Synthesis SyncML engine. In the following paragraphs, all old-style configuration tags are marked as such and mention which new tag should be used as a replacement. The following paragraphs describe all the placeholder sequences that can be generally used in SQL statements in the configuration. There are additional placeholders that are only valid for specific SQL statemements (such as , see  REF _Ref46754571 \r \h 12.19); those are described with the statement they belong to. Note that placeholder for strings always only represent the value, but not the eventually required quoting characters around the string value. This means that when using a placeholder that represents a string value in an SQL statement, the placeholder must be enclosed in quotes itself. Placeholders for all SQL statements %u represents the current userkey. The userkeyis obtained with the statement (see  REF _Ref43727921 \r \h 12.16) and/or using the SETUSERKEY() script function in (see  REF _Ref43727925 \r \h 11.33) or (see  REF _Ref43727928 \r \h 12.17). Note that the userkey has a meaningful value only after a successful login. %d represents the current devicekey. The devicekeyis obtained with the statement (see  REF _Ref43728215 \r \h 12.14) and/or using the SETDEVICEKEY() script function in (see  REF _Ref43727925 \r \h 11.33) or (see  REF _Ref43727928 \r \h 12.17). %C PRO version only: represents the domain, which can be set in in (see  REF _Ref43727925 \r \h 11.33) or (see  REF _Ref43727928 \r \h 12.17) with the SETDOMAIN() script function. %sv(var) PRO version only: represents the value of the session context variable with the name var. Note that this works like the built-in function SESSIONVAR(), see  REF _Ref43728461 \r \h 6.14.6. Note also that the %sv() placeholder simply represents the text string in the session variable as-is. If you need to insert timestamps or strings containing non-ASCII-characters, the contents of the session variable should be generated using the DBLITERAL() function, see  REF _Ref78024414 \r \h 12.1.4. %p(mode,field_or_var [,dbfieldtype[,colsize]]) This is used to insert SQL parameters into a statement (normally a ODBC {call ...} statement to a stored procedure). mode can be "i" (for input-only parameters), "o" (for output-only parameters) or "io" for (input-output parameters). field_or_var is the name of an internal (from the datatype's , see  REF _Ref42589436 \r \h 10.1) or script variable to be used for the parameter's value. The optional dbfieldtype must be the name of a database field type (same values as for "type" attribute in , see  REF _Ref47173451 \r \h 11.34.41.1) - if not specified, dbfieldtype defaults to "string". The optional colsize can be used to explicitly specify the column size for the parameter. Note: Make sure not to add extra spaces within the paranthesis, only the needed parameters and the separating commas! Placeholders for SQL statements within %GO This separates two SQL statements that need to be executed in sequence. Note that only the last SQL statement's result is evaluated (in case the SQL statement needs to return data at all). %f represents the current folderkey. The folderkey is obtained with the statement (see  REF _Ref42943895 \r \h 12.20.1). Note that the folderkey has a meaningful value only after a successful login. %t represents the current targetkey. The targetkey is obtained with the statement (see  REF _Ref43728908 \r \h 12.20.2) %X represents a new record ID. Note that this only works if there is a method to create new IDs before actually inserting records (meaning that must be false and there must be a statement or a set - see  REF _Ref46750086 \r \h 12.20.18) %x represents the most recently generated record ID. This is especially useful in layouts with one master record and several detail records that need to be linked to the master record by ID. Placeholders for SQL data access statements within These placeholders are valid for all statements that access actual data records. %GO(set_no) this special form of %GO can be used in front of any SQL statement. It modifies the operation of %N, %aN, %V, %aV, %v and %av (see below) as follows: From the list of mapped fields (see ,  REF _Ref47173451 \r \h 11.34.41.1) only those will be included that have a corresponding set_no. The default set_no is 0 for all entries that do not specifiy the set_no attribute. This allows for example to execute database update in multiple parts, each using a different SQL statement with a different set_no and therefore different fields. %k represents the data key (local ID) of the master record inserted. Note that this is not available when inserting new records when is true (as the local ID is only known after insert has taken place). %pkos represents a string-type output parameter that receives the data key (local ID) of the record inserted. This is useful if inserting is not done with INSERT, but using a stored procedure which returns the generated ID as an SQL output Parameter. %pkoi same as %pkos, but for integer-type output parameters. %N represents the database field list for a SELECT or an INSERT statement. For data writing, the list will only contain the fields which need to be written. %aN same as %N, but list contains all mapped fields, even if they do not need to be changed. %V represents the fieldname = value pair list for an UPDATE statement. The list will only contain the fields/values which need to be updated. Note that the values might be represented as literals (normally) but als as ODBC parameters (for fields where no literal representation exists, such as BLOBs). %aV same as %V, but list contains all mapped fields, even if they do not need to be updated. %v represents the list of values for an INSERT statement's VALUE part, matching the field names generated with %N. %av represents the list of values for an INSERT statement's VALUE part, matching the field names generated with %aN. (Note that in servers before 2.1.1.7 there was a bug that requires to write "%av(" instead of "%av" ). %d([opts]fieldname,dbfieldtype) or %d([opts]fieldname#arrindex,dbfieldtype) represents the value of an internal field (from the datatype's , see  REF _Ref42589436 \r \h 10.1) or context variable contents (see  REF _Ref42672298 \r \h 6.9.1) named fieldname, where opts can be "l" for lowercase, "u" for uppercase and "a" for ASCII-only. If the field is an array field, the second form allows accessing the arrindex-1 th element from the array. dbfieldtype is optional and specifies how to format the field for the database (same values as for "type" attribute in , see  REF _Ref47173451 \r \h 11.34.41.1) - if not specified, dbfieldtype defaults to "numeric" (which means that the value of the field is inserted 1:1 into the SQL without surrounding quotes). This is to be compatible with the behaviour of %d in versions before 2.1.1.15, where the dbfieldtype parameter did not yet exist, and %d was often used inside quotes to insert string values. Note: Make sure not to add extra spaces within the paranthesis, only the needed parameters and the separating commas! %S represents the number of bytes (not necessarily equal to the number of characters for character sets with multi-byte characters such as UTF-8) of all strings in a writing statement. This might be useful for tracking database space requirements. %dM,%tM,%M represents the date (%dM), time (%tM) or datetimestamp (%M) of the last modification of the record. Note that for a 100% multi-user SyncML server, the SyncML server must be able to explicitly set the modification date for all records it writes (as all modifications of one sync session should have exactly the same date). This is only important if it is possible that records are being changed on the server while a sync session is in progress. %AF this expands either to an empty string or to a WHERE clause condition preceeded by an AND. The condition is derived from the active filter settings (see  REF _Ref46752884 \r \h 7). This placeholders can be used in SELECT statements that already have a WHERE clause, so the WHERE conditions will be extended with the filter conditions if there are any. Note that automatic conversion from filter settings to an SQL WHERE clause might not work in all cases. Therefore, the ability to filter at the DB level using %AF and %WF is disabled by default. This will cause the filters to be applied to the data after fetching it - which is less efficient but works in all cases. Set to true (see  REF _Ref69052620 \r \h 12.20.9) to enable filtering at the database level. %WF this is similar to %AF, but instead of AND, a WHERE is inserted if there is a filter condition at all. This placeholders can be used in SELECT statements that do not have a WHERE clause, so a WHERE clause will be added only when there are filter conditions (and , see  REF _Ref69052620 \r \h 12.20.9, is true). Executing SQL statements from scripts In PRO versions of the SyncML server and client, it is also possible to programmatically execute arbitrary SQL statements. This is especially useful for implementing special multi-step login procedures or similar tasks. The following SQL processing script functions are available in the (see  REF _Ref43727925 \r \h 11.33), the (see  REF _Ref43727928 \r \h 12.17) and all scripts in the SQL datastore context (e.g. , see  REF _Ref153776799 \r \h 11.34.41.3). string  XE "DBLITERAL" \f F DBLITERAL(variant value, string dbfieldtype): This is used to convert a value into a string that is suitable as literal value in SQL statements to be sent to the database, as required for example in SETSQLFILTER(). dbfieldtype specifies the database field type (as in "type" attribute of , see  REF _Ref47173451 \r \h 11.34.41.1). integer  XE "SQLEXECUTE" \f F SQLEXECUTE(string sql): This can be used to execute a SQL statement. Note that the statement is executed in a transaction context global to all datastores. Make sure that you use SQLCOMMIT or SQLROLLBACK to avoid unfinished transactions. Returns 0 if statement executed ok, or a non-zero ODBC error code in case of failure. integer  XE "SQLFETCHROW" \f F SQLFETCHROW(): Fetches the next row from a result set of a preceeding SQLEXECUTE call. If no (more) rows are available, SQLFETCHROW returns 0, otherwise it returns 1. integer  XE "SQLGETCOLUMN" \f F SQLGETCOLUMN(integer colindex, variant &value, string dbfieldtype): This reads the colindex-th column from the currently fetched row from a result set into the variable value. dbfieldtype specifies the database field type expected (as in "type" attribute of , see  REF _Ref47173451 \r \h 11.34.41.1). Note that if SQLGETCOLUMN is called multiple times for a single row, colindex must be increasing for each call (this is an ODBC requirement). integer SQLITELASTID(): For SQLite only: returns the ROWID created by the last INSERT statement.  XE "SQLCOMMIT" \f F SQLCOMMIT(): Commits the current transaction. Make sure you call SQLCOMMIT or SQLROLLBACK before ending scripts that use SQLEXECUTE, especially when the SQL statemement was a DML statement (modifiying data in the database).  XE "SQLROLLBACK" \f F SQLROLLBACK(): Performs a rollback on the current transaction. Make sure you call SQLCOMMIT or SQLROLLBACK before ending scripts that use SQLEXECUTE, especially when the SQL statemement was a DML statement (modifiying data in the database). The following two functions are available only for ODBC, but not for SQLite:  XE "SETDBCONNECTSTRING" \f F SETDBCONNECTSTRING(string dbconnectstring): This can be used to programmatically set the ODBC database connection string (which is normally set using , see  REF _Ref203474873 \r \h 12.4). Note that while this is technically possible in many scripts, it usually makes sense only in (see  REF _Ref203474654 \r \h 11.33) to eventually choose different databases depending on login information. Using SETDBCONNECTSTRING closes the currently open session level ODBC connection (if any), but does not open a new connection immediately. The new connection string and password are used to open a new connection as soon as the next SQL statement needs to be executed.  XE "SETDBPASSWORD" \f F SETDBPASSWORD(string dbpassword): This can be used together with SETDBCONNECTSTRING to set the password for opening a DB connection. XE "datasource" \f T: ODBC data source name Contained in: , Can contain: name of ODBC data source Attributes: none This tag specifies the name of the ODBC data source. This is the name that was set when creating the ODBC data source (see chapter 2). Note that for some data sources that need additional parameters (or if you want to connect without a data source by directly specifying ODBC driver parameters), you might need to use (see  REF _Ref58909011 \r \h 12.4) instead of and . XE "dbuser" \f T: ODBC database user name Contained in: , Can contain: user name for accessing the ODBC data source Attributes: none This tag specifies the name of the user that is used to access the ODBC data source. Note that for some data sources that need additional parameters (or if you want to connect without a data source by directly specifying ODBC driver parameters), you might need to use (see  REF _Ref58909011 \r \h 12.4) instead of and .  XE "dbconnectionstring" \f T : ODBC database connection string Contained in: , Can contain: ODBC connection string Attributes: none This tag can be used as an alternative to and in cases when you need to pass more parameters to the ODBC engine than just datasource name and user name. For example some versions of the MyODBC driver need the "DATABASE" parameter to be able to connect correctly. Using it is also possible to connect directly to a ODBC driver without using a datasource by including all the driver-specific parameters in the (this is for adcanced ODBC users only - see ODBC documentation). Important note: the is shown in debug logs for reference. Therefore we recommend to not including the PWD parameter in the but specifying it with (see  REF _Ref58909800 \r \h 12.5) - which causes the PWD parameter to be automatically appended to the before it is sent to the ODBC engine (but after it is shown in the log). The following three examples are functionally identical: mydatasource test secret DSN=mydatasource; UID=test; DATABASE=syncml; secret DSN=mydatasource; UID=test; DATABASE=syncml; PWD=secret; XE "dbpass" \f T: ODBC database password Contained in: , Can contain: password for accessing the ODBC data source Attributes: none This tag specifies the password required to access the ODBC data source with the user name specified in (or in the , see  REF _Ref58909011 \r \h 12.4). Please make sure that the config file is not accessible from the outside in order not to compromise your database's security.  XE "preventconnectattrs" \f T : prevent setting connection attributes Contained in: , Can contain: boolean value Attributes: none This can be set to true to prevent that any attempt to set ODBC connection attributes is made at all (some ODBC drivers exists which will crash when trying to modify connection attributes). XE "dbtimeout" \f T: ODBC timeout Contained in: , Can contain: timeout value in seconds, 0 for no timeout Attributes: none Default: 30 seconds Defines the timeout for ODBC. Please note that this does not work with every ODBC driver, so this setting might have no effect at all with some ODBC databases.  XE "afterconnectscript" \f T : Script executed whenever new DB connection is opened. Contained in: , Available: in PRO versions only Can contain: script Script context: afterconnect context (private only for this script) Attributes: none Default: no script This script is executed once immediately after opening a new database connection. This can be used to execute extra SQL statements (such as access authorisation for SyBase) using the SQLxxx() functions (see  REF _Ref78024414 \r \h 12.1.4). XE "transactionmode" \f T: Transaction isolation mode Contained in: , Can contain: transaction isolation mode Attributes: none Default: "default" This tag is used to defined the transaction isolation mode to be used. It can be set as follows: "none" : no isolation mode "default": use default isolation mode of the ODBC driver "read-uncommitted": other transactions see all changes done. This is the least restrictive mode. If you experience locked table problems, try using this mode. "read-committed": other transactions see committed changes "repeatable": reads are repeatable with same results "serializable": full serializable isolation Please note that not all ODBC drivers support all these modes. Setting a mode that is not supported may result in fatal errors preventing the sync server from working at all. XE "transactionmode" \f T: usage of ODBC cursor library Contained in: Can contain: boolean value Attributes: none Default: false This tag is used to select if the ODBC cursor library should be used or not. Under normal circumstances, for the access patterns generated by a SyncML client or server, the cursor library is not required and only generates overhead if switched on. Please note that some ODBC drivers may not work properly with cursor library switched on or off, so in case of strange ODBC behaviour, you might want to try changing this flag. XE "textmap" \f T, XE "textauth" \f T, XE "textpath" \f T: outdated - no longer available Contained in: Available: no longer available in 3.0 version These tags were used to control text-file based administration tables and/or user auth. This has been replaced by the plugin mechanism (see  REF _Ref135023442 \r \h 14) and the built-in SDK_textdb plugin module (see  REF _Ref133810323 \r \h 14.3). To use SQL for the data tables, but have all administrative data stored in text files (as it is for example required for SQLite based setups, see  REF _Ref182743880 \r \h 12.20.6), just use the SDK_textdb plugin in and enable / at the session level (see  REF _Ref153703095 \r \h 14.1) and use the SDK_textdb plugin in at the datastore level (see  REF _Ref153681044 \r \h 14.2). XE "cleartextpw" \f T: plain text password in database Contained in: Can contain: boolean value Attributes: none Default: on This option (together with selects how Synthesis Sync Server authenticates with the database: If is set, the database must be able to return the password for a user in clear text. The Sync Server then uses that password, together with an eventual nonce string (see  REF _Ref5608796 \r \h 11.7) to calculate the MD5 digest to compare with the client's authentication attempt. If and is not set, the database must be able to check authentication (and perform MD5 calcualtions required) for a given combination of username, MD5 digest and nonce string. In most cases, should be set. Even if passwords are transferred in clear text between database and sync server, they are NOT transferred in clear text over the net. So if your database and web server is properly secured, set does not compromise security. Setting prevents clear text passwords to be stored in the database, however due to a design problem in SyncML 1.0 (SyncML 1.1 has solved that), this will prevent that clients can use the MD5 digest authentification. This is more of a security risk than using , because when clients cannot use MD5 authentification they must use basic authentification which means sending passwords almost clear text (only B64 encoded!) over the internet. XE "md5userpass" \f T: MD5 digest passwort in database Contained in: Can contain: boolean value Attributes: none Default: on This option selects another mode of how Synthesis Sync Server can authenticates with the database: If is set, the database must be able to return a string which is either the B64 encoding of the MD5 digest of "user:password" ( set to false, see  REF _Ref166649222 \r \h 12.14) or a 32-char hex string encoding the MD5 digest ( set to true) for each user. The Sync Server then uses that information to verify client's credentials. See " REF _Ref5609191 \r \h 0" for security considerations. XE " md5hex " \f T: MD5 digest stored as hex string in database Contained in: Can contain: boolean value Attributes: none Default: false New in: 3.0.0.17 This option selects the format of the MD5 digest when stored in the database (see  REF _Ref166649220 \r \h 12.13). With md5hex set to true, the format is a 32-char string of hexadecimal digits (for example compatible with the md5() function in PHP). Otherwise, the MD5 digest must be stored in B64 encoding.  XE "getdevicesql" \f T ,  XE "newdevicesql" \f T ,  XE "savenoncesql" \f T ,  XE "saveinfosql" \f T : Device management Contained in: , Can contain: SQL statements Attributes: none Default: none These tags can hold SQL statements to manage a device table in the database. If these statements are not defined, the SyncML engine can also work without a device table, but it is recommended to have a device table. The device table will receive a single entry for every device that has ever connected to the server. The table for device management must have at least the following fields: a device key as a primary key to the devices table. a device id field, which should be a string of at least 50 characters. For better performance, this field should be indexed. a last nonce field, which should be a string of at least 20 characters. Optionally, the following fields are recommended a device name field, which should be a string of about 60 characters, which will be assigned the descriptive name of the device. a device info field, which should be a string of about 120 characters, which will be assigned some additional information about the device (type, version, OEM manufacturer). The four SQL statements related to device management must do the following: must be a SELECT statement returning for a given device id a result set with a single row and two columns: first column must be the device key, second column must be the last nonce. If the device id is not known yet, this statement must return an empty result set. To include the device id in the SELECT's WHERE clause, %D can be used. Note that all other % placeholders described in  REF _Ref43729255 \r \h  \* MERGEFORMAT 12.1 do not apply here! must create a new record for the device id with a new, unique device key (by means of an autoincrementing device key field in the database or another database mechanism such as a generator, sequence or trigger). Normally, this is a simple INSERT statement. To insert the device id into the statement, %D can be used. Note that all other placeholders described in  REF _Ref43729255 \r \h  \* MERGEFORMAT 12.1 do not apply here! must update the last nonce for a specified device key. To insert the device key (for example in the WHERE clause), %d can be used. To insert the last nonce, %N can be used. In addition, placeholders described in  REF _Ref47172128 \r \h 12.1.1 can also be used. is an optional statement that can be used to save device name  and  device info information. To insert the device key (for example in the WHERE clause), %d can be used. To insert the device name %nR can be used, to insert the device info, %vR can be used. In addition, placeholders described in  REF _Ref47172128 \r \h 12.1.1 can also be used. The following example shows a complete set of SQL statements to manage devices in a table called SYNC_DEVICES: SELECT DEVICE_KEY,LASTNONCE FROM SYNC_DEVICES WHERE DEVICEID='%D' INSERT INTO SYNC_DEVICES (DEVICEID) VALUES ('%D') UPDATE SYNC_DEVICES SET LASTNONCE='%N' WHERE DEVICE_KEY=%d UPDATE SYNC_DEVICES SET DEVICENAME='%nR', DEVICEINFO='%vR' WHERE DEVICE_KEY=%d XE "userkeysql" \f T: query for user authentication Contained in: , Can contain: SQL query statement Attributes: none This tag specifies the SQL statement that is used to check authorisation of a user in the database. The SQL string specified can contain placeholders to insert values into the query. In addition to the general placeholders (see  REF _Ref47172128 \r \h 12.1.1), the following special placeholders are available in : %U represents the original user name as sent by the remote device. %dU represents the user name that has been set with the SETUSERNAME() function in . %D represents the "domain" value that has been set with the SETDOMAIN() function in . %M represents the credential string (plain text password or MD5 digest, depending on login type) %N represents the nonce string. Depending on how is set (see  REF _Ref42943854 \r \h 12.12), this SQL statement must do the following: If is set, the statement must return a row for every user with a given name having the following result columns (in that order): a "user key": This is a value (normally a primary key into the user table) that uniquely identifies the user and which can be used in further queries to subselect this user's data folder(s) (see  REF _Ref42943895 \r \h 12.20.1). This value is treated as a string, but can be of any data type that has a unambiguous string representation. the password for that user in clear text. If no user with the given name exist, an empty result set (no rows) must be returned. If is set, the statement must return a row for every user with a given name having the following result columns (in that order): a "user key": This is a value (normally a primary key into the user table) that uniquely identifies the user and which can be used in further queries to subselect this user's data folder(s) (see  REF _Ref42943895 \r \h 12.20.1). This value is treated as a string, but can be of any data type that has a unambiguous string representation. the B64-encoded MD5-digest of the string "user:password". If no user with the given name exist, an empty result set (no rows) must be returned. If neither nor are set, the statement must return exactly one row as a result when there is a user that matches the given username, MD5-digest and nonce string, having the following result column: a "user key": This is a value (normally a primary key into the user table) that uniquely identifies the user and which can be used in further queries to subselect this user's data folder(s) (see  REF _Ref42943895 \r \h 12.20.1). This value is treated as a string, but can be of any data type that has a unambiguous string representation. If the given combination of username, MD5 digest and nonce are not valid, the query must return an empty result set (no rows). Note: When using (see  REF _Ref36896289 \r \h 12.17), the columns returned by are assigned to the local variables of the logincheckscript in the order of their definition. Therefore, the may be written such that it returns more columns than those described above. This allows fetching extra user data needed to decide about login in the logincheckscript. Example with set: SELECT USER_KEY,PASSWD FROM SYNC_USERS WHERE USERID='%U' Example with set: SELECT USER_KEY,MD5DIGEST FROM SYNC_USERS WHERE USERID='%U' Example with neither nor set (note that this assumes the presence of a non-standard SQL function "B64MD5"). SELECT USER_KEY FROM SYNC_USERS WHERE B64MD5('%U',PASSWD,'%N')='%M' XE "logincheckscript" \f T: custom login checking script Contained in: Available: in PRO versions only Can contain: script returning boolean value Script context: login context Attributes: none Default: no script This script is executed for every row returned by (see  REF _Ref13986562 \r \h 12.16). Local variables of this script will be initialized with values returned by . The script has access to the same special script functions as (see  REF _Ref36896793 \r \h 12.13 for details). If this script returns TRUE, login is granted. XE "timestampsql" \f T: query for getting database time Contained in: or Can contain: SQL query statement Attributes: none Default: not specified This tag specifies the SQL statement that is used to get a timestamp of the database server's current time. If this tag is not specified, Synthesis Sync Server uses the local time of the machine it is run as current time. It is recommended not to leave this unspecified, because time differences between database and sync server can lead to data consistency problems. The query must return a single row with a single column that represents a timestamp (combined date and time) value. Note that (see  REF _Ref185246110 \r \h 11.34.31) determines in what time zone context the result of this query is to be treated. Example for Microsoft SQL server: SELECT GETDATE() AS CURRENTDATETIME XE "timestamputc" \f T: SQL statement to write activity log entry Contained in: or Can contain: SQL statement Attributes: none Default: false This statement is executed for each datastore involved in a sync session after the sync session has either completed (with or without errors) or timed out (see  REF _Ref47163749 \r \h 11.2 how to set session timeout). Usually, this is an SQL INSERT statement into a global log table. In the statement, all escape sequences described in (see  REF _Ref47169796 \r \h 11.31) plus the following special escape sequences can be used to insert information from the current session into the log: %dT Sync date %tT Sync time %T Sync timestamp (reference time for comparisons of changed/unchanced decisions of last session) %ssT Sync start timestamp (when this sync attempt, successful or not, has started) %seT Sync end timestamp (when this sync attempt, successful or not, has ended) %f folder key (see  REF _Ref42943895 \r \h 12.20.1) %t target key (see  REF _Ref47171780 \r \h 12.20.2) %u user key (see  REF _Ref47171842 \r \h 12.16) %d device key (see  REF _Ref47171876 \r \h 12.14)  XE "datastore type=odbc" \f T  XE "datastore type="sql"" \f T : SQL and ODBC Datastore specific settings Contained in: or Can contain: All tags in chapter  REF _Ref42944330 \r \h 12.20 Attributes: name, type="sql" (or as an alias for backward compatibility: type="odbc") Default: not specified This chapter describes the tags that are specific to SQL and ODBC datastores. See  REF _Ref45367951 \r \h 11.34 for a description of the tag in general. Note: Starting with version 3.0.3.0, the SQL datastore type also supports direct access to SQLite database files instead of using ODBC for accessing the user data. Admin data (SYNC_TARGETS, SYNC_MAPS, SYNC_DEVICES, SYNC_LOGS in the sample config) however is not supported for SQLite at this time. See  REF _Ref182743880 \r \h 12.20.6 for details about SQLite related config. Please also note that SQLite support may not be included in some products. XE "folderkeysql" \f T: get data subselection key Contained in: Can contain: SQL query string Available for: ODBC only (not SQLite) Attributes: none Default: empty This tag specifies the SQL statement that is used to obtain a key value that can be used in subsequent SQL statements to sub-select data in a so-called folder. Folders are subdivisions of a user's data. For example, a user might have two separate database for work and private use on his SyncML-enabled PDA. To allow this on the server side, this user can be given two separate "folders" to store work and private contacts separated from each other. On the SyncML client, the folder name is specified in the target database path. For example, if the database path for contacts is "./contacts", then a folder named "private" will be addressed as "./contacts/private". This tag can be omitted or left empty if the server does not support multiple folders per user. In this case, every user will only have a single folder. In this case, the user key (or user name when using (see  REF _Ref13986080 \r \h 12.11) or , (see  REF _Ref5702037 \r \h 11.10)) is used as folder key, allowing to differentiate records in the data table by user. The SQL string specified can contain placeholders to insert the following values into the query: %F represents the folder name. If the SyncML client specifies no folder name (eg. just "./contacts"), the folder name is an empty string. %u represents the user key. The user key is the value that was returned by the statement (see  REF _Ref47171963 \r \h 12.16). The query must return: An empty result set when the folder does not exist or the user is not allowed to access it At least one row with one single column containing the folder key. This value is treated as a string, but can be of any data type that has a unambiguous string representation. Example (using a link table between folders and users to allow users sharing folders): SELECT FOLDER_KEY FROM SYNC_FOLDERS F JOIN SYNC_PERM P ON P.FOLDERKEY=F.FOLDER_KEY AND P.USERKEY=%u WHERE F.FOLDERID='%F' XE "synctargetgetsql" \f T, XE "synctargetnewsql" \f T, XE "synctargetupdatesql" \f T, : Sync target management Contained in: Can contain: SQL query strings Available for: ODBC only (not SQLite) Attributes: none These four SQL statements are used to manage sync target information. The sync server needs to remember some information for every client database (called sync target) it does a sync session with. This information is stored in an auxiliary table which can exist once for the entire server (as in the config samples, where a separate field DSCODE is used to separate targets from different datastores, see example below) or in a separate table for every datastore (for example if varying custom data needs to be in the same tables for each datatype). The SQL strings specified can contain the following special placeholders (in addition to the standard placeholders as described in  REF _Ref47172128 \r \h 12.1.1) : %f represents the folder key. The folder key is the value that was returned by the statement (see  REF _Ref6117078 \r \h  \* MERGEFORMAT 12.20.1). %u: represents the user key. The user key is the value that was returned by the statement (see  REF _Ref47174498 \r \h 12.16). %t: represents the target key (only for ). %D: represents the device ID of the SyncML client (client URI). %P: represents the client's remote database path (client datastore URI). %L: represents the timestamp of last sync (only for ). %dL: represents the date of last sync (only for ). %tL: represents the time of last sync (only for ). %S: represents the timestamp of last server anchor (only for ). This (and the following two) is needed only when (see  REF _Ref8187404 \r \h  \* MERGEFORMAT 11.34.37) is set. %dS: represents the date of last last server anchor (only for ). %tS: represents the time of last last server anchor (only for ). %RL: represents the timestamp of last sync where remote party was updated (only for . This (and the following five) is needed only if (see  REF _Ref71016088 \r \h 11.34.36) is set. %dRL: represents the date of last sync (only for ). %tRL: represents the time of last sync (only for ). %iRL: represents the custom identifier for the last sync where remote party was updated. This is needed only when (see  REF _Ref153708057 \r \h 11.34.38) is set. %RS: represents the timestamp of last server anchor (only for ). This (and the following two) is needed only when (see  REF _Ref8187404 \r \h  \* MERGEFORMAT 11.34.37) is set. %dRS: represents the date of last last server anchor (only for ). %tRS: represents the time of last last server anchor (only for ). New for Version 3.0 (only needed if is set – see  REF _Ref153707807 \r \h 11.34.39) %SUA: represents the resume alert code (only for ). %SU: represents the timestamp of last suspend (only for ).. %dSU: represents the date of last last suspend (only for ). %tSU: represents the time of last last suspend (only for ). %iSU: represents the custom identifier for the last suspend. This is needed only when (see  REF _Ref153708057 \r \h 11.34.38) is set. New for Version 3.0 (only needed if is set – see  REF _Ref153710706 \r \h 11.34.40). %pSU: represents the Source URI string of the item that must be resumed in the next session. %pTU: represents the Target URI string of the item that must be resumed in the next session. %pSt: represents the partial item status code (numeric). %pM: represents the internal partial item mode (numeric). %pTS: represents the partial item total size (numeric). %pUS: represents the partial item unconfirmed size (numeric). %pSS: represents the partial item stored size (numeric), which is the number of bytes that will be stored into the partial item data field. %pDAT: represents the partial item date (which is a BLOB of the size indicated by %pSS). This value is not literally inserted into the SQL statement, but as a parameter. The four SQL statements are used to look up, create, modify and delete sync target records. The statement specified in must look up if there is already a sync target record matching user, folder, deviceID, remote database path and if yes, return a single row with the following columns (in that order!): target key: this is a value uniquely identifying the target. Normally this is the primary key of the sync target table. It is used to subselect map entries (see below) in the map table. This value is treated as a string, but can be of any data type that has a unambiguous string representation. sync anchor: this is a string value which is set by the sync server. The database table should simply provide a string field of 40 chars size. timestamp of last successful sync: This is set by the sync server. The database table must provide a column that can hold timestamp values when (see  REF _Ref8187433 \r \h 12.20.3) is set, if is not set, it must provide a date and a time column). Only if (see  REF _Ref8187404 \r \h 11.34.37) is set, a separate timestamp used for last server anchor (if is not set, server anchor and last sync timestamps are identical and need to to be saved separately). The database table must provide a column that can hold timestamp values when is set, if is not set, it must provide a date and a time column) . Only if (see  REF _Ref71016088 \r \h 11.34.36) is set, a timestamp of last successful sync when remote was updated. This is needed to allow one-way from remote sync sessions, and is set by the sync server. The database table must provide a column that can hold timestamp values when (see  REF _Ref8187433 \r \h 12.20.3) is set, if is not set, it must provide a date and a time column) . Only if and (see  REF _Ref8187404 \r \h 11.34.37) is set, a separate timestamp used for last server anchor (if is not set, server anchor and last sync timestamps are identical and need to to be saved separately). The database table must provide a column that can hold timestamp values when is set, if is not set, it must provide a date and a time column) . Only if (see  REF _Ref153708057 \r \h 11.34.38) is set, a string identifying the point in time of the last sync for the datastore implementation (plugin). The format of this string is free and only depends on the datastore implementation in the plugin. This is used when the plugin uses a private count or timestamp for detecting changes since last sync. New for version 3.0: For databases supporting SyncML DS 1.2 Suspend & Resume (those that have enabled, see  REF _Ref153707807 \r \h 11.34.39), the following additional columns must be returned: resume alert code: this must be at least a 16-bit integer. timestamp of last suspend: This is set by the sync server. The database table must provide a column that can hold timestamp values when (see  REF _Ref8187433 \r \h 12.20.3) is set, if is not set, it must provide a date and a time column). Only if (see  REF _Ref153708057 \r \h 11.34.38) is set, a string identifying the point in time of the last suspend for the datastore implementation (plugin). The format of this string is free and only depends on the datastore implementation in the plugin. This is used when the plugin uses a private count or timestamp for detecting changes since last suspend. New for version 3.0: Only if and (see  REF _Ref153710706 \r \h 11.34.40) are enabled, the following additional columns must be returned: last source URI: a string used by the sync server for resuming partial items. last target URI: a string used by the sync server for resuming partial items. last item Status: this must be at least a 16-bit integer. partial item State: this must be at least a 8-bit integer. total item size: this must be at least a 32-bit integer. unconfirmed item size: this must be at least a 32-bit integer. stored item size: this must be at least a 32-bit integer, and represents the size of the data stored in the "partial item" column (see below). partial item: this must be a BLOB column that can hold an arbitrary block of binary data, with potentially 2^32 bytes of size. In reality, this block will never exceed the maximum size of data objects supported. But for example for emails with attachments, the partial item can get quite large. The statement specified in must insert a new record into the sync target table, which is uniquely defined by user, folder, deviceID, and remote database path. The statement specified in must update all values fetched by for a specified targetkey. The statement specified in must delete an existing sync target record identified by a target key value. In addition, it should make sure that all related map entries (see  REF _Ref47781675 \r \h 12.20.5) are also deleted (by an implicit ON DELETE CASCADE constraint or explicitly by including more than one DELETE statement into this tag, which can be done by using the %GO special sequence, see  REF _Ref47781653 \r \h 12.1.2). Example (what is new for version 3.0 is marked red): SELECT TARGET_KEY, ANCHOR, LASTSYNC, LASTTOREMOTESYNC, RESUMEALERT, LASTSUSPEND, LISOURCE, LITARGET, LISTATUS, PISTATE, PITOTALSZ, PIUNCONFSZ, PISTOREDSZ, PIDATA FROM SYNC_TARGETS WHERE DSCODE='no' AND USERKEY=%u AND FOLDERKEY=%f AND DEVICEKEY=%d AND DEVICEDBPATH='%P' INSERT INTO SYNC_TARGETS (DSCODE, USERKEY, FOLDERKEY, DEVICEKEY, DEVICEDBPATH) VALUES ('no', '%u', %f, %d, '%P') UPDATE SYNC_CONTACTS_TARGETS SET ANCHOR='%A', LASTSYNC=%L WHERE TARGET_KEY='%t' UPDATE SYNC_TARGETS SET ANCHOR='%A', LASTSYNC=%L, LASTTOREMOTESYNC=%RL, RESUMEALERT=%SUA, LASTSUSPEND=%SU, LISOURCE='%pSU', LITARGET='%pTU', LISTATUS=%pSt, PISTATE=%pM, PITOTALSZ=%pTS, PIUNCONFSZ=%pUS, PISTOREDSZ=%pSS, PIDATA=%pDAT WHERE TARGET_KEY=%t DELETE FROM SYNC_TARGETS WHERE TARGET_KEY=%t %GO DELETE FROM SYNC_MAPS WHERE TARGET_KEY=%t XE "synctimestamp" \f T: format for timestamps in target table Contained in: Can contain: boolean value Available for: ODBC only (not SQLite) Default: yes If this tag is set to yes, timestamp values in the sync target information are stored in timestamp columns (one column containing combined date/time value). Otherwise, timestamp values are stored as a pair of separate date and time columns. Note that SQL statements (see  REF _Ref6030156 \r \h 12.20.2) must be formed according to this setting.  XE "lastmodfieldtype" \f T : modified time stamp type Contained in: Can contain: database field type for the modified time stamp field Attributes: none Default: timestamp This tag specifies the database field type used as modified timestamp. For SQL/ODBC databases this is usually "timestamp" (the default), but for SQLite databases which do not have a native timestamp format, this can be set to one of the integer timestamp formats (such as UNIX epoch time). See description of "type" attribute in  REF _Ref47173451 \r \h 11.34.41.1 for possible values but note that only timestamp-related field types makes sense here!  XE "selectmapallsql" \f T ,  XE "insertmapsql" \f T ,  XE "updatemapsql" \f T ,  XE "deletemapsql" \f T : Map table management Contained in: Can contain: SQL statements Available for: ODBC only (not SQLite) Attributes: none Default: none These four SQL statements are used to manage object ID mapping information. The sync server needs to create a map entry for every object synchronized between the server and a specific device. A map entry links the unique localID - normally a primary key of the data table in the local server database - to the corresponding unique remoteID for the same object in the remote SyncML client's database. As there are separate map entries for each database on each device, the map table entries must be related to a sync target (see  REF _Ref43728908 \r \h 12.20.2). Note that map entries may not be related to the data records via localID in a way that would cause automatic deletion of the map entry when the data record is deleted (such as with a ON DELETE constraint)! It is essential that map entries remain existing after the corresponding data records are deleted - this is required by the sync engine to detect and propagate delete operations. The SQL strings specified can contain the following special placeholders (except selectmapallsql) in addition to the standard placeholders described in  REF _Ref47779943 \r \h 12.1.2: %k represents the localID. The localID is normally the primary key into the database table containing the actual data records (such as contact records or events). Depending on the type of key, this might be a string or a numeric value. %r: represents the remoteID. This must always be treated as a string - normally it is not more than 30 characters in length, but some clients (mostly those that have to deal with Microsoft Exchange) use very long IDs so we recommend reserving 64 or even 128 characters here. New for version 3.0: (only needed if is set – see  REF _Ref153707807 \r \h 11.34.39) %e: represents the entryType. This is a small integer (8 bits are sufficient) and determines the type of the map entry – because for some SyncML DS 1.2 features, different types of map entries are required. It is important to include entryType into the primary key for the map table (and no longer only localID and targetKey) because multiple map entries with the same localID, but different entryType can exist for the same targetKey). %x: represents the mapFlags. This is a 32 bit integer and stores extra flags for each map item required for SyncML DS 1.2 Suspend&Resume and other advanced features. The four SQL statements are used to read the entire map table and to add, update and delete single map entries. The statement specified in must return a result set containing the entire map table for the current sync target (normally there is a WHERE clause including %t to restrict the SELECT to the map entries of one sync target) in two columns (in that order!): localID: this column must contain the localID, which can be a string or a numeric value, depending on the type of primary key the data table has. remoteID: this column must contain the remoteID, which always is a string. New for version 3.0: For databases supporting SyncML DS 1.2 Suspend & Resume (those that have enabled, see  REF _Ref153707807 \r \h 11.34.39), the following additional columns must be returned: entryType: this column must contain the entryType, a small integer (8 bit is sufficient). mapFlags: this column must contain the mapFlags, which is at least a 32 bit integer value. The statement specified in must insert a new record into the map table, which is related to a sync target and contains both localID and remoteID. The statement specified in must update the remoteID for a given localID related to a sync target. The statement specified in must delete the map entry with a given localID related to a sync target. Example SQL definition of a map table (what is new for version 3.0 is marked red): CREATE TABLE SYNC_CONTACTS_MAP ( LOCALID INTEGER NOT NULL, REMOTEID VARCHAR(63), TARGETKEY INTEGER NOT NULL, ENTRYTYPE INTEGER DEFAULT 1, FLAGS INTEGER DEFAULT 0, PRIMARY KEY (LOCALID,ENTRYTYPE,TARGETKEY) ) Example config to access the map table defined above (new for version 3.0 in red): SELECT LOCALID, REMOTEID, ENTRYTYPE, FLAGS FROM SYNC_MAPS WHERE TARGETKEY=%t INSERT INTO SYNC_MAPS (LOCALID, REMOTEID, TARGETKEY, ENTRYTYPE, FLAGS) VALUES (%k,'%r',%t, %e, %x) UPDATE SYNC_MAPS SET REMOTEID='%r', FLAGS=%x WHERE LOCALID=%k AND ENTRYTYPE=%e AND TARGETKEY=%t DELETE FROM SYNC_MAPS WHERE LOCALID=%k AND ENTRYTYPE=%e AND TARGETKEY=%t  XE "sqlitefile" \f T : SQLite database file name Contained in: Can contain: path to SQLite 3 database file (usually has extension .sdb) Attributes: none Default: none If this tag contains a file path, the datastore uses the specified SQLite 3 database file to access user data rather than using ODBC to access a SQL server. Note that SQLite databases can only be used for user data (contacts, calendar, notes etc.), but not for SyncML administrative data like users, devices, folders, targets and maps (see  REF _Ref43728908 \r \h 12.20.2,  REF _Ref153731855 \r \h 12.20.5,  REF _Ref68495073 \r \h 12.15,  REF _Ref43727921 \r \h 12.16). In a SQLite based setup, administrative data is either transparently handled by the SyncML engine itself (this is the case for custom clients built with the Synthesis SyncML client library / SDK) or must be stored using a database plugin (see  REF _Ref135023442 \r \h 14 – " REF _Ref135023442 \h ,  XE "client type=plugin"\f T : Plugin Based Server or Client Config"). The built-in text-file based plugin is usually sufficient and can be used as-is (see  REF _Ref133810323 \r \h 14.3).  XE "sqlitebusytimeout" \f T : SQLite database file name Contained in: Can contain: SQLite timeout when data is busy (in seconds) Attributes: none Default: 15 This specifies the time the SQLite engine waits for data becoming ready for access before it returns a "database busy" error. XE "quotingmode" \f T: how ODBC strings must be escaped for the database Contained in: , or Can contain: name of quoting mode Attributes: none Default: "singlequote" This defines how line ends within strings are encoded: "singlequote": This is the default, and this was the only mode supported before version 2.1.1.5: single quotes must be duplicated (ok for many SQL DBs like Oracle, Interbase, MS-SQL) in string literals "doublequote": double quotes must be duplicated in string literals "backslash": Backslash is an escape char, and CR,LF,TAB,BS,\," and ' must be backslash-escaped (MySQL mode). "none": No quoting, usually not recommended as string containing the single quote string delimiter can not be used then. Note: when used in context of a , this setting only affects the actual accesses to this datastore - so it is possible to have different quoting modes for different datastores. If used in context of or , the setting is used for all accesses that are not related to a particular datastore.  XE "dbcanfilter" \f T : use filtering in WHERE clause Contained in: Can contain: boolean value Attributes: none Default: false If this option is set to true, the server tries to convert active filters into an SQL WHERE clause that can be included in SELECT statements using the %AF and %WF placeholders. This is efficient as it prevents the database from fetching data that is not needed for a sync session, however not all filter expressions can be converted to a WHERE clause. XE "earlycommit" \f T: commit at end of SyncML message exchange Contained in: Can contain: boolean value Attributes: none Default: true (false in 1.0.5 versions and earlier) If this option is set to true, the server always commits all updates to the database at the end of every message exchange with the client. This is important for database setups where an unfinished transaction could lock other transactions. By setting this option, no transaction will be kept active for a longer period of time. XE "multicursor" \f T: no longer supported in version 3.0 Contained in: Can contain: boolean value Attributes: none Default: false This option is no longer supported in version 3.0. XE "commititems" \f T: commit each item update Contained in: Can contain: boolean value Attributes: none Default: false If this option is set to true, the server separately commits all updates to the database as they occur. This might be needed depending on the database design. XE "modtimestamp" \f T: combined date and time for modification timestamp Contained in: Can contain: boolean value (for ) field names (for , ). Available for: ODBC only (not SQLite) Attributes: none Default: true This tag specifies if the modification timestamp in the data table consists of a single timestamp value ( true) or if it consists of a date field and a time field ( false). This setting is used when reading modification timestamps with , see  REF _Ref47784397 \r \h 12.20.14.  XE "selectidandmodifiedsql" \f T : read IDs and timestamps Contained in: Can contain: SQL statements Available for: ODBC and SQLite Attributes: none Default: none This SQL statement must return a result set containing localID and modification timestamp for all records in the database for the current sync target as follows (in that order!): local id: this column must contain the local ID, which can be a string or a numeric value. modification timestamp or modification date: this column must contain the modification timestamp (if is true) or the modification date (if is false). modification time: this third column must be returned only if is false (modification timestamp consisting of a date field and a time field). This SQL statement must only return the rows that belong to the current user (therefore possibly including %u in the WHERE clause, see  REF _Ref47172128 \r \h 12.1.1) and in the current folder (therefore possibly including %f in the WHERE clause, see  REF _Ref47779943 \r \h 12.1.2) and passing the currently set filters (therefore including %AF or %WF in the WHERE clause, see  REF _Ref47173394 \r \h 12.1.3). Example (note that records are selected by folder key with %f, and %AF is included to extend the WHERE clause with AND plus a filter expression in case there are filters defined for the current sync session (see  REF _Ref46752884 \r \h 7 for details about filters) SELECT CONTACTS_KEY,MODIFIED FROM SYNC_CONTACTS WHERE FOLDERKEY=%f %AF  XE "selectdatasql" \f T : read record from database Contained in: Can contain: SQL statements Available for: ODBC and SQLite Attributes: none Default: none This SQL statement is used to read all fields of a record identified by its localID from the database. The statement must return a result set with a single row containing all columns (fields) in the that are enabled for read (see "mode" attribute of in  REF _Ref47173451 \r \h 11.34.41.1) in the order as they appear in the . Normally, this consists of a SELECT statement which uses %N as the list of columns to be selected (%N automatically contains the list of all read-enabled fields in the , see  REF _Ref47173394 \r \h 12.1.3). Example: SELECT %N FROM SYNC_CONTACTS WHERE CONTACTS_KEY=%k  XE "insertdatasql" \f T ,  XE "updatedatasql" \f T ,  XE "deletedatasql" \f T ,  XE "zapdatasql" \f T : write records to database Contained in: Can contain: SQL statements Available for: ODBC and SQLite Attributes: none Default: none These four SQL statements are used to modify the data table. The statement specified in must insert a new record into the data table. If (see  REF _Ref46750086 \r \h 12.20.18) is false, the ID for the new record will be made available before the execution of (by executing ) and can be included in using the %k placeholder (see  REF _Ref47173394 \r \h 12.1.3). If is true, the execution of must automatically generate an ID, which is then obtained with the statement after the insert. The %N and %v placeholders can be used to easily include the list of column names and values that must be INSERTed. See example below. The statement specified in must update a record identified by a localID (which can be inserted into the statement using %k, see  REF _Ref47173394 \r \h 12.1.3). The %V placeholder can be used to easily include a list of column name / value pairs for an UPDATE statement. %N and %v can be used as well, for example when not using UPDATE, but a stored procedure call. Note that %V, %N and %v only include the columns that need to be changed, unless is set to true. To include all columns that are write-enabled (see "mode" attribute of in  REF _Ref47173451 \r \h 11.34.41.1) the placeholders %aV, %aN and %av can be used. The statement specified in must delete a record identified by a localID (which can be inserted into the statement using %k, see  REF _Ref47173394 \r \h 12.1.3). Note that this needs not necessarily be a physical DELETE statement, but could also be an UPDATE statement that updates a flag in the records such that it disappears from the list of records returned by the (see  REF _Ref47845006 \r \h 12.20.14). The optional statement specified in must delete all records that are part of the synchronized data set (that is, all records that are returned by the statement, see  REF _Ref47845006 \r \h  \* MERGEFORMAT 12.20.14). This statement is used in a server when a SyncML client requests "refresh from client only" sync or in a client when "refresh from server" sync mode is used. If it is not specified, the server will repeatedly use to delete all the records one by one.  XE "ignoreaffectedcount" \f T : Ignore SQLRowCount Contained in: Can contain: boolean value Attributes: none Default: false New in: 3.0.2.2 If < ignoreaffectedcount> is set, the SQLRowCount (number of rows affected by an UPDATE or INSERT statement) is ignored for and (see  REF _Ref66078569 \r \h 12.20.16). This might be needed when update statements are implemented as stored procedure which might not set SQLRowCount correctly. XE "obtainidafterinsert" \f T, XE "obtainlocalidsql" \f T, XE "determineidonce" \f T, XE "minnextid" \f T,  XE "specialidmode" \f T ,  XE "insertreturnsid" \f T ,  XE "localidscript" \f T : local object ID management Contained in: Can contain: boolean value (for , ), SQL query (for ), integer value (for ), one of "none" or "unixmsrnd6" (for ), script for (in PRO version only) Attributes: none Defaults: : false : empty : false : false : 1000000 : none : none These seven tags specify how Synthesis Sync Server obtains a new local ID (unique key into the data table) when inserting new data records. Basically, depending on the database used, the next ID for an INSERT statement must be either obtained before doing the insert (e.g. in Interbase/Firebird or Oracle by using a generator, or by using a random generator) or the database generates a key automatically when the INSERT occurs, and this key must be obtained afterwards (e.g. with MS SQL server's identity columns or MySQL auto_increment). Unfortunately, some desktop databases like Filemaker Pro do not provide proper support for obtaining the ID of a new records, or are terribly slow in doing so. For these, the very special and options can provide a solution that is usable, but not fully multi-user proof (see example). The options are used as follows: must be set to "no" when the key value must be obtained before doing an INSERT statement (e.g. Interbase/Firebird or Oracle case). If so, the statement (see  REF _Ref66078569 \r \h 12.20.16) must contain a statement (usually a INSERT) that sets a value for the key field (normally using the %k placeholder, see  REF _Ref47173394 \r \h 12.1.3). must be set to "yes" if the key value is generated automatically by the database at INSERT and can be obtained afterwards (SQlite, MS SQL or MySQL case). If so, the statement should not write to the key field but rely on the database to fill it appropriately. can be set to "yes" if the statement (see  REF _Ref66078569 \r \h 12.20.16) returns the new ID in a result set (single row, first column). This can be useful if insert is implemented using a stored procedure returning the new local ID. If this is set to true, the is not executed. must be an SQL query that returns a single row with a single column containing the local ID (data table key value). Depending on the setting of , this SQL query is executed before or after doing an INSERT. Note that for SQLite, this is not available – the ROWID of the last insert is always obtained using sqlite3_last_insert_rowid() SQLite API function. should never be set in multi-user environments. If set, the sync server executes the only once at the beginning of the sync session, expecting a numeric starting value for keys. Keys for new records are then generated by incrementing this number. This can be useful for accessing desktop databases which do not have a proper mechanism for generating unique keys. The SQL could be something like "SELECT MAX(ID) FROM DATA_TABLE". Of course, this will not work when the database is accessed by more than one application simultaneously. is only relevant when is set. It can be used to specify a minimum integer value to be used for the next id. If the result returned by executing the statement is numerically less than , the value from will be used as starting value for generating IDs. This is useful for desktop databases that have some auto-increment feature for generating IDs, but no way to properly obtain the ID via ODBC (Filemaker Pro 5.0 for example). With specifying a high , one can guarantee in a single user environment that IDs generated by the internal autoincrement feature and those generated by the sync engine do not conflict. Inserts done by the desktop database itself will have autoincrement IDs (say starting at 1), and because of a high (say 1000000), inserts done by the sync server will get IDs starting at 1000000. With "SELECT MAX(ID) FROM DATA_TABLE" as , the sync server is able to properly continue numbering new items, while the database itself uses some internal counter for the autoincrement field which is way below 1000000. can be set to "unixmsrnd6" to have pseudo-random IDs generated as follows: UNIX-style time() is multiplied by 1000000 and then a 6-digit random number is appended. This gives a very high probability that all IDs generated this way are unique. If is not "none", the is notused for obtaining an ID. can be used to implement a completely custom method of obtaining a new ID for a new record. This script is executed before is executed. If it has a return value, it is used as the local ID for the record to be added, unless is specified as well (in this case, the result of will override the return value of the - the script might still be useful in case some preparation is required before executing ). Usually however, either or will be used. Example for MS SQL Server (ID must be obtained after insert): yes SELECT @@IDENTITY AS ID Example for Interbase / Firebird (ID must be generated before insert by calling a stored procedure): no SELECT * FROM NEXT_CONTACT_KEY Example for Filemaker Pro (non-multiuser, lacks proper ID mechanisms) yes SELECT MAX(CONTACT_KEY)+1 FROM SYNC_CONTACTS 1000000 XE "map" \f T: SQL specific field mapping features Contained in: , Can contain: nothing Attributes: SQL specific: readblobsql, keyfield plus standard attributes: name, references, type, mode, size, truncate (see  REF _Ref47173451 \r \h 11.34.41.1) This tag establishes a link between an internal field as defined in a 's tag (see  REF _Ref47173292 \r \h 10.2) and a field in the datastore's user data table (SQL database table field or plugin data field). The tag in SQL datastores can have the following extra attributes (in addition to the standard attributes explained in  REF _Ref47173451 \r \h 11.34.41.1): "readblobsql": This allows specifying a SQL statement for fetching only the mapped field from the database. It must contain a SQL statement (usually a SELECT) that returns exactly one row with exactly one column. This mechanism is intended to read large text and BLOB fields from the database only when needed. Unlike most small strings and other fields that are always required for slow sync comparison etc., large BLOBs and text field's contents are often only needed when actually transmitting them to the remote party. So specifying "readblobsql" prevents unneeded reading of large data chunks and thus increases memory efficiency and performance. Note that the "readblobsql" will usually not be executed when reading other fields, but probably much later in the process of the sync session. "keyfield": this must be specified if the "readblobsql" needs a special key value to be retrieved independently from the main record. If "keyfield" is specified, the %N list of fields when fetching the main record will contain the name of the keyfield (instead of the name of the content field itself). The value returned from the keyfield can then be used in the "readblobsql" statement using the %K placeholder. Note that for BLOBs that are contained in the main record, "keyfield" can usually be left empty, as the main record key %k can be used to address them. However if the BLOBs are in a detail table (see  REF _Ref153765172 \r \h 12.20.20), the "keyfield" mechanism is important to obtain the correct key for individually reading the BLOBs of an array. Example 1: the PHOTO field of a vCard (key is the main record key, so no "keyfield" is required: Example 2: the CONTENTS for email Attachments, which are in a detail table ( map, see  REF _Ref153765172 \r \h 12.20.20). Here a "keyfield" is required, as the key for fetching the contents is NOT the main record key, but the key in the secondary table (here: ATTS_KEY): … other maps … XE "array" \f T: definition of master - detail record structures Contained in: Available: in PRO versions only Can contain: , , , , , , , , , , , Attributes: sizefrom The tag has the following optional attribute: "sizefrom": this can be used to specify either an array field (usually one of the detail fields ed in the ) which is used to determine the size of the array when writing detail records. Alternatively, this can specify an integer field, which is then used as array size - it will receive the number of detail records read after a read operation and will be used to determine how many detail records must be written. An array is a powerful means to map an internal item (consisting of the fields defined in a , see  REF _Ref42589436 \r \h 10.1) not only to a single database record, but to a master record having one or several detail records. For example, a database for contact information could store the contact's name in the master record, but have an unlimited number of attached detail records for each phone number relevant to that contact. Another example are calendar databases that store alarm information in a table separate from the main event table. An array can contain several tags that control how and if detail records are accessed (see  REF _Ref47867141 \r \h 12.20.21 and  REF _Ref47867143 \r \h 12.20.22) and also contain tags for SQL statement to actually access the detail table  REF _Ref47867144 \r \h 12.20.23). An array must also contain tags that map internal fields (and local variables of the ODBC database context) to the columns of the detail table. As an array might have multiple elements, must either map array columns to array fields or it must map to the first in a block of fields with same type (such that the second and further array elements can be stored in the second and further s in that block). The following step-by step description shows how works for reading and writing. When an item is read from the database, the following happens: The master record is read using the statement (see  REF _Ref47784098 \r \h 12.20.15) If defined, the of the is executed. If this script returns false, processing continues at  REF _Ref47867609 \r \h 13. The statement (see  REF _Ref47867926 \r \h 12.20.23) is executed to fetch all detail records related to the current master record. An internal array index is reset to zero. If the result set contains no more rows, processing continues at  REF _Ref47871470 \r \h 11. A row from the result set returned by the statement is stored in the fields as defined with the s of the . If a mapped field is an array field, the internal array index is used as array index for the field. If the mappe field is a non-array field, the internal array index is used as an offset which will be added to the position of the mapped field in the (therefore, second and further elements of the array will be stored in the s following the mapped in the . Note that if a within an references a local script variable rather than a field from the , the array index is irrelevant if the local variable referenced is not an array variable. If defined, the of the is executed The internal array index is incremented by the value defined with (default = 1). If the number of array elements processed is less than the number defined with (and is not 0, meaning unlimited), processing continues at  REF _Ref47871522 \r \h 5. If the "sizefrom" attribute was set to a non-array field, the number of array elements read will be stored in it. If the has returned no rows, the (see  REF _Ref47867954 \r \h 12.20.22) is applied to the data item in make-pass mode (see  REF _Ref47262189 \r \h 7.1 for details about filters). If defined, the of the is executed If defined, the of the is executed Now, reading the item is complete. When an item is written to the database, the following happens: If defined, the of the is executed The master record is written to the database using the or statements (see  REF _Ref47784099 \r \h 12.20.16). If defined, the of the is executed. If this script returns false, processing continues at  REF _Ref63052833 \r \h 14. Note that before Version 2.1.1.24, the was executed only after issuing the (see step  REF _Ref130893908 \r \h 4), so returning false from the for an update always caused deleting all existing detail records. From Version 2.1.1.24 onwards, returning false from the causes not touching the details records at all. If the write operation is an update, the statement of the is executed (If is set to true, the is also executed for inserts, see  REF _Ref207637531 \r \h 12.20.24). Note that updating the detail records always includes deleting all existing detail records and then creating new ones with updated detail data. If the is defined, it is applied in test mode to the data item. If the item passes the filter, this means that no detail records are needed and therefore processing continues at  REF _Ref63052833 \r \h 14. An internal array index is reset to zero. If defined, the of the is executed. If this script returns false, processing continues at  REF _Ref47869783 \r \h 13. If all fields that are mapped with for write in the are empty and the number of detail records is neither defined by a "sizefrom" field in the nor with a , processing continues at  REF _Ref47871769 \r \h 11. If all fields that are mapped with for write in the are empty and is false, processing continues at  REF _Ref47871769 \r \h 11. The statement (see  REF _Ref47867926 \r \h 12.20.23) is executed to insert one array element. The insert statement must make sure that the detail records are somehow related to the master record, for example by linking them with the master record's key (%k placeholder). The placeholders %v and %V will contain values as defined with the s of the . If a mapped field is an array field, the internal array index is used as array index for the field. If the mapped field is a non-array field, the internal array index is used as an offset which will be added to the position of the mapped field in the (therefore, second and further elements of the array will be stored in the s following the mapped in the . Note that if a within an references a local script variable rather than a field from the , the array index is irrelevant if the local variable referenced is not an array variable. As a consequence, mapping a local variable in an means that the array has no "natural" size (as any array index will at least get a value from the local variable), so it is essential to use or the "sizefrom" attribute in to limit the number of array elements written to the database! The internal array index is incremented by the value defined with (default = 1). If the number of array elements processed is less than the number defined by the "sizefrom" field and less than specified with , processing continues at  REF _Ref63053303 \r \h 7. If defined, the of the is executed Now, writing the item is complete.  XE "maxrepeat" \f T ,  XE "repeatinc" \f T ,  XE "storeempty" \f T : detail record storage options Contained in: Available: in PRO versions only Can contain: number (for maxrepeat and repeatinc), boolean value (for storeempty) Attributes: none Default: maxrepeat=1, repeatinc=1, storeempty=false These tags control how stores data in detail tables: defines the maximum number of detail records for the . If this is set to 0, this means that the number is not fixed, but rather depending on how many non-empty detail records can be written or on the "sizefrom" attribute in . We recommend specifying the "sizefrom" attribute (see  REF _Ref47864390 \r \h 12.20.20) when using =0. defines the increment for the array index (default is 1). This makes sense if the ed fields are not array fields and therefore the array index is used as a offset in the field list. can be set to true to have even elements with all ed fields empty stored as array element in the detail table. If is set to false, all empty elements will not be stored in the database.  XE "noitemsfilter" \f T : detail record storage filter Contained in: Available: in PRO versions only Can contain: filter expression (see  REF _Ref46752884 \r \h 7) Attributes: none Default: none This filter is applied in test mode to check if an contains any elements. If the data item passes this filter, the SyncML engine assumes the item has no array elements. See in  REF _Ref47872399 \r \h 12.20.20 for details.  XE "selectarraysql" \f T ,  XE "deletearraysql" \f T ,  XE "insertelementsql" \f T : detail record SQL Contained in: Available: in PRO versions only Can contain: SQL statements Attributes: none Default: none These statements are used to read, delete or insert array elements. See in  REF _Ref47872399 \r \h 12.20.20 for details.  XE "alwaysclean" \f T : clean detail records on insert Contained in: Available: in PRO versions only Can contain: boolean value Attributes: none Default: false If this is set to true, the will be executed even after inserting a new master record. Usually, when a master record is inserted, no child records related to it already exist and therefore executing in these cases is not necessary (but was always performed before version 3.1.6.12).  XE "optionfilterscript" \f T : prepare SQL filter according to options Contained in: Available: in PRO versions only Can contain: script Script context: database context Attributes: none Default: no script This script is called once before any reading or writing takes place. It should check the user options that might restrict the data to be fetched from the database, such as STARTDATE(), ENDDATE(), NOATTACHMENTS() and similar. If it is possible to generate an SQL expression that can be used in a WHERE clause (see %AF and %WF placeholders in  REF _Ref47173394 \r \h 12.1.3), the script should use SETSQLFILTER() to specify the expression and return TRUE. If it is not possible to create an appropriate filter expression, the script must return FALSE or nothing. The has access to the database context specific functions described in  REF _Ref153776799 \r \h 11.34.41.3.  XE "server type=textdb"\f T ,  XE "client type=textdb" \f T : Text File Based Server or Client Contained in: Available: Is no longer available in version V3.0, replaced by „textdb“ plugin, see  REF _Ref133745663 \r \h  \* MERGEFORMAT 14. and can be defined as plugin params of the plugin module  XE "server type=plugin"\f T ,  XE "client type=plugin"\f T : Plugin Based Server or Client Config Contained in: Can contain: tags described in this chapter (see also  REF _Ref47164079 \r \h 11, and  REF _Ref90895285 \r \h 16 specifically for clients) Attributes: type="plugin" This chapter describes the tags available for the configuration of a plugin based server or client. Plugins are additional modules, which will be accessed thru a standardized interface. The details of this interface are described in the SDK_manual.pdf (Reference Manual for Software Development Kit and Plugin Interface of the Synthesis Sync Engine). One member of the plugin family is the „textdb“, which is the replacement for the implementation in the 2.1.X servers/clients. Plugins are either built-in (e.g.: „textdb“; replacement for the former server type „textdb“) external modules (DLLs / shared libaries; e.g.: samples of the SDK package) plugin module: global settings Contained in: , Can contain: Default: empty built-in module called „no_dbapi“ w/o functionality  XE "plugin_module" \f T  The plugin name can either refer to an external module, which will be linked dynamically (example: SDK_textdb), or as built-in module using the bracket notation (example: [SDK_textdb]). While external plugin modules can be added individually by the customer, the built-in modules are integrated by Synthesis AG only. Built-in modules are: the empty default adapter „no_dbapi“ the text db plugin „SDK_textdb“ , available in demo/STD/PRO server/desktop client, see also  REF _Ref133810323 \r \h 14.3 the Java/JNI interface „JNI“ ( PRO server/desktop client only ).  XE "plugin_sessionauth" \f T  By default, the session authenitification ( login / logout ) will be done by the underlying layer (ODBC for the STD and PRO server, see  REF _Ref43727921 \r \h 12.16). By setting to yes, the authentification of the plugin module will be activated: yes  XE "plugin_deviceadmin" \f T  By default, the device administration (nonce handling, getting DB time, saving device info) will be done by the underlying layer ( ODBC for the STD and PRO server ). By setting the tag to yes, the device administration of the plugin module will be activated: yes  XE "plugin_params" \f T  All plugin specific parameters must be passed as within . They will be passed as a string to the plugin module. See description of the used plugin module for the details of these parameters. Example: /var/log/sysync  XE "datastore type=plugin" \f T : Plugin Datastore specific settings Contained in: Attributes: name, type Can contain: Default: not specified This chapter describes the tags that are specific to plugin based datastores. See  REF _Ref45367951 \r \h 11.34 for a description of the tag in general.  XE "plugin_deviceadmin" \f T  By default, the datastore administration ( ADM / MAP tables ) will be done by the underlying layer ( ODBC for the STD and PRO server ). By setting the tag to yes, the datastore administration of the plugin module will be activated: yes NOTE: If this flag is set, the params of  REF _Ref133832449 \r \h 14.2.5 will not be considered.  XE "plugin_module" \f T  For details see  REF _Ref133830177 \r \h 14.1.1  XE "plugin_params" \f T  All plugin specific parameters for this datastore must be passed within . For details see  REF _Ref133831852 \r \h 14.1.4.  XE " plugin_debugflags " \f T  16 plugin specific flags can be defined for plugin debug logging. Two of these bits ( bit 0 and bit 1 ) are predefined and reserved: bit 0 is used for all plugin interface logging (which is part of the SyncML engine), bit 1 is an unspecific DB flag, which will be used in all the plugin examples. The flags must be defined in hexadecimal representation. Example: 0x0501 ( Bits 0, 8 and 10 are set If is not defined, ALL plugin specific flags are set ( 0xffff ). NOTE: To activate any plugin logging, the global flag "plugin" must be set. "plugin" will be activated also together with some combined groups. For details see the description ( REF _Ref47170147 \r \h 8.11): ... ...  XE "plugin_moduleadmin" \f T , XE "plugin_paramsadmin" \f T , . For this case and will be used. If only is defined, but not , the datastore data will be handled by the underlying layer (which is ODBC for the STD and PRO server ). An overview is given in the table below: DATAADMIN--falseODBCODBCaa-falseaaODBC-bbfalseODBCbbaabbfalseaabb--trueODBCODBCaa-trueaaaa-bbtrueODBCODBCaabbtrueaaaaXE "plugin_module" \f Tplugin module “SDK_textdb” The built-in plugin module „SDK_textdb“ acts as the db interface for the „demo“ server/desktop client, but is also available in the STD and PRO servers/desktop clients Files of the textdb The „textdb“ creates 5 different files: TDB_uuu_datastorename.txt uuu = userKey BLB_uuu_datastorename_itemid_fieldid DEV_ddd.txt ddd = deviceKey ADM_ddd_uuu_datastorename.txt MAP_ddd_uuu_datastorename.txt The most important one is the TDB_*.txt file, which contains the data for each datastore. The file format has the same structure as the former textdb data file: The first column is the GUID (object identifier on the server), which is an integer number in the SDK_textdb implementation (starting at 10000). The second column is the modification timestamp in ISO8601 format, UTC (you would need to update this in order to mark a record modified). All following columns contain the data fields in the order as defined in the corresponding (see  REF _Ref6030571 \r \h 10.1). uuu is the userKey, resulting from Login( username,password ). It must be unique for each user. The ddd part of the name is derived from the client's DeviceID (which should be, in theory, unique). Login( „test“,“test“ ) is hardwired in this textdb and results in uuu=“test“. The DEV_*.txt file holds the device information, ADM_*.txt / MAP_*.txt contain the administration data for each device and user and datastore (if datastore admin is switched on). Normally no reason exists to edit these files. PluginParams of the textdb Plugin specific params are defined for the (see  REF _Ref135023800 \r \h 14.2.3): : The data files TDB_* can be chosen specifically. If this tag is not defined, data files will be stored at the current path of the SyncML engine. This plugin param replaces the former of the old textdb. : The BLOB files BLB_* can be chosen specifically. If this tag is not defined, BLOB files will be stored at . This plugin param was not available for the old textdb (because BLOBs were not supported there). : The map/admin files MAP_*, ADM_* and DEV_* can be chosen specifically. If this tag is not defined, data files will be stored at . This plugin param replaces the former of the old textdb. Some legacy params, do not use them any more for new applications: : path for TDB/BLB/MAP/ADM/DEV files ( Linux, MacOSX ) : path for TDB/BLB/MAP/ADM/DEV files ( Windows ) If platform specific data/map file paths are needed, use the platform attribute (see  REF _Ref153284855 \r \h 4): Example: D:\projects\maps XE "plugin_module" \f Tplugin module “FILEOBJ” Files of the fileobj modules The FILEOBJ plugin is able to handle OMA DS 1.2 file objects. The items will be stored as real files, when possible with their correct name, file date and attributes. So with this plugin module, a file sync via SyncML is possible. NOTE: Using OMA DS 1.2 FILEOBJ do not require necessarily a FILEOBJ plugin, the objects can alternatively be stored as BLOBs within an ODBC data structure. Even the textdb implementation is able to store these file objects.  XE "client" \f T ,  XE "server" \f T : Synthesis SyncML Engine library only configuration tags Contained in: of a Synthesis SyncML Engine library based client or server. Can contain: tags described in this chapter (see also  REF _Ref47164079 \r \h 11,  REF _Ref47164085 \r \h 12 and  REF _Ref135023442 \r \h 14 for settings not specific to SyncML engine library based clients) Attributes: type (see  REF _Ref47164079 \r \h 11 for details)  XE "binfilespath" \f T : Path for persistent storage of client settings and admin data Contained in: Can contain: path of a directory where client engine library can read and write Default: platform's default location for storing application data The Synthesis SyncML Client Engine Library usually comes with built-in management for persistent, but user changeable settings, organized in so-called "profiles" and "targets" (for details about the Synthesis SyncML Client Engine Library, please refer to the SDK documentation ( HYPERLINK "SDK_manual.pdf" SDK_manual.pdf). This setting information, along with some internal SyncML administration data like changelogs is stored in binary files. The tag is used to specify a directory where the client engine library can store these files. If is not explicitly set, the platform's default path for storing an application's data or preferences is used (the same path as represented by the $(appdata_path) config variable, see  REF _Ref184460000 \r \h 4.4)  XE "binfilesactive" \f T : enable binfile based admin Contained in: Can contain: boolean value Default: true for clients (false for server) This can be set to false to disable the binfile admin data handling, and use admin storage implemented as SQL tables or in a plugin (like textdb). This can make sense when using the engine as client and server for the same database. Disabling the binfiles layer makes the engine behave like the command line client products (where remote server URL, login etc. is all defined in the XML config (see  REF _Ref90895148 \r \h 16).  XE "crcchangedetection" \f T : enable CRC based change detection Contained in: Can contain: boolean value Default: false This can be set to true to make the SyncML engine detect changes by calculating CRC checksums of all records. If this option is enabled, the underlying database (SQL or plugin) does not need to have a reliable last-change date. The engine will always query all records from the database before each sync to calculate CRCs, which then are compared with stored CRCs to detect changes.  XE "client" \f T : Command line client-only configuration tags Contained in: of a command line Synthesis SyncML client or Synthesis SyncML engine library with set to false (see  REF _Ref247361078 \r \h 15.2). Can contain: tags described in this chapter (see also  REF _Ref47164079 \r \h 11,  REF _Ref47164085 \r \h 12 and  REF _Ref135023442 \r \h 14 for settings not specific to command line clients) Attributes: type (see  REF _Ref47164079 \r \h 11 for details)  XE "defaultsyncmlversion" \f T : Set default SyncML Version to start a session Contained in: Can contain: SyncML version string, currently "1.0", "1.1" or "1.2" Default: Higest version supported by client. This specifies the SyncML version that is used in the first attempt to contact a SyncML server. By default, this is the highest version supported by the client (1.2 at this time). When session initialisation fails with a SyncML version, the client automatically re-tries with the next lower SyncML version. Only if you e.g. want to prevent attempts for SyncML 1.2 or 1.1 completely, this can be set to 1.1 or 1.0, resp.  XE "defaultauth" \f T : Set default auth method Contained in: Can contain: SyncML auth method: "none", "basic", "md5" Default: "none". This specifies the SyncML auth method that is used in the first attempt to login with a SyncML server. When login fails, the server will return a challenge for the required auth method, and the client will login according to that challenge. Another setting than "none" should be used only for special testing situations. In particular, using "basic" comprises a security risk as this means the client will send credentials in decodable form.  XE "defaultauthencoding" \f T : Set default auth encoding Contained in: Can contain: SyncML encoding: "chr", "bin", "b64" Default: "chr". This specifies the encoding for the SyncML auth credentials that is used in the first attempt to login with a SyncML server. When login fails, the server will return a challenge for the required auth encoding, and the client will login according to that challenge. This setting should be changed only for special testing situations.  XE "defaultauthnonce" \f T : Set default nonce Contained in: Can contain: nonce to use for first MD5 login attempt Default: "chr". This is relevant only if is set to "md5". Then the specified string will be used as nonce for the MD5 login attempt. In normal use, the nonce is always sent by the server in the challenge, and is not known in advance. Therefor, this setting is useful only for special testing situations.  XE "newsessionforretry" \f T : Use a new sessionID for retries Contained in: Can contain: boolean value Default: true If this is set, retries (due to auth failure) are done with a completely new SyncML session (different session ID). If this is set to no, the retry is done with the same session ID as the initial attempt (so it looks like continuing the session). Only some special testing tools may require this.  XE "originaluriforretry" \f T : Use original URI for retry Contained in: Can contain: boolean value Default: true If this is set, retries (due to auth failure) are done to the original URI as specified in the (see  REF _Ref153889197 \r \h 16.12). If this is set to no, the retry is done with the URI returned by the server in the element. Only some special testing tools may require this.  XE "smartauthretry" \f T : Use smart retry attempt variations Contained in: Can contain: boolean value Default: true If this is set, after doing the regular retries in the way configured with (see  REF _Ref232415540 \r \h 16.5) and (see  REF _Ref232415549 \r \h 16.6), the client also does some more retry attempts with varied behaviour. In particular, is inverted for the additional retries, and will be set to the same (inverted) value of . Future versions might add more elaborate retry attempts when is set. Note that this helps to get authorized with servers that have problem with either type of retry (in-session or fresh-session).  XE "putdevinfatslowsync" \f T : Always send Device Info at Slowsync Contained in: Can contain: boolean value Default: true If set to true, the client will always send it's Device Info (DevInf) to the server when a slow sync is performed. If set to false, the client will send the DevInf only in the first sync session with a server or when explicitly requested by the server.  XE "localdbuser" \f T ,  XE "localdbpassword" \f T : Login to local database Contained in: Can contain: user, password Default: none This information is used to login the client locally with the database. This is needed because the SyncML client can connect to a multi-user-database, but will usually synchronize only one user's data in a given sync session. These tags are required to specify which user's data the sync session operates on.  XE "nolocaldblogin" \f T : Prevent local DB login Contained in: Can contain: boolean value Default: false If set to false, the client will not perform the login steps to the local database. This can be useful when the underlying database is a single-user database. Note that the sample database layouts delivered with the Synthesis SyncML client are designed for multiple users and therefore need local login.  XE "syncmlencoding" \f T : SyncML encoding format Contained in: Can contain: "xml" or "wbxml" Default: "xml" This can be used to select either the plain text (but bandwidth wasting) XML format or the much more efficient, but not human-readable binary WBXML format. For any application but server debugging, this should be set to WBXML.  XE "serverurl" \f T : Remote SyncML server URL Contained in: Can contain: URL Default: none This is the remote SyncML server's URL for use with command line clients which specify the server details in the configuration. For clients based on Synthesis SyncML client engine, the URL and other settings are specified in profile settings, not the config file. Still, this tag can be used to "hard-code" the server URL so the client can only be used for a specific server. All clients support http URLs, some clients also support the following special URLS: SSL-enabled clients also support URLs beginning with "https://" instead of "http://" OBEX-over-infrared enabled clients support the special "obex:irda" URL. OBEX-over-TCP enabled clients support the special "obex:xxxx" URL, where xxx is the name or IP address of the OBEX server.  XE "serveruser" \f T ,  XE "serverpassword" \f T : Login to remote SyncML server Contained in: Can contain: user, password Default: none Available in: command line based clients This information is used to login the client with the remote SyncML server.  XE "sockshost" \f T ,  XE "proxyhost" \f T : Proxy servers Contained in: Can contain: proxy server addresses Default: none Available in: command line based clients These can be used to specify a SOCKS or HTTP proxy server to be used.  XE "proxyuser" \f T ,  XE "proxypassword" \f T : Proxy auth Contained in: Can contain: proxy server user and password (if required) Default: none Available in: command line based clients These can be used to specify a SOCKS or HTTP proxy server to be used.  XE "transportuser" \f T ,  XE "transportpassword" \f T : Login to remote SyncML server Contained in: Can contain: user, password Default: none Available in: command line based clients This information is used for HTTP authentification if the server addressed by needs this.  XE "syncrequest" \f T : Request to sync a datastore Contained in: Can contain: , , , Attributes: datastore Default: none Available in: command line based clients This tag specifies a Sync request for one of the s (see  REF _Ref45367951 \r \h 11.34) available to the client. The "datastore" attribute must reference one of the s defined further up in the configuration file. Multiple tags are allowed to synchronize multiple datastores in a single session (however, each datastore may only be synced once per session).  XE "dbpath" \f T : path of remote server's datastore Contained in: Can contain: remote server db path string Default: empty Available in: command line based clients This tag specifies the path that is used to address the remote server's datastore that should be synchronized with the local datastore identfied by the "datastore" attribute in the enclosing . Usually, this is a simple string like "contact", "events", "emails" etc. But some server support structured paths like "contacts/private", "emails/office" or even CGI-style filtering like "contacts?LAST=Miller". If the server happens to be a Synthesis SyncML server, you can refer to  REF _Ref46896711 \r \h 7.4 to see what options are possible.  XE "syncmode" \f T : Synchronisation mode Contained in: Can contain: "twoway", "fromclient" or "fromserver" Default: "twoway" Available in: command line based clients This can be used to select between three basic sync modes: "twoway" means that changes made on the client are sent to the server and changes made to the server are sent to the client. "fromclient" means that only changes made to the client are sent to the server. Changes made on the server will be ignored. Sometimes called "update server only" mode. "fromserver" means that only changes made to the server are sent to the client. Changes made on the client will be ignored. Sometimes called "update client only" mode. Note: "fromclient" in conjunction with (see  REF _Ref90894483 \r \h 16.17.3) set to true will cause the server database to be completely overwritten with the contents of the client database (also called "refresh from client" or "reload server"). Likewise, "fromserver" in conjunction with set to true will cause the client database to be completely overwritten with the contents of the server database (also called "refresh from server" or "reload client"/"reload device").  XE "slowsync" \f T : Force a slow sync Contained in: Can contain: boolean value Default: automatically determined Available in: command line based clients This can be used to explicitly request a slow sync. Slow sync means that all data on the client and the server are exchanged. In a two-way slow sync, the result will be the union of all client and all server data. In a one-way (from server or from client) sync, the result is that either side (client or server) is totally overwritten with the data from the other side. See ( REF _Ref90894479 \r \h 16.17.2) for more information.  XE "localpathextension" \f T : local datastore options Contained in: Can contain: local db path extension Default: empty Available in: command line based clients This tag specifies extra information for addressing the local datastore. Usually, this is empty. But if your local database makes use of multiple folders per user (see description of our standard database layout for SyncML in the client or server installation manual delivered with the software), you can specify the folder here. Likewise, if your local datastores support filtering (see  REF _Ref46896711 \r \h 7.4), you can specify the required CGI to activate the filters here. Note that the same kind of options might be available at the remote server's side, but then they need to be specified as part of .  XE "recordfilter" \f T : define SyncML DS 1.2 record filter Contained in: Can contain: Filter expression Default: none Available in: command line based clients This tag can be used to specify a SyncML DS 1.2 exclusive filter expression (see  REF _Ref153291752 \r \h 7.4 for syntax and  REF _Ref46752884 \r \h 7 for general information about filters). This is relevant only for sync sessions with SyncML DS 1.2 capable servers.  XE "recordfilterinclusive" \f T : define inclusive SyncML DS 1.2 record filter Contained in: Can contain: Filter expression Default: none Available in: command line based clients This tag can be used to specify a SyncML DS 1.2 inclusive filter expression (see  REF _Ref153291752 \r \h 7.4 for syntax and  REF _Ref46752884 \r \h 7 for general information about filters). This is relevant only for sync sessions with SyncML DS 1.2 capable servers. List of built-in timezones Special names SYSTEM DATE FLOATING USERTIMEZONE Name east of UTC Afghanistan 4.5 AKST/AKDT -9 HNY/NAY -9 Alaskan -9 Arab 3 Arabian 4 Arabic 3 AST/ADT -4 HNA/HAA -4 Atlantic -4 AUS_Central 9.5 AUS_Eastern 10 Azerbaijan 4 Azores -1 Canada_Central -6 Cape_Verde -1 Caucasus 4 ACST/ACDT 9.5 Central_Australia 9.5 Central_America -6 Central_Asia 6 Central_Brazilian -4 CET/CEST 1 MEZ/MESZ 1 Central_Europe 1 Central_European 1 Central_Pacific 11 CST/CDT -6 HNC/HAC -6 Central -6 Central_Mexico -6 China 8 Dateline -12 East_Africa 3 AEST/AEDT 10 East_Australia 10 EET/EEST 2 East_Europe 2 East_South_America -3 EST/EDT -5 HNE/HAE -5 Eastern -5 Egypt 2 Ekaterinburg 5 Fiji 12 FLE 2 Georgian 3 GMT 0 Greenland -3 Greenwich 0 GTB 2 HAST/HADT -10 Hawaiian -10 India 5.5 Iran 3.5 Israel 2 Jordan 2 Korea 9 Mexico -6 Mexico_2 -7 Mid_Atlantic -2 Middle_East 2 Montevideo -3 MST/MDT -7 HNR/HAR -7 Mountain -7 Mountain_Mexico -7 Myanmar 6.5 North_Central_Asia 6 Namibia 2 Nepal 5.75 New_Zealand 12 NST/NDT -3.5 HNT/HAT -3.5 Newfoundland -3.5 North_Asia_East 8 North_Asia 7 Pacific_SA -4 PST/PDT -8 HNP/HAP -8 Pacific -8 Pacific_Mexico -8 Romance 1 Russian 3 SA_Eastern -3 SA_Pacific -5 SA_Western -4 Samoa -11 SE_Asia 7 Singapore 8 South_Africa 2 Sri_Lanka 5.5 Taipei 8 Tasmania 10 Tokyo 9 Tonga 13 US_Eastern -5 US_Mountain -7 Vladivostok 10 West_Australia 8 West_Central_Africa 1 WET/WEST 1 West_Europe 1 West_Asia 5 West_Pacific 10 Yakutsk 9 A 1 ACDT 10.5 ACST 9.5 ADT -3 AEDT 11 AEST 10 AKDT -8 AKST -9 AST -4 AWST 8 B 2 BST 1 C 3 CDT -5 CEST 2 CET 1 CST -6 CXT 7 D 4 E 5 EDT -4 EEST 3 EET 2 EST -5 F 6 G 7 H 8 HAA -3 HAC -5 HADT -9 HAE -4 HAP -7 HAR -6 HAST -10 HAT -1.5 HAY -8 HNA -4 HNC -6 HNE -5 HNP -8 HNR -7 HNT -2.5 HNY -9 I 9 IST 1 K 10 L 11 M 12 MDT -6 MESZ 2 MEZ 1 MST -7 N -1 NDT -1.5 NFT 11.5 NST -2.5 O -2 P -3 PDT -7 PST -8 Q -4 R -5 S -6 T -7 U -8 UTC 0 V -9 W -10 WEST 1 WET 0 WST 8 X -11 Y -12 Z 0 Error codes This section lists the error codes that can occur (normally visible in the logs or on the console). SyncML Status Codes These codes are defined by the SyncML standard. For details, see HYPERLINK "http://www.openmobilealliance.org/release_program/ds_v12.html" http://www.openmobilealliance.org/release_program/ds_v12.html. Note that this list is not complete, but only contains the codes that are important for the SyncML engine. 101 Server is busy (session limit reached, see  REF _Ref47451430 \r \h 8.2) 200 OK, successful operation 201 Item added 207 Conflict resolved with merge 208 Conflict resolved - client wins 209 Conflict resolved by duplicating item 210 Deleted without archive 211 Item not deleted 212 Authentication accepted for entire session 213 Chunked item accepted and buffered (this status is sent for each non-final part of a data item that has been split across multiple SyncML messages) 400 Bad request 401 Unauthorized (bad credentials) 403 Forbidden (e.g. attempt to write to a read-only database) 404 Object not found 405 Command not allowed 406 Optional feature not supported 407 Authentication required (no credentials found) 408 Timeout 409 Conflict, operation failed 410 Gone, requested object not here any more 412 Incomplete command 415 Unsupported media type or format 418 Object already exists 419 Conflict resolved with server data 420 Device full 500 Command failed 501 Command not implemented 503 Service unavailable 505 DTD version not supported 508 Slow sync required 509 Authentication required 510 Database error 511 Server error 512 Synchronisation failed 513 SyncML Version not supported 514 Cancelled Internal Error Codes 0 No error 10000..10999 These have the same meaning as the SyncML Status Codes (see  REF _Ref47451048 \r \h 18.1), but they are offset by 10000 to make clear that they were generated internally, and not sent or received via SyncML. 20001 Bad or unknown transport protocol 20002 Fatal problem with SyncML encoder/decoder 20003 Cannot open communication 20004 Cannot send data 20005 Cannot receive data 20006 Bad content type (message received with an unknown MIME-type) 20007 Error processing incoming SyncML message (for example invalid XML or WBXML formatting) 20008 Cannot close communication 20009 Transport layer authorisation (e.g. HTTP auth) failed 20010 Error parsing XML config file 20011 Error reading config file 20012 No configuration found at all, or not enough for requested operation (client) 20013 Config file could not be found 20014 License expired or no license found 20015 Internal fatal error 20016 Bad handle 20017 Session aborted by user 20018 Invalid license 20019 Limited trial version 20020 Connection timeout 20021 Connection SSL certificate expired 20022 Connection SSL certificate invalid 20023 incomplete sync session (some datastores failed, some completed) 20025 Out of memory 20026 Connection impossible (e.g. no network available) 20027 Establishing connection failed (e.g. network layer login failure) 20028 element is already installed 20029 this build is too new for this license (need upgrading license) 20030 function not implemented 20031 this license code is valid, but not for this product (e.g. STD license used in PRO product, or client license in server product) 20032 Explicitly suspended by user 20033 this build is too old for this SDK/plugin 20034 unknown subsystem 20036 local datastore not ready 20037 session should be restarted from scratch 20038 internal pipe communication problem 20039 buffer too small for requested value 20040 value truncated to fit into field 20041 bad parameter 20042 out of range 20043 external transport failure (no details known in engine) 20044 class not registered 20500..20599 These represent SIG_xxx codes in Linux versions of the SyncML engine. Unexpected SIG_xxx will generate a error code of 20500+signal_code. 20998 Internal unkown exception 20999 Unknown error 21000...21999 Database plugin module specific error codes Index Alphabetic Index of all config XML tags  INDEX \c "3" \f "T" abortonallitemsfailed 110 acceptfilter 121 acceptserveralerted 111 adminreadyscript 127 afterconnectscript 157 afterreadscript 138 alertprepscript 128 alertscript 127 allowempty 89 allowmessageretries 147 alwaysclean 182 alwayssendlocalid 119 appendtoexisting 61 array 179 attachmentcountfield 90 attachmentmimetypesfield 90 attachmentnamesfield 90 attachmentsfield 90 attachmentsizesfield 90 autoenddateinclusive 109, 149 automap 137 autononce 104 beforewritescript 139 bigendian 94 binaryparts 93 binfilesactive 189 binfilespath 189 bodycountfield 90 bodymimetypesfield 90 bufferretryanswer 69 cleartextpw 159 client 101, 189, 191 client type= 151 client type=odbc 151 client type=plugin 171, 184 client type=textdb 183 commititems 173 comparescript 98 completefromclientonly 147 configdate 65 configidstring 54 configvar 55 conflictstrategy 119 constantnonce 104 contains 142 crcchangedetection 189 customendputscript 106 customgethandlerscript 107 customgetputscript 106 customputresulthandlerscript 108 datacharset 131 datalineends 131 datasource 155 datastore 115 datastore type= 164 datastore type=odbc 164 datastore type=plugin 185 datastoreinitscript 123, 126 datatimezone 130 datatype 91 datatypes 72 dbcanfilter 172 dbconnectionstring 156 dbpass 157 dbpath 195 dbtimeout 157 dbtypeid 116 dbuser 156 debug 56 debugchunkmaxsize 109 defaultauth 191 defaultauthencoding 191 defaultauthnonce 192 defaultsyncmlversion 191 definetimezone 66 deletearraysql 182 deletedatasql 175 deletemapsql 169 deletewins 117 deletinggoneok 109 descriptivename 144 determineidonce 176 deviceid 144 devicetype 144 disable 57 dispatchfilter 142 displayname 117 ds12filters 121 dscgiindevinf 146 dspathindevinf 146 earlycommit 173 enable 57 enum 81 enumdefaultpropparams 111 externalurl 103 field 73 fieldlist 73 fieldmap 134 fileprefix 62 filesuffix 62 filterinitscript 95 filterscript 95 finalisationscript 140 finalrule 143 finishscript 141 firmware 143 firsttimestrategy 119 folderkeysql 164 folding 59 forcelocaltime 147 forceutc 148 fromremoteonlysupport 132 function 55 getdevicesql 160 globallogs 65 guidprefix 142 hardware 143 headertag 89 httpport 70 ignoreaffectedcount 175 ignoredevinfmaxsize 146 incomingscript 95 indentstring 63 inheader 89 initscript 94, 137 inputcharset 149 insertdatasql 175 insertelementsql 182 insertmapsql 169 insertreturnsid 176 invisiblefilter 122 ipaddress 70 keepconnection 68 lastmodfieldtype 169 legacymode 149 lenientmode 149 licensecode 53 licensename 53 limitedfieldlengths 144 linemap 88 localdbfilter 122 localdbpassword 193 localdbuser 193 localidscript 176 localpathextension 196 logenabled 112 logfile 111 logflushmode 61 logformat 59, 112 logincheckscript 162 loginfinishscript 114 logininitscript 114 loglabels 114 logpath 57 logsessionstoglobal 65 looptimeout 56 macro 56 makepassfilter 123 makevisiblefilter 123 manufacturer 54, 143 map 134, 178 maxattachments 90 maxconcurrentsessions 53 maxitemspermessage 118 maxmsgsize 53 maxobjsize 54 maxrepeat 181 maxsessionruns 71 maxsyncmlversion 101 maxthreads 71 md5hex 159 md5userpass 159 mergescript 99 mimedirmode 99 mimemail 90 mimeprofile 75 minnextid 176 minsyncmlversion 101 model 54, 143 modtimestamp 173 msgdump 64 multicursor 173 multithread 105 neverputdevinf 66 newdevicesql 160 newsessionforretry 192 nocontentfolding 148 noemptyproperties 145 noitemsfilter 181 nolocaldblogin 193 noreplaceinslowsync 146 numlines 88 obexservice 70 obtainidafterinsert 176 obtainlocalidsql 176 oem 143 optionfilterscript 127, 182 originaluriforretry 192 outgoingscript 95 outputcharset 149 parameter 82 plugin_debugflags 186 plugin_deviceadmin 185 plugin_module 184, 186, 187, 188 plugin_moduleadmin 186 plugin_params 185, 186 plugin_paramsadmin 186 plugin_sessionauth 185 position 84 preventconnectattrs 157 processitemscript 97 profile 76 property 77 protocol 69 proxyhost 194 proxypassword 194 proxyuser 194 putdevinfatslowsync 193 quotingmode 172 readonly 117 receiveditemstatusscript 106, 129 recordfilter 197 recordfilterinclusive 197 rejectstatus 150 remoterule 143 repeatinc 181 reportupdates 118 requestedauth 103 requestmaxtime 102, 150 requestmintime 102 requiredauth 103 resendfailing 129 respurionlywhendifferent 104 resumeitemsupport 133 resumesupport 133 rulescript 150 saveinfosql 160 savenoncesql 160 scripting 55 selectarraysql 182 selectdatasql 174 selectidandmodifiedsql 174 selectmapallsql 169 sendrespuri 104 sentitemstatusscript 106, 128 server 101, 189 server type= 151 server type=odbc 151 server type=plugin 184 server type=textdb 183 serverpassword 194 serverurl 194 serveruser 194 sessioninitscript 105 sessionlogs 64, 65 sessiontimeout 102 showctcapproperties 110 showthreadid 60 showtypesizeinctcap10 110 silentdiscard 122 simpleauthpw 105 simpleauthuser 105 singlegloballog 61 singlesessionlog 61 sizelimitfield 90 slowsync 196 slowsyncstrategy 119 smartauthretry 192 sockshost 194 software 143 specialidmode 176 sqlitebusytimeout 172 sqlitefile 171 storeempty 181 storelastsyncidentifier 133 storesyncidentifiers 133 subprofile 76 subthreadmode 62 superdatastore 141 syncmlencoding 193 syncmode 195 syncrequest 195 synctargetgetsql 165 synctargetnewsql 165 synctargetupdatesql 165 synctimestamp 169 synctimestampatend 132 systemtimezone 66 textauth 158 textmap 158 textpath 158 textprofile 88 timedsessionlognames 60 timestamp 60 timestampall 60 timestampsql 163 timestamputc 130, 163 timeutc 130 transactionmode 158 transport 68 transportpassword 195 transportuser 195 treataslocaltime 148 treatasutc 148 tryupdatedeleted 118 typestring 92 typesupport 120 unfloattimestamps 87 unicodedata 94 updateallfields 132 updateclientinslowsync 145 updatedatasql 175 updatemapsql 169 updateserverinslowsync 145 use 91, 120 userkeysql 161 usertimezone 109 userzoneoutput 130 value 79 valuetype 89 version 92 versionstring 92 vtimezonegenmode 87 waitforstatusofinterrupted 108 xmltranslate 63 zapdatasql 175 zipcompressionlevel 93 zippedbindata 93  Alphabetic Index of all built-in script functions INDEX \c "2" \f "F" ABORTDATASTORE 128 ABORTSESSION 43 ABS 43 ADDFILTER 124 ADDSTATICFILTER 124 ADDTARGETFILTER 124 ALERTCODE 125 ALLDAYCOUNT 39 APPEND 43 ARRAYINDEX 138 AUTHDEVICEID 114 AUTHOK 114 AUTHSTRING 114 AUTHTYPE 114 AUTHUSER 114 CHECKAUTH 115 COMPARE 43 COMPAREFIELDS 98 CONFLICTSTRATEGY 97 CONTAINS 43 CONVERTTOUSERZONE 42, 115 CONVERTTOZONE 42 DATEONLY 39 DAYUNITS 39 DBHANDLESOPTS 125 DBLITERAL 154 DBNAME 124 DBNOW 38 DBOPTIONS 124 DEBUGMESSAGE 42 DEBUGSHOWITEM 42 DEBUGSHOWVARS 42 DEFAULTSIZELIMIT 96, 125 DELETEWINS 97 DEVICEKEY 115 DURATION 39 ECHOITEM 97, 107, 108 ENDDATE 124 ENUMDEFAULTPROPPARAMS 44 EXPLODE 37 FIND 37 FIRSTTIMESYNC 125 FORCECONFLICT 97 FORCELOCALTIME 44 FORCEUTC 44 GETCGITARGETFILTER 123 GETDEBUGMASK 42 GETFILTER 124 GETTARGETFILTER 124 IGNOREUPDATE 98 ISAVAILABLE 43 ISDATEONLY 39 ISDURATION 39 ISFLOATING 41 ISRELATIVE 40 ITEMDATATYPE 45 ITEMTYPENAME 45 ITEMTYPEVERS 45 LASTKEY 138 LENGTH 37 LOCALDBNAME 124 LOCALID 97 LOCALIZEDASUTC 40 LOCALURI 44 LOCALZONEOFFSET 40 LOGSUBST 138 LOOSINGCHANGED 99 LOWERCASE 37 MAKE_RRULE 40 MAKEALLDAY 40 MAKEEMAILSPEC 37 mapredefine 134 MAXITEMCOUNT 125 MERGEFIELDS 99 MILLISECONDS 39 MONTHDAYS 39 NEWKEY 138 NOATTACHMENTS 125 NORMALIZED 37 NOW 38 NUMFORMAT 37 PARENTKEY 138 PARSE_RRULE 40 PARSEEMAILSPEC 37 POINTINTIME 39 PREVENTADD 98 RANDOM 43 RECURRENCE_COUNT 40 RECURRENCE_DATE 40 REGEX_FIND 38 REGEX_MATCH 38 REGEX_REPLACE 38 REGEX_SPLIT 38 REJECTITEM 97 RELATIVEASUTC 41 REMOTEDBNAME 124 REMOTEID 97 REMOTERULENAME 44 REQUESTMAXTIME 44 REQUESTMINTIME 44 RFIND 37 SECONDS 39 SESSIONVAR 44 SETALERTCODE 125 SETCONFLICTSTRATEGY 125 SETDBCONNECTSTRING 155 SETDBPASSWORD 155 SETDEBUGLOG 44 SETDEBUGMASK 43 SETDEBUGOPTIONS 43 SETDEFAULTSIZELIMIT 125 SETDEVICEKEY 115 SETDOMAIN 114 SETENDDATE 124 SETFILTER 124 SETFILTERALL 96 SETFLOATING 42 SETLOCALID 97 SETLOG 44 SETLOOSINGCHANGED 99 SETMAXITEMCOUNT 125 SETNOATTACHMENTS 125 SETREADONLY 44 SETRELATIVE 40 SETREMOTEID 97 SETSESSIONVAR 44 SETSIZELIMIT 96 SETSQLFILTER 138 SETSTARTDATE 124 SETSTATUS 128 SETTARGETFILTER 124 SETTIMEZONE 41 SETUSERKEY 115 SETUSERNAME 114 SETUSERTIMEZONE 42 SETWINNINGCHANGED 99 SETXMLTRANSLATE 43 SETZONEOFFSET 41 SHELLEXECUTE 44 SHOWCTCAPPROPERTIES 44 SIGN 43 SIZE 37 SLEEPMS 39 SLOWSYNC 125 SQLCOMMIT 155 SQLEXECUTE 154 SQLFETCHROW 155 SQLGETCOLUMN 155 SQLROLLBACK 155 STARTDATE 124 STATUS 128 STOPADDING 129 SUBSTR 37 SWAP 45 SYNCMLVERS 43 SYNCOP 97, 129 SYSTEMNOW 38 TIMEONLY 39 TIMEUNITS 39 TIMEZONE 41 TREATASLOCALTIME 45 TREATASUTC 45 TYPENAME 45 UNKNOWNDEVICE 115 UPDATECLIENTINSLOWSYNC 45 UPDATESERVEINSLOWSYNC 45 UPPERCASE 37 USERKEY 115 USERTIMEZONE 42 UTCASRELATIVE 41 VTIMEZONE 41 WEEKDAY 39 WINNINGCHANGED 99 WRITING 138 ZONEOFFSET 42  Page  PAGE 11 ©2002-2008 by Synthesis AG, Zürich, Switzerland – HYPERLINK "http://www.synthesis.ch/"www.synthesis.ch Page  PAGE 202 ©2002-2008 by Synthesis AG, Zürich, Switzerland – HYPERLINK "http://www.synthesis.ch/"www.synthesis.ch ()*+,-34|}¡¢£¤¥¦§¨ÆÇýþ de)*56\]^vw©ªÏÐÑúòúëúäáÜáÕÒÈÕÁÕÒ¸³°«°¨¨¨ú úú¨–‰€0JOJQJ^Jj0JOJQJU^J OJQJ^J0JjåƒUNHCJNHCJmH sH j‡§UmH sH  j,•CJUju”CJ(UCJ( jCJ(UCJ$NHCJ$ B*CJphÿ j»CJUjU jU,-|¦§©ªÆ  z{»+oñ4Ù- r Ê * Z e `ùôòòðôôôîððððîçäçÞäçääçîð„Ä^„Ä@&„Ä@&^„Ä$a$ Æ_¾$æÕäÖýý)*+o€½¾¿ïðñ-.4GŽÂÙôõ   + , . R b g r Ž ° ± ² È É Ù Ú   ( ëÞÕÞÒËÀ˲ÀÕÀÒ®¨®Ò®¨®ÒÀËšÀÕÀÒ®Ò®ÀËŒÀÕÀÀË~ÀÕjʇOJQJU^Jj‡OJQJU^Jj`†OJQJU^J 5CJNH5CJju…OJQJU^JjOJQJU^J OJQJ^JCJ0JOJQJ^Jj0JOJQJU^J'j „>*B*OJQJU^Jphÿ1( ) * B Y Z À Á p q ÇÈ&'oÃÄóô  '(23MNOQRú{|ìíÄÅòóKL™=>€ª«",-`aqrŒŽôñëñèèèèäÞäÖäËäÖäÖäÖäÀÖ·Öäèèèèèµ±µ±µ±µ±µ¬¬¬¤¬¬j‰U jU5NH55\mHnHuj‰5U\j“ˆ5U\j5U\ 5NH\5\NH 5CJ\CJjOJQJU^J?`mnoúû¤¥ßUV˜™"#,‘ºê"z±å@m¡Þýûûûûûûûûûûûûûûûöôôôòòðððôòò & F‘𛵶·¸¹ºÉÊäåæèéê !"XYZtuvxyz‘«¬­¯°±ÄÅßàáãäå :;<>?@LùôìôôùôäôôùÝôÕôôÇÝô¿ôôÇô·ôôªô¢ôôªôšôôªjøŒUj{ŒUOJQJaJmHnHsHjþ‹Uj‹U5OJQJaJmHnHsHj‹U mHnHsHj‡ŠUj ŠU jU OJQJaJé ê !!!! ! !!!"!!@!A!B!Y!Z!t!u!v!x!y!z!!!ª!«!¬!®!¯!°!¿!À!Ú!Û!Ü!Þ!ß!à!þ!ÿ!""""""9":"T"U"V"X"Y"Z"‚"ƒ""ž"Ÿ"¡"¢"úòúúäúÜúúÏúÇúúÏú¿úúÏú·úúäú¯úúÏú§úúÏúŸúúj€ Uj Uj†ŸUj ŸUjŒžUjžUOJQJaJmHnHsHj’U5OJQJaJmHnHsHjU jU>Ý !B!z!°!à!"Z"£"Ü"!#a#¥#á#$Q$}$»$ô$0%g%Å%&P&›&ó&>'…'Ô'/(ýûûûýûûýûûûûûûýùýýýýýýùýýýýýý¢"£"»"¼"Ö"×"Ø"Ú"Û"Ü"###### #!#@#A#[#\#]#_#`#a#„#…#Ÿ# #¡#£#¤#¥#À#Á#Û#Ü#Ý#ß#à#á#ø#ù#$$$$$$0$1$K$L$M$O$P$Q$\$]$w$x$y$ñìäìì×ìÏìì×ìÇìì×ì¿ìì×ì·ìì×ì¯ìì×ì§ììñìŸìjh¤Ujë£Ujn£Ujñ¢Ujt¢Uj÷¡Ujz¡UOJQJaJmHnHsHjý U jU5OJQJaJmHnHsH>y${$|$}$š$›$µ$¶$·$¹$º$»$Ó$Ô$î$ï$ð$ò$ó$ô$%%*%+%,%.%/%0%F%G%a%b%c%e%f%g%¤%¥%¿%À%Á%Ã%Ä%Å%æ%ç%&&&&&&/&0&J&K&L&N&O&P&z&{&•&–&—&™&úóúëúúÝúÕúúÝúÍúúÝúÅúúÝú½úúÝúµúúÝú­úúóú¥újP¨UjÓ§UjV§UjÙ¦Uj\¦UjߥUjb¥U5OJQJaJmHnHsHjå¤U OJQJaJ jUA™&š&›&Ò&Ó&í&î&ï&ñ&ò&ó&''8'9':'<'='>'d'e''€''ƒ'„'…'³'´'Î'Ï'Ð'Ò'Ó'Ô'(()(*(+(-(.(/(`(a({(|(}((€((°(±(Ë(Ì(Í(Ï(Ð(Ñ()))))) )!)P)Q)úìúäúúìúÜúúìúÔúúìúÌúúìúÄúúìú¼úúìú´úúìú¬úúìúj8¬Uj»«Uj>«UjÁªUjDªUjÇ©UjJ©UjͨU5OJQJaJmHnHsH jUD/((Ñ(!)q)»)ù)L**æ*"+n+¿+,k,Ã,)--ß-G.µ./b/³/0o0º01p1¼1ýýýýûûûýûûûûûûûûûûûûûûûûûûûýýQ)k)l)m)o)p)q)š)›)µ)¶)·)¹)º)»)Ø)Ù)ó)ô)õ)÷)ø)ù)+*,*F*G*H*J*K*L*o*p*Š*‹*Œ*Ž***Å*Æ*à*á*â*ä*å*æ*+++++ +!+"+M+N+h+i+j+l+m+n+÷òòäòÜòòÏòÇòòÏò¿òòÏò·òòäò¯òòÏò§òòÏòŸòòÏj °Uj£¯Uj&¯Uj©®Uj,®Uj¯­UOJQJaJmHnHsHj2­U5OJQJaJmHnHsH jUjµ¬U>n+ž+Ÿ+¹+º+»+½+¾+¿+û+ü+,,,,,,J,K,e,f,g,i,j,k,¢,£,½,¾,¿,Á,Â,Ã,- -#-$-%-'-(-)-n-o-‰-Š-‹--Ž--¾-¿-Ù-Ú-Û-Ý-Þ-ß-&.'.A.B.C.E.F.G.”.•.¯.úòúúåúÝúúåúÕúúåúÍúúåúÅúúåú½úúåúµúúåú­úúåúj´Uj‹³Uj³Uj‘²Uj²Uj—±Uj±UOJQJaJmHnHsHj°U jUC¯.°.±.³.´.µ.ô.õ.//////A/B/\/]/^/`/a/b/’/“/­/®/¯/±/²/³/à/á/û/ü/ý/ÿ/00N0O0i0j0k0m0n0o0™0š0´0µ0¶0¸0¹0º0ý0þ0111111O1P1j1k1÷òòåòÝòòåòÕòòåòÍòòåòÅòòåò½òòåòµòòåò­òòåò¥jm¸Ujð·Ujs·Ujö¶Ujy¶UjüµUjµUjµUOJQJaJmHnHsH jUj…´UAk1l1n1o1p1›1œ1¶1·1¸1º1»1¼1ó1ô1222222P2Q2k2l2m2o2p2q2¡2¢2¼2½2¾2À2Á2Â2ì2í233 3 3 3 3E3F3`3a3b3d3e3f33Ž3¨3©3ª3¬3­3®3ã3ä3þ3ÿ34úúìúäúúìúÜúúìúÔúúìúÌúúÅú½úúìúµúúìú­úúìú¥újU¼UjØ»Uj[»UjÞºU OJQJaJjaºUjä¹Ujg¹Ujê¸U5OJQJaJmHnHsH jUA¼12q2Â2 3f3®34J44ô4O5—5ã526ˆ6Ó6&7n7Ã78X8µ8 9h9Á9%:p:±:ü:ýýûýýýýýýýýûýýýùùùùùùùùùýùùùù4444)4*4D4E4F4H4I4J4o4p4Š4‹4Œ4Ž444Ó4Ô4î4ï4ð4ò4ó4ô4.5/5I5J5K5M5N5O5v5w5‘5’5“5•5–5—5Â5Ã5Ý5Þ5ß5á5â5ã566,6-6.6061626g6h6‚6ƒ6„6†6úìúäúúìúÜúúìúÔúúìúÌúúìúÄúú½úµúúìú­úúìú¥új=ÀUjÀ¿UjC¿U OJQJaJjƾUjI¾Uj̽UjO½UjÒ¼U5OJQJaJmHnHsH jUA†6‡6ˆ6²6³6Í6Î6Ï6Ñ6Ò6Ó677 7!7"7$7%7&7M7N7h7i7j7l7m7n7¢7£7½7¾7¿7Á7Â7Ã7ä7å7ÿ7888887888R8S8T8V8W8X8”8•8¯8°8±8³8´8µ8ê8ë899úìúäúú×úÏúú×úÇúú×ú¿úú×ú·úú×ú¯úú×ú§úú×úŸj%ÄUj¨ÃUj+ÃUj®ÂUj1ÂUj´ÁUj7ÁUOJQJaJmHnHsHjºÀU5OJQJaJmHnHsH jU>99 9 9 9G9H9b9c9d9f9g9h9 9¡9»9¼9½9¿9À9Á9::: :!:#:$:%:O:P:j:k:l:n:o:p::‘:«:¬:­:¯:°:±:Û:Ü:ö:÷:ø:ú:û:ü:';(;B;C;D;F;G;H;o;p;Š;úúíúåúúíúÝúúÏúÇúúíú¿úúíú·úúíú¯úúíú§úúíújÇUjÇUj–ÆUjÆUjœÅU5OJQJaJmHnHsHjÅUj¢ÄUOJQJaJmHnHsH jU?ü:H;;Ò;<<Û<8=®=>x>Ì>1?¢? @n@¿@ AVAAìAQBªBCPC¬C DWD¥D EýýýûýýýýýýýýýýýýýýûùûûûûûûûûûŠ;‹;Œ;Ž;;;±;²;Ì;Í;Î;Ð;Ñ;Ò;ü;ý;<<<<<<l<m<‡<ˆ<‰<‹<Œ<<º<»<Õ<Ö<×<Ù<Ú<Û<==2=3=4=6=7=8==Ž=¨=©=ª=¬=­=®=þ=ÿ=>>>>>>W>÷òòåòÝòòåòÕòòÇò¿òòåò·òòåò¯òòåò§òòåòŸòòåjxËUjûÊUj~ÊUjÊUj„ÉU5OJQJaJmHnHsHjÉUjŠÈUOJQJaJmHnHsH jUj ÈU>W>X>r>s>t>v>w>x>«>¬>Æ>Ç>È>Ê>Ë>Ì>??+?,?-?/?0?1??‚?œ??ž? ?¡?¢?ê?ë?@@@ @ @ @M@N@h@i@j@l@m@n@ž@Ÿ@¹@º@»@½@¾@¿@è@é@AAAAA A5A6APAúòúúåúÝúúåúÕúúåúÍúúåúÅúúåú½úúåúµúúåú­úúåúj`ÏUjãÎUjfÎUjéÍUjlÍUjïÌUjrÌUOJQJaJmHnHsHjõËU jUBPAQARATAUAVAmAnAˆA‰AŠAAŽAAÊAËAåAæAçAêAëAìA/B0BJBKBLBOBPBQBˆB‰B£B¤B¥B¨B©BªBáBâBüBýBþBCCC.C/CICJCKCNCOCPCŠC‹C¥C¦C§CªC«C÷òòåòÝòòÏòÇòòÀò¸òòÏò°òòÏò¨òòÏò òòÏò˜òòjHÓUjËÒUjNÒUjÑÑUjTÑU OJQJaJj×ÐU5OJQJaJmHnHsHjZÐUOJQJaJmHnHsH jUjÝÏU<«C¬CçCèCDDDDD D5D6DPDQDRDUDVDWDƒD„DžDŸD D£D¤D¥DëDìDEEE E E EFEGEaEbEcEfEgEhEœEE·E¸E¹E¼E½E¾EíEîEF F F FFFBFCF]F^F_FbFcFdFÁFÂFÜFñìäììñìÜììñìÔììñìÌììñìÄììñì¼ììñì´ììñì¬ììñìj0×Uj³ÖUj6ÖUj¹ÕUj<ÕUj¿ÔUjBÔUjÅÓU jU5OJQJaJmHnHsHD EhE¾EFdFãFfGÏGEH¦HöH\IÀIJzJÑJAKªK+L’LÜL&MoM¸M$NtNÉNOjO´OýýýýýýýýýýýýýýýýýýýýýýýýýûûûûÜFÝFÞFáFâFãFDGEG_G`GaGdGeGfG­G®GÈGÉGÊGÍGÎGÏG#H$H>H?H@HCHDHEH„H…HŸH H¡H¤H¥H¦HÔHÕHïHðHñHôHõHöH:I;IUIVIWIZI[I\IžIŸI¹IºI»I¾I¿IÀIóIôIJ÷òòäòÜòòäòÔòòäòÌòòäòÄòòäò¼òòäò´òòäò¬òòäòjÛUj›ÚUjÚUj¡ÙUj$ÙUj§ØUj*ØU5OJQJaJmHnHsH jUj­×U@JJJJJJXJYJsJtJuJxJyJzJ¯J°JÊJËJÌJÏJÐJÑJK K:K;K’O“O­O®O¯O²O³O´OãOäOþOÿOPPPP?P@PZP[P\P_P`PaP•P–P°P±P²PµP¶P·PQQ Q!Q"Q%Q&Q'Q{Q|Q–Q—Q˜Q›QœQQRR R!R"R%R&R'R[R\RvRwRxR{R|R}RœRR·RúòúúåúÝúúåúÕúúåúÍúúåúÅúúåú½úúåúµúúåú­úúåújÐæUjSæUjÖåUjYåUjÜäUj_äUjâãUOJQJaJmHnHsHjeãU jUB´OPaP·P'QQ'R}R¾RSrSÂS"TyTÎT UvUàUKVÁVWrWØWHXÀX"YƒYßY5ZZýýýýýýýýýýýýýýýýýýýýýýýýýýýýý·R¸R¹R¼R½R¾RõRöRSSSSSSPSQSkSlSmSpSqSrS S¡S»S¼S½SÀSÁSÂSTTTTT T!T"TWTXTrTsTtTwTxTyT¬T­TÇTÈTÉTÌTÍTÎTþTÿTUUUUU UTUUUoUpU÷òòåòÝòòåòÕòòåòÍòòåòÅòòåò½òòåòµòòåò­òòåò¥j5ëUj¸êUj;êUj¾éUjAéUjÄèUjGèUjÊçUOJQJaJmHnHsH jUjMçUApUqUtUuUvU¾U¿UÙUÚUÛUÞUßUàU)V*VDVEVFVIVJVKVŸV VºV»V¼V¿VÀVÁVúVûVWWWWWWPWQWkWlWmWpWqWrW¶W·WÑWÒWÓWÖW×WØW&X'XAXBXCXFXGXHXžXŸX¹XºX»X¾X¿XÀXúúíúåúúíúÝúúíúÕúúíúÍúúíúÅúúíú½úúíúµúúíú­úúíjïUj îUj#îUj¦íUj)íUj¬ìUj/ìUj²ëUOJQJaJmHnHsH jUDÀXYYYYY Y!Y"YaYbY|Y}Y~YY‚YƒY½Y¾YØYÙYÚYÝYÞYßYZZ.Z/Z0Z3Z4Z5Z{Z|Z–Z—Z˜Z›ZœZZäZåZÿZ[[[[[;[<[V[W[X[[[\[][§[¨[Â[Ã[Ä[Ç[È[É[ \\(\úòúúåúÝúúåúÕúúåúÍúúåúÅúúåú½úúåúµúúåú­úúåújóUjˆòUj òUjŽñUjñUj”ðUjðUOJQJaJmHnHsHjšïU jUCZ[][É[/\·\!]©] ^}^Ô^-_’_õ_O`¦`þ`\a¸ab\b’bèb$c}cÙcCd­de‘eýýýýýýýýûûûûûûûùýýýùýýýýýýýýý(\)\*\-\.\/\•\–\°\±\²\µ\¶\·\ÿ\]]]]] ]!]‡]ˆ]¢]£]¤]§]¨]©]ë]ì]^^^ ^ ^ ^[^\^v^w^x^{^|^}^²^³^Í^Î^Ï^Ò^Ó^Ô^ _ _&_'_(_+_,_-_p_q_‹_Œ_÷òòåòÝòòåòÕòòåòÍòòåòÅòòåò½òòåòµòòåò­òòåò¥jj÷UjíöUjpöUjóõUjvõUjùôUj|ôUjÿóUOJQJaJmHnHsH jUj‚óUAŒ___‘_’_Ó_Ô_î_ï_ð_ó_ô_õ_-`.`H`I`J`M`N`O`„`…`Ÿ` `¡`¤`¥`¦`Ü`Ý`÷`ø`ù`ü`ý`þ`:a;aUaVaWaZa[a\a–a—a±a²a³a¶a·a¸aáaâaüaýaþabbb:b;bUbúúíúåúúíúÝúúíúÕúúíúÍúú¿ú·úúíú¯úúíú§úúíújÕúUjXúUjÛùU5OJQJaJmHnHsHj^ùUjáøUjdøUjç÷UOJQJaJmHnHsH jU?UbVbWbZb[b\bpbqb‹bŒbbb‘b’bÆbÇbábâbãbæbçbèbccccc"c#c$c[c\cvcwcxc{c|c}c·c¸cÒcÓcÔc×cØcÙc!d"ddAdBdCd‹dŒd¦d§d¨d«d¬d­død÷òòäòÜòòÏòÇòòÏò¿òòÏò·òòÏò¯òòÏò§òòÏòŸòòÏj½þUj@þUjÃýUjFýUjÉüUjLüUOJQJaJmHnHsHjÏûU5OJQJaJmHnHsH jUjRûU>ødùdeeeeeeoepeŠe‹eŒeee‘eòeóe ffffff`faf{f|f}f€ff‚fÑfÒfìfífîfñfòfóf8g9gSgTgUgXgYgZg™gšg´gµg¶g¹gºg»ghh"h#h$h'h(h)hihjh„húòúúåúÝúúåúÕúúåúÍúúåúÅúúåú½úúåúµúúåú­úúåúj¥Uj(Uj«Uj.Uj±Uj4Uj·ÿUOJQJaJmHnHsHj:ÿU jUB‘ef‚fófZg»g)h‹håhMiªijkj¾jkvkûk;lˆlälLm›mæm/nŒnÔn8oyoìoApýýýýýýýýýýýýýýýûùýýýýùùùùùùùù„h…h†h‰hŠh‹hÃhÄhÞhßhàhãhähåh+i,iFiGiHiKiLiMiˆi‰i£i¤i¥i¨i©iªiãiäiþiÿijjjjIjJjdjejfjijjjkjœjj·j¸j¹j¼j½j¾jùjújkkkkkkTkUkokpk÷òòåòÝòòåòÕòòåòÍòòåòÅòòåò½òòåòµòòåò­òòåò¥j UjUjUj“UjUj™UjUjŸUOJQJaJmHnHsH jUj"UApkqktkukvkÙkÚkôkõkökùkúkûkll4l5l6l9l:l;lflgll‚lƒl†l‡lˆlÂlÃlÝlÞlßlâlãläl*m+mEmFmGmJmKmLmymzm”m•m–m™mšm›mÄmÅmßmàmámämåmæm nn(núúíúåúúÞúÖúúÈúÀúúíú¸úúíú°úúíú¨úúíú úúÈúju Ujø Uj{ UjþUjU5OJQJaJmHnHsHjU OJQJaJj‡UOJQJaJmHnHsH jU?(n)n*n-n.n/njnkn…n†n‡nŠn‹nŒn²n³nÍnÎnÏnÒnÓnÔnoo1o2o3o6o7o8oWoXorosotowoxoyoÊoËoåoæoçoêoëoìop p:p;p w w$w%w&w)w*w+wtwuwww‘w”w•w–wËwÌwæwçwèwëwìwíw.x/xIxJxKxNxOxPx‹xŒx¦x§x¨x«x¬x­xÝxÞxøxùxúxýxþxÿxJyKyeyfygyjykyly§y¨yÂyÃyÄyÇyÈyÉyýyþyzúòúúåúÝúúåúÕúúåúÍúúåúÅúúåú½úúåúµúúåú­úúåújUj˜UjUjžUj!Uj¤Uj'UOJQJaJmHnHsHjªU jUBzzzzzzƒz„zžzŸz z£z¤z¥zØzÙzózôzõzøzùzúzž{Ÿ{¹{º{»{¾{¿{À{ô{õ{||||||X|Y|s|t|u|x|y|z|É|Ê|ä|å|æ|é|ê|ë|"}#}=}>}?}B}C}D}—}˜}²}³}÷òòåòÝòòåòÕòòåòÍòòåòÅòòåò½òòåòµòòåò­òòåò¥jzUjýUj€UjUj†Uj UjŒUjUOJQJaJmHnHsH jUj’UAÀ{|z|ë|D}¹}~{~ò~m³ì*€h€¡€G€¹öe‚§‚ä‚(ƒgƒ­ƒ„”„è„ýýýýýýýûûùýýýýùýýýýóùýýùýûùù Æ ³}´}·}¸}¹}ð}ñ} ~ ~ ~~~~Y~Z~t~u~v~y~z~{~Ð~Ñ~ë~ì~í~ð~ñ~ò~KLfghklm‘’¬­®±²³ÊËåæçêëì€ €#€$€%€(€)€*€F€G€a€úúíúåúúíúÝúúíúÕúúÎúÆúúÎú¾úú°ú¨úúíú úúíújå!Ujh!U5OJQJaJmHnHsHjë Ujn U OJQJaJjñUjtUj÷UOJQJaJmHnHsH jU?a€b€c€f€g€h€€€€š€›€œ€Ÿ€ €¡€ä€å€ÿ€%&@ABEFG^_yz{~€—˜²³´·¸¹ÔÕïðñôõö)‚*‚C‚D‚^‚_‚`‚c‚d‚÷òòåòÝòòåòÕòòÇò¿òòåò·òòåò¯òòåò§òòååòŸòòjÍ%UjP%UjÓ$UjV$UjÙ#U5OJQJaJmHnHsHj\#Ujß"UOJQJaJmHnHsH jUjb"U>d‚e‚…‚†‚ ‚¡‚¢‚¥‚¦‚§‚‚Â݂ނ߂â‚ã‚䂃ƒ!ƒ"ƒ#ƒ&ƒ'ƒ(ƒEƒFƒ`ƒaƒbƒeƒfƒgƒ‹ƒŒƒ¦ƒ§ƒ¨ƒ«ƒ¬ƒ­ƒýƒþƒ„„„„„„r„s„„Ž„„’„“„”„ƄDŽá„óîæîîØîÐîîóîÈîîóîÀîîØî¸îîóî°îî©î¡îîØîj8)U OJQJaJj»(Uj>(UjÁ'UjD'UjÇ&U5OJQJaJmHnHsHjJ&U jUOJQJaJmHnHsH<á„â„ã„æ„ç„è„%…&…@…A…B…E…F…G……‚…œ……ž…¡…¢…£…î…ï… † † ††††<†=†W†X†Y†\†]†^†”†•†¯†°†±†´†µ†¶†á†â†ü†ý†þ†‡‡‡>‡?‡Y‡Z‡[‡^‡_‡`‡—‡˜‡²‡÷òòäòÜòòäòÔòòÍòÅòòäò½òòäòµòòäò­òòäò¥òòäòj -Uj£,Uj&,Uj©+Uj,+U OJQJaJj¯*Uj2*U5OJQJaJmHnHsH jUjµ)U@è„G…£…†^†¶†‡`‡¹‡ˆwˆØˆ)‰z‰È‰.Š~ŠÏŠ;‹Ž‹ä‹/ŒwŒÏŒ,œÝŽJކŽýûýýýýýýýýýýýýýýýýýùùùùùùûûýý²‡³‡´‡·‡¸‡¹‡ó‡ô‡ˆˆˆˆˆˆUˆVˆpˆqˆrˆuˆvˆwˆ¶ˆ·ˆÑˆÒˆÓˆÖˆ×ˆØˆ‰‰"‰#‰$‰'‰(‰)‰X‰Y‰s‰t‰u‰x‰y‰z‰¦‰§‰Á‰Â‰Ã‰Æ‰Ç‰È‰ Š Š'Š(Š)Š,Š-Š.Š\Š]ŠwŠ÷òòäòÜòòäòÔòòäòÌòòäòÄòòäò¼òòäò´òòäò¬òòäòj1Uj‹0Uj0Uj‘/Uj/Uj—.Uj.U5OJQJaJmHnHsH jUj-U@wŠxŠyŠ|Š}Š~Š­Š®ŠÈŠÉŠÊŠÍŠÎŠÏŠ‹‹4‹5‹6‹9‹:‹;‹l‹m‹‡‹ˆ‹‰‹Œ‹‹Ž‹Â‹Ã‹Ý‹Þ‹ß‹â‹ã‹ä‹ ŒŒ(Œ)Œ*Œ-Œ.Œ/ŒUŒVŒpŒqŒrŒuŒvŒwŒ­Œ®ŒÈŒÉŒÊŒÍŒÎŒÏŒ ÷òòäòÜòòäòÔòòäòÌòòäòÄòò·ò¯òò·ò§òò·òŸòò·jð4Ujs4Ujö3UOJQJaJmHnHsHjy3Ujü2Uj2Uj2U5OJQJaJmHnHsH jUj…1U> %&'*+,z{•–—š›œ»¼ÖרÛÜÝíîŽ Ž Ž ŽŽŽ(Ž)ŽCŽDŽEŽHŽIŽJŽdŽeŽŽ€ŽŽ„Ž…Ž†ŽŽ‘ޫެޭްޱ޲ŽßŽàŽúŽûŽüŽúòúúåúÝúúåúÕúúÎúÆúúÎú¾úú°ú¨úú°ú úúÎú˜újØ8Uj[8UjÞ7U5OJQJaJmHnHsHja7Ujä6U OJQJaJjg6Ujê5UOJQJaJmHnHsHjm5U jU<†Ž²Ž"Qÿ‘ï’"“2“6”~š‹š/œžÖŸ~ 5£>¤9¥™¥ñ¦v¨#©ñ©ýûù÷õðëëõéÞÞéÞÞÞÞÞÞÞÞÞÞÞÞ  ÆÐk„e^„e & F¸a & F¸üŽÿŽr‹Œ¥¦¶·¼½¿ÀÖ×çèPefg‘’­®ØÙŽ‘‘þ‘ÿ‘’ ’9’:’;’<’=’€’×’Ø’î’"“2“{“†“ ”úìÝØÒÇÒ¹ÒÇÒÇÒÇÒ«ÒÇ©ÇÒØú¡úžú››Øú“úú©©ØØ‡Ø5\mHsH5NHjú:UNH0JjO:U5jÒ95UmHsHjU95UmHsHj5UmHsH 5mHsHmHsHjOJQJUmHnHu5OJQJaJmHnHsH jU5 ””6”j”s”Ô”å”æ”•–M–N–k–V—W—p—q—r—s—t——€—¦—í—ü—ý—¤™¥™å™æ™ÿ™ššššššš0š1šAšBš`šaš|š‹š±š/œWœ01234ižjžƒžøóññíññíñèàèèÝÙÝÝÎȺÈÎÈÎÈÎȬÈÎñÎÈÈóÈó£ó—£ó£ó£ójî<UmHsHjUmHsHjq<5UmHsHjô;5UmHsH 5mHsHj5UmHsH5\NHjw;U jU5NH5mHsH5\mHsH:ƒž„ž…ž‹žŒžž¢ž¿žÀžÙžÚžÛžàžážþžÿžŸŸŸ Ÿ!ŸÖŸíŸ  , - . 6 7 Q R ~ ¤ ³¡´¡Ì¡Í¡Î¡Ø¡Ù¡k¢l¢…¢†¢‡¢¢Ž¢þ¢ÿ¢£££ £!£K£g£óêåêåßåêåÓêåêåêåÇêåêåßåêå»êåêå´åßåêå¨êåêåêåœêåêåêåêåêåßjW@UmHsHjÚ?UmHsHj_?UmHsH NHmHsHjâ>UmHsHje>UmHsHjè=UmHsH 5mHsHmHsHjUmHsHjk=UmHsH8g£‡£ˆ£¤¤.¤/¤0¤:¤;¤=¤T¤f¤Þ¤ß¤ø¤ù¤ú¤¥¥W¥u¥™¥£¥É¥Ë¥×¥ë¥E¦F¦W¦Y¦k¦m¦€¦„¦Æ¦É¦Î¦Ï¦ç¦è¦é¦í¦î¦ð¦ñ¦§w§|§}§–§—§˜§ž§Ÿ§ §»§¼§Û§ö§$¨P¨Q¨j¨k¨l¨r¨ýøðøøëåëÜëÐÜëÜëåëÎëëëëëëëÜëÂÜëÜëÎëÜë¶ÜëÜëýëëÜëªÜëjÆBUmHsHjIBUmHsHjÎAUmHsH5jQAUmHsHjUmHsH 5mHsHmHsHjÔ@U jUNHCr¨s¨u¨v¨ˆ¨¨Ÿ¨¨¨´¨Ã¨Ä¨Ï¨Ð¨Û¨Ü¨õ¨ö¨÷¨ú¨û¨©©©©©© ©#©:©ð©ñ©ªÛªÜªõªöª÷ªþªÿª««,«-«.«5«6«y«z«“«”«•«›«œ«Ÿ«À«æ«ç«¨¬©¬Á¬öñëñëñëñäñäñöñØöñöñöñÌöñöñëñëñöñÀöñöñöñ´öñöñöñ¨öñöñ ñäñöñ5\mHsHj7EUmHsHjºDUmHsHj=DUmHsHjÀCUmHsHjCCUmHsH NHmHsH 5mHsHmHsHjUmHsH;ñ©Ÿ«Œ­w®ä°c²—²…³¡³m¶¤¶¯¶ç¶I¸u¸v¸¡¸Â¸Ï¸Ð¸æ¸¹ ¹!¹B¹€¹¹ôôôôôòððôêáêáêêêêêêêêêêêêê  & F„l^„l„Å^„Å  ÆÐk„e^„eÁ¬Â¬Ã¬É¬Ê¬g­h­­‚­ƒ­‰­Š­Œ­©­½­w®‡®ê®ë®¯¯¯ ¯ ¯4¯5¯N¯O¯P¯S¯T¯°°°° °#°$°ä°ö°H±I±b±c±d±g±h±²²c²—²¡³Å³V´óêåêåêåÙêåêåÑËåËåêå¿êåêåêå³êåêåêå§êåêåËåêå›êåêå”ååÑŽ \mHsH NHmHsHj#HUmHsHj¦GUmHsHj)GUmHsHj¬FUmHsH 5mHsH5\mHsHj/FUmHsHmHsHjUmHsHj´EUmHsH5V´W´p´q´r´x´y´|´’µ“µL¶M¶l¶m¶£¶¤¶¯¶Ì¶Ó¶æ¶ç¶#·)·E·L·I¸Ð¸¹¹ ¹¹ ¹„¹™¹ž¹»¹¼¹Õ¹Ø¹ä¹ý¹^ºsºxº•º–º¯º²º¾º¿ºÀºq»r»õïáõïõïÞÞÖËÆÃ¼Æ¶Æ¶Æ³®§®Ÿ®³™®™‘™®™ˆ³™®™‘™®™ˆ™Æï0JpB*CJphÿ0Jp7CJNH 0Jp7CJ0Jp5CJ\ 0JpCJNH0JpCJCJ 5mHsH CJmHsH0JpmHsHCJOJQJmHsH5\mHsHNHj HU\mHsH \mHsHjU\mHsH4¹™¹Õ¹ì¹û¹ü¹ºZº[ºsº¯ºÀºr»¸¼²¾¿)¿o¿p¿q¿z¿À'À|À‚ÁùùùùùùùùùùùðååùðùãÝÛãÙãÔ & Fl Æ_¾$  ÆÐk„e^„e  & F„l^„l„Å^„År»€»»Ž»³»Á»¼¼¼¼4¼5¼6¼>¼?¼¼‘¼ª¼«¼¬¼´¼µ¼¸¼è¼¾‚¾±¾²¾¿¿)¿o¿q¿%Á)Á*Á€ÁQÄRĚģÅ\Æ]ÆiÇjÇqÇéÇÈ¦È­È®ÈÆÈÇÈÈÈÉÈÊÈòÉûÉ,Ê-ÊEÊFÊüùüôðôçôÛçôçôçôÏçôçôüÌôɾô·ôµ±µÌµÌ̵µ¬¤¬¬µ¬œj’JUjJU jU5NH5 CJmHsHCJOJQJmHsHCJNHjšIUmHsHjIUmHsHjUmHsH0J(5mHsH0J(5\=‚Á¤ÅêÇÈ|È}ÈÕÈÉzÉÏÉÐÉKÊLÊÆÊQË&̞̟Ì*ͶÍúúøöñìÞÞÞØìñìÊÊÊñ½¸a & Fn a & Fn„Å„;ý^„Å`„;ýa & Fm ÆhЄÐ^„Ð Æ_¾$ & Fm ÆhЄÐ^„Ða & Fma & F & FlFÊGÊHÊIÊ_ÊsÊyÊzʑʒʓʕʖÊöË÷ËÑÌâÌçÌèÌÍÍÍÍÍ Í Í#Í$Í%Í'Í(Í\ÍmÍsÍtÍŒÍÍŽÍ͖͑͗ͯͰͱͳʹÍ\ηÎÐ/Ð4ÐCÐXÐVњѤҥÒÓÓ/Ó0ÓÔËÕ?×@טؙØÙÙ6ÙXÙ›Ù¿ÙÓÙáÙ<ÚúúøúðúúíøúåúúúÝúúøúÕúúúÍúúøÉÇÉÇøíííÂííÂÂÂÂOJQJ\5\j÷LUj|LUjLUj†KUNHj KU5 jUL¶ÍYÐÑãÑäуӄÓÔÔ1ÔOÔPÔZÔuÔ€ÔÔšÔÃÔÒÔÓÔáÔ ÕÕÕ1ÕdÕpÕñìçåååååããããããããããããããããããa & Fpa & Foa & Fn ÆhЄÐ^„ÐpÕqÕÕ©Õ¹ÕºÕËÕÌÕ×ÖâÖ<Ø=ØËØÌØÙXÙ¿ÙDÚÛéÛÙÜ ÝFݦÞýýýýýýûûùûûûûêÛÛÌÌÌÌùûÇ & F: & F5„e„›þ¤<^„e`„›þ & F4„e„›þ¤<^„e`„›þ & F6„e„›þ¤<^„e`„›þ<ÚDÚ^ÚˆÚ?ÛeÛÎÛéÛFÝTݦ޶ރ߆ߨ߫ßÌßÐßüßà”à•àšààÍàÜàsáá¢á²áaâbâãžã ä ä$ä%ä&ä)ä*äÐäÑä¬å­åÆåÇåÈåËåÌåIæJæcædæeæhæiæïæðæWç½ç¿çÌçÍç7èGèRèUè¦è§èÀèÁèÂèÅèûûûûùùùùùùöùùóñööìäììöìÜìììÔììöÏÉÁÉñùì¹ìjéNU56mHsH 5mHsHmHsHjlNUjïMUjrMU jU60JpNH5OJQJI¦Þƒß¨ßÌßüßšàÍà=ásáëâãFã8ä~ä„åææ9çWçÏçÐçè èÉèÊèwéxé”êúôôôôôúòðîðúúúúðèîððððððððð Æ_¾$e„^„ & F:ÅèÆèé éUéVéoépéqétéuéôéê9ê:êZê[êtêuêvêyêzêðêñêŽëëÝëÞë÷ëøëùëüëýëìOìPìiìjìkìnìoì¯ì¿ìQíuíåí/î0îxîzî‚îÀîËî7ïDï ðð'ð(ð)ð,ð-ð0ð6ð¶ð·ðñññúøúðúúîëúãúúëøúÛúúÖÍÖÁÍÖÍÖ»ÖÖëÖøøøú³úúøëújZQU 6mHsHjÝPUmHsHjUmHsHmHsHj`PUjãOUNH6jfOU5 jUD”ê•êë‘ëììãìøì6íRíuívíyîzîÀî7ï0ð#ñqñºñò@ò™òÆòýòQó›óýýý÷õýðððõýýýààààààààààààà„ü „ ÷1$7$8$H$^„ü `„ ÷ & Fº Æ_¾$ññññ ñ#ñ0ñqñ~ñºñÇñòò@òLò™ò£òÆòÒòýò óQó^ó›ó¦óìó÷óEôQôô‹ô°ô¼ôCõDõèõôõfögö€öö‚ö…ö†öÐöÕö'÷(÷v÷…÷ˆ÷Ž÷»÷Ê÷ý÷ÿ÷Qø`ø¸úÆúÒúÕúûû¸û¹ûáû†ü™ü^þéÿøÿóô?QRÖÛì‹÷òòððððððððððððððíêòâòòðíàðàðàÜààíÙÔÐíðÌðð5NH5\mHsHCJ6]6jTRU0JpNH5 jUj×QUP›óìóEôô°ô¿õèõÏö‡÷ü÷šù»ùWûáûüHü†ü™üý‘ý¤ÿ½ÿäÿåÿ×ÂÔïïïïïíëéééíëëçççåëëëíëëééío„ü „ ÷1$7$8$H$^„ü `„ ÷‹ŒÝðòüýqrÔ‡ ëì      , ë  ‡ ¢   1 2 3 = > Á   ( s t  Ž  — ˜ Ý Þ ÷ ø ù   K L e f g o p ç þ …ýû÷ûýòìòãò×ãòãòìòÑòÑòãòÅãòãò¾òÑòãò²ãòãòãò¦ãòãòãòšãòãòìòjÃTUmHsHjFTUmHsHjÉSUmHsH NHmHsHjNSUmHsH 6mHsHjÑRUmHsHjUmHsH 5mHsHmHsH5\5NH<Ô‡ ç >+† Ï °Ù,ôÀ"¦#É%Ê%Ý%'€'Ð(Ñ(;)Q)†+‡+ýûûûûûùýûççççûûûýåýýýýýùýý & F9 Æḧ́ʄ›þ^„Ê`„›þo…›ÅÆßàáæç-./56bxÞß÷øùþÿ2349:>U£¹ÒèRhÒèmƒ•«+I1¦¼ $NOghistçèùôëôßëôëôëôÓëôëôùôëôÇëôëôëô»ëôëôµôùôùôùôùôùôùôµôùôùôùôëô©ëôëôëôj0WUmHsH 5mHsHjµVUmHsHj:VUmHsHj½UUmHsHj@UUmHsHjUmHsHmHsH 6mHsH?  :›±ãäýþÿg„†Ï×&'ÛÜ45NOPVW‰ÁÂÛÜÝßàâ &Œ¦§¨¬­°´Ùá,8qr‹óêåêåßåßåêåÓêåêåßåÏÍÉÍÉÍÂ͸ÂÍÂÍϰϥ°Ï°ÏÍÏ£ž–žž£££žjYU jU5j Y5U\j5U\j£XU\ jU\NH\\5\j&XUmHsH 6mHsHmHsHjUmHsHj«WUmHsH;‹Œ“”£¹ô y È É â ã ä è é 2!3!L!M!N!T!U!6"Y"Z"s"t"u"{"|"¿"Ý"##€##š#›#œ#¢#£#¥#¦#¸#¹#V$W$Û$Ü$‚%ƒ%œ%%ž%¤%¥%É%Ê%û&ü&Z'['s'÷òòðìêòâòòòÚòòêòÒòòêìêÎêÇê½ÇêÇêì»ð¸»ò°òò«¸òmHsHj‹\UNH5j\U\ jU\NH\j‘[Uj[Uj—ZU\5\6 jUjZU@s't'u'{'|' (¡(±)²)&*+*L*Q*º*Â*È*É*á*â*ã*æ*ç*X+Y+×+Ø+,,,,,¾,ü,X-Y-Ü-c.G0Ø0·2¸2Ï2Ð2Ñ2Õ2Ö2÷34B4[4º4Ñ4„6›6›7¬7µ7¹7â7ç788r8|8Æ8Ç8ÿ9 :E:F:W;X;©<º<â<ã<û<÷òòïïëééòáòòïòÙòÖòÑïÑÑòÉòòÇÄÇÇÇÇÇÇÇïéïïéò0Jp5j©^UOJQJ0Jjþ]Ujƒ]U66]NH jUj]UL‡+B,f,½,¾,Ë,á,î,ü,ý,Û-Ü-ò-+.<.R.c.d.m.µ.ô.;/[/F0G0[0b0c0v0ýûýýùùùùýýýùùùùùýûýôôûýýùùùù & Fv0x0›0À0Â0Ã0Ö0Ø0ä0Ý1Þ1&212²3Å3÷3º4á5ü56„6u7v7µ7â78r8ýýýýýýýûùùùûùûùôïáááïùùßßßa & F~ ÆhЄÐ^„Ð & F~ & F}r8Ñ9á9ü:ò;©<y=É>ï?ù?z@AAÐAâA?CbCC­CD D!DBDnD“D”DeGgGýûùôôôôôûùùùùòùðððððððððùêêc„^„ & F€aû<ü<ý<==%=&=™=£=->0>§>¨>¿>À>Á>Å>Æ>Õ>ñ>‡?¡?¦?§?¿?À?Á?Ç?È?X@Y@p@q@r@v@w@ë@ö@ü@ý@AAAAAöAþAGBHBVB^B¦B§BÀBÁBÂBÅBÆB?CâCãC“D¢D´DÀDÃDùDúDEE^E_EÂEÅE÷òòïííòåòòííòÝòòòÕòòíòÍòòíïíòÅòòÀ¹Àííïíïí NHOJQJOJQJj…aUj aUj‘`Uj`Uj_U6NH jUj"_UIÅE–F¥FG/G@GOGgGüGZH[HsHtHuHyHzH^D^H^O^Y^[^²^¼^M_Q`X`Öaæa@bIbIcYcecåcýùý÷÷÷ó÷÷÷ýýýðëãëëýùýùýà÷ó÷÷÷÷ýýëØëëýýùý÷ÓÎÎÈÎà 6mHsHmHsHOJQJjÜeU0Jpj_eU jUNH6NH6565OƒY÷[>^=_>_M_Z_d_i_n_o_Ž_¦_§_·_¼_Ã_Ö_ß_á_â_õ_` `:`Q`X`SaÖaýýýûûùùùùùùùùùùùùùùùùùùùù÷ûûbÖaæaIcYcæcôcldmdydšd­d¸dÅdÓdàdád÷dødee+e,eYefewe€e‹e¦e§eXfýûýûýûûùùùùùùùùùùùùùûûùùùùùûûåcæcôcád÷dõeöefffffÂfØf2gög÷g0h…h†hËhÌhiÂiÕiRj`j€jjÿj kikk„k™k¤k¸k¾k¿k×kØkÙkÞkßkynŒq@rYr§r¨rÀrÁrÂrÆrÇrÔrár’s“s«s¬s­s®s¯stútuûûòûéûÝéûéûòûÚÕÎÕÎÕÌÌÌÌÌÌÌÇ¿ÇÇսǵÇǽǭÇǨmHsHjÌgUjQgU5jÖfU jU6 NHOJQJOJQJNHjYfUmHsHjUmHsHOJQJmHsHmHsHBXfYfef†f¦f´fÁfÂfØfÙfæfõf#g1g2gŽþŽ`R‘ “¨“ ”•`–Å–F—ýýýýýýýýûùùùùýýýýûýýýýýýýýýýýd||8|=|i|q|ž|¦|©|­|Â|Ê|Ë|Ú|Û|è|ë|ô|û|} }.}/}8}@}D}H}N}T}€}‚}ƒ}ˆ}¯}·}º}¾}Ó}Ú}Û}ë}ì}~(~)~3~6~P~V~Y~\~m~r~x~y~~†~‡~œ~~¯~²~¼~Â~Ì~Ò~á~å~ë~ "(HOž¤Úà€€'€+€©€­€ú€þ€4;<Oýýýýýûóïóûëûëûëèýýýýäýýýûóïóûèýýýýèûóïóûëûëûëûëûýýýýýýýýýûóï6NHNH565j5U56ZOP_cfknŒ’¡¢ÏÓÕÝÞøù‚‚"‚&‚0‚5‚?‚C‚D‚H‚‡‚‹‚­‚²‚´‚»‚¼‚Õ‚Ö‚ë‚ï‚ø‚ý‚&ƒ*ƒ/ƒ5ƒ>ƒBƒ„ „w„x„††9†:†;†O†P†S†[†\†q†r†„†‹†”†›†§†ª†«†®†°†Ó†Û†߆æ†ÿ†‡‡‡m‡u‡÷õñõñõïìïõ÷è÷õñõñõñïäïïïõ÷è÷õñõñïïïïìß×ßÔßõ÷è÷õñõñõñÎñõïïïìï 56NH0JjÂhU jU6NH5NH6565j5UQu‡€‡ˆ‡ž‡¦‡§‡½‡¾‡ч؇á‡è‡ò‡ù‡ˆ ˆ ˆ/ˆ6ˆ>ˆEˆ^ˆeˆãˆêˆ‰‰Z‰a‰›‰¢‰ã‰ê‰%Š,ŠTŠ\Š]ŠsŠtŠ‡ŠŽŠ—Š§Š±Š¹Š¿ŠÀŠÅŠÒŠÔŠÝŠäŠóŠôŠ ‹‹0‹@‹L‹S‹X‹e‹¤‹¥‹Ó‹Û‹ŒŒŒ'Œ(Œ=ŒDŒMŒOŒPŒTŒ]ŒhŒtŒ{Œ‡ŒŒŒ¦Œ­ŒµŒ¼ŒýûóïóûëûëûëûëûýýýýèýýýýûóïóûëûëûëûäûëûýèýýýýèýûóïóûëûëÞëûëûëûëûýý 56NH5NHNH565j5U56X¼ŒÂŒÎŒêŒñŒõŒüŒ()TUv€Ž”ÝÞ>ŽHŽIŽXŽYŽ`Ž÷ŽøŽþŽ )`ast’ËÌ‘‘R‘\‘]‘o‘p‘ƒ‘…‘†‘¡‘£‘j’k’å’æ’ÿ’““““ “““*“+“>“@“A“\“^“¨“°“±“œƓۓݓޓô“ö“ ””ýýýýúúøðìðøúøðìðøúøðìðøðìðøúúøðìðøèøýúãÛããøðìðøèøÙÔÙøðìðøèøýø 6\]\juiU jU565j5U5NH6T””+”,”?”A”B”u”v”•••&•'•=•?•@•––F–G–`–h–i––€–•–—–˜–®–°–Ä–Í–Ζà–á–ó–õ–ö–——— —F—N—O—`—a—s—u—v—”—•—£—¥—Á—×ã—ä—˜ ˜ ˜!˜"˜9˜;˜<˜n˜p˜Œ˜Ž˜ŘƘ͘Õ˜Ö˜ê˜ë˜ý˜™™q™r™â™ê™ë™þ™ÿ™šššNšOš÷ó÷ñíñêñ÷ó÷ñíñêêñ÷ó÷ñíñèñ÷ó÷ñíñêèñ÷ó÷ñíñêèèêñ÷ó÷ñíñèèêñ÷ó÷ñíñêñ÷ó÷ñíñê6NH5655j5U\F—˜͘â™øša›BŸŒ¡¶£g¦¨¦ª±«¸¬«­>®/¯O°@±\±æ±=² ²³³à³_´ð´Aµýýýýýýýýýýýýýýýýýýûù÷÷÷÷÷÷÷÷sdOšøš››››*›.›/›U›Y›a›i›j›€››—›œ›¨›«›·›É›Õ›é›ì› œœœœœœæœçœ”™ž¡bžhžižwž¤ž¸žÙžížŸŸBŸCŸXŸYŸoŸtŸŸ„ŸŸ“Ÿ•Ÿ©ŸªŸ»ŸÀŸÅŸÉŸÿŸ   6 7 8 > ? E I { ~ ƒ ˆ « ¯ Ñ Õ ó ÷ ¡ýõñõýíýëýõñõýíýíýíýíýëëèèëëëäëëëèõñõýíýíýíýèëëèß×ßßëëëëëëjòiU jU6NHNH6565j5U5U¡ ¡q¡r¡Œ¡–¡—¡±¡²¡Ì¡Ñ¡Ú¡á¡ë¡ó¡ö¡÷¡ý¡¢ ¢¢¢*¢4¢9¢:¢T¢Y¢o¢p¢€¢¢¢¢¢Í¢Ò¢ô¢õ¢F£G£_£`£a£e£f£€£…£‡£Ž££˜£š£Ÿ£¤£©£¯£°£¶£¾£¿£Ú£Û£ö£û£¤ ¤¤¤"¤#¤'¤,¤6¤;¤E¤T¤`¤j¤k¤Ф•¤ͤܤ¥ž¥¶¥ýúøðìðøèøèøèøäøèøèøèøèøýúýýýúß×ßßýýýýýúøðìðøèøèøèøäøèøèøèøèøýýßjojU jU5NH565j5U5NH6U¶¥·¥¸¥¼¥½¥×¥Ü¥Þ¥å¥ç¥ë¥ì¥ï¥ñ¥ö¥û¥¦:¦>¦?¦C¦g¦n¦o¦…¦†¦™¦Ÿ¦¨¦¯¦¹¦Á¦˦ЦÓ¦Ô¦Ú¦ߦë¦ð¦ñ¦§§2§3§K§L§M§Q§R§l§q§s§z§|§„§†§Œ§§’§—§§­§³§¨'¨(¨>¨?¨S¨Y¨b¨g¨s¨x¨‚¨‰¨”¨œ¨§¨¬¨÷òòðððìððððìðêâÞâêÚêÚêÚêÚêÖêÚêÚêÓòËòòðððððððêâÞâêÚêÚêÚêÚêÚêÚjekUNH5NH565j5U56NH6 jUjêjUP¬¨·¨¼¨ɨΨϨ©©+©,©-©1©2©L©S©U©]©_©d©f©l©p©u©†©Œ©¢©£©È©Í©ô©õ©ªªqªvª¦ª®ª¯ªêĪÙªÛªܪÞªøª@«A«Z«[«\«_«`«m«n«±«²«Ç«È«ß«á«â«ä«þ«G¬H¬a¬b¬c¬f¬g¬¸¬¬ìÛ¬ܬõ¬÷¬ø¬ú¬­ýùýùýôìôôêêêêêêçêçêêýßÛßýùýØôÐôôçßÛßýùýØôÈôôýßÛßýùýØjØlUj[lU0Jp5j5UNH6jàkU jU565O­#­$­v­w­­‘­’­•­–­«­³­´­Í­έß­à­ì­í­ú­>®H®I®`®a®y®{®|®~®˜®ú®û®¯¯¯¯¯/¯0¯G¯H¯a¯c¯m¯w¯x¯z¯”¯˜¯™¯ݯÞ¯÷¯ø¯ù¯ü¯ý¯O°Y°Z°q°r°аŒ°°°©° ± ±%±&±'±*±+±\±ýøðøøîæâæîßÚßîæâæîÖîßøÎøøæâæîÖîÖîßýøÆøøîæâæîÖîßø¾øøjÌnUjOnUjÒmU560JpNH0Jp5j5U5jUmU jUNHJ\±‹±—±¶±·±d³e³~³³€³ƒ³„³4´5´®´¯´È´É´Ê´Ì´Í´aµpµ®µ¯µȵɵʵ̵͵G¶W¶X¶k¶l¶¶„¶…¶­¶²¶´¶»¶¼¶жѶå¶ê¶ë¶····9·:·P·Q·h·m·|·€··™·ž·Ø·Ý·Q¸Y¸Z¸ûõûîûåûÙåûåûîûåûÍåûåûõûåûÁåûåû¿·³·¿¯¿­¿·³·¿¯¿­ª·³·¿¯¿¯¿­­¿·NH6565j5U5jCpUmHsHjÆoUmHsHjIoUmHsHjUmHsH NHmHsH 6mHsHmHsHCAµBµµÙµ¶F¶G¶H¶´¶9·Q¸ì¸Ò¹•º¼°¾¿OÀcÀAÁÄ˜ÄÆìÆRÈʥ˵ËÌúúøøøöôôôôôôôôôôôòôôôôôôôôòôdss & FZ¸o¸p¸…¸‡¸ˆ¸ž¸ ¸øĸì¸í¸¹¹¹ ¹!¹F¹K¹¹†¹”¹™¹Ò¹Ù¹Ú¹ñ¹ò¹º*º+ºDºEºFºIºJº•º–º°º±ºκкѺl»m»†»‡»ˆ»‹»Œ»Ö»×»ð»ñ»ò»÷»ø»¼¼¼7¼8¼P¼U¼d¼h¼s¼v¼w¼|¼~¼ˆ¼¼£¼¤¼©¼­¼½ ½üôòîòìéôüôòîòìììòôüôòäÜääôüôòîòäÔäääÌääòôüôòîòîòîÆîòìéìì 56NHjºqUj=qUjÀpU jUNH6565j5U5N ½ø½¾¡¾¢¾°¾º¾»¾×¾ؾô¾ù¾¿¿¿ ¿¿6¿;¿I¿R¿a¿f¿¿˜¿™¿­¿®¿ÿſƿÀÀ ÀÀcÀdÀzÀ{ÀÀ–À—À À§ÀÌÀÍÀÁÁ*Á+Á,Á2Á3Á9Á:ÁAÁBÁ[Á\ÁrÁyÁzÁ¯Á°ÁßÁàÁøÁùÁúÁÿÁ¿ÂÀÂØÂÙÂÚÂàÂáÂ2ÃýúøðìðøèøèâèøýýýøðìðøèøýýðìðøèøýúÝÕÝÝúðìðøèøúÝÍÝÝÝÅÝÝj-sUj²rUj7rU jU 56NH565j5U5NH6N2Ã3ÃLÃMÃNÃUÃVÃaÃbÃcÃhõöÃÄÄÄÄ,ĘĠġĸĹÄÈÄàÄáÄaÅbÅzÅ{Å|Å€ÅÅ­Å®Å ÆÆÆÆ-Æ.ÆCÆGÆIÆÆ‚ÆÉÆÊÆìÆíÆÇÇÇ)Ç-Ç.Ç3Ç9Ç;ÇiÇoÇǓǬǭǿÇÀÇØÇÙÇÚÇàÇáÇFÈKÈLÈPÈúòúúðìðéáÝáÛÛáÝáÛéúÓúúééáÝáÛÏÛééáÝáÛÏÛËÛÏÛÇðéú¿úúðìðj tU6]5NH56j%tU55j5UNH6NH6j¨sU jUKPÈRÈSÈmÈnȆȌȎÈ=É>ÉVÉWÉXÉ]É^ɸɹÉÒÉÓÉÔÉÛÉÜÉÊÊÊÊ2Ê8Ê:ÊÇÊÈÊÙÊÚÊòÊóÊôÊùÊúÊ[Ë\ËuËvËwË~Ë˵˽˾ËÍËÎËÚËßËàËúËÿËÌ Ì ÌÌÌ(Ì-Ì.ÌDÌIÌYÌ^ÌjÌoÌ|ÌÌ…Ì̵̡̠̰̎Ì÷ó÷ñíñèàèèèØèè÷ó÷ñíñÕèÍèèèÅèèñ÷ó÷ñíñÃñ÷ó÷ñíñÃÃÃÃñ÷ó÷ñí6jŽvUjvUNHj–uUjuU jU5655j5UMÌ…Ì9ÍÎÛÎ…ÏèÐØÑfÕrÖz×HØÙÑÙÚñÚåÛ3ÝžÝÞÒàNáåbåIæ,çèÂèé,êýýýýýýýýýýýýýýýýýýýýýýýýýýýýýdµÌÁÌÅÌÇÌÕÌÖÌïÌôÌÍ Í8Í9Í@ÍAÍWÍXÍfÍÎÎ-Î.ÎCÎMÎNÎw΂δξÎÒÎÓÎÛÎãÎäÎõÎöÎþÎÏÏ Ï ÏÏ"Ï*Ï0Ï8Ï>ÏAÏGÏNÏTÏWÏ]Ï…ÏώϣϤϹϾÏÇÏÑÏÒÏÖÏØÏîÏóÏÐ Ð#Ð(Ð;ÐCÐPÐUÐqÐvÐИХЪЫдÐßÐàÐèÐéÐüÐýùýöôôïýçãçýçãçýùýôôöýçãçýùýùýôôôôôôýçãçýùýùÝùýôôôôôôôôÙôöçã6NH 56NH5j5UmHsH6NH565VüÐýÐÑÑÑ Ñ%Ñ9Ñ<Ñ=ÑAÑFÑOхъѨѮÑÃÑËÑØÑàÑáÑøÑùÑÒ Ò ÒÒÒNÒOÒgÒhÒiÒmÒnÒÙÓÞÓýÓÔVÔWÔªÔ«ÔÄÔÅÔÆÔÌÔÍÔãÔäÔfÕgÕÕ‚Õ™Õ Õ£Õ©ÕªÕ&Ö'ÖDÖEÖ]Ö^Ö_ÖcÖdÖjÖkÖrÖsÖÖŽÖ¥Ö¬Ö¯ÖþÖ÷õñõïïëïïïïïõ÷ç÷õñõïâÚââïï×âÏââ×÷ç÷õñõ××âÇââ×÷ç÷õñõjxUj†wUNHj wU jU56NH6565j5UNþÖ×:×;×V×W×p×q×r×v×w×z×{וז׭׶׹׿×ÀרØ"Ø#Ø;Ø<Ø=ØEØFØHØIØ^Ø_ØpØyØ|ظعØߨàØøØùØúØÙÙÙÙ%Ù&ÙBÙKÙNÙwÙxÙ–Ù—Ù¬Ù­ÙÆÙÇÙÈÙÍÙÎÙÑÙÒÙóÙôÙÚýúõíõõåáåßÛßúúõÓõõåáåßÛßúõËõõåáåßÛßúúõÃõõ¹´¹°5\ 5\j5U\jñyUjvyUjûxU5655j5Uj~xU jUNH6CÚÚÚڈډڛڜڥÚñÚøÚùÚÛÛ"ÛUÛVÛnÛoÛpÛuÛvÛËÛÌÛåÛæÛûÛüÛÜÜÜÜ&ܾܽÜÖÜ×ÜØÜßÜàÜõÜöÜ ÝÝ&Ý'Ý(Ý0Ý1Ý3Ý4ÝIÝJÝ^ÝeÝfÝžÝŸÝ¯Ý°Ý¿ÝÆÝÇÝÞÞ Þ4Þ5ÞGÞNÞQÞƒÞ‹Þ»Þ¼ÞÞÞùõóñéåéññéåéñàØààÕéåéñÑñÏàÇààÕà¿ààéåéñÑñéåéñÑññéåéñÑñÏÕjd{UjézU656NHjnzU jU5j5U5\5\ 56\]KÞÞßÞ÷ÞøÞùÞþÞÿÞ/ß0ßHßIßJßOßP߾߿ßààiàjà¡à¨àÉàÊàÒàÓàêàëàáááá$áEáLáNáVáWáoápá„á‹á”ášá¤á²á´áçáîáââ ââââ„âËâÒâÓâ4ã;ãJãKãƒãŠãÀãÿãää?ä@äYäZä[ä\ä]ä¾äúòúúúêúúçççåçÝÙÝ×Ó×åå×ÝÙÝ×Ó×Ó×Ó×åååÏå×çåÌå×È×úÀúújÕ|U5NHNH6NH5655j5U6NHjZ|Ujß{U jUL¾ä¿äååååå%å'å0å1åIåRåWå`åbåcå…å†å¥å®å±åææ$æ%æ=æ>æ?æFæGæIæJækælæŠæ“æ–æçç ç!ç"ç)ç*ç,ç-çIçJçcçlçoçÚçÛçóçôçõçýçþçèèèè+è4è7èœèèµè¶è·è¿èÀèÂèÉèÊèÜèÝèýõñõïëïëïééõñõïëïýäÜääõñõïëïäÔääõñõïëïäÌääõñõïëïäÄääïõñõjÃ~UjH~UjÍ}UjR}U jU65655j5UNHMÝèæèëèìèééééé6é7éFé ê ê$ê%ê&ê*ê+ê,ê3ê4êMêNê]ê$ë%ë>ë?ë@ëFëGëˆë‰ë¢ë£ë¤ë¨ë©ë«ë²ë³ëÌëÍëÜë®ì¯ìÈìÉìÊìÐìÑìöì÷ìíí,í-í.í2í3ítí{í¢í£í»í¼í½íÃíÄínîýùý÷ýïëïýæÞææýïëïýæÖæææÎææýïëïýæÆææÃæ»ææ÷æ³ææj¯Uj2UNHjµ€Uj8€Uj»Uj>U jU5j5U6565F,ê«ë5íGí~ððññóófônô¡ôÃöl÷HøÔøúûÒüÓüŠý‹ýáÿâÿ+,ýýûùùóùùùùñùïääïääïßßßßßßßa & F a ÆhЄÐ^„Ða Æ_¾$dnîzî;ï<ï‚ï¬ï­ïµïûïüï‰ððxñyñóŸó9ô:ôSôTôUôWôXô¡ô«ô­ô¸ôÌôùôúô-õ5õ?õGõ}õ†õ“õ¶õöö÷$÷k÷ž÷¯÷%ø&ø?ø@øAøDøEøHøOøPøYøløðø ùiújú‘ú’ú«ú¬ú­ú°ú±úûûHûrûsû×üáü”ý›ýýúöðöúýúöëãëëßÝßÝúýýýýýÙ×ýëÏëëßÝÊÝÙúëÂëëßÝúýýj$ƒU 56]j§‚U]6]556j*‚U jU 5NH\5\NH6L›ý©ý³ý0þ8þyþ€þ5ÿ<ÿ ÿ¡ÿ»ÿ¼ÿÔÿÕÿÖÿÝÿÞÿäÿëÿ¹Àçè  ƒ/=]u‚ƒ›œ ¡tu²¼ÓÔêòõûUfƒŽ›§ºËÍÞ ) 7 I j t ƒ – ¥ ® ± ½ ® ¯ È É Ê Í ýýýýúõíõõýýúýõåõõããýõÛõõúýúýýýýýýýýýýýýýõÓõj…Uj—„U5j„Uj¡ƒU jUNH6S,6Oƒ/SÍ ¯ Ð ¼ šï-01AKÐÚk€*úøöëëøöéééééÞÞÞéúúÜÚÜÚÜÚÜc a ÆhЄÐ^„Ða a Æh¤„¤^„¤a & FÍ Î Ð ä ó    T h Ð ç ( 1 7 8 P Q R U V } ‹ 6 A ¤ ¥ ÆÎ-6—«Ùák€ýþ5°ÁVWjÖ×èKLn˜™²ÝÞöGHXˆ‰ÒÛ6;„…úøøøøøøúðúúøøíøøøøøøèíãÚÒÉÚÒÉÚÒÉÚÒÉÚÒÉÚÒÉÚÒɾҾҾã¾56\]mHsH6\]mHsH\]mHsH5\]mHsHmHsHOJQJNHj…U6 jUH*5¯°W×L™ÞH‰Ó7…ëXz\GYõ ö !6![!„!®!Ü!ýûùù÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷ûùùðððððð Æ8¼ac…‰“êëøHO¼óKPWXjºÁ`hmsyzÎÕQT[\e´»9>FGž$Ÿ$š%Ø%Q&e&ñ&û&' '''' '%'''_'e'~''ƒ'‰'!("(:(;(<(B(C(G(H(±(²(Ë(Ì(øóïóøóéóäóÜóäøóéóÜóÜóäøóéóÜóäøóéóÜóäÙÔÒÒÒÐÌÐÌÐÒÙÒÇ¿ÇÇÙÇ·j…†Uj †U jU5656OJQJNH6]mHsHOJQJ 6mHsH5\mHsH56mHsHHÜ!þ!$"K"v"™"À"â"#3#b#n#z#„#²#ö#9$:$Y%Z%š%À%Ø%Ù%Ú%&''øøøøøøøøøøøøøøøøööööôôîöìöö Æ_¾$ Æ8¼Ì(Í(Ð(Ñ(Ö(Ú(à(á(Á)Â)Ú)Û)Ü)ã)ä);*>*D*F*3+8+ê+î+Ú,ß,ä,æ,‹-Œ-Ù-Ú-é-ê-... . .l.p..‚.¯.¶.Ì.Õ.ã.ç.ø.ù.&///»/¾/î/ï/-1.1F1G1H1K1L1³1´122;2<2Q2R2a2b2w2x222­2º2úúøôøúìúúøôøøøøôøééúáúúøôøßßøôøßßéú×úúééÐÎÐÐÎÐËË0J( jUjø‡U6j}‡UNHj‡U565 jUN'Ö(;*3+ê+Ú,l.ã.õ/þ/ 0 0µ0Ò02;22­2Â2Ó2ó2ô2È3É34/404ö5J6ýýýýýýýýûûùù÷ùõ÷óóóóùùùûûùù÷'eº2Á2Â2Î2Ó2Þ2ó2É3/4ñ4ò4 5 5 555ö5÷566J6X6h6u6‚6ƒ66”6Ÿ6º6Â6{7|7”7•7–7™7š77ž7´7µ7Û7é7ù78%8&82878?8á8â8Õ9Ö9ì9í9::-:::Y:Z:f:k:s:D;E;;ž;·;¸;¹;¼;½;)<*<J<K<e<f<ûøøûóîæîîßÝßøøûøøøîÕîîßÝßøøûøøÒßÝßøøûøøÒîÊîîÒßÝßji‰UNHjîˆU jUjsˆU jUOJQJ0J(0J(5PJ6h6ƒ6”6º6Ç6È67Û7ù7&878r8s8Õ9:-:Z:k:‚:ƒ:J<<®<Â<Ó<Ô<>W>u>ýýýýýûûùýýýýûûùýýýýûûùýýýûûùý'f<<ž<®<»<Á<Â<Î<>> >!>W>e>u>‚>ˆ>‰>•>š>¥>å?æ?ÿ?@@@@@ @@@H@V@f@s@y@z@†@‹@–@~AAÕAÖAàAáAúAûAüAÿABBBBBEBSBcBoB¹BºBÓBÔBÕBÖB×BøBùB[C\C«C¯CDD DDhDiD‚DýýùýòðòýýùýýëãëëòðòýýùýýààëØëëòðòýýëÐëëààÎÌÎë65jàŠUjcŠUNHjæ‰U jU jU0J(50J(Ou>‰>š>Ï>Ð>@H@f@z@‹@À@Á@BEBcB{B|BC€CªCDEE—EÙE÷EFFýýýûûùýýýýûûùýýûûûûððêêùýýû„<^„< & FZ„¤^„¤'‚DƒD„D‡DˆDEE—E˜E­E®EÙEçE÷EFqFrF‰FŠF£F¤F¥F¨F©FqGrG‹GŒGGG‘GóGøGCHDHEHLH—H˜H«H¬HÖHäHôHI I$I0I5IˆI‰I›IœI¾IÌIØIåIJJJJJ!J"J#J/J–J—J§J¨JÀJÁJ÷òòðéçéääáòÙòòòÑòòÏðÏéçéääËäÅéçéääËò½òòäáòµjOUjÔŒU mHnHu0J(55jWŒUjÚ‹UNH0J( jU6 jUj]‹UGFÓGòGDH—HÖHôH$I5I6IˆI¾IØI#J4J5JîJK/KŽKŸK KkGkkkrk†k‹k k¨kÂkÌkxl±l²l³lÈlÉlílûlmm%m&m2m7m?mGmnnnn@nNnVncnŠn‹n—nœn¤n¬nðo÷õíõõõéõáõõÞõõÞõõÞÜõõõõ×ÐÎÐËËÇËËÂÐÎÐËËÇËËÂmHsH0J(50J( jUOJQJ\NH5B*\phÿ™5NH5B* \phº55B*\phØWIílm&m7mGmHmn@nVn‹nœn¬n­nïoðoòoóo qÕr;sQsls}s¶s·s=u€u–u±uýýýýûûùýýýýûûû÷ûûûùýýýýûûùýý'ðoño qqËqÌqÕrÖrërìrùrúrss;sIsQs^skslsxs}s…s¶s÷tøt=u>uXuYu€uŽu–u£u°u±u½uÂuÊuùu`vavv‚v²vÀvÈvÕvâvãvïvôvüvw§w·w;x?Z[š¨°½ÓÔàåíù<…=…S…T…b…c…y…óêåêåÞÜÞÙÙÕÙÙååêåÉêåêåÞÜÞÙÙÕÙÙåÃåÃå»å»µåÞÜÞÙÙÕÙÙåÞÜÞÞÜ \mHsH5\mHsH 5mHsHj)¹UmHsH0J(50J( jUmHsHjUmHsHj¬¸UmHsHGz{‹{›{œ{§|è|þ|,}=}Q}R}Š}v€>š°ÔåùúŒƒùƒ<…±…Ç…Ý…î…Z†ýýûûùýýýýûû÷÷÷ùýýýýûûûûùýýýýa'y…z…±…¿…Ç…Ô…Ü…Ý…é…î…ö…5†6†O†P†Q†W†X†Z†'‡(‡)‡C‡D‡{‡‰‡‘‡ž‡¦‡§‡³‡¸‡À‡̇ÓˆÔˆêˆëˆ‰‰%‰2‰?‰@‰L‰Q‰Y‰”•°Ž±Ž»Ž¼ŽÕŽÖŽ׎ÝŽÞŽ  #$%*+8XYjk“¡©¶ÃÄÐÕÝùööòööíåííàùÞùööòööàùÞùööòööÛÛíÓíííËííÆùÞùööòööOJQJj ºUj#ºUNHmHsHj¦¹U jU0J(50J( jUNZ†[†(‡{‡‘‡§‡¸‡͇̇Óˆ‰%‰@‰Q‰^‰_‰.Š/ŠXŠŠ‚ŠˆŠW‹}‹ž‹¿‹ÞŒߌýýûùùùùýýûùùùùýýýýýýýôôôïïý & F2 & F;'ߌÿ./8X“©ÄÕâã„…ºïðöÅ‘ë‘&’G’f“g“”Ôe•–ýýýýûù÷÷÷÷ýýýýýýýòòòííýýýýý & F2 & F;'Ý!”"”K”L”e”f”g”n”o”z”{”––6–7–8–>–?–k–l–„–…–†–‹–Œ––‘–¦–§–Ì–Ú–â–ï–ü–ý– ———~——˜—™—®—¯—ô—#˜H˜I˜b˜c˜d˜j˜k˜n˜o˜ƒ˜„˜¦˜´˜¼˜ɘÖ˜טã˜è˜ð˜[š\šušvšwš~ššµšýøðøøýøèøøøàøøÙ×ÙÔÔÐÔÔýÙ×ÙËøÃøøÙ×ÙÔÔÐÔÔø»øøj ½Uj¼U B*phÿ0J(50J( jUj¼Uj˜»Uj»U jUNHJ––Ì–â–ý–———˜—ô—n˜¦˜¼˜טè˜ô˜õ˜µš›'›B›S›_›`›Ù›œ9œtœ…œýûùùùùýýûýûùùùùýýûùùùùýý÷ùùù'µš¶šÕšÖš››'›4›A›B›N›S›[›Ù›Ú›î›ï›œ)œ9œFœsœtœ€œ…œœœœ¤œ¾¿µž¶žΞÏžОԞ՞؞ٞñžòžŸ&Ÿ6ŸCŸPŸQŸ]ŸbŸmŸyŸŸD F z | à ü ¡6¡p¡r¡¤¡¦¡¨¡ª¡¬¡°¡È¡Ò¡ä¡΢Ï¢Тê¢ë¢"£0£@£ù÷ùôôðôôù÷ùôôðôôôííèàèèù÷ùôôðôôôù÷ùôôð×ðÏ×ð×ðôôÊù÷ùômHsHj¾Uj0J(5UjнU jUNH0J(50J( jUP…œœœªœ«œÄØžŸ6ŸQŸbŸyŸ†Ÿ‡ŸD à ¡°¡Ò¡0¢1¢Ï¢"£@£œ£­£®£¥¥ýýûûûùýýýýýûûùýýýýóîùýýýóîîa & F Æ_¾$'@£M£œ£¨£û£ü£¤¤¤¤¤,¤-¤•¤–¤ý¤þ¤¥¥¥¥¥Ü¥Ý¥¦%¦/¦Z§_§n§p§q§r§…§†§³§Á§ѧÞ§ó§ô§¨þªÿª<«D«Ž«3­4­L­M­s­­­š­§­¨­´­¹­Ä­Ó­å­í­Ú®û¯…°†°£°¤°ذæ°ÿ° ±±±&±+±ýùýôìôôééôáôôéÜ×Ü×Ü×ÐÎÐýýùýéÌ×ÐÎÐýýùýýÆýÂÐÎÐýýùý5\ 0J(5\6 jUOJQJmHsHjÿ¾UNHj‚¾U jU0J(50J(L¥¦/¦?¦L¦[¦s¦¦¯¦¿¦̦Û¦ó¦§/§?§L§p§q§³§ѧô§¨¨=¨‰¨¹¨ë¨úøøøøøøøøøøøøøøøøöôòòòöööíí & F<'a & Fë¨!©"©„«…«Ž«¥«Ù«õ«¬¬¬6¬e¬Œ¬™¬š¬²¬â¬ÿ¬&­3­s­­¨­¹­å­ò­úõóóóññññññññññññññññïííííí'$$a$ & F<ò­ó­Ú®â®û¯…°ذÿ°±+±H±U±V±A²¬³´T´y´”´¥´Ë´Ù´Ú´eµ¥µð¶s·t·ýøøóóñïïïïïýýýýñïïïïïýýíííë$a'a & F±a & F+±6±H±P±U±V±²²^³_³´´0´1´T´b´y´†´“´”´ ´¥´°´Ë´Ó´¶¶·¶t·u·‡·ˆ·¹·Ç·Þ·ë·ö·÷·¸¸¸.¸6¸ñ¸ò¸—¹˜¹«¹¬¹͹Û¹ò¹ÿ¹ º ººº&ºAºIº(»)»>»?»`»n»…»’»£»¤»°»µ»À»Û»ã»ý¼þ¼#½$½8½9½x½†½ž½«½±½²½¾½ýνì½ó½ ¾¾’¾ýýýúúóñóýýíýýýúóñóýýíýýýúóñóýýíýýýóñóýýíýýýúóñóýýíýýýý0J(5 jUNH0J(]t·¹·Þ·÷·¸.¸:¸;¸—¹͹ò¹ ººAºYºZº'»(»`»…»¤»µ»Û»ð»ñ»#½x½ž½²½ýýûûûûûùùýûûûûûùùùýûûûûûùùýûûû'ýì½ ¾¾¾‘¾’¾¿£¿.Á/ÁB’¸ÂÌÂÝÂÃ%Ã0Ã1Ã(Ä`Ä~IJÄÃÄÄÄnÅoÅýýýûûûöööûðîýýýýýýûûìýýýûûû Æ_¾$ & F·'’¾ ¾¿!¿£¿±¿†Á‡ÁBÂCÂ[Â\’ ¸ÂÅÂËÂÌÂØÂÝÂèÂà Ã%Ã-Ã(Ä)Ä<Ä=ÄWÄXÄ`ÄnÄ~ċıIJľÄ9ÈEÈ4Ë5ËjËk˃˄˅ˉˊËË©ËÒÏêÏÐŽÐ#Ò$Ò;Ò<Ò=ÒEÒFÒ{Ò|ÒÒÒ¶ÒÄÒÐÒÝÒäÒåÒñÒÂÓÃÓÚÓÛÓÜÓàÓýýýúóñóîîêîîîîóñóúîîêîäúß×ßßääúßÏßßóñóîîêîßÇßjpÀUj÷¿Uj|¿U jU 5mH sH 0J(50J( jUNH5NoÅÆ‚ÆoÇpÇ8È9ÈŽËË1ÌkÌÂÌ(ÍÎÎmÏÑÏÒÏ{Ò¶ÒÐÒåÒöÒ÷Ò#Ôýýýýýýöðöâââââ×××öÕÓÓÓýý' „hdð¤^„h & FX ÆhЄÐ^„Ð Æ_¾$ & FW@&àÓáÓüÓýÓÔÔÔÔÔ0Õ1ÕOÕPÕgÕhÕiÕqÕrÕ~ÕÕŽÕÕ¸ÕÆÕÒÕßÕæÕçÕóÕJÖNÖ6×;×ø×ù×HØLØkØq؃؎Ø"Ù#Ù$Ù-Ù€ÚÚ©Ú¬ÚÛÛTÛUÛ´Û½ÛÜ Ü ÜÜ'Ü(Ü)Ü*Ü+ÜÓÜÔÜ7Ý8ÝQÝRÝSÝTÝUÝÝ“ÝÄÝÅÝ?Þ@ÞúúòúúïúçúúàÞàÛÛ×ÛÕÕïÕÕÕÕÕïÕïïÕïúÍúúïúÅúúÕïïjXÂUjÛÁU50J(50J( jUjbÁUNHjéÀU jUN#Ô$ÔlÔmÔ~Õ¸ÕÒÕçÕÖÖIÖ5×GØj؃Ø#Ù¨Ú³ÛŽÝQßÂßWà›áâŸã'æ.èýýýýûùùùýýôôôææææææææôææææ & FK ÆhЄÐ^„Ð & FK'@ÞÿÞßßßßßßQßZßÂßÈßXà_àkáláœá¡áPâQâ‘â™â™ãšã ã¨ãQäRä©äªä6å­å®åææ&æ(æ.æÚæÛæ6ç7ç’ç“ç/è2è‹èŒèwê|êëƒëÚëÛëåëîëíí’í§íbîiîÂîÍî³ï´ïÊïÏï$ð%ðMñbñòòòò·ó¦õ§õ¨õ½õ¾õîõüõöúòúúðððíðíðíðííðéðéððíííðíððíððçççíðíðððâÛÙÛÖ0J( jUOJQJ65NHNH5jÕÂU jUT.èuê€ëäëíÉïMñòNóOó·óÒóôQôôÌôõPõ™õ¦õ§õîõöö;ö<öòöúúììììììêêèèèèèèèèèêæäääêê' & FK ÆhЄÐ^„Ð & FKöööö+öÍöÎöåöæöçöíöîö ÷$÷œ÷÷´÷µ÷¶÷º÷»÷¿÷È÷øøøø ø$ø%øÖø×øèøéø ùù(ù5ùLùMùYùpúqúˆú‰úŠúú‘ú¿úÃúmûyûfügü~üü€ü†ü‡ü”ü•üòüóü¬ý­ýÂýÃý×ýØýþþþ(þ2þ3þ?þýùýôìôôêôâôôêôÚôôÓÑÓýýùýôÉôôêêôÁôô¾¾¾ÓÑÓýýùýNHj6ÅUj½ÄU jUjDÄUjËÃU5jRÃU jU0J(50J(Kòöóö÷¾÷Öø ù(ùMùlùmù•ú–ú¾úlûÁýÂýþþ3þvþwþÉþÊþõþ\ÿêÿýýøøöôôôýýýýææýöôôôýýýýææ & FZ Æh¤„¤^„¤' & FY?þöþúþ[ÿ\ÿ]ÿaÿéÿêÿëÿõÿ{|•–—ž¦§MNOZ!";<=DEJKdeflmtuv‚±²ÉÊËÑÒÔÕÖÛ|}~ƒÁÂ-.ˆ‰‘’“œŸïð!ýûýû÷òêòòçû÷çòßòòò×òòûýòÏòòûýûýûçûçûýÌÇÌûý0JpNH0Jpj&ÇUj©ÆUj,ÆUNHj¯ÅU jU5\65NêÿNuÕ}Â.’–øKLü( t œ ¬ ÷ . D x öèÚÚÚÌÌÚÃÃÚ½½»»»»»»»¹ Æ_¾$ & FZ„¤^„¤ & FZ Æh „ ^„  & FZ Æh¤„¤^„¤ & FZ Æh„¤^„¤ & FZ„ ^„ !qr•–—©RS÷øùPQJKLäåü˜ › œ    D E W X x †  ª Ê Ë × ¥ © 9 : ; F   % & ' . / 4 5 N O P V W ^ _ e Ž  § ¨ © ýøýöôñöôñöìåìàÖàÖàÏÍÏÊÊÆÊôö½µ½½½­½½öô½¥½j™ÈUjÈUjŸÇU jU5\0J(50J( jUOJQJmHnHuOJQJ NHOJQJOJQJNH560JpNH0JpAx  Ë   z { ¤ : _ $Ú-·ÓÚ–ÏX9L]n|}ýýýûûûûíäíííííäíÖííÐÐÐÐÎc„7^„7 & FZ Æhª„¤^„¤ & FZ„¤^„¤ & FZ Æh¤„¤^„¤'© ® ¯ çèCDŸ #$%2ÒÓÙÚÛé%&,-.4de|}~„…¸ÆÔåÛä—›žÍÐÜYcepvw†‡´ÂÙæìíù{|×Üëì\ ] ^ h ä å æ í ™!š!›!Ÿ!ñ!ò!"ú÷÷÷õó÷õó÷õóúëúúóóóóèóäèÝÛÝØØÔØÔ÷ó÷õóõóõóõó÷0J(50J( jU5\0JpjÉU56NH jUT}v´Ùí¯°Ö] å š!"¦"K$:%E&v&Ö&'x'*)u)Ø*ýûùùù÷÷÷÷éééÛÛÛÛÛÛÛÛÛÛÛÛÛ & FZ Æh „ ^„  & FZ Æh¤„¤^„¤'c"" ""¥"¦"§"©"­"¹"J$K$L$T$W$c$9%:%;%?%B%N%%Ž%î%ï%& &9&:&;&A&B&D&E&F&V&Z&u&v&w&†&‰&Ê&Ë&Õ&Ö&×&æ&é&''''w'x'y'‚'(())))*)+)/)t)u)v)~)))Ô)Õ)u*v*É*Ê*×*Ø*Ù*ä*ç*ó*Œ++¦+ýûý÷ôýûôý÷ôññìäììýûôýûôßôýûôýûýûýñýûýûôñññýûôì0JpNHjÉU jUNH0Jp5\56V¦+§+¨+°+±+',(,),/,-€-˜-™-š- -¡-—.˜.(/)/*/2/5/A/z/{/{0|0ã0ä0D1E1€1122±2²2Ó2Ø2Û3Ü3ô3õ3ö3ú3û3 445555`5a5‹5Œ555¾5¿5À5Å5û5ü56Q6R6Å6Æ6Þ6ß6à6æ6ç6w7x7ì8‹;÷òòðîòæòòãðßÜããðãððãîòÔòòîãîãðîðîðîãòÌòòãÉCJj}ËUjËU0Jp5\NHj‡ÊU56 jUj ÊUNØ*(,)/ä012Ò2 4«45Œ5¿5ü5W6X6ê8ì8 9%9ñññßßßññÔÏÁÁ³±«¥££„h^„h Æ_¾$ & FK ÆhЄÐ^„Ð & FZ ÆhЄÐ^„Ð & FZ „hdð¤^„h & FZ Æh-„-„&ÿ^„-`„&ÿ & FZ Æh „ ^„ %9M9ˆ9Ò9 :K:€:±:è:é:í:î:;#;V;–;Õ;ú;<D<‡<Ó<=]=¬=ê=÷=D>ƒ>’>ýýýýýýýýýýýýýýýýýýýýýýýýýýýýý‹;Œ;ž>Ÿ>­>®>È>Ö>Þ>ë>ò>ó>ÿ>?q?r?Ñ@Õ@AAAA_A`AaAkABB+B,B-B3B4BÀBÁBÂBÆB,C5CoCzCZDfDGEMEÂEÈE=G>GWGXGYG_G`G(HÊIËIÞIßI JJ#J0JBJCJOJ{JÛJÜJM€M—M˜M™MŸM MûøñïñììèìèåãáãáãÜÔÜÜáããããããÜÌÜÜÇñïñììèìèåÜ¿ÜÜjîÌUOJQJjqÌUjøËU jU65NH0J(50J( jUCJCJNHK’>ž>È>Þ>ó>??ª@«@Ð@A`AÁB+CnCYDFEÁE¯G°G'H(HAHbHŒH¶Hýûùùù÷÷÷÷ééééÛÛÛÛÛ÷÷÷ýýýý & FZ ÆhЄ ^„  & FZ Æh¤„¤^„¤'¶HàH I4I^IˆI²I½IÊI J#JCJ|J}JHKIKpKÒKòMóMNçN P~QTÄTýýýýýýýýûùùù÷÷÷÷òò÷÷äÛäÛä & FZ„¤^„¤ & FZ Æh¤„¤^„¤ & F]' MN"NæNçNèNóNœOO¸O¹OÒOÓOÔOÛOÜOáOâOûOüOýOPP P P PPkPlP}Q~QQ‹Q•Q™QÆQåQ9R:RøRùRTTTTT)TzT{TÃTÄTÅTÑTUUôUõUŠVWW$W%WZWhWWŒW“W”W WÖW×XØXBYCYøZÿZ[[ø[ýû÷ôïçïïïßïïûýôûýýÜôôôûýôûýôû×ÐÎÐËËÇËÇôôûô0J(50J( jUOJQJ0JpjäÍUjgÍU jUNH5\65NÄTõUöUŠV¡V¹V×VöVWWZWW”WÖW×WIYJYwZxZÍ[Î[÷[Å]œ^h_ñëéççççççåãããééééééééñÕÕ & FZ Æh „ ^„ ' Æ_¾$ & FZ Æh¤„¤^„¤ø[û[ÿ[\]ž]@^O^ñ^ò^_*_i_n_Ä_Å_` `½`Ï`aacc9c‰P‰Q‰t‰‚‰Œ‰™‰§‰¨‰±‰¿‰tŠuŠ,‹-‹?‹@‹Y‹g‹q‹~‹Œ‹•‹›‹()LZdqˆŽ1Ž2Ž÷òòëéëæáæÝæáÕáËá¾ËáËỹ»ëéëææÝæÝ»ëéëææÝæÝëéëææÝæÝë5NHj¼ÑB*UphÿjB*Uphÿ5B*\phÿ0J(5 B*phÿ0J( jU jUjCÑUI›‹œ‹LdŽ1ŽjŽ‚Ž›ŽªŽ«Ž67ijƒ¢¾É‘‘5‘C‘D‘j‘‘ýýûùùùýýûùùùýýýýý÷÷÷÷ûùùùýýõa'2ŽEŽFŽjŽxŽ‚ŽŽ›Ž¤ŽªŽ 2Ehs‹¢©çòjÉÊßà‘‘‘%‘5‘>‘C‘j‘n‘‘¡‘Ù‘Þ‘°’±’É’Ê’Ë’Ñ’Ò’“Ó””” ”!”'”(”m”u”ý”þ”•&•A•h•j•u•‰•Š•–/–F–G–R–ýöóóïóïíëííííæöýöóóïóïëëëáÙááÖáÎááëëóÉóïÉÁÉºÉ B*NHphÿ5B*\phÿ B*phÿj´ÒUNHj9ÒU jUOJQJ560J(50J( jUH‘Ú‘n”þ”•j•‰•Š•¬–­–8—ö—˜1™ì™šI›œ“ˆž2ŸkŸ…Ÿ™Ÿ² Í Π^¡_¡ýýýûùùù÷÷÷ýýýýýýýýýýõùùùù÷÷÷'aR–S–l–m–n–r–s–ª–————&—/—2—6—8—9—M—N—X—_—k—ö—÷—˜˜"˜(˜:˜Q˜W˜\˜]˜˜€˜ ˜¡˜·˜¼˜Õ˜á˜æ˜õ˜ö˜0™1™2™V™W™j™k™q™v™‘™¡™§™ë™ì™í™ š šš!š6šDšIšŒššŽš®š¯š¾š¿šÅšÊšãšñš÷šH›öñäöñöñáßßß×Ó×ÑÍÑ×Ó×ÑÍÑßá×Ó×ÑÍÑßáÑ×Ó×ÑÉÑÍÑßÑ×Ó×ÑÍÑßÑ×Ó×ÑÉÑÍÑß5NH5655j5U6NHj/ÓB*Uphÿ B*phÿjB*UphÿOH›I›J›j›k›z›{››†›Ÿ›­›²›ÿ›œœœœ,œ1œDœRœXœWX“”²³ÇÌâòø‡žˆž‰ž£ž¤ž´ž¹žÍžÙžÞžûžüž1Ÿ2Ÿ3ŸEŸFŸkŸyŸ…Ÿ’ŸçŸ * ^ _ ¬ ­ ² ¾ 7¡8¡O¡P¡Q¡Y¡Z¡“¡—¡.¢6¢V¢[¢ü¢ý¢6£ýõñõýíýéýçýõñõýéýçäõñõýéýçýõñõýéýçäýÝÛÝØØÔÔääØÏÇÏÏýýýäj¬ÓU jU0J(50J( jUNH6565NH5j5U5N_¡’¡-¢U¢5£[£ä£u¥Ì¥å¥ú¥”¦•¦B§C§&¨'¨1¨\¨u¨’¨ž¨Ÿ¨ƨ਩+©ýøøêêêêèæææýýýýýýäääääääää' & F^ ÆhЄÐ^„Ð & F^6£?£\£c£å£é£%¤T¤h¤ƒ¤„¤¤ž¤Ÿ¤£¤¤¤ý¤þ¤¥8¥N¥R¥S¥t¥u¥v¥ƒ¥„¥Ì¥Ú¥å¥ò¥ù¥ú¥¦ ¦ ¦ñ¦ò¦e§“§”§«§¬§­§±§²§ȧɧâ§ã§ä§è§é§ÿ§¨¨¨¨¨¨1¨>ª?ªýýýùñìäììáÜÚÖÚÏÍÏÊÊÆÊÆÊáÆ½Æµ½Æ½Æ½Æ­½Æ½Æ½Æ¥½Æ½Æ OJQJj˜ÕUjÕUj¢ÔUj0J(5U0J(50J( jUNH\\ B*phÿNHj%ÔU jU5B*\phÿ5\5?+©G©b©©£©°©É©ä©ª%ª2ª>ª?ªxªŪíªþªÿª6¬7¬j¬¡¬¢¬­2­d­u­v­®ýýýýýýýýýýýûù÷÷÷ûûûûûûù÷÷÷ûû'?ª@ªQªRªxª†ªŪÒªìªíªùª¢¬£¬·¬¸¬ƬǬÞ¬߬­­2­?­c­d­p­ЭÑ­®8®ß®à®ø®ù®G¯U¯`¯k¯›¯¨¯¶¯¯ǯЯ֯߰à°ù°ú°û°±± ±±±ñ[²a²9³E³ͳγY´Z´x´y´´дÛ´æ´µ#µ/µ;µ@µIµOµ¶¶¶¶¶#¶ù÷ùôôðôù÷ùù÷ùôôðôíðèù÷ùôôôðôôðãÛããíí××íù÷ùôôôðôôðãÏãjŽÖU5\jÖU jUOJQJNH0J(50J( jUR®®8®d®®²®Ó®ß®G¯`¯›¯¶¯ǯÖ¯ׯ[²Y´´Û´µ/µ@µOµPµ'¶q¶жŶà¶ýýûûûûûù÷÷÷÷÷ýýýù÷÷÷÷÷ýýù÷÷÷'#¶$¶'¶(¶?¶@¶q¶¶ж•¶ŶÒ¶à¶ì¶ñ¶ú¶·0¹1¹H¹I¹X¹Y¹n¹o¹Œ¹š¹¥¹°¹à¹í¹û¹º ººº#ºŒººÊ»Ë»$¼%¼:¼;¼x¼†¼‘¼œ¼±¼¾¼żÕ¼å¼æ¼ò¼÷¼½ ½4¾5¾G¿H¿`¿a¿b¿h¿i¿ƒ¿„¿”¿•¿­¿®¿¯¿°¿±¿Í¿οæ¿ç¿è¿ï¿úóñóîîîêîîêóñóóñóîîîêîîêîççóñóîîîêîêîîêçúßúúçú×úúúÏújØUj†×Uj ×UNH0J(50J( jU jURà¶ñ¶··m¸0¹Œ¹¥¹à¹û¹ ºº+º,ºp»$¼x¼‘¼±¼żæ¼÷¼ ½ ½¤¾¥¾iÀèÀÁ!Áýýûûûùýýýýýýûûûùýýýýýýûûûûùýý'ï¿ð¿À À!À"À#À*À+ÀDÀEÀ]À^À_ÀfÀgÀiÀjÀƒÀ„À–À—À°À±ÀèÀöÀÁ Á!Á.Á5ÁEÁUÁVÁbÁgÁpÁzÁÖÁ×Á3Â4ÂÿÂÃ}Ã~æçÿÃÀÃÁÃÆÃÇÃÊÃËÃçÃèÃüÃýÃÄÄBÄPÄ[ÄfÄ{ĈħķÄÇÄÈÄÔÄÙÄâÄìÄOÅPÅhÅiÅúúòúúúêúúãáããáãÞÞÞÚÞÚÞÞÚ××Õ×úÍúúãáããáãÞÞÞÚÞÚÞÞÚúÅjíÙUjrÙU6NH0J(50J( jUj÷ØUj|ØU jUN!Á5ÁVÁgÁzÁ{Á`ÂaÂÊÃBÄ[Ä{ħÄÈÄÙÄìÄíÄPÆQÆÅÊÆÊ\Ë]ˡˢËQÌ÷ÍÏÏýýýýûûûûùýýýýýýûûûûûûûûû÷÷÷ûd'iÅjÅkÅlżŽÅÕÅÖÅ×ÅÚÅÛūǮÇåÉʸʹʢˣ˻˼ËÑËÔËÖËòËõËGÌHÌQÌYÌZÌwÌxÌ…ÌþÌÿÌ@ÍAÍYÍZÍ[ÍcÍd͛͜ʹ͵Ͷ͹ͺÍ÷ÍøÍÎÎ&Î+Î-βηÎóÎôÎ>Ï?ÏWÏXÏYÏaÏbÏ'ГєÑäÑåÑÌÔÍÔúúúòúúððíåáåßÛßðíßåáåßíúÓúúúËúúåáåßÛßðíúÃúúÀ»À»ÀCJNHCJjÙÛUj^ÛUjãÚU5655j5UNH6jhÚU jUJÏxÏyÏ&Ð'ÐCÐcÐyÐzмÐËÐÑbѲÑõÑÒ6Ò7ÒOÒaÒbÒƒÒ“ÒÝÒôÒ)ÓfÓsÓ‘Ó™Óýýýýûûûûûûûûûûûûûûûûûûûûûûûûû™Ó»ÓÔ ÔÔÔVÔcÔyÔ¥Ô©ÔºÔÍÔ&Õ?Õ_Õ‹Õ¬Õ½ÕÐÕÑÕc×d×.Ø/ØåØÆÙDÚÚýýýýýýýýýýýýûùùùùùù÷÷÷÷÷õõõõd'ÍÔÎÔëÔìÔ&Õ4Õ?ÕJÕ_ÕlÕ‹Õ›Õ«Õ¬Õ¸Õ½ÕÆÕÐÕÀ×Á×õ×ö×ØØØØØ/Ø0ØDØEØUØ[Ø]سعØÑØÒØåØæØüØýØÙÙÙ2Ù3ÙWÙaÙgÙqÙ¯Ù°ÙÆÙÍÙÎÙàÙáÙêÙÚÚDÚKÚLÚ_Ú`ÚjÚÚ‘Ú§Ú¨ÚºÚÁÚÃÚ[Û\ÛcÛjÛkÛÛ€Ûù÷ùôôôðôðôôðíèàèèØÔØÒÎÒÌíØÔØÒÎÒíÌÌíÒØÔØÒíÒØÔØÒØÔØÒÎÒíÒØÔØ65655j5UjTÜU jUNH0J(50J( jUPÚcÛ²Û°ÜOÞ^ß„àÎá$ãgã€ã ãsä”ä¥ä¸ä¹äææÈæÉæPèQèéé,é;é<éýýýýýýýýûùùùùùù÷÷ñ÷÷ý÷÷÷ïïï Æ_¾$'d€Û‹Û²Û³ÛÊÛËÛÞÛæÛè۰ܱÜÍÜÎÜæÜîÜñÜOÝPÝ Ý¡ÝÈÝÉÝáÝâÝãÝëÝìÝ(Þ)ÞAÞBÞCÞKÞLÞOÞPÞiÞjÞzÞ¿ÞÀÞAßBß^ß_ßußv߃߫߬ßàààà8à9à:àAàBàlàmà„à…à›àœà¨à—á˜áÎáÏáçáèá÷áãã$ã%ã>ãýõñõýíýõñõýíýêêåÝåååÕååõñõýêêõñõýêêåÍååêõñõýêõñõýêÆÄ jUjÅÝUjJÝUjÏÜU jUNH565j5U5M>ã?ãgãuã€ã‹ã ã­ãÃãÉãÑãÚãáãçãöãÿãä ää%äsäƒä“ä”ä ä¥ä®ä¸äpåqåÕåÜåßåèåúåûåæææææ{æ|æææ¨æ©æªæ±æ²æÉæÑæÒæëæìæüæ6ç7ç~ç„çŒç•çç¤ç³ç¼çÃçÊçØçáçîçôçùçè©èªèë ëùöööòìòìòìòìòìòìòöòööòéççâÚââéâÒââÐÈÄÈÐéççççççççéù5j5U5j½ÞUjBÞU jU6NH 0J(560J(50J( jUM<éeé‚é›éÃéÓéê&ê]êsê}êŒê½êðêùêýê ëëYërë’ë¦ëÇëØëëëìëÑíÒí;ïýýýýýýýýýýýýýýýýýûùùùùùù÷÷÷÷' ë7ë8ëYëgërë}ë’ëŸë¦ë¶ëÆëÇëÓëØëáëëë íímítí®í¯íÇíÈíÉíÎíÏíî îîî=î_îcîvî›ïœï¯ï°ïÈïÉïÊïÑïÒïéïñïòï ð ððˆð‰ð¬ð¼ðÁðÑðñññ5ñ6ñFñKñSñTñnñoññ£ñªñ®ñµñ&ò'òDòEògòlòýöóóóïóïóóïííèàèèííÞÞÛèÓèèÞËÇËÞÛÞÞÞËÇËÞÞËÇËÞííËÇËÞ5j5Uj³ßUNH5j8ßU jU60J(50J( jUN;ï<ïèïéïñ&òlòúò5óaó‚ó“ó”óô¢ôcõuõ;ö<ö}ößöQ÷·÷øù÷÷õõõðîììì÷÷ççå÷÷àÒÇàà a ÆhЄÐ^„Ða & Ft ÆhЄÐ^„Ða & Fr & F_'d$a$d Æ_¾$lòtòuò’ò“ò­ò´òµòÛòÝòÞòâòæòíòúòûòóó5óCóaónóó‚óŽó ô(ô£ô¦ôÅõÆõÝõÞõßõåõæõ·ü¸üÈüÉüÓüÔüæüçü ýýý"ý2ý?ýhýiýý‚ýƒý…ý†ý«ý¬ýÄýÅýÆýÈýÉýãýäýðý^þ_þýõñõýíýëçëëàÞàÛÛ×ÛýýÒÊÒÒàÞààÞàÇÛÛ×¾×¶¾×¾×¾×®¾×¾×ÛÇj"áUj§àUj0J(5UNHj.àU jU0J(50J( jU6NH6565j5U5Dø/øuø©øÕø{ù·ùçùlúgûhûpüqü·üý2ýäýõýöýgþüþ«X23ƒôôôôïôôïïêêêêèæææääßßßßää & FO'a & Fa & Fr a ÆhЄÐ^„Ð_þgþþüþ ÿ@ÿAÿYÿZÿ[ÿ]ÿ^ÿŸÿ ÿ¹ÿºÿ»ÿ½ÿ¾ÿ89RSTVW‡ˆ¡¢£§¨«ê78QRSUVX˜+,-/0Žª«¾¿ÛÜ+bcot}ýýøðøøøèøøøàøøøØøøýÕøÍøøýÕøÅøø¾¼¾¾¼¾¹¹µ¹¹0J(50J( jUj äUjãUNHjãUj•âUjâUjáU jU5GƒÀct¤¥Pœ³íþ j¸Ï! 2 K L ¤    úúøøöôôôôøøöôôôôøøöôôôôøøøøø' & FM}£ %&./GHIMNPQijœª³Àìíùþåæjk…†¸ÆÏÜ ! - 2 ; J   » ¼   È É 5 6 N O P X Y /0HIJPQŽ©ªÐÞçô>?KPYh)*ûøøóëóóäâäßßûßßûøäâäßßûßßûøøøøó×óóóÏóóäâäßßûßßûøój}åUjåU0J( jUj‡äU jUNH0J(5R  õöŽÐç?Pij‘Ýô&=NOlƒ²ÃÐÑ£Žýýýýûùùùùýýûùùùùùýôýûùùùùýýýa & F'%&OP[\‘’§¨Ýëô!&1=E§M./EFlzƒ±²¾ÃÌÏÑ&'}~£ÿ³·fk$'-.€™š› ¡¹º9./~€“”»ÉÒßí÷òòïïèæèããßãããÝèæèèæèããßããßÝÙÝÙÝïÝÝÝïòÑòòïÝÙÝèæèããßjsæU5NH50J(50J( jUNH jUjøåURޱ²e#@A9~»Òíþ  Q‘¨ÂÓâã\ ] Ý ô !ýýýûûûöööýôòòòòýýôòòòòýýýôòò'a & Faíùþ FGQRij‘Ÿ¨µÂÎÓÜá] ^ u v … † ª « Ý ë ô !!!!²"³"Ö"×"##(#)#;#<#R#S#t#‚#‹#˜#«#·#¼#Å#7$8$ô$õ$7%8%O%P%Q%V%W%Ò%Ó%Ù%&'&o&p&‡&ˆ&¶&Ä&Í&Ú&ç&è&ñ&É'Ê'ýýùöïíïýýùýýùïíïïíïýýçýööïíïïíïýýùýýööâÚââöØÓïíïýýùýöOJQJ5jîæU jU 0J(5\ jUNH0J(50J(S!0!1!è!W"#t#‹#«#¼#Ó#Ô#&&'&M&o&¶&Í&è&0'1'q'Ï'&()f)‡)§)ýûöööôýýýýûûûûòòôýýýûûûûûôýýa & F'Ê'æ(ç())<)=)f)t)‡)’)§)´)º)»)Ë)Ú)Û)ç)ì)õ)ý*þ*+++++#+$+D+E+r+€+“+ž+³+À+Æ+Ç+×+æ+ç+ó+ø+,¼,½,Ý,Þ,ö,÷,--%-&-[-i-|-‡-œ-©-¯-°-À-Ï-Ð-Ü-á-ê-O.P.h.i.j.r.s.x.y.‘.’.“.›.ýöôöñññíñíññèàèèöôöñññíñíññöôööôöýñññíñíññèØèèèÐèj]èUjâçUjgçU jU0J(50J( jUNHR§)»)Û)ì)ÿ)*#+r+“+³+Ç+ç+ø+ , ,»,¼,[-|-œ-°-Ð-á-ô-õ-ª.E/f/†/š/ýýýýûûùýýýýýýûûûùýýýýýýûûùýýý'›.œ.ª.«.É.Ê.à.á.ÿ./E/S/f/q/†/“/™/š/ª/¹/º/Æ/Ë/Ô/-0.0·2¸2Ì2Í2ß2å2ç2ñ2÷2%3&3Z3[3z3‹34%4+4-4>4D4h4z4›4®4¶4¸4ã4ë4í4ÿ425E5M5O5Œ5”5–5§5³5½5Ã5Å536?6r6s6¿6Å6777!7€7Œ7 88)8úóñóóñóîîîêîêîîçßÛßÙÕÙÓççÙÙÕÙÓÙÙÕÙÓÙÙÕÙÓÙÕÙÕÙÓçÓÙÕÙÓÙÕ65655j5UNH0J(50J( jU jUSš/º/Ë/Þ/ß/0€0ß1à1}2~2¶2·2z34h4›4í425–57 8;9¡9Â9â9ö9:':ýýýûûûûûûûûûùùùùùùùùùù÷ýýýýýd')838<8>8^8_8i8r8¯8»8<9=9`9a9š9›9¡9¯9Â9Í9â9ï9õ9ö9:::":':0:ä;å;þ;ÿ;<<<'<(<Q<R<Ÿ<­<À<Ë<à<í<ó<ô<=== =%=.=¯>°>É>Ê>Ë>Ð>Ñ>#?0?1?E?F?J?Ã?Ä?ê?ë?$@2@E@R@_@`@ýùýöôôíëíöèèèäèäèèß×ßßíëíèèèäèäèèßÏßßýÇÃÇýíëíèèä5j5UjUéUjØèU jU0J(50J( jU6NH565M':::;:¿:À:°;±;&<Ÿ<À<à<ô<=%=8=9=Ê=Ë=j>k>#?Ã?$@E@`@q@}@~@Aýûûûûûûùýýýýýýûûûûûû÷ùýýýýûûd'`@l@q@y@}@A‘A·A¸AàAîA÷ABBBB#B+B0BÀCÁCÞCßCD+D>DKDuDvD‚D‡DDDiEjEFFF F:F;FwF…F˜F¥F²F³F¿FÄFÌFÑFÐGÑGéGêGH%H8HEHsHtHHŽHH‘H’H“H”H H¥H­H¿H¹IºIÓIÔIÕIÛIÜIJJGJHJhJiJ¦JýýùòðòýýùýýùòðòýýùýýùííòðòýýùýýùòðòýýèàèèùýýùèØèèíòðòjOêUjÒéU jUNH jU0J(50J(UAàA÷AB#B0B1BÀCD>DvD‡DDžDFwF˜F³FÄFÑFÒFÐGH8H”H¥H¿HÀHGJ¦Jýûûûûùùýûûûûùùýûûûûùùýûûûûùùý'¦J´JÇJÔJáJâJîJóJûJ!KmKnK‡KˆK‰KKKúLûLMMMMM"M#MEMFMtM‚M•M¢M¯M°M¼MÁMÉMÎMNN3N4NƒO„O£O¤OìOúO PP'P(P4P9PAPFPXRYRqRrRsRyRzRñRòR S S SSS8S9SZS[SœSªS½SÊS×SýýùýýùôìôôôäôôÝÛÝýýùýýùÙÖÝÛÝýýùýýùôÎôôôÆôôÝÛÝýýjAìUjÆëUNH6 jUjIëUjÌêU jU0J(50J(N¦JÇJâJóJ!K"K¤L!MtM•M°MÁMÎMÏMƒOìO P(P9PFPGP8SœS½SØSéSõSöSÉUGVýýýýûûûùýýýýûûùýýýýûûùýýýýûûû'×SØSäSéSñSõSGVHViVjVÃVÑVäVñVWWWWW4WX X!X*X§X®XôYõY ZZZZZ{Z|ZZŽZ¦Z§Z¨Z­Z®ZÕZÖZõZöZ5[C[V[c[p[q[}[‚[Š[[é\ê\ý\þ\ ].]A]N]h]i]u]z]‚]ˆ],^-^E^F^G^L^M^_ _!_ûøøûñïñøøûøøûëëëæÞææÛæÓææñïñøøûøøûñïñøøûøøûæËæææj²íUj7íUNHj¼ìU jU6] jU0J(0J(5OGVÃVäVWW4W5WÔXDY±YÔZÕZ5[V[q[‚[[[é\ ]A]i]z]ˆ]‰],_f_‡_¢_³_ýûûûûùùùùùùýûûûûùùýûûûûùùýûûû'!_"_#_(_)_,_-_C_D_f_t_‡_”_¡_¢_®_³_»_Á_"`#`;`<`=`B`C`e`f`~``€`…`†`·`¸`Ñ`Ò`Ó`×`Ø`=a>asataŒaaŽa“a”a™aša²a³a´a¹aºa5b6bKbLbmb{bŽb›b£b¬b­b¹b¾bÆbcZc[c÷òòëéëææâææâòÚòòòÒòòòÊòòÇò¿òòò·òòëéëææââææâòj–ðUjðUNHjžïUj#ïUj¨îU0J(50J( jU jUj-îUH³_Á_Â_5bmbŽb­b¾bccŒccÝcÞcdodÇd2e}e f[f5gêg÷g¹hYi–iÚijýûûùýýýýûûûûû÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷e'[csctc„c…cˆc‰cÞcácddodtdÁdÂdÇdËdeeee(e)e*e/e0e2e6e}ee f fUfVf[f_fggg g!g&g'g5g9g£gégêgíg÷gûg¹h½hYi]i–i›iÚiÞijj}j‚j j¥jÄjÉjéjîjkk4k9kZk_k~kƒk£k¨k&l+l~llälèl-m÷ôïïíííêíèïàïïíííêíïØïïíèíííííííííííííííííêíjòUjŒñU6NH5 jUCJjñUUj}j jÄjéjk4kZk~k£k&l¥l¦lälOmym¤mÏmn™noQoroo oîoïoæpdqýýýýýýýýýýýûûýýýýýýýù÷÷÷÷ûûù'e-m.mFmGmHmLmMmOmTmym~m¤m©mÏmÔmnn™nžnñnònoo/o0oQo_oroo…oŽoo›o o¨oío"p#p;p„÷òòïìïïïìïêâÞâêÚêÚêØòÐòòØêÚêÚêïØØØïòÈòòïêÚêÚêïØØïjT÷Uj×öU6565j5U5NHNH jUj\öUO>„ˆ„‰„¡„¢„£„­„®„b…c…v…w…Ÿ…­…¶…Ã… † †††5†6†7†<†=†>†?†K†V†_†цÒ† ˆˆ‰‰‰‰6‰7‰8‰?‰@‰¼‰Á‰¬Š°Š ‹k‹l‹„‹…‹†‹‹‹Œ‹Ò‹Ó‹Ú‹ŒÁŒÂŒÖŒ׌(5O[`iúòúúëéëææãúÛúú׿æãÕãúÍúúÕÕËÄ˺ÄËÄ˶˱ëéëææ×ææOJQJ5NHj@ù5U j5U5jÅøU60J(5jJøUNH0J( jUjÏ÷U jUFb…Ÿ…¶…?†V†m†n† ‡!‡ñ‡ò‡Ÿ‰ ‰ ‹ ‹Ú‹Û‹ŒŒ4Œ_ŒlŒmŒ‰Œ´ŒÁŒ(Oýûûûûùùùùùùùùùùùùù÷÷÷÷÷÷÷õûû'O`no­ŽáŽûŽHYgh¨‘Ö‘ð‘’’#’$’“s“§“Á“Ü“í“ú“û“¿•ü•–ýýûûùýýýýûûûùýýýýûûûùýýýýûûùý'iéêŽŽŽ Ž Ž­Ž®ŽÂŽÃŽáŽïŽûŽHTYbÄÅO\‘‘‘¦‘§‘Ö‘ä‘ð‘ý‘’’’’‡’ˆ’s“t“†“‡“§“µ“Á“ΓÜ“è“í“ö“º”»”A•B•Z•[•\•a•b••‘•™•𕲕³•´•¼•½•¿•À•Ô•Õ•ü• ––#–1–=–B–K–O–W–úòúúëéëææâææßÝëéëææâææßëéëææâææßúÕúúßúÍúúëéëææâæææj±úUj6úU6NH0J(50J( jUj»ùU jUQ–1–B–O–_–`–¢—ð— ˜%˜6˜C˜S˜T˜_›¤›¾›Ù›ê›ö›÷›*ªëüžžÆŸ1 ýýýýûûùýýýýýûûùýýýýûûùýýýýûûù'W–——K—L—e—f—g—n—o—¢—£—½—¾—ð—þ— ˜˜%˜1˜6˜?˜C˜K˜¶˜·˜Û˜ܘõ˜ö˜÷˜þ˜ÿ˜3™4™dšešmšnšËšÌš_›`›w›x›¤›²›¾›Ë›Ù›å›ê›ó›*+IJžª·êë÷üžžÆŸÇŸäŸåŸ1 ? ^ k y … Š “ — Ÿ g¡©¡ýøðøøéçéääàäääýøØøøýýýýéçéääàääéçéääàääÒéçéääàäääÐ5 0J(5\j©ûU0J(50J( jUj,ûU jUNHR1 ^ y Š — § ¨ ¢¢V£p£”£¥£¹£º£®¥¯¥Ö¥—¦{§µ§ï§ð§d©e©ª ª«F«`«ýýýýýûûùýýýýûûûûôôôôûûûûûûùý & F?'©¡Ú¡ñ¡w¢x¢¡¢¢¢£¢½¢¾¢Ò¢Ó¢í¢î¢££££V£d£p£}£”£ £¥£®£Ú¤Û¤:¥;¥×¥à¥˜¦¢¦î¦ï¦|§‡§¶§Á§©©©© ©$©%©ܪݪõªöª÷ªÿª«««««F«T«`«m«s««è«é«¬¬¬¬¬­­)­*­@­N­\­i­q­}­ó­ýúýóñóóñóóñóîîêîîúúýýúýýåÝåååÕååóñóîîêîåÍååóñóîîêîjýUjŸüUj&üU jU0J(50J( jUNH5Q`«s«„«…«M¬N¬­@­\­q­—­˜­ ®®:®æ®¤¯#³µµ¶µĵúµ(¶g¶v¶½¶×¶ýýûûûûùýýýûûûûôôôìûûêêêêêùý$ & FLa$ & FL'ó­ô­;®?®Ä®Å®Ü®Ý®Þ®â®ã®ç®ë®¥¯®¯¶°·°n±o±™±š±³±´±µ±½±¾±;²<²#³.³Ò³Ó³ë³ì³í³ò³ó³³´дÕ´µ¶µv¶w¶޶¶½¶˶×¶ä¶ò¶þ¶· ·q·r·‹·Œ···‘·¸¸¸ ¸P¸^¸j¸w¸…¸‘¸–¸Ÿ¸ý¸þ¸¹ýûöîööûûýýöæööýûöÞööûûÙÒÐÒÍÍÉÍÍöÁööÒÐÒÍÍÉÍÍöjÿU0J(50J( jUOJQJj‰þUj þUj“ýU jU5NHK×¶ò¶···¸P¸j¸…¸–¸¢¸£¸κ »'»j»{»|»8¼9¼ú¼û¼;¿7¿R¿c¿d¿&ÀmÀýýýûûùýýýýûûùýýýûûûûûûùýýýûûù'¹¹¹¹¹;¹<¹U¹V¹W¹Z¹[¹’¹“¹Á¹¹Ú¹Û¹ܹã¹ä¹ º º$º%º&º.º/º‰ºŠºº‘ºͺκϺçºèº »»'»4»K»L»d»e»f»g»h»j»v»—» »X¼f¼l¼m¼…¼†¼‡¼м‹¼¾¾(¾÷òòòêòòçòßòòò×òòççÒËÉËÆÆÂ¹Â±¹Â¹ÂƯ¯ò§òòòjîU6jsUj0J(5U0J(50J( jUOJQJjöUj{UNHjþÿU jUjÿU?(¾)¾*¾1¾2¾•¾–¾¤¾¥¾¾¾¿¾À¾Ⱦɾ;ξç¾è¾¿+¿7¿D¿R¿^¿´¿µ¿οÏ¿пØ¿Ù¿ê¿ë¿&À'À@ÀAÀmÀ{À‡À”À«À¬ÀÄÀÅÀÆÀÇÀÈÀÊÀÖÀ÷ÀÁ¥Á³Á¹ÁºÁÒÁÓÁÔÁ×ÁØÁíÂîÂiÄjąĆİľÄÊÄ×ÄîÄ÷òòïòçòòàÞàÛÛ×ÛòÏòòïàÞàÛÛׯ׾Æ×Æ×Û¼¼ò´òòïàÞàÛÛ×jYU6jÞUj0J(5UjaU0J(50J( jUjäUNH jUjiUGmÀ‡ÀÊÀÛÀÜÀ…Á†Á*Â+¼ÃiİÄÊÄ ÅÅÅéÅêŃÇÉÇãÇ&È7È8ÈnÉÊOÊiʬʽÊýýýûûûûûûûùýýýûûûûùýýýûûûùýýý'îÄïÄÅÅ Å Å Å ÅÅ:ÅCŘśÅÇÅÐÅ ÆÆÆÆ6Æ7Æ8Æ;Æ<ÆÃÆÄÆVÇ_Ç~ÇǃDŽǡǢÇÉÇ×ÇãÇðÇÈÈ È!È"È#È$È&È2ÈUÈ^ÈlÈzÈ€ÈșȚțȞȟÈ^ÉlÉÊ Ê#Ê$ÊOÊ]ÊiÊvÊʎʦÊ÷óë÷ó÷óèæäææß×ßßÔæÔÍËÍèèó÷óÃ÷ó÷óèææß»ßßæÍËÍèèó÷ójEUjÊU jUNHjOU jU560J(jÔU0J(5j0J(5UF¦Ê§Ê¨Ê©ÊªÊ¬Ê¸ÊÛÊäÊòÊËËËË Ë!Ë$Ë%Ë>Ë?ˉ˗ˀÌÌ Ì¡ÌàÌîÌúÌÍÍ'Í-Í.Í>ÍBÍGÍOÍPÍ\ÍaÍjÍÚÍÛÍºÎÆÎÊÎËÎãÎäÎåÎêÎëÎ ÏÏ&Ï'Ï(Ï.Ï/ÏºÏ»Ï Ð Ð#Ð$Ð%Ð-Ð.ÐvÐ}Ð÷îêîêçååàØààÕåÎÌÎçççêçêçêççÕåàÄààà¼ààÕà´àà²5j¬Uj1Uj¶U jUNHj;U jU60J(0J(5j0J(5UjÀUF½Ê¾Ê™Ë€ÌàÌúÌÍ.ÍPÍaÍtÍuÍnÎ1Ð3ÐuÐvÐýÑ%ÓÃÓgÕ&Ö±ÖJØÙÙ¾Ú˜Û¾ÜÀÝýýýûùùùùùùýýýýýý÷÷÷÷÷÷÷÷÷÷÷÷d'}Ð~МÐбÐÇÐÐÐÑÑÑÑ/Ñ0Ñ3Ñ4ÑpÑqѫѴÑÝÑàÑýÑÒÒ Ò!Ò2ÒHÒQÒÔÒÝÒÓ ÓÓÓ%Ó&ÓAÓBÓYÓeÓfÓyÓ‚ÓÓ™ÓžÓŸÓÃÓÄÓßÓàÓ÷ÓÔÔÔ#ÔEÔLÔ`ÔaÔyÔzÔ{Ô|Ô}ԄԅԕԜԡԧÔ[Õ\ÕgÕnÕoÕ„Õ…ÕÕõÕöÕÖ÷ó÷ñïêâêêßïïñ÷ó÷ñïïïß÷ó÷ñÛñïïß÷ó÷ñÛñïïêÓêêßïïßñ÷ó÷ñêj¤ U56NHj) U jU655j5URÖÖÖ Ö#Ö$Ö&Ö'Ö<Ö=ÖNÖTÖUÖÖ‡ÖÖžÖ±Ö²ÖÇÖÈÖÙÖßÖàÖõÖýÖ×&×:×;×S×T×U×V×W×o×v×{××JØKØfØgØ~؄؅ؒؓؼØÂØôØõØ ÙÙÙÙÙÙÙàÙáÙöÙ÷ÙÚŒÚÚ¥Ú¦Ú¶Ú·ÚºÚ»Ú¾ÚÅÚÆÚØÚÙÚâÚdÛ÷òòêæêäàäÞÛêæêäàäÞÞòÓòòÞÞêæêäàäÛÞòËòòäêæêäòÃòòäêæêäj Uj Ujš UNH65655j5U jUj UMdÛeÛ˜ÛŸÛ Û·Û¸ÛÆÛÜÜkÜl܅܆܇܎ÜܩܪܾÜÅÜÆÜÞÜßÜîܫݬÝÀÝÊÝËÝàÝáÝìÝ[Þ\ÞtÞuÞvÞyÞzÞŸÞ Þ­Þ®ÞÆÞÇÞÞÞâÞãÞ"ß#ß-ß.ßFßGßHßKßLß[ß`ßaßkßlß߀߉ßöß÷ßààààà9à:àGàHà^àýûóïóûýêâêêýûóïóûýûóïóûêÚêêýóïóûÖûýêÎêêÌûóïóûêÄêêýóïj~ U6j U56jˆ Uj U jU5j5U5NHMÀÝ­ÞaßGàõàzáâ¶âiãæä·åç`ç„èìèúé ëmì î’ïRð òbò1ôÃõ÷úàúúúûýýýýýýýýýýýýýýýýýýýýýýýýýýûùù'd^à_àtàxàyàÁàÂàÚàÛàÜàßàààïàôàõàýàþàáá'áQáRájákáláoápázá{á—á˜á±áµá¶áÐáÑáéáêáëáîáïáþáââ â â%â&â4âqârâŠâ‹âŒâââ¶â·âÒâÓâëâóâôâãã0ã1ã2ã5ã6ã=ã>ãEãMãgã÷õñõìäììâõ÷Þ÷õìÖìì÷Þ÷õñõìÎììâõ÷Þ÷õìÆìì÷Þ÷õñõì¾ìì»âNHjåUjjUjïUjtU56jù U jU565j5UJgãhãiãqãrããã¤ã²ã³ãèãéãäääääÁäÂäÚäÛäÜäãäääæäçäåå#å(å)åMåNåfågåhåkålå{å€åµå¶å·å¿åÀåÙåÚåêå#æ$æwæxæÉæÊæç çççç,ç-ç8ç`çeçfçzç{ç†ç©çªçÃçÄçÅçÍçÎçbècè{èýûóïóûìçßççç×ççóïóûÓûçËççýýûóïóûììììûóïóûûóïóûçÃçççjÑUjVU56jÛUj`U jUNH5j5U56M{è|è}è€èè„èŒèè¦è§è·èìèíè é é(é,é-é0é2éaébéé¥éÔéÕéíéîéïé÷éøéúéêêêê%ê©êªêÃêÄêÅêÍêÎêÿêë ëëë+ë,ëAëJëLë_ëhë{ë|ëºë»ëÔëÕëÖëÞëßë`ìaìmììíííŽí§í÷òòðèäèðèäèðàÚàð×ÕòÍòòðèäèðòÅòòÂðèäèðàðÕÂòºòòÂðÂòjÁUNHjDUjÉU6NH 56NH565j5U5 jUjNUI§í¨í©í°í±íèíéíîîîî î î î(î*î4î<îûîüîïïïïï%ï&ïoïpïˆï‰ïŠïïï’ï©ïRðiðtðvð€ð‹ð ñ ñññ*ñ+ñ,ñ4ñ5ñÈñÉñbòvòyò|òŒòòƒó†ó¶ó·óÞóáó1ôHôXôbôkômô õ¡õºõ»õ¼õ÷òòòêòòèäèâèòÚòòòÒòòèèäèâèòÊòòÇèäèââÇâèäèäèò¿òj«UNHj.Uj³Uj6U6565j»U jUj>UK¼õ¿õÀõÃõØõâõìõõõøõö!ö9öBö_÷`÷y÷z÷{÷~÷÷€÷ž÷¯÷²÷lømø‰øŠø‹ø™øšøØøéøLùMù ú ú$ú%ú&ú.ú/ú\ú]úú€úŸú úàúîúúúûû'û-û.û>ûBûGûOûPû\ûaûjûÖû×ûôûõûüü]üküwü‚ü—ü¤üªü«üúøôøôøòòúêúúøôøúâúßúòÜúÔúúÜÍËÍÈÈÈÄÈÄÈÄÈÈÜÍËÍÈÈÈÄ0J(50J( jUjCUNH0Jj¥Uj(U6565 jUMû.ûPûaûtûuûôû]üwü—ü«üÌüÝüðüñüyýØýÙý¼þ ÿ&ÿFÿZÿ{ÿŒÿŸÿ ÿ†ãäýýýýûûùýýýýýýûûûûûùýýýýýýûûûû'«ü»ü¿üÃüËüÌüØüÝüæüQýRý þ1þ`þaþzþ{þ|þ†þ‡þŽþþ§þ¨þ©þ¯þ°þ¼þ½þÛþÜþ ÿÿ&ÿ1ÿFÿSÿYÿZÿjÿnÿrÿzÿ{ÿ‡ÿŒÿ•ÿžÿÿÿ*;jk„…†‘˜™±²³¹ºÆÇÞß $/DQWXhýùýùýýöôïçïïïßïïØÖØýýýùýùýùýýùöôïÎïïïÆïïØÖØýýýùýj5Uj¸U jUj=UjÀU jU6NH0J(50J(NäÆ $DXz‹žŸP­/VjŒ°±$}â<Prƒ–—ýûùùùùùùýýýûùùùùùùýýýûùùùùùùý'hlqyz†‹”ÇÏéê  …†Ÿ ¡©ª­®ÉÊ/:IUVcijz~ƒ‹Œ˜¦WXpqrst‘’«¬­°±UVopqyz}~œâûøûøøöñéñññáññÚØÚøøÔøûøûøûøøÑñÉñññÁñññ¹ññÚØÚj Uj#Uj¨UNH5\ jUj+Uj°U jU50J(0J(5Iâð'<IOP`diqr~ƒŒ^ _ ¥ ©   ¦ ¯ °  à Ë ò ó      5 6 K L ^ h i v € ø ù  & , -  ‚ › œ  ¥ ¦ À Æ   v Ì Í æ ç è ð ñ 3=ýýýùýùýùýýöôôòêæêòáÙááêæêòÕòôöòÕòáÍááôôòÆò¼ÆòÆòêæêòÕj5U j5Uj˜U56jU jU5j5U56NH0J(50J(J— c e § 5  êÁ4nŽ¢ÄÕèéøžq‹¦·ÅÆýýýýûûûûûûù÷÷÷÷÷÷ýýýýýù÷÷÷÷ý'd=>op²½ìö  *+7€êñò Z[ÁÂæç)*4BnyŽ›¡¢²¶»ÃÄÐÕÞv{ùú 9:q‹˜¦²·ÀÄ‹ŒëìÖ9:ýúøøúðìðýúýðìðýúåãåúàààÜàÜàÜààøø×Ï××åãåààÜààÜúúËÃj5U\5\j’U jU0J(50J( jU5j5U6NH5MÆÖª†¡²áKL´ÿ/{ŒÁ?@£¤= > … Ÿ º ýýýûùùùùùóýýîûùùùùùóýýîîûùùa & F Æ_¾$':STdemnstŽžŸ¦§ª«¾¿ÊËãä5}~†“¡­²»áçè567?@Iª«¹ÛHI©ª«°±´µüñüéüéüéüÞüéüéü×Õ××Õ×ÒÎËÒÎÒÒÒÎÈοη¿Î¿ÎËÎ˲ª²² j0J(5Uj„ U jUj Uj0J(5U0JpNH0J(50J( jUjŠ5U\j5U\j 5U\5\<µÍÎÿ /<YZstuxy{‡Œ•ÁÇÈÚ234<=>Ž z{“”•Ÿ ¢ÑÒ  2 3 4 9 : > ? Y Z … “ ž Ÿ ¬ úðìéìéìàìØàìàìéééìÕìàìÍàìàìÊžŵũµÅµÅʤœ¤¤ðúðìéìéjv"U jUjû!UmHsHjUmHsH NHmHsHmHsHNHj~!U0Jpj!Uj0J(5U0J(0J(5j0J(5U 0J(5=¬ º Æ Ë Ô Ù ß à ò ô 6!L!R!S!l!m!n!q!r!&"'"("=">"{"‰"«"¸"Î"Ú"ß"è"é"(#/#¦#¬#Ì#Ø#ó#ú#$$k$l$–$$%%ú%û%p&q&‡&ˆ&Æ&Ô&ö&''%'*'3'8'q'v'Æ'Ë'( (D(J(´(¿([*\*u*ûøøøûõðêðáðÕáðáðÐÉÇÉøøûøøûÅÅÅÅÅÂÅÂÂÉÇÉøøûøøûÅÅÅÅÅÉÇNH5 jUmHsHjó"UmHsHjUmHsH 6mHsHmHsH0Jp0J(0J(5Lº Ë Ù ó ô '"{"«"Î"ß"ï"ð"(#¦#Ì#ó#$–$0%1%p&Æ&ö&'*'9':'q'ýýý÷õóýýýýõõññññññììóýýýýõõa & Fa Æ_¾$'q'Æ'(D(´(")#)[*¢*¼*×*è*÷*ø*Á+M,±,Ë,æ,÷,--ñ.J/d////ž/ýýýýýøøöôôôôòòòöôôôôòòöôôôôò'a & Fau*v*¢*°*¼*É*×*ã*è*ñ*ö*M,N,o,p,±,¿,Ë,Ø,æ,ò,÷,-¼-½-ý- ...../.0.7.8.˜.™.ñ.ò.//J/X/d/q//‹//™/™1š1Ö2×2î2ï2ð2÷2ø2$3y3z3Î3Ï3å3æ344"4#4F4G4‰4—4£4°4¾4Ê4Ï4Ø4£5¤5©6ª6Â6ùööòööòùðùööòööíëæÞææíùðùööòööíæÖææÔÐÔÐÔùðùùðùööòööíæ5NH5jë#Ujp#U jU6NH0J(50J( jURž/=12$3å3‰4£4¾4Ï4Ü4Ý4Ï6)7C7^7o7|7}7˜9:.:I:Z:g:h:7=„=ž=%>;>ýýýýûùùùùýýûùùùùýýûùùùùýýûùùù'Â6Ã6Ä6Ë6Ì6Ï6Ð6é6ê6)777C7P7^7j7o7x78898r9s9‹9Œ99”9•9˜9™9¶9·9:":.:;:I:U:Z:c:¬:­:Æ:Ç:È:Ð:Ñ:È<É<==*=+=,=3=4=7=8=J=K=„=’=ž=«=þ=ÿ=>>>">#>%>1>…>†>÷òòëéëææâææßò×òòëéëææâææòÏòòßòÇòòëéëææâ¾â¶¾â¾âæòjR&Uj0J(5Uj×%UjZ%Ujß$UNH0J(50J( jU jUjd$UH;><>Ï>Ð>7?8?ß?à?~@é@BAWAëAìAÓBÔBàCáC DODFpGDH5IJ_J®JöKýýýýýýýýûùùùýýýýýý÷÷÷éééééé & FK ÆhЄÐ^„Ðo'†>>ž>Ÿ>£>¤>^?_?w?x?y?ƒ?„?’?“?¬?­?®?¶?·?~@@Œ@@•@–@­@®@é@÷@AA5A6A7A?A@ABAOAWAcA»A¼AÕAÖA×AßAàAQBRBjBkBlBpBqBbCcC|C}C~CˆC‰C DDOD[D°D±D E÷òòòêòòòâòòÛÙÛÛÙÛÖòÎòòÖÊÖòÂòòòºòòò²òò°°­NH5jµ)Uj:)Uj½(U0J(5j@(U0J( jUjÃ'UjH'U jUjÏ&UD EEEE8E9ERESEcEdEnEoEqErE‹EŒEœEE§E¨EªE«EÄEÅEÕEÖEàEáEæEçEFFFFFFF%FqGwG(H)HEHIH½HÀH5I>IJJ`JdJ¯JºJbKeK‘K•K–KžKõK÷KLL L!L+L˜MûMANBN[N\N]N^N_NaN™NýùýôìôôôäôôôÜôôôÔôôÒÒÏÒýÒÒÒÒýýÒÒÒÒÌÒôÄôôÒj&,U0JpNH5j©+Uj,+Uj¯*Uj2*U jU6NH6MöKLaNcPQ–QRSR‹R SES}S T’UV€VúVdWÅXúZ<\ý]æ_¨a>b?b—böèèèèèèèèèèöæèèèèèèöææææääo & FK ÆhЄÐ^„Ð & FK„Ð^„ЙNœNÉN\O]O”O°O±OýOCPDP]P^P_P`PaPdPnP QQ_Q`Q—Q¡QêQëQR'RTR_RŒR–RSSFSQS~S„S T&TÑTÒTÛTÜTôTõTUU U U“U”U V VV‚VÕVÖVûVüVfWgW¼W½WdXeXÆXÇXÊXÔXNYtYÅYÆYßYàYáYéYêY|Z}Z–Zú÷õñõìäììõõ÷õ÷õõõõõõõ÷ìÜììõõõ÷õõ÷÷õÙõìÑìììj›-U0Jpj -Uj£,U jU5NH5NH B*phÿQ–Z—Z˜Z™ZšZ¥Z¬ZûZüZÿZ [¯[°[Á[Â[Û[Ü[Ý[ç[è[<\B\ö\÷\0]4]÷]ø]ý]^__æ_î_™`š`Í`Ô`!a'a(a)a7a8aPaQaaabahaiaa“a§aÙabb!b"b2b3b;bbvb‹b—b-d1dKdXdgdhd÷òòðîëèòàòòîèðèîèîèðððòØòòðîòÐòòîËÆ½Æ½Æ¶ jUB*OJQJphÿOJQJ B*phÿj/Uj/Uj•.UNH0Jp56 jUj.UH—b¶bÞbcXc…c¬cýc[dgd¤d½dàdád­f®fgg¬gðgJhjh–h·hÈhÛhÜhíiîiýýýýýýýýýûùù÷÷÷÷÷÷ûùùùùùù÷÷÷'hdydzd¤d²d½dÉd4f5fMfNfOfYfZfugvg«g¬g­gÃgÄgðgþgh#h$h=h>h?hGhHhIhJhUhjhwh–h¦hªh®h·hÃhÈhÑh%i&i>i?i@iHiIi]i^iÛiëi5j6jNjOjPjXjYjñj÷j¶l¼l²m³mËmýöóóîæîîãÞöýöóÚÑÚÉÑÚÑÚóóóÇóóî¿îîã½îµîî½½îj}1U6j1U5j…0Uj0J(5U0J(5OJQJNHj 0U jU0J( jUDîiUmVmnn!oÐo2qèq“r¿sžtlumuÂuv=vQvrvƒv–v—vºxDyEyÁzÂzD{ýýýýûûûûûûûûñïííííííýýýýýýý' d„„^„`„dËmÌmÍmÓmÔmnnnnn3n4nAn·n¸nÑnÒnÓnÝnÞn!o(o)o>o?oKo]odo‘o’o¬o­oÅoÆoÇoÍoÎoÐo×oØoêoëoôopp\p]pupvpwp}p~p¨p©püpýp q!q2q9q:qMqNqXqÃqÄqÜqÝqÞqäqåqèqðqñqrr÷òòðîæâæîòÚòòîæâæîð×òÏòòîæâæîðòÇòò×××îæâæîò¿òòîæâæjæ3Ujk3Ujð2UNHjs2U5j5U56 jUjø1UKrr“r›rœr¯r°r¼rss¿sÀsØsÙsísös÷szt{t“t”t•t›tœtžt¥t¦tºt»tÔtÝtätòtót!u"u:u;u‰ŠŠ‹‚‹´‹µ‹Í‹΋ϋًڋµ¸ŽŽ¤ŽµŽÕŽÖŽïŽðŽñŽûŽüŽÿŽCQ^_swx‘ûøóëóóøóãóóøóÛóóøøøóÓóóøÑøÑóÉóóÂÀ½½û´ûj0J(5U0J( jUj¢;U6j';Ujª:Uj/:Uj²9U jUNH0J(5DLˆMˆC‰D‰ŸŠŠ‹"ŽxŽyŽþŽÿŽCž¾Òó=‘>‘e’f’å’æ’2“S“k“|“ýýýýýýýýýýûùùùùùùýýýýýýý÷ùùù'‘’“›œž©¾ËÑÒâæêòóÿ cd|}~†‡‘‘É‘.’/’H’I’J’T’U’e’‹’œ’¼’½’Ö’×’Ø’â’ã’æ’ç’““2“@“S“`“j“k“w“Ú“Û“ê•î•Ñ–Ò–ê–ë–ì–ó–ô–˜÷îêîêççêçêçêççêâÚââØêâÐââêØâÈââÁ¿Áççêç¼Øâ´ââj>UNH jUj”=Uj=U6jœ<U jU0J(0J(5j0J(5Uj<UF|“}“4•͕̕‹–Œ–¬—­—˜˜8˜9˜t˜u˜•˜Șç˜õ˜ø˜™I™h™|™}™¯™°™À™ü™ šýýýýýýýýýýûûûûûûûûûûûûûûûûûûû šš šjš‰šµšËšÌš5›ƒ›œ›ß›ð›ñ›34íîÝžŸ/ŸaŸrŸsŸË ¡3¡J¡[¡ýýûùùù÷÷ûùùù÷÷÷÷÷÷ûùùù÷÷õùùù'˜š š!š5š6šjšxš‰š–š´šµšÁš ››/›0›5›6›P›Q›ƒ›‘›œ›©›À›Á›Ù›Ú›Û›Ü›Ý›ß›ë›Pž^ždžež}ž~žž‚žƒžΞϞݞޞôžõžŸ$Ÿ/Ÿ<ŸaŸmŸÏŸПË Ì à á ¡ ¡3¡@¡I¡J¡V¡T¢U¢ˆ¢Œ¢Û£Ü£õ£ö£÷£ýöôöññíñëèöôöññíßí×ßíßíñëÒÊÒÒèöôöññíñèöôöññíñèÈÒÀÒj‚?U5j?U jUjŒ>Uj0J(5UNH60J(50J( jUCJL[¡\¡÷¡[¢\¢‡¢ƒ¤„¤¥¥œ¥½¥Ø¥ó¥¦¦¦O§{§–§¨§¹§º§ñ§2¨^¨x¨°¨è¨ýýýýýûýýýýù÷÷÷÷ýýù÷÷÷ýýòòòòò & FT'a÷£ÿ£¤_¤`¤x¤y¤z¤€¤¤œ¥¥°¥±¥½¥Ë¥Ø¥å¥ò¥ó¥ÿ¥¦ ¦‰¦Ϧ §3§{§‰§–§£§§§¨§´§ñ§ò§¨ ¨2¨3¨B¨C¨^¨_¨l¨m¨x¨y¨‹¨Œ¨°¨±¨èĨè¨é¨û¨ü¨ ©!©3©4©©©¥©¦©º©»©תÛª²«Ù«g¬Ÿ¬¡¬¢¬½¬¾¬ЬÞ¬ë¬ø¬ü¬ý¬ ­k­l­È­úúòúúëéëææâææààææâæëéëëéëëéëëéëëéëëéëëéëÝëéëàààëéëææâæÝNH60J(50J( jUjÿ?U jUWè¨ ©¥©Ü©Ý©›ªx«Û«¡¬Ьë¬ý¬­­Q®Ÿ®º®Õ®æ®ç®k°l°¸°Űî°±1±2±úúúôòòððîìììòòîìììòòòòêêêêê'a Æ_¾$ & FTÈ­É­® ®!®"®#®(®)®.®/®G®H®I®N®O®Q®R®o®p®Ÿ®­®º®Ç®Ô®Õ®á®¸°q±r±s±ޱ±Á±ϱܱé±ö±÷±²²²βϲ'³(³H³I³‰³—³ã³ä³V´c´p´q´}´‚´‹´Rµ×µƒ¶„¶â¶ã¶d·e·}·~··…·†·ˆ·‰·«·¬·ì·ú·F¸G¸ýøðøøøèøøáßáÜÜØÜÓáßáÜÜØÜÜýáßáÜýÜØÜÜÑýýøÉøøáßáÜýjpAU6OJQJ0J(50J( jUjõ@Ujz@U jUNHO2±c±q±r±Á±ܱ÷±²²²'³‰³V´q´‚´´´ˆ·ì·¹¸Ô¸å¸ò¸ó¸Í»/¼J¼e¼v¼ýýûù÷÷÷÷ûûù÷÷÷÷ûûù÷÷÷÷ûûù÷÷÷'G¸¹¸ƸÓ¸Ô¸à¸å¸î¸U¹V¹µ¹:ºS»T»©»ª»»ûĻʻ˻ͻλë»ì»/¼=¼J¼W¼d¼e¼q¼v¼¼á½â½ú½û½ü½¾¾¾#¾X¾Y¾x¾y¾ƾÔ¾á¾î¾û¾ü¾¿ ¿¿x¿y¿šÀ›ÀÁÁ!Á"Á4Á5ÁNÁOÁ•Á£Á°Á½ÁËÁÌÁØÁÝÁæÁÅťŦÅÃÅÄÅÆÆýùýýöôöïçïïàÞàýýùýýïÖïïôàÞàýýùýýööàÞààÞàýýùýýöàÞàýjfBU jUjëAU jU6NH0J(50J(Tv¼ƒ¼„¼X¾ƾá¾ü¾ ¿¿¿ÁÁ•Á°ÁÌÁÝÁþÁÿÁiÅ¥ÅÆÔÆïÆÇ ÇÇ~ÈèȵÉÐÉýûûùýýýýûûûùýýýýûûûùýýýýûûùýý'ÆaÆbÆÔÆáÆîÆïÆûÆÇ ÇvÈwÈ~ÈȡȢÈèÈöÈBÉCɵÉÂÉÏÉÐÉÜÉáÉêÉùÊúÊËËMËNËQË_ËlËyˆˇ˓ËÍÍ7Í8Í9Í?Í@ÍBÍCÍWÍX͎ͩ͜ͶÍÃÍÄÍÐÍÏÏ*Ï+Ï,Ï2Ï3Ï5Ï6ÏRÏSϖϤϱϾÏËÏÌÏØÏ[Ñ\ÑtÑuÑvÑ|ÑýúöúúýïíïúýúöúúïíïêúúöúåÝååïíïúúöúåÕååïíïúúöúåÍåj×CUj\CUjáBU jUNH jU0J(50J(NHQÐÉáÉíÉîÉùÊQËlˇ˘˙ËBÍŽÍ©ÍÄÍÕÍÖÍ5ϖϱÏÌÏÝÏÞÏÑÎÑéÑÒÒÒÐÓÔýýûûùýýýûûùýýýûûùýýýûûùýýýûûù'|Ñ}ÑріїÑÎÑÜÑéÑöÑÒÒқӜӬӭÓÅÓÆÓÇÓÍÓÎÓÐÓÑÓíÓîÓÔ+Ô8ÔEÔRÔSÔ_Ô$Õ%ÕšÕ›Õ»Õ¼ÕùÕÖÖ!Ö.Ö/Ö;ÖœÖÖ¶Ö·Ö¸Ö¾Ö¿ÖØØ-Ø.Ø/Ø4Ø5Ø8Ø9ØRØS؅ؓؠحØÍØÎØçØèØéØñØòØóØôØÙ1Úúóñóîîêîçúßúúóñóîîêîçóñóîîêîú×úúúÏúúóñóîîúÇúúêîjÇEUjJEUjÍDUjRDUNH0J(50J( jU jUNÔ8ÔSÔdÔeÔšÕùÕÖ/Ö@ÖAÖÓ×7Ø8؅ؠØôØÙÙ1Ú}Ú˜ÚìÚýÚþÚ;ܧÜÂÜÝÜîÜýýýûûùýýýûûûûùýýýûûùýýýûûùýýý'1Ú2ÚLÚMÚ}Ú‹Ú˜Ú¥ÚÅÚÆÚßÚàÚáÚéÚêÚëÚìÚøÚ¿ÛÀÛ ÜÜ;Ü<ÜRÜSÜaÜbÜyÜzܧܵÜÂÜÏÜÜÜÝÜéÜJÝKÝÿÝÞÞÞÞ#Þ$ÞÙÞÚÞßß2ß3ß[ßißv߃ߕߖߢßËàÌàæàçàá'á4áAáyázá†áæáçáÿáââââgâhâ‘â’â¨â©âù÷ùôôïçïïãôààù÷ùù÷ùôôãôàïØïïàù÷ùôôãôù÷ùôôãôïÐïïàù÷ùj>GUjÁFUNH0J(5jDFU jU0J( jURîÜïÜTÝ'Þß[ßvߖߧߨßËàá4ázá‹áŒá‘âÙâôâãIãiãzããŽã¿äpåGæeæýýûûù÷÷÷ýýù÷÷÷ýýù÷÷÷÷÷÷ýýýõ÷'a©âÙâçâôâÿâã!ãHãIãYãhãiãuãzãƒãNäOäšä›ä³ä´äµä»ä¼äLåMåeåfågålåmåpåqå‹ååªå«åÇåÈåäåæåææGæUæeærææŽæ¦æ§æ¨æªæ«æ¶æ·æÏæÐæÑæÓæÔæÚæÛæóæôæõæ÷æøæççç¦è§èýýýùýùýýöñéñññáññÚØÚØÚÚØÚØÚýýùÏùÇÏùÏùÏù¿ÏùÏùÏù·ÏùÏùýöj¥IUj*IUj¯HUj0J(5U jUj4HUj¹GU jUNH0J(50J(HeæçcçdçFèâèãèìèéOéYéZésé ëWëìì%î&îtïuï”ð¸ð0òdóEôCö±ùýýûûûûûùùùû÷ûõõõõððððîìììììea & Fa'§èìè'é(é@éAéBéFéGéYéwëŒëêìëìCíDíPîeîïï2ï3ï4ï9ï:ï6ð7ð}ð~ð¸ð»ðÒðÙðßðæðññ0ñ1ñ2ñ7ñ8ñ‚ñƒñ›ñœññ¢ñ£ñÀñÁñÙñÚñÛñàñáñòñùñ0ò3òJòSòYòbò•ò–ò®ò¯ò°òµò¶òûòûæòûòûäááäÜÔÜÜááÒääÜÊÜÜÜÂÜÜܺÜÜäÒääܲÜÜj‡LUj LUj‘KUjKU5j›JU jUNH6j JOJQJUjOJQJUOJQJF¶òîòïòóóóóó"ó#ó@óAóYóZó[ó`óaódógóˆóŽó¾ó¿ó×óØóÙóÞóßóüóýóôôôôôEôIôLôMô|ô•ô¤ô§ôëôìôõõõ õ õööö ö8ö9ö:ö@öAöCöFöpöqöçöìö\÷h÷²÷³÷Ë÷Ì÷Í÷Ñ÷ýøðøøøèøøæäøÜøøøÔøøæÐæääøÈøøýøÀøøæÐæääø¸øjäOUjiOUjîNU56jsNUjøMU65j}MUjMU jUNHHÑ÷Ò÷ø&ø?ø@øƒø„øœøøžø¨ø©ø¿øÊøîøõøAù°ùåùèù¦ú©úÀúÉúÏúÙú û û%û&û'û.û/û@ûIûpûqû€û‚ûšû£û©û³ûêûëûüüü ü üüüýý-ý.ý/ý7ý8ý;ý=ýŠþŽþ”þ•þWÿXÿpÿqÿrÿ|ÿ}ÿµÿ»ÿÉÿÏÿ úøõúíúúøøëëëøøúãúúøõëøøúÛúúëúÓúúëëÏëúÇúúøøøjKRU56jÐQUjUQUjÚPU5j_PUNH6 jUN±ù²ùåù¦ú€ûü;ýúý9þŠþº›–ÓpÍûX˧í å ­ Á4=>ýûýýýýýûùýýýýýýýýýýýýýýýûùùùùe ’˜©ªº½› –›ÓÖptÍÐûÿPQX[Ëϧ«¯°ÅÎÒÓÜÝñóCD\]^bc‡ˆ ¡¢§¨°¹ÁÅÙÚ01OWu€…†÷ø     3 > ž Ÿ ï ð   F G } ì í ð ýúøøøøøøøúøøøôøôøôøôøôøïçïïïßïïýýúúýýúï×ïïýúúýúøøj¼SUjASUjÆRU jU565NH6Uð Ý Þ å ð ? @ ­ ± JKcdefgstqrŠ‹Œ“”¤¥ÁÅßàøùúõökl„…†‹Œ«¬ÄÅÆËÌ-./9:>EF[\ns|‡‰ýûýûöîööýöæööýûöÞööýöÖöööÎöööÆööú¶ºÃ²Ã²Ã0J(60J(j0J(U0J(jžVUj#VUj¨UUj-UUj²TUj7TU jU5NHD‰¤©3>‡ˆ ¡¢¬­°¸¹ÏÐâåèþÿ45DÜäåýþ&+4?AQY§¬®¹øù  $%&01yµ¶º»ÂÚ#$9:FþÿûõûõûìûäìûìûáØÔØáÐáûÊûÊûáØÔØáûáØÔØáÐáÐáÐáûõûõûõûÊûìûÂìûìûõûÊûÊûáûÊûØÔØá¿ØNHj–WU 0J(5NH0J(60J(j0J(U0J(jWUj0J(5U 0J(560J(5K>°ÜÂ#$qRò, M s „ …  !%"Y"z"´"Å"Æ"#4$Š$«$Ï$à$ýýýýýýýýýýûùùù÷÷÷ûùùù÷÷÷ûùù÷'d23A qr‘«¯°º¼/0AB[\]abÙÚóôõúûRSlm‚ŒŽòó  , : M Z r s  á â j!k!Ý!Þ!ö!÷!ø!ü!ý!%"&"6"7"Y"g"z"‡"³"´"À"ûòïìòûòïèâèïìÝÕÝÝÝÍÝÝìòûòïèïÆÄÆïïÀïììݸÝÝÆÄÆïïÀïj YU0J(5 jUjŽXUjXU jU 0J(6NH0J(6NH0J(j0J(U0J(HÀ"y#z#ì#í#$$$ $ $4$5$S$T$Š$˜$«$¸$Î$Ï$Û$—%˜%í%î%©&ª&d'g'Å'Æ'Þ'ß'à'ä'å'k(p(**§*¨*¸*¹*Ú*è*û*+3+4+@+Ü+Ý+õ+ö+÷+û+ü+,,v,w,~,,ž,Ÿ,Ü,ê,ý, --$-é-ê-ý-þ-.&.9.F.p.q.ýøðøøéçéääàäýýýÞøÖøøÞýéçéääàäøÎøøýýéçéääàäéçéääàj|ZUjZU60J(50J( jUj†YU jUNHQà$á$ú&û&Š(‹(Ä(ï()+)C)D)r)É)á)â)E*§*Ú*û*4+E+F+},~,Ü,ý,-)-ýýýýýýûûûûûûûûûûûù÷÷÷ýýýù÷÷÷')-*-è-é-.9.q.‚.–.—.µ.7/£/Ä/ä/ø/<0M0`0a0U1ž1¿1ç1ø1 2 2m2ˆ2ýýýûùùùùýýýûùùùùùùýýûùùùùýý÷a'q.}.‚.‹.µ.7/8/V/W/£/±/Ä/Ï/ä/ñ/÷/ø/0;0<0H0M0V00111I1J1K1Q1R1T1U1V1o1p1ž1¬1¿1Ì1æ1ç1ó1ø122f2g2n2r2‰22Â2Ò2"3_3a3o3œ3¦3Ò3Þ3ý3¬4­4Æ4Ç4ô45 55%5&52575@5E5£5¤5?6ñ6ò67777"7#7/707ýýûôòôýýýîýîýýéáééûôòôýýîýýîÞûûûûûûûûôòôýýîýýîÞûôòôôòôôNHj÷ZU jU0J(5 jU50J(Xˆ2Á2`3›3Ñ3ý3¬4ô4 5&575F5G5?6ð6ñ6n7ˆ7¶7·7·8Œ:Ò:é:;;!;";Ž;ýýýýýûù÷÷÷÷ûòûûù÷÷ûûûù÷÷÷÷ûûa & F'a07B7C7n7|7ˆ7“7µ7C8D8]8^8_8a8b8“8”8­8®8¯8³8´8I9J9c9d9e9l9m9ò9ó9 : ::::h:i:‚:ƒ:„:ˆ:‰:Œ::¢:£:Ò:à:é:ö:;;;; ;G<H<_<`<a<e<f<==°=6>ó>ô>…?ýöóóîéáéééÙéééÑéééÉéééÁééöýöóó½óó½éµéé²°²5NHjã]U0J(5jf]Ujé\Ujl\Ujï[Ujr[U jU B*phÿ0J( jUEŽ;¹<„=q@·@Î@é@ú@AAjACaCxC“C¤C³CÄCÅCýDµEÖEòEFFFOGPG™Gúúøöôôôôøøúöôôôôôøøöôôôôøøøø' & F=…?T@U@q@r@‡@ˆ@·@Å@Î@Û@é@õ@ú@AAcAdABB,B-B.B3B4BÜBÝBôBõBöB÷BøBCCCC*C+CaCoCxC…C“CŸC¤C­C²C³C»CDD1D2D3D8D9DýDþDEE'E(E@EAEQEREjEkE{E|E“E”EµEÃEÖEãEòEþEF FýùýòðòííéííéæáÙáááÑááæòðòííéííéíáÉááòðòòðòòðòòðòííéííjR_UjÙ^Uj\^U jUNH0J(50J( jU5NH5O FFAFMF®FºF8G9G›G¥GÏGØGLHVHÆHÑHGIRIêIëI@JNJ€JŠJÓJÝJùJK KKgKpKŸKÏKÐKèKéKùKúKþKÿKLL!LCLML`LjLÅLÆL1M:M_MMŽM¦M§M·M¸M¼M½MàMðMúM NNqN{N´NµNÍNÎNÏNÕNÖNèNöN)OûùùöòòòòòöðùùùùùðéðßðéðéðÛðùùöùðéðÑðéðéðùùùÌÄÌÌðjÅ`U jUjJ`5U5NHjÏ_5U j5U556NH60J(5M™GÍGJH’H“HÄHEIóIôI@JLÑMéNSPTPÃPÄPÓPQ%Q&Q5QgQwQ|Q‹QÆQÖQ×Qýýýøøýýööôôôôöööòòòòòòòòòòòòa & Fa)O5O:OFO®O¹OÙOäOýOþOPP7P8P9P?P@PRPSPÄPCRDRXRYR…R“R¦R³RÇRÓR8S9S¾S¿S×SØSÙSßSàS%T(ThTlTÍTÐT4U7U•U˜UáUâUúUûUüUVV&V'VW‚WšW›WœW£W¤WæYçYÿYZZZ Z­\ýýýýúõíõõëèáßáÜÜØÜúõÐõõëëëëëõÈõõúõÀõõõ¸õõj,cUj±bUj6bUj»aU0J(50J( jUCJ5j@aU jUNH6H×QåQ4RCR…R¦RÇRØRÙR=S>S%ThTÍT4U•UµU¶U/V¾VX>X”X#YyZ³Zýýýûùùù÷÷÷÷õõõõõ÷÷ðââ×ðââ „hdð¤^„h & F= ÆhЄÐ^„Ð & F=e'³Z [ê[@]¿]À]U_V_v_È_É_é_>`?`Ç`$aqaˆa¨aÔaòabbbØbôïáôôÚØØÖØØÖØØÖÔÒÒÒÒÒÒØØ'dð¤ & F= ÆhЄÐ^„Ð & F= „hdð¤^„h­\®\Æ\Ç\È\Ï\Ð\é]ê]^^^ ^ ^K_L_v_È_é_>`—`˜`Ç`$a%a?a@aqaaˆa“a¨aµaÔaäañaòaþab bb[b\btbubvb{b|b-c.cFcGcHcMcNcTcUccŽc¤c¥cÕcãcøcdd%d*d3d¢d£d eueve²eúòúúúêúúçââçâÛÙÛÖÖÖÒÖÒÖÖÒúÊúúúÂúúçÛÙÛÖÖÒÖÖçÀ¼À5NH5jeUjdU0J(50J( jUOJQJNHj"dUj§cU jUJØb]c^ccÕcøcd*dAdBd®d e²e&f'f¼f½fßf g!grg•g°gÁgÐgÑg¯hñhòhýýýûùùùùýýýýýýýýý÷ýûùùùùýýýý'²eEfFf_f`fafifjfßf g!g"g8g9grg€g•g¢g°g¼gÁgÊgqhrhŠh‹hŒhh‘h¨h©hEiFi^i_i`ieifiÝiáiëiïiùiüi[j`j®j³jýjkkk)k*k+k2k3k5k8kHkIkakbkckjkkkmkpk~kk—kúòúúíæäæááÝááúÕúúÒúÊúúÈÈÈÈÈÈúÀúúÈú¸úúÈújgUjgU5j‹fUNHjfU0J(50J( jUOJQJj“eU jUFòhÝiëiùi[j®jýj5kmk¡k×kbl©lìlBmYmZmnnÊoËo p'pEpkp|p‹pŒp,qýûûûûûûûûûù÷÷÷÷ýýýýýõ÷÷÷÷÷ýý'e—k˜k™kžkŸk¡k¤k´kµkÍkÎkÏkÔkÕk×kØk÷kùkllblpl©l¶lÊlËlãlälålêlëlìlølBmKm¬m­mÅmÆmÇmÌmÍmn n1o2oKoLoMoToUooÉoËoÌoâoão pp'p4pEpTpjpkpwp|p…pŠpìpíp6r7rt÷òòðòèòòáßáßáÜÜòÔòòÐÜÜòÈòòÄò¼òòÄáßáÜÜÐÜÐÜÜй¹NHjèiU5\jmiU0J(5jòhU0J( jUjwhU5 jUjügUI,qNrOr)s*sÊtËt,u¶uFvGv^v¹viwjwÁwXxYxy7yVy|yyŽySz´{µ{ýýýýýýýûûýýííýýëýéççççýýýý' & FA Æh¤„¤^„¤ett t!t"t't(tStTtktltmtrtst,u/u¶u¹u!v"v:v;v‚ǂȂá‚â‚ã‚ë‚ì‚ö‚û‚—ƒ˜ƒ¯ƒ°ƒÀƒÁƒɃʃÔƒÚƒ+„1„‚„–„úøúðúúøøøøøøøúèúúøøøååúÝúúøøøúÕúúøúÍúúøøÈ B*phÿj´nUj7nUj¼mUNHjCmUjÈlU5 jUO–„ÄĄ݄ބ߄ç„è„é„ê„ï„3…8…„…Š…Õ…Û…&†+†˜†™†²†³†´†¼†½†džÚ† ‡ ‡&‡'‡(‡0‡1‡4‡9‡Ї‹‡‘‡–‡ç‡è‡î‡ó‡'ˆ+ˆaˆfˆ™ˆžˆ׈܈c‰i‰cŠdЇЙŠS‹]‹zŒ…Œ ,±²ÉÊËÒÓJŽKŽbŽcŽdŽlŽmŽyŽúòúúíëëëëëúãúúíúÛúúëØëØëëëëëëØëëëëúÐúúúÈúújqUj¤pUNHj'pUjªoU5 B*phÿj-oU jUO'ˆaˆ™ˆ׈c‰ŠŠkŠlŠS‹zŒ (ŽØ‘i“ç”蔾•ù• —‘˜’˜C™‘™ß™ýýýýýýûûöèèèèèèèââèèèØØèè  Æ_¾$„h^„h„h^„h & FC ÆhЄÐ^„Ð & F²eyާŽìŽíŽ˜™ýþ !-f%‘&‘=‘>‘?‘F‘G‘Û‘Ü‘ó‘ô‘õ‘ý‘þ‘ ’8’ “ “a“b““Ž“§“¨“©“±“²“¾“”è”ý”c•d•}•~••‡•ˆ•¾•Еø•–N–O–––—–®–¯–°–·–¸–—— — —1—2—K—ýúúõíõõýõåõõõÝõõýúúõÕõõýÐõÈõõýýúõÀõõúýõjýsUj€sU B*phÿjsUjŠrUjrUj–qU jUNH5HK—L—M—U—V—b—Ä—’˜§˜ܘݘö˜÷˜ø˜™™C™S™‘™¡™ß™ð™š,šTšdšš£šÌšÝš[›h› œ œžœ°œÚœÛœQfŽÕêžžpžqž|ž}ž•ž–ž—žžžŸžãžäžaŸbŸzŸ{Ÿ|Ÿ‚ŸƒŸ—Ÿ¹Ÿ½ŸП q Ý ¡v¡÷òòðëòãòòððððððððàðàðàðààòØòòàòÐòòëË÷ÃËÃ5B*OJQJ\phÿ5OJQJ\OJQJjëuUjpuUNHjótU B*phÿ5 jUjvtUHß™šTššÌš[›‚œƒœ56¹º†Ÿ‡Ÿ½ŸПÝ ñ ò ¡v¡Š¡‹¡¡¡ñ¡í¢£ññññññïêïêäêïïââââââââââââ Æ_¾$ & F² & FC ÆhЄÐ^„Ðv¡¡¡7¢Ø¢í¢£v££Ž££¦£§£Þ£ì£ø£¤¤"¤8¤9¤B¤E¤V¥W¥n¥o¥p¥w¥x¥¤¥¥¥Á¥Â¥ï¥ý¥ ¦¦L¦X¦]¦f¦p¦:§;§º§»§Ó§Ô§Õ§ß§à§õ§ ¨ ¨8¨9¨T¨U¨h¨i¨¨‚¨’¨“¨«¨¬¨¼¨½¨Õ¨Ö¨û¨ ©©"©ûóçóûóûàÞàÛÛ×Û×Û×ÒÊÒÒàÞàÛÛ×ÛÛ×ÇÒ¿ÒÒ½¹½àÞààÞààÞààÞàÛÛ5NH5jßvUNHjfvU jU0J(50J( jU5B*OJQJ\phÿ5OJQJ\OJQJI£££H£v££Ž£Þ£ø£¤9¤F¤G¤¤¥ï¥ ¦L¦]¦p¦q¦8¨û¨©1©W©h©v©w©¯«ýýýýýûù÷÷÷÷ûûù÷÷÷÷ûûù÷÷÷÷÷ûû'"©1©@©V©W©c©h©q©u©¤©¶©0ª1ªTª[ªê˪x«„«‰«Š«¢«£«¤«««¬«É­Ê­â­ã­ä­ê­ë­í­ð­ÿ­® ®®Ú®Þ®í®õ®í¯°/°0°I°J°K°S°T°V°Y°i°r°%±@±I±q±…±±‘±š±DZαÞ±ç±ÿ±²²² ² ²²²&²ûøûøøûöóöööîæîîîÞîîÜööÜö×îÏîîÜöÜËÜöööööÇöÁÜö 5OJQJ6NH56jPxU B*phÿ5jÕwUjZwU jUNH60J(0J(5L¯«0­1­í­Ú®í¯V° ²±²²²"³#³3´Æ´µçµA¶œ¶¶>·?·°·±·$¸%¸x¸—¸ýûûùùùùùùûûôïïéïïûôûôãôûûá Æ_¾$„Å^„Å & F´ & F³ef&²y³z³™³¤³´´+´,´3´:´Y´`´Æ´дí´õ´µ&µŒµµ¦µ§µ¨µ°µ±µϵеçµñµ¶¶A¶J¶h¶p¶ ··(·/·4·<·y··Ž·•·£·®·¸¸¸ ¸¸"¸S¸u¸ú¸@¹X¹b¹§¹Á¹Ĺֹ#ºFºyº‹ºŸº§º©ºɺëºõº»»)»I»p»ýûûýùûùûôïçïïýùûùûûûûûûûûãûûôôôôÞÖÊÖÞÖÊÖÊÖÞÖÊÖÊÖÞÖ5B*OJQJ\phÿ5OJQJ\OJQJ6NHjÍxU jU B*phÿ56NHP—¸™¸»¸ظú¸¹@¹n¹p¹q¹ĹÖ¹#º6º7ºFº©º¹ºººɺ)»9»:»I»’»¢»â»ü»E¼ýýýýýýýýûûýýýýýýýýýýýýýýýù÷÷'p»€»’»¢»£»¹»º»â»ð»ü» ¼E¼Q¼V¼_¼d¼нª½¯½´½¹½º½Ò½Ó½Ô½Û½ܽ޽߽ø½ù½ú½¾¾¾¾¾¾¾$¾%¾'¾(¾@¾A¾B¾G¾H¾§¾¨¾>¿?¿X¿Y¿Z¿\¿]¿a¿b¿x¿y¿z¿óëæßÝßÚÚÖÚÚÖÔÔÏÇÏÏÏ¿ÏÏÏ·ÏÏϯÏϬϤÏÏÏœÏjµ{Uj8{UNHj½zUjBzUjÅyUjJyU jU60J(50J( jUOJQJ5OJQJ\5B*OJQJ\phÿ=E¼V¼d¼e¼½kÀ¹ÀÓÀÁ Á,Á-Á«ÁÂ3ÂUÂfÂ}Â~µÂÃÂÃ/ĨĩÄåÅ+ÆEÆ`Æýýûûûùýýýýûûùýýýýûû÷÷÷÷òòùýýa & Fa'z¿’¿“¿°¿±¿í¿î¿ÀÀGÀHÀaÀbÀcÀgÀhÀkÀlÀ‰ÀŠÀ¹ÀÇÀÓÀàÀÁÁ Á)Á,Á‹ÁŒÁ«Á¬ÁÁÁÂÁÂÂ3Â@ÂUÂaÂfÂoÂ|µÂÂÂZÃ[Ã~ÃŒÃÁÃÍÃ.Ä5ħĩÄÑÅÒÅÝÅÞÅåÅæÅýÅþÅ+Æ9ÆEÆRÆ`ÆlÆqÆzÆÆ=Ç>ÇáÇâÇ÷ÇøÇ0È>ÈJÈWÈeÈqÈvÈÈ©ÈiÉù÷ùòïòçòòù÷ùääàääàïù÷ùääàääàÞïÞÞÞÞïïù÷ùääàääàïù÷ùääàääà50J(50J(j2|UNH jU jUX`ÆqÆ€ÆÆáÇ0ÈJÈeÈvȪȫÈóÉ<ÊVÊqʂʑʒÊÅÊËË8ËIËXËYËøËRÌlÌÎÌôÌýýûûùýýýýûûùýýýýûûùýýýýûûùýýý'iÉjÉóÉôÉ Ê Ê<ÊJÊVÊcÊqÊ}ʂʋÊÊ¡ÊÄÊÅÊÆÊÛÊÜÊËËË*Ë8ËDËIËRËWË»Ë¼ËøËùËÌÌRÌ`ÌlÌyÌŒÌÍÌÎÌÝÌóÌôÌÍÍÍ:Î;ÎSÎTÎUÎ]Î^Î`Îa΃΄ζÎÄÎÐÎÝÎìÎûÎ Ï ÏÏÏ%Ï)ÏbÏiÏnτϵÏÀÏÞÏæÏ9ÐPÐSÐfÐíÐþÐýöôöññíññíèöôöññíññíýöôöññííñíññãÛããöôöññíñíññíÙÙÙ××××56j¯|U jU B*phÿ0J(50J( jUNHUôÌÍÍÍ`ζÎÐÎìÎ ÏÏ*Ï+ÏÞÏ9ÐíЉъÑ1Ó2Ó?ÔXÔŸÔ¹ÔÿÔÕ5ÕTÕeÕsÕýýûûùýýýýýûûôôôûûûûòòòùýýýýý & FC'þÐÒÒ*Ò+Ò,Ò2Ò3ÒdÒeÒ‰ÒŠÒ¢Ò£Ò¤ÒªÒ«ÒßÒàÒ Ó Ó%Ó&Ó'Ó-Ó.ÓÔÔÔ Ô!Ô"Ô#Ô¹ÔºÔÓÔÔÔÿÔ ÕÕ&Õ5ÕDÕSÕTÕ`ÕeÕnÕrÕÀÕÇÕÔÕÕÕ‚ÖƒÖ›ÖœÖ֧֍֒ד׫׬׭׳״רØ/Ø0ØAØúòúúïúçúúïúßúúú×úúÐÎÐËËÇËÇËËÇÅïú½úúúµúúÐÎÐj‘UjU60J(50J( jUj›~Uj ~Uj¥}UNHj*}U jUGsÕtշ׸×Á×ÑרØÙØóØÙ.Ù?ÙMÙNÙ‹ÙŒÙTÜUÜñÞòÞ»à¼àÉâã-ãHãýýýýûûûù÷÷÷÷÷ýýñãýãýãýãù÷÷ & Fµ ÆÐh„h^„h Æ_¾$'AØBØ[Ø\ØmØn؇؈ؙؚذرØÕØÖØÙØçØóØÙÙÙ-Ù.Ù:Ù?ÙHÙLÙ§Ù¶ÙÚÚÚÚÚ&Ú'ÚdÚjÚÇÚÈÚóÚôÚ Û ÛÛÛÛ»ÛÀÛpÜܥܬÜåÜæÜþÜÿÜÝÝÝ*Þ+Þ‰ÞŠÞšÞ›Þ³Þ´ÞµÞ¿ÞÀÞ ßßBßI߂߃ߛßù÷ùù÷ùù÷ùôññíñíññíëæÞææÜôæÔææÜÐÜæÈææôôæÀææÐÜæj}UjU5\j‡€U6j €U jU50J(50J(NH jUL›ßœßߣߤßÂßÃßààxàyà”à•à­à®à¯à·à¸àààìà‡áˆá á¡á±á²áºá»áÉâÊâéâêâã"ã-ã:ãHãTãYãbãhãpãää7ä8ä9äAäBäÀäÁäÞäßäöä÷äåå&å'å@åAåTåUåhåiåvåwåå‘å¢å£å¾å¿åÒåÓåìåíåæ÷òòïïïòçòòãòÛòòÔÒÔÏÏËÏÏËÏòÃòòÔÒÔÔÒÔÔÒÔÔÒÔÔÒÔÔÒÔÔÒÔjiƒU0J(50J( jUjî‚U5\js‚UNH jUjøUMHãYãhãxãyãÀäæ4æ*ç;çñç}è~èêêKëLëmëîpïûðHó¹÷ù`ûaûŸûÎûýýýûûùýýýýûûûûûûûôôôôôôôîûì Æ_¾$ & FH'æ(æ4æAæTæ*ç6ç;çEç˜é™émë‚ëìì0ì1ìIìJìKìSìTìÎìÏìçìèìéìïìðìîîî.îjîkîƒî„î…îîŽî‘î’îðîñîNïOïhïiïoï‚ï"ð#ðûð ñHóSóOôPô¿õÀõöövöwöŠ÷‹÷¹÷È÷døeøÂøÃøøøûøù$ùïúðú%û+û<û>ûGûHûŸûýýùýýöôöïçïïïßïïöôï×ïïööööôöôôöööööôööÕôöÕÕö6jÚ„Uj_„UjäƒU jU5NH0J(50J(TÎû ü üqüŸüãüäü*ýQý£ýÂýüýþ3þ×þØþ¿ÿÀÿlˆŽð-tu¯Àýûûýýûûýýýù÷÷÷ûûûûòòûûýýûûýý & FK'Ÿû üiüjüqüãü*ýÂýÃýÐýÑýüý þþ+þ3þ>þbþcþ¯þ°þÈþÉþÊþÔþÕþ=ÿ>ÿVÿWÿXÿ\ÿ]ÿCD\]^hily12‰Šßàø‡ˆ’áâøùö÷%&ŽðtÒÓìíûøûûñïñììèìèìãÛãããÓãããËããÉøøøÉûÉøøãÁããøû¾ã¶jC‡UCJjƆU5jK†UjÐ…UjU…U jU0J(50J( jUNHOJQJHíîö÷¯Àˆ ‰ ˜ ™ Ò à ë ö   ‡ ‰ ® ¯ Ý é ) 3 6 7 B C [ \ ] a b “   · Å *Uccd|}~†‡Œ¥¦§¯°þÿ!"–±²Êúú÷ð÷éçéäääâÞØÞäâÕúÍúúËËËËúÃúúú»úúú³úúËúj1‰Uj¶ˆUj;ˆU6jÀ‡UNH 0J(5NH0J(550J( jU CJOJQJCJ jUCÀ   ˆ Ò ë  Ý ò ó ) Ô Õ %&ÔÕ./n×fþ(‰ýýýýûùùùù÷÷ò÷÷÷÷÷÷÷÷÷ðëëëëë & F¥f & FK'ÊËÌÔÕFG_`acdŠ‹£¤¥­®ij‚ƒ„†‡”•Z[hi¦§¿ÀÁÂÃ~—˜™¡¢ÃÑרðñòõöž¶·¸ÀÁ34LMNP÷òòòêòòòâòòòÚòò××ÕòÍòòòÅòòÃò»òòò³òòò«òj„Uj UjŽŒU6jŒUj˜‹U5NHj‹Uj¢ŠUj'ŠU jUj¬‰UC‰j§Å7M°±ñ3ÄÇ7 C Ù Î!n"€'Ý' (Ú(ý(‰)Ÿ)úúúúúúúúúøöññññññññññññññïí' & Fªf & F¥PQStÆÇàáâãäRrsÆ €™š›£¤ûüktùú     ¹ º Ò Ó Ô Ö × Ž!!®!¯!Ç!È!É!Ë!Ì!#"$"M"N"f"g"h"j"k"”"•"­"®"¯"·"¸"B#C#úøúðúúíøéøíúáúúííßú×úúúÏúúíúÇúúíú¿úúú·úúíjåUjjUjïUjtUjùŽU6j|ŽU5NHNHjÿU5 jUHC#ˆ#‰#ç#è#8&9&G&'a(b((‚(š(›(œ((ž(ý(þ())!)")7)8)E)F)\)])‰)—)Ÿ)ª)¿)Ì)***"*+*”*Ÿ*Æ+Ç+ß+à+á+é+ê+ü+ý+,,Í,Ù,¯-°-É-Ê-ø-.....;.R.S.k.l.m.n.o.p.q.}.‚.‹.«.´.Q/ýýýûýöîööçåççåççåçâââÞââûöÖööýûûçåçâââöÎööÞââÌ6jV’UjÛ‘U0J(50J( jUj`‘U jU5NHPŸ)¿)*"*V*W*”*,Í,¯-ø-...q.‚..‘.†/&0<0\0x0‰0—0˜01d1z1š1ýýýýûûùùù÷ýýýýýûû÷ýýýýýûû÷ýýa'Q/R/j/k/l/t/u/†/‡/¡/¢/´/µ/Ï/Ð/â/ã/ÿ/0&040<0G0\0i0w0x0„0‰0’0ë0ì011111115161d1r1z1…1š1§1´1µ1Á1Æ1Ï17282332333q33Š3•3ª3·3½3¾3Î3Þ3ß3ë3ð3ù34I4d4e455Z5[5úòúúëéëëéëëéëæææâææúÚúúëéëæææâææ×ëéëæææâæâææââÑâÑâÈj0J(5U 0J(5NHNHjL“U0J(50J( jUjÑ’U jUOš1µ1Æ1Õ1Ö13q3Š3ª3¾3ß3ð344:6;6À6Q7o7K8L8ß8ý89ª9«9e:¹: ;ýýýûûùýýýýýýûûûû÷ýýû÷ýýýûûûû'[5s5t5u5{5|53646:6f6w6—6˜6±6²6³6½6¾6À6Á6Þ6ß6÷6ø677Q7_7a7b7o7z7£7¤7½7Ã7Ä7Ý7Þ7î7ï7ñ7ò7L8M8j8k8ƒ8„8¡8¢8Ú8Û8ß8í8ï8ð8ý8 93949L9M9N9P9Q9W9X9ûóêûêûäûâÝÕÝÝÎÌÎÎÌÎÉÆÉÁºÁݲÝÝÎÌÎÎÌÎÆÉÆÉûêûªêûêûêj<•Uj¿”U B*NHphÿ B*phÿNH0J( jUjB”U jU6 0J(5NHj0J(5UjÇ“U0J(5CX9p9q9r9t9u9‰9Š999œ9ß9à9˜:¦:¬:­:;;g;h;±;·;À;Á; < <*<-<V<d<“< <º<»<Ô<Õ<ê<ó<&='=-=.=G=H=Š=‹=¼=å=#>N>“>”>??%?/?7?8?m?n?‡?ˆ?‰??Ž?§?ª?Ð?Ñ?ï?ð?@Ž@¦@ûóêûêûäûáÞÜÞÞÞÜÞÞÜááûäûäûáÞÕÓÕÞÎÎÞÜÜÞÉÁÉÉÜÕÓÕÉj2–U jUOJQJ jU5NH0J( 0J(5NHj0J(5Uj·•U0J(5J ; ;‹;Œ; ;ë;7<V<“<°<Å<Ú<ê<-=X=²=Q>R>Õ>Ö>ì>??Ð?@ADAý÷÷÷òòðîîèèèîæýý÷ýýýáááæýß & F¬'„`„' & F« Æ_¾$¦@§@¨@­@®@AAAADAEAcAdA¨A©AcBdB¡B¢B¿BÀBÙBÚBîBýBÿBCÛCÜCDD8D9DwD…DœD¨D³DÀDÏDÐDâDãDçDèDEE E EEE!E"E+E3E4E9E:EŒEE¥E¦E§E¬E­EµE¶EãEäEFFæFçFEGFGQGVGzG{G”G÷òòïïèæèïïïèæèäïïèæèáááÝÝ×ÝÝ×ÝÝ×ÝáïáòÏòòïèæèïïäòj*—U 0J(5NH0J(50J(5 jUNH jUj¯–UODAyA’B¿BêB¸C¹CÃCÓCDDwDœD³DÐDèDøD E"E9E:EãEF¤FQG¶GáGHýûùýûûûùùù÷õõõïïïïõõûýûûûýû'„`„'”G•G–GœGG¶G·GÐGÑGñGòG H H HHHHH/H0HDHSHUHVHªH«HÄHÅHÆHÌHÍHÏHÐHïHðH8I9IªI«I²I³IMJNJ J¡JÌKÍKÓKÔKìKíKîKòKóK÷KLL.L/LMLNLdLeLƒL„LëMìM`NcN÷òòëéëòáòòëéëßÜòÔòòëéëÜÜÜÜËÜòÃòòÀ»ÀëéëëéëÜ®B*CJOJQJhphCJNHCJj™U jèðmHnHujŸ˜UNH5j"˜U jU jUj¥—UDH@HšHÏHIFIfJgJžJ»J¼JKK÷KÿKLL%L.L´LŠM‹M6N_N`NiNqNzNýûöýööööööööûôôîôôýûûûûûèèè$If„]`„]$a$cNdNtNuN}N~N‹NŒN­N`OaOxOyO(P)PyP|P¤P¨PÉPÌPáPâPêPíPQ QEQNQ±Q²QóQôQ:R;RƒR„RQSRSiSjSkSoSpStSwS¡S¢SØSÛSŒT•T¹TÂTÅTÎTàTáT=U>U·U¸UÑUÒUÓUÙUÚUÝUëUVV‹VŒVñäñäñäñäÙÒÐÒÍËËËÍËËËÍÍÍÍÆ¾ÆÆËÍËËËËÍÍÆ¶ÆÆËÍÍjšUj—™U jU5NH jUB*OJQJhphB*CJOJQJhphB*CJNHOJQJhphHzNˆN‘N¡N¢N§N­N®N¯N°NùùùðççVðð$$If–”÷ÖˆâÿèE£0 $] ^ ïîöÖÿÿÿÿÿÿÖÿÿÿÿÿÿÖÿÿÿÿÿÿÖÿÿÿÿÿÿ4Ö aö $$Ifa$ $$Ifa$$If °N±N²N³N´NµN·N¹N¿NÀNÅNööööeX\\\\\ $$Ifa$$$If–”‚ÖˆâÿèE£0 $] ^ ïîöÖÿÿÿÿÿÿÖÿÿÿÿÿÿÖÿÿÿÿÿÿÖÿÿÿÿÿÿ4Ö aö $$Ifa$ ÅNÊNËNÎNÐNÖN×NÚNßNöeTöööööö$$If–”÷ÖˆâÿèE£0 $] ^ ïîöÖÿÿÿÿÿÿÖÿÿÿÿÿÿÖÿÿÿÿÿÿÖÿÿÿÿÿÿ4Ö aö $$Ifa$ßNàNâNåNëNìNñNôNõNøNûNOnTeeeeeenPeee $$Ifa$$$If–”÷ÖˆâÿèE£0 $] ^ ïîöÖÿÿÿÿÿÿÖÿÿÿÿÿÿÖÿÿÿÿÿÿÖÿÿÿÿÿÿ4Ö aö OOOO O O O O OOOöööeöööööö$$If–”÷ÖˆâÿèE£0 $] ^ ïîöÖÿÿÿÿÿÿÖÿÿÿÿÿÿÖÿÿÿÿÿÿÖÿÿÿÿÿÿ4Ö aö $$Ifa$ OOOOOOO$OnTeeeeee $$Ifa$$$If–”‚ÖˆâÿèE£0 $] ^ ïîöÖÿÿÿÿÿÿÖÿÿÿÿÿÿÖÿÿÿÿÿÿÖÿÿÿÿÿÿ4Ö aö$O%O(O*O/O0O3O6O7O9ObAbBbEbFb`babŽbœb¥b²bÀbÉbMcNc}d~d–d—d˜dšd›dždŸd½d¾döde ee(eûõûòéûáéûéûõûÚØÚòòòÕÐÈÐÅÐÕнÐÐÚØÚòòòÕеÐÐÚØÚòòjžUj–U0JjøœU jUNH jUj}œUj0J(5U0J( 0J(5NH0J(5G(e1e¸f¹fËfÌfgggg•g–g¯g°g±gµg¶g¹gÆgïgðgh h h h hhh(h)h*h,h-h2h3hLhMhNhPhQh~hh„h…h‘h›hœh´hµh¶h¸h¹h¿hÀhÇhÈhèhéh/i=iFiSiti‰iŠi“i¤i¥i·i¸i€jýöôöýñìäììýà×àÏ×à×à×àÇ×à×à×à¿×à×à¹àý×à±×à×à¹àöôöýýàýñýj~ U 0J(5NHj Uj†ŸUj ŸUj0J(5U0J(5jŽžU jUNH jU0J(F7e8e·f¸fg¹g…hÇh/iFiŠi·i¸i]kk´kìkýkþk¸m n!nSncndn±oõo pBpýýýûùùù÷ùùùùý÷ùùùùý÷ùùùùý÷ùù'€jj]k^kukvkk«k´kÁkÔkëkìkõkýkþk9m:mžmŸm¸m¹mØmÙm nn!n.n>nRnSn\ncndn»n¼n«o¬o±o²oÎoÏoõop pp;p°v°|°’°ž°Ȱɰ ± ±*±0±J±P±ýúýýýýúýýýúýúýúýúýúýýúýúýúýúýúýúýýýýýýúýýýýýýýúúýýNH5cï¬6­J­‚­Ê­í­3®R®Ú®ý®-¯E¯e¯”¯¾¯é¯°%°8°v°‘°’°)±*±J±^±_±š±›±ýýýýýýýýýýýýýýýýýýýýóýýýýýýñ g„„^„`„gP±_±m±ʱ˱ß±à±á±fÊgÊhʛʜʰʱʳÊãÕäÕåÕæÕëÕìÕòÕóÕõÕöÕ÷ÕøÕ*Ö+ÖOÖPÖQÖaÖbÖcÖdÖiÖjÖpÖqÖtÖuÖvÖwÖ©ÖªÖÎÖÏÖÐÖàÖáÖâÖåÖýøøðøøøêðêøçàçàØàçÕÎÕÄοÎÕçàçàØàçÕÎյοÎÕj}©CJU0JCJj¨CJU jCJUCJ0JmHnHu j0JU0J mHnHumHnHsHu jU55›±¡±ɱʱá±ü±²'²=²U²j²²²Ÿ²¸²ɲà²õ²³³6³O³d³}³œ³©³¸³ϳݳýûù÷ññññññññññññññññññññññññ9 Æå +ݳí³´´&´=´S´d´z´Œ´¢´¿´×´è´ú´µ%µ8µFµ\µoµ}µ•µ­µɵáµ¶¶&¶6¶ùùùùùùùùùùùùùùùùùùùùùùùùùùùùù9 Æå 6¶E¶Z¶s¶޶¬¶¾¶˶Ù¶ê¶···)·7·C·M·d·u·Ž·¤·¾·Ñ·å·ø· ¸¸.¸C¸X¸ùùùùùùùùùùùùùùùùùùùùùùùùùùùùù9 Æå X¸f¸v¸‚¸–¸§¸¸¸˸߸ð¸û¸¹¹0¹:¹H¹V¹e¹t¹‰¹š¹²¹Á¹Ó¹á¹ø¹ ºº*º8ºùùùùùùùùùùùùùùùùùùùùùùùùùùùùù9 Æå 8ºSº`ºrºº‘ºŸº­ºººÓºìºÿº»»1»C»V»l»~»“»¨»¶»É»ß»ï»¼¼ ¼9¼E¼ùùùùùùùùùùùùùùùùùùùùùùùùùùùùù9 Æå E¼X¼m¼~¼‘¼©¼¹¼Ƽ׼꼽½,½;½G½_½o½y½½¤½º½ȽÛ½õ½ ¾¾+¾:¾M¾c¾ùùùùùùùùùùùùùùùùùùùùùùùùùùùùù9 Æå c¾r¾~¾¾Ÿ¾¯¾¼¾̾Û¾ñ¾¿¿¿/¿@¿S¿e¿}¿“¿ª¿½¿Ñ¿ê¿÷¿À À6À?À\ÀuÀùùùùùùùùùùùùùùùùùùùùùùùùùùùùù9 Æå uÀˆÀ›À©ÀÀÀØÀúÀÁ*ÁBÁZÁgÁ€Á–Á¢Á¯Á¼ÁËÁÞÁíÁÂÂ%ÂHÂZÂu‡—¦¹Âùùùùùùùùùùùùùùùùùùùùùùùùùùùùù9 Æå ¹ÂÌÂåÂù ÃÃ<ÃSÃfÃvÇÙçûÃÎÃêÃÿÃÄ/Ä@ÄRÄhĀĘĬĻÄËÄâÄöÄ Åùùùùùùùùùùùùùùùùùùùùùùùùùùùùù9 Æå  Å#Å4ÅOÅbÅtňŜűÅÄÅÒÅèÅüÅ ÆÆ,ÆCÆSÆcƀƚƩƻÆÏÆãÆñÆÇÇ.ÇGÇùùùùùùùùùùùùùùùùùùùùùùùùùùùùù9 Æå GÇZÇrDžǓǠǮǾÇ×ÇåÇöÇÈÈ,ÈAÈOÈfÈyÈȟȵÈÄÈÕÈëÈûÈÉ,É?ÉQÉmÉùùùùùùùùùùùùùùùùùùùùùùùùùùùùù9 Æå mÉzɊɜɰɺÉÈÉÔÉæÉûÉÊ,Ê<ÊTÊfÊgÊiʲʳÊÇÊØÊàÊïÊËË(Ë8ËCËùùùùùùùùùùùùùù÷÷õõïïïïïïïïï9 ÆE +9 Æå CËSËeËqËËËˬ˸ËÊËßËìËÌÌ&Ì3ÌFÌUÌaÌkÌzÌ‹Ì̯ÌÉÌØÌçÌôÌ ÍÍùùùùùùùùùùùùùùùùùùùùùùùùùùùùù9 ÆE Í2Í>ÍGÍZÍlÍ͌ͤ͵ÍÄÍÙÍêÍúÍ ÎÎ'Î6ÎGÎXÎiÎvÎΒΞαξÎÒÎàÎóÎùùùùùùùùùùùùùùùùùùùùùùùùùùùùù9 ÆE óÎÏÏÏ1ÏBÏTÏdÏuσÏϢϱϹÏÇÏÖÏæÏùÏ ÐÐ#Ð8ÐLÐ[ÐkÐ}ÐМЮÐÀÐùùùùùùùùùùùùùùùùùùùùùùùùùùùùù9 ÆE ÀÐÍÐàÐóÐÑÑÑ+Ñ=ÑVÑnÑёѢѶÑÏÑáÑðÑÒÒ Ò0Ò?ÒJÒ`ÒuÒ‹Ò›Ò«Ò»Òùùùùùùùùùùùùùùùùùùùùùùùùùùùùù9 ÆE »ÒÍÒÞÒðÒÓÓ&Ó6ÓFÓWÓkÓÓ•Ó§Ó¸ÓÐÓÙÓâÓîÓüÓ ÔÔ,Ô>ÔOÔ^ÔjÔzÔ…ÔŽÔùùùùùùùùùùùùùùùùùùùùùùùùùùùùù9 ÆE ŽÔÔ­Ô»ÔÈÔÖÔãÔøÔÕÕ'ÕBÕ\ÕjÕwÕˆÕšÕ¨Õ´ÕÇÕÔÕãÕäÕæÕ÷ÕøÕcÖdÖvÖùùùùùùùùùùùùùùùùùùùùù÷÷ò÷÷÷ò$a$9 ÆE vÖwÖâÖãÖäÖåÖýýýýý2 0 0h1hP°‚. °ÆA!°Š"°Š#Š$n%° Ä3 0h1hP°‚. °ÆA!°Š"°Š#Š$n%° P Å/ 0h1hP°‚. °ÆA!°Š"°Š#Š$n%° Ä2 0 0h1hP°‚. °ÆA!°Š"°Š#Š$n%° P2 0 0h1hP°‚. °ÆA!°Š"°Š#Š$n%° Ä2 0 0h1hP°‚. °ÆA!°Š"°Š#Š$n%° P2 0 0h1hP°‚. °ÆA!°Š"°Š#Š$n%° Ä»DÐÉêyùºÎŒ‚ªK© àÉêyùºÎŒ‚ªK© Jhttp://www.synthesis.ch/yXô;H¯,‚]Ä…'c¥«º“Ddõ*e c èèð€² ð c ð\AÁ8¿ÿLogo-Quadrat, alleinstehen ð€Rðæ’O91ÍîÐü¹»s"œµ!ÿÂ’ÿ- Fðº’O91ÍîÐü¹»s"œµ!ÿÿØÿàJFIF,,ÿîAdobedÿÛ„         ÿÀ*õÿÝ?ÿÄ¢  s!1AQa"q2‘¡±B#ÁRÑá3bð$r‚ñ%C4S’¢²csÂ5D'“£³6TdtÃÒâ&ƒ „”EF¤´VÓU(òãóÄÔäôeu…•¥µÅÕåõfv†–¦¶ÆÖæö7GWgw‡—§·Ç×ç÷8HXhxˆ˜¨¸ÈØèø)9IYiy‰™©¹ÉÙéù*:JZjzŠšªºÊÚêúm!1AQa"q‘2¡±ðÁÑá#BRbrñ3$4C‚’S%¢c²ÂsÒ5âDƒT“ &6E'dtU7ò£³Ã()Óã󄔤´ÄÔäôeu…•¥µÅÕåõFVfv†–¦¶ÆÖæöGWgw‡—§·Ç×ç÷8HXhxˆ˜¨¸ÈØèø9IYiy‰™©¹ÉÙéù*:JZjzŠšªºÊÚêúÿÚ ?ôjþoÔ/õô´ÓÒÚÆá­¿Ò½b䨿»øw®*­ÿ!þÔÿôõŠ»þB/ý©ÿéëwü„_ûSÿÓÖ*™èÿâ2þ™ú§*Gê~¥)¿.^§ÑJb©†*—ëâ1~†ú§*Ÿ[랥)·>ŸÓZâ©gü„_ûSÿÓÖ*ïù¿ö§ÿ§¬UßòíOÿOXª+Mÿ}mIþŽú?«zþ­iðÓŸÃ×®*œâªÿ_ú¤Ÿ£ý/®Pz>¿/JµåÃâéኤòíOÿOX«¿ä"ÿÚŸþž±WÈEÿµ?ý=b­¯ü¬>C—èŽ5ø©õšÓÛdX«±V:ßò°ù?¢8×á¯ÖkO|U¯ù¿ö§ÿ§¬UßòíOÿOX«¿ä"ÿÚŸþž±TòÃëÿTô‡¥õÊ[ÐåéV¦œyü]¿«Z|Uáðõ銡ä"ÿÚŸþž±WÈEÿµ?ý=b®ÿ‹ÿjúzÅS=üAÆ_Ó?TåQèýOÔ¥7åËÔú)LU0ÅRýcüAÆ/ÐßTåSë}sÔ¥6ãÇÓúk\U,ÿ‹ÿjúzÅ]ÿ!þÔÿôõŠ»þB/ý©ÿéëEi¿ã/­¯é?ÑßS¡çõo_Õ­>søzõÅSœUBÿëÿT“ô¥õÊG×åéV¢¼¸|]<1TþB/ý©ÿéëwü„_ûSÿÓÖ*ïù¿ö§ÿ§¬Uµÿ•‡ÈrýÆ¿>³Z{b¬‹v*Ç[þV#ÇôGü5úÍiÿ!þÔÿôõŠ»þB/ý©ÿéëwü„_ûSÿÓÖ*éߤ~§é/Gë»ú¿Wåé}£Ç?‹ìÒµý¬UŠ¤Ú—øËëmú3ôwÔè8}g×õkOм>½1T/ü„_ûSÿÓÖ*ïù¿ö§ÿ§¬UßòíOÿOXªe£ÿˆÿ}úgê³è}OÕ÷åÏÔÿcÇŽ*˜â©~±þ ãèoªr©õ¾¹êR›qãéý5®*–ÈEÿµ?ý=b®ÿ‹ÿjúzÅ]ÿ!þÔÿôõŠ¢tïñ§×#ý%ú7ê[ú¿Wõý_²xñçðýªV¿³Š§X«±WÿÐô7”ÞÏ0ÛJOøŠâ¬v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUت_­k ¥Ão#DeúÅÄvÀƆSN]LU0Å_ÿÑô¦‰¤M§Ï©É#«‹ë§¸Œ-vVPÔuÛMqWb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]бÏ<¼zoý´­¿âGdx«ÿÒõN*ìUت”—v±7 &ùY€?q8ªßÒòÓüÿ\Uߤ,?å¦/ø5þ¸«¿HXËL_ðkýqW~°ÿ–˜¿à×úâ®ý!aÿ-1Á¯õÅ]úBÃþZbÿƒ_늻ô…‡ü´Åÿ¿×wé ùi‹þ ®*ïÒòÓüÿ\Uߤ,?å¦/ø5þ¸«¿HXËL_ðkýqW~°ÿ–˜¿à×úâ®ý!aÿ-1Á¯õÅ]úBÃþZbÿƒ_늻ô…‡ü´Åÿ¿×wé ùi‹þ ®*ïÒòÓüÿ\Uߤ,?å¦/ø5þ¸«¿HXËL_ðkýqW~°ÿ–˜¿à×úâ®ý!aÿ-1Á¯õÅ]úBÃþZbÿƒ_늻ô…‡ü´Åÿ¿×S¸Ö4‹hZk‹ëxaZr’IQTTÐT’SЍ[y›ËwRzVº­œòÓ—®"v ïEcŠ¢ÿHXËL_ðkýqW~°ÿ–˜¿à×úâªZþ…fª×z­º±¢´³F€ŸɆ*Õ§˜t ÎTÔ­n}:sô§øÖ´¯4­1TGé ùi‹þ ®*ïÒòÓüÿ\Uߤ,?å¦/ø5þ¸«¿HXËL_ðkýqW~°ÿ–˜¿à×úâ®ý!aÿ-1Á¯õÅ]úBÃþZbÿƒ_늻ô…‡ü´Åÿ¿×wé ùi‹þ ®*ïÒòÓüÿ\Uߤ,?å¦/ø5þ¸«¿HXËL_ðkýqW~°ÿ–˜¿à×úâ®ý!aÿ-1Á¯õÅ]úBÃþZbÿƒ_늻ô…‡ü´Åÿ¿×wé ùi‹þ ®*ïÒòÓüÿ\Uߤ,?å¦/ø5þ¸«¿HXËL_ðkýqW~°ÿ–˜¿à×úâ®ý!aÿ-1Á¯õÅ]úBÃþZbÿƒ_늻ô…‡ü´Åÿ¿×wé ùi‹þ ®*º+«Y[ŒS$׊°&ŸAÅUqWb¬sÏï›ÿm+oø‘ÅY*ÿÿÓôÚßIwƒYÌÖórøÔi¹Û|UŠ»xçç¯æ™äxQºO¬]L«…˜Zþ`_i֚Εg¦²%¬Ò4!Ô¢¿©'=^|«ñ|ù9*ú«v*ðïùÊŸùGô?ù‹—þMâ©üâý5?ôaÿc8«èUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìU<òüuüboÖ1VkŠ»cžxÿxôßûi[ÄŽ*ÈñWÿÔô7”ÞÏ0ÛJOøŠâ¬v*øÛþsY®ÿÆú*°?T,a=½C'ï?áDXªEÿ8ݬyÂ{ôÖÞÛ_’D67|Tz\wH¤…ŸÚVƒíqÅ^÷­y?Êšü–÷®™o{-»¤°Lè UM@ä7dñFýÛ~Òâ©ÐØtÅ^;cÿ97å+»Û{DÒ¯Õî$H•˜C@]‚‚i'¾*õùåÃ$¬ XÔ¹­Wy•ÿ9-åMGS³ÓâÒïÒ[Éã·ØCÄ4®I ¥N*ôÏ1ù—Dòæ—&©¬Ý-¥œd/6©,Ƥ"(«;š}•Å^E{ÿ9Qåèî8Ùh—Wýì²G |Â/üKeÞCüïò›ïSM‡ÖÓõY+éZ\I8ŽGÓ‘ ) e¸7ù8«Ì¿:¿8´?0hº‡•m¬®¢¼¶½óÉéúDÛHÊÔâÅ·§Ãðâ¬òÏÚo’<Ís«jó\Ã=“Ú¬vüyyb̨ãHŽ*úoòëó'JóÕ•åÞk=ªYȱ:Üp©,¼ª83b©›¿ç <‡åû©,¡yu{ØÌ)‰uV•Š©ÿž~¦*Æm?ç*tœ-Þ…u ÞH¥ŽW§úŒ"ðø«Öü­æÍ ÍJjš-ȹµbQ¶*èãª:Õ…ãeøqW—~g~dþXYy¶m'̾Y}[QÒÄ@] qÆXÖeP]Õ™©öáåËgéç½*?ËåóŠZʺjÚ‹•´P‚QVeÅQmóÇ–<¥d.õËÕ·_B Í)’5ø»}…ý¦Å^Y{ÿ9S $¤YhwSÅSGšXáoøÿıVYäoÏO'y²ú=1Ún§)¤÷AxÊi^1Ȥ©oò_ƒ7ìòÅU???òRë¿ôiÿQâ¯ü‰ó&åÏ7ÝêÚ½À·²ƒN›“Ù˜ÉTE³·e«Ó.¿ç*|¾—%mt;©­«OVIcéãÀ ü>*ô"~ey_ζ²I¤LÉsæÆpxÁØ5edÿ-±WœÎTÿÊ?¡ÿÌ\¿òoKÿçÿé©ÿ£ûÅ^Õæ6yËiÔu»Ä´·¯Á©y•á ³·ú¸«É¯ç*<»ül´K»ˆA§©,‘ÂÔñ =_ø–*Í<…ùÏäÿ8Ü W’ÇU •±ºYøŠ·¤êY$ ýŸ†OÚáÇg˜«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»O<Ÿÿcÿ›õŒUšâ®ÅRo4i·wöÖIj¡ÚØ'2KñTçÿÕô7”ÞÏ0ÛJOøŠâ¬v*òÎïËíÎêÚv£Ê)¢U’Êö0 ÈE ý¤oÛOÚÿ[‹*¯–<Ïÿ8õùƒ£´’Y@šÍšÔ¬¶ûÞ>ð½—ù1ú¸«Ð<íç'_ì/nl^¤Ú|ܽ*Ž«$|5ÿcÏ}cùcçÈ<íåhµeŒAw›{ûu©T™'wàÊÊëÿû8«ã.ÿÊA¦Ì\òqqWÝzüsîãÿÄN*øwÉŸò˜h_öеÿ“銽—þr²MC×òôdŸÑånY@­ À <¾IN?ìñVùWwù8–wvÞzµ•¯¥—ýìú愨inÜÖN|‰~ËŠ½ÃòÉ¿–z\—º§•/ãÕ§ˆ³«Ëm n! ³§»:ó|U‚~x~RyWBòí÷™ìžèêW7ªÒ $VŠ·Yè¡ê~‹`_’žFÑ|çæ«­/Wi–Ú.Û¸Fæ³D‚¤«|ä ý¨Ãpž&§Šò\Uîó•/hDƒu!Æ,Uÿ8ŸÿMOýØÎ*óOÎ/7^y“Ïz“É!6VIga j‹,P²Y}Fÿ›WzƒÿBÅc¡Åcxº…ëFÝô–úˆvˆÇÆ5ôÖ¿c‡û.MмV›OÑüÕ4þV¿’{+;6•Å£’ŠC¡!Õ’„ü ËŽ*ûcËz°Ö<½¦jÀúý¬7%FáL±‡+þÄšb©Ž*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb©ç“ÿã¬ã~±Š³\UØ«±Wb¯ÿÖô7”ÞÏ0ÛJOøŠâ¬v*ñ_ϯ̽+ÈÁ®f qª\F«§Ør¡vwjn±'í7û UˆùsóóòëV°Žk»ñ¥^q{;¥o…»ñ‘T¤‹_³û_ä.*ñÏŸ;yWÍ~c´Ÿ@_Um`1\ê ~±-U0W+ÿÚþ\Uê_ó‹úmÝ¿“/ïea½½?V£,H¨Î=‹òOù犾nŒË¤ëJ]yK§Ü‚Èv«C&àøn¸«êýó·òú/*\ꚬW72Û¿Õl¾»Jèx#ÇNQü_m›á\Uòß“?å0пí¡kÿ'Ó}ù™þ_)ÜÉç(Ò]&2 ©¯ªf¡ âCú§zq?g—/ÝóÅ^;©~E~_êZ;ë^WódqZÌ©õÇŠH†ÕâÃNÍÓö±W–þ]kZ–çmïOwYšîd =X¥‘QâaÜ88«èÿùÈå'òÊà€HVäûDb¯ÿœ{ó.‰ yêiõ{¨ì­îìeµŽâb1!–)7? ‚±7ÄØ«ßüéçÝ=<‡æ WËZŒ×:|Dö’$뒪ܲrN\ÿØüX«æ/Ë?*XùÏÎéš¾ öÑÜ '–^@Í3Ê#=xõåȇý¬U꿚_•ß•OòeÕÊ$‰¬ºpÓ—ÒÉ)a¿§P¥QwsÇû,U‰ÿÎ3䯗þÙóÿÉȱTŸóóÿ&Ö»ÿFŸõ*öývoûtÿÌÌUãßù6´/ú;ÿ¨9±WÑ_ßù+5ÿøÅüŸ|ûÿ8óÿ“OMÿŒW?òañU_ùÈo0êzæ%æ›<Œ,´¥ŽKrh«êD’;ÓùŸí' UèžAü…ü¼ºò¥†³ªÜÉ©=åº\M"Ïé[ÆYy2Nû¿²üßí/ì}œUáÞƒËþpÔ­ü°yhpºÇhÜÚ@JÆ¢B®Ä–S(“‹Wì⯢2¿õý³ô¯ù=mмSòSÏ–Nóy»Ôê4ÛØÖæURÆ*²ºÉÄ|L’Œö[}¬þv~\iº[ß&± ëñ&Kb^gjT/?w_8ñÅ_&C ÿ™üÒ#‰?Óu›ÃEQPâJŸö+Ëþ{Ïüå$k–´“ì¥Ìеð1Tüâý5?ôaÿc8«Èÿ2´ ÏZÖŸ:êI`'ö¡™Œ‘0?ê0¯ùX«Ö|«ù7ù3æ-VÓ^¾@Ñ«]@÷VŠð=*É 0¼OÚûXªFü·ü…ÕüÉ?—ì¼Ã©½ôL Ö†#âX$ô8ÈÊ~òÿÝ|×} hÖº&‹e¤Z3½µ„)o ÊAr±ŠÅB¯/’â¨üUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®ÅSÏ'ÿÇXÿÆ&ýcf¸«±U ËûK$î¤,²,1’ «¿Ù]늫â¯ÿ×ôg–-.­îõ¶ž&g¿’HK rBxŒU=Å]оüýü”Ò|ïæ©Çw%†²GÌk,.‹Rªñ’8Ò¿j6_ò•ñWÝÿÎ4~cC)HZÆê:í$s²Š{‰*È|­ÿ8»¨µÊMæ}N(íTÕ­,y;¸²euAû“}¦é¶e„}„ mej‚8 AEU^ƒûqW‹þfÎ;O®kw:ß–ï ¶šõÌ×v7\Ö?U·wŽDYïâ(Éö¿oI<¥ÿ8Á«~’Š4_[®Ÿ{[6w’Z°]–1Ÿæ^mþ¯ÚÅ[Ðç|×§kšv¡.©`ñYÝCpè¾·"±HT¥h1W£þm~S7Ÿ"µ’VK› Â(-[–ä”JÉÛÔ¾‡†*ñçÿœaüÁp[½5£®ÒúÓOqèòü1W¢~ZÎ>YykTƒ[Ö¯QÔ­;X"R¶ñH:=[â‘—ö>ãü¸«Ó|ÏåÍ;Ìš 拨©kKØø9_´¬$u¯í#…uÅ_;j¿ó‹Þq†å†™¨XÞZ×÷o+I´ÿ)H¿t˜«Óÿ*?)¯<³å}cEóÛ^Ǭ5&†Ü» ŒÆP©gXÏ-û/ʼçÌó‹¾c†õÛ@Ô­®l‹V5»/ Ê;ÁŸÍ𩊣ôÏùÆ-M´ûÙµVõwˆ¥Œq™ !Ø<²2‰ˆû(©ö¿›d”Ÿ’Zÿ’üÒúÅýý¥Ì k%¸ŽSŸ'd`~4QOƒ@þe~Aù“Í^uÔuû=FÎ kÏGÓŠoW˜ô Ž#^(Ëö£¯\Uœÿ€u/ùTŸà¿¬Cõÿ©}Wë?£Ë—*ôçÇýŽ*Á¿- üÉå_:éÚýæ£g=µŸ­êE«Ìú°I§$UûRW®*õÌ-Ýy›ÉÚž‡i,pÜ^¢$rË^¬Šûñô_ Uæ–‘bòœm5ËÝBÎâÞÝ&FŠW™2FÈ)Éu>8ªuùµùoç;ÅÖ4Û¤°Ö‚æõT˜gTÙ •ø‘Ô|<èÿ㊼ãLÿœcóÄ“úú¥•­aê´/,Ì@î±”[ý›¦*™kß󋺤š¤¡ê6Ðé"XRèÊf,±*ÈÏÁ Õåÿób¯Tóg‘µ gò»ü!Ä1ÞýVÎßëËÒåjñ3j7¤xü8«ÌtùÅë…[صíJ²ÃKìù—ŠpÀ†e‘Q^><•’¿ð?kHgÿœ_óÒݘá¿Ó¤¶¯ÃpÒL†Ÿå'¤Ä7°-þ¶*õ_ÊßÉ#Ésþ”»œjZáR±Üpã…D¤“ÉâÒ7ìý•O’¨ŸÎOËmWÏZfi§]Ajös<®×èC' تò_ò³XòéÒ7v÷_¤¾­é}_ŸÃèz¼¹sUëêŠb©Ïæ?å_—¼ói× ZjVà­®£Ôø:šz‘×~5_òy6*ñ;ßùÅÿ<Å?Ký>æ~剩âÉéµ?Ø»â¬ÃÈóVzeì:š/P–…°a%Ü‘‚¼‚¿±Â?ò¹}œUWb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»O<Ÿÿcÿ›õŒUšâ®ÅXçž?Þ=7þÚVßñ#в™uúÄÄv,ÍHþü*‚Òÿç%?1mf yõMB*üI,>™§ù-Jš¶*úòóΫç.E¬®Ÿ6œŠ¦¡V+Õ¢}½Hëðóâ¿,U“b®Å]Š»|«ùÓù«æ]CÍš†‹§ÞÍc¤i“=§£ní–HVZ3|a‚¯ØãþV*»òƒÊŸ˜)ç-W¸´Ô"Ñf“Ô{¦õ=6ŒÆÌ¥…»}¾&~,Uôž§æÏ*éW"×TÖll.J‡]\à ñ5¸»+q4늣4íOMÔíVóN»†öÑÉ qo"Ë*h@t,¦‡lUŠ»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]а/ÌÎ/-y'ýP×ú˨tÓ¡ ì´Îj#Sògÿ#Ž*ñ-Sþr[óêV6Kg§Å_c‡Ôj”Ò—ü•qUMþrgÏ–s/é(m5;züjSÐò^?…~˜›}ä?èžuÑŽ£¦sâaݬ£ãŠJV†›2ŸÙuû_ð¸«&Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®ÅZfURÌBªŠ³€¹ÅR8|ûäiæŽ<Å¥Ë4¬(’öÝ™™UCÔ±=*žâ®Å]ЧžOÿޱÿŒMúÆ*ÍqWb¬sÏï›ÿm+oø‘ÅY*ÿÿÒô7”ÞÏ0ÛJOøŠâ¬v*øçþs[Pºo8èºy¨´ŽÍ®~ËI#ð?JªøXó_—üѧKB»–k#BÒ„’:H ¥dT~Œ§ìâ©wš2¼“å[ȬµíHYÝO­^Œò“b¼¿t’ñ+uÅS/-y§Bó6›úOD¸7V%Ú!1ŽXªÉN@ UÒ¿jœqV;¯þtþ[蓵µÖ°“Ü¡!¡´W¸ Ž ¼`Æù%ñT6ùïùeª\­²j¿T™Ïq¼(~ré/û7\UŸ«”ÕNàŽ„b¬ßó×ò®æâ+xu¾sLëkõ[ÁVc@*a©ÅQjüâò–/ÛNÔoËßÇOVÚÞ6™£®ÿQÁ[üŽ\ÿÉÅY^›©ZjZe®§jŬï`Žæ`T˜å@êH=>аÍoóÇòÏHíåÕ…Ôèhéh8´þñG¥ÿŠ£¼­ùµä/3Ü­¦—©¯×_ìZN­Œ|8 !öFlU—â®ÅR=ùž?+ùGS×C½œ5F™ÈŽ%>ÆF^_ä⯌ôû-sÍþhŠÕÝjú½ÇÅ,‡«¹äî粨«7òªâ¯©<§ùä Â8ïlW¿â>±wv9†joÂ"}4OåÛŸó;b¨o3ÿÎ=yYž ìámÒ@×"ÓìKtàĤmü®ƒýƒb¯@Ðô-'BÓ!Ó4›d´²·Ž(ÇÞÌz³·í;|MŠ­×<áè6F÷Y¾†ÆØ &`¼›¯iÛü•±V ÿó‘?•Ë?¤/§d­=qm/ ‡ÿ„ÅY§—<Ûå¿2Z›P†ú%§¨#4t¯Nq·¿åªâª¾aóåÝ*]WY¸ú­„%VI¸<”.ÁWá]÷cü¸ªC¢þnþ]kR\ǧë1¹³®®žX§·D…P¹yã>Ôˆ´åËâÅRgÿœ†ü­K£é™¡¸[iŒñð˜«=Ò5+Y°PÒ²›û¹â`Ê|AðaÝOĸª&Yb†'–WXâŒy…UQ¹$€«Õ¿>ÿ,4éÚªÉѤO*”€Ûýƒ¶*œyWóCÈÞh˜[èú¤r^_ªJ7[òη§ú*8à–S¡õнÀŒ:WÔ†ž“ÂÉû\±WËÚÎú7X¾Ó½OWêWÛú´ãËÒrœ¸Õ¸òãZW{µ—üâ×;Bÿâz}f%Ûê?f¬¯ÿ-ýšb¯*üÌòø#Ìk£}{ô‡+t¸õý/Cí³/<åéï,U˜~^~@ÿŒ<«m¯~žúÖTú·Õ=n>”…+ÏÖŽµã_±Š£ÿç"¼úß˺¬'ÕHícÒnæ À4–Éû§+SF‘ŸµþëÅY_üâÿ™Ï–u- gýæ™8žÇaÀÜe•›þ2b¯óf¥uæ8kZ­º4Ââk‹• ¯hªTŸd…WzÏüâǘ==CYòü´ñ¥õº“ûQNZ{°xÿà1Vù˯?˜?2õW„™b·”XZ(©ÚÝ¿ëK͇úØ«éÝÈVV¿—ÞO¹/FÏм’ÝÌoêÉñÌêËã+1þV_…¹.*ò}3òÉ:%ÅÃùÛÌ$bCõ(â+@b­å2ü\Ú¿b?…ߊ°/Ío(ùF{k¿'ë‘j6ó³Gqd&I䉀¨udëtø¾Ë~ÓrøU{güã˜îµo ›K© ’é7-kcVô ,‘ƒßáäè¿ä¦*ùV e†h慊͇PÊjúqW¸i?óŒ~`ÕlÆ£®k«e¨Ýþþ[A®\<Ÿõd2EûÊŸŽþ/ÚÅZüðó^¥åí Cüº±º Zi¶é«ÜEUõDh"HüUÓ2:þ×(ÿÊÅR¯ËÊ¿!ë:jþjóV’\3}_OŠêÞTRW”¾§&«UJ/Ãþ¶*Ä¿2¼£¥yOÌ1C¡jñêš|È'¶¸ŠXÞX˜1$h9­9+˜«éïÉÿ7\ù«Èvãs¿ˆµ­ãÿ4šsùºvÿ)±Viм«þrQæ_Ëb#¯½·ÓùhçöAqW’Î6Çnÿ™q´´çÃA_çøTÓýƒ>*úÃv*£yu¤÷w  xÚYœöD˜ýb¯ŠüÛæ0yÿÍßXpóMw0·ÒìÔFŽÜc‰JšŽmûoñb¯LƒþqWYm4K6½Z‰ZýU`w„5:¹«}>†*òëk¯4~^ùÉø1´Õô¹¸M$Ç"ìJ·NqJ›ÿªÜ±WпœzÕ¶¹ùÚۤ7ëe:¯R¼åBTû¡øN*ù×ÈþTÕ|׿t-6A —jÞ¼®Hb÷Œ\/Úªñ_çኲßÌÿÉCÈÚU¾ªº’jvRJ ˜ˆL²–SÇœ¡ñ#—/µŠ²¿ùÅnáumgCg&ÞKu½Ž2vWÄNT–%N_ê.*…ÿœüÀ¿º×O”,¦1éÖ*¨*zÓÈ¢EV#ªDŒ¿ûó—/°¼UJ¿/¿çu¯5è±k7zŠi6W µ¢˜LòÈ ‘̧8‚¡§ÁñüX«;üµÿœy} ÌÒj¾až+ج$VÒRÁdqFJ¤|<ÙŽ¿oüŽ<Õb?ó‘˜ú‡™%ò­¤Í“¦ðúÒ! šå”9-N«`Š¿ÏÍ¿—EyòwòÚóË–×Þdó4QêW‘ ~­oyk€8ª«sÍ"µû*ßUæþgÓÉ~sx´]U/Œ‘Üiú³«TjP²óSðºÿƸ«êï01~Jj:ß}¡]É*‹(¶‘dQì$ LUòO—´­[XÕíô%Yï¯ÛиÔ6íÈÿ QÉÿÉÅ^Ç/üâ®®ºq’=~ÔB×ê¦XKxzÜË}>†*ò+Tó‘¼ÙëÃÊÓUÓ&1\ÀNÍÁ©$OMš7§ün¿³Š¾…üÄü¨ƒó"K7Ûë&ÂÝ´¸}smëCÎá[Ÿ«*&ãN8«æ}Ný%¬XéÞ§¥õÛˆ­ýZrãê¸N\j¼¸ò­+оšü¼üÿy¦Û^ý=õ﫤©õoªz<½XÊWŸ­%)Ê¿gx'æž±¨ê¿˜:ì÷ÌÆHo&µŠ6ÿuÅo!|•à¾,UèzäŸåç˜tËmYµçEf†âH¸#t0*­Ä_O©Š¾Œüòä»q¥éõ’G¤¼»qGš_„#öTtDý•ÿ+“2¯ZÅ]Š»v*ÿÿÔô7”ÞÏ0ÛJOøŠâ¬v*ò¿Î9h¾QŽ}_Vˆ‘!…(d–Bã•cÿ ¿*‘ùwÏ^Róž—ºf¥¨ëÊHYÕfÅeŒžHGýsоmÿœ‚HÿÛ·–¹¸h˜êßS*`õy|càõiËÔãþO/g_óŽúeýçå§™­”ñŠúi µ'oÞ5ª£0?ì£ÿÅ^å=J=Î:V¡}ôÛèeºŠŸH €?™hÙb¯¶¬õÍ÷M­ôiÅyýmdS_Õ¢ûòÅ_"~uy—Lóæýö˜âk(Ö;xîìÈb@Ô÷^U ß´¸«é_É6çMü±Ð-®AYL ?êâWü‹Š¾IóŸü¦ïý´.¿äû⯸´ïøçÛÆ$ÿˆŒUòïüäÏþLh¿íŸüœ—zçüã¥Õ¼ß–6pÅ"¼¶ÓÜ$èèÍ)p÷VVÅY柖™ü…ªiÑw>—ÖlˆÞ³CûÄ ÿ)éÿ³Å_%y/ΞW¼Ô.-«[ý>æÁ¸š3'îÜÆ9B6*ôùÆÏ(Ûk^a½¾§ÔΛB6?\¯©Ou)ÿ=1VåÝgRü¾óÛ\²s»Òe¹µž.„õýž_*œ~HyqüÇù“d÷Õ‚À¶¥v[z˜ˆ)Zõå;G_òyb¯vüûóÆ©åo(D4™ †§7Õ’å~ÔQ„-#!ìÿeTþÏ.Kñ.*ðÏËÊKóâúö}HZZÚº‹›—S<òK%ZK/‡Äîÿðxª7ó{ò“Eò&›a=¶«-ååìÌŸW•QO¦ˆK8ã¾ÍÁÙb¯@ÿœVÿ”\ÿ˜¸¿äÞ*ùóËê­¯iªÀ2µÔ!”î2.Ç}銾Rÿœ“Ónm¿1šî@} ûXd»~ì™~‚•ÿeЬü¼ü_;y}uk?0Eo*»EufÐx]NÁˆ‘kÍ8ºšb©­çüãµ–«i¤ÝùÆÒ Jø3ZZ¼<( +/¿Ãüÿ±ö[{GåOåüÞFòíÆ‘5êß´÷ov&XÌ`Ž8øñ,ÿïªÿ²ÅYž*Åÿ3<¬þhò>«£ÂÖ¥ˆIi_÷ô,$ŒW·6^ÿ+|åO1j>RóM¦¯d]iò‘-»Õy- Kw^JYÉÅ_aù[óÊg±K­3Q„» Éi+¬wžáã'—û!ð7ì¶*“ùçóŸÉ¾SÇ%ÂêWÏ"«ÙYº;Æ•øÝÍx¡Uû(Ç“ÿ«ñª©œú¾•ço!êå륺MBÆæÚ"§‹¤²ÂÈÔîŽ tlUò/‘5›mκF©|¤[Ù]Æ÷"•e@hçó <©Š¾Öƒ[Ñ®4Ñ©Ã}šq^\YÑãJÔ½xŒUñçç˜ôï0þa꺖šÂK&há†aÒA KqþK2žäqÅ^·æý6çMÿœf²´¹gX¬äun«ë\,¡Oú¡éа¯ùÆoü˜ÒÿÛ>ù9*õŸùÈÿü–sÿÌ]¿üHâ¯.ÿœ]ÿ”ÿPÿ¶Lßõoб¿Ï=6æÇó?YõãtÑÜÀçö£’5ܪÁ“ý†*ú/òkÍš.·äMÚÒâ?®éÖÚ]ÚrThGȧ^2qæ­Š²Í7_Ñu9îíôëØnæ°qäq8s‘PŸçË’ý¥lUòç6›s§þfk©8#׸úÌLz4s¨‘HùWûU–ùGþqçüOåë-nÃÌú7q†x¾®ÌÑH6x›÷ƒâ¾UXÎ;Xq´!çOÓ œØúÔôØ =_jñû\~/²Ø«Ö[Ê’yOòCWòü—"ñì´N· ¥z«<£á%©ÇÔã×|áùAæM7Ë¿˜ZV§©7§b¦H¦š•ôÄÑ4aÏù*Ì9‘Ë}‹.³¤E§NKØN Ïë†Dôxøó¯Ç|[ù‘¯YkþyÖu{÷Žæàú E9"(Œ=N|y⯮¼«§O¦þ]év­Å¶—s)ê²5ÿbÛb¯|«q·š4{‰ÜG7ÖÒK#tTIT±? 1WÝ‚D!H`Cý‚Çjíã¶*òÌßÉo(ù“Ìk5¶¬š7™55iE«t¹ô€ë$uz}¶CþW\ÛxÇæäïš¼‘kýü–÷:|²ˆRæÙØñr (tuF‚·Ùæ¿åb¯pÿœ:óηªjº——µ;‡»ŽÊÔ\XË),èœÂ ä¸ªi¯~Fþkêzbkœ«y†yV6³{˜™¡· Ä—–WXëÏáfUÿˆ*ô¿È$ùŸÊš>«o¯Ù}Jk›„’õb—’ªPšÄò¿Ž*ñíò+óRÛX±¸›Dá 7I#}jÌÑUÁ&‚bz Uõ¶*Ä¿2?.4<è¢Êñ½í¹/a|£“DíN@­G8ÞƒšWþ|õqù7ùÇåk÷—FŽvê¢ûJ¹àY|(9‡Ò˜ª¶‡ùùŸæ-P]k¥´ärmBúQ4æŸÊŠÍ#8ÿ‹?õñWÔ>ú7KµÓþ±5ßÕbX¾³rÞ¤ÒqäíÝŽ*ŒÅ]мŸóKòMó]ÌšÆ2iºÛŠÎÑîùŸˆä’xÈ¡¹~Òrø±W†jŸ’Ÿ™Út¬’hs\(? ¶¥'V FKöJ¸ª¦‹ùù™ªÌ¨4w²Œý©ïX@‹Ú¥Md?ìclUôwågåfäM6UYæ«yÇë·t*´_³iSDZõûOÿª«üÖÿœ|—YÔg×|ªñCwrÆKÍ6SÁFݤ‰ú+9Ý‘þ_5û8«ÈßòWóEgô—ççZT©dlå„KëÛËñ³¡ŒR;tSÛzçg–5Ï2ù]/E¶úÝó\C"ÃÎ8þ$±å+"íþ¶*Àÿ!,|ñå_8^jö›õ;9tù-ã—×·–²4ð¸^1HíöQ·§UŸ~j~Uiž{Óâ&Ag¬Z,ïxòNæ)@ûQ“Óö£o‰m]WÎÚ¯äOæ~;Gú ÞF {I#•Ü ¬€®‹Š³ŸÉßÊoÍ ÌkºèvJiw ¬²½Ä5©Òˆßù¤dhþÚb¯Kü×ü¤Ó¼õiñʶZ媕¶¼ ²ºTŸJP7áÈÕX|Qÿ•öqW„ÿÊ«üíòÌòÅ¥Áyrü/6—uÅ$â7G§üdEÅS%ÿÎ?yÿPÖ"ÔµéßD%=Ϭ$½vµƒ?ÿ‹$‡íp|Uï~~Óü»ó|™øi«ÉÏ&4¶qR{œUñß’|µþ'ó=–„&ú»_zˆ“È+¬NëQü¼”rÅY§ùùŸarÐþ†k´‰=¬‘Éñ_öh˜«?ü«ÿœzÕbÕmõŸ7Æ–ðZ²Ëo¥†YIÕLÅK"Æ:ðäÌÿ·Çö•}@ ‚*ÄUò·ž?ç¼ã¦ê·ù~×ô¦#³ÛzN¢hКˆÝ«1_³É9òÿ'ìâ©×ä—å¿æ“ç›SWÓ&´Ó-#YçtL‘2¨XùsÜŸÙ\UKó;òó^ÿÍ7:ì.¶$pÖÓ[ȰK jv‚'eáéþϤò¿â励¹-?<|ÄÑ[êVÚ…Ìq‘Àê7UŽ>Õ´‡þb¯¤?ç*G‘fº–òtºÖoâ¥Ì‘WÓ‚±ÆZŒß,ÏÅy|?ʽçv*Ç|ì̶zwEu`i¶ÜŽ*ȱWÿÖõ4pCsj†Fç!P&=Í:œU~*ìUƒù·þ; þ¢~¬U&Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUþaÿÊæoûdßÔ3⯕$òièñ–_ù1&*û+v*ìUØ«±Wb®ÅSÏ'ÿÇXÿÆ&ýcf¸«±V9ç÷Mÿ¶•·üHâ¬ÿ×õN*ìUØ«óoüvýDýXªMŠ»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUت•Õ­µÝ¬Ö—Q¬Ö×ÑO Š«£‚¬¬Ue48ªK§~_ù#M½ŠûOÐì­o $Ãq(®¤‚  ¶8ªŠ»v*ìUØ«±Wb©ç“ÿã¬ã~±Š³\UØ«óÇûǦÿÛJÛþ$qVGŠ¿ÿÐôg–.î®.õµžV‘`¿’8Cñ@x U=Å]а6ÿÇa¿ÔOÕŠ¤Ø«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»O<Ÿÿcÿ›õŒUšâ®ÅXçž?Þ=7þÚVßñ#в·Ö.b¶§.<}RG.Zxb©Ž*ÿÿÓô¦‰¤M§Ï©É#«‹ë§¸Œ-vVPÔuÛMqWb¬Í¿ñØoõõb©6*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®ÅSÏ'ÿÇXÿÆ&ýcf¸«±V9ç÷Mÿ¶•·üHâ¬ÿÔõN*ìUØ«ó{*êÎÌBªÆ¥˜ì©Å^+æ¯ùÈŸ"h³ÉkdeÖnc%XÚ;zÎ@oœk"â¬R?ùÊëc5$òÓ¬5ûkx©þ©…Gü>*Î|Ÿùíä?2ͧÖKÔ$!c¶½ ØöIT´g}”3#·òbªþ{üãòÿ’µHôýcNÔ]¦ŒKͼp<2/F Ï27$;:•ÿ…eÅRþr;ÈZ®­i¦¥¾¡j÷’¬)qs ³š/6Yœª×jñÅ^©Š´Ìª¥˜…Uf;sм–ïþroòúÞîkuµÔ®dÅŽ@¦œÐ´êܪòUÅYw?2´ŸW×<ͪ¦•¢Û«ÇÊ‚QÙˆUE¨ßzßüã?æ4†xßO¹ ýV)ÜHO…dŽ8ëÿ=1Uÿ”ÿ’¦¹®Kqæ[Yl´2cͼ¡’K‰“ýÔ½?v?Ý’/ú±ÿ2*÷OÍ/ËËO8ùIôØ‘"Ô,Ç«¥I@H«ON½£‘~ÿbÿ±Š¾5¹¶¹´º–Úæ6†æÝÚ9¢qFGCFR;F*ú÷òOÏÃ;Pˆ]KÏXÓ8Ûj?Ð~êoùê£âÿ‹LU"ÿœˆüÂýåñåÛ 8êšÂ;)£Ei^.~sÆ?ÈõqW;Zòö¥æ-rÏFÓcõ.ï$¿Ê«Õ¼oòqWÛRòÆå/YèšxýŪQ¤ ’C»ÈÔý§mÿáqW˜ª¤ÍÑÏ ´sDÁâ‘MYMU8«ìÏÊ>Ãç?)Á|ì£S¶¥¾§Ú“(û`$£ã_öIû«3Å_Ÿ˜«êÿ$é7šÇüãäUSw{§]AsÅK¼²SÛyý ‡ægûâÓþ’úb¬?ΞE×üŽ´‘¤÷zñˆœH8r+¹늭òg’uß8j’éš*F÷PÀ×.%qújè‡sß”‹Š³/úÌÏ÷ŧý$/ôÅ^±æÍûCÿœw¸Ò/­å”1ι/!p‡cß®*ù[~â®Å_*ÿÎLÿ䯋þÙðÉÉqTãþq[þR sþa"ÿ“˜«Òç!¿òVj_ñ–ÛþO¦*ù&ÞÞk›ˆ­á^sLëkP*ÌhMSгßùP›_õbÿ§»?ú­Š»þTæ×ýX¿éîÏþ«b¯gÿœ~ò/š¼§g­Gæ ©=Ü5¸õa—EpßÝ<”§!ö±T«þr[Ïwºm§•´ùL2jQ´úƒ¡£~E=·ã++óÿ%8þÓb¯Ÿü»å½kÌz¬ZVl×W²Ôª >Ó31 ª?™±W£\Î3~cEhgI4ùå¿UŽwV*ñ¤Uÿž˜ªÏÊïÈýk]óßâ+Yl4.P—±H I4ƒF3ü´¡yý†ø>×,UõÔÁ¤Í(#†+vHãQ@ª©@ð|оÓüŸÿÉgåßù„_ø‘Å_?~ùî÷]ó…΋¤i,†„…îá–F«+r•Wü¶ÅX·’?-|×ç9e]Ý~¯ =äíéÂŒw M 3’ŠØ«$óüãÇæ.d÷‹¶§kÊD°‘Þ@£© "DÏò›b¬óòòuí ¿›üÁ[’=M"ÅÁ0zO þb?ºOÙþóíqâ«Þ±Wb®Å]о|ÿœ¡ó}_Nò¥³ì¿éÚ€&©ÏGeÿŒmоÅ_b~GùÀy—ÈVfi9êgú å~Ñ1鿉ç ·óóÅYþ*£yymei5åÔ‹ µ´m,ò¶Êˆ€³1öb¯¿5?55_;j®ˆïo [¹úiP6ÊÚ‘¿ä—ÙOÚfU"òŸ‘|Õæ»–ƒB°{¯Nž´Ä„†:ÿ<ŽUÿ&¼¿ÉÅYúÿÎ0þaD†ïLJú&i¹|¶‡‡ü6*ÀüÛù}æß)αëvr0Ü©BçÁdZ¯/òÇþN*ú‡þqGòÏUòÄ“ë:´³A{©Ûº_"#Ž ÊÊò§C9í_î“áûLüU}#Š»cžxÿxôßûi[ÄŽ*ÈñWÿÖô7”ÞÏ0ÛJOøŠâ¬v*ø‡þsNº·ü׎ñÁ6÷º|§ÃX‹# >+ð±ÿ_a“_˜¶^Hó÷Z…»Ía}¡;D’:0euŽCo‰kо¢ò÷æ’¼ÄiŵįömËúsïÿIÂOø\U‘b®Å_<ÎH~[zR4È¿w!Xõ˜Ôl®h±Ü³Ú9?Êàß¶ø«Ì¿+|û7’¼Õ¦Cɧʦ FÝ)W…·ª‚@çëÿûXªQæï3êgóî·|}w!e޵Xã$kþJ-}ÿ8ùùmúDÿj1qÕõhÇ Œ7†ÔÑ”{4Û;“é¯ób¯^Å_Ÿ˜«4ó/e±ò/—|Ýh¬öz”MøÜúw +ª7²J‹ÿü늯ü¢óüžLód7R¹ýyK}N1¸ôÉÚJ4-ñÿ«Í?o}•±ËKŽE ަ ©Øâ¯ÏìUö_äþJÍþ1Iÿ'äÅYÆ*ù—þr›þRý'þÙãþOÉŠ¡ÿçå?Ô?í“7ýDÛ⯨±VùÝÿ’³_ÿŒQÿÉøñWƘ«ë/úÿË?÷ýßý#·õÅ]ÿCùgþÿ»ÿ¤vþ¸«Âÿ:|ã¢ù·Î ªèí#Ú-¤P*Ûš3“±ÿXb¬Ïþq[þR sþa"ÿ“˜«Òç!¿òVj_ñ–ÛþO¦*ùGF¸†ÛX±¸™¸C ÄRHÔ&Š® 4=*úÛþWçå/ý_éÒóþ¨â®ÿ•ùùKÿWßút¼ÿª8«-òß™ô?2鋪h·?[±ghÖnGñ&Ì8ʨÛ«Š¾uÿœ¡Ó®¢ó®Ÿ~À›[«Ž'¦Üá•ù ù ¿Ùâ¬SòóÓÉi}BöÝ籺­n=*YÕà$¡MÖ¸«ê_.þcùÌAF“¬[Í3Ò–ÎÞ”õ=½)8H~…ÅY&*‡ÔãŸsÿŸþ"qWÀ˜«í?Éÿü–~]ÿ˜Eÿ‰Uò‡æFu§yûÌ· ‰üòÂ…’Y ‘¿û4ulUèß‘_œ_ò®›>¯+ÛÛMp×0j©‘Tº*²Ê«WýÅ•_} ¢yŸËºä^®©[_­*D+²ÿ¬ ò_öCLñWb®Å]Ѝ_ÞÚØXÜ_]¸ŠÖÖ7šyEHÔ³  Uð×›|ÅuæO2êÝÍD—Ó4Їö# iþÂ0©Š²>þYÜygÊ>WÖ™[ÔÕ a¨©éîLÑf07Í b©·ü㿜?ByÝt¹ßޏ¢Ø‚hÂ’`o¤–‹þz⯫ñW”ÿÎHëòé¿—âÆã&­r–ïCCè 2¿ÞQ¿É|Uóƒ£ÜëZ݆‘m´÷óÇo™/#ìµäqWÜ>Zòî—åÍ×GÓ"ZZ UþgoÚw=ÝÏÄÇDjz¾“¥[ ­Rö bÁ÷R¤)ÈÔ…äåW‘§LU$¹óÇåµÔb;Ÿ0hÓÆ®²*IyjÀ¼…]|Oò—|»æÏ,ê>Yó扨-.-ˆp(²!Ý$_ò]lUôüãæ'éM!¼§¨K[ý19iìÇy-A§ ú´Óþ1qÿ}¶*ù›}—ù#ÿ’³@ÿŒRÉù1Vqоeÿœ¦ÿ”¿Iÿ¶xÿ“òb¨ùÅßùOõûdÍÿQ6ø«ê,Uƒþwä¬×ÿãò~Ü£Fãæ¬Å^‹ùcùÝæ/-jözµÔš‡—Ý‚MÄÉ$M9Âæ­ðuô¾Ã“ö±WÕw²$šdòFÁ‘àvV‚ Å_b¯´ÿ'ÿòYùwþaþ$qT»ó?òwDóÂ-ØéúÜ)Â+å^Jê7 2TrÊÀó_ò—àÅ_=y—òCóAæï¦6¡j•ÿI°>¸ îP2õ£ÅXD3^XÝ a’K[¸át-ˆÃcB(ÊÃ}ùùÑ«jº¤^Vó$ßZšuoѺƒPH]c§öù(<$û|¾çÏáUïX«±Wb¯ ÿœ“óè¿(Å¡[¿½ié-:‹hHgùs~ þRú˜«À?.4MwΚ^Ÿ{$qX„·¯+*§£æêKmñ…ôÇúØ«ê/Ío/ùŸÈÚž•¡h×b?^Ä £¯¯Æ€|_·OOýž*øò æ‚hç…ÌsDÁã‘M ²š‚ˆ8«íÿ ù¦4ùGMÖÒ‚K˜€¹Aû3§Á*ü¹ƒÇüœUå_ó•qÊt/È+é-Äêþ™¯à­Š¼—òjh"üÏòóÍNä ­>ÛÆÈËeÅ_gâ¯&ÿœ™ÿÉsý´ ÿˆIоUÅ^—ÿ8Ýÿ“·Êßñžoú†—~„â®Å]Š»ÿÐô7”ÞÏ0ÛJOøŠâ¬v*ó_Í1i>]z¾«0†ÊÚ$.z³²¢Úw;(ÅR_.ù“Eó—§£Ý%Õ¤£í)ø‘©R޽Q׺¶*Å;tï,Üþ_j—ÚD%¶ÛMÀ-ѺHÛí~ñ«¨ýµŠ¾9Å_yym.S˺Z]Wë+gž½yˆ”7ü6*˜â¯“ç#ÿòfOÿ0–ÿñвŸùÅ?øèyþ1ZÿÄ¥Å_Dâ®Å_Ÿ˜«ì¿Éü•šüb“þOÉŠ±ŸùÈ˿ӺóŸ-WHBgU¶ƒâaþ´;È¿äzŸä⯛<»¯j>_Öìõ9ý;Ë)‘žÄtdjuGRQÿÉlU-Å_eþHÿä¬Ð?ãŸò~LUœb¯™ç)¿å/Òíž?äü˜ªþqwþSýCþÙ3ÔM¾*ú‹`ÿßù+5ÿøÅüŸ|iŠ¿@ñWb¯•ç&òcEÿlø?ä个qÿ8­ÿ)¹ÿ0‘ÉÌUé?óßù+5/øËmÿ'Ó|«åßùH4Ïù‹ƒþN.*ûÏv*ìU¯kº^ƒ¤ÜêÚ¤âÞÊÕ9Ë!ÜøQûLÇáUý¦ÅT<±æÌÚTZžr·6ÒÈ9ÆÄT¤‹Õ”â©ç囿 êÒëÉ[{yÊwÔKž'Ñô›írgâ¼GÛû-ð⯌qWÜ^[K”ü½Ò’ê¿Y]&=zóÊþ|;оÓüŸÿÉgåßù„_ø‘ÅQþmóç–<¦¶m­Ýý_ëÒˆ`P 7ùR0ˆã¯Æøªykumwoͬ©=¼Ê)£`èÊwXTм;þr‡NòÊi}ñH£ó—,¶ÁŸ©O´¨þŸo³öWí6*ñŸË¹Ì_-‹zúƒQ¶-OäY“þI†Å_nb®Å]о0üßó‡ø«Ïw÷Ñ?; cõ; ê=I‡´Ž^_öx«ŽÎîT:Œ¨Ä}àb«¿GjòË/üLUNX'„4m;€êV¿~*÷/ùÆ8z÷•.‘Þy` ÿwF J£ýx¿üòlU韞žT›Ì—׉j†KÝ5ÖþÝ©oH"Žõ1;ñ´ÜqWÈvwwwp]Û9ŠæÞE–ªº0eaò#}ùiù¥¡yÓKˆ¤ÑÛëh€^é¬B¸p>'ˆWˆõ ¿göñVmмgþrŽîÔy+N´3Gõ¶Ô£•mùPƶó«8Jòâ”ÿ+yoüãwþNß+Æy¿ê\UúŠ»Cßj6v)ÝIé¬Ò,1š3VGÙGÂ\UŠ¿ÿÑôg–-.­îõ¶ž&g¿’HK rBxŒU=Å]о+ÿœº_Ì)¼æ_U¶áåkp£I’سÂy(çj7 Ó‹Ž*¿ <þ7u^¦ë¶—1ŸL½¸±œìe¶•áz¬…N*»T×u½YÖMWP¹Ô>ÃÝM$Ä|Œ…±W þN~Qê~iÕíµMFÝ¡òݬ‹,²J¤ ’†¢(ÁûjÄRGû*¿å⯭1Wb¯“ç#ÿòfOÿ0–ÿñвŸùÅ?øèyþ1ZÿÄ¥Å_Dâ®Å_Ÿ˜«ì¿Éü•šüb“þOÉŠ³vPÀ« ©ØƒÐŒUñ÷çWåéòšÜÚÇÇEÔËO§>ß÷ÿÏ&?üVÉŠ¼û}—ù#ÿ’³@ÿŒRÉù1Vqоeÿœ¦ÿ”¿Iÿ¶xÿ“òb¨ùÅßùOõûdÍÿQ6ø«ê,Uƒþwä¬×ÿãò~¦8+µZ€ ÑŠ¾bü×O=7›®n<áC{)"߈?WôTü+nße¢ð\¿¼ýç,Ué~fó&“G¥jך|ljÉkq, Ÿq.*„»½¾¿¹3ÞO-ÝËÐ4³;HíáVbXâ¯ÿœü¤Ô¬/—ÍÚõ»[H¨Ë¥YÊ Ê ƒ‹Nê~ÇÀYcVø¾.ÉÉW¾b®ÅXçW›ÿÃ>B¾–㨩Yo¸iãþ1ÅÍ«üü1WǶÖÓÝ\Åmn†K‰Ýb†5êÎ犨ù“оæòw—mü·å7D‚…l Tw·!ø¥örlU8Å^Aÿ9)å/ÒžP‡\‚>WZ,•”ަÚj+üø8¿É_S|ÙåÝróA×lu›3þ‘a2LŠMq;¡§ìºÕüœU÷>‘ªYêÚU¦§füíoaIánüdP´î+ñb¯Ÿ7¿!/Ἰ×ü£nn,æc%Ö‘þò&=Zn6?î¥ø£ýŽIöxq·<ฅ½ÑÑÔýXU8|óÀ‹ÑbÔÄ4§¦/.8Óœ銤ÓÏ=Ä­4ò4³9«ÈìY‰ñ$îqW°Î1y7ÍŸšš·›1Ò,^i®oÙxBÀñü,üD‡›ªñ“b¯¼1Wb¬sÏï›ÿm+oø‘ÅY*ÿÿÒõN*ìUتÿBÒoË›ÛdŸÔ^¤2Ò”"´#a§üã¿ä¶§!’çʶ¨Í¹ú³Ïj>ëy"ª¦“ÿ8ýù7¤È²YùZÐÈŸa® ·$ô‡—|U—¯–´5P«hªª(ª ì7Å[ÿh¿òÊ¿{\UßáÍþYWïo능—åwåΩtnõ?-é÷×D3ÜÛÇ4…W æášƒUÒ.|‡£´¤h6ZsL™­!X …­zayR»WL¿Ãš/ü²¯Þß×wøsEÿ–UûÛúâ¬{þTÏå/ýIúGý!Ãÿ4â©Í“¼¯akŽ› ¥¤@ˆ­à_N4Ô…E¢®ç¶*ˆÿh¿òÊ¿{\UªùÉz¼)­£ZêÆÜãŠê1:«Rœ‚Éȡ능Ÿò¦)êOÒ?éù§Nl|å{ XììtØm-"Eoúq &¤*-w=±TGøsEÿ–UûÛúâ©^«ùiù«Ì“êÞ_±Ô&xG-Ô ;*Ö¼CH…©éе¥þY~^é s¥yvÃO¸t1¼Ö°$.PÅKFñª©ãþN*šÿ‡4_ùe_½¿®*‡¾òw•ïíd³¾Óa»´”-¼ëêFà€ÈÕVÜwÅRoùS?”¿õ'éô‡üÓŠ²ðæ‹ÿ,«÷·õÅ]þÑå•~öþ¸ªS©þX~]ê·"ëTòæŸr žêÝ&~"¤/' ÜEzb«ô¯Ëo éI&“ XéÒJÊö¤ Ê @cZŒU¨ù'Êz«Yê:U½í£^Þá}XÉSPJ?%4;â©Gü©ŸÊ_ú“ôúC‡þiÅ]ÿ*gò—þ¤ý#þáÿšqWÊ™ü¥ÿ©?Hÿ¤8æœU¥~Z~_é<úO—ìtù¤^Kk@̵¯Ñ…%j:b©“ùgB‘ÍebÄv ‚qVªÿÎ<þLjŽ^ëʶªÍÔÛ4Ö¾ÿñîñb­é_óŸ“:T‹%§•­K¡ªµÃMtA­kþòòÎ…*%š*( ª¥€lâ­·–´6R­h¬¬(ÊKAìwÅXÿü©ŸÊ_ú“ôúC‡þiÅS«?(yfÊÖ;K-:kXG „ãEðTRGËY¨ù'Êz•«Zj:\–¯»Ap¾¬dzŒU†ÞÎ4þGÝËêKåx•M!¸»wÿ&)‘ U9п&+t)DÚW–ìí®Õ.8³Ê»×á’BÎ>†ÅYøsEÿ–UûÛúâ®ÿh¿òÊ¿{\UßáÍþYWïo능ú·åï‘õ…u}ÏQXI0­ÜK8BÔ©_S—Ó¶*ƒ¶ü¢ü®µ¸Šæ×Êš\0°’ⵉMU••C+ÐŒU<ÿh¿òÊ¿{\UßáÍþYWïo늩\ùOË—VòÛ]XE=´Êcš AttaFVV%YHê*‘ÿÊ™ü¥ÿ©?Hÿ¤8æœU9±òw•ì-c³±Óa´´ˆ¼ 鯀š¨´UÜöÅQáÍþYWïo늤ºïåG导yk_³½’”JŸ½v$ðX«?󌑆oXùa9Ô »à›'áÿ ЧZWäå.”Áì¼­`’.ë+Æep}žRì>üU•Ùèúmœž¥´'§‚zxnqTf*ìUŽyãýãÓí¥mÿ8«#Å_ÿÓõ,76Ó4‹ ©#DÅ%ÁŠ8ê­O²ÞÇTÅ]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*Ç<ñþñé¿öÒ¶ÿ‰U‘â¯ÿÔîÚ¿£iºŽ»õÜvò>¡#*¹5+@+øb©ÏøÓÊ¿õr‡ï?ÓwøÓÊ¿õr‡ï?ÓGéÚ¾›©#½…Â\$g‹²v'|UŠ u-sIÓ5¿ºKs(&0õÜ´ûñTøÓÊ¿õr‡ï?ÓwøÓÊ¿õr‡ï?ÓwøÓÊ¿õr‡ï?ÓDXy“B¿¸öw±Ï9„jMh:öÅS,UFööÖÊÙî®åÛÇNr7AÈ…‰ÅR¿ñ§•êåÞ¦*ïñ§•êåÞ¦*ïñ§•êåÞ¦*ÚyÇË:¢j0³¹ ª ܇lU9Å]Ф¿ãO*ÿÕʼÿLUßãO*ÿÕʼÿLUßãO*ÿÕʼÿLUßãO*ÿÕʼÿLU5µº·º·K‹wÁ(å‹ÐŒUWJï|Ï Y\½­ÝôpÜGNq±5€aÛÀâª?ãO*ÿÕʼÿLUßãO*ÿÕʼÿLUßãO*ÿÕʼÿLU§jún¤Žö p‘ž.ÉØñT^*‚Ôµ­+Lôþ¿r–þ·/OŸíq¥iòä1TøÓÊ¿õr‡ï?ÓwøÓÊ¿õr‡ï?ÓwøÓÊ¿õr‡ï?ÓDXy“B¿¸öw±Ï9„jMh:öÅS,UFööÖÊÙî®åÛÇNr7AÈ…‰ÅR¿ñ§•êåÞ¦*ïñ§•êåÞ¦*ïñ§•êåÞ¦*ÚyÇË:¢j0³¹ ª ܇lU9Å]Ф¿ãO*ÿÕʼÿLUßãO*ÿÕʼÿLUßãO*ÿÕʼÿLUßãO*ÿÕʼÿLU5µº·º·K‹wÁ(å‹ÐŒUWJï|Ï Y\½­ÝôpÜGNq±5€aÛÀâª?ãO*ÿÕʼÿLUßãO*ÿÕʼÿLUßãO*ÿÕʼÿLU§jún¤Žö p‘ž.ÉØñT^*‚Ôµ­+Lôþ¿r–þ·/OŸíq¥iòä1TøÓÊ¿õr‡ï?ÓwøÓÊ¿õr‡ï?ÓwøÓÊ¿õr‡ï?ÓDXy“B¿¸öw±Ï9„jMh:öÅS,UŽùÙY¬ôî šj6ÄÓ}¹U‘b¯ÿÕõéöÅÞÚ&f5f(¤“îHÅZý§Ë,?ò-¦*ïѺwü²Ãÿ"×úbªÛÛ†$ˆÈE _»TÅTæµ¶œƒ4))_³ÍCR¾ÅTÿFéßòËü‹_銻ônÿ,°ÿȵþ˜«¿FéßòËü‹_銮ŠÊÎ'çÆý9**Ÿ¼ U[[$QÊ…$@èz«A¦ý*£ú7Nÿ–XäZÿLUߣtïùe‡þE¯ôÅ]ú7Nÿ–XäZÿLUÃNÓÁZÂÜÿLUŠ»CþÓ¿å–ù¿ÓwèÝ;þYaÿ‘ký1W~Ó¿å–ù¿ÓwèÝ;þYaÿ‘ký1UtD"„EØ*Šô U¼UFK)\¼–ñ»ž¬È¤šmÔŒUoèÝ;þYaÿ‘ký1W~Ó¿å–ù¿ÓwèÝ;þYaÿ‘ký1UHmíáCDä"…¯ÝŠªbªs[[OOZ$—xóPÔ¯ZWSý§Ë,?ò-¦*ïѺwü²Ãÿ"×úb®ý§Ë,?ò-¦*º++8ŸœPGô䨪~ð1UlUl‘G*‘¡ê¬›ô8ªèÝ;þYaÿ‘ký1W~Ó¿å–ù¿ÓwèÝ;þYaÿ‘ký1W ;Ok#pDký1TF*ìUú7Nÿ–XäZÿLUߣtïùe‡þE¯ôÅ]ú7Nÿ–XäZÿLUߣtïùe‡þE¯ôÅUÑ4Š`ª(Ð1VñU,l¥rò[Æîz³"’i·R1U¿£tïùe‡þE¯ôÅ]ú7Nÿ–XäZÿLUߣtïùe‡þE¯ôÅU!··„ I;Š¿v*©Š©Ímm==h’^5ãÍCR½i\UOônÿ,°ÿȵþ˜«¿FéßòËü‹_銻ônÿ,°ÿȵþ˜ªè¬¬â~qAoÓ’¢©ûÀÅU±Wb®Å_ÿÖõN*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb©µço/hÞ`Ñt ùÙ5O04ɦ@‘»ó6áZBÌ ˆÀ7|U=Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUتEªyÛËÚgš4+ÝÎË­k‹3éÖë¸u·BòeP*‚~_Ýâ©güägæ/›tKKo/ù"F‹ÌR[\k:…Ê*9¶Ó,QšG!Ã/ï\p]¿a“ö×zo’¼Ã»ä­_gj÷s1 gˆ4€öø[8«Ç!ó¯æ˜ÿ/2<ý¥êÓYé´£ÉЬqÒ;M4†žärB_ë+¯Æ_ÓoWzÇ埘fóå×—u˹=K«Ý:Þ[ÉH þ˜5:ÞÅ^Gä?Î/6ëÿ° ‰Z?!y’=BÛÊÐ2 I[MãÊä7R²zRìÏþìãû8«Ð?<¼íªùcÉÉ€ÔóV¿u• ª€Íõ‹†¡p¤7÷iË~<}Fcëæ8èžÞVò†¡¬Ë¨èú¶‚ÜıÆ=MBÙdi¦ªª]açÄ«"üëóž³åÿ,A§ùoâów˜îSKÐJË)øæ½,|G›¹É¬rMýç¡ÀªÿÅŠ­ü¿×<ûå_Íéÿ-<Ñ­7™4ëÍ3ô®‹©ÎŠ·(ªå JA$×Ó˜LÿaxóeÅROùÊ]Ï^T×5Ôó”©åËÆµµÊ‹eÌÆŽ ß?Sâeyÿ»ÿбVmùuùeù“å»Í%õ_?˪hš}¸€ùôt'Š8ýu’GãâƒãôñW›ÜêÞsÔ?ç&üáiä¸aý*tûm7ô½Ðçoal±Ã-Ä̃ûÉ}`±Ãí?Ûødwòæç•|·©y¿KüÊÔ5KH‚Kû›+Èb[9¢}I•a£÷jÅW‹'ÃË–*õËß57š|‹¢yŽhÖ u+8î.#a$+IÔŸƒ˜n5ýœUç6þdüÄüÖÔ¯“5Uò¯¬&{U×Öž÷R–3Gke’‰º·Â$ ÏýŽ(•J|á¡þq~Vé­æý#Î^mÒ4ò²kZ.®™­êɵf^=O>ßï”x«=üÁüÙ³òçå)óí„?Y–¶Ói0IPïB˜}JPñ@üäZþÇU‹EùQù˪i‹ªê?™—¶^c™=e²²‰N…Èä°ðR¾ª/Ù2qÿbÿ¶«Ð¿-OŸÿ‹çÅ·_1§%íX0tàyÊGÛX¹GûKö¸"¬_ò?ÍžaóMÇõJñ®tÛo0]iú,EQDVöô`£ˆ j²ÇRØ«ÓuÌ/Íß0kï£ùšO)ù/A¾—K·z+_]Ü@y^V ÅĬœe¸påñ⬗È^YüâòלçÓõmy|Ïäy-½Hu î)} ÅH¨^O'OÔoOƒr‹«ÆÊ½CcÞ~óÆ‹ä+^y‹WcõkPp%=I¦sH⌮íÿ¼¾Å^o§yCó¿ÏãXóšæò]¥ÐXùwG‰DÐÆÛ¯ÖnŒž­)Í>/ùåýÞ*žy Ë¿œ~[ó\šfµ®Eæ%¼àÔ®À‹P†jü1ÑC¿Êi]÷L«Ì-5O;êßó‘ž~¶òZC£4v¶3k—J%ƒOµ¶Ž4Äîéä™A|<¹óøáU?óç’?6ü•å«ï9i?˜ú†©}¤'Öîôûø£ú¤Ñ% ¡c«$& Çü•dozGü¬Cÿ*üõaê~…ý+õ:ž>¯ÕýONµ¯Sáåü¸«ÿÑõN*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»x–½=¯–ÿç(´ÝV᎖½å«˜ngr†²f¹‘‰=a·ŒœUùI¡Ÿ7¯š?0õ¸˜ÿŒýK&  :\¡‰)û-qOROæâ’~Þ*óÍ Î:ÅüãÌ~F±~~n¹Õî¼™h ÊÏ1i\Ò¥V+i¸sÝü о€Ó<‘¥é¾@Évš|zsi¥ºŽIŸµ!fwÿ)±WϾNón«'üãÖƒä=&OKÍšþ¡wåÈ:†]¥¼¸Ÿ³ok7añ/%|U™þpy{NòF‘ùi«éiéYy7X´³v?hXÝ(Šá˜ÿ4žšs?´ïËL,óßçíÖ yåÿ˘ •§t“W»¿aQCèF=7±"Fت—çœcNüÄüªó58¬ÑÒç“jqÔ å_å !ÿ‚ÅQ^P_ñßæþ¯çGoW@ò‡©¡yoùñ€ý!t¿*ý]\|2Gþ¦*Äü¿ç8,¢üãÓäâFÔÆ©£ÚŸÚ}eÕâQ½P8‡—ò¯&þlUê’ÞJŸÊ—Ú}…í[Y¼å¨ëR¿Û{Ûª<¼ÎÕdb¯üWгœUã¿óWúV¥{ª~[ùÆûÊM)¹›L ·6 #,D QáËÖãöWáøqTwäÿŸ<÷yæ¿3y Ï?Vº×|¶ ”j¶KÂ9â¹PëÍUÅãeà‰ö¸²rOT«óÃ?ó‘¾Dó(ø-<Ém>{MÁSâòMÿžXª¦ˆ¿ò³?:®¼ÀçÖò‡¬t~ñÏ«µ óŽÍè…Õ‚Dý¬U¿ùÊŽ‹äÿ+ÿÔÁæKYWz¾%`wµ$x«ÚUT*€ª¢Š£`ì1WŒÙ«ÎXj3Tò÷–b¶ä;Kq2Ê íÞ;‰1WÎK§ÁäO,¯]kÌÖK ñ†>JõØì ¨Äÿ“нŸx¯üã¬I¨kŸ™^j§&ÔüÉqi‡¯£iVŒTšý›Š²ÿÏmPi¿“Þm¸&‚M:k]ünÀ¶û÷HÒóAÿœ^x-¹GwmåFv*$‘ìùÊGqijŸòqVùUùOçKïËŸ/^èŸ™š†›¦ÝYÇ4Z}½¬M'Å,j}O‹„ÆE-ö¹b©þ¯ùçÝKN¸ÓuOÍ]J{ Ô6÷òÚÅÆEP¡ýèûX«:“ò¿Ë—–vŸ—Ú°kÍ*ÞÊ &˜~îRöê¼gMÛÓ“šz |Kûb¯8Ô?+ÿ8|‡£Ïyä?ͨiº\-,z· L 0!oI'<øü#Š*$ þZ®*ô/Ë¿ÌFóGå]îí–Ñ嵸žê'€{G’9 דf…+ɸ6*Åÿç,%ƒòsO½š¾¶«uy{)"„“;EÊŸåyb«u¿ùÇùbó¡æ? ù²ÿÊŽ©!¸½¶„ ‹e$±chþÓo‰¤TäÞšqø1W~Uùßó?Ì=còÛÏrÚêzŽ›bºž·f‚!,ãN2 ¼Ï¬´ãqá'Ûø{*ñOùÈy o4þWZj Mo0Æ÷Ç˜Ä<ê@§Ç ßöyâ¯kÅ]мWþqš$¾‡Ï^j"³k¾e¼!û˜!!â&¼U§”*þÎ*Éç"5A¦þKùªrw–Õm@ñ7R¤ýùŠ®ÿ ùPá®Öÿ }S }o¨ñ­:×Ôø©Š¿ÿÒõN*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»ygçoäÅ׿=Ç—åµÔÆ”ÚSÜÅw(V2Iiz©ñ¡SÔÆŒ¿Ãñâ¯KÓ´û=7O¶ÓìbX,ìâH-¡_²‘Æ¡QGúª1W–ywò!tÏÎMOÏ—ëq§M-Åî—¥aè^Þ¢%Äí_€– ø~/îÿ“zÞ*òOËÈ…ò§æ½æË»ä½Šîâêm ÅU‚Ù­ô¥æ?§¨cXá䟱Ïf?š^Hxò­åYmä¿= ‡R˱H²£7§$ÞŸ³Š¨þT~_#yB-[Ÿ¯êsM-æ­¨šò¹º¹<„·Ä~ ñ|_*…üåüº½ó÷”cÒ4ûåÓu[Ø/ì¯\1Ë!Èp£âíÄâ©×<›aäß'éž[²ø£°„,³R†Y›âšSï$ŒÏÿ аO8þD/™?7tÏ:K~©£@¶ÒjšG­ÍÅ‘‘­Ùˆø(ƒ+¯ÙGþ|U—~iùgÍžeòuΑåmhè:¬ÒFEð.‡ÒV«Æ$‹÷‘ò´Ÿê}—ÅWßyõoË‘äíkUº¹š[¬¯5ˆœÅs$¨Šjƒûn¼™¿¨¿¾§&Å^w£ùþrW˺|z“æÍÿG¶Q –¡¨Á?×b…G7à>Ï«,¿ëqÅYÇååœ^L·Ônï5 5¯3k“ sZ™B4Ò-x" $G|›‚Wö¿—Š"¬þr¶½òŸ—´Ë |Õw­Û‡#„ÒS:†V`ÃtDõ³þËúX«Ò.<‘aäŸ&iž\³£}N!õ©Àþúåþ)¥5ßãž5û)ÅgJ¼õùuyæ;y+]qÃaåk›‹»‹VR^i$ú\HÙ}6‹¿ób¬ë`¾Pü»½Ñ1|åç Û¸®[Ì­h¶‘"°h!µŒÇÅËËô¾Ïòb¨?ÎOËMwÎ1è:——5(tß1ùjóëÚl—H^ݘñªÉ@äoðåãñb©×í?3`·½“Ï7ÚeÝÜ¥>¥•©ACsäò#—%{|Ïôèæ‰^ËÑú»@À1qáÀŽ„ÛxÖùKù·äInlÿ-<Ëa'–§•æ·Ñ5øåeµ2°ŠhVI ×ýEþegå#*™éŸ”žw×uë oó3Ì˪&•2]iº”kaÄg’K#|2ÎPýŽkËü¾“Mÿ6+õ_7¾“«hôú™4m6à’Ù‹Ž$I xò¥WÔ ß¼r$‰öUc7ÞAÿœ„óM‹è^jó^‘§h7 bÔ%Ñ`•¯.aaGŒ™’4‹Ô_´cÿtø1W j>G·‡òÚóÉ^])§ÀúdÚe„É„BXZ/Q©Ffø¹³}¦‹Cùoòî 7ò¶ÓÈ—WRpOúÍå›´sp}I"añ)æÅ–¿ìùb¯?п.ÿç"|¡`º–üÕ¢ê>_·„º¼­Õ¼#eD$ŠÜ?dI#/û‡fŸ––ùVëS×u½Qõÿ8k¥««È‚%á¢C k´q'·Ûø~àˆªµkä=/æõß›.|Ï#ùQ­Dž[Bâ5MTóB}-¤7¬?}ñzÝâ©·æ?åî‡çï+Í jüф֗QKop€„•+µG&VSö‘™qVgå?ùÉÝ.Ýt«O6èZ„kéÅ«jó õ@( DGŠG2É#7í»b¬ÇÈ@Õü­¥jfûÌ7z÷˜5w7š…Û ÏÂú0Ë (â>ÙEý”DUZüœü½—òÿÈV^[¸¹K˨$ž[‹˜”ª;K+2Ð6ûGÁqUŸœŸ—×þòiòå¥äv+5Ô]K*³†.È‘ñãLU›úqú~ŸéÓ É&[Ž—‚”P)¢; %ü?d ^’xIâ%ˆ—d ^’xI⥶¥ÑÓ½ãCTÝf®¢kÄqÿì>ý­¥0¦‡@À±.üXû»‡´‰AŸÞ±=ºD8® • ç·Å˜ËSêüðvCÕ(%”?ÜËÿv)Œ0 ŠÃÚr@›¸–ÍT—0T‘~G˜íBaÄí<„B( !àº2ü–Q•€ `¨Z[iÛ: Às©"#ÂoÉ À ¶m;ŽÓ–CÚ4¡Œ1B(Dø¹ÀFÀUUMh“Ïs*^’xIâ%ˆ—d ^’xIâ%ˆ—d ^’xIâ%ˆ—d ^’xIâ%ˆ—d ^’xIâ%ˆ—d ^’xIâ%ˆ—d ^’xIâ%ˆ—d ^’xIâ%ˆ—d ^’xIâ%ˆ—d ^’xIâ%ˆ—d ^’xIâ%ˆ—d ^’xIâ%ˆ—d ^’xIâ%ˆ—d ^’xIâ%ˆ—d ^’xIâ%ˆ—d ^’xIâ%ˆ—d ^’xIâ%ˆ—d ^’xIâÕŽã´åiŒ1|u]߀mÛ¸bÇÄǯÎ?¢ ¸oØžÿ„ïÇá-ƒÏÙ‰j7Çq(¥Š¢`·8>އŸo‡RUà¯xà£ëºØÉà9ÅÇGîBcØÆ²,×u)¥Ðú`Ê@ `Y!„Rl7ئsÕnŠ¢0ÆLÓ좢(¶my(ŠB‚lzÊŸÿÀG¼:´ZRçÛ¶#""’’’úôé£ë:PJ-ËâãéÜü_"„ {–––ææfJill,¥”¯HJ)wPŽãà ÐuÝëõ¶´´PJ{÷îmšæÍ›7ãããÑtâ@ÚÍ@Q”æææˆˆˆ»wïnݺu÷îÝÕÕÕÜÌy›ÐÐÐaÆåääLž<9<<\Ó4à>ƒJgá7ºŠ«RªªªëºW®\;v,¥tÕªUsæÌA@@×uœSnï¶m뺞——wàÀQ£F}ùå—ß|óÍܹs?þøãI“&¯›?®Ž¬ƒˆˆ¯×»xñâ;v@«3E‹Ãå¯(ʯ¿þúõ×_—––644,X° ** Zý!ä/ˆÜTy^@ñz½PPPðòË/GGGcÿ¹Qó•ªëzyyyaa!!äöíÛ”R¿ßãÆ 4¦Nˆ8¤}ûö!°,kÆŒÅÅŇ:|øðêÕ«SRRø¨Þ}÷ÝS§Naèã]ÿ <®K ]ПFFÆñãÇ> (Zà+Û¶ÿñÄÅÅõïßO†C°m»s£ZG|c¬¤¤DQô§¯¾úê_|¿Z–5bĈìììÌÌ̆†¶}ûö°°0˲lÛVUuРAQQQ<}¢”ÖÕÕ]ºtÉ0 ÆXRRR ¨­­UUUQ”¬¬,Ó4/\¸PYYùóÏ?wéÒ¥OŸ>Œ÷ûý¯ë8ÎÍ›7:tïÞ½ëׯ;Ž–œœÜ·oߌŒ ]×¹ës]wæÌ™¶m/_¾|̘1š¦á@xÂöqôèÑâââÏ>ûl×®]~¿ßu]L@0’wnXîÈšr]÷—_~]×Ç1MÓçó…„„¸®‹Kµoß¾………MMM˜bGGGïß¿ݺuxø¶mÛæÍ›­YŠßïŸ7o^yy9†îªªª¯¾újõêÕ]TTôÑG•””ð@¢(JŸ>}Ö®]›Pïܹ³fÍšuëÖiš†É Zë3Ï<³uëÖ””tâ”Ò¸¸¸üüü1cÆìÛ·oöìÙØm<ÆØ† G޹sçÎà|ïÏXÁa@)MII)++3MSUÕÝ»wß¹sçÙgŸMHHxì±Çúõë×½{÷¬¬,´SÌG{öì‰ EY¿~ýÔ©SCCCÑ \¼xñøñãÕ§M›6`À€àÎÈëõΚ5«®®ZÎìõë×óòò’’’žxâ ŸÏ7þüýû÷€iš”Ò°°0EQ¼^/æ6§OŸž4iÒ®]»† bš¦ã8>Ÿo̘1ÉÉÉ7nÌÎÎ6 CQtY¸Ž=ZZZúÉ'ŸÄÆÆZ–å8ßåà t.‰Žì“`öìÙ½{÷Û¶ !eee«V­ÊÍÍ:thrrrZZÚôéÓóóó8à÷û)¥IIIo¾ù&²¦¦¦¼¼}¥tçÎÜ_{í5àöèóùêêê²²²¶lÙ²wïÞüüüÈÈHÜ666–––Ú¶½bÅ @)Y\\¼téÒS§Nùý~œPÛ¶Eijjjnn¾xñ"躞‘‘±~ýúΚ5kË–- Fíºî­[·öìÙ¶m=:==4Mã9åÈ‘#qš4M³,«gÏž¹¹¹8 ÍÍÍÛ¶mÃŽuíÚuóæÍƒÆXïÞ½SSS¯_¿~äÈ˲***®^½Š¶Œ»–qãÆ=ÿüók×®2eJHHˆeYš¦©ªZ^^~îܹ‚‚‚ˆˆɹáót'.…ŽÔ*¥4--íàÁƒG-,,\¶lYNNNRRRxx8oi†išeee¹¹¹MMM©©©Ó¦MÃÅ^RRRUU¥ªê¾}ûÑM¿ÿþûh§ý Ãp'//àÖé…^À6À»qãÆ½{÷°®0lØ0„ôK555W¯^­®®ŽÇ¹Ãꪪ‹/®®®Þ³gªªÉ|ø•W^ñù|+W®0`ÀôéÓùx9ƒà¼Hp­ë0~ø¡ã8º®›¦yðàÁ§Ÿ~:66‹w8<¯×Ë(ŠÒ­[7LnnîÎ;ïß¿_WW—››‹ç2dÈøñãyUU×u´èà +/bî–eõë×/..®¡¡ÁuÝ'N”——gff¬Ê½þúëçϟdzýðÃÈØ², 0a„ôôô+VŒ;öرc§OŸ.**òx<Áµ¦à”‰GˆG0`^gÛ6híßrµûE‰ŠŠZ¸p!˜¦©iÚ¥K—^zé¥;vTVVÖÖÖ^¹reíÚµ|ð¶gŒõêÕ+##ç.%%eâĉ®ëâ½Øœ9s µìŠ•p¹ÏçÃ=ÿk8)Œ±°°°œœƘÇãiiiY°`Á¦M›|>_KKË·ß~;yòd (ÊÌ™3cccÑkáÕ±{¡¡¡ .¼|ùòš5kÖ¯_Ÿžž>jÔ(x¸ômš&‰ Ã@x¥MÓÄóàÂå{òöªƒûƒ·ß~»¢¢âرcX„¨¨¨˜={vxx8º¿ßÏ`¬W¯^ØWMÓæÌ™STTäóù°²Ý¯_¿)S¦`Ä£‚Ý:‚Â#„`ÖûÞ{ïUTT OûþûïóòòòóóCBBêëëMÓÄyŒ‰‰yë­·pGé8ŽÇãAçÆ7%›6mZ¹r%!¤°°044”/œ\<ægÏž5 í »­µÛ¶GŒí÷QaÀ‹ß¾}ûÖ­[?ÿüó;wî躎[*Ã0Ð_£ýfff.Z´ÓPì( >|äÈ‘EEEØû¹sçvïÞZ—3´ºÓ4£¢¢0—çLÓìÖ­[cc#îª!QQQ7nܶm[ss3–Ø8BÃ0FŒ±téÒAƒáù5MÃ;&c¸I^¸pá™3g233srr‚»Šö…YV8ÐCë†Ð'ÇÄÄ|÷ÝwQ=£Û;ŸdËñÒßm4婌]º AvjšfSSSUUUmm-zÛ¶ ÈŒŒìÞ½{ÿþýSSSqHÁÅêŸ~úiâĉgΜÑu=::úôéÓqqq8)ØàÚµkwïÞUÅçó 4(44Zc£ëº'OžìÒ¥ DFF&$$`$gŒ]½zµ²²²¾¾¾¥¥7111‰‰‰Äí:!¤¹¹¹ªª*999** ïÕ`ÑÔ4ÍÊÊÊ®]»&&&â÷˜V)ŠR[[{ÿþýÔÔT¯×[]]m&c¸:yµ&44Ôçó 2„©Tc€?ýÚ\üÝÉÎgÇ"ì(ÚŸDì%Ÿz|­¯¯¯¯¯wg×®]6lÀ–o¼ñ¾.Àñûì<üâªç>š»#Jip¢òŸ·¯¡õ7Z6ý=¿oÛa‘Û ¯ñ‹ò°Œ=q]ã?¿:!ÄÖ^É‹ÐôpÖøX¼I“BhM!0M€'NL:5xŽbbbæÏŸGy<¼)ýÈÝ0§‹¤¹wbŒÜ â¬Ùw†{mžÅ—}¸çá=7)~,æ'ÐTUE»áç±,ë¯È‹c<æÜ-òB<´¥Wkp\Ål5!!aåÊ•)))¸ñ† ¿,ð” Å<÷€VÒtïƒaXRÆz^‚ß´À3óEƒã}æ·0Gðx-ûßÎü‘ y(@Æ\ŠÒ¶©M \Æ\` aí.ÛRò¯îcýëŸÈ¿ºªs†öÈ _!FhÛî¶µiÀ.Ä!ÄQÚü²‡ÿg÷¯º.àá?jüÝ ´¯º×¦uÐÔÒlY–J…æ´ïV*O-8 œk^²ç  úKáßWÁ»¿æûÞ¶Ò&ÇþYõÇ:&õ[úoXûwIâ%ˆ—d ^’xIâ%ˆ—d ^’xIâ%ˆ×ÿ3 ïÉH8öIEND®B`‚^ÜDdÆ*‰+ðj² ð C ðFAÁ.ÿsysync_diagram_big.jpgð€Rð ÛTª(†D»NCTœZÌ2ÿ|Û˧- FðtÛTª(†D»NCTœZÌ2ÿÿØÿàJFIFddÿìDuckyGÿîAdobedÀÿÛ„   ÿÀçÚÿÄ¢  s!1AQa"q2‘¡±B#ÁRÑá3bð$r‚ñ%C4S’¢²csÂ5D'“£³6TdtÃÒâ&ƒ „”EF¤´VÓU(òãóÄÔäôeu…•¥µÅÕåõfv†–¦¶ÆÖæö7GWgw‡—§·Ç×ç÷8HXhxˆ˜¨¸ÈØèø)9IYiy‰™©¹ÉÙéù*:JZjzŠšªºÊÚêúm!1AQa"q‘2¡±ðÁÑá#BRbrñ3$4C‚’S%¢c²ÂsÒ5âDƒT“ &6E'dtU7ò£³Ã()Óã󄔤´ÄÔäôeu…•¥µÅÕåõFVfv†–¦¶ÆÖæöGWgw‡—§·Ç×ç÷8HXhxˆ˜¨¸ÈØèø9IYiy‰™©¹ÉÙéù*:JZjzŠšªºÊÚêúÿÚ ?÷ö*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š¥ú–»¢hñúº¾¥k§Å¿Çwq ·]ä`2“¨Æ šh°½Oóçò_H¨½óÞ‹É~ÒA ËÀ¡HÛ¿†?˜ŸÈþ¤ð–'ÿ9{ÿ8ûaÉÅŸYnÛOÔ%®ôÙ½Ÿ{câž‘?gé!xXåßüçä}¹"ÕîèH<( ~×ï¥Mßí‰/柳õ¯ Mqÿ9õùMqo¡y†gRBo`ˆÔ;ýlú¸ñO¸|ÿbð üüòï·•õ£ó6cþga”§ÐŸüuxP­ÿ?òw6 äíLÆ àÆêØ;7§ß’‰—QøùáFùÏÿËz ùc\¯z /ú¯“^TóŸ”­nt1G-OöŸ"Ó·Ä׈ QœÛÿÎr~GÎXJu‹jR†]=O*øzR¿ãŠð²ùËÿùÇËÒù°ÛHIn4ÝI­y‹r€|Û¦Y¦þ~JjÔž}Ñ‚ÜßÃhIÛ`.Lg¾+LÓKó®/-U³Ô–•ågs À§bfÅ –*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUŽù“ϾIòt~§š¼Å§hâ• {y ß꣰fúTsDm{ùn~A4^1æùÍoÈýœzuí÷˜n£†™f꜇üYv`R=Ö¹G”OÇoÛö'…å÷¿óœÞoóïeùkùq-ìÀÑy./ä$ýšÛÙD¤ùèr¬¹ŒÎQ€óýd¹Š\þ|ÿœáó¿Å§éÑùfÒJòãkceÀmE¥œ}¹©ÏÛš8}YL½ß® }íƒîB·äGü䯚èÞrüÎ’œ­ÓSÔ.x×­aAU§ƒf¯7µ:AËŸ¾¿I%˜ÂQó„z37«¯ùÊöúfÝÚÚÒ;rMûSI9=¿Ï¦ý³ŸðcÞoõ2ð<ÙnŸÿ8wù?eO¬þ•Ôi×ëWªµÜþ­9ƒ“Úí\¹ppýd²bÉìç$l(bòœ2°¥Zâêö⦔©ÌÃð¦aÏÚ=l¿Ê|„GèeáG¹>´ü—ü¥³Cä¨8þûO·Ÿj×ýÜ­¿¿\Æ—ljåÏ,¾d}ÉàÉ´—¾A¶áõo*èðúTôý=2Ñ8S§1ŠS(–¿9ç’_éŠxGr3ü'å_ú±éÿô…üÑ•þk/óÌ­ËŸ’Ö6Mÿ9Qù“jÖÑX­µq5ôÐ.©h¥™ÙöÄåü—„Þ÷÷2h€õ—Ôá?*ÿÕOÿ¤(?æŒã?5—ùÇæ[è!¦ò‘®\Éqå&Yfi4ëV$R›“ÉvqÊrÿLW„%7?“Ÿ”÷@,¾IÑ éi–°úÔÄ‹—ǵõCü¬ÿÓpäŠóþq¿òJûûÿ(Û§Oî./-úÆ “2aí¶<²?xG…æ3¨Î ~N^‚- Ôtê­ñjmJ¬¤ß=ó3µºÈó1>ñú©‰Ã%¨ÿÎùa›ž…æÍFÅÔò‰®­àº*A$Äm÷t§ôÎÅí¦QõcÜHýlNÞ…OùÇ¿ùÈO*Êù§1‚=’ÞKýJÅTl=3Æ}Û68½³Â~¸H{¨þ¦NQ1ù£þs—ÉKYÒ/3XB¢Ó¯ §ü`0Ý1ù×6˜}¥ÑÏøèù‚?c„÷# ÿœÙüÈò¬‹æwå“ÚµB¼°Í.‡Åc¼ŽpÕì=AóͶV,¿D„½Ä³‘åŸùÎÉMo„zÄš——'4 oìÌÐò>dÓš{².d1§´y_ó3ò÷ÎG•<ϦjÒ°¯Õío!{ß⇗¨¿JâŠeX«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«D…˜ÑFä€i^SçùÉ?É ´kh·»Ô£¨:v—]Bà0ß‹}_’!ÿŒŽ¹_Š:oøï䞀ëóœ~cóãé”BŸP¼'÷S߬·r•&€›;Ÿò<Œ§6ns”`?M}ÅŠC6‰ÿ9“ù¬9y‹ÌÊZ<Ûý].NýÙê¾–œsþ¬Ì>ìçõ^Ñèñõ9ÙöÔ~MÑÂ}ÉŽÿ8[åÅ—ë¾uó5þ³xçœËh©jŒÝü¾¼óªœÒgöÇ',P{þ¦Á€uzÏ—¿ ¿'ü³Å´ÿ)ÙM2ÐúÚ‚¶ ü‡í­´€õ@Í£·uyyä?OÝMƒGG¢[Û[ÚB–ö¤ñŠ$Q"¢(ð  š©HÈÙ6Yª`Wb®Å]Š»v*ìUØ«äÏÉ_ýjÿÌÏù‡Ö?î«i¿lÿÆ^|ÜÉ¢Y}gœC{ãÿÎmR÷Sÿœ„_-OçëŸ#h0ip<ÚŒÒÛÅÂ'•j‹4KÍË*õ”Îï±ñè8Æ!–FGj¿Ð\yŸW:ezE­ß•?-üé­Ï6ó&žÖ¶[ëàËzÚ5ijñ–+›É+/¨©·Æ½@Û0²ÈfÔbåx ŸO.!^è«ÜÈlïVò¯š4Ÿ+þXhçœ|Û í¬¶pH|Ç|Ì^úêe•' !b‡áy°"¹¤Õi§—S8bÆA¿¤o_-¿C`47,‹ËÞuòŸ›4ùµ_-kº¥…µE̶²¬ž‰ Ê’(ø”Óz˜º\2œLIïH/6ÿœlóÿ›¿2|¡ªùÍw 9MRk=?„ÂVáŠMÄj ï%+í›h´´¹£ b½6}öS R$nÈ7ÿ5àü§Ò´Eô¶Ö'Õ¯ÓOŠÊ+…·‰ÜÈ¥‘ÃQ•ŽßjµÚ‡²{,ë%(ñpˆ‹º´Î|/EÍS6ThäPñ°£#A±iX˜$¿)üÑÌêþRÓÚWÝ絇êS1ñ2ÚœŸ™ÍžŸ¶uX¾œ’øï÷ÛŒ%óüáw‘¯Y®<«­jÕyF’ð½n8ƒéJ>™No4þØçŽÙ"$>Gô±¬àX<‡ÿ9uù[Y<‘çó™ø,d»[ŠF:¨¶ÕDÛ´O_ ó Ó{[¥É´®ÌXû?ST°ßLÿœÓüÆò]Äzoçåô¹×"8Wо\òŸ–|¡d4ï,i6ºU˜”v¬eÈèd`99ÿ)‰9Êj5Y3K‹$Œ›prN2„»v*ìUØ«±Wb®Å]Š»v*–j¾dòö‡u§Øë:­¥…î«(·Òí®n#Šk¹‹¤| G!œò‘ 9»Ÿ&@LbHŽæ‡/r 3ÊRìUØ«äoÉÛ»[OùÊïÌ–»ž8Hu„ŒÊêŸô«qˆ©¢“OÏkÀ˲ðP½ãþæN<>²ú»ô¶•ÿ-Öÿò:?ëœO….âäZ,EFàô9v*£ygg¨[IgoÕ¤£Œ¶óƲÆãÁ‘Á|òP™‰°hª^þVòÛèÓùté‹ Ü‚·lvñÇm b ¦´Û-¬œb|Gˆu½ÑAŽy«òƒÈ>oò§’õ=-bÑ4ê-mÃ%›EaqZlMCq™z^Öχ)Ëz¥ÎúûÐ`¦%åOùÆŸ#ù3Îz74kÝBKÍ9“н™.VáåŠX}WbŠC*Éð…¢ü#jÔœíW´y³á–)Ô»¶®_©ˆÄ·¤ùÛËŸâÿ(k¾WýYµ{›$¸§!ÍEr;€H$f£E¨ðsC%_ œ…Šx¿ä¥ÿæÇ‘?BþSùŸÈŽ4;º‹üUep²[ä–”5v¥y†¡û΃¶a¥Ôqj1åõô¿wãïkÇcjy_”?5tËï6þtë>my¬¼ÿ¨Ïs…dmæ—îYb"•URaøœÁAÍÖ¯²ç©Å¦Ž:8â±åû~-q|ÑÞ^˜?—_ó‹š~»ä¥Y×u9u^ò–{›k‘Õª Á,â¬NÛ°¯Qù}Oi˜fúa2ü‘b3ï!ù÷óËŸ2ù¿Kó&›ù‘¤éQG6˜×1þŠÔ¡ôxIz—êÄ"áæÉWvb TšÍv‡NuÇ(K —:õGú<=ök¹”djù¡?çÿ5üËæýCZ²ósê·SêÒϪhÓMnL¶´ŠB&Ž+“FÚI¡Uâ¦ã'í'eãÜ|#†£-ýDô±îÝqLžo¡´ï1yWž[m'V³¿¹‚¾¼6·PÎñÐÐóXØ‘¿Žr¹4ù .Q ðÜL²¥@ë&æ 'ÓuÝ>ßSÓäûv·¤ñãÆ@E}òÌ9§Ž\P&'Ëe"ß?ùßþpûÉZ¼‡Rò5ôþVÕú‘D¥îlýE< ì%Œ×ö–J/eΧCív|{ecäWÙñi–y1‹OÌOùÊùDz#óU±ó¿’mÍ ÔÏ%ê¤KZ•½Qõˆ¶éõ…*:–ƒ·tÚ£*—óNÇöüyâ!ïß–ó–ߔߘޅÕéò¿˜¥!›«²ÇŽ{Ct?tÛì”rz.nˆ{À €A¨=(v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUãÿšÿó’¿–”¾­Ž«~u_3 4Ðt³\+v½DpïÔ;r¦áN)ó ÷Ÿÿç&ç%eh<±y3òþf*g‚I-!’"hD—”õî *aP‡ö—¾j;G¶ôú]¦n_ÍŸÙñm†"^‰ùwÿ8£ùyäÿFÿÌH|Õ®¡d½@¶HÿäZ‚U‡üe/ãAœ/h{S¨Íb»—?Ÿê§&8@{´PÅoAk1€±ÆŠU@  €ÍI²Ú¿»v*ìUØ«±Wb®Å]а¿$~gùÏÚ¿™ô] ¸®¼«x,5º„G’‘9DUš£”Oö¸ž†›æÃ[Ù¹4ð„¤Ed+ôüØÆ`²ë‹ËKCºž8 αB%uNr9 ª¼ˆ©$€ÌÀžA’AæïÌ%ù gó~µm¥-Á"Ý&bÒËJR(Ã;QRƒ¾dé4µŒq2¤J@sBÏù£äX¼‘uù‰± ß•-´·¶ÕóäEÃf32¨FÔŠÓ'ÌÎs &$Lô?¹b­òwç?ç^•çÙ|‡ækVÑÓCÕÅåî¥n±ÛÝ[—ŠFheBÀ•hWïíÛö?cKN2ã3Œ¸ãD¸;ó‰Îé÷yÓ’ìUØ«óþëòòÇó/þróB¿¼–Æ+{Jõ&Q˜¼w±EćڄHs¼í>ÞŸfvf °ˆ‘<1£çÐÝÙºêsJÕ ûGëeÿô)ž]ÿ©Š÷þDCœüGúŒ~eÞÿ¡|Ï(aÿ8IaçíçzŸPñ=GÁp‡ñˇü¤~­8#úÿñÂÖ}—2}ŸµzÿÎ=þbé¿ñÅüƹ‹U(×–¿jî§zn:e£þúIÿy¦ûb~ø†©{31Ë ù+¯‘ç'ôz¾›ù„×ÀV‹6©y3ŸÚéw/QAñeÑöϱr}x%ócþö_¡¦^ÎêG)DüOêD'šç14 åôu«téÊ-.ZÒ§¤^”¦´ï™í?g³ÿ<~°ãO²5qþø„Ló“ž^_ßÍ¿—‰, ^SCifßÕcjsû9¬Çüî£ûY ±/KÒµÍ]·úÞ‰©ZêV¿ïû+ˆ®#ÿ‚‰˜fŸ.ã58˜Ÿ1M€Úž©åÝ\Šxu.ÓPŠæ?Bán­â›Ô‹~ ÍM@` ­ökS†dF<` ±ú»ü·Lr‚ô>~aykòãËÃÌÞešDÒÚhm£kxÌÎòMR¼Bö⥫^ƒ5zMNOz½ÙÊ@Egwo¨ÙÁ}jÞ¥¥ÜI4/B9G*†SC¾à÷ÌYÄÄy„¼óþq£òÓÏÞµìV_áýz@Oé1V5wñšßhŸ´@V?Í›ÞÏöS§¡|qî—è<ÿG“\±ò fÿœ›ÿœeSI¹>pü½·ûVÌ%½µŠñ„Ÿ^Öƒ¼méƒÔ¶w]íŸSBø%ÜAä~ÿ'xH} ùMÿ9qùcù—õm3QŸü-橸§èÝE×êóJ{[ÝÑQªv áöS›æ’ýŠŠ»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Vù•ù»äÊ}0j>sÕRÖI6šlT–úê›~æ<ˆ®ÅÍwaŠÓä-wóËóçþr.ö/þRiÒù[ÉÜŒWZ¢Êb”¡ÿ–‹ð> ý+qϵXf»_Ú¸4¢òK~î§àÛ d³Ë/ùÅ?#y5¢Õ|ÓO5yO>WIKœïð[’y‘üÒ–ñ §8Òö§>{Ž?ÝÇËêùþ§*8@æ÷ÄD8Ô*( ª¢€° æ ¶ÖñWb®Å]Š»v*ìUتԒ9 Ü1CÅøx°¡§C¾$R¼3Ìÿó•Ÿ—z*Κ¶¡æ+»9fŽþKY ©Uyfk•B«É¸©ã¹´Ú½&›Ù}DëŒÆò³w}ÔÔs#¬ÎOùÖÔiÞ{°òz/äÍåêØ Né¿Ü”®•X§+G Ê6V+Nu9‡Ù¬'‹ Éûð.‡ÓåÓ~~ NSζMÿÄ:ýÿçÿš-µræ*y§Ëï7—ä³e·’ÚI­¢¬A$j§šñœ«5zÛe—Ç<ñ€ãÇ?Uï{Ø›õñÊ—:çæâßXùª[_"ùFh¦Ô|ׯ갛RöÞOQb´g©^k±U'Z¿ è3jµô”qÞLƒhB&¢?ÇŬO=™'çÖ§¢þ}GæûíZ×Kò¶½¦[Gåß3_é_¦l­áFαEÅÇ3 sÈ –Z칉Ù1Œô>‰”á#Å.wëðû“?ª×ù/òµ|ïù;çý+ÈúÍæ®úŽ¡mwa%æ–º.Ÿuue+HæÍG^¡ B#*T(è5§àjðË,DxbA©qÈüíº|o~iŒ.&•<Ùoùçù§ùi§~\ËwÒŸËëbn5 ©ã€^=¢‹HÖÒ9–$CF.äHʰ#K-“S,þ7ìÕï½_ܧŠB©õÖ†/F‹¦J?GQ¶âòÊÅ'ô—Ô^HYM¢¡ˆ÷Î7¸yY§ #²µv*øÃòûÿZó#ý][þêVÙ¾ö×þ1tÿÖ‡û‰»Og?ÆeýS÷Åô.xëÛ»v*ìUØ«±T·Sòö­¯ gK´Ôö»¶Š~Ôÿv)̽6¿>îòJÕ‘sNLŸÕ}á‚ë•zÀvý õ Þ¿¾±žX8×Â>F?øLèôžÝvžò¼cº@·êû]v^ÃÓOøkÝø¦}ÿ8´–7_ò_šîôÛ¸êa7 Wµ'¶h™~„9Óé¿à"8u#!ý_ìeÅ÷ºÌÞÌGø&G¿öSp7üå‡å埫ŠtèúÅ,©¨ÕGM®Â\}Ù¶ÅÛÝ…¬úÃ/1Ãþæãóuy»Uâ_·tóIÿœÅÖô;„Ó¿3¼“=Èþòk/RÞM¶%mozÿÈìÍ>ËáÏ=6a1ð?ì£útå8œH/eò—üä7圌pØyŠ÷§ú¨ Œ•=4Ô²;f“Wؼ˜;ã¿Ý¿Ø‘¦:AwG"¤öÓ¡WFã’7 ƒPA4à|Ù±Mò¯òãËš¿éíË}†® º‚Ý£/³zc¢T|m™¹»SQ–œŒ{­ˆ€5·ü©ó7å—•2uï,ÜIæŸÌO6<²ÚܤqÚMÎMJ‰%#”m,’ìßk¶måÚ˜õYpà ðñcçחíóaÀ@5Íãzò5—‘¿%<•ùr4x%üÏó¶¡ ÄÍ$(o vuýØzR¦H`ãZ}¿|è4:Ùj5™sq øÆçä×(Ô@ê^—«­ë?œXü–òýÚ]y/ÈÚM´^mÑ]AxÖÐÄ8ȳ¤ƒ•D(¬%fz³PqBIê¦*ydx(ÕY=ß~ÌïÕ]ÌŠOùÈsäï0?—7¼³uå$žY¿Ejñ}a=²¹³4ˆ`¥yðçCÔ/Aˆ=Ÿñññé¦2wŽDìø§Ä£»Ûí® ¼·†îÙÄ–Ó¢K ƒ£#€ÊE|AÎvQ1$aµS¼oó;þq¯ò÷óM¿ø̯R5M>5T•Ï{‹}’Ov\ÿ6oû7Ú=FšÕ[›«‰(bEYÝÜ€ ¤œUòæ—üæ-þ¯©Ÿ"ÿÎ?éÒkZíþmÚU ZglÃ㯭0?•‡Å•fÏ Q2™¥”clgÉŸóŠz™.§óo玵sªùƒPVw°Šé¤twZqtjY’»GÀ(>&]³‡í/kÍðéÆßÎ? ~¿“• éOä˜5OÉÏÍ-cò;ͲŸÑ÷÷´{†$FnÙA…Ò»¹‹É¯Rr]»‚:Ý,uxùê÷uÿJ~ÅÆxMØÁ¹Å]Š»v*ìUØ«ó§æW‘¿/ †9kPibâ¿W…„“O(H W¨îÁh37GÙÙõ$ŒQ2¯—Ìì‰HoÿœüËón}ä¯5ù%5DòÕš[ëjO¨%ã«Û[ÜÇð7:FÜ£ ýŽtþÎön)Ç.<¼ªŸ—¦VKÏ,]Ïlîn #‚<Å}:Ñ—ï¾:>Ɇ9 <¼,†ý]2 î=kšÊw¾áè¾iÿœ”¸ògåÇ–õ½[BüÛæM/ìœ@ÃJlUUdºµ “7¦„°Z ŽA³S¥ötgÔN1˜à„¨ÿ:¿[3–ƒ?—óFп+ôŸÌŸ8Æ,íõ­L–ºlƒP =Îâ4‘8© µOÃB*O]`ì™äÔË-Ⱦ~ƒ.:YÝ­ÆŸ®ép]ÂëKÔ I£'Ã, eä’Œ§pÃ5’Œ±Èƒ±‰ûC>ož¿2ÿçtRèùŸò²ïü-æˆ_׎Ö7’+'™O д»×¡J¯J*õγ²ý«ÉŠ£›×ÿâ¯ïóižy!/ÿç+¼õùc«Gä?ùÈ*ä¬TH|‘v±•åXþ ˜ÿâØ.µæÙßéuxóÇ„ƒ‰(û'ËþbмפÛkÞ[Ô Õ4{µåoyk ’6ÅGB̧pv9’Á3Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb¯4üÝüóò'äÖ™õŸ2ÝúúÌè_OЭJ½íÏP‰ $u2=Zr;b!HŸÿó—:Šßk³Ÿ*þUÅ';{XËg ÛzHxµÔ¢›Êä"šñãöN‡µ»pýSþhý=ß{v“UfÇ—Vz•³Ë _;~wþRùËÊþw¼úÞ‘q2ÛùSÌRÙ­±ŸÑc"J°ªFLHñÆA¥~&Jü;kûJXt¼y1 zãw_÷ç÷³…ÈY‡å§å7žì¼»såÍýgNó?”Ê;NÐá…¤H£ùG!¸xà“’¨ »(¤0¦ø£Ú¸%dÓFPÙ—¿ÊÈüre¢Ë|—ù%ùcù}¨6¯å};mT†T¼šY_b"k‡~mU¡#bNak;gS©IØîØ}Ì£ŒLÿ5lŠ»v*ìUØ«±Wb®Å]о0ü¾ÿÖŸüÈÿWVÿº•¶o½µÿŒ]?õ¡þânÓÙÏñ™Týñ} ž:öîÅ]Š»v*ìUl’G m,α³»ªª7$“°(ÄÈÐÜ šæ–iþhòÖ­pmt½fÆúékÊ k¸&Pj±±=eçìÝFñdÇ8ŽóÚa©Ç3Q'È„×0›ÝŠ»v*ìU ©é:^µhö½”öR}»{˜’hÏûW/Ój²`—9HuØ×“f*@æñ6Î1ùKSs}å;¹¼½¨©çjZâטܬÂD5î¯AÙs¿ì¯ø#ê°úucþ–_¨ü¾.‡Uìæ)ïŒð˜Ilü÷ÿ9ù#Æ=v/ñ” ØÍ3=â¤b•+t \EA°õ”¨ì3®Óê{#µ¿»—…ÿ ôŸ—Ó/óM¼î§³µ¨Xïþ>/lü»ÿœ ü´óߥe{uþ×\ Ùjn©¿qÖÑ··> {.`v‡³Z>àqǾ?¤sûÜHåì—6Öº…¤Ö—Q¥Å•ÔoÑ8 ±H¥YXt!¡ÍdbAØðo2Î+ù{PƒNÒ¼¿®êzg•aÔ÷PòÔ×—:|—D·¤'#•$!ÎùÒéý§Ée8FSá¡*_ÿvÍGaÿ˜ÐXùþrcÊþNóô gä.ÞòÍÞÓR¸’4nUYB™©íN14å\ÏìùKfäË„ÞIQ½â?³‹o %Þ]¿Ó¯5oüŸäÆ·Ñ¿"¼ƒ äÞiŽeIôûÛ‡Ë1˜Ý RU Õ"bŒê1Ê:Q“-ËQ˜Ž’¥W—?3ºƒ½Aë^Xÿœˆü¢óVºžZÑõÕ]BWY ›y­a¹sEU…æEZ±4Uj;sE©öW†r†Ýhƒ^öÁ’%êy¦fǼåäo*ùÿI}ÍšlZ‘©Œ¸+,.nVŽî§~‡lÊÑëréçÅŽTÑ(ƒÍòî¥äÎ/ùÆZ8~Sê3kžHf2êZ\Èf¤Kÿ-–É@à/ü|Cņõà:ú/d{MQPÉèŸØ}ߨý®.L4úoòGþrWÈÿœ¶ñéñ8Ñ|ê‰Êç@¹“ˆ%žÒRL  uî´Üõ9iÅÅ]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUòŸçüåÌûùòr%ó窾¥ }jÖÖføx[¢róE=yn¹ 䌔ÈFØWåüã-7æç•Ëëžf½¬¶q/Ö9¥òJ‘!Kð(Ûâà{cÚ£+†Ÿaüî¿ï?s—{é袊’Qc†5 hªªŠP6ƒ8’I6[×b®ÅVÉsFñJ‚H¤]VV ƒ±b nñ…³Mÿ8Áùôö²–òÓÍ”âÌO¥´²|-]Ç+I‰ïéþÐÏA«¡¿ò¸þÿøðû}Î7Ñ/'Ú Êêd` °5„óç%¼UØ«å:jÏù%ÿ9/'æ'˜mä“Éžo²[GÔ6”ÛÈ*K#Û£•]ý6økÓ;m/ÏvoƒëÆn»ùý÷óh‘ᕳo6ÎOyr-CEп,-‡ž<ê\$oeng·D…ÔÓ÷Ïù_„…PÅ©šý/³Y e<çÂŒG=ÙŽŒŽQÓt£[ÿœpótžp×õ'ù¼yoÊr!üͦÀŽóVBÍÐâ`2cãž?¤ý×ø¡¿_.'GÛÆqÃÇbbzŸÛIGœ7uã¦ùFò!Šo8ù¦ ;Éв¤1K]H4äüªß²³;²}•Áâj²êìaÀeë ô÷ Û©hÕö¬øqG×0ãñÑ‹þe]y‹ó'ó;KüŸR0éÖ1Âu›˜‡î'âêyŒ`ÐñZ,q’@nù¹öwŸ³;6}¢ar‘<ó‹†1¿3¼Pâv„²ju1Óql>¯3VOê —Vÿœ\ò©³·>XÕ/t½fÝãe¾šA8`¬91Dàn¥wÍF—þ Z®3ãÂ3Ò}»íß`¹Y}›ÅC‚F2y½§L¶“IҬ쯯Þökh£†Kû’‹$î /7ãAÉŽpœƒ6YJ$ðŽCÈ;üqàˆÝu(ìÆmv*ìUØ«±Wb®Å^cçÈ!ùÌIr¶Ÿ¡µ‡«}OUŒ3òÃö§© cüÙ×ö7¶ÚíG‹Ä‡óg¿Èów“¨Öv. Û× »Çêy½¬ŸŸ¿ó”}ëüQäXNö®²\ÁcÆúÖûTÖ&1Ú¯Lô='löWlí?Üæ=û_º\¥ñ©w–ÕöN}>ãÕñúGO¹îß–_ó“Ÿ—¿˜>†}7øsÌ’¿P¿‘DÈ{Asð£o°WàDzœÂí/fõkqï¤hp#”²\YÚÝðúÌ)#DKBì8Ù”¡dnªx±Rh#29džùÿò2ÃEü–ó_“+ìäK½Jxµ7¶yšY®LÇ)dsÈ€‘Ò5bw÷$çG í¹OY.s´GºÁßõµK¤€ð6y§Ë>~ò/•?)¼‹ä‹»/Ì› ­"¸SfÉe$ éÜ9™ªy¹ í"­Äô gK¥ÒäÓçɨ˔D¼ï–ܶò÷¢A»×µùÉKÏ/yþo+Ùh÷>hò¿–l½?6êÚe»Ü\¥ä+Ig‰¬hãƒú¥Ey|Bƒ–‹³£&ÈcœÏ HЮƒ¾ý͇-{’¼ëåïÌ/[yŸË&çL¹ä¿˜åŠT4x¥Cº²ž½»‚A9Íf&›!ÇQ ±"Ùb¥óÇæÿüã—æißÍß—/—<ë ýdE0ZÝέÌ81ÐÁ5w&Äý¡SÈu}í<ðT2Ü¡ßÔ~±øòiž+ä§ùCÿ9c®y[W–Ÿó¶òéÚ½«-¼>cš0¬; ½TYHû71Ô»w|ôm>¢ 'Ä ‰(Óìˆ'‚ê®­eI­¦E’£`é"8䬬µj˘*b®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®ÅP:γ¤ù{KºÖõËØtý&Ê3-ÝíÌ‹Q ڬͷ]‡‰Û|9ù•ùñùÿ9®Ü~XþI[Ïcå姬žvòÝÛ“Åžy)X-ÛzGöä¹0µÝ¡‹K<†‡Ú}Í/[üžüˆò§å-žŸ›&N7ºäÈ€zÇn¦¾”~4<›ö‰Ø/í~Üˬ•L:Gõ÷—6Ä^«šVnÅ]Š»v*òßÏßÊèÿ4|…u§ÚƧ̚g+íR>/Yゾ(ááË‹³›žÂí3¤Î úe´¿_Á†HXaÿóŠšy·Êry'\‘‡™ü¬«Yj%›OSéÄÄëýÓø|5Üæµ™àåñaôdÿuûyüØáŠ}œ»k±T¯¢èþ`°“K×l-õ-6jz¶—p¤ñ1‚R@EGcÛ,ÅšxåÅb{ÆÊE¥ž\ò’¼ òIåÃIšPD³ZZÅ®§~&@9·Ù­2íF»6oï&eï(“!ÌT»v*Ðt,ÈZrPwéQ+ϼ©ù©cù‹'šlülòOåÆ[T¾ÔWѲº½oRˆ†2òp_Oâr üBŠsiªìÉi¼3”ý{Ðæß"wtòtÿœ˜×4|ßåŸÍ=?,ùëN´»¸Ð 'ÕnÜDÂÕ¤g©.*²(â´¡máör<šyqã‘]ã¿û9†¿®ù³ßùÆí3]·ü²²×¼Ñw¨ëÞd‘õYî/ç’âQ”KeV’Ä¢@?Ë9¬ö‹$¤ÃŒ=; ߯۷Á–!¶éü凗¼ÙæË™Dk?Ð:X—S×c¹}h‹bž‰µ(¨ )“•>þ9>Ëj1cÔzïŠ^˜×-ùßÙHÌ {ʾCóæwüã÷­qç+½K[Õ!Šû@"¶BÊk%{sdï”’7*Q™€¡ø¨HÌ­V»—_CŒbj]n÷âò?Øc̓èvÔ9¿0(¼¯¯C"yƒÉ÷òù•&Vîtþ¤’räßVÇó³”Í–}t:}FHN@8}Òþß“."§ó‘ÿ,?ç#ÿ0n¼õ¢¶¥§]D—V·+f—¿U{¸á¸wá'@æCqÐü= ÈÇ}Wga¥ÂFÜêêÇèº[FÕÿ+.uOÌO'þoÊO/ySÎ7¿”ínU¡Œµ­Ô·qÑV¼cǪî@¯ ‡iö„tÙ´üGŽxÇ®¼À>gûSØ>i?—?)|Ѩþ„òŸ™¿-u‹ûëI£‹UÔ5O0ˬcÓkèªP(C% V¨ã‘¨í\QâÉ<@#az¯Îÿb*}º«ÅBÔš*MI§‰Ï:r[Å_~_ëOþd««ÝJÛ7ÞÚÿÆ.ŸúÐÿq7iìçøÌ¿ª~ø¾…Ï{wb®Å]Ф>vòâù»ÊZÇ–Ë*>£m$PÈõ(“S”NÔ©¢¸Ri›>ÆíÉê±çþd>î£ån6³Oãb”;ÃÌ&?%u?"ê·ž`óeŽö°‘-ž’mä’hà·ãG`eD ‘DQM–¿ÍµþØc×âŽ81…ñNÀžœ‰÷žó]Σ²;"X$g‚ysüÑÒ<Çùqù¥oùâØ>¥¡Îª5xb÷<`ò‰8ƒÅYu“ µÛ–ÓÙ­VŸ´»0önYðdA=}\B»È;ÿ7—–/ibɦÔLGzü«ð{ÙFÿ9%äÿ1ù‡KÐ,tÝF6ÔŸÑk‰¢Ž‘LßaxBò3z¶Üzô­4úïøêôØ2fœàx7 Nã®ä ÷us0{A‹&HÀ z˜×æ'™|±ù‹æÙ¼½’õO5¿•x®f°º6Ș$£Š)f ÉDø”’ 6Í·`vv§³t£1ÔãÁãÑQâóë} êâkõõ9L9dðï‘¥È2ÜØjþtÓÞ[Ø|•¢B×QÙêŒ^ãO1;ŒöR\0û=:å¾ÜötrbÓLœùO ÃéÖþ{‘^ö=‡¨1–A¿EÔ¹…þRÿœŽóV¡§Þ^jO¸Õá‚tn´˜fXaªH¸‘„‹Ïuâ>w;d{Sþúly#j#Œ‘ÊdY?ÑçÞº^ßË(’q™oü?§›Ùï1¼¦j‹¡êzõ•ž±ð¬–’Ü h€<$o²§~ŒFp}ŸÖåÅâãÅ)C¼~c©ø;ùö†ˆS]ÖÁõ¯Ì¿17çf•ù{å¿«Ë¥¬Q¶¶&Œ¹Z£\ÈQÕ”©ñã¹›ps¢Ñû;§“YžÄìðQóá?­wä9ºìÝ£“ó‘à ¯âûþç°g ï]Š»v*ìUå¾ü†òWž=[Øaý ¯>ÿ¤,Б¼f‚¡ÜŽ,›;.ÂößY¡¨“âcþlºV\ÇÚ<6»±0çÜzeÞ?HxÏ‘??0)5{Ï-Ïv¾rò–“3[Ï<ޱGú|ín™K"ÖC†Oå×=wQØú}~(eáðgXå{‹¢:Ÿvýï0qÈÆø„O7Ø¿–ßœ>GüÓ²õ¼·}ÇRC]è÷4ŠòR¤:ÿ—e÷®ÙÃödgÒJ¦6é!Èþ<Û#1&a«XK¨é·öv—Ri×—–ò[ǨۅõíÙÑ•$N`‚P·%¯|ÀÅF@‘ĺ<‹"6ù£Éú§ä?äôÞOò5¥Ö¿ç9Þ>û]†Õ¶úÙôT¹½2Q„P«?Ûfz×:Ý6®=¡«2‘b#}Ûü{ϦƒÐêöoÊËØ,|ƒ¦yT:Í}kNá>Ì·“žR•ÿ%vE=ÕFh;[^uYå“§!î‹m„hRa{ù‘äm3ÍQù'RÖà²ó<ɰXÜóƒÕY‰ˆå‘DLÌE«“]©•C³³Ï‹“ñø´ñ ¦S˜I`Ÿ™ÿ”žPüÖÒ?GùŠÛ…ü*Gêð·v¬•ÚB~ÔmðŸf¡.Íí\ºIÜÝGCøïc8 >xòŸææ§üâ6½•<ë ¾bü«»•…Œ±V5-ÉžÉÜÒ7ý§¶sÄÅ+Ìúfv¶-d.XõŽ÷&2sy?Î^Yóömæo)j1jz5ÐýÜñÑÀ£‘ŒŽµø‘À#6)î*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»c^|ó÷•¿-¼·sæ¯7ß-Ž•mð¯íK<ÄÁÝäjl£æh «á½SVüÑÿœÇóAŽ?SË”:UÇÀ´&0V´gÜ ‹¢§ <"µjú^×í¬z8ï¼Ï(þ“Üñâ·Ô~Fò–?.´|½åk1kgiZ=Ì´¡–y( 9û‡EPg–ëuÙu33ÈlýƒÈ9‘ˆ™.b%Ø«±Wb®Å]Š»|wùߢê_‘ß›šOçO•¡? õ‹‚5‹DшÓg¨}2rû¾ãÜÂq1Ü"¿ç|ëå=Eºü»Õ¥“JóÝÅô·³[j èµá™c³š³U>›Qy-ErÕhòÎc4}XÀ­º{ÿZáåÕùý¦X~f~s~_~T˜ÇIõjê%Q:Z8.bJ|9§Jºûd{ $´º<Úpˆé~ïØS\€Fþ\[~pþOyÅ-ïô»Ï8þ[Lk¤kpËO…3ÈÁ-(ð3 }¨ê6jûFZMnHcËüQþwã¿æ±â‰®¡u}.Ï\Ò¯´]E=M?R·šÎî:Óœ7˜¤Zû«åqe8æ%q6> Ä[È<‡ù9'ä•¶±æ ;_Ö¼Ïka§ß7Êž‹K£0/0g‘â ­­Ièk›íwkþ|Æ„`I?³sÜ/«\aÂÇÿ&ü­æ-óƒÍ_œ~`ò¬þR±¿µKM+M½_NáåD&Ъ0b!«A¼›r¡9•Úú¬xô˜ôÐÈ2l‘Ë­·ìcL‰¦e?ånº??m¿5l®­@m,Øj6¬ò‹É&ôÝU”*)æ@v;xëãÚpüÓx¸¬w}þþŒ¸=VõœÒ6;v*ìUñ‡å÷þ´ÿæGúº·ýÔ­³}í¯übéÿ­÷vžÎŒËú§ï‹è\ñ×·v*ìUØ«±Wb®ÅPvÚF•e;ÜÙØ[ÛÜÉ_RhaŽ7jø²€NddÕeœxe2@èI-qÅ›óÍSòSKŸÌמjòþ»ªùnÿSf}R=2àGÃ9äç§ Y¾&øˆ¯@3¨Ó{c–:héóbÇš0ú8Ř÷|†ß}º¼ä„¥.ty°áù9æÏ'~Xù³Ëþ_š=oÌžb¸ˆIpŒ-™¬PJ}v¡sYú?\ßktºÞÒÓæÌ,Xbvú½ËééÑÁþIˇM’õJgÝ·ÇãófÞSòö£ùyù4ÖVPÓÌvšUåûÆ3FH^p†• UøÇþÇ9îÔ×ãí×â‘ýÔ²F?æ#~V7ø» . iô”¨DŸóªÿcÅ(<£ùQæo'k:ÏŸob“]k‰Úêk‹×·šÚ ĨŽLÌY‹Õ? :×Ð=«í^ÔÒêñâÒDŒt(Ø‘åGm«a[W7AÙZ].\R–Sê¾ú¤÷þqg˯su¯yÖížržž“§ÜMñ9U $¿h’(‚; ŒÖÿÁ/^#ZXÐç9òoû\f´öe”ïü#ñò}/žHõ®Å]Š»v*òŸÏ¯ÌOð7”ÏO—‡˜u°ö¶%OÇ TýôþÜAâ§ù˜Ç;Ob;óú¾)ÝâõKÌÿ ~<Ït½·¯ð1Pú¥°ý%gägå¤OòQ}bÕY×ÑgÔá™p”úV̬)²±.ûLGl—¶žÑKY¬ýÔ-¢GY|ùyv7g 8}CÕ>~îæ=çùÇx¾º<Ïù]xÞ_ó »úñY¤¯A½`•([­ëÛá¸ì/ø Ê#ÁÖn/âÿ8ßïpûCÙèËÕ‡Ò{º|;¿“/Ë¿ùÊ-kËZ’ù+óÊÆ[+è8ĺ臋èê(ÅOi¡?Êwlêu~ÏâÔãñôR‰éqè|ìyyqc— Åú§OÔ,5k(5-.æ+Í>åD–÷Vò,±H‡£+¡ –qÙ1Ê1¢-Œ~j7œò÷Ìä Ç͂ںpŒ/Û_WÒ ZÉésôÇóR›æoeŒ?˜‡ô^ÿŽëæÆw[>.ó>¯æ _˺7‘â×®|éæ3ˆ!»Ð¼Á¤Ï±¢êI"–’Úöo‹eh÷r¡yæ§ é±c†Ie0¡ ©BC†qóˆùûÜbMW7Ðw?óþWü»ó'—ÿ,<Átuôë,üÏæQ%b¶¿†SÉ@%É*ÆZn¤¹ä-ÀË©Ç<ð6I„{Åþ)»ÄÓÜ´­WL×4ëm_G»ŠûL»A-µÝ»‰"‘ueÛ®ÇÀç7—±ÈÆBˆèÚ ¡üÅåÍÍš=΃æ+õ &íxÏm0¨> ¤P«º²AÜžŸQ<3¢E¾JÕ¼·ù™ÿ8•æy<ëù}<š×åµÜŠ5; ù4b2HX¯U>ɤW*űñoMìOh!«ôäîè}ß©ÄÉŠ½Ï³?)¿7¼¡ùÅåµ×ü¯qIâàš¦•1êÆvá*ŽªhxH¿ p@égءث±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]аÍOÍ(þPùfO1ùªç>QéÚtTk«ë€µB¿ñ'? ÷=*¨‹4/,þaÎZù´yûóWÒ¿.¬¢Ótè "4`ÔÃfÔëܶäì½(œßn{A à†ùÊ>ÿÔäbÅ~çך6‹¤ùwKµÑt;8¬4«4[ZÀ¡Q{w$îIÜÎùæ³O,Œ¦lž®`ŽÊÕØ«±Wb®$S°N*ñ̿ϟðíÝ®…ùo¤¯ž¼É4sÝ]Á¦Íõ˜¬­­˜$7ÕDË‘ãÇjwìAÙ݇âƒ<ò𣰵“Ýt×,•Ëv]ùQù¡¢~lyV/1i*m®coCSÓ]ÃÉip%K9)’=!Ø@ÀíNÌž/·xe ñsšæLoÏþKÓ?0|£ªyKU[ꕎjh'_Š)–½ÑÀ>ý;æ^ƒY-6Xä1öŽ¡Š|çÿ8»çMSÊcÖ?!üæLŒ÷£; c«Ü@„õW_ßÄFÄr=Æu~Óhã›ux¹8¿AýàÓŠTxKë â[ÝŠ¸ ³(Ü“°b¬GTüÄÐ!òŸ™|ÓåÛ«o0§–mîç½·²»‰‡©iâi˜SÄxÎÅÙùXc˜0ã"¬wš¶&[[Ïu›o&~v~HGç¿âhVn@ >2$J…ý´âΣµN“W”é² Ãé==@ýŸ"Õ ˆ°ǫ̈üÅÿ9äß'ÙyCF½±Ñ.õ}æ5DúÕb·A…2Ó×Võ‘ æ>ø³CÙÇfæÈrHÔxw»û¹u®m’¹OKüÀüü¿üɸÓïµë) Ôtâ‚í>Am;ƒhdp§’ ¸þÒþË šéôµŸJ±.‡qïg,`²]'ÈþUÑu6×,´ØÛ_’­¥ÖnKÝj1,*­up^R8¢òø¾*TÔæ&]nYÇ€ËÓwÂ6ÈlÈD2 ÅK±Wb®Å]Š»v*ìUØ«ã/ËÏýiïÌ¿õ5oû©ÚçAí§übàþ´?ÜMÙ{=þ2ª~ðú–§ ƒ£\[»cÐ’ üI_³"íãCP4¥Ù9´’©ºHr?ŽçL¼Çä-+U½ºó.“gŸ…ÆŸ§ù—ÐÏl'^!ø’•¥¶à¡ Õ§×J•Ë‚c|ÔÇæùÇÍ>^Ñÿ!?-¦òd6‹æ¯Í¿ÌQ-”÷&¸2zçƒ …Ǧ§âyO3° ë4º‰ö†¤e'ÃÇ~î_û†Í$pŠêQ¾QüÓòÿüã×—,+®,¯¼Ñæû1%ÿ˜¡ÒÂÉo§ËqI^äLjT?Ƶ$‚i•êû3'id:€F8£ÅÎU×â‘1LûÍ?ó“^PÓ<¥ kÞX·—^Ö|Ë,qézNî‚q ÂU^eX0hÒ¹½8ÕjF¯KìÞYåœ2ܺr±_frŠÙ쪑êºj¦£eÆ+غÓî–9(²§Ç ª £R¥XTûŒÐY„½'‘ؼ6>MüÅü¦ó‡ä?™?åo~HÍ$Z]¹-©èÊo«Äæ²+Gþíµ;rSñGöÛ’ú`ûF3V,ƧÒ]ÿ·ïqrâ­ÃêoÈÏÏ+~vh?YÓȱóE’!Öt9²@ÇoV"¼…›ì¸éÑ€={‡«â‡b®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]мóó‡ó‡Êß“>V“Ì`“Ö¾›”zF‘q}px­kÅ É!QâÅT©ñÿ’¼ƒçoùɯ5¯æÇæä­”‘øéZDAâŽâØ‘²–&;pßnJòÖ†µaÊvÿ´#Oxñï“¿ù¿µÈÅŠ÷èúöÖÖÚÆÚ+(RÞÎÝ+{x”$qÆƒŠ¢*Р<ÒR2$“d¹j¸Ø«±Wb¨ g\Ñ|»`ú¦¿¨[ištd»¼š8" zr*{ùfÉ.#Ü7Rió÷üäüѨ~\þžü­Ö¬µ?%KëØy¢m8Çs2Gs¤+*3pOŠŽ Zž$çSìö‹uˆ˜äØÂöåø÷4å‘­¹0‹_(Êý[Éÿœ¿‘P]ù‹ÉšÔQiºÖ•¹»e¸uWJ(¨,é¸;G2 ü'ˆØËWù¸dÓjÈ„ã¼eÈmøøÄ±áª!ïÞPüÑ<çýsÏÚÕÍŒ^a…Ç—"YÇ37©$Œ*ž[ àK€Jµ1«íyæÁ 3ð«¯ãïÙ¶0£oIÍC7b¯–ÿç+¿/ïì&Òÿ:ü£Êß]Ð¥·]VHWãáƒmtiÔÆÔëZ©_Ù\ìý–ׯBZ\›Æw_¤|yÿkFhõtü®óþŸù™ä7Í–4InÓÔ-—þ=ï"Mõ4 ºWª{ç7Úz isKéËÌtm„¬[0ÌN C¸=F*ù‡óGòSÌžK¼Õ|ïù+ú®±kqgæ'Ä£º‚éYíb^¤s,#¡û™ØöglãÎ#‹UÎ$O¸ŽóúzõïhœÜ3oËïËmzóþqâÃò×ÍO.‡ªÝ[Ý[_”ô¥šyµ &81J¼/SÆ»Š‚3]¯íG´|~°#ßÂÞÎ1ôÑzg“|©¦yËo•4v‘´Ý./F•¥`X»3•U–bMÍ>³U,ùe’\äÎ"…'™Ž—b®Å]Š»IµÏ7ùSË*[ÌZ冔åKÛ¸mØe‘5íLÈä˗艗¸ƒ i­ÿÎRþKhÅ‘5×ÔçZÖ->Òâ^‘Õ#5ö|ÛáögY?àá÷‘ý¬X° [þssÊ–]Ë•ûtO­ÍofÓoîÍÁÜûLÙâö3)úòD{¬þ¦8è)¿ç-45jŸ,~]€¦¼ ‰}A½*`H+ÛüúX}Ñbþ÷PÆ1ûÉr!‡<þœr?P’~wÎRju6žZ³±¤±1Ð ©þ—pß?ìÊΟ±qóÍÿr¨öN¶\±Ÿ»ïC·ç0.¨EÜ6A{t3ο5“§Ñ:¾ÁS/ùYûˆû=¯?Á_þµ/Ò_󖲓+ù•ßâd®ž´'zQ â>°*öÛ€ü¥úÛ³:ß/˜bV@üøÓ<Ǩy¶Æþ|Ū‰F¡|&·-0šEšJ«FTUÑNÊ:eÚ¾ßì}FáÉ(F¨Qé°ëæÙƒÙí~)qB÷„ô'üå©å±Ŷ#ýƽ)ÿ¢§ÝšžfçÏò³ôIÌükG”ÿKúBåóüå5 °Cz«QȦ”yס¤,‡oÀ{;Ù©ò&?Ÿ¦Ñáv¼yÆÿÒ~µëù³ÿ9 ¦m}äøoP1K ™Ójƒm1þÎ@û+ØY~Aùñÿ}ÒÄêûJðßù§ôEÿœžó.–iæO#É3‰¦µ§OÙšÿ‰dü ôù¹Ôƒðû¤h2ãþó1÷„ÿMÿœªò-É ©iº•‹ž¬±Ãíp¨¿sS9íW±½§‡žêÔ¿Ü’]†.ØÓO”À÷í÷³‹-BÃR„\i×PÝÛž’ÛÈ’¡ÿd„Œçs`ž#Ã8˜žâ)ØBq°l"2¦nÅ]Š»v*ìUØ«±Wb®Å_?ÿÎGyÖîD°ü®òç)µ­má7ÑÄ~?IÜ,ûw•÷oòGƒg§Àÿ±à õù¶† xo¼T¿Ío˜yžßÖX!õKŸèªþ\ù&ÓÈR±òõ¿¸}]BáÝ÷rd}÷¥~ÿ$ âý í‰ö†ªY¥ÈíÝÈ~“çnç³ôcOˆ@sëïey¥s]Š»[$qËÅ*‡ŠE(èÀ2²°¡ˆ#%A¢@"‹çÿ>þFjZ¦¾{ü¸“J×mÎt«wôÁ?´mXš Ž°·ÂÃaO²}SÙßnã’?—×ú¢vã?ïÿâ¾}ï'Ú}^¼?éWêz?ä¯ü䵇œ'Éߘºžbo«¬’)‚ÞöTŠÿœ~ÿœÐ?;4-ééþvÓã_Ó:7-ˆÙ~³mÈÕ¡cô¡ø[öY»—‡²â‡b®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb¬ócóWË?”R¸óW™$.kèéÚtD ﮈ%a޽:UÜì«¿€*€ø×ÈGóOüäÏfüßü×äžSÄzN’¡ÒˆâbVÞwèkê?Y»×‘§´=¿ùqác>³Ìÿ7ö¹8±^åõüAkvÖѬ6ÐªÇ 1¨DDAÅUUhPži)lór×àWb®Å]мƒÍÿó‘ÞCò7šu*ùŽûk½*Ò+¨¥Ä­ô²‘H- “FR¨‡âø‡÷ºOg³ê1G$"F¹òó?‹ä×, yWç«åÝ[ó·É‡óHÜCùQu¤‹Í2”¸··úܪ䛨¬ŠÁ½5‘z¨áÊŠNnû#Hh²~^¼a*5D×—Núø°™Bù*~Jé^TÔ?;<óeùs]þP\é"ÛT…ħËu1}$|Lïørýž|~8;g.Xè±ûf±üêø|>Ϋ8r}ùsùkåßÊí}ËMrÖ72Þ8»¦!ä   ÑT*…]–¦•jó—íÑÉ«˜œêÀ­ƒlb0ÌNÅ]Š¡µ>ËWÓî´½J¹Óïb’ÞêÞAT’)T£©ö Ó'$¡!(š#p¤>=ü³Ôo?ç;µË-~vÿyŽHÿG^LH@e$Y\× ©­¼Æ€r¯Î󴱎ÒÑ ð¸sî‡ûáû\xž Sì¼à‡b®Å]Š»v*¥uukco%ÝìñÛZÄ9K<αƋâÌÄ>xc#@YWy¿þr‡ò‡ÊlðG«6½|•ßFŒ\­GOß±H¯òÈs}¤ökW›~ý-¾Îc\²Ä<ƒPÿœ²üÉódkùk䵊2Jýnáf¿uÿ(úb(£?ë–¸>Îèô¢õ9€òÚ?¬Ÿƒf Y³Ç/ƒºÒç$üøKù§ÍÒérÿyi ×Õ×ý“œ6§ùmóß1çídivÅÄ=õúg¿È;¬Ëjò}d@{÷û?[Z_üãfzÚö³y¨NÇ“ú –ÊÌMO"þ«ø!šýOü3±cŒGËþ%Üàö;úæeîÛõ³M3òsòßKâbТ¸‘z½ÛÉsËæ²³'ܹ¡Ô{U¯ËÏ)Õ¨ýÛ»|>ÏèñòƾÏß³,°Ñt},Ó4ûk%€[A ”øf—6¯._®r—¼“÷»xÐ<Çåû¯3i²Iú&ÌÍëÉ$LŽ>®‚G!w&Šs;[ØùôÙã‚`qÊ«~óAÅÒö–,øŽX“Â.þ±¸¿=¿,¤n-«¬~¦ÒëþrWÉ1Ü2éñu c¾åOPGt~ƒ–gµÜãàÈûá÷\yi{SOË÷ƒý7ê’o¤ÿÎQËa8°óç•î4û¥ –KNJñ­µ×ÿŒ‡5ú¯øŒ‘ãÒgÒÿŠÿ¹ahŒlf'ñÐþ·«ùcókò÷Í¥#Ò5ÈãÐ +¢mn ÙT›#þ¥sŠí/eµú=òb«S8ÌåÈ<+òË:‡›üɪþqy z·7LšXaðú­ðK"û1§îcú—=#ÛžÑÇ£ÓãìÜ» >r>©|;Þs°ôòÍ’ZœœÉÛñåÈ>Ï'z´–ÿ;^Òõë-j7ñÛkš4–0JxúÜX'c·"Oµ©í› —¨Ë‚Yá(@Ôˆéû;ÏN®<õXã1jRäf½Èv*ìUث˿5¿%´OÌHQ´á¦ù²5Ž¢¢‰?@—!waMƒ‰}Çç²þÙfìâ1Îç‡ù½cçÕÈù:NÔìhj}3ûýÿ­ ü©ÿœóåþ²Ÿ–_ÂH–±Xy‚r]âBx§Ö$ßÕ…©ðÎ7_Ú¨Ý}]Øøu¸¿3¢"@ÿýǾ?ƒÆLO¸2 !õŒ°éÚŧ4pßé—h­ÅÕ'‚hÚŽ¦†ªÀìFq ÊÚÁÍ.ówšt¯$ùoQóN´df™šqm,¸UUUîÌ@© I|·I¥–|‘ÇrD |›uæ_ο0Gwÿ9%寗|µ¡Å(òï—µn Ë9HRžœF?PÊxÑÜQÂñBÓ·Ž›GŽ´Tg)}R±ýö6‹‘õ>Žü¥üÓÑ4<«§êö÷°ëòÂÏ©èÝG-Å£Ç+@Ìñõ¯(˲Ã9>ÕìÉé2˜xoiVǯö·Bvök>QüêüžÖ¿.uøÿ;ÿ&Ùôûí2_®êº]ªž1ïY'Š5ØÂ¢âðñ$ýšß{9í`Ìwþ~ƒú —PúWòóÛ@üîòѼ¶U±óNœ±¦»£ÔŸIÚ¡f„Ú ñ=Tü-ØžåÄ!ëX¡Ø«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*Æ0<ûåÏËO*ßy¿Í7?WÒì–Tr–âfÚ8!_Úw;Ó¹¢‚qWÃ~Vòÿ›¿ç,0eüÈüÀY,¿/4Ù}-7KFoEѩۓJƒJÜÎXì)·kÚÝXðC|‡ýŸêr1b¿sìK[[khl¬¡K{;tX­íâP‘Ç*ˆ«@€ òéHÈ’M’æ*àWb®Å]аÍoÌûoËM*ÂH¬Xó·tšvƒ£Dâ6ºº€99Š‚Ê ¡ÜÞ£gÙ}šuR;ðÆ"å.àÆs§ˆy»È~[ü溗RO4Ágùó …¬±y~×TŽâÎÂêË”o F’›·Æcðp^Ÿk:=&»&„pødéìúŒhzŸÚ75‰{Ù/åüÿ™ÿšsÛywó“ÈKåm&ÖH¯ïõkb—7Z€¢Å=²8Ø•›DîHað¦aëã¦Ò=6cÇ#°‰ØG¸þß—TÆåÌ=ãDÐtO-ié¥yN·Ó4ØÉdµ´…!Œ1êÜPI¦äîsšÍžyeÅ2d{Ëp˜eJìUØ«±Wb¯ÿœžü«?˜>HmgI‡Ÿš|¶$»³àµ’âÚ•žÜSrh9 þe ûG:?f»SòÙ¸d}Øù…«,,#¿ç¿5?åeù(u)½O4è>–­Í’eãû‹“ß÷ŠcüêÙ_´]—ù\÷èžãô‡ÜœS°ö<Ð6;v*Áüõù¿ùyùs4kPÃ|SL‚·¯µGîc«(=™ø¯¾lt=“¨Ôÿw]ü‡ÍŒ¦7ÎÚÿüåž¼ás.•ùEåg‰~ÏéÈþ·p¡º9¡¯ûñä\é£ìæ—K=^P<®‡ë?ƒ\æ±DÈþ>LNoʯÌÿÌ;”Ô4¼×3¯"âÈJnZ2z„xÛÅÿ<Á‰›Û ”pé1_™ôø£ñ§£Òû%š{æˆîŸÕ÷³/~Lþ_yx+¦–ºÒÒ·‰$‘ßÓ`"ä™Ëk½¬×j9Ï€wCÓöý_kÓi=žÒaþ#ß-þÎ_c0Ô5=ËÖ[Ô®`Ӵ訂IYaIû*µ ¯€¤Á§Ë¨Ÿ œvåÚåÍ nDF#àƒòç›ü¹æØîeòíú_%œ‚+‚ŠèQ˜rHªH=˜lh|2ýeê4†#4xx…Ž_¡§I¯Ã¨ã—syOæg熳å/3^ykFÓ­¬„[»“$œŒÐ¤ß !@( ÉÎÇÙïcñjôñÍ’rõ^º9ïÜó]³í.M>cŠšÜù‹òïdŸ›¾`Õ­ÿ."ó'–/d²/%Ážk•âH;èvÍW²úRל9â%´…çGû °ííVHèÆ\R1úMŽãý¡åú” ó‹g­ùÓóCÑŽþœéóÝs•CõJM8ÜR”ç]Ÿ´å§Í,Zm˜šâÛìéyÌZ›gŸU\BèŸ×/ÐúKJx$ÒìžÖqulÖð´7#¤Ñ˜ÁYúÃ|òÍHÉ!!ÂlØîß—Áïða6(oßæñÏùÉx ycF¹Þ‘ߘÎÛ~òmÏÁÇü§þwÃî#õ¼§¶QýÌô¿C$“ò{ò÷^òô –776ÑÉå»:˼`†û\Z•èÀŒÕÇÚ­v æò#±äwû>Àû?¤Íˆz8IÇ7Ÿ~Pkïä=ybòS,M¥Ä–§—%A4¤ˆ§ùkeÄçKíN’Y¥ÏG$…ü kã¿ÜèûQ#¦ÏŠFįˆ•ýÈÏÊ‹‰äoœh¯n5uÜiѸ&¾ç(ö–ùcOçáÿÓB{gù37—û€À¼—ç/!è^TŸMó/•XÔ¦–vŠõ­í÷VE ¸Þ-?g¥vε»+[ŸR'‡?‡¦åóáä~.“³»CK‡Ž\\r$ïCå|Þ¯ÿ8ï ëš?—µ+VÞ[[kùã’Ê”£ˆUåÛ€ÕPzxS8ßnõ¸sg„q‘#xˆ÷ò¿/ÒôÞÉirãÅ#0@‘Úþ÷¨ù[ƒËzþ»sK „/;Ä„~=ܳ‘ÐhΧ41DÑ™§¤ÖjF RÈwóhç"üˆñÚ4ðßE-À&tXŵ¨õ1ZËà ±ñÛ:™û­Tb@å¿ÕîÛá½<ü}­Òб-ü¹{÷û­éöšÆ—}¥Å­ZÝÆúTщ£»,?LþÑ-J{צrYt¹!ã”O5]mè±ê!8 ‚8H»kO×4]\¸Òµ+[⛸µ¸Šb´‰ {ˆ(üÆnv*ƒÔ´/X·6ºµ”ÖÇýÕsJ»÷Áß/Óêra—9Ÿ#MY°C ©ÄHy‹y§˜¿ç|«‡—Kh·F¤w2ÁÈ÷h¥'odeίCíÆ³Ù+ óØüÇéçµ~Êé²o òÜ|è¦/—¿>?,¨ÞVÕ›^ÑbéeË×P‹_‡ê×eù@Õͬõ‹ÚŸßã𦋗û(óÿ<:iöWhi?»—‰ïøéÿzÊ|³ÿ9A§zÿ£<ÿ£M¢_ÆxKqn$JÝýH Sä9œÒvü ²pñé2 ±è ðôŸö)Áí‡4Lã§1ö½¿Bóƒæk1åýF FÓ`Ò[ȯÀžÎê}˜žy­ìüúYðfówÁè0ê!”\!3Ì6çb®Å_1þpë‡æ§æ.™ùMå¹èû ëª\'Ä‚áGï¤qÒ–ñÔR»¹+Ö™ëþÉé1öOgÏ´3TÇ Gø@þ¹ÿcG½ä{[,µzˆéáÈýý~_{èÝF°òö‘e¢iqz:}„)ºm^()V"•cÕs¾yN³W=NYeÈnS6sÔáÅp Ìf×̾nó‡/üäPÕ<Åx–Ú“l‘ÝÜ“ÎXâõQcQ»?¯p¿ Šž9ëÝ• Ì;ÃÃrjeöFû‡ :÷¼Ž«<¿Šf£Œ~>ÒͼŸùÑ«ù«SÔµ™4%Ó?,,crÞ`½˜ÂèÑV¤ìË!m—Ò재jsÝ­ì†-&8bxõR?ÝÄ_?º¿.}ÎÃIÚóË#.CøãpJ¯?ç+<•ù‚×JÔn¬¸›À°ÆXö’7pH=¹>Ã3qÀÇY(\²B2îÜüÍ}ÖÓ?i°‰P‰#½ë^PóŸ—|ó¥.±å˱sm^!%†JT¤¨wSøÄŒâ;W²5 ¾hðžÄw‚îôº¼yãÅa?Íc’ìUˆþ`~]y{óH:nµ ¨ƒ F ={Y *Tžªiñ!Øû¾ìh³ön^cÒb¼³–KEÔ¡å‹Æh. ™iÞ¡•¡8©Âx§Fã(Ÿˆ+Íã_šß”7>uó>“æ}r+É.Y½Ýæ‡6¾œ–«¿"ƒ¦cýº‚ˆ ¨¹fÿ²ûX`Å!Ž7žf„¹óý7ó;–©ÂÎüžqùe¥Ûþe~x[~`þ]hQùWòÛÊѵ‰»¶„Z~”uÐ)œ:óªÆ£‘äTfß´².ˆáÍ?.MèïÃøûùlÂåc“é*þcy7Ηڞ—åíR;WFš[}NÁ•⸅âÄÇ„K/!NiU÷ÎGUÙù°F2œhHX=Äe$(w¨Ì4¾FüÞü´ó'ä§›¢üñüž­­•¼¾®³¤À„Ãn¬A—”hG+YiûÔÿuÖ‚œ=Ù¾ßñ@Ôú¿„÷ù{þÿdÑH‚þ.0ë:S7)ln¸Ô¡4‘ºÇ%(ÃÁƒÙ¸¤=;v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±T·­é^[Ò/uírî;#O…î/.æn)h*Iý@ ÉØoоÔu4Îd~ho_Jü¤òÜ„B›+¬NÔ¯B¦êà-OU|iñé{o¶#£Ç|ç/¤~“äß‹¾½Ñ´}3Ëú]¦‹£ZÇe¥ØÆ°ÚÚ¼Q{âz’w's¾y6lÒÉ#)%Í‘¹Z»v*ìUŒjÞyòÍ—˜í¼ˆÚͽŸœµKi¦ÓmeS!E™AQRjÊ…”¸V¦fbÑd–3›„˜Dïøý=d.Ÿ1K0ó'˜òCþrbi—S†ñ¯<¥æëvKo\\;¡FÓ—¤|“á#Ó4eZv xXÿ5¡ª§u_mŽ¿6Žf¤Ë?,"/ôïÌÛo6Ï Aå/,ùTÝÛh–±\«íaÜÉ ÝÝHÌÅAGåÇá¦À-+˜=¥Û‘–˜ã9'’Œ¶¡[Pǽ¾˜ÎA¹ØªÅޤÝ]ÊZÀ­$ÓÊÁ#U™™¨rNÄÈÐܪO¢ùÏÊžb·±ºÑ5›Kص?_ô¥2ò¸ú«˜Æ„†n|T}9~m\D‰ÄŽ¿+ä SÌÇK±Wb®Å_ùÊÖçþq£óÖÓÎz\L¿—Þhi>·k%)]MÜzr‰ÊÏÚ‹Ó–zŽCµ4'¿¼ÇËô#óq¥è•ô}“kum}k휫=¥Ìi5¼ÑÉ$r(de#¨ Ôg(˜’Ä9/8üÊüøü¼ü±G·Ö/þ»®€xhº®«ÛÕÜ$C÷cGÙ6ÝØzVñç_·àÂY|ß«þs~z~s»Ùù&ÐùWË YZîÞFÊÖ”{æPäŽâÝTøçE=/föX¼òñ'üÞì✽fêuÝÇnó°ùþ¥O+ÿÎ>ywOqæ«™5ÝI©$d´VÜÉäIós^ìÔ=×9îÒöçQ—Ó€ QùËõ€ø½~‡Ù<8÷ÊxÏÈ~³øÙë6:}Ž™l–Zm´V–qŠG¬q¯ÉPœ^lóË#)ÈÈž¤ÙzŒX£Ž<1àÂÿ244ÿ˨­R{o¯ï–Fµ‰cŠ‘P7©!©°è§7ÝìäûDȉÆ5}NýÃöºžØí¨h€¸™rîÛÏö%ú·š5/8~OÜù§ËW/§j¢Õ®$ú»|q½«ÿ¤Æ 9 ª·±ès'MÙØô}«€œ8«~¼_Iû¯âÑŸ[=Ogœ¸ ªöòú‡ÞÇ´ëé1!oṑ®u}>ÞXæw%äiôò.#%𤳯¤õ$æÏ>ÙݵP™wTý'à ¸roeÈå~qÜ|Å<¿Èµ÷‘"Ó|ýcÎ}[™t1ZƒÐí20ñ°1ŸæB+ñg]ÛzhkŒô’Úb"xÏØ~Ñ¿‘£ÎvVyiuÞÁ1öýܼǚmªÙ[ùßUüÐÖì\CkoÕœëN,HŽXwÞ(ZŸŽai³KEEŠ{÷ƒþúAÊÏŒj§ªœw>~€YΑsþ,ÿœv¼·sÎ}:Êxdht×Ä?äZ&sú¬”íØž“?éö?i.çO?ÌvIc?Òn>Êy¯’-ÿ%ãÐb½óµÅÔšï©(–Â?¬p(­ð`E¥E:É×:®×Ÿkæ:aއ«ÓñæCÏöl;8bÎOûoúé{%­†‡ù­å[|£«jZ…¢JúxŠ&tyR(# YX•Ueâ^§®pÙ3æì­LΣ2äÈ8·édïË©îz¸bÅÚ"0ÎXáÃö?½)üÓò%íåvŸå½ oõÉìu¸SÀÜÝ0”NÎXDµ OlÌös¶¡>Ñžl¼„¡_ÍŽÜ5Ìù8Ý·Ù’†Š8±ñLÆWÞ‹»Þ”[yóËRÑ­<·¢ù`é1Çm §×ç‰á™Q#órʪh*h„ŽÛævMccË,Ù3x„ÈË„ïøA'çN,5}§iòõöŸ%¾·%ñ´µõ#-"Íg KFV+ñeÜæË¶{[M›µ0fŒÁ„lïµNG¹ÂìÎÎÏA—£S—|@Bé–Z¾¥ù-7—5;&µó ­ÍÅþŸ œyú¨v]‰þñy ߸9n£ÚXû\f„¸±ÈÈù~ÃE«cdŸgRL!øóäο)/üÇqå8tß4é÷V:¦—ÆÙdº‰£úÄ~éÁn¤žUïœ÷´ø4ñÔ™àœeïé7G¯ë±Ýv\ÇŽX˜Ê;n9ŽŸ© ùë}õ/Ë]Q£ÞIkl‡ç:ÈÃC—{‡´ š$~Â>òÕí6^¼è}¯.‹óȶÿ”å ¬]uãhÐýM­ÈSu ª]ú?hH kÛ¦uòì-d»Só_»â»¿áá_gsÍǵ´ÑìÿÇ×UU×ù×ö£mµ§òwåW—ü£¬h¿¦55=Á¶Ó'‘ Xà–e1òañfud¡­jÊ2i³´²ê1äðã‚®@]7ølAçîn† é´8ðÎg-ÔNÛ^ß}„—P±Õ4?ù:¼±•u‰o èÂæ;¨$òŒ3qrV$ü[øfv Øõ-A9ŽxŸª<&$yí}îq2âžV1 R2L®ÅŽ?K4óožüûÿ+hùgÉ4»KKxÒ}2OH[Ë'¤gg’I*¨¡¸º“N5®h{3±´_Éž>§ÓÄMK{øhÏ‘æ;vúþÓÕ~ÂÁ½§jå{Ÿ“!—ó3UòO—í¦ü̲ æ;Û™â²ÓôµG/a>6&V^­Ù¼6­s[g±ks‘¢—îãe)÷›Ûé¿ÁÝΗlÏKˆT}r&„{¶ódJüÊò÷ž$¸´ÓÄöšµ ås§^GéΊRÂ…”Ššu¨îk;_Ùüú%:”%ÊQ6îÎíŒZ¢DlHs‰æÌsFí]Ф¾aò—–üÕoõ}M†õ@!$u¤©_ä•hëôÏÐöž£K+Å3»â9W Ã¨’"_Ï›ÈuoÈkË׿§?,uÙì¯cÝ-f”Å%:•KˆèíÁÖž-®›Û,:˜xZìBQ=@±þ”ýàûƒÊj½–ž3Ǧ™¸þ¿×óFè?óžmò}Úh?›:$¦E¢JÖ)ÙA¡s¤Rò¢e<Ä×{¥ÖDåìü£ú¤Ø÷_Õt¯àáãí¬Úypj`o¿ñ±ø=óË>oòלl¿HyoR‡P·õmIb' ’&£¡öeæ}£ÙZø3ÀÀùò>ãÈü‹OªÇ˜\$ üßóü_—¾N¹Ô¢uý5w[]"#½no!ËÕϽ|Úû)ØG´uqú#ꟻ»üî_oGµuÃOˆËøŽÃßûwüãŸåüš'5”-¯ùˆz‘< ™#²fæµ'zÌxÞ#Žo¿àÛ£Qœi±ÿw‡m¹rÿcôüÜÀÐøpñeõOîý¼þOnÏ|óõN Uî}\\Gßéâ뽤‘Œ!í~꯽ì¾Xò7–|«åø¼»¦ØBÖ˜K––$v»jO9#ã,wßnÃjgÚ]µ©Õç9§3Å{Q>Ÿ(÷S¾Óh±âÇÁ+ï÷±#þPAä/9k>cÑõRº.¬®£@[nCY‰I}F¨CÈ'À(™¸í¯jåÚLxrcõãÿ)ŹڎÕ×kÜî=e >iN2ôËøkö½/9nìUتCç'è~yÐçÐ5ø=[I~(äZ,°J ,LAâË_‘‚Fm;#¶3è3 ¸£¤‡qü{œMfŽˆpÌ~ǃùKÎ~qÿœaójùgÌ.¯ùc¨ÈÏm*B+7Å=¸$ð‘kûè+Fê:«g´cž›·´þ.Nhó}Ǽ6_´<¯I“K>rè{ßhéz¦æ]ßTÒî"Ôt]F/R ã£Å4N(Aé ¤mÐç—ñLÆC†Qb ¾xüóü½“O»ò|¶qj“] sNò¹ϧÈÜå[уÉC]¸±P»ïÔö&¿ˆd¾žuÂgÊ_ÑüsÛ¹§$yw0_ÊÝgZó?æ-§ŸïµE!~^ÅmçËØZÊçU²’"¶ð]Õ«"òZw¥ |ek²í<0ŧ8DyšˆÆ7=HîŽL lß@ú³È¾{ò÷æ.€žeòIJK¦<³[†š…ÃÂÜ[á~Çbññ¨V»C“M“ƒ'7"22à‚ê -®cY­¦VŽhdPèèã‹++TA¡1c" Ži|uç//y£þqSóßó?òö6¹ò§!ƒRÒÙ¤‰#{9ˆŠ9[KBTŠþß§û=ÛƒU ŸÞGýï÷÷üÜL¸ëÜû›Èžyòïæ?•¬<ßå{Ÿ¬iZ‚r¨%‚A´Ì ž2!Ù…~U9Ó¸Ìv*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«‰MêqWÁž?˜úïüä—æ·äÇå¤Õò^9“UÕ­ËÀÀKu#)Á i×÷Žk½R˜=¡¯†—É>œ‡yîl„,¾‘ò7’t/Ëß,Ùy[ËÐúvkñHÔ2Ï3y4¬«¹Üý€žA­ÖÏSä™ÜýžN|cB™b¥Ø«±Wb¯/üýüÉÔ+ü‚ÚÎ>¹¨]Ã¥i²MÄÅ ó¤’z®€…Hš•Û•+µssØ]^~} qpéö°É* óò³OÕüåÈ?2<Ýigù¹o$‹¤y¹Ü[}bîK—¸Ž×á ÌŠQ8HG%Tì»?´å ó81“„ýPçBªÿù†ÛÕü…ù/ç{Ì‘ù¯óúêËÌ3鱨è:p *#G2Íõ™Li3UiF _‘åÐwl`ÇÃу#r? ¡ÏötL`I¹>…ÎYµØ«±WžyÓó[òÛGÔ.<‡­yŠÂÏÌ—ð< g} ·±µÌDF/ «’I’Ÿpsk£ì½Dâ3FÄcc·ózüa)ŽO—¼»åWÿœ`üÍÐõ¿Ì‹}S@Ôí¤KmnÅ'–=*ñÇïDHô,P&©ÈÆÜ“pË–£Uü«¦”0Dý&½CÏñÏŸ{@w×¾AóÞùåØüÏ¡Gq›,×Eõ¸L.â sPj °c¸ pšý ôÙ<9ÕÐåæäÆV-“æ]Š»`¿›ß—6šFÔ<³?¿+õ&å¿Ý±bb{+T£ÿ’Ç6]“ÚIœd¹sÆÅ>)ò׿'ç…î•ä–ƒyú*])îmî$åõkèaŽB²A%Ã1eX˜@=6Ü gwÚ:} ÖeBUæ éCÏÏdè´¹u3±ógþNü…òÞˆËæVý=«“Í„À‹Es¹¤d’çÄÈH?Ê3†íomuî8u/«çÓáó{ÎÎö[VOÞKý˯Çäõ˜ãŽÖ(‘c‰TDUTl`3Œ”‰6y½8 J®ñ:Fæ)HI Qˆ j=ñ‰‚E¬#gÉVžuüÊÐüé¨êW÷ÓjwúJº®Ÿ,„C%¢J#›„J*ƒÅª‹·Ú¥ÏhËÙŸŸIB"Ë\q*±góæ|¹ÓæûGY‹Q)JFGÔ:Uï·ê÷³ÌoËÞyÕ-5K9ºf§y5¥ôMÇœHóZ$±H»ñ`$oÀ¨sEØLúzÈHT¡(ùí:#ËoÐí{cS‹W=4ân2‘ËxØ?4_äÔ¾\ó'™?+µŸ‹Œ’Íj®> cÓ–ƒÂH¸8ö)ö¿Ôéðë±÷|¯qþ–V}›™Á›.’}û~Ÿ˜¢·òr¾Sóÿš¿.ow·”¼–‹&áÄñÛÆHd ÕÉ{Uþ¢Á¬1Ïãú¤+âgÿÁõYtÒåÓáúâW~Wùþ¼ñä0i· 勯1Û^K$nÖò¼k$.Â…ˆ*êE~ÈÈûEÛ#MªÃ1âÇrßÔ¢>câžÅìÉŸHŸ\¸óaø2_ÊʽCÉPyŠÛ^šÞê\Eo€±oB/YX¿5æ$¯LÕ{Mí$5²ÂqŽÎýç‡î§aØ]‡=(È2DöÛ»¾Ù/’¿.4¯%è7Þ_†ê{û=E®ÅÁ@¤É‰ø*( eµ'5]¯ÛÙu¹£”ÄDÕy~nó»"\RÆ —;÷S¬?*?.tÚ}_˶OùiV»ÿ¨–“þÓkòsÍ/‡§ýÍ..ÂÒC–1ñßï¶Ugac§EèiöÑZAZúPF±%zWŠ3O—4òœŒ™·g`* äˆÊ™»v*ìUØ«±Wþqy;_ó¿–ít Cv·S¬ò4|Õ"‘© Àîýé?²½«ƒC¨–L·F<"…õ©Ñ{AÙùuXD1ÖÆ÷÷Q”¼¼!°7šU•Õí„Á ÜÖÑK*ˆP"ñ‘×¥6ÍDûS=ˆrŒdI H¿•»è1Tx¡b²íæ¡æÿ#ywÏqZkÖìæÝ™í®"sЖ7ØÐTFÃÃ,ì¾ØÏ¡™–#Ϙ;‚ô;3ª d¹¡Œéÿ’þ^Ó<Ï¥ùšÖöòIôÐk Ô¿Xõ˜+…vwÜXtÛnNm³ûYŸ.žx%>±\º|>×]‹ÙÜXóC(”®=ûß5¾Hü½Öt/=ù›ÍúäÖó¶ª\X˜ؤsLdd`ê´*5®ØíÌYôXtøU÷][+Ù½““«.l„>Uæoõ1OÎOËWúݦ‰æHoô9ìciô4E–+ñb‚8Ï&@@«Xt¦çsì–ŸQ ²á0Ê$jx‰£[ïg‘òäC¬ö‹6äÊ%qÉÒýÝßh)•ÿ3|ÇkùeæO2ÝÃÚ½¬ÖövZÇ ª÷2Ja§!@v…hAa¾ÀæOhû=§—háÃD$ ¥ ú@ßÓÝÄ{¼ÈhÑvÎhè²å •s½·ïáa+æZÇFý9wæŸ0XùÝŠÝÛ[^,§O½‚GDU, úd8.¡;JßžÎÅ“/…¥ƒé&5Ç;þ;lo«§ÜÇâ¹#—˜ød<¾ï³èüʱÒ/tŸ;yŠ'C¨{kuÞi¾×¦®@¥8«}‘žl=ŸžmvM6ô™n{‡Ø=ïp{b8ôÏ}@l;ÏwÞŸh^sòǘý$Ò5Kyîå….>¤%ArˆëË㊼î)¶ku“¨ÓYÉ5Å^ŸŸ'7MÚ8s×$]^ÿ%Þjóv…äÍ0êºõÇ£`‘F£”²¹ý˜Ó©#©ð;7²ók2xx…Ÿ°{ÊuÚüZhqä4>ÓîW»°Ð¼Û¤Dº…¤Z†•yM\DwY’°+PõØŒ¯|ÚL§‚F‰­w»ŸÜÏ&,ZŒcˆ F[î=¯þFêº÷ø‹ò³UšÃPŠ­‹Ìcz«Åwù%Ø÷líô^ØbÔCÁ×ã‰þ*¿œL~O'­ö^XåâidAþmýÇõüØ«æWÍ^~Ð-¿:¤’ÇMÒJCyÕž:ÇÈÈÎÑ'ûø…WxÇÙÝFÃ:=7fbÒhržÌRɼ}@ïË™þnä×›ÍçÏ<šˆÇUqç·ãŸxèû[KÔ4ÝV ýâ­6eÞ{wW‰”l8•Ûn”íŸ>êpdÅ3 €ÆC˜<Þ÷HÎ ÄØòEå ŽÅ]аÿ̯Ëí7ó#ËRhW²}ZåO§ß*ókyÔŽJA*Ë]Ǹ7¾ÎöîNÌÔ ±C”£Þ?_qýhhc©ÇÀv=qyß-ÿ;ü™¬Ûi¾t’ßËÍ: ÖçUõíЂ£““¸eR KÐûgSÛ™;[†SÒƒLȨT÷&[ްÞún³Cfˆåß}»¾h]gó·Gó̶Ú?’<Í7”uˆ®‰‚ÿU³êWà+(ˆ·)$5eAò®]¤ö;6€K&«Ô@ÇxÂGŠ}/üÒXeíˆg"8§á›ç!±òëö³ŸÊ?ÌKï<Øj–:å´vÞeòõÏÔµAnko+U•dŽ¤Ò¥SÒ£cAÎûUØÐNÄL±f/˜å±ùÀv—¯–xÈHT h÷"-?6ü¯ù‚ÿ—–>µÎ£?;ØSÔ¶Y⤄²Ô‚ª>&û ü5®U—ÙmN=ÖJ£~“´¨ò—Ç»oÉœ{S³ø#sßÒû™îsNÉØªKæ¿*hžtÑ.4 ~ÜOc8ª° ’«ÒÏK“†\º÷Ø—¾aòôÞS¹ó3HšŸ–Ê[ÉÞ3x—ž‘gãæj8Óçœ|4ùQéÖûQabŸù—Ì7^v‹Ëz¾±£Kå_ùÆ»fÛLµÓm¡õc~RIq0†¥Íóuû$…Ÿ“DÓiÆ8Æ^&¨ÄÈ“÷ üwíN17îf¾Y»ò]üä_–¬¿!efÐ.¬Ý|×ohÓ¾œÑª9,}S¹QÀòû!øñ®ÔÃ4»>gWõèºâü~†B¸½/®mo¬¯LâÊæ+ƒm+[Üú2,ž”èh߉lO!ƒÿ9,ôýv-6é¡ÒEÊÇêÙÛž0<«*²Ôoé´œ¨FrÝ©¬Åãøšc(q ëmÏ:ý>mЉª/U··‚Öí­bH-¡UŽbPˆˆ¢Šª«@Í,¤I³Íš¦v*ìUØ«ãÿùÊ?#_y'Íš_çg•#ôÄ“E¶ˆQr«Â9Øž0b“¦àw|íýŸÔCW§ž/"=>ï׸ýˆÇšX2Ç,9ƒøù³o.kÖ>gÑ,µÝ9«k{‘Vµ(ÝÕSòÏ3×è§¥Í,Sçø?Öôš¨çÇ‘å šf’ìUóïæÕ±ò?æF‡ù\ôëò Õ#ãÉdྌÊÀíûÈ€êNz_³?=Ùùt„ú¡¼|ºÇå/½áûz•ÖCP¦[Kî?8¥þbü¡Ö4¯:hú¯’­ÛPòÅÕä:„0£NЬ‰#,@àT| ZÓáê9:j1eÒdÇ©<czËb>}ããîÇÕöLz˜OâÆd%ý^_gwÉëŸåŽ£ùcçè拾»³HÄ–Ð"ÿ¤I$ îÕØÆ}6wÎ3Oí ñèe¤1'sÐáïÜy½>nÆŒõQÔqGA×ð6déåÍ 5™<ºt§%[P1«OEOLsR¿÷lÔ~cˆaã<øonwËÞìF“ÉâpŽ>þ½Éžb9Å]Š u kGÒW–«¨[X¯^W3Çûäa™4™rÿw KÜ ûšrê1ãúä#ï 1kïÍÿË}>¾·˜ ŽÖË-Í~Fqøæã²Ý¡“–"=õ¼‡[—·ôpç|,ýÌzïþròöÞ¾×®éÓѶ¿ò9ãÍž/auÒçÃ|¿P.Ok4‘åÄ}Ãõ”Ïÿ91å•?èÚ5ü‚§y íØü.ù›øj:äˆùŸÐY{e‡¤%ö~´ÎNiá.LW±7h ãÓ9xÿäÿÕ‡ú_ÚÔ}³‡ú™ùþÅ¿ô3¶]ü·/ý&¯ýRÂàw/õaþ—þ<¿èÎêgý7ìT‹þroK$úÞ^¸AØ¥Ôn\„¿ày“¦Qþ”þ´ÇÛ8uÆ~i…¿ü䯔ŸZÒõ(‰¾š[ÈúeM³ð?Õ¦p?é‡ûÒßltçœd>_­:³üÿü·¹§­ysg_÷ý¤­Où$̾ÄëãÊ1—ºCôÓ—Ú¹’=àþ‹dzæoåþ§Akæ+ ÍÑg˜[±Þ”~¹ªÏìö»Õ†_Å÷[Ÿ‹¶t¹9dÄ×ßLžÞêÚî!5¤É<'¤‘:ºŸ¥I©ÉŽP5 Aóv0˜°l*ä;Q¹µµ½…­ï ŽâݾÔS"ȇæ¬ÉãÉ(‰ ù1œ#!RÝkË:6» \ùnîÙSJ¹Ó1B«§CÉZ0V†Ýs/IÚpg¢}`õÞýþ÷Q¢Ç—ÄG¤÷<çIü¯ó¾›qc¤]y–ÛVò5“ÿÇ2þÍei ©ˆ«Ø)¢þòŠw¶u¯h´yc,‘Ã,yä>¨Ê·ïý~ûÝÅÔÀÆ(ž(ÿ £{w~ üÁÓeó§æO—ÿ-,­ÞÏËš4 $Áchã„Vs¥8¬j‘!è‘›>ÃÔ gåÖȉdÈvë¿KøÜ“ƒÚ¸N«YKP€û<¾›4Ö,ÿ-?(Q¼ÓŸ¦¨ð=¥¬.æ[ª•n(®ÍCP9IØëÓ4:\½¡ÚçÀ32ñyGŸ:û¶ÔcÑöoïDjU@gñÞ“ùGÉš¯šuSù“ùž¡$@dÒtYÇ, _ˆ<¨û ·úÍ¿LîÔílZ\_“ÐÿŸ1ÎG¸ú=ÃgAÙÓÔOóZ¯óbyDyþ<ËÑt:ùK^½};GÖm/o`†eg`½JÚ¹Zç/ªìVqäÇ(ǼÅ|]öÑÁš\0˜‘÷§Ù®sR/3ù?˾p²6:ý’\ Ò˜|3Â|c‘~!òè{ƒ›Îí\ú9ñb•yt>ðáë{?¦<9#x÷ŠÜùSó+òNö]sÈ—²j¾Y¯©wdêdþZ-Ԋлb¡øŒîãÚ=ŸÛpµQËÒ\¿ÒËýì¶÷¼V§²µ]žLðž8u¬~‘ö=›òÓó·Êÿ˜h–$+Ì”øôÉÜTRmäØH=¨xS|óÿh½ŽÔöq2þóó‡OëŸw›²ìîØÇ¨Ûé—wêïznrÝØ«±T6£akªé÷z]òz¶W°ËmsØybÉ5(G¼nd€œLO")ó7¼‡ùƒä*'4;[_4ùSX»d²šK×ÚtÓ8ãY„BÄí)SM÷]†zçcöÞƒ]ªüÞYKlqõ?DÀò«5üßw7’Öh³àÅàÀ ÂGm·ã¿îCjòþUè0þQùŽ¥ù®º¶½kG6òJ¼}i¸e^çì-_bß Ø0ÖÎ{GWèÓbþî2êñ+ùš!¼'3¤€Óáß$¾¢:yÆÜÞ¹ùKùw ~XØ-ÍݼþtÔU[Q—Õ_Põe†b‚øÒ¬w=€áý©íüý©>(ÆC>‘[{äyYû9w“»ì½4±¢GçúƒÓówÅ]Ф>pò~…ç}_·õ­%ø¢•h&‚PYbbZüB$f×±ûc7gçqúŽ’ÅÄÖèᨄ¿±â?•ÿ˜>aÿœwó‰ü·üÀ•§òôœôý@1Zú­µÌ5©ôÉ?¿ˆ}–« šóöŒøðvÖ˜jtÿÞc¯õOŸqê>Ï>Ï‚zl†üy¾¿¿Ò|³«yuôÍBÒÎëʲۯ+i&²6Ê¡ö¨”Ž”g ¹!“Š$‰ßÆÔOüåù­åæo!Î=iÖºýݶŸ®yÞŠF­s'¦‹Å —ïXô cµÞ²òL ÚÉ Ž?w—èù÷8ò˜åC§ézßüã'Ÿ¼¡åÝ;]_0ùÏ·‰o¬XMk^-Ñ’+qs©i)Ê`UKhÃry L™aÚ¸2NPà–!é7µnk»£ 8ó}=«y›ËÚ Îe­jvÖz¼ßVÓ!¹™#{™¶ø# ENà|ÈHÎ;›&A#’",×Fâ@H¿3¿.´_Í)]ù_Xÿ{az4–—HŽdéâC üJHÌžÍí é2Œ‘øŽñ܉ÆÅ<_þqwó[Zü³óuÏüãÇæ{›sÁ‡ËWr±áć’Û+µ+ À!íÏó?¶û“U øÆHÀœh¾Ú̆Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å^]ù÷ùŦþLyã_—„úýákO/éìkëÝ•¯6ƒéÄ>9Éz°Å >uÿœdü­Ô§šãó¯ÏÅï<ׯ´—:[Ýo*EsS%ÛW£Ì ƒhúlÛyçµ]±Ç/aõyžï‡ßîs0ã­ßMgÞìUتòöÖÆ5{™â„Êë i!$Òl‘©n¬Ç`ù(@ËW…ySþr VƒÌÚŸåÿæ~–üê%›ô–f‡M½W,má{’²q®Ê³(*þ¾Òê»s`‘ž?âþpï5ú:{š†Mè¼ãówÌ›z—“uO*þo~_ìù5Ö•æo/òš++ˆjb–EV•xLmÍ£< Ú¹¶ì>’9£“Mš#õ{½ýwa2jˆ{_üã¯æOü¬Ë‹+‹Ù½O0èôÓu~F®òD£Òœ×sêÇF'ùùÙÏ{AÙߕԦ[Çõ|ÙM¸åaë9£fìU%ó™ ò–5O3ÜÚÜ^Á¥Û½ËÚÙÆež@•GnìÇec°Ì&œæÉ`ÄktHз˜ùó¿LüÜÓµ/þ^Zߦ¾ú ÍÒjCÂ×OÔ¦£‚ÚYIÔñ+„±ëMÆ~Å–ŽQžb8xÀ®²S]ÌN.O’t­CËsiñyͺ4ß”c–/ÊÐiwj^a×ff¡ÔnQUÄ(üCÂ%V+ð§lîrãÈ%ÇŽDÇ'9ñCú#¿Î½î8#«î-ù2Û^·ò¯¿04;#ù§YßE"Ù¼ÇÔô• 0¬U¢–åŹ"¹ç:aÆrbÃ#áHüüþ?ÚåÝÍŸf±“±Wb®Å]Š»J¼ÏåÍ/ÍÞ_Ô|µ­Eëiz¤mp‚œ€q³©5£)£)ì@9v›Q,9#8ó‰´añ/彯©ùWù…«þPù¡éÜ1Óg5ò N•è·q vj¤çQíVŠ:í,u¸†ñ¯wütýEì·ixY ¥Ëúß·ï{ÎyƒèNÅRígAѼÃo¦·eý¬2¬ñÃ:óA"‚¡¸ŽÌEei5¹tò2Å#EXîhÔiqædˆ÷GEpF‹1¨Hã@UTP*°t);’Ý€(r_‘JQÕtÍÜÝê×°XÚŽ³\Ê‘%|*ä åø4Ù3K‡LpÕ›<1‹œ„G™§škßó^DÒ¹G§5Ʊp*Õ£ôá¨ñ’n;{ª¶uz/aõ¹wcfÏÈ_ÚCÏj½«ÒãÚ73åËækÎ/Í?4íäÿ,‹[Y>ÅËE%Á¾“Ó‡ï\ßãöC³ôÿßå2=Ö#ö —ÚëÇmö†«ûŒ4;蟴ÔPíäïί3ü^bó+X@ÿÞ@—,½â«0±ø,̆£²ôßÝa=õúee¶=ƒÚšïrðëýÛíDXÿÎ>èêÞ¦¯¬Ý]¹5A#‚§Ü¿ªry=©ÉÊß¿êrðû ˆo“$¥î¡÷ñ2[/ɯËûJÓžéÇG¸¸˜û}”eS÷f¿'´©{€v¸}’ÐÜ ½äþ‚{mä_&ZSÐÐ,íb‘…<Á9‡>ÓÔKžI|Ë²ÇØºHrÅô ýé¤:F“l)oao¥)¦Þ˜òÔd—9ñrá¥Å¦|-UQB  £` Pòʉ¶ð)¼ Y$0ÍA4k 9¨j}ù!"91”æ-?—´  EΕg05¨’Ú¯.¿iO\º:¼±å9‰q§ Á?«O¾!(ºü¸ò-å}mÑkþùÐÿ“%s&¯©,‡ã¿ÞáeöE>x£ð÷S¾üŽòØ?WŠêÄžŸW¹f§üfv?i5QæD½ãõS¬ÍìnŠ|„£î—üU±éÿ!®leúÏ–üÉ5¤ãìz‘²7·ïau#þ3G´±˜¬¸„‡ã¡¯'±ðæ ùÒè\¶ßóVÞÏRý7j›²¼±Ý–Çëaeÿ5ÌyéûSõCÃ>W÷>Ÿ›D´±¦úeâx—ûª?$]§ü䘴YVÓÏWx$èÒÀ%¶jâ+€Á¶ðp37°¸rŽ-6o©}±ýL#íF|'‡Q„ƒñØ[ÐtÎËÝŒiª >å¿ÝŠýXŠÿÅ„˜¾çÎc[ìž»O¹‡ìú¾Çu¥ö‹I›øøOt¶ûy}¬ö9#š5–'Y"qTu!•îØç;(hów@‚,.È¥®*X5  MÀ4¨¯Ñ†Ö˜*þYÙÝyê:ë·²jÎ?DØÜ*ˆ¬ŠÔìÍÄî› “Vø³¡>ÐÎ:1¦Åùòåøëò6tñ£-IÏ’FÍ”?^ìwþr&ÿS´ò<YKKËÈá¿t¯÷B7uF§ì³(¯Êógì&sÖ.q‰1÷Øßäà{[–qÓFTX›<¿ùyå_$hÞiòn¤©æÈ^ÒkK¨î̳\ɱ¼™WŽä€ ²zçGÙšív«Y“¦º"@Ž*]oÞ{ä×i4š}42à—ïosß·ìòz瑵{ý È:v«ù‰¬F—7 %®‘2G(å Lƅ߈äkñoNÙÅvÆ–õ³Ç£ÆhmQ³¸æ|…ü§³3Ë–3ÔÏsÖ[{‡™ûYf¯èž`€Üèš…¾¡ š;[ʲp'³5SìsMªÑfÓˇ, ˜§g§ÕcÌ/„‡‘Ls½äÿ˜_’zW™õ¯-2èþdSꆎ©oq Ü º=wõuê ß;.Ãö¿.˜xy¿y—˜¤yƒÌö·³xóúñz'öÕï ‘<õï(jCÉ›ÐËÄDpë.¥¥Eè¦~5õPö•*|yuöß±X5˜ÿ3ÙÄoÎ?Íþiþ‰øS¤Òö¶]<ü-H Ž¿¯¼y¾µº¶½¶ŠòÎd¸´VHg‰ƒÇ"0¨ee¨ Žã<£&)c‘Œs˜zxÈHX6r Š»yDß—šå~Ÿç??yvnüÇ%­í圗lnÔúFFT-RÀ½Y™ªÄlOR{Xvö~ÕɦÒf"8Ä£píŽoðØV×½:S †–92ÃyQ"÷§Î:^ƒi„>süÅŠëQÑ|Ïíiæ[+‰d¸Óµ(¤‘i˜¨4jíöz0ÏVÔë¥)6ŒÆÀEâN§¸oÓãÌ<®<DeÍf3º;Æ^o¥¿!üɬkÿ–¶:‡˜åi'†il὜üWÆá#fcNG‘ôëÔ•Þ§<“ÛnÎŧíC @‘ˆþEŸø¯+îzÎÅÔO&œ÷Õ÷þ9=?8÷pìUØ«üÆü¾Ò?1¼».©Üu“M¿ Y-gÛâ*ÔâëÜxßû;Ûù{38Éâv”œ?XèEºîÒìøêqðžc‘ütyßä接är_ÈŸÍ:, íi¢]\Ñ¡_V¼m™¤”û†>!:Öû_EY„kt¦Ákïòþ'1–)sCßo¿%¿.®ü‹yùyo¤%‡—oÎÂÐð.yr[+rbêvRõ~qÛ9ÈvÆ gŒ®C¿•w{¿·›.TùÛÌ>\ò?äšlN’º§ææýÌkþ°¾ ööJü¢ŠfX—”Œ(ÁXôý›:½>£?hâ<\8p¨Žg¼y~9´"{Ë3òݾ—¯åÍ;þr3Z²Ö?3ouA¨ù_H þ¦‹,ꌱÊöαð‘âŒG©NcáçRF¿Q)NZ(˜â©Ÿçü÷ÚÍžuÜÈK›é\ä[žÿ9+ù40¼¼¾fòì$yãAC%±‹i/-P—kzË©øá÷ªþÖÝ/³}±ùlœ>‰}‡¿õþƬ°°Î?ç¿=Gæß”¯ÎŸ|¼‰¦€÷¶ÿb;À½Éû3S£ï°uêN ÅÅ]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±T.§©ØhÚuÞ¯ªÜ%¦™a —7—Rš$PÂ¥ÝØø Å_i‹¨ÿÎZþvÝù·YŽH¿,<°Ëœ‚Šöêå¡·#qêNÃÕ¸ð_†¿c9ÿh{_ò˜ª?\¹yyþ¯7#;/±Q$XãP‘  ˆ U€:žPM¹â®Å]мßó¯òïÊÿ˜~Rú§™µS¡>U¸Óµ†œE ­ÓÒ(ÚEvXÜÁhÔ;ü,¤æÛ±»C.›-ãósãvˆ#wκÝô‰èþOÿÎLÛ1©_)~d@9¼B€+I1¼Œü"B~.ž¨¯ï«Ãz þ¾/ÙÐ÷}Í'ºOlü‹Ó¿6|¶Ú‡”|ë5¶³å 6(_Ë^fŽs$·PK¼hŸh´jƒöÈ)²‚èT¯=Ûy4¹k& c9}Q®GõýþE·#bïÉï˯4ùÎþ}ó×™­­ôñ5ç=Êo^/J ‹—`%ùUv »«ZcÚý¡‹&X±“.¼Žß‡êæ°‰—³g>ØìUóïæçüäO•¼»¬j¿—÷Z>§¨éÉÚùYÓ&ú»X-üC‡ à|OÅÅ tØWqGe{?—$#˜J17qŒ·ºïü©äfiùeæ$ó;þqz÷üA¢ê6©oªé³£%ÑPÔ‘]à©çS$|‘âzñøIUØÏ´±çâÁ¯b/¿àw0à#x¾‡ü¼ÑüÏ—ìoÿ1–ÆïÏl$k»Ë[xÕ¡IºAê.ÌcSÄ”¢üþÓr½¡›ÈF ú~ß‹tA­ù³,ÀdìUFòòÏO¶–öþâ;[8G)®'‘bŠ5ñgr3’„ eVØê¥ª^é—PÞÙK_NæÚDš'¡¡âèH?~3Ç( ù­¢2*ìUØ«±WÎó––3kþ^ƒó@—Ì~X®ÚIdÓÕ½BõÖ¬ƒÁKçWì¿hˆLàŸÑ“¿¿þ=ËäÕRÂOùgçX¼óå[mM™F§ú>¥ý›„­Oqó§lãý¡ìƒ¡Ô˜ Þ>ïÙÉõ>Æí«À'üCi{ÿo6cš7jìU‚y³ó{ÉRõ ¹¾Ú’mõM oj„OpÍ_lè»3Ù}f®ˆ -‡Ã©øK®íý6Ÿc.)wGØaqù§ù©ç×k#é¢ôâJ›Ú,JÐÖâp±ƒNȼ‡c–e»?G¾¦~$»¹ô£™§D;W´5Æ´Øøcßÿ;|·[cù#©k¤¼÷¯Íyvô/.Ò¿ÈÏ=~T ò9›?hqៈ÷WØ?[™§ö2y§)‘îÿ²?©è:/åç“t-§é0™Ö”¸œ}bZŽá¥åÄÿ«LÒê;WQ›ê™®á°û£GØ:M?ÑŒ_yÜý¿¡“ôØtÍs·v*ìUØ«±Wb®Å]Š»v*ìUØ«±WbªsÛÛÝDÐ]D“Àû4r(t?0Õ(ÌÄØ4XOf*@æÁµßÉï#ë\ž;#¦\µi-ƒzK^ߺ ÇO’ŒÜi»S‹œ¸‡ô·ûy¼ö·ÙM}Äxôvû9}Œ;þU¿æW’Üù_k‹u<¾§ÌBXûÃ1hæHùfÇ'ihu¢µ8…÷óûEH<îOfuÚCzlœC»—Ø}%5Ò?u­åt¿ÌMX']Õ´fr0JxµzòGÀf£Yì>,£IÝ-ÇúaËâ>,q{O—¸5XÌOxöÐ^¿å¿9ùcͰzÚ¥ÛÊHá<ëÄôqó¥3‡íÉÔi eŸCî<žŸGÚ8uñÈ¿åÍ>Íkšñ?=¯Ÿü½æ-CR¼±9ùTÒŸHãQknj=8Ô•d=%âj>ÑåB;îÆ:FB2ü¾¢Äÿœ}ç˜?ͱ嵼‡iVÒ”£ãaú{¾»¿ç»òG"óÇ!Õ­¼¹&ä›I¥‚wšapñžB1$û¹sNAvT÷5nƒ¶;lèt‡³ ¹åµŠçQå]/r|¹i»7²†«R&1øx£ÐÙ¿+<ïìiÇæîªù—óJÃËòÜÛÚÛÇd’èñß3-¤ònîŒE22”÷ …ì¾|znÍ–Q"eSáú€è~ßĹ]¿†yõ±ÆH‡ÓÅôŸíä§äÑ«Aù¿¤AiåïðÍÀµš=zÎÙ‰²¸HÖ@ÓFWnP‘Ì ë\ŸjøR켆Y|aÄ2~¡ué>|û¶Ggøƒ´ ?Ñãé<÷\¾/`±üÎòÿšoü¥É[ëyÜ8ÙÝ"ÉZU âyR§a\áó{=©Ç¦Ž ÇÓ.ŸÅäkÍê±vÖ ç–w^ž{ù3Ñ»V;æÿ$èwÓŽŸ­Û‡eÛ]¥xþÔoúÔì{ŒÚv_kçÑdãÄ}ã¡÷þ-À×ön-T8rqê=ÏÓ5¿>α廞SXp‘*Y Ž4>jLîµz½tqá8”x2§·ëëÈw‡Iü•‹”øˆÇFây<¢dó‡ç¬‰åï!Z'—-t"´3EIèÒ˜•‹Ê~Ð@ ÔššžÒIØ#ÆÕËÆÕeÜÖæ:¾Qé{qt(iˆË¯ôb¡Ëñß÷=_òsó;VóN¡«ù'ÌÖÑ'˜|¸)/-dy!¹Ky>¬ìÍ#9/ÈË—ÇZÐgío³x´˜ñê°áæß†@!Ä9VÕÒ¶ów=“Ú2Ë)b˜õC¨ë[~;Þ»œ3¼v*ìUåß_•P~bh\ÓÔGæ½1´é¶_]Ämœø1Ýì·±lí}ö övn ‡÷3>¯èŸçÓåît}³Ù˜‡~¸ý¾_©8ÿœiüê›Îvy Î4^zÐÐÆ­qU–úÞÁ‹rßÖˆü2ƒ¹ÿ;h»a#6-ñÏ»¡? ôþÇ‹Ç>‡›Õüý k:ž‡yäÓieçèí%·Ñu‹«t’HŒ­$jì Pái]À4$f“Cž˜lã¿TAæÎC»›äßÌ/ þ]þTùnå|Í®^ù—óïU+qcwewp.-.ä ¬´W…jj¼Ÿ°ö{»Q«È<8ˆiãÌ(ÇvëD¢"<ßU~QŸ77å·—žùÿЍú÷¬IžœÛÑ3rßÕô¸zµßk¾q]­á~b~Ñ{~šò¾^MðºÝšf½“ä?Î.ë¿™Úgç·"¦—wrFµ`µ‹‰ªfŽN#h®–»Óá“~¼3Ò=–í Ϫ#o8þϹÅÍ«íß#ùËDüÁò¦•ç.ÍëiZ¬"h«Nq¸%dŠ@:ü¾Ñ|íy£]ü‚ó¡ùùe¤pÌ&@³hâX ¶Ïo8õ~±ˆj@*À Àí5ù±ãÅ d/Yó·ÞÆÞûý," ðó¬4 KòÆ‹cåým¥iÐ¥½¬ –âˆ;“RIêIêsˆÏžYfg#fGw Lr¥v*ò>~}~SygQºòn¿¯M£"5µóé©pïdeR¤´öàð‘k_€–SÛ7zÃÕeˆË æ.·øŸc dg‰y=5Èß0 þØyãò_óã‹OÕ­ úä’“Ó‰$D›<^-ù/Åá“:-YŽ¿>|<ÁÛñïù÷µGÓæ è_Ë?Ê.~U>¶<·sxözÅÂΖW3´Z"-q/C¹?UŠñíSËv—kdÕðñqÀæÝ½5lŠ õ=_JÑmþ·¬_[éö…‚ îæŽù‹ÊB¢§Ã'æj “庒ùþr‹ÍÖÞhòY׬Ÿ_ü¶šÖîò.¾¯g¨j|Y õ®#`=4åT6ÊÍJԌ콙Ó‹/àË`]YŒzÐïæÑ”î;›ÿœl{/)yÆïÉš5ÂkÓjöŸ¥õÛPúƃ¡ÏéZÂi/­.è'­Óo‹%öˆØFYÃ!SŸy<¨yWÞ¸¶4ú¯8¦÷b®Å]Ьš®"’ ãY`•Y%‰Ô2:0£+)Ø‚6 áƒa_ kLßóœóinY<…æ:Ii#r)´ŽxTšÕ­œ”mÉày~ÐÎã[„vÇgñï±}ýGùÃí÷;ÃíÊj7>‰ìAø}ÌÛοœ~Qòp’ØOúSY^–Œð–]Õ>[·ù9ÅöG²š­eJ¸!üé~ÌýÞomÚ>ÐéôÛ_»‡é=>ÿ'–Mù»ù·¼múÊòý¥íâ’3î+,Õì+á¾ÏìÞËéâäûŸÕ½ÑÃiv¦ã÷xÏÀÓ/¹–ùgògÊZIï¢:ÅúЙnÀôCå€|4ÿ_–bë=¡Ï—hžåÏçú©é;;Ù-.žŒÇ‰/érÿKËçoCDHÑcBF E@Í7¹z€À—b®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®ÅP𖕦ëÍgªÚEyjÛ˜§Eu¯JŽCcî2Ü9çŒñ@|š5ly£Ã’"CÍåšÿäuªÏúOÉZ„šN£ç /#˜Õ»zs)õçñgG¦öŒ‘Áž"q<ÿhä~Ç×û ãÓHÂC¡åð<ÇÚ†Ó6¿0|u—ù‹¦É¨iäðŽøYˆÒeýÜ»vj7‹f.¯ÙM¶&zIpK»§Ëœ~y:ÈöγC. T ÿ¨ò—Þö¿+yÛË^rµúÎ|“²€f¶o‚âß¼‰¾!¿~‡±Ï>í.ÇÔhåÖ5Üzqü«ÑvŽLo¯Ë¨÷†AšÇ5y³É[ó­¢Zy‚ÐMè’mîŒsÂ[¯]è{©¨>³ìÎ×Ôh¤eŠU|Ç0}ãð\wfáÕF² ®G¨a~o±Ô-.ΑäKKËé™ä·†èÒy¬bºnR:ð·o³E cSÐfû²ócí-‰ª”b*Èä$cËŸ—?-F¿ô:N 8”+æc|ÞwæOË¿*y òÈÜùž3?ž5>?T++††v!Š*«q+ÿxÄž‡uΟAÛºhpà5‚öæ;ûìžC»âèu“ƒI¢¼»å—-ùÙ×û¥ùg¨?–ÿ.ôVó¾§ „Ó+µ©Ô.#……»1hP´¬*B@ìÈ{C€juù?- 9ð‚wêvóû^“±²øHxò'—­ºsòzíž¡n—v]ZH+ðH²ÆÃü–BAÎk.㑌Á‰¢ï1äŒÅÄ‚;ÂÍKM°Ö,gÓuKt»°¹^A*òV~ðwnã%§ÔO ÄàLd9ŒØa’&3GÏúÇ—¼Ýù®7›ü•+ÞyNfQ}e)fUBM"¸Uꢿ»˜nÇü¯HÓkt½½‡òú‘Ô}2||ûã×îàuÝ››³gâáßQÝäAüE~_þah˜º0ÕtY8Ͼ°ZÖR+Å€ê§~.6o@òžÝìý››ÃÊ6?LºH~9ŽŽ÷C¯†¦QøŽæYšG5ت×D•9žÂì/z†uèɹæO¬{ í rÃòľ‚Ü~˜ü»žC·û2ó¿_ë}!ùCùŸ¥þky>ÛÌ6a`Ô£¥¾¯§†©¶»P ]ø7Ú»ppv·fËG˜ÀòþÞ?Ý 'Äwù‡}ùcå­SÏÞ{ò­µïç.…§G5ÊI²›&>œécuô¹• ²îBïJµv½Ÿ NXáÅ‘‚rùõ®þŸ˜J…‘Íä3è¾yò—å¶“ÿ9æ5Þ¡¯Ï5¥ÕΕ<ò=µÌw3¬fÒ¦R¨þò>X8›ØæÁ›Q-‚E‹­Å|¾GõµÑŠß`ù7Ο<»gæŸ.LÓé7¡ý&t1º´ncut;‚¬¤g¬ÒOO㘢ˆÊÅ¢|ËåÝ'ͺ¡å­r¬iZœ-osCÅ· §³)‘»0!¦ÔOA81*E¾fÿœwóŽ­ùù·¨þFùÚà-kw´[É’îZ iГ@—*ni QÙ³Ù;;]Vä_°õHQ}Ý™­nÅ]Š»v*ìUØ«±Wb®Å]Š»v*ìUçß?šååî§ç ¾_"ý[G³riu¨L£ƒÄP»Ðý…nø¤Ì_óŠß—šÑÔ:¼ä^ëÌžc’vÓfŸy=)¤&âèÔlÓ=Uz|ÓgÏ<ö·µxåà@í«ßÝðûýÎfu};œ[{±Wb¨ ròÿOѯﴫÔõ;{ye³Ó‘Ò6¹™”ˆ<„*òj “–a„e0$xA;žå/‡<•ù±aäëÏ=ùçÍÖ÷WŸZ„Íc¥é×v²,VÂj%µ+é£`§‚ª'Újz>³²¥œbÅŒ§ÉŸö÷÷Ù.,gVO7Òº_å|ÿ˜Ÿ•ú>‘ùáj¾húÍ{km{bdÝK¼Uâ%Û‹7PÔ©ärö˜Óje-/¦ÜÁøww7XÝ”þZ~VySò§F—Fò´s¹“Ö¼½»‘e¹¸p(¾£"¢ÑFʪ ™'0»G´òêçÅ’¶ä Ê0äÍ3^ÉØ«Ö?2¼££ùÃJòΡO5ëA¥œhdô”Fî¯1 n(&§Â›ævÎË<2Ì¢<Ïêbd.Ÿ ùSÍ~Tü¶òÿ?.ÿ5¢Ó ŽO!(õH’F yr_‹¯wªÒåÕdÅ›OG­p×=¹rÚ»“Ž‚7}/ÿ8íåkÊ”ú&“æHÚ-L´÷¢ÒPyÚ-ÌŒé º°SV‹œ‡´¸fÕJPå°¾úoÆ(=W4¬ÝŠ u=kIÑÍšjw°ÚI¨\Ge`“HÜ]Kö"ŒËtf<3ð‚hYòêKäkë­+ó?ó«SÐ?ç!?-Zh6RÅ¡é^k[)KNd§(š&áψØq+Ô#-&Ž3ÑúÌϪUg—*÷ûëíqùËÔœÎ;è:/˜o0|ƒ,+æ¯Ê-6ý@ŸQŒM Nd&J32S³mÏ|h3ÏØ4‡ª»¶çøû“Œ]Ž¥<³äï+y2ÎK*éºM¬­êL–±,fG‘‡ÄÄ ‡"s‘Ôêòç7’FG͸DIÞc¥Ø«±Wb¬SÏŸ™Oü¶ÒŽ«æÍE-Uƒ}ZÑh÷WL¿³ òos²Ú#3t=›U.q¿>ƒÞXÊ@s|]ù“ù…çùÉF×NÑ4(´ï*éS<–·SŽR©qÁškŠPrZF }ùPÞè´˜;&&SÎCýôŸ±ÊÐv^£]*Ç¿œyè§ÞOüŸòß–‚]ß ÕµaCëNƒÑ¿â¸FÇöš§Â™§×öþlûGÑ.ú7e{)§ÓT§ûÉ÷žCÜ?[Ñ:l:f‰ê]Š»v*ìUØ«±Wb¬ÍŸ›š”uI´kËKÉïáÍé$B"$@âŒÒßùsw¡ì,ºˆ ‚>ûûžgµ=©Á£ÊqJ22Õ[üCoÏ›ë÷ht,Ks îfyV´¬qDâY³ÌFòeáúItÇÛYä5‹—ÆþÀ?KÖô+ë­KF°¿¾¶kKÛˆ#’æÕÑ‘¢•”s^/ñ Ò¹ÌjqÆ%›ì|ž×EšYpÂs2 Xî=y¦C”ìUØ«±Wb®Å]Š»v*ìUØ«±Wbª–Vz´–wðGsi(ã$2¨taîlž<’≢òá†H˜Ì м—Ì“ÙÝ~ü½½“MÔá&Hì̬ƒ—„3ÉkàÕÄ é´¾Ð ÇÃÔÄN'­}ã«Äv²2ñ4’àþûOÌ"ü©ùåªh·£ËŸšrZÝFB~“X¸°MŠ?ïÈ¿à{æ§µ=ŒÇ–>.ŠV?›îOè—ÍÃÑûG“ ü-\LHþ*ûÇé'¹XßYjv‘_i÷ÝYΡážާ¸eÛ<ï6 â‘„ÁŒ‡0^ÃHÎ"Q6PˆÊ™°o3þXi>kó^•æmRæibÓ—‹éoG¶—.”ìüF®7ä(6·³½¢Ë¤ÓO"Ÿñï÷í˹Ók{£<2Ìšðô?޽ïóF‘æ8þgyŠC :•×—d­|½tïÖ¬#?f¬¿²C‘Q^]úó³µX4}„Y€Ì äxf{þï*ø¼–·]N·!¡#”Xù}ÿEù-¨¬Ÿ˜:õ——,®tß)½¢Íq¥Ý3?Õ/TÆ…AbH<Œk¹Q¿MµžÖà#CŠY¥åâ¡(ÿwý?{ìîkÕäŽ(˜ã«1=%·íø=ÃIÖôv)§Ñï"¼ŠÞi-¦h[Ib4e?ÃÄn6Ï>Ôèòà d‰‰ }ÅìpjqåÂB@ø£eŠ9ãxfE’¤‘¸ ¬¬(UØ‚:Œ¢2166!ºQQäù÷Î>I×ÿ)u¥üÂü¸‘ÓK¹j¤1“VG_Û€÷®éÖ½ô®Ëíl¯‡òzÐ8Ó.óÞ;§÷ý‡‚í^ÈÉ¡Ÿ§úzŽïøïÜ÷ïËoÌó'DŽœDŒSRÓ]’ÚB>ŽHÔ<›û@òÿh}žÍÙ™¸'¼OÓ.’¯¼~‡oÙý¡ L8£Ï¨îfy sÝŠ»|ãæk{ïÊ¿ÎkïÌÍgHŸVò†§©[Æ&}>IR8ªj@R p^D@IÛ=[³²Cµ»":Y<Ð?I5ÆŸ;ëêí»Êê#-&¬ç”L¡.½Ü¿âÄïôÝ_þr ó óVò…¬º'•ͼ¦©0áëEú„ʱµ$ÑxÇÈì©È޹»Á¨Åìî‚8õ2rÙ” 7¢vÚþ˜ó¹WYU¸SÇ>ÐÎeŒp¨ŸÇ3åî}%äO(yWÉz9Ñü®‘”‰ý;ëË$ó\G³Ýh~‹ÐžOÛ}«ª×eñ3ÞÿHäOóGwŸW«Ñiq`‡?}ù²ŒÓ9ŽÅVÉsFñL‹$R²Fà2²°¡ ÄÔ”&bAˆc(‚(ò|Íëê?󌟛ëšzI/åǘ›Ó»¶NL©:¼B§ymÉç?iîÔ÷^É×÷t2¡Ÿ?º]{ÁóîÓÐ.]¾™rý_²~cþ]y®ûÌð~q~L¾Ÿª]ëZrÙëš5ñF±Ö¬fDly²#‡Œ"°ieRZâvhbŽ#¦Õ\Deqçý¾E”MØb–¿ó‰òO¨·˜¿5…ºBfk‹_(iŽÂÊ&cQ꺱øGûí ®Üœî¹Ú>ÔÔx4÷Ëë—?Ç™ù1Ž÷Ôö––¶ÑYXÁµœ ±Áo ,qFŠ(@М\ædl›%½["¯ÿœ¡ü©o=y?üM¢ÂO›<²¯si.,—ãšMË-=HýÁvΗٞÕü¾n DþÃÐþƒû²ÂÃÒÿç8ÇæçåÔ-ªMÏΧa®‚~9è]ü¦U<¿ËWíLõ'‡·b‡b®Å]Š»v*ìUØ«±Wb®Å]Š»~mÎP~`jŸŸšsyGÊ­ëyoÊ+qmmñ…Š{¤!n® èAp°ÄzPrۑʲæŽ1eÆÖkqé¡Çкd•ÿó•W^U[?%þki&ÎÞÆ8­mµk(=3 1(=kTJ€>ܺ!ëœWj{,2Þ]<¬øIûëù¹Ú]t2ÄJ$J=áõ†…æ Ìúl:Ç—µ5-2îî­dYž¥I^Œ+ºÇ|áóàž)pÌŸ78HIŽT—b®Å^kù­ù!äßÍ‹>Z¤FÃÌQ/-vÕGÖ#¦ê² „©_ÙnŸ²W®mû/¶³hϧxõ‰åû ãUü›òßæ?•|½u£~bëQks[\˜´{”å$¿REZYžŒÅEaU§ÚjŠGµõ|ٰdžǫßä»ÑsTÍØ«±WÊ~aÖ5É?Ï2yïÌ^X»ó—üÑ I¥jö1‰fµ))…y|*~K)*†ÕÚéðÃ]¡†(LBXÎàõóh'†VõÉSóÍjþpüÀ´ýc¨\†òž=¼QÜØØƒ'&w¤„Èãê6úNØÅ§Âc â zå{÷måÞÙNåꙥfìU(ԼͤiöWËqãÛHö«ik,Oq5ê)ag—ÎÝ2AËñé§)U{Ùå_Î÷y —ÈŸœ_œ^^üÄòÙÓ5ý'Pò'æ–.SÐ’þ9 ´‘µ•Q]Âò^q*óUøúçuÙ‘“M“ŠŽ\S2¯¾¿o"vqç0Gqz†¹äÿ/ÿÎQþRhÞgƒÒ°óŠ[Ÿ«__Bò*¥Å¬ÜjƽÔàu ¦Á«ÉÙ:¹c;Âùyt#Ïû DŲïùÇÿñ…¿‘Fç/.Cåëý"æk¾­ 6±^Ç ân…U%Ôq“í®Ç0{{Á9ø±LÌH^ökÊÏàreŽëwªf•›±Wb®Å_:þrÎQi>Qš_*þ_¢kÞpfôáA–ÎÒBxñ f”¸.Àõ5sªìf¥˜x™½ûOêÚÖfIሲ^¤~Zy‹Îz³yÇó^þ{íFä‡úŒ’!^ª’²ÐF‚»E)íÓ6ú®ÛÇ‚”_Õßï/kØÞÇ™VMOúOø£úÍë––v–ÑÙØÀ–Ö°Ž1C„EV€g-“$¦L¤l—бbŽ8ˆÄ@­lv*ìUØ«±Wb®ùuÅ^Kå¯Î«;›½V7ˆ4„³*¶«šfv Ë"’¡‹BÒŠ3§Ö{;(Æ ÎùòçŠìÿká)äŠÇÃʬ÷ß➯ ÑÜCð·(¥UxØt* ýÙÍJ$=ÎŽE .¤Oto§°¶’ô€¦åà¥!zdrÛ¶ùduxDw^Í2Òb”¸Ì"eßBþoü•ÿq^yó€ßæP§oŠÒäGM÷­ç]íï4Øò{¿Ù |ÿÙÝksbò?ìe_¥2Ô<Çæ$~iÅk¬j3Üù[VoÜ,îZ(c¸4k°1H({ðùæ>-&-Vˆ˜D îë_¬}®^}~}iä™8²r¾@ø“ö{Û–êûÍ£O†æa¤hj²K r8Œ›t y(4Þg |F1„pvwЧþ:²É=Wlp  \Åíéÿ@þgÜk×?š6• ^Igy%µ´p°‘„bFšcê2ßcÓ.ìhbŽŠsÉ~á³íLòí,xñHĘƷÚî[¥¾lÑ<íù]%—™-üË>¥Äâ+TÊ¡¥*d $o$Õ‚¶õ®_¡ÔéµâXŽ1råähS‹Úz=ge˜æŒÁ4nùó¢ 6ïIóæD^\ò~æ X[ýf(d°·ž êÄ%fzP ‡RFh;?²mD±“´ ³î4õ]­íÓi!š"å|Åïî`“yëó/EÓíüÕy©éZ¦•3FgÓ-Þ’“p®bPÊM@¯7¡¥suÌÑå™ÅÎ2ÄoŸê;>ÚíÆyOàjâ*Å÷×ë/jÑu[}sI²Ö-÷°¤è­ö—˜©SîÇ9F‹$ yÄÓßhõ1ÏŠ9#ÊBÝ­jqhºEö¯:—ŠÆ n«zh[ˆùÒ˜éðœ¹#üF—W©1K!åOÉàú6³ùÁçÁ}­hZŠÃom'µGŠäG1jÊk@FîwñÎÏQ§Ði8a’6Hç¹øŸØùÆ“WÚºþ,¸§B'–Ãà?kÓ¿-µß9k6 æý1­f¶NÖA ¸*HpbÚ…HûJ8Ÿ£9î×ÓiñHx2°zs¯à½³úÝ^hÌC„Ç”¹_~Þ]ãbÎ3Nô.Å]Š»v*ìU&ó'•4?5Ù-jÕfQ_JaðÍ ?µÇË¡îeé5Ùtò⯸ûÜÐìÌ:¸på÷£Ü^?&™çÿÉkÇÕ<¿;j¾SfåsÑ…ÿ‹££SýÚ›t¯òçGhû^GN‡¯Àõþ©ý¯¨ìýgdHÏãÅ×öŽŸÖçµùó+ËÞ}´å§Éõ}V5åu¦LÃÖÄ©Ø:Wö—é¦yÇm{?ŸA/Xâå!Ëö/•½/fvÆ\}&¥Ö=hófY¢v¬'Ο•¾Xó¼ñß߉¬õx”"jN#” ­ÃV¾÷ÍÿdûG¨ÐÄÂ(á–ãáø§QÚ=‰‡Tx¥q—ó‡6ù•­êV—Ð~Xù"ÍÿÄzÄ6é«j¾ˆ†[˜–1ŸUB†øõd袪;Ó£öGŽp:ÝT‡‡Œž]ˆ›¾^ÿ¦<Éߺô±©œd4¸#ë˜Rª$WÞzrEy_òÎ~F¼Ó%òß™!ú´ó#y‚ -T#"­HJÕœuE©ò©¥=£í>“] ŒØMû³Åø¼óîîmÑv£I(œYëø¾îïRÐüÑåÿ2Ç,š¡ è¸N‘µ$º|hÔaíQœ†³³³éˆ`c|¼þ<žM­ÅœŽBTšº$ˆÑÈ¡ãpU•…Ab=³  ‡(‹|ùç_'k_”ž`ó#òø˜ô´~ÓÇ#(ì £¨ëô§ìS±•Ù=©‡µð³yW¦]O˜þ˜û~wÀö·eOC“ó>ž£»þ:~Çп—¿˜7æ.µ¥Nu¤wö.ÀËk5*U©ÕOTj|CÞ ygovnÍÎqdÜ ºH~9ŽŽçA®†¦QøŽæYšG5تWæ/.éjÑî´rÜ\é×kÆHÎĺº7Ue;©™ ×åÒfŽ\G†QüQò-:ŒË á¾eÕ¼ý¥~aYþV~VÉaåÝ/M°K»+kˆã Dæà¼‘ÈÌÄò]¨I ÌÕÜz/git9t×ëÄóNsá‘ú7¡°#Èü@¿ÔeÏ ã €ˆ±æÅ´8®—ù› Üè6—:_šµíJm?óË.ÒËlnu uµ*d’P|iöOŹ×vIËÙ¹cšQž,PÓåØJ¸O ×º1å½ß>Xx5|˜ÊU’=.ùýçËÜú¿¯Î1±Ø« üÃüØòGå…Ö¼Ó¨¬wn…ít¸)-íÍ6ýÜUÛ›•_|ØöefÕʱºžƒâÆS›ä¯9~y~iþsK6“åHÛËLbc™â¬ÓFv>½ÈGX¡oFå×;þÍös–¥?ÞOÏ÷Ò\­fê5†±ÇnóËçúIùaæ‹ÿùÇ/Í=\šwºò®§²Öʧ%¬Œ¢R§ã…¸Ê›ïök¹Î’2´ößbÏC(‚x„‡?>¡ú‡oqݼWV²,ÖÓ¢Ë Ñ°d’7••†ÄjMÑ*b®Å]Š»v*ìUØ«±Wb®Å]мCþr›ókþUWåÛi·/5ùƒž™¢i$|×ý"åG_ÝFvnÎÉãŠ@|aùcåŸÐZ ÝÜ'GRã4µê‘S÷I÷GÜûf‡[ŸŽt9Í}£íÌgáL6þ¥’ë:“¯Ú›MVÙ.#߃GŒžèãu?,ÆÇ–P6 ©ÒkréåÅŽT~ÿ{±Ò?0ÿ*u&×ÿ-5iÌ‹˜Èƒöe€þîaïNC·Žefð5qàÍïýG£Ývgµ8òTrú%ßü'õ|vó} ù_ÿ9iå2´Z/Ÿã_,ù‚¢3tÄ:gèjïñB}¤øGóöÎG´ý•ˋՇ×ïâý¿“ØcÔ‚7åÞú.)bž4šY!‘CÇ"ÊÊ ‚6 Œå ÑrAµØØ«±Wb®Å]Š»v*ìUØ«â=~RyßòëÎz§æ]¿—#Õÿ/4­h꟠_QšïÔˆ ®È´Ef5.¡xÁfô]jáÔáŽ>’æþ9ô£³(o£Ü¼§ù“ä/ùÈ;OD“Éój^]ÓlṓPÔía’4»–¡íU™d BŒSFû4RÜæ«³³öpŒüAHÕDž]þï{h—D§þqkEÕt¸¼ïwu¤yQÕÌÞTÓõhî¥I˜«’Ôà!J’jTïPrÿi³Bg2È#ë#—Jý'âŒCŸsè<å›]Š»BêZ–Ÿ£Ø\jš­Ìvzu¢4×7S¸Ž(£QRÌÍ@O9NB1OE|kù£ùýæ¯ÍJ_!þS$Ö~]jÇ}«|PÏuFf~°À|>Ûý<3¼ìþÅᇩ Ë ç_¬ýƒílÒi2êòxx…Ÿ°{×ùòÏEò\KqA{®2Ò[ùìTn°©¯ïÔ÷ðÍoiöÆMQ¯¦ß­õ.Åöwˆ_Õ“ùß«»ïfù§zb®Å]Š»v*Ó*XÄxŠTÓ°®‚^=}ùÇ©ëÒÈZ<ÒkNìºE%"@99@ÜTÔÓâjùÔãö~G¢c‡Ë½á³{Y“P|=&2gÅÝßW÷•žMóv§çŸÓ_—¾v_GR– ‘&HÄ2‚‡ŒˆÈ>HhË·c\=¡ †—ƒQƒx‚<ÿDz{S&»ÄÑê¶‘z£æ+¼s Dù[Còw潎…©Ä/<½?¥é}{‹rVz]¦µ)›OÎåÔèe’&¦?›äS¤þMãí8â˜âÆj¸¼ÅoÓê}jm^…‘ŒCmHPñã)Ùh)ðç>+¹]÷êúž3 ¨Õ ¶éä­lxž‰¤jº_熡s…ÁÒîd¹3^,2ë6ÿX¤QÄUÈž¹×jsÃ'fÄ![^ûåî|ÿG¥Ë‹¶g!ÀL¬Ñ¯Tx¹òæË?8¼·»äû‹ÂU/tp×HÆ•E½Ž¿å(¨Ø Öö°âÔôžÇôÇGuí_gÇ>Ëø±ú‡é¼;ù ¥LÖZ¿™ï Is8%’̱þòF©ëÉßsâ¹í>qÅ Qå©Õû¦&3Ës3WîÜüÉûÿæL:ž¡ù¹§Úhó‹]UbµW öVUç*–Øí]ºÎìyB ‹›\g´É“µ!g†uç¹Dê~PüÙóæ¡i§ù±c³Òm“Îoéï³:¤LÌîWe®ÃÛ|¯¿C¤‰–2>ÿÓÈ6ê;+µ5óŒ5Dóô×¾Üþ6e?›^D»Öüµ¦¦K>† Cf»´–슄-z²ðZû÷Íoavœqf—ˆhO¯Ÿà»Ÿj;YôðEœ\£ßnÁæ±Aå VæËM_$j–ú³º¦¢–“Íû¾Ìñ¤Áûšñn ý󠔵ĥãÀÇøl¶«ô¼œa¤Ë(ÃòÙïÕÂNÞ`ûkÞú/CÒ-t&ÏG².Ö¶qˆ¢iHiب¿!œ&§<³d3—9Ô´zXéñGn¢+~j:þ¥ XY<ÃsWßè¦;‡ %õ¾€u"‡¹Û%¥Ã–r¼`“öéMzíF p¬Ò2ôïÖöx˜´1~Nj æ,^™¼½w(ŠKy~ «,S/FÆE¡Ýúý&«iCÃ˘ÿHýOŸkô:ŽÆÉã`•㑪?t»üˆßôõ›;ZÃä3çc¦h.#·s_ß?À‘’)Pd!ká¾s0ìéW}jü»þOk“¶"4_šªôÝyô5#yÒ3yZO2jö‰¦ÁJEvhÞ8“ÊU¢•=O´»8`Ì1@ñ_oF¾Æíyj´Ç6Hð~êÏâù2=/WÒõ«Qy¤ÞE{jvõ pàVMÁö;ælÅ.ƒæítÚ¬yãÅŽBCÉ”¹Å]Š»v*æUe*À"„Á±Â ·ùÓò–h.ÿÅ—Ò6Ÿ¬@Þ±²…ý%fò·aN þGÙ>ÝM í¸Ê>¤q@ígŸ¿›ÃöDzÄKÆÒzf7á¥î÷r÷2/ËOÎxµ¹“Ë>rQ§yÑI}(®]vâÊiéËþOBzPü9ÍûCì‘Àm?«:æcúãö޽ì;Ú”øYý9Ý×ú—ö=ƒ8g¨Xa…¦[†L謉)QÍUÈ,¡º€JŠa’5W²8EßW‡ùë[óµ×æŠybÏÌ+åm1m’ãK¸˜‚îOL1XQ‰“’Qª>•4>ØÚ={8ç–/\U 9Ä_Ní¨í¾ýÏÚzLµ¾rxQ«‰èoƒòö©¨ß~hhÚ6›maæ;)¥·óEÎ’éú>úÑ]KÍÆ/€¹W«ñèvv›;;,²NRÇ !?®Þ†ûó¯óo¦î·IžsÖ㈌âHÈaôÊ=û~.žÁuùÇùylÑ/éˆåi.Í‹>›)£Jõ¥"ïÁP{V‡8|~Êk¥»"£Å¿_!ý//›ÕOÚ$k×{ðþßw›9t†æŽEYmåR®Œ#£ A¨ ƒœø&&ÆÄ;’…Á|ïæ#\ü‡ó|^uòŠ´ÞS½Jòı(ªÇ“[Êhh§¬2ucþW¦hµ{{JtÚ²ÇxËýðÿ|:ýÞ}ÚZönoøåÌwyÐÓÞUóFç-×ÌÞµÒÖ†‚Hœ}¨äPMNÄ}ÛgŽöŸfåÑf–¢¥‘óEè´Ú˜f€œNÅ9Ì!Ø«üÎü½¶óîƒ,6Âo3[)mUu!íä ¯¨Ÿ«Ò„ŠÓíQ³}½.ÏÎ ®X¥õü{¹Xûy:îÑÐ D(m!ôžçE¢~QjysÉV¯æßÎ ¢Öך¬¼‘YÍ «Åmìî?h÷ý£J¦z\°fíŒc6ªCO£Žñ…€d##Ðw}ƒøžhN9pb&c±=ÞïÇêf_•ÞpóÇ”<È<¥ù«¥&§æ™ÅÆ“<‹ÌQ¹^.=H]¸©øC"ŠE±!Ch}¥ì³Où€ŽSÄžíˆó¢wŸ™fêóaÉáê®gn¿wà>ƒÏ0zwb®Å^ ÿ9 ä{Ô[/Í?+3[y‡Ëï—’Á´†_œWƒv…º“ûËž¡ÿîÝGC›xd¾ïëó¾ÿ{Ë{EÙöUóG坿·¨[i1@>­­‰¤–÷ñ¨2F ’O=ž5b¬;æf¿±òâÔœ0]cæ?Þj3[Ã?0¿ç,µÏ1]Iå¯É­>D.xvæ Ó°­ AÕ#_ø²nß²§|é»3Ù(Ƨ¨7ýúOêù²Ã&ypb‰‘y~“ùs5íëëÞy¾“XÖnXË:Ë+ÊÉ­e•Ï)áóξ"0ˆŒGÏoÙ~ÇÆ5=Aâ?;'¯ÝïzQEi (±Ã ‘  ª£`‹ÚãÇDF"€è/9yy<Ë¡Obúâ~úÍÎÜfA°¯ƒ ©ùä¢hºÎÛìÑ«ÓÊÄ7¿öò}ÿ8Où®þjò]Çåη9>bòˆ f’m$šI!#;ŸAÿt|Æ3!ñiăEõ6,Š»v*ìUØ«±Wb®Å]Š»~i~pùÇþW¿ç¥Ô–ÒzÞIòÅl´þ&±K¼Ÿ¼”v?Xš¤¾˜_åÌ]^oeÔöçh~WNHú¥°ý½’ç<ùc±C±V5æ_#h>gV{¸} ú|7°QeÛ§.Ì?Öú)™8uSÇË“¶ìîÙÏ¥5qþiåûo,yßósò"P4ÛÓ~LVå&Ÿ?9mBÖ¬BÔ½»wä‡zò鎯³ôºñê3ïÿkßvgoáÔmÁ/æŸÑß÷¾«ü®ÿœ‡òæjÃc Çè38´[çUw~âÞ]–QàÅFpݧìþ}-šâ‡ó‡é>ï7¢† ŽÅëY£rŠ»v*ìUØ«±Wb®Å\@"‡pzŒU a¦éÚTUÒí!²¶äÏèÛDÇÍ·f†žç'“$¦nD“æ´‰È+±Wb©G™üÑ¡y7Dºó™/RÃI³^RÏ!êOÙDQ»;•Wrrý6šyæ!d­¾!ó¯Ÿ|ëÿ9#¯¶›¦‰4oË› AXXÔµã-Ç“0û1ƒÅ>öo@Óé°vN>)z²Ëñ·póëö9Ý•Ù9{BuLÕ/Ç3äô?-ycGòžššf¥¡–V¡–g¥ ÈÛTþ¶sÍnMDø¦P÷>µÙý‹Iƒ¡öŸ2œf#žìUØ«±T‹ÍpÐ|ŸkÖ·pcõÉX!KË!Zr⣰®ä홺-]Lˆ€åÍÖö—jàÑÄK)«ä:”ÂßWÒ®îÒÚön¤nÒ‘ZCnôã'kÄò9Dôóˆ³×ǹÊǪÅ9Æ@’8ª÷®ÿsÊüóæíOUól¾JÓu¤òÞ—c­ªjìá’‹'nJvä *°$×zgIÙºcÀ3Ê$¤}1xÞÙíL™uGM ƒ b.sûvåÞ6ZMùmæo2[ùÁ´;BëÍ>Vwá-óÅ5! *&¬ÕhÀm™KPö©¦eö¾ Óø’ˆÅ“»mü¶æà{?Ú:ˆêü(ÎYñ:ŽÞ{ò÷[\ÈŸë°MÖ^ªNÀ%þÛW YÇÜ1¿Íöoô¡þ÷þ:´4±ÝŸïÿãÉßš|©æ+?Í]/Í^[°{¨'ô¥¾hÊÆŠS÷«3£”DR½MsE®Å- ±e•u÷µØv—fg‡iÃ>F_îeó‹+óß宕ç©-n®n$³¾µSÏ«sˆž\[À’FýÎk{3¶'¤?{¹í¯g±kÌe"c(íc¹3òg“tÿ$érištóOÒ›‰^vRL…U P (£1ûC´'ªŸ€+g/²;'‡„ 6o~öE˜ÕØ«Ì|ñù{æÿ6j×Wó´òÝÈ„6žÍ3(1ªÔúbˆj×\è{7µpiñ‹Çs¾ß{ÈöÏajµyMeáÅ*ôïÓË—=ÙÏ–´ O,hvz‘- ¢q20¤v%ÈÌÄœÓë5RÏä—2ô=Ÿ¡Ž— qG”Gϼ±íCòî-CÏ6¾v}A’KS !*DHWwå]ɯÙÌì]¬a¦88yÞöë3öɭލÏé¯MwyÛ6ÍCÐ;v*ìU‡yóòïJóÕ´FyÓT¶m¯QCQNå –»õ‡­v½™ÚÓÒBây‡EÛ}ƒ‹_g†qå/ÐGPóÁù%æûé-ì5¿2,Ú ³VÄ·2/OÝÃ(„¶lÞÿ¢=<”1Ôϸ|Èܼ¸ö?UˆeÍxãËy;š/óÆѼ£ èZlf=9}6§Aõx¸Ä¬ÝÉ«6ýH®Uìܼ\ù2K꯼îßí”<.,P~á·éJü×ç¯.Ú~YéÞUò½Ð–ææ`ºEVV†0ÏΠNûÞ§2t=™–ZÉeÊ(Hóîù´ûkOΆ ³ òå~dþ–W§ËåOåTwR(ÅÊz¢6-}vµE#¿¦ rsY–'´5Ô>‘þä~¿ÒîpHvOf ¬ïþ|¿PçîI¼³ùâm´ëeó…•ÃÏ+•]BÚHž1AÈ‚ã“^\ö—¬öoŠgÁ®âwü{ÜÎöˇ1gø€Ú¾{ù×Éì–7¶š•¤7ö,öw$†d5VVÜœ¦Lr„Œd(‡»Ãš9`'q<оAµØ«±Wb®ÅXæ厛ç8Zöן˜£_Ý]D›ˆÙ& 7ƒS÷fë²»fzcÂ}Pîî÷~§›íßgqëG}9#ßå/×Ì}‰'å׿¾©åÝE|‹ù“Î ˆYa´ÔîéÙVw?iÜ%ûÍ7ûAì¼3Àêt{Þæ#¯õ|ûãòÝç;/¶²iò~_W`„éòî—ö½ì@ Ô‡<؇³I¼Ñå}'ͺTúV­:ÈŽÜ¢’[vqOR#*°V÷ÙÝ£—I”dÆNÇqdäj¬8šÝ=F3 ŽÖ<żÇQ] þqûÉÀéþ‘ó6¨Æ$¼•8ú²(äYÀ'ŒQ×hÁÜž»–ηÍí¯Öx1Cz—|ö<îa‹±ôþ‘Å’}{ÿ`îþÖ+åßÊ=Ë¥ùòóêRë7WÂòóK¿‰U)Iv–EQÄ5Mx*ÕMÚwµ! écÄ!ðÆQ=GAåæNþçY¤ì Q”5áâ2³çÏ˧½ô–y[è]KM±Ö,.4½J¹°»FŠx_£+|·¸#pwvŸQ<3©DØ-y°Ç$ $,oŸô=SWÿœyóëi÷Í%×5§¯3V¢A2Óa,5¤Š>Òöû4ô}~—´Z.8ÔuÿýYtî?óÉF}•¨á;âŸãæ:÷üŸXÚÝ[^ÛCyg*Ïip‹,FÁ’HÜrVR6 ƒQž%—±ÈÆBˆ4GqzØÈH9\ƒ'b©d]Ðíu›¯1A§ÀšåêGÕøAëH‘*¥ºJN´è32züÒÃ&gÉ$G ¿ÇâÚc‚f`#Õ0hbiRfLцXä* *½9z€h+òÌQ2^Ŷ…ÚüŠ]Š´î‘£I#E™˜Ð7$“Ûš%៙ó‘XÒb¸Ð<­o™uIÕíå$ÓטâUˆÞjÖœScüÙèÞÎ{ªÍ(åÎN‚þÃù¾ó¿“Ïv‡nãÃã'o/ÛðxG–ÿ+u=H-ƼͦéÌޢء&c_f$&Û|UožÞd½£²½‘Ë–¥ŸÑïâýŸ“ÖtKÐíE¦—l–ðíˈ«9ÝŽì~yY6úC‹MqŽ}èü[±Wb¬ÏÌwŸ’ß›ºæN˜Œt©æ+«[GÒXeø.â§JºQ+ûb½²ìeòßk»3ÁÍâÄzrºëóçó~Ÿi÷öZ­…®©§L·:}ô1\Ú\Fj’Ã2 #u> ¤–2ü²òðÐü¹ÄËKíKÌÕ*„~é>…5ù“š nn9×@ù§´zÿP@úa°ý'ñÜÍ3 çÝŠ»v*â;ƒÔb–æoÊÝ#W-y£‘¥êhzc÷ÃqTdû§Üs;ºQÚ[‡¤ìïiráôäõÇíùõøüÓß$ÿÎCþfþS\C¡þ`[Kæ-©Ãq+òºD´€Ø—~Õ\×뽞ÓêÁ–#Á/³â?SÞviãÏÅ+Í<ÇêûGsë þhy'ó*Ãë¾TÔÒæTPnl$ýÕݽ{I |@Wö…Tö9Âkû36–U’5çÐü]¾<ñ–Üwãô3 Ànv*ìUØ«±Wb®Å]Š»v*ìU&óWš´/%h7ždóÚÙéVIÎYí3~Ìq¯Vv;*ާ/ÒégžbJ’7Ã^có/›ÿç%<Øn.Ìš_åþ—)ú­¢š¬`þ\:ý¦è€í·Úô(Cdá¡êË/ÇÂ#íû¶}ØÓí ŸÍÇrýÏîûú¾“¤éÚ„:f•n¶ÖP©¼±êIîNç9ùç–FS6Këš].<Æ8b¹KìUØ«±T©«éš-©½Õ®â³´/«3„Eê}†]‡òˆÈù8úV<âÉ!æóÏÌ› ÿÌMƒÉÂÏU°–ä´×bAÊÝ‘ R­Ê€P²¸#—M³yÙc£Ë#›Š]ÿŽ1íöŽ 7 âe¹¾_޽y0ïÈÈ4{1jš¤/šíƒ­¯¨ì F¿»š0›kï]ºR‡6¾ÒË!ÅxÏ?Ð}΋ØÈbŽyÇ #,y_w) ïütL¿2/5 _]O9ùZÞb ™ õˆy-ϤH£/%!8º«r­~Œ~ÈíhcÅàå&r>ýÿ±Ëöƒ°rfÍùœdêõŽÞV6£Fí¢ùÏþcÕtÉ5Eò‡–´£É,ôç6Í5YK§Ÿ—ÅÆœš€•9^£U¥Ã pŸsë-ëæ´šv§, ãù|Xÿ†›ïäo~òõ;ÝDÔo Ôµ .¯­T¥¼ÓF²Åy|!ª®àç9U’1Œˆ=Žm“œ¥D‹¤Ç1ܧb®Å]Š»v*ìUØ«±Wb®Å]Š»v*¡{ce©[=ž¡oÕ¤›IȲ#SqU`FOY@ñD|š³a†X˜Ì ÐîÂ5/Ê'Þߨ_[[›bèÍknAp©'¨VE ±'¥ytÛ7{QÊ$ñqu<ǹçõÊé'8J#‡„òŽ÷¿ö¼«ókÌWjóDºf]i>^I Ë4fB>±#Ð)¢WÚ½ó¤ì- Óá‘©düD~—ö£_-^¤ÂŠnÿßÑý¬Ïÿ™IÖ¼„t z——·±04Rô™X’JñT ­|+˜—ÙœZ®9òfþ¯Ç=ݧn{A£Í¢ðñîMTj¸kìÛ–ßs ò®¦ß—¿”Öºž¶¬Im-áfk™áˆwÜmà+á˜Zì?œ××SîæC³ìÍOòweÆyyî@þ±ôÓä¥äßέS³Š4Ï›«=*¢Ëè8 £³+I¦î|vÉv‡³¹1Èœ@Ê? ý¿&“í~°9×Z÷ù|Þ¨¬®¡Ð†F«PAèAÎlŠ{ m¼ v*ìUØ«ó×´¯;éþ•Àj)ú•úŠ2wâãöž£îÍŸfv¤ô²±¼O1øêé{k±1k¡RÚcé—wë #òçóVò&¬?/¿0 GjŒ#°¿–4@\ý¨[ö[ö:¾ÎG´>ÏcÖãüÖ—êþ(ÿ;þ=Þ:ûùñÝ—Ú™tY+ªÚ¹îíÿšzŸw¡TnCž^CÛ±Ï;ù+IóÞŠÚ>«Ê2­êÚ]GOR € 0®ÄhÊzz´ì~×Ë¡Íâc÷ÐÇW_Ú]W‚Ü^Oùˆšíÿš|±ùA¦êÓÙérÙÄ×7óÈL×Tõ20*^‹ ⵜӗa8ôÙ»BxĤ$j m\»¾­Ï@ó=¬2Ï>-fDLw'™çÏ¿—.ô<Ÿä§ž¼½¤Ùkj^Zó ‚Þ{¶hÙ¤XŒž˜$ «+-+B¹lócí­\’Æ!“±!×bjþŽ›Å>ËÔã„fe ›ñ«ûCèLó7¹c¾vò~›ç}ãDÔVoÞZ\Ò­o:ƒÂEûèø$fÓ²;W&‡8ˈïߎ®iv|5XŽ9|qïyÏä_žµ/(ëÓþPùͽ)"•“FšC²JÇ— õIkÎâiû@Û^ÄÇ«À;GM½Xòþw¾<¥óè^3²5SÓå:l»vý^ãÌ>”Ï%z§b®Å]Š»y÷æç“¿/cx/®>½®R±é6Œ­5i·ªzF?ÖßÀéû Ù-_h`8qÿ>\¾Îø|HušîÖŧ؛—pülùã\óGæwç4…n$ý åj­¬e’Pk£Î~tJôãžÓØ~Éèû4Ç“ùòçðé†þeÔaÒk{Oîñ}Ÿ®_w¹‘yoÉ:–P=¤^µõ(÷³Q¥5ê²—Ó\è̉{NÌì->Œ\EËùÇŸìø2<‹¹v*ìUØ«±T‹Íú ù@ºÓ€X§«jÇ´Ñî¿~ê}ŽJ&‹«ížÏüÞžXúó¼rý_пó„™§ÌÞAºü¾Õ$ÿs^Pz[,„ú’i·.Í͹ô¤åþUà3!ñ9 /©±bìUØ«±Wb®Å]Š»v*üçÿœ‘ó[~nþ~/•­dõ¼¯äÐö$)ª4Ѱ{÷ö-([öæ>«/ êë»_[ùm<¦9‡¼þ®i€ €è3œ|ءث±Wb©FæM7]¹¿µ±õ=]6f‚ãœeT°bµVÜxŸl»&@z¹Ú¾ÏÉ‚0”ª¦,n›å. …Ý­ý»ÚÞ—Ò Ì ÔÐä ‹äÃ!‰áÜô|ïaqyù£çhô>NÚy±Kµ†Îܘή+çÈr å¹!sºËè4Þ&œqqVç}»ÿï—áÉ>ÕÖ Z³ÁÃÅQoÝ×ðôÉïÿ%üðÚmô?•µ>?¾#fˆš,Ôsˆš8GÍr£ÓÓqGl‘üW¸ôþÖÍ<çØºÎ ’qO¯—¾=±™ùÓò†×ͺÂy‡HÔ—N–éTÝ‹ÕI~ P«- ^½_ê{?·¥§ÇáÎúvOnñÿ"}äÖ…?Ÿš¤†¶þV<Æ·29¯ÌB2Ñì´<¿gí@öÃQ/§LkÞOû×Êø×?êV?ò:_ú¥úÇþ«ö~ÕÿEš¯ùF?ì¿âW/üäÔ;^ùa’›³ ¶ZõZã€û*,¿gíAöÓ$>½9>ø£í?ç ü¼ä Ý*ò õ1¦þ £Ê'ì®QôÎ'æ?[v/n°«‡ºêdVœ¾@¾!_P{I€-̯ÞÈGÒÙ—ÙýT?†ýÄ;<Öègüf>ðheºn½¢kºV£m{µH‚d‘‡Ì)$}9¬Í¥É뉼;½>·oîç{ˆ)†På;v*§qOo, +ÂÒ£ š2ÆXS’–Tu(Jˆ5l2GŠ$]Xæ:0¯ þ[Yy'ô“¼ãP¹¾n ;ÇÄ‹PôÙIaRÄòñÛ6ý©ÚòÕpíÂ#÷÷ºÃö~2O—Zþï×ß².Ë!Zj¥bÑ¡ yª³ÈЫ šˆYŒcþƒ¶U.ÙÕJf¾óæÝg4PÉâ bþ5òºû'ù“çüãædŽ?RO)hò"HÑVŽ­"¤³Ô7ÙŽ½¾g:îÈìó¦Ãf¼IѰýoík f¢…œ8ÏO~òøòµ•~ißþ\Mä¸!ÐÚÆ]EšÑ‚ÈGêĊÙ'Ä«À£þÕ<3[ظµcPNN.ø¯¯»ötw>Òçìó¤–Ü<5c¾ú]ýY÷å̳éÿ—º,ºìÂÝ’ÆK‡•Œf 锦i;^"z¹Œb÷éß[ý¶ô#AŒå5·^ëO/÷y;ù rùGàóÒöWŇ×´~±Ì3¿ÉOÌ´üÃòºývAþ$ÒÂAª&ÀÉQû»€ißÁíLåý±ötöv§Ò?u=áå߇ÝN?cö‡æqïõGŸëø½/9nìU"óOœ|·ä½<ê^dÔ#²ƒIÖY˜³kVsòwÍ—fvN£]“ƒ Ø=çqµ:¼x#Å3Oœ<ÕùççÌ™t?Ë›It$ž2êí÷iGÃöB_Á»g°öütújÉ©#,ÿ›üáü_¼žtëõZéxzh;ÿYä>ô¯Ë–:fšâÿ\Òš£mêTÀ®MIâÛ¹¯í?ÝžÅB†Áè»/ÙLX}yy?ö#õü~LðP €¬¼UØ«±Wb®Å]Š»b>Oó[~J~{hÞr©‹Ëš»›}` —ê·L#º®ÛúoÂàä—ÀØ|ŸÚ¾Ïð5&CéÉ¿Ç¯ëø¿NÕ•”2TŠ‚7ã&ò­â®Å]Š»v*ìUØ«üçüÀ‹òÇòÏÌ>qfQyglcÓQ·õ/®†ÙiÜ 3’ Å!ùßùM¤Ë™uæ;âÒ_êÒ³ d©vÕ‹êîXŸ ÒöŽ[—sçþÕëxó C”9ûÏìz&kžQØ«±Wb¨MR+Û:ê :U‚úX-æzÒ7a@Ûo·\œ_&ý4¡‘3wï$Òõo4þ[]]/˜4æ»Óo¥õf¼ˆ†¬§bë Ø–þW¡>ÙµÉp8Möú.›´ã|2ˆ wu~‘oYÒ5;}kM·Õ-ÖÞåyƲ¯¤n7ðÍVHHƒÑâuZi`ÈqÊ®=È܃ŽìU+Öü½¤y†ÛêÚ­²Î£û¹>Ì‘Ÿq¸Ëqf” ‚æhõùtòâÇ*û¼0KMóò§RmòçU­Áå5ª|Lè»ñš±(ù û ËÊpj£Áš#ñÜz=¿gûG‹1'îçüîŸ?Ðv} ù]ÿ9oåŸ2´?D¾]× ýsâ6?MÉ«DIìÿùYÈöŸ²™1ܰúãÝ×ö½\5f?^ãùÃôÒ/àú> ຅.-¥I­åPñËGS¸*ËPAÎJQ ÑØ¹ñ°l/À—b®Å]Š»i™QK¹ Š f&€¹$œ@WÃß™z§ç§œcü¼òTå<“¦Ê^êõkéݼFrôë†ý£ñw} ²ô0ìÜ>aûÃÈwy{ûûœ‡&·0Åâ{‡ã™f¾^Ð4ß,é0hú\~´rwyý©÷f?çLæõz©ç™œÎåö=‡—ÇŒPo™LóÌv*ìUØ«Ï3¼û}åd±ÑôDþbÕ[·%æ"RÁ ûLÌh€íÖ¾yØÝ™A”ò„9þ>÷˜ö¶ç¥Lj^Lœ¼ºrï'“Õu/Î/ o0kw«}aøò?±éˢíØirù®ÂÚãU³ ;-=H¢¹áÅÊT Šö5§ZœñÔRÃ""vø=pÑŒðÔB&qß¼ uü~¤ë¦Ã¦a»b®Å]б1þfù?Ë%á¼¾7ÉPlìé< ŽÍBO³0ͦ“±µ÷Œhw‡ãÜèûCÚ-&—iJåüØîPø—›ß~ty·]f·ò†Š-ã$¯ÖeáÇ­4?ër·³xqï–wåËöýÏ:=¢×ëO ÷×Û´GÆÒ; Ͼfø¼Í®È!µoê3¨ÿžQðˆ}²Ç-6îà/¿öósqûÚzÍõY¸Guñ±µgùm ÁCró]7pÏÁЀøl2í žTþ“þ Þd>f‡û?jumå/Z!Ó`¨è]‡ï“‘Ìyjrd½ŸÙŽÏÃôà‡Äq}²´Î( €R’1àŠõeFDów°CÓp¥L ®Å]Š¡§Óì.kõ›Xf¯_R4z×ý`rBr‹‰ŸAƒ/׎2÷Ľ*¹òo–n«ÏOŒ%¢§Ð„Ã.ޝ êé5>Çvnnx@þ­ÇýÉ#»ü³°-êi·ÓZÊ W˜GJÀ¿2#Úø€/5¬ÿ¦ž[áË(:ÿz~Ò­kuù¯åj;SmJÍ?Ý8¸Gnÿžg1òétyþ¨ðŸ-¾ïÒê2vnhwÅ?#¥ßÙ-ÿÒ²]óäÁ(³ó~%¤âæµ ±ñ0LCòsš­G³/ ïÈþ±úšp{c,RðõXŒ$;¯ýÌ·û^£¡y«ËÞf‹ÖÑ5®è*ñ©ã*ò£z8úFsš\²D»æõº.ÒÁ©Šb_Ëšo˜®s±T¿]ÒÛ[Ñït•º’ÈÞDÐýfs@ÛrìFÇÛ¡|¿M›ÂÉЕEÅÖé¼|RÇÄcÄ*Ãòwåž“åÏ.^hzŠÇ¨É©ý#)R«"}%QZ€£q½CTצl»C¶2fÌ2GÓÃôþŸÇs§ìŸgqi´òÅ:ŸÕçÝòûÐw䇒l5¿eº¼DnqÙÜÊ ÔT"+0 Äõ˲ûI©œ8v`o÷¸Ø=ŽÑãÉÇê—‘;}Âþ'Þ¼Óo}ù‡ù¦ÞO¹ºk=Nøc…GDŽ ò2¯BîME§†û}ã£ÑxÀqJ_¯o€ûÝicŸhö—å¥.C§¸YøŸ¹C_Òäü—óF‘ êÜiz‰aue;ï,¢EL*µCÖ3Æ äô¹ÇiáœrD G‘Ù»V»L{SŽx¦L'Î'¸UÝ{öÛbú8gÓÝŠ»v*ìU~g~^Áç-7ëvJ±ùŠÍI´—eõnasà`ö>Äæë±»Té§Rú?/?Öó^ÑvÖãâŽÙ#ËÏú'ôwÿ&?2æ×bo'y•Ì~gÓƒ$-0ã%ÌQlÊÕÿvÇOˆu#~Íšk}žæ0ÝË ?ïOØvîuÏvÁÊ< »dZý#¯Ï½ìÃ=C óåw•<Óæ[O3k0<óÛEé=©zA?å‘zž5;FïQ±ßh}£ÔétòÌБ»ê;ëßötu:¾ÅÁ¨Ì2ÌY—CÝiî¯å/kÖ¶¶Z¾ Õ”‰5¬”HÞ1E¢­lW¡î3]¥íø%)c™‰¢{ïñÏ›™¨ÑbÍÄ`&À€lÌ7)¼ ùßÌö÷Ÿ’™v~wÐâcå}YÙ/m#Ù(ä5Å¿€è%‡ÜS¢ç¦è%ÜìéirŸÞãúOû™½—í|ûµ4dzµC4¢|ÇÞ?Hý©#×ti4hüÂ/¡MXRéoä‘c‡ÑW.ä7ïž3-a˜áá> << Y±Òžg‡Ž»x?žÿç%§mòÊѵ=FJÆ5Ibf[¥`‚œœŽ¼ž‹ìÃ=/°?àq9ÖMaáÌÿÎ==Ã0óÚ®Ý3—‡§Zû‡WœÙù[ó6 ÞaüÄÔf½¾˜†kc/7§P®ãeQÙ#Øv#=_I¥Ã¦Æ1ሄGAøÜù—7Aì¬òËÄÕÈ“üÛûÏè7¡ÙXÙéÖéic[ÛG²E…Q÷w÷Ë­íð`†(ˆÀÐ"06»R¹¹·³‚K›©Vxi%‘‚ªÜ“‹ ¹cŽ&R4RÁçüËK©ÞÛË=Ö´Sfš5hâ¯Ùf§úÀdø;Þ_'µr1Óâ–Zê6qûi8ò潯ê·s[kš\qÇÍ'g,®Õ€ø@­ zà ;Ìí Fi˜åÂq€9ßÙÉ’ä]Ó±Wb®ÅX‡æF‡úkË3¼KÊîÃý* ÈAûÅúV¦ž dàh¼÷´úÌiIT=Côý²ÿç1å`þNéKw(“Zòáý ¨ÔüL-Q~­!®ç”*ÝØ6^øù{–(v*ìUØ«±Wb®Å_ÎtyÊmoÌTü¡Ò¤«†]WSU5Q=Ák{Ujt(ž«°=NBsžy³ Xå9rˆ¶!aeeoal8ÛÛFÆ?ÉE +ï¶s3‘‘$õ|{>c’frç#hŒ‹S±Wb®Å^Cç»ù5]sY°¼Ô¤°Ó4+D–+Xº¸”!Z‚Ewp+½N§6ÚXpÆ$ 2?'¹ì\sŒ¥–Ugø@¿Ô˜ùGRÔ4¹ô?'ê1›¿Ò¶²ß]Éq#LУ£˜áàÕ   ­{·L¯Q!)¨Ó‰Úš|yc—SÃáÈDP«6,ß^cÒ¢Š("HaEŽÔ$q  ªª(`Íq6òr‘‘$îJü ]Š»v*Æ<Íä=ÌêÒÜEõmD†öëÛ˜èãç¿“ƒU<|¹;ŽÎí¼ú]âóOèîH¼µçͯȉÇèûƒ«yD5^ÎnrÙñ'ÃíÀÇÅvùäµz .¸z‡ ûúþ׸ìî×è7Ž\þiëðä}â¤ú·ò¿þr/È_™K¯úÌŒm*õÕ}FïèK²¸öÙ½³†í?gséw®8÷Ò‚Ð d'¿øOǧ¸×•½{4.s±Wb®Å_.ÎRþoÞBSòƒÉR4šöª=rXÇ3ÂÑHèÒƒY<oÚ4ì}šì¨×ærý1ú~~<ýÈ”ä!r—&;ùä«O$è‰f¡dÔî8ɨݲIM”¼´_¤÷ÌnÔíj²qúGã©}{°û:<<äw‘ï?¨tý¬¯5ŽéØ«±WþgyÏ^¸×­ÿ/üœÍ©qÀ^\DxÈ «ÍcWý€ãwì;õΣ±»?Äu¾‘È~Ÿ=öáý¢í|òÎ4šo¬ó#žý/¦Û’Ì¿/<­¨yGB“OÕ/íô÷2]K2³°DDâ ›Ÿ±×5]«­†£(”¾÷}Ø=›= ’â‘‘‘>ð;ýÌOóƒÊzíõÞ—æï-Æ÷†“Ä</9@ŽOZ)z·­ToÓß6}®ÅË]„ÿ°‡Ií_e朡¨Â.Xú{wîÅõmÏÿšvÖÞXƒBm:ݤGÔ.ÙeXIN…šET‹‡ÄÆ›fÇ—K ')ÉÄz ¯ñæê5ZíwjÄ`¸Ž#½}¼‡ZܽÃAÒaÐtkÝ‹Åe p‰ÅÊŠ#Üïœ~§9Ë’S?Ämô-”iðÇåI†På;v*Áüáù©åŸ)sµ2~‘Õ×o¨Û0<ÂY7TùnÞÙ¸Ðv&mFõÃóú_¹ç{WÚ]>’ã|sþhý'§ßäòCÌ_˜ß˜d¯©úA~‘DZt>'ûÉ*?Øü³©Óö~—IÓŽ]çØ>÷IƒGÚݳ¸ýÎïˆ#ýÔ¿Üû‘:Oåþ‡§…{¥7÷rÓ G_hÆÔÿZ¹n]tåË`ö]“ì‡MG ñ¥ý/§ý//²¨ãŽ$Ä¡#]•Tö0É·¶†8ÀÄ@»NÅ]Š»v*ìUØ«±Wb®Å]Š¡¯tûF/FúÞ;ˆ»,Šžàõå’„ÌMƒN&³AƒS Ðcîîø0ûÿËÄŠa}åËÉ,/c<âRíEaÓ„‹ñ¯Ï|͆ºÇ Ç|û´ÿàuŽüMÎ9@“_ }Cý’i¤~kùÇÊ3Çaç;FÔlI¢ÝŽ"p¾+"üPvjšíO``Î8°žÝÓö~6yãÛ¡Ù“õ°2I~© ¥î;÷½“ËžmÐ<×kõñg*–ðÍ{ño#íkiŽ)aúä{¿„÷ßèø<¯AòŸ|ϤØéšÖ¡sgåK"^ÎÊgjl\´pIcñ¿ŽÕé°ÑàÇ–YcâOœ«sñu™ìî«Uø„Ãå|þôŸµé:^‡åÿ'éòÉk[C¹¼”ÖFUÜ—~¿@ÛÀeä’÷šM›AŒ˜ò<þ%ˆy—ó2ÖëMÞS¹?¤ç-ùÉB±¸?z‚›OJü²Q‡{Îö§µ0ž.4½f@n:w‹üôoÌÞYó ·—|ßp.­õÒï—>2± ^d) Ÿ„ƒÐÒ›b@"Â{?]ªÑêcƒU.!“é—=ýÿgË£Òò·µv*Â|ËåýcÌúý½•ó}_ʨ'Ç q(ê¬:Švð Ôí0hy¼Ïjvvmf¢0Ÿ§Eì~£ÝøéæºÿÏ>Mò­¸°±t˜Â8¥¥‚«*üÜQñÞ¸ˆ’ËQÛú-x A¯á‡ëåöÛ¼æýgÌ÷ӵƒlôoO•µÍ5 —j¨?²»SDv/lçÖd&XøqÖÇ~~þ¿Í2JìUØ«±Vˆ °ªˆ=ÅHµ_ùį4ËŸÏ=OòþîOOEó\M ¨cEVá®lÚ¤÷¥‹Ý˜ ȉ°ølh-¨ž>€íî;‡èVIÕ»v*ìUØ«±U“M¼RO;ˆá‰Yä‘UEI$ôb¯ËË}~oÍ?Î?5~e\†kG¸éÁÁªBÃêö©½7Ktí×5Ý£’£ÃÞóÕêø0 cœÏØ?m3ìÒ¾xìUØ«±Tµwua¤ÞÞXÀno …ÞT»ðŠ êþ7ûº‘›^ÇìëÌ!ü#y/ÚÆr¡o”?)<©{q-Ïæ'™ÙîuíaäžÞI÷“ŒìZK†¯íJNßäÿ­?oëã¶ŸÑ?‡O‡ßî{ÿd;‚?™È=Rú|‡Çî÷½g9‡ºv*ìUØ«çÏ0Þ·‘¿:?OjˆÏ§\°™e§ÐžA™ãWoïÆ—æ»;ÇÔ>ðoí|Ç]›ò=¯âä™oð1áû鷣˦þ˜ŽþÒøó7‚Tô‚Ò»µh>YÇ6A>ÅÝ[¾‹f#Ä÷³Ë<…ç2yÇó Qh¯¤—ÊvBåá„Æ‘§¦ïÂÜTÄ|C‘®Ç:>ÓÐaÓi#q$«ö¼wbv®£Y¯Hœ1â¡@mÊ=>;÷=‹9Wºv*ìU¬ëzW—¬$Ôõ‹”µ³«¹Ýš• Š7f4Ù@®_§ÓO4¸`,¸º½f-< òK„ÇÅá¾aüËóOž®%Ò<švöfº'„Χ¼’ ˆÁþT<‰éž‹±0逞oT»º~ß‹ÄO´µÝ¯áÑÄÆeËý4¿‡Ü7>k4"izO‹À/¯úó~íù(Yü336¶SØlß°}†Òèêy?{“¼ý#ÝÒoÊ™^a½»±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUJ{x.¡h.cYaqGÀe#Ü1‘ÃV}<3@Âq‰æá…jI¼Ón—Xò}Ô–wОi©ùFõÿ…mŽgGU‘àÊ,ÌûcØc— ‘Œ‡ð_û™~‰mæÌ|™ùÎuÐüõÔu"1¨á7Oß'ìò‡Ãþ¨Íhû;C¨7õwýþ÷YÙ¾ÔÊð5‘ðæ6²+ý0éïåî{ :J‹$l7‘Ô‚¬¤TGPs•"¶/l"Ç&ð%Ø«ó÷“Ït3¥%ëÙJ²,ÈëV‰Êþ̨ä7¨ßcC›.Ë×þW/ߊtý·Ù_Ãቛ¿/ˆëúÑþVò¶•å*=+JŽŠ>)çjz“ÉMÝÏ€íÐe:ÝlõãŸö9›Ù¸´x†}¸ò—ö>g¯Ó˲5ƒ$î²tûÇÜ~]ï¥l¯mu8/ìeYìîcI ™ UãqÉX|ÁÏ!͆Xæa!R‰¢ÛHÎ"Q6%|©›ó‡æ•ü‘oêëWcëL9Ca $¹—‰QAþSP{æß²»S®•bŽÝd~‘ñýw]Ú«‡J.g~áÍá:Çžÿ1?5d’ÇBˆèžYbRVGe½–p?ºF)â\õ>ÇöOM£©O÷™;Ï!î¤ïîyC©×v¡áÄ<<}ÿ¬õ÷ŠqåËÍ˼.~½©­Ö¦QDoø­7 óÜûçO)’ôÝ•ìÞ -HúçÞ@é÷ù²üƒÐ¥gÒäÖ¼¿¨išMhµ™©,p€ÆŽIi$ØÐ©ãJ“UéLº¾e“U¥:ŒÆ³DóÏ©÷mï ìzGŸ|ü¶j\,ll˜.eÓrh‘Fò35êÀí#¢íÓà9*"Ey'à;žÅ ÈÆ“?«*ª‰$ãÇ›BÜw¥Ol¥ôx"6{Õ1dÆ<û¡^yƒËÒÚiõ7ѺK A hhÈÄ)BNýÀÉDÑt~Ðö|õZcP u~O9Ѽ™çM)„ÉåûgMÄ·’G1ù…õŠ xñË êñº.Ä×a60@žùßW؈ӼëçýKYH±6÷3FãÖG‡‚Ÿ‹”¢ (éÉ~ŒLE7i»s´rç¡Ã"ôyïÝæ>dÊ_Hov*ìUØ«Î?1Í÷—µ/ù÷Gc§¤]BÉ0¯Ã$ ˆjlZ¿<·x/m´V!˜Týãô¿O<¥æ;/8y_FóVœkc¬Ù[_B+R«q“÷RxŸq–¾tœâ®Å]Š»v*ñoùÊ¿<ÿ$üÁ<úz–¶«¡ØQ¸±{ðVb§¨+•…;ŒRþYi¢¼§jî¼n/ɼ“mé%ðOÓœþ·'C峿^Ñê¼]T€åOËŸÚÌsлv*ìUˆy·Ì^gÒ®à¶òöŒÚ’ËÜLc‘ÑXš*„oASó—§Ã ”©Þv^ƒM–&Y²po°±ú^{q§yîÿ_·×,4#£êLÃÕžÜËÞUv#¿Å¶ýóRøÑó,/Í~a¹ÿœ†üÚ’÷ãBòÿî¬âj€m•º‘µåבîSös"—£¯ò³ûÿT~ÿ{Ööf~P,~îËõ|~ëzò"F‹j4UTP6Û8âmö0À—b®Å]Ф>kò~‰ç+a¬DIŒ–·¹ˆ…š"„£z÷s7C¯É¦—¼t.·´û+¶.Dsç—Gÿ8ﺬºû*׊Ú)Œ…GΟFtgڳö=ýû}Ï`Çù}?Õßïz¿–¼¯£ùOM]3FƒÒ†¼¥‘)fzP¼µOà;œÖ³[“Q>)þÁî{>ÏìÜZL|Å´ù”ã1÷b¬OÏÑü‘gÎé¾±ªJ¤ÚièÀHý¹?ò¥hýÍŸfö^MT¶Ú#™üut½³Û˜´0¹o3Ê=`óx²óæ6 º÷š§h´î¶¶©T^~1!¯=ÜîÞýsµÇZHpbõ?­ÐvO³z®Ù˜ÔjɆ/á¬DtÒæz_6qgei§Û¥­”+º}”AAó=É÷9‡9™/®èôX´ØÆÐëûS³á«Á,RëÈ÷‡ñÑç”ɧTò/îVÆ=)¥–Îy‰âœZ²ÂRžqÐoSN£3½«ì#«àÔé£ÄgB@}‡ô‡›ÂviþPÏM¨<<WöÒ;ÝæÏ-wÌ—/¡~ZØÈ¼ê­©H€ÌTíɾ×ü·ßýS–v?°Ð…OTxóG/‰ëðÛÞO´9õRð´‘?Öëú‡¼ý‰>‡ùb¯pu8\¶©ªJÞ¤‘4Žè_ÆIâþ<ï #ˆÀÐ9ÝìœAñ5'ŽG§O‰æ~ï{ÐâŠ(#XaEŽ$R4U@ìØ`{@DPüY;v*ĵMÊþWRóséé-â“pYþ/Þ»Pª³Ÿ´wÉ‚N΃W¢ÒhÆMQ€2çñ=ÝÖz°Í>/ÌŸ;Æux5/Ñ– ÍõeYd·FâiE‚Ì%òFƒÍiáÚ}¢Ÿ‡NRò­†·¦é k¯Ý‹Ëðîþ°frÏ ¥ž„Iú6í•ȇºì>|XDsËŽVwçÏ̧yfìUØ«±T—ÍzOé¿/jp^RÉh7õcøÒŸ6a‰¢ë{_Gù4ñõ#oxÜ}¯¡ÿç|ñþ!ü¬ºò•Ìœ¯ü§xñF„Õ…ñkˆI®ÿÞzÊ<ŒÉ|BAõ(v*ìUØ«±W¿óœÞc“Ì>xògå}œŸ¼gP½ ½&¾“З¼qÄíò|†IðÄžæNq‡¦„Ç¢Š8"Hb^1Fªˆ£ UîÎ`›|vR2$že~.Å]Š»¼k@ó¶‰iç­cUÔLÖ¶×ãÒ¤ â6B«ñªŠÐ…ø~žù¸Ë¦‘Å7§¼×v>iè±ã…HÇ}÷|þ<Þ·c©iú¤?XÓ®¢º‡ùáupâv>Ç53‰¢)â3iòb58˜Ÿ4VE¥¢BŠ“A°ßÄš SI˜ñ4-M´úýxZÎmøý¯SÓÕÙÖàÔÔr~îìO¸þ¿µé=w3ŸzÇb®Å]Š»v*ìUØ«üÅüɱòU¯ÕmÂÝy‚áI·µ­V vKMé^‹Õ¿ÝvOdKU+;@s=þAç;{Úh£ÃVCÈwyŸÕÕäú–/õ‹×ó7œÔH&5'ÀÈ;û1ôîο&h㇈PÁaìϱóÍ?Íë®R;ˆ¾_¢=:÷3ž›™€ú›x«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š¡ïl­ug´½‰f·Q‘¿X=AˆÉBf&Ë­ÑbÔã8òÄJ2éøëæÂ,ï5ÿÊ\_é¬×~]ºp.m›ì¸ì¯ü®ÙqýFej4ØõÐá–Óã§“ã£ÙºŸgóø˜Éž ŸÀ—t»¥×æBy{Ì:_™ô¸u}"oVÚ]™Nϵ‹Ù‡ö³‚Õig‚fCÚh5øõXÆLfÁû<ši˜Îc±WH'sîiLQNÅ.Å]Š»iÝ"F’F Îì@UP*I' @½‚ Yäò¿7~uišt¥ùR!¬jÌ}5™C5²¹ØqáñJkÙvÿ+:^Ïös&J–_L{¿‹ö~6xÞÕöÃ+†âK¿øãߛʼÙåo;ÝØÏç3g•ãYá ,ÑÆGfDUG´­|Fvº}<0ÀB€x |u‰Ï—r^«ä–Ѧòí¥Î‹l–°J£Ö‰7a*|.Yˆ=ØôÁ+·Ô{X%¦Œ°ÄDcÏ­õ?E‘wÅ]Š»v*Ç|ó¦I«yWR³€rœF&‰GRа–ƒÜ…¦J&‹§íí)ϤÉά|7ý ;ËŸ™:å;{¯RMJÙZinB±âÅï_l™%ç;3Ú}>ŸGÊÌã·ûï’U*ù¿ÏúÍ–·a¦¦‘_ªÞHYVŠüÁgmÞ†¿a0ì1­í<ðÍ c‡)}óþ/€{2òâ9Ð= 7ïJå/¤‹­×b–#ç8ü¯¦¼Ë¯i¦úh¸ÚÅE žN¼‘˜-+]Ødã|ž¶ã¤ÃZŒØøÈô޽çqËæÅ‡¼íæ ò–õK?²—…m¤,CåC’ᛡþ]×j½:\\1ïçöš‹ ò—–|Õ§êo¬y‡WúÔ’ÄÑ5 g•@bQ›Š­è«‘”‡GoØý•«Å”åÏ—ˆ‘\;ŸØ>›äØ«±Wb®ÅVÿÎ.ëÿàùÈÛÏ,JÞž•æÈ.-c P‚R¿^·#ÜxWýlȉ°ø¿oé< VHô»ã¿ÙÉú!’t®Å]Š»v*üÆÖõ³ù‹ÿ9 ç/82ØYÜÜAc'UôméamAÐrŠ2ÿ<Àí Ô+½ç=©Ôpi„:ÌýƒÔÌsFùñWb®ÅR?5ùŽ/+é-¨¼Fâwt‚ÖÝM ’½H¡ì é—éðø’§cÙžuYx.…Y=Á€'˜àÖ.õ(?04+H-ôèRI¦T¬£KÇÒˆ2±nLù–”ß3¼<9Þ˜ö|°ÆI–DÌì6áÛ™îÛâÏü¯åí@±q¢r6·Ì.C»s%YP ââ¾9ƒŸ4¦}\ÃÌö–¿6¢cÅç¿iæPë’3è+æ]]%®¤´YJ1’0¥ OQP *:u˰eðåÅVçöv»òÙFN*ï`£4<¾p5Ý1:BÕ•‚öø‰Ê69ǃ/1Â^—ó›¬úÇ….þ_o/˜Ah÷¾Eó¹¶µåÙ,uÙäâÑÆÒú)ÜóJ•ñ? Ì øšŽÐìL:þ™wÒ:ýï¯{3íô£QŒ¸‡ó%ÏüÓý£ÉëþQüÃòßœc §\z:ˆ“O¸¢N´êTVŽ=ÔŸzg¯ì¬ÚcêñËö>ÃÙ}½§ÖA©4óý¿Uš×tìUØ«±Wb¬7ó϶žHÒ¹¯µ« Ëajwï,€oÁ·‰nÉìÉj§ÝÌþ{¡íîÛ†‡󜾑úOû^Aå/ÞêwæÏ3»\ê7L&eÜ‚zHàڜ¢¢–|±Ç À5û!ì¼òKóºÏTå¼ÿtÞŽŸ*œf éîÅ]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±U+›h.à’Úæ1,‚²F ƒ†2 ØiÔiáš@% °[+Í_ò£_]JÃ×—nÈK‹rM•@ëÕ¿Þ3/S§†» ¶˜ä;ßí.ÎÏìþ§ÄÇsÁ?Ç þþ׿ú/GÕôý{M·Õ´¹„öW+Ê7¬àƒ±çúŒÅ3 Š!î4º¨gÆ2@ÜdÊ\‡b®Å]Š»ažpüÍòדÕàžo®êÃìéöì ƒÿ7D=üÍ·gö6mNàpǼþŽ÷CÚ¾Ñiô{Å?æÓÝ÷ù<ºAù‰ù²áïô?•˜Õc’'ZÔ• 1÷b™Üh;#›x‹—ó?Øùþ³´u}¢}Gƒpåÿøíîz•ü‹åÿ*F „­ñ’új4ÍãÄôQì¿MsfÏO£†.C~ôúöÎßP´žÆí–×1¼S!îŽ8‘øâäN"@ƒÈ¼cÉRÜy7·’õ&Þáëi!Ø4yFðõ#ëîÈd ý–Ö6¢Zy§ËßûGÛOWÊ_Gv*ìUØ«±Wb¬cNò•ôÛÉo’ÌOq$*ŠH‘rnAcJ~É¥}òFeÒi½Òa™˜…’o}ëÜ9{ºù²l‹»kšòáÈs§.5Þ+LQbév)R¸¶¶»Ñº…'„Þœ¨®µSPhÀŠƒÓ1Fb¤{¼tjÞó<Úž©£]ýVÇKfág„øV¤"¨SÌñ<¾ º€|çó£¬92b— qÿÛáçñýBò¿š­u-Á¬êEjëÊ+ÆwXãYS®ìh*(ßNW(ÑzþÉíxgÒŒ³"=%ÐXüZ}iwm}oÝœ«=´¢±Ê†ªÀl~c"í°æŽH‰@Ø=Uñlv*ìUØ«Î<ûywå?6yWÏúpÿKÒ®à”°2YÌ·1)?åQöËq—Ï}·Òú±ån'ï¥ú—¦êº¶iªØÈ%±¾†+«iGGŠd#šr×ÏÑX«±Wb¬;ócÍ_àËO5y©_Ó¸Ó4Ë©m´ÿJhÌv⽫+ ÅCó‹òsMú·—®u{éÈSãˆÿ†/šNÑÌçÏý¬ÔqgþhûOì§£f½å]Š»Q¹º¶³‹Ö»•!‹’§9*òrEOrM0Æ$òlÇŽS5eŽyó@¿×tˆN’ÁuM>â;Ë@HÞ0G¶ÀïQ]ª3'K”B[ò"¯bk¡ƒ)ñ>‰ƒñy½ž“çgôžq¥=«kWqÜjš”ñ²"¤mÍU+@B¶ã‰>°–LQ©|#`õyuZ,<A/$B ÷í¿í{]¥´vv°ZC_JÞ4Š:îx¢…úi¥+6ùþ\†r2<ɵl mcE’v RÎ5Ÿ,ùößSºÖüµ­úñÜ»L¶LÜ)û*©'8šƒnF™±ÇŸˆŒâõzNÑÐËqgÅD âý¢¤>Ô_u½WÍMy®é–ë6û»}Ebã'ªy# -Z+ˉFÛä5x£h“¿FŽÜÑâÒS5>q½«¡ýL÷0^iØ«±Wb®Å]мïóo^k-ÔŸ­êGUû^‚Q¶ÿP{ï›ÏÅÅ.#Ñê}–Ñqå9eÊìýIß”ô5òö…k§P Ž>¥ÓÚ™÷mûÓìa›—UÚºÓ©Ï)ôä=×ëNñuÎÅZeWRŽ#H¨ õbkpÀüÃùecy'é/Iú/RBU — Ž;Æ}×ol(òzžËö£.Kˆ|zýþmhŸš¾kòmÄzGŸ,ä¼´û1ß }`(îìJ>d7‰íœßh{7'«¤÷tý¶{=íÿ@™ñcßücßßñù—³h^bÑ|Éf/´[Èî 4äÑã'ö] O±Æêt™0K†b‹ê-~L8±HH}ÞñÑ3Ìg1تQæ1éþTÑ®5­E¿s¤qñÍ+}ˆÖ½Éû†ý³+G¤ž£ „yŸ³ÍÁíÐǤÂrÏûOsçíÓPóƹ?œ|ÉñÂÏþ‹¯¦x*¨?î´éîz÷ÎþBlc?Çí/5ì¯bO´óv¨\ôÇ¡#ýì~ÓÏ«?ÌØŠ»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š¡ï¬­µYl¯#[Ì¥]OàAìGPrP™‰°âëtXµX¥‹(⌆ÿŽþâÅ<›æ;ÏÊÿ2¶ªÈÒy_QpÞ©é? Σ±,€vßz Ÿjhc­ÅÇ®?o—ê|g‹Ø:Ã)¼3ÜKý÷¼rý¢ÑÒDY#`ñ¸ ¬¦ ƒ¸ ŽÙÀ‘O¡°Þ»J<ÃæÊÖ]ÖïÚ3_J?µ,¤vÄÇðó+K¢Ëž\0÷{ƒ®í,:Xqe•}çÜ;©þaùßó æM'Èö’iÚ]xÍ{^2ñ=ä˜|1í¿ø½ÏLí;?ÙÜx½Y=rÿcû~?'Ï{CÚ}N¬˜iÁ„{ÿ‹çÓῚwåOÊ}Ee¾ÖHÕuZ‡&AþõøPý£_Ú¸gFë4ýo/Qz €è1vNÅ]м«ó“C‘!±ó~ŸT½Ó¤Ž9ä^¡9ò‰ÿؾßì±u=¥ŒÇ‡,v1?Ùö²¿/êñkº5ž«¸ŒQû2…×è`Fc‘EõÍÖNåÄ>Þ¿jgÍv*ìUØ«±Wb¯6óž³æk¿4ÚùCB¹x¸ˆIõ‚x3Ô3Î…€M8îNY*Þ3¶õº©êã¥Ã.!wÊùõøtDywËz”5a}«ù„\k7€[úê¦C3-YÛâ‡lI¾½›Ù˜ô9¸òçâÉ/Mwß¾Éß®ÏAÊ޹ثÈî4/<é^dÖmü§Ea¨J³5Ë,kW¢´µ v_„W-±[¾}“A¯ÃªË0¨ÌÝí]ý{¬·TÒ¿' ú棵Ik{5ØÖ’H?ãLNFzObºæÉðë?©é:>‘e¡iñišz²ÚÃÈ wg5bY[Äší•“oi¢ÑãÓcáôŠ?”ìUØ«±V%ù“¦þ‘òíe´áw·¤~3ÿ['»ÏûO¦ñtsï«åÏì·Ú_óŠjÿþDùZYÞ‘š5È­x}BC+ÿ"=#ôåï´â‡b®Å_0ÿÎuyŸô?äý¾Òo1j–ÐIiÊÚÐ5ÛŸzHýø¤>|òžú+ËZ]‰^/¼m*øI õþŽsZ‰ñLŸ7ÈûS?‹¨œûÉù ‡Øœå.±Wb¯-üÛ”K}åí6öVƒFžv{¹G@¢3|ÑÓ›>ÏHŽocì´j§so´ý¤,×|ŪyŸW¶ò—‘o;h#ås¨Ç+€B7”Uø¨ ¨?8°ÇLòƒ-ƒ—µ¨Ù'hÐû¹Yûcùw®kªj¾V×n>¹q¦ÔÇtX»|é²—;°$‚¤ï•ë1G„N"­Åíí‹|C„O§ÂþDÍ{Ë õ]F #MºÔîj`´‰åuZrn"¡Ev©; ž8HÕ¿M§–l‘„yÈÓ_Ì/&ùŽÂãMšþM5®âx_Ö_IÕdR¤‰(ñƒCÜæ_å2c ÕÓ¼=…«ÓLL@O„ÞÛòòرø<‡æKŒ¾Jó:Ïbÿ°&dJ‘ ÷ ËΪûÈnìçÛz|†µX*^ï×GïfžFòÄÞVÑ•ÔË=ìòµÅË¡bØ¢–¡;/Zf«8É+mvˆÕæâˆ¨A“f3¨v*ìUØ«±Wb¯²?ã_Ì©õýæ—¤ŸÜžªDŒtÿZJÉò΋K‹‚u{­GøgržN!³Õr÷ˆv*ìUØ«±T=í…–¥nö—ð%ųý¨äPÃæ<·aÏÇ®[ÝÚÝÛ%å¬ñÏi"óŽxÝ^6_ÊH#9iã”O ^÷XΖ;8@DPñdìUØ«±T&©§[êÚuÖ™t+owÃ'ˆ)Qî:ŒXd€œLOW‘þVÞ\iz†­äí@ñ¸µ•å‰MiÊ6ôå½ÂÃé9^AÕÍö;Xa)éåýa÷Ð~oPÊžùØ«±Wb®Å]мïóvÍßD¶Ô-íÃOmp¢K¥_ÞCVý¡¸RÔúrÌ|Þ?Û,$àŒãã/«¨ªÒK/þ^h‘AªkZàÔnÈY•!”ý¯´H+%kÝ› $º½?gvnœ ™³qËžÇôGÕó/SÓ5+]^ JÉ‹Zܯ8É4­#ÄC•‘Oy¥ÔÃ>8ä‡)#09Å]бíCÏXÒ¯åÓ5ï«ÞÂToCÿœó°ÛyãÈwOÆK+›mNÊ‘ZÒäÓÛÒ„fSàÙ±˜HÄóŸibÔìUØ«áùÎMUµßÌß"y[”6¶¦îUjwBåO¶¯°>ù^YpÄžàÑ«Íáaœÿš ûlæv(v*ìU,×4 +ÌVQÕ õ¡šJº5)ÉXn2ÌYeqs4zìºiñc4Pz'”tŸ-Ù\Ûh¡ žåHkǤ“¡ ~!O„š…¥2yuÈA“~³µrêf%—qáä?-ò“î|´·×š¤âçW¿™eRXV$|M¹,O&ú2ÝV d 9/¶ûZ:žã0€ÛñåÈ3Ãt-2«©W”ìA{âi䟘V‰?™´_/Ago§öY.¯âŒFÅ]Ê¢×á=k½>®“$„%"nº=·aj³GM—1‘Ÿ(“}/ßø(2y.ÏËZþ‡i¡ê—6«Kè3s¬±HŠàÇÀñ%»þ=2Ì:“’2Ó•Ùý¯=V ²ËËÃäy÷ßsÚ”qP¢¦‚•&§osLùù-â‡b®Å]Š»cÞxÖAybþõÃ'¡mãêÍð=ÔßFdiqñÌiØÚOSô»>áø¦7ù[¤~òདiq¨¹˜žþ’|ÖßNt%Ù{O«ñ5#”|zþ¯ƒ7Å犻v*ìUØ«±T§\òÞæ=NÜ;Hç_†hÿÕ~¿AÛ;EÚ9´Ò¼gáÐüM¯ÛkÞA–]IÖd}?X‰ÕíÆ7<8÷P[ì‡]Îý36“I J ˜ò/©û;í£QŠQÇÅ/Iq+îóû|Ù§•4Ðt¨à`>»5$»oòÈÙkà£lÔêsx’¾Ó>Êöìí(¼—ª~þïty|ÏT÷1Þ•Ø«±TªãÌš ¬†)õA³(1Àñ­2ØéæyéuÑè0ˆy ¾þä]ž¥§ê*ZÆê+€>ЉՈù€j>œ„ñÊ<Å9º>ÒÓêEáÉÿT‚ŠÈ¹®Å]Š»v*ìUØ«±Wb¬Yüý¡¥ëXŸ×YLúkǘnyt®eêöx¹ûy¡Žc„‰ñ pý"®ë½”æ#Ú;v*ìUØ«±Wb®ÅP#XÒïèáy¾ž‡1Σµ<}ºäü)Wlë‡liNoĉüÛßÝïòæŽÈ;b®Å]Š»`žv°ºÒ¯m<㣓휑™ÙGB§àr;ØoLÏÒÊ9"qOp_-öû±åŠQ×áÚQ#ýì¿ÞŸ‚/NѼßù¶é¬ù‹Rú ÈÂ(!"€©£,P‚BžÜ䫬3/GÙø´Â >=Kçù³ê{Dñå—§ ¾ôÞ«åÿ+èžY¶ú¶‘j±–sñM/»¹Üüºx ÍspéáŒTBq‹{±Wb®Å]Š»v*ñÌH›Ê¾}Ò¼ÙãmyÄ]S»EH¥xÄËOzà"ì–c¥ÕÃ0å{ýÇìzz°`H*EA‚q˜ï­{†ñK±Wb®Å]Š u8jÚ]Þ˜eh>µÄ&JÕ ¡ê+¿L Ó­Óxø¥ŽëˆU÷<²çJü¶òeеÕÍÆ±©¥ °€ ÇPª‹Ð׋3e–KÁåÒv_gχ/YŽc»á°ø^“å­WCÕtÄ“ËüÆ"Sêè‚/I¾ÑR‚”ë_|®@õ{NËÕéóbŽ•UðN0;b®Å^mç4yE5(ìcÒ­µ]åŽ9å0£ú`7¼À,ÌÁGOÃ,ŒKÅö×jèÆQŽ9r4 y_2|¿±è–öðZAµ´k¼J8ÐQUG@†Vö8ñƈ 9\Y»v*ìUOþq£To*ÎQK¥rámæ[[ëS]”™!Šý<àâ?·2 v|kÚM?…¬È;Ïúmþ÷è–IÑ;v*üÝüßÔÅó•¾aœQítN±€kÇêviÔø‰Ù¶aëåXÏ›£ö“7’CùĶÿBušÌ]Š»v*‚Õµ};C²}CTmíP€\Ô’Ç¢ªŠ’O€ÉãÆfh9:].LóàÆ,±ý#ó#ʺÍâØÁrðÜÈÜ![ˆÌbF;­¸©ì ~MH !Ùj½ŸÔá‡:7L·1]#±Wb¯;üøò¢ñéºî mõKjúrÛ£Êð‡¡+ EaC±âwð͆ŒeŽñ=O`ãÖãx¡p—~×îý|–ù7È:47Py‘ufÖø ÙÉÇ‚!Ag$¯`iO u:¹a\)í~ÜÍ(œ>…üïÅoFÍ{Ê»v*ìUØ«±W”~m]K©jZ/•mïgLã¨å+z1T{|y¶ìÜ|åð{OeñŒXòê%È ùnCÐí-¢²µ‚ÎÆ xÒ(×ÁQBÀfÍä²ä3‘‘æM«bÖìUØ«±Wb®Å]Š©Ï“‡”®¸«ùüÞ•š§×Þqÿ)4¿óßò:ÿwðýÌúøÒ—ü8ÿ»{¶sÏÓÅ]Š»v*ìUØ«±W“Ãä?0¦¶€ú²L$úÿ5ÝCråJòåíN¾Ûæäëqðy÷>‡Ø^ÐŽ´_Ò%~%ŽWw\ø¼«Ÿ–ïXÍ3îNÅ]Š»v*¥so ݼ¶³¯8fFŽE=Õ…ȃa§S§†lrÇ1q û‹ü³Ôåò¯šï||çê—­ÊÑÛaë(ªÛ÷‰±÷gE‹ œA~yɤ—gë'¦Ÿ v=ýÇâ>Ýž×–9ÎÅ]Š»v*ìUØ«±Vù±£ [É÷3"ÖãNe¼ÇŠ|2}Ÿ£´±qb>[¨þ_jߥü©c+·)íÔÚÍãÊ…kîS‰Ê&(½ß³š¿GyÇÒ~²™>EÞ;v*ìUØ«±Wh·~_ÐüÝæ5ó|h.䤴žâ&™}7vsÄqjVR :mó´ÙŸ;ÐæÓiµ™ÿ47!{Y=ÝE&–Í Ï™¼Åy£Äbòü…DKÇŠóæJPvÛ‘§`F òg³3Õgž!X/žß§Üôü­îмgÍ^}¿Öõ<¿c8Ñ´Ñ#Ásu1!Û‰*ÜÌaŠ­E(½{šeÑnù¿kûC“Q”àð¡tIçñ«¡ä>+|Ÿåÿ>Aki}¡gqhËé)E˜§6§^&¨@­ 1•DZaƒKÚ1˜œe«n|þ«âöpAƒPwe/¥Þ*ìUØ«±Vu©)~uy͵á7öå«@b†íVmûV))—c;>ií¶ Ï ÿ:5ò?´?Q²Çˆv*ìUùeäÝ@ù£óÏ>rcÌê7×W 曋û¹.6#jQFÃlÕöœ¶ä}°ËXñü“òþ×¢æ¡àÝŠ»I<Ó¯·–ô£©%£Þ°‘#ô•4j’Õ Ô v ^$ªéØvn„jrðpíÏñO'ó‡žô6Ã¥ÆÐ\A­È’òݸ•’ n.­^@:¹µÓéeŽùnײ{.ÌØ.Ÿ·Ï•i¿LÜê¼A^*è÷ý³ù°q5øt+‡ôùUy2Êao®5±ÐÆì u®Á¹W߉޹Úã|ëwYíQõbâúø}_}½/5Ï$ìUØ«±Wb®Å^A¥ñ殡¨ŸŠÛMõ}×÷ [->d—ÑiaÃŒ·Öƒvd!Öuöú¿cÔr÷‹v*ìUH\[›ƒh%_­* L<‡1¡¸õ¥AÅŸ‡.*ÚêüÕq`ìUØ«±Vù©­=&ÿIÔß‹ÔCº1â¾â¸½G²Ú?CýÑåø÷"<µ¤F¶² éê\ÞWݾï³ôg?¨ËÇ2_¶½›ì‘ ÑÃzªåýcÏåËÜ|¥Þ»v*óÌmíoƵ fKIQVvPO¦è8‚ÞŠo›maÃÂy¾3ÿNÄÊ3þj ˜H/è‘¶þDVýè/ùö÷E¶ŽÂ⻳‹hþ."“Zr¡ÕNYŸD&l.³Ùÿnóèq 3€ÉòÞ¤>;ßËâÏô?7ióz6îÐÞR¿W˜cN¼H$£5¹´³Ç¹äú—aû[¤íÃc?æËcðè~ÿ&7ùƒ>µ¥Ý[ÞØÞÏ •ÂðhÒF ²§°éÈ~£™zÂ@‚‡öÿ>·I–påœa1T ¡!úÇÜSß#ë2k*›™ —–Îb™ØÕ˜}¥cóŸFck1pOnE齈í™ktCÄÖ³ù¿Ãá?QÚìWé`:Œ¾†½w8ŒWr¿•ã)4Í”À'Ë»C/‡®É?æä‘ùL¦Z÷œæôÅÛÞCjä2H†H¢PßgˆR¿ŽSއ¤U»ŽÐ×vÌãùœ‡,`wqF"ùP‡qëÞYG<Ñ}¨\I¤êR™Ø!–ÞgÝþ+ýj ÌMvš1Q{O`½§Ï©É-6yqšâŒ=¹‚z÷޼ü“/9y½´–6!_R•y–aU‰ @$w'°ûò­&—ÄÜòvþØûZ{8 Xhå½ùDwûû‡ÄùÄá°óö¯j5T¸¸1°õ"X1(€€=ºW¶f™àá¡òx\:ÞÖâüÀœèî=|7çØør¾ˆÿ'ùËP„z>³#MÍéE4¿ÞG/@¬zš·Þ¹V«I(»Od=±Ô~`iµR2<"Rú£.€÷ÙÛ}í7óßšnô_GOÓ˜Gw:$˜€JG^#ˆ;TwÊtZa=Ï'}íϵt<8pœÅ™wB¼Îûôû¢6öÞz½³ý3o=Ü–ä®·-̪“^)ΤW°›)a‰á |žO¦íÌø5 ä”{ÆCt;£ÅuåODò—éæÒÖMyÃLä4 ËIV:» ©ùWÇÛWªàâô>±ìŸçΔKXnGéÛÔô¿²ÇSÐs¨<î7˜#·:„æx±˜ýFãÃÖ§xS6‡8.‡'ɰ{A®=¡Óáñ@®#UÇTËü÷曽ÑÓôæÝΆI& ‘׈âÕ$ó E¦Üò{ßn}¨Ë¡áÃ€Ôæ,˸ræwß§Ý·¶óÕíŸé›yîä· •u¹neTšñNu"½€ÌÙK O äðz}7ngÃù¨O$£Þ2¡Ý+¯*z'”¿O6–²kÎg! VZJ±ÓýØEOʾ>Ú½W¡õdÿ>t¢ZÃr?NÞ ?¥ý–:ž€û1ÞØ«±V ù‡a4Ë̶$Çwc"+ȽTåÿ±}¾œÙv~Z&/—ÿÁ#²®ÕÜ ½Çé?·ùÏdòö±¿¢XëÐ-ÜJH>_ö,Í«Æ`Ê2@K½3ŵث±Wb®Å]Š»R¹·ŠòÚkIÇ('GŠUñGR¬>ã‹DEã•SK¦jšï•îOïm¤2*ÿ• ˜e?OÁ•ä_±™Ìg— þ·Ëcú¥•=û±Wb®Å]Š»a~k¸ò¬šö›¤ù‹OŽCu²j2¸‰"Uäx³‚¨ñ¦ù8Ýló]¯—Huñg€<@úÎÀsëøæ—ÝyËJÑõ}Aò¡³—M¹b½ŽÙ z~£ª)WF IäIذðß7/máÁ› 7„¥Rᬱ}üž‰•½ƒ±T¢ÿÊþ]Õ¤¾Ó-å•É//¦«#¹%Öøá.¿QÙ:lÆçŽ$÷Öÿ>l>ûòëÈ73›kkß©]Ö‹WhíËÀ¤¼Ûñɉ—Ïì×gÎ\1Ÿ»„û –_å ü7¤Ç¤­ÉºŠ‘¢vNVFçÄ€OrwÈHÛÐöWgþSÅÅÄ5ñÝ8Àì]Š»v*ó_ÎKRúF|£â·¹hê:,e«_œc,Æñ^Ûa¼0Ÿt«æ?cô÷Éº×ø“Ê_ó<†¯¦Øßò¥+õ«tš´þl¹ó$ïcŸ˜:·è!y§]‰Ó4JôÔ{Y%Øÿ/Å_š?“Þž}vE{²Ÿ5Š4§âÇ4½¥/XOívKÏ÷Gï'õ='5Ï&ìUØ«±VçO4y'I»ú†±§&¥~T<‘¬HцÜry)BFà ó;Mƒ,…ÄÐzNÈìÝfhñ㙄}ä_À,Ñ<½ä BÿO¾Ó­¾©«¬Pê‘Ù‰_’!!‘ 2Êšl9sfˆ ›™k5úìpœ'.(Y…×Î6˜2ìUç7œEž¡ucuaqÂÚiaBÑÉÌFåCqb”­+JæÀvtˆõPöS,ñÆQ˜õhØçóJ¯5Ê?1]›íJ)m®ä Êæ9ãõ l@Yj{·_|¶8õ7f-'jé¡Á$œM{¸ž—¡¦’šU·è5EÒŠr¶‚©=~-êOZïšì¼\G‹›ÉëS–^-ñõ´Ã+q]Š»v*ìU«^7K½ÔZ”µ‚Y·îcBÀ}4Éã€ïr4¸|\±‡óˆ7šþPÙ0ÓµV]åºb z‘ò&¾åÿ 鞣ÚÌß¼†1Ê"þØôŒ^IØ«±W—~eéWúmì^r°¿0ʆ+qêèhiÀˆ;òVüp‡³ösU,šp±¹þßÐS_'þcZk\4íc¦«²£ý˜§=©_²ÇùO^Þ)Âíg¥‚ç‹Õ´~±çóg˜¼Ë±Wb¯!¼“üUùûó°Ò~E-ŽþƲŸ»1µy8qŸ7ßàUØ>&lBCaûÙ½ÿ{ö½4OÔNÅ]Š»CÝÞÙÙ"5ìÉ JÂ$20™¶|”`eÈ8º½f²<"ú“Ñ'Ôü—åýL1kQm;tšß÷d£á?HËñêç¶è;OØÞÏÕ‚N> :Ÿ³é?òêiz±² %³¸")S£˜ž‡±¦nþ¨ïÔ> x´š¿ÝˈãžÄuá–Ä{ÞÍæ}$kZ-͘œRÜøJ›¯ßö~œÐéòðLè_i»'óÚ)âUqGúÃ—Ï—ÅæžG×DÕ&MÂÒxœK]¨ñê~{úsm¬Ãǹ¾;ìOmÇAªÈj‰¿|nCôŠ—–­$óšRkÉL¯yuá@Ü©ò,BáÔKÃÇ·¹§Ù½$»Oµ§¸â9'ó¿´ÐfŸ™ßñÁ·ÿ˜ÈÿäÔ¹ƒÙßY÷~§Ðÿà™þ!øhÿq4åb'¥©ÉO” ˽(æ™gi¥ÕÿÀ¾‡<ºÜ?ß%ß™ê£X´`>#l>4‘é–öwÐ}î«þ ±œÆÚÿßI˜ù“åM>»ÿøNù­þôþ:>ì1¾ÊÃþû¹<²ãþRiæ9¿äþn#ýßÃô>'¨ÿ)Ãû·»g<ý0ð‹´Y<ǸûÃô´1Aœõ9ÿ¹/.ü¿$yžÚÒjÿȳ›}w÷eño`úçt¿Ü•?=ú¿â›ïWþ*ááÇÒZS%¢¯ 4ûsÅü©—‹ú5îàŠikiùö°½£ÊmZ40¸·Ó*8ÓãéL¦RÓÙ¾~âîôºOhåŠ'—†§•mü]È(üŸæö¾²YòŸÖÉ'¯nO>\É4~µß,:¬\5{®Çì‡kœã,±Ü¸¸‰ãÇÎîþ¦cç_)O¯olEì+é4nx‰¥…±ž¾9£Õ {Oí§²™;G‡.ü×êô£ã“é>Æ{Y>ÑâŘìåË¡|Þqoÿ)4_ó¿ò6’þïáú#ÓÿÆ”áÃýÛѼëå)õã íƒ(½…}&Ï"T°£v “×Ç5z=PDZäú×¶žÊdí¸Hñ"8híÄ.ù÷‚OÍ„ÎçåXÿãâÒÕO´°'ý’n~üØ~ë/q?kçëÏcÇøñÀëCýôwûYÇ’¼Û>¿ëYߢ‹ØH²  ‘+Ä’;Hûó_«ÒŒ{ŽO¤ûídûG‹`ÜávŽŠ:¬Ã.S~ßÝ.ü•ÕeHuO,]šOe!ž$=@céÊ£ÙXþË:Pl[ó×gñc”ðÏi@þÃö½chìUØ«±Wb®Å]Š»xƨ¿áÿÎH¥¾¬¨iãõˆÌ_Œ©\ŒÆÎ/feð;J¤öùŠûÞ¡”>¤ìUØ«±Wb®Å^O¯~Vÿ¦®£ ¯ Åß+±râŽdøUó%·â2Ñ7ídý~ ‰KÕŵy¾ý)Gå¿õX!’ ýb$¸0†Ø3TÑOú¢¸7.dÇfvnhƒ_~ò¯?/€·¡Ç$sF“DÁâ‘C£©ª²°¨ ŽÄeoa Fà¯Å“Ïÿ4uBÒÓOÑt·1ÝjÒ´lÈÜ_‚•^õ™ÆþÔË KÚÍnHBqš–S_ ¶ø’€“:wÔ8¶£?éN?ÞŸWçOäãÊ•ÿ/ÄÄâðþ³ÇðáùsûS/Ë=oPº·¿Ð5w/£ÉésV1Ô¡RNçƒ)=ˆÁ1ÕÍö[]’qž ¦åˆ×Õ|g¹«v*ìUØ«ü϶M½zU­Þ WþFªÁŽNÞwÚ¬\Z)Ÿæ~Úý/¸ÿçõÓ¾H»-É¡²{íõ ‰m;ÑŒ½òõÌPòOùÉíOôOä'ž.«ORÅ-+ÿ1·1ZS¡ë굊CâÊÛCÉv.E ï<§þG2ÁFh5Æò—̽¥ÉŬ—•±™f¡v*ìUo4#,=B9¨©jÓ 2£Vño=µß—õo1úÖ†X<úÙêï°…}HëNàE{.n4µ8ǧ£ßv(†£•$Ü{ùÑüy¦þCW×|Ìž`³³kMOÓâÓÒGLòF¡+¶Æ€oC°*Õz!ÂM’mÁí²0iÎKŠs™Ÿ¸ÿªf­ã]мÛÌ–QE4ÚÏ–ïEÝZI-ÙÉ5 ™ '³†,ØáÖíÃ!aë4>Ñ<ÑâñÚ_gè¢Æ,5ÿ*}e´¿:hpÜ!â÷úr§¦NÛ¸¶?yB~Y“>³ÿ#7¥¯·sxš¹žã_-™..¡ØªÕÌVV³ÞNxÁoË+x$jYÜ1lÅŒÎB#™5óx·Ÿ|ñcæˆ-,ôøfŽÚ Y½`Š]¸ñ^!YºÝp‡Ð» ±'¤”¥2 "…~’\Õ›½#¦ùq¡¹ˆ*,ö¾¤ÎÈ£ˆWà€7M‰ÅÉÑi%|y¬’¡ò²ôÿËÑæ5Ñž?0¬ŠñIéÚ-‘7¤ˆÈ© ®ø ÆöÿåÎ`pÖãzål»D€ÖõÒt‹ÝHõ¶…äP{¸úM.V‹OãeŒ?œ@y¿å¥‰[ ½V]æ»—‚±êV=ÉúYÝšžÑÈG¹û'þ}œ1é§š¾³Â?«Ú~Æsš÷ÓŠ»v*ó=èc¿½úä Þéè)ŠêI'ö…~ŒÚh³ãˆ£±|ÛžÁíFo?½Æ>˜Çœ{ý=o¼_Ãf$­æÔT߈©ÇêÃ×ãO? Íýß=¾Ç…‰íAxÕ˃×^îIå/#_½ä:ޱ·µ„‰í$Ž»­W°­wöÌ]V²5Qܽ²žÄg–hçÔÇ‚6"~©ÊÇAß{žUÕê¨}ãyÒ†—¯LÑ€-ïÖ#±rCø Notyx¡î~{ö㲆“_#§'¬|yý·ðeÿ–ºWմɵI’^7Éÿ}DHÛæÕû†av†K—sÞÀß²ü-4µå4?«Öo䟘6º†‹60=Ä«tŽÉ–!DRh;TŒ¯C1’MlçÿÁC›S£„q@ÎC 4íÃ?Ö„ü¹Óu :Aoí¤¶24EªW«Jüòzü‘‘mÁÿßfê4°Ì3BP³âRóHÕ5NÖ[In#H8³F…€nlhi–èrÆ16kwYÿÈÕju8処+Ò/ø‹(òm­ÅŸ–ì­®âhnÖ炬+3°¨>Ç0õrÈHülöžÇi²`ìÜXòDÆCŠÁØýr,Í>QÕíu[›»+i.¬î$i£xT»!rX«*Õ…|ÙiµP1š!òßj=’ÕâÕO&(K$'# b,‹7D öïîêŸy*ëÍW:Ÿ_ë_PŽ g‘KÕ@øˆ+˜ú¸âôÕÛÓ{ªí\ºšÔøž‰ú¢@½«zy÷±¹ü½®7˜$¸|æxÒ =6ãÃÖ¯*øS2†xpUŽO#ŸÙýqí LaŸŠMðš®;·ªkqI>‹¨Ã —–K[„T³4LÄœÓá50|Ãí½µŠY4y£r–9€;ɉ§œù'CÖ,¼Ãoqyc4*ÊI#ePLd Îm5™¡,d%ö+±5˜;BÉŠQˆÜ‚ÒY?œü¢Úò¥í‰UÔ¡^[e•áIìAè~üÄÒj¼='²öÇÙ#Ú eÅC,EoÊC»Þ:}¾PëkŸ>èþ‚¤„Uc_«úÁkÙ‹~3¥¾!Ë·N»žŒJêûÏz¥©Ò®`º– ‘M©V G&à_|ÍŒ0Äñ>o ©Ööî¯ÓÎ%Ìxt~'‡ñÕ•ùÊ·š)›PÔ@ŽêtG!Š%CDmR@Øf·R'@r{a½–Í 2ÍŸiÈpˆó¡voÌÐf¹€ú#±Wb®ÅX=´ßáŸÍ;+ xZj¥c“²Ÿ¬þèÔûHœÞhgÅÜø_µúOÊö©Ú9@—ÏcþÈ_Åî¹–â»v*ìUØ«±Wb®Å^?ùÓ Ù_ù_„~òt'ü¨&þ6ÅÔvŒŽ9à ç÷nôhäIcIc<£pXwTÆ}v2ŽE~,Š»v*ìU‹þ`é7šÏ•îílÉt†9’ݤµJÜÒ´ÎJ‹£öG=F’Q€³±®úyþ£ëk¹×õY´EÞÁ,ì­îUYÑcŒÚEjÒ¹a4ò:mml³e8«ÑÃ/çzFÖ9ì~tõ*Ú]ØùsL³¾R—PÛÆ’!5*@ÙOÈm•K›ÜöFãÓcŒþ¡œ`v/8üÕµ¼/ êV<÷wQ#Bä“ÁÖ¡A=S,ƒÆ{]Šw‡$‘Œ/ý?ñOæ–£µŽ‚¶ª~ËI£}óºÃ Z?•»[/ч‡ß?Ýo‘<¹æ­;ÌúÖ¿q‹øŸÖ $eŒÍ"¸¿ù-+_ÑzÆ¡gOkÝ:÷ÿ¾d¾ _Jb‡Îßó›:‡Ôÿ!õ zÓô†£¦ÛS}øÍõšmÿ{þ¼R0ù"«ùGFŽ”­¬Rt§÷£Ôÿ³›ÕÉ/{äý³>-VCý#ölŸå±Ø«±V#ç%?™æµ¾´ÔdÓõ 5e…Ô»šõR¬ {ƒôf^›Sá‚°]çdöÀÒ‰BPŒ¹°Û¿2yÛÉGêž`’Ï[Óê4fb<;Ió/f\pâ˼n%ßbìý»Õ„K½Æ¿WȆ{å7iþl´–[$¶{R‰42¢—Ž%Não˜:9Æwêó]«ÙY4’D.E‘æ;ªK|Ã-ä:¥&ž’=ø¶˜[, ´ž©B¨PI šå˜@3Êܽa,Ю!wʺ¾z—ë«7©æûMVä)­dáaã_^)+÷ŒßНA§Ç€ŠÓË÷ ÿs Êt Kò¹î`µmèÝÏ"EÜ7®…‚€G¨Sü™–êø…:}vŸ´„L¼Xжߣô½´ *Š(ذf•óâ[ÅÅ]Š»v*òÿΛ–n“§®æââIBޤÂüÍŸfGÔKØ{!÷™'ÜùŸØÎ¬m–ÎÊÚÑ~ͼQÄ)àŠøfÙåód㜥ÞIù¢1j[$‹o+š"Ì|8²ŒI4[~aù#V¶’Îúáã‚u)$SC(䧨& ߯zØÜ2€Ž Ò‹Òî?.×è×ÓM¸“褧þFQ±hÔãíõø„|kìÙ”E$2 h^>€¡ ]4âAßšüX»`¿š÷æ×Ë"ÕOÅ{¢ Ÿ|½Gí)®Tv*ìUØ«±V#æ:Ÿ.ê1Ù- º•©é•,Ì }–ðÌÝ>“ÄÝ<'´ÞÙžÌÔ C‰qâú¸jÉǹ緷zœ5ÄeŒ}br±CÔ¬q»1ùæÎŽ{Ÿ)Öêõ·®Tê1”Gê’}ïh²´ŠÂÎ ("·E>J)SîsC9OWè’|0ŦðDd\—b®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUþf[2Úéú¤GŒ¶Óù£˜æ§è)›Ο¨‡Ì?à›¤¼8³q‘úaï~×¶é7ɪivZ”bî§ÃÔ@Ôú+›gÇ>(ƒÞ˜³v*ìUØ«±Wb®Å^{ùÍgõŸ'}` ìî –½ÀnPþ·ºÞÕâ¾â˜ùFëë¾XÒn «XQ‹F¡íî¹D¹¾‘ØÙ¼M&)D}›'YdìUØ«±Wb¨=P_6ìilRôdú¡!Hõ¸žå·_!ÇÕŒž¼?®¿£Î.4Í«˜dš}f8Ù·¥Þ“µ*h¾ŒAkó#,¸¼fNÏí‰Ä“” kýÌi’þ[jO©ùZ &»’òê)%ŽâYË4ùsâY‹@†½>ìŒÆîïÙQͤÈÈ‚A'óøóeÙ H¼á­Íåï/^j–Êæ0‰aU#„j×%eÕöÖºZ]4²G˜åñ4ó›o1ù÷AŸJÖuùý}TxùFÂ2rA¢Q¸žJ†ù:ãqvŸhi¥.sxòÝÈû¹Ü=*}Ø«±Wb®ÅP÷Ð}fÊæÚ•õ¢’:u¯5+ßçˆjÏŽx!ê¿óïËÿSÉ^oÒùômRÞç£ë6Â:צþmü{fSà’}ƒ‹ÊŸóŸ7†/Êm ÍKsæ vb>ÉH¬nê§ý“)ú1L^% ÅèhzdNÒÝ(:|1(Û9Œ¦ä}ïkeÅšg¾RûÓ ­Åv*ìUæ?™Zœõ¿­èÒK6’±*=•¼ì­ÈYŒU«QÒ§6Z,¸â*\Þ¿Ùív“xr€'Q§§ØÆ<±mùle¾b†î×SR‘ßÈË?õ¡XÊÿÏ@3'9ÍÎ4G“·í¡\XLeèþÛûÉ£éº.Ÿj?AÁ6“Q¹Û+%6º×—ι¨É9Hú¹¼&¯Q›$¿zI#¿§Ã¢c•¸ŽÅ]Š äÒt©fK‰lmÞâ6Y#•¡ŒººU•ˆ¨ ŽLdeÈŽ«( >eqÝŠ»v*ìUثɿ3?Ó|çå­/¨&"G]¦¸ILÜvhô“æö¾Ïz4y²{þÈþ×¥æÅã]Š­tI£GYOB¡¦2 ØyoæN‡å½IŠk-28ïî¥ôã•E¨™‚«'`G|!í=œÖêså"s&1Ó²ÔõË}ÃÊ’jÝJo €\‹)ŠR@ª·ÖQ=%€C_âÞ£ úp´êûF&5mêz×7.›qz ÞKko%Àn¢V‰Kƒô“Ûá$À΂?Çb¬cóØ]y'Yˆþ̯ü‰u—þ5ÅÄ×FñKÜÇ+î=&Ù¡50<ñùÎ?ÊgÍì=”ÉÅ¢ˆî2mþ–ez7b®Å]Š»Y ,ŒŠÜ]”…=Á¥+ôbÆBÅ<ż…çÍELz¯™ˆ‰Å$Ž)gt ö)HÔåœC¹â³ý¡”V]FǸÈýž–]ä­KÐôo«iWbþ)%y&»R¤<¢ˆ@âMãJW##eè;C‹Mƒ‡¸Á$™wž_¡‘ä]Ëóî™u«yVúÊÆ#5ãz- kÕŠLŒiþÄ”MKí–yô“„ËjçÐó›ï/~eëº]ž‘{`‚ÂÄF äöèߺÓZžeÂrÀb7?gv¦§qN†[Ç ®ûdú>—ùžuKKcQˆØG*µÌÐrö€X£å¾D˜»Í“µ|XË.AÂãn_ô0Á…T‚7ôØåo` ·Š»v*ìU˜ÿÎLmõ?Ì(Ô¢¶“"~1=ìm@{žK÷fH|Q‘ÜKíÜ-Žçà· ¾Ròe¡r]FòQôaº©cÛncïÅ”^ojž•¬1qãÂ4^>P)œ¬Žï‹å•ÈŸ5l nÅ]мóÌ7ß™³ëwv~\µX´¸Š,7NŽ@Æ¥)ÍÄOE͆àGw¨ÐaìèጳJæyûÿ£ä“Ü~ZùÇÌRG?™uˆ9/Ù*†W@zŠ*Æ¿@l´kqÃ苟Ú&˜ƒû¿[>ò—–aò¦”tÈg7!¥išV@„³*¯@Oòøæ£?‰+y®Ôí«ËÆEmIîPë]Š»v*ìUØ«±Wb®Å]м›Ì¿é_›zLMÒà¥Oò &Ûé9¼ìñû¿‹Úè=•÷“úÒó5ã]Š»I¼ÍåËO3é§Ý1ƒ ELr@4î(hF.ó{Bz\œqß¡áçßò¬|×*®q­¡Ñ•‡½[† £¡¿ì°ÛÔÿ¢](Òè5RáÅ–$ž†âO¸J‰M²—xìUØ«±Wb®Å]Š»v*¥qs¤/qs"Å{¼Žhª ¦äáŒI4uŒx`g’B1Éä—‰ü½ÿW;où¿×-ü¾Oæ—Sþ‰»?ý^é‚g±ÍM ŠE ަ¡•…Axå$VÎçX䈔M‚,Ô:Y#†7šV j]ÝªŠ’O€k“$a)Y=À%Ÿâ/ÕÎÛþF¯õË¿/“ù¥Ó¢nÏÿW‡ú`˜ÛÜÁw \[H²Á&é"«i±T¢A¢í´úŒy 'ŽBQ<ˆäÿh^¯£úFßÕåǨµåZRž5Ë< ÕÑu¿è‡CÅÃãCŠê¸‡4Ï*wÅ]Š»v*ìUØ«±T«Öt»Û~¾­¼Éÿ„dñ>njáñt¹aüèH|âT#î}O-ßZ“S ë0öY"J~*s¤~{ì‰~ì7§âí]мSÎß—¾SÐL’;ß© ‰ßÕK‘<Þº‚¤¢ xÈR+MéóÂèµz,xëz³çú•eäO'éî²[hÖÂD5G‘=RèA”¶ø¤4x£Ê!âä»v*–y’¬ywW·¦[+¨è Å §¬âá!ä^qù=/?-]DzÇ{%³Er¬œÝ÷±s½,‡tÏÝ¡åo^ìUØ«±Wb¯6ó5ÝÙüÍòý™¹{kUY 5N@×cÏ‚¡d~’ñ}©šʸ!ÄcûîþtÑ. Žæ m¥¯¥24oÅŠ·4e¡Üeoc“œLO")æß”å­ï|Ã¥Á)›M¶=­TžR'!ÛâUvY“£Åû L'Ÿ7¾Ñ•½ºU´¸¿Ó®l­nšÊât(—Qмd÷éàp‡W†YqJ—#êRÊÖÑÀ‚4³×!]–gaœ{T³E¿Ï—Ï'é/2?•ðz@†aßÈýñý+d±üÏó ›{û‹m Éö”[S=@*Îá׈D´ý«ªôÎQü<þóþè3 D¶òö—•hòI\9[“sÉ€=@›z.ÏÐÇKˆc‰$ôÏšìUØ«±VCÿ89"Áù©ù‡`O ÙœD>Í!¿(zm·1LÉŸ í8ðê2éËï/»p¸‹?çá$+È1‚=F¹ÕЧí#¶ƒé¤0¬åv*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»y-Ïï:ŽþŒ{VÀÿÍC7úîƒÚÇnÇ÷Ÿ÷ïĻv*’y¯LÕum!­4[¯©ßú‘ºNd’*;ŽQØ»ËÔâ׋,x£Gjïyf¯eç½öÆÆ]~[‹û÷áooåËÈP[ÕUP*i× Úi3hu”ÆÙ1ˆû¬«ë~byb(.ïõ—kiÜDfIä•bfÞŽ+ÐÔZôSìýY1†=Æõ@_»w¯iâQaj'M8†/VU<•߀äÀíPNøQ^$¨P³²'—b¯&Öü×¾sÕÒ>dMþŒÄ×Ý¿DÿÀñðùFgïýlï4ÒÎÅ]Š»v*ìUØ«üÆÖî,,àÓ­Ç%ç&™ÔÑ„IAÄò‰ü3?A„H™œÁ¶òi°Ã3Âr_øGO讬7ËÞNÔ<à —Pɨޟ©%IgG…zœÏϪŽ3G›çÞÏ{!¨í8‘„«=O ¤–úªêqAs*~Ž5y.¢;€¿²¨CÝ¿VS.Ð Žnïü5CSNCÂæg.”ˆüG_'©EÃB•)„RÌY¨¢‚¤Ô“óÍ96möœXÆ8ˆŽ@Vûý§šü[Š»v*ìUØ«±Wb©åÔÔOù8¹‘¤þð<Ƕñ™›Ü?ÝŠ*3e„œŽÂ¡j~’3oΑ ‘ÓŸÝú^»ùy©ýwB®k5‹˜¦ßįњMv>ß{ïð>í/C៫áøãúGÁߘZŸÔtµF¤×Î"¿¦>'?©~œt8ø§}Éÿ‚i~_BqƒêÊx~åú¾/"de Ì9!=ÅJÔ} æîß”ž¼¾ïÐö¿%Ê/§¨ÿòq³A«þð¿Eûÿ˜}ÇýÑy'ý/¿èóþfæïø>„Èÿù+þýïYÎ?O;v*ìUØ«±Wb®ÅZ Ab*EìXÿä[M~ÔïéIjkÚ¬%^Ÿìs§ù§²‡ œ{ëzö.áØ«Ï¿7ìg¾òÝ´vzsj†í1rI,A£r]D[þÈSQMüi‹­í8c,Û´óOç·ŠÝ4‰Y”õç±t‘¸Ž®\¨©ùaq#¨ÕUpýRò¤úÝÎi?˜£ôu—õMÌ|BqýëðÙvûp;m1™€3æœâÞìU~‹%Ìmº¼R+b¤XÌl^Gù2ÌtI+ð‹„ {˜÷ýYVGiìAýÎAý/Ðôܭ튻v*ìU‰ùßÉ«æ«hd¶”[jÖ„›iÍx°;”b»QPGL”eNƒ·{kb O ãÈþƒøÙ‰I¡~mÞÂt»AVɇ˜Íª'}RñÉÜ^~]ŸÛ#áÊ~žûxLëÊ>V¶ò¦™õ(_Ö¸•½K«‚8ózP7¢Ð\„¥oSØÝ“ .lÉïý‰þEÛ;v*ìUØ«±Wb®Å]Ч?ó…Ž©ùëçèÒgÓï¤T=J RŸøeûó&<ŸíZ¬¿×—û¢û× ¬|Eÿ? gY-1ÉÃkÅW­H:}¤ ¾~ÿþjÔ·ý!ÝÕ\Ôþ[ó¾Ðñ?É™þ¬ÓGþ%ßã?ÍOú–ãÿ¤;¯ú«å°;í ü‘ÙŸêÇý4â]þ3üÔÿ©n?úCºÿª¸þ[ó¾Ð¿É™þ¬ÓGþ%ßã?ÍOú–ãÿ¤;¯ú«å°;í ü‘ÙŸêÇý4â]þ3üÔÿ©n?úCºÿª¸þ[ó¾Ð¿É™þ¬ÓGþ%ßã?ÍOú–ãÿ¤;¯ú«å°;í ü‘ÙŸêÇý4â]þ3üÔÿ©n?úCºÿª¸þ[ó¾Ð¿É™þ¬ÓGþ%ßâÿÍi~òìhÇ£}VàS¿W–˜þ_ó¾Ð¿É]˜7ñúhÿÄ»üIù¹ÿVHÿäAÿª¸ø:ç/òeªŸŸìwø“ósþ¬‘ÿȃÿUqðtÿÎ_äþÊÿU??Øïñ'æçýY#ÿ‘þªãàéÿœ¿Éý•þª~±ßâOÍÏú²Gÿ"ýUÇÁÓÿ9“û+ýTüÿc¿ÄŸ›ŸõdþDú«ƒ§þrÿ'öWú©ùþlj?7?êÉüˆ?õWOüåþOì¯õSóýŽÿ~nÕ’?ùê®>ŸùËüŸÙ_ê§çûþ$üÜÿ«$ò ÿÕ\|?ó—ù?²¿ÕOÏö;üIù¹ÿVHÿäAÿª¸ø:ç/òeªŸŸìI¼·s«Þ~g vmª¼oõˆUx…¥ TÚ§ª€zæÇ b y9½¥;7‡¸^ÇüïÖö±à]Š»yçæƒ­K¨iþfБ§¹° ¯ n¾›™Õ?krC¿L!꽟×açƒ)¡>¾ñD_O&9ªj>sóè·ÑŽ–m`IÌâ)Q€W“¼ü=~x»}6ŸGÙ÷—Äâ5¶àŸ€{×ì­–ÊÎÞͲÛÅJÇ©¨P ›'Ì»É?5|Zм—Nÿɬ«7ë0õÿÝü_¥à=ýô?áRûÃ<Í+ôS±Wb®Å]Š»v*¿0|½wªÛÛßX!–{Nk$**ÍPÕGréï™úâƒÕó¿oýŸË¬Ç ØG±ÝÄs1=Þîï6 ¡y§Uòáx-½»7)-¦S@Ý Pƒ¶l3i£“sÍó^Âö£UÙwQ‰;Æ]ÿx?Šgº/晩J–·±›‡¢«3„±Úœ¶"¾âžù®Í¡”EÃéý‹ÿ6ªCXœR>w÷í_^m~aÛß.›§cq,-jÜgX¤d9 !Of§ßކC‹„Žhÿ‚Ÿ8ÓÇQ†r†j\$LºíÜ~ô'对=â]é—“4ÓFDð´Œ]Š+бè >üž¿ øvÜó ˜2ÈÊCÕ6k‘÷ù¡ÿ25»‹{‹M6Êw…ÕZyÌNÈO#Å*G9.ÏÂ2!Æÿ‚7mdÇ“ S1 qK„‘Ïhò÷±VÚ=BÏòúîþ{™íÐYÒF•ˤfET I¨¨ßéÁ#œ6 ºhj0{?“4ç.<• LÅ(ô±¿Å‡ézÇ™%•ì´û›‰î®×ÓÔwp+È•ä~·Úì3;&,`YƒÀögkö”äqaœå<‚¹’{ö³·¿ S¾‡Ìz Ò5ëÜZܿƒz¤ò§Z:1÷à ڈj×aíÎÊS)shžs´ }èÝÆÒ2…‘%&NL@‚±a¹ý¬´fÄvÙÔ˱{g eáÈ ˆÜKÕg•Ñâg:Ì¥¿‘nãÖ'â428PŠHûD6k±œÃ„P}+¶0ê±öHêgÇ’…Ÿó£·™ý~Ö äëÕ/ol¬öSªW³òB‡è`luSáù¾i솀jóeÂÀ÷Ükäiù}¨?_ú”¤¬wªae;RTø’£Çb¿NW®ÇÅ îvð?í¦×øRØe?ç Çéÿ05Ô|À,`«¥š¬(£zÊæ­O}Âýèaà =Síþ¼êµã 7Àˆþ±ÜþðAyËOM.úËOO÷E”*Äw~NXý,IË4“ã‰=å×ûa Lø°àÅñ¹Yø›/JòWü¢úwúÿ'5:¿ï ìÆÆfqÿt^IÿKïú<ÿ™¹»þƒáò?þJÿ¿{ÖsÓÎÅ]Š»v*ìUØ«±Wb¬sò;ýèó/‡;=þ™ó¦'æ¾Îþó'¿õ½ƒ ¶v*‘ù·ÌÖÞSÑeÕ®PÊÁ–+xâd•êUk½'Øbãêu8‹ËÿåfþbZšå d*Aú¼ÑÇÁŽÄJX‘ZìÄpº¯ÏçˆÇÓîz懫ÚëúM¦±e_«Ý§5ª°%YOº°*p;Œ9FH‰©†-®ÅVº,ˆÈâªÀ«v8 ‡ÍžHóF· Ay•¥¶¥Î!T‘½6ýØ=}ü22ˆ.»°{[>–2ñø€‘ß·É•ÿÊÈó‡ýKÈ«Ÿù§!À;Ýÿú'ÖÿÊ9ùKõ;þVžå·ò´…FÌ~­tûÿ±ï_ôGÚútçý,˿ǟ˜Ÿõ+IÿHw˜ðŽõÿD¥ÿ(çý$Ýþ<üÄÿ©ZOúC¼Ç„w¯ú í/ùG?é&ïñçæ'ýJÒÒæ<#½ÑiÊ9ÿI7?1?êV“þï1áëþˆ;KþQÏúI»üyù‰ÿR´Ÿô‡yï_ôAÚ_òŽÒMßãÏÌOú•¤ÿ¤;ÌxGzÿ¢Òÿ”sþ’nÿ~bÔ­'ý!ÞcÂ;×ýv—ü£Ÿô“wøóóþ¥i?éó޿胴¿åÿ¤›¿ÇŸ˜Ÿõ+IÿHw˜ðŽõÿD¥ÿ(çý$Ýþ<üÄÿ©ZOúC¼Ç„w¯ú í/ùG?é&ïñçæ'ýJÒÒæ<#½ÑiÊ9ÿI7?3ŸâËJ¨z´ºåôÖAú±ázÿ.v©åƒýŒÿâþ1üÑÿ©r?úDºÿª¸ðǽ–»[ý@¥ŸüS¿Æ?š?õ.GÿH—_õW÷¯ò×k¨ô³ÿŠwøÇóGþ¥ÈÿéëþªãÃõþZíoõþ–ñOXÿœ ¸½ºüøóEΣ‚þ]P{ˆB• !ÔìK/$Š–…í “žiË á‘&Çq~„ápŸÿÏÁãU±ü½½ßÁq«¬gµmÔ|Ð`!5`†œ«âŽÅ]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb¯%›÷_-ß×AíJX͹¿Ñt?^ÔoØþãþÿö½32ž5Ø«±V!ç=sÍZDÖ±ù{NúôS£™œ[Í;FêE7Œ€*|]÷cè´¹„Žið‘ËÔüØÉó?期èü èÂÑÇâÍL.ãù7²Æþ'û!úú_órR,xµô"ù—4Å)Ù#œïâCÕp«1†ãÁ¢o…›î<†nr—ÝCáÝ™ž}‘Úcüœ¸eýS±?/Pø*]ó_›™#$Çuqé£ øÁ܇É–þë¸6ꌻcµˆ,“¡åµÿ¥ôŸ8FùNú(׌qÇ¢ŽVEf«Ho(}Úüq‡eeŒEþš,#òÍTëó’*VÒB¾ÇÕŒ~£›Ñú½óøÄ|ü±ËýÔ¯Í>£§šn%pÍ3³~¢ôðO¸Â¤~åž@Y_Ë:²Aýó<¢?õÌǺ¼Hßãv¯`c9vn Cê&UïàÄ<£-´dÓä¼ B$"­Ð9FOÉÈÌíP'§‚öK.,}¥†Y~ž.½ôDÙSÛ™•\…¤ÐTšôœçߤ% 7&’/:ÿÊ/¨ÿ¨Ÿòqs#IýàyŸlÿã37¸º òÛþRÿ˜iâI›.Ðþïâù‡ü?ã@ÿR_|P¾m´“CóL³Ûü/mØmBÇ‘§ÉÁÉéeÇŽ¹Áö³K-jJpÚÈɉ¿÷@¯òu¬ºßšRêçãôÝïnŃTуW. t=ÍžÈie¯íA’{ð“’^ûÛý‘ ÿ™?ò¯üÃEÿ|gÿwñr¿àÿú‘ûäÏ|•ÿ(¾þ£ÿÉÆÍn¯ûÂú±Ÿñ™‡ÜÝ’tתz}oþfæïø>„Èÿù)þýî¿X·ÿ~§üÎw„¿Lþcó‡ÍrI•àêÔëăú°Ê#.Dø³v*ìUØ«±Wb®ÅXçä`,ÞbœÝÈöœ|võÏñÓŽOÍ]™.)d#‘?­ì»wb¯=üâÑï5O+$öQ™M„ëq®•X¡ Xÿ’8Œ.^ÒŒ±p¹äô_Ë­"ïEò~e|†;²$šH˜Q“Ö‘œ) QãÙèqbóe8¹nÅTo6´¸ÿŒoÿ8±—"òÉøæjŸñž?ø†U‘ÙûýÖOë¹éÙ[Û»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Цÿó…ñ ¿?<÷xM-3P€(èCê–ÛÿÉ1™äølÊõY¯/¼¾÷É:·Æ¿óðkuo,ù&ï‘åýüA{,±?G YEçй’ä;Ub¸®r¤nø¬ÅàbìUØ«óž¥æ=&ÎÚ÷˶Ÿ^t”‹»oI¥&"§p†ØŽÙ“¦„$H‘§oÙ}>i˜æ—Û­þæ;¤~ph·$C­[K§\ÅÜZ A¡­qòâs#'gH}&ݦ«ÙLÑß„ÇÈþ¯µéÚ¶™«Eëé—q]ÅÜÄáŠ×³¸>Ç0gŽQæ)ç3éra58˜Ÿ4fAÇv*ìUØ«±Wb®Å]Š»v*ò]sýóƒO—§­{Žü¡x¿†ot÷Ok¤õvLÇq?x/LÌÇv*ìUŠùÏ\óŒ¶CËÚw×Ús/¯û™g)À/ˆ"µ=|1w}¢Óçâñ§ÁU[|ûؘ׿6.éèé¦ ÿ˲§¿û¸œ.ïò=•s¿ó¯îOo!üÁž÷AšÒA°‚ßô²1…@œßnAtöÀëpÏAen\ù ~Ös‹Í»yF®>©ù¯§eºD'ß•±ˆu÷^Ù¬ˆ¾ïÿ=O£¾qù‰~’ÎsBýPìUØ«±Wb®Å]аß<ùwYÖÖ4ù„À7±$%_Œ1Øšm¿Ñ™Ú<ð‡?›çþÛû=¬×ˆË ®1ÿ'ËçÈž›Õtæ^~4/4Ú“v7¨í£¡í¹JŒÙxØÎö+‡Ú˜I€Å”_óD«ìÙ9Ð?/õ;ˈæÕ£6–*C:1¬€~ÈQÒ½ÉÊ3ë¢Grô]ƒì§>A-HðñŽ`ýRò®žóòzº"ÆŠˆ¢€ª£`Øšb_p„@P3üÍÓ»]V:r¦)‡rÑ…½þO£6Ý’ÁsãŸðKìÁ Øõþ1Ã/|y–ß©ùe¥sšëX|1«ÀOó5ÏÐ(>œ£“aïøv_òjd>ŸD}çy}”>%™y¦Îæÿ@½´´ŒËq*¨Ž0@$‡SÞƒ Ì 4„f äúµLš\xǤóƒò—µ'XžçQ´h!kg\²±’6á'°9›­Ï Àz¼7°žÏë4zÉO63œd]Ž|Q=‘M<ÿ¤j:½œztwŽVg TP¥~"2XÀ›.ïÛÞÉÔkpãŽq˜È“Ë»ÍSÈ:V¡¤é·0ê0%yù¢’¦«ÁE~{Œܱœ£g°}•¨Ñé§ ðà&v9ráÉ™ÿ/îd¹—PкJKÉfHFV&§4ö$S¶diµÀ —Íç=¦ö$²Ë6’ˆ–æ¨õáé^[WDƒônxY¼mDzi$„D„t*Y¸Š{fO„oaå»k-b0ÈDy#Â=ÖxYõ\ù:}>ûÖ®èªgvÔ€ÌÔ€œÖÂpAÔµ½Ÿ®ËØóÖ²f rëêÉØšæµ ò7—5­+ZkBÑ €Á",„r,¤„Ÿ ÉÖg„á@õyaýÖèõ§&lf1à"ìs±ÜSO?ùz÷XŽÎçM„Íu 4r * ÅAøˆèGã”èsˆX—'síï³Ùµ±Ç“x§A}'~½Ä}ªžAòýÖku>¡£ypáB  Ûì’7$àÖç A·Ø>ÀˡŒy£Ã9š¯èwy'ä<ùsZÕu¥¹Óíx¡pÈ ÌHøˆñËôyáQ=]·ÎëušÑ“3(ðv9Ùï,ÃÊÖw6•¥Üf+ˆ•„‘’ »Õ`êd%2G'½ö_I“O Å á”A±þqyË-åĉ§¹G–FSÎ=ÁbAûY·†¯wƵžÇö”óNC £"yǿޡþ óGý[Ÿþ?ù«%ù¼}î7ú í?õóëf—ú«¤M~Ú•³@²¬B2̧‘RÕû$øæ»4f ·Ð½€ìMVŠyNxq×.—ÜK:Í{énÅ]Š»v*ìU}7Õì®gééE#×ýU'%d]—ÃÁ9ÿ62? €üŒ·ã¡êwTþöíb­?ßQ+uÿg3ó§dGÐO›Õ0;wb©/™¼Ó¤ùNÀ_êŽÔvá€ÒÊÝHPH¤šbѨÔGnO>Ñ2/§ÕRI´8ô»§oƒQ6Öç‹7w‘uùïůÀeôðžúZVVPÊC+A ƒÜbîÅ.ÅRí~Q…ªNiH­.\ÔÐ|11ÜâÕ˜Ô ò/4üœŒ.ÞÊz=ë¨êÃÿŽU“›¼ö*?àÓ?Óýz.Vö.Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb©÷üá ^¿æ÷æýxñ´™=:V¾¶¢µöááß2cÉðÞÕ•êréËýÑ}á…×¾Nÿœýµ/ù]åÛÝ©¿?å~úÆé¶öýÞø²‹Æ´Yº>Ÿ(èöÐ0ÿeœåò ‘÷¾9¬e˜þ‘ûÑÙØ«±T=íõž›l÷—󥵬nYX*¿sØd£#A·åŒ$÷<NÕÐÜk^™£E­Í©]<–O4F_J0Ì9ªÕiß7³Ç´I— Ó3éO<“ÈqGÕF¬íµòûÙÏ?.µ=R^Õ¦HgU%Œ_¢•<Ü W¢×ç˜Z½dgóyÞÜíüyñœXÁ#oQòîNÍkÈ;cÞmó†å+4žíL×SÔ[Z¡œ¯RI袢§ðÌ>žYNܧeöVMdÈŽÀs?ެþV—šâA¨\yp Ðú¼.JŸ ˆ)ôñÌßÈãä%»Ñ¡­)<7¯»Ó÷sz7—õû2i‘êz{Ud¶x¤ixŠæ¿6#ŽT^W]¡ž›!„ùýã½4Êœ7b®Å]Š»y7æú'æ–ïÎÈßVFù%ËrðìùºìÓè#Íí{ × Íë¹ýKÌ÷v*ìU'ó>»—4kQÓÔt¢CiÎG4PO‡s틟ٺ©Ì1¯Ÿ¹ç\üÒ{3æE_÷Õô½88~× ‡÷œiûU­;Ó Öf øÇËœ¹ûù[Ѽ­¯ÇæM MSÓ•«ñP’¦Ì±ê=Ž“í= Òæ8îÇOrs‹¯v*ò¿Ìuú‡›ô[¢0øˆf«¾C,ny>£ÿwƒšù™c/«û‹6Îqû9Ø«±Wb®Å]Š»v*ìUØ«ó‡™çòÚÙ›x’g¸i9,œ¾ÊèTжeétã%ßGö¿Úl–1DHÌËc|…w{Þo­kšŸ›/ Vˆs»¶¶„»úÔ’{æ×â‰|‡¶{oSÛà wåFúþ“ú¹åý(hÚE®Ÿ·©ò˜Žò?ÄûüͶi3äã™/»û?ÙcC¤Ç‡¨¯ëÏÛö&yS¹v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±T“Í÷?UòÖ¥%iÊ#üŽ"?øÛ/ÒÆòö·QàönywLJý7§ô§ß”VUòE¤„PÝËq9ÿ‘†!ø Îñ>Ìalë`ìUãÿ›ò髿/-~’˜=¤.úÏ‹ú³Ì¼ÜPPòËJ×a…Òö™/—Qä£ù}ä‹ý ÎßA6sêÍ4bÔY*HèC+ú`qïÛ=¡<2€«òz‡–!k_/ivrL“Ímk2¼ny¤aHV´éÛiÅB#¸&Ø·;c¾|¸ú¯“u¹+NV’Åÿ#‡¥ÿbãk%X¥îbŸ•0|Ÿ”§Ö&žAïGôÿãL¦|Þ¯Ù|: œd~Úý Û ôÎÅ]Š»v*ìUØ«±Wb®ÅXך¼ë¥ùSÑŠé^âöqÊ+hiË…iɉ; ìžÿFd‡ÁµrâÉ#ÞOÞû‡ ŒùÇþs~ÀÞ~EÜ\H°Õ4ë’Ag·Þ¿ñ—¶)š|™7¯å=ü,àOîÐ'ðÎoR+$½ï’ö¼8uYôÚm<Ês±Wb¬Íúÿ‘u[)4]_VôÕ&S2Û¬ h[uøQ€ßc™Ú|Ybx¢²´:ÜSqã½¶º­þ!+°üÁü¼òÕ¿Õt[Iý?Úh`ä>.ó:³}9dô™²‘s3ö¿S.,²æy{€=GÕ Ö´»]VÙY!ºA"#ÓÞ”4$vÌ 0‘£ÌêôÒÁ’XåÎ%qм§ÎMgæv‡&·OÑèd§¤œ¼KWj 8ò¯n»fÓM~¸y½§d‰žÎÊ1}vysþÑtõGHå’E‚®Œ9+) ŽàŒÖƒc›Ì¿)RH¯¼ËQ¼Zr\F!ŠE*ÈÁ¥H=^<‡Ë6=¡Ê=ôõÞÔa„“r£uðý<žŸš×v*ìUØ«±W•þsÂñ&‰©Ç³A,É]ú°G_øÍ¯fKêgìŒ9`zúGéz2¤ðÇ<{¤ª®¿&´y)ÀÄz*bÁØ«óÎ…qæ/OegCy$ð!4ÉZ­NÛ‚iï‹·ìMttÚ)}'cñFiÚ]Úùf Q˜ ¯ª}Vi¡q¬|U¨ïÜïL\}F¦RrÀmÅÄ÷ÚÉÞ[>WÒåÓšqpïq$Í"Ž#â ª(kCÅA8·v¿hþo(pìãâY.©Ø«Ï?7¬}mÒùEZÖã‹™H?ðʸCÕ{'Ÿ‡<¡üá÷~ q¤^ CK³½­LðÆíþ±QÈ}¹Íå‡ ˆ~åì_æt¸²ÿ: ükµvÅ]Š»v*ìUØ«±Wbª7–·kÂêçAÑeEq÷08c"9Œú\Y…dˆþïYm§iöD›;HmÉØ˜bHöÿbd”¹›jÓv~Ÿ÷Xãêĸ"r.c±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»a?™—žŽof æ`HñH–§þ®gö|.d÷Îà•¬àÑÃç’_dGë1zÿ–ôó¥hfšÃŒ–ÖÐÇ ÿ‹ðÕÍÃÀà‡ î ¦-ÎÅXœ4 ^ÜÅqæ×‚+ÓŽ–éà“Ó H¢«­EIÞ˜¸Z¬XI¼•~ö:¿”IÕíÅæ¨Ü¼%‚xgŠ£ý;­…ÆþLÅ1q%åÏÊHü¹æMjU® ¶2lðpfå*üjälH?g¶X;7Ø—'¥bíа?Î ±m䛘kCw=¼Þë̼]iʱ:Uò=¯Ôü¥¤CJr·Y©ÿ‰—þ6Ê%ÍôÁÅáèñèßÏÒÈ2.ÝØ«±Wb®Å]Š»v*ìUØ«Ìüü—Ú&º¾gŽÐÝØËa-ƒ¸6Ò¸p²t4û_¬eÜSÄûCš}Gæx¢`aýS¾ÿoÞ?%¥×˜oü¹ ­£CaåÕ™îoŽÂG‘Ìœ}ªmZîÇ%-­ÕögªÉ€F5rï$Ý~<ËÚ2—ÒŠ»v*¥q(‚ g="Fs_òEqa’|1'¸='þ}óbÉå¯;j„mscoËSo’‹¿÷Ý;}9”øŸebÅã¿ó•:oé_È:ÛVŠÚÚìÔ}RöƒØöC_lR~XÜ ü•§ Õ¢3ÄÞÜfr?áHÎ\+)|ÃÚ8pë'çGì ¿1±Wb¬Í>GòôZN³«Yi‹&®ñÜ\‰¥sê5]™P±ZŠ’\ÎÁª™”bNÏGÙ½³œåÇŽS¨X9{ù°í?]ò^A“N¹‚3­eFŒÛ“3Üž\$ñ ±¯-†ÞÙ—ÛÈH" :ÔøÚƒ2t¦wî㱥¨9<&¸ÅwÁŽXþnÃ%Ô+ªéXi×-HoK—Z¹QAÏiï™2ìó[J˵Íì©>A9qüö½"8âBí*™[œŒ m@9:š+šâ^RR'ŸEø»v*ìUØ«üÚ²ú×”%œ ›9áŸÜL'þNfwgʲ{ÞÙ|ܰ?œý?¡äËϯyWIžµ"Ý"'ÄÃû£ø®nÜ.ØÅáê²;ùïúSÜ]c±U“4‹ ó•UŠ!Ø3°úN, "ù¬¯@ÔŸžç±´º{­7\·]AQØ1ŠYÕ6ûŠøbé5ú~=œ¢#,Rà÷€kïûmè¸MتMæ½4êþ]Ôlr–HY¢2GûÄK(ÅØv^§ÁÔB}ßÜv,'òâÿë:Y±¬–R²þDŸŸ¼¶iõð©ß{ö‡üµþ.„â<ñH„½Cíâù3Á{÷b®Å]Š»v*ìUJæâH$¹¸N”¼ŽjB¨Ü°Æ$š :D0ã–IšŒE“ä’ÿ|¯ÿWÿ€“þiËÿ)“¹ç¿ÑŸf«”¿S¿Æ¾Wÿ«ŠÀIÿ4ãùLËþŒû3ýX|¥ú‘ún¹¥jí"é·+;D*°â´û@xey0ÊP§eÙ½·¥Ö™ áçϯ¼Ã+v®Å]Š»v*ìUkºF$Œ4˜ÐI$ⱜÄA”¹)6›æÍV¼66W<®J+# .ç`+—äÓNÈÙçû7Ú½³1ÅŠw.–â®ëþÔï(z'b®Å]Š»v*ìUØ«±Wb®Å]Š»v*ÀõHĘº>†(-Z6zŠô‰~ôP3sÙð¨_{â~Þjÿ1ÚPÂ9cýçÔ~Ê{Îg:×b®$S°N*ðï.ùJ?yŸÌwÞc¹—•¥Ç¦±BêògU܆øP§_è0i†|“3<Н”ì®|Ÿù¥'•ôË—¸ÒæSõ…r+Ãêæt.ƒ’š Ó¿¾,´Ð8µ6?e½³½v*ìU俞M%¾‹£ÅñIs<“p(4ûýC‹¨íReÃÌ–{in¶–°Z§Ø‚4‰~H¡GêÌgÖð〈èù+bØìUØ«±Wb®Å]Š»v*ìUç—_˜7Vw~g’D„Ùi&;kXÒY.™™7vRC3t wË89<~_hçŽz‚@áÇQˆêe¸øŽdùo#ù³]Õ59ôO0[$7)l—°2/é1@($nHî;à”GFÞÁí}Fl§x€xx‡M¶ýcô³ÜƒÕ»v*ìU)ó4ÿUòæ­84d³¸*Êô˜/O|1æàv®N 6IwF_sè_ùÁ 7ê“W׬£–£®ÞL­µJGmm‘ºøæKá²}?ŠŸæŽuÿË_8hмäÔ4]NÞ 'Ô’ÒEB®á¨F*›ß“W^¯–î­‰ø­îÞƒÁdüCf“´cëÉóÿkqÖ¢2ïÜKÑs^ò®Å]Ф:çœü»åÙ…¶«vbºd,+ŽÌ¬HR;§/ŦœÅ³³ÑöF£R8±ÆÇ+°ó›ß6þY5ã]ÛyuîîÉ,O¤‘ÄÄnINd{š¦l#§ÏTeAêpö_hðpË7÷’~uúYç’¼Ùþ,´¹¹[c´‹C‘uqÆ»7Àé˜:?†@»y¾Øì¿ÊN1ãâ2øÜ²ŒÆtîÅX7æ®{«yi^Æ6šK)ÖâHTZ0ŒŒ@’9Wå\ÍÐdžý^‹Ù\0ê*F„…_žÌ;ÌÞxµó®‘kåÝJ›ô”ÒÄBB±¤\ '¤-f`ÒœR2‘ÙßvwcKE–Y²d ¿ðw{o%žŸii+s–b‰ßù™);ø‘š‰›$¼.£ žIHr$”NE¥Ø«±Wb®ÅR¿2iÿ¥4 KO¯=¼«ÿ‹8’ŸðÀe¸'Ã0|ÜÎÏÏág„û¤>]X/å%÷¯åû‹&5{;† ðŽU ?áƒgH]ÿµx8uÎhü bòîÅ]мÃUü¾ó&¥­ê’Û_Çe¤_HÑY“ÕZ9E Ô5ÝO\6öZ^ÞÓâÃŒJS€ù|Nãà­“¡~W¤:­ç¯¨^Ý7Õ–áQR8øšŠX‘P:üGnصÏWŸµ‰Ç„c½u?ƒ5ÒüãkS\A¥Ý-ËÚð3 Äs­(Hôíçµ]Ÿ›$xx¹&˜¸NÅ^?¥'ø_Ï÷ú3wŽÑhß½ŠŸ J|ó]ŠÜý+ÿ~Ýýô##¶XðŸëÇ—ÏôÏBÍ+ôS±Wb®Å]Š»v*”ùŸþQíOþa¥ÿˆœ»Oýä}îÚoøÏÏýI}ÏÑt™µ½B=:ÝÖ9dCÉ^#‚–==³{›(„l¿=ö7dÏ_¨ DL¯sËa}Gü« _þ[-¿ä§üÓ˜Ê1î/kÿ&ËWþ©ö_ñ,ŸÉÞU¼òä—ou4R‹…Œ/¥Ën‰¯ _£$OÄ_É"üÅó%ÿ–ô‹iôÇ y=ÂÆ *¸ôÂ36Ìzd -Õ{KÚy4˜c,f¤e_ ?±•ÚúÿV‡ë$ž ëøŽT<ƒ¿ÅÅÂ8¹Öþõl[мw[—òÂóÌ’êWw&OT¨¡Œµ´®Mx–¡#âã×¶Z8©ó­tû+&¨ä”¥w¸ÒOÊýõÍ—ùFßC½Öõ2éZ›j2]zqñdt6è@<>0¤Š¨ã¶ÀS#+ªzÇǧɟ.£Oʇ"8Gvþí»€fy¤v*ìUØ«üȹú·“u#Z4¢(—ßœªü-rPæè}§ËÁ¢ÉçCæCìÿùÄÍ$éPÖ“]Çy{!ñ7³IêÝe3!ñÂö¬PÓ*º²:†F2‘PAØ‚*ü®ü»².y»Î>Q–¢M6òK~,(ÀÙ\Knõë¿LÕvœv‰xÿl1zqÏÞ>ïÔô¬Ô¼+±Wb©V£å­W»KÝNÂ+«¨ÐD(-D X VIí–Ã<â(stý£Ÿ La3MìóÌg‘|Ñæ+mnÉ iæ-i%¼*¬Åq¢²•"žæË.f„LK×ët95úl2Å+¡½ž»_Änš~YI6¡¯y‡Z´ít+·¬10¢™K–j…'•:W*ÖF'r/hâ1àÊG‹$Fþêü|žŸš×v*†Ô.šÆÂêõ"3µ´RL!SBþš–â æ”ÉB6@nÁ‹ÄœcuÄ@¿{Ë¿Çq½\ùwÊ‚Ý{ƒo,¬Ã®Î¢0Oß›?ÊãJoaü¤…G6{ò°?[3ò»wæ/G{,s_,’Ç9Œ¡ ÉU”Bøæ¯„èrt=·¢ŽŸ9Œ¡LŸ1;±Wb®Å]Š»xÿ“‡ø{óZòó|0Ü Ò¼­ßñŽt¸gÅ^ß¶?Â4óu_ÜÙ©eìUØ« üÉó© i6í¥·£-̦7¸â¢…-E¨ ãˆzgtµO‰¸ˆºb?—>fÔ4éõWQ7Wë š P^âG4åÑ NAÃnû´:ly•ìWmçí <瘋Œ«a[P/8ódó/˜õY1  @è3i¥Ã‘ûWšc´s#õw¢/´5êÖÏæ ÈšXÝLÓŽb.µXɨP: Œ3bà^·°»WYŒërÄÈÅÏ~(ôû¢7òû\»¶ÕâÒ¤•žÆè2¬lIXÝT¸e¯JÒ†™^»1âê°·›®:s"qä±GøHîå_&Cçÿ3Üék•§¹Šêtõ&™M#&€)ìI~Ù¡Ó‰z'ªö÷ÚlšA>Ã9‹”‡1B»‰ß~ƒÞÂ4¿-yƒ[F¿³‰™*H¸’@œÜuâXÔš÷͆MD!±|ß²ý›í x9±D‘Q5gÈÏ¿íQÖ/5Ô’=?WyVæÌ^dóâÛŠ°?ð8qFãÈ´v¾¯\%:“!,[oÎŽüúùµéz±òrÄ¿Õ.O"wÿvwÍVaûÿˆ}‡±$Oa{øy?ß0O"Í3ù¦ÁZFe>½AbG÷›`üu|ËØ|Ó=©„¯û\‘˜SJžcuIWÑ‹`ć!¡Ãrÿàƒ–qí#Ó4z'š¼ÇcðFšÒÖ+eyÕbPŸ±öÜ÷93›3]\<}‹Ú½©‚9¨ÊˆŒlÖÑéùnz›Yåj÷HÖm­ÄŒ-'•a¸·bxümÇ—Щ5êÂ'zµû%ÛY´ZÈBÏä#(ôÜÕ×xùôz?›üÆ|½§«À_\’–áº-YÈïJ¼Nj´¸»íw´_ɺpa¾Ií.ù|6øÀt¿.ëþqY5+›¿Ý*²Ü37&îFÀ xfË&xaô€ùf{=¯í°sÏ&×W2MŸèŽáðÈx®õ¿#ëÙÞª„4&£nàÆ•#g…¸˜µZÞÀÖxdì9Æý‰ëú0~!ìv×]ÛÃu å è²F|UÇ!øÑÊ$/ÐmDscŽH}2CÜwUÀÜìUØ«±Wb®ÅXwæ&­õ=!tèúEûp u!¾óEûó;A‹ŠwÜððCíoH0Äú²šÿ4sùì>oLò6ƒþòÅŽœëÆè§­wãëËñ0?êì¿Fn_7ÒaðñÕ‘bä»cqòÕ—œ¬—D—PkYàu¹ G5âȦHͮ曌\MV˜pÝ<³TÓ<ÿùdmä±Õ}}*yE¼nQzŒ Txf¨R@;©úpºœ˜óiª¥·ã£Ùü½>«u¢XÜëq¬:¬±+ÜÄŠÈ›p ±$)ÈW®y€ÈÀsLñmv*Ó2ª–bTI4çäËŽ,ú¥gñÜçËGÙ¸äÊr}ÿ¹ýlɶ^lµ¿¼o2êðß3F£êqËÍàzÔ@ª«Q^™©–2§UÚù´³„| f;ó#ŸÆÍ³<ÃtÅ^g}æ/Ìûû»«-E[X¢’H’éã¡`¬T:½Ã*µvS›(aÁ ¥o]‡AÙ¸ãdÉÄH¯ôGµ:ü¼ò®¡å›¶ÕeW¾¾•e’4nJœAêÝØ’kL§Yœd"¹_ÛݧU8øcÓ_&e˜n…Ø«±Wb®Å]м“ó!@󆋿˜IÅg+ÜÀÔzÿ­ñú3sÙÓ¸˜÷=·³çóL¸>Ÿ_"˜¬®¡Ð†V©=l4ŠÙ¼PìU/Ö´í?R°’-JÓë°Eûõ·iž0H ºîzuÅÊÑê2bÈ %ÂN×ïy«yûÌÚÝ4ï'i_W‚0#GTõ]l*H §ˆúp½xì-6^§%“ð¿÷Å:Ñü›®_éš…ŸœoZd¿h¥EIŒ“A$DïÈ‚‚µ§Q×jûc<–š5Ác•Ûñf:6“k¡i–úU—#mn)òrY‹±$¹$âè5š©j2’æQø¸ÈMSNƒVÓ®tÛŸînchØõ+Q³pw¹]D°äŒãÎ&Þ[ä[Éô­FûÊzÃ<2;@B˳…¯b(Ëôæ·´0ò~´ÿ´É§'iŽ8¾éøIŸæ­ö7b®Å]Š»v*”ùŸþQíOþa¥ÿˆœ»Oýä}îÚoøÏÏýI}Ï(òjØ>¿êB´ã/1pÇ^•ç·^™¹Õñpo‡{×Àg0©_pý&¾­žõ%¾´¿ølÔqfþ—Úû7åûùº–4~œÚ,|­ô“jµýãÅjbè9èÊòqó•ü]§gKE†›ÃHÇÃîºÞñï7ÊK©Æcú†o4¿Ý‡À=­ÿ,ÿÖ{8iü@}Sµ8f‡ø¾/ÐÔ?/]8CÆ<£ÿ).›ÿ‡ê9¾Õv_ž}’ÿ,ÖL¿1b‘<ÈîÿbXbhÿÕ‰üAÊ´÷nßþx¥Ò$ò”bG»—Þ Ð|Ÿey Y%«¯;x’)ârIQ‰åQšÍT fo«êžÈk°çÐbȸDFC¨#c~þl óþÊóY‰-d{x½9äBäXž5Í–‚0ß«æðD×aϬˆÆDŒ#R#¾É¯‡é¦_¡ÿÊ¿óuÿ337÷ÿ÷݇ÿ#þ“ýóò'ü¥zü÷ÿ¨y3e­þèþ:¾aì/üjáÿ?þ™Éù‰ÿ),Ÿñ†/ÔrîÜ¿ø!ÿÆ‘þ¬^“åp—tÀÕâ;{­sU©þò^÷×ý˜Ùø?©¹äy–P:}y¿äþo#ýßÃô> Ÿþ4¥ÿ?îÙoæ”RúÚlÛ˜J̃À0*ú³ ³NÄ=×ü1K¿†¤>;}ÿ¡%Ð<³®kV&çLÔ"ŠvF…¦™®êˆFõ®_ŸQJ¤w°=š×k°qàÍÄá2˜ û„HÝ/5¹®¾¯6£g%ïþ›Ï+IéÔ€hc­+è`sr{­É—‚Y±Õќ̫¿èºzN‡e>›¤ÚX\²¼öñˆÝ’¦ž€ Õf˜”‰__ìMôºLxfA”#F¹}´˜enÑØ«±Wb®ÅZ$I4rN*MnXG•¬ÛÏ~~mN@[EÑÊÈ•û-é±ôWý“‚çØS: 6.Õù÷¶;DöŸhK'ù8mpåó>§ºåíŽÅXÍžtMGÌóùZÑ™î G->Þ“KâNäROMŽ.,5–CÍŽyËò¾ï_Õ¥ó—«µ¾¦á8E0!‚…$ŠŒ¢ƒù[ ‹ªìó’\q•0þBüË×n­4¯2]´º,k‰.RPF*+ê3R¡yø¸§G¨™™ÛÞ÷ ùØ«±V-ù‹¬ Éú•·îêoC΀‘î“}¸šì¼‰ø1ßÊí/ôw•!Å&¿w¹o'àAÿµúr™Þ»ÙM'…¤ó™âýì Ó ô®Å]Š»v*óŸÌGQ¼Ô4Ï&i’ú/©Ñîž´¬lå?gábý2ȯí>§&L˜ô˜Íœý×Cá±µ;ÉÍØíon¤ášB†&zw@µû5G¾>#žÅaðê3—yª¿urø¤ß—çSÖ|Ý êìd—Ëö’[†mÏ í†=ÈÛÿ“†{YìÖ—s‚&?i¤üžÇ•>ŽìUŽùÏÌÿá]#ëÉžîi±5x™«Sz;uÉF6éûoµ%‡Œ ‘4›ºówœô•‚9h°Í¢]:ƒF•Zî(90 EW'Â:<¾nØ×`£«Ä9áúÎþRz¥©·6е UµdV„ ¡ªÐ PS*{Ì\<#‡•mîVűث±Wb¯=ónœ|×ù‹ä%¨-úJöÖÝÔ-õÜväŸS¿l·ç>Üg¼˜áÜ ùšýÕ µàÝŠ»|ÿ9«¥ÿ‡¿9¼•çDNú•œpNãnrX])¯¥š¬K\ú\SƒùåMûfÇÊ YâßÜõÙ¸òéñÌGŠ^ þ­ïcº©ùßPÒ5/.j–ÒÏ-¾¿õ¨õʱˆä‘–èOÃÏÇcØæF¨‰F@ÿ S¶í¬˜ócÍŽ@‹„Ç¿p?]=·4Ïž»v*ìUØ«±Vù™£þ—òÓFµ¸°"ò/FÀ9—¢ÉÃyìï}Õø:¨ß)ú~|¾ÕËÝ_ô¿•í ·+‹:ÚMãX€à~”+›â½¿¤ðu2®Rõ?¶ÙN.•Ø«±Vç¿1ËåM2Ú×G…#½½gK~(8Æ©NL¨ U€¡ì>ÎÌ’–RLcÏÏãðb—ù—å{t×õ £qh¬¿Xµ’_T(s@hšUØ]Þ1Ùº¹0„ ù~רé:”:Æ›k©ÛŠEsÈîTžª}Á¨Àñz½<°ä–9s‰Fâã»y—æn‹=ͯœ4ÁÆâÝ‘nÈÔÒ9·ì7Ñ‚Q^÷خ۞Ÿ(ˆ5(ž({úÇ› ѵH5: BßìÊ¿V¥lÊ~G9ì¸Ì$A~Ïì~Ô†»O Ðþ!¸î=GÁ•»7b®Å]Š»KõËY¯t{ë;qÊyá’8ÔfZ ÎY†B3÷º¾ÛÒÏ>.8 ”¢@÷ò¿ùWþhÿ–Tÿ‘Ñÿ\Ü~{{â_è´ÿÔÇúhþ·Ê¿óGü²§üŽúãùì}ëþ€{OýL¦ëd¾Gò¾³¢jÓ]j0¬p½»Ä¬$GøŒˆÀQIì§1uš˜N Õì=‰öcY ÕË&h¨ø¢z{ŠYæ%ùƒPÖ¯ommÕ­æ´leI‰®[ƒWÀ]?´Æv†§[—.8JǪ?­é~›}SÒ§Çéñ§¿f¦÷}‡Ã>^ûiåï%ùƒOÖ¬¯n­Õmá4Œ%ˆ=®m³êá( ãÞÏûÚmn,¹ c+>¨þ¶gæŸ,[ùŽÙ1 ì5ô'¥FýU½á˜:mAÆ|ŸAö£Ùœ}§ˆoÃ’?L¿Aòû¾ÃÏòÿÍËé¤(Èj É2§û"Ÿìsgùìds|¦^ÀöœgB ç ûhý‰g˜47Ð.¡²–ešá Yfá^(ìì8‚w;–àÍâ|Ý7oö!ìì±Å) HÀJUÈe·È§yzÚY|‘ ²-fšÖeI¥Lœøî|kšœò5ù¾ÍìþžsìHãÕ,süî*ûØß•<Ÿ¯izý¥ýì –Ñz¼ØJŒG(Àש•©ÕBp Þ?Ù_d5ÚM~<Ù`#Å~¨žpè{Ê·œ|§­ëÓÞØ@²[˜ãPÆDSUìÄŽ“SB‰r=°öS[­Öœ¸b xb> 9{Ë5Ðíf²Ñìlîà†8äPA•hwšBS$w¾‹ØšYàÑâÇ1RŒ@>ðu7’|ÂúÜ—«n¿Wk¦˜7«xyV•¯LÚ f> ½éòlÞÅv„µ§(€á9 ¾¨òâ¾þç¢kZ5¦»`ö`…?r/ÚÇF«Ã”㕇Ö;k±ñv†‡'¼±=ãñÉçäß7è³»é4ˆvõm¦^Ü•ŠŸ£|Ú^)WÚùýŽí}BtÄ‘ß pØóÒ‰Ñüæ+A5VåìÝX;L%õ.Xó'èÈeÖc¨‹ûœÎÈö#´rê}DÎ2 ñqqd?iø§ …:ûæ¥ö`Þ*ìUØ«±Wb¬?ÏÚãXØ.“hK_êUÝ–ð‡v?ús;CƒŠ\Gxo»wòÚËÀþó/Ù¿é¹|Þ‰ùåuò¯—¡´”Ò7éÍÿ°|Q~u=órù®‹OáBºžl§- ©µÊi·d+x°JmÀêex~4ņKá5Ξ ùwæÏ-ùNÇT¾Ô¡y¼ÂÌ¢ð%8ý‘!'ÅöÉíN¸^{C©ÇˆHŸ©»…üÉÖtÛŸ>ɨIigï!g’ ÄÜÄ¿þQø¿ÊÅeãÎ'-Ðürzç<Ásæo,ZêW }p†vPvŒÓ˜¥E ÷ÀîtYÎL`žlŸ-Ø«±W~nÝˬëš/“¬š²;¬³ <ÇÓŒŸõW“c‰.§[Ÿ40Ç™?{Ñ-mâ³¶†ÒÆ"‰|*¸f3ëX± q(Šl[Š»v*ìUç?™F« þç  ×`Už0 ˆåÕ¸ÊÕ˜=;e=7Ú}h䆫³Ÿ¸ Í ¥üå·{*Zé’~”e¢£:˜UÎÕ¨ø˜{q|7~ÛDãôã<~ý¯ï?$ïòÓË÷ºNu©êˆSRÕdº8£¬kR¼‡bK1#å‘™·gì¿gO)dÈ*y ü?³ŒƒÔ%>dÓõ-SHšËI¼6²)r ©PŽ€ÈA¥0‚ëûOM—6 Rà‘­÷ïòy–¹åŸÌéí¢µ¼‘5k{yVxY&tt õé¾X%ˆ×öWjÊ"2# ‰±¸»øÑS×µÏ3ù•´Ï.ëºLºm¼×0‹‰R•‹p=J(oü0€ì{C_ªÕœx3b8Á³G~›^Ïc†(íᎇ¢UD_Q@>ì¥ôx@F"#TÅ“±Wb®ÅRÿÈÍ,y·þr«Jf¥——ãžòOcihUµ.$\¾gÈ=©ÔxšÉ÷F£òý¶ýɼã±Wb¯•?ç<ü²u?Êí#Ì‘')´UV§Ø¶¾‰¢s_yRŠbðÿ.j¥t7P&¯qoÈâÎ ?ü09Ìæ‡ Èó|ƒ´0xYçâ~]<©Ãv*ìU+óüú^ƒ¨ê6ËÊâÚÞY"î*š<S–နÀ=îggàsÂå"O£ùùƒËRy²ãV™õ™V{ˆÈ<èð–;nå‰^£§¾m2jø'ÀÏkªí¿Ëêœc‡Ï»£Ð¿.õ›ÍoÊö×7ìd»‰¤·’f¯)=3³zš ñÌ f1 „O1ÛÚH`ÔÊ0Ø5Ýl«1]+±V=æÍËzµ‘¾ó_¹°F—ë ÌŽˆ>&MÈ4é÷fFŸ,âj=]§eëµgÄï=©‚Ú~fÏcl‡IòÌ‹å[2!YðPiS'·èIß¾fËD õKÔ^/³±É#âf,·­¾ë¿Ç'§éz•¦±§Ûêv/ÎÖåÆH¡ˆ#ÄAÍnH’ ÇêtòÃÂ\âŒÈ4;v*ìUت×D‘94n ²ÁPƒ„@l<É…ü§çmOÊ—‹k’~ªOr€Éÿeûí&œp{~ÙW¢† s?¸ü‹Õ2ljv*ìU†~bùn÷\Óí®ôÀ[RÓ]¤Š54gWãÈ-hR>X‡ ö´a§É(äúf(þ>,;TóGœ<×eþHh®%(·Œ±È¬ÜHmù€#šŸ§ ¿Óvf“I?ä°>Çèúž™åÝ>=FÓ´i¦Cp‘•¥@ç!¬’pr'èÀñý¡œê3O(_ÙÈZq‹€ìUFêÖ Ûi¬îIo:4r¡èU…ųYc”M»È4é.<…æi´=Aè{¶ íöhÛG/üjÿÙ˜šÌq±Ì?GÿÀ×Û(ã5&Òþ„ûýÝþTz=4ÑŽÅ]Š»v*ìUØ«±Wb®Å]Š»`_˜“kœmⱂUÓ£"i.a©>ªŸ†¼7P½j{ü³c ÞÎï˜ÿÁ 6º¡QÅQ”œ9rÜó÷û˜Ì˜>e†Dͤ dˆH ?H̳¡ÆO'ŽÁíÿiB&Q—™ˆ¿Ñö„&Ÿ¤k~lÔLîOU¹½Qt;ì6~¬žL°ÅûÏìolê8Íž#êÈyÑîˆûÚ-m¢³¶†ÒH`Eù((3C)Kô>—M£ŽLˆ÷ •°7»v*ìUØ«±Wb®Å]Š»v*ìU ©j6ÚUŒ×÷mÆV§Å@£Ü†O33AÂí.ÐÇ£Á,Ù F#ûó,{òÛ@¹óV½7µ”­­¼Ÿè1Õ¦_³Æ¿³éþWÈçC‹„@ÏòÔä×êe©ËÔì;»€òiɹîÅ]б{Ï˯'_êGU¹Ó®™½Iy9µ«F¬ÔõÛ~ø¸’Ð┸ˆÝ üÏÓ|٪ǧh^ˆ6‘{ð],iÄFb ¯«%h±Ò„:¯}†´1ä•FãäÌ|³¡Ãå½ÏF…¹‹d¤’Rœär]ÛébiíÍÓáà#Ü›bÜìUdóEm —°HbV’G=TT“òBËÅ|вù«Îš·œnTú13-°nÍ áêD(~c!³öSLsêgœò/yýCïz¶Rú3±Wb®Å]Š u@i:Uî¦ËÏêÉ0NœŠ) }'l [­Ôøg“ù –äÿ0ßÚyR÷Íg¼õ­fšImW¬›L¢ïJE:ôé9 è<×bö–Hhç©ÔJâI1ïî¡ñä:%Ú'æ.›u­@u ;½~º‚ª—«7ÉŠ-ENìØL6p´>ÒâžqÇ„CŒí/ÛCâ^§•=Û±Wb¯ó&¿æ«ÛOSÒõ³Ó4ëÕÓ-m¢4i¦¯vôåñ}hó¾Óí^IdÉŽ|0„ü8Ôþ7Ý‘ùGUó«ù‚ëAóA<61†¸¸Pë .% Ô0=Jvß|Œ€­ÇcjõÇS,9øH€Üí{òª®~æ}zÇb®Å]Š­‘Ò$i$ÞCÜÞÎ×s¨?äú1Wæ3$ÁõyÎ\’™þ"O̾äÂã;v*óïÏ?*·(|ãåÈÓÕ¹¹ÓgšÒ *^æÎ—vê¼±(Å!ùóùC©}oÊídÍY,'’0½Är~õOÞ[îÍhB§}ï{U§àÔñ<˜Ûõ3üÀy—b®ÅVMSÅ$ ’U’DaPÊ„àFi”$bAÃ˓͖žI½ºòö…¢Ë>¦ËÏS¼ Í"™H«->ñ^Gz}9³:s” J[žOb{.zèG6\ NcÒ:mø³\­“hþh–o2K¢\AvW°CE¹€ü3À­ϧÄM[¦ÛûÆÉ‚¡Ä9‹¨ÕöhŽœe™DðL‡õteÙˆèÝŠ¥>fÒäÖ´ CK…¸Ís ,DšP|J ð$rÜ8& ›ÙÚ‘ƒ<2@ý)¶óÍΕå‡ò]Æ/镊[%B(¤KÈr)NDü]Úñͤ´¢Sñ¶æö™;9u#Sƒ‚ľ^Šz‘4Ùü¹å+huvòRy„¬a1`¬NÃjWß05S2˜í­@Ôê¤qî6ºÒ{¦êÚn±“i—QÝC†)$ˆòPà"½ÄtÊ'ŽQæ)Öê4¹0'EîÈ8îÅ]Š»v*òßÍ­*kY4ï7Ø76r$S°(Üásòj©ùŒÚvv^q/c쾦3ÓÏ”…¸Ç›6Ñõ85.×S·þîæ0ük^-Ñ”û«TfÕæµši`Ë,rçŽÅÆv*ìU„ù×Ï^_¸IÓlžmNáE+©1щQÁWwjŽ›}8½cv,u19'*„y÷ü{ƒ ºÑüí`bóβޤ–’G+Âó™P°qQÅTÖ…GL/C‹W¢ÉzL[ .¶ýdùý¯Xòö·oæ&ßU·R‹(!âcRާ‹)?>žØ#_¢–›)Ç-ëí ¦.±V7çO+Eæ(”MFÞ²YÊzr¦èÇù[ú]¿cö™Òe¿á?Pý>ðÃü“æ)\·—5zÇ©ZV8}M™–=ŠþÒÓé,ÔëtÔx‡'ë¯`=«Ž§tÙ%rÑ/çG»Þ>ÑîfÙ¯}9Ø«±Wb®Å]Š»v*ìUØ«±Wbª/km#ú lãpÌŠOÞF#ÞÑ-.)1û‚¨ €è07Mâ®Å]Š»v*ìUØ«±Wb®Å]Š»i™QK¹ ª f&€Ô“Š%!g`{*Þþey’-LfC´nwØ(4iO‰?f1ý´Þi4þ³Ì¾íOoKµu#ûœgý1þwèí{¶§ÚiV6úu„b+Kdă°ω=Iîs-Ä„@EbÍØªI®y¿Ë~\‘!Öu¶šAÉbã$²q­*V%b¹¸ùµXñýF‘Ú^¯¦kVÂóJ»ŽîÞ´/Äø0ê±Å³XÌ\M£qlv*ìUØ«Îÿ8<Åú+Ë£I·z_jÌb!~зZû-“Ü…Ööž~pŽrFy+BÿyvÒÉ×Û^ïÇÖ“rú¢‹ôf<—Ðû ³ÿ+¦ŒÔw—¼þ®_C‘vîÅ]Š»v*†¿²ƒQ²¸°¹ÛÝFðÈÇ‹©SCã¾Zu#—¡.R‹Ì­¿)µ/­Ei«úÞ\‚C*[«H“ÔÏÀ„‹rÏâ1{—ŒFyo7[ý܇½WÍ–š÷›t+ZX}/KT™¦Qð}]¸†"›¡8(þl4-³¶4óÔë1i£c£ÑÛìCÍê9[Ü»Ku=wJÒ_®ÝEñB÷"ÝVW'‚’ èFØ@·UÚpÇ U{;˜”Þ^ÒüÛåi¯´}6}Jçô–à°&xÝÔ– ÍÄnÔ+óÉ]žŸfâ×i ð^3’\w/çy󮼓%ùsQÓ÷XÖ¯“PÕuL4Ñ1tF(´bµùSld\ÎÃì̘Lò昜òVã•=¿—d…Ø«±Wb¬sÏzèÏ)êsƒI$ˆÛÇãÊr"Û䜔Fî›Ú Oƒ£É.¤WúmŸVÿÎyTùsò7N¾•8\ùŽòóV´¸´‹è1À®?Ö̇ÅËèLPìUØ«±WåÜ'ü«¯Î¿:y¯¥f—WÁÄÀŽn-v÷·’¹®í\îyk4üx#“ù§ì?¶™æi_ŠWçwùÞþIv‹¢\y.çM󯸋qõ 2Ö ÒˆŒ¡«ÍÅ@V}·ùíLž\£(1Æ<Ë•¬ÖG[áÒÇŸªDíu\‡>ç§éú¾™« ›L»Ší`NV…ƒªµ+JŽÞ­ž9G˜§Ï¥É†¸âc}è܃ŽìU‚y³Ìžn¶Õ΋å­טƎºƒ)‘xIׯJ2‘ñ1Ìí>fßÓé£Zl_çÅŸ‰ ÿ@òÞ“å«gµÒb1¤„4¬îÎÎÀPSO¸ ÀËšY ÉæµÝ¡—U.,†ë’m•8.Å]Š»v*‚Õ´Û}cLºÒº£b:©={ƒB2xæc GG#K¨–‘Éq6óËmFãGÔõ%ꇄðÈïl غm"­z†:ûTçI GW­öOØáªÇÈÿGê?§dž5Ø«±T-âÇ5úÚ‹›Ëhä0*ªú¦¢¥NTì$“ÁÅÃ}Þóîy<’ùÏó*Siõ 6õªÃðšüMö¤aà6à ÜF:>ËOO·þ:>ß{Óü¿¢[y{J‡KµbéKÊßiÝYˆíòÀñÚýlµ9NIuLñpŠ»`?˜L—Q§˜4E)¬Ûqi=šeMÃ-?m{x¼1«Ø½o³]¿-,Ä%*q—óOêûŽêQóTzí¿Õ®ˆV€RXúz€mÍGüHvÍ&«Lq›Ÿ¯ý‘öª£‚d ÑççÒ:{™>b=›±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«ÏüìßyŸRO(ùeL­3úw3)øZŸhr¢/Voó;m–½Ræøÿ¶~ÕLŽL}<§!ü^Cú#©ëîç×¼¡åK/(é)§Úþòáè÷—$|RËMÏ²ŽŠ<=뛘Òé†(Ðø§ø¹.Å]оr¼¾Ó®ï|Îúµ›ên½¼ú–—láȈ3´|”)  ªù>ø^fS‰3â2h2ï,Éwå2hÞGÒþ¯4—H.¼Á:¯9DÅ]Œ\Á *(^;w¯íbæiÉÅ’8£[ï'¯àwNÅ]Š´HPYˆ I;*ñ 'oÌOÌIµW«èzA_@²R6>ÿfõûm‘™ ãö&“óºÎ3ôcßõ|ÎïYÊPv*ìUØ«±Wb®Å]езл`™O‡Y5;N+¬<æ¸Fa“á­Ojdá*y/i»:ˆŒ‘þóa¼¨Výû}É3ù#ÏÚ5»ZhкӥS¢\ÇD}‰T“’¯^ªÕÉqÍÖžÁíY /YØýŸùMt4Ñî®çÔõImõoÑñjÚF¡”YäaÉ£$Õ‹3*C•>¶ñx€¡µÑuùÚ1€0ã8ç9þêÏÉí¾UÔçÖ|»§jw+ÆââeÚ€º’¥€ðb*3Mž3 >}ÚzháÔNä q”¸Å]Š»v*ìUå_ššLÚeítÂ#º†Hã¹÷uÞ'#¾Ãƒ{S6Ý›ø Ùû5ªa=.MÁ¿Oë ÛCÖ-µí.ßTµ?»jÉÝlÈ~G6o5­ÒKO–XåÓíéŽ.#±Wb­¢€t’¡{{i§[Iy}2Ák«Êæ€R{ [0ážYÀY/*Ö¼ã®yÎðè>S†HìÞ¢YGÃ$‰Ð³·DOÄý4ÂöÚ>ÈÁ¡‡¨ Ë» ÷wŸÇ›Ó´KKë*ÖÓR¹w° In#‘:îh6äzõÀñÚܰɖR„xbO/Çà#ñq]мßÎþGœN|Ëå€ÑjQ7«qmÅÈë$`~×ó/í|ú‚y=¿³>ÓÏM8ÆR11>‰ÿ7ÈùaÙ•|Ýo®Æ-.©­ýäGa%:²Wñ^Ù¥ÔéN3c“õ¯²¾×cíN£˜ ÇIyÇôŽžæO˜fìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®ÅZ$S°N*M0-oÌWþb¿_+ùMLòÜÜÆiÈ~ÐVì€}§þvºMz¥ò|‹Ú¿l¥œ.Œìv”Ç^ñ.ùué·>¡äo$Yù;O)UŸV¸Þ]×þ+Jî~'sà6o%£Ò 1óêÊð9ŽÅ\H§`:œUæš_æ¡«ë·z˜1YùL2Cqw'RÉÄúl ø‰&”Tûáuxõ²œÌ¹c uΉä/Í J{­ú[e;…q( z†7¥O@J°÷µKL‰‰¢Ìü¡ä-Éë$–eîu ‡o&§>5¯QV¢§Ç¹Àçi´pÃËsÞÊqrÝŠ»y×æçš¿Bè¡í$¦£ª†F¡ø£¶HÞܾÀú|0ºÎÓÔðC„s—ܯä//Çåÿ/[Äh×w@\Ý:À»¨¢‚6!EÞsFËßû=ÙÃK¦ˆþ)zÇõ2|‹¼v*ìUØ«±Wb®Å]Š»v*ìUãþwHõmcÌsê/Õ´XO·SÅL·A@s±iÁ=ȧ†[öôF|ÙåšÃð9Vÿ3÷/ò¶‹ªèþfÒtÛeþ§=”Zå°cé•&_‰MIÙ¶Ûñdl2ìl¬xá”𘠒<Årøí³×r§ÐŠ»v*ìU*üÐåbÿÎOiœÓÖÒ¼©ÏQž¢¡?FÝöÚòDËà6|ƒÚ_¬r§åÏí·éM犻v*ìUóÿüæ?‘¿Æ’º–¡o=KÊóG¬ÁAñb¬WB¿Ê!vÿ¨1H|¡ù}«þ™ò¥„Ìܧ·_ªÏã΄WܯúsÕãáÈ_,íÝ/ƒª˜è}Cãûm“æ3§v*ìUNx!º†K{˜ÖkyT¤‘:†VS±ˆÂ Ã8LăD<·R°üÂÔêÕî-¼¹å›7’5–"¶°˜Uˆ 8ô#ĪœÙÂxcFŒ¤~/c§Ï Æ# %›,«cê7÷}å1ò‡—¼—%•Ί5Hõ÷žD¹ž* I+êF€ò1är½Fl–%\./jëõ‚qËÀqP |By{¶zqÇ i J(Ô""€UEtf6òò‘‘³Ì®ÀÅ ¨XZê–Sé÷©êZÜ¡ŽT>¸ð#¨9(LÄØnÁžX¦'D1ü¯Ðä³±±¾žâê>Yž"_‰hå ˆ˜Šü#ìÓ¿Jæ_ç¥dŠï´™„å(0>c¯¿ßlÖb·†;xc‚%TŽ4UUИdÞåÐNfD’l•ø;v*ìU¦eU,Ĥ€¹Å [ϼÍù«¦i¬ÖZ OQ'€‘jmÑŽÃuÝϲýù°Á ”·–Áéû7Ùœ¹}Y}ÿeû>?$·Hü¶óžîSWóµÔ¶6òŠÙ€ð=£‹ìÄ=Ørñ®l¢!ŒTCÓÃ. $x0Ä_ë=P^[–ïÈo»òn®ÿè72i9ÙK7÷Ri¼å—bÜÝÑVšÕ~î¿.oSÂð.Å]Š»y–¿å?6y«Ì’[ê7݃ÛÊ¿ÝúmÐ"V¦JlÄôùPa{jétša( ÈyŽ·æ›ÜŠÖµÝ òïN:6ƒ >¬àòe$m$íÜï²þ¡‹FCŸ´²x¹Cñ´_ÞSŸ%ù¾×ÌvEq4k­"Ÿ¬[©!›ŽÜÀ úµ¦¶;&Zl„€|>‡ôk*ÅÒ;v*À|åù~5)ZÐÕu¥>£¢·™†üâþýNû¬ìig¥”c2h}2ãû>ÑÑ(ò÷›ÖýæU6š”GÓõä^ Ì6¤€Ó‹{ô>ÙªÔèˆÞ<»Ÿ¨ý“ÿ‚=LcS $~œŸÃ/qóåîfù®}AØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wbªw–¶ïuy*Ão«Èæ€Sà0ÆFƒ«ÕâÓã92ÈF#™, }G^üÁ¿:–¡h´ÑO¬Ü5Tp¯Ú•‡Ù_ŸÃ7:m†çrø¿´^×fí){†.§¬½ýÃ˯^á×|Ÿä½+Éö^ õ¯¥ëW® I!ðʵ迬æk§Òéc„PçÞÉ1rŠ»b³þaù-5ÑæÕ#õëé»qsc±S0>g•=ñq»¾ü£´Ò>·ªÝêS\ùbÌ=ëXÀ¿¿tKqäX%Bþ߇†]>͹qÒ+ò¿C7¾`¾ó½‡è½ Ñ Ó-A?x©`Nä¿èXíÓ}Ÿ‡Šg 1èõÜ娫±T6¡k¥Ù\j²­-‘¥•ÏeQ]¼Iì1a9ˆ‚O ùîÚÞïó3ÍÚ¥û<6 ?dŠÅ ÃÔ^í·Žei´þ!òyÈÄêr_ŠG"yÏòñÌ–R~‘ÐA,ñÍ­w,•¬gÝM$)r3cÙÿÄG:Ùë}–âÊ"æ#éûM$>sÓ<µåWÑõ(L«¬$êÂ(®s,|jf¥MjæFšsÉÄ'ÉÙvF£Q«!¨Šê*wã•=§4ÏìUØ«±Wb®Å]Š»cfóÞ…å…hî%úΡO†Ê ×·3ÑÏs'–y9rwØ™õ[QþqýìÞ×óóZO€~ŒòÑmÜòH ƒÿ3Â×ùsm‹1y—³ÓhtºcÕ>þ¿³ï÷½[Ê–¾\ò‚¤öñ}sUâÔ..Mz ùoâNL–N¶yyì;™ŽEÃyçæÇ’š4oÒ:|u×4Åg€(ø¦‡«Åîi=öï–c•aÙú¯T~’Çüæ±æ-/ê÷Mþ嬀Kšõ‘z,¿OF÷ùŒ¼¼Çov_å²Ü~‰ròòý^L¿BìUتÜSMk46Ó{‡FX§ ÆäP5ƇÌRŒd …€yw¼û@òM§—ÅÇ™<ãq÷q3ÉYÉo´ŒXUÝ¿gúô/S¯í©êk˜Àû¼‡ã’A¦¼žlüÁ‹WÐí¥…¬‘K< qýÔ{ôØ4€qâ;}'i©ˆÑè<²â”yžï(óüe¨~gùfÒ'{yîTŸÐôcZQNR)mŠÓ§‰ûðSÏàökS2"®ÿG¿îeÖ—PÞÚÃynKA:,‘–R¤« ƒFŒ]\GŒeÌl­‹[±V;æ&é^h†· èj) ì`sÇí/±úÅÛvgleÒ·Xþ®âóžó?åüéc¬Âo4bxÁ2’VŸñ[ž‡ü†úŽ3Ül_zö7þ RÅ|Lcø×êùyr÷3}'[Óu¨=}>q%)Î3´ˆOfS¸ýY¨Ë†P4Cï]•ÛZm|8ðÊûÇñxüäÃ+v®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb¬sÌsÒ´0ІúÕøémû'ü¶Ü/˯¶e`ÒJ~Aä»Û/gƒ|LŸÍ?¬z}þI^ä¿4~`\G©ùŽGÓô0yCYÔïû˜Û¥Gû±þŠæãã>G¯×jûS'yTzDráúNïeÑô]3A±M?J·[{TÞ‹ö™»³±Ý‰ñ9k~,Q€¨Šü[Š»Hüßm¬ÞùzöË@!u;•#³ð ŽÀHCv<*.>¦3”2ò7ò•†³ªÚyI‚It«qq¯ë %iøh¦¢ª©Où§réΚ3Å\#ÔYåÿ™%Žmòwå¨Uþ­|çá;GéÆMy¡*Û~ÏÜ1r;2y¤ï÷«€P@ÀÜ7Š»v*ñ?Ío4Ï®jqy/E&Xã•EÙCýíÅ~ê?e:·ù_êä£MEÚ:ƒ9xqüIåÝ K‡OŠ øî%ûÉ[í7˰öÍþB§/Ž4šå­Ì?Ì—ú^¬ZæÂ–«rŒ~éۯă¡÷_Ç0óhã=ÆÅÂÏ¢Œ÷ªÇÎ>lòTÉaæxÿM¯î9rz‘)Ù¿Õ}þY§Í¦”áÚv´º!Ì8áß×ç×ãózn‰æ-#Ì6ÿXÒ®V`)êD~c'³¡Ü|úxf)÷úÒê9_—Qï ¦9Ø«±Wb®Å]Ф¾m»¾²òíüúdO~c1«;©“á.Ôü òú0Ç›­íŒÙ1é¦q‚eT+žý~Þuùoæß,è6¦j%ìõ ¥gžæD¬l~Ê/%«#ù…*NY8’ñÞÌvÆ—MŒãÉq‘;’6ò4OæÅ–­/—íô¹c¸¾¸•½ ¡eÙ~%4¡nŸ,a³wµy1ç8#Œ‰JGb7çCïz¶T÷®Å]Š»v*ó¯ÍF_ÑÖ^^³V–óT™r€³:FG 7«HVŸ,³xÏlõ¼cˆs™³î¶¾OÒ/ÊŸ$ÃùuùuåÏ&D I¥YD—eiG»’³]8§f™Ý†\ùf8«±Wb®Å]Š»|ÿ9§åI<—ù£å¿Í}:-5¤[}L ëwb¢3ÈÒ€ËlÊ‹þ£ey±ñÄŽ÷Y¦ðËþ!ýŸjU±ÏO ŠEWÇFV|Æs$Sãò‰‰ ó ð1v*ìU¬húv»a&©Â&¶’†•!•‡FV‚2Ìy ‡'I«É§˜œ òéí¿-|‰õ¤–}_V·$ÃkêG*Ã"‹TPAþbHð®l͘WÒÆ;G_8fˆ±ó'î÷²¿"yæO6½ôwPÅk,,­m HÚ"7¨'‘âz°P7Ì]V—ªÝÒößc ‰‰2™®¿Ž–Ís çÝŠ»v*ìU-Öuý'ËößZÕ®’Þ3^ w’B;" ÏÑ–cÅ)šˆrôšº‰pãýÃÞ^guç?7ùêí´$ÙKokÒK• ”)?iåû1‘¯¿lÛaÐÆËröº/g°i‡r%.îŸ.¿™—”%ô)—Pó+_T¯3 ©µF&»†ÞCîû“ß2%“¹ÌÔv”¥´=#íýQUTUDP¨ P(ÊÝcx¡Ø«±WƒþcyróÈÞb‹Ï^ŽšmÌŸé°-BG+ŸX‰'Qàßìrür½¾! ^‡'>‡ôûÃ5ѵ{=sNƒR±~PÌ*Tý¤aö‘‡bXùî³I=>C ó‹Gââ»v*‘ù§Ë¾iÓÖÊâW£q$R¡¯ÐÕkCQ_–.˳;JZLœQØ¢€Ôï´oË¿/*ÚAµJ[A_Šiˆ©gn½¾#ôع:l9»KQê>óÜ<¿CÎ,<æo0ÛMæÄX¾·$ÂâÞÖDU&`­D ^¾ÖÿIzÜý¯¦ÓHiÍÐOóMû¹}ݲÓë?U‡ëßõÄUôÄ”ø¸×zW¦Îòðñ«ÚùÒ¶-nÅ]Š©\Û[Þ@ö×Q,Öò2E"†VàâÏIBBQ4CÎu¿Ë-æ:Ÿ”.ZÖå!hÎ@ùG'QòjüðH(½¿bûg—O0fLd9N;~’Wkç}[EœiÞm±‘&]½u@®GNEvVå)Í~nÏx—ß½žÿ‚ˆœ@Αšì˜¥aõ^Îí6²¯ê;l¿IÌŒZYÏÙæ»_Ú݆ÄçÅ?æÇsñè>%Ž[Üùãϲ5¾…ll4¢xÉtID§~SRÉŒW6xtP†çrù‡iûc¯í †Ýcòçñ—üM=Ê•Z—Ê^jÕ5U£ e_ÜÆßäFj öš§Â™˜étýn}Ežâ슻yÇæ¥‡šV?0h²¬Qõf³ˆP« þÿañ€V¨ضYÚ0ÉBq?OOÒÇï?2µÏ7Yiz•Úù‚øº_²>Ÿ¦+XÜôVbz­)‹-|òˆÆHóB¾±çïËMVÓüGzÚ®‘v~>S=ʲ­9ðy€uu´Ø|X¹´Ògˆ‹#×*ε­M®iÃYZjƒäjŒÅ–@ q*ËU~¼[û09Y»;Ž|Q• sz¤ÙèZe¶“`¥m-S„|X’K31ñf$Ÿ|]Ž,b‚;Çb®ÅX7æW×ÊÚgÕ,œ~œ½R s }R?÷ùauúý_…Q`ÿ—žXkHÄ‚“{r ¶WÝ’6êæ½ßõ|óm¢ÓÐâ<Ü-ž‡æYög»b®ÅT®-­îá{{¨–hQã‘C)àà”AQ(‚(°=WòþæÊàj¾Q¹{K¸Ï%·õ ýÉ^ÿÊÛ{æ»>‚÷ÉÁ:iâ—È#4?Ìû›Æ•ç;g·¹J)¼XÊŸœ‘æM½³S“ ‰§§ìßkˆ<‘GùÃôÕòzU­Ý­ô ug2\[H*’ÆÁ”ý#({Œ9¡’"P"@õ ø¶;v*ìUتK¬ùS@×Ôþ’²I&=.zsökB~Gl"D:Ýwdiõ?Þ@ßÈüØÞ‰ùae¡ù†^¶žÒí¼È ¬¤qR]h“öFôÉØtºeqéµ#(•Ä]Îýÿ±Ÿd±Ø«±Wb®ÅR¿È,ŸÍ_ùÈëKÉSÖòÿ”+¨ÊiT&ÁÀ·èy]2½;¨=³"ƒãžÒk¿1ª‘£éÛoÒ,“ v*ìUØ«±Wb®Å^Kÿ9'ùwÿ+/ò‡^Ñ­âõu›ÿKhàNnì~ §¨I$°¯-d.SŸÀ›š“×}³; Ë”pƒ°z] µºØ PFÓo>§îH<¼šÿœ<ímçaú3Kxú»V0¬ r!}BܨX òܱ̌]—g¯84z9i¸øæ~Ãú=Ï\ÍKûv*¥qsoiÜÝJ[Æ9I,Œä†MxñÊdF"Éîy™?6ÓÔýå8¾±räF·²)ãɶ(ÎìkзÜsgƒ³úÏäöì©>¬æ‡óGé?«æŒòïäö­­ÜkóòF’CËê+')XuIÈ?ÈO¼fwˆ¨‡y-n<1àÃãñ»ØtÍ+NÑ­ÃJµŽÒÒ?³JW¹=É=ÉÜådÛ«žILÜ”f,Ÿž|ù¦y&Áe¸XÔ§êv*Ôg§Vc¿4ùd¡ rôºIf;rïAyGòþrgózÉ<Áe,VÐnG«a%ü¯§¤¨EAŽ8cšá”ƒUw^-ØÓ20î=(WïBùÇÈÿó‘_‘ñ~—ó<ùʨ@¹Ô-dkÛhêiY$)Ä^Ï"p©¦çl,rö~)…&Gå8i>rÓ¡¦· R‹uhäz°9ìÔêì·FcÊ4èuib•ßPÓìõ[)ôëø„öw(cš&èÊQð=°M0™‰sŸ^-Gò“ͧޟË7íΩZ¥iÌûiPwFeFVþÐÑG´0ÜvÉÅ{G©Ã470¤ð:˪9‚¬¤TFÏ'AB¦,Š»c¾rò´~jÓ¨Cyz–³0%CR…Z›Ñ»âí»#´Î“/\NÄ%zþ¯äß"FnæŽ}^%KXdEø¶Ë×ípQÖ›‘‹™§Á‹]®< ˆ‘óýV^y¥¥ÍåÄókÝÞ—¯¼BçO–veŠddõz…»vùôÂõz“D X£“ðÈc§/Çézåÿ˜n¼Å ýbûâ¼¶•­å” 8ª°j «FÞ˜ Æöö‚:lü0úd,y2AƒPwbé[ÅÅ]Š¡oôë Rm¨ÛGsý‰T5ˆ®àûŒ[°j2b—$b|˜«ùOkê}kË—¯ap§’E#3 =¸È¿ý<±;ózÎÎöÇ6)1¸þ(úeøù$ò]~bùcáÔlÎ¥dŸîྰâ;ú‘|Cç ÌLš,rå³ë}‡ÿŒÂ¢rG îÉ´¿Ómì‘–™Z4ô[èe³“ö=XÇÒ¿ü.aϳæ9núvƒþ :<›eŒ±ŸôÑùÿز;=E¿ê—ðÈÇ¢s ÿð-Fü3x'`½v“·´ZîòÀù]‘ßìL²§lìUØ«±Wb®ÅV¼‘Ä¥ä`ˆ:³úN [äŒÈ€<ÒkÏ7yrƾ¶¡°ýˆI˜×Ã÷uürøirK£Ïë=­ìí?Õš$÷GÕþæØíÏæ?Ö%º›-ÕÃí0jO´qò'ï—Î?Ä^?]ÿÈ}:|FG¾[±0ˆƒÊ™žlßQisõI¥Uî=$¬‡å!Kr#®í®Ó×í’|?ÃHû7?çgåïÊ/,hå'¿VÕo~Wö„mÿ[2 ™ŽŸQg¨‰,q¨HÔTPt À ]Š]Š»BjZ•Ž‘e6£¨Ì¶öp/)$nÞ¹$ìÜâÃ&Ag“²üåòõÞ¤–w—–3ßL©¥]A4_zŸ|.º©* ÞÇüãåkß#k0ùãÊH> Î{`¼£€È8¶Àÿtà‘·Ù=;QqµZs‚^.>_±cÁæ¯Íù,.&‚ ;ËV²8yc•]¹íê|5çÊŸd~¸©5th‡´ÅACãj¨‹àª(ÝÞB—â—b®ÅR?5ùžÃÊzLšéäÿbÖÜŠiHÙG·v=†.>§P1Gˆ¼S˺]ÿž5ÉüͯŸRÔIÈ©Ž¿f%öR¿wŽfé4üfÏ èôøåžfsäõ03rîÏ)yWVó¦½kåí^]Y‘1®ï$„B¨ëµ{ šd2dZòåwš|£æ&j¤y†Íín–¦6?S%vxœlÊ}ºt4;c ˜°¸²ÆbâRL›c±Wb©~­¢išÜWÔ­ÖUaúH‡ÅXn2¼˜£1D5eÊ!Üh>gò,²jžZ»k5k$ð=½}HþË?iwùf§Q¡1Ün4ùµ)qá–ÝGOˆý<Ù§“ÿ0ôÿ2‘gt«cª€)8ôæ=?tM ?äõùæ¶P§»ì_i1êýôO»¡÷~¯½šd•Ø«±Wb®Å]Š»v*ìUتAç-lh]½¿VãrWѵއ֗áR?ÕݾŒ”E—UÛzïÊé§>¼£ï?«ŸÁô—üáåÑò§å|¾o¾‹Ž­ç þ²„ƒÍtûRÑ[)¯ó1’]º«.d>'"úo;v*ìUØ«±Wb®Å_š™þT?“ózž•zVó+}wLê#X/œ²¢íJC8x†û.ç®aëqqÃÌ:_h4^>˜‘õCÔ?OØÉó@ù{±Wb®ÅP·šu†¡èýzÚ;ŸAýXD¨#ÐŽ@ûä£3E»¢xï‚DX£H¬‹S±C±VæÌÝBçi`F¥ª ¯¥~ê6éñÈ*+þJÔøÓ3phe=ÎÁè»7ÙÌÚŠ”½óæ}Ãõý¬»òóþqócóžk}{ó âO*ù=ˆ– yb+w2ÇÕíœîÙ·î ÜaÁc`÷zÎÃ¥c÷õ/_üíÿœJòU·äü°~Zi™ü·ÏRŠà“5î© úÌ3Hwv(¼âE^(£‘Ëœà^+ùSçñW—+¹9júg{Êš´‹OÝJküÀPÿ”bä›í 7‡=¹wpnî ²µžöå¸[[FóL碤jYÐ,£M?ÿ8Áù^Ÿÿ˜¯æ­Åוt’;-6aÊ ‹Ês†8"þÓ2Ö °9q­Ãˆb€ˆ~„ Ðd™©ÏPKmsMm24sC"‡IÇVV¨ ƒB*üýÿœ‹ü”Ô?"¼ËæŸåÄE<‘}8QÓ‘ŽÂiML,Ñå?ݟ؇o‚±”m†l1Ë&:¹eæ="×YÓÚ¶×IÈ)ûHÀÑ‘©ÝH æ)^W6#ŽF'¢Í^XÓ|Û¤K¤ê+EoŽ ÔUà”EùWqÜmŒeE–Ÿ<±KˆÐÀ­¼¯æKï«ùcÌöQÏ£Û#¥ž±_Z*}>-È;âÉáóÂôÙ;OOŽóà‘‘õ@ò=ÿ¶ ß2ÞÁä.Áå C&«v¤ÜN¢ŽCFz ÑžœTvåŠ{7 µúƒ©Ê*ä=Ý=ÙókËמxò¤6}ö™ëi“¾òÍ5LG"9+0QAb|qOhbÑk ç ÔÀä?ø¢NÛOš2í­m<£/­xÔi=2Z=øªqö˜ûtùãM=™ì锵"£>~v:ûÉ×^sy.m<Õnª°ª4W_wgýŸÝ| êE)ïØ:Î×Å£2Óž|Æÿ§vY‹£v*ìUتW¨ùoAÕªu>än²” 'üÑ¿\Ý?hçÃôL»åÉ‹_~Rùrâ­g-Å›vUq"¡ÁoølmÝ`ö«Q¨F_aû?RRß•Úýüqõò }}[ù6Ï‘”"y€ô/ø eÃô™ãþ¤ÏüuaòßæŸ÷„wéIQëÿ#ÐeGKŒôzm7ü5ÿ/1ýh‰Å-ú·æÜU­ºH«VËâØ0?†CòX»®?ø0gÚóƒïÇú¢–iz¿æ6­©Ýézz‹‹ûbâ{r–È!(üân#fÛv8þGs½Ò{wÚ¹½PÈ$$,zc°=Û¶Ó±¡þrM±‰ <ìw¯È·L#E¹Ê—µ=µ/ãüܨª¯å÷æ…ïûÕ¬El§­.dSô#§ã– 61ü!ÃÉÚ}«—êÏ!î—ûšEAù#qpâMg^y›ºÇcô<Žâ9hˆtû?&Sy2;?ydšwå“,hÓÁ5üƒ~W35+þ¬\ÞÜ}™Š<ų /MÒãôtÛ8m"î°D‘ƒóâqsaŽ1ä)‹7b®Å]Š»xÞ¡ù¡æ.y³V°ÕaŠúÚ:ÃgklB*¸5¹|MV÷€÷éÓ ¤ŸhOI n:2½KLrò–¡æØ®4³dúòÂ"¡_ÒžJÕj‹P»âåäÇãc%Æ·§œjSÅç= Só>·¨Çai§s¶ÐtH¢•zšŠAﲊbë2r4Ó£~Z'˜dòäšOšl8-É·¶7 rš dhÛ~+г)Û¦.Ï@&qðÌrfvVVšu¬VV0¥½¤#ŒPÆ¡UGÈ`s¡C’¾,Š»Kõ½kOòþ›6©©J#¶„V›rvý”@z±ì1jË–8âdy<I5Í/1µÝÑh4›s@ Õmá&¡Ò…Ú›ŸàÌ>ù<ÿ«U’Ï õ+KK{h­-#[B¡#z3{ˆŠÞ19"a†[‰£·YåeŽ(Ðgv4UP7$ž˜II4úËóúíµ­®¥7šCóO­YÙÀœÞ)ö¥I«¿(¤ò³]“\ÕaÕäí“\7â×óEó·_•¿ž–PÁ¬ÙÈmãÖ#…¥á—˜Ñfe‘hŒáFÆ ¯&³§”yˆíÜò_ÍÊ{¿ËkÈ&Žö;ýPg|åÑn¬‘×zöÓá?ä’fiõ ós´º¡”r¢s™[±Wb¬#Îz–»©XùËP½æ·«M Þsw™€ŠáÈXšPuØœ×k³× |]_hj(p‹ê[þpKÉ·¾EÒtý/S—Kóý²‹ÝdžÎúèürz°9T1+FT…§ ç5nŸ‰ó‡™´¯ÍŸÈ½F=#óJ’ïEvôìõh˜Ío0ƛúr…zvQ•Êõ•í^lŸ¼û!ñëñù†G¡ù“Fó¾—r²0É|3Gþ²Çϧʈ§Ñt§ƒWÇ+òê=ãðl{±Wb®Å]Š»v*ìU€jZ-÷æŸæ‡–ÿ+´–n3Ü"ÞÊ‚¾’°õ'”ìºY¾ñ—cš{eÚyFÊŸëÔ>÷ꙦÙhÚmž‘§D Óôø"´´~ÌpÀ‚8Ð{eŠÅ]Š»v*ìUØ«±Wb¯™¿ç5ÿ,œ?-ÎZl<õÏ';]9E«É¦ÍÅn—o÷ÝjžŠ­ãŠCæï$y€y˶·Îܯ#…àî&ŒIÿXQ¾œç5X¸&GGÊ{gCùmD¢9Ǹþ®L‹1ÝS±Wb®Å]Ф>có†‡åˆ«¨Ï[¢9Gggðø{v Ëðéå““²ÐvVmQô »Ï/ǹ)ò’?8ÿç ®LV±:7“y¸Õî ÃiÄ03S”Ì;ǧóS®n0hã ù—½ìÞÀÁ¦õ\ûÏè‚û/òwþqkòãò˜Aª4â8FoPH…üm-þ$‹ÙªÒuøèi™ŽòÞ㊊¿;?ç ¿.ï¿ ?4£óï—m‰òš&½´`íçú—t/ûöß ¥W¢Œ£a§Q€e‡ æÊ4ûûMVÆßQ°”Mgr‹,2/B¬?_ˆÌB)ågAæGç.±ú/É70#qŸR’;4§^$ú’}P¯Ó“Æ,¹Ý›‹(=Û¾Åÿœcò`òG䟕´ù#ôïõÓÕX˨Ÿ¬(qüÉG¯òæSÑ—®â‡b©O™ü¹¥y¿ËºŸ•õ¸DúN­m-¥Ü{W„ªW’“Z2Ÿ‰[±â¯ÍÉÑ{¡kkò=ëú£Þ:>È–^Úb7;Šz僧í|cÓ'®e.•ŒùÛÉzw4¦³º+èkÚU¡øø©ý¥þ4ÉFTäéuRÅ+º¼ËždÔ¼—©7“ü⦠>«¨ïý¿ßÔU•Ô2ÊÀ`j=8¼1Þ(v*ìUØ«ƒÈ–©æ¹|Ísr÷\« €Ls¨Øª°)·Ñ‹½ŸnHéFÄG¡#¨ýgª{®ê–š6“u¨ßÐD†±~ñ›e@óL]n‡K<ùcs'åçðxÿ•¼¡«ùëb±4Éc¸çgÅ ¡~\Ÿ€_²«PÇà ÞvŸkbÒÖƒ0G«•÷’ô}oζ^Y¼‹NÔmîç>ŠH÷‘GB )È€ËMÆû|°<ž‹±§ªœ Fäp’SÍ+WÓµ»E¾Ó'YíÉâH¨*겚~xºÝV“& ðdQظÎÅ]Š»v*ìUØ«±Wž~ZäÆóWúןõ0¾éì¯÷Pÿ…ÇîbÅë]Š»v*ìUتK¬ù»Ë~_ªêÚŒPJ}L’ÿȸÃ7á‹F]N<QK4ßÌ¿%ê—Igo©¸…ŒO«°ÝB׿qjǯÅ#@§bó‡–t©µmE£#]ÞI좃Üÿn-ÙóGx‹Íu̯=iki®j¾]»` ‰ß÷î„rëÏ$t&0=°º¹ëóF¤bOãñ³¼Ëù{ ë~Z›ÌþRÚò厠‰È‘$l+$*ƒe Ô…ëËáù+¨ÑBxøñó;þÅ?+~j]_Á¥ynëK“Q¿•ÖÒö`yz–çà/Æ›°SñòÛbk¾Ê4ý¢d#<¹”éß”žQÓµAª"O7¦þ¤6“ȯ05q Àv ÇÞ¸¸vn(ˉb슻v*€Öu;@Ó¦Ôõ9„6°ÏVv=v=†-yrÇx¥Éàš†¡¯~iëÔ¶ÑíÀc·Œ÷=9HÔÿh ¿ÐyéÎz©÷ö~×¥iZ]žcŸbœ Œu;³1êÌ{“›ÌxÄk€ É¶=ò_ÌþRòŸœ¡Õ<ÙlÒB…•èøÒÊf4õž m¶ä7^ Øú¬r”j.&³ç ‹èWò-–Ÿç»¿Î½GÌ2j~_µ³–úÊ8«+"´L¼#1UZ‰Œ/R~*î[]ã .¯Ç&mò¯¼Ï?œ¼×ªyšxý&Ô&çU©Ž$QHOr¨ª Ͷ,|ÝaÇÁäªëRÔ/¡µ·½º–â ý 8å‘a‹‘~ ØT“A’˜ˆ¸Y;J|Ç®Cåý*[ù(Òý‹xíÊÃá.çÛ*Ï”B6ÓŸ0Ç{¿üágäİÃ/çg›"õ5mSÕËqÊ( rR{ÊÃK¼qô¢r;‡ ”‰6^js$Ù}“‚UÒt½wO¸Òu«(5.éLw6Wq$ðJ‡³Ç *GÌb¯5ÿçáËæÉ;öÒµ8ë òõÔÌ!fî-n˜–ŒŸä”²’~Ú®ØÓvóÇ!(’ê;ÿŒ¼Íä­^O+~hi^­nB¼²Bc’£:ž¢H¶# 9T±÷=ße{dEGP?Τ~¯“<²¾³ÔmÒîÂt¸¶³,lO¶Ýý²²óxeˆ”=B#k±Wb®Å]Š¥úÖ«‰¥]ê·Çm~5§&èª=Ùˆ@·]«ŽŸ ²K”Gö‰zwüà¿åä÷§ÿ95Èù]êRK¦èÎàׇ1%äË]¨ÏÆ%=Gó >¨Í,“3—9/´0´»v*ìUØ«±Wb®Å]Š©][[ÞÛMgwÏip ðÈ$‘È¥YXˆ ÐŒUù…©ybëòKó—Zü»¾fý { }"âN’ÛÊKÙÉ^ç‰1=?l À×áâ…Žaç}¦ÐøØoÖ¿-üϨAs¥Ø]K¾§m*Ïl² Ã+F\‘hJõFÙ€<²¬½Ã®í È8¢7Gjöñ~s~kyCòï@˜^iÓ\F/nm›š¬r-Ô– úVñ–¯F8£IìÝ9Çd(—éô0Åop@‚8bUHãQEUQ@k°_Š»yOç×çf‰ù-äùµ;‡K3ß,ùJ¨/5Çï]zˆc$4òQ» Râ?ÉQ¶Óõ4ë›P×ä+IýãFœÊÞò3–ùP÷Ì|²²è{S8”„Gð½C*uNÅX×<—¥ùÓL6W£Ò¼Š­gz«W…ÏÝU?´½þt9(Êœ6ªX¥c—sÇ4Ís[üºÕ?Âþn›L–·@ vxÍ*ñžëÕ ÉíNdž²>.§Ôwþ£÷ý¯P‚xn¡K‹iX$£‘e`{‚1xIÂP&2B¦,Š»v*‘ù§Ë¾i°[+™ä€Æþ¤RFjÒ•d;6ÇeÙ¥-&N(€ocýªëÉå_'Ü~ƒŠa%¸§. ²£HGr.kôâÙ¡W«)úÎÿ«ô07Tóá÷~×¥iZU–‹e…„|!MÉ;³±êÌ{“›¼xÄk€ ŽÉ¶=Kò7ÈžVóö¿¨iždžUh- Öv°·¦e<Â;ú›ïT…¦õ¯A¾.¯, ·<±Ä²ýwþqœÝ$÷~@ó ¾©.ñ=Û(–9#4xÌÐÕyƒ±VD¡ë”Ã]_P¦ˆv•}b’¯)ù—ó7ò2ïêfÑ®¤òœûûY©;½µÂrŒ6õ+ÊܸžHcÌ,ÙåÇP.'v ù«ù;[ó]ơ䛰Ò%D.¤zk$är‘Ò‘Šž‰Ù^ÖáÍQËè—ðŸOÍž+”‚¤T¸ ÷[×mâ®Å]м÷ͶگŸ|á þVùpzšŽ¥s MJ•W—ì—¦üc”¯í¿l·êùç¶}¥rxž[ËßÐ~Ÿˆ~šy7ʺW‘ü«¤yGDNfm¤3ðOÚv«¹îÄ寞b®Å]Š»v*ìUØ«±Wb®Å_-ÿÎl~TIæÏ#Áù‡£E_0y<4—e*$—Kv )oX÷£Á}Cמ{Ï^Jóy—@·¾fò1èÞ¨í2SOaóÎsS‡Ã™(íÒç0þ¼}ß³’$‰4’°HÐwb¨’Iè2€lbI¡ÍçÚßælmvš/“mZÖnE¥È#l4Œs•¼íîsaƒ³ÉÞ[«ìßeòdõfôïâýYü²ÿœ8óŸžn óOçn£6™`Ôx´Müˆ~.20;t;UTêC¾m±ãŒOm¦ÒãÁq›í/(y'Ê~@Ñ£Ð|¡¥[éTB¦(ŒìÛ–F«ÈÞ.ìO¾XÞðÿÎùÌO ~^ýcEò™O6ùµ9Fbµ“ýÇ[IÓ÷×+Pä÷\<ºfCŠiâ”ó•?˜q~p[7æÕñËiHìÅ«Çõk=1ȶžÿeyŸNVsÈ©äìx ³&)B¸…[¦ÖaÎ Å!.F·Ý÷þVÞìU¦eU,Ĥ€¹Å_žÿó?ó¾düÜó×å×å­ÛÙyÍžýF 3ªq<IhE½vŽ1öþÓV .F›M,Òá‹®í^ÕáÅâe>áÔžàòÛ/Ë/AKÃ-Üä|r—1Šÿ’©Ð|ÉÎbâ{%òÍW·ºÙÎñðÂ=Õ2E(A£y§òÓXƒÎ¿—Å®¥aWâ¤}3öÔŠq•ûQ²îTó—üæÏ|Û<º7äÇ–ÑOÂ5mB5º»PNÎ ZÁO÷cÈ0Î0#O0Ó?.¼Çæ}xùËó_U“ZÖd!ͬҙêA%VW?E'h£ø>²™eîu:®Ô±Ãçúž¦PEØÐ ¥Ò·Š»v*“y—ÊúG›4×Óuxy¦æ—iazPpòä‘yhúB3‹új>)V3W4I$¹¦-‘Úë¼L‡ë¿…òýH?"ù§Ë—zE‡–%ONñÑà’ÚHëÆŒÌKn§˜ì{í…ÈíÎÌÔC,óƒq»»ÜbYù•®^ǨÚùcM2Ad‘¤— j¤;†¯ÂÓáU§O˜‡3ÙÍ9g]/ÇRÆLiž\¸²Ô<£¨^ä~¿axÔ 7†Üw#®.ßò™51”50ôeÛ»ß0>bìUØ«±Wb¯<ü´ÿÉæ¯õ¯?ê0a}ÓÙ_î¡ÿ Üŋֻv*ìUØ«±Wˆùî7ò_æ6Ÿæ«u"Òñ–iBŽ¥@ŠåG¹BæØ]°x9ÄÇ#ø+¼Õù…yçxÛʾPÓæ’;²iœRDV€ªHE¨ø™›§†)ÔëNoF1Íé~Iò×øSËÖúS¸’ê­5Ü‹öLÒuã^À£åÚi0xPê·òß—í/›S¶Ó-¢¿rXÜ,(‘êA¦Ä÷¦,ã‚ñ-4Źث±Wb®ÅX?0tŸ(ÂÐÔ]ë +’7Ù¯F”Šñ‰üqpµZØâÌ÷<–ÇHóæ¤u½~gKh¯N  5ôíÐôQü߬×34úS=ÎÁÓÃõâŸ/Ç'§XØÚi¶±ÙØÄ°ÛÆ(¨¿¬ž¤žäæâ¼ "(rDä™;dGóEÇ“|×¥ùŽÞ¤YL­8Õ›L_SyËPòwåqÔ¿5´øû\óJC˜‰ÈZ—hCú•‘‰øìõcš¼BY*t¸c<µŒì"ð=ó×óÌž[ŸËZÔ& ¦X¼‚Ä‘nL,c!8«D‰ œÏ†’•‡i 8ˈ<×2\·b®Å]Š¥Zöaæ?ª_)O(fJ¼A>=ÆU›È(´æÁ‚Š Ë:çç‡åŠˆ<æÉ×KBZ==¤I-Æõ?è·‚HVµÜ®kg ˜å»ªÉÙÓ·z^•ÿ9£ùå pO4ù[OÕíþòt¶¸µ™¼G«ÿ‘Y,0\Ié§`½[É_óß–ÚÜñYyÃI¾òµÄ„+]5 (ÏCÍâT˜oá÷¦TÒbúwGÖt0é¶úÎ…}¥¤Ý¯©m{i*Í «ZU] „PûâÅ^ÚòÒóÕú¥Äw„þ“«úsGöã~$Ñ—ºÆ*¯Š¼›óoþq×òÛó~.5»ÑþeãH|Á§…Šì(¢mŠÌ»R’@û%qH/Š|÷ù7ùÉÿ8úò^zâo ÆIý#jŽðÅ=g‹â’ØûÔÇ_Úc‘”Aw½•í}&ÀñGù§—ûñ²–¼÷¡y”,PKõmDŠÊr“ßèã忈L¢Cé=—Ûú}^ÀðÏù§ôwþ6dùv—kš½¾…¥]j·G÷vèX/ws² ÷f aÜM~²:l2É.Q3Ð|^“ÿ8?ùiuu«þvùŽ>w5†€Î:Õ©ypƒ°¨ôø°f@ˆjuË3926_kaqÝŠ»v*ìUØ«±Wb®Å]Š»R¹¶·¼·šÒî$žÖá)à‘C¤‘¸*ÈÊv ƒB*ü½üÇòåÿüã—æ®·åñÝy_QC{¢‚Ü}[IK>#_Š& “Ö…©ºæ.«L2Þê»c²F²_ ¢yùud>Aüˆüãüý’OW'ÊÞA‡Žîæ7Q4}µ±*ót‘ʧ^-Û%‡M |¹÷³ìþÉÁ¥rþqçû>¶¿*!¿.'íycNëLœ.uëÞ3_Í_´”5?ÉUñ©ß2’—æ¿üäåÇ峯˜µu¯åo X•šöBETºÔ”ÿ<„{W¦)ñæçÇççÃϧY1òÇå,†ÂÕÝhúsq@ó“Ý,~+]ó7K É›¡Þè{_ÚM.€TÏÿš9ü{¾?ËÞIѼ¾dO­j­ÜÀù Ñ_¾tÚNÍLJ~g¼¾OÛ>Õjµ×x!üØþ“×îòRóç—¿NhÍ$ ]BË”ÖôêËO>*=ÀÈv¦“ÅÇcœy6û!Û?“Õ#èÉé——qø}ľÑÿœKüá™ÿ—0éZµÏ«ç+¬v:—6¬·àRÖèÔ’K"𑺗ROÚǾâCß±CÁ¿ç/?0çò俣Ÿ)‡Xó,©¢ZH†s«=ËŠn?rŽ€ŽŒÀâø¯Èz"húËKËÐ.'nôqT_¡çcÙšaï–åðÏk»Têõ’ú1úcðæ~'ì¦Q›—v*óß0¦»ù®ÛùÿÈ÷Òé„lé$ö¤+Bó!˜ ÅÁ!~yÌö¾„@ø‘äy¾µìG´'4-”Ü¢='¼w{ÇO/s!ò7å®›ækX¼éæËùµëýTµÌ‚Id ÈX‡3ÈÇÔ‘ÃËp+ãœäò§¨Öö„ã#íO\²±²Ó­ÖÓO¶ŠÖÙ>Ì0"ƃäªÊItò™‘²m‹b¨Í3HÔõ«¥²Òm%¼ºn‘Â…ˆ&›îvÄ g r‘ -êþZü‹¸‘à—Í×éd&?ºÓ­Zw re2¨ H@Ûwlqw»<=˜Œ×“Ï|ñ¢XysÍ:†¦N×–®¡Àä¥9BGRµâNÙ Š.§„ÌG&=‘hCÞØÙêV²ØßÀ—6“/a•C+pq”dblsx™¿,µï&Þ7˜|‡,³Y­ZkWš4­Jñÿv§·Úýrøä¾nÔgŪ‡‡œã‘FùSóM×BYêluc·4†Vÿ!B”ýË)å{SÙìš{”=pûG¿õýÌ×v*ìUØ«±Wb©[yoAkåÔŽ¿F,ëVæ CmJš÷ÅÍ£œCƒŒðò«Hüáå ­bê×\Ñn×]²§¦Ï²HªK($B 4Ú‡¡ÅÙvGkG e‹(âÇ/±¥h>aÕu'›Îšu„¶¡Ó‘B –D5 ­XƒûA˜ÔW#U®ÓáÆ–süê¾?e{‹Ì;v*ìUØ«Ï?-?òcy«ýkÏúŒ_töWû¨Âã÷±bõ®Å]Š»v*ìU'ó–4o4Co³š+i}h»!'‰R¥–‡‰®àZ3éã”.ˆ½7HÒôx¶—i¤;Ua@¼©ÝˆÜŸs‹¨ì\³^S6õ?ä×çá›=>‹¬þM:} ž)þ=ïDUTUDP¨ P(Í“´JµÏ2i>_ˆI¨MûÖŽÞ1ÊWù/aîh2¬¹ã»NmDqÒ?ÌþvóKwå'_jz|D‡žÚÚêéVŸÌÐFT|³ö‰èt»Lô úŸlu+¯Ñº” ¦êaŒ~”§à2Ä¥HR­]¸°öÌŒ:ÈÌÑØ¹85Ñ™£±eÙ˜ç= RüÔ¼Ô¿+ôÿË«‹D•ìç,u ~&[x›œ ìÓ!?Èîi8 ÜXé@ÊfóÜÈrŠ»bžkó\ºTé·ä‚žPóSV@¶ñÿ¸Ë‰ãÔ·JzD‘öá¥:”c‹!"&y‚Í?ÉMM4?ÌÝitæb–š¢ŸV)ÕEkÐø$ÛrŽCÚãÓ+”¿²½­Í†£—÷‘ÿd?_Çæ‚ß~vùãË¿—~Qg6×Ò£ÜÜ20-9Í4Šfƒ7¹ØvƤ{OÛ±ÕpÃô Ï™ýÔ,ysJò‡—tÏ+èˆ4&Ú+KHö¯”/&"•f?7rIË=6Å]Š»v*ìUØ«±Wb®Å]Š»v*Ç|Åä/&ù·QÒuo3è–šµþ†ÒÉ¥Ky˜[¼ÜyU5à¤r„7ÅVù×ÏÞNüºÑÛ\óž¯o¤iËQ™«$Ì¢¥ …’F§ì¢“ŠÓâÌïùÌo<ùúâ-þMØÍ¡é ðK­JêR)¨,¦¦;e=¨Yû†S¶]ƒO<¦¢-Ã×öŽ $8óHD}§Ü9—èÿ—ð‹—Õ¼ÏpÚ¾¯;™¦i]¤C#³;?Å#Ô·Ý“±á çê?gí|»¶½¹Ížá§ýÜ{ÿˆÿÄü7ófŠŠŠ*(¢¨À ÜO);•ءثÑ|Ë­~F~céÿ˜ž[RúTÎaÔìãðJAžÙ»ÀsŒþ˨4øs”í]‡.8ý2û ìþÆöÿæðø9ï1ôÑï÷ŽGà_§>SóV‰ç-é¾kòåȺѵXVâÖQJ€Û28ñt`U×öXš‡³|Aÿ9½æ#æÍ)þ][¿+m&ßë7Š»qŸQĬ£õ²í>/$cÞ\.ÒÕþ[M“/óbOǧÚÄ@ ¨¢€wÎD’l·Š»I¼Ö°·–µQqOOê³˧0¤§ÓÊ”Ì]p ︻gŒÆ»>8ü¯²ÓÈÉŒžJhËòôo'UZ‚QJ£RªI9çÙy¾ÅÚ£÷¿¥ånµØ«±W®hÿvú—ca¦ynÚÝããú@ÂÞ”rñز*­y0ß““Cã–ŒµÑÚãí!€"<Þ£Ÿ,]\_~kY_Ïumõ)VKiÜ·Õ0$•P1< mþŽX+êsñðs{|Ÿ6ÉúSÌz­ÕÌPÉw¨]¼÷r¤(Ò1©2Èh š ó›Ïž)Èžd¥øÝŠ»yÿ¿*4?5ú—ÖtÓu¶©7¯î¦n¿¾AÔŸæø×'„; /hOÇpóD×<éùstš_š­^ïL¯'åÈáš”m¿a÷äåàƒÉ†³±túÀgˆðKìøÒ>×¢hž`Ò¼Ál.´ÉÄ€yøeŒø:Çϧ†ŠÖè2é¥ÃWŸCî)ž.±Wb®Å]Š»v*ìUØ«±Wb®Å^yùiÿ“Í_ë^Ô`Âû§²¿ÝCþ¸=‹­v*ìUØ«±Wb®Å]Š»v*ìUØ«ó_æ7—¼¬ $úÆÜ‚ÊâÇÜ'Ó¿¶.§] [s=Ï(º½ó¯æmÅe?TѾ’Ùh~ù3#šY9ru–]IîÙûY¯—¼¥¥yu[§­zEî@ šõ ÙG°úk›|:hãåÍÏÁ¥Ž>\ûÓì½Éc>oód^]¶X`]Và«ÅÔ é͇…zç1µ:Œy¸š­HÆ6æ÷ùÇßùÄc«?1?:á{›‹¾7–'ªü'u’ülw+n(û}Ðie##eÐO!‘³Íö••žk ŽŸo¥ºˆà¶‚5Š(Ñz*" 2-o ÿœŠÿœlòÿæî‘s®hÐG§~bÙÄïe¬k¨_†Þî€rœRCñ'ºÕqH/ˆ|‰®Ýß[ÜhÚ·%ÕôÆ1ʲ‚%(§ù#-ôW|Üh³ñŠ<þÐê8ãG˜fšç»v*Çü׿{-Ø6“P˜kî{»’?™¨Î17S¨ãæúþqþqæâÑ¡üåüÄ·2k·¿é[ÓîWâ·ŽAµìªÝ$pr´øâêWŽŽR$ÙyÙÌÈÙ}ƒukm}k=•äI=Ìo Ä(d’9«£)Ø‚ ÀÁùyæß(Éù5ùÕ®y ƒ.…{ ›Gw$†µ¸¬¶¦§©Z´ {°9™¢ËÃ:è]gæát)þn]ë±U®é4’0XÐv&€*I8“H&˜W”ô9¿7<õÊpËå="’OԗóLFþ €Îo´5vl|;;FuÚþˆóý_¹õ\qÇkJ$QUU°fô€_ÿ+<©ç˜Ú[ûªêô¤z¥° 5@ØH:H=›2Üy¥UÚ=‡T.B¥üáÏãÞÃ<³çïÏùÆ™VŸüSùsPÙÌd{h£&¿»oŠKVûã©èÇ6óÆ^÷í.Ãͦ܎(ÿ8~žçØ”ó‘–ÿœÇo£^þŽó/Íåí@¬Wu¬a5ã2÷ŒÔ´«—:RµŠýoBѼɦ\hÞ`°·Ôô›¥áqgwM upEGP{b¬cÊÿ”–þJó-ï›|©åë]#[Ô-ťĶŠc‹Ñçê0ŽxGÈ…åÁEx YJDófø±v*ìUØ«±Wb®Å]Š»v*ìUتPÔ,4«)õ-Rê+->Õ ·7w,PÅîYÝÈP‰8«äÍ¿ùÍÍ2ÂY|·ù9gú{Ycé~œ¸‰Í’7Cõx™‡fn)ßã(ÄÈÐXåÉ q2™ˆæNÁó%Þ‡æÿÌ a¼Ñù¡¬ÜêZŒ»úRKÉÂÖ¼$IÿÄùfóIؤï“o'ÎûkÛØÂá¥Gùç—Àuøü‹-²°²ÓmÖÖ··N‰ ¯‰ñ>ç:x£Q3Õk2ê&g–FR=OãìDäÜu9æŠÚ.'`Ĭò9誢¤ŸÁ)‹<ƒ€}šìíÖæ#$‡(ôùFGâh'ÞXóIÖ¤ŸN¿·6ZÕŸûÑlkB+NK]éR6÷-oŠLd8d9‡AÛÝù1¸¥âaŸÓ/Ðü“KOµÕlfÓï¼ëŇqÜ|AÜf^lQÉr.—C­É¦Ë¸ÍJ'ñóDþG~}ë?óŽšÿ•|Õgs¬yõšâÚ;b¢[yéOZÜJBà,e…Ä kËŠÕie†\'û_}ìŽ×ůÂ2c;ÿzÄ÷~£Õˆiú¾­ù‘ùƒæÍ=r?N]JâW¶Ž¥„a€#F4ªÃ ¬@÷ͧb鉑ÈyOí÷kF8†š'Õ#rò>ó¿Ã͘çJùC±U »ËKZâöd·zÉ#_¼ä'’0#A»O¦ÉšBâe#Ð b:n™æoÏ/6ZyÈ–ìönë%õó«,Q@Œ9ÜNvãW`wf 9~ÒíÓ§ï}ƒÙOe¿$‘‹Éj´YpÉÇ$ÃØ«±Wb®Å]Š»v*ìUØ«Ï?-?òcy«ýkÏúŒ_töWû¨Âã÷±bõ®Å]Š»v*ìUØ«±Wb®ÅX·˜ÿ0|±å®QÝÝ ï–¿èvÔ–ZŽÍCÅÙ‹‰Ÿ[3¿sËõ=ùßÏ2=—àm?N? ˜ZÄÿ¿. )òZ}9n<2™Ø:™ë3gÚ‡ãª3Aü¶°²+s¬¸¾»ëèŠú zîïôíí›<:Çyn[pè#å¹g‰ª"…E*¨ t ÎØ»v*žÿÎ ùÏó7óOZüÀ×ãZ_• 2Ø[H*{rÎ-MÄB‘3Óùøç²äã‘/1¨Êg"_¡¹[C±Wb¯ÎOùÊ/'ÊïÏh¼Õi£åß8«_¹.Y„wËSÔ‡)9ÿ\eÚ|œÊÒåà˜)x ŠŽ™¿zFñT›Ì~c²ò呸¸<î¢ÚØ4Œ?RŽç)ÏœcZ3çÅ—¥Î1ÿÎ<_þbêÐþmþgÚ“åÈÝ&Ðt™’‰¨º¤²FÕÿFJ|*½=~óÑäÈfl¼öl¦fËï@: ƒK±WÈßó_—2ê¾VÒ?3ô˜é/,Ê-5)#_ê. RÖ‘O@üXǶ Ó(š/žô Z=oI¶Ôc#”ªÊ?fUÙ×ïéíœqéðåãˆ)žXÚÂ?25;˜lmtk*›MÊ0O´È¤ýf`? À×åáw¸ü†„G9>„ü¾òe§‘¼³k£@®ÈjýÝràs5ðe}†rYrq}²ôÒáúžòÊr·`ìU¦Uu(à2°!”Š‚PF*CÈüéù£jÓgÉó‡õèØK‡’Z´Šj*|Q5z4{å̬z’9îó¥ìÎ,×,^‰±?«áòO<…ÿ9Wù›ùI{•?:ôÙõ;²œMúF»sYvŽèM–OænÙ ‚Cg„Öh2éåÃ’5÷q}äÌ?&~dhé®y3WƒT±4ˆÉY cûBôxÛÙÔ{m“p™>*ìUØ«±Wb®Å]Š»v*ìUØ«±W€~qÎZþ]~W›#Ky£ÍñU›c*‹kw®®€eR;¢zìÁzâyÃΛŸž÷«}çM´ÿ-«ú–š< ÐZF+QéÛV¬Â»K33S¡#lÚi;+&]åé#Û>Ùi´— ¼Ÿ—Ò=çô±¢yoHÐ"ôôøÈE$¸ŠWù·ðgK¦ÑãÂ=#ãÕòŽÕí½NºW–[tˆÚ#áúNé¶dº—b®ÅRÏ1YM¨èwöVÿßÍ ¬cÅ©P>šS1õxÌñJ#™ϱuQÓêñd—Ó ÷~ăò÷YÓî4˜tDNÅdúų!SA&ïZSr£­s ²µ0ùJ<ÃÐ{gÙy¡¨– ú±ä#†WåËä6éI¿èm,y›ôÂÎWV0{`éF‹dæRœ¼kLÊü¼F—¢$h±Æ¡#Pª€°$¹LÈÙ6JRÕ,4‹V¼ÔgX-×nMÕ‚¹>Ã*Íš8ãÅ#AÊÐè3j² x¢e/Ç>æ/¥ë>{üÂÔ·ùcåÛ­Jë`ó$&SmƒÈº‰kûRµ3A¨í¹±Šó/¥ö_üñÄ jeÄ›‡Ï™øSÜ<‘ÿ89æ¿0Í­ù¿æSh„†m#MassÄîQ®÷1hÒAïš\¹§Ü½Þ“E‡MPCïïø¾¾ò寒,tq¢y+H‡L´j5Ä«W¸¹qûsÌä»öäh:(l­ÉNõÍHó.‘y ëÖqj>¡Ayg:òŽXÛ¨#±Aƒ¸ß~x~l~Pù»þq£Ìïæo,¬Ú·å~¡"©w%ŒÛá¶»*>ZÒ)©FéÖ«‘”m§S¦ŽhÑæÉ<µæ#ÍšjjZDÜÓa4-´°½*REìÛ1eg> b•I9ÀÒìU—þ[êþZмɧæh¤’šÑ‘y¬sÕÙ:š~Í:þRîåèòB¹2ËoÍû^÷S´ó®™õï-_ȯkl€;ÚTJÖ£v`ÀÖ´ëLŸ‰|ܘö€‘"bâ~Åú¯š#óðÓÿ.<‡§7C’E3<Š÷q·¨Y‘ Š~2Krf§~©—Á93øÕ‹ È¼Ãÿ*±n´ÏËmF)ãšÄÇ WÖéúRÊ6Y&5z±~MEãÈïÓiMù| G’ù÷Ê/ä¿0ɤz¦{gn-&aFh\•€Ú¡•”Ó­+í•N4]f«OáO…Œä\gb®ÅRícBÑõûoªk6Q^A¿*Õ‰Fe>êFHlÇ–P7O(×#d·›ô‡“57¶¸CÉ-®”¯ücž1È{_öYlr÷»Hv˜áËŽŒy¼Õçÿ&:Ûy³L{‹`B‰ä^5ö[ˆ¹FßMNZ<œþÏéuâ—û>GvO¤~dy_Tâ’\ ƒAéÝ‹_i)O™ÓÎêýÔâÜ1ýÕÍ•Ç,s"Ë ¬‘0ªºÊG±bé%DQ_‹b®Å]Š»v*ìU矖Ÿù1¼ÕþµçýF /º{+ýÔ?áqûƒØ±z×b®Å]Š»v*ìU ¨jºf•¯©ÞCifžEŽ¿.DWèÅ„òF"äiçÚççO—¬CG£C.§?g ÁüŽGþéÂësv¬#ôîÃnuÏ̯<Õaå§érTR.VЕ>.k#=²üziÏp¥—QŸ–Ãä˜èß–ze¡Yµi ôý}1T„<›é?Fl1h">­Û±v|FòÝ›C6Ñ,ñ¬P ¢FŠTx6ÌÐØ9à°T—b®Å]вùÃ=iþ@üÈó寽2ÚGæCésÊB£^Ú Qr= ÑÊxW«Q»g;’2!åóã1‘ÏÐ<ƒK±Wb¯ÿœ¬ü¬—ó?òªñt»s?™¼¾ß¥t”QñËé­. _ñTª÷u\R á¯!y…5%-&÷!b«ŠNïÙßm¿Ï7Z<Üq®¡è4Yøã]B7Ìþj±òÝ·)šþAû‹PÔcþSx/¾YŸP16ÍF¤coTÿœtÿœbÔ0oaüÏüß·qåù8O£hSU úý¤–dê–À}ˆúÉÔüoI“!™²è2å36_yEPD‹1¨Hã@UTP*°t•ø«±T·£i¾bÑïô fÝn´NÞ[KÛw­$†d(ëQ¸¨=Fã~gþh~UùÇþqÇ͇Š][òïQ”?SQð0?f9HŽáÆ»HGù9}AÆ|œÍ.¨ã>It~ò«À&kïL‘SE'0|(ªGÜsh5˜ë›·ÜuvÇ^ÏÍ›šý¶ùy ÞêWújÉ8{u«ªŠ775á>͹ØoAšÝ^qŠn«T' cµ='Jüÿ»Ðæ:æNy§k–„GtñÃéIËÆ[Yý6CãB}€éšyé;‹Õh½­h›ïêgz_ç徫ÄE®Ão#uKÅ’Û‰÷iUSîl à˜èïpöö“')ïÛïfVwö:Œ"ãO¹ŠîÜô– T?ì‘•C´Ç–3òD`fìUªéf¹c&›«ÚE{c(øà™­{^„v#q†2 ØjÍ‚bc0=ïÔ)|ßä `y¿òcZ¹Óõj~¢&á/ ÔÆ®ÿ¨i¼S å³7«¤ž/´½•"倨þiýõüÞÏùSÿ9­g5ÒyWó¯Oo/k±0…µ¨¡‘-Yº­[µd…v^IÞˆ30x옥c!Dt/­´ýBÃU²ƒRÒÓîKmwo"Ë ±¶á‘Е øƒ…©Š»v*ìUØ«±Wb®Å]оÿœ¬üÝüáÿ•…wùRn×ÊþV›ÓrY;ÆÚÇØ–{9ñ$2…Ây뺊ÐýbUPÿÅi¸=ϾušNÌÇ‹sê—ê|[¶½®Ôën øxÿš:ÿXõ÷l<™VlžU-ÖµÍ;@´7šŒ¼ík¼’7òª÷ýYF£S 1â‘v]—Ù9õ¹<|ùæ$ Ûøù=GiöwgvvžX¤N]D‡1üô}²>@³œÜ<+±Wb¬gÍO§Þù‹M³ô¹E…®B „‘Ôz}ªPuýY¯×†É8¹[Ó{?k³cÒæÈ|+âá¾ ‡w_·«Òît_-Z§šu[ãªy†þ>qEœ™yÔïµ:1nñÖàž<ñg.9ÉêûC«´2 ~ f‰#»¯ésç#ÝÑtë³coxa{vÌ2©WBz‚o±d㈕U¾o­ÓxeˆK„ÕŽE–8ÎÅRoË!Yþu~yÃäß0Þ½¯—ôøf¹šß„³ÅlªÍDÖ#0,ÝBMÀÎ?µsæ òŽÏ¸û¡† 'êÉê'îú_¤ÞXò§–ü™£Á yWL·Òt‹qH­mcµîÌz³Úv%RsZõ)Æ*ìUتRÓtýbÂçJÕ­b½Óo#hn­.dŠXÜQ•ÑUð_ç_üãgš?&µ;ÌÊZóÊ Ê]GG«O>ŸjÁ”’Ó[æÝã·BùFØeÅ‘á’_äo>i~v±2[ÿ£êpõËj²WöÐþÒßïÌižoU¤–¿.öY‘qŠ»{‘µo.ùÈ·ÞjŽæÏ4ßk ¨`d„Ôúq²Âíê9èhZe°""ú»]6HaÄgw"˜Aæ/Ê-jþ;kM-Ÿ˜¢ô¥¹ÓøÌѽÌ@p¨¬p)ñŸ뇊'vÁ›O#âKiw<ÓÏžl9yŠ}_ŠÔ*ÁgnÉd•åMªI,~y\åe×j³ø³âcYØ«LʪYˆ I;sŠ¡bÕ4Ù¤Cy’‚$ÈÌOÈãLÎ9ˆ¼X,–(¦¢™HœQÑÀe`{v8¤`úçå’µ®r%™Ónš§Ö±oHTøÆAîQ“sqvŽXu±æÁn¿&üá¡H×SÖĨ }"ïk#xhÛý‘`Ê:¹SÖ`Ì+,ûjO0þhùdñ×ôW¹~ÔÆFßñuµcûòb@¸9;E›û¹pŸè;¢ì7ôi¨5 )íX÷Œ¬È>gà?ð¹*u™ý’Í¢B^ý¿["³ó甯iéê‘FǨŸ”úe ?§7aêñóÆO»¹<·½²¼­.b|b‘\“‹®É†pú¢G¼+âÔìUØ«Ï?-?òcy«ýkÏúŒ_töWû¨Âã÷±bõ®Å]Š¥×šþ…§Wëú­±V[ˆÐü¨Mqj–hG™Ž_þky"Æ _›©ì[E#ÿëÿ ‹>ÑöÅ5Ï8*cÑ´‡‘ŽÉ%Ôwíû¸¹Wþ ‡>×ÚM7š?5¼Ì8ÚFú}³÷‚1j´ñJKÿÀ¶] 4åÈ4F§'-‡ÉJÛòÎþö_­yƒT2LÛÈ#-,ó–^ÿìNeóÏñG³å#s“-ÒüŸåí#‹[Ù¬“¯û¾Þ½|G-‡û37šäÜzXCOr÷!Ø«±W·yCò[A¶ò̘™ÚYùbHãž+["d’E—dY$Ujv)³{ƒ˜Y5G‹†w]—Y#. ÑŸ˜MüªÔ,Ï¿—ÑIaõ˜íY%{ŠÜ‘chÊ\3ü@82ž€ý× ÉÃ&83ex'½¼3Ý›±V-æï(¦¾‰yfâßX·Ñš¤Ô+¸¡û-Û1u:aXæáê´£ ±Íë¿•ÿóšiò<0y_ó‹I¹Ö-­•cƒ[¶à5M>ꬅc¸ ÿvVþbä×4ó‰¢LR‰¢)õ“ç#&<ò"FóeœÒÐ IŽŸqÌþ­Ð@íÿÙ² tõ%euWF ŒV ƒ¸ ŒPÞ*øcóëò+òŠO9]ëžRüÌÐü•æ[™]KB½½"Žw$É$fõ`äMLe­iÄm„HÃ8ÌÃ%üŠÿœJòÖ ó×™üÓcù‰,N }:E¸Ò–u¡i9»NW¨F ¿Ì­‰$óYLžo°€è00v*ìUØ«±V5çýoÉ^_ò–¥©~aIhžRHøê ϪÄÑeoQ˜ÓŠ$žƒ|æüáMÿ™È¼ü±Ôí4¹fîP^]¬Hyͬ`½â±÷*?`ôÅ–ï¼<‰¤ùKòå›þ^YéöžY¼.mJŽ4‚tqU“”`s$uf©ñÅŠ3Ì>Qò¯›m¾§æÃZ¶‹¡i Ð_uõU¸Ÿ1Wù‡þpóò_äñy~]á«Yô»ÛˆºøE+K§´x¦Þ3æßùÁsËË&µù?ç ÒPüQiÚ‹ i¤WŠÞ[qNG W‰T÷a€ÄmØuÆn$Äù0/&þiùƒFó ~^~lØÉ¥yš Ù.§Ñ-!ÙuÇ· Sà`GúÇ6š·‹Ûö7´ž!ós<¥úÿ[Ù³ ì]Š»c^nò–<ïkèk¶jóªñ‚ú*%Ì=þ éþKU}²Èe1äàk»7¤TÆýýGÅæZ;~uÿÎ:^ɪyQ}sÉ¥ý[Í&Ti *7&kZòCN³@Àíñ6ÌüZ‘.{ƒí/g3`¹G×.cÞ?Õ_“Ÿó–—šWÒu –|á%ô]ô«è\Hv¥­É ®Od`¯à\ÈyÂùŠŠ»v*ìUØ«±Wb¯ž?ç.¿&Oæg[Ì,§œ|¬²]Ùª-dº²§+›m·-AêG×â^#íœRùÌc_Ògjê6|b¹¯Wø$ÿdþõÎdz5~6=þ¡Ïõ¾ígb~GRLGîç¼|»ãðû©”fÅåÞùÕõMZ¼…®tkY8]D ¤¸jvø¿S¾i;V58NBâ9¾ìn^=>£OŽ\f.'¿jû>Ë¾Šš‡æ ]2iÞQ¶{ýBQDs,qûñjOz(Éeí^/NÄK^‹ØÓŒºéŒpKŸŸ•’˜ùzâçG‘tß2êés­j/êÃk^F/‡uä6Óa@+ök—é',g‡,îRéøüw:þÚÃV]& 8…wïμºÍ}TÊódònÅVº$ˆÑÈ¡ã`C+A¨ âEóLdbAˆ`Í ùkÉú”z­ìR\ë¡£pг2Š‚T oF¦Àl3Lt¸tÓã¾#·t^î=¯®í\9øp¹nx²WÀóîêNå+òí×›Tžsw-õŵé¶Õ´çaéÇ l%“(CP(íá˜ÚIçã&̈•J>]áÚvÖŸ³†ž1àŽ8Ï,ƒ™þPóÏ^÷¢G©éÒÏ´WQI<Êïk"±uCň¡Þ‡øøføf ,¾s=xÀÎPŒHv'qø÷w¢òdžëMæ/$ù§OüÏòdÆ gJ‘&—ˆ,>àK¨§(Ý+«ü§çœ÷lhI>$~?­ôïaý ŒcùL¦¿˜}ÿÃóÜ|»Ÿ¡‘ÿ~^üëò¢ë:w=vÓŒZÞŒ\4–³³/v‰èLoM÷âg<úiOÅÅ]Š»q‚¨=F*üÖüÍ´òv‰ÿ9<Öß•’ÄÚlä~™µ³§Ôíï$I ä0ðªðPB£e’ª)Çhdäãk€8M½1^YØ«±Wb®Å]Š»KµíjË˺EÞ³¨5-m»NNݽوQ„ -˜±ÈDub–’ߘ¿ó“Oæ=kS>^ü¾†fŠàÒ‰ñÚÁTS£Ì涨Ur££š†Ã~÷±^Ï¿<öœ4ÿ7j°_P~úx-gŠ´ß÷H"n¿ñfIÈây·˜ÿçÿç"?,‘ï¼›ª§›tx7ú­«±¸àõ²º¨ú!‘Û"` “K'0Ç<¡ù­©¨.yªÌè¾dÌ ŠñÆó©âb)'Ç×nß½vÊ'Ž6¯³N1ÅÃÒ²·XìUتS©yc˺Ác©éV·NÛ™$ Ÿðtåøá!¶çD†)}ù1ä;ʘ­&²cûV×÷7¨? Ê\¸vžQÖØíßüãþ˜Æº~·qnAª™¡IÈßü†‹$39íyuˆ(6üšó¦ÚgšhÙ¬—0v§ìÉx¡„µzyýXø¦/7ík°Ì®×rµHíû؆5˜h%Ïù~¢Ñò·çlCš^E#ˆ$¶5úÇÄ‹Éöqþ÷_­ƒhÒyêËÌšÂhÏÇ_ËÈÖ¶žMÑg{]E刲ÃBVeeãsVä«3ƒ×|„±3-Ë\ðÄcã3õÏߜڗô¿Ì}jËËA#ÓãxËÁ PÜ4jf)°ë°û&«Û6S#nÓG)`Ë›ËÜ—bª76–·‘náIá=c•¯ÜÀà”AæÆQb¶¡ùqåËÚµºIe!Þ°½V¾êü…=…3z[8“Ðc—-•´4þn~JÕ<™æiŸC·eiôÉ™¤³e,*$´”´{ô/ÀŒÀÏ£”ó»Q¡”ó ûÍó¿œó¦*y:ßü- ¬ vk9¤Q,¬€Jf¹ uˆž\ O‰‡Úçû82ÓÙý›—U>yèôoùÇ'ÚZ*ëWWZñ¼’7ñþB(-÷±Ì)jåÑí´þÊ`Œ}dÈü‚Oså>~@k çÿʽRâm2 RÆ_Œ5ºµLwQ'šÍXÉö…ä/éâØót]±ìä°êü“üÞÑ9ü•™ôÔšŒMõmgKçÍí.”V´£Ê6¦ãn ”òÄ=;v*…Ôõ=?FÓ®µ}Vå-4ˤ¸»º™¸Ç1)gv'°~u~cyç^ÿœ©üÆkKaù[å÷&ÙHàÌ„•7ZÏ0Nȫȵ9²ˆqÙ•-^JåõÇVy©þYùCPò³yN=:[”¶–(Ç­ Áh³ûEë»?C×5ã4„­ôLÝ‘‚x|.Nð{ýÿz3þp·ÏúŸ–üÇ®þCù¢pÙç¼ÐØÐKåu Uê²!ú º;~Öm#+ù^«O,9 %Î&Ÿkäœwb®Å_7ÿÎc~Si^tü¶½ó­¼ šü¥ ¼†ñ@WšÁ·HÝÕT´©àÃjrj©ä”~d¸óGôÍBõÌ—ð‡³º‘K½»pIêY8³{œÔç‡ ‹ë‡«9ôÑ”¹ÁœeNÙØ«±Wb¯ üßüµò=Ɖ¨ù²çýÃj6±´­uj«ÆæC²$’ªÌì@ šÎdàÍ+›ÌöïdéÎ9e>‚:Ž¿7´ÿÎj¿šZï“õ-GÍÚ¬×ÞJ†E³òâ_-É–/ïÚ9ßã0 ã«rªÉórú«;v*ìUØ«±Wb®Å_œ_ó’¿–~HþfÅç_/[ò/™äw0Æ´ŽÚå;›@ûØÛUFÈs+G©8r ]}Ϋ¶û&:ý4±|â{¥Óõ$µÌ–ñ][8’ÞeY#qÑ•…AÎÚŽEùÿ> ♄ÅJ&ˆ],QÍE2,‘8âèà2°=ˆ;& Š,1ä””Iu V¾¿³Ô¤òד4t´¼uW¸¾XR4û† S·&ï°Í6|²ŒÎ,£ÔÓÞvv“\WÚÌà ‡&ÇNÿ€÷“I—¼g¥KúGRê:Ëmq-YQúÕnOùG–di;68ϽRïu½µí^]L|,#ÂÂ6áGtò{ÙflžMØ«±T.£§Yê¶rXßÄ%¶”Q”ö=ˆ#pGc•åÅ‘1°\­·.› ÉŒðÈ0ÝF=/òóMxô»w»Ô5Wô£ŸS‘QѨ rû o\ÕfÑ .Sï{=õ»œÒÇ„YáÚ½Þf¹ô¤–|§yåÍV×UÖE ‚Hœ»Ë(Ck1?  ¯$xl7ö­= °LNuUò.nûE´4óçãâU ãRzöòï5Ò••”2TŠ‚7ã:_3 ƒEÄ" ìAÅA¦kyæ_É¿6Úþcy SÀÿé–G‘ár ÌŠG(^?dЊåûO³¼?\>ž¾_±öd½©üÈ3ŸÞ¤ÿ;þ=÷¿E¿'¿8|­ùÍåhüÁåù=èxÇ«é077W‹Rœ‘¨LrF F•îÈz(Zî‘£I#gv *¨$“Ð Uà_™?ó˜”~A3Xé׿½v*g¤2½²½iI/§ÌŽëŠ@|ÍæßÏ/ÏïÏ$“OÑ£Oò]ÍUÒÑžV&¨¤·ŒÒ‚ aUFý¥ÈJ`8Ùµ˜ñs6{—yòãIòLM:9¼Ö&^^ºñ¢Ö¼#Zž+ã½Oá”NvèµzÙfòÌ‹]×´¿-é²êº¼ÂH¨+J³¹û(Š7,|?†D qñb–IpǛέ¿>ü³-Ï¥qayolMôèEÅw]‡\UÄ%XPˆ=AÅ]Š»v*ìUØ«ç¯.ÿäÉóoüÄßÿÔiÍ×fóø>ØŸHþ¨ý ÷7@ìUتœ³CòšE|]‚Ç@A sYݤÍÂã‘ÿ•XýÀàªäUð²v*ìUØ«±WÒ“·Vÿ™–:÷åf§ 7ÖQ´º[¾åc‘½H˜w¤SÿÉ`½3[©A0êucÂÊ2%ù'ùqæû>Xk3YO§iz%˽íäècVxy#Ao¶K|-Çe¯jݪÏ9’ß­ÔC€‹²P?š}Où\Sù³ÊÓ#*[hí®“t¸{hÂHI_´Œy%Aø—%§Ãû®ue¦ÁûžuLüõÿ9æ¿2$–\ü?¦>Ï$OÎöAJÍ@¨ÿ(ä1h£Îå†ÏŒw–åã ÌÌY‰,MI;’Os™®Á¬UØ«±T«¬iú-©»ÔfGÑW«»*/Rr2ÆË^L±€²À,›YüÜó5§–´ðl´º´Ó7ÛôàJsšZ ¢¯J+ß4zÍiòptøç®Ì1Çaú;ßUùgË:G”tˆ4] ¤"¬Æ†Id#â’Fîǹú4™‘²úVGOŒB€û|Êq‘rVº$¨ÑÈ¡ãpUÑ€*ÊE õ{–~Cë¯ù'ÿ97“g—Ðòœ¸Ú®Ԍ4ÅžÁÅz•—•·û#›l3â¾OÛ:Ëg”.cÜý Ë]K±U’Ë<Ó:Ç j^I…UU,ÄìN*øó÷ó§YüþóBþSþZHËä‹I‰Ôõ O¥¨<.?#-io Ä¿¶Ôn¼†Iˆ‹.vƒC=NAsû‡{0ò‡”ô¯%èphzJR¾9¦`=Iæ`9Êäu&Ÿ@ è3U’fFËêÚ4ØÄ!ý§½=È9o üÜ:‡åçŸü­ù¿ ¥.lî¡`l²Kly*¹¦‡œMþJæ~’{SÂ{Y¢©G0þ-¿§Ù÷?Eü¿®i¾gдß1èòúÚV­m휴¡hn#%GcC¸ìs1âÓUØ«Âç-¿14ï#þNëZl“­ù¦4m2Ô5D¸.¤ oÁ!-SÓ‘Uý¬R?~Ihsè_—zj]!ŽæøÉ~èEYÛ÷uùÆæ¯Q+™}OÙí1Å¥ó—«çËìzPîÝŠ»v*ðŸ6Ǭ~y~hé?”R:ÚàRõAh£h«õ‰Þ†…`Jª¹9ãÝsc¦ÅBÏWÏ=¦íO'…é‡?9~ÏÖýò¿–´'ywMò¶ƒ·Ñô›xím"Ú¼S“YYÛ»s)äÓ|UØ«±Wb®Å]Š»v*Ä?3¿/4_Í/$êžK×½üu¶º ÊKK¨þ(n#éº7Q_‰j§bqWæž‘o®~]y³Sü¯óŒWÔ¬'hà©% Ÿ‰}64ªJ¤I÷ñ9¾ì}m\º~§Î½¹ì8þkÜ}~î’ør>^æm#åMb¬oRó¶a.fã~ƒˆ‘Ôý]%eª,Ž7´©¦Ù¯ÍÚ8á# ßì¿7¦Ðû+ªÍ†9ø} >³¦#îïDy^—T{« Bk¬X0«rFW’D?ÊFY¥Õ— ”yþ·¶{":a ¸¥Ç‹%ð“±ÛœeæÜÌtNÅ]Š¥ºÎ‡§ëÖ«k¨!dGFèÜ]w ·ì¿µã=`ÔŸIt—‘þ—ßïçï_É/ùÈß&~phRÎfEó>›O­h×éEøî!‘¸ó„u-Õ:7bt~CåÎ/ο7ÿÎBùªçÉ>Dº—Lü³²b—©xÅú§Ö.©Ä”j~æÜüÛ³Jšuˆá•/,~VyOËJ’‹a¨j+Bo/†Ñ>Âûm_|Ç–B^>¿&N´<™¶AÂv*ò­D¸üÔüçò§å\´vRÍך?´ˆènnd¡)lœ–¾ù‘ˆmoAÙX¸`eÞýÔ(?,5o,Eäëÿ*éÒùzÞomkõtVB…åËIQöÞEpÇ©9k²·Ç™ÿóŠÞü£»ŸÎ“Ww:ß—V¯w¤0ßÁîCD -Ê èQD‹ü§vÈÊ °Ë†H1Ÿ$~khþhá§ê\tÍ{ì›y‘LÃcé3w¯ì6þÌyã!Ðj»>X÷‡ ä{±Wb¯üøY­ÓËz¼`0²¹œP׉wH Óþ1» ¹ìyo!îFhÿ^ÿœ‚üÇ×2¼ëÎ}"„Z~œì}8ãµ½¨ãAÂ$ ¸æÍÈדW{Ùz!–FRä>ö}¯¯8b#ª_`{m­­­” mgvöÑŠG (±¢ªÔF <|¤dl›)»ä/'ù‘[ô¾o,ÍÖåÑŸþFÅÅþó”fÑâÉõD985Ùq}2?¡ãvü›Öü«a©j>HÔnfÑî!)ªi~£$¯l¬%*ÞdVPÜYj(ç4ZÎÈ0PÜwuz-mŒ„G £ßÓö2¿ÉVÂ÷É6Ö„‹5åŠî6¥CK#L’ymò>Íå´vž22’z½ ëÞùSåIÚ;ùŒü»£r–?P|3OåZªžÚƒÄe˜ãÔ»œÞKéŠeùëm Ûù{Ìö«ûFÕµAó]—˜àC4PóŠîØ7^ÞUâé_Œ¾àeY±qÆšuFH˜²¿=~~y×Îpͧ[ºhº$À¤––d™eB(VY̓Ѕ êU‹GoÌ´`ÐÂó/,̧5Ø«±Wb­3*©f ($ìÎ*Ã5ŸÌ X&o—á:®©+âxýF4U^¹'²ýùƒ›]í˯ϯŒvŽçì{_äïüáÿš<í}œ;ž};Jø^Û˽;ë…ûAgãþóÇãýáÞ¼çW<†f˧˚S6Kü•²´Ñ2¼û¡E­Ý”óÛÁl~ÔQ[^Ɉ+¿Âx˜ÎAë}ñ&:Ðû÷ý{̼v*ìUã_óž[žãD°ó–™Ê=O@™KÍC¬8âàëHð©9•¥ïy_j´\x†QÎýÇõÛŸ“˜ÖŸšŸ—œ t7·0¬:´)OÜj—T}‘Ëã@a”÷Í‹çe›^^Ziö“ßßÏ­¬o5ÍÌαÅQ©gwv T“Šþx~yó×^ÊÏÊI$‡ÉF©ªj”xN €Žo! 4vËÐ&Í'q¸\„æ",¹ºMFA þï2È|‹ä]ÈZ:éšbú—Qﯜ-Ì u> ?e{|êN¯&C3eõ.ÍìÜz\|1çÔ÷²Œ­Ø;H<ëå{o8ùgPòýÅ®c­¼¬?º¸OŠ'Ûz´ê*2xçÂmÃí Ôa–3×—¿¢þq+óÖÛÉþ§äæLߢ®¬®dO/Þ]0H•årÏe$Œhµr^û-È­~Åvñ ‹‘gÃ,r1¢9¾ÜÂÒóÎ?Ï_$~Lèïu®Ü­×˜&›Lòý»©»¹nŠXoéÅ_µ+ uâ¾RâM:ÇÎ?ó^t?™ß™U_/!¦—¦ ¬bRÞ;ˆTï#ä5ëRF.|ü;oSØ=„s‘“ ôö_±îÀ€lÍsè®Å]Š»y·ç/æòG—Mµ„”ó¨+.'â:I9äÖ‰þWÈåú|\GÉÑv÷j~[DúåËËÏõy½Óþq'òI¿,|–|Ëæ~xó:$÷bAûÛ;#G†Ø×pÇûɇóQOØÍ£åÒ6ú';v*ìUØ«±Wb®Å]Š»|Íÿ9wùÿ˜~\_>yVÜŸ<ùr&gŽ}]BÂ2dh”.æX^*n~%Ü•¢ )Š;‚ù/É>hO1i¼g`5;Påzs¤À÷ð?Fv=­ñ¡¿Ô9þ·Ã}©ì ÏqþîO—ô~<¾,£6/.ÁüÏ êVÓ]_y~º:Ç}FÊThBÌ *VŸ¯|Óët³‰2Æ/iÒ÷ƒÚø2FõR0ð.Xæ 8ò7± ¶Ômü޲ÚZ7é4\[¢¥ž!A#r@íR™… £K`zò}º=}ûd‰ÌxhÙ!)p¿Åݽ#HÕìu»$¾°•e‰¶p+Tp*T‚¨ùfÿxåKæ½¥Ù¹tyN<¢Þ;Ñùs‚ìUت[ªè:F¸¨º¥ªÜza‰du¯Pj{W(ϥǗëì{;µõ:2N˜ß>D|†¨iú¦ þSÒ­Nå«>2^OOïë¸nUø«O†§µ[¥£. dŸƒÁÏÏñý¯o£í,:l#]š~>£&ÐÍò®ž{u¨ó²ËÞkµÐ5[½"kæºòŰÚÝ«é½FÕ‰wòïJŒ¯I®Ž˜^1È×êr{gÙìší<3dž¢{Ê<\ÆÿÎ<ù{®‹Ó!š+ˆ’xI Š9ÕYH¨ Œèc EŽO˜åÅ,r1¢6!S žù³ÈnZ]cËE­ï È.-"%©"GƔ䤫'FŸ=hvOÏ>ïÔú?³>Ùœu‡Rn<„û¿­Þ<úuò—~EjºTº ΋>†¯i+MzNæuÑ$@àWµ+ûYÉæÞÛµa.!+°y=_*uNÅ]Š¥óˆúió7üäG›¼Ù"ó¶Ñm/Þ^´–yÒÒ¾—2à(=nš8¢<Ÿ|ä›]м ó·þqOÈß›¾·¦òçØý)mô.Ü …Ü+@ÄŸ÷jÑüyR˜¤Ⱥì_œ—ñèÿ˜ÚTš—KzVz´le‚EoBê”&Ÿî©@Ê¥ŒQÙÐɼv,çË~nÐ<×mõíeeÍlßñ¯Ü|ÆÞ(”HtYôóÄjA<ÀÐÀÿ8tÁ©yùè ¶/äUñFàßðŽÙM,Î×’ý~hß?þq~kÿÎMÌžZÐtÖò¿åáukÕò$üX×7%cõ(G$‚5»µh™DFí]Ù9µ2¨ºË z’¼“¢ùGM+HŽ®h×wŽ­q-7g#·ò¯@3Y“!‘²úggö~=.>|ORÈòs±W›ùûó]Ñõ[o-ùJMs_’/.Г"A-ÅXÙO2vÝ…6Ù‹S/ňr4iö¦LsðGŽugÈwTÏòóó#Jóí‹úkõ-vÖ«¥HÕ’2 9¥@,•ïMŽÇÞ9q'#²ûZ¸ÿ6Cœ1?*ô/ÌYÏÔu¸W¾¥j$«QÍ|7v=pâÌaîaÚV,úd?‹õ÷±+ +þrƒËö åÍϲG§ Bba‰EQ剥Œ°XÍe\^F^ÉêA bG¿ö*ùcò"Ùu'óæ¥'™uÉŸÖ™%y$…äþi¤˜™&;~Õˆ9NMQ<¶w}Ÿì¶rÒ4Ç×<Ó%äʶд”’àU#—öX”5 ™àƪ¶&ƒÁdÇž33#$#Ç;;èîø>ò.³®ëþY³Õ<ŧ7R˜P«Ë(Sº‡ê“·}ó $@4Ó³säË„K$xdñLµísNòÞw­ê²zV6q™$?´Ç¢¢ƒÕ˜ªTÕg?¦,¢ZEcy3|@…û0ÎOÃÙ$Ûj Ëôú‰b˜”\ÓììzÜÓ‘ëÜzîýŒ?HÕ­5½>FÉ«£u?i}¤opsµÓçŽX EðÒììš<ÒÅn>ÑÐz8€À©ÜB=Ž\àƒ[°mBo#–Þ[Ó$ºÕõGt†v@»òâ[®Ã¢íÒ¤íšl±QX£r“Ýèòäí™êóbÂ1å~uçÔùС¼¿y¤y)íõÝAN±zâk˜!VC¶ÊÞ˜ É?†CK“’^©nk£“ÛmOlÊ3Ób>1Ã"˜³Ëo×¾ÌÖMcL‡O]VK¨×Np¬·¾aOlÛD8Éô÷¼D;7Q<Ç9ðõF++¨t!‘€*ÀÔw–ƒn¢A£Ív(v*—ëzgé.çMõÞÛ×^>¬}Fõ¡ÁèøÊu8|XÝ[°ì­å5ÍÂ'ÂyÇ>ãа}fÒkd‡òûËv…MÂ,·×²­%E\±ë¸Üöû#4ÚŒf iñ|ÏãñÑî{3S†]©«ŸÒH„ä{«î~¢Î´6=#LµÓbbél9·V=I§j“Ó7Z|#GGƒí-tµY瘊37HìµÂHõï5èþ_¾·0{ªU-#!¥cÚ£öG¹ÌMV»¹ß»«¼ìgµ:é5²?Oí÷9ù5ªYÏç½NòòEµ¼Ô ˜ZÛRˆí$É3Op£Ç|áõy É•s6û.£HpéaŒ\„îú 0Ý3±T§ÌÚÌ>^Ðu fb´…Þ0jZR5ÿdÄ 1[pb3˜{Ðÿç|¥6›ä0yÎé—ÌZ‚[Û»T™-´Ôeæ ìešU>ë™\_Zâ‡b®Å^Sª~s~Lk>pÕ¿'¼É¨ÙɪEéÛ]Øê‘ÆÚ}Ü’ sn²IÊ&u¨VG¡å°©Šiâ™ßó„RÝËæOÉ]¼¿ª©2¦‹u,ŸUåÜ[Ý%eн•ÊŸ´«€„$(‹ÔüËù¯ùK|š?æÏ–îÆ8u ¢Z þêâ*ÛÍAÙX•Kèësö\%¼ ±:½óÏ’üÙåmZÚßV†¸²¸F‚å„#4D…ÈäAþZŒ¬@‚룥ˋ$IP¿óŽz¨¹òÎ¥¤1¬¶b`<"¹ŒqðQ¾v‰’ñ˜÷½§Ú U’2ïsÙstèб_Ì8Úù'Ëw:¬Œ óƒë-Çoå_´ÞÃÆ™‰¬ÔŒ02ëÑÍÐi|‚=:ûžuùåû7Ë÷ZÝ╟Y‘^>_hÁ Œk¿ÄÌÇÜPç–V]ïjf˜ˆþ©eN­ØªomæzÓGŸËðÞ¸Ñn+êÙ°GŒÔ†$r©¨¯ÂF#TÚ3ÌG†öFÞyßY¾òµ·”&XF•hé$L‘•—àä@f B jŸ‡®#TÎZ™t o"ã³ï1yïMÕ¿/ôo(YÛO Þœð=įÃÒGŠÜhÅ·g®ã')ا;.¨K`á€äb¯¼¾Oü¬ÿ5-v3jDq|¿×7=›õ|?Sßö'!ýQúƒ›—¡cº?™SòÛó¿Ê}¹%4Èn"Ò€j°8kK¢8îH‚ZÓ¿LÔkáS¾÷IÚP©ßx~¤Å,SÄ“Bë$2(xäBYXT2‘±t9‚ësùñùž¿”–𝛢U—V,´h$G¾¹ªÆXmU@FÜ)¤Å–?”²yð¿æoæÄÚΣ­9»·¶žFý걨šr´$7û®5¢…§cAËö·lÊ8ñí\Ïê{Æì8Î&]ïý%ïún•¥èöËg¤ÙAch´ ´I ’€ å²d”ÍÈ’|Þ·(ÀT@Élxüäg,µo,Éç->Ýc×trs4kÅç´,ƒ‘ÔÆHpOE 3 ìt¡“Ã'Ó/°¼ß´:ÏŠª?hýŒÊš«k: ìÊã§9îdŒñb~tåôç©éòqÀQ¦ÉÇS¬¹½Ø«±Wb©f»®Yù~Áïï "¼b‰~ÔŽEBâr¼ÙD–¬Ù†8ÙTü¿üŸüåüú y§D¾_òDŒUµ[²ñ[È Â%Õ¸;ðN¢„®iòê§? èóë'? ûò³þq+ò«òÙa¾¼²ió"Qާ«F’EŽöö‡”I¾ê[›ƒÑóÃ%ï€t¡Ø«Ëÿ5?ÿ-¿(`dó&¥õp¯(43ßIQPY*5?Í+(=ªvÅ 3O+y“Dóß•´ß3hÎ.´=jÕ.!æ¬r­9pMQ×±b‡Ï¿™Ÿó„ß—¾n»›Zò]ÜžMÖdc)†Ú!>šÒ}ª­¿$hªßN{&,„ˆxΩù%ÿ9_ùkÈèÓÇæýÀ¶/€è=ÁÅÉŠ¹L°DôvúnÞÕbØL‘Ý-ÿk±üúÔ´=DhŸ™žYºÐµ!gu†X] hKÚÜ Ù˜ûf<ôÅèô~Öƒ¶XלWí{6©Xêö0jzeÂ]X\¨’ ã5WSáôìGlà ƒEëñeŽH‰DØ(¬ ŽÅ]Š»`ÿ›ï˜ü½å »ï.Y©HhîÎB 諹*{þÏÚ;—`ˆ2ÝÔöÖ§.Xã}çù£¿ñÉãš”®´½IüËü¨¾—SÕ­£T×ô©©$’HÀã  JþÆäŠ2šÓ2e;&3y}6†PÇ N–FR\~ñû>!íÚ”ôI5H¼ùq¢ /ÍwÖÊ.á2ôd~óìÑK‘ð³R>g1%3\7³Öi´XÌÆs’ù~ß6[•»'b®ÅPº–£e¤X\êz”ËociMq3ôTARvÜŸ78@³A¯.X㉔ðŸ>y÷Ëúúèþ{ò^´¹å© ²è·.öí5´¤ BÄô ÔÙý2~wøFfbÄEÆCbò¥ÚX²ðgÃ?V?á;Xë·ß]=̾_ËŸ"þf]Ù~az—-§ \ÚÅ*¬7>T 0âXà°Ýr¯Pô»9vV›[!¨ßÔ‹Ø×Ü^ F€4lÃ1Þƒ“Â/`Öÿç#ÿ3l?-|¡#'•4ù ú¦¦£”KL{¶èP}8¿7Z6Û->g›æÞÐö¿æ'ÁèÚ{ÿSôOÊ~UÑ<‘å½7Êž\¶º6• ÛÚÄ)Rvw NìK;~Ós%æSœUØ«±Wb®Å]Š»v*ìUØ«±Wb©~¹¢i^eÑït rÖ;í#Q…í¯-eI"PƒÜàÁÜoŠ¿33?/5ÏùÇÌ 4»ŸRïÈzË4ÚMñó€5(Ä ¡¨Yí â›Ï×ßé<ÿ[Î{Mìü{C§l±úOûÓä~ÃñNaš+ˆ’xI Š9ÕYH¨ Œìc EŽO…åÅ,r1¢6!}ÝÓ –Û3ËZ¦´|ݧµÃÝJïivðúÉ21f*…¶Ôwö4¦sàÁ9øÑ»;»}S8ÏÚ}?ärˆˆ%.¶æ·¡ûEÛ¼­äûÝn{lÉn]ì4âH.$bõ=S^½[åƒE –P ö€åûAí.-¥=K<¨O'u ùùr÷¨GpƱD¡"@@ ªt:0,œÌÉ”“̯ÂÅØ«±V¨+ZoÒ½éŠÛóœtŸ.Jv3ß‘U´Šœ¨z'e¶`êûCŽç¹è»ÙN¿xŽ8òøwýÞhŸ'~\þ{þsúsy[HmË3Ÿ‡X»-gjPþÒÎàÉ(íXûç=¨íl¹6‘åúßMìÏc4Zj3,»åËý//¾™ü¯ÿœ#ò•¤‹VüÀºo8k`‰>ªêÐi‘¿SX¹š‡¼Å»¦k ·« ‚¯üäßüã*yîÎ/;þ\@–zÑ¡Eú°&£ol D‰ÇˆI¢‘6Õè¥Tóؾ?›ó‡Î/a— ÓÍ¿›ÒSku<‘|uO†ž„‚‹%kêré¿ÃiÌ¥C{u´8pñdÉ*„Eû¿7/ž?5|¦âó[EÕ4ÍŒªé ^¿¼€SîÕ\ËÔv^LbÈÛÉÕè»K³µ§ƒê]ÆÁ>ëçðÝ6ÓÌŸó’>sÒ|ƒåxÆ™¥Ð]êÜ:ŸJ8è&À#ŸÔŽ5݉ޟ³‡S¾Ñè†'rý0ò•´$ùgKòž¡¤iékj„ÕˆA»¹Ú¬ìK9îÄœ±ÌN±Wb¯3üøüÕ´ü üºÔ|Î̬Ê>¥ Û>þµüÊ}2WºÆ‘ý–HÅ ??¼¡ù<þyòåך<Ï}q˜5¹žòÖì䉳K2¶ïê³ê (k¾nô}”2bâ‘¢y:wlœYxbŸãÉ›ù7ó·ó§þqÞâ 'Í7›?/•„q,Ò»úHNÂÚì‚ñÚ)A^ÊÚÍ~§E“ õ »Ý–“]‹8ôûº¾¹ò/çoä×瞘Ú=µÝ­ÅÍÚñºò¶¹IrÕܯ¡7(æÆ"àw¦b9”Ä<Ëÿ8Kù!æ æ½´ƒSòÿ6äöÚMâ =h—‘\qÈ@ðÅmóåÈ¿+?ç!<ÝùujÒ-}T±YO)=±ÞÚ—j ‘Кo›~ÆÉYHï›·qñaî/fÎ¥ãÐÚ†¡g¥XÜjZ„Ë•ª4³ÌýTŸ`:äg1IäãÆg!¹/mWQüìó›êº‚¼OÒÛ„PO‚µT~Ü”å!Õû9Äö†¸å•ôèõ¢1Ñbá\¿gG¹ÇpÆÄ¡"B"(UTP@j16¿;v*ìUØ«±Wb®Å_:ùÿ&š¿ã6§ÿQË›žÍú¾©ïû”ª?Cгrô)'štüÅ¥=BÝ!õ-e?³ ±§Q‡Äuqõ8´ßÃ2´WãB¿œ>÷_^Kþl¾çÊÿ•Á‡—f,j Ü…}‡§ýuÏbÐ}‡ìïîþ,Û3\ô£¬izJzšÜvâ• íñ·úª*Çè åŒy–¼™cf˜÷ü¬¯,zÂ?Rn§­èžÞ•åÿ ˜ÿžÇn7ò†;êÊ­î »‚;›iX%PÑȦ¡î3*2Xs# E† ù£† .ù£3Y[LëqH êq* ]ÅB‘_|ÀíšÖö”MýBüºó_–<ëä½Ì>Oh†qmÚÛBE§¦¡ ³"Ð#DG´Ú›mš§HÊ1Wžþfþvþ\þRZ ¼á«,z„ˆ^×GµX¿¸§TŽ öy §ùX¤É>gÿœ™üîü踟Dü¢ÒdòÇ— æÕU»âz™/X„ÓâáõflÄÕk±`3^]\í'geÎj¿>Ÿ4¯Ëÿó:?Õo.üë©Í¬yŠý%çq¸Š æSYƒ9ç+†<¹I@{®s:Ÿh§) PüÏêünõš_fqÆ'Ä7":r¯ñ³.ÿœ:üÃÔ<‘æícòÎúlgšã@g?Ý"óš'~3Æñt Ýó«Áš9`'Eã5Zyb™„¹‡ÛÙsŽìUòoüæ'ç奷•¯¿.ZÎÏÌÞz¹”1qYBHâŸXiWtœðF¦»ü̲ˆy÷ä×—u_-yÊÇYVŠòi%ºú³ý«t˜Õc#± äGbNjµ–Ϫv–xtÂ3æl×u³ü¥Ü»BÞjzvŸ%¬7×Q[Ë{(·´I]PÍ1„@z’L ד4 @‘ˆÐó/7üâóµÞ‘å›DòÕúC.§ú6}V'V[@œ„ÚŸ…Á=À Ðåø1ÙÝÑv÷hKáʸ¥ÃÅÝßñý¬>ûIÔÿ+|ßåC¤yŽç[·óÂ[jZ}Üž§ÖÙ#2ª‚A?ÂNàŽ¬+–‰ ‘6*fLÐçÅÁÌd4AëË·û^¥åŸË/ùK̦½¢™ šª=\‹XwäÅ#ž•¯ÂÐf<ò™ Ðé;'Ÿ,²BÇNƒñötfS³v*ìU/°×t}RòûOÓïb¹½Ó$ßÁ†x\ŠÑ‡áóu$bCN=N9ÊQŒ1çäñ:ùãÏ7÷÷³y^ý4û =It='LÉ=Ʊz¥}b}U D ýªñ¥;œÊÇŽ oÝ~ç•íÑÔÎDâ—àŒjÌåןEo)iÞBü׊ûOó•ÓIó~–Æ=PÙFöËê(XFÃ--6¼J91päÕ[}ßq{…¡é¾[ÒmtM" …šp‰:“½Y˜÷f$³ç1¥##eéôÚxa€„òÍïèþÒ>LÄ€À« ©Øƒ¸ çNù$ 'Xò+Áy»äû—Ò5»WYà0HÐ…‘ CDèA‡jmòÍ&·±ã?V=wOØú`ûq“ cÔÜãüïâÿç}þ÷½þQÎijzÐyKóÂÒRbãyš¿|«Ð5Ü?x?âØw?ÊÆ­œÞLR© /ªiuXµÅ!(ž¡ö†‡¯h¾fÒ­µÏ/_Á©é‹ÎÚöÖE–)CFRwfAØïnLqWç?ç/œ%ÿœŠüíML˜Éùyå3$K~îeGêåH¨&wQD°ªÔûY™¡ÒøÙéÕÄ×êÆ F]O/{Ô"Š8"HaA1¨HãPª¨ € ìÀ§ƒ$“e©à†æ·¹f‚PVH¤Pèêv!•ª8¢¢D,óWäG–õiÿ˲¶…©ƒÍ5kbàÔN §û.ju=Ž{ÇÒ~Çu¥íÌÚ~¡ö£¼µùÙÿ9%ù3ÇMÖ >uòÄ_ mv%¼dAþû»÷éØ8`:š<ýŸ—1c¼=Ÿ´°åJqÙ#Òu4~m~wÞ~ljšèVB%V€óôù%ˆ±HÕäD26;„cÿ=Žbêtà ±ÍÃÕiFAc›Ú¿-¿1î¿ç",¼Áÿ8ûç뀿˜ÐÚ´¾ZÔî¾½—O"hÒfëë!JHÀUâ䯥X¶”Š4]¢bXÏüãçf¶Šëò³Ìêö^dÑ&¸ŽÒÞàp¤n}krüâpÛ/O²síýŒ¼Xò<ýÿµí½œí(x2;Ž^ïØ÷œæž¥Ø«Ïÿ;õÑ¿•žc˜4°Gl£jŸ¬Î7˜œÙvD8µ0wòê»k'–gʾfŸ)ykÎðhº-¾“ga-æ¤Ï!*U/#ž!iÉŽÔÛˆÏPëáU»Ã`ÖŒpª²ôß-þQÎFþfm3@“˺D»}{QMŒ)èÃ×á‡ùQFFW“Y9y5d×Î]kÜ÷_"ÿÎyfÎDÔ2¼Ás¯^’[ >¶–¤íU’wå4ƒÝ}#˜¤Û„fKÖ<ãÿ8ãù?/åæ¹¡hþMÓ,®¾¡tl5m£úü7) h]n䬯Ž£ICѶ'[àOÊë§—C¸¶v$[Ü7¦쬊ƒý•Nmô¸Ü]ïgJàGqf7¶VÚ…¬¶W‘‰m¦^2!î?ŽfÊ"B‹8 <–šžtÿœoó= }_ò÷R˜6¡¥»Q\Ó8Ø‚"GíÅÀôtz9Æ|«JqŸ'ÜúÇç—oÿ%uÿÍ!ÝG©Ç§é÷A Š=½ê¯Šê*òR®ÊY{®êH æ;‡O‹(ÿ-m¿2¾³ù£ùy.½¨êWS:Á3’²Iqi.¡;Š$bŠt"€s=³Ú³Ç/wŸÔõ½…ØøòÃÅɸ½‡ë}kikco”ÛZB¡!‚XãEª€ùg')&ËÙF"€ ­‘dðùÈ?)êo¦~kyYžÛ_òü°5Ôðm"¤R‚àS¼RlOòö\é}Ÿ×pË—#ËÞò¾Òh8¢3G˜Øû»þ®¼ùéäÏ5~TX~gëz®‹eÃÐÖEÄʉk¨Âš ,I?J>&FSMó¯xŠ|Íù©ÿ9_çÌÝBo!þDZÜÚi²ƒטJ˜¯fŒü,ÑÚÚ/ø±¨v§±Œæ",¹ZMLóဳøæ“~]þKéRtÖu·¿š õ ÂÐ[¹Ü˜•÷-_÷coà5Ùu[O¡öO³øôÕ)ú§öwëûž£˜ïBìUNyൂK›™xU¤–Y*"(«31Ø:œ@D¤",ìƼéggùÝan|,6zÑMªÝ$ÐVˆ½ `*A`¼ªžw̬gÂ>®¯-ÚãÚq‰}FÇNŒ7Aó•t+Ý~VyÛËW[Kå‰íì¼·HáEÊ»1"E_³Çáe§„Ó-”$eų«Ój°ãÂt¹ñž..œÉþw¿ï÷=sÊ“ÞOòv¢º½¹¾ÔcR¶ÓꤦÝH¡ª$j *A#¶cdÏ) z]a`ÓÏŽ7#Ó‹§»`Ïò—rìUØ«“Ît>r‡ÉSE,ZÍ›_[NáD3*±45$° Ìvè2~áâp޾P0l‹Åç~}ü¹Ö4=Y¿0ÿ,Ù­õ´f—RÒãþîí !DØÒ¯íuZ7[ñepË“¤í.ÊÉŠ˜Óm/âã¨ëÓuo9¬4?8ùGS™ü½,Ð\ÛϪ‘I:'2¤ƒP@øj¦£cB0ÿvH"Áaêí(Ã6pO ƒæôï(yb)èii3]Ýò^_È Ks<²4²;nNìíASLÇÉ>#nÿC£|b7g©ï<ØŸæßælEÒþ£§2Ëæ‹ô"Î-›êè~]רý€~Ó{–`ÃÆ|wnvÀÒÆ?\¹yyþ§®Î(Î=Ïäk3ù™ç¸L¿˜:Ò3ÚÃsV—M¶¸ÝËrÜ\LïU_ƒj¸;00œÌ‰$Ù/¨p°v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]м£óçò;Büìò©Ó®xYùžÀ<º±Â­ ¤o”ÜÃ%uí³ Æ)ùõ¤Þë¾I×®¿.¼ûnúv³¦Éõxý~ªzªÜ20!¢phTŠS:ËíXæ}Çô~§Í=°öZïS€yÎ#ýÐÿ}óïfùÑ>^Ǽßå×óš±[È"¿¶ZÕÏÙä “ØÁ×é§¥ÏÇ”)4ªà׉fPTPôVÍnÄðÄô²ú?ürDe˦1?Mýáú³ jšn·¡išÎŒÈúF¡kou`ÑÐ!·š5xø…Ø$tÎmõ4Çv*Â?8üÆ<¥ùUç0úž”ÖzMïÕ^´¥Ì±m÷÷•Ôb¡ù³ù[ièy~[¦ÕòŸBÄ6u]‰Ž±Þ_öÿSǬÁó6~êg¸xgb¬UÒu?ÌÏ=h–žZeÔn®$œ¯! aÊGb7 ažJ~±œÏmjD¤ :s}oØ.É–,RÔJÿy´Gëñ<¼½ïÓï$y?Gò”ôŸ'húz^‘n¶ñVœ¤oµ$¯OÛ‘Ë;û“š7¿x§üå÷çü«ËæòÞqéù»Ík%¥±CûËkq¹¸ÛpH>”g¯&ä>Æ)àß”žIMò¼Z޵©q¹Ô ûIQû¸Ø¿ùE³°ìÝ/ƒ~g›Äö®³ÆË·Ó‡ëgÙ°uŽÅ]Š»v*ìUãZö»¨~Q~zh›²éÍ©h‘|2F‡Û´{£äAÄnd–Äü9~ØÁ!“¡zþÃÏbàêmyþr#ò{ó8F‡æ‹[}FP£ô^¤âÂð;~ÀŽr¢B;úLãß4îê“/7þIþSùû”žhòžŸ{s.í}_U»jøÜÚ˜å?Kâ¶ñ?1ÿÎ~VjNóy{WÕ´)¼a2C{lžYQeûæÅxž}ÿ8Aù©¡>Iü·|\ýwLå¿Ù¤ r½Œv¶ïÊa,€q,GÒT©&¾Ív£(œ¬ uz¬Ã$¬ }1ÿ9Aÿ8Ûwçæåªµ·æž©-í•¿îßRXRX™hEÊþpû@WQwÇÇÄ‚ ó¿ÉßÍÛ=Ùþ„Ö©kç+¥Ô,8 µái£]¨Õþñ;ÆÝ8nÕì³§—~ƒöy>‡Øý®51á–ÓoŸëz¶iãÈÿç$]—ò¾éTÐ=Ýš¸ñ§*}àfë°ø@÷Eíÿ>ðúGþq¿Ê~TÒ(ü™¬i:5¦­}¤ÚO}¨Ám \ÜM,`ÈÒ̫͉$ƒÉ½³º|콃;y?çç7å·’ü©æ ?Vó-‚kòi÷ÐZi1L'»{—·u~nœœÉÀQÜâ™>M×µ»Ky4_.éRjz­Ô¦UXã’f WhâC½rèk†¡æ]Ž“4Àá„x‰zV›ù9ù׿Hþ¹©jèJÛ¤\´RR›|jôÿfkíš]OµÁØ™{¿Ücì}f]äx>?©!Ò$ÖlµýSò÷Îanîm¹¡g> n 59 +)ŒwþfëF¢¨ÙÄÇÇ’×rØêzßå¥&œ^÷Ⱦd·—Kóî};›;„dx˜ïÆTVf‚aº·· ÑÕi¼3c“«ÒxfÇ&Oä5ß~JëÚ^ºï{ùg愎…­"‚áT£-=;¨7hÜw§ÇÌö¿eøñâÖ>ß/Ôì{µ¿/.ýì=ÿ­õ¥Ý­ý¬7¶S%ÅÂ,°OIÅU•†ÄœD¢bhìCßÂb@ll‹% ËKmBÒ{Ø–{;˜Þˆ\UdŽE*ÊÃÀƒL”dbAÃÀHwñf¥ùycå¿Í(<‰æ›Ë‹,\\l.Q€Èã UU,ʱHüz¯€ÏBÒk|l"cŸ_{çßɰǬ²’ NÇÈòýEõ/—¼±¡yVÁtÝÊ;;aBü^Fœ¤sVcîÇ1§3#eô}.ðãÛ"䡯u?LˆO¨ÝÃg#¼!ßû;ÑŸó‹ÚŸšõxÿ=4ãiæ¸]ùkN¸ZzŒ c½tíR–ñÓü¾k´Œ@+Ôêgšfs6K팓ŽìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUá¿ó‘¿ó:Gç>€×ÚrEgù¦ÄF“©n_U¹ ¡ßƒuFÜlX ¾Ðuí_CÕî<ç‹ytÿ0éò›R.‡=EÛÓ’½ÿ‘ú0¦ý é;3´øª;ô/•û[ì—‡z8ôó”GO1åÞ:{¹Mó|ùÂSæ].]gB½Ó``“NƒÓ$ÐrF>­ck0œ¸¥Ì»nÂ×ÇI«ÇšBÄNþâû.Þ{–uMVÖM>ÆÞm!y[&­gp¡#/û¾Ü‘¹ø*ÀýsGòG† ×<½áô<ݽ§ÓdrJ9ö™Å8ýCúùì|¹#µß;ê–:ËhvÚÇ3@‚ñ˸EP¬¦”ëö©Ó¥kÒÝOiN<8‘@ÿ[ƒÙÊéóiF§,fe(Èð zþ‹ç±ªçÑÕÔðRêdeä?h TS¶ù¿óy@îhÕ¥Þ`ѡ״›6SÄÈ+‡ö$]Õ¾þ¾ÙF«N3c1.ñ»NZ-DsG§1Þ:ÇW¬Î þ{.Î?$¿0.>ªRf_,^Ü0’HÜšÅÜöv< =É+]Ðg“¡#sÐ:mN=F8äÆn2päо@ÿœçüϵ´òÝå“/­®k“[ÞjÐFjb³‚NpFà~Ô³*²¯q„MJbÊF€Ýáš4}ËMÛ•¼J²ÐÈ~'#æÄçu¥ÃáãŒ{ƒó¿kë¿5©É—ùÇow!öRc—ºä›Íì~^Ñæ¾jƒû»XÏíJÃáúÚ>Ã1uº‘‡—^ž÷sØ“-v¦8ÿ‡œtG?Ÿ!æ_DÿÎ~PÉ¡ù~ëókÌQ¯ù™Z=#ÕZi~M6û†¸q_õHÙŽq‘&Ï7èB0ˆŒE(>©Õµ]?CÒïu­Zá-t½> n¯.d4H¡… »±ð À—æõ¶¯¨~þqꟙzÌN¾[ÒäHô›9hV8¢'êS¡#y¥§íŸͯdéÜòüãÏä×—ü«¥Z'é:¼íkn÷Ž©co¨Oq+Fä/r²S‘5â”QØfC½´Îãþqãò>éUdòŽ¡MG¥h°Ÿ¤ÅÄŸ§´©¿ç? ™Ï’-AbI¥Åêüœôb¶?óˆ?óŽÄ“þ ëÿkm`ØÞ+mРÎ:ÿÔ›ÿsmcþÊñ[GXÿÎ*ÿÎ?éßï?’mŸ¯ûÓu}u×þb'|VÙE‡ä·å™Ceä=7‘!ÒlÞAQCGxÙ©NÕÅmšZÚZXÀ–¶0Gmk¤pB‹j<¨b…lUñüæGå=Ÿ“®¬=<‘"húÀ¾Š-f™c\ÉVŽî4;b ΣíƒÈ¶MyqÆq1°[°æ–9 DÑ ³ÉúðóG•´0„ôÛQµ†y#¢HËûÅì g›j°øY%âúž“?‹Š3þp@þcyOüoäÍWËhâ+›¨Õ­do²·¸–.G²–P­ìNY Ôøc>ƒîkí /†Pêy{Þiùeÿ9=ùƒùåˆ.|×äYµ”ÒZDÓfk©,dŽs!Œ¸·¸IT3´øvÞƒ= §Aq!óLÚ<˜åR‰;½ÿœ¨ÿœ‘óµcò'’ Ñ¬å¨Šñí%¸q^”¹¼híÍ=ãʳv†TÃnÌÏ“é?`ù–7äÏùÉÌe#óÏ“YØMýõ„wOéŸõ­,DVÆŸëf¯7´Xcôƒ/³ñòw=˜Í/¨ˆý§ññLü¹ÿ8ÍäM$¤ÚÜ×:åÂД•þ­lHéHá<þƒ!©ÏíiíˆùŸÇÁÝiý›Á æLÏÈ}Ÿ­ëZ>…¢ù~ÔYhz}¾k±1ZÄ‘)#»p§Üïš\¹§Ü‰'ÍÞaÁ b G’a•¶¾Ióã$¿óº¡†€"@%e<¹‘¦F |)P>ŒôŸeÁð¡þwÞ^´ ëå^_îBi«éÑjÚmÎ0.#eþËuVú u¹!ÅåÆ'W¤Î)ùsË¿œÿ•mü¡óÌ{}úý"åX-݃j "³[1œd™… žd5AÎuåå±aš…—æü⚓˾gWÖ.5]´ýB%"9 ´O¥2ƒY f¡ìMC棴û*:ci÷÷ûÝ×döÄ´ÆŽðîîó 4[N×tÛm_I¸K­:ñ¶óÆ~SóÜv îÇ8\¸¥ ÈQ¡bË‘‰°Q¹Ç“~~þ_Ÿ8ùIµM>.Zþ„æÛˆ«ÍoJϦäÐsOqAö³sغï/ úe·Ç¡t}» ññqGê†ÿ¡ ù9ç¯ñ¯•"rs×4¾6º~Ô”º˜ÿ®£òƒgOŸ ¼œîÁíÌáõGcúÇï·¡åíó×’|½iùÙ«k^póŒóOamqõM3JŽV‰ ‹ˆq^& q+öH«TœÍÉ/+³ô±í9Ï6bH£ç£þhù×Î:6Ös%Ÿ˜´Óëhró‘  ô«P@~*ìhÓ„ù;ÎØìèê1€ N?Oêy{é>~üںѴ_1hòè>_Y¾»æIau’Y(¡=5>˜©e x1ø‡¶dqGnú<ùÁ©ídÆqÝο³ì÷ìúÊ×ê–ñÆò5ÅÂÇMw" –vxó“€QS×aLÂ%í±Ã„Ì÷÷¢03v*ìUثȿ:5‹ß-]ùÌ.³$Zìz6Þ^¤‹PŽVJÄ›ø-O·53'O+mÞó]¿žXe$'Sh;áøòÝù9©^yªÃZ×5Ýdꎡ9ŠûB#Œr'$XÄN*9/q±ïVàÎ8H3ì²ÏÎsâ2;Ǥ~›)ü¿ò…Ç’4›­ß}sNúåÄúdekki[’ÄÌIäkñA¹9^\œFÝfhNšV,˜ùå€\xÌÍ]£ÚÒãã—Àw–?ÿ8ýù­þwy—þV÷æ´ þÕ´}-ÁHõ‰¾T;‹XÈßýøÝÏÇ]¤ "(>Y®ÖÏQÎgsöyß ªŠ¨Šª`7 ¼UØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±WƒÿÎGÎ8éœÚAÕôŸù…§ÄFŸ¨Æ;È×qktGìÿ¾äê‡üšŒR á½^Ö<½«Oä>[M¦ù‚ÂO«v¥0è’W¹(ãf5îz>ÍíK¨d;ô?­òßjý0½F˜zyʧœ|»ÇN›r›æýód.£ ÅÅ…Ôrú7RÅ"A/ò;) Ûx¯,I‰4iÉÑe†<ЖAÅ Hï¸`ú •‡—<­}/™tÿFQ+ ƒ/ Ó+V/Lô=;WâÍ>—p`‘Ëß>êüy½×kê³v‡hcL¼C‡ÓV8/êâý=…(òµ¦®š—˜õX®G 9·ž[÷ž*ç'*„áËð8º,yã–`ðïFù{üÇ´4°dÒ`”[D~¹r¨×ñrïáåæ'ºN©ªj•âÉkÑ«é÷Ñ¿/X¤ƒQì)Ó7x3Îs6CÞð£Ùú|!S>5‘8\?óAù¿Éðy’< Õ †~Îá«ÐöÊuýž3‹H9¾Í{M>ÏŸ ½X¤wÞcõuzwåŸüæO?.m ò¯æ¶>¿ij¾®¯5l—ýÝÀòVþfcœžlÆjBŸfÐëðjádžBCî÷ŽcâË<íÿ9ïcubö•þW¼“Y¸!¼ÖDJ!b>ÒÚÚÉ1ø"ôÊãMnVIÆ2‘§`ùëAÐu½O[ºó¿îd¾ó-ôpÍpÜäõ¬’•¦Ê£e@/fvaãŸ>ƒ¹òŸk=­Ž¢'O§>â—󼇗»œÏ7ž;H.¼‘sùûù½c嘹ÿƒôrnu‹”¯iRŒ6 3Ò(ý¾.Ç8þÓÕø¹(}1äû—²=‹ù-7‡ï2o/.èü:ù—éí­­µ¬Vq$vѤ6ðF¡R8ãP¨Š£`5¯Pøûþs_óRîUÓ#ü©!—WÖ^ ybaÈBÎ>«hOc#UÁ¥Sö\ä¡"æQ)ˆƒ#È$^Lò½§“¼¹g¡ZÑšåu0ß\>ò>ûîvƒ;m.œb€ˆx-f¤æÈf?̇åßœÞ\Öu+m̺òóËw-tÖJ 4‘³FäªÛ‰‰j£zš®ÔÁ)Î"Ì/ǹÜöF¢2„Í Š¿ŸëL|Ÿù»å¯8jpè–Ñ\ÙêòDò.QsˆUãWV$*ÃáÓ¦[¦í,yeÂ,_edÃ#Dy%¾Mó¶­æ?4ù«X–íbòŽ­*È”/ø¥ÊœQ…ir­.ªY2NWè‹v¯G x±Æ¿y/Å2-~dhz÷–ÿÄ÷ßîOõÚÔ=ü±";¨÷mËâÓ 5Ã20k¡<|gÒ/«‹¨ìùãÉáQ«Ù”Øj6¥²^é—Q^Z=xOo"˧Z26̸LHX69ã” HQT‚æÞê?ZÖTš"HFÁ֠Њ©#l"@òD¢FÅW b®Å]Š¥:•ü·«ÔêšEã7WžÚ'zø†e¨?NS=<'õDƒ~=NH}2#âõŸÈÿËýR'ÖO¦\°n“Ìÿóšú‚úWeŽÝ@$2&‹ 5Ú•··å„öö›¼üгº“ü#æry_þr§U%µÌë‹E'qo¬j·Â((-¢ACóÊ%íÈHü¿[|}—Îy˜ŸêB[ÿÎ8êÚÝüWÿ˜^r»Ö½"¤YdeÚ«õ‹©¨4dÌLÞÒôG?Ôç`öXsžÝÀ~ŸØ÷>ÂÏJ±¶Ótø– 8’ hWì¤q¨UQò9‰ÌÈ™eêñ㈈ØNE›±Wb®Å]Š»v*øî[Òßn¿¯%‚{ÈUº×Ñ™m–›ôâ¹êžÏcáÇêýïŸÎ\ż¸ŸÔɯï­ôÛ9ï®›„!w?.€{“°ÎŽs\™ÌD^Éÿ8 _ ŽF¼`ð¹ ²BøçqÙš¯Ìà£õGð Çä'³µ‚cû¹óý?.cäú)cž$šC"‡ŽE «+ ‚êÂ÷€‚,qŸQQáúbÁ˜¯NìUتÙ$Ž(ÚYX$H ;± ªª*I'`Å€,¥ú?˜t?0,í¢jj jâ)ÞÚA"«‘ÈK±ÛÃ%(‘ͧ«[à•w<Ï?š^güºóf§avmu‹J›D€:ÀÖöœ ±S»·ÅÔÜ œxDâ:<×höÎmyDÔąǧ¿ñ¿“Ñ<³¡\ÜØhúלb³¿ó…¤.Q†%ýÚÎyqV_„6ä»u§SZ'-ÈÞ“LeO0È1æœØè6™¨_ê¶QA¨êl¯p‹G™PTþ;wߩș)ÊÇ¦Ç JQs=éo|ë£yF}[Vz¹ªYÙ¡­Ì´¨D·ó7@>‡3#A£´;C—þ½ˆ~HþIy“þrÌ«ù›ù˜¯oä i)a`9F5M¿¸€uXŠK/W5U5äɵnjDP|·´5ù59 æ}àÐ+{{{Kx­-"H-`EŠ"P‘Ç*ˆ«@€ ›€©Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«Å?ç ç¼½ùÙ¤ ¨Šižy°‰—KÖü2(« k  –ˆ±Ø‰ ªÔrVR àèu2~^ë÷AüÉ´“OÕlXF%œ†*t%Á*ñ°Ý%RE=ºoû;µkÑíÐþ·Î=¨ö;Žóé†ÿÅ×Î>~]zoÎl`MTîÜs£|¬‚ §Ìš ¿˜ôÇÓ§sä$†Uá"‚#¸¡ ŒÆÖiFhp—oد=q–"ö¢;Ábz¾Ÿæ ZâÏÊR³Ç¤ÙÃºŽ¦Ê±¤ê¿ËÇj QT÷ÜôÍ^|Yr„ý z¥Þõ½›¬Ñéa“]YÈŒxîÌo¿®ýOvÚÛÍw¶×R‡tó7“ôˆÌsP y¶õÚ½öÜõÚ×J2ýÜoà¹ýžÅ“üÞ^^sbúF¾Î›ì9o<Ñõk]oO‡R³åèL ÅJš WpFn´ùã–Qä^´»;&4°äçî^ô\°Ã:çeŒõGPË÷¶QbâcË(‰ ùl§oegi_ª[Å/µéF©_Ÿ20Çò6fÕeËõÈËÞIûÑ6‡b¬?óÌIÒ¾¡jÇôŽ£X£ »,ggaNæ¼Wû3UÚº¿ ç/¹ì}Œì_Íê”m^àÇÝ©Û8l’²ì{GQâN‡ ʼÑl÷¾YÖlâ–âÆî$¯Äð2¾g#n. Tâ|Ãÿœu¼†_'ßY.ÓÛ_»ÈŒìû@â#¸§·àFP{ÃØ3r芼‹ÌÿúÑ_•öÖÐî²¹Ìöß÷‘÷~—­öû©{ÿCô‹4®íñ'üç?ü§?•¿ëÝÿÔU®UŸè—¸¹_ï#ï{ѳÌZv*ìUØ«±Wb®Å]Š»XóC"I"£ÈxƬÀ>¸@%€ÆtßÌ#êúüžWÓu»{r>`Û':1Ž¥•%+é¹5Tbv̼š Ї¢D\<}£‚y<8È~> §0Ü×ÂVzΫ¦yËÌ1Xi’êšÅííÌijí'1på¿w³1©è)ž«ÙùüÇ$jq×{×3ΟOv*Ã?4|æ”/4Z(Ô£YÒæm½;¨Áà ì® Fö5í™Ý¬:|¢]:ûi膧 ^cÞòïÈO9O}¦\yY-µ òH#–¢Cj¯À¡zÂÿðGlí5Hr.³= g†T9{¿gê{.c=K±Wb®ÅRÏ0ëúo–4{sWwO´ fhãi[ã`Š 'v`<´O$i‚v  [‰Ú¼|3'O]CÍööc–xpƒPÈEžñcñòznƒå¿-yIžßH4ý59\ÝHò3T¤`4’<„•wí˜ò™‘Ýßé´˜t°"†<Ïëcšo‘-¼Ë¹¬ÙG±˜du»½iLüHä¶ò6èŽ_ ëÞ@™É8ÐåN.ÍÒfœ}~'3Ïäz2ß.èvÞZÑ,´+IfžÚÆ1rÜÈd•€ßv?=€Ø †Ù\åÄmÙitã8ÀD{Òo>þ`èž@ÒÍî¢ÂkùA:r0ÎÞ=ø ý§#osA’ňÌìâöŸjcÒCŠ[žƒ©ýži'äwä™?<õøÿ5?6ã’%TI¥iD´_¤MQ#ZòKaݾԎå³iŠ—ëµÙ5 æwû¼ƒï[;;M>Ò #µ±µ!¶¶…8¢Š5 ˆˆ   2n¾*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]мËó£ò;ÊZèír?ªk–ªß¡õØP‹7mèEG©·£‹Q‚_žúþçÈŸ1Ÿ&þ`Ú3iVÓõ¹I°Ö‚Ki“ù£4eðß³ûLâôËxýÏí/²0Ö^\5¿d½ýÇÏçÞ%V×V÷°Gui*Ío(åˆj¤gS ‰ Ãã¹ðO Ì& d9‚²úÊ FÎkÆÞá rb‡‰ð+¾ ¸ÄâbyzMTôùc’TM‹ÃõýQ´Òì|©å«fK ¶)y|H4[Ô¦ÿ*ÆŸä Õj´óŒ#‡Øó?¯ñäö]Ú˜2ê2kusp}Ü>îƒüãÊÒûKí}n%ò×’â‰l´OÝÜ\N)¥äyזÓ†¥>ü£\¶q`¡Ìž¥Øjtš3êû@ÈÏQ¼cáŽÕòsùKåŸ5Ûë€ØÜC[[ëvÀ!‘Ê7¿¶Õïß6=pËé;Ls3Û¾ÏOGûÈz°Èúe×qbÿ:2LÏy·bªWÚ[Ëupâ8!V’G=TTœŒæ" <ƒf 2Ë1 ”æ›ÿÎ+þ[Mù»ù£?æ6¿n[Ê^U–9-¢qXæ¿_ŠÖ ö"1ûé)û\A|â5zƒ›!‘üè>ÆìÈètÑÅcê=ò<Ïêò§èžc;7À¿ó•^}»üÜüÐÓ¿&¼±qË@Ð''W¸ŒÕPU"áÛ±ÑÖ0?߅dž_¦ÀrÌDuiÔêfg¢c¨êÞZü¹òõ½©èöæp¨d5"‚¡ENÀ³xça<˜ôð°äññdÔä5¼ŽéÆ™ªéºÍšjUÔW–R}‰ápêOpHèGpwv<‘˜¸› 1J¤(£2mnÅ]Š»B_éšn«ÕµK8/­ë_Fæ$™+ãÆ@FBxã!R³†I@ÜIÉyãÈv¾kò§øfÆDÒ¢†Hæ´Ä¢hëD1§Äò=:óW£qðK™¢×9xÏ«½„y÷ɾs¹ò‰祭êZÒÍwefŒ©ql€ÇUâ 0Jrø?hÓ¦øÍ.S† úŒO!Üì4:¼#<ˆô‰ ‰èR«ÝJÌï8ùPù{A»ÒãЧYµ+ë˜>ŠFñ¿¤ P„ $OA¾U<‡S–#„î[áŒipä㘗؇?§|Ùç>ù‹L×î4]/D…âõíÉ+'Õ…âÐgfïï‘õåË–bF"?£ûz0âÅ @HËôÿkZgæoæv™ä«5^Ae}¢Gpmd¸º./.¾"*8P…yPšŠqǯÏBfˆºß™NNÍÓK1Æ «Û{å…Ø¿±µ¾T1­Ô1Ì#o´¢DCî+%Äïy™Ç†Dw ¼Ëæ?ʺ%Þ¹©µ-­R¡ø¥ì‘§»¿³+Ïš8 dz6iôòË1ó/ ò.‰©~cyšÌ/5v1KK R?vïøAÿuÅÿ Ýk8mfªY$Iæ^§S8éñŒPç×ñÞ^ݘ.•Ø«Åÿ-¦KüÜÖ|¤ÌÇRæ–ëØ2¯Ö­ëò™~g:ÄÏY+ùÃíÓ´áãic“¬°ý¯¡s¬yWb¯"ó?þ´WåGýµ´û¬®s=·ýä}ߥë}Ÿþê^ÿÐý"Í+»|Iÿ9Ïÿ)Ïåoú÷õk•gú%î.F—ûÈûÇÞôlóÖŠ¼ËÍŸŸBò–©.4—Zž£nJ]E¦D“]kÉä’5ä´ø‚“N‡|Ûi»6Xñ ˆ=î›UÛ˜0˄܈þoà2Ï&yËGóÞˆšöˆ'[&wˆ­Ì&”ä;« ú£Úµ0µzIàŸªüœý²ˆqÂëÍæ3”’ëoò¯—§ŽÛ]Ö¬´ë™@1ÃusNTíË‹°4÷é—âÒäÈ.1$y6¯3S‰ó/)üÀüñTüÁÒ´]>O¯è±¢nÒÚÙžèÉ:s„A$…ù+ÆëÀÐøï›cø¸%#´¿„ÞÞwöºMmø:ˆÄoâo¿*ûÏ6~nÝé¶~\³òæ…5ß›|мìt‹ïôg¶PxÖà)½h9@I`øúnË33‡27¿s‘ªíc<œ¢v¯z@üÅóï˜çüµüÀÓ"Ð|˪YO&‘¨i²HÖ)aY%¡«ûKJe¹ô£ŒfÅ.(Äîà5àí ÒÈpfä=$~ Æôß+^yÛòûÍ^i×5]BóÏ^R™–¸¸i°<•åW©&c^[ÍæMHÞŒ@†AÝ×—êyüzSŸO“$äNLg¿þ´ïRѬ­¼‡ùgùä½#ýËi÷0C©%Œ%§»š&>£ÊbdÅOg§Jf><¤æÍ‡$¶#kéøìr2aˆÁƒ>(îºæ}ÿö¾ªFŠâ 0Mû†¡#œy{`^¦ù~@ÎJÇæÛôh¼›æ•–=BeR@‚õ‘®S©ŠåVf~?<ï{R2`¬vý_cç}¿¤8µô–ãôý¯Ð­7RÓµ‹ }SI»†ûM»A-­Ý´‹,2ÆÝ lÛº$K2¢³»E³@Ü’N*ñ¿ÌïùÉïÊËK9Ö]bwÌA¢i2¥ÌÆ@6Y¥Œ´pŠ‘^g•7 Ý1H”,l|Ñù¥ù“©þzyÒ/Cëÿ¢`âV2Z/« ˆ6æ(aø¿i·­AÎg·õñð¢w<üž³ÙÎΑŸ!°åçæ÷ìä^ÕØ«±WÍš ÷åïôÏÍ.ÇK{™•58WdúÏ5:,ñÔ¾Ð'©×ö¬eÆp˘åîý#Úø¥¤ÔGS¿üx=§EÕìuý&ÏZÓdõlobY¡nôaº°ìÊvaØí™r‰‹ÚéóÇ,ãÊA¹Ø«óÏæ/—¼…o ê¬óßÜ×êº}° <€mÊ„€«]¹¢¹fŒ~‰{”ÎiÄÇŒãâó}ʱþkþTi’Ïõ/3ùqå±¶º`O£-± "~& 4b*‘¸ éC‘)øs=ÅÑiôC_¢€&§ŽÀ=ÕÓåKŸÊŸŸ`±o*ëÚµ¶‡"ˆ/5(óÏF_CµG^\9~ÑÜàãÄ ºN‹´²ÇÂÉ0#Èž¤}ÿuõzç•ü¹aå=ËËúh?U²N!ÛíÈìKÿœsÕdÔ-¹ëß—2¤ªBÇÌÑcºU¯£/`ÿaûoð®n]<mÇs£íÏg°v„=^™ŽRþ=ãËä³C×ôß0Z‹>^DSÕ…¶’2{2ÿ™ÖéµP͉|Wµ{>‡'Qî=¸þ ^b—Y‡IšmRMA(Â7Rå“ö‚ ‹¸® \² dãæžÅÇ¥ž¢1Ô’ zƒ[ô¿'—Ï®ˆ¯$Ô¼±sqi®jlûIú¸‘}rO"¬õý¢HøIß¶s²ÔÔ¸±'.q®¯©aìž,C²ž"á—Š½=,*½ÀÛ¯6DÖ7~PòÕÓØJ’ùªà-ÅóÕd™c­\ª’»šw'3Ž9i°žyç¿ðpjñö®º(1ÓGÓb$ô³ÐË»Üo&ê:ýêr¿–=GK–!$’pÖN Æ(j w§ëÛ+³òå—Ôx¢FÒýê}¦ÑhðšÆ,€Ô±›"ºLK–ý×ðÛynlÞEƒyÂ]W̚ƙùy娚ëYÕç† }Yå`"ŒžÂ¿“Ðzg?ÛZºýØøþ§Òý‚ì['U1°Ú¦_ |{Ÿ¥_”ÿ—:_åWôŸ%é|\ÙGÎúì/uy/Å<íßâm–½íœëéå‹ÿÎFþnÅù?ùo{¬ZÈ¿â}K–ŸåèO~µ"šÎTÖ« ÕÎÔ-ÅOÚÅ >@üòtÚF‹/šu`Ï®kß½õ%«J¶Ìy­Y·¬§÷Œk¿ÃÜgSÙNqžrûžG¶õž$ø(ýÿ±–þbëšg—¼¡¨ßê¶ñ^BSцÊáHçžM£FV¨"¿{s3[–8ñ!~Ngá–L±5çÜ9äÿ$jYÐô_7Ëæ¯ðÅî«s’ÚãŠÛKm!äŠÀü<Ìaœswáëšm6’Xáœ|GáN÷W­ŽYˇÆ">7ý¯¢úî:gHò­â®Å]Š»v*ìUØ«Ÿòó@O/k]ÑÑô»}m‹ÝÍ4¯Í¸†#Ö-± B½74Ì3¢‡¡¸œèëòx‘œ½\<˜Çš¿+õ CÊÞXòv‘<'GÒ®#}Qå-“(Ù¤T0©ç#[îcj4–8c‰Ú'ÇÍËÓv”c–y$=R~>OSUUPªª€€ØfÕÓ>yÿœƒ×–ã^Ñü±,Ï—n‰y}éG”Îc‰"¬‘©+þ¶s}·˜™‚Þ§°pT%’·;§ù[Pòåîm–."›M¶"Ž8Ũ ¦Œ­ãÈW9y{¸zˆLHñÊw¡Böò×N´šúöU†ÒÝY¥c@¨¢¤â(ÄÈÐæùfûVÖ®|Ã'æl²¦˜š´kËlž´cÖŽ ×v än½Fgá‘ÆAª:aáxgºŸcÅ"MMåŠа¨9ÞƒoŸF—áCȼÏÿ­ùQÿmmþë+œÏmÿywézßgÿº—¿ô?H³JîßÎsÿÊsù[þ½ßýEZåYþ‰{‹‘¥þò>ñ÷½<Áõ¤¹%äZ&¥.œ ÔÖá­Ü™„Lc§û*e˜@3ÊÃVrD%ÃΫ߿ɒþvÜ]iÿ•ú¥ß–odÓæÓ¦·,úlÍ k•ŠHÉ€‚?¼«/ߘ‘-DDÅØ<ýÞngmHÇM#Œ× ¶ëäóÏÌO1CyÏŠ±|2çðùw§þyƒÌ˜¿–>RüÁÑôV_3Ù]­ì¶6q3HÑ#´BH—yŠ'UÜ…=M+˜ú3O¨É†Rô‘VeÉ×G&§M4cëè~<‡Á7Ö|»çÌø4?é|žLó¶q$Vvz¯".mø¤˜úa”rgP­û×(ÅŸ”ˉ ÌzÇ›~m>mXŽh $Â]GËßÑ4ò§åÇœ¯<ñææN£isªØBÖúVŸ§+z«+©f.«Ð;>#S^[S*Ôëñ >@'r[ô½šYÆlò@LËBü½òß—µ0j6QHòùšG—U†w ógb¢:÷ã×0sk²dŒþNÃgãÇ)È?ÇÅiÚf¤ZGa¥ZCcc};kh’(–»š*7Ìl™%3r6\¬xãQ$VA›ó’ô=hï£y‚ßÕ€žpL‡ŒÖòR‚Hž†‡ð=#2tº¹à—íqušA@ð/ÖíôÞÏéñ› Èùòù~»zÂ"F‹jUQ@Øi‰w`.Å.Å]Š¥iòæŸæß/ßùwSZÙßÄbfþÒHµý¤`}Æ_¦Ï,S0ãê´ñÍŒÂ\‹ç¿É}sPò‡™uOÊ2· ˆ&•ôÒÄñõTrtBfT¤±ý=Û;¹Ê9`2G‘t>Îꥃ,´¹;ý?>cö½ó1žÍØ«ÂÕ­üä]Ìžiâ±Így~Yè#Gh£P¶Â¤LŸë“™•x¶ø¼‡cÚ§Åê=îñï‹Ó<õçÍ#È:dZ–¨¯;O(† H zÒ ,¡ÈÙ@Üü³33Aßö—icÒ@J[ÙªÒ_ËíZÑ|Çæ©å³ko.kS[ꚨñòK‹ˆùÜÆcRH!˜/J|;dòÈ;ÉÙzl˜²å$T&D‡¼óøäô<¡Ý¼{óóŠKkåòwåäGXómÔ‚Õd¶ŒÜ,39â#‰VZö¡PzÔÕs+š÷<žW¶}£Ž+LJyu=ë?cÙ¿çç£òõÌ?˜›¡u;ÊßYµÒ§qqŒ¸–v$‰§º¢v«Ë°Ÿ>É–S$“d¾¯ÂÖìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±T=õ–§g>©[Ey§Ý#Cskp‹,RÆâŒŽŽ`GPF*øƒó»þqWòÅÜþzüŽõd·BÒÝù\1yá^¬lË{Œ/VþRÛ(³ic—MY£Å©Æq刔Oãà^#å¯=Úê’~ŒÕÓô~µÞ)DwSB-Õ«±Fú3¨Ðö¬rúe´¾Âù´ÇeÑÞLW<ì£ïïcãL¨ZZ‰ÍЂ1tE ÜÔ§‡*W6žnëw‘:Œ†G‡ºÍ|’m{Êðë3Eos&Ÿ«@¥#¼‡rP×áu¨ä7=óU¢H<2C¹ìŽß–’2Å( ¸¥¹„»ûÁèU¼³åø|µ¦~Šfœ´,²°ãÉØÙjh(£jäôzQ‚ ÛOnöÌ»C?‹(ðí@sÛ~½y¢5Í^ K¸Ô®7X—àNï!ÙT|ÎOSœb‘èãöOgOY¨ŽÿßÈu/`ÿœ%ü¦žöâûóÃÌ𗺺yí|¶$Z}¢cº»_Æý¹ûg“!œŒ2ý §ÓÃ8〨ÄP}ªÌ¨¬îÁQA,ÄÐ7$“m~j~hyþÇþr óÞg¾Ž?"hlöš4RHná…ë# b*÷2ÓL/u̽äÊŽßœNÐÏ,XL¢,ýÞofUUPªª€€ØgjðLϾ@¼ó¾± ½Åê/–ôùL·úqV1ëPÀjJ8‚ÄéšýfŒæ”lúG0ìô:á‚¡ê<‹ó>—qù•ùŸ•¦Y­<±å˜·%ˆÈòSxÉ´x¢štV#0õΣQÁÊ0s´Ù—Mâ 3™L//4¯ËuŸË¾Uó%ŒzíÕâ]O˜çžX¡…â© 7ǹsÐå’”t÷LqüVÕKSSÉÂz+ô²/$þbGæ=dkqçßùuøê’Å(’ÌÆC‘4rÙ>›w?=ó'K­ñ¸¶1çÜâë4 ‘>]þækmsmywVs%Å´£”SDë$nt>õ•â›þ rq'ÙøeÒ‘z?üâ÷üä7æmì~bÜÃå-¬¦I&·šBƒzÅkdì‡Aë:ÓõÊ0·›?¤n›ÿÎ`ù_Ê¿––—ÿ•žSƒÓ‡ë÷wüZupð°¼ó2Ó“ÈÓõãÚ‹@´É9²->ÜÙØZÚ1«A QâQÿ ï¡>q’W"{Ê'$Áä^gÿÖŠü¨ÿ¶¶ƒÿu•Îg¶ÿ¼»ô½o³ÿÝKßú¤Y¥woˆç5¥üÚü¬µ“â·[Ó R²j+}áFcêÏî¥î?s•¢½‡õ‡Þôœó7Öм^ü„´ŸZº×¼™æ;ï(Þß×qØ—11fäÜDrBÊ ß"µèLÝáí¢ !’ ¯ð]~Âfx¦q“ο´'žOüòß•´=[Eºš}gôò•Õç»rÀƒöOÀjKr©zïËaL}WjäË8ÈTxyWãö9:NÈdž‰&\Uþ?jKÿœü°Ó#dm2KÖ2¤ë-ÍÔÞ¢4|¸…0´Äj;íZÐdòvÞ¢_Å^àÃ`é¡ü7ï'ôS4Ô<¡åMZøjz¦‡§Þê* »›8&–‹ö~7Rv¦Þ³¬° d@÷—c“IŠrâ”=äåUQB ŠU€Ð”7€Þ)v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb¯ž?ç%|¹žúGæ&•u–¿g4PH¼Ñ%˜#s†XÔY¢mš€ü$v\éýžÔ’N",s÷kÊûEƒ€ÇM­ÐfÒä8òÄÆ_Ž]ÿfZâ1='ËŸçg掓ùo¢»&›¦MRñ7X ‹{™Ïj¢ü׫š~Ör¯«ñ'À9Gï}—ØžÅü¶cדìOŸ?“õ CÑtÏ.hö‹n¶šN™V–VÉöc†‚§s°ÜÏ|Ô=ª?|ùùÃÿ8ùyù˜n5•¼ß') ý”cê·2ësl ©$õxø·s˦)ò¾»kùßÿ8÷r–|ÓZòˆJÛW‰Ú{vPh=;°9!?³ƒàß6z^ÕÉcê«WØø²ïL¾Ï“;òæ/•|éMØKêVM>â‘\®Õ4ZÀx¡#:-6·o¤ïÝÕæ5]Ÿ—Ô6ïèʨ+Znv'å™nË|Áùo«Ã®ë^gòÓX_I«ÀÂãJÕíáLÊ»zNÌ Tö¶ê6¬Ú Êp£ÅÒBÝÎЄqÎÇ ç_7Ÿjš§å i¾JX‚y»Î·Êׂ>cuTˆ”¨Nž,3]“±aÿ!ÝÚcÍÙå—ø1 ¿_ãÉ5òo懕<·åJñçh¢}n9&/@„³‚›(5cÇ·ÂFùoƒàê! dù´øþ6›$òDGÞÉ¡ü潺յ켯u} é×BÎâòÖQ%Ò–s¿Õ‚T†#a_¦»fPíBdjıÏäážÈ"戺<¾oKΕúE4ƒyê²Ä.#±w ;Dj9ÚO„×m³gâÇ‹†÷îu ¸x«nWÑ–5»v*ìUØ«±Vù‘ùyeçí)a.-µ‹NM§ÞU©Ê9Ü£PtÜÇÁ×h†x÷ÉØv~¼éå|ây…!ÎRþiþL-¿•?5ti|Å AHlµ#'Ô‰{%É À¢ÉGÞ”ÊgÓO© {->§ap6ú_Êó•ÿ‘žo8y–=ñéÊÏ\C`É_æ™É·ÿ”å ôžy›þrò[ÊškêWÞtÒï¯(ít»¸u™j*¡"´iÅ]™¨¾ôÅiñÿ™uŸùÉÍÿñî£hö~Lн8tË9 ‘ÀÆH¢$|-#»z³R´ iÇ6}™¤92 ¦.¯µµƒ3}Rü[Ùs­x§b¯"ó?þ´WåGýµ´û¬®s=·ýä}ߥë}Ÿþê^ÿÐý"Í+»|?ÿ9¡ÿ“‹ò·þyÝF<ÇÕÿu?ꟹËÐÿ}ë½éyæo«»v*ìUØ«±Wb®Å]Š»v*ìUØ«Ö<ÍåhÞ ÷XŠ Íi¤°³HeýóÊÀ#)Ë‹csБ™8´ù7ŽÑܸ¹µ8¶•lOå]}ü§ yÓÈL3ù—ÊK5õ»ëe7Kê~üà ,(@1ü_8$nFnu8ÙµÓv¾Hm/Pû~n£Uظ²oIû>LÓÊŸšNó´ûáo¨7ý+ï) õðZ’¯þÁŽo´úüYyû‹Îj»76bÇxeòC ¥ ±«˜Øiœ†‡MéÉÈ3i´ðãg®Ö™þ]ùâ?'ùkÍ—Wͨù_I¾Ko.óaÎc#JjÄP«µÃR@í–èµ~9“¼b}-:ý“Fr/³ö²+?ÍÍO¸Óeó·–[HÐõvU³Ô£—˜Bû¯¨¤m±©¯Mès"=¥8‘âC†2êâϲ±ÈKŸ£Ì=ëÍ>^±ÕB^ê0ÛêžÖ} [‡î~"[“Qv Iß6RÔB2á'wU6IGˆD‘t£«ùÇËzVú%¾©'£c,Jó¬®EGm½ú`É©„$óäË“&BDFñçÓïOr÷ u=9o?Gµäþ€ýTÊžµ¡á^[öÛ!âFê÷gáÊ®"²l®m­¯ {kÈRâÚAI!•чVˆ"‹(ÈÄØ4X­ù-ù{«9—ôi±™·/e+¿Dcè\×äì¼2é^çe‹¶5þ+÷þ-cùä 9ÄÓ%Ýò‚XCsp8u¨ÑXÉçóÊáØøAê~-“íÌò({‡ëz=…–™i†o­”#ŒPBG]‚í×6p€ˆ (:©ÎS7#e’`ìUäú¢¬ÿó“¿–J9D—Z4ª¾º”¬Þê¹ËöÙýèþ¯é/]Ø÷2þ·èÑÜÓ»§Ãÿóšù8¿+ç—ýÔcÌ}_÷Sþ©ûœ½÷Ðþ°ûÞ—žfú»±Wb®Å]Š»i™UK1@©'`îqT¶½¡ÞÝ =NÒâùjZÚ˜¤”¹ª+Ûå–Ë â,ÄîjŽxHÐ'Þ­©ÞþŽÓo5Eî>©·„tç'¤…ø-h*iA\Ž8qHVYdŸ L¹Ðxdž˜~bÒ¯|Åäß$Ç'—tßTÞ^]]‰PHôE1… •^yÐÇÁŽB2z ö¼Ðí½FXâÅé2Oö~”žïóãUó‡å¿æ™ Þèrö†lº\¢_\MþoâØWšmÿ+4&ùcYò Û¿žá–Úæä¬³I00Æe™ç‰ÉHøH¢œÿd7Ìí4µ3Ë8å»Ü~ªø:íTt°ÃŽXOï6=~6:Q{ zµ­þbù?ógÊ6É&“®iñ1©•FÆÜƒÌÁY@Uâ‹|ÒІ š|‡xŸOãñÍߌɨǨÆ6œ}_Ç&Uä¯Ê?Ê6¾eÒžìßùÌSJãIx½8­ ”:ƒ%‰F [áû#0õ}¥,ƪ”>÷7GÙqÂ'¸Ìòî ×JÒtÍ O‡JÑíc²Ó­ÁÛ@¡91f É$“Üï˜rÊr2‘²]Ž,QÇŠæO8ycÊ¿[ó©Ÿ‘$jË ︖®ÿìTåº}.LÆ¡Zµ¼XEÎ@~;ž/©~}yŸÎZŸøgòwËwZž¥-U.¤·iæ´æ–ñÕUG^rµ?™FtzOgzå?úÞ_[í?LCâWãÜÎ|•ÿ8iç;_Eæ_ÏŸ1Mêº%œÉquƵàóüPBµ¤*õþe9ÑáÓèËj5Y2ÊæL‹ë$~]y'òãLG’´[m"Ðê´)Yç+ѦËI!÷v9sŽÆ¿>*m?8?.u,«­D>» Üµ£ ŸL=@LOþKW¨¤Æ‘nºšÎïòÿ_ ½åæx¢†m¥ô#sÄÀïÊøHð íšýV:7Þú²ý¥âcðdw/êþϹë:ž«¦è¶Rj:µÔVv0ŠÉ<΀©êO`79Š"NÁéóf†8™L€{ŵ/Í/9~cëCÉ_’ÚMÍíìõVÔR/Þð¨S"‡¢A®òÌE+û'3qizÉâ{SÚƒ+Ž ‡óºü;¿Ÿ@~KÎh>Už?5þiËš|ÜÍë­‹—N¶”ž\ŸÕ®$ñ2ä›3@xÙÌÈÙæúUUB¨@ `ì1`Þ*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wœy÷ò#ò¿ó#V±×¼Ñ¡E6µa<‹ès-Ê@á„¶<Ý~§²ðåÞ¸OxüR—–¿?<§«·Öã“D½;-f·-Ò‚Dì|Ý`íŒsÚ^“ö:Oaå†ñõµèW²/˜4 ÄÐ5K^[Ë®¡ ãG‘ ‡6Þ•¯\ØÈø<'˜æêà<<ƒŒ& ~NyjßÊvz™m!Ôo –k‰.âi"oRV§ÀèQéÁPvÛ0°öf1ŒFbËŸŸµ²¦p4;‘þjü²Ñõ%(è±Ç¥Å‹sbTE¸@Ed&¬Üƒf$žûôË5χ»šô½£8fñ%ê½¹†_ù3óKÏ¥h^t¾]Ó&I®.mœ´·~šð­7ÄT° Èšt…=.£7 rPˆû>Í6)â³)wôü|Tt/.i¿˜ß™þoÕuûcu¤én–6öîÒF¥×÷JßRE"f§ù@äpàŽ£Q9HX~>L³ê%¦ÓcŒ oøù¤Þgò&qù©¤yGË7iɬwSÏͧlc(¬A¯ãêÛ–Êsé"uÇ[_¹ÈÓkd4²É½{ïûKß´{;» .ÖÊþñµ ØcTžõÔ#Lã«•_ çAŠ&1›=ï1–bR$ Ïœ5ûß$ëšÞe=]Ko¤B £@²±[‹oNþé\þÄTŠœæóKõñNܾOY‚±éaá <ϸïú•|¹æ=JÇÉŽÆþæëÊöb;mêå™eCs9…Bˆ%3(¥:ÐW òŽ,´Iˆåñc¨ÓÆY±XgyW{åö©ecåO-iZ®¦‡\¿²Žî(.®¹g&PT9äÔ‚‡¶ntyqÂ2>¢/~n‹_ŒË,åúA­†Û3E’7fTpÌ›8§ßÃ3m×Òì(c>jó¥”î´{[ËK›–Ön~« ÛFcj¨«Ô޼…n@>‹¨Õ F ‚x9z]³ @á»&̧Ø«Ê/¿õ¨¿,¿ã>‘ÿuó—í¿ïGõIzþÀþàÿXýÁú9šwrøþsCÿ'åoüòÿºŒy«þêÕ?s—¡þúÖ{ÒóÌßWv*ìUØ«Î;<׿/&y+ôç–¤Ž+Ä»†)žX–`!•]Ml>ÐæÓ²4ØófáŸ*u=µªÉƒ9ÛÎFXè1ùÊ1iÚ½¯Õ’ý´¨í¢ ö잨 >­$)Ü Ø¶lä%? ÀÄÝ]õù—X”cÅŒ…]WOcÿš¾iÿ•“ù9£yÊý ›-Kêš­š3ÑÚ6 Þ´$DÊ@Ýs'³tß–ÕKäc`þ>./jj¿5£ŽQ±¢?)6£ùgšü¥¬y.ËPòæ§^Ç.¯®Þ ™â£«„EV˜“Ee4ãZî´ÌÁ AÅ’9™#hŠýŽ É¦qË0ŒOªFÏë}oqm}kÕ´‰=¥Ìk,2¡ ’G"òVR6 ƒQœD¢bhó ‚ùKÉ>G×õ?5ùÇòÂËÌ÷‡cq<ÓÙÛÇͯ i¨t ý0Õ$zga«ÖB8±ç0‘û?¾Þ#E¢É<¹0 †íÞ9}ÔôÍoËòzËË,¾_¹†úÝ·’êg–CÌJV>¯-‡ìŠt­ìÞÑ”õ\S?X¯//¹Úö§fFNcè7çç÷»Ì¾Nóç˜u)~iy/Ó°óZéÐêÙ_©€†hÏ.I"ïý㣦ÁHötú¬8ã“Má{N>YcÔbÚ|;ƒ³ ü¼ü¨Õ<¯®j¾g󴚦¡æ$]fÁ-•m^y¤õ]ƒ*¢¬ pãA®í(å„aðˆîåveKå’râ3¡[_ãÉ‚j~IóÖ£w­ù{ÊÞBÒ<µ¦j2ÜY¿˜]£õNžÒ8ªÈåy¨ø„h~Cc›zÌ1œòÊdQáóu¹tYäe xclqGñÜ÷)è6ÞLò¦› ý`<]ºÇ-Ô‡€fiÔü ±&•Øg?©Ìsd3¯¨½&—ÁŠ0¿¤0ï5~}þ]y`±n R“àñF¹f<²¸škËŠHómSÍž•Ž-ÿ4<Ÿ;Ù#p:‘‹ÓiðÝÛ -œû.mpöÖHýC‹ìuû·1ûB} þxyZãÅÔšMËPzwÉÁ+Þ’¡dýb3k‡µ°Ï™á÷º|ýž‡òz¥õ–¡¹°¹ŠêݾÌÐH²¡ù23a‰ Ý\àbhŠ*ô’ç©îi’bÃ|Åùk¢ùƒ^¶ó0º¼Óu˜8+ÜXM虣M¸¾Äôøj¤m˜Yô0É1; ù; ?hÏ (J'½™æk¯y§åÏåíÞŠºüþn¶´»½Õï=r1ž¿¼QûR7QšÍˆÃˆä™{·í xŸÆHäç”ËÈ–úFf#Žîþh-£ ¢«ÈIÌ'\¯µ…aˆæ[;\Y̤y©¹w¦y{ó£ËCZlô­#IŽÞ åÚ*ˆgE$ÒƒâjWmÆQ–QǪ‡¡þ·' %“G>fRý!å¿0Êo?4¼ÿ¤ŸVHTG¦ÌV¿ I(âª#Ðåx3o›,~ šŒ°a—Å,:~­§þ[·æ·¯—Z½øf·MÂC$¾›B>"Þª‚^½¼Úʸ%(Èlùþ7nñ!-G‚qåöû™]÷˜üÇosùOc§:ɪÅm6¬L…šéf6îD¡ªNÜ…}ÎeÏ<ÁÂ/ê«óäáCOŒAᛯ.|ãZüÊóš<é¥hzìvZ,’÷¥ç™¾®ìUØ«±WŸ~wéÿ¤¿+<Çh`ŽéOqõiÒb{öS›.ÈŸ¦ξaÕvÖ>-,Ç•ü¼³Aü÷µ‡È:W“ü½¤_krNNŽ¡xãô¾Îô_Ñ­ü½¡éº«´–úm´6‘ÈÿiÄ(‘÷4®s¹òœ“2=M½6ŸÅÀrˆ¤º×Èþ]³óuïž ·qæ+ø– çõ\'¦¨‰A!w­jã-–³!Ä1é QÑcŽS”QdyŠå¨ÝÞZX@×W×Û[&ï4α¢vbÉF&F€²ÆSMœy‹óóòÓËáÑ5C«]/û£LO^¿)IX¿áóiƒ±u?‡„yíû]N£·tØÿ‹ˆÿG·—ÚÁ¡üèüÓü¹m?òŸÉ7*[Ó7† oZ=«ÉÙAüôf¹Óû9¼äO»oÇØèu>ÔLíŽ {÷ü}¬³HÿœHüñüÈ™/7<Øš6žä;é±ÉõéÔõ ··1Ú'‡%vùm›Ìä’Ûþr ;“aæï-Ýé—±3,f®§ÞÄL¿*œØãíÈÿ~N·/³Òþ ïf:_çåæ«@šÂZJzÇxoO›¸á÷6gcí<2þ*÷ºì½“¨‡ðß»v_c©éºœ~¶›yä]}KyRUûБ™Ér ¸Ç(í B/&Á.Ôô Zh›XÓmoÚXZææ)Üñ. +Mò¼˜a?¨Û<áôÈ‹î)6§£Xùk@ÖçòÆÝåê;ͦÇ@·r8*y«F%•w#a¾Q“Ç FÉéÞäcÍ,¹"':¯sçíCÊÐëÂ=3Ë>EÕt­zêUÞ4æÎÕ+ñ…iPVŸôùÏON'´1Ê2=üƒÓãÔœ~©åŒ¢;ªËÞçü½Ónu?-jòÜÌ·^Z‚;{hÓ‡¥ E W ¥»vlèŠ&P•ïšùÎ4*en‘ù}k¤j^hÔÒúI¦ó9s*º(ü̆‹ÇíSÔ¦þ1èÄe3ZåיƯ£íäò/”"òF€šWFñVY&õÚ1&B 8‚Ý)ã“Òi¼pݵëug<øê˜m÷þµå—ügÒ?î£>h{oûÑý_Ò^“°?¸?Ö?p~ŽfܾÿœÐÿÉÅù[ÿ<¿î£cêÿºŸõOÜå辇õ‡Þô¼ó7ÕÝŠ»v*§<]C%µÌi5¼ÊÑË ŠQ••ª#¨8A ØD¢£Ée­•Œ~••¼VÑ$1¬k÷(¾LË™´F;JùI&§ç)輿Kk–L½R{¸czÒ´ ÍR}€ËñérÏé‰?.¯>©ñ #Vÿœ…ü®Òõ9uV Åem+ôðyDh~†Í†.ÃÔËøkÞ]v^ßÒÃø¸½Á†Oÿ93w«Üþò?“îõ;ÇþìHÌòõ ÿGµI ÿƒÍŽ/fñÏä?s«ÍíHþ|Ïèý©­—?ç0¿0ÿÞ- ùSN—f’ê(t€ø­á{¡óEͦÂÓØâ÷—SŸÚLùpþÖW£Î ùŸ^¸ŽÿóOÏïu(ÞK}]Dò‘$ù—·ù;þq;ò7ɦ9£òâëwñÓý/\ß§s·¯}¡Ë­ì¶–––ñÙØÁµ¤#ŒPB‹h½hª >X¡[v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»JµÏ,yoÌÖÿTó&e¬ZСk ÒzÑfV«ÈüÉÿ8‰ù æ3$ƒËgHº“¬úUÔöÜÕ„³@?ä^)·”k_óïÿ/ú‚(yÛPÓeJ˜Æ¡k ãW°õ-Úԯωùa”›æÄîÿç?ç$ü¸9ykÎvz­º GßÝ#õíÜMìó"ܱå"âäÐàŸ8’CuåùËÿ-÷!åOÒѦááK+Î`ÛO˜6ôé@s*¯˜s ü?S‰>ÅÓË#ãúí&¹üÊüÞÐ+þ)ü·¾¶á»³ØêKABH3G §\ÉnO¬GãæâÏÙøR?êBÃÿ9§£˜µ//\ÛJ§Œˆ— #)îtŒÔeñíÈõ‰ù´KÙét˜ù&ÎDù&Aûë=J¥Ma–¾¬Õü2ÑÛX»ãâÑ.ÀÌ9ý¿©0‹óçòîCGº¹‹jÕíd;ø|²ÁÚø;Ïɨö& t4\ߖ޵ma£?ÊÖw„ÿÂÄFLv®ç}‡õ0=©þoÚ?[Ҽѡy·þrSòÛQòýß×,¢¼Òmä—Ò–*J·Ò9^3*ަ´¦h»SQ ¹‰±_¤½di§‡ŒÅýúgš×døOþsŸPM#ó3òïU‘ ‘ØÛ›§H Ë òÈTÜÓ*Í8÷‚ôù8'wXŸý o—¿ê^¼ÿ‘Ðç+þ†çüðö_è§ó؆oùË€ b‹zŽ™¤i:-°³Ñ¬-ôëAÒÞÒàŒvû…¡Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*”ëáŸKþv?¨zéaèpã_ø»jWyαÿB¿êÓÿà/W›Wëß ùzŸµýöõñÅ;±{þpºì,¾BZG¥©ipõñô¦\Wtº"ÎÜIêIuäàÔ‘ùŽ—oòc¼Qøb»¦~Tò?üâ ™t«Ï(]ya¼ÓÔ2i g游7jÀÄ"ˆ]¿6åÑxšâ»¾‚Å ~¡úš~•ú¯©CéýkÒ寻ñõ;b¨?ùÓ¿íYÿNتs£èÇõ~?Wâ¾—§N)ðñ¦Ô§Jb«ñWb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb¯ÿÙ»DÐÉêyùºÎŒ‚ªK© àÉêyùºÎŒ‚ªK© Jhttp://www.synthesis.ch/yXô;H¯,‚]Ä…'c¥«ÕDÐÉêyùºÎŒ‚ªK© àÉêyùºÎŒ‚ªK© dhttp://sourceforge.net/projects/expatyXô;H¯,‚]Ä…'c¥«ëDÐÉêyùºÎŒ‚ªK© àÉêyùºÎŒ‚ªK© zhttp://sourceforge.net/projects/syncml-ctoolkit/yXô;H¯,‚]Ä…'c¥«³DÐÉêyùºÎŒ‚ªK© àÉêyùºÎŒ‚ªK© Bhttp://www.zlib.net/yXô;H¯,‚]Ä…'c¥«·DÐÉêyùºÎŒ‚ªK© àÉêyùºÎŒ‚ªK© Fhttp://www.sqlite.org/yXô;H¯,‚]Ä…'c¥«ÉDÐÉêyùºÎŒ‚ªK© àÉêyùºÎŒ‚ªK© Xhttp://www.pcre.org/license.txtyXô;H¯,‚]Ä…'c¥«}DÐÉêyùºÎŒ‚ªK© _Ref182744145}DÐÉêyùºÎŒ‚ªK© _Ref182744145}DÐÉêyùºÎŒ‚ªK© _Toc247362773}DÐÉêyùºÎŒ‚ªK© _Toc247362774}DÐÉêyùºÎŒ‚ªK© _Toc247362775}DÐÉêyùºÎŒ‚ªK© _Toc247362776}DÐÉêyùºÎŒ‚ªK© _Toc247362777}DÐÉêyùºÎŒ‚ªK© _Toc247362778}DÐÉêyùºÎŒ‚ªK© _Toc247362779}DÐÉêyùºÎŒ‚ªK© _Toc247362780}DÐÉêyùºÎŒ‚ªK© _Toc247362781}DÐÉêyùºÎŒ‚ªK© _Toc247362782}DÐÉêyùºÎŒ‚ªK© _Toc247362783}DÐÉêyùºÎŒ‚ªK© _Toc247362784}DÐÉêyùºÎŒ‚ªK© _Toc247362785}DÐÉêyùºÎŒ‚ªK© _Toc247362786}DÐÉêyùºÎŒ‚ªK© _Toc247362787}DÐÉêyùºÎŒ‚ªK© _Toc247362788}DÐÉêyùºÎŒ‚ªK© _Toc247362789}DÐÉêyùºÎŒ‚ªK© _Toc247362790}DÐÉêyùºÎŒ‚ªK© _Toc247362791}DÐÉêyùºÎŒ‚ªK© _Toc247362792}DÐÉêyùºÎŒ‚ªK© _Toc247362793}DÐÉêyùºÎŒ‚ªK© _Toc247362794}DÐÉêyùºÎŒ‚ªK© _Toc247362795}DÐÉêyùºÎŒ‚ªK© _Toc247362796}DÐÉêyùºÎŒ‚ªK© _Toc247362797}DÐÉêyùºÎŒ‚ªK© _Toc247362798}DÐÉêyùºÎŒ‚ªK© _Toc247362799}DÐÉêyùºÎŒ‚ªK© _Toc247362800}DÐÉêyùºÎŒ‚ªK© _Toc247362801}DÐÉêyùºÎŒ‚ªK© _Toc247362802}DÐÉêyùºÎŒ‚ªK© _Toc247362803}DÐÉêyùºÎŒ‚ªK© _Toc247362804}DÐÉêyùºÎŒ‚ªK© _Toc247362805}DÐÉêyùºÎŒ‚ªK© _Toc247362806}DÐÉêyùºÎŒ‚ªK© _Toc247362807}DÐÉêyùºÎŒ‚ªK© _Toc247362808}DÐÉêyùºÎŒ‚ªK© _Toc247362809}DÐÉêyùºÎŒ‚ªK© _Toc247362810}DÐÉêyùºÎŒ‚ªK© _Toc247362811}DÐÉêyùºÎŒ‚ªK© _Toc247362812}DÐÉêyùºÎŒ‚ªK© _Toc247362813}DÐÉêyùºÎŒ‚ªK© _Toc247362814}DÐÉêyùºÎŒ‚ªK© _Toc247362815}DÐÉêyùºÎŒ‚ªK© _Toc247362816}DÐÉêyùºÎŒ‚ªK© _Toc247362817}DÐÉêyùºÎŒ‚ªK© _Toc247362818}DÐÉêyùºÎŒ‚ªK© _Toc247362819}DÐÉêyùºÎŒ‚ªK© _Toc247362820}DÐÉêyùºÎŒ‚ªK© _Toc247362821}DÐÉêyùºÎŒ‚ªK© _Toc247362822}DÐÉêyùºÎŒ‚ªK© _Toc247362823}DÐÉêyùºÎŒ‚ªK© _Toc247362824}DÐÉêyùºÎŒ‚ªK© _Toc247362825}DÐÉêyùºÎŒ‚ªK© _Toc247362826}DÐÉêyùºÎŒ‚ªK© _Toc247362827}DÐÉêyùºÎŒ‚ªK© _Toc247362828}DÐÉêyùºÎŒ‚ªK© _Toc247362829}DÐÉêyùºÎŒ‚ªK© _Toc247362830}DÐÉêyùºÎŒ‚ªK© _Toc247362831}DÐÉêyùºÎŒ‚ªK© _Toc247362832}DÐÉêyùºÎŒ‚ªK© _Toc247362833}DÐÉêyùºÎŒ‚ªK© _Toc247362834}DÐÉêyùºÎŒ‚ªK© _Toc247362835}DÐÉêyùºÎŒ‚ªK© _Toc247362836}DÐÉêyùºÎŒ‚ªK© _Toc247362837}DÐÉêyùºÎŒ‚ªK© _Toc247362838}DÐÉêyùºÎŒ‚ªK© _Toc247362839}DÐÉêyùºÎŒ‚ªK© _Toc247362840}DÐÉêyùºÎŒ‚ªK© _Toc247362841}DÐÉêyùºÎŒ‚ªK© _Toc247362842}DÐÉêyùºÎŒ‚ªK© _Toc247362843}DÐÉêyùºÎŒ‚ªK© _Toc247362844}DÐÉêyùºÎŒ‚ªK© _Toc247362845}DÐÉêyùºÎŒ‚ªK© _Toc247362846}DÐÉêyùºÎŒ‚ªK© _Toc247362847}DÐÉêyùºÎŒ‚ªK© _Toc247362848}DÐÉêyùºÎŒ‚ªK© _Toc247362849}DÐÉêyùºÎŒ‚ªK© _Toc247362850}DÐÉêyùºÎŒ‚ªK© _Toc247362851}DÐÉêyùºÎŒ‚ªK© _Toc247362852}DÐÉêyùºÎŒ‚ªK© _Toc247362853}DÐÉêyùºÎŒ‚ªK© _Toc247362854}DÐÉêyùºÎŒ‚ªK© _Toc247362855}DÐÉêyùºÎŒ‚ªK© _Toc247362856}DÐÉêyùºÎŒ‚ªK© _Toc247362857}DÐÉêyùºÎŒ‚ªK© _Toc247362858}DÐÉêyùºÎŒ‚ªK© _Toc247362859}DÐÉêyùºÎŒ‚ªK© _Toc247362860}DÐÉêyùºÎŒ‚ªK© _Toc247362861}DÐÉêyùºÎŒ‚ªK© _Toc247362862}DÐÉêyùºÎŒ‚ªK© _Toc247362863}DÐÉêyùºÎŒ‚ªK© _Toc247362864}DÐÉêyùºÎŒ‚ªK© _Toc247362865}DÐÉêyùºÎŒ‚ªK© _Toc247362866}DÐÉêyùºÎŒ‚ªK© _Toc247362867}DÐÉêyùºÎŒ‚ªK© _Toc247362868}DÐÉêyùºÎŒ‚ªK© _Toc247362869}DÐÉêyùºÎŒ‚ªK© _Toc247362870}DÐÉêyùºÎŒ‚ªK© _Toc247362871}DÐÉêyùºÎŒ‚ªK© _Toc247362872}DÐÉêyùºÎŒ‚ªK© _Toc247362873}DÐÉêyùºÎŒ‚ªK© _Toc247362874}DÐÉêyùºÎŒ‚ªK© _Toc247362875}DÐÉêyùºÎŒ‚ªK© _Toc247362876}DÐÉêyùºÎŒ‚ªK© _Toc247362877}DÐÉêyùºÎŒ‚ªK© _Toc247362878}DÐÉêyùºÎŒ‚ªK© _Toc247362879}DÐÉêyùºÎŒ‚ªK© _Toc247362880}DÐÉêyùºÎŒ‚ªK© _Toc247362881}DÐÉêyùºÎŒ‚ªK© _Toc247362882}DÐÉêyùºÎŒ‚ªK© _Toc247362883}DÐÉêyùºÎŒ‚ªK© _Toc247362884}DÐÉêyùºÎŒ‚ªK© _Toc247362885}DÐÉêyùºÎŒ‚ªK© _Toc247362886}DÐÉêyùºÎŒ‚ªK© _Toc247362887}DÐÉêyùºÎŒ‚ªK© _Toc247362888}DÐÉêyùºÎŒ‚ªK© _Toc247362889}DÐÉêyùºÎŒ‚ªK© _Toc247362890}DÐÉêyùºÎŒ‚ªK© _Toc247362891}DÐÉêyùºÎŒ‚ªK© _Toc247362892}DÐÉêyùºÎŒ‚ªK© _Toc247362893}DÐÉêyùºÎŒ‚ªK© _Toc247362894}DÐÉêyùºÎŒ‚ªK© _Toc247362895}DÐÉêyùºÎŒ‚ªK© _Toc247362896}DÐÉêyùºÎŒ‚ªK© _Toc247362897}DÐÉêyùºÎŒ‚ªK© _Toc247362898}DÐÉêyùºÎŒ‚ªK© _Toc247362899}DÐÉêyùºÎŒ‚ªK© _Toc247362900}DÐÉêyùºÎŒ‚ªK© _Toc247362901}DÐÉêyùºÎŒ‚ªK© _Toc247362902}DÐÉêyùºÎŒ‚ªK© _Toc247362903}DÐÉêyùºÎŒ‚ªK© _Toc247362904}DÐÉêyùºÎŒ‚ªK© _Toc247362905}DÐÉêyùºÎŒ‚ªK© _Toc247362906}DÐÉêyùºÎŒ‚ªK© _Toc247362907}DÐÉêyùºÎŒ‚ªK© _Toc247362908}DÐÉêyùºÎŒ‚ªK© _Toc247362909}DÐÉêyùºÎŒ‚ªK© _Toc247362910}DÐÉêyùºÎŒ‚ªK© _Toc247362911}DÐÉêyùºÎŒ‚ªK© _Toc247362912}DÐÉêyùºÎŒ‚ªK© _Toc247362913}DÐÉêyùºÎŒ‚ªK© _Toc247362914}DÐÉêyùºÎŒ‚ªK© _Toc247362915}DÐÉêyùºÎŒ‚ªK© _Toc247362916}DÐÉêyùºÎŒ‚ªK© _Toc247362917}DÐÉêyùºÎŒ‚ªK© _Toc247362918}DÐÉêyùºÎŒ‚ªK© _Toc247362919}DÐÉêyùºÎŒ‚ªK© _Toc247362920}DÐÉêyùºÎŒ‚ªK© _Toc247362921}DÐÉêyùºÎŒ‚ªK© _Toc247362922}DÐÉêyùºÎŒ‚ªK© _Toc247362923}DÐÉêyùºÎŒ‚ªK© _Toc247362924}DÐÉêyùºÎŒ‚ªK© _Toc247362925}DÐÉêyùºÎŒ‚ªK© _Toc247362926}DÐÉêyùºÎŒ‚ªK© _Toc247362927}DÐÉêyùºÎŒ‚ªK© _Toc247362928}DÐÉêyùºÎŒ‚ªK© _Toc247362929}DÐÉêyùºÎŒ‚ªK© _Toc247362930}DÐÉêyùºÎŒ‚ªK© _Toc247362931}DÐÉêyùºÎŒ‚ªK© _Toc247362932}DÐÉêyùºÎŒ‚ªK© _Toc247362933}DÐÉêyùºÎŒ‚ªK© _Toc247362934}DÐÉêyùºÎŒ‚ªK© _Toc247362935}DÐÉêyùºÎŒ‚ªK© _Toc247362936}DÐÉêyùºÎŒ‚ªK© _Toc247362937}DÐÉêyùºÎŒ‚ªK© _Toc247362938}DÐÉêyùºÎŒ‚ªK© _Toc247362939}DÐÉêyùºÎŒ‚ªK© _Toc247362940}DÐÉêyùºÎŒ‚ªK© _Toc247362941}DÐÉêyùºÎŒ‚ªK© _Toc247362942}DÐÉêyùºÎŒ‚ªK© _Toc247362943}DÐÉêyùºÎŒ‚ªK© _Toc247362944}DÐÉêyùºÎŒ‚ªK© _Toc247362945}DÐÉêyùºÎŒ‚ªK© _Toc247362946}DÐÉêyùºÎŒ‚ªK© _Toc247362947}DÐÉêyùºÎŒ‚ªK© _Toc247362948}DÐÉêyùºÎŒ‚ªK© _Toc247362949}DÐÉêyùºÎŒ‚ªK© _Toc247362950}DÐÉêyùºÎŒ‚ªK© _Toc247362951}DÐÉêyùºÎŒ‚ªK© _Toc247362952}DÐÉêyùºÎŒ‚ªK© _Toc247362953}DÐÉêyùºÎŒ‚ªK© _Toc247362954}DÐÉêyùºÎŒ‚ªK© _Toc247362955}DÐÉêyùºÎŒ‚ªK© _Toc247362956}DÐÉêyùºÎŒ‚ªK© _Toc247362957}DÐÉêyùºÎŒ‚ªK© _Toc247362958}DÐÉêyùºÎŒ‚ªK© _Toc247362959}DÐÉêyùºÎŒ‚ªK© _Toc247362960}DÐÉêyùºÎŒ‚ªK© _Toc247362961}DÐÉêyùºÎŒ‚ªK© _Toc247362962}DÐÉêyùºÎŒ‚ªK© _Toc247362963}DÐÉêyùºÎŒ‚ªK© _Toc247362964}DÐÉêyùºÎŒ‚ªK© _Toc247362965}DÐÉêyùºÎŒ‚ªK© _Toc247362966}DÐÉêyùºÎŒ‚ªK© _Toc247362967}DÐÉêyùºÎŒ‚ªK© _Toc247362968}DÐÉêyùºÎŒ‚ªK© _Toc247362969}DÐÉêyùºÎŒ‚ªK© _Toc247362970}DÐÉêyùºÎŒ‚ªK© _Toc247362971}DÐÉêyùºÎŒ‚ªK© _Toc247362972}DÐÉêyùºÎŒ‚ªK© _Toc247362973}DÐÉêyùºÎŒ‚ªK© _Toc247362974}DÐÉêyùºÎŒ‚ªK© _Toc247362975}DÐÉêyùºÎŒ‚ªK© _Toc247362976}DÐÉêyùºÎŒ‚ªK© _Toc247362977}DÐÉêyùºÎŒ‚ªK© _Toc247362978}DÐÉêyùºÎŒ‚ªK© _Toc247362979}DÐÉêyùºÎŒ‚ªK© _Toc247362980}DÐÉêyùºÎŒ‚ªK© _Toc247362981}DÐÉêyùºÎŒ‚ªK© _Toc247362982}DÐÉêyùºÎŒ‚ªK© _Toc247362983}DÐÉêyùºÎŒ‚ªK© _Toc247362984}DÐÉêyùºÎŒ‚ªK© _Toc247362985}DÐÉêyùºÎŒ‚ªK© _Toc247362986}DÐÉêyùºÎŒ‚ªK© _Toc247362987}DÐÉêyùºÎŒ‚ªK© _Toc247362988}DÐÉêyùºÎŒ‚ªK© _Toc247362989}DÐÉêyùºÎŒ‚ªK© _Toc247362990}DÐÉêyùºÎŒ‚ªK© _Toc247362991}DÐÉêyùºÎŒ‚ªK© _Toc247362992}DÐÉêyùºÎŒ‚ªK© _Toc247362993}DÐÉêyùºÎŒ‚ªK© _Toc247362994}DÐÉêyùºÎŒ‚ªK© _Toc247362995}DÐÉêyùºÎŒ‚ªK© _Toc247362996}DÐÉêyùºÎŒ‚ªK© _Toc247362997}DÐÉêyùºÎŒ‚ªK© _Toc247362998}DÐÉêyùºÎŒ‚ªK© _Toc247362999}DÐÉêyùºÎŒ‚ªK© _Toc247363000}DÐÉêyùºÎŒ‚ªK© _Toc247363001}DÐÉêyùºÎŒ‚ªK© _Toc247363002}DÐÉêyùºÎŒ‚ªK© _Toc247363003}DÐÉêyùºÎŒ‚ªK© _Toc247363004}DÐÉêyùºÎŒ‚ªK© _Toc247363005}DÐÉêyùºÎŒ‚ªK© _Toc247363006}DÐÉêyùºÎŒ‚ªK© _Toc247363007}DÐÉêyùºÎŒ‚ªK© _Toc247363008}DÐÉêyùºÎŒ‚ªK© _Toc247363009}DÐÉêyùºÎŒ‚ªK© _Toc247363010}DÐÉêyùºÎŒ‚ªK© _Toc247363011}DÐÉêyùºÎŒ‚ªK© _Toc247363012}DÐÉêyùºÎŒ‚ªK© _Toc247363013}DÐÉêyùºÎŒ‚ªK© _Toc247363014}DÐÉêyùºÎŒ‚ªK© _Toc247363015}DÐÉêyùºÎŒ‚ªK© _Toc247363016}DÐÉêyùºÎŒ‚ªK© _Toc247363017}DÐÉêyùºÎŒ‚ªK© _Toc247363018}DÐÉêyùºÎŒ‚ªK© _Toc247363019}DÐÉêyùºÎŒ‚ªK© _Toc247363020}DÐÉêyùºÎŒ‚ªK© _Toc247363021}DÐÉêyùºÎŒ‚ªK© _Toc247363022}DÐÉêyùºÎŒ‚ªK© _Toc247363023}DÐÉêyùºÎŒ‚ªK© _Toc247363024}DÐÉêyùºÎŒ‚ªK© _Toc247363025}DÐÉêyùºÎŒ‚ªK© _Toc247363026}DÐÉêyùºÎŒ‚ªK© _Toc247363027}DÐÉêyùºÎŒ‚ªK© _Toc247363028}DÐÉêyùºÎŒ‚ªK© _Toc247363029}DÐÉêyùºÎŒ‚ªK© _Toc247363030}DÐÉêyùºÎŒ‚ªK© _Toc247363031}DÐÉêyùºÎŒ‚ªK© _Toc247363032}DÐÉêyùºÎŒ‚ªK© _Toc247363033}DÐÉêyùºÎŒ‚ªK© _Toc247363034}DÐÉêyùºÎŒ‚ªK© _Toc247363035}DÐÉêyùºÎŒ‚ªK© _Toc247363036}DÐÉêyùºÎŒ‚ªK© _Toc247363037}DÐÉêyùºÎŒ‚ªK© _Toc247363038}DÐÉêyùºÎŒ‚ªK© _Toc247363039}DÐÉêyùºÎŒ‚ªK© _Toc247363040}DÐÉêyùºÎŒ‚ªK© _Toc247363041}DÐÉêyùºÎŒ‚ªK© _Toc247363042}DÐÉêyùºÎŒ‚ªK© _Toc247363043}DÐÉêyùºÎŒ‚ªK© _Toc247363044}DÐÉêyùºÎŒ‚ªK© _Toc247363045}DÐÉêyùºÎŒ‚ªK© _Toc247363046}DÐÉêyùºÎŒ‚ªK© _Toc247363047}DÐÉêyùºÎŒ‚ªK© _Toc247363048}DÐÉêyùºÎŒ‚ªK© _Toc247363049}DÐÉêyùºÎŒ‚ªK© _Toc247363050}DÐÉêyùºÎŒ‚ªK© _Toc247363051}DÐÉêyùºÎŒ‚ªK© _Toc247363052}DÐÉêyùºÎŒ‚ªK© _Toc247363053}DÐÉêyùºÎŒ‚ªK© _Toc247363054}DÐÉêyùºÎŒ‚ªK© _Toc247363055}DÐÉêyùºÎŒ‚ªK© _Toc247363056}DÐÉêyùºÎŒ‚ªK© _Toc247363057}DÐÉêyùºÎŒ‚ªK© _Toc247363058}DÐÉêyùºÎŒ‚ªK© _Toc247363059}DÐÉêyùºÎŒ‚ªK© _Toc247363060}DÐÉêyùºÎŒ‚ªK© _Toc247363061}DÐÉêyùºÎŒ‚ªK© _Toc247363062}DÐÉêyùºÎŒ‚ªK© _Toc247363063}DÐÉêyùºÎŒ‚ªK© _Toc247363064}DÐÉêyùºÎŒ‚ªK© _Toc247363065}DÐÉêyùºÎŒ‚ªK© _Toc247363066}DÐÉêyùºÎŒ‚ªK© _Toc247363067}DÐÉêyùºÎŒ‚ªK© _Toc247363068}DÐÉêyùºÎŒ‚ªK© _Toc247363069}DÐÉêyùºÎŒ‚ªK© _Toc247363070}DÐÉêyùºÎŒ‚ªK© _Toc247363071}DÐÉêyùºÎŒ‚ªK© _Toc247363072}DÐÉêyùºÎŒ‚ªK© _Toc247363073}DÐÉêyùºÎŒ‚ªK© _Toc247363074}DÐÉêyùºÎŒ‚ªK© _Toc247363075}DÐÉêyùºÎŒ‚ªK© _Toc247363076}DÐÉêyùºÎŒ‚ªK© _Toc247363077}DÐÉêyùºÎŒ‚ªK© _Toc247363078}DÐÉêyùºÎŒ‚ªK© _Toc247363079}DÐÉêyùºÎŒ‚ªK© _Toc247363080}DÐÉêyùºÎŒ‚ªK© _Toc247363081}DÐÉêyùºÎŒ‚ªK© _Toc247363082}DÐÉêyùºÎŒ‚ªK© _Toc247363083}DÐÉêyùºÎŒ‚ªK© _Toc247363084}DÐÉêyùºÎŒ‚ªK© _Toc247363085}DÐÉêyùºÎŒ‚ªK© _Toc247363086}DÐÉêyùºÎŒ‚ªK© _Toc247363087}DÐÉêyùºÎŒ‚ªK© _Toc247363088}DÐÉêyùºÎŒ‚ªK© _Toc247363089}DÐÉêyùºÎŒ‚ªK© _Toc247363090}DÐÉêyùºÎŒ‚ªK© _Toc247363091}DÐÉêyùºÎŒ‚ªK© _Toc247363092}DÐÉêyùºÎŒ‚ªK© _Toc247363093}DÐÉêyùºÎŒ‚ªK© _Toc247363094}DÐÉêyùºÎŒ‚ªK© _Toc247363095}DÐÉêyùºÎŒ‚ªK© _Toc247363096}DÐÉêyùºÎŒ‚ªK© _Toc247363097}DÐÉêyùºÎŒ‚ªK© _Toc247363098}DÐÉêyùºÎŒ‚ªK© _Toc247363099}DÐÉêyùºÎŒ‚ªK© _Toc247363100}DÐÉêyùºÎŒ‚ªK© _Toc247363101}DÐÉêyùºÎŒ‚ªK© _Toc247363102}DÐÉêyùºÎŒ‚ªK© _Toc247363103}DÐÉêyùºÎŒ‚ªK© _Toc247363104}DÐÉêyùºÎŒ‚ªK© _Toc247363105}DÐÉêyùºÎŒ‚ªK© _Toc247363106}DÐÉêyùºÎŒ‚ªK© _Toc247363107}DÐÉêyùºÎŒ‚ªK© _Toc247363108}DÐÉêyùºÎŒ‚ªK© _Toc247363109}DÐÉêyùºÎŒ‚ªK© _Toc247363110}DÐÉêyùºÎŒ‚ªK© _Toc247363111}DÐÉêyùºÎŒ‚ªK© _Toc247363112}DÐÉêyùºÎŒ‚ªK© _Toc247363113}DÐÉêyùºÎŒ‚ªK© _Toc247363114}DÐÉêyùºÎŒ‚ªK© _Toc247363115}DÐÉêyùºÎŒ‚ªK© _Toc247363116}DÐÉêyùºÎŒ‚ªK© _Toc247363117}DÐÉêyùºÎŒ‚ªK© _Toc247363118}DÐÉêyùºÎŒ‚ªK© _Toc247363119}DÐÉêyùºÎŒ‚ªK© _Toc247363120}DÐÉêyùºÎŒ‚ªK© _Toc247363121}DÐÉêyùºÎŒ‚ªK© _Toc247363122}DÐÉêyùºÎŒ‚ªK© _Toc247363123}DÐÉêyùºÎŒ‚ªK© _Toc247363124}DÐÉêyùºÎŒ‚ªK© _Toc247363125}DÐÉêyùºÎŒ‚ªK© _Toc247363126}DÐÉêyùºÎŒ‚ªK© _Toc247363127}DÐÉêyùºÎŒ‚ªK© _Toc247363128}DÐÉêyùºÎŒ‚ªK© _Toc247363129}DÐÉêyùºÎŒ‚ªK© _Toc247363130}DÐÉêyùºÎŒ‚ªK© _Toc247363131}DÐÉêyùºÎŒ‚ªK© _Toc247363132}DÐÉêyùºÎŒ‚ªK© _Ref201664889}DÐÉêyùºÎŒ‚ªK© _Ref201664889«DÐÉêyùºÎŒ‚ªK© ÀFSySync_script_call_flow.pdfÿÿ­Þ}DÐÉêyùºÎŒ‚ªK© _Ref185238094}DÐÉêyùºÎŒ‚ªK© _Ref185238094}DÐÉêyùºÎŒ‚ªK© _Ref201664889}DÐÉêyùºÎŒ‚ªK© _Ref201664889}DÐÉêyùºÎŒ‚ªK© _Ref185238094}DÐÉêyùºÎŒ‚ªK© _Ref204925451}DÐÉêyùºÎŒ‚ªK© _Ref204935552}DÐÉêyùºÎŒ‚ªK© _Ref204925451}DÐÉêyùºÎŒ‚ªK© _Ref185246110{DÐÉêyùºÎŒ‚ªK©  _Ref47173451}DÐÉêyùºÎŒ‚ªK© _Ref182995906}DÐÉêyùºÎŒ‚ªK© _Ref182997657}DÐÉêyùºÎŒ‚ªK© _Ref207618734}DÐÉêyùºÎŒ‚ªK© _Ref204937964{DÐÉêyùºÎŒ‚ªK©  _Ref42673942}DÐÉêyùºÎŒ‚ªK© _Ref182995906}DÐÉêyùºÎŒ‚ªK© _Ref204935761}DÐÉêyùºÎŒ‚ªK© _Ref203479102}DÐÉêyùºÎŒ‚ªK© _Ref204935780}DÐÉêyùºÎŒ‚ªK© _Ref203482186}DÐÉêyùºÎŒ‚ªK© _Ref203482205}DÐÉêyùºÎŒ‚ªK© _Ref153590626{DÐÉêyùºÎŒ‚ªK©  _Ref42675268}DÐÉêyùºÎŒ‚ªK© _Ref153590626}DÐÉêyùºÎŒ‚ªK© _Ref184459487}DÐÉêyùºÎŒ‚ªK© _Ref183001062}DÐÉêyùºÎŒ‚ªK© _Ref184460000}DÐÉêyùºÎŒ‚ªK© _Ref183001062}DÐÉêyùºÎŒ‚ªK© _Ref182995906}DÐÉêyùºÎŒ‚ªK© _Ref185245663}DÐÉêyùºÎŒ‚ªK© _Ref185246110{DÐÉêyùºÎŒ‚ªK©  _Ref47775300{DÐÉêyùºÎŒ‚ªK©  _Ref47775275yDÐÉêyùºÎŒ‚ªK©  _Ref6129297{DÐÉêyùºÎŒ‚ªK©  _Ref47165113{DÐÉêyùºÎŒ‚ªK©  _Ref47165137{DÐÉêyùºÎŒ‚ªK©  _Ref47165113{DÐÉêyùºÎŒ‚ªK©  _Ref47165137}DÐÉêyùºÎŒ‚ªK© _Ref184460000}DÐÉêyùºÎŒ‚ªK© _Ref204511965}DÐÉêyùºÎŒ‚ªK© _Ref184460000}DÐÉêyùºÎŒ‚ªK© _Ref184459204}DÐÉêyùºÎŒ‚ªK© _Ref204511965}DÐÉêyùºÎŒ‚ªK© _Ref184459204}DÐÉêyùºÎŒ‚ªK© _Ref183001062}DÐÉêyùºÎŒ‚ªK© _Ref184459487}DÐÉêyùºÎŒ‚ªK© _Ref206385571}DÐÉêyùºÎŒ‚ªK© _Ref206385661}DÐÉêyùºÎŒ‚ªK© _Ref184460158}DÐÉêyùºÎŒ‚ªK© _Ref185247389{DÐÉêyùºÎŒ‚ªK©  _Ref47173451}DÐÉêyùºÎŒ‚ªK© _Ref185246110}DÐÉêyùºÎŒ‚ªK© _Ref185245663}DÐÉêyùºÎŒ‚ªK© _Ref185246110}DÐÉêyùºÎŒ‚ªK© _Ref204922935}DÐÉêyùºÎŒ‚ªK© _Ref204925451{DÐÉêyùºÎŒ‚ªK©  _Ref43727925{DÐÉêyùºÎŒ‚ªK©  _Ref43727928{DÐÉêyùºÎŒ‚ªK©  _Ref47173451{DÐÉêyùºÎŒ‚ªK©  _Ref47173451}DÐÉêyùºÎŒ‚ªK© _Ref204936212}DÐÉêyùºÎŒ‚ªK© _Ref204925451}DÐÉêyùºÎŒ‚ªK© _Ref185261956}DÐÉêyùºÎŒ‚ªK© _Ref185247389}DÐÉêyùºÎŒ‚ªK© _Ref204925451}DÐÉêyùºÎŒ‚ªK© _Ref185262282}DÐÉêyùºÎŒ‚ªK© _Ref204925451}DÐÉêyùºÎŒ‚ªK© _Ref204925451}DÐÉêyùºÎŒ‚ªK© _Ref182995906}DÐÉêyùºÎŒ‚ªK© _Ref204925451{DÐÉêyùºÎŒ‚ªK©  _Ref42506966{DÐÉêyùºÎŒ‚ªK©  _Ref42517152«DÐÉêyùºÎŒ‚ªK© ÀFSySync_script_call_flow.pdfÿÿ­ÞyDÐÉêyùºÎŒ‚ªK©  _Ref5625615{DÐÉêyùºÎŒ‚ªK©  _Ref42509834yDÐÉêyùºÎŒ‚ªK©  _Ref6030571{DÐÉêyùºÎŒ‚ªK©  _Ref42673816yDÐÉêyùºÎŒ‚ªK©  _Ref5625615{DÐÉêyùºÎŒ‚ªK©  _Ref42671142}DÐÉêyùºÎŒ‚ªK© _Ref185238839{DÐÉêyùºÎŒ‚ªK©  _Ref42511232{DÐÉêyùºÎŒ‚ªK©  _Ref42517152{DÐÉêyùºÎŒ‚ªK©  _Ref42589436{DÐÉêyùºÎŒ‚ªK©  _Ref42588386{DÐÉêyùºÎŒ‚ªK©  _Ref42509834{DÐÉêyùºÎŒ‚ªK©  _Ref42590185{DÐÉêyùºÎŒ‚ªK©  _Ref42511232}DÐÉêyùºÎŒ‚ªK© _Ref153285595}DÐÉêyùºÎŒ‚ªK© _Ref153285595}DÐÉêyùºÎŒ‚ªK© _Ref247357288{DÐÉêyùºÎŒ‚ªK©  _Ref42672298{DÐÉêyùºÎŒ‚ªK©  _Ref42673942{DÐÉêyùºÎŒ‚ªK©  _Ref78023979{DÐÉêyùºÎŒ‚ªK©  _Ref78023979³DÐÉêyùºÎŒ‚ªK© àÉêyùºÎŒ‚ªK© Bhttp://www.pcre.org/yXô;H¯,‚]Ä…'c¥«}DÐÉêyùºÎŒ‚ªK© _Ref182995906}DÐÉêyùºÎŒ‚ªK© _Ref182995906{DÐÉêyùºÎŒ‚ªK©  _Ref36890908{DÐÉêyùºÎŒ‚ªK©  _Ref36890908{DÐÉêyùºÎŒ‚ªK©  _Ref36890908{DÐÉêyùºÎŒ‚ªK©  _Ref36890908}DÐÉêyùºÎŒ‚ªK© _Ref204926421}DÐÉêyùºÎŒ‚ªK© _Ref204926421}DÐÉêyùºÎŒ‚ªK© _Ref204926421}DÐÉêyùºÎŒ‚ªK© _Ref204926421}DÐÉêyùºÎŒ‚ªK© _Ref204926421}DÐÉêyùºÎŒ‚ªK© _Ref204926421}DÐÉêyùºÎŒ‚ªK© _Ref185257870}DÐÉêyùºÎŒ‚ªK© _Ref185261956}DÐÉêyùºÎŒ‚ªK© _Ref185261956}DÐÉêyùºÎŒ‚ªK© _Ref185257870}DÐÉêyùºÎŒ‚ªK© _Ref185257870}DÐÉêyùºÎŒ‚ªK© _Ref204922935{DÐÉêyùºÎŒ‚ªK©  _Ref42675268{DÐÉêyùºÎŒ‚ªK©  _Ref47156991{DÐÉêyùºÎŒ‚ªK©  _Ref42675268}DÐÉêyùºÎŒ‚ªK© _Ref204932692{DÐÉêyùºÎŒ‚ªK©  _Ref47170147{DÐÉêyùºÎŒ‚ªK©  _Ref42675268{DÐÉêyùºÎŒ‚ªK©  _Ref43727925}DÐÉêyùºÎŒ‚ªK© _Ref203481904{DÐÉêyùºÎŒ‚ªK©  _Ref43727925}DÐÉêyùºÎŒ‚ªK© _Ref203481972{DÐÉêyùºÎŒ‚ªK©  _Ref42589436}DÐÉêyùºÎŒ‚ªK© _Ref206062819{DÐÉêyùºÎŒ‚ªK©  _Ref70164511}DÐÉêyùºÎŒ‚ªK© _Ref207622654{DÐÉêyùºÎŒ‚ªK©  _Ref54091188{DÐÉêyùºÎŒ‚ªK©  _Ref54091192}DÐÉêyùºÎŒ‚ªK© _Ref153773639{DÐÉêyùºÎŒ‚ªK©  _Ref42941679{DÐÉêyùºÎŒ‚ªK©  _Ref45368759{DÐÉêyùºÎŒ‚ªK©  _Ref55271118{DÐÉêyùºÎŒ‚ªK©  _Ref43008951{DÐÉêyùºÎŒ‚ªK©  _Ref42672298}DÐÉêyùºÎŒ‚ªK© _Ref153284855{DÐÉêyùºÎŒ‚ªK©  _Ref45001933{DÐÉêyùºÎŒ‚ªK©  _Ref54091553{DÐÉêyùºÎŒ‚ªK©  _Ref54091119{DÐÉêyùºÎŒ‚ªK©  _Ref97961473}DÐÉêyùºÎŒ‚ªK© _Ref231887961}DÐÉêyùºÎŒ‚ªK© _Ref231888133}DÐÉêyùºÎŒ‚ªK© _Ref231887961}DÐÉêyùºÎŒ‚ªK© _Ref231888133}DÐÉêyùºÎŒ‚ªK© _Ref231887961{DÐÉêyùºÎŒ‚ªK©  _Ref42675268}DÐÉêyùºÎŒ‚ªK© _Ref135023442}DÐÉêyùºÎŒ‚ªK© _Ref153291752}DÐÉêyùºÎŒ‚ªK© _Ref153291752{DÐÉêyùºÎŒ‚ªK©  _Ref69052620{DÐÉêyùºÎŒ‚ªK©  _Ref46904847{DÐÉêyùºÎŒ‚ªK©  _Ref46823382}DÐÉêyùºÎŒ‚ªK© _Ref153288035{DÐÉêyùºÎŒ‚ªK©  _Ref47262189{DÐÉêyùºÎŒ‚ªK©  _Ref46821357}DÐÉêyùºÎŒ‚ªK© _Ref153288035{DÐÉêyùºÎŒ‚ªK©  _Ref46823145{DÐÉêyùºÎŒ‚ªK©  _Ref55271118{DÐÉêyùºÎŒ‚ªK©  _Ref46823382{DÐÉêyùºÎŒ‚ªK©  _Ref47451551{DÐÉêyùºÎŒ‚ªK©  _Ref47451589}DÐÉêyùºÎŒ‚ªK© _Ref203479102}DÐÉêyùºÎŒ‚ªK© _Ref184460000}DÐÉêyùºÎŒ‚ªK© _Ref184460000}DÐÉêyùºÎŒ‚ªK© _Ref203380577}DÐÉêyùºÎŒ‚ªK© _Ref184459204}DÐÉêyùºÎŒ‚ªK© _Ref203475251}DÐÉêyùºÎŒ‚ªK© _Ref184460000{DÐÉêyùºÎŒ‚ªK©  _Ref42675038{DÐÉêyùºÎŒ‚ªK©  _Ref42675038}DÐÉêyùºÎŒ‚ªK© _Ref153282321}DÐÉêyùºÎŒ‚ªK© _Ref153282321}DÐÉêyùºÎŒ‚ªK© _Ref153282518}DÐÉêyùºÎŒ‚ªK© _Ref153285510}DÐÉêyùºÎŒ‚ªK© _Ref153284855}DÐÉêyùºÎŒ‚ªK© _Ref153336229ô'Dd)¬ ðf² ð C ðBAÁ*ÿdebuglog_folding.pngð€bð:'öÆÑ6²ÈTcBLRƒwf2ÿ'ü-nð'öÆÑ6²ÈTcBLRƒwf2ÿ‰PNG  IHDR¼”þ¸mftEXtSoftwareGraphicConverter5]Hî&ŸIDATxœì]=¨ÉÞL™ÁŒƒáÀ\ràèìËeü…vü:N$!pxÚŠO¡`áàxl¢@ Ìé¼»@’ûtHÈœl×¾z[[SÕUSó?+ÕG³ôövWW×Îv}Ý]3»ªÁæ´º{û2}ÿ{^¢jÐ$q°øÝoW=›ó4¬¨ž‰Dâä°0]?jpp_CF3¡1H‚oJó‡RŠ‹ÎˆžŽ&–Ìp,):åwv& Žæ“Y/R ¸v ¯V°Ñ\aî¿iðqÞà­qq¯ßÜ{ЪmOÒ€ÀH :S€Œ¾—Ò# õ½úwb§¡’£Ž´4´DñxÆ?¼i$ "§þí¾(Ó³ñ9 þóè.¾*ªoî”wîš%X„ L‹ëõ¥@ÈЂ›7Ç<†æá EÄnAÒÒ8í C A§ 1¡È| °Në)(OÈúÔ4Çj84²'úZºõ”êõQ2BCÒÄ’ÙŽ%E§"¼ ‘4PCKó)­qÏø°¦Î¦ï"´à»ÿ¶ÇÅ ¸×´b^ÞÿŒŸÛ›ÿöì÷3 ÿzó¸ªÇ@‡€<Ôysþìë“O´YÂü‚šèŽãÝ! þñD¥b¬jˆQHC¤¾Ôƒý>u\ô~‚°õìð¤HÑ;O jš;å}ºÖ‘Œz€ÇEáê"ÒŠ£Ä(°Õn¹y"d& Ú‚d P'`›ˆ»´ìFoÑ?Qàzµ#:xʮ͈ —¡t[N³29<ÒÀƒüŒhÒ ü‰b „îô0Hƒ‡z&Aô›:ä §˜Æ~ÂRü"l{|°¼Z?Þ}Äç/“Áa“9ZÄ4Ä1i7P$æ@’†ÄìŠÀC\qseT/ÂCd Õűśógô–þcüUĸà®!Ƙ4Ø·\ŽwOÄ1 ihøYNÅ­B_Ó8=&oHÖë}Ю5†8ôÁ[¾Z?¤ç a,d1Äa±x¢îðbm=—nÒAB\ qÏ$¥Ï?øô¿ù“UsÀÄÛýÔSúÙ¯—ß_ÃD"‘H¼å(=FznEé1ÒÓkÁ˜³zäb‘†®ê%‰Dâ€æ £ý!ä¤0þ°j]iænNÒ!µSÓxÚv"‘H${„ÿû00í_cGP?£ú…ÃIÆ% ×Ëÿr™H$‰DE_‹N >Zø²Ô%‹ÔgPöEŒfDÒ 9cL$‰D"‹:÷Û×€úø /¥h`MpfÑU›/C"‘H$ZÁ÷Ä|bÊMÜNpvfwÁŒ[ˆæ=²Nq‰D"‘ètÒî¹È$(µ…háÂç.ï$åÿÿÿì»jI†­ã 6ó[øü4›ïKø Œab;Š– '“c6h‚b(ê=èggërúôuºåÿ£¥¾Tºt×?U§»êïçn¨á ‹žÔXÞ”=7¿¿M¶ä„ÝŸenâÉ“x8ì·ŸßËΫ¿>=þ{¯û%l­’£~<„Bf¢‡z˜y[¤VPÚ>Vâ(£±&„ü‰w€áéñˆ>XùѱDH:ûãý]Qßv—öœéÄC!ä<´ºÌ)–4áøÂ™3`»öàN| &6¤1[œ$$*áÇ—þùþ59´ýü>!„óÓÉÉ`à6¿ Åx„?‹‘#mÿöë»×¿¼:áÛu.ÑÒ‘Õ²çp{Ý)B! bˆSÂp—ˆEÒý[êÓ ±ç"~•á›S냭£ƒ†¥G¿üð8íéñ¨³ èš.·C êµ€-ŸÉãw…B™ˆ °Œ5ô 6–hH©h@X¤ö«†Àî&d}_ÈÃí5Ü$o¶~< „BVÁH«¶élP«ŒÐÓ*s9“Іx8žŽ^]0ð4˜BY2‹[êõ,¢Áyo3’Pî ©àýŽ`<„BÈ’yi¢ÁvÒÑ€A‚ˆa­’¢6Å`߯l‡BY,‹ Ðï4èž_vDÃþj+a}y2ñ?ÈÒBÀáá°oN3ði–q¦ìwŠ– O!„U°bÑÏ,ߘp!èçí‰b$rF)ä¯\¨^¢àÿHëY› ¡h „² V,!„2' „B AÑ@!„ „B AÑ@!„ „B AÑ@!„ „B AÑ@!„+ ­kMõ¥EÄ“'ñpØããùºØÖ*]{Bϯ}¬ºÈÓãQ×Ï´áœÖ5·”o»Kœ¹¿ÚÎÿ=ʸËa¸ÍÅ2w>T:IµŸ¢^f¨k[°Ó¥2çºÖx’å°bÑÐT–rPÆí“ÛìxWTyŠaÃÚjªÿÉêœÃíµ> m8bd˜×CÇ?vTÄÐÔ+*X«î8^¦p¿7¨_†—Õc?õkj*aóÕó3jKœ~¶Š2qÏ•8œ1•äÜlìrsFÃYøâ~F¯“Ž;/Lôk‹­±UB®ò删 ¡uo'íØ"TH;[Ó6øù ¿òiˆ}ñ8áÖi2ç*k(°N)™„&‰ˆå×t|üãX »^p¬â­•I+“®ï—0†éÎe¾ªîˆWIW)z94õŠ{äÅ“áóU]Ïj§WG©.Ö¦ÅS:JØ|õÒ}ü³P?WòTMQ’àÓ‡sÇFCTÀéW\—^ÎÓz^À4¹ûéý´½?Ð^rwY·÷ÜÏ«Ç8þ’ý1¦»%âq¤ý»PdíóJiûA>¡µïº…õŒžÿ…0Í0Zs:Àµîз;{BvÛ4L]8Í2OÁVÑÕ±'Êï²Y=±ê a·¤Ìš` ±’—þsùëº.2[×cQ°cqO`'×+ÉWî¾z…Þ7YÐ(çt‘·†$à(0 F´Àh€ УZ`4@‹;6Vëè9Å–Óg¡xÆ$´þÚi¶/v”ÊçG­ÂÎ!Ÿ–íjÕ¿þøÍ|ãz­ÃÕ¥ÕRŒ…TSÁêÔµl¥~ZSo\¦Ü±Ñ°Í¶„ˆe4ˆ¤T|ùýdl{ÆøO{Oá/ ­ ›8*ã±xUÂÊ…ï¦÷(J[!¤mAìoÜdÜ4¤Øô¡ÊOšf™¯Û_§î‹ÇÔWû(€sßFÃö —9K ™Ö÷½dÒ¥´_ðnøs1ØQ®‡0Šÿ¦«Q1WÓ.áÓ˜›Å2¦;nU¤®ãXMv»ö€‚›3®Üûó(Š=nØ™qãÚ1ü¨¡|ñígQ Ú²+í04½wø(£Áôý´œëÔ}ϧí½Ê®ìøxÖh˜¢«úö­O›à›nmÖ´ÿu&Ãoåh‚ ì©§øý§þùxµÎø6Ûx³“ë±kAÙûöýÞÔ1¹?<á÷~ÿöÕÒ]¹AÔ©ËïD‘öþ9vT à‘xX£aÚš®2Oëýæ ¥5MÈÕíè iÍ_¹=ÆžóiøBKI¼íÃc`*‰þ¾½¾XO'ãò4¤>WMíÚh`nÖ¤m‘ŒvOÇ2Þ;šAýÔ·°‘w21V<—ÑÐ?î'äø©+Ã8”P‡Oøl‹¨M§FÃJÔ+3¾k4lï’÷pDÍ~Oƒ²éþ•»ø½Åuê[pM=w‹a€§£!·w/H¨ðmL޻ᮣoÿ!FƒÔí•= ñX£<±«&%½½ëééUH¿}ï÷šð–âtâCú*wPðhFCTÒÝéýÿ»ìš+7ÕÇgéȤ1¤nmá̱k4ÄÑÂhqü"]Õ`ÁÊu´J£ÝP§¾ 7g4œÅ8Ý?öEwt§VðÉã̽”wekä[óôâ,;iÇ¡BÚ¸«ð[9ˆîzt4,*™#— Z‹©([‘üÔ%²>á?˜®ÄàÅ;–çJ÷Œ÷*é¿ÿüݧMÖ©¯âVq pîØhGüW\—ì†ÓzöÄ4»+¶Ô]Õ™• žÿÓ» ¤Ÿ_…ßöŒ­#éºyû°9ìdZz².–”ñtÕ šDœ]¢_êZ0,Ë#p]»’A%<•mûy­Æ~¥×O˜zPõ­xfîØh€kˆk'ë÷ËŒº}( €) OŠéÅèøöúÂR…íè4´yZÑ7:øw凌.fqgh6¤Ç㻯ï~X.Ù#½È^ªj°šàû#©~ÿXåfF,w| sñ‘A¯ëœŠ5g# •š´uõ‘Ý“²]ŠÖ‹¤Ðz„V"b£öl\šiš×PŽ]¢xqžV4¤"÷ëµSqWÚ\°ßlÈÝmÝ i¯àzKö·^¹ØZÕÀ±ùî­ý7-ÑŸö†m]¨¢¤×q-ÿ›Ú¶ÙK¸TEÜiÆ®ÕE³ÙOštiǃ”ê—©º’tÆàGÙ[¸•× óßçò—øæV_J0wk~}¦¡ˆŸÎˆ;›¢¡gêÎŽЬG>o!ÉU§j4¹¢JÒæÍ^‘DŒSªr]Iƒ¼9Ó‚hÈóüw4Tçí?jXšÑ îYÍ úö!¢Ardr¦¡Y×Müãâ&>¥ w䃢h›) %>g“tI5= ãÙDCŒ0ã;çO?nJŠÞ4¸üñ}¢AT§»_4(¾ÂrÉ‹=èWÓÎ÷Ÿßýþ¯hYÁ«Z®÷O$û{E^y’ ¾ Âgkzæi£§'Á— 7‘Nê¯ý£}½ïqÝÂæsÍmì x.àÜáàÈØdá`¬3ß ·ÆoT®©bÙÝ’¦ÕzƒÅŸ"5P=’ÕÔnEƒÝuÖ{¬*[ÿ$“HÝ5¨¤ ÙŠÛ9¨F?è{>å{#]pÕÖ=²üu~Í té]až¾ŒÛ6Oscö‹póÑ7ÇüCø•ð®mzo7)f‰,Tàƒ–¿vc›q'„rv+¦0ÍUGk½Ž:à¦Ïë6¤Î5ÆBŠgBtžò6ÓëŸÆîvÁ–õbüŸzè,?ª•™½¤×šF¯øQ£XÄ’zÍ ó"CL×{»I1K4LÇ”¿NŠQ4Bn‡Û ã÷ã éÔ¿¹+Ÿí î),0{M¯ÇGÃe€ Š¡õJƒx_]òiF'tW0òMÛ¬þ³yt“b®hÐÐ×]þ²!„Œ@Ñà§Ë бJ3ô¯H_ÜW$ö~=®4dùg‰Œ@œp» §Ÿ®Wß…Ëw—uÉÑÓ€ 'V\žé¥h˜ÌžNfêH— !äÙ›h°ÎxÄËfSÕnCñÝl: š ¦[ ²á8„ÇÂîæŸ%¦ã꽋ñŒ•Øg#íCŒ‚¼t‹ ±¸S ˜ý»õ‰ød¦«DÌ(Lmª:ŠBȳ9Ñ0‹xZ€]ñ²pTúð¤ž6Òy0v²ñÜ}j_å^*DN¹‡ËÒ§™1 Ù=Ž1(z$éÍuõ,í ã€ÀÛÓ šg9 ~É,9Ý æ‡¿wÅñ!WØäÝ»§ËÐ5c¤x–~¦§¤ãß¿ÿR¹Þ¿o—ÕV$ƒéVë>¦˜¯Aææò±¢Ô§O/Ò1ªŠ¼+yÞ¾}ºùñcv+®¶.ëGãØNýöÇŸ¸.lÃkµKY̶DÀ׺^â€x5øW¸ ¹‡ŸËÒ†8Å/_žj.p_뙃Żéë›.:®Þ—Ȧˆ$6…E=žYwÔf} Ù1Î\· óQΩ۪𠟾ðø¸ÄyŠ+°ÖÆšÒÙaÍ{]·MÑ@ȱEÑ ÎnÒ}ÅãßþòWßÊÒ§£_Á[]œ;ÉÌ,ÞM_ßtÑñ»»N‹‚¨xW¶¨¶îNSúŒ3×ù¥kª\¶39oé¬h—¼+§²¤‰¢®Û.2¬wù „\éרøOTŸ\4¸y­~fÞ+KÇLº»Bд¡0c°x7}}ÓYÇÕÓ‹WÙ1‚]i¨U hXà O(Dèl[FÏýœÃycm&3ïbk MKšØ!qÛÙVE!7ÅEƒKׯû¹¢áþþÙ’X‡Aœs‹¯Y¥ˆMÛ¥ò¬ã$Ë.­Ç•v™˜"à#3fhp³yµDÔ \¸®ý u|@YÍšC=&ÛÁˆèůǟºÔšÝ> À? Âlµ’SÆÄޤ}uª1nÀëÑP{lPl®§#vºûhIV§¢YnÛJU¶†¨-ð2 _ h äŠØ´hÀR~ÑÏ ðOÓqæÝô]¢s‹¯ ±éѤÔ㣦Œ¢AŒÆB® M_®¢az¹v¢"îƒ(.O¶òT ã€Jä²K/ðÄ2Èâ‰]µâP¥9ŒU”R¤kL1Øu’²ðèq’õ´°³¾/ê´,pÛV7ÔéNUœc­‚r16-äûÔFÅÏ 6½ðIµ ÑŒ¹Å׈†ºéAwÞ]¯Ö¬7¬ S+n`Äà àHþ&Ýy8ø‹¢¹5Æ£1£mdÀ³ S{ßµ³°ddį4¸²]1ò’²e¶+d^U„ÄÛ—ËÒkßÐ5c°x‘¾ éºTÖÐH^ ,ÛÊüºÐ|ë’¢Áæ«®×*N.¦0RÀ>Ñcÿµº=%²Z½x¶éP¯P4²{6*ä›T&aú}ŠÕõƒYâyz"KÏ»ì34Í/^§¯oz¼ƒÙ9 ®6»¿þé‰iúµðº¢Á>>sx¹9eÙ9D°;#ö„ ¥¹¢0bgaIV§åTOOP4²{†—ws¢h¨Ï .ž ß¶sÏi¨Ïpèƒõvæ×4c¼x‘¾¸i”uPnÄU<<ÒAyKF@Ƨijf¼XÛ4FªÒÆb4¤8²aœõÃÅ‘ú¬æoÚéBvœ…jIV§eÛÖ GWUɘB®š³ˆ†‘üÞó­‡°/{Yo:÷DÈâ¤H׺½ºft‹ékšŽ‘Œ±ƒrYìágdG‰¨:x>qK#'BN‰«Ž½À…p}×;{¯±ýêùbå žžp¶Iפ#ÒM}ú@ÁÃ5.4ûõ%<±3UbêÑ@‹n(t½5ÂÓÎNmêÐZh-©ëTVІæîF¬ŸOO²¶(È–¹ñOj—Ý?·Û®ë§h äŠøÿÿìÛÁ € EÑÿÿë¶-ŸX:Žçà>l .h¢1—OªåöEª ý>ÇÍ\>¦üLä ï%6®Ý¯ˆT‰ 8ÑD¾Œ†¡5ÿ\`%ÑDDit øÓÿÿœY>u"°IEND®B`‚}DÐÉêyùºÎŒ‚ªK© _Ref153612150}DÐÉêyùºÎŒ‚ªK© _Ref153612128}DÐÉêyùºÎŒ‚ªK© _Ref153557607}DÐÉêyùºÎŒ‚ªK© _Ref153590626{DÐÉêyùºÎŒ‚ªK©  _Ref43727925}DÐÉêyùºÎŒ‚ªK© _Ref203481633}DÐÉêyùºÎŒ‚ªK© _Ref153590626{DÐÉêyùºÎŒ‚ªK©  _Ref43727925}DÐÉêyùºÎŒ‚ªK© _Ref153612650}DÐÉêyùºÎŒ‚ªK© _Ref153603854{DÐÉêyùºÎŒ‚ªK©  _Ref36888765}DÐÉêyùºÎŒ‚ªK© _Ref185246210}DÐÉêyùºÎŒ‚ªK© _Ref185261956}DÐÉêyùºÎŒ‚ªK© _Ref185238094{DÐÉêyùºÎŒ‚ªK©  _Ref46747184yDÐÉêyùºÎŒ‚ªK©  _Ref5709751yDÐÉêyùºÎŒ‚ªK©  _Ref6058882yDÐÉêyùºÎŒ‚ªK©  _Ref6029952yDÐÉêyùºÎŒ‚ªK©  _Ref6029971}DÐÉêyùºÎŒ‚ªK© _Ref185238094}DÐÉêyùºÎŒ‚ªK© _Ref185238094}DÐÉêyùºÎŒ‚ªK© _Ref185238094yDÐÉêyùºÎŒ‚ªK©  _Ref6042344yDÐÉêyùºÎŒ‚ªK©  _Ref6060179yDÐÉêyùºÎŒ‚ªK©  _Ref6030571yDÐÉêyùºÎŒ‚ªK©  _Ref6042851yDÐÉêyùºÎŒ‚ªK©  _Ref6043386}DÐÉêyùºÎŒ‚ªK© _Ref182996929}DÐÉêyùºÎŒ‚ªK© _Ref182997376}DÐÉêyùºÎŒ‚ªK© _Ref182997381yDÐÉêyùºÎŒ‚ªK©  _Ref6042344}DÐÉêyùºÎŒ‚ªK© _Ref182997376}DÐÉêyùºÎŒ‚ªK© _Ref182997381{DÐÉêyùºÎŒ‚ªK©  _Ref42941679yDÐÉêyùºÎŒ‚ªK©  _Ref6046402}DÐÉêyùºÎŒ‚ªK© _Ref182996673}DÐÉêyùºÎŒ‚ªK© _Ref231889747{DÐÉêyùºÎŒ‚ªK©  _Ref62467260{DÐÉêyùºÎŒ‚ªK©  _Ref36890908{DÐÉêyùºÎŒ‚ªK©  _Ref62467260yDÐÉêyùºÎŒ‚ªK©  _Ref6049927}DÐÉêyùºÎŒ‚ªK© _Ref182995906yDÐÉêyùºÎŒ‚ªK©  _Ref6049927}DÐÉêyùºÎŒ‚ªK© _Ref182997376}DÐÉêyùºÎŒ‚ªK© _Ref182997381}DÐÉêyùºÎŒ‚ªK© _Ref182740974yDÐÉêyùºÎŒ‚ªK©  _Ref6043386yDÐÉêyùºÎŒ‚ªK©  _Ref6055322}DÐÉêyùºÎŒ‚ªK© _Ref185257870}DÐÉêyùºÎŒ‚ªK© _Ref153617304yDÐÉêyùºÎŒ‚ªK©  _Ref6060179yDÐÉêyùºÎŒ‚ªK©  _Ref6030571}DÐÉêyùºÎŒ‚ªK© _Ref153617348{DÐÉêyùºÎŒ‚ªK©  _Ref45025338{DÐÉêyùºÎŒ‚ªK©  _Ref45025338}DÐÉêyùºÎŒ‚ªK© _Ref153617348yDÐÉêyùºÎŒ‚ªK©  _Ref6058085}DÐÉêyùºÎŒ‚ªK© _Ref153617348yDÐÉêyùºÎŒ‚ªK©  _Ref6058882}DÐÉêyùºÎŒ‚ªK© _Ref153617348yDÐÉêyùºÎŒ‚ªK©  _Ref6030571}DÐÉêyùºÎŒ‚ªK© _Ref103576461}DÐÉêyùºÎŒ‚ªK© _Ref103576458{DÐÉêyùºÎŒ‚ªK©  _Ref46895327{DÐÉêyùºÎŒ‚ªK©  _Ref46895428{DÐÉêyùºÎŒ‚ªK©  _Ref46823145{DÐÉêyùºÎŒ‚ªK©  _Ref46895473{DÐÉêyùºÎŒ‚ªK©  _Ref46895489{DÐÉêyùºÎŒ‚ªK©  _Ref42944330{DÐÉêyùºÎŒ‚ªK©  _Ref46752884{DÐÉêyùºÎŒ‚ªK©  _Ref46896711{DÐÉêyùºÎŒ‚ªK©  _Ref55271118{DÐÉêyùºÎŒ‚ªK©  _Ref46896711{DÐÉêyùºÎŒ‚ªK©  _Ref55271118{DÐÉêyùºÎŒ‚ªK©  _Ref46904847{DÐÉêyùºÎŒ‚ªK©  _Ref46908455{DÐÉêyùºÎŒ‚ªK©  _Ref55271118}DÐÉêyùºÎŒ‚ªK© _Ref169607904{DÐÉêyùºÎŒ‚ªK©  _Ref47156991{DÐÉêyùºÎŒ‚ªK©  _Ref46904847{DÐÉêyùºÎŒ‚ªK©  _Ref47156991{DÐÉêyùºÎŒ‚ªK©  _Ref46904847yDÐÉêyùºÎŒ‚ªK©  _Ref6046402{DÐÉêyùºÎŒ‚ªK©  _Ref47164085{DÐÉêyùºÎŒ‚ªK©  _Ref90895285{DÐÉêyùºÎŒ‚ªK©  _Ref47164085}DÐÉêyùºÎŒ‚ªK© _Ref135023442}DÐÉêyùºÎŒ‚ªK© _Ref135023442}DÐÉêyùºÎŒ‚ªK© _Ref133810323}DÐÉêyùºÎŒ‚ªK© _Ref207626203{DÐÉêyùºÎŒ‚ªK©  _Ref90895148{DÐÉêyùºÎŒ‚ªK©  _Ref90895208{DÐÉêyùºÎŒ‚ªK©  _Ref70164454{DÐÉêyùºÎŒ‚ªK©  _Ref43008774{DÐÉêyùºÎŒ‚ªK©  _Ref43008774{DÐÉêyùºÎŒ‚ªK©  _Ref13981914yDÐÉêyùºÎŒ‚ªK©  _Ref5614672{DÐÉêyùºÎŒ‚ªK©  _Ref43008774{DÐÉêyùºÎŒ‚ªK©  _Ref45371286{DÐÉêyùºÎŒ‚ªK©  _Ref45371414}DÐÉêyùºÎŒ‚ªK© _Ref153699553}DÐÉêyùºÎŒ‚ªK© _Ref153699553}DÐÉêyùºÎŒ‚ªK© _Ref185261956}DÐÉêyùºÎŒ‚ªK© _Ref204925451}DÐÉêyùºÎŒ‚ªK© _Ref182995906}DÐÉêyùºÎŒ‚ªK© _Ref231889747{DÐÉêyùºÎŒ‚ªK©  _Ref43008774{DÐÉêyùºÎŒ‚ªK©  _Ref43727925{DÐÉêyùºÎŒ‚ªK©  _Ref43008774{DÐÉêyùºÎŒ‚ªK©  _Ref43727925{DÐÉêyùºÎŒ‚ªK©  _Ref47167783{DÐÉêyùºÎŒ‚ªK©  _Ref46754571{DÐÉêyùºÎŒ‚ªK©  _Ref47168251{DÐÉêyùºÎŒ‚ªK©  _Ref46754571}DÐÉêyùºÎŒ‚ªK© _Ref153681044{DÐÉêyùºÎŒ‚ªK©  _Ref47168523{DÐÉêyùºÎŒ‚ªK©  _Ref47168540{DÐÉêyùºÎŒ‚ªK©  _Ref47171157{DÐÉêyùºÎŒ‚ªK©  _Ref47169243{DÐÉêyùºÎŒ‚ªK©  _Ref42941679{DÐÉêyùºÎŒ‚ªK©  _Ref47170147{DÐÉêyùºÎŒ‚ªK©  _Ref47171157{DÐÉêyùºÎŒ‚ªK©  _Ref43727921{DÐÉêyùºÎŒ‚ªK©  _Ref43727928}DÐÉêyùºÎŒ‚ªK© _Ref185257870{DÐÉêyùºÎŒ‚ªK©  _Ref78024414{DÐÉêyùºÎŒ‚ªK©  _Ref43727921{DÐÉêyùºÎŒ‚ªK©  _Ref68495073{DÐÉêyùºÎŒ‚ªK©  _Ref78024414}DÐÉêyùºÎŒ‚ªK© _Ref185246110{DÐÉêyùºÎŒ‚ªK©  _Ref47173451{DÐÉêyùºÎŒ‚ªK©  _Ref47173451{DÐÉêyùºÎŒ‚ªK©  _Ref42944330{DÐÉêyùºÎŒ‚ªK©  _Ref42943895{DÐÉêyùºÎŒ‚ªK©  _Ref42944330{DÐÉêyùºÎŒ‚ªK©  _Ref55271118{DÐÉêyùºÎŒ‚ªK©  _Ref45368706{DÐÉêyùºÎŒ‚ªK©  _Ref55271118}DÐÉêyùºÎŒ‚ªK© _Ref169609101}DÐÉêyùºÎŒ‚ªK© _Ref169607904yDÐÉêyùºÎŒ‚ªK©  _Ref5625615{DÐÉêyùºÎŒ‚ªK©  _Ref55271118yDÐÉêyùºÎŒ‚ªK©  _Ref6129297yDÐÉêyùºÎŒ‚ªK©  _Ref6060179}DÐÉêyùºÎŒ‚ªK© _Ref247361819{DÐÉêyùºÎŒ‚ªK©  _Ref42941679}DÐÉêyùºÎŒ‚ªK© _Ref153291752}DÐÉêyùºÎŒ‚ªK© _Ref153732324}DÐÉêyùºÎŒ‚ªK© _Ref153288035{DÐÉêyùºÎŒ‚ªK©  _Ref55274563}DÐÉêyùºÎŒ‚ªK© _Ref153732596{DÐÉêyùºÎŒ‚ªK©  _Ref46752884{DÐÉêyùºÎŒ‚ªK©  _Ref47262189{DÐÉêyùºÎŒ‚ªK©  _Ref46823145}DÐÉêyùºÎŒ‚ªK© _Ref247356244}DÐÉêyùºÎŒ‚ªK© _Ref247356327{DÐÉêyùºÎŒ‚ªK©  _Ref46752884{DÐÉêyùºÎŒ‚ªK©  _Ref47262189{DÐÉêyùºÎŒ‚ªK©  _Ref46752884{DÐÉêyùºÎŒ‚ªK©  _Ref47262189{DÐÉêyùºÎŒ‚ªK©  _Ref46752884{DÐÉêyùºÎŒ‚ªK©  _Ref47262189{DÐÉêyùºÎŒ‚ªK©  _Ref46752884{DÐÉêyùºÎŒ‚ªK©  _Ref47262189{DÐÉêyùºÎŒ‚ªK©  _Ref42941679{DÐÉêyùºÎŒ‚ªK©  _Ref43008774}DÐÉêyùºÎŒ‚ªK© _Ref166651506{DÐÉêyùºÎŒ‚ªK©  _Ref46896711{DÐÉêyùºÎŒ‚ªK©  _Ref46752884{DÐÉêyùºÎŒ‚ªK©  _Ref46896711{DÐÉêyùºÎŒ‚ªK©  _Ref46752884{DÐÉêyùºÎŒ‚ªK©  _Ref54100850{DÐÉêyùºÎŒ‚ªK©  _Ref46896711}DÐÉêyùºÎŒ‚ªK© _Ref247356737{DÐÉêyùºÎŒ‚ªK©  _Ref46896711{DÐÉêyùºÎŒ‚ªK©  _Ref46896711{DÐÉêyùºÎŒ‚ªK©  _Ref46896711{DÐÉêyùºÎŒ‚ªK©  _Ref46896711{DÐÉêyùºÎŒ‚ªK©  _Ref46896711{DÐÉêyùºÎŒ‚ªK©  _Ref46896711{DÐÉêyùºÎŒ‚ªK©  _Ref46896711{DÐÉêyùºÎŒ‚ªK©  _Ref46896711{DÐÉêyùºÎŒ‚ªK©  _Ref46896711{DÐÉêyùºÎŒ‚ªK©  _Ref55274563{DÐÉêyùºÎŒ‚ªK©  _Ref46896711}DÐÉêyùºÎŒ‚ªK© _Ref111000885{DÐÉêyùºÎŒ‚ªK©  _Ref46896711{DÐÉêyùºÎŒ‚ªK©  _Ref46908455}DÐÉêyùºÎŒ‚ªK© _Ref111000885}DÐÉêyùºÎŒ‚ªK© _Ref111000885}DÐÉêyùºÎŒ‚ªK© _Ref131305143{DÐÉêyùºÎŒ‚ªK©  _Ref43727925}DÐÉêyùºÎŒ‚ªK© _Ref111000885{DÐÉêyùºÎŒ‚ªK©  _Ref43727925}DÐÉêyùºÎŒ‚ªK© _Ref111000885}DÐÉêyùºÎŒ‚ªK© _Ref153732324}DÐÉêyùºÎŒ‚ªK© _Ref153732324žDÐÉêyùºÎŒ‚ªK© ÀFSDK_manual.pdfÿÿ­Þ}DÐÉêyùºÎŒ‚ªK© _Ref207634778}DÐÉêyùºÎŒ‚ªK© _Ref153776689{DÐÉêyùºÎŒ‚ªK©  _Ref78024414}DÐÉêyùºÎŒ‚ªK© _Ref153776689{DÐÉêyùºÎŒ‚ªK©  _Ref78024414{DÐÉêyùºÎŒ‚ªK©  _Ref55271118}DÐÉêyùºÎŒ‚ªK© _Ref207634778{DÐÉêyùºÎŒ‚ªK©  _Ref46752884}DÐÉêyùºÎŒ‚ªK© _Ref153732324}DÐÉêyùºÎŒ‚ªK© _Ref111000885{DÐÉêyùºÎŒ‚ªK©  _Ref47451048}DÐÉêyùºÎŒ‚ªK© _Ref153774103}DÐÉêyùºÎŒ‚ªK© _Ref153707807{DÐÉêyùºÎŒ‚ªK©  _Ref45371286}DÐÉêyùºÎŒ‚ªK© _Ref153707807}DÐÉêyùºÎŒ‚ªK© _Ref153731855}DÐÉêyùºÎŒ‚ªK© _Ref185246110}DÐÉêyùºÎŒ‚ªK© _Ref153704184}DÐÉêyùºÎŒ‚ªK© _Ref201668435}DÐÉêyùºÎŒ‚ªK© _Ref185246112{DÐÉêyùºÎŒ‚ªK©  _Ref47173451}DÐÉêyùºÎŒ‚ªK© _Ref153704184}DÐÉêyùºÎŒ‚ªK© _Ref185257870{DÐÉêyùºÎŒ‚ªK©  _Ref43728908yDÐÉêyùºÎŒ‚ªK©  _Ref6030156{DÐÉêyùºÎŒ‚ªK©  _Ref43728908{DÐÉêyùºÎŒ‚ªK©  _Ref43728908}DÐÉêyùºÎŒ‚ªK© _Ref153707807{DÐÉêyùºÎŒ‚ªK©  _Ref43728908}DÐÉêyùºÎŒ‚ªK© _Ref153765172yDÐÉêyùºÎŒ‚ªK©  _Ref6030571{DÐÉêyùºÎŒ‚ªK©  _Ref47173451}DÐÉêyùºÎŒ‚ªK© _Ref153764303}DÐÉêyùºÎŒ‚ªK© _Ref153765172}DÐÉêyùºÎŒ‚ªK© _Ref153764303{DÐÉêyùºÎŒ‚ªK©  _Ref47173292}DÐÉêyùºÎŒ‚ªK© _Ref247355579}DÐÉêyùºÎŒ‚ªK© _Ref153776695}DÐÉêyùºÎŒ‚ªK© _Ref153776692}DÐÉêyùºÎŒ‚ªK© _Ref153776693}DÐÉêyùºÎŒ‚ªK© _Ref153776694}DÐÉêyùºÎŒ‚ªK© _Ref185238094}DÐÉêyùºÎŒ‚ªK© _Ref185238094{DÐÉêyùºÎŒ‚ªK©  _Ref47173394}DÐÉêyùºÎŒ‚ªK© _Ref185246110}DÐÉêyùºÎŒ‚ªK© _Ref185238094}DÐÉêyùºÎŒ‚ªK© _Ref207618734{DÐÉêyùºÎŒ‚ªK©  _Ref47173394}DÐÉêyùºÎŒ‚ªK© _Ref153764303{DÐÉêyùºÎŒ‚ªK©  _Ref47173451}DÐÉêyùºÎŒ‚ªK© _Ref153765172{DÐÉêyùºÎŒ‚ªK©  _Ref47172480{DÐÉêyùºÎŒ‚ªK©  _Ref47864390{DÐÉêyùºÎŒ‚ªK©  _Ref78024414}DÐÉêyùºÎŒ‚ªK© _Ref153776724{DÐÉêyùºÎŒ‚ªK©  _Ref47173394{DÐÉêyùºÎŒ‚ªK©  _Ref47173394{DÐÉêyùºÎŒ‚ªK©  _Ref47173394{DÐÉêyùºÎŒ‚ªK©  _Ref47173394{DÐÉêyùºÎŒ‚ªK©  _Ref46754571}DÐÉêyùºÎŒ‚ªK© _Ref153765172{DÐÉêyùºÎŒ‚ªK©  _Ref42589436{DÐÉêyùºÎŒ‚ªK©  _Ref47865711{DÐÉêyùºÎŒ‚ªK©  _Ref47173451}DÐÉêyùºÎŒ‚ªK© _Ref153776799}DÐÉêyùºÎŒ‚ªK© _Ref153765172{DÐÉêyùºÎŒ‚ªK©  _Ref47173451}DÐÉêyùºÎŒ‚ªK© _Ref153776799{DÐÉêyùºÎŒ‚ªK©  _Ref47864390}DÐÉêyùºÎŒ‚ªK© _Ref153776694{DÐÉêyùºÎŒ‚ªK©  _Ref47173451}DÐÉêyùºÎŒ‚ªK© _Ref153776693{DÐÉêyùºÎŒ‚ªK©  _Ref47173451}DÐÉêyùºÎŒ‚ªK© _Ref153776799}DÐÉêyùºÎŒ‚ªK© _Ref153765172{DÐÉêyùºÎŒ‚ªK©  _Ref47172480}DÐÉêyùºÎŒ‚ªK© _Ref153776799}DÐÉêyùºÎŒ‚ªK© _Ref153776799{DÐÉêyùºÎŒ‚ªK©  _Ref47260717{DÐÉêyùºÎŒ‚ªK©  _Ref46752884{DÐÉêyùºÎŒ‚ªK©  _Ref47262189}DÐÉêyùºÎŒ‚ªK© _Ref166648484{DÐÉêyùºÎŒ‚ªK©  _Ref73442286{DÐÉêyùºÎŒ‚ªK©  _Ref47169796{DÐÉêyùºÎŒ‚ªK©  _Ref46754571{DÐÉêyùºÎŒ‚ªK©  _Ref43008774{DÐÉêyùºÎŒ‚ªK©  _Ref43008774{DÐÉêyùºÎŒ‚ªK©  _Ref45001933{DÐÉêyùºÎŒ‚ªK©  _Ref43008774{DÐÉêyùºÎŒ‚ªK©  _Ref43008774{DÐÉêyùºÎŒ‚ªK©  _Ref43008774{DÐÉêyùºÎŒ‚ªK©  _Ref43008774}DÐÉêyùºÎŒ‚ªK© _Ref182995906}DÐÉêyùºÎŒ‚ªK© _Ref231890048}DÐÉêyùºÎŒ‚ªK© _Ref153700641}DÐÉêyùºÎŒ‚ªK© _Ref153700641}DÐÉêyùºÎŒ‚ªK© _Ref166648484{DÐÉêyùºÎŒ‚ªK©  _Ref70164511{DÐÉêyùºÎŒ‚ªK©  _Ref43008774{DÐÉêyùºÎŒ‚ªK©  _Ref69047370{DÐÉêyùºÎŒ‚ªK©  _Ref47164085{DÐÉêyùºÎŒ‚ªK©  _Ref47164079{DÐÉêyùºÎŒ‚ªK©  _Ref90895285{DÐÉêyùºÎŒ‚ªK©  _Ref43726555{DÐÉêyùºÎŒ‚ªK©  _Ref46754571{DÐÉêyùºÎŒ‚ªK©  _Ref43727921{DÐÉêyùºÎŒ‚ªK©  _Ref43727925{DÐÉêyùºÎŒ‚ªK©  _Ref43727928{DÐÉêyùºÎŒ‚ªK©  _Ref43728215{DÐÉêyùºÎŒ‚ªK©  _Ref43727925{DÐÉêyùºÎŒ‚ªK©  _Ref43727928{DÐÉêyùºÎŒ‚ªK©  _Ref43727925{DÐÉêyùºÎŒ‚ªK©  _Ref43727928{DÐÉêyùºÎŒ‚ªK©  _Ref43728461{DÐÉêyùºÎŒ‚ªK©  _Ref78024414{DÐÉêyùºÎŒ‚ªK©  _Ref42589436{DÐÉêyùºÎŒ‚ªK©  _Ref47173451{DÐÉêyùºÎŒ‚ªK©  _Ref42943895{DÐÉêyùºÎŒ‚ªK©  _Ref43728908{DÐÉêyùºÎŒ‚ªK©  _Ref46750086{DÐÉêyùºÎŒ‚ªK©  _Ref47173451{DÐÉêyùºÎŒ‚ªK©  _Ref42589436{DÐÉêyùºÎŒ‚ªK©  _Ref42672298{DÐÉêyùºÎŒ‚ªK©  _Ref47173451{DÐÉêyùºÎŒ‚ªK©  _Ref46752884{DÐÉêyùºÎŒ‚ªK©  _Ref69052620{DÐÉêyùºÎŒ‚ªK©  _Ref69052620{DÐÉêyùºÎŒ‚ªK©  _Ref43727925{DÐÉêyùºÎŒ‚ªK©  _Ref43727928}DÐÉêyùºÎŒ‚ªK© _Ref153776799{DÐÉêyùºÎŒ‚ªK©  _Ref47173451{DÐÉêyùºÎŒ‚ªK©  _Ref47173451}DÐÉêyùºÎŒ‚ªK© _Ref203474873}DÐÉêyùºÎŒ‚ªK© _Ref203474654{DÐÉêyùºÎŒ‚ªK©  _Ref58909011{DÐÉêyùºÎŒ‚ªK©  _Ref58909011{DÐÉêyùºÎŒ‚ªK©  _Ref58909800{DÐÉêyùºÎŒ‚ªK©  _Ref58909011{DÐÉêyùºÎŒ‚ªK©  _Ref78024414}DÐÉêyùºÎŒ‚ªK© _Ref135023442}DÐÉêyùºÎŒ‚ªK© _Ref133810323}DÐÉêyùºÎŒ‚ªK© _Ref182743880}DÐÉêyùºÎŒ‚ªK© _Ref153703095}DÐÉêyùºÎŒ‚ªK© _Ref153681044yDÐÉêyùºÎŒ‚ªK©  _Ref5608796}DÐÉêyùºÎŒ‚ªK© _Ref166649222yDÐÉêyùºÎŒ‚ªK©  _Ref5609191}DÐÉêyùºÎŒ‚ªK© _Ref166649220{DÐÉêyùºÎŒ‚ªK©  _Ref43729255{DÐÉêyùºÎŒ‚ªK©  _Ref43729255{DÐÉêyùºÎŒ‚ªK©  _Ref47172128{DÐÉêyùºÎŒ‚ªK©  _Ref47172128{DÐÉêyùºÎŒ‚ªK©  _Ref47172128{DÐÉêyùºÎŒ‚ªK©  _Ref42943854{DÐÉêyùºÎŒ‚ªK©  _Ref42943895{DÐÉêyùºÎŒ‚ªK©  _Ref42943895{DÐÉêyùºÎŒ‚ªK©  _Ref42943895{DÐÉêyùºÎŒ‚ªK©  _Ref36896289{DÐÉêyùºÎŒ‚ªK©  _Ref13986562{DÐÉêyùºÎŒ‚ªK©  _Ref36896793}DÐÉêyùºÎŒ‚ªK© _Ref185246110{DÐÉêyùºÎŒ‚ªK©  _Ref47163749{DÐÉêyùºÎŒ‚ªK©  _Ref47169796{DÐÉêyùºÎŒ‚ªK©  _Ref42943895{DÐÉêyùºÎŒ‚ªK©  _Ref47171780{DÐÉêyùºÎŒ‚ªK©  _Ref47171842{DÐÉêyùºÎŒ‚ªK©  _Ref47171876{DÐÉêyùºÎŒ‚ªK©  _Ref42944330{DÐÉêyùºÎŒ‚ªK©  _Ref45367951}DÐÉêyùºÎŒ‚ªK© _Ref182743880{DÐÉêyùºÎŒ‚ªK©  _Ref13986080yDÐÉêyùºÎŒ‚ªK©  _Ref5702037{DÐÉêyùºÎŒ‚ªK©  _Ref47171963{DÐÉêyùºÎŒ‚ªK©  _Ref47172128yDÐÉêyùºÎŒ‚ªK©  _Ref6117078{DÐÉêyùºÎŒ‚ªK©  _Ref47174498yDÐÉêyùºÎŒ‚ªK©  _Ref8187404{DÐÉêyùºÎŒ‚ªK©  _Ref71016088}DÐÉêyùºÎŒ‚ªK© _Ref153708057yDÐÉêyùºÎŒ‚ªK©  _Ref8187404}DÐÉêyùºÎŒ‚ªK© _Ref153707807}DÐÉêyùºÎŒ‚ªK© _Ref153708057}DÐÉêyùºÎŒ‚ªK© _Ref153710706yDÐÉêyùºÎŒ‚ªK©  _Ref8187433yDÐÉêyùºÎŒ‚ªK©  _Ref8187404{DÐÉêyùºÎŒ‚ªK©  _Ref71016088yDÐÉêyùºÎŒ‚ªK©  _Ref8187433yDÐÉêyùºÎŒ‚ªK©  _Ref8187404}DÐÉêyùºÎŒ‚ªK© _Ref153708057}DÐÉêyùºÎŒ‚ªK© _Ref153707807yDÐÉêyùºÎŒ‚ªK©  _Ref8187433}DÐÉêyùºÎŒ‚ªK© _Ref153708057}DÐÉêyùºÎŒ‚ªK© _Ref153710706{DÐÉêyùºÎŒ‚ªK©  _Ref47781675{DÐÉêyùºÎŒ‚ªK©  _Ref47781653yDÐÉêyùºÎŒ‚ªK©  _Ref6030156{DÐÉêyùºÎŒ‚ªK©  _Ref47173451{DÐÉêyùºÎŒ‚ªK©  _Ref43728908{DÐÉêyùºÎŒ‚ªK©  _Ref47779943}DÐÉêyùºÎŒ‚ªK© _Ref153707807}DÐÉêyùºÎŒ‚ªK© _Ref153707807{DÐÉêyùºÎŒ‚ªK©  _Ref43728908}DÐÉêyùºÎŒ‚ªK© _Ref153731855{DÐÉêyùºÎŒ‚ªK©  _Ref68495073{DÐÉêyùºÎŒ‚ªK©  _Ref43727921}DÐÉêyùºÎŒ‚ªK© _Ref135023442}DÐÉêyùºÎŒ‚ªK© _Ref135023442}DÐÉêyùºÎŒ‚ªK© _Ref133810323{DÐÉêyùºÎŒ‚ªK©  _Ref47784397{DÐÉêyùºÎŒ‚ªK©  _Ref47172128{DÐÉêyùºÎŒ‚ªK©  _Ref47779943{DÐÉêyùºÎŒ‚ªK©  _Ref47173394{DÐÉêyùºÎŒ‚ªK©  _Ref46752884{DÐÉêyùºÎŒ‚ªK©  _Ref47173451{DÐÉêyùºÎŒ‚ªK©  _Ref47173394{DÐÉêyùºÎŒ‚ªK©  _Ref46750086{DÐÉêyùºÎŒ‚ªK©  _Ref47173394{DÐÉêyùºÎŒ‚ªK©  _Ref47173394{DÐÉêyùºÎŒ‚ªK©  _Ref47173451{DÐÉêyùºÎŒ‚ªK©  _Ref47173394{DÐÉêyùºÎŒ‚ªK©  _Ref47845006{DÐÉêyùºÎŒ‚ªK©  _Ref47845006{DÐÉêyùºÎŒ‚ªK©  _Ref66078569{DÐÉêyùºÎŒ‚ªK©  _Ref66078569{DÐÉêyùºÎŒ‚ªK©  _Ref47173394{DÐÉêyùºÎŒ‚ªK©  _Ref66078569{DÐÉêyùºÎŒ‚ªK©  _Ref47173451{DÐÉêyùºÎŒ‚ªK©  _Ref47173292{DÐÉêyùºÎŒ‚ªK©  _Ref47173451}DÐÉêyùºÎŒ‚ªK© _Ref153765172}DÐÉêyùºÎŒ‚ªK© _Ref153765172{DÐÉêyùºÎŒ‚ªK©  _Ref42589436{DÐÉêyùºÎŒ‚ªK©  _Ref47867141{DÐÉêyùºÎŒ‚ªK©  _Ref47867143{DÐÉêyùºÎŒ‚ªK©  _Ref47867144{DÐÉêyùºÎŒ‚ªK©  _Ref47784098{DÐÉêyùºÎŒ‚ªK©  _Ref47867609{DÐÉêyùºÎŒ‚ªK©  _Ref47867926{DÐÉêyùºÎŒ‚ªK©  _Ref47871470{DÐÉêyùºÎŒ‚ªK©  _Ref47871522{DÐÉêyùºÎŒ‚ªK©  _Ref47867954{DÐÉêyùºÎŒ‚ªK©  _Ref47262189{DÐÉêyùºÎŒ‚ªK©  _Ref47784099{DÐÉêyùºÎŒ‚ªK©  _Ref63052833}DÐÉêyùºÎŒ‚ªK© _Ref130893908}DÐÉêyùºÎŒ‚ªK© _Ref207637531{DÐÉêyùºÎŒ‚ªK©  _Ref63052833{DÐÉêyùºÎŒ‚ªK©  _Ref47869783{DÐÉêyùºÎŒ‚ªK©  _Ref47871769{DÐÉêyùºÎŒ‚ªK©  _Ref47871769{DÐÉêyùºÎŒ‚ªK©  _Ref47867926{DÐÉêyùºÎŒ‚ªK©  _Ref63053303{DÐÉêyùºÎŒ‚ªK©  _Ref47864390{DÐÉêyùºÎŒ‚ªK©  _Ref46752884{DÐÉêyùºÎŒ‚ªK©  _Ref47872399{DÐÉêyùºÎŒ‚ªK©  _Ref47872399{DÐÉêyùºÎŒ‚ªK©  _Ref47173394}DÐÉêyùºÎŒ‚ªK© _Ref153776799}DÐÉêyùºÎŒ‚ªK© _Ref133745663{DÐÉêyùºÎŒ‚ªK©  _Ref47164079{DÐÉêyùºÎŒ‚ªK©  _Ref90895285}DÐÉêyùºÎŒ‚ªK© _Ref133810323{DÐÉêyùºÎŒ‚ªK©  _Ref43727921{DÐÉêyùºÎŒ‚ªK©  _Ref45367951}DÐÉêyùºÎŒ‚ªK© _Ref133832449}DÐÉêyùºÎŒ‚ªK© _Ref133830177}DÐÉêyùºÎŒ‚ªK© _Ref133831852{DÐÉêyùºÎŒ‚ªK©  _Ref47170147yDÐÉêyùºÎŒ‚ªK©  _Ref6030571}DÐÉêyùºÎŒ‚ªK© _Ref135023800}DÐÉêyùºÎŒ‚ªK© _Ref153284855{DÐÉêyùºÎŒ‚ªK©  _Ref47164079{DÐÉêyùºÎŒ‚ªK©  _Ref47164085}DÐÉêyùºÎŒ‚ªK© _Ref135023442{DÐÉêyùºÎŒ‚ªK©  _Ref47164079žDÐÉêyùºÎŒ‚ªK© ÀFSDK_manual.pdfÿÿ­Þ}DÐÉêyùºÎŒ‚ªK© _Ref184460000{DÐÉêyùºÎŒ‚ªK©  _Ref90895148}DÐÉêyùºÎŒ‚ªK© _Ref247361078{DÐÉêyùºÎŒ‚ªK©  _Ref47164079{DÐÉêyùºÎŒ‚ªK©  _Ref47164085}DÐÉêyùºÎŒ‚ªK© _Ref135023442{DÐÉêyùºÎŒ‚ªK©  _Ref47164079}DÐÉêyùºÎŒ‚ªK© _Ref153889197}DÐÉêyùºÎŒ‚ªK© _Ref232415540}DÐÉêyùºÎŒ‚ªK© _Ref232415549{DÐÉêyùºÎŒ‚ªK©  _Ref45367951{DÐÉêyùºÎŒ‚ªK©  _Ref46896711{DÐÉêyùºÎŒ‚ªK©  _Ref90894483{DÐÉêyùºÎŒ‚ªK©  _Ref90894479{DÐÉêyùºÎŒ‚ªK©  _Ref46896711}DÐÉêyùºÎŒ‚ªK© _Ref153291752{DÐÉêyùºÎŒ‚ªK©  _Ref46752884}DÐÉêyùºÎŒ‚ªK© _Ref153291752{DÐÉêyùºÎŒ‚ªK©  _Ref46752884DÐÉêyùºÎŒ‚ªK© àÉêyùºÎŒ‚ªK© ”http://www.openmobilealliance.org/release_program/ds_v12.htmlyXô;H¯,‚]Ä…'c¥«{DÐÉêyùºÎŒ‚ªK©  _Ref47451430{DÐÉêyùºÎŒ‚ªK©  _Ref47451048»DÐÉêyùºÎŒ‚ªK© àÉêyùºÎŒ‚ªK© Jhttp://www.synthesis.ch/yXô;H¯,‚]Ä…'c¥«»DÐÉêyùºÎŒ‚ªK© àÉêyùºÎŒ‚ªK© Jhttp://www.synthesis.ch/yXô;H¯,‚]Ä…'c¥«u i@@ñÿ@ StandardCJOJQJ_HmH sH tHN@aN Überschrift 1$$ & Fc¤ð¤<*$@&KHR@aR Überschrift 2$$ & Fc¤à¤ð@& 6mHsHJ@aJ Überschrift 3$$ & Fc¤à¤ð@&6J@aJ Überschrift 4$$ & Fc¤à¤ð@&6H@aH Überschrift 5 & Fc¤ð¤<@&6CJH@H Überschrift 6 & Fc¤ð¤<@&6CJD@D Überschrift 7 & Fc¤ð¤<@&CJH@H Überschrift 8 & Fc¤ð¤<@&6CJJ @J Überschrift 9 & Fc¤ð¤<@& 56CJBA@òÿ¡B Absatz-Standardschriftartb0@òb Aufzählungszeichen+ & F ƹh„e„›þ¤P¤P^„e`„›þ0 @0 Fußzeile  Æ_¾$2@2 Kopfzeile  Æ_¾$JþO"J List *+ & F ÆÔЄʄ›þ¤x¤x^„Ê`„›þ$)@¢1$ SeitenzahlD>@aBD Titel$¤ð¤<@&a$CJ0KHmH sH u(U@¢Q( Hyperlink>*B*RþObR console*„°„h$d%d&d'd]„°^„hOJQJLþOarL Zwischentitel$$¤ð¤xCJmH sH u:V@¢: BesuchterHyperlink>*B* @C@’@ Textkörper-Einzug dà¤xR@aR Verzeichnis 1 Æp# „l]„lCJaJmHnHu^@^ Verzeichnis 4" Æp# „l„8„˜þ]„l^„8`„˜þaJmHnHuX@X Verzeichnis 2 Æp# „l„ð]„l^„ð5aJmHnHuV@V Verzeichnis 3 Æp# „l„à]„l^„àaJmHnHu6@6 Verzeichnis 5 „À^„À6@6 Verzeichnis 6 „°^„°6@6 Verzeichnis 7 „ ^„ 6@6 Verzeichnis 8 !„^„6@6 Verzeichnis 9 "„€^„€8Y@28 Dokumentstruktur#-D .B@B. Textkörper$$a$BþOñÿRB Font_text%CJOJQJ_HmHsHtHDþOñÿbD Font_titel&CJOJQJ_HmHsHtH<þO< Tagheader'$$„V„ªù^„V`„ªù0þO¢0 tagheadertitle5hþOñÿ’h TbT.TblTxtLft)1$d$ÿ¤´¤x ÆB*CJOJQJ_HmH sH tHBþO¢B Normal (Web) *¤d¤dB*mH sH uR#@RAbbildungsverzeichnis + Æd# mHnHuF%@ÂF Umschlagabsenderadresse,CJ K@ Anrede-D6@âD Aufzählungszeichen 2 . & FD7@òD Aufzählungszeichen 3 / & FD8@D Aufzählungszeichen 4 0 & FD9@D Aufzählungszeichen 5 1 & F8"@8 Beschriftung 2¤x¤x5:T@2: Blocktext3„ „ ¤x]„ ^„ L@ Datum40+@R0 Endnotentext5CJDO@D Fuß/-Endnotenüberschrift60@r0 Fußnotentext7CJ0?@‚0 Grußformel 8„œ^„œ2 @2 Index 19„ð„ÿ^„ð`„ÿ2 @2 Index 2:„à„ÿ^„à`„ÿ2 @2 Index 3;„Єÿ^„Ð`„ÿ2 @2 Index 4<„À„ÿ^„À`„ÿ2@2 Index 5=„°„ÿ^„°`„ÿ2@2 Index 6>„ „ÿ^„ `„ÿ2@2 Index 7?„„ÿ^„`„ÿ2@2 Index 8@„€„ÿ^„€`„ÿ2@2 Index 9A„p„ÿ^„p`„ÿ8!@’8 IndexüberschriftB52@22 KommentartextCCJ./@B. ListeD„„åþ^„`„åþ22@R2 Liste 2E„6„åþ^„6`„åþ23@b2 Liste 3F„Q„åþ^„Q`„åþ24@r2 Liste 4G„l„åþ^„l`„åþ25@‚2 Liste 5H„‡„åþ^„‡`„åþBD@’B ListenfortsetzungI„¤x^„FE@¢F Listenfortsetzung 2J„6¤x^„6FF@²F Listenfortsetzung 3K„Q¤x^„QFG@ÂF Listenfortsetzung 4L„l¤x^„lFH@ÒF Listenfortsetzung 5M„‡¤x^„‡41@â4 Listennummer N & F8:@ò8 Listennummer 2 O & F8;@8 Listennummer 3 P & F8<@8 Listennummer 4 Q & F8=@"8 Listennummer 5 R & FV-@ñÿ2V Makrotext"S Æ àÀ €` @ à_HmHsHtH^I@B^ Nachrichtenkopf.T„n„’û$d%d&d'd-D^„n`„’û(Z@R( Nur TextUCJ8@b8 Standardeinzug V„Ä^„Ä4Q@r4 Textkörper 3W¤xCJLR@‚L Textkörper-Einzug 2X„dà¤x^„JS@’J Textkörper-Einzug 3Y„¤x^„CJ\M@A¢\ Textkörper-ErstzeileneinzugZ$„Ò¤x`„Òa$dN@‘²d Textkörper-Erstzeileneinzug 2[„„Òdð^„`„ÒR$@ÂR Umschlagadresse!\„„üÿ„ôÿ„à&€+Dp/„^„4@@Ò4 Unterschrift ]„œ^„œ6J@â6 Untertitel^$¤<@&a$:.@: RGV-Überschrift_¤x5Z,@Z Rechtsgrundlagenverzeichnis`„ð„ÿ^„ð`„ÿ:þO: Simple Bullet 1 a & F§JþO"J Simple invisible bullet b & F’XþO2X Simple bulletlist continuation c„e^„eJþOBJ Functionlist d$„n„’û¤P¤P^„n`„’ûa$JþORJ SQL placeholdere„5„Ëû¤P¤P^„5`„Ëû0P@b0 Textkörper 2f5HþOrH Errorcode_descg„„éù¤¤^„`„éù2[@‚2 E-Mail-Signaturh2`@’2 HTML Adressei6]He@¢H HTML VorformatiertjCJOJQJ^J<^@²< Standard (Web)k OJQJaJ2&@¢Á2 FußnotenzeichenH* þOÒ Zwischm&þOâ& new i n & F}VþOòV list * unindented!o & F9„e„›þ¤P¤P^„e`„›þ&þO¢& new in B*phÿ$þO$ list q & F»&þO"& stand r & F6þO26 List Bullet 0 s & F½0þOB0 tzlist t ÆÜBmHsH„•øœá¬gųÅäÐåÑ ÿÿÿÿ4 ÿÿÿÿi ÿÿÿÿš ÿÿÿÿÎ ÿÿÿÿ ÿÿÿÿ6 ÿÿÿÿÎÿÿ"&£ÿÿ"&£ÿÿ"&£ÿÿ"&£ÿÿ"&£ÿÿ"&£ÿÿ"&£ÿÿ"&£ÿÿ "&£ÿÿ "&£ÿÿ "&£ÿÿ "&£ÿÿ "&£ÿÿ"&£ÿÿ"&£ÿÿ"&£ÿÿ"&£ÿÿ"&£ÿÿ"&£ÿÿ"&£ÿÿ"&£ÿÿ"&£ÿÿ"&£ÿÿ"&£ÿÿ"&£ÿÿ"&£ÿÿ"&£ÿÿ"&£ÿÿ"&£ÿÿ"&£ÿÿ"&£ÿÿ "&£ÿÿ!"&£ÿÿ""&£ÿÿ#"&£ÿÿ$"&£ÿÿ%"&£ÿÿ&"&£ÿÿ'"&£ÿÿ("&£ÿÿ)"&£ÿÿ*"&£ÿÿ+"&£ÿÿ,"&£ÿÿ-"&£ÿÿ."&£ÿÿ/"&£ÿÿ0"&£ÿÿ1"&£ÿÿ2"&£ÿÿ3"&£ÿÿ4"&£ÿÿ5"&£ÿÿ6"&£ÿÿ7"&£ÿÿ8"&£ÿÿ9"&£ÿÿ:"&£ÿÿ;"&£ÿÿ<"&£ÿÿ="&£ÿÿ>"&£ÿÿ?"&£ÿÿ@"&£ÿÿA"&£ÿÿB"&£ÿÿC"&£ÿÿD"&£ÿÿE"&£ÿÿF"&£ÿÿG"&£ÿÿH"&£ÿÿI"&£ÿÿJ"&£ÿÿK"&£ÿÿL"&£ÿÿM"&£ÿÿN"&£ÿÿO"&£ÿÿP"&£ÿÿQ"&£ÿÿR"&£ÿÿS"&£ÿÿT"&£ÿÿU"&£ÿÿV"&£ÿÿW"&£ÿÿX"&£ÿÿY"&£ÿÿZ"&£ÿÿ["&£ÿÿ\"&£ÿÿ]"&£ÿÿ^"&£ÿÿ_"&£ÿÿ`"&£ÿÿa"&£ÿÿb"&£ÿÿc"&£ÿÿd"&£ÿÿe"&£ÿÿf"&£ÿÿg"&£ÿÿh"&£ÿÿi"&£ÿÿj"&£ÿÿk"&£ÿÿl"&£ÿÿm"&£ÿÿn"&£ÿÿo"&£ÿÿp"&£ÿÿq"&£ÿÿr"&£ÿÿs"&£ÿÿt"&£ÿÿu"&£ÿÿv"&£ÿÿw"&£ÿÿx"&£ÿÿy"&£ÿÿz"&£ÿÿ{"&£ÿÿ|"&£ÿÿ}"&£ÿÿ~"&£ÿÿ"&£ÿÿ€"&£ÿÿ"&£ÿÿ‚"&£ÿÿƒ"&£ÿÿ„"&£ÿÿ…"&£ÿÿ†"&£ÿÿ‡"&£ÿÿˆ"&£ÿÿ‰"&£ÿÿŠ"&£ÿÿ‹"&£ÿÿŒ"&£ÿÿ"&£ÿÿŽ"&£ÿÿ"&£ÿÿ"&£ÿÿ‘"&£ÿÿ’"&£ÿÿ“"&£ÿÿ”"&£ÿÿ•"&£ÿÿ–"&£ÿÿ—"&£ÿÿ˜"&£ÿÿ™"&£ÿÿš"&£ÿÿ›"&£ÿÿœ"&£ÿÿ"&£ÿÿž"&£ÿÿŸ"&£ÿÿ "&£ÿÿ¡"&£ÿÿ¢"&£ÿÿ£"&£ÿÿ¤"&£ÿÿ¥"&£ÿÿ¦"&£ÿÿ§"&£ÿÿ¨"&£ÿÿ©"&£ÿÿª"&£ÿÿ«"&£ÿÿ¬"&£ÿÿ­"&£ÿÿ®"&£ÿÿ¯"&£ÿÿ°"&£ÿÿ±"&£ÿÿ²"&£ÿÿ³"&£ÿÿ´"&£ÿÿµ"&£ÿÿ¶"&£ÿÿ·"&£ÿÿ¸"&£ÿÿ¹"&£ÿÿº"&£ÿÿ»"&£ÿÿ¼"&£ÿÿ½"&£ÿÿ¾"&£ÿÿ¿"&£ÿÿÀ"&£ÿÿÁ"&£ÿÿÂ"&£ÿÿÃ"&£ÿÿÄ"&£ÿÿÅ"&£ÿÿÆ"&£!ÿÿÇ"&£!ÿÿÈ"&£!ÿÿÉ"&£#ÿÿÊ"&£ÿÿË"&£ÿÿÌ"&£ÿÿÍ"&£ÿÿÎ"&£Ç` #£q.ª>}NÙ_¯pg‹~–ñ¢|° ºq»QÇÑûÙ=Ýè¿ñ†ø‹†Ê!d*m1Ð=åE*MVŸ^2c2keqQ`ŒÉš>ªì´Â!ÐÙÞífðdÿA XÙ! ,.Õ5>îFÛN‰XÆdïks{(ƒX‹˜“Øš/¢q¢â©t²#¸(¿Õˀלç<ñ§û¤]"¿0`<pFRÇ_*näu‰|,†ÚŒ2šŸ£ß©m³i»\ÆÍτیå”î·÷P* A#&·-&7À>"FP‰X÷bj$u ‚hŠ¢’Æš ¥İ͹ƒÂýÌõÛRëôö­ÿ ªôí$$.t7pBQ¬^iÂuf€ÿ‰ø“Ë› ¤r¬Ͷ¥ÀBÈšÐ'Ùpà”ë;øK¾%§%U,Œ5Å>SK×T^5f¶p8z…C”ž¯¦°²¹ºáÂ`ÉÓyÞéã÷ˆúè!†*À1L3Ð:¤AµIÝP.W8`¸a±j!sÆy‚€5ˆ¥‘g•„•‘˜›øœj£¾ª›¬á¬8°f³C¶ñ¹̽šÁöÂQÄgÅjųÅúÈ̸ÎäÐåÑD  9QYAj— F … ñ¦ Õ*«6„ t PZ ª! ":#ß$%ò&y'ñ(æ)×*E+.,è-.Ò/ 0"12¨3%4X5B6'7Æ8X9":;™<s=¤>;?Ö@yABBCD”EôF8G¦HIrJ¶K§L–MNsO=PaQbRÆS‰TU3VyW-X”Y€Z[h\Ã]þ^_`Ja1b‹c]dÐegføgehiÃjyk]l‚mµn£oÂp‡qƒrs@thuÄvûwxPy´z({…|»}i~X×€Ü3‚nƒÁ„Ã…Ô†x‡Qˆ ‰‚Š,‹ŒGŽ…jb‘b’““_”ô•×–œ—¿˜¢™VšU›ŸœIFž8Ÿ ¢¡k¢8£¤Ý¥¦N§¨©ª²«O¬V­Ä®G¯S°±J²p³˜´µ‘¶“·G¸­¹ºé»t¼½J¾‘¿sÀeÁ~Â}ÿÄÅÅÅÅÆÇ+ÈÉÉÉÉÊÊÊËËËËHÌÌÌÍÍÍ-|¦§©ªÆ  z{»+oñ4Ù-rÊ*Ze` m n o ú û ¤ ¥ ßUV˜™"#,‘ºê"z±å@m¡Þc½ L„Ì`—Õ J¼3x©ÙFu®7xªÝ Bz°àZ£Ü!a¥á Q } » ô 0!g!Å!"P"›"ó">#…#Ô#/$$Ñ$!%q%»%ù%L&&æ&"'n'¿'(k(Ã()))ß)G*µ*+b+³+,o,º,-p-¼-.q.Â. /f/®/0J00ô0O1—1ã122ˆ2Ó2&3n3Ã34X4µ4 5h5Á5%6p6±6ü6H77Ò788Û889®9:x:Ì:1;¢; <n<¿< =V==ì=Q>ª>?P?¬? @W@¥@ AhA¾ABdBãBfCÏCED¦DöD\EÀEFzFÑFAGªG+H’HÜH&IoI¸I$JtJÉJKjK´KLaL·L'MM'N}N¾NOrOÂO"PyPÎP QvQàQKRÁRSrSØSHTÀT"UƒUßU5VVW]WÉW/X·X!Y©Y Z}ZÔZ-[’[õ[O\¦\þ\\]¸]^\^’^è^$_}_Ù_C`­`a‘ab‚bóbZc»c)d‹dådMeªefkf¾fgvgûg;hˆhähLi›iæi/jŒjÔj8kykìkAl–lmWm®m n…nÙn2oŠoëo[p¯pFq§qþq€rÒr+s–sísPt­tÿtluÉuv¥vúvÀwxzxëxDy¹yz{zòzm{³{ì{*|h|¡|}G}€}¹}ö}e~§~ä~(g­€”€è€G£‚^‚¶‚ƒ`ƒ¹ƒ„w„Ø„)…z…È….†~†Ï†;‡Ž‡ä‡/ˆwˆÏˆ,‰œ‰Ý‰ŠJІвŠ‹‹‹"‹QŒÿïŽ"26~–‹–/˜šÖ›~œ5Ÿ> 9¡™¡ñ¢v¤#¥ñ¥Ÿ§Œ©wªä¬c®—®…¯¡¯m²¤²¯²ç²I´u´v´¡´Â´Ï´Ð´æ´µ µ!µBµ€µµ™µÕµìµûµüµ¶Z¶[¶s¶¯¶À¶r·¸¸²º»)»o»p»q»z»¼'¼|¼‚½¤ÁêÃÄ|Ä}ÄÕÄÅzÅÏÅÐÅKÆLÆÆÆQÇ&ȞȟÈ*ɶÉYÌÍãÍä̓τÏÐÐ1ÐOÐPÐZÐuЀÐКÐÃÐÒÐÓÐáÐ ÑÑÑ1ÑdÑpÑqÑѩѹѺÑËÑÌÑ×ÒâÒ<Ô=ÔËÔÌÔÕXÕ¿ÕDÖ×é×ÙØ ÙFÙ¦ÚƒÛ¨ÛÌÛüÛšÜÍÜ=ÝsÝëÞßFß8à~à„áââ9ãWãÏãÐãä äÉäÊäwåx唿•æç‘çèèãèøè6éRéuévéyêzêÀê7ë0ì#íqíºíî@î™îÆîýîQï›ïìïEðð°ð¿ñèñÏò‡óüóšõ»õW÷á÷øHø†ø™øù‘ù¤û½ûäûåû×ýÂÔ‡ç >+† Ï °Ù,ôÀ¦É!Ê!Ý!#€#Ð$Ñ$;%Q%†'‡'B(f(½(¾(Ë(á(î(ü(ý(Û)Ü)ò)+*<*R*c*d*m*µ*ô*;+[+F,G,[,b,c,v,x,›,À,Â,Ã,Ö,Ø,ä,Ý-Þ-&.1.²/Å/÷/º0á1ü12„2u3v3µ3â34r4Ñ5á5ü6ò7©8y9É:ï;ù;z<==Ð=â=??b??­?@ @!@B@n@“@”@eCgC‡C¤C¥C¶C½C¾CéCüCýC(D=EMEåEòFÀGÁG$H%H2H3HtHuH‰HŠHãHäHII×IñI¢J£J²JÇJÈJäJK$K%KRLSLpL|L¡LÊLóLM)M*MzM{M†M—M˜MÇMöM%N&N©NµN OpO¨P;QtQ¶QßQRDRpR€RRŸR°RÀRPS]SŸST´TƒU÷W>Z=[>[M[Z[d[i[n[o[Ž[¦[§[·[¼[Ã[Ö[ß[á[â[õ[\ \:\Q\X\S]Ö]æ]I_Y_æ_ô_l`m`y`š`­`¸`Å`Ó`à`á`÷`ø`aa+a,aYafawa€a‹a¦a§aXbYbeb†b¦b´bÁbÂbØbÙbæbõb#c1c2cŠþŠ`ŒR ¨ ‘`’Å’F“”Í”â•ø–a—B›Œ¶Ÿg¢¤¦¦±§¸¨«©>ª/«O¬@­\­æ­=® ®¯¯à¯_°ð°A±B±±Ù±²F²G²H²´²9³Q´ì´Òµ•¶¸°º»O¼c¼A½À˜ÀÂìÂRÄÆ¥ÇµÇÈ…È9ÉÊÛÊ…ËèÌØÍfÑrÒzÓHÔÕÑÕÖñÖå×3ÙžÙÚÒÜNÝábáIâ,ãäÂäå,æ«ç5éGé~ììííïïfðnð¡ðÃòlóHôÔôö÷ÒøÓøŠù‹ùáûâû+ý,ý6Oƒ/Sͯмš ï - 0 1 A K Ð Ú k€*5¯°W×L™ÞH‰Ó7…ëXz\GYõö6[„®Üþ$Kv™Àâ3bnz„²ö9 : Y!Z!š!À!Ø!Ù!Ú!"##Ö$;&3'ê'Ú(l*ã*õ+þ+ , ,µ,Ò,.;..­.Â.Ó.ó.ô.È/É/0/000ö1J2h2ƒ2”2º2Ç2È23Û3ù3&474r4s4Õ56-6Z6k6‚6ƒ6J88®8Â8Ó8Ô8:W:u:‰:š:Ï:Ð:<H<f<z<‹<À<Á<>E>c>{>|>?€?ª?@AA—AÙA÷ABBÓCòCDD—DÖDôD$E5E6EˆE¾EØE#F4F5FîFG/GŽGŸG G}š}°}Ô}å}ù}ú}Œù<±ÇÝîZ‚[‚(ƒ{ƒ‘ƒ§ƒ¸ƒ̃̓Ó„…%…@…Q…^…_….†/†X††‚†ˆ†W‡}‡ž‡¿‡Þˆ߈ÿ‰.‹/‹8‹X‹“‹©‹Ä‹Õ‹â‹ã‹„Œ…ŒºŒïŒðŒöŒÅë&ŽGŽfgÂÃe‘’’Ì’â’ý’“““˜“ô“n”¦”¼”×”è”ô”õ”µ–—'—B—S—_—`—Ù—˜9˜t˜…˜œ˜ª˜«˜Ä™Øš›6›Q›b›y›†›‡›"œpœŽœØœéœ01Ï"ž@žœž­ž®ž  ¡/¡?¡L¡[¡s¡¡¯¡¿¡Ì¡Û¡ó¡¢/¢?¢L¢p¢q¢³¢Ñ¢ô¢££=£‰£¹£ë£!¤"¤„¦…¦ަ¥¦Ù¦õ¦§§§6§e§Œ§™§š§²§â§ÿ§&¨3¨s¨¨¨¨¹¨å¨ò¨ó¨Ú©â©ûª…«Ø«ÿ«¬+¬H¬U¬V¬A­¬®¯T¯y¯”¯¥¯˯Ù¯Ú¯e°¥°ð±s²t²¹²Þ²÷²³.³:³;³—´Í´ò´ µµAµYµZµ'¶(¶`¶…¶¤¶µ¶Û¶ð¶ñ¶#¸x¸ž¸²¸øì¸ ¹¹¹‘¹’¹º£º.¼/¼B½’½¸½̽ݽ¾%¾0¾1¾(¿`¿~¿²¿ÿÄ¿nÀoÀÁ‚ÁoÂpÂ8Ã9ÃŽÆÆ1ÇkÇÂÇ(ÈÉÉmÊÑÊÒÊ{ͶÍÐÍåÍöÍ÷Í#Ï$ÏlÏmÏ~иÐÒÐçÐÑÑIÑ5ÒGÓjÓƒÓ#Ô¨Õ³ÖŽØQÚÂÚWÛ›ÜÝŸÞ'á.ãu倿äæèÉêMìíNîOî·îÒîïQïïÌïðPð™ð¦ð§ðîðññ;ñ<ñòñóñò¾òÖó ô(ôMôlômô•õ–õ¾õlöÁøÂøùù3ùvùwùÉùÊùõù\úêúNüuýÕý}þÂþ.ÿ’ÿ–øKLü(tœ¬÷.DxËz{¤:_$ Ú - ·ÓÚ–ÏX9L]n|}v´Ùí¯°Ö]嚦K: E!v!Ö!"x"*$u$Ø%(')*ä+,-Ò- /«/0Œ0¿0ü0W1X1ê3ì3 4%4M4ˆ4Ò4 5K5€5±5è5é5í5î56#6V6–6Õ6ú67D7‡7Ó78]8¬8ê8÷8D9ƒ9’9ž9È9Þ9ó9::ª;«;Ð;<`<Á=+>n>Y?F@Á@¯B°B'C(CACbCŒC¶CàC D4D^DˆD²D½DÊD E#ECE|E}EHFIFpFÒFòHóHIçI K~LOÄOõPöPŠQ¡Q¹Q×QöQRRZRR”RÖR×RITJTwUxUÍVÎV÷VÅXœYhZ\_P`añcàdIfgklmmNm~m˜m®m²m³mËmæmn)n*n+n¼nðn o8oholomoƒo„o»o×oØop?pxpyp°pÉpÕpïp q#q¥?¥x¥Å¥í¥þ¥ÿ¥6§7§j§¡§¢§¨2¨d¨u¨v¨©©8©d©©²©Ó©ß©Gª`ª›ª¶ªǪÖªת[­Y¯¯Û¯°/°@°O°P°'±q±бűà±ñ±²²m³0´Œ´¥´à´û´ µµ+µ,µp¶$·x·‘·±·Å·æ·÷· ¸ ¸¤¹¥¹i»è»¼!¼5¼V¼g¼z¼{¼`½a½ʾB¿[¿{¿§¿È¿Ù¿ì¿í¿PÁQÁÅÅÆÅ\Æ]ơƢÆQÇ÷ÈÊÊxÊyÊ&Ë'ËCËcËyËz˼ËËËÌb̲ÌõÌÍ6Í7ÍOÍaÍb͓̓ÍÝÍôÍ)ÎfÎsΑΙλÎÏ ÏÏÏVÏcÏyϥϩϺÏÍÏ&Ð?Ð_ЋЬнÐÐÐÑÐcÒdÒ.Ó/ÓåÓÆÔDÕÕcÖ²Ö°×OÙ^Ú„ÛÎÜ$ÞgÞ€Þ Þsߔߥ߸߹ßááÈáÉáPãQãää,ä;ä<äeä‚ä›äÃäÓäå&å]åså}åŒå½åðåùåýå ææYæræ’æ¦æÇæØæëæìæÑèÒè;ê<êèêéêì&ílíúí5îaî‚î“î”îï¢ïcðuð;ñ<ñ}ñßñQò·òó/óuó©óÕó{ô·ôçôlõgöhöp÷q÷·÷ø2øäøõøöøgùüù«ûXü2ý3ýƒýÀýþþþÿÿcÿtÿ¤ÿ¥ÿPœ³íþ j¸Ï!2KL¤õ ö Ž Ð ç ? P i j ‘ Ý ô &=NOlƒ²ÃÐÑ£Ž±²e#@A9~»Òíþ  Q‘¨ÂÓâã\]Ýô01èWt‹«¼ÓÔ!!'!M!o!¶!Í!è!0"1"q"Ï"&#$f$‡$§$»$Û$ì$ÿ$%#&r&“&³&Ç&ç&ø& ' '»'¼'[(|(œ(°(Ð(á(ô(õ(ª)E*f*†*š*º*Ë*Þ*ß*+€+ß,à,}-~-¶-·-z./h/›/í/20–02 3;4¡4Â4â4ö45'5:5;5¿5À5°6±6&7Ÿ7À7à7ô78%88898Ê8Ë8j9k9#:Ã:$;E;`;q;};~;<à<÷<=#=0=1=À>?>?v?‡??ž?AwA˜A³AÄAÑAÒAÐBC8C”C¥C¿CÀCGE¦EÇEâEóE!F"F¤G!HtH•H°HÁHÎHÏHƒJìJ K(K9KFKGK8NœN½NØNéNõNöNÉPGQÃQäQRR4R5RÔSDT±TÔUÕU5VVVqV‚VVVéW XAXiXzXˆX‰X,ZfZ‡Z¢Z³ZÁZÂZ5]m]Ž]­]¾]^^Œ^^Ý^Þ^_o_Ç_2`}` a[a5bêb÷b¹cYd–dÚde}e eÄeéef4fZf~f£f&g¥g¦gägOhyh¤hÏhi™ijQjrjj jîjïjækdl{l›lÇlålöl m mcodoq‘q&r‰rÖrhsÅs7tÔt$u§uPv³vgwÒwT{é|˜~b€Ÿ€¶€?Vmn ‚!‚ñ‚ò‚Ÿ„ „ † †Ú†Û†‡‡4‡_‡l‡m‡‰‡´‡Á‡ˆ(ˆOˆ`ˆnˆoˆ­‰á‰û‰HŠYŠgŠhЍ‹ŒÖŒðŒ#$ŽsާŽÁŽÜŽíŽúŽûŽ¿ü‘1‘B‘O‘_‘`‘¢’ð’ “%“6“C“S“T“_–¤–¾–Ù–ê–ö–÷–*˜˜ª˜ë˜ü˜™™Æš1›^›y›Š›—›§›¨›¢Vžpž”ž¥ž¹žºž® ¯ Ö —¡{¢µ¢ï¢ð¢d¤e¤¥ ¥¦F¦`¦s¦„¦…¦M§N§¨@¨\¨q¨—¨˜¨ ©©:©æ©¤ª#®°°¶°İú°(±g±v±½±×±ò±²²²³P³j³…³–³¢³£³ε ¶'¶j¶{¶|¶8·9·ú·û·͹º7ºRºcºdº&»m»‡»Ê»Û»Ü»…¼†¼*½+½¼¾i¿°¿Ê¿ ÀÀÀéÀêÀƒÂÉÂãÂ&Ã7Ã8ÃnÄÅOÅiŬŽžřƀÇàÇúÇÈ.ÈPÈaÈtÈuÈnÉ1Ë3ËuËvËýÌ%ÎÃÎgÐ&ѱÑJÓÙÔ¾Õ˜Ö¾×ÀØ­ÙaÚGÛõÛzÜݶÝiÞæß·àâ`â„ãìãúä æmç é’êRë íbí1ïÃðòõàõúõö.öPöaötöuöôö]÷w÷—÷«÷Ì÷Ý÷ð÷ñ÷yøØøÙø¼ù ú&úFúZú{úŒúŸú ú†ûãûäûÆü ý$ýDýXýzý‹ýžýŸýPÿ­ÿ/VjŒ°±$}â<Prƒ–—ce§5  ê Á 4 n Ž ¢ Ä Õ è é ø žq‹¦·ÅÆÖª†¡²áKL´ÿ/{ŒÁ?@£¤=>…ŸºËÙóô'{«Îßïð(¦Ìó–0 1 p!Æ!ö!"*"9":"q"Æ"#D#´#"$#$[%¢%¼%×%è%÷%ø%Á&M'±'Ë'æ'÷'((ñ)J*d****ž*=,-$.å.‰/£/¾/Ï/Ü/Ý/Ï1)2C2^2o2|2}2˜45.5I5Z5g5h578„8ž8%9;9<9Ï9Ð97:8:ß:à:~;é;B<W<ë<ì<Ó=Ô=à>á> ?O?ApBDC5DE_E®EöFGaIcKL–LMSM‹M NEN}N O’PQ€QúQdRÅSúU]?]—]¶]Þ]^X^…^¬^ý^[_g_¤_½_à_á_­a®abb¬bðbJcjc–c·cÈcÛcÜcídîdUhVhii!jÐj2lèl“m¿nžolpmpÂpq=qQqrqƒq–q—qºsDtEtÁuÂuDvEvšvõvw)wJw[wnwowHxIxBzCzÇzÈzÕ{Ö{Ñ|Ò|}R}…}›}ß}÷}~ ~F~‚~~¸~û~(Vk‚¾ü€:€f€’€¿€Þ€ö€÷€D]‰¾ÏâãLƒMƒC„D„Ÿ…І"‰x‰y‰þ‰ÿ‰CŠžŠ¾ŠÒŠóŠ‹‹‹=Œ>Œefåæ2ŽSŽkŽ|Ž}Ž4ÌÍ‹‘Œ‘¬’­’““8“9“t“u“•“È“ç“õ“ø“”I”h”|”}”¯”°”À”ü” •• •j•‰•µ•˕̕5–ƒ–œ–ß–ð–ñ–3˜4˜í˜î˜Ý™š/šašršsšË›œ3œJœ[œ\œ÷œ[\‡ƒŸ„Ÿ  œ ½ Ø ó ¡¡¡O¢{¢–¢¨¢¹¢º¢ñ¢2£^£x£°£è£ ¤¥¤ܤݤ›¥x¦Û¦¡§Чë§ý§¨¨Q©Ÿ©º©Õ©æ©ç©k«l«¸«Å«î«¬1¬2¬c¬q¬r¬Á¬ܬ÷¬­­­'®‰®V¯q¯‚¯¯¯ˆ²ì²¹³Ô³å³ò³ó³Ͷ/·J·e·v·ƒ·„·X¹ƹá¹ü¹ ººº¼¼•¼°¼̼ݼþ¼ÿ¼iÀ¥ÀÁÔÁïÁ ÂÂ~ÃèõÄÐÄáÄíÄîÄùÅQÆlƇƘƙÆBÈŽÈ©ÈÄÈÕÈÖÈ5ʖʱÊÌÊÝÊÞÊÌÎÌéÌÍÍÍÐÎÏ8ÏSÏdÏeÏšÐùÐÑ/Ñ@ÑAÑÓÒ7Ó8Ó…Ó ÓôÓÔÔ1Õ}Õ˜ÕìÕýÕþÕ;×§×Â×Ý×î×ï×TØ'ÙÚ[ÚvÚ–Ú§Ú¨ÚËÛÜ4Üz܋܌ܑÝÙÝôÝÞIÞiÞzÞÞŽÞ¿ßpàGáeáâcâdâFãâãããìãäOäYäZäsä æWæçç%é&étêuê”ë¸ë0ídîEïCñ±ô²ôåô¦õ€ö÷;øúø9ùŠùºû›ü–ýÓýpþÍþûÿX˧íå­Á  4 =>°ÜÂ#$qRò,Ms„… %Yz´ÅÆ4Š«Ïàáú!û!Š#‹#Ä#ï#$+$C$D$r$É$á$â$E%§%Ú%û%4&E&F&}'~'Ü'ý'()(*(è(é()9)q)‚)–)—)µ)7*£*Ä*ä*ø*<+M+`+a+U,ž,¿,ç,ø, - -m-ˆ-Á-`.›.Ñ.ý.¬/ô/ 0&070F0G0?1ð1ñ1n2ˆ2¶2·2·3Œ5Ò5é566!6"6Ž6¹7„8q;·;Î;é;ú;<<j<>a>x>“>¤>³>Ä>Å>ý?µ@Ö@ò@AAAOBPB™BÍBJC’C“CÄCEDóDôD@EGÑHéISKTKÃKÄKÓKL%L&L5LgLwL|L‹LÆLÖL×LåL4MCM…M¦MÇMØMÙM=N>N%OhOÍO4P•PµP¶P/Q¾QS>S”S#TyU³U VêV@X¿XÀXUZVZvZÈZÉZéZ>[?[Ç[$\q\ˆ\¨\Ô\ò\]]]Ø]]^^^^Õ^ø^_*_A_B_®_ `²`&a'a¼a½aßa b!brb•b°bÁbÐbÑb¯cñcòcÝdëdùd[e®eýe5fmf¡f×fbg©gìgBhYhZhiiÊjËj k'kEkkk|k‹kŒk,lNmOm)n*nÊoËo,p¶pFqGq^q¹qirjrÁrXsYst7tVt|ttŽtSu´vµv^wx“xÓxy\y¨yðy8z{k{Á{§|ð|9}ö}Ô~+‚ê3€„€Õ€&Ç4‚‘‚î‚'ƒaƒ™ƒ׃c„……k…l…S†z‡ ˆ(‰ØŠŒiŽçè¾ù ’‘“’“C”‘”ß”•T••Ì•[–‚—ƒ—5˜6˜¹˜º˜†š‡š½šКÝ›ñ›ò›œvœŠœ‹œ¡œñœížžžHžvžžŽžÞžøžŸ9ŸFŸGŸ¤ ï  ¡L¡]¡p¡q¡8£û£¤1¤W¤h¤v¤w¤¯¦0¨1¨í¨Ú©íªV« ­±­²­"®#®3¯Ư°ç°A±œ±±>²?²°²±²$³%³x³—³™³»³سú³´@´n´p´q´Ä´Ö´#µ6µ7µFµ©µ¹µºµɵ)¶9¶:¶I¶’¶¢¶â¶ü¶E·V·d·e·¸k»¹»Ó»¼ ¼,¼-¼«¼½3½U½f½}½~½µ½¾¾/¿¨¿©¿åÀ+ÁEÁ`ÁqÁ€ÁÁáÂ0ÃJÃeÃvêëÃóÄ<ÅVÅqłőŒÅÅÅÆÆ8ÆIÆXÆYÆøÆRÇlÇÎÇôÇÈÈÈ`ɶÉÐÉìÉ ÊÊ*Ê+ÊÞÊ9Ëíˉ̊Ì1Î2Î?ÏXϟϹÏÿÏÐ5ÐTÐeÐsÐtзҸÒÁÒÑÒÓÓÙÓóÓÔ.Ô?ÔMÔNÔ‹ÔŒÔT×U×ñÙòÙ»Û¼ÛÉÝÞ-ÞHÞYÞhÞxÞyÞÀßá4á*â;âñâ}ã~ãååKæLæmæépêûëHî¹òô`öaöŸöÎö ÷ ÷q÷Ÿ÷ã÷ä÷*øQø£øÂøüøù3ù×ùØù¿úÀúlûˆþŽð-tu¯ÀˆÒë Ýòó)ÔÕ  % & Ô Õ . / n × fþ(‰j§Å7M°±ñ3ÄÇ7CÙÎn€"Ý" #Ú#ý#‰$Ÿ$¿$%"%V%W%”%'Í'¯(ø().)q)‚))‘)†*&+<+\+x+‰+—+˜+,d,z,š,µ,Æ,Õ,Ö,.q.Š.ª.¾.ß.ð.//:1;1À1Q2o2K3L3ß3ý34ª4«4e5¹5 6 6‹6Œ6 6ë677V7“7°7Å7Ú7ê7-8X8²8Q9R9Õ9Ö9ì9::Ð:;<D<y<’=¿=ê=¸>¹>Ã>Ó>??w?œ?³?Ð?è?ø? @"@9@:@ã@A¤AQB¶BáBC@CšCÏCDFDfEgEžE»E¼EFF÷FÿFGG%G.G´GŠH‹H6I_I`IiIqIzIˆI‘I¡I¢I§I­I®I¯I°I±I²I³I´IµI·I¹I¿IÀIÅIÊIËIÎIÐIÖI×IÚIßIàIâIåIëIìIñIôIõIøIûIJJJJ J J J J JJJJJJJJJ$J%J(J*J/J0J3J6J7J9JÈGÈZÈlÈȌȤȵÈÄÈÙÈêÈúÈ ÉÉ'É6ÉGÉXÉiÉvÉɒɞɱɾÉÒÉàÉóÉÊÊÊ1ÊBÊTÊdÊuʃÊʢʱʹÊÇÊÖÊæÊùÊ ËË#Ë8ËLË[ËkË}˘ˮËÀËÍËàËóËÌÌÌ+Ì=ÌVÌnÌ̶̢̑ÌÏÌáÌðÌÍÍ Í0Í?ÍJÍ`Íu͋͛ͫͻÍÍÍÞÍðÍÎÎ&Î6ÎFÎWÎkÎΕΧθÎÐÎÙÎâÎîÎüÎ ÏÏ,Ï>ÏOÏ^ÏjÏzÏ…ÏŽÏÏ­Ï»ÏÈÏÖÏãÏøÏÐÐ'ÐBÐ\ÐjÐwЈКШдÐÇÐÔÐãÐäÐæÐ÷ÐøÐcÑdÑvÑwÑâÑæÑ˜0€€˜0€€0€€0€€˜0€|˜0€|˜0€|˜0€|˜0€|˜0€|˜0€|˜0€|˜0€|˜0€|0€€0€€0€€˜0€ñ0€€0€€0€€0€€0€€˜0€*˜0€*c 0€€˜0€` ˜0€` ˜0€` ˜0€` ˜0€` ˜0€` ˜0€` ˜0€` ˜0€` ˜0€` ˜0€` ˜0€` ˜0€` ˜0€` ˜0€` 0€€˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#˜0€#c 0€€c 0‹‹˜¸ a0€‹˜¸ 0€‹˜¸ 0€‹c 0‹‹(c 0ïŽïŽ˜ 0€"˜ 0€"(c 0ïŽïŽ˜ 0€~–˜ 0€~–˜ 0€~–˜ 0€~–˜ 0€~–˜ 0€~–˜ 0€~–˜ 0 €~–˜ 0 €~–˜ 0 €~–˜ 0 €~–˜ 0 €~–˜ 0€~–˜ 0€~–˜ 0€~–˜ 0€~–˜ 0€~–(c 0ïŽïŽ˜0€c®˜0€c®˜ 0€c®˜0€c®˜0€c®˜0€c®˜0€c®˜0€c®˜0€c®˜0€c®˜0€c®˜0€c®˜0€c®˜0€c®˜0€c®˜0€c®˜0€c®˜0€c®˜0€c®˜0€c®˜0€c®˜0€c®˜0€c®˜0€c®˜0€c®˜0€c®˜0€c®˜0€c®˜0€c®˜0€c®˜0€c®˜0€c®˜ 0€c®˜ 0€c®˜0€c®˜0€c®˜0€c®˜0€c®˜0€c®c 0€€˜0€q»c 0q»q»˜0€¼˜l 0€¼˜l 0€¼˜l 0€¼c 0q»q»˜0€êØa0€êØm a0€êØm 0€êØm 0€êØm 0€êØ0€êØm a0€êØa0€êØm a0€êØm a0€êØm a0€êØm a0€êØa0€êØn a0€êØn a0€êØn a0€êØo a0€êØp a0€êØ0€êØ0€êØ0€êØ0€êØ0€êØ0€êØ0€êØ0€êØ0€êØ0€êØ0€êØ0€êØ0€êØ0€êØ0€êØ0€êØ0€êØ0€êØ0€êØ0€êØ0€êØ0€êØ0€êØ0€êØ0€êØ0€êØ0€êØ0€êØ0€êØ0€êØ0€êÃc 0q»q»˜0€×Ò˜0€×Ò˜0€×Ò˜0€×Ò˜6 0€×Ò˜4 0€×Ò˜4 0€×Ò˜5 0€×Ò˜5 0€×Ò˜5 0€×Ò˜5 0€×Òc 0q»q»˜0€Ùؘ: 0€Ùؘ: 0€Ùؘe0€Ùؘe0€Ùؘe0€Ùؘe0€Ùؘe0€Ùؘ: 0€ÙØc 0€€˜0€=Ýc 0=Ý=ݘ0€ëÞ˜: 0€ëÞ˜: 0€ëÞ˜: 0€ëÞ˜: 0€ëÞ˜0€ëÞ˜0€ëÞc 0=Ý=ݘ0€9ã˜0€9ã˜0€9ã˜0€9ã˜0€9ã˜0€9ã˜0€9ã˜0€9ã˜0€9ã˜0€9ã˜0€9ã˜0€9ã˜0€9ãc 0=Ý=ݘ0€è˜º 0€è˜º 0€è˜º 0€èc 0=Ý=ݘ0€Ré˜0€Ré˜0€Ré˜0€Ré˜0€Ré˜0€Ré˜0€Ré˜0€Ré˜0€Ré˜0€Ré˜0€Ré˜0€Ré˜0€Ré˜0€Ré˜0€Ré˜0€Ré˜0€Ré˜0€Ré˜0€Ré˜0€Ré˜0€Réc 0=Ý=ݘ0€¿ñ˜9 o0€¿ñ˜9 o0€¿ñ˜9 o0€¿ñc 0=Ý=ݘ0€šõ˜0€šõ˜0€šõ˜0€šõ˜0€šõc 0€€˜0€†ø˜0€†ø˜0€†øc 0†ø†ø˜0€¤û˜0€¤û˜9 o0€¤û˜9 o0€¤ûc 0†ø†ø˜0€Â˜9 o0€Â˜9 o0€Â˜9 o0€Â˜9 o0€Â˜9 o0 €Âc 0†ø†ø˜0€†˜9 o0 €†˜9 0 €†˜9 0 €†˜9 0 €†˜9 0€†˜9 o0€†˜9 o0€†˜9 o0€†˜0€†c 0€€˜0€Ê!˜0€Ê!˜0€Ê!˜0€Ê!˜0€Ê!c 0Ê!Ê!˜0€;%˜0€;%˜0€;%c 0Ê!Ê!˜0€B(˜0€B(˜0€B(˜0€B(˜0€B(˜0€B(˜0€B(˜0€B(˜0€B(˜0€B(˜0€B(˜0€B(˜0€B(˜0€B(˜0€B(c 0Ê!Ê!˜0€d*˜ 0€d*˜ 0€d*c 0Ê!Ê!˜0€;+˜0€;+˜0€;+˜0€;+˜0€;+˜0€;+˜0€;+˜0€;+˜0€;+˜0€;+˜0€;+˜0€;+˜0€;+c 0Ê!Ê!˜0€Ø,˜0€Ø,˜0€Ø,c 0Ê!Ê!˜0€&.c 0Ê!Ê!˜0€²/˜} 0€²/˜~ 0€²/˜~ 0€²/˜~ 0€²/˜~ 0€²/˜~ 0€²/˜0€²/˜0€²/˜§ a0€²/˜§ a0€²/˜§ a0€²/˜§ a0€²/c 0Ê!Ê!˜0€Ñ5˜€ 0€Ñ5˜€ 0€Ñ5˜€ 0€Ñ5˜€ 0€Ñ5˜€ 0€Ñ5c 0Ê!Ê!˜0€ï;˜0€ï;˜0€ï;˜0€ï;(c 0ï;ï;˜0€Ð=˜0€Ð=˜0€Ð=˜0€Ð=˜0€Ð=˜0€Ð=˜0€Ð=˜0€Ð=˜0€Ð=˜0€Ð=˜0€Ð=˜c0€Ð=˜c0€Ð=˜0€Ð=˜0€Ð=˜0€Ð=˜0€Ð=˜0€Ð=˜0€Ð=˜0€Ð=˜0€Ð=˜c0€Ð=(c 0ï;ï;˜0€ýC(c 0ï;ï;˜0€=E˜ 0€=E˜ 0€=E˜0€=E˜0€=E˜0€=E˜0€=E˜0€=E˜0€=E˜0€=E˜0€=E˜0€=E˜0€=E˜0€=E˜0€=E˜c0€=E˜0€=E(c 0ï;ï;˜0€×I˜0€×I˜0€×I˜0€×I˜0€×I˜0€×I˜0€×I˜0€×I˜0€×I˜0€×I˜0€×I˜0€×I˜0€×I˜0€×I˜0€×I˜0€×I˜0€×I˜0€×I˜0€×I˜0€×I˜0€×I˜0€×I˜0€×I˜0€×I˜0€×I˜0€×I˜0€×I˜0€×I˜0€×Ic 0 Ê!Ê!˜0€©N˜ 0€©N˜ 0€©N˜ 0€©N˜ 0€©N˜ 0€©N˜ 0€©N˜ 0€©N˜ 0€©N˜ 0€©N˜ 0 €©N˜ 0 €©N˜ 0 €©N˜ 0 €©N˜ 0 €©N˜c0€©Nc 0 Ê!Ê!˜0€PS˜’ b0€PS˜’ b0€PS˜’ b0€PS˜’ b0€PS˜’ b0€PS˜’ b0€PS˜0€PS˜0€PS˜0€PS˜0€PS˜0€PS˜0€PS˜0€PS˜0€PS˜0€PS˜0€PS˜0€PS˜0€PS˜0€PS˜0€PS˜0€PS˜0€PS˜0€PS˜0€PS˜0€PS˜0€PS˜0€PS˜0€PSc 0 Ê!Ê!˜0€Q\˜0€Q\(c 0Q\Q\˜0€Ö](c 0Q\Q\˜0€I_(c 0Q\Q\˜0€æ_˜0€æ_˜0€æ_˜0€æ_˜0€æ_˜0€æ_˜0€æ_˜0€æ_˜0€æ_˜0€æ_˜0€æ_˜0€æ_˜0€æ_˜0€æ_˜0€æ_˜0€æ_˜0€æ_˜0€æ_˜0€æ_˜0€æ_˜0€æ_˜0€æ_˜0€æ_˜0€æ_˜0€æ_˜0€æ_˜0€æ_˜0€æ_˜0€æ_˜0€æ_˜0€æ_˜0€æ_˜0€æ_˜0€æ_˜0€æ_˜0€æ_˜0€æ_˜0€æ_c 0 Ê!Ê!˜0€2c˜0€2c˜0€2c˜0€2c˜0€2c˜0€2c˜0€2c˜0€2c˜0€2c˜0€2c˜0€2c˜0€2c˜0€2c˜0€2c(c 02c2c˜0€e˜0€e˜0€e˜0€e˜0€e˜0€e˜0€e˜0€e˜0€e˜0€e˜0€e˜0€e˜0€e˜0€e˜0€e˜0€e˜0€e˜0€e˜0€e˜0€e˜0€e˜0€e˜0€e˜0€e˜0€e˜0€e˜0€e˜0€e˜0€e˜0€e˜0€e˜0€e˜0€e˜0€e˜0€e˜0€e˜0€e˜0€e˜0€e˜0€e˜0€e˜0€e˜0€e˜0€e(c 02c2c˜0€Œm˜0€Œm˜’ b0€Œm˜’ b0€Œmc 0 Ê!Ê!˜0€ðo(c 0ðoðo˜d0€eq˜d0€eq˜d0€eq˜d0€eq˜d0€eq˜d0€eq˜d0€eq˜d0€eq˜d0€eq˜d0€eq˜d0€eq˜d0€eq(c 0ðoðo˜0€Q˜0€Q˜0€Q˜0€Q˜d0€Q˜d0€Q˜d0€Q˜d0€Q(c 0ðoðo˜d0€^‰˜d0€^‰˜d0€^‰˜d0€^‰˜d0€^‰˜d0€^‰˜d0€^‰˜d0€^‰˜d0€^‰˜d0€^‰˜d0€^‰˜d0€^‰˜d0€^‰˜d0€^‰˜d0€^‰˜d0€^‰˜d0€^‰˜d0€^‰˜d0€^‰˜d0€^‰˜d0€^‰˜d0€^‰˜d0€^‰˜d0€^‰˜d0€^‰˜d0€^‰˜d0€^‰˜d0€^‰˜d0€^‰(c 0ðoðo˜0€@­˜½ s0€@­˜½ s0€@­˜½ s0€@­˜½ s0€@­˜½ s0€@­˜½ s0€@­˜½ s0€@­˜½ s0€@­˜s0€@­˜s0€@­˜½ s0€@­˜½ s0 €@­˜½ s0 €@­˜0€@­˜d0€@­˜d0€@­˜d0€@­˜d0€@­˜d0€@­˜d0€@­˜d0€@­˜d0€@­˜d0€@­˜d0€@­˜d0€@­(c 0ðoðo˜d0€O¼˜d0€O¼˜d0€O¼˜d0€O¼˜d0€O¼˜d0€O¼˜d0€O¼˜d0€O¼(c 0ðoðo˜d0€¥Ç˜d0€¥Ç˜d0€¥Ç˜d0€¥Ç˜d0€¥Ç˜d0€¥Ç˜d0€¥Ç˜d0€¥Ç˜d0€¥Ç˜d0€¥Ç˜d0€¥Ç˜d0€¥Ç˜d0€¥Ç˜d0€¥Ç˜d0€¥Ç˜d0€¥Ç˜d0€¥Ç˜d0€¥Ç˜d0€¥Ç˜d0€¥Ç˜d0€¥Ç˜d0€¥Ç˜d0€¥Ç˜d0€¥Ç˜d0€¥Ç˜d0€¥Ç˜d0€¥Ç˜d0€¥Ç˜d0€¥Ç˜d0€¥Ç˜d0€¥Ç˜d0€¥Çc 0Ê!Ê!˜0€5é˜0€5é˜0€5é˜0€5é˜0€5é˜0€5é˜0€5éc 0€€˜0€f𘧠a0€f𘧠a0€f𘧠a0€f𘧠a0€f𘧠a0€f𘧠a0 €f𘧠a0 €fð˜a0€fð˜a0€fð˜a0€fð˜a0€fð˜a0€fð˜a0€fð˜a0€fð˜a0€fðc 0fðfð˜0€6˜§ a0 €6˜§ a0 €6c 0fðfð˜0€˜§ a0 €˜§ a0€˜§ a0€˜§ a0€˜§ a0€˜§ a0€˜§ a0€˜§ a0€˜§ a0€˜a0€˜a0€˜0€˜c0€˜0€˜c0€˜0€˜c0€˜0€˜c0€c 0fðfð˜0€˜0€˜§ a0€˜§ a0€˜§ a0€˜§ a0€˜§ a0€˜§ a0€˜§ a0€˜§ a0€˜§ a0€˜§ a0€˜§ a0 €˜§ a0!€˜§ a0"€˜§ a0#€˜§ a0$€c 0fðfð˜0€G˜0€G˜0€G˜0€G˜0€G˜0€G˜0€G˜0€G˜0€G˜0€G˜0€G˜0€G˜0€G˜0€G˜0€G˜0€G˜0€G˜0€G˜0€G˜0€G˜0€G˜0€G˜0€G˜0€G˜0€G˜0€G˜0€G˜0€G˜0€G˜0€G˜0€G˜0€Gc 0fðfð˜0€Ú!˜0€Ú!˜e0€Ú!˜e0€Ú!˜e0€Ú!˜e0€Ú!˜e0€Ú!˜e0€Ú!˜e0€Ú!˜e0€Ú!˜0€Ú!˜0€Ú!˜0€Ú!˜0€Ú!c 0fðfð˜0€µ,c 0€€c 0..˜'0€;.˜'0€;.˜'0€;.˜'0€;.˜0€;.˜0€;.˜0€;.˜0€;.˜0€;.˜0€;.˜0€;.c 0..˜'0€ö1˜'0€ö1˜'0€ö1˜'0€ö1˜'0€ö1˜0€ö1˜0€ö1c 0..˜'0€3˜'0€3˜'0€3˜'0€3˜0€3˜0€3c 0..˜'0€Õ5˜'0€Õ5˜'0€Õ5˜'0€Õ5˜0€Õ5˜0€Õ5c 0..˜'0€J8˜'0€J8˜'0€J8˜0€J8˜0€J8c 0..˜'0€:˜'0€:˜'0€:˜'0€:˜0€:˜0€:c 0..˜'0€<˜'0€<˜'0€<˜'0€<˜0€<˜0€<c 0..˜'0€>˜'0€>˜0€>˜0€>˜0€>˜0€>˜Z 0€>˜Z 0€>˜0€>˜0€>c 0..˜'0€—A˜'0€—A˜0€—A˜0€—A˜0€—A˜Z 0€—A˜Z 0€—Ac 0 ..˜'0€—D˜'0€—D˜'0€—D˜0€—D˜0€—D(c 0—D—D˜'0€ˆE˜'0€ˆE˜'0€ˆE˜0€ˆE˜0€ˆE(c 0—D—D˜'0€îF˜'0€îF˜'0€îF˜0€îF˜0€îF˜0€îF(c 0—D—D˜'0€½H˜'0€½H˜'0€½H˜'0€½H˜0€½H˜0€½Hc 0 ..˜'0€EJ˜'0€EJ˜'0€EJ˜0€EJ˜0€EJ˜0€EJ˜§ a0%€EJ˜§ a0&€EJ˜§ a0'€EJ˜§ a0(€EJ(c 0EJEJ˜'0€ÛN˜'0€ÛN˜'0€ÛN˜'0€ÛN˜0€ÛN˜0€ÛN˜0€ÛN˜0€ÛN˜0€ÛN˜0€ÛN˜0€ÛN(c 0EJEJ˜'0€ÃQ˜'0€ÃQ˜'0€ÃQ˜'0€ÃQ˜0€ÃQ˜0€ÃQ˜0€ÃQ˜f0€ÃQ˜9 o0€ÃQ˜9 0€ÃQ˜9 0€ÃQ˜9 0€ÃQ˜9 0€ÃQ˜9 0€ÃQ˜9 0€ÃQ˜9 0€ÃQ˜9 0€ÃQ˜9 0€ÃQ˜9 0€ÃQ˜9 0€ÃQ˜0€ÃQ˜0€ÃQ˜9 0€ÃQ˜9 0€ÃQ˜9 0 €ÃQ˜9 0!€ÃQ˜9 0"€ÃQ˜9 0#€ÃQ˜9 0$€ÃQ˜9 0%€ÃQ˜9 0&€ÃQ˜9 0'€ÃQ˜0€ÃQ˜0€ÃQ˜9 0(€ÃQ˜9 0)€ÃQ˜9 0*€ÃQ˜9 0+€ÃQ˜9 0,€ÃQ˜9 0-€ÃQ˜0€ÃQ˜f0€ÃQ˜9 0.€ÃQ˜9 0/€ÃQ˜9 00€ÃQ˜9 01€ÃQ˜0€ÃQ˜0€ÃQ˜0€ÃQ˜0€ÃQ˜'0€ÃQ(c 0EJEJ˜'0€²h˜'0€²h˜'0€²h˜'0€²h˜0€²h˜0€²h(c 0EJEJ˜'0€j˜'0€j˜'0€j˜'0€j˜0€j˜0€j˜0€j˜0€j˜0€j˜0€j˜0€j(c 0EJEJ˜'0€Õn˜'0€Õn˜'0€Õn˜'0€Õn˜0€Õn˜0€Õn(c 0EJEJ˜'0€=q˜'0€=q˜'0€=q˜'0€=q˜0€=q˜0€=q(c 0EJEJ˜'0€`r˜'0€`r˜'0€`r˜'0€`r˜0€`r˜0€`r˜0€`r˜0€`r˜0€`r˜0€`r˜0€`r˜0€`r(c 0EJEJ˜'0€;t˜'0€;t˜'0€;t˜'0€;t˜0€;t˜0€;t(c 0EJEJ˜'0€ív˜'0€ív˜'0€ív˜'0€ív˜0€ív˜0€ív(c 0 EJEJ˜'0€§x˜'0€§x˜'0€§x˜'0€§x˜0€§x˜0€§x˜§ a0)€§x˜§ a0*€§x˜§ a0+€§x(c 0 EJEJ˜'0€>}˜'0€>}˜'0€>}˜'0€>}˜0€>}˜0€>}˜0€>}˜0€>}(c 0 EJEJ˜'0€<˜'0€<˜'0€<˜'0€<˜0€<˜0€<(c 0 EJEJ˜'0€(ƒ˜'0€(ƒ˜'0€(ƒ˜'0€(ƒ˜0€(ƒ˜0€(ƒ(c 0 EJEJ˜'0€Ó„˜'0€Ó„˜'0€Ó„˜'0€Ó„˜0€Ó„˜0€Ó„˜0€Ó„˜0€Ó„˜0€Ó„˜0€Ó„˜0€Ó„˜; 0€Ó„˜; 0€Ó„˜; 0€Ó„˜2 0€Ó„˜2 0€Ó„˜0€Ó„˜0€Ó„˜0€Ó„˜0€Ó„˜0€Ó„˜0€Ó„(c 0EJEJ˜'0€X‹˜'0€X‹˜'0€X‹˜'0€X‹˜0€X‹˜0€X‹˜0€X‹˜0€X‹˜0€X‹˜0€X‹˜0€X‹˜; 0€X‹˜; 0€X‹˜; 0€X‹˜2 0€X‹˜2 0€X‹˜0€X‹˜0€X‹˜0€X‹˜0€X‹˜0€X‹˜0€X‹(c 0EJEJ˜'0€’˜'0€’˜'0€’˜'0€’˜0€’˜0€’(c 0EJEJ˜0€˜“(c 0EJEJ˜'0€n”˜'0€n”˜'0€n”˜'0€n”˜0€n”˜0€n”(c 0EJEJ˜'0€µ–˜'0€µ–˜'0€µ–˜'0€µ–˜0€µ–˜0€µ–c 0 ..˜'0€Ù—˜'0€Ù—˜'0€Ù—˜'0€Ù—˜'0€Ù—˜0€Ù—˜0€Ù—˜0€Ù—c 0 ..˜'0€Øš˜'0€Øš˜'0€Øš˜'0€Øš˜'0€Øš˜0€Øš˜0€Øšc 0 ..˜'0€"œ˜'0€"œ˜'0€"œ˜'0€"œ˜0€"œ˜a0€"œc 0..˜'0€Ï˜'0€Ï˜'0€Ï˜0€Ï˜a0€Ï˜a0€Ï˜a0€Ï˜0€Ï˜0€Ï˜0€Ï˜0€Ï˜0€Ï˜0€Ï˜0€Ï˜0€Ï˜0€Ï˜0€Ï˜0€Ï˜0€Ï˜0€Ï˜0€Ï˜0€Ï˜0€Ï˜0€Ïc 0€€˜'0€q¢˜'0€q¢˜'0€q¢˜0€q¢˜0€q¢˜0€q¢˜< 0€q¢˜< 0€q¢˜< 0€q¢˜0€q¢˜$0€q¢˜$0€q¢˜$0€q¢˜0€q¢˜0€q¢˜0€q¢˜0€q¢˜0€q¢˜0€q¢˜0€q¢˜0€q¢˜0€q¢˜0€q¢˜0€q¢˜0€q¢˜0€q¢˜0€q¢˜0€q¢˜0€q¢c 0q¢q¢˜'0€3¨˜'0€3¨˜'0€3¨˜'0€3¨˜'0€3¨˜0€3¨˜a0€3¨˜a0€3¨˜± a0€3¨˜± a0€3¨c 0q¢q¢˜'0€…«˜'0€…«˜'0€…«˜'0€…«˜'0€…«˜0€…«˜0€…«˜0€…«˜0€…«c 0q¢q¢˜'0€¯˜'0€¯˜'0€¯˜'0€¯˜'0€¯˜0€¯˜0€¯˜§ a0,€¯˜§ a0-€¯˜§ a0.€¯˜$0€¯c 0q¢q¢˜'0€t²˜'0€t²˜'0€t²˜'0€t²˜'0€t²˜0€t²˜0€t²c 0q¢q¢˜'0€—´˜'0€—´˜'0€—´˜'0€—´˜'0€—´˜0€—´˜0€—´˜0€—´c 0q¢q¢˜'0€(¶˜'0€(¶˜'0€(¶˜'0€(¶˜'0€(¶˜0€(¶˜0€(¶c 0q¢q¢˜'0€#¸˜'0€#¸˜'0€#¸˜'0€#¸˜'0€#¸˜'0€#¸˜0€#¸˜0€#¸˜0€#¸˜· 0€#¸˜· 0€#¸˜· 0€#¸˜0€#¸˜0€#¸c 0q¢q¢˜'0€B½˜'0€B½˜'0€B½˜'0€B½˜'0€B½˜'0€B½˜0€B½˜0€B½c 0 €€˜'0€(¿˜'0€(¿˜'0€(¿˜0€(¿˜0€(¿˜0€(¿˜0€(¿˜0€(¿˜0€(¿˜0€(¿˜0€(¿˜0€(¿W 0€€˜0€9ÃW 0€€˜X 0€Æ˜X 0€Æ˜X 0€Æ˜X 0€Æ˜X 0€Æ˜0€Æ˜0€Æ˜0€ÆW 0€€c 0(¿Òʘ'0€{͘'0€{͘'0€{͘0€{͘0€{͘0€{͘0€{͘0€{͘0€{Íc 0(¿Òʘ'0€~И'0€~И'0€~И0€~И0€~ИK 0€~ИK 0€~ИK 0€~ИK 0€~ИK 0€~ИK 0€~ИK 0€~ИK 0€~ИK 0€~ИK 0 €~ИK 0 €~ИK 0 €~ИK 0 €~ИK 0 €~ИK 0€~ИK 0€~ИK 0€~ИK 0€~ИK 0€~ИK 0€~ИK 0€~ИK 0€~ИK 0€~ИK 0€~И0€~И0€~И0€~И0€~И0€~И0€~И0€~И0€~И0€~И0€~И0€~И0€~Ðc 0(¿Òʘ'0€§ð˜'0€§ð˜'0€§ð˜0€§ð˜0€§ð˜0€§ð˜0€§ð˜Y 0€§ð˜Y 0€§ð(c 0§ð§ð˜'0€Öó˜'0€Öó˜'0€Öó˜0€Öó˜0€Öó˜0€Öó˜0€Öó˜Z 0€Öó˜Z 0€Öó˜0€Öó(c 0§ð§ð˜'0€Âø˜'0€Âø˜'0€Âø˜0€Âø˜0€Âø˜0€Âø˜0€Âø˜Z 0€Âø˜Z 0€Âø˜Z 0€Âø˜Z 0 €Âø˜Z 0 €Âø˜Z 0 €Âø˜Z 0 €Âø˜Z 0 €Âø˜Z 0€Âø˜Z 0€Âø˜Z 0€Âø˜Z 0€Âø˜Z 0€Âø˜0€Âø˜0€Âø˜0€Âø˜0€Âø˜0€Âø˜0€Âø˜0€Âø˜0€Âø˜0€Âø(c 0§ð§ð˜'0€D˜'0€D˜'0€D˜0€D˜0€D˜0€D˜0€D˜Z 0€D˜Z 0€D˜Z 0€D˜Z 0€D˜Z 0€D˜Z 0€D˜Z 0€D˜Z 0€D˜Z 0€D˜Z 0€D˜Z 0€D˜Z 0€D˜0€D˜0€D˜0€D˜0€D˜c0€D˜c0€D(c 0§ð§ð˜'0€v˜'0€v˜'0€v˜0€v˜0€v˜0€v˜0€v˜Z 0€v˜Z 0 €v˜Z 0!€v˜Z 0"€v˜Z 0#€v˜Z 0$€v˜Z 0%€v˜Z 0&€v˜Z 0'€v˜Z 0(€v˜Z 0)€v˜Z 0*€v˜Z 0+€v˜Z 0,€v˜Z 0-€v˜Z 0.€v˜Z 0/€v˜Z 00€v˜Z 01€v˜Z 02€v˜Z 03€v˜Z 04€v˜Z 05€v˜Z 06€v˜0€v˜Z 07€v˜Z 08€v˜Z 09€v˜K 0€v˜0€v˜0€v˜0€v˜0€v˜0€v˜0€v˜0€v˜0€v˜0€v˜0€v˜0€v˜0€v˜0€v˜0€v˜0€v˜0€v˜0€v˜0€v˜0€v˜0€v˜0€v˜0€v˜0€v˜0€v˜0€v˜0€v˜0€v˜0€v˜0€v˜0€v˜0€v˜0€v˜0€v˜0€v˜0€v(c 0§ð§ð˜'0€ž9˜'0€ž9˜'0€ž9˜0€ž9˜0€ž9˜0€ž9˜0€ž9˜Z 0:€ž9˜Z 0;€ž9˜Z 0<€ž9˜Z 0=€ž9˜Z 0>€ž9˜Z 0?€ž9˜Z 0@€ž9˜Z 0A€ž9˜Z 0B€ž9˜0€ž9˜0€ž9˜0€ž9˜0€ž9˜0€ž9˜0€ž9˜0€ž9˜0€ž9˜0€ž9˜0€ž9˜0€ž9˜0€ž9˜0€ž9˜0€ž9˜0€ž9(c 0§ð§ð˜'0€ÊD˜'0€ÊD˜'0€ÊD˜0€ÊD˜0€ÊD˜0€ÊD˜0€ÊD˜] 0€ÊD˜] 0€ÊD˜0€ÊD˜0€ÊD˜Z 0C€ÊD˜Z 0D€ÊD˜Z 0E€ÊD˜Z 0F€ÊD˜Z 0G€ÊD˜Z 0H€ÊD˜0€ÊD˜0€ÊD˜0€ÊD˜0€ÊD˜0€ÊD˜0€ÊD˜0€ÊD˜0€ÊD(c 0§ð§ð˜'0€R˜'0€R˜'0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜Z 0I€R˜Z 0J€R˜Z 0K€R˜Z 0L€R˜ž 0€R˜Z 0M€R˜Z 0N€R˜Z 0O€R˜0€R˜Z 0P€R˜0€R˜Z 0Q€R˜Z 0R€R˜Z 0S€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R˜0€R(c 0§ð§ð˜'0€mw˜'0€mw˜'0€mw˜0€mw˜0€mw˜0€mw˜Z 0T€mw˜Z 0U€mw˜Z 0V€mw˜Z 0W€mw˜Z 0X€mw(c 0§ð§ð˜'0€wz˜'0€wz˜'0€wz˜0€wz˜0€wzc 0(¿Òʘ'0€‰|˜'0€‰|˜'0€‰|˜0€‰|˜0€‰|˜0€‰|˜0€‰|˜Y 0€‰|˜Y 0€‰|(c 0‰|‰|˜'0€¼€˜'0€¼€˜'0€¼€˜0€¼€˜0€¼€˜0€¼€˜0€¼€˜^ 0€¼€˜0€¼€˜0€¼€(c 0‰|‰|˜'0€=„˜'0€=„˜'0€=„˜0€=„˜0€=„(c 0‰|‰|˜'0€,†˜'0€,†˜'0€,†˜0€,†˜0€,†(c 0‰|‰|˜'0€ˆ˜'0€ˆ˜'0€ˆ˜0€ˆ˜0€ˆ(c 0‰|‰|˜'0€1‰˜'0€1‰˜'0€1‰˜0€1‰˜0€1‰˜0€1‰˜0€1‰˜0€1‰˜0€1‰˜0€1‰˜0€1‰˜0€1‰(c 0‰|‰|˜'0€É‹˜'0€É‹˜'0€É‹˜0€É‹˜0€É‹˜§ a0/€É‹˜§ a00€É‹˜§ a01€É‹˜§ a02€É‹(c 0‰|‰|˜'0€þ˜'0€þ˜'0€þ˜0€þ˜0€þ˜0€þ˜§ a03€þ˜§ a04€þ˜§ a05€þ˜§ a06€þ˜§ a07€þ˜§ a08€þ˜§ a09€þ˜§ a0:€þ˜§ a0;€þ˜§ a0<€þc 0(¿Òʘ'0€2š˜'0€2š˜'0€2š˜'0€2š˜0€2š˜0€2š˜0€2š˜0€2š˜^ 0€2š˜^ 0€2š˜^ 0€2š˜^ 0€2š˜^ 0€2š˜^ 0€2š(c 02š2š˜'0€u ˜'0€u ˜'0€u ˜0€u ˜0€u ˜0€u ˜0€u ˜0€u ˜0€u ˜0€u ˜0€u ˜0€u ˜0€u ˜0€u ˜0€u ˜0€u ˜0€u ˜0€u ˜0€u ˜0€u ˜0€u ˜0€u ˜0€u ˜0€u ˜0€u ˜0€u ˜0€u ˜0€u ˜0€u ˜0€u (c 02š2š˜'0€?¥˜'0€?¥˜'0€?¥˜0€?¥˜0€?¥˜0€?¥˜0€?¥˜0€?¥˜0€?¥(c 02š2š˜'0€¢§˜'0€¢§˜'0€¢§˜0€¢§˜0€¢§˜0€¢§˜0€¢§˜0€¢§˜0€¢§˜0€¢§˜0€¢§˜0€¢§(c 02š2š˜'0€ß©˜'0€ß©˜'0€ß©˜'0€ß©˜'0€ß©˜0€ß©˜0€ß©˜0€ß©(c 02š2š˜'0€Y¯˜'0€Y¯˜'0€Y¯˜'0€Y¯˜'0€Y¯˜0€Y¯˜0€Y¯(c 02š2š˜'0€'±˜'0€'±˜'0€'±˜'0€'±˜'0€'±˜0€'±˜0€'±˜0€'±(c 02š2š˜'0€0´˜'0€0´˜'0€0´˜'0€0´˜'0€0´˜'0€0´˜0€0´˜0€0´˜0€0´(c 02š2š˜'0€$·˜'0€$·˜'0€$·˜'0€$·˜'0€$·˜'0€$·˜0€$·˜0€$·˜0€$·˜0€$·(c 02š2š˜'0€i»˜'0€i»˜'0€i»˜'0€i»˜'0€i»˜'0€i»˜0€i»˜0€i»˜0€i»˜0€i»(c 0 2š2š˜'0€Ê¾˜'0€Ê¾˜'0€Ê¾˜'0€Ê¾˜'0€Ê¾˜'0€Ê¾˜0€Ê¾˜0€Ê¾˜0€Ê¾˜0€Ê¾˜0€Ê¾˜0€Ê¾˜0€Ê¾˜0€Ê¾˜0€Ê¾˜d0€Ê¾˜d0€Ê¾˜d0€Ê¾˜0€Ê¾˜0€Ê¾˜0€Ê¾˜0€Ê¾˜0€Ê¾˜0€Ê¾˜0€Ê¾˜0€Ê¾˜0€Ê¾˜0€Ê¾˜0€Ê¾˜0€Ê¾˜0€Ê¾˜0€Ê¾˜0€Ê¾˜0€Ê¾˜0€Ê¾˜0€Ê¾˜0€Ê¾˜0€Ê¾˜0€Ê¾˜0€Ê¾˜0€Ê¾˜0€Ê¾˜0€Ê¾˜0€Ê¾˜0€Ê¾˜0€Ê¾˜0€Ê¾˜0€Ê¾˜0€Ê¾˜0€Ê¾˜0€Ê¾˜0€Ê¾˜0€Ê¾˜0€Ê¾˜0€Ê¾˜0€Ê¾˜0€Ê¾˜0€Ê¾˜0€Ê¾˜0€Ê¾(c 0 2š2š˜'0€ÍϘ'0€ÍϘ'0€ÍϘ'0€ÍϘ'0€ÍϘ'0€ÍϘ0€ÍϘ0€ÍϘ0€ÍϘ0€ÍϘ0€ÍϘd0€ÍϘd0€ÍϘd0€ÍϘd0€ÍϘd0€ÍϘd0€ÍϘd0€ÍϘd0€ÍϘd0€ÍϘd0€ÍϘd0€ÍϘd0€ÍÏ(c 0 2š2š˜'0€$Þ˜'0€$Þ˜'0€$Þ˜'0€$Þ˜'0€$Þ˜'0€$Þ˜0€$Þ˜0€$Þ˜0€$Þ˜0€$Þ˜0€$Þ˜d0€$Þ˜0€$Þ˜0€$Þ˜0€$Þ˜0€$Þ˜0€$Þ˜0€$Þ˜0€$Þ˜0€$Þ˜0€$Þ˜0€$Þ˜0€$Þ˜0€$Þ˜0€$Þ˜0€$Þ˜0€$Þ˜0€$Þ˜0€$Þ˜0€$Þ˜0€$Þ˜0€$Þ˜0€$Þ˜0€$Þ˜0€$Þ(c 0 2š2š˜'0€æ˜'0€æ˜'0€æ˜'0€æ˜'0€æ˜'0€æ˜0€æ˜0€æ˜0€æ˜0€æ˜0€æ˜0€æ˜0€æ˜d0€æ˜d0€æ˜d0€æ˜d0€æ(c 0 2š2š˜'0€úí˜'0€úí˜'0€úí˜0€úí˜0€úí˜_ 0€úí˜_ 0€úíc 0(¿Òʘ0€cð˜0€cð˜r a0€cð˜t a0€c𘧠a0=€cð˜r a0€cð˜r a0€c𘧠a0>€c𘧠a0?€c𘧠a0@€c𘧠a0A€cð˜r a0€c𘧠a0B€c𘧠a0C€cð˜r a0€cð˜r a0€cð˜a0€cð˜a0€cð˜a0€cð˜a0€cðc 0 €€˜'0€·÷˜'0€·÷˜'0€·÷˜0€·÷˜0€·÷˜O 0€·÷˜O 0€·÷˜O 0€·÷˜O 0€·÷˜0€·÷˜0€·÷˜M 0€·÷˜M 0€·÷˜0€·÷˜0€·÷c 0·÷·÷˜'0€þ˜'0€þ˜'0€þ˜'0€þ˜0€þ˜0€þc 0·÷·÷˜'0€P˜'0€P˜'0€P˜'0€P˜0€P˜0€Pc 0·÷·÷˜'0€j˜'0€j˜'0€j˜'0€j˜0€j˜0€j˜0€j˜0€j˜0€j˜0€j˜0€j˜0€j˜0€jc 0·÷·÷˜'0€Ž ˜'0€Ž ˜'0€Ž ˜'0€Ž ˜0€Ž ˜0€Ž c 0·÷·÷˜'0€‘ ˜'0€‘ ˜'0€‘ ˜'0€‘ ˜'0€‘ ˜0€‘ ˜a0€‘ ˜0€‘ c 0·÷·÷˜'0€˜'0€˜'0€˜'0€˜0€˜0€˜0€˜0€˜0€˜0€˜§ a0D€˜§ a0E€˜§ a0F€˜a0€˜a0€˜a0€˜0€c 0·÷·÷˜'0€˜'0€˜'0€˜'0€˜0€˜0€c 0·÷·÷˜'0€Q˜'0€Q˜'0€Q˜'0€Q˜0€Q˜0€Q˜0€Qc 0·÷·÷˜'0€]˜'0€]˜'0€]˜0€]˜a0€]˜a0€]˜a0€]c 0 ·÷·÷˜'0€˜'0€˜'0€˜'0€˜0€˜0€˜0€˜0€˜0€˜0€c 0 ·÷·÷˜'0€o!˜'0€o!˜'0€o!˜0€o!˜0€o!˜0€o!˜0€o!˜0€o!c 0 ·÷·÷˜'0€$˜'0€$˜'0€$˜'0€$˜'0€$˜'0€$˜0€$˜0€$c 0 ·÷·÷˜'0€#&˜'0€#&˜'0€#&˜'0€#&˜'0€#&˜'0€#&˜0€#&˜0€#&˜0€#&c 0 ·÷·÷˜'0€¼'˜'0€¼'˜'0€¼'˜'0€¼'˜'0€¼'˜'0€¼'˜0€¼'˜0€¼'c 0·÷·÷˜'0€ª)˜'0€ª)˜'0€ª)˜'0€ª)˜'0€ª)˜'0€ª)˜0€ª)˜0€ª)˜0€ª)˜0€ª)˜0€ª)˜0€ª)˜0€ª)˜0€ª)˜0€ª)˜d0€ª)˜d0€ª)˜d0€ª)˜d0€ª)˜d0€ª)˜d0€ª)˜d0€ª)˜d0€ª)˜d0€ª)˜d0€ª)c 0·÷·÷˜'0€;4˜'0€;4˜'0€;4˜'0€;4˜'0€;4˜'0€;4˜0€;4˜0€;4˜0€;4˜0€;4˜0€;4˜0€;4c 0·÷·÷˜'0€&7˜'0€&7˜'0€&7˜'0€&7˜'0€&7˜'0€&7˜0€&7˜0€&7˜0€&7˜0€&7˜0€&7˜0€&7˜d0€&7c 0·÷·÷˜'0€Ã:˜'0€Ã:˜'0€Ã:˜'0€Ã:˜0€Ã:˜0€Ã:c 0·÷·÷˜'0€<˜'0€<˜'0€<˜'0€<˜0€<˜0€<c 0·÷·÷˜'0€À>˜'0€À>˜'0€À>˜'0€À>˜0€À>˜0€À>c 0·÷·÷˜'0€A˜'0€A˜'0€A˜'0€A˜0€A˜0€Ac 0·÷·÷˜'0€ÐB˜'0€ÐB˜'0€ÐB˜'0€ÐB˜0€ÐB˜0€ÐBc 0·÷·÷˜'0€GE˜'0€GE˜'0€GE˜'0€GE˜0€GE˜0€GE˜0€GEc 0·÷·÷˜'0€!H˜'0€!H˜'0€!H˜'0€!H˜0€!H˜0€!Hc 0·÷·÷˜'0€ƒJ˜'0€ƒJ˜'0€ƒJ˜'0€ƒJ˜0€ƒJ˜0€ƒJc 0·÷·÷˜'0€8N˜'0€8N˜'0€8N˜'0€8N˜0€8N˜0€8N˜0€8Nc 0·÷·÷˜'0€GQ˜'0€GQ˜'0€GQ˜'0€GQ˜0€GQ˜0€GQ˜0€GQ˜0€GQ˜0€GQ˜0€GQc 0·÷·÷˜'0€ÕU˜'0€ÕU˜'0€ÕU˜'0€ÕU˜0€ÕU˜0€ÕUc 0·÷·÷˜'0€éW˜'0€éW˜'0€éW˜'0€éW˜0€éW˜0€éWc 0·÷·÷˜'0€,Z˜'0€,Z˜'0€,Z˜'0€,Z˜0€,Z˜0€,Zc 0·÷·÷˜'0€5]˜'0€5]˜'0€5]˜'0€5]˜0€5]˜0€5]˜0€5]˜0€5]˜0€5]˜e0€5]˜e0€5]˜e0€5]˜e0€5]˜e0€5]˜e0€5]˜e0€5]˜e0€5]˜e0€5]˜e0€5]˜e0€5]˜e0€5]˜e0€5]˜e0€5]˜e0€5]˜e0€5]˜e0€5]˜e0€5]˜e0€5]˜e0€5]˜e0€5]˜e0€5]˜e0€5]˜e0€5]˜e0€5]˜e0€5]˜0€5]˜0€5]˜e0€5]˜e0€5]˜e0€5]˜e0€5]˜e0€5]˜e0€5]˜e0€5]c 0·÷·÷˜'0€j˜'0€j˜'0€j˜'0€j˜0€j˜0€jc 0 ·÷·÷˜'0€æk˜'0€æk˜'0€æk˜'0€æk˜'0€æk˜'0€æk˜0€æk˜0€æk˜0€æk˜0€æk˜0€æk˜0€æk˜d0€æk˜d0€æk˜d0€æk˜d0€æk˜d0€æk˜d0€æk˜d0€æk˜d0€æk˜d0€æk˜d0€æk˜d0€æk˜d0€æk˜d0€æk˜d0€æk˜d0€æk˜d0€ækc 0!·÷·÷˜'0€b€˜'0€b€˜'0€b€˜'0€b€˜0€b€˜0€b€˜0€b€˜0€b€˜0€b€˜0€b€˜0€b€˜0€b€˜0€b€˜0€b€˜0€b€˜0€b€˜0€b€˜0€b€˜0€b€˜0€b€˜0€b€˜0€b€˜0€b€˜0€b€(c 0b€b€˜'0€Á‡˜'0€Á‡˜'0€Á‡˜'0€Á‡˜0€Á‡˜0€Á‡(c 0b€b€˜'0€­‰˜'0€­‰˜'0€­‰˜'0€­‰˜0€­‰˜0€­‰˜0€­‰(c 0b€b€˜'0€Œ˜'0€Œ˜'0€Œ˜'0€Œ˜0€Œ˜0€Œ˜0€Œ(c 0b€b€˜'0€sŽ˜'0€sŽ˜'0€sŽ˜'0€sŽ˜0€sŽ˜0€sŽ(c 0b€b€˜'0€¿˜'0€¿˜'0€¿˜'0€¿˜'0€¿˜0€¿˜0€¿(c 0b€b€˜'0€¢’˜'0€¢’˜'0€¢’˜'0€¢’˜'0€¢’˜0€¢’˜0€¢’(c 0b€b€˜'0€_–˜'0€_–˜'0€_–˜'0€_–˜0€_–˜0€_–(c 0b€b€˜'0€*˜˜'0€*˜˜'0€*˜˜'0€*˜˜0€*˜˜0€*˜(c 0b€b€˜'0€Æš˜'0€Æš˜'0€Æš˜'0€Æš˜'0€Æš˜0€Æš˜0€Æš(c 0 b€b€˜'0€¢˜'0€¢˜'0€¢˜'0€¢˜0€¢˜0€¢˜0€¢˜0€¢˜? 0€¢˜? 0€¢˜? 0€¢˜? 0€¢˜0€¢˜0€¢˜0€¢˜0€¢˜0€¢˜0€¢(c 0 b€b€˜'0€¦˜'0€¦˜'0€¦˜0€¦˜0€¦˜0€¦˜0€¦(c 0 b€b€˜'0€¨˜'0€¨˜'0€¨˜0€¨˜0€¨˜0€¨˜0€¨˜L 0€¨˜L 0€¨˜L 0€¨˜L 0€¨˜0€¨˜0€¨˜0€¨˜0€¨˜0€¨˜0€¨˜0€¨(c 0 b€b€˜'0€v±˜'0€v±˜'0€v±˜'0€v±˜0€v±˜0€v±(c 0 b€b€˜'0€³˜'0€³˜'0€³˜'0€³˜0€³˜0€³(c 0b€b€˜'0€Îµ˜'0€Îµ˜'0€Îµ˜0€Îµ˜0€Îµ˜0€Îµ˜0€Îµ˜0€Îµ˜0€Îµ(c 0b€b€˜'0€Í¹˜'0€Í¹˜'0€Í¹˜0€Í¹˜0€Í¹(c 0b€b€˜'0€&»˜'0€&»˜'0€&»˜0€&»˜0€&»˜0€&»˜0€&»˜0€&»˜0€&»˜0€&»(c 0b€b€˜'0€i¿˜'0€i¿˜'0€i¿˜0€i¿˜0€i¿˜0€i¿˜0€i¿(c 0b€b€˜'0€ƒÂ˜'0€ƒÂ˜'0€ƒÂ˜0€ƒÂ˜0€ƒÂ˜0€ƒÂ(c 0b€b€˜'0€Å˜'0€Å˜'0€Å˜0€Å˜0€Å˜0€Å(c 0b€b€˜'0€€Ç˜'0€€Ç˜'0€€Ç˜'0€€Ç˜'0€€Ç˜'0€€Ç˜0€€Ç˜0€€Ç˜0€€Ç˜0€€Ç˜0€€Ç˜0€€Ç˜d0€€Ç˜d0€€Ç˜d0€€Ç˜d0€€Ç˜d0€€Ç˜d0€€Ç˜d0€€Ç˜d0€€Ç˜d0€€Ç˜d0€€Ç˜d0€€Ç˜d0€€Ç˜d0€€Ç˜d0€€Ç˜d0€€Ç˜d0€€Ç˜d0€€Ç˜d0€€Ç˜d0€€Ç˜d0€€Ç˜d0€€Ç˜d0€€Ç˜d0€€Ç˜d0€€Ç˜d0€€Ç˜d0€€Ç˜d0€€Ç˜d0€€Ç˜d0€€Ç˜d0€€Ç˜d0€€Ç˜d0€€Ç˜d0€€Ç˜d0€€Ç˜d0€€Ç˜d0€€Ç˜d0€€Ç˜d0€€Ç(c 0b€b€˜'0€õ˜'0€õ˜'0€õ˜'0€õ˜'0€õ˜'0€õ˜0€õ˜0€õ(c 0b€b€˜'0€ôö˜'0€ôö˜'0€ôö˜'0€ôö˜'0€ôö˜'0€ôö˜0€ôö˜0€ôö˜0€ôö˜0€ôö˜0€ôö(c 0b€b€˜'0€¼ù˜'0€¼ù˜'0€¼ù˜'0€¼ù˜'0€¼ù˜'0€¼ù˜0€¼ù˜0€¼ù˜0€¼ù˜0€¼ù˜0€¼ù(c 0b€b€˜'0€Æü˜'0€Æü˜'0€Æü˜'0€Æü˜'0€Æü˜'0€Æü˜0€Æü˜0€Æü˜0€Æü(c 0b€b€˜'0€­ÿ˜'0€­ÿ˜'0€­ÿ˜'0€­ÿ˜'0€­ÿ˜'0€­ÿ˜0€­ÿ˜0€­ÿ˜0€­ÿ(c 0b€b€˜'0€}˜'0€}˜'0€}˜'0€}˜'0€}˜'0€}˜0€}˜0€}˜0€}˜0€}˜0€}˜d0€}˜d0€}˜d0€}˜d0€}˜d0€}˜d0€}(c 0b€b€˜'0€Á ˜'0€Á ˜'0€Á ˜'0€Á ˜'0€Á ˜'0€Á ˜0€Á ˜0€Á ˜0€Á ˜0€Á ˜0€Á (c 0b€b€˜'0€˜'0€˜'0€˜'0€˜0€˜0€˜0€˜0€(c 0b€b€˜'0€ª˜'0€ª˜'0€ª˜'0€ª˜'0€ª˜0€ª˜0€ª˜0€ª˜a0€ª(c 0b€b€˜'0€´˜'0€´˜'0€´˜'0€´˜'0€´˜0€´˜0€´˜0€´˜a0€´˜a0€´(c 0b€b€˜'0€>˜'0€>˜'0€>˜'0€>˜'0€>˜0€>˜0€>(c 0 b€b€˜'0€'˜'0€'˜'0€'˜'0€'˜0€'˜0€'˜§ a0G€'˜§ a0H€'˜§ a0I€'˜§ a0J€'˜§ a0K€'˜§ a0L€'˜a0€'˜a0€'(c 0!b€b€˜'0€p!˜'0€p!˜'0€p!˜'0€p!˜0€p!˜0€p!˜§ a0M€p!˜§ a0N€p!˜§ a0O€p!˜§ a0P€p!˜§ a0Q€p!˜a0€p!˜a0€p!(c 0"b€b€˜'0€[%˜'0€[%˜'0€[%˜'0€[%˜0€[%˜0€[%˜0€[%(c 0#b€b€˜'0€M'˜'0€M'˜'0€M'˜'0€M'˜0€M'˜0€M'(c 0$b€b€˜'0€ñ)˜'0€ñ)˜'0€ñ)˜'0€ñ)˜0€ñ)˜0€ñ)˜0€ñ)˜0€ñ)˜0€ñ)(c 0%b€b€˜'0€å.˜'0€å.˜'0€å.˜'0€å.˜0€å.˜0€å.(c 0&b€b€˜'0€Ï1˜'0€Ï1˜'0€Ï1˜'0€Ï1˜0€Ï1˜0€Ï1(c 0'b€b€˜'0€˜4˜'0€˜4˜'0€˜4˜'0€˜4˜0€˜4˜0€˜4(c 0(b€b€˜'0€78˜'0€78˜'0€78˜0€78˜0€78˜0€78˜0€78˜0€78˜0€78˜0€78˜0€788c 07878˜'0€~;˜'0€~;˜'0€~;˜0€~;˜0€~;˜0€~;˜0€~;˜0€~;˜0€~;˜9 o02€~;˜9 o03€~;˜9 o04€~;˜K 0€~;˜K 0€~;˜K 0€~;˜K 0€~;˜K 0€~;˜K 0€~;˜K 0€~;˜K 0 €~;˜K 0!€~;˜K 0"€~;˜K 0#€~;˜K 0$€~;˜K 0%€~;˜K 0&€~;˜K 0'€~;˜K 0(€~;˜K 0)€~;˜K 0*€~;˜9 o05€~;˜K 0+€~;˜K 0,€~;˜K 0-€~;˜K 0.€~;˜K 0/€~;˜K 00€~;˜K 01€~;˜9 o06€~;˜9 o07€~;˜9 o08€~;˜9 o09€~;˜0€~;˜0€~;˜0€~;˜0€~;˜0€~;˜0€~;˜0€~;˜0€~;˜0€~;˜0€~;˜0€~;8c 07878˜'0€g_˜'0€g_˜0€g_˜0€g_˜0€g_˜0€g_˜0€g_˜0€g_8c 07878˜'0€¬b˜'0€¬b˜'0€¬b˜'0€¬b˜'0€¬b˜'0€¬b˜0€¬b˜0€¬b˜0€¬b˜0€¬b˜0€¬b˜0€¬b˜0€¬b˜d0€¬b˜d0€¬b˜d0€¬b˜d0€¬b˜d0€¬b˜d0€¬b˜d0€¬b˜d0€¬b˜d0€¬b8c 07878˜'0€mp˜'0€mp˜'0€mp˜'0€mp˜'0€mp˜'0€mp˜0€mp˜0€mp˜0€mp˜0€mp˜0€mp˜0€mp˜0€mp˜0€mp8c 07878˜'0€Ev˜'0€Ev˜'0€Ev˜'0€Ev˜'0€Ev˜'0€Ev˜0€Ev˜0€Ev˜0€Ev˜0€Ev˜0€Ev˜0€Ev˜0€Ev˜0€Ev˜0€Ev˜0€Ev˜0€Ev˜0€Ev˜0€Ev˜0€Ev˜0€Ev˜0€Ev˜0€Ev˜0€Ev˜0€Ev˜0€Ev˜0€Ev˜0€Ev˜0€Ev˜0€Ev˜0€Ev˜0€Ev˜0€Ev˜0€Ev˜0€Ev˜0€Ev˜0€Ev˜0€Ev˜0€Ev˜0€Ev˜0€Ev˜0€Ev˜0€Ev˜0€Ev˜0€Ev8c 07878˜'0€÷€˜'0€÷€˜'0€÷€˜'0€÷€˜'0€÷€˜'0€÷€˜0€÷€˜0€÷€˜0€÷€˜0€÷€˜0€÷€˜0€÷€˜0€÷€˜0€÷€˜0€÷€˜0€÷€˜0€÷€˜0€÷€8c 07878˜'0€ÿ‰˜'0€ÿ‰˜'0€ÿ‰˜'0€ÿ‰˜'0€ÿ‰˜'0€ÿ‰˜0€ÿ‰˜0€ÿ‰˜0€ÿ‰˜0€ÿ‰˜0€ÿ‰˜0€ÿ‰˜0€ÿ‰c 0"·÷·÷˜'0€æ˜'0€æ˜'0€æ˜0€æ˜0€æ˜0€æ˜0€æ˜0€æ˜0€æ˜0€æ˜0€æ˜0€æ˜0€æ˜0€æ˜0€æ˜0€æ˜0€æ˜0€æ˜0€æ˜0€æ˜0€æ˜0€æ˜0€æ˜0€æ˜0€æ˜0€æ˜0€æ˜0€æ˜0€æ˜0€æ˜0€æ˜0€æ˜0€æ˜0€æ(c 0ææ˜'0€ •˜'0€ •˜'0€ •˜0€ •˜0€ •(c 0ææ˜'0€5–˜'0€5–˜'0€5–˜0€5–˜0€5–˜0€5–˜0€5–˜0€5–˜0€5–(c 0ææ˜'0€Ý™˜'0€Ý™˜'0€Ý™˜0€Ý™˜0€Ý™c 0#·÷·÷˜'0€Ë›˜'0€Ë›˜'0€Ë›˜0€Ë›˜0€Ë›˜0€Ë›˜0€Ë›˜0€Ë›˜§ a0R€Ë›˜0€Ë›˜0€Ë›˜0€Ë›˜0€Ë›(c 0˛˛˜'0€œ ˜'0€œ ˜'0€œ ˜'0€œ ˜0€œ ˜0€œ (c 0˛˛˜'0€O¢˜'0€O¢˜'0€O¢˜0€O¢˜0€O¢˜T 0€O¢˜T 0€O¢˜T 0€O¢˜T 0€O¢˜T 0€O¢˜T 0€O¢˜T 0€O¢˜T 0€O¢˜0€O¢˜0€O¢˜0€O¢˜§ a0S€O¢˜§ a0T€O¢(c 0˛˛˜'0€¡§˜'0€¡§˜'0€¡§˜0€¡§˜0€¡§(c 0˛˛˜'0€Q©˜'0€Q©˜'0€Q©˜0€Q©˜0€Q©˜0€Q©˜0€Q©˜0€Q©˜0€Q©˜0€Q©˜0€Q©˜0€Q©˜0€Q©˜0€Q©˜0€Q©(c 0˛˛˜'0€r¬˜'0€r¬˜'0€r¬˜'0€r¬˜0€r¬˜0€r¬(c 0˛˛˜'0€'®˜'0€'®˜'0€'®˜'0€'®˜0€'®˜0€'®(c 0˛˛˜'0€ˆ²˜'0€ˆ²˜'0€ˆ²˜'0€ˆ²˜0€ˆ²˜0€ˆ²(c 0˛˛˜'0€Í¶˜'0€Í¶˜'0€Í¶˜'0€Í¶˜0€Í¶˜0€Í¶(c 0˛˛˜'0€X¹˜'0€X¹˜'0€X¹˜'0€X¹˜0€X¹˜0€X¹˜0€X¹(c 0 ˛˛˜'0€¼˜'0€¼˜'0€¼˜'0€¼˜0€¼˜0€¼˜0€¼(c 0 ˛˛˜'0€¥À˜'0€¥À˜'0€¥À˜'0€¥À˜0€¥À˜0€¥À(c 0 ˛˛˜'0€~Ø'0€~Ø'0€~Ø'0€~Ø0€~Ø0€~Ã(c 0 ˛˛˜'0€ùŘ'0€ùŘ'0€ùŘ0€ùŘ0€ùÅ(c 0 ˛˛˜'0€BȘ'0€BȘ'0€BȘ0€BȘ0€BÈ(c 0˛˛˜'0€5ʘ'0€5ʘ'0€5ʘ0€5ʘ0€5Ê(c 0˛˛˜'0€Ì˜'0€Ì˜'0€Ì˜0€Ì˜0€Ì(c 0˛˛˜'0€ÐΘ'0€ÐΘ'0€ÐΘ0€ÐΘ0€ÐÎ(c 0˛˛˜'0€šÐ˜'0€šÐ˜'0€šÐ˜0€šÐ˜0€šÐ˜0€šÐ˜0€šÐ(c 0˛˛˜'0€8Ó˜'0€8Ó˜'0€8Ó˜0€8Ó˜0€8Ó(c 0˛˛˜'0€1Õ˜'0€1Õ˜'0€1Õ˜0€1Õ˜0€1Õ(c 0˛˛˜'0€;ט'0€;ט'0€;ט0€;ט0€;ט§ a0U€;ט§ a0V€;×(c 0˛˛˜'0€Ú˜'0€Ú˜'0€Ú˜0€Ú˜0€Ú(c 0˛˛˜'0€ËÛ˜'0€ËÛ˜'0€ËÛ˜0€ËÛ˜0€ËÛ(c 0˛˛˜'0€‘ݘ'0€‘ݘ'0€‘ݘ'0€‘ݘ'0€‘ݘ'0€‘ݘ0€‘ݘ0€‘ݘ0€‘Ýc 0 €€˜'0€pà˜'0€pà˜'0€pà˜0€pà˜0€pà˜0€pà˜0€pà˜0€pà˜0€pà˜0€pà˜0€pà˜0€pàc 0pàpà˜0€Z䘧 a0W€Z䘧 a0X€Z䘧 a0Y€Z䘧 a0Z€Zä˜a0€Zä˜a0€Zä˜a0€Zä˜a0€Zä(c 0ZäZä˜e0€”ë˜e0€”ë˜e0€”ë˜e0€”ë˜e0€”ë˜e0€”ë(c 0ZäZä˜e0€²ô˜e0€²ô˜e0€²ô˜e0€²ô˜e0€²ô(c 0ZäZä˜0€úø˜e0€úø˜e0€úø˜e0€úø˜e0€úø˜e0€úø˜e0€úø˜e0€úø˜e0€úø˜e0€úø˜e0€úø˜e0€úø˜e0€úø˜e0€úø˜e0€úø˜e0€úø(c 0ZäZä˜0€ ˜0€ ˜0€ ˜0€ ˜d0€ ˜d0€ ˜d0€ ˜d0€ ˜d0€ ˜d0€ ˜d0€ ˜d0€ ˜d0€ ˜d0€ c 0pàpà˜'0€ò˜'0€ò˜'0€ò˜0€ò˜0€ò˜0€òc 0pàpà˜'0€%˜'0€%˜'0€%˜0€%˜0€%˜0€%c 0pàpà˜'0€4˜'0€4˜0€4˜0€4˜0€4˜0€4˜0€4˜0€4˜0€4˜0€4˜0€4˜0€4˜0€4˜0€4˜0€4˜0€4˜0€4˜0€4˜0€4˜0€4c 0pàpà˜'0€§%˜'0€§%˜'0€§%˜0€§%˜0€§%˜0€§%c 0pàpà˜'0€~'˜'0€~'˜'0€~'˜0€~'˜0€~'˜0€~'c 0pàpà˜'0€é(˜'0€é(˜'0€é(˜'0€é(˜0€é(˜0€é(˜0€é(c 0pàpà˜'0€7*˜'0€7*˜'0€7*˜'0€7*˜'0€7*˜'0€7*˜0€7*˜0€7*c 0pàpà˜'0€U,˜'0€U,˜'0€U,˜'0€U,˜0€U,˜0€U,˜§ a0[€U,˜§ a0\€U,˜§ a0]€U,˜§ a0^€U,˜§ a0_€U,˜§ a0`€U,˜0€U,c 0 pàpà˜'0€¬/˜'0€¬/˜'0€¬/˜'0€¬/˜0€¬/˜a0€¬/˜0€¬/˜0€¬/c 0 pàpà˜'0€ñ1˜'0€ñ1˜0€ñ1˜0€ñ1˜0€ñ1c 0 pàpà˜'0€Œ5˜'0€Œ5˜'0€Œ5˜'0€Œ5˜0€Œ5˜0€Œ5˜= 0€Œ5˜= 0€Œ5˜0€Œ5c 0 pàpà˜'0€q;˜'0€q;˜'0€q;˜'0€q;˜0€q;˜0€q;˜= 0€q;c 0 pàpà˜'0€>˜'0€>˜'0€>˜'0€>˜'0€>˜0€>˜0€>c 0pàpà˜'0€ý?˜'0€ý?˜'0€ý?˜'0€ý?˜0€ý?˜0€ý?˜0€ý?˜0€ý?˜§ a0a€ý?˜§ a0b€ý?˜§ a0c€ý?˜a0€ý?˜a0€ý?˜§ a0d€ý?˜§ a0e€ý?˜0€ý?˜0€ý?˜ 0€ý?˜ 0€ý?˜ 0€ý?˜ 0€ý?˜0€ý?˜0€ý?˜0€ý?˜0€ý?˜0€ý?˜0€ý?˜0€ý?˜0€ý?˜0€ý?˜0€ý?˜0€ý?˜0€ý?˜0€ý?˜0€ý?˜0€ý?˜0€ý?˜0€ý?˜0€ý?c 0pàpà˜'0€CM˜'0€CM˜'0€CM˜0€CM˜0€CM˜0€CM˜0€CM˜e0€CM˜e0€CM˜e0€CM˜e0€CM˜e0€CM˜0€CM˜0€CM˜= 0€CM˜= 0€CM˜= 0€CM˜0€CM˜= 0€CM˜= 0€CM˜= 0€CM˜0€CM˜= 0 €CM˜= 0 €CM˜0€CM˜0€CM˜0€CM˜0€CM˜0€CM˜0€CM˜0€CM˜0€CM˜0€CM˜0€CM˜0€CM˜0€CMc 0pàpà˜'0€$\˜'0€$\˜'0€$\˜'0€$\˜'0€$\˜'0€$\˜0€$\˜0€$\˜0€$\˜0€$\˜0€$\c 0pàpà˜'0€^˜'0€^˜'0€^˜'0€^˜0€^˜0€^˜0€^˜0€^˜0€^˜0€^˜0€^˜0€^˜0€^˜0€^˜0€^c 0pàpà˜'0€!b˜'0€!b˜'0€!b˜'0€!b˜0€!b˜0€!b˜0€!b˜0€!b˜0€!b˜e0€!b˜e0€!b˜e0€!b˜e0€!b˜e0€!b˜e0€!b˜e0€!b˜e0€!b˜e0€!bc 0pàpà˜'0€×f˜'0€×f˜'0€×f˜'0€×f˜0€×f˜0€×f˜0€×f˜0€×f˜0€×f(c 0×f×f˜'0€Ëj˜'0€Ëj˜'0€Ëj˜'0€Ëj˜'0€Ëj˜0€Ëj˜0€Ëj˜0€Ëj˜0€Ëj˜0€Ëj˜0€Ëj˜0€Ëj˜0€Ëj˜0€Ëj˜e0€Ëj˜e0€Ëj˜0€Ëj˜0€Ëj˜A 0€Ëj˜A 0€Ëj˜0€Ëj˜0€Ëj˜0€Ëj˜0€Ëj(c 0×f×f˜'0€Ys˜'0€Ys˜'0€Ys˜'0€Ys˜0€Ys˜0€Ys˜0€Ys˜0€Ys˜0€Ys˜e0€Ys˜e0€Ys˜e0€Ys˜e0€Ys˜e0€Ys˜e0€Ys˜e0€Ys˜e0€Ys˜e0€Ys˜e0€Ys˜e0€Ys˜e0€Ys˜e0€Ys˜e0€Ys˜e0€Ys˜e0€Ys˜e0€Ys˜e0€Ys˜e0€Ys˜e0€Ys˜e0€Ys˜e0€Ys˜e0€Ys˜e0€Ys˜e0€Ys˜e0€Ys˜e0€Ys˜e0€Ys˜e0€Ys˜e0€Ys˜e0€Ys˜e0€Ys˜e0€Ys˜e0€Ys˜0€Ys˜0€Ys˜² 0€Ys˜C 0€Ys˜C 0€Ys˜C 0€Ys˜C 0€Ys˜C 0€Ys˜C 0€Ys˜C 0€Ys˜0€Ys˜0€Ys˜C 0€Ys˜C 0€Ys˜C 0 €Ys˜0€Ys˜0€Ys˜C 0 €Ys˜C 0 €Ys˜C 0 €Ys˜C 0 €Ys˜C 0€Ys˜C 0€Ys˜C 0€Ys˜C 0€Ys˜0€Ys˜² 0€Ys˜0€Ys˜² 0€Ys˜0€Ys˜² 0€Ys˜0€Ys˜0€Ys˜0€Ys˜0€Ys˜0€Ys˜0€Ys˜0€Ys˜0€Ys˜0€Ys˜0€Ys˜0€Ys˜0€Ys˜0€Ys˜0€Ys˜0€Ys˜0€Ys˜0€Ys˜0€Ys˜0€Ys˜0€Ys(c 0×f×f˜'0€Žž˜'0€Žž˜'0€Žž˜'0€Žž˜0€Žž˜0€Žž(c 0×f×f˜'0€¤ ˜'0€¤ ˜'0€¤ ˜'0€¤ ˜0€¤ ˜0€¤ (c 0×f×f˜'0€8£˜'0€8£˜'0€8£˜'0€8£˜'0€8£˜0€8£˜0€8£˜f0€8£˜0€8£˜0€8£˜e0€8£˜e0€8£˜e0€8£˜e0€8£˜e0€8£˜e0€8£˜0€8£˜0€8£˜³ 0€8£˜´ 0€8£˜´ 0€8£˜0€8£˜´ 0€8£˜´ 0€8£˜0€8£˜³ 0€8£˜0€8£˜³ 0€8£˜0€8£˜³ 0€8£˜0€8£˜0€8£˜0€8£˜0€8£˜0€8£˜0€8£˜0€8£˜0€8£˜0€8£˜0€8£˜0€8£˜0€8£˜0€8£˜0€8£˜0€8£˜0€8£˜0€8£˜0€8£˜0€8£˜0€8£˜0€8£˜0€8£˜0€8£˜0€8£˜0€8£˜0€8£˜0€8£˜0€8£(c 0×f×f˜'0€¢¶˜'0€¢¶˜'0€¢¶˜'0€¢¶˜0€¢¶˜0€¢¶˜0€¢¶(c 0×f×f˜'0€k»˜'0€k»˜'0€k»˜'0€k»˜0€k»˜0€k»(c 0×f×f˜'0€«¼˜'0€«¼˜'0€«¼˜'0€«¼˜0€«¼˜0€«¼˜§ a0f€«¼˜§ a0g€«¼˜§ a0h€«¼˜§ a0i€«¼˜a0€«¼˜a0€«¼(c 0×f×f˜'0€åÀ˜'0€åÀ˜'0€åÀ˜'0€åÀ˜0€åÀ˜0€åÀ(c 0 ×f×f˜'0€á˜'0€á˜'0€á˜'0€á˜0€á˜0€áÂ(c 0 ×f×f˜'0€óĘ'0€óĘ'0€óĘ'0€óĘ0€óĘ0€óÄ(c 0 ×f×f˜'0€ÅŘ'0€ÅŘ'0€ÅŘ'0€ÅŘ0€ÅŘ0€ÅÅ(c 0 ×f×f˜'0€øÆ˜'0€øÆ˜'0€øÆ˜'0€øÆ˜'0€øÆ˜0€øÆ˜0€øÆ(c 0 ×f×f˜'0€`ɘ'0€`ɘ'0€`ɘ'0€`ɘ'0€`ɘ0€`ɘ0€`ɘC 0€`ɘC 0€`ɘC 0€`ɘ0€`ɘ0€`ɘ0€`ɘ0€`ɘ0€`ɘ0€`ɘ0€`É(c 0×f×f˜'0€¹Ï˜'0€¹Ï˜'0€¹Ï˜'0€¹Ï˜'0€¹Ï˜0€¹Ï˜0€¹Ï˜0€¹Ï˜0€¹Ï˜0€¹Ï˜0€¹Ï˜0€¹Ï(c 0×f×f˜'0€Ó˜'0€Ó˜'0€Ó˜'0€Ó˜'0€Ó˜0€Ó˜0€Ó˜0€Ó˜µ 0€Ó˜0€Ó˜µ 0€Ó˜0€Ó˜µ 0€Ó˜0€Ó˜µ 0€Ó(c 0×f×f˜'0€Éݘ'0€Éݘ'0€Éݘ'0€Éݘ'0€Éݘ0€Éݘ0€ÉÝ(c 0×f×f˜'0€Àߘ'0€Àߘ'0€Àߘ'0€Àߘ0€Àߘ0€Àߘ0€Àߘ0€Àߘ0€Àߘ0€Àߘ0€ÀߘH 0€ÀߘH 0€ÀߘH 0€ÀߘH 0€ÀߘH 0€ÀߘH 0€ÀߘH 0€Àߘ0€Àߘ0€Àߘ0€Àߘ0€Àߘ0€Àߘ0€Àߘ0€Àߘ0€Àߘ0€Àߘ0€Àߘ0€Àߘ0€Àߘ0€Àß(c 0×f×f˜'0€Âø˜'0€Âø˜'0€Âø˜0€Âø˜0€Âø˜0€Âø˜0€Âø˜K 02€Âø˜K 03€Âø˜0€Âø˜0€Âø˜0€Âø˜0€Âø˜0€Âø˜0€Âø˜0€Âø˜0€Âø˜0€Âø˜0€Âø˜0€Âø˜0€Âø(c 0×f×f˜'0€ˆ˜'0€ˆ˜'0€ˆ˜'0€ˆ˜0€ˆ˜0€ˆ˜K 04€ˆ˜0€ˆ˜0€ˆ˜0€ˆ˜0€ˆ˜0€ˆ˜0€ˆ˜0€ˆ˜0€ˆ˜0€ˆ˜f0€ˆ˜¥ 0€ˆ˜¥ 0€ˆ˜¥ 0€ˆ˜¥ 0€ˆ˜¥ 0€ˆ˜¥ 0€ˆ˜¥ 0€ˆ˜¥ 0€ˆ˜¥ 0€ˆ˜¥ 0 €ˆ˜¥ 0 €ˆ˜¥ 0 €ˆ˜¥ 0 €ˆ˜¥ 0 €ˆ˜0€ˆ˜f0€ˆ˜ª 0€ˆ˜ª 0€ˆ˜ª 0€ˆ˜ª 0€ˆ˜ª 0€ˆ˜ª 0€ˆ˜ª 0€ˆ˜ª 0€ˆ˜ª 0€ˆ˜ª 0 €ˆ˜ª 0 €ˆ˜ª 0 €ˆ˜ª 0 €ˆ˜ª 0 €ˆ(c 0×f×f˜'0€ý#˜'0€ý#˜'0€ý#˜'0€ý#˜'0€ý#˜0€ý#˜0€ý#˜§ a0j€ý#˜§ a0k€ý#˜§ a0l€ý#(c 0×f×f˜'0€¯(˜'0€¯(˜'0€¯(˜'0€¯(˜'0€¯(˜0€¯(˜0€¯((c 0×f×f˜'0€†*˜'0€†*˜'0€†*˜'0€†*˜'0€†*˜0€†*˜0€†*(c 0×f×f˜'0€,˜'0€,˜'0€,˜'0€,˜'0€,˜0€,˜0€,(c 0×f×f˜'0€.˜'0€.˜'0€.˜'0€.˜'0€.˜'0€.˜0€.˜0€.˜0€.˜0€.c 0 €€˜'0€À1˜'0€À1˜0€À1c 0 €€˜'0€L3˜'0€L3˜'0€L3˜0€L3˜0€L3˜0€L3˜0€L3˜0€L3˜0€L3˜0€L3˜0€L3˜« 0€L3˜« 0€L3c 0L3L3˜'0€77˜'0€77˜'0€77˜'0€77˜'0€77˜'0€77(c 07777˜0€-8˜0€-8˜0€-8˜0€-8˜0€-8˜0€-8˜¬ 0€-8˜¬ 0€-8˜¬ 0€-8(c 07777˜0€Ð:˜0€Ð:(c 07777˜0€D<˜0€D<(c 07777˜0€¿=˜0€¿=˜0€¿=˜0€¿=˜0€¿=˜0€¿=c 0L3L3˜'0€?˜'0€?˜'0€?˜'0€?˜'0€?˜'0€?˜'0€?˜'0€?˜'0€?˜0€?(c 0??˜0€ã@˜0€ã@˜0€ã@(c 0??˜0€¶B(c 0??˜0€C˜0€C(c 0??˜0€ÏC˜0€ÏC˜0€ÏC˜0€ÏC˜0€ÏC˜0€ÏC˜0€ÏC˜0€ÏC˜0€ÏC˜0€ÏC˜0€ÏC˜0€ÏC˜0€ÏC˜0€ÏC(c 0??˜0€.G˜0€.G˜0€.G˜0€.G˜0€.G©0€.G©0€.G©0€.G©0€.G©0€.G©0€.G©0€.G©0€.G©0€.G™0€.G©0€.G©0€.G©0€.G©0€.G©0€.G©0€.G™0€.G©0€.G©0€.G©0€.G©0€.G©0€.G©0€.G™0€.G©0€.G©0€.G©0€.G©0€.G©0€.G©0€.G™0€.G©0€.G©0€.G©0€.G©0€.G©0€.G©0€.G™0€.G©0€.G©0€.G©0€.G©0€.G©0€.G©0€.G™0€.G©0€.G©0€.G©0€.G©0€.G©0€.G©0€.G™0€.G©0€.G©0€.G©0€.G©0€.G©0€.G©0€.G™0€.G©0€.G©0€.G©0€.G©0€.G©0€.G©0€.G™0€.G©0€.G©0€.G©0€.G©0€.G©0€.G©0€.G™0€.G©0€.G©0€.G©0€.G©0€.G©0€.G©0€.G™0€.Gc 0L3L3˜0€`J(c 0`J`J˜0€=K˜® 0€=K˜® 0€=K˜® 0€=K˜® 0€=K˜® 0€=K˜0€=K˜0€=K˜0€=K˜0€=K˜­ a0€=K˜­ 0€=K˜­ 0€=K˜0€=K˜0€=K˜0€=K˜0€=K(c 0`J`J˜0€jP˜0€jP˜0€jP˜0€jP˜0€jP˜0€jP˜0€jP˜0€jP˜0€jP˜0€jP˜0€jP˜0€jP˜0€jP˜0€jPc 0L3L3(c 0UU˜0€HU˜0€HU˜0€HUc 0€€˜'0€.W˜'0€.W˜'0€.W˜0€.Wc 0.W.W˜'0€Y˜'0€Y˜'0€Y˜0€Y˜0€Y˜0€Y˜0€Yc 0.W.W˜'0€E]˜'0€E]˜'0€E]˜0€E]˜0€E]c 0.W.W˜'0€ž_˜'0€ž_˜'0€ž_˜0€ž_˜0€ž_˜0€ž_c 0€€˜'0€¸a˜'0€¸a˜'0€¸ac 0¸a¸a˜'0€Çc˜'0€Çc˜'0€Çc˜'0€Çc˜0€Çcc 0¸a¸a˜'0€]f˜'0€]f˜'0€]f˜'0€]f˜0€]fc 0¸a¸a˜'0€¸h˜'0€¸h˜'0€¸h˜'0€¸h˜0€¸hc 0¸a¸a˜'0€±j˜'0€±j˜'0€±j˜'0€±j˜0€±jc 0¸a¸a˜'0€l˜'0€l˜'0€l˜'0€l˜0€lc 0¸a¸a˜'0€An˜'0€An˜'0€An˜'0€An˜0€Anc 0¸a¸a˜'0€p˜'0€p˜'0€p˜'0€p˜0€pc 0¸a¸a˜'0€!s˜'0€!s˜'0€!s˜'0€!s˜0€!sc 0¸a¸a˜'0€»t˜'0€»t˜'0€»t˜'0€»t˜0€»tc 0 ¸a¸a˜'0€¢v˜'0€¢v˜'0€¢v˜'0€¢v˜0€¢vc 0 ¸a¸a˜'0€Yx˜'0€Yx˜'0€Yx˜'0€Yx˜0€Yxc 0 ¸a¸a˜'0€Æy˜'0€Æy˜'0€Æy˜'0€Æy˜0€Æy˜0€Æy˜¨ 0€Æy˜¨ 0€Æy˜¨ 0€Æyc 0 ¸a¸a˜'0€ }˜'0€ }˜'0€ }˜'0€ }˜'0€ }˜0€ }c 0 ¸a¸a˜'0€I~˜'0€I~˜'0€I~˜'0€I~˜'0€I~˜0€I~c 0¸a¸a˜'0€X˜'0€X˜'0€X˜'0€X˜'0€X˜0€Xc 0¸a¸a˜'0€‚€˜'0€‚€˜'0€‚€˜'0€‚€˜'0€‚€˜0€‚€˜0€‚€c 0¸a¸a˜'0€Ò˜'0€Ò˜'0€Ò˜'0€Ò˜'0€Ò˜'0€Ò˜0€Ò˜0€Ò(c 0ÒÒ˜'0€L„˜'0€L„˜'0€L„˜'0€L„˜'0€L„˜0€L„(c 0ÒÒ˜'0€7‡˜'0€7‡˜'0€7‡˜'0€7‡˜'0€7‡˜0€7‡˜© 0€7‡˜© 0€7‡˜© 0€7‡˜0€7‡˜0€7‡(c 0ÒÒ˜'0€÷‹˜'0€÷‹˜'0€÷‹˜'0€÷‹˜'0€÷‹˜0€÷‹˜0€÷‹(c 0ÒÒ˜'0€lŽ˜'0€lŽ˜'0€lŽ˜'0€lŽ˜'0€lŽ˜0€lŽ˜0€lŽ(c 0ÒÒ˜'0€¥‘˜'0€¥‘˜'0€¥‘˜'0€¥‘˜'0€¥‘˜0€¥‘(c 0ÒÒ˜'0€x“˜'0€x“˜'0€x“˜'0€x“˜'0€x“˜0€x“c 0€€˜0€g•˜`0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜t0€g•˜@t0€g•c 0€€˜0€øœc 0øœøœ˜0€h˜0€h˜g0€h˜g0€h˜g0€h˜g0€h˜g0€h˜g0€h˜g0€h˜g0€h˜g0€h˜g0€h˜g0€h˜g0€h˜g0€h˜g0€h˜g0€h˜g0€h˜g0€h˜g0€h˜g0€h˜g0€h˜g0€h˜g0€h˜g0€h˜g0€h˜g0€h˜g0€h˜g0€h˜g0€h˜g0€h˜g0€h˜g0€h˜g0€h˜g0€h˜g0€h˜g0€h˜g0€hc 0øœøœ˜g0€x£˜g0€x£˜g0€x£˜g0€x£˜g0€x£˜g0€x£˜g0€x£˜g0€x£˜g0€x£˜g0€x£˜g0€x£˜g0€x£˜g0€x£˜g0€x£˜g0€x£˜g0€x£˜g0€x£˜g0€x£˜g0€x£˜g0€x£˜g0€x£˜g0€x£˜g0€x£˜g0€x£˜g0€x£˜g0€x£˜g0€x£˜g0€x£˜g0€x£˜g0€x£˜g0€x£˜g0€x£˜g0€x£˜g0€x£˜g0€x£˜g0€x£˜g0€x£˜g0€x£˜g0€x£˜g0€x£˜g0€x£˜g0€x£˜g0€x£˜g0€x£˜g0€x£˜g0€x£˜g0€x£˜g0€x£˜g0€x£˜g0€x£˜g0€x£˜0€x£c 0€€c 0›¬›¬˜0€¡¬˜@+0€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜`+0€¡¬˜+0€¡¬˜0€¡¬˜`0€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜90€¡¬˜`0€¡¬˜0€¡¬˜0€€š0€€˜0€€š0€€š0€€š0€€š0€€š0€€~~~~~~~~~~‘‘ýýýýýýýýýýýýýýýýýýýýýýýýýýý( Ld{@é ¢"y$™&Q)n+¯.k14†69Š;W>PA«CÜFJM’O·RpUÀX(\Œ_Ubød„hpk(nùpäs wz³}a€d‚ᄲ‡wŠ üŽ ”ƒžg£r¨Á¬V´r»FÊ<ÚÅèñ‹…‹s'û<ÅE¹S@Yåcu|Ou‡¼Œ”Oš¡¶¥¬¨­\±Z¸ ½2ÃPȵÌüÐþÖÚÞÞ¾äÝènî›ýÍ …Ì(º2f<‚DÁJíR·]éeðo3zy…ݵš@£+±’¾àÓ@Þö?þ!© "¦+‹; Mø[spõ„2ŽR–H›6£?ª#¶ï¿iÅÍÔ€Û>ã ëlò_þ}íÊ'›.)8`@¦J×S!_[c-m_t•zî~>„iW–©¡ó­¹(¾îĦÊ}ÐÖdÛ^àgã{è§í¼õ«ühâ=:µ¬ u*Â6†> E™N–ZhdËmravõ{؆‘˜÷£È­G¸Æ|Ñ1Ú©â§è¶òÑ÷ ð ‰À"q.07…? F)O­\²e—ktö|–„yŽK—v¡"©&²p»z¿iÉþÐAØ›ßæŸûíÊPC#Q/[5X9¦@”GcNŒV•](e€jatÜ}†úŒò–µš§e«P±åÖ,/0235678:;<>?@ACDEGHIJLMNOQRSUVWXZ[\^_`acdefhijlmnoprsuwz|~€‚ƒ„…‰ŠŽ’–˜™š›œžŸ ¡¢£¥¦§¨ª«¬­®¯°²³µ·¹»½¿ÁÃÅÇÉËÍÐÒÔØÛÝßáãåçéêíðòôùûýþ   "$&(*,./01468:<=?@BCDFGHIJLNOQSTUXZ\]_`bdefhjloqsuwy{}€ƒ„…‡ˆ‹’•—™›ž ¡£¥§©«­¯±²´¶·¹»¼¾ÀÁÃÅÇÒÔÕ×ÙÛÝßáãëíï`ÞÝ /(¼1ü: E´OZ‘eApÀ{脆Žñ©¹‚Á¶ÍpÕ¦Þ”ê›óÔ‡+v0r8gGMÇQƒYÖaXfi/pzF—AµÌ,ê,*Ü!'J6u>FrMV#díl±uz{Z†ߌ–…œ¥ë¨ò­t·ýoÅ#Ô.èòöêÿx }Ø*%9’>¶HÄTh_¼s)wÑ{ƒ›‹‘_¡+©®à¶!ÁÏ™ÓÚ<é;ïøƒ Ž!§)š/':A¦JGV³_jdqb…O–1 `«×¶mÀ½ÊÀÝûä—Æº q'ž/;>öK—bîiD{FƒLˆ|“ š[¡è¨2±v¼ÐÉÔîÜeæ±ù>à$)-ˆ2Ž;™G×Q³ZØbòh,qµ{'ˆß™£¯«—¸E¼`ÆôÌsÕHãÎûÀ‰Ÿ)š1 ;DAHzN°NÅNßNOO$OAO_O&QZ7eBpBz’‚‡÷T™›$xž÷ŸÀ ¡2¤¨ï¬›±ݳ6¶X¸8ºE¼c¾uÀ¹Â ÅGÇmÉCËÍóÎÀлҎÔvÖåÖ-149=BFKPTY]bgkqtvxy{}†‡ˆ‹Œ‘“”•—¤©±´¶¸º¼¾ÀÂÄÆÈÊÌÎÏÑÓÕÖ×ÙÚÜÞàâäæèëìîïñóõö÷øúüÿ   !#%')+-23579;>AEKMPRVWY[^acgikmnprtvxz|~‚†‰ŠŒŽ‘“”–˜šœŸ¢¤¦¨ª¬®°³µ¸º½¿ÂÄÆÈÉÊËÌÍÎÏÐÑÓÖØÚÜÞàâäåæçèéêìîðñòóôõö÷øùúûüýþÿäÖ.)+|¢¤5]vÐ)€¾ïô+±ÈÙ(ó  ' 2 N Q ,`qš¶¸Éåè Yux¬¯Äàã;>Lhk€œŸ½ÙÜí  B^aœ¸»è+GJc‚«ÇÊù?[^v’•´ÐÓë )EH`|›·ºä.1Wsvˆ¤§¸Ô×ð %ADTps©¬ßûþ25Wsv‰¥¨¼ØÛé!=@Yux«®¿ÛÞþ9UX‚ž¡»×Ú@\_„ £ÀÜßø  0 L O \ x { š ¶ ¹ Ó ï ò !+!.!F!b!e!¤!À!Ã!æ!""/"K"N"z"–"™"Ò"î"ñ"#9#<#d#€#ƒ#³#Ï#Ò#$*$-$`$|$$°$Ì$Ï$%%%P%l%o%š%¶%¹%Ø%ô%÷%+&G&J&o&‹&Ž&Å&á&ä&'' 'M'i'l'ž'º'½'û'((J(f(i(¢(¾(Á()$)')n)Š))¾)Ú)Ý)&*B*E*”*°*³*ô*++A+]+`+’+®+±+à+ü+ÿ+N,j,m,™,µ,¸,ý,--O-k-n-›-·-º-ó-..P.l.o.¡.½.À.ì./ /E/a/d//©/¬/ã/ÿ/0)0E0H0o0‹0Ž0Ó0ï0ò0.1J1M1v1’1•1Â1Þ1á12-202g2ƒ2†2²2Î2Ñ23!3$3M3i3l3¢3¾3Á3ä34474S4V4”4°4³4ê45 5G5c5f5 5¼5¿56 6#6O6k6n66¬6¯6Û6÷6ú6'7C7F7o7‹7Ž7±7Í7Ð7ü788l8ˆ8‹8º8Ö8Ù8939699©9¬9þ9::W:s:v:«:Ç:Ê:;,;/;;; ;ê;< <M<i<l<ž<º<½<è<==5=Q=T=m=‰==Ê=æ=ê=/>K>O>ˆ>¤>¨>á>ý>?.?J?N?Š?¦?ª?ç?@@5@Q@U@ƒ@Ÿ@£@ë@A AFAbAfAœA¸A¼AíA B BBB^BbBÁBÝBáBDC`CdC­CÉCÍC#D?DCD„D D¤DÔDðDôD:EVEZEžEºE¾EóEFFXFtFxF¯FËFÏFG;G?GˆG¤G¨G H%H)HpHŒHHºHÖHÚHI I$IMIiImI–I²I¶IJJ"JRJnJrJ§JÃJÇJïJ KKHKdKhK’K®K²KãKÿKL?L[L_L•L±LµLM!M%M{M—M›MN!N%N[NwN{NœN¸N¼NõNOOPOlOpO O¼OÀOPP PWPsPwP¬PÈPÌPþPQQTQpQtQ¾QÚQÞQ)RERIRŸR»R¿RúRSSPSlSpS¶SÒSÖS&TBTFTžTºT¾TUU UaU}UU½UÙUÝUV/V3V{V—V›VäVWW;WWW[W§WÃWÇW X)X-X•X±XµXÿXYY‡Y£Y§YëYZ Z[ZwZ{Z²ZÎZÒZ ['[+[p[Œ[[Ó[ï[ó[-\I\M\„\ \¤\Ü\ø\ü\:]V]Z]–]²]¶]á]ý]^:^V^Z^p^Œ^^Æ^â^æ^__"_[_w_{_·_Ó_×_!`=`A`‹`§`«`ø`aaoa‹aaòabb`b|b€bÑbíbñb8cTcXc™cµc¹cd#d'did…d‰dÃdßdãd+eGeKeˆe¤e¨eãeÿefIfefifœf¸f¼fùfggTgpgtgÙgõgùgh5h9hfh‚h†hÂhÞhâh*iFiJiyi•i™iÄiàiäi j)j-jjj†jŠj²jÎjÒjk2k6kWkskwkÊkækêkl;l?ltll”lÞlúlþl5mQmUmŒm¨m¬mêmn ncnnƒn·nÓn×no,o0oho„oˆoÉoåoéo9pUpYpp©p­p$q@qDq…q¡q¥qÜqøqüq^rzr~r°rÌrÐr s%s)stss”sËsçsës.tJtNt‹t§t«tÝtùtýtJufuju§uÃuÇuýuvvƒvŸv£vØvôvøvžwºw¾wôwxxXxtxxxÉxåxéx"y>yBy—y³y·yðy zzYzuzyzÐzìzðzK{g{k{‘{­{±{Ê{æ{ê{|$|(|F|b|f||›|Ÿ|ä|}}%}A}E}^}z}~}—}³}·}Ô}ð}ô}C~_~c~…~¡~¥~Â~Þ~â~"&Eae‹§«ý€€r€Ž€’€Æ€â€æ€%AE¡î ‚‚<‚X‚\‚”‚°‚´‚á‚ý‚ƒ>ƒZƒ^ƒ—ƒ³ƒ·ƒóƒ„„U„q„u„¶„Ò„Ö„…#…'…X…t…x…¦…Â…Æ… †(†,†\†x†|†­†É†Í†‡5‡9‡l‡ˆ‡Œ‡Â‡Þ‡â‡ ˆ)ˆ-ˆUˆqˆuˆ­ˆÉˆÍˆ ‰&‰*‰z‰–‰š‰»‰×‰Û‰í‰ Š Š(ŠDŠHŠdŠ€Š„ŠŠ¬Š°ŠßŠûŠÿŠ‹‹‹¶‹¼‹¿‹ç‹ŒfŒ‘Œ­ŒŽ:Ž<ŽV“q“s“å•–––A–`–™1™3™iš„š‹š¿šÚšàšþš› ›œ-œ6œ³ÍØkž†žžþžŸ Ÿ / : Þ ù ¡Î¢è¢í¢|£—£ž£P¤k¤r¤Û¤ö¤ú¤¥¥¥Û¦ö¦þ¦§-§5§y§”§›§¨¨Â¨É¨g©‚©‰©êª« «4«O«S«¬¬#¬H­c­g­V°q°x°¸5¸>¸¸«¸´¸­ÄÇÄÉÄ,ÆFÆHÆyÆ’Æ•ÆçÈÉÉ É$É'ÉsÉÉÉ–É°É³É à%à)à¬áÇáËáIâdâhâ¦äÁäÅäUåpåtåZæuæyæÝçøçüçOèjènè ì(ì,ìííífòò…òë 2=sŽ—Ýø K f o Å à æ .5Þøþ39Nhsç ãþ4OVÁÜߌ§¬qŒ“Èãè2MTYt{€›¢‚!!¤!Z#t#{#È&â&æ&×'((·.Ð.Õ.â8ü89§:À:Å:¦;À;Ç;X<q<v<ü<==¦>Á>Å>ZDtDyD…EŸE£EK©K®K¸OÒOÖOôOPPP2P8PSPmPrP‘W¬W³WØYóYúYõabb¾gØgÞg§nÁnÆn’o¬o®oq!q#q‚:‚O‚厜7œ>œFŸ`ŸeŸ¡·¡¼¡2£L£Q£¥,¥1¥@§[§_§G¨b¨f¨v©‘©•©úª««Ý«ø«ü« ­&­*­d¯¯ƒ¯®°ɰ̰®±ɱ̱*¶E¶I¶l·‡·‹·Ö·ñ·÷·½+½2½ß½ù½ÿ½¿¾Ù¾à¾2¿M¿U¿aÁ{Á€Á¿ÃÙÃàÃ=ÅWÅ]ŸÅÓÅÛÅÙÆóÆùÆ[ÇvÇ~ÇNÎhÎmΪÐÅÐÌÐDÒ^ÒcÒVÓqÓvÓ"Ô<ÔEÔßÔùÔÕ¬ÕÇÕÍÕU×o×u×½Øרߨ Ù'Ù0ÙÞÚøÚþÚ/ÛIÛOÛ?àZà\à$â>âFâã!ã)ãÚãôãýãœä¶ä¿ä æ%æ*æ$ç?çFçˆç£ç¨ç®èÉèÐèé-é2é¢é¼éÃé9ðTðWð%ô@ôDô‘ö¬ö°ö»ûÕûÝûçÿ ‚œ ®ÉÍ7QU!$;$B$±$Ì$Ð$Á%Û%ã%é)* *--G-K-ñ0 11{3•3™37¸7¼7å;<<à=û=ÿ=¹>Ô>Ö>h@ƒ@‡@‰B¤B¨BqCŒCCFF!F§FÁFÈFiG„G‹G H&H-H—H²H¹HÆIáIæIéPQQ{Z–ZžZv4v;vÒwíwôw5‚P‚W‚»ŠÖŠÝŠ ‹$‹*‹Kfn’7’>’k’…’‹’H”c”j”[–v–~–µšÏšÔš¸œÓœÕœûžŸŸýŸ  jƄƉÆ#Í<ÍEÍÂÎÛÎàÎüÎÏÏOÐhÐqÐ ×(×*×7ØRØTØÿÙÚÚÍñæñíñœòµòºòóó$ópõ‰õõf÷÷†÷{û–ûû!ý<ýDýJýeýlý±ýÊýÑý &.4OVލ®d}„!:!A!Œ&§&°&(™( (Û.õ.ú.Å1ß1æ1=,=3==BXB_BH˜HŸH¸JÓJÛJáJüJKËcæcícˆi¡i¨i1jJjRjÀ{Û{ß{«~Æ~Í~w•ô €€‚‚‚¢‚°ÊÑ 'R‘m‘r‘7œPœYœƒŸžŸ£Ÿ“¢¬¢±¢È¢ã¢è¢ÿ¢££ß«ú«¬±±#±Gºaºhº”º®º°ºͺçºïº»"»*»D»^»f»¦¾À¾ƾOÀiÀkÀ¼ÀÖÀÚÀ@ÈZÈcțȵȹÈ>ÊXÊaÊõÒÓÓÈØâØëØ(ÙBÙKÙÛ9ÛAÛúàááá©á±á®èÈèÎè¯êÉêÑêÅðÞðåðhø‚ø…ø«øÅøÈø@úZú]úŸúºú½ú8ûSûVû‡û¢û§û7üRüUüý,ý/ý.HM5OX/ I P   % €š 7 P V ý%&&O)i)r)x)’)›)ä6ÿ67¯9Ê9Ð9sCŽC‘C¹DÔDÛDmFˆFFúGHHXMrMyMñM NNôTUUU§U­U,YFYLYZ"Z(Z"[<[B[e[[…[·[Ò[×[s\\“\™\³\¹\Z^„^ˆ^`)`/`b b&b-hGhLh"k}>ˆ>8@c@n@q@œ@§@ª@Õ@à@æ@AAAI\I^ICK^K`KÛOP PÅTàTéT|U—U™UÁVÜVçV7\a\h\]2];]4aNaYa#c>cGc%d?dHd5eOeXe²hÌhÓh·iÒiÝi¬jÆjÍj\kvk}kÃlÝlälzo”o›o!p;pApöpqq:rTrYrss(su"u-uv6vAvÎvévòv y&y1yžz¹zÄzðz {{R‚m‚x‚þ‚ƒ#ƒƒ¸ƒÃ´†ΆÙ†Õ‰ð‰û‰wŠ’Š›Šc‹}‹†‹.IT¼×âÑ‘ë‘ó‘À–Ú–Ü–d™~™‚™Ûžöžÿž_ŸyŸ€Ÿ©"©(©.©H©N©d²~²…²©¶öʶá¸û¸¹È8È?ÈÊ+Ê2Ê[ÌuÌ|Ì¬ÎÆÎÍΜѷѾÑÓ.Ó4ÓÍÓèÓñÓÅÕàÕéÕÿØÙ#ÙæÜÝÝšß´ß»ßLàfàlàá§áªá¶áÐáÓáÚáôá÷á'äAäFäê3ê9êì1ì7ì‚ìœì¢ìÀìÚìàì•í¯íµíîî"î@îZî`î¾îØîÞîüîïïëïð ðñ9ñ@ñ²òÌòÑòƒóó¨ó ö&ö.öêö÷ ÷ø.ø7øWúqú|úC]b‡¡§÷J d f q ‹ “ ß ù  k…‹«ÅË.9‡¡¬ %0A\aÙôúÝ÷üì Å"ß"ä"Ü&ö&û&0,J,Q,C3^3a3“3®3³3I4d4l4ò4 55h5ƒ5ˆ5G7`7e7=-=3=Ü=õ=÷=?2?8?ÏFùFþFH·H¼H´IÎIÕIK8K?K¾NØNßNáPûPQR›R£RæTUU­WÇWÏWéXY Y[]u]{]-^G^M^Ea`aiaqc‹ccEd_dedf*f2fHfbfjf~f˜fžf´fÎfÔfÊgägêg¬hÆhÌh1jLjTjo!o'oSoloro!q;qAq8wRwYwÌwõwýwnxˆxŽxØz{ {y|“|œ|Ç}â}ë}—~À~É~ÃÞ瘳¼ ‚'‚0‚±ˆʈÒˆJ‰c‰l‰ýŠ‹ ‹%Œ>ŒFŒÛŒôŒýŒŽ¨Ž±Žc~‡–‘¯‘·‘1’L’U’Ü“÷“”|™–™ž™aš{š‚šV o w º¢Ô¢ߢ‰¦£¦«¦ɨã¨ê¨/«J«S«Œ°§°°°¹¸Ó¸Û¸Þ¸ù¸¹¹¹$¹'¹A¹G¹>ºYº\ºaºyºíºG»b»g»:ÉTÉ]ÉÍ+Í2Í‰Í£ÍªÍ Î&Î-ÎÏ Ï"ςќѧђҬҳÒÕÕ&ÕóÕ ÖÖå×ÿרšÙ´Ù¿Ù‚ڜڣڔۮ۷ۇܱܺÜß8ßAß0çJçSçÎçèçïçjé„éé¯ùÉùÔù=úWú\úCû]ûhûöÒíöB\ac } † Œ ¦ ¯ þ  ! ± Ë Ô F`cФ­iƒ†¦ÀÂ~˜¡×ñõ·À3MPÆá㚣ù¹ÓÖ®ÈËMgj”®·#›##Æ&à&é&R)l)n)Q*k*t*ë+,,Z0t0{0—1²1½1Ã2î2ñ234M4P4W4q4t4m:ˆ::;§;­;Œ@¦@¬@zB•BœBñB CCªCÅCÌCÓFíFòFQNjNoN·PÒPÙP°TËTÍT3XMXPXSXmXpXvX‘X”XîXY YC[a[p["]=]A]}_—_š_•b°bµbïb c cc)c,c2cMcPc›cµc¸cEo`ofoùpqq;qVq[qƒƒ"ƒõ†‡‡:ŠTŠ\Š0ŽJŽRޏÒÖ¶’Ñ’Õ’æ’““¥”À”ĔՔï”ñ”½žGžåžÿžŸá£û£¤ʬ߬gśŰÅäÐåÑX”ÿ•„X”ÿ•„X”ÿ•„X”ÿ•€X”ÿ•„Xÿ€XÿŒXÿŒTÿ•€%Tÿ•€ 4ÿ%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À%Tÿ•À•Œ”ÿ•€”•€Xÿ€Tÿ•€Tÿ•€”ÿ•€”ÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€”ÿ•€”ÿ•€”ÿ•€tÿ•€tÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€”ÿ•€Tÿ•€Xÿ€”ÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€Tÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€Tÿ•€Tÿ•€Tÿ•€”ÿ•€”ÿ•€ôÿ•€ôÿ•€XTÿ€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€”ÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€ôÿ•€ôÿ•€Tÿ•€”ÿ•€”ÿ•€Ôÿ•€”ÿ•€”ÿ•€Tÿ•€ôÿ•€ôÿ•€ôÿ•€4ÿ•€tÿ•€tÿ•€tÿ•€tÿ•€tÿ•€”ÿ•€Tÿ•€Tÿ•€Tÿ•€ôÿ•€”ÿ•€tÿ•€Tÿ•€tÿ•€”ÿ•€Tÿ•€”ÿ•€ôÿ•€”ÿ•€tÿ•€tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€”ÿ•€”ÿ•€Tÿ•€T•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€”ÿ•€Tÿ•€Tÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€Tÿ•€Tÿ•€Tÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€Tÿ•€Tÿ•€Tÿ•€”ÿ•€Tÿ•€Tÿ•€ôÿ•€”ÿ•€Tÿ•€tÿ•€ôÿ•€”ÿ•€Tÿ•€”ÿ•€Tÿ•€”ÿ•€Tÿ•€Tÿ•€Tÿ•€”ÿ•€”ÿ•€tÿ•€Tÿ•€”ÿ•€”ÿ•€Tÿ•€”ÿ•€Tÿ•€Tÿ•€”ÿ•€Tÿ•€”ÿ•€Tÿ•€”ÿ•€4ÿ•€4ÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€ôÿ•€”ÿ•€ôÿ•€”ÿ•€”ÿ•€ôÿ•€Tÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€Ôÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Ôÿ•€Ôÿ•€ôÿ•€Tÿ•€Tÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€tÿ•€tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€Tÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€ôÿ•€ôÿ•€Tÿ•€ôÿ•€ôÿ•€ôÿ•€ôÿ•€Tÿ•€Tÿ•€Tÿ•€”ÿ•€”ÿ•€”ÿ•€Tÿ•€”ÿ•€Ôÿ•€Tÿ•€Tÿ•€”ÿ•€ôÿ•€”ÿ•€”ÿ•€T•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€tÿ•€tÿ•€tÿ•€Tÿ•€Tÿ•€tÿ•€tÿ•€tÿ•€tÿ•€tÿ•€tÿ•€tÿ•€tÿ•€ôÿ•€ôÿ•€Tÿ•€ôÿ•€ôÿ•€ôÿ•€ôÿ•€ôÿ•€ôÿ•€T•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€ôÿ•€”ÿ•€4ÿ•€4ÿ•€ôÿ•€4ÿ•€4ÿ•€Ôÿ•€Ôÿ•€4ÿ•€Ôÿ•€4ÿ•€Tÿ•€Tÿ•€Xÿ€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€4ÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€tÿ•€Tÿ•€Tÿ•€”ÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€”ÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€ôÿ•€”ÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€”ÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€ôÿ•€Tÿ•€Tÿ•€Tÿ•€tÿ•€Tÿ•€Tÿ•€Tÿ•€tÿ•€tÿ•€ôÿ•€Tÿ•€tÿ•€tÿ•€tÿ•€ôÿ•€ôÿ•€Tÿ•€tÿ•€tÿ•€tÿ•€Tÿ•€Tÿ•€tÿ•€Tÿ•€ôÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€tÿ•€Tÿ•€Tÿ•€tÿ•€tÿ•€tÿ•€Tÿ•€ôÿ•€”ÿ•€”ÿ•€ôÿ•€ôÿ•€”ÿ•€ôÿ•€ôÿ•€ôÿ•€ôÿ•€tÿ•€tÿ•€Tÿ•€Tÿ•€Tÿ•€ôÿ•€”ÿ•€ôÿ•€”ÿ•€”ÿ•€Ôÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€Tÿ•€”ÿ•€ôÿ•€”ÿ•€”ÿ•€”ÿ•€tÿ•€”ÿ•€”ÿ•€ôÿ•€”ÿ•€ôÿ•€ôÿ•€ôÿ•€ôÿ•€Tÿ•€ôÿ•€ôÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€”ÿ•€Tÿ•€”ÿ•€Tÿ•€tÿ•€tÿ•€tÿ•€tÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€Tÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€”ÿ•€tÿ•€”ÿ•€Tÿ•€”ÿ•€”ÿ•€”ÿ•€Tÿ•€”ÿ•€tÿ•€”ÿ•€ôÿ•€Tÿ•€”ÿ•€Tÿ•€Tÿ•€Tÿ•€”ÿ•€”ÿ•€ôÿ•€”ÿ•€”ÿ•€Tÿ•€Tÿ•€”ÿ•€Tÿ•€Tÿ•€tÿ•€tÿ•€”ÿ•€Tÿ•€tÿ•€tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€tÿ•€tÿ•€tÿ•€tÿ•€tÿ•€tÿ•€tÿ•€tÿ•€tÿ•€tÿ•€tÿ•€tÿ•€tÿ•€tÿ•€Tÿ•€Tÿ•€Tÿ•€ôÿ•€Tÿ•€tÿ•€Tÿ•€Tÿ•€Tÿ•€tÿ•€tÿ•€tÿ•€tÿ•€tÿ•€tÿ•€tÿ•€tÿ•€tÿ•€tÿ•€tÿ•€tÿ•€ôÿ•€4ÿ•€Tÿ•€ôÿ•€ôÿ•€tÿ•€tÿ•€tÿ•€ôÿ•€ôÿ•€tÿ•€tÿ•€tÿ•€ôÿ•€Tÿ•€4ÿ•€”ÿ•€Ôÿ•€4ÿ•€Tÿ•€tÿ•€4ÿ•€4ÿ•€4ÿ•€Tÿ•€”ÿ•€4ÿ•€Tÿ•€”ÿ•€”ÿ•€4ÿ•€”ÿ•€Xÿ€Tÿ•€Tÿ•€Tÿ•€”ÿ•€”ÿ•€4ÿ•€”ÿ•€Tÿ•€Tÿ•€Tÿ•€Ôÿ•€Ôÿ•€Ôÿ•€Ôÿ•€Ôÿ•€Tÿ•€Tÿ•€Tÿ•€Tÿ•€XÿŒtÿ•€tÿ•€”ÿ•„”ÿ•„ Dj{ƒŠŽÃéú!”ÿ•€XÿŒ!”ÿ•€XÿŒð@ð  @ñÿÿÿ€€€÷ðH ðð0ð( ð ðð’ðð0ð( ð ððB ðS ð¿Ëÿ ?ðåÑÿÿs _Hlt46910490 _Ref133810247 _Hlt13986753 _Hlt182821983 _Hlt182821972 _Hlt182821980 _Hlt182821935 _Hlt182821922 _Ref13981953 _Ref13981961 _Toc247362773contents _Toc247362774 _Ref182744145 _Toc247362775 _Toc247362776 _Hlt247362399 _Hlt185238125 _Hlt185238126 _Hlt185238135 _Toc247362777 _Toc247362778 _Hlt185238325 _Toc247362779 _Hlt185256783 _Ref201664889 _Toc247362780 _Toc247362781 _Toc247362782 _Toc247362783 _Hlt47165200 _Toc247362784 _Hlt42508635 _Ref47171157 _Hlt90895144 _Toc247362785 _Hlt47171210 _Hlt47171141 _Ref153284855 _Ref184460226 _Ref203380577 _Toc247362786 _Toc247362787 _Hlt184483889 _Hlt184484230 _Hlt204511968 _Hlt204511969 _Ref184459487 _Hlt185753198 _Toc247362788 _Ref184459204 _Hlt184483930 _Hlt203381072 _Toc247362789 _Hlt207626871 _Ref184460000 _Hlt184483894 _Hlt185753259 _Toc247362790 _Hlt203475569 _Ref183001062 _Ref203475251 _Toc247362791 _Ref184460158 _Toc247362792 _Ref185238094 _Hlt185238130 _Hlt185262188 _Toc247362793 _Ref204926421 _Hlt204926469 _Toc247362794 _Ref185257870 _Toc247362795 _Hlt185247427 _Hlt185262081 _Ref185246210 _Hlt185262096 _Hlt201668363 _Hlt201668420 _Ref201668435 _Toc247362796 _Hlt185753882 _Toc247362797 _Hlt47776140 _Toc247362798 _Hlt90895146 _Toc247362799 _Toc247362800 _Ref42511462 _Hlt185238829 _Toc247362801 _Toc247362802 _Ref185238839 _Toc247362803 _Ref42588386 _Toc247362804 _Hlt46751931 _Ref42517152 _Toc247362805 _Ref42509834 _Toc247362806 _Ref42672298 _Toc247362807 _Toc247362808 _Hlt47156384 _Ref47156991 _Toc247362809 _Ref42590185 _Toc247362810 _Hlt42589455 _Ref42671142 _Toc247362811 _Ref153285510 _Toc247362812 _Toc247362813 _Ref153282321 _Toc247362814 _Ref247357288 _Toc247362815 _Ref153282518 _Toc247362816 _Ref42511232 _Toc247362817 _Hlt42675121 _Ref42675038 _Toc247362818 _Ref42673816 _Toc247362819 _Ref42673942 _Toc247362820 _Hlt207635186 _Toc247362821 _Ref204937964 _Toc247362822 _Ref204935761 _Toc247362823 _Ref204925451 _Hlt204938181 _Toc247362824 _Hlt204925429 _Ref153590626 _Toc247362825 _Hlt43728474 _Ref43008774 _Ref43728461 _Toc247362826 _Hlt47156799 _Hlt47168403 _Ref42675314 _Toc247362827 _Hlt202252094 _Hlt202252095 _Ref46752884 _Ref13982166 _Hlt54100713 _Toc247362828 _Ref47262189 _Hlt47869695 _Toc247362829 _Ref46823382 _Toc247362830 _Ref153288035 _Hlt153299871 _Toc247362831 _Ref46896711 _Hlt54077065 _Ref153291752 _Toc247362832 _Ref153732324 _Hlt153732341 _Hlt207636283 _Hlt207636514 _Toc247362833 _Hlt111001235 _Toc247362834 _Ref47775300 _Toc247362835 _Ref5701987 _Toc42530039 _Ref47451589 _Toc247362836 _Ref47451430 _Ref47451551 _Toc247362837 _Hlt45016694 _Ref203479102 _Toc247362838 _Ref204935780 _Toc247362839 _Toc247362840 _Ref206385571 _Toc247362841 _Ref206385661 _Toc247362842 _Ref204511965 _Toc247362843 _Toc247362844 _Toc247362845 _Toc247362846 _Hlt42675118 _Toc247362847 _Ref153285595 _Toc247362848 _Ref47170147 _Toc247362849 _Toc247362850 _Hlt204932610 _Hlt42941500 _Ref42675268 _Toc247362851 _Ref153557607 _Toc247362852 _Toc247362853 _Toc247362854 _Toc247362855 _Toc247362856 _Ref153612128 _Ref153612650 _Toc247362857 _Ref153612150 _Toc247362858 _Ref153603854 _Toc247362859 _Toc247362860 _Toc247362861 _Toc247362862 _Ref203481633 _Ref203481904 _Ref203482205 _Toc247362863 _Ref203481972 _Ref203482186 _Toc247362864 _Toc247362865 _Toc247362866 _Ref153336229 _Toc247362867 _Toc247362868 _Ref36885158 _Toc247362869 _Ref36888765 _Toc247362870 _Hlt185247433 _Ref185247389 _Toc247362871 _Hlt185247364 _Ref185262282 _Toc247362872 _Hlt185262185 _Hlt185262200 _Ref47775275 _Toc247362873 _Toc247362874 _Toc247362875 _Toc247362876 _Toc247362877 _Ref5612241 _Toc247362878 _Toc247362879 _Toc247362880 _Toc247362881 _Hlt46746680 _Ref6129297 _Ref46746740 _Toc247362882 _Ref5625335 _Ref6030571 _Hlt47174977 _Ref42589436 _Hlt78207127 _Toc247362883 _Hlt42507453 _Ref5625615 _Ref46747184 _Ref47173292 _Toc247362884 _Hlt6036362 _Ref6029921 _Ref5638461 _Hlt42589475 _Ref6058882 _Hlt153617393 _Toc247362885 _Ref6042344 _Toc247362886 _Ref6042851 _Ref182996673 _Ref182997657 _Toc247362887 _Hlt6043408 _Ref6043386 _Ref73442286 _Toc247362888 _Hlt6060108 _Ref6046402 _Ref6036405 _Ref182995906 _Ref182996929 _Toc247362889 _Hlt185262841 _Ref42506966 _Hlt47776143 _Ref62467260 _Toc247362890 _Ref6048674 _Ref182740974 _Toc247362891 _Ref6049927 _Toc247362892 _Toc247362893 _Toc247362894 _Ref153617348 _Toc247362895 _Ref153617304 _Toc247362896 _Toc247362897 _Hlt46910489 _Toc247362898 _Toc247362899 _Toc247362900 _Toc247362901 _Ref45025338 _Toc247362902 _Ref6060179 _Hlt47238459 _Ref231887961 _Toc247362903 _Ref182997381 _Toc247362904 _Toc247362905 _Ref231888133 _Toc247362906 _Ref46821357 _Ref103576458 _Toc247362907 _Ref103576461 _Toc247362908 _Toc247362909 _Toc247362910 _Toc247362911 initscript _Ref46895327 _Ref206062819 _Toc247362912 _Ref46895428 _Hlt47156255 _Ref46904847 _Ref55274563 _Toc247362913 _Ref46823145 _Ref169609101 _Toc247362914 _Hlt153689703 _Ref46895473 _Ref204932692 _Toc247362915 _Hlt47156780 _Ref46895489 _Toc247362916 _Ref182997376 _Toc247362917 _Hlt47165090 _Ref36890908 _Ref36886351 _Toc247362918 _Hlt36890891 _Ref47164079 _Ref47165113 _Hlt47775313 _Toc247362919 _Hlt90895315 _Hlt90895390 _Hlt90895528 _Hlt47164153 _Hlt47164182 _Hlt90895495 _Hlt206385761 _Hlt207626040 _Toc247362920 _Ref47163749 _Toc247362921 _Ref70164511 _Toc247362922 _Ref207622654 _Toc247362923 _Toc247362924 _Toc247362925 _Ref5608796 _Toc247362926 _Toc247362927 _Toc247362928 _Hlt47171970 _Ref5702037 _Toc247362929 _Hlt13986741 _Ref43008951 _Ref5703127 _Toc91387367 _Toc247362930 _Ref69047370 _Toc247362931 _Toc247362932 _Toc247362933 _Ref153699553 _Toc247362934 _Toc247362935 _Toc247362936 _Toc247362937 _Toc247362938 _Toc247362939 _Ref47168251 _Toc247362940 _Ref204922935 _Ref204935552 _Toc247362941 _Hlt204922458 _Ref231890048 _Toc247362942 _Toc247362943 _Ref153773639 _Toc247362944 _Toc247362945 _Toc247362946 _Toc247362947 _Toc247362948 _Toc247362949 _Hlt47170323 _Ref47167783 _Ref47169796 _Toc247362950 _Hlt72137546 _Hlt108511794 _Hlt47170149 _Toc247362951 _Hlt153773450 _Hlt247357576 _Hlt43727939 _Ref43727925 _Ref45368706 _Ref47168523 _Ref203474654 _Toc247362952 _Hlt78024559 _Hlt78024432 _Hlt43728343 _Hlt47169251 _Ref45367951 _Ref47169243 _Toc247362953 _Ref247356737 _Toc247362954 _Toc247362955 _Toc247362956 _Ref45368759 _Ref131305143 _Hlt131305183 _Toc247362957 _Ref169607904 _Toc247362958 _Hlt169609104 _Toc247362959 _Toc247362960 _Toc247362961 _Toc247362962 _Ref46908455 _Toc247362963 _Hlt36889516 _Ref6036607 _Toc42530040 _Ref5709751 _Toc247362964 _Ref6058085 _Ref166648484 _Toc247362965 _Hlt247361683 _Toc247362966 _Toc247362967 _Ref247356327 _Toc247362968 _Hlt47260869 _Ref247356244 _Toc247362969 _Ref54100850 _Toc247362970 _Toc247362971 _Toc247362972 _Toc247362973 _Hlt153777894 _Hlt231885580 _Ref55271118 _Toc247362974 _Hlt69827968 _Hlt207636277 _Hlt207636510 _Toc247362975 _Ref166651506 _Toc247362976 _Toc247362977 _Hlt71969232 _Ref111000885 _Toc247362978 _Ref207634778 _Toc247362979 _Ref45371286 _Toc247362980 _Ref45371414 _Toc247362981 _Ref153774103 _Toc247362982 _Ref185245663 _Ref185246112 _Toc247362983 _Hlt204934722 _Ref185246110 _Toc247362984 _Hlt185247455 _Hlt185246527 _Ref204936212 _Toc247362985 _Hlt153700673 _Ref153700641 _Toc247362986 _Toc247362987 _Toc247362988 _Ref71016088 _Toc247362989 _Hlt42943584 _Ref8187404 _Toc247362990 _Hlt153710530 _Ref153708057 _Toc247362991 _Hlt153710662 _Hlt153710686 _Ref153707807 _Toc247362992 _Ref153710706 _Toc247362993 _Ref6029952 _Ref6029971 _Ref17723797 _Toc42530042 _Ref47172480 _Hlt47173434 _Toc247362994 _Ref6030192 _Hlt175633690 _Hlt183626927 _Hlt185258856 _Hlt207618552 _Toc42530043 _Ref47173451 _Hlt69048936 _Toc247362995 _Hlt204935243 _Ref247355579 _Toc247362996 _Hlt153776691 _Hlt153776839 _Hlt153777014 _Hlt153777228 _Ref153776689 _Ref153776695 _Ref153776799 _Toc247362997 _Ref153776692 _Toc247362998 _Hlt207613371 _Ref153776693 _Toc247362999 _Hlt207625463 _Ref207618734 _Toc247363000 _Hlt207613369 _Hlt207613370 _Ref153776694 _Ref153776724 _Toc247363001 _Hlt69048829 _Toc247363002 _Ref47260717 _Toc247363003 _Toc247363004 _Toc247363005 _Hlt42941703 _Ref42941679 _Toc247363006 _Toc247363007 _Toc247363008 _Toc247363009 _Toc247363010 _Ref6055322 _Toc247363011 _Ref45001933 _Toc247363012 _Ref54091553 _Toc247363013 _Toc247363014 _Toc247363015 _Toc247363016 _Toc247363017 _Toc247363018 _Ref54091188 _Toc247363019 _Ref54091192 _Toc247363020 _Ref54091119 _Hlt97961444 _Toc247363021 _Ref97961473 _Toc247363022 _Toc247363023 _Ref231889747 _Toc247363024 _Toc247363025 _Toc247363026 _Ref247361819 _Toc247363027 _Toc247363028 _Ref70164454 _Toc247363029 _Hlt5702867 _Ref5702859 _Toc247363030 _Ref47164085 _Ref47165137 _Hlt90895270 _Toc247363031 _Hlt47164148 _Hlt90895655 _Hlt90895638 _Ref43729255 _Hlt47268694 _Toc247363032 _Hlt47172042 _Ref47172128 _Toc247363033 _Hlt43728338 _Ref47779943 _Hlt47779954 _Ref47781653 _Toc247363034 _Hlt47781638 _Ref47173394 _Hlt47785233 _Toc247363035 _Ref78024414 _Hlt79212320 _Toc247363036 _Hlt78024546 _Hlt78024525 _Ref43726555 _Toc247363037 _Toc247363038 _Ref58909011 _Ref203474873 _Toc247363039 _Ref58909800 _Toc247363040 _Toc247363041 _Toc247363042 _Toc247363043 _Toc247363044 _Hlt42943817 _Ref5609191 _Toc247363045 _Toc247363046 _Ref13986080 _Ref46754713 _Ref46754709 _Ref42943854 _Toc247363047 _Hlt5608811 _Hlt13982107 _Ref36896793 _Ref13981914 _Ref5614672 _Ref166649220 _Toc247363048 _Hlt13986561 _Ref43728215 _Ref47171876 _Ref166649222 _Toc247363049 _Ref68495073 _Toc247363050 _Hlt43728174 _Ref13986562 _Ref43727921 _Ref47171842 _Ref47171963 _Ref47174498 _Toc247363051 _Hlt47172168 _Ref5624476 _Ref36896289 _Ref43727928 _Ref47168540 _Toc247363052 _Ref153704184 _Toc247363053 _Hlt71969222 _Ref46754571 _Toc247363054 _Hlt47168312 _Hlt108511282 _Hlt47170329 _Ref42944330 _Toc247363055 _Hlt13986432 _Ref6117078 _Ref6117306 _Ref6117429 _Hlt43728875 _Ref42943895 _Toc247363056 _Ref6030156 _Hlt47777532 _Hlt47171817 _Ref43728908 _Ref47171780 _Toc247363057 _Hlt47779252 _Ref8187433 _Hlt47174587 _Toc247363058 _Toc247363059 _Ref47777798 _Ref47781675 _Hlt153731886 _Ref153731855 _Toc247363060 _Ref182743880 _Toc247363061 _Toc247363062 _Toc247363063 _Ref69052620 _Toc247363064 _Toc247363065 _Toc247363066 _Toc247363067 _Ref47784069 _Ref47783567 _Toc247363068 _Ref47784397 _Ref47845006 _Toc247363069 _Ref47784098 _Toc247363070 _Ref47784099 _Ref66078569 _Toc247363071 _Toc247363072 _Ref46750086 _Toc247363073 _Hlt46750578 _Ref153764303 _Toc247363074 _Hlt13986666 _Ref47864390 _Ref47865711 _Ref47872399 _Ref153765172 _Toc247363075 _Hlt47867866 _Ref47871522 _Ref47871470 _Ref47867609 _Ref47867554 _Ref130893908 _Hlt130894065 _Ref63053303 _Ref47870052 _Ref47871769 _Ref47869783 _Ref63052833 _Ref47867141 _Toc247363076 _Ref47867143 _Ref47867954 _Hlt69048878 _Toc247363077 _Ref47867144 _Ref47867926 _Toc247363078 _Hlt6030208 _Ref207637531 _Toc247363079 _Ref153732596 _Toc247363080 _Hlt47170196 _Ref6039859 _Toc247363081 _Hlt90895644 _Hlt133745674 _Ref133745663 _Ref135023442 _Toc247363082 _Hlt153286317 _Ref153703095 _Toc247363083 _Ref133830177 _Toc247363084 _Toc247363085 _Toc247363086 _Ref133831852 _Toc247363087 _Ref153681044 _Toc247363088 _Toc247363089 _Toc247363090 _Ref135023800 _Toc247363091 _Toc247363092 _Ref133832449 _Toc247363093 _Ref133810323 _Toc247363094 _Toc247363095 _Toc247363096 _Toc247363097 _Toc247363098 _Ref207626203 _Toc247363099 _Hlt207630554 _Toc247363100 _Ref247361078 _Toc247363101 _Toc247363102 _Hlt153620653 _Ref90895148 _Ref90895285 _Hlt90895609 _Toc247363103 _Hlt90895304 _Hlt90895385 _Hlt153620745 _Ref90895208 _Toc247363104 _Toc247363105 _Toc247363106 _Toc247363107 _Ref232415540 _Toc247363108 _Ref232415549 _Toc247363109 _Toc247363110 _Toc247363111 _Toc247363112 _Toc247363113 _Toc247363114 _Ref153889197 _Toc247363115 _Toc247363116 _Toc247363117 _Toc247363118 _Toc247363119 _Toc247363120 _Toc247363121 _Ref90894479 _Toc247363122 _Ref90894483 _Toc247363123 _Toc247363124 _Toc247363125 _Toc247363126 _Ref185261956 _Hlt185262195 _Hlt185753893 _Hlt204922464 _Toc247363127 _Toc247363128 _Ref47451048 _Hlt47451059 _Toc247363129 _Hlt153795123 _Hlt153795208 _Hlt153795243 _Toc247363130 _Toc247363131 _Toc247363132 _Ref78023979Ü  ¾` ` ` ##‹‹‹ŒŽŽŽïŽ"V“~–™c®c®q»¼êÃçÈ×ÒAÔÙØÙØÙØ‚ÛÍÜ=Ý=Ý=Ý=ÝëÞ à à¬á¬á9ã9ã9ãèèèèèRéRéRéRé°ð¿ñ¿ñ¿ñšõšõ†ø†ø†ø†ø¤û¤û¤ûÂÂëëç ç ç ç ††ÁÊ!Z#;%B(B(d*;+;+;+Ø,&.&.²/²/Ñ5Ñ5Ñ5ï;ï;Ð=Ð=ýC=E=E=E×I×IK©N©NPSPSQ\Ö]Ö]I_I_æ_æ_2c2ceeeŒmŒmðoðoqeqQQ^‰^‰@­@­@­d¯O¼O¼¥Ç¥Ç¥Ç¥ÇËžÙ5é5é9ð9ðfðfðfðfð666GGGGÚ!Ú!Ú!Ú!Ú!3'µ,..;.@.R.R.222”2µ3µ3í5í5f8:!:<<>>®A¬DœE§FÿFÖHÖHVJVJîNÃQÕQÕQÕQÉhÉhjìnYq‚r;tXtXtív wÁxÁx[}TDƒë„ë„ë„ë„k‹k‹k‹§’¯“„”„”Ö–Ù—ï—Øšòš"œ>œ>œëëëýŸýŸ†¢†¢M¨¤«1¯ˆ²E´¬´?¶9¸\½(¿(¿=¿=¿`¿{Í{ÍÍÍÍ~Ð~ÐÐÐиииÐï§ð§ð¾ðÖóéóÂøØøØøØøDDXXvvv‡‡‡V!ž9ž9®9®9ÊDßDßDR%R‹wwz¢|¢|ππQ„,†@†)ˆF‰à‹þþ2š2šFšFš„ „ R¥¸§¸§ß©ù©ù©y¯y¯@±I´;·<·i»„»„»è»ʾʾè¾è¾ÍÏìÏìÏdÒ$Þ?Þ?Þnâæ8æîîcðcðcðcðÅðÉ÷É÷É÷É÷øø2øhøãøôøýý«þjj††Ž ª ¨ ”jv)o!o!o!ˆ!ˆ!=$=$E&Þ'Ê)Ê);4&7ë:¸<ß>A;AÐBêBêBsCiEiE!H¤J¤J[NjQöUþWDZe[5]5]L]M]Z^-h0jækækllllll«qrhsw€w€w€w€ׇׇɧŒsއއއŽÕÕK’¾’x–J˜åš¾¾¥¦ ¦¦¦¨*¨*¨œ«± ³èµèµ4¶è¹è¹A»A»†¿¢Â$ŀǀǡǡÇXä ð_ò õ÷÷ÜùûßüßüÊÿÊÿÁ ç ::¿¿¿´ÎÎÿZZ'>>ˆ!v%M'p'ñ)ñ)*å.//Ï1Ï1ê1ê1·4·4787878<8K8K8K8~;~;~;~;~;ƒ;;;;dKz_z_¬b¬b¬b¬bÄbÄbÄbÄbŠpŠpEvdvdv÷€‰ƒ‰ƒŠŠŠäŽ •6•Q–õ™á›á›á›± O¢¾§p©r¬¬I®I®¬²¬²ì¶y¹"¼ÄÀ¢ÃÆÆXÈXÈSÊSÊSÊ—Ì—ÌîμмÐSÓMÕS×S×3ÚçÛçۑݑݩ݌àŒàŒà«à?áGá¶áZäZäZä”ë”ë”ë¾î²ô²ô²ô²ô¦õúøúøúø   kò74TT¹%¹%Ÿ'þ(W*p,«/«/Ç/2 2#2C2£5£5&7q;q;q;q;ˆ;ˆ;`<>>+>+>@@CMCMYMYMYMYMYM$\$\$\@\@\@\¥^¥^!b9b9bhbEd®f×fgËjËjËjËjãjãjãjYsYsusususus»tŽžŽž§ž 8£8£8£U£U£º¶º¶Š»¼þÀþÀøÂ ÅÜÅøÆÇÇ`É`ɄɹÏÔÏÓ0Ó0ÓêÝßßßß¹òÑøÑøˆ™™™™™F(7MÇùCn€" #Ú#ý#$¯(¯(¯(Ê(†*†*¢*,6,6,3.3.À1À1ß1P2Ã2L3k3k3347777H8H8ð:d<Ú=Ú=9?9?AÑB0C0CðC.GNGyJyJ=KjP0UHUBWBWîX5Ya]a]¾_¸aÌaÌaÌaÌaÍa›cÇcécécvfÙhÏj¡l¡lbnbnpBsÔt¾vuxÝyÝy8}`~o€ë`„7‡M‡÷‹ ŒŒŽ¿‘›“g•g•g•g•g•øœhhh(ž6ž:žx£›¬¡¬iÅæÑ@@@@@ @@@@@@ "!#$%6&'()*@+@,@-@/.@041@2@53@97@8@:;@<=>?@CA@B@DFE@GHIJ@K@OL@M@N@PQR@STUVWX\Y@Z[]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ@„…†‡ˆŠ‰@‹Œ@Ž‘’“”•–—@˜@𝙛œžŸ ¢¡@£¥¤¦§«¨@©@ª@¬­®°±Ë²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊÌÍÎÏ@ÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîúïðñò@óôõ@ö÷ø@ù@ûüýþÿ     C@ !"#$%&D'()*@,+-.1/023456789:;<=>?@AEBFGHIJKLYMNOPQRTSUVWZX[\]^_`a@bcdefghijkolmpqnrxsvtuwy@z@{|}~€‚ƒ„…†‡ˆ‰Š‹Ž¾Œ‘’“”•–—˜™§š›œž@Ÿ ¡¢£¤¥¦¨©ª¬­®«¯°±²@³@´µ¶·¸¹º»¼½¿ÀÁÂÃÄÅÇÈÆÉÊËÌ@ÍÎÏÐÑÒÓÕÔÖרÙÚÛ@ÜÝÞßàáâãäåæçè@é@êëìí@î@ïðñòóôõö÷øùúûüýþÿ@@@@     @@@ !("@#@$@%@&)'*+@,-.@/@0@1@2345678@9:;@<=>@?@@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^`_abcdefghijklmnrostpuqwvyxz{|}~€‚ƒ…„†ˆ‡‰Š‹ŒŽ‘’“”•–—˜ž™š›œŸ ¡¢¦­¯£¤¥©ª§¨«¬®°±²³´µ¶»·¸¹º¼½¾ÀÁ¿ÂÃÄÅÆÈÉÊÇËÌÏÍÎÐÑÒÓÕÔÖ×ÙÚØ@ÛÜÝÞßàáâãäåèæçéêëìíîïðñòóôõö÷øùúûüýþÿ     @ !"#$%&'()*+,-./0123456789@:;<=>@AB?C@DE@FGHIJKLMNOPQRSTUVWXYZ[\]^_`abfc@d@e@ghjikl@m@n@opqrÝ!!¿l l l +,‹‹!‹Œ=Ž=Ž=Ž!1t“Š–4™®–®y»&¼ÄÉáÒAÔÙØÙÙ‚ÛÍÜTÝrÝrÝß*à*àÌáÌá9ãVãVãèèèèèRéRéRétété»ðæñçñçñºõºõ†ø†ø˜ø˜ø¤û¼û¼ûÓÓ  ç ç ç žžžàÜ!|#P%B(e(l*;+Z+ã,0.0.0.»/Ä/Ñ5à5à5ø;ø;á=á='D=ELELEðIðI¯K´N´N\S\SW\å]å]X_X_ó_ó_;c;ce.e.ežmžmpp$quqmmu‰u‰@­[­[­„¯b¼b¼¥Ç´Ç´Ç´ÇƒË¶ÙFéFéXðXðfðmðmð6NN44GJXXÚ!Ú!Ú!""8'Ñ,:.:.:.K.Ž.Ž.I2I2I2º2Ú3Ú3668V:V:G<G<D>D>ØAÕD½EÉFGIIsJsJsJOÃQÕQûQûQìhìh?j:oq±r³t³t³tHwHwçxçx™}°zƒ…………’‹’‹’‹Ë’ó“¥”¥”—˜››"œoœoœë!ž!ž  ²¢²¢²¢r¨׫S¯¸²Ì´_¶w¸‘½(¿_¿_¿_¿_¿{Í͵͵͵͵Í~ззззиÐð§ðíðíðíð ô ôùùùùDwwwv³³³³V!ž9Ç9Ç9Ç9 E EYRYRYR¸wÊzÔ|Ô|  s„,†X†Kˆi‰ÿ‹2šjšjšjšjšjšË Ë w¥¨¨FªFªÁ¯Á¯p±‹´F·w·ç»ç»ç»ʾA¿A¿A¿A¿A¿%Ð%Ð%ÐåÓfÞfÞfÞnâXæXæ4î4îcðtðtðæðÉ÷øøøøø†øãøäøôøõø0ý0ýÿ››··Ï Ï Ü kººÜsso!µ!µ!e$e$e$q&Z(D*D* 4ž7#;ß<?vACCC’C¥E¥EsHëJëJ›NÂQ4VXXeZ†[V]W]l]l]‰^MhPjækæklblblblclclrr†sw€ž€ž€ž€ž€ˆˆà‰ÕŒ‡Ž¦Ž¦Ž¦Žûûo’ï’£–˜0›UžUž¥¦¦E¦E¦?¨?¨?¨¢«¼±O³ ¶ ¶i¶ººl»l»¯¿ÈÂNŀǀÇßÇßÇXäÀðòßõ\÷\÷ úû ý ýáá3 3 pp´þþ:>„„'zzÅ!¡%°'°'ñ)I*I*å.ˆ/ˆ/Ï1Ï1(2(255D8K8ƒ8ƒ8ƒ8ƒ8ƒ8~;~;~;~;†;;è;è;è;QN£_£_¬b¬b¬b¬bïbïbïbïbÁpÁpEv™v™v÷€CCăăBŠBŠBŠä1Ži•i•‚–šá›œœ¼ z¢ϧž©À¬À¬ˆ®ˆ®ë²ë².·Ź”¼ÁçÃPÆPÆÈÈSʕʕÊÍÌÍÌÏøÐøÐ„Ó|զצ×ZÚÜÜ‘ÝØÝŒà?áFáFáFáFáÔádâZärärä”ë·ë·ëßî²ôäôäôäô¦õúø8ù8ù 3 3 Œò++X‰‰‰Ù%Ù%Û')¢*,«/ó/-2-2O2m2Ñ5Ñ5Ñ5f7q;¶;¶;`<>`>`>%@´@´@´@CMCM„M„M„M„M„M„M„M$\p\p\p\p\Ô^Ô^Ô^!bhbqbqbfd®fagagËjãj k k k k kYsusttttÆtŽžÝžÝžî 8£ä£ú£ú£ú£á¶á¶¸»½*Á*Á/Ã;ÅÆÇQǵɵɵɵÉþÏþÏØÓØÓØÓÞááÈòûøûøˆÀÀÀÑÑdˆŒ¯6ØâÜ"Ù#ü#ˆ$ˆ$¯(÷(÷(÷(%+%+%+,E,c,p.p.À1O2P2P2ò2Þ3Þ3Þ3Q4U7U7W8W8;x<é=é=v?v?AàB?C?CD™G³G“J“JPK„PGUdU¡W¡W Y‚Y]]õ_¸aÌaÍabbb›cÇc.d.dœf iôjÖlÖl“n“nRp|s*uævxzz‘}ž~²ÿ€‚‹„m‡m‡*Œ*Œ¹Žñ‘à“g•g•g•••h{{)ž7ž;žŒ£ ¬Ȭ›ÅæÑбŠßŠ‹›ÅæÐëÐöÐdÑiÑuÑvÑvÑ|ÑѧѨѩÑáÑãÑæÑÿÿ Lukas ZellerNE:\Projects\SySync\Docs\Manuals\Sync Server Manual\SySync_config_reference.doc Lukas ZellerNE:\Projects\SySync\Docs\Manuals\Sync Server Manual\SySync_config_reference.doc Lukas ZellerNE:\Projects\SySync\Docs\Manuals\Sync Server Manual\SySync_config_reference.doc Lukas ZellerNE:\Projects\SySync\Docs\Manuals\Sync Server Manual\SySync_config_reference.doc Lukas ZellerNE:\Projects\SySync\Docs\Manuals\Sync Server Manual\SySync_config_reference.doc Lukas ZellerNE:\Projects\SySync\Docs\Manuals\Sync Server Manual\SySync_config_reference.doc Lukas ZellerNE:\Projects\SySync\Docs\Manuals\Sync Server Manual\SySync_config_reference.doc Lukas ZellerNE:\Projects\SySync\Docs\Manuals\Sync Server Manual\SySync_config_reference.doc Lukas ZellerNE:\Projects\SySync\Docs\Manuals\Sync Server Manual\SySync_config_reference.doc Lukas Zeller‚C:\Dokumente und Einstellungen\luz\Anwendungsdaten\Microsoft\Word\AutoWiederherstellen-Speicherung von SySync_config_reference.asd®|ÿÿÿÔè,kRÿÿÿÿÿÿÿÿ}ÿÿÿª°˜Qÿÿÿÿÿÿÿÿ~ÿÿÿ Ú¢¾PÿÿÿÿÿÿÿÿÿÿÿZüNOÿÿÿÿÿÿÿÿ€ÿÿÿìÄf­1ÿÿÿÿÿÿÿÿÿÿÿ¨­F 0ÿÿÿÿÿÿÿÿ‚ÿÿÿA>/ÿÿÿÿÿÿÿÿƒÿÿÿˆš<¨.ÿÿÿÿÿÿÿÿˆÿÿÿŽÂ–?Nÿÿÿÿÿÿÿÿ‰ÿÿÿÔi´äÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„{êÿ€~ÆP˜>kÿÿÿÿÿÿÿÿÿõ>ôJQlWÿÿÿÿÿÿÿÿÿBûÿÿÿÿÿÿÿÿÿ D¢‰Ì\ÿÿÿÿÿÿÿÿÿÏCÀÿÿÿÿÿÿÿÿÿ³ÙÿÿÿÿÿÿÿÿÿyÔÿÿÿÿÿÿÿÿÿX@Æî\ÿÿÿÿÿÿÿÿÿ¦­V†&ÿÿÿÿÿÿÿÿÿ8¶ cÆÿ7B rHä¯ÿÿÿÿÿÿÿÿÿÆ'` †нÿÿÿÿÿÿÿÿÿó6í ÿÿÿÿÿÿÿÿÿžLþ ÿÿÿÿÿÿÿÿÿ5DG ÿÿÿÿÿÿÿÿÿÎP© ÿÿÿÿÿÿÿÿÿør@ ÿÿÿÿÿÿÿÿÿ>¸ ÿÿÿÿÿÿÿÿÿ &>ÿÿÿÿÿÿÿÿÿKÿÿÿÿÿÿÿÿÿ-z2âšÿÿÿÿÿÿÿÿÿ=8èŠNàÿÿÿÿÿÿÿÿÿ›`âš•ÿÿÿÿÿÿÿÿÿ£Vv–Sæ£ÿÿÿÿÿÿÿÿÿ8 ܪ°ÿÿÿÿÿÿÿÿÿTedÿ zRæ¿ÿÿÿÿÿÿÿÿÿØ]‚vü>íÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿ[plˆf¤FaÌ)Æî\ÿÿÿÿÿÿÿÿÿØH„ÿÿÿÿÿÿÿÿÿG=¢ KŠÿÿÿÿÿÿÿÿÿ®\âÿÿÿÿÿÿÿÿÿ`tmÿÿÿÿÿÿÿÿÿyQ¼ÿÿÿÿÿÿÿÿÿ[3ÿPEÿÿÿÿÿÿÿÿÿ¥u¡ÿÿÿÿÿÿÿÿÿ•ÿÿÿÿÿÿÿÿÿ—Vʸܫÿÿÿÿÿÿÿÿÿë|!ÿÿÿÿÿÿÿÿÿTK3!2ž‘ÿÿÿÿÿÿÿÿÿMî!ÿÿÿÿÿÿÿÿÿt7#n âÿð2+$ˆf¤FÿÿÿÿÿÿÿÿÿŠoÀ%ÿÿÿÿÿÿÿÿÿ¹Wz&,ZlRÿÿÿÿÿÿÿÿÿzU„&ÿ)&'ˆ&^nÿÿÿÿÿÿÿÿ±]]'ÿÿÿÿÿÿÿÿÿ½sô'ÿÿÿÿÿÿÿÿÿA(5(ÿÿÿÿÿÿÿÿÿ}1þ)2à<ÿÿÿÿÿÿÿÿÿt#ž*ÿÿÿÿÿÿÿÿÿ@+ÿÿÿÿÿÿÿÿÿ=³,ÿÿÿÿÿÿÿÿÿšB- ,ŒÿÿÿÿÿÿÿÿÿÎ-ÿÿÿÿÿÿÿÿÿEr.Ê¡ ºÿÿÿÿÿÿÿÿÿ%./ÿÿÿÿÿÿÿÿÿ¾c|/ÿÿÿÿÿÿÿÿÿùkž/Æî\ÿÿÿÿÿÿÿÿÿT î/ÿÿÿÿÿÿÿÿÿünû/ÿÿÿÿÿÿÿÿÿõAD1ÿÖ1ÿÿÿÿÿÿÿÿÿOo<2ÿÿÿÿÿÿÿÿÿe"3ˆf¤Fÿÿÿÿÿÿÿÿÿ"£4ä2þÿÿÿÿÿÿÿÿÿ¿#6"O²ÿÿÿÿÿÿÿÿÿˆ[6¤ú9ÿ¿$•6ÿÿÿÿÿÿÿÿÿàÁ7ÿÿÿÿÿÿÿÿÿK¿9ÿÔ$z:ÿÿÿÿÿÿÿÿÿrn*;ÿÿÿÿÿÿÿÿÿþs/=ÿÿÿÿÿÿÿÿÿŸu¥>Þ{Šÿÿÿÿÿÿÿÿÿ¿-B|:ø‘ÿÿÿÿÿÿÿÿÿGÿÿÿÿÿÿÿÿÿ§jæHõ¢ÿÿÿÿÿÿÿÿÿ–z-IÞ{Šÿÿÿÿÿÿÿÿÿg1K@âT÷ÿÿÿÿÿÿÿÿÿ¹ HMÿÿÿÿÿÿÿÿÿ¾DäN$tÄÿÿÿÿÿÿÿÿÿL;KOˆf¤Fÿÿÿÿÿÿÿÿÿ¹A˜Oÿÿÿÿÿÿÿÿÿ|lTPÿÿÿÿÿÿÿÿÿ·)\PÿÿÿÿÿÿÿÿÿÛ/eRÿÿÿÿÿÿÿÿÿ Sÿÿÿÿÿÿÿÿÿ2×S–ýžÿÿÿÿÿÿÿÿÿz:%Uÿÿÿÿÿÿÿÿÿû=MUˆ1ôÿÿÿÿÿÿÿÿÿ°ÎUÿÿÿÿÿÿÿÿÿ‹%ÖVÿÿÿÿÿÿÿÿÿ+HÞVâæ®…ÿÿÿÿÿÿÿÿÿ¨OWÿÿÿÿÿÿÿÿÿ?D~Wÿÿÿÿÿÿÿÿÿ:¶Wÿÿÿÿÿÿÿÿÿ¢VaXÿÿÿÿÿÿÿÿÿYÿÿÿÿÿÿÿÿÿ.Y*¶&ÿÿÿÿÿÿÿÿÿt~ÎYÿm )Z‰þ$ÿÿÿÿÿÿÿÿÿv<ÀZÿÿÿÿÿÿÿÿÿ *'[P²Z‰sÿÿÿÿÿÿÿÿWU[tIŽÿÿÿÿÿÿÿÿÿv[ÿÿÿÿÿÿÿÿÿQv«[`âš•ÿÿÿÿÿÿÿÿÿóK ]ø¦#ÿÿÿÿÿÿÿÿÿbi]ècFFÿÿÿÿÿÿÿÿÿïu1]ÿÿÿÿÿÿÿÿÿ%K^Û,pÿÿÿÿÿÿÿÿÿàVs`ÿÿÿÿÿÿÿÿÿ{u!a®°Lÿÿÿÿÿÿÿÿÿÿ~%aÿÿÿÿÿÿÿÿÿ¯2saÿLKQdÿÿÿÿÿÿÿÿÿp8¹eÿÿÿÿÿÿÿÿÿIfÿÿÿÿÿÿÿÿÿ¸]§fÿÿÿÿÿÿÿÿÿS7½fÿÿÿÿÿÿÿÿÿ´!hÿÿÿÿÿÿÿÿÿ£!wjÔNÿÿÿÿÿÿÿÿÿÏ|ájÿÿÿÿÿÿÿÿÿü.–k £ˆËÿÿÿÿÿÿÿÿÿüuèk;œ0ÿÿÿÿÿÿÿÿÿQúlÿÿÿÿÿÿÿÿÿZD nÿÿÿÿÿÿÿÿÿ«M®nÿÿÿÿÿÿÿÿÿâI6oÿÿÿÿÿÿÿÿÿéZoÿÿÿÿÿÿÿÿÿåCçojÛ„ÿy5ëpÿÿÿÿÿÿÿÿÿzFÈq¾ˆ£bÿÿÿÿÿÿÿÿÜdtä2þÿÈ @tv¼½ÿÿÿÿÿÿÿÿÿ_µv”)|âqÿÿÿÿÿÿÿÿɾw@J\ÿiD1xâëšÿÿÿÿÿÿÿÿÿÄõxÿÿÿÿÿÿÿÿÿØw&yÿÿÿÿÿÿÿÿÿ¨D·yÿÿÿÿÿÿÿÿÿøKãyÿÿÿÿÿÿÿÿÿ×XäzÒŠBÔ %ùzÿÿÿÿÿÿÿÿÿú4~ÿÿÿÿÿÿÿÿÿô/~ÿÿÿÿÿÿÿÿÿÅn~ÿÿÿÿÿÿÿÿÿõ/¡~@J\ÿ‘ÿÿÿÿÿÿÿÿÿÁK ÿÿÿÿÿÿÿÿÿ²q{:1ÿÿÿÿÿÿÿÿÿÐ:Êvˆ^vÿ„Ô„˜þÆÔ^„Ô`„˜þ.„¹„˜þƹ^„¹`„˜þ.„ž„˜þÆž^„ž`„˜þ.„ƒ„˜þƃ^„ƒ`„˜þ. „Ô„˜þÆÔ^„Ô`„˜þOJQJo(·ð „¹„˜þƹ^„¹`„˜þOJQJo(·ð „ž„˜þÆž^„ž`„˜þOJQJo(·ð „ƒ„˜þƃ^„ƒ`„˜þOJQJo(·ð„h„˜þÆh^„h`„˜þ. „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð„h„˜þÆh^„h`„˜þ. „h„˜þÆh^„h`„˜þOJQJo(·ðh„Є˜þÆÐ^„Ð`„˜þ.h„ „˜þÆ ^„ `„˜þ.’h„p„LÿÆp^„p`„Lÿ.h„@ „˜þÆ@ ^„@ `„˜þ.h„„˜þÆ^„`„˜þ.’h„à„LÿÆà^„à`„Lÿ.h„°„˜þư^„°`„˜þ.h„€„˜þÆ€^„€`„˜þ.’h„P„LÿÆP^„P`„Lÿ. „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð„h„˜þÆh^„h`„˜þ. „h„˜þÆh^„h`„˜þOJQJo(·ð„h„˜þÆh^„h`„˜þ. „h„˜þÆh^„h`„˜þOJQJo( ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo( ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð„h„˜þÆh^„h`„˜þ. „h„˜þÆh^„h`„˜þOJQJo(·ð„h„˜þÆh^„h`„˜þ.„h„˜þÆh^„h`„˜þ. „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo( ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo( ðh „h„˜þÆh^„h`„˜þOJQJo(·ðh „8„˜þÆ8^„8`„˜þOJQJo(oh „„˜þÆ^„`„˜þOJQJo(§ðh „Ø „˜þÆØ ^„Ø `„˜þOJQJo(·ðh „¨ „˜þƨ ^„¨ `„˜þOJQJo(oh „x„˜þÆx^„x`„˜þOJQJo(§ðh „H„˜þÆH^„H`„˜þOJQJo(·ðh „„˜þÆ^„`„˜þOJQJo(oh „脘þÆè^„è`„˜þOJQJo(§ð„h„˜þÆh^„h`„˜þ. „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo( ð„h„˜þÆh^„h`„˜þ.h „h„˜þÆh^„h`„˜þOJQJo(·ðh „8„˜þÆ8^„8`„˜þOJQJo(oh „„˜þÆ^„`„˜þOJQJo(§ðh „Ø „˜þÆØ ^„Ø `„˜þOJQJo(·ðh „¨ „˜þƨ ^„¨ `„˜þOJQJo(oh „x„˜þÆx^„x`„˜þOJQJo(§ðh „H„˜þÆH^„H`„˜þOJQJo(·ðh „„˜þÆ^„`„˜þOJQJo(oh „脘þÆè^„è`„˜þOJQJo(§ð „h„˜þÆh^„h`„˜þOJQJo(·ð„h„˜þÆh^„h`„˜þ.„h„˜þÆh^„h`„˜þ. „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð„h„˜þÆh^„h`„˜þ. „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð„h„˜þÆh^„h`„˜þ.h „h„˜þÆh^„h`„˜þOJQJo(·ðh „8„˜þÆ8^„8`„˜þOJQJo(oh „„˜þÆ^„`„˜þOJQJo(§ðh „Ø „˜þÆØ ^„Ø `„˜þOJQJo(·ðh „¨ „˜þƨ ^„¨ `„˜þOJQJo(oh „x„˜þÆx^„x`„˜þOJQJo(§ðh „H„˜þÆH^„H`„˜þOJQJo(·ðh „„˜þÆ^„`„˜þOJQJo(oh „脘þÆè^„è`„˜þOJQJo(§ð„h„˜þÆh^„h`„˜þ. „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo( ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo( ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð„h„˜þÆh^„h`„˜þ. „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „„˜þÆ^„`„˜þOJQJo(- „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð„h„˜þÆh^„h`„˜þ. „h„˜þÆh^„h`„˜þOJQJo(·ð „-„˜þÆ-^„-`„˜þOJQJo(·ð„ý„˜þÆý^„ý`„˜þ.‚„Í „LÿÆÍ ^„Í `„Lÿ.€„ „˜þÆ ^„ `„˜þ.€„m„˜þÆm^„m`„˜þ.‚„=„LÿÆ=^„=`„Lÿ.€„ „˜þÆ ^„ `„˜þ.€„Ý„˜þÆÝ^„Ý`„˜þ.‚„­„LÿÆ­^„­`„Lÿ. „h„˜þÆh^„h`„˜þOJQJo( ð„h„˜þÆh^„h`„˜þ.h „h„˜þÆh^„h`„˜þOJQJo(·ðh „8„˜þÆ8^„8`„˜þOJQJo(oh „„˜þÆ^„`„˜þOJQJo(§ðh „Ø „˜þÆØ ^„Ø `„˜þOJQJo(·ðh „¨ „˜þƨ ^„¨ `„˜þOJQJo(oh „x„˜þÆx^„x`„˜þOJQJo(§ðh „H„˜þÆH^„H`„˜þOJQJo(·ðh „„˜þÆ^„`„˜þOJQJo(oh „脘þÆè^„è`„˜þOJQJo(§ð„Є˜þÆÐ^„Ð`„˜þ.„ „˜þÆ ^„ `„˜þ.‚„p„LÿÆp^„p`„Lÿ.€„@ „˜þÆ@ ^„@ `„˜þ.€„„˜þÆ^„`„˜þ.‚„à„LÿÆà^„à`„Lÿ.€„°„˜þư^„°`„˜þ.€„€„˜þÆ€^„€`„˜þ.‚„P„LÿÆP^„P`„Lÿ. „h„˜þÆh^„h`„˜þOJQJo(·ð„h„˜þÆh^„h`„˜þ.h„Є˜þÆÐ^„Ð`„˜þ.h„ „˜þÆ ^„ `„˜þ.h„p„LÿÆp^„p`„Lÿ.h„@ „˜þÆ@ ^„@ `„˜þ.h„„˜þÆ^„`„˜þ.h„à„LÿÆà^„à`„Lÿ.h„°„˜þư^„°`„˜þ.h„€„˜þÆ€^„€`„˜þ.h„P„LÿÆP^„P`„Lÿ. „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð„h„˜þÆh^„h`„˜þ. „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo( ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð„h„˜þÆh^„h`„˜þ. „h„˜þÆh^„h`„˜þOJQJo( ð„h„˜þÆh^„h`„˜þ. „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ðh „Є˜þÆÐ^„Ð`„˜þOJQJo(·ðh „ „˜þÆ ^„ `„˜þOJQJo(oh „p„˜þÆp^„p`„˜þOJQJo(§ðh „@ „˜þÆ@ ^„@ `„˜þOJQJo(·ðh „„˜þÆ^„`„˜þOJQJo(oh „à„˜þÆà^„à`„˜þOJQJo(§ðh „°„˜þư^„°`„˜þOJQJo(·ðh „€„˜þÆ€^„€`„˜þOJQJo(oh „P„˜þÆP^„P`„˜þOJQJo(§ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ðh „Є˜þÆÐ^„Ð`„˜þOJQJo(·ðh „ „˜þÆ ^„ `„˜þOJQJo(oh „p„˜þÆp^„p`„˜þOJQJo(§ðh „@ „˜þÆ@ ^„@ `„˜þOJQJo(·ðh „„˜þÆ^„`„˜þOJQJo(oh „à„˜þÆà^„à`„˜þOJQJo(§ðh „°„˜þư^„°`„˜þOJQJo(·ðh „€„˜þÆ€^„€`„˜þOJQJo(oh „P„˜þÆP^„P`„˜þOJQJo(§ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ðh„Є˜þÆÐ^„Ð`„˜þ.h„ „˜þÆ ^„ `„˜þ.h„p„LÿÆp^„p`„Lÿ.h„@ „˜þÆ@ ^„@ `„˜þ.h„„˜þÆ^„`„˜þ.h„à„LÿÆà^„à`„Lÿ.h„°„˜þư^„°`„˜þ.h„€„˜þÆ€^„€`„˜þ.h„P„LÿÆP^„P`„Lÿ. „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð„h„˜þÆh^„h`„˜þ. „h„˜þÆh^„h`„˜þOJQJo( ð „h„˜þÆh^„h`„˜þOJQJo(·ð „Є˜þÆÐ^„Ð`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð„h„˜þÆh^„h`„˜þ. „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ðh „h„˜þÆh^„h`„˜þOJQJo(·ðh „8„˜þÆ8^„8`„˜þOJQJo(oh „„˜þÆ^„`„˜þOJQJo(§ðh „Ø „˜þÆØ ^„Ø `„˜þOJQJo(·ðh „¨ „˜þƨ ^„¨ `„˜þOJQJo(oh „x„˜þÆx^„x`„˜þOJQJo(§ðh „H„˜þÆH^„H`„˜þOJQJo(·ðh „„˜þÆ^„`„˜þOJQJo(oh „脘þÆè^„è`„˜þOJQJo(§ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð„h„˜þÆh^„h`„˜þ. „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „„˜þÆ^„`„˜þOJQJo(-h„h„˜þÆh^„h`„˜þ.h„8„˜þÆ8^„8`„˜þ.’h„„LÿÆ^„`„Lÿ.h„Ø „˜þÆØ ^„Ø `„˜þ.h„¨ „˜þƨ ^„¨ `„˜þ.’h„x„LÿÆx^„x`„Lÿ.h„H„˜þÆH^„H`„˜þ.h„„˜þÆ^„`„˜þ.’h„è„LÿÆè^„è`„Lÿ.h „h„˜þÆh^„h`„˜þOJQJo(·ðh „8„˜þÆ8^„8`„˜þOJQJo(oh „„˜þÆ^„`„˜þOJQJo(§ðh „Ø „˜þÆØ ^„Ø `„˜þOJQJo(·ðh „¨ „˜þƨ ^„¨ `„˜þOJQJo(oh „x„˜þÆx^„x`„˜þOJQJo(§ðh „H„˜þÆH^„H`„˜þOJQJo(·ðh „„˜þÆ^„`„˜þOJQJo(oh „脘þÆè^„è`„˜þOJQJo(§ð„¹„˜þƹ^„¹`„˜þB*CJOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð„h„˜þÆh^„h`„˜þ........  .... „€„€ûÆ€^„€`„€û ..... „„ðúÆØ ^„`„ðú ...... „ „`úÆ ^„ `„`ú....... „0„ÐùÆ0^„0`„Ðù........ „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð„¹„˜þƹ^„¹`„˜þB*CJOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ð „h„˜þÆh^„h`„˜þOJQJo(·ðh „Є˜þÆÐ^„Ð`„˜þOJQJo(·ðh „ „˜þÆ ^„ `„˜þOJQJo(oh „p„˜þÆp^„p`„˜þOJQJo(§ðh „@ „˜þÆ@ ^„@ `„˜þOJQJo(·ðh „„˜þÆ^„`„˜þOJQJo(oh „à„˜þÆà^„à`„˜þOJQJo(§ðh „°„˜þư^„°`„˜þOJQJo(·ðh „€„˜þÆ€^„€`„˜þOJQJo(oh „P„˜þÆP^„P`„˜þOJQJo(§ð „h„˜þÆh^„h`„˜þOJQJo(·ð½‰ÿÿÿƒÿÿÿ‚ÿÿÿÿÿÿ€ÿÿÿˆÿÿÿÿÿÿ~ÿÿÿ}ÿÿÿ|ÿÿÿ¾DäNbi]‰ÿÿÿ‰ÿÿÿƒÿÿÿ‚ÿÿÿÿÿÿ€ÿÿÿˆÿÿÿÿÿÿ~ÿÿÿ}ÿÿÿ|ÿÿÿ?D~WYA(5(ú4~³Ùrn*;‹%ÖVÏCÀ5DG ¨OWØH„G‘ó6í |lTPyQ¼´!hÔ$z:yÔ SÏ|ájâI6oŠoÀ%·)\PŠoÀ%¿$•6þs/=àÁ7¥u¡S7½fåCço¯2sa¿%./½sô'Øw&yLKQd«M®nz:%U=³,Äõx:¶Wt#ž*¹A˜O &>Ån~PEZD nô/~¨D·yOo<2Bû%ùzünû/°ÎUéZoÖ1K>¸ Ifør@ y5ëpÛ/eR[3p8¹e~%a±]]'žLþ ÎP© ¢VaXïu1]Mî!×Xäzõ>ô DiD1xWU[7B Er.g1K—VÁK Qúl¸]§fT î/@+`tmð2+$L;KO-z`tme"3û=MU`tm`tm zóK ])&'v<ÀZÎ-®\âv[¾c|/¿-B=8£Vv}1þ)Æ'` šB-{u!aùkž/2×S+HÞVÌ)X@Qv«[›Ø]‚zFÈq£!wjTK3!ü.–k¿#6%K^•m )Z¦­t7#8¶ Ð:ʈ[6TedTed[plõ/¡~ɾwzU„&"£4K¿9„{êt~ÎYÜdt[pl.YÈ @t–z-IŸu¥>€~ƧjæH8 üuèkG=¢²q{_µv¹Wz& *'[ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ®ÿÿ®f‹ fµ‚h6I_I`IqIˆI¡I¢I§I­I®I¯I°I±I²I³I´IµI·I¹I¿IÀIÅIÊIËIÎIÐIÖI×IÚIßIàIâIåIëIìIñIôIõIøIûIJJJJ J J J J JJJJJJJJJ$J%J(J*J/J0J3J6J7J9Jhttp://www.openmobilealliance.org/release_program/ds_v12.html0Uý SDK_manual.pdf0UÁSDK_manual.pdf^Z|http://www.pcre.org/t:SySync_script_call_flow.pdft_SySync_script_call_flow.pdf.s http://www.pcre.org/license.txt%3http://www.sqlite.org/D\http://www.zlib.net/LT 1http://sourceforge.net/projects/syncml-ctoolkit/ &http://sourceforge.net/projects/expathttp://www.synthesis.ch/.(http://www.syncml.org/http://www.synthesis.ch/ http://www.synthesis.ch/http://www.synthesis.ch/m#*Logo-Quadrat, alleinstehen pv£SyncML6q§sysync_diagram_big.jpgtðodebuglog_folding.png  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿþÿÿÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙþÿÿÿÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ                           ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~  € ‚ ƒ „ … † ‡ ˆ ‰ Š ‹ Œ Ž ‘ ’ “ ” • – — ˜ ™ š › œ ž Ÿ   ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ ­ ® ¯ ° ± ² ³ ´ µ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿ À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ ß à á â ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö ÷ ø ù ú û ü ý þ ÿ                           ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~  € ‚ ƒ „ … † ‡ ˆ ‰ Š ‹ Œ Ž ‘ ’ “ ” • – — ˜ ™ š › þÿÿÿ ž Ÿ   ¡ ¢ £ þÿÿÿ¥ ¦ § ¨ © ª « þÿÿÿýÿÿÿýÿÿÿýÿÿÿýÿÿÿýÿÿÿýÿÿÿýÿÿÿýÿÿÿýÿÿÿýÿÿÿýÿÿÿýÿÿÿýÿÿÿýÿÿÿýÿÿÿýÿÿÿýÿÿÿýÿÿÿýÿÿÿýÿÿÿýÿÿÿýÿÿÿÃ Ä Ñ Ö Ç È É Ê Ë Ì Í Î Ï Ð Ò ß Ó Ô Õ × þÿÿÿØ Ù Ú Û Ü Ý Þ à þÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿRoot Entryÿÿÿÿÿÿÿÿ ÀF€|9JÓqÊÆ @/Data ÿÿÿÿÿÿÿÿÿÿÿÿ8ª1TableÿÿÿÿÿÿÿÿÚЃWordDocumentÿÿÿÿj SummaryInformation(ÿÿÿÿÿÿÿÿÿÿÿÿœ DocumentSummaryInformation8ÿÿÿÿÿÿÿÿ¤ Macrosàõ7JÓqÊ€|9JÓqÊVBAÿÿÿÿÿÿÿÿ àõ7JÓqÊ€|9JÓqÊThisDocumentÿÿÿÿ ÿÿÿÿÔNewMacros ÿÿÿÿÇ __SRP_2 ÿÿÿÿH__SRP_3ÿÿÿÿÿÿÿÿÿÿÿÿU þÿÿÿ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGþÿÿÿIJKLMNOPQRSTþÿÿÿVWþÿÿÿYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€ÖäêÔÝ1p®»·ÿÿ£ˆ¶ÿÿÿÿÿÿÿÿÿÿÿÿ}ÛiÔ‘nžIØŽ—¼SœØáÛ§ˆ¼Dªà÷ÍA%Ð; Á_êÇLš¦ÿwðSÿÿÿÿÿÿÿÿÿÿÿÿxÿÿMEÿÿÿÿÿÿÿÿÿÿßÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ(S"ÿÿÿÿSÿÿÿÿS"ÿÿÿÿ<ÿÿÿÿÿÿ(1Normal.ThisDocumentÿÿÿÿ`€þÿÿÿÿÿÿÿ(ÿÿÿÿÿÿÿÿÿÿ%ÿÿÿÿHÿÿÿÿ@ÿÿÿÿ8ÿÿÿÿ0ÿÿÿÿHƒþÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ %‚ ÿÿÿÿþÿÿÿ°ÿÿþÿÿÿÿÿÿÿÿÿÿÿ %ÿÿÿÿ€ÿÿÿÿ¸ÿÿÿÿ°ÿÿÿÿÈÿÿÿÿÀÿÿÿÿØÿÿÿÿÐÿÿÿÿèÿÿÿÿàÿÿÿÿøÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ(ÿÿÿÿ ÿÿÿÿ8ÿÿÿÿ0ÿÿÿÿHÿÿÿÿ@ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿˆXÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿPû¨ LßþÊÿÿÿÿÿÿÿÿxÿÿÿÿ™°Attribute VB_Name = "ThisDocument" ŒBasŒ1Normal.VGlobal!ªSpaclFalse ¢CreatablPre declaIdžTru BExposeTemplateDeriv$Custom iz„Cƒ1ðŒÔØÿÿÿÿ2 j p® ?ÿÿ¶ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿxÿÿMEÿÿÿÿÿÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿP6 ÿÿÿÿLÿÿÿÿÿÿÿÿÿÿÿÿLÿÿÿÿLÿÿÿÿ”ÿÿÿÿ<ÿÿÿÿÿÿÿÿÿÿ( €`ÿÿÿÿ@èøþkÿÿÿÿÿÿÿÿÿÿ„"Project.NewMacros.addTagIndexEntry`„ÿÿÿÿxÿÿÿÿÿ 4ÿÿÿÿ`ÿÿÿÿÿÿÿÿØøþkÿÿÿÿÿÿÿÿÿÿ„`„ÿÿÿÿxÿÿÿÿÿ$ÿÿÿÿÿÿÿÿ€ƒÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ%ÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¨ØÿÿÿÿÀÿÿÿÿXÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿxÿÿÿÿÿÿÿÿ &0˜tÿÿÿÿÿ@þÿptÿÿÿ ÿÿ ÿÿ@þÿÿÿÿÿpÿÿÿÿÿ ÿÿ@þÿð`ÿÿÿ ÿÿ ÿÿ@þÿPÿÿÿ ÿÿ ÿÿ@þÿ(@ÿÿÿ ÿÿ ÿÿ@þÿ@0ÿÿÿ ÿÿ ÿÿÿÿØ@þÿÿÿÿÿ ÿÿÿ ÿÿ À@þÿÿÿÿÿÿÿÿ ÿÿ ÿÿÿÿ@þÿÿÿÿÿ ÿÿÿÿÿ h@þÿˆÿÿÿ ÿÿ À@þÿ ÿÿÿ ÿÿ ÿÿÿÿ@þÿ¸ÿÿÿ ÿÿ À@þÿÐüþÿÿ ÿÿ À@þÿÿÿÿÿøþÿÿ ÿÿ hÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿhÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¸ èÿÿÿÿÐÿÿÿÿpÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿˆÿÿÿÿÿÿÿÿ &0ÿÿ ÿÿ b@þÿtÿÿÿ ÿÿ am@þÿÿÿÿÿpÿÿÿÿÿ yS@þÿ`ÿÿÿ ÿÿ 5.@þÿPÿÿÿ ÿÿ om@þÿ8@ÿÿÿ ÿÿ oj@þÿP0ÿÿÿ ÿÿ c\ÿÿÿÿ@þÿÿÿÿÿ ÿÿÿ ÿÿ @þÿÿÿÿÿÿÿÿ ÿÿ ÿÿÿÿ@þÿÿÿÿÿ ÿÿÿÿÿ ÿÿÿÿP@þÿ¨ÿÿÿ ÿÿ n@þÿÈÿÿÿ ÿÿ tÿÿÿÿX@þÿèÿÿÿ ÿÿ ÿÿÿÿ¨@þÿüþÿÿ ÿÿ g103ÿÿÿÿÈ@þÿÿÿÿÿøþÿÿ ÿÿ ÿÿÿÿÿÿÿÿèÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿèÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÈû¨ L$*\Rffff*064ca0a8fb*\R1*#103*\R1*#5c*\R1*#1e*\R1*#129*\R1*#c1*\R1*#17bßþÊ"€ $7 N{@€ ÿÿÿÿ"˜€  $¨7¸N{Ø(€ ÿÿÿÿ€ ÿÿÿÿÿÿÿÿ8–]òh !d' &Ñ$¬Ñ( B@"¦ !.Ñ. 0Ñl¶XE "  ¶" \f T Ñd·Ñ2 !*B@,¾³oÿÿh–€]òÀ !d'ic &Ñ$¬Ñ( B@"e$¦ !.Ñ. 0Ñl¶XE "  ¶" \f F Ñd·Ñ2 !*B@,oÿÿÐÿÿÿÿÈÿÿÿÿS±Attribute VB_Name = "NewMacros" Sub addTagIndexEntry()  à :.’Pro cDataInvoke_Func¸4ject.-È. @u Dim n As S¡¢ng nBSel@ion.0TextMoveLeft Unit:=wdCharacter@, Coun2 3Fields.Add Range:=‡', T$yp wdEmpty€ ?:= _'"XE ""(" +€Z+‚\f T", PreserveFormatting:=False End €° ´½“t€m‹¶}ׇ1ÿCåCFæC rU€€€€~| ‰©Ñ 1a¡8Ü$pÿtÿ$ <tÿ >pÿ1xÿtÿ7 ÿ'ÿ(0ÿþÁPÿtÿ$ <tÿ ütÿ6Pÿ0ÿÿ{ÿtÿ$ <tÿ äøþüfÿlxÿ*#pÿ*F0ÿþÁPÿÿÿÿÿQÿ[üþÿÿ$ <ÿ ˆÿ L/pÿ) tÿÿüþÿøþ6Pÿ0ÿÿ„Ü(xÿ4 pÿtÿÿÿÿüþøþPÿ0ÿÿ8Ü$pÿtÿ$ <tÿ >pÿ1xÿtÿ7 ÿ'ÿ(0ÿþÁPÿtÿ$ <tÿ ütÿ6Pÿ0ÿÿ{ÿtÿ$ <tÿ äøþüfÿlxÿ*#pÿ*F0ÿþÁPÿÿÿÿÿQÿ[üþÿÿ$ <ÿ ˆÿ L/pÿ) tÿÿüþÿøþ6Pÿ0ÿÿÿ„Ü(xÿ4 pÿtÿÿÿÿüþøþPÿ0ÿÿfrU€€€ ÿÿÿÿÿÿÿÿ$`ýÿÿÿÿÿÿÿa$©`ýÿÿÿÿÿÿÿÿÿÿÿn_VBA_PROJECTÿÿÿÿÿÿÿÿÿÿÿÿXE dirÿÿÿÿÿÿÿÿÿÿÿÿŠ__SRP_0 ÿÿÿÿ—5__SRP_1ÿÿÿÿÿÿÿÿÿÿÿÿ°pÌamÿ äú*\G{000204EF-0000-0000-C000-000000000046}#4.0#9#C:\PROGRA~1\GEMEIN~1\MICROS~1\VBA\VBA6\VBE6.DLL#Visual Basic For Applications*\G{00020905-0000-0000-C000-000000000046}#8.1#0#C:\Programme\Microsoft Office\Office\MSWORD9.OLB#Microsoft Word 9.0 Object Library¸*\G{00020430-0000-0000-C000-000000000046}#2.0#0#C:\WINNT\System32\stdole2.tlb#OLE AutomationÞ*\G{0D452EE1-E08F-101A-852E-02608C4D0BB4}#2.0#0#C:\WINDOWS\system32\FM20.DLL#Microsoft Forms 2.0 Object Library*\G{AB8C0D4F-F982-46CC-BAE5-82D79A0E6A49}#2.0#0#C:\DOKUME~1\luz\LOKALE~1\Temp\VBE\MSForms.exd#Microsoft Forms 2.0 Object Libraryá.E à….`ŒM ´*\CNormal*\CNormalû¨ L*\G{2DF8D04C-5BFA-101B-BDE5-00AA0044DE52}#2.1#0#D:\Programme\Microsoft Office\Office\MSO97.DLL#Microsoft Office 8.0 Object Library  ÿÿÿÿÿÿû¨ Lÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿp®ThisDocument034ca0a8fbÿÿThisDocumentÿÿ»·7ÿÿNewMacros064ca0a8fbÿÿNewMacrosÿÿ ?p ÿÿÿÿÿÿ8ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ‚ƒ„…†‡ˆ‰þÿÿÿ‹ŒŽ‘’“”•–þÿÿÿ˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯þÿÿÿ±þÿÿÿ³þÿÿÿµ¶·¸¹ºþÿÿÿ¼þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿê\©ö‹F±þ r ÿÿÿÿ ¥k!qB¦ÆZ³PfYkÿÿÿÿÿÿÿÿH€ÿ ( Wordµk VBA÷âWin16Á~Win32Mac³²VBA6­# Project-®stdole“`MSFormsCˆ ÿNormalߨˆ ÿOfficeu ThisDocument<ž €ÿ_EvaluateÙ NewMacros®j¬(addTagIndexEntry¾Âne SelectionZ®MoveLeftv“UnitŸ wdCharacterÉCount0vFields7©Add÷rRangeÚ  wdFieldEmpty›çPreserveFormatting=¬(addFunctionIndexEntry× „ÿDocumentjÓ €ÿDoPrefsFormtÊÿÿlÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ$@€³€0* pH‚däProjectQ(@=­ l €û¨ L J< rstdole>stdoleP f%\*\G{00020°430-C 0046}#2.0#0#C:\WINNT\System32\c2.tlb#OLE Autom`ation^mMSForms> MSFErms3€DD452EE1-E08F-101A-8-02608C@4D0BB4 DD OWS\sEFM20.DLL#MicrosoftŠ ‚: €] Ob­ Libraryè/;D1€„€tˆ€ˆ€00}#0‚€#€k0ž €€AAB8C0D4F-F982-46CC-BAE5-82D79A0E6A49ˆ6DOKUME~1\luz\LOKALTemp \VBE\DS.exdà:€ €á.E à….``ŒM ´¤C‰N©@falC‰N„eaÀ‰( À À*\NC AÃOPfficDšO@—fPicBšŒÀ‚ÂG{2DF8D04C-5BFA!xB-BD@A00TAA@™4À2EAD:\ÀÃgramm,e\t\„MSO97Œ|ƒ 8..0Ì|!€‚Ü"Âp®BÇThisDocume ntGÀ T"hÀ0sD@Dc¢u€ªenÀÐÎ Š2Ú ` H¢j1¢u7@€",Qâ»·""+¢‚-NewMaY(GÀNÀ)w(Ma+r€sË2Ô/p b- ?!b#b“K*mÿÿÿÿ *\CNormalrU€€€€~~~~~~~~~i G§iÇ–e,G½ž<èÓgAÕ äÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿ¹ˆa 9ÿÿÿÿÿÿÿÿÑÿÿá¹Á¡‘ <ÇÃN¶ëE°æ~!{ Ïy ThisDocument NewMacrosProjectïÀF /C:\PROGRA~1\GEMEIN~1\MICROS~1\VBA\VBA6\VBE6.DLLVBA ÿÿÿÿ A©0 ÀF 0C:\Programme\Microsoft Office\Office\MSWORD9.OLBWord ÿÿÿÿ9©@0ÀFC:\WINNT\System32\stdole2.tlbstdole ÿÿÿÿA‰Pá.E à….`ŒM ´C:\WINDOWS\system32\FM20.DLLMSForms  1y`O Œ«‚ùÌFºå‚ךjI -C:\DOKUME~1\luz\LOKALE~1\Temp\VBE\MSForms.exd é ypLÐø-ú[½åªDÞR .D:\Programme\Microsoft Office\Office\MSO97.DLLOffice Ñÿÿÿÿùa€addTagIndexEntryaddFunctionIndexEntry ð ÀF¹ ÀFYÿÿÿÿu ÀF XE " " \f F0 ÀFY¨ " \f TfrU€€€ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ  "Project.NewMacros.addTagIndexEntryjThisDocumentThisDocumentNewMacrosNewMacrosID="{048068B2-39DC-4C93-B43B-1D7131A08ED0}" Document=ThisDocument/&H00000000 Module=NewMacros Name="Project" HelpContextID="0" VersionCompatible32="393222000" CMG="A1A31F6523652365236523" DPB="B1B30F7010701070" GC="C1C37F808080807F" [Host ExtendPROJECTwmÿÿÿÿÿÿÿÿÿÿÿÿ²GPROJECTÿÿÿÿ´CompObjÿÿÿÿÿÿÿÿ»jObjectPoolÿÿÿÿÿÿÿÿÿÿÿÿ€|9JÓqÊ€|9JÓqÊer Info] &H00000001={3832D640-CF90-11CF-8E43-00A0C911005A};VBE;&H00000000 [Workspace] ThisDocument=0, 0, 0, 0, C NewMacros=0, 0, 0, 0, C þÿ ÿÿÿÿ ÀFMicrosoft Word-Dokument MSWordDocWord.Document.8ô9²qlibsynthesis-3.4.0.47.1/doc/SySync_config_reference.pdf000066400000000000000000066401361226375725500227170ustar00rootroot00000000000000%PDF-1.3 %âãÏÓ 1738 0 obj << /Linearized 1 /O 1740 /H [ 8198 5727 ] /L 1785950 /E 780754 /N 206 /T 1751070 >> endobj xref 1738 382 0000000016 00000 n 0000007996 00000 n 0000013925 00000 n 0000014087 00000 n 0000014158 00000 n 0000014278 00000 n 0000014436 00000 n 0000014616 00000 n 0000014749 00000 n 0000014901 00000 n 0000015030 00000 n 0000015160 00000 n 0000015383 00000 n 0000015629 00000 n 0000015808 00000 n 0000016003 00000 n 0000016196 00000 n 0000016349 00000 n 0000016528 00000 n 0000016704 00000 n 0000016875 00000 n 0000017030 00000 n 0000017188 00000 n 0000017354 00000 n 0000017519 00000 n 0000017706 00000 n 0000017869 00000 n 0000018035 00000 n 0000018201 00000 n 0000018384 00000 n 0000018568 00000 n 0000018746 00000 n 0000018921 00000 n 0000019100 00000 n 0000019263 00000 n 0000019437 00000 n 0000019601 00000 n 0000019857 00000 n 0000020046 00000 n 0000020211 00000 n 0000020381 00000 n 0000020589 00000 n 0000020772 00000 n 0000020954 00000 n 0000021155 00000 n 0000021277 00000 n 0000021507 00000 n 0000021636 00000 n 0000021772 00000 n 0000021905 00000 n 0000022085 00000 n 0000022230 00000 n 0000022371 00000 n 0000022512 00000 n 0000022637 00000 n 0000022762 00000 n 0000022908 00000 n 0000023054 00000 n 0000023320 00000 n 0000023544 00000 n 0000023721 00000 n 0000023946 00000 n 0000024128 00000 n 0000024279 00000 n 0000024450 00000 n 0000024621 00000 n 0000024822 00000 n 0000024993 00000 n 0000025188 00000 n 0000025370 00000 n 0000025538 00000 n 0000025822 00000 n 0000025989 00000 n 0000026207 00000 n 0000026375 00000 n 0000026550 00000 n 0000026741 00000 n 0000026905 00000 n 0000027080 00000 n 0000027261 00000 n 0000027431 00000 n 0000027621 00000 n 0000027793 00000 n 0000027958 00000 n 0000028173 00000 n 0000028343 00000 n 0000028523 00000 n 0000028759 00000 n 0000028932 00000 n 0000029106 00000 n 0000029275 00000 n 0000029483 00000 n 0000029662 00000 n 0000029834 00000 n 0000030006 00000 n 0000030197 00000 n 0000030367 00000 n 0000030538 00000 n 0000030741 00000 n 0000030892 00000 n 0000031078 00000 n 0000031236 00000 n 0000031415 00000 n 0000031574 00000 n 0000031735 00000 n 0000031880 00000 n 0000032027 00000 n 0000032215 00000 n 0000032391 00000 n 0000032594 00000 n 0000032764 00000 n 0000032966 00000 n 0000033182 00000 n 0000033303 00000 n 0000033460 00000 n 0000033635 00000 n 0000033800 00000 n 0000033984 00000 n 0000034157 00000 n 0000034332 00000 n 0000034518 00000 n 0000034690 00000 n 0000034870 00000 n 0000035062 00000 n 0000035241 00000 n 0000035426 00000 n 0000035621 00000 n 0000035813 00000 n 0000036028 00000 n 0000036232 00000 n 0000036424 00000 n 0000036613 00000 n 0000036802 00000 n 0000036977 00000 n 0000037149 00000 n 0000037292 00000 n 0000037461 00000 n 0000037670 00000 n 0000037831 00000 n 0000037973 00000 n 0000038148 00000 n 0000038341 00000 n 0000038493 00000 n 0000038702 00000 n 0000038922 00000 n 0000039098 00000 n 0000039249 00000 n 0000039419 00000 n 0000039598 00000 n 0000039779 00000 n 0000039948 00000 n 0000040115 00000 n 0000040303 00000 n 0000040525 00000 n 0000040709 00000 n 0000040899 00000 n 0000041068 00000 n 0000041255 00000 n 0000041441 00000 n 0000041609 00000 n 0000041783 00000 n 0000041962 00000 n 0000042142 00000 n 0000042346 00000 n 0000042540 00000 n 0000042724 00000 n 0000042892 00000 n 0000043065 00000 n 0000043269 00000 n 0000043458 00000 n 0000043646 00000 n 0000043814 00000 n 0000043978 00000 n 0000044145 00000 n 0000044314 00000 n 0000044492 00000 n 0000044654 00000 n 0000044827 00000 n 0000044998 00000 n 0000045145 00000 n 0000045313 00000 n 0000045535 00000 n 0000045742 00000 n 0000045937 00000 n 0000046106 00000 n 0000046281 00000 n 0000046445 00000 n 0000046602 00000 n 0000046774 00000 n 0000046929 00000 n 0000047087 00000 n 0000047244 00000 n 0000047402 00000 n 0000047560 00000 n 0000047747 00000 n 0000047962 00000 n 0000048151 00000 n 0000048347 00000 n 0000048518 00000 n 0000048703 00000 n 0000048872 00000 n 0000049056 00000 n 0000049242 00000 n 0000049406 00000 n 0000049587 00000 n 0000049791 00000 n 0000049980 00000 n 0000050197 00000 n 0000050410 00000 n 0000050579 00000 n 0000050744 00000 n 0000050914 00000 n 0000051089 00000 n 0000051278 00000 n 0000051441 00000 n 0000051604 00000 n 0000051782 00000 n 0000051959 00000 n 0000052121 00000 n 0000052295 00000 n 0000052469 00000 n 0000052681 00000 n 0000052827 00000 n 0000052953 00000 n 0000053158 00000 n 0000053376 00000 n 0000053556 00000 n 0000053700 00000 n 0000053857 00000 n 0000054021 00000 n 0000054203 00000 n 0000054391 00000 n 0000054590 00000 n 0000054775 00000 n 0000054943 00000 n 0000055116 00000 n 0000055315 00000 n 0000055521 00000 n 0000055698 00000 n 0000055860 00000 n 0000056075 00000 n 0000056243 00000 n 0000056377 00000 n 0000056533 00000 n 0000056693 00000 n 0000056852 00000 n 0000057001 00000 n 0000057160 00000 n 0000057325 00000 n 0000057468 00000 n 0000057629 00000 n 0000057799 00000 n 0000057976 00000 n 0000058143 00000 n 0000058293 00000 n 0000058462 00000 n 0000058618 00000 n 0000058785 00000 n 0000058990 00000 n 0000059136 00000 n 0000059298 00000 n 0000059485 00000 n 0000059642 00000 n 0000059799 00000 n 0000059972 00000 n 0000060131 00000 n 0000060307 00000 n 0000060482 00000 n 0000060628 00000 n 0000060791 00000 n 0000060965 00000 n 0000061127 00000 n 0000061295 00000 n 0000061493 00000 n 0000061702 00000 n 0000061856 00000 n 0000062023 00000 n 0000062181 00000 n 0000062374 00000 n 0000062535 00000 n 0000062699 00000 n 0000062859 00000 n 0000063038 00000 n 0000063231 00000 n 0000063418 00000 n 0000063581 00000 n 0000063767 00000 n 0000063953 00000 n 0000064125 00000 n 0000064288 00000 n 0000064465 00000 n 0000064630 00000 n 0000064790 00000 n 0000064934 00000 n 0000065101 00000 n 0000065243 00000 n 0000065394 00000 n 0000065540 00000 n 0000065707 00000 n 0000065876 00000 n 0000066054 00000 n 0000066220 00000 n 0000066378 00000 n 0000066540 00000 n 0000066715 00000 n 0000066902 00000 n 0000067035 00000 n 0000067172 00000 n 0000067353 00000 n 0000067495 00000 n 0000067642 00000 n 0000067786 00000 n 0000067972 00000 n 0000068102 00000 n 0000068228 00000 n 0000068430 00000 n 0000068607 00000 n 0000068732 00000 n 0000068856 00000 n 0000069000 00000 n 0000069152 00000 n 0000069300 00000 n 0000069453 00000 n 0000069627 00000 n 0000069758 00000 n 0000069885 00000 n 0000070022 00000 n 0000070146 00000 n 0000070268 00000 n 0000070408 00000 n 0000070544 00000 n 0000070721 00000 n 0000070861 00000 n 0000070987 00000 n 0000071121 00000 n 0000071261 00000 n 0000071428 00000 n 0000071571 00000 n 0000071706 00000 n 0000071842 00000 n 0000071998 00000 n 0000072131 00000 n 0000072291 00000 n 0000072512 00000 n 0000072645 00000 n 0000072778 00000 n 0000072920 00000 n 0000073096 00000 n 0000073243 00000 n 0000073384 00000 n 0000073549 00000 n 0000073708 00000 n 0000073851 00000 n 0000074005 00000 n 0000074184 00000 n 0000074307 00000 n 0000074463 00000 n 0000074598 00000 n 0000074746 00000 n 0000074878 00000 n 0000075005 00000 n 0000075207 00000 n 0000075331 00000 n 0000075493 00000 n 0000075630 00000 n 0000075876 00000 n 0000075919 00000 n 0000077005 00000 n 0000077216 00000 n 0000077271 00000 n 0000077819 00000 n 0000078035 00000 n 0000078624 00000 n 0000078765 00000 n 0000113674 00000 n 0000114533 00000 n 0000116977 00000 n 0000130942 00000 n 0000168316 00000 n 0000173390 00000 n 0000008198 00000 n 0000013901 00000 n trailer << /Size 2120 /Info 1703 0 R /Root 1739 0 R /Prev 1751058 /ID[] >> startxref 0 %%EOF 1739 0 obj << /Type /Catalog /Pages 1715 0 R /Outlines 1741 0 R /OpenAction [ 1740 0 R /XYZ null 846 1 ] /PageMode /UseOutlines /PageLabels << /Nums [ 0 << /S /D >> ] >> /JT 1737 0 R >> endobj 2118 0 obj << /S 7267 /O 8383 /Filter /FlateDecode /Length 2119 0 R >> stream H‰lT}TS÷~obH" ! Ö¦³³N4á£-2Êšu«gǹʬgÂÇ` [á"B¤AºYE†«,àÁ3µ›J@8\C ‡lMÀœã$&7'd] ‰b‰“ªûáìì»ýÎ}?Ÿç}Ÿ¨|:D¢G#ij/"Ð_0 ªŸ`]cû„qÇZز; °dßΦ"*änfShˆø)@£0¨0õî§ÑiÈCÅå²Ù4P‰€Ë¥Ñ¨˜Êô$1FQ© Ç¥PA¥*P³© ¸±t­qÆ `¨ø\Æ„‘'…G£DÐ~ ]*›Ž5¨ø|Þ+ôʇª®œÍ åIõÍl&‡‚™PX,=k©Tü¤X *Ú•ÂàEQ…›øl ¥q·áQ èØSÀWïtqΣ²›vSF*’÷RÞkÙ¢¤4Û¾¿ó§pïcBQ¬¾ÈÁáóû,üÑF­‡`î‚ëM Ïá¦Áã,óY[àd ç»ÐÇø'´ñÁ^²qïÃ#Ï_Úb2°_Úâ^ÄÞ QV0^è¹|øGEäm˜¶a!øÈ´îôFîƒKü(|Èå¿õgB, êsçPŸŒP…hC ËaÞG/ç7pÖÄnw÷r¸¯€>‡Å‚›!6wC¿<Äz* ¹Eàȡ烺…¹ô*ÖI™Ø?„á”HøMÌ7à“.Ƨp¢‚®ƒm]¼bî„-œ<(ç¯_ÄR¹LüÙFŸ‡¿W¬‡[6æEð¥løÖê‰Î„Ë)Q×à¯\æh-d‚Ó)Ñ›àkQôK0Šé»Í²…1'»"ë¡®—Q ¿µ1"Ñ<×-ƒ+× á”ç¶BcPáa}ŸÚЈ.r×ÿ Ω¢ÒÁlc•csŽó¶¨6øÜÆ|$ž¨ ,šX›!Øý"㉽Zã H²EAÉgöù úß`¤nÂYc7ì/ŒH‡÷M‘ØÕÅ‘ÁºÖÙ ÁÉ>õ]8ƧO|;lT+Ý;÷|y^˜èÞ{Þ­´¸ù‚¨6Ì\»ž:§é •ÿkϽâ›ÓNž«®wïê¹táÞ­ÀJj°îüÎ4µòùñìàÏÝ/÷i>žA/¥`%_ó±÷;(o_g·Ò½iÆ83±)£Û¿ã÷÷Œ‹ñ“ÃÚñµ4aGªzç®bÞ·ôqéè‹xä rE™u|ÌÂ.ÔZ–FçËI¿Øb×ç*2Quoõ¤d9>QJÌ–š‚÷Qó¨hÞ•}¤t5û°y®Š04ÆùÀ轟ÕjOUÄB•·šÝ90w%cÈ8:ßn𨓵•¾¶ ×6ÂÒÜC=:‚šoê$3Ûd…_Î:~£×ò镟y¬V{´Ú K×dIsÖš?”´¢ØÐ8"IW$Îd»º È}]ê\Õ%k‰p©y!”áôü¬\Ÿ'çYÍN_‡N‚–¼Çœcz—Ö.–Ž“GG\Û%MO¢¡”¦,øcN©¹¤Çîz[˜¥´¸Û›:¯ûÛÐdŽÍ¢¥´{ÒÛa•â“ÖkÉ2ËL WÜI¦vLx—Ë Ý^­_H×lÉ'ËŒ\!>SœYIHƒ5dÞøìa³»ßáÚ·.¦%Ì•xo¤*'HütÝzí|Ť$ oju†Û 2í~"rîÐOWÅ'ùÜè eºo¤vèó—kHYµTçB$h‹¼5„¯UNOù*­åñ‰2ÁCüFQ?1´>(lû†Þa—à5kÞòÌä\w­ræeêÿª—Ì.C_…ãÑúÙ?¢‡Û->Nm¾îSŠ‚S–€bÙ1²re(ª<,ׄÂÉÚ 5ÖAíòÏÁZ壢« %éñâÖ>²T')ÌjuÎkRoxʳ£I›Ô-9XcX“§^Œ”‹#ÈÃsÁ5]P'¾iÕBâVsÀÞ0á–+׆ûM«t@4‰Ó=œÆæ–í®¥Õ k™õj)™Èk¬K=Ñ,âSé©Ç Rèð„1gðòáèüSg§½Œðô… GÆÑÝ(Dò4ö…ñWyÂb^8¦Ó\ÐOóUÿÿ  6Ž’eº™¥ZÿŠ0ɼ7üõSÁ"ꞌ)¨úïBöÇ—I'ý„¸ü5ÃL¾¿Ê ä&¡ƒV|֔⭱æá§È§ü &GÃe„38ø²©)éGUÑHûV4Ó²aŸü׋hŸ5¨Õxñ©´¥*«4GJÇÃ¥ÈÇÑô«¨©ô ÿ…ðPˆY ”í”ÅÇ8²²QU[g§KQ$Z¶f <’å±f Ø©n\ÐÅŽXq§Ýí´]‚èÃk“횈™i 8v0`$´ öü÷‘°Û sçrÿÿžÿœï|ç;ç6˜&ÕÚl€wއâ‘7öXТXe.TAßÔ"°nÏ ¹EÜ©>ÔN¤ D¼ôâ²1OñÈÜjæ•òÚ»gç’m¸<Ó”PPø<_ *ÅÏ‚oôOB 6&Ì’58'±Õög+lvÉ>Ïeȧ ±O]ÝìBcî|…]â©z0]œ©|ašTò’AùÆ6!•O Ö͸*¡r!§XK~wЧ.4Éà!W?vJÉ–a&¼>þ*ªT'êäˆr¡`õSíZóÒù•Ú{NYEO_¨ zp*¹"Q£ˆmÒMÏq ¹ žýXINrú'›êŒÃ¸qðü$ÎqÃBH\Z%›»¬”u°Êô"PÚ\½DçXXn‘œ_iíÏé¤dP´qR¾ä–ôÚ“´=[‹£ªž-Í;™ü¢IŸÇ#ˆô[³rQ¤$;b“§Ä !ãÎØbÉ–5(õÀÌÜéCíФ _PP)zÞ€%ãJš‚‡2B.TÐ…›k»î¿‚ ºÿ£¼hòÜÓèˆ)<,¸[¹—k[GÒÀÕŽ%³¬#J­)*ãÆÍ Îd[­TBt1ÿs|Rcx~{¥Õ˜×yб«{aÏê‘û³*“øN¬¹u¼kë4ö›ù|zã–äÓÃ.Ç‚'îâð4¤`‘C5 ·gõ94…¡©Î÷z¶LX;]¸«Þé"w]r¡@Jt0‡\+쇜 Ë9³å¾–= Ÿ0[‹¨ïhÙÕÄY’ïq•k³Q›º×Ú{Ñé">—¶Ç–C.Ô‡M3íši}Á[ÝëÄJ¦=‰£¾iÒ>knù©çȇƒ‹:ÃRÎôÇ÷ˆ~j²Étg€l â» °W›až]­Þ]=8]|úÍcÃÎFƒ4©9ûk-õYràTÞ›žW@§V˜±c¸ÇaEªÕö&èð]€sÖ·#ø ;ø@€—¾š/ÍO‡\¯>@KôåR¸(ëÇ]y3dàß²DÉ€ÅSgOêŽÀMÊ@ùŒ1¬Hl×Ú MZèzP5±T*|MP©T1bð!&ù¥òÿW!qåó‰¥Mé'È%DíÜøNˆï,ö¡ßÖ z…>±„¤l>Ÿ/%ö°àGºÃ€»tyÜnÛKnÅXx/ü”¿|à“ï%¤{%)Sˆ±mg*ù˜±#ß»ÎbñU~¤«¼.²øB•?LA{ Céøw"**.¦ïÊØF¹ˆ—)o(d H”6g’¾‘¯ÑQ°¨(à·“ŸJûöäÓ¸ ñÉpbȇ^È0ÄÂv:` NõA› ÞOFÂ"ÌØ!•J}БwÁÞÆcÖqQkl?o½‚PöR`¤“,| jèè©ØÓ¥ÞÐa¿MÇNåûVµB$ HFꎱ=ÓçÌkÇiè 5{¨ô4âûŒ¦S`‘ÛÉçóið¼Þó…€P¾Ï.q4"Ù#¥ÓæÇŒò¦ž†”fKHG‘à3Iáæ…‘hA*3ÉͦHà6gú¶Ò/8ø_’„LbEÈ|b)O–+Às¨ötš¸¿oº4éúc®=™b…/hŠ[ìT¿=Þ´ÁƒàT¿¸pœ8Ðuµ½ÞºÈñûDï òJfžðÛ/=ôkXuÐÔàºê%M¾A§WÑþ´!U@ù‘îg–éóÈ«/~w ´ƒA »H´ »ÁhýòjX ÉQä·²)ýêv*8ß§TA»…tÈ>2{ýa±)«¤’ R8È#è²ðó—”â,•7@æ …®,â<°u*Ÿv‰âÿqrs.3ªÎÒ}nùùç]ë;ˆ“?yÐÚ{Íy¿¿»ó7£>E5ñ{~Ô_’ø« wë÷)ƒ®Xwÿ‚1›½Ìà}m}•Á¸ŒþîŽüýÞ\…fPøOÐ…šˆ·²Œè·PçQægh1>bºžõ]t;~ó¿PS<óŒ]ÖèeôÒóýÛÊ0~nÝñã˜;h‰ãÞ&Aÿ, {„Æ­ 7º4ú_të\Ø)ô·ø­Nô»èø_¢ªÇLjsG0PUóOà?³Õ¸7õ iFø²ÝŠú5úd ²MdD_C†ŒèýHŸþ᎔¡÷æ|$sG¼äç¢s-#D‚êêÃ#}MÄuäˆü>êK ;Šfˆ>¾Éü3ºV¢Akh,z×þ#t­>JŒŠâ·ÀtÇ+y´ †YÍÖf.v·ÚˆNñȉMbÛ¾þ˜?É&¼[,9!÷GqK^Çiñ-ë»Ìd\Á­lå7Éð°:¯K›Þ×ê4~ÁGø-fð3»ç'Œ³¡É%¼g ›|ˆßå3{|“òN‡yÜ”7qc^Á‰9ˆÛâOêMf©§\Ä-ŒÍÇŽÙåªÎ01Aس•ßàc¼\”â¦Ä¶‚×3äõç$cRä&<²]›„³‚êy/± ¯ÁIÉ#ˆ8Oˆ z|Å`Åqq´ñKA5ì„¡Ìôñ*d«ˆË±µj%S¸ Q¦MLZrT?o˺#’6'¹“x‹Ôs-HsÒ•LË¿y~"^ë2æºàµ;®c“òù”62ÜÌJ eIMJ•Ä2¢ŸQ¬KBNX˜¾ —•êJ±å| ¢K„7ñ*kÕô͈ÍR͸€ŸŠ(1Uanñ8 7ä½åÖ4s à¢\»&оÒk„‰…gÓ´"¹{ð"ޓŇuiËœ“â˜Uïˆò]­n(øSòà¸4ŸSñy5sP2¦…w† Ë¸=Kß:º‚—ªUEa窳xzê<|ÇxMä„R8"ø ±]аžÞŒØFq*óÀJÆT¼ ‘UéÏjwêÞQÜœcò`7Nƒ}8;p#`3g¿,Ù£Ÿêm/Ni9"¯Ç‚ïð–‚ÓŒ·ÕÖÛjÁþÿ¢º‚C89¯‰r§TíÓó/&,CQ{@Xlµ³sÛ!Ø¿î@¼x·öÜøK hÚ[À°˜ÿõqƒxÍÞ+‡àŸÍÿ 0œÛ¯Î endstream endobj 2119 0 obj 5605 endobj 1740 0 obj << /Type /Page /Parent 1704 0 R /Resources 2102 0 R /Contents 2107 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1741 0 obj << /Count 360 /First 1742 0 R /Last 1743 0 R >> endobj 1742 0 obj << /Title (Introduction) /Dest [ 10 0 R /XYZ null null null ] /Parent 1741 0 R /Next 2096 0 R >> endobj 1743 0 obj << /Title (Index) /Dest [ 1650 0 R /XYZ null null null ] /Parent 1741 0 R /Prev 1744 0 R /First 1745 0 R /Last 1745 0 R /Count 1 >> endobj 1744 0 obj << /Title (Error codes) /Dest [ 1637 0 R /XYZ null null null ] /Parent 1741 0 R /Prev 1746 0 R /Next 1743 0 R /First 1747 0 R /Last 1748 0 R /Count 2 >> endobj 1745 0 obj << /Title (Alphabetic Index of all config XML tags) /Dest [ 1650 0 R /XYZ null null null ] /Parent 1743 0 R >> endobj 1746 0 obj << /Title (List of built-in timezones) /Dest [ 1634 0 R /XYZ null null null ] /Parent 1741 0 R /Prev 1749 0 R /Next 1744 0 R >> endobj 1747 0 obj << /Title (SyncML Status Codes) /Dest [ 1637 0 R /XYZ null null null ] /Parent 1744 0 R /Next 1748 0 R >> endobj 1748 0 obj << /Title (Internal Error Codes) /Dest [ 1643 0 R /XYZ null null null ] /Parent 1744 0 R /Prev 1747 0 R >> endobj 1749 0 obj << /Title (: Command line client-only configuration tags) /Dest [ 1596 0 R /XYZ null null null ] /Parent 1741 0 R /Prev 1750 0 R /Next 1746 0 R /First 1751 0 R /Last 1752 0 R /Count 23 >> endobj 1750 0 obj << /Title (, : Synthesis SyncML Engine library only configuration t\ ags) /Dest [ 1583 0 R /XYZ null null null ] /Parent 1741 0 R /Prev 1774 0 R /Next 1749 0 R /First 1775 0 R /Last 1776 0 R /Count 3 >> endobj 1751 0 obj << /Title (: Set default SyncML Version to start a session) /Dest [ 1596 0 R /XYZ null null null ] /Parent 1749 0 R /Next 1773 0 R >> endobj 1752 0 obj << /Title (: Request to sync a datastore) /Dest [ 1616 0 R /XYZ null null null ] /Parent 1749 0 R /Prev 1753 0 R /First 1754 0 R /Last 1755 0 R /Count 6 >> endobj 1753 0 obj << /Title (, : Login to remote SyncML server) /Dest [ 1616 0 R /XYZ null null null ] /Parent 1749 0 R /Prev 1760 0 R /Next 1752 0 R >> endobj 1754 0 obj << /Title (: path of remote server's datastore) /Dest [ 1616 0 R /XYZ null null null ] /Parent 1752 0 R /Next 1759 0 R >> endobj 1755 0 obj << /Title (: define inclusive SyncML DS 1.2 record filter) /Dest [ 1627 0 R /XYZ null null null ] /Parent 1752 0 R /Prev 1756 0 R >> endobj 1756 0 obj << /Title (: define SyncML DS 1.2 record filter) /Dest [ 1627 0 R /XYZ null null null ] /Parent 1752 0 R /Prev 1757 0 R /Next 1755 0 R >> endobj 1757 0 obj << /Title (: local datastore options) /Dest [ 1621 0 R /XYZ null null null ] /Parent 1752 0 R /Prev 1758 0 R /Next 1756 0 R >> endobj 1758 0 obj << /Title (: Force a slow sync) /Dest [ 1621 0 R /XYZ null null null ] /Parent 1752 0 R /Prev 1759 0 R /Next 1757 0 R >> endobj 1759 0 obj << /Title (: Synchronisation mode) /Dest [ 1616 0 R /XYZ null null null ] /Parent 1752 0 R /Prev 1754 0 R /Next 1758 0 R >> endobj 1760 0 obj << /Title (, : Proxy auth) /Dest [ 1613 0 R /XYZ null null null ] /Parent 1749 0 R /Prev 1761 0 R /Next 1753 0 R >> endobj 1761 0 obj << /Title (, : Proxy servers) /Dest [ 1613 0 R /XYZ null null null ] /Parent 1749 0 R /Prev 1762 0 R /Next 1760 0 R >> endobj 1762 0 obj << /Title (, : Login to remote SyncML server) /Dest [ 1613 0 R /XYZ null null null ] /Parent 1749 0 R /Prev 1763 0 R /Next 1761 0 R >> endobj 1763 0 obj << /Title (: Remote SyncML server URL) /Dest [ 1613 0 R /XYZ null null null ] /Parent 1749 0 R /Prev 1764 0 R /Next 1762 0 R >> endobj 1764 0 obj << /Title (: SyncML encoding format) /Dest [ 1610 0 R /XYZ null null null ] /Parent 1749 0 R /Prev 1765 0 R /Next 1763 0 R >> endobj 1765 0 obj << /Title (: Prevent local DB login) /Dest [ 1610 0 R /XYZ null null null ] /Parent 1749 0 R /Prev 1766 0 R /Next 1764 0 R >> endobj 1766 0 obj << /Title (, : Login to local database) /Dest [ 1610 0 R /XYZ null null null ] /Parent 1749 0 R /Prev 1767 0 R /Next 1765 0 R >> endobj 1767 0 obj << /Title (: Always send Device Info at Slowsync) /Dest [ 1610 0 R /XYZ null null null ] /Parent 1749 0 R /Prev 1768 0 R /Next 1766 0 R >> endobj 1768 0 obj << /Title (: Use smart retry attempt variations) /Dest [ 1604 0 R /XYZ null null null ] /Parent 1749 0 R /Prev 1769 0 R /Next 1767 0 R >> endobj 1769 0 obj << /Title (: Use original URI for retry) /Dest [ 1604 0 R /XYZ null null null ] /Parent 1749 0 R /Prev 1770 0 R /Next 1768 0 R >> endobj 1770 0 obj << /Title (: Use a new sessionID for retries) /Dest [ 1604 0 R /XYZ null null null ] /Parent 1749 0 R /Prev 1771 0 R /Next 1769 0 R >> endobj 1771 0 obj << /Title (: Set default nonce) /Dest [ 1604 0 R /XYZ null null null ] /Parent 1749 0 R /Prev 1772 0 R /Next 1770 0 R >> endobj 1772 0 obj << /Title (: Set default auth encoding) /Dest [ 1596 0 R /XYZ null null null ] /Parent 1749 0 R /Prev 1773 0 R /Next 1771 0 R >> endobj 1773 0 obj << /Title (: Set default auth method) /Dest [ 1596 0 R /XYZ null null null ] /Parent 1749 0 R /Prev 1751 0 R /Next 1772 0 R >> endobj 1774 0 obj << /Title (, : Plugin Based Server or C\ lient Config) /Dest [ 1556 0 R /XYZ null null null ] /Parent 1741 0 R /Prev 1778 0 R /Next 1750 0 R /First 1779 0 R /Last 1780 0 R /Count 16 >> endobj 1775 0 obj << /Title (: Path for persistent storage of client settings and admin\ data) /Dest [ 1583 0 R /XYZ null null null ] /Parent 1750 0 R /Next 1777 0 R >> endobj 1776 0 obj << /Title (: enable CRC based change detection) /Dest [ 1583 0 R /XYZ null null null ] /Parent 1750 0 R /Prev 1777 0 R >> endobj 1777 0 obj << /Title (: enable binfile based admin) /Dest [ 1583 0 R /XYZ null null null ] /Parent 1750 0 R /Prev 1775 0 R /Next 1776 0 R >> endobj 1778 0 obj << /Title (, : Text File Based Server o\ r Client) /Dest [ 1552 0 R /XYZ null null null ] /Parent 1741 0 R /Prev 1795 0 R /Next 1774 0 R >> endobj 1779 0 obj << /Title (plugin module: global settings) /Dest [ 1556 0 R /XYZ null null null ] /Parent 1774 0 R /Next 1783 0 R /First 1791 0 R /Last 1792 0 R /Count 4 >> endobj 1780 0 obj << /Title (plugin module \215FILEOBJ\216) /Dest [ 1579 0 R /XYZ null null null ] /Parent 1774 0 R /Prev 1781 0 R /First 1782 0 R /Last 1782 0 R /Count 1 >> endobj 1781 0 obj << /Title (plugin module \215SDK_textdb\216) /Dest [ 1574 0 R /XYZ null null null ] /Parent 1774 0 R /Prev 1783 0 R /Next 1780 0 R /First 1784 0 R /Last 1785 0 R /Count 2 >> endobj 1782 0 obj << /Title (Files of the fileobj modules) /Dest [ 1579 0 R /XYZ null null null ] /Parent 1780 0 R >> endobj 1783 0 obj << /Title (: Plugin Datastore specific settings) /Dest [ 1562 0 R /XYZ null null null ] /Parent 1774 0 R /Prev 1779 0 R /Next 1781 0 R /First 1786 0 R /Last 1787 0 R /Count 5 >> endobj 1784 0 obj << /Title (Files of the textdb) /Dest [ 1574 0 R /XYZ null null null ] /Parent 1781 0 R /Next 1785 0 R >> endobj 1785 0 obj << /Title (PluginParams of the textdb) /Dest [ 1574 0 R /XYZ null null null ] /Parent 1781 0 R /Prev 1784 0 R >> endobj 1786 0 obj << /Title () /Dest [ 1562 0 R /XYZ null null null ] /Parent 1783 0 R /Next 1790 0 R >> endobj 1787 0 obj << /Title (,,\t> endobj 1788 0 obj << /Title () /Dest [ 1567 0 R /XYZ null null null ] /Parent 1783 0 R /Prev 1789 0 R /Next 1787 0 R >> endobj 1789 0 obj << /Title () /Dest [ 1567 0 R /XYZ null null null ] /Parent 1783 0 R /Prev 1790 0 R /Next 1788 0 R >> endobj 1790 0 obj << /Title () /Dest [ 1567 0 R /XYZ null null null ] /Parent 1783 0 R /Prev 1786 0 R /Next 1789 0 R >> endobj 1791 0 obj << /Title () /Dest [ 1556 0 R /XYZ null null null ] /Parent 1779 0 R /Next 1794 0 R >> endobj 1792 0 obj << /Title () /Dest [ 1562 0 R /XYZ null null null ] /Parent 1779 0 R /Prev 1793 0 R >> endobj 1793 0 obj << /Title () /Dest [ 1562 0 R /XYZ null null null ] /Parent 1779 0 R /Prev 1794 0 R /Next 1792 0 R >> endobj 1794 0 obj << /Title () /Dest [ 1562 0 R /XYZ null null null ] /Parent 1779 0 R /Prev 1791 0 R /Next 1793 0 R >> endobj 1795 0 obj << /Title (, : SQL/ODBC based S\ erver or Client Config) /Dest [ 1297 0 R /XYZ null null null ] /Parent 1741 0 R /Prev 1796 0 R /Next 1778 0 R /First 1797 0 R /Last 1798 0 R /Count 49 >> endobj 1796 0 obj << /Title (, : General Server and Client Settings) /Dest [ 931 0 R /XYZ null null null ] /Parent 1741 0 R /Prev 1846 0 R /Next 1795 0 R /First 1847 0 R /Last 1848 0 R /Count 111 >> endobj 1797 0 obj << /Title (SQL Statement processing) /Dest [ 1297 0 R /XYZ null null null ] /Parent 1795 0 R /Next 1841 0 R /First 1842 0 R /Last 1843 0 R /Count 4 >> endobj 1798 0 obj << /Title (: SQL and ODBC Datastore specific settings) /Dest [ 1400 0 R /XYZ null null null ] /Parent 1795 0 R /Prev 1799 0 R /First 1800 0 R /Last 1801 0 R /Count 25 >> endobj 1799 0 obj << /Title (: SQL statement to write activity log entry) /Dest [ 1393 0 R /XYZ null null null ] /Parent 1795 0 R /Prev 1825 0 R /Next 1798 0 R >> endobj 1800 0 obj << /Title (: get data subselection key) /Dest [ 1400 0 R /XYZ null null null ] /Parent 1798 0 R /Next 1824 0 R >> endobj 1801 0 obj << /Title (: prepare SQL filter according to options) /Dest [ 1546 0 R /XYZ null null null ] /Parent 1798 0 R /Prev 1802 0 R >> endobj 1802 0 obj << /Title (: clean detail records on insert) /Dest [ 1546 0 R /XYZ null null null ] /Parent 1798 0 R /Prev 1803 0 R /Next 1801 0 R >> endobj 1803 0 obj << /Title (, , : detail record SQ\ L) /Dest [ 1546 0 R /XYZ null null null ] /Parent 1798 0 R /Prev 1804 0 R /Next 1802 0 R >> endobj 1804 0 obj << /Title (: detail record storage filter) /Dest [ 1539 0 R /XYZ null null null ] /Parent 1798 0 R /Prev 1805 0 R /Next 1803 0 R >> endobj 1805 0 obj << /Title (, , : detail record storage options) /Dest [ 1539 0 R /XYZ null null null ] /Parent 1798 0 R /Prev 1806 0 R /Next 1804 0 R >> endobj 1806 0 obj << /Title (: definition of master - detail record structures) /Dest [ 1513 0 R /XYZ null null null ] /Parent 1798 0 R /Prev 1807 0 R /Next 1805 0 R >> endobj 1807 0 obj << /Title (: SQL specific field mapping features) /Dest [ 1505 0 R /XYZ null null null ] /Parent 1798 0 R /Prev 1808 0 R /Next 1806 0 R >> endobj 1808 0 obj << /Title (, , , , , , : local object ID \ management) /Dest [ 1495 0 R /XYZ null null null ] /Parent 1798 0 R /Prev 1809 0 R /Next 1807 0 R >> endobj 1809 0 obj << /Title (: Ignore SQLRowCount) /Dest [ 1485 0 R /XYZ null null null ] /Parent 1798 0 R /Prev 1810 0 R /Next 1808 0 R >> endobj 1810 0 obj << /Title (, , , : write r\ ecords to database) /Dest [ 1485 0 R /XYZ null null null ] /Parent 1798 0 R /Prev 1811 0 R /Next 1809 0 R >> endobj 1811 0 obj << /Title (: read record from database) /Dest [ 1476 0 R /XYZ null null null ] /Parent 1798 0 R /Prev 1812 0 R /Next 1810 0 R >> endobj 1812 0 obj << /Title (: read IDs and timestamps) /Dest [ 1476 0 R /XYZ null null null ] /Parent 1798 0 R /Prev 1813 0 R /Next 1811 0 R >> endobj 1813 0 obj << /Title (: combined date and time for modification timestamp) /Dest [ 1472 0 R /XYZ null null null ] /Parent 1798 0 R /Prev 1814 0 R /Next 1812 0 R >> endobj 1814 0 obj << /Title (: commit each item update) /Dest [ 1472 0 R /XYZ null null null ] /Parent 1798 0 R /Prev 1815 0 R /Next 1813 0 R >> endobj 1815 0 obj << /Title (: no longer supported in version 3.0) /Dest [ 1472 0 R /XYZ null null null ] /Parent 1798 0 R /Prev 1816 0 R /Next 1814 0 R >> endobj 1816 0 obj << /Title (: commit at end of SyncML message exchange) /Dest [ 1472 0 R /XYZ null null null ] /Parent 1798 0 R /Prev 1817 0 R /Next 1815 0 R >> endobj 1817 0 obj << /Title (: use filtering in WHERE clause) /Dest [ 1466 0 R /XYZ null null null ] /Parent 1798 0 R /Prev 1818 0 R /Next 1816 0 R >> endobj 1818 0 obj << /Title (: how ODBC strings must be escaped for the database) /Dest [ 1466 0 R /XYZ null null null ] /Parent 1798 0 R /Prev 1819 0 R /Next 1817 0 R >> endobj 1819 0 obj << /Title (: SQLite database file name) /Dest [ 1466 0 R /XYZ null null null ] /Parent 1798 0 R /Prev 1820 0 R /Next 1818 0 R >> endobj 1820 0 obj << /Title (: SQLite database file name) /Dest [ 1458 0 R /XYZ null null null ] /Parent 1798 0 R /Prev 1821 0 R /Next 1819 0 R >> endobj 1821 0 obj << /Title (, , , : Map t\ able management) /Dest [ 1446 0 R /XYZ null null null ] /Parent 1798 0 R /Prev 1822 0 R /Next 1820 0 R >> endobj 1822 0 obj << /Title (: modified time stamp type) /Dest [ 1446 0 R /XYZ null null null ] /Parent 1798 0 R /Prev 1823 0 R /Next 1821 0 R >> endobj 1823 0 obj << /Title (: format for timestamps in target table) /Dest [ 1446 0 R /XYZ null null null ] /Parent 1798 0 R /Prev 1824 0 R /Next 1822 0 R >> endobj 1824 0 obj << /Title (, , , : Sync target management) /Dest [ 1411 0 R /XYZ null null null ] /Parent 1798 0 R /Prev 1800 0 R /Next 1823 0 R >> endobj 1825 0 obj << /Title (: query for getting database time) /Dest [ 1393 0 R /XYZ null null null ] /Parent 1795 0 R /Prev 1826 0 R /Next 1799 0 R >> endobj 1826 0 obj << /Title (: custom login checking script) /Dest [ 1385 0 R /XYZ null null null ] /Parent 1795 0 R /Prev 1827 0 R /Next 1825 0 R >> endobj 1827 0 obj << /Title (: query for user authentication) /Dest [ 1379 0 R /XYZ null null null ] /Parent 1795 0 R /Prev 1828 0 R /Next 1826 0 R >> endobj 1828 0 obj << /Title (, , , : Device ma\ nagement) /Dest [ 1371 0 R /XYZ null null null ] /Parent 1795 0 R /Prev 1829 0 R /Next 1827 0 R >> endobj 1829 0 obj << /Title (: MD5 digest stored as hex string in database) /Dest [ 1365 0 R /XYZ null null null ] /Parent 1795 0 R /Prev 1830 0 R /Next 1828 0 R >> endobj 1830 0 obj << /Title (: MD5 digest passwort in database) /Dest [ 1365 0 R /XYZ null null null ] /Parent 1795 0 R /Prev 1831 0 R /Next 1829 0 R >> endobj 1831 0 obj << /Title (: plain text password in database) /Dest [ 1365 0 R /XYZ null null null ] /Parent 1795 0 R /Prev 1832 0 R /Next 1830 0 R >> endobj 1832 0 obj << /Title (, , : outdated - no longer available) /Dest [ 1357 0 R /XYZ null null null ] /Parent 1795 0 R /Prev 1833 0 R /Next 1831 0 R >> endobj 1833 0 obj << /Title (: usage of ODBC cursor library) /Dest [ 1357 0 R /XYZ null null null ] /Parent 1795 0 R /Prev 1834 0 R /Next 1832 0 R >> endobj 1834 0 obj << /Title (: Transaction isolation mode) /Dest [ 1357 0 R /XYZ null null null ] /Parent 1795 0 R /Prev 1835 0 R /Next 1833 0 R >> endobj 1835 0 obj << /Title (: Script executed whenever new DB connection is open\ ed.) /Dest [ 1352 0 R /XYZ null null null ] /Parent 1795 0 R /Prev 1836 0 R /Next 1834 0 R >> endobj 1836 0 obj << /Title (: ODBC timeout) /Dest [ 1352 0 R /XYZ null null null ] /Parent 1795 0 R /Prev 1837 0 R /Next 1835 0 R >> endobj 1837 0 obj << /Title (: prevent setting connection attributes) /Dest [ 1352 0 R /XYZ null null null ] /Parent 1795 0 R /Prev 1838 0 R /Next 1836 0 R >> endobj 1838 0 obj << /Title (: ODBC database password) /Dest [ 1352 0 R /XYZ null null null ] /Parent 1795 0 R /Prev 1839 0 R /Next 1837 0 R >> endobj 1839 0 obj << /Title (: ODBC database connection string) /Dest [ 1347 0 R /XYZ null null null ] /Parent 1795 0 R /Prev 1840 0 R /Next 1838 0 R >> endobj 1840 0 obj << /Title (: ODBC database user name) /Dest [ 1347 0 R /XYZ null null null ] /Parent 1795 0 R /Prev 1841 0 R /Next 1839 0 R >> endobj 1841 0 obj << /Title (: ODBC data source name) /Dest [ 1340 0 R /XYZ null null null ] /Parent 1795 0 R /Prev 1797 0 R /Next 1840 0 R >> endobj 1842 0 obj << /Title (Placeholders for all SQL statements) /Dest [ 1305 0 R /XYZ null null null ] /Parent 1797 0 R /Next 1845 0 R >> endobj 1843 0 obj << /Title (Executing SQL statements from scripts) /Dest [ 1330 0 R /XYZ null null null ] /Parent 1797 0 R /Prev 1844 0 R >> endobj 1844 0 obj << /Title (Placeholders for SQL data access statements within ) /Dest [ 1323 0 R /XYZ null null null ] /Parent 1797 0 R /Prev 1845 0 R /Next 1843 0 R >> endobj 1845 0 obj << /Title (Placeholders for SQL statements within ) /Dest [ 1305 0 R /XYZ null null null ] /Parent 1797 0 R /Prev 1842 0 R /Next 1844 0 R >> endobj 1846 0 obj << /Title (: Data Type Definitions) /Dest [ 775 0 R /XYZ null null null ] /Parent 1741 0 R /Prev 1958 0 R /Next 1796 0 R /First 1959 0 R /Last 1960 0 R /Count 36 >> endobj 1847 0 obj << /Title (,: SyncML version support) /Dest [ 931 0 R /XYZ null null null ] /Parent 1796 0 R /Next 1957 0 R >> endobj 1848 0 obj << /Title (: special rules for specific remotes) /Dest [ 1254 0 R /XYZ null null null ] /Parent 1796 0 R /Prev 1849 0 R /First 1850 0 R /Last 1851 0 R /Count 24 >> endobj 1849 0 obj << /Title (: combined datastore definition) /Dest [ 1241 0 R /XYZ null null null ] /Parent 1796 0 R /Prev 1874 0 R /Next 1848 0 R /First 1875 0 R /Last 1876 0 R /Count 3 >> endobj 1850 0 obj << /Title () /Dest [ 1254 0 R /XYZ null null null ] /Parent 1848 0 R /Next 1873 0 R >> endobj 1851 0 obj << /Title (: script to execute if rule applies) /Dest [ 1291 0 R /XYZ null null null ] /Parent 1848 0 R /Prev 1852 0 R >> endobj 1852 0 obj << /Title (: max time for request processing) /Dest [ 1291 0 R /XYZ null null null ] /Parent 1848 0 R /Prev 1853 0 R /Next 1851 0 R >> endobj 1853 0 obj << /Title (: reject sync with device) /Dest [ 1291 0 R /XYZ null null null ] /Parent 1848 0 R /Prev 1854 0 R /Next 1852 0 R >> endobj 1854 0 obj << /Title (, : use relaxed conformance modes) /Dest [ 1283 0 R /XYZ null null null ] /Parent 1848 0 R /Prev 1855 0 R /Next 1853 0 R >> endobj 1855 0 obj << /Title (: set default input character set) /Dest [ 1283 0 R /XYZ null null null ] /Parent 1848 0 R /Prev 1856 0 R /Next 1854 0 R >> endobj 1856 0 obj << /Title (: set default output character set) /Dest [ 1283 0 R /XYZ null null null ] /Parent 1848 0 R /Prev 1857 0 R /Next 1855 0 R >> endobj 1857 0 obj << /Title (: end date for allday events inclusive) /Dest [ 1283 0 R /XYZ null null null ] /Parent 1848 0 R /Prev 1858 0 R /Next 1856 0 R >> endobj 1858 0 obj << /Title (: prevent folding long lines) /Dest [ 1277 0 R /XYZ null null null ] /Parent 1848 0 R /Prev 1859 0 R /Next 1857 0 R >> endobj 1859 0 obj << /Title (: always treat received information as UTC) /Dest [ 1277 0 R /XYZ null null null ] /Parent 1848 0 R /Prev 1860 0 R /Next 1858 0 R >> endobj 1860 0 obj << /Title (: always treat received information as localtime) /Dest [ 1277 0 R /XYZ null null null ] /Parent 1848 0 R /Prev 1861 0 R /Next 1859 0 R >> endobj 1861 0 obj << /Title (: always send time information as localtime) /Dest [ 1277 0 R /XYZ null null null ] /Parent 1848 0 R /Prev 1862 0 R /Next 1860 0 R >> endobj 1862 0 obj << /Title (: always send time information as localtime) /Dest [ 1273 0 R /XYZ null null null ] /Parent 1848 0 R /Prev 1863 0 R /Next 1861 0 R >> endobj 1863 0 obj << /Title (: allow client to send the same message twice) /Dest [ 1273 0 R /XYZ null null null ] /Parent 1848 0 R /Prev 1864 0 R /Next 1862 0 R >> endobj 1864 0 obj << /Title (: allow client to send the same message twice) /Dest [ 1273 0 R /XYZ null null null ] /Parent 1848 0 R /Prev 1865 0 R /Next 1863 0 R >> endobj 1865 0 obj << /Title (, : how to show datastore name in devInf \ sent to client.) /Dest [ 1269 0 R /XYZ null null null ] /Parent 1848 0 R /Prev 1866 0 R /Next 1864 0 R >> endobj 1866 0 obj << /Title (: ignore maximum field size reported in client's de\ vInf) /Dest [ 1269 0 R /XYZ null null null ] /Parent 1848 0 R /Prev 1867 0 R /Next 1865 0 R >> endobj 1867 0 obj << /Title (: never update client records during slowsync) /Dest [ 1269 0 R /XYZ null null null ] /Parent 1848 0 R /Prev 1868 0 R /Next 1866 0 R >> endobj 1868 0 obj << /Title (: update server records during slowsync) /Dest [ 1264 0 R /XYZ null null null ] /Parent 1848 0 R /Prev 1869 0 R /Next 1867 0 R >> endobj 1869 0 obj << /Title (: update client records during slowsync) /Dest [ 1264 0 R /XYZ null null null ] /Parent 1848 0 R /Prev 1870 0 R /Next 1868 0 R >> endobj 1870 0 obj << /Title (: do not send empty properties) /Dest [ 1264 0 R /XYZ null null null ] /Parent 1848 0 R /Prev 1871 0 R /Next 1869 0 R >> endobj 1871 0 obj << /Title (: device has short fields) /Dest [ 1259 0 R /XYZ null null null ] /Parent 1848 0 R /Prev 1872 0 R /Next 1870 0 R >> endobj 1872 0 obj << /Title () /Dest [ 1259 0 R /XYZ null null null ] /Parent 1848 0 R /Prev 1873 0 R /Next 1871 0 R >> endobj 1873 0 obj << /Title (device identification tags for ) /Dest [ 1254 0 R /XYZ null null null ] /Parent 1848 0 R /Prev 1850 0 R /Next 1872 0 R >> endobj 1874 0 obj << /Title (: General Datastore settings) /Dest [ 1016 0 R /XYZ null null null ] /Parent 1796 0 R /Prev 1878 0 R /Next 1849 0 R /First 1879 0 R /Last 1880 0 R /Count 48 >> endobj 1875 0 obj << /Title (: Include a datastore in a superdatastore) /Dest [ 1249 0 R /XYZ null null null ] /Parent 1849 0 R /Next 1877 0 R >> endobj 1876 0 obj << /Title (: prefix for item ID) /Dest [ 1249 0 R /XYZ null null null ] /Parent 1849 0 R /Prev 1877 0 R >> endobj 1877 0 obj << /Title (: filter to direct incoming items) /Dest [ 1249 0 R /XYZ null null null ] /Parent 1849 0 R /Prev 1875 0 R /Next 1876 0 R >> endobj 1878 0 obj << /Title (, : Pre- and post-login scripts) /Dest [ 1008 0 R /XYZ null null null ] /Parent 1796 0 R /Prev 1927 0 R /Next 1874 0 R >> endobj 1879 0 obj << /Title (: alternate name for this datastore) /Dest [ 1026 0 R /XYZ null null null ] /Parent 1874 0 R /Next 1926 0 R >> endobj 1880 0 obj << /Title (: mapping datatype's fields to database fields) /Dest [ 1174 0 R /XYZ null null null ] /Parent 1874 0 R /Prev 1881 0 R /First 1882 0 R /Last 1883 0 R /Count 7 >> endobj 1881 0 obj << /Title (: support for resuming half-transmitted data items af\ ter interrupted sync) /Dest [ 1168 0 R /XYZ null null null ] /Parent 1874 0 R /Prev 1889 0 R /Next 1880 0 R >> endobj 1882 0 obj << /Title (, : mapping a datatype field to a database field) /Dest [ 1174 0 R /XYZ null null null ] /Parent 1880 0 R /Next 1888 0 R >> endobj 1883 0 obj << /Title (: finish access to database) /Dest [ 1241 0 R /XYZ null null null ] /Parent 1880 0 R /Prev 1884 0 R >> endobj 1884 0 obj << /Title (: finalize written items) /Dest [ 1233 0 R /XYZ null null null ] /Parent 1880 0 R /Prev 1885 0 R /Next 1883 0 R >> endobj 1885 0 obj << /Title (: prepare writing item to database) /Dest [ 1225 0 R /XYZ null null null ] /Parent 1880 0 R /Prev 1886 0 R /Next 1884 0 R >> endobj 1886 0 obj << /Title (: post-process item read from database) /Dest [ 1212 0 R /XYZ null null null ] /Parent 1880 0 R /Prev 1887 0 R /Next 1885 0 R >> endobj 1887 0 obj << /Title (: initialize accessing database) /Dest [ 1204 0 R /XYZ null null null ] /Parent 1880 0 R /Prev 1888 0 R /Next 1886 0 R >> endobj 1888 0 obj << /Title (: auto-map internal to DB fields) /Dest [ 1204 0 R /XYZ null null null ] /Parent 1880 0 R /Prev 1882 0 R /Next 1887 0 R >> endobj 1889 0 obj << /Title (: support for resuming interrupted sync session) /Dest [ 1168 0 R /XYZ null null null ] /Parent 1874 0 R /Prev 1890 0 R /Next 1881 0 R >> endobj 1890 0 obj << /Title ( \(or \): custom "time of\ last sync" identifier) /Dest [ 1168 0 R /XYZ null null null ] /Parent 1874 0 R /Prev 1891 0 R /Next 1889 0 R >> endobj 1891 0 obj << /Title (: How to determine "time of last sync") /Dest [ 1163 0 R /XYZ null null null ] /Parent 1874 0 R /Prev 1892 0 R /Next 1890 0 R >> endobj 1892 0 obj << /Title (: Support for "one-way from remote sync") /Dest [ 1163 0 R /XYZ null null null ] /Parent 1874 0 R /Prev 1893 0 R /Next 1891 0 R >> endobj 1893 0 obj << /Title (: always update all fields) /Dest [ 1163 0 R /XYZ null null null ] /Parent 1874 0 R /Prev 1894 0 R /Next 1892 0 R >> endobj 1894 0 obj << /Title (: encoding of line ends within database strings) /Dest [ 1159 0 R /XYZ null null null ] /Parent 1874 0 R /Prev 1895 0 R /Next 1893 0 R >> endobj 1895 0 obj << /Title (: character set to be used for database strings) /Dest [ 1159 0 R /XYZ null null null ] /Parent 1874 0 R /Prev 1896 0 R /Next 1894 0 R >> endobj 1896 0 obj << /Title (: output data in user zone) /Dest [ 1150 0 R /XYZ null null null ] /Parent 1874 0 R /Prev 1897 0 R /Next 1895 0 R >> endobj 1897 0 obj << /Title (: timezone for database timestamps) /Dest [ 1150 0 R /XYZ null null null ] /Parent 1874 0 R /Prev 1898 0 R /Next 1896 0 R >> endobj 1898 0 obj << /Title (, : type of database timestamp) /Dest [ 1150 0 R /XYZ null null null ] /Parent 1874 0 R /Prev 1899 0 R /Next 1897 0 R >> endobj 1899 0 obj << /Title (: re-send failing items in next session) /Dest [ 1144 0 R /XYZ null null null ] /Parent 1874 0 R /Prev 1900 0 R /Next 1898 0 R >> endobj 1900 0 obj << /Title (: script to handle status codes for received i\ tems) /Dest [ 1144 0 R /XYZ null null null ] /Parent 1874 0 R /Prev 1901 0 R /Next 1899 0 R >> endobj 1901 0 obj << /Title (: script to handle status codes for sent items) /Dest [ 1135 0 R /XYZ null null null ] /Parent 1874 0 R /Prev 1902 0 R /Next 1900 0 R >> endobj 1902 0 obj << /Title (: script called before sending sync alert) /Dest [ 1135 0 R /XYZ null null null ] /Parent 1874 0 R /Prev 1903 0 R /Next 1901 0 R >> endobj 1903 0 obj << /Title (: script called at sync alert) /Dest [ 1126 0 R /XYZ null null null ] /Parent 1874 0 R /Prev 1904 0 R /Next 1902 0 R >> endobj 1904 0 obj << /Title (: script executed at end of sync) /Dest [ 1126 0 R /XYZ null null null ] /Parent 1874 0 R /Prev 1905 0 R /Next 1903 0 R >> endobj 1905 0 obj << /Title (: script called when admin data \(targets, maps\) are \ read) /Dest [ 1126 0 R /XYZ null null null ] /Parent 1874 0 R /Prev 1906 0 R /Next 1904 0 R >> endobj 1906 0 obj << /Title (: script called after accessing database) /Dest [ 1117 0 R /XYZ null null null ] /Parent 1874 0 R /Prev 1907 0 R /Next 1905 0 R >> endobj 1907 0 obj << /Title (: script called before accessing database) /Dest [ 1074 0 R /XYZ null null null ] /Parent 1874 0 R /Prev 1908 0 R /Next 1906 0 R >> endobj 1908 0 obj << /Title (: make incoming items pass) /Dest [ 1074 0 R /XYZ null null null ] /Parent 1874 0 R /Prev 1909 0 R /Next 1907 0 R >> endobj 1909 0 obj << /Title (: make item visible) /Dest [ 1074 0 R /XYZ null null null ] /Parent 1874 0 R /Prev 1910 0 R /Next 1908 0 R >> endobj 1910 0 obj << /Title (: filter invisible items) /Dest [ 1066 0 R /XYZ null null null ] /Parent 1874 0 R /Prev 1911 0 R /Next 1909 0 R >> endobj 1911 0 obj << /Title (: filter subset of datastore) /Dest [ 1066 0 R /XYZ null null null ] /Parent 1874 0 R /Prev 1912 0 R /Next 1910 0 R >> endobj 1912 0 obj << /Title (: discard not accepted items silently) /Dest [ 1066 0 R /XYZ null null null ] /Parent 1874 0 R /Prev 1913 0 R /Next 1911 0 R >> endobj 1913 0 obj << /Title (: check incoming items) /Dest [ 1054 0 R /XYZ null null null ] /Parent 1874 0 R /Prev 1914 0 R /Next 1912 0 R >> endobj 1914 0 obj << /Title (: enable date range filtering) /Dest [ 1054 0 R /XYZ null null null ] /Parent 1874 0 R /Prev 1915 0 R /Next 1913 0 R >> endobj 1915 0 obj << /Title (: enable SyncML DS 1.2 filtering) /Dest [ 1054 0 R /XYZ null null null ] /Parent 1874 0 R /Prev 1916 0 R /Next 1914 0 R >> endobj 1916 0 obj << /Title (: use a datatype) /Dest [ 1046 0 R /XYZ null null null ] /Parent 1874 0 R /Prev 1917 0 R /Next 1915 0 R >> endobj 1917 0 obj << /Title (: datastore's supported types) /Dest [ 1046 0 R /XYZ null null null ] /Parent 1874 0 R /Prev 1918 0 R /Next 1916 0 R >> endobj 1918 0 obj << /Title (, , : sync confli\ ct resolution strategy) /Dest [ 1042 0 R /XYZ null null null ] /Parent 1874 0 R /Prev 1919 0 R /Next 1917 0 R >> endobj 1919 0 obj << /Title (: send localID \(GUID\) in all operations \(not only \ adds\).) /Dest [ 1042 0 R /XYZ null null null ] /Parent 1874 0 R /Prev 1920 0 R /Next 1918 0 R >> endobj 1920 0 obj << /Title (: maximum number of data items per SyncML message) /Dest [ 1038 0 R /XYZ null null null ] /Parent 1874 0 R /Prev 1921 0 R /Next 1919 0 R >> endobj 1921 0 obj << /Title (: transmit updates to remote) /Dest [ 1038 0 R /XYZ null null null ] /Parent 1874 0 R /Prev 1922 0 R /Next 1920 0 R >> endobj 1922 0 obj << /Title (: try to update "deleted" items) /Dest [ 1038 0 R /XYZ null null null ] /Parent 1874 0 R /Prev 1923 0 R /Next 1921 0 R >> endobj 1923 0 obj << /Title (: delete overrides replace) /Dest [ 1032 0 R /XYZ null null null ] /Parent 1874 0 R /Prev 1924 0 R /Next 1922 0 R >> endobj 1924 0 obj << /Title (: read-only datastore) /Dest [ 1032 0 R /XYZ null null null ] /Parent 1874 0 R /Prev 1925 0 R /Next 1923 0 R >> endobj 1925 0 obj << /Title (: decriptive name for a datastore) /Dest [ 1032 0 R /XYZ null null null ] /Parent 1874 0 R /Prev 1926 0 R /Next 1924 0 R >> endobj 1926 0 obj << /Title (: datastore type ID) /Dest [ 1026 0 R /XYZ null null null ] /Parent 1874 0 R /Prev 1879 0 R /Next 1925 0 R >> endobj 1927 0 obj << /Title (: Activity log header) /Dest [ 1008 0 R /XYZ null null null ] /Parent 1796 0 R /Prev 1928 0 R /Next 1878 0 R >> endobj 1928 0 obj << /Title (: Activity log format) /Dest [ 991 0 R /XYZ null null null ] /Parent 1796 0 R /Prev 1929 0 R /Next 1927 0 R >> endobj 1929 0 obj << /Title (: Activity log enable) /Dest [ 991 0 R /XYZ null null null ] /Parent 1796 0 R /Prev 1930 0 R /Next 1928 0 R >> endobj 1930 0 obj << /Title (: Activity log text file) /Dest [ 986 0 R /XYZ null null null ] /Parent 1796 0 R /Prev 1931 0 R /Next 1929 0 R >> endobj 1931 0 obj << /Title (: Acceptance of server alerted sync types) /Dest [ 986 0 R /XYZ null null null ] /Parent 1796 0 R /Prev 1932 0 R /Next 1930 0 R >> endobj 1932 0 obj << /Title (: enumerate default property parameter's values a\ s property names) /Dest [ 986 0 R /XYZ null null null ] /Parent 1796 0 R /Prev 1933 0 R /Next 1931 0 R >> endobj 1933 0 obj << /Title (: show size and type in SyncML 1.0 devInf) /Dest [ 979 0 R /XYZ null null null ] /Parent 1796 0 R /Prev 1934 0 R /Next 1932 0 R >> endobj 1934 0 obj << /Title (: show field support details in device information) /Dest [ 979 0 R /XYZ null null null ] /Parent 1796 0 R /Prev 1935 0 R /Next 1933 0 R >> endobj 1935 0 obj << /Title (: error handling option) /Dest [ 979 0 R /XYZ null null null ] /Parent 1796 0 R /Prev 1936 0 R /Next 1934 0 R >> endobj 1936 0 obj << /Title (: end date for allday events inclusive) /Dest [ 974 0 R /XYZ null null null ] /Parent 1796 0 R /Prev 1937 0 R /Next 1935 0 R >> endobj 1937 0 obj << /Title (: Set user's default time zone) /Dest [ 974 0 R /XYZ null null null ] /Parent 1796 0 R /Prev 1938 0 R /Next 1936 0 R >> endobj 1938 0 obj << /Title (: Handling of delete for non-existing items) /Dest [ 974 0 R /XYZ null null null ] /Parent 1796 0 R /Prev 1939 0 R /Next 1937 0 R >> endobj 1939 0 obj << /Title (: LargeObject chunk size limit for testing) /Dest [ 974 0 R /XYZ null null null ] /Parent 1796 0 R /Prev 1940 0 R /Next 1938 0 R >> endobj 1940 0 obj << /Title (: Add resending policy) /Dest [ 970 0 R /XYZ null null null ] /Parent 1796 0 R /Prev 1941 0 R /Next 1939 0 R >> endobj 1941 0 obj << /Title (: SyncML command flow option) /Dest [ 970 0 R /XYZ null null null ] /Parent 1796 0 R /Prev 1942 0 R /Next 1940 0 R >> endobj 1942 0 obj << /Title (: Custom handling of SyncML Put/Result com\ mands) /Dest [ 970 0 R /XYZ null null null ] /Parent 1796 0 R /Prev 1943 0 R /Next 1941 0 R >> endobj 1943 0 obj << /Title (: Custom handling of SyncML Get commands) /Dest [ 966 0 R /XYZ null null null ] /Parent 1796 0 R /Prev 1944 0 R /Next 1942 0 R >> endobj 1944 0 obj << /Title (, : Creation of custom SyncML Ge\ t and Put commands) /Dest [ 961 0 R /XYZ null null null ] /Parent 1796 0 R /Prev 1945 0 R /Next 1943 0 R >> endobj 1945 0 obj << /Title (, : Session level status\ code handling) /Dest [ 961 0 R /XYZ null null null ] /Parent 1796 0 R /Prev 1946 0 R /Next 1944 0 R >> endobj 1946 0 obj << /Title (: Session finish script) /Dest [ 961 0 R /XYZ null null null ] /Parent 1796 0 R /Prev 1947 0 R /Next 1945 0 R >> endobj 1947 0 obj << /Title (: Session init script) /Dest [ 956 0 R /XYZ null null null ] /Parent 1796 0 R /Prev 1948 0 R /Next 1946 0 R >> endobj 1948 0 obj << /Title (: Allow multi-threaded execution) /Dest [ 956 0 R /XYZ null null null ] /Parent 1796 0 R /Prev 1949 0 R /Next 1947 0 R >> endobj 1949 0 obj << /Title (, : single user mode) /Dest [ 956 0 R /XYZ null null null ] /Parent 1796 0 R /Prev 1950 0 R /Next 1948 0 R >> endobj 1950 0 obj << /Title (, : RespURI configuration) /Dest [ 952 0 R /XYZ null null null ] /Parent 1796 0 R /Prev 1951 0 R /Next 1949 0 R >> endobj 1951 0 obj << /Title (: constant nonce string) /Dest [ 952 0 R /XYZ null null null ] /Parent 1796 0 R /Prev 1952 0 R /Next 1950 0 R >> endobj 1952 0 obj << /Title (: MD5 nonce generation mode) /Dest [ 952 0 R /XYZ null null null ] /Parent 1796 0 R /Prev 1953 0 R /Next 1951 0 R >> endobj 1953 0 obj << /Title (,: SyncML Authentication) /Dest [ 948 0 R /XYZ null null null ] /Parent 1796 0 R /Prev 1954 0 R /Next 1952 0 R >> endobj 1954 0 obj << /Title (: specify URL used to access the server) /Dest [ 948 0 R /XYZ null null null ] /Parent 1796 0 R /Prev 1955 0 R /Next 1953 0 R >> endobj 1955 0 obj << /Title (: artifical slow down) /Dest [ 943 0 R /XYZ null null null ] /Parent 1796 0 R /Prev 1956 0 R /Next 1954 0 R >> endobj 1956 0 obj << /Title (: max time for request processing) /Dest [ 943 0 R /XYZ null null null ] /Parent 1796 0 R /Prev 1957 0 R /Next 1955 0 R >> endobj 1957 0 obj << /Title (: Timeout for unfinished sessions) /Dest [ 943 0 R /XYZ null null null ] /Parent 1796 0 R /Prev 1847 0 R /Next 1956 0 R >> endobj 1958 0 obj << /Title (: Transport Configuration Section) /Dest [ 763 0 R /XYZ null null null ] /Parent 1741 0 R /Prev 1995 0 R /Next 1846 0 R /First 1996 0 R /Last 1997 0 R /Count 8 >> endobj 1959 0 obj << /Title (: internal data field list) /Dest [ 779 0 R /XYZ null null null ] /Parent 1846 0 R /Next 1985 0 R >> endobj 1960 0 obj << /Title (RRULE field block) /Dest [ 927 0 R /XYZ null null null ] /Parent 1846 0 R /Prev 1961 0 R >> endobj 1961 0 obj << /Title (: definition of a datatype) /Dest [ 874 0 R /XYZ null null null ] /Parent 1846 0 R /Prev 1962 0 R /Next 1960 0 R /First 1963 0 R /Last 1964 0 R /Count 14 >> endobj 1962 0 obj << /Title (: definition of a text format profile) /Dest [ 858 0 R /XYZ null null null ] /Parent 1846 0 R /Prev 1977 0 R /Next 1961 0 R /First 1978 0 R /Last 1979 0 R /Count 7 >> endobj 1963 0 obj << /Title (: MIME-DIR profile, text profile or field list to use for datatype) /Dest [ 874 0 R /XYZ null null null ] /Parent 1961 0 R /Next 1976 0 R >> endobj 1964 0 obj << /Title (: MIME-DIR conformance) /Dest [ 922 0 R /XYZ null null null ] /Parent 1961 0 R /Prev 1965 0 R >> endobj 1965 0 obj << /Title (: Custom item merge) /Dest [ 922 0 R /XYZ null null null ] /Parent 1961 0 R /Prev 1966 0 R /Next 1964 0 R >> endobj 1966 0 obj << /Title (: Custom item comparison) /Dest [ 917 0 R /XYZ null null null ] /Parent 1961 0 R /Prev 1967 0 R /Next 1965 0 R >> endobj 1967 0 obj << /Title (: Custom processing for incoming items) /Dest [ 910 0 R /XYZ null null null ] /Parent 1961 0 R /Prev 1968 0 R /Next 1966 0 R >> endobj 1968 0 obj << /Title (, : Script-based data filtering) /Dest [ 898 0 R /XYZ null null null ] /Parent 1961 0 R /Prev 1969 0 R /Next 1967 0 R >> endobj 1969 0 obj << /Title (, : Custom pre- and postprocessing items\ ) /Dest [ 898 0 R /XYZ null null null ] /Parent 1961 0 R /Prev 1970 0 R /Next 1968 0 R >> endobj 1970 0 obj << /Title (: Initialisation of type-specific script context) /Dest [ 890 0 R /XYZ null null null ] /Parent 1961 0 R /Prev 1971 0 R /Next 1969 0 R >> endobj 1971 0 obj << /Title (, : Unicode content) /Dest [ 890 0 R /XYZ null null null ] /Parent 1961 0 R /Prev 1972 0 R /Next 1970 0 R >> endobj 1972 0 obj << /Title (: Allow unencoded binary in content) /Dest [ 885 0 R /XYZ null null null ] /Parent 1961 0 R /Prev 1973 0 R /Next 1971 0 R >> endobj 1973 0 obj << /Title (: Compression level for compression\ ) /Dest [ 885 0 R /XYZ null null null ] /Parent 1961 0 R /Prev 1974 0 R /Next 1972 0 R >> endobj 1974 0 obj << /Title (: Enable/disable special compressed \(non-standard\) item\ format) /Dest [ 885 0 R /XYZ null null null ] /Parent 1961 0 R /Prev 1975 0 R /Next 1973 0 R >> endobj 1975 0 obj << /Title (, : MIME type and version) /Dest [ 882 0 R /XYZ null null null ] /Parent 1961 0 R /Prev 1976 0 R /Next 1974 0 R >> endobj 1976 0 obj << /Title (: vCard or vCalendar version) /Dest [ 882 0 R /XYZ null null null ] /Parent 1961 0 R /Prev 1963 0 R /Next 1975 0 R >> endobj 1977 0 obj << /Title (: definition of a mime-dir profile) /Dest [ 792 0 R /XYZ null null null ] /Parent 1846 0 R /Prev 1985 0 R /Next 1962 0 R /First 1986 0 R /Last 1987 0 R /Count 9 >> endobj 1978 0 obj << /Title (: mapping of text based formats to database fields) /Dest [ 858 0 R /XYZ null null null ] /Parent 1962 0 R /Next 1984 0 R >> endobj 1979 0 obj << /Title (RFC822 email body options) /Dest [ 868 0 R /XYZ null null null ] /Parent 1962 0 R /Prev 1980 0 R >> endobj 1980 0 obj << /Title (: type of text field) /Dest [ 865 0 R /XYZ null null null ] /Parent 1962 0 R /Prev 1981 0 R /Next 1979 0 R >> endobj 1981 0 obj << /Title (: tagged header handling) /Dest [ 865 0 R /XYZ null null null ] /Parent 1962 0 R /Prev 1982 0 R /Next 1980 0 R >> endobj 1982 0 obj << /Title (: empty field handling) /Dest [ 865 0 R /XYZ null null null ] /Parent 1962 0 R /Prev 1983 0 R /Next 1981 0 R >> endobj 1983 0 obj << /Title (: header lines) /Dest [ 865 0 R /XYZ null null null ] /Parent 1962 0 R /Prev 1984 0 R /Next 1982 0 R >> endobj 1984 0 obj << /Title (: Number of lines to map) /Dest [ 858 0 R /XYZ null null null ] /Parent 1962 0 R /Prev 1978 0 R /Next 1983 0 R >> endobj 1985 0 obj << /Title (: definition of an internal field) /Dest [ 779 0 R /XYZ null null null ] /Parent 1846 0 R /Prev 1959 0 R /Next 1977 0 R >> endobj 1986 0 obj << /Title (: root profile definition) /Dest [ 795 0 R /XYZ null null null ] /Parent 1977 0 R /Next 1994 0 R >> endobj 1987 0 obj << /Title (: handling of floating timestamps) /Dest [ 854 0 R /XYZ null null null ] /Parent 1977 0 R /Prev 1988 0 R >> endobj 1988 0 obj << /Title (: VTIMEZONE generation mode) /Dest [ 854 0 R /XYZ null null null ] /Parent 1977 0 R /Prev 1989 0 R /Next 1987 0 R >> endobj 1989 0 obj << /Title (: control storage position and repetitions) /Dest [ 842 0 R /XYZ null null null ] /Parent 1977 0 R /Prev 1990 0 R /Next 1988 0 R >> endobj 1990 0 obj << /Title (: property parameter definition) /Dest [ 831 0 R /XYZ null null null ] /Parent 1977 0 R /Prev 1991 0 R /Next 1989 0 R >> endobj 1991 0 obj << /Title (: enumerated values) /Dest [ 827 0 R /XYZ null null null ] /Parent 1977 0 R /Prev 1992 0 R /Next 1990 0 R >> endobj 1992 0 obj << /Title (: property or parameter value storage) /Dest [ 817 0 R /XYZ null null null ] /Parent 1977 0 R /Prev 1993 0 R /Next 1991 0 R >> endobj 1993 0 obj << /Title (: property definition) /Dest [ 804 0 R /XYZ null null null ] /Parent 1977 0 R /Prev 1994 0 R /Next 1992 0 R >> endobj 1994 0 obj << /Title (: nested subprofile definition) /Dest [ 795 0 R /XYZ null null null ] /Parent 1977 0 R /Prev 1986 0 R /Next 1993 0 R >> endobj 1995 0 obj << /Title (General Global Configuration Options) /Dest [ 686 0 R /XYZ null null null ] /Parent 1741 0 R /Prev 2004 0 R /Next 1958 0 R /First 2005 0 R /Last 2006 0 R /Count 37 >> endobj 1996 0 obj << /Title (: HTTP 1.1 connection) /Dest [ 763 0 R /XYZ null null null ] /Parent 1958 0 R /Next 2003 0 R >> endobj 1997 0 obj << /Title (: Max sessions to be run by a process) /Dest [ 772 0 R /XYZ null null null ] /Parent 1958 0 R /Prev 1998 0 R >> endobj 1998 0 obj << /Title (: Max number of session threads per server process) /Dest [ 772 0 R /XYZ null null null ] /Parent 1958 0 R /Prev 1999 0 R /Next 1997 0 R >> endobj 1999 0 obj << /Title (: OBEX service name) /Dest [ 769 0 R /XYZ null null null ] /Parent 1958 0 R /Prev 2000 0 R /Next 1998 0 R >> endobj 2000 0 obj << /Title (: listener IP address) /Dest [ 769 0 R /XYZ null null null ] /Parent 1958 0 R /Prev 2001 0 R /Next 1999 0 R >> endobj 2001 0 obj << /Title (: HTTP and OBEX/TCP server port number) /Dest [ 769 0 R /XYZ null null null ] /Parent 1958 0 R /Prev 2002 0 R /Next 2000 0 R >> endobj 2002 0 obj << /Title (: communication protocol) /Dest [ 766 0 R /XYZ null null null ] /Parent 1958 0 R /Prev 2003 0 R /Next 2001 0 R >> endobj 2003 0 obj << /Title (: buffer last answer for retries) /Dest [ 766 0 R /XYZ null null null ] /Parent 1958 0 R /Prev 1996 0 R /Next 2002 0 R >> endobj 2004 0 obj << /Title (Filters) /Dest [ 656 0 R /XYZ null null null ] /Parent 1741 0 R /Prev 2042 0 R /Next 1995 0 R /First 2043 0 R /Last 2044 0 R /Count 6 >> endobj 2005 0 obj << /Title (, : License) /Dest [ 686 0 R /XYZ null null null ] /Parent 1995 0 R /Next 2041 0 R >> endobj 2006 0 obj << /Title (: define custom time zone as VTIMEZONE) /Dest [ 754 0 R /XYZ null null null ] /Parent 1995 0 R /Prev 2007 0 R >> endobj 2007 0 obj << /Title (: override local system time zone) /Dest [ 754 0 R /XYZ null null null ] /Parent 1995 0 R /Prev 2008 0 R /Next 2006 0 R >> endobj 2008 0 obj << /Title (: avoid PUT of devinf) /Dest [ 754 0 R /XYZ null null null ] /Parent 1995 0 R /Prev 2009 0 R /Next 2007 0 R >> endobj 2009 0 obj << /Title (: set timestamp for config file) /Dest [ 748 0 R /XYZ null null null ] /Parent 1995 0 R /Prev 2010 0 R /Next 2008 0 R >> endobj 2010 0 obj << /Title (: Debug Option Section) /Dest [ 706 0 R /XYZ null null null ] /Parent 1995 0 R /Prev 2011 0 R /Next 2009 0 R /First 2012 0 R /Last 2013 0 R /Count 19 >> endobj 2011 0 obj << /Title (: Global scripting definitions) /Dest [ 697 0 R /XYZ null null null ] /Parent 1995 0 R /Prev 2031 0 R /Next 2010 0 R /First 2032 0 R /Last 2033 0 R /Count 3 >> endobj 2012 0 obj << /Title (: Directory path for debug log files) /Dest [ 713 0 R /XYZ null null null ] /Parent 2010 0 R /Next 2030 0 R >> endobj 2013 0 obj << /Title (: send session logs to global logfile) /Dest [ 748 0 R /XYZ null null null ] /Parent 2010 0 R /Prev 2014 0 R >> endobj 2014 0 obj << /Title (: generate global log) /Dest [ 748 0 R /XYZ null null null ] /Parent 2010 0 R /Prev 2015 0 R /Next 2013 0 R >> endobj 2015 0 obj << /Title (: No longer supported; use instead) /Dest [ 748 0 R /XYZ null null null ] /Parent 2010 0 R /Prev 2016 0 R /Next 2014 0 R >> endobj 2016 0 obj << /Title (: generate session logs) /Dest [ 742 0 R /XYZ null null null ] /Parent 2010 0 R /Prev 2017 0 R /Next 2015 0 R >> endobj 2017 0 obj << /Title (: dump SyncML traffic to files) /Dest [ 742 0 R /XYZ null null null ] /Parent 2010 0 R /Prev 2018 0 R /Next 2016 0 R >> endobj 2018 0 obj << /Title (: show traffic in XML) /Dest [ 737 0 R /XYZ null null null ] /Parent 2010 0 R /Prev 2019 0 R /Next 2017 0 R >> endobj 2019 0 obj << /Title (: string to be used for indenting blocks) /Dest [ 737 0 R /XYZ null null null ] /Parent 2010 0 R /Prev 2020 0 R /Next 2018 0 R >> endobj 2020 0 obj << /Title (, : text to add at begin and end of logfiles) /Dest [ 733 0 R /XYZ null null null ] /Parent 2010 0 R /Prev 2021 0 R /Next 2019 0 R >> endobj 2021 0 obj << /Title (: if and how to show log output from subthreads) /Dest [ 733 0 R /XYZ null null null ] /Parent 2010 0 R /Prev 2022 0 R /Next 2020 0 R >> endobj 2022 0 obj << /Title (: select log file format) /Dest [ 728 0 R /XYZ null null null ] /Parent 2010 0 R /Prev 2023 0 R /Next 2021 0 R >> endobj 2023 0 obj << /Title (: append or overwrite existing session logs) /Dest [ 728 0 R /XYZ null null null ] /Parent 2010 0 R /Prev 2024 0 R /Next 2022 0 R >> endobj 2024 0 obj << /Title (, : single file log option) /Dest [ 728 0 R /XYZ null null null ] /Parent 2010 0 R /Prev 2025 0 R /Next 2023 0 R >> endobj 2025 0 obj << /Title (: show timestamps in logs) /Dest [ 724 0 R /XYZ null null null ] /Parent 2010 0 R /Prev 2026 0 R /Next 2024 0 R >> endobj 2026 0 obj << /Title (: show thread ID in logs) /Dest [ 724 0 R /XYZ null null null ] /Parent 2010 0 R /Prev 2027 0 R /Next 2025 0 R >> endobj 2027 0 obj << /Title (, : show timestamps in logs) /Dest [ 724 0 R /XYZ null null null ] /Parent 2010 0 R /Prev 2028 0 R /Next 2026 0 R >> endobj 2028 0 obj << /Title (: dynamic folding for HTML logs) /Dest [ 721 0 R /XYZ null null null ] /Parent 2010 0 R /Prev 2029 0 R /Next 2027 0 R >> endobj 2029 0 obj << /Title (: select log file format) /Dest [ 721 0 R /XYZ null null null ] /Parent 2010 0 R /Prev 2030 0 R /Next 2028 0 R >> endobj 2030 0 obj << /Title (, ) /Dest [ 713 0 R /XYZ null null null ] /Parent 2010 0 R /Prev 2012 0 R /Next 2029 0 R >> endobj 2031 0 obj << /Title (: define configuration variable) /Dest [ 697 0 R /XYZ null null null ] /Parent 1995 0 R /Prev 2035 0 R /Next 2011 0 R >> endobj 2032 0 obj << /Title (: User-defined function) /Dest [ 697 0 R /XYZ null null null ] /Parent 2011 0 R /Next 2034 0 R >> endobj 2033 0 obj << /Title (: maximum loop execution time) /Dest [ 706 0 R /XYZ null null null ] /Parent 2011 0 R /Prev 2034 0 R >> endobj 2034 0 obj << /Title (: define macro) /Dest [ 706 0 R /XYZ null null null ] /Parent 2011 0 R /Prev 2032 0 R /Next 2033 0 R >> endobj 2035 0 obj << /Title (: define configuration variable) /Dest [ 697 0 R /XYZ null null null ] /Parent 1995 0 R /Prev 2036 0 R /Next 2031 0 R >> endobj 2036 0 obj << /Title (: text to identify model/product name) /Dest [ 691 0 R /XYZ null null null ] /Parent 1995 0 R /Prev 2037 0 R /Next 2035 0 R >> endobj 2037 0 obj << /Title (: text to identify product manufacturer) /Dest [ 691 0 R /XYZ null null null ] /Parent 1995 0 R /Prev 2038 0 R /Next 2036 0 R >> endobj 2038 0 obj << /Title (: text to identify config) /Dest [ 691 0 R /XYZ null null null ] /Parent 1995 0 R /Prev 2039 0 R /Next 2037 0 R >> endobj 2039 0 obj << /Title (: maximum object size) /Dest [ 691 0 R /XYZ null null null ] /Parent 1995 0 R /Prev 2040 0 R /Next 2038 0 R >> endobj 2040 0 obj << /Title (: max SyncML message size) /Dest [ 686 0 R /XYZ null null null ] /Parent 1995 0 R /Prev 2041 0 R /Next 2039 0 R >> endobj 2041 0 obj << /Title (: concurrent sessions limit) /Dest [ 686 0 R /XYZ null null null ] /Parent 1995 0 R /Prev 2005 0 R /Next 2040 0 R >> endobj 2042 0 obj << /Title (Scripting Language) /Dest [ 519 0 R /XYZ null null null ] /Parent 1741 0 R /Prev 2049 0 R /Next 2004 0 R /First 2050 0 R /Last 2051 0 R /Count 30 >> endobj 2043 0 obj << /Title (Test and Make-Pass modes) /Dest [ 662 0 R /XYZ null null null ] /Parent 2004 0 R /Next 2048 0 R >> endobj 2044 0 obj << /Title (Filters in the configuration) /Dest [ 682 0 R /XYZ null null null ] /Parent 2004 0 R /Prev 2045 0 R >> endobj 2045 0 obj << /Title (Special options in CGI filters passed with database path) /Dest [ 675 0 R /XYZ null null null ] /Parent 2004 0 R /Prev 2046 0 R /Next 2044 0 R >> endobj 2046 0 obj << /Title (CGI Filter Syntax) /Dest [ 672 0 R /XYZ null null null ] /Parent 2004 0 R /Prev 2047 0 R /Next 2045 0 R >> endobj 2047 0 obj << /Title (Identifiers in filters) /Dest [ 669 0 R /XYZ null null null ] /Parent 2004 0 R /Prev 2048 0 R /Next 2046 0 R >> endobj 2048 0 obj << /Title (Basic filter syntax) /Dest [ 662 0 R /XYZ null null null ] /Parent 2004 0 R /Prev 2043 0 R /Next 2047 0 R >> endobj 2049 0 obj << /Title (Time zone handling) /Dest [ 489 0 R /XYZ null null null ] /Parent 1741 0 R /Prev 2080 0 R /Next 2042 0 R /First 2081 0 R /Last 2082 0 R /Count 3 >> endobj 2050 0 obj << /Title (What can be scripted?) /Dest [ 519 0 R /XYZ null null null ] /Parent 2042 0 R /Next 2079 0 R >> endobj 2051 0 obj << /Title (Debugging scripts) /Dest [ 638 0 R /XYZ null null null ] /Parent 2042 0 R /Prev 2052 0 R >> endobj 2052 0 obj << /Title (Global built-in Function Reference) /Dest [ 567 0 R /XYZ null null null ] /Parent 2042 0 R /Prev 2053 0 R /Next 2051 0 R /First 2054 0 R /Last 2055 0 R /Count 6 >> endobj 2053 0 obj << /Title (Functions) /Dest [ 563 0 R /XYZ null null null ] /Parent 2042 0 R /Prev 2060 0 R /Next 2052 0 R /First 2061 0 R /Last 2062 0 R /Count 2 >> endobj 2054 0 obj << /Title (String functions) /Dest [ 573 0 R /XYZ null null null ] /Parent 2052 0 R /Next 2059 0 R >> endobj 2055 0 obj << /Title (Other functions) /Dest [ 615 0 R /XYZ null null null ] /Parent 2052 0 R /Prev 2056 0 R >> endobj 2056 0 obj << /Title (Debug log functions) /Dest [ 604 0 R /XYZ null null null ] /Parent 2052 0 R /Prev 2057 0 R /Next 2055 0 R >> endobj 2057 0 obj << /Title (Time zone related functions) /Dest [ 595 0 R /XYZ null null null ] /Parent 2052 0 R /Prev 2058 0 R /Next 2056 0 R >> endobj 2058 0 obj << /Title (Date and Time functions) /Dest [ 576 0 R /XYZ null null null ] /Parent 2052 0 R /Prev 2059 0 R /Next 2057 0 R >> endobj 2059 0 obj << /Title (Regular Expression functions) /Dest [ 576 0 R /XYZ null null null ] /Parent 2052 0 R /Prev 2054 0 R /Next 2058 0 R >> endobj 2060 0 obj << /Title (Macros) /Dest [ 554 0 R /XYZ null null null ] /Parent 2042 0 R /Prev 2063 0 R /Next 2053 0 R /First 2064 0 R /Last 2065 0 R /Count 3 >> endobj 2061 0 obj << /Title (User defined Functions) /Dest [ 563 0 R /XYZ null null null ] /Parent 2053 0 R /Next 2062 0 R >> endobj 2062 0 obj << /Title (Built-in Functions) /Dest [ 567 0 R /XYZ null null null ] /Parent 2053 0 R /Prev 2061 0 R >> endobj 2063 0 obj << /Title (Flow control) /Dest [ 547 0 R /XYZ null null null ] /Parent 2042 0 R /Prev 2067 0 R /Next 2060 0 R >> endobj 2064 0 obj << /Title (Defining Macros) /Dest [ 554 0 R /XYZ null null null ] /Parent 2060 0 R /Next 2066 0 R >> endobj 2065 0 obj << /Title (Using Macros) /Dest [ 559 0 R /XYZ null null null ] /Parent 2060 0 R /Prev 2066 0 R >> endobj 2066 0 obj << /Title (Marco arguments) /Dest [ 559 0 R /XYZ null null null ] /Parent 2060 0 R /Prev 2064 0 R /Next 2065 0 R >> endobj 2067 0 obj << /Title (Expressions) /Dest [ 547 0 R /XYZ null null null ] /Parent 2042 0 R /Prev 2068 0 R /Next 2063 0 R >> endobj 2068 0 obj << /Title (Variables) /Dest [ 529 0 R /XYZ null null null ] /Parent 2042 0 R /Prev 2069 0 R /Next 2067 0 R /First 2070 0 R /Last 2071 0 R /Count 4 >> endobj 2069 0 obj << /Title (Script contexts) /Dest [ 529 0 R /XYZ null null null ] /Parent 2042 0 R /Prev 2074 0 R /Next 2068 0 R >> endobj 2070 0 obj << /Title (Context Variables) /Dest [ 537 0 R /XYZ null null null ] /Parent 2068 0 R /Next 2073 0 R >> endobj 2071 0 obj << /Title (Array variable references) /Dest [ 543 0 R /XYZ null null null ] /Parent 2068 0 R /Prev 2072 0 R >> endobj 2072 0 obj << /Title (Field variables) /Dest [ 537 0 R /XYZ null null null ] /Parent 2068 0 R /Prev 2073 0 R /Next 2071 0 R >> endobj 2073 0 obj << /Title (Local variables of a user-defined function) /Dest [ 537 0 R /XYZ null null null ] /Parent 2068 0 R /Prev 2070 0 R /Next 2072 0 R >> endobj 2074 0 obj << /Title (Constants/Literals) /Dest [ 525 0 R /XYZ null null null ] /Parent 2042 0 R /Prev 2075 0 R /Next 2069 0 R >> endobj 2075 0 obj << /Title (Data types) /Dest [ 525 0 R /XYZ null null null ] /Parent 2042 0 R /Prev 2076 0 R /Next 2074 0 R >> endobj 2076 0 obj << /Title (Identifiers) /Dest [ 525 0 R /XYZ null null null ] /Parent 2042 0 R /Prev 2077 0 R /Next 2075 0 R >> endobj 2077 0 obj << /Title (Statements and Statement Blocks) /Dest [ 525 0 R /XYZ null null null ] /Parent 2042 0 R /Prev 2078 0 R /Next 2076 0 R >> endobj 2078 0 obj << /Title (Comments) /Dest [ 525 0 R /XYZ null null null ] /Parent 2042 0 R /Prev 2079 0 R /Next 2077 0 R >> endobj 2079 0 obj << /Title (Embedding script source code in XML) /Dest [ 519 0 R /XYZ null null null ] /Parent 2042 0 R /Prev 2050 0 R /Next 2078 0 R >> endobj 2080 0 obj << /Title (Configuration variables and conditional configuration) /Dest [ 469 0 R /XYZ null null null ] /Parent 1741 0 R /Prev 2084 0 R /Next 2049 0 R /First 2085 0 R /Last 2086 0 R /Count 6 >> endobj 2081 0 obj << /Title (Timestamp representation) /Dest [ 489 0 R /XYZ null null null ] /Parent 2049 0 R /Next 2083 0 R >> endobj 2082 0 obj << /Title (Time zone specifications) /Dest [ 507 0 R /XYZ null null null ] /Parent 2049 0 R /Prev 2083 0 R >> endobj 2083 0 obj << /Title (Timezone contexts) /Dest [ 489 0 R /XYZ null null null ] /Parent 2049 0 R /Prev 2081 0 R /Next 2082 0 R >> endobj 2084 0 obj << /Title (Overview) /Dest [ 450 0 R /XYZ null null null ] /Parent 1741 0 R /Prev 2091 0 R /Next 2080 0 R /First 2092 0 R /Last 2093 0 R /Count 4 >> endobj 2085 0 obj << /Title (Sources for values of config variable) /Dest [ 469 0 R /XYZ null null null ] /Parent 2080 0 R /Next 2090 0 R >> endobj 2086 0 obj << /Title ("platform" conditional attribute) /Dest [ 485 0 R /XYZ null null null ] /Parent 2080 0 R /Prev 2087 0 R >> endobj 2087 0 obj << /Title ("ifdef/ifndef/if" conditional attributes) /Dest [ 485 0 R /XYZ null null null ] /Parent 2080 0 R /Prev 2088 0 R /Next 2086 0 R >> endobj 2088 0 obj << /Title (Predefined Configuration Variables) /Dest [ 479 0 R /XYZ null null null ] /Parent 2080 0 R /Prev 2089 0 R /Next 2087 0 R >> endobj 2089 0 obj << /Title ("expand" attribute) /Dest [ 479 0 R /XYZ null null null ] /Parent 2080 0 R /Prev 2090 0 R /Next 2088 0 R >> endobj 2090 0 obj << /Title (Using configuration variables) /Dest [ 469 0 R /XYZ null null null ] /Parent 2080 0 R /Prev 2085 0 R /Next 2089 0 R >> endobj 2091 0 obj << /Title (What's New?) /Dest [ 399 0 R /XYZ null null null ] /Parent 1741 0 R /Prev 2096 0 R /Next 2084 0 R /First 2097 0 R /Last 2098 0 R /Count 5 >> endobj 2092 0 obj << /Title (Basic Concepts) /Dest [ 450 0 R /XYZ null null null ] /Parent 2084 0 R /Next 2095 0 R >> endobj 2093 0 obj << /Title (Synthesis Sync Server Config specific XML usage) /Dest [ 463 0 R /XYZ null null null ] /Parent 2084 0 R /Prev 2094 0 R >> endobj 2094 0 obj << /Title (XML basics) /Dest [ 463 0 R /XYZ null null null ] /Parent 2084 0 R /Prev 2095 0 R /Next 2093 0 R >> endobj 2095 0 obj << /Title (Configuration Structure) /Dest [ 450 0 R /XYZ null null null ] /Parent 2084 0 R /Prev 2092 0 R /Next 2094 0 R >> endobj 2096 0 obj << /Title (Contents) /Dest [ 15 0 R /XYZ null null null ] /Parent 1741 0 R /Prev 1742 0 R /Next 2091 0 R >> endobj 2097 0 obj << /Title (New in this manual) /Dest [ 399 0 R /XYZ null null null ] /Parent 2091 0 R /Next 2098 0 R >> endobj 2098 0 obj << /Title (New in SyncML Engine 3.2 and newer compared to 3.0) /Dest [ 399 0 R /XYZ null null null ] /Parent 2091 0 R /Prev 2097 0 R /First 2099 0 R /Last 2100 0 R /Count 3 >> endobj 2099 0 obj << /Title (General changes) /Dest [ 399 0 R /XYZ null null null ] /Parent 2098 0 R /Next 2101 0 R >> endobj 2100 0 obj << /Title (How to migrate from 3.0 to 3.2 or newer \(up to 3.4\)) /Dest [ 425 0 R /XYZ null null null ] /Parent 2098 0 R /Prev 2101 0 R >> endobj 2101 0 obj << /Title (New Features) /Dest [ 411 0 R /XYZ null null null ] /Parent 2098 0 R /Prev 2099 0 R /Next 2100 0 R >> endobj 2102 0 obj << /ProcSet [ /PDF /Text /ImageC /ImageI ] /Font << /TT2 2104 0 R /TT4 2109 0 R >> /XObject << /Im1 2115 0 R /Im2 2116 0 R /Im3 2117 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R /Cs10 2106 0 R >> >> endobj 2103 0 obj [ /ICCBased 2113 0 R ] endobj 2104 0 obj << /Type /Font /Subtype /TrueType /FirstChar 31 /LastChar 252 /Widths [ 750 250 219 406 667 448 823 729 177 292 292 427 667 219 313 219 500 469 469 469 469 469 469 469 469 469 469 219 219 667 667 667 365 750 677 615 635 771 656 563 771 760 354 333 740 573 833 771 781 563 771 625 479 615 708 677 885 698 656 656 271 500 271 500 500 750 406 510 417 500 417 323 448 510 229 229 469 229 771 510 510 510 490 333 365 292 490 469 667 458 417 427 479 500 479 667 750 750 750 750 750 448 1000 750 750 750 750 750 750 750 750 750 750 750 750 750 448 750 750 500 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 760 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 406 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 750 490 ] /Encoding /WinAnsiEncoding /BaseFont /LGLLKB+Garamond /FontDescriptor 2105 0 R >> endobj 2105 0 obj << /Type /FontDescriptor /Ascent 861 /CapHeight 0 /Descent -263 /Flags 34 /FontBBox [ -139 -307 1063 986 ] /FontName /LGLLKB+Garamond /ItalicAngle 0 /StemV 0 /FontFile2 2111 0 R >> endobj 2106 0 obj [ /Indexed 2103 0 R 255 2112 0 R ] endobj 2107 0 obj << /Length 472 /Filter /FlateDecode >> stream H‰|RËŽÔ0¼û+ú„âCëD=/}Vþ¾z÷ê%íÇáxº}¸—5³òÕG‰K„êŒ-v§q ·ZbÕË|~”ÈzÜc¼j«~èzZ"c‰Éé…°ªu¡¡Ú(g,ê_%aS‹’Ãe8é§ÓDÙ*W]@ 桃™ r"/TÿLµ±ðÂÒCRÈ2~dÑ\õ÷ô„ößN2( ™g²ÊÑë¬; :~~èÎS០l‚rſƫèˆ=´ä®:çUp«}¼Ú‡fé‚(+kÑÞ‹ëœüoòfÆrü1U‹ËÜZeo316 "Ò‹&»jÚ˜3å®Ô5Âè] ¹“ËîÜæ#ôèTüÇ©_¸©æŸ–>]h6N€00©©&éóäH xÙÐÓ›µË¿¹TÁØ endstream endobj 2108 0 obj << /Type /FontDescriptor /Ascent 1100 /CapHeight 0 /Descent -309 /Flags 32 /FontBBox [ -194 -307 1688 1083 ] /FontName /LGLMBL+Arial-Black /ItalicAngle 0 /StemV 0 /FontFile2 2114 0 R >> endobj 2109 0 obj << /Type /Font /Subtype /TrueType /FirstChar 32 /LastChar 148 /Widths [ 333 0 500 0 0 0 889 278 389 389 0 0 333 333 333 278 667 667 667 667 667 667 667 667 667 667 333 333 660 660 660 611 0 778 778 778 778 722 667 833 833 389 667 833 667 944 833 833 722 833 778 722 722 833 778 1000 778 0 722 0 0 0 0 500 0 667 667 667 667 667 389 667 667 333 333 667 333 1000 667 667 667 667 444 611 444 667 611 944 667 611 556 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 500 500 ] /Encoding /WinAnsiEncoding /BaseFont /LGLMBL+Arial-Black /FontDescriptor 2108 0 R >> endobj 2110 0 obj << /Type /ExtGState /SA false /SM 0.02 /OP false /op false /OPM 1 /BG2 /Default /UCR2 /Default /TR2 /Default >> endobj 2111 0 obj << /Filter /FlateDecode /Length 34816 /Length1 46800 >> stream H‰|V PT×þιåíZÁ"«æ®¸»¢¢ˆHt»ÈÃ(讳ËCñ¬ŠV¬IÖ¦–æ‚m£¡ã£mÚÆ)Îä.š„h›’N›´©yu¤Óik›‰1“Q˜”Fk…Ûÿ.â@šô~îÿ:ÿýþÇ™½`†€Š«²çÔ”ù.¯”vymc0ôæšœ.à,ÉìTížfåÀ¶Õo“ío€ØÚÔxçÖ#W©€äòMÛZ66=uºHë¾7£¡>X÷Fš7Ÿâ¥3¹ ¤HZãb¿KrzCcóÞöŠ3¿#ù Wµ­©6ÈVüñ6pºäõÁ½!Ë£b?Ï"e{°±>wDZg—ϤPÓ®fÂMë\Ÿií¬e}óÎD ™Dù—QTw š$Œ‡ —Ghð†q—ôO e‚L$àWÑ[ìñëKN}aò;þ•Ní_a?²0§ÀiÏc9pb%ްX<„õx…tY؉ç0¯CCéÃ1ˆÈ ýLä`?GrŠp QÏ7Á……³EXvSÌV¼Ç Øm!Œ\ÌGVc#ÐŽËl €¿ ;} èL!¨§¨ðmÆ ¼Šw™Ìv³=ìÜÍwñ}ü¤ Éb“6¶C¡lô¶ùѳ~C•{™öoðþŠkèÃç„Áll ³³…ÌÃ*Xkg‡ØIÖÅ~ÁzØìûŒ ðIÜÅgñõ|ßÉ;ø)þïæø€ð°°Oø‹˜-ÎI‹¥:©Kú½ü¢ü¡¥Äh2.7¨›¡·b¦bõp:eOupÃC9TS7k°‰p·`ž Ìߢý(ꄹ Ýø5ÞÁ»xá >aœNcYl{˜•Ò®bkØ:VǶRí¿ÁždY;Î^`gÙìO&rv‹Ý¢Aã\à2e‘ƳøC|)R&›©SOröiþg~™ßÒ…éÂ!Oð!!,<#(\… å|û)džMó¿H*å¿ÅM\Ä{ä]"[°‹ I³\¬fUTÍÖûTHe…b¶¼?!Ôa¾ Œ:µ ¯KÝ+ü$MHþ€³4ýmt×·7Œ~š4…ñt_Ëpx(‰ÐÂvšèšüRšÖ tƒì¨vç-È›?7gÎìYÙ3]NÇŒ³¦gf¤«ÓìÊS§L¶¥MJýúÄ”ä _o—”˜c‘%Qà N¯ZPôÌ€.fª%%.SVƒ¤ŽRt…TÅc}t%uSÆzºÉsã<ÝÞîûžÌª ÀåT¼ª¢¿ãQ•n¶¶ÒGü!êWôþ(¿,Ê‹™Q!‘»N(ÞÔ¢³€âÕ‹÷4hÞ€‡âEâãŠÔ¢ú8—‘¸xbã‰Ó‹ÕP„/bQ†{ó#1‰„J/S=^½Tõ˜t!ìÓ+*}^Ín÷»œ:+ªUkt¨…ú8GÔEÑ×èr‘n‰¾FÙl¦ƒ6%âìÑÚ»­¨ 8êÔºàzŸ.ýæ;Æ;ô%ªG_²ïãT—³›ý¬Ê§Çu3Tù^C™Ž”†=?yj‚WÓZǺ»œå+}v£zÛàJ_¹³Ôlz½©3N¥^õššÀEU ÕmK€Ú¦éXÙbïJ+s¿f|ˆ2¯¢UùT»¾Ø¦úƒžÉ‘dh+[Ζº•Ò±—3b?\ÃHÒ¸{LBâh¦þ¾-ÊEÝMŽP‘™ˆÔRj¾®Ô*„ħê<#ÏüWŸ­6ÜhùÕj3U& YóÍKVUÑn‚Z¬ö÷Õïiä ëM˜¬9÷‡‰ì#¼îpè3f˜3`)¢¦²EQyžË¹G/WCVE/§’¡ÂG‡üùÙTr»Ýì_[·5$èáJß°¬ ÆÖw¶Ã¯ó€i鱤T›–ðˆåþñ€Jƒzæ÷LŠ“yÿoœuâoC¾Î&þsý°.†W‰ˆR†VáË jm¶Ì€Öî§ÖÓ%Ó´bU)ÖZ°ÛרŠUÕ"ååZÈI©Û8ßfÓ‹Ûýº5ÐÀ¨®zÎpAô E>ÁÆý÷ Ä•¯RË+×úò¢}ƒ L¾:HßR1W†>úOÌ(ÔQ‹?#p÷ˆõà1ÁƒýZ¨–;P&õb>ÛŠJ^ójã’° Éþ4ùVñ0–Òs¯4 =(!:Nä"ZA4Ÿh3QÑ"Óg-ùï&ZC1ŽŒ¿¿¥Ai«1 ^‡MJ_v`¢äÆl1Œ…Ä?*§`:ï…ƒw«¤ëÈ;/w"‰li²È/“ø Ìz±L¼nÜ•:‘A1?³¤}Râ$7=Ý(á¼O˜wp‡ÑKÏBÆ Þ‰·(÷B1Ó„j,'}‘ùäP-I?•õRz)~æÒ3ŽÞ—Nz•¨”(U¸ŽbŠ“Aùì zå‘lzŒRµqMèÄdŠg¡úå ½Ì&‚]"œÊÿ‡fÞQ¢¼ÍœGr2ñ›˜¾”Û‰õƒ£èî(lc(Šk4m¥Fj(Æ ªkÉÍTëÐaü‹ê0Žjï5ÉÒ‹©”ŸY+sFŽÈ½Æ{8g›3At8JTg:—M± ¤spÐÍÝpR½ù9¯ب®+zßßÇÌ<òÇÀ… µ±Cldÿ1K &àl†ÅqÌÅÄ6©€KLU‰¤…¥‰Ú4ÉÉQé2 -PZƪ¢¢V5®‰ ‹²¶a1K#µ LÏý!ÓªËHçŸ÷ßrß{÷{ߟ|*bá g*GéËXÏ"ø«šØÉc•M´ gw‡íC Ðæ„AôWÖhÖW<¯ÞM«q®‹øü çÔ Ì‡­ ÀZ¥ÆÊ·°ø×$ºï¼¯n¢ßˆC4ð*Ô ¬Ä~MÖ1°ãÃFˆØóà,î2`ëïð²°µ–û{<4O±¿¤£"~À€“ÀAå<ùG«X³¬Ö'k„õ¸•­àµóX㬳ŒŸßƸN ˜¯¡lû‡Y3¬[^ç]ÛÐë$ˬqŽaGÿ’噼_Ö×]nLß°yÄX;>C4›×Ⱦ±Ûþg×t#¶9¾Nÿ× ¾—áO2|Ûah ›÷Ä>N/Á{çŽI Èycó^Æ_:›¥Wì˜-ä¸Éðg‹šF®:ƒ:Î'ˆ“‘̹ÅÖîÎú7Ëœ{8þ™áãêÌ{©ÏÐúËvÞBîÈžVY–öÐâì9q,rŸÛc¿³í¸Ëä\õ«È ¬}>3èRO³ìýÆpïlG< ßjyäÒ¦u<žëå?Aow¨A¾JâüÕH\‡÷}òãä’/Гv»Ëé#‡ì~ßGn]MJ˜ž“5šh·_G;‹\uƒH—Pþ=øxg›×ð>@劄|wwÔ¹ôÇv=sgs±Þ'hª­i>»llCWúÓ×õ°ÿ<Ü#aïö.á ÙWŸÁWì/;+}–mùDÊbš T1ì1YeüÈãm_a>û~‚MõýŒ¯tØ®ÇmÝF¥Ælô/!ÒÁ<úÏ3ÞC;¥3wÔBy3òÆòAó.;Ætø7gÐD>†¼ñp9ãçä²ë8÷;\`ß pASÚxh w“Ý6ëXN>†òÅôß•;¶Ÿü%ªÕjÀXŸ=ö6¾xîF;wosîE¾sà.èô'ïB_^ç-^Ïeäý_“'«é‘œÕ¸†\Äùˆó·!o­ÁÝô ù›é9CÓy|GÁß“´fúέͨ¾GË‘ÿÚ‘ÿ+e¸3#þ^Á/2ôób£š¢âþ·ÈÁ/ÛwÏy©D9/Tõhú/êQi·ƒlù^ ‘rÚ˜÷¶ý¯õÿ¤w3( ìç†ô.­``ߤ"Ê@–ўȠ˜Š~‹ {øóàÛð°Ú>T{þ^š„úÆì݉óH!×ð¶€–ÑÒ¤T–ØPj&¥)'Ú+ÍC[*QœœXÃ4)±£Ò çII¥ Sú¸\*M´yb"ÆÝŠmL±GÍÖØBÍÄ“ë̤ø01ü8Þ&$šÛ@ã­üÍ…æªË<Ûz¶ýlLllŒÉ¿ŠÄEÚ{…âbb»8->¥rÀdñ3NTšW“"|¼Ò¬„½"L)`òàÏÔÈa«TxúýVCwÿp¿° ñþ¡~5Ð/è’çRÃ¥¡K×Ԥȷ\ÏU˜ß‹ÃnQ 5°W[„g0`¿í5ÖBèöÆ{z‡{Uêõô–÷Z½ ½-½e íhçV#€Š¼(9´W<ß›Ú+Q§§¼G¦žW{zdOxœ(ÆlÅø–ïÆS[\ƇÍeÌy™jÅÀj`+°0Ä«ðgÌ*ꩾ¾¡¾á>…úÊû$.Io‰Å;4&6¾ÙZinXÓfV%…ïxä0³÷Mpõk q2CVþ˜9p¤Â<™enˆT˜ÕÛ"gÐ’k倫G Íê¤TbùÖL6×´•šU;`±º=6Mù­)8ùêV~äPÌ“ꢱWcñX*6S[bí±îX4¦Ä"hO 5±ùAXk=i3wU9îˆ{³ôØfž–""IE"C‘ሺsË,Tmôl »Äð0á)Ĩ${»`Í@§ÜÑ“ãÉõär¹<ÍÔËtIצšUn­L[­íÑ~ª jiM/Ók’ ¤A'L’ LUB1a*LVЬ2å2Y’% ¬•¶J¯H§¥k’Jóæ!}^ÚHŠŽÄü ЇÖ;´Î¡µ:4Ö!¿C>‡¼¹ÊuHsH±–€ÿ ¤€·€G€ðp8^v;€m@;°Ø´ É¶»Ñ1ßæP‹Cã*phŒCn‡F9¤:$[Að0ü8 üxØ3¿Â›ã͉†G‰#¤CÃ/ÛÏZûYfYzôWzô%=ú¢}Vvëѧõèj=ºLŸh”ãAc¼Qh~cŒá3<ÆhÃeŒ2 C3C2)­>žzšê[ñO—±´'–ÇÕ`ˆûê©~i]ˆ? ×KõKêâÕ¡zœâWâU¡úxNC¤é˜ßnFm\úVRÐÒ&l™«öÅ}³›NBEÏì{¾ˆ9ºïùæfèþ_Á½/¢¾açIhnÓ Ý¼¨›kuÔÕ/AU”«¢õ¨]U mÔVÿÔþ– tŸAñ/&Ùeî†%u˜«é˜AuͳW8|\Ê…U·7×ù=íÚ[¨).Ø]t 6Þ ÜPsܬ‹çÜ4-<-ÌMnjw¦©`wMqÑ)ñF¦Éƒj/üI¡uÙK N»l¿.‹ŽÎPhUÇªÌ »:ï–ÿý6::;»lêêìèBPG Q‡à:»,:).Ï]Ÿ”ÆÎ]·ö·ÄÁ9q+ 2%Á9ðZg§ã»cVln î—¹ûñιwF„(ñŸLìßÁ2ä´ÜÊMÒo !nzC>)øk{çÏT[‹çôòéÞbï¤bo±BŸäÔç–JŸQ@IÁÒ®ôGbZDùTL —LIñGkÚ¸×Í\÷áœF?‘_QÆvû-¿D~óøÏúý×üi¿î÷K¼¾™e+ŸÙve×̲¯{g–xn]¡ÚÛWk§—? KJåÉ¥“g<üHe…?Œ.¹…¦g^Ð8ùæ(UGÿ“ðj nâºÂ÷îÝÕêåÕ®´Òêa½,[òS+Y¶dÙ²õÀ6¶‘±,?dŒ05P¨dCp ÅÓRCi£å2&žÐ‡Ûñ”$iq§)ítš¤†N§£i¦“1¡3½+HÛÝÝ{wÏ=ç®Îê~ç;çò•ž ï!äðP{}m8á¬ì‚˜¢b‘ìá`0jô¾U|wÇçò?×¶·¹Ý=ÝØóo!ñ#êë@ Ì %æ(<¸+3— œ(Î#á<Ç•Ä"ú5úQHÌb7ól>Æþ†˜°ì!ú¯oȉþÇSô›¡¹¡®Í„‚¢Å[Ö…‘ Vªµ¶‰µ§Š€•M¦hk«8´£øGìÑø“5ò®Ò,Àþ;!W©5,KSv›–ãdd¹UÇóšM½ž`Ê” ͲÛ9•ˆç·ë +Tör³ÒrEN‘P¡Á zµmÌzÑTf¼¢Ñê Œ ,Çëi"X|ÜޏÇA–ƒÇéqõl‰ )aB@‚àt”V'‰D!çf³BˆX–VE¤£‰<|ùʲ$ãc‘òÖ-°«‹^£tƒFɘfK*<°ú•ð´Çÿ¥S@R è]È©w"—Nj®æ€®bÅ8ÜœÊÀ»C™ÌÇa[ñÖàðP1øüpú·,®Â³ƒðÃAt^)NH-SÜ“)æà%©eàùâ^xC~°øÔNu€]à›à$¸nÀÜ{^GõTË1µüä³Û²o÷òdÛ…‹$¢Þ8ÙÖ&%xÝÅ/-QKmÔIò´ÿ…óäÚeh‹xµÖa$Œó–´FïœWÉÓ;%•6;ØNÉGÓÉ“x&yíåeè¼Y¾fY†÷c]›ÖbÉTr"9“<š¤4I˜L^e×4Ù‘µÑÑk/ß‘Ësϵ;l|&~4¾'cñÏâŸÇQüo¾\,—ÊÉ‘÷r0'Îf ³Ù|XäbGNþ‹¼´xè‹ü¦-™XgoO÷շߺþFK¨9àwØÊÙM©-ƒ¯œ9{îÕóöMÏÌν`4YøäЩK¯¿vq÷ÂáCçÕ#Y@ òȱ—ŽŸP—©GY!òŸk˜Ó ú¢y!œç„pôp@4>` B˜-`+KK$»’mK¶ø}UÁ(ôx QØÜ z$‚AÀÏ+‚ báiD{Ü/ôÈð AOìÐðLCãS/ð´ GX(ØÜän–Ñ ¤]ÁfiB)êƒN²6ë<¡&ÛUA 4~ ï ¶C<Ã#½Ç6Æ(ò`Ù zƒÐK–5„7« !k?šß§•UQ£ÙÁ—¡:ÜJ‹¢Ò¬s(ø€ÅB$!SŽ×˜|Zõ„^«D2 iÙ%§ˆ*Ħ§*…†˜8`Ï©TP¡ÜWWQN`“DPý.æ@CÈd ‚hc”RC¸Ò×[f5ºª$hØÖõ$°bÞµ¿oç%§Œ‘÷èƒ$ ÈðQÝ¡ç=y%g6U˜Ô†^þ†UirýBFuX\AwëžØe Qñu›[«Ù¨gX‘£ˆÆ«îÔ¢LS~Áù|qC+ÊQ¥ V¶ZëêÊÓ'Zl^ЬSGG*ÔèÄxÂ÷bp4ÛyõXãòYq»Öç¦í{ûël “›×©µ¤ÀÕ÷äDzç(àpðØ ~Ûªb˜ ç«\žÈ­ ë5ú°¾Wÿ{ýc=¥ÿȳ¬­÷­¬”µ{Ý Fº#÷#ë*òQr½º©¥©§éË&²I©’ÇC ÐÖöÞ‘68 Ýô¯Tà2J’´ðXµøÙâp=ÆÏøWü÷üˆõCg­”ÿŒŸô/ßÇÔ)ã„ñ¨ñŒñ#e³Ìc˜ËÍsÞÌâN¢ô­G³ùB6/–zU"{Fc~ÕCøº!UãKWÊA“¾` ›0]Ì¡ ü?êi…QG/šàO?PŠ²â¦»iªnírnò{Û|W÷‹•ÂŒœélÜh묨'^Éí¸XmÅšÃ.ãŒký‘  t•Õ/kˆu¨¨°µø^ñ2 —îÜzmïxwfl´}á\C2¶ÿ“3¾h1}éý[ßß7Þ5<6Y8ÛÐûä<Ž+Г¿P·ÉŸá=n| vÆæ¡ï ,p«ºAÎLi&CУª,Ci §A6˜N5W£Í!wýäc'T:¡sØ& ›m6³9U_ŸÚ894¹sr}’œ¼Þ¡H­¯Ë ¬úz£Âms"»Y๪Pxˆ2)€:=Föíxãû.BýÛLïÃ>¾e·{û—ñêj€úP¡ðnÛ ¼Ð» ¿Œñö„˜ˆ&6'¶%¦G§—Š^¿Y‰³³ẏ…+æÃÜSNâÂQ¨´ÊÑB›am@d1f³žÚà‚º:•¹™v»ñ¾åvò¡|…a‰\™ª*§îK§ÝøÛdpB[]],Ýä«Ã~˜…³ð3• À%ª‘ê™(~ a:cÚ%0`úÂü„áò”ˆ0·¹*¤ÙØ,ˆÏÒ¼t!®‰¨çmD 12ÞüÝÅ…oíqõ›ËÞ|®ª$ö»ŽÎd÷Ž{ŽLµÅ}†RtÉÑ–íM¶ LÊÓõÃÝÇÞì¯ïi×o ü©%–élOV‡aŸ}Z3½pÌ™>>˜»L|0?È?ºmd^ôY¹'^¯µÖª•”BE‘ µLeëÿûŽ ]9®‰ºª ]õê”5к÷ú@dzs-Scê3ÎŶíì 4G3…WU$T‰oo·ü›ërmê:ãø9÷áëëkûúú^Ûy`ÇŽ_ÇÁñóp yÜ„,NðHX ”"d<ÒP” ²AYA¡aH 2hZÑNH[@]ȺnË´jÚ£TÛhšBGºÑMÝ´JÄÙw®¡Ò&Ë:'öutÎ÷øÿß¶®Š•@&«†ò þ ê.@/‚]:ÝFSИ€EÚxh°ÖÿÖ÷ª<± á©Ã%ÀS¥‘ÑÌ]{ÑxÆB ²^Т .S2("*`hò}Ë¡ù8zŽd¿]¦½g±SKà 0ñ§Ç9Ià©nA77¯O÷®WS–\»kCcÿ»°yM²·‘õæç ‘ºòc7Mì½õéáT‚ϵkå­Ç1üÉš84ÖóÍ„þ±â)¶¸n¥žB¢Ï|b®§ØsÂócö`Ï!ÞáC4‰Ãâ¨8)2Htˆ~QÛÄnøsF¼%ò"Ô3œ”é³óÓU_U¸fXMœÄ/)â—\xq«)¶¥0^Vu¸Ñz@YýµÞ®@c{ÃÁò´%£ûä¥ËN>·ý#>þrƒt Lk}1óxðÝÎý™¿\88PÎ…x.ÅŸÓE¬¥±I?à…¤7 ØT›*ht’Nò µIm O•t:È š6žà•D‚GZS’V½6>hI:A©Mt¦Óµ¿Qª–`‚5IoNuS~®dsÈõŒHѼf‘»¦¡]¬n¯iÏE Á0«^Ï—`Ñý£@l·Ð=ô±Äj¨TKêC䑊ù"ÛïóssŽ9G izO꙾gùe>7™#Àb/-9n? ˜J6ZjŽ<ý¿«'…=r&Û¤UI„5ª<.hN’lMÅDxÄÄ©á ¢¾©ÅõÈei,cu…Mk'%åQ%Æ[2T(â¦)YvÞèå}ß±Øó9˜²RÃëuø1KE®ôP,|‰·»è2Ëò°Âë3íê)_‚Až?+™m¹‚uY·?(l©2É›’YÞé ™:íIeÑÍšB6)bþ'1eOdø ÚμÇ| ¨õLjÂÚÛ ¾ÊY¦±¦ÇxÓ)Æü2æO!Á/hB·pOx,˜üÂ^á’ðCaR˜nÁfM(Áˆ= ÿŠ z©\—‚Rà þ¼?ÊH…º’Ýxð'¤c×e.ât å¢5?ˆC—§ñé©d:äÆ0M®Ò¥Q÷ûÜÃîQ÷=7ëžÆºÔ'bÒ úÓ1‘ö€ÖÈ@ƒ 8qv‰dëiw¨F v44ÄŽ×a«µ7 s“h-r¤dE_ÛDæb‰MìŠ.r¹\&Æá’ãRð@Gíér蛪À?ƒI·E/eXŠ“id¶wJl'݉®J)\»ùïmJ·Ò§ +—•IÅäPÚJ‰÷ƒêHDɾ0Ê’”¤“œ®Ü“ô$Øß Ñÿ8®Xc_õímåéBª. i–¨3÷HœÂï`–¦øV–¦1¼9ÑÀÂ}Ü‚~™+z›~ƒ·˜¦qžnGà×~D?"ßÍút »+Ӓϼlf ¡$º¤¶$Z·zqc]<®7Àãû3ŸÑ¯°¯ $ô|„)j+š†o åi á‘þ€èò>C•㎇1ä?t„Ëq®è˜¯ßÀ¾úåF˜f[þJ³9/õëËòÞ…“ Ýi¾a¦Ì6u ¡ÀÆ:ô<†"œ@×чèú'²šnƒ†¦x¸dÞU:¿D¤ÞÒÅ÷ýØ?–´¦­ë­;¬ŒL¼k¾kß–.xõWï‚Ëb…ÌÄFÃ0x8Ÿ!X8‹`œIr„U9UzXÌïnÔvW÷\i;vtÅ®›5‘sXZ4ÔžÊ)Ú0”ÄÔ¡m'ßÑã%#XûÝk8òzË[×Mþ»ãÌþÎm—2?ÍÌ,ìÆESp ˆ¢þÄ:QZ}= »¦ñ n ²‰ìFlÍɱUVLc×|~†­îm“6 Ù4›n›µ16[U%Ièü|ªËÐ(HP Ñú¢q@¢÷µÊXNªɧ|™õ€liÓ_B †ø¸¨Û™*l/Z²@ÙPußmvröJsíÖMEȳqo*hZÌX`•lœUrËu¦BÌ|ö²ïÒ„d¶˜l>&±ºÓ„¥Ê'ßêð7ˆ!ìÃˤcP'ྵè÷zÙlñl”Ϊ³z\ŒÓ®ˆ«Ø¥e^¶È-ðüñ¨ªD£j^ž*H vª”/Ò\默E¾ ÿóöuÊ bÏê_°|TP;ÏårI.Í}ƒÛË q93ÇyëPÅ¿ R“)*•ªyÑŽícz¨/t94bêC[CgÉ&ô©Ãë÷j^ÝËxã¤FvÑPÎ"`ýÜßÈ똕OÅ¿"}ÔÕ…ûûû‹ %UŽ=¼œY3|5v£¤ÙA@_îI€9$ˆÎÃ3tï¹'w·®´zœ‹Ö^¾wz´·þ`Èv1&³YÜ|íÀùß¾òdmó çäû—Z¾ãÑŠsX K™M0Uš Ç™hpÇka¼ï…Ñ¥1ïá$[ìW}ïŸÜóу-&$ïÀØÂš½+c‰Ö…9z;t[:¦Ëj8”‡5„4Ázg „C!Yƒˆ^gؼiÌ땾£²MïTcOlÌl®´t`ìž#îvŒ:&7Œã׺gÆCÍ¡€ŠÌwõï›ï”f&Ôl Lósõ²I\Ég’Á%²J‚ã1¢“LøÀ—Q8ƒà<¤ïŒ`rÙÈû«úìßݰµç¥œUgÖe>þó•Ö’`^ ¾wÍK3G{–·å$"ƒ5%}›ÏÑçh-›ž;Û‰[ßìþEæ¡–v†Ú?¼4òýæH‰oãúºxë ”\x@¿ 1©CËÑ{úÎæÆææãÕH©®F¨¥ºþŽõNÙ ÛíÕ[îÄb^ÄzÿËtÕÆ6qÞñ{žç^ì³/wŽcŸã÷$vâØñ»q|!¶ÏI€@ 4@’ÍM2²á½é ¥Ðt D¥›ªò²F]E×5¢íF§f+›Ð&õÓ6u™Æ*M]T> ÄV{žs@ÕéîžÓ݇çþÿßÿ÷"”—I´ð6;Íý•©tÒH­*xêZPžÍX3µ'’©ÌJΟFˆ+äý§ª¸Sù7ªÞ˜×nFÒ,¸¤ŠGÓ/§çÒ(ŸÞ(`¡HŠ´ ™\/â'Š%g‚¯E-shõÌ“¬‚Å"zka‘¼% ¤1*©áXÖ"s²KñÂlM®,+³"¨®Ã¥Ô4®$'¸¾ä(„9Qc‰ 7dð| Œ5hYÕ–0Ç$RB–ËUÔc†‡AÙ( Br{¦6¦‡ÐÙù›öï Øpæ§ž+(w36;u|jÿ9'&(z€§¾Ä¸„“a_^ËOËsVƒÁêŽá#§ï5} ¬ûîçÿKAxÇÛ¨—qPEê‚Z‰‚€_½jek7O:+ …ÎÂò2fŠ'ÄWE$ŠîNˆµÚ 6]^O×Í‚¿©‘Ø=·`ä;Q¡à£úúz—Í.ƒË¦(Ûœ Úlý’ÏëKøZ0%0zÊò¾( ²¸%µrRcÙ[ J Èrb‰ ʤækךIåqš{TT2Ú%tË$3`/8Í^hè.y> ñ,ö…5Z0A—ðN>j,^á÷ðîžIÅÃŽêi€äp÷Џ¹?Ø´Úc ©GÞvnîõá*±|#ÀÚšëξÂ/Æ”A“hdŒAÀãIœ‰“Ø£›êŸRœ"+!ècz±O‘¼-›YO¥ïÛ½êÊ5Ï÷ô'€À‡-‚EªÕ'mDë|›_Xú£Z™eP¹^Wߌù«¿¨– Œ`‡Æ`+GØ~+æ˜aÆ÷¯¯PÙ‡·U‡lSβ¦ø dŒ0ic€iÉjS\³ KÝm÷ØÇ«{èôK4¢ïQÕÕ‡ÈT™ÇŸIO¤aZðx$¾Ƙ‘§¸°® …Ï„gÂsa.ªÝP„o¤¥•ÒF IS^%¦¨ÊVåCåºò'…Pö(cʤrAaÞÕ´@ ŒÅE|Å¿h"êIÜ€•ŠÒ¦ùx,FFp~ -%?-ýw©‚ô h=#£D:¼ÔK|py &Z‹Ef…àó`(ûd»S‡Ð«#Ë·7íuXtB™½ÃÀu»b•_¹‹ÙÙR^³ñ'ï^›z¯ëiÆ-–hC”Ò½a×;? ùǶÿlôÍó:è2YÅ2±ÂŸqõ²¶öù U@w'îl[q®¡‰ôᩇ_ }ôª@ízßf³òجßTgE àÌdì>B&& i§Õ.¬N'ŸºÓÅð3<òðGyHñ€¿áÍÅrjn.GGs»s0GL"©ž€$‡d2=žé±&‚„-J²FßIyðØRì!³¡•Å\bt®¦®š0S]íRÙ05¿’~úÙÏúG;äAY'6³G‚\f2Í&ÖklrîG$E0gÛË_‹¶4¹ à Œ¡@DCú6ñ¾:Ω¸Ž]×룱b½YôJÒòÁš?®éã»ý¢ßh@àjË®Òènl¯ä±ŸÝ‘»›1Q*‰¹ÿêÙ¼”olŒ‰Ÿ0£&©©<Û‚ú¨Ã)£TÊ+™ZRz[`\ÖMè~¬Ã£´={( ³ã6Û ÛY² >x~ãSU ]dÅá»h0¨u–-–IËŒeÎÂP–˜EÕðRµ `svC¹(:@Ì1递Ãëˆ9T­§ ïp´µgBÈiïÈñ‘Úrí‚%‚`¹ˆO²3®žË¦htÌ[* l9©5ª—¸—PÄè.{døµCÏÐs´>ªÝ}Ã3‹«ñmñ³qz2~!߃¸F‹ø4UƼ±!,ÞÒì )jnº–ÁxdÃ5OH*ȱ¥¢-y?-s”JotxCgÿÚ¡3òÏáüðŽöãÙ®ÌÚöd¯·LÇ댫Róì§7_kÝF_ízb×éé‡ÔÕg¶ê‘(ÔÜ> RŸÿ´gÍÎßû–Ê"^”ôwm醓X,z@òõgtôþ tu\_®õ?Ø÷`/éúø?áåÛÔuÇñ{Î}ùú__ûÚqâØNµqâ8qLB|yš@ž—à@xHRiLÚ•T)+*4´£4•V$¨4µBEIÑèl+Ú¥šVuÚ€¦ÝРZµAœýÎM‚´¿–«ës}}ì›s~¿ß÷ûùíb~CŸ]㩚MQÌÅ‹<æ1wnÞæñxx^ÝLD&{•/çÛà|)|“œô©Ḭ̂ö¿«|NÍã(„zX–ÆaX]49Da†¦ViñÓÀEô1xn™ômш†Ç~«¯òÿ®ÓŽdT% ×™ðãÏé«O™Ý™xS¦n3ÇÀ:µÙ»ø=Ö=M=µg‚*S3ú,a ¶XÜ6÷Ï—«Ý7eâuŠUÿ¬Î$_è à@@EO"ê'Åß( HDMü”w¶.«•áJ›4_ïzÌL‰÷çÞÁÿUB*…qT/óy*˜ïúôÔÒµ”p‡,D?M8˜ò}14c…ÝË­9[¹ªñývOSLTг•gÔw7.OÕ­¨r÷EŠŒ´a(wQ±R¯(\Š–˜ì&»ûT}o‘hƒäÞ‘<4.™>Åî©ß´üjkòHÂ.dñžlá̓òÜBµlqõRØ£Ùï(ŠíbÔ6ê ÂjcgߤëÞnšªê:èÕ+nß7È¥–íÚÓ×Ï$R‰AÓáSŽ¥©ÔÀ€¼S£ÅÆæFº±qƒLÓÚæq4yyÃz­ó*š¤6PÅhR—ÖhZE{©Á!;é€a { 4@ -nOÈSåYééôò¼çá=‰MÑáè;Ñ?D¿Œ²ÑqùèµÀ/ (ã¨Qu½œMá”×ÚÞº£•n½°y òoA[@ƒÆãÐaÎÁ $=• T.N‹SáGÓâ£iÒ¥glñy(!‰d pâ"=Èt:¬®E‘XõÓƒðHéöf'¸îÕ¯ç¤.Œ@+@Î —$î‡:ÇòÁmˆªÎÍΧ@°*мH‚èøˆyS–ÉÅÛÖfº£ >ƒÛÕíl•½y…%ùRÑÙujÈÆ6XÊ$†ö[*n;lv N“Àš»Šd.GÊMù&E¦³F O˜èÅÙÍ»+d9Z`Í ;{†Ÿ­5Zø.#P=Ïû ˆçíáW5{Ý2Ä×ÿ¥¦£¶-Ñ™í½Ö‘ňŒE0q,ø$"b³,â± R*²á1ëµd¦ß™cÍóX€šãñ6Ž ü\ú›dî:×\ëAarg3Ì+QQ*EõPª‡EQµZÕobßÇplÈß::r8J£ñ[*R5Ž.Ô.¬ùÝšÉ5ô-‡ÑC‰¢hí^Òg±ê•;¾­ï£ävy§|P¾)?”9¿IÍ@Gl9@–å­¡Tº»‹õŽ”‡PyH aCħ§¦f¦H•êœO‡!âƒTx<ðHç%H"ðn’DPËUs±p%5kEs=S‚惛ÃyâK‘ÆW4@z.Ì›»Ìûäiêʰ~ÓÅË^œk3vZräRÓ¾Á?²}¯(¹™ïîŸý´ °€ålGò93éDm Åh_$ö§·r+;ºÚV¡Òˆÿvër_[8¿é\÷'Ø-¦™[>±F»•3]§·òzS1íÌ=Ó&3Ë19v9tÁêZnìE†ßÞp›i”1¯uw$myvÙh {½‡W¾:“ä Å–ýÕE‡ºjy—IIµý£½T^›ýšù Ô4Fý¼–1Ð&.Ï¿ˆö:9Îëuš´*Ú©…iúºJ‡:-äÍóüEŒä÷«¸ïůá˜Ã?`%Yêh©¯¼l´ ¿S†ÊÂzë5˜Ž„¡!,é. Dfá–¤—èB5éÜ”EË ú ²±žžvYetU´ë¢Ê¼kFY³Ùá‰>É<íp¡8DÖ»s~Sò(jŒÙܲ`•YdàhCyCчŸúæb›ÏÌ3ˆ7°\uNbß©%m'Žý8}©ÉÅܲEÚŸü*c„\¯˜ý'+2ÿ¡F©q5Ø~§IÛzÇßßÜÿBÿý¿ì¿Ýÿ°Ÿ÷÷—÷ãþ~_E…¯ù8:~üdÁÇàvAˆßRÍgÓrÉ;/ÄÏèï¶ÑNbí4W-9Ùz`cº{çžtw÷þÊáá£^zéÍâJåpº¸øÍdz?DE)P+‘+P¡GÓ5D–fâá#:è^FK›žJLé™ö1äœ6ôie޹PwRº³ì¨-¤6àx6"ó å;í dEy•î ÀšÚQúÃÝç?üIg½] ¦ûü,ÍSHªð@h¬P´ðÀ)fΞ_ã¹B’sôæ®óÅŸƒÜÁv¼Ë‘•/˜{ O¼EܹM4“¾wÏ»êï66cÒôgLš~²Îa§u~rŸqvèX™P‡¸‹Æ|ã*eX¥7]å´k@URù‰bOñ…‘âX1SØSø~áýÂBáËÂJõš daIYS¼4ÍÏŒ¸‹Dñžò@!ÇñË(˜u?ÕVR'²ÒåÇWíy¢ë‘Iº2õ Ëïñ´–0ï*¡iwóúKs%MV܉yeRFA“B ÃôT¹¬*=Z†e»‰°Ûú°@³:þEµ Y¦E#æµ4¯šEå¦V—%ÛÄ€ù|øÉùÇDŽ€`c_˜SP¨ƒstÄ­ pÉ…ýã©#$/ž34s&ßx¦ K p¯Ee‚üÆ‘]mÓ€·6€ *O¶;)†áŸ,äΤ¿gφD˜â<_6¹\»C®ã´ ×™ßsAŠœ#Ì&™W<ªÃÆð6KM0Û»-y‘–îïøvx%†¦D–IÀÑÏ ")FwþàZ†(qp€º~å{^ ¤d’Rmè» º¦Ò$¯D©V<ÚŸ¿þÃÄó›| ´ª6…qÚdÈJV–ñXC³Ýpû…âeŠÀêêµ\ 9§íT^`ðM€¾"@¢ˆ8O¯D>ÓFÂhå† CÎí7¼rkÝd k¼kª‹ò“Åú“° Rœ…—!µŽÃ)HAØÕY©0&šò¦~?B Z2M¿´D0nÐYž¥ œ$³.¥³0¨Àf‡«€qEœ„¢çŵ€FÓ@>G³k~$rà)À½EêñÝv $C“¢Çs·ªÔH´*ó­/lžZþrðk§úwÕ7[]]½Šl“9X¡¦ æ ŒdM¼Xêy{¨z¼ÓÉ€TdžCÍ æ® -ÿ‹L£}ÙB<“AFοÐï1jcF=Þ¥– är¹©ÜlîrމÞw35GüE-› hM©¢fؤ½ª]Ö~­AÅÜ`eg,ɸ†6§¼7Kñåu¨ÉQ¦ ùÍrfîRª9B¥Ö£ý‰c´¬fXxÊ¢ggñæè•ÄccÑ…Ä~×ÒPeMÖ…mø4J-6,F×.6Ò u5|¥¢ kéÆpø Ñ«áZ¢·6~‰€èº‘€áZH5ö¦ b,7 Ét—ц§ ¤¹jýÃ.V,•vò9ã+XF÷cdÎ(â¥Óß0^ÆK½Ó\˜ NÕBåÇO{y¿í¥¼Þݽ ·q±tÜßÍØ´DSbU;{›rd}»¬ N:¶áÄ{#ËŸ0Âè‰/:D«ݤЭ3Ãë³5ÿ!ºìc›8ï8~Ïs/ÏÝÙ¾;ûì\lÇq_⼜ã„$æ%ö×Mhš„8 x© …4qÉB mÚ DÒ Ô–d”Ò±±nEë`iU¥Eí(+£-ƒ±¡ mQ§VEå¶nÓâì9Û0Yö#ß‹-=÷ý}¿Ÿo•=Ü6¬%xƒ·ÕbfŒEÖ¹÷î!>k0o»Ý_o4a`2ñ†3 @ù¢Éj¬/×n@ˆV6§ÿ¶iF¤.t”Q@¬‘ ”lTUíÀñŽ4ÍÎi©Ø<¿äýòäJ«Í€/ãšÇ䂊ÅÛ@q.k£œ>”^J/Ù‘ AìÝ<A÷EÃò¨ï㞥Ï?ßÕ š›Û%qOÆ市×_8`C¼ fsÙÕÆ¶¶~ã)±Ùݬ5w64ÓÍÍ%³þ>bÖ6Íiºbé`Éh™|Íi$ã 8Ts…¨Aö5¬¬Ï#~r7Ä£Õ ·•ÌØ[‘M±É¤¢G^m&ˆ3¯Ú¬PJа8 u¬«xˆ°É“9¼SÈ•stþj®k½0†yAÉo‹ü4²*R®ÐF¹Èà ¶ºôátá· ÜŒh´!ÊbŠö/š>­ã-FÖn u«Å÷†´Ø bM-RÍš‹¡ô¹ôgM…ø¨4ª¥¬äèP‹^è·š Ô9HXþš99h wü†û¿ý•;—µ<}˜ÚdÜ·rn‚Йïÿè¦S¢1É]§>Høðjά@æ®’býÇÜëCF–g•ZOðÈ̱ΚނˆŸ‘l<]œ©©GiÄIAEò² Ùt YT÷›0Ò°žú1ªW¦?j)ÇpEz‚!G"ÖáK+ª*8%™þ Äò& l/S¾TÜZöˆbãH–áJNýlB‹C4‹,m¬A‘4Ïõ/ͤÿ äë’É\1ÕXöº‚ 42š!m)è¨öKŸ\8°Îi´È4ËáX%)ì%m–KSz~~ù˜7Uʤ߲>š:å¡MÆ}"mø d Š~-²:A^¦–(÷sÇŸB¹ð¬ó­$³—:Á+­ÎR¡²ü§…áÁ¹¯¼ =±«bJl·”VI,DNGAÌSýxƒÍ ¥Æ|åc,eJó^ñ›{…h×­/Xè y(ïÀcˆo¶Ì<Ñ.pfàÐB.Ùh !40ré>ê?Kogø\}dÇÒ_ûVISìšþÊòk®7Ö@CFV`(7"‘u8Ó G+.]™óì¦Ê®ÕX·4¢ñùÀŽ–B¹ø×é·Òç*|,gaÈR²4€…F„µ)<4ÙôƒC àÝb‹àtVë_þ’þ3m$ ˆ:â»aõ|àý$êr±åp®”ï¹"g]§]еç P8íÂòÝpÐj z%üÁyíÞ¸÷‡"åÝù”x\„âZ³i=ÚiíºF3Ðvº ?1J#¨×‰»ø/‚~b¥ôÏdâN2±”¸“¨¬$BxÑßÉ %äº&¨?×,¦è…RO@oq5 M¤®Œ»‰«Ù_3rê趃—Nu]¥µk´áö¿>7yuêÅvx¾çÜt§¿Ì=ýþPß™¡MÀ†§O§·½6¿ßïi|b{kl×Èóg¾ÙÜ»êá¦ø™OÒ‚¶kê»Mn}mÚÄO®tÆ>9¾7„g²tùKj-ýÄ¥‹„qùvXVìÁëî›*´Û]q‹%´Å[õŠãa=;"l_f²ƒù—°>à‹s:10Ð#ÉyAQß½"üвvm ÑÓêÙé÷¼å¡=;׋“â¬Hv‰@ü8MtÐITCçÏ}.@G8/1Ûö2ÑíïwŸí¦®vƒ¢î®nØí\zé’–ð®&0W5}Wïá~€¤:nd ‘¨”s>žAÍB€w7V~}¶làR§>Š;¬ú’±yExx¯ù²ƒ£¿ÉÒµ .K+,tqG¹˜÷ð[â¯Îo½5_­’) bq]ç ­íMÞ£eã Àõƒ1ÑlþH=Í2”I6®è­9;ÈûÁDâqm¡òJ^¢©%’ÏÄßíuÑVhÉ;Žtu¼¸ÂŽ5œ´:hL7ðÿ#»l`›¸8~ïÝïžÛwöù#N¸KìØvH\Ç$‰‡pBâ|Ñ#’@’”° (¡KÚEб¦P m¦M´ !Ð`"$ÖªÚ‡ ­¦ÒnÕ¨&¦NQ+µª6Q’½wÕ¤IɳÇŠtÿ÷ûĤP1ç2BZoF,âhè*FÈ´É6ï8rõº¸ÊZné@îüà|3û[AUQ-Ô‡IsMë'ècáÏ)æx+¬ÖY`Hnq{$·ÛãR­nÀøÊL5êk¾s¾O|´O€Äè)xBH{·•ñ¹\­Ü:ÓMдËìc>àó%Q´8 £»™1 —äú¹ýÜî÷ܧÜ?¹saªfÁʤƒM. ’»îÀ’@(Ðx-p;À%+…oóÄ’áüÆüƹ¼HÊ~!Û‚˜i퇹‰êàâ´ÈQÂ Ô ±@‘B”8Vºàˆ0±Vg̲ÈqOÉâ°ƒÏÎ^¿ ”¾»/^‹TˆKo"g4ä@®He܆¯ÿ¸¿3ziþ‹éY0í¾iZ&OxØÞ³5ÁÜk?7yþwG濼ԧcÑSgƒt‘KBÀ`7!¶ÈVŽlJ5ÿ”N_CNé[bß{ýùu—»§.î~fþÎÆ8V)°ðˆ-ǽ±‹ÚFý)YâÁ+1•Âá¨/ö,¯§=½j]]I–R;~Ùf5C0Ëòµ:Ìw\SLaY–Õ? €µF= ý>gxuX ?þQøNø~˜ Ï‚“vsÔþýí§ûw5)·xKÊ,x´!* ÒÓÝù†~ËTn*„@TCÃÄå ÈÕ`YêH”QMsù¹¦šþ»9,~¤œ¦‘ÖŒ4jüqLP5ÔÊRG˜W£‹†sJ†Z9Ò’ÊOc9¿Î&êpmÂfÓ}Ï` ˆãPËFÒ¿l¸–-?a5xÜTððžh}»LêÜý+;Þ-·ºWn«ïà¥Y£#3ðªì/ë-¥âýù¥|‰a½×Z4yuI¼Pb\µ±¹+,cwIa,rl±¡ølU`ÿÄ£«#a›ÞÀ`éæ7gEãªgþòÕ½N‡ œü0løÒlž¿`u[½^Ô&Íè< Dcâ¹Æ–¶úµt¤ôFûZì·í ÷éØÍuïWVQ$ þ`,*ÅbQG¨Q­Q¦ñ_<àyW£\}×ÿÀý~×”Fé«Aõ¨ ÅĨ• ›˜*ðMŒy< âÁ#ü™±“ÔÛÔ5ŠÞƒÿ¶KûMÀtÜèHÜJÜI0‰„¾AÙ;íöqûŒ Ù}¼}í8¾÷Z©&jcE±ÜÙ®§ªD]'¹Ãxà‘Sãc9—?DÞÂ^Lþ$/:êòÃß#Š9Ĥy4± ¶*C›¤Ù*é6Oš¶æ¶7Ƹ¬U3nº„g t¨ìõÝ#'jk?šy¹uÏÍ3W—aä!˶m=Òq4[W7ÿN¤' |ö›­kbÌGÍzµN`àÔøxo*ÛÕýì˽;on ºÊ,q¬­†çŒ–ƒƒÍ‡¹túÊÒt¶¾ý'ï:,xÅ-|·ðó![K Q_'­ú€n=ܰ¡ÇëMõô-«é)f˜Y’5=*2 äxšëÈÑKŽnrt’c-9²Epµš&ܦj#I˶¯`ýئM¹ÍޱÊ1J”½Ê¸2£\Vî*Ÿ+|™R° Ê–'Ãý­'»óá~*'ä’9º,ÊÍä.ç˜Èå¶l&§âa”È•Ÿ+€ˆEzÒA)l©äûÿ¿æ ”ÐÐРm] 1U+^@øÑc/+À[_œH…Šjà ˆÓH-ÔG A«DÆQ!1mø×ZÕÄ3ª°¤VÚOk[‰\mvU,eLÈâí6}ð!ptÑ›[3¢e£•/ ËÊóEH’¥ì±‘8äœÑ ŠµèØ¾Ä‰Ëô8}äÀˆEÏ †MC¯(O –9#HÌŽ“²TD04 ¡NÏ$—0’PÙ«œ7 Îì_ï/¶3•åæÝvtG69pÓ”qèr:¨s" [Õ‘ `´8Kéd-Ô±E í˜ ïÂߨíx¯¨Ô™¤Å-Ø‹ëÒ‚ÃYçvãݪ.#òVU¨•D^oÔ©kUÆ¥Œ´NzFÚ']“nãÇvp²4"›¾)g5Y’s¬3>‡Büxü•øBœ9ñYð¤%§Íý]ÓŸg¾ÊÀ½™ñ Ì~Œk¦5ž¸…Lœ[ô^,\ Á¢jÛŒ÷¬ ©ÂGEì‘P$aöFŽG`äƒ1'p¶v§3FÚ8 N_ ákQƒEÀ«îq~ø1~)&8Œ£ÑÙô€H3§MÁÅ0œ¨v>é-4†ª6üÄø8]ø´>â°j Åcd§YH3Å«OAomX’6 8Í€$"ô/î=‘ËåÊÍ–ÔwRÖá;ïäKÇ%cù©h{–çÒ‘èJˆK䢿5ˆ-;cÐ9¥žJûüD–‘Á¸?;ÿAyùfÃ1߈8­ u‚Ì‹íü[û®¿gypê¦Î ÐÉ®þØ&®;~ï~½ûí³}ŽcDZÛ!‰cÇ †8qƒ±1 MˆˆáÈ2CœU„öh2Ô%j¡4LJh6´2uSÃVØdLm¨­ÖuÑÊ6iEÓ†&íòi-Ó¤N›D²÷ÎmšÏº{÷Þ»§Ó½Ïçóý|2&@s¼9 rœÌ‘B]Ë£‰µ?o/G‚ö+äµn‡#´+Ÿ­ß„>zE ÷n¯­¿ü¶gyÉ{}ýåÔ|yqÁ»ì±Ù¦V–µ••å¥bñpΣåržó ‡Ë'µrùäb(4•.két9;î¿\ö°K7tIgÈ&=Þ£oÉÇÉWõ—ô¯“ÏêÃÃûô|~¹œ_âò‹<žO{:Ë \Ÿ<ï9Î|Ÿ˜›Ÿ#£s©¹QãâÜÃ9öÀÜqÔ¸…šÌ¶¦þth·7M¦“CÉãÉ“óɫɒ·’“"nI5 ’×Ál* ÷„…×Ãô«a//y<`cs¦AÏ`aðØàÏ?d‘ÏZ¹U¸S xqɶ’„yîÆË#˜*\‰ZC´­-x TÆ %¸Äb(ÝÅ$ïRT鎯ÿ‡«ÿºÌL­67£¢Ú06>~ìòÒR1›Íø=þ€'ð_^¼üÃÅP&›Í—ËéE]åV•ÕNEç.|áVwꛢ À5À¦!Ü E†ÍZS H¸~#uGÒŠ‹„½3Ö‰‹Fg›¡EU1²B3e”|;šõ$î²Æº&€} °÷üVLþHƒ*kbü+$¬<@²ªºE2d,`"iLGobÊS#µ§ëyJ4ËÁž×œ¼«Ù” øðÞ´™û±ÏjØgãHè•{¼›Ú¿È[TE¡Õ[­»Š‘Ý>³¶Y#p¦¯¥›2œÊ™Ý}A‡–sš¡u£èƒÛí&2éõî:a)Ê5Äqhwí}Ú È~«“ê’ZVÅÞþñf ¹¥<,Åv<u7¿ùÊ„ÄCVhµ ÐR-ȱÒË›qðcXÙl½ºvv»ÖS â,¹k³q ¼’kÞïd^âä%ªŽ2y–†’`½vÿ ¿ ÙÌMq+r€„xAŠ #×Yýoî Øƒç–¿©ßìŽ2 ¹Ý‚‰¸*2Š]CÙBùS*®ZW7»ìl–<õ×>ZûC™1À.i/¾q(À,ØšêVÍs´^E‰Ö?e~@?"fÁ³)IPè,ýu3l*•°‡uçÃZ>ŽCxj2§MNærñRÞ†“ÜLæ°>†KåA]GÔ¸ýÎAèÖOáÚ)Îp½Kï%Cº÷»,º÷¸È\<õÖÑÌdæræ~æŸfì™;*“©Ï7åÉ|Éô@ÿçn: t¯žÒ‡tZ×Ï;M l"‚€ÎÉàÍš‚IHL[§£Ó©é‹Ó·¦Ùéàu‚0˜9’ÀÞ6‘(^¶ô·G0AáÀS±S~þ$õü÷0ó"ѶM{ÐgeñD©dê{f``ωå ô=ÚÛdäF`ó ÿ ¾uaÆU©÷x3”ì—\=‚Dè1/¶âxT©#Ø™azTèÙщk~°:±ĨuÓ àN¶X·_ýêM0ëäy y ‘bx ™AB¨ZE•çÅîsw³‡î4(ÖzhFLåEФ´f¯ìüíQ[§7Àq–µã§µ¼YgwXRb‘©a5Mî=[„ùw]Áú€UqÈáÂ@ʨlÿ`v31Nü;ÕÈû€­ØísÛÜ>ÛTqT+GÝèÎwª;­uw§Ý£ij€éÐãËm-ú& ú6RÖYÜÁŒà‡!÷ë{pÇ@ŸÞÑ® ¤3ÙnßæV½õl+…¬bsÊ} >¿ÿ þÇøÃ8û³8ˆÇŽlEB®ƒXÊAGú.dÝÙáüS…há@*Ž©€ùz·ÞPiI VÉp/fíHÚŸgÝqÍa`3Ù¸A´¢Ÿá`*êôÃï1^ðˆ¡d(~%Ëõ 0Ñf¯J=úη©•È ÁôWí&v>è0·#\Røi_H‹:÷Ýÿ¼ÃâæzŸMUQÛ‰Ûìß69çߪ¡I«g J´¿wm  ©–•mÒùße튓EVp®ÀuâG³Z-MAøÒ6N¢€Üpú“-ÍÖ>NEÀaIäiD “(ɧú½û6ܳ>þ—Oåx›l)q, ü†Eâøï¬}V  $ê_ûõf+[$É,ò@DRÍ­†“@lîølª—!‰TsÇúßéO˜^âñûTG D-’Éb"­á–¦FÁ"‹ÞÕ£B¬·w ‚Ó9é}}ÑáÞü6}è}péïmb˜ðƒûoG-8qÜKµD½µ5Jö  mDŒ…ˆÅú ·8&œN°c‚èýýcý¨ dZc=›Á‹àiÈ58œý?_ù0\ëÝèØ ™©¯ÝʋȖ¶·Z¶wüõÖ¨Õúùw›ìrï7~“©EÚfoû/¾ë†´¨Ð$E‘L·Ñµ¶¶öËK\Ü¥vŒxY´s¹úÿÐ\­Am\gôÞ½»ÚBÒJZI¡'b…„¼,£5ch ðK0¯zÆ1ø•ºŽÇNÃOÚibOë8n3Î0ýQ'ÓÔuÝ@…tâÆvÇcò#¶Cʸ™ñ+ãaÊLÝ4mŒèw%¼îîܹsÏ9ßùΧ-éÀ«øÏ:=ü£Ë“t¾2¥FÏH;¨I qê<>Ž! n“ŽèÿWë{>Êü{G@£#ø¥ŸzÄ·Y5˜˜™ìDãˆ1¢NÄ 0Ä]ê>ÉgÉ5‘ÁÍb¸x¢—ùtwæ¿ÛÁo?Ïãa@­mRËÝc.³£1†–Þíz é.š®íŽÈªÜ)÷Ë·äÊšqÏËX–Õ….‡ÛÊSÈŽ¢Ð‘`u¬Ü(@9€Ðž}…ç‚0”Q`àG X©Á;$\êf .b£h®Ä‚!dŽb³®Âø¯ã“–a4ŒâšÆm×±w³/J mÅÃæ ã[¦¢_Ù7{掘 p–üûãmy~?¿8"…ol29·ø(‰&­b$s}ˆCûUBa˜ŒÀì–ààp˜Àøí?© ‹<‹C— K`QÍ';¸qî]î·ÌqÜnŽáÂÒ…hKµITN.Ó}jÜ@3Œ@yÐb^‹ƒÀÝÜÆÌ+™“)®oåaßÌÄpòêÓUÄæ¯ŽÓÆ+è´Öãá—á*#¼ÏêËg ¾{|~nX}Lb¤5 .Ì©¯_ à3¶³væ†þªõjÛ.ö½Öë‡mä|ëù®÷ìä¼þ¼ýl„´ÙÚZ_«$‹­‹m íä®mÁ¾Ø¸°™½Þx³õfÛßÚÙëù7,7­d1ÿ Ë—V‚P}~cGKXNÉÌ-ù¤<¹¢eÌèð8²۱ßñ‘ƒœpÜr¬:ˆÑŽšúaA×1ËøTÙ¤sUðþÁ)å-…Q”.ÐêÖüéxK·cúBü^œ1ÆÕ8ŸÅUí_À…OHX X¢¹Š‘zh¶µ.e‹2µ”µÒt:·Âí±•4AŸ4}ÐÈlÔçžï&âõ8Í&5*Íl‡E¡C–PIR]óSR®)ðÈÊæ€M;¾ÞÝ[ñôˆiihN–X4¦²B›9oÿÅTÏV•g¡{a‹¥Pvæs™'¬sή.«eŽÚk§è}Ã4Ú§l®ÛV7[w­Ž­qqN9ßrÎ;:5ÎIyÿ@ ¿©\R˜N¥_WN*ôãʲ" ET¼JDQ•ç[Z-Rp•²æ¤K+|Äû+É—¡ÃQ!²_YŒU(bžíe(t>…")HM¤ WLöZ=iK";½ÆlVx­”Í僲Ñéˆúh4³­NTǃ‰ª Œ£k¼p."ù…}Çx# r Ó¥oM‡:+ûí¥ÿà¥=;§ó< Ö ‰Ù…»pe²cP›g*oa¿æòÌ– ¹ÌíÝ{{8—‡µ½R:¾»yŸ2t¨«© 7þò…et[@÷BògÙwï_üÕœÇâýë“Òzgu”öÕ¯ˆ—Dýâj1¶ÌbAÕ A~BHþè·ÿž{† ƒ©®÷âQšzÄâ–¢Þ¢‘¢;ElÑ,ãUcªØ)ö‹Å×ijâ¼È#‹¢WŒˆã"+^F‚(¨B§À. X~$<ˆðÌ/~“Ó§$¤³µƒRPKOÓµ©•ûä»û+pNüY†Z¨ÀÅþ5¹Wn?7:~eàðÇg~ÖºNñE“%É’íë»~;Þ~tf㖆÷G'®ï‰…¼J½ìj{gz.†àf«_’G\J &ô{µ&(ڵ˜nFü( ûU~ÒtŒ¹f|º†áÊGåSò9ù ùkù[™ ¥è’;¢ü5?^] ½Ý]…{QwÍ´cß¼›'[R½)&5Håש[Ê=#1*%¬¤” å±¢Qž5çH¯@_zz?-> Ú &‹9§=j%N*7Y¦aAe•èr!Ùf%žª)Jã3Qʼn¬kPલq‹‚géQèÖc öKx#sj0ÆB0É“š Øã;íµ˜¿~µã7ÛêÂîÛÝS½N#ë›ì:øîï^iû1sÛuxqW´auyùnÚš9‘iÔ¢•0cæ^S¤éçŒ £³ý=ïÄýZ{©~åtãgHo¹üÁÛ–RìÛW’©B!´}¦Æ›­øNþmÃm¡]ldWùbUvŽ%^6/ÐÛA ™D“×1©&ÎD…9¸ Çúa-ظ®fGÍ–sÚø`¨Tª‘Z¤iDâ$iƒê õ‡ÆCó!‡CŒò†"ð͆.hihÿ¥eµƒÈ-ºUw§›]vcÕ}Ê}ÎMÜÏ’Ïù‰BöM‹KPýYR²*]KÅÔþïOŽò õ÷ÿ]®1mg?ïyÏ{Žï>¾Ìåcƒ1¶±}Á‡„kà,æbb'Ì¡ $PpRªÞH³.]Ú5™Ö®»·bݺD»t™¦J“2-«ÚFlÓ¤vù`>dR§ %¢IYì}&Ñ1øØ:›çyþÿç÷ϤŒ§]à¬Ø ÚA’À+1hetKî^2 Á£ p©3 ˶æñº—NIí½,h¼Øãìé:¾P¨ªokìɵ¦†6ÿÚÙô©Í¾Cñgºc4™j­FÓ¼ç79m¾V§’F¬êª†?¾Öpq°Å²T¸ßhµñ4k1ŠCѽXûÛÛPB­ÔõSÙ&´ÍlãÕ{•Î&ص~Ðßð©ïw^í¤;#SA©Ó“q‘DÚâÔ|ÜÛ;F1`;3æø55ln7/Âa×lbx>R‰À|`=ÀPTàrc£»ö@jâIø|@ ZÀKÏüo)£Iy<ñ;á3·n*óMœHËñ¥Øle[@)` p7ebÒÅ‘«­+Õ¶…'a± Dã±Ç‡<ž˜ˆ—ÄâÂ`þ!OÃr‡÷ù mÑV[úâh ìÿ_ 0r#å†FŽ˜5@k˜”¨ç0ë8óp[Ã\ÏцêzÑÛpHk±Æ—A-kÓêŒÚ®CšÕlmK^›^­VAA 0©DHóV• ›UWUX>:ã5ÚZ¾îDÙ¾WÂn·(ÔTú,5u¿&cšÒoÞ‡À(ÕK SÓÔ¶<úÞÈ•#ŸµÃïµgägC=ñØë“ &pj2ÿá…ÄÛ‰÷0‘ƒ«µÅZºvÍ;Y™½„i§X‡í˜V4Ÿh>Ó|¡y¨A!ÍÀ¸3Ö‚ ¸~ K‡ÆM܉±³c¿ƒcã²Ñg¯Ÿ¤¢!Mªoj¹³ó$ºé\sÒNgö,ÕÚÚN}’)ìmELJ+àŽ\¶ÚWì£û?6€U0¢‹)Š Ì>€0&6HØ,lDš d6&RXQ¹äÆ&¹TRicºrQnS"Û¶€e•C^E>¤‘^ÂCŠ©‘›Ùã¾’ÝŠÏÈÚ¨+ ª¦wÞ(‰bYFJ{˜…øîv@ä·3ä`Ðuðm/×ë+ßúý›ûΤ㭦ó:»Qgâ+Ï!0þãƒlevÀã> Ôg–:ž^ÿÖ»¿êK½èqÄŽ„FÏ,Í×~íØŸ;ãÎÖŸ{O¥;ö²Í¡*o¯·ªMÙŸ|ý†Eã+‡È¤¶6ñ|-=ÒÓóÝÚ­‚5¢b¾Th;xqd0ÛX· [è}ã϶¾òê7.½úèoÝÉ…¨3éש}ob°ë¸zû!ü/ŠR'¨ë²ïÆþÛ®ÛýðŠëJÿ œ˜^š¦?ï{¦¤l4<ÉF5Æ)óuìò+Ûë²uPÌ÷QSDzùÌÔ‘l^Ó÷”›k[ŸËÚÎåðì;~Pôÿ h•ëQö¤˜^ægOÌ.!B2J¡ $.£u$TâQ¿u!t€7á\‡÷!‚`•-℺lrÂH‰ä£š%c­ˆýãdåòª®¨£u³ÍÏR/ÍKK#K)iŸ2¼’Þ• $uÈ»Þ~¯ÂÜó;[q£@% ¥F' §OcÚ.Pp‚)XˆxK‚…ñ¢(à,X «ˆŸ—É)é§dì1S÷ùˆÛ“Hx<á4è@î¡ §Ãœ CöY!ªÛs¨BÿíêJ¤E&ïÔ˜h˜?ׄb¢o¹ª,ßë§AȆ|-[ë[«ž*³VÅ!V rÈ ¢Ö @¦Ë¤#E©ßü'hEJG5S×ä`õ”S+VˆômñŽøoñ‘Ȉ¸î!7îÝ`Õ]tßso»72jHÑõF YxRîö"D,à5ü#èõa£(ŠôªXï‰ÛøÎò¼@ËB ?ÝÖ„uá¾ÀQ/„(‘p©è §ñz|Þ$Šlø §Òä“’Ÿ&5ß­8·SrRpãfâzøˆ+ Û-fÜŒ´w —8Ri­óDFTˆ¬ëA½¥OöùV=Ï!5äêbÞ¿AÍ|è„}~ÑÖòp&8Òuf´¼ñ‡À3Ü¢7³xky0[on¯¹ùË‘6Ù£Rá8º½ÿ‚Ú¨—@½êîÓ©®®ù™iëÌÌtGWׄ×oõzý]Þ?÷ÌL§à¤'ã™ss‡ã_ÎŒ’™ŸÌäÈLkWÀ?dÓBd^Ô˜¦¬×˨p¦=ÓBPÅg­3î™èLç Ó5ã……¿1"F†"0²þ%ãÝ“šÖå+ó¾|2ÏTçA~4Èû.¤ßN¿Ÿ¾ž^K£¥ôjº˜†é¯!j‘_t.†åÅÔ"»8ë.,cº\³óÈŠÞG ±B¡sK»ÍÁ­á7ïb´ÇFˆ’„þ1ËãîÑGrcãîcwlÊm`Ò'´Á 0/ð·. `Yà ·HŠÔµÃK]T±ËèÿŸd«¶F;G¼1'ûl§¯ EvbÁÎaÄÞI2êÿ/÷ئÎ3ŒŸï;—ïÜl_Nâ8¶c'Ç! qœØ &vââ˜ÄIÖ0MR.!#4D@¸­ ƒ©4Ó›4X/+(ÓhëZGéE+BµË4Zi©¢@;UKÕi”i¢Iö}v2úçdûØç*ù{Ÿ÷y~ï“— é•€Í!ÑG¥IÚJ@Ò3wm® }Þä}vÉ<êÞª´-n@FAH^ßϺ ®2É Ê}m_KŠ5yš<=ÁÒRF` Ü»Bf[§ÁYï°0`[]ø\áD‰æØgoÜÛ^©ëŒUê‘y]ÑÒ(²s4Wrü Uh,ÒóÓz·Aæ$YCÛW™ž¸ùh½ÍX·*™Ò,‘£ ?STW´W¹ÜHdœ%ãMÖ‚>QYFF"‡¡‹çy æõG{ŠJðZD‘³c>ÚçÁGlZI]Ž[?e1°˜PÃàM˜3Ñ]¡'ã Ò2ŠgçÐdq[H?ß ñ¼`eémp—ñ‘ˈ0M& èÑij”Ò}L?§3q½KÀ?¯é¬¢×à(Dð§Q×ÕD ¸}³[ˆˆ0-gçï?|Uò¯ûÙì2'çCtœÊZ‘|b*h¹n9ÅXÌÿl‚9ÑäÇÓ[;À -ȇ%^Ñб ÏŽYhW“¶—F˜ÛvATJjÐ׳¯e¹1ƒjDŒ( 4ƒî}Q°›¥ç?ýâ‹}>·ÉŽ×®tqãéÔ `‹›o¬¼‘¸1A;J:Æ™ìsÁL(·`Í™FñéÌP&+‚Ì |äÉC™øóäTÓ¤hö˜¾c6t¡ýj;lÇHòÜ6 L¥§NMÑ5±5pÍÈZŒ'ŸTÁϱ PA¥00„ƒ##%#ÓG>IOú^Ž¥AšœðGF´Þ}Ó8J_4ŽÆù.~€ã'ùSü9Q¼Â{ø|ð?Ã#ÁăÙ¤xR‚\ –ûX!“àý¹\AÆshCJ1Gø5ï¶Ž¹‚Þ(_ý·ulŽô´Ö@"oyYjÍ0v`<úÙóxC¼YË3ކá…ÓH“â¦õå¿I6A<ÖÆÁMœŸ-ó1éó—àóËÏRb|–å×à&à#)Wœåv•C»Oò­N6sœgüvoc²o{uæGícmë°× .‘9´Mõ×l¨“<mѼ£3:^S²¨¹X‘síÂÇ]Ø£î· ÁÖõëN´ò¸EãþrO­{ ú$†•LÎÒ;iÂÁ*”˜#ݘºÆ}åƒ~Gˆ­Éö“ßÚôù mÂÂ’L~€€xY6ùO Õ‹¼4q¥VFT ,ÀSn2VfycËÞcÉÃ{ZW;µ…™Ý8¦ œÌK<À2eY¬Jßâ¯w´=Ù°·yÓ±w/üçƒ#»{öƒ·×ÿðéæ6µ¼øÌ/ÀŸzå°«b‘zãÜãæàµ…¯z~7Ñù§M3ÓWÞ!ÿ¤`þ_øŸ¢ê©6êÝxDwFœÐ¹*º¦©‚‹·ªÃ ¥"g5 ¡Öm;ÜîÛîÏÜÿv³È Ü(Þ¯KÁý6Âdê 9EŒö« ;žpö†.UõF§¥d"“¸šx?Á$†¶{÷{_ðžñ~èýÌËyS£êèŒƤIé”4#})±5R\ê’$rˆ“òô?„¸äý¹åxÂäÿ Í/ĵ`Ê má–ø³ üÄR#.ˆËø9›²Ä)È,K{uµøN"ÍB·˜Xž†+¦¸]Éh?·áå?O|4Ò¿×b‚f!Ðå0±ÏöŸ>‘±¢ùàw~}å'±‘ùG’€D«lVÕ—Áe°»O“‘Åમ«¦¹˜u÷ªú;¿úî¶y®«ia¶ÌÊpf¡BÀ2Ê ¯T¦=u¯Oýòú R—Öù‡ô<Ýç².êçq×ÍFp·¿o'a$z:z3J·¬ŒÒkÓe·–q‘´ÓÝÆ+é›i˜Þ•¦°`¯BëúW!ßÁÊÞDÑ(MP¤6zbúC0Ç1 §†ºÂà½ð­ð½0íÇÂÙðPx<<þ{…Ù=ãX‹Ù¹y3Ž&åá}"H²ê$˜p%–W»Cv¨ÓÅj5+Ê»ÀRR`Ì+˧ÍrXq„üª±„ G⥯Ð8cr‚&·ºp¹èÎ2H"ƒ ùR8N*5Ú±ÿr ×2Ì dÆ#…˜ʼ7úx¦{{Ògà§c ª:´áTÇêîó©ÝQú×…?v{ŠÊ›÷~ÿˆZa ¬ØÅÑ¢ bTYV(bGýï_:ˆì±Íïî¼ôOÝ)™çw¨7¯Ý<Ñ?™9ý ^DzÅyx¤Z©‹ñZÇ©®úØ6Î2~ï}úî|¾×öÅÇvâäìø’Ø±¯vÜ$õ¥qZ÷#NÚ4kìÌ˺4í>znEË(Ý¢iÆ@í4`›h(ôŸ‰JýБ@ª¦vÚ ªT´ 1$@† 6ÖðÞ%¥Å>û^Ÿ^Ÿìçù=¿D?1¦ÞˆXLÂ͈4!¡‚K@b’ª®NªTÃ*þ]õ¿«µwè\;3\©ŒeÌ”1NBÍxËÃ<žo€Sz[ ëEïtê"xQ|Þ`ÿÎâ“ìyÄlq§åýÍqø#ZÔ‘Ux4õõú£qHûõ àjyÜ,8ì›q,k¶™kRe7³ì¨ð!𸅗dó"L7ÉNq$m líÈ£)4#Wr^‡°££g@jÀY1Àb! Ñ0 Ÿ“ŒêdmÇãÃóYdžv‘b8°Q¶ êÝR?wÒÂØV/dãƒj‡ÛßÁz iõÒñ$j7Oq4göCµ¯¯¯áoCØúµß*+ÑÛ±;=äûÑ›±[êïò}ûMá¦B|ÌlÇ_n9pÐþ®bvIì‚b’}2å>[ÁÖ0tO)IÍôñÞðŒÄüÂЂ"°íÔ94wÆYì”7£d2™2“ÉÁÿ°€c{z1¾Ç'ãµøbœ€q#ŽÇ¯FNcÂ0LÂ}°?‡LꟄç!ÎbŒÂ_‚§°ü׆ínš±ûF*³Þëæi#»5sè8‹.úªÈVÑÅ¥>Å5sÈêX=²æT™cÊi§åÁMnózBi¨eäL£Nüì4sOæ.·rl[n –H<øwoïîW²;ëÝ(±¬#xfhhw0øûg’_y-óò³Ò_îÁ“\¾¿«$›yz` XXØâñ¦Ÿƒ©§v öF"3ã/¤Æ¾ÖŸ°yXiÉo·¡ ¬ÿ¯w_Öí©þ$‘®8Q"}A½M÷0ô¹0‡[GùÎNÙa„˜¶¸È幨“Éèz0z{ðžž}£(.Ó7M°WÓ ,ÿe*QEÑ]¼oB„cñ†É¦ÕqDó„´A&YÙŒYÄ1Yh@f,'’Í€`ˆÄÝ”¼+¡J1œv¾=îB|ß*krÑÓŲ®íbÎÑXÿB÷y¼9G ÜÞ^)ôÔJj-u/E¦îbz Ç;ž)ðÛ¦Å`%½(Æ\ˆ®EñO£ jÅ4wñ#ôž¿P\.Þ(á¢Q\,ž·>ÐÉ¢^œ,Ö6/1WŠ€ÅŠ`kÑŒ(',«ØÜp‰U‹üï7ëùælºTUÍå6AYu§½ÙTH™Û¢xóe©0ò‹i/j§hÉÁ ’däß0Ê0°´Àä ¨²ñ% ®fÇSD´Õ¾§]>âG5÷Níúf‚"@øXÚÙašâ9œ8É2ö.Vßšj÷R@pNÌÝ>Š ?@nÀ|T$œ8Ž»¿÷j‰¿rhËpÒ÷}-ä½çIDP<„f××ö}-Ð|[OElû(ºi¼­Tú''ÝLÊ&yÁ)l @ÁIÑX¿¿þ q›±qìo:çñ€×Äë¯éÝra4\, ¹E’å–áÑÑšD«`KQR…=™²RNÒB™1½¾Ç’½ §GW  À_˜…QY‹±‰Ø‘ØéعØç1:{9†ÇàϺÓ ížF`Ô&µš¶¬Qç5 5ÀU]n)bÈ>-óäƇ‘™ºÄ¯òŸ!CÕ¯¿§/Žãã‰z³z¢žËm²Q.çGƒ–ËU1_¾>ôPW,_¢,Zêó™'Õlz•ðxÍѳtBb¬šzoÊÇÆ|mö>j¶4öš™zc¯¹ "J¦.máO ¶º)Ãë )ÚéÚ“fP[æ¢Ûu$ZÃ̆>þ”½÷BíÙ™'$1,¶i¼ðvö^Ïx¾J2 ‘O@Ër<l"Eq-”ûÞ¥úî¿›Üéàìm,p ’ Ž"¡ ä+½c/µ†¼å“~úu) ÔÙ¿¬ÿ†:B´`uð†®,¸úçRÄ'V§WŸX=¸zèÎ<ýáü÷éN?érÁZmn¶ân¬¿uÎÏ…ëïè§µÊPØ]©ZBÒ´ÄÀÔÌLM@Ë~a~Þ€¼!_››«AZ¹f4¸À»Ñ6WŸ\©€Je†Ÿ[™óüdy[yŒö–»Ë!š.¿PÆèÐÉÄÉüÉã'É™Š_ÓJþù9BŘGÀH¼¢Kx)_--—n”(£´VÂa ”à²îú† ¸®)ú÷ú+þü¤¿zô¦ä•eåŠrC¡’Š¡,¢Åв¦ÐÐ š—õ(¿€‘o’ÉkäI‘`4tcÒ¨fœ7pÃX4î„‘@€jV7 õe9C [&´LBGQródb¬ÙÜj4MÑÑ?¼î߆Ü’…@Möü,í`á×—]œSõ €€Íæf)_ ÇÚ'®þãÚ–=‡Ä ¡yÚ$1F–Õeg=íœöàO/¥Æ?Üñ_ª«?¶‰ëŽ¿÷î—ïùì;;>û;vü#Î/Çvâ8áàH.¿ ê%‹‰SŒCBX¥ù±AIEÛô(ËDÛ14µQµµS+ PK±þ€‰îu“èÆþh» :±iÒ”iÑÆ&%Ù»3vòÝ;½÷d½û¼Ïû~>Ÿ}[cž »…šÈ©`,gµ±ÁíkýÚñ² L·ÜëL¬½³‹T¶Ó°?ÀY9‰ÆpS¾õuê;„ÛOÃ×õÜŽÝû'¨îÒΡ±ÝãS÷¦™Ow~¡|®~¹óËÌ3lK™¢¨_럞™Í´ôg³ÍeÓSS^e6“™V—ª*ÞælvdÊë"½u*;«4{-@ëËm3ÊZ‡–ÓIû^>”›0:Æò¹}¤ýénÌUWä"Æ`5 rŒ1hq棞·°›çš_j>G¬—7@‰¡@¨º¢ù }²‡ñ8rg ¢ö©Cê•V3â¶À6´íO@“´¨–ÔæµmQ»ªÝÖøŒ6ª}K;A:niÖ¸ßiPÓæf Jâ‚H‰¿@èXv J ™ÂÂÑÂÉ«…7 ÿ.ðl>¹7 3“#“Ó“ó“´4¹0‰&Õ’0yµØ˜dWÕ™üqõÍQÂü gn„¤‡¯ÿzPO¡¸]º®™Î.iä2ÞM¢“PUBô±y 4- iäb5IÝ M:§|kDWsx£ºzüÈ4E¡ªÉæØ•€÷Oņ¿7⮩¼-¦1JYïGRIeÖÝÝà G‹}%åHíÞÊHQ]\ZWç~Ò·!‰ˆz´òÌw÷×75BÚùCœõ–zB”èL¹m§¶Ô¦Ê!es•D¡}{°PF#»Ü9ñî‰3,/ykв·Ñ$ÙÙ9†Gœ•±Hs±çz]ž,ÄùS‹ M[žÆ«ï¿˜ôÛ"ó Ñs?Ec‡Õæ~£·vg½»ÚË—Ø,Œcm4ƒìœC\veñm–å×rk5C)`Œht¹˜„¿ÍA)¯ú¼„ØÒîlÖ74¬P´žÍY– Ö£}öTnS†s5¬Û—£ÙÇÃY}˜šP ¢Œ©>±2P‰*—à zu4Ù’ìI>™<’d@&ÿ*åo`¨ãyü þ1¾Žo`¶Oc„ ¹æÁc#ch̰û3yCy‹Ä1t—PF!v˜5q–Üm„Zî¸XÒ]ùááiEr‘«º>’õ¹È²ÿ_•sk,šýºâä2éSB8Ñâ1”W.²Âu?سŸA¢¾Ä*{îÏz Ïv("+ÜPêpÈ4fm„†IˆA£¢T4¢iÁ-&Û»[b4”c­^D¤ÕÝ—®÷E}"[VÕ+@ÖÒÚ¹_—8 ó®Í‡@óL‰(À· R”ó»S¢£¾6€±-ç–qCOÙ”g–³vÉÊ……8ÌZ0Í8¬Ø%(Ûo~ÿ)mÏò®]§XÆ;y‘Ar!b-”Å-DínaSÔǬékJ+{¹JÑMW…*Ê(†¸ ±ï½@¨FU¸Å…KiÎFxѼþ_ªœÝàGzðñ^Èû’MMÓwAÈóìjÒ·ÂÅ­pëÖZ·»£Ü0Úɘ°§–mšèØÓ…“ñ¶&>æVüGË?ߦ )Ê1å”rNa%;¶mk±Çc#±éØBìFŒÅz_'ËMäÉnϨ‰eS ó+Ë$÷UD$Úä§qÇ~3dÜY,uÏšåÀcl¹uÑpU”»ï¤¸h•i¸R÷ëÂ#‰ˆìÕèI¹ñ¢ V†CÍðédƶ¸|//Ôô¨–Õ8y—•¡ËqÐAq–žÖ¿Ÿ,é" §ýjÝÿGí@§Ób8™·­¾Ñê¤ä“­ìß<˜g‰õ¦BYMÄ)@Þ:žj·±å¢ÌÛO[-¾v×Ö~‰`uAgð™ŒõÞµª9¢à˜Þï÷[‡1†ò° €a(ž÷¿ãÿ™ÿSÿïýŒŸÃ² ‚ý€"Þà刻L+‘Q='â œÄ:γ¶€ïb 0;( Cœ˜ÍϬh«š´Rüå5‚dÞÈ.ëÄr©š `Ê$6™' mÖQ#ʆŸ ¸±œá ŒIõ½õYü™ÉÉg⟽uäpýËg¾Wxí`ØóÕ©ínêyÖ^c?Þ»éÃí/þÑö=·½õZ×øGMéŸw]kí{ž|éÍÕ»¨žÙB> ® DôR•¤F¨ij‘ºH‚uƒB’aFÚQT’eÐÖFÖ—r„áÍ\ŽÙrï2aꥵtËDl¯¾ÙýÀøÚۙ‡#»’¶–Õ¬Í6fØõe«}KßùÈLÚUwéT½J›¢”.>9pª3r¸«‹©é<ÅÌMdáVÍ0Z%¶6JqÒÓ‘g@f~òØlÍê´{¬VŸ×jõr¯8HcózF;<^±•8nÞŠKÁ¹è˜VÔjvTXõ±NaQÄ+dm4p ÃØF8 X4m>Ä×óÍüþ2/«â«ùÏHàêiÕJxÞn‹îtWè …B½äáƒ^Ùï ´*¥èeBÐå ]¹¡;¼;$P’4‡r]!!77Të’ îÑ‹ˆ%bEm”óö1µœŠ9AqháV¾™·:/ y· òY oQqiwn0'êˆÛZÖÊΕò0#„f!ÑÎéPvõéÂê¡(LªîP¬Ýb­-¾NÆÒ‘Õèd¶7p´ð¤xES¾A0TŽº Ò½T}g` ÑEßOË£ªTñ`LÿiÛ"JÄÉyï¢{ÿÀ =ºAùíw³Ã”‡›£›˜ßˬ–ssô…úD­B-uKeöüÒìœ*ïäâ’ †k®W©´qÒ•:ÛUìœøüü )¯‹—*sù§ÑlJV³LžÝQœ3Ï]¾ÉЩò_K6#A*eöÜ1 ëÆmËòKe‘Yï‡ GS)ñêdôÖ°¼‹ÑC€š)8ц¾)›Ø8fNIm1AG•Ò¦$‘žD%˜AY­lVv+¹ËJFIÔôk(ˆVÈ#^ÒizD×l’#z©s¸iÅŠç}t+—Š*ñ¢SJÄ-]6V²ÊäML|ÃäwûÌ%ù;˜‚³&à4ù Éö@Öxvd5hãÎHNrØÌ™ždkcqõ>·µþ¥l½Z?:Ãå‹KÈ›í ¬µÑb‹•Ƀám´ÿd•€œÎxÅzÂU@Ù ¨rµŠ°Ðø_ÚB# ´Ëê&IW€äë´ÕnÒü€þ4~0¼dœŒÕ€‰6néÍjÂ'€åâldßÞ8t@Và,\Ô×½(ȶxþÜ[Ó‡°MxzlÏÁF0‚Œ`ÿt“f¢÷ËdÊLHbÒ 2<¶°œT'W(U j6Q—”̧¤¦éÓG2Œ&³e4löLGVvŽ3×åÎË/ðx}…þ¢gŠcJJƒ!¡¬ãÆO¨˜8iò”Êg§VUO«™>cæ¬Ùsjç>7¯n~ý‚†èç<4$Ýæ:þéÈ–Çû:\Y2Œ~øà°ƒžFh‰5ebõXƒõØ@Gö£ýæ$³Ál4gR?3ÊÐ0\ûà/âõÈ„†ÁŸ7nèÙÓ³»çÓž 1öUØÇöcQÌ =‡dŽdML–‘d¿0O#åLC²„b›“YÒׯdŽä•1YFò®ÊŠÊÊ)åΊ†–†¥MËýŠJT*Ét9œ$7 …°MX†FÔ`!Âh%þEý£û>Më’6üŠ\”¢Õ"¢& ù}h¾s`vP‹œ#I|»[c‘„2æ^ù;å!*”fšÐ/'³¸×Ë®ˆ1/Ñï>ûòõ5õš’ß0Jí}H½'jáÐÊrO¤w`«|]å(¿ETÿ×HBtÚ endstream endobj 2112 0 obj << /Length 783 /Filter /FlateDecode >> stream H‰ÿüÿÿÿþþþýýýüüüúúúûûûøøøùùù÷÷÷ÞÞÞ®®®   ”””’’’“““•••˜˜˜±±±™™™–––‘‘‘¶¶¶´´´›››ªªªššš———¹¹¹†††°°°æææ³³³ååå²²²ÊÊÊää䯯¯ŽŽŽçççáááãããÇÇǸ¸¸éééöööñññôôôØØØÏÏÏÎÎÎÒÒÒÖÖÖÑÑÑÔÔÔÐÐÐÓÓÓÃÃÃ|||pppnnnssslll}}}­­­ÈÈȤ¤¤xxxjjjtttqqqmmmÕÕÕÚÚÚïïïêêê½½½ÀÀÀÆÆÆ¿¿¿ÂÂÂÄÄļ¼¼¾¾¾ÁÁÁÅÅÅ»»»bbbîîœaaa222 000RRR«««ËËËvvv''' GGG§§§)))ˆˆˆºººÉÉÉßßßÍÍ͇‡‡888OOOóóóÛÛÛrrrµµµÙÙÙzzz KKK‹‹‹eeeÝÝÝMMM„„„,,,èèèEEEBBB···ccc ………âââ"""€€€ààà---```¨¨¨PPPŠŠŠ¥¥¥yyy555+++DDD^^^‰‰‰¬¬¬666***///iiiŒŒŒ¡¡¡AAA333IIITTT...£££dddCCC@@@XXX¢¢¢ÌÌ̦¦¦~~~]]]FFF???$$$ YYY!!!VVVSSSwww%%%QQQŸŸŸõõõUUUuuužžžìììZZZ&&&;;;HHHWWW777444[[[:::ooo999111(((### ===\\\gggkkk{{{ƒƒƒ___JJJfff>>>‚‚‚ÜÜÜhhh©©©<<> stream H‰ìTwTÓY~¿’žP’:„„ 5´P¤H B 5€€"ˆ(EQD¤ ‚ˆ Š# 6¤ˆŽ.–±ÌŒ:†Ã(#ë2±nÆu÷xv÷Ÿ™w¿s¾wï¹÷~ß}¼óz¹°*€HW‹D–ñƒ à3ÀŸâ?ëË\˜-‹&2šÊÈÿÇÿÐÏrú˜ DG?ï#ŸøGÇ……ÉL“ Ê~JÍž|¦­¥½­-ÇÊÌ’é!JŒ—¦å2C¼Ý™ÂŒ´ i63'3^(br˜9²ÚgZøßïa"Je‹$2E¸X”/–$1ù’q®8CÂK˜²mÿZö™ÃŸ”ýòdÒ ­ë= Çš…[t€üõ&@i$€Ä´É:PdT4óãŒ?!Éb„öÓtQ|Î' è?]áÚßqÒG?$”)”fçý£÷ñ5`È:PZ@ɾ+`+ð¾ „‚(°A2HÙ ƒRPªÁ^p4ƒvÐz@?Ãฮ‚à6¸Y°žƒeð¼… Q ¤ iC dñ gÈò‡B ((J‚$*†¶CÕPÔ u@=Ðiètºݾæ Eègè ŒÀd˜k†°9̃Ý`?8Þ'ÁYp!\ïáNø<_oÀ÷áYø9¼‚„„0„ƒð>ˆD#‰H6²©BN¤E¦‘¯Yd ybQÊD9¨#ꃆ¡B4 ÝŠÖ ÍèqtD¿BçÐeô=†‚ÑÀ˜`0L$& “©À4`º1g1S˜û˜ÌK,ËÀ²°vXl6[„­ÁÂ`ǰw°óاŠ3Á9áqñ¸\\® www·€{…'áµñVx/|4^‚/Ã7à{ñ—ðwñOño ‚!@ØL¨%tF · „·DE"‹èD %¦K‰Ä~âñ1ñ‰¤K²'“Ĥm¤FÒ)Ò5Òé5™Jf“ùä²”¼‡|Œ£â¨†TOjµœz„:A§!4=Ÿ&¤m§uѦh t,EÐSèÕô“ôú²UÉF)\©@©Eé¢Ò,a2Œ4F-cñ€ñFYSÙMY¤\©Ü¯|WyUE]ÅUE¤R¥2 r_å*SÕS5UuŸê°ê5T­¬–¯Ö¦6¥¶¤NWwTªW©ª«k°5B4Š4ŽhÜÔXÑÔÒôÖÌÔlÒœÐ\Òbh¹j¥hÕk]ÒZÔ¦i;k‹µëµ/kÿÈTbº1Ó˜ÌI沎†ŽŽT§CgFç­.K7L·Lw@÷‰Q§—¨W¯7®·¬¯­ _¬ß§ÿ­Á€glpÐ`Ú`Õea¸ÓpØðK…%`²úX(F.FYFF÷Œ±Æ<ãTãCÆ·Ù0›ËNf·°o™À&¶&b“C&wL1¦ö¦ÓNÓ‡2Ç“ÇéãÌ™1ÌüÍÊ̆Í^˜ë›G›ï3Ÿ6oÁµH³è²xdIµôµ,³µüÙŠm%´j±ºgM±ö².±±þÉÆÄFdÓfó5—Æ àîäŽs³µ³Í¶í·]´Ó·‹³kµ{È£ó‚x5¼kö{wûû ö¯lrþæÈqLuìu|¶†µF´¦kͼ“®S¼S‡Ó¬3Ó9Îù°ó¬‹ŽK¼K§Ë÷®z® ®Ý®OÝŒÝRÜN¸½p·pÏv?ë¾Êwàoáy ÞU3žTÏ0ÏfÏï¼t½’¼ú¼–½¹ÞEÞc>?Ÿ}>š¡ G°ìkç»ÅwÒì·Î¯Ùï{¶¶ÿhà°?àñZƒµ’µÃ P¸?ðI+(+è|068(¸%ø‡Ëâéu´u±ëz×½ u­ }f& — ï _ðˆ¨‹˜4Üy#J-J5‹îŽ^Yï¹þÀú…nLẼ ¬ ®oTÛ˜¶ñb¬|l|ì™8L\D\oÜ»øÀøÎø•M‚M­›–…|áAáóׄú„E‘“¨Nô4Ñ)±.ñY’SÒþ¤Åd—ä†ä%1_Ü,þ)Å'¥=e550õXꇴˆ´t|z\ú9 U’*™ÌÐÊ(ȸ“i’Y‘9›åu k9Û/»;ÊÙ3’KÏÍ̽)5’îÎå9çµä½ÊÏ?S X )¸¹™½¹róÓB¯Â£Eh‘°h¼X§¸´xn‹Û–Ž­ÐÖM[ÇKôJÊK¶yo;^J,M-ýK™EY]Ù¯Û#¶–k–o+Ÿßá½£¯B®"»âáNÇí»Ð]â]3•Ö•M•﫪¾¬¶¨n¨~W#¬ùr·åîÆÝö$µ­mÛ‹Ý+Ùû`ŸË¾ãuŠu…uóûöÕ3ë«ê={àzƒMCûAâAéÁÙFÿÆ‘&ý¦½Mïš“›ï·¸· ´j´V¶®J8t·Íµ­¿]³½ºýÍañá¯;¼;†: ;Ž`äù¡+¼kú(ïhO·Zwu÷oÇ$Çf‡Ÿì±ëééÕè­íƒû¤}‹'bNÜ>éqr¤ŸÓß1À¨>NIOýx:îôƒA¿Áñ3¼3ý_|Ñz–v¶jÚ<´<œ<<;5rçœï¹ñQÇѳçÍλ s¡å¢ÒÅÚKÄKå—>\.¼¼2–9¶t%éÊüxìø£‰È‰{“Á“3S~S×®z]˜v›¾|ÍéÚßÑ.ÿ¼É:ɹÊ8Ê·Ë6˶Ì5̵Í5͵Î6ζÏ7ϸÐ9кÑ<ѾÒ?ÒÁÓDÓÆÔIÔËÕNÕÑÖUÖØ×\×àØdØèÙlÙñÚvÚûÛ€ÜÜŠÝÝ–ÞÞ¢ß)߯à6à½áDáÌâSâÛãcãëäsäü儿 æ–çç©è2è¼éFéÐê[êåëpëûì†ííœî(î´ï@ïÌðXðåñrñÿòŒóó§ô4ôÂõPõÞömöû÷Šøø¨ù8ùÇúWúçûwüü˜ý)ýºþKþÜÿmÿÿPØ•‡ endstream endobj 2114 0 obj << /Filter /FlateDecode /Length 13872 /Length1 21068 >> stream H‰œVml“×>×ök›¨I ˜€ÍKhÁ ÒЄ²’Ö±I ƒ@d³v>¨“’%%a6´©ºÅ ë˜ ˜•J¨Ý"½ahÍØ4e+…ý T±þYµM++R™˜&:±¶Ä{Îõ}]'c«:+Ï{Îý8çžûÜsÏ "šAýd¥úÍOøW5mˆøˆ¶\Bï¦æŽX×£ÅO‡ þ–H 5«Çš¹q Æþ€öÞÝ]OuÜjüSÈRO¤å<µçÀîÕ·:§ÀþÁËñÖXËÕÕîGˆ¶Àfu—¦ï"r<‰öâxGÏþ»Õ7"h÷åôìélŽîxí]¢º!ø[ÛÛߥ½iû%âù!æ{¾ëhõh#ªïÁúË»:»{7~õ <Þµ·µë­ž7iùpYtÃz¯H²'±S¼"*Ä«ÐOEÀGâG¢þ(âô,ÖëÄ2È÷ÄFú•PXtQ=¥·Åaa£AJбJìEˆî§")–‹ZºƒxFÅbÂòsúQõC«+,_µr…yY©oÙÒî_R²X_äõ,\P<ß=onQáœÙùy³\÷Íœ1=7gšÓa×lV‹ RaÂ#s>·×딩ö¼ÉmÃZâú‡× <·WŸUž™åžb5J»xJ{A¦½É #¤jØó…þjP¾! âeDþ×±”2 ¶´ëÁ6cn %…Eîò¡¿ûe,Ê÷HnN@´æ”•ÒHN.Ô\h˜Û5"B©XBÁ5#rÎ(+5ò|†¥$Èh7ª£PôxÂHþ#£©±¡ì!‚™©å§5a؆C®ëi3ªc zFJÇC£.jŠú¦·è-±'A] 1޵$o`"ƒŒhÜcØà\~Üèñãž„ÎtãQ|õXݳÝÓáCÞ1·‘4fùŒõ˜±þÙÝÖD°¨ÍÃÍDâÇ8µ%œ=êåo$)BÀ‰ ‡pl [)ò—•¦÷¤h‰¶óší1Ž3ØîI ¶ÊX‡d rj0ÎS=û²‰‰D°E¶ÄZK/0ª¤ †ía¹G°WQ]jFlr$Zñ¦ùÞ°5àØôX;}ò™ž¨êAGÐôpup`xš=m ë˜ZÉŸÖJJ4WÊüñF¬ê¿°2´—îI|B†ˆê»9¹'¦zì%®OˆÕŠ&!ÝJD±ÑT“îq鉑 ]Á(V­Ãj4uqÐm„†"†+k@?'AhkxÛ;+b6ëÍ&!«[¹r;`uJ€ej{= ª1qƒ§0ë ÐÓ’s ¹[‰cV´1G­•zJõz9AG«© £K8ÝöP“ûžžöØþBuÚÍÔ§ö*²ÇpR»BGa“´Ÿ¡@ëŸF[gò˜ã0~ع¯²Tvë?ÚìKsR*ieÿè_?‡,U©O!ýXÿ R·ï¡8<®öP‹9.Õÿæ$,gR'•>~žg=Ë®Öz˜^À~Ê!+Ñî…nAœVè¹Ð5ðWŸóÀÙ)ÈB¬ß¬ö͈ñžÍ=qüÊ÷½‰ÑD:>ˆñC`"+¶©è‚ÃÖr)Ùç3À£Èƒ öq:ÄãöÝ´†áø-†ÿ7¥ïZj¯£n¦|Î îÚ´mríýðѨ] Ÿý(-×ú©ÜâKÝÅ:^ Ð~¾þ‚Ÿ¿Ê‰çm-2OJ˜Ûuš}psû8G3\ô­æóC,·±ÞC pbpLÖÛägÞÙFl›è†¯<¬U̇^ pXåqˆíù¿&•+GMÉàü•ÀÃêŒvØ1_— •+|7¡óš|ÇF![T{9ä9à+Å㜷œ;œ£œ'œ#rým´%ïƒó\æZšïƒà’Ïn°q¿®²Ók|o˜_yo”o™c8gSrÞÈü¦>«–ªõê²äIûÕfxà\SÒYEgµ0 ð]äûÀü¥eˆ893òªwUùå»bʬ½ûåÝÔˆ*Õè5¥ÉM†£á¬úõ_ ÷׉{¾÷ñ8;H¡à<5ÙF„r3â>1E&Žk¢]£1Û8îõ5ú¾å÷ôúyÈ.ìûjW“¹Â—)Ís¹‡L*¾ò8/qn¥È;›8g ×rž@žU|ë\L;>‹¼ ç/a¬[ÖÐjIügñ^vÅT¾³$¯Ñ˵”ë™™Ö…SûçzÀwšk·ÅËdçZ!çÚß!»ã4ÙmÈBà×@ Ù­Åé9\û9~{êGúÎ-âu™Îa©WÉz*ë>ƨ{—”÷⊔~9§EžƒÕq„¶*ûJgm²5ɼ—õ\æú´û¹V˺õ8[Ï¡/Ígƒš÷Æ?7kº¯ÓNËúqÐV…öç°uÉv¯ÃóöÓLGô#\›¥ï^³þrïÑé¤ ¹çÈœ…ª1üvèÓΑH:ÞÅœ÷阥é&@2Ã×¼#ìË@|/ʺ$kÛØ;3|%³¹RoŸ}š\ÙÿŒ9tÈ 9ÍMI§Ê§Ñ·ØIë¦Õ@~læûc» N\ÈÃ4“ó~œàr£öcô1tðw‘Ü8÷¼Yo|c™+Î!§6xµ—i|u;’´ÏqžöÙ}ät ŽØîHÛuŽqè2×jµ8îç/ûAþªz;Á÷ÁYHn§6˜Ã1ȺÉçö ³þŠßítO•fNÛ¹^È· uvñœ·Q Æi»ª­›]À·ÑwB¾Yã–¶q!´s©mÿ—´s–~ÖÿSN…øMzŒ%#{ì«öÿ?°¼¯£¸†‰\!ìç»üö9>+)Ñè–8—Šó]ý±M\wü½ûá³Ï?.>çÎvûâ81 —ÄŽ Y|…BaYƒübRÈ&$% ¡Vhœ" ¢IRV1UÛºJc5¿“¶Û²©Ó` U…4ª­Z™º” ¡®¢á²ï%ã¯I;ésïù½wïûý~¾?üÞIc¾Ì4#Õéf´úŠ˨q€€â†ä6"ž«Y ¯~>P}¾=¢w·˜ÿ¢èyAÌÛ%ºÄ©S½ÄÈŽT/Ñ'Ž‘êõöôŠÎüž^§§·g°‡èéuwï=Ý;wæmÏÕWÌz;ºr…üŽ.Á3Ò;ºÜí¹ž‚+‰+©+Ù+Ÿ]¡¥vÜÞ™îÏ[ñÐp ðà(à ¤C€AÀ~@ä‡{Û¤³éˆôvÖ"½›Hç\¿3‘F‡"Ò 5ŽO7çJc€“I»tp¬Ù.½¸”^(]\(m4JGR0Üä”Ò€€ÔþÔ`jˆj´Kƒ€ý€©¦;MDëV»´ In¶KÍ€¦^jÄðÖz«ô, ²^ õ€§RpEa±À/8E°DS…` dH@åBi·P¶=QÂØŠŠ¹Â€­ÀÏù$›'ßku¹ó¬‚è´òŽ\+—c·X¬6‹‰5[ ŒÑBR´ÎŽÃq®…äÞ娵h-¹Ö@z–%n©Q"cF -1J gùTS·<ëÀÐnXžUäpÎúlD®Éš››ÎaüêF͇Æ1Üi©Cã4üŠM››Æ±[ŸN{àgÓÂ8•>êùo»q£ìÍî©ÙДíónÌVéQïF$Ã30°Kþ?>_Ÿª_Ùuä)y~5–ç;s=yàñ²ù±¹ßÿ³ìbæg\W d]ÙØ8¿àœI7±mýrýò¤ß (g1UØýöb¿ÝO¡™rrF¥Ñw¨€š„ ƒÂär êa±·v"Ÿ*ª mÆf•wDãæsÖLšU5Ãæì¤jÊuEU”18””‡ä¤œ\¬Ë›½k¸FßDÅ(Œ–¢×ÕbDá A²4FU`1æJ„¸Òªò„‘c<öÏ~­.²X£.Œ™‹(,©B®’Ôˆs>Õ×â;ã£|>—‘A)Œ«B)—kÑ~ßCÈ¡i%4m(  %û§í|,fñNxÉI¯šŽOÄ=67äŒ%+¸Ó6Ì8E'SŽC  hñ¢he9†·…\˜Q\ Á@¡AÈ%mXÈ•Heöàjwù±üÒÛUCÊöíÇÞ×nkûÅoU_Ýÿ÷ݧۆºwIÚòµ «ãÕµºÊ—ÛŸ?ô qíé¦í«»x÷LAoUAéƒ_í¿óÌÖ‘ïÿøO“k7Ôw7WãUr{YèÉÕÕZpY]hÍÎú6„0ÜoÏà/Á74*V…H’"Ò ú'4¦Ÿ¥ûèQš¢CÉät,†âJ¨"ì𠤟¬Ç¯«Ú¿–ÓïÝ×>Á%ú>}Ú:â:xŊªï”õç$$:Èݦaeô# Ïc†¡S px(ù(ªzT…âq *™Ä Á„G€6x<¥XZñ•öû7FßÔþúÍÇÓZ¥æÅüëðUˆ¦H: ’‘Î h©ºü}ZÂÇ ò=–ÎGgYž6 ¬ÉD¤YÖ’î4šÙvB‚³”MÇù˜n’=×À,¨Æ•}øÂïµìj¤oàãÚ¹‰[ëÏG»×Àîex/±Ÿ¸Ñ—«²èI R% 2ÔB¡Gs;øËˆÄ£,qQûÜ6!| Ö{Ôt–ä‰4IÒ EΫ²ç?‰Ú3ø”Ö _áÙ»D,#Q™ê‚jD\y$ 3 AºQÆd*¡¤Q¯¦Ëåáý‡ àÞÚèGô͇‚ž™u³_ÐìÄóµjŒáÒ-ä-ú–å;µ­²ã«˜ª$—X ïɈcVw^†cãìK²~¶—pdPš ~9”ÔµO'çœÕïÈAþˆpŠt ƒ ‚DqÄ-DrŽÉu¸ /:þ›=+…í¾vyâó5‹—áã­[ª7Ë­­í›ˆ¿ã·p횆~z^ë×^}qç:ì~G»{½ñƒ?â¢k×ÁÖ·!Éïî,ªš@ ¤­ßÊEÍ$&™Ó†»=j0,C¸XÂ`ÀGâÄ‚ @E QžŽ%eÐêd™ÜJÞÓÚÚÞ?zãO?eäÇ?Ø"ãÚÖ=…6Ò¼¨{ñ³ßª‚Õ%ó\4•o³ZÙ1žÉ?]¢^>‚ÏÙð^ç“y´‹1œ2œGDR”Ä^š±Ù°ë¼)óÌZP’IyŽB%¤P®GùâÇÉÏWJÄùo`@c?5óÝRá/¸øB[kMm«]ët¥þùÑ'÷2oN½´a ±ïŽš>\½¢eÛ>ÿ/÷ܶ?¿|ðÁ꟪ԭY ~'Ášrôé¢AgtvÁ¤¢R6ð¡²^õV-1Y¢Á1ÕŸð§ü£þ¬Òÿ™Ÿñû=`Ön —ŽQŒÓåòŒ9ÜÜøì·`#X¸`á¢N :×XÌrE}³0”3HFd às•d•¢ ãËp\œáH.Ìõ(ƒ±+ã 9×ÕyŽd½¦B•Wìà:Yç ˜‚ˆÓù‚ñiYæc¼^n+ÂHÆÅÑ"¥€ÒÙ:k6(„2[ìÃJ$:G)ãw øŽ6ÁðKuvÕ—­YwpæúÕ/NÌÚ1ftØÂoVš‘™ŒJ‹Ö,ñ9sÄxÙˆ´VÎ̬Àã~ãyãm#q#ðØhQ1òáí:™›üÐãaohd1(̘r Tæ‹ëMO:¬´ë‘;^þ”œ·!Ö_G+ΜÑ^ÑÚ‚æ³ÍCíÚí3üúPó;f;xÐú‰LTõy‹W ›L„‰n§-½ÞŽìöt'ÁÎÞˆpMÀ‚À¦÷Jö0ÃÛ(äù9Vekã1µÈµ`ûìĉö¨-Ç–„6Ýïó'ÑÕÉO I?)”€§.(T…€“jÇ€Ä_šã¿ìÅxSÎì=3û‘²O‹_Š}[”…ŽÈ«4FÂß Nšª½ÉÕÞëw¹´{—^Ðîï nØ»fÊŠ5;wìÞâL ^u¹xe2ÌuN·ç-n5õ˜°Áäa €ñÐÔ=½&“‹ô:W¯âpæ>Ñ2LNT–Ê¥n‰• ¥Flˆ¦MJUG q8%1N!½A/¡Rx¦r#=dŽ”¬¹8EQ„ìc<%·´ëãÁÁ[èЪ HŽÞ=ݯÝ{ = Žÿ¦3^Ò¶°z}¤vÁ&)^P±²òÓ¹s´Oþ»Ýþ2 !íCM5G†â­][žÙºkÕ‚ÅÀQж0¥j.6ˆbF»ùc36ÃþEÑ"ãrÜY,c.ÉBÓñRl|€¥\<1Á½<ë~Ù܋ɛ‡×n }î­+úݵød¨úàóßÿÕÝŸiZƒ®£T˜\#“ÇÉLbJ˜ª&Þ…6»¢ËŒ›Š”˜~«^P!w¯ ^ÚÞ?àg]~Õ_íßáßïçüþü)½éŽü^ƒPdY)¤Ü ÀMÛ„ËJQdW8!7zÍtË„M¦¢¨¬”+Ý «•Fœ ˆÂè„À„$ÃI˜ÂTf(Táq”Cçõ––R.6!g%Ó‚]^ o]]0UðmãÁbÇÝ£Pýä²c]Gä˜^¸¨µeÕKo½yoGš¶l~Å¢¥¡¹á´ÍU¡o·Ì«jbíþòºÈ™–Eo¯¨SËJÏ5oüùÚ©¯<»ó$ª© / U- ÇË—·wÔ/ßÚ¼3|ƒ 'y»EUvxP›é °Ö ¨SJy*É^ZÕ©ãì 0¯€Ä£Cª†ÔùFK“¤Óé°Ã^Jb›Þ’Á@²—)™F¹LJb( J:XZ‘Õ耵*øT°ÀîÓ>ß{çt?2¾¦ýH»züR'¾ÔVWÓÐX[׌Bþ+BŸ>^2®¼x»½G; na“Ö]s„eÃ[Ú)‡qÂG~˜¤:Øcå½LŽ æ÷°‚ ‚¥2º¥Ò å`y8é«RG½¼‰G[{,]‘úD}E‰™¡æ&W4Jb&9&)¢l…Åk%É ‹Ë’¾¸¿ L£µlÔ4Ž3Î;ÒhIÿHCÞ³¤‰~.ÄðL½À!ÇY î#Žç3È¿Á,üq‚!'Àôq&qˆ%|5SûÆÕ›/\¯²2`0ãðùý¾Aß UÓ.Ý v=œ‘0„y(¥ˆˆô?è&Mñyødý «0îi_ÂjÛÐcä—¤E¯«[UÀѲ ‚]|=áYž|4£sc¬žÛÈìçôw‹öÞQí=Û­‡¬þY-d²¹Ê¤Ç $Lo'€ÿÜ ÚžT¼LB’dêQˆ ‰ LªJZ€~Ÿå@æ±lE¢ÏRÓô[M‡³ƒ²²¥Ý²awZZÖ¹>ûõlœ æN6=…Ñ6Ž{½Å¾0u a}¢¸)=ƒk¡¯ª[+r`S´g'/,Ç?óÍôÀäø'ähÝÉcÖª•7HÍx3ùÙ­vlYóªóöç±Ö<5ïrÛ8/Ï™cXg̦D ­ Q„¸;Lù¦Flwn·yl 6ñ2]pâcRnj —&¬@qÚ¨ìêc'Çt^”2rÓÃVÿñ_5µ¯X·¤tSoñÐôë¾uµµk>¸ÑR¿¬õ:wö‡w…gäz~ú|ó©·lgÛC©•Co×VÌœOûpùðuî.p3‹©T§|‡ë2Ãh²"«55f&¨Ho6&3ÆÙ¬²Ìt jÄŽ1[LÎ{ÚL‚nc¤ãè”HŒuIç<ù‰¡ŸE²í+xg¸ï–öû~´=…RÑ#ó´HjºgãìCßšñÝÎ]{ð¶£ÍÏ¡¥Ð¸ëQ×À'OÎÊž6}ë’¾/~ò"í§#€È?ôYžNuP‚BË1‹’Ï#{ï౼ݒaiHî0Q[Ú·à1ðU‰R¦è§4è‹#ø‹_¾^Ùðþ†ÏÄ—¡¾ÆÚf|—;»þ’öÅËÿÖâÇdãеòWÞ½ù­Øˆþ4D71µêt†X &1«P-ì@?ŠU¸,FøÃh`ak†˜I:óF xCbØn2›F°gëû òcêB¯äý¸ÿ"^ÎJ¨½¸xSû“vMû1ÝÅAДÿÀ.Df®ZüvqY@Ѐt¢ÇCÒã‹Fq4>DÿzðÄuÔÇ×àéñ´RÜ7ÌhWãoѸK‡oð~à‹²/rÃyFM&†ÓŽ9&gŒ·ýêjŠê:ÃçqÏ}®°wï (..»¨« ŠP„4·Ñ@›8E[_ˆeÔNÔ¤­ŠI¶‹ï⨰ձf§5c4jÒø ­Ÿc“†6Ó˜Ní8Ĩé8£15faýÏÝE‘™Ý½»Ì¹÷œïÿÿï±?Ûµ,Œh#ÉŽê#õA-#Î@ô5o'cª,üùdR‰œT,Ó±Œ©æ)›DW“?_äý“÷òcïŸ?õJßÝoÞÅŸÍY»ø•#ïí™¶¥–X¸8ÑÖºè]¼ðÚ¼h~õÜÛüÓ¹Ý=·?;iK9ÙrêWbç’Ö4 »bx$%&‘€zWIH)‹Èd·c(ásøk|—s“W°ÎD?ÁÀ3‡Rû Uà9…l_ëfQê!±6Š)e±U¢Ë…šF`€ž0ÿûðy>Yð¸C ÿ†tÒaž€mé†á`µbd(i FTwÐ×›ÉÌà„¿LÇ’‘ûø|-¿ûé•o7ºðìeŸVÍ:û¾ìåŽ6µ¿¢þ¹áVÓ¦*ûTöØõ»i7%;ÉYÒ­Ñ õW„0&«šªhc’ª(mI*×¥k%Í+IZ Áš 2nHQ „ŠNc-Â}*±…‚¸‡m0°••"Í Q¼D¥ o`óˆCÝ6ä­Â…ê>«w£HÄÁ çi@ßJ²—ɼÄMR˜ø”tÓ)Ã%2&ñy_#©»Ç'p쀉ͅ³14Ô’ *-5ƒ˜¢ ÑÅíÀçÈ™ÞfÖÙ{ˆ¿ ëã)Ö»Ð^;MV±WÍшæ×'”ªÇû{l\¸ñêÇET¢~-·ŒhÏ{ðI„À=‘–[JUÝG¨—€§Ñ5mÁp‰‰Ãê‚vp] ø‚VêJ „³¢·¸†¸8Ì„)1Q` ™ÒãòЄq8 V>Òdåå`q@ÈÌ‹“™7®“Ÿðíü ~„_åÛ úè˪¤çz/^p¾]©‰ÐP=¹†ØÊarJ‘IWÜd„")°«u²W¢‰í0‚´€/k JKŠSœ­zÊøçLLÊŠ9…³ÄvLñ¶ ¿EFá·ù¬Äe>öó ?¨¢Á¾ËÀíà—iÀ/CPª²‹[U }¦‹*ÞÄ:Ø.å„*ÍfµÊRL3ãT2㺜ŸœŸEÙh€bR”O4E,¡CÈt‹áÈ'ÁAa%‚ÛñÜ€·ä'¾½Ï?ø+>÷æößîy«­õä?âÚùjþ:ïçÇŽ½Žg÷_9}ò»îS§…턎Zˆé0›ãìl xC·€guOzT ­ei1Ý«?ÔøÍ&Ud]Ê ˜Ô|'ùæ»{ü¿}Ÿ—ã ë—Í­e7ÿuåA¢‡þ¨®úé…ÈA¦NÞÈ EcÐj{š$á¥Á5AR5¬6¸í JÛ‚­!Ȇ¤è,Oω›0¯yÑf/Vƒ˜ðsC¡\IòE½c½£iá´G¼ [ô8æ˜)øv ­&¾¦|SFfF¦ #ü!3l0§ÃÑe¡‚2A?ìÀ¬ì‚§~½ 3Øq•¿ûá5܆†_ÀÛ8+}3¾yßÞ¶ÂÑå/UWN©Ï¼T‘ž1œÆü?xç¼/ÃqÞÌwð‚õ^9yú“;§µ²â?þ©î”ö;Ž3 å£öS†å¶<žµ¦Ûkšn·…Œì8ò¹}-¾Ÿäó¡ü8¦¦y6YØm˜V–'fšþ¨‚~ÉÏŠä @0a‡†M¼% pÆ,-z yšh ‘´c™pJ+†  ‚Y":v"Œ_#À·¿y¾nò’Á¬îËý¯0¿øû£N¨W>ïå ¬ó‡g¶¾x¤,™“ãYåçspל쑉ƒôy¯öÌøêi‚± é²5Pë±è}»tÃÈ? w½’ÀÌÀ†;o\!yF@b™é¾éöaŸ/'î•`©!ua‚Ha *ê²uÝ(ŘÅÇX¡ãýwìÓ,uÖ‡Ü>’…/š™©FC…¡Fg™mÁo8Šl+£¡Ü¨{œÛi‘‰Eá[á$TaÑa§Eã$½_SªQĬ‹FqÚ» T_šTRš?QxÁ”–C¹°È! õ¨J W­«_:aÂQ~)Ö²+×Ñ‚a|–ùšéyþf<㕯ñÿ~Æ·ð|=giYm]eù¸q£¦46hºøË\ËZ4oÊøÀ°áYöúÓÍÛn¿„ýÇ"˜Óv'Ÿ ·ÓˆÊ< !RLaE"9 ÿ“¨|$êE¬žOà|˜žŽÞÃÒt¸Ç«ý7d/ÜÇ íáÀG­²Èиj!7õÅH6h±'–ž•¾ü!÷@ÿ4E’‚œ†ÁlŽ,$Ü?I=Òt|vÆÁN,Oìß–=ŸÝ¸jåF ÁŽu_ çÖî³õçtYßÚæÍ_„ç3èx°HFë횣E NÉrË%&É1G…¨0“ Æk‘ì…D–(†ãÊʈ$c²áôúü’VvÒE(ˆP¿€Î‡Ñ/˜ W<`Ï‹ åÍcøßøü4þ8ÑÇ‚P~!p“˜œpáÏùhÒ'v>f3ùvÙ(u®ÚªÒÿ³]6@Qœgß÷Ý]voïkwïöŽ Üw‚à8à€zÈú ¨€ŠŠÑÃo8NÄ2ñëz~ ‰µæ”JL´µéØN5¦µÚ™èÐ:¦_6´%ÍdšVgt'NÓ4©rKŸw§» Ãîû>ÿçùÿ/½|0¥$¦xÀF–>™&ó4Œí o¼„U‚ìœÀWß„.M5/9Iéø1Þ¾ãT=NCÝ,}n~t’.LæÂŠþ:ú¶v 襤oÿ=F1¦±6¨§|•"„Naì<¿$ÀÁ‘ÌĤ?¾w¶dPÝØ=VdfQTuð%ŒÝSs BH)•‚Ó®é›q:/¯ÔGŽF¾'–’¢L¡ÒD†CVT‹ »D›r‰&SHVò*â’¥ÊÅT ¡@ÌUéjÃãN >®ª‚! á‡oÂpñWÎòý³„OiD’&ãô„&ÆÆ[‚¿U|æÂ!¸R1 a"õ:–7TþbûÕëËÂ6·vÐiáš»N¼{káÂw,žÕ°98Õ5¯ÙãÉ;{Þ®ü»‚¶]þœÜ‚Ù…ß]¤ù­˜Sà/Zâyþ»|EÞìEaw†v7Ûéq{fªç¬[LêÕõ²€Ò2•M­R3-k,Xtìd„ÿ¦Î 7¬KtÈåJ°¢#a‚µñ‡yœãÝ|¶I(.çÈ[HI ÅôZÀWJl¨îà¤2œ`ß:ŠM!½>4X=Ø:¬íümß‹«ç6j14ÐÞX·iÃüåÐ Œªj÷µÇ—µ/cEÓ6ÃŽ£½»Oìíé….­‡$v€Önj¥ZYÉVH-ì*‰ÙO!»=  EIOH"¨Ne'XG U)Ô(´³ÛAÇ\Ô³b‚Gh›<÷¦¨ªªXÏKp’¬“„¥@§ÐÔ”$˧O¡˜û›ÿ¸ré“o¯­,xmÑË׃¤ 퀼®iKßžõM[Ñ[ÏïþÑÆšWß=wqkÓ¾œ’ëC¥óæŸ<;²ŒÔ¾vì3µ—¨ç¨v¨=³†Á4©½Hj¯ß˜: K”’0‹Y Î@D«5$\°™-!,Kq”ƒ¢8=&d?ÙQ’ô¥ÿÿµÄ/×Û—‹2iKÉ6ɇ!fD‹5Íié¹›üùºÁ0ݹtáúMu Qrê=·9¯ÕŠx”®ªhttm_oϱƒ»_߉®D:hQœ£Ønä> dãRa¶\ »HÂAF6avTJÈ 1AȈÝt`#˜",˜(òdªºa¬ªŠIpëô“àäú@ÊddÅK„b£·3f® ‡<>tr­6úùÿõªAw߯m4µ7oøšW@—7ægÛÞóÇ^Fô•ÿ¢²~íÑû‰ž¶%c p–^ Œ—Nµª^É*óWìÈ®,!{Š07€x+«p2–0ˆÃÄN>gzH¿‚wèW@5Ì_N†ƒ4°~=é1Û)•à´ŸÒò²Y¸4èäˆ\V‡‡µèÀ€kɱC/þ¦°®°" °ŒOûS’Á£hF`ö›ª3þcòæ;ˆçiK™ úÓ¨Õ¯ZÚ=(˜·,;HM#­d"7T‘#?Ób1ë+t„Èõ'€Ms¦L„)•äïÊOd%<"eíÈ>š)¿ÇAÅ–˜Ñèe—dOš_R'òšÅj’D#ÊöR–b,§ÈMœŽMAg5Ò›P§Þ}S}€nE}hÅ«#ǵ›ŸatÌšS8¯eU8ܺõƒXäáðž ´›·w54DߨR¼ùÇÛ‚7/Øs +”œÖ]ºƒ×¿>òbš7hgw¼´cçÎÞn’e½ÀTÔ٨¥×(vìáø>1·¡Ì¬ÔÕéL™Ýs1„)ËÔlŠ7(†(FrÜf·m™<-†K%2\þ gs( ajŒ$O/:³üâ¶·ohíõsë×jàaÉ;+ëßûC2‚k7/ßvRÃdbúá‡VEÿæ«Nš†c圧9Îò</õC»@‘kdÒü…øô£3Zù€?þsßã)<ö†¶çéÏ“©¹êtA„]š“U²õŒà2Ë&òx“,Ûáù6Y>iNèLÐä%:Mú'^ jÙt‘Ž¡-ŠªÎžè¹R]â, ÁÛïíyüèÖŶ<”/,ì¯6»Rgžkj-Úì!+ÝHãßá±HÄMÀQ¾½Ñ7ðyü¦Y67ðÀw€—à2üÆNcíiil¹a¿xÀ&#C[©8£ÂòiJŠïOC"dgš7šŒ)¥Âa \<2n$:ÂäE~Xì±@{ Üp¼æÃúѨ{;_·_Ç&š#jžGô„Ò)­üÏßÒÖƒœ&´^;žl@ß?­}Jö|tBË,•8‡‚ã4ÍB‰Z/14MMª¢GI ‰™Âír=Së¥:¯€·‡œ.B߇ fúd‰Ç‚ïð˜Uæ¸Ï¡7­b¦W¶ÆE>#.^ÍDÓâ™W½7¼Ÿyi¯ÏKv¹ó ªøN²JoV²íä¹j¢a•L¶íôñ¾…»T¶Iž½hϲïõì{½xý›;pS‹º ªk[´(oVý ^ТŒopòVGýú/É-8R›WÝ‘ü×-ÈÈ/éÜüûÄÔÁîlÔâ¡«À†?2x°Ññ³<8ë³îAÕÓ™\ÿÓ×»ârߥ‰c|?ì\ó«÷Ÿž7Â…fX™Ê ‚ª;d<Äà ºRÀÎ-J ÁaqY\ø•IµM!=#:©BʸÅ—龩®U‡j‘Õ|'¦ýLûdŒzs ìXÕÒ½½yõN,~Žf^K|ø…ö˃PÚkG½Þø¨N]ZkÕäïTet3¢.šÔÅAnP–¨˜‘R_„ôwPY÷_ ‘ð'=‘N@„ð‡ÌÏ:0DQnÞþ6˜épLPVDßt‰~ŠÃúç¬îúà¾6Ü:X­gÿæÚ†(,õú¹MyÅÚõ‡Ú—Ú}µFcé‹{_ÙuüÀxök]Ìì…dö"6‹OPL1¹‘ØÅJV G(Ò²xB1<¡Ɇâ Q“9üTxy»x$bGX*“aN‡³Üƒž†—-áÁuÿc¿êƒ£ºªø9÷}ìûØdßnÞ~È!K`H“Í6å#!”Hhˆ±Ð”8(Z2©!†vl)H¬e¥UA[J[t”TЬÅh‘/§˜>´: v0/ž{wDeÐÿÑáÝyïžwïÛ³çœ{>~‡€ä‰Ï®h¬¨ÅõÎcHάkqZñfyŒJ>€FG~ÖÒ—Ÿi[÷üƵmÜ[7RÔ%,¨> 2¹hÜU{cc¨&¸¨Ý± ᥖÿ‡ˆZ/õ .¤´ÐòZ"䮕N"ÐÈË!µ9¼ïü»` Jà“§nÄõ%k4®ØP9þ¡Ürg¹9°ª~²s>­¢iÐy™ä(¼(¿LrL€ë‡aÌàu!"\ˆ¤iò·cYÕí,3[–C¡p̲ŠÃ1Ã(‡GÅ’­âQ/Ú”„—y;P,f%æC„½E“9…>”_Ì „­@Ó-5‡•Z›C=–$ØæXá˜?H\½>z˜žâpG(¤uääNã iSÌ´ÏçX2}ƒV¾5Œ¢ÑaÂËSo“t…q˜-(ª8AÑ)­¦d§!ÇvE””ÆrØÍÍ—†A%OR6yóó¢”)ÄmáÆêº¼¬ ™ÏŸ|uUÛ©7¾h]޳Á“U0}FyNÎçßýQËÊߟp>ø3F"•÷g¥ŽÍ yÃÙå;·ôTOi{,Rʘ˜5Ö¶­`]ÏÂE–{ÂäÁKR=åò ÔÇ"ǃà7m·¾=9 Ù=ÌOõÇ6Ý’ä¥3h÷úú|L 'Ý._½QÏ»jðÝÂ{äÐrüÍŸ-0l !¡ X$Ð[ÖߟdOÊ›—ÖÝÑóÂŒ;¨¸¶:§®éÑ©ÎÅ̹»^ÇO㸣\ÆÏPßpNŽPn-Œ¥S¨QEÊ¢ôût¥OðS<™š­=:OÃYtbÁ8,âQ)¢~o¦|ÎÙT¿Þ#ø¥ÙV5a÷7o<þ3öÊÀÛŸœÿÄVäÿJiT¾DÿªBwlq•t\egÕ+øI +•銪VBÈŠ¬2P¨wÉ rEeˆ] ÚT¸™*KEõK ³äZ™É*²tØ"x÷3Â1ÖN€@fa*Þ……¡|‚ÉÔŠÅ+8³2_)¯ß]ëuQõ¦ ^áš wJæÌÄL†{Nü¿ìLsºåÈ@3û $’_¢z»•äwÃŽ{þxŒûˆ™©TJ]š¬×ý¼üžŠ­&BQI½.Ív¹4YQ6ë†MŠê†ÄØfÓ°M†¦ÁI¸ܤ¡»Ý@¦’Û×TÓM·_S Ø(J†k±«Ý%¹$Ó@7cF>¬$ŹPFÌXl´²AZ'”&µ}\óÁ ¹Ð¿lÃhÃhdå6‚f¾C¡”I1%l"Ìb Ág÷Á•ýû°ËYçì8Ýçl# -e;ù}óÛ8ð4·”In6YÊ„OÅ´Ù“ì$“4“˜!´"} B`qüÅÁ35ìL‡fØÅõÑ;Ó 4 ´­WûP“µ!µ(¬¾&ÔâYÁwK+Ò‰ã/!«.$¥~öÂÞcøŽ³79ÙÇ.:³ðsÔþœÁG8‰ œo°\’T¡Îç2IꅟǦè–ìm à%{ã¸7î€^á€^:¯ây§Ñv:5¯ÐÆí5“…ÐVòv}¤×¤'uùr&¡±#2ÖÊß"oõ"ƒ-¤SÁàgç–A.Äqnëgä¿OK£A®tTxpS”ëï—¢t¨q_nŠF…;'¯ÃQNÜòè¸;Çû%‰j‰‚~ù.nuVV?~¶á팆ÖÊGÒé§±£7·þ`úâŽYQOvɦxšEvÑ©-Óµ*‘ò´ãš¤‘]öÅý™y¨à2m;x\ Y“¶«~Mr1¦˜J Óu—á♜’4ݯ5•–4 E ‘BÎOU™ãå9ÒÙK¬ôæyü«“+G~7pÞ¹ŒÄpJØné·ÊûP oþgÔ7‘`3Lˆ¥c³{‹{—[ò¸ÓÝåîZ·ì†^ìC:0°PA2VQæ7‘ýŠnãó–àóÖ->æs—)yÌt³Ü¬5ez¡² ù2Âí|èu&Ûòb^UÁýºNUWU]‡ÎxÁL)Æü(ÁèI¢5Þ*ðÇ}Å%ÁdtâGΜ—¾ûñ5 J1«=|ªîõâUÿÌ[1öƒ`mè:ë4¼ ÁÛ[(˜LÊ/Ý­ºÆÞ%Y3ñàKßi~òa¥Oyßyíðéy‚µ¸ìá151~*NÅ™b¬Åçp¾Ç¢ì츴^:#×Ë?U å5u¢Ú¨v«¸˜+ÉÕF㪶P;¤]×Kô5úIC3ÆÍÆ{Æ5³ÉÜmþÉ]à>˜IúqÒÕäÜäÏTO_ žÖsÖoµ÷Û¾o¥ÏI©JY•rÈηgÛ‡ýè¯ôXùApyð«!ê] ?>ò?5.¤ºR‹R—Þ÷ƽñÿ0D5ˆçP‰S˜J· w½$P試¨ÿóúRl  §Ž9*-=#s4ŒÉŽŒÍ7>š›7!¿`â¤ÂûŠŠK&—N™ ÓøÏ+`úŒ™³*«fW×Ì™[ûмºÍ¯_ðpÃ# 5Ýé/ß8tw±þ{— OÑ3©ªAŒ†qPNH¾‘]lË™1Šj/ˆäÂbg |1¾3xáö™ý=ý= [ÿëKº«L,KpÀ e¢} Z%j ?IY§•a‚8Í æ&h‰¾X” e¢Û´Jô+5³jæTÔDXݲ¤5¯¢uÉÒÿÎ ÔÀ,ºçйÖ@”l±ZÈ­PÂrXKÔZ»ÓWy´Â¿X wæôŸ~#¬Ãv¡ ’³2Ò/Jhm“4-îë2à ´£ÉDñ·¡–1²._ÿx åtAŒN~›Æ[´Ÿhû¤5‰Ó`Ë–}ý/eØì)»#4ñõ«óz¯óù{ïìÙï¬øBR»¶^Í!_øÛÑ1c¤ endstream endobj 2115 0 obj << /Type /XObject /Subtype /Image /Width 501 /Height 554 /BitsPerComponent 8 /ColorSpace 2106 0 R /Length 37200 /Filter /FlateDecode >> stream H‰ìW‰TÕ~Ë ¡83!$!c 0ú¨mR¸ˆ­K7ßÝÞ½wÞ VŒŽ¶Q¦SœQkikkmk¡v±«¥ZZÜÚª]ì¾ý[=÷M“ÙÞ þ0™ä}¿,3ïÝíœïœïžc˜†aš–m´€iÁ¯aX—¿Ï~5[7æ‡OvÍ·æƒ[¼·ª{µÄü¥#/Z;L}ˆDÍè; MÕº¢ì°ôˆdã’f;cBK­¶ê¥mœDI£eLU͆¶i´·Þ†ek¿Z¡w[ÏX¬vè95ÇèÄÓ¨µ=ÂŽ0JêŽe+úLýª’V"<ÉÜÛHXÉ–ÃuÌZÖ•]ô“µ‘\Ûn¨:í6NNèu¯8Ç®&Zë«+ašiQv˜ZjaG(P‰ú úÀªëRét&Õý©ÕuK&VÃãX“J ¯˜?#±¶ÕðÔ`ÿàêÔȺëëÏzýº‘ÔjxÙrâÚ:¿¬LÃö=fGÿz{V²;³c°dÝŠùâÜÖŽÔšô†ôšúÊÞ°&•ÙÐúP‹ÔY1éïô¾ÑõÛÖ‹Ucy¯âªä}SzÌ´ÚÜ鋵Р¹+º-äŒÍ[ÆÖLZ¬­NÜ²Õ ï¶eÈŒE„bŒ¥€¤UÃ1éËö\­“¾,w».÷fk˜ôedXP^nAcÒ— ,³/·ùÆêç˜ôeè>†ǪŸcÒ—,+a$·n‹I_nH®Mm?˜£éоõ-ðyb\kXšëþj¦Û£©í8Õ—>jI7F37Y¦e/ì‰b\sÔ’n®¾yãý@-é gÇM+‘Xà#Ÿ֘'ïÉ[fÅXÒ˜WÈA ×gŤ/yÌËt ÝŒk÷¥y¤·‚Ù»U½e@b[¦™4›™¡Ÿ\vsié\óîˆt@ @24TSÚ,vg™6 ; !лÁ]h3íd²áE'¤÷:Bçr¼­b-­<·[˜Ó éɤm…ÙÞ£¨+Æ\+Zÿ>¡}£#à •¾á}¯Â°’–•hãfzO뻩U}–ùfwöœiz˜i4ÊáRC'¤WÒÛ%Žæ²z»™MHµûlØ0ÄXÑ¢øéAØ¡%Ö{¸ÓÍžnæ€Óé M®439 ç„~l~øý>صW¢©luDúÊíÙ¹k÷Gw÷(öìùØÞ}hÿ­n»í㟸}ニ{÷¸ïøä¡CŸúô~ç3»w.À¯ vîÛ½÷³Ÿk’«µ¤C]kÚMz;;y§‡ ¦ˆ9ÜG®G°/Gˆ Â0g’u D¥bR!LÅ’F çyÆS˜†$vD·ÛI$á' ú'…ƒ;hÄP·Ë/b ‰îŠÊôDBÞ@zÒØíHpÙ#wþž£Að…ñcwtòûî…çªkÒyèWÄB˜£ 7j|~'¿ïþâ~q—‡8f¼ÛýbÒ£å½QúÆr@‘Ã|)ŠÅ`² ôÐÃÇK9)¤ß5é“҃̕ SÇ#‘™ÎÔ­_† 'ÇW•q év¿˜ô6¤¯¾ûÌFÒ;¯`N#„•ØÀƒÏo\ îÀD»þC’(ýEDbØÑƒR›ûR»P)E¸ðªs‘¤t¦!öÌ…a0V£BV ˆøJúlW{®w~æÀ ¥]PôÃ`OQ¨ü¬QŠKJØØ_ÂWh‘…õ"9Çd.Óa¿©!*±„ÓžËà¤$ßHºSæy0n"ª»D¢…fð*Ђt}‡¯Ýpgé?­rŽ`ù5´t¬*;0}LÀŒk?iƒ÷ˆë‚ßô~FL€ªa… yw0KºÀÒÇ*©§DRGSÂE^™¡²ÇÞ³  ¸2A¹“G„–€|É(¤=Nu!Ä@y+;Ê@‡vPøŒæ2]×#¸\Pøš*)àr­#Ý…Xžt89XÄi¹Œ‘X`¯ÍI7 ;iŒEeúÍãÓ•Ði/"‡*âƒúrI µNꬔTeAݵ_H¯£îZ§Fšb\]9²/Ù·¨è£ã2`¯‰Ýð&– Ÿ–ô~13í×I¶™†çK½áÐÁÒ‹ãí°:9ž©M9ñ?ÓÓS·ÔÜ ¯c¯]éoý)»ÕJ„ª¬uÿãÛÓE½ ¾È¸©C­›ÑSAkž€Ä ì”ÅÝ“ Ö%¤d=¯[¾ÂÕxŒdœ9Òùòi]‘²Â¾ l™ü0õAÛfÐD¸y@ ›‘^³Nò^#L(#kßéYvéñHÍ8pê!Üéñ ö 2ADÚ“œ0Éb„»ôî\´k²Ï|ºÇ1!b“Y~…7Jâ„ró\Õå}誽&õUµåˆ £‰½­î³´â;ï=¼³öPO?òg8Ž]\4•ó+,å“7ú)¤@蟒w²we^·ãÉzºÞÿs€Ìó‘îU0xÂ@j6Êë¿F=•úájozgRœÐäʦÖþ²¿î!NÝF«z¥K2Ý´Ï rv}ÖZ³.Ô‹Å”N²{iw§É­ÏßѽtëTњͺòª²báw ¼j}šÃd5 z%™m>sðŠVS, ÍØ&Ë*úƒ;Ñ~ 9mâDf¸0’$ûʘJ{~Úš¬‚åKŠ”Púèþ‡Fô’iv¶X|n¹® v´M†Q0Ú$oàô±©û «é–÷JIËÍ'ÚªK»÷X‚3îWƒN<ÞŒÑ>õ_bi›-z”‰F¨é¬TªqEQG#£.÷¬œ¤Ž,Þþû½¶”Ì-ò¾ÆÔ­²”?zhÎã3h#â(nÍw'+]È5þê:.¤£ž}Ò@Ž@±‰\wlÛ¢|‹|yUù‚[8Á Ez„Ì@?„ =Ô‡÷ôÑ\a²¨_…ýÿ#=J!wFåõ_#ªô/’ƒÊÙù±N¼ ê*(±~šù¢èXÕ  _þÕôר2%›ƒÀ[¢Æ¥cs©¶™î­µR”ö©!V–9„q»À=â¾b޵Q~5ô-Áò‰¾à}ì!âŠÂc8KbIfe•}—z\Ž[‹žA_U46Ý<Ì?J%<Ð雺B§zY*ΚL§H óHI»žgYi¢À!^D©ã uo¢RôÛ †éՊ<6敹·/³©ðíjÐÁv?«C#”-»ÿ¶ÐõlðHs9a.mŽ Ž!%$µpHò)$E!ÃmiϘrÇŦmïo5œƒ…ô*ytp†G²²ÍÌl5ó~ÉçÊϲ®ÊñŒóµ»?¹t¡é¤(Ó߉âÂÁ-ü«*§\ÀLɬ6LºP(mE›u0½¿cEÍ)GrEfd¬ÌJa;ÊwÅh£¼þkÐÇÔÜ/]W¬÷…p¼ú³ûŒ÷ª´ÀË)J©¬*ï ± ó³¼ÑynÁAD.ëJGyÛ Ò@g©B”œ1QÞ®Ë[áfè#¥–‹w½Ú½Û¿Ç—¾íûò€i7z ¡•–íÏZöZGhfÆp`ÞzRêúh ´oGñ-̼ÇÊ‘é1iñYèãÑÿ•K Ëæ0xü²Î¯-ñÉMdßGTé÷á8”ˆ®Óþc©C¥wÙ­êÞ•—kì†åu÷Ò.”V—¹ýL€1)úÆ êC#>Ñ“xv=ÐCP·'ñ«¡›AÍuyÔ–ŸO*øy%]Ø"ÝÛ‘´ x‡E\ÖíRßâ¡q"oK¨UŸOºô;:9y½ChÓ§zú|#Op8Èø³„™' ƒ{&•ºe,ü\»Ò?w¯ÇŠë]7[œãÀh+q:ˆ0Dñ €D Ô ‚ ŽÈ t_RÅV¬ªÄYX5 ç§Îº;x,ɃTVQÚ|2Ïðba›òºÕõ†¡‹™ç0mp °FQ¼á±W ƒ2›3Сbgkñy‘ïb°kxùá†iÓžjó”‡*=Ö­…"˜8@­yv(8ÆTJEW0ýÓJfHóÐŽç,Gyݶ]×vÙh£¼þ« ôšš¤Ö¯ýÖÔ·]bÕ5MιŒ1%¨Zý‰Àr°H*ËF9ã%“’,¹|ºˆ¸÷Ëçœë7 _jÕ¥]€ šÀ ._º`ê÷ö²X·!-Ö‹žX|ÃÐ ;\6æíƒqÌ™[¸IK„ÿ›2™ŠnãÝ‚ÈãÔ½¤‡ä}….£(„¿ñmɸdÄahaÝÿ°_ö±Y]uoyÉÈK[Oc«Ëí?vf™g8ánNcr^ï9瞇hWžQö¨)z¹6Ï}èÓ%K!2 )/e %“ Åh t™¡n1ˆ¸„m1qi!ò0Òø‡ÙtþãïœÛ u­ÿ4¤ýµ}zŸ{Ͻ÷œóù½|+Û< ÚCO5ʉÛ8ÐgÝÎxè³g­Îˆè9ó½3+bÉýë7\p—Í2¥™:g˦]ƒ~Î4²gÇ Cå„‚g΀oÔ]MÒi“€.Hõ؃bÙé70PG”ÿvºdÚOe☈ Ê^š4t6Ï&óœÙ||4ÊÐ[·j5·Õô²é?üEbªÁ—ÛœPL +î{oƒŽ»’3½>튑–*^e¡í‹UÏ"&§åÄm賫gÍþ¤š^]ý,îx~ÿ]ë,o·I»¡rL÷Ù=‚{&Ê2¯v“ƒÕ#µb÷ ‚Pµ<ì„QѬ'D¶Þ Bùé®6¦° Ä0Übéh#Æ"5.:7i褾Ց=N½ˆÄ±ðž´%%¹½Ð¯FDf[¢§7;UbÌ×…"¢7¹]œ´5ݘ-K|¨ËßC’Aé·CïùHw´?)½WWýo‚6JàöÊ{Nvƒ%ÓZ4¯hwé ®)i÷‡::lnB·­‘Ÿ7WgqŒj«²Jfašñ¿¬ÈNÌ…w;}´à~&ó.w ® 9QÛªç’ɧ÷:÷ÄŽsÒç-]”-8`s‰)Þ–ÞÍvcvî^»¤îÔEãJé~›(Å{ i«h¡ë÷.XoÉ™+ó%÷Ë ¿¯õl{@¤ SMr6ž›[uŸ®]ý?¡WÍY ÝÔ ËÍ6#»p*À¿Ü BÄ33Hž$gsî&t»É~';þ´ïPýW6$N˜Ï E‰¾Ù¤ S³½g„ГV#$¦{è3“‡Î`nàͯÖA1®ýÚðÓ2<} º+H9pŒ’í%\k7hJ?… Õ;ú: e]¶o€jðÚ®»Þi·‚¯ø‚‡BAN5ÉIØxÐçTUÍ[ø`züð’Wî®Þ¿{͵?–­ý_†¶¨{ô÷ Tç€w €ZÓ‚ ›ÕaÒ’¸”/úݽ\ªœmöî0ýL+/Š™[–˜OîpTJ‰i>~|ó(XøYÁä‹§`z¨”´ÇX,'ànr¹:˜¾·–ˆçJIébå,5¥´MsºÍØß‹Ök'(ìß[‹ +A¨Ç&28ÛD]Ùƒí´Á—s‰+¦0<Õ'oã 9 ¼â&ôeÞ•ùÜ£¶ƒq9<í&±Œsx¢„ðð%×)•Sǰ—lS›Ì÷±|Õ¤¥Û]¹f?ÞÿÈSJ¼ú‡m­ öJ¿Eâš­emÐd•¬ m±¡V4‹UÂØÒZèåB@"nu_…HE^.VŽAÆë›;ë<9˜ñïSjâJ0U„7Û» à.å$nÎ;w´Q{³Çõz…$DÀ=oÙèüLÁNhî©F8y›ôKöWÝ-Ôç~~íEˆAÇ9.<·|XëÅŒ>væa6‚ fç?¡³yÁér¹`F¥hiì\£„а¯ôÌ“æ {[¢ Z œ¦:™¾f 5»z›ôØjÒã\#˜eÅ„jJߤù¸œ@dކñàùdÐjŃT Aì™’©|ùEç…ôv ¬€~jt–Š3BåÇŽŒæ6KÜÚÏëî¥b>j‚¾ð‘jw꿽‚jz^ttZyØ7Ïg³HZq#2_XzÕ¶FVû˜·¶Åén•—úÇ».¸+¹r2Cuš2¬A¬íè^@ÒÚaË¿éá‘Ëf±¸Ñ:rýTzô'tTL]j=®ëÝ¡)FZ+¡txÄIS -w©zÔãîzžÊ êL«›^ûìÙTuØ y]ÄCP›TîI“}ù y Ðupô·0ªärBÙlßÓ‰ü©F8y›ôcËWuoÿa÷ígØ[ñîÞv3šÝÛ¿SõÚI)ÏÃRçϺK×.Õ=”®iZA­ôåÒÓ·§÷í}㛡€>—)xa‹¾¼µÙmu¹©ÞW±5û®X50øí¬ü'öçó•­‹¹ÔÑJ¾¿)ßô¡”<ýùÊHCœ]êkÊWò}§1£$lÃOõ> é;—¼¹F*~¥¿¯ïHÿ%Ò"óa¾Ré;þN‹Öô;Õqáä ¦cô(ã‚wßÚwá*¥ CßH7d}IWòØWDrEˆK¢ü˜¯l$‘=bÊ=àý%L#_úËÚÅ;~‰‘‚,Ó”Ä5 „Jù™(ÔÌ‹3ËèÒàB&‘J?ŠBOsÅkAó/îB°$tæÄ÷lô$¥â^Ríc6è³³™Á×;jzuÕ§¡Ô)Ï>@{ðZL`$%'L uÐ )FĈ¶¡Uœ‚XÓ!la ‘-4”J”é{˜aë&k nÁ£6Q­4ƒcÍ¥uŠÆŒ”ÌÓH¹„‚½¥(…¦ 1†íIð,X´Q<š ˜DŒy c­”†·Sï‚q bgÅ(‹¨®Ç ×ˆÒ2КX(©`8¸¡Ge€´®Ám, ZN à™m°RI£)&øØD"½úSwÍ~ !Ss¥!¹ãp’ K d’@Xjˆm # %Ø'œ1hk ·W†û˜B2–°—Ü#Š€C(J_([Z…›)•hwyŒÚÚO|PðœHmb=  <ÁH((È<*)@ǾFœ†>”+Í*pâ>Ôú2¢ö) a4ÃÆ+x¿†3˜œFö;¼“C]çºAIsÈW’ƒ´®w¯ÙD cé–ø=¸èén3Ч¡Í@Ÿ†6}Ú ôih3Ч¡Í@Ÿ†6}Ú Ïrsï4ç‡ôßÌWoˆ\Wßl hÍ&†$lë6I§ië]*´ á~ë¥ý rÏýóî=SµÒé3ÙvB(AkD#¢Zɇ*Òª(XA—HL%í­Tk¥þ©b¡ŠLüâï¼MýÐÝî,$$¹™ìμ÷î¹ç÷çœC9ΔuÔ9ês"¦![ùbÚŠ>µÿ¾Ç~{øÁÃ/=v]¦ècH1£)â±—áôZ‡Ùd Ú'ÂŸÚ Ï5»ì¯txÿ_>xÏÚk\ˆÑ®“¿)]þÜüÖkÞ9sKÍÑ›5;ò]O”¸[“¢Wq*h‰ÔuÏÜ_z½"ë`ö.°"ÄN¼O|)r1+'—‚ª›àTŒÌ8¡—_3q\Ì]õjYÆåœIGȽ8Ð7Ï̾cf¾úšÏ)]©:X5ú¥C™8+oK“R¯þcsµ™dþt)¡ €ŸìB(&¡ ûJ‰…æt óqQ+TôÝw=|hn9§°´œÛÇ™ssÕÄ):Æn)¦‚Ûµ‘FnÓÚBŸÙô¯wý@¶A[›‘—É‹^§'ãŒÜU&ã2êó‘;L• F Î\5µRJøégW|l<î•{Ûs–AùËw"Û¼ž^Ö…V:zïúœ·Ý¸¸Þ•ÓíýÖc(ìkÙûÍÛßûSà†Lô&R1.Kå‰7Ž@¶Ó‚ôŸ,‡Ú&îÉï¿ö‡/œpû»9‘q{TSÁ©.eB.fuÿÏ«p±•–"ï B€Iya«rçJÇ÷æò2G9zÝG?½øÁ·¿r oQõõ˜ÏÖ¸ê]Ëw|MÚ0¨@²€l´…ýûuÍÓg/1w z¡ºK¸(åá¬Uu)óqQËœ|ÚczeeØOÎUÝ´Ž^Þ…~=…~gAJÏR¹çÔ:Wn@é;¶í]³¤o¹‘?+9]¨èÀ[ÿäÍU9Ï”BbiÃ1Jx%­jNŽ„3Çím—Ê+UÖÙ£]Ï7Œ[öLv¡cŠ„q¥=g´£Ž’'&ŒIâþºrQÇŽï%æœ2Þ8ºHèÿÐd­˜Ð×`–Œ(tªÂ€Èâ{ª¢VõO{¤5ey>&±Õ}gâ„ 4é3Eì«=^o£Akõ¥ý›ãŽag £† 0ôOÞS{ä˜\Fu :X2ÃHmº£Î"IÖ+J˜²†B /‘ 'r%¼Và‰8!G ÒqðÊdœ”tñl™ Ø”5ò€’Êš¶K¬Híö쬆Õã:/‡ã¢ îçÆÿw­z ”÷,ܸ>è3·|ëE*ùx©üü›só[Ïÿ ø?4×`{l(·Œ©6ËQ0¢e䖨фм¦Ê߸Ì7è7]DÀs=©e0Oí;âEŽpºlØjmPZsH ¿3‹‡‚V@[YIÚæ.×uÖŽ ŸÅ–^Zödϲn"”i¥ÝñH;2›É0ö²´J±È$qHÝomË1ŠùÙoÜ9?7ÿÏ§Ž ì/Ü´œl{—‰‹çÀ°@LÜŠÏñ`ƒŒ¢¬l¡1[Å¡îg%}¿Ã„ËZ qAB+)Ëuä±B7yTΠ/UA!I˜ï„¥ä)Á’Ám¥ 6µÛš$ö†6/•>FDµ90ÿðŸ?¶à›7mšÝ±sŠÒg>uJØø. ®öfþ¹ç~GØ$œ†u£[çj±²Ê¡Õ¨#<À¤\r¸B'H˶¶5÷¶‚à>¦è}®cÊJ7¹Fn@Sgä´®r¬)从'jXÐCNïE-æ8så!ÌÈLE 9H"Y!¹€[$ŽDbQÓ[AâÈq|ú`>?;û“ŠOÊüî3eéÅk¹AC (8W¶oa›Ð«Å¸ê¿ÃvRãRl¹;å¡ >Z×;ø¤)µM@ÃIY³­õ!· |@l¸„WðϺ/ž‘4Nø™uPJ>à"|ýÖñJ^wBÔ Ÿì!~ˆo´Áaá+¾øØJ—†ýšmï_ôÙGX¤ÔG¯»#UJ |Ï/=*‹ƒËÁ:}–IÁ°|j¹ ŠèÐh Ù‰Ò{£2Ú.f¯€oÚÖ–ŠRv á+ô„9 eUE1’ØYfë²K6w\•„êC¾n²Š) ŽÂ0É.dÅýaêpˆ¬gÁÅC,ÂI—#´UöNÎ*ÀþR¹·WFÈäWšEnlÛxßë_Üs[5RR¼ È•‹ízZù ÕÍ©Ñuå°±PÀƒï1+|ƒ¢%B¨Yª1@¿R˜XÅÄ%jTi¸¬ÝdØBljÕ๑Å(£è¼-NÀ×âɺ‹w"¥=Q:*K©"…LiålÆÃà¬sœ>0³eMß¿õúõAßòèŸepí•ÉãM‡¥Èj(¸'#é0# ¹Ú`‹ô/S—mBqª_Ü?Ÿ¨ñˆÉè]h<Í1äôÉÜ%  …¬ñÔˆ²”sò$ÅðIA(Ú‚Öl!zÑgËþܦ%Qã´AÐAä¤G8€L:ÅîpBO­B=ƒn^}w4–Š>(¿ºV7Å,C0Š„F¹ÒR¤-âB#Á œÖ)Ex¹ø¬ÇÏÒ€ ‡Ù,Ø„TÄ%–ì±E•`Ým¼ø°Æ´Õãt5”øág1õyØFGØw›Ç¡º(ßAž¨PÝDÆ08´=Øœ¿ œ…Á©XB3éCAFÉýh¢>¼æ[€ñŽ…›§Ùû_{Rƒ—&W‹ª6V6;ÑUàÇ1𧏦§Où™ƒwÞDp#ù:äêÀq£õ÷Ûošèô­Rï<ÒÓgîC?kû¡ã¨åp¿¼Ü‘îÏßþ?Ϋ68ªê °u„ 0²t˜°CÇÞŒ!?´·Ê…‚î÷Çž’ȰȺ.÷®¹û#e&-UegL(Ž- Æ:°.HZ¿:P˜BK!ùP†€h;}Þse âŒù‘dï={Î{Þ÷yŸçy1@C%GË'4=­ùZˆ?.”Õ‘Õ“ú„÷4¼ÖyßèU–éÀ0$ÚpM(ƪ Tw׬ürq’„¸q¬ÄÆß¬ÞwþóݵÐ\u¨ÉUÙI¾‘ÅÂKM€ÜÚ”Ex°= Â`T[’ììäÅ {αðrš£YͬëðÒ†™Kå””5çlCçÌÊéY¸8OKµ[²m*ª«Í~ùÒÞ†ÃcS¼ îŒ~Qõ40°{íÀK ç6b3 )G\iÿ¬¤iy’+;5c>9pßí#I7m#™5î©Éyæ4(.b~l¥ –1;òp’Ž!Y‰ª³ö¾t²k©î䑯/xz6|ĸ1wÝ´èÃ+?ÅÍ»Ï.§àF¤,„SëÀɪíjIXegôÛňJ‹ny}mb©ž›Ó«Úðµ~2ÐV,á£Ø(.1Ï€õ#ÉAÜ|1¦‘ hü°½È©O´1þúw Å?/'ßÇ.O€nè3o h‚ ñõ7çʵà@¨ŒËg,¿ÿm3¹æ9YÛT`Á±TyåSïáM†±e¯ Á~£æpý²½0bEÒ°GêÀúlèž;Ó* ¦n–ê`ÆkwPÐH·_º2Þ­sí´£)ŠÚÕÂ}JQµ«µˆiïá¿é¼©SöÌ'–1 ÖøÌ6óžZ§¤ôüªmï£2ä^Z$IFŠXC©iô‘Ìð˜«îz?#¦ˆ¾ú¹¦5­ù‰ƒPä»S&+œ¨óéÒì¹}|aa±÷Òɲ﮸û]x‚ñ¸q§ dMóhDq$ضI;‹ÿ Xst XÖ0¾š7Ft×ϰf“FÀ;–Ps1‚NéÐÒ_ ¥w°ûð yÃoZôao†¹áf™G¦x¤´°¡ ¦c“¬;s[E"D9qlæ ‚“4:3âÞôQF°((¼2á< ‹ŽÀ¨B9&Fü%¾9 Î^nr,6ž”´­î%D@3RÄ5-¯T` -9ÀgŸ÷ŽX‘'QMºöŒy-´ªÉ³T`þUYƒÑ¤B_ëtt¢w¸(ßê¸ß„<ŒÍa겎Ʋ$ø§iVÚP%[s,¬t|Þçð÷kk¸ ¹­ËÕáø÷!ŽÖ# x¹®¾• "Ìnìd7•D³;(4zý£"¹B$ŒQp6¥ËЇ­bêòž}è–ºKÀ.´ÀóÞiýtø ìûõ?ߦé·üV]FûâGÿgçVÉ6æ1˜³Sº‘¿?S RA¨c;lò×!=-Ã}±fúCöEbP©ùÑLdäïè Ç“;‰Üì€D¶ÕA“ ãMJ•®ƒÌD´€:‹;>•ŒŸæ‹]š{£X PYeÉl£2{Z‡ÿI(ªtÝàËmjÿ=%ËCŒ ”dÝ ~,†:q¿¶OaɰfŒA Å2\l‰zO¤{NÞ¹óy,µ‘R‘¹`ä0]œl§í %q:*3Sr øFƒŽ./ņË`ž- ¯ƒ ßIç²ÒîTröÁ«ç;ÏôGâöŸ[^'\DA† †Á‹È²36mm.ñÂgüƒÛMöè:r‡ˆî) æYC4_s@ d»|VÙ·P-\©}¢§yºQ)naŽCÅ#~…é°6¦êÔ¼ÅÓ“ I‹Y+Þ¿QKcÏN÷øµ|Q +!µM£à%Çóy‹Ñ[?ùªbÖ^mʚϮ5WPmµÎ3õ Ld6àOvt¶¡|yã‰í»‹~ëm®ö‹L¹Y¨Ý©­›»R9¼±:u+yÎ\Ĉwpu:×Aè/–ñˆTù™GCŸKEÅr/xzf³<Ð\$kžS–!Á «IÖFΕQ¦J5/¿ùÍvvz¦UŸsšpa—MÅ0Lîf9•xý¶2îyÁ³}Õ5u©q ¬H&â*dSþšÞáä ï#&P»ÞÒé°o4½;â$æ¢qA£±çFbäp§E\±áZñOF” ¨ø½ »açÎðg”›"¯qæ ÖÂíø€õ“(½2QµÜìz© "ÿªåB®L"V`¨]8³€ ÙKZô$•_$µ¬»§ž±Ÿ`g>^cY·?Óžžj÷Øÿ«ñ=;ý'šV»çPé£@epdá!ÃÓrªg­¦Ä’ò»8Òs׿Z*«ÖSÍ'<Ù\Ù*@9Ù†ãû”Œ—[øƒbÆ C³{ôí¡ÏMç'’ê+Yx(Ù|rAõ\µØg&2Õ–&ì_0½Ç§6•¢ìÇAÂÓ¨ 9Ÿ<ùëJCÉή7OEknÚÞcjI%q¶D®„•FZ²éx_‹6>ì,#süТ˲åH8o +ƒñŸ£ô„Ÿ_æe l59¯õ@zD³poBWÿoÁ{Áë¸P«ŒÂýï Úuúïn®Ùó‡?ûÃ.ÉHc6¼?&X°â ’äšeÇÇâ-¿š®ÈGnä ™››Q%jµÈjëJ„¨;Ù:I$D+²{ovþ‹#s–ª<ðþmE¿åÖ/²Õ³ôÀ!Æ Š.@ÑEϦàådù­’ éÅ›ó˜r¼öªôæùuqØoˆ-¬&ª aŽX¾&Ÿš³nî½e  Rš:‹Ôz‹ØqÓ{èëi¥©j©¢gǼ\ÎÈHüØ„ÂÓ;Ë…Ü rÔÊ<Þ"Âv­·1SÃòOã × Bèo‡Èý¯Ê—'ÇˈúŽû™S¸¿>öyÞW×:®g¶‡ÖY‚ñúLÔ.7èÿào¾×Ýw8e…´4Õ×z¸‘’[.g·‡èñXãW¼B£é8¤)íévxzã Îá pàì²³pÜ´ö>óµ˜)ÍcÌÿþÏÛFðíÙ¸¶+<Œ»â‡‘ˆ#Æ6 ž#âk¦»#Nš¨4Jˆ›£-Ö@8­Íi—NˆH‰@Û$iCê—”9M‹¹7/Æ¢q+‚?T¢ÊNd§XFfï£ûÖ#à4 Š;)îm9ëaÊ7zZŒn"ÃD¤Ìß·÷;'÷OnÛ¿ëýו1ïz–Øxª¸ða_mê7þ7²YϰÉ`©Ö£JÜ˜ŠŒúD '‡Oe,ì¡ »"lDAf¾×*ÛhoÖ¥ôÓeK ¼WÚZUæ¡Òoû‹kLÜrûä¶ÉÁÉÁc[†ý&~f!}dÔµæÕýWä­¤°å(ìö.á³jô.;áµH3æ¶­è6AÐüú‡Îë³ý¼Ÿ m(·²fx˜½³Òû(½r‘ŽåIš= wÔZX7&”8L‹ZJQ­qC×`bïõ#þ™!¿'¿7p=˜È%c †€ÅB³ThžÍ q¢aj×E¬ˆ¾4’ÙÚ"{¤S“$Ü–eö²óÎQé3>‹UL…ÚZÌ@Óßd©{Â$öéíØ½TEºTI TÊö Ó[[סèÑéí½Kb÷Zò©èNï\îõ#ÞºW3¹È»©[¶¼ÔçAm‰ßÐoáknÕî§–ß½âÌì½Û§f1è¬á·9æ\ëFˆGn^(1S¦A‰Xò—i4àÆ&žÌkð¬(Hj¼Þ—g:‡ŸPÿáÔ¿y'Ð:ÀðñS/þ “ÝÓÝ|ÓÛ°sÇb >¨Æ%f0 ÅÎfáýg¨ +ÂaWáî9Ö£x•§ùu=Ázˆ‚ÖñZK/€’Œê,¼œFðWKÀ¨2ù„Ìå(j/¼ôwçVôô9õ[Mg"ˆ„–%šàÀoq‘œr~ë'ö2)™ªÿX&ÌcŒZÄL_ôY"Ètðn^¼-*þˆ»Ž{ Á²Û¶Ékù[Lke¢…­‚LÄ=sW„œ%VG>hïDïOMšyÇuóð@WÿìÞîÝýý×~rGç¬^6åí´ƒÞ ¶Dpû×Í·L˜¤/²ZŠ¥{÷íµã2Ô<96â‘áWY2¨c$GÚ¦|5œ cú¢óƒþ ÷ûX\„Ð}K3…‘ÅdY‡oíØ\ÙÑ5§³kÇìY•ÞÎ=Lr¡|EÍ+—D†â (ú¿ôf+fI$T9 ™«áB r¬5að‹œyÎ\îyoÆÌsTú§u”]3öÓ›.gV`ÌÙè–%y÷ò@Ρ7CÚ¤2!¸ÓV¯iÃù½8¡²Ó½µ'”c „ùÖÒ†WùÙ{!féÕQÆìüq.¤ úÖ•ÂÝzz© qQ/½üý¢7RJm+¦Š.ºË 3|í’¼X‹<Ì,òÐf§€OÂÁM~ d‚–[ßÏD\ATÝ{Ü­½ê¢5* ( À\Óæ["M’¡ HTØa7ü¿B5Ò7NDS÷Û+ÿèŃX›qø,Ðwi㕯-J£ùol 1ôÛó~ÃbØŠ†·Èþµ~J5od6Œ¼Ò£Œ!"HkòÐ,¶â`Ùýq­¢ÈßùÞŒóϭ軤f6oqîЛˆhc$ÇÕPߟX„»KŽ7˰ôî ã9•ôâ£ÔÍtÕ+ò?œ—mlÇÇ1¨QË‹ ‰1‚Ì)4]‚æËPªrPˆ¢îîìÜÎîlàx9r$\ªcen/># %2BÈ|H+BHˆM u1/…¶iQˆÒPµ4¤¥)jTÒPõÿÌœMEÀ•ºÀ>ÏÍ>3Ïÿù?¿ÇÞ •^8S²2RØšIë:ñn޳U,ß.רOïxÉ”qCßDoOìd]”§}!ú¯J¯Ò[ðsÒy×>mvjS‡åZÞŒ±R¾uÓ¸Lû”ê;â@žüøýNà pÙëŽeÒ-‰™/æpÍgŽbìµv$„rp‚‡RHƒ—.}\¤½£äŽƒœü±ju|8~ó¡eœ¾ÓuѼñŸÍii1cðãu 6é áÀSÑ…+€(ÍÙG‡¶þ8*©¯Uó™¬k ¯äÊR&.mk2ï8m^ÿüwÿÇÄv¿¤× y"=z•êEÝ-¹>õ¡I—_LL“*>Ðx "ý[¢þps¶ÿV­ñȾV¨Ùwî›ôH­mð1U aÐJ=R£WúÞÀã"è«(3„(uK€3VO™j1Y]ç;5Ë Ø;=w*çÏÐvHÕ·è÷0nÞ¤Ê=MD—N *óC–µ¶¸Ÿh÷Ò2kûÉúƆÕï.ÆæDûK&¢©ÝeÝ)•ZÓfšní­qwáJ>K´zû“Ú9NÏϽWûÔææŒ/²3.kF-ªyÒΠϗ6©\O3>æÁO,Üý\7 ÏbÞŸµÙé v:ÐvEK©ŒM­ÃdEkΚĞ~øË½[‹aõðþd«#œÀ¼¸0r™ÒŒÙ'Èt0',¼ff?¾’ºú”pÆ™ïÝýlÑ{kâ7Ì¡{®Rmªm9nò|aWŒ^#3*ÐÔ´(%zÓ(©¸“© ./`NÅŽÈXàø1ÿ“™ˆ^)nþô44…¿”—lãìèoûÈÙžá·bîh¨3A8J÷^ w¿ÄHð,cè NíÚ¼ö%éÚñ€p…­ÏJùþÉ Ty…dÏç_¤÷/Õ :„í¸=hÒ¨³^ÔwgðÀ ÔÁž™Sâÿõ^•SwÔJµ]ŸlŽpè~#â¥øê]‡z—#­cE}&•‚ê¶0¾ø\̤éŠH!é óGO¬$É5}Þãé&³ž=^ëõÛ½`ÁÒSEd¸\m·á æJï$]:©#ër>.â¿X[Á·qÃŒYòîœòWˆª¢ŠfÐÓ祳â<#ˆ¼öä’h {&h5ÓÐo]gZb¾ÔMs!ØV=)ªÈá®î”ŪÇMʦvÛËjï»cgÌï$'©ÁÔê mRÚ‡:¥8iU'—î;G®pb™Äɘë…mô- .8Èx0º~ÖüP­ #~]w¯JV×5áÑÁ+½îÍvez­ùG'G©½?m•"‹#[³({ZŒIBŽˆÐÛ?³]¦™RŽ6.Qž*|`¨ðÒ©ðpÍ H•}ŒÃm}9æ9eNWyG¤B){‘–2Ö| ˜Ï.—¿•èê+ =R¡$Õò /»½1`ïŒgœ¹½µW™Øé×V /Ìiw=> ?«Põg€ª5R¿û*+“—ïÀRIÔÿg˜Ð\à+šKcÍ Gz`Ã÷·GfE – ­ìÑý›Ù´YéTœ^^«eZÝ®´( ãZ0±Àh6‘ P7hniû#Ú’”éØ"ô¢k +»Y<º³ öjakµªê+áç÷°÷ºº¡ÃÆ4 žô¡Cž ^êOz¡]‹²xõ| F­™½ÔúPT½×jt¥ÒçÚ‰ö믒QðæÙ~*“n:­’vMAØé`Ƴ)¡Ö%T?™_2Oð@ؼõP¹hî÷/æA™)kø¼:1êˆTû:a¤@]V w’¦8å¬ÉC߉š(6x”­ó…JgÌˬ?¥÷(˜L`}‚­làqÖ²ý ;SË\B”¯¡,×Û‚šõt}ÿ#9B¸˜",%&\›}û7‰Ð"ãèêÜÄìZóÛjZ - •œZ<ÇL¢šñÒ{½µ{OH€j<‡`Ù”sPI9"¿©ª%œŸ,àŒÕNš¬è¡æêdvûu2fâׯô/?̧îÞ Q$1U¹/íJ{¾P¹âÓ…ý…øzÕ/'!ã€<Œ´N0šWÚUŸaÅ#¿Ws DøRàŒà—Õ0 }›ã=NƦ) jUG×ãcÓ^øàÕµº\ªdñÏ^^¥…³UX2[Ñ¡Uè/òx:q±MÕ ùÕšæØòAq,¸;é%7(e:.t–MR«ýµ¹µËÊøÅS²6þ\;O¿ì=*\r ß­O´$ã<.ƒídzŠzzà¢Ã¦Cý_‚J7D ä=že޽ó÷!T¡H®™,ÑÚfY›@îÕ &‡QRT×V»Ø ѺõWkh‡ç˜è¶^é°iÌ€. ŸîÜFÍÞëydäÃ'}È÷‘ßx¬RsȨZ8ñîN—!°8•Ê´¸oÜR‰ôe•“ƒ·œ4fužåî¤NÃê8z:f3Éì0¿¬§L.Tå“)*3iË®>í|•> œË#¥æsúæsï ‡ˆ¬°ã’{“/¬4tÖ¾iJ0J缸 š à¢hÅ™ž^r=‡…iwÿ–UºiVUïRÄíg1¡>ïNº‘ÈÀi:¼‡$7¡nþÃOžE-ûžÛ‘g¾ˆYÇ­çIøwïÒ×ó"tEÊs…\ÓšZ5)‡"ûQQ;ÒŠÉ‚e1p¹`½9{Nè/"1%]ž)ÅÒ›ðqKÑ×4ଽtÞB|>M9\CAÎN\SÔ"É]cÇŽ”€sòÖ:æð"hˆð7wÉŽ½Ð9{P[%Œ­Ð·él¾$ÿu–Ž^ÿõÁ“þÀWD x{ðÛkqî܇ôâH§Y‘‡³ÏÿþàÙß~ò8‚ƒI@U…‹«¥{¿ž¤ÉÖ›}ðÑ®<ù4¦—ý.!m›Iš%Y4{ó³¿üñWß¿v+þÞ“„^Zapþî/Ÿ}ùƒó·ï<š„Ù$X©NºÔ´©w7߈®Å­žI~gE”ôwHdaGôŒt £-2N£<èé¤ ³,OË‹E:oÐ7$SúÚtJ'ÎbF—fišÓ0¥ç$-y:FÅAùÉÑÖ$鳈þixtÑ-ZËÒ}OŽãˆ¶î)­/cZBSú"Z¦ó£¿‘žzU‘XïdôCh$â¢8,¿Š~(};íôxtB9Ø™¥ôgÓ‹›öÀ¤<_ÐoK—³Ižfå&ÒìÓòø³ò@£COy¸“•[V•{!½Ó¡…žûò…OÑV'yœÆ=X”§ô;Ód|·vqòfo8ÿÄh¯^×IñƸükÿûIBÿ§è¼K øåS»ràüŸè~8;ìw.'}ÿ˜Æººï}É-]•|ÍYèKn™èRÉ…1Ð_oK]Þçw`yí-] 婚Ó;Зܒ'½¼©þš[êAnþÁǤ¿î–¾§×ôå–&Y:ÿüã{ŸÜ»÷‹wîB=×QvôÓö{ëöo¦Á«?ÐÓ8‰âÉa>I²¢˜ÓoñH@oJù,:,Šp\м§qQ¼ú#½9eGYá8O§Qšg¯þ@@oLQ^ã˜Vy:ÄGQú- è)ŸNÇAA‘Žã¬ˆ^ý‘€Þ˜Ršó8 ó<Ë‚"/ÂW$t¹*4Ðe®w¶¾¢›è\²™ô‡S¡ª³ô¦fƒþEoX·¾½©ÙMúžœßtY¡oœÎÎ$ôÑ[ƒ*9Л›úÆYÍ ½±Ù wÛ sÊ€.¿z:‡ì&ýT¨ª:ЛšºÞÙúŠnbOg“ͤËÕºÕèÍÝЛÐ ètºƒÝÁ€î`@w0t_ ­Î't%/ï:,ЕPåœû@ç’íž.%–w6Y K¿U³£½¹Y —뺇åQ6ËûŠ­&O6èþá5‡w 76ôn{PKôÒôfot–Õ£K-¥ên`Òyf˜t"VkíÛ@g™yy£õm ³Ì€î“q·· t–™–w©t·³t–—w-Ÿ¼tžÕ£Óê®Äøóeßp{ЙtºƒÝÁ€î`@w0 ;Ð ètºƒÝÁ€î`@w0 ;ÐÌ€®È´ße@w0 ;Ð ètºƒY ûÁÁ¶ÐÙd3éûÇBht6Y +ZÙUÕèÍ]*¹0:“l–÷ùXÞùd®…òN›ôò¦:—lró>&M¶{zM@oj@w0 ;Ð ètºƒÝÁ,ЕX¾*ï:,нë½7èè\²YÞžŸ _cyg“ úÍ·¥ÆòÎ'›=ýíö©¤Uè\²™ôQo ZÕ¯zS³@—ÝÞ™ªné@ol6è7¯î ,YÞ»íAI t.Ð˹^:ÓLè¾h›C ³¬}~lÓ¾:Ë “®ey^×@g™é ÷²1Йe@—Ë;ßL¹—:³êÑÕbα§ó “î`@w0 ;Ð ètºƒÝÁŒè½¯eõè~Iüô)&g¦I÷[+ÿôs ³Ì„NÆ£m ³¬])_ˆ×O€Î2äK)Ô¨sè,3_²©Í«C ³Ì°¼Ó ë[Ï'}íÆIyйd˜t–ýÎ`þ¹î¯oËê ½±Y ï=¾¯+sôæf.ÄñÂèL²@_%Þ–:Ÿ¬&]`ÒYeƒîy蜲@—º|:Ÿì—÷J@oj@w0 ;Ð ètºƒÝÁlЕÖó{€Î$ t5>йd3éûûBÊ꨽©Y ¯v¿§•ÄòÎ&›Iÿ×ùé|:“,Ðeÿê®®ìè@ÿûå*ÇUÇñݽ÷6ŠIš´I©Í%ÞÆM­=׈‰O§TâHÑ9ÿ朳g„Ш\ØþÉÃd{Ù¹fcI‹y0j„‚5iª¶ˆ±ÚR›¶ÚjɃÄjA*ÑêC‚H-ÔP­~Ïì»“]ò–½ó»wïÝ™9sæw~Ÿßï{~sõÚЧ·\¿µV6rdãÈûÜš›+Cô½„~µÚ8Ðׯ½¹ÜÓ'É  ÃfnX}k }"m8ôZmº2sËÇÊJŸL+ªô©Jmãõ%ôÉ´"èµêªú–­%ô‰´áÐg<âê5•úDÚpèÕj¥6ö%ô‰´âî}ªR™.¡O¤@Ÿ©a[ï”Ð'ÌŠ+ý¢•Ð'ÌJè+ÐJè+ÐJè+ÐJè+ÐJè+ÐJè+ÐJè+Ð ¡×*Ó}Ð%ô ³èS@:]Vú„Za¥{ä3%ô‰´áÐk5ÈûÌïËJŸL+¬ôê¶¼úh }"m8ô©þüx×Jèi—éÞç6ÜVBŸH+€îÏ­½µû}óš òW•Ð'Å  ×<ëkoîjýæÕ[§†”z ýjµ1 W6¯ýx­Z›*¡Oн¶yÝmC†”ЯZú4™ÿDµ6=]BŸGÞg¶õN•Ð'ÃÆiäЭª•Ð'ÇÆ©t@¯ôî%ô«×Æ^`SÕw$•Lj¥STP… ø`Rf¤U3"ª'ŒãNõ)¤ÖŸRV0®µŒ²V£Õ¿®˜NÙp‡q‡ÊPaG-MM¸V…Iid¢àaK+£¸pî+ªŠÆ3ŒV(î‡ác$Ö„Uø%ÃðGX£9ÆQc#$üÌ4äƒõÏaŒå]Ãí†[„ŒŽ,A„PÆ FËÆÓ!÷…#pI*IÕ}žÿÃá¾ Óï ÷xÐ+•G(|§VR¸m,’MOWÜj©µÅcfëJk!­¼)àˆ£4ðI2¡‰¤IÑžI0˜`ùbú×5x ®4a’#s aùñr ,—– ¥tƒ´')Uñ| U‚>󙡬O[ÊtÆÕ0ar·åákä²ýûÀ[0¤ ¾øôêÂö™Ï­i)Þ›çrÆLK!0B `¸ˆ$ía‡C1âÁ¡ :$~Y~e¨Ká“Ô kÅWZéºO(Kµ°ªAüƒ˜á*Q*ÑðqÇ,$BPÂÂ0¯ á3Û«¡V!’œ3s:j™¾ ʬŒõ¯SãÉXjFX$–'ÃþñÀ|(sÀ2ž¥Ÿ¢€©Má¼&,J·` –ÐZ˜Là ?Ä4êY¼C_ì×£Z Õ%[^ $²ë‹A gd-¶"*LßN#0Ê"W7£‚,„ÆWô2C@9ñëhñÐ*ôL8üÒð‚Ý•ö+¬ô©Ú·¼´iÕЊ­¶0”^z”O®ÙEÊg[”k™"yÐid»ÑóuÒ` Û€Jêл\Þ1%%æ}ò¸Ì­DŽ–wÎD€’<]t]ETÔk…Q@¤H¬!Pg™ð¢ñ‘%="ƒL5 q¨mC‰m–©§ò£¤QG~ob$÷Ÿ‡aƒ &ÌBÄ”g[Qú¨(B©° ƨõ4¨µ$ l6!A#ƒn¡K©#-Vp¢…³ØvT/-¸‹mÆêOVf®z¥úA%Eèç|øO{[z㯧Þ^Ïô^ò‡XÝ&Êo«â}{«¯sä«\Üh|#>ˆÉi–ËpÄê¡X€-³\gÛç]œ%ïš/ˆd11Eò®íö9¤"[¤tžÖ(»0$ÛçlÑ|œ°ùOA»»{1¥DYáwGïÛïÜÙ“÷üèyˆ¼NΘÍýüÓ††"HP PH¼¾÷…Ç¿ÑvéÞÃÿýÌZÊH5GA“o?b£ˆº¹Eåpè^¼ H~UÉwüë©×–æµ§žxý{Ok*ˆR‘¡_d>ôÚ£\kRävÝåœk:—¦ø»3ÎC'öaç:εq2>´+ߣ¡¡H<¾páM ÞÓö7t~;¯×3œYjm°Ðû×ÝŸØVøØÝn„¥oEDÍŸÏ—ÏgÅ÷Ak¿¿tpW§áìg‡.3ãÒ×’uåc ¥ÂÌ}ó'Ù²½Åqêvÿú‚…ß¾¦©¸1_Ï_@òQ˜¡ê"ùçÑÔíoç—÷½øœXc¤rɺ ßyÀ-ù0¿ò!6¸cõW¦¢Y,¬ßùwàŽÓ^8ðãœÿOC/¢×úß5W}ªv?Õ–ÏÎÚãÒvì²Å7ãæ’;ø‹ãĶ.ü!Nýyýðlß%á; n“wcwÎ/:=çNÌ.ê0Bìö¸³Ï tïyìO¢ý2›F1wñÛzr¢zÄ×:Ïl ØŽPåH‡tCz¹)OR_­¨%ÊeÃÞyI½Ô[7¨ÇÈÞoß´C¢Ç4\<–ßõ‚ †š$äøíí´Á¥vvsúÌÓ§G3‡\ yø¥O ˜ï¢ŸÚôã,“uzË©û²šë`xšÆ¾º¥ÿþQѶʶ+«ôÊýÆ´’M¯t'¾$:©;»S†ê»iVwй]}§| f7¹.½ì¯Ÿùãö†¥qÏ\»»žXLÿzó0zq“‹G˜{Qbƒ}²Ù?^>ŸõªÒtÍØS¡3dK‹æÃØ£„aðïk´±þhÓuÚ<ïJÆ=m»ƒ¯4¦!·r?vqí;?h¿¡¯Þ㣓n7³Há ã⟛‘¯lŒSEžÏ½^Œ4šÈ!o¤x§ mãŽ}í¾ yçðiöáœù[xo”¼ÏdÇV¾=âçý²—üÒc׋À~à„˜ü Þ?ÊǹÝ[|´¸ x÷ yÒz)ÝôwýÍwÙ*O$CÇÝ}»ôï˜Ææ¯2yF}•¡{Ýp1Ë|ÆuºA‡'¹5Ö²Ïæã£¸Úû{7ŽujÊÖøÃvŸä¥Öt'±]j)Ð×íÆ¢;ýGeËO½ßm÷øF)GF啎™±“ ®ùºÝÝ’ˆs?}Á#_6®}3!ú”Si>íOýë£6y˜m ²›»÷>ë#’6}JyñÍÀ§½{›î臯%ïS >35û#áŽ;÷ù8§ÙoÜÍàN†ÏKëëV~voÛeÖŽÛß ¾·‰üëšM¿Üét1íwÏÌÕÙB˜CE©û üÍ zqÖ²0×½üúIŠnÈ¡ô‰H6³$ÊÏ¿…7$v4ÒøÐ›ý^fñ tRxÛ ‹áµwõR¼ÝMéîpìkîÀu-ŠØË5Ë¡cKØtvÉ/9öáog:ÑÌ~!…Çõ€ËŒàõ`vßE¿Þf!¬Ë¼$”H¤ôĬûJúrXÇo_.k•2?S¿ÂCï Áy ôêªjeH±ÏT¾Pߴׇº}®ùÖ«?FŽªŽßÙ"Z(¥¶¶Ð^±– %™3Ô?È“bXQqÞ{ófÞÛ·µ?I¯™“¬åº™µ{&H,†–F¨M †¦±ÒІKÑ4MPRhÅ`J­È¥ ÒTB¬¨Äøù¾Ù›ÝîܱÖòz»IgßÌ|ß÷óý~>ŸoV±TFu»ßŽÄöÄœ~-õè;.3®qì<‚ÚÓJ\ñm*>Â=©þÀÃNÃ[ÉÅsªÖÇ!U›;ÍÞí©²7k¼Ël“b›¦"ÎRúWzÛÎs½Aa!¤U ʯ¢RyÎ^cO½š®’º×Ó¿Í3`Ä擹 KÿNø>º#u5Òˆ3ÓJ[6]:ùˆš‡ 㿾Å.Ö.eÖ¢¼)`Ï"mH;o?Y¥çR*ç kÆ-Ô)¬Ô/þÔ[$ïvÐãØ‹›¦>$žHÓ¶:ʶ†õÂ/Ùè ——ÜÔ"•L xTú®k¨JïV81,d DŠqĦ+8,“W¤÷1qlW{‰ŒƒT? ¬åL06vΠ“ÖB ÚŽ«ÇÐJ;Í݈²i‹ëÙCÜcÀï÷b ”ŒØìNÐo¥c=JGJžŠD!Îîýç¨îÚé óÆ+•6Úi$|z½‹P)î^|ÒáMÊ7Ý5}¥ „¢IíËâß];}‰û.ì™ru¦[8ÉH•„Ì!ebÄî?4(‡1ÝxæÐÚlf£R[0¡0Ñ⩦óÃ/{Ã’Ç‹rP3lj_Þ †o™øä1´¿yª:þÿ4r°§äU†Ò<'éÖPp9vΚÞ*ß³@^Å=ÉMÌ\C¶V©ÈÀ$$¡'횯b4&ðE0«t5ms•„(ÍßH2Ì!sÕ/“Ï_ùÆŸ×ÎA•d;ãºE’y±™Ë×4œ†î6©W*º«ÑÔ½s•w1rS.{¨·ˆ9èý“?oX2Ç ±É·v]ÎÔÂÅï¿[}™o`Ã$úT-s4@"`—áp¨È',y÷:®Uç_3øÙ–_Š­Rµß[ªQÌ §7kÎÅÏž]Ù\ÇŸßö’³§TÈÛN??~}å H:Û?ô=v…3TèôŠ}ü ô•×W[FZ–éÈšG¿ÿ¯ _üö ’«G"h(øÏ‹;A7ËR©B³=~j»Ï£ç¶þˆåzOqÖuf‹öÛ¦†º•Øá¾ÚÙ\Ð×_~"!²Š™aøþ}— OnŸ{ü>jr$}Ã"íÝ4sŸÕé7,þLÏø÷)Ÿ¢£š²¿¾õ6T8JlËÊÔ¾”¤€¦\“ú5Wž)ñþ×$ô<àò:;d³ViïçB—tØïçIŠ• øëÐ…N·73TuyüºQ}ßÉ&&Šoò,”Ɉcç :eµý±t%åµFO½E4Ólùæ)Ãú™Ô¢æ¯ß¼ ‡¡†ù4¼àÞÅ(óL‘ª¯•”_üú;’ã2€Å-â+¬íÖ¶a7ÎŒ"™­óh¼†-#Lbb °Þ‰Ç¶\(->ÞµÊ6ÖØ§ÏH/ZÒmd›9ãsSz{¦vî™Ú33sÍX#Ÿº64œ£½}-þòˆï•™B›cÀü§“Ëq©¼ãN?Âà¶h£»‹½ƒ‘ ¤’Z…ªý8$™xô]"”9í忎†…è¦æÂ·ŠòŸR/öãlã ˜s¹óÿ¡wôzº¼s»bšI©èDŽB×,cÊèÐx\s5ëu@ sÂöM© é2Î,߈ºN¨Qf£Æ÷øE/¢àY›alÿ4¹¾¤-K_Z Ñ(Ò¥i›’lä4yÿÌ(®1¦9ŽÅçë×ÚµÛQì?=ÅqìlÐ/ùì’Ž=Ó ¡¯£È/ÉV$U!øÒÝÎYJÒ‰U;ÒJ3ödV©`Ô\Йâ§WzÐ%dd<1þ{e 9 Ú’¤ÙÎ\‰Y›lB-Mg…ueÅ5ltoÓ«†zõ•–ì†f­WíïÃEΑض³i¾¤ô3™gCµüÛq›{hw°I¤Pmšß¹Ù’)HÉ4eãâFUnÑ;'ûÈŽãõ¬&FndHc ¸mâ’‹éGæÉ¾ê›NÀÜø\5ýÃAïéÙ—Ä01xËþ· Ê(bhvíw•ÐG­aO¾Z“׿æéãjÃM ú ;eý”ò¤ˆ ‰‘lgˆI‡+‡º2B®àŽð7Ö ˜æ÷çÛBß…%n~m\T’¡Jõm#Á(²Ïð<@2üƒ©/ÊõÇz{®ºäê½·w¡­ÒÄaëuûÖb#á© n¢sèm F@Åñ±[6õ¸ì©…£¹¤·@ó–‘j¹Mñýpy°j`§t~ë~oèu'.åôNç£na¦Œò1µÀ+¹‘…µHZµÑôÄ ë$+vœþÄ{e@X™gº‚Žœj–‚×Ð3)¡}ô6Ú&ßg ÖÃC ÛÌÜß<q­˜4!c0qZPn¸•ê×LÄÜ~Úüw¡÷¥ã~ ¿ñWÓ††¶¨@WpbFê¦0 ç€;8ýX˜°VèôʱañtL¼SEÝË”I÷λÓWv¬­wß•ÌÐ]¤•M/vv:WÓ¾"ˆ ¬sÒÕÝÏ|ÊŒ!²èÞœ†ø}·í^ŒÁ®ÄYWzÇã´‘ƒ‡2n‡ö<ãÕtôúÉ/çņù4Zg3¦Â æ²Æñ„¬2>(ƒáR¢%•/¸>Üó‰‰@ï5}?ìú×ÿl›Gw9xôW1±xÅ µ¯·fµyÒn¦éª‚H7-@†*ß–'iƒÐsI’‘üÁuƒPÒ0Ðç zqQéU&Ùb\D¨«ºµO(Eb§2¯£©F¨±xýJŒ^]œ|×å*­[rACkŸýÉÌ&º•€Iüœ93®lð¤:M>Øü“9¿ƒ6øƒq%!JµöMMÆÕ‚Z5ri”)ý\@(µ/¼ÿ2_µ1R]exw›&€!é‚5“5Õ ¦ž‰41z0ˆ7!ú瞯{Ιs‰ e›‹vM·ã2wâ,J‰„ »ÚŠÕ4@ÓZÛš´%´6b]äíþ( …Øb¨Õ"Ö6qù¾çÎÌnçRØM9ÙÍ~̽ç¼ç}Þ÷yž÷{­€vÃÈÖõí?w]ôù{Â{Ø2žRõRxj÷NÝ´ášìŒO[xìMÚ#ªvîýIþ”‚4ùrrkÆH5ͳúÄQN]«¦'.ûn)‘µVE\7í+ú¹G£$Iàý—¯Ì] tÞ·-“b_kîÉg~²´µGZ@2²o¢šå-~­ÀÍ/\¶Â 7èRmÏû™’6zL;˜Y”zO»ŒhSxivÙ°½ÐyÝ8Ç-¸2è7ÝÖÿ –žÏ7쇷wåwnR–h 3T(p8¨ÍE¾9|œW1ÒàÚ¸÷x£¢ƒ¿XC”뀴\±ëîô¸ey…,·¸÷Z~šŸvî2 )GDØ;ÕZYx’õ×w“˸ •2¯mÄÂfЩYSÌ6GÍ­é]ù¹E2 éçiÜ·¤÷{߆:~2šDñCǶí>I 0S ³ŸªÖvv_™Ñ|àŸY¾x¾hÇî3V'Ð{nï[W˧ïJ—`ÓºÉêì&$ë1 ’ôEº®é:ð¢{K ˜‚hÐ/@5Èû\y"Μ϶†Lu½ ·]YêßÛéÕ¤ÃÃÒ˜0b,·blk¥6V{Ö·ieÏ~‚#$ç- ÃL;å¼û*Wü >iºîè‘ñ°#è¦{ü[êé´\ž÷Àé¯ÿBÿ»Àë¾Ó™9û]‡{Jsú‡º>cé×'ñàxFf‘@Fÿ‰£¨ МÁfŽl¾ï÷*§^Û7ñÞ{6vx–BÖÔi3OoÑVËp@O⤦' ¶ƒû¹P–Z3ÂDÐ÷Ã*VÇ=+wñß·Žä(Ìv0!}²tIŒ¸Œ†fF±=B/LmGÏÒ±ÓQÛžðc­ìW°xï©L— A‹ò%Ô ¶{Gp_·x†Ç˜ÍN¿év¡ïÈýrGvû!¼r}Šžø¼™Ì†¹zðbM˰}ïýRÿO< ^#¦uDØBppç6Ó“½†\¿‘kÆÂô µ¹Nëk9 ¡'ùݲ«\"öºŽ ï^}$˜[ÑGšA:ÒO¬‡S+èUÊ.k»õFņeë|‘ÄU÷;­µ‰9‘i_šÄ²è/jíchðÑœºƒ3ŠhVA¤–¨Ü œ÷õ|y“³/CT;„ù–Ó‚$ÉŠ;Ìýt\ci¶½¼ÑbúÇaT|ŒgaÚd× z»åå£ t¤*(ã–•¸VД´TÄÆùª»›v+'E·Î4Vj¾¨tB45ƒfÕñ3%bÈ7A’þÖä‡;n¸Gª™­MAbÀ10®^šp5?UyÞjA?çÍ&bÙÜ€ÞÓõ©ƒ1)ÌòÕ¯âN ‘i™pÅe”sйdÆp#jÓ^‡bŽVi2”܃.[AO7 %¬¤ËŸòµ4š,‰f½ÓÝèfl”6‡îhW"kZiËÀ‡ÂÜþçNúˆÑÊÄYA? £ŠXniER…¡Rìí_ñ¥Þ!Š%‡\e_0}ŸfЕæûR—y€‰Ddõ³š…vî˜ÌO@û0ö›šh€‘›#zŸ›¤–S VbÉ£‡«i]Ü‹Øô¯Ào0({I,˜9(VìËæ!˜T‡ÌÔh¿•Þ/P ÂR”_ù-ü ËíQÃùë½9™ùðžÍu5ž zMn‹-˜O ŒÙ¼`DðA*-~1Õÿàî Øs)–rkºø.W>iÑt°Ó&”¥P³Rî­É3>õ.ËH’þ¸¿æR†vÓfÜž.Ÿ+@«€À„öÑÄÛg©õòšƒ½S‚­Í@¯Ä£[ósz÷ÍÀвà£ÞmL½ ò£È[RȦ¶jÂ"dîM¬  I/ =äm@ZEƒýŒ°Á7çS NùA=Û vKì¥5mîtT¡âÙæçIhÉ00)¤°¨pªÚÀzË‹› Aüo˜ )Z;]­J 3!ŒܾókÅÚØ‡–(ýkGMµørÍþ¹øÐåK—/­=ùèZ¬ìý·µ5ÚJnìwßw°ïSbN@ïîº$Û„ -425\/5i䨭 ‰j6rÀÕŠÛ-d­wkUù†Ã© _Ø6fgtÉfÝÖ zâ@' ÀÁ3¡Ƭ"ƒ9ƒGK/ML§tŠHÐ3³¸t({` ÅáÍl(iÿùÔ› _w“¶ÓyVŒìrnZ¥ê¿¤~²ÁŸg¬P†s8ä¥ìsø.>Ï4äFÝÆ>Ðòv}jö•AŸ×ýbV# õüMm0¼z´q×ܨ¸÷ :ÔËýèâ´¯ìnùüƒ]“‚ "YRàK`<ƒ7Çõø‡ÿظ÷cPÀÁËšAÏYžo;3Å ˆžúȽؕ‰Kt>ouâ=Mjö¯>Ê(@¼“-{Û•1)<~Œ”"‘ ÊÚ\2]I:‚Þ Ï«ÃÞ‰Þ»6*p’02")1žo ~hªâšAØÅ+iVºPŸ;oÐ8i­Ì1ÖHš€= Ätc¡AÕ[@—)¦tÿŠ w÷|“DšçL)Šde¬Ôˆ´q×s¨çâÚAGå¦ðZÈXÓ²ñAƒj@´òcA¡7!aɠаJe©”Ôva3è"/`²Êš …\úBš§AW“ÓWO§-xfHLâqw[­ Y äÈØüø 0y(•aªˆ¶~(é@ï=]= ¼°_©Ó|ÊŠÏ/¹ó.q‡–œ3Q<’ÔƒšB­‚¿VС¡òá’“þRU/U7èº$¬)©/œèL·Ë7Ô¼\?çT(Ñ”µ¸w]Ϋ×Î[iKp=5áÞúCwëNçmº˜ –Àæ¨e7cÅ™ÊW·õ)c©ˆ”yƒ/{­ß¼F¦ûr¡éx=OíA‡>ÿt×Uèý!M¢ónè‹Kó²@d!°ÛWô>žÖº‹ÁäHä5ƒ.Òèªÿ3_õ±mœeü¾§ mj»–®É «L%¸P©±“8‡­×1Rä÷ìóÝùuÕnkU[% ¹–g{q#!S3˜ ë:Öѱ• Hi'1bjº¡†nÚ`+lÚSa+­R`+ôCTžç½óÙ¹³ÝT•Ö¾Vâó½Ïû<¿çã÷ä*ëQKÞù«:¤é±º÷‡pIYIš†QÐO¸@|rwB%>ÐI<¡¾?CŸØ’ãà*Šª)‰ƒ¬_C‘Û[Öô°¤1ÂÝôÎv–-(âwÒƒ@ SI5­l{©LYÛbý%]H…jçh‰löÆûZƒU]øoþWcmAp{ty=2Œ{÷Éñ˜®FvÉ™úå–Éš’*.8— ºQHkrwöA¥BgÊÔ;µ@W¡žÂ¢-°äÈã*A~-ë ¹jMέªj¦bÄ—Þ•x¬ëu(S»îÁëk/Ì‚õ,XÊÔZɳû¸äøÑ­¾}ë­Î8ùó侮)¸î›pw¹Û4Љ/Rvby}ç¶d=ƒh“o}^+ÐEøð+®ûœýkÕâ=Í@¸ohëËLÄÌþ»¦€3,ß|„²ßeàˆ³ÞË_6èšb˜jÏajŸùÑÞzd(F2®¦Ã‹gÑ®4óÕ ‡¦~ˉۑrÌÀI3Ý×ѯÕÙûNÀ‚ß0ó»$Ø×Ôÿ~+Ë_UÛ¢˜÷z&¤¤¡~ \6åhi|¥œ)®Þ¤ žÙe&«ßQäÜjø«9ÖÆ¡Õ  ¿|Ó¡Ö†ÎÓæÜ,ÉÃoÄ`œÒ“7Ll{3¡¯ÃlPfåó­B2z+q•(§)@$éTÈPIR5¦Súˆ¶Uãý';þ™¡Æ%#}7'øQçÿ¸™V,êø– KsÈ"žèÉú•¸LÐÕD ÛES7a£ñѵl—=¡¬ÅDŽ¡žq¤2Þ„wòcÐÑ) !zÂeï™IbB£ëgpeÛº0'áÅÓ«äì¤ÿzf2ÞŒYŽúÈRt¢ÖÍjhº¦­­Ã¸YV‰ªˆvCÞö$aÌGŒXˆ>Y-Ï‚Æö ‹¡îÿÀÏ&TnâƒY‡¸9‹™`æ·DK›W ºf$ fóîìÞ½v"½ ›Þ˜™CÃ( ¨2}¾‡“%Ã0ꑾ¸É$°»_ìª2t2V•m.³®fÞ펛=Ÿ½ Õ‘ÑWdèñϪPíˆVÏ$”'fú=dj4Á·k!®HfÞ€ùâ–æ/‹mÛ:L0ü¼ïÛ2×Ñ>ÒùΦÙ=È-WþÒÖ×i0ê©u² :WóŠ#=©©¦Ö3H!ýf£å¯2è:À£^Øaë̘œÍfè{ç 5" ¨)knM§{ 8Šfê± Û\Ú–[e´ê¥‡ñ™Ð¼×Ó¡ýzŸY—V?‘6b:°…º]uH*d/ÁÒà3=j\‘ ë˦1ùâ#´ì„J¦®<ytizµó¹ ·ÄP§nÝ‘³ùˆM2_?Ý•Ï&uäažKm¬`MƒÏÝOj1âÏ8ƒž]2o˜Õ’JážaHT-æìè‡ס³=ØÊÔ‰O/9Kkû¼ò í¦q‡NU6¦É4DÊÃîzï@ŽBÙR’Š®Lž{eÜbÉy„ãø½ç&á5NWOfó]îÆé" U;Ö󣟡‘JŒÑÁ_õø·’¾{9CIfW¾Ë4‚þZÚC‰‡6åZÚ­çßÇg¨ |Ž%[Îþ}aÂȇþ×Îù€à>9S–üô'}êÇÇ}áPhAh¨/Ú?íôŒìX¯TŒôF³k†Œ¡Þãb¸¿8=‘ ÷F£‘âЄ:”_ôåí§Àœ¹çî?±¼û¼:1TŒD£½½ÑÁþhßP¨¶¯‰LOG‹Ñb626“ŸùÇŸNaê}~ûmËÉPØ{­ú(Lï Eú£ƒ½Å(Yã³W$<Žìvåxí’½81÷Ýõò¯Ü п±ÿ{Ǿ¹,ЬÉF£¾"ú“÷ü"Ç«yÛ 81ÀÞH<ú9€§JNÄ=þм$ Æ–ŸW·œïN\-BâëP0 ˆß$¹ûàO²oË _g Bêâ |¶Ó~à?QmÝE ãL:/:gÖ¯}Kìàp]^vÀlV9!1Åá 1y,ˆø0¥ \£[CF@¿åësŽÝ%Qø6΂½Øšf)‹Ÿ›˜‚¾´Á» ðç¶-ÄÍtÞ9ÎrÍüÚˆgÏq­c½Ã‘ïnc¡Õ¡³Y`²3ƒmìÂÊBã+Þ¾;&%ÁŸbæ]Ó&Ù¶¼s­´M‰ç! ZÆ ”_ݰU?å[ÍãSP°ao@‡tÏ·v.†xÊqm‰Àóí@à$•ØZÕÄŘîé5#Y1þÏ~ÕÇHU]ñsï}î²à"iYìØ]åÃa+”Xˆ&ÄvAØVÚsï›Ù}ï;·ìÎÊìü˜æÝwî9÷|Ÿëì*Œ§Ë!±v0Ê·\7´ié½v$1è©$h.ÇeÙÍa"ΕO”ó‘z=NWQÍì•Î*›Ÿ]S²8ËwÊ#]5ÇB6Z'éî|Þ÷Š™nAw9] jé̦§o¡F9i%àu¦§e™ö^™Ñm͹=Ù2pgêº2*Só‡4¾m*áo Rv5=F ݦñÚ…+a²‡düv¼±®Êãèpºœ6ƒZO…—Óí4yQp:Cº<QØÈêéM¸ˆ‚€Óé4®;ú@€Óé²®kÅò^øp•wƒƒiöïyŠÈ\NŸµûbqxp9}Diµã˜`¨²ß5ë ^º.z–¹ý97eóÍ€ƒÆéeÖ<áGß½QIá^A¾çòèê¶Â¤ltEµúª)ÝÊ{Ju{C×:ÓUß÷/ $ôpˆá½\ 譀ܮ Æt.yíô?—G Û`Þª£ðàÃÊÓÓûˆ‘wö¼IÉqFpà”Ï„ÎÝªë ¸ÿ€(“GäroPvqÒä'€“W:¥§¯q V™ùƒ‡Œ·jÊÇ1MË Ú"tÇ©(N7Í€æï}%$_ú´Ê}&t-{) ѼzH‰ÂdPBMI¥ýãÓ’qv óôP%!‹…oRDšãÀTzø¶4]v=ëÞÐÓbd/ëV>Ä)?z8¿Ÿ™­NV†U¤«úàÝÛ÷P½xˆy'ƒù—xîØbRXÜxXßTÅ•yA-5KÂ=¥Y† SUª‡•³_~iè¼æèþýUÜ­rõzšU–D"û'xé2ˆGšã‘jg¹‘Á‰úÑWE£ñæ ‘Jïa}é3rîW¹åPOBâ¾ô^=¤&ñÉQßs®4ú=;2íô1cËKJËJ˼(ZeºDÀã_[‘E–AÅŠÒŠ¸'ðŒ¥%~ôÃËÊK+JGF¼ÆòA\ª;äÍß—–—”•ûÒ{ô­phi‰¯"…ª‡.KÖ´_µÚë뛣‘xԃȄÉ[;Ýz̲0Òì¥ëBUý⻫CÎSq¨­ó%Ç«èo꯱|7¤Ñ<ÞíV[FöWùÑgé!À˜Rßœ¥oÁëႜAzí9£»‡SLš¾Ħpu$ÕÿµÀ©–åpÕÑÕÑœ¢tÏÝǯ¤ƒ©^? S×ÅÀçê‚n Ì8}œa!8ó½Þ¦ù÷ý¦ÃhòQï…‘SÁ³x8QÀz¸…3ÈýuÁ¹nžÄF÷¿!0×liIøÞ(¸¤fÙÁè»! ¡ìâÎ-~ôÙzÐ9¹pz¸@¼‚ÊJ×úuÅ2%‚o9$ÖÿP½Êqüä×!¬¨GO/³ËŠjƒSy90ú2ឪL£Ð„  ¬Ïém“s£:‘ýíAT V¬ôTVì`r0åö±üÊ §Öç 69÷­oö“Dþ1½Mê"#¥É„´Ï«‡m'òÕà UœzÈtO°°ÞJÝFÜKó€Þk™ÿNôàR—¥-&AëQD¾!roý7-ýWD¾a·ðþI=î©EHhÞ+Z^Àõ´ì"ò²ºùOtérMë¯Î2ÐÁ 9¨…ò/WZþåA  ÙÄg«ûA.¼×0±XÝû&Àåu8$ïÖ§òþÈ™d4àÒYÄÿšÙŽgFå_.3wcª_. rL—ó!§(¾FYX™ûô.&mšÛΟZÛŠƒ\~À¥ß5!]ÎÃòYû &¯än}c®|°ï1#LñqlmñÊ–˜äôk44wfÅﵞɨÇV9 {Åúsîr‹è+tX¯é”㜙FþxèÕ¸:Uþ%öPã˜&&/ˆÜÛJ×ò5}×®Ú÷Åõ™¥7qöpd´\²ê¯lù‚InoÇVêÚt–00Vž;7<»wK[2yhѼv‘˜Œ1˜;m̪¼SLS|uÇæ-{§?¥è¸Øßð`ãZüëš5 «h Äqü5mŸ2óઓ;Ö¨r­‚/,ƒeÖ6_:y|–HÇ[퀺OœÜ|âÝ«UœÓâþES•ËHÕ{†œ¸tªc©É.”á,ëƒq·Ü·sß¾é“å‡õàCôÍŒ?­úlú RˆÝü£<ïH=yEª"þm“5FH«Q×%“/‹øËÊPÄyL>Ε‡™ö‹e‰¯¼‹M·‘É5™ŠVë?4; ñ¦µÇèÎ Îøß1Ù³0ñÒ$b»}5~ Êô]tà±kô°Û ê3lEDëÉwÉVª=‹a2AkM”â§Ì){“ôˆÉØK•J˜L^· >IÜ&Ã’Ë4nÿíKпÕ5*‰ ãÒÊOjUº¾÷ÝÖZ$ëÐ`WâšÐIñƒNTLZ;_¥Â—íÐwmÃ&K.¶åpëûâbs§*·µ×¾‰83]ñôGñôøYÖÚ5QkܘÀ(ùœ²Ô€Øó7uÚ¢D|îÃ:_œÂ9þ»ÉøÿZ¾cùp¯|þ¹õ;YÃu™“lN_'CC /,} ßéøÏ ÿ| SßfTDZ)Iòeìa¹ñoøõ[ŽàéçÚÎuÆäQÙ¨&…வˆ§÷Lß1ã4¹òW’R@ûy+ù‡¶G?z…üÞЩÂö Pç¹ÿÄ#Î-˜Oì¾ÃqõaðÈj´Ž}xû{ŸnÂcqªö“’¸k6Z/?¾éÔ:LÜA qÓu¼1™¨ÕÔa&¦Z^•6£¶iÁ± ^@k®¤"£í£´Ù¤ËÞ¡@p g«Î©³FLáºZIH¾ü¾ZWB\LáÙïQwÕ­@¤2-ÚRx³+'‡S¸Mæ|(‰³Ï¬¼Õ z[O[­¥ÊÏq-¸KV™Z"5—áMëʈZÓÛßAXRÊœçqåë²!ðý¸qCHÎ{0ùõúö&;ÔŒû“‰O¥Hó¹Þ!yjç,<èÈtYêÂpkÌzk©TXëœqÏST-jjz¸€Sòyˆo;Æ•›WcÉÙ¤¯ úåoáQ\¹žÜHнŒ‡ÃcᔸÎàoÖ&ž9a-o´l!‹>ƒo˜Ê²æQüwšªf1m{Slt[æë­JE¤Ïm™VDѲEÍ¢ÿq_­±Q\WøÎ½3;ëV<\‚Ÿ-¥­Å-Nq$@mZÞò7Þ†”d,-efã]ŒK†”ÄæmˆI"ZPȃM"b ™Ðà"ê ˆ64vSÛ"Q‚1=çÎâüªÔŒ­ÝÙ»÷Þ¹{¾s¾ï;pŽ‹ˆl}˜(ûÈO5£XVOàk¶ûAøùº[„ì‡j”죃A™@–©mVËnlo i/hŠîq 廑1” m)ͽWšL* €!tv¹ÐE–˜Íý×íö8HvnïÕ»•Ø'òvWÿ¶-‘Eg;}•„ŽwÈ•ò_ïþß.û0nz‹·u<í_Díëh¦wB£‹ä)\îÚEï$î§š9ŠéDÃXL¿>Ý&9Â?`š­¯98©×pZq§ rø’#LW˲DƒÅÌw‰U"¼ õlÁwÂÈ?LîP鬉tCR2øÇQݗƵß3;ôpŠëüÚ4”ÕÑ·RØ,Þ‰BÙ|6kU¡—ÇÛ8ã  »Vë&«¹Ø!ù~ W0øð¶ð,µÑ)©äà‹  38¾«Ãmøâb¢Yñ`Ë\<Þsá¡€Ü3EŒ§Ú¬Á¿Âú´~’+¯GKAÁN÷S ‰-"èì*P¢;Bn§6#±M?‰È®jð7ºÈ$|,Î"b¡WáPQªµ2Œ›.MK4yž>UЙšVÛ¢UÓ¼mxnt:ôYøån¢‹®ž<žOlÝùfNþ`·,ºV¿¨D è"lvŽê&vFü’Ézÿ‘ó¤ð3µOKÜC©áð'R$ìu@1á3•}•Úéu åøoêeèJWV†„Ø£ÖÐSNzÈMœF¦^ðwHµmôc£t.YŒФ»¾8GÙ¤"%%ú{~>iz&ü©X¡ÅŠ<Ê.l5Ø»ËÅNˆ ]k‡Æè$²o‹Ïû‰B¥3–“aœñw¼£Ë*ubQþY¯áDñø5—^Ћ1RgpŽXMdÄüQ¶Úƒ ŽÔwëëp¾g8û] -“à„‰qy¾éëg³P_³ºÇLŠ1ÿQÑϺ –Õ—b§Ñ5¿Ä¡H´Øsºi=âœWysŸâ‹8•C`Ù¾·™¥ ò™óziãš~±4¯*¯jiÅ6¸© -2ô…§‡œ3®œ+gcïZ —½›z¹TÞ¼:þPÛnäˆëd[È[Ã,§¤IÿžU Œ¼ è]ˆÉÀcdy{àaÈ HH6½xJk§X ‡k{9¦¦ÆO?Er¯©ÆJ’Ì1,ÖÖXRÐÉ(zHtª…î%p‘DM3MŠ0–áçœe´¥il@¥óy—¶gõe[ÿ¬ƒ‰!M×ÂŦ¶}žÇA~c»2oÀOZAs]1Ô×%à{n “`ˆued¿h8õx-ý â #™ü@K“¨ÛëÉûÞéÙSŒî‰mñ×n‹N+ðC¥™½IÎ $îü–Í9I̦›¿»°­Ñ.3EqÛ•]ˆ^IdØ*î *š¯#FC¹q,ºÚó( õ•œBÉfJ nÈhß¿%sÊ!0÷± 'ØaçS–…TÙJªœ­Õ˜ó²U.ê„äVĆßÜ'ÃZaÛ*1ÏGoE¦Ž\Á™O·^9seojCCÃö†­åÌê9"ü½ì=qJ…ØûÑ©B¢þqÝ•î÷IúOœÊöü$`í2\ŒÜŸ‰> ³,éOy‰iÿ) þ›Åùc4"ß;ÆNÊžá¾"ìÙNu‹Ér(סè›ì`ßá° éµÔ;(WZÚåjïœPÑ¢ø Aå5Âÿ0¢VĽqì:Cˆ‘õv9Õâb&x›ºAo¥¬ æn&Î~®·„g‘ãS–,…oi÷eO º¹MoøýoÞGÔÓ¨Ïa*çÏ2KkMægjùUš¤Œ–AŸ µ‰ÝeÏ8½Ÿ\‰I¿œoµ%:quY¬à¶ø¼ ?=‡VY˰ÿßûÿÝ¥TÊ/—ª;¹xe¥ÿ‘°÷à2ë/VÐmßÃÎB‹‹vƒ³SDד“£²»Œ$+Á猥±Ãù“KqZh=n3sáÀ©KëͲ%c)7÷ qJ³î ç†àIº¾u¤×îðm•7Nn(¬”Ô‚ðyá_8ëÄ$_³ND—,eÒŽ!B‡XŠ]AÝ×19±–8øŽ6kºw$‘ÑS€ÑÑs†ÄY÷™ÛÂSù"TkYAß¹Ûÿ›!¤¼mÖvQ kÄX¹éùªóssŸ_¡5•b’ª$²ÖýD³/eDÑ¿Q4H*Ÿè˜úD?à TªŸµƒû²NOHë¶ôQe‰&Û§ð[q­&^Ed¯ø^Äm*TÖ6àå ÆÆ“8Ò¶KÄtPÍG™Á½ÛΖTÀ*hñLJ1z!nq±Ó.›¸5‘lPK´5Ô­£¥ÿ—zèpJKZÆQœÈ¹5>/»çÓw$Ѳí»t®QTצœ.ú£œé`ô( €ZŒ¹õW\ª…‘!Ž—ÕÔ!o§•Nˆ.†¬Ä'lŽma!ó=œ0¤Î6Üëè³Á¾ÞDüQ¬Çú%F6æŽÑ,LñOèWÊ È®q¶hšöAÿJ[|ó¼BÁmœ†Ð:†aŠO¤||(t+ ýÂÁt2E+s½É§¸Œßó(ˆo§WZåJsñ/uæ[<§¼Øqk|RxÂÄŠJüÄ牻À½&¹H¾?Ü—#Mÿ‡ñj‰?¡-}œÏJcW‚ß-Ãé_=kŒÒA¯E±ãó‰ìy™°ž@U¹³‰í9Å'ƒ ‚Šnü…]6½1Mt%&N+ïW|7¿M\’£T{ü†‚³™)‡Ž³ ’×r]BŠË3¸Â lÖmaä .Ñ0ÐÄSgQCe ¬¨þ6ím]¯ÁòçVÊ?Ê;¾Ð›Ì]"mxí54èjíüÖš(Ñ„ÁZ}J”ÕyÌJsD¯8~`ÞîÄÙ¬Çv\Ué¬ßêÎÁ[íÙL Ýg¬¶¯äêÿàÌÁrÿx.ÖOb{FFðþ#8²æ sðâ ­ÝßXþOö«&6ª* Ÿ{ï»ó&"±A1D(?ƒ,üC"D¢D± ‘3aÓ…1c1µ3aHCTŒ’&ºp,AêÂc”µ‰bMlâFS:QSÁ‰RYÔX4X¬ÕóûúÃÊ•­-sé{ïÞy÷¼óóïãî»åo†ú…šd(WÇÜvŸƒ}¯ùÐrÛÛÂs<`l‡˜O¬lXÊŸçw[=øcoðÓRÖÕqKLÓ>åÁ3÷¬¢”’/`.Ý8¾6\8‘~ª£y÷]âL;¶ëÊÌ;H‘ßfVp_–¦—HÞ+ m%Òv<ûbéÚ†Yo'üãêöczZÖçScNf@Œ87áU:~m¼‰ùÃ%7½%•ðJ íö9ÌË}˜Ì³8áã§ò‹Ö瑵Xu5%É/‹Vn{ñ`‘ç‘$Ôd¹e6Rýç9ñøþÇ^¿¹7«(ê­ WRBÙ_EYž|+Ÿ?u<áž M¸W炎ø¬¼eúwºŒ@s¦,5˜áÆGqù‚gß¾™wÍ¥¬º3ThúÃ2µ÷Kü’Ìa‰ŠôUµPì~!´èï\8ˆNì­‡¤†öÇ-FÉ€ø»Bò:ành7~6æN<ÄUäG8Å6Q\R5—¥ÑGxßÇDé<–”òÄp'sóî¦2·$ ÷wt䨾“ÌEÞ%?nÞ¨`N+˜—(¡Ør%‘Ç 7qÏ Q=ó¡U#höJ¡„#ËœüpZ*ax!w×S˜ÖV¯ð97f:lOeh³p` ¸ âöKW±™:dÁ¹YZSi4ˆ‡tÝÞ^yDû/‹Jø´ý åòÆ÷ÇNË(—äÑÎÙ—û¹t¶s;g ÓêöKj,Ñ?[ºêÇÏÛzi©® Î{?9PüæÛ7ųú ºÇ©ê¢†ç“Nm´ÉöÎÃÝ|`ðèj'tŽ÷žÙׄCšå–_ÿs3ó{ëóòrS¾²aÔ1éõù ÿËIfBÁ5z¹üìT»S³É0FͨܽÐrqª½©ÙdYP;î nyfF Æšý›9p€¿ïpË:¸ø5\Íf¾ž¹®Fîgî$—›jwj6)æ=ýõ—ø§Å¦î׈©ôËÞ¹çAUq5t¿6,"{ȶ t[MêÖ¬f5û¿Û?R…ùà endstream endobj 2116 0 obj << /Type /XObject /Subtype /Image /Width 129 /Height 128 /BitsPerComponent 8 /ColorSpace 2103 0 R /Length 4903 /Filter /DCTDecode >> stream ÿØÿîAdobed€ÿÛ„ÿÀ€"ÿÝ ÿÄ¢     u!"1A2# QBa$3Rqb‘%C¡±ð&4r ÁÑ5'áS6‚ñ’¢DTsEF7Gc(UVW²ÂÒâòdƒt“„e£³ÃÓã)8fóu*9:HIJXYZghijvwxyz…†‡ˆ‰Š”•–—˜™š¤¥¦§¨©ª´µ¶·¸¹ºÄÅÆÇÈÉÊÔÕÖרÙÚäåæçèéêôõö÷øùúm!1"AQ2aqB#‘R¡b3 ±$ÁÑCrðá‚4%’ScDñ¢²&5T6Ed' sƒ“FtÂÒâòUeuV7„…£³ÃÓãó)”¤´ÄÔäô•¥µÅÕåõ(GWf8v†–¦¶ÆÖæögw‡—§·Ç×ç÷HXhxˆ˜¨¸ÈØèø9IYiy‰™©¹ÉÙéù*:JZjzŠšªºÊÚêúÿÚ ?º~÷ïg âWLì~à«ß0ïJlB` Û²ãÅ|´NF\ÂÕ™š" ŠR† ò–r¤ϺÆ]·oŸu½‚ÂØÆ'¸ñ<3+ôây›Sr;#jvœÐ ‚{ïÞî[ý’ž‰ÿVäÿÏýwüSß¿Ù)èŸùÕnOüÿ×Å=îƒÔ?ót-ÿ[Íûýû·ÙDßöÍÕ4û÷»–ÿd§¢çU¹?óÿ]ÿ÷ïöJz'þu[“ÿ?õßñO~ õÏüÝ{ýo7ï÷îÝÿeÛ7TÓïÞî[ý’ž‰ÿVäÿÏýwüSß¿Ù)èŸùÕnOüÿ×Å=úƒÔ?óuïõ¼ß¿ß»wý”MÿlÝSO¿{¹oöJz'þu[“ÿ?õßñO~ÿd§¢çU¹?óÿ]ÿ÷êQüÿÍ׿Öó~ÿ~íßöQ7ý³uM>ýîå¿Ù)èŸùÕnOüÿ×Å=ûý’ž‰ÿVäÿÏýwüSߨ=Góÿ7^ÿ[Íûýû·ÙDßöÍÕ4û÷»–ÿd§¢çU¹?óÿ]ÿ÷ïöJz'þu[“ÿ?õßñO~ õÏüÝ{ýo7ï÷îÝÿeÛ7TÓïÞϯÊÏÝsÔ›#œÙÔY:|†CuA‰©’·-5|mE&'1VU!•ˆVi¨¡"] €Œœj#Ù ÷®‚»®×s³Þ=و̈ŽL,ÏYRљ֜{E^÷ï~÷ï~軯ÿкv5ü½ÿâåÚõ´÷#q{®_v5ü½ÿâåÚõ´÷#q{÷XÿÉŸò³mŸé®¿í ç«6÷ï~÷ï~ë :÷¿{÷¿{÷^ëÞýïÞýïÝ{¯{÷¿{÷¿uî½ïÞýïÞý׺÷¿{÷¿{÷^è‡|÷ÿ™_³¿ðûƒÿyìߺ ÷kÿ=ÿæWìïü>àÿÞ{7î¨=û¨#žÿåaŸþy­?êÊõï~÷ï~÷îÝÿѺv5ü½ÿâåÚõ´÷#q{®_v5ü½ÿâåÚõ´÷#q{÷XÿÉŸò³mŸé®¿í ç«6÷ï~÷ï~ë :÷¿{÷¿{÷^ëÞýïÞýïÝ{¯{÷¿{÷¿uî½ïÞýïÞý׺÷¿{÷¿{÷^è‡|÷ÿ™_³¿ðûƒÿyìߺ ÷kÿ=ÿæWìïü>àÿÞ{7î¨=û¨#žÿåaŸþy­?êÊõï~÷ï~÷îÝÿÒºv5ü½ÿâåÚõ´÷#q{®_v5ü½ÿâåÚõ´÷#q{÷XÿÉŸò³mŸé®¿í ç«6÷ï~÷ï~ë :÷¿{÷¿{÷^ëÞýïÞýïÝ{¯{÷¿{÷¿uî½ïÞýïÞý׺÷¿{÷¿{÷^è‡|÷ÿ™_³¿ðûƒÿyìߺ ÷kÿ=ÿæWìïü>àÿÞ{7î¨=û¨#žÿåaŸþy­?êÊõï~÷ï~÷îÝÿÓºv5ü½ÿâåÚõ´÷#q{®_v5ü½ÿâåÚõ´÷#q{÷XÿÉŸò³mŸé®¿í ç«6÷ï~÷ï~ë :÷¿{÷¿{÷^ëÞýïÞýïÝ{¯{÷¿{÷¿uî½ïÞýïÞý׺÷¿{÷¿{÷^è‡|÷ÿ™_³¿ðûƒÿyìߺ ÷kÿ=ÿæWìïü>àÿÞ{7î¨=û¨#žÿåaŸþy­?êÊõï~÷ï~÷îÝÿÔºv5ü½ÿâåÚõ´÷#q{®_v5ü½ÿâåÚõ´÷#q{÷XÿÉŸò³mŸé®¿í ç«6÷ït‰üÏ?Ÿ'ÃOåo¼öŸOvn;³ûƒäøÅÑg6ÿHt¦ œÝTøŒÆLâ0Y-É‘Ìg°¸œ2î:ºjÕÛ¸±&[qæZ-Tø_ #µwÅÿ Ìø÷×›«na¾\ü ùçñlî¹|XMíÙ]cO&:XV岇ÈUmÃ]GKa÷GlPnZÅŠ7nºÈ¶Ë÷ïaçWvvÁîž»Ù]³Õ{§¾:ã±vÞ+xìÝ·êf#píÌåø¼H ë)*¥ìàQÃ*ˆ~ý׺÷¿{÷¿{÷^ëÞýïÞØ7j ·În´•è°Œ¦f±)ìf–“AS_:Ó‰V©+LÚUš×>£Ï¿uîŸýûÝvÿ-ÏæYñïù£tNG¾>?Sï}½ŒÀnêÝ—º¶/ebðø-ÿµòñã±™ÜeN_†Ïî/á‹mçq‹odé2­v.°2ÚD‘Í|–ùÖß:µ¾FöþV|W[tÞËËomÑQA¬ËÖÁŒ…¾Ó ƒÇ‰é¿Šî=Ë”j=»¶ñD9mÅ–ÇQ†MCÝ{¡ãß½Õ÷Å_æ­Ðß-«þ$cvÇíÝ»Uó£»×¾úî-ëƒÛ8ã·6¿ÇîÉÀõ~óÃoAºò‡¹*·å¤lMøÕ#R+ºÊ2B{´~ëÝïžÿó+öwþpï=›÷Tíç¿üÊýÿ‡ÜûÏfýÕ¿usßü¬3ÿÏ5§ýY^½ïÞýïÞýÐ;¯ÿÕºv5ü½ÿâåÚõ´÷#q{®_v5ü½ÿâåÚõ´÷#q{÷XÿÉŸò³mŸé®¿í ç­xœ¯òšïîãþiýuóÿùwüºø½·þ^m‰ú°Ô|î>ÇÚ8}÷Šì¶ÃÓSlìÞËÁf)w=j“qíŠ|8¬Ùû“ ‡emYš*ÚôÌ[M>{|÷þv= ÔTÔ¿Î{ùH|>ùSñjo­¿‘×3ƒ¤ÉmZãRµX .GûË×ý“¿6ÖÛËe©òµ¸lEnWaáܾ\Q„gqº¯æËÿ ÍÛ_=¾O`~rüjù%Ÿø}òß.ΫÍnü^ÛªÎà÷V¯i©1û'zÅU‡ÜWrlýù·ñœ>&=͈®Ë¤˜œ."7à "û×*Ýýüƒ?œwÎ-•èï›ÿÎsØ=AÁå³Wkô>“%›—Qô5™ˆ0Ç`.äËQj¬_÷Ÿ3š£¢ÊŸâ¡ZUR}Ö@uTÿ-¾Tçúw­¿•óÅþZô¿Ñ_1›º‹¦~AüÛ½Ÿ§éîºÞy½÷Y­¶6]&ŬÄv®ÙþýmµÜ£EFk±;;r}Žr欧›ùü¥íOæáüâ¾ÿ.ïƒ_!»cü~Ú}}·{ãäWcôwfî’2[?±pÐÜošÌì ¾:§î1=>›Gnlå­¬+EØ­öIêŸù¢Õÿ*åüŸjÿ”ßj×vR›³þ>vuWFá#Ú¹ǽû+·°û‚›uSöFkzcöùÙ›CqRvþW ¹åÛ AE‰_ázI(hV„?ðŸåÓ‘èŒ=ó“³¶ÆG Ù_)«iö—ZSg1ócòx®ƒÙu¿tsðU«J>ÆßaëN¥Ñ[†Ù»G- 5%b–÷^ê¸öžÜù½óGþGüÃ~ u_ÏÏ’ºFÝ©ô¨Ù»ÿwåò;k¨6†G¬Tm.¤Æe³ç±7&gqUm¬O÷Ÿ h2´;hîPMp¬­Äåݶ¦åOòWÿ…|^ø‰¶>lüƒù%ñï¿¶®Üݯk÷FòÌn#•ÚÖÅÃäqÙÌ&C+W·wíÍǰÛrmÍß·h°ÕŒ¯Iþ1fÇß’îàøÙüáþUÿ4ªßxÛˆù'ì|LÒõÍV'´ÿ¿[ƒ®³4óϽfÞYJLÏð¡±M(Ó¶1:ÎRÊTO—É=ò{ù½üIþh4½ÿ‰ÚxOo®pý1U×5̆ó]‘º{qTÏô]ã¤Ã.V—}­«meôy%O¥‡º÷Z×,~¥ù)ÿ gîï—_%>_üãùÒý-Õ[§kmíƒñ÷ãwcTlü>܇{ÿyó\&3_O–Ûxœ>ÚÃà¨ék7-fÙËnmù™-W_˜¾wñ ùvÿ0å¯ò¯·v6ùƒm¿’¿ËÃ{õ–ñ£›¥þI÷èÏü¡ÚÕ¯Ö:Ü.kdí9¶®SlÑåñ’”ÑV¹¸¶ÖßÞ ½m~ÚLÝ%bJøN—Êoˆ(»Gä?ò~þbìŸmŽä¬ž³vtŸ`uM?dl¼wÜdryh0t‡"røm÷6ÝVZ´ìÔÜ›>MÅ´VG¤ƒrM©˜Ž_á>ûÛ¦>XöWóùÍó/ó7ænñÙûÃlmá.Éþíí.¼¬Ýû>~¿©Ü”tÕ:ººü¦#gÕVíµ‰ÃÑí ·¶6Õee –£zuî‹gòß)ðW§ÿ“çͬtpc:æ×Å?¾c%54˜­¿ÛTô*‡=ù™Y<µYœ¦kãöïÍW•DÃîí„Äë¢UkSùHõ:ÿ˜‡KüƧñ/Žÿ ¸ß5>iT@|nãí8«êæøsñç%Tµ$ê;‹–ù ¼°Õ”l•˜M›°þƒ.n8õÿòÔÙÔÿÊ£j+îÝÝïý±ˆøßAÐùŽÁÅa*6ìòæ0øåþîö6ÝÂË–ÉÔa³;csRâ·vÝÆ¥4yœ=y4!eü¸¾æ>tvohö/pdþG|†í]ý›ío¿#709îÜì >;lá2â¾ë(ø¬NÓØ;wim 6嫊,+J®¯•u÷î½Ö¿_ÉöF›º?’¼ò#Éð/ù´É#ý/œ=r?ã_ןõýî+ï^ üŸþW|xÇ|Ë|eùÓ[[³~õÊŽœÉîÖøÙ¹û'joüÉ®ïÄwEV;maû»aÖíšÝ¶p”˜}Å™ûµ‰P@ötöQÿ7¬v÷ÚÌù«ð·uuÝéÁVo±¶>vNÔÜ»‹hC”¤¨Ü˜=»¹+þYnŠM½–Ëa–¶‹™¬Û¹xñU­‰­Œiouî…¿žÿó+öwþpï=›÷Tíç¿üÊýÿ‡ÜûÏfýÕ¿usßü¬3ÿÏ5§ýY^½ïÞýïÞýÐ;¯ÿÖºf¡;ò¯¢êw5E.Ù§ÜŸÞHq1H“å$Æ}¯ð§Èº²´t5Þo7ñ2¦±mGI|÷ï~ë,ï.l.b»´”Ãq cQŠ–F»dVCTfSÆ£4=X·ü8>cþ}~7ÿBª¯þ±û÷ü8>cþ}~7ÿBª¯þ±û®Ÿ~÷îÿ®|ÍÿG6ÿ²[/ûfèðn¿—{;~M¨ßúçyÔbKœ]Fí8ÇQŒ.ÅÏðé²ûB­¨½Fÿäú.EÍϵŒ?Ì#i ]WŽãH¢Š-×SF‰Â…~ƒkX±½w{÷¿uïëŸ3ÑÍ¿ì–ËþÙº±oøp|Çüúüoþ…U_ýc÷ïøp|Çüúüoþ…U_ýc÷]>ýïÝ{úçÌßôsoû%²ÿ¶n¬[þ1ÿ>¿ÿ¡UWÿXýûþ1ÿ>¿ÿ¡UWÿXý×O¿{÷^þ¹ó7ýÛþÉl¿í›«ÿ‡ÌϯÆÿèUUÿÖ?~ÿ‡ÌϯÆÿèUUÿÖ?uÓïÞý׿®|ÍÿG6ÿ²[/ûfêÅ¿áÁóóëñ¿úUõß¿áÁóóëñ¿úUõÝtû÷¿uïëŸ3ÑÍ¿ì–ËþÙº4Ýíòv»»öÞ+nTìúM»/:™µªƒ36IætÇÖÐ s˜ê%EÓZÒy±¼jš,Igß½ûߺ#¿Ü/7;ƒu}1žá•PÈR8ê¨(£LH‰Šé©ó'¯{÷¿{÷¿t¯ÿÙ endstream endobj 2117 0 obj << /Type /XObject /Subtype /Image /Width 730 /Height 743 /BitsPerComponent 8 /ColorSpace 2103 0 R /Length 606987 /Filter /FlateDecode >> stream H‰ì–ýoÇÇÿ€þRµ€}»;³;»{ç3†@I   EšB µÁ`;$ˆBÒ@K)à0i ¼ƒí¢*"iUh¨újZZAi `Þ1”"¥¥¨©‰B1ö½ùãóíîÌôÙÝ»õa ¿DÍW_Ÿyæ™ÙõÎIχs!!¡ÿ{QÎlw2£Ô¶¸“2›KÔ‚?6ccþ²+F]»'Ñ\Æ“Ÿ³rÅÔrS;çàÁ¹Ê3l=Ë;öþ×wíÀ;9”BöûšWæ8NpTðÂÃ^>H1»_çË e•ɆEiF/“®ß aêwa¿2‹À)Ž;º ’+ö„umæ—1`?Î9D6f ,°°Üö๟ónÎ{¼ mÛ`)†1ÃíäøÇü‡5DS¿Ì¶íaL’T>„ £¬aI!!!!!!¡ÿ]^«çгm¯Åº1´~lêšæj,Ê`Ù³Ÿ"aƒŒ9 P{Ð7§g¶ë ÈM™“ñc7H'{ °䡌ۃ6µrö‰9Ô±`•úÓû gØvðïøãƒôâù¸q°7¿>8$c>ÿ =FA×÷ #CyÚm —:†0„:Ž•7`ô@µ-‚tŽ:€4ìÌ€ô÷Rþyªïjÿà5‹ýÆdïŸ?ûüã¶³ûNŸ;púü/ÚÎþü䙟ž8óÞñS{Žjý¸m÷¡Ã­ï½ß°}çÊw›êšš[š·íiÝݼ«éÌ©ÓçÏžk¿p|ñü0—.¶Còrû¥›7þeg¬Q]Œ¡¶“Ícyd‚â,áP–-ój†Ž¢Áà%BBBBBBQNš/‡»MÖmÁУaB³¦Î@ÿ]+ãNyÒ¶oSvÓr>È\íJ~réêÞ#Ç7>ÚÚÔ¼lãæWwî~£n]ùüªñsÊ‹T­tæ Å¢¡B“(X¡É0êÈp AAª¦(’ÀÅá°RX(Œ€XW!3ŠàUi Ö±öê1‚°aªU3uCꃫT.¨˜?^ÅkK–nh|»µ¹åÇ-­à ç΃¯_û[úÞ@@#Y&ÉÀ¸S?|ñõ”/LHHHHHè‹'h¼´à çýÌéæ À#Í´ã\Ëd>íë»|çN[{ûþ#GvïÚõú† UË——WUM{ñ›ÇŒÆ U'Š!%À‡T¥@ ä(2Uˆ‹ÃQR4Eèa`,!0ìòqÂ' 1°¡ª`¢ŽÐµ‘aC ë²wZ–"º™+ËÒH¾}P ¦A™©é°„B²?…ƈh‘CŒXAEáÈì—J—~gÉúu ;¶mÿ`ïûm'NþõÓ¿t'SÖ`†ç¡‡Ï$Aüt.KHHHHHè‹©Û™Áëé+GNŸÛ½ÿÕ[¶U|ÅÔy¥3¦N%’‰Fá‚/—˜ˆH_…©ßý¡ÑcIÁ’djÐåe‚&›¦& ð‰1’.N¨ Ë…0šC†`yȹÛ%Ë'RÄ@ÅD‰¨’®£0¨#&€- •ø† Œþj>«ÀQabÀ~¼6d¬è1ˆ®" ‰T‚À§À˜Â’©_Ÿ8©ººzÍš5---¼råJ*•zÚ÷%$$$$$ôÄĨkêxç”sǵŸv3Ù²œ=QJ³Iê8Vš3›2n9°òiÊú)»Ç¹í–± §}¶}˲®ß¸ù»ã'·î;ðúÖwgV•ÏzñùÉEªlÈ’© &a¤†¡(Š®ëŠ$Cû†Þ=úº®ãPh$Æ€ !YÓ0ÆŠÒ´%ªš°Ý;èe”wì—fM¦zî”Êòçª+&TÎûÝ%“·o^¸sËŒ‡zïOžŸ5íYEtbh…ä“¶Ê£GæŸ8¶øQõM[«6½YöÆâ‰ ç­.W]6þåò‰³_ˆ†‘¢K¡¨FЉ©`S6GkcôB Å{g¬“0Q#X ëZ1–“T0ÁDC:R4ë`"ËB&Ò"ªárQˆè¨¨ì¥ù¯T¿ÒÜÔü›_Ô~ábOª;w¶ÃÜOßßf¶ã^'·™{“C·æÞ¨Íyƽ–~ÔÏf¯;Œý€>‘_žPVYäpeÌ¢4#t$¯/¹yê0Çq ßQ˜qÏ¡îªÏ-¾!v<|Žhqf9ÔîIgþ~ãæGmgßÙ´µò«f––>;þÃÄ tØ"B5Tô Ðe!cD¤‘Ðq£j(¬)*–PÔ,Òe Å:‰"E5U¥GsŒN¦O_1{ò¢ª)kkJwlyy׎9ö/þÃᕇ½Úvzé­ŽÆxÏÛÿ%»{ßI¤»ëâ©u]É5±•ñîšXbýCÝÙ±yQÕTkÀ9É%;n¿õ¨z8ªûîÚ;ñUñxDW¼!Õ³¡3ù‰ àÞ¨?ß¾ä豿ýýœ_þjÆŽí¥[6—Ö®ž¶xáä²™ã¿1¡h´†"22d¥Ø€/ƒ‹4£H3uL"¤H•´0àW(dÄŽ ›@*RFhj©ë8Š$¢*DWõ’’’¹sËêëk÷ìúÙ¹6à“8çýœ÷Q§ß²,#lÿ6AÜ¡¥Íìí3÷rAøˆ,¸î¼ë4"$$$$ô¤EyŠó´OÌc wÊ{ )åc ä³Ü×јÍ+ÃYÚßÀ½Û©Þ?¶ÿiϾýËׯÿVù·K&Œ•MEÖGiD. kÑ01T%D䉈.E ©„¨Ðz 5šª" £CW ]2 ”q™=ý¹E•“ÖÖLkÞ9ûÀ‡•‡/½zùµŽ[o&ºÞŠw­‹ÇjR©š¾¾š®Ø²Dle¬sEOª6•¨IÆjSñµñÎúîÄúÞd]üÎÁ©ØêžDÍÝžZp2¶"ox¨»{+Ê¢D—.À……‰î†îÞ†T²öQõ±U©žúx²&Ù]OÖÝéZHÕǵ±®e‰ø÷þÃn¹þÆq•aüàµñîÎý²^;÷€B% %´¤±…4NHÓ¢œ8µ÷6;³·\šPÒV\œ¢VH-è ´¤‰DZÄ¥ ¤r -QŠÔ6ÞsŸY’8öîzyg ®Š’˜GÖç¬Ïœyß³Gz~a xžâ,Å9(Œ¢”Íi•b(ÞáÌcÔ!ð/Vüå¯~õç?÷ìö'NŒ¹ù-{wߺíŽk­„)'t%1’6á褡”¡Zºb«)[•L-a¯hIŽT“3iÎ0­ ŽŠ­Xë‡7íÙ¾ïÉcßüÉ ?~ýW¿Œìÿ‚íå_s©w­Ï“ @ ¸À*üfE+ +V¬X±bÝ$u{íÎÒR»zÝ¥(·º½ùÅžÞèõñ£Û¾¶Ôd ’ (¤×éðNï"k½rî7OÎ>ýÀäÔgÆï^“Ñm HCK6ͤnKfFµÒŠnkCº4b¤”Q==¢Ùê`jX5ôDrÔ”Æî\¿kçšcÇ·}}vË‹gøéÏöR^Ä4´*섺¹àŒTˆ?Ù9N"ºÄa¾+pE Z ²O – …#Xr7s+ \æ¨Übu0i”À°˜ûUNœëšÑ½÷¤mK6JË *Ms>s£õ‚S¿"H]*õ½€ÖB^ Y4%M7<ê×8>ÄÑ ì†ªr9.Býç©õâ7œ€× GÊ<à› åêÌ¡¯¾zîK/¾ôàã'¶*"À^`AÀƒˆbç}(RÁôP£Yk4#t³2UŸ¸Mä2Q§ð öp„×7öÝûvn0€¦ôtFõq­Ï…­'~x‰á °À©¸P ¢%Ì\Â=ø„ÂÀÑ׸œ-8–'êÏ]5Òp(rIÓ¤~98NQ(%À9Öœ¾¸sïL^mUHs¦ÅKÔÏr8+`0Z„î¤2‡ªþ‘åÜîÙ§vWjc»&6lX#ëÒ€&YºdéÉ´l¨ƒ)SRÓ†a¨’iHi[–•[4E¯]µkçÄS³'÷úo¡pVnÆ1I¬X±bÅŠu³ÔéÃÈ"ðL®^¿ø×7_8}öDÞÝüÙ­ªmÈP‡,Í0U]Wª|‹®)KQ,YÏèö¤ë‰¤%¥nÿ¸úÐý›N~cÇ˧ïÿÓù©ñxpÒà!lâ8ÁÇ89ÆH³cyAK਑ç¤ÌPùr𨠇9>„° f¤Œý|¢¦-À°ÈFnÀë¡8‚š^ó’°£Ïp^à¬HpŽÀ/ €"‚€gÊ{`áPR‚M()^לÖ÷ìX§Ê d´•2©…À0ȹáú>5-oK°†·¼ßuàLp£<,Ü…–WLiî}# ™èAxºƒÝ0)1¨9!¯í0\ô›Ó‚;Ð&<°2næÂÀç¹0Ì7_>Á¼àsNþÂÛå³g<ñØÖ÷ŽÞõ©QliÀ’?bHI#¥² †6uU3uÃ6-$‡£™‘ñ­cíÄéS/7.ÍEh |Úé.bÅŠ+V¬›¨v¸põ‹OÿyoÿÛoû¤‘14mȲÕuZ2 ±¢¦R†¢ÙLí´2lI¶)ŸØ´vjrlöÛg^Û÷/CøBîc¿Lýš uMN³ €hf´à7Â4àyìÏp\䨄HÓ<åEô§E&\f1ÏžE$˃|qv(žŽ6$3ÍpZh‰2ð „uH«ÀÃwCZÃ΂8!‹¦Ìw*·¬ò<ÃÓ„º×5CÕû&ÖÙ¦fhò°¤PVáÄ…ýo´~™:ú†±'X5bRn± ¼Ê€v—ë‰Z&îѼnÙÈ/¢B˜‡€iç­b“NÁ7;˜¹,¨!êùØC¼Þ •À/Á+`g¡Y÷i-`U8x/E…€;Á¿Ø/ÛØ(Ž3Ž÷k*U%rÜíûÞÞmˆ“¨p)á¥(@ Z …¶ïÕç;ŸÏæ5¶¤%­ú¡B¢ªŸÚBÒ8ÂP5"%jQµD”Rûnwfvöö ûönûì­k¡H Ñ&Q÷¯G£ÙÙ™½¹gçÿ…Ru ëÖ˽—3'ÿ´ùðáím çÏi&È7¸L”dIÙ—ú 2wηãÑØkG™8LâÉ“'OžþU­Þdîqµê”P¸aÕj– nQ­Ô»Vj#¶ 1Z­ŽÖj5wHµ26R³,·ÿب]!¶ý*œ:ÑÿB6·nñâfQœ®$ a^ r‚ÀK¬ ) xÇA+R€c¦<ü¿ö{ß9|pÞÉ7ž¹ò1àGãB¢àÈŽñ¡©gŸZõ ÄK`Ä!ŽG4Ipê6ýq1GËmç.´žH Ÿ<±áü?wR5§™íCÚÁ"ͪÅ=e#:LºJ¤GÃÀfy¬Å(Ž–Q÷U¼—ªy ƒd2ÁËa”D8 „p“,Â;Ìr+ÕÛÊFR+lwF¼WE +†{°š2$ÑÚxnõž'¨DçÔ)é¦$÷ñGÏ~{Õþ¾MëVÏnnš*ó_Š~‰ãæáE‘‡Dà"Ó 0!ÎÏ4„¹Ç—¶ìîízû­?¦mÙÕ17GmûzÕrrÌI½š5«2ž—i–åd $`½œHæ‰Ëϵ{òäÉ“§/¸ªu¹(âîÿ•Z¥!u©¹XâܲÆl Œ¢Ž;Ô*õaöÈâÕѳg?xå'?ݾ≹A ¿ p÷I¼/(H2ŠÄ†ƒ¼"ƒ)Ïfå¹³ƒ­Ï>räÈ“ïŸm»RHÐrŠšúr©<P„Ò$8ØÜÝljɥSßiìþ„å{$ÆýŽ ùý²ˆU+ØøtË©·–²íÌ»í›7ÎlÝ0ÿoi7¯Å·^5s·™f¢P€¥‹•hJÃp˜à4`ð†n¼X,îCƒ‡ ÜW¢)ç Æ=Ĉ;è¢eJú^¬öB;€ Å·™Z†¸s4|‰æ‹C)RÚIJ©¡Bþ½÷:_yySûŽ…ó[d‰ùZHfÖ'rH%"±23•2a…o†ôàìŠ'–þÙÎ;å¤ÙxzŽV¬k5ûz­z­Ã#•JŽL2Q¿Yµº¬º&ïCòäÉ“'Oÿ«`¯‡ý|üüXÛ9S^¯Ù7`?¯kÔÁÃvšnÝ®S  ˆ=zct¨ˆÎ¼új4_õæˆÄ‰`¸ ãSY•ˆ–¼ÄøCÂô óÕéžåE²‰Uoö÷_çÛ ²‡â>ŠzÀõJ¸Û@Y‚ÅŠbÜAH.oïÚ_š¸C!…XüÀ@›ÈOWäFžvÞô˼(¢}çô¶bñùOÍ—>$Ý·~ƒRÀ»±*À“`Ò]Ô[uœ0i«)¬¦¡$Z²\êÂZ,ÕõèÓkÛ¶,8Þÿ$Òb:ÊPÜé° ´H!-¡“N¨hZ‡QÚ‰ôgnõž4â”;¤¥š†™zÑÚMšÎßÂ(©Ó¬†º®|=zlc_~ÁÒ…R„÷É~¾A †%¿"NQ„€(a9ÄÃ,ù,…š›gµ¶n>vìØ§Ÿ\¶ëìr2äg­:ž·.r¸iì2 °‡‹Öíccc“ýEyòäÉ“§;—»{O\ŽoãlþP‡üz=*Ž#8LRµ*p>5nXÎüãW~¼~ñ’Y"7Cñ³R€“X%$6É\ˆñù‚¢_ô‰3qñ‚p6=ïÍþ­—>Ìh(c–Àã¦ÑièI\ìеX™$ ðÄbÑwR-•:¡Ø1Ø"xXÞÝljɥ´cÚñ‹Ÿ/‡%ÙHS¿zMË’%’4M‘ÓBâýaÖ7пÉ0³m;+—ÁdêÑ+…bä°–¢Óõ@ ]Ë–È®Þ% À %‰•«gK¼¯A”~û»ïc=AqÜrp€DOëz¬ˆ[±ÞIEu.õÜšFÒ.@…êNPÂÔS%’¤(ü££”ó|@,”AÅ<°ŠQÊ}x©ã÷G×t§.]ð`ˆ8 If!sÁ  ‰‚_îUBSv:\/[¶ìÅC‡/œ¿hAfVí Ø¸<EnÎêϧ´'Ož·åñÛЈ $uhL4 íXÝE4x=&ÝC<ÂfM¼ ~øD'I¬'Õž.F¼¼.Öñ­ù-",Žh s³.¨ð|DáØ€ ø9† ƒóæÍM§'þP³«5kÌäšU½q}¤NË5€J¥â&³U×Ýù¬H>×Ö~ìÈQË0H&&&®v•@ªªªªªþ‹ä~fOÓs(Bhñµ×Gw>»6¼K,QàF*t% HK%NPMU¨Y×Rÿ—?õÞ·ŠÎ(Å †òĤhÐK¦¤›8]&ëgd$Á@`Âú\‰Û8ÍPŠA‰ÓÄJbäeg0$DH^„ô2Öë8IÇîc$Oq~áqâÖÒˆÃE3¶åi÷‡´ÆD™‡¾°à«Wô=ÑÒî"ÎÅ€èD„;ÿñÑ1‹™t×ù £OllJ‚ÂEê¤:Íï«×>ÿÒ‹-_ʱrá܉ã›ÕÚHDå6·ÜGYŽ ¬Gh7¥ buQKXØ¿ÁQîê];ß8ç– L,¥ƒóÌÊ‚m”+£BÉʃǭ!C„ sÂO8,MPÜ!)p™ö3«[½Œ½ôÒPV0ÍrÒÇrïM~ï»O­[[§ ‹B²¬ð*L£"ɺªñÈÊp0ÔþlÛáÇBÊ•JåzLOO/ØæªªªªªúÕôÌÔ¬§]·2KžÜÊôÔ´[©LÎÌ|:멚TfÜ)xí&&áFymrâò±_ÿ¤ó›‡øE’¢ð‚& !YPuQÔxŸRã ÔùŽ[šþtû‡‚T’³iœàî²Ý»ðéþ6÷MÒ#Ï!’êÉ]ù‚Z£†üõº¬ò|2¯*ù4Ÿpðgß0iÿeÚ–b­â¤"Îc§ëÜßS=Ú¤‰+Äeýš/oßÔ¸²a_³BWý¿x³Å.˜¨ÿÛû¾¦+ºâ«O%êŠ_aq`Â1cïoO·?`Ý['»?:—°pa÷àCŠO¨|û†ÖexˆXC–Õí”w!ÔÀÄh±(ŒÓ²ò˜&©ÆxY{°•·hœÙyËŒ—Kýu9N£¸iel §4fÛu@%ÀŒMûç§²x‰Ä1Ža+ó·c¯þ¸%Ú&¹Í ŠºàEžSe‰çyEVUNÑx¹³­íô[Ç+Õ.àuö¹·+¼Ò…ÊÊÔ¿A”ÜrƒdªªªªªªúÏ'îŠÌÒÈgr=€LMº““Ÿx@âNÍÐð™33c?ù£Î® Ë$]ÖdNSM•YòCâS¢\+7Eôޝ¼ºñÜù‚i S{ˆÐ,£}ÄÊ`£PB£ Ÿîosß,X9 olm–x¢'b÷&Í[ž¸ë–æM­ÁÕMü±ÃÏVᢑ òŠ&Ö…ŸÅ ÌÉî] K&p¾Ž®ú‹V®hö½û~{8,Hý¡û¹KÖNçZoºçaÎÇ…Äð}–íŠgßík]W«HŸ“å¥@ž_Y±èWoF7´*!%¢râÉÓq„¢6Äf?Á ÇIcIlA¤ÊÅ8E}WJ…Ëb3AÍt™ö;ŽIÎ&{Ð¥ç©1JÍ!³˜*—òŒä*•Â( †Ic”žo,£ÏÖ¦4ñæ°!†ö£±ç.F_ymí3ÛÂwó!A׸0Ä-[Hñ«BÄ×ꊩ¯ËöeÞyûÌä§S×C‘«Ÿ\…àŸœ*€ÏÙuÝÙ>³ºÅ{¶ªªªªêOW'&n<_¿âÁáê½Â‰|ufö–8yÕ«qÝ+ç.œÈv®jŒh‚§w8Ìù_Ô4Iä¡X¬qæ˺;Ö9Ú~ÙÌS'k¢,vzI)fâ®1³n¬ §)ÊÚ¸°ðéþ6÷MÒÈ8áR¾¹9 ²**ÇOm2q’¢ÇÌQÊFŠ—Œ— ¬”3ÿߟ†®¶”|E#õòÝ0hÑÉ2‘`"ÆÔH.ñæ›m»vÞÖºÄcÔʆìòiš_óªušW÷)’[×j[—5÷ï{æÜÙa ©©‹e Ÿ.}.ýû‡è_¥¢Š*ª¨¢Yk¦TK;ÓåÃé™ÒbàÔôÔ$pÉ$¡C?:¼gÍšÅ^O)-ôJ¦ ü¡×Éus Í ¹Ò£Öulm>vlÓÇŸ%x1^ A ÅŽ ¶P‚² Ø«à)F#ØÚQ×µ·ûë¼fI# äpBÓÅ£úôæ·Þnç(n£0\5q!ʬ$C°ò©'Ÿò«R]͆‡—s'“·º›ýs\7»½‹uù³¦É¬çW5¿¾PŸ·¬Þíú㻣tÇêЦŸ¼sê D£½Ù¿âW«,YèI¤îzöé¶Ž-M~ ¡Þ ÒnÉó¨à ŒÂ‡J;VÂá8Í`È壔¥1 c°íFÑ|®‡ó Iè(‚ž,Ëi„âã, ”Rj’&( TSþ±¸ðêKq‘}š³(¥Bz Å…L¦(ú'.<7òñž_¾ñð¶-w5únRkoñ¸aÝæ×U¹uYönE’ ][ûàšWvŸ¾4]B’2­_v`”²®á³[QEUô£É‹—¾ÈwÓ—§f¦K¦¡f.ÃËÖ9yêgO<±Öçui’äQ% ¦Ç¯¹MižºÀ«wlnyõ§›ÎÏá"-œ†ÜÊw »‡¢C½à†UÁ‰ Û–+e‹äøXúÚÛýu^³¤‘"ŠPžõè.YŸ§IÊ»¿ßìð‰d¸ËFQÓí{íè6¯»Ñ4´öõ-‰ ;óÐ=KLÉðhUG^ÛøÌÓ÷ìI­kÛ¸xåÊ&¿Ü´@¿)?:ÀÆc¦R§{uCªåö^Ê÷.jªRÝ>SküÍ©vD"E{PDx×=~Å4$mí}K (óÇ04 Q$ +àØ‰ÿùô¶Ág–nÙÐúÔãkòã¶¡áÃô £pòå„“\t œ¢£Ñ¨ˆ0Ü„³x™fGr®º ((ÔÃËHÃf Q†BãÅ$Éè§6FJ“bßé¿§ŽëØþí^¹Ú¯zêu¯G’|šæÓÉU­+®zS »N¾ýÛ/¦/]aõBûWô^QEUTÑ®+Aoæ‹Ë“¿™¹|irlt䣃‡+WÜƒÀ¨¸TŸê1$ð:¯ÏcÊuU®¾õÅûèãLÞ‚`` îƒ ql¥(ðã;Œ9À!árEÊ–Á¸”U¯½Ý_ç5KVÄÂY[ñéÍÊœº‰ñÎ:³EY;'Æ$³yvðÀÝpŽaT|¤À¶ Œvݫת†ª?ÿÒC9’ÆÅ½Ã$vüÔ&:‘9s®›Ù=|q»]w.0rÖŽOFR`Ö õš\m]xÒfÝh426¶ûÔÉ]úºéöïÜz¿ÃKý x ؘĶCï€ùãüþÁC›µºjÃíóé5†,û¤Û›}‡´s’*Šþ¿þ%M>Ì÷Ž¢Íœ$Š8 ‚QH†ÒPM™.®º„OØ" MôËi/AihQ(Nb G‰4^” Y“ˆw["ø·³Á—_Z÷ÀJƒ,{\ŠOöÕ+õZ“T£ût¿®*w·Þñž?;tæ ÀOM—P¤B#UTQEÿMO]š,…¾™ËŸOØ'ÞþUÇãuµÚÔuÞÂJMƒ¡ª®SsÚ +–ë{2Ëß?cÑ>æÄ (àˆ^Œ¢‚ENÂÖ1FÂR-Úƒó{ 2¡(Rba,Hi¶×Þî¯óš%\ ÞûÓS¾É/×5Õ´phÐf”b<+HÆ¡ƒ…\äÙC÷Õ«^]q ,eã–µëÃ’-wÈRµÇTjžÜvçÁo¶¶|‡?ê{m;rüø.¿fxuïæuKÇŠáát„[–á&Xd 4HP⯯‡nñé ƒývr"8íÁy€ÐN‡|å…ÇL÷bSšïSdCž cJºO®¾mÁ¼‘OÏöÓ}ã¢[oìØº”9õr²ÉwQ®ˆb¬˜,á4sµu(³J¬IœéíîlÙº¡éÌÙ}Üî<ñÖöùjƒG®z`õâÝ_($9ëy¶Ù‘ïïpWD –#}µu (Ip‰78‡> @ÃÀaî²hˆŠŒeeÊr‘-ÝŠl+ɬ)„Š6\€Ö…óaò9Þƒø?Ø/Ûਪ3Ž釶Ój•—Ýû~ïnH…†—Š´­HG¡ˆŽÅ‡y#»›ÝÜ}M6‰¢QÄ7*ò…Š:NñCµ­ÅÖÖvl ¢NÖZ;hCöÞ{^ïÝ H’ݤÏn:á-Œîž¹97gï¹ç>ç<Ïó;;þü¶–æåõC•d¿_SDY”4E è¬ËÒÅK}ø‘¡ÁSU©ªªªªú”J-'oGFFÊ [–Š¥qè++·ce;rä÷í-šl(¢aèu>ŸO–EYUµÚ†zMXûÿãßpü½NÏM ;ä’‹ÄÏ•!ÂnË'l»“tÎiæ#éëæêŠ®ªªî,±­HÞÍr» } ?-óÉEhÙå+g&c1JLN³?@íݘìtœ–ÝKÝä‡ÖÄ"¯¿±åÅ~¸{×ÚÃGÚ05ó^òÝw2[7ÏÕÅ«I6jä hŒiAe±.ËA¹vðïÐî.N3Øê,à@ì)«õÅß¶Õ)AYœ¾qý2†# ›ÄŠØÊÅ]ßpÓ¢zµÁg={pF&ÀÌë‡[D@‚ÐÁÉNF"„¶ÿí¯ÝžÜ0pχ^hwX†äÛa§Çå!Ž{?ø0zóêš]ýß=zxÀ4urÚí „ƒcðð ²2Øî£ðr?ãÁ~†²0C„Ú ¸ˆ÷œ8‘}ýh¤uý‚! ϨӥÚkƒj½.Ï‘üšä—V\·âà3ó<ÿ1ëKÃãÅsè42:::ññaaNªªªªª>«‚\W,'*×ÉÆDi¼4áR Înƒƒ'ïß•iœ;SQ¿ªªÓtE„"¢ùË5¥Nô­¼Î¿÷ñ›Oœìƒ#$sMê†m…@H'AI†{/;\!FPгøÄ±âœwyÞä´Q'u©Æ¹mý×u%à÷ AQC4ÅHüOpt û/@Á…¹Áõ"4â¹è…J œ ‹ëØaŒbðÂÛásNé¡$æyÑ\®Ýåé!”À$]ùðÈ™BÏÉ=O=yçÆÁÕßÐîºcɯ~ŸS7M“¾pý"½À÷!{‡ƒ#¯—8&µ §Ûþôç.ß´«ÔàM+5õcÊ vœ.„±Ýæ‘n‹%Tñk³º€0íý㩼b4þã=kTYQj‚-M7KPÞ|à‰[Uá+€4ºØ¨‹â¢ù_zþM„ 8¨…81buíûéšFU0f+— Žý eo/¸i{¨“à.øRX#˜E]%]œvqrJÿ;}ía$f;Í6iv‡Ã¼`:´Ór2'OfŸz¢é¦oÍ Ôªº K°@j½¡J†¦‹>yÁüy=|ïûÿ~§yå#À¹œŒÊRùxP>#ŒWtùREUUUUÕÿ\•„WNƒe©äÃRiì­·_ G›T}º$ˆªXgÈuŠ è¢_šákPÄöm+^þÝ6™y/içyf¨PN2g•S„¦/;\!†ðp>éqŒD¡Fs’öÈ=—nüÄ÷7.„ê&IR¬X( ¨` ÅÊLrA£åÂzžF>y{A€rcV,áò8¥ÇÙÁ°é ™ÄÊ;ÍIÒ¥ @,Žú)Ë8v¬¼Hı:(11ÍØ´9ý^~`Ð y5ôì³·=½3±ïæ´ ‘N—õÀØŽb;î2ÇŽ÷}siV«ÍµÎŽëÞzÛüç?b¯ýeky>¬õÐ+ͪ,H5×/Ö†‡ÖðLlÛæå²tÕ£nÏC·»^öä©Ð’¹J@\* ºâ7ä@hyÆwÝ»ÞuéK®þÉÞU›6/À®“ÒÉUËP7jçÚ <Ÿã±n˜¿Ë¢y£(ĀĜÈTþq™IqxÌåàÌ8Ä…íÄ ÍPÒ؃œˆ…Ã|¥©uûâçø|º¯¨^®üÓT)Pg,Œu¦ßüû›e›ŒÁóìq.<«ªªªª>»*G!ÛAcä£3㥳gNÿæÐ¯7ܶR×eßL]öÏ6ä€! YÖüêŠÅÇÙð¯c!šÃá[ õäY’œ2 ¸;Oz¡„}*î²n×ëÎÙSfïÏ›—p.æXíy7îXqŠîöØÝP¯/ÕøÈNÜqëÉ/†fˆµ…Õ‰¸®9Õï*h?>I £ ^¦xQyþ8íòtKhø!ÏSÄ QöXš:™2 ò ô«ËÅ™‚›µ¬6B[ Ùvu#–m2ׄ7Z¹m§‡;ç$F8ùæ^ïÏžÞdÀ¾›åVjÀ’›×ƒ¹>Lú{–tEµÛ74bþöË=8ªúŠãý§Ó?–G²¯»÷µ„ ÈË"´Z¦ÖFhˆPUæµï;² H(ŽÚÑéàt*U‘?­¥ÒVñÕNKÅiÚi­C%ݽ¿÷½ÄG€ôÜe†v: ÿàÀØ=sæfs÷w{îùýÎïû9å,¦ùæ†ZÍí ¸¥·ÞLŠñßüvuÀ¥¹kêg5Æhß[ˆ/_и¬9pàÀÝïŸJú\ÝÙìUT¯z‹®:¾°ÉÓÜARÔGqšã pE .AMË|Æpš̃ÌÀ³€âÀ$À`ÃT[,«xoìL‚Zƒ?½oäöÛ˲óæ:9X¢yê¼nÅᘬS×Ý¿ö׿:2ùɧ—hä²]ïs¢jU«ZÕ¾h« È§Ÿ‡€?ÿ‹ƒK/ò)Šì‘UI®÷×)Us*Aïô|ß÷ìÏ×ãáès)K™fŒ³nèáȵX:\P#ŠS'K0qý1àqËì1Yú¬9X*ö˜1ÂÃ%²‰îZýI·µÎÑÝår(ŽZ^N&8Äxe¿Œ ù,¹‚ÔòÌË ‚kòNû)Îb#MH/£° ’@Vö¢c`‰8xy"Bp`•¡~€‹õƒ¸ÃHÇy“ìd¨cb"Wl$œ`B;Ö+DœÐNÓŒ`4tðÐÚù-75ø‚ªS«“æiÎiO>¹œYÉ»–¨x¥™·¶xþ|"}úÌßßî“j5—AS ãÔuŽn­ó~# ëªæÎ¤o{ïdnt4LHžZáãïv¯XÞ j·H¯¦9<5¾zݹòåðsÀ®x;VbHž€LR a8~µüP‚Á` pNcŒD°Ñm‰Ä„Øf'ÚS1–gMñº\>¯Gv:çôÙþ›{»ZŽÝ:>>€H?ãÝ ÝIØ=, ÙzÄ¢„E1 F$ÂY„É(…¯;Ü ÎÍ1ÙRn œÏ~0¶ýå#mÈÌ^«ù!Û«ïmèÉ£4úNŽZ|CÄf®èFÉ^ÄÿˆéçÑ Æ( ˜!8ü›ö@¥ PåNp‚â4PŠ`yøloºµl¥LÞpª2>ÂPÚD;€W 62&ÍÁ‚R'2¶ Ç1Šc".Ǹ †Š¾“c±§žºg ¿bãý-»·ß5ú× ¨xûÕ\$+ž`í U“=õÊLŸGò¹gûU}Ãë ¨—ÐÁrlª_Ó<]ÖæÍv~q#lT*6$†Å®®îÃÔu¿<3à èÓÕgl0p”yQÎ2Œí&hg©”áf’pØç½WË0á;!fJ# ê%†WËŠbWG 2#è *Fq)VæCmnÅ Î׎=îü–ß[T%]žæq¸tYõiºâ•o¿àÑ‘GãP§“““.\ø¯²­ÒHÕªVµ/•qNGöî™ÛÔèõ¸5Žw¿Ò¦ùܾ–Fy åñw2ˆm+â(‡ï¬³qÁâpœ‚”ˆJ¯òH–ò¢Iû0g—šÄgŸ%pÿWNK›"cÐŒ‡}î¯4H³üòWÇÑžk5?ÈwÛ} Ф)Þ ZS722û•—Ö¾z¤ãè‘uWôÂx€Ä–Qžæ,õ¹4Ê^­Àg/çÎc°Ä”¥˜H¤‹[!Âðô'¸È¨(‰iœò83£u—Í$C›`I§e†±ÙIBÂöã´n2’Â1Ë)PÿŠvÃø¬I2¸ᢿH7 3K‹Û¹Ñó!¸/Ÿ]¨(5ZP’¥€âP—-­Ó¤éªG{ìÑuLl$à¤ï/':^-µæ¾¹’~“êœôÌøåá-¤8`’!uQ½¢9}Rís‡Wþ䉶-ë—ük¬‡ðîSc¡‘Ý­Úg­¹'йiÞ§[OžÌQ–…½}Õá<Ä´ÉiFÐ'iÕ3ÔÊ$f}”Ç &Ÿ5S¤Ô+ŒA\L ¥æVdõüéDïðÐê¹õzP÷»k$@#ºªy=R˼æ}ûö;w€ärÙ™T¤jU«ÚlÐ>]j¢.VlêR/NM~|Áþ.“OM}$DaÏž¡ºÙªWuɲ¬HŠOR¡Á J®eóç<óô’÷þ‚£((Áhx©Ýç^eÿ"Pa¼°Ñ²@»M²×äF! ò bYq 0&â%…kÜ~ÄH Ò‹¶n"܇YóX‰„-º  ܱ´”`w“Ï;ãч®Uü˜F¾·¦ÉïHŠS“]ªgšê÷{Ý3t|E×¼ª&é>EWœãe‹ë×´.l_Õܺª¹³û®ÃmC;îÞ³÷Ž—^þÑ‘WÖ½þæ ¶ÄÈQÔo¿])Y6óF)lФi3CÄä ao Ð4Â)Œ³‚Ä8Ž#i±~гàe„™GãYAU(O2+‰D›é"KÁ6ƒô2a£ ¤Ý aÄ¢UŽ£¸‚†ÙÄâE øgÍLétöïf~úÄŠ}/9þöÎu«šê<_orùÿF„˜]ÇŽ…Ûï½í»ßž5úÏÁ‡½¡Ìw¼šC•kÖ·ÞY:2YöЋ­@ÝA¯¾pNiåŒñxY¤!€ß ÍmÐew“êÕ5e¦«Fõû‹9þøÆ  íœwÔc‘]ÅÉ Öi’¬i¤íàY¸aÒ.Á¸Ç© »•FFÄâ€U1Æ¢ˆv‹r6Åi‚ú*;Ê.1ØcôîdÕßôiµnÝ%ë’¤«Š¦¨^¯§a–6²wwátaê<Ô2`ÉGv•Ûu>uþüùJÅÛ•~©ö/\ïS¨jU«Ú¿Ù/ÓØ¨®+ÿ¬TJ[žåm÷m³Ù1e‹HDJšPL›4­‰…±Â 1Þf3c=Æ1›”4mº©š¤P©ŠEêb  ¥R¨¢TUTPÕÒ4ÆãyïÞû¶›‚Á¦çÙV~ñD~ÌÑ‘l?½7~ç̽÷ûN=΢OF§Ùù˜»5{c¦6ï)ÞxgZ*ž’‘ ]H\¥JªÈûbŠâÅë•×~Ö¡[¥òÇ®5j’~8-Ä`# ¸ïÚp¯’knIŸžšxPâ: !€ ÐÄ»¾xgÒ㣙ÆzܶróJ$ Ü1qƲâ¶ÓW¼g½OШ‘ÃDsì„û'õÞmßZ Ý™/ŽÝs·Þœ§mû%F€P^ s,lމkyIºc + ¾zEiGdET‡¢¼b„F^޲bÈϬÕŒ±‚*ŠàÛð°ÔúÍØîÑC‡žxéÅ-¯þ´íô™½ïÐ71©;I.ÃÜo൩&yèñŒ"FW­Ây5×JÙ4An“ö#Ž+IÛ€æ»vªÛ¡úˆ…™ô°iŽRtȈY¸h@|m^áάEºknžêyäŠÑ÷¿™‘ññÁ‹µ}çqh5˜aÏÁˆâoˆ Êc¤Bÿ¦M-«U),ó ½ûWWiÉ5KÉÞGd¤¢W*}E×»ë¹Ë—rp¿$øEayTD+U•ˆ_¡°áµ‘Ð{ç Ž’…íP«eôJÊû®íÌüJðìCkŠS³{ª6¤O ƒ{PU³H¨æ Tô,< åÀ¢‚GÀâ ¡|£’5¬Á«•Âo´mÚð P¡í"Ϩ(&"?â$ŲéÔ¿¯|xûö ð9ÏL7þÂ~‡¸57W·‘zÔ£÷=¼³h~P‚‰iñ€š…c ´äöë3ÿ+_Hñ /ra8ÜË+œŒ|(ÄsmkÞyg_Ù vÆRצŽÖ¤Ç¸g, °úýv†{–5Nm U÷QPÒUu qÏÇpÁµ‡ X×€8@O°2 ,KÕÉF‰ž2±6å–ŒÉ XŠEÓŽ•%FoÍÍÂï€!‹d±ÝCHÕ‹–£µoý’Ĉ$þüÄ3w­¬µo{Ha#¢,³ôXÓÂò%–«{Ç”Y¿lÙౌˆó#žSeE’YŽ÷ñbPRƒ‚œÄE†SxYö±Ìа¬FPù嘋pb Pɳ µ!E^Õ~æéG’½›~êõ×¶Ÿÿãó—ÿ‘Åz¡êh& [OZå´s´’1ô´U¨‘‚k¦ðS.’JÁ‚?møúLz]ÄH@QMAmª}"à $¾^½÷朗ÓYÆ»Íj²‚5ÛNLV2ÿ¼4ZÊ#Ì}A 0žbñ¢äWåe¿ýMû´s´<_ÛĈHRuìÜî2Ö09@-í'?ìPXUѺfÿ™3`=üçJ>“zTd%…÷íÙX_« ‚½œzs×É“­Ø<|•Š’3‰Ÿ£f¿í–Ê$ñö»mÛ·>åÂ!N ‰QáÁA5e1’Éd>úïåÙÛ  Bû}a™™™©ÛH=êQOWÌÎÝš¹éVs·?¿¢eCœ"‰Œ„||‹‰«c<Ú±­ùwc»&,¦ý„ éFÆvú°‘‚£’Ò$¨ÆqР0pù¾kÃ=J˜gM³¯Ré¬V»‰0ÃârÊ$@@(xQ™Lz”c.‚¤áJrÊ´Œ­hh í%ú°ƒR=aLv9´ Gh—y-_Ö=ÇÃvß±ãm|ÉáãÇ6ß­÷§FvGÛÃ2B‚/"ùOåþ$x¥;xÇܱEêhÛ[¤m-¡§¾^ãÃAØ/Ä8Iñ±JÖFÌ3’„ˆKl“"DEN@<#‚K‰"hÇ…– ³|„“Ԁ؄b6 *aFåPnkl[6¯Û»÷ÑcGŸ|ëÔ³.v«Ÿšy{ Lƒ–8FÆK3gÓ{sqúXœAêQzÔãSÓÓÓÞùcʱìï½üݦfQ@>²€Y0*ÊüÒöÖ5gÇv•ö=l$F9˜ìHe7ÇÉI˜4í!\ŸÿÚpÒ ÆÇÿþ·5J Ъç«V8µ)¼†Ø6ð 4WJX× EÀb$ˆž±ÍŒEºÙ d4‚eä¯U‹\u‰Yºð^þ­7üê»ÿú~÷È‘–º\áƒ=ïšMÑô®­ë ±b•Ü05ÖìþI©m¸~úÎyó´ïÖ™×O/½~vÉõsŸ«þ~‰{æó×þì+Ÿ•?8¹ìÜ÷—þáöÔ(ÿã^ßKû#+Ú¶HO?¡¬Žú#"# b0ÀH!•– ¢Â aËåxÅlj¼ ÈŠªðälDnT¹Ì ã £b>ûµ¯6õ|üÈ _?õö®/¥*FήåuœK^šÁ: ŸÐU‹¦0É 3`›C¶Y„Eh‘,0ÇIÿŸýrâºâø‡ª Äxmïkvç½Ûø 4 P+(`"žE`¡`cãÇz×ëµ×kc †„”W’Ví—V¥Ú¦©ª*öîúER*šV¢j*¥EiHÒ°;¯;wf½Øø==ùÈG¿øèh_3º{ÏÜsÎÿwD¡ÙLN’¤f¤@Šv›Ç!Æ$©GR `½GÕN J’ᆳ™ñNMïŒ#^SÉörÆí«Xa?ÕU=:¼éÁý»*YÊE‘ì`âБ–êÄJ Rß$‰|·ÔE[uµI‚7>ÐN«—å+J‹_<°Þã*XYh9×WõÉgõÙɰ„%©1›m‡ÚÝèJTŽ"¥a"{îŸw J7¢k&í㈘#¹ ( )X:Rç  [ 5d²2jMŽعÝçu³A’ K2´ËÇÑ>ÊM^üÑ1-ä!ŠLMM-hûY´E[´E3fffÌ·‚dåòÅK++*I§ XÄ c®ÓÉ8œ^—íÀžŠø@­¬Å@[Eñôö±±ôs1ã[»ªAvÑׯm½ôš02À…'‡'á·>éܱÕWÊå6]=6vB†ÀM&A­ w0ÚJ|.bHG y¢tkM’QqŸ$Ÿ’Qœé¾#ý03ÐPTLµ"­%%žîŽ®/ò/+"i*‡,ãɽ;7Q¤!÷|ÿ±… 6Ø^IÑ~@…"aô“óCysï~ÃH.´gmá²rÖêsÙVðå°ŒŸ ýn¶˜õq.š£X†d(Šò±•”Ãç¶q<åó3¼Ûž[è±ï¨þnW´ê?ß÷ÁßÛ¾LB™^GE© øDÖë%í¸¤Ö‰¨²2 >dã½lnMÇ&7tlæ*ð ü¢ :M (Jì«»A=ÛšÉCñ1Q8©kYªL6T”-åùå^—Ÿ·Ú„»1Uíi9^EÛy/Ï\¾¼Q–»îuˆJSbäË?Mºˆò2 ¥añWš[ü^žpuQžBÊYìb§µ„cw½àPŸz/’béT7œ¾žiJ}Ù¨©!]¯ƒûÛ¶®öç_=[ýßÿ„20ˆ€AIka€1Ô$|Êê1Ui•¥À- aH6pAâLgÿáš]U+h?ï¶ù7e/" )/-{ãÊëMŸŸ›žž^è&´h‹¶h‹öÀæ©û“—.\,+)åYŽv‘†ó10œ2Å¿oGy2yED¥f7ÍÓB½EHÕC?ÌfzÓ©€®·Âç‡nª’‰"²Ô6–‰.86:ý³Ÿܽ“Þ³‡Û±‹|ë7ûR©^Ç0¥„ÎX¬Š§l.»½ä L¡ÛÑáxèFÒfI"g6±t¶ÿ)“U®Ù§ã¹ÓùSqÛì°{*é4’£¿Àè·qÂHšW?ÜO|k2NŒØf®Q÷†I%Îÿã§Ö÷^u¼Õ²$ü"õÒVûÆRK™ÏØ<|–flœ›àIÒËzX·‡&<,åe)žgxŽvó É‘¶ÒBÇö­E‘ ¿ºZsý/!Q9£¨'‘ÁôVMmÅJX#p4æé n`$vŒõ )„ä€"E!iU܈p-Ü «}ppX"t4]’bX9‘ÁÍŽ|üiðµ+›k~°²7¼U úï„<¤“¡,kËžë;³ùúš·ß9¸i³×ÃñP;ÍÇ× Tw÷ÎÎG:y¿ßÕÔ²*Ùß~*¼JÌUPìgÉ«¿® ¶®Þ[½&Þò¯×"­¶)ûI áæúÕ”m‰—¶þøâºÔn]M ÂñAP_µÀWY©WÕ€Yw"`IÏd9Š!dÂÙà@|ÿ®m¥~Ò ëÀ îóxÝ„ êýÍ×ßÐTãò²d!íôsN*ØX•ÚðXãíÛç‹Å“óƒË² ËTœ™´=Ò'F—M çL LÚ'“Nøef¸`fÈ2;êçÍŒØÇÏL¿—7>´4;¸dbä©ñÁXpfÔ:>°ln$z0w&a™*˜OZLʽ_j¼o[¦¯9'ís Âü—+&þyÕöî+ä¥cî¶-öëŠý´Å?ÚÅRNŽ&ÚNÓVÊíeå&I—H®ò.ÂG‘Ïs{·­:ú…‘ä±/> k¨¸KAµ¡AUƒfº*El˨M ©(lJ¿Ò¦«@ QElÇ(€q½¦¶ bgº%Ô ·‰/#1ªh¡ôXgJî•P£†¢š~Tz›6xY MäzÝ^?YD‘4C;+ýÎ[Æt=|ù¶lérg­3úd¥CW[ª`ŠãÆâ¥ÞN—0\¥Ÿøë¬\’Ä^Y=¡â¾[9X0¬7RŽ„Wˆh±Ú…fV™ÖÄõöË<6Šó ãý³)˜Ã×ÎìÜ3;ëkM ¸qe®”v( W!lÀ·w}íú&Žc¨…FJT@´•ˆBMÀàR””4‡”6@H›6iÛ;3ß\»K Ø»ëí;kUjµâ*´^Ùß®-ûý¾ïy~¯ì¯h/šZB'pãê‘컥{4Ùc Åߤh^=ØÙÛ[ºnM.Ün¸ã,I3- ܆-˜7¿§§çA›PB %ô°)Fc±{uïe,l}›ˆŒÅ&ÂÑqk GÞï⼂<'YÊNá¸ÀpE9hûÚÂe¿{ÍðM7ÌYü†G­æ¬x=x¸ŸÒT0ø9R<Ó«ÈnMm[Lë2]nו.È,U­Š»}fVÂ' ›Û!ÅÉ««ûd½B3}`òW>Û8ðvᵿU©FU X!©•—.ù~~ì鿦›ž~2“°¹(!ƒÈ¨”ÓʨbèÝ<agYrV.Ùµ{Õk¯ü ; ÐÁQ=onðk%§~½•O8ζjqŽa¶jZ¥iT#e÷ê¥.{:Î;ÉË—‹U³ ÚÓP3l‡¦U[1ªþÏŸÒ<ë×ä34ï †¡"ýx¤/9ÚŸíKû¿ªÈ…é¡séWÛz÷°ûKù­K¨Å³¸8«¬`"¼H;X‚cáEŒfvÏáJq1‡aV,:½ OŸØrùj‰„‚AÀE·¡Ö4ÊJ#R}£rky5;X©+¥8-(·iJ}@o44B•Öç¬7#åyEêÖQð¶Å0šÞšmC×½‡¸f¹’ Æc¹t>ŸF<µˆ|çb%`€µ,šÇSd:o_{u üÍk»y<;“s°¾e㬦Úå»hžL†)`åÒ,hIµ`‹ßh¹p©¸t{^]IþÐÀ$hO‡YÀh€c kCõiÈk°á‹·"W«¨>ÞáÞ÷sgwýø™9fIA`)šÄYÆš? òç¿ÿ‡÷bààqË£ˆ…àå¤&âºg, %”PB߬è¿Udbb<W»;nAÉÄíXlô“«m{v‰ñÅ2 ~î#fR‹fœ9»óòŠÜ v˜ºE#ñ‡ùÑ£"÷ljû,€ ( Yª1tëé¹V•‚jM©Õä&ëw¬ˆo‡¬Wýõ£ÁNi¤À ß6PwjJûí;õŸ~¾ýÔ›?Ý»åØ‘BøÑïÞÚ&â6'Í$–%¤Qé8mŸ"Øs&ùÀ¡gº[AÞÊÒb„o]ü°VÒ:åÅ7N­X‚ÆœÏmž+«û^|"“³“¶¹ÝÍÛUµM×ʳ©±ze6ŸKbâ[ƒ[µ&¨ ­*²ø"IGu+Lœ™ëK÷ΈÚÂç±Ð¹Ô@¿M95ãüAü•êäòå©KrpNgâl6EdàI ËÙ)ÚNZ!+/¤q\*ÏœPP0»¢ø‰ã‡×~öq±¦Tªz½jv*þ:µ¨r‡¨ˆE5ÝÀ¦Ö¤+>(C³’!Ø÷R‹XÔ&ÀW¸À´´@á»ûHþòyç‘cEÏw.èîZúúñMW®¸Í[È|®p‡HÛi›½`ö£þ´ÙT»`û:š—q´@áS7o˜#£—dÿÁ“'wðTŠÀ ™ç÷wÝí÷Ë•íùï|X6"u›šè`#ðUÕˆtÔ¤ÖP AWjâg&…zh3´§÷ëö]òw›®Óg6­È¡R ž`œËRÁ‘Â1äÚ¢¼û§˜5©ŒÆ'–XdÐÄB‘I{øI8šà‘„Jè¿Uä_‘˜E#±á!©µÙK)¤pÐÙP0µ9HjÑ÷Ø£‡·êú^5PºS á ž¦*À! †“F!þÀqâ>K‘Ý%àÞ@#°˜4së+òªJeÐð†ÌVÉ_ fj/¨JÓ]³Y‚ j1B ºÙ:2Ü~Kß««%þ›žsýëyœÒë çèBÝ">3Ö;?_Xµú±Òª•¢ÃÉRvùö‰“*Ñ _^vGd1tú ÝEkЍ>•裸ilšÓž—Ëq2òüòèZΞΉS —qšÑ¡ ]ªZ!ùÛvm-à‰4žMùÍëŪڂP9<‹Š€¬¬Ä4õÚ‡•Fîž]õ&MôMõM‹õN‰õ%ÅN?26 Žö¥ß¹0õ«‹I×O¥ ¢÷•sÅË쮬Ù"›ÉS"Gòµ"ÍepœH‘âXó †Ó+K–ç´u|ÿDÏÚ/‡J^­ëCóMë#µA’öêtÕ˜g¨: ª˜DYÓhŒ_¯Ø‹ ƒM7¤s´MBuŠZ«µ’T zªÊç9V$¹š²| ̺!£Ü5{ªC¤6é·=¥B3ꎿ±J0šV/Î Žú†GjOö<+ßÉâf”lÎRõvÍlQZ‡¯¬‚†á "¹Ä0ܦY-A‡Nð/dÉŒúµ4Ú&Éõ$~µé¿*\²ÐaŸ‰Áõ§p’¡hcy–ñz½7®ßßð€)&<6>é$á0`ˆÅ!ãÿô–„J(¡oнA¬ã“Dc·õ€~à'?›åú.QNÞá`ÆÎ;Çœœ™/¿¼ÌZÀ*e©Êr`Tq eÍY†/>pÕMÖljû/¨É@‰ AËÛ€Á t±K ”!Í­Í**7‚ÕÀiËçÑ©Â\WêÑW7izù-cÏ?òd1.ËÎaí~¹J5ªv|ñ÷ ÉhüëHÛÒ•MRœ=¸oƒ"a‡MÏbgqWŽ(fqÉ|Š#‹ä¤mSѶmv^ÿÒ{ퟓÁ\pP¶ÃGÖIZ§ÜwàÀ“™ìL:Í !ûRûª€¹Ç4kâÍ×AÃj ˜5+Œ¦‡ÏÛîö§ `cýöÑ>ìÎ9zŽˆ &ÅúùûåÛÔyÆqi_P‹'>7Ÿ‹o¹ÑPJa\  B‚€MrÁN‚ã$vb'\Ê¥D¡jÖJh[Ñb—¦±K©`2ÊÊÚŽ4”*øøÜãÛ‰÷8l|cûÐh(^½>::~ßó>ÏÿùýãWâ} ¢W2¢Ÿë¢=úȧÚHל{çæþÑ“ÙV¢ÐÅM¸™À̸D1#Aä“d!‰™Œ4£cÛß¶ùõ³Åׯü$8T; ìÍ{UáÏ¶Š¼[U\ªÚÀóv.Y.Eðœçë õ'QPj…D¾…îÏó­"Ð;|XΑ,Ñ+ÛåЉƒÖ˜Ór}ÿuÈ™Ãì¾sŸìAIk6ª]ýFl‘C^ø—½{^#I-™<ŽU!©†Ý[Wä$“QxصA‘<÷¼‡éÖW6Vuˆê»¶ªr£"ÖKR½ $áòAà\ð$,Öü¼sWeÚX«7Ôǿز8194AšhE´˜[XXtæÌy44’SÓ“O&ž* 0É‹ÑµÙ˜Ùø?ŒgŠ&} `É… Ÿ-ÿáj „fÀ™×eXiÝ{'× Ü?$È-,_V.,º#r›8 ЕtR3(úò+‰3ãÅãÄ÷tŠèã3Xö¶ zÉ0·;<^ªF¸Zž?vùÒöŽ÷Þ<{ºäŸCÎK—J“™C:Ã0$†å0Y—~¿ƒg+9±© Gof£ýK¿è…ê%y$t¨\N#Œ £öî\"°‡Gåý"çUÇÜ„1c¡³ËËVüúº¾/öÝtþížm`°Y³ƒ•"w¸lË«£p+CâV3žÃP&p­n¡ pL×Þ¸:¬¾Çq5p"ÀŠ¡`£ÀÂ1Õ½¬4÷Í›òÏùçMRcÝ©ÑîôXŸ&Ú«û2£¾¬©nl*@Ä»²]Ú„/-á[è¶Ä:3's£W燿Р^¦|ÇÑÓ;çü¸È²„Dr³À?%0% M1ƒ”Ñ€ZˆùEù¶}Ë.þ¦üÁ· »BB3Ç7‘ÊŠ ’„ç û¾o$¿!ÉLuÔCsøƒŠÜ(ÂUrªR³*¹Ã’Wæ=Ã!Ï0çºü»í’\#ñ6)lÛV²A’êÄ‘REh=w¿i2ãFјòþݺ ×põF%Ẽü) ‘/oïåDÛ©ãÛLørIÜ^µÎß[ÎKnE9Ä ÕaµX€DUš8pÚ Eªü:åmaÙ£Šm?²ä”åv–õ<¬÷Hñ«ùóLD6`‰‰´â(|&råÊ•—.þ6ý›I‰‰‰$“<ó8³1³1Ï‹g¢1==Ýßß¿sçNš2X²©Ud*‡ÒØ«—üõöaI­ñõУÁ J|“$8ø`mXájù±…+È/Ì_Å+Þ$“H® ÅV¡Ñ8¤ðé›·lç/¬8»y]a®¢³0+š“—C®Xa¥IM^Æ …[HÜøÖšÜqÕ.6W”/&-¥Ç>ùå.Aðp’ƒ—ì¾_ž‹,4#HñZËàw@;õªp Ä5KáÆÓ›¨LÜHdlÝ\ô탦GBë­ow¿³iÑò×É_}´G`a‡¶¬[µÃçSe¢ŒH–ÖlšóÑǵf2ÃJ¡{vh>lˆDœªÒ[€f4¦âXûËJ#ÝÑnM´;3Þ5åËŽwé§»0»µ“í”/#Ñ™>õiJ´+ žëÓLwkãþ´©@zÌ—2Ñ97î_èÓ$z4ñÞ”¡‹s»ÞO;T…nXŽ[)4d¡,Ãô¥L(ÅÀOœÐÒ´¶¢´àg”}u§iDprruHª¤Iö@ Ìp *âi]ÀnÊ’MlŠÔ ‹ ìˆ ÎˆQ’m ášdb„ÜŠT󯫌Hª‘"LŒîö­•·‡Õ}'Ž­7è-£aÛ;…<[wÛkW›z×Úê…Š|BQ½­Î·Í¨.Ÿ2SYº2³¢ÌÒé«”c#CÞHø Ô+Š“5)R®(>—NU¡Ešy¶A9UÙ#ò..T'‡ë8Åõõ7ÍíËhš 31 xÓ3jÛÖÒ›×o$¦¦§bñ§L2K#³1³ñ¿c:^&6…‰,J­î°4IÑd–‘Bh\g1¤—•äwuÖŽF:x©N`Ý‘p³$Uñ\ +Y8šT-ðq"H®ÜÓ͉ 5ðœó…ãÄ÷²Ø #8ì)†íð\r°Ù]+(D›o2”l\e$Õ‚îÓcÄ—á:ìTÇVtýùºÝ Ke+ܽûeõÛ|òtŽë)=]W½˜ÜÐâ;{*Á`æÒLå•?ÝÜÏ+m„ÊÞ¾ÒþµC#5÷´mZ›—Ç1M¶™Jß°Öj¥iBG™qºÝYQ*_ÇŽ4 Žì?u²tGÉÒ-Åy{w/òù«”ˆëêµâ_ÇO?ñÄÖJcû9ÖVÚf€ÄÁóu3¸ ߢÊ"×>Ùâ…¦Èh+ 9„`“,×ñJ­¬x¥ `໣þ|Y‹k™*{SEñàÒ"€“BŸ~þÜöqáø;6 µPD‰è=墨d‚è>ÜÖ²®¨ÐbÐëf"õo½æÿÃ.‰;Êsõ’T u ïF2ynþ Í\Ð(A°A¥Cþól»¢8†ƒÿb¿Lc£8Ï8þ¡_z…#±×{Ì={Û`b Á€c§H7¦@iÚð®]Û»Þûë JÔ#­Ši5‚’¶!mlhTµ'‘‘"5r"nïîÌ;ï»6¸^ïîô\¥Í‡HHMb¥Ú¿Fï®F3óÎó~7{ß<ðÃ:§Ó¬'ô:3a$M¸…fõº’®PX‘dFòómqTÐWAùlnÎ1~}¢|ÉR'XD"IéÍ †U­Æ¶s°Ê­Zvƒí)>¤p~hQ$m(#߃rXÃÈlàý„FP¡Ù=™ŽÌ;Nü%ð¡Kì=ÿ—º‰E¡i‚žÕ‘cµ,n ôvš0T®1>û‹Çv7,#0Kì¤îƒ÷‘{7‹\`ßVѦÅ$VzêD"„׆Ÿ`X#cp>ºÁÆqÁk×[œc‰4šê+[Ü›7铤öϤÑ¥Ý<ˆjÑCC©6TèžÅdèV:ŠžˆÍI!rꕆê¬cKÒèE@‚B ò“ß œTsy¤ùö¹‚ *h”Ïÿ§ýgggçVT9m%—ŸÎ«“9u*«ÞΩè×é·Ï_xdý†4&Š&X3mÇ4ƒÛ̘}G]™ ÷AÅ@ ŠQóŽw;=ã)1&ñ½’Ð'ŠÝœàR;/¶Ê²Kà$¨ù?ŸŽ¼wÑýîØA‘÷ R ‰ë´HéæŒ‡=Õ‹.~îOû˜ƒƒvÒ%ì[oíJríPŠV¯XŠà„5ÒgÏÉv?Þ¦A ½ ©© aÛÕ+VÌ@ÓKHË=IphJh¤1Œ™Bo‘ Î’¤©¤ÄF±ë×~-~í§ŠÒŸ.to~ØôÒÀ÷ÚôÆë5LÉh:„îl‡Oc ñ3³íçö>¿"4òEW~„B “úÖÌ™Eñß“oc=;t–}!1ÇHR£± â£h=f4¯®r¶‡«Î½]Ï)~4÷Ó 4ïAHŸ‚a †y„÷©˜,vÁdgš°‡"F™hx=²Ô* nžëæœö\½üùñ­›j‡:èÿX^VNጙԟ<±¦Zâ|ì£ ÿó/=îö¬s:X s0$C“: 7.u.I^@°Ÿãš¥´ˆ> X!MÄ8¾S‘b¨;’7]iÉ/䤀÷‹ C;¡I–‚"ß“QIð)Ð/ m€w¡G’=¢âùørÃÑÃÕËœVʨ#Œ¸™t PCÓÅ©»ð>Ê;¹lg¦o«ùÙ;õoKúĬ2™ÌÜI.—ûÒ]³ ‚ úœ5‡êõøÜb>:µ¿vÈfÔܬVieÆÛêahC‘„´2f°˜Æî-µ°4î$ñ"3®;yr[œo†0†fÞyÇŒ»¬É´ .À”e xà“å^.Ù¼Tæ»RððØ»»jª¨2¦|ïÎj9u .Ô§'£\Ò“žÜlù£ñ®­[œ ¶+…9 +Yb$1Cå*ã…wê'ŧ'’ÞR¶˜2àVÜúç¿î ŒÂl«» #3NéÛ¤¤Zy®õô”2–fZ½üæÍ¨,·}¯¦œ%W˜ŒØèHÓ4ôíØVi7“ú¢%óÃÕåMîŸÿ壃#{ñH:ÝýF³œêLp-ß@D½\—VbE’ñv(øQJ‹«ùrjzÈ”2¨Ã:õÌ}ê¨.3jHb`”xç$ydϽ-Åez›·kd‚XŒ²Q˜ÅHØ æRŒ©ª "þª c ¡pAvBÙ dWü$!ì—§Ú9¡ÈûÄT“,wˆB‚0ä"(bPR<4ǹƒ@Êâ37¯¾zÅ¥Žß¾¼+*¡õ¥ëjh õƹ¶Ú VB¯·±:¼˜²áevg dѾ'V¾úêNYôB1 o°`ÚdZ·ÞüäÑ-ã×£@jãAuÇ-%&$|ß=•Š¡$Ã2ìEÐ25ºyíÈ!Asƒk“!2ú!CÌ,§;îÙ¿]ò4ì­pЮ30Em,é Hßש(Šæ>Z!2QósõéÜ„433óåZfAôÅ*›Í~:bLg2·çhDÍjÑäw§þXQ¾‚¡YÌ€¡ÜÄ%”¾dÝêåC§õ²N“EVÂñÝ5ì•ëAÀ{RbòîyÇŒ»ž({*á;á®…8Qð*RŠ™Š8— _ü{½ÃŒaz‹…Ò__›è}åe—”j…b#ÏGwÖ®´`4CÐËd,RôÖ®©Àí Aš<öƒû´?}Ë·uS…³±Ë /n”Ä#h^¿øÂV ³³”m{m%/5*©¨$?i5ᄎ´˜ô/ºS“îV×J3À¦ø¹£›¤±_æ±Q\w¯D[%!Û¬w×3;;×¾0®@‚JBb(I›©!6¶×çÞ^/6ÆØ4…ˆ¨ miKh”&iIƒ öúàHÛD"QcA$T*Øžó͵kp}nkG(òO@­ö§§Ñ›·z£Ùy¿ß÷÷ùö7½óöŽÃ¯­Å¶ßhEú^¤F%¥AVÃñD­ x3âF”¬SO×}ŠZ©ÈèS²Jñ•Ú4"K>ù»§Ä4|C#=3F»ïŸŒÍN¾oJž˜“<™™ìÌHvgŒÄfŽyðæ¹9WÞ"×Ù~¾ _h§ÝV·¶S$MbŒÏ-bŠœ9´³­^ºèà> |3¨®4BºJȤ Ò`¿,Ö!æ5ÊbÀ$úUÕûTµ^kÎt–þ¬8wÁ\sû¾U¢<öú¦B†dÖm³ç‘¶ë ÷6­:+ú÷©RJJ8n„ß=^B›ñ\¶€elÎäÏÿá™Þ2Y2iPå†ü(~^*Gò+šÞ6(ÖÈj yF³†"4P£¦øS¯Í×CúÃÞ~® ˜\’ÃN[W/£]¶Ü|ÖeË13öŠ²Ï›WðÖÛÇ@ˆÆÆ†AFÀMéÉèèè´HMKÖ·T:Ò‘Žÿѹí2&§bºÀ§dž†ôääĵ¯¾Þ¶e+¨I˜HÜÉÒŒ“$Ð/¶ýt€kCJøúuÿò•]Àà4‹Ñí­?_Ww'@¯î5fÜá¿–r—¨Ì ®!€ø *†ùÁ ¦‚Å«¥–5« ÆX–þñ—ƒøA‘¡¯^DáOÎûÜ8Ë`Υˉk×9ª)Mü½Äa#Âí¶Ñ~¸ƒã<ûÛ7æÒnEy* e9ªh¡¾¾j&׆c&7…ñ( ‹¼zî©ÕsiÖÍ>qüiàŠžXé_þº­ïó  ªv òµHöWÀU|"ç5Tp !$…§º Àƒð¦|¨†Ÿ`V€-p…½i¹;c²Ë2Ö•=ÒeíÎë1u[F:¬#'­£=90™8••ìúþäß¾§Ÿ{èüQü÷ÄšùÎù´ÍIP9…ÛY;CÚ왬#ƒµYs‰ì «\oþf w-|S ª’ Ñ8jF|H‘ÂCÆ.8ež«P‡#&QåfMi”å:ŽÛ ‰ah»uä“ÿ½SÿÍexiõb8„Ä 357>uñr÷§2Mo’¸j™óÝD»e. qás§·_½ê;þîæUKX—ÕùpîœÏ.UÊÚN¤xDT%*åŸ]®Y”Ÿuäw›µYjàø°*J”â *Kñ <¤hÆ0‚ŠX'à%=º¯}É‚|3‹±¬ RÆÆÒ`qÌ[¶núò«‹Éá‰äÈÈøðm™«{¦›éHG:¾ƒø6„ܾONþð+÷ÑÁ’ nšt…aÏ=½ðó/ÂJ¼ZÖ*Áï 1ðÛc(«Ãi§„Ëm·\ºÓ«÷3îp€r‚\ƒB‚˜s7‚:ŠÞL„*qwyõrù”¬[G[ I0 E0¹I™²^{u32ªÚ[žpà& ËÝûòèõqX!k¾¿XI™uѳÙsúìVkV†“!×þh./UÃ'zdù\ÆnwáDo÷vI‚©üÓÅí»Wœîª¹Ñ_£ë¤D8T/è5 µÉ冿›²œíN­ˆ**3Ôvè>ž ×Åã)ü(R¤=†Þ˜š§þã7(¢*Aè i¹K4ÒALÆrF{³nõÎê½o¨ç‘žÌñëd¯u¼Û<Þm13÷dMöÌÝ—ü óÊ뙇‚æÇV™H†3.NP˜™ pààTš±ÚìyaÙÉ÷JdÔªi~] Šôz€Ì†ÔYk!²hê‡ã†Ö¯«Q$5òMðAâ Q%þúËÐGJ6=I¸HÆEc”%a¡«­õ±Ë_„øZÕ¨×О?¿³­ôùÂÊçW~uÃ…¾²ÄPslj’ “‡Q¿l]¯Å›8!Ò{VQ—lYÊb$ƒ›‚ùýý{´W’ªxf„xä<„[Y®ŠÇÀØHܥȄj•Áà-µIâSÕ§^,+Û>×MØœ”Ëf!¤Ó–c+**:p`ßèäÐDòÔðð0x(˜LKÖmáJG:ÒñÓÕ 16ÉT'ÏŸ?ÿøk1k¶›)d±<î`0üÑ…ÔÙ³!Q sr¹ Wk® *†9´ë™â‡ÝKæXèGMÅ ^òŠ\ôžcÆMj=B<Þ :c ()!AÝ%£Ð'ÿ(Ϸر솦˜l†p‡ük>ú("ÊPbgÛž•n{¶ƒÌóEÖó‚¡j°¢²,¯|„¡h•ñ‡£Åºéçò'nr;Íóú>-UÄ]*òVV¬tÓ3ž-^Ü+•Ä:ÀøªŠÚ rûñ  AH}dE­På‘÷@‹¨PQ‚<ºV7¼†â×Q läš‚«,Õã =‹_:ø»R• IJùÓ4rWÆH×£Ý3ǺgugŽwš’ïg'OY’'sþÓ9ë֩̉N,ÙcOÆ,ã0Ï‚I¼3kòtF²÷þñއ®¿IþºžX· ›ÁIÚ6$À à¤Ãn#4]€ãøâ%…‘ðü?ñý’êååRI-WÕZQ¬sW”:M¯’ä ž«…´Ñ”FM éÜž h-œ\ ·Hô© oGgíæâ%N‚ryt6Oá--‹P"zèWKí³`Yû»Õ”ÇØ7?¹èåƒÏ¸ÀtäàûÛ7 Ò‹‡^Úâ°>øøÚÊjq“¹NbÖÉS/ÈJ³Š€½ÿºÖâ)/ª­-ºr9l$D¥R4Nr3ä¿,Ö&t¿&FU¡M•[- ¡úÿ²_®±Mgß—µl…8ñýØçb;‰sáZBéDPÔ()·B–{'Ží8@R ]™Jµ“¦iÕTi% ¹@-—uÓ¦ublZF !¾œsÞ÷=çØ&!±CΞ$Ûć!õ‚nò£GÖ9ÇÖñkŸ÷ùÿL:Ïõì_ó\ŽÒÙ-nœ¦ »ƒÍÛ´qóåËONN>(\SSSê\€züš™ªT¥êÑÖƒÉâ?C-Ëòá¶£ cq:²Ad,:M®ãéÎŽÍcAW0è‹Å:g=ÕÇ•€ö(Ä'Iî+ŸÔä°:ÚlÎd³¨ mOï)ê{â˜ñ%;*v‚6ÊÑýr¼öÓßW4¹V/sjVƒÓ±PÄ!ܸ¾Ð¹i]Ñê«‘æ(êÌû¤qïÈIñ~ßi5Ú,æü|ÛçcÕ²|„<#·]Krò8Ö˜Å>ûsólߺŠ2é]>üõÆÐ­@\982R 6+è‡DôÎý™GÒ i°´LD!Í1|Hºq蘂˜´ˆÈ ¯ `’àÞ“PG¿)Kà85|¸fö󲇄+%R Žú (L2Ï!TS4òxzæ‚)ÙoHôè“gjYí5ÌÉ¢© O¢~¨=éɳ ’ý Cú‰AZíËMüÆ’ìÕÍ\Șè_<ÞoP>bFN§|[Ÿ½ +mQ6ÃŒ‹lÙše­¦|§C»e“å—ï¿âÛ1ñÃSž}Ü¢‹ :Œª±X+¡& 5Ã$VI¨*6Q;Ê—GPM\ñËb30mÕ¡˜{øÒÎ&WAm̶èß?³åN¤«Ð¹ÄJ­°XŒ¯ï.¬®ZS²r™EgÌϱY 9NFÿ«¶†qË÷¾«wNÖÎÑ&‹‰n¨.I7Qx¾¨£±öyΘcg³ëËóoݪ—¢uEùßt}7æÝë`3 á­@TñaRqóow½¹!“ý|[6“Ké8Öê`¬tww·(Šê\nRˆQ©JUªþ?jžIæiäêÕ«%%%”•æ8†ch«‰bÌe¯œ¿X)Ľ"qñ!W\>„"ÍbÄöG+娯êÀ :ßlÔesK6oXRö=qÌø’øê¨ì!BÇéS[ œ:JcÍæ ,F{ÙöÒÑP3°ÁíÏ›Âb кÞnæ²èÅu•ÅA²O’[Á/ mϯ´qf=Ke®}6³ëÈúÃÍ‹–jÌ8˲ݻ‹CÄ=.{@ÿò‹ '^<;¸Ì:&·¡j&©—xÀƒ=vC`„`‹×AªÅ¤Šð'ñ yâRmœÑQr‹Rƒ@\Xr¹‘ˆ“€…32öÏb!j†§7Ÿ¿ÆD°‰.‰x@ç nx8mJÑÈãéÉþ´ä@úÌ :1°øÞÀ¢ñ!Íøp†Ú§>§2›à4y!]ЪeDÏ?^4Ý—¦öêf»OsXswhaòâ;Ý@[uVZKs‹5“£ó``lúeßé9óŠt`Ù'`/ . y±àV”&Yò»~ÀF¥v,´‰v´óíwq *]»’eÌ“.×a§(&Ÿ5e´Ô¬Šâ!ì¿5ÖÔP»¼bgÉë{#á @èˆè ó9æ ?xØþ‰ã#ˆo”åÆ0ïçÒ‚¥Ï0E›ò2´Ùh²1Yí‡Úc±ØtMM€šÍÌ©Ü\ÍêÛÌL2…)©JÕW²æg3‘H¨Éü'gaåwŸ^Z]\”É:Yг˜5ÚB›4åûНþÖÅ“€ @œñƒ8<Ô€„VLÚOÿtgdhDzúeEé_Ül îF\˜oÁ÷±[DÞGåzŠØ*‹ÍB¢_ ,TDï6bäÁ¨HÁ1H…Ý(ÜŠø„jgePpÍBÞ%£V"ø0ñ_ÿãÛÇ:_Z[¼x,XXrêÝõN.“â4¶–†£³7:ÿʹ¾ruÈJU\öc'^(.àš6jßûñ¦päàµOvŽü}·ó\úؽí•å6Æzé´éW­Ð¿ÕõrðÎq"½ñÄñ E#ÿµÕa3F²/ý_ËÒƒïß2¨½ZÞHWÏkQ&ûÓ“ƒÆD?õOöË5¶©ó㟶 )I|=÷sìcÇ„,\B)0ZÚ­»”A;ZtaÜ’%Nì8N|Ã$ Sµ±®›6ÑN´hVÑ®@ì$Uë@SWZT(S×’¹øÜÞsu ±“Ø{ Õ>í R¶ÉŽ,ûÈ:ï«£÷yþ¿g®ö™íG§’ÈL¯9ß»(?Xž¹€¦ÎŸ¼AvÖyc8­e4…`”…"PŠ{lB“kWUüúg›¹Û¢Ü´öq#¬ŒîÀ¢#ŠÔÍó^Hãªêƒ–)À‰º_•ã¢)½E|iõ(dïuµ´ÓF16··8ˆA2[鬸y+¨(~ö=¸–±™YªbÅ2ËàŸýuõ5+«°\\¿Ò±qƒó­ÓÍs|P‘‚† ñ\D ‡x¡3î™íü¨R´í¸ÑÅñ@=úÁåøŽmK|nÇXÊE¢2Ö?u鯉|Þ€M*?“ûwÖ}‘r÷BonÒ¶¨¢Šš]Ж™L&—+x¶À!ù{þÍîOd2áPŒ!<AâØ3»‰êšJËïOl képjó¢+I ÎJr2€"ÿdhØÿä:ÊExHÂF`hwè;ªç¹–´Þ) ?Ö@V0˜Ekê¹A“*ÂAøX͈ ó­WÿÞöóãÏ55¬ÚñBe ©¦ï\}!lµEõÂb‘ †­a€¤ðºZ»›$X¼â•_Õðݯ܈ÚÊi‡ %¬V^E±nÂê&™Õµ–+W[Di». Ö; ‰NÒ¶ñ‰'Üö…¯¼´‰KPî„RúÞ¡[±sÉMW®5J {4Õ¡¨1M ³¿·ÿ×ë…F2ý &’ ¦úʧû-¹>ëtœ9[:ÓkšH”d’d’ 'ó'’ó—¾0oâ½’9£‘ _™€«[fΘ ¤ÔgÊ÷•æÎ.0þ„€sU§»Ø¬([lC„w°(]ÉÞ:BàÖ勱hóºkkII¡a£G"†‡ì!Š^Mi/À9ߦÉá‚+Ũ  \G:âùFhv]é¹1Üø›—·ìܺ¾¡þ›ßZ[½„ð¸qìHO¬…Æ8ï­ÛÍ5•8ƒVã6¢»ëQM pÒ¯oµÆ@ÓSnÔAY±Hx ¼ø®Ä„T› SøTÙŸÖƒc#³Òˆì‡ÝæÄ'Aò)ZœK~ëÍUnÔã,#ívá&1;‰‘ñh×ɱÜôÌÝêLNNÂÏìý +ª¨¢þ+5>>^°íLúwfjúÒûƒ«×¬!0ÖåXŒÙP7MV0¦úíz5zG?S‹ö†¾p@Q#¢º{¶ôà¸fô(3ôàÀù]”Íîf*H´Â…›.^òòÀ§>´ÉBTÚ <¬©Ç‹­@Ù ÷ cöÆ?}Ç~ºÆKh’r î"-_úã©]š“ä=p])uäóÏüöåçDàç%¯btœxu+j¡Ú±þ17/úôóàÊj+e_•,Vå²±JÓøb'ý­«EiŸ*Eß¿ôà8CÑ8ZRA „Ú±Ù-Iñ1a·Bp•´–$­0N)P`9aîñ H#¼îöÍŸ(›°Lö–Oõšà\²4ï ΃Ó?Ÿ´æÏâù3t>ÉμcÏõ"sµOHJÙ„5›Ä¦Ï“SØDÒ4™,T¾¯ 2I¦÷Ëïš.þky]æ" '‰¥4áp9Q†D¬å8˰uÛ–KÔ‹r+'øŽû˜*G),‹!EŒhj‡ÈwÈb\äú†§W[%1 H~ D ¤ÿ¡Øz·YÆ~õæpLb²ÜÔ80ÆAUÕ®Â5õ°!¶¨â! þðâE?,$'ôà{iJ¥¢ÂXØPâŠÔiÈ™Ic!MоÏr~$!9DQ›t£Eä[ ƤõĘ¡áPý¶8 ;i¥œåf±Õµk>ºüa!Öî%Ûý Ëf³s´EUÔƒ5}O_üÈå!‡@ÛþòÇ)Š°Û­¬Ã‰Xì J×T‘8ÕÀCãºð­’àÓ• .S!DiÖ.£w¡/ĪùÑö”Õå$=Œ|þYÐã#©ìB@SC@êxXSOO‡dµ“—oÞêÜüm'ƒ $BÑXuíÆ-eß}ÒÁ‡5ÈMº|¬»³¦ÒYâ°•|u“bxÇÄ}C£__Î"h)c§úúwÂÍòqØï]µõy&ÜpìÐ3Ñ®§mf¬Âå®ö ©TgúÎ.¼þÚæeKX§´òhÏ3CŸuir7¬–º|XÂ0luƒÜ+§ ‚ЬëmsŽEyà9$Ûg™L˜²I3îp‡S‰…ÙÄüL¿9ÛoÎ$L3 [æŒe¦ÿ™:o›«}æ“öé„i¢¯tb°l|°t¼ÿ‘»‹¦/”¥ûí“ý%ùþ…ù>Ëô¹ò©wÉ‘w*Oušk«ÌÂFÚÚI“¬¤,Œ¹|©•X·²ü“u¿^lSå8CÐ šæŸ,…•Ä P-ð~ †¡ý¡au­s,¸òQãÛ§¿7:¥Eßÿ5vu;^~âÔ‹@n0R^mìˆÀwlù†“tÓ˜së •7n{= è;q/Úá£Λփ×"óÁY…vUmãS͆½«wÜܧɭ²ãÛÞ~Ó·ÂC¸‰r5a&ÊE-¥2ŽÜt¹\nN㶨¢Šú‚2‚†ýðƒË›6~·£8B²4M#8‹{^\sc¨hí‚Ü ÊUñêjð‘B{RZ¾U•Ï–@içR~YlOžó]½bqŒ& ‘°¤Ýúú©-é;‡p¶]lXSO⢼ä•Õ—6>MQ6«‡Xþ/öË<6ŠëŽã=¢@À8>×{ÌÌÎÌÚ»>0ØBˆ8š4QB•†B Ŷ᰽¾ööîz}„@šÐª‡Z(¤•ŠšTåð¹^Ó”ÒB AQ@1ö̼c޵ÁfíÝéÛп*,5ª…êŸÞ¾?fõæ½yïý¾¿Ï·69k—9²ýð¡M]'6‹’+;e¹YølÏî–ÕŒ©¬ˆ.Ù°vÂA%îZêêVq6ž6øšV‘U=CõŸ~Ö(*.²‡~·É^XÀP¦-[ÊUµCª‹Ë@Ú-Ê­"ŸÒ8$Ám£c»ÀpX•käÔÂf~EÆÔN x1xhôõ¨´G…F½¦‰î|‚"ú)óT,¼7‡ðIjЫÞcÑOäL‰1ã'?_j4[ïÊÕ{rõÞ¹c§3U°õ9KyÁb{Þ"mfiƒ•+uÐ¥v »z9·ïíçÿqÓ©7 Â0ÆM5C@²¾%}|’GSC¤‡R}Ú’h>„%ˆ+®“Ç~±K‚eŒÙÁÚ­táÏ~MÍ?Ž#šRwjð”q®ÕRÌ›mœiÂJ›<êåŽoíyñ½£Û>þ¤†(Œw’§»?ij¨r«,µÇåv ¸Øxw´ zE±kÎ7ýÛ6--ei;C“‰x†åYný·_¹xá£4$&IÌ´ÜÎÆlÌÆƒã>‡þÐÁß,©¨$¦†¤°+à-ÌÒ2ö?ÿ@a¬º0ȸ+Q )¨¡zA|MAvb)4zÀ¥i$ø±YAAY ¾±û›v>×d2Ùm¥_[Å^»¶›ø)ŒÜi¶!ýCªz j¥·¨æèLµ˜3çþù¯©r›ýµ¨J&‚U²ìƸóã\kuØÊKiþòù‘8Uk;sÆm³˜i«•3¯_ Êr¼Õß­xºÒ´ºjY±ÙAþ-sϯe1„ÄF„‰—‡[âq¿«GÇ\DÌÉ,’ÝkER+B H‹§t;¤ÁvEŠÌ8ÌÒÈ[ª×˜ìÉKögO dÝíyr¢Ï”Ñ 5ÀÄ5ª0¤Žtˆ å i]Ân¢* N§Hõ¦ŽèÕÄvùÑwk8´bY1ËóñFÛÞ=Ï"µŽ¼J†-xVÕ‹£íHxs틼ã)*ç§û6Cáu ýãMñAѧÁynŠó›ªhŠu0¹¾5w´vYµŒ2æÛ˜Êû_"(rùr„7•rÏ0¥ÆÂëÊÎ^pÝN s«R‡¢Õ`q×¨Ü D'ù2#;eèÇR+Ä^¬x Ô!\§* q¥™Ð‹½3޳4òÀ¦wçé„4¢ ÑùãýÙ‰û(ÝíûÒÆ˜µÏXªøŒõ+ÙÆuê Äcl¢?c¦Ö9ÙKMôäLöÍÓc™ÉXîD4çN,óîéãì^ë½^ËT_V²N2:ï^Ö½¨!Õo˜ì&͘Š´hÆõcÔ/½ìó 4m⬠m¦m»*æ ÏTRÎk®\®†}šJì†A—"ûä"ň*·ÊØ¡ËÎtA„a¤9%)Œ5g‹ûeÖD| Wý½*xÞ9¼ÙΔ2Æ%K+¸KŸ¼ŠÐöÏ6”Y9–²óœ¥7ÑùŒÝ¼Äf¶.­üÊ•k­ÓÒˆDT‚,£˵»n¡)~e$H2Z“Ãd"v‚xàÂ¥ÈÆïTØÒS0Äa L²uK5p¦Ew6fãÿ;R„;’©¤žœ"þï–"¿‰¾ã•‹J(£¥¤¨ˆ1Ï·1yœÑqhÿrñv$®v#²ì&DA_¸z½ÂØ%I ªê…À­àðÈPË»Xc13Å«ÕH-_XqábkÈ˘BœéïÏ•~(óøÂ…Dþy£Éf1óT±Õh9ûa#üw°;­cRHSÚE±^F¬„öw½÷j•Ë1–ŠÅÙ7o´I# ß^÷B9Ox³måÓÌmißç¶F‚«vm«úÉž¯ÿýo„‘f¢Òd…i”"x&yþÕ\a‘äB³‚|’è&EJÁi÷ 6CÑ¥ÉA{d ù.E  VÁ ´!è#H© €†Û°ÔGQC A€ŒZÉÖ)jäö0q¾UI#9J [Ôö¨ÐˆFêïûéÝ™úÀçÁw)eõèœxoŽÞgë£S}O&2’Ç ÷¢™z×—õã¦ÔûóÆçèýùwNf /\Td¦Xš§m6Ê`³Òl‘Éa¶Pü ›ù` DîO¿?EöQƒæø_² èƒsf«þËöûHẊÇ#Ç•XÍ1E¬ÉaÉeÌoóÚ‹—vB¥V%§?Ô4}Hò!”¾öÊ¿Ø/ÓØ8Î2ŽÓ¨*mêâØÞkvfv޽ç N[Ú4JHcˆ”*¨$ê['ÙË»¶×Ç®85Ò ø€€H­ÚÉï$JDQDÚ¡”&޽;3ï\{ر½^Ïìê,Å(UäG¯ÖcíîìÌ;Ïóÿÿþ>À{ 5+茶SÌ7BcH¨UF—ÿâ+Ù?ýÁ7òqÛ²¥ÖæµcžÃ[T%¨ˆí®YË:4cÙð˜ýÈ÷7ýôÏl­^a#`èÛ×ABQ4˜(º‡~ȇåÄ«ªÑeDmIrõÀ?² sWWìüÿºŽÛÁ‹h‹ÙIØ]67e¦×¬X?ÐÛ33­+`~F›žÊAÓC™–Ó´› ”333ðšËåtÕœ-¼µP µP·­r“¹Â_}è²Y5¯å`áŸÃ‡:¬ "Œ‹&p£ÑM¬Ø¶uõ¥ßÖŠ¤ä.> ÖV”ˆÀ!‰Â¼©ÎÀsÀÐ «ñLÉ®ë-K:IlñîªPZ €‡‚?‚™]¾¨3ÿƒÑËr¨¿÷9Sæ¤]4FðJ»"µHI?Ï7‹R”¢€X·*Þ¾åSä€*×¥”0<`øé¹ö-%GZdTø`6 W€%¢}ª‚w®)£´Ù†Oúq¡€¢:yq”ª¥Z8•"t$¹°’jR•E¸dž&BAE Ý-42sÎ49tïd¿15À¾b×á÷T2;w_û%“;Ehý‹òçšéŸÈF¹d"ëâ¯Óc2ªÊmÉ„Ž.K%€ÝC… €–Ȥ[Ò©Vn, Há»…F´ã­×¨ –M™†ŽZ «Ù€ÙI»{ Û03dÖN,Êô/™ZüÃpEp[Å+~ËO:¾ ¬Ð†–¼ í.¯ÉF-%1·ÅûˆãÁúøkóÁo—W¯}€ÄËM e­dW•–ô¡R%¹SKf{,Ú€eö¬U;CÞq̸Õý¹p¯vÖ;cš4]:f¬ÙTº32$UnsylË–[H·á¬ÿà/¾ `:A}Ð iéPF> ‹Ah0 äLº š  tòÝ÷B›þ³]7’/@S]öAF :òò\û8jÍ"hÝÐÁ®-.Òá´YŽ~§zôF ‡®/¿÷²¬Ä AÀ'‘-W¯ó‰çÇê%! ,VæL¢º7Á‡o$Ɐ[ ÷»X£biISæO<òçÿ¨ÍæŠ2ž™†¬öišššÒþÍ' µP u[ r Œ H>7ýÖÇ—yVÚi7K®biŠÁÍU«¬o¾ñMIŠ'ÇÂi5N®(‚Ÿçým‡j¯û(R ˜>ÈÈÐHHêàXca•ƒd03MQø¶­“\½*FŠ–Z|t/çM#ÒÞÄhçÚeÂXfÇñø^næ„ ÜZáv¢ ¥"ÚôHÕp͵ë@) :´é èÅÅ:­–ÝNK°~ËßþîGR T11¶€Š¤ÄýR¢£hôŸF‘âú¬iðIâ›d¡UÛ%ÔªÊ1À…æÚ7Øü‚€‡ Ï". í"ƒo§[‘P›NùHI1n´!£tÀ[ .·™MÅD¾1%¶È¨ °Nʼn5¢Ô,ð×Ï41Z@R<íÝA#'Í3=x®÷óÚÀ⛿ªø’›ö`´ »÷”Ì —i'èÉÛõÓ¦ÍK)Æ`]ÎPÏ>õvº”;NV­dJmF‹yK[vXGÏØÔÓl¯-?l,9µ¬´–U2Äj¬×ß²O÷›´^˜çæà}Ù¾%“}ØÇŒ[\j/–ë7j§ËµFíliv¸ìÜÍ{ŸºÏcÃör–4ºq·—ªÄ1«Ív(ðå÷¯ø8®IQc²ýW¥&kz耆`&ÑÈf ýBe €ŒŽv tXNïÅ—úÎìb¬4Å:ƒÍHèTøš,š ú×3Ƈi[Åw»¶*è–xKÝö5ÓëǾ&§bBúyIi”¤º”NŒÔN¤âb²1-µÌ©\IU$PóÉÓ/¯ô’4iaI·¢KV/_óö›oë4’Ÿ¼"Y,À‚ZþëøŽ©öB-Ôÿeé#`Jk‰ÄI³ÛN.£q;‰,NíÜåºúI¢ˆk‡Ø[+ËaE‰ÀkE "rÑ(¥Ž;~$†Ð0(ÍÄž•öè´iÒ:¤ ±’8N ÔMëÊF'ºÑ¦@ƒ}}ß÷:‰!qÈÝq<å¿L¤¡J9ºº²-ù÷;÷wî9ßÏwÇ”ÊËB”åB {×Vج„ÖYáÖ_¼ØÄH!>Õ( þôí:IjKö<5X?83§62Tp ?ð®Øö<±kÇš®N/-‚û‹PT,6COâCl:(³­Šš¦}žlÇ@‘¥C,zdÙƒ›êÜŠ¸¥”¥“ A}áP€žõAq gN‡6,ÊŠ> Ô§RµÃr„§¢uÊÇ‹NŽ]z×{âè–´oþÉ›Ïýýo–má¤ºÏ Œö•‹}˜ØW2Þ3OéÓT­&€ÂÉWÖc¹³¥Û*Å5Áq·Î„[«ûäíEùNÝÁWŒn„\l'æŒ;7˜Fzðáse£‰YJ·^9­V’(ÿÛŠd´,uºl¤Ë œ3Œvè”ìnß—s}³òIu¾·ä‘cÆýžOoéX:Ú…*Ihj´³\I 47~­ŽVk­ˆA*ps‘N;î&ƒ /m?¶ñÚ¿ö Ù&ð™t0—kæ…:ž< ·‘JûŠîCà›x¦†‰ û •úûý«—áb5!x"á—ØïBg]úãN·[‹!6’4¿wiWšñvÇ÷xØÏM 9[CK4w„æÂ¢Ø0(5°©ý€"çйS½oY!ȧCz Œ2©ñƧ±«WÚp½Ål˜Ýbôàz{8ÎÊì¸rWQò“ì1 $pÏçóÿc²ÎÄLÌÄ´"? •ÿðÊûU›ªHÔmC=VÌl3kÚÔo¼±îæ@s†>‚%pé[ 9)†Ü ˜š"ŠÀTÁ… 3} f(?| `4Ñ/ˆ Kya»ãǾNšPÒL8,¶•‹m_ÉR³(DŠJ:)¬ŸAµ3)}ÑË—C‹Êjt8LæuOÙ.üyG7ÉÇ9¾ùýË{ž¯r:“ Õ¬Xáa©ƒLë0{”ø'†(®™ãê‡ä “‰pL!Ÿ¬Ø îLÇîç ´ðdzð\s1í‡O#Måh&áD/C^näDßTçÆPÍP9ÛC¥½ÃC‡dÙO³;YLëwX¶••êåœïÓtøÊ‡¡Þdíå«{¡{,Žõ©•ó†{IÃH|žÒ "nO˜9fÜç5–œ·»DéA”nÓøYÍXïü»Ér9nN”Ž'5JÇ\¥wö?~§Úþ Ym^¤CÀѸyÝjAð¥ã÷OTݦڄÁ×86 KÐ D‡ ÞIÀ­çùVFhà%¿jÏ ùÒÍm‡ž6aFi«pqF`•V³{©ýÓ¥ýðž¼~dƒÛbBô&›Õ‰u¤s¡ Pƒú‰å%Wþ†e‡$€m_*톚§|ßh¿(úi$# ± ýª(zçÂEÿúçTˆæq JZp«•$ÜnçÉ“'s¹œ2$ÿš1ùu&fb&þÿˆµ´Z, À;Iš ¨ÍTVSSùÏOL°Aƒ(8PXÊ'ó1.ùèð“nŠ˜Ð8˜0þéªO*U;$…Õ`(ÁLÎøM5e¥CíM$jmz»wD¹™Ðð—mEa-ª<\ŸMâi°`CŠõfø£õû¿FÁxa$îÂ,:ÌŒX¬F3¦u➥.û¯~ùrškLqÞ,Q¡ì 7Ãc¤H&å»Ãæ8K/ÇyÁë±t”š `0A ì„/ƒ;ä Ù>l|¦ê%ˆ-©Ã?sc îÉgWj¦<71˜a÷1|}&ëüCMÞ…»·§ÞÞfZZ¿d×ÙŸYµ|í*7€™_h't´ò?ì—yl×Çù£…Äø¶÷šÝ9÷d‰ ††Fµ¤„•‰[Âјû°½>v½öúÌa‡¤QÕHi‰¦)…¤QÖ^Û» ˜ @›ÚµU’ª¼;÷ÌîÚ^ïåéÏXBüCU$*RÅ?½½}3š÷æßßçkÖÛÊíª«{x¾†\‡ºVZaÏèÑ㿬ºkŽî{åõ*+VJèÐm;çÿßÐÈ 6>˜“Ô¦}9ѳEr_–ÉÅPœÐ/ø}[Þ¯å› ,˜IkÀ¬¿9«³•÷´×Lz ³Q±ñmbp¶âUÁP“þ‚‰~,ÔÄý³Rý†¤·$s&;1 ‚Òùé^$Ý_̽“ûáKßüô$öÀ1ã¿_¡â×g‚è¨/wâlÎ乂ñÞ|¥_?ÈûµI?šì×)~UÔ›wþebÓª<‚À0=F & ±Ø°³Y±Lóê«Ï‚˜@] Ž’>À ÇNyia¹Vl ¹™é’¹=¡3nè¬[ÿt ¡SY͈ÞPèp¬¾ú×êWÿ§ n«!Û¨[€Œ{¾}Mh8ÿñÖeK0£áI\§rÖ- · ,0³[Œºo Ž»n9¹ú¥Ã@/"ç–ÙvvE`²óïŸܽí R¯1áfDƒIEØ»»»§ D¹Kfb&fâ?G&“™>5ÓWø«d”É4üRéÔX&5¡L*>ºö©uEḞÂ)RGو—~º–ã=Räž½í}+läMNÞ!Ë~Xa5`t(‰ÏVϪ׷í4W~O¥ÑÛ)J½wYöøY­4 Uús>è¶•’$aÀ­˜Êµ«Tä*ÐÞgN{s”>MæÝÅ?[ñ©’§1åL^Ü—£ å*Þ¹Ÿ·./U¡”×él¾˜487kƒ/ZÆü:åœN>¥NžÕƃ9J^t g|È8æ¥ô(ܤIúôŠW­ d)Á¹™ÞüŒW¥ +~õ¤ì‰]Tz‹•Ò÷2¨I h½^Tï^• Ê`°áN`*“5iMÖ–›% úPM4¶ýF´ö:ÓƒÁ5ƒßù:QläÚ…–ï`¸v‰?-àM. íbén!RÍÉÛ8ÁõÝ5vðl~¦œùWÓ¨ÐÄòm-ík¦vjÜðô#p¸D®† íçE'͹i¦‰ã[¦Ìç¹ó°l»(vÝU8ø •_ü|ÈM 13j H½níêïlXI)‰1T%LŠN ìm¥…ëm퉙øšÇxÜŠT*u'ÀdØ>5…%IåÃKWJæÙHRƒ¡*3¹×—”ž?ïˆö€pô]³Æÿº0tc,ÚÊ0µ Û|ù£ƒvªÈŠÛ)ðZdöïÞÚÁðÕ<]—Úù‘v0Y4{Ï´ …³!,¸E±žåë¥Hçõë—þX}êí­'Þ¬ôw\¿Ñ%ˆ‡e± Æ‘ëïß§¹DfÕ–ðv™ji—„>N­9*×ħ(Ôò|»L7*ÜdÒè~žkXêüÇß¶=¹¼¤Ô\lAr‡‚‚ØŒ$=>Ô“Zd¾#<ÒH‹»~rl=¦#Q´àù/9õöóÇŽTœ l¼zµ~é#Z KT?ëYÁó5шçŸÃÎÇ«MØ‚…ó´,×€TõÜc&Ò`$¬•ë²â¡ãb„® ßIêLz4ßLå…éÆá/ÝeÖB·™Í8n'Õ0¤…&ʤÁKHÂBæ}þÙöp¨þ†5‰e€7' ÊWF>uÒ—?Ñ›•,Rºx@ÕUU„ º¥Æù6Þb$U-úèeL *âè™üÄÀ\³Š4 ¤Éˆ®[¡W¿‘ñj&üÄè`VâýÙé!D~M5©÷–}y“~ûhÿ%ˆ|ú¾ÈT¤§03aGŠ œ$uº¼2²°§ªXôÍR.¨'ßÕ¦úDŸ~<¨Šl aé^$Ò—“<«̘ÈKùŠ’]"€ûñX?2áÏOŸ›£x‹”`nâqVâ >1P0xx²7ûAÑH|©Ó‡Ô«ËŠôÅV Z‚¨…Àô„ÐuÇ–åŸ_icFÜ´tˆ‹ìгõ°iùP—À´r\uˆÝ §€¥³k$©!tÓ%ˆ-pð®ç…ý?@ 9 eAçÿù²+>ÖÀÑ»i©¶¼Üf1™Q•ú•_m‡1É-ómaÚÅ .ð/t¸ D`Ú¡ It3ìNQÞyWaà±pØÃ Ï Õ.)/0èŠÁYIˆýÑÒE—.„$ãJ:J+Ü)¹Ó(ò@d&fâ+Ód~›C€I ÇS“ñ̈(‰øä‰7NPi¢HD«1"ó0µê¹Jûµ/;Ã\ËÔñŒ[âð¼Ò´ÈuN%©ýh×:R VHK¢ù«–—_û¢Q–ê8z¯Ìy ÍñÒ=ӂĵ‚EŠJ­ÐËÍÐ>ÈãÒ¨#,ìäÄZ†¯ä)Òf”!uB÷‘F¦dšIn™­ÈFú7ûeÕyÅqR^g½ÛÜeVÛIí¸.q!´D,®)$Â) vJXLíñ:cÇã lêB)Mãä¡ $BŠšÒQlÏÂŒMÝ6Ô*iHÚF5Ò3¾û;6^Æ3sûM,Q©RPá£óp¿—ï~÷ÜïüÏïä±?r«Yæ;AÂl‡$¾róöO>û·#L7Ý‘ŽÈ\ƒ,µ½öÓ-&ÜŠiáu¥…wŒg;dÉIGê£R}Tè£i;Ç´8ÙÝh¯4lFBQz¶™ë±õŒÔûó7jpTC¦R[îµk€+Ât/ /3c¶UV†ë`Ä—ì§ ª‡OþhGº>¢“æ÷GDGåÆg¬…¨ý¾mQ¡³r}±‘0PHźò¦Ú­'7ÿ°¿ìÂù>ÿA_pÇëµ?$1mKA‚b‚å–(ò‡£|›Äµ2\“<Ýq{êp˜v›õ¸†4@FÁ0· J‹4]îrNvÎÔïÜeºjCM­ög8¡+p©Öå›qäø±í€îXißÙ·ê0¡p}O•Èõ«(ˆ?¸%Ú7m°‘V„[ÞïI’£ÛUa„Ì$ºª¥å[aþH$v˜NÔ×–:ù<= *•Ü?ÀßÏKòÒHܯ^ÎNø³ýTÒ¯UÆtŸ kË¡Lƒu bB6Â×ý+åÐr@‹Ã:etåÜŸô½5H ŽÀ†"S‘µz^òjR~Urx¥RÏ]Ì™"‹!XV+¿Ñ)¾Œ…@¾ò{hfD'Žë‡)ì¹ y‚¯Ð¹  ¢Gq×B¶¦FV%ÇVÔWç[Ñì %ȉêÜø¢ø00ÜS5ñP®rMø4I_¶âÏQ‚pÊŹ3Þ³ùàðÕkI‚0˜áüŠ¢ÇÇ2ÌÔs¾Ü¤W­\T%G3ioþënè)<Ǧ·0\;ƒ–,€‹ÊJ 7ßÜ;# r|- ÐìLıdØ©æX\é´_àYG{¢¢PϾ~jkYü|…‰a{¦Øú¨Üó‡÷Zp#‚ª}æ‰Á焨;"ÖÁÒ cXÞ!²ÐÔ A»MǺ˜H‹Àºfå¾/»‡Ý,q-iˆ8Åh#4rÜñ¾Œ¢0-¨8‰chsë~N 'SÿUZ ±‰Dbé9ÿ¿ÿQ<Ї/îvÇÝŽ˜UÒ(Ÿº™Ú´q3h% ´8ª³†b«í¹—ºO’Zx¾‘™j„VYpò‘ŽE#~ãs; ”®zºXMB¿Sñt[{å7Êá'Ì6½T³:Í{üR‘àK%±ciù°ÑHb,;1¢O´ó>½Ò¦|z)˜ßû]Õ5YLj¬jèt“-"âÁ¬…ЊÅQXñ믚&ÖI-n ÚB ©©D?>›%\‚å‰ìOß1Ù®ùe»öN0_ ¬TÎgÌO¨‚¯ªZ·Pßß’µw Q³jkÎ8tUGY‚C&̸w=*…P€"R ¿ÔœCl–³mmæÛE‡6æîÞðXWúÏsËcA]ú>$5œ›òeÌû3ãA]rCË®¾»¼1äm„ÑÒ¸ƒ\ð¡ŠF”@&À¤?ž¢JJŒÀ±ßÂ’ñl}¼ÏÁñ<“Ù€ÁŠh¬$ù¦Õãáp/Ã7È1»,&i‰ .ÒÊOuK¼kFîš ·¥ï-Ý,Š­ß>9éúð¯{€_=Ëð®U8ôöË46ŠóŒãI«´ÐÆ>vç¾vf×»>À©$-µ‰É¡$AJ£4qH|°^ïáݵñš¤%miz¤j*U"‘’Æ7ÓëC?4¥—R(Áxgæygv×^Û‹ Óg³R*ñ!R$"Õ^½zg>̼ÇóþŸß¿Â+ú{¸êâ¥>ÓŠhZ#ä[wx–ø\¶G›jͤ“p; ÇÒvÈk7ÌCŒZ¦­n@ "D¤Å‘Ú•Éö¾õvúµå2-„(²¼Wñ?ôÀŽsç/5¶È!Ó÷I¸Kñÿ ×ÇW?äóù¿ÿíµk*ÁŒIœ ’rµ"nÝŸ9Ó‘iÒÔ…:,3(’Æ©KQèo¨­`‘Àá‚©I¡†ÜìÁ[ý+³T…@2¡–Í)ªya¶ÖUåFß×ãà’l;j§ƒ&nÆF+ü¬©…38ž1“H`T¨¤@) zŸÕº :ƒ~B+–æ"™ÀûóZ:Û7Õù ™^6ué%X2­ç.&ß~GW’ÈJÙíÛYøð|lxü»"GúÅÀ½›j&QÄ0záÈ2v{A9Í}uXBÙvïïÏ4^N½ nRx^r“¿?¶šl3”3{Ó¸Uìz¥oETÔzýOþüÐÈÜðrgˆ½:ìÊ •8cÄ»¥ÎiR¼Û•ß?Bÿá'Ä•Ñ g€t†n¿6\æ ¸ŽÙ9FL3z³âNªŒ¡ê$Zd8 )o’ùúš²jr…HT­‘]o¿¢à1¨ÎÒ[ûéZ†áHžhë—9n¥°Ž“Y"¡.û9Ïg„…‘²¹¡ü…›•´\ÅKüZY ˆ.J(Y¡þÜÏ–-ŽWGVC}Ï%œ±ò«cËòÃ_uFn›qn¯¬¦Zæ9—8üªÛX}³hd¦4äºv´<|ÅÂ)h+¯œ(uŽ“™qwÿÓ•`,*+Ë9á6ÖU༢‹Ž…¾uîB»‘nVQKÚê™ú¨m&·l„-Üd[­€NÛ€8Ì@SÑ™Ìˇ~x¿‡(@í ;1šÈÎt8RÜž±útµÙ6ÛõÉ„möšV¯jvš™î”™™îЧnèb²øCgl èf-µgÚî1µ„ž !+4qºíÁ{««…€H*´‹“%OMÿìÙ³E±ŸŸ/Àád)–b)œO2I.—;vì˜È34éÆÇ ‚ûögŸúÚ‡çûTci<£„a„0«SÑ´Õ6äfш÷BE6Ô֌٠Å1“ ©ZldðQZåUxÊEúxn|<œJ% ô\u}Úïëz“m‡jÆ8Ì¿@j,mîµq§ev«h©쀻§3}†ÞñÒpˆ®Eж€éQxÿƒW·ù%†'èíøÑžšÚ=;›Tµ.u65|]â)‘£–Ù¾um$²UQH™"½¾Ù-V:´vˈ!Ôjê=0U]kÎ$R“IœiÎÌFÜìeh™áŸ}bKJ eí¤1•HgŸ‚Õ!}ß}Ûž’%ŠÈ.† 6ÞUmfa"nÑq"z<¢ 3•>ô²’@Q…*‰ë׸þzv·Žâ¦…ÿb3rñ£àá_=lÚðÄ®ªxìÎ'“45 „K. ŠÑ«øø¹¢‘Åñ g”\Z™[ymTpŽß¾xtUþ=×µÑÒÜíLЋÀ''Ü×g„r]FVºÌŸ¤æ¾ðçU|Cr{™Õ’Hº9Ydy…Txg¥‡`Dÿfñ‹ï¿AYCîú5ÁÊïÛ °/?]úãçJžÜò¥êZ8X8xIaY{½}T¤VJ”I\E~õj5+͵ÿý?Ïû{¶¢CgÌ{ÓZ‚Y­Ü7¿¶ŸèDR]Èh·íÊI¢,o‡ç3xч'³RçŒ#« KXœÂiš% ¿h6Æ.G:g d¾VÅ_Ê92-¤±â¸‰¥1›i¾-û¹oqÚ)úæÛ³€s³í$ZµÅ6Ù÷cºh$Ù;+Ñozêǽ¦©žXÞDo¶gËÃ…4eÆXu>ýraq¬C,YÀa…,bÜþ|Á¥‹»uµU‘]÷Ƶ (¬I“›t­ 6¼ª4ñZ3¨Fv)R£;t¦«¢bC™(T”ëâ£miQ\ºxHk$õAlÿý>Ž€Çç;pdåcÙüT“ô}‚äŽÅ[¶ª‡c­BÄ£Ê !Å£(õ²ÚvðÀª|ÒDY;ÉA’¤ßïO$à·“““©ÿƒ35S_ûšššúŸãûBHþ§''’#㛟¥r.…Ù)”Y0ßòú[´xH’$fß§N‡ÿ·¾~«¡¦&aÇQ„¥˜'¶ó‚Gib]²Ø8ó‰B8•®†>cê}Q yŸ$¾)í²_RZu}·¦„ÂᚘV;*¹ôh£¬º/ÿ±êg?êÉ‹ÔQZl½xÉ…“ÅF]Ø¿æ‰2;¤E*³«»A€Ëc!‘Oß–W¶ëZƒ&tœ~ûùR'ƒXŒ*YÜJãŽã'¶B„Œ+{ã߈СòAYÙSë^& E@šXµ¤üØŽdãVÖFPïœÝsífý+'6jz ÜU—‚Áæ…$a!HŽDØcÇž ó.EóÅ4·¨x«ªÂ… ¾èåW+$%˜vã/y=§‹F¾¨î>L¾T“ÛúlFÇ ¹§‚Ök¿%=xª'{¬ ÿ9'ËÌÙì BæÄÀìÔ…Üá.¬jsvÎj]š§F»ÌþMeËalƒþmMžcÆß¥â—sÇÏgOõd½t˜²™,6›6Û °¥ˆ9Ÿ¡ðyˆmÕrãQß|'A‘” År:òîd$ Óµ©.k¬;35˜™x×0ö^ÆÝþ€“+Çi§1×I¿ŒN¶'©Æïe›™"ŠÀ$‹ÁQ–.&©ü€omøïî°êç%ØÞ¨PÕ]­@:ž&ƴ褴äHÒ-zt%êÓcµªÐ&EܺZ 'hª(EŒy"òÎë t¯ùWkÊ}œD g13øÁNAóiÎ €c@ƒ "óíŠT-ñµ1H( k@}Ù l·JK2¼/ò‘Ü ˆ·ÞÚ¼¸xŽÅ)Ã1 |iGÅV5*ó‚ ¤ôÔ={~€%÷=y"™œ†Q1S3õUÕ}&O&“÷i>’)ÀðíÛŸ¬]½CP†´Ñ˜âÛò¥æÁËõúÈA¹"ï ðO;f|Î俣?]Ã"ÂJ²6s©ÓpûV» Ô€íĵM òa·À7…`Ú~4¢Èn!ìÕäfQ¬®‹Fk%Å+©µbØ«H ÜLi»qõÈ徊úø“ÝÏmrPFÉcPÌN௼º×ª$9€csh+WVÌÜ Õ]Tº²_êtíð›`^ò¶·otØ)JsVš£Y§öí],!YðÊ‚PA•ݪبJðh—*d%‘vEùÖÊM%ùœAYa RHg„#î¡xþý¸Ðòë¾½¤ØF‘¸íïßž QTˆ¸dÝÛ²¿¬Ð‰ –¼ý¤<"x\ghä³{b0#Þ—§÷’Z§÷wûL©žÜÔ¹9úŬ@eç@ ä|¶xe)ùLyöê„5XHŽá8×Óæ‰î¬ÔûÆ#;s ØÞ(QDÚ>øufê:~ž˜ìB“Ö[oZVÚIµ¡Ô\'æ(/ÊÛ´>‡¥òP«É†e—âÜœG‘%+G.ØS]øÝÞÙÓµ£†TŸeâ\æÝž¬D150KëEªWÍvP,m³Ú¦vÓ,©Çœ^œ‹ì¾ÂÁ£Èw̵ӅVŒ´bFfâo–-#NŸÙ*Ë­`Pºê¿¨¶KR­&V«’ö<ð¿"6ir“,¸Ó›SôˆR³ Ôó‘ÚÑ¡EðGø:Y >°nÉ¢âe‹í­*ÿø£Ž_í†ëñÅ8åUU–¨ú± 'Ý{ïQz0¦àï5EÁ¸’À-Š?I‡ Aq)ÊáÁ -+—ZHÄÉÒe1¹qý3W?úK25–6â©tH„z$ã‰Ä ‹ÌÔײ’÷06üƒ¯i2™J áêÕ«¥%N3²ÁºcÔÆ'‰×Ûx¥&ÌW‹¼²`z~M7f|ÎŽÅšþ­]±ÄQ@Ï£Ð;áðûžàã5ð¤¨OŠ´ Çið|p8Ì—þ>jHW]B´~H=ȇ[â±€$ºÅhpDêàyÿ¥]{jKKˆã¿\LJƒZÜË¡ŽÖM…4Áb8mÅœ ÞÚ²æ|ÏfÖF³¤åû•EB$46V ¿¨)!I ‰‘¶Ñ¡ý¿Gö­[[€Y11Õí^F[Hà'mqGùµº”±j¸¹(x ÊéŠOÉükÀÃϾ³‹Á,€@…¤Ãnvày½•’P”z•¯eÏÊeóX)¢Éhd_LJQ?¸q„oþÝëÛi+K[ ª¶•Iòt¡‘ÏìTWFª3+ÕkL ˜&{²¡S½æT§5ñnôJöÁJs‰%ÃN>B ЍâåKòæa LX~ÏËp_ÖPçÜå ÂÙ³_¦±QœgO•¤ƒ½ØÞõsîìåõ…†’BÓDˆ„¦4QhA@CT°½>Öës½>;8 Ð%U=QÜ–(€]€DÓ~hURZœ–TŠíÝ™yç\ïÚ^ï®§ÏâôK?¤ùPd©ò£G³³3šyß™yÿÿç÷A<ç¦æ±ä°.uE¯]ʉ×ôî×™ó6»“bºæÉcV€œÛ—K;wëáQàvÚm˜¥¤ëõ•scyÚ¯Öh£Köb#íb®Äf`ƒVíêÊ_6: ò)³´Z6Ù³ÇfÖ®F²ÕÁüäµG´Ãôö“•Ø–2Ê‘4a·ØJ(ø5Üd»"À  Õƒç€I¢ ðC³ã•Åö ±(ͼX=ÉÖHÒ‰Û·{÷ìüšËš"²YI¤TZ|ó£ÚBr!•NÍÆ!±Xì3Ó^¢b±Ëñ°#‘H,î,É¿c¶ïü+é p£“¦í˜ÝŽçÔÕl„BZ‹EðÛ¡Þq¬¡:éáW™ÿU"Ö#Ë £¡C”Ah“ÍF`¯æŒðCB‡¡(K’W®ó¡Ïg*  Çd¡‰Í`Œ’èŸV[£\#ËqåXp]¡Õ~yàU`?Yj“ÔÆ0ò|ø[ÿ76®-$‹,ú<+Uðô×K ³“¡²~tz‡Ä&NQ éày¯ªxáæús%t”„Ñöíç‹ïO½›VYOZifÛ ø­»T«ˆÇ$îˆ*ùá›>°ë^ð!±îëÛç©X»{§ëxÏŽß_ZkGB¸«,µŽâsÚÍFìzqƒõONÔÅã~èY®ehø»Üà$ ö|§˜e;%¡a™FþK†Èä€)9¨™^•[•¸š]­]$µÁ/¥ qÀ1t?í!/öê~wÆTd²ØL_Áî‰ó9éë9·ÎåD)¦wŒ»ç5‹4ªWÌ^ÉÖúOšŸ.³ÑF§bž)Ê™¾j×ú³µ¾Çµ±¼¹~¼Ì•k¦I†6Ò&óÍ÷̳Á,íýÕsKö⣘6˜ìÏK]a—EýøöR M:ìÜnq¬Öicf­Ï0Êž¦´‘'’kF0-¤¿óìp«™i“V»ÝZæ`¨r}öôNùa1 b•Äõ(rKFà‚„êX\É@ˆó ¬˜à)Õ¼|ì©' ¶¶À˜]ßüLmív»™d Èm›7ºÒE;·®³òÜ›r´>ÌÆ‚žðýS¬£ò[¥†5EÂ>p8¨ÊÓ*˜L½ ×*Ó¾0ïå…ÇöÔVnpÐ&ÌD1´‹0Û\6çoÞûébW8ŸÑþÓ®—c9þÿ"N/nS©ì,nÏýâ—4a²Ñf«‰*ÄJ Ó™w_Ô®éè!>\'„Û®5ª´‡€Š¡ä-9f|ÁŒ‰-(Ü)(Õ»^vºÉ F1xáÎÝÅÐ4q¨žkß ˆö‰È+óGö|d!c€,ªëã/'4±Ð¦ñþ¨T9>ÞDb$Ô»ìTµÂ{¹66Rn5÷“;moìÛä¤lV ÇI•´A{{¢gÏÇšïZ¥Hj¬¾?l|çÝ­vš±“em-[¥Iºê pg‚p˜cýZˇ×|¤Eà‘E±.CJ\fÐH¤FQ|â´'錉Æ;3®g…¶îömÍÏ–•ä’¸“a˜“?ü&+t©±ŽryÎîºõ—@mXï¢ö¾\#‰žeùüTG²âëRc¹ cúdÈégGògFsçC–ùÑGÒcYs¡¬™ÐóÃØ|È”Yqãçº3M†ž½y‰`v"¨ëÝŸEšÊÌÎbÒRzóÇíZnrt4Î\Z­08I9ÀaOEnlȬ]ÌÕÆ¾¿lIŒ­xåùBÂJÒ¹[‹ŒÓC–ô"çF –ê=Ì éµ««Õ]¼?_»úØ*+¶Ž¤LAo+&'ú­Z®v› êé~ËlЩ êæV$®ä¦F‰·›‹s MF‹Å—¸ÜPå {w­ÿëx'Ô!¡B@ HðˆR•¢za‘ƒâ@øˆ÷©r³Äw\cFe²çÞTûú2ÊImØþô滚óüq¼j÷°CÚi‡NÍýÎñí¼è⪃CUEÌJ¿÷¥¿}ì“Õ*Àž)¶’EUª:òCN+ÄWƒaf&Ò¢H0‡)Ö#H’âW@þ\àìÙ×ÊDYJÂå (› ÿþÛ'$L-:3D2™\Âz±Ëñðb‘F—z<‡m[[…:ßF%ÔºµSßù]‚è‡2Ä…ëcJ·Èû¹*Ž"tE¦2-À’cÆLn²IŽñèÐZŠ­¸ª=IB?r¡o¯¤tñR¥(7©J{x²R}2:üЧ„¼àEÿ=pîÜÁŠCîàðØL/Ë5IÈ;8´Ÿ°4YøÒ‹åj¬‹‹ÔI¨YàŽ*Ò!0Õ0ûÖ©Sû]ÜbÄá)í ÈûÖÝùô¨ 5!T#^ž­‰É'àï·¶¹("Á‹BÃû%T §D阧â)s8Èõ6 µ©|Õûž{pÿQ¬ÏTv®>*·!¶A–ªÐbÑ#¼ü=N:C³\‹$öº ù…˜›±<‰[¬Åeº{‘Îû“-\¢t¼OƒFØ#ç¸.Yn‘o™F>?çG BRƒÆä%<õrá2‘4ª¡Gg†ñ™QÃì)=„§‡³C¹s!ƒ\ÁR#ö…á5Z(ç_ì—ipçÇ3 SÀƇdÉ’vW{鲎“81ä($-m @ÂPh „c°9lY²,YòÉå@ aÊд_Ò´%ÓLCJÀ–uØàé1e:JÛ¤…4°¥½W‡Y²´}”Ì4ýÒIÚê~ð3ï­v÷}ßÝ}žçÿû¿ÞkØ´ÚLbKž­­˜ /‰ÕJ›ë'/«•!œ *pÌdCª¼[—L]A•63 ÊŒ™PeƒÍb@Q«?¹Ã2=¨ž aRØÌ\½% žÍ\6¦CÅ7ßÔÕè¸eaÔTcúóýË”Q,ýŽ:?Z”.Ï~±@,‰v*X®„õÉKªÌ¨nìíêã{,ËPm¡Á‚i£©Öjzõì†í˜Ã@ß(ˆMðl¬c<©¤þ8_\rÅ¢Np(É=½ ”©ª¤Ïž]ŦZnEÛ_GS(M™êWVßz¿]H5þú·Žºåj ÑXQãé“[Î?6îŸÎ— ™{ø˜o¢0y#k‰Ë'D‘EàóHZX+.·‚º;îüùù]ÖêLMhð4NzÛ=J.ÿO&™cµ˜ù¸ÿ4’ÏçS©ÔöíÛõz½‰4ÐB#h]}íšON¶òBSœ?Æ2},ç•åV–k’D;î›Nᘖ9ÇŒÏ9dÁÏÄ\r¼G½G¯6¡ˆ‰DM„}u~÷£bÒqwlÿd²$XàZ$¶ã~ïGâ{»<ÕÙQ N!:M}þì÷×ð² Ú™3kÍ$I Ç žkKÊ\¬Mä}ñÄž¸ä”SÍ¿»æ²(…Ô.·#4^j³’A®| ûÕo@úý"ãøý2wäÆu'ôIi³R†{ãÞ©„3)A×픤ï8Ö=SOµ\qñÂ7>¼uHº%É ®MÚþ`\ôÊ|wBn›HôFﺓr7´k)µü  ZŠéløƒ_^Uu¤ýµ?x£1ØU›$¸D®Ì&$ /¶q¼‡çûÀʰ"ï™§‘ÏPá ¦*ge¹!µB”0ªQgGŠsA[ö’N4(CT.T– —¥u©°!þKMv¤Bz .^œŧ†Î©‚§åª.ÔÍþBŸ §¯¨²J6?­¢èV“½ÁŠŸE’‘’d™¸ª}«Ù@UVÑVÔ®#nü€PFT¹  Î*Á9£‘\@“é²a0˜óEµAk×c(؇ÝO?¸l˼S¦D*'#‹&CšüåâìPÉL¤LQç†ôS$ÒMt“Ãx.¢œ±¿P[fÑèíÖZÔ€PˆÑ†š¶l\ñ§ßŸ`£§Én^:É)ˆ~hk< ë•D7”Bò‹l§(·E={wÚkH«Ñ6Þ Äòáßšç,P§©7¶kžlܽügçöܹ} NŒ…ÞØÎíÄÚ’ ¬Ç½ñfY‚U: ‰œ\”U¡;É®ä„ïÊhã#•,³š …iI ÿæ–­²(}B#³™ì\kÅ|ÌÇý €L&?dY^»v-‚ E™Q;X×~uéß>èâ.Д„Ø+p­‚ÔÅÉ-¬Ô e(²GRWl|_BtÏ9f|ÎÁó-‰„;:Þ'&ýÀõè2ÜŒYLkÖß=ùµßšœè¿ë‡çy‡Ì·ÝõtÞx¯}ÇÎå„'ч¬„Åb,u6=û¶ûDÿ:%€—.^Øf Z\<& ̸3Îwˆ¬šØ?ÙTE™ªÿȦ—_Ùi b¤3ZªèÊS‡¿”ä:‚pâÕÓël”Õ.ß¹ëA<&G]ðÉ$®0'|Y)¾ÛÉÇ`Ù$É!ðnh˜²¼Ÿcb´Oâàb@‘6Yèà™>à fü$ 't`H‰î;¬#1ÙuN M)vŸí¹Žmù.`˜S” 6ë™§‘Ï ‘AL if‡‹§GŠ&#åSam:¤É «§ÃÈÌ€J*WÂ¥™ðâtdIáâ€VÐ)C¥ùÊpMzpa.‡ åÙadò¼J¹Z¤\„[Š3ƒ´2¤:×CÙuõZ£!ÉgkL‡·n&›·”×¢$AÑF“îɺâ™z6¸(\4±*esõf†™­ ?øî©ÒjC,´·[ÐʯfÂð–ÔùÁ…™ 51¥/áJ b6HNJòá¢ü J‰¨f‚(#ųtú²îÖ ¥·™¤Q-‰ÔZ)†”P¸®Þ¾à‡ß[?v¯ xƒå@#‚ØÉÃñ>9~PæŽÉÇ¥ý<ãÏ%½CÛ­ Ž}Û½Æ膫^9º‰]¢Ø·s[tKŠ' Ã1cMRZ£ùB‡û‰±±ÞÄ„'mœJuóŒGdÚÖ-'|<,〙eÁä# m°Ïzþ£c&R=7ÿÞûÜ’À–ŠÐ8‰#ØÆõŽ )0I.7×¢1óñßGîã‘ý8góŸÆŒ2“ž…sï]¿þÌãO˜1ª3ã„͆VìØjÿËŸ}P;Ñ訦ØXëÿ@AÝþu|zŠsC©rQÌw¬ãJÊÝ`(d±MŒù%¦3%º$¾¼xPÕ;ÜͰ‘õIB“$5¾ñ£—L(†£…’x)qýú‚[aÚ%ÞǤ­ë?¦®d· ¼àt$ß'O‡À²t€ãHÜqŽ=$Jûd¹•yAåy~W"Þùö›»¯ÅŒº µ ˜yÕjåSµ„¡ÚFUüñý—¤¨{Ztpbsœ÷Op]Ltw|Ú¿ýÛõ´n© #ƒá­¬Ðÿú7ÔÚË­h Qi1Ó† /Ôß¼³Ÿ•Ž=ÿ­©¶éL?}­‘ý|¼ù~ǹœèÝüâc§H„4’™wmÙPe€d®1ãÿd8¿e«1"zÍb±Tÿ`¿Ìc£¸î8ž¶ˆPH°ñ±žÝ{OÛ\C © ¹ZÔ†’¦ iZ 2)†õ±Þõ®½»¾¹rH”DEý£¤¶j€’(ð ¡J‚H  §GDkŠwgÞ1ÇÚØØ^ïô­·¡U%\É¢‘üÓO£7£™7¿'½÷ý}¾&áÚ™k£rìŽÂìÂ7Ëçø;aJôdœÊïž3ÓõŒuZ&ÏÌKvdO´²)h<“1Ú¹h¤gÁx+otÏmÖs&›‹¦Ý. µgSætçOÏIv|Éø(óÜ×·‘Ã. Öâ(ä¶Ü‚¾·êʯ¢z¢R¹oÍă`Ôp€rUõAŽFCX­+M@ÞùÚ+k\Ü"å|ñ¹|€Zû_}ùYžæxÎÌÓ;êÖ\¿æÝ¿÷Y7#0æ"ËúÕ›Ïëj–½HöÚ‰Ê~0ä‘a=¡¸V­É;5POTH;ö¨Z…Š# ÚäjM¯èkÚ¸®P4°VJEʬztYoï9#acÿf’Qï)mO$fe6¾Adòs&¹d?§Hd¬÷Ó +–}ƒ5qù6ÎicY³¬úfÿµ×±²K>M Gª†õˆ®xgº›¤ $ÝÍñÀ‰‚wE£5Z< Ñv]«"dcCºG/g1¤4 XµŽ«A¬Š01 wš? Ê’¢BVšâ뿾û'?\)0Ï2¢•õn_!£²8ÞM<¡I M·þ4Š&!™®?Í'D⨲ƒ 䤪¸Ž<Ÿº¦þù¯5¥¥ùù“H»ÝÎ¥¹¦/»D·g¿|Å/É„[0(ÃJ(ÖÒd¨¹oÀ·¼ˆ¬ËÉ›®^ۢă@œ;ï_¾tQ]ï´1Öbwæ™®ÆHÄ}ìÈ^!œ&áRˆï96ÌPÎÒÈÝsäsЛ»Ê±Èau‹”=Ÿ¦_æ^Â瘱˜Î¼ükz¬3ÓhîÜÉ6&y’šézÆÚ­ÝL´g]L¢+g¬={ì”åVûB26:ç rÖ,+Ű6ój7×÷ŽcºóOtå%;7ßãÆßÏ‚g¬ûÊíE,k¥sM– —ËÁÑB±ÛqühéM}‡ B­D‘›t%Œä€Š~T«šG{ƒ1y³Œ*dÐxìhÉšGî¿t9 º÷ÞÝ PŒCäxKAÀÿht°Ê58Þ¼þé•NçÅ- c7jã¸.®4È €”&òVʆ´0’¼ F¼I Y)Ñ”: u HÑÀÍ¡ü‘;ôª¯je¶æY\.›ÅÌ,/^ö—?]0ãÆd’pÈøø8‘qb*Éulbb–Ffã iù¯›âêIãâÅ ùE™l\hlôÜÆÈSýabT=ˆ”jE°!MÈ?én2µ„(Ò@r›FdA¸ª~¢n#­Yƒ-*¨‘ GÑý)ë!Õ A u¢¸c·ŠWU )R=µJ¼æÄÉ-N>‹¥­‚ÕµÔî<Ùþ jTDjðÈQßtëO£ˆ,ùÿ!SK˜ZN K¬&Z„q…¼DÜ öaewLòkjƒYkC‘ßþnݲÅC:»K´°Ù®‡‹-û~öm 5Ä`#À ì±J$íþàãŽÉa™¼59‡â‘ë¨x%äíý4ôýuÌÚ'ø7ömüäb- Tb%BH¢REñÃØ®{Ž 3”³4r÷4ÎÒà䃱SÖóû¿zþó.q…Kx‡‰á)óó/Ô>°u<8yœMtÌ5:2Œ6ëLדl£“]Y·:2=yÙc­f£CL´eïÏýûaæ!·ÉfIY$ÚL¨Ééšöü£íYã&ãf£Í”<¾(ñ‘ùì!û Oºio¶>à 6«“cèM›V|öYÙ(ô)È c5XjÖq3±$@"–'@l ŽWJ¨ À †w\ë 9úðCoq~ŽÀðÖþÜú%’´+®‰4]½^²„ç,Ù.‹û—o”`rÆQ¹Šý1Pе°ŠÂE@l«†ªãjHÓ2ôm+†!¢ºVCÔ)zÃG$hx8D(&GZšYì´´S`6ÞQoëè:hI1ˆ‘’tŒ=ŸÙø¿D2I8db2#„I¦d?ùÍA‡`cgãvñô¡›$àÓ‡«e\J¡*…UÜ€A59V3ÝMHïN÷ôÛ­<}«ª>6Ǥ€6TQó¥?Öï}í[¯ïýnßµ=19$ÁrÒŽ “1™êìMwü…æK͆‚*¬‡±H l—•úJÏ Ž±°”Ïs¯ÿN>P|„Tè‹£ªÿa äÛ4ŠyÁŸó•$…ˆàèaªmz ÄGÂM‡ÞZwè­'ªÖP–C„µît÷K.»À›9;c²[œ.†"ìÏ}Ü[EþÔ_p©®ïüùþ§yF´‹Ü¶²ÇäÁš‘øNM §n€ðe™à Y¦êÃêVU+“c”“ˇãABn÷f(giäîy³ý+ƹ…ÃmóGO¾Ÿ7Ú1ÿêÛ¦ƒ• _\5ÿ€—R;ÝYFcœ—躟¼0Óõ§r’]9ã=9#Úó'­F•lŸ3yzaÕÞîøšÌV÷Ú¢Ì[]÷%O³Óžÿô} Èb'NQFwF²‡ÒÛùþVªÞ“UL3l®Åææ)^î©ÕîžÖ­P)#ÇÚÁža½ 6‚Ä›”EqáÖ)r-Œ‡ô–wßÙüÐbçç¯ZÉý£¿A‚¥ÄÝ”l^Í‚²}ÝÉ÷~Ò¤êÛTÍ RkâZ¹t=¤«ž!Ü‚¤:âGŽþÑßúv‰¥J)V¡*Dî‚KÈmj¬ø5½h²He –g9›hgżcGOÔûÖÈhšI’Éä=m/³1Ó£££dHósÒH&&¼}ØÅ±"M ŒKü'ûåÛÔ}ÅñNêÖBBâ÷½¾¾×Žc’”òÚ´ LÐÈèD»N´ƒm)$Ž?Ûy”„G71±R¥ ¶•jª*¶µƒÛIJ¶0`BbbÚTXÙD_ßÇï¾ì‡ãäîKhš[þ)?Y¿{}u~¿û8çûùâåfóâ'vÎjëNÒ ét¡„Üò1´_"9y×ÈáǽyîÖ•…=€’èNÐþŸ¿ûåVjm4V9– Át°ÈÅqnEòÑ §$´Ü/?˺d±q÷ ¶ð€|×®¹ª*JʇÅhǵÆ¿Ú"*‘ ¦yß\÷Ÿ{D÷P°$G#¼A¢e|°tJ:„øƒ}ý¯mÙ@X‰Â#· r#¨½s—Ð|üØV¬„°ùG¾¸}ãWˆb¼Ì\F`†Ê*ìø»/ t …NÞ|}-¦Ã[~ü“o_ipŒZœ"v°Œ‡]–¡`Áf9›õe ]7ªøã~äØ0O±@#ÿCãÆñ®âɸi2FÍD 5®éÊSût‰¨5;ðl&ž¯ödÏ.9_0z®p,fš÷ýœ[4-˜ê×EKfbÆé®¢lü™ìù§¯´9pJ¯ÕáV+®«:¾T=™asÍ?-ÎÆóÔóK³ç‹S±‚ѨVëÔØ—&cÚ‹'Wn|®3—™) T½ ·˜qâàç9¾““êDÅ•+ !è).ˆ>Ž¥ä&Eô¦Äæáá}¬¹0ؽ{UÿÀwy¾MägÒ¡ƒë¬D¹Ãhzÿ½×8!4’hpÿèðKGìøÅÉoüëÆÛ£Jk2¹7-uÒIÿà ×ë_ÞR}ýj`4ÝÆ£:è<ÛÄóNàíDœ ±ÈÿÁ¯ßx®ÜdÐhl6›Q_m%©d3Sê]ƒ©.0ÉÂxLFE2™ üÎ~À3êûï¢,$‰i,z+Ä GÁ•«^Nr*Š_LvŒÊô°GD>E ‚Ê#Þ~gÃAPrrEr!3¡:ã|_me0-# ³Öj%Hƒmͪ¥/¹‘‘å€"’ §"ߟšx¯"´Cëà¸z¸ŒM60H’ÿÈ¡-C1…[)Ò´²ÿÛM@‹ÄÌ™F„ÿªŠ@{ßB©ýLr¨¸d`d$páâ¢Ä@+ö}æœi©g€£< ïkÜWc'uD‰½;þ† ¿ÓÜDjõ6Ìa6–‘úŠ]5ö¿_o¥p©é© ëáàæ~^ËÑA 1Yô‹\‹,DX®:@ €DJnã“‘kK‰m#·ÆS96ÌS,Ðȃ#]:Ó§QûòÕî'Õs‹ÕnýD¼$Ý¿hªÿ‰‰®üì™bµ»p:–—é-ë)ëŸ÷ý¨±%ãç &?ÑNDujËÆžžúc!ŠSßÞhpà¤ÙT¢Å­55^pçã|5jœk~9fÊöXÔØ3™è™^íÄ'¦l¬P=«U»ó¦zñÏ>®pÖËÌÜb;F(»™Ø¶»|µžAól²!%„y:s¨#°0 í„"‚Vƒ”ZV¬ÿœ>$¥›XÆÍòžÓ§÷”š6¬”ÒU4ºìŒÔxã–ÇY»žÒ–›í¥z»Ã²lýj|èb]Õ3BÝ•KÞ•œ'µŽ½¯b\²U”÷%i7¸ †©—d`‰È7‰Ë.5­Y©Bš+ÌFŒÀÍÇú³œ¯T§8daQÜN¡õY)ì•í_–•ÃÉa`‰zo¡Qû‹›«-&« 3}zËI³õ²Üùá{ªËµ”ECY1;aøÚJÍG¿Ývår’ÀI5Ë|D[`¸È±~AhäÑ> Jx_ˆ?LG8&(IÞYÃ…¼jFÌÃx$häÁ‘ÍÄ5“gó¦c‹³½EÝÆLœ˜ê3ÌÄó&Ϫ½¤ÓLGó'ºò&{ò§úÍ÷~Ô¸>+žè)ÌDµjT;ÓûÅôÈÓ-v NáºüÒRërì 7N¨˜¦û—Á5sÍ?Ñg?•é*P»qµ§P°'Ó«¹ÓÌœ—Œö/úݱ꯮(%õEåD®§,&rÝ*ÃéÓo&èVQ<¸íIË~E𳉈"5ÕɰM²âFœK÷K‚?ò ýéûUUz[A Û7Û“(4̆wÖME8ø‹³b`t ¥frÝjÝ?†}ŸÞ nÛTYNØl¸áÙØ_¯F¸dŠt¶õñaY "”ó€Ð@üˆ ¤•&†o¸0¨\¾ÌJ-+%­¸ÁdÐéÃÍ¡Éñ `’©ÉÌ£–—…±0þ¯1==Ífa2~g, ã& P¤ÔjÓëë_ Ý‚Ð!ra‘ Êb€ç< ¨?Ó(ò!8)ð!¨ &é’ÄÀC”œŽƒˆƒ”Ã!HybÄ}è/­]£Û¾uÕºªRQ0ti?«Ô_¸àÆ0#‰Ù)SÉoÖqWmƒP¼÷K.ñ>`‘ïä™6:¹w쎗i’ ä‘÷÷úI¬Äl±`fÁõ¹îAÂþ¹n~Ö@Á*w!$w °ÿ›7¾çªÛPIêìÅúßœÚÅÑÐjZY©ºfÀ^uu‚{Kâ#’àaQð³/ÌF¼º¬œSE©ŽcBHܼÕþÍ/ï²ýòT=Mw¦F Ú'òí2ßœ¢›’ìnY ƒ½J§ZYÖ sÄEàÅqBƒ ù‘èçG}À*ðÏÍ™²—X ‘ñdÜ0ÇáæS½EÙî%ÿf¿Ìc£¸î8.¥R0ì®÷œÙ™½llB¨Ý6д *„£ ©ÒŠ£|ïmïÚ† ©UT•$jSª$U)Rx¯Ù¥¤’пš¤RªV@0ž{fgר»žñNcWT¥TT!þ#<ý4;3ûæ½7oÞû~??-U§¦MÚyídÝd²^Ë€MãZÖ©&Mw}Hg5g­äiIƒš»ïÚï¼O6×8p/îñmΗ5‰–S ÀHçï¸}-õ€FZ•¼µ’©×FLZÊ &“uj®ú-§ÍS#µZÞô÷“Ë·?æ³á„×çtX„ÝGX£}+ÿv%<^ŠC‚&³{en˜ÿ&ÓM qALpL_‘Ù'Ñ!‰`nxíÕî–‡ûÆ×š¯^ë¤øþ£GÖãV¬ ý /z¶«ýÐѧ6m]†¢vóó‰­›–ûí­>´·›ß~/ S, €äB6/Üá~Ä0Ïw3Bàâ»Áµ«—Šxq·ßíuØìƒñ„:¥T«Õ¹ö™{å^ù¤LkÚ”ªNÏœÏ.NB€œM¿[ÕÂÁæl ˆ…¨ÃêAÚ·m¬¿òáPIÞVîÉ1ýàV‚¼Û®!‰1–ŽrL\`‡9j Z`B"dänŽ9,Б y·H=+ð{yñÇk¿µ C­„­Éº Š¡µLé9†= RÁ#¿ãÇç¹lNÔ†'óŒ\ì(2Cw:žÿ‘Xêyâ1·Ep;êq,Þòx%GahÌÌ(½d¡ ä™ Ííšú4šÚ¸f¹Ïiò8Ìf;ñÆNª´ƒ£[ý:a÷>½yÍ„eöÇôJ{N'»pg´~wÓbfFëDº»ÀAÆZ4W.Ïqƒçøˆ™;À{!‘ééè¤b¸>šíe…'ÆY>NKñ1¡4ð‚Ÿa3˜–œä£*ÜËÑaQd…NH°l/è-¤™Ð¦ÄE$6”%Q1†K°¼Þµž0 ¸)²0WÈLºxNÏ%9Ðja@ä"ð,%wmÝ´GÝ~ܸ¤q>ó§Urn¾–®-§­ é÷™L¦2¦*iRQ²‹´” |PM!´\£’5êè’k¬œ³–Ò†rÞ<‘6LfŒJÞ2‘4(¤ž…j3Ï+Éú*i¨fAhgµ³F <=­_V³æJÊ:•A*dc%k˜L7”S%cU3àòH…ü’’©QSõZ²± cƒú¹E¹…sŽ+ŸsTÓæé¤MÉ×S6ííãã‹ÝˆËîÃ=j÷lø²ëÆ™:-S3}UÈz5ýÀgÕo9[«’uĪe-JºV=ï”R­§"÷9\Ë}¨Óo1/Æ;,øºÕí.Ä(¹ØV>ÍÅ _à})Štç-¾ƒ¥öEp¼^áò{¶=~ÿ{vé›Bî[âµ45Ùfä¥ckıçKÌÄìêÚýH‹»±ÕÛâ!q‡Í ¯ß*Ãwª'Ö6»õ„Ó‹!Íæ GwW•²6¥éX2“{Î*?ü¨Õª2==wŽt¯|q ,<àEÑ—å¿h¹ªÇTe:¸p»×íÁÂí4®û¶Pd\~az¼ÁbxvV>\Þuƒ»¤BìbAè/öKÌšš ¬æ×§¾/IA˜†ŠŒO$@dt`£ƒE)ñ?Õãg# WþÑ»ne{«÷áv§Ù~âÍשþ§7>Øìs¯ýf-tÝ’uÎaøž£G6»¬nÌnŒ„V# Üž"š¥V¼ë”ø__J p,’h/¬‘‹I|R6ïvàèAÀ6ž‚id¸Àì$èÌÉô \  Y¦£ t_B7¤¨8¹‘¢‚£Çºí$* êtÊ0lŒåúqpŒŽÕ¢ˆ|pT )½5>±¡›£Ï½siwjä{éäòä®|fg6õÌ9r;™Ý¶qu +î¨]ŠšÏþò‘?¼ì¹üÓ¦‹ÇL—~¶èÝüùX õ¦±rƦ¥¬ZÚZ>g PΕœi2 ~gÒH+‚:R£åªÉEʈQ#ZÖ®»° iTóú‘4•S Ó9K%m„PÎÛ&sæ i.§MŠ$õÕÔ-3ú÷†‰TýäˆIË"‰ü¨#óµÔýS¤CÉ!*DÖ(¢d¡AÜãÁçJzž–uOå(díÔYÓo5,s€Å:œNG“™8qÀ&Ãç Í0ÿ•L­šþÌú­u@#ÊY‹–2”“óÊd]õb3{ÚŸÕµ® AlY Á0ÇÃˬ¯¿²M˜o©[Âv ‘›×ŠÂa‘ST°±$$ú…±k‡eñyø÷‹]~Œp˜›—>ˆR"Ô<ÄÑ]27|ér¯ÇÞìEq¯Ëì±û‡â«xi€¾S=ùëGñ ë|„Ýírº0—… ˆp ¬©·@çEÔ™2ë³@2‡–t¯|aËô¿ d†á|ZQuQ”X$èoÂæÁFÍøú5ΫW‡Kò~`†ý!l(Ýmùn±¹Ûî{ 6¸(Kx¡SزTH{DvØàúDZ_ïl[jÙ²y¹kؾ£åÔÉîõ«Ü^;êÈÖfßuRLoáVøýãmK:¼g×W]V‹õûÝæã¯íݹ£Ý‰˜|.#w»KÃ’0¸ýÉ%͘©½mÁϱ^÷e¾üšºÇ sF#3 q ‘X@²(ÏDd1.³d~¾dAê¸^Ž åAþf_¥8G‘‰Êü{3\‡yº¿øOöË6¶©ëŒã¦mbBìØ÷õÜs_í8 ”v@¶n¨-”÷—B»–²Aé`P $ÆŽBMÕѶij¥jS¥µê‡­[»;vØ*¤}Ø4i“ÖBa”Hìë{}¯í¼ØqìÜ=&š&Mj%$J>ŒGÎõ}9G÷žóÿÿžL¯ž ¡™†çá ¦OëPovݸü`x×ðÐÞygOß™ }gž ô¬Ù±½éémKvl_¾~õƒ7ËÒ%70Åp `=ó¢ ‚€1vI5T½,à7ÖÛ·\ëfkš›€yI!¡#`®zb1¢%§m©@nú®gç:eÇêúÃß#N¶Ê§¼Â¯Û§ÝF_}‹`¦j­Á…Vd^1”Ñd˜,FèÉ'àÄtœ*щùcñšñ„c¼Úg ˜±„m,±°ü¾Ã¢­ ÎRôëãá¯L%”Γ…89³†ìSçíÅáE€C¥A[%â°ˆ9ǃ{œÅp5ÄÏÕY±¯UÎÓ¾'i‡M’EÌSìÁ ‚~¡¾wûáÊšÒ€}:Aß­q ±å0©ÃŠÏ/ ~µ[0#*¬»vNôÿ ‰ajy…¡¼Â ¼ÔqxeZëN¦ö™¦7gWÓ±¢ÿúÓìËfý h7?óMúÔÔÑdò…üݯ°f\-CÉ|{R*/ØÎ¿=»CæX™i”h¼{Ç·3æñ¤ú\V;y§zbdƒÿºÚ»u£À"vJÃ!αwßN=­YÿAÙ‚tÖîÇý˜“˜]„UN¶*3КcÛºm˜¶³Œ]ä= ‰6®W®_;©i^Ãðëú@¨p¡8Íh=©¤WÓÚ¾lwÓÁŒ´ ØbÀðOÖìÇOßð™£êá_¾±A`´Ýå–\<#|üÙ‘dçþU-Š@È.QYý¨2Biój{ï{Ö>æüË_½Z&dݦÚ{§óÉ©éäá|ÞùJïƒM‚ÀQˆ’ÁøúN®VãšáÕÓ]¦0thˆÏHÇÿÈt`J£)¯fô¨f‡·í[")³v‰òc«›1‹eÄèíY³+“ ¤GƒG÷7¿ýÆÞ.õiFŸªyu­5ov™/Á¸#©CsE#šê53~Mm‡Ïs¦?j5v íV/d&2Ò½À*@&zÚ›3|¦æ«öÕê»2³ÇÇFSÁô­Î?ðýÁþ?=µêåÐÆgŸùæ¦MË/Ʋ[Fˆa(§„(…#]ŒÃÍØ=ðù±Ä³R@#w4©>¯ôÝé|&3/ë©v#Ófdú~ýæ6¨_ÀæìY¶ØqéÊ‹iÛËvçŒ=Õ£©]šyð‹ÕÞêíûßCÝØõTJ øÛ×ñD#Bµ"RÜœûVª fj²-g´Ñ>5Ù•RO½•Á·ÐR>u´Š/P¹¹¢‘¼È™AC T'“ VyÒè5Í´ô\®#ŸëIŽth*T‹'R©nÍèúôVpøÂ®wßÛ}úÔæç÷,rë2«¾&F€{»ðÄ2´ö0 Aâä*tÈ.Z8„%Q–xIF‚‹\ vQ\3’šsÃí4+SŒ›A„XN¡‘`›¶¥9® ‘ãy5ÜNàWDF2Ϲ1ö¸,3"´ Ø%3¼xBceÉÀ3á–œ®G¬s€BnQbE´M¢ë\dM‹L­]*?½ò—v×¾æµÅ~N|ôBp–âŒEVDªòI„­ 0Óa¦aJQb:æ¨$ìVØa… k†³±£gÁjkæîqNE™ém]”1›¾CŠ´k Â6šìÚ¹ p±¾ò;›5h/Ææ—ë­!jò©x   Gå0Y9g·â¤wB[îwZç™j'áøÛ›-ë[Š^¤ËaYBK=bÿû’©@6sl<0ÕL‡š Z(5Ú9–?õò¥“ɮ߿»«î³? PÔŸy¼·wå£`EX‚Ô²Œ€ª'­ûòÙŽ¬¹?› Ý©žöW÷£áÏdúÚZ[$@yô]"Iabr¦\™u„û(r?æ0ª@R©& @òÚÇ×€  4/²¶£í©úu£^Mù7ûuÅy¸RÕ(ˆsíÝó›™=èâÒÆHBRÅ…€Aà‚Á¥Ü`l¯½>֋현˜¤k;Uª†¶ê¯6ª‰ñMI´MTUTjSZ%)ì1÷Œ¯µ½¶·ïÄí"!ü‡Ñ«Ñìjgö›oæ{ßç…Ú eESjÁ!–IÔJ1Yr¿«›®„U ÖT•,•ǓŪÔÇÊbÒ!E=¦h•’LêÁþ¡“>w¶_o}ä¥X²bT?£é'^?³ *¸— xq48°KÓ#ñTêr¸ Y=ùAW^»×ñÄ>¯IM”‹1˜Š°¬Ö¾˜Çq É!–#˜ÊÐúÛ±°e¶dµ!¿fêu¢zä+²ä h^îdù€YMÄÊGG+’R0)UÿäÝm+ЇòÊ,ÍlŠÚhh)yJ–¾ä‡rDVCº‚äfèÖ¹pAI ÂñBiD—^•âa]­ƒÛOŠ•Š^cŽEbÉRY«LHšyú‹XÍÕk~ún~CdcagCîj?ÏðˆbŠtí<탄ÉðF‚ßç¢HVp;0Ìíñ Žó»0?‰hÆO#ž Áò08B$ÃSre­âí/¬wïü>¿íiÇö§ms¿ÙOþ¸Ðsî\Ss~Ÿ§¹ÐóúNú\‘·iÝø2ÑTÀ6íÉ~k¯p®(»iÝîhßI´ív¿±ËÌcŠÖã»×/?‰^xÖ·n . ÅˆYæõRœ€†<át²$Ãfi.YCq .ÁK<ÎzÆI†"IÒ%ëu"ãIFÀ¨Ç¶5×y|‡£á(~µùŸü¦öÃØÔÀò™(‚=öôà#³Îö.Îô¬ÈôdÍõfÏöÙÒý¶çÁޱîGf®e¥œ—¸ Gnzíã˜ý‰ǧ¿&ç†ùÌe€-Õ³hªK,™îÍúºþ¦:õ-Ýë²@ÒƒƒIÒÝDf(Ûǜ͢#Óíœé]vëJàÀ‹4O;@Ë4–ãs{6ûÂùíñx•t»jL‚´YchÐÄE ‘‚Ò­…¯„á›1£!–]¼XðÔh5Ïx0×JÁÎÖXíóÿîˆ>Zl­n­BNV¨bͽæE:¥‰gÄxÄ0‹?ÿwiyÙ3>Q.àD“Ôæ¼MHþЂFþÛœ>Ünv³$ I[{CÓç)b… ÐÔ’PpýˆÖ”ŒSE ðª2ôðü ŸL¹ ߈íßïê6"5ɉZ]©4ÍJY-—”ÈgŸÕýñO¥Wz^ÿkµ"ŸM$+uóLkëó½”§r=ÈñÛË»”Ø›ŠTš« w粎¥{väÞ¼6Œ2M J Iò1E< ¹×ñhZ}Ñ—Jk)âÎîáƒ[éýé—¾Ë}œts<>ìBË# >ËóX€wù¼´]*¢p–b’ƒñÈ ·¹Öm/ÚHœÛïz?lûÇElò ŸôªÃ\j›X6Û·(Ý»xº?{r[p<àÈ /ïvÝèv< h„ܼ7'›}»byæjÖèûÄì3ÓÏe³f‡ìS½ËAq_Ûÿ‘é>€dªÏ²Ð4ø¤Ï 1ÑoÏ <šéYPI]¶ÏôËøÐ×Zºníb±%òÑ$íàÁ57?…–ªÚ7C¯ŽÇNŽŽÔÈRp!‰‰/‡E½òï7JûºËjËw¸áüJ/›õó÷ãM£JKºÒ(Éwí2î–O¬vR†¤ÑÕ M+‘䯓ÇÖ<ø|¶‡÷3ë¶Ä*07ó"·…Ûæ¬ÐUmû¶üù—ÓêOiÿñÒ ©Q“ÊÆäS´V¢×ªjPOŒTÉò)]ŠÉ ˆ©7Üïê&'ÊL½\ƒ%ñúΖü kp¯‹„†ÓO1[r>¹^¬jûE©þGÖ²w3öÇ|Î &oÖG«?þËñ®·7'¥j]­ƒ9¡$*M-¢+aU?"ßûxDµL3BIñ¡œUÕSI±¡øhDûx½g— &ªMµÂÔª%%(«õ_‘=þ?þw¿Z)$+C:mJâírðRB¬I(g ŸfæII,ð$âu’~R›ŠXe=#€¢T¢(e`«Z ÈjPQÃ}t´#º¹äÄ“[òßñ0u>ãíÞé.ïX?Nu` ’î²§Ú‰) G›k¼Ó–jõμ³"uÞ?iÅ`?Ù‰ÆÛi8Ñ‚M”MŸw¤[°¹vbÎjs¥Ú°T»k¢Ÿi³Í¶ÛgÚ1Cª ¥¢nãëô\¯ã®•S—~èzëöx·%×#а¾¼, áÅÒÄ—SaÑËx–`BŠæóÈ2 šá?g;·×Ù׈ߺäšþ ;3`›°÷/<pü‡ýrmë®âøÄhmÓ$Žkû>|Ÿ¶»M›>Ö¡i´ˆ­eÝPˆµKÓ4ï8NœWÛt-‹Šš8q›†6T!þA š6qÜôb€* „@¬¬LCKãû¾×o_¿.Ç iZ&Z¡]Ýë\ÿrü»÷|¿ŸS¼Ì7ˆ;jwÑ•ðúìݶ5yc“ñóÊâM“6‡'C&ýúã™+˜1g½_ÿ7ýÎ „Mz¸,{½<½°Q—C¦gÑ¢9zܘ7é![ôš=¶‹Ÿ{çÒÞ=µ6Öæ¡X §­$IØï~÷7ßV?Ï7+êII>ÉsŠÔ]èžEáÏ÷‰‰—¡qº÷9Èr’`FÎ×G¤^%®/©—:Zk•û¬zƒnK­0³‘®˜æ…s^mi| :ßÅ8« €DDð‚\.÷°=éQü?Ga%3ÙìêÉ¿#k¹B,«¯?‚  ËÒ A0¨³ßKÜûè x7øZ,ÖGEêSÄ5»à¾¹˜pVüŠÒ!G^•ù~EèÅfèÙeé•X¼•¿×ÍKÞãÇžwºÌ$âtØé’ŒS‚@wmõüþM1íÔÝ»m_¨³:´š`¿¸k‰;ÏÇ”xg„óqBçý+µ 4d¥Ô3¼Øù§÷Î<é®7©vW0HÍÞ>&È%„“ùö¸Øõ°¨`Í}æ{Kµ±ˆ­’Ô`©ª^QlçÄ“²Ú³éD¿ª E¸.AòªZ³ ¶5Á0gqbWDîŒhª< J~Eó>Å¢½RdèÖÜÑñ³Ïªº®gP„EiNì±1NŒfaªŸ]A_¬6­–©xá)º­Þ5ú-v¶™ºsšI\ù1{&H|j!¤gp-hNLb©]ÖäÆˆBIN’ñ–™†{P=ˆæ&)=@eltÆ“Z“Êä ¡NšÓcdqbGt¢ÒÓžô[bÂbc¤*6…䃞Ä8žœ$`µØ8¢É)45cKL™³“tbŠQƒ¥czžC`Ay[«ÎÕòYÍÒW`åêcÒBޱß[±osùr“ #)Ô»A ¤Ãκ)'‹4†Ñ$N’X йa£p0Ìž:´ùòãêÓž.Ú¡Fý¼Ð£)ƒ$šâGš¢Ü(Ìþàð¡Í¿~×§(]ß"Чµø÷®MæºS1¿éIÄz%¡w-hmÚí$«;ëdœA¼xàùDTSÈgÿ$«d’/! Ÿb,âQ|æ€IÏå %ô(‹EøŽÙlÖ(ào (Ž;˜Íêp±ÞÎ/Šd¹ånIì„÷\¨æ½÷À]R’é~XUe©E;d±O”R M>wºoà º½Ããn?¾¯­iK•U;Ü,^÷òÁ]K‘ãñÄ©+³‡8é±ová/]zIT|à­Šx6ªݯ:aÆøÎR©RŸ: vpË烾öŠÛl5,òÄúΚÚ+-ûUîŽF þžÃ#öò<ânUî*ÃÀ~«ªÏ]‘½ eQõ´& Éü 9 G—OÅùÁ„è×x/¯z—–ºç~zäLÇ—ê÷î¤ìŒÙIWÔÚY±!&šbœìЍ!p'† Í2]Ûä+µUÏTL~ÓôKr÷5J.Ù:š¢RAü:Àsdztm—Ÿ´¥¦¬©i$ó&Ÿ"cAJ›À£A<1AÅÇJ$“¸èH\¤ãöøø¦Ä”)3NA‡>êŽ9¯ÃXµQ*6eIÌÑi2;EDß 3t:€òÓ,˜·Cf'˜ü¤+têã4L:`׿o.q}K[rãÖ\bäþŸidHà¸J#ƪ"ñ‹hbÚ{s×½àŽÛƒälS™ï»µ¿Œít›¤²S.Öåq0.»…$I@8œ"1† XØIÌIØjìÖ:þÈ·ûÉ;oáéY´2ë¡™ëåÉkëõú5€ðI~®Â›Œù ÙÅJ=\¦_Ýû…ɸŒWIcÞZ¼ºî¡ãÇ'°Pª2àW¬ÓçÌ|üÀWöà Ba˜v¢ý%$¾È­¹Ô|eê²-³°)³"·`-.ØŒ›U‰¹õºþh¸2·ˆpWvûmf(’¦IЍÄìv7]*¡ñ i@†#Ü k‘…^h4hÀRë‰~Àd²¯Ô’ÜãÕTH ú`.Á)]rÍQî4tè_?<÷Õçª)l}gÃͰWVŠâÐÒÇÍqm(¡õòûø%¯¢œ#çÖÒ?ÒÞ²ÛE$Rítà4…>÷ìó†‘2ŠF>Ÿ›(yÄJdázÅ8Å£ø/c•láJëºñ/)…îõ¶3 …£˜‹vWSh[Ëö{B*Š€ŸŠ¸Ð{oTëÐ.©É`”mür§"·ªò€,·B ²Ô%ËÐ}ïÝ3$†mߊÜþ]›&·÷~{û(e·°ÄVÁßÿKÏ7ÇÕ #ç>Q»î­7Dñ5Nl‰E{U©OàZï››Ë P˜À·Šʉh¼ÿoùŸ~ÒYCma 34øÈ«ßà俍tVáלMV‚ú•$Žšê×”Sð¸%Á)Fz$¾§¤ŠP°4d >P˨e´WT½g¿ÌbÛ8Î8þR´6lI´Hî.÷>È¥ä#uš(I›ôHÄ~háiRqàIœØ’eÔ­*vë 1j‹\î’rH/ qб.JJ 4})Æ/ŠºEêÀ’x,¹ËkÉ]rÉí'+̓!-Ã/| †ƒåÇ™™ÿÿ÷­gºÕ\&9ùÎR÷ô™ƒOê r(Oxv7Ó‚Àð,ÂRþN6ıÝÞÖ/3žïÜÍ8øÀ¥£í qÉóûêñ½¶Ìš¼•i¯%û™°%_5ŒT¢Þ’ìÕw~Æ›‹{¶2wàcÚWž&(UŽ3…YœáŠqÁ”p+B6£¬#ñ¶ÌWF“ñLœ¨I­Æ4jÉûTà/*2[ ûíkÇÉbÜÈ‘—E5&Vföé2 cÇq3Š™ÆŒpÕ0oI|S%X“èB1dÌŠµ0d¦U>‘F6hd3jŠ0@8F/GQHhÄPÐHÁ‹ uí—æ^>Ì~ˆÿJ€„×ËQ,dI‘¡G8ÂÏ `β,As$Iv‰èñGÐß±¾ºÏ^ÜÙL¸ìÒHàµy´¶ài®xê‰û>g–rXglÎ{í««¥üàg7ÏÑ\6”χҩ^pvU;©ú.½þ\ÀÇ€„Eé¿]é…AM½íøqSÀþn&èa&5¬¦‡³ê 츖š,d't5¤gO©™z®Ê´äzO:;´šì}ïýgñëÇ¿´kÿŽ'I‘¦ü¼@(æk÷ûyQè Îù÷Á€x €?ý5òÜSä[SÂjL((+ÖfÉm–â©ÆpC¡KkHBM›ñNCfK]ŒPÀ fŒµd¢®léòå¨PØá`í_W(ŒjÄg†i;ê©ÊH^!r ]P(3âuη8Ó;›I œÒŒßˆ`uÀ•È+BÙoH@ju¦Y{šÓ£„ƒ„˜#a…8$AK1˜avÊ2Y”ðbË…ù \¹€Ty‰3£< Õ'âÇflZ ­Gè’Â[3"DUáŒ(S•`É\-¼Ë {j2mÅ€šü0nFiXÚßÏ"s'Ý/=æyò~ßÝ,.´Ÿâü$#ú˜ Îú 0PàEFpžEâÀ—Ú&+çØü¤³Øî,ì¬Î·—i;á1íåWi±ÕH´Tç]ö,â̳·?n {µ—Zí•]Õ¹˜}n{s¥=óþ[](B3Ëuø:~zwþêÍý¡ÕÙ:uy[3ái,ºyŸó;Ì™ÝÕXòçÅ[=ç2m^þœ³ŒVߨ^Küü«÷ˆPòÑ´_¤¨ Žl?túàßÇ Ú; ( 6‘ª ¸¡jz,µ6©i’›MÀcpg“™î\~,•™ø`mü‘‡ƒpDò9ÊÅùðNÁ;9ѵ“׳/´1M ­¯uëzÿV:IukzšêÿåæÌ>ŽCiš 6í‰]Ûà¨^?þ¼Óî´OÙêÈÎæIö‘hÀ²ø`ï}É䄚Ð3§‹Å¸Ðß@mB×>2ß[í’ºÚ¯gÇÖ×&Ͻüе듫é!­8ü¯«ãZ¶¬ó'g»ÊGùÄñ>šSG «ã…µç‹úÙ±ÉG’ã ÏÒâÑ‚6’Ïç´ã-¯M¦’§òZ¨¤OrS©ëŸÕ<ÕÔ žÌ`âð~ÀÓ¡“R_Ȩ£G¿W¤™NA­øÞc÷' ?H«·žâþï€W»‚Ê ÔO×s¹“P å³ƒ `°:G55‘JN­®M¾ûî±—žøî7÷w’8‹’Í1 EÓ8Í`,†ÆÒ(Cu¾Gw»Æ ¯?üÇ™öd˜*¼Âæãx!†—bt!Ê›±ÝÕ˜ßýÐ/ÈByÆ_³†ŒÄšFjaÔ–+BšaÒŒ0Õ0[ ó[¹¼aëJБ„Æy¬.y­¨ÛŽ"NŒÙÈó•¬Ç+Ù‚Âé€Pgù|¢—ŠõýøŒ4@RË”{ñ”ߪù©È©"±§Xö%ý|ÆoOžäÓn[Ö猹s«éýÄt?5í›7å!K$üdð4ç~q—ñ'^G±‹Jx¨d?’<ÅMð‡KÿPƒß¬%nV㬶ÞjÄtrŠ× ,Õ¼4ð€á7Mv/Éú¨˜—’=ÖÄéëü,<’¤—Lù¨´ŸNø)ÝCÂRq?£úÈx€šôÓS|ò$’t#q9ÑKAÅÝæ¨»`"`IõcÙST¶Ot[cýÈŸ:_÷½øðâPÆA°… G9]´]ÀqDJÀMÅ òõ•¥þrôÃ>F°CyÆ•BcOšõÑ/Î9~W‘L&á™Édàvu´µý Ï….Ù²‰ºw§ ´)8V+ɇr ®MÃ59\—FµGLòdUR«/ür»‹±ÚÙ"†ä¾»m%/´£Ž—–Üþ{S8صv9jcì,Å®YëÜÒÙñÍRêàm6š®¯|Y6kZuH)«Šé‡¦ ~ÈœËËeÖêW•J)Ø ‡š¹V’ª¤p£nãŠIMáðþúºu%%´ÕIJ$¹öKÈxøí9ÇÇ LY4Z¯ª50¯ÔH³"•Æ(ë ç/¼ºwwñše,Ì|³³ÇÒB9|)bãp{!¶ÚjÚ÷êßËþ­Ùí·k>$áE ¿3yœËvóF€Iw[Ò^x#î±ä €gúéL 0²ûJ+ÖãQθÑhOd¢Ï÷šLÖƒMýW¾?›ñ>2áÍOy«=Žsû¬oo£+6Zv¾8ﯠ¯®Â–ó¦RÙ´œ¨ÝˆœÛ‡þõ3(I¦OXõ^tßðó÷{ë±¼¥˜µˆ0ï^‰H'É^f"àSû_¤pš&hŽ„©O1^–v ¤KÀ:^1_­”ž¢L/?Y€8{ÿ¿h$$'éT7“öÐY;ég 3^2íß ñíá"=6¥×1ÑëLø¸”›šîY`ôfzð ­{hÝM$ÜHÖDý¨î1gÖÌ)졹ÚÌþ¿eU„ÎEÐÝ$%М‹cm,Ž:i‹‰À¡}¾±Ì~du³Ï’^l /2.™æ?ËÌÐâÔ`aæªÕDŒ¡‚ñ‹BCIX, ‹Ñ¾k=¼¶(þ+“q£pz(/u…q©kDr /s=ÿLcÁFW¡¯•y8²ÀxßöÄë.œüpqrp!œ­1‚ů™ `cøÙȵ•Çw—®æx›/pÅÐ_v6ÿ§?+{p¿í”Ç*¢JÅÝ»5›7-a‰°<ŽýäÔΈØëÆÆkß=³“Çx–dœœéÓ{5í„$µªúî°øýˆ:³ [aæ«ò!9Ô¨(•ŸÜ©Ú¼-áì,IÓ8 7¿ª¢ôb2“ͦ3s­`OãsÙl®Ö¹³?¡I è—¶8¶¾"ܹÛ&†êcZsh¼\×J‘E‚7@ìÐÕš¸^ (¢*MO\%#»díHûÑõãÀpžaŠÌ{Þ^týF¹ª×ÈRͯ?(c10fšXÂ. ƒ¬€½lXçTõÖðXƒ¢¾%I]`7BRyX®P£M¡pCXl”¤fQl™½R߉Ê?PäªHdŸm}G 6Aƒß;d(-eH†Ç‰c]æ?Ëÿ°_¦±QœgÔ+€Ûx™wî™Ýµ×6ˆ„4"Ž€(mC”BEIÛ„ª!-Æ'>°M•#xÙÛFmÓªA=¢”ËØÆUùPE­RµR¥ë¹÷Þ½¦KÕ~©? øÂ«W£wf4ï;óÌó>ÿß_‘¢ú€¢t‚ƒ¿¹5zöýWûÛ…f§»–âjÀy4ð*Çq$M3WGÖÔ#vc-ÑûUúô#Ĩà©Îèä8G#ˆR¾ªì {júQb‚Œ…Èxʆx#Àe½Ì¢òg’~רs~»á³eýØ¢d˜!åEF€Y÷ `Ì °K©|ÖçJ{ì…0ÿþ­uUõ"'Å:qF 9"I (¤B,NÝÛ÷ª…x&x6LA ²^!ç«[|ÄËf`ìç ¤Å€µäG…w¨›žÚ_¾mëØh{¦†$‘ßÈp–Bõ,æ ¢X‚ip1Î õ·­øÝ»K«ùCêÙÙŠÂSº´²xÔ|ŵ½ÎbµXá .„~3‰§¦-&(þ–øõŠçñ¥çÁÍ«I¿b÷¿±†²!9Û7Vç©ýþæôJó eÎéKe±¹²ü,VšFÆYÜœZž¸Â¼{¨ÞÍ „q<Ë?°¨îð賑GUyÜ®÷ªò ,EÕ}¢Ú­ÊCòí¡¸ÜUÛ#wöu·oâÉZ°9'ö±W—õHßï¯õ®©±mò4¹êfñ&žÞ7Ð5*¹¢/éÂDµÈGW4y§,vêêž\?òÂsô]xCîäOßÕXìÚ£v/­Tú_Ò …»ƒ\.g˜¦Q0‹¹âÔgxœæé ž· ¼ñµ—+þöÇ‘DlLÓz4$DjhùA«aTÝ­€|‹°h+(».(‘1UQ¤®å­ë7G›œÇÐŒÂøÀä+’´v(IÑÝ?ÿõµ5¬Ýåà› Ÿj°=øüBd,í‘¥š²K–ÊË ôZ¿ªí x¾â1³»X–¬khüû'²:¢EßV¤( ªØfD×vÞ·¥¥6]íÖ”0V’´G–ÇÄ}’t0¥ êwzâD{AÞ-Ç©;éPbm²Þ-Š{¯ÎwwmߨTËÑC¢x’¤ ŒgP K:pK#ohnøá·-ß ¹2>+°DÚG¤ÆI3ì4}Ö´§:ÔbG­… ž  Ô¤3î«M„Í#öd˜ÉY)Lg}TÁKk~&ïç u.TG¹ÜÅŠ‡°œŠ]9À\¤ü¦mïVöµa­ÓòQ¿-áã“~&ÆM›õ4Dà¢ÓN PÉI«ï’g\$Í9iŒ³Õ5¹¬ â­d3él XE‘Í‚ÛüŒó·cÓËeV=d… ·~Ñ-°¤Ð×Ös¥q{Ö /¥ÇÑÖ–:7ŽÑBFÃßêpÛñÕ´ §ÈU6„  Y/0„Øxy>ÍÏæƒLÆ‹[Þ‹2>.îw¥ÃOAd’ãl.d…påµc©ŸVf¯Š8’DˆJ…ìp%ÂR~WÖË‚δ‡9sA>á¥Ò€daaI*[¢ÃÈz­é ññóƒìðû¦f‹@Uóœ“ÅII¸áÄA“NŽ˜Ÿ[Mx;œÿ<É™gÊÍY[ašHΣè‡U™ùÏd§ž(#Ìi¢0³¼8÷YóÂæ9,=_–¹P•›µ–æ,Źrcn…1_‘¾xÿÔüÂcÉKTé4nÎU‰Óì–g«,ŒÃÁØkìνoX¤sæÅ²üiTš'ŒùÏ™óUKÍSšcR³Èœ/ßÒâ H«‹^÷Ý2s¹2=KšW>_šyܘâ²S¸9³Ì¼dÍMY‹ÓLé‚=?Wž™]–»X™›·efV.Z —åg*òçmæ¬Ý8_ž»Pi^&23Ä=SÖ [˜±˜Wª®M4¯wÛä&Ë8ÁMQ«:ÚÖéJLëÅáO#£Š6 L’PÇà"l^]ùž(vhñÖÛ·ìnÛ<¸s£¬mO!*W¯m[ÝØÌ#¢ÞI`_Þ´šÂËê7‡qÛß|ZRöjz«®u*J·,õo,H]`ÓT½WVÝ¥"÷C‡â×l.DvÝþ´ó¥/¹æqÊæ¦›¢ðS§QÊÍü"“‹EP™ÿAeJ¥Bé©]û¤çP5K"ù±_¦±Qœg¯zˆ#v|ì1÷½‡½Æ8ÑB"¢RÒ A¤’ ’ víøÛ¤ Ií]ÏìaC›H4TJJˆ±×k{–‡&UÒHU?’0öîìîì9{¯§‰J¥J|@¢¢RóêÑjv5ó¾3³3Ïï÷g­iaQÓ¯žgÓnf^¤S" “ç$3Ð_uU;’—ÌꈠzŒâL -4+˜(¤å‘Žl[äÜ^þóQ{3¬g×qeFX3ƒëö¬\tpi'œ^²ly%q¤†¤7¯1i"™…òP HO6ÕÀ?‡!讵TÈýPzX:J]8ØØö„E®š6Z™š®õBÄÓPr±9§1å2&D"%y7•“8ϼ›Q†ü>éa2G¹”“R%*%’ " •6ƒºdD¤è¢æ%6gÇs¢1ïAÁ…rÇðô0’õ§±è!Kž@ îÔFb"£JdÑjn¤~(Yo¼¹ü//ÙìÛ„¬Ô3ŒAdP ^mÃ+αÎxâCàäýš¯27n,Stí,Sœ òg°’/øuêùû c¨6 ª`ÔÆ ¥qÍËi>J×ß-)#šÏN,ÒÆÊwA³BÚhâk×™ÿùäÊâïø]ó£ÉѲ”17¾ä¶óx+çÏéfÞ]\C`„€›xnà'÷©“ØEÂkTÏPÚ¢ù+s©SmŒÉûË3pÈ¥ùØÂ(\/ZšÄá>§ué1}ÑG¤ÏT|mŠMžª,LVܱey©‚ï©3Hòyá¸móªz3mÂÎBÖr²a{ùóþLô`2´#,¿Œ´çöÞLXñè!%Òu#¸CÍô„äŸFƒYi¿x©åáFèçK˜—7PÓS­×‚}þس|9ÊÜ2žù퉶Àl7ĽHpDë€z1ª,´Ü¹¹ž[6òï<%w‚\¾òê÷[aá«­¦:ÔHñ<ý›÷Þ„” ÷Ëœ p) ›ÒíPôÕøÿ_>'0r¹Ü­¯Ùlž˜ÿt‰ã(–á HZh[£­ú“Ϻ“ñCàAyW,œzQ ÷‚$'w’·©h´¡#ê•çz³ñXw$ÖRZ”xo Ô1ð³MõlYOëæG› IB/úvuíï¯äv9Ô3zú©Ù™Ã¡hs8Ú:nÇE·Ç¢=‰h(Ð¥Èî•„"í@ÂJG Ü61ñ<‹U[˜Fg¥‘‰‰aåèsàVwÄ"¯Ý­u¡ŸÀåÇ¢]J¸=,FÀ|:gã-Jª7î¿1ÛuþãúÁãoí|òQK-Âð8Æó¨™'¬a2Ðf¦(«@¢;¯yw_Í•W‰¢¤×† Y'q0y§1çÐ N> @wqÅ"=T¦ŒTņu©a$å6ľ™•èÜ™<ª‹;Ë N49‚âå_X®a?9L©#hÎmÍÛõ‰côÜ ·qyF‘M24KèÉXY q@}š@y?òŒ)íÁ5•p˜`*𜴇L»”ɉ<°>1dðlÓ38K1¼‰ÆÏ÷‘²„my©!õ¶ðùH´ÛlCÊH®N±ËŒKÝnK qQ{yZ¬ûñŒa(o~¢ÉZt2i‘P] ÚÓ ºŒ4/Ûº¶,ì©…³Í ;¤Àâ¹:†@¸«¾p2%;¢9±ð—tÓ ›”UÔçÅÊœ£ª4L¨N¼xT§Ú±’«² –k..3P–·Ãn:P‘ü ¡¾D¡(™T‘t" +I‘MIÌBy è˜„.(ÜÚHÒeʸ˜¬dÌ Víš×`¹7±¸›Kü•×,oï´lZÅÓ,båñ ¾ž`q¯(E-@ÆæMúñ×É, sjiÂ_©ú…)}q¢:çÕe§‘ùÑÊâhUqL7ïC `£tæ~Í[u·ldþ´I›^\ò¯½¯ûÏ™ ¥g ¼Ô¼8ê´se¹–hSºŒ¯¢4iÆÛÍS­(ùª. ƒZiÁFáÈGoUýhzŒÖÎ/Í{‘è)‹<¦ù°‚š÷- W1Ihcdñƒ m²\›Z”ýº6]•Eµi>ë՗Ε秗&OÃn`,èÛÈø75¿)åýVé,–ò•]óÖo]k!\ pSËsÂúµ¦/.·&ƒT¥;Ùá^ä°ÜÉ%=0'ï!Q»!Ë\ŸiõŸmYÝh¦Œ¸‰àWÔ°.mW”]‘hÿõdËÆ§X[Éáú7?ë z +B{!¼f¢„öC,ºe#ÿá$²ÜõjßÊz—›Ø:ŽæxÿôÓµy­[ˆ·™LæqŠóó÷w_ÿõQ¼9`CUUí_Bò×Ï>z°~5„žgYŠ_Ñ€ž;Ûõ+JG8¼T$i¿ ʹ¶PhßÚÁ¶XdÁ…fg:ã‰þë³°èëÓ{Z›×Ÿ8ñÃ3{7ùŒî¿xñÙ¦úFj™º —Ÿ<µåÙ§75Ðì‡ï? íË=ÑxW@n“CðÎö…‚=ð oœ<×q¯lBG0ÐUº¡f ÿ Ï­bQ‚X†™·omš™{9…Ý:•Ènè ±ÈËwoi˜³ ––oÞXè9‘@·Ü}ö¥¤Ò›éøƒwWËsëÌp4Ú=³úö|gÎ|ßùÿ>}¯oßVùZ+ö«.2#ë4ŠËRÌg\ÕkËzˆ´”šH»©÷÷p6¤'±Ôå>"3¡×œti¥º‚¹ñ†tº1ÏJ6éw>bÍúê2rmÊ‹ZfÀ8ši¶¢”Á3¦<@gÒ!ŠD¹gËš¨lËÔæd*=Î\]ÏcëêÛscÊ$SpU妨ËÒŸrR 7——ÒnSA®ÉNðËr“êjT=(ù›7$GkŠ.!ãij2•)ຜ̔K:!Æ\u±Qª X”O0–qP©1&ãr.ËÝÒHÆE'\ÀUؼ슇[‘…˜GÒÜÆœ‡(¿J§1ædþ~¢ÉÑjûn=fåDh-´h¬VŠ“Ísä¶fÊÓAöNuiæÁübmjËÎÚ¹*mƨ-ò • ©Éùšì’)¿¨Ë.PZÒ]_”zvYy–æÐ:‰àë8Ë#›7,þnŸß?˜ õ…‡Ëm-2¸ºµáÀu¸¼ÍÊ­Áp´óÄðVžÆÌ”ý›VâWö«êÞ¨r(¨t½ur‰ü†À‹‡_ü°-y^U÷)Á®pp | o ÀaPQ~üßrH`ºh¤f¹téùFdL8FS$ÝÔÔð·¿~ @¢KðyGhîÛ}ûŸVZ5pòùümÌõë×›ëͲ1„ (·¾¡æÊïû`цƒ½‘ð™êõ_U»¿lÕŽEûý7{ü·ú"ÑCp÷?®i{¶ÉLV‹Fë»oïU”—¢áÁÀ!Eyõ×§Ÿéµe±Ö‹¬ÀᎯxŒ1žr²Ùš]¯É¢æ“'ÒÆkWF°ŒGiôJ­[Ä&d²ãMЀ”u,÷ñ0 [r!U6òö|I„dÅ+¢æð“èƒvüÓ!:ê°Á˜”ƒLù,Q^t×À-zRÆHJ#挌§TÒK½âüÞL#D "¢N¿Øôá¹*çe2.©8jלlv”ÜÄÔ"‚`EÁL@d>-b.bÏ&Ñ ‰ƒPáq“’FÌ© –%LK#Ò´»Y¿Ô[ÿÛ~j©Ÿz¿Ã²»Å`çX‚3KtcÿwTÇm)¯>î®-º©œÏ‘é11=ÑI¦]ÆO‡m£OSŸ3\î4ø½ôŠ—O;¥ä0SônP=dòm11bÈ8 ±IÆïcc4›v– ®'A2^6+3…q8çni$¿JGq7•ô±Ø#é¨-xM‘q*)›Š.cÉAdLÎ#f=`ÛåAâÍïOÔó<^® ‹“²›h„qÐúCÁÎy#e«ç—ž¹l÷+?RcÝþàA¨ÿgž§$±‘0ñ"‡Dʲý±úO®^RãýÑðPp¹+ØQ÷ÇÝ¡PgÀßuUþn/˜:¶2ZZ¾qD‰ôDã/½~âIÞˆÓ&–G›ÉO®v9”3T_„3Ƚš,é (ûB‘E …N\Xêê9؈pœpËÒ Ë”¿xžªcpëV‹áøØ¿@›òc„σR.<5Æ¥e!9ÎÇ}(æ!à—ÜVÁrc(ïŠ^)ïfrNƒæÅóã”2†…O2Ao˵cöÂÏë’®u97žpò*ŒñTe=Äf[-ÉèEÁBŠ Íð""Þë0¦GLEo]Ü'&dJÞų„dçÉŒá7]S>³*W¯œÄr>}ÉMÄß2¨èEŸ0ApÈ-á#Joб³_ç±Q\wÀQ‹ŒZ ^ï1ç›ûØ]Ÿ Τ¡4©¤©PR·BJ¢âµ(@¨’õÞkÓ¤N©´mñ²6P£ªÿ´iÕ?* jØÞÝ™Ù{½'ž¾µ¥*jÄH þÃÓhþ˜™÷æÍû~~.KÑËädáCáÚ &8ÇÈ<œ{ÐðÇ\Ñ=@¥C ÏPP#:<<>|Ö ÃV~©ã \& ™šyÁp‚h2Òr# . ÕÅDÜ–´ŸÔˆ7ÝŠ.1å¶¥j`¼]^ª,p¨éªOßo>¼}å*Þb­ç¶5Õþ²ÕxË-–@÷A‘ Ÿ‡tÞQ=ï7æhÉE<$½´×’𛓣ˆ¨}X<•}Æ à5’óƒœ˹-÷]4„SÁ‹Fñt¹„‡Ì„œƒ8̸ —®Ø¿ÕdgÑÊ{N@ –f$H[V¡Þý5·Î™³!¬0‰B5åP•~e™ªž¿ˆè—¤G¥‘TŸ -}k‡@J¢dš5½¶-\7Î]øš>U;… téRmqÂP"TÍ•e['›D~™ˆ2ç†ðð8÷G‡øLs­1’eÙ†FZr´1¹ë¬~¹pbýžÕË­ÄÊ­f+êIl "ßµòæ¯êSSÆìøJ=ÊÁZ}ÊTš@¶_¥+•A»É0?iÈ¿^²úEQ_zçºxj`cjy†&ˆ‰F}abDéˆ%ºïN¿]B¬.›1µ *%®öÜû¼;‘é‰ ONíÕýÊìQ臱Ÿ¿ÔÄ6ÒfÖžÏ?k½3}xzº?ìýìo?úõ÷>w©Z¿¢½¡ªmImP ÷@~,^ù¿YÜ4¥C C“À\èÿ}K#/㦫 1$õâw¶gRéùòýÿ1É“ö¤}¹‹E}a†À–L&wî܉ãxE¶xµ¯úY EÓ†RéŽðtœÒ‰xÿâ„ ÏvªÊAH‘Tò'Pà=¸•¶˜Ús9–8ýÉ÷$`¡ÃÉ“-w£ÝjêØÇc»zrרé-ÉÌÐÌlwLí<á@g|k3[l˜+ŒØ2.6ë$õQ!ï&J^âa52çÄŠ^°:³#Ö¸_V¼"|›¿‚àtsE/ Ù5¥ùÉ´ÏósÉÑ&8 î»ñðûôÙ·¸—× ˆ€±“ÀŽ#"Š4YòdðU"ä’"S\þª©xÿ-ЃýêW•FŠA2è`¡‰àY“Tßü5¥_\^ºlÎO¬˜¿L•ƒd)´\Ÿ²”'Èâ¤ééuÉ1ªm8bLS£´£‡[ƒdFbòô¶§7NqúÄRmœë} «ÃxX;À鈳Jó$k£Ych†>kÿêÙ!"sÍžŸX>wa™>A”'¹‡íW>T3¥J¡ÅKxùš!Z¡ObúET×ñÓ'¬vÌlåL4jj”8Š9÷‹ܽ3A¢D»aå×:”èậ†û#ÓÝqõHT­T7÷Â"ZÛ¹³- °ðX©º[¤[·zÔXíU¢o‡&÷‰ô’§š ¯ë¥é™|áø½;•UÂC=´H‘/j$ªµ¥SƒÊ,dO/¬ROòB=Ãpd-ü4xšÝ¶ek1_€)K‹ yÒž´/·/2µ\.÷õõÁóȧ=L% ëÓÿ.A™Ç VX&c½ÉÀÁ½L¬`â(i£qÁ½“Œ¹©¹ ›ð1éýž‹ì~ß²~íz¤ÛÑ€;·jÞ ø¤ ³>~ÎG|‹SˆÅ/°kÄÜyü‡+$X@ÙËäƒL?8)õ<­{”ÁXÚŽ uF–chdf$žêhì{¬þe'•ãÔw´…±•…QêÓ¢uü+Õ‰&ÂjGA¡—$`zÏÜ\‘Ÿ"Š“Ú…·V©úòˆf~R“ÇþßuŠ#ä/zyŽD3™7mţ޿m·^$W{k+ã˜:¾L5“ à <üÃw ¬2! ¤•Ì$fÿK¼á$ “„zsueB \´ä皪*þZ[«Z¸Q!òSÚÂÛ+3Sõª~ázUò÷“³k,”ÉÄ­apM-ÁÙp€dÚh¤#•h„3J/4_ÙÜ¡Èì3 —<Û‘Îv||·y­…F<¤L?ý$÷ÑGÇ@…àäx´M‘{Fn±"BÔ7H”Áq´öΞD²SŽü?îÅ'zM6΄Ž(W\îm Ë­?ûé. «åh¨a˜¤¥ùh¥<¯‰|N#Ÿù±°ð¿k`$—/Á'D›Ã ’( Þ‚¾äh~hfúL6wjfº9›ì•CŽ”â¼ßîö†C­©T»錅O…Ç¢‰cñ%vX‘€¥õÅýõ&š#Ë‹f£(R‚(VÑ4ÍRV3"ß}·u‘š–JÑ“rØ¥D]‰xÜ%*C8bQg"Þ/u¸dªQûè’Ÿý¸O¼tmoÐY) <àÕ¨µp&Ž·!‚ßRCyÐÿø^¹õ zM¯^cÕÃüäÊ_-Òå ®p£z~¼Z4ÌßÀŠã†ÒYà £Uê­^_Vú&>!Vn>?æÆ(uòWšŽ”“‰¢…uÖåñ7–«StîúŠ¥ºê-αËÈ’"XE‹˜]B5S½gó²?ê‹S+Kã6u¤Êl'’VLO™kܶmq¹½^]#n¾jlú:m§p‰ŒÄÖbìí¡*õ*\åÓ“ÆO‹¾r£Õê V~[ûÇŸoyÜF"Ö¢ãH‘-HwéÒv%ÙZ„TKr¦W‘›QG,âHÆ[ã‰Fh*ãòéË?þ†@“ µ«¦ï@SÙøû?¼ðܳOí|vCÏ™'>œnžŽ´žy¤Fâpâå³ÏÌ*®xò€ êȤà‚íÐ@Å¢­±¸3–l…ŒÇ:@9ÓiJÏÌ?Ov:aS°u@Îuµµ€ÏË弨T*Ýó¦ øÐçã36Êåòo}±XP­,VEáÊå+VQ‚¾êz™¶–†Ð´0`zöp*é Ï8²©n¨çûíÂPÏᙨvE9˜Íºfgºåhûû·_èqnM¥ÜÓ‘¶7¯4ñ”ÖÊ®õ®¡-ë×TwÞøýOI¼ÝÂÑc{¢Ñ¦%SÜ–Nu)±¶{Ǹr¼>¡´$•cr,þØÌtc2Ù&ˇåXëý^„[ï4Yy’Âh11ÄòÉ›?ˆ)Ç*ÁI9›í°Ç¿á¦Ç¡¦LÚúÉÃãÄäã1Ù•ˆL%rÌÍÆœïOí;¸oN!Q¨åÎÆ’6\o%˜MâŠÓÏ™ÿtNº²Ãä|¯¸©R‹É `I/Sô³¯•ÁEKÍ»MY[öbÿb¿Üc›ºî8^m]¡ ı}¯ïûÜsﵯ¯c'„× -eVèc¥b]µ† Ú²i-Ò@È“GIG×Ñ4‰ÛIXÚ­Ý´µÕ´" ‰kÙdƒµU['µeHÄo_'Žíøuw¼Hlÿ"•¶]]{tž¿ûû~¾¹¬ÐÇ\¦lwU¡O¸|´òø¶¶Z·ŽºãJ;ã-›s™‹nîïbµ€Ìc%%êm Ò[ÉR%¯¿Ð.i}Vµ ´8Öj†¬läöÕÒñgÌk!Ïð`¬é)Pج Ìx•‡ªò<ÔȤTÃ3¨›È‚¶2ú*ö®_¢gÝ0Ö-ìXS&›ðjÞ"3F±”Å/^­žäÒN "˜áI*ÛWá‰ÓL>ï®Ôºav€™ê'>VxÜ,T“ß¶ILôSE§ð°O¯&,hŽ•Y[ÒÍÆ{‘úÓ& ^ X’µ&­†z”mßdDx–_#Ü3~Ä<×ÅÈd7«¹°¹cÍiBºŸqâÙNIõâsnSâ8÷dl+ÛÖE=b¡›(tÒi¯8ø#Z¢È"‰Ÿ|¤½Ë =bÄ¥?ÛÂ.Ç6ÒÝ߇?~tIr8¦Æ'6è}xڅͺk´×¥_>…ï7é`W¥æ¦ %û@È)h}K¢^Yí´'ûj"^8í¡cn£ÚO÷3.2åbr}h.òVi$ÔÇ"øÔœŠæ±„»8_+Wÿ·˜X©0˜™¦(B‰•)|“BÞJ_}›Ó%ÿH$F`ö,W8§Ë”iC:ÍOF*2C r¾{Š~CqÏaÚ®ùHÔžö-Êž3¥†b˜¢_üÇÛüý6HZ°]Ü{/ÓgéÂÉ……[Wÿ´{ùiZA±aµà,ºk›ÃXöZ=<· }Ê–eý\à÷ÂãÑdwÀJH2?Ù|ç?ßç‹£d~Ë’ªÏÅßê`“‰eS^xdŠ8ê¬è_øeшöÔ† èLÒÃøìŸ¤ñß=°Ö^.2€—Dš08Xæ•ö-ñÔΉà®`xŸnOÄ„&[ÔÈ¡X¸9+Cpª ɃÏ}x±-8ñò…ñ'-ŒÉfeq=fã«×­²]¯»>Ñìrn¶[,µW£ÑHWš{î9÷þÿ¿=>>þ2!×þÎ&U+$Ù¦¦¯Æ²?ŒÄÚ’±WcŸ½öñ½æ‹?Ù´wOƒ©jÑöÚñgÆÆ\©Ä±…®›JÍõ ø6%Gcº ß)Œ4˜óã:†¢ædÌõàÞ‰ÌÑèx[*zbì^ëÃÎC6qìÃö×ר±3*šC¢÷ÜúT¼ËH:Ý6[Ü…ãLƱÖ£û⑎˜Þ’L4âEÆ\‘íFǃè.]?õ濽ñ¹zM!-hb­C©eXA¦d‡ÀîZG޾BNôZ'¼åi·Í Ã[c”lKAÆŒ€4åå&ÏÛL7iº¥L7LûYó -ëátxû„3°[Jú,Ù¾åy·Õì­üÈËq,Åóõ’P½¶Éø”¸Ìú(£»æGÏ @¦–V¹ÚÞïÕr’ ”DÕ¾¾ó &™ŠÞ<’(ˆ#›k2n°R¦U$J<·®(xÔ\`›Ãñto,”°¯=!°‡–åÌ´Üd®»Ûè޳‹˜é#’gÊ.íÑö~ƒyõùåž—ÀûÔõc䬻¬à·^zý—‘ŠA‡¯xÊápoçm 7­TWÍaêT@´Õ­P+{^²LûeÃÃëîŠT·ý …ã5LH"‹&ÞrnÛtPy¯A§Fa¶AìÙm4¶u³FzÑ7kìuðˆVYûp+œKc%ýbú‚çpÂr^TpÓI/] v õx #ÖÛû‘ч©O˜t×ÍöZÿr`gá8Z@üÙ-ÖÉPCö¢ý¯çÐåæŠÀ6Õ¿MìÚDþ¶ƒùûIbC*ʲÆQ7›ø™3²Ù§\l—Ò˜9-/ulUŸt–892ò‡=£Îe3Èd»S^&ž3}.¢á[ÎèL\ýÒÈ”GÊ™Ü[¶—L¸Ñd·dúi3¸$ÞƒböpëU„,¼^`ì’iNaÀJ$ºž•>¾ÍëdñòÜÀ’ü““ù01®2•¹aëÔe S¹péìˆÍ`Ì[aðsæ¨ríL‰0@ÒdºªV$ov©ù!K!LL¢ÙwËêò¹+´yµÒ)ûcŸòÓ¶Gõ«Öé!ëì a¾ÍšWéâHÕôª-k(¬D¢ƒ€í÷>Âx¦KsïÚÍkD!üÈ̈-u…0†Ë/u@' $ÙúõÔµ>65$™#Ü‹FrýUSáGÌQjæ20‡*f®}¡pÃñ·Ÿ/ßø” ‰Mv2”(µiߺH¦eìß}ÖD¶}ìÁD¬=¦Å’ŽÅ-‘lß—ˆ7¥2íÛ6®’ŒÕÄ?>=¥Ç›7®Ô€­ÎÉ<½AÁª™[×ãx*ÙõùþݳñÃÉh«>vKtT?0×%Û±nãŸc ™}üÈ»mO¯•yVb(rE½zûÏ·ç hžCðÈçóÿaRÿÿ £P(Ì}þ¥–Ö FÔXme óþo\±t>·é>´#ㇱL#ñXk2yða»pü³¶L¢/—HD["º+}]¿¤ùðRŽY¬@Yb °5–:8g¾úÞá‘ïk€ä+êêÑòÆ=«ÜïÊMµécº.†y¼Slîú8ÆûÖ4î¢-˜Äp/€?0¥dÒQ^ÆM¾ziýäÃÎCb¬S‡7°†CâÎ,SÐ'Ÿtâ[£J$šç"Œ¸Rñã˜I°°¤âGâúáH¤)k6¦2'îÞ9õ‹Ÿm{òq»&Zx‰´CfTÈR4gANp왪?T'ü\ÊcŸ ñÅ&ç·'0T’!.²gü¦`øDÃ'§‚ ëå‹î23P‰¬¿Ik\4UÍQ·\öDh©á³Lw—â÷Î5P€,b9á§gk³þŠ©^hœW‡)«X%Â2Òqr8÷b¶ò "?hW¦Cäéç €lÃÞYg˜­_Á¶DÀ¨sç´³èG“^«Â€‚$‡­â­}R:Db—Ï„¼Æ}+²~­àå>dz©™¢È©€lv}>wMö*¦ÛZôðYüüjY¥‘$„¨U³%ˆƒ’øâdB&h¥Ì"T®ÈÞ™ä…*óWèeñƒsµóqh‘Š·É´-{AÌyKð~G]ƒ–9Õ›Q¾Gȹ)ýÍÊ·öVK€e’çm»V[R~húk /‹Ý9ãV'&º¢—Íx™É¼Ñ©8IÄ#R»×Á1ŸfúhÓ#$ƒZçvVåD+5ðâHsùT4ØY·ñ>èd^xŒqZ-[ÇŠNšgéÊ/AñÀ·Ðu¯µp‹›]\*´›aÃ@a öšã{g/_ v¸›Ð¤MB®K"Ü ˜4±ñ}ƒc“&b¼÷§MkªöC$Ž`Ì•Ej¥|i*!%j(ÆöÎìììÎz{mïô5HùŽÚÍ£Õ£™ÑŽæ™gÞ÷ÿÿ=ô±« |=OÊRÇóÔË9êù§¾+‰ÝÒ¤n.ÿ¡zN]Ö%†òâ#ÙéñœÉ[ö}›JQjI¾²UUl¸lœI´L §Äƒñx ’h¤K6G亰ü–0Ù ¶üþy–BÌðéJ9ºgRlêhÛÆc,°mÞ”?ùàhl¦fJxWº #Ä”öàôY¬‹)Ç‚Ópšk\2¹5"Cj„Óœ,×F£õ¡ êØ§Ÿï·ç3 (†Ã‹qÅf“¢( Ѐ`þBþß"N›¿H$òÊæ—  µ0fÖ_hÔܺq8nˆ5‰èñ©‰Úp°.<ÈÒ3ÑcБE±úI»pL®+¦…jI>=4¼[Qz„@­¢¼9)vn}±pÉU°ñšÁöÜSMccf<{£Ýt¢£LŽÏ(oO  í?îs—¶'„.©yi…šà΂p‹vJáö©é9Ú,„ÞX~©ZŠ„ÚŸt”P#œA¦‚-å[í,a¦à)¼²jMXê„åÁ‰’a`ª1,—Äv)Ø)E· b£¬´ ¡®Ás¿þéZA,(&pÖÄi@QZä9«þäNìo'Mª3sÖCǼ¶ÔċÉfÖkUO1I6çÁ¡K.º`&R^*á§”>bÑ‘=ïç"g˜±v¦lΤ‘Ì£H„gKŽ=K nvÎGι °©&Xœá3ÜÀ~]ÒŸ)ù°”ŸzpŠ"hœ)ø¶ Ô}7(7ëhš„¯V¾FwÏ›xÎ`zxoï.CÊ¡ïûM>I‚ æRµ5í¡Ÿ÷Ý^Ô°ùfóíDd7&;‰»G©;5lßд•س1cdzyÓ½ë’.0ߟ—t᪄Ý\x€K¸2“}Ñ ö=ƒS ¥Í·8c)Öáãâi$ M¿†ÿ\ðÒq/¦xñs‡8ž I€’@Ö²Œ7Ðcuøo·›­V+Cä0ˆyÝÊÌÄL¸ÛþR!RrÆÆR¦rúêz]1쎓(D;迉Ŀ;Bì#w—RExÂX(’Ý@£[ÖX~µ:ë9@ùvY#ລ&3j2ÚL£†ÕüLûe÷š%ììËKö#ö¸4’†—‹…ÍOxtq¯ÒHÜc•\ºŸ9éBg¼º˜‡‘=Ü­ºê9¶Mn" KÒ\bÄ_9ç߯¢—Áü¨fñ“ õb–:¤S‡ êeíÜõlx¼8æFz›lC9gâ) f.)dîŸÓª×–- ç¦Ærç¯fª×´ëòʼ SG²R—èøláÖSóÃuˆPG—©7´ñqtþj“k)° 0îø9»pA§Ž%.äªcšÙ!qé+Ùó#¹êͬØE˜²8¬U¯g/Žf¨7ÑÄ5ÍwE#òe‰Q\7Ä.ü@½I¦®ÓÉ+™êðŠùQòÁ’W6¢ Y„2&\_×°vb¢3–ì )oA “¦,tF¤I¨—¤ÚˆtT6 rÕÞ«M»ÊJøøüîž·³ ÎÓ¶Røì³ƒ3ñ¶S }XÑÚl‡“ŽhÏ´ ÓUp‚Ê õç¡fÖ.I¸ jÔù©V´‡åæ)±òöí&#a`1p3C”••ɲ =èŠ@cJ¥Rÿgü>þûñDggga~ôÝá•ÖÖV8.áÔ5Ðþa—®Ä %Ô55Q ·‡¥¶ØôÐìêᢂOÚ…CB ¼ŒØmfsºßÛd¹^ 4Ýû׉­/ØyŠ¢# ƒÜ&ë¿øÇ¾‘‘׿úª ¢B0t(n…7¹åqŸ ‰Káty!P OãÊû¾ér9¶9z¶ML·‹JÝĽÞo¾îŒÅkª'Þ±V"‡^ÚÍ+¬t ³)½}õP?PœìA#þ‚ˆ¨=K¯¼à#=Ú¹³Ä”‹ky‰^G¢ª7ìÎðêšåUkuýeøÅJôën*îÏöc³=úè)ÚoKú¨ˆ#7ía¿ì¦®¾]p­•ª.Nùs!NÄ]ˆä4×Óƒ‡}Û³îv[¢~Z9cXðRé3ì…JzïzËk¥äõèÉÑ€›ñó²MžÁgÜdÄ«™sr³^4Ú‡¿_Fs ÉÒ”£¦l\—û[@fHž22¤‰B}•Dܧ»{0@ ÑÅŠh½dÈÇÆÎþ‡ý2âºã8j‰ ^Ö{ÌÎõÞ;³»>0˜»$! j“4))´%Ј3) ñ|·iˆÆ^{×»>5m©ÚF‚íõ²v[áR¥Š*ÑTBjzÛ»;»³Çì}MŸ©ÿ#AòOžF«ÙÞ¼ù½yßÏçÇÏ™Þ=°ÆÊ’aÞ á¼½¦ÔoTAG‹§üãuÔÂyKn„.2Áµs½XxPÜóˆV$8š¡yŽq‹…Ùõâ6V{y/¡ŒUE4‰1ünm$íà2:ï0ú¼C÷‰AVqð1—¾¤SV&ú 4mp “ÝLiˆú¨×Ö²•µÑ†„Y 2`AÕ&æµ½äŠ+³:u–R'Ùâ»òÒTEÁ‡ç}XÁKüå û¥j|qý³QDïQƒ:òSËKÞò蔡4³43q×”GÊ‘ð<¤\5¨¿5e|+²×ñ„wyq KzVª>ClœV}äF3QÉ»¾L}LüËÕÉ Õ‹&°Ô{©3uB[ð‘y­z—ª&u ÆE }ÊúVÞ+Éz ©qM~‚,úðœoiÚ£ÉMB$'ê¸Yñ=à¿aÙó°•<ƒ€ã²å•Çnÿõ’¹ÀK ¥3äïΟŠH'¡”–1Ô‚»ýRï÷z¾ú•Çj- t”H£uÓzýïgKÆ…`Ûéž§Eh2ƒ%­Íµrø,ÊII:‘[ÁöÅž1Ú„]Á@³>…âTu*ÑîïK&^ G›/ÿp·à<«G‡š$ɶ¶¶|>H”N§?[8~>>ýñÉÖg³YõFj·Û!„,kà©Z ´vvl È]ÁPS(Ð wÅåV9Ø 6EÂ'%©±/*wßo G¤®°ÜõËwöŠüÃ-Zù£ d¹)²p&Ýsû?M[6ñ(œE`±þò¥R IH9‹7J†°¿GŒJ¯Ýõsåv„ø@ðˆ’hcòÝ:Ýð2!(P†k¿>üÁÍïìzNènÙ:ïo G ; w†¥n¤ÑXÏá}›9ÜŠBrâ¡Ý†ùõ¢îåÀ¢¤(6¡w_ˆÔ_óí~G p"eC HÇâ­ÞÀ–;öÒÿì¯DjQtÒ¥!&瀨?Í8a~á¦"áÖGF¨Ø0Dm¬âDñÂ1úMº „˜¼“‹^ÐÇ:@ÞlëŒehZž¡R€Ü£h'R—øÐ`Yvp]ò‘uÉ!,ßg,:µqWmɵDr¨Œ}ºÜ0È”JvCÌmQ\õ<Ÿ²ëS#Ö˜S“q3Ù!nÎaRG…¢£,:"ª}ª|T›é³.29F·?JÑ Î0LÃÛYÍ“ÀL¬e αB )@kx†W]¤ÚonâXpÎV…“³íYMáM›8²CØá!üÖ–ÕªSŸn´•[@ ¬f¾bô §Øq$ci7^°3ÙñÏg0e¢I¡’‡_Ûû^ ¯Ö™ØjŒâwÖ­¸u~mÁÍ©vãÝÚHÒ â.f#Ã<ª*ú¢PÝ ƒXÆ­Sú¸œsUÑmÉôùSÕßÁ+ƒ ~¡â挭OéªI´“B•…b€yeäê(]×nýŸ~B¤fË23_ÈùÊÕ«Ú˜¦½åªïÁ³ûô ÏóܲÁš6f&Õƒ\…Nx˜´o™:ÅܵŒÓù.ëÓ«žru¼<ëÕ¥§©‚—Jz¡:ñ@~W¯ê=Lj&’´Ø6ò`þ,cYfzia æ<¦ÒŒ6ùžÝ&M¥éK>w Ľe¥ëBÆ£Q=ú{e#ê¤VõPéÅ—ÅŠãZÕ«/]Ó*“†¬gii\S˜$þ~µî›O0€5VÉÕU€BBrçÎw•Ô©…ùá@GLFæ+ó‘ w+þž¨¿# 5ú/þáãÛ6o i’«kWÃë¿kÇ‚¯·šG®€éÜ™ósgRSTiò¤PGDî@B‚²(m]L¤hWÐß.K=~éD,ÚŽ:Ĉ܀¤¥÷ÌS"'Pq‡E_ûÀÀ@©Tú?¡•>+8~>>ÕQ*ær9´ÙŸ\W®¼my@f¸`ÚÖ›¤ùWe©>0ß õÃ÷¶!ä9§¥ä‡Bnò‡•úh¨%"õüãßG·?i±RV'*骋—¾ž”ꥹSr¢þûgž«hxiÿ£÷j=R´Þ?‡Nhw<Òö‡HòÙoc=ã¢XQc]]-ÖY€E$ ¾©—ƒárèh,ܶÅã­ G$¤p¡nÉìÞ­§!èŒG:¤À‹·>¬_[¹ÂÆÔBÚÂ0à­Ñcñpg,t0h—§Â‘ÖÞa÷öÍV³$'Tso3Q5•Éüóç—Ü~ƒMŽXSSÆiÌi§ ©!6çâ•>SÎ…—ÆŒ Ç $Éa>ãÐùÇLÙAËoÚ(ç.25"¦ÝËSçÖì+cCba€žmá‚°™+6ZÄZ`D…›+·Yk•asl„*œÇÓ#?Þ‹™x›`•4çÜoË9ÍÁ‹†b6Ñ@þ—ý²mâ¼ã8R×ÀBpœøì;ßû«_I ¡PH36…¥+T*±!eÝ`ƒ$@yRÞ¤¼ØÆ/±!«˜´Uš¦Ut¥y1 MS»?ª1 …nP± HbŸÏg;¶Û±}{²J•¶ÿÂ&Mýétºîy~~§û|¾ fÅÙRUy·ÒAŸ!zL_aexøEDt3P)VoúøPQÚ‰dm†íëôŠ5k +«¿ã\¦Øˆ¬ËàµmMMÌ9)Gò<ÁqàÐzR@)#ÎÔ®‚Û×!¿®%ïŸ(K{Ë2n2ŽÜ‹<-UŸõ5å+šr.r˜³/I\bj^0™%¡Ÿ®-=+~[‡~oeb m^Iüâ禰ݤx™äè~oõÓ-Oèv¹@Ù¶QÇ·2õ50C‘`à,Š9^/™²³ÊöØvL‡¤+Š?éF¶ò„G—ugZÅÍ uXËÐb-Ã4æ{‹ŒxHñ<ôÖ*èÌOtÒi:ç¡“®¢¨wùôu´·ü“NÖߦþs'%Ÿ­œµ©».æ1G.P9GaÎÉ$|H±,ìæ“MÆ¥]ØŒ Ïy:÷ÕõRÓnɬ‡ˆ»ð˜‡Júè)'špèg=”â"n^ôb±^äîÑe-ë‘r^‡`ËÚ‚éi–63UŽto/yü>¥ø¿­ –Ì-Èýþû/ •«¦9,4àØ§Î‚ŒŸÏ]Ñæ>P+#äl?š¾)~h¾èŸð«²ÃH~è¹Y?ù«.£À- XˆPݵdäºJé7*.œ.š¹ t‹ßX¤\Cb”¤G‰Ä:7¬UühnNŒL«rÄœKôSÊ Uú÷H~X•¾ªÊöë”ëσ£)t¦_“|>sJ cOÛgl´ =¤W>”kK&û­?ª*&0T#ÎÇÛ×´b\jå# ÈDBûcG¥hk@j Ií±Hˆœ¡ðþÉÉ“Í{–‘›Öa·ïÔË‘®{_ì­Û±š@h–%) cI+‰ÑåeÆîS›ƒ‘àòdS8Ô)GÄÐNYš‹QyÎI¢á£‘p}p¢)=2þ¤!1Ó>1y¸eïK@ƒy‚Á¤´¿»ü›9$å”lJÉå€T€S_!+›Í~}ÿ¦þo øg.óÕÌ•l^¹}÷Ö² ÖBz9Ã?Ø"Œ=<‘Ä­©M’Û&CMÏÚF¾cÑN)Ø‹6†ÆI‘F9vp"ÐsãF}Ïɵ¡xûç_îÞòê c“Àóìæhôă±¶ 5•Õ×U7ÕmÅwæ­ñx<Ú˜¨ŽïIFÎ>~Ô”÷Ük¬¨„Q‘§9Ž4ѨÚ骃§e±[DCÝQéäøã}S±Q¹+,vD#{ç«QnŠa±h8ÙuîÔ›¤f)±5ká±/w‡C;%±çÓ¿´7ì)ç0ümh=>‡$–ÕÓ|¥ïy’N“¢»<ÙW÷°‰¹4ŠR€ôšt³q;’ñÐ75ÇGiÌ Ïø,ycs_-WCs±è„S[a‹üÅb¥·,àZœó0Ÿ´è-¬“øk¯TÔUQ4)Ð ,âZ;r—(vzÆCÝ:Ákq ÂÖUðŒ‡Œ{õ³ñ‡ï”™qc4”þa”è+Q<ÅÞF0aÔŠÃ(Ž0ÚHXD/žvi6îâN2² Éàq¹Õœ²Ó)·C½ÛÊ ˜nµ€¾ù"Ö¹¿´ûÃìáY"ì¥}KE¯v"3nX$i+Mºðió?×ÿ´¯&ê0å\¨â€Âç¹*Š_Šf̰oƒ:礇jÊÍ%]TÌE¼ü´OíÃ"ç òž¢©^öý&n£a¡AxG@úJ†«b u¨EC,Å¿· Ë»)ÅÎý¸º”Ñ#@6Ö›t€þÓ}DÌ»$i£3¾EÓïBwN³/™h5YfB1#ªµoáïž«/éÓ6,íD§ÎY”óLÜ©¥Ê4¥A˜hŠÐôÞ°ûøuÓ)›vö‚6á’nd¶›q°ñ‹DÞ]\(. Q¯ "Ýkž±3^]Ô®Myø´“[äzɤûð¬M—t2³iå¬8Hùö§ãhÏz`[:…´6S¨ÑLêà—ËŠïâä~(>XÒoßPÊCV+ Y9Öu\fÊ•*ý¥ŠN B ?”Õ¤F—Ì—¤®.Ê€õŒéyÔøzÅb¢HÎjAU®}ÏM\Ö+CßJàS%ʇP|X›QeÊ (CK½Ç¼Û¸ø¦U¡”Ê\]¨\S§ý‹’ýºÜ¨:?\E£ô#Óý…éZ$•!}~„Îø‹ò>u«`)?©\/M_ÑÍ qWÖnBд…€a0èýukž„·? ¶ˆ‡[Báƒ!©30¹_ ¶Æäމñ݉äñÉÀ‘ž“¯< ¶>´?küþËœ' 4 TdçK}à KyžDÝÑR#ËÇÁ‹rèp0Ð(вÔ%:åp I<(ãÑCñæx¼- íÛÝ»}òW)6ñœ†!9‹¹ìæg7˜òÊ´’û7l}­%€_ÿ}h~Só^ùUhÈÜ s™L*9“ª®®xÜÈ œ¾|å Õ_?ëz4^ 6Åå·HÒžp¬ùYÛˆ8y8Ü ïûF¥QÚÿù½ŽúŸ­X3Ç-xêc‡nÑôÚf‡–1 cÄáMß­^½Z-P”™aÿöà°nB»æ«ŸÀD @"Ö“:Çÿñvrª'$¸u«qãÆï”Š%Í4ÆtYŒ´MŠõ Y„¥²_ç±qTwÀ«*¤-vì½æž7÷ÌÞÎUR’¶¤J 4 *ÔJ))´Ð&NlÇW;‚íõìήXªúGª‰"'¶×RZÔR!ÔJ”ÑV©ã½ïõ^³ëé3é_ü‡”*ÿtô´FoÞûû~~=±¥£éÄ1hªXô`ìF_&ÙŸLì»eÏ'Ñ¿Úe¬j¤î|üÑé{¿Å4-Š¢L‘êK}òñÀ '抓`{+²à«NÅËtƒð•Ó17FÜÆ8SÖåq{)(}d&Ô˜PñÓ•Êa %?UR™J€ƒ©W™pdžó?¾C!'°»€ÍŽ@<„:™ªÆ–‡¥å)Ö¬×^]e¸C$.µ+%Ê,‚ÒtûNÊÐІÊäýŽÜ$ع‰v±„D…Æ®û˜úžŸ¢uÍóÀF–gQ’µË@É«ÀÐð¸F>¶½I àì‚Ðl 0Å5[ÖGýeÃIj# ×SÍgµå|”>…­¨æ¿ ãdq'Øü8› ±éÕ” ÊuëŠfÖÕ]5ÕT[ÅOBA}Ýv~|f”4È*©BŒ³ø'/s^Q bòÌ“Þü°Ç Ëð¡F€X™pÔ‡°ò$_ eÕ¬ÚŒ_¶½7 v+Ol#ß þpãùž-wÓ´D¯qËÔ•SBZûrL•6q&–v¢Ô{¿§ðèšUŠSrzÏû=Æòçj‡lÈÍ(Øì¶Ü¹Ý εC⺊C!¤ýÌO6YR²ãNwKvÀT£xÙäÈ÷(†/ޱɑ›wÔj !Í”µT¨dJÃLE«*¨~*Ãå1 žVµ•UkUÃÊ!º¨ÑÅ-Ê“lÕ§1Š@ׯ¥¢Ê]{ô~תp4F{HÆM…ŠD ÷y,¯œØüÛ“bM’,Âxx’²}ôY[0Õ.›ŒY´>c[·–ß´”ÖUæn™FŒ«¶Â«-ÆÔ˜1¯„mL8·rX3iGðU`ouH?ØNïÞiuH0fMÆi¼‚é3ì§«j¹:äÞ“<î¼ÇÅN?Çe¼ËókWÂkWæ°ê ¥ÏâÆŒ^¢6éóhíµfã’ ¢¢|¡Õ˜Å>÷:§ùò¥/TÃxý2a„-Å‹&’Ç·µÒ”×)‘"Âmä×wøÆbnO2shµ^e» !²éî|º?›8œŒöÃÊ–ÊîÄú–R»¶o×}_·óƒ"vÆ:;×¹´Ø•ÊtÿñÝCmî0mvëûÀÆíçÙÔ1X¦ñUä³Ï%“pZ8a2Ö—Nô$û Fr…þtæäß?¼/‘êJ¦ö&rÏ.Eº K≟eRóé£Ð$™ô­ÓZüH:Ar0•èŠFÛÓÙã¿>÷”kæy+‹XU¶x`vãŒHa (Z¦›!–FdCEJ/[жdŠ£HÉOÔü@°0J*¬ÿ«mi-DUƒLÙÏÂUPžt¦îw;̬YGÙR“ ºa 9L¤Ó¾nz€[ö‰å Ÿ X’gm”™¥ X‹bcŽïxPž‘iIð(xô”\µe2̦àGX`Eéü~Ö²&5С^žàIÀ€¶wz@þ khȇ'<^…3Ñ %8àäÑÐ*3ã ÀOíÂ/àß^ŸÑ6|!@5|Jq’[VѲƒÁWõ£ðÐýH=€ýÐ`â*ÀB2D\ójô’·Ÿº_.ùØœjŽ‘7Ž‘ÆNDìòÅ.s-ÄêA61îŒúñ¤Šä5qe„¯aWBî¨X–}æÚ‘‰‘‰¶Èš 2¹!óïºõ8ò íŸAgu™;Êó°ÖÓN+‡Ÿk £–šoMmÜvý,¤‚Í8ÅBr˜‹ ÚúwH2…º…»ZÁå`Ï?˯¥2«O:-ôfŽwòDÓàýÔ;½ät—òý-< ‘QvzÑëÃ@W• ²:!ü¸>lmLà…1¢®YV|–Â0^ Hzƒ¯i9Då†HÝ×\‡çL q?Ûã ?R ¬ÏitV³åòrhcFãRÚºÊ8ZòO=èO·’2ÿz¼—cd˜Ûku¹œ8ƒ£2#1ŒëØ,õYP“yÖ˜çª3¶j¸E_h©_6Óø­ÒHiÆb,´V__k,Æ V½ˆþæy‹X8Eá µ1§ÅÈŽíÆœµ:ý¥ZØ\·skŒ…–7TV_ÄhÉÁ Ýóí¦M;Œ+cºY¿ ä/µ·L¹ScÁÚ˜¡õð:ã­;ôK¦z+…-Ÿ[#àÓ05®ZН›‚¤<+F.¹þ&§PMkǬŽTºöoK䟎Åa×óL±x(è‹þ»#ï+d"‘_¤2Ï$³{ÿ‡§7x e8ÂYرk$öR)q2—ê¹k?Ü¿ÃÁJ,ÑzêŇ–Rý7÷æs‡ó¹ØÖÁžHìO§º“q(œãP#ù\?<gŽ';£?ù¾·¯vK$æà%§Äÿ°_ç±Q\wÀiZœØ{ïÜ÷ììá(R’PUä RB -ÁÆìr™Ô’`ï5»Þ5”Ò+RKT’â`blAm“¶ŠR‰FjªP Äöîì1{ÌÞ»ž>·R+Eí‘!UyzZí?»ïÍûÍ{ßÏ£ìOÖªŠZûO^üûóËö×òµJµ¿¿ÇLªQÀ[)íÙ³¤äîéÈ‹qÉy÷ζbþPtjo,ê’“Î/Z#ÑÈ®ÈTÀO,Ö àq:¼‘ÇëY„îè N ¯‹G^’£]™˜X×ßní]¿¶™a €Vš_³ºõÖÃÓÑÍ™„+Ý9Wó‘ãû£Ó/¤SÎdòhvFÄ ^$ç' aÔ7ç…«^3ýjXK¯ÌÙ€ÔWöñª¸P}™¿Ø‰­o5®Àá…XÃŸŽ±e‘Rý€ppyK‰æOì[Ÿ0myŒ–¼Æêä­CˆÁB€1zË ¦ê&Ãu 9 d½çx–ùÀß÷ÀeQÓ-´ñ, :LXGr•—‰”[—ô€Å·^u9n­ˆˆ¶‚>”CV)Ô˜ RŠ…(‰f`Ë¢VÌzy`B— ¢—ªzêU·iÆÛ˜t³© ±†fßÕ!²l2¼{€ÜÐNbÒNƒ ÒBÃ(Ú@ÓM«hFyWßz¨2®-þº¾ú¦Vƒ+ ù­z R/ s¥‘ÜÕ†Ú¨V}SF4•ËæÚ¥‡‹ãäïO·®²›áZžjCHxãëfržT¯×©—M…óæÚÛ”2f˜º “gzí[WÏ# «ƒg¿½üÁø(S}³A½‚—Æùìø<õKéûr£Ô¹#‹õ ‘ž¨«Œêfýœó¬ŽCå1“rñõ#Iõ"à¤NÔߺØöìJ+Íš»•@Z8Ø“ÁQ¶3wI“‡³‰Þ$¸ŽM?n£±¸óúÕÝKšt6¼%8 Kq$äìy<.;¥[ûógLÞu¢¿ƒ21ÀWý}OO'©ôIêG–œìI$ºâñ'Ñéžè” ø$&í75€0V:µojúûrúèOü iÔ98!(úûV‹Åê?Û¿«R©ÌÌÌÜÓÐü²ÍAûoEÌ¿þËs4IX-,KXX„ìÚ¾4–ÜŸL=Ÿˆ¹äرlæP$òBF>$M¹’’ë‹ÖHRîLH½@A j¥DÏŠÅ;0MÞ¸Ñ%Ŷee§"õ'§»#‘-R|¯œ:1|ö['N¬ùùknOîK¥§dWôÓ=i饹šOlêP"¾'ïŸJ8§{ïL¹$éø'7{’Ù#½½£ÑZo§í<ÿ©ÕŽëïmïë[·¬Usm¢;!íUä#rÜ•HtG¤ýs¶>ÒÁøìîûÜ2"±m²Ü{mb»€ÛHåh ,kjC-mº+Ç,ê+æ¼_ˆù¸´)úP%È¥Ã|:PÍ €Cf)"Y/šÑŒR|xÎ3›Œ•ªˆú¤OŸ¢ƒß–@” µZ8Çšo’.0Lç@šŸê@¨åOÖ«a#fu0ÚŒûø8ì@à ”¦;ñ»"Ÿ ëU7ñRë– çh¢‘Äopj ©0ú*Ò&<Ám[mV¼l|ØRÒÀ{QøðxcÆßš cò ^vjÇLØ–wÀ$K"W ë•°NqeX b. 2B ÑEQòÎvà%à–²(èr€}dÜuÏùñ™^í³¥ñ@¹‘´]ë]>±»%° ‹âr§)%`Έ†œ¿¾Ô‚¨âÃ~T­,šÁj€Â)~NZõ#Ÿ¢só™aƒ:ÌÄîSƒBn€­ Q‘ÿóÀÒ ]B!¤S^ÕÔ‚6 OÕ'Ü8nkÆî§(;·­]nx£úcóÈ"ÃR ¢gC;_pcïF1‹ÙÓ-”¡Q2M›åG›ùÛG™çVÁ&IÒ»^?ã‡Êak!(|ØÇ.£t5/ð?cˆû[Ô!,ç1åXUÔ¼†TÈRñl€Í†„ÔI“¢ŸíµçL;¨¿ 0êiRÔy²Ö¼6@¦|Ь Ây7^×bP›¦~Öm]æ0ÚHa1 L0VßÈ5ÑFqÇ|eŒ+=¬NhÕ‘:uD7s +Œá…q(ùs§ùÿêYðÿãHyD£^µ¥Ç´Åñj ê•ÿ~Ép¦Ç¼v%GC6†kY†/øH„2ãugú¡o_±šm+1og]ì\ƒ:ªQÏ›¶®Ó£‡ãø`T~·¡t©>7ò:öÕÚ…û~ÑKÑîì×{lS×ðNÛºQH ¶¯}Ÿç>ýÆ@´°Aû£b«£+ll…È’Ô³tAâ×õ# ”­c[ûÏ:¤50^eê4 ¤vªPÇZV(‰íë÷ÛŽí»Ÿ—ºýW)ÝCêÑQ$K–sÎùÝ{¾Ÿß‰=dQqŒVÇéϺÎÂ8*M̯^64@rSS¾Œ«×5êÛ¸èá•Å›7 Z Én¦Gwîµ”„3„tçÓÇN²/óübøE3­·ÑmÈ m_Êžvm6sär»ð·{ñþh¼óû¯¶-ÁŒäb(ÇùóßÇwE•éÔ@tzÔ¡ÄvF-^|.jèmᯓÊÀÔ£®bþ t£`¡þ—¿æå)€D -ÞúõlVÍ‚42û±\.ÿç²ó‹1×ãÓ©ÕjPÖ;ù }Y+Ïr,…Ý‚-›¤ptPIü$ëLÅ÷AäÁÃOHLéË$”pÏç­‘djO,rhzjo"åL¤ŽZX=Û¿»ùéèTw>s4<ýãXäÈ{·œ7®uLLì¼õÞ$ñø+ k€·Ý /N¹|ø4g‰÷Æs·Þïøþ–v„>Qsäк{wÇ•®h¤/ß÷û±žÖXD+¢t  $‚êÜáPÂNeÊ‹ô&Ò]åМ­'Ü—N:SIg\Ù‰îSmKw!w¼³c= „ç$D.•0ꌳmòç¦jÀA¬ˆªËú4ž/]™Q‰èLC|!ˆ9î£àz¯¹^ °%Y€æ´ìà ^mΫ­™nÍjË¢ž7­uW7­’0L0Ñ„nÓ Í]ÿ*UæiDËäÇ' X‰ÞuÉDž³ê™7ºÄ̰¡îfà7ÏýˆayÁD1I¼Þ!•ec.@¦FÉïY4„ù[ÍïóÆŠÇ\>+*>­êmÉ¢ê0¯Ê€Š¦ú°PaÓ.¾< »Ðf¼L1(•B ,8ã™awð¯ÿeÊ8ÌšÛ\”fÜ⌇oøDfò^²ø¿§‘bÀR’õE/ T½ºTH_ ,ŠÈ-3¬è%f‚|E6–\FØŽêU7Êmy_Ò©!’½b^}£ˆA<¤Š.>FH2¯Ó ˾ÆÌ¸ÕCb'­õa²î§ò£\Þ¥ŸÁA¤ƒ[VÎÀl6j‰m¡Ð ‰3‡Y9âÄ6!ïm~s‹x‰M9$îqb4/±Q ñ„ÄKðüŸy®¹ì‡-cnt|©Õˆ/¶1ÍcýkïoÔß÷HÕaVõ£¤Ûœ #T0'c1YüÍò›Â<½žÛîÐ|<Äׂͅ!.´€Ÿ³>])DUÝ€gC5@Ô<\ÁÍ'tr”L‡ô¡Í|»h@h%Æó$k¶°‰'7,5]ä^X\¿ÆÎŒ-¨OèkWQá26s£e®4R+W¿\Ç*©Ê]é*®^ýºú»¯T®¥‹ÚäøcÕ› “l™#j0Œá,i£I^ ³ cIíSvüü~®~¸6L‹4«-[V±ÊÅ/©×Œ@šú%¬~}ބ˰ŒäpšâXq…aÞûg¨ˆÏºÎúÉ ©Lè«ã@šÇÔ T'êoëŠ7›½Ó¶mõˆ¢! &Äüê—[§#é\\þ‰©p÷ÄÅaK&A»²]wýÏϾûî¼Å¼NX·F<ù³gNžÚè°FÖn¤+ýõP2Öß ‡2ôèï¯f’Ç#@KÜÕ ºD»qgãÞVöCã–Œ9séÈT_C>™>%yü…ç—J,fYÚZ·oßžÍ,õŸ&ùt}1þTp¶š³(R(Ö>ù-–!)‚4óŽ•mÔ‡wÆÓ/‡£=)e y)ïP¢½™Ô±D¢7Þ™N|îI¥»@ËÙl8âœ53´@Ø­ÚÉû=Ó“{â©þÉøÞÓ§¾ÃD#³ àß–ˆõÆ•ŽDcÁѾtjߣÉÎxâø\­'ë»÷ÉáåŒ7´‘$²#­Ýøôòløx:Ñ=9ÝKŸ:öÓõé$ÎÆÒV§V·¯üÓW”Hg&áŒLw‚F`#svD(Ǿh¤^äHä@*qJì¸÷à Ý¢eX–a¹VŠ n'2ê .5,¦‚pÕÔªz¹ü [ñ13>mÖ+åýB.Ä&}†|€ˆ‡tλÉLÏCFû¤’›«¸éºŸ©É¨ä·ˆ{64!pjÉ -ûÖNüÍ=žD”ÀiDó³m|äD‹i¶pÔ•lÕǼÓÃQ6Èa&L»×ë gAX5Dß9ʳF«„sV^Û¹%ýd>$„GZ>8²üþŠŒÑ³–ª¬SOÏÏøéakÕ+äüLfˆ†\.y 1?Sñ³åAdSÞC•tÑŪCŽ’Ÿ‚m–|4Ì‚*Ê4Ì<¨Cfr>:5B§Bxq˜(ú1ˆ{n€Y^fÿëüø·™õ_KY¶äý\}(ênM&Ž¢r>T Òp°}d2 6Wdªä¡ªA®äcr"` £B*(sE7£zÉœ‹¨ÈD<(6¾ãA©3öêà™‘…ê0Œ©È|Ø«S} ¤å½úšÿí^z·ˆ±Ù¨CËž[L~âÒ«#쥗‘! Óô‘«ýÉ]k¬B/>…EÚ Îts?‚3Ÿq¡°Ÿ{’!Xì„h´á›×p+ð¯q¹Ú&Û f«þ¯æGM¯Fõ,Ìí£?dZÑã8…ôÂ’žäàCõa*xdQBn‚Ç50Æd=è¥([²2 è‹>CeˆQ]7*ÝÏXÌì"+Â9z!‹#Äýƒý2âºãx£¦$ØÞ{ç¾÷06ƒ ¤uë4QJ’B)%¤J6¾1‡)õ Á{Íø(¥IÓ–?ŠªŠ`{mlB5Q¥J½¤„„&âÚcvvwöÞõÚÓßÚR•øÉü)o¿½™yïÍoÞ{³ßÏ«BËš^˜÷ÏóXñmÝÄÈœ)¿aòM“64[(bÒ.ZÓƒHñjùÔP™æ'ラ³ægóuÚð|mÕþT‘y¤x•Ë [·U’ ÉJ–bWUbÕ,¿Ð\e³áMWNé* «‰¨ú¶×ü6íH~´<9Šýí,WÇ“UQÉ N³°û¥òÛ®Ò.Í»ÿ8ËH2~²8fÑ.êµKÌäˆA½2§8>'Ñ05n»õV݆ՂÎì …jÁóú¹ï­2d£rddwBÝö<ÁP¶5O­o“Õ®°Ú´ùùj©¥ ³ pøq,Nb$Ç̹pas$x"!·ËWŽw.jÞÃÜúähB킬¶D ‘¶h´q¦d/ÙJC4|P v¨Jk(Њt~ðߎº•"-a)€ ™ñÑ7™-y.—-ÓBZÀ¸snªàf'< g=\Ì»©i £ó`è>ˆ^Ün&|lÜ߃¦Ý֔˴S¨¬H&Ýè„0ø¿ò대¦+hÖ€€”`dè•öò’%'ZÀOaÀ‚,xHx:°bÞ O„f8D›­É^$Õ‡NxK·²n ,4í³&}¦d¯”s9ò.8sÊC:NˆÄ“¼XœÝ‹%&êr¾wˆé߬k­{èØjì÷{æúÐT.ßcý÷©eOX¿d¥…\éphrâ´ù¦yãe²au5G–qÄ—‹¢];cÊJÖÃ[*y¥Ør† rG€;t„S°ðçX`!Íżå¶Úƒtn¨038N2µ¤õÇ›`Zë¡'\T Ñ‡Â<¤D–õ^ñ§|ú‚Ϙõqã­Ü¶U:;c¡8#f–vÖ8b“>?ˆi#ÆÌ°!ó–!=jÊŽZ3ƒÆÜ%DóSÚ0¡ .Ôü_™-JIŽéµ7mÈX¼R69DhæÈegµY_agXTx­.º}ŽhXç © îǺwZbÑŽPhüPT>;6|·ýç·”Vh¿Ær¯’³E#·)ï2æÜ¦‚hÍK`afU4%$s¦Çžr I7Ÿð1É^*ÑǬÑ>“êC`–fõ™Ó¤„Aßœ¯„.ËÀëO³MÚKÞä¼4ê)7 –šƒÉìT‘P%|Fq›R}liFàªIRìe³"•òài/‘‘¨¤Ox0à"¨Ì(„ Ò)‰™QÒ¥ZHyèž›i¯=ö*—–,%ù̯ dÇÄEKz° º°¤È¦{Ù¤D&¥{Æ{;Ý/D]DVâÕ¾ÚßlÇë…G Šr Çi’ÂLÜw꘿ºŒÚðÜ”ð›¸8O«(^Ö§+&.ë'/›ŠƒÆYsù+íÒÿØ/ûØ&Î;ŽóGµWãøbŸïýÎ>¿Ä!Т´Í`ÒJ·ªëV¨ªV“¥¼´]B `‡ð²Ú¢%±}wΈ¶kµ$ŠZH„0˜ûcê?Ó¦I“MâØgûüîóÙNn?Ú´IhB Têé+Ëÿ<çßó{?ŸÏcÑÇÍÅ+ßÔÆ}lyjk}§(ÌMëׇÜÚøcú¥Eå++NwðÊ9hŽ$nÊú—ñÒ…ÚÒ„%z–ÞÔDÚ1Gyì$ûã§;çLú(βò8¹Puê-å1$w~IiÂPþ}ý?\ÿÝÕŠñ°¸¥ÎÎñ zío'S‡RѶ„ÜW|á™w•tçlìM¥Š oBé¾3uümí<ðâ‘®ç>üàåp¸+*wÄßÕßmýÑ÷·Œ²s3xrËL¬;™:œˆïV¢>px›oƒÀ±§eõî–hŽÄ:”äÁLÊ›mÍ(ï•ì´Æ A1)I9½<(ÓuµPüÚF¾¢¨È=!Ñça µ›7& §ÒκX+ߺk]<Ù©(û@²©ƒ ¦šžÙ´7:Ý¥D{RŠö§<»/©t¾ÃÑöd²-•èH„Ç#¢ñï¼ó´Ëf$pÚép±Ë‘pçÁöìzv*ü¾œoY¨z"Ê¡;³{³¹#rt<±+‘öž>ýªƒDì¤4[Ÿ{¶áŸ3¾´º3|§„„ÁêàìdPË/?Ù¬¤|‘è[0$mN¶¤“Gåø¿7êLĽr´-ê‚©=ê~‚ÿ¨JÏ…Ñ7(­ãI#W‰›Çí¥Të¥t ȸ<3ÀEH]„/ ú¥‹ä'-c%휭¾Özø%«vŠ…èW‰•,ï®­gÊétrÆE7zxµ×”þ˜ü›ßÞHq+q·‡]ö’{YB@µº´ä‚uj:?€ÌÐZß’‚ÿ¡éù ä†ñ쑤rƒ4@Ü#'Úr_‘è²HiA¢ÀUÿRb/‰¸&⪈©"ZYÕ¬""€Ô’d«©R>„«ƒà x1dÖ,¥A+¤²d$²Eê~þ»5À@ {å9¼¿µÒƒ¬ òýDÎÆHæ%,'Zî¿G€Q ©™¹SñÓ•^R•x0U Õ ³€šÁ æk2dÊ Y`Öùf FQðbÐúÐ}«©IÖª5ÕH&M2«RmQrg~Žë»(3Œþé„kç&–FÌ€JÚig …‹úÆðŽó‚¡ ‚ïyæÄ•gÞ^ã¨5:9W½™Þö=[ddµúA"áÔï1'9}¤®(¢ŠÈîzž²ób^SGâ¿jEÓ}Ü|?ÄÒƒælʰ–DV ‚š‹’áAõÃæÌôa¹!VGë]¦¸ÿzbýñ…#«)³ )[iµ¹qêøvwú£Ÿ_ª_6jÆÊUDs¯-Œ"ùIëBQ^»lžÿ¼Vµä&–/-×Çk†ë'ÙFuà¦:'ò›>RŸ0F?#[^q:Œ'xAÞ¾(=º\¿L|yÁ°q=ÃÐÖz8¦‘¯¬çn_@õKØÜä¢Ê䊹qtÁlä|ÕÇ*×puÌ4eqll韾ð´¡G6›guýÕû’3¥Lól´#¡tÊò%¾7Ý›Nú¦§ß*ÍDÚ"ácáÙýqeg,ÙŽýôÜg?ipðN–åI—ƒFm8Åbæï4ÚÏi“#Iew–”; †[·¼k=˜ô8¹:¼Ærûö¡DüõL¢{:ìûáì r6‚[[gûí•fEiO%~ÿ²Xìp,¶7&ïS¾xÌbSõ¹ZúÈû9”˜ñÅ’ÍÛ77Á}g\€‰ÍO™¢![%ÄWüFu°Å$°[þ/4ÿoÊý”0Æþ ÁYÖ‰1OÚ‘x•ÎSï­jrS.NP‹q“üðë”~ ùR\œ 5toÀ7:—œÞ}ÑïÖýTFD©åP]Etû°l¿I°¹á‡·£¤°úm÷¨]¢eÁ\Í… ¢J ¨:€æ,ÙAKvÍŸë°—D›&T= HšlYËÙ²°&ÛëÊÜjÈ•hÀhj˜P†P¹lLõc™ ™Ù{çIøw@'Šq/É“Îø à é,;h…_/„,JÀPÆJÃd>ˆÀ.B|Yà󽬂5º/6šH•RHM„©U½EdÔ•Z• š¢UKÉH¶ŒÈÃg^¤a}Ëöð­Ã U!¡4‰­Hܼ@ëý¤Þ‡¼*9ÁÄ`.e?Q ÖT>"ÿñþæ3N—µÆmk2›P«AíkšìäÍ^F)`x±gi‚ °žøó»µZšÔ”NYŠ5ôð„an„8ºuQ¸ ¯o`‰3oTû–-DÁ ó~¶,zæ$^ Uiyy+†ì´‘ 6&é7¥Ha€RC4Œä&Q›Ö!<Žë š#I« {¬ÉSsK"=¹ËÆüØ"ý¢aþsºZ[EÕI¤4aÐGA!V¤®šÏîgœ8ý¤ËÈ­²,uYpa¡ª un{Æ6½ÊH_3¿¶a±•ÿûuÅuǼÿPÉE¾½»3óæÜ=|R P©!!(‰€@C(!Ð*.c|Ÿ,Œ ±÷>Œ QU”¶¢MÀ.ÆGi¢þQªÒ–¨UŠ[%€íÝÝ™=f/¯§¿¥RÕò‘QU)£ŸV«ùc÷½7ïÍ÷óCfœÀ‘iC­éo`†¹©"ùfilR³8N,™F&uñkËrÓš…q¤Nb 7 ¤iË_.?gaxŽ^ŽH×­]ýÏ{ÇbBO(Øއ}rèx$ÔòçM’ljܖŠÃ«xŸ>9;ÛiÞd¤X=eÔ3üÚzî­3Û;š6ZèN[ÅáËoM´…ù×¾ê•BR¸zÏàì 10(…xB %cƒóóñПîvmß\­'p'k̵5Õµ‚ø7Dr™¯9òy'EYÌ忽¾k/‹8ž4³_¿BóÇ;sÂaE郭%…Û" Ö'ž’Г:Eᘮ1;åŸíŸ™i‘£AW8Ü*†›""Dy›ß4 ´ˆrÿ\¨Ï/vÂ-óÁFEÀ–ÅÖX¸yɆ$µaúB[4|44¿þ]þúò6•“x™™^ydß3Áý‘@{TîþëÌ‘M›V(J•ÿdô%!Ôœï… $#5 BSÀßâŸo…•ŒH½ €Ö×ÈCàYo$rè³;G¡Äô–#*)æÝý(6jQ†ŠÒ.FöÒ†i7ý4½għ†èžm&œåiš4°æ+GHÕC¤ÏinŸa¸¢b–ÆŒæ †wn©TìlÄU®8õ³oU‰îoÇÝXÒ]¤U&}(áÕË6m>àFHÅS‘9oˆ cK¥‘¤ rœ…H6¤<¬âan:î¢bžügÜA*Ài˜µQ9;pSQ’­xÜJ2®|Š)Ãä={åíSôÇ}Ìt§ñò~êÂäÛÆ¸¶0[WÙh~cµg ¹·Úó4õz õêj>_õz¨OõZ½joƒîàwQû&n`kÕÙuç~°âš±·ÚôŸt£»ƒø¬“ŒŒR± DžbÅséd·.êÅã#HÑJîr<Á¸›€aÃ\Ò^Nu³9$?k ¤p~­‘¬ @´dµ’vCÚÆem|ÆÝ…é‹XÄÁe\–ÄÛTzå¼xnÔøéI£ïòØZnßcß äG=TÜ^®:Ê‚>Íïú,¥%Y–B|ó‹ 4í®Rú¤•RÎÉaƒêÐH#«zž_f'TáÌ/~T™²sI—!î(RFA/|ÆÁ¦\8Fr€¹¸;¾tßÎ;xØØª[«Ú+6q‚oÑ"0æ<´Rž7ëVp5&ÄÔT•”1…Èh1šÞÝÅ÷ߣrSXllyêVáÂx¡z•Zª”ÏM”«“xz\›™¢2ZõªV½¦KOħŠ?ÿiÑhGùŽçW­ûŽ™äªB,¦Û¼ÿâ}Cö½RuØAk z K˜ªñ/V,ŽU«c%ÙëXúZ¥:E,L-Ù8'1uJ“ù`¹ púUùâM<9QšºUþ³¡z³Nkà)ž­5³†çžá?»×;Åp·î>슉'„¹Î¸|R{ò]á|SB:ý÷Oû:n6$4¹&¶nÃFÓÌç'gý­v]º´ÍDÃMò¥”˜wHcØß ÃàÁxt@ÀÛ²(ÝpÅ?×.†ÛB³üýšVU’f††%aIók»ö@Œe³iuñ«___éÊ.fs<é²ûÆ 'Œ(fN÷Ëw_•¢' .ý³-a¡%:.øBbÛ×H¨)èü¡ƒî÷w5¯i9Z78vG¥>Yj ¦˜< †;ýÁç;"¡9t&4×´¥¢]‘@kèaûRŽŒ'hƒã‡Â?—÷ƒ(ó¹w›9ž$9-æz^‡>úøØ†õÚ ^ I=÷ïwHR{,Ú&Ì7 B3¨Æ ‡NnHä´†„Ö'½ž©Hç}¡#8ל wœ:½ô E0¤áûu%wÞ®ÉÇÓ"{ȘW›Ï\7û¸iµèBÒ§üÿäô*3ý¨›#-»V•¤Ýä‚«$âäÛK×r:œÃj©ÒK;KbVË¢O«øtÉs˜TÒ]œu³¢‡‰; )Pf˜HZ‘2Œgí„â3$œKC(iD Á-{µ€ GEÊ®ËÚ±;­8$xÒ£WF`)L³oS3ƒÚÉVöòaäÞõmÅß|–Ú´†^Y‰ô fÖc4^JåKÐ4¢–Õ*iÖ„(GvòfæôµŠ•)D©6JðÖîYoä(–bÍõnfޏ9ŧ‘¬Å9׊ØP±zû‡ÃÐõò ŠBe\I5Â.0§¬¬2ÂJð NKΊgtÚƒEÜ…Ÿ&1ÊÇŪS½_úÜ}FÙI+6"cC Í„“‰y™Ø“³“6Ì|÷µ{Æi˜¾VÇ"qÜò=KÉûgÉÄ4–¼Z Þ"“ãK•ò ׋ÔXr¬8sƒJÿåÆuêu6}õ[êõŠäX™ú!óÅωµUËtœ i¸cÕŸG5êDInº g»Ž£«5NWpOUn¿Sš¼®Uo–-ŒU¨ßT¯|C½ò/öË46޳Œã ”ûðµÞÙ¹ßygörœ8MœRš Q¥U¤B E¶BIˆ|áø¾r8 M|ìeoÒ&­"(H!ØÙµsôUJQ!TÀ‡P°¯wgfgöòz{x6þć|r„úê¯Õ;³š™ç}ç™çÿ{L³ã_Yª8³Ajþ*cŒZ2—WS™«¦ÌH‘qu…|ÿÊó´°Š!Œ$I»vUhÊ1Y®S”z¨“P‡cò15Ò69}PµFÕÓwï6|û›Oæ Èl‘Úˆ˜u~4©ì›ÍÔÆõš‰©–o=S9áDÄŸ?mP•Úõ¶5ªÕ¨zc8Ü5#·†¢¯éZ8‘¦ö@ý„VNQOÝoTõ†_ÿ¼Cd¿æ$ÌTÐ$îïï/xZ>÷¿öÕ/Ç3DòFöwŸ\‘(²DanYÏáU­ìU wÇ”ÎÈt½®vÂaX>ô¸ÝÒX‰tOM×Fãm}Ï æõN¼öOwO©‘–ÐTÁ»u½ÓSÍ©øU©kÍáé ½Q7ʡΙûÝr¸#™èZªxîO4N|q¢÷è³ß}Ù¹{×–®Žÿøçq9Ú GN4Ô}‹%ˆcyéâ>U=v?T¯iM÷þÖÕ[­P?•lü×þ˜Ú®Ê‹Ò¢*­Z´ØFŽbÊ_%Ÿ«Lú¥ìõjš÷¨û–v/Nè4ðŒ§<á-™ã~b¶f̹YxY³C\|¸,uŽÖøäpQÖ_wSÚpEÌïXäIÝGÎöS_œÜôuËJ+IR$ûzõ²¬Ë”沃dzÈëÛ”÷³9Ã6¼RÆQÀ܆zçžuqsçJ}kæ½ÎIŸrû¬ôÞ²ïeúâkÖ['œÑó6ÃÏ,œ.y(-{,°„”ßž:ïH¸aùtÆÇ)gËsd~Ç|윻îð~°]$[%ª`ylfÐŽ:õaòxîš9¤—Îå×fF-sU¹QS.@åÆÖ-Œ³¹Ëìˆ)7^8“_類²™6có˜[0Æ‹’êýよXÌVm)‰^ýn·°0²ÌJékEúµÕ¹Í©+ÅÆ zv„Yª8ç[šps2w£(\^ ²ñ€|еðu¶J†ÄB‰À:DÁT[ûÌLè(´®ñxsdºMµCŒ¥º¦î÷\Ùû䲺¼„P©SbfíØµýjô´HI¥%ª®Þб áf z´¸~T‹¶Fõ¶¿ÿõèû{Ÿ}vTM7%bíÐx*@‘Ž©é(­0QÔZE9ÓÑ^ÍSË-H¨‚çЭ[Ÿ<°µ/ÇÿßÈåŒhLÙX…žŠgØ^0O͸Ôh:¢ËÇ£á6]߬Õt ßÃÛ=•Ðép¤]Oš˜îi8ø¬“©iª®n{4Ò¤)]šzD·Ë‘C1­M µÅä#áPCBï[R’µf5Ù>m·,Uª[eóŠC óçË~&=`7úˆˆÏ™.Ó}tÆ 5éZ6k~.í]g :~*ÓT/®W/Åü„áµ-^¬íÞOÄñ«k¯íàsxÇ&º™0ÉI4²@ ‡+p EäÀ€LØ‚8ºðÐóx‘Ià/BÇa†z±q,üb€Œ‚“Vž/\Å3 —xÄs<ðt ’6€mDÃ# Û8$"ÁÎñV†·AŽ0ÐÜ"aYÌqR!C" ðI¢ÊlYµ|i{噥—^%ï´!å§RÎÉ¥¼–˜÷‘ß/`ð[ÚEfÜ€kÖ#¤ÜÖ„ËõÙâ^13Tžñ™Ò{DÞcžïߘtsñA)é³§‡,³®µóp‰Ë;¿°"1è|§ÆþôfQàÑX§Móo3ÞX“ä 7™õš>÷’ßßfr¬°m³JŸàãoã䆋5ì€=šoÃÉÝ+ìˆaIRâ­ÁW—­?óë¤û‰ÜÛ¦‡ÅŸd3.&á¶ÄÜeI¯iÎGdÝì¼[Èú¨BÚ¡”%úK€…>﫪{n K±6žÙ+¦Y¢|gµùæYlW-•Ëç¯ÍR 7WåGKŒ •¾öÕt°(@ó17V”®ÊŽ•k¬øã[ÜoÚ–%ôBÐ|éHiÉ;yŽf‹­fçå^œ/5‚¥© }ÛG¾[_<øº0ôcöö…²ù릥ŠÓ)ž ”Ån‰›¦ôè*c¬t~Ô”£Œ++äÄGŽC†Lÿ›ý2â:xÔKiI xÙ™{o¯ƒ¶ ­Mˆˆ5 5—Yïá5>p€R!‡÷šµ1I•*ý£U©jŽ6@¤VTôR“´¨M£ãcwfvfïÃkO¿ RUUu%$Úü“§§ÑìÎ̧7óÞû~¿Ì¼{ŹS£‘<ß"uMÍônƒÚ'Ÿ$ÉrÊ ã¾×±cG•UOïïØ<Ã;Sb_bòä_kW' *½DމQÈð}BÌ3y°ík´eV­Pßù½‹ŸöHü ª3Ó.)Þ+.ÈŸ1¾?"uFø³Ï|Ý@QfØ3••öD"ñisõ³ößÈbqaá_•q~~^Y(]8tСѩ, ÕfÝݲàyd@Ý<ïŒF»%©âÈlwL쯣}qñˆ0=(FK«K’_ŽŠÞ©ÈP,霙<šýñ_½56²”™Yêý»ûf#'b1¬Üb¤_ˆuÆ„Á‡$ºÀ@f#½Ñè`\:^ ; D¼’Ð+D1Á z&™¸wo_µ·’DµÕÒ¾mMíJ-⬾ 0ô‡_t‰Ñ=÷þæZßÀèu&C:­’xïÿÚ.þ}EÑ)D] öïÔ¬sÏ.œÕÒ•Z £Ë÷· ÒˆQñ#Å ºäEMÚÿÐôŸ÷©³œ5"‹cê÷CÕuÖ'0œ²ã*ëc€‰ì%Kêüòù,ËŽòˆn±8ÍМR(AzÎešlH57l(øÙ\„ 7¤3A6dä ?¡ÈP–ž SÐSA*Ã1òE*ÔΗ+÷ÿù”å'Ó¹çñ¶ÚªeÕj¨¦ØCcE±,¨d7⃊\b˜™¡lPÐÁ?&©$‘z¹uµuo5ÕÓhÿáÍßÿFõ•=ën¾ØðnGÍ;­יּšžæ„»1ínL¹ë“ÝkR®uÿ±gÜ OSÂÓ4ãhøpïÊÛ»Ëo½P~«ÃþÆóëC­•ç·ÔœÜºöÅ5¶íu¶­µå•¤ÆL“Fò!õ,M°à" ŽS˜Eg±èKÝ„›JVEÑ`VfL¦w™ht}¥®³EÇí&®öZÓ!6†0Œýt!dM̉a6`R>da”Îtà–%…Ðù!~™»À†É"GÌ…ÑLP j !"dB–d€NpDjOÃ%N™º€.j5<ËQI¿^¾ ûhà pÌ  % SÎ3ÓçØ¶ŠÏH+h`=óå;Cö„ËŒaÙF9[®„U_´»Ú´ÆB²†Õã¤Ð—ÑeIßl’†9¥pxÊÏÆ9ͼŸÈªxTÙšѦ9Í\X7Ò†µðvàfù½Ø8ÔGm5,úSÔrÊÀ’øšr }ù%{~â+Åkxn\]œX¢\YªŒ/WÆŸ,^V/Œë”ËÈÂ[*eU&•§Š×‘ôÄ#³‚‰pQÛÖ„•­0¨ÎR§®Y ï”E~ºÔµµh­v•Ýdb–ÑK+óÞõįGmÙ›Ÿ“¯i•kÚˆrS.?.]¡Õx2×UÊÛ˜rå‹ñ÷¬ÏPP*â$£78…¿úúsS‘ÁDì4?Û‰v üÉó§[`¯ð¯«foü¼#ž:ÚÛj5¨`•îj³ž>ù\[ûpqŠÖÒ¤æÄÑoF…äÌ)(<£’ãî½}°ž-xµ eƯí\,¿A—“ÞßÞé^[NÀš7•¶3Ù¾ý@[±XÌ-,ä”\¡ì››Ÿ_Ÿµÿk+‹ÿœ‰”ÏçaÊ.½BQC `*£~óÍüÔ¹ßýˆ™ëø^>ê˃ÐggܰФdÇ'Z2ON$¼Q±; Æ›:8;Û—¼²ä˜ž>tæô:JK°D•ã ="ô  Р‰ŠñGdÌäèÃŽ„tƒº—N„ˆ6=Ù†$a .L»eñˆ,öߟ<(Éž?î?ó¬•fj*È&ÏL§Ç¿³Ñά`0µÃY#΋N÷ÉRßÍ÷ºêV©==­÷gŽÉ1÷§®ÿ¾[#=‚Ð-D<²pF+È=7ÞuÙHå3«¿>°"ÔåC ¥ õ°6’ jãAœ^ñ-}ŒÇSc/Ùo«‘/UI ÂÎ…ðô0ôIpøbqpù D É"fã£Vù¢-új™<†ìÒ~]2 Mq%ŸVƒ„ßHùið“hIP -‹l·Ù‘=ø·×£¬ „Ñ#ª!L˜ŽFŠÀY3…&j1"&jµ Fa2MhäSµÆåÏ®bö4Û¸-Äëmæñ]Õ¿Ù×0Ù½IvnÊ~zþðÓSžÖè‘¯Š½­1OKÜÙ”q7æœõéCµ¼³Iroˆ{7È®&©»¾ä=%åXÌF⎵qW؈ÜÓ,º›y÷†¨§…ïiÍ»ëâ]U)çê´·Qv­“½-‰þ-³® GÓ_ö7ür÷ê·¯òm^ém¬úV½­ÂÊ2(M¡©#I 62I’z‚D¡\%M$eÒ)’†3‚,Gõ•:½Uo¨eº¶±¯@ÿx²,RÃêLÉJ?îÓ&Chr—B˜Ä‘ÉQc~K‘„MHPÁlØ˜á ’Ï€rT~„Ʉɸ®êó#ôÜÈ¢”`#ЋcFñ¬Ã9Iø+?ô›6ÖZl´ #´k-ÔïŽZ"aS.¤O‡õ0*%`’‚ª`kñÇL`d´×éÖ"X5aÒãe¤ž¶äÕA¢£ùKo,˽bÆž£ /I…ʲœ=9lLú 9Î ² ú$szx»ÅÆ)ŒòÕíßÄ·dh]9²¬'µ²½^ó«K˜ò3uþ­¥Ù[*þª6ÿŽA¹üDáú?Ø/óØ(®;ŽWj*‘ãcï™swfm|õÛëµ1†ˆ£9ÕrŠÖ{O¯±¹Ú$mÀö®×ÆÐ¨5*J+µ“„’ªŠJ.•(JpŒ½»³;³³÷™þW‘ZÉ YJþÈÓWožvß{z3¿ßÌ÷ó[±ðV^úÒŠÔäÊì%åÂedaJ•¾¼j¹Üÿùæï•°ŒB£,×”t>ò“yÒ%ÅÂô©F­VÓ´ºŠfq®g&CHr+óÐÛãš{ÓúôëÅÒô#w/È+ÌL/ÛyÒo>H&]2d'±ÏÞ vn©„ä"pÀ^§Uþózçß vEC¯pÁCóœu×®ÚǷџܲůp¾Þ÷þµ»ª\+ ½ס8Cé Ãâ†íêoþûpX´Ìû-cÃͶ¶|ôTÇuz¤à±ÍºŸm©ï›Ÿ³Ý™·¡þó¯í(#Q–@U ¥ÁÀœ›8ûµÙe2,Ü×wíÛБÍfsãED¼'}øþ¬ž‚÷Ž¥õŠ?aš¹üs=Bе\nÈ|]ÁÀ¡w(èöÏw‚ÂB?l»t±%z1Ä‚ œ™i…#aÞyýÝ–¿þy¿oÞꟳFø#ÿ‰Íõ%:Q¡SßøÀ6{Çks=¡€“çŽÂ†L#GDì™»c…>¤œAs@òÝBð XvîÆ¹Þ׈ìòG¶6”¹Ÿò4Ïò'Îýî™r&ŸTr> %ÀÕ«Ýï¾Ó:;cà¿ù©Ó:ä{9nï7Žÿ/¡Kœ1±Ï7 wj÷q­¾Àomíõ2ÂP†ªõDéÓFdv´ ÞäI*>Ž>(€mÁréd¡4¦ºÙð !ydÉ  ˆè–gÇð”OxÈÔˆ>êYrŸx?¢€:#ªø˜ú¤I¸é› Â^$:¦J+SEÌ#ã‡e)‘”KžBiX%ô“׺ ýÏèZ°Š\=ERàÂ…йž$(2W¿©-À’“VAcŠrY_IîoR÷n£Ïýd͵óí›ÂÓ– ©vSÜÚŠv˜bVSÊiNuÖÆìÕQ{UÒ^·ã¹¾:f¯‰ÚÖ‹öõQgm¤sp…ho„¿¦{ÝR4²8íþLsÂÖ´7%­@°U¬³.î¨ÙŒI‹1Ù^•:¸.Û^qšDG}ØnÃD »p(`¯ý¤õ‡SÏWœy¢¬«¹ôÇU¬‘!iDCpR*A€ƒÓ˜Â 8a@q†D ¤Ö@Q ùÞªÑæ£>…ÏͤΕ$ÜÅ’W! ʤ“ű2:DFÇÉÈ.žÖ yÞukãnEÒ£ÉäPN©QR/™'Ã8ðhÈ0ú¸K åï43«YMž–®a ïuaâ¸raDv –v3¯fvB÷Ó 5./`uZú‰6ÓíÓl`Lûú ¥›˜µ*]W’¯"ÈýëæUÂ%Á¶n}ÒKc²¬¤Ixp ©¸—ÈŽR÷NÓÙ‘¥óÙsÉ™Òó­x£’£ÆRŒ–)ÑêëôØWQêmUâ¢&ú&Γ& â“ùÉé•©+CŸ™R&/ª’)”¦äËåþ_]Ð?Û,/S­éy]Á¤¿?”¾Pà=X¬ÓÒ8 UQÅè«ý•SëÛ)]Il`Éù?®¦Ð»ó³“ßO¼e¦^®óĦò“W .Òevºè󫯇Ã04ŠËJjJ‘\m Ú3¨ƒ„DÛÍ›§¾˜ûrVÿüXüW—§v™ÖÒ ¼˜˜:÷`1ÂÒVýé-{$|ôËÏì{~ެע„üýÄs>_v çüÜËK}ß‚B;çï2–ûz\&R­aiÕ(i’úøÃÒéô¢ý,ü×ö¾kß– xÿ"eRiÎxê‰'I ¡qŠF©í›ÙÏg­3wÀ^;ÄPßr¹!ç é䈈½ß°ñêÙV[ÔiÙ:3×-D»ÅÈÑpèðí‡êz5mª(;êÚzýZû|°ûµó?bˆÐ*­ËºÅÏà¹ã€ 1ñp`î××ñàtÔðÛE¾›ó[C|[8þËÛsû‚ü1žËýëìçÃÝ!þEŸ¸/ 1`Å$²ºµµÙÕ¹½D[¢S'·Í}5²Ë£õy{w—'"/{>—ÏßÅñV‘ïýæñãåçÁ Mvûïtð‘ƒßsëÖK%FD‡²¥X)Žâž=˜uèICúŒâiăGưÔ8žФÄdFh°›ðØêwëw’;jéJš&µ,‰0”ÖR«pRFâຠ…r/ƆÔ1ä³UÌ‘exríŸU ê¥<4„lfÎVÇ;ë#®Æ˜Ë Œé0Š]®ƣž³Õúm5 ðýPg}à¤Ý”h¯‹[Í1[cØÒ(X{³`5ó–zÞRu˜E›)cË’4YÄ À«)n©MZj5!k“èlìM¼½!ìlõ¼ÝínˆXÌ‹Iì¨ Ûª#£Ø¹Vì¬ ;ËRMq{CÔš£€`ßf|ãóØãk-ffKbÐÊ1†ÄHÓ—«u%¡'´:BK€}Aa‹S,†jôZ[ú§=È—'¨ì(ÏÅ[)Ìz‹’Y­N ¡9ðÆ’^íÝ1 D'íѦÜZð}n|‹x•KÅ79B„Ô@ À$‹d?ÆGðÇðkÛtÅï#ÃÃJiTÇ{ó!—€H362Xtý7di1I2å("?þØÊ»£òôH¡4.ÏŒiŽï +u ­$5D)¢^çÜôöë46ŠóŒx© qï=÷ìmc0Ûkï®Í+©AJ iCA0Þ{}p!MŠ`½‡× j›¶ß"µUB€,AÓ @¢V­Û‰ i¤º©÷šsOïa¦m©R#ù’U¾dôh4ffßÙyçýÿž•¥¨¡ÏÒØ6¸*¨+ba~ÆÈ|Ë4å€4µÐ8g"J)Z_8ómiL;q¦éE«\Oª)\Mà*Š0heÆþ§ÑÔ{Jiüq HùÚ’Wuå+H9./][Y¹±ªvC^½¢®“‹•þR|Uj\;°rò]ŠË¤¸ü«[O¬3›Í¨†TiaÎ ªá=Ez×>ˆ"ú#ÚüKÿöÒÒ‡Hõš\ˆ×=xO³h¹¡ªŽ/­]þÎÌUe%þ­ê‡ªÛ¿j¶7Q¨Ú@ieZ‚~vËú|î9‡À›Jõ±ÂPší›k-‡ÆË1.^¼ïÐÅ·{ξ¹;Ý11ÑÇd^çÅ»ŸìéjEP…YjDñ—zÖqü8¾7ù¯×3¬g¡õ Z-&フ|*áaØSÏlm4& Ã(‚´¶wó…™jí¿ñW«ÕŒÆo¶ÿã©V«óǵJ@rúä)à $I«ñ &ýnï…·)ˆGRIg*é^¬4„ä9?ìEa0“v'¦ú"ؽžni ´¤¢î‡»›î}9˜Üÿ¼ïù-¨7ép *#fÛ7‚ìÞºq$üb÷ÖvFÓ*åß>;˜f|é´3ËÎ$ñBßCëˆN§\€™Lr€Í8Sì~±pöç?{áBðåtú­¿ÿÓO÷¿ûÛbñÔdb`ÇS­ZJ¦ÅeÐEš ÍÅØKIÎ?ñça³’ÂS4²+5åá’ýyaˆc}É„'“~äüøzñƒðù§’ÞœI»á³5±üÉðØvYB¯FhѪ[2ù£4BFZ#å !AÅQåtŒbƒX"‚pLŠ5Ì„”3aB ()PŠ¢¹À¬.¼UHñ—B˜#Úì¨.%³Q¼E²s£(Œ âiò¼îƒ†þ­È:Úd ´E«)RŽ!Ž –è&fBH-JPˆr¹zWSý›Û¨ßìjúç¾öD_'ãÚ,x·BÜg½]¢§“uw€.*nû´§3ï´gûí…¾®JßÉÑñ´²>K~ ³äë,¹me‡­Úo›qØ EW{ÉÝQôÌ•Ï:_y_ç,-æ(%¸Ú¡à`!àä¬Ç:WíYŸ%çoÏZÊkÉavÚŠ®Ùš3 °‘óÛ³¾ÙKæÔÑUtw› Ž.ÁÕ%º-p“‚·*ïiϹ-‡½Øgyà°H{ºßzçÕ¶‹ÛýVÔÞˆ­×«õ¸R‹*L˜j 5Bc«ÖꮄÆÄ xkÀTϬ[uô9Åï7²€Ã1¼%jb&D”G¨RP[  AE1¤®„°j˜¨„ðbÍ…‘Blaµ†¸ 0f3åQ|~ÿ RŸ R‰@먊#)Pφd•PC9`Ã+ÊaÎùõ¾¥&¤Q¥o;Ý4W"2é¬"X;Z}ó°Q©¦1­–P*º©_œÑI#rnƒ©’)ŒÉjc4x˜(Å(Z¸HŠc˜Asc ª¸2ªË[>CÀÆ•0R3Çö øãˆÙ„+ÔF ­'šž^¯¸D¤ëË!Ò•ÕÒe¥'fâŠr|yíÆòêuå÷U‹•þ3ñÇ*7ÕÓãXyü1øE)ŽÜUÒ(J †FŒÜ¾y™J®AIʼn]ŠüUÓÇÑej\F#ÊWzpîY»¶,}¥tK-]Fk<Õ–Kã(<éôõ³X×0×Tñh3ÖÕËBÚìld¦ÎqéCΑJïÍ oð¬—Oɲ‡Xv?“f¹×8þ¬Ã »Ÿ÷%RÃÑÈNB³¾h ¹”Ð4;º)“>Í2ý|òÏœJdö.´¾A'ÈqN6sHÜ‚pú÷·\kõ¨‡þ„‚t|P›„@ü=ÚüýfûÚo^ Päò¥÷qƒÕœT×7º £»“©Až=6õ•‡cŽ ‚w±ÒãÜ,ëb7hËsÃ9ñø÷_ó´Ð:NP*ã³Ýæî¾Ìro|61Šìþî6µž’™H3®Ò‘˜FGipU³‰Òcr™×±…Ïù3i:å?Ë:Z#,\åaÓBê4›:šÉ»û¾‘’qù/ÞÞyûãþ Ê' Æ›·zYÑûÓSß#f˜Û$RÿjoÓ$;ôÉ_~ܽ™2©Ön\küû—Cë“GS½‚èä2ÇyÆõèùñ¿•ÌxSïì?Ï qŒ—I;Æ™L{˜ÔÉîM„V‡ÑˆÌ¤ANôàRÌ$F‡ÕH-bžíyõÕ‹èô˜º8¦*U•^]4Å Y@hc¡E-Œ,¨!¬™ŽÕQ¢tNQ;¯FiT]=¿:ÃÕŸN¨£¯ÏµP„À\G«BŽcr¦6cˆ EõJ84VkhìùÖ†ó;Z?êµýÛaϹ:ò. 4¡iî³d½-‚{ïÙÀyŸäZS­_‹èmË{ Zkf°%u¸­ìè,´åûm9‡wXYW'çÝÄx»R~+3`gmŒ¯#ãmc}­Œ·%ílž7F´à³ÏkDtwÀñ‚q΃Ä*x:XOà‡ñYØ6ÖoM{,¬×*øìड़g3”ØßUêë„*œðPv`‰è±ñ^›èêš=Ç·Iðu±~[Úg…&:ª¾ž‚û)9ã²Àý³¾ÙÁ€jÄ!Û½}¯¾°þm–žæV=iÈQT=®[ŠÑ«H-NâzLc$qEêhš^Gc½›uïì3Lž!¤JŠÈJAµ&óc†B„„ü‡ýºmâ¾ã΋M­xjž}ö=ŸÏ‰Iy´cœPÊ“@í¤j…ekéÄZHlŸí„“†‡‚¦n̓Ÿ’Û/¶J{RŒª[Å&mÕV6iL”U…$¾óÙgŸÏvì8ÞÏÐÓ¦hBŠÄ›^~/NÑßwÿóýýÿ~~’|‚§øK®eLy ãQ¥F*ÓãTv¤<,H€è"Œa³Ã¬4^¢ª !ÃE{™©ªbØZÿó®Õà„Å ^ èå ͤ‡Þ@!˜†®¦ÔÇ_Ââï®S~P±0/‘ÂpqnÊpÕBP]G%_IÚ(J²K®CŸi~‚̈́ʒÃjùm]:„DÆU>bÚ¶^ebž!'kpMµ‰Z;ÞÇ$®5®}ñêÊü¥’”ª0­Z¸¼&ÿAéâòåJÿùéŠÌ¤ªp¡²p•ÎN­ÌM®øý°Q¯¦5z¢s˪/.˜ö71\ƒâFg§z¬[e`ŸÑ#Úol­Š_7,N–K×Wä&×ÂÄ–k>…É’ÔdEâZiá&R¸¨OM=½©ÍÜXû³à6Š¡˜úJj5C£Üž÷ò.Â=á(pÅ {£B¯8wL ï•øÁ˜è½ûY_×Ëf­†ÖÓ& 5­¯E~ùk×gìqeàÞ]ohøÅû3vØó—Úß Õ}àQGgg»gf‰Ñ“ãßÔãU8ôY 7=u¥_„ÈËf³O:¿:þãXü²D!Ò¸¡!(ÅY¢bßËÖ°à„D„î”|,*öCx-Wò|°.ÎIHÇ$ñä÷¢ü)AtÿT»žD‚Öú:£æÊÕ!>âá#‡?ù«=àß½m ÉÒ+)DˢЮ5,ÅjÔ¼ÅÅCbÄ Ïö=¶F¢ýáp·õFïÉÑ7Á`/¼PB"I :ýÓêÔdÓZ£›¾Ò‘FæÞÚ¹£–QY´Ž@– pU¹‘…Þùñ¹3ŽŠüY‚dœ ;Š]€0ðÄùñ¿Ï+DɉØ Ñ>‘÷ÌÎ8@†±°sòýWXSñYXÌP‹ª{dz<Š,í«L–åýpHƤ'ðLˆÊÀ¶ï'ä‘  Hþ]&ãg–º\:H@pä*èI“>ýÌëþq¢öäNã‹5˜!1 ¦)hiB­Ãh« (LC18É41L×ýÙ] ¿ëêÝ[îÑÑu40·9élSœSNkÆiÉ:Í9Î2ϵ)Ž6Èñ8·9ëÜœè±ŠÜÆ9—Eè³&À-IgKÊe–ÍÅw (Eq·¤<­2×uØ$®CâlqgQŠ«#Åu(ÎvÉÞw´Èœ@ŠÄ9k|)Š@™Ô'à% &]$ܶè¡0 (ÑÛ’ìm-Þ×Ý¢¸šeT TÂe‰ƒU8(˜‰MäZm …³¤æl9×mÎ÷´ÊÝ´ÂÕ¦<ø6¢\GÔa‘¸æt_kæ€5åhOzÚ§aÆÕvs¯-ø\ÎƦzšÅ«0ÓB{K£j=Z^­^SMP4ÆbˆÖD±»Ûèà+êÛÇË gKù@]b¢.Ò˜÷!¹ ž–|¿€¨G,IŽªád‘|xjÂô­^ð©ãAƒ4¡-Œjs!unD?'BÈÂ;è·™Fükɰ*l—yýícì ’_5ÂßhEkËÙrÞª/ùKH—:«üTê4–+¿}‚:ÿ†îÜkÈM¯ñóÑZ9Èäš¼O½0Š-Ži—šgn”V~¤ a9¿©0AD}JÈ —ÜcœÛUZ”0„ž*#(ªšRíÛZy÷lê†A™Z“»¼²0­^¸P•¹\’š~jÙÒÿ’©ðÁS… «òSHæ^¸‚}ì¯Òc*’D;Ÿ-MMé÷ˆÎz­V[O㤡²’ÖT™ðš¡×ÊRS« —*R7péjÙütÙæó¾záÆyª4w‘Í_Yÿ ¥\]‘Ÿ*‰}Hy_ªaT(i@aÉà«Þû髳üñ(6Yî‡x®ØHÎ HÂ[²èâg¹?Ü´¶âF-›¼ÅžÛ¬ùôoß¾?Ó7'þø–k»­~©;wîùþÈ’[œèŒ ÇDÁ#‘A82ÃÝßeÒÑZH7-ͬ¯«Ç¤G ÉçóO:ƒ¿:¾s|,手½Ò\¿(¼ŽvýóÞ©íÛš1þLxUuS=úáG=‘hó’àýûçö=ß2HŠtÇ07´š çõj$æˆ  q0>$ˆCáH?(=~òüø¯šåûb’wv¦'!y¢¼G ÄDøi÷&æ„¥{:[HºEt:jýn[yvyl„Ö¦ÇЬ_›öážõâ#Lü4)#‰ &á¹ ™ Êh%PD«Y2ützúVD§?:ÁÛlª-¥Ô•‚@ º--PDÍŽV¡ÑÔ ôžSèù Ú×~È‚œfH^ÙÞPÜÐ!sÁ1‡”"9ÚãÝfÅaNƒF€ N›Šp¶‚²žŽyK(Å*ÛÛRîv°AÌÙ&»mP’Ó’pXŠÌàÌ`B9.ËCKX“([Ê×´À ºüpà‡‡&qXSpkG;”b·);HнC8[²8ÿ–¤Çú7pY ÜWæ€=E¢@ÁÇaPñ¢O¬Åi»‹ÐJz¶Æ]›bÎŧ€v ¨LêÝ/>¾ >"{Úå^kÌÙP°7†í–‹ßièÛb|¶7âd5ùoöË-¸‰ë ÀLK†ìYÒjï÷]ɶ° Ô-¤†& mÄšt ‰MÀÙ–Àæâ@’R\dYÌP2-}h:ä ÷LK›LfhÊ„I(Ph¬Ë®´ºË²,m1Óé‹é¸%ÓÎüÚ9çEûïîÎ÷ý`G–P$ı@þ(’Äi’àhÌ,óÌüïª']oE’#@;»ôi‡!á “]âCJeLB€Œ-Á$åÀ’K4#©øHíÄ2ûðÄ!:îÒå;5’‡‹wSê/àÈA¡f)Ë3¢ CP¬øå2Á³‚Û[MWUB‚”1p,7…Ó™ýÅj*ýœ_]…! ;"Qf>e@¿'Lv½ªû²Í˜ô%îd׊=Pdâ4€‡Š8¨´SHw")¢ ’NþH <[Ô‘˜¹ ¥M ˯VLú°²ñásO¨ýúüI*×O¦¦=*ú÷C™sOfÏ@éó…É>XõN ‹*yЙhîG ÕžéÓ…«£[€óC˜¬ôÆoõj¤ö%ÏbÇ[ÑØGšG•Oæ”9©U˜ŒÊž)V¾™óê3ý¸ÚûDürå«hXÏS´I$Ê9Të=»Zn}.àË ¿ªJô¼6Y~#Ø 7\úS]™¦0“@Qõ oÝÚõ7Dåfw×b+4±,‡23K°›w­=å6ç I áP½ÞäìþâVSy©Ð  K3Õk~2f#Çÿkd2™±É!Ì©ÃÃ)ðEŽ}…)ln¢ƒK{O/ ølñèÛÒ}’ÊRSHn ñ¨hªQ‰l”CµÙÞS[A`ü¹ï—_½ö–ÏoLÿô²eމcžei’7Ô. Ç÷}%½®( ’¿A l9´ýڕ͋痑ŰS®]o ù~lRwM˜Î![8Ú Ö‹ö‚µ`é°¯bi Ghš†hRsø—5²²]ÖGuŠÔ ¼õÙ'õmï¼`o_tâIJÛ_Zåà¶ ¿ ©E 7º™T<"YjˆH{d‹ä·…€*€ %YyÛèòk¶”pð]°yÿzu=GhÞˆ£Ü3ì¶•«NÜÅ'ìúÌÞï¤U>e‡h&j)q7–²³¹Æ‘N6éÐ&=º!‘ÚÏN3ÕÍÄìȰ váNȈszÚÉý¥•g¹~‰Y'0 ‚²$ü\ £ÖLÁé[B²‹i¸yw|MU´~”û@$€$ŒÅC¸ÿ8þcÄ,‹–ª¤e^¶À·õ;Ÿl\phE©m®EE728KãCÑàl§I LM ¶æ[ȯkÙÛm<àu­vCw|c£á“.mÊ¡Qð°“Lt!Q'qãQÕIåÌxõ“:hŒ:±”›òµi†œÈßìÄæP˜€sFáHLZB¬€0ÁŒ<=»²dÐŽæ;4y—øi›f;e3#>eÔTzˆÔ³”( æ•s ÷ìFIÚ®K:˜ŒÛrÝ¿—w²nx¨¿žM»Vu!—›ñÕÏb¸gLf5¡ÓŽí,Ïj¯&ºh¤QÎë†Îg½ZµçiµoZîtÁH‘ñÂÙ¾©¥Þ‹çú loaöLAº¯ žŠõ0wMb)–@øï–ÐG¬å¿wNó}„ìûñtª›fOµ!ïEÕúÔ¥‚] %WÌ'b— ùÞÉÊÙ‚‘óÅ `)ªSO?:k:…¨S¥³ÂŸ3Ò0 –$ÑJqÖõ?Û‚r“¬X|¾–Pd‹pkLÙ+-!©9mü‡¿åè‡Õ•¥ß8öþë¡À;a¹öêß-ëjfþ”£Ì„Á(RÜÊeeÇ¿)KïJEjf* §Ñï«)ãžoçϬƒ€™D‚Qôðácê ` ü²Ùì¿(ùŽÇ×3ò÷Ç¿/Ìî¿õÛw>7—Î]úMÛ³ë•1xQZB²U [%™ÈEýÿ€·ÍREÃOñ )Еå(NB²y-VÆÐ0TH ú™„éƒæ"ÿ9ÍîjÝŽ²_f±Q]gŽZ©¨,Æö¬wßfæÎxlC0^À†„5Q(Q±ˆ&mSÆx—ñN „†âmÆÆi‘ÒðЪ´¼'˜Ð´}èCHi 5P{æîw{ÛÜãåÅnÝDJúë×Õ}º÷è?çüß÷¿ …F¾©]…ÒzïKpjÌ#H˜fš_ÊÒúñÄàÊÄEJ»hНPGt3}‹£" µ~*1²$Ò_ÿeA‘Ã'Ž˜Áìùâvææ(˜(Ž(¹¹1¿$—s\¥ WH‘êûãõ7nzÇÆ8®yh`OÁj'lÊ´‘$S,[LftàÌÎm佇• ᇾ˜Ú(„TµŠÜóõ·pèÍc [m˜ÅlÈÎͧœŽ5wîÜÑ´Ä2Î9ÉÌãø<ý•йÚ~VHæâÑÔ¬ìe7…3LS²¹ÔzãVÝœŠŒ?œÅº(Ôpa"ƒÝ\0mçËÐØqAª ‡ I¶oˆ¡²óXÂNšM?¯V‡#‡nß«þþþ×Y©| Ž¿°Írk´îÁ_D:%Kå‚X.©uç±ÃÁÚ#úãSÛC¡ …o‘eÏB×7)Rƒ"»Âã¹|AOVÙXà@†úÞÚº‰vX͈q%ƒß;ÿZ(RsøðÖ¶÷Æ+øpETm‘Õ:N¬Yèc±: "á—×JB£,6Í=µR–]‚àæ97¨ÿã]ð]ù_ÛHH T'…ÿ6Z^º>‡ÄíºÜaÄOìõ³öøóL<Õ™¥©TlGj#Ñžìd7”lCSg°é.2Ùƒ+ATwôZ<Ýe[MÕÔ+Ïbv³©µ’ c f“´Ù¬8ì4f½¸ÊþîΜ?بø6¥¼“îÕ•/WÇ+7™Ë/œã_ŽT}ÏÄ}U¥IwqúHÑTeñ´ký´«,æY÷NÔn¸ïÙpq漢Rz‹ e #£i±0,S4„[a‚Å­vÒùÎöe7NäǺ±:vÖÆP%@ÇÛó&Úé ™Ø'Z-ñŸÉ44':³ç=B]Žçó—ä! …‘kÈÌñvƒvfét;ÝÝxh´a&‹3(aÙf…£¹RGF"`ý]]ަM4ZµšfŽîZ­œpNvã§sK(‚²­Fˆ¯Ý<ŽO¶:µnz†N´[‰N`Pö™"„絑3x¤ õàHk­æhÐv¾‚]oË2¡6P ¡ÿÎÆì;¿Á´^“vyy´Ò®é^6lžèÍH ë½+µaä?ý)y9#=ÒÅ.eÌ ÉBYÖò*™‹éQ‹"œßEÒ×p¥?SøÕm(GºH4î¦s‰$pÒãŽÚƒØø‡púªI„´KOÅû¡©A6Ù¯_,™ì7D?_[,èÒÙõ8a$hŒÄÌ ¹\e@6©Yä¨x©#ª*7†Æ=²:p'äDßÉ›òÀLˆ¢,ASƬ5m½{hô®ÿÕ}ÅVÜB™‰“o?ë~Q®y¿*6J’Ðj¾þÆñµ½Uµó9§G!h™…¦öíÛ«ÍLƒH§ÓÚcyô8>wDå8É“RÿKÿf´sïž#1 Ž 8HÓµkÀNë®$ؾh¤pç¼R¿h6™¨ UD">s‡Ç<À®~p¨È¹ …À Ãx=%ÃͼìU#Í;M8BR8h'ÄÓ,üÑÈ.TO‰âÁÛkÇÖ\Á 14à‘¤c²r„ç.t=qåÔø}¯"Ö¨òQAhä%WH<ý×?ùž¨ún?¨y~³ÍŠÙ-4„¡z×Óh0·F¡,T+aOLiùÆn <ïާÈ~Yl„zð7\®Y9á›+Š\1a~ç_¬[L/ä¹ê÷ÞßE:Æ¢£Q{‘cÅŸ:§!-hJ¶bÝT¢´B µ®Û ÆO-ˆj(ÞfˆvSA<݆${ôŸG[_cËrI¶ZiFµ£Ù n"HˆDtÏ9á¶oüé2Á½aÂU’ô­OøŠ“îÂ)OqÊ]soP«·NxËæ0úDKþ/'ÿMF*KW‰ì.Q<ë"U¥Q_IÌW¯Z3åÙwmˆz×)5E¼¿4Ô°åS÷³#{ò\ey[7à0ÊÒŒƒ"P 5b$¤#iÁ÷®2]¬€Ô€q: ˜bÝP´R[±ØiÛ,÷Ïbñ.ƒ@ä.ç|ç(DûÚJ1™°5ÏâÜI²¿¯+¼ß“m[*œf·ç€Nf Ù*3x˜b b“çÐθÇÌ0œKšQ®²cy¡Æ:Ý™±{a‚ ÒÚ_‰M©GxªŠ¬Ñ4ÈЂðd=ÑFÌ·ž©.Ü‚X'š’­™S]L¸=ÿ~ô[OëY#+L’Ù´qC]ïaguéáåÚ°Në7¤/¯Ð®š’ƒúɾ¬é¾ ¥üT?pC¢7 P^ûB’X™X®õÁ“½è§–×uû7“í¯?5Ù÷õG#˜ÖoŽ,­~±`&‹™¦™µ ål,šï0ëv™Æ~mÒ>^® fjƒÓ™‹e#ê•¥Ú 1sùS—u©‰Îc,N›<Æõ ÏÚ÷rü©Zæü×TÌe©I«p û¹ÿrãHÑêlhe ƒaks‘ß^øÄùEÞ=Æúè‡1ËB2y,;.6 ‘r‘kRäÃ²à—øºy[œêN´\¹Rî ²i„°20ŽÐç~ú³9 ÎQ2•J=ÁåEê/w|Vöý;Àûøƒä9ÂÚh‹667lQ¢õŠ Tì8‘ê#’=è¤éŽÔµ®"³)›‚zʺŸ7,Ï/ÖœcïëKT™¾‚è14~eû³š*`£Z¥%è_¬‚l5³,tÁs(e2é|å?.3S8ªÕš¶A¿>zDû¨»Ýc¾¾×(˜£üütƯl=áu²Ÿï#£~8Ò.±D·Jé/¼sõ.GMDI®2‘fJ°‚Óí9ñó³c3”OT>B“Õ¤.f)—³ã³§šòÉ¡9™á‚̰*3¬ I åM\ÈNêü RÎ*ç5Ñ|éS4=œ €&îÿñÙµU88+¸È¬ÉY7/{ó⟘5¨…D´è‚º¥¥#0+Ã9‰?«”óÙÓ¥‘øåå\ŽrW>…ψ^ÁÚ¶.„TF’Äi´ØBÁçß”øVs†¤LÐ ;D¡Qæ=RÀËœ¼°ûäÉf½j]]éÍ›»™±v™ë¯í²Û+Œ’D #EZFÀà&ðõ€"²Ð1é9Ï4ßmŒ&ºÞêzňR$„iuoܸÒ0•J}Wý}{¤Óéož?¥hþ¦õ( £Q-DV¿‡"ûx¶MG¡Àƒ v²Œ P\>}2]©Çó¬Xð|èf™íѨW|ŒØp뎯ÁVj"L:¨ÈˆK ù×®ÛXÑÁF¼W®ºË,DYÉó—.oc‚{Âr‹Ä7~~©µ¼Díó¼ ÅÛBÒ&¸ã…О©®Go¡¿çêbBgBMzT«EÐe‹Š>ÿâu!äe˜ú®ÿ½qu-N@³(m-vw¤•ZCBWp´0°!ÀLYA’Øö„|.Iò€n0A;è9I$êâx/Ô³\=øF²(èeÞo]#‚—¶ ŒC怎<CT š IBOä_ðXþ¢¨ß8Ñ«ŠƒAµoÒ™q²RŽê'zðÌQuê]øn7Ò¿%oUI¡^c ‚™h ӨDÁùPF"¶JÝ…5†îE×KáÆš”£&j_ Òk± ®Å1§5i·FKDOç[â2ÔTù”"?hdº*ä,9—„]WuÔ±<ÚøQ•nªJ´¬ƒæ;ËÆÝ‹âÎ…@#aÇ ÁþRÚþBªÁši.‹û–þËYÑÿÚ¼5¥ˆ^=K‹Ò„Š0’ZŒR«pà pt]z©Y{ï9ršŽœPK‡Õ‰#Ô£^t¢gÎdû'qL; ó~z÷Æüb„(‚ ."Hµ2b8Mg•ª©J-}w'‘927ÙK+½jùÞ±NoÄ,ÀBkaÀ†‹6¨¶8…pLGæ`Ž01óΟè©ô~rsù3Vcö©­ÅzçrÇ`¥{Ƥë9^$ö¨@…%Q©cyÉ£¹±ÃšÌqŠë¥»ë –à8‰¢8ª7š³hßW÷l/ˆ]Ð ŸNùfcê9y(EëÔï8ñÄДK3¥Alº421ˆÆ†f>‚Ògó&>ÉO}<“9g]½Ò„«1 ]„â‹,¦[·=RÄË àä/Ï6Ë¢GdÛy¶ƒa½£Áö3ï¯ ²¿f;˜×8¦õÞ=×¶_–à † „ ëÚmã½¢Ü*òÓÆ²ö'cÝ$ç­¼C\AÖÅ1û×ÔS…”Ec0µ~ýúp8üMJNLL|W1ý=yd2åÿQž4üôéÓŒéqYKèYW¯¹l£Äu„8‡À»%Ñ J–@*µŠ¸‚èœ¶à‹¼ þ-Ï:xÎ&rÁ@ç¿ïÙq¯ 4‹ÒÞ}]?3`4A9×ú}­À7q=7oºÎüîENÞäÅ2Y®›ö?wì^†·qÁÆd¸ƒ ì Nº'Ý¥BÇ?ntѹ¤ÚD ¸Ž¤iÔD#Ä|ùÊ¥O`ö*€=ÿÙ¥u×®¹%~PxãÈWMñèn 6Øþ8ÕÏööÝæ8Ð ,vÊüÛBðÀýfìáIÞ)HpS8ÁÅ'ðÓ×ÿIŠalrÈÎ3>™w‹œö†j W“@¬8±ÞZx÷ðÂT7”é#â½ÈT5’øûåÅuÆñ> "ÂÅx½ÞÙ™ûÌŽ×ë6¾°Æn!-4¥ˆ¤8¾ìÝw0w!°^{m %´RÚTÍC Œ¹Y”¨@”TQûPUjÅÁÞËììÌÎÞ׬§ÇAB}q%"£¾pô=œ9}óÍÿ|ÿßyŸN¿ÜKtnÈ®0"0n€qŽ¡p#Žs(LŽãKˆ?m.ò5Õ†[Ö¤-Õ1Ke̾DvVò–RÑYžì¨–­eQk]ØY'¶ÕJ¶%ñ¦ò‰ÆŠ¤¥*l7=±Ñç423á¬Ø¿S³ú­aûª9÷ÎsÉ‘lÀ“W±Ô%mâÒS»ü£+êø…HÀD¹š«\&‡5™ËšôÈ,á’&1œ¾¬J] ”ËY?!~R5B™˧¹Ås³÷ÇÊ.s]š¹¦Ò3g(À4è†e¹ñaJ!¥« gŠF”óHjDš¥\%Ó²”kLbxþßTçpØ<½®Œ@ÈW^6>Ú½þYìŽï½Ôë·úù]|pïTÓã[Àe ØïÛ(âúuå¥$D2´Š%òÖ­"FÇ̦‘'^ù|Ììøoy<-**⚆  K<²zÜwX’ö ü;¢·-$8€¦\20@ EÌ”ë€l„ý¼·C–>¾ùÛo¯_‹½ùFõwÿì–„Žñà[Ÿ|¶±ÈÈÚRp¡ uø‘öjÉäããÛ¼¾Aê”å6aìƒPÐÍÁ°EäʼC|Ø%…œA¹ñióùûßÞ½6dË#²vt½ìܵÅæ‚yž·Ø@~sg4b ù[C¼9àkCm²ðVÈ×å³G6pŽ­Éa[Ðgþa4PDTÞ3>ºçã³¶¿®Ú²žÞßUÿÕvI<ÎZ hóóVA|¶(B–!ÿ~Þ×ðZÃb+øM÷8ËŒ:c)œÒêÔïÄ”có“nDrc©~øiiäÓ²áÅì4Cò1RObÉÍÓâ:J¿ˆ€Ûk™»;*kµl®Ž´T'[*ƒöå!ký]´”§m¦„µ&ØP)Û—Ç­å`%b6ElË%ûJðNÄR›²Ô>§‘™ ÑR'šM€4⎪¨³Ð ïXìwTDÍq{mÔ¾ T^´ÔH–ª¨µ4e/ Z–Äli[iÊR1WI暈eiÌ\³–ŒÙëÿ¸©|kÞˆth!F‘;¥iåX ³RÙ}ý?…Oôª¦•ÐIäÎ˼ÏÄúˆ‡ƒ\òtî7ûñmÆm5ú÷6£gvÎJýšM»1¿';|2+ÞOúNCŠ«8áÒ¾V¬&ƒÁV«»ÞÎñGµ_Y¡»{JÖ”æèqd¤ÓëׯÝù·zJŒD6ŒYšÉᣛK~·iöÙdº|b.]ºW­ôåfÜDØ­ûôì%õiÒ2<@ èíÝôºBJƒë©9Ž‚˜íUÐ?ÎR™YñsY“Wˆô•9Oëò‰‹Ù€C2×r’Có&†²¦/A“—Ð̹Ê¡\ÐMžS)#Y‰!Õöêu ÄÑs´Úb‹}ù›&¯/T.ª”‹êäeøó^¸®Áˆ¤_®!&†±ÌgryöŒÑÈÅÜôð¼èÍìä0˜£é¡Ù°xãG}¸Ò€ªX' CñîÝ+!‹à=$÷†BVAnö‹Ž1Þá ˜#’#ìs„‚ à>xìÀk1—% JWÀú·—þû~»w¬Uä{Ä@G`¼Y|àöÉPƒÜð:C¡°ùñ£›iØHÓZèÇïß¿ÿØ+ŸsÈ3ñ‰‰”’Q¥§&&[·ü…òi‚Ö#…¯¾H v)ô.ï·C­>¡c¦ÜY|~ ¥N!¬|Ê|ƒB—Ïß&òÎà8ÐO'ðb/¿Ëf+¥Ð\JW±ÔTxë‹m¼ow˜·ýõÖŽuõE‰¢HázV?wHr›o¬C€ …@ËSç1{MRÈô7De@ÝMB¨ãÁh[meÙª•‹Yê…CûV†CíB éÎíöÂB5ŽAy WZ„9³uœïÂvÀi?€Ê‚¾nÁß%;§Šàw‚‚„‚»€×{ÅÆpØ!ñ]<¿óÞ·‡^z‰`æpŒ`)´8þè÷ëÇ à„†üGÁY{Ö4ÂûÛ‚|«ÏÛ"‰­~Ÿ5Þçë9v˜£})Jh8c û\ÌdNÂeŽ ¸É”›ö11TG5ñA4í¡']H¬•N‘~XqA‰ì§ffS½ŠÄu `Å øHƒõQd,^‹ýë%¢c¹l6%ìS!ZÊÃvÓÿÝŽŸÇŒDÒVm©|n_ñ—·kºj˜: &µ:˜ (Ö“0ŽTp‡ŽWà/qƒªä)Ÿ 'û¥ˆMï7H.ct»u.bò8‘qC©þ¬˜[÷è§¥—!s<[9©»ædWäkTZ–2”ü‡ý2â<ãx%š¦ÄÆÞû³;÷Ìξ&X&6§©Ò–"¨’r@Q“`|¬×öšÚæjÔÞË»q¸¤ò¥U_kãPé¡T‘¥U¯¨âØcfçØ{×{L_·ŸóÁ(_xôh4iæ}æ=žÿïOc Ê4ÂÈ}vRo+b>HÆž†+)3¦"`º³0°‰d5†Wᦠ–/NâqŸI8].ûô¢›NzÔ1—Irkc^$îÃc^,æSn,ë$3gÉÜuÀ…Œ±á2ù<ñ÷áÚ×Öj GKe·/½..›šXö]ðo'Ã÷xüëË£;›«H\IèÖ›&¯wOà¾=*¶ñìàíÛíµÕ$ Œ…ÎXc|jfú`°çú¥ÈÑ厭’B»é8#kù#¢x” õDV ö—wW1‹Ã_Þe¨©Áq3at%FLŽ¿˜-Ú`æqÓ˜[Q°ƒÅîP°#°Å¥wlYO`F¢&£Q9ø#8í¬(x+c4îS$êpˆ.cÎE,:4I,xLyWiÞ­*zôQ·éÒÏñ͵j3 ×êÔɘHœÄ´:¡Œô®:ÓG?®“»¶Ýkß,Ù¿ïmŽw4fºšR]RGCÔúÍËè“|$³nMY7%ÚžKv¬Kôm}зýN˶‹»ê63Ô³$‚#Z ‡ ¤Þ‚é*aM5 u6›ÿxÌ’¾‰£zÎY P$ëÒ¤œ«¢.UÚmȺÌI÷ ¯%3JçÝŠ¯£‘¨“Îèrn8{Ép뽿¡Ü¬(­B(ÃÐxÙ¥·(ÞW–z¿*ù^襻·Â(¡CÄ›j)bÿÚU[«‰JÃÓZBHxoÝSŸ;VÀN: ·*ãÔ­ÈŒày1-žaÒgˆ´Iyô)”s2!cn"ëƒãŽ’øÌßÜÛK,¸Þ3’2h¿ý\•æÃ!(=­ÈÏ©äë*ù“ŠÔ”29Éó:yfUv²<7‡/Wå SPqF›÷+ 7”yÚ¯-Λ\öLñšŸ/[\À³sê?øˆ-&Lé f0rOãwÅyHþ’§5…é²âR˜PÉþ²Œ_]¸aÈŽWÈ ÈiH¾U¿R±8mç+3×ÕùéyIOh—[gz–ŽÜ4î}"×V›£yÅ_>â…6‘ ?è–øN‘í ýQ©t]Ð6#ÑÁ;1ŠPíÞ±öÓ»G@åØ'7› %i‘ s%a|°g7ËH‚MŒôýÏôõ‡Ýß#þEØî˜Ô»$C‚=Àf#ý7oôTS¥ jÄMÆÆ.–0$›Éd€V>‰ÇE€zE9Ÿ+‹‹÷ïýãÙÕ&ƒ AêÑ_½»M#¬=ê«æ¬ñ‘©*l 'cƒ‘po8БˆÙÙP;< °ÁàÛm¼p"Ì L\Û×Pƒ£X¢‡M´ñõ7*ÿúÏn^ê‹p'¬oÖO^ß/ÅNòÒá@¸°M„í»‹ ô,·žP 7{GâŽKì€p€QáøÅsÍ4©¦ *HmY]Cܹö Ⴠv~÷覽Qvlâ§ÀРx>d[þEÜIç.Q&:B.ºM‰MÔ©Iø˜¯£‘¸×x‘ªäiìe"æ£NÔ¶}qƒæ`3uáU$y^›þNa¬þ\;! Ì`dôxsü»cHðRuèìó-›š˜©Ñ W[ÌI§!}ΞÁ2Îu‰(;ªË¸´‹ŽŠ‚’=hÞ‹¦¼°4ªÉ ëó`¸4áÅ > Tn g]ú ¯V×@ £^OR•FÊ@"ê+ǙĬZžYY×$§*Òsšì$,ûUHŠÓäÙ/óà&î+Ž· å0¾d{WÚK»:}à+ƒ§5„Ä=¦i7„iÊ€1>$KÆÆ6h0¾äƒ$ý§ÍLi¹ŒmYL’I§¦üÙ™&$MØÒj/­V·doŸÈßùÃ2Ìd²ó›ig¥÷Û·ï½ïç»jqç«$v%3áÎMx4ÊTfH®SÑ© êµõªû‘Ølž8M `Ûè|š¦f‹>ßòÛºÜÏßöÈS§2Õ)FÍI¼…©žuþÇ+WÖ'ç4ÊõuÉÖ­Ì®M]Y«^ÕÄÞEãníÊE!Jʳj -ä© üG•• Má›´¨Îd¢Û´´ÔÃq'BrOzÌz{Ár 8µÁ×åcŸ~Ùqîå]¼ó³ãޝ¥½y‘A §Üj*ÑFi4Ú‹—÷„pìQëˆ}‹wí"× ÆSrzÒ(Â;ý¼ƒ—Z|Â!%tögj n¢’@ÊJ+¿øBXNkf4™Œ?dÙþŽiÞK}ý1~èÀó4¡74æì®cXþŒO8̱]A©”ÈÇåEǃR7™ý¨- °ëíL«üø€<ËKÝ]lß6”BKâQ 2pú¼í%vñèož¶™B\gDõôš¢Ðp¶âÒÆ\Zi„ ã£dÂ…\¸<ª“ûKJs¡Áq’b(‰!0”0è7Õšð³O”Ò\›pÔDì;[µd«ŠÛÁ ¶m‰Ùk଴oØj¤ŽÚ‡.£ß¯³:kƒŽJGMÔ±3b«QZÒï:é¬õq[u¨¹êFcùÁ-F EnÅuÄ`уXÓÆíámôÍÞ"eL£Ô!Mx]XüU"5\ aêkÆ¥ÁÜo¢‘å‘‚à68IÅ'É䢑ñ ÌÒ«÷šA9_$¾bjS²?è¶l%IBo`M±»Ú¥—Ï!êHvj<ïÒþBŒÉÒSåE ?‰ÿ$\¹Ëç±È8™&ð C` LdËã™ÊX.ü[x”ЏôêÁä1"0HŇLê )ñ2¢ŽcÑ’KÍh©1fŒ.#p=M#¿×(3úÈ ¢ÎkRîìÔ¶2O$f²Wf6®V哳Yê|~t:'hqM ¨sgEݪ[§Î¡‘iRñ˜Þè-ØLç’: A"&]ÞÞí9ÿ½|?Ül~üºfi.㫹ìO/fo#sZu_™¦–ug¦æquYqÿP½¶1æY½–›\ £³kV®d®vŸqφ„;?:³îŸ¯×[˜¢<"¯ØhÑ¡Hß?×ω­A¹—g03yÚˆEƒ'Áº'}wÉ¢]Vš.¾ÙÞ•D6Ñ$ÖÐ`ê=¾ç™_×’Ä ÑðXµŸïçó¶Â(“ø.YìM7Î. ½¬¯ ü Ÿµ‹²MTÝY:äçN=±Ëh†÷“z’h|êÐË5¬ªÉ‡*ÚßÙcù~~aM_y‹ÔŒ¶¨Po1ÓYSïíg¹nIêösM¢àüÇ”ºIÞÓÑ!Ž|u·)¨œ„zè•üÇX®8ÄÑ^ñÂÞÊOn÷ù@øÄ^‰oÙS­MåfZGQE˜I\séR£è‰ó;á·²Ôç÷ö¥ë3к´Ô$®žF‚R7ëm‘ƒ­¬pÐ˵sü)Nx¢Ëbÿ_ÿ¼Ï€jŠä§¼„ºù¯N/ ¢|$¬ô) ~‡,u l»Ø <³ê<ˆÍÐM~?4Bp»ŸëæîŸÃr·Äuh=ýäf³nÛayã/‹Ƥ£Ÿ2ýçNggWuC}鳿,ÈçüMß6HàÀS¤‘Ï@K’мqÑyëãÃFƒÅH’$Vd,@¦Ž˜âc:eˆR'(p…ò –œ A/þvH[_–]h*ƒ4Zi"ÝãàYtT-•yª¼Û´Mtì–»¹¶­B{…ÒY¥8j…–ûÖ¨­:fßµíPZ«•öÅQìØùðeôûõ –bÛh¯Û¶sí;ÅŽŸÈ?;¸¶ªhky¤¥:ÑZ¯Ú *o6mê¬7Y1$ÇXBä“嘾„6a¸±ÓÙëònö›ãC†åq³2‚†]hÂE)¯`ñÁõBÎ7ш:„¤ÆÑà„FreGF°ä )5H/hC¸:ðˆêªˆŽ3Ÿû6£b*Äi e=³·T˜ÈS‡­êˆeq³íBP²ˆ!‹uغ‡uù‚>2†A{]Ze¢0|Ö6„'©à$)¹ôÁ!Cl˜^%Ã.]t ka“tù|¡:V$• Lx»ÕO™ñL#fÄ 4MdâhY÷3:ÿ sÂý#u ½³&y#?:«û?h$îÞ˜òä¥<)@’pç._ÍJÎgç‘•é,uÎòþäÆ J¡£§ TÉ‘ºœÏßÉT2àNnAÛÿ<ý³ŠÒ2]NfØL¯?ß¶Vœ.P=Ú°]ùŒ½‹«óY¡Yêæ$óÙe4yC{{£ ¨ã!V»ÏåéõQ}ˆ]Gº¬ m ¤H_ Èßß|Ž€Qm×OàCý-Þ{­áPŸ$—@¸v¤l¡ÈJ+ýî¹j¯ÿ%¯ïE^ì8÷¸‰ÈÔk‰/ï#§Éág§ܙݑÎì=÷ü~GOÁ0<>6 Td.óØFʺ—ËÞËæ¢‚TUQf¦LZµ‘å÷toˆI= +L¬§™]÷Ñ#ô‚czPt‹rÝL¸Yˆ·M‡Þøª+Ìwó|;¨(^ìüÕ; TŠT7U›¯|Ö,ÆjÝ1awànW™Ö¨%) W¯vÙ¿¦ÞƒŸbßz8ÚÃ{ø°Gm±˜[à.4Ÿ™é×Òa !ùkÛ™³[Yóá/^¼yÛÃqm >¯}Ú¾¼2¥ˆ†(7ëÏ´ Ì!`ãÀa$© ·rlw,Ò˲- ·‘ýàrÏ ô&@ïaù6`æ ×Î ûBVp^ÛQª§ŒJ‘ÈS%0eÛWäûnܶUU :M©½¥ºb¼çaÛïbh'8 0V„Yûýµówš¥Ä‘·z7 Ȉi)%öÜX¦œ{ÏøŸ6÷’缋SýyÒûÊø€.ã+Íú©Œ_) h²ÃxÂ+oæN!àiÄ%†qz€Ìù¡´Wùåd]µz VL¢BY´¨¼mSÞÌÇdfì[¹ËEñ±Â̤b~”X0å'å³#‹Ó£E@HRd©ósc…ÙÑüÙÉÅ™óÏä.D'+woÄ1´ØˆcíÛ‹¤‹ªÔ¨:{¿6\ø]s¾‰R˜ŠÂ*Ú’BkÛZ•8å®<‘ù]^n OOœ>PÞTJ8·*¹) *¹•0²àŽ’ œæŠ˜­wÂ^›rÕÍ:–§ÝËS븎Õ3ŽFÖUŸê¨ÏÚk“6à¢ëfíuܽ|÷:½Î„«µÈ„jLZ¥FQƒä½¬Ÿz×"zɈ×õ•DÉo²é á-ËzµédnP›ú)Æù¿÷§üpbPž:EÞ:^Ññ<º\«úê=!Ëù)ÁÞ•[œ›(’& ýVY9‘¯P•™hർù hö÷…ÉKÈBóÌNeÏ-šŸ$€¤.†.W7Y VéI $Wnßff˜c,Ý)ò.‘·Gøn–Ûyýú®m›-¯n1ïÛæÛ·PX¦C‰É+/…èæ¸àfŽ;S:TIjjцõšÜØɨàà'ú鰓ã‡ØVÐÉì;ÂNÛÐö…bÌvë?½Õ*=FaDÐÛGßžK=jlÿŸ®{¹{Ÿ]ýG´F=‚«e-ræô^6ê"66؈bÚ9¾›¡íßúm$*öBýæ ©Ó#åò‰/ÿjì°S–óœù¨ÅbQjµÅ¨š0ÁæW~P;8°y׎FRJÀO‡ÅwÍ Ñ%Ñvž5Ùf÷rŒ°Rì@qïûíB­€¶v´­4"ÀC ¥¢P-©ÑëPŒiNŸn¦é–¨ØqõŠgEåÿØ/óØ(®;ÓHM¥v|ì1÷ÌÎ^¶×`ðm¯lNZŠcDP) „ÓÞÝ™õ.ØÆ ¥ÛØ1 ‡T¤©Š(-66P¥”F=¢¶H­Ò–æpíݹg/¯w½ÞísÝô?¤Z!¤<ý4zó´3ïÍoß{ß÷´/­ÁÿþnÞ·3¨trmáPðIêâøƒÜÂó£*^à!<çRÔ®Oþº¿÷DÝæFjkS¡cOñƒ»TÙ#øm\_h2`H¶Å„SËÀÀ´i&Œ¤ô9Ý«>÷3ˆ“Ÿt=iQÀ¢æØ¹ŠÔ¬O;TùÐ’Ïä£Á€Ã§ì¾tq ådD.¥/¤uvbÌËšÃTFØš?ìª÷TU@P°Ð¹”Ã,ŒWÒ‹ÏnÍRðx¯&ñö#mdºŸŒœÑ+ƒéÁ~mâ´!Öƒ…zàÏ©LD¥sXø$‘ê]î'†·ç^qeÆûuÒ9ZÐÕy­ZK"I„ZÞÞ¥­‰ü ñäw–T®0ñÁAfª;ø-ú×ÝuÏÆOAÑ~44„ÏôÂÀU¢½æø™p«ôéb§‰D¿yn´CºÀ{t¸‡Lõæ~z,÷»UÉGPFX º¼-eÙã?†R¿x>yuIü–v¡”g™½™5}mÉ̵ô¹Æ]r¥¥nÉ«i©[ÙS£Ïù?€âöÔÈÒÔÍÅÂ(¼£Vo€1½I£'³ëŠðï» Á]K_)‚qܦÇ˪é4ùz?’v¨QoD 0Ž`¹(œMn_KrKþ*}ftÑBÇ™ÓEGééѬä5C¸ À¡rªÏ{Û<{ h€îQöéG¥3&õ]Ã@S68²éP:O‹4”eLG¢gÉÉ·Ì %VÌk1É`!qÌ„Ã::ßh˺ô¦-ÕkRú`ð†Ð îÑG¬‘sâ?)h•!S WßÑG‡°X<Û§ ŸÌˆ¾gï[Ñ»f‘Ž2›ñçiË‚Š« ºøâÌͯ§†Ócײ×uÿ¹jgÇÒScèÌUbzì¹…ÒÿQ‘º?øb‚5z<Ó¬ÉÙTh’jˆ]͈ßÎôý,ccq®E—ŸG¡7ÎC›ìI¥S„VORVÊÒÙ”¿¥®kf.ãɱ% í7öaflT3sE“ÕÏ §%nþÛYç"=n°^À „Ì!yçͰ¿M–Ý@$꾇ÿôRÐbTX[…ûÀ©ÐÏl¨¥,ः+K–½ÚTW^j£ ‡( §7­K»w«Yâ‹x¶÷{AEàÉ;^ð‚àxOóëµ&=f&q…^ZŸJ¦fggÿËÖÙÙD29ׯÊÿSæs‹ÅR_ I8)=?4ØÖ±™&ó­ÚiŸïVä–ÇE1Ñ×%‹¬(íå9V•;UÅ+ÈQa×6~³šÀ—‚~×®Öø&»ç-î¹ðî¢rÜ/2²zÈÇoßWe"4¤ÞHB60ËŠ³ïÞÝ7éßÏqͪ´OáºLU±CàAhWU>(I‡}~ 05eE&¡Ý»Qn¥ö‡ã­õ5+ ¢ ýÐ;‚â–„2ßè?¯ ì—•E7çÛ r ÖHçó€a?W'mXc4SëL°Ík=j!¬9Æì÷ßßÜ^ð¾ê8rüÛ݇êÏõþG,ÈR0|xrÂÁù@㟸H oÜd»àï †ºÉ3ákQmA¹k‚÷NÈs öÞÈî"XGeåà&‚G%”¦È•b.$µÝëldëew-P‘y™#˳¦" RL•ÌV¨L¥ÄØ¿ðÚ}ÚUb #n[ÈUqW(Žª€³Ni©bVE\Õ’§2¼ÅYj[`«ÁâÞꩽåOýCžÑ3'ÀÚÿÍ~™ÇFqÝq9‹M£VP(*ÍÁëݱ×çÚHè!jð±kch#õŸ¶ i †à#Y…J•ZÔK‰Š”Œñîα;{Ÿöô9HiÿA Š”§Ÿfæ4ï½ßoÞû}??±±"ܰ&î¹¶~dß1ñ£í?XgZƒê«NW¢¥iU”AË^ª0ÿã $2d‰÷’€=Ò#Úùs ù¼:ѫΠBé!mjP•ôjb8æÕ…½¨è},ÄÎC©ÓK¦Û‹‹´*DϨ˜Ârq«Û–óRmËV¥¤´8Q„"›ú7ö¨Ø– ÃTë5еæÂù!clX—(2¬õ)“ƒXzJô¤d6?€Gu©!"Þ‹d½º”ô"®@Ò¹3:3`Ø€¨¶Yà?Qò |u‰ü¾:wƒLLåÅÇ–f/+å?ª<-ÉL=w®• “žÄ@^ú˨J˜Z*O(£——Ë7Ñ¿]ÔZtËxe©Él.  ÇV“ùouÑáq\žR$ÆÙÉNO:obrEvB›ƒäI87¾Lºº$qÜ*Ý»©ƒVд Ñ"›« 33ms3­ÁPçs‰bw3[k@M8¤òm%÷ÌÇ'»OU¼°ÓZH0-jyÑPø²÷.ßýÓ1©@Ç9ƒb3ϵ„¥N FË{Þ%†Z®;wÊŠhFHP£Äùs#”ôs&I¦ÓßÐÈl PÙlöÑs2™\¼-ÈÑpÄf¶RØ"Šè4=g¶Bí³]AÑþ´TLâO'h‹H'}>; ‘Ïö÷!(«º}ëp4ÚÌñï¼sÀˆ¿³¿yÓît£M~®}r¼éЛ•Dë6ÁÓÓNèCm`4Îß! OL#’Ø ÖØ ´®%(ò“O^Ų̂3ï{Éäߌù"=<á眸¶ÀpÍœ:¾çOøçÚ¢’[^ÿ4"òΈÔÁç~ƒ8&p!ÉîãÙ»÷§owã°ÚBX|°ìÚ»‡¯^:¸§ÎLB$aë×¢¶EcN!zØ'ß[fçìA©…}öXÔtr¯œFø@»Àµ/ž\Áí{ØÌûÚÂÁ®ÐÊû:8éä,ï¸ó§#ûëJ +¦ƒBᔤ ÔPYô×ÃuIvC¬¡Xj¶5ydÏ\×¾œ…+…¦Ê¨£zÞ¹1ÎVÇØõ W™Øº8vTE›kC®ªpKÄV&Øêèë³;dWMÆ^$´në7G]5â± ˺gîÈ×ÔÀΑZkƒµaWyÖ¹Vv”ËŽÚ”}SÝvmßú=f¥Eаb-jQRf#f6¢êŸ¾Ýÿ9šô ’‡ûiî¬"}aep@ $íA3Ib ŸƒƒÃºÇÑHÖ‹,xñéfÃæÂ¥f%HSÏu ^ta@7éÈ3SZjiƒeÎì5ß6¥Fj/"¬z†ÐSuk LtŽÌõèc#úä¨><¨–ÑÔ “îקϪç=ºh¿týDʃe‡±pŸ IrÔ$ Üc6À¨ÙHSÔ«Õ­QB^¾n ^ùVê}…|–?È_’qÝÓ¢‘ì2ܦÕJ#QÂ`ªÌu]zªP¾òœ<å.-÷Á8ŠU6A«Kq•Š4Ö˜VLÄú`eúÊ2 Spæº*=±ôIçMO¬˜ŸÔ¦¯hrï©ä›+Ó“yÉñüÜ üî¥M•VŠ¡FÔ¦‡™÷  °õsî°xœëïüë0­Ïg´›V™,ƒC»ˆG~ó{gU5¡×* ²P׬5ON´Ï lHìôûXŸïh0Rq HþA±ç\Í{Bϳ >催§‡QÏà(J`hIñª™{÷s¹œü“<ºæ>{ø¦ýß–ÉdþÛYÓɸ¾öÊ«”ž¦uƒ»ê sB§ŸoK$›øûÔTÌ×4+rìÿ}n®>>u{º¡´”Ñ@y¤Žòx·ˆ|ÀƒO?u¯±àd  uÿ™ù`»Ÿoˆ„ݾ@#ðþé¨t*byá¨róþ®ˆÔ ØæI×#"¢¬ ‰¸8®¼üðïGJkÐÙ¶TYbÒ aæ•h  Ó¯~½—‚)R[pqd?Ïw#´]~òyÛ‚œ[º€ ƒ.8 Àµï5íÚ¾jÛV3ƒZwï(å¢õ \R éãÿlK5HeŽP¿{û{82¡½ÁXÞ爆ÛE®9àwÀú¹&NhúªiT¿“Žˆ"â;%á„P$ðšÈµÏÞmy³»¡´b”0…”tK±±}%ñÖiçºHÚ\Ç–³"ÞTý¹¬ü¯=s™û¢V_\ÊSÍ•qvm̾.áØ"9wFZÊ$Çj@&gÅ{å­C¥¿Ý[ܳ{G¾žo¬»ª¸æ*ÞUa×%Ù5Ivu¬quÖUš`­A¶ì—ß-*1iP[$BcÂ1±T1ÔåW Y/ăCæÔ€1:‚'‡ ˜S}Æäžô@)´ð–ùñšS滽ô¡Z5[£IŒ gÐpvüÛ…J­‰BqLOâ$cQ+Ž?O:«]¸ Þ¹Ú¬GžÇ)Óm÷ yŽ{LI/êA“ˆÃ¸ØoÊ UxP›Ä‡Ä=x¸ö#HÀzbgV†G âý[/[HÅM˜^c¦‰¼òbøŸ£td¢/¿'//@[:?žÿ´h$ý®â£ 6ŠÒÐJʈoŸP¤ÆUò˜báÚsòM²·UUh\–OkŒZékþÃ~½Ç6uÝqGª¦IˆŸ÷ú¾}íØ &á•„¼Ú€µ]·2 ¢J;~%qâ) VHHB-[E»¶j'H÷ÇZ¡NÓºJ+SUªÁö}_?âGœøî¤ÑþÌ™¨P¤]]]Éò=çžû»çû9¥ÐçƒFå®*|afÌšA¦®-S‚pfá:Êåóô¨!5¬J®ÈÝÍÏ®ÂÉŒ«¯/¥t GP´5üéÃ=aÁÍ…Árê‹Èö¾¾Ÿ˜IˆBD›ˆÒ`% ÄŒ¡&ƒöµ_”}óà„ yY¡™ã’ä–$ïœ@þK‘y5"ño1ì‘Ù˜ÚÁµ{{)Xߌ éô-'ÈÐÔdòÙ¥úâ>²Ùl&“sÚ§ý„"H FL¨…†ÐàȾ‰4Eŧí| 0#&·qL;nÇÛAÎîÙa†à𦫫‹ž°Ý‚x4ô¸óW/W °ÊBÂ?n4=š8ÍɇdÙzÔ‰|g<Ú$òo0áƒñ¨/òÆ£'&B9î[èxbb+Èq@‘ãá%8â‹ÉÝÌDW‘…D ¸™¢/_Þ*rmñX×?ï¿QWSj1”ØLË?»×a²Ô. ~Qðþ‘x @²Ïtñö†·?zìª*G)TcÄ)Pá§Ïlãŀ鎱Ëíím58b4Ƴg^ãd#‰íNÏ0~!ÜÁGÀ¾ KýaÆÉò®ï[#¼ä_±,{ÀãƒÏöÍr>sÿá¿\»CQT¯Ï#1#M”˜ Úú"üƒŸZú¶å¼u{)ØÆ2íµ’§.ÙT ¢|$‹T#Q—%¨e[*cþí’gë¿×ÜÚ¿ñ÷{*~ÓX⨤v®&Jj@j…ÉÕ:5ãŸ9ve½QWeÚ¾8„u®U ÏüAi›Õˆ³\pTÊNPH›âžZ¹m#ßQιëÞº˜¿Vn­}дéô®b­¢T0a0Z „Û4Zä•Ê‚G”2}®d²??Õ«M½¦zLéAkò"™ê•óð|™Rg¡Ôy^èXh¿ ¤c1@ñÖH¸ Jй!Àø?x ^Dèi\kjvl vž;æ?¶xm#…•Þ×ßÔ!qþÉYiçdSÁ2^pO0?ß·FÀà?t œŸÃû¢‰À½O|^]e¦LHKÑ6àm8qjó† gUÊQ6å­:ªApL¶UË®uRóúI׿9Š$­FR®šûöG+¨ VÔ VE\Gáz³ÂQ„@ #YŒaÅeÓãf=e¿¡}p_CÚQ™j^—hªYÉøªÍõÏüAi‹{ªîà-d[ê§›·¦ì[@‰-å1G½àiíuiGy²¹4í¬ùÛ¡í{+Ð2Ô¶±*´ÀXf‰â"XîeB¾@'û5Ê NéWeû´ÉËdì¢ØžîCæÓHô‚Øù¥™w‹Å>LЂEáÔ$õîVCP:ÈŒªï¶«¿¾`Ú_®#`-Y+¬M!P#î~·1~…Œ j”¡Bö,-€›\Ñ(½h朼¨Ëô›&{5©íÔ@2Ù'/“=p¦žî!Ó—ÈÌ (åýÃêõ¦Uz”6£ebj0­øû%€$w¯¿0=Nf‚ª§¦‘‘HcÄ?®” ÌáùE„ùÕ†ç^¬ÒY ›ÁTˆa6k{冗fÆVŠ£jed¹2²D¹]0ušº“—[2}G¿à®ƒy™›ù™ zz Ρ3A8ó‘&wCŸº³L ª…ñÆ2\gF€FhðÅÚ_ œPŠ´H±cŒØqíæÎ#+JiËÞ=ÖSoU?|Ôñ(tTg"²Q1bH什1¸HlAp¬ l3ç_ú<<Ó v^ákâ‰[ŠÜÍu¤V¢“Àð-õ›ç"Uù?CrÌâí;‡ÌMÝ{¿ý˜OÅqƒamiá×ߺ9îX$dgž´É‚_=O+Å@h€ÄùŽp¨YÜ{r|ÔY³²V¡3W›`³7“:]u±g8Ò5Ëî8ˆuñ¼‹_™“ é4™-P<ë ÂqÁ:˜½Œøkç& ¥µày7®’dûƒoš~´4S6ƒ¾ˆÆ54 ™ÿC}7qßqÏô¡´uêÛ’¬½wuø>d,H'æH(M3)$¥Ðlë¾|` 0Mb|—…†™ôȦËíCgúÐv:Ó¦-iB ’W{¯,Y–l©M2Ó)t`¨w~/Ò¬ôßýíÿßÏj€•E/íTÿá.AòI+ Ýô‚ @šùTÆt \/¸lQ²ˆâÀMçµ+û¶û_÷ºÏŽíѡم„†DçÎí 0],wìâ…Wµ gþõoØ eÚeá$èè¡(z@K•Ä^ðZ=i£JB èæ¥>š=1<²½ºBAèp)Vé t®z¹úÓá-ËŽ:ÞS#Yjãæe»Yö9O5g«‰Y¿Lá5ª‘”­8`m>P®Öâ*ƒB©Ö( @I%©S“„¢*h «(H –ÍFÕ3_¤BöÚ„·>j¯—m  âkæ~ÿß*ì2,Ú[CÄÚ±4Ç›^h¯|°2aoµl«ô˜Wm¬£îÜž»Ê\¥TA(FjA„Qê¬V#1ã5Ü4$§ˆ•á¬Å¡\a—ÆÉ¥ ìaˆLâ± (ü.$R¼2¥FÖ‡‡Ô§w•éTå$Ž îF¥amp”zû]%Š«ÁÌÀ«Ô_,ÊZœÀ¤A(6 Ý9Sê2}íJwÅÒ;–•šÒÊ“Êø !WÏ’$áÁ¼ØÓÄÆñ¥I$6¬Ž¾KE†K"?\ŸÃÏRP "ÁzIüî<)ϨR~]j.eVù¸4²z^œÉ\½ùû Ýeëó!¤X é)H¯ÃeH)V ¯‹\ú07uûî:þ5"Ý̯d%?Ò¥®i¢Óë#³Y+3:.Uê¦*9›—˜Îãþ¼Ä¬29§NÝRÇ/gGg ÿHiLÀ¸ðÂüW¤é#’èZØ7ÀÒ\pqÜ)°™]Šœ =ï‘Úîä˜à °“M#d! æDÑÒd!ðÐ]-/tÐØUæûÁÉ ´ïÎ?zëªr(ŒÀ €dblü‹H]‰'žvȯ™#­‘Õ$hÚjbEÄÊÒrt$\ñÎh-+û¶=Ì÷‡ù>:h•„Ǧna€cœ<ïOŸ¡{ÀÐm¬à¸{϶ï5Ç„(Ä4(¤úî>/¹t,tHR'K»ÂÂñíf¹.€PÈÆqVApè Ü‘4w]M<˜f»Æ'_À g5êjJ]ºø}šm¾»Ÿù|Ý­8¡&P¥Ë Õ}ý[ï|r”ûC¬›g޲´Oìë·½Hj²äÁ:_°<‚F†ŠH"gò£ªÄBä1XœPEFàå(1'ÇK#ã4–ÿsЍPŒRÁ¤…µfbÝŸD¥ü_I]ýˆòÇ¥ÙŸ“šÎ[º–‘ú0[žËþËûdƒ>GH)@I²L[xãäWcþÜÔœE¿:u5õZÞè÷2Ò£™¿ªŠÏd¦fÔñieò*ö¨ã‚_­Ì*âe¬ú3R7²–g3csÙòLFjYœýzÊ¿.q«Ê×+€e) Õ–äÞý´?½ËãÝ"ÛÏÑÝ4³› tBý<ýòÒAȽɆºxñu–µŸ€óÓÙÁw.Ðm`ŒyèÒ‡ïBÇYæC[8ÁÇr'F‡·§÷‰(®Ö,).F@ª‚lM&“O;çׯ±²"I%ñX¤ÛçÖ„Á1ÛÒ”5ïtXîqÏJ}ó¬5Ä»ö' @ç{ƒ žë–¹^‘=ò¸Ò ˜ãg—ö˜j0°ËÔQ…j(¯´Rç÷wèã¼äàøÃ ö°x$ðÀÊ‹µë£ÍvþóÓcUå9ª++É9¡‰¡mK¡ÈÂQ9Ô%òžÏç÷_÷¼>û4xBŽG¾/: Ž=LÁ¿ 1mßβ} o„¬ÂRß=Æú­UZHQ£×¦÷ \Ÿ¶Ö€¥Ã¨AaÍÆp…W©s_0UÎ\nc‚>‰ïâY'xƒ€âž´:dÆË îûœ…-c ó½AÚAK€aÎûóýï¼ým‚ȇT˜–‹:œO‘FEƛͺ;Í1Ï&°þŠÈ.PµO=¶þ£þ+~"NSÔUÍvmŽv¢#×Ñîz.ÞfXr´¤3ÎÝ,Z·Dí[–]û†°»Nt›£NÓ'®m'¶–›)Ås}{sÙàóÿ+%E0#**Á5ê{«ÅNcÔ±IrÕ‡º ²«‰·nþ¼÷ùˆ£i±Ý±ÕINç6.·×¥~ùZË…–¦ÖâS;Ì÷íåQWMØR³™N5—ý¸eÃñÖê_ì6Åiç¿Ù¯ÓØ(®àm•H¼÷îÌÎ쎽¾°YÛ»¾Å¥@8 ¸iP5%ñµ³3{øâ!´”`Û8Á´!©"µUÔ#ÁÌ‘*iÚH=ÔTm…Z%H®cçÜÛ»;}&"UKŽè‡<===iwßÌì›÷þ¿Wþj‹óruÃÙES‡Jhwc*àšé+ˆÍñçjb¤“é®g»*Ó‡@:yÜ•$÷0„kÞç wWJív…tÉõlÀ ÔО*ÎWöWK¸]Ʋ·ˆ‘%«Ã¾z ¯Žû¤®ZÞ] 4F»ìw}Ì]'xoÝ| – ÔŠ¸3ƒ× D¸PÂ]·@lž&+é>g´}£ÒÞøÐ'ú¿jÄݘl¯Hùjß=ìØ_a„aÀ#fȳ@6E]vÍuoxÁ´¦áÔEmjT'\4НØÄakòœNÔ(£Z~TÿYJQ.¬ ž/:Td3f©õy¹hñ6;z°jå;Ý«?8…V£ÖŽmÙì8`†YüÑ*Ïf3jRå ˜ÊZ¼3ÝýÚÒM鋪ð¨:>dH›¤—Ôá!cì‹84EFàø”†#†È°N2D.å1ç¬ïþ*8F@FÌX¬‚òK7ä¼?nVnä(“k“w4ñ (3‰d&Ö,ÖIda –o}m©*ˆÝX‘¼¥Z¸©OL>’¹›ýëPš¥±X`kasqöŸ_†’og)· ± H™\¡üB¹nA-z#Øؽ1uêÆªPÊ/5Ë¥#áÎc‰[&åWZeâ+Ák%[V²Á`V[­úÖÅžeCmL0¢ÛEª[š[zÑ$ò Ÿ-Ràè× *Ro®'Μ{ø4ë¦Dÿ½Nt’Žl5™m&Äl„ÜŸ’H)ñLDÉ<ˆÚh>IÞ/‰ò?JP$GïÝûŠ¢F½C1`Ý+—[Eú¼0‹‹óÏ ¡®àoˆ!8Ž÷²,0É2Òñ-[êñ½3ÓQ~þ$Þ‚é‹ò¸e·ƒ öP”{žê§ù3]]5f-‚!ˆI¼vu?-ú悎ÃËæ4:ÿEk„ž÷Sà!“T—©~vÚŸŸaŸ»û»Ã-»,ˆÖdÕçæZ1Ƞݨ×~;}÷™½ã;bdCÒ]!vTp §<5’»â¡ÇÐçѨɶ*o û¾ÅôobðªP 2;À#ˆ¤3 r™Ø$ãaO•ì)“Õ"Q›è,M‘5@œ{ïÝ*¶sÄ&ª³¦6£°Þj.6[õo~§4BÖG‰zwþåPy³¸½y¶ØôŒS'šÁ OE6Q>×íevlm)¬+€×¶ä©fÜô¢ jg5…èêC¦_µÏak-+@´:+l3¡F­¶Pƒî.(»¼£,ãq2=5r 2Òa—ˆ©ÏÅw¥Ü• ž­Œ»X&íI5ßáû] ^“\t;$ƒÇ«d½HTÉ„3êóU-{’\ì¡…‰: ¯ÝUQ¢2(Ÿ!{¸îµÇÑ-–·—ï*Ÿ|ª:Ô]&¢þoÎwÚ=›CøÖÓ,ÿwóÎêeߦP[­äiölÛQTgÂÕùF Ñë`ø…–Rþœ1Ê#ÅÒùõ©¡uñA}lÔ¹„q/ic/«>K#Ñìä뺿l]Ód6˜³ Î7c%ãßCùK%™ú\^f0GÒŸÙ¥E,–3lj…4'ŸF/îƒÞĵ‘±ÂÄÔÄ6:úd!¦ƒÔl0åÁæ½Û7üæÎRGÁ[AS>^èX¶´¥»ÎŸÝSd.@ †7~Ö6Ëúy¡“gÈYöàñcö'wVåa„£LÈÏ1Ý¡àÒµÃÚ/‹‹&ð}ÛGÑÝ ÛËqmÜì÷yºW’ÚBr»ËY…B6³Åö§÷qŽ=*Fº(®ãß³/îk-Í5˜$ûÊŸže{B€¸hq±|ÁY\•t?à(XÔ2}"Bõ$…“Ó÷½—FvbVXeÑå`H¡ÎÇŒª-¢øã‚»9ÞU“öØÈ Ù_Ëû\ ˆ“žª‡CŸ'o9ç­b¼Ûîw5*„3Üi û«ç»@GˆZ ÁS)y+¿ï®‹øëD¼"N”¥{¬³8î®Xð7ÅȦ'Ê ó¬ˆÅ”o€Uç›1™tŸËÞš;6Wcf“ƒá+O”G=Õ,Q%\¡žæ±½.¦Ë²@ÿa¿\cÚ:Ï8mR»”¬ àÛ¹ß||ÀƒccLmBצKRu%MÛ\HCÀÆÇ6`’¦Iªli£B€¬­¦5ª¶*š&–A¹­™:Mš¦hŸÚªë–æÂÍ>ö9Ç׃pöÒ~˜”©R‘˜²{õÊ:::—×çÑûÿý„ µì·Eh[·ÐVí¬+ @÷eÁp} c´b3E¨FòM,I¡zX”ò?Øìˆ„*Å.[ÚkÏz=qΖ7j¸Õ\ÿn£e‡vÁŒµÛYf<]‡þµÉ&jS«¬ø•+ Ä#P“ô9€€ªI´»ÀL\i_e²­*¬ÿW½Ýn Q3 c%¤Š@!VÞÈ@= †‰f§ÂmŒƒ[¸ŠAï{ô•}hÊœ¸b2´qÎï™y½h¶cýŸ[7ì³8B24L"”©P¢ ÖFü±ÃÌ÷#³'U¹AFêÕ(ƒêù£Üg’{ðÙ>ha‘{tà!Ù^øIîší‡’g…$3hˆÿ\}¾*c‹Ôx«.2“æuÅÐí rý1ùw«Ò—×Ì}¬^¸Š)— €Ì]D—Jÿ…ËÐì%dþŠV¹¤™»°R¹ñ¸0Š÷ÑÓCªÙáÅ FÞ,t#šb\[ iî²Ý½T07VøáqÊØ0¬Âb\3>ªUF –ËF”KkfG!ù"®<1ÿ þÓfÑ€¡Pz­ »sϲ+c2ê]ŒÍ%æ?u$·% Ä,h!}fŽïó^Ýr"pyøw5BÀ´Q[lQ›´zœ¢ iš„Uª×^~åÈ‚8ûoê~}üyx<Œáa$ z†E!Ô„QZœ‰g³éÞÿðå»±#|Xä»åhP˜èÊÆ¤âG¢€3‹þõ ‰eb&Ñ-ñ‘ î7ù87Ís7o¶n}–¢ÙèQ“6ìÜΊÒ!QôñQ`A¾åz¯ïì}ûyŠè75Ù§„cÓ1 XÜ—wO®µÂŤmÃÀÇÞŠò]ñH—Ll©4çýà72ž¸×).Z?Û½·'šøèÑx¤›Ÿä"]}ôE­Dpm`¿CŒ˜~1™ bøÎÝÎMO±ädªÓýòüV1}l: gotÚ›–¼Ë–:Á~œ¼ß%Æ9!ŽNvÞºµÿ'/“Äj–*atÃPZBõ‚þÓŽŠ´Ï T ÁŠdÐ.‡ìéŽ*ЇF¾[«äVû#ÇÐw±‘¤×9Ôè<^§o´àVõW^O&ä’ý?[dÀëÖJpÖïŽD¨:éuÉ­5¢Ïow œG®¸u‚·:ÑR•nsz«Í4‚0IÐçÖg‚’m•é@u¿îÄ& F `ž¬V_k ÅŽšqÎ1ã]›ð—ï+µXÅq3N~²§2wÀ#sõÊ~·äßÚ.FgatV±°Ò`6˜&qŒ¦é| ±zƒí´þöëðñ%? 7X-ßñÜ{ÏŸ.Z£Ã-fÄYó½ACtuž¶qÃd !ôÌx $´×Š^g†s¥ýN Z’ß•âÜ8Ï•güe™`í§ê6—´¶€fÌ`=j‚^EÙPc©ÉGuÅEm³£ÙéÈúª³m±µ<Ñézä•}hæÿ`U¬½\ô•Ëíî¯[h«Š´W nq»ƒÖQz ÇšÄHô‡½Ûèä +ô2éA4; ;ËdOc¹Ó¦o³‘Ì)Kæ$6Ëž‚å=ÎüY¯u¤ƒ¸yT/÷ÐÑA$yNõ«½…8V ,|·J¶Â‚z7•Ô”Ò(n&4«ÃνJdNëå:9 “άÎô«3}¨ÔÇŠý%™l¦—ûàìm¶_+Àé~8Ñ ý¥ŸþÅž|’ÄiÊ€rhV¿´ž½ÿkhá¥ÜÈO=6?†äF`åºNÍ[² ,Œ’¹Q•ruµ2üă‹+ÐfÆpåªzöšjøí¼’+ W (%5Ï»ò¢CÐÂ%øãžï[p‹ Ïßó’V¹ /—Ì]|RÃæ®â©+«”±'ç‡WŒ7»$f%P3ë÷ì*Ÿœòƒvr*K–}|8í¤(‚{D#ûEž£aïúâV¨i› #À0p‚Ä`„µ!ø5›Û ‘4L¥Iâ÷##ÊHÇÂ×ãQðþzÌɹYE©­¯§T¨•`Õ†¶’¡6Ñ4¢Ök´˜g£á7c¯Æ¤ 8½7%,rszÂ+ÆB¢°X¦H´#.t/ø¦;¢“­’”bo|#¥ÜSÓ¡®Ãuº²ª¾sû/í‰Æv‰ñƒRìgËõÞÈTð‹Ïɤ†¡ t÷ÛÈÈ×B Ï‘:ˇÞ9Q›H‹ð»ã±Ö8ï]2ÍE 0\Œ$¤.^ðOíM$}ùw®v=ùÔzý;Ç~|çŸ{Ó‰î¯îµx…&Tõég­ ©còž? Œï»wçÈæ§Y 31$f@¡¡ß6§2‡bSGDþ0põÿ¶D£ÞD4a>É]Ú^RlÄÀþ£( WiHÊ#ï{Šbû*“ŽØAgÄWívñ!‡à«\äMëSÁš´¿â‘cè;Ú…@A XI†}ÞäɵÚr-ޤ¯"ÉÕ‚ ²íŽ´QEÄ ØH®Í ”¥‚Δ¯:ÕR#ûë²\,—ÂöS Ê`+Ñ4¾¥”LRÞ Éç”|®É–"‡~u1ÉR¨)¤Î7Zg¸ÊT¨xªÃ]ù/öë<6ŠëŽx© ÀÇ^sÏìÌìa¯OÖÇ®íõ‰/( ‚Ò(„$mÃzwöðúÀØ„B ÁÆЄ&-U$h«)>j” ”HUª¶©H)hÒ{wgwfïµ×öô¹H‘Ú ©–Ñ?úô4Œ4ûÞìïé÷ý ë”ÈÃ*åo·Tˆ&Ájþh¯gT,NHvªÞ]Œ~ÜR!8k?i-lÎf±Y8胙–\ ‰½Dj¯;¿½¨ˆzl…0:O±舥(5x†Àt0vqG1ß¾yÞaŒØÍAg] µ4é.¹Òˆµ\lô*;*y—1îÎ= CõÙZT¦Ã!-¦bé…–…!S„hh­’Ý)7åd~ܲ5ao˜i³ÄvYÿsú!wq¢­ á. Û*C­ÕQΔlË㹺ë{óv„Þ ÃõF)…ÉÞaÌøÃz¡PGG©SéÒˆ.Ö?H#©aPà!:€¥Nc©Á4i S:Ï–EN®“Þf®ö’ ‚Œ¡0ŒV3¶&2pFèCÄa­QޱpOSº8„IЈ<1¼16‘$çXa÷¿'Èùa ,éSÌÁHbCÐü€.Ò'õAç­ŽB:–d3år¬øi“üówuóã_“ÆT ãé‰IEì]ÕâèÚ•¦¿4 B_ÿ¥*õë4éƒ4iIþ ž¿¼&ui½xõ±½µ8KÁ„^l(@ÕÂ$I@Í&&ú“Lé=YQC£ò žøêji$1–)MÀK—2æ&×IÐÂ/Ö¦®Ê'Œ$"Ó¨ 4 LÿìÇ{‚ÞŽ¨Ð3}﹕ö½©Ùç„P'ïíõ{»@äyGX8ö×OûnÉf X‹dé%K*Ô„ª¾¬øíoµ¼ÿ„ýXñE † IÜb±,,-¥R©………û™»¸¸øÅõÿã_Æ‚t¼¿ʼn<œÁry>ÒÔ¾“h (4C±z4KOe±T.«Ÿy¦à“û§îÙÄp»vDÛ¬0àòA±V+õxþŰÐéŸõ„EýÙiG<Öã÷[ÿvïèØxË…w¾áóN:Àñðó«µnHGáC¡ÿF#`îÔkõဠ™ž4Þí(z,·­¥w¬Á]s˜—QÑVÆ;ËD{ÅìQr-?µ•Fì¥awYÐS6ÛVúÓot¤^K਑×4ç1‡Ms\E_M`°šÉ!z«]ä̉Vã•çkYšd†&WUnÒQ ~VpäŠmµï=k„õ*”TÀ¼Ó@üÞ^Ø·¬¸Øn q5‡¶™HÓ£L)ß\`p’:êC6Ó­ÓfZ‘(Î’8{îë–€»vÆeþAsŽ WR†,V…׸ÚT{±h-Ýõ€U §IàÊb\¥Ø^Ö㪞â˜+ïvkÝV2Sã˜&/ÖÕé5oíæ/ùfmáàaß½Ã<ÿòŠÓÜÔïïæùƒ¢xÔëíš™é¸~íÐáέåf’¡6°8£#òfIUcƒ6?›fÈìB~ëNOw½žh¸cú®Ûäþø'WAÖWÞùáã¢èðùž ‡[BÂÁ` ãËÖÈÌÌ+~ðÂÖFG@44š‹­-Ê@™´7=¡®rÐÌ}ÖjÑ^åÊ\UÂjN‚˜¶W%m•1›%l7‡æçáÇЃøq~q¿³vS6Sp¹+/w_eÎv‚R­Ý•3ÝÖsZ"­%W…Ï^rVĹòy[]l¿%ÎUüƒürmêºãø¤©­ÐXIœÄö}___¿Çy8vâ¼_ h) °1¶yøq¯í8a%´Ðiçl-ƒmR·"ÖQB^ MªÚý1MíºµB+-”Ǿ¾¶¯Û±Ä;€úÒ˜¨¨´£ŸŽŽ®tÏùý~çñýülÈ@ÜZ²5&:þ²³€†• D,“EÍv4¥z*{eØÖanu×êɧQ“P„¥ÇÛ ™îêWÖši ’¡JJšwy‹)ÑUë2¥YSÜZ{uK±Çå­”Iú*d`•(»Úë0úXݲµäŸ?¯/Á¤$ZIµMÏÚËÒ¶ª°½æÌzA2Už‡÷7@^çÚ„sõ¼³"hæP•šÆs8­IÞÞnŒõè#ÖÒ0Û¢HXA{ ˆ”ë1Ĭ«!wE˜Ñ½¿»N.ÎÅH…•£’ßµWòLUš1‚ͽn5ì7h UÏ—Qì2GØòkŒuWÅcßèû,agxXqU‡†ˆÓ8墨kâV]‚©þÚ^“p–~±ÛÔ®VÐ áX‹)a’–òþzü‹ÃÐü›ùü Ý©ìÑH|X—C£Ã9±A">¬Lœ „184Š{¥Ì ÊZóA¹#P/£‰îŠâД€Bž‚åbqtEü¸<5F„N¯+zëá¾ño»Ÿ å§Þ@2'²ÓCp£‹Áá×$HR£$èChìu(5‚/xàø =?‚.fdž±ƒë5*VOb„Z%UuoX鿪ŒOH–.æe®æÆ.ˆšFf$ÉK?HMå¦gøTÖ€“+âÔºø®(ý^Ö¡m0…JóIââQyârNü½§~ãÆh]ŒÒÊ<¡€%ÊÂ"|ùOŒF–§%ñÉ™«Ù‹¤KwkyF“žþþ)ý³Æ,¶ Çó†3{ká¾9Ÿë¡ßíÀÁÛ·˜è|?:tþÛÛžËWQ°ÓRDK’$„i‰Bgý¦+[w]ÛÒùQ³ã“5]××0«ßw²öù"Ãpëõ%¥~¿?sH–¿i[ù¿‹í—džP„Ép †À:IãÙŸÑïìþÚ»'˜·?2Õ»}˜õðÂ]Ìðâ}/ònމ†\AÎæï,;½~‡ïTër>wHpÝöuú‚/MLZ÷u˜ÛÛ{:ªOŸ]çåúù0#^æý]Aÿ€á"/<ôü=ÝM[·\Á°ËÍ”¼èªòq½\èå·ÏµwY €~d„† 0ÂEâH¾Œ¼ºžó³ ä Ü«Ïßï ¸nÜ´òsÇ9o/È<ÈOÀ¿Ÿãß6œ9½µDýCŒ"1 CI…«C%§;š޲HÙo7Äz VŸ`–TD¦¸£"Èš8¶‚sU†{*ŠŽ=n ú/i$Ƙµ+¡\Œ ¥4EÁŠB¦ÌÍÍU•ŽÕH?g›çÙÚ¸¥<ÎVs¶ª¨˜‰w¬>ÈD¹3`1  Áæ¯ÜuB+‡sä2RŒÉþ±M/XŠ£lU-Ktë£ÖšSÍ…r $†P5Œ=kT/tèÛšŒú¨¼ŠÕ°`­÷;k…ž2ÞQíªü¨­’@Џ€$VÛÜH[ŠRÎçS´¯S#O@¸T%ÏU‰Q¾×8o)²kºJ²D²|"•¤Ä¨v­zWIö‘Vê͆uMààA$ÉtkÕ<[¼à4¬U »yÁVr4D˜JŸ³4i3§:·9hÓMý¸¥”riN« ɹmƘ½ðø+ì\ý/WËô&*bkY`Öp=5á΢ kþÊe~ì}ŸI²ÕKõɽõ kc„­}Œ-,•QgU¸»|ÞÑ8s–1m-¤H‚ ÅŒP2…Å[ØŸ{•é1 ăhdÁ“••K"1”³0,NŒâ±Q<>D.z ¿þ‚¨ÊÏËCåmzÑÍãYÑUf,›ÅuÌS¸8"JzÄáAhyLT×ObRZ$Úk‚ßï¡æGáùAIÄ£^8 IŽ ÄRò¤‡L=‰g<èÂ9)‰Ÿñ£jG3c4‚R2%)Çrz·ÂÑ 23½"ó®(5“ý°ê¿0If.˧W,Î<‘ž‚“Ò¥™•ËSÙé yz<çÃ7²4!Ší¥Ôì…ï-N*3ãð H…ÔJ•F"A)±§ãÉÔ処 ÒÑxvüÊÊè ²<)Î\—Ó«2“yó3«. µ0Œâ8Eèhôé©éŸxCÿÃ;¹Ô}×®Y¶žC#ZQâ8 ƒÇ¥w˜Î­ßþÁÆŸ~¼™ù¸År½ÅþÙZËß7Ú?}†ùðGì:L#SÓRÀø‘#G’Édæ.€þÜÿ6vziiñ$»—‡›_ÞGÄ -Dâ´T}h­f|‡æ÷›Moµ­>Û^ôV{á;; Nm"vJ”9”XªƒÔ$aéúÖ‚óçwýÁ(3îäý®Hh¿Î 0‘pO€sx7PÉ Ï ,0çqû9ßï¡Ï;Ûým«çwÍNŸÙ¬¥0RŠXìE/n-ÀµrHúêÑ _Àößžc>¿i{ó××5j)£PTAª1Zª%¯iùð>–Û¼‚ãQùÃùíŽ ‡Ü!ì‹›ó;;Ï[ü¡^o_„ï‹p~€šBï§ÿî³Ú+i!qŒË@ÓPN§YþIGe¦S÷Øeå>‹X.›Aĺ:ŒY°W.vÔDíeS–´Ö%-Õ‚­Hp—FJ[ !âÿ!¿Þc›ºî8€÷©0HHbûú¾_~›˜8qDZBá™d”Ga­t ò°¯q@£S‰ŠG‚“-­ÖM Jy5,…–iTÚ•¶«J5ÔMKˆ×öõ+ŽíØÞ‰¨ö×ø£ÓvôÓÕÕ½œsϽ÷|?‡3íFF©~ó M‚%G ¶?J bI …‘rBªB©—åÈCûº\ß²€»þoKÊÓ”²y`­'Œg–kQ³$˜=%$—cò+›*3+pZÒÑ8å\–í×%v[4¨Š–‹iV…aïn_¡¢Q%½gÎ"˸šyNq5'ÜKÂ.ëÄV#‹£8à ßYÉäµ~‘>KhOUÎÖ|u£IMŠŠX‰hZ R¿½1Þo™ÙµÜªf4QJ«HŒ,Ǥ(%%YJ&&¸¢Œ¦À¯¯‡q\>Ò\ÏwZR@#®ÚXwmºpËø‘·¯Ûœ€7¢®Ú¿Úš«I °ƒ+1†Y¡—~ø²9ãZžäjGUÄU·­ŒÛ “³à°ä¸zÞ½&Ý]çç*À­T_cnWEÔS›îYs,öU ®¦gìæ8hI:¢Ü|=³O˜y~–ˆ½.™bžF¿­îËm íR¹ ‡”(Žj©¬Ò@g~¼K¢£âÂ>w‚ŽÀÉבÌ(”=Zœ£Ÿ¤”¹“hzLòjQŽ6<7ù*›‘±Ì¼ 'ŽKf†d…c¤pZ<;*‰”Žâƒ/ 5$Š!4J³•ôÓ$?‚çŽéÃT~H’?g¼lÜ‹¦F$i/:ßÅ0N2^87"Í{¡ÔópxɱÖçT°ŠÀA´PöÄÎEñ¢Ü-Ij\47^”»µ0uM”¹A&Ds7Šç®‹òEßU¡;%™«%…ëèÕ>Z - YÖZ%:Þ…üx{q%XÏ`•ô"û6/Hÿvaáš(÷.â¿\|÷Ì‚øu¸p]œ¿ü|îý²§E”y¥\¢·¡]Û( ÂÔ, 6µVU(舆÷O?²‡øƒ‘È«¾`/öøý{C|ï|Bú"Á^wGB.ž·#n_h ìüY³^cÂP´–b˜@HÅ:…úôºíŸltµŠ{°ÒþÅî‹uŽÏWÛ¿\ãøs«ãÓµ=ß4so-ßÊBš–Q$Í Dè‘.9[˜+äÒÙo¹–&xv-ÍþËa‘š“s®ÅVŠÐ-Ó/:¿j3\ܲôÜfýåmºs/Týzƒé7/š¾­îP»¦½ª”,¡D”†‘kå4Ã0mÝÙðÁ‡îh¨/wM:£áþd`02y@ö‡"îÉ€C €ŠðýBhè÷û\ Hž9þÃõ“—ªå0MK hX’$!ªueõ×Å}î`Àzægì‘çþg{ì7šªYÑʨ’7În ‡<¼o^àïxZ㉠û€@ü>`7 "€"0I(¸×7½;¶…ç­rp:ràöï»[›ô‰ÁH†T l Ê†[+'«ãîeÁ½ÿu{Þ8Hy‡Ô“¸Ë’p[Á”o ø!b¯‰ÚêÂKhÀq7$íM!GÝÔÀÚ(×Xàü»«C6Ó…µz˜“ŒšÔ© iœ$q‹?½^õ‡ŽÆo-é}ñ.M’3$]¦”³F°UÇúW=i<[ÓêMC ‰ ¬ôè*ã3q¼Ä^UâE%´ÔúÉzÞØúûÿß+µÅ3¬-ðx§AÿëÏj=ÀKñ:ü¬3àwø¼{Xik,Üÿèk×lxÏøÑ—Ë¥…´a|—QtK1qa{U€© ÙËc{SÝÊeçÇ7ÄP$´Ô}ȶÔ50AF¿`.OÚ´q—6æPE™J¯¥å[ŒZb‡š³C%þU§"akL9šNÝÍ.e1š-…Ÿka“ᘂ+Ø¡•‚.']ª £ŽÚAkY |§EŽpX«éië‰1¦’¤ \ƣĔÔ]#]têccÀ¦™sÃݵ~C¨k©DŒ*AÎÁH\Lsü»[Ãæòˆ º"ì¨ ôhNo)“bð`Dp$›—SDWêÀõ¾åˆ ŒÀ`/AœK;•ñ.Í¢«†uVw”p1’O d1gÍW+î÷êîõ–NnkUí[oxE'{ATSϽß. ;õ ·µTÄÖ¡g÷®¢šKb.õ¬Cï·–gz+¾´zœ€‹pD(R\±+è/vW¤ºèk¥IƱ¬ ÷jCnÓœ]7åÖ-¦ »2î©yà1E_«Š9ÔIF9ë6Åš0£bÍÊ€M0ãgÔ!»:æÔ,ãõ³tÖ•À±A›á HÂY5m©|§U.G9£x¸T*Eùئµ¢ûØ/~ˆŽ…áÌ('4J?M#©1A aöðÞ“Ì #Ña(5Šf_ÿözŽQœ'Ç yWH pÞß =fFðw­”ÑèJªð§õÏG†rÙÂà0w~D‚"¿Ì ¿ƒ, –$ób#Âè=7JÅGð…8z €$>J~ñ–¼COã«C4 ­þøÇÜôyAüäŠÌy*u&/qneêŸà&'Ö$Oñ¿uýO=Ÿ¹°2}1Ø&= úµFĈ\B$…¹…ЉŸå¦/dÍœµ0!þÉóÄhP– ñÉÕpä<ñ4gá$”9+xVI[;µ&9 ýºÇ 1¸J%I‘ôÖu‹ß·Ç;»+²û¼žPÈùÕ£—"þ}SAæ1ËÄâoNåœ íýüZ×¶M˜!Hƒ¸„)ðB¡˜è1N5m»Üö£›-ö» ¶;&óFÛõvçå˧M–ÛMöMÌûµÚî«möÛ­®ãu/Ã8?EQ$INNN>‰ïüüÚYøáFýx§âƒöÒñmeãòñöâãmEÇZdGš‹ÆÛJo•ß&9Ü\n®“P"  0š…c| ¢u*éÐÈ–ÿ|Ý÷Økõù¬±¨svÊö½ ¸6ÁÌÌX€9HØYÏÛ·ì<ø?ß×qr«ˆâ %„¯‰x µÔß/›}¾W‚~;;³÷Á=Wõ°>s(àw„/Ø][…‰Há’·¿Ü|¸ÂN»žá’€mÀªü¬›eí,Ë,ÌzS½§ûf“®~R.ÀJ@ÜP¨@ IP>£•^}µ:ᬜ½°©‚=ʘ۸ìüøÆ„€YjŠÓ4d%ê®ö9¥‘~}¨[½`­¸ÕUÉÅš Q¹8è·H.ÉïWø˜¬«üQ¿â£6Õ-sõ•.,ÊAĈ‹jÄ(êPGÌZëH}Èf Y µQ‡>b©xªFlšCõ$&– 8™G“uZÄ7j1]Zðñ„£ Ð(fÑm/°'±ŒBHD€½¤¦S̺ˆ½ ˆP&ÁDº"äò(–ùó÷c¿å¦~‡.žËKœÉOžEҜųYßZ#@c§VÄ/deÎà™Óß›>¶j»!†KÅÞ®Ïú÷áU™KÂÀîgïæwhá2¿%ð<ºˆ–6ŠéG²Ó?Hœ}>szVI^D3g²~Ÿ(|qIòó+p¤ä…V™Ï»é‰çí›vúg]áÀ^¦ë Íxf9Þ³îC##VÓp!Î/Â(ƒP!*i.Ò¿[³ý“=ÿh´<¬u¾Á|«Þz§ž¹Õh»Òhù¬Á|·É~¿Ñy½ ¹Ú`¹Òb¹k2ßmíëRTUbn“¶ŽŽ4q:ý¤Â‹ éeôÀwä5ŸL}ò—¿Ž£xôqeæÐæÂ›Ê޶–½ßRz|³òƒmG¶ËtëPœø/ùuÕu¸}IKSð:ËÝ÷Ù½Ìx6ÏxÆ ¶Û”³U@#L=Û1¶!¥Q*Q…ƒm M›Dj“@CÙqX*H¢Dª4!iš”ÐЀgßWã¹=}ªÂC$*ý:š¹wŽî™sÎ=ÿ÷w[^í6]Y5±‚<¾Ìø§åê£?ª?°\·\K`•PÖŒ‚P v)ŽOn¼›Üùï€;4åʆþ ?ÒhÔ 6I8ä‰5ÚùØyð-Çç7ݶj% —ªÁ{ˆsˆ–#r-‡½ñî’©ðð»ìõß}ëš×f)Ôí¾ùÉ϶(0QµŠÃCñ§ƒS`>îÕx‚A€CŸÿÞ ¨€ƒ¡ÞH´\ vܺӻqFM‘ j@ª $;)ör»æ_ÃK£Ã gÍ´SŸë1f]Aý±óãk4Â7¤}vЊ$xˆ`Ÿ1ç\|}ƒýÀ|öÈ ½¯EM3pΨP¥ÕÔâ*‘2ÄkŒ)¾ ä_aK§Ò±£®–ž#¦aŽPˤܵæ€Ï’j‰õ›Aœ–è@k’o͸ ¼ñaãV9µB^À9‚™ªÄIŸ5êh ñ¶ŒÃåë [›RÛMÑ>S' ‹¢ ¨äè2ëWuÊgJõ7%xCÔÛ÷Դɤ8Yk´$º¸†iÆ+kP–Ãdb’!pR.ý±W!_méz­1_ÓÔ€®Ø§M8;WÖÒDŠdÕ*±zM­ôÈRìò*­ÓTàâM5p g~ÎÛ>ݯ/l­I:,q _}Ò ÔÔ˜ù©.7`Kz›fóò¶ºDŸ)ånÈ÷§Ú°Çvñ'-¶jDUYá•4G–’ÌÚæSÞšî×M»Mø_ÆÈàâfS ¥*’hã~xm•ºèš_èÕÇuA·ùÁ’E¶@›áí ·=Å·D]m_ÅÝ1W=hFežà:0ùgcl›)á3Þö¶nÖ¡0H/'Ã)Ç(Tôûubá —¯šeòà‡i$=NN¤Ò#áy¢°š9DåÇ©Ä~"½G‰&áy8!UàjGyÁCµWÌ.. uÕàϯÅ9) sL•ª‹£øô^\…3¿ªÈ%)cãdl™åÇ8 ’ÇH€s²û¡™qiz/*€?ø9&GÀbBªXèI³ZtçÄôU\¸$.ˆ…‹âüéÌ9H˜üÞ7ÖÈY´x™Lœå'Ÿ&KŠ—¥ï&Û©¹ÏnªÈ^ŠWÐÌÑï¶KhìP1Š(¢\ÌZ¤hùðfù ÛÅwNq³c8=çQi$u.ž+N—e® ï¼P©’ÍÅp™‚d0÷ÚñÞPx8èw¦bƒþ»ÞHx0œè‰}µ3æöðK+,u"Æq‚ƒP‚`5(<·ž£÷Ù—Ýèò|Ôåþ{§çÖ¢á÷Ú‡þ¶Œÿ`1øêþh¡óÆB¸õNÏdzŸv¸ÁÝO»ÿÙÜw«Ã{¢e£– hœdiäÊ·Þ~û¿) Âÿ9FŠÂýÂ4h7¬[4BaLHè &ýÄ͉¥úW—h@‘vbuýÄZýÄ:Ã+k k ‡W®Ò[­;Þ­xy¥éD·úx§òä íî%UÖj9L@ÊR8ÃP8ÅŠ1hÝSæ7ÿê„}A¿+Ý“€¬z¢¡Á°è±óà[ŽhxçW]æšÒ3ç7ýáX·œ„@zR"Z} çö´[Œ¨UiåÐí/Ÿñ‡Ý7Þì^dK*4´ip )á#þh`{,°ûQ's†ƒ;±]€óÞ½­ÑX¯áë×]K›kb’€U#gQ¤U„œîiÜõ§Þ?h§t¦O—õYb|sÊÝùØùñ?ªÚ…-'(iPäæzY ö'„ÐhgÁSSJ’æÉQ’HÁ%æÈŽª’@_‹º;ô÷—?;üѦþ#ûÇÎÎîξ·»ï½ï烂‘媨þÌ´ëÁÏxeb]÷ÝÚž›uÖ;MÎ?7Ø¿\o™0Ù—Rï¸Soÿ¢Þö§Fj¼Ö>n¦o5Úÿn¢þi¢Æk,õn§jm!´TÜÀíèè™ý&kdaaanfé ,Î/üñÚuFxƒH)Ú„ÃMŠ_¶ˆÏ4‹µ¥d¸U9º¹l´M6¶I9¼YòA›h¸­l¤U:²Q1¼Q~fGÑH‡h´¥ì´¹ì×€.ÛHª¦T\ÌÀ&†PÉ#x(_Èçºû«Ç½öàa"yÈì÷úèPÈôÓÑP_ÄÿÓH ÒýÄëš|DGüGÁÞ«×¶— ‚ L´ˆ'à1‹&ñ½7žz‚Ñžëè.%óø³c³èáäþHØóõ†}ÁðëÏ«?~˜‰½þ©Þ€Ÿöû­Ñð^ï×/~D©K‹±<‡Í'I’ȇÛÈüÛîŠ(¥QEYZìÒø]zßP-*2]غl5ì³ÓDý4G–@âЦ<’ÉbRÀ0ŸˆxkXU¼œ7uœ¯Öl× ŠIˆ ãl˜ä#Ÿt*2T¹·_wÔxmÚáa²Ha­â¼eŒÛ¥!Oͤ]—îÕÄm¢¥æ\ú¨]ù¬þÌP÷©¢áqHaS­šø®$îR'\†Ôi ——;ÿi~ö3$rî……Ë+g?D²—_\<—{éû/©I˜È•’\.J îVú»#/$¯ä:„H‘¼B2'C4r–ÿ ãyi${ž9ÿÉ‹©‹@V¹Éß®|Dš〠ðûàÚI/ƒðÐÍo8(%˜álh „£(QÈGpÉêœNŒë´>0÷Þ4Û¾4Y-î4ØnµØÆ7ØÆÍ]kpNÔÑmtŽ×Ó1S·M¶[u¶»­ž “ó®Éî¿m¶LÔQw×Zî5y.Ôí–!$?"`Œƒb¿9~‰!‹Ù…™¹åvÁòmÿ¡Hva±R£HãÀ(ŽrжHt#ÛKÆšd#â±vÑX§ôôfÉÙMec-¥#Í%gšEgÛË~±©tl£èL³d´¥ôl£b´U5²©ltSñh»t´]>ÒZü³:M»‘Š  ˆ‰æÂ„‰EïÿXû¯¯—btÊÝO5öíYvü¿5Ú;ƒ^OÌ×ö¡¨ýú­î!ÎÇsylŒ`³ì=^ïPÐ ¹Â÷Ðɦ·Þj}x-·&–ðcxÈT¬û¹õÇ·'Y²M `‰Dm~ïþNu–"/2\´†Çâ ´˜ð¬‹SÚJ§«Â.mØ©ŠÓz°nÏ:Ê—ÿ•& @‘¸K´*#vûº(­iSËË Õ(Â`|!;÷'íÊ€Û°IRnÓ+ü5$Éू!´U ãc¶nÎ.NîUÜÞi,e¿ 긢|>ÊeÿÈ$~H¯ÿy³ì¨žxH³.eÌ%ó9ÕI§áYýIÓz¯‡áKåÞžªôÖŸøÝê4- SfÙS®²ŒG³HN·)¬„¡Î=¼A›¢T VyÚ^¤uQ‡:ä0NSª¡µRÊá`Ü<‚<¼^8gQÇíʈ˜P—Ù½äCˆ«*ºGñ¨æº”±}š ešêÏ:%³Ti˜®»º­òHmñF)»NÅ{UŽþÔTro§6äÐg»*gv«”>E×,E°³4áRM;ê#Žªh¿<ÞSöÄn¼µÿþœëÀZÌJ…àùN )¥Æ;Ií!Û–·7y€@ÞêÝóçõžÛ½0¨[]Î÷ÖÙßïÝu«Ûù^ûÇ~öín;øñ×~©µŽº¹ºÙ¿ôºßÙèúSŸcª‡ýÝzçGë¸míý&”QÃHÞz«uQ#À‘GM‚G´VX(¤O?ËȈZBWNÁ´3~òVÕ™¥•úõÍ•Gz•tQ®‡q=¦!%xA$*ƼNõê…aá…xÔ/î{Óöxx˜çÙÅtޏƒ!.Ì Á}? 99–¯B¼”ŒC‹´¸ÏÝ›ví÷õڟמzySpî;aadfÖŽøÂ‘‡vRš›áâ‘¡XÄz#!?a<êÍLðÏ?ŽûÑáÈôw¿í²QœÀT(MË0¬ƒOv™c®.0&Ùº8·v¹S Ŷ‚ˆúêBsØÝó®MùÛ¶.ÃVƒXŒxcΆÛãi‘‘ánùd¨.ÉYBÞz~Èœ÷›f؆®>ÛúæS5a—97XÁ;±uQWkÑUóÆ—™B¯ å4A+PèÍg*’»,)o[nwû¥'R’ª)m0 ®Î»¾6ÁS—wT††»º™Ï‹”ˆ ì"­×ÄÐÕxÙ”¯§ÈÕGÝÍAO[ž­[j¿ao]ÈW·7Í væØæ¿m磌„–*êt’U7··f÷˜“lUÂc͸›y®)Vín]W£Äp gÔ$º¿§:ål[îû’6p˜fü¶]VˆÀP7‘R„ã#ñÆæÚŒÓšè<ØcTÃRŒÐ1ˆŽ¦É_lQ&æ¬Êpæ]½u¢ÔàÈr´£R(²àoâí¶×üÚÓ$!D¬TqId{ƒÀÖÎì«O;;JsÜÝuXÓNs˜³Ìµ§\y{cÌoTH:-9À<¶!æ±D}õqWCŽ} —»²œæö×»vV40¦¢i”@•4QI ¿ÙSQT@©Qi6€æZá^:ªŸÊ8!@@ÍEtüœ=Aò}` lUÈ4„F `Ta5ŒQ#‡ËNÛÕÅÃåùQ8tDÿî e Øãm¦Ôz3j†!¿ðòN탔¨y  “dò Q:†ðHߪ'PÌr•ža˜WG¤¹+’Òù•ù‹Pì†$3¹*=ñÅâ¯ÄÙ òÒ$Uº"ÉN®NMH–¬‚ËŸùûÒª[¡’i6ZW¾ó3({™)­É‰r“PfÆé×¹ÇîüX”Ÿ¤sãKVPéº,YTœå/Isã²Â$’›e/IrÀBcòì8’½Læ.®,Ýxlî‚zw—‚$I… Úi3›+e ¹B¡PôX…Ä܊3ûM]¿ísÜé÷u¼µ~÷û}ìC©ßwÚµ¸œQ`4Ó$qæÌ@‘t±¶Åt.Áw>Ÿ_ éÂÿ¿Qṳ̂J9›ÍFA„ÂÔ*¼â¹–‡¥óé-U?ßjùé³Õû7âz˜)aT a¸ø0¢"¥›ž©¾p“§¿ »ƒa{ðþ^!ä‰!ÄÄBÃ|Ø3t=r3,·F>ýË}$¡à‹ŸÜݡ†…¨–wða.$øƒüàC;oÐŒð³^`p£á!’Ù{.žÿF\ðE¦¿:wgýk(¦â"%ˆœìWã§6™øáµünËü`{ˆ]öY5â툱ÍIgC’µÆ=ÍA¶žwÕ§|Mawôß²¤Ù&}¼·ØCpšK;:B®ª9Ÿ)º¯+±­ãæÓM’J¹HÒ 9Ôª ¶×Î lŽz›¢\}ÜÙ:e·™(‡a£Ajœýr ˆ³ˆ§)3ØþO_»I1˜‚B/›Ø¬K Ø€yŠ®æ×ûb_-0Œ˜RÊh ¢Ò´¶×id¢kÛ[ã.kÂÛ.¸m Îê¥ö[d-!Wë7[”}ÕÊ­z¢ä9ŠiI¥ŒÀw˜˜»®¾  Žßq/6ãšouÊgûa—A…cI«Ð²ú ó^ërßÁÕõZSlÓÍç[ÉÕ«5ª5V‰¹ ¢Š‚IF«‚RB„R“â¬ü#O–ë,z­³MVJJªÅÁ“ÂN>µèÉ„Ë6ã³$]Í;j0 M«) Á•¬MáÚçµ³>sÔm³Ý·=fÁÓõ´ÞÎÚ„ß" ÔÇw™#¾fÁÕ–Ç 1g}ÒÛçA=*ÛÓ{ÛbÎî‘—’$ÎÈ%­6àe?yK%©îªSÇÊK‰ðK²ôaìßÁþ«‘ÿ€–8'ðÂ"7* ”¿2¬¶èåFR#L.Í© @cÇ©ÄIþ$ö‡@ÕF“‚*¢F¡+oîÓi¤  ÄqY4€”޾åDNµ~¥j%IÖàk%µ‚¢$SÇ4ÅK ÁW@/LóË WËs—ÊAÊgΗ®@ù«Ð’µpA”¹ŽŸûùõÛÔuÀœi݇5 yؾ¶ïÛ÷áGÞÁI¿pœ'IŒ]ÑT ñãÚŽI€B‡ª4,¡ÔNS¢Œ0VRpž&UhÝ(kÕ Ú­Ú´ˆ?â·smß•M•ú!R2¤íêȺ÷È:çøžãóÿ£¢ÃÏ 3“õQŸLð WÄÙÑB~¢(=!ÉþŽ™½/Œ3¹I T.µ}@‘äHAfT,LÈ2Ò…1qÊW †š¼òTød²8:U¸àC„H¸Ž~~ ¤$qp¥GÁË{‚ŒUheWÝônË ìr´Áýa§ý“¶Þ/×{–K#·»]GŒëq‚1¸»±…Oñ¢A)Âóüã¤Xò?|‡9~ø×H1ªTh(%J Ý™ç–K#•oý@wy‡fx›êÜÖº7w”»¬p Ba¢º"FM–IHµ‚QiÔ²ÝnÃí¿šŽí F39ÿô¾yÿá°ÿ%ÿŒg&ÀÍÆiv^ð-Y Âe†ŸúNò4ÿ."¼/FW-jäº\˜(âÇòRãy‰±Báš…xŸT.µýÜ8(’[䓈g¬ ;%ÊN!Ù«ß&Ÿ•™Q&7V´0Uxÿ·TGû:–ÀS“4 2P€˜j%5çŒÛ?ètÜÝЯÝu·ûs÷i»óÓûriäÎ÷Úl à$D à4DCÈÅóÃBößÍ.>Š<1"ü¯l&–x«Î¢Á4`P²˜j§N;üüri¤æâvõ]•6UlU oÔžÛfܬÜU‡arCX\!ƒ–.'0X³¦èÈë;îÝ÷΄ƒ‡üA¿g>ph.°ÿAÐñÄͰrùKÀM(80ëw¥…ýáà@P˜s/W¿Á€H/8·tyçç½þ™EF¢?ùøC[—±œDXß ÍªEOoÔ°ŸíÒàŽô­ó»êF@hÆm5aWýJïê)›!î0ÎsÆy¯qÎU ,”vè®9akÍô6¥íkýC`Àrè=æDOCÀ¹6اK:¬{ud%ŒH0´‚!Š”E„¢X"gEx ûj<Öˆ§ dÙø– µœ¢H ˆN=Ž<àêCn#è(õbùP‰ŒÂT4LÔh舭äKØ©KÛB¿õO/N·k_^[rÔDœß¤¾±sÝ_œ-óæ·†·W˜CÞ%¿¤³®în-tþ#(T)#ëaè%«ä¾½•ççܺù>3x!`1»¤ð}·å¨•jÑ*ºLª­Ztx‹>ÙkXéy™é5$û›‚=k·eaOã½=ëÝfCä¡ KËr%Aãp%#/_GaZÔ!·5Þcˆ: 1»ÞeYD‹‚„ï××E<aNrš„ݺ—›KÁªÃå4ÈÁÎJ$boˆÚ ao-oÓþÓÛÔLÉ”X™þÞ–ò¼¿ö¬sºÀ€nnÀøÐeäíú¨£¬L€’˜³!â1ÍzjŸ”F[]´Ïœì7áÖŽmµÖ©–b4«„)%zÒèñ’ôY¹ðjiâ„(9ˆ=.ÿ¡42X–:AeNbÂ),~cê›nªŽ’ï†äÂIiê˜ñ‚~¤SÜ-ƒÀÁ•'Ä`!†aBXv!©æÒä¾¹0õȳ×ë%>Ê5g¦Ý‡Ÿ;VU# ¾ÞôyÑžWÀÄA¹]COÍ0àñ+§íZ˜w, Çkq¹x=öÿµ_Ü¿¶‘Š`” Á¨‚‹ê+\ýJí±jÿNšŽu ¢nÜn “-«½«‡,ʨSOSµR±Ö¦Mnbݲ5hÓ&¬õq\ï#k\•×Ùr4‡lFÏ!ýœÝôvWµ\$ R`©³²ÌõqkËp‹üßy%.Ur '·×3ê¨æIQˆŠ¡’R.:½µCÈÞÉàú$Q`CÛª½„ÎOÔ‡(P«®²gU°W›"ôn‡|“\Áµ·vêd9P‘DË!Œ…Uàm˜ïGÂÈëœô(/1‚ÆO! AòÔ!KZHžg‡†áð1QjŠž* ž-Ξƒ˜Ü¿Œªžœ)eFŠ'±Äño~È©çÈy:9_È•)Ú4·ùïî… ˆZÇ{–F’çäᓬäHqrõŸ@ÃgÄY~ðØwƒo‰ßÛ—§bqŠ`!„‚í ðà(tMÞøfêÚfŠ“™fÇfòb7râS9À'ËÕBÔlQ|¶0pc~ÁÎ^Ä®³éINvй,Qœ-LOç378Ì 7u…³ÜþS“ìô,'5S(’¾žŸú(?1S½–ÇL~#{…ŸšaE~Yt}ÚÙÈ’ ØTR,âHHÊGÊÑÒ}š¶éüOö?o¤BþÐŽßÙH|ÞM}ÖCÝÚˆßîÀïöØVJ#w[ñ»­ÖOz¬:±C¨@€ÂÈ{—A2§R©Ïêlöyáwe²±f‘‹ŠåˆX$b‹H½âÒÖÊñÓˆr|[ù…îò ]Uï÷¨/_5¾yíØ&ùO;ËÆ:«ÆvTéBë¤bX Ç$GP‹bŒqwþ@{ó·/=öãs.§gá ÇÝûÜÙ°zY´=ø/|U³ÏG.RÁcÿ§Rìîj¥Æ]p‘`Ä—Íï·ÏÍõœ„èÓ¾¤(ƒEh Iår§`H[2?ÐëÕxö×ú‡AFöWfpu€Ò=1ë}–U×ȼ]>T²V¥(hmÜÛ~º­ÂÞ(œ·­õ5É~5c3…ûA iK¢„*º_á¡:»„Ũ@VÂÃKݶ¦(^"knôÖ·‰ 1‘*D°øå þ“ƒ­CÜ¡#ëJQÅ I ,±©àÐ@‹ßªñ éÝx“µYÉã¬Q¢œj úZ=+h1Òöu4eŒš® 6z‰ºD¿:H™üæ§wUÂ^§½—Ô,w¾ª"計õ{ûh’ÆÇ„.æP'(ƒÏ¬š·ª s³>Ž|6]€ÒЃÆQv²h’fEW†í¦Ð vÕÓÖªNÙþþZ·¹&ìÔ‚q“}Õ™¾ƦöRú‡ö—³3„7¥úêS¤Ék1Èš ¥¦Ú'¤v»ŒÁe%¨áówk%ú6„œMsøú#:1$§’R.R‹ºpSÄbqÝ}s“R*”!pP.•JQvn™€]Žb<ˆ£†sO7T=47¢veT€eë!M1â¹i$bß„ìÛ[! €ÓQ‹Ú5Øp¯O¿MQ*‡D¹" ÂòD|qRòð¨ˆ9{sQ#K& ‰’ÄqÌ7ŠÐg…‰Ó¥ÑØu¶`î\="ç2oÁ®c‚À(çË‹KòPTÎA€ï –º5; 1ÃÂК··pF·AÑQé³4–&NÁ‘7‹"§9QØs Ž ™óRϨ(sœ{¤+_W"â2 87rYc‡«ÂC‘©ÜÌÕ|fML³â7¿˜ùVöJÑrµÀL±’WyÌG’ÐÏ¿“šÊc¦ÙÌ$œád§yÑA‡ìÄd^v¶8qµ™E—Ûf–Ÿœ.NÍ07‹EbSù©YNú:”¾–›þëö»9¯îb—#ü<>.¥üJ¡BÜ­²ÚkëÜëü´ðx°ÎüûMäçä—í`Ãvü³Nâ‹6ëýõøJiä‹âV›ùN7õ†a&à•A(G„êMÆ%ФÓéÅŒÎd–²Ôü?¾&&&¤< C¤`)Ø®ñâù…îʉÿL‘ÿB#k?ØZ}qsíØŽÚË/È/m‘}Oýþ–† [äã;*'6—wk/î®¶´ ¥&äK \T†ñ&“‡º?½G,„»^yîlX=€ß%Š|]#~š¤=Ö…ù~ÚCú¼¶…9‚v;ô¡•×í%iÿÀ‚Û1çÂ=´Ã³ðúøOzuŠ|X -Áx <ìTçZÀ€¬¹Þå4yìÍn\²üƒû:mê>à^i§Ú@nï~~ϱcDZsùˆÏ\cH m9F+*¶Á°ã÷üžPÛ:1Um†X@•Ú­¨k2:u[! a0MÚ¡µ][ ªS)$¾íøˆããí¶ýÓ?"˜öôÓOO?ýô~‡ž~ßϯ¹èÓƒKnÄg‰pöÌP׃>ÕÃCqoÓ"Ó”9àš|¢}›J¦¬.S SÏ´d÷;ãÞŽ+»]¿ÝaÉ>g/z³‹Àë¯|«·žÖ¢j)%žÝÞt÷ŸÞj0×áͰ˜BÀ?FHë3¼úÌSºÛƒm¦ $Å/žnUขÚ$'nr= ÞáÛã>ëì.Û.mÙXê¢{ÝÍïö$ݶÖnÍöF<¦Ä )æoKræ¤-hZHòq¾+î3/úWœ†‘€+ìoOïù& [˜Ã\w–s,²†¸§5㳦6†YŸ%ËC¼!åîIxÞ±èâJ±Æ¤Çxà) èæ t”ê(z­Y)ë×güÚ…S†·„íal…=Ë[½F0ç¨G[Øk»Ã¾×FÒˆB…“$‰"Èj¦Eý¢C9lTSh9Œ¢ RCÁÐ~sÍ"ïŒyÍ1¶iÁÛ~¤ÏP ã‚ËpI£m T©À¤d#¦¢0% )~èÔüa ;°˜æœÏ˜¼;tÚgzX¹5h*ºY¿=Î7Å<Ú¿+èÊíi¼öÛ†…V·’R†Dd½«…ºyˆZ8§GP@‘ÿhdtY …±úÄøêèø—3#áe¹p)HòctÐå%‰p¼æö)êÀ&‘ºª7âteWrk„N†ó£ŠÒ¸(z|¹sa¬á‹4²8‚¥Gàü«xvNÂ…Ñ™1"quá}E¶ÓX¥¬…ĤL£Íõ’ß7f.)JçÞçÎÂÙ_—/=&œ¯X S¥éÊÒVš]%\Ä ç¿Vøe•p®:;]Vœ•ä§!a)ÎTç¦W¥ß}¬0+Yé÷ó3¢ÅsU¹éòâ…ÊÜLUþ¼´t\x ÿ9ømic£ˆÄY-¤"`9&&Å´Wþ¸çÙk}Ëk<—׺?v27œÌ˜¿®õüÍå½êbB®¯eo8F|WÖÞ7Þ\q±_Ï¿ïò­äŒÈ trrR¸ëPŠüß;äÞc5YœÖ‰ä(!UsööŸlÖžyJ=¹é~iÄðÆFýäVÍÄ6åé-Ú7·ë'žn™x²á§ë'žÔ½Ù¯ y»O5±±åäf펣ܘ—Ðt%Š7ä/Œº> ù:œFþ»ü»=:ÿƒ0Øüs‰è¾HО瓱áÐÜàý7eC‘@8²7öG£Ï¿vÊÕ€©¾VFPR¯Æ¨ñõê…½½ Â|[$`YðsŒi‰uDüŽ9ΚòY2¾¶×ð Oõ$ãÌ» ‚ßôžÛìTVW㸸N‹bu›Uè§þwú4:²J¯¬¼ÆOë<»é6ßôû- ƒä°JAUïn®éQUC0I Á•8½^¡zýqcrOŠÕeØå!ЬõcÞ®¡0†)LT‹É§6+3¬%»ÇP`Œ UÿÉt,q½‚G/0ê מô7Gئ ×½èëLzS¼.é·?$ù¶d tˆx¬±ÁådLèWžòÆ¥A}Ám.1kâ~K3¥8mŒ7ç9»0Ðv?ßgI/¯×ÚÛžbñ€1ÊY¬=Á7¥y}Òg‹­xÜ•–,×a ñ!SÔoûQ®+°FùVð«€ÝÈrÆÌ€6Ç5¥ý-aFºÅ˜Ž4ÛZ0Ä–ßìÜЀËi)ŠàÀ¯%ë‚1Z‹1%ŒŠ„þÓ75Ÿ³®tÀ²äm ±f­´¢ŽT#²:‰²Õ‰õêö6Ù4b­’!AS¤è«£Oo{»…=Æ’·l@c’{h)zÌó]t°9ÍYœ x5ÃY}ÝÙ!íŸeȨ•Iä8JËáŠNmkôEIvÏáÀ!@$@ ùW(aT’;!‰ŒÉŽ7ä‘©cÒ¹q,~²|i”ËÂÇŸí­¢å˜ •) âÖ÷ÉȨH8QS:BFŽ¢©qñ 4q¼ö‹4’? -À£G¥é1H8ŽåIs£PþR<ÍeN’ÿ8L¬ÑÕÔB4©#É6í#Ÿœ¡…‹_ÎV•ÎÑé©UK¾^šZ±2—ªS3¢Ül%pBzª¼pÏN?šŸ-Ë_,[:_Y<-ž­]š©-¥KÙ™U+ý~nª¦8+.^¨ÎÍTdΕf@‘_z¤C«pŠ–Jp& L&Ó`bβî†sø²ÓysÝå¾îÚó¡k÷.àö£u^’œ×\ÜU—ï/NïûØ÷6r÷K#î[®ot3W»Ù“–-!0¼&m6@è{)Þ}6îósoE…¥¼PJ…âÛ?;ƒa 2ŒD´xË;Týš‰õmoõ¯T+--›ïñ¼´Nn/§ûU¯oP™å" R¢¥UP\‚â”´É¡›ÞñÙÜËÙàóñ[dp8ÚNÏ™›ááÛQ.•bbÁ]Á;îD|8Ù ú:3þWJp08ÏÅãPˆù"±ÀŽsóéègûÒsæ"_}m;"a¥†ˆZ„è¢kN÷©Ã\gб.x-ù€#Ã4?èÓ;ÎØÒþ®4gO2íi ÞãQ_GÚc vGÁc9÷^}¹ÁëTS'­1Õ0)©©¥HZ°hLgdŸ1ã³ÿq«7 T¡B)ºF&§1ªCÅÔF‹|j«.Éö¼ÕGüê™–Ov¶¥ÿâ¾^c›º8€w_¶ICð뾟¾~Äq^Nl_çéi«xZŸo`,_Æ`mEð[ëLóÕb 5™ÎÚ” ƪ'Ü+®l³n3,ºX©Pƒmª Å4B³J5Áâ Ô¡Ueí–¡~Ú^sšvX*¤j¾’ËYu›Auwo}ÄmÎ9+2]-N¾ŒeC1¼ÄÄÊÿa¯Ú­ã]Õ)GE ·>n·„ ŽÊ”«܉¸jﻃBÍ´Ãø¤ ¼9±ó€ “à%>êªëu?¨l·aÌVó’•£P©DÉJ© ´±¤øfŸ.é¥ãÇá)/’ðªcñHÁÔ1"y û¯ ³IW¤¼Pö¨<}Rû›´†”Âl9Š«ü]ŠˆàQ/1Ù¯ ¿‘÷ÆÓl} ÉH•}¶ ¹ø#ö/½*ñUi̧~”RÀçNôC9í-¸õ§G‡)êJûÜjIl¨8â_25¼T¼ Í^*‡¤ÿ«¾«$‡¤â0”ý”»‹ïÊ3Ãùâå'ÄKÒØUEjX–õÃéw–‰Cò¿œ€¶·I´ˆ£•N‘4àˆE;+®¬êü¢Éþ]éâÿÐÈ­Ž;m€:ŸµØ-L“ L°4sîì  (ìì–ä2Y1³p@2K‘t:=KpnmnaJG)1D¡ßÓdüÝVýù§ªÎ¶—ž}j®52K‘ò3³ ç²Óí$§·{—ëÍJ\!¡(‚å8G• ‰±M{KÞ¾±/<8>îÅ:v_…ûâ£îÑ€û›ñ¾Ñà‰Ñ¾è¨'8æþ&äžü0V#4î¹ïöD#‡‚c38ãÐȡи ¬á™µCj\M!’\ÅHÏl³þûù5aÁ’fT²ó1gÕœ–{fÿª!î²$]|B¨ŠÙ SBeÐeй*3‚éëî’‘¾æ]&D# ©X G!–B 2ȽÜFŠŽæÉ.ã˜ËìæK•r DéÉX²`O£îýÆøÎrÑ^óIWS­R*CImæUW=ؽN¸ê†×kš5Ã;V~-¬…úy¯ï–IWSÈSì© ;Js.~ÊÝüy—õ[Ë+me¯¬S]ÙѼµ„Q(8‚6cØÒSÌÝ• OCÄaøp³Ù Aç`…¾zÎ÷4Fº«Ç<ü”§ôKO ¯’áœåP*ÿÝíâ¾êɃ ã‚%Ýe˜tZ‚¼~ÜQ7᪠æˆÍ˜Üß|ÏV¶£àÒaŠÌ ¤&殀Ç<ês¼Ñ~¢Ë”émû{·õ`£ZC£2×±ª"ü'fRqÃÃM&Å7‰¨Ošî—O¨’^ü!E¾¥ 4õB™þ’ô1:ê[|ï”nsÉ㘢®”Rø²ôQ¥è#†û*[ˤÅ2œ…–‘tÑ2.—Ãz%|¨•ñ)Ó'¹ï‰Gi$ê£bÇØ©þÂØayÐWñ«ÝÊb¸`õjDÆa²“?ƒÄ÷$â¥Åñ«Hú2-^Ο/ˆþM_–%üpêªdz¨0w¡07$ûÑ쵂‰wòDÿÒð üâ³CB8‚kÉB A1ŠTD‡Æð[ë–?­n¯´ßZïš/ÜYåød¹ýã5ŽÛlwV /ZžDDI±‚5ÔÕÏ´¶(¦2™™þž~p±PŽéÄJ¥R3óšo¼&)-Æ0 +Å˹Ùtúé²óíü™ ús›¾7Ì‚äaŒ§ÛËÏ?czksiw=^Ž „‚"HFNà8L@rØoü…õú_=ññƒ÷ƒ˜+4êž{aò«Cyáž{aG`´'xiÞðI0(„½c#žPÀ?¼ïŽ\¿~­NQ%0†4 -3éèëÛ,`ÿ8ã{EÒ]6’#6cbÝ\ÿKƒÞ‰xxj¢=µ?é0EcÜY%:†¤ÛštÖMöZ…õZšV”ÀÌ¡$Šl)Ãþ¸³ö®Çê±Æl¦,¨• Ûy•–Ó(ÐBZ‰×°…ŸîîHuµåöð·m•»V²ŠCÊ2=TpukKØ ¢:ÞS±[B{ù´P'zøD'=ïõ½ÐÒ]u¿ŸŸt•'lúLWÙTWyL¨Lõ´z a§ñÕ¸ŠÄµ ²•ZôewCÐ^Ûßä²è9L¢yzJÕQ®ö™ÇìæˆÛ·Õ&mewû·éŠ9„äpcäGÚøôÛt6NÛ áý­×~ªjS®º À‰PrÔÄvgÜz@PðÅ&<€7ÐÏõ:D»á¾†Ç’ê©ÚÛŽ7W™pLB ‰’(Á+ÕôÑa¯"wB26 ™:Ì$Žb / „ò `4’ôi'^ÇSÔ”OšðÁÿ|­ìÝclY)§øèemèˆôÖëœY¹D«9\ƒQ¥VPFkôPU>I+I­}ù¢ÐI}üò(„|\ÖÇ&¼±cdv@=®ùù Áå*”RÒMçß>$7úšfÄ‹‹çK#Y^Æÿãô¥¼Ìe,í‡þEé+àŽL¼ø˜xIvÂ…ëJÔ(£…1…Rp¬ž¦ñFŒ{Ó¼öÃ']w–Û>_çùsÓ¾ùÒȧ+­¶ÿm­ë³åŽ[k×VṲ̂ ô²šåHnÞ¼™{`\.7ÛÚ ã˜™Î·G&•óÚÐÞÁ±J=Â@ŠÂâ=µÚÁMÆÁŽŠÁu€†³[¿7>tWžÛTrnMùÙµú·Ûõ¿ßb8¾±x“‰Tc8…Wý‡ûzië¼ÃþeÚ´Œ-ƒ/ç~Žo`0ã ¶±! IšÖ¤¹-`ûøœcÀI¦¦›Ö(U–É´eZ#- VµêXÓ¬[§i]¡É&miÖ¥[§) `ã+¾àx/#“ö%)Q¬G¯Î—£c¿:~Ÿß©V@„#¸˜hs?ì½÷ù‹Áà¡`€ øù`èD*þbÔφf]É…“þyߺ3à) ЈŽ ‡C‘y.â#sžø¼/ìÿÞø÷p1\)`„RË©Z{ç€1ËÛrn]Î¥I2+£eˆ·ƒ¡Œk}J§xP F0Ò†X[ˆoŠ 8b›ClcÖm q„އL/”oÔJŠcP%ER!FKe7{¶dŽU発φìKCÎYq:>>ÒÝD ‹a©VTUIŠÔ Á>c9c­Ö“%‡3-UÒÂKζ˜³<7ì6exû2gõ邌qnȺþõýl%ï4%˜úØ  $ê±&YkÂk‹yöëC¼nˆ×Ûü€kûE—ögÒ‡\SŽ«1Uï?ߤÆH -Se4QÙ]£È°u< ϰÏq«"ßiÙ!%Õh5Š.ºÒn)¸ )V l™°¿µË@A²CZÙôACá„=ëÒE\V?×<ïk‹sÖÖòßÕqHâà=g×|’Œ=ÊêýMÒc(0ö”³åJ§©œ09M©IˆPRÄ_¢#ÂütiX’ÁVAÖÿÓ¥Ò£¢Ü|-ŒËÓçÊþ}±vh[ñSÁó¢Ì8ÖÓ"–P0…ˆ+%B›Zt¦:ÛA÷j„¤d.§Ô°`Ò¥ŽŸ“p[²œ>éµ$ùƸ۶à4§ó¢Çšb)¦mÝëûË 1È‚KÌÓsÚãÎÆ×b­·#ì±%YÛS—ÐÅxíCWmÞÓ’í¯ûwk”2-¡K„REYY))î1xk¦¿.ÍhÒƒúן7—‹¿,†ÅR²¡J?ío)ôéµ-÷7wª`–Éd¤ )z»Ó”ä·…ysâxcò˜1ÂXB®úS¿ ’(cïÈZïC˜·¤Øú´Ûœt›cýÚ´×ðˆÛ|}{-"#ÄÐפ˜R‹ÕÜ$ gñÈ%Iæ"¾ ’•Œ «IA™aa@e\F‰åKò™zùœ$;^â?]©•%˜T¨ö–—>:_³t¹bæ2ùðeü Vþøå¨£†X¾Œ?I#…‹dìì7r㪅q~L’8+JþˆþƒÑÈŠ•J9$¦(TãÞgo—¦'‹ò“ÖK#ù[Âä›XfRPx·¨ðËâܯS?)h‡Ä„†BJ(Ba™ !ËÅP;VùÖŽ}Ÿ63÷wpê`§·û‹ãÛŸmõü½›në_/|Òêùs;÷á–¾{;Ù7;ÿº…¹Ý|Ô,UÈP‚ $SSS‹™ÌÒÒÒJ‹?+Yýd³Ù|>”uøà¡•é’¤I‰æ°M5±W?ÑUùó6ýõ]ò›{ê®>÷Ej\¬‚¤ê§;ëoìÕNtW¼ÞQ=Ñez­[ÿÚsê‰^úôfÄLŠÐ0Q!J †HEm®ê7ÞwûC/ƒî@Èí €æ] ­;ž’Ìû™xôdx~0bgg¦’§‚³gF‡›äp™– Êp¢Ô+ª>èÕ-yuéc¦8ßõ˜®•âˆò¶°³>Ñg(€IvOé€kSÊÛœáÒý59¦:ïÕ'9cÐ¥K 4, ªc‡©Å¡¦Û»:¼h§–ºÚªÀ0%Lˆ¥åJƒ/µ×fxCš×†œ¶˜ÏèÓ<ÚÂÇo÷Øë*‹¢R©L¬”0¥Ä)…¼Üª˜ñmIzÌ ãŒ5ÒgmãÌO-(ÍoŽÓ¯{}?c ±uQÆ`ê—Xûc]tëy}„«ø ¹ iÆ”9\“à®I“&­F°ãǽ}çø;‰ǯ8契„! ¯uFYâØ¾óÙI°ý1UU×P (tÕXI€”nTC{´]‡†´©Ý ´4lÚ¤–%>¿³“؉÷K#¡I­©«í§¯Î§“­Ÿ}úù¾ŸßIáüIjnDÊÁ §ˆÈˆ$1"ÏœÊ=׉¤"µ,?Å¡öÂáõË×rS¿dK#™«‚ÌûëÓWʼn_ý²îX׆ Š Å0„K1BCJIJ[IýHÕŽémôÝZÏM[÷”ÝùQƒkÊæ¾Ûê¹µ™ž´9ï?ãÌ–F¦lô­&÷íf÷&ÇÃF×d ý ‘05ªPc„|ïùƒÙVÃڎ韇޹EóàvåØý›Û Ç[õ; .mûr4²pþ8åã»ÀÍ¥m…mù·jßîÔÿb·æ§-º @—äw ¨B–ÉBŽä,Á1UÎþÃæ÷§˜ÏbGýœof¶à$ë øªdÖÍÍ0Ü Ë=ÁÈ¡O½ðã3{Ø×)BII D\Š×÷›Ó‡Œq‡6â¬÷»,AÚóUϱa‡1æ4ñŒ5Òc\ë§tÔ]d*øžâ9Wq¼¿ê§öíݦÑÝ5:ªãlM„1ñÝe×:Jþæn‰ÑÅ»Í*ËÙII4Ï€ ¦Ô‡|_ ïªÀVs½@&útWuÔÓð§öší²A;üC;~uOy˜n›óÔÍôÅXkÌS½ä©»ÌqoY¬¿ÌÏ@‚ýFðñ¬×÷ÿX’´e¶$]¦E¦Œ§!—.ÊGØÂE·)É#té¼·2ì«úÔ[ï­Y8P:ë¬íÔËä¤Z„!Å"Á¾?ÇH’‘ lc ÙuÊøi• LJéÐM×vù.K ¯"ÉV¼··'Är&Q¥˜€ BT,EåësÕhîð÷û­3=–U–c‹»1q\;A„G…‹gáÌ+ î58ö2úaŸ8„$I¥ä›É׉Ð04?$N jbƒªé3B­|øp)“I¥RÙ†Ã6–——ÓéôêI¯×‡£Š}‹¶âüs†ñ6õÄæÒ‰vÝ…ã¹mòŸùχ¨&¶ê.··~Mthƶ_l+ýYgÁ[ÚñVÃåNóéNM‡§’p®RRx¾CI‹¸÷´ýæÌ¡ÙáfŸ_ăLÈφ}³~ïL௽¾E%ŠP8ŒŠ)ª_ßg³¦p—!êµs‡*À>1¶ÂӜӜfËŒ)H›¾òµ~JÏ»¼S7G—Dj>è®r0@@ ù$§P´¿žŠ8¬ } 3Ýe±kÒ]2½¯ÚˆÃjH ‘R Ê9bÈä|†gK®Ø•Û’y` ¦$è«[èQñL1Ç¥XxWÙ¼·*ä,] M§9Ñmö³•ó=Þc¸ A-9ëRkçU÷šëëÿ-!¯1ä5ÏÒFÎk öV™Jž®žwÖ„½VÎc°€+Ö¸«tÆc1åIºîú#%å`¢<Ï—ˆÞÝi™ØUI"Hª…Hò`•€DQV …!`j4oMŠi{˃^ë.Ë–“/!PœÌ‘ $¡–á q®TÕ-ø*HÂn+Xó@#Q—§Ík}w=ú´St”qlm´·H,B—%\U©îÒ³EB%.–Ê•$ûFm¡6ü’€$y[ÆVA²"“a$1"Š¿Š‡NH2ÃèÒI,4DrÃDbYÄçNÁüÏ•#D.…j.<«Éœò£¢Èiáò |nwÆ ¥›äRôÏGˆ'iÌ87 džò’CÒ…!ajŸĆÉôqé£c¤Eƒdà ,¢HdGé¦Åw×eK#™k_ûãèÆH„ðED2Ua¨‚@öUþ¦™¹oë»_ÛóIS÷¤í¹­à;Î{v÷T0‰{²‰¾¹™ý ™Î–F&›>×H£{º‰þC«ã£×­ÍÌßë{y!8)K|>_zyyµ»³íˆ/h¤2üç/\dGGQ“Aꟴœß®Ÿèx¬‚µÖˆnâÛÚ±íº±6ãD‡n¬]{¡³øòž¢ñ'¾_3Ñ |¢¿´©ø|»ö…b‹R$['—æà€@p UKaÄØ¨zsßTèÅ×ÃE}ÿôû¢³‡# ‘C~&ð„GÁ.ÐÏÍö†ƒnÀÿolæpÖÙðß&èäüž€¿?:‰x9ÎÁqÎ`À ßÜÑ`ï[o|'’Ê °i’e ,øÝ³ÞWï.žg+Â.3ﱬy1ùô‡>ÙSžtW‚é¬1A\樧,î±òÝåºÊ´8 0li1‚©ÄJ,óV!Ÿ±µKt]ØY,qÌV¤Â`!¡$DIöBu}þÊšÖaÎlÕòl}†¶Y½¿×È»Lký»ânË¿çñõ(m ÓÆ c y 1ÖÄ{L º4á,I2s®2Þm¹,ÑQ_g±QÜwÀ[)}H;`¯wwvfçØÓëµw½ö޷퇱´V jsïÚ.m¡UšV‰„ q4Q¥( wD‹7ªš*/AU!R¥¾D콯Ù{í顪ú€Ò@QV?­ö˜ùÏ~ó×|?vçA*y2¬"p‘Àº2¬=r¥x[„îLNÙAÈ‚s´G Ý9²¾KŠó&ÃõZ ÚŸd)6˜ùwù3´h˜I’s‚†ƒÍ²Œ_ ƒõ ¹Š!/hT~ÂYšôTè`òƒÊãrž4[?‹û;ZÁ”R!ë£ê[&äϳñ¦ÂÎlÈV¡í&áÜ­mZXŠ©Õ8„ì @1Ö¼úîÎv­Á•*Xe BcTK%¸iÜgC}1=P&Måqë|¿Q†ÊUD—~VÁá~Ç+½x¸Ïl1Èj’êU*I»»¹¿3w°' l0î¦LQÊ›šé‹ñý)~Sš€Õ˜e]IÖà< Þÿ¸×OžõUIs™óÿvW·^-AÄ‚ëp…"h¶Ü}E'“®ÎB•ãÍwÞBĹŽõ!Ì¢âIIô$ÁnmT+!9ÚfÓ}ëƒ_èÊs™ã¬KÓ 1HaØ0L ËoéJÇ$©*áèñø†üT8ªY›‡ËG‘õƯƒ*³ø'‡áŽ™N¡Òhär½ôWczqéùëxéR‹¸Ðš»öTá£Æò•âõ¦/«‹ÚÕÆêµ–âe¨|M±º$_Å…&q*]k(/Jk—%âšÄËÒµD¸"‹_~šöuᨠV锪6=¬7µ [Û,_¼10~³÷ôß·P·¶POÊÿ[ý¥÷@c€e’â©ÛË¢¸Z+$µZíA¤¯Ý‰_G¥TÅ’¸V«óGŽà¡”JôE:O =x·œ~’Ç­‘Žs/˜Îï6ŸêúýîŽÓCígw›Ïî±^Yo{óÙïÖgujÐxnÐxq/ÀŒõØnëÁ-j“±µU§„ H©Ä[ -J‰²õ™Í#æ‹ûáÝ;?MG}cãq*¡#ñéHêp*>‰43÷VÈdz:›ùQ21ýä9ñ•5’J†±H¢+áX4”IÏD#|,2‹•ãáÅ÷Gu:¹–QH‰ëE.ìë[9¸¹Àû¿ Ä\¤ùØS;Nuæ§|G,±²%Çm9¶gmLû¢¡MonRa6i;µD; ©!\ƒ„‡©üÝaó2ß[f»£3~pßþ'¿c@/E4*­RgDTj ÷#êTâÐ.ýÓ+ÔVñ€${dƙ㟘FêîšôX¨@†$Ø@Œï…7¥xGšµœ I[…´–_¶¬Žwƒ¶äi°±/O‹tOêU¡û–isŒíÊr¶ë,3Î í„+N:öáUà=€4àôsŒý~YÖ–çìõ½(gt¤ȧÀº AEÁ¥ "Ó¾{aO4\çGnÒ^·&Igšvƒ¬,²A@” ¨Nú+¾Gշ¤«8:æìL-±þ{áçÞÖ‚]#܆Á­­èÆ¥Ž"çˇ¼9f`q¿u´ÁжÈ ã{,êKßwDÃþ,iO0Ûœn¼è3Ê7”ÚjEá÷†zoOt¦½«ãÁ›û6o×Úrœh@1íϼÄíÉ:6J“>íHQÎmÍðVà“ .D7XœyÊ]¦}àÄ÷úÉÒ¶â}‘Þ ¼=äêBáfH©&T:EÓ UõÙ«pqVY›SdO4‹GŸÍ¼¡ZW 'T™y8?¯øÇk.'&Å¡ †‘†}6Ã6‹Â ÉÛàvÕëà–ã#úò¬´úš*ÿÝ·±ì³Ë~h¨ëü æ3»lg†-ïì´žÚ³®FNïí>½hÄpf‡úýAý¥½Fí¿í95¦Ûk÷,-B(:oSb8¨t²ÑC?:–É🧨ÏÒSÙô¡Øm:§ 6Å“|$ÁF̽¹’"Ÿ<'¾Z%“\<Æ&aÀTüp<ò“ÛŸ“BîDZøT%2þ׎J®Å!×#ˆ¼†?uŠ$Hs‰5U¦\± {žï)2,eÖ«tÈ™ ,Sö$i«rî2ãN‡ú–ÃÏ/¿ä› ç·š¿çèÀ° ¦Ý¡‡ Í:D¡ß‘©µ­ˆÆBà°Tfì+á.a¢;9Ýsi¿ß 5£ˆ–)ôjm„«u/*Y|éù{äHsteywŒµ>äYožqdÙúRœ'øÒ]~ÙS;àðñW`Þ› ¹âSîHØŸq(S‰éÊ“–˜åzò´÷¡U&½õ §œEÆ]âyÖ&pÖ<ßcú²Lot†æÙ`˜d}ªœ³Ä¹J¤½0a-&M»â3Ž•ƒŽç˲ž4íJ1Ž çʨ„œIÎþ¨úV¤ì ñ¤œ`[•é¿5æ§;¿ÙFH7`:ÑèØç²œ/1V7[œ±§ÂÁ;¤÷Ö¨e™îÉri­ÒUÞ–a6Ýì´cR™Ò„h´j|Ôa*Ñ6‘2$)—@uWùî #Ö.ô_Ô×yl×ð*jþ _»sïÌ^^{׋÷ðzïËGíÅŽC §Ò$¶÷˜™=ls(i¥*MJƒm0h…¢ †J¸ƒÓD¢UÕ¨F¥U%Ó6 øØûÞõÚÛTVÿˆ¥¦ÁAýô43zÍ<½yßÏ{…*1„ÒÐiÚéoL°€SŸsÕæh0Z`9àspŒv¨o©ÿ‹˜ &ðuE¯6álúE‹Š/@x_„B\¡¤MUQØ‹§ ³CXr€›; /¦…ð°87Ä)ÃÑ}Ò÷^ªÖs–‘¨´UABBJEá\´BÔeâM Š2GÑÙÁêÙ}ð ¯Ì¥zæóaeîÀŠÙ<=°¨vâÃXf?2wˆÜ/hS#0ŽÔBضià/GÙ Ë2cËæ.s—K³c¥…Kè7ÖÈUNæbIîrÙüu({©4{é?'ù9éËe©÷Ÿ*Ž­üdkÑVTp¿JL’8ŽB,'½ ûWwM¬§Ç×w„Š<ÒÈ‚C¾G_όضà0Ì'HŒäÕÕÔfb±|>ûß‘>77÷èäûÇ’B¼ýè™3hF¢€‡QÝÉ­êÑT§:@²p¾Ô©=Óª<îPÞXy²U1Ú®8áМ߼Xÿê“à=7´(G5'Ûä§Êšw;V¶HÏu¨vÔ9êÅ$óx8EЏøùPÅíüW¯¿õÏþT$05ÕšaC“}‘©ÝÑé=Áɾ™é‡&‰2÷ÂÎ'ΉoYÑÈΙi&d"áþàô®ÐÌîh¤ïþý®àW‰Oi¥”KPˆˆ’rpJÏ—ÝxÉ” XÓ^  HÚ§ˆ0uaÖ”ñÙRNíR¯ºqÂ~S¨Ï” è“ݵiÚ0³kÝõíõ­ò*‚ä•”¬JV‰qú-²;?ÑÌ޵ÖJIà`JŒw(¨`¯1ÙS“cU)_ݤÛ|lƒ®š·—@ÐSby…ßX1Á®uò»,a¯ºàµd]† «ÿî5ò€"¬1ÄÖEéú„§>åÑfYCÆoLø ‘€>ÆhÁýP-èÀhc hÃtc”mžv™£^[Økû é=¶VsÚ§ö;¯š>Ý®þx“|ìEåG›U¿X7¶Eñµu}³üÆvåíÃ]ocÐß¥í —5ë¶Æy‚]•ô*“À'´6áÑÅ]  p^ 3Èw€œ„ÇwZ3N{¬ä¸ ˆèAbÒõVñÕEukÜBúD¯%H‚´бHÛÓ;[ÿâ¶±L©Ñgnn1M÷êŠÒ3`RŒ¶Äüæp¿ñ¾WÚ© ùu*Y_cÖ)ʽnýÍZY W¢° ä9Ú©ÿ’QÅ=Æ"m› ˜C=’É@‹°¼LŒ¨«1&‰œ×2åÒ†ÜÚ°[e,À]I—8-JÛf<ÖÚñšã>cŒ}lúZ¬¦ý `2¤ýšt—²è±ÜešzíbT.Ä*9D#´íƇå¡a~ú´˜B* ƒœ¹!nñ°0ôüÉë«,U?”RÏ È帰†¹*~«C8±ŸÈ¿SZ| ¢~¶u…€(¯âK­HìPMáíòБ’ÅžŸ=Xš‡…÷‹Æ_©)˜Ç¯$ ãol&óàÄ/>]¼V^¼'/®,\…¿©F2æ®R™ó+ ,/ŽÁÅ+œÙ ¥Åëœâååó×Vþí„ÀÓŽá2!NR$‚ò0JTQÂM2í¹†m_´o6wÝZçyT ùþÙ:æ¯k™'ÎŒÿ±>[ËÞrô¶ŠV¥ p=÷ÞYà…Ba!ÒBHæOPÿÇ1?Ÿ/Îή¶Ø!‚/åU"¼ éž&ùˆã?# 2YÀÉRk¤æl‡ê×l¿Ý¡8¹uÈ/lwø#­‹õ—¾ íÔœz^sbƒê„C=²¡~¤]w¼:ý#í¹NÅi‡äŒC¶·©ªQ ĹBA%I!^µŒ«áÁ¢j‡ä—ç:¿˜Þ9abÑ]÷ïz‚_ù²±Ý±iÿÔ=ˆò`¨ï‰sâ[V8¸sj’‰Å¡;=E‡‚~€“d²ÿã~«Q&!p=K`u˜à|‡tÆ×èQ¦™º|/ØóÖ}†XÀui3K¿Ì»ôqð áÕg<šüÎÆÛ=:ÿ&&…B’' Ë 9λék)ôiƒ½Ú¸¿ah]}5§„À`Þ‚‰ûfƒ¤È6}ʤS•õ™C´ubGóûëôn4ýk›äfÜ¥È÷)ÂnqÚ[—s2.SŒ6}÷y’kŽ2¦°Çöè"´>Âè¬TÆÛ_Üm-ÈÓcK³ö¶ª/üXqxäÆj§^Ò¾JÔ"—*0ìj…BñQ„ƒ )A`A®Ä(ŠG|}(…rù(W„TT!J6I¨…t³Zì4Tý´¹æH›ââ&åøËš»Œ!ÖoɰöHa—ärÊ«ÏzuyZS 5Ñ€TÄk|ø ¦8cMÒö¸Ûú¸Æí­mÖk‹úŒÀ9)·"õª \ûÛÿô²õݵdÊßœc´w}Ä£+8­³½¦h·*ë1æ<¶T%î2å A§¦è–ÿùAR.Æ$$ÅË· ÿÝóÊ\ÿÐgŽÖ}0¤¦ÛÛÌ"ÁÈšjÛ–<­Ìúµy¿.Í´2ì×E&žaÌYÖœ÷gݺ¥ž?!·1æ7Eé“$ÁhЬa¢Ûº»Q(¨àã$ŒàêÞ&(|D\8À.ª‘Ùnú°45€æ–dž+BÑ©£Ê³êÁèkmÕ{· Çß§öQs¥©ƒÜ¿ÿœ\­æ#\ŒàS‚i ò+,Z<º2? ZìùŃÏeTFߦÀkߎm—s˜OrÅ|~ ‰^„æ_’½òtö*÷ßÔ×{l÷piÒT‰2BbŸ}w¿{ûíØñ+qìÄN ï„dM€l¤-¬Mœøí8Ø&m«6Ô–ðµÚ 4@ tŒ¡¥@Wml´j”ZKÛµ yÛÁŽcÇĺýÒLü±6¬@ÔÓW§‹|¾è÷óÝïû9þBæLúƒjdª_”ºÅ¿“ÅŸ¦þ˜•:#‚DZs?<º[EZ<3’”"™2 Gi²Qì/^{}µ÷ã ×Ge­×*:êïÕx?¬t]­p~TéºçJ7Ì¢3ã>sceûÕ*Ïk¶õb€¡hùV+ŸI}½}ïøñ?[ŠO]z÷]2K„3 ‡“ˆèzŸV©œ§ DÈãÔˆåðºô*œ­Pê·Tç÷¶hÕiÔä¿ù“…Î×|½×oÈ9VŸÝ[¯>Ñ ìkPœ¬Ïî[§émRjÈé]«>ݜݳ>'X48Ô:@|LNƒÈ ³´©vœoþ|¢s"¾uxÜ9tû¹è„; †G_þ|Ñ9ñ3>Ú‚£›p޵B–„Çùñ`m™ ,‘a2(4FHý¾¿ë7ÞñÂú+Œº-cí¦·R$äëÓ¸7ïQ¯ºpa‡+ü”Ï›:Ô¦ û,··”þ}££„ ƒg«Q\%Ænºì|›6á0Œ8-°[ $Í`"Œâh‚‹.n°'¼aшß<å֦ܖ»ôv§-¼Y ëÖ„Ö/'´­(ì´DŸ7%½vPßÌ=–„ÜX. ¯å®» é*˜vAœØB>ûÇ:°ÑØß¨ÙU"wæJW«$Ð`XZÈP†f &IÍJáÀq¨Àb4ŽR“@±(û­‘ˆY .7?X§a(’¦–@e .—9‡1œÈĨ–ÄêiÓŠ€ß_£¸Ð’û/gñ°Ï>î5‡ý¹1§zÚ«MøL1O.ìë¸ßÉuÙÖDÅ:ó“3ï,„N ê£AÝTGöŒ+ª•÷[BíšÁ x· Îa¤³pµ2Ö®½ÛiŽ#.U¤Ë æMA?8QOi³V`˜ a0‚N§qÁÔ™™ÑçŠx¯6ê4@ŠüÛ[ØšGJ¤ @Ä”k¤Æñ@þL‡.îRE]Æ)ŸaÚ¥»s’Þœ¤GŸðb®<ø˜<ͦ<¦¯}Ì]2éÍñhàËÊnùò7ç«Y’|BÌip9üw4>™ØËòÝÔ‚Z؃LíwöpSû¨äA‚ß&_Ç^f¢û¸ÄN*¶= žÀïFûÒNùĹ”œÆ0 FÑŒ\H€¶RìÓn,¶ÉL·r¡ëÏt§GˆS{©éƒË£Û4³OóŒÀûB„¤J5iƒg°Øù¬ø_2ù·Ó“oe<¨Fîþ퇱³O$ÿœÎ÷§'Ï-M^ľ<+=ý›åv½PÂBAJ)±š#¤3‰¨­öz¨ŽKu®*¥ŽëU®÷k=ï×ø®V Cæ›Rä´J¹î÷™OÊ]—+—ë6B¦€Ï/IŠPôŸçþúß6ÿžƒ$‘L9ZÛXš’‚ˆ¼µHsjƒþD-„ǽ@‡Ìç1hÄ´}P’Éfdr0勯žúÂã¦××,ø•cuÐ!Ð$Ù'5}ë BT}ò¾§ÔoTéO5NnÒþiö‘&í‰FÓ‰õy‡šä-f Œ£q–ŒÁ)Y¨mò+ξ×9Û9Þ2<êšó„Æ‚¡ñ-‹Î‰ï_dò_}á ‡CÃ?› m¼µ£½E +NF .–f’'šÍw|péVNûìðM3âµÆüE‰@ñd\ró]¶ ¸ ?ê¦v›à¿‹8 §çAâ6{¬ã•¿­Î–#+(DÎ iR”ùÒõx§ |Köä^~>ϲ4² %9¯Êf‡Ú‹¾Eý…¼'oÒ™3W%mº;›s? Å…<,ý.Û§~Ë„×Æw­Štä<6‡ÀAÍk$gØe XGý¶;î²QGŇϭ׋ÁZSÄ„8.Â01AQ p‚†Ú¢ šÂI%¥)21®B P àz,À‡{L‚‰¤¸˜è·'Q@‚ (‚dH††ˆ‡8a È ®osçásJ"a 9K3°Vähš…^Þl¢·Vçý£!çÚÆ‚ÛÞŠ _IÈUiÏM8M³nÓÚ®I~¦ÝœrÙ'=–Qt²aÚo‰tÙÆ˜_Ÿê4ßî,î°B%: nuæMù &!ó¼Eñ@ù´¿lÌa û C~ëÁj=”´XÂQŒR€ZuœT¸e‰³âʳú¨¯,ÚV³»ØˆQL,T“Kå$÷z½!ìÊ›öçN;Ì“›ó>÷—¶¥nÐ[=â)‰øàõóc>Ä$ïHð¡ék¡$Æ1H£®Ò¸'Ò+´‡Ûsãný-‡±V'ƒïJ‚`R)÷ꆥüKº…´0µ ã÷ "ûÈÈAEòd¶Oî‘ñ;‘ÉÝ\ò\r7Çïâ>yl+WËÓä*LÄÒJT°ŒÅ)%PIBÍ*¥äÐÎô…®y‰Xë&B;–𯒉™—~­- ÓX 4-ÁdÛZ–‡úÕü¹Ì»zrömáƒj$ùÖ þ,qvYüü’ÈEÑùƒè¦*J(Æ0… “IÅ$hŠVlÒ¯ê¯h½Qâ¹^⸹Êq³Òs©ÖóAâäZ™óFõ\¡ÏSd Ú3P醋ΌûÌõÊö+%­WªÜ¿2¬Vfá"ãvÝSMÉdr¾Ð!Hæ KfggOÿÏöåW£(pd#"FŽ[<›st½®¯nÞßÌ£Ö÷»†LN¤G9ÉJ½ùðFÙ©ÅÉ5šSë:_¼^Û;§íñ&ݱuúžµÆ7Öšzšôo6iÕë{~¬ë«Ñž.×ô•È{Êáu,GÿÃ|7qÝÿÒs–mI«½/Ik­uùuY¾°-Û‰0W†Pb[Z­V;t($m“–Ž 6!)ÉäK° „N4™v&m¦”‰M&´š†Øò¥Ë²d$[}Æ3ùT¦eŠK5ÿÙÙÕì¾÷æ½Ýÿÿ÷6Y5³-69AÒ Z‡ë(ˆR+ˆGôŒ¦J½çPÕO÷gÄP40ô>lKü×1ã ŽwÇ£/Œ%Æã=·¿èÙÛe6 Y,WF©Ut^ÀŠGüe‰Ž‚¹Àú)Á—loIBtÆ»J ¨ø€"‘ÞUϺ3B°û‹‹•$ÑJØ~¦<Ž` ¨…gµJ5Aè µŠQ®ý`gÅòmãl *"T¼Õ¦WA0KçñJy.Mýr=+3]®ˆÇÙëš ñg\ñݕɀ¸DÀ’ì,ÎìYJ§6 ”ÿEVbE#`†¿µòXMþcŽŽþŽ’\§"Q ã´¯E"Y„¤œDÁæÅ ˆ¤`bh˜aPšFÃh¦%¯!Z(M+Ê<‰°~’ßÏ2ùé¼çXþ9Fÿ/ãyuÑÖ,yÛP¦‰`ªhuAª!I*(\ÉàJSiP¨F£ÁH5°crW>(`Š ŒJEP,…»4ð®Büx£îêÓ¶ äˆJl>'zÍ‘n;pNX*OJå ¶9_Åß“=q¯3ÒeKû«ƒ]ÎŒPï,í5…E@;牧ÈL2é­§Ìzf E²F °jK‰îµ:»É&`‡aQ8‹€ñ,Ó( s)¤2Ÿ^*ŠŠæhgÕ¨`í+å<<²“gö[µÃÍcŽÐ'øLâ¢u^r®ö›s;PœÜñš|΄Ç`6ÓcMzœá^ãÍë¶"J®„YR§Ä0žV^Ø{iaþ(1Û$f§û³âxüE4ý²j¦_}5k©\è“ýñÙœV*G¥‚Á ˆh¼¬Ã­ÜU–“!¸W5ëù{µ?¦È 3¥òé×Ä^¢¦ŽçÛ¡BaDOñJç0èÃ~(óö÷2畉 9÷«‘¥wä©·¿›y?秘Ÿm̵Àkq£  ‘rÀïvþòÖ‘&ÏÍZñV4Úä¿âF÷ŒÕøÿZ)|^-\¯Ý=êÞµ¢×ë—5ò— 8޹ýÿi<&|Vë½ú¸ô~ƒ¯aPðþ*a’$ÇÇÇW@4ò5BH*.þý/•JeÀ—2‹©48>{àG4Á(²ÚÎs'[JÛôgW]Æ3 üÙVý™í–“ÛLo´ê†[ùsíù§6Y·c\.eu×ð§[ Cõö¡Mü©íä¹VîÌ&éàYÝpsÞéfÃ`+PÇýök:¹Õpz»qp«þ'5lƒÅeD.Ä‘¼•1*HÉâšú}on»üa8Ô zãû¦'}ãaïÔŒ?<ÑšÙ?=+MOíO=ߛ싡 1Ú75Ýûe°ça©Œ68!ÌLƒ±¦&¥Ù™np²ü00òÇn{"3/¦ý…[ ¯á!f”µ· >ã«Hv8c~WD´­vvÊf¥’XwõÜîÒEÉ:í1%®9Á÷DD]¸»(¨˜}ÚzG*Ž‹&p°Çvã)K¡‘C˜¢!užËl w•¦}Üd·cJ¨ˆùÜ»ìx6‰© ä`…úåJä³} €;þÉnSx¯%&Ù@1±dÎos‚+p„|¶ðÝ~’=&E½Å É9ï­L‹å)iP°üîIóëtÕf AQ 2Œ£*PÝÁ®ì œÄ…h”Œ&Q\À¶“D•š9@q?§u¯jÌ¿æ,ê79×ç iʾÊ+ q]_õÆq–)|‰1ôPÜ]K Å ÅrqLv¸,Ø…¡Ë¥!9Éa4¡Ø²aøQ+«j³_ÛÀ^ù¾=ÞUñT%½e QÁ‘ôا%`Z…Ò”§t^,ùËfEWÌ_~Gt&ü¥é”Ï9å³GVVM(¹ßu3¿(yá€3ÑÅgDÓ­@U§ £ÆX9Û‰5'`½ZÍ4D0&% LSNb(Îø1WYLác;òfý5áÝÕ!ÉñÓJ«ËLjo+qeÕ ž«Cf‚:·Yô5 Ç%ãj/÷ŠoIF*ÙQ²^›Ã(dœ&h5O‘Wz±ÙW¨…xn@‘9òÍX?õå1Ýâv/E¤û¹ðaøõ.‚Bå8lÄQ CYBy¤qíØa,õŠ"Ó§ܩ֒*9L[¹uÓÏËb}P48€ÍAýèÊù½Ú±V‹¡ë`@ik©I–~‡š;Ÿµð^öÒåo%Ïã U󾑺$_¸ŒÅ/f¥/+Rï*—ÑßÊâïÉ.e%.<’|wmüÒºÌÅGã¿!{UÅ„œE *’g“)×5©u/ÛÿS½÷º[­ö\[ï¹Y¸ß*ÿ·:éF­ï“Zá·øq£¤^P¹Q'~ä–Fê}#–3æö5 ×:>ªûÁ>Ýà»Qëýs£çj“÷³jÏç5žÑúÎÕÖäÈïÇnœˆ:ª¥ ÍSR¿ªyjáÎRzTyÀ’ÿ[¬x Œpùâ®F2‹KÑp¤Àd‘Å(ˆ–—÷m6·N4釚W[#úáÃpKÁÉÍ–¡mùÃmú7Û-¯obw¨êyNKpzµº§ŽûÕ–Â3–nýéVðHñÉ6Û‰6û©6ó` ?Ôlj+l¿ß~‹Nlín,j×oÓJ•t)‡+sXT«"q’PqrT«U;w9½õOæë4¸‰ëø—¦CÒ:ö^­¤ÕeIÖaÙ–å Ë’%Ëæ° ±!øÐ±+ÙÆ„öCK3MÂÎd¦“–!|QšfÚN§LšBjSlʤMèÈ>$K>d,ÛlŸâ´ýÄL=ƒ‡ìüµ³óv罿öí¼ÿïÕ ·…™Ð˜?<Ø<:Ñœm›`¢CÌhdßDhÿØø²=á¨ûìØ¨w2ú|(P$™)þ«‘‰ñæ¡Èþ…!j4|à×gjÔ’—$‰ƒéæ¥î6R½ Öiá¤'{ª¹œã‰Úºº«èb“9ÖP[ËæáF}¼9?Roü× Ùa>h×ÖæjZÖgvo’}íÕ´€*k±†5]Õ: Rp"™'“)‡Êuóãd‹…cÌ“þœŒãu庫ÕQ¶ PdY#`¬gNÓMΨ· Âê£~C”5G|P£Œ¼½96'ñ½¹S¾âÙ@iŒ-œnÐõ7ÚÎm2ìÌ"Õb>DÂ(‰Ñ¨@ÅOÁŠ@Å"õ‚1EAÇE¨ãW‰È}RõòìßÊ ïÉJ†h[ˆv|-³?”—öA¥mHY:¢,N(B–ÿ¬4"(- J‹奃rû²|XU”—÷ÉœŸˆ×¿O˜¼¸¢œ u$,¢„`­ Db%HP¢ \"–b‰ !D&áY ¢Þ"¾¼M3äËš dÇü9Á¶œá€iÌgœô™¢Í9‘@Ö´W¿à1Œ3º(kšóç?f,óÞ¼ÇÞœYÆ8ÃV¬&wΓi2EÚŠÂLîÛòávØ6‚¥Z„ Œ8jËsñäßÙ[º•FÒ±t*Áê<£µ|ÁÚêÅ+»Ê1–Ä—³Ï±ßŒééR‡U4ÌÃ$|1&T’b%)Sø÷ÝrÌ]f³ž—Fâs˜-eŠ>ÛY˜%JåÉ) ¢prSúð'xè î„$ö6Ä} œ9Ž/K}šbo˹÷_ú4 4"©<“RDô½K^*tR´ðKãÔA!w,iì´$`C^3¤ÿá Pdþ¾¬‘e$Lò”þ?û©ÂH¦‰q:Iˆ©°5‡1îúã7Rž\çÍ_×éÜ5ܵô¥„ñ«éO®I¹K©Ü5wŠ_YÇ„ÜÄæ/!ÜMÁÅ|[ö ˆËh¹–‡¥JE5Jþ<ÇyѶ£·’ý{s×îù[¥Àå¿gu¯´ÊîlºSîészFú¾{oY"@Ÿ6ï'sßÅö–{?/«ïµ7Ü/÷ö¹˜/]þû¶„RzAØú*<·\«®  H\œq¾&C0%¤¨8C©šžIPä?ù¶ÖWÿIéÉ·ÑÕщAˆ„¤ä8I-í¯+Û7gvWguÕ¬¶Ft=ÕÆŽ-ú3›õç«ÅÝ5—·[l‘j…)SŒEZË»[³®ÖI.:•].}Gþܦ¬öÆs•†ŽÍ Íùõ¹«êÙ¬=_¡;[®é¨T_yEÓµ]ó–KµÇœNK(°»€D"¥0)„¹¤ã@Yg?û‰Ÿ…"máqOl„ FÞ¥„Z…ö · D÷M„ý£# “îç¥À!@‘(`Ò¸h˜P´ƒ$£#­‘Éæ[¿k4* –R<8 ¶«“oï±q>Û¼Çj6³¦ÇÍæiwæj¯¢ÓK¼¾pا› h–Üy!výïwšë ü X(â d<^&,Ä`JI½åÔ-ùJçöærodî65ç* ž@I@‘*… ?ÖæD=%Ó»U½š¨;;ê+Ž·•Ä›ÔÀ!˱Jù/Õç=SLIÈ—7åÕÇX#øG!Ö:È™`McLÖ$£{³ïÖç­4•k)Ô= "'Å8!%0ÈA Dâxн QG`õ§DÁ?%Îtý]2.+~$K`cˆ¶ ÓfQ©5B['eVpwT^òHQ @2´l’gaYþ8m™gyá0mIŒûÍèÅA…uDQ:ª* ªŠÒ[â‚Oðl?©ª!ÄzÁHHH`0J`ˆGé4T&ÂH0M$™š†ÿ€­Ý¥ÇÎ:tÓ{ÍqOÁ‚×óæ~CNùóûó§[­^¼4Ÿ&ÊègÓ¬7Æ]´â©i+Šº3Z,÷¨c?* ìÛÈ$£1Z Rkeð` "Ò ¤‘Çùò¸íoÚt&j-$QˆÀˆó—6:'š fZ¬S͇3PA2A.^‡ˆÖ£ˆMÑñø<8] Ò EJ½WFÏùJž—Fb>SØ] XæXË…ºœLA T~º7‡yŸ9¥áŽ)ÂïðO¥ÅÞ}ªF–NAOŽÒ“Çáõ/gÂÐ6ï«ãÒùCâ…Cü؉äÅ“Bîx ž&‚Çî (?IüŸ™;Müj„¥c2‚xJß{(w}íÒMhá Ÿ»–Ê}¼h„û8éÉo^˜»¾fñZ¸5w9‰û(…ëY³tóå{ŠW‹Òi{(LðQTH`¡Þ%1ܰ×öÙÜ_Ú™¯lì@©çN™ûv…ïn;à`VZåÿ\á¹SáMhÄîé·¹C@ã÷}W' rØ›î‚F`’JŒÒg÷õ:Ù¿–ùî»üål¯ÃûEsÛåYmôÙšú¸ìž»v÷Ÿjü[DZÇQœ@a¤óBDzF¾ãá¾ÁÒ2H@Î ã å§í ަéZŠs¯¨/T©{ªMç«V[# ¶Û«ôUÒî J€ÖRü¢\/M& •BJd¦Å?.Ñ\¨Ë<[£¾¸îÚ(ëqÑMO•¾{«±«V×µe¥ƒÊ;7dtoÖtnж»´í•†ÎjmO­¼«®ðxµ1¡p1†QXŠ' ,û7óuÛä}ÇüÅ4Mk§røzîÇÏcûñ_±c?¶ã8ÍA UYÑ€Ä×ã#P˜6µo¶©ƒ†cGa)GAÓ€•¶LÛØV±\Úq&!qlÇNœÄ$'Þߣ­´¼ˆ¢ÖWù±=ÏOúÛÏïóSP•â¿kýà†'>Â%áÑØ¦©Ø–XÄŸ寒¡ÑĦH,‰G“áñd0•äž—FBþ'`,š¯a,¹9™ØÖ©x×íÑõ÷úB5å0Jj!žŒFfZtáU}*\áÌãêé€eš³¥¼ÆdÈ𬟢р-ç3t?;ë¶ïk]T.*DDÅDó¥²b à4‚,â‹ÔZß`D@óJ„]ã!ÇK¡ ƒP‚@4Nºø&×– ؆ìSA6×iˆʆú4gýŠ=_³äéâ$2§ýås Tš³§B6p8³AõÀ[?Ùá¼·Þº…ºFÏ/Æ J ¾”B(\,Ei¹H¦àK”%dÑ¢žþcöPºsrÇ-Um\Y7¢¬¼£²^/3Giû°Ä>È8ú••ª¼7bòꄬú¦Êr[i¹£`ïÊÙ¹øaDLâzZ”Û@î«òéWYóQ[4Ö¨œf,ý²Š~†íWÚ˪†TUC ×€Æ5È8ïR•'­o¡ª¡"„¤XŽC(Œ”Â$D2bBFA¸Âä$‰Š×˜Á¿Üz÷5Ë£NS.`ðöèã~Әߜo¯ù³Žûí£œ3ªï¾Ä¼Óàš>#`aÊ­šðk/ºí#Îð ´è¸-CnÝp¨22g:µãnu*`NxL¿uÀmë`ó. ¦8՘ϚÜlÓó IÂRLY… N¶ÛF¸e÷<®Mub¡˜/"hX(a¨¢/×U?/Lú,“~ýgŽúôºªö6`L ÅHƒqHü¦ Êtã±m‚l·bìWÔdÿIZÈì%ßÂsïH"Ý’ëÅÑå™î‚t•Û'vS{(pNúí¢é½ÈƒÁ£íßyœ¯òõá“®Ÿ~Éô®±b¾ÐŠW× ÙSèÌÙ‚¹³EÎ.˜þ¨hüTá£3 sþ sî{S¼˜ù°ðÑûŹ¿.Úí÷Æ#ž‰±@*Ò‘Šz§áTòõØHdlôõøHðyi$ <0 pH<ŠEƒ£ñ0(2´5ÂTN 2+ñ’“/ç1š"œÌV9¿sÊmKrlªËö¬Ÿ¢)7› êÇCƈßul‰|æ‘$©‘Qçx¡æk \Êç¢üû‹ú;§¦x—ý/íf‰ djX$ÆÅ»ã× Š$h4T4ò$ÏH#ie¼Óój'Ãå‚àkÂoøM?kÔ/S¡ŒG …Òˆ Œ °)ÆàR0²j1j%©Ü.Ñ—™‡ä–»  GDf‹Òlœ¶DiKDnVÙ¾PÛn(QEpÈ0SÕÏTÞ’U)YˆÂQŠØ#Lå°Ì™ÏSÒ¸Q„©–9"RGLfKÙ˜Ä:*±€5*µŽ0lDÎF{¾`‰#&q *­·æ»e,ÀITâŒHª¿d\ÿ¢Ø-bù*!a*Bd¥ˆÂIŒä“xÒÀ„"\‹I:L†ã+íý>vn«yΧžõ†'Õ`7Sœlßt°|¾û2á·¥ÜåÞŠ ¿#Ë™rÁ²¿fÄo?°Ší©‘'6§ÂšqŸs|£q¢«b*¬ïªL{-3^ËD°"f£A{ÒãÌ­¯ Ø?zÅÈ ¤ˆ+IL Cç×ZS]ö¬×4·Y}?`êqHõ0JÊ"ˆ·µ¦ìyi$ÅYS[Œi¯i"ÀNq` ¨þ±EAŠ„°”ÂqžB ?ØÎ›þ½hrõð—âÉÝð“´í‘¤zŠì€g¶ÑÓ=ü¹m r;ðá½ÈôNÑä^mbt¬û…™íE™êô.ÅäîpæãüEž¬‘‰tvOÁå7Pª”R“rŒRÂ<Þo»ÌYÀ…™3/LŸ/IŸåÎй?ÒÙÓÂܹ¢¹Ó/Îü:¼¯PxP1F”ÈEŒ”, |¤êÖ,½Z¿árËúÜ×êúñ0Õ_ƒÿj#—Sï»Zã™o—¿WÃ]¯õ^^ì¹Zç½Vãé«õ^¬óܨñ^käþÖй˱ü5kc” œ¤E0E R:¢¸M©¿Ù}µ–»Þ~Ö¹Ò+ÐÈõ%¡.÷…FÎKq#ÁŸþûÐÙ³Ùl¾Ëg³ßZ“|SØììlžOs9ŸÇ‹!(Ix$O¶Î`8²ZÖÛ²èh›òørÃÁg®ÃáV0)•k×hÑZª?Þ¦Ù×fùͫꟷ@. HåC"\30!À˜S&Ýh0í_¢>Ú¤;Öª?Ôþ_æë4¨óŒø§Ó\HÚ]­v%í¡ €.tsÁÛ×N™8Øè²1NÒé$“¶žÄà3Ný!±¹ìtœN]g:ñ§Î¤GÆNc\7© !!qŒúÊt&Ÿ<Ϙqwžyç]ÍJûHÚ}ÿ¿¨]~â>uv–^h–ôm¶” îP\lVõ6k.´€N„çÊËÍšÁ=<ŸQÑB.J3p6!€‚Â"ˆØ¢ò«N|é›{;>嚟éJLß|<´8”J¾‘šûùôô[ÏJ#ÉD˜Ì$;E¦¢`’™D×tÔÿö!Êw…ò¹¬üs-êTgå‚[“è(Ÿòi†l+SÌ¥MwUÍxj©ýØUô !Ö®ÌzÊîºÌ2îK¸@HÃ|.‡|¥ëo)vkÏÕ‰Œdqœã|‚Ajøyi—cÑSw™²nËaƒ(QÊùÁ»áTWã’»"¨H²$ÛeëA݊˼A‘ÍÓÈtGi2P¶ "¯ÝkÕ\k‘ï3‚'“<% ‹pÑ\¶C ŒÖÀBQz¡DÿU©yBbiþ€²Šj¦hsThŽŠ-±mRR5%¬Š“Ž„LôQZ!+@…©Š0­›éÁ'(-˜G„z@‘Ge Ó•OK#QÒ6IÙ&HË8e[G¥æo%• îËÌcó¤È¥LÂ8AÇÄ&ðbBhO– È4&±Þ/Éc|Ã8eÝÞ*Ñ}D«v#Â&·QŠ¡ çqpƒ ³ †DöW*¾yÍö˜g:ôóå¼W²à’.»•™'ÿ¿–|ºE`Å{Ìå˜n7,ÕK^ùŠWŸ 8×\ÚØY¶«l¥Uµäw¦‚eÓÞòÌk²¿jÉ£\i“/ø”é€zÖ§¸ß¥ˆ-Çl´Œ]€£RœÍ{ÇL¬å¸+ž>¨›i•/ѺŒ ¶À¸šyüg¥‘H§*åÕ¦<š•`ż¿|®]6åvüLI   #x ¢Ø9$LddO­¾Ï}œ’ïdÏb™nVæ4=šŸ=,¿—?{ΜÌöÍŸz>{ÎvSËGÑ¥3Üä) dC#ù~÷q9Ïä­ŸyáØN¯ˆÀ!—)DŒÈ;{™½ò“åÏŠW®1²Ÿæg¯<—¹þÃä ÿ|kµ¡hÄÁØ8ÅF؉IfAHYõy­ûvCð«šà ë‘áêÎaç¾Õ.Îw«½#6w®j|wœþ[5ž'Mù{µþ›5n››uÞ[v×=»çn­ÿë:ß×õ¡£õZ‚„8Å‹)(f"s †8,q”]Ì.hÉ¿h9øMmð¦õÀfkä†Ó{·6¾&phòŸµþ.M ¿ˆÅÇyÊ™’}uuõ¿Aÿ¼e2™ì#2†£‘I‚/À¹¿Ë²¤=õâ¡&éù:q_ƒü“ÒÞúÍÖˆ¼·^<Ð,Ú¥ìß¡êo’^j” 6©^©Ø£ìÛ-ënäm—‚B°ŽeBÌü|~­°âÃFé@}éå@#Êm’KÎ'=/}¹IÚ¿Myq»æâŽÒ¾Yÿ6EÿvÕ@‹¢wOùà«àâÒVúwг/Ëö ›„x f›€ ‚0¹¨qvjÎßtÄKÿj:y$>é™›òÍʼnxg4vøYid:œŽ‡@„Ħ‚`Lͽ?ú`¸‰8ŸB‹øùyoZ%³àAÒ%ŸëÐÇÛÕ+!˼K›t—¥›“Þ²wùf¯¢“-Xض){ëiÅ¡"ZÀÎUË_ìp$½ê…ƒšd§ýÓŸV:Ìb›%3¹ØMB2Kò…eိ]…^k+_öT§_פ}ªµ6uü°qÁ[–éS®ïûß$Ìû-s>óÝ6Ýñ:Ê,eA8á’–€„Ÿ§`6Á¡a͸}“'ÿ½Èö jœ´ƒ ‘¦(¡úIÚ2%®š!ÌqÒ¡Ì ýÇ(Ë8m‹Ðö( @bˆQưØ0&ÍÕ±nR¨‹SºQ± ¨`\bž›Ã"óÄ#Bä@ò”4–Ø"Rû„Ø:!Ì),²†)s„¶€&'iÓ‘é;I! Ü©©Ê˜À&,èÜa“¸1Ž’¤9)²Åiý·”q„¶‡…Žy‘uTbì£T”Ð@0Íb¢,XsHž€Á›áLIQ^k)o YùïýeK~õj¨\™Ñ€á‰5Ð'”ÌxÊSµsöD°lƧY 9ÓCÖ«^ôYf÷«³ý¼¯2wmø³‡ 3íšHP9b™ ÀÅ?Ь¹JýÆVZŒBÉC±_Ú‰•ýê”O [ßW¹ê7FÚÊie`&¸øYi$ÙY‘jÓ‚ßj9¤M·ëR€s!Ãí}zQP‚ˆ!´â@¥Þè¯ù³gÑìûÕÂÒ9|áÝçÖŽ#‹©3hæžý€Hw¿˜>ÆÈœDzò{^Ìôð3Ç<©ãÜ €ÚÐÈEr»ùü•3Xº›¿t"º³ˆ ”ÇÇØ$xgoQì ’ýÓKkW¡‡W ³×_Hÿ‘1rðîøþ˜Íå#…Y¢BX¾…]M–~f}ý¯[½_Öyon l=rÏžãÇpµç_ΠÈ*A ;r/×ùŸ4åo;}7œ@02¹ÓÐñyCûo,-z„(a¡àQÃP"„ãÀ©½Bu§ÚªU¬ÞMÊßþVëqþáÜ\Š€ú{•g¤ÚÄu£jÿíïí*ïÕš6-,‚Ãlˆ ÙŸ54þ÷–CH6»¾¾ž×žÿíÇs9¨M‰ ÅÐêR½¾¿I6Ø$ìmP m.E@©{†Z¤}»€+J.6RƒµÒOø—/—]ÜVöñ.ew3¶½´-”Ã(ýêë4¶‰ìxÕ/U©–†ö\žñ5ö؉ø¶'vç2vrp4ì–¥»ø!ê¶ÚOmé–#µbWˆ„$ÛCU‹ºª­ºEÐí‚w@—k—ÍeÇ÷çÆ}‘Vꇖ‘¡Žÿzz3’ýþÏ~~ÿßÈʺ̆¡.Áo[¥¿Û[>´W=Ò¡\¿F6¤£Íe#»Ê‡Û—׿ D´ª/ƒ4Úʇvé/wT\j®ÞˆBžm”ÖRˆÆå`k ßCx]…k°ü/ãî¯R? G˜TÔ™Š¸£_$þÂ4‹E@'ïD¬Päã$®æC/ q~Fu(à/œµ‹¬ù™«,Áš=f°Å<ÚL@¿àUgÊÔÑ «ÚÏ‹9g]&Pe4‡hˆ¡<¨”À·Ýï1Ï»´iÖ<çÔçMošI ºÁ¶ Qü-›rŽÕÍú©ø‘Ò´·fÞk^qêò.ÃD¯*}İࣳ‡Œ¹¾z`•¸ÿ?m’F®0 ha5ô2ŒÂ±Å% ãaU|\L½_f|L™gE¦¤˜ž’k'eºiÊ¢*ÃTUH ü@OI“¤q’¢§dô¤œ䘤ÖbÜJ¦É†¸!,´†„5€+€!q¡5&ª™V‡EÕÀ!“”y‚2o”F¦Åư´2$1/…Ȫ±eJh ‘5OeU_‘æ !=#¨ŒˆÍQÒZÀª§ óS=!5­MGVù%ez"1|)3NHëWBrÓ ¥›@ªaÊ fñyií0¥þ¾€b…;p„ãBD$ã%¸|“bn‘ƒä¼Ý( öX²þÊ—r½¿KŒ1eèr~-uÚ«Mô*R~uÚi‰û áõY§]õ‰£Ú#I¬Y:îV§ýk‹gÑmJ{ À'‹þڄϲâTýi¿¦ˆðP„D·¶‚©Nª3^c&PÜþ×*JøÛE…Œ+¨(¿(<û!ÚOG y=øï$ÜÖ)ÖœgølQb/ÍJ‚%(Ï®$²'ÄésÅÏÓÂì '?È_8MÄÏi”,ž(Ξ‚OC ƒE §D¹A Ž¢p@Fqy:,ãÒEú ánj5P™ôÔ}ÜY1ÃÔ®:é€Ð(éVçz-)_eÊK§XcÔ¯‹-Å@ ÆNžó­‰b£ò_ôÔ\Ø©à"• %8&ê­'ògd©A$ûö·óç„s'¹©“âå3ðò`Aê çyŠØ¨xvË nI N ‘s"Ÿ¦¸(Ç#c‡æ‰?ã«W‹¯œêõß!`®’ÃG0 ŒÁ ‚ß§mü»Ýûhg`¼‘ùÌÆË//ÿóúu qŒ‡ƒÝ@# Oï£ÆÚ£­ŠwÛJGºäcC›®‘²¡=—š5ïuêÚ¾•Ü.–À\¬ÏÅ Ú!,€ôúÓõè>rdOéï_¡/tÒ§ZkÆ^“_Þ 4¢éT]lUtÈFZ7;OíP;@šþWKY+¢@ùœ)Ƈ¸0NpDE…¨œ+ñ«ŽtàIøÍ¥™ãÓáÀÊtïl¢&Þ—1‰¨3œrÍFý³ÓÇ6[#É„;;63s,™dbE3½‡ö¨)dÁ… 0:nì·N÷Ò9¿œÓÿf¾Îb›¸ó8€¿mW‚–†¶çòœ>ÇvìØN|ÅgN;1!,Gè¶Ò$¾/ê¶{D!àí³AŽ¡ª[´ó’Ür—u$Eu)c\d}BË˜ÈøÔðŒÌn[ï*Ìä–)ií¶îŒÈ£å¤°„"Êp.à‘4!à“ ˜Š(Á¦ýñW»ÀÍ7- ¹éÞõ½>ÍRȘ ÒžªÙ 9±ÄWÝhXŒÙæ»×ˆ"@§C:Xÿ^XÌ/"1±„K³èF¯ý×b ^l”Ñg`å“R¢dhOy6lškr‡ª3]õ~½ˆK½pªÃ¸Ð+Ëvë|æù5¾_3¶eÕ… y~Ÿ æ'„MÀ!àÁ'øƒkµÿ’W7µ¿a#ÁSŠð0Æ—Qe½„厕¤úÙÔÛ¿(“䎢sGñÅ~4„»ÞY|«dü¸,ÿV8RT8úü­?JËÉbˆ`^ÀqñËw;¥í¶ç¤Ô 0#ÆðV– Q±ùou]—›B7ë#5žË à‹.ÏðÖðõZÏß}Wä’Ó{BÝü²ÂØ$’Ÿ¨Þöe«çƒÍjz¤ág·ü•&ÿÍÆÀ5‡çòöƒ=Ž#”áó–Þý•³ûfsd¸ÆsµÞwoKlÄþÚÙsݸb{¨à;§ï{—ÿr]ïHKäÛ-?[Aÿ‡F®7úÁ 7x‡þá¦ÕHL¤‡B4Šß_¼ôMa¹]ʯ–ž®:þ×±²:Kˡa!À€îíÕ>îžßªr«Nµ”ŸÙ!Úœ°Þ-¯ìPµ©ßw–êQ¶‘”B8‘8Ÿ†0Æ4ŠL¼•Ù©øëVéùmÂ3.Ýà.°›øÓmò³;4§·W}²8A~zÝ5¢8ÛÎ~±ƒü´U~z—e`»[ËüÄ0ŒË§XH—ฆ´½i¸Ü=•øýXºkf"0ûèÀôdßDúàh"89Yÿízkdj—LE&“žÄXl~ê÷ÿà¢6sq¬!IÇ>hR.÷™§#•ãAÝcŸa!T·Vé—‹ÖÏôªæü–BP7Ò­Ù©¤„0B6‘ [ŒQ†šïuÎEõÓÅT@—«VBu³]Ú\Ô32"D• Ih‹ŠÎîS¯xUñ8ëÕ_Ùã0ˆ6– Qr@/þ{¿!Õdƒ•™HÍLoU>X•¬Yzg£Õ)u* ËĪfb椯.ë©.äý•ùWõ'›•r&E|ŒD¸°‘Ã(†p¹jˆç¡$ŸKŒwÅ5I¦&IÛ¦µiÒ‘&¬S´uTb—˜§hÓSgÀ32·Y{\^;-±$(Ý¥KJ- ym\l¿-´Ç¥.”Ga>Š1<Šæ’|P(4Ûf$ÿñkÍ#ºà³ü– ¯"ã3fCޤ¿:Ôäû”é ;٣Ʉš×êyXÛÅ cæ^=¶¹t³€SΣYiim–|šÃ§¹„A ˜Ó])6,wÖÎÆT‰öÃz­“ó`Ùt¢Å<[e¾WWÛçº+3aý„O›‰šBHfWYeÉøt`ÖP#s~íbP9ÖíQ h\ŠC‡Ô,üÍoˆÜqÉB?>w¸tñ(–}š;Â_ìÇÖ[#ùâå£âôñM©ãÏ-ÿ™Wx›þx/¦Råqè2º™äÀ8$"åBXÈÃ!7)ýȱ{ؽfï½]ãèŠÞ¬÷^uû¯7ôÜwG.:ö]ß®óžsíw ,*Caœ&eh ¥ø{Cל>€ €–ŸÛòë}#à\«ïMC+¡ÄŸ%ý–Ö¦®ms0À¸Ôìû¶Ñs§Ö?âŠÜiŒÞÞûÒ±w¸ý PÓm«çFcpÝ5ÒøÓž}ßèû$×Ü¡× ÍŽb ë!Ôë¬ö}aeåÉ×3x,?ÑÈR*—e…2Qê~·j¨ù¬Qs¶¥j°M9ø+ù™6Í™ÖõnyíÉ6õ`;¹_SJqiŒ7Èä¯X0ƒ˜æ‹K%<Õë.và%rw¥¤C.;éÖžkcÛħÛdçv(Àé§ÀªÛµCÛåCmë½§t¨]úI³j¨=×J~æÖŸÙòÎ6ÜIJ†Oe$R •rá2a¼kÀyáA×hª/?ûÚÔd$ïËNün:q(™ˆ¬·F’“áT*œžñ¤'_ûç¹N„2$Ì%D0Š00™¨5’.†Í)_Õã`ÕLÀ¶féÝ]5ufê¯ö²¼2Ÿ‹ÊX‚)†!’íT 󽵋aÓLH‘õ—º¬_;±%Âú³z–ÃP")F¡Å¤C‹~Þ¢ý®Ó6à®´à œ V&àþd¢ï‡­ùˆ*ã¯ÈÄV×^Ó>ãZí?ÓkœŽ“ àš³Þêt´:q z<`þ ^kQbŧ @™‚19J˜¸ð!Zù5ëׯ…¦Q‘aLbšZÆÄö1¡m\d$³?PØïˬqQõ´ÀüÔðŒÌ-UÝCÖ1)2OŠŒÅúĺqa–±ÄeÖ)ýÀþ…Ðô !”¡ÿe¾Ü‚Ú¸Î8þØ‡Æ—Ø iµ÷]]VZÝ%t—’Ô\ M±=Nlƒiu'}«ãÄq·nÓ™:Ø@ˆ§îC’´“6mãØ­±!&Î¤ÆØ!0Qå5/™:gþ£9³Ú™svçÛï÷;ˆ¦ÔFD±b!† ¦‚Cfê“Úɰ}!,´[9Û\ʾ²¬Äõë1ÃbÜ2unU=¬7Ûº…”ûËæ²¶R¹‡!BD¡âbL½ÁÄŽ()v”ņ›Ë—SÖÉãîŨõ7 "öP)©'áv‚˜à”󦥤eö(»Ôiμlžˆ›–žlܺi#¹¸m#œe>bު̓¤öÕ„q3ÝùËTDJXbÏŒª-¦NÑ…7$‹ï W΢+gö>ù5=z{U$w)œD–ÏÓçŸr–X9[üà¬\CËH –Á˜ˆ ¤R)ƒ’†™ êu[Õ`ä–·`÷vmr :vÇ×zÛ{ìVUä‹`Ë׀šØÝÊøÍÊX#kÞ)B)‚¤pJHMâ0’iÿŒ| ùÛ¿/å|‡ï¢ÝÁ£ºÝ(I‹”8õ[[ý` ›Û¡è@%÷¯*îF ýnel¤29쫤Þ+mjÒÚXït…n…Êbw±ÿƒ ¸¡ÿ½ M!ªŠÿ±â¨B$B#¸„–ÌÎd€Œ¬¯¯=kïøî±ú-««…åËWûq!%çÑ@£h¯¦¤§QùAôr ¤·Öø{¥àÞгí”7ö××ÄÓ“%Æì"CO“çâÄ&EB…O\~ægåïRêQã‡/jß«Ñö5ªú4½ ªK5ºîzS߆–H{·Ýšt—ê€öèûëÔ}!u_µ¬x¥Qe¿éU/m! AñiJJ’4NîBUƒ$Úßt}ìÄâd*“‰ÌÌÅréÄãÙä¶ÛHúÄ|–›šìüÏ7Np,B ”äóPÑ Jbô˜;—*™‰²Iûú1;n&ªÚªî·–,‹;Ç£úWü&œOk‘bŒu™¢WJ¥= ö•ˆm¾ÍMè×8ïZØ•ébg“v`&Ù›EDÐÂG)±Yˆ  pB)! KÄ–@‰*lóäŽ{–b†¹°n6n›Yó1[.¶eô™KØÖâÎåˆ5Ñ?M³€,?QÛ•˜ £qÌÇyÊSÁ„!í0öšD=(õÞWÆÕã2ûc©u’uŒ+\#2ç#Mù#¥{œu?VxÀd”uÉËfÞg®?d¥ž ‘sTâ˜P–gÔÓLù„È=.)OS¥£r÷¨¶|R^þ˜rÿqEd ß)¤ ZH+Q…#"BGJÈë­¥ù¸è ùb½q/´;òQãJJ»Uõ°¡ ac:jx’(ÍG—ªUé.9üœœäi !\´ÓÄà§¼šGœc!¥Í'¬éN}wµ‰¡á"‘@ÂÛ+%•¸èô~×§mŸ¾è¸Ÿ¬Ê'|O¢¦lLn^>bå,¹„d˜ðÆr|ܱeõÜáÚx„¨c1j¾¶ß®ðX1ÍÃp¾€8é£Öß‚žžÂ—ÎñsgyKo£óç¶ÝFVßgÞÜ[x«¨ð6–ýñ§’ N¤Aø2BŒña¢ÀçNá’6­÷/ÍwªÛ¾®J~UÁÝö‡oVqÿ…ï¹áJîsËH(þçàÑ}ñqOêw‹f/,  „k¸GÒ”´ bWñkúÐ}‰•ñïKù›uí7«Ãµ” ÂqFZÏ—¾ðоðíªÈ€·mЬIÔ$ÿQÍ]ó½ô®­^'–k R†‚»¡j©æãÚèW5ÇÿYÞv Å"›6²9×CñŸ3zZ²!¤ºzõjá)Àþú³öŽïkß6d©°\ê÷Èi™ŒO H×`{kÕýõ²ú+uÚËõ÷€ûúž†í¦¼¬/h¸ÐÄÈYŒ‡ëZ×j)3½QRm—ï÷GΕðZʵ¨´Ta¼è‰€.¥(zswüzaêF0ÙïŽ|iy5¥ÎÓR1*Â0LŽRÃB½jõí»¾;>8ü 4»äoøBú‚[q5¿ˆŸt”´ã0,ƒÐ`8¼¹Õñ=owüÿ×úÆ–FF†ˆP a”@œ™ ™þX­è(ö0·WëÎT*;ʹ® uÀÉŽwyåç%òÅ¡Ed¦R“åÔ^:H+2XOjOWH¿|622»Ÿ•?RyNg8ê»+5`ùépÀ’ÎSÓS4¢=]–s¦JßV¤ëŸ—1m%ªöÂÜž í{…t•  „D&%ÁITNA´Ä,Ó¿íN;˜¼9Æ”ºê—7¥ôNrž1Öu—qwØ1Ëâó‰üíÚkõ¦õ¤óáëÆÕ”yô ÓDRû0nOǬ› ûH±Úl[¯Ó>Hy7x÷Rƒ½³‚C%(EbÄIX”Ä$T†A"‘ˆdRˆË¤åB䥺ìŒ;IÏl£a&aX‰ÚWš\Ó ÆYÞ žG€ù˜€·+ÿqS:’ûàL ÛhÜS«%Y‘ P¡TjF…¿¥—~Ï®}¤¼ÿhõÁNkdñ¤>ý>ùV%k—âñƒ,˜ÔS€YÉŒï9 ú‹õ…\(øñå@í‚æÞ¢äe_ÃÕP¢·(u)?Ò_ØøÂØ¯9‡ ¤@ Â$*ÿ‰Ö%Ý%·ý°9<䫌ùÊ}(Lé2qt— ©ÕÙ¯„ãOÛåoìN xø‹…‰/‡Îú€ë’ÿ E®çƒ Ç-EZ r– %  äæOÐúÝ„ü-•÷ß¡è…Ý ç ëwZ# ®ù-)ùÞÿD#׃üW¡z+FJ¥„ &a»58¸ù‚bä±’<<öæ‚Bh ¦@Qy•FÕY¡é®Ò·–›NíÑŸÙ«î©f?/cÛ‹ŸFt]U–SRhD°É;2%V«5Uôq+%˜]²ìPŽ¢«TÞ]¤n+Ö´—¨ÛJ²»ÊUmeÚ¶rKç^ý'E;žgk¡±«RÛQ­h«VvíWwVgŸ)Ë ´ïÏ鮩*ºJtg+•'ü¸_NÃ9LÑ$I¢!³>bßáOo·ì¸F–£_ŸÛï¢B Ai:RÅhsx6Îl$œË¼u%꜊:×£9+ ]:V°]Õo!©Hz”˜3d¤L/ߨ3Þ?èX‹X5h› ž¯Ä=鄌lGŒ ±Ð|R±^ï™MØgšÙÕ¤ñ^£ïÚ¡Š9'|ú–"Õé*Õ8ï™–SÖµxö*¯[M:㮥ëo]MXfâæÙ¦m«ÞwëdvŸtæ0žÚå`S}P!]Ìôc¹~"Õ‡N @¹_@ùýÒ©×d󯣙~eª/ä÷ÁiððˆúâžÒͦbµŒQÈH%,Wà‚@j)Äj-çš·J[ “k+Ø¡–®!oèvûg_GWMË0Ç52\S>M•ǤÅE4MIõ_Z×;Â0çÛØ¹n)Z¤ÅÉ€±ù7wËX(77´"´p½™½áì*Ô÷J{h¨…ý«›ù~¾aÓÞº“B_*%i˜¦p'K9E„ZŠ4àÊM•ö÷ê;?^É]ÿu®y…½Á«­]Ÿ¸ÙÅÖHÁj \_Î~ÐÒÍÈd4‚½M湯bdff\2ÆGãát²7ëI߯G…ñdo!Ä¢lRbc\RÜ™šØ32âO&…Äø®½‡Ž’Ȝđ ”8ÛYy‡·Í ‹®‘I¾~°™– ÅZJÉȘ¶U¶»"Å;&·9ÄuŒµˆœ#Å7¦BöTМá­YÖ‘ínûÌßþᆦ6Õ™5UYW–µ=®ñ¤"`+¶æºMàðcl›-!X³Ak’/5Œ„l©žÔÞôW­­GdˆL‹ÉÁçAe„Á„ ©Ë.1ŽÏ5MO<ŽŸòV5ÞÕ9>Ó×ÝSYD…#ªv]ѸÞÖ8šiºŒ€±âq$&y¶VýÌžfj8hŽw.ŸïrÍq¥Ñ øs>àH³u¼qR°L uyÁ‘åì £ì‚T¿î¼Êm™ EŒT%ÃU§Öiø ªÐJ5­F—õšâœ'å7fys¾×ºÜêu^|¡l8Üøþ¦FMè :P§;êÖêáoÓ%ˆfÙVMý#â™ ×ÏtÙFÃŽÇ5ÿÓl-gޝ'‚”` ù¡]…cŦ6R2´ä‚@ÎZ:Õ‡¦ Ù~jºŸL½V’?gd¹~tº(¤‘©ŸS³ýÒ™ƒKrû$“¯3Ù>}æ9,M\27@ç~‚ÍBFõz–iI‰¾x R*œ+ ¬/¯¾ú˜}ýOð’—+”ª@—Ý]7ZÙkí@&Z^Ú ')Fܸî/{¡û•sC\U²l…‡k:.¶°÷]=7Ú{7ì@\r)§ç<[.wpC®î›.ö¶‡¿Þroµ …úÞlY¸Þèவ~ïÚd†H CÅ ˆ#†õÑ¡4¼bi?ïñÿ½cÛ­‘ ö¦'üySäjKèF›ð©+t¹¥ ²»nºC·=‡ËýnU9*“QГ乳çAô?²Çììì—ø?käË›‡ü[$óÇC(¤ÁI5Žhý¶SêÓžÅNíŠ7ž¯>µ±ü׫'ÖTÿv ýV»æ„Ï|d=õf‡éwKúP¡¶¨ô9ƒ18.— eRœU‹ ܪ«ü©¯îÌæªAŸñ¸÷‰óイâäjPX@R=ø<¸–ÿfƒ~¿W³¡’ÒBTB „’Ò E˜Âh'©ÅøêG/ŽE_ÎGFâ/ÅE~<.ÄGøñ{B*Ú›ŒïŠÅvEc; i$‘Ø’wÄ¢‘‰äîûÑñd·˜ì9÷‡P™& ©’¡P z°©ìÀ¢P› Õ,¶F¦C5‡ÔÀ“j„$!}£Nñ€3güY¿a2P=É™2a[š·-P$`ʱƑ®º­V”d¾IÊ%´ê´«òþÖá-mH¬14‹!sº§!®OEêİUܶ0€TØ<²Æνí‚x)Ai´Â0°á”̧`Þ•Û£Êæ/tŽ Mãã§¼DÚW9ïëêFF³H×'W‚qªuÈ N9+q„…Œ¤Q”40è{ßµ¤º¬IÖ2®ýùuÛÆu´?ý Pk%9ûÂÅU)®’Imd´»–¼¤*'¦È™!)ÉVR)ŠhÝÔÚëM“ µ"Ùµk-º8@4E‹Äµ¼[¶×2"Û’(ŠâªÕê“øÃ? ØÑGƒ!0œ÷æÎ½ç%Ú8ëJ±U)¶$Å™b~#B"ìXàÊÀE:ôÌú‰Ëf»Œ \éßÛ­åCˆ&JñKÔ“¯Wü¤9{ÜoM2Ö¹9ÅiÒaã cÙ£| ÍÃù¸NÎ'H!ÎiT˜r$¥IìC¯(Éš# AÇóÊ@ñÍÙÚÀb`±› ‰w9§C¶]4V”Q\k$V~.\ì&{‰ä(}\íCÒÃÐò0?Ý'XìgÓÈJþo±z<,Y"ýy‰ÞâlmI Æúá{á2Œâ8Ac”Á‘„ðÐØàåþÝü¢ºc²œÉÖUoV³_ÖønxØ‹À$îR%û†Ä„ Áƒ0L3Q¾Rî»â úd&‰Ä0Ä.Q|âa† LH Š¡$!Aˆ«Ê?ma¯7tN¸wª8À’ µ Þ¬ãnÜS¸äao×ÿÓ®%e«P‡a):¨q Z›G­{Î:÷Ÿ*ß÷~YSÐPñ–Æ}Ä\×­« ÈíUU‹Tógûvid¼²c¢:ø…Û÷SG#ޤ…`X˜ ?qÈ– ¶Î_›FoO±d#éeN^ŸâÑd¡òh“î·»egš^tË6Œ´éN´Fvë>n$O¸Uhµ¼»7·‚Ä{ìúÛtg÷¶˜z½²–åçj°<43Òůك­Úß·S¿k¢G½šSÛn§B{ò»à¬Û.ž€D7ºKyª^yÂ#mМ}Eù3]£ Å8*€Õ¨²€Ã(JêRÖþªñƒÛû©`t–‰ÍTžöD#oÎ>ìžžéŽ$²j$a"³]ñè‘™GÝóÑÎéÈÁk×{êÜ ”/¥HšÂ°V¹8tÇü¥ëê÷ܪ\¶ˆ3ÚÓ-e$8D˜Bóo0/†õ i†3§9C’Ó'Ø™&YÇZÐQ«ÊG¨BD€`T1çP­¿Z¶vð™÷ªÙbÙo^<äœ —Ͱ¥™@Ù:kIK#!]ŠÕ/p®¿µ»¼jEò´RÉpHN‘°ÇG°’$Y‘ìœ*rÎ*ÿ—n{;þ†Ç´x笸""uÌ(ìSJÛ¤ÒzOᘔ9çdÎ8]qY\Þ#R+ƒ1*—ˆ„Pò¹å·|¶(뎇œ©®Ò‡¡²%Ƹ²$ÙÒΜÛH@&–gÍ«%¿zºÓšô;Ö¶5¶úÓÝ.‘GÂ9ïÕKgƒžMŠãasÊW¶Ê9çC¶L¸$ÂT¦‚Ö[“[OåÂKB˜çó)1_ Ãs{½%÷BvðLwš×ü†ç•ÿ[ÐpJ„, ° Ø ˆD§éÊ.uB h)M 8úQ­zù¸dõ”>ÆOÿ’N ˆ—ðåA^ª/?5 ̦‘ÕãpºO’&ù ½9™^d­Zøvz@þYÜX’ ‘R’’“( Sy"‡ßÔ¹>wû.y¸/=k5 Ý³×½Ùkeࢗ½éå.T¾qÙËÝñtöêQ"aPH\ªï¯fîÕ>gÙ'Á1QÙžT(Ì%¡|–H$Èæ!Á©#”ñïÁ«u¡-\­f®Õ‡/ÖqÙÆ½Uø¯eîT3W]GMRc¸B„XLB Ga>Æ/”b°Š"D"@Ýa$…< ’ø÷t–íÒ˜ümOè†'ôWO‡ F„!Hq‘j~~~K#[*øÚòHÖÖÖžü,ùãés<D“ h*•º±võ‰Å™Þµõ£Íš‘FíÉfÝÙfÑI¯þÔ>×[qB #Šv«ù£W6ok,k5½ßªékRÿz¯ú½ÝÀ0êÑ&åXƒr¬Îtz·éãæmçÇÿ‡j¤ ‰~l$[1Ž4«O·HG½E'µgÚ´íÓ®¥Jp¼GD&§(\(‚Aæ"EͲ¶sûÿ|70=2{kz:ð0⛇¢‘Ðü$—M#ÑèÛ¦:âó?xø»÷?xÔu(\Žæ´¼Z-A\h7-t¹’!}< Ï„Ü/Z#‘péå€KQ˜³9Ô‡·-ôƒC–T§}!h™ ˜bŽx÷ι }>èˆqö5…]Z G!•ƒƒmŒQfºž[5žãÌ1Öœá,ö%Æ]»Ä™WÃÖùpÅ;µE Á`¹D –æ* Ʊ£¨ò_²Š)eå}™uZn–X•ÛÞŽ¿á1Qä¼+·OÉl¶)•}Re»_dû @±Ø|·È9—EÞÏä®’†…E„T†Q ŒD6©ø\›$Û£ãr6í7%ÖÍt;HæS&ìŒ3Ϭ‘EÖí\~պΓŒvîûüËé¦ât—=æ3¦9; H´KŸ—,LqÖ•ñ9¢òÅž’ɰ¾ÍH‹Q!ÆË¡)Ô=1oÇH³ùAH÷8hLtX×ýÖé úyå?XãÂÆ'`ÚÐIØZÀª#~Ór·i¨J/ ”ä©!%èó!j}YêýNæXþJ¯tñÑb??9Ÿ²i$1¸#Ñ—¿Ô­ö WÑÌ»ÐÌ1ñêûÎoC¦Øx>Œ€ö­Gá]¨ö|ÕÏë˜ñ—¹›•ÌD wµž»è \©ôem¬5Ü—C×<ÌxMǸÇÇþ“û53JC$*¢ðSõîº'ôÏZƦTQ,%…;p>΀Ð8ŽòÁYéo¬{ÿáé¸ÚØyÅí¿ù?òë=¦äŽø?ý£R¥KIbc¯wwv×ÏõÛø ¶›‡m0`¦!„ô’¨\ÀµÁK“ôN×VU{¹»ô.IS©­›Ë5ŠzÿT•z­t}%$W¯IH Æ€Hà.ÎRÕ¦¢R¤þ¸ÕOÖìÊÒ̬væûWøzyä"ä;M²^¿Ã¥ÁeÑ‹eÁ‘Êðhið·;¢:Šú:ÅBðù8`ºCuP…€°íG „r„â@‰DB¾€ñ¤(¶Yr®•F]ÌpYÔ/7áhá…ƒƒƒÐмddz¦ñÝ{…4MbX6¶E´*úë¥Ý>y¼¶Ï«ýÐ/éòHû*TÕÈ^)i4[É&HáÕiŒga¦‹ÏUSç«•½^e·WÛã3õú g+µ]•Šž*É€ßïÛt{<[}~8lùYo$ð Ôd‰ªÛoè©Ëéõ©}Ú.¯å—Õù=²žÜ&#_‹ ²Y‚I1¾³ùBŒ–™bÚ#îúôޡɹÓ3-É©æ…xlqâÐz™N|*ÎÌLµ%EÓé×/|´GˆfI ¶ó8Û~V®Y^‹~ý\«.¶/¬­‘éù“QÛ†ò0‚äPÐr²Nù¤‰€*ƒûáÚÞ84&ƒú¥Vc*¬¾P¥'Èìm¸H‚Š8ëæ>×t{ÎdÛ ÓH:fŸ ›fú¥áI w1ìˆwTü¾AW.Eôœo€›-!- ñjýXi‰ËK⢂iYÁ¥í6mº+·MÉ]q¾éqü¯ûH‘‚‡ÒüqYþ=ÚzOby ¶Æ%ùw„è“»Rë-9)vÄîŸJt2ÀÚŽ6%À0 pp ?þG#À‚·ªžØÐöú¡Fà|szªM§½¦ÓUÚ¿ì\­ §¾ÙÉ*¹_§†óæ¢l(%æ…¢Dñ¶þ¸ÿöøéÉ#³ñãóëidìad6yx6K&ZÇþñO‘˜ââÐ"dk£À#a¢ÅöyL1µ¶)9ÃFk$ÙjI…Mï´¨1JráÂÄØˆ]ĨUŽ2EsöÕ¨q5”wìñ¶ÂO÷êUÂW²ø$‰©ER¯e·:–:,Ë/NM‹MÆÔÛôë¹ñˆa1æ¼®>YcÓq¿w-€²l `Ae½%–$îi‘cLd¾«´>”ZS¢ü¤¼èŽ4ÿ®8ZîÞô8þŠ×4?/!)x$sLʓҢG4,û]¸ ΟØà“)¹}œÎýgNþg9ξ½^¤RóØ$Î¥y¸ðY$¿˜Fÿ²Ët?R˜<è„ I‡rW¢–4cNµæÍDrŸ;åc…©pAâ@^",KGôóGz¿i®M9Ò.v¤BÖU¦p.h†yòfÉ|P7V|Öê.¡I f¦®tœ‹PjœàÃuϹdÖ¥FëB»}¾É”x+ôÂꃷ–žZe÷.8/e·Wú7ߥ&ŒF>¶E†È‹d“(QI{Þ/=u=x;[šlZO#‰¹àää¡™©¶d"ú£ÃE4B\@PÛ””ôj0o)y0͇e+1Ëìk–¹vÝFk$4~Ê›;w›ÿÅ~µqßqÉC§;Ø€$´§v%´:è@Hè$YXF;v|`Œ¤]i>êv:™6“Në\Çu“¸3I]Œ±™ÚÓ‡´qÆã´MÓ´Û€/’ØÆ'˜CHÈ€þ©gÚ'˜x¦ÍÎovöA³»ÚùÿþßÏâ¢`s „„ l¼D¶K«øƒ'/º[û,lê©7¿íИ>qÀHfˆdXú§; ‰Pþ|£&²,×û€7*ˆUñ}Ö>ÚF+8Rî*Ž”ðAdób3$»$uŽ+œ‚AÊxGY4(³ÊŠC(3È;zĦÇÿçõ@nÈ1Ý•Yf[Ç„¶˜È1,¶ß[(ã£û©ã>U4$1‹õ£¤eB\§l¿A•Ň 2ŽfŠ˜Dr:ŠÖ$÷:&ýú)º ÉhãlA¤yÉéŸòÉSlIt§uü€}VÏíã̺§¾â§A[”Ö±…QÖ<ΔLÐÅãm*œÓ]—S,ÇB.ÎH‡WS”5OØj"ˆ'HBªåh {òŠYF¿\ë?Ô€3ÐÈ$kJ†Œã]‚6L°¦”_=ß ‹†KZ½zDˆH\ÆÃ5é«.ü$?~lMêÐËÉwÑè{èÄQôÙAéb™nY“x/ëâØgÈRg D1‰ AkêƒÊäYΗm¿\ÑpÕå¿ájºîZàÈÊ'}ÅÅtW†º*‚½¥ÌmGh±T?¸ç`/»|×Ê蛥¾® Á+öÆ{ÎðÖ<[–§pr ÌÕ`B)Ÿ‘@ÈIáyÇ®n×ÂÁã®–1Ÿ»û]Ì{ÅµàŸžuþðnö²Ó³œ]4ÐË›zžò`w™ÿª³ñR9Ýåaï:BWÊ«nVÐ7œ}ö]·*B×Ý¡¿Ûv8I‰„Çâ8£%ÙŠÛú+öÞ²Ó/J#à‹]wÑ}ÏMUÊVªtR‚ÄyŸÏ?wîÜ0Ž™™™oŸ" ÇìÜܳÙù¹ùú;.€…!C(™»PsÜ›sÖ•×¶Ay²œUí^MçFõ™Zò –ú\ù©ji»Wy¶N~z ÕV£èؤìx5¿cÉ÷Y6½tÖŠäý¶BÊ«?Q#ß_Y0ZEÂÂÇ(H"É$0 £^“×}PõqÿÛC;†"ì“èÇ÷LJ±¡æèЛƒÃááøñ‘Ÿ~~¡N„òÓ„ ÉÌÂ…—f tñæ’xÀdŒ)ÌG†XH·ÒÚoŠûr烅×ì[”ÂÌ JJIÅqŽeá(vdP(‚a‚‚¹ 2!D sޝW&ÂöÙ°vœÖGç’Õ,IÑÚ© Œ½ÃlÑØ^Ó[8(ùAAÄ/ŸcKþè-4’P:L H¹ˆËOÇÒ-÷ *¹EY'äöÇ ö0ÉK^xì~WËR#ë¨ÄþIa#‹¡Wˆ—Šˆ”#B7k±; ÎùsÕ= «ã¬a2dû÷2L2F ”ŸduÑfÝ㦂¥®Ãh8?rDXë¤O5éÓ.¬É&Ë'»4¹ÈË!Â/äðj¯T|×çiÊþUµç¾de^Ülކ¬£![Œ±M²Ú•îÓDSA2`m2Ì‹¶@€žCâYöÜôÄÅì/ÒâGàùw°g-ðØû¼™V*ÕB¤Zág­œ¹Ö̧‡áéÃèü¡ôoZL?ôð²‰ï¥^Q$#¸BŠ4ï#“÷’;x£‚YÀ²¦í'öz…¸ØÃ (.´[\ð'玛¥ 0F7 Gy€çZEsŸ3Ô¿¾éëRú«²`WÙî«®Æ>§¯Ïìr4Þv.®‘Eª¿8p³2ÜåòuWøz»:¿7o3ŠrDÐH6Ÿ_%S׸]ÊôV2]¿óκ¦‹ÎÆþò¦û¶Ð•ôgnÿµÊà?=+®À?P_9ü_Vѽ¶ÆNÃk|„/‚ ãõ­ÀÏD2ý_|K™ššZ¸š[¨ÁGE¤( JLwÌ£8ãѶoÌ=Y«ìذâ)Üæ¦ÎzÉNô”à'çLµòŒW{¢Z}zSîÕ­ùH’ÁBˆðHò¹ÒQÎ$ÏL²Ôçj:_U¶¹µ¿óÛªMmÕ…må‰òÜ6× ÓÈÉ ù^íi¯´½’j¯Òœz½ððÆ<¿Mœƒ!0‡"™$ÁG!’–­çæ‡ ¶~¶ýËûoFÑOâ“ÍOÂc‘}‰Q&:¼gt¤yè»Ù©äBi"B#éu 1 HtŸ-ÞdMÍ©  DQŒË6s-Vq?ØßL@É}Å«76¨øb(=C@‚LÀø8À¹Bd˜@‚. 2TóI+¼ö¸K2ö£õcÁÂÁzej¯m„^²šR´&ÎXbÍŽØCÜ—7Ý ŸaL£aU"¤æ+ûY±&¾Ïˆ(#2¸ ¯‡„')ËuåbÝ‘á aÝ“}§‘ÿ‘º+5Ý“ÊJ¿;’jMÇÁ¬cd±&½„ä\¨3Ï0æ©}Å1°xüꭇ̠¬56Çim„V'÷,½öèb>s,l™j2ÓÆÉfë7»­›¨WD‰â)á`t«³†¶Û¦ØÒT@õÀo>V&묵Ęâ)Fæ…(k +VºO£Œ2Þ\” X@ƒDº/v­S!«B’% DøèFhæ×Ää!äiKöü/Óâ-päæ(9š=ŒEŽ É÷åyÒˆ^ÊCÖRY„Œ/—q ,s­U(~ËPuÞãûGU¨·,Øc÷õ:}å ×€%Ë•¶×íZnÌá! îS}ºÞÙÍþÙ¸T·\(©ÿ¹¾â_ì×ëO[çðÿ`KJðíÜ/ÇÆW0¾`|Ńíp1Ä!—µY|lŸc.IªUÕÔh_ÖeiÖ¨jEmÀ(íÒôä­›"¥ÝÚÜ"$kX#r+I¹Ù‚¹îE‘¦}¥ É—Z^ù‹õ¼>çyŸç÷–É•8!„|»LÑZÿ\~@bÈûÚÓ Ä2êgBÞáPçuOëÕ J†Â¿ÄJÈa$Ç~ñ^™rµÙ½˜°ÌÄô€ Ù„ xøIÔ2Í–¦AQ1ƧÃfë0“0-FJf¢¦ WšN¸¦ØÒ¿í+%ùB\ ÎkäŸñ¨žD½¹NítÌ´Òf[j? ¬Ç-‹m²LÌæJ&Û ·úœÎ²Å“ À0g:Vº7.ÇÝoW©„È+ˆˆÆH™™ n¼)œ·pî=lí­¼ÜûŠ©·/ü‘—ûƒ|ýñúŸà/b¨×È#äùrH‰AjÒ!ˆLIáÇ ÖKžƒÃþÄp½Y­ˆn˜û@#€"¾ç¦‘ÿT°q¾ö–Ùßl¹ZÁÞñrÿv1`Ö–t(E0ŽàJÀ4è HŠ£*†‹D¯+]ßø¢×ƒì]o|ÔË|UÙô”wµŽV·_]¯f[ý:ÇqT c 蔩nÈ¿åM\²~³¸ª˜’ÊxR‚ÃBÞëž¡*îj;änúâWü[®‘«~𨙑JæÛòæ±`ûÕת± 0D"¦H¾øüB.—$X\ZY}1‰Vÿ/ÕÚF4ýú Ø’Á)„§:ê1ô7j»«åý! ]r˧³½»VÓ[«í©·ž¨ƒ¤´\J:Å2§ì•€ñ`Ò*%j•C$Ž!”„  ø0zÊù $úÞz}ÿ®Â0XÊôO6êöÆldOÕ©’õªþ½šÁW_–F R … zj‹RuÚÁzEªFy®ÚØÆëõçv•¾QI»¤"|Š`X©jA#„Y½µìÆÓÿjº?Ñ>?Ý97Ñ9;¸{3Ê(pþ(\±ƒÇ?a+αº4zŽ Pd!fZ²1 èrSqóVw¹,§Ê°æ9®l‘sf 8ÃãNßða“Uí’@R!Ÿ@ †¢üýFéÛ»œ¹Òɸc†ueŽxÀ­p¦E;ÕÏr›îÆiƼ|Ä–³ÓR§9s´hœµýsÛ!Ð0Òˆ4:]Š g Œc:÷´Ò7.sÜ—”NÑö'jç˜Êö=m›¡Ü/}ŒþÏ%~ C´ý]ú@ážTV~E;~G)äµV@JÁp™m²Â#žù×cœkUW”IX¦¸’Ù„Pv¡­h³uŒ±-É€f7T3Åè¿ÜoCqZ†æo“"8Âo+_ªæÙ¢É¸~ºË™m×ÌFm9Æ›‹š3q}&nKG]ξÕçtŽsÍ2†ÙvËSp}ˆ™æk&ÚÝ69‚á@-fâñi2{‚X=ÉÏžÄ×ßgN‰2§¡‘7$‡œÜ¡¦,O †±ΓìVÏ»ÃÃÀÖ;•#ÞÈÍrf¤" Lr£*6T¹áÛ~îyMÛËè­*öKoÓ÷¡ccžøoHtÉ×âWÉ„0OćH‰(!(b¸Ú‰q0Pv`0§¯õp·}ìHeìÛ@ÛfóÞ ¶_ ²×\-hý: ËÃø !¢‡ÄÝæÝñ÷]{Ô¥•a$‰ârB’‡ Á[o€”ßÔu\ö2c>nؽ鼛+‰ ˜keÍ£•ña_ìŒu7A``WbŒxuÿ¯V—Wž¡ ·¼üÂ4òì³²²²Á’µõ?¡H1 #rG4|ã™]©PQo=P¯ë ¦B[=…©jI_¨$Õ¤=ä‚ >`rH,ऀRñqJ ÂaXMÐb”ÀN!Õt×úà H4½!]_XU=›VSÁ@üSÍÇ5¦ÞzSßn]²A™ Óý{^–F”½õ…ý†Þ¡»Æž|_>YSœ é>mPöÕê>k4%÷iºÊ03‰ " ‡©X.Þ.$¤0ÞV¬ëŸùí½;š÷Äù‚Ž8£%K\ñÓvK–unZ#]®Å˜a1ºáŸiÆ0u|Òè°R±AþË~Æ6‘žqÿZU]-°s¶Çã‰øŒï8q|&qÈ tV°4±=_ ÛU+QmÛU¥Ò=TT퇢.‹ew¡jÅ—JÝvYuK€$h6„……$„8ÎE $ôM#õ»Q_­‘åÇã™÷ùÿ^ŒO$W!ØW¬gLY~[^:ÄÙÇçëü^ãúNíºÃ8Æî;\Åsѵ!u[éc]÷T® ÎuSeÿŽsŸLÑžÚê‚IlãØV –ÓDµJô¯·¼’îe¡ô¯™O¨Á™Ëºs)çS<ÿ÷“ÖG­æ¥´a!k½Õ/§´C­n3‰¨p©„Dé7»\Kq àúbÊ13޽SšKºgâeS‚5ŸHpçcŽ…ÄÓ´.¨FsiK®M®z6nYl³- eg_×)àª$„Rr²ø/­Ð“àÙ#/?þ@rÿ·ÈØ{Ô{»HŽE(§a crÑ<4þ{[-È÷¡€0è‹^õóÿð·\«J „… aT_8q%,€p¼ì‹oTÚ^ˆð7‚ÂÅP´/´Æž[Õmÿô·e*©T ~• Áu0¡‘bŒ,cÕ&Œ¢œ#R‡4Å–÷úø+Õ©á@¬àÖ¾ø5¿pÐìÃ)!‘âÎ’ÔaÏîŸé|.… ä‹[qH$'():jP²Œf©õVÆGÂ탕ü·ÁÔHUv³5Ò€Öz«b×€%ñ~_ìë o%å QÈä3Ó9 `@‘Ç««ÏR#ËËËk/«O¾øìs‰HLâ„BŒ";ã©f®#bèÞ¥îiÔuñOQ\O×Ù\öÇ}[¬¨âvUŠB.Q"” lY”BAR©ä1'böZB ÝM% €%À!%=MëUh_yg@ÕUm:Ù¤?^¯>Z[r¢QßÕ¨é®{^Ñt5©;êÀui»êÀ-àzvŸª—w׺êU]¶³œ7öìÖ}ÜÈì· ÅEJÈ\FbrSìbjH›1ÿøÌžï’¢E \"ÇH!Î4˜g²úù„åAʆÌ_ <°6ÒŽÙäÚq³§ÜRܳ”qç3ŽIÞ2µ/$Ü`êæÓ°ÓÌÇ-9Þ²q‡,¥J—â†å˜a–·N¤K§Ò–UÁú„7çxÓDÂ9÷Úw4c˜i_£×¾t"î}ßgÔ£¢­ÒW¤¢$åÛ0I‹\yƒsim£j×<îW{&X÷„Ì1FÛFåvU£*Ï÷Åžç£/jCêëV:FXû4㜥íwå¶Û,‰kTç<khŽ’Éq1$“ˆ4q1!ùÛëx›ù =SÍúé¬c2aË­¯B*—v-Ål‹)#¨Ù„y5¥›KØ~Rƒl‚š¤Ë4Xo,r7]:Ûæy Ø'%v°:¦†yÁ0Ÿ4çã¢`ÜìuºÒâ›j·Í ܃¬ù^ܼqó¦GiW»OE“$RÃfà‰_mY="}_qL *¸””@qb;)©Z´]…)ÞµúΣõ?ï­:x)Ð~9˜é &†CÂEì|8~>"\¨úC‰Áê’/ºQi{=œ¨h¨I\öG‡*â~þw¥´ ŒÄ$0!›”Æ£¾½ßT%‡ªÛ/ûø?˜ëU¡”1£òˆ¹xéš¿µÐ¾Ã~áݪ&z[‘JŒPA‹`?g’!(ŠÂàþ4ƒ˜A˜Ø­µŸt¾~¶*z¡6 s©2Ö[›<lí ò›­‘þpÅÏÿ;Ð2äûIªÓûåFwÁaôϧÏ,?|´úl²îŸu¬>^9°ÿ-@$šUòr§j´õ‰&cG£æX5×U¿Ù)¬ï®Õw4˜G¤Aš©`érFáã˜2Z£¦8ûÌê×,Ú7ÜÞRY«Ñ|´ùÿoÖ¿„8¨BûšOïaWgœ² bØVݯöO^}^ůUwÖë?Ý£ín,înМlPuïÔ}²Sûi³á³fó‰%à§šu]ͦª õº—d/#X‰RF’Œ"e…¦ÄHŠ 1„a:Dœ0pÚ@ O'óéµ7yÁ’OÙæ³N@‘ûQˆþÍžr“•¹¨i*©ŸÏZÀ˜åsiçÝ”é~zmë·˜:Òç£Ú™¸ü°|›ë^²r6åZ Ë|ÉRÊœOÚ§ÀÆ0S^pë¬õf‹nñíÐh,tÈÊÈ0h+†²&ƒvÀdÑŒeº¸ú–Òq›6ÏÉËÆ”ÞIÂv[áWyòLENî¹¥tÝPÚÇçsѵ!u“+¿L¢*›T:ïÉíàüyKS~UkŸS8¯3¾WE25±Ð6S°ÖOÁFLÃÙòÅvûœ`É's…kd&íXäÝÀ3³|I>í;‚•˜y¤ÝÛ`¦Ô[ÀÞ ¡Ñ-íe[Æ´“‚e&ã~À¯9|! Ö©ùaÔ8Ÿ0MgÌ Óf¯ÓE`­¸RK>mšnµL¶¹ÅLC|…-’a3‰ª'¾Ê¨ö¹·;X+‚$?"1RIQ2éöýÅÖ¯C±ë5ïœ $ÎWð×½™+ÌÅHf :ÕWÙr5œì¯ú#©°0P»Rg.פ6*m½ñ>ìÛHúš/6RÁª½Lн„‹}Û<øÉpÍÁë^á?žèˆ? â¸ÓóM“âíb•w˸¿×ì# Ÿ¿6ò9+Ba–RÈ!œÀpX,fˆ@.)eØ_˜ƒ_z[†Ã™þ²–‘úŸöúcƒUÉó¾ÖþÆ Ôˆ·`\Ä€?~1Ð:Œ÷…b}Uq`Â?YêP)L ˜Œ Þ|cï“ÿIdeeåY‚d½PPnjš"H‚HŠQÚØñ†¬Ûgêi`ÕÛ;ÿË~™Å´•qü½i+e/wõõа÷l¼³Ø–ÌL2Uðr7Se3£>TUÚŽÚªR“a1†d2}™Jm¥jÚQ£I!HH“É„[ ¸‡¡R«ª©”*UŠï_÷^{ô{Žïùþ¿OÓQŸoÞk VeBC1ÉÏC¶3G gލ†Þe¢ÙXeOÄÖÑô×*U5k‡Þ‘gõ½õ€Chš€*²Mÿ@š¡~OÏÉH‘ÇA8RQÆ H‰¸DäïDµçZʳͪ¾F]ßaSÏaÙóÙ˜ê|«álcå¯ë¥ƒ1â|CEƒn &j¨è«ÓŸò‹«U•ódbâA„@¹; “iùüûŒu-iÜNZgË ò› À"mÚ’´  Hž±ïu–[f´ ¿-±ÆʸÄX@a˜O™·(P…í$ØíÊÑÕ@kLÕ*í\¡Ì9Æö´Ã´AÛVºls´!G[ÖÓfäEÇÝî°ÒÖ‰º#Å<GˆÉ …¡ ýNîÌö9¡iV¼+‰Ü‘{¦Õ¦»rçCyõLYõ— ÷Wr÷¼Äµ u>Y÷ÝF_ë¥hVâ¹+u}©pÞRÚïÈm³2Ç‚Ô='v/‰\eUdÎÛånV$ƒ ‚‡H”%èAHf‹~áÇgÓÖ¯Ó–'¤e#í|7¼èw¸š6/uXÁ¾Ë±Æ9Ú3ŸrR–Öð Ýõ–MŒCž&÷*eXx·òYÚ‹;Ö×išIëÓö­¸;G9º\ù¤k¯÷é+ß"Ý‹]ž…”f›ÖåºËŒs™6m&@ÒÕ á"Aù\T.Sª±W!o@0!D•D± †«=Ç®D˜+æR09HÞ´O†N\ žöw9@ ¹ågÆ< “úf 5å%E^ ¥^–Û^а×}ô¸Ÿü,Òq3À|Qß-- £H _üÛ:êvýÉIWâZ€®M]¬OM“#µô”%*ú)¸ðûöðTMòEǽ GÔ)¥¯Œ‹„ !*ĸX„£ÁÇuUƒ¶·&=ôMu-D_ ÅGëÙÑu#ÄNUÅïøéaÿ‰ápüºoÏidÂOO™É ˆk4«£ÿHŽ…."PáC.<¨`— ^ŒäÁp϶ Ï Ù ¸@$Àp>Vz”°ýª¹<Û*ˆi†šµ} úÁ&y¦öe¹- ˆÿ(ýÙZÝO y˜šIZtjÀ'õ’lTÛÔdÂåÙ:u¶Aî˜u&Z™‰=/¾:Ó VÓÜì¶\ÙiÉÖé(2­ºl‹z ¬øä°ñ'­ ˆ@ ±‚‡óø5¬(‹1®¦Ý¨=׿9Ý\ÞÛbÊ4(²µšl›:Óèhÿ(å9ëÙÛlíi–o–% ¸áÂEB –—–¢˜„àãB¬´Y/¸ËÖm1îGÉŠMý“F@Ý÷¯Úëì÷²´™¶-$-_ÓŽuZ¿@ëVت<åX#•Ê=ÞáiÔ!%E uÊAq§€8A~Ob¿/uÌÈœËÜ»Úw£|­}Ô,@]Õ-µã‘Ä1-­ú™Píà—p…%•‡ ªäà“frÄ×q³®ëb(Õo=‚ó J à4…Gýéé*zÒG‡Éñ0ó7/=å'/FRŸ^‘
Aø>¼ìJ8 pÄ™ðS€šÀ ; /žKM“Aòr˜þ½§C&ÀŠ„°ÁÄ¥\­˜8­ñ8~¥Ž¸2UºáMLÉá`b8H*ø,”ø¡)ô¾Ê3ÚÐ=YÃŒ™ýZ·ö2»†ÁHˆàg† [Û›…­-¯ä·¹¹‘ßA’0Å0(ŠŠ@Íò÷¬¶ž6õ@‹¤? L\Ó[¯ÉDÙú½¦Ý…¨4iyжP„éù²_†lçZumå·(‡š€ÔC!•} êÞ:Ý@ôyñUýÑ]Ù0…Ýv}¶U h$Ó@«¢?¦9Ueš‘6-.`üÁâNžÆÄJÁ×ÿ8fø žˆ*9Ç–ÞÎeÅä=1íÐþãÇ¿©2Ó&ÏÆÔç›ôƒo?8\bb˜àq …!)Žãß=P+ã÷EM3´w1­Ï³Þõví6«^aTKŒeùÝš‡)k>aú§‘¹„y£ÛµÈ@^-ÐUHãLÚX ¬8j1‰¾ñ8 ±˜ƒóüƒ¤Ÿ«ªŠìÒp¢×(òZ3R÷ŠÐ¹$vL+÷UÞ»µ½R{¤¸´Ê¥(ÿBŒ¿c'âæ÷̳¤íq§m5a\'ûL\»B™¶ºÝk¤éE¿[@#€=æ:p^M[w™4îù–é4-¥*—ISŽqäÓ®'iû“4xÃt¶ Å%B‚r¡ï·w6Á±µ¾™E4²½½.Û…­Õ|EùßÙ¯×ߦÎ;àÿÀ´š8¶Ïýâûýn'¶cÇNœÄ—ÄvlçÆ: ŒÆ±Ïñ ­´©Ó$6í¦VšÐ¦m-àÄhQ·»h+… iH€²ŒÁh ‚CÈH!{¼H¼@ʤN ÖWGÏ9:>ÏóG¿Ï£  C<düiÈTìW”b2 „BÔi†CÊ_ýתçj‘•ÚÑ]v‚F(’GµÖá~õ¾°¾¸IUèWúÔùu>¦+vöhËEaU¬84”ÿ¸¢Ï÷I‹êီ3ÒŽéÞË¿6Jii¾ÏóÖÈ" _„щz£å%"jE6ŒDQŒéÕ•{UEÿºóã‰hнô¡°æ€_únL{x»ê;=ÀT4JærISÃ2)_Œ5›ê¹§6™ç·_sβ¦ÙAÃÌ7ì·Ó¶yÖq;çœO[Ÿi̽Ú|3®KYo§šn%LË9óíTãï7;,bƒk7¢0£bÅòËÏMi+pÈJÖ½>ÏÿB*B÷ ¡ã†Òõ™Ôö ^?#ò|¦é<*rúHœFk`’¬ƒi µ¿2±År·{&nZØé¼‘´Ì¤l 9÷­A ÉâWÄTý\ÖŽw3V c§³é5_/  È°Þ³ИI˜æS–yÖ8·C_É:oÅíŸ'MÒ¦™Íײ‹/5¾¢#Ìu0ÅC…‚S¢ H!„ýÚýõ nÊ—9áÙ>Ú:0Ù–¸Ðœ¼äbÖ«ªNµU1ÌŒµÄ§¼é|ŒOÔâŒÁ;U®ÉÎÐÅiïàxËÀ¹VælGf¬ d/¶ïþž¹K‹ q ¡PLa:íg&‚Ù _j¼5q¶­:Ð8Ó–\­ß‰|ÉéæÔ;®—ß÷$K¦[sS-Õ?~Üž¹ÐÌL´°ð þ؉IL Ì'qТ‰¨ùжà)ÿú¼±•óg(ˆ/Â)Á¥jõòÜ ‘åjžÆtsùáÒââÉ£Ç`*‚q’€p—D_êQcòRLUŒ 1s!¦*FÖ\#ú‘^Ë›ý"ƒa®8٤꓿Ó#*E´b†án0 S>¢ÍUùNÅpXZ ¯ZKÑj/åˆb(´r XbÜß§<œ0#ºBHZ ê~læQu¢3˜µ,g¡y„0$ÿ~D·/€!¨€ƒÈ„¨n¨_^K½Õq–|ëÎ'¢,DÕå°eȧ~Ë'Û×#h^Àkh.&ĵ Ã2.Î…PÇäPù2ãÄÇïÝ´ëk~˜¬¿‘4ÝÚe¿7 Yɳª‘”~~‡cf°”†;Yý]Vwt³ÛFñ7r…Jìåp”$öÆ›b÷5•­"p^“5­”¡Ç,yŽ“ÿçTh×ÇJÇ”Æ~]f¯lWEö«’¦9™÷´Øàµ—I€H8¨&|ZîôórÖý £¿¾«~mXfœà«û4®[ÌY¿èw 3Ÿ³¯P ä1NÖz½ÜM‚õÞ(r7k¯vÇš—2ÖûŒ©òŠíÁûlÎ0“Ò-&tŸnÓÿ¤U+ªE¤8ÂãðpRÆåSBR€sjÁî…‘½æÐ¤7}ÖŸð3WB¹)ÏÀX=X·ªz®==êíHµÅ/¶§O¶³aBÉ¡…_¦´ÇÌ”7uÞÇžkI^ô°SÍÉ“Í̃¿Qð0ìKO ðHDˆ£¿m|锟ïH¯çŒgðßô;éØú—ÎìoÜ?íbÎ7%.zR£>öJkö„'¾×ùªÜ¢C)”c(N‘4IHŒäâh KxÜ×õ-'üÉsÞuT\&¬0"D¡þî‹K÷–=%|¾ô°ŠŸGKßÚõRb‡¨:-ëVŒ‚Z¯,W‹¸~¨ PÖåå5׈|O€¶eõXD’‰õ½@D’‘¨êpLV J ~M¹C?Ò¥-w©KQM¹gµçëŠQð4C¹[3Ü¥ ëK1p Ú†ý}ªÃQ C¡K;”‚ºv k!'õq·uÿ&ŽWÀ•†ÿ2ª8ÖÉôb¾€”b’B¯t$l,ô¨„´ÅÀºóã‰è ÝÆ|ÐR ZKÝšÝͲÂù2.àmØ“ä³]¸J,ÁøŠ x$Ëy­Æk÷º•·›çrÆ9Vù(i¼—s¬PäÙÕÈâ€a.a¿n¸Ÿ6,¤­oG5&Drp)Àø¤pÃÆ}ÍyÛ%ÊqCî¾*׬€ä¹Fžä’ØqUéú«ÔzIb½®iº.o¼L[.‹­³’¶sB{a¨¸N"በÜ©‚/l7Uv9æ3Æù„€d&e»“¶ÿŠyìpm ‘ c^ëõ2ËX³Î cý.îtT/&- ËRÊR´Ì°õÿØiŽHÜ‚˜‘ ¶3 Š p±’¹´z Ì’$¨à.Zü^Û¶¿ùrçÛ’“ÞÁ=[“gýéu«ª^àf4ÀŽû“ÓžÔX;óMM3ØáÖ<')<Ò¶õï.äxg*ØöºÁ+¥I!Ž _äÍQ¨€¢ ¾¢ÓÐw¼-~&º˜ô¥@H¦VŸ×t+3êKüÙ?ÙU½ùýû§pæg ‘¨Êh%hðL>ðh ¼F’‡*ø$¾«áQ>Zû톎#ÎÍUud>舯×{;ïa÷:»9P-ص©xd:®BäéiXhä¾­ÁJá"!„×HjÌoFåå°¢V—»B4ù°n¸ZÊ•…®µÖˆ6d#pŒà’µ*ŸÔúƒ`ãÐ×èbXz(&=–½â’W=Ñ–cÊ·WÏc„€ `‰*ªš$ß+-5…0#ÝPH(fØÛÍ£êHIj)é«^>UÃ%9*¶Uup3ý];ÂGEͲCý‚¢Ï\ˆ™þÉ~½Å6up™´‡nZàŸûÕçØÇǗ؉cçâ[ßc'¹H¯¡ ¾; ·V+Õ´IÛÝ:*Z¶Œ8±C`<¬ª¦=míC¹BB -J!áÖ’¦t-;©BhTb*X•býeë\>ßùÿ¾l».*8?î‹e Y7Òd¥L;SÃcÅË”4Ça$Õn¶nMªwüTÜšb›íÅŒœ”czHÍKðÅ0eUb{[Ko¬·ßH—ßì.ÿÞñãþÄùxu>nø¬ÇôVPÒXÆr ‹¡EJbé€`¼@WžQU]Õ¹N³gµU ™ZÔÈbîæ¬h»&8gyç¾êceÕ´P=¥²žÑÙ/³® ‚岯ÞIñNA(œcìJÃã]µsÉ’‹ë-—£æ/bÖüÃÏ[ àp4(@ò84véꙈéæÝ%¥»€*¿®.Ÿ,™IWý}¥µ]/a Ci9+àÃÐ0¢ÅéU6÷ŽÞͯ'×Y5RT,§H^o*s½×õt÷FO5ö޹"Õ¦RçãMLÔ§úãÀºç]4bïÐ@rˆ'á¥K6˜\ƒéwÏ=#š’"0¼˜Ea¼Q†P`´[p†÷ïRä˜?1æ‰Nú“À!@#@&T?µßyßÕ5Wýl'ot’‹ã†SÂ0‰¢à˜§(½(þªrÅ_Ýk×%ÎzúÎyz>¬‰~PÛ=á‰jÜ&½‰º^ä1!P=D™Ìf€„Çd‘ÿ^éΉãG ü',ngumºl¸dÔ\X;Ô@2O…Ì#צŸŸùœŒP" „¡YÑ…%¸S÷y*ÓêØõ4ð€” jsàöÀï¿E# &Ê~ðmn—FJsMº¡6Ã@SÙpFXZù$Z¤b%JÃ8"¾ù|ùËA^êÆyRØÐìm‡}¦þpÉ@«vOáùqÿxöÅÝaMn%•¶#$Dá “2IQòëgÅIâ÷QéëŒ;7K[Öð¾*GyB g­Ät•ÿ×sΫ½Öë13È‚FòàMUp]<ìÛ5e¿ ^ìÜ;Ôjj‰©Tˆ ‚Š*b¥2ÚN\çøšK|õE¥õŒÚýM -jd1 U¶i®ò*g›j.‰Î%Çyµ˜ä´²ú²¦ö]u…·wŠ,NÁL)P%‚._ÍËH®­·oõÙoDÌŸ'óßlî]zaSðYÒr3]‘O˜¿LUæc@‘™îsIû©®Ê>›€“ä“#Q¢fÐ%ËP ê+Ù±v ²ioô¥¡øË}¡U*„»„Aì qŸ·ó¼¯Tê„?qÈÙ5éOªUx““ô„;vÈ·öOt,8ê· Uª@ˆ2A´ò¢aA $©€é’b”‘CJŠnW[†­“®äIoj} 0<˸'vÌðÆFÆÀÉ}±]wÌ:éí9S—øÄÛón8nTñË—-¥YV‹²¬ÃAÉ#H%¥è58÷8Vƒ[uGN„zŽû£5]àx4˜8Ô?| vu„ö»»ëy &—sFbäø‘±Ûs_?&|5÷ïÛù¿üi;¨`T‚:*…‘}&4_Ù™Ýp“n¤U34ßì ¾µFÐgÊô4Æ ¤€ r˜d Æ1€4Ç!Â<¬ög6K“1–†BÚ\øA矿ۻYÐøf¶×iÕÙ&íH£1Û$eÚJ[ ƒu¶QÿJ€•ãÅ " …‹œœRÐËIr)‡‚…VTR)•e^ÐæBú‘@u¦YÛ¿‚ßýÃw–á°ð,³š*ÁébT‹r”R­òso­×¿û“èΘúw½e¯o¶Å/µ( "G`"F2„&h”A?ÚhÓÏFË4Þ‡ )80*·ÆK)ËaÉDAeàÑpÙr ¥z—sœ|€ÓêŠ)Éþ)í»¦¨¿·†5²3ªŠ)•õ’ÒqApœVÙO¨œ'ÅZ)…uZ´}$:#O“„0² €d¥á‰kLséšk]e³=UùxÙÿ7{ï]q kð‘k¤×2›2þ"fº1ç×ÕŠäìKyžca¹„â,BâNØUÐljy¾¿çÕ\bËߺ^y§óçoG1~Õ¡,Q ˜‚fIH¾Ñì;JöDú'ë×ñ$ Õª‡}É oâxmä°?2鋆=ëë}ÕÙ@AÑ Sã8C³Lp('1ä‹båÛµk&k'úxç3æ'Ò÷ÄAÆ]Ñ1ðhÞØ·hä¤gý_j01Yð%Û¤òR”ˆàT)­J•ù†Ý/ð'&ýIÐûã¾èIW÷1O×hýÚÑ@ôh0~Ä—;UW˜A»{ÿ±ƒ¡Ä†r·€ÃP2äm¸9wçñ`äÎW_Ïݹ Õ+9Æ#üoë5Cõº=õ¹fã®°)׬Ì5»ÃÆÁFC¦¨FZ ™6v³C D0Áq\F³:H!,cK`DQ¾EoÞÕ¢ÚÔîiÖ÷·>èüÆL8¹4èSï Š{WTüùé–Ë a:tÆ->ó®6iwX ¨s’Á`ùP“©…D„S“bii)Ôr ÈùÞŸX^k(zJ9ؤi‘†æy&fC…R‡6´€ÑÛRïn³Íæl+FU6¬ôèG:”q—©˜ddH‘ŠÀÕ”ö͸z{êF»£—í¬Ç´<Á<‚qø`(Vòm~ã'‰Ú|Ú~=e½™²ÝˆZnÅ+nõêf¥3qûõdÝõ„m~+—šßUJŸ'«g"¦kió§ÉR°³Ë'­³IÛl´âˈmÿS5&F šPã0\AÿP: ^s‹ù^gZUs…µ^VTŸ­ÓJçØ¯ÓØ&Ò3À¿*UZu%ZœØžÏáû¾í8NlÇ6Iì8‡ØÉ’m8¶l{Æã¶ÒV«©•ºU«R²¢P6‡¯$ ZèvU»UUQRBB íî–­Jr $ýBþ¬Võ?" ‰Ñ«Ņ̃o^>û{ßg¦EÎ.¾áü€ …lŒðk´ÈýúÍ„c!bý†6¯“æG1Ë2mY¥Ìë†'ããÖ۱’Bí—eÚ°ðØBÎZ´l™çø)_ œ‹¤i‰V,%$‹É’O›^±€Ác!Œ¡‚( a{•ÿLû»ç#=g#dž©c9ºg¸³ë\[×0y´÷E0ØBƒ¹¸✫iŸ¨‰ýÛùªš¾ìÉÛµ e\ >l¥|‚ƒÉŠaPó”â¨Ö“oþ„‡,¹âŠÌÔÅ@€ p óÍ–¸î¢n¸·¹Ø;Qæ 1ˆ ÃyÛ^ðàÕZ8mÊEÍTÑ׫c—ê—èÏÝíã^ê’7|ÓÑ1o'ÿ^G^öP׫H –)OÈçJUçlm|ÚÙù…‹Þéõ¹QM×F/X÷‰JÀÁkìU›ØØØxöìÙö8?}úôÅsdcóîÝ;b>f01Œêð’VuλãI´™ z¸QšöªS>Mʧ΅Äçštg\¦¬_“ ©šKÿЪìªá¤˜è5†G &KÀ,íöêGZd©Z]& O…òåW 5>O[¯Ëx§•¤ƒE°ôEB&Îf‹Ù˜•'ï(7œê†ßTfBòþ}æ ìg•‚ #vA‚ÝÁÀäÒdqæhRÍ’T@• ª†¼ºl£2½ãë“W#Y¿1Ð 5*‡Câ´Ï˜iÒ¦ý²‘€*ãÓþ¾é‡r¦ã QÐBÞéS'óiDý~D{úÕo(ÞÞ*H€#Œ"‚ qœÀ‹THþÐ.D5K‡Õ ýfÄv7ìXIV¬&KQíƒhÙ*i]%Mkq]¡ªëbÔ¸FÛ—¢ÖGG,k¤áeº·n$ìiuh„ßS3x0Ÿ c˜õ©°lV¹§àíìU¼ÔñYåm¾u^4R¾ ´¯]Ù»y ÌÁ‚Å£NǾþ–y3þ懑òEªì>@r¶³œ¬P[x.Ô~ù&fXéÔ/¦{Ië}`Òô,] ›Ö% ¤úéá=ã­¶}z ‹©f¢ ð`Tá~cÅ/ßN¤’½©Ž÷F#GÏEŽåÈ£úpÈÇácg©žÂïÖ­80|-î®ySú‹Š0h¬çÇw¢ÇR@ƒÃÂ8ƒ+9nmºèŠþÃÏ7²†$˜¨O¹I[žèdþüc>z̹VK–ÜðÄfÝ—ñi7rÙÙÑWâkiÄš6ƒãw¶æ«.jÞœØÓ6VÓ6]Ù1ìQ«!/»ÂÀ<€4[i]$ÐÈdU$Ùéõ”ºZÿ›‡r`"6Žðq®„+˜Ÿ»½…mìÜñìÉÓ‘?]@ŠX"—¢(áUÓ­Ò¡ºo¬>ÐO%9Ÿ"ãÓ ô™fez/ÿÃFKP~ºA1ÚÂË…#!õ·d$¤üÈ/ŽÛQ¯äGn´üä›òL³,Õ`)Ò¼ÉU¿!0úÍ}AfƒŒ…±»pœÅÇY<.çÁˆ@ˆ=2e·[›Ýoî9úßêà÷û?wŠzª3M¦ì~Cz/”¦Õ¹fÀ'íOŸ€·*”F¹&í`°$Rgƒ’Tƒ>T¦}’Q¿nôÇ‚ý šì.&0„ñe"ÉqJ}"žO#â“qÁo#‚¾¨ìTRÑuPä.'ø±!Lˆq&RÌFŠ™“Lk1ó\Lÿ¶>¢ÊtW(ýò‘’•w@‰+{¶ªº®Óå·¢Æ1;x‡¹vÍZ¢ôQ¢òÏ­Z­¤˜2^GÙ*6W°?Wì¹%´þWh,x;{/uÜ”WΉì·Ä–¯äesâ²Ç<'É´ÈFù¨ƒqP ¼ÅÀX¤,Ë ËCʲµ,'+îÇ-'‹¤ `=^Z¨ý²©öX¥´+´énÂv‡¶= J6iÝjÔðu»£×­ál‚É“¡ò"R,Få0Q%Õw‡ ÇzG:ºÎFŽ}œüÅ`ç{ç#=¹HwŠêÎÑ=çÈ0žMôöîí€ ˆ‹â K`ä‚ëí+ µUE.Õ„ ÎïÄgÎ6;ƒãáËÎÚZÇíí—Ü‘ñÚè¿<‰¼qE¦=Ño€ÛÉm$ü¿Ø¦Ëõz¦šœ²·Ïº¢ÿtÓSÎŽ/]ÉSæ Cð‹™ ‚`Â,~1[Žïëfݱ-ÔÓ“®Î1Oçl%9Q«%'êiêš‹°®<‡ÊN¯xí«µ±+u4%*eà,Œ‹1w}rþ“  pþ6H¶_ä±±y0A aL†ÄÿÔ¥hVçíò/*tÙЈ8Ý ¬S¥Cå£?)=ÑRÒíż*ØH0Õää+(³ª¯ž?X\aɼahVõy#‡ÔCM¢\P–óë>lÈ—_:Ð`i2ðô×–¾eøu“²³r—ãa£8L ^-&LóÄ,¼]/ÿU&Õ¢n–žmR}2ŒåCõâT@’ Š€œÊ~¯.Pgw|}òj$Û¢ é†Bš”O™õƒ_J:T/Ïúµ§Z!ñn1N@c!Ú¶Þ•ö%óiDâôaé1€ùÉ„jÄLJƒÏ=A(·ÁQ|xèN¬òI§æaÔ´,_ˆ›šuR»L•ÏEì…ª®k–{G K´a5bYOØ7Hóø>³÷Ú÷¶˜ñînöëŸÉªç‰Š»¢²›Š’‚·³WñRÇ×òÊy±c^jûRe™••,í`dFfóP;¬ÿ±_ï±M]wÀÿ4uò°}ß÷Ú×öõûljÛ8¶;àGœЭ‚øq}8´S«láÑM­x•è¦&vìÄ °­Óþë?ÓÖv „4ÀJ[] ÍBH °A·‡‰?Ü¿ˆ,$®¾²Î=ºçùØ÷ü>—!Š`޲æVÄz7Z¹)[f w»«âU ±ê]¶ûS¡ž—²uwºíwØÊºï¸Š¥DÕgžç¬¿uWmá<¾ˆ•‚Úƒ¡j„¢hØ<ys¼ûWÙݽ†÷ŸíìK·¿y:ñëß…öŽFú€F2\Ž%*gc’¡Þ†2 A†à8üSUÅåºè'>nÖÍœOeÖ×saãîIwôœ7vÉý¢!h1áØwˆ#<]ù?E·y5ò¹+ò™+’cÉæØùÆèĖؤ—K5´W`4E/ÑpÉ(!€%„P+2û@õ¿ÜÓÈyWèe¶±k¾XÏÎ8³õìT}ôŠL5ÆÖz}€|Àtu¡¡Šf„Dq6Rxøðá“<{ЬÊJ£¥ÄÄ£Ö™OýDŸlÕ5¯uUU&}š¡-†tTRíø+Æã­T@0<‚ËJI¡å8‰ò`LØu#;ª“¯Ê=²1¿âtP5èW§ZdÙÅH“)åÏwc¦M7Üêµr,FI‡|ºZ-C?6íó-JH X ˆÁc" B˜¶ËÔl­öd›2»•InÖg¼ªl³&Ô§ƒ€"ÚT@ŸmUfšdé¼ó®ùº¥·jÓmúT“6éÍQ$ãS y+R­ä3…óÁ ø))­B”a^ÿ豚Ã,s"¢;&Qos db&i’„¥4„¨1Šð“>ßs±Ç²VÝìkžW^·jw]Š™tå œá?í•_F=nÉz d"M‰@ Ãýâò›Œë¾Ðþ¥Êz]e-x9{‘ç:×ä5·Ä¶y©í†:’/”U7äÕ7äÖ9©å[yínXa0C‰éRZ,ÄöXDó\õýžªåNùJLs/ažg«îÆ-Ë¡‚id!®½×Qö0j[‰›—£º%Öò§í–VÊ'R˜”0Aò!¾€$DÛjêÿ¸ëµl÷[#±}éhßH¤ðcŒÝ7Û§C}ÙèÞt,—Lè@#gÂ{ÏDö½»#j«ÆId|è#gÇÇÑ‹ÎHÁùñTfì!€éF”þÏ\¡}‘¿¹;çkØ|×L9Ã9±¬4À)èÌ;…'6½%þiC8 䜳sÒºäá|«~= ÀF£S,`JaL½ •@(´Ul˜ðÄ/9"`,¸3Ò¤# N¯8¢—ë"3®(pȧîð…†ïSÐ3‹+¾ã´3ú‰#¬Ä‰R‹hƒRóèÑ£'y’gN‘™ÙÃA £a~© 3ï(Kµ¨RÞ5/¬ÙÓ ¯b8À¤ýº‘WÔÝvB 7ÿ)ŠIôG%´@P¬çYwjNn'jýPP›ò©ÇšDÃͨÈ-º‘@¾û«‡|€š´_9ì• o6þ¾UŸõª“ ÆT£1é7öÔ=µDD€ƒ÷)!„,‚¦‹ ¾XÌ7õê·ëU#A0\“ôê“>€EFƒÒ”W‘Î;ïZHL7Ú¦Ot)¯jÔÏ ûÊ“mÖÞ Æh’@pÁ4í^úxXt²K9ðó|QIOu1ïw—›Þa•‡£¢1ê§=¶§â@Xês  XÅC Bj1˜ïe³-•‹{œK¬n!ªXI˜ÃúBí®‹ íÝðÆåˆu%¦»ÝÔÄ ¨DÊ´´”A¼wÕesR;(ß(êæ%µ×$–‚—³y®sM±qNb[[Hæä¶¯ pÈ7âÜÿj ·îh”1EI‹×¯£©¡-²¯u{Ìÿ©î²†ùhÅmÎR¨‡仨vå5ýbLµÒi™i÷D7©%ðz•¡Pìÿ0¿DˆÂ®jë;Û"¶ïM®2`#§‘î™®ýÉPoº³÷txo6ôK “ìjÀgØýã¡>Ð?ÎVÚ>†ã(Ç:õ¶I7{Þ*8?ž Ÿ=¡™öóºð„½}jsô¢—û«»#¯^\¹ œHà4×™çú G'øœv³3€%õQ Ÿ¿;Ù˵a¼œ FPáAKóG®pÈPCK…°ÒBÄhíÏÎÕå^±GÀØ+öœ76Y™us?çÝ`Ð?k_sL»#S`ÞÆ®)ë£T|â8¡W¯^} †ÇY£ã½Ç%I#Bæ¡»LòÁæòTP› ®uUUŒ4U&å)¿4ÛdúM^+Bà‚ʼâÎO0D^m×ëú<ˆ—“ÉU™N Ù öL“f$ ô«R~mÆŸïþ@ê4àJsYº@B=¸Yôh2̸W• ¨Ò>u*X>´Ý|0¨Ú^ŽkzŸÆ ¼–ab%%"J^"ì˜|°ÌeÈ4• Ê€L2MÒU§™2­…Òˆ!Ù¬+à׎xå¯<´}°ƒÙedPœa4F•êÓ1VÜß!à˜#‰|!NÅäýœú½ÕÓ¸n [ÛßÅ pšþ(},¡9Ù«}ãUÔj&!p’¤ÖQ¸†0*Þe$ÿ²ÓzoOímÎ|³»`ìB\'a]n¯^ènd­B ƒJx‰âeä Äx¼ÉJÌ7”à›hÕ‚ÆYðrö"Ïuæä–9Æ @ˆ;ÇÔüCºé&mýVd½%·ÍØnÒ¶:Wð6È1èeJa†×qënu;ÿ¯ük\NØnsUË\U¡ž—¹=ÖÅPùW‡üú 1F•Ð ®@ T mñ!“ª²'°3ÛùÆ8×›äöž½ý‡Ø[ÿc¿Î›¼ï8€ÿ41rÙ~.?ޝÇ÷DZçÄNâ#>b;Ç ŒÁºØ~.Ûa¥ÚÔBR¨èÆ´Ò6¤ ¥ÛqºMýe¿¬ÒÆX9BŠÇP c-Ò$†B`_ƒ„*¶ü MÅzËú>ü|žGßÇÏ÷óz€4R‘í‰ðëi¦{4º d”ꢺ†én0£s‹½•&wdèî1zç{›:µ|1qE,,*8bÛ4錭:?žÊ%Gì„5tÆFžsF?³GNׇ&ô_<˫ɖÀ„;z¬1 Ovþל¯§ÏÙ¨‹ìYyºæç$“®(pE£Ê Q„„ô5ŸÙ£_º¶}ê¤Zp%ÊÇ c ÖãNzÒÁwG}ÌŸ¼äîʦê–qON# äiG®ø…æyÏÏ„ƒœx¤©Ó6²Kkƒø< ‚¤¿§§ç?)²´´ôl5²©c ÎãóŽö·Aõp[i§M>÷®*MùÊ“õ [4â/ïiáÿGiã:uºMµ§‚ó0W±Õ©Œ5âh‘€Ë/²‰«ü(˜rk?r*GÚc­% ïrõUi¯*íäP´”¦7(üš‘viƯ9Ø¢O·jÒÍʤ 4t€ "Ý"Êü˜ße:(ÆÁÍ8O k›&±A–r«’Ía8„Hùä©f@‘’þ¦ÕÒˆ1T$ݲ”K3ì&Rne¦½¦ãÌk‰BDñÕnñŠˆö‡Õ{eßkËiDÝ×)ée…°’ýqñ‡q0õ°%=q¸·“è¡4ïv({iULó!z©<ãóQ A‹1œÏáàÂVåE²æU²Z«ëõxÕ=J±³¼]¥òæI„„¡›0ÅyMS3OÉ—•¦kÊš*ª¯‰Í«ÞÎ^äÿ:S ÉyõYí…õ²Âú•Üú/¢îª¸úkyí qÔÔ6®(kæƒ÷H\ÍAóyb;ŸóçVÓSu;b˜‹Y®ÓÆlçªi$)nÖ»å8VÁ‚ò` O€ ¤?k  o;Bîì í"w F• oÏt¼ñ1½ó÷Ì.0›'ª+}€d„ì#»“¡×Gâo¦¶§Øî¡H×DZÝ6£E€¢ó óh]å¤mõùñTÆ­‘ËέgíìɆHÎ 4èõ—¿Îì4pË'æv0˜x´s¹ßŸrÒ§I ³væLÚ:Øw1ëE¥ÊG!«_÷y{©"tÊÏìÁ`œ‹aՈ䄃=e ý®¼i³DG”vˆõŸzÈÉF¨æt}$WóyÏ—ƒmÂE y”ÃApÁËW1èS§¹¤üÚ¡`Î'Éf]* È4›v7ÉBÕ’_·ÊÆ^‘%}†¤]“®Žzõ‡<ºƒ”*“E?RæöµjFZWKËÏçËúýy¦Eq¸Iž´×¥Ö˨: n 7á”ð;êax‡l•÷°Ëid¹H?ˆŠzh¢?.ëûX]ßVåžH>ë‰aáⰇŊsyyu"h¯·q1Tz‡©˜a-ß²¦›¬îVL—í4MG-Wã†[Qã]Æ´@ç¨ÒéxÅtgÕÍXÕJWÑyº6Ûi™Š™o1Õ³”éÞÖÒ©ˆf&Ú0Çj¦·Uîw˜eˆHÄÅ!š³+^õ¶õ"ß«dñêoˆª(-W%³Ò†ODåVˆ»V¯*è\C\[25×)m–Ñ,FË¿e3Ѳ™NóM¦l&jÎÆ*À¿zžµ¬ô¹¸KëÁÕ%«g#µYºö6]~›)é ³Tù,£]ˆigcå7âõ×YëÕ ÚFY ÚÂ0L 3ɸ˜ßbM¼òK€Šaº{”Ý9¼ ¼6Wšd´;ÁvíÝ-.„@}‚”°àÞØÕ‘cMÔd}äLcè¸+rÁJ³GÏÔ³«Î’§rÎ=Ù÷2ŸÛBëÉK6f¢žwÆþhÙDjk,0^ÃÊqþ1/uÁw„VZ¿»Ô (RŒó-â+ûkÇêÃã.ê¨m³ ÌVOŽ õR Š9`yÅD<´HŒéÖrG\¡óÞm“V é„3rÊóÜçáÒ:fÜNŸpÑ“ö¸*ƒp1BpÇøwç€.=xÂ’'8Yégéq––žTùÛ_òa¸˜‡ñpL`%ʵ*†\úA¯òÙiD=èÖ¥š5éfUÒ 0P’ ê“]¢Ù0è¥Ú†!Ÿîm{^Q>¸#r²¶d° 6 L¸Ñ¿ø@3/p„\'fêo'Ò}Ú¯O¸di"(;ܾìyQD9èyL0Èi$Õ®Úl’Š*à©aY›^»Ç#8²Ñ8Ð¥)§"í3¥^.}ß[žnCGì«Î§¢úÈ«;²Q“ð+Gýe™ ±/PdFa…!@m‡(BÖê÷Ť=Œ¬weQôå’£H_Lò>­ézs á¿»E¨àÅÜ|ž*0¤xíKÁšš’‘¶ò{±ú{ÚRŸ}Õrƒ5ÜcËYËmšbMÀ!Ù˜ež4χMwÉ¿ÎQ•×:Jæ@ªd>j¾N–Þ}µæNX;jú{s¥Fºâ®ÂŠ¢6WÔ¯z{z‘ïU.5ßHknˆ+¿$*¾PÕ}­l”Tjá<„/qHœ¿¶àf)Û¸aºÓ4C²1ó4e˜aŒ9ŠtZfYóTØ@²ÒçâvØŽšù7ûuþÜÄyÆü?è àK{¼{iu®,iuÛ’ïK²-_ÂG „’†ÛZíJ¶$3-á(m“¶i8†”L|ÉÆÒhki&“š›33mJ C ¾Àƃû¦™–L™1…qg@ó•F3zvõÎû¾ÏçmÏÛž7×á™–ìa÷t¬ðúv/”–3¯JÎ[1ç×Mö=¹ŽAz–gÍ3£"´)D™%ãõÚ—º;öEÃo|‡ŠÇÖH⇑]‡›^«´g‘8±4›Š¿ê ž È£åòÙ@øt0|²¬õBIä|‰|*ð§‘±¼-çK•±2ùl¹òi…Ü›¿Nræûh:ä¦Ç¦AZÎyñb¡2Z*/·þ‰âÍFŒ`TP†*ÜýËâí;K A<&BÒÈÒ}Àuqqœó«·~I°‡"1cs®³§NŒÅžJa áIuÏôx5PÄ é®{ªœñØWe׈=AÛÑŠéåæÁÕz\P1©ž¹)?Iƒ­Ö¤º£ù®Î°1ÓFkÁs’Ëña£q°Î1°ÖÑ OXeˆ×Øúê¡à‡ÐSW+È$¾ÖÚ²Ôù®OÍã0ã†W1cĬTcƒ3cw0ÿp½µ»BýQHßÌì ‡‚+·"ö×Õ ‡ƒæa@]­®=±©jšƒ L‰÷Û ˆa|¿ÝòŽÌw)ËÖHg0#tÅ€%àÃ~@b;Ø¡9ÖБ¾»I—뙩bIéUi$ÎR\Ú&7=ú£ÂÅŽâùfû¢”1!y¦Ú2&eì7ÂÞy9g!š=¯øæ”eïºàÉHÖBÔ»([gÂö ¥p¢5c)fùǦR¿ ‘(‰¢Sà¼ç¥™Ïù¬i­ÅÛÓó Ÿ–ê\(‘G É®4?¾¯…‘2帿©Vp³©*‚§çHþ‚–ã :­d-ˆûÖR½Túê˜_yŒ[´X½Œ*HÃ޼`Á1’&‘…k)T¨6vX †r_­hÿ8 «Úv¾<6Z>[Õ6R>]®Œ•„Ÿö8Œ€CÊäSélqx¬L9Q¼YM I1½¶&” È“ÐÈÝû¹wÿõà››374êÌ€ñ´™°}°ÞÚWíŽW‹}ÕOP#àsuzw…ëØ ¦þ*#äHµº¿„ ôÖ{j„#AÛpcG%²(-I³$ÎS$¼'0ϯ"(ie—£¿1}°çì­±Õ™j€:ÿí¾â`\"ð(bé­y ó±å·5νՆ^ÒŠ©QKa«‚JfXZK¥!:k½Ã~äeÃÑ[oõÊóã?£‚ Ã!gO£ãÇ•¤£Hħј Þl6Œµñ‡¢úw% …¾ky˜$àŠq¿ 1l{PÓø^›ñ€bݱ¾ÓjéT,¿–õ*‘Τ[MrZ-œt)ÇUNuRWP¼ ,µdÂ~ ¹sÏ·ûæ•Ìi9c¼}Ù»îḏ ¹n6»'¢9`››[,¯ßÊ£~€#"HéqÍ~ä˜5ÿÕ”õµÞ»âíéyž©üݘ7¡Î×çüMð}cðMr®ò¾k|Ö—bÙK˜G8Á14ÒjñU¿R|»Å7†Y ™‹xa€€"×åe+}VrOµˆ7×\GæDÄ9)¹Ú²ïD½§š\1gÂ(ŽæYÄ$64’䘤 à~ëåX|ëÞxdç`ø²_§ÁMœgÀûµ¶Óba[×îê^Ý·laÉÂò¥Ë¶l É&Ê[»ZI6&†Ží2”¤MƒÁÆ\G—Ò0C§ýЙÒvÆ1 ¾Àæ0”0iá´¹J ¤LÃ0t’©(Œ;;ÿygWÒ¾ûî®vŸß›´öSÉPÇÕñˆ°þøfz¡:bT{2²ñPcÇþ!"f`lfçÉ~ï|â Ž8ÉI[`Â8å)›~<‘Ó%Á‘ЦNC•ˆÆä2Ø_›Á²Šd¡ëÁ¢åC¶ÆS¥ÔIg舋8a NØÉô«<Ñg_!ð1>þb¸/@6†Ñhv¡¢}‘ëWE+GìÔ”-|Ì<î ÙÈq 9ZÒ09‚§Jƒg¬Ï]#p§  Á\ÔŸ”á³L .¾{çï÷ÿyï¤,÷<¸ÿU'Ûá¡ÙLŸÍabÙ¼ ™6V¯ˆWé^u«ˆ}m•O7 mŸOu«“~°‡6Y«‰ùuÑZPŠîÃeòè° |[X¡ e˜"VÎæj²:Œ‹)äruÚÜÞ2EÌ+‹{• 6î¨â­*éý†C+c^pÈ#Š€ôq¿2jËéó©µx_(^#{Û¡ª×ò¥YbƒŽ±$\‹µ`Q[¥$¶D-ÓÅ\óÎ'"I”«n8#Ýžz™MÁÄà™ÇP*©³Kv6?@Üí¤¦+¥ˆt)r({šU=Í’Tv¤(";)hÕÝaé6RÐÄ÷´(:›T V•‰Îf™˜ˆ/æCˤ˹ JäŒß-5þp=;á |Ð_ çÞ ™ùé¾uo4çܦôw#ÖËÁ‚›M–ÙK¯G­g.ò$ ÙLœ!ø G÷…|ñ ±é‚¢âœÒ0ïåée^¨|.µ~ÁËŸÅ‹ÎJÍJÓUYá /ÿ´Ì|Ad›9°ÑQ—±-—`§W›fš oDÏ’&Éݰåi¥Ï¤¯ô{óUÂr-\ÕmB~÷õüÑ mK‰ZÃUqé ü ;E0!ËÅ-ËV%¨”1ú[oöÚë7ï&6¤>œËC †6BûI„;zCíÀ›ƒkÛzƒ­&±JHŸ›N2XïÔ W¤ê餓L9CKÞÿU¦Ê¨!Gàg’R3#5lä]£çžÈ§EÄ_œ¡£eÄ´#øyiNa¨tÍñô5uÜv‘j_šÍ °°"å}éá’†aGpÌIM:BS6 (œq„§JÉSåM“åá;1f'ŽÙÈ)ûs¿cs™pÇdjÅHÍ™haldôjäßë÷R¾³åm €ÅAÐLqĪÖ*På«”}@ˆg¦M|N#‰¸_«3í«—¶—l«„(’>e´:/±TÕë–&*±¥¿¬“¬Öñ‹q”ùÝl- «S«Ö•åîª+ØW¦ˆº5±EK)ŠD+¡e¬ò(ò!ÑÅ|Š÷ݰ‹´·*õƒAŸ,Q©ß·ÄÜ]+Ö M©ÑÓóvyå±òEƒ~ý~÷¼óã‰è{«ðxEN¼Ö¸ÙƒŠ˜6Š0‘L¢ßBEðî¸3Qï\§èŽHºBéjDØEA?åŽ&Ðà:n‚Cä=aÑî&ÁÞf`‰x+)ÞN ÷7Ë;×Ê6¬äX8,˜RdÒ8(å!8NÿÎëå‘W3Açíu3-¦ÙPÞ]"mÀ¼ïzÄt«Ér‡È»N™7”ðitD dÑ¥ ¤Š%œY¯Èò>“çŸZ.)Kæ½<½Ì •K2ëy±ù‚Ä ,9-6&Ì¿Œ[Ï«­ç%ÖܼßâÆ\*b B¾\üÃŒU¼sDîµõE3M‹oRù’YØ$ 3acºÏÅ¥`Àæ¹x†²^l¶Å}:·„Ž1²³<@Éæ`Lö÷µ|fCQÅž@k´yä£ð[ƒdŠ"@ŽÑ%Z[6?®‘‡ ö)4¼‰QíÐÿ`cÛGÔ¦³šƒb\&’²}2Ãa'qÂ<æ"¡Ì:Èy·ÇæTÉÚ?8^Û’ëÎb ± ø'eáéBâlqðãròOUÔHE¸Òe¯ûqžcÈE¥ÛÿI{h¼”"e¦W¸Ú¶Ç¡â•pAF+iÔD)9Yi@€vrÜÖx6‹Ƌ֎ÛÐÈhEh¤22TöÜ/Œa¬Œ‚;5Z–ºS£Îðn£Ÿ±¹CÐwþ‹/¿bȃ¹åé4r.«¦¶ºÀ³Zš©ÜR•ÓëWôy¤q·¼ß¯Ùÿ̪§.Y%¹A#ªXÍ¢ýõ²¶ÒoåO±\¯Jzðh¥&Qo|¿ÖÔWÃt`níuÒ>·8Zmî}E’¬%<†ä«ü¥’:Vaˆ{5Ñ*yÔ£ìóH ý> Î×WðibK!Ú¸¢û"Ø{V¼½À°ÓoJ¬Ð|à“ô:åýÊŸ"V-¬w¢(SP(ÍݳL—ô*ûÝœ„GÙ»|ÞùñDòö-xÕÉYµšÆ](cpY¢(É•ôD[)éÞy'¥ínæm ¨·†àÃt5‚ïjBä]aŶT+ïiŸè:IUWß”v†u;Ök{šäÝI×kÂ]Ͳ!ÍVBBøÙz-‡Îg¡’l›£¢#ÙzüÛ›œÌ醜Í4.­³¤ûÖ ™.®+¼Jä|I®¦Fm6ƒ‘Iã+yH–‚Ã:¬/…ié9žùªÂx] Ÿ—Ï{yz™*Ó Óeyá§bËEáeqñ¾õ‚´øž7žÕäÿUaÙÎ5°!ÆbqØ?XÀCÙi€Ä ‘w+hº6ߌä]å¦û\Ü n wZLÃkŒ :ž•³ Ã$ÏÎâ1ÐZ‹wûšöä[¿¦6\óÓÐÆx ’$Û‚ý ­ ‡GœxÄ’Çqòßçñf´ÔŽ6´õo`¸PÄÂ2˜(“ñ›¢U§‹ÉW42loœt¤]ÍŸwŽºVOWþ‹ýz j*=àþ¾©µ IÎ%ç–û…$$!!wÂ- !Aˆˆv]ëºBÎ9É `;µ­ÂººÝéCÝ^t½Ì¨„tËv¦}h§íLgÔP@q­coÖew„*Ø݇g|ÐÁ¡žùÏ™3™É÷}çLrþ¿¯õ¯¶mR¾FQ ò¥[Fª¢#ÕÜßÜ ËÆ·ÅB®âÊï þà~çEÇÞ¸à÷[¼ñs¡øåZî3÷ŽëÕÍ úª¢—¼Ìp ~ÙÇø¢ºß=çk Çk˜€d¤’¾êã_=änT°@>@#`%@Aý>ö/eÍ0†`¨h˜hä)!_Ž"_ƒdqñkÏ,=^˜›‘Ôò¨ˆRä«RQ¶ÞÔQfjL'ƒªž+Õž®›±3AC¯ Sg:´•a(†©ß/3dȾZýÉ õT£æô÷Œ§"¦aÓÉ-æä&K:\ªVfüÚÞ €–dÓsÕÑ.L…m”=!]:bL6žjÐ$ë5=Ap–§ 2]¦ëõ›’Ûˆ™Å…¤¨®P»§Òx¬®0³¡ ['Í¥ö"ä‰×8~Ñd6«ºCúTðlÕùñL ™ ¸Á‚£[PÊ[O¡0 #нÍ/ªŽ• p‹ôPLz8®;ÚnüYTÒä $ŠˆÐ|…`La‚R9r<`§=Yç4c˜mssN$\sœu†1ζ:&cÎ)Î0ÙnßežH˜gXËkïêqÆ<ÅšÀ»w³Mp¥ûü…ù(OÍ—“$©€Ö|"uM‰¼ÿ‘•ü[åü\渭tßR–®z=½Îë€üWí¸©²OÈÊïRžŸJ¶ƒQ1"–Åç¿_”‹iYÍÆ>Ó^>Á˜r¬qƒµäâÅSíÖñ6ë8W<É™ï'Šïq–9®8Õƒ?ÂT«ëNÌq—sL·Ús´ã:íé(S*5yŸÄH)ŠHÐ|ŠLÎÎM;»£{úbû˾ìÑ{1Z¼Dž:$Ívf£}Ñw“ôÞܲóø-³kÀÇܨbF±K•-CÞÿ; W±ÃÕÌ5o|·®D†òQT ɶË[•%:X"Ä ˆÀ0 Ç)ÞkóùhÐ×ç½;‡B‰Ëà‹~îJulȳbZõ0}ôß«¹Á@àZ% 4òÒ8ÐË 'ú¯Êøõ ¦¿6®ozâàÙ®Ô¼C•€Cìh 0Œƒ‹ AÖMR¨–"B>|øè©'€#½$H¾)™‡ >=á©v(¡HR.Õ¦6Ê2õ†TDu:hìªU§WL#E]åÙ¶' éª“n³KÅQΓÔPÖcõÊcUE}MÆ“›T[M˜A¨ï¼¡åÁ:ý5ÅÝ› ©zmWPßÛ ï®}Þøút½¶»¶0[¯J‡– q:R(ÕÑ'½E©}ªI¢Îº,– ¶_4Bˆ‚)„‰aP”ë:8 ‘5™ˆ!¤ˆ¼<¾|]ÑûµŠîúå‘Say*¸êüxV#©€6Ý$cÊ!’GÁCI‡Q}pu(bø¨œE‡c š#m¶C»Œ?Þ†n,Û"'a°ABdŒHÉo¿YŒdB–ÇQëWÍšé¶âùV÷=ºl>Zžk1µë—š-óQk.æÈqÎcΰæûmö©Ö¢™ã\ÂùÇF“\²V£ ,àC?’¨‡ÕÕ2Ï?•®[*û;¨€[ŠòU¯¡×yåÈ·Ž1¥kLQñ'±}I­ÅyL,1ŸI2–(ºµ,$L·[,‹‰’…˜yºÍ (’cŠgiû<íX`œóŒm®8Äžc,ÚœšMië\{É—QólÜ~¼ÒPE| †ÞÀPr 4¦Óà’Ý‘íw´§ûú¸Óïö¶tdèŽÓñª5r&ÚÙCwœe÷ygÏljû·Å”BJã"S¢Â?—¿=êc/—5ƒâöÅWÏäŠ7~1»ZÅ‚~ÿuyÄ$‘Á$^˜OP‚‘z‘B „ñx”@ŒÁAµþj5 d5`.y™Ê–Ñw¹’ƒ¬˜F\€½Öãg/ÕpKçüÌHMh¤ßÏŒVdž+¢!nÈËÞðÄÀVìQTÒËñ0W<ËÚÓ5*u$NP#ÂþO/.>9^Î!ß<–––žÐdé—?$0D,$”Qpˆ.Y¯I7¨3A=¨àÔŠiŒ©K† Ò!ãG´QæÃ0ÎZpÕ‘FCöMu¶A“ŒƒR„à­SrT.Š0 ƒÍ’Â]>gv‡(]«Î„ éçj¤ VuÕ² †L:T¤ƒ²d­êTX—¬Òõ„µ½›Á}YRõÆ“ w{óñu•¡ØJ¨X‰U™T%Diø©Â\”éWaMoÄ”¨NGVÏD×å5¤·àJ !¤´“ÒuŠ#‰ÕÒˆúCVõ›¸âh«ø(GfUÇÛuÇv)ÒÀ$R›‰!ËÃÅ–¢|¡”Ï”‘ƒÛÝš-[´íXÂ0±»l!êZ m3Q[ŽvÍÆJçâîYÖ6/šLèïÅ “1ÍäŽ ·âA<ìNÐü0)QVÜQ{Ákÿ¦Æ>¦tŒ‹ì_ÈJoËÊV¿†^çu%_JÜc2ǘÊ~Ÿã ω­BBCׯEˆ÷JU³Œ%·Ns¦©˜ý[ôULw7Q|ŸsÍÓîù–’ùç cb-“?tOq¥wš-3œá>+Ÿd ¿ßj«•å£"p£pRÉç‹T¸*h:ØüƒÓLçYnÿ'ñgŸP¤—îTÈ0¯Z#`"0 `O_lÿ™·ú;îý‰ÎP‘ `I’!ÿ“÷ZMtýgåôˆŸ[u~<ÛþÕñÁšØ`ÙÎ;e‰ UQ'&H\ˆ"üì×Ûs×ð? ÍõUZí®vW÷ËêjK¶,Ù¶,Y7_„- 4­¡X»Ú]]€2eŒ í„ÜšbbB ¶, _`Ê3íC3™Clp %¤”Tl \Jlpã™>0“>¤JÝv¾³£Ñß9gvôû¬0¼‚桞O®é.óœ¬~ ¾âd&ª©¥®]»˜qL>gk=ãµÔ˜‡ž®¦¦ªèkNä´«x ጛZZª“úÌÏ]ôr5ôXÏ ÄM팹h ‘Ë5áñÚðn³P‚a ÃÞüÕ‹ÏŸ/,qda™ßéžYRÍóŶµë€v@ TÈS¿ÝP”h2õ7«RÍd²^—®×'²¦]ºYÛ_§J6•¼±ä)ù_˜«ßV«jàQžÜ¨Ý^%Ç!)!Aø"e®àšÊÉç›E¦wƒ²‘Uʯðü§*© v Ñ˜hP'=â´W;ÒbÜvAŠR늎4êeCÀõ=ëˆÍżj¼@R DP˜GàÀ$ˆ\˜a Lò³öH“ìX½6QGö“ÇÖ®8?^ˆ<áÓïk@9X*)S½GIß§VJ#šƒ1²7ª<À©{£äÁ˜ì=¤èÐvÍÝû´4äj$r%0QO˜ãZ ôvúóóÜvÅ£¨ô)e¸C¯¾µµx&n¹Ë–Î…JKžD¬÷b晈î~¸x!jÙY%΃¸H)ŸRÛKkæd•7d¥7TÖ(m©-£¬¾%}©‘—ùÿˆ<ÖÛ²Òi²xF]qWZ»3b‚Ü<¤FŠìT‹ò~¬âñVËMV7ËYrE_Ŭb•÷¹Š¹pÉ,S|;nšÙQz—±ÝátO·iÅK?Údk¯K„¹bZE`< %"R¯+í]ïÜöÚñŽÎãt È±o2Âíeº—Mò½‡íNÑ XÃ(µ;Éuýrm‡P‚Äf!Äcnö?{ÙÞ1îaWœ/dÊÁ`ŒyÙ‰Š-#«×ë!„aàÝǫоYìý¸òg.ö\ uÞËLÕm½TE]^MM»#`;ç<á îðEW8k*p„.ùÙ1_ø¬'tÁE_õÅ€C€ ¦Ì§ŽŽ%‡€aß”lÈây^v1 Ü„{I#çü,8à“áªõ„ðÇ‚õÅùE@ˆùÅçóK$ùîY¾?›_ШIpÚ #ó…ª#­¦DÀr4(O·hë5©:ý`s¶ºgQ²Y æL6«·9p”/â|$§| ÃrØ­ ’ïø1_ A£ñy¸U’g€$œT€æ’í¥æþÖâd@–ô~{‰FÝðZòh#ØЈdÄWrlƒrG•ñP³ìÃ&U¢M›jU¯3Gý%}Mò!@£€®' Ö¨]\Æç¡«òD«^‘æÍEÅ=­šmÒ¡zc:`èƒÁçÇ Q$[%MZ”W ‡¥¢B¡¤¹FÙ'{˜•Òˆú·1€õ~–ü k<¸ÕÐ×X"Џ!öoÒô„ôûÚ‰¶JDIÈ `u.‚ÁB …Z•¼>¿!w>Øn™݉êïÇMàÏùqÔò€+¹Ïšïqæ9Öô8^þQ Âˆcb1,ƒ áuÅMIÙ¬¤üï2ËM™%£°Ý’—ýMa˨«¾”W®|z™—QØo(«¿”'³ä •麲ô‰ÌyEäø1Fäà°’H Ŀšf(ëBÄ”‰–?¡ ÷(ó k[n5?‰Ä ³±¢EN¿2]k/ïvÌ„D Ëq˜€‘<)"F eRÕ[-›ÏíJ‡1ïîØ9Ù;ÌíIs݃ìn „‘p°ÁÿF# @>€C#¡ÎdèõT¤»TJò¼ð„‚Êg½Ì_tÜZq~¼¿Ô°5ô¹@ôS7Ýë\‹£†¥~mörmºàf&Üܸ3ü™ƒºê‰MU…ÿà£/øcÀ0ÓvÂË© û¸ÉÚ¬©à¼—>ç£ÿ\ÛqÑËM:èi' V8îbþêŽ^©¦'\̤‡»ä QÆÜÌ„²TwÙ!`#à~ÁÇ‚B€@gÜ”c¨'D *ÍâçOHþ‹ëß¹6}ÌŒ`Fø•"2µ®8QghÑ ÖëýYÓH@>ÒhH6 9 Dðaà AžiÿOµéFuPZ¯æ£Dƪ¤‰Æâw#„ Á á…®/X– ’éÀ·Í¯ð“é >ц©ݪÑ5¦ýÍ?0æcÄr\µÑb~Ýk>ÜZœnƒeé€&í)Jךþ€:ÑLþ®IóV-ùZ…ýÍ–òCJO´KÒD£MÔ“c*kçµó<´/Ïᘀ‡ "‘qW»ø §í‰­”F=¬|?£î‚Èzi/';нqòÃÊàKNûÁvm÷ÌoÏJO …¸Rh)<ÕV6ósûBÈöt‹ùQ‡ác¸5ÎEK²e_Óö딽Z%" †æ´M š‘Ø2âò/¶ëdyFiŸ•VÜ•Ý[3ÊÊ›+݃^æe–ó¹buF¾ú*Y–QÙ2Ò²[²ŠÛ ן”V“ðò嘈ÇFÄ#Ö¾¸Å àý5c~ÄYç¢ö¯b–yÎøŒÑý“*½GWÞ¦mCì.¹DR(Vcrðc†$ˆT‡Ê·T7&™®ÌžjW_dϪë$÷Î2BÜîÓ9îL‡w/i„þþ)Ât¥èΑÈÞ4Ý9Dužàö‚ûqv]$ D$@…"bÖzÑÿ¤žÌ^÷ÌV¦j#§=ÔǞД?–p¬ò0T…ŠÿhõbC|Ü9ï‰\òÅ'ݱÓ5T²$È‘öãî͞ؤ=4ቜõ† &Կد÷ئ®;àûÒÊâÇ}?íë{ýˆíçá<;±ãGbÇ΃×Xa…Äï8 Ê @X»¡Vla”ı’2­Ý¤©T]+U£€B@¤]×0d'ÍhüCC½?¾–Ž®ä{~çèÞûûœ¥ªçrUô¼-øy͈7îª:2Vû¼6þ¡gã®øDUx̵/¸¢cµq ¨¥š÷´'2ê /°Ê¹à0^”Ÿ9””ᨒ /Ÿ´¨‘ÇßÅ#ósssOž¬Þô™«eÜ›}~<•sÎè§µ¡ghÒÓögó«l>‹‘”ÛeräNxÚ?u´t—6­W’¬‘êdȯŒŽÞÖq[ä¬3rÊ=éj>ooY²z<‰LÕ:ÁL…„Ê/ˆq±ü´7vÉ9á 9\¨ŽœsGO¹–L#Ÿ×,@qÜw‚u-kÔãÑ­•r£q2uøèÀßsräÑ#À™ùÇþÞžhÄÀpÝV9µÒ0P:ÐH~ºÞ”ôq™ú¥êžút£*é1õû}kJ”‘c:„É!%0Iâ8ã/Gq/ÿÃÏó“+ i§úpƒÒ. ÃKh¢ZgȬËû“7oø™:2¦jùT@›\%©5ªk‹µ2Z-S¤†0&10‚p5ÉÉ\”Gx—N¯Ôuû´™ÂP“€¤¿A5è2îüÁѺ¢UÚ£uÀ*bê™ ÊVT42Ût”ŽîLÇ»úƒÛNÞ íìïèZa²j "ÐnÞ.¨wÇþéÞ˜u~<•‹®8èé—«"§­Çu6»F Æ”R‰CÐZy­òÛ~ł΄a# µŸøZ/»ÚGlÍ@##žà…ê%SÁÅê6ps+€œ ¢(BB£†åRˆFšû‘/xÉûÄ:á·‡FíA`†¥š÷³šÐà‡#¯?`L6,¸â  Ý]¢÷èàb &säÌÊ0ŽT„R ¥1¦pˆ0Ò\c¾z»ÃØë×÷ ÆRM  }²^L7SYT‡:v¬\X]É@›òšÞ]Uø†¦5LB$ U|wDÕÛjø}XÓ›Š÷sìs÷ÝNBÛ‰_bÇNì8W’j ø“2¦Ž‘ÁàT¥!@(¨8¶.ÓV©Õ&UÛ˜ZŠ:B …ŒæJnmakwS Ù›¦Û7&‰¬JE–eŸóœG‘ÿ¿wñk|ù¥‚DÀ¿: á„–Zs$ª¤_LV6¯c·!…Ô‹ÒxŒ’½”ƒhp6d2&›¸Áš‚Á¦¢£þõ%ÄzL¢ÎÁ¬?ä×§‚ºd•&óX¨€CÒuºÌ2€F'H4où5ý›µg›éÃÞÂ_id°e™2F ’ 0%¥()ä8%‘¾D³Rü¨U<ã[yv@U\ÂSDÝï_~ºLx@CªFHŠ2? [4(в8E@Õh×Op'ÛÕÝ1þx4ëÌx¨„Å×#ª“;õ=¯ˆ›q¿fHr]ž„BÕ˜Àçñ|µî;ïÕ›Ó•ÇH¦æ_ãESšŠ{¬ù®Î˜–Õj‡Y¡øW<Ål˜f‹fó¬h™æJ&è ³¬mŽ+Ÿçíó(¶7ꉯùŠœ‘ " ‡’ršùâþ_ÿµ¬‘GOg‘G‹ßhä—‡ÁRŒ )Sù ÖZ#@€ @#@©¦Âuúý^y¨q*”A½òÇn¶·I¸Ø ¬5 æÚ^T#NáÊui¢ ½ÍšÞ*M*@Ö?îúÊd ø»¢m2¨ë úë Ó…Í|ÆOüªÞp¶¶ðU/£–³„œ”!´™Š„X'—“øz’0%Êdî”|ݘi×YÙ€*Y£úúâYI~_€¨5&ÔýA1Sug¿/Óçá0@I£`«¦§ƒëŠ*{Ú…oF”'`lðBÑÞì0v%4¡:ÂjX”¢ LÆ+ †ÄRKs™•Ryžwˆ6|Ê8'Ë kJ0öÕj‡ ¡d’/™áM œyž.YP-‡-Yݳœsб±¥àŽãªÒ15èSÖëu2ÅÛÆÛ8W6!–O ¶IÚ:ÅÛI²>Ø3æS¹}œ±Ž3æ¬å/\ékc¬÷W¶æYPšþÈæO(]~ŠH&ó$ß kGv8¶$ô=ZÁq$‹‚E(t–ÛÛ3»ö·í=Þ÷ËöƒÃûÚ:³ÎŒ'Ì…pg¦}ß&{•%d0L£H»¦ôFÕ2<@¥ŽxãCîÈG¡áÊɰ;’- {#@GË4ò¢Žºw³7R‰\QhÌj^ÿFQà}{Ûmï+V„îxÚGœá ‘O亳uÔ¿í]EM…ï8¢Wª£`3ã®ÄPeìŠ3|¬È{»UÓ‚ UF¯W„o¯½âF*Ûk½‚"ñ\)c¿½üû¥Å¥‡žR#‹_ýséÑÒ?»RR©¶™×Z#šsAÃ`# ˆªÓ~í@máùúd½îLÀt®Eß·‘ÍÔñ©j]Ò_~®El5Š0很(Qõ1ÙdL•—êùþÆÿq‹ÿ²a$ÚÞ‚SnuÊ£¬6 ZÙzR’C¬ÓF}Š$ ¥øHÕ¬‡1“”Gšåà»+WXá H¶(RØäÓA°(cìÇ/d¹=$žC¢¸B‚0´êž¾'ÁwEÅ7âÉxÖ™ñ„¡N'¸ž„p,&ÝqÕ©Õ‰„òµ°°­J¢RðIJq“#2Œ@0˜ÂPXêS0ŸàŽy•ýU0%˜ØòIvÕ42CÛçXÈ kŸ`ËÆxë]µõ®Ö6F›¦¹ÒYÑ6'”M3¦)ºdŠ-wÏz½®Q&Ù‚ MÉgZ`LŸ)JÐæi•å.SõÁž5Lù¬`ŸÌÓ|1x1Ë—Ï®žfÿßÌ æ;\Á´íÚ£à×G¡rÙs JFQ"…‚ eP!©<¸ew2Ü™ u^ˆìÿyôÀÅоÁÖN`’ ñYgÆæRt_:²·{Çn\ ãH BüÆv„@Ÿ‚b½Y»V Y–€'{qQ„>r¶Öþð¦=ŒîØŠJ$ ÉJäõO]k­m²T¼&U£ÉÔ¨üÊLµ8Pͧ}º‹5b& >ëÏ?0\¨ú|º¾:1Ù‚•ñ°RŠGÌùƒ[Œ½A]&¨0Hn|ÜõE”}mº°Ç®_™_{±žNzÕ½A¢ÙÀà×¹W­îoæÒÕÜ/º@~O#¤A J¢k,¢^ó,3æ?Y;]²‚œ¬Äªˆ©`a_P™®Õžß„øD'&œZ'c·ø4=dOL *þDŒ;õ­Ñˆº+΋(Ïìš’w…å`þÞÝùÝ?R½B6™¥D®!ÀIŠ 0./'s.àE³jïg\Ù [<ñoêëü§ÍûŽø_0­Kc|=·íçyü¾s€±1`cÐP-M–ŒOȶl)„œ[[uÒr‘²¤Œ IÚhÚ´VmMºMi! ¹HH›I“6E˲¯“­¿eB ôѤ·¬¯ëùúó<¶ü~=|ÉCÒv-]®vü˜bK§ÔÖ;”ù>e}È–.жDñ”¶hŠ/œa‹çÔÅ‹Œy³Ì³à]¡»uÅòÊzƒ3O3¶{ê²UÙ¼ªì&o{¨2 >ØkæžÆz›/¹Ãe EO«‹î0¦œE¨y¦UæG9Žû´ùoÊʨ‚“"¢DPJ¬2È%(…ðBÄ*±ÎÊÆd`çPhpÈH  $“ð®TdW"Ø#83–˜ÁîdÛ»Ÿny¯˜1 †à.•²®ú"/Ên¼2C‘‰šˆP™¬‰^q†@^ÐèbutÌûÌÓ~³ªãK{ÛyGûduì/®ö?x‚¬Øžµo¸åŽÝqE.•m¾P¯³®¹–mþÓnðѱ«5±ÛÎØpISIdPDg¹XñüŽUGE.–·/WGÎÕ¬øý¹à V¼C‰Ä*…R)ÇZÖ¯öäé«käé¿fž<{f.Î#d0 “Yjq~ÓJkð Óïq¯.S¯>m«Mºõ)/Ÿ¬¤?ñåoΨe“žÜ´?'î'Gš ß_£ûQyNüm6Y¯IÖò oÁÇ>mêiä?ìyî‡oRq)Õ¬>Ö¤*Ó)%JAñoç³ÇëJã-ªcUº‘5ºïs…Z %àlyaj2sá©° °  ¯J#š!1U’;àSåmsRZŠAB*nïFÝ(Ј¾o { Hö…gÆcüe8Šê‹ƒ€%`~¦¯>ÔNíWÑÛI æmoAi]-Åi2K!ß@S”ãžÖ1KYøÒiµ ´ä ïX®vX$ é’yÞrŸ5ƒÍgÕÖ¯éÒǤm2Ï“%‹ªLæiPÊæ»lÉM¶Xðz]¡œ¢JZ0Ü‹ã>%íÇÈ&HÑD(¨òìu£5ÏÒ%³”m†uÌ2ó*Û#Ò<Çš„šç6]ú•Ú~ƒ3ߨi3Â""K¢D)ÍwAJ0Q½Å|ô[v§c=C[ÓÁ'c{‡ÛmÝ';~Ò¿é§#{gÆ3Úº-ꎊxÖâ2„ ð”±^S<á{Ч—ªÂ ï&ªÂBiä¼½õfMÇUG´ü˜'hqɘvÆÎU®Uw\­Š}V¶a§Î^ÇXf(eÔ`î5Õ©Ø r¥"8Y6¸^\®y®UF'íA°kŽ…W)e¨t5œÕ¬7y£ÀãU¡Ë®0 À €Üy÷·qß¾pŠd8„Á¸2™LÏ2 xúªyN~øxÅ Nâ"2¢úÑÆ•Öˆ>î1 yõÃu`­MÔiâ~]ܧô±ƒNUÒ;Å7«$jAíjëòS-ÚŸ1ÝHTñézc¢¡à˜ŸyéþÙÉúo¦ûóC>mÒ¯N5›úýyý jU¶H‹`ýÚBõˆÏt¤‰»Á¶Æ ê¾#WP²‚£•Ó_P$³N5ÒkÓHÒ«Oû³>ÃP­>¹†û¡MŽe‘àZeÊÞåE©Ca]ßî`HõQHpf,1êý!€¾7¦=Ü¡=å÷‡Ùƒ¶¯ƒ?´•;СéQ!¿ˆÄQ“AŽP}AæL*Öë¬å_>£0MqÖEMÙrµÃ_ÕλLùÖœäò?¤u= v»‚ßMf'`ãoIó¸ÖuW_ó€sÌж9Ú:Ï Ý­+–QÆÁÉÅY¨DL rAÇdÝjÁZ{¹r…/¾KZOZw°y;ÔÆÏÉÒ‡´ý#˜*ïñåsHá4[|›-ú;íxO¡ÑÈÄD.'Çw6n:Õù~zóöãÑ=©h×PäÇ#á]ÉÀöthg*’YŒFvœ$ÛºgÆóIp{ªsÇðæ®£.JáŽ!hª íœKÕH`[d¸Š“á=N>_‰)0)D`è‰ü’ o ë„=0YùZõe¹R;[ÑvÁ½Tžt/»‚_Vlºè ÏÙ¢ Ç:=KÁã*Ãår%Fà(† P£ÆUè–úÓîs_¦±Qœgÿ\Uj@f½»sß3;³³—×'>ÖöúØñ±¶w½†@Ai {O¯ Qi#0GZ•lcH"|¬×Qi?´Rz¨ù’pÔ˜Ëæ(.Å$1 ªš6%Ä}¾Q!°5«¿VïŒÞ™÷yŸyßçÿ{ãSÕ‘©ºèGõáåŠç]ÏÆ\‚_Í¢,IŠ&b5ƒÛxùDî† UᙚĴ¶Hq@&@t´ë•+žø:Ó¾ÄV[‘I¤DŠe3ÑÏ~üõ×_='<\øï£ƒ?? Åc¬jBW%rrGC+íªö4zà±Å;@Ùéf÷pÐ ¤ÖåŸlÊlr¦­C À¹CË-­Éã®ô¥Óû ³JÆqDd½¢u³‡(±žÀð®Þš÷Þz½¨ãir²S”tP©+ìm±†Ð8nþ¶ÏûY„?–pßaïnçúÒ‰÷ÛúcÆ%‰AäbO\îK*Ý kwB>qôuºz:„ãqt[à–‘fDŒðØ%±r¹\`Î^uUZûÑó7¹øsµæ/¢o„-Q9” 0š&áÇ „¡dŒäq Å ÅbL$©Lļ–åÏ•]—ô·×¥º°RxÃQ=+VÜS¼órÅ-®bV©¾/?­ÿ¯ù† HÊ, $…‘‹mŒÜËÙtŸÈ j7ëb(£‚J Eáˆ5Œ ezÅó‰ì½­–ÍK%€%×ϼT{ÚRÆ`ß¡ ƒÕÆpooÙy:º§?¹k¢cÏDdî8ñ‚ìIHE»&Úººü¯ñkœ¦`»µ¸ò¦ýç*¶_«Ÿkˆ^Òbµøùº¸^4ò4]®moä]$Íeð¬Q óqjsvɵ¸ö ‚àÁóüokZ§µèGÚv˜Â³¾ÿãopbº²íj]ü|eëŒÖñA]òÖr¡xš3@ñáhÞ„·qy¿©Þ ¤LiQÐåšøbÒ|‹©»R›Xé<œ¯_ÓÚ»] P- 4yèСGÏÉ" _.|ñèa玘À0d&.a˜tÐoï¯_iWuŽ6Û†Õ“ ®Á`îÈzàÇ€ß=°Œ‡Ätd?բ޵X‡ƒÎ‘õ¶Áe7?”êÝ㛊l$Ëx7P2‚‚Sœ 1Ê‚qØêL““T\–3Ô?ž¤‘á k0iQF›äEbf §i³×÷V‚ëÛuØ$„¾vñxÒuDÌXºlÇ:䞄ڛ´‰Ùû:IàŽr4.ÜF8$Фy‚3áÆc–üYë²aïÅÿRªn¨ž;¶Ê)¹üuVvb 7âqi5Ãz`P’ÌX§H‰¢%¶Á“8TN”¬”"_yCt·×%ê¶âœUK>ËîˆùsR4þª‚g?­ÿËJ#e(C`f™€Ã,ƒq ˜¾l2%)—^ñÌ å³ÖÒÏÄây©è–\ò¹ä;'Wmfi”EHœp®ÅíïOîˆþètüMÝqâ5Ý7ëJGºÞîïù~§“àq*,bø?ÔµMkñËZd².r±&r±.ñg_TwüxB¿òm± 4Мÿ¡ä9߬ìl _¨j½ãëHU|ÏÃ¨Š‘Q0Æl0’­ÿËJ# nb)ø²8œeIPB!i¯¨ê_>kó~j)¹/ÏY ˆåŸ*Õ£–\’ÈTL8P6„ïÙöúØŽ}£­oŒ·íÕ'^P§bûSÑ®QhDö '÷û³Šhd‘FyËÓ<[Óy¡*|µ66Yžô'.UëO¨%PŽåíœtF‹Ü­JLúc×JÛ®h‰„³ÖiDZm…@#SZøBMüYߥ2zι¦%Îháö,`23…QÔ‘žAPðk@èÊ·þ)»Ry,xö2 ç‹\\yŠƒÙ]©mÿ£^{‚¤qÊë){ôœ,²,òχ A%†AÝT^ÿæìÑÀJ»ª­¿Ñ1p.²GÀ5ÖlmVÒM–á€3Õ˜3Ì>Ùèêd®sŒ­s ²›–kÜì“ÍêX‹ebq üáu®wBÎÝšÒ줳Dž7Sb†ES vù! ê/[ÔqMwüxRé} É5² l$ܨ€âœ™€…àøévÛñNþXÂv4á8ÁÊ{“ºcÆÑ„8{;=IKwàDì‰Ë= û¡§Xàl¨˜YŠÂÞã þ.zçÅÜårJéM¥ä¾àû]lÁ3Œ„ÉJò4Æ`àÀ8ÅQ ìz C ÃpáP hÄ‚PN‹”À…#R|É IÓÝ^—¨~!'‹D€.XÓ*ΜÐ(K›ö1ÊÓú¿¬4ROð­1”D ¸Œ£»·^ñÜ*nÛ*îÊ‹4rW.š—ŠHÞ›ÏA…ÀHV!,®‹uŸÿDwœxAMD÷Å÷Ÿjs¤u÷Hò@gã&É ¨O‚¥}WÍŸÑÚ/øþÇ}½Æ6upÿ¸/kCßëë{Ï}¿¯_±çe'1IüLâÄq <*6!‰‡V¾TèhÖnSU‘@(°B'1:i´¶}([÷*¼F¢@õ!>l¢ZÛƒT©HH„&³Àú˺¶®î9¾Ö=ÿßi¹æ^ì¸P½ì]r›¯tN9êU–/êÜæœËþØ ÷¶¿ø¶L‡;g‹ÛzòÃÉÕƒ$+Y–5ü ÓKŸÿ§å±KžhÜórÈh œ'€/‰\zr÷šÚ*RåI‚bA_nÕtägWK¶_ôµÂ;öP#S(É”¯ f¥ïø·yŽXýJ1«²@„Ìð÷ïßJ|õÍÇ/ ™:¸Ø2$nð+9ñ桊•nÕ(Á°y4¬%jÄ¡Jq(d]—5²Q«5¿*<q¬7 Eø¡ e¸*g4´\ã×ÙŽUšGCÜÉ*îdµi¸Öz¬Áx¤^h´ ¯w®Í=^ÇÆëØÑËPÄ:P•z~|?Æx8I¸£ÕB·'ÒE°8)çB„H‡:ÄþvØææ·£ÆþNþ@Tív4gÛ³è„ïR'J_ÌÖ×)lò£ |ÜPK²wÄŠÛ|áM-w¹Z`FËŸ3ºoód]¦¤§d„f2H†fqLOËÑ Gh<%Ò³ $Žã/ôðÑS(ÛÀU&£@G° Ár›Aò(fø%þXÝ=¯9!ä*†ÆD9 $Š6“éÿàKR5ŸÏ…575÷¼âZ”³šsF· ¹+¸>T<…Š$•É2z‚8ÜØoßûþ¶})çÄL¢uÉXô5xoíîkÚiÃ9’ÇØIîÏþVX©WKw\¬l;l»Ržz~<’3îM†L†d8>ðþôR eÂÛô÷`óµ`Wc– !°~“õœoûu_ìü$,)7Ê:{sBù¬¨ÃŽ¡ ±¨µ’ãléÖ ¡®¨V”†®0¬U+¼¼¦eÒ“$ÁÃ|w…‡&Yéû0l;WÞ<íëØ¬ˆ8_D?~îÜÓa䛯þ;vê4“\fè˜mù–ÁµÖáoaû@د1žË£Õ°aóã›\‡6Ùö†¸ŸØ° š­ä-[ön_þ@£ãt#Ü»\ã*#¡¬DÄš¨W×Úß¹vù¯úóŽl.8¶^‹‡´!¯6ìcß«•km¿‰ØãëRÎG52X›•¨µ­er€áQ‚ Ú‘ÄDØàÛ;L}É~‡ß“ Šò.wNbÃr«Ô*'…}~-`Öa«~Ìg¤iH&X•RĽåÖ>Fª²GêmÇjµpÊùñH¬ƒóhÈ~8Ìd±,Fs®—héõíI{|WîýßûøL¤/féë0öÆÄþvöp»Ôß^ðv'Øèa3 ˜*€Œ´Í,7Ç»g¥Âyµd^p/W Ü“‹gÔÒn1‹!1 ’}KR€ê׃A±àSÍsK-½¥ºa_ü[(ýVòMKî^ÎÞÅ+)®ÏLå‹ ç«3åõú„9)åiÒ>b,¢×ôC¢{õqç?¯¹f„uÏI¾3Rábá-Å7/»—Q¹KÍM©2û¦T4§ÏI% ’{^.¾®}.”üA.6aÜz0˜àÀþ m°»So‰–Dëž“ÍÝP#'»zF[ºß‹í‹ F=ÎÀ¶l7lðKå­ã–©@ë_sÊùñH>¬Øº;Û«bÔjã ¼bײÖb X(þS2`­ó»5[®xZþêoú$бÔëw‡²^ÈàiP´d Y’vR—mÍëŽà°{sO~ØBpL&–Eóg«;Ï—¶|\¶ý"´Ç@<ÉÿA#ƒÍÿôE§8+‡î©ÞyÁyË¥H“KŠÄ|ÞþÔ5ljÿR@.µ=Ÿ<Ô<зsÿÅäáŸîØ i„ËSš¿l¾k¿jú,Ü|­bíñã }Zþ½¡h[®ŽÏ% ,Noy9©­ÇvmŠ V¼0R–¼m½K=müWc~ŽÁHØu €ÌÃÿãâòT!€ pÀC{A蘫îîmH²( áká}\¾c8’ µü*ØDЄJÐIäùêÄH#—-Å%&\¢Q4—_g;Óhz«ÖÔY±Zî©uTu%ò»kÔó jåLuÑ›µ›ºÅ •…ÝUÅgcΞ„º7ÃÓ"Ãàà›*O°&ßHr94 ´8bƒ ­Ýu–®jSwµu ÞÒ›0uTö~i^˜ª 'µ2‡k³:]Ã+F€£*‚à”‘#XçpšÒ  ¬(æW+¬}Õ=u¶ÞK_ÕšãÇRúÊ ;·ZkE±8€(J4ÅMÇ[W‹ ̯¦¤S»ùÓíÊÉÝÚÏöP'ZÔÓ/oÿ€„{}7v¢ÙqòEp*³ƒ¦Jà ´H QÆ_æ´âý\)]üãꪹÀ‚“›1\Ç@Ò|* 8Ê`¦¼¼¢í¦9²œiÑ>šï½#zçÙØœàɈžYÉ?/Ó¼Z̶±ðkF¶-ñö»2t7ÿ´â–]i18ůk‘%¡ì¶É1Fò§Å² 5o\Ì®…“E10¢E¦¤È¸â[ìÙ€ŒgN°§eó¬T8¬ù¦ÅÀmÏÁ“kL.|(f”Â9“{N*›Êÿ(ù/Hö_ûœSÊîê®QÝ1%ÙÆ´àŒ¸i^· –yÑ?·Fô Üy‡ì“I#Emüâm/«¡8¥ ,½Er9‚¡HÁ!°‘ðb“£4;B"ŒÃ‰ßEZçûË’×Ê›¯ÅZãÿós»MÞ %/—7mu  Iâ$ŠšU=K///ÿ4?þ÷4²ü7’ˆu‘cdŸ`}³Aê®´ $VË=­½õEµÖ³[`X±¿Ê|®FØBT˜:ªmzwÖY=·If4q#ÇçÈGjŠÞxÞvöÙü—7#N‰2â,Fé\íç•…=õÖÞZ½kËJdK׿A#_@ÈZ¡¶Æ Ùöw€Î-ø–]Ü_Åý(JV“K0†Äˆ&«¥³ f±tÔ˜;ÿïhDï¯(8ÛÈÛEŒ€5I’4­Üfy­mµ@>ž’_kÓOíÑŽ¥ à/I¤c«F;_&ýx›ræEÈBʉ6ýd»åDûúB#I@J,i8Æ™ïê>èqs¼Zê*ö¤÷´ÒŒPV ‚ç2$CÒ¬{ ù›×@ —ÕðŸ•ò¦$#eqbZóAØ€f:%:ï¨Î;÷„î›’}S‚ç¦É{Cñ¤åZ’ª¤A##TaÌVŒo¡ø.Ú¼(ùÒ\É}Á»ÈúÇdï„ÿ…oR(…ã+‚¶aji.ÆRõ çA пec¢c”÷n£…8+x¦Á(%_O¿ ÇøÐ‡¬·•Vì4ÅÒðzäˆÇòTË© v‘~|Èïšý÷ùð Þ>ïŸåœ÷YwFö“ ¶9AK• U˜ N¨á¸w„U‹¿Zõ É0-y®š}Û 62R8+ ÌŽàæ_î>ºB#ÐÙû“᤭㫫7•Ýð œKîh}©cï‘mŽo„‡KÀvà'Åñ›‘¶áÖk‘ä`<¹æøñ„†ÂMƒá–ñèÞ÷Ãͯ8j“šçYT/çô×ÕøÛ¾íC±=Gr$”òï€~ýq´éiã_Ù²÷ÃЮ+åmŸDÛ.ù¾s¼¤¦]÷4pÊß©¯³Ø¨®3À¯U¥°Ç³ÜåÜsî¾ÎŒ=6c{¼Ž‡±Ç3Þm ”¦i”âe6CÒ>´„Å• ‘ÚI(‚±=¶!$©ª¾4­RACг™:@0l˜%UŸxéïXBm*¢F„zõktç>œ{ιçüÿw(q"¬@ØÅœH‘Ƴ„°ƒáç? §?‰ôœŽõžBt?ñy¨ë¾IŒ5%O·lhQòL ó«²V^(XhB@¹À¿cÚŠ#z[ }  2%# ÙZamÔŠöáR§sXg!ÒhIÍã°EWPÎS£TaþÈßÔjï(!˜®/¤Hì‚^vO­žÉ^±j.I5óÁnQÕ]¬É ]X¤8Q"Á+6>’·Ut.Ö~)†‚ó+¦ôòÈ5¬²{fݤYs”÷¯Æ‚NÛܬ°pB$¢ÌÊËKrI4d¢Ëž™çñŠž×Ã7¼5—ÍÀtAÕ©D¢ƒå { ˜µÁgÑÄp¶ÚÏÖú\ ¯^=ã©;Æ—æHv…!ÅåóꡞM£ÉþLÏæ“t½òn¢jú"Nþ/b8ÕŸéÝr¤wëÑž­0„®M™tÿ««»á£À>€™î” Î6l8K}é=ßðôùñu-4Ç'Ó—jS—Ã}'ÂÝç"ésÑÔGm‰©pâTktûlm|¼>þ~å³Ö¾8ÖÚ÷mÛ¿^ˆ+õ}S‘ÔD¨{¢¶w,–kHŽÇÒ¿_ñÂkÖõ¾Ê°æ1yÛÁœËñJQÝßãÍ©s±äd]ÏßSOzÎÕ÷NESãMÉOS?ñVB`R#D£ûÖ»xÚãâEXZ!@`ã+x7?î½EÀï¢Fàp¢2$ ¥‚ÍÜ×Y”iµÞiÖ‡ÚŠ‡Û½[k–&Òì%r¦¡h¨Ó÷öª§Ïÿ k Ã·)Jsy" æåú2cwÒx3k*Ðöö{RæžTÁŸY{7 à¡òfêIkÄÜ·Ñx­·à 殄¼7M‚E¤{šA¬c;ã¹gDá¸:§VÜTkæ…Êi+k y ÍèU#B@âYÞŽ”<Âð¼J±‡‘Vyçxñ}¥ô²œu‡n ¡›ÆŠkzÙ¬TxKñÏÁZuWßRóVxܬõó¬ŠÞ… ‡2ý=™ó‰Ü ¹êšQ9ã-»©•ÝPÊÿ)„®[åóbð”2D–w0"6tJË·k–Ëñ¼î¹©F¯©%sJ0—Ïå‰dÚxãˆádWŠž"Aø·,ÓÀü@Ñ*ËÃ61( :É¥sž>¬y¯û‚ÐIÀ[?²A* †bÀü’ Òˆ–h4C\ŒÌAúÃS,f8ƒrüI¬ºCªî‹%ÈFà(†y¸ÎI·V2ÉÆ268£ÉœDÛʼn<¢™L4ñßer:WHfÅÀ´7pI¯˜—+á Æ&|á·¹¢ Ó”-gòCE¬a™¡Uf9"Ý  Ï"Ú@ÔK¼u^­½«…?3K¯5ðÕ®Ëw<ÑA”D”µ³û}ÉÁš§ç2D€“Ìñ0:Vw/ÁŒi·µ+肺O—\WJfÜåÛyÇ8! K™ ÍñœÈ:>$UÙj?[ës^®¹noé+®J‘ˆ*¹SCÒó0KLÖ'OE{Çëz·úˆ‹’^dñ>|øÍöøïëÕ¿b¤Ò˜œ›cž•æ@³g0k±FÁ!-æp›1ÜQ>°ÎÝ }´T Škä‚EÛšŠ÷¯]þR¤!†·—$W¸G;¼ƒßïÝG;üÛ;l¢ò eòÞCÿ"¾Îc£¸Î€ÿ[¥ªJb{ç~ÇÜ3;³»^`c¯½^{/øØ€ƒCi£6-x×^¯¹ªª‘€RZµRiÎFLlsµô RS©×_…Ƙ’–Ë6;´4U*¨ßb UH¤AZäѧÕÛÕ›7O3ß÷ûR›àè2ÐÈHÃ]eé']·b´yDw_»ýn«Á³PÄ=¦Xz`EÕ±e¾áïHgåH»K\…%°ªä㫆»Ñ¶ò‘eÁ}/Í;? ÿPÝî ª`@éÁÄÎu»Ûû­Ÿ®-” ì·³}GH î̾>sŠìÈi{rÝkUþwrú÷^-Q%—ÇŠ$•cχJÔÙpÛª´BvdÒª/ F&œÊ¼sĦÕy‰‡]54]ä9„G±ˆ04k&Èy¡(eé{œ…±a1ÑÉ@ÓŠÈ”¾­Õ]7ê¯ûOY‹§ôðjÊaÔMj¡ioÕ¯ÌZ¢ˆ– ‚à†H¡ñ©æDKä½À°°Sª JÖ ¶Ð‹£ dö5Îû‘¿yÂ[›w=­ÕÎ:M—­†Ãb¹¥0_KJtµ„è62)`Ï-I_î‘ Nõ &œ’àÙ V`Zm¼§†§­|iž6£çph¡ÉÉlà‡*Ž‚tR “!2‘`gU}¢YŒŒH9O(µ·ìؿ،Ruûø;ºËQ¢@æ¡“¿;â9®Ujþ‚iDmœt#·Õšš‰}zÍò‚)ah?£vùÞÜÆc¹­G{7˼~8½ "?˜of|ÎíÛ q$»– “ä[“ Cˆá‘Àî‹®<ÕÒ>Ñ&ùÌ«êÓÆùÖø¼ɾ³8õíªhoeè‰WÇ’«ÎEÓg¢éókO´õðdTgûÇâëžvþ¿¶õŽ-I%{Ï&Ò[³]‘9Ó’팷fÇcéñȪ ÑÌ•æÁóÍ'›VŸêü]ªÿƒÖÕWÚ×Á.´å.%ûNžõÌ·"‘>ÏŒ5÷kØß°Rö°”bY@Û¶m{dŒû÷ïÿçáñàÁƒÏÖÈŠ—z°ˆ!•a­¤t{Ê7ºª¼ï`G¡ªgÕ®Eû;Û‘e¡¡WÔå•,å ¢—È/`Y*Q…ç ­wˆ¬È¸+­²Ýû»ýï§*vuíåÇhšPúrMåÈò²áî|9~y¼ßù„€@æ(2Ç’ÀP—o‡H°^¤˜ÔPûêàBæáeþŸ÷T¼—”º¼Pû gÓf«âàR÷H .þ™w~<¾ŸCß3ÃŒŒ¥ýo ˜»ÖJ08ÂùIùžõyìÎwlþ'…¹+òqw–¾»¦ÂEòòÈB$§ê³¾¶›jõ”[wÝ©»£5\„¡À*ÛTºê„>õ¶Õkâ?/ ¾‡ŠUt0:¡²£" гa¥ø‹2»J·Ž£E×Hd¿YÚtË Ý°?Ñ÷Œ†?[Mº(8È+ê¾&j:#E0þ›¯yV¯¹êV]ó‡&½Ñõ×ôXLW {â5BN‘8 B­ÂÎhÓv|ÆžUc&T^§Hóq" ˆA", ÞU ,–`zq1œ2À"°^ªJ<–±, Ì/qè®»èF7ªAçI g (/ø¸…"!CcäïKå_HZˆ‚†˜ãvã„Û<ãþZLA³s^Qt!³ŒGMŽèˆr²Œ1%YdÌP„ÌÉ2Ö5XAÑ)obÊiº«UÝqë'åšYËoÈâJ‰a™ç]Ù ’j0¬V‘ÅVEyÃZ´Ù®n–uX<¼§ˆÐç0rXX?aþ¤ÔÞ³wÕÐtÆHl1J‰\ÂÑÏ©§¸% Ë ŽŒ˜&eZN“J’À+_‹ð 9<X2ˆ•³È½æ ½ÎÛ"ð“L AãýVjþB=Ÿ3Jã”™0ªîØ‘›j² ó”Ë7hÐ?nþZæÈš7¬Þø³¾-Ã飙Mdz[çŸ3õm~4“í{ýHfó±þ-K^+Ó)b~Í¢èÉdæãDîd2=ïüx,®„WAÅ?—̶.f‹¡Gø}ô›Ÿ$Ö_H\J œMæND¾n#Dx±ìéÆ5O;ÿåØê ñôXlÕéÖÌx[ßéxúl,s)Þ¥¼¹@òakþóRË ìÏß›²ùh[ ¿\K^¯†³[ssdz¦q.™OdN·ô_hÉ}ï5ò‹" žžž9„ü_üïÑKªTEÅEÄò÷¯p--é Ž¬zz‡–‡;‘óPgùî¥B»É«,á$†¶}œ-3feI£Ø„ mXðÅ*ïŠEJÄyÆhµº5ï­,=ð¢ÿ@Êw°+0²È4§‘ÒƒO¼ôP×\<É\Јó²%$ ÷•jk[Wàû©àW¬Ê"x ˆd¯û´»#ùËÁ%æEÙ—k¸ü©JUøì݃æÎï[SA`{VÙ• ìYØð•Æä`_ƒ…›ÿIòÑÞîóî]üa2<ÒDƒýƒQ;å‹Bz¿îÖL8õ ‘«nø–U0Ü´ê¯xC7Ñi3¶ûbˆ§b‰+’ ¨I’äå2†Å U"/-B+rå²¼A œÒ"ÿ²b·­Úõø-»ñ¿Ä—kl×Ç¿ö°»óºsçÞ™¹óÜ]{müXïÛë]{wÍæ1ТªiÒ¦µ½^c‚Ôª­x“¨©E q%¥¿ iT·ª’´$„W!ƒŸ ãJ$QU„zLÕ~@¢ ’©WgGG»š{Ï̽÷üÿ‰²ä•òüZÍÿê‘Àa™¬ØŠøŽŸÕÓ#0Õ5§~ÆH¼ï$t@ŒuG%bi‡eÿ.ûÓWƒ‰,è¾D" — ÍD" Œ£ 0eUü)ûñ, ÅUy‰é•½<àŠnAÁ²þ’º¡7L±ô1}Q_¶Y m7+~¨•3ÉÝ~ζÁöürÕÚ¦†¶¸Õ[ŒÊŸ™eÛ©ó• ñ#ZD <ã‰"ñ~ÀEã°¨QÂTi­¢oV‚ëuf@`´”1€Æ'ØH}ÒVyé[¤úRýx0þ¹]ó¥›»@ÒY,ÃCÙ" p*tмaMr#³Fö’R}KMΘùßè!¦xUÉ”ZÈ@²÷§šsɨŸ&f´Ä‰`n5†ÿ`3AWƒ<ˆ˜áñ Oáú¯XÓˆ›yÕ,Ë‹ªÈ’cfìªÓ8«¦¦•ðHYòä²$ì¨H¸‹q:O( @<à1›¯ñçkN°E¯“Nl–å¶k•2òQI‚ÙËö—¶½Û9§ã]Û†Šsj¾à˜ñ j†‚:\Ú•‚K;;·¾úÌ& –!£´áÿ4[¼’é>^è\püxFòŸå:?Zѵ¶*Æ©24ä=ñu's='b?9ÐøƒžšÆzæ.F]'VGcÏ>êø§ò§  õÃË{κÏäŠg›»O7wŸÏ•KÎ6Ï6œÎ—>ɶÿµ±ýDséBºãr¦ëd¾8’ë¹ØTú°Ð~2Û~®é±¿‡ó…¹+ÒÙlñxc)„5EU4 WWWü3 ÿçýÏÿ¦Eš»ßÀ²ÂeCß·‡Z€F}«æK=+Û–õ·ú—;‡VÖô­5K‘@[-I•Ë` yÅ”˜+‰Ð‘$• ¢è2—×òpA‘I*âÖ:¡ý+*úÚBýmåƒOpæ\]6Ðz?¢Ú÷ÙP¤¼oõ¿rí—)Uòè2q0ò¨^0FÃWp90}ªnáÈïÖV•¬éüC+?ò|½M8‰ªÙ…¤³wÙÛ]±ûùù¢}_OàåÎoU¨úÊDÙ+]ìÍÿ‰*v÷ÈûºÍçV1;òP©I Üaù zí¬?yͬ´â׬$ˆÅ¸=o42£¦oÛÙ«f䦛u3[™VË‘°DY©T@d½Há™"’¬p¢+0Š …X°[¯ïiª½ï¯ºmÖM¸Í×캯ìÚ/ôª#f\Ç¢#HŽÈ'Èc‰ß¤ø'XÕ`tÚŒO±Ô$‹¾ì¯ây%2S8 çÝÚ/ir‰ÝÔkî 6D/‘Éçƒj*@B"ùã·ŒÌM+1«¶|h.(d YbRÙBH¤”í¡òS”ž %¾Ö#zxÔJ9é«VømV|Ð!áÔ«ÒœUeß‹¨jÒh·ê§Õص@bܨ›ÕêÆÜèví1Ѱ$cÎáà¼0¯®ä0VïXùKNäŽÕxT­MŠ’. "ñEïÓŽáón Tß0Ò£dxÒNï6«^ïb˜–hð°’Fý2ÿ.«¿m€0gœèx0qhÍL¿D*‘¼ÔGA•ô*ÁP'©‹.9¹‹¡š)§þ¢E-/Àr…ŠQAÄHjS¬–5Oû›ÆXä6K]7ޏ‘?iÕçÊR³fò‹Œb7ø×j,Ä.b!Õgp2@ )#MB²É¿ÇjæküùÚŸãNn”ÕTÔMÚáQ#ý©½BÑE"ŠÁHß×þ‹?”v¦õì 9Ô¾eÁ1ãÆï;·îØ:оùíîýÅ­Püáž] –v„ —вŠ“ÄÙâHºô—ÅÇâxóÏä:€vm‘ QŠÁ°êh²¼H—TNEÎ!òpýâQ§h*œnêü[¡t¦©ëLcq¸ÐŠ4û̯ªrß±CõŽÓà8ë­Ê_W䥟ýdeé\¾ôq¡ãlCû…|÷‡ßî†A.fÿ{kê8uæ»ÎeŠçó›bV€2h„Rz÷î݇QÀɽ{÷ ¹÷ŸäÃÃÃÐd(Ò5¡Ól ¬Xãµ¶ý£Ž,TTj«{«¥v¡n°¥ìà*ÿкøo¿GZ]°Z`Í l D÷‚éE^×'‰aìîÊT¾³&зrÙÕ¡ƒ«ýƒ F•ýk½ -þ¾ÖŠ>@©VóP‹©“ Š}ˆ£ºi¿wƒÑ[*}ã|QùÆkO»qXCêäXepûsnïF»·‹í-ot™{J8½]Á×JFoq¾æµ_Ûh½ÙÃöuÚÕAÎ’(Cø‰!˜·®þ0ïiE'ƒÉ ; Šùy0:eÇÆ­ÈÝò§i …UòŠ §)Š%URd…˜<0Š¡ù%¢ÁK èMkÙ +yÝß0â$@§&ŒÔ*ÙíˆI–‰(7xž$¦ç”‘™ÒÒvzÊŸšÑ£ª¤QåEYT&S²A±§ìÈÜu7<­§&­ ÆX•0Á²) Š58!Œ_úg¥ö²¿n4˜œÑÆÌÔ ô2VrœW!À ¯c†h€`˜ë¶Y?æ&ÆXzÔŽ½§‡0ð•ˆÁ‰ÌåÞ¦=ô=1"1(ð¯(²ºXû÷õúÛäuÇüO˜¸äâçyÎyîw?¶ãĉq.Žãø–ÄÄ´2Ä%;†´ªV@¬ƒñ¢U›Ò®*%Ĺë¶¾ë^lªÖr+$] ]BÈ•4- M‚ö{©/Ðò"j²H³Ž¢Ç‘}n>ç|?‡*ܰa\+˜ýßIÙ;¡ïhîO{ ÁDј"ù ¢wˆê´™Ö &µü‡JyTt„IhDRð™=Xº§UŽÛüð\ᄵô¡]Skééð9!““ M¬ï}ÿ–ÝÃzþ¸\‘ÎlHÃaÓr`$+A½)»ÆÕÒ)Ù3«}+ƒ¦¼³Fá¿Ï]£pDòÌþaÕòœ2|0dzaø0 00!ð “³Rõ¯ÔúœS oÛýÔ²»Jѵ`Z)Ú+IaŽ'[+w\<ðZ_ë±®–_~Üòúïö]sfüÈ’ŠÙUd\‘ Núkï„ykÎÊ›êëÔ<Ž(@5Aй‰a0°gŠYp¹…æÈ¶¼à`yhß‚¿`†/Bf‚ߪ9dâa‰úËš®E[FüÍ×*Ÿ'"/ÿ>°gwQˆä cŽ1w™YhvQþû £7ÊÛFB­Ã¥û¯on¼h¼±9q¥|Õ52‰_­0[Ý 6ýÔȃ`LB¿zþìù³ùï@È¢:–z]¾|4Âc Nqg¶µ'–›Úî<3ú«W;mó»jrÎnu|3Î×[»w9»~æx·ž=á_r¥‡lƒŸtÈR&‰}²|¡a¹õj•:¹g;Ë1³õWk©Zk_ƒÐ_}n‡–ð¯³[ˆŒõ M"µŠX­‡ƒ®Þy JMmq÷×ç¤böÞUŸ‡¥Jvw]No=µúàì«Íî‰9Sæÿ‘CÁ,‹Šè8±ÏèH* £=¾R*:`›ìºÜÿ ‘A8Tµ1&ý6‘óNÂy&)u4;NÇm æýY+Óè¢F¬gÒ‰] + 4†¥¸Bœy=»tµ52)ë~ðì컫*ièÞïÄèßÅP˜¿WÔ Á²žÛHÐ*4`9’ΔH™>ÐYü‘R0±PÛ˜Õ7§”ÜS|'$ƒ¥ÒX$ËkXBˆÝø6ý@~mO+ùŸê[à`‘I’D$±‚ÉóJÁRI‚¦Xð‘‹Å7?ÄߨµhN(”}“ÖÂ1¹¤aÎFš(¨HF§ÄúwrÉ¢F¦äÀ¸î]¶F„M<² ,AÛ0ö…áÐÕ˜¼A.ß×ý ‘I=8¢mú›”‡XfQ#pD/j¤^P&5S#÷â1)äaD ` FµAè”râo8×QVþ•¨d¬¯ Ö×8ë+’|œw¨ì˜hSæÅ[fÝ ÞÓÜ3ª÷1[YßfH•`a©l¤PG™²´‹föÒ¶“RîÁó@ªÒ}åÀ´=0§Â¤ygï?%?üÐKid¥ê_±õ©xîj%ÓJpJ)žÒ=Ózñ{JžŒ ›‰Êùà—ZŽuµ¹Ôr¼¯éÿA#‡7702-"œÈ+½]Ö:X¶öüx¡¼š]†H.$MA?  .,$U[1Ë#Rá˜m†ëOìj¤éó²¦[Ñäõµ°ÉÉp#”Å·ÿ=åËš®öÝÞr¾;´¹í¥{vJ.--S„½ƒ`RÀ,À~’”HdlD•¢?mm‹&¯”¿ E7+«=ƒáP<|±ð|ÀåS(, 4ò×?ÿ4ò| óóó/Øc~áõÃÛÇ···ÃN‡;XÎ~ÐgKÕ@‚Fìý«ž¶Zo šs¦ª³.ÆäKUBo¥­{‹ûl•÷lÌÝUŸ›Ú¡¾t );s³~4ºj–[¿íÃJw÷öÜžFoÞ[¥öD$ŽTµ7j¨±÷Ô¹ßßî}c»úŠ?óe¯ÚÙ÷þwßN`˜œªÌê«s¦êl窜kC³œ¯^ÐHÍ¢FLŸtÅœí[, dâçZ]§Ê õL«ýôŠ©Àõî!å¨Âæg TNT,4¤ŒZÎz;¡v&oų;Ûlï$ìí ¡cŤŸNj ¡¾D° ‰ôQ2œÃ«­‘ûb`\ Ψ¡o”à¨ê»«C¬Ü—ŠgÔ‚YÝû-¤¹Bä¢IAÜzL§Ñ,+b6]"xšæ>ƒ!ñ:8dFôNë%ÓªwTó~n ä3(ÐH` K«˜#Pf…ïÙ6ß±Ϫž×57"ÒdóƒŒC˜²„1¾­‡—Òœon´¥1kù¤µhTËŸ•S’oJ/˜ÑC!NÄ O#,# sð’ŠHphdB÷‚Ffä °d¹ù4BÁ•@dhVdÁ‡ãŠsÜZ8¡oÓ2ÌUp\Ë6|pS3ÁDÑ F 8$·qÒ¸LÛJ®>HP–@f9³¯O1 â øK¤‹Ì/Ñ"tq„•DëyèO"ÉÂÈðK¢±}•Uhþ@|ð-ÎLP0â±ÀúH È#DPX!rˆŒFQí’7 %Ïù²{0·ZÑ#ÙH[J#+UÿJ­Ï{jþœUýЫQÝž¼¥„ÂÐkž2`vðéÝmØ{´;y¼/q¼;qlÍ9ñ#KOüÈ{»A–™+Ÿ¦£’1Xžø²,¾æüx¡t…_"±Å¼G ŠÎÈ´Y`w’Q-çpN°ÃSóIÉϯEâŸE¯„‡+’#‘äÍŠ8ä5€äz¤ žÍJBM_W$—ªÿ«hr¸,þieÓÍpóÕhkƒ”ûŽ¢5Ô‡Ð$ wFØ>Ö ÓÉp¯Ùë.¹i¾Þw¥ªe8 _âõäÉ“gÏL²œ:u n(p dqýºÒžªÊê®8ú–þË-öz×…mÙ½UÚ¹°Ñ_‘uq«³g«;U«ŸÛ¢_¬a?ªä/ý‡úzmêºãþÿþkIìû:÷ý:÷úí$8äaÇñDZ“Øy–±Eˆµy9Í£Ú¦…‚´IÓ´–- ‰IBJG7uÒ&UÕ˜¶µ€Jy¤ƒ HHp¢ý±Û~†)š*ålahÒÉÕ‘—Ï9ßÏÛ&ìÇ‹&Ú¼Ùôšµó‹VçÑdéØÖ¢©-в;›pOÖ¹F’Òdž¨÷L¥ŠN4x³)}Çhº8»Å õ‰z÷x­w¬¡x´Ùs¼Õ;ÕjŸL=+¸ÇSÞñ&'°êDÊ5^Ï’‘Œ¸QcX†Gl]…ëð€4”¸õ­— ¼?î.9ú]~ Åâ3YŠQ­H±06 w5,²ÿàeãÝA| Ûû΀m¨Ïî_¯~]ÃêpFÅòš4$sįd?äûÓÖH>Ðqø¶-º`ß´UÍÛ‚Kö dʼ£tÖ¾)ŸJà¯jì/FbF ýšõ‚h#ïAdÈ *Équ7kóßVýwõÐmѱl_rZ8 œ/±2-"Ž—‘õC˜®^4Ëj8!Ú†d n4FBÁ^Ùö@‹®ªAz*Œ””ô;f|ɨ¼i–/™áE²¯lÙŒ%,°’H³!0 GK(ÐȲþx:ÿ©F>’7©\~0~¸ñ)ˆÙ©oäMó/êU‹ù5,»åŽbŠ€48.¯…bšyyN‹À·sºÿc©‚ `»`YL’F½}7Pdºw6óú3çÄY¦2{>èÞçÔM@)ϳn†;SÓq9öìùñµòap[B2¿møz‹Â5v/aUâU~ë\"ó§pf6òÊ•DßÙdb>²¦úc]?|r.Öy!‘O®FWmÿB¬ëZü•Oj;®ÅûŽû·hâ9™a±,X-ß)®ÊÛ/× \‰ž oï(€CHYDJgéŸoÞBø¬>3ížyúë6³9b]Nô‚FÞ‹µëpv9A‘ä]¯íü(ãÑßWàñèÑ£•úÇáùÄ!O¾jkk“bižæ‰âƒÍîlëDÚ“mqN¬9ý×Z|£)ûHÒ}ªÕ1Ùì}·É÷Vʹ+R´+¾iwÒu¨Á˜1ßά— œGmz¼o÷¹¸ƒ¬-cX3ËópÛ Ä;uùÕ6óÈ€q¨×1< Z·~ñPFx}«A¢B™n8fÖ_ÖO[#‹Ø[«˜3*¯›P WÝÕü ZÅ-³j ïkÁ;j`^÷ßÂÁ%z€#G…b™¥ŠsRˆä)ÐâD7IBL,àÀ}¥*9³rI žÑƒ6±Þïd$H´Œx PÑGë_i5Ÿj%˜`4*ÍËœbe SØð‰QqO®¦ƒŸAÐi¡ŽWïj±;zùœ½2g„îá}Ó2Ž‚RD$I5Â2éÂR³8¯‘9 Ó)KÖ¬µ CלŠØ¬J²põ푊oåO4’ÃU9=œÓËæ]QlAO4ÿ¹¢‘Y5¼`¬®Z¤üò¬Æ[uƒ´+¤Ë‹x°'H¢N)É õ|Ö+öª¯Œèo´ÊVÖ%æ9°„•€ y0ˆ à¡ õ<)ÓϧeöKG4gDîk!ø¥VÓÈzµ¿^û3§”/˜Áë¶@û—”²E#0ïˆQ"mÕ8¶À|ªcú¥Ý?ëÚÿ~÷Ó]ÿ÷9Ù»÷tçqŸ¶= Ûž&ÇÂ[/F»ž9?¾VnÆþxùJ´w&9¸·¤†# UŠÚW\û»Tæ·µŸÕt^¬É\HôN \¨ïûbs×ÅpÇÕšÞËñÌÙx×¹ºÌçµ=«µ¾¦ëR¤óóú¾™êžíJ‰ @§¬Bo–$>Š¿t~s×õpæF¤zù8Ù9Tžæ «* $YØï ^ÜÜûE¬ðs)Öù?ÓÈ¥Ú ÔßaX$¢™¶–VÐÈ£¿=\ÈŠ=V*ÿ^Åb2 FŒÜ£mÞñ„{ª1¯‘lêi§­íT“m²©,Ûîy-&„4S oadRb­Ú«!ïÛŠ·–·ÂHì“ÉÙ†5kç­íb¡F°"'*4%r„U²²…6òrÌf¶û´ž2}oÈ1”²¶àl[ñÈVûx‹>Õ`L§S-EÙVÏX£c¼þÙi¤Á;’rOn‡xÆj]ï7WŒl“|èQ&¨Bwý¨Ó<Ø‹ÀÓ|g}HE9Ø#âÝÅû}‡¿§7G9A ” ‘$N—ÔmµE?ÉØšÑŽö¯W¿ú;=bƒ_aVTžÙ¯zçÍ袼éikdÞ,¿Ë [szå­zA«º¦UÞ7c÷åȼºfVß´U/Áœ¸a«üÒS™3S!ÞÚA@" w&\š ZN@eÑæŸ•Jïáø‹ù£5†—‘a9I€a.ãÄ›ŠC¢8…C Aaó Ó*зÌjHöÕ4±ù×Ј¼¢‘=¸dæ5rG 'xU~¬ñ!ŽåAMsFð®^Ñȼ^±VœV6ê,)‚Fh†ç˜ ´¿Gô,àrHÞÅ.ÃÎÚCš…YÑüœ›@#z4’sÏÊU’@À‡ü“ú:âºãþw¥ªMÁöîÜ÷={±kã5»ë=l¯÷¶Íb—# šÒ¼ë]¯TU%‚¢ôPK)uI‰š”ØølP+Ô?ÚªR޶¨%>jlSc>±¹¢„?ŠÊÑßâ¤U‘\ e]ÔÑûc4š}oöÍoÞ÷óàŽb9œþ ôÉ0nIBõ4¡ðxŠåI\¢h …‡¤!ýEaF\4U®H›æx÷=q^ðS6îcšÿºšUQ™Eg à„˜0 Eሑy¦“s. ÁÛ¢ÂâYM#…ê¿Põy]ò]1ûçtï¼âY–Ý`’I“Y Öá¼€Œ*‹#øv?6õró‹gR/>}N|ºÖ›=2°÷`6¶ Á)ô[å¡áÚôSçÇcííDj"”½ÊŽD³g=;O87wywœµ^ò¥Æãmïon{Ëûl›=°:Úí·Ý_¬o §/T7‡Z ¾ÏÅÓƒuYHðÕúŒçÃ}4’®Í”a4ì\d”ˆ²æ?…÷ Õ·‚dFà·±ì0ÜœhüìÔ&Œ€oÇa ÎÅrù §G£k>oŸhÎÇ‚-Žd`a$I’cØšªjÐÈÃGÖ¸ÿþÃÿ<<:þuýîÝ»°bMŒX*ê=[o†-ý ÖÎ-N¯yÚýqgß.û7B¸E×—H(-ñRލÁöÝ&½£IÜQÆ?WîøùVË[ê@òIûçŽ$q·QIÊ,ÂBmÓ£k1*£M!4a” £ˆ®ã¨ušƒY_+ëÃö_ìbzãbWÜÙ¿½ìt“­kÍU¶Z3õÖ•Jš{¶™{=õZ_ÃÆŽœDÀz-BÕ•jzG< ¼ÚjéhÕNLÚÑýF›t2g;–1ËbIͲLBP"sP0RƇ=–ï·Ø-Ô¸æãͪ,A4`fÃ÷Ôš9½jAZs,¨îYÝ}M|$‡.«Á×L¿§ÚÎ[¢ôà)KÕ´Å?£zç€dY÷¿£‡,(Ab¬ Æ "B¬3«U.K¾ë¼‚ãªÉ•߯Ê_‰å&œæ&-/–`ä¨à©g8‘`¡¡ÜIJ°¡ô¼’}Q­ú/Ñq^\V‹2¤¿kAöÏkUõ+H4"âàÍÈÕã\—‚hOª‘3r9‡—„=ƒF‚ä¼ Ø¯)îE¹n˜U¼óZͬºiR÷ÉE?ÒE+id„,™¼WÅ`M(…ÿˆ'I† pÒ´˜Tβç’ÅwUÉ¿‘›rí5%8§Ô,ʵ‹rÍU1°Ä>ª®È.˜áY³N@‰78Œ>¯ƒâ|ŷŲ¯QæRx3 <^ÌâÖ°¶è³½¦¤Ð¼T9mÝ´šF Õ¡ê^Tà ˜ê¹bªOÎÉ•×ïQÎ¥—CY(zWuò—ÍGº3Ò/¸Ï*¢-£«+ë/µÍ f€alÈ©,´¿â¨Ÿˆç.„Z.SãÁ44àÍXmúb$ûú¦&¶¤„ãø¬úƒ_å@ãñÿ…FÎGÓCáô_CiàŒ[Á)ðíã(¦Hò?Üt«5½'æìjÒOoÓz’›úê…Ψù;õ°…Ä(\¤i)P±ŸhW:2ægåW Ch¥?i·ËH'²ìÏr扮R²LDM’ I¬£Œ˜(Š­Å ¢Ïj\ê›æõ¨ H¸J]V¢Ë:ä¬s­5²$y.kù<ý€ ýšs»x#‹~öjY0»A)Šë–è¾-TÞ’üsj`ÊØ+Ë4ŠÊ¤j¤”*–qRaøT‚¤¸É{—xߌÉ;iª¸«F%@È-š• âÊÀaë9C.1 NѵŽâÕˆÂZ͉gÄ%#™!,¿mh¾È&¢­Ã‘–±hv¼ªyµþóÂñîŒå:+·˜á©"ÂxƳg(–Œ6%ZÞ¥ $Z†"ÍÃÑÔP8ËðŒ(Âash,Ò6KUe­ça<Ø¿™e§ƒm>ÙÂÀû _Z¼öðÁÃÕŽ“ÜÿÇ=¸ç½wÞ…õCD…ÂÉíº²¯»AïݼáÔf{w²P©jïlpt'ͧÐgY_“µ³ÞÖY•hù+ÛO“YNé'’úX÷ °Ñ(;¹»$Âü“øzmêºãþïþ¨X!‰íû>÷ýöµ'qâ<œÄ؉C;*íįè¤ñŒM´R×mPBtE…8`›Ô!R+M¢Ó6• ´¬kᑄ׫*þ(lû™üÃ?ù•(Ö‘umÝ{Îù_ßßçHbHVÙVëʵº‡»^v\OWér£ÈÎQ$#PNÃÕ^cµ™FƒÃ4yšÅ‹HœEÜ,+R,ÂYŠ"m•»:œ'»Ôá&Ïp›y<á<¾¦øèª¥Òˆ{(¦Ÿ\Sz´Ë;¸Z:ÞâZ­¯«”i^%Y„‘Lw«>/âÜ¡ŒÙŸqõg_¶ú[û³Ò¡uÚ9Ð+Êšý=}Û”,:”qèe¦µþ¬ûΡ|ÙÂH¶+ìK­§j=…P’pJ'9‘B4BâOÚKÞÍèGÞ¤ú“|:?«ƒY¹?µàÐ{=¶Š})õÈvã½´u ¦¡ÞŠZ¼ˆ`EB¶ÓŽ}²ë±X5­UBIZlÌè•×eï#-úw!°’ЍB’$¡¬ûxûÑ9&æ¤èC¹yR޾/•%DV$ó´ÅXŠ©. bV´ìm}A5ýI¨@ö×<â€Y “Š#Ž`i’P(Îd`;xõk%<©TL9kg Ö¨¨8Sîª¯Ô ¦°ˆÒZTH‰¤xƒâ;‘0«4>Pü÷Lÿ ¥jÒ Ì¨¾{rÃ*$»e‚q˜›Úá1­ÖB·uÿc¡|Z͉µ§%Ÿ†Øž%9@bì$Í©²kJÝ´U}S­¼g„€U³jùWõŒâ?%yiW(4Å‘8ÀÀœü†«} zo›5szãœu+qÇ'rè¶ÉÌZ ÿæ|¥àgÎÈO”„Ùé„jØ•¶ÝК!Ô gD€ BA41!ì«ê±ï[`+åPH’ Y™d­Þ’Ëîú}jé9ñÛñÔnHq|Ë®¨§ @ËP´VHž '/5§/6¥.F’PõÀW¢é±ÆîË­=K¥‘+ͩϻ?‹gþÞ4ÕØûëŠv†ç^g™=FøÓŽ7›D'h„äK×Ë‘²‚%ÝõQôÇ_F{.D7_Šg/4wOIJׂɅúÿ2œ¦.…“×ý!íMj5R½q"Ò=߯·Ì·+ÑäÕXúÑž  ÂÍ\Äb›½ ãÍYX+€Êb¯ÃÕ¦ t-–¹Ý2Ñ”œˆf~æj ?èâ/ç?}Q#Ïž={ñx^#ÿ{ö_8çìé3‘P$†~ä)ÉuX#qc´Ã}ì•jd(^:Ú qæÚ\Ãq8ȳd´Smµ2…(„yßn7ŽtÐk,ÑA~ÕêÒ~Ò)»1óå`$3÷Ò*([[â—q”ME"*„]#vø\{ßÐG¾WU¾ÛìúyHÍú͵>½Æ2JÌ‚2ÜÜ٨ő•¥# çPÂîô . E YÃ+CîAÐH§6ÚæÉu‰-O"‡íÒ~ºʺ~ Ðû¡¦g^V#æþŒ|8߃³/Ïs ·¤¯WÈÊöõQ\ý½Jo—&Eš%8Tióþn‡õ› ÚØd“9´Ü®;™D4¡7ÕUïÞì>¼]<܆7B_°N†¡Ý[¥þ P¥2 õ —tš<­UÝWªîʾ›æ¢kä®î¶³ñ¼Ü ©8¶|¹@– ™³@ *ü¥‡cɺiI!ϸ0V‘Ñ”‚S¯ÓËK9üŠ,Ôÿ%РЈD , [qœ€Ñ (¦y¸/É¢³jíŒR?§ùï¨5µÐu­áWyËôΨA†)‚Mb1†àBŒÂ5KÐÌ--4«ûç ¸Ê?m†æÔêûJ`l¤Œà \¢YŠáxŠ˜U‚·%XɪY©üs+8é¬ýHªTÈB³(Ï*(¦ÛyŒ&è„Ð'Ÿ*?k~\§$Ϥ^7¥„ΰ5°,Æ1¬€±œäÁQo±ÅàŸ9=<§ûn¨“ZÃ]½î®QqBÉy03°Ë€Kb‚r]‹ÜÑ*nÈÞ'Îæ‹J(Áð4³¼spnVdÒØfI>¥–pžh‘ 3˜SÊ[ìÈEbQ(2I$‹Y±Y¡fº8 ÷ä 4M7‚Í Ž](<È8ÿ,ø¦¬ð}3|G œP«C8ØÈf—‰ÆÙQ§ Y5ò€¯ýè‡â@(˜'„˜öUõ¿Ø÷í-µþÉ… ØÉR¨ÛÌìÊì^rN|Ç6šÚ 9™Ü½Îe @¢Ø©÷ý¡4?7@f¾ÂÇ|µm^Š@»Ð¸i*Ö3Ö´e,šü¢©g‡äIFäÄ÷ª:Ï­L×sª@Ñçê7ýÊ/³1<æè«ŒODÒ›»ÇbI¨Ý—¢©/" N^Že®´n=K ,<>c÷Ö¯…«.?_h «‘ü™ã¡î¿…“Z©6=Þ¦•Œ5¦ÇbéË-©EWY4Ò ¿H74ÐÈž²&š%ÐÎ9;¯‘¯§OŸÂû·Ï_p³oŸîûí^ЋD* msn¯/êp&@#щ’áÎWUUcmî‘Nk(áÌÅçÛü÷æH‡¹¹Z&mß§¾WòÁjkh­#$É8‡ÚYéÎmnG4el(1sq÷‰õ/;®ûÄmgPªå¬PfÙ"…_ÆðäàWy¬·Úa8ëDB?6F›Ì\¬|°Ý¿oMõÑõ %g®⻇WÃT‹ó‚Z˜Cùi#kþO|™ÿFu]qü/@ àyó–ûÞ½ï¾ý½™yãY°=õÆx›/Ä;˜&%"RlÏb¦RÓ%¤8U‰Æ,^0©TðC¡J©Ô¨R~¨ª(ÊRkš@ã…%ô‡ª ¤gL…"UD¢"}5ºzºsî=ïÝ{¾ŸSq¨ø]‡úpÔKIaïèÑŸܧ‘"QLdû3J#öþ"„¸ce(F3§†´_Ž(ÓÅÌQºê©V…o¦õƒÛåéáèÄŽHÿ& I9®øOúÜ.ñÍ3phy$–þ™á³C;Ÿ:N|Cɼ@òëÌ®‘Ž- #º+‚´=œ:Ý8Î{¶%.üqst È$ùÄÝöaTø¼)}:9pæÙÜûÉDʼnî•f_ø¤e„0•ç ‘;“™ªÚ¬a •䇡Æ?µdOmÈœLöŸiN”xWÿ-°ø6dOµ ½—J»¢Èp%”’‘hòÓúá³Mä†ÞM¥O$__ß·s]KÞ÷™QK¦<Ô$‚+tçd*¾eø|ÃàÿFVè(}:5xŸF&kz)EXÆ»oÏÞ;ÿü×¹wïÞƒq‘Cþ󴨟Œ¾N‰¬‹:‡×FG[ÂsE™í~Œ4,œë)ýŠ‚+ z¯µ˜Üj²ÁÁxì­±KDC/FÝBŸúrŒ"ª¢ÿ»õ‘Ù«ÐõÈt¤'r칊ÂÖÀ®V>eв×ÇI>F•-bvF‚?ï²ç6ºÇ{Ü£mö‰Öà‰MB{x¦=Tè(Ùží Ïv–ï|Š4RV豎o\w¨+z¤74Ù#, åE6æVì+ú¾=‘аÆÓîxö‘id¢ˆ©|p,ãNåalNæ``Ld̓ùÈôßXÚ[à²EŠC¾ØîáÈh¿<Ô«t[Ϸ⪰¨RM’±Bu¯È!}§Á€þ‰,|躆BüoÀBîøÌ/Ý“•·$ ²¬ ü( }a%/ù*oUKfÝ“®ê—üuoh¾RaW•L¤Vш çËè*¡ÃbàšD©ÉÂa@0WÐ=Dh6” ´þf ñ°ø7¦?èë#˜U¼^¸¡ÆðÒÀáSBr8¨–-Ù)ð¯‹Vå_õÚ¥êR°aѪYÔË–}IN\‹YDà‡’(pÌv…^±šÌÚkFÍ’ÐXr٬낫 †È’H"JªîŒ¦%£&/j–ŒÆ¿)•×ÔøVE•`pª_¶4^R%É‹E[Ö¡›+¼šGf0[W_q*—¬ªßh1B3Yð"‘Q…“™ïéþ+fͼÓxC‹]wj. 4¶¬Ç¡ƒóbÀJ€"¨ý`·,_vê.;‘K¾ê«võmZs>ÐpXކDfö¬Q) Ÿˆˆˆ¤â|Qú•ˆâÁªËe‚© d¿&@Jv›î?´Äßíø¢Sû©]×{"Äñê– H()¼L%™….Ò’e ø×»jË6§i<ë©–¹wÔ²e§îBpýU=)@"$»^ Æ@²+þ“>·×õKj".Ñ• I‘ˆ<¾mÇlæGO'¾9Ì î<žÝ5¶uÈô (/X”ZÌèÙDú\2@þaKt¶mž<-9Óž?ï¿°bÄï'ûÇ⽦‡—$é_Ýoë¶Aò®LO5oß[ÙdÂÒ+ѦÚ²§ZÓŸ$úÿÜšÞ¦úÏ4çÎ·Ž´ëÊs&‘»Ipãºx[ ¢Fñ— ŠÎIÐÑ@O„Pñ@ªH„r]¼ÑHü#RÛö³©ÜÉ"|œê?ŸJŸl9Ö°U@ Ðë»F¿\;wî|EîÞ½{Ï¿¼{´å¹çáC«-QJÊ÷ö½x¶Ã9Úœíx\®8ÚS’™Îp¡¨ã®<ŒÍõÚ6q:«2Å(Ð× ¬"ÓêMñÐËMbDQèI9ëgme¿êûÖuwFfº¿ØàéÎmq_m¦I›‘¿,ÁÔ‹8–'ŽnvÇÊÆ6­;¶Ù=œÒß´FgÛ£…žPa3(phC`&ñ´hÄí(ŸéÑwGu–6»£m’TB±ª ìm«ŒŽç'H@@#Á‰Ü£ÒüQŸÈú¦†ƒ{²¡‰¼2‘±¦†¢o –¿™ e#;·ÙÙ^¬«}k‘®ëˆtªD!H‚cÆ ;“ÏÈàŠ( ÎKí@¾ñ\`2÷54«&‡é"Möçü“Ã廳ܷ/cŠ aíïÿM|™ÿFu]qü?hží-÷Þ·ïïÍØ3Þ°=›gafŒÁã1˜`ÓŠ¤mÛ364mó*PUmj"ˆüàxÁ6T”Ji¥týÒ,ŠClðŠm–*ý%”¥=SUüæH4¸Œ®¬;ã™óÞ÷ÜóÎ÷s Ùjñ9'2k„—ôu§‘ÛFä’ÓÜÏÉ‚Hëœ,b…p ¡)±Db8óáE"üÇ(9ÝÍy5E`x—Èfyñ#ÔôU¨uZ ®ÿ®_S/©šårÁã\Ác†#L•佪¤¯éñU-1cDni±Y½áFe ñŽØ°ªl‘½p+:ÇqUŠÈ(2MÚuQÉü]m^ÒÂ7­Ø¢š˜÷GgÌD'œ#è,œ‘$S2üÄ¡è›ZbIKÎ)ѧqÆHΛÿRÒ§á a¡×+6•ÐÕ $ˆQOÛÞÑæåú;úG>*!/ƒh¾lÅÞ_ Á».º ÄæõÔŠÒ¸P™r©>‘&PP&°@f^”§ÌÔuãe+ü3qÅh€œ\uRoJ5 ª@*6è”Oc( #"°P2Ë;ت3œ‹¥[‰ü®ž³Ó³þÈR v‹«ßnhdÜ¢á°d,yDó4d–òêq´a/#‚&Ú‹éoqž´‡ùµRuOKÂ}.é±%@ÈQ ‚Lû¬â¯wÝ.Ñe9ùSÕEJyAKɹžCÏ'¾áï;:Úwd¢ø³·÷ 1xxj^ù´¥t)Wº”î…¿m)^Ìõ–\É”žH”8³ÿãôÞ/ZœI}'èC”Æë Ö}ìäfeqN¼ü¢“»WQÛòA¶÷Ãì> ‘«Ùâä–þ¯¡‘+¹þÉLßdºïrî૎Á0»Ea›æu–=à4èÃðB„lä}‚À  VR0ù]âû[ú Që‡Ï³¥OZŠ3{§2}ZŸåúßß¼è«ÌH4Ó½«ëÁý>‡>Ùß¿ÿ¿@òÕ} –ŽöBÙShRazëNï²GÛB#eqF·‡F;Ÿ•«Úcöpð\ð6þÑ‚1’lsÆwK{š ±š‹(¢#A4#Bçç݈V¦ìi¬Ü¥¾½58Úþ´×­ÿM—9–÷Ÿ-l/·Ç_¨ìÒ~q…ÒÁ´nަát¹=ލàŒà˱mUCmÕ£»BçvWÝ<Óú¼h° 2¦NäÃmuC]zoT`Ü‘!9ä[ÁÇõ%0tpídñ ÀíxQ;UF‚àñ@#þS­žÕÔX]ÜH(·—Öx êj#Œ`D }‹1˜²Í›Fˆç\2p ÏùÆm:òråà«Ò±^¸ÿ‰ÒZ×Uß(ÿ P ˜Ä¬p(tø{”^ bL'5çä¦Í¦'6mEõäzwõ%­áž¸mfÿŠÃ9«^—"‰.ÂR¼|W&„£$H„ ÇRÝÆÇÓ*G½ÎÕ,(-ójlN«_ð×­ÿ޽§¦Çì†Ú Ù3Ì $"ŠÃ2źû%å–¨˜±c·­$É’žÓã³FtÅiž²r&Í,0Ì©â55q×j¾]ƶè²›uš®ëÑn,ù †v«¤Bâ¼¼ËèI»iÉNÝÒšo˜À 3NÓ‚^°Òã|mŒ 3 E»dQàe¯À¨¤$ùP}Ή­¨à­©÷¤”Œ°‹Ãb¹ç1^TFÐ_Éõ³v|Îl^°Â‹ZxYN¯˜‘þ¨æÝ QeÜ¥ )ãÜNbÌI­«VvYß0£·ôÈt¨’6­&ÏËñ$鈨@,aXÂ2âTžh’Eh¯"²¯"ç[13_jñ)½öš¾ã$®Ùñ?‰YI´b¸=>ÎEs+ª­U"Ë‹&À“¼Ä=ßÞ)Ê¿#_Ø™;:\·ö®3’ „€Ò@ ȱÏ*þz×í¢Ñ´h5ÿA#T¡0œÌii½úÝþü¹ãÄ7\çzž))MÖ¨þÏ…×_Zö}ÜZšØRºÝÿI¶ïóÍkºùz¯3½—'²û'3=S¹ó-=}¡å©`KC‹ôÍCµ™¹ÌN×çcºÞD g"]ŸeKËíŸÌõ^Jïš kÅŸJAìd¦8™è«iöȬW~Tæ XД8–’X¤0åå`””Ìv=x ì¯I]Èô]NC~zþ4Lu¡eßµT/Ðȧ-ýÒ½ VŽInmÙ¤ñèÑ£<~üø Š<ÙÃçðXŽeÃO`ú£B¨n¨Ûk¯Î[ÛÍÑŽàÈŽgåªþ3;Bc;7MtWvT¾ÕV=Ò oáê‘¶À¹]þ×òLJͲÓIý`XÛȸTâMÊΉ¶ºwvW·ÕLì|j Î׿‡ •cíÎxœ=8ÔéLt× ¾ ¿EµÈ )Ç ƒ˜ÈÂi ’r8Z9Ôáœ-’‡ ÊpÞÏ׎¶=/ ï¨+˜cmþ±v8±# ! ,Ò8ü¸9,íd¿}¬dœ¢(>-Þ8`/)o–÷UÇäSýÕ'2ñ ”7, òMp¢Îòâ€Ã:hŒxYÂ4+yYÕ‡ÌcŒ½õ—ÚÄw§C¯•¤“å€þS×{¿žF¥ü'ǨĽÛD†Å,xýA¿kf¦íÆÛFyÉX÷óK16c…ÔȪ™º'§GäêY\'QË”|@/ZPiCPœXcÙ0ò6*ÏË‘e»c$Vý pŸëVÓZñçÍÈŠ»êlÞJÌ. ’Æc/‡U‹öý^¯ˆáU+~Õ»g¤§õð²À,¹_1ãßÕÝHí$t'Ço¥."¼¢©ÿf¿Ü›:Ï8þô§Š[âÛ¹øÜ}αc'qœØñ%Çwçæ\¡áRQB_´©*i «˜˜4îÚruL+­˜ö“ø¥´š I€œÄ8JÑÖ_FÊOÓ6iŠ´ª°hÒŽ¿²ô>Ïó}ßWï÷s¦ÕmeV´=¢%`†i®c$hfpHãø«ÊPŽ;¢ÔO»~‰%„¤*Àø®¤år“»qU7®RÙ&µîI½ Ö˜mN”ûMÅCÖ<ÏKϨê‹hÅ{¬ÎËp¤ Onr%lµFU¢"l¹ γ%_é<óLÍåJÓEèyгƒr@HË $Iû²ò¿ês›áÍpT€KMªBD†²…4'£¿Xvœø‰q±ýýT´ûd¬ëÓð›*}À!ŒU È)kËÕÚð¨/rÇ¿î å­üz™hd°&–÷bxÌõ†Æk;/¶¬W `%ˆRAÊ[0íe÷Û÷]±[¾Øçµ[ºËjn¸ÃSÞÄ`MøfmdÄÓZ –tyOxÕñ[¾ÄžòZEøUrm\…j5bb¸FÑ5H{˃§?wm¹æ }S$îú·Öv¦«w¤]áÏÖW½·½‘<Ô„&¥ÐȰ?:ꉕ …R®`ifñ/ÏÿB~øÛó÷àwñ¾k  Nè¤iªÛrœ@b«|[Ó]NS5Áææ))A‡÷´ÖY¾r1?MótÅc–æ¤/xËg´î ¥»+–O±ž,ãÊjà ˜³¬i–š´sà dõΦä)mš¢Êi|Bš¥Ý€[×xÓ%¶äUúi™a] ˜å gû³.0.ØÐΓãliÑXñ†òdå‹.M;ÑkŽ_øž3~Iz+dtî*­=ìyó†ãí!ÌŽùc7X€Ç¼{£ƒþÈMod´*<ˆíkön½Ú¸í¿C#7ê#SRh8Ð1ä‹L¸v^ tw: PÇóçÏ_üËó2™›™…#V¯ÁРƧ;Ó`<µ–î ê{ë É—æÂ†Þf6U_Ü·žÜfw£Hš –j÷Ôè϶éÏ®ÕõžZá\Pw¢IüU Õa'>tkURµ|_ “ çZµ$U¿T~mÿ:®·®¸·Ñp¼¡äü:õy/s±N¶OnÒþ:Èǽ\‹7iPÃU(¡@(%AÈqJIpµQ!«1d5ºÏ!ž¨+ém†!ŠS-údSQªy¹h¤èl³!Õ 9WÍ÷+NlÆñµ!¤¢˜ãD€"Š÷Ç©C ˆý0òíÿRdA& pöóÏÎ áP%»†7ŽŠU¸(Ù¨ ¾f øt]aHõãb9Íè—)ù÷VŠòñ2s_H7Ü`®7%ýÆ¿).L6™S!cÚcNû-ƒ¡‚dØœ¬‡)-ª‘þ)[o ›Sak&¤ÍºVö×+›L8“‡“y4!Q&•®H–¨„¥å8Jb2‚”Êä™™"zõ¦ò­> ˆ%-"Ęª_àŸ®Ï­Ft#>€bÁþF’\A#8Pt¹EÛ5²¿4Âõ&ŒÅÁߣux@¢ëI€CúÙÞ˜ö€`íë4€+ºcæ½m¼Ð€W[¸f§.Ò ßþ¶æÃCy0Áˆ«çÍ#2¦·ä£ìî¨{EŠ@ðÝÜjºãºÝ›1£ÀHFFؕ̌BÔÈŒfÕ}VÔÈ×lî·ý—ŒÇ\åmMù]]嬪bÆh›Ñ•=ÒU^וü]QòoÖ½“2Ñ’GKÕð€à`= Š×TþCSõ@µJ¬,œí&h„]™ó…¼‰%³lå=uÅ]}õ)yM/£q\.ÅWóC±®±6Q ÐŽí„ÆxdgZèÊ=3^Z#£Â®ñØ.˜vOëÏ58ƒÃÒ0Ò¥2Oz¶]­&ÝÂåê-üñsöÖéšh®ª0X„pÕÛ>陈ä˜t~âm½V?YùÓ‘ªï¸¶Zl?áK‚*cµ\¥Ï“ç¡'ªÞ™r “޶éðÖ Ì¢óŸtµŸ÷ÆA,Wm-œ­—}‰ŸòÅOÖFSeÍ;Œ5{Ì®Œ}ãIOä–·ó„»%WÏábmËû˜'( 4rÍ;ìˆK"JZ.'éŸþù»¹gyòäÉs¼h?;uò/ˆT¦`ä ”a7ZE¤ƒÖT£fXÔˆéõiD7è·Ž… ?ö3o›$r™:2K•Z)Î (“ŸOQËY·ÖüK¯)µ–ô¸õ©uÚLX?„Z\˜ Z†€IºÑEó[Rë­™zuÆË'æ~¯~¸Îv¤™‘ËhT"GEUÊ"ƒç³,Â[äô )Õw¹¬}k­ƒëÍ–ä:ëPx"€S:‘CŠ,hÄ4€åð ®_8IlБBi6P ®Pô%ÌûEf€ ô „Ū¿nžªnAs ¡;ØGÌÕ˜÷%ø}q¶G€„¢~Åz"ô¡„òH{¸ƒ;Ôùa¬¶·.Œ…ŸÜþ˜(œÞv1^Q#º‚ík×þ: sS¶Ôa€TGpé»j묲ú‘ºüWÍÚ9ßö_2þ¦ªº¡.¿ÅÛ.«K¯iÊ*KÿÉ•ÝኳöO46žDƒÓ4‡NÉäŠv\5ÅÛÿ¥«ša‹rU³jûmMå#¶$ç yK"ªm”e_ñ¶lM)(e2'8}¸õ=± ·lv¥£;@#¿í^B‹îž?‹îHt±:Š )f•Q§= ÐÈ%(âµbu1àˆçª $¾ðD"ó…8:QùCÅÁ*d( rš"Q”%H†–Ë~Èá †$+›.úâSöÖK5[®xg|‹jäJ­Å^±·]r´Â¨?ùÚv: (%¼k†ÄtÄ”/[«0|êN{:sõ&ÝÑ OÖ¯ãœ;zÅÖÓ~×\EaCÀCÀÏœ:=÷íSOŸ>§ÈÜÜÜó8›<:€£¼h!¸è*>0¥æÁµÚ,h$`zm1Œ7ª‡ü†”we_ˆlÈjµ„ÅeD¾!ŸS,g©8„£ˆÔ„3-« }MýMÖt“>»†KúÅá™Íhò-–ŸÏ6›ÓMÖS4.IÕ¿lÂHŒ$Q %ËS£XA/x­{7ðG~¤ÏlâÓë,©FCÒo©³d<–´[7äfÆ<`žɆ™H\iÄœ óé:]6À§Ö°›K@SIÓ£y§jº¢7nØŸXpBÓ×±xõA„±Àe  PqDL /8Øg†žvèÑxfgØèû¹^‘+ÐÙàÝü5bªWÕˆxÓh„ÿ0ÊìÄ]+1Š5B,ÓT|-jdõ¶ôŽNüô{¸t4r+ÜÑÚ) þÈŸg*n«Ój[[Ü@Âg«„ÁAþ jªÅ˜|9®,žUUü•-¾­YùX_3ËUÏpå³Üêœ/äM,‰˜UÛî+WÝ×–ßSÕl! i>l†¿¿¾ªùx[E´uAYŠ-vg„ÃÑ.pÔPû.»¡HNÒPÚÔùèqOäKG|¢62éŒL¸…‹ÎèdmŽ(ârÖ7ÏGìœ#rÍ.ŒÛ6"’·´„œ€×@’AÀÌagc ¤-X†-_wÖÑ:íM\u “¶ÖóþÄ¢±Ç>÷Ä ÄO¹¢W\ñ³>á½"G±”Ä »‰‘( •å7h ®ÛÚsöœ‘‹žÈ”K€ö˜ª=zÑ-|Pì‡ÀªqÚ½oÿ7ÿyü{, ä…C~Î}·wÏ4I Ñow³u–TÐ8ÔÈg‚ÆtÝk¬ªêþ:ãp½a4¨’á¢CM%¿jàÚJˆ"9®ÆI£¥$)ä KQ*]Õ«ŒÛªW÷¬/N7Œ7³iŸ&Ò6.–_›^ÖŽú,™õ°—Éú•{ðï•#$KÊg†ÈˆåEa‘ê«Yzs¡6ñ_öë-¶‰ìŒøsû‚Ô’Øs;g®žÛãKb›{0q‚ã\Ù° (øš,ÝÂËBºˆe)›„°l Iì\H¶°UûÔ®TµªÔ] K²¥¨,MÈÚ¾rí7¥íCV¡B²}fìoΜÿÏEêa¯y Öq¡1ÿB‹ó\PkYÖPÄ5ªSÄ–B¥‹")4hÉZÛHmv²UªÖL˜¢YÓœvè­e,3Îí}ñoш­7fèi¨)N€ôoõÅœ}Pp b:×ÁŸ‹óg£ÐÖÓÛéêë„ëæÞ¨n³zgÝ3)Ÿ@ÃÿÒ\|YØÎÆÍ}aIÖéXÖ‡q2[…E(ÐXCÓjù}Ù»`.X’ A#³*P¤(íÛþ*ëJÑ’¥ô–Åß„YX/2Q Œìz¦”ï¯73<Å -'2DF³ï!^Ì™µ.ið;·äž²i^ymôµVé­Õ;k.¼oÊŸ³nþïáè ØÉižß]Z3ÖqôräèXè d2Ü=™’IÚ™±Z¤ìŒÅz¶”IˆƒWƒäýØ·}¦,¢k¤::íèñGÓ®pÅ—Ño*ü:°WR4lh’ Š4 46˜ã2x¤Ñ|»Ûw¹t×-üJuô÷¾ÞtÌxÛWêîú¢2 )Õßù]E¨Òd§Fà 'œÄ[Y^ÂÑÔ¯Š÷¤kfÊÛ¯ø÷_÷‡§¶„¿¬ŒÂP§üÑÁ‚&ˆ`=…YþøOÞ{öÜ Ï^hþ>|ÇGÁÝž®nЋ0B´ãD#È®ÕF›²’)Œ6¾ªTÍlÞ0±^g›lP&êÌcuÙãÍîDcÖX“ãý á-å¦y J0ÒfÎDâu¤œaÈeОlÏ…fHäìdš¬Ôß9Øä®²Œ×h‰`Îp£ëb“íP©B°ûó¤%R¢Œ$Ãó$Å“Ç1€ xÁ’´D[] _®9×ëIÔë S±ÕêyuóðhÄ:Rç­÷Œm 1™ˆÁˆµo (ÿ¶˜ÄÒý¼Ð@EÊ!ê{{Å‚lµ¢Ðº­B‹5ÛºvÛ?gõwº,#>öâ+r nÁ@>úûbz‰/[å¥JˆÉhÃpÛKˆX$X·Õ,½hò/¨%³æüEµÂ42Iû¶¿Êš“7Þ·ún›«ò06ÒTf¼G QlH˜X ±(Š|Z7$å>P‹ˆKæây­dV.¼'—,Z½kY«UÖ‚¼iN+¼/çÍÚ¼Ÿ›¼,7’ÂïÓg± `š$‚²+]ópÆY¥k”C|å ÿ±l?K# Øúºà²Fž>}úœ©¿Ç/_„»olmA4aÄ È3ø¦k´:'Yoov%A#ÚhÓ«JU°‡’¨µŽµÚF[³‡·z†šƒuÎÑFOb›ãDÀÛ¨4XøŒ%‡ÅPœ 22¬@ÁkÎ?×bú$¨LÔmH¬¨ˆlëD5ðÚÍÚx0g¼5ï£Ýöó ¦S⻥R{±TïQJìªMäÁ¨fðT†Ls˜—Y†7ÑÄwåïdÓ5²L‘¬±Ô»§(¢%‚éÒHÖp½6^(rí Ñ:™b2y6Ûíx˜{£ ST§Â™N+¦¿–:*½ œ»û:=ïGÈP50¿:`ÁpÍ‘úbÀgäÀ(XbDP‡12˜PCsYŠ  Uî‹®œœ¯ÿÐRzG_ù [’õ‚ŸÅS7uÎû\ÉW†Êë:ç׊Òß1z9ñ‚ãh’ê×Çú&»ÁÄX´7Nœ ­X#£ÑnxN&ÂÝ'c{R‘î¤Ø=)öA6ˆ3‘>ÈüµŸŸØú&Ü<í~/Ø{&Ôs\”MwÁ#§V>.À)Sm*Ú“0¢å`ߤÂé<îŠë´[¸RÌz#ç¼áluaè¼søtUhêñE/xBçjÅ6µ¹…9O¼ôa ø«¢šFcÊ¡ Ž•1Ȥ³CºÁVýüŸV‡>óгU]×\p>ZÒË/ɲE,u½a+Œ{¹"8^ùc•åÒ‰ÉÏ»¡’È5otνÏúÂSžðg^© æj®Z„+Ó^a>‡“ï{~ô‰¨‚¡[}5‹ËËÿX^’L²ô¨FA#v[P„!(…•ÊéЧ¬Ã­úT›-Õ i$Õ¸Z]Õq¬Æžn5¿å—•¡8ùKÈ0…\Æçªä*çAŒ ‚P¢r}XO:h]S¾}kå×Ö£­Ží¶T£y¤Î2Z¿j~< ;Ñ MµÂ[­¯<¶QÛï7ŸjÏ:? Ëp«-U§NÖZvÔPxn)ã \Ýæ_i÷7ŠƒF”¢¤‘¨¹?n?¸E¹k£>Øhìô|%ªëéU@JŽñŒ‚Z›‹äÊ Šœ¨P | K¬r(Šr ¤èG¹ðhD31ˆRƒ1­RÍ£8ŠÊu8 ¹©v‚FngÖÛ§M#7¸Â»šŠ/ÔUרò³\Ù$ï|›ËO°Ö½ŒyD]ô‘ºò:çºÏ{þ¦ñÀmŸkœY/øY<ÕqÓPrs~©-¿¡q~¥,åì%Ëh¤³Ì—Žõ‚F&…ÞñHÏ“i,‘8JLlÛ{,¸ã¤ÐóAtß‘ðÎdì[*ˆÝÇ"»ß¨Ûð“òšúü²Ým¯Ãˆ'ƒ‰‘XÏ ±w¬k ü?Éø§˜ÒbÉ£¤‰S^ôÅf\¬O¼â Ãž¯²¨‘tÆ#dzýe_ ð~éÆŸ9¼]¶²F½½˜àô2D‰¢K¼È r³Fžc"¨OÝÁuÛg}Â…òÍ—½­Ø~˜q!ùYŸ0Yþª*§qÊŒÊ?ò/b3¸hÁ† ùI}üýŠMÅ¿/hÞks÷™+Ç Û@nR…¾hF#0o ‘éÇ»Zñ2«†]†Èm*ÍÂÒÒ7—,ÿ·FHŸ¥¥%¸Ž!(PBYÄå%;õcõ–ãMºdkF#†dójuUîݺ—’-¥[\¼"Lj“,J®A9Š4Féqª’ã‚ú}µöÃÎ#¯›¶YÓÌécªÍ4Ò¤?0ךÆVMGyi·!íÕŽ¬ãͶwjÊÆ×ÙSõêQoÖùñh ·À¡O7Å* GP £îÕ¦'Ðùþˆz0®>ÓöG­ƒÛÌoG顨⠠< èþ°MÛ/Ü'*ª H’¤ci…ÏÉ·¸(‡ S0†irI#ÝZÁE!§­‹a(®=$®´Í`T?3 Ĺ·B ŠáÇå~V ÉP䖺䎺$£‘»êì/ûß9Šîj‹¿Ô–~­­¸¯sÝS»n++n©\·ùâ{ºò»úŠÌ JwÂ{)K²]í³xºã¯Æ’;J'ü¤ÐTüY]ÆÓrgáê28RñÞ‰`⌸gLè–4"¬Œ’ "=üí1ñJ¸ËÛôËæÍ§7íLoé“("$à8(ìðêÌZ9ü‘[Š]0Öxp·!¡X÷œŒö­t\Hr*,@ÐHZìñhí°3‚…BMP¬F ‰Ïy"Ða/e‰"ÿÖHµThdÊšò‹âi{3Š$A)pšÏ!8Î!$(âG4¦#舡xÞ™® ]ª੹@üqù¯V —jDHÎ9W-|ìqr©epòf—`wm6•®ÓÀ‘AI=Êê¤ÞbÂÒN¡Ž…M¥Ÿ¶€Fæý±‡É$Ÿò„¿ïùqk­,”BàŒ,ì‘ÑÈÒÂâCü&Ëp•#Ͷ—.áŒ£í¦±ÇH«&ÙbNÖYRµ¦dËjuUå¸×–l6n¯XC?Ï£ó4ÉÓ§úi‘ýÍúü‘NãD«f¬^Ÿ¬³Ž¶ä'×kßmÒ¦jGkìÿb¿NŸ›¸Ï8€ÿL µ-í½:öÖaÉ·l˶,ɲ-ßÂ8i¸¬•V’ m 6G’픀Oð$ƇddÒ™Î$¯šIs'@&$Ø`nhÞµÒ>k3„¶Ã 1N=žAóÌÎOë=ž]¯öûùjÈoN7›cõb¬v±úÉñÙ'ê„xåðÓp½å¿u¬ÎzxÑ®w±Ê<Ö`Ÿ¨µN4ò­9†ét0Ž•›’M¡'$õG¸Þª‘ÁÓ"°†=…¿?hî ;~±6{(Š~#"c¾’µ7š¾?jëß"EVãfÞ€‘FZoª*w¼ Œ1ïW@#LŸ,&¯¡?,(–>…ûÕ:ø‘‘)RÛÁØæÄ’(2ÿ¾U)Â.›Ô¾É\gWŽ«lþ5&ŽÉ¿e,¸Ïý/¼Á9¾a³/qÙ—%ÇUÑy“wÞcŠ—¼áµ¬ëS!üX挅w WÄ¢¯¹Š,ƒ"q"ƒ`†£;'Ûç5èJ$é…UöÚ´½%·LGP0{]çtØñ.x㨼ëÃàn°J¢óí6§ÇB1†gsæxçÛp:uÇÍÝÉ»Ç;€Ï­‘ eWbEÍ9¥ðj‚i,­E¦*^û²"€x…œ=í-•FNEÙôçç5àÂü(Ó¯°óeÜ€1=Ü¡ŠdìÞœ"Ñ4­Ñhd6Ö˜÷acf(ª}_Dm¯û…7hÄ´/d<1õ(ÖÞˆ±7 õ%­®7,ô…žv®ÍGhÕE¤ô2¯ j@/PÆO]uÃPtÓX|›)ºÃß`aMá¬PxYÈŸ›ÿz—/½/”ÝV­U0Ã|+.yÃ/jY³ÿó®ÐŸªä‹.Ø à9ïVt4ú2ž’ÆÐ$I¦0´"Ñ;à½ú¸æ5rC,å2ÒÈucéW6#–~%]œßšJgM%W¹U³lÙU¾l†/¾lt\6æ^áògÇ’7ü¢–u]á ¯sêà6“ÿ5ï¸e\µ•”PB 0`Òðë1eçT{7äûs¨àp û¨¼ 4¢x[ é`Þê”ìûƒÛ¶·¬ÿE}›ìiªË,r$}*J`8NS¬† UELmxë#yw<ôƒ(’ÕœöMÈjÛ[k_¡qÒˆS4Švø.•‡¦½ó‘q- ETT´Ÿ÷>ÎôsUáÓîàIW–'Šþ¥+p±J9ç‘§½žö3•í°æZYÇ´+t±¤ýóÊÇ}  xã¸[~¦F<áÏ«‚gËg]íçÕƒå‚)ÃÍZ AP…L`Q<_/T2æZÁ.›Š½¬;Ë;äh/^7R¼æãÒ×g+:ÏúÂp®³ÐªW;EêǾ?ì  H“;v øùçÇ y4uðèÑÿð)Ú,Ù p‹HÀKнI§ÿ‚=Àªæw—ú#PÜ`ÄÔ£˜¢Ö÷BÜj7¥ÅxŒ~™Æ¸mkí¿ ClC[¥ß´Ûú;$¥‰ 0=J ÂuµY;ôƒÊ¼sB\O Ù~¤¾­¦Á°8Ðgšô¶g¨_±ÅO4²ðŽŠÀridv¾Õ›BÉ®ä6St‡-¾Í_3̘T‡Ü`Kî1Å÷Åß±¥ßñ%7™‚%oøE-낟Æ-£sV€qþ>ï:»ê‹i$I2Z´0Þyxs$;ˆÆÉª kíæÎê5í«ü ¹¥Š1`$ñÓT+n€·„Š ÊRz˜ÒðjÀ0Š¢*myp"PD"¼ûð¦Gª+’=éÓ™ í‚%ÔŽÖ zŒ„( “3K.”ÉÓ¾D¿©K§Hvµ<¡‡@©,ñ„þê ÂÊ ÿf¿Nc›È¯€ï‡JÕn öxÆ3¾ætlÇ9Hb;¾o;Ä &„†Š ›xX_ñ k ÆœoÀqšLÏš–ÕýiÜàeÓ4–(QìâÅ‹i‚<ùR Ï5òGžÿùÓK2œp‚xéE4ÌâdÐн™ê† Òõ–ç÷¬Ùô7¯Ö&ÃÊD0¿¿<÷”7¿/ÌõViºkŒ?ö«BšuªlT$a0J…*p‰DF b3J6s»ª4gÃù½åÆîÊÜÓLÿšÕÃ&ªuÉš‚dµîxHßU™×ÖœªÈë­Ê8?þ#€aºþþdX&!Ù(…ËÉ5×Ù¸ÚéêP@#9MìáÓ.À;¨FÞ!è7êÛò4á[œ*…’^‡Êd2"hÌmoPo";bÔñf œQá8…°Ëi÷íT¿'Çâ9ÇšÕq®sÕ:¢5±ÛÁI¹BJã)%í!㜧,iŠPfØi¿ŠŒoûÿḛ†)ºd†5ΪKïѦYÊ´À˜ç(Ó"e˜§ prJm‚gØ»¬y†³NQ¥/øÿñ?ðÏòPa¾ËYî²øÕͰΔЈ” Tˆ´Æèœ‹´\ˆ¶%"û¾†F`+À1)0@Ž`2ƒ§W¹v"D.G#e‹ÅJ¹Î(ÅX,Ts!~àLݾdCpâƒHK_´¥¿~ߪAk{®`És¨åáQ(]†íЖLØ"ÃãCîHz°º3¦‘T >âŽ6 —¬»®¸êáÌU7Ù@a@…‘²†Á` „pÃÛàgÔybqOAhÐWÇ-LøãpÁ¸oE¤ìÂ-O¸ëJöGnÚùËå @ÈPeóeod,Ô4àÇ=‘ _4勎¹ëÇ|é+‡|õ ëp¯~0P÷'Çð×gƒU õ¸;úªûóæ?•‘P2xcòhéÉò¿½–––àü‡ç/¨d0ý1)‚b‚vÃ‰ÍšÄæÜÞMºž:Y¡ëÛ¬?Y¹VS5?YÉu‡¸ó[èdPðê“e0ú¹®­Ê³elo¹îP™b§>K“%A^£Q)%Â)1©K¾“—]øÛ­T_8·'”wºœëgœßpèú7åöV߆â"J;‚X5º#Í«þ+s8VxtÝ.Gãú½Ûà‡ÍF©‘ÜF{ÁOvv¼©}7†Ö¸³XlÚõØ·(‰îW¼òD3s¬IÓ×v4’ÇV­#²SÆ0ïFhLN"r©D´ '¦)WÆ·÷—t÷Xë¬k9Ï·‚FVM¡U‰"T"ÆPWÐb<@ˆ$l¶t½L*"`n „'%¸" )’³5Îà×HñÂ~ôÅÛÎDöŸ­ß•_~”‚D2Œ€]ȫɻG¹7 9ƒážòòÀa»`PivçØÆ¼M#¾È@™rñN~8rÖÝðÄ>©Þ4¹L-ÕÉèmõS=à„)GôS?¿ÒúàQŸpÅuà6o9b׃MôìíŒll¼†¼ü¸?šò§Õ1äGƒ‘¡²{„Îèíàž¬§¨J¥Û×ÉιvÝ î½f\ócAa8ý­WÛŸj‡˜@à‡ÂHý]‰/–—Ÿ>Yü«F?~¼ôøÉáCí¨È¥ùÃââ®êœÞ°>ÎKT‚F´É°¾kͦa÷ÆÂ¾-§ªt§7çv‡ »« z·çŸÜax'¬Ýëávš¹`!¥£á DFHŠlœÂ¥¨Yn>µ=çlU~oe~WˆíË<¾éè«Ôv—ç¼W!’dÑb9!•àž|Mûª§ÿJÁ‚(ޤMBý¦)ï /*ÉÁÄb&Å$¨J¡”áüB1*ƒXPŽ"b"hÌïh&:ø®îPœ;WvÆW­ ÷ãÜÑÙú}‚ƒF ©—‘3´3ãÛûKÆ$i†a÷9휧lS LFÌÄE•mгO²¶&¦e¶.°6Ë4›ù‚_QÌ«J¦IÜà=µm–¶A7жEÊ ¢xaL3%‹¤ñsÒ:GB[lз)Æt›*š¤Kï«ÌSŒyRc[¤Í³Š’ÛŒá.kZiHñàY:H ©¡(ŠyH[æ¹Ò¹ó ] ðNf¼Q/¤}–1β†g)wÝ¢\,Ž€Fàe µ=ñ–ê[A#I~´eµ*pj )\ž\¼.[¤ Ö)q)©´Pº2½ñ»×ŽÐ[•;Ö ÇêßêÛûóµÒH_ÝÛ ¡å\´Ò/¤ßOGßVŠaTÉdfer®¹„”/ôñÔÈ` :à|‘ý¹ •j×Í”ébˆðó7ý 0ô¡<àÄTÙÞ?X·×¼.Ç`¶‰P)‚5Ó0ƨûwÜÂpYÃJëà ™qwtq;М*kj7WÚÅO•ƳæÚTÙž[ž†”ƒ‡>€[Ëøq¯0ꊤ<±¦Ao¬Ë¾í{Zƒ";;‹±ß~ý<ï'žÈ¸/ž ÄÇ oÞ´VqÂ^ƒÉQ0†R,íøuûß–-?]þJ#à/Eòtùà/~ —É0Þµ­ö¢î­êžMúD%hD“¬Ð$6åu¯ÙTq«ÏoÓþÈ•w«k‹Õ6 û'õuúÛDzü¨VU—Íá¹<÷á±ÇNBbrøvb;'1I[š.Uƒï#¡UÛXªu³ I ä„»ÝJýP©í—ª‚- á^®Ø9`YVÝJ•ÊÕg ¢_ȇ”€…õ(yÇö¼Ï3¯Æïó›"Œ#³Q-F’´–0 B¢”–æÞA³(ëÙ5‡7H£~(É<Ò`8Þ”y¼Þ0­3Žú¥=> Ë•0àÆ5X•ýÉ•Ò?˜>ëû\_Ôxh›hB‹ xN A„ž‰² e(’eàö,³.Û{y·iûÃúɼž¸2ä-»8Wê‹ÐÉ&*ç0ŠÖ";XüôÆ?«‚:Ò:WZp@½)ÛSŠ úã}²ô[Òv±-öyè’¬mž²Þcÿßøë]*îÜiÀƒdM˶Yh1/Z)Ùñ˜‘ŠõޝÇ]F]"°ÇMÅv[o›“³¼Vð¦. h1X¯+KÎ) ¤ƒ¤Z-@´©Å%ЩÓbé ©ê¡P’ñ…zÉH ®9±T ÜW¼uQ¶ÞÊ-¿VEûIxûgÁΓ¡Nèéã¡ËUA‹¥Ò£˜7¹ªƒ¾F'kä³PJ½ç® ï<ß5ÛÂ3|ÛóYd׉o_)œŒtO솿cÑÎOÃ]Ñ&J`qŠÄˆ"нä‹A >ï OÖD3©‘ÊÐÅêÈéµÑbVÈ¢´¹fG˜ßUlþkE+@\9ë ÎøâçêâG]Í… Çf¡Iìë‚×*+“ÞðRóƒC®VÆ®U'®–‡¯•GÿR ›ßAߢ €‘õLÞ¯V×þÙÑúeyòJE|ʾâm›tE>·´t™kªäÕ$ç ¹Ð`Þ, W½ÚŸ˜¬‰MzC°túU¯Ï°ëû,îFÑöüú£>|ª‘çyþzô4è}¦eO¹y¸Y7âäøA#ú1þðÊuÕ“ïæ¬×è²³Hô-àù®€3(A#…±8¢Ö h DrUõö;–ö+lhMÑÐy¼4R0ì—‡ê3΃×Ç›ÄÊIPL"þÀ£ôo[)ˆqº'¤lç»CºÁ¤r MŠ¿‹”*y(C¯ÒÙ†¢á…kPJƒéµ¬œÜPØ—“À}_ÜØÕíÑÑåæ5 $…þûÃ*RƒÃÃ9Bá¼Tžñíýe»0gI e7õVè¤ÐòRìµå)¶†²[²5õ´EÎ+î´Ñ}K¶ßàË2^ð+ŠÛÆò[¼eŽ/[ËRzË-ƒeF.˜ç\/ŒY}Vq'l‹œ-Å©zùJ²Ïë])I¥Hšµ,²Vp|gž·-5¤P,RCP“’œwxçí¸'y `‡ðfÆê%cVt<ÓHJr«Ë¢³Ì î&Šƒ4ÂçàýŸ uN„:@# ‡åª`$Úq8¶cäç¿ýŸoar1'>øh4°x9Ü óÔñJi$Ô ù!F#@‰ä‡©ö -NèQ|º*6õT#Ó5±óÞŒiäJUü’«õOî-¨&[KÑÏEW»§<[¯®mEœó†&ׯ§ª"ì­ “Ó ‰d¾[Ä)œc1Ds¬²åKOà‚7x±*¾Ôü«ž©Øú_–xcg*yî2šþ 8ÎÓ,ìÏuórµnµ,K4M¢„@0Ž L Ï•:†ï.ªû}uàºm°Vç*‚ç«c—kêà¯Ï¸u“G(- û|ï¾î=yðxòøÑs†<|øð™Fºó£U© !îræ­—G×åøóŽÖÇ×FŒCþ•j©Ê‘FóÞF6'Ë”Ëë‘Ï!ßb Š`$ ¡)M®”“[ Ô™ÖB}WEñ'ßwj):´>ÿä&a´N©/„¾<Ö”q¼îòç7q±RC„AQ¨•ûÚVJ#ƾÓÕlËë‰+=1ñ@œ tþˆ¬Íq 4!f!B6¢ÕóÜFOÁîÖÂþvøœ Q5Ò—z£ì@l¹yá\a Î×;Hø½…eýš—øÆw‡”ÔQö¬.JjÌ꬇ÎÈ•Ýçmßp¶4WzM.»n²Ïl÷á’3]ð+ŠÛ¢k–³(€ :˼T6G—Ýåœà±Æ=Öæí3¢-¥¸Dë]ºôkÞ6ÇYoÁé²ýžè€XÒ:×"eý†´/5¤€D’Bj(Ê€bfŒ¶›²Æ‹œ pof|¡^2fuN¸L îS8fåÒ9Þ£eÐŽãl¶¯%H îüZ8Ý8²õƒñpG»w}…Ñì1­i¯Ût"¾{$°æ<•üp<Ö5Þ©â!ÖµR™¨yÆ'˜ùd°c4¸Ã­1ˆ– Ñ|Q†.-þ\utÚΔF.WƦl[>µ4³l–Ô*µoN{bÓžÐùŠÐdEà‹jÕKW½ÑËÞÈYOð”­z.— AÛ›.T.úBç«—ÔÈYΚö…Ïø‚SUÑkµíg|¡?Toý‰¹Ê…‹xV6B“$Ë``“lÚʳ4:”ð ž«EK(±Kñ±Û"35íWœ¡Ë®à%_ôBUtÂ÷Ê×mbÍ ÕÐ$¸ˆìÞ»ïßàŽÀÿiäÁƒê¿ÇO>ܽ‡ÂµZ¬¦ö:MÃòxƒi¸Þt¤Ö8î†WL#úãÍÊ^6¹Š¶¡¹ t5]Pj¤Bæ¼®JËàFÇÐfëpsá‘zãprÂoÚ`5ê'tÇü £ü¿éèŠÕó¦DÞÐ:ÓX#½%ŸF4,Æ‘$¡o[¯[9B€" ‹üž¸¹'É÷„¹ÃIùÈOõý ±'¢Û3 ¶é$¹ý®Oˆ8‡Ûz#†þ„i°]ê‹É—]¡7Áˆ‹3‰“p¯j‘·Oó®9áï)¶ä¾àü–sß¡³œ3-ûÒRå,é¾Ky`pÝà½!©m÷.o_ì×Õ§ÚÌ×ü*âëÿ°_ï1QäwÀÿì_iNO`gvwfv»³oT`y,»ì›QÐ{x§5 ûš™IŸ¹kÒæ*o±×SÙ] Ú»kÒ4Í¥M.§òRñ„º‚ò(^½û§ÉÕG¿ƒwIÓÈtÓ¦ä›Éï÷ËÎ÷ûavŸ¡¬ Œy^›W™¹@eþÊ_ÆÌ_Ñî{ªÌçÆ}¥u™¶Þ#sïhrâêœ%Êô%kùBsW]îÒ4ÏæÏè àÖ}IZîkl«åPÊAQ( @ÐÌ"› D¼¯-x@™!`SXLøZgÄÕyKŒ¨‘YƲHåÇ5Yp½'FÐìÚ”DV·çlè àÄoBkÖB¬âøÅ£ïõUÔþNx÷œ¿öƒ¿Óüi÷aHÕç«;ï¯ï4ôêE?pMQ_íFid(ضà›ûùæ˜ÐÔ_Y©<îJÍ paHò§ÖÃàИd `̪³Ù¼EÖ]MþmM>PäžÎ~F›ºZ(… …ÒдÍL‘¦‹Š´6ûB À~£ÖwØÜ%:4rWY¸DÜÑf-3ùÝTº…·L)È9Ûž>@E >úO42à«¿ œâß9ã?î6d·0°C¥‡TÁF €bk¾ÈŸ ®9ÿj1h„†APp\ð7BoxhCäÐ…ä#Ó›£î†-8j\sp‰ÒˆØC±ðqáAfkrŠ\.!ð_d•^w‡`£¿êB\wr.±=ƒIZs÷2˜BžŒª%²óöØÜr„†K«å¿é¦ÂU«ÿ’Ó?æân9`¾jMú!áe‡ÿ²#0æ9øa'¹(üyoÔÁ{ÃcE8 PtËê†Æ=Áq/wÙQ ‹@±%wÝ%¼p­¹%Šb&Cd÷íÿæÉãÓÈw(yZâ-B“!MA¶PfìÛ§Œ”€FÒÏ•TÑbC¬t£vUUŸ{[ïͯv¥Çö©{KØ¡"MÔaèq¥F¼šˆV ýeé±òô³e©gËÓzö{Š´±¯ÄØSœÖ[ .ÒFKÒbe çÁKã¹RЈêí4Ј,Gdó£}LûÑÒÈ3r€7ÔÝÕ@ mGØØ"lk«Òµ ºÎ*À‰ª•?ÙÆkZ8C[˜=US}{ØÐQ¥ëª&[ƒúÓ5ß~f-¡o­Rt 4ËH¥R\|[ؼÈýh¤Õh:(Ãu›7¡ÒÍ€GøÊ$$Ž0˜”`$‹ÂûSJñƒ Ù+M„z„µ%¼ásê‚UÎ,›³Hf/« ÿl°Tà Ù¤@dÏ wò÷ÿ¨Íùвę¬éÔÜE:ë!–³ÀZâªÌu<qyšÎù;i›ÐoùÞjy ‚rPJCÐ4SCõÉ[,Y‰Ê `SXLøZgÀÕ-R;çTyqÆ ‰ë²*ó£ôN‘IP”Då‡r\½|ìé¢FkVãÜ‘Ÿ€F€.íñÝAŽÙŒ;E$p¹Ÿo>Ï5EýuQ_íFQb((ö ˆŠë£|ã`eýP¨ù ÅË x M ;ÊGÜ¡gy »êj Ü´ú “ ¹BFh ú™zÙåw‚V(b Žúa<¾’ݤxUBÉLJ‹¸k¶Š[¶ÀgÞU5™ÇÝÜ%»o¬ˆŸrS¹¾ ÷§RþŠ«bÜãwù®:ü7<¤“¿a ~QºmtɸâôݰUN9üîÊKÞŠI¸KŽÀ5»Ò-Œ[|pœpòc®®¸;ÇFŽÊ_+){ôä ÀãÑwyüX<ŧOKKvIž.*Mø¶ûÿxn¤ÆŠµÑýŒY ÿ&2Iš"Eµ'9eKhÍêèDH€=ZCäé0õ³#tí[šŽ0Ù±]G™Î*ªk%Zy}g±¥ÊØY£ê¬Ö¶Wg¾_þs^Ù³Ý5ÚÖð¶÷yy7w Í/C†SGÁ3xך5Bwðº¶*D"Ã1‚’I<„ü/:Ç"ý_£‘ieYi™ÑdÍhwÌÐTÎÏñüC”F&ÅÅw7a’¶êP”@%h²„N‘K%ò$ŽbRønj$ð“ŠbrÅv™¾Ú7º—hómz{\ošg²î)s'  ¿ÀuƼ2oîÙ‘Í™WæÜQîÆpA(ø‡£²WQ‰„À4[e2×n9 j;IfÌ©ÌqÍÎYuöeZÒþ•ÉÿšÌ¿­5/“¹°¸¬5Í+Í1,SЉ§À‰p:$TÒBr(… ])ým͸•K0ÇA¿R) ` ‹ ¿QëŒFŒE*wžÎ…Ëœeón*³FérI"ä ‘½Ù…°÷„ú}¾úµª``唈¯TpØì•nMA¤R…ÿu¸¡'Üë}¾:ÈŸœDÃMƒÆ!_Cÿáã Ÿ>¡9Â5WƒMk®lì Šàêôú¹²_ç±Q\gÀÿì¿Q±½;3oæ½7×ÎÎîú\ìõîú\Ûksƒ)…¦áðîììzZ’6>1M•6!Ä`C‹0˜#)Š*U‘ªTU[q„35$¤€ccÌÕ¤•úGãš~mTU ± ´ª`õíhv¥÷Íõæû~¯wÈìŠøá)³­| °ü“ºöóµÑk¢'Cáti䣺¶Ï‚1àDdn¹œeƒ©åAâ²|ÿ)€J(~± x?W=¾(ñþÂð+Žb¨D–TŽos{5Ä/UšŸ„âÇêÛÒuþO;Î4&©À) „.]Ô Ìücúî}î›dé’f"XÖ…mÚÛîóx`äíoÌÞ·ÂáwÃ3‚¦ÆaHµû+ý†6ÏHÌØPô3Ó³¸ Z&OxªÈVg#Š$c·F‹ò¤À\mn¾PZÈ ±o6©(’[‚ÒwBRk¶¶Éó¶iYb0Âq¼m¸·E-ç¤x>úÎö¼míлEè œmÁW\Á[é®ícÎ (þwä’/•’ÉüÊß“y+EÅÃØò3ˆÎQx§8ŽAˆÅ”RI"ðQUeëU™':–X‡dG\~þnfÆïWåMgé5gñqÞßià¯rUÚ/ð ãa!04¦Úxæu›K'ÊóëˆcÌ]5æ*¹îöÝp&õŠkšÿ†ê¿èòO9Ë®éÞqOé„«jƒ  ‚!0†CH…,c+ù3¦¸E@‘kªu±žòË.?€ê?#S‘çø¯ï2:˜}#fßc¨`$Þw0Òõ^¬o닉b=W¡€?vSuËžµ¯mÿñ{FïÑHï;m]ÂÃÑîá[ö¬ÿá/“¯KDº†Â°3î~<@BØ‚F,™ÝÉêf a#¸º·ŠÍs5Æù ‘F\˜?VµîOµ±‘ÊÕ¥ªžIî½ã6´ÜYøºwÁoêÂ6~xiKamÈ“gç3%‡šØ‚,a¨bÕh(y6;Š\¨7ÓΆ§'ëb ÉzGÅæ…KîkäîôÌ×™™ù÷þò–eâ¡Ía^H{Û} Јg¨U AãE† ŠÇÐÈìí }GLî7”]qØQZƒ°À” Ñx ïPйca‰’†`nPº e8ήРŒ µ’²Ù%o¶kÛ ­?ªíNª;ÌÂ퉂dªçãŒeÿ$,bYqö’rU«ú?ÒÈ„«âºîÿ)¾%ù&Ýu«d(™ßÄ /ßkµH ¢DdY”eJ1ƒ˜Y„õ2*Pæg×Üv–_Ö‹/g{o¸|·õŠOoÚ/ð ãa"P ”˜f0©T˜ˆ‚ #~6Ê:á¶2å |ᬘpú?w .ê^h²“Zé—ÿ”³|²ƒF` „áÄJÅH ÉŸ5|îô[;÷Mâ \w—ý‚›¦±Çù¹û¾íöyà5TÍ¢‚gGÜÕo¦ÚýsûãúÎvÇ@Lß½!wgÒÓZK9ŽfÚ` ™U»IaK°ã° X•Á¨’ÁO€Šªª‚ÍA’½$;ÐÿýœIЈús+¡•ùpÊÙa:´šðD戊9Óé™Ð*§¥i/﮲±ßM¥ø²«â \L€áU;f øh•‰Ä𼳋œMǬ,2ß ð© À‹É£¬’uT*¾á ÞQ«ÆÕÒK9¾Kù¾I—ÿ¦§òJvEÚ/ð ãaá±%˜o°È•‰¥kØ&` –Dü¬·”ü¿8‚àÛª‰±ìrˆqÍ7¦—^S}Szp§XÀ  –@DÉìCBZHþ¬idÜ]Sqü?÷üëȶñFp¥ìðÀ¡øæw#=Ãm©ªàprËÑyÄè=º¶ëk6Uç}Ë¡¨nX¡È€mHœàÀ"l ƒ¬B!+.;ÞèÆXÇ5º-„»R=îH¸¶€¨ƒF÷»Q+Ã~³{˲õp ,b‚PwNõÙ`ú5r¾*|¹qÉ`ÛÙ¦Äk¤»ÔÅ “yŸÇ 4a ÷G¨Ÿ”åsí(îñXoœª1ÏךpòŸ6&Ón†§õ q o-ÐZ—.Ÿùjæ«»3wg ‘æÅK€"ÐtDBÓßvŸÇãÀü‚}+]%:¬%D²¢E¶ÇRíþÎÁ88${0˜ÉyÓp¯ ñš”%ñðÖÀ2sÇ`‡ÂaãyžN²–«%LE–W2,‡ˆ6ŽòBhŽ{«¡ï²òo ò“Ù»’©ž{{Ô¹q9±Q0÷²3oR­œÔJÒ^Þµ hÞK9^hyW=¡Y¶Ù0)Ȥ²ÕU!Vbì^–¼$z:hÞOiáfä^Ãk”°2âyÎ^„™_‹Å_zêGó+Æ;²ÿ¶«ìªÓ{I.™L©þ´_àÆÃ4Bˆ@yn‚ Ò=<ꆩE0Óˆñ ½qL/›TJ¦tÿÕœrè¶_¨þ«ZÉu­ü–»©•ƒ•_b D’@*Hi!ù3§‘{ °þÑüÀ¶I‡¿TpP ÂCù²c8Ü mDq(UŠD{ö]{#GÌÍïGûöƺ¥ I(ª ŽƒR!*ÔZ°@"‚R4¿ç}pÄ£çàú $‘îÇÓÈÁ˜uÎptРèõֈʼnÀ³~5§ê\­y<4N×¥M#£ÕÆéPôt0 4:Ó”ø]mÛÖ‚ú*$ÃÅT¹ÁrÏ)ˆçRÇ€¯ù·õÆhCâãPüxÙÚ?×µÿ‹ý2mò¼ãøÿûg-Gbû½ýÞïkûõ‘|qb;q Ü¥ 41‘ÆN|$¡•&šÈTvHrŽŠ6!¥k«µê:­ª6µG„³$ä‚•ueS!û™H]ÿ !«û+Û¯åß÷}ž×Ïûû~žAoÅñ`ÆÆÿ¤u:\P‚ý—[·æ'w¿½{àcú¿82===ûaÕŠ•€²°„€I2»Ïô é»K-o®eÍÚYAõD¹±-™núKmq À®µš{£"ç×Q€iWœß[ÇïÛdÝU§_YDp ªA F£T»&ï7ñÜæZ®fµÚiš£ÎFQ^WfiØ ß·‰ÙWZS¶rk\Øe;Ò¦#}[L®{"µ°«Å±ù¯Ò†I®p\ve¼½?¢FEÏUÙ1)¸OÈAIí™eqS«iB›-RYÈóëµü;œûªaÑ á!màS´–byâ¹f>gœ/fmã:ï¸èžà]#‚{Xt_7ø'”ÂŒÏîñõ0Œ„1‚Rk,*Aà¢@¿Ð²htþŸôÁ©`„·IΫR*[oq®aÁ6.ŽÊ!£FÅáyŸd ÊÁ¬àlÁüi£X‡°r®‰ ˜)РÐlX«cÎpTÄÉ·¢›{b ‡£[ûãMéRÀ@_¢©¯²áPEýþêz…ä4( àÿlcE8èL* –¥æI¶6¬wü²?¶íÝØ/R(Û–îIA0ÚTíýGtES4þ@¡o6N•$NU)Š,ÊXš+‹,Œ\ Å•G‹£gK'K7¼n_“]KKPPÊDs”¿×±êÏűs¡ø`jÀUƒE)Ž:[‡ñŸ/IfžNb,¢[›@‰UK–ÏÜ…ç̽»Óß¡Èw4RRf´ôý•ñØ}¦ÊÐSf>ð"Æ« µ)Œ¤­f]Gr–ҒЙZ“ÀÌžÔ7†×«¨Î8ßžd:k¤–„¹r¥–að¹ÙóÌ‚††Ž:¡£†Þ”›ŽäzFàñ,5ÎÒ®¦ˆqï&ª%ªÛU­oOÏèÁ¼#íñÈmQ]ÍjŒ¢x”Dˆù ”aŠŒê~042!ú&'DÞ›¼U™£z^–Mjz.—M¡œÇ äFÿ¿„à7¼Âb\.˜ÐÚ¡jJ ˜Cï‹¶sZç·Jñh»IÛGuž¡œüËf?¤É Á7Å{GgÆ'ø˜zp†(Fá€|–f1©PA£„€Qjõ‚y‚óè]C²RuŠq§°DvŒÈ…Ûi3I¨é–ý€A!”ƒ X!Ø‚ùÓF#“¼€ ÖL€$õ¥à¼‹)=›Lc1¼'ÞØoìÔ÷¥O=‘†ƒñNü`Ókºç4²ŠP²ijF'¯(y Ò<÷ºÀ¢Ÿ-Ý,%¼¦ë¥Wß®l|;²å`´ñÐÿJ#½‘¨&Ÿþè–îªÆ_½6ˆ(E@#ûÇBôSÅÑL¥íñòäÙ@ -Ž„£‰ãþŠ#E‘¡âäÉp| ¸ú¯%ñÁE5¥ñ/B‘/Š£'–ÔœUFΕ&#§Ë’Ç *à3”gž˜9îPøÛ\yö™éû4rïÞÌ÷$wîÜY¸ O£Rß*zCÆc÷™¬ƒ‹-^TQsfiDt/”ÛúæXºéØ µÄ,-IC{’íLÀ«¥9Áí«Ém®•Ú’º1vy!©B ;×e4´$Ù=µr{®£VÚ÷rÊcu¢C(vmHÙQ-v¤oLí5R[<ÝñH­)¶"G9œÂ´ª&F¹!‡†%{ÆÛû#jŠñ; <¬N@q„äq D]ªÕÁ¶q½†üÒø†±]’sÏ­7yç5ÅqY³sßÖzÿÁø®ÉÞ+¼uT°Ü#¼mœqÜäR„3¬ó^Ô{®š|Ÿàcêa4""¸šD³(.š^…U¼©}‚HˆV‹4A„(üodþ¨És^g»Åù¾b½ ŽaÅ9$ä—k0Š¡ÔÊaÚT AA9˜€‚-˜?m4rSÌ =0Íïšè™¥‘å” Jhà‚ô&¶ÌÒH¼)m0ˆm{«ª!…‘-Ý•õMk#¯ý4v ±¬€R€àµ/ÑÐr(Ò̰?чðãw#)¢è»ïâŠ4Ï ðÓSYµÀ3ý6U[{c[¹ºR@Hî6ßlBÊ Vf–F.ø£Ÿ—D,Šfœ)Š *Η%NGþª,‹ Vú+¾ U],ª>оôé’È¥’ÄYïÆÅ‰Ï–ÄNÇfŽ–fžÎ%Ý §‰s 4rgæ{(rçMÃûô4MS(‰eÑk7{ÊÊíYaî^fé[©ô,3t•[º–å(·v­°t—ÿ_Šë/PzV©‰‹(C"´àÊ;«um•é¦ÿäoKXvÆM;cˆCÁµN’³É´çSkmNs­²#nj¯[ÐR÷£|#%pÆ9é0™:넎D¸;ÉîMœ˜ölJÿÔµÜ?¹€³†¾Ç;&9dtÆÛû#ê‚ÎwNHžŸK!Y§›GB#<Š¢aûDñ|-ø&8Û%Á:!{/KÎËzï˜Tx› ~M¦ä†1„[0*º.ÊÖÁÿGɱGrÒ…>Æ}SÎ^Ù÷ë>Æ{§ÿ˜¼`TÎÕ9¯pîKFß”vá½å6k¿*äÿNtuñ®ÙüwDë!ÙÕ#y?×:n® Éùäøˆ ý^Êý·õòÎnÅùgýJt_¬§ ®ýŒ­Š3,¡ù¤¸Ñmg Ÿ°y×uùÿÖ:¯+ž ¼uLö]1ù'iǸÉ7ÁÚGxï5É5&9®‹öÁ~C \‘J>â Sö—I)$КŠjåí\ÎaÎ1I‡ÿÉ9þ<ÀZ'©¼[’gŠ+ S‹á8I (JS$ƒQ$¦zŸÏegix ÖMÒh6ưè§ÿa¿Îž£8î8€ÿ©ÂH«£§»gzνtA¬öÐj¥Õ A@Bpå—´—DŒƒA²$¤RIqc;®ÈÑ0W¹R©8•"ÉK*˜ÃdlÄ¥›Ã\ŽìÂR~‹WÈ/`TßšjÍNwïÌîöïÓî(ÔÖ›zàšòDîšð¨£Gr‹ž…Á8A”÷g5`r‰¢Ì¨$X’ø]ÓÈÿË"ÙÒ°€1Ò$Úl‡R~ ©}²íaUÐ߸ñHfóû©ŽéNà4f6 öµtv­^íC‰ŽÃÉN0C_¦£'“U˜¤»ycw²íýÖÍÝ«ÖCÈÃÎ ]ö%ÚûšÛÀ3@ùl]ü2bDA‚ÇÁ¿1'v¬¦ùtmâñ—ÎV5ž©J=0ƒɳ±Ä@EâLeræÌéxr¦ºåY ŸUeÎU‚ˆ’Oãéó•éÏ*RçÊgã©Ç’Suk*~E¡L’(&{_ÿG¾†Ó÷¦¦²‘)|]‘Fí@q~_Ó‘îß{ßÏR¤§ŽE}Ë ºH|½ËžÊõ6”t½(¢4UTÔî=i}wÓãÒˆ{[’½ÛêÚ•vPÑÇË’Ý~Ÿ´½YÛ™öíluíY£ýnmáÖ„à·‡ˆ„¹^{GÊØ€IŒwZ½ÛR4õ“­‘;¬ü²'8ä)íÖŠ5GîsLƒQYµ\†ý„ßbøÔà]+~ÛŠi¡ëFpÄò„`;êŽ~ê.ò…á~áUØÏÂ]JA>rhbžÍ;1ËqIœ_Ì[Aè otÌ]zÝU#Ü´â7õØ]-4n/ô‡~¡ÚÄÁ„Œr\h–ÉϦø¹=Šo æ2JÀˆŠD·˜3 ÍòIĸ ò)ï¢íúüÁ©J¼)ˆŠˆ !²,;©ÓBÎe<=húãWݱaÀ€;2n–ŽØAh\v‡‡=‘ #ô…^~ÁÛjùË©XÈå¨NF¼¢(~A)šå0ïQ§"Y’ ª2D rvH.ÐÎsÁ¤+tÁÂíÜ0+;ˆmbQ•a øÇSü*qýQÈÈ!S”¨& À›g™ÉBjÎhDÇrOêÍô'6>¬ !=«ß€F_ÓÆÃ­[ ñûŸ¬Ë*eÕpȑԦޗÖIvj~sÿª Û²æijÛŸêÈ"Ñ–¨<ì¤ÿô½? •=&Ûw¼¦ð‡%‹àDAèØÂô@<ñÏÚÆºä@¼é9^Ÿ:QŸ:UŸþ¸6uº&u¶JdòL%TÛä³@@tÕ&Ž×%!Ý<±“‹2Çk%u¯.S à3ƒ…–šiÐÇ7Ó_ý#Оššúæ~j¸Ò.òùº—?)ìYGï _ϼÝËÝï.Q¶UI¿Œz;jžÊ¯«™û³¥HU,1oþîŒúöc¢È® 8DÝ›¶w¦I±Û%)¢$Aø%akïuGÊûÖ+…?o¶bc ËPPõ<×ö$h¤h[ŽæÛ­¾íi׎GÉ“­‘Û,2î ]6ü] j‚#WÕ¨¤2Nâe’ýYååx ÷Óß3JN[•—¼u“fÙmO|\ë%7 »¹ªG®xb®Ø˜µ+Ž™óœƒœ2¡N…ˆòy(úп橳#—¡¯/>¦—]7£·Ìò ùµ+U >+0IU$MW1(ÔùÒ¿£WÖ2F X/2užÔKîuVx.±f#B0UDxð˜`…a5ʹŠl½’á^cþVõ¨VrÍœ´K¯’²[Vð–™0+{Ì’¨A9ƒánQž¦šXVQÆH㩃B¯:Cd>QޢσC.¹K'XÙ""‚âd"«Îý@/ý“•±#Q©†E¹àœtU·vh̼¬Æíª2Ñ |²$ Þ0,k ᎲÐ+€ǨÉŸiä1kä`ËæÞÆ G2›÷­Þp8½ LÒ×ÜÖŸéì[»å×/¶¾¾tes|ékKWþæåŸv¥ÚöµtÌlêoÜx(ÕÙŸh‡Ž2›²×'ÚvÞÃôߌ0Ã’®Õë¢ð‚åh¹V|¼¶õRyËPÔtª¶ùŒ®ú¤¢é\Udòq¼Μ¨‡âÛ|²:ñ,ÁÊÄ`Uê“êô`MúLMj :y2Þ y\Úù°>³Äš£P"È’HðôW÷¦ïMù­F¦¦ïÍhdjš‰Hå³û¦3ØF=1þ¶­c þÕ‘Û"BóžÊp:Ïùu'`†U‡}ÅÛÓÊÎG¨þŽþÛÖç·µ€F´•5"/(ª ›Å)rsÜù‹*üuQÉkÁ´Q(ÊâÖnlðîn±öd w´»RÖÞÿ®l÷ïšFƬа'4©íŠ:…å„DâÍ£ð$º"bä!Ó)Z˜ò ±÷És‡ôø]½úŠò…¯ÚáÏÕЄÖ£z鈫üªU÷ºYˆ §Rf9™ÏÉÕxį'ùãr%Ðås7#óËÆÍЈ=ÅÊóe,å ÒQÖD—í )êqWMºÃ#j¤ZfÅœù=Er~ã.JнäÓ-¨û¹²„ˆEÜà‹C&O8Œœ£Š*•Ø «ì¢wÞM30b….Áìzðºû•V¨ŽC<žHòK*åx@ØÃ¤ Ž€( „I.UÏ­¡Ö9ú/otÐYL(¦ðª"0ïÇ *AŽ?¨%$14N‚ŽlDsþª‡F]åÀ‰ëÞÐU=ô3HäÙš„5Ä0¬X*û7ûuÕuÆüµoiÁöÜ{îÙÏÝïÌxÆÆxÁûŒÓ„ ¦K¢.QŠª`¼A QJ “(BU[¥!TéC#pYC©ªJm¤ö±}ë&µYêÈ› v¢6•šŒû¿LÒ¾ðò Ä£¿¬«±ç^Ͻç|ßïÛ$øùhð\Ø*Œìê1ç(w«©d³Š*ñ˜œ™¨häôÈþÛUÁ±¡gí;³}"Å̶}§w¸qícŒÜ¸qmié:Ž–n@#M÷/cŽbâ®s¨pòÿ7…DBâÝ“ÉfX—z‘ `RªmyéÉÚ#»WJ#úÇãMß ŽŒm3ùD~.ƒò•W>ìáU_hšø\Kä0ós/ _Ù¿<„À$prG—¾»5r%.½™m‹:r÷ŸÔ-9»f²B7í°»)mw¾4!–+qªÏÊx¤N9Ã&Á7ŽËsqy>h_ðÚ“Îù õb®k.,ý6jOLU•!QµvÐtµ®æv›oDýWs=ÿòÛ/fÛfò-¼¦‹¹žª‘*[(Í¥r6FPÍ3¯Fé©.ä6\ »ûbC¤´• °YH¡hövHi‡­k„e”§L(•Ë©qS‚÷ W$*4^õšçò}ÓQÓ‚¿ábR¾ô¼|/(µmYVÑ ,Ëme5ÌÕBXU8Í- Bˆtoz´úYS÷Ǥg¶Ðq>ižóºJ± /¹ Vq´T<½;Ö¯Ý W¢§L–ù*â’JáàÊšgXr5;ˆû<µþÃïûŽŒm““¥P*U…ú®ÎÎæûé·FÌ!LCA.N‰o°ª‘›yHÇ>ª$Ãcdž÷™8»ýÀ™Ñ‰ÛUÁé'Ÿ'Ní?7’¢bjÇä“<Ú­sáÀ'–7å< Ã@”ŽQø-þzùÙögG&™³;ž¿œ?> ŠœÀIF'ª|aˆVX« V›í 0Ûà–|oD;BÚ ?±ÓP±C®O´¶%b°;˜ÁÖ@íëW$ޠޝ´[0Œ,_¿±üÑòÿ^ÐÈuä¦FPBLqŽƒÒgäÝŒB®¢žpÐ/]NÍHE¸"èž÷d ¯ªñ¨GfÉÌ£¥ºúŽ_ܹR Œ_˽<cŸþF¦ršbÏu]P$UŸ‰t]›‘ú¤¸ûë ‡w‚ñK£9 äG;’#éI’ÃcŸ6ÌGÝç£ÎE¿ŠxϘI³Ë>£îÃ@Šv¬•Dî+Ü:&cÊÖj31FÈgËÔ:5¾]è}«¶kÞo¹ìµ\Êu\ZÞ÷»óÐ,3yËpãø\xâŠÌ©°u:ê|7hús±q!j¾@½ÛtàWÕôô sIÆ(Ýìó¿$å¿ùrÔø¾_þ¢çjbH4kã9Bdêú51ªf ³" Êk‰…›pŸ ¹H£½¬rœ‡Cw&×·´[ß ;®Dýð76\Ænt|F”% >E8¾OuD‰tª\E²Ô1FÜG-O¹ÏHó†éœ/öÍD³QÃ\Ôûeé‚ åØ3×!·_÷ZÎGå_„mœhDIîí$Îß²—ƒÎKqÇtØ×K)jš+s%ªVTãü>hùk±ôº×Š{Kå‰TA†¨U¬¬F¦FöO=±÷̶ýøø©ñƒ‡ojÝ jSúªCÇ'5ŠçTlò²/<>ÀœüÖÞ³ãÏݶ„xm趯ûÚ𦢑3£“Èñ¡}'‡'°r0.QJq 3ÅRö¸2ÅÕ-#èÇÁÃO‹‘Š™›Q«AÊÅ2 Ez£˜ÖÂõÙÊõÝòÒÝnª-Ì )A®//ýçÚ'Y^JßHYbÓ©m©Š=ÝYwWD–ŠºT';òº£Öí*ýŇKëé¶n¸'omô·vb€umî.:ëÑÊ‹/íZ)…WvÕW?x"lO<ñMoKy‡9‚bÂMRíH.ÌÆ¶àÙÇÜWv‚{Ä/á85ɧR#3ÙҢߵèµÏ„­‹qùïAù°©3ÐçŒEjmT9¾-ŒÃQ<}GJYè¨LÅÜwµJ´½K…ÓùûÑ(¯†åKÅÞÙlÛ?ÃΣ¹†Hfª•2:UM”£[MøNÔ{5ìžÏu¾¶] º~tžåVSôaŠ9ÆØY3á³í³µm—³÷oV*oÙk¨Îv%scc=ÄÔÑ q&ü“×wH7uH 3£É¥Ò×>!Y]u!ê_ˆJÀÀù }&îÅz.ÖJÂZkkðjk­çr˜ç¤n}ÛßôVüÀIÖü?ÈZkÇYáB\z³®g6h¿â¶\*v¿ôoá þáœ@h¡­™¶~4M']ïDýëqÇ`…£Bj0˜[? á®®Ù\ù„ß3`_á±¶Ø>þ±7kÛã¶¢€ "SÜPêU#•<(CÀµËojdâÄè›$ØÎ<³}âøŽÉG6ôJËF†>WåüúG;Š-yáY–Eü裊@>~-ݸ¶´TÑž,%æ‘\S}ýO·ÜÉOm®ÿ/ûåÕuÇñÿúggj\öqï¹÷ÜsïÝsîcï. °o`Y@QSŸÁ8i&*,,, m’Ž ’0}Óp4m䡉IlûWÛ?ÓÌ'5¶šZAžB˜¶ñ/‹ö·ašÎtìL°Î3ì|çÌÝû8¿=çÜ=ßÏwxSîÀ†¼¡Mk7zOÔX§6'7d~CõæÖ¼ãÏ)2T À'«h}X4¢õ§¤îô©mÉ>Ò”Û»Oëi.îjT^Þ©ÖVi;ª”æ-úOê}Gšò{÷³¾¹/ âíou÷4êÝ™c³/õ@¥o·Ê§YôºœõF.ško³²i5þ¾oŠ,,Ûx§[@«TdsKÌ)2.K†"*°eKˆ±,¡xUÖó*½î)Ÿañ1­tš†>•ü ZUM˜6õØ ¦©¨qàÕ<ãFl^‰Œšá)Zú]û-ù ÊQËΈ5§ƒJö÷X|žÅnKþ š1kÂ*D<܇S@vÉÉc^Œ‰Êˆ[È8µgAÉ¿¥W ‘µzB´«*Übׂ¨¸4îÛ·”õ[¥@\`åM?•UO€è8—Ä­V^Ľ$å³’%zź–ý\-¹SÒõ+´üÎxâfì Á²þŪ|Š(º=cŽ.™§<ÎÉ’¿£Ø~M ®š¡¿©•;ôBÃÅKN—é”Q]%Ú± 8¿¡§°SAdÓ9pœÉÙ;Xp^ LêþßÊÅ6ÉÉ8aD9¤"¶B#KªéP‘ 79]×q*q`¹TžK½úöÞv`ƒÁÖÎ|äÆg©¸³Wv5œl>|¦®ã\²³k{]±b ÄÉ’–…N¤½›ê: üê–8ßÐù`4-‡d°¤ñ¬BNYbØH—Ô/Ý•Ž=ûft×phÛ}5Ý>Ør&´ã÷ñÝ#ë“—ªš.Ç“WâÉK•+ÊèƒêÄÈ“‰ ë\—¸XY©¢þÏñúˉªŽFÖµUË>^äa«‡$rçÞ]`ÏïýóK¹s÷@ɽÅE™ãeÄ9±Ë ¬ñ ?½¢¯¡r†6fl¨–­ñšé½‘FŠzÚ|ÝÍZO°DïO±×²{R¹Ý)=bé”Ú—r÷·€´Þ(êK·f÷ï7»SÚëMFpH+.–[×›nàw”)˜0;dç9OÉ‚Z6mù6þU¥•̹Ã7Õà -ž0üSft•ÿ—}æ‰\V s3Á;1ÜHQíŠ(Š:GVaQvðÑa؃ГЃ'~Ó]<é‹Î+PU€ø,Y†´)¨‚D8›Hù¥‚1cý§4Â\¤QC,‹Ãq–‰ ²‡”DÎ+2oVŒkÑìÐ Û@X?â„’ )œâ ¶ß¡ìQ£xÜ(™¦àÑ¡Y#x•EÚæâV‘(a¼B\NHMç5ÿ‚îŸfE7Ìâ9WGÄp Lˆ“LÌDäzÚMFµR˜„)%0k–€éO±Ðœ±4-á/1à $$*NÄB&™RNÅ<žà ÓZð7ÒZ­Öx…ÀD‘ÇN€v.gW]õVå"^æ3ÁJú’Êý Ã#ð <@WÐ!t ÿ/i—³ l‰YŠ„p_áä ßWÓZ†\7©'ôà¸=>ïg Öa€0“Ô…Ïîéx§þ`Ã@ªcÙ4Rß>ÔÐ0\ß~¨¶0RD‚âDÏ–× 4´¿“|e(y¨ãÜÞŽkvºàM1³ñ¯ìLÀù¡º§›:%Þ®_vÝÓ‰ƒ§7fZ`’3 .úѶ:™%”YÁä–TÑxq]òÃʆ?U‚ñ5®èë¨ò†RËK\œ&)ÄÎ/Üùˆdš;wt"cÎÌ{ä¶»¢û*ïÔws·ŠØ¹D#’¿h$C‰FÜé¤Ò›TûšÔ£ÍÚ/÷é¿Ø§õ5³îÆìÞ6oo›Õ׿éÏ´VºÕûzÊw¤Éz­Ù×ݲtÕèmqw7ÑÞ”ylÿrëZ= é¹*"H FFƒ4¸ÀâLèáY=z“…çôð´'rM Žºý3,zÍ,žÑCŸñq³ê´ì¸\X«P…ØÖزçpR…bEŒÀ.ØØ%ž|O¢·”ØŒæÿ«74åöÏkÁ)À\9°`•—dääQVµ¨Í¨ONs¬àw,I Àˆ‰¨h. Øæõ\7b ¬lŠÆ­à¬Rú”D#a@„`že—Œdûûrᤘü7Ì™¡Q½äû’! »Œeðh•—!¡;ýŠæôÀ Ny‚]’ g'pn™C‚Æ7oÿ¹–÷w›gÑYï×À¯3ÓrݘYâåÐȇz4Œ3%0Æ`jÔE(r'9ôˆñ.˜(  _á "ùX‹þÿ4"cÔ¡äL‘û*ƒUF ,ñœ…%žÕð‚sô±y?7ŠºÂs€v”—Î&ŸM:SðDsûPÁ»û~|b÷ËÀí[_ÐEHr¡®ÚÄ[{œÞÛ>˜:<ì8ßôj×–= ŽH&'ulÛýVsç¹dçàžžN-·.àÇ |t¹ª¹ÌëƒÍJáEÅ)ü7,Þ]\’»‹áµ…ðçåE^ÍÖ¹í®è¾ÊÞä;±—Èqš@ä¢|«¯ÞL·<,¡é¤§7•ÛÛêýY"秉¢#ÍÖÁçéKµæ¾/´'Ho{FMn_¨ævUrÛcø™ Z»ÎØZI«£rI¡̧Á‚åÖõ¤“4±)C#F’=ó>ÑâSFà‘oã_Qczà†žR$~7iEƬÀ˜å_Pƒsj`BŽy"7Œèg´l\‹¼gµ‰Ä‡lÞ Æêâ/‹D%n;r‹Ž)gþk¾ð¤œÕ·Õ±_§¿QœwÀÿƒJãÝÙ9žcîcw}!¶×»Þ]ŸBb쀪’ßG Q‚±1F¨QT•Òª* W ÄI oÛJ­TõECTÑJ%Ûk{×A¥oR0éw M+Õ•¼É¢òú§ÑŒ53Ïì>Ï<ßÏSwÐ**”®l‰ DAD¡Ð…_±*ÀàžÿßÎÈ/¸ ±˜„¯—„ëáä=½öŽšl&Ãñi^ pÎu…ûhQ˜ä\þŒ„õâ'5E8‰i7~Û«~S‹R"@#jˆ©å "Ÿ•ãHs39Nîeºâ'€"h>oôb*?…¾ä‰iÓîŒG‚OUßr·œx&šÎW#SNÍæÒ zâœI§d7´F EqˆÇ£T"4ð6+ʺÕO¬E‘p².*è¥8mÑÃ7²PÖ¤•xäÔŒ_ö·ÄÚA=CÑijˆ\îB¦Ø1x¶³/o´öãÚ íýÐÈÀÎïyL‡p¡G›ö}Ô5t­óØûGÎuôtõmû.&¨~Û <´«׎t½ØÒw¥÷Øù¶¼´¨FŽ7µ¬häÙª›z®g€°‚Q­€á|WÞ*ø¨óèÙ–C#û¿ß1ðöÞn½PÂ=JwÄkÚöÆ­ý—[_{í­3m‡šbµU$•᜽|àrûÀHëÀ•ö#àÊÙö'Ñ.üZ#¸ÛŠFžÅú¬¾s-ÖDÈ ‰TmˆÝ;ð÷ð±F°?ÿÕW_Îû‡»MBÁì -{ì®Ô¢µöÂwJÏ5³u–&ùA ›–ó“}îÉÞ§¥ïd·6ÜåêU_zaµðÖˆ®L%¯<ñƒi¡ˆ(æj Ä *FÀ_!ž,™*ª¨ÓÓ4ª-DR«²ŒwÜç! þ&šš²S³,áçf4>áUÎéu[UÄ=±%޼V¹¦ ªªf"õ9³É8)_#fŘ•ê׊˜"0…Q<‘ìkìüD‹}©ÊšÕà `ã©EU%$a𨡫ouÓVðð)b%²VÕ”V™Õãsvj’Wä«‘œ‘¸^”Žó üDd¸H=P£Na4Œ“­T¼e§²^Õkg¢°ôk%ã Ìøïš0«ü²Àžî€KЛË>ð–X›ˆÅ¥à Kìlב_´‚F.tôå«‚‘ŽÁz† ‚Kmýïv^OLœӠؾ¹ùÔ¾ƒïõ9ÙrðåôL‘²¸]üóÎ>8äãöA\Ì\êz2@ _kϰ¢‘g®>ÝÔåŠX<ÉåÛ7ny° kdÞßààÁÇ»w4i ËYöØ]©E«ôüvhDELIÁ<€ä‡FÂÃûŸ–FÖžèq‡{ŠÞ9îmêÄüŒû¢ÉÔ—‰BȸÒ6p¥g¨}c#] xH¶ƒŠW¨D%v5ÆB21ú7œs±÷èåÖþ_vƒFÀ T¾íB +ù?¨ë[z-Q ²„ÔxqûÎGy¬|î?|8ïkÇ/6úá"ÞyeÙcw¥­â³[‹Ï4²DáÅýµ"÷NµFNxZ‰ü¸»èôþ’ÝE=ÍWB!ƒRÝÒyrO¬g±µ¬¬„V”ª©çíªÂÛjÝõnSƒÙ\ÏškÉžý•­Þ«»¢÷æÛ®5Ü­ ¾ÄEÆ‚ŠÐÅÝQ¯>ç<3kÏ -9Ng½ø´Q1ã¦?-m8n­«-FôŠvÝœS—±â7ݲÑHb2R3i¸ãÖ_*N>GflM¤çvˆ ŒZŠøOöëí'ŽëŽøP)jÃîÜÎÜÎÜgvv—sÙ { 1`®vRù¡Jk0° ŠÔ¦±±C©•Õ¦æj'l/ ¾æRKUûÒªR«äÁQ­Fil`YÀ;nÚäÁÅÐß8Š"U~0*µjé§e´Ìœ9sæìù~ÎßÄè’š2"óR匕øT ϨÁkzd¨È"E$hÖájAÙ¥˜ CÉ籊 ámËrntC ç<‘œ^6§–ÍiÛŸ%Å̓F$¼SFé¼9­:œ5â³zlÁ(‡ãœÀ>Ð ë<9VhÂå¹lÎ Íë‘Ûr –R¤5p)œÀHú­Xú# …‡'½aÄsJdÑŒÏZ±qñub½™Õ* ‘‹xÇÍ+,t…ái,32ËÇ †-f¸÷¥È”'² ÄA#Ð h 4Â#ê àÕ¬kÞŠ)O|ʈN뱜ƒ¾-ªŽ÷6}â=dÁ†ÔÍ“‚ DÌÀÅN¦w™hyÝ*è8’¹ÐûêÛû¿Ý~d¬óG O‘Jq°~8ñ8AÀ¤€- L×z«ô/ô]L=·ï£ˆî Ý“ûnˆF^mÝûD#W]ÙÑ£Ò$¼/ØÞ>×ÔæhäÞê×¹·voeõîÚÚÊêj[S‹ÂÂæÁîcÓc÷I=° 2þÓ­\Ô«PÎ å(ÞÙg§6J#x¬[=™’;}o¼(ÿ¼Ý3’´îE;Þm&½Ã½¾¡^Ï`RìQ†zä±|ꣽÆXŸ6’Ò‡“æh/”1²îþècIóX'hD„H»¿K ÓVõ‚Þôeü!kFMÌ™‰œ\r[)…Ô{“óÆIú˜”˜§IæGjôŽ]0C3Vp^ Þ–#Wq¤™gÝ®oÊXtq”ȲJ>x\ƉÓFå¢UzÍ._ÆU³j|ÙŠƒ²FÉi~›K¤’(7ð\A ·Â¸M‚C$ƒ$4âÏç>¶›rj1hdY ß4"KjpÑçÌš,énA¡yV`·² fÌä;QC3_idI Í+‰£Ø/~¥°’H¸eVxK.Y´‚Y½ì3©ôª\á3Ò„Ï휃HŒ8>_Úzù ¦çÕò#6-‡²¾Š«zÙå|ü'Oéz5’Õ·/)Ñ)¥ZUx@‘ˆ'ERÔI™ óXL2<GøŸRíGvø–Tùh‘Ì;¿"G#C¾ÌÛ—•ÂÖ»²÷WØþàýƒTxU]3˳F4«=6Z†ßT¾älH+=Å÷;ù~©>û׫‚óûû'RéŽC ‘w÷O K¾6ü.`-€ š‡€hš.óÆöý`29p©k1Ñ~D1ÙÑÿN÷Ñ'ùÿ¬÷j:†t¶ˆÝÝØúŸY[[]]½ÿg­­¥dûe¤[ìñF3ÓàÍ4e·M@î´Î6oTªúÒÉÆ@¦¾`|§çL›7ó<ܱøT½¼É?ÙbgZ¬t“uºÑ—n.L·¼éœéÏÔÙ æD½5^ï›h.šh-<µaýy\ÊŸi°2»ÙJI!H–æEAöÿô€9Ú½Qч»íÑ”1Ø%ý²7ð³.}°Ër¾ð€@¬‘^c( ذÆú¾´wÒù¯õÚëx—ÏI·4Ú­®û¾öHÀF!Y˜©˜êX|[®Îé%›¾Œ?¬FÌhÖÏ*á›ZÕïùÁçƒ1¼n™d % hò;œr~"оO›ÍónÆI|ž—)Ö ÄáS˜&Ð{¾HÖ®Ì)›ñi3š3b7´Ø´'ø®Š±Iæ+¢Œ Ä`A&i bZ ·ÊÓØÅoíÑÕ;bù'ž`N-½aÅæÅв§.¿®WÔ ˆæ]b‰i!M’¼)U,ëáÏqù-9zBÖÍÕGp ŸuKâHZâ$‰ ó–^z]/›ö%¦¥Ø ½ªQóØ Å <†tÉ\©¬ümŽy] Íʵ3Ò3i­¬™¦KÜyÍ–ý…X>WXùYrK ÞQ#ÛÕuœ°³Aó8Ŭ¬¹é_k‘Eüƒ£Âªœ´½{\¾(Ì q Ã>½UDˆU‚2¶ýƒ }¡–ÿÕt. árhš‚f ††g@.‘+_d1ÃkHàYä–`‘|`1V Xâ²›SâÀ›¿‹ÿsZΚÁ¥|A¯ZÄ ðÒu3¸d$®˜HmÄq0 Þà©Îƒã]‡A;ÖG¨ G@Pp<ÑÑ68Û3>Ðÿ½g[ÂVË:ï4ªû_ªÛ3Þéhçl§sòù®W à @òqZkïÏ´J'_¹Ð~joEƒÌpSš%χw°£ûÏÛ;Þ¯íü°jóc÷I=°®Ôt n—¯Œ wïzneuíîê½µ»_kdeå¾PþµÒÜØ„H²p8ÓâË´z'íñú@fg ÝàI×›“–ªÅgZ§êíÌóR žlQÓ­ö¹]Ú¹Gi JCÑdSád³=Þàoôo32Íúx“çlÛ™&Oz'x$³é<øïkÄž|^xÖÐ(4±¢çÇ{õ‘ŽÒˆ6Ô®]Èo¤JÆ^TO¦”I >‘ÂcIåD¯6’ì¡”¸¯ðxRëñŽõìåö×q/ÔÚ?Üã}­k½÷õŒöiÇÀÄ£/ñb /.«5Yã±ÑÈ’Tú©]ô×þ–  »¶`§9Vwcñ[82_¤xÂö§œ›C¢ QÖHžqCpÂöŽ‘\î2NüZô‰¯bQO,Šå FÌAŽV>/G¦´âE­ê˜THH”Œx†p~§B2MÀZ,QŠJ‰<ŸwN)žsúºiDìøŒÎ‘9©lN®lA¼Œ‰¡%–ÑhâèÈ5#ñ—³_ç±Q\gÀÿ¯Z©ÞõÎÌ›7oŽ7çήwmcì=¼»¾ðA øÀ(¤­ŠãõŽM¤æ á²1½¢„B ¤"özmcÀ"R›öŸJU¥üÑ*mQJklãƒJ[©ŠBM¿e«ªˆ«VŒTìO«µµï›yßÎ|ßo‚¥"óVÀ3k„ïÐê×øB‹a¼ )Ê 1èÑŠ<Ü/ä KJÙ´»aÄgíø,©‹°y_Ð\†jðœ$ñ4À) “/KH9Š\Xpq&çiq$éÈFõ=o›RJ&íêoð²íá)œaD%ÄŽÙeÚ¥,/j¡ lÒ¬:¯„~7)`¥b7dY…Èæ:Ñ$üϔФ]Ò£× °ÂrH© a6íÃ-ÃÆaûP(ÊÅ9N‚:çæ$¬ 4%ó'`ð¸ëÑÁ±¶ó 红E'ôÄ„6"k~á}šFÔÊoê û¥^&qà«ðdW¨fxßèþc0Üa ¯TÃû%À$ÀxÍýy©§¤ýeøÏˆÓ›qŽŽôôBž98Þñ/{ÀÇ àýE§"ç“$Ét¹œêƒ÷ƒÝÙä “½U[(<‘ "häBdÇ ]Wk“ï6¦~W\ó±û$ïÖ; â ^€®ØÒÜ ÉâãþƒOhdùþ?v=µž8r žk)|¨_&kƒ`V#M«¨z© ¤Q2¸µô|³õrÌxv}ù÷¶–ev›™ÍöhÔzs@(0ܯ¾LcAf§op»ÿÍVÿ@s` ©h¸¥è¶‚‘ÿCl¨m…Ïé$ï·¿nühßjiÄ{¦ÇwÊñŸt!^uŒW÷Lìïwøžßc÷ì´:·i{6ѦJ©.‚cÅ8Lê}ݱN$™&,ý²KÓèú£í+=®uº;pz¿ZèWd0|¡Çu“ÖÌØ]·ÿ´˜Ñ‹ÿbVüš&Šdް9Žóá Y*˜d{¦„pqÝqóù0Ô<,1¯éÄ„\žÚú)»rÁªº-Ån+ñœF@‹Z|ʹiT^£µ _|öW#0$9Á¸ÇQÈրЬV{Ý[RÃ3JdˆNX‘Iä–Y0ëv J™,(Ãh,QMàó–´Ê)£xÆŠÌXáY;´h”Ý¢ýbAöù–a‚yA¢D`~ª–Ü¥¥ÙÓçx#pVçˆ]* /²ùºG3‘áFÈ'I:G`¾SAÐ6Üœ—æó%%\«nû6Þ¡a8n.RŽÍ—EÌy`Öç‹’Êä¿-o×Íie÷äð”/ {yϨ² cå(O°¨H ÞnÌé牻JôÏ´–ÀBXI $„´¶ ‡íC P( §W*Ô¹| !tEG‚À¡‡&Xxt°nð?+#çëái31i—Oùbk~á}ò:´ÂóFü–U³¨UÍxcÓftÞ¨W‹eØ"h ßL4fÁàôf5’\ ²IIx€Æ:¿Õ}ÑJ­pä«öH›5Údd6ùF·”¤[×¶” ´”¦[JÒÍ…CMþá­à–5çÁç靸‡ž¢{6h<Aö>¿Ë:“\-è§ßÏÿø[ÁW’r¼xA•°”@7ƒ€‘— èÙ)K$˜‹ÖëNa_;B¬_Tt–G;«Vz\ólOðd7ðFÆŠÌ 6fþ`ÔLÛÑ5oïŸ1þ®Æ¦iùÏ *êU {òB*|5Ÿ€(Ïj§³|q¢€T,ð¢(Í‹ ÁÉå(ú´^;§'”8PioZñf9$_ÒcÓþø¼»§Õ;‚æ’= / ¢âÉå]xöëÿ›Ù0e”Ïi‘;öÆi;1mÇnØ¡9-4ï­o•L,ª"‘l7VYI Vp-Ùõ·¬è¢·zʈÌá;ZdVõ‹A ÆX„/šC<¡àÌŸ¨¡¿ªñi36ã­œ3#7 b“jü­È¤<‹$®Œaã2Œ>žçÀjBE&\Þ ²yÍ®¸­E&ôÄ6Q60\?”²º“[¦”Go«á»fbNÝÕbSvxÒ¾£×´ótÊ÷Tä4Åa¹Î*ëgÌŠY3ô'od XKÌ,‡$ BZH[†Ãö¡P (”ŠsL.õ1(×øÎVeݣȈ<2ܲÀËò:…ÈØ}E /šUKztÁ|ì´ °œ5bófõmµbÊ Où¬^yZ @WÇ„Pw×µ wQ€F+VÁsýí.§ú®8ý;vÊt¼ÔÓŸî<4ÚuŽ'{$ðÿÁ}‡º³P€@r&KüÛ'+‹To¦ëÈÅ}Y‡@Z Иӷ=R7L+¸¹ÞŠïþM]òZm×{›ßn\û±û$¿ªORI€{1hÏ®=}|? ‘ÿÆÈòò2hä;ýÇ)Ü,4QýAUà|3hÄŒ´Ò[í¾‘¶Õšªþ¡f@dŽ=m¿ØèYÅ…¨fª†˜˜l ª/ÕÎí.ºð´?ÝZœn-¼Ülg¬úÀPcáp“°ÑÜ]k|îÌlö§Ûh{TBh’0\,§Í>ÓµZ±N¥Ô³ÝÚi§ø5SQu1&Ã+ˆ‡[>'Õ,E@&†ç,•ƒ !?LzK‚q#€—RÍ+=®q¦ÛÒáëB /+Qæ³òa;]ûÿYâºU9§U-Ù›®3å–å“9Êb^XÄ‚LþÉ~þFu]ÿ*5Û³¼wßþî»o™Õx›±gy3ãÕ,6! "‰À€Ç †ˆ´¡›˜¦M0¤ È4‘ Æ6ã/5JÔ~è‡VM©ª*K Œ±ÇöxÒ*­*ÀÐ3¸ªZ…u…b*1:=æž{ï™7ïü.'òƒþ‹)F°¶0ˆf¾%ÙÝ,ÕIë_âМË#á ¦È„#rM &¡ßAדKàórà/zùJ€ðvè´v†lDzb†%ºLý7§õØ´¸n„§ÔÈ(N‘@JõMR‹­‘dÇЂ\DvD1¢É5ªnàÈM¡bR‰NâpšD’ZE»’¶ X†Â"ì^°òôœu”j±)R>#›£šyK4oò>¥ Y” +áXÞ"q”À!–ƒ¥!Y²Šœ•— lË*f­Cvï# $˜“ÊÊÉÊp,’<Ã,8Q#RñŒZ6!Å&tsLõ¥uÿ 5Ò/,›¡ˆ(F lýX%ÁYÙwÕN©¥0ÂpH© !¤…ä°eØ8lŠ¥€‚dÊ¢F^ÒŠ‡ zˆÍC](žçiÀéa¡"E³ÑÂ{slDÿ´ÃÀ<ß’ßx_‹’q54©Ffp(i§Õ § ëðÿŠk¯Û±€Ls/’{:00±ã{`’¡øN÷ê÷·”mlˆÕÔV¶–mzs[ëО#š:.ì8I~- .|²ØyÿɧÝm@¾æö†6ÐN©«@f–‚GŽýeÛ?«lúcYüÒªÆO+š–¼í>‰‡Æ EYÇK¼ÔÑÞ1ÿþmàÇíÿàÈ;w@#o;A6 Þ•W#ùgjdý‚F :{7>ª®j$6*¼}ëVœ©+:PÃ:1‡iAFDÊá Š' Å;iq­SûNÌú9åì*Ï`mîðfGÿz£o;±>·o}noÍ’óàŽ‰u eO„¥-еáù¯l_£ŸÜõ¨4âíÚ+w5soîök¤0gL‚2§^‚C/ nx‡VÅ<´Y-/mrÿdŸû¹5Ë‚Mb«ÂÚÉæÅΫl4ºšÕ-UpVå(èáكؗ2BKýlÿocT‰¥×\挾-Užó_@ЇçV„Á4›C3Ùˆ±°P=ŽEÉjU½€c¶3x͛ű¯43©äa°Ä¸¶áQ=0é§µc GÓz`Fñ'=µΑ9¨A<¿ÇæwðÊŒ^5¦–Lk!>¡&Iè–Z:c˜SzèªÜÆ ¢åYˆÉVè,Ùž9ÎËÛ~ë6ÇUsB©ºEª€"`ŒOÕÈÉ[`³8²³1k%ÌS«Í…¨„œÍ0¯jÑ\~K‰ÁzþŠK¡¹' ˆX7Î_mCŽåË{¦»3ÃPœLó²)ò(¸M ¿QÌ9½:M·”+²™À²Í†ée*“ŠXÁÐï*…_¸K“zeʈ¦ˆ–ø¾ ¾¤€ŸÎÖlËu{VnV¶ÃþÔVžN)‘ #t“njÑ b«®RI $„´¶ ‡íC P( §^Õ3u `ƒp›Ûjyf³´]AÖ‡†ðh`¤¶÷)…_ºÂ3¤$­–,ù÷µŽê¡IbÎJÁkºŽÀï[Ç4/lcŽnk9¿»-#„xÛ¢)ÒØÞ½ãe`2 íÿQç ­òB.+'eÈÀÃæì(êÈ;°ñùÞÖW[:Î7¿²¸€  ‘ÿa^X-ði8~4ÒÓxp®åpÔSál´È¡_¯Œ_©n¹kø¨ºá“Ê'yLc x‹YeÄÐ6úÇo,hìñﯻwïÂ'Ç;qp’C –ü VؽٛØä8Wãéßà>[ãîÝô5Rpv³»{³µ~nmÁÛµêó>\,ÙÙoKHd,ÜÛpÔBÈÆKˆ“)Ie¹­Þ¼ƒÕ¡®­…§Ÿñü´ãí…U­]r|Ñ{nµ·§N¹Šcm˜âÄâg+õ;•FäÚ©=¹§öåo–|Jb9Ži°ÓP sI°P«kµxÛ*£±ÎhÝ"ï«3ºö¸ÞÞçîŒç¿Õ £¯íRßÙ»Øy'›Ä®¸¾u5t1‰Ç N)ùêÿFæœÑ1ìOj%)Ã×#—è•Õ¿$£rÞ‹¢s“¤ä²4Oga”ã¥,=+ˇ‰ë}ÕŸT#sFlJ7S$8¥„RZζº {‡@…þ’6ÂÓ¤ôº«$-ç9cßÜàBKð†þ"0œ Ú‡¤’Zù¸VœÒƒÓjtL/†¶;'E¡­9Ì?a³ßSØmø.’’‹FñE¡¨˜=¤pÚ~…“t1¦`ŠYÃüzW)º(ø´âcÅ{b G Œ‘ð¬¼î0Ór†:ã"äLëá ¨)tD>Ö£?s›gD_;ïy†“Ö R=6:Åü÷qø½òº˜5*ÆÔèï ?¬íoRdÐáÿPŠü‡G´Â ¤è¼ì–}£bFSSZé¨bŽkY¥*óg}ÕâÆECºoX žvù~¥ÏQ¨ |Øö¹33ÂpH© !¤…ä°eØ8lŠ¥€‚@Y`—µp‚Žààˆ&þ÷„|˜b—Œ`ÿC¦‘}Päµè3ÍïÁÔ×?-O©ÁäÌÉ Ä⛊™$åO‹prà2± õûv~?±ó ô÷¦Ã‹UÁpsG†";î{`SíöaŠS6» I”ÀYš—äØ|’±ku]Oý¦ƒ€‹þÅC(Ñ|ø\Sûàî6ˆÞx6‰½!WžÀðÅ»´¶åJeóç¥ñK+ãO4òØF¿™æ)!Žf¿~lþߟŸ¿swÁ!÷îÝ›ŸŸpuÿèk¯3v K!õHÔöiO_­Þ[ãN¬ÿûuþÓæ}ÇüOØ#|<§ý܇Á`Œ0n|IÓfÝ’¦ ¾p€F‹Ò&¡MªtR–•…ÆHQ~]'õ‡µ«¶¬Y¶¦9$Üc©:USŽ}ÜHÓVmÒˆP'Ûøây¦(-¾bŽ«@ÖXÇ*m[cìK”eFcº+•Îi³:ë}É4Í–Fe.KE©5‚ê²Ó§^#ÞâëWpÛ‚l»ÃZÖÈÒ©xIp¬h³’kF(ý·}¥+…~Ó­÷HÛœX;Õ=ä ÐÆ[RéZ—7èEUÙÂÁiDtšÈuWÿÿz(´kúCøP˜ë ™{öt© ~x?ÕÎ?ÝYÐÛIõ…¡.¡7¢ WÌ}]ò©°n°C:á7½—¯·_éôâ\ÿî[L¶vN†íÑ k¤-ãÛûË®&‚ãSú­“Ìñ–YÆ´F™×Dû¢Î:MÞ]Ÿv« ÅsUF ÊÍ8¢U ›zIižµÏ öyܼ*W¤Ks¦'ò*É<_¶¤µÝí328вÂ9ïÒu–­€mS9h}´½{ªíÈù¶4 ƃ‡×«‚‘Ž÷'ýG⻞ àsPV†³PU-î¨lØår×,` N’@‰F;?¸´§;ÝcDZѶwA2{­·ßdàô D÷wƒI`$ŒÓ*®®bÄ?n ]®ܨnÿ²*x¹.œñ²û’ ûSmøjM諊À5§ÿ‹ÿÕúЪÀ'ÞÀµ²·?õ†>sížÙ¹éðÿ¦)tÍ•1­ýÂù:¯@pµAT'{zž}ûøÉ³ï@òÏyú|òë_}L¢8X0ig±IV¡¦5âÞXotÑFiÜ-§+¬WHºÅI¯pÞ«ÿIA`ꌬ £[ ¢Û¥ŸyUÛòq½–P¨7¡DNjQT[Śεˆ#®u÷›h5F½yQ˜òå_xÍsK£õÜ”·0ÖXóä7IõòpCAÌ×6Àð`œy>.Ù$Ä›ô#M`.–Š@ä”×h4œmÁp…VÍà Œ*ÑS}¦þt˜=ä‡ö±ƒ¾¿ŒAŸlcÎìCÎD¸sï;¹¶)n·÷ÿTú9ˆ%Âwq}a¦7Èô§õ¢?‘zÃÜ`ä4BŸíâ>ôsG*†5Ôª&óÛûKÎS6ËÚ–´¥‹ë´\vSïXbJçÐ’EÒòˆ¯¸%UdóXÏ"à ŠfSj×ðŠÍ ö%]ù´hýšrLs¶yÚ’ñ‰¼JFY¦ì³‚mV¶¬2%‹¬ãЦ G7«0T£Bëõ%±öt5aăG3;w¹wÐð_ªBX„¨·–‡LµMú§:غKP“9›³q­trgÇŽi?ÄÃÝѶ÷@#ï¿°FàÃsM R¹¥DÕ8â W«Ã ‘ë[ÂÿŸ¹âò_Ù¸\ú¼6ð‡úôô?w¾ý»šÀJÿ­êÐåX“ÐÕÁ/«Ãð³?×´gjœÝE TŽ’"•JqñÒ¥gŸ=~úôñ¿jäÉ“' ‘ß~úÙ?4"ÿ¨ 1Ÿ¬6èǼ OZ#±Ö ,¬y±t Ö‹±!ÙĤ©T¿Û„à*B‰².!/ê“SÍù#­ìþ¤@ƒ!j¥I”ãÀ*eTþ9p©~ÝÕ<ÞjŠ·”$›¹±j>Õ Å ­üÄ6}Â'ÅZÄø6yòMqj›låqÒÃM5‹Ñ&@‹™pëâncb«͘F¤˜GŽ×Î6«i%…И Õ8y°k£4òœRDìk`PƒiŸNK:Þl& „£¹‚ªº8ß|M÷ÑÞ¼áýê€ö—`‰n¨“é HûþÎ~½5uçqÚwGn99÷krNN®$¹&  @Bë´ ! Id±;ã¡jít;­•R,¶ ! (VÛî>ìÓngZu½_êª#­7Ô.ÓÝÎìv­º?–Ngg_bò 3ß9“ûÿÿ?ùÏÿ÷ù%?t—f¤WØ’Õj%p’Ê#±;ª•)?Þ—8³lþŒ®øžÚöXyE.;)¯º«sý]]7+WßÔ׌sÖB‡~!Y6¶Ž2D;ÎßÔUÜÓÚoh æÄÒ[BáMêò") hdV±->TåßU¯ü”)"± ‚¡9_WR$@A?œð'­‘ã݃‰Ž-SÁÁŽRG1 ŠrßË›¦6nûxãŽO:úá·{‹"Ãc!bôžÖîc¾Ã]ýãþíñàˆb²kûÏÔüÚoÖ…aE@,‚!;Œ… ùsEð’þú¹ÓÈ9wèŒÃw±.r¢®ç„£óZÜŠž3®Ð½’àå2ßÅ ÿyWètMàËÚðµšÈÙò®TÍssv Eúù‰ ‘ï=ú©Fž’‡ˆY¿ )D¯$aç+•JJG«7æ[¦Ö‰ªdÇÍ·J‡\ºI·1Ve9 ‹òäF[óÞjÐõ•óksÉ25ϱE*Ö­3ô––´™Æš q¯>î1D]¦D½~rµ!Þ`‰6§J#Ù“^Ó”'g¬‰41,Áá(†s„áíšȼF†#` é€a_H ¨F#æ½!nm%NS°+4Çá ZØ*K³u¶¼·Ã@áý°v$¢Ù‘Fæ%“ì¸Ú÷º C½ìh¯&×ýÕ˸(–¤üx_â|«²Íì7Å‚‡šŠ7]c&ö2¡êcô[h}É`Ž*xŒ'x™ÃY½‚€¶÷Wt[(™åónëìWÅ‚¿²¶ÚçNq/²YMÉ}µý–d»£-šS~­.ÝK›IBa3ÑÍžµ±ÀŽ#þy€F ²'«‚yu„vOùú_©n¥("0ªLl:0 ƺ¶ý.¸û#ÿ`lÓÎ6[•€PJàÄ~£Õ/ˆ¡#¡Gƒ¯ÂçŽFló¶CÛ‚Fhb‹¥übe4rµr^#gSmƒ¥Ï)g÷éò®sß…ŠÀ—å›å¡+U‘?:ýŸ»‚'+»/Ö†/8üðÖ•âγ®¸K©šgï §@$‚°$ù‡Ï>[ÐÈãÿ§‘×®C‰ñBÝ=Fs´YŽ×fGW›¢M 1M4.VU5NµêÇêMcn ˆw«£µ†q€A“f°*‹ÊR“¦ã– ,ŠqË z%Î)32²Q¦£ hu¬5;±Ær0ù¡GÝúÃ^ÝñáP…9êÉm2õ­RÚ)Œš_¸cu V«dÇé,Deˆ”š´¦Û̇ÜÖjõñ:1æ±ÄMeÉnš¯1jdljŽb ŠbÊòfx±4¢ñC¸ê‡æŸêöõ\i2t:°1À!ó R„‚¥\)­ušööHû‚Úá°ðnP핇z’W74½³‰:Ð+:  ß¡^‰g~*¥üx_âüE,½¡/œò¾‘*­@¢(«äh¥D¡Ydz‹È(MaDAPe*(lF¬zÈ=P<4–]–ŠþƯ¼ûüÝ·ù1³¢ý¶h»+Í Å3RYÒÐ$†Q$°aÏÚ@¼»Jù$8$˜4 €™éÐÎxÇ–÷Û7g3ê4ðBăã‘ÁÉÀÀ´oGlÖ±ðÀ/íN 6ªµRê‘ ¯ïÙŠˆú':·NunOt÷?›F&W T¸º™!æ[$Gß¶ºÎ;ü眨³—+g*ý)çÁ v­®÷|Y×uGÏÕºÍGÊ^z-×µÕRÙ½b倵귶—fìþ“µÁ¯ÊC_Ôú¯¤N#>k98„FQŽ N>ýô‡'?¥È‚F?~üôÉÓïÿñO¨È8‚¿ÌWÊæ±]ÌmdÇ=šÈdÑ4bˆ{µ]Ù±zí¤‡ŒU«6ç]oÜ߬ÝU›‰gIi¬€3ËI4;]¥QH™,¿\«ÖßmÔ$štS«uQ>ê5Å[“×”€ïºÅ¸Ûx´5g¨AÕhÌTedÑÊA³I †’4ŰËbшë̶å7å~PkJÔkâuÆh}ª4D”»-Q¯Êe $Æ(QíÖõ‹¦‘ýf¯O;Ú+ #›L;ÚÓ,j"3KE2Љà8εª##ðp(•JU:’¡aVlmÀWTÃ=â{¡gЈv$¤ßáöoR¯s2¸GÀqäMÁœò³}‰ó•T2c,¾/äÏñŽœ“HþeZ™‰08Oâ"IÓHŒäT(OJžG†Äœ»²ã;Á>+Þ’ŠîÈ+ïkʶ”/äER \o©‹g5¶oU¶ry œg’„e†»~=å›×wÀÃÒuD;· îö·”UC/$Ò\§³1æÛþIø5ÐÈtx×[}6ÑÈ+ dڞįvÃ@ã¾mñÐ <ø(ðê3@èGă Yo¯a + C' ZΕwƒF Î^ª œMµ –>×Ë»a—œÁ/*}¯çÖ”²’@*”JŦóÛnUõí)¨ù}yûOäOŽ®TÍÓ+å’8&1,€ä›¹¹ÿjäñ“ÿ hÂÓì‚F¨R•åPó‚F M¦X¯5/ZU•þSÐ-‰]¢^žôZ&Ú¬¯7ê;KU:ìa‚×`“AgI %Îcòj«uØkжè7k'ë³'êrÆë´n~*iè&œ†„ǘh±hãÚVp"I§# Å'9Lɦ+èe—NR™$†ÀL²–¥aV ”¬8øoöëô7ŠóŽø©`ï1ÏÌ3×ÎìÌììéÛx½>°×°‹í=lcãB+NÛ{ú"%`cRªªä_Ðpy½»> ‘ú®}ÑDÒJ! JZŽ!†„V}W¡¿5QÕ¼´lÔòè§ÑhW;ÏóÌì<ßÏÓfK3~€™i²![qL´Ó öD“¹½ŒÁ”ž!%‚’z7=-˜Ç{”á¨z´‡‹ZG»•¾UXoAŒ‘ )gÿr»8Ö-ߥØÁÕ• ,¯bv¡Q7{óÇ…£qЈ ?_†‚Æ¢–á~u¬OÞÓŠY¬Ãœˆ¨kÌúòþœë¦T=¯V~mtþÕP¥"m. oÖsú\K$†{±¢1ðz–¶#ý,\Vën«kæå2ÐÈ Cɵæ†ZýT•õ‰¼¨¬Ô RykQ#÷ W·k0ƈÆÅœ2<Ó58€L‡|?ZºFâ™#HÆoYm5H€ì¼µlÝކ_ÙÓ²µÖVL®È(¦Èê8zyv×/€@©Øþ©îïDÌv$;÷.µßÿØ)ù–R-•44 Ó½Wµ}®.¹èƒFÎ{cYçÁs®Ï¼Q˜ûß°«¹”âWÚš„G#St.ƒ>ô÷ªÚT¤A-¢åÞ® Ù»?^ƒ ad¤Ž@3òxœÑÈÃGß¡.QÀ!<Ͷ—rr§ÚžhÄ–jµ%Ÿ®FLgZlÓAó)o~2àJm2õ»4Zý±póxJÇåë‰^Ê÷Ùmoø¥¿e¦Á4éÍ›ô%ƒ–Óõy)~ÚgKz—Úoáä: .•n+Üç[%jY R‰Ïáù|\¸½ªøH«%ùõD›²ÛÍÕ˜0­³qVý~D:ËhÀpÆoM7&fÙÒHA²Í8냇bßVÑ2HÖ‘ìÎàÓÒˆõ­hÑx¿ñpØp¢×|8J7–cLÊDb\º¯C:Ú+vG»Åãý¥#Ød„¥Ñ¤¦Òn}=ÌïF3†±õ,µ_i ³Ë>Ò¯ür+æèDÃV®‰f²¾¼?çš—Ýó¢óž¡äмF¤u˜áy iEz#ÉJ¹¤¤V‰ŒAKÁC ³æ»¢ÿŸ|í=¥ú¢)ÿ®â¼'–_5×Ü!’²?‘••z¢‘›¢N¾á]ŸÊ5,ZA"Šb—d›ê}íðÐtxl ,C#S±!ðL:>TÈH 43:ÄÒŒdÉ-$IøF¤9OyuGÿUwÛ‘–ÐDhïé®W"3ûÎÄ_[¶F&#0rIƒµ/6ãsîÈ%O42WÓu¡.<·>žu<çúÐÓqe}ÏûîMHÒhV’2oÐ’XQs)XŸß÷ÄËÇ!-¢s“Um©‹fkœë•|Ølb@ò,òèñ¿n¯¹ìé~Öãù¸>zymô²;òÉÚ0 Ê¥ÚМ'ªˆüC òìðÆÂ·öø/‡,,6€JS Hg6^æ)ÛD{~ªÞžòF '‚&ñÄSKÕâD[^"è8Qo>ÝhK¶K;Êt¹?6é¤[%ÔY,ûëíévËl‹š¨Ï;ÝP–j²$êt“2ÑXð;N5À`”¤¿xjãRûu$Õé€ód;ìD)±F]¹àLl±O4:R5ãœf¸²åTcyrcÑx£iµ £)ZƒØRœ÷î&øÊœl eK#pIŸšðIo)RC¬‘àØºÈqe$’L-æ;Äú24œ0ŒÇ„‘œ;^ — »V Ží2 ‡å£ÝêÛ} “¼cýr±]FØD`-GI‡:ÍcÝ–_÷+€+ËЈ2Çbêhœ­,âIZ 0ü?3ð¸+–Þ5–Ý–\W•j0ɼø?«‘ÏÕÒëjf{;/U%Ö|itß0­»jYSõAÝ=×…ÚÛÆ5óÊšy©ò+¡,ë~Qß«ºfrþCp!W~©”Ü–œ8‡ GC’ÞødúL…—§ A:º¤k÷:Kq'©/j)!‡ŠpƒyXš¡ì%2Û †a)^g’$õɘûùæðLǾ¥ö £…®S±ýÉøþ3'Ã{e‚õ¦VÍÉsu™<¿>ü‰çÿT#—<]rwœun&0eàøcemç|Ý»ìN‰‚²ýîÎj;i½ÇVyõGU;ŸõxÎyÂÝ„<ÑÈgu‘Ku‘óÞ¨Àò¤Ž—nhnYxððñ¿Ù¯³ 6î;àïíLÛIliµ»º÷^­„Ø€Äi@ Œ$‰í&n) „°3™sØØq<‰‰¹ øÀèX |Ä}ë´Ó‡Ît:™ÄuëiÒiB-!ìÄϽ|ô'ì6ã¾Éc[žŒw¾ÃüW»ìþa%}?ÿ'·G8yÌ’{÷÷v¿H¤ð”Q9ª›sâ6Гì4E;XÑ¡¹ŸU«r/+ºù¤‹]s•ˆ^ÆWŽ0¯ ;HêD3{ÎÅ_í®¸Œ«q¥™^µa×Úõ±ì™tÒ^–p–Åœ:±ƒX±?Å|JãN2f×ka‘¢U!˜0jS®Ù"%¢ Zž»ô 7ÉuW^Ú'¼YQ¨ÁÔ¨J¢ü‘nÙ«Ž9Jcn&iË—F±£$áD§~©WKUˆš”Èåå,»{óß „åL‚¹ 7à‡@2@ÃüÚ^…#Sˆ94axƒ]~[ñqœÆèû¡V¦”ÉÈ)fb.ÂlH1ï¨Èçr½/L®©\ fBÌ^àT+¬%­p[S—ÖìÈp– ùËlM×d¨ïl ¯ó•ëlÅ-ª"EìL•[TU ØÍ;^pn4ö|a .UwnÃ$ )z±¼ë‹¶Cn ‡¢¨‹6Þ¨éý´5 A1c[þçÖÐ ÐðžP@’}(ÍþßYû³^EqЈÓîxøàჭíÿLòø•GÞ}O)W@à¯àNìÖGÛtq÷ãn.á4Ä=ϪU;Œ+Yp—\lÒIO7©OÔë.t±kN.é`£Vv¹Q±–&À.aÙ¹cÙ  ×l|ÄZ²Üfˆw0ñ¨æ\ïË‹YÃÇ[1´ —3RYù…}Ôjs¶ß.0u h‡Œ:¹q›þƒˆR‚¿Æmäbž OÙŠ5_ÑefçcíÆånŒÇÕÅr²“‘r:ýLH; ¶29*rÉÖ/Â@qº„ý…*”/1¯K¾WË‘'zôßo膈¿.ܵ½”Ü&+B]Õ;f‡ùÙ p±ç>…Ft3AÅRÐ0ÞÞ_ “Â" >;~…ê¢ù–¶"Å[6Õæu¶î®¦:ÍTåýkÿ9åk­ùaneèª4g†¤Øª »ed9d“®¼Í˜7Is†¨˜å}¯òR%o¶Üï“¿µ:D«•í*© '.„²Iú'âþìdƒ\U°>&úƽ‡/û&>ñýyàØ Ñ3/ÆÆVC“ÉácçF¦~:<ÚÕãkêØ·k·M_Q«øb9UŒé¥Ê…Ð(œ“³Fü q0 ’Ëþ#‡]oi‘¬F”r|H_ŸÕHãÀç­¾V?”à ë`Þyð¢5²«4rµñ®Æ´RÙÎüë=Ë+%˜M0}Úê6Ö«årU!2j±_ßÕ÷¼ç,üSó ×›| 0É/Þ‚e¦ WÀ2³ËÛ Þ¸ÿþ·üø/Eîomptê£SYÄâÀ9¸IßÍ‹¨`èAFl×GœÏªU©5°“»ØÆÄ톈Ýt¶mgÄmHzt—iŽ3â5Š{¨µn"ñ†°¼¯b~oÉH³~Ñn¸æÑ%ÛJ#öR±“»ÙXûSh¤Dô‚FP¬ X©"‹$†3^nµ.ÅÇ즄·$Ö n6áaW½ÆÑ6ŽiŠ”˜ì5ÓñV!ÞiŒ9MÑ–|i(áâm%Ñn……ÒHq­Çq„>Ù ŠŠ<Ò;=>!gsVÁÌ ?à΄³ôÒPÉI_‘E@ ‹´¸þÐÞò…Cä´Ÿšòe/~>ËnôM¹»V3¶_fKaîô ?åÏYAsAÝ\H}6¤¼ßÿºÇ0L…`»PÉW|[š¨Yg*¡¦S\Ã7Jsбäýkÿ9å.QG[»âÒVg´–ÛË]uÕ]eå&U³AXÒdU†¶@`¢Íî•F^剤µæÝQWlÒU¿¢« ¡dê…¤…1Ň&“}£‰qèt°$6˜³FÎF#á#±`ÑÞ‘ÕÁ# Â5ßÈ'½ã—z_êêÀ ‘QqøX40 Nœ Œ~ÜsðxW_2<ïy/g^íO€yÇ/'}»œ¨)¨*ý¨ÌþH#ŸÙ|ÜÒÈõ|ÛàÅç/¶ào›zÿÐä·R¼´h; v¾\/W“ ¢•6þÌT£@Š<»¨üeKÿçÖç®`!Päfs–%7¶4òYËÀjÍpLròÄ÷þõï‡On÷îÝûßøŸÿÇÒ¢¤¨ž²ÁÙPµ.nNì`vÃÊ3Ó±ê2E<ú•Nfm¯AÜo8ßÅžë çÛ©ÉVâ`±¿Œ´q¤Y«Ô¡˜ºŶÿ@(”ö¸x;›°•DÆXs2ÑÖ\ïkŠ:¸D;i%‘B©R…o/¦‚ÕtÒ¡O¸Øe›>æ*= > ñòI¯ºI‹ã¨QFbÅß7-yÑ-¬8ˆ5[¾4Ró¢H¦»)O,”˜B…¢šwº¡ÇéÅ0q&,0³Í\ÎèçÂÔ\€9;Ì- óar¸SRJËúÚ 3!z>È·Jѧ|ÄŒvéó…÷{™¥!ØUÍ èÏf¹Rv:”ëM6pej1LÏ„©à¶,|Ô2œE ~£kÎP ime†4opuw”Uéï®FÒtÃ-ªþ+ª²Nצ˜º U—!k3LSŠªß ëaœe‰ºjC›åYÞ'ü*/UÒ¤å]›ÖTܦ,P)†)Q †÷Õ¶‹Á# ‘¸<韸òH#ÁÜH¹ê?ºØèÿûõÛÄ}\ûoM°¥$¶ïíÇÝù|ç³wœ÷;¶ãıce+kó²}¶“PØ´AB cíÔmÁy¸J¶“Ú´NÚ&m¬…®”´!еÏý3i›V’ìkЦ©x"¤Û8}uºóÙ¿ï÷îwò÷ó;!ír&¼»aä1bŸøNGâêQo/°g2Ð29§í=Ç{á*üF8Ñ‘tÞÉPB#08hähç¾Ùe*"¡‚Nm=o \¨ò±{¡ýO4¾µçÁS޹šŽsï‡6é°Ù•¥¦ÓÒ6 ¦#Õd.Ê)ݦH¡•Êïê«NY½óÕ«]Ï5>˜‹¹ßY[B#[ïÙ|‡ÍN@¨L1XúìÁòòòÊçmË+¿þå¯T”’Ä JFp-y|´Ž»Lcý”K?í̘h|b]5ìZrô›2ÕÎt¢€Á x*“B*SÔDN¤¢„Œ$QA@ŸÅQD#p Ýš›ÛÈO׃ŒPRÔa˜NZ™cõ´Ë<ºW?‡ƒkRhASzÜ¥«Ó9Œ“nH!Ž»øÃõhöU\Á i’éÇJÑÇÜìtÃZiæBŒ×É„¨Gl+§îöd«=ëuIî¤% „øã‡‰$M‘GQðjüü‰„Loî4íØ NÐ ‡˜¡€:ìoG¶'L2PK¦¡.v8È=L'†ƒDDÊ w%›×0¢‡P¿*Ðt¢Î ´ Á)tÃA6‘©¸¯E_á‚¶ø¶¦(Á’µþÛ_¥¸Ì\á ¡/r%w´å÷è²ûšÒ{ê8½Î]Ó]ÕÿQW|…/¾$_KÖ¼àgñ…  ÈM¶ô[Rui( U£˜†Aä¯=ï{{  ptvÐH,Ô—¬ Þz©÷Ä‹»~æß 9Üúíן—z_ÜÓÜö½ÖÎuìíê›Ù¾ÿ¨ÔïØ Y¢¾ÈE@jPÊÌC™Ài²y:P3üÆ„ã ÆM ‚ňßTv\°A#ïÖvEÎ[¤ÿCÌ–·\²‡NÕzÏ—{{³-…8£Û€!i -B“J%Ë2S[0ã)KèŒ#t©Ú»Úõ€CÎUûf«½ ‘¹*ï'Öài›·?Ó Fâ 424 Þxðà¸ciié@$”²¼òî©Ó X–ª¿-Go&£n~ÊÉO:LãŽ'ÕU…ÞÚõÚu$¾&IM ¦ÃX¡X9É( F*qŠÔ£$Žà$JÀ-èב‚3'ëM7¯£nЈ0Q/NY“VP¬A«åg6S‘$(˜,*ÃÓeÜ! €¾ ¹ ñFÐHöDSæhcÍŽÍ2#·“ë·å'æh£nÊ“}䉩,yM5™ÀB3v>îÎÜQO¢¨œ"•(Š4—g½êÓw2a¿q°ÓÐÐ;“U; ñƒAn¤ ÆÉè¤"z0NP†áèàÒH§ò€— KÜP2ûxß×á*wx»ðCŸl4Ù“Ík ‡¨¡DåÄHÀ0Ô­þfÁ!p,­‡2ÜT—ýYS|•Í¿JÜÑ–.ÒEkþ·¿Jq‹Ë»Åš!3ô”ë\abÉŸ·À™!µù°ì½Ë”ÜÕ”ÞQ?Óȳø—¸¦+»Í–-ð€v‘zŽU0i¨Z”+ÆB{¢í»À Q)¡‘Ÿ´õ@gÿ4¨8Ö½ÿP°gsaMÅÒ«]h| Z¡wÚ6wì÷õý4°oºm7à'.%,3W@)3Á½±@rI!¢Á=':öÀÈ ¸3Æb´‚'•g­ÙBUúNÛÚç«| ؤ5çÁSŽkÕßZ[.Úç+½sΗÃÅÍv:“ÆÔjDª9º7×:WÙùN]÷…šÀ|EËj×3o•`"@#³µhäcKàmkû~±Ö˜@ÉÛ'ÞH¨ãß¶åGÛƒ¥[7) 'šX–²Õ‚.Ö¬; ƒ‹ãõÂT“qü‰uá¼ýîõx “F£rÀ›J†~ %Siœ@ ™‹¤Rµ¤v«O”Æ)9žÊ—ð™Ã[LÓM|´VŒ9Ìãn0‰6žt=tÔšoàã.nÀ“¦ÇŒëä tôR&gâý‘Mb¬9+Öœ{Ä;æácMÄ´Û<±‘þ~ñ—^›"u™S›¸¸“‹6¤ÇÝk¥‘ô ˜‘Ó¤M?n×E6ÊëYL©‘SŒIÐtóC!õÁÐ/ otôÉ‘ ¡‘HH–@Æá.m$ðPÔ~ý@gÆ«~c»Gë(W¶:„½­¦‘D$¨ 4MU ð=Û´á øÆË²AéN6¯éðè†CYý!|Лõ?¡ŽhP‰Bî³–E¦à†±ì6UxY[¼Èý×hä¶®ð–&ïŽP~M¬¸Æ–ýISq_]¾ +[d‹“Š»ÊÜ«ºü›@Ú|E›OLò‰á ÷þ®.¿N\ÔÞàJî0…7µ…À§ûjó=MÞ]uÞU}é§| j‘+ùT0ßÖæ¯yÁÿcq—.¼Ìå-h‹ß+ØÔTRN a2“íþS¾ÞŽÇŸÿ¼ã•Aé;9:ƒêábÁ0Œ" ‡@+'ŠXC¿ï[3Û÷Oz{ÀÉæý¼€¡`@¨ä˜¿o°m§NA&„àZ8k—ÎUûÞ©÷E.VIï[ Ys<嘯÷Ï–¶ÎÛ»OV·]²Hs––ëþ“Vß/Ê·ÌZÛ>¨|éŠ%pÆîýƒM:SÕþ{ûª×óaeìçªÚÏ•·Î:¤s5Ò|uП^³Fa¼*ï¿wæ<–VV>[ZzL‘¥‡Ç‰ýòÊßþòWx¯”$­*dxÐH´>#î4F„IÏÔˆñçËÙ)r¥§1:âjt¦¦"[Ë`h*‡díõh£MüÔæ¢±6Ó7*T¤\Æ*P`÷ð£6cÌ¡: ÜdÒ*0s‰c6SÌi8ÒL·•àŒlæ+ÙûÜšãN樃ŽÚuÓNvº™°gÄ]æqWæ˜;?ºÉ0h3Ç›…‰qÚ£‡qÆÖJ#¦ñMBÌaü÷uþe~Çü_h7 s<ós=óœóÌÈÜ\ƒ0Ì Èåma.Ô=uÕ¦]Û¸«(ˆl+ 3ȺmúsûC›lbí"ñZª.÷¥ÝZ“¦QpÛÏÀÖ6&Mv îl¼óäyH†çóåyxÞ¯'á†ë¢ÿ匒¨QB) –Ôž€FÈÞ(ì@­3ç"ÂùötUÀôDùî(0†™t·˜®6mw”~{‡”׈eˆŒ%E8*ÕÑt[½±çMæƒV‚"1  ”îè>íÙvîâa݇i+hítã™6å…ˆötP®£•(ª”ÊY2ª‚Ǭ}–µÍ’ö9Ê9“égþ·Ï cž& f)Û$i™VÛ4Î €Ê KH+³\ÑŸ…ÂiƹH9¦ûCÚþXãøªl‰0Oh,¬æ\ ¬Œe‚³ÎR–{‚m‰´Ïh Çu… tá#Uá¼Ò¶È83>ðk–EÒ2E™ç¨¢TFµ8[ÿ@ÖZì} Àörøø 8h~oW±gíõIXJ$‚#©R©”KQZ&/áM§÷D¡cW릑+Áã0 €d¸õèO·=2™ z­™Ë½^‡|æ ß, €FþT‘y|÷ùܸã ÜÝrø³ÚC“ŽÖ«åÍ7ÊB÷]¿ßrà®;:V¾Q¾e?p»°õª'8Zxå#¹‚7+"ce­7KZ®y‚×Kƒ£e‘í” n¸jrœx¸ôÔ±¼¼üteå?YõÉs<[^¡5ÐE…=bˆ7q±Jã`5Ô7—ôëcÕëÕªùñî'¥›/ì°Æ÷›b¹±m¦cU5bÇȆ\ý¥zýH=H>ì×_l’EDìFãn]²F?èçãÕ›b~múçå<S²†o5Æw  ñZ¦¯>¿¯4'QA%*„+[uƒµÚ>·i¨šë/ÑöWoŠ×å'`Ëö{ Ãu!CbÝT–nŒõÚd•.^¡û6Åv),¤ÃTbB¢@…“ûù5œk£;à.M@¨saí…¦3LŸPÚÉóaýùh·Ôȉ)²?7‚ð:MÞÉ}di$‰jƒDíuêÏF™®¨ît$mu†axMW(Å\ìPuU%E1 .'Ľ„î1YO~½îç•Â)_nßN}²‰‡’•†áæ’Oˆ×BB.æË̘FruÂ`µ0à†ë’ߦòpQË”Tª?Øü {Ú¡Ö¡ÜÓõÀ79⻣)ÌôDA#@ã™6êm* *QÉáÆ€'ì+¸§dDµ3÷£Žœc͸#Uê,å~|@ÞÝ&tz m@ ö\„ïé ºCLd«J,ÅCE{åßÉòûÛ<ãx qLSÿ7Y`Šf9ç,k[ Ì)jó”:oQeža¬iå‘Ú¶¤(øŠ´-‘©ÆŸÐÌœ“TæøB&Y;¬wFcx̬2އÇ=Þ™êJÊ:Íš!SêÍS*ëSšñ_³ÌR_QÅ·¨Ò|DD`6­P4¿÷-Pä¹FÖ®5&)pB"«59Î…Þí;x¢·åÝSÍë6+SøA k‚ìn~kxõ»ë’¡ÐûÉÀQ ÌДW ¥&&09NÄìu·ÊRsG@#·])Œ–3΃ï8ãîès15ŽJ”WrÇßq§(XEUŒÅTDéQj?-Ý{ÃÓ>æØ7^~å#¹‚cåáÑ-­_¸‚×Ê[GËBW+ÛóDÔ\;ViÎYÇëg}¤,x¨²Üã­ø5Ë™»D]V™å˜%P)†–çÙ> ¤ßþ«üx¾¿v89Ñ\äSÊpDAYHWËÛƒ£C-G~>ù›‘_¯±MgÀ¿Oš& ñåÜÏñ¹ÛÇwçBÇ$΅ĉıCÖ¤Û ÈÅNìÀ ëÆ€„޶ޑ+E@.ŽËغI“Ф©ZË´µ@hÊ*¦MJR¬íÃÆJ’=NV¦!MªQÀZwôÈzϱ”çy“èýÿN×w{;l¼^GÒ 8zwì…§Ú÷¿V¸;Ör(2ÑÙS"Úà£H§Q¶óƒUÌz³eíïo ÍTþ?jäRU[·ÃÄi¢Ž5üÚÝüZn os‚ˆ¡¸†ÄIÝeÌ}³6|ÙþmUëÓžg¶<™ñ´F®xZg*Âoù: Jã¤ÈòžòŠ•O²´Zk×ò§,I.`¹¼ràëû9Ëá"Aª¬¯úìñ ~¢RØó[âþuKÕ±Zs,(L5ˆS5RÂc˜(Ñ2#®ãQ TàxÙcjpŶçö5à…£4z­¡69z¼¦±€«Ô9F@Õ©ö…d%¶é'j•˜/ë¬wËÄ X‹3¨'1š£xQEI*£Tê2aóɯZÆü¦ñ:)V£ŒÕcÌ#>G"`Š×¦K#`¡¤©Æƒ–DÐ êzPZ‡Ð4IÊò×4néKƺ8²Fô§£ro~Ž2åûB¦¡.{oDòq8%1œŸ ÒÈ>Ù¥ÿŠ—É@Šcvx©¾|tµQã`$zK–éTD:•rߤzÃÆˆ4Ø ˜Ü:Ø¥uYXJ§C1„Uÿ”wÍ)%·¤‚91ïH#‹¼û–X4/;çŒÎE9ÿ_¸ ”ýÊR‰ Öòˆ"kr×ÂKŠã¥–œÑÖƒ? ½°çÐmÝoìJ~ºm9ŒÞdá­N{¦ùÀxhÝ4r!Üùtöœ ´áAQ0D>)¿ëi‡à{ok{R#åÉ„(œI· ž}]©ê¨Ög"Á©°©²í7*"6½LQƒ¢ç)JO’`¸7+ZÊ¢Ïâ÷SÚ&¼ZÙv½¤LrÍÓqÑÓÂYþp/46=øÛß×ÔñÉÒÒ?>\ùO<„'«9ñêñUÜ :B-(„à“&“±ûã5땪Ö_öù@æùzûpµ}Ä“3Ýs̯¦3(†Ña¤ÏÀm¨P l`3Ô”–¥ r“Fíb­¯o3ŒTÆD]æ°P‘rë„ß ˜GëŒ1îhиϹѨ¦4¨%y§Q”Ôj9$Žh9ÔXœµ9¾Í6†½`û¸$3N¦‡"IĪ…öX½i"˜ôá™/ã2Âh)Ç9«i.õ…A#rÈ$UðC©ö¤Fú“*X¢Âwv²³@²]NÛ£|§tlÇq¬—‹r­ý{•pƒAKéŠÎ2E¬§÷§ÚJè0÷Gøþ0¬Í'æÁ(½Û+¢GÐjJ½3ÝáKæ ù7%'Ä\ÚýÏšJé]©hQ*øƒ!÷Oºü»tÑE±`7ÃÖÑLJ$¸ ÃûÝN ÿ%¿y‘uÝ•·üEÈOû«›b.€Ä8gØr›/¼'”~h÷\4å¹y†Ã2T_äP•—bƸÌÛ†àYÚþ¼•1ï†\ì¦(pE<à ¾h9ôÄyt›h;Ûó­×¶G9„À(²Â‘?½ïX¢ù›à„ñÖo÷ÓíGœ™9p&˜9ɨ&[“OÖK#ª©p÷XèÐñ¯uðZ§)^?¯Ï„\õü‹°NæàÖö´ÛàÙ×lq(Ó£$éRìãÅM*4nshn¨øybÁUÏ 8r½²kÖÕ:ïŽ<íy®—‡g*Ãïù¿+Þ3ëi¿\Öw5â¸r„gØž#ÝIl¬¬,­Rdiåß0Þ ïH®9CÁ¾è¾Py^ŸÏc_b0,¥¢q§„ êPg$¤¼yɽht}(e§}ƒÕMƒó–ìš—òõ…qEñ%o+Έ¶€S:™2p¸¸A£*§¨Ÿ+y÷Äôü9+ø—˜á u„ŠÂH–ÒYôú‡$žHkLwôÀ-Pd¤ù*7›l˘In°yÿšF£Ýç£Gζ¼L’$¬Ûê,üÉžÃÚÖM#“»^ˆ¼-^ n§µÁЊšìÊ©z¿"üNeû•ªðµòöG‡içÁ3®ËžÎÚ  :}>RИ) „†üzÉZxÕÙÁYsì Ì¦ßø"³eïVv>õ‘JÛ.—·]󆮻w_¯ ƒFÎå…T§qò{ÇO6ö¹øø!ÜmƒƒÍÕp Mºå¶¾c–HírRM]'5mp›NkœD¹UZ÷fÒ*- @ $ËJÂŤY_L껩ÛϤcÓWõDDf}uôèÁ~žçìç÷yüyÑ]¹ZÝXÛ¶÷v*ò($w ¡$¯›÷(FÛb.Óù}ܽ6Žk³4bnÕ 7£ †¸›s[˜fh„ÏÅIšVÙ¥‰tÑ?\©ýÆ÷ü™ª ­RNÂ¶ëØ­rº@¯?Õi:fªKÕûF´Ó¢Ìy®roôKŸîÃê ª"Aál€ØàßO­*Óy %pRÌ"YR6ÎXæõÖ§\É’P¼éÛþ÷Ì o},”-«-+ÊŠe±,)]áŠ`Ç&(ZF‘CÃ)voA†˜œ 1#_2[†¡£Y¿e·%Õ%U?ËÓÍ›TÃŸÊ +|Ù*_„ûRUöŒKûþtyÂ[àºÄ—/ ©@c½ó…y$­²/p¶Ç\ù’¶ø±ªè&cc(<‡•³H6Fçf‘ÊP<š{Z2ýMQ’¶ª‚9ùòe˜Z4'E ØfUX g†¬ðf?Éÿ;/{œW-‹|áºÒ§tÑ3m‘3Mz+JÖU¡¢‡Ð*i6£( kwÔ\ë<>ØÙ“iõHÄ}ÑPÊ$ŸzN&w<ìÜC­½pƒŸ¼MWplסáî“Býù޳’‚f Ü3êw¼ÐývÜ× CXà ÿÄw<è½è¿|ðx¦ë¡b¡·®¶÷¹‹lêLý;b-RÌmˆº¹öBr2(Ú$½¿FŠt)"¸*Ïtg¥ölxû¸m‚ ‘QD+³Rßy5ÆÐYrDÃéßÜg:÷s:ÌèÖž @„ê3Aˆx&,Ét^Î]™Ú|ä‹äž¦ KBå’Æ¼¬ü¿×a2ŒÂH0?‹SÉ$ŽÐpxq8ePZA ùŒ-¡ž*KÕ¶ôU¸$É—>Ïs–@ÖÚÞW¾²VÄ¿½çíôª™—Š¿b­K\%ˆeI]˜ä‹ÿ ´¢²­¤ e1\Di£Z)ý(«W¥YÒª>-€¹²Å¡"5õZRX[\¿C5Ϋ–$W´ 3?aËk*òæ¯TÀ­¾ìÏ›;S"$&‡“öÎþö«Çâ¡·3­þ:{bÞž‘®·†;Ž%:N\ôîwå•ÃÏœÃ(Q‰ÍMµ TR¹`P¡$ŽãEJ†¾×:®üìñŸ½8 ƒŒyz=©v oÈs<áí½8•ézE#þÞ˾~«”ÏÈ Òâ¿ßѱY™ª <¨ €FnÕîTvÎÙý7ž)»wÖæ›©òÏV!wèo€CÀÓ6ÏtMpÚîŸsþË÷yïó–î?ÖzçRDñNUûa4ÐÈŒÃ?•ùzæw„mtjQêhŽšPð”‚FÑ}RѸ­ã PÀS4M1UJÃŒ=|Ïê¹Ußþ²ŸÏ¬Ý¦š¬ñ€Ffj³¶@»¾4´ qâæ?ý#%Žoþ $Ï5òŸ€ø¦)p4Bç±yÑ݈J¿~d§a¨i£ªª&ñš.êÖº€%Âpƒ)æÖÅZ˜h£k4%Ú ßt®9?êÖ ;…¸“¿àÔ Ù Çv®õ¸Ä‘:.Zï”â;3W™hÞ®5w 'ì'g(šT‰†Ø.͈“IØU‰jýØn¾ËFRrx23Rr~”hècMê‘í`£a¤q³4bŒ¶ÁJÄÑxzùCÍR¬Y{²ŽÆq(pð’ïÈ—> s‘  iR× Óˆæ]¿¢ª˜øa6RÙ ‘Í’p82l%xšeDˆA4=Àýæñkº¿òkN4†!úHXû~P*?ÎX#ªÞ½B.™ËP”<»†Âñ;´Ö§\Ù¦—ƒï™ta(^Š“2ŒF% Xã8”Q˜—…Ê´óŠ–Uµ5)Z òBZ”, jó_¸’Œ«_ã<­«œ’jÀ°é«öCMÉSÖ²ÌÛ¾ä, B!Üò ±2/'‹“ÑɨVŽP ªÒü´P0¯I«©gœFX‡DŠjKR²®+býáúëÙ¨q^µ¬²æ¤X±*X@tóàLÉú@]¶¢*¿®5ëd[9˜R®Ð¨¥‘𱋇ތuõgZý/zzGý}ñîþ¨/Å ht¾aãŒJ<…8‘4 !0\‘*‚ÖgÁ˜„S!ò•%¡šÖ3{à ™sÁž±®þ«¡·/yû.øú$#žq J†ë¹4òœôõˆ¸ÊMÛHÅT}÷fi$Uaw¤q»>8íðÝi K檃7ü7k}·`ߌÝs§Ú;YçwúA&µ~PǤÍsËîí0•ïSå½.æ6Œ×ùglžÛ5þ‰úEîVù&ÞL×3·Ãs«©+l°$‘Ëþ“û:}jã<þt ±ÚSÚK«Õ ¸$,, $„¸}ÅIl¬°[»Mðíf¦æðÆÎØ€@pܤÓoù&™&ž;©k'ÁÆøhè´ƒ1ôYpíÌfª ŽÝjžÑ¼ÚÙ}ÞcVïó{áô–æ#ø[Ε4Õò†å/üH ¨Žlß—¥‘KåÑç–B#e¡óni¤õ)‹ù#‰¢PmU”ò/wïÍÎÌ>þ<|øÈ ÿœššž™yðàÁ“ë3³y¹Ð“‹äžjT÷¹LI¿ð_²*,a£Û0ÈNútÝÎÌþÊÌ>¿i Awû+ L‰rC_¹1ÌýëÌÇjÅ_¹Äã>ýpµ6éÑøtÉÚTûå’ÞÜžJm;3Q›ÕѰœ]F!•AÞòjÅwb²Ò_Ï×åÊH&ÇN"÷d½˜¨Ôõy´ƒÕ ‘¬¸ßÔ÷ì4Ò[ ½sCº¸?ÿ”Ÿ¬4hÀy”Dqø“¦ëhÝ‘˜ØÑÌdŠ2]K¦ÍÑÂS( D¡ÂWÈœ‚Óƒà+pÅò\-­a_ß ÷ðGbÜÛó‰]ºc­\gŒîŠÁHæ5IT©ëHy4LrŒJ[‚)—¨.†²~Gxöå࿌Å4B"rÇ\)(h•’–“8£$Ò¨4:[0d¤ °ð3ÊÒO«-×Åâ;L>TØÅú½ño°}ÃY$·ÄˆñÔ«íùÚ¡­RpO..߈w™b` 4r[(¼¦uì¤4(²p¤eh*‘!i6Ž<ÇÙþA/ªpÌ:Ÿ)€bbÎHÿùóéæyÎâ6S2Á–Lhl×…‚¯ù¼qm!4îs%?a´4–ÿ>CYos%¢m§»ãᔫÿéà¾ÐÞ¾ˆd’3Ñ ÉëÁ¦Êz‡9OPÊQx'°@›‘cJx©QÎDð–Òi S „Ê“S°WÛ¼c°i7$l0˜ï1ž÷‚{“ÛvÜVÈ ¶ «ç3/:cÏJ#Pack%?@¤qÖ¶õjiä¢3:w1xAªÂsk#Î& ËgžÈ%GøŠ«eÔÝjEŠk"š?tl¹T8õF!ç¥ÒÈ$Õñ\µoû¼"4Rºí£â—»,¾¤¥ú}à ½ãÞ¨g”q̱5ó„Æì/ÿYÌ­CèóòæBŒ¡0 E’驳g¾ëGü˜ øÌƒdjjjfúac}Ê0‚D ¹åpØWa¨6Å«u‰Ê¥ªªÆ~¯&áÑW Ã^~Ð+V‹ñ*cO1Ù éõúë2OU›Þð_-Ó¼beªÍL®ƒL® ä™{õ=å¦~Ÿº/å~ùÝ•†„O7X—Ù»±â¸|¥>MIå’¦×ÖŸX_йNlÌeW®de¸ŒãÅЪÕݵbŸGNÖÀ ³ûk€IÏJ#`B ;\iˆû­'ýì Ç”Ü€çÑ  #àj8¸U×ÙB ›ßŽÐK§²+jÚµñËÀD…cf [cgÃUæœC;Ä#-ü±Vc×O³^±[+Máz¬#¤:㎷ЇC õ¡0$Ñvµ¦Ú/¬™ª*d8FáËÉí”ño¤ý¨j,¦%Š(¥[ÉdPIF¼ˆòë”—R-%,ê¢)I­Çñ߉«¯kòïr–I!w±~7æÊëMÖ:ÁXoóEw¹¢ÛLÊëvS(’V›+@ÂIÅ]Ê9W» ¸çoŠÿÌåŽkò€L÷yÇ'š’RòrF¾‚ÇÒ6Ņ̃ªü{™Î;˜y±<_i Ç…G ç!³€Þ'4@ivß Ü¢óZª<Ï[Üaì7™â›bñ¸:ÿ&›ƒŸä$Zp‚”ËT¿’xcC´;ôê™h{xoªÕ?’  î}7¸oxKÛo"†"íMmƒ‘ö¾–ý¿Þ²}ëZÿcŽâàT¢À0B¥”ÙÇh¥ GÐ ™Ô×5¹³|]o m8º^8ýÑÔñ~hŒd³« Aüž.ÿÅj÷˜-ø¬42âŽ:%]ŒÚÀ ¥Á1[àO®æ«…‹ö pâ3Oè¬7}¢ÆÜS­…ÆUUÝ€[HVè†jô'ªòNmÈéjÔì/ãZ­ì¦Ò¥&Ì©\Æ¡+Õ˜‚Ê@)œ’+5Æ ¢Ú°jU¼1{¨:«Ç›¯Iµß¬„oU·WÓïU\o•y»-]HãÓõr”L[¡üq†rJ+ ^Ó1\PZÞòfõׂa?B¿_ìñgÇýê>×3Ôˆ>Q!ùŒ½~Ko5“têë˜3PB+tA¿¡£…91ްá¥Òs¼ÙÔ¶™õ—ècuº7ÃlG”;Öƒ@:wàQäd‹ØÑŠVXÓ1…‚§•îC×öU‡ZL›¸×6dm:b‘¨îHÊýŠGcžaóQ¸œP82°ë\ÙøÿF鹌†íS’„dF÷¤Ú=÷/U­ù–)»Å;Æ@Û]6o‚_}EŸ½h¿BÑ|Lª‹ TÍU«B0Iªã‡Çá[‚(վ߹¸`ܤ a¾×xË„hTYî« ¿Ê&YûU¢ä#²àcÊú…B°þ&"æ/–ç+mÑ×I ¤.šÔ!Æ¥g Ÿ@‚“B‚ÄSÎó¼Å$k»ÁÞÐÜâ,\þ=ºè[ú[.‡Ä•,CÁ19¤ðnh?”þÁðž¡HÊî<œŽ mÛs&Ôþh¤i÷ûvh‡ö%‚{âѽ=Û÷wEÛ~ùRs³§Ñi²hI†Àpx±)•Š$IDž!'qVAìiØ:мpŽ7‰È¿¨¯óç&Î3à@Iƒ/I{ïj/íêòOY¶|ʲdËY&”J!Æ:V’9Òl0’i‡ÎÛ`ÙÈ– &„ÉL§“N¦t¦™P  æ 6à`mÓÉ/-$¤B“I§¸­:fœî<£yµ^½ûî#y¿ŸÝóoKv=§ࢭ¶ÜB˜ŠMI;Yõãk•‹C(Èý«ÎPB•>Ü®Rn9#¿¬]¡.ôWèJr¥Ê>º ƒê„ò¹:ÿר¾gYÃ`ŠjXœ:\âù¸!Ç\¬ñŸwÂa~ƒL’]ÏWðý²5oç8ÂYåÛó]ošl;síïV®¹R ‹ ߬I.Vû=Ú7|üòû™¨ôý¾¶í’=¡µ3ÕëX `úZó 0Æ—O¿„€:¾¥Ès|ùÜ ÏžTà¯Oþú·}{ö’˜J_:¢‹9îÑÇ–ç zåц…JÕ¼!gÞ±Æü.M)M™é ^•Τàø)DM(A l¶ E0‚ ÁEéx~†–Ly%­ޏõc¦h]æ`Ò1Åê Çê…K–‰qwáá&U³~ ›Æe¼† (‚Sãnñm?ÚŸJv1P1¥c %¢FÃ!Ê+Eã¹êÀšð¢iÄî¿ZåOncøloÒü•«•W¥ ¨ GÕ †q²‚ÖKù?ÏsEm+/Û['ì¾óÎÀÅjÿ¶ì¸œ¦xœÏ?.TµMÔ*—+}â0óe'¹7c¤Ô„‡` J§‘8FF íJ§P†ÄêäÌë¥ u‘kÊ9×KïÛ¥*ß »rÁì‰ù÷f95Œ„›^ôè±/ž<f|CÚž}½} ’'OžÜ¼y#IEfà¨P&Ë'We : #uY#Þ…JÕœ¨[?ÒléoI5d°))‚ª#¨t1ƒfIþU C"„Gê ÃÞ’èj&˜C£Kx„‘ Ì…GWéŽWÇì<&Éó.ršc òq~Ô+ »ÍƒÎü¡Æ¬!y›jÏÃך™Ö¥rWUö€Go’Æ—“§ÜÙ±Fs´jÈŠ5åÇšLQ×Ò¡SÙBn¦PBC§ãj–ÍüPAÁ”̽‘…Òßö¶-íÛ¢Wà}þÐFÃ~˜?"ìöi}Ë8k.K1`rJƒ±©b ø#5ðDD·ßãÓÞÄõ*à©/ü¼„¾LnØ?ïyÂü0½«GÈœ :VÈÔ Á5ÇØfEë#)‘ѳºÊ;lÙ½}†[ü˜ø—4|±Fä”ÂÈ ¸{ (Š¥4`È-£ÒðXôš–óg%ˆÎrHÕ)©àsÎ2#XfXÛçZë!ÊèÂh'c\†êq±–ø;ñuþÅuüh…€×»3ófæÍ}íå½ÌzO{×ÇÚ öÚŽmŒ¡-‰ŠðµkCU€Ýü–ª„ÃF1¾Á¤þTµ¿¦ ˆr„pãLÌÚ¦R¡¤ß U„‘b‰ÈÚ¯V³«Ùù¾yûæ}?_5Åêšÿž^¶KðD9Adl¡ÐYÐ&Ø£êsõÔèekÅ}9tKöŽkÁ e ðÃx^äœ3ø/.zŸ‹KÏf¯“<ÉÑ"æ5Äq4í£˜fÎy\Î?o‹Ý—°»šSËEG™dk`´2ÉÑ*:gµ8xãºV÷û­8-¸“¼½‹K°³[¼Äÿˆ%„ÀM%ÿŽß'ûÊx!)Ù«±c‰`T2R-G>S÷™d¯æò‹se’Ô óƒž@»¼sÎHÉ;ÆÒ 1Eüów>t×HÎâè5'iñ”xÂÝ•ƒ_H±Ãjø Á!D™b͘â‘a–bQœßSŸK¿âKa’/Ø<×¢Köø¥tF(œÑbà®)[xVðÏûBz.¦•ð1vK+œ•0É“¶’^ÆÇSÙ¤X˜”­à`z3`¬£äp¬mÛ\«?ˆâhG÷hóæ¡–ÍýouÇå<áIèm9®ÄXŸZ¹ï¿‚FÖ¼{<Ý}¼e+àä©7ààPó¦ÑµÝ ™ãí]sÍ;Òº¸q$½ ¾yª—?´lk-«ã1PÙ.#v1Þöqez¾4(rqI牊Ös±–KɵÛã¯S‚þÖB‰ˆ…=PAX"ZEžçóek«~ן*‘óS¥úæš÷|yúT¢õóDú|YûÙŠÌ…Òô¹dÇ@¬ þ÷ln1«ì~U”ÄÁc’ˆWDÓ”‡@ë]…§’ퟤ2WâmÙ_ýÀóó·oæç㊖«e™Ó%­iW &„.•¤N|òéS‡­OÏwøþáhÖ"p¹+ŒŠÈˆ¿`”ßÐʦ”ø cR+œTãWÅ¢/¥’/´Ð}98n„&”¢‹ÖðFYÓi lÔ*ÁJ‰iR¡Ñ8ŽþŒ&4lº5†`YMiTÖŠàCƒ –Qè/¢çk½ø¶¾lÍêÑ;\`ZN‘ 5zOHâò3&<"³; #FPÍEiÐ :°ôW®p»äU‚Ï1[͈¤sÛˆ¤Já-50e/ÍÈ‘•HƒíWB&d­$RàIüe=pM[|M‰¼ÏÛ 2W£›™•¥[rIö'gøŠ•¬ÈcÇA 0V(‰É%¬¹9»h…$ÿܱ&n«Áëzè¶›–‹néñIÕ?-æ?TK>ud÷‡ySóª³0Éè´ “ˆæ0T< ë6[)D÷•’wDo+…WµÐ]­ø¦Ñ oJá [œ6ï 鹸®GÈqx¿§E®«þ«ŽÒ&ŠƒÚGÓ´fa:“ËF:»F¾©ãPÍÇÚæF‚ÿ« y3ÐblÝû¿YÕaä ÆL"Cj+°Ð„Já;M«=ý-á̡շl9’élÛ2¸fÓXË{sÍ›m¦ à²O}2Ö¶m©+…¦•Âä¡pãç%í'—Ì›FÎ$ӟŚϷœ,o…‘\)N÷z–˜XZÐ_`†&AÐ$˳3˨Р0¡Ès žH«}“«|®y/”g õùdæ³Dû™ò4¸âDy[·«„&é|3>i:S»›+É_õ§â7Ë(³ÂU0k8N´].i?øÁççlY;éd²íb" iÒóaq²ˆ…mjzrê}|ýøÉ“g5ò,K¾‰w±[¥`1ܘó`ƒo°Ê:XéèiÕÓÓW©®µÿñçž}u¡ýîÑ&éHµq´Öµ£ñUm!"ÊaÙ}ø§Î„ûh¥6š”Ž¤¸F‡Æ`3EòÕNc¸Ñµ¿Ö3¸b®ymGR ×P½í`*o eŒ¤„¡*ëØJÛ±Z8†\ý ®þFßÇoËÕw‚BÊiNà‚ݯkcuò¡ Ïp>œ²5Î;?ž µ£T rX–å/¤ŠbOƱûåidOZÛÝ®ôtÈ{;;2xU¹ÅcX¸ƒæ_3[ ,p¼ Ó ÆYöS4<’ŽÒÒY_°½Ã»s­zà—Ú‡íÊŽ6`‰õÃ4„}W|Š€7¾;u³¾'íëÙ t4­- æÈœo‹¥lá)­`VÝT"w䨤ž´†æ½L|OÀ®••u‚åh:B³ÝlÞ¬³Kxqlí[¥¼_³ÖSRtˆÞP×ì…3Zñ%GÑÛªU¤Íà ˜x™1Ecz­áÍ 9Šà ¯ 9É 0a)† DîÇ ¢s^©×…q. r˜tÄàš_*1ÉC0Ý-x¼˜ú³Èa¦Xçð,¢XLq¹˜#8,Xhx )ƼœWV ºÊQ þG}¹ÿFq]qüˆE~ìî̹sïÌ×ÎÌ®×ëG`ýX{½ëõÛÆ`7à*¥°wí]»"iš”ghPE•„l ,8BJ«þ5?DJHC€Bì’EMú 4= Q„PZÕ*­ÕÕÑhtw÷ž™sï=ßÏ— œ&ƒÝ“yÔ†•+fÕ #4rÅ.Å\B Q"DtA{Öx0H<<ʤ7vÕW KvÕŠmbEpe7Â.%+7@Oëp© Y¬‰²î¡²Ä<ƒé“d É‚`å®Õ b·´ÐoùçvlR,)›6˾°âgŒXÒôë¼ËD‚’­ [SEMç³¾Õ" !ÌæÖ¶Ý#ùÎ-£ñ+µjB ÍXPáŠf%¬Ý§ê¶™÷ôPL8Õ7Ì*Àï);ÛÔå¸àDKpº‘Baã*Õ‰‚a)=¨X³;Âñç–ýp(ùÉÑD–"2ÝëàŽ÷nþOhdôÞcíÛ ÷’¢©<¾§ìÂ{­©3õ} ÇóE#6÷‚Î^lLœªM\‰¥Î¶ ¼³$™©^ùjÙ’t°¦Nóù©¬P g%_pYy[T॔ZÇwxEÁÎlÌFüf:‹2OŽvøÆûǺBot=¹wiá¶–‚çcƪR¾FÎóæ`ü„%äšT~=z©ÍÿVga¦)<Úaïm^:ïøñPx_éP¤‘b)JI³³ÏÙ•¶vô?*q†Sæ`ÂÚ=P¸çYû'Ës‚àt¹/«˜Bîå8Σf{Uª€;9λ$ªmOXûÖÊÛ{„=Á½ÏC)g×Láq^ëõöý ñîîñíHø‡ÓÖ¶„PìP‰¨"4Fô[8e×N{˧Š)½|ÆŠLëå¾òy—‰“F¼n\dˆP=š/c@‹ãLÁ- žï "qLA…È}Ì(¿ìDÿlÁËFnëµFd3u§`f –#["LÝ¢¨¤ËŠÉ+^Š "³s¨"¢¬I‘9Ÿç½è¼æÄ>Ó*/ÚUq¢Szå_µø¥È6Ðcb~P²±Í“ŠàIe…)ºÌaQÀØÔ|Àk§‚¤pÈÊ…6+/RôI+2«‡¦œ(°èf;óBÖE^5W ‰@'3Jì¦ÅŸÒk·*EÆ=p‚ŸÞ‚sÔBbHV©åA²KQUÌdBÝ‹Å$ºèÁA·g9\³"7ÍÊÏŒòkZéMä²_«øe¡<ñy/L‚‚‘)¢<’‡8eTÏ1'1ʘË]À„ aTßd §Ê «ì†QvÝ_rŸÑyßHÅ-3ò'³üsýÞÕhHh/å+’¬ Ü®[ûòÑ5ëOto<–Ü4Ö¿å`rý\©HæW}[€Fàï‡×þ|㊞±–RféQ<]Öûh*EG4«·K÷%~v"µ0æxz ÅÁg^˜kÞûìqÿ&+àÍ/V½Cÿ)oQýgš|²>ùIÝü ÄûõÝ ëR§ZÓ'›úÆkzÎGgRçj{?©I\ާ/Õ¥OÅ“¿ý`¸¬}ë‚ÆÊ`0@d¯‡§n—NFÏÿ¡vÍ\óž‹%>lLBŒƒÖߣ‘wÛzWšA‰—›ô¢Éºµ# ;=Gtåƒ†ä¹øšß•ÿÈ<~Ž?MžŽ'.Õö®ÿ_ÐÈx}PÓùxïMÉ÷uð„Fªª¿þû×~¤‘oFîÞ\ypäå­UÊ Aü-ÚÜ\x Íi|„êÌ´Z£-úhkñQ@ŽâÌâ’ƒí ö/òmkWÄ\8S”Izª¦rø)óíá=]Z‰Ÿ@Kñ»D²8PxhYÁ¯—š™–¹§^T4Òî?Ôí lÓö7:ƒ-¸Q¿LT$ .NØKŠU&èz>Å Ò{+ô‘¶@¦©äͦÒѧœ7Ï;~<þ#ßWK%ŽðÀ2UìÍ«AÁAýxw¥|ƒ½¡ÿ/ÊŠ:„¼n ÔyÃF Xþ†pÉOW¾ÚÇVÖƒ^ø=˜ 襯¥;úý¯§Ì]ý¾ÁP‡5”Vw§•=ýÚýÎPÁÎ~ßP? þ³¼ÚžDáöNÂ/åeqÕ%€‚óXì¡úŒÙ8kU]õ•M˜¡«Nå-µbÊþ¿¡€ŽL$T»D@‚9Qàä¬}øÎ$¢z\¿Õ#³fíu#”•$V3¡×l’ÓÃc¢(‚,aÅxdÓØãŸK<$‘§œ ÍÇ „€O¬Á)«1Ù”·nF M™á«Þê‹þè8© ©a7`­žÇ€jtUÓ°$ ÙI$ 1FDvO†TYuâx‡ SŠr™ŒI»¬O›ÑÛZÙ¬Ÿ2Ë&Íp»dd°ä$¯,`L%|]‹Mš5ÓFxBmQ‚:BTU¾!ŒCðÊf>—üU^²Móp¹M C•T—("& åøYøTÎÚ±I5ô¥^9a.¼iÆ^L#†Hp¦À~ç^HÑ]MéÞ—d_\mäTE¨Ã"¬ˆèaܪ˜Õ«¦ìŠ+v–F¦ÿA}ÆFqÝÿVUŠò°wwÎ7÷±3³»^Ÿ16Þõz½»öÚk|€C8Z `ïiJD c’¶é0w€âõÉ‘&j>ôCÕªRl°¡Êa°’(BêíꈈVuDåvõ×èÍjFï½™7ïÿûÞZé´R>ç 驸BðÝÐ<ŸI%SZ`XôåÒ6HÓˆæ×µ:„Z·õ½–NÐÈ@ª«'Þ1[¤×½q2n ·e{:ÖÑ—ÚÙÛ¾ëh|ûW%¿S\Q,"ÅXpŒb qš q—”Â'£'š; ß¾hÇ`bç7ÐØ£?Ú1Ãh@À?k«ÏÙIÄáXÇK•cþèpØLvs¥@Èx(>R¶Xr¦&9Z•¼ˆ_+Oœ­Iœ GM6c0¼«ɱò–QóŪ¶sØïB͇¯v¸µ‚Q­:át¶ý‚ Ë„ããUÉ‹¡8àç5ñÖl&K"B§ƒk>ð®1¾Öw6œ­ØÐ•[Ëë2Ž¬ã‘¶ËcWªR#Á– ¡ØûùŒ‡àèñ\uüÃÐZ–À Ö'óʲ¦¯>šÁÆÃ‡Ÿ©‘Àÿù;üî^'5Be(\祲–¸ûž›FŽGœéZ#]kž¯s¥—æô6åõ,Ïé_ÍhV°7ÇŠß¶[ŒCXYÈT8æ¹YÅJË¡<Ò¶”çö7ªCÕúЬ5âL/.8^ïìmpô/ÉïyÙ5ØX¸¿Ñª¿h!(ÅŠ“q†Ç‘„D¶À 1’Q”íz½ÒlÒû;ÒÕ® ê¯æžO…»…¸Ì I„'Ø„í¯ÕfíMI݉祱; qw·¹“— g8Yi…Ùâ÷–±‡R ãDÖꦦ5S)/Ȥ±muöOãî}íÂá6ûî„¶'™÷ó$ðC8˜BûârwŒÂù7áöÇrv'¥‰ìýõ7VJ’d¦rĸö¡ ¶âÛz1”±Æ"Ø™ïÙÿo4³ ÉP ÁÈ$ÓHcDHˆÔ¶ä³C¦T™eÜö¡äý\ôMË §¤â»rÙ¤VÞ):£²9< !Èø@ŠÂ"4Ÿ¤¥6V^E :nË`1†¡iÜ´,Úh—9*•}i÷Hn;|“rèMÊeá, Iò0$ 2pV ) ±QóˆLpZ›èh¢Ù\ 6[‰ƒ}($n…¹À 8‚®cÐÈçB¨ Þ3H$1C#Ë ºpR*šÖN …7²»JéNN³Û,𥃢yŠhÚ •¹ é×…ÀwðJŽÿºü™œ/I¸É0VÂæ\@ã CÑ™ï+Å_H¥·ìyŸål°„BPöb,³€£ –‡=ä.#Ogß‘óþ,øo¹«®e‡ÿ"•ýÆ^´^°gpV©UÂh’àBu¬zK-ƒá”`ÊÓš¿ i°&eÊÆQ¼Bšï¾µiÑ?e/T‹n¨e‚ ÑP sŽ•Éˆ±6+ÚyÝÿ©¸­ø¯ªãj>ì²ÅäŽ –µ}.ß„´è¾á»'9ʶ ŠC–çY‚Ð)é[ôüJ‰–}c}w„⻺ïx y'XÏrUpŒ`y‰•+edbK8ꪽòS©ü¯º×Ä­\ü‰ì½©ýÏiÖÕ=Ís]-ºh÷(IœN*[kW NÄ:"C p:[EÒ±ŽÁMoníkë2=³a;€¤7Ù9Ýñ^ÜdÆ[¯FaOV¾Ôã­Ts÷µl×o;ïˆ}A˜7xæàŸP¤gý÷Vè" +à¥ápr܉$/…æL#dlj±`ìb0:Z™‰€:L\Š´BãRUj<œ ÆA cÿ ¾NŸ›¸Ï8€ÿIibliïû”V—eË—$[>$[’o'0L°%Y’2™)˜@H“6 Œ 8E`M3Ói§/;MÓ¤P‡nƒ 6í¤/˜iÒIÅoÚ8Sêç…$ïî³ûóo÷ûùUE/×uÁç oü†·ë”7rʳñjMr"Ø}Áݾؾ_ÔÅÆk£Ù3G4 §ý$ ‹¦TaýdMäÁh¾¤(% °,!àY&I|½ê\®M€ÎF‚Ýÿœ dÇÀ¶%¿ £QÏ>ÝcÇG¿ùç× ÆXÐÈ¿¾«oÉ£YØþñÕ=’áÕ–ˆŠ;^ÖYDe9ò#¡Z<æw:Ì7©û’ Ø><­¯6°Ièµîꢢ…ƒ=ro«Ž'9 ‡(/&±³1œ‚c^öÜ]ð~^ò˜øž!qa(ÃpŒ¨8…±4D?ÜÚ‹E9¡Z?f,»-•Ìi¥wùâ KåU¥|³ sxžŽ¥ˆìa(¦ÙKŠÿ¡ä½-;fû×låu-Cx%—†¡ciÐo*`LF,š’ÊnZó¬ë÷ÆjEr(J&XC"GGcn=‘]äÐCºú>ç }Å»ÿ&»® ¾ œ…Fp#˜ GXˆCІuX˜‘®ª¦¥’ÆêëªsZªhAENsh ¨"p‚ÆX¿+UM«çJf9ÏÏi“ˆå¶XHå<Ç4sƒ­ºo¨x@Ì«®9ÖuVóü”u,. Ü©#hRJ‚(›2•gÇYrMëd*Ϻ&IÑ8eCÉŒíª\=g¨º¢9¯©îû\ùUCÁœV=ŠÛeBÿ<‰²à7Å„Þ;­øçYHp{—-y VdÕ·Ô鱚6Õ\ <)V3 /èa¾€1eº¶·o9Íša¤³ïh<›ï ˆE«@’ØööÊö6“kshíPd3œ „ù¸£ïØÆ­G{ßêµOÃY:©*vL¼­á÷ßĶƒ[FYÀ'~H ŽF^‡Z È{ `fó!0ŒÏb?ïM\òÆOû;O×.™F 5€ä‚¯s²:v¹&~¾6KFÒæ®¡xËÍer V_JÑ]ZÙñÚõ 8jÜù¥3/p‡ÿà}x°Ø¾ã+âÐ÷ª/ ¨8NžõÆ.—G.ºÎø¢ŸÕG¾ôE?¯O Ù[,z^ÑAøãðJ‘f´rÝ_ý§óÁä¤/>þìÇíŒ7½€‹W¼ñv¥4ÿA¸ Ï>ýó·ß)c" ùæxÚú¬SU:Þ  7X·W’A W`Á¤ç9,/H™ºË\ƒE#ÍÆtИYÓMöTsYªÎ:RomÓŽ´Œ­V2õR¦QK/ú:µLsþ‘¬C”‘ópP JÇÂŽt‹¸Æ‰ëõÆÍ%…éuæÃk: žhYr~<^ÇV8[s‚2ÂΉ¥õ½lÚåò@RÙ7ìMXöuCôË{ãðËb5´PúòîNÓ^åÝvËÌääI8IT¼±QÚ„êá÷w›>Hö¿jØÓÅÔ#½×aO¬¶lzÁÛªa=+a„¡~Ì ¥;"†=ìþ¿·Ó¸¯ë?ôÕöe ¤íï±ìŠ›÷÷rïµ£þbkLlÅ!ï3“ÆšYƒë>[iuÅP³ä1ñ=5‚“Œª#% c0d²ŒA a—AÈ>±pšF rç˜ÁuGòNižÛ‚s^(‡Lïã ¦GišC)Ed©v2M*ewÔÒû‚jÆèœ2ºq6øì»ÁÎp‡ÃI yo¨Õ›9G eiŠ!Q”DZ·)íŠRrÛV~ÑèžUjïÑ®›æÒYÁ}Sr6C óE–á!I²™f”Ê;rÉuƒL2+W4"¼ˆX¼Áê 6GfĪiÙyW)»%Umç, ¦#(šÅ²úB,E˜¯©Å·T׌\}S.…Sýšu8†S¨„3 P„¢hŒéã´›jɬ±â–Rý‰PKã8CrHvBs8õZ‘ïd¸ûËò¤GÐôÅÑÄo]ëþ²"¾Ø¾ý‰ñ@'Ô„?y®&:^×q¡.v¥*2U±áL8ö'ÿÆsuÑÉÝ©â¦õ¢=¤Z¢œíwÎ6 Óu±ÏCÀÐȹÉg=>à´‰`×éÊŽ³þ® ÕDÓ$ƒ<Ëý7uÔ­œê†Ø C¥?²Ú¸à(a ñÛÅt˜Â©[¸…!I™F žQAR׌À¬ê¾§¸çí%sZéºóã5Âp"E@GRdTÄmæm_‹¡›j”ø‡6È]¹|Jq/˜‹oƒC´’{¼ï†^²šFbδ¹4²,ùnË)ÌXýŠk5,©nÐH§ ò†(Z$yj4 ¹•ø£ìñÜÕŠ¤â9=pß6ÿ½7ÌEKrÅÎ^œfL'àØ“ÒŒ>Æ;gÌ…s†wY)›Õ¼ÐÕ¢ì@ü ™dá­| ‘›–Â;ªw^*9ǹÀx !5)ð"`OdY˜œX)|£L™l8Fq.]fpÑ”¡!ÄÒg)ÏÈÞÏg/©žeÍ xG |'–ÌÉ®õÚ?@‘É3§x@#óº/õåŠFæÍ·9ÿ»FYÎFŒ§ˆßÂJƒm¿\kõ¯£w"zèBû¾d×kï†SÌH´íOF½{m`×Þb% þ8KcA›ƒâ³´Æj7w5m/ÍΧ0‚¢i81>)ŒEz>¹Øy`<Ü æ9Ù_$ZXŠ–IÞ½äßþuEô“šðdmìóòðziärUdº²ë£@ë5‘« ݇måvŠ“iNÄI’¡pDH8©0+qœ²ÑT`B} WÅ¢BÒ¤å?­ _©‰­uÜ©@äJU䓪Î+Ωš840É7Õ]“ÁÈduø«ªØtI ða°ó/µñ¯*»?hj¿ŠYý¬:òY(~­2r­¬c2Ðñ´×çZEÆú²ºë㚘#!éè‚ìȲ?žEþýŸÞ×Ë"PJR-½Õ¹·‚žvUu{ÎõNSîh(°1Þd$!}¸L?¨M„€"–þ&Û+Aëvâ5X•‚ˆT6!žÇŒçyç›Í‰zÇÚãÔ’•Î ¡¬áMŽ‘çó4çu—æÔç,!´•DµZöPÈœÚFê Ƕ­;?~¨‘ážx6ï7›1jT £ ‡ª tª'ãæÁnðPDïO•uËP>°6Š@ÕÈ)ÏHG:Ìç÷Úúãæ7veíQFµþ¸1´ÇvöÖ#1¾½ó8M„‚Â!$™ˆL«¨ýªÍüëNÒŸQ8P„ÞZæ<ûÃСõÔî””VLòÐцºáê<Þ hÑÎíq½6¹ ñP•p”vZvÝ}3Zþt–òöºóã5¯MP°J ŲÞH‹‹rå’^tGñ=´-Iù÷DײQ¸¬¸„<èsIôÜ2—¯¦‘ßÉ0(hdAñ¥bÐ çÍþ?¨îÕ4rGvÏå-ü_þˆFæôòOƒFà$Ã#"T(Z#6LÙ‚·5ÿU%û®­tÖ(¹sÑ}Sö¼eÃsËRósÎ*°(“F*ÉAazb¡9ÐÈœ^xK÷Ü×È‚æ^Ò|H÷5’êDÐ}Ì™‹þλµ²7Å,šÉÄNÆž¢dFR¨ÿ_ïOQ]wÀÿ‚´‰ºîÞ×¹ï×Þ]vY–÷. Y\v—…(à ¦£˜È>¥uL+àÛv¦M¢‰@+ U^ Û™Lû›ÓN«#Q  ÆÇHĘ֙¦?4Õ~SÛÉD§ëh`Î0÷Þ½÷œ3ß{Ï÷û9T„çŒâH–5‰,Æicº^1áâXRàN‰HÀ ÖÀ-o“m׌ş«î)µX¸a/\¬ïçæBŠ@›]Ð@2¯ל¡g•¡Y”ú×ÿh ¶5Õê2²c¨±mdóÞc-»O$v ‡;7n;ß1Û>ؼsÏêð+E,ÞÈánÀ€%!ã),ùá] £èÈoÕÓÒŒ;œØ S:ß hÙ¹Ñ_­â êDD«Í=VÑ2æ\ñÆÏ•FÇK‹¥`À_ãõ`ëŸÝœ²"0žgáˬU3‡}.z[.7]­ØúÁ‹ rÇP˜Bc˜Î+ZHWÕžíÄ'½áTÇ,ou¿:H€ÄÆýñ3ÁøAWmˆMƒ5 \ä$€m%PȔٙ_}yåæK^€Sd"ØF#I±t6ƒFlï´ÀüÙÎÜœñf‚Ȳ0­!AO.éUr?“‹?• fL‹V5RÕz )Kòt™Â'ëŽÅ~K-úÖö‰É3§•̊ëšVtS*øÌX4/8©.oFv=ÔÈ´’ §pñ1™Ñ< ¼$S8d6Žæ@#*E«”î=ÍyWö¦L®±àZš{^+¾¡dÝÑVL1¾ ¤°4 …‰LPÌSÓÉŒHyÓÆüOTçÜÒ @#¿•<½ š@5½-:§5÷’·„~ê¦Ñó¡“ÛU\'3˜™7è9ļ Pz†2P,"iœBðzZÔSô‘ÇYVŸ‰/ÝŒ…‚;ªg^ó|.¹!È7ÅÜEÓˆ)é›_Kÿm×Ìž:‚Jœ´G¾êßEÛ6¾žrõmÛð¦=‡m?©xe«ï¥¡¦H0i‡ƒH{_¼ãÝxÛÏ×7¿”ïÉг$IÂŽ¢Š#Šb§¼é¹ûSWУd0Ú£¿ßu4ÜÞÓÜáR¬báUÊ$êw×_€bç‹^õ% Ø}ä/–F&|±ÓåÑýMG²kàûG$¦è‰út×h0qåÅÈLIËxyó=¯Ž¯l9ŒlQ°)Ó3ˆE¤ˆa'½ )‹ŒûSVÁÙÒÈxyÓDId¼h㥪-¿*ªóqš^·Äjà0Š"`S€'—ÏR|™‹ºóª/ûâ®$ @ %‘‹eMà™óþèwŸÑ@t¢4±%ÇËáhþNy2üëþýüýKUÓà{ƒ®h;íè]k>¼òYWÕŒ.¿c .w_–1Œ3¼ž·ã*É&÷B|8ÁŠ0ð •©ñÅ™úMÙüž@Ρ†¢÷6Ø{V™‡jŒƒ•é¿IY#é?®ÕAŠƒòI‹`\‚\ºŒY&f(lµÕ¶Å—»•³oMZ%7ÔŽÕÚB‹Îoj¤?d¨VûVZö”ÑÔ2NOB­á¶Œƒ›$æN|­‘™¤¬‘·É~ ‡î–§–}¿WlµR”TعP4 ÿE–çIZ„ 6£R_š±·1§³îÆÍ¿Þlz+’Q»šAÖîÍÀ$ r34üšÖÙbéLNž… Xº6)ÑZ c‰åH¤éBͰî)Í=-,:?þOÈ$Ë&ÄqFð/ÞÐüÓ&ç¬êøÖvKΘ2çÜ”sgÍÉnçD״溥 &¹Xg΂Ŏp¤tyââ“iä«{÷ïß»¿Â»ª?O³Œ„gw¯¶ >óªj;Ri Ù»j ùˆÇ "#d 1£$UP‹-¦æY·•Øß®Ìì­±þAnOUÖ`½µ¿ÞÒSgï[¥T˜†jž@ Ù»+(‹N0T Ú6¸òÛ™ª3z×8Õe½lªK{·2ãH­u8-ýpÅ¢óãíßÄ—ùsS×ÇÿƒÓ[ÒÛ÷M»¼Ä¶$Ë–dÉ–¼/€IqHiRlí2KÚvš6S6ã…ÅlcÉN0KÚä×þf €14¸nlãb0¤é¤’v:ôÈüÖÄ(µæÌ›ûÞ»÷œ£óÞ»ßÏ1õ7µ–DåôZÆLájBCÒ€‘âÛo˜:ã å éÀÚž8Ј{Ú4Ò3‹É]QðcìŠË½[MÝmÜF|_YxJBd‚Ií2‹Ö8ô;6™;bÌ»mL_ Eäƒöx”9×-a‰Ø…4R˜Ñ4†–‹kXJ(’‡è†%,UÚƒ-ÜËä%T"¹ æ‡'iÓ]gAñ¬8~|GaðÕ,–Éápú ©Ÿ'kþÂøçÛ·ÚW¬kVïážÕygxçŠg\o›4Ø–£‘ß V áî‰%÷%' à..G#sr!ˆþï§Ì`€IJÁDEŠÖãØQ.TÐ%_ˆöƒXhÚä½,ÿ˜Iõ­¼ Q±¨˜yn4ÂhˆD¤=+ÙJ (Â=Éq‰/„û&,È%s²ý¡Pü'ÙãÅqA‚f1*§PB³‘ä¯éÜ]Ÿ+ŽI¥hV,žQr%û‚Ñû1ÿ±h^ïäÞ»¯u.ˆÅhZk¿§u|É;þF?fŠVìzÆ!‚ã>_4(2­8Æ%ëzZ"Ð,* Æ[+ß ´< ‡ö§«þý±=¯:|Œ %0\Grmµδ¶„ö&£{“¡ÝC­;G‚{.G\ï6HvÂ1ùÓ#‘}À gÂ;“ñ}n}gdSûs£‘Ö]á]ýb`Ï…èþ o ´6ðJ05–Üño¹êNø#7ü ‘±Ò£È!¥¶mVF¦Ô(PïÆœ’ɲmôGkãWªÂ£ÞÀ­²ÐµÊð­Šè”;¼ËTšAàãÚ$åß* _÷µÞ¬L;ˆûIYËuopºòÍa÷¦l5¹[òI›?r¿>îÛö®}}µ.‡!0'g—_­Møcc•ÑÑšÐÈxyävuüÿA#ÕÑQOÐNs4úYQø×?¾þ~4òï¥CókÍ,FÂA™ÜþrËPã‹VÕ‚Ä:¢¿:'ÑL×É$›ÅÛ´Ò«1ìŽÔz×X×k ƒ¦d•)Qg¨5ެ1)Û¢‘Êû•G;Pmj(ìM;.{±6ûOéé׸äÈ÷ùD…e¸Ê2à/40~e¨NIÔç$^Éé­³œ©6&ëV?þËrÎ6Içª µ¦Á&¥ÌD³N2b’¹½A(d<¾EèI=1åD›ÒÕwÇÓ¥ùD›¡# Ë 1ôD˜>+8€ÞS@I!è|3l‡ Ç·™Ç„SmÒ¡€®#"tE€dÌ'·ñ‡0PNn…K´àçøÒ¸;®ûùt¦‚‚¡; Ó€ˆ®`¹®'Èý¤:•WSŽ­vrêiÒqOë]qüøŽ42Âga ¢!5*èþ$ŠnÖH•,]O*ßj>RlàtëÉÅA 9%:±…‹rár42½|Wq@8H •ƒbÑ_à󗣑Y¥pQ,g*µ ˆ€RM°("kø…TmÇÈkrþ¼P0#€ç>ÚXNa«QU@…ƒ4¡0âyÑ«Æ#ÙS%Úeï¬ ×õ¼È<£Èh¶Üg42'9€F¾’ÜúòmÀ0gY£eD‹#¸qõª^ɲ ;fõ…¦‚¿³¶iCÁcÉù¡ÎîÔdøhô#©h‘.™×ÙI6À’)}ÂXtW±>¬À“×J½?€F`ø@&sJ1 È 6—ÅQ!!yÞLqg7oŽ´¿Ú{.ø‹tÕS‹a SqMÓ.%;Ѷälè-  ‚DpW2¸k°õ­áÈ^° ¡½ppe(¼§/º;e­;.ÇÒŽ»œç¾ðÎÁèž‹-»aìÌýúé“§GÝ '`¢¶œ†óõ/ZU³Ï½Zpª¾¸¯?ábÎUÊÃ@úD…8\aHÔê“òP“ñ̺‚ÃõÂÏì–£u†äzc.ÏP *nîß ¿WcIV¤×<´6w RJú-ýµº‘5y§}Ùƒu|_£®ÚB"Â*¼A,ŠTqç×ÎWêV?¾aµ†³k­M|Ò§Û©Y%"‰RAŽpæMíѰ¹g €Ý6vFôÝÑtid9c}Vq£Ÿ>°)ûXˆÅr0ÌvGøÞ6òd\ìŠçum·‰›{¶ÁX{j»Ð™b Xeèi3 AJTWæë¥•ÔÍÊÓ‹j’F5*jU;%.Èþ9Ùû@r=’‹@›få’G’ç¡àYY)5yÈ—Î鋦ä¼ÇRñŒÞþ™Á6"J* ¨sZFi@ÎI­†EpNA4÷Ï´Ö>+‚Ü»Ûy#È7¡a¹,%I ƒ‹(~I°<à] \ñ]mÊ`§pnÁ˜“a ,„åàdNk}Â8'%o»bÑjT˜J y9“á³pÐtžà@ô9”ÉæhsÕŠV3Ys–C ã"È %î{Ý®j<Þ”>ºÊ2^cŒ{óâMŽCë³4ÊDzâr>¨³†Kõ5iȽ/)UJ²¬µËk S*¡ÅÔTš4¤fÿjMþÉ&ÓïRçM?àË­1z¬Û«­c 9#Íb•I'&‹Ð;u§M¢DÌÜå2­J?Þ¸Üìñë×XF3FV›&ê2}x)ãÞeÆ Ëï·è÷ÆÀ¾Ã1yOT †B¯ŠF¬1 ´_¾“¶;Ì …²†;Í{;¤þMÙëjPq6[heìY|½SioNÛUöv¨ƒi(lÞß ù戴/p²ÔyjÌÃ\K¸!+r™Tã¿W¸ÒRጜ?§·Ý1”ÌI¥¥ÒCÑr¹ÉŒàx Úî*¹OŽ–p“ÓJ¡Œ‘<É,)àCÓ8‡ÑZšcÈÔyÙ5c´-ª®‡|q—¨ 4Ž^Æ9Hƒíƒ¤#&åŒyÙùP,¹§CÀœÂEø  ’¡ ¡Y4ÚoɶEƒûœâ\Íñ4‘¢Gñ°3¥uš¥ÿ\+­HLÃ!-Ųˆ’6`Àõµ”—¡qŽY©hA-šU ž²n'ÁÊáðƒhJ¤H†MZàËïÉy7M9 ²£›7é$Œ`Ybµ …($¡@. ¤AFó4WÈ“Ša$šb)Š¥Yž"ºq^NÞ‚Rð¹\|C)ùcɤÈ71-Íèà†ÄyX7¡"¢Œ¤×R‚$`iXmŠYƒHê-6•ctocÊ= ¯è™7”$bYiVòÈXv[_´ ØîsYðÿÄkÑjAjq*É FÞ~ø¨­÷d 7îy™ËºO…vL{G£}@§ÚzÆ‚=»6„y {‚¢Œ¬Ø½¾íDlçXÛö‰È’Í[*­6>OÓ¡´•¤~V_âÞýýŽÉ­ŒzW m,Ô;îkÙöªhd¼¥{$Ü ãŸhÝî÷5!”hbð¤n0ZÏÕ„¯;üSÞ0ÐÈ7–wͽ<(’·ÿ“ŠàÅʈ gÌÇ2¨T2æéœòEÀë?-\÷Æ.zCð´œ÷…á¸ÕT ·X•‡¡s¾È…ªàŸÝÁËÞ—ÓNEÀã²;tÁ&™,{ÛEðÙ8µ^ÍnÏq°7uƪ[íœb é¦´¼+ÕWœ uQXÕ«ZëMV.E›Žó?µV|\óJ7*4êM¿~}É®»#}™nD¾èu »xø__ÿûÛÑÈó¯ÿùÕóç_<ú«A4¸VFZ£?ÒlÝÕ.£×¦Ó*ÅrX¢±4§%éT<…¡äŠ¢Ì±f¹Ñ”¤juô ä3­Î=\oiXê¼æ±Õæñzv½Y§JB¡Ê¾_~°Q¢8^—,A'æµJ6`žAÚ7›âKÿuGF¼Î2Ú¨­³ž\“}tPŸ!h0Ð ¸]ÙX­?øŽþÃ0˜8‰~($¿2öE.äƒèÃ{¨#cwDi©Õfée Sã2OÒ´„ѰóB«™¿h·ìé÷FåýíiC1óÏC†}힬jÉ42R÷ÄÒ:˜üL1 ‰Éºä˜>/:gÔ’Y9oÁ`»c,¾/;ž*®et“{çœ¡àžœ <0Ë.ŠöÓRì`g»¤ÀX0T-¸Îñ$J~¬”=óžqöÏÅ’í¢ž¦S44ÉèŠH¨;µSúÌ9ű Ïèp á'H€4H†(„rä®Á>§:žèKsΠ|—ÀàÚ¤$P!É„aq dµ8¥ÃhÂí¦º7 ó°[aiB&³52ÿPp>bíõÅ‹²í ç.—–¡¡/Áú±@B ÜsŸIù_òŽ~JOÑ)C`ˆ†×$¡@.-ÁTrnBFƒów\Gi€Ž A‡CÔƒôðß6Ûg 6ˆ/$×mÖõ#>M¢R$"•ÅS€”àMmp !Šƒ¥Ã20iNÁ`;HœOÒ]Ñ@ ² :–Fî‹6ø¾j,˜Um_¢¢óJIžÂ‰¸ ÄkˆÍåuc[ú€.&¢;_æò#¡nÈ™ ïÓ O<Ú»©¬VŠÔèd†[_â+@,@‡ý]ýký6Þˆiuœ$â: z Ì‹)ViÉßõ½è±P‚`ÀcmÛ`RÀ¡WE#­=Ç#}'üÝ0¦Ó”…Óp§4K{‹Àà>-m½ä‹ü—ørýâ:ÃøP©U©wwvfÎÜÎÜggwíµ‰/ëÛ®½¯/Ø`ƒ]j‚ðÞ¡j’†øBÔF­¢6Ð*vÛ &I©ª¨ýR©Uc®¥€±c’ЪH­Zš¸ïÒo‘ˆd„eéh53{Î;sžsÎûüÞsµñKáÄ…plª6¹l4êœhHžoØÑ!xÀÄEŽ{Ï×q=Òu#”¾Z¿ˆ_‰¤ÏÕ%]µ±Ä.AО”K®6t_ eQäBmìiñ§êS€4×É‹¡Äµ†îã¡.;!ðÙΑ’c/²ñs%ø²Îâ"JþзùR8}5˜¾è:Qёϊ$ƒÜŒü›À¦³õ‰Ë¡ø•`üR]êl$@r¹6µÔú|R½êÚà,Â, RÇÄÙO¾úòYiäñ?¿ZXx¼PQXdåiÈ€”n/n_jW-nzatu^¦iå@]+CÁbB®`Hž‚Ï–hð<‹B"+§3Îckʶô5x~T]ðn«ãÔz÷áUyc‹þNíèW¦™+í„îDØ|¹À9ÔÌ1’ÁâÛe9e¤ÌJ$"‹ßh2‡V-;~|­å¬ñŒµÉ#Mù£Ípáz)( @)dµ¤@;’Òö']ûÓúÁ”v(õ¼hÄØŸ €aîö t«›ë±SÓ¾mEQ¢@"Ù†\Lö‚Å‚£´Ðýó¨ãp7?˜pîp¿$¼/f ,þÕûø@ÂóîËÂŽ6 1ÀÞ"L rxç\Á@×Jn;ÊgµªyGàžZ±\n2íðß×¼`‘ózð¾äÿB­þP¯snQM#±¹Â.SlBÄ[ï:B3Z)˜þç’¯Wt`ÆjyÌò†?¥æÏj¾'6Z .àÂ_кAçìÆ Ã!È´Zñ…˜S½÷Eï´ø½æ9&$’ƃiŽ£Y†„ÃÀxÈ úc1¸;}"4J–àD29PázßVq Уr^ ת²N³¹V„y` "!XæõšûJᬣtÖ îM„m”À²(P ˆÒ€ #ˆù‘\*²„Œd‰ÝE^¥Y²_0f ?0Õ³lF+ùL«˜wÕ|løú§€Ç 'sH°ó'`ƒäò(^¶ó’djV Ûìëñ·F ÈŒZ4k—E‘妑ϵê[Îòi˜¤ô±~…Õ,É"™EŒW2ßëê;¶õ•ñx0ÆX¼÷\þhª0`#KÑž“±¾£Ý{"ù^X2X;¤§íÅ“‰þñwŸÜù³C©Ý„\¡œ:ÂÎ1Çä6Œɦ"ßpº÷ýäžÛ³¡à½Y~xN4òA¼ÿÌ%Ös`Ë.Í[‘]ÂB.ÍŸŽDÁÁ'@#`©W 0ës ËF#àïg“SáÄ/‹šyÚ‹_HáãM–&'|×B]müñ1_{Îå.fÒL¦ìSþΛáôéúød$ú´ø"‰K‘äPj"ýcxû›ÞU•“#XŠ8¨¾8’†ƒ$BêcybÙ;N8Êß©ZÿjnM5«‹ÈÑáÂ@¦©š8ÈêẢº¼Yr9î¼ÙQ¦P†Ð)«ê£Gþûì4ò¯…,üpC;¥ œA¼­`OÃ’»ê±uæh³#ÓâÞ$7x°…pÙ0Ðâó„çB-Œ¶<ó'ÕžÁf}¤Ñ•i-ÝP<Ô*·Ðã«ò¬5F¿¿h j-Ì´±> ùæ@c8…æ²µ"9«…’1…³›3O`{‚I³bÎYqG¯¼ódáHþß²(»|4 ÍåGºúÞ÷–ÀŒß‘/ JW(zÖoË$úN¦_ß·u—_ÉeQ4o§A1‰dtA‚‚BB¬€ÊOÛc™xïx´÷ƒÔ룱žÑäóAh€I™Î×`:éÚV…Bvކßîò5éKÁØ…pìü¹Z“{=Ó°<(íJ0>ÙÔ5Y“ø¸&ZnšØfc1÷=ÆÎ"r“»tÈßq<¸eoÙÚ„»²+ßEZãáüÖ(æD}×§UQ ‘?Õv~Cüó‘xö-]]“ éS¡Í©âª-®¢N1I#„ÍcÌRÙt@ˆBe3$IµQ ÉÂa´ó캕¾ßWn»\›ú4ü¸X“y¡. BØ¥Ögª>u:ƒÚ0­?È‚È?#,|ùdøÂ[oý‚Àœhå%ul-]jWõŽmÌjvþª±øÈF3´› m·B"Ö Yiµ[Ûô¼½®øh‡ûH³çتÿ1_g¿Q]wÀÿ„6Øž™»ïÛìãÝx<ãÙ==3Þhq!BìÙ¼QÔˆ%† E%6vÁÆûB¤/‘òÒ6R i ¸a0‹Ûl–BŠÒ6QR÷7ô¡R$éŒtçÞsν÷7£óýœü€v,ÌUšúBE}Õº¡°v$T0¶–®Z¶‚ND”á0S¥5¡Î²t9š¬—2HœaÔºÁµkv•‘jLÈÀ˜uzËxÝŠóãM;2 TšÆj }aÃhØ|²†X«Okö6™®Á—Ó½]î| €®f¾#ö¼4bú Ék¡»“æÎ6±ÜŠQ¸€âaEAЏ¥·~eܵpžEÔ5‰ÿÜÈXvnTŽme:ÚC Ј¶«•ïX¶Ž¨c Ë‘Vº#®ëÞf~{#C³‚c…ã«z™¼EÉ=¯@ˆ¤52-ên]©4¹-»pE7¥5s’sž·Ý ?s·Bˆf—Õ"6„âu·>KØ„2W$ë‚ì|À•O*öC¼©¥+ è@FH*Ȱ•”ð9Ÿ ·{¬ðîú6ø 'át€nІÀ@“ÜS\sbÉ=ÙúP´NKEO8ç “JôLpå=hþ&„/ÀA¹ªÌu8÷6›ý±ày"Vˆ@%K¢Á(Œ$qb#Å^Wœ‹ŠgV*™• g%ûLöŠ\€&ËE¶ gê1qÉ^<Ó:t›“<=¤eÊÔ#l ÂTÐ(( Ê ¥ƒB¡˜'µ54S‹õ$¨0!ÖìAÉtG,mç¬iá…‹ìÌ#¡ôk]Ù©¤GÈnfe†³š UQ°žàˆSyXü·¢~Š-¾Ç?ŠÒ…0 ÚOG#stÑ¢l›Qlwdÿk8‡#* ¥Áž•Æ¢Áí¿~œ‰ï9™hŽï>™Üóaì™)ùxHg}üèé‹í¨ÉµãYØ­0îÔåìßܶ»vs™>ŸÉD æ(‚”inÝßÓ¼ëÐëÛm‚‘@0„&áj£³j iÐL{NIk$žVÓñ–­™Á0‚&t/©Ž—½z݇½XÿÒŸ€TMù© ¬˜F®¸â—+ZÎb©@óÒH£¼œ± «Ÿ Fô"èÁÔjÐ5’ñ²—‘Þs×¥Ê[.ù›S®èå1³柨ˆ]ðÇà‡+®Ø´;1lž´¿ñ¹7zÚñêAk$n*-'K&Ü ÁhT ˆW0•†&Õ`B›¡î,à À¶Ke ˜ó‚/6éOÀ™]xÇ~g†©F°UŒ&“OMñŸg‘ï–¾‡ÏÒ7ßÿáÏÊÂQQÅß–_tªòƒa<$ž©ÖŽU›öù…ײµÛ\–žõ…}õÆázýè/sNÔô×K}Aù£ˆ8Ô÷uãc(»¯Úx"lé­Ê¨2‡–{_e4Mßj3UŒZeÞb3¼`§)ØXY^iÔ­’ž@ȘÅзlí¼è&„ÁÜÁjã@­y$$Ÿ ûÊà'ƒ˜“Åt !mÖiÖv$¤ŽøóÒHîÁfÐßÓ&îo\m`a ;ÐÕ¸Z~g“r AŽ3]-æÃmÒæÐÏ(DÄ(T¥R6 ]mLWR>’€‘Ä#ËֈЙÔNÂ)Dõ]m|µÌÌãÔjùÆ «·Îix[q@”,ˆ+¦‘Ù}Ÿ·Þ×Üá9ë¼¾à¦ÑúGƒ{V\^û‡˜Ñy ’npþ”äx$=–¬‹Œc -y@9®Ñî»ÚÊEÑGN‡û-Ö5%ßOçxñmÙ à+œ„KкAga8LrS.ùJr.HöYÁúcKÉÖ›¼õŸ²o^vLó¶k²ëºÁUë¿*ºoJÞyÅ· ùþM—ž£òp"ƒF(Ža†ªQZ£ÞI)³¢c†·ß•Kî*ùôö¿jÝ÷Hï]Òq_ò,JžÛ¢/%z¾£}8û"Uø„±Ï ΔÎ;/òþEÁ{—.…A¡ \P4(ÊÅü†±_e³BÙ=É9£uÝ’üs¤û1m_JoÉ% ‚mV r°>¦‹AðÓÏpÙóÊš­}Jq\V|_ʾÏxÇiºð3Îö7¾t‘s€Cnˆ3BŒš69€mO ÷“шTüDtÞ2x»Å"CÜljÀÉýõM£Éö4švŽFwý/ÊO'÷>+å @‘“ÑÝÀ8þ8Ú]µžÓà¨AIB•™¥'8i5B¬ÊâyžÃ)^7VÔ´îùðõ0C,¸’Eƒc2Fo. ¶´·ìjÜÏÓ>GœŠïÞÕ°…ƒ<ÇQÇËQñl°mʨH'iʃ€žôD/»cå+¦‘)oò’;zηå’/šŠlëµÖ»Ô<¿Z%R‘8˜ kTS:”Æ0LÅeö@^à|¸í²'q>¼èŽN’“¾gªà¢·qÒÓ˜ò'ÏVľp¿1ái:iNù›a¼>0æš+ÝΗÅok8jô7È9V^!@%1M.‚Ÿq­Âßþ#oìéäÑ®W¬­ÐÓ|ÞÝÓùöÇYdié[ÐÈ¿3K _?„N#!*„²q/:U̓KÀ<êF¼úñpö‰Hþp­I·£-èÑX^×vû¾¨ÊÅ ¨ÖU¤t´*ÝÛ¤Þ7ÉΤñwoZÛc*ƒ(hsŽ»r¥÷š@#Ú®VxñP\×ݶÜûfÞJvÄòº·ŠGblGTÿ~n’þË~Ý?5‘ŸÿÚ›9_€d7Ù—ìfw“ÝMBBHÀ$$!/&$¼Š‚ZëxcB² íµN{7×v¦§"Çè(‚¡øv3ןÚiï®g«RßðõPˆàËÕN¨w^tÚßj‡:\gÊ<Ã|³ù¾í³IžÏ—ËC Œ%s–½GéFX×]Î>¡+}¦vÎ@aZ¤jò€õÌp%c‚c–ñ~AÛ&Ã,my²ۼb†± ̓ړœ{F„ÊO÷xç}¾pDoá]3‚oš*šf,¹¢'Œ}\ë~̸îkìã/ð.Â[кAga8Lµ{˜µM1®§¬ÿžÖ3Îͽ«)Lã‚e†«mhû#Î1Í;FYËïa,Z>‡ÎÑÊT”§eJ©´ˆ¼›1ÏjWÞcJfø’ uþCÊú˜ NŠ¥Ÿ E“¼yRS˜eVLòn`À°Î6*NiŠF5ÅÃ:£ã!k›Ô9ÆD¸…$ ÒIƒÔA!LØ*xcB°gYØ&\t~Á–Žk­ ‘§jרà¼#8FEGV€çî†üL²v¸þ˜*yÀ8²Z'Ü~Vm-cBÁ¤¶(˹¦ïCµw–óͰ®º06þ !ÿ|‚SÜ\,šFDçc„×…"2 #H–Vàµ%ö3±ŽtÃOz›vj}·góÀ!@‚LÃÎ×úÓÑ9¤í0êl¤ýtSûáÆjž$É¥8ª`i™L¡H• Ÿ£À¦²šTt×G{~éèkÞ³Î]F+ E5±ÙUÞo;Þ´³?Ñq*±÷ddÁ4;vߊ(p‰Ê…¾[ÁmÀ‹Õ (£·Kçêø%_#øäj™´X H ‘ápâš{Ëu_ãÝ•-g<[ÊLv¢D•P0qUŠËPhhq* 6 n„Œ—Æïø¤‹e±ËeÒõ tå5Õ<»êk.‹ƒ¸n¤á•ñ Ȉ;6âm¼h 7^-oºlücyäB8r+$Ýį·ýÛúm›’o­±Ø‡Ó*¢sK”'3˜çªw®q鿯‘[~©Zo¦JU rò“sç¾þòÅ_Áßè†}ùâÅóçÏ¡í÷úàã Ó’J¼°û{¦žr>ÖRk Ò5bo…Ø_·PUæ4¦««õ©U…©*M¿‡96¦ÖZÒ›¹ V†D8°¡^N9<‘_ï¶Y+ÔSý•†T¥õX©·ÞØWkꫜ÷Ò™S¦Æ|¬“¬oÐËôK”KH#á8¢ZkÉ?²J— ›2UBO{´Â©RuÆãµ=•¦t­©W§kõ}Õæã¡ÅÒH~ª&?½Jè­ÖŸX£ë­µôÖ™Uå¶Š‚¨ò4Åbž"[W+vp+t»ðËäBiDß)ñ‡š¹}QCWòM\fDI2¡6† ]­â>èTjQŒ;öm—éá‹ û!ôœ°_RŽóq ˆ±»•ìŒÎw]í‰ý Á}ÐHˆû$ód¡´v©R¦†LódqžÏͬÊ:­qÍRžÅª&ÿ+1$–NQöUÑ ãœU‡ºUÅV…âcºb„-¹/¸ÆEÇ}ågžâ­÷Åâ;¢åëù”s‡dÄrÐÅä8K *ä»rlù'”÷íelÓ¼êø e›ÐÚý¿åqKg¢õ<%“jç_:ɖ̲®‡¬cDS8•j#ó±Üœ¹c‚Šs|ËëÔ1¯øÙ†˜ÓP2J‘˪"HDÉ#D³·ödboÿÖðÿhÃŽ­?õÐz ÅòT8“ƒþ|}´¿q×@¼#%µeš;ú£óÖ欴7ýƒ0I¬=Ý ë§¶¶õ´t8 GQò¡o”¶ÅRÇM¿t!8WÓoø£€ˆJmÓ¥ðÜ–þàÙ2J\ñKWÊ[.x›îú¿-Ùøã"ßz“µ ×®çLo›Ü§œõׂ µŸóeM°™ÑÒ(å\(z+œüÌßp­ªe°¢árhNh7ÃÉß„«šïânÝ×Cq âõ•±›Á8ˆØ3Xýs¹t9ÜZ¬b“C”È×_}ñ÷of‘—ù—cZš“fСÀtí!Soµ64dVëz×ûjô ‘Ìš«ª½u'j´éJ>UcNUsiŸ~`•õÀÚÜBãPSJC1%h9Š‘H^€ÖŸ]§=Qe<^cJ­6ýªŽï-Ÿïºæþ:MO¨àäZó¡zlµÓb¹è’7˜¥D1¡ß½Ò::6§ª´©òüÓu†T…¶oMÁ@}AºZŸªÔ¤WHté*K_ÅbiÄp¼ú•Ftýð\j!+zëù÷ý(…r…£‘+|·>]­ ¥¾3ÆvÅÄ®fàÁ›ÉÊJ.³ðLWsñÁ¾' I*õ6³_úŽUC,É#0¥Â¨±îO ÝIMw3}¤E<7uÎ[G°"P„9( šƒq]wKAÇV"l£s剋 ¢FI³¾QÁ™¥m¢wÑËÍ·<ž¨]Y}šwd)çeÊ[D råRN™s 1|JÙ§¸à_˜•iOV]:Íù²¬ï<åõÃÙÏs F˜—)ä ‚ø)ò’Úó„õŒp+¦´%¸’¬ºäÿù1ª-yL;AÎwtNHÚ3µû¡ÖyW³âoœ÷0k²äå2ÎÈ1NIUëb ¥‘´´ûu‘ʇ*¡8'Ç­8·mÕÆMmǤ¶ÞøKfl{ç-§$Uy(P¿ˆâFwžŒ¶ƒú“{ûb»𿝑hû©ØžLSÛ©ÄÞ¾—ö@|ØÔ±­v…“DÀG±š1|Š M#·‰Át-òF^iä¶/2T.ýÞ·¥ŒÞÒ¹£7ƒÉϼ[GÉse‘ÛÁøuot°vûï*¥óžÈ0LMËŸÊj?ý‘±°_g¿Q]wÀÿ†ì¹û:÷ν³Ü™ñ,^±Ç Ø3^g<‹0਀Íì61$E †4ˆ6Å`  1ãYÍÒ6U¥(J¥>D„`C¡˜àÒ¦yèS!ÐþÆIÕ§*222ýtu4ºWçœßhÎ÷s›_…ë;µ]¯ÈöNÁ4dª¶Ô¿_Öu½mà*LçŒ}Öºs®ªÿv}èRsðE÷çª+ ¹îŠ@]s†áÀÒWøkûôÁ’¤ˆ ‹ùöñÿLñ<yöìÙ“'Or™,œ9@Žb„Þb{¶[›n*IŒ©N%ÛnI¸ ©Îe ÖdÀšñjSmï¶T@I¶”žéVE³,§BãXœe5…IC`*_-o(±§z´ç½ð 5é7g:µ©ö%Ï;å±Ì¤¬GNJO÷”îi·”ív:ƽՙõ¦œ_Ly홉žòL—fºQ›ô)¯aºÙ¸'ëL2ÝnI®˜Fl 4´Ë 1À á+É®/NtPYÍ“l!„3„üâdØx,&OìX.NÅuQóÛCºñÓºCTfŒÃàÐÚÕ-ò§ôg^+z#¨öÔ›—HsMÓ®2ó[ã¯#êc!öÌ 2µŽ-}^ðÏD|QV⩸úAãÉAÃp¯(‹ÇòÃÐè(­<Ò9¿’*ïLè¿Ékj+nèÊætõ[µÊOÄ@³šÆVÙir'гššœTw„/ŽZ‘"u(Ž£…Š5`t©EMÏ–‹îÊu¤÷ôå rÕ}©úBÖ±â|ÙK¬z$:î+µ ‘‡Rå×bÕÚÊy¥rÞÐÒNÓ«Y”§95J¹Ì%©Ø¾\pÉéÿÿ œx/¶ïè¶¡ƒConŠœêýük‡ÏG2£Sñ‘[wn[çáqJ-ŠAH6V7BÎÁ ýÃ3±Ñ¼(BKŸ76 àÉFöç5²}øBtpª9:Po­ Y^61ùU™ûJÛÀ×ÊPj®!|©9 ¹¶vûõ¦è g>v?t‡6‹%<Ëà¸jª®g¶>‰|¯>ö§¶àç ñOêƒ5‡/7 ~Õ0t«64ë ýe]x¹ÖóyMôrË@¯RZ„ÓZø9PÄŒ’4sc.ă¶uËÚ.Ö½rýë;m{á-ªÝhÌ[’ïOc¾E7êC“ŽnÈkš$x’|}ÏÏ5ò Pñ|yú]=}úøñãÛþŒÄ  U-”d6i3­S~}ʯϵÛãòiĘ ˜¦[”œW™Yoœî(Ît–¿å/4ÑÆóMØX¶×^zȧÄ×j\&‘E¢J‹YÞhÒ§Ýæd«%åÕ%}Eé%¯§(é3g}ÚŒ[“qe;Ês›ìg;ÍSû¹niÊ«?ÒªÛ\jðËÑ:ñpKIf³%ÙeN{Å©zÓL»!ᱦ;ÍÓ^C¢u¥4b¤°CÚ &˜S@;hÅp. WSb [N½ª_Š@iNFäñð"KC eVF(©».ÝP°Õ-—Ùt­Ã^P ÆüꉨéÄ<%Œ['‡¤ã‘%Ï{" WÝñèwa'còé "Í&§Àò$B ða¸Šj×Ý–m+7/wÝQÊÿ®­úZv&4•8ƒ±£+ H–Ây¢Ä!T4…¨YJ¢HÁ )’£¹"ZC B“:‚Ó¬F-‚ø±¼fA[ó¥¡|ÞPöHªº'9îék%+¾Á—¼„ê/”ÚûR4mA_}W®˜—«¾4ÔîæM&#8Ž¥ /Þ{¿oïÅÈèriä\xžÑ0NöïI÷ Ò}{ú÷eÂ#Î `‹‘¨ !ÔœCc:²e qnû>X@uÁáì"‡òsEGáš î;Ö»CÏ è5j#B|àì¿Ú¿ì ­”F X/5æE± i{Ëû¤56æðªqFD©U æcõ;·ßlŠÌÕõÍ6…n5DßutýÂÚœ°uþ¾¡ÿ#wìZëÀ­†e[Ïͦ¡ñÚn«$!H!œêltòFxF"ˆq‡¸2×½Ýüöëõ·©ó ø_0UŒ$¶ÏýnŸs||‰8œ Iì„ÄIœ+Ê øvâÀÔ%8j+•6$„†Ç—pQ;­_&U¬›&*Ê%Ä ½°qéØ4­¦nMØãfß«tFáC¥GGﱎß÷õsŽÏó{ú’åEŠL“‹bF VŒrÑâúËê‡ j¦ös½2Üb.@„Ó/‹ER!‹ AÁÛá‚ã(=¢º’šÅÚÀ¢{ïsÏOM27(l»å Ý©U«y3Ɇ¡îÞ¿Q<[ZþaYú$ÿ;Y~ÖÚܲ¢‚ÆìÃu¹©VÛl³œ®¿ù±FK¢3SUUIuäÎxí)Ÿ!Ö2Q¦õþ† ´Ê—+¦¶ óÒÙJk²Éy®‹Ù•‡ŠÀ0ú6¥àL“3ÕªL×™ÚgV­iÖ ?Ê1Óœ¦>o®É´ÐlŸí°½Ö 5èP= u\€¼"8¡PdYŒbÚ,e#ísbÒk…lÌ´äÆ›ik¥ h$áƒS™ã>À•%ÙaK´é;LZJá «!å¦Je,$3¥°}¢ßpJ•GÃ@‚¢h7R]øHARð B`4;ð6ÓѤÎlÈ;ð3åíýú±ñ­ ubŸéT„=‚ãª5r*l>H'B°4 ¬£ig÷‹û:ŽÏÑa,ÉàXÎ+‚ò©fíËÍ‹ÅÊ/ ågù\Àë%h NËkÏ¡¡íÂHLG!…qÅP4#<‡ÐCz)cê“Í$*à ÿâ+HÅäÂGÆ’'BÙ#¡4òðG|_üYtÁñ)‰Úx_*ýJ_{MtoÁ „Ñ1 ƒk©zKiºŽûW£`€LidN=ïIÏv1|dnÏ ¸âȱ¹žƒ ݃ áé¾Ã“Á»–¡´¨AGîoz9ЦÂà ‡´ˆz£ €(V­‘PÚ ™ùžèyÿ¡”?šT‡§ý¢™GÃpDs±¢kѺZÝ»èYФ«­Ç½&ù¸V]Lk$|¡f·9KGC£…býùU6„ï7í[,Üù^õ./±(ÂëP‚¢4$NhBJ¯*®+îŒíçnEŸƒ×¯Ã³wˆïoVG\[«&–OTvµ+E8Š 4Û‹—n½W^ôøŸw~®¯«z%0øÈí¿Q¾âéU Ðt.&“ ,ñìßKß®¨â‡jä?KKËËËKKK@š7ß8ƒ€*£t;óã­RÒgL5Ûâ^ûl£)™1ÈÉ-ŽXcA¢Ñšl1Ï·fꌑRЈ¥„<¦ðt'ÿN‹mÁkóåNµR-Š00˜6»žVf|ù‰fëL“2ßì˜õ­v]˜Ð8Óo/ˆ·*q/@¨ðõ–l'ŽsŒ¢¡Œë´,­E¸—xr€h)’^/dI?/.žÙ*&š,çÚì±ÖܘϘlX+X“iŠØ“Íö„’`‰5Yg}$slsîqŸ†×0NÀTâ­ÇºÙ“=Óȉ€e4$Œ«Ê˜ÊN„K&ˆƒ]èÖ*N‡Ã£‚8‡S¼ªIÔ–ØŽöÚNôñ£AÓ‰°m|_ѪãX¯41®z]q¼_ÔŸ N†aZРHUÅ©ßZF ¥au™3+–¬y¹yÁãS¡ôk¹ê¦Rò±$DeÙ(‘µãПò$F‚•st‚Ve‚C)Ê  M±c„„fùò]ƒóžTþµqÓßôŸ(IÎÇâÆ'BÅ_ùÊÏLEçšÿÀ<È¥9ç—ré’ë‘°é¶Þ3ÀØ(<‡ÂµA¯Ðâñ®ýïî9x^šR/gL#ßE*0”ôGÏ«G.ô¬`>Àç; «]zËÀ–îs¡a¸&¾w.Hö„+Ó3†æV¿îÊ䃇/øâhL=ôJývhx9Œ„¦¯‘³\õFnUoº‹µ¡µÒÈMwïGžžžÀ wpÑ­Þq÷MUl'P-.Œì=ÏžÅÚÀµ²]wëú;õŽl ^z H„$IŠ1C¯§Ââ7»3µŸ_Wíf5Ù2M$Š;®ºÕy.èšYË'nõ²7PƒòÑ2»qÛ½òðíªàÇõ}Ï;?W7oÀÝ©òßñ„àNÁé¼Á %4Ž¡GÈ;v¤ òÍ·ßü߀äÙò³.ÿ( ‰‘úKA¬o8b^[¬!£étL7Íx¡¶J‰Ó9߯W[Hîl=óRÑpéíúÂé9Þdo/V(¤Ä£9ôî<éÒ6yÊ[”l“ öĪU`ŽÕÛε[’2xæ|»k·÷»q"[O°Z ¥¼ùÆã­ÖøÖÂW½øxÐ`;šœRÚ1Ñ!§Z‰–ܳi“õk¥K 4UomÌÌ6Ùf| #G|³4¿M*Qd‹ü]„°9È”FìãëH[OFȉ<OFòFú…_vK»gžRîä;=úèNËX¿y4¢Œ„À ÊxÄp"HwÕàÞi$œXíº0ƒé­q4ÌŸîã&ÓZáüf4"õȹz”ÅNÊÊ.ˆ5/7/x<Ëo‹ù_IΧBñ•Mï+î ¦xGê1’Ä¡aI’'gIœÃAdÙ:ŽK âË?UJ?³V<`ÄŠ[×_D×Áõ„ßôw¾ês¥ì¡ü£F¾'>7¹¾dO×cnÃ?ùš¸è’M6ƒñ„–ÕèÂÞí³þè%õð´ÿ@ªøRÏ‘LidÞ?œXP€: ÀÀŒ‹á#gB/†µ÷8aR=8<Ì÷D!.©GÁñžÁKýÇàbøV"8´êuCðôùÞ!X©ððdp Mq£& B ¯;}¿óîT‡n»ƒ×׊"5Á[µÁk5½wêú®UùÓ©Š/òa,™…!Eü¾jïÃÊЕêî×u$N°ÿe¿Î‚›¸ï8€¿ö¥2ÒjwµÚ•´‡nÉò!É–I–eÉÆH–veÉ@’0פíLSØø ز.˜L&}èL‡¶tÇ6á,g€†4Mi;} @‚NÚ™N¦cÆÞTšj•§<¦Œo±RU•ñ€C´q·.㧒͆̚ò>ßwœ/3ù |9ªTQšw¼æL›fÂͦ½å£ëNy‡¾¨§^™°ªßw—d^-\+ŸjÍu_nÂkH6›âí”J»ÍñW9_9„™§$V™nÔÏM®)9ÚoéFÖS2¼PŠKey¦7lúévã°Û’hS¥³)J¸5)“t&}êD“.íÓ%¼ºïR)…Kû#mªíÕßU,SŠñÇ8¹þp@×eû:Õý1ÍAÞ0¼8AõòºC9«à›JÝ…nÚžNf0F÷w‚U ƒQeLÑU¿¾ž(Ñe‘dñæVùPs$bئéí„‹ávÝ»œM<,äº/ü]øPwißÚ WÑŠŠ T.B6ä%­ësÒök›çJîÒæ?æ[KA/~-¨jËTžꃘòJJ5 eñ²ô²¢ü&[y›«¾ÃVÝVV@ÝU.ý_𺬫¾ÊXnË-Ÿ)*o)-ð ¼ËUßSVݦí÷¸ª+ò¢û¬ý,Y[†ˤ¡(êÕ¯ŠoÞñaôGÉÀÎTtð`*œ;<„}P ˆ¯_É6éØ}<´ê©IÆŸ¼{œßµXÚù¦ú ¼3Ú šìÎvìx]!Âh„P ¸^*û…cóźȼ£ãl]òn©4r±†?Ùž©çgkÃ3ÎÈBeè¸ýûùXžT$Ñ¡Ô[%îß{Þ<`ô2ùh!)UJ¤4&š«,8„Ÿ»;J•ZŒ¿D Mdq®ûž© Äf…Sõ¡ öðiÛk³žÈ•šð[ˆ”€q ‚ºòOœ1 ¡D¥hÔà8ßøÆ/‚‰e0¼ð¦šKõÑ3Μù¹ÏÇþ¸A8ífk§Ýá9kÇù†®΀£ð EÉÅó=zôŒ ù¯G¶4{ô¸ÞQ ÁÅRR^¨9äQf¼¦¤×”ð©3>MÒ³X驞ðê“ÍÚ—>ãg3~mzõªømw• Í—(ó(¾Â0¾®áŽÕ3MÒk˜ôkÞk+ޝÕh%ÓuÔ ³t|ƒf¤)g%›t >áqÇ}†áÕ’5|`fc©%Ó¦ª+hfÞ÷˜†|Š*–’ÈáƒGo4±ñfSÊä`¦ZŒ¯f¼Mù˜d ŒE•hè“-ÆôÒP$[i_ñX«~À¡ͤ˜ÈgHmW‹º'Bõ„ÙÁ˜ê]ž;Ä˲lÐ^4нwl;ôíK˜pH'×¡ß ±®jÁ`°I(¾—OhXìPHÖ/È´G¢ª¾¨²‡ÌÀÅà¥\÷ez¸+ëŸCUл-T"$ŽÓ’—Ò¥_*”e_pŸ©,×i3$é’ÇÓ ^‘Û>WX?e­PÛ/«m—9ëu•ýŽÚ¹N[@#ÿÝ·ùÿ (r‡®ücý#]uCi¹ÆVܤ+'·˜ê+Té}µý&c_‹“œÁ%8Qˆ–‘ÜO6Ŧ£ooÙ–ˆóÝ)~Ï ~®éŸîè~º€&À€ì³°ZÁ"Ka¨`œß› îvO 9÷ϵ¦‚»GßN {ž®§·ýØWTI¡R ‘Š„7Z×>W—͸ùÚ0„òRiäœ=tÚYhèü¸6|ÖÕy±Fø™}“VŒ°#¨D"‘aR(XÀwšND¶û焳Öàµú®Z‚Í+Ì£ /•³Fæ\ÑGø”“?ÛÀ_ut.4ò¿qO9¶œ¬ ›YšÁD[Uóµ|+ÊBês+$ôÎmZ«¼ Æ£+ý3¶àɺŽSžèóžÏùZ¸øQCð\=̇‡#}T/”J))†ƒFà¤ÿëß¾¶ÄÇŸÙ!ÿ¾÷‰Fvïê&p)–Í´å\¬’JùŠ>ý˜·8ÓF'Ý‹•žìx³6Õló@ÄC²s)_I¢Ý2ÒNÆVJëDúQ¿qr|´É4¹Z=Õ¢uP™FcrƒjGCѱuLª¹l¼]>â4§|¹îkL4«“^Mº™mÔNùµ#­x«‘’ 2)θUÅñù´‹É8d“uÅGÛt•Œ¢@‹ ˜×ÊØxKÑT;=æRL4’n6Ѧ·•d^1¦ÛTÚ±&vÔ ÂY*’C²Y7µ^³®¯`ÄDË­%ºÞ¨¢/¢Œjº˜ƒ!Ð7¼•íK#Ä€@ö   So „@D ?åé. %ËeŠÊdðO,U’r‘–ÖíܨŠWÔý1@ˆâˆ:Ré4÷lÍu_MLuX0öDÙ¡.èƒ8JÈ‘ Ö¢rJ:I–|IÛ¯+Ëî©+®±«®ÒKO/xÝdÊ¡n°å×93<ß Í·”æÛÊUà§0ý”®xª‘;ßÎó–Ü‚qÝ`*n¨ª€Ä “›¬å*c¾O;ö`l>¶¼@†“…('–nw¿2±í‡À@BºshØ0èÎ9ýÃ{3¬4¦"ûÀdx7T*²*êŽw¦:º³2±„v?w„³»Àa@Vp°À›\Š=yþaÍ¦ÙÆ„ÝŒ#y7S^*Ì9Âg\„,ãŒ3r¾V8UŽè+!_Bò ‰ @"Åa¡A¤í?[Ï_rm]°ò+Q²S2BPÛrVHÌœ¯ã/8„K¶²_§OmÜgÀÿ€N&“`#iW{é\iu dqJ\º’ãi;)ÆH«{ܦÆÆnS×õ ñYƒ8q’7©ÛNëvìPc;±ë°fÒ¾k;ÓG™öU;šÀàÑ|gG ;¿g÷·Ã~?°ÓŽð5{ླcÊ?_¶é×5o^¯_uGZ´E/‰y˜„RòáJ¼Š®S‹—+[çêâ÷ì±Y³µ÷gÆ‚§Lº ÏËÂÛÆª¶Jyh´àrÖgñð­5ò|éóõ×Ùµžõ òÛß\æ#¨€bHžÄ­dÒ› =Ú„»(å“§=+Õžòa·6í1$õƒÙ5UÃMÊ„W7äSdšŠÎyµ V¯™m¥š·ò±fe¦aÃ-¨¡¼úòs[5v]Æ­I笣¢„—I{Ôcͪ_9Ôi·.³¹`·%^äã½XÿS—<³©0á+HlÒõÕóxßcøÌ+x¾ªÓN'}ú”Ïòj3CÊ]n4œuÏ6hNÛõ)OAÚ«JÔËr¿ž•ÓH½2áP¦½G›(1—Æ(J‚±½oªOwPAÍ™ èq‰|å4¢ìNÆÕ‡ƒtX{ªCi˜ y$"G)Ç)ŒÈ~ÉãH ®e$m L×6ÃùÁÉòcAÕ©8u’U DGc¹ÎÕhNu¨Ž‡á$§£ª¾V~‰ãppJÂ#+¹M›ÊK?U”<•›d浯§;4e”¥ó²âyÚ¸H/¥tQVúŠ,™¥]¾æü‚ç©´ì‘¥]6Ï|C‘ÏhÓ‚²ì3•u”2ˆy¯àRÁË" LjíFÛH´/Ñö“1÷h¨7ìJE{³U¾½3×ö¿Ù1Ø  tƒI–eò^¸/ÕÞ™UÛàß™™`O:´ºÀí¤ÛöÀ}½Ëö¸šœ”@$Ba^Õ†YG|¶:0ióOÚƒ·­¡–5¢Ä†¶½Y埮 €F¦+ý÷ñí­NZ+Ã0‘ˆ„ÅEóI’ÿººøÏ®øýêâ®à.m•„J)‚Ç[Ÿ4mɽåƒ0q¦Ú¹Q·Ç«Û?6±sÕ±¿TúïÛãwªY`ÏùŸ–­Ç9|!–Gphîßhž°°SµìÕ¥Ý[íý¹îÁeܰ²söдyǤ3²¯ÈIòù '~ñóƒ ‘eE,¿ÍçÙ³gÙã—_ÁšÿøâïR±DH >4à.lÓú4©ý[i\±k†#hDw¡A9äÖŒ4©F)*Ó"Mn¦µ97ä Q¢º}>å ¯ èË$Æ-Øn.-dܲ”#×¹† nÅpv:ÜŽ*Y§ÌøJŽ5çr$ù"FPF…nK™q§sëò ¦Óùä:¥9Þ$öœŠ€(zÈ!ÌØô Gq"+"&ãV']údƒvtåö'Ǩ2 Õ`öÒŒ§PÀå¨P!Ž`¼ÆrÃñ”>=Ñ Ä'ÂY œ ¯”F6‰h±…§wÉ´¢îRŽÈ0‚&)u>sŸSÂõ´ OB.ÂH¬Ê ~ëuÙ‰ DóN<{1 £cÁ\çŠø Îí–öÃM©ú£Ê³;¥»ZxŒáJi”áë¶Pø_–Oèò'Ó’Ê5¯§<‹Rبò'â²ÏEåŸK*þ&­\”šIÊ¡IåËïÿýãwùyD—CÊË"fØÞEQécqÙ¦ê c®ÀP™B1œÄȒ©À(ë‘{?ˆHù÷:‡£û'—‚ûrmÿ Û o€CFü]ï‡÷_ ô,¯<ÖÞu±mïûÞì²þ®$ÛSV[#é@øg¤­s,¼ïTpO‘@/\@QÿlIÓL]ô®É?c L9B¶àlÍšidj©mo×oÛ#SõÑÉÊö»µáu‘+®È!C—Ròø6s°Ä}ÅÆÞ¶Dgììµê¶`¡IF‘„€Àq¤„MÙB¹Îw°®È¸-ZL[‚“u±+ßø½©í#gt¦68YÝ~Ç›µ†»_³—Ò21ŠlD©mÚâßÙüŸÖÆšC–Àœ=²Úû3¾ž›¶ÐMKðV¥Üm‘p ð8Ü©‰É/ÿù¯e‡<þ|E4YN•¹RÈ'( Ã%ˆñP‹>¹I3Ü HÔë+ÖžºL“bÐ¥Kz ÒªDƒ*åV {”éå…fc¯OÁáÒ„ˆáQð‘£;Úh|Û›_-bò9ÃP@‚N9‹‡¾Ï„J$$)æ$ˆô‹‹ ‚O òqAq|r›±`¨Y9êo¨Ï¹õc?Pn¾ëÏœ­Ó~Ð"¾èÍ ‡}k¥é°Ë˜pk“NùH“ö Ä׋øüá¯S^ëlUžéõ‡€"Ê“¦?²‚aNÅäÇCTÄû’Z@‰(ØF!Êgƒ(Ô M“MÞ·]t°]ê¨ÐpHŠòPëFý¡ út}$° Ñ;9_øLTõKVÛ“ D4'£Ì‰°öDTÚZ/ÅÅr.)…×™×-Õ|"·,ȪžŠMk^O/xæ™JÈ‚Ì ™gªç5UËÍ tù7YÒH¶XÓwù¿y$¯xÀ”?Tš–(² )ƒ­›×TMHª¹"%èõ˜ ¡4”t`k4ݱÀ0Æö@qg–²ŒŠœêÏŒDû2±¾T´w(Òs>´7µsÿùo¥C=ïÅ,³4ƒ’¡îÕÖÈp¸wÌß ¹¸ûm¶¾EŒàF(Í>Uºî Ý­ ÌÚØI+{͘«É¹ÍW*ÖölÛZ‚ÓXÇ[µ¡©šÀt¥ÿŽ3>éŒ\µ®Zü7má¶ø\YûGµÛÿ`m+‰QG€ã8ŸwÈè¼UãÏuîŒÅË…ÛŸ°°÷jÂM±kµl›¢„K!v©òrùV€ÊŸlí³uÿf¿ÎŸ›8Ï8€ÿmâ€mI{¯v­Ý•V»’lù6ËÖ}û¶p ¤C¬û°9Ò–Ò4 I)6>0`›•e›«Ói¦“éL§“I§ñ;n§š™ôǶ€I_A'ù©“qk™NvžÙY­ŽçÑ»šý~”X°&æM‘?Öv\2…>´Gï¸v\6u|j‹_qFo,½ï£Kv}À¨2Çþà‰Q˜FPZIýóïÿøz1K‘'O·ÿ…"ß¾ý™FŸÜ€V€L–‰¡1ФÝÌYŸñÔ²¥§(ùB´i?`‰0êã‡]pˆ»p¸A×ZN¢„ Å!ݸWÈØu£^í©Æ isE èu¿ªP8¾¿žhÕešKF›xɳZa¤0ž1íRI.!½I]'ä -‡¸³®¯“>žTuGµ}©åÕv2I ‰myJËY«ÂpˆÂrp9ê^§Ü¿…îO©û:…íÆA¤TD¡×Êò¼pÇË`âHPßßÅuÇØÔRû ƒÛ˜ÃAÝàv¢'ÂôÄ´Gãºc)`-¥½"@ÁMDQËbÊË}ö{|GļǬêø¼ `ãgú«ºö>[óF²Ï> د‘ï,`ÏÁ*©7<`ªï)+ÁÃ[zÓ¾,…hpz!7Ÿ%™’<ü'Mï…÷Já=Ï‘î>Ÿ|°d<¸d]±Ôôï¼y£=¨0—’\A.Ä„¿¬&åoï ½–I½V!ßVòÐXÇnÀªþÈÏ*Ô:FSÉУç{ÄÜ”#42e\±Eæë«¥‘)kˆÚIshª¨#L2iç#“öè”9ü[rÞúÀºâˆÜ´$fí¡îDÜ`braQNlQ—]t„§ê¶.µï¼9¼Pø¯œun½îHþÎ1bÊ9#ÙÃSÎø´-|Ù›© ÎÕE¯E«‹ÍÖÆfœÉËžrÞþ¬6¾Òë3iKÌÖFfÌ‘«®Ø¼96Vó2Éá§iijþ·–c[\\ûGeyêÉ×—.~Ìȱ§Q ŸicGÌo›ËN,[zê†}Ɖäc%¯˜ñëÓ>c¦Þ yUçüØ#„ ‚Sî²Vö¶¬b.C‚dázÃÍÊ ‡µ¼˜À,µ¯jÂ'œ®/i2J~혓›p¤]ê±6݈[Øfa‹5$’NÒT1£ß¾A<ÕÌ_hâÎØô£6ã™FÃH½mÌŠÃJ„ÌI¦Ì©~³]/m‡ ’O=æ]-¦Ô„·â”ƒ=ç¤e;}k‰5*+^‹¾$RÜ[ƒ)º'ªíïÙ­îK.—F´= ð™EÝ©|‹Q‹E?ÓZ–ÝÖÊ¿w0GãLoŠ8ÑYÒ»#¿T‹a'Gˆ‚k³jŽDÁHÀ$ü»ÍÒûêß C;Ñîw¼³` )ö¦ôÝIìxœ?üc¨”W)HðÛÿXÊ Üß³•¨ªU§ç¼n3ew4•·5•Ÿ©+n³•_°U÷T•÷•å÷UëA=ƒ @È7µê?çõ¥ªú º Pܧªî ¦«Úò†0.Gp%'S ÷…èOûS¯½ßqp$¼;“808²;¼ÿ|$‹pf©é.qHŠî=ÔÒQ«Òã9ù$IÊ)âEFp¿‚LêÂ]¯Œ&œàVZ#Zâ‡ÀwÙîmWÁ8„ „)!¹9[DíB]ôCwhÖž±FoØb3æOÕÿT@D7,ÁëÎȬ+9gÉòãckðº+1eM×…€I@ÿ¹6:k‰“,ØÂsÕÁKæX9Í7Š•×\]ӮĤ}ɹäÉbì#{ÈMq0”kGØH‘)’iå¨UkøÄ‘œÞÐq§&rÑøùuõÆzÓ™ºÝ´v]®Þ:ïLÌØcxB+½>Sö$@XŠ«þädM°Ûà’Ãù‰á(öÎÛ‡Ÿi$Kˆ•Ù(L†Ã˜:¿@NC…CíE§½ì9¯pÚ·Ò©j:áâ% „¡¿ `§Ílº‘¢áÒkuFãÉv½@¢Dä”JuiŸ 9uã^~Ô#f|úQ¿8â3¤´#þ¥öå3-© ‡ïó‰oÔ,Qä*— H™¸ÙX>Ôž­g2n}zÕ4R$9ëx©¥PjÎÔsC^¹“3ä*H Æ·Ô•QƒqÍ`—ø«8ß_.¨º£Ô@:çwm&u×TÇõÄ5½IáX§ØÓ)öv)»cÂÀvmçF9£dxI.&à r“U<ce_ Šé[ža@iŽ&øý¯âZ5,ƒhB‰ä¯Y‡¡ïó­_2ënq•·øê[êõwU5_1–›¬iÕcëûú¿¬Ûœã®rÃ]¾êSµáoLÕW´e)&(Æ1Œ hÚ^a}!¸À#Û·\éîÕ=ý±],A„È`ˆFp àÅP]C" óhJAÓ  ido:±lê î>ËÚi,¼÷Ùp0Ùw>ºg0µû½øÏëøb˜ÜŽòw ŽÕRÇóV3–Ð-kò7¦Í<á ¸L„Ã(¡¤‹+ɬeÎÚ5gK-˜"Ó¶ðá+ !à‚î/v^3‡oØ¢W\Ùý5ÇŠÏyÍœ6/¹²h¼cÙfÒˆ‰r0AÐÂÂÂÇÁþñãÇË®‘F·Gp•œ’2ñmÚ«óê¥OUjÂo8Þ¬Ô@J*Ø\\|> ޶•{Ê)œÄJquÈ$ƒå”UhóuCÍÜX½öl«f¢™M׫G³Ñ¥ë ™ÆÂ±_§¿QœwÀÿVŠ{wîyæžÝÙûk{±½6Økï²6{øZ4×xïµM“rÚ‚PˆJ|Ûã½l „T}Ñ}©êš`L Bm ”Ò*i“Wô‡úK}Q©/,­cŠ}5Vóvæûyò­k[–Yç‚J>`Êg=¶+ÝúÅβó!ÓG»¹x]FKá+ïC1 BjY1›ÛLú ‹ÍêbKIfݵö¿bMûôxÐeK·r;M‹í†øvÕÒÎb“”‘ ;ÓÍôÛ'R…jÓôäÇÊ5'ÍC{J?Hª3ÏÏL¤ÄѸnömË™¤±ÅÍI"\iqL,F‹ ,ß0§”é~HøcÃTÁîÇ6½_:“½)Œ¨%‹d²ôG›:iiIrÞ1¹¾ãkÈUw Îo˜ª‡òö¿K® ¯­Wy)s_Øö½X÷€uüUqÞ—kÍm­ Z? Á·¬göýl!yü“ø‰‹‘á…‘`E±á®Šz€¸up†PymGG&‰$ŠÛy.9|)<œ® ½;^¨¹"—Ç!?rᣫgàñóƒ#ÙÈáw;ûŒ…_Š¥+Q檧gÃð‚ä¦/ñ{OßÉŠ& ¾rçp4As éȳL)É÷š«Ó®Ý\ÝM@¢Dß‚ŽÖ„nxâÐ!×<ûî4¦~€û\jŒÂ,{ãPAKõq#Ë"8"b„Õj}ôèógÏVåðìùVXLüò=#8œ‡Hí­TBjÚoͬ¹å×)×^’ï2†+IøîrEúH…ùt3ÙS%b"Ô ¥@KæÒ mÖùcºC•d:,¹9× Õ¤Ìû,ÙÀZç–,´(™&.ß`ýU›5,;סß_gñÛ¡?Pøál7 ¡ Bâ)hÈd~»Á1ÚZ™Ûe‡"Êøát[¾}£4bÎø•\›9ÛaŸ*Y¯z¥Í1ÒŽTÐ: Kiq:„gôxŸy"Q¨ö‡×4ŒÄ („é$;7(Ͳ£ˆujP:·Ÿ‹µrf%‰bç Ú‚±¯1(ãwÚOEŒgÅÉ„:Õ¯ÀëŒì~ôn6ÅÎ$¬? ²É@(Ajö±ü-ÁõO¹ák©ü/JåC}Õ·¬ó¾~û†×Ö«¼”ùV©~ W|MÂ×ÿFÞf ‘b–⢠Èï÷ \H CÀdûŽ\Ž+” F#?Š0‘åÍ(ó~GøRòÄxâ]T FôEÄÁ–7¡FŽu÷õÔNuG.÷-ÔÜU~@ЬjâduŸ‹ùxß§¥”@0ŽaQT{¨Äu-ðCèÿE~çî¹íM~éMŽT6(õ˜!C”Àp†¡IPDG@K* Ga˜†£Ë5àjcï wlÉ¿^þÚ“ú²!ºîñ„¿hŒÜqŮՇkvÁ.Iâp…¹{÷îU0òY2AËb«šöçw®u®ñlƒýÓ.!Û\2”_·ã6 ¥!å"NÆ$ÁZ¡qýV^ŽT›§»³eéœ ˆ™JÆW’ Ú²!Ýlp£4­hʵ›Ó­ð9˜}âbcYºS¬æ´¨ÀðrC™Ti*iœIèÇ¢òtªPí¯Ž% E䨱0Ô?“§’æÉ~îoqÛÊŽ+&0'e†‡¯˜€QX Ê|à ÇÙwàÍÀCÀ+Àê~äé0;7LÆåñ¸Ú!lF‹$FÃP$¶å k¾%ÕÝW·ßQuTçŸtÎ ¯­Wy)ógÅöÀTó¦ösÁ]-°4Rpq¸2J:ùF,ŸX)ë¹ðáùøÐÅÄñ‹}C…"A²y—@1€¢;Ëër{^M¼Ûåp”°WO…¸y‹Ž4ÒÛØv5u²Psó‘¡UŠ@“¬ÊžûKѡӡ>ÃX¸ÆF€ßî/¹7ž/Hn7Æ—¢˾þ婨\a%X¤8(L¦Hž¢p ǵ(‡"( +U .¹Â7šb7ݱÛu‘õ뮑ëî¾%Oô«ÚÈMwã^ÁÊ›X• (‡â„Õ°ZÌh¹®2ÇX¨|a—:ç7äƒrv‡šñÚ³kÖ¯äúœö²}ísÍŸ¶[Ï·nv³ MXH=‰€ä —4Z Œb›-üÉF9‚¡jÖg›k2/ä+Aý¥€)í³Î­hDÍul˜F2Íj¦ÕšÙY²èrj¾Õ~®0ÑðÿlÐò¬ÉfùÌO+§÷ƒ™‚iF™HŠç .cêd ÒB¹ ƒ†ÄŒ„‹2øy”QšÖKxOSÙ{1ëHRŒEt3ýP#ºÑ˜ej `:šŒ)3qÝdDžŠ›>ˆs^'½çi'h”*:Ì›Êîo8ç}Ññ7cÍ=]Õ†×Ö«¼”¹§/ÿ^®ýB®¯cYÁõZZÖPƒ¾îËN/î;º’Ô ¨‘Åø±ËááB©à-—ŸcXÇ÷ºüŸ ž:ּǀÀ² ŽEÌŇªxuª-äoK®÷p¡æþ—LVóÜ$G,OÅÞ)õÀ:ƒå»á xAò™¯ïóÑ{uñ?6|V×ëXô¯Ëu‘\uç^«³L”áÿ‡¡IP Å4Rú¹š®eOüf}dÙ½í뇴»¹³Ý5Ò½¹ã_5í/eŽ$Q–òîÝ»OŸo«ù7ûuúÛDzÇü?X•+ñ1÷øšñÌxÆNì’@Èe'v!”¹|Û ìR–3=ª,KˆsrűÇv¤Z©oVíª«jŽ‚v»+JYÚ­ºª*•}âM_P9 ªb}5zÆžñó³ß|?³°°°ˆ‡gÏr«‘…çOÚwíÆa <Ï¢Xž°‹IlѥꗺUÕ3MDÆÌ]p«\¥ëµT&QÉé*×YÎ6ò©fÝ9oñžje3[xÌLýØËf]üT½!ëagÜJÑΦêMI×›î«OÚK϶hœE¨ S`ìZ)ËeJ$Ÿ¬S²=åºñ­üôö‚™½è¤D‹rÖjL;t¢Nצ\¦¤Ç zѳ\áÓfÊiÌz )§Z„ПnÔÅjÖɾÇHHKÈH>é(>!rGíHD8R„©±(`†b$¤ù°£šÕ2 HFÈ<9)G {õq÷ú“=†±^  ÍH˜_DÐ?–3ƒáÂSaEÜÇEè±(7Ô”®§òI%„# K@'1Ãß”[¾£ÍÈ ™¬dIòw¢òZfV¢$QäÃ$D¹ÇÞšŠõŸïÜ9úA¶óàlìÑw(í;t1Ø—+ ø-éº|LA–ª¸ÎÞr­•ð W»3ᾄÿ`!ª–£ÀùQoûÕîœíû23¡> ð‹Àúbä8íoì€aXƒ+ðµÒÍ}ÕÒq§Òw§6´ì xKrúUEÛúCuø“ öJÝ\áœ3ÈqËümmôRÅν&KƒÖԮߜ¨ÚvùpînmèFM×¼5ð…¥ûšuÉu7o Þ5ƒißÙürDª5ˆ¼º¸ìž½x½4IÎ5òÝóM‹LP+`Ê­/L·±)ÇR·ªö¼G¸äÒ ±êUtžÊÁ1=eüD“ꜳàⵓÞÊ&-ÅS6Ót£á¬¾TW”²Q§›!T¡ÌW *¡Uä!kVïwo.ÛÆLºÙ7“q¾é¾b½.á°Œµ¨¾Ïئš.¨´C›±óI·PÇ73Õ'™íLºY+zøt£>Ñ(œ÷’^ƒø Ë¥]Ê(Â$êÀQH¸‹Mü9·NôÒi®"„ÍÇd¤l #c|êá÷rÕþÀ!à(ÂÄ]¡°**"É]v~((ÂÆcÚ±^r4BŸéÕ ©Á?ÑÅ#ìH”[4C®æQ÷RgÞåCúÑ(9î§'"üpf  10D†­V@ BWüCm~À”.{m­äÿ2jA¿f­L¾–T‘yä-«¹à?”ž ôˆÑ¾)ßÁË¡cWüý³Á~1œ€Œwî3ªY©1’È•‚#ÕC{Ïvþp -ÈÉ ™šOµõE哾 ¹Ú÷%EfB}`€"ñ¦ EXˆ€ H 4W¬]¬=s6ßoj»–oIæmÁÛÖÐýÚèçvÿ/+w}ZTûžnãÁÂê«Û¿´ùçíá;–à½]7¡_Õv}] ¹]¸Þ›³.žþnKèKGøNÅÒÏi ܨ _¯òµÊ´0K¥$N|ö³Ÿx¼î'Ož€ãÓ§Os«‘ç Ïÿýì™ÍlÅ Tà8!N¸ Ó[¹”‹™ròi>ã Z[HºrÕªgAÚKs›Äí79c+ì%¯>Ý ,$¤ì™u®GÔ(† .G!T-'WГí`ݤŸisrÉC¶‘›¥ìf§¦´Û˜tü·}9±쫟ôê²[µÙ.Û€QrÚ«ïµ@&L#““ˆ"_†²*šm)¡²ÛLSM Ñ®šu°™:}¢¾0ÓDçîOÈaŒ¢«ä|kž>_…a¬î­Ðœ Eh&bT<¤ õ€*GÇs¦üãݪÝ'ðÆp@Àƒ #1°ÖŒ„©Ñ3}yñ‹O{Èá°z$ BŸÙ N ú»Q[)w`¸š#A0$2Dއէco:òhLÌjT°ïI@#¸ñc yL—=dÊh7þQ»é¶â[uÕWTå²×ÙJÞª<¤6½ÊŸ5›QåßjóH[v_Øôµ¦ä/ªMRWüUiýжÅHŽã†¢8NKÑí…•  ¯D?LuøZþõ¼z?:’ñží>r¹ãðOƒÇ3/ýûõÛÔ}Çüm«´M„Ø>÷»Ïñõø–„„\¸ä'vìÜeH|ML€Iš4PÕiHÂ-øn®ëº‡íu·îF)tH+£T´›ªi•Öe?“ iHyE8H_ÿåcÙçÿ{°Î÷óøú»6:ÔJ‚çyŒ ŠHF¢9‰Wã(&Š"á6NsxGw28tÝ3´Œ¹Ú=÷ô§zG.vöÿ´ó­éà@¡lc:‹§9b­˜« ܰ§{íözOưBr¯Üc“ÿvE_¼²C†C#¥Pp˜VIQi …vKi2§ý“Ê=¿¯í¾]×s³Ê›©9ï”{>¬ñÿÊÝ«!(áDÉ#Ø—_µÌêXZ#óß>ì`IF«$Yáýr¼E/?iº4E’M¹©Érµ§±!äd[n¬I³Ë3®²3M¶ WÞa×*VNgqƒ³¬’'³8¥ üÏ 8«@ÊyëÉF[¬Ùz©MK4B`69ì0'Ü0°œp£ Kí«I4äÄ›lg9Éf1Y/§\yã.r‹‘e0CM(‹ Í‘z¥ŠeUê¾à„Ë–h‘fºx%ê0ÅšL‰f["óüx6‰z[¼ÍæßHщ‘Âp&½áx§îôn0hA7J;a4` ª'—‡"é„W7Š@`#íX`$‹ï%òäníI?|mQ,òÉž5ã{Ò 9Û'½ëÍéû¡:ߪâhÔ"Ù†vZN÷™ÆžðiÔg ÁçÇ0ºË0¸E%‚ ¬@#Ù"™õeûJªøD]ôWðP.} —|Á?ʾ”*2^¯²¢’FˆìQ–^5¥’ÅÜK¿JI…Ÿ ïë˪k¸¨Æ² Šbi†Q îµ½Ãà„‹žYß‹´<¬3¡gp2Û5p-8ë:¾ ‡ýýqÚ'ðádç>WáF ɲ)ÒªPñ,óÀa–X¥XÃh¶¼9³÷h¸cÿõàÈriä’(ºëhFºxûJðí=Ž×9ŒäpZ%²E(û~Õ›V{S±óãêàÚžŒ3`…äf¥ç†£ï—5ÁB”ç %†®² jxPU4‰âÅPUÄjú,ëÏ»ïÖ35çí ÿ\…ï|Ùf^…q%Œ~£½}~áñËÁÈ7ó °Õ­›†¿4¥D)ZI”sæH4;MgŒ:/%ËW Îô gš­‡1ÞP˜j[Û» w›¬¸h&R–šWñ$AÑ$¡§i‚@ Áš¼£ESn[¤ÉuÃMÖF­1‡9 ´pËáz[¨àÖÆ\Ú„{©}ÅT£%âÎ;çÈ7J©hp“·ä\‡ñÂI‚–U(03òíwµ*‹b{NÉĈ.bÀcnsvwdžÏ(kÖnˆ:‹Ïo'JEWHA½gZ*@#ò{ݺ>íTH}:ÝòpiX&Š@òT#‹I+eÌõ£~p˜ˆ¢9é·h&wëN…ôã!]‡“§Yx”ñJ\‡’¦|ë‘.Ãd¾&ŸÛ£™è6>·FL“=ì)?{p+A׫9œEž#ÆëçBå¿´×~¦-|¨/~Ä®û»T–ñú{•ÐPä¡~ý"Hžjä¾üŸlñ§šüû¦âÏ5Þ h:Ÿå†'v­aÍ™`"4|¡óÀlpx¦kà4Iÿö Hžj䃎Á‹ýáø\[Š%“·Ò}Þsà²oèòŽƒ×ûŽN÷ oÛ`7(HIIðxÚ!Pjœ«ÔØŽµûà>³žÁTW¼ëÐrinõö'}ƒ—<ƒW|Cžýë$`FÀiÊôN}ï«}²?Úè™Ë´VNþPëým…o¯­*›D4$R/èv˜ÖFV«I’!eVÌV*I–Z•ý½ƒñ×åÔÈ­rÐT"k†Ra‘È…ùùo^ŽFþ/ÉÂc«^¦HG•¸6Û2Ö*‡–˜ úÀºŒ±$Zä¨[ŸtšÂµ–”£øL«ºLü>©äI` a:JAQ"Éä ‚Y`•ŽÂÞþj«å’SŸ°ë®6¦ërãiŠèÃvsªÑœ™8-±&C´IŸÜ¼Ô¾†d«<íÌMº-á:ãŒ#wª‰ÊãX‰«T„Àe3ÉùÇ7Ï· J‰«Åìu®‚ÄVí…zkªYާÁc Û3Îg•u¥Þ4m7¥^×ü¸2ŒŽ² NÐn·Œ‡Ôãˆv²G,'—Y#Ïòf¢G:4MõEÄŸxô§wkÏörã~a"¨Þ«90óñ› àɉ`˜gádG£hv®Æpx§î\ŸfÔ§?ÓËŒûòF{ž[#'ºuS!a*P´o›N$+¼Æ’£Óþƒ¯zÄÝ5Ü7ÝÓß3¼ÒÈ«ü_@#°E5òôò¾¶ô®Tonsë¶B}¨©×HDâeÁ׋æiºñSÐ×=o_èØÅ?ü(òT#‹—¿ð~4•Vr‡)‘ÓZ0Ï¥]ý?÷D·ï‹#¡¡ñ®}¡šV»¹°LÎm)©Üß¼ã¬çÀµžÃ³;>Øs,á}n-©‘®dÏðÅÀÐÕÎÁïà®j7®Ba6–$«Dùgu]Ùèû¨Ê;W¸U×=WÈ8VHæj¼o ³Z ÇÙ%ÃûåÛ§]]&F ¼S.-¤D‰eµ$-2Ä9ÿw=ÓHUàF…¯Œ‘xœ@I‚&©¿Þ»·ðxþåhÐóøß_/,|ðyŽ€Ö¤ÂØWk;Ó‰6ZãnÉÿ‘lZ®öŠ€p@#–(4»ÃúN-¢VðO©V,JçðR«ÕôN•m²9?XG`x®fd.é°Å«*Å+î5gëå„cMj³!êÔ¥œ¦—9ÒqåD[M±¶¥öµEZL—ár“©6'œ¶#vÉ’qãÙ¯³Ø&î<àoûÚ9<žûòŒñ1¶IBB¹ÈIÛ‰ãdiÒ†$¾XŽZ¥(är ‰O’¥h+¤JûP©Û.ªv[È.,Ò.B »Òª}Ûm—BöoÌf%$¨,œ¬¯Fÿ™Ñüÿ¿[þ}†ÔIòÛP¢¤¨ÜQÂ-X´ã6žÀ18Cݶ+/Ø,Dë„ Y¶“ˆ!sÊùñâóŒÄ£*R/.6“•r*} 訄âÌ…ºÌÒAvÒ­÷ Ó~Ь5ç¼ÉÒˆjÒ«|–Ä®r:Å”¬N©'¼@&ì¬rÒ3íÅÃì9òD;¯”œ• E½-Ã)ƒ õÊm³ ™€—™öˆ3½?£ží}Ü´W3 8ä áe\†Ö Ê-4̓ҳ¸ø/{ .ú«|ÇCÅ®û𢔷¿7Ù\á ÉŸEÈ €CªŠîªr¾c‹î**Ëâï²0F‘å”Ï÷fÍG;•ïTKBˆ^J RR‚Àé&³íÑäÒ-aæ|àZM \¥šëvzå&½ìŒ—˜v¨>vÞK ¶<§J#0‚¤%R g4k\ñ÷ŠòïÙÝ÷U»RßþÞd3%N¾dƒ"”ñü‰+)' àfñ œ¡è¦¼‚€§?èú¤çýXÇñËÎ!ÐýW}£Qç+kd!I¤¿ÕÁC8E$ŠçsW‘9ä¾è:qÈÜü^±ÉUa;ûnoØ5–¾âZî¸á½Ú9ø±'^ðÉêÁ÷W€[ºú“¥‘سڢŽÕôV#)NS8Š•É…Ïª·K·ª\wËœkUÞßV»n—ºR΀M’¯k\Ñì Ã]-jþ}•§–ÖÐݬÞ~·¼çÛ2±Þ¨ÂðKÚ¿­öݬNÙsû¦Ì5’»G¥ñŸA=rlýéúÓŸ^“FþóÃë러ÿø·ïþ¡f²­(„"„œÐ\0Cõ ˆá: uت š“Õ=ÅåxëBC°N}Én*Ç)œ•bL_!ß•£‘Â2J+£Å 6íj½1ëC ì](i*KVvžoàVAUfí’);Ö˜6S‚b ‘žI…ÁvÅl7åÑNøÔ^~&ùÙÐH"²@|W˜ŠëìfMöfne«óå$gBõîü!r¬ƒœõj.Ιè¨À¦]úéÞW­ ¸…/7ë&¤!å`+¢f00“H ,í(¥]cKþ¬-ýgª{ß›l¶ü®0NPä¾|×=.ïsº(_N8DKPT²„Ìš[ñ[ñ ~„»O\ñŸºê*uõÇü#?[#ÿïûÎA ˆÝ9y,F"[Ò-Y»çÜý‘ÞѦ{´Ù²L”GI*]šË¨zªWúN¯º†®¸†?q\:Ð扸O‚ƒ Ç;Ž^ëû Y ºÀm®8OŽuô( Ã0'hœ*«¿eé»Wê¾Yíø²ô½{æƒ_w®Uö¤œ›$¿«êþ´ø]Å S]í !ˆ#yå7+]_U¸·32†Ä šþXæ¹SáK™FÊÝ开’Ò8õÅç_¬ÿ´þš,>"OxüôßÿZÜÑØ¦“ò$Î 06¶€$ tÞ%‹fɬ‹Ök£õ$ÉêžêH¶hÂVCЦŒÙóƒí|¡§P<3CÑY ]²‹Akv¨IjÅ,ºX­1X­¯P·i³Î¿£}¸‘Õ«&M¤F®ÕÅl/[L¥[4{É]¨cW¹ùF„HF•e±Bȶc¡I£æI)FŠAmÉ ( Íà[³s—[øpÕö˜M³d£ö”óã…ƒûŒ;Ù«»dU_4Sû*!Š•"ލÛM@ èœG?á7Œû˜¹ä dÒ»A‘DT3~&à=Ê zÚo ”÷5B;5*EQz¾×pÆ#œ?è"žõh§ü0š@/ؾj=ÙÓ>zÚ †ñ˜j®G9Ù¥ø •7êP’d’E Tº­“b¾áw=âóSÞþÞdSeC#”…UE@#€"w˜•r¨”À`9FdB9¯tä뮡ë]CËŽAÀ ãÄr×ÀU×ðÙ/· ¦î<Ž¿ìÃNû`G¹œûÉIÎÉIÎÉ…ábÂM$&! D¼Ôbr@íÔµŠ Û:£µŠ¯U WÄÑ™Ýî}föÖµU\V«¶«+hwÛ}ÜA‹û‹¼Ö‡í€ìƒg¾ùÏï&sòýÿ“ÿïû ðÉplÏúyÉáM,3€"ïÇäˆcúÛàþ»¾m¥$O"„Àqš"QÜBilíLuõ§£}ÉhŽCF»r€4Ï6€"éÐî…¢‘d|o¶õ'—¢ûÜÆRZ E©Á ‚ïÊþRÙv«*<îý¡.4^ºãìw,Yªþ¿éSGpÊÙ­C3Çï/«›¨Ò qßÈè>µ‡³k¶h0ŒQÈǬ›g¬±ßzÃKæsm…H2w™4bDfŸÌÎ='™››ƒqvvÆÓ'O‘81/³Ï"$_5'|bÒ^œñóçý\¢.?õÌ”ÿ_ŧ¦LC~Òð`HùJG6êwTÿ¨`i ô­«óÏøLYOþÞi>»AˆU°6£ˆ¢º\x³Örz‹¬H¦•J8DùR@n;ÙdÉlä“õúlƒ˜¨3§ëõ¹g~ÿçš’õyIŸ9ãÒ¾‚󛊬g=F„X®V(X§¨}ÏÃuÙxBÁ­$€P ôǶåÖƒâT‹˜òfæaW^Ò+d¼‹MÆ„¬­`£Ÿt#^ AsÊoNæj~4 k¾Â„¿xÄ/dBÖWÚ$ît+JY²’VÈÕ$®&”RDA5æþmÊãaáD'3Õ/ÜR¢Ã0´ó˜­-Õ.È †À ¨QR4µJómLDz? í](?©X_º£l€À[6ò”sb}cÁcý=ë_£pJKª¹ ÓP("‘”Óí·þäî™pÆÿV¾î^¯m»j¬0uF¯ºc—]‘ñÚŽ›kcKŽ‹¤öØ5{øjupܾˆ~ìh›¬m›p¶ÿÙš¨ ^\ø¥»õ–»ûwö`‰\%§hNЉ2’Â0¹ 3Kä¿v§jÂëÝçTUÇUO×åêö‰ÚÈ_í¡kîØ»bn¯¬Ï—Ò¹MñxüÉ<~ Ïçzüøñ|ñÅ›jFE`xH,tÁéM‚†4䯲;‹ÉK[1ÛdNçh$/]ǧêLéfÛÙÍE?õòc …é@^¶žK¸Í]Ê“\ÀÕÁPƒdé ™­Lo…èUî¼¢÷ܩͦD“6YoÊ6š€4ÒõbÂó¬ÏÍK ÐÔÃN.é·e¶ïò,/RH†”K_¶·e+‡¸Z¦0:*¯ÏQ>¼YŸjÒ¦½£üá:€í³ig¡[]mm‡©v Št@LŒç›aEç¼…Â2}Â…&>í7¦6X÷ûø5Š.W„R©¤q’‘ ð·EIPCpõUǺèvã`œ?[tìÆ†­ïÆ «‹(#US S)p9‚ЖílÒŽšºÅ#yGâêSݺb†c]º÷ÃÚ£QÕñy" |ÂDÊq°G|'¤)+¥$Ø §ßüò+¥8zIUô™Éù/~íŒÊvG´Ýçmߪ+f¸¥ËZ\qÖ»l錮ò¡®jš±N+sP:­µ~­¯¸£¶ÜåKoë+î©Ö¼ÃšiL¢’*%M ˜WEMC{F£ýcá¾  ý DûÛçc{ÏGû¡†1Þ3Ú5øj7‡œg&ÉáJèed£¥²©ÒN·‘Ñ´®ñœ‹ìδïZ(?€éÐnXãÅØ>˜™€%XõÅhß™Žå:#† ˜a•*ÅX‚Ö ®PPr™‹Ñ²®9c“5‘kkÃ\štuÞtt|â ;"×í‘I{tɱa‘ô{gû-{ç5Ñ©ÚÈTéë_:â“®èç•ퟯ‹_© N:#SÎÈøšà5ÿöƪÀqKC{D ”ÅÐV¡øãúøduÇxMû¢ÓHMä“uÑ+µ@#ãë¢×áx"m±(%àË…vý›_üê  ÁwOfç¾{n4òèÑ#ç€æž8jí€"4II©åÅ}>õhƒ1S§O{ #uù‰€~áÒòÝ8ì3y̯n´ŽÍzõÀ'Ã͆ôzqÀËT*qLB£ ‚¢YD)G©U DY‚æà15ê?ôŠé–Òáæ¼áFÝOŸj0&üàÓ”©×§}ÏNù†¼D=Ј.ãU&]ÆÑëЪ³„Ts4!c¶Z ‡¶Ñ^«’¡kUº÷ë-‰fc¦™Ëøu£þ¼”?Ø e]¿Ø4’c¿Lƒð#‘[ ÔóSØÓHn™BÆ ,g;(Ú :0l*‰z—­*$4â*Z-§H‚"Yèˆ@3r)ÜRZz6‰gÞÐj!ý™F u o¿&-xŒ&娜"à‚®%”r{ZUt§·ë†Þ1ê$‚^ʵ:ÿ@Xsî €¼=üÑ(;S‹.”õ`Xu4,Šª]åì*T¥¤Wh`o$r‚µÞÖÖÜÓ?à hKþ.TÜÓT/}\¾Ðbê6o»«){ÈW>äl÷Ù’¯Åò~°E_iò¿ÑÚî‹ÕŸ±5mœŽDV¢$!ã9¹Tf$Õ=ž–DÇî‹áþKÑ}9`ˆö.`úgbý@ Ép/‰H/(ß÷_öë,¸‰ûŽø{_Ú°¤ÝÕ^Z­Ž]iuX–|1¶eÉ’eݲ±9†ÓÖ--\i“ƒmpâC·,s Ó§LŸ:…!ሦt(’¦t:M'p Áô‘7 ¿°ó›ÿH³»¿•þÿý~Ö¢ª òPÇq0.Çe‘ZGÎ?pÒ¿AH¨„/`ýw#¥"CËÕϹða€"€t`ôv>rÈ$×y(ì2»)>„ !B –6¦B9Oá8ˆT©ã|æíPW-˜:ïZ ryѽf ^iê¼a Þnß1î4=mWªî›"´…ozún5¿´ô\¬ß~ªÆwÀД6´}Ö¼Þºk]©ÛµhŽþ®q—™RàÁ¦V ÜŽ+sÆ-wZºoƒÀE׈) þ”[–ÈbcèKk´`cà3k§"E|„$IŽã–þûcA#/^þðbéíP¤€WÛÒÒ¸îäø&D ÇP¾ª½œÊ¶r)»"ïÒÎ:ôq7—ó.[àfÚJS¾Ò™Õ¬…ÍØäy»lÞ)Kµ°;×cÈö=‚0¤@*‚)lŒïÑu¬vÀ©<ã*ç¬ò¬­"åa.EÒ­›o×e}€7š”[q±iÇS>éѦ=¥i—6ïarIʦJyËf}åÃ^ÌNêVëâ.nÔª8ÖPíÐfœLÂ&OÛ• eÖ¥šsèæ<꤇ʹ¾€{€@ pk°PÒ :{UƧžÙÈ„kQN@ PZ*[…0)E(A+Æ-#¿ÒnÐc¼ ‚’%|IA7ÚM…ØÉh±5¢xß_¢ E¹†Â0‚— «`ëhPÕŒÄÄÓ{Èɘ|,FǨ.'xóCD˜f›]{",?Ó-HÇÂÚ‰ÞŠ±eS“x*¤þ¤—9ÓŒÆTÍ”ó…H`ñ QÞ>š}Ä6|GW=r5wekW<.ßUQ둼övÃSéÚ¯%¹š¯U5˜ªÇÒÊIj(ê?§ë¯ù¥HBƒ”…!´’bo Í~t \òÏw*ø¡÷è²¥`h!0” ä¤ÃCàä`œéì?ݵߤÐS&&D4ŒÙ>ûæLß±‹±c›*Œ…i,¢Ô°h*rh¾û(8p¹ú9^ˆ‰š½åýƒç‚Ã#Û÷k)†€a`4¥2ûZÂsDG–J4 !BÂ(ˆä¯ª†È.mÃêv^m ÜjŽÞ³FWL»¯5í~`‹®8ŠU¦ÐÍ–ØõÆ@¾nk3©Pbb%x — IóázLúq…ýŠ5´híþÊÒs·6ðÁzo¿ÁrªÚõûúÝíûÀá_XÂ_˜‹®‘Esäz`O¤€sø®1|Ã9UÑBBÂD¢];v(ò¼Àƒ^þô–5¶Ÿž/ýíñ 8 ^cqB‡jæ:Ø„C‘wf]åsnEε\i Q–i+˜kÑ$mšœCs!üë(’§ä‹dˆ\‰TWK;MºYgÅ”GŸÙ¬Î¶VÎ9ô){É'Éû˜¼W9ïÕæ|š„ äuY®àeê}*@¬g½ºŒ[·i².ͼ›KØô9oE¼­b}‹üœC›pT&¼!TÞ®IÚI€¸Y{YÜkÈlž‘g<ÅÖhòõPðItkâòn6ÞÌåÜÊÜFzЈ×K "a'Å€lA¡8έ×w wMìH µ‡¤€%D¸)¤ïf³<{€ñ[#Ô™nº¡J†^˜N+ׄÚ$'ù>édüDH1Ñ+>ÅÚAó"“Áèj †uÙè©n|*ª:Ó[9¾Gu"´\ý(ÇÂäh3–N„e“±²]^9Ac–˜d(ºº#®*Œß³ÖÇÒuß*W>.ßUQ뉴îyÝSÙº§ÌÚ'ìÚ‡Tù²ê{…ùÓt _«AB¡€KD«aBM¬æôö¾Tl8¾Ðs|!4œó\îýM&0°\é¹kø‚è\øp6Z¨×¸<Œñ‰ÿÀ~×Ö­ëšö:6ìèŠ |äß»¹Ú$`(I ˆp‡Ñ+øÁ?¸\ý\ w—ˆ æûŽ¥w‚Æ<†˜-%(!D4—Z{†úÿm9Ônh“cjH a˜äcŒ¨–UŒU¹@Øý¥1ºØºo -6…®Zv¯<ŠS×ÌÁ?#“:»§„¾šÏS4ÅÇA CÃdá­Ð.âÎV¹î5w?ܺվھn ÿÕÒ÷UmðFc঳çsS°Ø}ܰ¾ƒ·¡?›bWœ=[h-È <àÒ…‹/|þòYÁ!ÏÞŽE^mÏžýÿj/ e26.F_UõKžt1WEÜ£)œ¶/WÚ0(“ÎÒ”§,í¥Mع«&Þ¢špÿ¬Š·þ9MóÕFõ‘Qžw©g]Ô‚µÊS ‹}ìÅYªEù©]›jß²i‡*aWÍ9Ài9à„£,ã{³FÜʤ½,ëÑÄí@úœ°¤4í”λ gH8Õç;ÄÓN}¼ÃؤJ¶ëSvCÊ¥‹;JgÝút›.Ý Î¯Î·[#ªWà&)Íx_SüVú´O—õqéVöCíQá4_ñ!ΈX«|~ !%]¡Žàôж™ƒ3"Ó#‰£ë7Y ¨Ì1 ÆWq´ôDgùh¤Ø‘º—{?€—qRžª,Uöog&z¤Ó{ññˆòìí©n´[ìØ@ó„@¿b•”@KsÑVîL/;Ù­‰r#aj¦w¹úQœ «ÏöÐ!f2$c“aIÿ6RË1BÃ… ®‚Ñ$Yù±ù;ªfÅãò]·¤µ`ÿwfý?$Õÿ$«þ-mø–µÜ7&Ê9X þûuúÔÆ}Æüu_´“Öáv÷·—VÚÕ}r`c #¡ Ç®ƒm¡k%!l1·À`l'¾aƒIq×þ NÇñíL›iÚz&õ´iû¢ïìBèOq_ôEý"3’ý&;ßíh¤}žÕ®öùü0ðs1)D1Èi»n÷Œ§ó6?²êLù‡½}©Ž‘µàHüxÏ-ßp¦¦¢­g³s|ˆ8]£‡<3§oÅ3ð:wNOĽý‰öÞµ@¤ÏÖ*ÎAH ‰D¨©Tfü½ëÞ¡[®HˆLõ³é$Ü}`ðd“®ÞÍàhªs´ÛrT,$I8IäÅLÉÇM§'ìãc¶ öóÃæáî]æ"+…J(N’8æÓ ¶Nΰ¾û׺¿ÞÿîÙ¥¼¨95[}ˆÃ°Ÿ`¿PC‹0"!hi *@¡„Þ%{$^Ñr×üjÿÌþmç÷ÆàÃ=®/ùû¦ÀÓÚì·ZëyØÀ?ªó=®ãí÷ýáÀé;îBÞVð‘ ÃüãÛ¿ïlO‚ôë[Û^¾|ùÝ÷ÛkD§¦¡F(! °Ía½<é„r(Š9 Òs?CÓÖ°êÇš`”1›6ÑlXjÖ-Z qû±#d›^ÓY[zã~É,Yª’%ëô×¹`±æx©âh9Û¹OuÍ®‹9 ›Ëc-Êe«>™öLAªY¹lçbf8»!œÞTW•0+b&MÒ Ç:ü¤j±I•hÒ.Ûd›Ž¢Dsñœ5«o•-Ú ³¶’…u‰&CÒI`XnÑ&òEøõF]2c*{SÒ¿L 5¢MØ^Sþ8ª9“z²EÙZÎ* ?;dÐŽ$Î#¤…Ž„@…@ˆãÐ(ÛÓ¤i?Œu”–æ‰$<´å!KKUM› íãF›*?T Í&qzët–ìóçtþúý:möʼ%eñW²¬ûÊÜÛÚ¼kšì[òLx¹¬Î¾£Ê\óz}™gæ¾,uIqGSp/Ñ´$/ºÇÜ“ç-©ò–UiwdéËê’]E+“’˜€ˆ1”').BÌÚô··x'ABǤ»cÂ^­–ÿÀ>ëï>åÚs.Ø{Þ~ßÑöÞî>{IuGRœaJ‚áQB‰R°Ä„4IDø­›"Á® G뤳ý¼§ ÔÑ^±uðUϸÈÛ ZXaRŒ«7ç9_û¸¿ÜuAèŠ8íۼœ„´,&M@R¥©As¨¯þ­K¸¯@ÞkÛ÷ÌÔ%×$K´tÔ/J0ð.†¥,ÓÉÝú{«û£šÀ´YX,q^7»g,î˱~Ìž…aÞä^(óÍ—zgK[š*rΚœ7‹œ€øÔ´Å÷—"W•\Oc˜LŒg“굚Þäš*s}bvOºfнýÙur '„cØm[¶®0¶'ߊäñxðcRVƸ{÷.…r) Ð#ëG´ÕúˆM­}Ñí¬«è"•PÐHJ¢”2Y—– óf l4Ú¦ [h†ãˆ34ä®='~XxŠh¥z¢*9bM?Y±aĪ·É&k“GªÓ#[Ti„<žf’¦áŽCcbŒ’äÔ5Øåx7Üt¢Ýér´?O#ÂɰŠýD[h´§Ô^#"%ÅÐ"LÊ1ª7·iކ”ÃAnГ2ÔÌ Š¡UÓˆbÀ£ôôC!nȧ8HÜÝðs=ÿ¯pó8’Å*%IÝëP.N´(ùeÃ!õ®-d¼$NÉÈQ’£Ê¡L¨ï÷úSš_{ÔÇBÔa7ð†>êU ùá+øAlÀ­ðFÀ?ßwΕ c$¦¾ã•׈H”Ä0Œfi’âh©IŠŽsë¿ÒZ–yã׊œëêÜ¿ó…ßÈ ?SïrÆ/eù· >W¿ÔÈÿhn© ï$-i ïªw™÷”YUä|ÉgßP”µ³I*>{…†uEPRDªæÝÖ×O9~u.Øû¾œõtBÅGW¯åÏy»Æ{Þ tÇãl‹»ª3  åy‚öåÛÎ7µû:„ÚÍr’ÂѰHZª·žöLø:#ÎÖI78('Œ`ãí\­ W³:N7î>½³Ó^l•­AâÅ&0F•ñú7önìë)ß{ ú@wy÷[µ}ÏÓÈ~Û~àJg}gS¡=ƒI“!4PÇ$$IJïVÿP☭üåtQ`1/ðq‘c¾*ôi¹÷’É1kñÍ™½WL®Ù ÿšóã©LÕ„,þkežÅÇL¥oºÌû§ ¯RÆ&b¤ˆ',Jý‡Vÿ”±ñ3‹ÿVEðbÑë—ÌŽ«yŽy³ÿóÒææÔb†Ó(ÎôZ͵T˜ª“¸¯:LþêDƒJJr%E±ß|pá¿xøð!häÉH‘ïjä_ßröåÅ¥¼”F œ¢âu]å²hî”U÷â5’ÝæQ–FëNÌIre›7¤F7«G,Šó•üd}jSsƒ&2kΉšSUú‰íD¥*Zšµ$Gm)‘zÃØk†6K¼>ND­£9Zž€ó-%h¸#š<ýöV¡ùDýÝÖ¦Hdû±]ÂÈžçiÄs<ì:ÕÙpl׎‘6ÏpXgJGQ‰\Ï8›‘¢=èåú5ƒ~æ°Gs,¨VK#š¡`âÑ 8A=èSö* a»(G«"Yi‚$†+svæÛä#;•ÃÍŠwÜ܉†ý>Ö¸# ôßì×ùS“ùð¿¡ZCò乯ÜÈ!H8 $$PPpE®Ož v " ë"‡œ ‡€ºÛ™þÒîÎì´;Ь‹«Õ­­k×¥Û{j;Ö£ÛoÌÌþàèŽT~ñ™Ï|çûL’o>Ï<Éó~}ÁJ Ò(TÒA=êQµ€‘惼dÂp™ƒ-ñÓñÕD+xô.D;ì>yÕ>Áå3ƒ\Êh+hv·ª¥ä,`8M°¨‘͈9Œ]‘¬)Š;Ö¤y_Érÿ(Ï]S‚‰þ>›³&/ØðØ}[/¬¿2…¿SäÞReß—mÿ›D¿¦(\ÑþL½Ã„‘Qމ0 §HšãF]Öiû‘ÜÝ—ùîŦöÙ¦c îä ƒ¬„X·”w‡æÝÁK-=ñS¾ëtc« "PO%eK­‘ËHU3õ}8D‡³e„"b‹ 9BÖYÇù€™÷=ñ®“µ¾IÔ%¾{ɼàïjÛßÈ$ 5I.hL+ÐØ‹íÝ5án[¤×ÒßWvò„µï„íÅ. ÷Ûúû€I~i+?VU•‚kãO3G!ˆÀ`œ‚õN/ù•É{«ôÈbÈÇOŒÎO˼·MÞ߸VAbZø çÇsuÍàº^äúÌ &Ž›eÞeƒk$ÝFB"CP±ðd~åWæ#7Џ«EŽ›ת…ûÄÊß)ö.¹ÏŠx^“$v<`k¶Qý_14ãÝ,tÝ4û?68iìq!лN£ý÷ƒæ a‡ÜqÒúﺶu;ä&=Œ¢„‰ Lh²@hŒÊ¼+-¸«öȹ/ÉúR}O£ÿ‹$û•½á±û¶^Xß(òþ)ÛñIÎ×Rý×ÒÂÉÎ •¢C Í, „rŒFqŠ%$nCÕgð'¾pÈ%.tÑs|³a‘ ‚Ó%׺¥ü9>–]pu^ä»Î{wïqH7A J˜T³|çÈ–tT‚a‹¡Z×Xýát©¼J’$ø‚D}aÙEøRݱ„FÀ\p@­£L–<‘ù¦ö)oG–\‰Á" ƒ–„0¼;¥º«:®ì ›#§ÊOôWœ:QÑû2ôíî •{J{ú­§z¬½á]a¿ÙgÖ”Òb08 )$ Ñ.©v&w÷ªÉwÝÒzÍÏ÷«…ö›Fþ–Ñs½Ð¹áüx®nïŒ+÷³ë·&þÃâf­`…EÚ-P$ÇöAÞå2ïj Þyg÷ËRîN‘÷ŠÁ½bk= Ì”Ó$ƒ RµQý_5sŸ—x®î°ß(iéÍ(!M“ÀÀ<çþ6®€8BxôäÉÓHâ{?~œ˜ %Lrïîš Y ¶±IÒMyÓÓfªÞ@:§œ³)gm©‹•ºXå&å„Ã’±á«ÓÏWÊJ²ö¨:+ä4­0$ÚpN¼fm]¨Ò^ÚÍÎWhçöè‡÷Êö¦m–}¥r!É0¡h„“TÁ~Kc¬Ó5vôàb¨a®³)ÚáœìpO\S@‘¦ØK5⊅ÆÛ]s] 3†hÀ ››voÆ’@܃Á‘TßÇ Ù•.ÝÈúP$^§9É„Ÿ™ðiÎúÓýÊ·dIJ^{´­5fœiM›xrS­ÙãÇd;ŸAQCP ±¸Frâ]§fÈŸ>àÓÔ[ÑŠÜ”SnM¸ ߦÛ ’J9R_v¼E5êO>Û¢äEC¯¬z4þÕ°WvÆ šL>ãkÂ1_ò©&©¯QËd›Q5̲I¨Bª—I.+õ÷T†ûRýŸÙ¬?)s~¯ÉþR–µá±û¶^Xgõ`²¾aò×ä% ò#͈Q)Æ0Ià$,B‹déïÕxÜÚ à1×ðC †o×¼'4ëìlXrw]°Ö+årŸá¬?PçoÈ·Üi=jÙ7ʵ™’³`‰ÅŠmÓÎö÷=áš‚‰ …P*«ì¬uÎ8ÚÊ…fÀj‰1A‘„LÖ­øðŒ'´/Ç€ “†À„bZ@lWmï*¯èî±…OXûzmý‘²Þ°µ§¯ò¥i3íßÓ×_u2lŠDJ{ã©<0Ûš l6#¢„RÀÀ8žx $phsÏ—4¬š[¾ØÁÝ2z¯™=¿68>7qÎç«Èµlt-›Ëî ·T\‡bB”B` {= k Ä.ËŠæÕ|TƯ”µ¬ù»ÙÜíÏÇ>“ (ÃB»,{Ãú·xo»?5p¿0rFƒ(ÁÐà.ôóÿûäéÇ¿Éã§OŸ<#Á›9ž>;¾“IbòŸo6×Ö³‹‘ „oÚ~Ø ž­RO[ÿßé¬[,UÏÛRf*5SâR–DqšŒI«™«K›Ü¥›¯ÖOPšÒ)CD*#7œ¯«‘ikÊ\Uf´Vë/B’1)p[LÑŒ±°8§4wo¿—‹†€=öÏvÔEÛšcÇt'ítÇ‚ÎhÀNçB/ÓHãl¨i2`o³O¶;f‚ŽÉo츼8ÜWÑÿدÓç&î3à¯ûª“àCÖÞ§V+Y·mlã c#_B’-aLGmŒîÃPð¥Ãò&Sð…/À–…/`&äèôE’¤™¡…ÉA’–4oÚ) ÐGvÓiÚð"­Mg¢ùŽfgG»û]Íìïù,† (.É ƒNáÔaÕd@9êÙ,&:ø1/F¼fÄ¡Ïyá›?„˜ô+†œšé£ä˜W?þо«EV` ¥N’JŠKG¥”\–Ýy@1TŒÔ- EÁNÚ\FçÈP’“`‚ýÈÀòÁFáŒàÆ}Âĺ©¾cOq2)%íh@7}D5ÙžTÓ˜—œ ð3~ùˆKiªKèL„ÅH‰œ}űô´†êãtk²ò‡ã=±ä¾ð·ÚÊ”Ýò­YS”~¤ªý…XÑŠóLVš“Ò$…c‹bù˜Ì_V¿â‰®úc³mÇ—‚‘ËþP`¸ìïƒY¿êƒF6†þ¦dékB⇻⮞¸§ä“ð„"ÍNPÂP9BöOϵÀÀ|[§©¤"g+õ¸0Ô€ýPìª#´q†¿ g"«¾è¦öì ¿ì³0ŽN®´4ÆiQ­ËØrzÏptWdÐ:° ô[ÂæHÌ6ð< 4öG­QÐ˰}¸× èeØöj¸¶oØÚß·;r`û<:Gh Cá4! ¨“clŸ¾ê—už[æ Päzõá5‹/õüøfÞ©õÜ©ñ½[ëzÏì»]éXØÖhÄ8Í–,Œ"qšÚB¢˜À0&Gp#§îÔU_3;ߨö|PÛ1Q¼nSBd¡ 6UöRªú¿µÓ±ftÝ5•ûAB%‰$O£ÿë_?û&=ž¬ƒäû¡ÈÓ¯Ùó䟮Ûzöçkñe“IŠâ±’–%vçÄíÿë鬸´S»²;÷BãÖø^¥»HI`t&Jሼ„U-'ªÙRÅK¥Î4!¯ËI9'þË(­êPWA2xšˆÑ<ÆãY ‡Éa·éì݇\Ó'Ü3ÎùðAPÇ…>ÿL¯{ªËs!â¾iînÌG[fºŸ§‘ýs½®¹¨gºÛ>Ô6ÝéŠ÷9¦Â†Ñ<'—’RÉdqÖRšsþgÔ˜S5²iÑŽegÝêsíIŠŒz¹Ùvn§ hN{sÇSاnú˜º§)ÔÂÍR K1‰â2Ž—wîgg: g‚ŠŸ{Q–†’Ò¨W NŠs Kæ«‹{Û 3G…õÎü9¿l2 õ}מy§½ê©jÒÇžuiƪ /¹1PN´+¦Úá7¤Ïš¦ã‰´ -Â0””Hg½XO"Kò¼„ŠGlå粪”Ýò­¹'VÅhe.–¯®F)¤$à…×jsO Ì#½¡D ²àî½âéYut^rõÂL¿ì _v†®¸ÂWÜô gϦMywhŕ̆–½p•«m½Ë‡{šó+IœÈÄQ“¦p¥µëuoìô~?¼‹i’H«?ÚxhÁÑ,æ ÃQpø¢«wãœP;áèÞ¬ž³­Ç·³jAâR)C2&X¶Z‡v÷Dë¢'NÕõ›ûêûûm1{?äyŸ <ÌÑXC¬¯>t²‹>‹²…²ÅòG|É#¶ø÷\ñ'ò’ûªÒß©K?K>—•¤|LÿŸæex(ßö {û}¡ü!WþvûgBчŠm÷U;ˆÅŸÉò¿å> ¨*~¥¬X$ ŒB F<Ë14—œæ¦ÍšÚ «žèåÖîå¶îq_—1¯(|ÐØXu$UsÉ^u8C¯ùb«îpÜճ⋂|¾ð¢/² ~pö,xCq_vÖè ¡&Šã¹„쨥9hß§¤8RÆ©%$œç5gd±µsÉMxBpàfõtA¥9OÏb ˜¹êŽ@O¸D]N9 S“BàÉ$2lI´!3 1˜£ &0Gc‡$MB8ûlò醧d³Í `BlcHHÛm{SUjoVÕj³I³›m÷ Ý@P¢ÞôjW­Ôw6UïzQÉÍèÕèóÈžy=¿ç[K[šókâ™A;€ËúiÓ˜ƒ¨2ˆ&S㤣Á™ˆüyÑ·*7úÄ1õf#}Ñ’³äNSÖf3Ÿl† ß/èï9aŸ}§Á¼â<œtg­‹× V›Œ«ãÝf>QgØpÜ>ÍŸ-@Õ°’I ¡À@˸$ÖVWuÏì0P$”˜ô­ŒvßúF`.xFr*òàOeHaÆû‰†Î½pŽ™÷jcaõ´O˜ € tóa1”Óñb͇@º™€êºo«FB-YOލÄj4w€@øX\a˜òã1_áÕ]g#e( ›ÑII%Nå^ìT/F1?3ç‡ 7Bœø)õ¬?]}Bà‹CÁMàÆ…¾Ü‰Þ¼à Þ(Ð,Í"$/%Y„`0Y…g™dñW¦ê휪ï4Å_ñ¹_ë v¶WLþsUÉ3Á¶£/ÛÑ”=g­»tÉcÝU•î{¬¿¡µ§µíjJyÛBé¶ÖþLk¡¶îqE»êâm¾hG(|Å[Ÿ©ì¿áŠÏP.;ù_­ä(ª<$o-ªœöœOô§+ÍAè¿MÆüƒÁ¨cF)5ÕÞ·Ov þ24!Š%piÑs¡¯¦µšË¦%ˆg²0¥+¯ìzGÿVxâWÞÑ»£)_Ôm±‹yE+”Ðã +Ãá‘G3¤' +€[ÝÃ÷cp9‘1½ÃéêË?šô ‹Èéºç‰Â™S}ãG[5r%Ǥˆ”ÀI¡óVvEëG~Þ2•.Œ6ŽM6L€F®8®\izoÂ5öNã@OUGžºX‰ðˆCiX›Éȃo•f*|ëŸÊ:EoÔøVx?«<<ø¸ÚóiEïcxY ðQåRéƒ1PäQÕþi¤&W2ý±Ö?_ì>ÅdggŠ“4™É†1ɲÌá 4~äÔŸkƒûÕç£c^¸u)ûi%Påh¶ ¿P ýÿËíûÄýïÿð;–¤RŒ¢0I!j¾ÕaªO5K´«õ9 '”~¥Þð#KÒ“æ)§iÝiŠ7ñ:]ÊeÙ8k¹æRõkuœœÈ h !$Ý‚nÞ‘½^o[>¦M6˜o;³fê-g”ñ:uÜ¡[mÊNœÜ/äÝre/» I·>åÒÑ;õ9+õ–8éhV¼ˆ’·tJˆ”c¹´Bü·ÉÕ”B!GX—b™Æ ˹÷ú»–¢m …;—^SpÈ¿¤I#í‰ñö«oójZ “Ÿ\Æ ˜ª,O?ãcnù?·áBºk^ÓtPKH¸þ¼¹þœéi>’3Þ­¯+“S˜”@GQÎU/?íÓÞ*§zM7û…kíòÙTFÀÇ °—©h‡õ[cëÔ.öÑ‹!aÆoº<€O€:éê`£ŸçÂì ?>ç¥D˜™¯‡ø¥ òt5Åq$B”Ã9ÄR2%õÖyŒ{ˆþ.ßåm_ó–§Bþ ¾à‰Ñú]É·¼í¹ÊöRUþJ}d?²ÃÛ÷=ÖßÐÚåìOU¥ß¨J¾S?S—ö¶Õ¶o5öoÀ!ûS¡rËoQ0zè ? ChD)Ak³ ¯´ãÁèz÷EðCºÒ<ˆnv ®t¾ ÀÀ•´T*ÕJ­œúà\ä~dr«sh³gøVx¤¡Ð®U°Œ uÈYŠT(.H‰¶’c+¾¡û¾Ñ»Ñ±Ö=JË¥2«”£(tÎ(è£ËL×À½àX²ãgÕ;´½›¾þ“þ¨xBotËÝò^ÚˆŒ¿ëj/du„,ƒ†[‡*8‰êDQkÔ9uDÓE‘×o5r¹æ½Ëµ—/7NŽ·Œ_rGš£'­gs•føÕPVžIË$˜Œ"™< z­Àñ &ð¸Â÷ Òóè¨ÿaµï“Zÿ'UHÿÏ+¼_Ø=P"Hªýú÷+å?>ÒùY•çË ÿ—å¾'ÕÁj ÛÉICEŒÒ!$+G‡H=Né>ª ¢ö«ÏOË»>w„;93hÒ•"±±ì·:þÛöº±ïÿùC‰Ñ,0* K‹¶«n>Ñ $Á úxcÎZ3”f¥N›J›F4I'쳓Múd¯Õn¸Ì©Ÿš—ÜÂZ›!Þ&Üv­† ·f½Á´ÑÌ/ËšjQ:u‡,™ÚwÊrÖ܇M eúúù_+ÑeXqª7[øÍFݚôâÐÇëØd­n£‰_mÎ~¿YY¡Á C*0g(F‰‘¸\®ÉÑÿYgmâäò`Ûò``uòš"€ Èë±x0Mi»5ØŸhì;C!™˜帄BUÇ+ØYŸ>3p‹aÍ͈H‚)Ÿ°NWÊC¬gÅúà´Ü\À´4=Ö%«/Šh>ðgC|,Ä/„Ê…`Ö\D8S³7j9‰Ð”V"®A&båé²¢ðfÍuŸy®>ÈÆ‚†)Ú42ÔÍ…@# & c~zÞ·E3ënG´§–*šU㙉¢*’ 09JeÐØ$e|¨°¾bì/ÙÒgÊ¢UñŽÆöTWúTkÛV—@€îðV'ûëohý•ïÞKméß„âWlþž²pO°¿ÐTî°åqM¾CÅà„Çqg!ÂÐ'Å‹8½¿Æ}'8’‚üíúmäʽ®¡t¥ùŠçâ/‚ã©ðX‹ÅNÉ1¸4-+7äNw¾ýapb¹ý|{E¸BŠ"Ô0C† (ŽÃ@¯àNU.†6z‡SÁÑóŽSFƒdÊ€Ü*„<¢3O‹Ü퟼绔ì9¬‡Fᢠ‡´õïºÛìºß3r?0ò±i² #™ÇUR®Rõ/êëô¹‰óŽøÐi‚YÇ®V»:V«•,Y>1 &¶%Ù’­ÓG >dÝ2—qldK²d›Ë€|_Ø–|à“LÞ´}ÑM ”r$`¦d€&¥iè4™ÉL›©ú[ò¶}§5;ßyf%ËÏó›ç÷yôAÛ@Ä:8l ["éÒHÄ>ÈhÄ2tÊ|2b4GCæpÌ4|ºi¤»Æo‘Wç#R”‹æ`H–Ã8—[#¤¦Êmë›5ž•mwë¼7Ì0 ÈLÂÄà|¦ÏL‹gRç¼]ÛySßb6ëüj½ŸV9ïÕuMmkl& %>'{K¬Âº©s?Ö82Uç}ƒ÷7ÚÖb.†çprQD&$¿~öÕw/È0;þÇõ"•zùËS?Æz‚|ì¸l!’+i,.ZÛ)O4€`†%{Ñ’]¾l–®ZÒÕÍ¥ ;½lU.Û ’6åš]–´P‹fù²µä’Y¾fÍOZ4—lê¹2±«à\‹¬A-A8.›ËÏÁíù¥³Íôº¹0Y¯™®Í”FdkM`3ÅŠE¾h tÊU³òj“tîm’î-Ëgç",† Yˆð²Å”D»Ïæ™¶-„Îôv%£sïµÏ÷€@ îÅ0Œí3} ‘ÎùþÎ4Qâ^í_8Ù¶)5jhVžˆËÉA¸>&9ÜR4Ö½X|Á¥˜Pã>¦‘Ρ/xÔÜΤK:{X~ÆYtÚ EgŠéàP’vìÜpœ”𘠜 ˆ’À^¡q;[ŒKòP–šTõÀlP°dÜ+œð*Ï{ÓVçk€)â¾ü1?= ')L”c^ò¼‹÷ɦŽõ´ªµ;„ð >GÄ&Dl‡ÇËA²5|dPÿNRõ”®ÿ±ýkqÅ_ÉŠ¿‰5ß·}+yë­y¨Øšñ¶þ3ÍwRÝRÍCªô Yú\¼íﲪ{²‹[øxy.:áãRŒ…á,^¾„ôUÙ§;{V½¡5ÇÉ+®Ðegÿª«?á ¦«›¯{BËîàRgXbwáÛ$ËaçñæM¨¦‹æœ½ñöc4c b6J!ÌÛ+d#pa¾Ëe«8xOãµö>`ÒjGßŶ£nëîµ¶¡½n(SsGÜCÙ° Ül8ÒVÿ’'˜ìŠ&}¢ÙŒÌ_§Ž(âÚÝLU” ø$/s„"â¡h6/«ÃnP7e•dÚ¯Hí_Ä—.-{.)ÿ§ ,ãmýgš/¥ í¾%+¿k7…Kdñ^1!AÁ!P å Ácc ‚l­6.¸ŽAÿ¨kø*8¤ãä5Oäòk<$á´i¤3¸ÚÙðE>r„ §›ò·JE\"\ÒXZÙQ×öà²ØE¸´­Ò<ëê…Õw•òI>z¬˜•“[,U\íŠ%tè èa–»ÂPù¯@Ô†k éèƒ%VœŒÞ÷EÀ'éª?éî_uᱬôÖ露xŒ< ŽŸ\ŠC¶U8Ûrz¨n$f:5hŠ˜ÂiÓˆuDMÑhýPÌ4Ž"ü÷7®@¯ñï—™vÇ¿¾*½J¥þõêE*e¨«çgçÁù^TªGS¾Ð¢H6K6`ƒzÙ `­˜ÓÖЗ!Mê•F$¯C/™è„™J6•_ÚSÔ­#ôT®”½ÍEøÁÃQŒÀÙ8. d åš±=É&Á’ØÈ E % {þB½*a-¼Ü¢œi¤Oè%:ÂÉ"ò !.Šrxb +Ûªnö¿Û™ˆîO†‹¡Àü€s¢§c¶×±<Ð6×ë™þ¤Œ€¸iŸéƒ¤K#‡fûÚ&OøV£­s½»C.Å ÌfÎÊÉjËŠCí…“GÈ n2î‘Mø¡5§«Ë+ã~˜Y9^p+gRSX%Ì_0êÆÝÐåU]ÊàÁ_Ê2 ç³ò²P.›áÞÆü™cÄ9gñ¹€z¦›Ž9ÀØ„›÷€jàß4P$Smšê”^ôÀl0-=î—ûÁN0%B ÞU•g¾õëç½w.juܽFç^¥üçMîûMî{:÷Ýæ\3·Z]À’[í®ûÍý7;·m›|¿jvþÜ2p³»ÕâØ«>G¥0 ‡??‰XꨕûúÕÈîñj§½—ú³‚•çÑ/¦øÊS‡Ê—»TY£vŬX³À dµí¿òe3VLZ¨,d0‚%1R,Ø'©cØãõ%YSÅŒ‘2°|Áwi‚BÞ”6Ì÷¨×:óµ®lµ]žígMÅë]åëoiV,êeSYÖZ¼nRn˜ÔYKiÆôƒŒ±lͨ\׫®ʳï–MYØ÷kx*Øbd8`ã1¨á4¿îVÇÙñ¾ÅÀÑ 'œ«AûÂè·‚!=â[ »VC}K£}™±þ%0÷è_ë[8bq]z—bötÀ½µÍ‡Ý™Dïù`ÿRø(¼,í[·-ÁüΕÀ{çFúG{/ŒÚ—ö…qpˆs)л<êΜçÇú.ø›©#gG+5òÑ‚&aC‡d × ÉËNyÊÎ °³.ɬ !ÙµDÚ é§šöä+ýeça õüPÙ)Öú‚ðe”°€D”ej¸Î¤=šÙÉ4W67gez@¶ð£Òá#ìa=Y£¥ö—›šöö0gìÜ rÖ 2)Mv9S¹a p cw çâ¹|õ¯N²³Å“äCÝX½þÙeQ(BËPt×ÜP¶%®yÁÖ>fk³UÏå5OeU¥_*+³µO¥µ_‰kÿ ‚ª—=—U?‘WÿNÙðHÞ°Å69Ž!(°ˤ½UÚõêåöÒ ‹|Õ¸“ÚyKÿo+E¶›i1Eÿd¾NŸÚ8Ï€ÿ ­cб«ÝÕ®V»º„PÂic@€Ä)ØÈ¶@èC $ßGb‡qâ|è÷N?$ž&©›4›æª/llwò©u;N™·“O¿(q5ÏhÞ•vÞ}ö•öy~ï.’Á…õêÜ “>~PiËMÖ+7Ìúsíƒäìd»•¾jIÊ”©ëê×ͺUH£2fÊ[iÍ]mS¤šÀ!’Ec~Ò¬_o“§äËõ3]â€,¾_Õ[µ»Ûþ‚A1¹PLbB”Ï£Ákõ%Çý®þH¨;èŽÙA@…=æ{‘F‰ÀáËýÖùAçrÐ:?ÔõÙcG#CÝɱ®ÅQolüð˜Óp¬E[]˜Sœ›_Q(+PêjŠj:-ãûŒß Z—üÇ㣳žÕ ÛrÀ™ uÎ ÚãA ˜ÄšðwE~厺"¾CsîÔô±‰>M¹–æñÅÅ"¾‚Õ•\î^²çÌy•3½;Ý0!½ädª›§m6˜ñªÞñÊì-|FˆíÚ-ÅVLk‚Ç™H/;ãZ€"r#oI§»°êŠïf„°ñ… D$ÆG³‹ÕŠºó½À Ñ9›ü‚3÷¢'à4ëz.@ò™J> › .˜’¤?³}ú ^õ›‰ö AÉ”rp5BÉÁË"¹¯È0~‘=)ÓüA^óXl¸/Þû­¬Èñ)úVRôµ´è+YÑײÒod¥·Ò½ü>S~›-€Þ}OV¼%/¸+-ºËÞa ^:?~ß±%·ØÐÈ–¤l[ºç‘´ì1»çSºMí_mI*À`pÂw¢Â;â’mIù6[ ±Åß~vï°÷$%éâ[âÒÇ¢ÊÇtõo™²"å«_ ä "öD$IRÛ:2‹_H+\†öY×H´{h£b£7 l°áˬF }_õ†9©®‘«®ñkÞ 0b]CëÞ((瀅âÿZ8lq+ 1Ljq’ÎFÏÛ*à«Vÿ¯] ç¨1¯˜B0 ÅÁÿÆÎO2ê¼çLS ÆÀ†LåŸžÐæ‡e$Wl>|’ö‰wÔYÕª0éÚŽpa÷”ƒH,@‘1 üxîL'Cõ¡ÓæS† À>9Óz.lO·© †›¦ÂÍã¡é–©pCødóÉLi$Ô†™A>  !Óð¡Òƒ¬žà`$F¨8˜”ËçXÔì»^íüSã‰/Ëí7}Ô;>Ú×ó—èÈÎj{>¯r¼tüÌñÇïõZÇ}öÏ«íŸÔöü¾Úþi­û¢¶Þëj ÿzòOèòOž[r_\¼-*z$«„ÃoÄEib)+¶÷¥å%å_*óï) ¿—”|O—>`öüUZù•¬ò¦´ü]F¨+ƒ•Â_A0Ž˜Šy•–‰rù4W°O©h>¼hÙpoØFSž±U÷` Ýj5Gn5ò®;Þ€i ;­.ú¾;ünßd¢kÚúû½“Ðî¡×N–>H&xÄ!Ã(Š(üìT±,÷¢}p³'pÍŠ<ÑÔ!G„B¾€æc:‚µ$ÝióÀ$€˜?ÙãO¹2D‘g9ozBÀ§L±é û^?ªÅ” ˆ^HýRЮoñ™ýaÓÄ?þ›pxªíd°.ßž6Ÿ–œm;ïÛ;zªùLØ85aš5BL†[¦CÍSc¡ ót¦42e:yÒxúTÃÙS¦s§ÛÎ…Íaw­gÁ~ Źå‘PHC¸FR5_tèãjLJǧ5®Ïj]¿©éú°¶ç‹†Þß5¸^:~æø¢Ú ëp½¦ç³:çͽ= ²?ú›(ÔLA®&SÐßÿÏ)òôéÓAÚ$íßÿÑPW/@ ô‹A¶j°J³Ü¬X7)â òdknâŸZ#ôz£f£]®×nš•Ñ:YÊ$½fÖ$[óWk]9"àã,ÊR8.±è%­™º.•j–¯¶ä¥Z€"š£*eT¯š´kMŠhf­U¼j’lî×]z]jÔ´@ JP’á,.à¦–ÔØßpÎùísÖT¸#6j‰ù»—‚]QŸmi´g9`]y‘Fl‹Ãp(Â2? ñÄ'í³6_wŽV™d!îTˆ ðüÁŸ ö‰EøkI¤ð aã U̯Õ9tÆB¶Xd] 8R¡g v.ØãAç¢ßu&Âð­eÞ÷æêézïA–& øÃÃÍZõê¿™¯óç&Î3àÿBg°u¬vµ·vµZÆ66>å36øec›p6²NK>BoÉòŒß–ñi;ù¹3™¶3Mˤ)dJÁ`âƒðc‡!ô‘ÍtÚLøM‰»óÌÎήfßG+½ûý¼šQ'3îÔþ‡ !Ÿi,¾ Õ•èDù®FâB ü¸K5çÓM7ðÞJü AºoŠÈ…IEg…iÐAO¹¹I·±,•É”J%/Ç%E'™Œ'JÇòP5 ‹P2FŽÚm5.žç§êãÆw42íúo~€F ¢Õù›šò “>äÑLû`\p´ Ç䌋Ÿ­7L¸5GåÙû%4h7`Œ(åÕRšQÆ2±‚2æ$Añ‰ÿ`ÒïsæGšÜ'PB$øW*ˆéô§ê¬Çš¬¢ùžÖüPÌy"ä|­ÊyÎäì9?~T`ŒmÁüX“ùHÌ|¤5Cmi³žŠY´)PÅ”MõÁG| Ô¦¶)d<Ô¼§=øO!mK•½ÅæÂe÷ÐF ü¸ˆþÆ(Žb$A1 ƒ‘´åd¸QÉVg Ô6¬5÷~Xßsí\û†­ã–+°êêZqv‚C®»ý»á rˆV”CÝpt9àþ»m¸ý7aÐ3-ë¶v¸ 'ëZá< ¼qó\Ä*Ð@‹õ%…ÉÉIbŸ,QoòV6[ß+OÉÑRª‰.iæXnѺ7ò"=Û;a ¨~¢×?t~Ó×»bkƒ;ï6|­18pÔžÄë`6ÉHe JAjs:-­ÁâàÛT°ô î·ôGÊG.Z/^¬î*ñ÷•ˇ*†úJzŠûz­½ý]–@´4·*¶Œôì;<Ð_6Øwd PtYêͺ¥ã±ÈÒLI¢«Qò¸1y#ïôí"ß§‘üõÝ=ìýcAÝ_òí{΃_Z#¹®¿yþTä¼]ìºg¶Ã£¸™}Z‹¯~ñü{ÈzHùW¯_ÿëå˽UÇÛ¶]¼zõê%tøêÉÚÊ*¡ÄYL…£r!Opõ˜q¥Ô¸V¦Y³šÂÕ?·F k• Ëe¦pQ²%9\±ÿÚ ýôÁJÄ11X Lvu,ÅĈϼTÅ­—Dk\aã(p˰\ ¯•ë¥ÂÕÝR±nµØtóøþ+Õq§3YÀär,Ûìb¤1Z‘qìpÍX˹ŎS Íu«NεÖ] 8Âû\{¤:À$põmqÎ\p.t‚΄»\«ý¶ñ¶ìãÅRNA+”ï¯]è<;× ²ÍµÙVý5ómÐ h$ÒI¸»öªLr.(8^¬& ¥D*P¬S¨ªrã'|šP=;å¡B.HXID#!/rG+Í#<Ø¡‚i>ã3LzµÍǼ„ÄØŠlý%W䳉Þç`­‰£¢œáð.ÇãÞ·FëÅé&í¨9 3*h˜eh^"ð†œö¨¯xuã.ÝO©)º&E<Ú1·qÂ?Ù2ŒºÅú²M¼ì¼ W¼¼ÿ,U•/Ó«I%‹âŒ‚f0š†iE Ž!ð.Õàû*zLuàSUö3&ÈñP“ñ7cê&Ÿ¹Å›·…ìmMÎS1gSk~ fÜÓ÷œ?.>í©ü€ÚÒ˜TÐö—꬇\ü¶ü=Ÿö‚M}Φ+doisîk2·ùÂûÜ;«ÒÏSb ö˜L/CcHŒÄ ^©”*#&É7%PX5ëh]r¶¯Ú;®Û:>rtßr÷ܨï‰d««jÃ'E à`cG&Q)`Ïoú×ì@Ž5ww¸®íº·8öv÷œpœ4>ŸZ[P~¹¦ 8ñ±=ð»ÿwΞw—§ò=FŽéh¦dd6)p˜ÂJ…eY§ŠâÓ¦›ý×êk;=H6]o¾Eô@n¹áò/ŸkË]²509*Cå´ÈIåH2—ôAiÓEkÿPñP¿uà'U<ÒßVØ>R92lê/îí*îöWÇ]“ÝÁ’®¾¢ÀhùðHÙp_Qp ¬¯¯¬7Z ZƒAko¯¥o·vÎôö@U Wö»2Îê)¬Ãx‚D%1RZAÆJõ$u>>ÿ÷æšÛy®Ïò÷òÝŸì=~ẓçºsÈó‡"ÇŸ‹w³í ÏÒ¥”YЦ†FHvHùHÖïÔÿç¶«‘7{pÓ¯¿yöµA§§"€¢dqƒå‰á#qâª%.\ùók¤:}¡"y¹Ì°\ž<^%֤˓œ•Š2NKè• Iâò¬Ö‘›±t\¿^µqÃGö/–'^µšÖ­ü†Eõa…þú»‰+'«“sÅ$N¡T(I†R’@ŽÄ05&WvÚêî¹6×Ü×jÇ©¥&÷²¿n¾½öJ‹}¦Õ1ߨ™kµ-u¾]#mð±³síu‹š± Õ…£Ä ‚8I`DvFVOWà‹;w_ï˜þQw>ÿûâì|jB‰`AJÁ±JƧèÃ-X(ÜU;ßæ\ê°-G‹PÐI]¸Ë¾â?=Ûâ\è>1Û–t8ƒ‘!†¨(F£Ú³¥¦±zÃl9å@ø‚FôS>.ä‰Všë¦ÔS‘͸›w MûçÏÇ:®ÊÄP#@ˆž÷3îd!#‘ã< oxŽfá­Èg,Yì„G¿ðk…½4r^‚¢:U\ Ÿ«WÍù@¦ÐÎS>¨ÈÍŽ|v÷Q)nÒ Ø€ûCÿü¨C=yJâ”×0áÖ„Üì¬G5ãÑÅ…šLSMºÉMó»ì¡ThžAà×ÄX­d4û ªPÈ*9)¡ˆØ \î#Ù ÕÏÄÜmun„"${úW\Ê3îàw\ò >eïùñ¿õX@Jÿ’O{¦Êø†Îü–1Çæ3¶E°GÖS6kS÷…öOÔæ[DbÅ™•J "aé¿™¯Ó˜6ï;à¯÷fë´€ç~?¾±MC8BCB 0ØCB’fËÁåã±ÍÑ€ïsÂB¸Ì’tj¥iï¦iÚ¦JÙÒeiºuZ¶t‡º*{1©åš÷{ju/ºF“&7Ìþ鯇Gèù_~žïça1Òn%#!¾Á b¡¨@ªr3Þ:çZ±õ$\î»Vÿ}[à-‹ÿ^«w£ÍËç¬Ã¿àð R‚ó©@OWšƒ1 kmÀÏ¢Õ3Ïy—.GúÏ;ió¤"h!"ùö Bë¬<¹èðÝmr¯s«Ž[Š«%4C J¥ ÃP¡¦XyZÌh:ªN?¨æß‚âåcó¥X’Æñ¯:°>@˜ÂFWô†õ*(H*ÀhŠ!( Þ¡”ˆ’«´Aè÷Õô ú_¤‚9:pêz¸2­ ÅŒ€ÀÍ«SÉ$Þ}ת'Òà„xK{GÌÃqC,j§M#æPÀä÷ÁÚP¤.Ššc‘Êx¨*2rr dì©Ï7)¥:°½Jˆ M`8 ¿Fª[+:ó¸Êõ°ÜþÛrÇžóà%ׯÊlï—ÙVayPa{¿Òõ“2‹–a"°J|ú‡T܃C>ÝÜü¿ÕHò ŠÀgw{4”bPþÕÃD²Æ‚Â…³šõ:ÝbM΢éëÖHÖj³¤WÜ©ÍГ¹†fŠJDKÊILümö¼Q§î3¯7k§õùwÒ7ž…úܯí’A±bÈ^m|mêì‘X½¶H%T!´ž™„”Ð Éàj[u廎±žk3aî¶§iÎ}~¾»mÞÛ>ëo¾Ö2}Køl‹`¨À±n™v¿H# … SW;ר·¨î¸ˆ£B¡£P’Tk´ãcüŽðœý»°G»Û›ŸÁŸëëëR #HJ$ävd¿m¨Û~;=:—B­·»áÀ2µÌy mžé†²/ù¹[îK«¡7†ÞT+¢å"ð àGI ¥àH$E*TP…¡J6-+ø¹²ô™¢ pòTqø‰²pÏùñ¥z–Uô‘¢è/ÒC ‘¿*JŸ©^ÿMVé#Més©þwÒ?’•L²6F}Œ å˜@„b»É? Qx® "Ãä0ЦbýÔ¹HRˆþ$µïíÏj«{Ãâ»oÞ³@×kßÎ PaÃæ‡‚ßp¡]±z—-ž´¥¹ÍݽŅ ÷%›wåj¬çts>!—â`p¯!ηû:Jf1Ÿ…!­´-=ïpáÅÖÞ†×^—Âã‡''¦ $MúúĕȲçÍÛ®(´pqž Ð L'ÕÝç,I×øášà¨;müŠÍØÝçŽVáߤÖÞ8˜LüBɹ`m`Ðt=R‹š£cô+UЫ÷GëkGÌCþo¼%ö÷Ÿ'w’ÉÏ’Ÿ|ð·a׈Çä9s#PŠâQÃW_äª_æh_C´Ac(lˆðç‡Â¦x¬"r½¦¯ÏvUq¹åR!#Á(‚¢ù õšë5-Oê.ÿôDÛžóà%×ãrû{Ç­*-¿.³=Ö·‡ €aÈ*Š ëLµ"ÛÛÛÉT’Ànmí¡7þëgww’ngk;¥‘÷~ùhÏ q1Ë <þ¼|¹&gAŸ³üµkäÕCþ|µfÍ”?ÿ†ð £’J±Å V„HOÔŽ™÷/4XlÈZ3«×MÙ‹•éêW¶Ú ^®Í^4ê–9+õyãuŠ‹¹ßR“@¡`g ‘Qš¹%К3õÖ™€u!xaÎÓ”ð·-šoûZfƒÍsakÂÛ2ß{qöÚÅywSÂÛ<ën›ñ:ç‚/ÒÈ©…nËjÈ>ÖSÖX‰BR(‚·EFˆVWèŸ~ø{þ§³½ ÙÜÙÜJî~š/noîní$w·þÉÿºžü‰õ{—dB\%BDœI %%º Cov,Ç.L\¶Í{¬3|/à%€ÎØæÜÖÙ^ëœ×9åmZ ›û:,«D œÂ•"ìùR PA5Áçiö¯Ù8—®4ß?êuu ‹Üñõ¤ .®u2“œ|ÄV8ÞÅL9ò9]a.ù¥SêdÚL¥DP„3:…:ƒÄ$"LDcGÂ6ÀxãÀ„K=ÁQñ&Iª¯ô:$U°Y.¸¬bŒãµ3ÊiFÚ1çþaWöX‡rœŸo’I‡rÌ¡oZÔ7íÙ“œjÒÆÞ²©Æ­ò.³¨:–°Ic(‰#$…³ .¥1‰° ‘ŒEx©Qâèa k"¥×Ùœ Õá=çÇÔ¡?É‹þ,/úHuômÉ5‡–dºaŠ-“À;„€Ãm"„Ý‚rRŠIåb–ŸAƒœA&¹rÕ¥’Š3­ g añlXü÷lÁ5+¤3äi`­Í»â ,;üKœo…ó¯sHð»VÿF›7¥ÈôT‚¯X<@‘»®pºÒœïÝâ[mêË[ i¸~l:F^üj~\£D(JIPBA³¡ó åŽèÚÅîûí‘YÎSSPŒÓ»+Æ*²ò笽÷¬þï[yÀt`÷!6ï.rT5¯†=”“t•ŸÔf@£ —4-@ôyÇ'Ýñê¾xÕ@ÜÜï©õ€FRõ%ÄN z«BqC¼¯:®÷=¸÷nr¾;›ðH‚ïÇÉwF~è« ƒXx$˜ûÓ¥‘Aã@¿±x6„"Æ0œé3öx"¯·6äm¼nžˆŽ˜bWLÙ’\ B3b^i’ Qq>JôdyTéÜs¼äzRÎ=(·>ª°=)±ü⸵B®c3Q¸×h’ºó/êË,¶ãŒã¯}hƒ¶EñZr¹ä’\^uË”eǺHêà)’‰â*©¬ƒ§(’rlH²xˆ"uR–uX2­ƒ²ÒJìF ´@ûP°QÇ­m¨p‘4¶Ž¤¶NQ»Mm«Å4AúF†‘ÁƒÙårvfgæûÿ¾Ä¥gà»ÉìÓçÏÁRž¾lÞø®Å¤©e0qœÃgx5×U‚­Öæ¬è ç4/œF.ÕŠgjr–ÞÈ]¬ÏòÝýͤðꋤKúoÕw…F²¤–.ióâ&¸]TåÄk%+ZABÁ]ª”&ê^›iȵV (JJS™Ma«Cf!Šà\s1•DÆèÏú=®XØ €Å[g»\ þæhgã·#¨qÎk[ìm™õÙc=ö¹€å‚¨P¿Øí˜ñÿÔÕÀ S¸ Fì¡W+?NÑlª¤pñë˯@÷ì¬'Ož„B!ŒÁBH>ÊBª0_ì=mŽë—ƒÇc>sÌ#´]è±Ä|–$ÍÑnë‚ÿ8ÜŒùë6ŸŽR©" ÊßGK;œ- ™¥“í$IÿK 1íF“ð@L&ýŒ˜?æ_Þ+—çOµŸÏ:ð¨K8áW§ÓÈ >ˆtÌÍ=z‹–#âP„Bã¡`4°x¦X2}‚rΑwÖ#s ŽUq”{¬2÷Ü;ؤ“{¡þ›3æáD=ҳάQ'>ÝÆŠ¶I§<¼Q›hæ„äŒæHÌ´#çììhr `ÓžÔÄ_¨à«r;Ž!†×¨yB:›‰Ò騮’…Á/K l›Ž°éL>Ââ" X4Îíàf̱sË>tSòˆ+ßâ–oñJ?å—m¥›ÄÑMâȆ xSxø3~Á6¯ð!;oƒ“³!,\—ÝÞ'ò?ç}Ê-|Ä‘módKdŸ²/ÐÂÂC[ÄÁ-¾lp] Û¯KŽüEtèhù‚‚Ml ž†þ×yÅ÷ðâûÈVØŽJ5žMC0*¤§H2úᜯFŽBÒŠ"»…ÅbñÓè9^qЩ4žipƒ/¯¶ö\2{÷Ê…¿«®Ú‚ñ†ŽZ{¯8‚+-§ÁÁ»(`´ó~“÷WöðKgžÊ&Ñ K+®šðp)? nÒÙ,˜e.ŒXO®:ƒ—Í>èdÞávyå)û•´× KÇ<—[ƒï[“xýì÷jü‹6oÜ\tú…à€[º–ÚWÌÝ?w÷_tøOÕ™13A§¡TJ¥¿B×ä«»´ºpD54¬Žôiƒúþ°n4 îU…úuƒºÁÞêÞ!ý@Ð4P÷õWG&ŒÓ~e°Ûä»võ÷;_|ùlç_; §;k¿¾9ØîQ÷D4#~ýH¯npÈ0Ôõú !¯>Ø« Õ|rþoõêC~­¿¯¶¯¯2|V=æ¯ê‹ôBƒP j&lÂÿ¶…×ô;Uûµ*ׇ@&UÎëò–Û*û¹ùF¥õO•Ž»åÖ;eÖ5Eë­2ërëMµë¥ãÄ÷ÔZ…ýC­ëºÜúg¹{IVw!30DK™L–²‰T2‘§O`<ò^"01r`2HG‘Œy£xY“·¨}Ñ4"YQITÒ¸žŸ0H§uw‘,¬Í޽½W4B,éó—  *bY%Jhù—4â„6¶F’0/¾•ßU‰”â8$‹11ƒ@ xyÂÓþ÷G_˜ FJ:g±!u•T¶Nz›£§- þ–¹.Ëì®Ñ/ÿ´Ì'Õ<ãµÎù-³>¨mó¨ÏvÛÇO£6“±ƒ fZ%Wþm{x#µRåkô|·¤n¦öI|)Ç%S0:¼]$lë išOÒˆcÁg›ï6ÏtÚæ}QoËlÀ1ßÓx¡Ó²8ípÏkš (ÎdÓèÊ¢ÑhûJ²#`ñ9Ú%µóÆÀ!)‰§Ü’iO!Æ{åμ¨[4êÈ=×.švƒ$õû¨aÑ9ÿXïŒC²Ð™ãmææfâTÆ« ëC¦ñ소ѶŒq7wæ„èd=Uȃ€,u0KlæM¹³'Úñq'/Úž$¨ónΈ%I ã­Ù;ÑÁ&n_/bŒØ2'\“®ŒóíøYpoê…ÓHá°3F>™D/a¨‰°êp…Œ%äÐaIAƒÎ„@’$X; KŒ1l„¦“pF:¦¿¢~Š#ŒàÒeNÁo8Å·yeŸð•e[BÅ_ àÊ}¢´É¯Ø&”ùŠø¥›"åºHqWT¾)?d—¯ äŸãòù6Wù€«ÜÀÊîcå÷Ø1K~Á-‰cÅ#Œl7Sh¸Ål”ÇJ§0÷ ›ABiéL¥2™ŒœOaK³¨¬N¢óÐ2)¬£DXù@CÛ¸åÔ¼;°ÒÛ“¾ 6ú²h¨cõ¾i{W¡iÕJX¼!+60CÜÙ¿BÛ©®êØO%çâX«hdÊÚñº¬Vp‹L&ã €¢¡ dÁÖ}Ù¸êêHXpà±6Í›ÃM˜ìwPaÕâú‚ž÷p Ë?àô o‡ú=WèWx¶áäðÛmÙަàJv—K*¬Jk±§_¬T '-^öW‡‚êþÁÚ!¸ ©Ãýšþ°*ª B;R{žì¯3NZLþÅî‹;’$±éß~žíücóŸ±Ó1¿ÚÖ „*ƒ}Êà°v°WÓœ3` Wõì„ }ƒ¦! ¥ˆfên£—»‡Ã¹!dEYœ:™ y AŒ¨ô—Gï–:¯—™oU;oWXnUY×”ö óªl€"7å¶ëÚ¶?j=kG­/'¾?\SZï¨Ük W ^@à8Ä ”BD")§HYÆ7²ÚJyþì‰$3“™Ž÷'Èó|UâKñ²úEÓˆ ^•³¤ÎXQ¡ñjâ]}æ¼&ïÝcÌ+ƽ¢‘Ü“(nÌ\Ñe/« UfBW°läÅtÃuÿ¡¾ÜŸšJÏ8þtº«@È9ï¹_BHHP]°C€¬—բܒW+B\D 䢠ufwúK§ý¥ÛÎnµV·3kw¦¿ÔÎÎv§?ì:ÝUQÓçÀŽÝéŽ3í,Ží™gÎ<9'ç=Ïû¼ïy¾Ÿ‡0ë¶qo*”A FwÓŒÂb±Ü»w/ ø<ñû[·E^ ô²l2—z¬­¶u~жà¯í>}¹³~Ö[?ë{ØæûE$,‰ùÀ2±ÆûàÜ j‹vÊPG"ÉìÈÔþÙß ûÿ¾ßÙB/v×&À«W¯qˆRÒ KÛÈ$MaNë¸ß6ß_;ã­‹uÛâ=µ—ê\èk"šïo‚xf½ĺš£Ý¥§,ÉŒ\Ò»TDB7uè­ì žô ·zÒ:çMKõw€©Æœ[¥Îâ´FËoɸàL»Ü¢ŸlAå{Sä) è0BªÚr±ó„nÔ“¶iÀ4‰7’ÕùyÊ1—öb3\‡ÌÓSÛd*‚MÛŽsšt}¿U=Ô´k´5}ºM=æ&]ì´[+ñIóŽ©6û0Ÿ§'3D„0F­È2̹TÊ™ஜ±æWM#ô´‹½äÇ¥“i/¸ÿtútW5oÚGe«ižaŒ& )\ÁbsâH¸L±EÓÆ“H €cS<…Ç“DËÎ|ˆ—`ì–ã?³öŽ5t¼¥Ö#R:Ò9Q/¨¸|-€1×{ºÖZbï ÂwÁ|aî[;ÙM}02ä†È¯ÛzÁ–ºÜ}á“Î\ĈŽ“r’¦9“…Ôí¥­Ãð#Á²Ð€12E@âC•ƒ¡Šh@Â46P>~ĆëQC0XÜ7\=Ü_ ûFŸ –ôFÁà±Àçwþžxšø*`òìëg‰ç_$~uå—þŠî‘ªÐ°q`Ø(Œ˜ÏyKzÃÕá­¢‘~s°¿t \:-ífwò8;>ƒª ó“¯ݽ}çÀþ|é«€9#R.—‰<§D¨1}÷ûÿXâü Èz¿Äñ¡Áþ‰±åîAûo‹ïš<;o4ü®ÂýÚqâûZ¡ýŽÁñQ‰ë½ý?IKÅrDÊ0… >xð`S&^Ç·ýÿ—ãYâëP4$Èšà•,iÒ«ç«Ô×*^5¨VLÙqSîB¹zÙ¤½nÉŒ³ËŸa«hD\1çÍ–ïY¨Ô,•WŒšÕ£š‰ªŒúÝÛ63U™O§Ê¡ÏMÃI¢ÈÊ}Ú‡bÜ ½©¡šÉ按o€ü-Tç´I·ê’G9Ú¤s)'ÝšX»Îwz{n‹“Њ"ŽqЏ”:CÖy¦Ñ‚²Ôªöã™SíôE‡vº]Q} Á‰rRê˜öèé¼,–ç…¼lUËQåt+(¾fÔ Š¥ô×@»›h6I&dŒ¡Èm™¼æì ÍT‹b•¾u”õ2@8D7Ñœq©xŒŽyƤôNz Ϻ¨]×ñNƉRÕ¡} Çó,í.MÂyáa¦ˆb%ƒüQ`CË(tSji¨Ð†àHÅB™â(Š¥)–¥¡œ§rÒh"!‡Áá‰pš¤8†•^‚Hd4§ y1UÓ–K*@èX–-Ðäœwœ=þ¶AEqÉ4AÈñ½‚X劽窵ç¦;Tø±b÷A€ÄTE`¾0÷­Š² ÙYqI#¯mdõ†'8Òt¶H“­Àå,‡! )! ×¹ ¶PEpÈ WL‘`ÅÐ@et°b \)H؉VEåý`ýÁó¦<º±Åý‹ñ³ñ Ù®"ã¯îÿùÜ/@!'À6‹Qâ³þ>5è/óEŒá¨q8j:7|tÔ{¨g«h$h Šœ+ ”j OŠ„´9¬6êŸ>¾ÿäÑã͆qyq)K§'p¤æ…d”Š‘8É C²‹ï\Ûÿ|À Î-£ ü~ý“9Tnš^?N|?ûC‘ý£bç½bg‡¾€ä•œYÞíp'¾…/ZÚïö¶ÿãÇ£g?ýô/*ŠÇå4¿]Žèíú‘JõÊ«E0íÒáœyËœÅª¬«Õ™sÆ •»–,[E#ÙË•ÚUsf¼,'^¥_:¡è(D¹@É*LNÉR8†F®SiƇGÿñðËõ„D/Önýñ“‡_|™©ÑB…O#Aʶk«Ý3àÐt÷¦YßËhÄ6#± ÐHílõJ .ÖcÝàýÞPñ¥Ö’`δv¬olõõÇÿÉ~ü+¶Ä†ó<áhhPÒ ‹á4–ʸ¹ù¤k"ôŸž÷ÖÎtA„4Ò!Õźâ¾Ú¹Î†9égÓlÀ6Õ›]¸“%‰¦Æ),%åŸÔ—{LTÙÇÿjÚÿ» 3sç¾ïÜ;¯;Ì0"ŠV òD¨*ó¾óR„yÁðP`˜qxƒ(¢®µlÓ&&›6»IÓ´»6v“¶i·ÿènûG×(ò˜þ.li»ýg1¶w~99÷œsçžó;çþ¾ŸŸª¾D“ôr@ q—jÄ%¨$Ȩ:!€m•:ƒ(«Ç½TÒ ´·Š¸#7é7´5{ RT®•`” ¥‹÷gzrG|Æ^; D÷hæ.’žj†¢©L„“€.J)ÎòíT%Á$„˜ÉR•‡Ø¸ JùèI_ö¨-Ì´h†#¨G8å%(Ê_?¨QX ³­¯›FŒ£â’uàÉ«MÒ Æ'Ü€LÊ ¯ ¨ìªˆgPaSn&%Wôu75n!{ë(¯Iq²€+ÊSäòŒF¡ÂhNN*d@„¥8Œf1œÀâf8›‰A/CÐiAËDV!i\*©†a%ÀcJ9¦‚‘R”ÊaHpC)&cP©‘Q’LF"Ñ Ø.¥ê`–áÔ OÑ÷zjg[oX;A…oÛ:ïØ7„ð¢+,ª¤# Ò *y³¹DZ6•t ºì!Ðл®®7E#‰“Í·”¡pNÁÉð2þÚoò2É”÷NÚ/ÁÌïÙÂ?vEïØB0á|íNð "•U(\°tÜsuG …@# Ž#¶e¾­0\÷vÍ5µÜº~è肅À" PÂz¡e«æÿ{|~ ÇÝ-B-xÝL6_(ÔçÑ™CÊ`#asÙmTs~côX(VÚ+ì-u›bÑÊX¹hx£»< @%@Xï±þžª>àŠØÙØ÷~ ‘eåYZ „×:ñ£èÑ© ]q,ÿåsh‡xõ ­¦Wÿ–žÞ UõDËûZ"¥]±šØVÑH¸¬»ß44Ro5µjޤ’Áå™è¥¶öõÕ50}«/Ä(øéã'ׯ¼%ËP㤊¤™ŒÅ€´¥ n>ÿÄÃ"ϯ ¿.v>,qÿîˆóÃëÃÃö?q¿qœøªVæ~ð¶ã½Bk­À09änðuðó÷7ebS#^ŠÅË–ÿ—KåÓŒ 𢜉óÚ¸o,ÅY‹¥¿¡§¡…q’Ó~eÂùýÀGp NS$ŠMƒ3FªWƒ(ƒÎB@Æä¨¢íd¶·Ž ŸQMžSZÌà Èsp2L¯ã9’ü&%ËñÕå$|ÊPÁ릑Wms±Ú1ߨ¿lç_ Jv›3ê3Žx³‡=@S†1Ÿ~̯{U£nvÄ®èkbÚO°¶£Úź²|ÝÁÝü.»ÏHð@g¨\.CQ„Â05F褘”Á¹íR¨Pœ£är‚5$ WRTžNÿ}îá¬Ü²]N.k*®ôUÖ‡ëí£– ÓÎÎëîð¢;rÓ¹e ݶŠz tqË\r òŽ3Ê»h \·v€ƒÁS*¢9C7lèÝxêÍÐLÌVTfÛŽí Aép‘IP)’¡ X)Öq¬qÉÝu×Y:ÝDá?rà AÑVoôÿLè»Ùt©½¶ @WAÒ„Ñ£ÌÎ8ãè|ÇojƒõÞ±o[Å’‰@bë[H_àd˜ ˆ<ÖÀ÷[›|¥ÙûE`[qJüé0þÔþº.s¨ÏÜ (2P>ÐcQ$jîé1EH†Ž õ˜za@¤¢+Tî« ”‡ºZº?}ø×ô2Pk ëë«  ~òÇ`U¨×ªŠ\©ïùøÝ¢T¬®?][`Yù<ýÑ»:Í¡ÁêX¤$­èÙ*ªé6õ¶–](Ôpprq œU=¯úôéf|Ua!þé“OlÍY¨2‘Ñ"[³29¤uªÜ‡{²ý¶Ôó¨Âÿq‘ë£Bë›Ç‰¯f»~SæîÝU‚0(#‘BUTVФøŸäãßeåü‚£’øþ/Þ“Ê¥ðµ*åò íö}ã ¯›Fôs&(u7«øÅJ~á¨î¦Y³hbË·ŠF ‹'v'jôµ{åèvL"á V)% „ˆ]RRrÿþ}qÁÖÓÏ^<[N‹*w/^ˆþxþüù¦sòv„ŠRì¼õv]©s<`™ €Ö;f‚_F#öišg‚MÓ¸uM…ü“‘Üãù@@ Œ¤%h¸=´¶ávñý+/¾ìÀ¼úÑmLíŸGk]4‘JÒé'Ož ٠ĸÁ$* ¬ÉNxµu.(òÒTÇ™Ù@ËtÐ1²Ít8f;-“-Sí-³Óãíµ¾SC­Ú¼,C(Š€|âpö™JÍeûÎñs$ª‡¨•›42áÛ*EV]ewWÒÏ]±eMøõã~nÔÁÄyÃ>:!’~Ý…z …P ¢¬KøÈ¤À§üycçÉ‚=à@,SFâ„„£øê¢ýƒ^~êk!Mù šïæSý-ˆ–ÓUÁ³µ€.” ÝN¢Ôn¼w瀩=Dž,ÌZˆ+í¤ÿµCÈu¨RnÜæÄåk7ÀCpf¹rF…½#î¼aÁ8êÒ$œlÒ¡;§Møø¤ÿ ó‚˜éŒç.MÒ­Nyàáߘ” L:Uq;téSݸGØa Þ]¯óž (J'!pݧ1„5%šÎ/øºnY;îØP.Y.Kˆœ` ‚äÝýõeþÜÄyÆñ! c »Ú]]–Y6Æ`ÜPŽÚÆ—¬Ë˜ á²-­vuØ&¬û–e— ÙØÆ—ä †LSÒÌ$-C;m a:-I3!C`HRši ÆVŸµͤu¦MìqºóèÕ«Õ³û¾Ï»û>ßÏCgHÿŒÑ7Óì¾dðÌ6{®4y.7º¦lÞ ‹;I».@má’ ¤çÃ'®4€ §E‚t%H'Ã$&7ð  øÃ¿ŒL›ÖŒFÎÛ¡Cæ’,…\"^e2›K`¸—¯?4Ùâh:>mõ_i‹ŒÙ¼9¹¸|*•%}äÉ™¶Ð€Ù¹Eœ gö•–d †Jýøñp¢Ù~‰ò1±›}“K¡AŒ@ ÌÒ½²Á¦—”YFó˜`V¯TÔÁ~—b gòy(ž)®/Ò¹Tö¨.ÒQ×ÖDAÓÃÚ€p‰_Žê¢Züôk¡úˆO°×8»öÜûè/©y&Az™{üxˆ#õä1PÉ\*NøôžÎºh´&âQ»ÞóFê €†FÁg.õÉ/>ñ©=§NE´+E#¾²PÇÞÎeûej¨¾àÊ•+ßH‰_/ÓR®¿ýŽª¢ŠýB†@Ld`ÀÞ(—©ä"mÊíoUoÖXÞ©2üºÚð‡jzÍqâ{Úí2ê­jC&å¢aæz ‘Ééó©ÅoªÆ¬pøÇÜ"ó4Rö¼¤…¢@ÄáahjÛ±Ú4’7¡’M«Ä3ªœIµrTUœÐ&Ô&´+E#y†-™J›³NŒˆTÊBPáoýc#æø1§R_Â׳ LÃlƧ°d´w D„²ùP0eˆXG;lô˜÷ÐÙãßB#¦!OÓ€£iØmõ‡ÜÖsÞ¶¸+3ŸÐ9DŽIî~ôéfÀÅ%Âø7¨ýÚ3I¿Qé)=}Ó`¾óO˜y.Ùµ_¾£8âr/[¿ÛÕ C‡vrÌspØÙ8è49çÚɦÁ“ô(Ã*@,‡‡½ôh¨ÁeÂò¥‹y«Ù|ž”=ת )èk•÷Ði‘öP +¥ÎÄ MqŠÚ¥ócVi¿ ï6æ“Ä͹=ð³U2ÐZÒÝ*Yñácy]tnoëÆî¢ÏZ`lUåáB)_¨à`خҬ3V| Eñº…jSüÌŒíßµ)D;6cp B‚Í'ø(t¤,>WŒçžxU£€²”ÝæìS&ŠˆÓ€X9§éÕ¦féz­¹qk^Ì–æ1)0I¯YÚG}”°Ÿ ˜eg͹q³"FKãfp¨õš¤qRÚkõ²Îe1“æÜkehäŒÂÏ>cˉ·Hlà÷‡;KÎÐ0\n¯-çuJqöµç^îz!ŠË ·$iϤÑ=IºÀ@ÝfÌ>ÐM83mòNÁ_¤‹‘Q@ ³{ŠvÓÎqÚ>avÌöÊ1M9àä„Én@#—LÞg$-ôŸ€ 8\4yA:Óz:µdkE# «—*ÓñÅ‹ÈÊçB~n.*j<1Ûì¾pÔD1nö` Û<Ûä‚HÙHÞó<²B¤\S,Êis‘aÒ~Î⟄™!±‹Î7(?¬\;A{ 3cdŒY“†›°xÇ ŽYÊ—l¶ÚTŽgr™ü Hh"Ù™_áipwjCQUhÄ« iuD´Œµ¿>T#†O¼u¾HC´½ÚÞÓññì§ó)H2€ ¾ý§k—ßüüÞƒ§™eqáÁÏ<ûþªh—êL°¶#𒯋 ÝûøÎâ†=xtöDÌ£±Õ!Mt¥h¤«6Ö®¶gó¤(Ÿ#àp$(qäÕÃK9z)ù-ÕeÏò!¤G¨"/ws©…Á¡!…T[>‹+D0!<Þúb>êÙPv}—áÃJúƒÍkŽßÓ>,·ôoR‹qÎb‰1¬tS £e_IÆ×ëÖtÿÿñ˜ŸŸŸ…} » ©XR2ºoãØnâ¼:oª^1Z¯H6”Œjò&«V›R–³ü„¶(Y_4¦SŽh”“õ¹ÓõYãyRSz®Îä×ÛH“ê-£7ÿTƒ–HÓ±@‹ (w õ{}ýü‹ÿuevkµÈOœ¾aG‰-æ6 {^i'‡ì†Á“Æ!»)é;<â8 r?ê3ºÈ~7™ð7 ;›Ú€”Ö2þRÉÅã7ÔïN-ü Y¿¾>£”tßår Ìô ;–½ÖlñH:Ùa’ËQ=â9z&Øã1Š6H6KÂåJx*TZöçÄlÀâ>FL N[òN›Uío5)dD¶‡–¦râ+F)Ë™ :pä¹B1ÃÆD˜ËÅ6+$§Œ Ê€IòþE¥°Û‚²÷˜ˆCÕrBÂBøë0~‚¿€ä²QõÖÂÓ-0a€Ÿìn ÂÉÛà*`dØ–£ÄÌòÜŒ¡…¸yµãZ}³ ùÆ (º#¿ä a­àÛl‰g €,:>N¹Á’´{ÊâKàÀ€Ñ•¦‹´ˆh¦% \@ãF'\>L9Ç­^¸„¹g³‚±øönÝhŠàê_Œ` ZÁçr£kÈäkóH€³îÅ2 È‚°…È:”›6~>ßWZ¾Úë0 dhrO}e°0X„ó&ûŠœQʩٲ\7ƒ„…×)kìÚö>RE:4ºàr*ï×yBj°2УïVqíu_M^ŸKýÄìîµ»ÑÚP—ºÓw°cñ³TêP©-@ °© vè£nu  ‹ti»œ{Ý×Go¤¤Þì¼l†ô¡ ÚV/;îrÈÐ…€LºpXªüQ]$PëkßëØ.Û.cKq¼¹¹\öåÿ¥þk]½ÿ~0äB*CP4ƒ-&à\Þ6DÛùò»5-ïU‘ïï"o•>8©6ß*#o—›þXi½Ynú}õÛêFµ Ú›µÔûU¦[Ƶ¢Žu–÷vïn£~WgùU yç'äÍjÓojɪcµ¸‚-FÙ|ŽŒ'ìëgPdá»èÈùxøðáÖ½( Ppμc?.œ~E:®RNëåãú‚D}ш:wªn­hdcBŸ“ÐH¦´Ùôÿ$¿îŸšÈï8€ÿNO4›ì&›l$$ àõô|8Œ’TîP¯<æaw•ÕëµsSï§v:ÕÚ«õª´;íµµv|èÔ!ýlbÛ›Îxs8£Ô¹å;;ßÙì÷Ë÷»›|߯oî”Q-Î/É?»@¢šÞMÄ´™Ó{×öÅ[ÅÃx@‰˜€õŠÑPúç?}š€7¶ü—vû·áˆxÂâð%ÂÝUtÔWó˜ÆÖ˜»6zÔ4î6O´U´Ö ;­cÛ¨·vÔ ¡&˜¸·Nòõ›¥åñ¡ŸøéIÃBòx>»BÃÿ¹rçεZp¸<.“Þi1‘±à»îª$™ž¥sÔY7ꬋº­ƒî­‘’Àø\©P˜&B¹ž{¸2{¤…Ò¹Ÿ>ܨêµAôƒCRE>`W 62T8N½èTÍíkÄ_Ï–py†‰XŽ€—ÓT¡jR6Iúm ‡ô^#;eWõÙUëz·i@²1~Âá±oÉEéoïTvS²h³dØ.°ñûI@ô €‘ 0;˜$ã83‚ Û•¶Ä7E#ÓÉ’Ê⧉œ”É„Ùq®!0cóÁÈq‹ .B=^ç8W= b™²y"ìAëš¼çjœ lh/t¸Åê¹hjë©mVcŒ(QqŽ@Êcs¹<üœw(ò€.?0{7`ž©šÖKöPouSG á Bæ±a8*È`£zõ†‘fïKÐH<É*˜&Ì*g“sŠ\ ž•o,b88JŒ¢Š`ßF¶É7ÛµõíåÉ|×vtè"톎g¦¿Îé6vwùZçùÎ Àf=\LÜüéo[u®^mWGQøH…çw¿ºx²øÅƒÙáòP¸8Èñ•¶ á’p‹îpàüH(âÑyýz¿¯ØÔ–« ˆ¯$Ô…€"aC¸CÿÅß¹'²ë>%W‰­â"1†!~ø£'ó ‰'_ka„­T`]½{÷®Ñh€ÕLë?a¡\ Ž«Òxû2Ö_Þ^ó-uMk»¶µî×ä'%öwXf·‘³…õ7 (Iê J´Ü(¦WJ#W‹èO è[;¨Ÿm¯»^HÎW4æwZ¢›ö­KCW Ps6‘qï޽䜟#IþOx}©÷8|jBS€bpÆ7ªØ~Å„.{ªD:£ ¨bù”a¥4’1¥SNê×N–ªNëÁHéq­ò=mn´(}ºTß½~´By K¬ÂP6,526ÑýÆëßýèÇ—áGÇ|¥Ë×ì< G†kÒVaJ‘µó€¤*Új9 ðpÖŒ´ZÇÜ–Q„{͘“÷ÕŽ¸Ìãn:æ­rÃ^¶ˆ@¸0ŒÞ½ó·Å…ÿþ´ž$_n;??gØ ¥—»&_»™^ÒH¶1׳4R Rb†Ýf‹…¬Cž ‰«%lvšX€#|¾ 3]~¨"»ß.k(¢3REvÒa€’q‚~Ñ©*öWJTYÒ×XRØà¢hfy°èµæœd\!믗ö’âቪ›odÑ{Ó„|áPX$æ €DBÑoT‡ÌÊ:½‹™ŽúDÃú0µ¾«>kКER,Éêoí¬´%¾)‰ÓLyê² 8qÖ”BN›©Œ†h†2iv¦Z£™¤Jê†3÷ù†¤vg¹5h¬=Yݵ:âv¦I½öíŠüžªF»f/Ž l ß‚ÍoÜU>cr½oõ]¬œ·§Í®ó&w¤¶q‘-Oã«Q*5o7 ÓÎi»ÿ…«,9 S(ÏyÒ šš©qÀIíY·çB®ò¾Cø0…íÒ­´†KCéaý±$9üÏJO±?Rv¬½$ìÑz'ñ¹Oç Âæ’íõ‘@Y¨·¸Ç_ä4Ÿ„Er‰…ÄGã—ý¥¾ˆ®x@ó€ÑßVâ–…ÞÛÐyi8²§k¹aŠ.,n‡>$í†ôì,:ªÆU®4KÙ÷ª0A ëÜWj$^©cii)u~¼ôäêÕ«Öæ£\Jˆ¾Ãã 1Ÿƒd¦±ª?/¤nÙ¯Z®Z³“¼©¡~Q`½^@E@&·Þ²HnR74äJi6»ÓvmueKÍ nhè_Ñ×5tr“x |… °Þp'¬þæç¾ŽÖ^‰#õúR/ôáýJ¹‚ÇE :…8Gá*V¿W&ïÊŒçÆK•ñ݊ɲ•ÒHÞT™2V QOÕ“†ì¸Q1³;}Ƹn¤"“ÞÈQq0Þj‚ƒ¤s° œXÍbeÉ2{»{ž:d)‘*KO–þ‹pÿ­ ›`ù‚½ Oˆ(¶å5÷{kÇÛª'Úª¢NÓ˜‹Šº,#NÓ¸»jÜiŽº-m ÓˆÃ4ä¬ ÚW‹Ø„¡þ¦o>É—žürÿØTåÑ£GBTˆ±¸‹…gtŸÛó1cly¦FFÔ„Ç:æywèhíé VÂ@ñ4V†g±V‹q¡ÊY™ÙKAÖ‹úŸªCž ëH þRUÙ×  šDš7Ø"”»%GÞi%†ࢬ‡”ôÛäI?ˆOÕƒõª>»$\B(ÂØ‘%ÃDÌv2ÅÓ›öÊNÐ9ѸMtÜ*8aÍ9(ì§`jÐV:À°|¶!ºÌ™É ¾âåÕÐ $U9K2|‘ò]"}-L}Æìf.6˜ÛLN¨ß˜¡½ñ:T±Ô9áÓ¸Õ=ióô™Wn.R ¥(Ê(d®Ï}sÀr”r¦10Z{ä’=4N:·gçÃA0žKŽ@:Ñà™¬>:J:-š²öýÔ¶ to QŽîªÆ1»çì¡vð Œä%hdæß™ž1¹ÎÕ¹> 1Ú]¾±(3‚0…qóXü°9%Ûà!„n!Ë¡[H€/ ÈœqúŒ“xúCJ&nÆŽcc㦙Ét2ÓãO6Ž Xý.ª©(™š‡t²ófg¥}o÷½Ý÷¾ßÏÎ=û³írD…¨ømb ‡{û$EQ 8!I’¨Ûð·3»ø¾¢ñó|Ãç{îïªû½ÂüY±ùA¡åQ¡õA¡ùÞ^ÃLžþaÞšiäþýìãíB¸è«b`é‹ëõ52„‡`$F¡è_ÿü—§ß`ÀñUd’Ÿâ–|ƒÿÎnÏg:O³™,Al45?#w´JvI¹a´8}ª4mªB6V±V‘ÊÇ”W*¡òhÅÆèÁœþ ah¯`›°y„ÇÆø¤™Â¤HÂ~ÌüøñãÄKó3¯.ûÏ%a)ÜþøŸ‰¦‘.‡ý7e_ýAðW;â­‹8 QŸeÄÝÐ׬jÑL¸Õƒ§LQOãnð”%âÝ£.Àð¹8|ŽÁ³]ÖÈË¢x¥-Ù*¹ÅbËÿW¬”'˜8£ÆeÔ9"­†ˆc%4Œº4ýÍP LUuÖù }.¥©Š€ÆbÈ ‘ñIÇd'g ç…-ÊÅç °@|'é1Cù+6nÏì²H5J©§h$ [Ó/˜E½K·î6ƒ.DçôdÄ?‰Š$I² ŒbÐþ“;,kU󊶡;rSû±!+à*ûØáÌÕéuV—.²‚S²›æ \<­‡†ÍZ[âç¢@t m B÷SÛJ Dïœ4¹§-^zÉ*48A/Wž)MËU êO™=³³YYC ø°Ä(.Žq¸.—ÅE(œÜ”– g¯éÝ7ëÝPTï8£¶‰R.E²IœÅbmgº+5%9Û âmË¢ZpßK/`pÍä ÝÐ{~Ð÷]¢ÈtRhà.½Sµe|AŠ)1+{GúŽCi‡$=@ AÑÌð©ü†•²R¿²ÓÇ•!G•ãö‡·!SÇ!€ÌÓqòÉóñ`töw³ðçRdyv£óz‹ÊÑVÖî/o´yžPY°­$Ô©ÁEþ²£MÙÞ^v4ÒVÖùªiS´ÁÚK:i€‘ö¹5»Õ²”t‚ÀàíöþÍ÷ñgÏžÒsåH Qý¿Ò…䩸4ÿÇ“o\-­b””°°.Jð`j$ŠæS©}¿,›Q5ÞÞ«}XdÉ3ÌìÒϘï›>Í×ÝÍÓ}Y`Y+$ ` úp§ÀxgWãÝf½t ®a†NZççççà]Áhã«Im?Ííù‹ ^Ü7ÂçQ0ù16)âqÖK²¦+rG’ •t¢T>VºVI¿T*›T¥–¦TfEoì¨L=³Nô‹46Ì^.çQLRÌ ŽªþøÓâ ß?KI¼ÈÝ«ÓÈübì{Hú‹ W“ep ˆlŒUuJÛ &ƒµCðÛ<ä¬v¨Çš‘VcÄ¥í?¥u5ûÓ~•E`(ÁÀx_~ñGXÏþ³vVÑ%K²xf¹9Ÿ=ß…1Ø|6ÂBe–ê†Wm“>â\I#šatÄ¢z4ë§ÛjÃMöÑ@¾ b:а¤l„Ëåi¹½:½Ç–uñ¨¼·4%=ÜY›¦HØúº³ª¤ËHž×Iûmé½ÖÔ^š@ è€(l6ˆ»Œë{lçLÂFÞ‰# œq¸ á—ïÂmÂA{v@ŸÙÕ( Óäà×—08L°+ GÞ Âeöƒ¹A}nØ.¹h¥zMâ‹V¨);k\kKü\4rYÛJkÄè™6º'¬žh£gÀäèÖžðVÖûª¼‡tþjC·îäøQߤÅ£™\1{¡ Pä²Ù;hn5ÈA…”à¯C ®ˆ ¸ÆF ÆKOAkò#ê“¿Õ¸'ë[n4uFê› ye“Íĸ‰æ d(>Jpù<8>ZTš®w€|®½ËF‚òÚE?ORbï·œQWoÙƒ ( Á`tŠE¶ò¶º”ÍþW 8¥]Õ0(  e¥ìïSvUP­µÐ¨ 4í?õA߇‰ï ‹ÏæA%àñ¹ØMw?øÄSæòªüû/8 ÒOåó+|ÀžvE;˜$¤ •A_‰®ìU‚寪‘`i›¯ÈwZu–VMeȦ°mmæ3@ 0aQµú]u±Ø÷KoâÛ‡Äå IœÀ>þtÒ„ÚïãsKäzð‡G¥JO(d²9°40&‡ƒ!^AÉnhïí4|µ×ú§<ëìNý<ÝgſŖÙ=kæ{ùº™ÓÃ<Ãl¾ù“|ÝÃ"ÛíG2Ù(ÂÇ9(‡BÑ¿}ýubi\±ç‹? µÿÓ-©(f£ G1 áQ¬·ùå©YÃãûäcå²qeæ„r­4"‹gL–çLWoî®ÊPoCä(“õ&Ž Å>6mÜ<=:‘xF/«.½ž$BËs5‹½òsY\XÚÁ+OäíÎ'p’Ã`Q8ž½cƒ:`3NkÚÁVë¨Ç0Òún¤Y3æjhÑ :ôQ·úô1DDS„àâ™òø|,ù„_†Ä*¶$±’c¡×ÝÒÏnÝâ£$hžEÞ…®Ï©tè¢î•4¢h6NùÁN5áãÖ ¿æb“qÜ[qX†ü;L¸(ƒÇåˆp"…ÁH´å©gôÙ}v‰ø¼NvIôÛ^wVx€7„çô’Á£’ ¦Ì~;ÿœ@"î6‰Ã4N2öõíòvž¿YÄàP DÀB9ÙR¹W›Þg—ž7¥È°EÞm%» ZÕTšˆd°àˈ`±(&!vædÙHRûm¸ifOãZ[â碑+÷‹r¡þxÓ~uÕ¯ 6 Óñ7ilBÊ¡A¼ÉÌFe9Û[öÕN5…ÆŒÎñP‚OZhrùRö[ëp&§z{aO­ý’=p¢ü7ÙüT0=|&çœÆ¨¸fõÕÓ¶ŒZÝÛ)œÅÝ{øø‚(’…PÕ&@<«K:çe½ ŒtÕâóL_»F&Ì´²®ÌêÿE~™?5•eqü˜zJ§’·¿—- ·ÒVD$! ±¥ÛT û*LCB²"²'Êĵqz–߻Ʃg”–Ö»,­êžŸ¬é)[ Kæ<"¶óS…%Å,·N½º÷%w9÷Ý{¾Ÿã2©È-†Åƒôð B–ˆïIÝ((öùJΰ:0 ò€yÕ>¨–¬¦þ@mÊ@gYgGip…·Ì×¢t Ÿ‹ýeft1º¸ôxdn)öhæ;ס怢-¨îô•t»•ƒÁ`©¿­Ø ðã€ÔA˜+Xè8ØÞ^„ŸÖJ#^µ×§ò‚0”]í(ÉRA:ÉP$† ™²'ß?aCørŒ\dCðüjÁpi¹ü­W’5è6?7cÌÇ%{åyýóÏ ²÷Ó ˆ@ ôÛ/âb|âÛVt%·êV¡éë¦Ù<ãW Û½BëlŽv£häv>L­ŸÍ3܆f®iFQoÌ܇!p XõÑVU/E£ #óË"÷?#ño777·Ü`íÏß~G“Òw³è'â•àò‡Û"šŒÉéTÑFшèšz+@QãnÎnîfú‚@#ÀÆá‹˜öÓ'ÿ+0ð³ø§yöR²c+Lgæ7Ù –<£ ‹p’ÿ8{')Š‹‰0"»9§RQ5ØR7å×¹õçZô#-uÐHm¸É4檱—4Us)„‘4NÙ,V–ÕçØçÊJÞ€I^‘Ìëù8ûÛ›7IÈ¡‚¦ñ½‡ Œ£žÚq×1XÒ*4¢wn>6î0Dܦ°½aØU{®¹rÜ~tÔ @"×&I”ŸÀñ›(¼þiƒ €D6ÔÒkŠÓˆ¨×˜,oÒÐ:iq›×F&MNøFWŽ·üÚèÒ·ٙǢCI¸J ŠØ*Ê´«,^…Ó¯înSô/Ã@;@ˆ§Äë/ ÀÓ£ð›ÕÔ¿­ÄïQùýJ¿_îëP´w(:ƒÅ¾â€·Òóýƒ¿-ÍC¶õâyìˆrOüc¨¦§KÕ(j÷(»‚å½.…;ÀÒŽøÄ£€¹U>˜(Å)oPñÃÖH#Nek燧]…nÄ’oÍD3I†3>Å ÷†XtXˆ"Ap{±4]F^Ò×ã!Ø…e!`G€®ÀXàØÜâò«Å…¹h—¿]–*òá lp£)EÞ•ÓÉgÞ/þ½Üð§âú™ýº™}ÚrëFÑÈLîÎí—Æ›…Æo÷Z¾ÈÕ‹I £pH „(~ëÆïbK/¹ëÅü|t­*òßP^z÷âÅ©S§’¹8… 1”‘§eM~,¾\šQl?ô¶èbÇXÑŽ‰âm“ª÷/¨eÀ9Eú¤R6U"»x(cJ“1Vš9¢–«3.¨ÄS…Ió‹ZkÈ=RÍ« P‹  ‘#«ªª=z‹½Äø™|CðXeOâÛ¯„B!ˆo8Žc„L¢5 ÕõãÞš;Èzݘ«æ¼Ó8á8±n2Žyw–äôBbäôôôóçÏ_­íõ»³¦ÂÒþŠ{q2a[K±žá <KF`¶÷õW:jFZ­ÃîÕhd5;:é¬jlóVÚuL:ƒ&𠌇bE¤Udu[RúÌT¿.%d˜SÎÔŠ-Â~¼L°¦ X@Ê¡.´­·Ú¦‡`^dÈ<Ѹ¥õ) Œæ"$Šòs· Ïè’GNÀ߼款zæœUÒgKë6§?EœÕ§L5À›ÔÚÒM ’—Ä%ÓvfÁ˜’.ƒ(l¤Ý&p‡¶ÐC&Á²ƒÐgÁµ”nƒ´×"é1§õ[$á`!°fÿt™6¸'tö)[[¤®åšÎùËúÀ Å^wð£ìÌí@š—È娢 "’4‘ˆðx<.\5Š2A¹,؛䚫Mí—jZ¦µÎQm³A^¾[œÉ$¢¿ª¶OjíîZëV©Œ½q‰ˆˆâ‘(D’Š1Íñ«ÏgzØu‹÷bÝ[¡«Ø’­LÊ*—îúTqx#¢wÀ.­÷>\48Á€v9ÀÆ.[=Ç•ºO/WlÞp]Ëá !²–Æ%„c›ðI9MŠF ¿"TuЬªòj¿¿´+PÔT½Ê¶ö²€;ÏyVy6¨öø”®Óå€+>`ŸÊïSýªv–Iúïÿæ~ì‡x"·¸°}öìY¤a‹°G':oM´Š¬Ò~kú€ ê,–ô­»:‹Xþeˆuüò6a‰Ô?Ù¯ó§&ó3àÃJŽ÷LÞ\ää)²Ø*,wrP±ZA!7I„ܸˆá–#œ®ºÛªÝ_¶3Ûjíì®´ÚªÓߜδÝÎ8Ž«èJúF†ÚÚŽm»~çÌ›äÍ7ßã}ŸçóÐ<6{…f< H`G-©IŸ%í¬--Ø(¨)ÁöîÄó³8ª½Â–ZI·Imá6ñJó!g‰Pw¢>³`¼Yß]ë¹6q-þ4¾úl"Ì7fǯŽüØYÓåWû½åÞ°*Ö…] g²4’"ÊH@v(Z¤˜ Š;„Fã`äƒ žAá¶Q¯­ÌdµBu=x.//C<‡g„b<„¤\@²ÒQâ0çbIýíRÛçæÛ…†û¦å÷ 7‹õ àÇ­"8äv‰à PäN¹õ7r[Aòeþ¶Âv«Ä´\aú´\ÿ„ÇEpºqãÆæ%w}Þl{¾Öâ/vg#§WWk8Û&„ ‚‘ªÍÈœÙ/YPIÉÒgA—ºP#ž¯ÏhÄSêôXUæ\uƬ.gAÇ_PŠ•Ò˜R:Q•j/`J!œN#™ôTç£x*—;22²6úÄËÊÊÊúàÿíÿOÚßSíálj„Ë`¡Û”€]’{|ÈÝxî¤~ªëÐX›a¼Ã<å6ºÝ6œ…Âhá+,*ÞXí—N^·}ób›Ö“x}¾ú«å_b(>A’BÜ2è4Ä|GÏ»ô£¯­ÛpgCôdÔ»q.xlÌ}ÈÝÄ–rp„®Þ#ékŸsç¬Â¡f€‡x°I2`Ÿ1ËÎX€ëTØêl+°d Ø2£Íi}VщZ²ø;(Ÿ½mÛ;üê÷¥C HðGì¼~Sv´El åË ²ÀX$¤'HU ¨0xnÉ{‚@ƒD[,$¨Tœý.ÂÈê·ã Yc`"‚~³`È&q$ÈqÆ $í·r¢‰>„Àe0 àøäMÛã[ ‘E‹gÚ´–…MȼCÆö<<I,¸¯¨$_vø{åázÛÔq?ð`Ñ៴¸z6W¦ç ¶£€F: Ö@вvMغiÿÈè¹hñ.Y<óK‹Æ`Höåö±¶zr)”-(ŠBaeV˜wø.Â"4:—¬Þ%cð`Fš3º ‡ÍžKfïV¯¬À¬¹ á‚ɽÐÐ ›'³Ç:ŒþèÑ¥²ì”wß‚š‹ÇD)”¤sxE‚ ˆo¿7¨]KâÁ+ƒMðUYÞ§òGT=§Õ§A§ªÚgñ;ŸÜYè¾àÓüUÁ€6¿õ)ü ‹^mol£ û•>¯ÚÓ¦é˜ôO?ùÃSªà€GñgOŸÅï~öÛΪ®îªH¯¶ÛUÖÒy’¥‘påi˜‹_ëû~~-•‚ã(ƒÃa×®[]kAróÛ$¶'OžÄ_Ävø—«W¯fåí‚ÃJa¢t:G( ÙMgµfìýi…égróçÅÆ{ÅÖûŽ›rËÍRÃÝ#hXPpÀy²4r«ÌrOnÿy©áŽÜv\¶›@kŒ¥Õj㛲a¶ÿ™¶¾)›ççŸ^ÿ ›@°˜8Êcìî? šW æ “¥éŒN«Î˜©ÊœÖdÍh3cÚ´µdRÅúPç;ÎëÒ=ÅœІ¾C TMÌÇPÐÁhkm}ôèQ"›¯&4òÒÝ߬oýæn¯\¹ÂA¹ŒbÐè(…UÔiZƼ çÇÜ 1wýX§}Ô»[]@â—‰‚FFGÆ`I“ò”ý cVãÏV ž‰ï«®m¢ `#´<Åwcô·~ÂixMŠ$42â´Nyê&]?ˆ¹ë¦K{Ìî…ËàÛ¥FçE“çc{0¦ï3t¨Òò`ã‚2%».4ù~höF–ô®ˆ²žOÇÙÎfbæòjÐÎ5£o©9P$ÚA2PœÍB<-˜nñ-®u $x\¶ø`Tp¬@2gpnõ:ÌZÝKvâïô®Ëf/ ¶¦|º¶e0C˜ #p:4ÊËáï:©8¨E„¨ì©Ã¥Èñª,цÊ ¿Ì Àéˆ>ýÓJ¢äÞßÇýÉÝñΉ¶ªŽ®*wPê,>ª õézýeþˆ¢§[ÝëÕ>°üñÞÃøJü«øŸ¡.ýúwÏÆípYDêÑEÜÊÎdi$XÙP†½Z·zG…8J¤lâG]Ýxãÿ(7ý‡íñãÇ›céFlÿêë¿øºÃi`cŠ¡))à¶“Ivï”/Yî–9~Qbü¢Èx¿Ôv¯¤ f€C–‹ð(’D|Qn¾»Çð¥¼é³}:Šq)6D`&Ž_¿~}ƒ"Ï×ÚËIá[Þ6'Ê™‘u:ãQLŠ¢’ý9ó5’¹’di$g¦jÇ´*s¦2s¾R6§ÍÈ%1uÆâ¾´éš¬Ô¹ g¼Í@l‚ýWêËý©©ôŒãÿA§»*sÍ9É DÄÛ¸ë e! à] ¹äW$ä+á"WÈQÐuÚ®Ó™þÒ®cí.[µí®?u;ÝéNoc­ÜIŸC”2»ãuÃhßyæÌÉ;'ïóœ÷9ïóý<ò ¸4§ ¢°ðÐï¾ú=œ‘éù9!Ä¥ÐâüBXÙWÒ±‘ß_ÓQÍSb)MÒ1˜WRÅ.ÖÐçhrÜÐ;~brƒLK/ܾPØp‹u Uº­»I'qo|JuŒÛÜcvwo¥{25š& D„v—Xƒ¦Kžã¦di*¡¥·Ý£Þìø/¸018€F®[]£œk€u®õ>> d6dÔZÛÇñçt'3èø÷ LA3ðj8&ÆQ&3é€WWÓ qûs¾ìeÉ Šø´~ož$¯SùZ­«)¿Ùéöæû¾øéàTòYÁ¦çB³s&‹B«úWèÙ—ÏîöÞme[/æVûü9 M¹­mS­Æí)ôý¼ûÓ{}Ÿ¹t|¶®!§±AÓ\—ÛT“å‹xsê šø\~—d‡ ЍXDÒøŸO…Vµ~/9!¢cfffõÏÿrÎì²®,_îÝ¿_”_@‰0JÊD¤Ðªà¸\LR>øtoé£LöáË£n*‹ Éã,ëãì£L \#E#O3-5¶û»ôI©#”uïÞ¯Vô:|bôCtäÝðF+ßÀËÈThñXA%d ©<ž–81IÒ%Œæ)Æ4ñ#š´áÂ…jó1ûdrTÝ…‹%EàÔ¦¤M€÷ïKÏ if9°ùYáLÍÌÏÀ)û>H‡Vqc¤ÆÊ‚+ŽàhOM=„¶ ]ÃPR”$â6«3iÎ:9£ƒ“mŒƒO˜Ä1Å&&&–¾‹÷+dþCÀ0Xp~á7¿~b*”hú)Lµ+ÅÚÅ—†AÞÔï,ë­y)íw”öUÌœî¬4ðgz.šGÜÅÁ‹úÏ‘¦Šm»¶`è\A1$‰ HŒ*6­âxz›Ø]ÛÍ@«;l@#p³Öj»µE i›IÕ]×mí+Wt°©˜Iî­Tw•ËšñÝöä6ÛÓ£ ±h³RYyBÞʪ;+v¶U¦Š~$Å1 “‹%buœºÙ 4Å´Îäx‡0øA’$ÎH†Æ°\´nž¡Nª.a:‹újgß6{¼ë4Š1ܶz@ˆïp>˜_ž©È9ªˆ!nq’ÜHÊÚõ•·8ï„‘‡Ç€†Ì5ð䤑r8ýa¶#IŠ‚,¨¢Ék”+ôYǶîƒ4Ii €‚ĸB •0AÎÉç—À3 ý`“œw ì¬ 2ióÀ"`Vw˜IÖœÊLü'6ïõ2+ÜÆ •„aRT‚£2%ɳÓójóœ,wKî倶 Ä¥q„Š€”{r¼¯Sùº¢zg¦«óHOM–³ÞXšz(4ÿüË?–¦—kèÂËâ¶´(”Ôo¿úë­ŽÛe—«rªwv­?×ëÍózr\uàNë äúÁ£/¯Á¯kŒx>rçxuþ#[ŽÉEr1ã¸È¤×‡ehu_#µGBK»ÜZ‚‹à¶Å¸„¦€ƒM»ycbÛ–m ìØ/óç&Î3ŽÿNˆ-iµ÷®V—%ë0ÛÛK¶$;ŽC‹Á²%Y²d0ø”o|`Ç'‡ï3 ¤þÆ´3)%¡C)G[Úédš63iI É[’åí³VPÒ¤%qŽ™vçÕ»’ö}ßç=¾ßσƒÎ#¸4†’håL…n˵¬ò+é%@# x¸á¹‘æ\+ùSjéål÷k ©¸!‚3 ³'ïÅÐâbd~¢f½æN÷Ý^Ÿ‡«È£m8üö/ÆÒ j$*£:‰j(­h$a¢@;žk˜~!i²@_—ŽïVˆe1´8%hVJËÀ]I¼Äëúýï cZ´\˜_^=]!8IáOácu;Ecù<™|ýùá®~t¢ ‹™Ù‘Ì]iÀÏ*L…–ààw€8!f)aQLFQÉÉÉáÏ û_­EÇü‡ºÂ—WßyW.ã S#X%ãjy+~¸’é+Ó÷û”e6† )d¨R©Ô;·0;µ¦ –³îwÓï·2ƒ^í ·±×ûtM‹$qXM<Ö ä 3 ¯ì•åïD5 …”ÜC¬Ã%2» úbûÝõ÷E¾w42卯PV?m?:[Z=í¨˜+©t‰—P(C‰h‚I+² &ÊjÀ©Ïí?èدÌÙ͹ëk÷:1$Ôjž("&+ýgíÕKë$Ž¿\™£B„©Iâ‚|会_4æ©vÖ\(oš?pôœ«~ÆY3n¯š÷4L»ëà{Àhü¼£î|Y·0çÝþ©ýG.T´@˜{“Ò´b’°”@Jú4ËÈ ¶4æÖ¶Z[Úr:;2;ÍM­Ö¶&k³?§î$m¶ö/rùK`CSF[W~OUÞÑ;Wþ (g˜ü1ØXÖtþ䛋„tn‘,ð‹pò«þû ÿÁå÷ßj{³«°½%§¡ÝÜÑlj,iÉóך5B³ÀB榵¢‘N[«·¿ÉÖæË:¤’hhœ¢”ÄŠŠŠû÷ï?*’Õ¿þ¢õ¨¤xÈñÂB¢6^›ÿðþÇ ]]šxƒ¨hH8T¢ÆƒŒº¸>€ä¦É 4òëtÇ­çÝPn¦»ÖŠFîl·ÿ"ÓÁ1$`„œÃ$è¥w.ðø‡fbm'ç{zAÜ¥_²æ¬!(K [³vÊÎÚ’G³ S¦ã–äÓyºùBí¤E7‘aœ²ÄOfçsµ3–¸ “aÒj³l³ê'3¦Ìª‘ å¤Iý†U=›“0eIÉfÎej¦sží+PænSbø%!Å!p·Ùl—.]Š äQxlæ2\ /ñÁO…þ‚ ®¾ó¤áF9!Úô(ÔWB|0$ÀÙ²ÐÇž?wá'Ï¥¤ òI8%•À.•a(‹‘„#Y„ÄÄ,*¥©Œ¡Ú[Wçvx„="»¸<¸¼ŽLs(ôX%$@{PøJ8\‚0ÃA4|ø£¿ÿm ½Cލf&1RIsùÞ¢¡*Çh}éH@Ü¡<)Š|I)­-­)÷—×=·/[Ä¢$‚Äã,ƒ¡Ìß•Ø]îÜSjðp¯—‚Gk|ª>O´"ëu} ”¢ô*z4‚ºº× ¬¢îtþ°2•³Ç‚‘á± }!–Ò,+"0AŸJTÃGŠÄ•äÐ8˺~!Õ*ä‡÷ú*»}Æþƒñ öhYiö3껡ËÍòáÃÞ”V¾ØFìHâXŠH •œÜ¾‘sÙtÝåÚ“‡¸ÿÓÈ*žZËæœgPÁ±$F=骙óú'ݵãî°ìywýœ£fÚ×°gk&ìy1‰+)6•Óûêg<õ@5@€如ZÍÄJe8%CðTMb]î gõw׬ÏØc»ènÚ –1oݬãÈ9Ÿ¨ôp†q…SM‰p”¦!cÃÞä—šÌuÇM-mY­-¶ö뻿ßÒRgn˜i557›G^Tn™>àÃg{ÏwætÏè˜<6ýÞí?F@Ü.ò‹ ü@З»×î5® r|Y±¯ËjjÎm¯2ÕdjvË {CŘ\LˆñÔ-Ûæ'f>¾{OÈ= ÊZUöåÕ©¬¦y Ñ¡‡jZUØH‰¼õ¨kf5·‡?ñÿEJø×÷ÿRôã}4Izg 'CÄ¥f¹q.­èzºûæçïv{ßM/þ•Éq#Ë{˜dgÙ]îk;]·2Êogz¯¦–~uÜ4ùn¤¹nî*»žéþMºóNºóöó®«YÎ[é>a›pd!^̱,Ã\ü/€Ç¿»–=~¸òó·!BÀi"—h;3æ^ÐŒf&ÎXu£Ùúñ<Ý´Í0c1ÎÚâÆ²´fý4ÔóÖÏäé', “6Ø~ÒÍ[çlÉã–Ä3&Ý”U>kÛ>P¨)Þ$Ò‹I0r0nZFIP‚étº‘‘‘ˆeG÷Id¿---E–#òÙ]!á4ño]üé¦)¿½q[ØÀð¼´ü•®øg••0t³ãYæ?ùðEEE”ŒÆQ‰—{’¢(9É)PŽB9)Æ)$誣å‰H¤2Š=äñݽw—_mlaa!Ú¸p˜VV¢² F¾YX\ð|ª©CY^ý3œ5¨¼17¿)9GPV‚%pJ46S±Eµ÷ ‰@Ü‹OU?¬-ì?UU6Ó¸wèpÉÉZß°ßTœÏiä¢uë@QáŠÅ¤LZ’®ÉNžö0®¤žò¤Ÿ¦Ç­ôrÃ^¶×þh>xð»ðpO„F”'\ú~_ÂÐA’øf»'ƒ~f}\J¢>íÙX%ò¢AfŠs%fýP%Ûï†Ë-ÛpTJAQ1y[5ƒ•Ú¾ M·Gq­ë«Ðµ8ÝõëÍ /~À—\ï@’u±®Âh h9A«2NJ¡(*Ù¬{¥Ð8øOöë=¨©ì ¸3v¦ÓéÚQIî½¹$7äEQpuëÖ  ! ¢[ò~bWy¢‚,‘÷[]ÿèLÿén;îè*¸kw}ìÎìhwÛé:³uUH é—Ä¡ÖÖZwÖqºã™CæÜsî9÷žû}¿³÷•Fþ{2Ú«‹ÊèhŒCR†Åá¼Æ"tŽkkGµ5@‘}í¨±î¸ñÀ&ñJ@J2‚Y˜¸qÐR7P1Ö1;ƒSÛã:RbÙ«*®È)ñ¼e>i¬ž´8A/k^½eUgöx†´Õƒ»öOêÆõv脹Lš]Ŧ â|”€D#âò Þf (òÖ¦ç–ú¦Ü†&eT—ÒíÈv=o–we7¸s|Ô:»(“E‡@Yl?­ »Qàà ÓSÓ&‹ƒ“ðÈD‘X ÉåF1Ëâ×ýN–0_O·\KÖ}’¬ÿ(Í8¥0^I5Lƒ+ Ç­4ÛÓ4r)Ãôi²ñzªéJŠ>?I3L§ë$gÚR¸<:" Xè…Î';÷ÝóÚÿu >Vï|(¹ûóÔ¹|Íf£8…ÇhdqC[Å™² •pD™Ð§‘idCyq#jé *n([6 ‡Äd‹ú”±#¹+‡ò%'3eýJù J|"íõþÂõý%bWOÊÁ(´Ée&ŠÄhœr»wïÞõ‡ÊâBZ4É“Nýôêõ¢¬B!‹æ"TÁ–­¼s¡o<÷|ÿŸO܇oáEîÝQ¥¦ÁkÂ%Ù4ŠPÎAhB˜¡PýØ¢ÿQõÞ¥VZ¢ûYjVDL"NŠ Š'DqN$VofJúԥˋ£‚©…¯2ÿ¯Ö]Cð ¡Kß–EþzçΡÖÖÕk×’Á#9p¯8Š,_Æ•pw¸¬»zêu½õa~€F † ±Øøj÷þ²S´}vm_½®»®ü„kÛ¾R\N‹.Á@Ä\>¤’È5Rqͯ%íQ‹AЬ•w•CZä·›Ä={…Çl1-ú„Žòž…;­aÄvÚ?P$0’7Ú+„m& &V–°âcP“ÇB™RZxÔjâvÛbÚŒÔÆDA¸‰‘]±EܳOÐbŠ?V)n5ƒFè.Ýmã·è'Ë宲˜µ‰†BQh„A°Y›Ïí«D+kv¿ÒÈ3ª®vÐæXE  8> ßúË”cí¹Rû9ƒ@2é1Õ˜3 ©åLš¦a:b&Q_P:šQ8Ëj«GK«ßµºÁ-§J÷›ê&ÌŽñ²š³eö—5¯I««o÷þ ‹ÈØˤ±Þ^`#|.F°0ˆ 8' 19«ù –4PÄï®I¯ƒ4ÝœsDÑ v4h*g“º 4R£®™hf,À߃À鯱Ž}íþ™`lñÏ~è®N_… ÓÄ´¢Í 6 »,p×ö³0P$¨‘v‹¤Ã 4"h5?»‚m€·ËL÷V`öbR½åà’JaOqT'9Q#¤³×sQ ”"`’Ùqd‹>æx¹ Ã&}Ç&íª±¼~¬`Ã+LŠDaH4ŽQkä|ç®Ø6«Ä£hRxl26’Íd2ãÕ›_iäY[g?krnߘ žƒ½ ÅeÝm80YZÒµ9Oí©ß¾^‹qØ(Æ€E¿,R¹òÍ~Kݸ¶ö´¾nÂP~N ïBLõ0Ùa}m°Ó\ÿ²æ€aŒ”UŸ1;ápÄêSY“rylЇ8“Éã‘{ :9fCU†­Yãq«œ¥Û­>’µ;ËÙ¤r=o–oP5¸s<.µË‘é„¶+×mßn÷~5ûÀ ®7§n~ùÙ—ðVç^àì;¿±4h@ U¹UæŽúûAMScVã‹ÖHÐZ*7\Ý• èò4¸“U¹óÍíRRL384‹â¡$Ü+ÐÂdPàX̰–QœÆ9kV¬.)ØÖq¸óâ{ïÍü=ì„°IwÈììl¸±˜;ïôz½ÿ¾Ïý¾ù9¾y¸Ä¿}}äÐa&Nb<¢1xROœLe‹ÚUð‘Âôa–i:Ãôy’ñó Ú†)¥q:µôi™R¯&ë0о’i¾²®ôšÂzzã6!^ ç<ÿãû€ ÌÎûÞçMk?¤7œ%ý’­ÅhTÉdá D¤Nˆ)¢G3dýq#jÙPž|°@2¨” ç‚C ®ÖăR†4‚þlùX>ÝŸ%Ö¬èÌ¡w$DJ¢YŒh>‰@—ÿƒý2mò¼ã¸Û²vꎊr8ö{~};I µ d„ÃNœªR!Á±ã#$!BB|ƹã$Nœ8IL.Æ¡iZÙþšz¬[§uŒneÚií6mÝþ˜Ö’Ûû½6¢¬LˆÒJ=~ì×zÞçø=ßï燢12–Ýœšzþ‡—>†ÝŽ€î<Q‘ŽFK$Øç¢‘à°J¡¤Á¾Iá"ÉHQRAb*Žþû_þ^~ÐåGÉ „Á?þøWmZ:`¨¥‘)Õº»Ötô=å"0+è™øæßæx& žøCk††×¹]ä®\DD‹DBŽAŠ–Keï]¿½2Ÿ¡ôÏÐûbdÙ¡©Ù|m¾Œ`i!"ãB€Žá8JQ„T#Ë9¼Ç:ê*ŸtÙö8± ,K²É%’h·5ä7uå··f{<™°$yP^޶áxý¥ï¿²psÔuiaÚ¨€ß©ç÷Vû»=ú}^½$óŸÜ|ÿ2(—¢IP$ŠK7¢2° ™/‹›Í.ý¶ö pÅ.ËõÝÖ+éå—³Mw£‘_eZßÎ4¿³³Päµóµíæw³kËã·‘(Ê’$nIA ã|äìÂK÷ZÅÿrYåñy)r¢p"7®]g0LNÑRBÆJÐxwÖ¦¹=‰gò¥ÓùI3ÅQVÊ&QOèUcºM“E©S/ÐSE[B/m:–!NFPñZ%FÊP–B9ŠCUq\GwË ¼$zAxú óèûïˆ(DÃì'?~ssr K3ÀË.ip #™õ­@¥ê„#D¾Î<´;#b ²ÌÀ!‹ãŒ˜AXqñ¡¯wv úÇžèûª/ôdï¬ 0#œz<0þTÿØcþ‰Çý³_é9/è™y¬d]©AˆÓ2t=D,Ì€äòÛ¿à/Ëòʿߗhä_½zÕår)4ÈàÞq8ÛN£(†Ä ®Œ“˜öY–¨£b¤Á0ÖXvºÞxÚq›EÊ‚ @#wþø 4rº±|è˜q¼Ñr­‡Ö2ã) ¼lœi©¶o+LgqT"æ-ƒ`\D »·ÄŸ<¬åFªãƒG“üÕjŸE1xäa»°¢Ï Ô5 $ªÀ‘hUôÛT~[¬¿J dâ·rKƒÕK²@Ul—yS 6Ñg‚R´ÈD%.ƒ'Š„1tÚæCQ’i/[³7qì„ÜÇΫ”/¿H“DÜzYZž÷\“ ËܺóÆŠ?¢‘ÿæÚ•Žs&û™jWFìfÇá¦ìP'¦îH¥ ¸úèÏ7à @#áå¥ðüRxaq%²Ýpâ ·¦±²r›K÷ÞûÚœ\È’xi")'@¦¾†Ë×fé…û7°‰%ÝÈŠ®}ðáý®bò6ÿ|Š"‹‹Á`"p Ñ8õ «¾dx¦3 9+L ú'‚¡ 0!èy¼gôéžñ§»‡×t?9ð=oF0>ö ‹+AcÁHT 凿ÿàVHó/[öç~öÓ·ŽØª29"ØOã$ŽÂ~¡b–¸{[ñÑÒ£ƒvÓP£aÂQ:ÞT>Ú`kªž4‡œ@&Qö Ï‘F,ÃðɲáúŠñ&ã„^}x´¡rÒaª7L;Ë&ìY潜ZŠ¢b–¤9 ‘˜<5Va-ŠóYÁâk¶ Ë{-Ð3hÕ@ Ñ*ë³ÄÔ*z+•>“r¨Š©â‚6MŸ%Åg•ÖÆû¬š.3Û[)®I®£K³6ª9 ÈÆl2€‚$µVAoóXÔ50>üM¼/§ðøŠbÏŠ„Ç‚×`, Š„‘çO’~D#÷®à×€3f{}^‰ £Ä(*ÁÿÉ~™µq_q\i“´™NÄ]«Õîj…Œ@§ë£®Û1—@HB`ðE|`,¬qÔõÄè¾vµ¸Œl0â0‡€8™üÑÌôδnS§š4q2Nÿ©SROíqgZcNõ- 43=ÃL<žiòӛ߮v÷ýÞoßï}??À&_*@å„–¬è¤çEŽÚ@Ü_·ùLjh¼É7buÃé5“gÌäõ™4:oÞ0{!ÞIÓS£‘©F 5ÖänÔØ.UHxÀ H v‚)kY³ßˆè™°!ìÑû“ÍTÐaCˆÒR Ë¡ŠÈºiDCÑA¯Á¬¤©ò0]ºð”º>þÕÀ"PÌ——o_ý¹¿ÖÔù#ºÊÀ€#Ö©Žb´A@À!ÆÐþ¤i„uZ(¯ÖÔQ!Ãè#¬•Gh-WÂ5eÐ[åw\®·±¨þðÎC꜒mÒ-rÁ& r[Ì–G®0…>h9/Å%…û ¦§§ïß¿¿VÞ“µ} Q’§kò Wnþ<ÆÀ^Nçàox²§¿/G™IËy k_ÄçoF ÿ˯—™ÿPl¾¡~$ü±°á–Ú2]·Y>Üg½^b>š¹-U˜‚að*Q‹É .`Ø0–‹æNÿÏ â^`¿ÂÜû©fçæþvû¯l">)#qLøB¾«X.N;¢&z›óºšr.ØÒ–¾$…¬ód„ì˜FU¸+M‘UH’*dÃ9EE€PO¾¦‘Ç[ÜâmòŽ×ÛÇ[ür1«'21­4>—8(˜NHk‹uý6×Ô fL5¸Þ²‡ìc­›'Þà|Óè¶y†­.xU¼Ù?fõŒ48€OâO/.˜íË'zhG¡LՊ݆ÀrNãC ÷ªö¾¦=ËT†‚ÚD¹*1xHüA Jã¥5~Z¤tŒ_Z¯Ê3eð Ÿ>@ŸS;}G»¶“Ñ„#zºç'a ‘ù³›¿¿Oê28Z?¥‹8tº†qkÜáJ:¤§‚ºð‰¼?aô “è0|BkhFË„4á°¶ÝWD×_èÐu‹$P ”ÓTu¨­ÒÞPdÚ¿½º$»d³*€D‚ˆ¡` @¡ÒA£Ñx÷îÝÄ*H¬!G$¹råJòtvvöóÅÿÛÒªÃü÷δYX^R˜íJ,Ýûç=·ÛI h:Bâ<$-Åž»±XšÑ»³òVqã£hä=µéãBÓïKÍYoïnÞû*–š"‘àB1œOffÌÏ-°"‘X\X‘¥¯pƒÉiN~‚œ9sFŠ€8˜H€ï–lï«Ê›¬Ø>Rž?X¦ÖmžÚ¯Õ(Gµ;®ÕnA3dY)r¨*$Iòx¼­[·NLL|†©+Ì9¿š!,þAþY^XœŸK,̲$œ_+ÙšŽ#p!¢|åŽï×Z¾ý³ËœžèwÚãœó¯sÚ;7Jä$ÁÍLåb„âw¿}'± ÃË+Ž’xùøHɬ[Z^I¢ÙÖ„à›d¼¥‚Ü]åœHŒsqüÑ¡ç»ûŸ¹8².ãœnˆ²$(W&I•ˆD5ºC,ç.Ïýùö'•†j9š&M§ p(ȸ/ÁÑø†¬Wò ͵Æî×@úƒ S1Çz)¢®×GÓ€ 襾ß~jÐ~rØN`„v"å넲ÎSê ˜ ŽE†c@ËJ¿8xÀÀPå¡€&@i”>à×{ýå>º‚½“ÒR´–aôië šÂ^­/XðUx=垎ýt)õ(õ÷먙ŸBE|ø×Üòèï’g¿?¨a¾4ÀÐ1¡ŠŒ ¢½ª=XìП•1Ay5ã¨pBøª}#­w–w5tH†p (˜ ¢öÓ^½oÝ~«Bv½~W}©R‹f“aD(äæª²ßýõ;ìžw‰-ìú脟*#ñ¢=/ß¼þ›Ä"\K¬I¨ÀâüB²ø/­Šÿg‚µÒ’WVÄä‹w¯}°Ð!e`$‘"xeËŽ_Ô¿[Úx«¤ù£Ë­Ë{%–é2ët‰ùýbãû:Ëã_ÊZoZ¥ýP€ Rùïr¹ÖŠØjÿ«Ù’ž<&ñòÎ;ª ¥KsB97¿­ £¿L9eȈëTÿa¿Îcâ¸î8€«QÒ4Ì^sî}ÀrǧœØ‚Í}›8®ãÚÀÞìvíØk–ÝeY°Y®vaY.sØnÔ?Ú?ZªJ=þhë$­«•©ýÑRu*|ý #Q„j·T‘ZžVoæ½ß¼ÝyßÏL”+ÆÊÒbÕ©r8©‰r‘¾ñ”«* EGGÇíÛ·Ù‘aazWFfú+ì\f¸ ?Žå0é½‡Ë Ëó¿üUn~ž)R!Î#`û§’ùy•ߤ}[‡Æ·ö\ÞÒEB“HïÌóÃßx·B¼« H>FîÛ³—|aaœÉÓ/™¥2ûküä£á!W€Sœ/¦¤/ØÎmëŒ!=Èà(Ú°F^îèOÐE|Nñy *±<ø¾«wx@œBa$Éa~½0Ý4‘LïÊ;P¼`în1G]ú˜[3â¬v0Ñ?²1Š0c ÑÛµ‘æÚóš!àÃw|@¢±×F›cnÍP4C„ÖD]p–.æ0Åì–8 ³ŸŽ¹ž4¾n¨4Rsž‰9à,[ÌS×ÖXf9AÁÁCe(Ü™¤@À£2TÉšâä.ƒ<~VÚgLº¤(-i—Œ—LÒÈæóc½F";ƒ¦½Í52M1y2W|:Ÿ°”ÁçéÑï©ûm™>}Â.¥R(’ó±Dµx÷Ù“ò.£8bS„L­ÚÝÒXþ­C)òÓÏ4òo4bqOÕ5_©³¿ÑOŸ2)y•ÀË+ß9x´å¤nÐb×;¦ŒŒ&õö)ƒc³êœ³x`vàÇex[V•o'ôvXÞÙº¦9“3Öà´–O©ÄLކ¢$AàÂT2¥&û;@‘Îê‹Ú,B˜ .aÑ^„>×(Kƒb?€¤­ÜÏ${‘—ΧY´ù½Åmí—*BðÏí•A°Š§´Õ[îuå;Ú+Ûž”ÚŠöiÿ4$ïýÇwas»õ›[î2OGéůK#ò×J –w®\‘×Wás•8m…ÉÙʬœäìƒÒ·Nî;AW{\%n¨–èÅ6XºÄÓZáÝè¼@ð«”vT;­%Öò½eo3‰Œ'€‡¹Hjbl|u‡Ï¯(–IÄx"GD‚0¾Wóù?>d´²Ò—V6’-®~]M«µ YU “’KË?ýÉ|Ρ,”Ëc¤ŒªaLâð/¤þY¶öw¹–ëùæëùõeëÿkþ$OÿóçoØ~›chÛY˜ÊÁ…B!dAFFØfÝì«Aùx¬.ûòštD()æ2%-áàøñÌ1åt•b¬jW \xP& Tº‚Š)>AææÍ›pîƒV‡b‡[¥ó§Üg¨ºü§ÏoÕÖš¥ ¤ çråœ×üWqŒâ¼•ûÒömá‘çº'h£³[úâHï$Ò?õBO éôð%2\„b‰†ŽÄØÁYJý“¶ÿêXZ •Å%¨Äf± xP¿@£ß.E#[C[zF‘ðÒ3ºQ ñ­ÝÝ;rK LŠÊIìÛ¯(ø$ ÷ W ÁñE(ª8~DßÕd‰zôÑ„@Ê:kã.mÌœ0FZ6ª‘šHxC;bflqÚuhû.è¢M†q DKMÜU3êÔ9MaWè‡ñM5F¼º¨ˆ\1Œ8Î 4'½O¿6Ònòj£vMÔQ£­#´iÀy¬I'K•I¹<5ŠCd‚×/¾ºçë ŠQ‚ÜÎI–* °•ü¨D oä¾h²n@ǑОFÂHGéBú&Pì¹0$~äÅZÁ“Èð"J˜¤Tݽ}‡ü?;Ø+e®ziùö—¥R*–H˜Ÿ²ÍéC†fþi¤w Eaö kdpjKxòùöwO.ŽbŒ#‰DJA ù7QŽî'GlJ× 7kãNã˜[aNyÒø0&Lhí€aà@Èu*t>3oÉO¸"’‡¡Ì¦”©–5ƒ˜V ØdC6UŸ%õ¢)5ܰéüX×Rz,É¡zYÈ(´©™òRBfu§1½×&´âa¼U8ŠJH † ù@V‰)q®€K¤)öy ²Þú” á™FžÞÆÌÎ+ÖÖ«F7”üˆè›Æmô”•¾j¢guŽ™Úæ«:ç5 é×·Àç›VªÕsÅæŠBlƒš¯Ú¼W òº–[ë?Ø/ó˜8®3€¶“Èjz$\»;÷ìì²^Àll\_!ÁœæXc.×qms-{€m|€aïƒ]./,k0^––ËŽsTîmÔ´UÛ´ª©©µi%·jSEVÛÃö›„ ;X"ªd©ÉèÓhæÍÌûÞ1o~¿9Wz4Ušè‘—à&Іÿ\Ƨæ™:0kQ/H`wYE¸ÂÐ)Çåý6{¾ ’B' ¹£Ôa­²´*ZUYêïm¯R¤•(ÒKd(ŠÓ‹Žì>ÒZz̤«¢ÛQÒeÌ6C…%öÕ¨ÝYÐs¾ðüÛcoç‚ï_ÿ½µ2„þ¼5ÓU)´u–t›r,]»A™ó5;ãv€À¢ÀqÎZ„Ñ ³8š|uûaÛ!«­ÔÓUÔ½†Ç¿D^xÌÍ’×aÉã†:eSØ!”9u©x $bg(=îÛ$MaR Á0Aá"R±,FŒÚ»{ÏÞ| ¸¿°¸p*ò–iÅoë/$ü/§{!ØÝ¾}Û Ó3 €2„H$Ki°£LF6¼§â7¹êÙê÷÷©ofªÞËRéS÷(€ô‰Ü•ñݹ¹¹•‰àðôUÖÞF‚¡¡ø|X‚÷¦g¯ ¸”`ä(õ¹ ¥þaš )š¢"…ÜË#oÔj]æîY ú¼#¨P5Ä QáÎýȥ⾊ €ùB¹f×l#î™°>ð™À·tLšf.ˆÀ²pT¼;µ¢­öÔ˜E=ª«¹Ô (¯7ÕëÀjBQ}ù<؈jtm*(ý†šQÝq¿îø˜±zÌXë7WûŒÕ¾vÕˆñÄiúgo|t÷ãÁŹO> ÍñÂÇÁÿôüx¬!`=6Úþý¡sj¿î\Õvüœð@Û”—Û•P2Ê¥QŽë«F[¡#Yõ¥˜ÃQ‘§ ~9e­ÌÖ' 4AÄzOᮺ§®„¬_ Ê$»ØÈí=ÚV~¹Y~ñD²K WÅ5 çRûšâꊿ$Žd0¾o&c˜„H4žb^Ìß7 uùÚFžÃD}ûTMÛtm;4JÞåË psweGÁª@wäv:ÊÆC†® /3™ Íæ\k÷—€/ŒîÒn}ŽÁZb³—ÛUÙ*yT…ÃJ'Á °%ŒKcZÊ0¸ME7Ý{ÄpPæj9g#Ž¢Îµæ…Ç-ÅVÈë<à€±…!…‘„áÕ•èN6¥³[¤8ßX±˜¤’R! Z”™˜¤Ü™™%ÄãY E 1Ø—••ýöÆ àÓ½…‹!¤–©<¼øBa+™WB!„ö¼“ܺu«¼¼œÂ–ƒa$ Š&¬ŠO{+«úÝüÆ›Í×rªwDS$в2ø­AgSËuòðâùûU¶‘àcÝŸŸŸ.Îß]\غç)+ $R A8…ÅÈ%r2 yªµùÿþ'0=8ÿy +ÕŽ«‡ß–B±¸ôÓŸ¼s¨² ¾ŸðÆJ£"cd2\^Rþ¼Ý¹¡ožß@\þuüë܈gqÏ"}3aÓˆÛÿM×ø3}ÓÈÀdpt£FË¢q0ûðúÅÉb?üÃùOV¾mü˶0ÿàå—2%b´V"olnA\“È¥ka½#È ÿ¹ 0×äZmäÙþ™u®Y¤k ñú_¨©§éMÉH%b1]Ó¦=pj®ó·Õ·Ô\jSNØ´^£ú²AíÕ©Fô` >}íH{õå–µÚˆÒËiLݨþ¸ßpÔ§;æÕ×z*¯åôHÇÕ÷~t;xçAp~iá>ô–Ph ÎŒ³î#ƒ- 3˜ØHÍàêy}mu>¤¨÷¶CÔ@#}úc£úê‘Vͨ±Þ«WÙ*uÊÍÛ’%Ba ŠÃb“R°[šžº2ÙÝ$÷4I¼'Ÿº~<›T·S¾™„w›fÁÄ"ZB°2œÙ)Ýz2¯ÉQÑc+u9ËÜÎÂŽ ûm ¼4!œ:y3éT8Š«¹Äb*3ŸQœ)ÙV’‚¦ÈhèɱŒ¢HŠÁ¤RbNéa~!W"–P”&ï¬ó`·=oUš÷õrõÖ «¥Âj,4Û÷;zJ/X Ìÿ+±åÙ:KPÿEó6fk'¡ÅÐZ–fWþèo‡o˯~þ y\‚ "JÆJÅQD½„ÁQé°æÛ»Šz`ϫښÂTl´°ÙJÁI,æ" È #ÔÑêÚ*ZSˆäX\ÂâÀz\LÒðIOaXwåÑ9†~ÝÔV±%EB Ę ¥%"Ú ëå\kë»w¹áCŽû÷ïóà'Ÿ‚ë3šmn¨ƒê>”Ú¯¦ƒ«ø^_ 9¯2ƒo =rRežn2袜U1ÓË9­æøU``µü<«µL6Á@‘HƒP$rØÐjß,̸&phiIœ/åKR1!hqÕ¶wÌïX<•.ËnÆRlgdG™ÝUb±Ë‘ì&™P$‰%Öb³MfuV;˜jSíÎ}ùdÿ5‚ñ„‡sHFAsEò y# ö ¡iŠÏÇ(6ÿ éõn½ê©ªí)u;ËŒÜ(b/qwïéqÈf™éyшó-—³ÒyXÖþýÔ­ˆÇ"œ‹ËÃà1(61$·nü¦`Ófã (LÄá•Ète' î2/ÁVn_ñ¾á³µÔâ®pÚ¡EJlîr·£È GK…¥]Þš•’™†‰pœ-àãÕÒœ§?®óÌ·~lu÷×Ó’,\˜Æ%E8pð¼¼¼Á¾þÄ|"‰‹‹šÙåÇ/ %ÒµXéÒÉØò{–Þ>ÑçìÜJgBSÆåa!‘ùëy;Éô. ‰ã©”èÚW“:['×LŠæcúÿsss"ü?6CWÆ V Z•ee<ŠKx:!Ü Lݾ}Ë»ÏÏ'â ~ö9ˆ¬ñ$Ì$qqiÁ™ûÿö¸Ü¹Ù9<œBÕ$íç`¢”ì‚ï¨[¾10¤ñbÿ4¢ŽþB‘¾ñ%™Zã›Z{jìÅžaÖ€ŸÕfùÇYÁ VOäß9`•u}£¯´ëó)‡¯ëÒ{“_ȳGÒ+Hý…sçCHú2_–—¾Úãg….°¼pcu޲¦Yþ•ÓH Ä:d L²úÏ|ëTèÛmíRÓ%ØkRžˆ¿‘VLõgŒF:šCzõ˜íЈmØx ¬MoÕ7"Å?‰€d…4´  •£†¦aƒó½¡ÿvó“ÅOç!?Qxãyø{ûî_Þ½rù?‰x ñIâÒ¯®6õUc¶†‘“ð *Ì`<•vFU{õA¸ w6›F͈±.lÚ?Á(ÂfEÀ ³6Ž0{Ì ‰†z å•$É4JIÇ·ç¥uì[uüxÂrú´é6éèáŒ>µ´O-´ýê[ê€FÒ¯ÞhO;ÕÄ’ëk÷5ÓÃZjX“׫ÝÔÛ’Õ§Éô*³[U²:›¾¦‘gÛ´ÂxFiê˜j±ži2<â…tÈ,É-pºj4ÖlºÐl†0N«Í“mV㞺 ³q!Aòšà`  €aä–ŒÍòZ{y'#wZÊÎ2[W)2k™ÍPùHCB€IÀ`ê©ô:d6W•ëØOŽ–JK²7dI0Z(¤0! ¨¢Ý…]nï/¯}øç?~ôÛ›·~qùJGsôƒÉ&$lBÀ‚\n®ºHý ²”[Aú=²n[¡Ó)·Û*ÌÏ‹F:å]†}Y^I*—R$†¥ˆEôÙñ)¤âñE¤Ä`0YLLNF ÖÂõ ¿¹ÜxÐ]íAlVá´î±­xëb‡·ÌÛYÞé,q‚ÁNѤ´Ó]âWÖÉtÕß«LO‘@·K‰)ÆþµÎ×w=è0Ç-îø ×gú®Ûz·ªª6£Ä0ð8JD¥» ¯_¿žÄ€¤Š}KÓÔR4G¯‰:ßÅyt|¬}p}>Žªë½Oï·;*$ˆ,ž@ò]&àQSQ–9_Hî?p( 2ºŒ=ëoròõX>’ñ¿sçŽ@ Àq<##Ãét~>; ÉH~t`±yHF® ¼L$f‰Ï!?èa¸<7Ÿxøþ¥+?xc'—³.ƒÂÅÙ¤D"a5œ|…ñ½ê;0c ÌŒŠ°z#+Uÿu?’¢Tšer™Òܹû3ó1D«Ë±69¥8ÎGãQ8ùYuM6ãò×Ó8ÍÒõ¬q®õEX, ©Åþ¼à›bùFÖöf œþæà8ëÔÈÚ]UbÎz‡ö‡ü©¶N{ÚQÔx4†Ÿªþ+5eQzÞûý?>ZJÅÂì¤c’ˆßúçmëÃ‡Æ —ÿp å 1øC{¨³)l« éëG ê1F25„tÏËm¯áõ¢m)B4)©%%i1Ÿ†.¬Ú±ÉVŸÛ¯Êö©_÷·n=õi²¸#eЦûÔ™ƒ-™K× VW¾ôöÕ ‘/›E4 @ѹf…ë!¢ÐO¨MZfBuüŒÆ8©±œm¶ûëNØQ,¥H¶ˆ+à³ùd %æñy¤„›^]ð60FWQçÓÔÓ*w˜J­ž¯µÒÊÈÍî —³Äî•y¬•&m±º€ÞLœ„ÆŒ )$Ž555W¯^M,+\IÕ™ûûÝ{{«ªq.€‹Ú®4ZBSBåîfÛ^‡­Øá.w¸jL)ã”yŸuGÙÊíf™ÙQ|eµÉ¬ÞÊnë[NÃÛú½Ûè‹ASIÆÃŽ9‚$„`aayWF•JåÒ=px›d‹½Æn+²uíé²”¬˜Žœ•.¦Ô 0”æ’{’f/µwÉÁUÛÑr-t¦”€“GÐøâÓ»‹ïm3ï½kÎÜý@çüÌä™1¸Ç}7ÕºúÛd Nq &‹Šæ‰$‘²®ñã»&fç¡„"À@"·¸\>¢±Ø†,$ž2ÓK’Onܸ±oß>PÏíÒÜ|Qº„ý_ö˨©ûàOѶÛuvm%^’—¼¼жjѺbµÖ¢ü©tvzò?„Z× !I ˆ !ŠÓy®»ºr¶uëõvkÏs·»µ®w›[¯þåD@·ïËÃè\]ÇÞæï¾Gò ¼|ß÷÷¾ßÏç d„öÂ_ÿFss.qý¿¼"Š?U*Ür.\ nIÈ]Áø mÃã4éÂ~xöܹ¼¼¼±f“„D@BW³d¢¸èÍÛÌOš;µúoó!ŽÃˆËG«ˆÃ?ÏÞ7[ú/nhæ&¾ {v1*`Ų‚ÝEÔuƒºI§31 ÒÜe~RÌ5§³¾9\õüJ’ýŒãqI9¨È…m}-Hà½E«o¶ù Î~¤µs!(³g¾½ |æ©Ò·%-!“3™†Â+’üùóç“1ŒñyR¶¤d}qSžÙ6¨Ùæ£Ï4@Ð’c4nmd¢%ç`ý.[•"[eêùÜœäAEn˜[¯¨LCŒãjkÄF¾U5ŽéZ¯«í¿ÚU™“”Ìç.+„ Å.äaIñ v‹eèâE¸ØQŠ®¤Ýtà²Zà Ì:Wiï¦eÆÑŠ…ØßCÚ\‘DŒ‰H1ž°nye·¡Ø¯)ó¨J|sFÿª.Ó™¯¿RcÔøù‘oû?Øóá‰ë¡ñiú’§¿™ºqìóÓgþô9ô ìÒMŠzçhsQ·z·W]Ü£-íRïõ ;U{æÎF~v¸¶Ø¯Ý*ëÖÔx ¹Õ;cWÅ¡$'CİE„T ôŒ‘Ëw¤Åµ”É<{Éîš{yâAår÷¾ØÎÂ] B²ÂYý YÿðÇ#¹Oé/QAUЇ}Ú¾*¿J«Ü·J,Ç8,LÈòÙ¡P‚“(_·±bK•>WoØbhβ™2Lª4uÃó=š (o´e6Ӹ̲€Š¬{#M$D* a·PŽÇÝ3DOÍÛãÆPì.-aÆ,`ñ“>^š˜$`ŽláÆ˜—MyFH´¾E—Þ0W6¢ÍÒ›s-iMæ4«yk“q»qoæÞ2F:Œ2 C¥rÉW_ÿyj*†ìm‰ ˜™½£G—.IŠ $±¼å–r8çló÷' å$Ûç0äØöm¨JˆYÆAy‚rÙÆ×Ò‡ÍꦡFPˆ‘ÚÆõæa­õºÎ:\§¿T§¹ª5Ö[‚¬SÆö?¼£Ù—š*ÁØq1x¬ˆ#HvnÛñåçh Qc#£TˆºkG¾s1Eˆ@Þ0$‡—°~0`ØDÝó4Öw,¦t'œ ¯H©™0Ž?}zpýÚûÇä’%`ËDD"Æ?™û&bjE:ÚôFuøgˆß˜ß˜çèEì=ˆÃG¼½wÖôoóG¹9¿Å͉žxúi¹”„~y}{>“í×Âô ä Ò´iý«pÿá<6‹/_d´Òù¸Â9ÀHÏÑYAn³Î\‹±g?m#-È¡žèKÀÓPÜš¥ŠNí®n•«QÖ”Î!ý»ê*;5ï}vÂóQ™G½ÛS§ìù'ûåÛÔyÆñCl­ºJƒÇ>wß’k®©2Z P ƒ8Î¥¤¥1Hâ\ÈR.N|;¾;qLÇqâø’2º0©Ò¤}ÙÔ¡Ñh›¦îËVuK'˜J !äæxωƒM£"(|È«G¯Î±||þÏûúyþ¿×`éú. u4ûôha~*ÌÑ>Å?Æÿ]éÕTÙS}êò> Cu@Ò§>Ô¬–žªAí©€ªl@[>¨« jÏô›NÙrî•áB†“(.ÂH!E’¼$*Mºµ¡8¹ãtZW}–»1­£Vâ¬ÚÚÝé=›ìª}Þ^ÿâÇMmP_ám© ²J¯®.dS «F#¾&øq·Bì ïEÈôLÈ /-16¦çdã8_(Bϧú[r"*Ù—³ý\izw#ÝS—ìix­³!óRmÚó÷ú?ÖhäYâÓzãeeóPµv¨Á`9V£ÈÙB2|>_LÐ$”*A PZB¥Þ‘wö`}[!k?liÉo1€éµqXrÈd?d|’{Ú60Ps¡ÅxÄ|<÷x† ƒÐ$‰“""5=ùË/ÿ χçæ9YˆÌ/ü—CbcÉË–ø¢cæÑ´ÕlI·€¿§Ð’]²Íù*ðh 38õ*Ñ€1Ï)´”´4).þ,ë (¬š@ ”b(¿tMMMF¢$µ°ÄK±±dÁ {62úõ(ÃÐÐxŠ@r¾àœuå:ꀎ¸‹b›©À¬Ïg­GlÆbã‡o¾/&Se‰„„!$ü„ßÕ^˜1^z 6N4Y£ñ@á ǽ&37³ÖZËC•iRc¹«³~«·N°-U–¶ó޾=øQÙ[¤P*"ù"2‰D) ¸„Ü–ýZO·‡£àƹù'ybl×bóáÅ•š™›ƒg¹ÛåL²6žb,/éééH”O碠¸Àý ÿ5úÝjCù.@IŒ¡…R“Œfòwxµî<ÒåBÜ#q=Ã?èö!ín¤cà‡ž‘õ®!¤ÓÇqHçeŽIÜ`߃qîgå—+vÿ÷K}ÃHkñ†^ÎûH&ÞJ£()–Êd²[·nŲˆ1ÉbuÏùܽ ƒ@Šc¼’ãHG$×`œër@@ÅŠõ´Cvþ <îô!ž«›Ïêh’¿`Hrû;oÔxõÊh¤Ú§©hVËý+üje_³²· £: >Ù{¾ÂßQåר‡»þ9vêg€$žŠ]ý^%«0˜å66ϲZ4b•·šä`úºæb•|ûaèêRŠCŠ¢ÜA/ φ£²¡†¹ÓN8²Ì‚cé„q¥ìçe„@˜H|˜ûPÄJõØ­QÀƒdMEfK‰åÜþsY¨§1!LEê}î³mc*ã´¶ÀbBkŸÐ·Þר¢(2mpN¨m€(5-“MÖImˤ©í¶ÖtOmÕ8^´ÿ­É¤—çËø›$$*ÃAb’˜fÀàöï{÷Æç¿_ò¾§±uˆn(‡1‹ŽÉÁçã-ž[c’§1À‹}²t /ÉÜÌl¯§';3‹Àp¨b(4™• ¨Í)™›O•¿ììDºBH×õ®ÄéE<ÈçSÌÚ=F¿Þ5çFKÀµ»‡×€ÊFWè¥Î»ÿzpŽkç*÷®.ÿæ´™(Á£PÇsrrÆÇÇ—g±H©ós‘ùŠÒ“$äਘ&TÖ"ž‘xPÛ1ﺼ¾+´®sãŠîâê_©ž¸ö_Ä»6´"ž+Ü@8ÁW ËHŒ·xæBÉ ¦Ätº<¨H¨ èÊ!V‹F|lå ©¬ßpÒ§…Ûê~ƒ2¨?ДªÊû4öÿ8Gö\|5öp€Ê)¯ªz@_á,Ñõܸv'2qóï·VMO`qöªk‚,`¤ ï=9Ð dRçg+Ú.ìÊ{‡Â0’$y -e)'œÙ¹-õãR{Eþ3”§öy{ý‹k4ò,q­FfOáT2@NS”P*áI¢$Å{Sa-Ò: lfy‹Qî0+.™òÛ½Þl/6Û Œæ|£%ßÈñ$÷4ç9 …ÖOäç*Ê&Rš&p^F¦ô¯ÿa¿Üc›º¯8þ#iÍ:µ’øm_¿ó¦dZÐRn-y‘„°®H@ÈÛyò$$ñûýÈËöÄvb;޶h£ÿŒn•Vu©ªÚQiÚ´¡µÕþkIJbãGìkSŠ&)ŒŸŽ®ÎýùúÞsν¿ß÷s>ùŒX†Éµšt/%vÔ(±A=)b“ú·R@’šI üeDcq§b9<&ó¶OQ¯R×èTIpÚ;fÐ×ToªÞ|åD %ŸKeAKEeÛšÛâÑdè±Tk¬Ý "‘ÈÕ€‘ò#‰08øð÷Àx,]Èäî¥î‘”n8žJ¶J¯¬T(kUªzÕPÅP}a½€– ØÎÁ^åþýªfY°¡½; ! D¢[–4’B‘o®(—¥¦%‰qiP’ކ¥¦å~ÕÒ fUnZ’éïHuËbuX¬»'ùô²¢aÿO `@øBàÈfa,óÜÙ†¯¾øòÑÒù0’¥œp8œˆÆSÝL ñNãñGÞéÿw|lÉ>”H ƒ¢…ñPb-KDï‚ ð»ªŽ'çä=cLŒE)Îfø»3OœJÓŽ¦ÏÒ&ÐȲyÖSít³9|h|!Ë tŸA¸ Mº‘Õ’î'è{Ë„?cœÀ„{¶ŒMgÛá‚™ts`ËÄâ6‹Ù]~4éɘò!“Ù 6dïÚ»{çv e:•$— &‚bI‚À›…Àÿzé.-‹Ec’øe?œ° üR²Asq™ýd’¬æ!þL‹™iø|Úè<šòm¿*'3ó‹¨;„t64T*™–µ*/uØe€ gÜr‘kXäêtˆ»œ’·Jä’5Ì µx›EçæÅvé/?úÍZr-kž?ýªÝ9Ôã>çh\±H֥Ľh3ñÙí¿öÌ(ÎÍIÏz% ®!à©Ù)Ù¬xZmW:ç$ΡV·¼Ã©8ÚRK/dÐYd:‡Cc0¹,6zS*•wäå²á†’Éó¥¶>îx§ï-˜¹(À» ­»ñžÇÚ‹&{A‹ -ÝÅÖž¼w—•°RËgƒ§4òd 'œvIÊàl!i‹]Òw»%ÑÀBÇ€ÿ¢Ì&êª9[ÆyQÀà@E¶S¹9\ƒCa òø§‹OþlP]«–W)T5jÀe¥B[£Û¨zê+t²’7öÉǸ´’ã–}þùŸ7k»­®”SóÈ<ÁQí5­Ò*Ùx¹U]­IÙcÆ©*×èª ºZ=$ BÉ ÜAZ+?uð­Š´˜F#aóèÑÃÁ`ð>%ÇêXoÄã¸*–ˆ:tˆœKæÒ9Bÿå'áqÆãFíëz}<]«¨‘ÃQW¹nGŽitÇ5ª:µ¼R4rúÈ[B:Æfr)tJ)5÷º¨ó®T¿2 ^V wÅú يİ#5€³¢¹}UõÉéöƒÂ]T š&‹Îásh$ÒK%¥&½æö·ÿ‰%Ö I$ƒ ‰<ƒÉèÃõy'OǣǃBAá¾ÿºB„6Ac)z%âkÜýíÖ­öæVL¥ìÌçs(lÖó¹!I°ãõºçÏ÷e™ñ Ë,2Í¢ šô>c]—F¶N8‘Ý‹ðÖYdqn³øÕ¦ÜhÜ…F\hÂ9áÝ:âØW:g‘ým„ûyöÙ±9ä Ë<29¶ŒûÐØì3öyâ×É@Öètö©3$.Ÿž·£˜Ç§©ïݸ E’ðˆEdë°Øsä“Aã쬨Cf3àĆiÄ:GîM³x3ÌÞL³{ëø\昙]™¶ÅôÉEäòfË Ïï}õ¾@KÂ( z.™Ïå°x̺ùÇëÿvì=×y§ªÇ¥èpÊšgÄmsòÍŠ§Û%n™hq‰â¦iÉÅ9m‹öÒërit!›Ñéàð™ì<*%[ˆ±_;ÀÕ4ïÃ/ï³öåÛ„æÎÂéÞ[wÞEpÞ[j»ÄR`íâÝ{oþô…'ÍOiäÉØ»rÈÝ'’x: &¯u+Ý"™_$»Ö!¿Þ)_ KêÎþt×Ëœ\›Á¢’I“ÆÁŒ< /‡s¤èpOU¤\¢«×iOè€FÔÕ*0 ‘¢è»èp[YˆQè&F'SýX,²Yûv0¸2p¥ŸEc`L‡Æ|­ìÀƒ±|ôñ9ä~œÕ8*+UŠj¥¦Ž˜QT(5•ºájÉ…Š‹¥y¥ùtBÙ³§leePäam}4Š$¾£‘h<êóù8,›Šñ)ìýÅûÔ'TÊr¥©jÌPi„"k굪*¥¾J¿^œ£Ç Šc2ÃÏ ð^4µú¾c—^á탾%p„D’¼QykX³*у} 6¼aY•—ź™häÎ’(—¥“ªŠºóIô6RÀæ1iL:†Ü¿ÿý_ß PöÕp6O¨L˜8O„B¡TãñÇÿàÜ}–‹F#Á{÷%l5ÇÕ¯ƒê1ŒÉ'q06›Á§‘y–ÇßùÒáíW.£±™4@à›PaH·Î#‹c=5Ï\1Ï!Û²Í#«k«ÅóÜÄ"丆Ì~d›CÓŽL£ù…>cVŸ©,™ÆÙÌQ/rø3§È4…Ìäô?g‚ÿú3Æ=Ä)<ÝìCv_–~äÙª“»(ä<6+—Å++ÚýéÍc‰`4L.ŒÄ¡ƒrYÙÅ?G)¾š69 P´QI·.@‚[p7Â]w Ü™d*¸•'}Ìq¦Œ±«NbÜü\å•8<è’€®™\¥kÕ_îq¨NÛ¯tø”çƒ3ÃínEÓô0H¶È%Û,õos‹ÅSV ±jbÿ¸ýåy»&›¼Ò&‡¸wJþþÍ×`9Ec© Bñ0(üç¯Fߙه§¯¶y6-ž.·´ÑÖßìn÷*HZgnu“Mü_öë=¦­ë øBóh²vƒøqß÷úÚØ<ŒEÞiÚP%¶¼0Ð*kyó~¦M_Œ¡?°yc6°¦ë¦J]¥­k•jÚ´-j—lÚ©¶tÓ”„4`0ì³éªªšˆª}ºº¶|Ï=ç\ŸïûÝB}™&5… %I,«“‰ëÉ$FÎA®eYnÿθºª¾sÊîŠø¶" €¢v•i¥Éö’dgi¢»LÑYÆu.» žhdyâJ¾ára¸Ô4\iö—› õ#ùzXŠ«…–‘Âúþ"Cmö©=É›0FN°4NÑ2)ÏÑp®ˆ‘¥ò;ówçùA8Ô'‡,–ÌPq·f5-V#uY¦—»åƒ(âô‰ÓZ³ÓK—¶ƒ7ÿ|C“¨f(d¥!“ª2«@¡& ˆ9]€“y–ÌÏ·H[¸ ߘL'1RÀ£Ñ¨¯_¿>÷-zü_„^hç‚À°±±±ø¸x9˳ZIð•{˦æŒfË+,²9K0¥çiô?ÃrB°d˜-™Býáz­ú LÄ4ñZœ­Ùtãus°Îù°ÆòÀ`½«³Œ*©ˆq]#P,¹¯³ÌƒäŽN˜Ü«4–¥î’S‚!Y†£p.£Y~ìå×~ÿ»?†Šätpn&8÷p Lšó×ÀöíOÚB þN_×È—×…êSø¯4:öû†“““I©”¦Ão¯@DŒ§ùÍ’Üü•v{„ÓºÞAŽ+ÈæCn?”éÕ­Q¶~Ô1°P5Ê9„àîAÔÝû”ÓiFŽËÈùÞŠKþg+.Šwîb¤´J„'ФŒ‘Š·ï{ºüÂjkrôFuúáªU—à^ÃÈ}9Ú=„.uE8½útûQ§µÑ.‘ÇIh9OÄñRj¯öGŸÿ}f˜{{ðmP.ä “ñ/D\r„ǹ8Š@Ààíèvz"\žðD@b£äò¬t¹%iGH©Œ"p^JR$ëê쀷ÅÆSŒŒÄqKÚ¹¡¼¥¶pМÓyñ¬¯þ¤×pÚcw](í7/Uõ?ã©9×[ÿëO?†É榇?x§ÌSÜ[è®ë~×7 LÎÍì§?Ÿº7¯]©L‚Á;Á1¯%¯GwÖ«[ªñ€Còú²Ñ”HÅñ¤„ÆI —¼öÀ‘(kSt—7ÊæAž‘È7}¨mµû¢í}Oµö §µù¢ÚF¬æ.°Ç jóBD:᣹Qçðš—(#‡£Õ2N“@”¦A$ÄÄàL\ì+ÇÕº~l÷Fô\EN8ñ¡.¤£om ²c$ÜíÈŠ¶+ëtoˆ±¤­1 Íq ›ú|êû~pãOذ™ÂE +ÿ>±º ä{öAäð£®áEk¤c9ûW¶ö?Ý2°ÊærŒDØGQËO×8HŽU{ö)™Æ¡1 ;W^Û8übôª\ ¾‚œˆH¶jŽ·¼^æòúL¹½:É©žÚüÞÚâ^ýRUÿÜÞª‚Ãù.ó¯nþö_s ‹Ó½ú~}W0_vÿ{òþ, e6x'0ÞôV'ø¤°½aôÃ÷C/A!¦Ì|úð³ânC~oÍ’éÈ«?ÕS3?Ç¢žÚ’^c¡ÇxªK—7¨Ïíª:ã­;ÓS·§ìUn»£ppHFÉ$XÍ(¡æRTÒ_ب?)sËÝ%Jw©Ê]ßV’ÔVšâ®Hi+×8–ÝO4²<á/Vhúyžñ­¼E:ó/6俸i‹ ‚‰”ÅÒAÇIiv#¡9¼5ó‚ö¼p¨¡AÛdÕ6[2šLéTç† !L‘†z­YÐ ÖLëch$ûÅl®¤IŠæÈââbØP¦`§—*oOM=‚>ùî{,MÑ +)õœl[õ‘šÅŽ34ý¬p¹×ÍY‚ùhýÙÝgvàÛy’QpŒº‡Q§¹úŸ15®ÉÈ"9U¢˜àÅD%OÛàî½Û“3Ó¡eõõÿ‡ýziã¾~@I–²¦KxÙ¾;ßÙ篒5IC›æ¹¬…„WB“¶YÒðÆB 4ã~Ø€c0¶1˜WYU5Ú?ûcSÿ˜¢mÚ¤DÛ‘úפn…”¼ïÙRE7%R•Ÿ¾:Ý™3÷»;¿ßÏOÄåA²‹….Ë´ü‰ÛPåÚ4TùTCmÕCò^uKQíh•8eõCÊJo[Í0°GQåRHÝšê.ÙÙ‹ð=<ŠÄa ! IŽ'£ÆbQ!æð h/i Å&õ9-}Ѩƒù¼@#%4]@wÒòBÙaá.Ê‘\;ùÏUM tÏŒŒž×t<’éíÖE¹q^iØ(Eæeô¢º@2‰€d­Í6£4ÿSÛ1¯±Íµê)szë×­sñ¥lV" ÛMf>?SÔñ³§îÝ»«N¸o¨Ÿë»êæ½÷ÿˆ $Dgggm¦Î”½{’ø>… XœTT´‹-N:plWmënc÷OÀÎñWz&·uO ý~dp8ªg42èGÆ®‘èN°Á 4â ½#¯Ú§b¬cŒ(ºíñVwyœ†âûŽÄ^•"öÄ=²]ßwù#Ž(“HH"Åé±\‹ëö"ƒ“€`‰séî޲…|!¤kéö#=}¯ýªŒgp!·x<Š…%ãx:%ØI  ⬠-1}#Hßøvç§1ÝÖè‹Á} qŒ#ƒ>ÄnßÖ®ÜÕØ„ØGá©X"*&øb’:qæôÓ™Ù`h5’Œ«a977ÝÂÙ(€Ó2eH¼úkw¤cÚr—LâÞ´î_é–CÔúõe.9Ök¤n%hçwûãr¤ ­†‡ - åšïÎ5Ok­§½{z(. Ë¡@çn©·}Ó4âRÔŽè`J×-Àú5ܬÔ#/QQê²NyƒGSçÓV*J»š\Í#¦á(+àQ<’ƒaÐy3P^¼çŸ=²·ñƒ½¶ÚÔÁÆ4WS¦ãæþ®ú­¶ÁKlQ4êFoj’;…WN¦'aïLŠb ’$x$.ØÏϾðFñ¼æÎ8ÄXhÔæêé|“é‚YW¤×ëTùjÐP$ÒÁ¡ýAèÏÑpÚF5²—J'1 %…)<&ËV˜D[Y lZÅf’3 †,&3N¢|>WŒR¿È>­9§Z¬çÇãd}ÀÍÂW`$Vu²(Âcc”åbhŠH8î ®€‹‹‹pÑ•`p‰Ìs9Z]ƒÎÏ`ieéË//P8› +±ƒdö_6€CÚÏë`«ÉgÞÅs5R¬·[é\]Óù[)d:g¥“hnfÖR{Çãv3  Zxª6Ï© KêQ$¢‘§rüpÈã6:b’99ýäŽþôÚøñ[]G@nYúD¿À|húÓmeå;Ç(vÆI‘$…{¹G"‘<|ø0.õë»êËñƒã;¶}÷3»{÷nNNŽBð¸hÒKgóS²zµ|G§qL#½SQ½Ñ=£Q@‚/â€_l×Ò=ŠtÇvN½Ò3…ôO2*°{ž×ÍczýHï0b÷ÆõLÇX'¡Ñ×hS|ZŽOÃ’y‰oS«¢‡¦£ìŸ#¶ ÄéížøYiµÇÒvïŽßs(ÞÔ‹X‡¢'.w4À®åðï`x0ˆ8‡¶Ù=Ûz?cœÐß÷ª¤Œ‹DìD¡P˜š$ÊHJLŠv^/ÝîDlþèþÏ~0ÉÀF5ôŠî‹î›Œî¡»ã*¤ìCoS‰d6Æ'qÒÑTŒœxïÌ“ù™&™»´ åƒ)KÞ7›ø(!Æx©@’yêàuk³tTwÕy»Æ§–xä›Õý%ƒm5nE™KV6¬¨ô(Ê-Ðîû~ë] ”™J 4 6j\òJOKåðm°ÁĽ»à°ïWú~ãÛ4Ї\ HʇÚ`>¥>EÙp[¥O^á‘I1:Æ\"ŠÌ òÿÌŸYï¬Eª_dñSTpŽOâÎ'P%Yïk‹ôô³úœ4b,²cÛB[­ë¶H“¦$2©Ñ4UU¦I›¶µj·.J œ&€÷{¶%•"Š©šú׿þüýÿ÷{¿ÿñýü9?Å“ˆ+ºw8”¡|ü¼lÿKµ޼ŒœkÛ£´ìqú)"£éäLš3ЏÂé#ÁÝŽÈ.çæšBÈÀõ¯/è É0â‹"£Ó98f 鎱 áÉS§ùEà £ñ˜h²`ÖÕÕ•Ú‰/‘om H$±ººšª{zz¤,<—Í`3„GJÚ•AÓ¥ Q&Úü0IH2Ý4® 0hlUýEãê– º%ª©Ÿè…4ÝcÄÀ9·¹kN¥+›Ôê¯'îÍ^ýEOÄVï“_òëäƒó«‹pß%67î&–Ť²5¨¾RöOZ>YüôÚ§ ]ô*Þ˜T5ÎhÀÛ† º)¨…Õã}-¼¥qlÛhª)¨išP‹'-¤òXý˜BœÃe 8(År8YB7?“ƒ³9Œ’œœºã/˜¤NÑ!Tè‘åº%ùÞŽBo'%Ùξ£:‹¼íNq‘SRHJ…ni¡G–íçzÚsG;Þö·,Ÿ”’퇲oš1¾-4ò¶˜xKB´Áy°ËmšY±vFJLµ©§D*蟕éÞ–ê F¤ž‘ÁÕ[h+#"y¤Kk»(=÷½—Џ9Ù(ޱPGa‡ 8Ã\œþ\æ3¯>-¯è3Õš(À¨°cèËu[¥‹­Zç±ÙÙ8£¦ò$œ²u8L‰D*-Ù®’<¼P·KeŸ•É€ü±ö»UšSjÛíÄ ½ý쀮š°ÖZ¬'m–*‹¹Úd¬1ª `¦J«­bÈ^>L”Œu–ú/9|øÉåb ­³³³©û*'¾T¯­ª©Ç¡†9oÞ¼ 7$—ÂbeÓø’r±î´ ÐøªÙVn7”ÆJp”±Úfª´ƒŸ°^Ö ³¦Vc>eÕVZOˆ,T€, ì­º0§¶.©l‹}¦e¥u…\PÙ—ú¬ëýsË]µêy­ÆÜQšÁæ5¶Û:Ûm‚êYTÛ–T`ðȜ¾UzYê1/kîhŒszë§„ÙSuú§Çesrx¹|:ïû¥eWÞûܮ˛ ë©õ‚ˆ&¡ âOl,'ép%%*ùûv”$šRå¡o‡ø¬$Hþ½²Ô+í0Ù9\ gÒy›O§ ™^Ù‰ït÷#n/âì Þà¶Ñˆ/r¿ÃÚá #®ØÎ‘XƹÆl åãxFE âÝí˜FŸ_VVvýúõû¡~p­¬¬$Èh8™Ì\A6gæ-i±÷ˆüDC@Û6©mò+ýŠÖpâÒXó˜\ÒnUÍÅAM㸼Á/o©[wü§ݪZ…á”ÁTe4œ4€´Yj¬–šÿ-Š€ P>—ÅâaÌW_y$˜º{I6âÛuŸSú E| ê÷¯]ÇPƒ<‹–öÕöªUCÄk:¢‚ô²UÀçƒ+M† #˜±Âf(7ëϚΗ](¤f3²àq CF.OϤPä+BùP&ûߘû(’êYXX¨««£Óääå²…´‚Îòv¢†€ ™_³ÚÏZ5F`$}¥ÅTc·ÖÚ(·ËõÖj³î¸ÁR=(zEÊgñجù΋¹Ï,Ê͛ǂÎþ‰‚øÜ`¾k°ÎkÍ˺Á/ÔÖ9¹i^aäXU ®(–öÕ~3؊º,·,), `*ûª­Óˆjà®Â/ZR›—åæE=ùûn­æx5—ÃÈãâéŸË‡dóLeÕGúpmssuíÞf*¼·±¾º¡I$à ‘(õÝWНM}ÿ/e#¹µî=ðùTX6)¸vêŠó„ 6-—ÃÂ4ž .7^ñ±ƒ -;F\ˆwq½ƒø~ŽŒÅ—»h„¢O8ŒîžD¼S¹PÀbÒ±¬}§ëw:Bˆëò_lŸ…„—"ä,BÆvzC´ÖÎÇ‹ïÍfÔ5¥ oš'9'‚8£ˆ3F5ÜÄJw‡(Ò CIV™Iƒ_‡“Üâ€{áôa?âCF'ÑÐrq‡v»¢éCQ„œþÙ£7Ñë.Ñò`X“Å!ÈÇ1!›•IÏãe—=4‰¤þypƒÝot´SjÂeRFǹÇJDƒ}AS½çMIÌÐÖ^ð÷C Bßèë”[UsÑ„ª5¨nšP–të¯þùƒµD ÎïݺûñÏ&ì±W€Þë`ñ8'Æ,­ƒ‡[ü¬7hižP6GÔÞ_Æ–aX2ÇûË??~÷ƒßÎÞøõÈe_ׄ©Õ ¬¢‡ pÈ^'Ú&kõõŠƒ*Ѥ¶1 nð+EA}GØÜ6ª©l=SpôÐSh€ƒeÑÙ\›róØ<4+‹ù|iž¨öé¡váh×ȯ· 6®3À ¶ã¸qÛqA—ÕîjWB _°I“Ž‹=žLœf\.B€/I\;6ÆŒÀ.6 »´º"@W!®·ÔžLÛiÚigê4íS;nkcÄD‚CHÛ`bóІ–â!¬—F6µ†À@b`d“n1Œtn-Q¤±P1g½Y¼äãÛjØ xË3Ž@=›=-[îïÐ-›šƒH{ä›®´v'ú7ø#/øF_ômi±ut“w „™KAóohf4ò ô#¤ÖÁ-žþÍžPólÀ•~ÄÃü"úöeSÒá"_*Äq K"Y)$ a§ð¶‰ùÜc¹9ápx†YÖøjYÿú\íaË=úiÃ@‘øÊ®¼TsQ*‰¸<¨ï8|nÚw+”C Ä9àÇ©´OS¬«i/t×?vBéÎvÖ©"Ö³ÞÚÞ®MÆç˜§™_¾¿gŽx]†Ú°ûO_~]žÃFÁ!‹L ·ýrö¶ëZWuØ^ÒÝP¬¿;35%^”Ù90½¹øÒ Yb~qÃ4äQu›+BzTUÄZÒU¯èÖ­—FÔ}†Š͹žúsýúÒ!ã™>í»=Ú VP_Ýc>Y~ß¡,œäÁK”˜G²QGùzß-¡dÓ.¿½7Pƒ·UŠ»kÒÚÕ¢– ©§2³­fO ZâSJÛÔ5@eW«*ëL÷V‚FÒÛÕÏÚÏ‹F†Uf0˜d¸L7Za¯4Aã÷.˜®ªèQ¥©¿\ªÔ…ª^E­ñ-ÅYû¥< jO@@(g’(¤Qr/-<(É~÷µÓuòzsMç8ìG\ö|§-ÇÆ4ÈÎp‚þ$§Ÿ¶FgNã‰àÁ0>:<:[`|¿_Ïš÷axYŽÿúWð¸(IðE•EfÖ\¶Èl —Ü 1šÌr‹£¡¬I£¬É~ÜùSYí©C?¡vb45á<4#CòÉ'7—™Z%®Ýe-p=Á±–[W£âÚeùþ/àiI‹á-âí©eÕæcf†"r«Mæ´ç7B@˜ηºòìö\+]h;ÿ#…”’²¸,’$„|Fl?œ‘>^V=a Ìjšb î…:ûRcÆè‚6¥wLií€YcãŒÎqü`rMšœwMŽÛÛ==©£§õ¶9ýq52Õàœ6¹'ŒŽ»ã”Æ<]o¹§±NZgŒ“Fw߉ÓûÅT2Éâ‹8ƒˆDqQ‰HÔÝÝÉL~9¾[ŒA˜ýz… ¬ØøäÿòXÝ<€ÕøüÖßÃN%’Äx2+eÎÂp–tûëÅÛh÷KMHèçˆ'’Ð܃t„ŽÞžÞO鼺^Ið÷lô!þH"ÀÀFº·h4˜Pº KNÊÈzÁàDú®nò!a¤}ñE6ûÈ·—wŒ þ¤©ïï`b`è›5Ò»¢‘¡DßÓCÌÿ¶…ÿ؆ÀØÆÖ¸{‚N@ƒHGx«o0Á'ô#‘ÄÖpbËâB‚£ˆ?°­FËÍÎãcX —‡¥’ý½ÔT¨DX{3$&ƒö³Ï?e>` ±‡UÀ*9þû<ºÓ$‹+_èõE!››ÊA f¦¿m©TvÊ{ €E¿¡4Ô Ö]i7›—÷è*úgÛ.W÷ÑΫ7î|:gJÿozÕAÃù.íÙ.]EeìÆoï,MÖgã±»±©ëŸý¹6ä8Ó®9Û¥Qãó‹E`>€‰Å³ ‘Å(Ì›þGM›IÙkVô®€$L+:µë¥‘óWÊ{4e½Z$A í|fTle•öTîSµY¹‡¸œÂqÅÅ|¡Š88ÅÅ0(¡$lŸD\šÿ}ý¹lïŬöK ´6#£½šjS JQ  "i]iœð¬ñ¼hdPeŒT™!ïUVf¸ª0\«0½_i-ÓG*ôµ¹ÿ’ÅV¢~çБW)‰(s¸›cà$.›‹cTl4oWNù Ý1¡È`È7ÚåwA³#×íÎoi*hvËÝ@«Ìf•C¬ÖBÛÓÖ HÊ–`(r¹>Ÿ™Ù¹h|ÝÊÞKXËñùÙ¹ƒÙ(>I`\‹(xUf>n±äÚ ›ô9ú(m)¤A#@2@šEn®À9éœ4!ŸÂ¹<.›%•¦ß¼ùW¦œ‚ܸð0p­QäÉL²¡_“ “ƒâ###<…ÅÛŽa .’&¥ŸØ\Ÿo´ÙE.:Çf>BÛ \ö"cËwŒ—rkŽHÞ”¦ˆ¡îà!É#9ìd>³NMJΓìqüZ3aþ'ùuÛÄ•|â%´´Ý†öxìÛñAnH)A-…Ý å°C-eYVrØ„„pʼno‰søŒ8>b'NBaEÿZ­vµ•ÐjWýkW•ØUÑ.H¨»r“„d¿±W)¢BÚTT•ÊÓÓäedgÞ¼÷}¿Ï=£tŒ·š¦ÔVpÈ„Šk5LªMÓZÓŒÎ<©¡ k­ã:jRß>¥µ€F&ÛÈÕjdºÕ×3´£5=P­3¤ížÊ°¨¦î]ÔÍšœw•”u—´CsØLž0–T›Ùë+ÊeúÃç°`.ÕëJ[™ŸA#ôrZZžomQ\\Àãó8x^f†–0!~yëÏ-—SaÄLw]cPA¤'†ô ŽFw8ÉMêL†ÿœ4‚x‚kìÃÃ}ÉA¼ƒiÝîŒ]2 3k=ÊE!}ÝH¥Ùûi38AA£ˆ3ÀpÄž+ˆ{éÆ\IwŒ Îþg^ß#Ã=€8CðÝ$OñfúûPŠ=–Öet†<ã Ý]p Ðq ÑãÞaÄ?´¶Ý³î2™ýöölq>++Gˆfåâ9(ÆÆ…‚BÙép4691;m~ñ1Ì,> KÿÛ°P¬,­Ä`e­œŸ¥‰baañB}£C—6Ê"w“ðø¥šæ>Rá×ÉÃzyX[ ñ+W›ÍÏ„ô¾ðuðF?Ôýû›þã—‘÷«~U]P+Ž5u#¶zŸÞûY¸ã³þó~S§­6¤«µÊý:ÛµÞ™åùøöYüòë[¦AW³ÇØ9ì»y÷ÖÂòc@þìòÂÕ/~Û2œjšS}ʆ°ñyi¤6¨–‡4gBôýà Ÿ hêúÕЃÚêˆö“°ê8ühP>Ú®èVIŽ sÁ$,xMœ'äCš†¶‰Å'˜,N.ÁÝQ*©)/¥N{Ï@xž:€Gž¯Iâm„Åq¢@Šßà¨û±ñÂh¤^;T¯»ZoøMÝáæ!ƒ u䜡ûTsýžÃ;Å› sp!Ê…`ÉËEqœÃÅ8<” âÍDiE™ô‡†JR'3èeÀ†Yf60’2“õp§y¯Å*µEÈ YAÆb2JÉZ#ªÊÖÍì7 #óu‰Hx-v@2·ütyò½Û£x¿o0Š¡LcÃz("ò«Þ?e9B™Ë)¸à‡©Âj™,‡­¶c@‘}›öå¡nxóY\\˜ Tt†\¢ãÕS¥Œ¿HžL²ßhñ¿¡H€/ÆQ4^.?›çˆöˆ÷žÜ^¥ªl#?&ÍGHýG†–ÊÖÆýçvä¿[Œˆs¹,—™-æÁ1S€1qB™«ÖÆ¡h‡¨Ú¾+xðÈïjÏþCg¹G¹]÷Õ– µuFk{ÔÖ1ßj›S¶Ï)­³mÔ´Ú:©1kÍ«ÕPgBm™ÒR3z\dê²a®…\PšµQ ÚŽ õµù¡Þñ7yëù·ßÃÑ .΄2“ËápØ‚VÓ‰šÛÿ*1‹ñöäŒ}·Œý‰5ú—–½žžÅ%ô^Æ ˆÖ8›“I^l|µê4Ã׃¸}I¾‘$÷0Ã9‚#ˆ;œf‹¦uŽ =£ˆ/Æp‡^éò?7¸ÃÉNи"ð’+B3 '’ެƈ’,Œ`³˜¬¼¢ôíÒ‡o÷JjÇ@ PÁ>„ôFÓÜ.¤Ë†„bˆ=šâ?óúN  ’$W˜á §8Â)Ý©]aÄKvÇRÜ‘dOñA‡ÇLêŒ"}A0öâ ­5Yßøðh†¸DÀÆ8l&_€ ¸9ü̬"\TWÛôÅ_¿š}ÐuÄòâã%PÅ ¸b™æî“ 6ïS&Y9ŸZãù¸I̤ J>›K°°ìŒ aHZ}¤©×XÛ§ýµ¯¥.FBº_m6NÈû5ðEEDSåoiëúu½ÚêˆRç µúcž‹Š^Þ§Vø5Š€º&ÔVQŸèkmèÑÝžøš~Ì…GcËSº!{Ó0uʯ:íÕhƒ¶Ûÿ 5ìæÄº^Ý ŸRÑä¾U«éY¤q²O`Õé NÐV÷*R'BmŸø• ”¦Ù>M¯­¦_SÔÔ š䛤Û8BŒ›%„õÍÂ%l]žpp`8^ aïÞ*<ûÑfÏ…-T]™óÜÆžs"w=á< &)ð4¹~tc¼(‰5èÁÑÚ66‘Á&­¦¹õXÍ;¢¢bL ÌDÙlز¸Ð%øl!ÌîÜð^ýN…Vª4í×µ åVk…:h³0Q2‹íÍ\IiàŒµ’24êʵúƒ: È„’Q?´F̺Ã[*r9‚Àø¶9¯xü›±GKÏS#‹ñh%C`üËò¹Çp6{«è­K—MåæŽCvr¿Ù"£ŒåfÝ!Csy³¬LòXBÈÛ½{×ÝŽG³¥å¸>žDH"^=uæÿo+qo%è=¡]¿~½¨ àâ°=! PA7 ¿t[nÙá;Û„[KˆbQŽHŒK€và àq8o–”\ý4ÐëI6HrÅx|‘@ìÌ"Ø9|“e ¹èfœ+å}ë]ß¾£ŸW_¼u¹ýŸ†Î»†îº®)Uç´’šRšÇU ëj5ò@MΑÓêÁ%㬺}AÛ ¼™o±N+m÷”æ)cÇ”Ê2Ñjºoh¿£·Ý¨núçefÁ«a²R<1ŠoåwXm÷ïß_™–ï²ä§Únܸ±ïƒ½l FBƒW}í‘“æÄîKu§v'w "ޤ'ì@Or!0ÃH’Òtñ'âÂÇRá$ïµt}· ìýŸ•nc8¼Hï•5]¡g]<Õe¸à'¢ˆzâ)F÷UTã !=!ÄD|ýˆ'ˆ¸Ó£¯vîâMö}úò˺ûXlnÑú×è<Æå‹rˆÒ¼R²½ãîÄ=› @;ðÃÂüãyù°Ïæ–èãÒ·yei9'Wj§j„ÄçþK~™7qžq\6P’6C,K«]I»:|˧¡4¤%àâÛ¸$Ällë–|pZ–vW‡>d[’m]–|B‡a¦ßú¥CÚ™BJÈ—3Ò cÀ`l£>k%-œši™¾óŸW«Ý÷Ú÷}þ¿"Ñ‘áQ‚'HAq&p¹lïŠBE?-X+ÃduxÙn®X5a›bª *„N)†`#HVEèꨀD A5AãÑ(YhT«C5‘&¹¿éü§¿e¸‹™åÌÇ»¢´ Ÿ:m¬Šjù›ÏùÞãGs“±- 2L34iƒäJш"l« PʰU4W kB ¬ƒ¾¬ Z€*ûOׄ²R›t£2`PûZ?¥è2äi¥¾½B'¸Ê6Œ{Å„ˆ]²M¢+ÝäPɼu©¾ZÐH¦[ûßfŒÿQ‘zë¸Îâ9\_¿»,7ëÇÌÎOF ‡ …8ŽÃ¼øß¸ù#aNÉ–‚ÅuÍe´­ÀÚZàtõ4çõXŠZÀm4œmö¼[ž Œ¸µÌÙRÔ b)µ˜ËÌÖýf¨·´ØóÏšFœÅ-'KÄ<1.à‹QLÊìݵûÎÝ»+Ïç¿U¼Ä½þ“ËWp„ã*àˆ<_–ß\ÜÖœkwæw´î³ÛË\u¹õ;¥;ˆW…B.$¤|aï}o÷×7o1Qhfn!é`8ÂÄ$SO°Äwf’oƼÐf¼Ùظ/3¹ØÕËoBQìc.ΆÁ QTÊ€pøfš$ÛP÷Hǹ<MQ¶;FÛ=SÛ}Êy›rÞ¤7-.ЋšeÚl²ÍЭ÷m÷)ÇmÊ~Ã<à.­|'Œ#1 ÌÈÇ[·n½páB|}–zDzÎÿK|clÌòñ4|êØ_n|©>xå¦òæhH…ìô¤W„Éü—÷ìgÙ\Os󗜣,ïVÿ«;$ð=ߨjßxBûð‹í¾„þQVç «o„ÕÜ~¡w|]ûðJ!Ê‹îðºZ#G´‰ÇKNå¦'¶w²ã ÁÄžó/ëOé"ö¹"iRîk½‰ž(« ÂŸà $¸ƒkº¢‰=#,ï²ÇÃZÝ{Ðe½é„@’ !¿!.—+•JÇäädl á¯`YJ)P.^¼˜ LSÊvDvåî¬uTsUÔª4õREÍŠ!²bà¤*Bê"”ÚoX)÷?棴ªj”¬ ·Dí`ÍB¤‚4ÿ‡¿¦ê§*†©Ê1sU ©ÞK_¾ñYì3ìÄîêC6À›š!ú¨ß ô—ÛoM€Œ_AʰY¢ö€› §:hu(Â$Øã©MÉj¿Iî7iBfŸ*1×äù™T&áñ“Q.[‚ &Aø™8&ðƒ`Å“Šˆ]oæ(öon–˺5i>]fO]†·VÚ«y´)úô>}†G›åÑeuë2zt™qðÖ‚R½úŽaO-ÜLïÑ ?³¼u™‹Øà­MóÕ¦xõ£ç…FuTDOé騆ÖPguô2®¦á ]ü5¢¥Gôæ!5 ¸2½yXGGÔ¦!-5¤1Œ©›&ÔÆójÓ9%9¡4ÑcÚUqBþnÙ;Òœ4”¡p 8wŠpˆ×P<ŒU‚â©Iâ×ÙóÒ÷Vï¨\)Z°Sæ"²¥˜n+¶¶åÛ…Ž¶ÂŽæ}®ŽÜfG~«½Ôa+h°q:©}-tiÇrÛoγ·°Wî:’’,¯ƒ PŒ‡ü|ïž›woÃQš_HRbçgg¦cL¨ž‰-É_ž¨ÇË¢U-¿-ív!ÄE8ÁGPœ#xCœS•Wu⃓šýªÂ­ù›ø2bƒ@Ì#¾Ãx{öützzziL[†g]žè&1V&“ÁfŽK‚‹ A™ÜæE$>|øÒ¥KÿÚLáÚµk>Ÿ¯¤¤Â5p äw,ÜA\ÀÜyH†@›žeÍ-þ¸þÊÜ3{²eÖìüº‰¾O·iܲاÌ]SË¥”§éá1묵ëê)ª~ÇÎ „ èŸUŒJĘè@Ùþ«Ÿü-6ûø€ÚãoÛÅoýhŽ·çŽQÄav{,vïÖ¤£Ã¹^¸AˆsÒ’qBB(sÊ“7¿»êø©Õ=Þ¤Ž§»óË X뉬鎰\ Äþ V`‚ÕZíŸ`u†×ÌÜÂòï;ÛY¡_­$º‡×u„Vuº¹þû޲úFYž‘Ä^ßÚòùél‚ãi¯ÉÖj`9Xž±÷ÙU£«º†º£ ™0p]Ý»|qYÑ\Þ—rÞâb(Ža(Ÿ/Iæ”——_¿~ufffq‘Ÿ“Ä– ñ•+W2eÙ|`II©„ÃÛ±}£¢ó´&d­è?-“5àÎýšAZ0ö&Y)‘û›ª"ä/'u!êó;}8; ›‰9æ§f§Û&ú«ýT…¿I°:Gz§b÷cç!ºþþ‹OTŽMð.Ј6L‡®Õ+pHKâdÂ0‰ß“Q…HeÐRŒ0ȧ5(R¢àE ‘š¾&uÖÍÊ>c]¿µäxÅyۉץˆ€‹"\/â ¤OB $”<›Ë^O ÈÛÓÞ/ÕR•íÒnêmÈöÕgúê€7€L€IRêÓúê€+ÒzuéÝÚŒ.Ì­ÛØSËPLJ0òè㈯ą·Ä<Ü¥Ûä~nhd\IUgU ~€ rFI‚öÐÒ£:óØÂc£*rDiS˜¢*܌˹é¬Üô‘œüµÚrNcÁc@5}jƒé üÀ¶Ý[ˆôÌ$^!ã(ÏdŒB>§O擌§rR¶§l;´½üDÑqse)¥WŠF6ÚËÚ[öÙì­ +ÉûÖ2ôÒ.ïìÒ÷Z>´šò ­yÖÎ_¸H–ÝE¾ƒÌ£LÅ[ŠÄlŽð!ÄþI}™7uœøaC$L¬ãÝ’ž.|Ôh!i(Psã£PnlcãÛ†B¨,É’¬Ë·uÙ’-Ë·MJïvš¦„$¥ÓL§Ét&Ã0é4e’ÛøFVÿ§çÑxhÜÖ‰B›ÞìîÛ·»ÿ¾ýÿÿû1Á‹»¾{ÿãa°©¹™ ›ö8ìøLÆàØ ”ªpƒeq'8yü„]1F) ¹’§PFÉ×óå1˜’ŠÂ•„TN3(Opòø±ññ1pe £ÜãA‘Pá) fÁ222âkõ¦J…+ ;”P" #@Ž9êv»ïܹÚ!œ÷UhÃ¡ÊØØøO{“­0¿`çŽïÈ©/_ʈ%À$ F3£Žòe&~ö›|Á÷7o,(ú‡¡~ªÜ2ªªÕYF®GÊMúºpÑȘ¥á#UÕ}}ã°¹ùW¹¯älÚ®äóqÆ@p&%$ÆÂ’Ú¤ ™c/«÷k@Yö7A úrâΗW&,PMæ|݉± ’…¡k%ŠøL—Ư>›‹8ZW?Ðâô.[Ú"íO8`ŒqtFÚYN@lˆ½ i¹ŸG9-Z‡ó¤ñ¼Ü‹H‹;\4²¬©ñ^E\O6v!ÖŽˆÖ눱晽‡†G“Q"Œ/¥V]*lô=Õ4ˆ´ ÍCËš_° .kêG܈»±w¬hìZ꺫œ=+Ü]+¿—)^+b¡ÅZÒT×Èyƒ…»K¾xáfæL ê!Ãüdd$))I{‰æÑJ+(z“ôÔ•¼ü.jóÛ´ùmÁèÜ©Îô–…‹FÎtWœî¨Èm×÷¿óÓ©À, :8¾¿üíN hŸî¾ù#Û»úÞ¸><;ÆÚÌÜܧ³cž_öµés»*sº+Yx𨗺.° ¨–ÝÊ~ u® ì’ã¹ú¶kÿ íœmSà ðaa‡>Ï«…p@rÒS~¶½²¤Ë\àÒ¦]ÊØ–¼SºAÎâ•.áó!¦ ErJ,âŒTâbM’bdIÏÇg§nÖäl®+M°_ˆsý@Œá,–»JX i.q•{(šKåA‰·—Ÿ$ÚJ:ÜÖ·œç†Á+K%0à«B#¯†H€+rYéÉ­¢*1ô•ê:ú ´°" ʵŒ¼QTõj¡~`r5C…º×K¯•TÁ‡-ÅjkÖ…¢G÷mÜž@I¥‚2Œ"ˆgI±€”`(à ER8%F%Œ@ümbDZ-Ç.§üPÄ OÓë“ æKuju¸h¤ú`½ñ%Kmrù Õ”fV¥i̹µ·_{oòÞ $rsãñ§~Ñü3]J…!I[ý²u©óפÖé,G¬e)åûã÷Å •A Áe½I‘ð“¡`Wþ™Àì4vfÀxoB¸fˆFü~ÿB/´¸C <y•‘‰ ø$¸SÒrÊ((†à¡ ‘T qÅëkëÀ´ç>:ác£ŽC8evrÍ©©©…› 5qÅ0>f _MNN‚vœLONÝ~÷÷žwIQqÒ‹/ÉqZŒÀ9$‰cŽŠˆu_Hãñ^Ñ »>05Ý/³Î”Yüºúa•aÔ&Q[‡ËãºÚQuÍÇ—ŒZÇ=“«åxænF$#E`ÑMCrD$H•žöÖ¹¹ÖñΰGR á¿øýÿwå›oJO‡scü8–H+HžÇñ¯§§"V+ÒÒ8V@ìv^EZ†¥7€‡ÅG/âè´õG8{Oï*Wëš+•¢˜4.WR$œäÓÊç‹#\4‚x;‘Z7bkGl=°=Äå^»{Ÿ,š/®YO’‚o½°ÌlAêÛ‘æeÎNÄîBjšwÒÜÔwGØ{‘æ.ÄîEìK]7¢Þ»ÜZ·V¶ù:ž’$Ú×{u6h !Bà* }Å/!ú}¤V}ð ët†Œ¤DB‰ ZÈÄJö_ 3Ü%݆ì6UF«*Û§¢+òUe5\NWeoÝÿ¼l“£ÊgQ„MD$FC‘à\oè¤$brÛIúne^ÚFûù„Æâ؆B€Š8gi¬³¨`½­HƒkÎ÷8Y‰³ƒÄÉš +À-_éÍ×€ôC½ÔÂH±®¿D?XP k‡€@…Å•sêkç4,ºéú.Z U¦Œâ¼½é·Çábœ*NR ŠHš†&ÆQ¸Õ)$‚Bi™P¾…Ùzä¹ÃÓ.è’ ÆTp‚1ÙÄÂCJ­%¹Ú°Ï.1¬³¤ÔS,ºtcuNí[ƒ·ñfÙK=´sÖ,'íê6SZUmrÍRç70[ÕX­iÕ‡*Hž„ýM\ÁÈá Nœ8qçî]?·>˜.„õ ÄîÏ.ƒ3άVsbb‚PȇGQŠòàô¡yøpúÍ77"ÿÓðÆÉì e!ݹà ñÌÂÁðëægà ‰öa¨><üÉ›oüÆ ÕíݵG†Q’¡ ±8UJ$ù‚Ÿç_×4L\1OèÌ£Z}¸hgZ]3©kÓ°L2¢­ýHcù@]U¹ÿå8£ D‚1 ¡8VHïÜ·çí·nqæˆñ±Qbx‹vêÌÑ“Ø:T*–<¡\È<ƒÅ|mÇÁ§´ºÕuÎåÎþHçµåö[ÒØÑÔ·(@X‡ˆßt5²º?¢¾qõ,·yWšW¦¤I¥’ 2üözÙÖ•Å—žlаëzzŸhð®ÀpwGÚ;Ÿ(¾( ¤1èZ &Çö¤#NRß»ºqDÔ˜¨mûŸ>–±Æ\ÑÚà´¼Ñ åð±;_*xúWœ—‹cEx4‰­;ynùŒþ¶Ã _xÂ~7ÀÐÀŽ`­Pô‹:ÍTi4 Z$ÁpMBÄ*‰½YéçlªÂs†Osª¥¬À«)ñªÃE#ù>ÕåvãŸî¾ÏòÐ$ë®®¿÷kˆæª>ÇŸG>„L.Ö1>˜eýèD`æÝ{ï›]ù.un[E¶÷ŸÔ— p×Ç7\¡t2iÆ#­ö´:,Ÿ` ÄBÇÆ'÷˜øÄ¶,[2бu_–-!lÙF²$ËòØÍզǤt(%˜”ÌÐi‡éšNSh€Á¦>e¡~«%*%‰;ÊdxóŸ·ow¿wì{ß÷ûhÑðàÓζ_?@@ †L@%e©—¾{•%]ªÒ-¨˜äÉT󨠌̯¯rÖKÝ À6E¾†·}õ¥=êý~ú…ò>SQûÑ|eùúÝé¢I(Eà<.—OQÖ\ˆ| ÃPŠaÈl…6—à-ILÜòê²²üª²T{ð„‚Û©¶É€1\µ§BÔ^ ‚ÛÄÎK;j—´+“0nyVh¤¯Z3P­¥%UŸ”ª¥šÓ•4u¼_®aÀnOViúk´}rm\ë‘« dÒ7óÒ—¾’FŠp¾˜KñHn2É…õ„|X# Y$%8(Eq‚T,éµ”×öm(øIÎaMžÆ°McL×·ÑàaÉmj̱€ Ò˜×-1ä™5ùz]¡éìÀï·ƒtš˜  œÞãpò ˜ºñÙß•ù@‹ÙÚ×g耠·6›·Ð@R—s4guv= ŸV -aÆ »h•úh=ÉN©[1˜… ÝØ¥ªèVWø50BP™ÔVÚ©*wk¤]új¯¡Ôr0½tûÒ +ã …±H‚EòqŠâÅóùŒ'ŽåP${„Ï‹£È—Ä\ÖòDÁÆWRr6Iêö¦jK–Ûd+Úhü´USí2êD5åV:å´œ54®8ÉÎÚ×g…F6†ª´ àw«tÔ?¨6¼+Õž’iOÖèú:wµÒZ¤8°mïžµ›ÒSW p. †Þ®8—®´¸Ar8þñèFJÀâC\^I-sÉëÒ7ªŽd1ìÔ™òæ,Csf£=³Ùþ–Õ’ 1ÝdÊ2sL†l£>Ë Ë2sÍÑ¢ÕvíÏo§o…9„>o£S3w§>éýýù¡³ãwFÁ‘ÒOÆCÊ]s¦eÖ]äÑødÉh 1e4Yv6)wªŠ_/Œ'¤˜Çã¡$h„ËC¹8ºnÕªF“ùÒ§`@‚&Šà¦ñßÒçc†¦'§© ÄêÐätp’~Dû•àà kz†‰tOÇ›ï´D’¯P8Ú^¿~}ÇŽ$I! ‚¢èš5k†‡‡ûêsÃGÁƒi„k„R˜42þ‹^eXúúùßn—á\ gcbJÄá°…«zãÆ/Ì­:k´hä¦Îòo­uªž†œ1uToÓZ&ŽÆUºQù¾Úv®üÐQåP\*R w–¶di³¥éö¿¾üz$z& ì:y¢Ždq»}qcÆÂ–VÄõó9­ýˆÝ…´»÷ÀœŽÓH‹q<‘"^:>ðœ½i˜çü­í‡%±ÉË„/‚s³E|R²|Qƒió.è@Žw"ÞÁ¨Ñˆó£E¶žE'úæ[Oγõ/:ªA1‰#ã^ޱ˜u÷-ÔÚ~´¯„Å‹g xcˆ¤…{K«qœœãèE:ºÿÇìiäD?±£½ÇqAüo>>>Ùá$"¼É2‡299Ý_ö˜+xxBY tåÊ•”¤dðç)”€„ÍE×doÙëô˜Š\G*zµÑ¢ˆÝêÓ-gþráNpd44elƒ ^ܯÚ×y°vÀ s©4½vÛûnǯ{«œÍUe ƒ¬O_ê©ûJõÿG¿ Ð5ƒ1 Š€Š]õ §ºÆ©Rtj^]µGSéR<È|O¤™_S% `¡²G_Þ­w«ËºéÙ•{B*=J ‘ªn`9­¼KWëÖÊ]ê·JêU•u«ŠzÕEU¾¶bÃî­+~œ,BY¼˜XŠÁ~£XìF1Éâ\.Aä²pP‚Ob©bôÕ4"½ &7ÉXº¬UžÖR“Ö*_Ú¦H=Q "q*DN¹Ð-ùîiT­cÀïÐvÊŽ—¼ÓX «Üš¿gÝæ7R^^AŠ%,BÈÂEÖ„/ªqp ,Åév"^€‰SðÔ×ã׬Ú}xs­>[iÉӲ̖Ü&ÜÆ £%Ó|,×jËi6¿e´äšMYC¦˜ÈÄ”c7AÑ¢GU[àz ŒÂ9¿3þQû‡ê|t§Ì­ï·ùCÓ3Áñ[ú\USú¬írõ†lÌ«9ÇÖ”mÕgÔÚÆM‡rmIÙšŒ&`1¬‘ˆÄ1 5J`(GH V¯\UU)ýÕ/~9zo„Á’ˆÛ‰äAO'‡ñàí¶¦fîܼ{éÂgÏŸ;w.7ÿqszb:8ŒÄ5°¾åûâG  ƒƒƒÉÉɰàå„< ®8›#‚»ãÀíÐгããã~ú_a@ë'E3Ìwæ?Ä—}PéÇWPGm¯wà!„Ýlv“ä5â *¾áyˆ‚¼´(V@ÞžŽ"!›÷   !œmçj;mgzÓ™›¶3éœý£3ÎÍÔj¯ÞÝ(jÒߥיrSoâõ™ovžÍî>»Ïïù½|ÚŒðƒûæý¾gÞôÑ­[I|> $,6Á!0t«øð±‡rK°hdž2ÌÉ3”ãK…îD5Kuø¨ÎR¥Ojœ»¬ðR¦ÇJ³©à‡i8¶B;pÙœ¨m‘™‡Üúèg>ïÒë_Š`7¯oÉë¿÷·ÏR£9á±ÑQ‘1©o ›³E=ëÌ®æÑ«˜@†n®Y-vdp v¯×›ßT1q>7<|;'ŒÎÀù¥!Úž }Sëz§ÖuyB-S›L®`ÑH¨i³m0 öéõ–)¤¿;˜Ž²"’Qbëî}.”GfæaÑ\Hxi€[l’Y_·ÅØ ßD,?¥Ÿp ƒŽ«çÕid«¨†¼…Åmã]S«ü ‹¾åçË/›ÿ¥?û¿áAlG«<¿rî‡@ DÍìlcü÷þþù‰ì“ìH4žÅábLŒ¹ípÑ» –6‘GUêü6ð_UéRVÙ ú+Ì?µ2%v(+‡o”»$-.IµíŠÈE•Û%UnuùUîh«—VØ©Z—²ÒÖ*k:$µ£í¢1-¾ž©SŠhj³……G+s^È>Pž}¨*çDÓés Q“uÍñk†ÚE#2G¸r¬¶K/I.PÂQ%ü#¦†e X£íFéKÕz.NiÍ„¬Æ)©¾Þ`oƒ{j²*·&{ÞzCÐ&oïMßÐjµŽm¶Œn0Ú‘¡Û è@ÌÓHïÄ&ƒõ “1ýøbv!öW¦ë4bšØhþ ÄêFúì¡}ŽÍTr¶™ÍFydB『#"<ãЕœÚØ7²E߉ô÷oîõ ¼7´Ï½Å2¾Þ<ò=“-Ô<Ú3u"v×fãØšïø¥T œÇÁˆh6q8.afæ!Ë/B&àí@ >𸾋8¬ãê)|ì Δœ†mÃ¥Ë]tùû5¢~êâ¸"X4òºuÉ¡:UÕvI£]doµ RàKv‰È)6ÙgÚjvߢ‘PÜ!$!5ÑûG&‹Àð@Ž©v,-¨l­oî•6 )jí”Щ¸è„¡ÚAB§ì¢½­jDøt ¨iäF°¾¿aPZ**ÏI~o7m;‹G° „`(gq Ö`iPˆË`òxFÆ°èŒ ù„$I(Ö ¸;†›šÂy/=±èÝøsÙÉõ%‰×Êbeå)¦Æ¤>ñ;Ýâ=-üÞf¾¥%eðjâà•XksLs‚¹>©¯1©¿)y@œ4 NìoŠëo¥õ‰a 0@äð3Üõjw‹Á%Rßl”O7É=uíî:É”X>Ù,w7JÝMÔd½dªQꪽ1QßîËàŸ ±ÂÕ@iΊ¨’*ñ©3Çr ÷:òÎŽT7Ž… ‚ã/D0A$ c @wt˜x$:$e3ر ^ “Ÿ{¤lOéÕ¬y¥ÎS‹"Ö’ê”V_b”ç«UyÊ΂c¾J¿h'[kô¨Oh“:O§Í×js•j]‘¾«¬Ã÷Ø¿¸8¿èŸ›óy»k ZŒ ’Øf<‚À›ÿ§÷¿úÓ·¿úxâcs^Y$"Òö¨ ÊB- e*ze:RTEšb°ÊÕœ+e{Ëq2·ò «8Ô]8² i“8‰£8TçŒ]{­²Ïþ|g™Þøžûçüsþ@Z¦Ôòð”ïþ½Ï.·ˆ Jš .Êè «’1¼(-Îö×:üÒ¼þEÈ0ÞT𢾿ÔëÎl~ÚìÞ'~ïâÒÒM§'–àÀt1ÃÄØÌmïÉüC…xèÌù¤öÛ$“‡Çì<"ú¯·ÿ3]ðƒè‰Óļ¦Xx>ŸuÇ ·â „ظO®)Ÿ·w/HÔ”ª'mªY©aFiœ‘h‚E)ké·mgwìác$+ %y…&3ÀØ2)õdæ1½j_cÒoÔÿc§ |ÛÓ§O3öíÒÛ‚ooÔl²"½#ÈÐDh3ÄêAzÇB­®5«s¯“®ìýŽ·Š+ÑH’ÉårÒÂT d̃húÖw ‡ŽÜÜØ5¢›±Œoés¼)ÑlËÈÚšréÔ#ÛF½¹µÎ<øÊ4Ò?‰ô¸7Ò¯v#@ÃãoX]oª­aפC²Ã"È3~kiŦËLî0ugä¾ã›͉<^¼î_Ì—yP”÷Ç_S'‰Ñ•Ý÷>ö}w—åPÔxPD’ "UåQ´¢rËX9ö¾X¹–cÙ…L;é1Ó&©Ig:Mgœ¶SÍ4Ók2©FkrØ>/«ÄNœ ÉožùíoÞÝý½Ïïxžïç17!î¤Óƒt ‹3¸G‘Τ}iö#žñ¥ÿ‡¾ÆW›¥„ £QiqAÑ\ý…h}´<ù|î™°ÈB{ôšÁkE.š›?|(D §xŽ¥×ÉÏzí'|Úo3¾ªùŒ}ÚÒ]i]Å€¶ržh‹|º ¯¡¬»¾ÐV%ÄGa*’ä )ÐÁ  2sF d@ ”ä)T © ÂVÍ+ÎVvi_ï3žôhËü¦ã=µ$`ùîêr¼«a±ü‡ù|*¼¦*Ÿõt·ñ„õŒæôñÄÙê¸ Â¦"œ•±Ê45-. Yƒ^IPFñRB†¥Ê14EÇ@FIŒäà âå(*6†IØÌ¥lWdîä$s‡SÇRÃk+Îåñgrgsùs‡Âµù1Öâ­Í§â›OKXQrP†JŽÙæ«ÔyOéÚò«l9ŇÊÀ¬‡J-Kê4ù§“²ËÒŽîÊ<²S“¶51y}\Bø–ÍtT4¦ _Ë©qNiö`9÷€h))Š# §ñF` Lã83Áª^… 2ÕF*&AŸ²~÷±WTî)=¿¿F@§Ë23Mæ ›-Ãñ´iÄ‘î4î³Ù²ö¬F‡ÆnN5šØÎeé y:ýaÝEØñ¨¹!×.Y3,ÎL»}Õ’cûÍЯAz?›ý rû?ÞÿÈUêþàò_@ê!ÀïO/|€jO-ÈóõoM¿Ac²jš´{M6źÇô¤~™ÒÌ–4“-ÓbÍ6rtµÙµ?̨ΌK‹SÆÂN†ãªpRIË€p¨"t!ÌyNŽ…Évl¿46~÷îÑ¡iH"NL.0‰ÓbV«gx 4 `F¼{p^€ô Îè°€8,+#á|ã’“þzóº˜^æSSS‡ÕV0¿Í<ýÓBâ æ1|ñ–y` XÅìµ?ŒÙ¸‰…„Å‹Ç1ì/Êk>ѵÜ6¶L˜:Yv6^¡b1%IǧïÞ335=9?;$¦™EUáùÀĽû·þõiRâNÅVy¦xcì'uŽ{µæÛ Æ ã?u¶;zǤ¾éiÓ`ÏuC«;¯(Iņ…R¤”ãá2ÈYš‰ŽŒêru‚·°™¢"|ëœûäää;o½ÉP¥  !iõ z Ò9ŒôŽ}Ç9⺄´­èô>– Ú{—¹Æ` K<( •Òϧæ }~Ä5Ò;†ô!íPwlESûʼR#H^Í®F±œô]=Ï·"®>¤{ü‰i¤Ó´„´ù—‚«nâö"îÁ—©n“¨7 D(/D¬(©AÀÿ¾#®ɶí2%ǯY©d¥Ea±;WÛÛDŽjƒ•Ž/sŒ }o.i\î}®ë"â~ì{;¼KÛýH–ÁT‘,š'Å[†\pèsbÝð“@›~VwàK¡÷ÆÛ·ÅAüF‚„”äÖ÷-šÚ> é©+÷ zÏ• 6zê€J}¦ª“¦"o-+Uóœ€â°ù‘*µ ÃF”rzÈ AáPLÁC•Á'Ρ´D¹%"9w_y{0I™ÇPê3” Š·~¼yìoW>ž¸u/0»ÓÙ[ó÷#ga‹>ÃÔ–~AŸaiú¾uâæ$|™}B펨ï³bÜÍŠÿš ÌÝeOä’¹ÀÍ«7±û­éfcªÞ”f´ižœš²K¶T‹mŸÑšj€í2e˜L€m}¦¶ZS]˜Tø½˜”*ZB °$ŠW0.—Ó‚ —…I¿»iëÏÞøiFÀ·~|=%i7‡~0G“ ʲ(KW—&¼fÓìoÑä^HÑh¢#yéj¸„p¾0-z³î꟯A~ Šd›à`öËÒÎ×Obf3`8”ùOï­‹\· GårV‰b[á½òš‹ûóZçíӴΨï¸\|v=L°<‹ãxŸ' bÈBI¸xeáƒÜ¾í¯ýé*àF‹!-YóVù™Û Ö;çõ÷µwµÿn°OÔZž6Ü©mÔ;ï:>Ð:ì»ÒbqB +W2´ä¤]W®\ ,hýÿ„é[ØàÐàè| '{?\`@ë©$,1éìGº$F–´Ž ÃË;|Uç.Ïòö¤mP’z„”ËU¡Ò•‡!½£Ë[/"-ÃHËÒí[îîYUuVŸ¼†RlJ"1)C“sV'àJˆc$Ä}é‰i¤kéð-kõ-íBºG€Î!¢¼ã’ÜØŽÄÏÕ#þŸ¿ÐôÄáÎ=JÓ´JŠÒ|±c7‹òаµDr&Òñ£e]¾%î‘%Íð÷QÄíG:=Kºoû±ãmS;íjËà-æ]r†ûãèÏ.^°ÕÚþô»ðÑ3îÙ}©›Î7ú @ðD§Ú³Ð}Ú”V`0ÉWr»ò]^…ß§òÛóíz¹N_¨ÓÕÖª,Þ¬Þž–#M¤ Q.GD8Š% %u&g&oßøl}RºŒ¤À=Ù·ŒñS9«ÏlÏý´ªá÷FïsSð…Á îùØè¼ïôÜ®¨;½ac)¦H1œ/Šƒe¤¥ÞþábÅ™{åÿ±úúã_Ë&ëP 3üxxÿÎ=ð3Ã%bÎÝNо¨ÕNkýOu®GZóK«ë©‘~zÎôÂrPH >MPäwÓ3†=‡·9÷F]v89_]ÇF_ÍàølVI^Mfç¸Þñì²í%Ý @2©Y|±YÆšèx¢Þ;AÚx±r÷Þ”5<°rHÄ쯯¯ƒ_ñÆøø8Ì`£þ|v9MsH¾¢¶‘uç®›H þ‹´^};/knDB½+E<<•"%)[ÞµyX6èìGzzWÚ]‚ü£RQº„ … h¡Ò6}«þc¤' î¿"0ßq ñö/˜F®ô"íý,z—†®ÅÁZ—¶Ût.mïD|mHÿPœ§ó;ÍÁ%!¤«—L^‡ó×.ß´ i¾òÞ™’âA·Ü@ZÃoyúðçËœýȵ!Ä׎tö½xí÷E‚W‘–~¤9ï½»}•ÈË–Pø*äþ $Ì+ ‰ÍßÈ`;¶™™‘§Ïe)æ¢ÐÁÊv®kè6}ã˜ñ_ªôb>&Å \Ä^ ÁeİEŒ †Ã ©#ø8äPŠRixrµaGjÎÁÌýG¶–î:Q¹÷ €‡¶X£?¬7Œf‹š¦UVÖÇN›ÜAËí6¥Ý¡v ¬›ó-V… dWº*wÌ|m ´Ø4¢Q^Š¢wòk–7&bæ7=Ñ437ÉÚß3 šaæò,s'pÇ®¤Íj«é°q죳ìÚô(3ñìËá¡æOíE–¥Ï¯p›U†¡æ! ‘3Ìî;@#.í-v˜ä¶…îàÍZàAƬ*—-ßÉ¢šÂí’»Þ¼j/€ ›4¥Õª¶Ò*º©Hw^}¾p‹:[´A Ça(ÀdÎ=vì/Ž’¼›°F–"KçògdÝ©¹>8þr Ò2== æÅ’Ø=§¦¦bàH]C£„’‘g)š»¦ëø™Ñ¦à3cÜäyd±;ì#Ã(í¾o´=7z÷É’e$† ùðëõX3sscSãÌ›k ÿñ•Ù`Ž~ò4#-|“ü“°ö7ë”É÷Bc‡<ÓÚ¦õöŦ‘i­õKƒí‰=ðXk1ØGMîûÖ€G} Cù±î#%)ùáÇ̼-@~ý£;fþ8Æ<ÔítM‘*N\‹®Û‚8|Ë:†–#Hgi»þZ0õ°Ýy}Y(€fçˆPž€¯Í{…ž^i±'|T+X—‡bhÁ„8àˆàEº‚´E`G|û'ñÖV$Ôövèæ‚i¤5×1Yâï‹k-õ_]ìC"7ãü7âá•…Ç1iªݸÄÕ¾ZyOâKx¼U÷òjO”.a+«J‘®>$té¸ 0󶽋ý38ð–ûÖké«ýæ’`4>| iíÿ¶Ã‹¦dCO™Œ¥°E›Æ:ˆ˜!ÆÎìÿxÄzx§lÇ0ƒ×ᤈ gâì>¥¨ÿßÐHUÔ\µTvjªûL§#Úª(]î!Q¤$®LÂMiT‚4Mͤ²·¦älKËÍMݶ-%g‹l³rƒJUP¼±øèæãå•Ö쯩?X^uѤ6™çaædáÁ!·¹o¾“.°Ú ìöB‡³ÀåÈw9ån·Ür)< X±€­«,tM¡­E.Kâ²[T¬™ÂÝìj‹»pÁ®½Pýjð̸‹ë£ì!™ø;óåÛÔyÆqChËÔÑB‚ïŽï„0n´(™(ê4–Ä×$4+Ý:n&Êe,‰ísŽís·}œ8q;q®Ð T:Ê@]WmÓ˜TíÒ%ëÔ}ئNP. ‰˜Äœ=ÇÞX? ‰HAìä¯ã£s}ò¼ïûü?q#ñÑùß~8ðók®}ò«?¨ÌÞŸÝŸJßà»ê"O¨†{?|U –éd’ŸºýÉMêM»k/kc¿Á°5Ô/‡¯š¬™æ‡±³À!d™—±R¸äŸkœ„ؼòß"ì~Ê`l¯‰ðUà„™„”²çrø$h â&‚Ýí'w“®Ýî=¯¼¾É¸ÈSg„Y. ¥J¡,PHT+Õ«dÞWËo‘ $8……¦°à„‹#CÈ 9Bñ „K½åméÚëX­•çÊrµZµB"Û¼qÓGF¢þ¼×·/zeÖžÀ@ýAN!‘k ‰óCÖê;žÐtý9Gh€¨i'žtá3—Àü óΑ“¥’3™e8¬â1yŸ4ô¹¢@ 0%&fi>ý×ß|:èFl¸¯š@Í`ª¦²†¶·Âü¸0Rð÷€¹:ê©$ð2³bc×Ç€cR þÝðEöµabß }ÐÿS°=~öìŸ&ÜV7i"2\á§+Csµœ‚7@~¼6Êg'Ù ?¸É‡Ûh²’…ìAb!Ïð ¿Å0áaÊ…QÞ;j©ßºú« ‰D/%8¡‘K·Èäç›ôwLüó˜[ û _ é $\ôäi<…n{˜(ž@é[næƒS®Ír9ô’ЀLåк ÝVHæ·¾ËqÃâ={ö¬F©–Š%+ z£T|ºtçMOp Ž!¾[Nz òhˆo`÷Ïî4G˜»žÈëk6õ¥T®“iÏKÁh§ç“Ff2¦™õwøÊ•+:V£2è”rô[åÐHã({Ç÷Äiäž‹š$Bã.:íòóîo._S¹I£/”Ke@#Û·½<“ú/;=-?züM¨äÐ>>˜äò¥÷t…A£—U©‹r1RÔzaAóQgô‘îÜÞ· 9‘·uõH¿S«hµ:™\“k,רebµ\¬Ñ.­¬Êñ‡¶^xŽu/©=o\+SÉ fW¨£®4²¸íG¢ð°¨mÞ&ê^é…Wå´õ tZæoUmZ®VÉJ6Ãm‹·¿Z¨W†¹EÁAQì]Qóż]•ËJm/b¨êëf­ø+Ë¿iEZžm}ûQß]‰?à ‰"çDíqQkÿbˆÄÙ¨5ÃRV½J½aÝú‘ÿɲúô¶K—/¯Y³F%SêÕjýzã[‘§Ï/ C]Σ1°Z°rì öxAª—I¡¬Ê•ï_ú‰ÐÜÎ IN ¿éìL~8¥æ*Ñý4T¹Lé€ÉL:5û³k¿Þúµ­ºòb©Ò •ÊÕ+¤/©÷±'ç+þúnïѨh€¡.ŽîÀ=¾ÛÓp ß}p9˜øïŽÄºnô`Ÿó@O£#ž•h“'1'\ÚÛçÜw:úÝ@/p¦.ê¬ïvê@ßì…KnG*ÐNÜ€À q€7H š˜Tßã>G÷ azéòµR•B·j›±xÜ-dãH;‡[¤-c%Í~Æ$+X÷ZpÂN<6X/ÇNbÍ$m%h«²<´Ý+˜cF`‹€YÁ³>0zpžß´pSÄVP‚Ì,œ¤,¬ÏLV–ª >iA«7Go5$Ò| ëÁ+˜PÙÜDmÁ`Y0li&̾^¤˜c†ŸâS÷îÌv’6sT?Ý)L¼Ðk¤'ÿžhx ¹º:ý™`ÍS|"ÉOðc|äT+UM{w‘¬•ñš(Èê\ãl6‚&?$h F€TC½:#Xްf®fòLT’€‚œ©…+kálaÔŽî,~¥Hf0*¡&©e±iíÆé g输™r÷PìrÚͦœLÒÉÜsGÙ»¾Àšl$ïctÒí™vÓ“XøÃcX©Xè¶ ÄA#àgجYÌo}[¸l³Ö922ÌX /4ê%Jqeñº¿4ÐIW@@ŸwÖÕ Ç7涇sÓ·)î3Œz€pS§¸áº“Jq¾V¥1(t›¶lÉ ô¼¹ðL&Êl Ù€!N¥\ñ/îË<6ªãŽãom.'´iðµçÛ·‡wm¯qŒi•Aœ¤'¾ ­h›ð±k\ Q°÷z{¿õµö¾öô®m@iˆE¤ÿ4iD«þÓH¨mUuUJ… Ø€½w³ÏÙ*h,ÙDéè§§ÙÙy3ó~3¿ß÷3&þ³ŠæÌÎÙÓ¦»Ê®»*Ëu¹Ö4rKCÆ4Ö95uWMÍv{ª£”Åõ‚‘øÃß|;E¯`oµœðØÊþÆêB¾8Ÿà”å²yÛwn°9±Á ˜ß9¼˜Ý¹&2†Þb€÷CÝÇpùAýöqÌHü–Í›­è\ÿ|cžt+ÎâÃyÈyqoæqMlêw¯ï1åìyµCñsŠñ¼Âlqö®¬Ï¹Ry(Ù'C!ÌáÁ\Á'ûdzxJ&+f>ñô3Û„O$ȳ¥›•ú ê³ù‡m. N,-æâ|.—S\’{øø†¾60†õ2¡õÎs©¯îJÁ0 °'(ƒ@¬×‡™‡D"Q¾@"áIʲYÛJe—?ûkŽÀ<èåLãHìQaLwN¦Ž:}Šèc‰DúEhYê†ÒB<º—=ØT%¿}ûö‰'ø\¾„/,ŠØ9[Ä%‚§~zÂoñju«Û|d˨ªÅ£iói@ñAàÚG;ìUh[Çt ¤ ¯¶= WøuÐD t°5¨>äSÂëŠ1F…]kAóŽkA—å£Ê7CԮʊbœà[jêè|H{‰vKŠ7Òyb)ã±}—ïÑ•p4JסD£Q’$aãàÁ»}[¹Ü¡jÕʃäaò|©œÐä#WLSÍòz³[½¼åñ›Â«&pžˆ¸üïÊvPÕ:CÕ\kZ-•7ÕÀÌ€.H:͆:“¾Ö „CCŽ¥Ú †ð£Ê ¶ÖÔñ0ÓUk߸”œG¬±\¸ò‡+†FƒmÏ€s¯ÓVk36´Õ$bª˜?ýè/ñ$R±Ä| àªìÑׯ}|5èÿD“ ‘»áä=0tü"Éù«‹>¹¿{° 𛵡‹&4KµZë‡a‘{ëiñÉúnsM7UÙm­ï9[¯Ú÷íW¤xÎÉËÆs”•zVSwÏœÖ΂|“]S·yuלÊ:¯¤ày[i™7Ùþ©1½UÕÀç²Äb!çìm»yó&¶Åä|<ºR}¡³„^:ÝѲ°”QèÂÖü}ú²Q‡ ™lönœ˜ê4E;¨¥aFKE:ªÎ•e¦Ã²SJ|œÇ‡”ñþ¥_'#(—>0õò;ËJ׿ônlØÿ §;›²­·Z7êMëmY®à¦¾ ØðElȇV²%¥L¡'DxŸ){vs‹"³Ï¾Áæ_-aôOeaƒ°æ ¹fwþÁæ%E\ºu KÇ~ú¥ÊŒ~Öÿ6£2ÃíãWìÄùRv>.å[ ‹YU?Ùdļo#°qÁv°ñÌÁsë†Î£wŠ8ÆhYçÏ ëõqŽŸÌIE¹L¡@Äc ¶ÊŠÿxåãÔ5 y5PMŒ>òT@·4“¤ -´ôÉT8 >‰¥¿æÃ‹´ÃÍ¥¬PV̱ ~>ö[ÌU~àçcÓpg“OuÔ¯“{4Ç‚FxõkÛCúCÃgÚÆÈ¶ É–[­pkÚÝZx"ójåî…§³Í§jõ©å~ jÿÚIS[Ûv»a·ñ‹ß|1ÂF— 0÷Ùë?ý#F§ÑX,™Vž"€Ã8`L¦MS o2ƒ¢44£qÒ™{cÓXéL“9W»cýn%¾P'%Éd8–ø£¥E"§ì£zgIßÔ[ú.؆+SU·^¨¡FÇ $PÿuÎ é'«ß9r6« ™X(Z¹råÝ/¿{–R>y±ÀÏJ>Ýq3:š‡ØÑ ÞR\"*‰å˜8¼§àÖ¦×â¼e"ïiÉa½óÎÔU~ ‚ü‡Áþg­s…SÁÚE©LÆä¹qƒOüàwþ3'ü7ý´Xм{åH8¦ÉtnN–ÈõVØû “†çKˆ›z2bp<0¹>×Ù¥ÈaU•L(¥Œ¢(èäàààäÒóâµa¶Þ‡Œ E"&—‰’ ñü5‘«ù»P]7òtÎô´Çø¨®ù:fº»QS+ò†âªÛÜ]±µÜ¨6ŒÜÁ—<—»#ÁÕ9Ã×ørI©:muŠXºH$Par"õyûŠâžoª¿ˆš."Whº4‚|`†`tÉ߉HÞ+È× Zø®·~íašQý%UŒÏÿjY ±`N’ÊT©j.6+U•<¯ð rPc ò/ ŽŠ‚¤@SÛ|p‹è<`’0€„¨^Â3÷•¦.Sc‰r‰H.Â4[7ß¹ÝÃÕÄQ ÛßßÏ> ¨“ß¾ªN>ŸMc\<ˆ ÃöÆßþ~âøÉKW€Cdb f± dž'É–®ã ùdY³å@“îH‡µ  -hª€‚XØPY2Cpäõ‡ZÅMzpHiÀ•—?'„ù-Ú‚€¾¬,nÒîsŸ,l¸PÚf. >÷ªZ2µhõGšõ ²`]¦–àA8h†|^_ŸñQîS^#ù‡=|ØÂ s/{t ™0[“%Ç 0‰Høºæ@nI4RÐfi¬<ÖbúFáÕü€-ðùO'ˆòÿ§K–Ýš ¥œ±g1t¶Ã¡a  JrÁ݈´ææl«)‹4Nß}¿i[mU»\d¾íá– Ü$êcÉB’̵ØwÚu[ôäÚ›× K7½xêã0hc„ Yƒö´#£Ê©©¶æÚª ÝœC"ì~þYm©ˆö sh 8„§È8Ìxªi¦O}ðSÀ¼,Æ™íŠPé4€“Ù:ý.í†Ô iÄÂy†‹Ó¤’m ÿé¼ù«s$PdXOß:­Ò3ƒ³OËLUÝnë¨{&çíJÓ!³ ÎôUR·LžËW$ ©L, ø›"\²zR*›ª=VÐ'%>nòå¥å’D±œP$)”*)Q½#¯òô0Þ72_VGÌ®»çÉÛ¦)5uß@Ý4ÓÃZïÙÛqL¤ pY¢Xg0LîŸ(ø¹ÿlm<3G³PyÙ1L,!p¥›û“CŽdŸ‰h«`{Ï]#÷IGß9KïyúÀºµB(ˈ”o­]ÿ¨X<¤×Äá ÔFà%aýºJ¦% å’Ù„P)8e@ !ÔÒ¼3kÚ^ñ†¯ŠoL ”û–_+”ûwTyäéz¥ö"r_Fõ]35󷿉ñd…ŒP‹p¦œ»67AkŒklŒ¯ o;ªkç ½¿cú4*ˆz©¶%¶®ƒCœNÔ‘ÿr½S{µ4¼tpŸlá¥x® ÓÖÌ:s [¼xμD¥rsLU3‚¯{‚\ø‚QfHÂ1µáxo×c÷Ô¶>ŒjxU·½žX©R-’ã‰$E¢ÌLÏè»Ó y¯ž<6ž`rþ~½ÀŸáq;mãßšüÊ¥ËPC1Fˆ¤É0ÄBÙ"E¬(„*iʺ;*‹Ê-'ƒÔÑó‘h,4W–µš@%!3Ä¡†Ê#óÑ€¥¨A_h9ž]þã {·ý ?#ûô¾|êD±O[Úd*è´í÷7WKZ‡:@¡¦Šç]=‹º’€4Õ|UÆ:à¾Z&p]»v PÇ „L>þð#£Þ›óæêï©•jq¢X+6ÿpóÛ»÷ë/?¸zëŸ71f”ÛH$2žÇØ_ò+ ·²H–¼µì¸ßX2 ëáIaeÍÆ§v˜§¯‘ @À<·èÿF¬Ù[Í…ÆFf’¶t+“IÑÚ4ÓNiö,§=§ŠÎu}[¡3(ߦ<˧W>eD_†ûA÷UÈa›¥ám?“Î@W-{̽ˎ =‹ÀÌa¦rSP„Nw‚L™ÖŸ5þ¢ö”O›g²fSp=¹¤²H[Ž™ÞÁðfŠ€Ix™@LWÿÍø5 ˆ=ƒ±¦s· ól–®“¼)%Y$’BY&–·˜¢Q½8xaKÚfHP´IH Aj ¥b©‘8ᇲø=»v›Œìõ/®ÁƒnLŽjff7¤®‡Ä’„B VÓi(ój‹|j˜o•Ÿ Ú“úÂÉ<¥<ß4rCr¬ ÂðZcËÊç N³Mæ³9ÛÊÑH¦Í¼×nʰ=+±çÚÁtYLËñ–аӸ\7úýˆ-ÇdÏ5ëvªÍJV›¯ùò³ë«„‚p¼þé5&Ÿ±ÉmòF6“›ˆ]Þ¬ÊÕ™ ¬Æ,3»ÇܬpÂ]&SÃäÒ0_@0ø º€4bÈ5ð€† Ö¤0³Ø“{ç¥f'¾"&¨„h1”#¨$fy**(«º­vŸÕ­ßц Ú(2ª³þGe ªªnc:û°Ê4 ¢³ß‚N= (2®²|§v¼/•D"!Ñk¿ÿÃÔ“ÓÈO%ÕýDÇïÄ»“|xvîÊ81ùJìjUñæ¶oÙ¶»*ëPƒqHc«cCLóPá¶Þ>¢µ<Ìÿ[zóh;~ÖdÚåkÖ¬BÑ8 §„x xÐÇV…n÷ô}6d1™1! yKÝ}‰[UÙUw+ú# ³>c¹å̆í…h”ÃÅqÂxOK@¾LGQ¤d}Âþê#5ÝÆ*¯áH·ªÄ«®èÑ”w×?mõ,r«Oz˜" T@$á)BL‚‘¯§½1 Îý€\ûã»ßÝ%!Ä"!lF¨-.ÄÁ O$,B&–À/ÀãPÅá4I–°a]ªÕj½yóæý ‡f§gzŸK,M¢•öú 7]êQ—ÏÑH…û14qæÇJSÕk„>$pÊyži$›£è°r“QÁêz:O§ÎÓh•:0BÏÈ}ž(Æœ<+áè(Ëx Í§¿þü+Èvœ²Ì„~çø ®¨÷©ìÇmÿºñO€n«BZÿw¨í¤K³‹vä63ú=LA¿—µ)í̆Íbí ;\×ehÍy¬%ßïŸgèŠè3 è?“­×çàÍ–|«N©+ÛY’ž²…ŠÆ)’#Äb0™ ¦zëŽou!uóˆÎ44ŽÖ›&µŽ1Ú(2nlÓ˜¦n´}¤Ž ÕÚ~d'ãZ;If§§9+ŸÂ0•KkOŸ™œ>©¾ð m>òyjjª¿¿ª¾ˆHB1…,ùÚtGk jlãŒcð©ÎÔ:n³Mß×냪‡ú?l²«ÌwèÆ µ³§ (EŒEc‚$Lœžž>66Æ+4?«Á³¼ÿ_}ùÈÆRJ$‘üv%x;¤5ÜVÁ“Qâö´idÄØL¿“IRTlŒP&‘nHJùaäÖÌô=ùx°æz°ÿÿÒfBÁIX-л;uãó+dl¼¥~…Ã\“…Çë9ýmŒhíãhÄå]Ü@ÚH{¤ù…ÖÞ[{"AýÁ\=áŽß >ϲ³GEÒµËs†ûÆ‹ˆëS¤Óáê žiˆh,rôE¶ÁõÁ…¢‘¥NïbŽÀäã"|9 ‡/v|Œ4.uwái[Pa”˜HŒ}ï0Òé_âì ‡µ_@L®—s*cßÈŒÚñ.rÆ@²ÄÕÏÑH«iç^Ž8{"Ú<üD#À*íw¤«¦ÆÝmû(ÂæY&W¼*x „’’¬½™Ã·†@øBÛóÂc-¬¢«W¯*•JXlÀ!p„ÅOb »÷fùŽ"£ÌR{Ôc(ò3Žt‘»¡Ò¯9ê¥9 ððÑå`^M©[ýn5ß;_[0–t¨×elÄ-_…c$!¦ÄP+‘'0BBéH„"QŽdlêžÍ…Žšª~h¤Ì§*u?u)ñÒ@#€L~Cœ(*%“‰(¥bßÔôôÌ\J¹téÒª•)\*@qˆƒÃ!‡$'$§mLÛºeÛúuH P€+|¸`JÐ?ÂÍM"!¢°°ðòåËüO©«ýjH‰‚rCee·ŽçÐñ2Ï£h„çž7€=ŽúõµŸ4”œWó@ÂxŽiÄ–c±ä‚ ³Úl]í®ÚÊ­Gm|¿`íþ‚×÷)Ö+ó_Ëߟz 8­¨zû):KeV.=¡óŒÀBàª:WíRµq42—îÆ¾¾Ó©íúæÊß ›™ A:‡ëÁñéÖšvFÉ6É[ØÝ&‹Ü¬ËÓér«ÜaÎa9Ë3±9F0›Òjͳ2àŠÅª°“‡@Ÿ'“y>YË7òisµ‡6\+XMF âÉXqt¢ÙRâDLt¥Þ4Í´Þù/õeÜÄ}Åñ•iÒ[ÚK»«Ë7J L)Iè”úD`3t°±-ËÁsÛÖ±º/ËØ€ñ!Y’-›£MšvÚšN;ÍA ÅôN;™Ò!%ÄÆ’,[ê[/¸NÍŒ;öt²ófç·ûÓè÷~oß{ßÏï¤yˆuŽ7Ø'4î‡ZècXã¹Çšg¸3V€Ïµö:û°Þ9¢uŒë\czÓX½íæs Ae&C=‰þöÉ_æ¬/Ó=ïoÑ(H WËW¯^ˆ ¸Î³JLîÈÝ0Ⱥ±MhLŸ‚ÿls¤ÞfÏþCïü;k‹XܱS³úß`ÕÚ»F›† m™i -¡¥É8†a7nÜàWŸqà¸fšóƒ¾ùÚNèГ¡ilÛ´1¬ë˜Ð»ïé QÖ ae]cö…¦‘ªS™¸P@Ñ´$MŽÓk!HßÉ'qN<¡/þšÀ/ÊŇšç(«Õj¾o§S«òMË›."­þå—Ïe¤Å·´½{6*àDù¿ZÛ¥%ž­‘s×ö.ëøÁJG×Êvߢ–ïÏ í¤³ië[ÑâYz·t\ž/JYÑ:ð\ó%¤Ù‡tzŸ¯R£hv*F 7K–¸. Þ+ËÏ÷%,èä5¤@ŒÒ)D!#ä²Ü•õúg›}‹=Ëšý+Zz–´œô!û‘ÎiéE:úQž½8Àí«­Ù…þiVáÈäys;Rz<ƒ~… Å×4¶d¥ÿîý ÷E'qNTÿ…èSO,3pçßÇß ;RGá"†KI #$AMŠ@aÖ–5 å¾¹ªÈbY@ÿ†·±Îg)8P,§ER‚¢ §¦ZõÎÛßÿ胵š-›_쉉 d^Lˆ2è×—«; ݺò[í7ðx£ê5Tú´B󥞕=ššn¬uÌc1˜\DQ²{/ô¯øÄÄ›ï4è$F“d$‘kE¹¯bWÙ³l`°là·Êß«ú¿•wæìúü2QÖ&œ3XJ*™”A­i– S2Q(JKÿú±¢t ³«QLBT_ÐVôzO«CF@¯ŠÞYi¤,`TuÕ^}OSÞ§ûޝAí5ýdððM#Âøô“£>ëžSµAýa˜Eé1(}FeÀPåÈi´« é5Acy@« êùÀ”=©@²`¦À*º5ÀH5Ý N#.E³­Ð ªj+°€òÂAgí…-æo»šö´Â¬9ßb.2Û÷Øë_;]´½àÕÜí/¦®O#¤bT$æR(‘ƒ@0BBˆIi1p#.@7çn¬ÙY¥Ý«5ï6YóìÍÅ-¶|—¥Èn.^pJ‡­ »!CS±ñÞ/ïB=ŽqÂUߣøxŽc“ax‘¸›è:Ù½Ðþpž¾ƒ9v;Á+ˆ*ŒÍ ›!ßè,̳9ò-€O¦»UÑ䆰³%'^–n I¨ )’aPÅ$“ -ÍLAUÛ¶Ÿ6\X×¼ ŸÆ1npŒhíG¿±UD bœåÚΩØ$ó±ècÕ›‘¼™¯&ü›hlrú´ áæºÝX"Òßß·†Ê‚”¡Ñäýësn×kâ–³O™FŒsö jœu}¦1E`pÚ~®p/”<ô *JŠÃ‰h„û´17Ÿ¢Íà\4›šF¦tá6;‡mÄã“”å)$ yžÆÈ0š¾w\?Ô` â@HëOøñ|Å?ª·<Ôš¢:×ÃǤ¶uLï¾krMÕ;·lxI§ÒJ¬to /"ñ©yƒÿË5ÃT| ¥§§Ó@^Á ò´/m/^ÞÙ³â\iíA¼œ¸ÏF`*€tô Ý àþeçýÇ~Nå—¹ú—3t†Ž ÒXÜÖ;_4‚\q áíG.…ž±:’whNÒ«ö+Ÿq·¬¬:&”¬CŤ4E@IÄ”˜â«I‘\˜µc‰ÁŽtõ.i !í!¤ÍÈ´ï[Ôv iïãvtÖ@Â!JkpqK{ LÕxîb€di¡‚ÄRqM¥Ä(fäÈ~sóT$öð9Ä}<æQ„{Ž'ÞùÞÛ¹9ëi”’´ £ óÃE©ô‹»¾^R_©j׿é7ÏU•€*ƒFe¯¹º¥É–Ð#bŽ­‹†#°(ë †Öde‹0òG…ÀC/I/l­vŸV{9©ôê*}úê$ò§˜¤¶×8_4rü¦O4¢ö˜ÄjZˆ¿®(å´cd4gm:ÑŒBKÂÒ kôÇ?=ÑÿÁÑkƒÊ+wÊ/ß©¸2X}嶪ÿWÊàí×ë®Þªí}ï€Õ·íÀQñ†W¾,”ËPFN‰ÐK’$ ³¥Ù¹˜A3Iz5ƒªÚt%U[ãתz`¬›•š‚ÆÊ.M§¡¦W_Ö£­èf;~<†<-oã‰)Ó[Æê€æp·®Úk®ô²Ê€ BWíÑð™kÛ4µ]úÚ€¥ªS§îµUujT=ð.°e]õªéOU=úê îU~¶Â3+Íóm®=M Ž–<h"¨¡%SIÇ.KS‘ÓoÐ)´u…Çw­Ëû•›ŽeK’ii #@–Ô’ŠCBÆH€C …€I(œ”‹¥0†¤ÊL’o—l=²óˆcŸË”gvîv;Š›, ,ý`–“¹Èb/rÁÖ ùúköP§ÑØŒâLCÉDâÖ»·š*› E¦…ö â Âc O&à›£Àl+²ž±…S±ÓZì²æ[í»,Ú"mÍ«ªµ)ÙY¢t)‰c8Š­ËÎÙµs§‡Be²p²ußþ¨ñì0ëÕÚçFlÃFûˆÆö£#'å*@19)Þºi×+¦â™äÉa6ño(¿„G^Y¢Ü\<†85>éð{$ÃÀ€gbEF·:ó}£sXk ÝC:Ç\ý34²ÎaÖöHk‹ÏÿºÑº‘ áHÌFáøÏö^||S>MLÆž¢ƒÓ‡yÿïëIÃ>u¤NŽSà¸ò{ÕWÝ¥‡E`õq¶‰§HæÑ¢ûç¦û{Œu?8c½ßè1¶º¿•g1™ˆøøOæˆ:y e}á®H$÷‰‰Ç¬{ýúuÇSE©)ÿä¾Îƒ¢<ï8€¿Ê£Ik–=Þcß÷Ý 55Ö«IFQ¨/DX`Axpì.{°'×Â.ì{°\»€&6flÒNÒFLMcKJÂØÖfÆ?’V‘åØþ^V¤3f†)þÑî¼³ó¾Ï¼ûîó>ïû<ßÏÏÃÉO¤§Ã[×´ vˆÝ+³ÕÈ|›T^á]Pëžow!• áRµMæ2¤Þîxoa•±6#Xuûâ*çœiÄîeÌ`óÁ¿D8¼K䆅ÉG—&§ÀE66q¨WA\Ë94ºj{tNÁ’ó1»¶c¸@EGmO@jëÃë:g'ÒÔiír„×´EÔ¶†×´„Ygî†Âá¢0íè©wH"ê¼/˜ÝQyù°P@zBM‹qɪØkï\…{20ä'S54`?ðàáÛ¾.ˆKXÕa‘ÎâD‘ËèŸ%îLמ:ã1œhÕ§yKµÌ:å!Ú2šä²&U\ÞAÅ“$dú–Í[Ÿôæ]hÂghh(35J]à7Ta$ÎW‹ãRrì%Þ²,§2ÃU’íeðÁÕpq®4’é.Îu*2\ŠÓn=æÒ& “÷ì ŽN$'ý§1aûÓ,S{AÇï²»>—vüéxûŸû¾Ìð}‘éëÍîüLÖy3½ó;©¾Ûé]·sºûO¶Ý’Õ”n~wkRÖt£(3—ùìÊr+¤MsÝÊl·VÖ¬Âe7–6|äÿjìë¿Þ½ñ×[—oþÚõÁ¥ªKîóõºB—ñ¤£4»AðÈhSÁd{T0ÎÙ`?0Œ›iÉôÌz=cƒx½9ÁX1…eñºòýeûUÊ䢣›n$Ö‹ØBŸ†‹Æð9BT(Æ…"BHb|f#˜ Ãx˜À!IS8ß°- k [ð*öÊ¡‡J“Ô†d³~¯Q»û™G¿.^ÃÜu‚‰ñU¼Fy@>rgˆËL¼‡ÓÁ‘`ïµ^ë)«z¿Z¯1&˜ŸyxI&F}ñ̳€ýС1Q[¯ÕÄéôI•æ‹.Ù¤IT«÷)_[õº0J"ä‰y\åÂÂ{#n÷ç}_ht1-qHÊ»œqr¬´âžR?‡S•ß/5<(5SR¾{õj…¯ ð|?øÕûãIž$È”´ßm™„†´ ÇÆÇóÏâÉÆh±˜ä²€"½4Ãr󤾿ŸÅÚo†‘Ró¬»ZbPe£JÓp±éžª¦<þ@,Á¥pRˆ’Gß„Bald4´Ø&ŸšÛ¡’0dªPça¹žžœ N¼uæ¬8“°˜B†±/îxcPYŠÿ–†EŠp*½‚T[êýˆ£5ÆXÉÚ¶C ÐÑ¥qt#¶Žyฅú¶p{ǼÚ¤Ò C¤œÓ2ÏÖDaÚë[g@âAjH]û|KCX–”Âh åBêñ0ŒâG».f O§'gJ†ññàã"ßí~gÅàl¶€"Q‚‹Qè†;Žhóó]Zi£2ÝÉDU¦KžÑX4ë w+ ×òjÁæ— šÏç ±”ÐëõS$øxö=êÌTðæõO·mØÂ欤ÅB ç²X$¾ôÚº4uÞ·ö„GíQf¸‹ —O4ËçJ#RWQN“ü˜³$ßUF¯ d†­[¹¦·ç§ qÙ{\Û–ÝÑ›æûCª¿ï˜¿/³ó¶¬ó/2–¯7ËwKÖýÇ4¿ÔÿeޝÿdG^[߉ö>™¯/Û×'äZÞÙ¾û0MPK‰ÓË0!\yÝÎ-ç\†9Ù¬Ìr=õ¾d®¢ŒÆ 'ÚTR§"·AuëÞfý @ 8 À@N½ß"u2&iÖÀ@嶨O7ë¯|ö›ÉµÀécÌ/¦Æ‚S#Á‰Ûw;?¾ªë´¦Õž—¶–æ¶•IåMšsNÝ)›ò¬GŸÙüS?kö›T{Õ€ ˆaŽ Í7ÍêDí¡¸ÔÕÔZ *{lž"P^´€æalçñE´hÓ†Miii‹åêÕ«===¿¿ñÉë==_‡ÍÕäL=rtíê5\6'¹ð ØüUÜ—2~ž¡LP‚F,IÖgþ¦½ZS¢R4bJÒ+â‹®Õ½¼ùjøFW)ËT¼W®K(SïRkã´†„§ŽÏj6 |3I‚‡bÐî-S'êMI¦=æò]&S¼®$¡(e[Ê l%Å¡h\¥ O ¥ZÍÄÔ4L×Êš*à4ÔS$‰ýVvÒð¾Ú8Z2gV› µ5UcÅ•öCÇI>›fs KLØZǘ¥læ3õý( •Z¡a–—i0zâòtáE Å%k5•˜Ô¦•Œ€™ÑÂÊ¿ÉË7â<Aˆ) C¸lM0íÆ&&fÖ¸JíÑÑÑÇ}f¬ õÈа¬è `9JƒÃci2eÕšoô–@±Úááû‡ÿýö­¼@2Z¢»¯ÒNjª¾–—'n؃²ø(”¹hRü>èa(DþŸ4Ò` øî+488¸iíú%¬¥"‚µäâ×ãFçóÖnÄÚ1kX=ó,íˆË‹Øë_Ô;{gdƒ{Ñæ±QB½rQÊá£e¾µЂ4y ÖçJ#5n¤¦©ó!¶.¤ÖÏìÔ1_Páø‘â‚$[ÆŠb<ŠÔ[®<§·…×vG:†rX°‚ÿødÒÐ…X»ÀQ 0€ 6x0ü°ÊZ€Rj¢@;p…Q ܯ­vÙÛžËÉ£$빘`F ¹K„´àT~ÁøØÃàô÷Àt°­¹EôoîË=¨©;‹ã×U[uk»> ûÌMAD«XºµÕºív}ì(ò«¶ÛZyä%‚BòIAQ!I€|­kÝq×ÙvZ·»Õ–—Öºkkw«ˆ²ç’Jeg˜ú›3w’ß½ó»çwîùïç4ašDiŒXD§ì—KÊó@A†ÒÜYV\™'+?ã·Ê‹«••ZIÁ¾¹<. / a¿¶rÕàð Ïç ü¯^f€‘ÌÀƒ{ŒZÊQ|MÅÂæ £ÃÖ§nÊ9ªÝí4$W(¤5jÚ ¤ñU*y¥þù•Ñ<’À0ŒÇ%’’â¤PPŒÓol•%»þ‘|öð†¤¡Yìi–¸›%®&y ƒÀ$© -bÏe¹÷óLoãnOsf]³¼¶K©oÞîmÏ<×!q^Û«£W'…pJpY¿‰Z¾LlÙ¿³R—å5%—Èé?ž7¦«Žý™<–Um¬¹ôAo`$nþ@çà}¦Ö õ 3Ý<£”8óR\°/…Ì•Ÿ^®ýKÓ%x,Ð; ×>¨ÑƒýC¡á!ÿHÿxóþ×¥rÂ{r2º3_üùVoçû__¾Óf8sDV©™lÑ'M›ÌŒdÇYŒqó–EBÞ–eÛ(’Ç,Bñy8òýf8Æ{uÙK&£ùüìºsw´ŒÚŽü'lˆ)ìÿ¾ýmÙ¡Ãl|%D¹ÜP!ÆÞ¿ß²¹À°nÒÕßkÆõg¤?ÁlNÔë·i/» Þ¢1n5k×ëìñEö¸BK¬åà[EùqªÉö'ˆ`àXLK°ëÖ›mñ¶‚D“dEòª°´ˆC°gËf-[¶ôã?9«LÆèLz% p:¹%{ºU ‘¾ ’B°»ëàûfÐw~É\óJ!É#84A h~ûµ6_o_FûY¨$O¶6£Ueh¨À{gvÊÅœ„C„a±Ñ1-м.Õo.éW‚ç¶G*+ÀÉøi¤ Û`ï3¼«Ð÷ꋆ”E4%æøŠO¡(.ˆˆ_Ôz­cˆÑ8¨½ƒcéàøOúúawz®]½†ƒq(Š ù$‡•µ¤]mý>ßö(Oø´'QdiäªVó+-= ýý|{aì&”*à þ %W>»<ª#ýAÐú© ȘàW<&[øqîÜ™0ZH )1ŸEгv+2çÓöŠqÓˆã4âh@²Õ¡¿I$W¬}&aÛs*ýÏÍö¹I›HZˆsyóß•>}¤9R5¥´ 9Ò0Q42£¸ 9T ?”Õ#EµÓÊN2\Tî©È'ÉHÅynk"r°)®›q¤)k˜·v3MFΓg#%5È!R]3¨ã`RÉôòúi¥uSÕ!åõÈ1†=¦® DùŸ¬y h­Ü5½¸)¬ax&OË,ÂQ,áI.•}×u7X«!Îí­mKDÑ(!äÓ,‚M,îÐeæ8ŒUIy.ȓ̩‘:5;ÝÚ].­Ä¡¯*ÉÜêô õú´71¦‹¢ðÃ÷ïÝ7Ä ?3‚,:šþ‘ÿÃÃýƒÌüGýð•å/3žS4Ç¡*r(n̺2ë¾½.SÚq%`ÒDÑÈ7lä[R©ûuâ>âñùa8Í&qO âPüð˜=®‹ÛO^Ý~ú¦¬¶U^weW}s¦·%£®5ÝsmWýu‰§#¹æjvýU¹§)¥®ñ=OcòÉkâSí²×eÞvñÉ–Þ&ñﯧ4´¥9?}CªÆÂ"DĈ<—‡ÇlX•íЃ‚K«Õ) ࢱüL¯ÑÀÆ¥šâ³Õ÷2DjÿöŸç[>Æ zý9Ç ²J¥Ô¥JuÁ‚J¹[›]m¾Úù/¸ègÄä³o:nt}õ0Ð÷}À‡û ¿ñuæThån}z™êbó'€(þ€¿'Ðkÿƒ#ËmœlÑÅé­I6ÓF‰eKANìž1#Y Ebs—âàK£¢ûU·ou‚³w´hŒÀÈ5äÉbüÑÛÛÛÚÖ¼xiNq „ò^ û•:Q r<Ùê_o1l0˜’¬†øØ5ÑbHÐéÞÔ™7ÙÍm– v[,C#pKŸ¨Ó'i&ÛŸà–IÀ‚(3ykœÉ`ÈÞ³zɺp®Ž*Ä0tÎeÑ$–.ßïêbRgEàZ\\(€Nç³ÑÐÊ·wôhí]³oâÔð®ÁP>PÙî«m½š"ão7ð±P!ô.K |ùþ»‘ jGPÖá‹ç!ɳì%ÙØBRȃ!Àc##¯ª¬ÃÆân•ùŽÒУaP¤Oak·ÒÕ¶½¡u‡·%ÍÛ ·RO|.oh‘{¿ü³Mrîvjí§ñ™‚'ŠÀx8Ê ã¾'•UfyM©Ž\`¿±üü÷åÅ}ð­ÏјŒàîöv÷îö@+hµ¦Ó45Èû¢m4*ï·Š Tî}·÷¾ãQäy܃7­McÇiœ´5)4 †Z£iši4ŠD9¸ãàú]L;8à ü“¿Y~Ü¿ýíw¿ûý|~Gm§AÞ±ëoÝû^¿Ç3â³¼ïªùCh ø†Çï·þÎ^à8eÙY!8‰­¢°™ú×ÄœŸž˜¸q÷V©C_l“œthš>èýÚ3F>îuû=u—Ú³ÚÕоôÓ295æ÷–·è2š$‹m#p û}žYý  ÈŒ®À`ÖI|þ¯|Ä!q&;r(’žõ“ *M½Øô·¦úÔ~£FlÒ%ÍÉÆêÕò8…Nl¦ô–´SŠE—@K‚6‰Òе‹½*Q ëq@E «ã5ÒÔ²ôˆ·› Nbt ‚‚"IÑvïüèÏú§!¸Ó³62Ec胋9çò¹»èµW«­·Ä°P4‘Rn‰q\]}W¦õ*,×NJ¢ ÅpÃÃD¡w>¿ O=<å;üßÒ’gãáááØØ½<œÛ ç3©QQCjÓ„ÌqYiéE¬µhô>äÀ)’åõ0•ngÅ™nZ9êºV×÷ÐBÒØ‰À©ºv0ZQÎt®ji[Ò|nI•ã{µpûíkµzÖö]Û¸—ÄPv̶èÁþH{™L &À¹2”—Y^ð®Ãp¤Eþ‹6åáViF›<Ë.Ío‘wj ª,ÐmÞôÏh)/sh±$T®p\ÈeqàùNú½ ¨lk$6pÄí¦«ßLáóù¼ÓÓ¾¾¾wÄìæ²yBx7q.І0Eì-q»2 ¥ e#9IŽMò¶KžçÒæž.¦#ÂáÀåØ˜ BÈÛÀÆ2«zrzoô~žïú´´çFÖÙ¡ŒžkÇÎíÈìÌùõ`~×`Aç`ö¹› +¹Ý׋:KàØs-÷lVÏÕ‚®›ù]×sºŠÎÝÌv ”vVÖuuëáŠ(Wˆ,’µqot‰]ÖWØ¡Él–ιÎ øÒ{ïóA|<ÀˆÉK×þ”eWjÞktû½ðå¬ëo¿/q*ó츩âV9ØÈ §‘vºM^ýâ¨MrØU–Õ¡,rh;._ôLx¡Lºý“¿½ñÇŸ·ÊJ\ú»w|S)®WfÍmG e#ÀG°c¢Þ ÖeìΈbm&PbÁILN¾uûö$ƒßërÃmOúûŸ¢1àÕ3}FH@bŸRéÛxòÓi§TÊ * 9‚ nÒÖxù~ébÓߘ@Ó,²$ŠJ·ê“Múx½æ YlU‹õªJ™¬Q'SZøf²É˜`6'Z{= "-1í7ƒŠßu"‚I²@/˜wƒ@ıè¨m•ºZp!¸ |Ó4.Ç=^_@Œpx$“äóجæÊU£*ÓÚˆWaUWV=¤,cà9ŠÊ¼W_GI؈€ä‹“ShvÏg€³Î`ÇSÙ·oß&ŠrP‚Àø¼„ïÇô—S "Þ êµyDn|¬¦[¾‘™Iô " Tó]ç…É#7»5•÷ËÔ>¹õkµq˜Òû+ô¨ê¦CG#qðPB( á¯ÆÑø<ðMû¿üâŸÒßd³Ð@¹æsxL.çøž„¯”U¥Å§0ŒWh'••¤–ÿ·»UÖƒñá» ·®N™’¢¡ÁäsA†††¡?p|üïl@Mzû®\ÙÈñ™ ¶Â—øä¶ƒbÄ~a½Éµâ ðºsiu×ÊæN¤Ê†ÔõÎe«­]/< ç“DkDêº?=†ó˜[^Y]”·6”Éd­};it¬°Ú–Õ:VVë;‘Æ6¤Áµ¼¾kEUR ¬Ÿsþùö¥¿:¿¢ñÜšªæŽ¾ôòv“³(Ë_/Ä‚¡zo߃T7#µ]/˜›Ð¨×DEãúBÿ°ˆ¼FùûÿöÎì¸GÀEa’E·‘D½)ɤŽWIœÞBFb(ƒÏ#ø€XñÏ”kš‰3í9Õ/pêökRÇ{£fLãF¼Yš~J-ÖjRuêd%6hSp¤öÓž MWÉ“¤ú4£6ŤM±˜R«4ñ4»Ûª×$Õ€ùhÅZmºF‘*£Ò(CšQ§¡’ÍÆd«!ÎhH ¨4eÆÞ£1›£ÿË}™7q_q|m tÒ–bÀ’%­V+i-ÛØÂ¸¡4BÊ$æòmŒsQc|a›3`Ë’V»ÒJZi%ùÆø’|Û@“iS aJziþh§¡-dhR˜`l°…d˶dõ­ÝaÚfœÄ ™Ìä7¿Ñ^Úß¾ßû½ßû~ª”â(¿§®ÀyÅ?tà wxä¡Ã?ß Î w竤ŠeQ¬BJ¦¦Ý7;CUÌ„Æ4B›LìiS³A ç%íw˜9«¤Woñ©Í~- #ŒÐµïk©Õ1ßOĉ ”;áìÔhaˆ_éà4ˆŽ§k>p‡ï ¥¦< 9SIexlÌÒ7~¶ñ££Ú0éÁh¤uÎêlâF«ÌÃzûƒÓO×Ý×ð$®b³—4!ŒT[Úš)m¯Úv×` WLš^Ë_§Š•Š$R±”ÊÁ]¹?éúë<9Áì© >^áðÀ›êÃGå2£q2EľEŠ‹;v}¦6zŽ{:Ö«·ù)û¨ÞîÓÙütÍ=½õŽT$µ%Pm½mæn³Æ[‡ôŽÌWr¸æÈs[Ï”ùLÏi-A-3`± ™øWî¹Ê2iªõi,^;N9üj›_ÃÒ5#”c²B×ý$wñˆ&£„B%bF'7÷ÌýmhPùj(¨©TC‰ªÄ±BùBUiEêZ–>¤¶q÷F²îù-gWÇl*Œ4öÚ̵èJ» E²Ì­\4’ï!sì‚üA`ì5†2>ÌÊïû»?ÝT3$<£åÂä”gviJJ´Å­di'ÍKg‡®¼ÛXØw´%mºâfMy½¿ËXp²jVSÛéÒV=hèÞNú@³rÝ*CU ¦R‰ ­Þ¼k_ßÕ½ý):õ§Âþ¿–õþíhä!Ì\ö^ y6¯4N.W‰„b¡8¥"ow«ú`3¿Å̾SI‹¶¼Cÿzkea¾¬—ÙӤѻ¹ðët*»òkíø%õÖ µÛzóΧüÝPøSÿPQ3UáÖvë ÚÔ@# g;ü£Ðäxàê­kî÷N7\袻kÛß{óŽw( Y<ò‡ƒ5ow–µSå­†ÿpp:Ç2t ^ßë®þºi„ͰY39ÓóÎ5;äÑR•J! 6¬]ÿEþ'¾¬€’þ7“'ù×`ž¥Ž«D²¤hå˳¹Ζm³fÛÍVS:kÉ´Y2,æt³9“qäÙMi&6å29ø›óE‡>UÿcÆWíûNŽËµ1Y n`ÒM¶t{MV=œXv°†\æXVeꪴĘåË1.Ba7¸B$Œy)ïÅ/_áámò‹¶)xòÒ¥K°¾*¥ D¯ Þ)?ì£í·iÃˆÑ 9FÛP¶!­T”n®ê?LY@7}¤ÈaTk÷UÛ?1pô¶­Q¨0A©Œ O%®¸?2NA˜N‚Vð$öÃáöÍ[Y[Sq±X& 8!j6oÿ'ÉNœ¾cÌ}­å[7W{µ¦0Yë}Ã8ÄØ‡ulØ\Wg¼ÇXƒU¬æHZznXc$»£3OÐÎÊ䧸úº³E‡7¨Tb¹'” ¡DŒ¢AlKÙââœuþ]ý>}[šB"‡zD ‹T¸@)‘ —¼º"ù7eÕ€">S—¶•{á#Õà€ ðϨÆþˆ—ÈÁIþwjj<<9ž¼æåžL„„CåÍ ‘º´‡:Ôaêÿã¹ ˆóè$¸rl òÊD(4žACØgS“7|··˜Š=äA·i JÌi¹zóú¾6 èî릞rlšLí$Éq¸JŠK ~ðþ3K?::žfŒÿ„Áì äÿpebb‚d¦ON¼{îíD¥‚ˆ¯”ÊŸ{êiWf­m Ë¥Û­™è¶4.á¦9ÇbLcÙ—jåÒ,ö,ÖF29Æo3¾Z§3)à`.Ãá̬³§×XÓ$L6©Ù¡ÎZ›•ˆ­Ä%±*,.S©–a8Š­fÝ;çÎóA5Á‡Vø Á/41Ñ–“»S#Ç•ñ¨x {™q€„øhnXg‡K8÷éç&ýÓ4Â$2HÖŒe×ß+éUIÿ&¿Ìc£¸¯8>ÆFiÓþ‘4>vvî=XclÈ JB „Ó`"‘Ëé“’¶@Øûï}ø^ß7¾0IÚ?ª6M¨ªF4I‰(m’DIq‰ØÆÞ]»ëÝí›Ý*T2ŠUªvô4ši~¿÷{¿ß{ßÏ“ÈP¡\H“(µ{K^àK_ÄÇ{æ[WÞÝ.˜#ËHhUp–cÉg·¼tCaŽj‚*ÛŒÑ9Yéüréþܱ:Æ\ÈZ=ªÔû4fXݨÙ}Ë`]PÕú•öi•Ù«æ&M–›:ýœ«Á÷SÓd¥Ã«0Á¤>]Õ¥Soäg®fÑTZÌ"„”°`(A4”E†—{zN‰gÐ5$jßµç–ÊT;¼œ P˜ n–s{56°YÓ¯²N3JÓ¸ÞìÕXƒJ§OçÊ“­eñT9™*OÕÉÄr1NìX•ùÞÕ´¦jVW=®²F5î¨Ê1©7OpÖ»F÷8ì‘©ê®Î ;åÕšýz딺rBWwnóöt1-Ũt”É^•õáÇW¢ß øŸ¼"(:|Ý .,Üøëõ•¬LŒAdxS“ó" HC?Ò8À[mw‚gqiìJ¬ú^SßödÉb:]ŠeŠ“ÉÈ4’ä}/'4÷ 5I\š›O>·-P¡©ñ€ÊǬ¾æZþàh„°¹?±þ<âîN¨éOj¼˜Ðø&Ò0Œ´½™àyq4¤dm¤YZD¤à)Ø#û SΨ›7 N 赪‘6øñ<â^V7”XןÐk^ê^VߟT3°è¼µç»."õžïWê1ñ”‘RF§‚ ¿V¯+mÓ‚oW€ôw«œì2elÌb0TJ‰€FFG¾ Ý艹™™‰Žè¥wßÛ½s0‰DHŠQ"]" ¨”Üv|ß«µºSmæ’Nmq‡&~¾:Ñ£«èÖ•·+ïA#¥mjÐbøô÷GÊ2”2(T=Š¡È WÑðg@#e®é»V~á/÷M#Åý×âñ~‰ $D*JÒtÖ‹YeÊònsQ»¾¼=F#ÝúCmo”ôË{¸SMú·®¼ïA_Až±ìà³$âÁ"ŽÎó­"ÄÈþó ‘²MQ‡²¢U÷›ëñ’ é4YÄÚÈ@^ƒóh„'<šê¾ü6ÌXÔ¦úI§ {$…_ÞÿìJY;¨ÿi±îqéó¸Ší§d©+‚Fqtëö­ÿ†ñgøXrC²»¾þ1N#Á8ÃÀÇP(C*4ÌBtnvîÓògž\µaMÆS`ð°>}öuÛ 7=³[¡Ë×Y L–¼JÓNÎuÀiÚ»¨ÿÿmf=`šü¨Þ[oßá2í°˜ò-†îÈs…kÉl©PLNáAR©Ø3éëœvÇôÝ)ȬHìt@Ðî"± ÍçFFFV?žIb$Ã02 Û–¾zBa›TX|Zç”Êâ78}œsLe˜2Z—ªþÀ! “FǔξÀUÏŸµ4î9®fàXyfJ²PB (V,”lÍûb4™÷Fƒ_y'ÕJ•ŒdaEŒ` ‚Å„æ-/ýsŒUÞÓF¿Á6ÁÙaÀY¥c©þÌií³z[èè\åß9ûë›^7 ²Ö =9ÆÕÌpæQ­f¶Òæ×Ø}7 Ê\¥{L¡ŸViŠ8ôg„³Oj¬ ‘q£y±Ü9¬s<¹Y‘ÒúœœÖÆí}Z‚a‡6oy21 4ÀOÀâØ©ã¬sVïW›'Y xɯuÁÀ‚ý˜ڬ°øžŠ5iß}”Žá"L&•§gfòÙæÆÜÿ«F pX ³|î Áf0¤T) ¥%8‰£Dü–‡4Ö¨ú¾ˆfߪº¶û—«ÂQÞ Hk'”i¤ígèL“(ˆþ`×j“ñ´ ¢^R “`I!IÖa9¨Ùõ­¶žÕu}«ÝHÝ Òz!²±o¥4‚€½¼ZÎ#KXÕÜÙØ-Øú„˜’‰ÄFK¿}BÑúÄÓZS®V@Ü”•&|çXN\©ëŽªé¸¯µ©kGª;#ë {}Hk?ÒÔµÜsrõ#ÞþûÝ>Þ?ÞWgƒx:LWÊ/&&úÀ‹O5j zª²;ؼ®•¡´G¹Bb~»{ôÙL"ü‹ýeåËGè³MîÇRþ¼~ãFqq1Ts)F*H )‘¼7å˜6ÿœ×¬òrÊ.NÙËeuª³»ØåúÉ;ħ…òß® œê0%¥>uІ=)yÁÜv|ðϹúñÀÕœþk¹﯈F ±ôQ†a8Jn?²;¯£RÙÊ *»•œô²ùÝ8¡Ìg½róÚBx<UöíëWO·s½úü.“²‘=ã5yÑÿÚ{—Â<9xE¼wã…톯:¯«êL3743 #>57óÁø'E &U“~^ØÂ·S^³²ž-èàr:*szøWïøy;ÔnxEÁpø•wßT:5ÿnØžrŸ3íNÜ {1Š$Ä"ôÝw~þÌ­P÷î^|ŽÒeÈBh‰üuÐxçíßœ+:»A.—JhØ‘Êhô‹¤¤?BŠó›SÉ)T&Ñ YøA˜£rZF ¥»SÏ.ãÒÍÖtמ_³;YM6Cs"5k›ü1Z%š€ô"“É ‘2b4ó™C—ÞüŸeÃwÁö%óÃya‰‚ÿ:=/-chÅ…ü’³4 8 ×Cj– w+?Í+ pM³eîEmõh…qTo¾×ê?£q€CÆ ÎQu„µÜ©²Z+@bÔXW²3U!Á Ž‘˜ '™Dñ©â¢âéµ¢‡·É© Ù£lõ¼Æ1VaœæÓ:;Ôî93À9Gî]GÃc@c›Öײ{0<ž’%ÆÂ²¥$OágŸHûHc×8gµà[p‰Rã £k¨R?arŒj- ZO¸Ô1ÁÕ±®+g´¯g6=õlóÁ£o”ü®ÜpKgxA`ƒqÖ>¦¶Më\S¬Ã¯wŽ«-@èP>Þ=ßÑ[!¢€Ú:nt³¦Ö}ÓàI&c‘ð—JÕ•¢òxB¤ ×ÎT|¨·Sb1)R¼¶>óy¿Þ $39ý:»ŸµMWÚg8÷$kkùKAC͇æÚ’GwƉDH&‘”Jåòë·>ž¹ûºç—ÿÛÇ|xi_á‡ø?˜üÃwnmÞô=Åa(·co´§áþêN¤¹'²vÙ*ŒT÷"žV¤ciyuµ«=ê¥\Ñ3/<`1E4]Œv¸ÑýG×&o’ÄFS(.'7Sxü:œ‰Ý™W´¦º=¢íÒ8ˆ4õ#ïJi$ÊÝYs8Ôu! ] =«ë»WÕv"ªÍŒìû„,Apøâf´"Þ××èõ$“"J`2mX+”Iã¥òIl:¦¦ihußçéCjû`†eûY;áö"í>¤®÷A÷+HíùUMëÓÒÅ´œ!édF‡­?¦Ï?ÙÉåvèT^ÝJi$½8“à1šB §Û³/taªÅ½Î‡%Å|š-ƒÁà§7a‰3zë­_g>,AÑxšN`¸Å ùÃŒ}'í¥§}&e».·Cí«4Ò¥tð±çù Û3÷Áž‚Kq’ÎäZŽþðPxþ²jà/À’o¦‘jpÿP¥‡ ¤ F"¤Ò”G€…­:PÒ§?éÓ*ÛÔù>]žã^kúýØ›scþðüPhLÛãÊn.ÏÙø|{©ªß=Ï®+«èsMÍO€@ûèöÍÂv#ü0ËÇ•ùlS ‹ÿêíëE>³ª›Ëï©‚ÿæ´Á€Tt z.'}ꬶʆK}0Ћs!8ä{ãb¶W£êXVq+¥çA.C»+i»^†)ŸÿæfÃK•qa ã™>.;Oææff!uÌ‚}ýïÚ¡b |¸‚  ?$óO „IèÛÄÑb|E&"’“ˆ ¸€p3^,BJ‚’$NaÒǘmÙ»²¬Ï-Ûÿÿ¶V•a¬Lg?þbŠl«LÄ0˜„–EòVÇð)Û/žäW€m~fn)Ý~®ý»Ã;37úŠõ«xžÿLªÀl ¼´„¡h‚ ¸Ö;[’¶ÿý ˤÖ4z†ï]#AÖ>Î9Æù‚k›V[F8”]( Î5UaÖ9ìû=²~}²MÀaŠmˆÃ¤Q)Ù{bóÖËó-ÖÒ¹zǸÆ: ¥VTpYÛk5Úîµ?ÓzkPãúØÐðô–­()ÊHÚò²²(+uçFF. èØ˜ò=ûÿf¬¾­wŒhÌÓjÓ¬Þ9¡wÜÒ[ýÖú‰2Ëë ¨ÍS:Ó|™uQ놠&ÕÖ)-H.ì~µ#\†±ß©²iL`ÀfâÕ9'*-SÀb‡óH¥ "ŠÀƒü•üƒnWÙÿ®sjKSvÖ8r¹¸¬èä—kPTçÇ¢Òfbg¼{9·½" ´5É„P5&‚ ˜Z3 ɲ€‹±^÷~¿²°ËeYØ » .#šØV§_Ò«µ­N“±ÚÎt’±©rßuwaÙ>fœ¶SœÒ1Ó™æÝwΜÝÙó>ïyÎyžÿïp?†·î=Uèþ$Un#ÒËòò/}çÍûrý•%¨2=–kᦂbËãV Õ¦$š°Ôpò¥ÞÞUÉÏIaàl"$ :ýÚõÂKÖò(_Ï„ /ã7$"¼‰Åçoþâ§$“Åe’lepy/TT#®+HßÕ5–ž p"ðbûà³q!=—Ûü‚èÝ̽¯ƒ)b¤¢YLÛ‘Rv|KiÙ6z*¾‰±awQ’Rô Vo’cDÿyÑb ö!¤ghM÷Ð7:‡’lƒH÷ Ò7„8®¾ØíÜ ’l(«ÜÐgC}ˆ{ô[g¬É¹\JÏdr™Ìô”ãG°o¿¼™DÙdêÚE›.(>¤wdMו„ΑÇÒÕ¿b\‡q BÐoöŒ"¾uöÀúvˆ;‚íÞ…l^ ¶¦àÄ:BxÙÐܯ|^4òFõQð/™L‡A\ûÑÁ·Rø_õk[rjp|Ú3)ûh_^1¶¸¸petä•‚’FÏ Y¹ v&J¤2’¹œ"AyƒCÖì×ðûWTÕ7E#õ^I3`‰[^ë’í¯+_¢‘4œàUH{jFï5Œ|"ôß:5v¯~tu(²À,ªk¾ #¹4nÉùZ¾WÖâR×z/ \¡OYçÕû”|¯JèÑŸu¥#öK£V`§¦€â¤¯Eà5ˆ›õ~¨íŸòʾj1¶¨ÞQìÍÜÅ™l%é(åDcOÁcDãÏDÔ ¶ÿõ¯n––!q&‹ @X MÅK¸8š—Ž•ïËÖT¿5x±êç’·'=M_SÄY 3ä|Ñ[wãlaCqÉK,ŒêÊf 8ÎIeíÁv¶¿ÿ?ÇŒÿpV½Vµ—½‡—Ìáb,’„;`$ÙØžžáwzbaªr¢aŠFbT¢CTÞ–r»œ^¨µyªÀVQøÀ¥$*6Ïõ:¨¸m(ƉK¤27îåÆâ’;Í-…eµê’šfÔ–I‰>&i[”[¦ÆI¹.*ÖÏÉŒSJÓœº}Zd¼ßª?_x¨ '‡Nâ\ŒÜ•³½öàáñÆÖ'*ÇÂ9CD¢ŸPk@ÐçÔÖ‡"ÝH¹º}R¢ ©L32Íj÷3!7\}·FUzlߎœLZÊ­óʸÌüP)­*,ÎFÙwrÕΗï·jÃ*Ë´R’êfås­–¸´3,2>Vi?7ª'šG2Õ”J7­¦îhVa€ýå†/5–Ç2$*(2tMIµÀ ³rŠC‚23Å$ÅŠ6@‘ ÊXõHa˜W˜£´·Oý°¦þ ¥-(뙑Y§¥æÌ-›œÌŽwNN(åþcÉ×p¨|Bf‹É­buH›4C¸ ¬cVe™TgTÆY©nFÙþ³sŠW0.Î妳XLfêIAíüb„êTOYˆ®¶kÿ¿™B‘™Šc‘v†žAûþYÄáF%ö Ý^¤wéö!ÝžD‡Ÿ:q|Ð5Hiq0è¾­=°ÖêG4öt^Á¡e%oLgg2 Ê×[½ íCHÿà¦7ËÓèøv&Vtqøz¯"ö+ˆ}<©}ø…®±Dk ¡'@­Öã‡X°ò:ÛðZÛðšîÒ5H…€ ؼ‰½ÕRÊzÛ(Ò1€ôøþ+ EŸƒ´…E¤m%61xfzÞæ÷Õˆg|£É±éà ÊΡѓJ%´ô¬m÷&vzžAÄ6¼2(‚m÷PIH²^F¬–ÑuZ;Še§£);·µi@Zï8ænßÑÖÖ …žrÝrá@2ŸUYñx8ýs•Åæ–MÁÓk—×¹~ýzNV6ÁÄ8‹ÅÀ8LœÇÀ3˜dIáñïžüÃyePi›[b—LQ±qZªQ~¬6O¨Ì“è<@s#Òöˆ¸-*±Å Áí!¹uNÚç È³ Ó„B·ZŠX5u¨­ € ³J(þ_äæ¿ŠL…9¯¦1¸™4Çñ,:þ“º a©ù‰L—ˆ^+Ä™´Í.Ð÷‰— šºæ[TÏmKZ#É´X¤°Ä2#6L‹ôayÛg*ݹ."6~.îx=ow/ëÏ"å´F4/2=RXy´-ŒtN.w|ïl”ÜÂNý}Ý釭êPœÌ`TÙžäƒT«,SR}XjšÐÚfðp´#ð‚‚‚¿“_æÁMw_Ÿ˜&`°e?=齧˲I 6“%@Bl &4!²ñms$$øÐiݲ|é²dë´$ËV(¤Ngš™˜i(-“ é$é1H9„Á¶eõ÷l ´SÈ8CòGº³ófßξßÛýíoßÏF"‘÷ýÑ¡òÿX†Ç×L|•ýdf^Š¡Ù€@\¨Ã‡aÔJèðÎl8<ÑOº …x’F’̤ïÆy¹D ÉÊ^8gëös'ò™­îœ[°-‹ÍI!ç%¿¶!Î`GæÞøî@r«•æ°ÓæE–²õ#KÙzÍg"S€FšFq úfÉtiÙ ÖÐlk=Èž!Ö³˳(? OÍΊS¨“ºüÈäENÿÜ—_2©ì4jæ¦BÔbÆH²öÅY<ÈìI6÷?Ìþ À•Ní3`I&ÞxªÅoqs–­Æ‡àAòØçW—»êKýºi«¡»‰Ö2´ÔÕPé“‚8–;¥e.\Ç âsqNnt²<Þp¸¯SS©L{ùòå=ÅÅBŸËb- 9ìôt‚Cš°rEµoÔ´×í÷(A¦E~Y‰Ÿ&¨j§¤Ö-+Ÿœ| JZ┈䵉+“…åýtgMèbYÿ ‘âþ‹Õ}g§K#¥á‹U¡³ÁEÁ?Õ~ðÙ.÷é°ø#y|6ádyȧ¹¥µÎé:_^•Zë›ü¦_ž>~ö_|½æ>}´Ú#© ¨Þÿô7CÑapË`,Úö+_‰­Öø0;{íÒÏŸ‚« Œoè1V:%ÕΆéΧÊ%!&Éâ,ä A@M#ú-ê­MùË^%‚+àòqê'>øhÍý·ü=€"±ÉùÆÒ<{ÑÎO«®4™@4AúGêtcÍQYë¨ÌxK¢».U_Sh¯«ô#êö«õªRý ¢m@j¤5ÚMÆïšFn7"šÖ©fD¢‹4jÆ¥mrKãó/åâütdêI´‡h ±ù§M#GÉßÝ‹Z‰ÿ¤Úù¼gæâ|Þ’Ybdr¢®cÈæJÙSNPÙl"•ÿx~ÉþD`$[(ž†.À$/,ü¡öíþ¤6Ïì–žD )G^‹Å;zÚ-øs«ÒŒ"¾UvÙ>Ðb—rºêS jîU”{eÅκJ¿¬Ì-©è–ïЀdÈãp9$µ{ç®ØdT?vÀ¾sç΃¯÷sãÉã'^X¶Œ‡³„$E0Òyl6Ÿ`1IŒ•E½²{sµ™žá^—´Â¯,óÉö:êAÐ+z¤•n±ÈUWÖ´ÊXœtŠ"8Loñšƒ*h ¯éŸŠ@-ë»T8Sþ¤²ÿÜîà…²Ÿÿ¹Ü÷Ñv©‹C¸! É%kóöu7‰Àù@#.Åtý¿Óu¸*¨¬v+÷wkJ;ÄÜêýUU@¾ÇQgû]ðø¥S—®}õÙØ×Ê_Ø+\’*¯øavxµç.ÝŒÝ9äP•w5V¹§;`ŠM°™$ྲྀ@õhÑnjQ*¶b ––AP ¦Ü§g|2þWÌLGôÞÖC’„§LÄ>8z,•Ã#p*§Xc)Ÿ¥}ýåÏÛkn÷G»bî=1ç®h×[.ј«dÈYúí®ô–ļ¥ƒ®õÛW ØDFññÔXËeERåFUËÖÕ&µ²@ùýЈz‹^U UoTòuÍzhŠ4áïêmê’Õ%9ŒEYL¸Ùrx ÇÓù.ËŸ{þHø}¢ÿSP¾ñ0Žßp&ÆÁVôÁCý`yŠL¦.'Ož|½hÌ®džIr16 ã<"ƒÄxÆzáéÚüþµ—.Ëš#Š–[òæ›bmD¢¾.U^‘Ê"ríM…ê5©v@i¼)o8Q´~×42"3FÔWÅÊ[rCLan0ý¡N»†Ê¤°ù¯fg½¶ø>ËÀX&±îÙÜ/ë £2ð´ù/b­½ èDí;CŠ–Û M74šÇFGcDlˆ(š¯J4×$š[JãmUó_•Æ yëh£þè¾·l‹ÏË!yÿ¬3Ýkb2óï÷¾óJÞ§ÓSŸ3G´jåßÞÕ)i¤'C½-kè¡Ê×åMC}¤Þptÿ{$s>Ï Ñ‘K)•ÊØ$…ޛǞ·e|4úÛ_˜Ž±(E°ÓS9)o½™dv&tõ¡Ö>ÔFŽ0²zLîm^Zˆ­þ»Õâ3ûH,',¤5¡î A·zfuÙfæožÃϦðá¼4ráÊ'%zÔJh;šh=oê‹7ORM'È:àGµ¡3Φ•:;ƒ`uø¹Ùß‚FfGux‘£uõ´“-ޏÆCDÎOž*ß—Üõ/îë<¸‰ë øú„´¥™bl{K†`cÓ”Æ&L†&$ŒÁÆ .ãC’O°1>u[§O,[¶Në²$Й í?í4ÓJ;N[s„#ÓNJJ⟲ú­ŽtÆLÝü‘7;+i÷i÷½o¿ï÷‘6*.¯4ðQŠÅïÝãñªÎUŽa¤g1ú™k{ÝÏù_Ä4´Æ8´¶{(ÆäCŒ6¤«/ÊÜXÝk?ÈgA1Ä8FîÈȨì•ì²kÄ¥:¡Éòûêó]R¦®9Ôoä@J„F¤¥×ÉT/ÖØÏöö¥žƒK‘œÇåÎܹs#ESñ¬×0’¤y8‡5£ ‰·÷Ð;âæšR§ú´CRêQÃmŸ4_º$gœõg¼²R‹"9=…„+8l™Raþ…00R08RQÜX©F ûo ˆ‡ÿPâ¿yÖÿÉéÁ«¼¿NÍ8°£ %8ÇÏ)6KDèHd•®tü <Â~yž­±¸_+v«A†ð EÎI©URÕ«,7É.úZò-"§ä9Yåü÷m¨ó¡¥…ÑÐä9‹²ÀÖ ò®8Ä6 MÐ$‰‚F ¿FÔ¹ÚçhÄÓç”îÒ,>k36ZR œ_z:¡‘b÷äàK¹q‰iwoßÙššÆÄ1•HpÈt÷粓KÞªP_É„]ö˜uOÙE“öâYWù¼³tÖ.\p-§‘9kѬ§dºó}Ìq—Lo qlc\bñ;"eŽJŸÝ¬ÉÖjë4Ùß„FôG[YM€¶Ü6ÃA6G£ß ÏV–ìgÒ›8IIŸ‚añKMìxcû•áË‹ó 02_±Ž<}­–ži§ òëÓÙ ž_d¶‘‘‘ªó•[’S ¤âIüc£8Iâ4@¨ ;®]w<#Ý™'ºY£ž”¶ÏÊÚ'¤úIuÛhcÓŒR?)UÉšÆTúÏåúqiË#Ië×­‘I™aVÚ<*‡{hÿ´Jé?)ÚŸöúÎÄ”]‰eÓúó±S©$ÇJ€çø ñG÷dšûšÖmçLfQjo2Œ*uÐ˺ŸI礼ãsy 32ý´ZóÃZÕ¿$Í!Yû¹jFÝ¡ºñàν±¿þæÁõó^- -ï9zY^#<’õ‘ÂynÈÕjëž§‘Üv]V“ú˜r37.„™JIÜ415=77÷Å‹ >)y_Ì|8˜Â1P{± ã¢n£~pÍP¦@=±µj>/3y=•„sùœ„µ{r£q~ˆôØ×¨qH}Í*é°FY}ˆ­ér­êö~c´!&ë*“;ÖäF.9¨ôú”Éc ¬T#§X“o•Ñ¿¦nl˜aUGq\F,—«çûg«ùÔVœÇ%9 ;ß\­Ò 67|]±=C±¨.Â<‘gÙþÍ6ø‹¨îa¤÷CÀRlbý¾ Kâ¡D"—Kál4‰LËÚUb“õ7æêWZ}D.¹Ø!Ù%Åýª3I™KS¨¬Äø8¢i’Jß±“¡B¸¦D‚üE…c¥P[KkEYù?îÿ=ò‘Y†‰q‘áëÒ äãPÐãóìßývª`™€ pŠGÆáQ8Ž%lÚ·ýhCQe¢Ê,Z$ùnU¹Sû^ÞaÅ)Šâü‡ýzjêJ~mµR­ïj÷™Ü$òµÕVwuív­vÚŠ Zl€  høäSIpIÑV>›^OnJÍD¬FW½šŸiòE5‚4u! n0 ¤oæh{78d­ÁƒtxŸjoZS A…{7”T0’±w­(Óáñ0.+g“GPg1svìc'ìŽÑj‘ö¤ùWË­¾•-Þåõ.8ŸñU{?R×µ µvlï?m´>—‘³)i;²y ¾%y<\˜”DmKØHdzH_pöŠ, ÙÇ¥ºàÒtTH]ʼ®ª¬º2*Y$ä @èPR11ê[Z/%$.Ð îA30‘™âAL;°ÿ'¾Þ¾)ÈQ*g‚Ìšž]^0Jp,2í‡ÝáÀ_ÿüÕåÒR”eÐH2‘ã· 4Ê%1k+Êùq|ÂÁ—qÔnPw’‰çy*Qæ½)ñݾpí³\ßW‹Õˆ´ÿV~ïYß]YÿÀÏ.7“I"”L6I/ÌÊwUgyÔ¹]à¥Ü±HÝUŒ1ª‚NÜàx“åPÉUòN]^§VÛNe±W/gίZè:ðÓ@Y§2ÇUží*ÏëT9µ%¶EÒf‚K ƒ‡alÐÍÆLiúÇkDŸVkI±SôW2 t"Má ey‚ëׯGƒ!ÄÆù™3W²6£‰/yãÐë|‚‚Ç^ÿ±¡xÜ^äw‰Ç’gáŒMðd¸/>t;ä B¹ ‘)»dÚ)_H#Óž¢Q[FÄžnË›êº0è*òŸaë¸ÿa¿Lc⺮8þ vÒ~±00ËÛgyŒÙ¼à¸%‹kbÇiœÆÀ€mêZµ[Ç,30ˆšeÞìû0ì‹`Ì ®ª(_Ú/#KÝ[/MG.‘Ç-6˰ÌÊô<ÆE|0i‰©RútçéÞ§y÷{Ï=çÿ;¢­R·#Ï 7š³¬@#¶#vs¶ù«FS¶àÇšeQ¼ªØíÂøP Fä:üùÏ áÀ"l è¾ÛœH€DªZÈ›>ß—¨laÃgM768·§¦¡aEDx=yòäÚââqPø9 á)ÿöx)6®tUüœÁ€&ï½÷ó’’â=»Ó1>ŸB ¢RœHz.¶ê»?a­^cã£ZÝŒÆ<]oö²Î¯šFµ Ù jÛ\1Ì6‡+›®Uh¨$‚áÉp ßÍÞWœõ×XÀ’™Û]•ùa½9 q.Õ[çµöiµi¦V?_gôh,OÍ•mAg{Äê=jý¼Öúq½Ñ‘"%6ˆÃÅR>WIaxÂÎ$æÌ ™`!ìÞiâuÓ¼Ú6¥7X+,ç¡¡ÉSo]`í@J0ç, Ö:E&ËëvJÅ<¨EITL¿uð ðÇ8'ôjý?Š<ñZ lpÎN'A8ÁH…ñ$/a‹¢8$ºmâÙ¦áè¶!¤àÄp’ ¢üηG£›÷(Ò|iàdºmié_F·¸b^z%•#ÂbIÉÖogÄe¾˜’@§ ÏÒ<æyK+ÒæÚòz^Eo'1&!Ùw4^ÝÕ (ÒtmiD:û7J#ë¶ÖÁèöšrôp­e†Ü'ÚÝ`yTËhtÓHT ¬Øtv<ÓÞ‡´öÁŠ¢.!ðbs÷ÄêL>t0†‘¢´˜ÁE ßÅ ŠÂO¯Ö~v÷Óìï½Iò„2 #@QJÆœ«­.èµöhÎ÷ª.ô²½šSƒú¢!miGUå@}QÏÅÂÞúR·¡´[§èÑ*ÜZ@‘ÒÞúÂ>ÕOúTÊcy§á…7ö"Nèq?zôhÄq«4ò%®à2d²°?Rå­Ìãõz!ãýáöM)A œO¢À.„°Â1"ÿÈñ÷u 2³?ä q)2ôÂk¾™drrR­V§¤¤uÒpìAÑ€O‘>ÜE((f[c$ “_eQŽÝ~{üåÈŸÖ£Ž²‘%#·cŽ~tfäfÑØÂñ§ÇþxzâÃ’Á[Ê«·Ž9ÜRj‡LˆSRRÌÇSOìS^RUô‹»UgÝÚ— ÈXb£êÿ?×Ü,‰‘"LHc"À9CžÑ˜g¶^WµíÙ6¹S—eÔ3ñ‡‰q1À%H–%{f8˜ ®hjŽA °Ì «oU CËœ¿0h$3™\t—øÜEÁþ"O§2Ô£Xp®Gëµ@Wq` p¾§Ø×U4²ä*¾k= ÄKx³GŸ«kÈqè²u°4{vú‘ç4æ6k™sl@/°ö,‹3Çk– Í–g´ÈõÆ, r»)ÏrÛuÄÀ´ÃH–Ã!wÀÝšgSý€ÝŸ–Ióq)!¢xÄñãÇ×ÊœêÕJö‰W`å܇ÖT\g¼¯Ÿ#™{þ0,‡‡G¯¤%ï`bTŠQ ïùm‡Ë$Fñy¿x÷gáåW„Á%m4®C‘Ð…fgg¯ŽO$oK‚Ú¡ø¨X„M—‡~Úl0ÅæëÌôÖªù\ㆆ{:Ûœ˜ÁÒ<­wò¶~¤½3`ÈwÇÒ1¼¹y8ªiç@ mƒi¤u€½mpKyU\Å´Œ—þ\ûLc7ÒÜŽh(Mc’ô-ÅŠØ}oÊ$iñ’¿})P$¦µië…ù7uon‰êF:ûž~Dµ ACš™ú÷áá¥Qn°´–•ÕuÂptSË0ÒzySÇ•è–qú-®oV_Œ}u?˜åŒXBà4ÉÇ$ 5Hnnεß|Ñè;·>Ü.K†“ üœŒKÅùƲª>Ýy·êXWEÁˆ©Ôe¬è6œëSÒž•«ÎþÈRYìÒ–¹åݬ¢¯öÄ•º"7[àV)‡ EªüÊ3ŒÜAãh!” „”äÈjÿÉóç¯Ü:5t»tìæz4R ø1rc…CþR2ñ1<áÙ«Uß.˜¸¡pý’É8L2©2œñytzò++ÍʵÂÅ–öëAÇýº¯!€R[sìÆ,‹å˜­â­ /'¾LðPZ„ŠD¢²²2ð oÑ©œ úWð’2𠜄ßÿöwœ³„¨Øé×÷x{KB®bÿeåRo§û\ÐU¼t¹`£4t•xÝo/ô*ü—Š==ʰ[1Û¥LK¤QIÛI¤éäZG¶Ý 7ÀÒ€Ö[—>ÛÄ!VŽÐÂ|Ä :ºl½5׈bȵhåhz¹†ÜÃ#4ø¼K.·-$¦Ã›Ü¯×­ÛEî¡$Ê$R’©©©ÕY\\üqٷȱ„ÒÊ`ÙÏmi(ä „!&¸¶|uüïdì’‘|È"Š“b OH¥ˆ;ÒÒðx\ˆ.¾’‘~ì‘P0ô/¾ðã_dgL04ýðQUù Ê$\ *[±÷À’¾TØ£2…XÛçš «¿Ÿm\Ò4zê­>ÖáãôÝ2ËZ¼zç”Æº¤i¥kï³&¯¡íÝ‚sù;RŨp-ó… †~ŸfþÅ~EußbZÓ¤ZÝ}çîÛ‹CñÀÁÚ¨-Ñx\«)^TDwATÐ@ {°×{{rß§€»€g:ý#m¦F3Žq“t:ö6mcD!,°ìËö»¬RÒ&ÎÐ:ítÒßü†yï±o÷÷~ï÷ý}?ßÖôŒÏ æQ­ùz¾zµD„“¤˜Ã]ÅýÁ¥: ´ökMÏJ#Ã% €dPÅxtÀƒ·Ä2¦±y´åý:ó=ãÖZ}æ†Ûe¿”çß:¥ÖÕyÔÖûzÛ]Û––‘Ÿ¸ ª)‚ϼÕXÝaù_M5ƒÅ&¯Þ6¤{ƒO: ¶Ã$|¡5Ž-•㑺¼hÛî”!ì×oþ æ?˜¦³}ûÿö”*iCmfÒ $S“¶s#PB§„Ò„…ær¤Å™WÕ³ r:M×u! ç!¿/¨ë_ÓDÈ×uΑ#‘|¡”,Þ•ŽÔw -—šúVô,JJ#ñx±0— 1K—ðÃqnZÆ lUXóù E*Z‘ºÞ°ê¤¼s^㤱ã™idÚHpÈ>ç ©à_-ÎyÍN¤¢±¯úú+Hû/Gëb¶ÏÌCã6Ð\‘˜‡I¨„…òa‡—Ðâƒé®]{{2X=Nñã^ß[·yØÕI’äÓtÌi¦ãlV&ÛY–×jÈd‹â“7qâø¤@DID$Σ‰ÈµÛÒtòœ6ua³îX«*×i:Ùª“› ±hRHQb—¢TAAAà_âÇ?´Põ•÷>¸ØÛ·Z D¹4JÄŬÝ}4Oš°•â$FÓ$A`WÆ®ª°×xÇ‚ùkrz$3Åą̃‚>™ xFFßþÍoKŠ•Û¶lÑHñ¸eË~®É‘$¡¢õ;ò\·³z>U¸î|“F2z?Éìù0çÒǹ—?‘;?T8?>uñ^¶ëwywä}×—m?K¯âa¤%Ä4uÀ˜¦MQ4©rÚ´Ù­š-Ꜣã¿m‰ÿ¸F iFS2cN¶CF6¥³‰G¢1 ‰c8…|ÂÕçz’¸¦×€*H‘'ëáÝë7`;…ÆÇIÝѾ¦¬©V…¯3w¨)ËÓvv¢éøXû±9k¤íôh{–§ý$Àf¸Eh;á?Ÿ¿õ¥UÀTŠÀc8ÒFLi&Ó>æ)1§š,iŒEÆÂ'õ)Óð1úý,›ä0§:@ à0 +³O÷ÚCêÂ#™5§˜­iV Ì ›Ê0),(¥X¦”,‹¾XHïO•…fT6;Äžnþ¾45Ý'ƒ ¯¯³+qÝD€p€·\ ðh EÿlcÌ;êw•?q0 ¢(Lj GùÔäÄäøØ4HæÜü³‡äŸ‚‘üåŸ,¥˜ã×~n¬rëì>;©dúusÖˆ[ÅŽ«¬¾R‹[iÑZ¡•2#Ë}3TjÐ[‡ŠMn¶öjvÁz)Í‘p ì¼‹~Q„­"зç¾Ô9†Jí7Ωâ)BBD¶e»¯·€FÔψ"ë¨ÖúE‰aÄ\ù¨Ä8®µûJÌ0òÁ2‹WU(µ?2X•Û7Ç IÓ8÷Õu«ï)ÿ¤Ò{-Õ#ZÛ€’}PVuåðIÖ$Çæ$ ˆWW9VÌLèí¥†a½cDëð0C*ö!cðºn²ÈÞv0KMcT ìÊò ¯g &@òïïÕßžs5[n3ÉåÎ7VÄ !FqnãÄ¿¼°¶ iíAê/…Õôͯq‘ÐЉÔv†Õºž«êyœÖ§ûßSm÷¢CGP>Ëã}/óðw€Ž.¤Ñ9¿º}iŠLÄK!sCœ¾pøÐwíÕH£ iêDê/E4¼ÔHe×|ø¡Úög¥ÈìA†Žƒë]HERíBû:çÂê ‹ª»‘ª¶EZÃó©‡ÂE+É%¼(“ (H|Q˜ŽÀÄ(•ñÓC°u3{p–3@áP KñÊå7 à i z¥0]«8ÞZzÜü-Dc¨ ¨ãEH–ræ%lÚpøì©Óͺ³­¦lk‘ ^ ÷E$¿lÅÀÀÀÌË þÊW=0×Wqv͉I(£6®ß@rÃ)É¥¥?9pª°ïý³Î÷vÈK#âÖJ¥b ÆãJ$4—žøã7¯Þ<)ÝüÓmö×B>Þ–§žû§ R˜ôM¾œ¸ 4¾D°<§ñ­3WþÓûÑ7iäØå{'ú>•;?ÈqÝVôÜÍîû}NャÎ^»pkW®Ž'Š¡Â#—cŸO&åeœ„¬Ý¬†ž×m:ÝiŠ(À$íe¡¿ÿÛ}Ž1î7ê“ ¶d‡uúϦÜW²}ÍV>‡Äq”/$Q‚ûλW'ã~ÿD(uÂËCNÓôý÷n’8!âÓ°µ²ÇvŽ7fN5gFÜÍrO{hÄÓ’1WL´œövÊÇ:r6ÞölcÆx“\öÊ:Š ù$! eë^ #càÑž¦‘:›lQ{ªݱÛfÛcƒo0ïe ÃœÂEÓÖ–b³§”[öÚ,I “b„°¯šIvŸY›®]ÎåóPÑÎíÛf¢Ö3„ÌÆÓ³Éìj.´Â!”kÄèéîN܏ަB›€ˆÅŠMH7¯Xsñœl¬é¨¿!s¤«è™-X”L;<885á…û}þ¯ÁÎÓ›ozOnéÓ™ôŽ+²N,)ZŒñPÍnÙŸÕ¶Qc…·”ñ¾x0Ï5Ë?RÝZÖÃ8–1Cz›Gg÷”ÙÜz›OËökMÃFÇ`ø¤|÷²hLÈÅ)4{æ7Å]'ò÷®HÞ (r«4êaYM@cï/±Ü(Ð8ÿ\eSYÜj‹[cVqk-#FÇ€Ö<¤³Ž–Ù†5íC£õK­}PY®Û±KIEJ©(EEœ—Äøyn¡!`¨ô•0㥖Q¥Õ­©ìÙæu“SeÔš50TÛh±îÆèe«=ÚÊkyÊuBz))ŽŽ†õ¼/MšüÐÚðÏý%~›,ÝP^›i¢©½ç| NHy8ÆçFñøß%9¬ªiêEê{êóóë»Ãº‘º®`¯îžÉò¡D§¡\ÿ|¡ž/^F‘/†‹£Úk†ËH󹿱_æÁMÜW(3 ÉбZí®vuúÄ\s¸ ‡ñÍÑB°oƒqbcÉÖ¹º±|àãS²e;¥“Ì´ý£ÓvfZ’à„’!a:™–0¾%K–Õ·’q™¶ÐqË´4oÞh~»Úß±¿ý½÷ý¼ÊV©X"Ëe’Q4ÿh>«£•ÕÚŪé˜×Ø Â8LÔÐÍ«~a4ÖàbYë˜^m°Áܬw².]f5\«tͯu,lhZTZöêÖ= ›R±HFQ$IBDKprED´¢ôô×wîÂ^y¼ÞÐióOø`Ó¼S~pP”¯ô¾)–‘ˆ€PbT(Цœ<–pVQ˜ÅÜp‰‹årBÎÃ7D¤ÃP0J,^›°%ólaĆXÆ•‘$ÅE ¡ýúÃßÂD¥üc‰ÿàÀ‡Æ™p{ vÎ[m* Kà5Éõoæ¶ý2Ëu+£÷nzçï².ütÓîÃK09,Œà¿&,–ãÅÇr2 ï}õu(ôBƒ0 Ðëcîÿ»s²üÂ"Ãd¡"ӹ׳»ûŸE#Y®ÛE½·ò×ò»?É¿rû­®™ÎOK®Ü>¨nDðX‚ D$/E¶ì}3½±<¯]UЦÉn®)tèÿ_iDK'€FÌ»l†=ú€±pWaœ|£§@›H‹Yuý³ƒx »þ`*ûè÷× ’ pxòtÊFKŽÿb†»-o¬%g¼¥x²)ËÝœ>[«ËmÉkɃî@#æŒÉK¹»7®€‰(!…„Ri@:™Ö%ëaÙÏz/xKR¥-¥Êœh5&˜ÍA7î6š’†D= 1MoHÕiÕô^e h0%ŸÙe 1î5êõô>ƒ!Õ¨O Ó”Iåqò8ˆMÓ^½zõñþùñåñx¦ º'ø @ÒÙ{yý¦„€“2@¼%N 8º<2ÜU|p¤é„·£Øï(Ô´dŒ´eíX%A¸JFâ²ÒS)Ÿ×ãž|άÏ6&{?YLiñ;ð)犅1\ôg9%ÃÊó Í ¬•yP3k•÷h­Tô ÉöPkRGÎÐn¥eXaòŸÒ{ô6ëjë§o«¤‡O ‡Wlñ*-ßžÓy­u÷Þ1¬I–p9kįNVLVÐZËp™ÙWfQ[}Z[@Y9¨¶¿(?g=kœÔØÏF5ÖG冡 “[o{¨£?È=¾‰ ¸[wô)Û![ƒ¸.Œ`óª÷¾_ÎÐËŸUºsåH9ÓeH¡/7ŽiÌ•º1ƒýÁiz\U9©4 iL£çlwΘâär\BJ JÀC7oŠ ¥ÁŽýHfk!ab´)X"ÄN< ¤/9Eñ¥|’çý8auëÜ&ñVUûüZל:« ˜¡#Ä34rhZ¯o\€ñš‹2rÃJ ¤äúhÁRŠcòµ¯œe¨¦ÚÉjêYPÕ:¯º†eUv°ª€"¬ VUë„"Ó‹©uL_ÛÌÍæn–½UçœÓÑù=- ÂÆÃ¹$%àó82!Ÿ"[âã:αaŸoòxÐóMx¾©@0}øƒÊdè(ú§\mT&\± •€”øÜ( “£ÆÃù’èW6%¢‰G‘øD±‚`‹å¤DL „ìE˜å p-ÊQÈCi:œNw¨êé‚*Ë7S ý[6ÌZ_}y7&*Z&’H”@å‰o[ózþÑz+Ãu/½ïË"×Í’îÓÍáëâ1D-ÄE@’‡S"’:UR ÝCã0ûl@ŠMJì ›ïÀŽuõôŠ…B9ÆÃpq|VEŽã£‚¾›Ï¢‘Ü®;…ÎÏNt|¼ïæÑžÏ3/Qünþ…÷Qk0\*# ¢äJWK‹êU¹íš\‡:ÄY—ÊÁgÚºÿ=NüwiD—¨³¦Z@¯AÙM{-údƒ&Usü‡'b±h)Oò„¢ÜØ•1ý7ú}ž Ei$d¿}ŸCP²›—O´Ÿd¤%k¢õ˜ûÒ‰©æœñ¶c³¥ë OGöDÇqßÅìÇ ™–¬±ÆÜ(!4 |¹|†F´IºçЈ9ÑnÚk£LÀ@–ýcšA›¤ÊK8¾?îÐb·on|C¼asä¶´M'«R+ ûHŒ$¶ÄJK’MŸDÃîR ôn£9ñ|ùUÊÚ}›R@’––J€3‘5£)ÿ<‚BÿO>@ÄûOúÞ[·zM$¶X$àघ Q/ —¡K¶J^í(;0è,iʺ›ºø£‰–ìñÖRwSAàÒÁ÷µ9+9óe˜‚‚ Ÿßè@]39k›á¢ÁÇ9yðRpZH>Æg¿rjëöû «WiTêGÔ&`’!µu¶*PZ û Ú<ª0ù´öÇj›G_ã-3{T6ÐýÇÚÊ•]³cWD7—mIÈôUеá¾B1®ª*Û™*$ü‹#EÑèüZû°Âæ6ÔWiŒRê}ŠF#sU¥ý›í°ÎîÑÙÇæñÓ´WaPi®“åçw¦ŽWÔ|P ”"Åøˆ@„@ò£°Ümñ¤«<šÊ‡gÔ´q ‚ÖšÁ«Í”ô˜Þ>¨0Ž–Û¼°çŒßhª2WJH>EŠ12÷r=ðä¼L+é“rõ;û—ötõ:ƒpps| `$0àõ˃ŒÁA8l!&JÙ…Š%ÕM¬‹í¬Ç\»‹Uãb5:YuÍOÓHH¦5}/Yí¼×·E¢+D¨ ‘`\9'ŠÇf qö²7^.U.jèfÆiì kp͵7Ï©uέïšÓØ^ïaUµ±»^Ô9ÂßúNÆŸ\.0;æµwÏ«®zéÐ[ìek¡¢8!0*åarËNßÿ›«?ö…jIÈ;nŸÇë÷2À´@05MŒ¹á424¸ƒ§ž×é‚z4†'’#CI’/%I—½\X° ¾™Åxc˜ÉÆ;”GŠ×aKQDŠ\^¸D‚¢%$a%}]=0Ò˜ßúLOCÈó³å³Œé;ÅГB§ÙDz@z#1be|ê)絬Î/ þÊ~Euß ÚNÒv’`ßÛ·ïØ –C1ˆšàˆI´ÕaA¼k¹A´TaÙewYö’EnXŽ]`YX´“ÔNŽé´¤MO@ÃŒÑ4­ÚjŒÜ×îöûØ”ÆÌP‡N&ù'?Þ¼YË›ßû¾ß÷ûýüz?É·K¬™ö᤾Á<û@¡ù½¨¬rNÀF6žˆ  çKh’ÊËɽýé-÷¦ÀÀЏ—³ëtÌ \†NL °s\½35·ûRºíêbÉ?w[b¹˜Þõ‘Ä>˜Ø;|ôÍ[GßÛÏÅ1˜-P™ìŸ\}"ÑT”m)ËéetÈ–˜ËÝIm.Él…ëåß?'¾[¨Åj]¬®"Z­Ý­©Ü­SF©´»uÚXƒd[Jk•ÊÇY›@_{app1¢‹ÉÂÂX³:„ /Í['âßkÌ1eÍ´¦8Z“§L¹s¦ÌqKÖR52Ý”5f:<Þ–5Óœù¨%ÓeÉiÎás|¡¶Ð$î¿A«Ð‹u€ЈNlXT#âJMŒšAË>…ô@iž8W¼NÆ ãcB.Æ£q.Ÿæó(‰Q4Êâþ‡6îÿUt¡z¿J«ÕÇèA#êF#Œdăب٣/ˆ,XM®Â½Q '0 3îœrw“'Rj‚Iy(½=¶W_~…í‹B*ûú¸"(ô¹W‚±Ž£»î·›†µt™­’‡–¼s¶³)y¶!eÌzòaç±Â­þ¨—H‚}±±wõø¿ÆÅ.ìÜñ:l.`&„/&â ÒB×^*”Î(«¡õ(*Ge•#%ÃR»üì)í¨\7^¦Ÿ+­ú\¦³fg¾Rê*oüG¹ác™ú3¥aªØxf×Á x^ðÚž» í— ÕJÕ¤Ôø‹°õ~Bÿ»}â¬bT®P¬}P¦y¨ÔÞ)“( _žZ²Ž;&Kk¯« 6lø]QÉg%•βj—Ìø°´ò†BIâ(â×~)»]Z¹Ž0Ü”x(c{L€êGþlßœµ/Þ-ªt¨ªïÊcªÓ@/˜$ÈíA©vD¦›TTH €w䆒bE9$E`LåìïêfŠêüâq—>¨Ž…FðÃxÒp‡nn~¸¯|õazzj”ÓõùýFmÙ&âá$ÄzÚ3dësÇåM¤±wymÿ²š^RÛòuйõzŽaˆ z-fÆ5í€LŸÌ Å5É„Ï57Ŭçcþ›®ùJåêï6‡ãE ù<ŒÄq,!ݳ©žyØFÀ[Ò`EZÚ¤RzGî¦Y"?Œ„ ,ß'ÉUAo¿qÞ1=ëÆ¢»³/Ðñ‰ÕrÑW;/'3½?þþ|ŠK`8œY•|º]Ò}9³ÿÓÛÅ\û_r»?HþõPZßÍDÛ¤¾Yý×$M¿Ý´W‚³É`6Ê£¹  €Îɇ“>üóŒp_` cŽ Š¤ó´hËþÛåôÞÅ4r¸k0÷Üõ̾+Éö¡Ô³7%—¢2Õ,THzñ|}¹¤06'-½SuÈzJb>•×\Io—¥µJ¡ƒKLÌùHW…Lò½sâ»Õˆ^lÐDiÑÊŠ=je¬J%®ÐG ‘Fèà ›ãV±iŒàñhŒƒ­Y³fèêƒY¤ÿYKNWlÌ.X P` ëc]ÚdKö\[ªÓ?cÊ™iNÔ‘³T8M9S© ‘9Sö¸9¼9ý¶>‰Kâ ’ƒGm,‘ƒF4{5 m”~±çÒ‰Uú=*itQBøÁü—üQŠMS$-€Eˆã£Hš`ï|œäå ‘í-~TDVª£4 08͸«F½M«‰Ö•Ç+^qŸÍÐ|š¦!ézzz¾éÅ#§ëÒ…‹ ‡â! ‰€p<’FéÕ<œ»E@ôäïÿÂ|r¢%ÃeNu´Äš²f[s%–´ sò¬IâlËŸ¿˜tµ:w5ú Šqi~ „åݷλëÇ’ÌÖÔÜ™w\A¢Áj _»þz©rLY¹§(Õè)fåU£¥§—Úå¡)ÿK¡‘êÇ‹ –¤$û©¸ð°û¥Æ ùE›ÙÏÛ&;Šj.e•°io!&"¨Î¸”G¥º‡Jýo"4í‹b/ùÁM&KucÒªIù™±âÊIiÅŒ\="ÕÊ´ð¿#ŒÜ cRøÜ0"ÓŽËõñ‡ƒ)¶MpI¾?›wüXá4ç_„c~éÌ9—þw !œ°{ E}Yn¨7ºé)ÃiOI}/R×ïYeöh®_L#Ëk-H“i°ýDfÀ6G?Ãy¤ÈgSR èõh´#u6¤¦ LâQ×¹²¶sECÒÒéaìZÖhº¦k¥²z…¾ij_Vk[^×Í¥©1žEšßDÎô uæ%k¤¶ iµ! ý+ª¬ËëÍH“©¶ mo7Ð÷Š·Gê«xØ) [˽}ǃýå‹¥¿Uìï) ;Äþ¾ÒqÛñ £ìwÕY‚Ç‚©1 "/%C^X 8D“­Óæ4¹dœ†l£!Ç ËjÐekô9*]NðoäoOÚÆ¥á:ʆQŽL&`R|Q °1FG&x‚ËÉFpI¦ØœßlØkÒè”9uÆ<£*G«Ï7ë÷ éºæ¦ª}U;bw¢Q  äĸ„«/‘×\^rÖxZMÏÖþLÈ5ä‚Ãd“mÃ`”ƒÓߌYë®Ìú·õ¤Ï. ô Y‹|ÖR¯mAŠóY‹fz+ZîÀ*0aFêkÉa虪ÁÌ×/Êž „gC!ð ½uëVfaF —Ë¡áÐ6`‚Ó+¶ný¤Z½X5¿­ÑÝU4LÉ´3ª&À wj5>•iJf¸¯h¯ix 5üA(ݵ’EãDé¦oÆ£ãP›þq¹ÊWÓY°9AQ>L’óžÛÒb“cQ•AÝÈÁ<%e@ß¿+ê˜T˜'2]@¦ó×4H¸¯l¼S×øK‘øe4%@Kâ&qï‹ÓuM÷4j¿¼yRcžx·þ£Z A¥lD‰ß‹ªÆUjO¹òåhºé̓žCGîÊ5Áj- ¨i¹qBÙ0.ÓŒ«ŒÀÕ†ªÆÕ(Ãrù“šT\€Q)>¦RÓÓv#ø–cáöuÊÏëó…ç¤ [ßœm6e´ÙEž¢¶°FšY¾/9c=œ(@x„Ô–Çd‘4…a€FSíÝó†ÑÐø—÷ÿ<ç¯ÿãÚþô}H`48sSFC–֘ѬÍÓªóUº,H‚>×`Ì2kÓõ YÍÁÑž²Í¬>›Ë ÐÀWñëâ®^¾ò¸xçjê) <)jP_ƒÎ3¸íLÁygPv'2ì’ô{ONºj¦Þô Ãö’°£ÌoMô‰ÊOè´(Ð+ù¤»&…K¡³˜‚æÀf£éÑ^$=©åGk(ô¸ zœ›I~û«_'Ç&ò9• z5‚ ‰Ñ•ôŽ¢ùvý¢Õ ˆW©ŸªÑyku øªÑ«2NÊ SÊ&¿Úx[Yÿ¹L§Ù“M8`FLÈãqxkV[ó¡2eÆË5š])ø À! ¡ãlœ 3¶3pKÆŸ±Û/ûÎhäLž>µùŽ\}G­»§5M*A…ù®¡ÙyàN*XMÛÎá;»§0>¨mú¢NTSv‚…3Q&aÊ;ö×wë÷nØ’°zíùªÚO5Æ)y¢Z=®5ûj Þjí¤®ùA™ŠI¹ðÉT½ùÃêšô˜$ÎKQ$í`pbB|pb2ä÷ÏM†?Øwo³áÇóÀ| ¾7r¦3h<ÎdÐÁH³¿jë^e9»´cjq-D#Ë`ôAnÈâYÕf[¡oš»!»{i—²Ø¡N;ÔÕuÏ­-6àϵ{–·ÛW,[Ái‹gSb-I‰$â£2D˜; æ>¨Ëö¼Åµ[—u,E€¯luBÝN¨ËuF"ÙÆÒ†å Ùìx4 erAWþì²ÓØr&4öõ¯&máÃÌu8 e%·/q__ˆFJ\c'\¥ k)Îea|œƒ1˜¶%ïd±´»^Ø%/ê•—êÊõ»Rl“ÿ/ûuÔdzÇüe=Ûµ+Øï}%À-j‹î¸ØêêjU”CEY»R¹B8ÎX@B. o!@¸1ÂÖi;Óiëôpmg:­ëtœ­m§e½9’¼Òç•]w»]¦²ãÌþ³Ï<óÎËKò¾yŸ÷ý=ßϓۡÉu–äw”æµk€R„¹ôÙ]U·!«Kÿ¥3ã9{nK þß©Šç@Â.]# âÍ\’YŸl8óv¶ž‚q“8¶sçŽøç=ú¼|rR²ŒbÁ1X\›¶ûq[&ïÊáÛÓ½-Ç'{ –ªO{¶ô–”ÙÎ<ëˆf{J I0$IÊ$r՞˫-®¶æ@µ-ÑbŠ3pI&Ãzÿé¸MñQÄ % J‚"LÒÅ€è§e(,Aqqáøø¨ó¹Yÿ‚F¼3ž»ü¥NcRd#¥Õ×$ØË*¸c\ùÁ .ÁTg²²Uª1äLIfãѲÜ]¹ëáðH\Á MãQ›"ûz„ ðóPˆríÚ5¥‚@q<Å^[÷2—º÷vë)Þ‘Ë;³f;”¾¶Tßù“³ŽtïùôiG¦§3wÑñq¦ñá;Š\êD)¼šÂe i˜bCÔ“'Ož]qzzõB™´FâAýÏOÍx Ô§)Œd$Ž£2GDû¢Öÿ2çìãŠÆ{Ë\iõRS~º”ùëÕVͬ •÷u懥æiHóŠIM™§¼Ò_XuרtpË60Â8Œ½Ê`UÇNþËlŸÓYáÆ›Lú 0ÝPc·ðgs?dwu\^ÁÙÅû’(:œJÃPÁÅ`)¦pœwúü “ÒÜïñù| Z˜¬Vs ÛÏm~¿pƒš"#ŠÂ‘ º‘ã‘;ÎôýQ龑9pCuq\yq,Í=’58–=0–Ýw3«çO*÷HzßÍt÷{ª‹w€I2úGTCãi½#J÷_ €ê¶3å,À¨Y˰ˆŒÆHXp.Wäe«‡/üô7x·k _ΠŽÁÊ"b{lAÿ»©—?XL#ªÁ‘‚¾÷2Ýcim?ÇâYLª#щ!+§Á¹Ñô›Þ|ýû?L̳+[5ÙúW™ÊeÌp–žì(IëÒ*ûŒù­Úi8Ýi<Õ©,Éu”¥ä»t_:3ž³gØÎà$E üÀ–4'š€F€+¾€F,ñU• 6°_v´ìÄ÷ÞQ a2œbI’¥©½{÷<š|ä›jÀ=L`‚ú`B¾•ßiÉ÷u(.%ïHõtd.U#¾Îl¯«ÀïHóväM:²·¥çîZtMÐX("Ë;¯7šâ,ÜaN{X“õVêîͱ™h¹T¡ÀrŒ<`q”!9#'P"” U*•W¯^j (Wxg?ÑÈÇýȡà +)•Ê‹cKl‰vàóQ ¸ŠªWÁÅWš×p‡lHâ+jŽYóbs¾ƒmb%¤œ¥DÈZ‚FÜ}ýÿ'Ô÷x< ;àHLLL#¸@¤áÔu‹rҙͷgÚòçSŽÔy§°Ü>Ž;³=ŽŒÅÆgÆ‘èQ{•÷§½N ÀDZ­ö£é÷S3ŒP׳³ß]¿¾5ú ðV°à², àFô»cêlÎ>QRî×Zgй¥¦¼ßX3¥1ŠLªê*' Vͳ†šiÈ벇Fó#M¥m_‚DŒ2x(2œ ƒ×ñ”‡Ú²)>Pa›.âîêx]ÃҚ‰ò†{eö©òú'ËDaé”ÉüÂ4b0ZL3ó\#øI¾s•Õ¯5ûtÀ¼ºº«êbFâh˜¥1f01ýCK¯©œ8Wq|ó&˜Û³Rl›‚½”uÊolž.`3e´~Xhô–×Né잢Ê)ƒÅk±yй CíÙ=û1Q0A"À\–èì° ¦b¯ÿì,ûU{1MàùyP 1÷ô¨öù‚ô`&%9‰†¢Tˆ*jê€Z¯,®×êšÞ5µCãPÇrkû+un¨ehemïòFw A]÷r[ïêZ÷ »ªíª{Ö8©g™p<ìå2Ó*[ãò¸Œ E™ðÕœªí†ì?YYwj[E@‡ûW¯·öBÕÎeíƒAzÛ¼¬þdˆˆ¤à˜·¶ßŸœ‡sy^˜ƒ>èϘ±$œ,x¦­µ^Ž,Ö ”ø4¨Õ Tï ƒì]PC—@’æ$`§¡wYËÀÊšžu«œ—¾®Ö…Dma(\AŠIpBÙ}`ÿ¯~ÿÛYPOËàíñl ý¼ç;÷Ï;ÿ##@1J‚×ÐxXÒ™Úìá[ÊáÑÌ¡›` (¢Í»pKåUõŽäŽæ ŽfŽg Œd¿¯z?sðVþÐ ¥ûÏÊ῞轕Ú5R8tSÝxå€Êùí7DN0ˆ$S°XOLÉ)\LJƒCe(‡HhfK²ê쥱¤ÞñÅ4’54’Ó;–70º-£˜Æ)¹øU ]J²a” ^+ ÇhLþ‡ý:nâºã¾ ͤØÄ¶´Ú{µ’/°áÖ\a’ZŽ8`âK¶ñ6Rcë²$ëò}ËÈ–,[–m ™É0SÚNg¦M( 0m§´4Ð&àß¶°ÕßZ¦¸ƒgÒÉ?Y¿ÑìȻڧ§÷~ßÏ ÅhV„q,#»n ß”“\"/hVp œ:¹CfWN²ìjy»*Û®Ìuj œêüU®]ñ­3ã9[Š6# b,Æ€FÊ÷é̲ò%S$Îd€~ËTWo‰åA¢LRÅmÚ/ æ$8C D E‡¹1ãy2ã™ß¾m'…S,%…­‡.ñõI{þ”5sÖY4g=²d´çŒ·ç{Yð!г®‚„ÍábVŠŠÂ®ð`þÉø“G¶‰‘"![ ˜à““!Ã$"6 KHHp»Ý††|НQ û¦¯O~&''«««9Kç0ºpw¡EVi<Æ8h¤2Á¢••«bõs|µñMs•¬B—¬ËÛu4,0nûQßÍå<÷·Å4’Ñ}-»ûæÉîO„ë¢á^ ¤(¢º¢úpF:#á0TÄ4‡S¡´Ò8‰ E¢`œA™õâ ;¢÷¦'déOŸ5Èú…¦ƒ–éÔdt(}í[gÆs¶Ä’T'Y gaÜHJ»O 1Ä›—ªÝ~a¿ÑüVEõþ:Ý^£þ@¹"Y)‹Œ A¥ád(€īө!zaö\þõï(\Ì¡„˜”Fúp,vÌyzÂqÊkK]*E¦ÛäC¶þôž;™îûá¹ý£ƒÇú)D$ÃDP"ª7Äú‹#ÑuoÈuΓ}×N¹nÉ]‹i$»ÿNZ×µƒJ+±!¤€ÆñÄ)sü¯3ysñÒÏŠ‹‹#ÂÂ%°‹¤i:Œä§%+Â<¸%h‚‘þ›ý2Šò>ãø¢éL¬Q`wßs/@¢xÅÄ£Úvâe”ÃH‰J,Ç.. Ñ "{ß» ×{ÁÂâ šé6íô²ÖÌÔ#Å#Ûô¤‰ ,×îº}^6!¶S3ÁIÇò›g~óλû¾ïï}Þßóý~’—Ì}õà®TQN±ñÔ‰6M¹]%l‘ òòNí3ÇŒoYâ<#9¢,‚¨0¤ëž†F2Uºƒ:eª üטnÖК߲(ÒU;×îä,g'¡\¨‹¿zõCÊÐ……@Mä$üˆÃøQ8ê:°ΗFf\Å#®ãaWÁ˜Kî(ú¬1Œ#Ø(I `ú<u.Éf8ŠÒ¹‰$Éd²QtÏŽöÖ–é@`jff¶ g{†¯¶÷£/j æÇ«õòåË t“ˆÅHÆO6¿©?`¬I·jÓ4¤ëa 2<@rt™fkF­v¿V–&;‘V±·•½‚À™(‹…xìÙµ{ðóû Ùd02éŒXœ—@_ò2'ì*Ÿª}{Ò]:êN´θË&Bk`ÆŒK8í,™rgÜ¢'ÒˆC8I]È· Ž’ë V3& @ž(¹ö‡«”üÎFÿ«*OqX$¤Žd`Xs%‚og î£¹S›¦« “2Ó Â0,§î+ Ÿ+A±y¾.?¡¬WÖ Kô~™y\l2œùH,?´q¡qµYCýˆL=#6Ä–~™u5J_Ç"“â“ÂÈ}kÖ÷ËUFË€Î4¤¦gJe ©ê&%ߊ@Œ*u¥æ_WÈããp‚nÊÍ¿¯«õ‹ÕCJ#Ř̬2À[ *­ŸœP§¯}™Ž"q –z©¬*,® ŠMSr3$mªÚ”š!o°¶¥uD_;&5 J´cR͹áÚú‹ŠÓk „ÉÂØ8‹‡òR÷ìyø` 1ü¥'<ŠÀñwãÿ0_QHø ‹”Cˆ’ƒkÝܺr%ûOŠ%)+ŸD#48l{TˬÏÖ{ÚzÙÎG×uÅ4tE5{¢šÝÏ›š–”+ž{K´øˆhiIeL£›¦,,ãÈËqKÛÞ 55ÑZm êÏÒZÚ—[ì4KÃ÷Θ†î[/ú¼iÄf_Ôä£5€Ñ;b…ÇéÌÄU`W(7[hCB!0»Ðt0<žó÷H"Z÷5X2÷\I!¨:È)IÆÅ2Ù ŒË¶lŒrØc,= ¨:hi6/µ¶†Îè&ïBxwÈR“wQƒ7ªÞEktRk†wozÿÃrŒ‹38 .ÄQyMÙgAC.ràV°<4R%B­Éh_Úß³R®æ¶‹!Åb 9î_N[/-” …ËæÐ©4_'“»\®Ë—/?Ü,$yöþ”õó1ðk—†6î|ÃT¯#Åfˆ‰¡ÞêÚ;à‘yI±Å,5ÛÌVá”éÝ2“½á¸MJB”\b£ÕXoyY´›ÏÀ1ŒÁ*c–q±ÊÊò«W¯@üôãOØ(‡ÇâÒqîþññöåXûl´=jI)3¡ÖLPµèoÏA-KãÍK‘ÞøxßjñÉZ³‘ž…@*:”Œ)ÿâïÝ…?3Dˆ­ØÒs|£ Š =…¡| —ƒÓé;YxPÞð/½eÎøa¿«_ÕµgÌ®ÛZÛ]=aôÌë=qÂ}×à½côÞÖ:Ò¦Á ˆeÆ4ppÜ$œù»ÄÐmÒ=§1ÌÍó„㟖aïž7¨ J9ƒ6.>&FfuÞÞÒ8eõ—{û3'ì9û–Ñý›#ýÊŸÿ쵑["ýë Cjí´V% ûŒÅ×z>iÕl¢âŒ>úfSNëXҹܰºo¶œv ©u%Ô.ý/÷ Q($ô¾_l¿aôÌ™<7kÜäÈó:Ä'nvß"íñã¦,á¾nv.i\WÕä«›ŸCK(<6 ­¨BxõÚ•µæçwãQåÜR:ßžŸ>Õj;ô¡¥ìò§7mYŒ!#¿*žx|4Š'‘¡àªT0:±nh>ƒŒùaÇQ{£ˆB§o®^ç !#“ëüSšØ°ï0¬¸®ñ_xìÔ42üë¢óOú"'À»ÈðE$paÍ422Œ†ŠÆbè »ð’Rð,Î)T°t:ý5“€¡?àtÿÍÈÀSÿy¼pÌ,. ž*CqN£a؆Ö€…& Xóüó;‡ OùC¡`,ðƒÉd†ÃáÂî6¬'³2“º‰Kͦj*F«€ KÁk»õ-ï|ª<ÿ…jòšòÿFM}Þwö¢—Ä<.4fLZI ¬-sÿá«°@ˆv¡uM%’¿ÿèc³Ñ´sûŽ<“`e~`i6Æäà(ŠÒÀhlf1VÂÝ,>Ù¶ÿ•×ÕmmŽ£‡ý†#1²3lNPF"ôí1}׃2¢QÆ´À'-ABÔwŸ±ÀZZ  à à–'¢ëíA-¨3LtGó×Ama-H±" “¼bà¤p¥p ®tL_שòXEgq±<³Lo©ur»UjùV‘r+È"·ZëlV¹Ã"tÛHi–%²Îb®7“ $ȾÇf’nÛ_É2Ji\.ûàÁƒàñélâ{6œfóÊ™Lz ëY5þ·¡öÜé·²¡¦…À¡\´çΈ"9ÑS¬æ¶!+4Ò'‰@ËÄ‘Wy :|È\§Ý1ŸËµ•ý²¸BÎktƒ^ƒYÂÅq!Cؾ£Ë*öx%£N±W¿‡´ì5$úÎ]â­’çÊ·°Q ÍSêVf¤FÞ/V[Ìv™…”º´õFùOk¹T6FeÂlqœY¹I@ïñ+it|#‹"¤<>¼o& Z Z+s±îdXè• u-E»2E*И )HV‹O6¬X·/ÄzRU&ؘ ´Ü™xûŽZ0Nx#޳h €QçatŒ¶‘É~¶˜y|—ô½£šë_Âê™ÕÀ óF÷j®R;òÒ¹ǜڶ@¸Kâz'¸ö¼Æ>«¶%ôî„ÎY¸5¯w/§5Ž‹{AcNÝ75õÏ–ñx•(çÏöÀhÝü*”ÆDŸáqèÃÍŠ¬ÖŽ7ú¾Ôºo|€:‹füÃ#§£ûºÎ’4ùþqÂ#Ö”ññ=‚òjÇ—Z2g95Gä'yÛ™:é¹ÚoøÓ ó6Þ&Gù-r Ö>Ozf´ä­cÖ”ÑwÓ踭·d Œf÷M£=£qýÝêkß¼UD+åp8ÐÊpqÎùÉÉl6ý)úÝx#ï³+ûZ¨íB&&`3ŠwŠÁ.ŸðO!ƒ#ÈàX‘?²ª«ú/"£“ˆ/†„Ï‘nê_ªú~i‹YòŠ ‰Ö‘cÅòf§ŒNÛðƒíRdô24ùøÐÅǽ“È`¸h$Š Æ¡ÓHdín>r|o0‚Œ…¢ç9('¼¸ù'¹ûñãáP$wOUü¦¿[Î5jä0q6”ÿ#­áÉ¡)dd h;»æùžF†§Ãññ§¥òr®--…*Q[[›J¥ ï-ør‡ “¹·Â;ÚEµ £ðiXÕÖݽÓ6_¼Ò9ùyÏ™kmÓŸýÏñãµ]øâØôùÏïâq¸8eƒƒÍÎÜM/e¾Ių3}+è«Í.9'æ.¿ÿÁ€Û#“HËù‚Ò D€Ëæ@©ç3°r4„t#ŠU ¸cC2³¬õÔõ%¬LÄ޲煃Dg_Ħ7´ÅLŠpž:Nªº3ªWÅŒp@h8¤+fê>mΓIH§ˆê{£DWH“§‘°N¹Â­¢)¢ë 뻃º®€Nz"z Ðá˜ñkné‰Ìà\9®†ã>uP›ŽðÊ*mõ6»Øk­óÙåŽUd³É¬€% 8ë¶z;S†á˜–Ñ›SÕŸÛºâæÎØI÷ˆÁµzÇù`°Ä€ÍŽ»Çø{Žö[œk⸳æ[TB‚HXÁ)ß©ÞÙh4>7ý5RôûøŸÇb­Hìú™ÙX$jj2Bí’BZÎ`RJ˜·KÐX8¿êLpyËÒ®ÚuIpæ‚ «_à»øTWèùýµ¤jB$Váp^ÍHÚ”ÏPê,IR¶DŒnÝ#8uù©žþå €9snuç¹gº.®ê>¿º%ðÄn~ꊠ»ouWxy ŸJ_GSˆÇÒP9T°E~˜›oB# ×Þ¿Ã\|úõ ‚¦œ`2VvxWt^\Ös^Ðøž˜F–u<ï½,8}îY£]‚(9¡J(B~õêÕG†1ÿèÇÌ::¹qý AÁˆSi'Õ{Œ½UW®—ÿæ†îìÇunT^üûÿ?“öÒ§G‡Ön;HÒ2‰h(ôTg'Lé—°÷ø%’ó1yÀ$‹Ÿ'ŸýãÓ÷޽™Ì{Kö¤§e©€ŠŠà¤U’ &§B*„’¦ÓJZŠP&‘aš×Öj­ÇjÕ¶2Ÿ¡f€¯ªýÆš°¥,È• àj¿¹*`® ñº^7ج ËBMÚ°I?ÈiÃ\Y¿¹<ÌjBü¢ªƒœÞoÒõA€7 né3TúS4AOm?·Ëp¡ÑZ5•D–m¼ck‹»¸ÃYàþJ¹ò] wä*r-Ê‘ëtnu¹òÜîmž…_ï+¿…/l>¾ãx6™¥ å4IÑ4 S]Hj …Èd}c# JÐÀ#r!Ò˜¿~4üv¼¿:(žÙ;Û[6¬]Òmýºé€v*TñW€\%?aQŒ%aSC]»¿LfïÅŠÃ…‰d˜_eXnoœBa)Ó uMAÕ[¹o•¬óe:# ÇÔH–L¬b¥ 5«’*±®R°8ƒ MЊ :ýX^ƒc«Ç³­Í^`¶ïrXP-RgªÒ¤R‘\Nggf]{ÿƒ ëÒ䌗$Mg’â/ü'§ÛwÇk§ô±`ÅLÝD_Õ¨O@2ÔÅûÊ—šŸXßÁ{~ýT¸aÌW5¬ˆõ–Æ|ÚX°fèÄ>FžDáêTB%ÅD?SkÞ)?2ìè¾{²%fò6L™œ1ÞDÖ<¶4L4·ŽrîÛ¼{¸Ù5ÌÙo›-fÛïü‚w íãF'˜ò0çs´TŒìcFþ–¥ýxÁŽýkÖŽ\¿Û[•"BXŠUS8E _Na,o””¨^Q'³Y¨âOÕµ7 üˆÕw19ÀÖG9×mÞñ­ÓˆÑ³µßij¾úÜîݘÂÒ2rßš×níÃ&+Œ$njþ¥C»~ƒ*I*M^‹#¿?f¸kòNµ5ElÞ‰&׸¥å¶Ñ „38&›[ÆšÜ#Ö.Û¦\€U•"‰ºÃ ‰âž¨6ßÓÈw(î›Ý|ÍŸ‰M¿ÝxTJ'³´Z3r„|®T/híYÙ1¸¬ëÝ%© #$8=(8t÷ÿ çÒ³m¡g´5?ÔdÂUHiN ŸÃÓhVõâjW몮÷V¶÷-ë>õôIËŠz³ µKà ºÎ |¿}bé¸ h?³ žÞÄÖ¿.“Q(I(%äøøøÂ{Ám‘%¶¼ÿ2à`6ólîsgdj;ØA’ì‚ÞÞ§;4òTÏÕ“Žy÷ÙUíç>âÇÛ¸BNIT8®«< Zù"JÍÎÇÂÀ¢ ¤ïÙ]ÂÒ ‰ )ñ£¼}GÞùKéÙ¿ê/ß(½ðçÊË×kÏ}çhäÐ…ë —>.jt‹h ‰â)ªbÙîŽîEÒø<ãÑ,}Ø×W3Ò8mf.þÏýûÃkCíÝÝ5‡íÜ©P«% †$Ãi™Ó`L¶\MaB tªr‡A8hÓÍ•!S]ˆ«ö*ƒÜ¡ 1Ñä€C*úŒ•~´¡G4Ágy_SEÀ\×o«ó7×ùø#~KƒÏª ñ•ÖŠy’é¡=hÓ…-€% ª´ÏTÌS :ßät‰0À¨TΨ<»lž‚Vk¾ÍQèþJy = G¾Ëžo·€¬öB[BÛí¶ Y·[,ÅÍ|1ÏqæBsÅýæÌMYt&#¥”r…X,ÊÍÝ2;=42=;_}ažgcGêÜp \D’º¼ ÃÁ£3¡ÒÙÞƒq_u$ܰ”ÛÞó•ƒÉLõ飡* °°5Ã~ôÁ‡ +˜HчÎ;_#` $¾$CqaÐŽ’&º1óE5­ŽÀ–ˆˆ!09A3R%ñB%ÚœÆî~)s{FJ6•Ä`p LJ¼Â®sîtºòŽb¾¥°­¹ÈRþÓr¥P–2«Hrra^þÐÐfiBβ4M1;sRoõÔOÊ#¾ÒhÏØ/ó ¦Ï4Žg¬Zwì8Z®¿;?¡ÕZ‘ Š­¸²®(¢‚]o”# BÕ ¹ï È%$^‹ú×Ö®ÿlwÛÚÝÙµk§¶ÝÙµ3*„\$Ù'Ç‘?tºÓý£ï<óò9Þß÷}ž÷ûy…l¥“v‰·K<Þ-ÙDsé}lBŸ­Üu^8Ö%r›ì.öv¶” ³W¡8!@h‚doOMR¶…N™¼@ˆOmv©ŒCJ}˜¦…e.×ÔšÀy=2x½Ù¥®Ö˜Õ†…έ4+Œ£êzˆ™aDª‡Ù£ª©ÖìJLŽgÃõÈiÈÛåU½jkwaÉ婇W¾Ý{¨hØ`ª³HIgQ¨ ˜qk,n«6Ãë=RC@>7ýX4¢04 £r­¯NíÑZÏ9Œ#¬d6ïÖ1±ÛÔ²§=Š6f¤$Óïñ²›o«LÃúsþjÔ¼¶=ª²¸$—\?¬Ðê ãÓ¨Ô<¢méÜ{„‡FsÃV„—ŠÄ€"A·/45œ|õýyüˆcòiÉGš‘H'2üd(7g7‹&áå$RÜee•ó[úísk[7£ÙÉhw.hq†íÕvÑt~™ðd ?5“„%& Ljñæ†\Çèìc4ô¼¹c?“Z\¬!†ŽÛ´u±Ñ4¯åå¬Ç XfEhJãË/n…ósrê¹óz¹ºƒ£œšš¡ÿXdÞ°.>Ÿ‹r(NŒ€Çc£qÍDi’ËCØ·=•ß\±óvsÅC‡ØÛ#ï)ýXq4+ {A$c‚Ò÷Ž™÷šu»tºl£i·$ÝŸþ›å¬D›‚$ÄQ¤V¡¸Ü×G4Å6›d¢kSþÝ&ô÷žœp”‡Ú H&œÞ® ¿]lŸ›F:Š'ç:DAGЈ§ó(lÆç(ô;Kï™+øÜ¨8ŒI Hɹ!þ(TÛ2¢4 ʵ ð¦Þ¥³†CnšËµ]r£Oekv×èýµÆq™% ·ø¥–Ôê—ׇȌA‰9TgWŸTš\Ó™m;9yàÞ=(f˜{üSÁÉÀóª?´ï¼Dò9ó„ÞAð3ÃÃÃkV¯ÆN’>‡Ä#y‡§UÕÚV¤öÄK5¿:æDí³êOÌ©9‰Ô;gTººÄ~|–Í…4õÁ›hy6dsT qÐèòÒY‡•± ¿ÀçÓØÊ5ϬæM®™5MQu§ºç–›pž(ðhTy÷ï߸Ç0n}³»giÁ°‹˜'`fçö8 ÃcBTôã’"¤¶eNMr´m.,¦ÆõÌë¯ï|y{&I-\ËÅc9ɯ½1æg<,Šøýþˆþ>ÞÂÃ]„³´Åd‡Bð1‰8>ÏqQÞñ÷Ü“7dǯç¹nåwÝ”¹.e¼ôǧLÞ{UÚ{+«÷Ÿ…®kù¦vIÒZ1-†lC¬\{“–.;x ðÌ'§ÇÆÆž¢ÊÇq‰œÛÈ~Ì$,ÈE² ë¬ Ë!ð9ü†;±Ñ Û…þ¿J$ ã'¢8–@f׫²:õ™E.€‡S“ãÐ4ªs›5ò¶’ô5ÉþfmJÁ®ù 9 ñe=O àPŠ&PpÁâa ,>j$Ë+˜EÁ"ˆBƒè¡h,I$q%¢hŒ&¹1qÜx® “ 8šø? @`"<*[åñø$ ¦fgc@Ä Á!F‹ ,/+Cvá/çÙ33b‚ Bk!? &¬CölÛMhIã\:å}ïMÐtŸ#m:µõ9³}ͲQ{ˆò¸]4BrQ¨7Aötu³Ó±ØÈ^’ç¸z|º]]²Lé²%KÁáBp- nÄQ8#µP ¢8±Ë…ÄûÛÞøÔ”þ ã€·Eh“O6e3BÍrÀ€‰æ<¯£€iØ~ј“€‘Ñ2šúÕâµú­¥å)õ¦­&CŠÉ´ÅbØaÔþZ»6~M<ìàˆPz[j*àìï:]8OH\šŠå‰ë¨9$í|ö´@{Ö˜S:áM5K§óϨ3¢%Ïß,›lL4ÉB-ö\À›#“iÊùϱ⟓<&Ó$ÊÿIÍν¬+ÍãŠòñbˤÂÐÚü‹Wa˜Nµ½ê2w‘Þ«2{ôUW •åßÞ·4iÇÏVØwïP—‡Šl}Í‹ŠÞY&ù(iÅu…O¡ók*î4Æ%‰<7mÙJ¯ÆæV›¿2Øö®ZÍÉñ«N¥ôëêF5%þ¢Ê …mLe+µ|¥Ôê¬nM¥[Qù¢iÄ£±G[†õÖ!ž9b¹y¸lqÍ¥MrÊ€Ò:¢5z4:·F?¨5ÀªuÆaÁ[jR通¼ÚòquùˆÒ2fª-*c45çß/~=N€£ÜxTH¡â%I‰—/÷3¡ÀÔ”òÁd LåÏ£ ?´ï¯±y=Ä\»rt²Í–$p9³Túyu]Hµkf}Rë@êíHUÇÌšÓÓªmM_TM;ÒÚŽTuÎnhå®ZGbœx¨ãbQÿмipÍþðÈ«”@Œ fh-ˆ½ ±7Í>ÚƒÔüaÌÕÐ8£¶onUR׉4{tÌ©î˜QëB껣l‡ºÎ¨jâ艪jäo~ç“büeJ˜Pw” ,0éóÃÁcBTêYZ0êÆfq?k0M‹¸  ób…¯¿TÝŠÔ÷ `Çœsa õÓÒxlN]ÛªœHó ¾jrDÙšÆOˆ¢ÃóWЏPÆòæ œ9}ŠUÓ'PýI”bÉ`$àû÷¿îI“D•l4.Þô›ÚéÔ_ÚýYAßÒÎ+Ù]Wòz¯g÷Þõ~žÞ}WÞ{'­óº¬÷š´÷’ìÄexÈpÝÈêù¼°ëoÒÖ~YÏmiÏíìÞ›™íý¹'®gu_ý®h$×u%Ëu-³ëXAÏ?rÎ$§zEœD“È<œ 0ŠËj.‡f¦íki¬¿{û¡Ë0Z„"œÁň¤ú¿º§Dþ>ü$ìÆ];S{h>‡â¹Ž²Ì6ÝþfµÔ©ÌïÐÉYQïo-Éwj2[U-¥ï~(ò\-„oÙÏP,‚"‘7 bA%L,`(é oàz‚Õ<îÁ–dˆo â)‹@Z¤gdÆ'„)à=¼\¼(hywê.«ÕzöìÙ¡¡¡oŸåi/€{ÜûË·Þ“8…SB’NŒ™×Q°i¼µÀk—›ßc:¤£öl_ËÁ†,Æ‘åvæ›vŽ;ó½ÎCºŒÉYŸrÏR‚‹qÅBW+U‘XøØ ®ždž`"ÆâaÀ?Å#áÇ-À–¨¶ã /ô÷«Š›×o¤9üRDãbŒ/q,nqH.Ç[JÅÊÞ”|üÑ·cÈ‘¨“2Îüé¨`²¹À ‹‰¦x¤ˆ Ö$¼V¶£Ü”b°¥JßÖëRúmfÃsñfEµ*Ü‹³Ñ9wî¬ðøñãl\pRÀÇ_%—/$cZ÷o€1ƒÍ9ÃÎãÈ :ä~»t²I dtÂCúxSæD[îtë™h•YŒ3§%s]EÅòø‹°Ø%Â…·º/Ë*˜âŠ¥i\W:;¬1M*ÓÒÈ£©üZQ«ÙJóyOçS|Šü^¶oBidŠ*¯«Ì+ph*‘•ì•Þ×V­5Tå½9pf¸t|-Û²kTgÐZþœ‘{^Vn]‹ª‹`ƒ ئàaÈXÕšöé!Ž)2”†»zãåCê/hEEHSñ™¶ì覭-ZòSÞµ SªêÓH©Õ[dô±ŽªMJ­ƒªÿ²_îAMÝY>qw»* Iî½¹y‡€¨Rµn¶Ö]­+ÐQ»‹"Þˆ"j ’@x!„]tÖÖîºÓmµnW¥>•ê:ã»;[‘GÞ¯=!”µnÓ™í´;³3=óËo~7wæ÷;÷Ü{Î÷sä.I½CR÷¤XöDª°–×:ÕÊj?<\´†Á$Q)v(¾Œø*/úÁƒÐåÍ·ÛýíºÔìmP@N’È•‹BF‰ë …?ië%Ôé š;z#‰éhÖOs‹ažê ¡IM¢ÇpÑ%k_CøqÌ击|_21+—N ¥£è¢ìÂÀz]@ Èošó„ºÚ9• O6ê *:B# ØpNZû§ôsTÚŒ„Æî¹Mº—‹ƒ¹Ñ\R0Š¢¡î•KW<®iÁ*q¹¾Í‡çüRæϹ (tÁiЙnÜ9ÿ”Ù¬›Ûj˜ßÐóM4¢ê Ï[us{æµöšõó´@VK¶n ÂBÃI,*Šî=°Çc·X/*©ÃáðÌè)P•+ÿà!(’Ôà ƒµiWžþŠ?õÏ쪻ºŸ5po×`²áfÖ™á,ãÍܶßmÉ®Ü$8ö*_°)©`·¸©°çÓ\àÀðYú¹‡©Rúî§õÞÊ==œÞs+¥çîwE#é=7aN;ó@Ð÷¹°ïnþé;Gz?Íi}ÃÞtÆš_,¥F`xhP(B '£á$ÀÉA( œþóÍÛJ%¥×/_òØ,^aój ØÌã²¢¹fÓ2óÒœNˆØl aá àÌ¥ÓK# qñ€, I¡ '²;¼4’¦•¤v§uIÓÛÄimâÔNI¶¦œ»Ž‡’IT”(³rՑÃ׮›§L›ÝKGnÏå/]ûóÕ›ŸÝ¸rù“~cßɺz…L^S­'ÓÒËízÚñ1±Ì*.3•*÷­[0è<ŒCÄ‘ ©¢'ÊÆÑ’ê1±Â"k-–ùvií÷M#ž’ºñŠ¿I•†]É‘(™Ë¡Ü((µÊÅ'?.ðÈN^äˆTöw «Š–‡Ë9D `}Ñ/cŸ–ÕËÇ+k§ÊjÌÒ:Siͨ¸Ò^ÙðôhÅXIÕ”¢aBZe+œ%µwe5?£Q€ÚÉx(°(“Õ~À‡"³Iñü_˜kÚ|EjìÊè—½M$&F!2#ÿH<`$¨º½@Ò¢ö§Âª>Bk7A¥ ¬ë T%4«ìu<„¸tûžÅõªàÍ»0´™LdõêðÅ!нÌ+‚;æÕšÛ›Ú~,L¦F¾¶@\º¨¶sN[Ac hí«ê!4wÌU óº½4R¯ŸsÓ©—bÁL6N¢’ƒ×®3O@„ŽÌf±úÊág6èß< rv· šºì#IZH¨ÙÄŒC áéšô Néæµæ6ù Ü^2ÔÝú…-uÆ€Ã✂eLV8ΉÁ88¹sç6h ËsoÁóU5qºÌW®^eP2‘Ç -FÙ‰2]vß êŸÑ5tèÌ}¡~0ëìÃä¾{¹gïçt\ܘr˜ ÇÒ94Ê£²9( A8´•¶‰Ž û®‹îþZ#s`$M?˜kÊí¿/ìùü»¢‘ñ¶°w(­ÿ^jÿH’áîþî!aïpÆéÀ’œ®?¥œ<›#‹|ƒR#è$ú 2NñV¡H4˜…YtJã²"Ö¥ EíjÍãG§ÕÍåU«˜äåùŒ¿4‹Åâ->n/Dó¢0eR©ìpVº¦\Ø]ž¡‘ˆtÒ mIfwyºN p’¥•Š´¥IUùK° €Щ¨HÞðÐØÁb2û²Ããrÿ{ñuk@ú¯üïöÌpËF¾?–}k?cvMÍî—³P4sË5S`ÓöB¾>ßáçvLüó‹7^‹„s‰‹¼‘ÇúKS¶¥+ÃÞ‘déÌ´hóœí"»:yJ Ê+´j…f-(¬ÐÑ–üLs06,§²iN!“ÛÛZ½|èõÆcsxgÃæ¶NyÑãxô×ÇïðA™Dº}ÓV6u aÓ™lF†°PŒE¥³0ÇX$¨5•ÁÄß\¥ÏNx\'òtæ;Tû=jw´piSÌšä ÀÔéOýÝY¶ö”ͯ¯eãt(4aäÐ~ee¼Lɯ’%Ƚ4§¨ÞQ]½S‘›M‹b 8Ž`{ttÔ™÷~{žF ƒX’ûv´Y›ïiK¶w¦xúŽLi2žµ ­º¶ µÐÕ•aU'ùóÇ©Øtùã­N]æÅãñ¡4,„Å¥¢PÒ H<^Ñh/Sþ£¤Ì,‘›Š”e'ý©9ðCi씉ü”MÇòÖ¿id½—s|¬Dù¬¢v²T9^¬9¡Œ[J§ÀKY‰¡Ã'®ãåS¥²²ø8Èx,<”Rw£¤‡»ÊG«­åS‰ÂRQo.ªú¾id¼Da•*M%õÇþÅ~¹5u¦qüÚam§V×\Ïýœ$„{Ñâ±V[]*꺵uY\᪵¢‚$„[Â=€@€$$!&$@;³ÛÙÛOuF»k/»íîìÌvœõ‚\LB®û¼Mk¦Û™î‡ÎôL><çò¾Ï“÷¼çÿÿ=™Y|.Â"àõñÔ?*›ÿ\R•ÊÙ#™€­Gr+AIm³Õ]'2³¹8#™f^¯¬õ+Ûî+ÔÿQ5=¨ ×é¯Õ.TjæêÛïÖ7ß©¬ÓT­·­ÙII(aq8)¸€ÇÁãNWÈ÷T~†ŸÖ¤ûq æ è0† $ÎŒçÇ1yi«jj¡n#’Ø;ÔcŒL# ê1Ƕ¬Ð:!½‘Ìzc³ñø1ƒP¿ó5ч4õ†0“‘ú:¤í]«i]—±ƒ—’ñjÞ1!‘”È%„ÜTèL{”vê³Du›c´€ClÀÖc;­Q=–¶(­ê…tN¨o(¶Fµ653ã&ÀÌx )(–†iØ\_pñ¯‚pHÐß»ßlÞ¸ô|yN|Yݼ²$µÅv™¢Ï[¡n;*‰´½ÃÑ}N¨Ç é­Ñ]£QícNÇÙ”¦Šc°ù«jjÃ>jõzÝO¨ |5ˆò¸–pà>xøà l&£2Þ/+¹šoH#Ŷ©RçT¡s"ß6)sÜ:n¹´õ€!` å£ÐXÎ' t Em^Æ%wŽ8P;ÇáM{¶•šÄæÙ ˆLNfR”eC5€FІT»‹¡—†§:ÚÚ—Sx\îåDaHxÂ/çáŒ}†ß˜ÿý÷d˜êñÿ]bžg‰¾#´ßÛ.Q¯?ä÷Üœ¾‘”¶¡’HJˆràö#ÛZOLÒ…~±ÇTî7Ê=ƒùn“Üc,õÅ~›|^/õ÷çûåfy6ÂX-$yÛx(§«¥aþÞ7!@ °þ¿L_°ôÉJDÛßÜLšÅJF!ƒ‹£q(Ì) ¹ ƒœv#ó7' Š÷oÿ}ÕoïôŠýú¼!/hz òÐPq`¨Ä­/|d,ö˜K@% F‘Ç$Žäþ}¡Ï(ykëÁ)œ›€Ä)Ö7R7ln8Øõ~usvSë¯5uÔd%¾³a°+ ·X,'ê7=u=9Oñ,¡¼„Dmâý[Wê2æ?ìÉ ˜ ½±Ç [’pÒ!ID1–úÅ®¹¿ÿXp¤,wçúµ0FØ›slë6O]ï]Eýœ²nN©~¤lŸStGróÏ$½Á`­Á˜ñ8bÊ‘ÎÖv?¬j} ÔzT=w*=Ú…3unUûÅ å.B È.½;-uòTÍÅò3é z™mI)›“…Ÿßo=ïUj½§5‹Ê¶™jÍÚ–9EÓÿ›FïU7.ª;¿>Srw6Ž£“µ!=](ÛCˆÁƒG¥³u JÍLUユ®«§[’¹k˜/ÿ!'ß[Ý2*lh@2s®ÙuVãR´Ì©;Šx´óuí׫{“Ò’0hÜ6<öñÇÞ o‰ƒÏ£Èrü3™ü$Že_Þ ÃV>Í ò¡¹ôF$«z-P‡y….|Þõ™BD鯢µ¨ß´êô©ÕÉi<”Éy}çê‚Jè\#T\B1) ~/: ÆWçU°™x< cœÏD¨5ŒÕ;ÞùE“ae¿ °ÆôY£;-1:;ÔmYÑmW¢u–¨#¤‡ºœ1ZklŸq¥¸8U"ŠËИÝá  ñ«ÿá4 õ‚ÏíùºÛšh3Æx(±f×¾¨¾þ¨n4h{IkŒéºØÐEF²ža¨×uY!£-诈‹i67FI.3-5åÁ‚¸I˜š‹a .÷³O?–åS»Íf œJ¦)6™TØó'ñÈ é'·#º¿s:ß~E4>!qNœ°_{óp‰KDX$F"ü”íæ¨úvJÏrS¶8Égÿ’Åáî>ZôÑðçRÛ”lük‘}Jæ¸&w^ý±hD Ä1U`»Zd»R ê—2û¤Üy¤“8¦ÅãÓ¹£“9¶¿‚š‹œ“eΉË•ƒ sÆáò¸ôLŒ I æc\ Þ}%GI­ŽàÀÔh‚¿7ëÝãeå†Aý—.ÏÜðÂ;ù‰Sƒý¼+ó-Åã0X,œ¹·ôH™¹1è\á°ªÔ¨”"Cu©¥¾Ô ’ T—šê¶çdñ(œ`p@—yñâŧÚõü;ó?¯iàtùÖ ï¾`—-O‡Dzæ[Áw3x½Þ§W–iö{†–h=¼8~O(°Øß§C`ðMR¿Šc|ÕÿaÐ,sõå·uenƒhÑ$wË]ƒb·Yh$d* Jþe¨ØŸN€/—O' °'€wÅò0hPt4 D„ppð¾Ø4±VHÆ#”¥‡™;’±“Yice{oµŠ‡Ê<rß ,<¹±`q@ì¹ôE3:飡R—ùļ±lÁX*ñ$ÁÁ¼Hî0É­—Ä 6D¶$nTyO­þMsÝzÍ!  ‘–}­MûšÔ‡êŠ3%ñ$^Ç4"“ÉÀÂùŸ/Ì{s3 {ö¼ƒrYŠÏZÇSØTö?õ~³Ü£Ë éjX’…ï (R=³å!ƒÔ¯MR¯>÷R›<•àK …l”õÇü’…ÚÖÙZõÝZµ«ºm®º+’›ß•-D0!AÏØu¯ª#¤Ðz*5®š¶‡ÊÎye›K¡qWÕ‡ê;ÕtŽKO¤19¯H*Ol=ÂKz•s !í‹òê»§ëæ:gU­÷«g«›þË~¹5}eq< ¶ëLë£I~ä—wµÖEwµuuݺ«[|Œ]+’@" õQ‘G@H„WäIt]÷]wÿqwfu[PÛ¿º£]D$wBöF¶Õ²SgìÌîLÏœÉü2÷þî=sÏýïç´ŒñÊ'¥ªo›FU¨CªÖñꊈ¼îÓj9’õB1JÉÄMñçç•aÀ2é”D¨j˜‘têrÿ®ìä}‰*$o™>[ ˜ä¡D9%möÕ4úeM_Tȃòæ™ê¦ëäG6dÀd¥RWzCss(’@âx(ø•;?ï#ýÎþ—m.Ió“º0ÐQ¦ÓÙl˜§¤Ñ7,­ªzEÀÀµ° ÷,ÒÙµYqÏbm?NkÃé:R¸"f¥â×ÜØ¼×Õ²êÄÙ× Nàš­8ÝÅäfýª‚£,)£SYdxk®Q½¨Ý‚ë²â:MÉú¾$°ˆÉ‰ë(Ò‡3Ú—´˜qŠ´}‹[[|¯»®Ÿpß»…®›×°´Øs[à¼#´'œïù´È}Wè¹[êá¶ÿþç¥õ›öÆÓÒ| 0JFè$„*FfÀp”ÓÈ JF£þ0k+çØñZ‰lÀÓ?62†@6û«K©+W±h 0“½i ¯­¢ÌVwÜTÁsHJM5¥ÖZMVb• á›jÄVùÛûÉ1D}åÊ•ÿ|U~Ž4æ§é)Ū➴罇_ks{¹|ÃSñRÕê=+õÖ©Ç% “R€"jµ*TßüàTÍlMë}Y›ro.à–„’è"pà™ÉC•²ÈÊ™J¥OÑú/©òÞy™W¢þ°¦áÛ¦‘éZíC©"p¡"$«‰Ö49ñP%cL íd§Vi|²¶iÝƒÊ ŠúøeDÒþÅùzŸT3#i—(ƒÕêxeãTâaµòA¥b²J("ÕÜSh9·€n…D¥ÒhÆ,‰I5>–Øüæî;ù±ØcŸKÜ“ö tšf»i=‘€¥c«,<-wæÜ2ÝÂ4ÒÝ·¤Ãž¤ a_ÒÙªmq­h1§ ø¯¾¹ Ÿ-£­ÅõÉzÏR•§s&wØ’ÔÍl(%“SY 85[“±ªèäâ6KBýõ½¯v¹+ ‹»ÀÊvœÎ‘`’¶¨$µÛ“´žEº_¾¤qàzËm/oÙM'3@!‚©Èëëß»>ù*#(â…ýþÂÂ| ‚(2ÂåÛ¶/mïZÒéÆu¸1èz^êðàº=‰à8‡$!:[r‡ci»k‘F÷Êá_°W0J@=?Û v™F"³ÀKáX8þL Îô¼ƒ),˜H£`øõo•;¯•|x›ï¾%p.¤þe½#çhѯ?ã[þ²#G!1H0†¥¯ßþ7¡õïEž±|ÏÝ÷ís—\FÞÌý~6gË{bÛµ¢¾¡"×pqÿàŠóú‹¢‘’„ƒ5¹}7ìáI@H‰ó ¦b÷°ìèÚKz‡Eαb×ïÃϸ®®ã:˜#îŒòz‡ äºÝ…gÓwLco^Ó` (•„<`‰ £€L1 hx)dlçŽmÈÈÐ&€ÑÝy?)s©öTØ+˺«Df©ÀVË5V á[$B£ô§…¹d">ƒÊ„H¤«W¯ÆŸ‘uPÖ€”ÏçÙy67úì+Ϣˋ²gùä9 ïl,ò¸J S„@èà¾íïâÆM<ŸYàLbáM‚°¹ dLâ(ÀgJÏ2òã®÷ÿ¬,åoco",M'Q<2ÐA@‰k0”I&ÐÐå´eÙ›éþ¬Ë§Þל÷Zx¾¡Ï, DA}qP_1ÎöpâzA\/˽–ÓSö3ÓÖRŸ…´ä‡ ùq[QÜÆ ]Ç#AÌ"Ž˜Ä ©ÀZ6ÑÍeÐI *‹¡ÛӷɲUMûërTʼUžB§¬ÏV+sZês•ÊCŠ­™¯c0-†as5РƽXüú‚‘sgÎ2Hšö“΀êÑÍ´!íi$¡îcq[ÉŒ©$ÜS:kYŽf§¦:ó£Á´¥xÖ^Õ½×-~‹Ž‡”E¡@Ä•†G?¯VMIÔ* «9L‚‰L*“ÿITá—h¦eŠûRùtm“·Z |F–l¯ªíŸ꽪Ž{Ò&Ù¾¼ *€Ó60)µûLH5÷«êµª@Mã£þÍ~¹5u¦qü`Kµu:ã,Êå$9!7Pjµvµ-nu­vÖêŠk©V*\H‚\´Xr¿C¸ „„KnPºÎììÎì¥íº³V·."xٶV \s%Ùç—í¬“љݙ¾óLæðrÎÉ›÷}žÿÿ÷(f…Ú9¹aJ®Ÿ’h§…jPû¤iä;‰~¢JíQê¼ç5ÖãùIÄ­ñ€yX FÞ¼ÍÞòÓ±r¹W¬R(aÜbÃäð†ÿ‚Ö+®þF¬†ßè-ẄÕóŠZÀ§€²nF¤ýBVS²ë (: ¿´´xqÉÊ °x»·\tË¥ŒŒ'P…?ŽÇ6€? [:©‡j†è I}=–­ HJØ”+’G¥£1˜c̶˜ÚÎØFûŠgL0‰ é°!Í®5bCb™0¶¡ ©ë‹5:cÇSuµ‰é;ɉäø8Z }S:FNLÆR‘Êê•õ–çê­ÏKZžt•ª}UsolcïŠbê~ªÎŒóI› ©·¯hq &Äâ$— 1F•’OEIDì¥õ›o þàÀ· li3& ë¨T*‘ÄX¹>=¥H€˜;W`Á!ÍÀHÖ§ëH³íà®hûÐÒk¶ÇÖX‘×3"U2! ü2‘~™ú—/GÐ=×ðI#SðIF£àLd7¤Péà8ð¯}Çö3-n[»[œg«*m¯â™ª€Fð°Hò­b¾UñfÞ‰@p¤RÇ÷µë¿\þQÀx”7WSö}Q]n÷–Ö¶<ù( Ežo¾@žŸ_Èc±"IÂ(tõ‰]A³ lb-txz ¬@GAÈúÞ¬‰ç1ñ¹+gÞV4ÓÎ ·täNuð'Ê®8¶óäÞmY;_zûg/ggnÎÛ“¦ÎÙý‰”ußTî³¾<ã1çøºrBýÑÝ/t@#úc:Õa)Јä Z™U«ÊÒKI÷ìÈd’V¡Ö._¹âõû#bè ?”èJÎ¥’“é$J…ÊH"°_OÿÊXî)t7 ô”ÎY;Úzü­Ì…Þw'ÇÓÅŸoç…[Oͼ–âT ¶;5 ÝžJûö|¯²úBç©¢¹ùz”„1hôD´û]îd…fV®qK”ž”Þ*Õ”Xõ@¦+¹ð §èO%g~Ÿ“çW{„õ·ÊŸž>ûϲª¡2X© Ÿ×-Ó-Õxd…n¡R(2!×y¤ÕÁrõ“¦‘ù ¥¯R7-ªmÍáa$Êê ™@°à3÷&1€àw¶¼p«Bég…53•MRõ™z®R àt_¡wKu^‘fZª™kŸ|Bµ»R-Ýõó41‰L£6¦Heegýa´wÀã áÅùˆ®>Z˜?¢ÈÿïðûýpªÝÖ.¼5HBAÛ1”˜Jc ýsÆ¾ÕÆÕO·õ ëêÆ‹ÑÜye}Òb­ï‰ièD€C>Š1¬T5e¤¿H"ÅmAQ"5©Ð®–6¬%nD_Þý“â²gÙg&éÀá-ñ k¶¿ºªÁŠú‘¦^¤Ë£7=ÛØƒt¸Z˪ Ò܈4wǶ÷Ä• ã6lI§’ðbÏØö÷±!_È Ê ãù„R6¢9‘9èr>v˜ÇÚc4[èÉéŒÄäT F‡ɇ•Gû]Ñ"¶¡1ÚÖß Mæ¸Wv¥a(Ø! Káóù^/¬'¼ì#KžZÄÙ÷ˆ´f¸{1sYT2}i-–DÉ8ÀdÙ/³~=Æê,¶²ì×£¹¡í3¾ëîû¶ñ\×-…F'¬I%cYªîû w`ŒÓ?šÛ}M0p›i»™o¿Ãv}•?p›Ûu]Ð}5pó8`CßM®c híæ rûöÛ=c‚‡Ùޫ޶m´Àu‡Û÷vß]–ëÇ1¨PÜ03XèØ®öÚoðœ7€@àm‹j¢þÞÎO+{÷ ä¯å¤g¾A¢¯'’èäÄT1…˜´‘ŒÒ“Ö¦âa (ýE ³Š{¶KÏ´Hs,çø½ü6«³ªÐ*ᘅp‘]ÉI¦  oàP ‘Ôâ™ ²ˆ×h?’NKf±ÔŽ-åRØï ûÂÁ@ØëÏE?Lü¬~ÿBÄéÂðä¢qÉ좎ˆ”ñôÀˆ¤„?’7¡` ’*x|xyü0ûð}ÁÈR}a|5ÞÈ÷à3ÁðÒÅR@ãøñå¿þñÒ¥šÚº¼S,ðY0n@50ˆÍë?×°ç-œpûÉÅ6¦×$ð´ ‚&~4·ý_‹P÷·&ƒLb$’hÄu3³ ‡[‡dڃͽ,K ¡=ªÖQÊ©P½­=ôú[Œ: ¥Ç^½úY(ôŸ#ª\ÆÈÒÒR"‘H&“!+­øÄ›vA ÷ÝÙŽÇrÎßšÿC×yt+mM\Æh²ÝïLÊUs*ÉÜùf·X7-ÑOеӲêI‘fF¬ó)êÜT^Ë„F©”¬í;&uaIÍDyÕwRÍ}µhZ$w+Z¤û³A–1 emÝî–7>.Š˜,Wxåµ³ýTUdIb-\@LŠªç$u³"ÃŒH?'­ž•ÀÍÚ‰Ö'“»EJ¯¬yúý´Ì0)Öø$:PçÖL ußJªËví¦añ¯Q°?}#W<Êöî!¢Ïo@ã\¹‚ ¤Ù}N>¡ÓÝJæú±_çAMÝyÀŸ®e­îŒ &yyW^^¡ žUwëY§­[EDPÇcë‚áH©‚ ‘“„„p#÷Smgÿ莥íªVäÑŠv»Ûé¬VE @Gö÷’Õmÿ°Sgì´Óñ7¿ù dÞ¼÷MÞï÷ý~¾㙺ÇbðÄœyÞýtÕH¦Ô‘¦ù&E“¼e»›ƒÁ(ø 9uê”ÍfûÿéùÚ_ŽßÒpg¼Æú ‹m& æ»vv–Ò7ÑÀ(«œ]m€t ÏÔHQ-TÖä*ÓÕP!IÓmñü÷ \?˜ãÃg1^%@uy¨K^—ë&~Àž޼Õëù¬Å>¬‹Vp^=t*3Ag¬s”u@2P¾Êm„Êͳ L³ÏXçY ¢úßW,ˆ8ÜœÁDpØ!—.[Þv¹ dꉱ‰iW»CçõÉi:³ON»s»«08§&èF¨¼ªv‰†3yl¦“d¬ÚiÔóJLÏ«‘ßWÏ*6@%u¯EŸ€¹ˋ•KV ¸B ŸøƒîD8nw%CPA­­­çã$— 39Kþª¨µö„[®=;ÞÜmè}f6v Œ·j{„g{X(Ê#Xl&z ïoÇ-ý‘Uíñ¦Þ£–>ACGüùþs—ÀØqÄØ—hí ×èÌ'Œí1¦ŽhsŸ ¾'ÊÐ+:Û®9RÛ'n1v‹>¼Þx3ÎÔmè€ "›®Ó—™o{­ýàï˜Æa½ÒZnüü܉0ß=bºiè5ö&šºë[y†¥Wn‰HYN¼±Í‹·Œ…ûR\o>†óa`B.‚zòWQû’…ñÕŠXCzD剸yTµ$¾.KP)Ž®Ëê’‹„Ù`·½ógrº‚ƒ30j<ýæì.'ÐTpí¨'5kzbbü©xGè>Í9þd>eÀ” $´%€2?Ö¦OL¸ï<9AóõÑÃÁK-í­—[ÚÚÚ®\¹rñ—._j¹ÖÕ=2:æºÈAÈ¥ {ÿþºçjÛÅO>þÈbÈS˲³$±‘á‡ö†íܾme` —Cà(ÆCx|”D^<Ea/o‚½H?tif蚯*ŽÛ+#‡'ÊŽŒUÅ×Ä;ª£qfüÄ9Y]»…<ãã¬Ý›iƒŠT! mpŽr—J¦Î –)‚幡UHvV°bû›ïù²ùÞ$·Ï>k~’!¦Ÿ:ôà™$%%ÁƒœäÂóÿž¼Ë^-˜j<:VB?ôyã¼I ¯ó0Šb“kªíXê0°‡$g(] J?¨ï£r=ͱò±$Û–‘c: \Ê`ƒ–£DNP؃¥33ï;©Ö‘,uÊŠº“”;øË ã°²í;dè^”FÜa giŽÀ¿`ŽKtö4=C;&ÑØ$4E‹•à+Œ¥ÊǤWã%_žVÛåE#)²‘ ÕX> VßÏÐŽgæÿK–›¸ñ­OŠïej†¥j[†®35+áuÕߤå:Nç:…ÿ9>&ËùîdúŒ"ÿaŠ|X¦JËžÎÐMJrîÉõÉo½ã‹¢^Ì%).‚ sSäû€omrròE×ãW0\ùÓd0¢l¤hŠ Ë"ÀC¡„ +gW˜ }9TQëQôLÌ*ªJ¡bÜÂêÙyePUÍT s1û <¾§ ÊC_ië ãœâ(C¬ÞÀ÷b€gyÁ—¿xÁ¦­¯j æŠä5BÆWôUót•ó*Œ¥FH n{~ŽÞ5AUæ¹gæGD1}—R ~0ËŸAâ0‘W^1îþ"Ž!Ón‘¸öí´«uœšv 5U—Ép&ÉœçO¡‹x+_‘ifÕA¥ÏG0=ò­¾lnqì¿ä>ºÐ)rÿ…ƒnsݬ4JìcNW{k³ÛÁúæÚµÞ8FÁ,æ³õýc'MW¢šº†ëóõHCW¼ñ™U^xîv¸áV\mw¬µ óÄQ„@øaéU15Ǭ‚š.Z–뇫ÛD–Î8KGŒ©ÿƒÆ‹~[B¸Þ«6…†j£¬½ –;1çþ i茳~%4 Àš® -·E–î(CG¬éÚQsÈÐ-4õŠ,·bΚnÍ_&œ»k¾ˆ‚z~n„7õEšo L77ôFnˆÎßYÂë{cÌ@D] ¦Nà“¿dVn‰ò[¾G½}°Å<ÃØž+6®;QªÕˆc$1.ˆê2Á]—‘T!§ù$†¶ hp|dÄá°[­ÖAô¦?mf2؇Ï'IœÍÆ`˜€aŽn\·fhÈá}{wï :¸¯J!-ÌÏk¾^ûù§¾ho¡!Ñ~õÓÏ/µqµ­µ½¥¥¥¹¹ùG)- çdsóŸE^ ŠCqP‚‡ÁôÄÙ®‰rØ,.bl&£8I¢\ÁžÍ€ ÇÙ˜7û’ÆXH"°DÌF`º¨q0I‹P\Ø$lÏå$C°có<‘½>Ñq&ÜYi+‹²ÕÄÕŲû‹3ã'Îéê8Ùþ \çc_‰Ø&ÔîÌËÞ­ÒìΖ»4"Ý©ÈRæ†èT;Õ²àì ËÖsF‚ÌÖÙÙ199A—0W‹JÛRàÌÌž={( ãQ>”çÂ?r+–¾?Sm/>oœ÷j’â¶4ÂdÌß·zý”¬f8S:,Î:­zœª|,V„€ê?˜¦8y(É [€pÑ(ˆaEAûï—?TÍ,n;–µÛw™?ß'ñµ8v9Yó¢4â¦XDzhá€ðÜó‘X1˜¦“éF¥Z@‘Ñ Í°D=š©’|rL¼FÂWÜMV9%z[ºúk‰48p…tãÛ¶Ì\˜o3reéÒÂÑ4åhzøðÛSªG©¹“²RÛi ЋM®JSŠ §*ÀýH”CYšád¹S¢»Ÿž—²õ] õòäc‹88â¿»õí‘ÁA÷ûzÉßüp—NzLÏ€&‚Í‚)œ.óˆ·¿GZ*TZý—ýzjêJ~Qëªl§ Hnîû•„€(>VíP´­ª[EñÑÖZ…@J}" $<„„‡„Gxò*»£µ³³ÿlgv×.vAå¥ÕºÓ?vv[ª$<²_–µ;ÝwêL;éôÌ7wΜ{sïɹ÷œïw®Ì+±úUÔ=5A×X‘j;rÉæWÕ–@Ì ôt°Œa¸(Ï„Ø>@*ë˜?76!Wƒ”ñË0iˆˆÄä‚À.G*+ˇHYý¿nã ë"ç§ŸW[TÛæ]´#•­H­ ¹hCÌö9—jü)ˆ°U”#IRÂòáèNlëN°vÁ£5Î~¥­[óþ("ÉÙÞÕsÒü»)&FXÃ3<0>Š˜ãÇNX´ÊæÌKžÆ¢S6dª[²2OÔæDFofx ù;+óW¯lˆ$†(*´Œá9œÂ) N-£h¨p$`€–+¤{P4KfhР„çÀŠåIHÀCÚC»L.ìžxÚ¤›ô¹κ¯ýñ$7€ç в$90 á)³Gš¤x‚a1J Y)ÍI-$#ûW… X–—R OSŒ/ £ϳÜjñâP<'ƒ¨€5kÍî•—ÏîžjO›hN™lÔø4Ò˜8R«<|ôqŽa,ÛèÎ0ËØd< §õÃi…c9µ†Áì‚ù†ñì’¯Òò€"pñD–q\g‚úß3óOE½‚áKe4ÎsÎìØôÚÈø˜ÇûïmÝì+›}w°Ò~ÝòSùq”oÌJ¨Îx­-­RABQbÅ!"YëŸSàWÞ‚”6ûÕØÿFæ\r"Äl[XnCÊÛü.Tþò`( Û4ìÕ-HiRgõ/®œ[÷빩z†“,‘ã˃Q $¤btÅ&?mRßä_l]¼ã€„g—á¶þ¬° ©´"UíÏU6Ì©nE*Û çœò6¤ªÊÿì*,JŽRXÊ)”cŰ|}ûÖj³ù£O:½“Óð—úúmVÛ»‡“b\D¡Á!TŽ1$·D¶zAºvaE3Üp~€ÄòÌ©v.Í/FQ.„Åø RÐUוñ'£:;M¾1Y<£põÌŒ{¼!RY¨À¡AAG¶'%Y?Vwøð níQwô)]=Im=OËΑÖÎã®{ [ÿ;ºL& \ÉN2ÿöœýzJ[gŠí–Æ> °ĵ}ªpÞ\¿W-AI)E¯{ýð馕Ö Ê/ÞLÙ™¨Kª¸’ìPwÜoºžlïQºîvÜVtÜKpÝQ9z“àøÇ×™þDÇ$×ÝD×íøöžDGœ¨m7¿oh\Àžîø¶.~ì= ¶^% ËuûŒãfrû-…µ7ÎñÙ‘ö;ÇÚ{“;úÕm»ÎâÒ0†"ŽÛvloJ£.¡)Ce1$[²õi*kV|}FR­î@ª"ˆAy‚†+) ãBƲ4Ø#àíEIhh!>4‘ÃEršð¥ ÔAø~B3&†Sr &† ÂXBNcàL†ÂƒQtêéón ¾Ž™ñ™ÉÑ?_û ®àCy‹ Ä,ŽÃÓ}¶¡YÀG±Vi0¤/ÀI \ا 8´À·-d(-#ƒ£B™½Q+c¢VœÛ¿±èÈvgÒþm„9Õk9ím֌Ծ;n‰›hˆóÔ+Ü šÑº$OcЧ6~Æ|ôgÆ·¦÷ö®“ʤ¡AÊ !û ®8¦ÔcÊCÉ.0Å”˜Þ0÷L‡Lgv¤rb˜C´qcÔ,Ef¦½ÓžéÙuâ}’ÙRZV&G)' ÂÙírÂcM±ÄNÕÖ~NYTSͪ’}/°Î r‚ŠX>¤-Öú²³'§’þHº<ð(»èA–òþ—ùÅWϦ­£ig0®%ÂI § ú¤_¤Xë‘ÄdÃO†² ß•Fåçøî .AýaŽ~$§`D ö(y¤3ŽfäéK¾ÌÌÉ+Ì(rŒdêò†2ŒÃú’AmPdò¼a\Wôyᅌ͛ÃAþ,ƒ24'¦lÙ9>4 ™òþg!ý:aýT~|eúß¥©Y ÏÈ(LQá‹R4 ê[‘ªŽ§fçʦymsËÚ‘šÖùU.¿²ÄìðÏ- zñe˜Ý˜ Y N}®ÌîWkó׿R¡k`Ý¦Ñ ""ré·ø²_/@MÜyÀ#Š:w½9És³›Ý<ª¢Wí€ÏVÔA­U‹òÊ;”„y‘—žæ $!Á«½Îx3w×ÎÕêY=AÄÚÞÌÙ»³7UÞwrĹv:ÃLi§3þç?›ì&“ÿfwÿïçOè(LÞŸQgYØìX”Ɇ諘ьåû34YÞ‹TYÑ`Â5›pMíK\¸'®½gi«™P ¡nØÅÛ€µ*…„§Œ€hkÈØZ*“F‚`& Ê™F¤$@Œ5da!qǹ:²­é¥&'×h}a\l#mMg`J,‘†:’“f&˜›ß¾…vŸÏ¹Á!o(\z¶ä†`ú*êËÉE¶Û‚î^ÏÃ\ë€Ð>"^ôûÛÐ|é,v rí7yŽa®ëÓ“^Ë.@iX,i^±7ïH]•´—ôjªØôgk€ýîgWˆ¬±dj4„åè‚ÎÁ“ŽóG bwó7Gê¯fÚ‡ùö!a׈È1‹ Žý~®}ˆã|ÀsÞçÚ„ÎA¡µWÐÙ'r ðºï ]÷¹¶»"×ýZ#p®a¾ktpb óììÎ;*×Uurå˜D9­ÐY¥‘iCç´@&“*ý¨\7^^ªªõ”©ÜšÑJ€ÐXµÆ]©ùBváôÎ]1Ä(:Dc2XÀØ»¶îôOy`Qœµû·BjnšÛþÜ~2-ø ÌæìJ!î0]ŠGã&˜¨é>–Áæ,­oŸ/6Û4w/m²ã.Hpu.\«+¢ÉŒÓ7G¿yè×láÍ…Hãû‘*#qÓ:&²VÂØªM¸³òÅmïAyg({Ó—Õi‹%x~IÄ…šHaáK¹EKõ‘zË¢Ö\ƒ}ñE'î’eA£iIS'Îpר½Po[hèŠh©[šÅY޽GŽ¡€Ò/T*¥ (FЉEãQ:¶á5+е„£ìE5šˆF î¢5²Å¹DoÅ5Ùp-ÎÕ¥°ˆ€Äc }h¤8*rýæíÐìu ~Ó!Áàó]° …=n¿ÿŸ¿B©4°®C©Tœc›”gï+qôŠÌŸtö‰]wÙ¶;Û]vW¿ÀñƒkÀƒïèÏïTëªÙûÅÝ…®{¢ËŸ2ñŸæ_~ˆ’×u‡Ýù÷üž{ÇÏê f¢2´í™oˆ:JsM%|“²ÀXÁ³Jr-傉È"dëR’À¡A€Ò’÷‰«Š,)¶Ý(îº-rÜôØúA=Œ[`º&ºôAFó­Êö ¹5µ¤1)Oº…+ÝΕíÈ9›–[ÌZ·™Š`d" <áà|ev‡fÙzoݸ! :ÆŠ‡£%Ùû|íù^³hÒÀ›2ò§ŒBŸõä„A0Ó.ž0æM›9^«ÀmâxÍì°Uà7±=­ÙÓÖ¢§-ü1ƒÀc)t·‹Ü&žÛÀž¹”çëÈô¶gyŒ¼@ûI·¡`Ò(œ¶ð<ݼ€™ãoq)tZ„~#ßgæyŒœß±?i' D2Ä„1dËêdíÛREºLuà¼æ J¾¿FyH'߯GGªr_ÏZ¯Ed<1†Éèí½å >ƒˆ6ï×:÷Æï÷?? ×êÔd29ŽÏD(%on5 š^øúxL¹a«hÔ(´sRWÃ$ŠÅãɉtìAIù˜J 0^1 €)‰hdD¢ž¨ÐKµîsÒ™2Ùc¥~°\ý!çÌUQñyEÿR5ý·Rç•égJk<íXyÍ„L÷}iÐh²Z4(ŒôD¢šÔ6|Q¥¼W¡»Ê/jN{ûCAÑ„²|:S­{Z¥|"—{«ôÿ)oeä޼ŒGR7n¤l U6L®~*‘MUiGË5#ÒÚÉJ¿úø§#•ª'eò€\?U¦ J&JÕ“Š:p|â¬bZvþ‘Z(Áa‚¸¡ÀûRöº½Þi¯TPИ«£¹úúNý¬‘Ÿ\óßÉ\ó{} ^?þèÚ†¸xŠŽc@ht4ÌÚð+¾tÆ5týý:jêÊ~%à‚GD!$ャÃRgTÚŽ¶u™ZµU÷j! ĵU¡„HBØ‚f%ì{¢cÏ´óe>h;:£¸¢NÏ©sÚ;( a™Óã™ãÎÑÓã=îyy/¼¼÷îûßÿï­;^çZ À›ÁšüSµ¶j'ÀÛãtv€Ÿõþ䜅ÄB“,mFù1€ûúO÷½ Èå J:…ž»_´  LѺ€Ù 80Úá4€õ& ³LÕxá9Þý ~ 5%h4³vîJ¢±#ó3 è(FI£Á5/BLKž›š’’Ìf'änL’”½cŠ9pwŒ:Ä .BS Ðx&«zæÛ³X,”FeÏ!VUÊÂ#ágXd |’Ï·£Æ …LJCáí»öÒÉ!R,kåæî ¼Ö…îëBÏ-~ûí÷å£þNžýZÞéï^Tóý?p¼ž«ŸµßÜëø¾ å äÁö*Wöò1zä~S1" Ã’²–w]º;³/EÐ$È¿¼Ï•ùλ¿ü—Àñ =ýwFÁÔm"¹ åÆ'–sé«vÂÊ 7a³–ää–4‰\Wa¹çzDgîpÝË„uos«·Õ·‹üWøþk‚–›…þn¾çÕR†°¥‡çï‚!h¹íÁõö@#qýw9Þë<ß5aà×q‰ïºRÔ9Tཻ,‡‡‘ç§§ TqË]ÇñBo9ßR%jþj¤À):$xY¡U–[¼EFT#¡}Áî£5‡]ßÎÜþ$ð½m?r[osZz`Ÿ@¯›ãï⺠|¼¶;yîëùޛ¶[|ÿu(¥"ÿU…þžb×e±ëÜüe›z&ƒÊHE±ðø 92Ž®F/œ?OÆÐDó‰oTæ“L…ù…¯Xõ}¹ì±"R£‡¤ P#Á Üî“U$U=ËÉ•?É”ý•uAÉË×ÔΓòÚG²HçGÓ©l$93y¶|ÛÖïªU*BÕu%Ša©Ö³C°š›Ff%%²Q¥¢O –*Fäu½•Š™:X)Ò*­í•Õ=¬ª,©‘5ö‰•}  {äê%¼©p¹ê¾XQöÁiÄDH”™NÅÐܵôõ†ÆB‘Y3’&Ï&Ò¨CžÖkŠüÿ´ÈX‡žvwv-Èz“œB¢¡‘¤†}bþá_©@aÐ>]s–pÊ4Ž):Aï'AçŽÕ{ "">iòhá!P{€Ñ5«A;;si6‰F¤ÌŒßv4Öè;€g3Ù§UŸJ£gÓ)ñ)É)o­Ž­2ü 0Ú@“~Ê)hýÀØ ,޽}–ʯòð6 ¶ ŽÈO\ É / ¾Î4óXMü§‡¦­ÏCÞ]øÞÚ«7MÛ͉?Q9£ÑàÏáŽÉªc卉n 2Ç4»€®ÏÎÔ[vlƒOŠ"‚ŠŒÌàÀ ô\U=w{T ÑMŸÑðø×g¾Ì@èD‰Ža9s¿ñ+ŽïÎ˪ÚÅž‹{u_/?¢{‹£\s çá9èØqê,2&†Íe,,°^ÜsæX@s)jVÆÉ^Ãûãõ}-WWì9ÁJIƒ¥P)d4ƒB¡SWn?XâýVä>_àíØÓþOꢥo’æ¡dfN…™ç½x¤ý×}‡ï»•ç”ì–.HžçŠ(ÐYäíæ¹»^µR Dž+‡}7!Nö·öð}—ŠÝÜ2]ïˆAãˆ3ºbá¶Éá‡Ö t®¨áQgŒÁ‰ÑEÐzãÔ>€{gèqÂûkèIôt*š°ggŒV«o‰·T𤬵)‹&™ÓÊ*cͧc –éÊÚÙjsœ&ôm@kÕ»b´PA=.€ûŸ!Ä9Sí‰S»€ÖýHh²NÕ4M=©™jÀãôxŒ®9Fg%蜱:_Œ¢È7YLÁ ¶ ؼ„z;hj:|Uõ¬¬EQ0htƒNŸR$B?çÎèhdáÍ h'À‰‰ÿ°_çAMžiÀ£b×vw§£9¾|_nB”«žkÕÕNÅ vue­Ö«‚$$!€ZL I¹Àp‡#9AéìîÌδÝîÌÎÎîj[@.µíÚ=f«ˆÊ‘p“}»lg:N‡ù«¾óLæÉûe¾7ïw¼ÏïÚÿó=dÁ㣘±‰iyùž[®çW ??ßÖå¸uÞùY®»3ßw krùu…M\O¡³K³½Yõ¿álÝÃ&cQtÖ›WRm,hëLØ~p'`IÂ÷ÏÈj™[ö®Ç6"?K9©ÿà”¾í`®út¡eFÓ"Âј=<{¯ãë4Ïsξ™Î¡`ë~z˜Ê¼[¨šTV JäOõÄÊ ±vP¡ (ŒS2ÝÐeé˜B;\¬™V™ÆÄ@MLslÓ&6‚Pñd&Úêr¹ç)²xG¾¿h?è6_dïÜá°£)(%˜¹žÊŽ#'Ä™pMŽÕ .\WeÁ…ð¨XbÇ™l’QÌΰ*×+& Ñh}9çbDü.$‚ÁÀð/KÇ™¼8“…°ïWQØ2…¾‹Z#‘€[À3agß ß¼ë•<)®¾ €«s¯ºýN\³Woó„K€0hMkèä`!ø'æVøW¡¸æ^Yå]Uí[Yí„àLnàÓÊÚ¶¥j&µRß°¢Á‰«p¯®j_Sc^ä8@ÇHP?“’Ceez&8¿¼ÍÍ·…+·ð-ÈZu¹Žà©,t#™Adn9>6pÝK®zÏŠ oŸÐ×/p÷Š|BODNÇp~RôVX”9d<…Áˆß»‡¢(6=ì¹–„׿ÊuÜÜ™ô.“°åЩ´–O2Œ®”‹ZaÝÇ—ÚzâR²(‹ƒ12MÇv'Ÿ.híÊm»Çmôe;þœéìÌn £‹nÜã·õ Ú{øž®åÖHž¯“çì;þ7‘·—ïëçù×> ³â˜DŒI¥h„´bQv£4ÃR ´ [d¹V9hDd+lò MJ2HEI ‘„Ä£ùΛ<Ï¡§œó…FžoLYDÍÂñ&Á{š2&yöóÃf~°Elà-¢©š³~37`=ë<ÆÓ{©ÔH&-ŠƒDÙÒˆþXyYЦøÄUþ~Þt{1†AŒP0 ¹|ùòÔÔÔÜÿÚ÷–¶éÙÙ™éÙOÿr“†¢:‹E£)O¾9cÏ[ê|gš2a"€«)s末àOšs;hkéT›B"#mé9êkþ"娼|F¢’–[#£2ã“bM@YñTR6\¤»ªš–ëG‹”ƒŠ2¿\e•†#ï2Háá üó·çr¾*Ñÿ³D;¢©zxU5.Õd†A©îR÷»‹E)ô •þ«HTþ.UÚÒyÛè”êTî}…î±LûX¥ýFY6*×ÍHô#ÊÊ2 p+¨2®ª†•Ú§%š Äð¥Êt$6£‘€‹1 £‹òrüÁÉ…•3çéù†îEû!·…g`áªíàƒ‡Io@2Á¤E„#L””xW[‹«ö„]?®q„4Rë’úØWü(D¨ì¶µµÍüü5›£ˆØºü°:Ûº£ið‹‰!öO²rpuvpEX„‰Fa /‰UaÍ83hÇ…«râ| 5•–—«a ÉZ –¬‘*ç «kE¥W{=¬Á÷ê¥K4„M§±€"p5þðûO‚ßÚf-¬u‹+ÞâFìÑ£G;6$Ð)$ £’9sÕY7n íüŽç¨¾§—çº *Èp÷¤·v ¼} ‘4}}˾#©"J¢`‘:¬Ô]ïðs=]'¼_óÚ¿à™<¤øm‘„ƒQ_Ýþ6Oç(ðvfú¾Ø>}ý¸B¦€Fà^ ¤&ƒµuGÒÛÜÂLûÇÂ_÷ƒyÒÛ?Ooïâ¶÷r½ý|ß½t{·Ðq;ÏÓ¿ÜÉñtƒ»ž˜/†³ýusò:!œƒÑÉdBÌÞÍ—šUÜÆ«B§"Ó&˲Hù-Rа$Û!»`‘ñ­²ìF‰AcƒF6ì>pÅu‹ëÈôݸoo^häùÆŒE8Ý"˜jæC2gA@_'š.Œ7fÁ!}ê˜9mÖžt¾?j~fõ×݇bxb$”06/™/=*$žûEì¡X‡g1#iôH,†ÅA‰™L2t‹/ãw“g´ÐÑ‘ÇOa»ÐX‰,x#æiCÎRç;Þ,šlâÎZA_Y£µ©3ž‹ê;©"¸ý11ÿV˜ž«‚%å#’ò'Rãrkd¸X7&¯)Õ+ts ÃØÅx±òA‰¾>.ÑÝãCC‘hû{"¿Ô8#5NJ´`•b¥¿Ô8!­WŒÊ4c2£_V5(Ö•ªŸ¨Uc*íP‘ò£ì+ƒêÚñ’Ê€D;¦Ò#UûK Ó%†€X?R=Ƈ…²i™_]ñPªù‡X•÷Úد÷¨¦î;àW¢³í¬‚ǽ7÷æ V¬Õ‚Ym©U&V;»Ú2ä‘„$P䕈 $€Hò"︵gÿm;ÝÐõt¾@ª³ëv¶ÓÍHxšýB¬óŸ¶‡sô/ùï¹çæwîɽ¿ïÍïûý„E&ƒ­‡"äâò²™`ægŸ~;¡sP?C…ti¼Èü BÇGsóS>¿wtìÀþ4‰…1(Lx5 “b6§Fž×…i/FžT°AÀ$$€"Áa*[„ÚuYƒó*g¸Æ)Ì‘ZëªöΗ«ê_-*‹R(¢ …(†1èÑH qÕÁLHk„ ½+$ tbb•üFô"ƒo‡p(ã•êÆ• ¤uƒ¯ŠT˜—×ä@ O˜Òº\a‹RÚ£Tî°7ÔẠÁÐè!ÒtC¤6ƒX´FT6Hk†Tf¨Ã¦é¶§Ä¯#¡ œ‚ œ<6è)þÉ ãŸ6<ø/ötÁ|yyùkF"(±cÇûE½W Ã×íÏÀ³êÎ÷ ßu“ëìç{yî› SÁ¼3«ã–Ìérºœ¿jŠß¦ÇrG QùÕý:ù\eý©Ü+j{Þ—´QÜ5LÖ4ÍJd>±Ì{®íRÙ¬´e²âì¿Î6ÿ–SF&’¶¬§ùEí3"¹·òìÃJ)¸~R*“¶ŒV6ÍžiñŠëü’&ŹùªÆ@MóÄ1¸À[w~¦^3Q&›«hžµŒ‰Gëä£âÆ ±Äl•Ü/‘?ll½W+óŠZ/—T¾GG T<†„cÔ’ÊŠià ó3¡š øñtE]/ø˜þŽ£¡]Ôé£ÉÁ½‡Ð82†¡  Œ1Âë)´R;–«ìHm]hÜÖ`¨¬á •wXÃ5.Hi…4î…jï†tæpKT-‹Lz‹ôÊJ&1&:õ`¸Ú)Pë$9•ÂbP×ESqZ4‚1ië (¶æµm/e –·é!å‚ytHïW»—©]ËÔp/He‚”æà xŒç …e¥Ò ˆ¡r.S:!…R¹ uÏ¢5Òa”&Ha…ôÖU e±08ŽLظ!ñ›¯ÿBûu̇µ’Ð$}}}0 3a2¨ `¯®íÌöÜ(´ óÜ·³íמUw.pô ]7…=C½C|ÏMž³Ÿg»Î5_Éé½›o½~Ò1ȶ òL_¦ðDxRÊöÔÙ=7=C”k’öd ›öœÐý¡Äô§­GØ (X%yOúIÏ𱞲7’ް (C)¯ïýè¿–ò³ÃþÂ3~ž.qîþä3å£ätaÆéöã‹œ×Øž¡Ìžç®‘<ÛH¡ë&ßq­øÓ;Çe.Jü™M^ûö‡ûÊmÍ9]›4W[)0×òô’Ün‰ÐXÃÓ?ÖHž©&ß Ý¶P%%Å)l¹“ç渿âØxž[KyÆÑs‡‘?Ó-áï.œ4Lé²fÍüqCÑ„åÌ}ñ¤±pƘÿ¨;ïû¾§å“}T˜€“„ :;Åâ°5ê:%Á0LŽ‹gªÕJ¯×X°G¨|ý?ë ã+ßÂK›žcRé$ŒN£Ò?~“â7/v½&ÞŒ.^ÏË™3ä<ê:î·• ~N'¯¥b Š%Ó™w*îIê½ÒæÉš Ï[#Þjù˜D6*n˜®•UÔ{ÚûJ«[2Žý»¼<À}i«ôý£ëNg¥oy¨ˆÂ×xááYÙƒ*鏸ÜqÓ¸´mBBæ«kÒðIå£åuSÒÖû¢Æok[¾­8믚Ê+wi«möÖÈÇDMS5Íÿ5ü§ºÞ_Ýâ«UþîdÅ.:ˆ§Ä’qZ&ªL?ZØ wÌ4Î~׆–Æ‹<æ'µÔçó…Nf§gÓ3¥§Ë(0þŠâ•JE˜[ÃkDrãJ¥=H@µ  À…ÒØ¢±¨,W9¡ &¨Ãì懲Q*31#—JÙHã½²ö°.gD»!êi$˜Ê3 3Vs¹á§*™)éDœBù§«“ßZ]Ó u؃æéèò£ ÈÇìi€vº¡N¤^‰Â<ªíA™€›ä)aJ÷¢5¢5CÏò6ÇK²˜Ä$м(Dð8¨¼IÊ €ÇãÀ‘…BÚJ¡ypÌÌÌD'Å(¬Í‡Ç—…½_å®ñ{†…ŽgÖA仆¸®Á\çp"pß*tuÝôŽZäYŠ.ŽÙþ|Òr9¯ërŽã:¯÷öNN-™ˆ1`Þ¸÷]nÍÆ¿¤Ö±xó;ðÍWy¾á;®6íÀÉd˜JÏnpñ»¯ œW9½ƒÝï“ög®%%P°x¦ÁD,–@KÜ}èPYkñoú{úŸ·Fò-Cü‹wÛ®—:.ÅïHʼnp(ñœ±s§©”ÓUÍ·Öå›D\mU±½g¬èÅ£$¤‘\SMž¶&-ë0x¡,8–L&§òkŽA®s¤1ß5°¤‘g>-gJŸâ3 G»x^`ÊR:a’Øxi[È ±aGwÑ?è© ´ÿýrj*½øå¡e·nÝQ„$7777OŠ«nwguÝnëÊÚQ׺u¬®/ˆ@Þyè. !! o „< /ò m¶Óç´ì–UVÅgÛÝéZ_˜„@B·_¤KÎê”íL;œ9ó%óÍýžç;çüÎÞ'M¢ÏßJƒ“™…N%Â(Ê@™0%p•JÙ²%»¿ßãóùbµÀtì†gøã¿U O1KNGg†>Ä„„PA[ôΪ‰nÑ|ë3q'»DÓæ¢) 7¨;„[ŠzßV¸c 6LBa¹iÇîÏµŠ¸Ÿ7ŒW5M*Õc•ªIYC°ºå\±tK*…öò²Þýœ±ZµÿDzç&#Ô÷Ö® «4ä1œx «Ô6‡T­Šú±ºöß);+þȼ}ïǼâ¯duwëÕ·kšîU7†Tmþº–¿W©nKk|Ê–1iý¤² “7ŒWÖ>hl¹§jöËZ/8¶ÖÃD ƒÅ$ €÷4ݺ‰é0°pàãÑȬ½…ÒAãÓM¶ ÿ÷^ìâ_§×X;¼5ŒÏDJŽ–‰©™KM!°ii(ª< €d±@/¤w©<ð€¾/©Ñþ­ ŽxMo|»=AçNjwhIÒÙôPaq’ª}±n:eN[—L Ñ3ÄÌ%û nÔuæ¥V-Š~—¼ä%:í墊„NÀŒ[­/tØ!£wÑ)oü)WŒ=Ÿè,qZk‚Æ–xÊë8¤±Æizâ;­ñZKL5ÆyÓHGÔî‰×övqH &™ âòƒõÆýâæÜ$455Ço¡Ph¶8”ÇãA„FWDÀ˜ksôgA²+² ç÷=#¥öÑg•…}×A&Íï»z¸ïj¾÷:¨s”çå{>)éû”×sŽ{ú˽Λ|ï5¡{¸ÀqµÌ1|Ø}KâÚ~ 7%’‰ Êf!)LDh黎ªÁpљ뻎7ƒ˜Ÿ “Øk_/3–ôÿ…ëâœgoã¤!X!… /OGV¬&'¯„SáTÒ öë(LÇà󦑢ÞK9î¿æ Üzí@Še 0J £TG&)1ÕðÌr­Zl©*2W‰M2¾Iε)MU"S¥¸[ʵ+…¶ºÜ‚¦‘“™¶n'WÔ{‘ë‘x¯ðhä™+@‘°YüPÏ»ªxÿ“²Í—•»}æâò=?ÌLMÆhËL€¼Ùé„ÁÚ܈剓üR–—NIa’Èl /öí×6—IJáø™oìaìJ#ÑÖQ3øT8¯ð¯!d¶}K¾Q@MF;õ Sità-¹ÙQ“p¾‡õ› ÂÖÒI HÔ& DM…Qã¯êHFêR:+“Af2–/-—NTÖùÿ ñW5å `¹€\}³Q›ÍZ<¾p󦻲¦PUóÏA˜¢±•4ôJ©ôau[øDóDeã}UÓƒÊÚHEÓ²ú½«™:–™’ªÿIÎ…:x¢)\Ù4)m Jë•Ê©ºÖ±ŠÚ¢u¬u¢Î'k¼¯h¼«¬‰V6€žî}_EIt˜Ì¤¦Hô,"ÅívA6^pNÌÄÒÌ\Dµ¾€" òT‰„§€Ãêµ: (F£P©d ¨1S¸y‹5H玩Ög°%´›Oºâ4}¶?¾³?©ÝûB»;ñT ‡ÄV+€„ÄN;Ôæ€ g Sor¡„Æ`“™dŒÈDÞÝ‘tÒ ºXçH8^Aƒ1*Bc-C“j?>cmd°ÅP$†%öøŽHçŒkí…̉jÛ¼©£ÓÐì<±Ó×˜Ê é- ÚžEmg ­ëE•Á°t”t„ù»³O» àV‘)ð;æó¿ùÆ›t2Ê Â4"å]^Ïù§|ç Ð3œï¼.ôÜXÅžË<÷ÈaÇå<×5®ç&×u™ë¼ q?ïlöÀu_x/ ÜŸîkq½µ¿ˆ¹f#аRWn\ÏùPâ9W`?_îzûÇ… t0©Äõ±Ä~>Ïñ×ñgž®ÿ;l%³aú÷%úbÛP¾ö×oì.bXkRà´5Ù…®+üÓ_䨝ìà}eûÁw„Uù¶ó¥¶?ð½7„î›±ƒ»GùîK<×E¡÷ßþY™ó3nß À?`càø ³ û®ðÃç0×y^4p™ëº(òŽ\ùö¡#ÞkûˆÐö9ß{Bg! aÀtl3çGsõ¼”ÆbQQl9…LA¹¦ß䀵z‡D½7þWh$`É[ó"Æœˆ© hOš‹qs!ÞÅtŠtåF»ó¦Mܰ!?bD­…AïIóà]qs>˜$dŒF^ ºó‚–â iÀV‚wøÍ<Ü\Жá=GÆ»8Q;Òœ7iÈ›1IB†ØÿqÛ¡‰nnä†ô¢€åØC“8jáD¼@×Q¿õèh½è®IüÞ¦5lÂR C04¥të†Õl„f KQ:‚2YÄÂoE»“F¢¨U<ÑÅŠ[%Q3?Ü]pÇ”Ï^öíWP #’Ò²²p|"2«‘@Κ-šðGùëq™KgCøb®|˜û>F/ ¸áÓÛv½¼%£i„%¿ªÉ ÄÏŒÊtá–W©L” # uÛ÷6ú x¹rLÖ<^Ýz¿ºåžJ¨nŽo˜”ÖßQÖÌ—:îÈêÆÍ~i½_Þø@Ùt[Vë“5„eÍ3Õõ·• !E;ÀÀ$aY‹4{+ f¤¡AY[ä£@(™¸‚Æ`(¹oo ÊÔþr%.¯ T•ß“WâªÖKeŠ BÊ26#k9éâÊ´-"mòUÕŽÂQ¨gäÍ«®»]Õ0£ÔW´Œ¯’7MÈT3'¿T©q²¨•ˆ¤¡,JG`²×뚊Ép8‚ðŒOxkL©¯ÖjÂZ””„( äƒ?”ŒkmÇ) VÛzE7¤èÚÐbÆXÒešº7É?é°bWi®XE@W!e¤3ãœÂúZpE/NmØø³£0BC¨:B㤜 †ß]¥ ßêÓPWæÐ¦mÛ{D¨ü°ß)ì㛇@" l¹}ãBÓè’^gf¯‹g6“ôM¬,¼Ð.6;y¦1®ÅÅ pŒ‰LŸåÿXhúCa÷'ù¶ÏA¶J&stb8Å 1b)¯'sòkúTÜû@`uG’ˆ,-éø™,ýgÙº.š%†£wí‹·n‰Š9Ýhâèïö³w'(0{4ýêÁ÷ÎÄ$þ*ñbïæ@†i(Í6!ìÿKªqDÐ÷€kä[ÆÁ™ÅL)æa°éÅæÛï¦[>9F¹ÆA‘m,gà^šaosÏHšûѸýT:…Lz;qO~çê(ú›G1¨Ì(r$Žœ(læ8FÅöQ!ÛD#þQH#ZTq<ªt·!÷qOÁÃ.ñ7z±·;N—ã1äyôÙ„{@#¨yÏ;Ïœ&k^›ýD#ÇÏë$nM†_/ðë3Bªôž;Ó–Ò‰Ü:®_ó_ÍŸëâ.ªÅ>uzÀÀŸÓ –Å’7Û)ðéxÀ0 êô ZäéWä,i.Lë²ÊŽïLbRߤP9G÷ÒQâv%Јèx‰Àdl‘]NžÒ”è2’XT&Â@wn§Î‚ah„n6Ú ^ ~1“tpHftÂKÙQd¡¢*ÕåªXôcÞ‰ö_W,¯‚—ÕÂrûvËÊ/vä²FBÏX% .¿ÙB®;C1,”BCP”vÙüUwñbgꥑ…îì?7ˆãh2ňaH6^æR™t¾KðÙ Ù¿*뿾^ ‚ÞWZ÷uÕÕjÄ]Õè)—û9®J_«vW4¸«åJ¤ž’šGåu€:_VzªeÓ  P>ŠBü4ﺷ¬îË+•E§~CgÁ0Œ’ñâ#Éj@k塊VgAÕñ„Ý„‘¾ÿí¿–5-”5/M—ÔÌßøGYÕB©Ì_ÕüÏâZ_YÉtE½¯HúeM“ô½“;##a"E˜T<¼ƒ=4x{…"XÍŸy Ïrñe{Ù¾o[ ù½XàŽ9ãbÙT%šDcÒP*™†O<öj[ûº&àèk:»! …Ré =Ôn€° ·AJ;&¥ÃC«×i}­ZN¸,$oß.“Aò¨ó#H£¡$‹ú)J§Òf,T\‚S÷o”™Öf^!¾}fÓá”0AÖ&iÓš¶®ðö^Ha ¯é€:´aJãj5²¾Íø ¯Ý°¼j]wÓ µš¡Ý–‚«1dv4•cã LÝõ<¿0^ÿS¨|15ÏfÓa|a‘Èô$IC^ßøEÓ˜¨wBhº# 0;…g¦uDd¾#2 fÙîf;Æ„Öa¾e;æk»®Dÿ½4ëýTÛƒ´ÞܾûܾIôéÖ‰‹ÝN¡ý~®åö®”4<‘Ä&¼NcÆ'§JÎ43znã\‹¡P2|”_Pàÿ gäÒ‡ËéuÆ>¾°…‚¢ç¤ËdžúcLdS"h[7ƒÇE!3@)"!noZ½¹Àr;Uæà4X²Œ·Ò­ãYVÀçJ¬Œ‰l#’^ß<̳ÜÉpñŒ bNIß(šg`Bhø=;áÌB„J‚áíQ‚æ¢<]éj5r2ï“̤“É 9þÈ9¡}XlBþ±hd¦»`V- ™sARÏ·s:Ñ‚–¿¤æzµ™Óíü`O>Ø 42«â¸Ui¡žçŸJ-é³µ"_{ª·ãò‚Ž·Ø#ôh¹!EšW—í7ä~RzI™yªæìþG ®·ëRH3ß!šéÊtwg.ôˆ=íi!Cî¼6w¦+ç‰>Ç-KB]éÞÖ³må)‡ß@að†ˆ##2^)II:ŸAbÒ™H m“[_2þfIõþ”FdÄ ÔÈ¡êó=&(ŸV0ßÉójøà¾ü]|pKjþ» Ú¨¬ÀùEWË0B,-þaßMÿ»º²eE#‹ÏDaè?Y=þ…÷Oÿ’Ç#(L§l¹zl¯G—Ò]ø¡42«{õYÕçÉ0•Ea±(Œ¤¸]¯¨~|­r±B6_Rû¸ªáqyûš4P.¾ZÌ•ËfJëÀ‚¿B¾XÞ(­›+ª™+»á-ª –·|SÕ8S,õÖÈUÖ?”*!ôTFaÊé'Õr_¹lª¤á̶x&F “@moãFòùæ9'N²£Yq0N‚A£ÙYî:¥¯¸f¦âæŸù¬´)PÙø¤ ÜWƒ ˆhúzýÒÆœ¤wwT2ü›ÉˆÞ¹}ÌZ¶Gp¹= Ëï[¾l/Û÷l~¿ÿéL_ ý{“û÷½…"€"”A,|\â+²&¨½ê0áÚŒa7 ë[tÚô8•ýVë†f0¤2à”Hi†ôvHg\£Pm¬©ß¬ÒikÓ¯ŠP&‹Af‚o©g9ë»-ëóê6¿s \+OÚJÅï!‘ qûq…a;Ôj‡ Öøš´Ò˜W«\« ì¡ÄÈ´Vik±@m6¨Ã®j#mÛMB˜[)(q½øJ üŽ9êâ `SLÀá $"‹N'Ò¢~~Jb½#î›äZ'3,™æQ‘yD丗juq,.QÿTf¯KhÂXbXG…öÉ­ží–À>(² ‹-£b³Kdþ™È°Žð¬÷þÍ~½5•Ýq¿Tݵu»Î*„$÷}oB¨ø¬¸(ëc]mµêÁ‚‹B IHx+"ò’7J”G äInûGgú×vlíVVy¿t]§3­;ED „éAgœÙ:SfvÿØÏÜ™Ü?îœss¿ïçÊìM ýû£+Úˆíû$ ¥y8³0­³owl(¤4N}tF^û¬©/¡ó‘ú6ÅÛ¹•Í&°@aU‡Àúè·ç•8ŽrP6ÉÛüqôÇÇcIPGbßo"Bv}‚<”bAÛ£²kå†;i7…íýbûp’µ7©½G æÁ6œdXúÓ:F“­MÃbûƒäÎ!‰ýî~lŠÃBA‘£DäJe–òTí…åj$¾>3€äc(IÁ¾$½IªþBÒ>,°vÿT42£Mõ€èoŒñê„®úh¯.Á«‰]7Ùt]¤W'ºðš“ç 2‡:áMý,´ˆ=êÄ…fW+ò¶Iæ4’©©C›â1É'ô©Ï›Î$„ÐA‚þžåm>ín,Ó¦µÒy½xºñô3•Ø ü$1”ÄòÛÀZ{ê£mJäŒZáÕ%δÄ7K÷ÀlÄãÒH_EŒ[—Ý_.ÁØû½ûß×ÏÁ ÆØìOÃŒ„1šâöM©Dî6ù¼A>Û*—³E8«¹µ)#µq8 ôÆAЭ[ÃÇ¿÷xܯâ Ô%hÿS&ßOºW9N°‹ ¯üx³Îgƒ®I<GÙaÔÚúŒ¹6ù\cô¥—F1×*xÒ”ù!xž‹²hš&¯žŠyQ\5_XíÌ-q”VM–V3¸@ .[#Ïò*¦J¯>-¹2HSP5“SذP|m²Hù"¯Ö‘_ã-ºæ,¨+%¿ÚE²‰C¡Ûžöä•8/Õ|‘‘ÎB¹0£¨÷‚S&@` võvŠÒÅ|ö¯òZgq-@ÎLq5€Óó¢+@#®KÕãùå3¥UŽÜâyeS5¹å1¡¡&3ÃAÄÉ{Žô…,.€ q¿^šï²ðm{ÛþÿöÝ/ˆep =‹“ÏŽ8„Ó´/‰â(ÆFpœÞöËÂ"HÝ©: Û ¥e¥Ò¸ò†É§Þ´dó*¥Í§Ñ²RmúEƒqUR Fè†ÁGs RjÞQßZ“užÃÛÒŠàS<¸¦ÑU×±7„s™¾²vŒÅÃü‚Y,ÆÎ=?¿vRš!5˸¢Ù Õë—«¨Þ!ZW© +–¼ÔµØ ~õéXÌåqpð]°1pÓì¬cÚ;ç}3GÀì,,zÿö×;“É' ÁÖq7'Uh„–{ýWŠ®Ç˘Â6”iïO2t'ßvþóŒi$Þ4$déO¶ÉìC"sÿ­qǽ$[·´ý+…¹'ÅÔ«0÷*¬})ö‰­Waé—™€F­}©·ú%úT^òÑÛ9ÝŸDMaQÁs=¥öË+.Zn'«þ°;ZöòsÏÛ¾ô#´†žc hirÃ1a†ùî˽ð˜4åòqŒògaX‹Åå£x ƒ4>‘¯M·ÞÙF¤ö~€œ¤ö>™}liZÚûR¬C2Ëa0åó¯S-ÿ8x® ÔIŠÏã²XAlÖ¯ã#2í×âÕ9rÓ¥åjDdÌ ;°šfùÒ0v2ëzŠu$Þ~÷§¢§I<¡Mp˜RŸëRÆ N]ötkŽCsq¦-Í¡‘Íë’´"w‹`N›ÒÜ¥O~S?CÊ´.è©‘Îëómi.mÚ‚þüLS̬Næ5ò#w‘åoVžÙëÒ¥Ý.ù¶IàÕœu7Çß«J<ºÁY,„ & f4ÁG዇w:ZÎ7é¾Gq ? DIw[ê¼*~Ê”}òÃ-$ÌÚˆ©Ñ³íOµÂ®ôãL„¶PÔž€"àMj¡«MºhL™k“¹´âyt®YîÖÉ"Ãi’»†yu5W½Þ¥8û¾7@±Z|Ù^W­W÷¯¹âr¹^­¸¦ž¿H$€=s‚Ô†`˜Ù*;>iLŸT%xõé?”F< ÂàF…^r‚Ë 0.…37ãܱ˥ãyeîüʩ²‰’ò™ ‡ê©ÂÚåjdº¸f2¿\®²ÏŠjž\®-ª0œ:]y*¦üÈÑo2.ŠLTy êž–Ö™Ï$wñqäqNéTQåb©ò?5Ãy5’]¤¿ïšKÂ0… ¼u~Á±mëÈ…Š'ŕΊ«S9%μ Ç媧—«™€FÜ…µ³…W&Š+gKkòkïå”ü.t'ÊXÈáù®÷ÇIÎáCGfΥʹè™_t¿^£×yk’·m¹ÍóòÔ¿Ú9àP/÷åY^˜pd(2)”Kaa%·0Ä ¨ÞµX¡ÖNHeïsÝ ²Þ§É5Z¡ Ô ÷©7CMöŸ5w¼[ß]·­hè\}RÀ&ÚAo _s]ž?&‘Ë%yþïaÁ!k£EPVÖ»G#PfÒþ±qþQòÕ5ÍÖºhGe\¶F; x БO½j¶­lÑ¿S^‰óvørI“AðH½Jëš›[:Ho>7à3 Lщã8ÅE1_˜Ü%˲tËn€Œ–[†“¬c²ö¡²ë`r™¤îRsOjטÄ:$4*ºÉì#"SüæKpÉl‹dÖQ¹ý¬cThë³öÆÙû’ w2l=KDé‹3÷&ÚSo}¤ïÍ´ßÏ2Þ¹ðùÃÓ†1‘¹÷˜ô|0X 6fãþŸà‚ÿKÁþty±B`ïÍjÿ2pÛ YÏÀcùj0D’ud¹@˜už¼ý÷[>+¶m ;Žú1ù¹)25Åô¥ôæˆÐ>"±õÉ-÷¥Ö‘ ÌÌHzç˜Hß ¦HÚù(½cH|Åo £I …™v(L¡+«óÎéKÏþ—ý:jêÎþZ;mY"xI^Þ‘GG¨X«Ö«"VkWq\uĹ "Š„åV ˆ 9HB¨þÓévö˜Ù²íz"¢âÒYw<*ጠGö‡îvÝÎÚfÚ?œñ;¿yóË›¼äý~ï}ßÏÏtb¶YNîÊIG2A"QêâÄÝJÇ Q{ç«¢‘@mJÀ|ÄcUŸná¯ã­Š¢1‘`2‚¾! ;òÙŠkuÙK(è“ÍB¿Aè5Š_ö;ÃMiã&à ø²¿Iìk<4Q¿? OóêeÖ¼ûÆcy{“¸ô0NF‘áqô`ƒuŠÍ™§9{C ŠÇÀ(3žÞ¾vé'Ëx†-¢²˜ìš]«ý¦,ÿùƒ ¬0&Î`S±E¦ôû†Í MJH,:~l뚉‰×˜ó·²Tœä›’({X/ò›à†Aó›eà4Ú¤N bUnã!!L: ŠiwíÊåçËÑsfüÐùñ”¿À’Ég1=95³vù'6ûªV’Á¦ÑèI„lýÒ6*½fá¸Y<Þœósi$pAô¤Eâ?¿ßs!kó‡\¥³hÎQmÜô°R;©9÷8W=RZ>TpzTU1”?;Š€æQ•ŠÎ>=~Æ_XwW]u:yÇ:ND$= f,â”[EŠN?Ò”{—{Šª»ŽgÀ(+nK Vh: hG²BéÌå,Ú÷Î’É&™"1ŽEOMŸ¾9`Ü÷TÏÿVµCÂCØôµ$5М9aPøŒÊÄh°½XO]tùèºGõ©¹Ï$7ˆ@›°H§,²iƒÐg”=ÔŠ÷~8ŠDq"ÂBB¶'oø"ÿ]¬þ³FM¿°dðûŸåïÔôøèpÈGËW°ÈAT:ǹôX*tf,…òûÕHQýpþ™Ñ’ÊÇùšQu¥göñjʨ%õ÷TåÇ’>B`˜cQÓc¸ÿ(x({¬©Îñ««¿/.]ÿþ2.Šf®Y?¢®}TTæ9¥ œƨ|PXq¿¨âqq…·°Ú_TíQ• æŸñŸV—ƒ;׌V–ªË†T¥C*ÍýÂÓžÒ:çÑbè#ØLàdŽ2Û?þÌ> ÈØÓ±©ÀÔÄÔÿd¨ ÿW¯ãuütL0|“h)¬w ¾8:>Þ¾KÎÄ´Ü£­åÛ{íý@#²–oFÒw¤¶^…£[êº.tw‰Û{3«`”›@ åÒØ(Nüæ„Df.Î2¤™N²¨sšJg«‘,£ú€%—ƒáj aÒÈ­ùÍ[÷«¢‘}ÎfÖ<&%˜d²1‹&Ф%qËXôP;Ž@ôòmCæ¬@4PîGš²_ª‘Fþ¤ùH‡F ú8>–B"0RIœn:ȵæFÓƒ1’I`QZ‚Ð w&~¿ëA]úPS¦rC,‰3P„nÉÜ1­=hàÿ‹ý2jãºãøb ¶›8¾@B»ÚC»+ 0g ®ã£>ëɧŽãÔ±$t€ÄeH±â÷! ˆC×J ’ ‰O›Ô“‰Çí4uœ Û“6Nb7qbÌ%#PŸ ÉòGfœÉtÆ¿ùÎŽv÷ÍÓû½÷ö}??A2jÊߊ |:}b°Iäi;ÊÈŽ Hd=.ˆß½e\—ä±åŒ²¸|"€ ‹@974G'̉“f…I´§Dtð‚*aÌ ™µe¹©Ë(ö½$©.½àÁ”1ÓÃÈÞ­ÍáQ4ÂYÃ'q&£¢¢ìv»·2úž:Ün÷fúû“jñ PäÖ­[F£Q”"ÄQŒ`…y­ƒ¹4A"8–}`Ç]ö“â¶${ôB^4ÍL2ƒøkKŠË˜âf2NÄŲ2¥¥Eo»{ºÞSÝzïTÉTEÃXQíx‰æÇÒȈªt¦¼ánQµr÷^ `ÓÍÛ°7lKåÁä·_QL×ÏçWÕŒV4¹_­UWd8J¡H w´-«šTª¿«¨ò(ëÝ…u#ÅåÃåÃ¥cêÚqµf¬¨~´´~²L3YÒ8|ªÊ¥Ö€[€7®²Ú‰ÊjWI]ÓÞç£9?Žã ¿»·×kó^p{fÝ ›_p¹9°?¬ÑâÂ=f’Çñ¨ì¨ÅÝ500 ö#Š¢Œ LyÕ–]O–ùiMþͶåZ»os70ýeZÀ m/Ôá„ N¨£×¯©ÛOçôkî„ VH×½âLßòæsPKßÊ–>¿VÝz:4 İ`ÿê:Hß éì>-}¨0¡¢Ã¹,„C>u²ÖçŒÕ_kõi9BMç!û~æ•­Ë_ƒ oBmíKÑdìòis@Úßö.¨Ù°ºÃüÔæ½aà˜#x “H$‹9‚a hfvv¾¹ù‚"µ€Ë£Q68)á°m ǵøþ›YöORÞ¼šf¹¢´ß”:n$ôŠ™‹;ޤ­Ch%0§ŒŠŠ=œ_“iú[Ÿ%:¿Ú¯ýOýÔ”ò¨´ó¹CNâAØKåâžqÿ§Ç”M „³3©kPrîn’õãØ-8Jc0ý»†·„ÖäýŸz÷ ülªýÅkŸ%Z¯‹ß’3g‰Q<—Æ9 =.l+”ØÔéÖ2©Q)î,Lî)ZŠ:2•ÌT ³¨d%s‘ÌR¬0—d2eÂ^¥¬4‹Äx$ÍG ”‡ bŸMÌp^;¯KC2ÇuÆ‚$öO¤ŽŸ‹F&;¥.³bŽ‘N›¤– ·1ÉcH·ä¿¸{ÄÇé‚ «è7ßêdc&1@svœ=ûù1sî “îa’&-’Û¶ÊÔ ?®?éa§Ñ@Õ¡vmÛ¿)öèŽMcà/ŒÇÏäDH8V$Æð u1ÁÔçÂi]úÙS‡®ª~»+6’¦ "s©ì÷ÓLú¤1eʤHÚÃÇÙ,R€;²ãçMY3f‘§C8¡Wî¥¨ðˆ€µï¨‡»Ò†ê¥‘ðZ {š‹s¿èȳ¥Œëdy»CÂØ+Žmæ/Œ¶¼1kÍ›e.}êRó0nV¸ÍR·Q8mÍ5Éö?Í]ÇEP˜ PˆhÏÎíeÅ…—.]üêëM/Ô .çÎèøÅ÷®üéÏïh_>t8:Ô[b0Bâ$† pn ¥Y<šƒ„ ¨÷óvÝoK™4§» R#!¯LÒGE#S¦´)“tèÖ%Ï1âÁ3Ò¨ '9d8øVøç-YÎ}µfNÕð  òžºf¢´æÇÒÈœ²a¤LsAšEFù0·?EúºôAiíDyã7®ª–UKU;ZPíR7\å‚–…^–NWzŠÊGŠ*ï7/Õÿtiõ]UÙƒêú‘Â*÷éªÁURó]iՇꖼ}/7Ø §XHLX”£¯ÿ'wÇñ8–ˆE¸=22Gƒ@98—À‚ú×Ù€Ú´¾jv@ún¨ÅêÛl…Ú{!­Õ¯±Ó@ˆ©j±AÚ.¨­ jµA­=Í u[!M£O‹Þ~äQ\6ÊÙw`YyÙ/ Ì:Õ™ÀØ„‚yA¨¼ð5Æe]}¾cEiùªÕÊÊ:ßÖVˆÑ/o2Bàùë Ï%iDkƒÚ¬«´vûêºV‹0 Î7P7EEDÞ¾}Ûó=x<\÷üü"Š,>\|{ç˯ø<šàrI„|q­ÅëPgÿ™Üu9¡ç£œ×oH:?õ Iûod:¯åZ.å¶Ÿ Ø œ+CH. tð¦=‡ò5¹Ö¿{ îÿ™F¶Ä+ØáϬ¡£¥Gšs(­çêŽca4Ÿ‡ ÏÆËåÎ'º¯Ëto“4ÍeÐüðEIï».é½êmï?¼)Û>TØoJ€zß9,A2Œ aŽØ#o8ýªC“bT¦™ r,%rKI£\ŠF–¢t³ @tFÀUb*N¶œ>,G06›M’RëÉ_ÉŒÛxdž’r^ýiø×˜1í¡I4eLêÌò×fRß+O" Cˆ.Ü&;øÀ˜3ª~6g‘Ì’g:R=FÉŒN<ÎHª_Ž ‘ÀpxµöÄs3­Çf»ä·“(‚ðÀ¤˜´d4%îÛÀƒ7²Öf¿ùy»ü/µ‰Ž¼#Ó­ -B—)ÓeË^Š£áQ [Ý"IæÒÉNì &ð@ÍØájO4€eþµ\ºqþ$ÌÙŒ¯þÖ| 0Æ}&/.„E®çDS¬+ÅGÆõñžî¼Ëuò[Mù_jófmJ-oN/œÕ gÉlgÆRó|FŸ2cL7¦Ý·);³oÂÖð`’(Œó1š‚q‡Ž ôº€dM4Åg­¢9àãáó8` BÃ/ˆ`?ÉnHÜ~§Eñoöë<¶éëø/)ÝÊ*®Žíßmÿ|ä´ XÇQJ€va°…hßvHÂÙ\>â„8qÎærûg'ÎáPF¥ýÙ¢I¨•:´ †Äþ˜¦Q I|ñ^ãŸ-•@U¥|õd=?Ëï÷¾Ïþ½ïç(tœ Ø”‹¡¥^«Äc{Á6¾* ˆr´"BK@.Oìg‹sF, Eù¼_(œ©ûüa¥>PÓìÒgj.¾¬Fæt-3õ¹Y™`6p§œ=”û¤º9ÐÐ4«nŸz4-s•º6·Úènh{¬itkº³H<c7ý1ª¦qZ£óÕ·„j»–›¦ZhlŸ­mé[ŸV5L© ÿÒþ©3IÚ”ŸÈ% á¢hVRÚ݉;Á×_qVb%þ7‚Á  ÈÒ+xë÷û§§§+**0$'y±ñ|Œ\‡ bÅJ¨½'ªÿ ¨Ó ™0`8HÀäˆêµ-²Áì„Ì£Pý«îÑ·úÇÞhl[_V¾!ï0d³c$ñ¶0a&‰Áì”4D¸™M¤!Ffìî¶}Qí4ÔgÿeKǪý¹Œ”Ôu$+‘ÃOؾ2ÔA¦Ñµ=WÖ‡ ~ë²év¾Õ;µ˜¡žáµmݰ`8¸€Pii6‚ŒB¡Ðsk=kÁpxéíRî _P_ò>>Êe"Ãtóž¼2çw’Ñ2û’+—ŒÜ–þi²düæb]½[⸣¸t§ çj,ÌàðÀq3qð,#$Ù<ßr ÷y›Ey©ý¼4"w|wÆùíQã`éØu©ó^ùÈÿ½\f æ%«ê<=>Y<4y¤TÃÃáT ÎÚyàE@0ƒhd±ôŸ›PŒÞzõü™Am0ñDþü¤Fzʪӵſ víi«Zi©•Øþ?E›m‘"rZ Т´k¥vØ®-¶kTƒºw²·Cò)‹›ˆq`25¯¶íÅžƒ5,uÀª~dÿ_·FÂf¥ÛªðÙŠýtqÀªZ0ôÚÆ;X0Â!ðl^ü´ ô²§='½…Ç&ÊfͲÀøJù<­hÏ߯ÃH›qîðoA Y3ÖS|&q$GŸÚÏûÍbÝÁ,±¸üœ½éce{¾Õü[ÝQŸ£lš–€Ëìrcá‹dc¨8;ÝmWÌõ•ø‡d· Çߥ֭a㈀*Ú—þ¥¦Àx|÷œƒ¸[öQ:@TÄœÓxx£êýÌæ¢½ŒŸ颰E6m?PD̲SI » d* ˆÜý%ËíCÄ\±Ë=fI˜–{ûON™å_ë‹~—›aƒÅ1 âáp.ÉfóQT@‰Î¥H Gpzppö¦˜ødvLFâ†O³…_Tü¡K ôŒJ<´\Ý3 õZd`Äo“½*‡,µ-ñÓª Uì3ÎÙT·úÎîç®å‰Å1fç‘cþºN—¦9Pi˜×_V#3Ã?*›`‚ˆÉrýB]°Úè­jðj[gª.úëÚç«çk 3U ‰~悱hçn€ˆ½Âwm×Óú–Gê‹ó•MË^BÛ¼Pmð\Ð?R×»ÚæjZ¿)WoCPàap~áàü"Ñìöøf]á`(ðúëÎJ¬ÄDèY,õA¶˜8ÂA8‘|f<ŸõÁ‘õ Myê¶C@— Ëe¨{ê WõÚ¡nGtÿxt‡ã;±ÕM}kv…c¸$Æú…¢ô “yõimü¾Ci¸d<¾ã3L éß®ÔD™c,1"%›ÚÈc2 M‰‡™§íxSß 5ÑÍÕc^^#c«ZÁb†!ëà†œ<›OÁœ];vN=~¼±”Q %&ôÌ! M0‡AeíêW_¾X‰p‹J‘µ}Y2zKæ¼¥p|bü^©óv㯢ËRǤtä~ñø]…óFÚÎR$&Œ‹¾ûžHïHÝWƒÂþ¨P&ŸüYkDâ¼/¿<)½r³èÒ­ŽÛλyê}EJtû‡’þ¯Ê9ÆlߟËd2X̘ߗÕ{¼Hä:`t”ÎIÑð]éð÷ûUZ¡’08~ÃöœßH-5R‡ZìPËA3&é:/·hdƒõËi¸hDf­UÒ…M'²ªKµ"Gâó,™G„ÉLäâƒÇMÚšó±Ò9!»%»¹¨çÄ’F¤?F"ý*¯Må*ØN-Êp¯È5t¦8;…‡ðÀÍU•³Ùm“Ï[ó=´ta 4`ùÍ.Zæ§ó…Û*/?Ä#„Ê=¶+Ãe*Ž˜å«jkºÃ;aBbÆ~Æ&ÉÞB%0"#S¹7nM2NîMŒ½ÖtjÞ*öôI®«óñF Ad¥â¾¾|ŸíôCK¹·¿âÂÁw2ù™o³xBðã°ã¸JáŒEæd ï÷Ê^¸h›ôa¿üßôgOµsfiÄ.öömJ¯õ¿½(Ëe-ñ=«þ@# R/«2‹lÁ¦ruFJ"Ù-ž¥Kô*5Å{n%“Ñõ›Aqyè¢8 'Š „‡q8 ,Ì0c³(äÃ_§×ìø‹¦ÈÓw6bRÌ%~›Lè¹ÍЖ( eÞ±Ï"ñYD¯N#" Ÿ½ÔÝ/,“ÏØË/Éwq`©ü8‘ÁÅž7<ª¬÷iZ¼µ­/«‘`Uã5Ñ9DÀã1 ïÑtL© >]›[Ý:UÓ8«5zô­ªôSúf—®%¢íø¡¾ÝT(¡0,™$œož«5>Ö\ºe©é˜ªªŸ×BÕÍÓ•tþÉt60-Áá`C™ªòRÏœËïö‚?ÿ\xÅ#+ñÓ(Í ÿ àç£áÈÕo®¥g¦ó˜bÁà¹Á)fFƪê‹kZL«{G Ž±¨Î±ÅŽÅ uØ£»ÑݣЀ3ºÏÎ8.%ÿÃ~ÇD™ÞqÖ]#Ë0ç;ïÌ;';\ŠZ]µZD«Ån×µ«+(0×;7·"ˆrXG¹™‹9™ ÐÖ¦é?›¦i¶+²€‹²j×þÑt«9‡9ß>#†)iMÖl6ñÉ/“wŽ÷ç÷¼ïÌ÷óÒâùt2›¶×ÐÓú˨˦ïkš‡2iL>‹ô“–´¬¤§wàZkÚqéG) üº]”0+·–Àjé\yéÊÊÖþ¥4ÝjÁu¹qZûêóUt*—Êes™l&‰øë_]‹`ôz™-À Yá`È?ïûáŽ0D£ƒ»/2´;+u ‰í÷Ôž»Š+w%ž/óú•#rטÚõ•Ð5.î4ö0‘TBB¨Ôƒ¥Mç¸Ì>šÝ¨gn;ˆšo¼Ì¸Y¤ÈwH#yžG9Ö;¢QAÿÚÿHÜ{WåÊsÝ(轩쿇چĮ‡Ìmxv ‘Ÿz¤Ñ³`ø‹ [`‰Ä5"tÝW{nóÒ‚3’³Y\– •[k¦ŠS™Ì^©´U«,5Jkx Š€’ŠXªF”æj™±J¬?+·Ö‚ú©äÌe< °aˆM!³ zÒÆÍ*×°Ò5,qÉúFe}‘iDfåùÖ4Ò­œ3(f͹>“ Ø£ë¤SöSY»x *â4Ùi“¹A[î¼ h/ô"òv ½|Þ(Ñÿûú,2D&!ÐÏvnð›U˜ëflMás¨ Bì­Š£˜.sÞ¢ÒÙ±‰ÅáÐâ‰9d2óhl~žµçcÎSS:uDäP`27aûF8cçÆã»Ì®š± ´‚}SùD*5ž sðoý€Sux߃®S~“4Ü#öòÂfQÐ$1Êfõò½sä…LbŸ6gÚ$˜±È¦­êiSN!“c©u˜è)šÖÊ0›2Ô-&ñ›”W â1sÑÓvõÈ…§0³þã½â]I'Þ‹ÏÝÎ;ü^bÎî ç2ÓÛi¿)ù`ô|æ³në- èÄa³2hQ `5T˜^2*å"T0Éü/\4§—x b_„FKÎç•Ë Gö™Ô^ƒ 3˃Fñ¬A䵪ŽmØ@ƒ‰kx0J+Oßï­kÿºúÞÓ^U#áªÆ?HK)L„KFØe\~æYƒæyÅ…É3¦kšgÏ6Î6Mžk­ÖÔ8È â©,„EA AèM3 ƒ«\ÜÞ€ßû:bæÍx3þ׿è…Èöû#$ƒ/ß a>>¸ç'É@ÿi„ä´w$y«ZÚ—uY–·»—wõãºúpmÎÕÀ'Öå\› gtÄhÚðÄ‘hñ·D+NâJÏ®=š ³×GXâ’_Ñîĵ÷ã:l8ÝÀ[Â|.N¥ÞÞlåù‹±yE)Dmæ'ëpÚk«5®¥4²¢Õ¾¬ç*®¥•ô£tð³"Á0OÌúøH €Ee½è[H™Hƒ S‘GMóE&¡Si„ÎJØZ`üDØw_áz4"p,8n)œŸ«ìcJ÷WB70ÉÔ=‰q±ë wë¹õº°ÿ±Ô3–oû]^ï§YWþ²Èÿ¨oÿg)m£EW ®Ï³íƒèÀ— åìÞÉÕqÅÀ¸È1"²˯>.´^—·¸_T8_Úì¸@/ÀP`C20*醉áð žA¦ÇÑàM{·ˆ/–æjÕæZ©©Rf­”˜+E=•¨¥v)(¬‘’šk€@ÀS°c‘¥^xé;á]†©$*$¸894˜A¡€S)6Ü ‘:‡¤žéÀ݈FÀ {—ì÷µkD/›3€(Ï™ïù,!ƒl¨*ÚŸLa² H²#óT‡»Nøµ¢)½ì¹EÖ § ª £dV/ uùS›8…Aæ"„Ÿ2çÏu0›*çÇÛù "L¢]~³d²ýf.|b-ŸèTß:½ßZ”IeÄCÌõIäµ^-:Ý ,¡Ú»Ì3–ú.ƒÅ£°ã‰1_kK0c.¦•<é” U}øIYÖkOüÍT8Ñ“´)BúL_GnX_áÕåô‚€Å Ò9# ^ôêr1“$¬“û»å*h.˜7(‚¥/b€ÿ¾OMEs&•¯;³ªÂöâH%fÌñ÷dûL"ŸU9mTÌö(AÖ‡ hP+ð™s€ßÂvÙŒ.Ç«êÀºÐô ƒà¹Y?]ßrroz2’H¡”nÙò¸¢ù牉ilÄxäxè´f²¶Ù{nÉãOÕ¶ú*Ûþ\ÓrxËf"Ïe#¢#ÌÔ„ä>»3â_ †ƒþ¸øý¯5rÞŒ7cé6þM#¾päI OÏ3Hd6‰DæÂ¬2ÄKyûÐGÑu ÑÆÞå­¶¨&óªnòó*­;ºÕ…kwGéík*jãö}Ä`A¬˜X&Mbr 3žJŽE`Òæí¸Ž¶ïuzVw8£ºuQ­m+[4ømép…Ñ)²Ö5kqí­8mÛª.+8æŠãRÁuDkô„Óet"‹È¤sˆŸ78øé6|>ßbk‹¯GnÂØÄߟ¥$%sL¥±8ò‰ù3ÙÀ#¹k,×ü™êê©ë ôÚ8ˆ³|ç=°­pÝ9V£%ÐX) "¸Í|ÿôe…{\à~X⺽;»$ãäÅüÞÛÇðB.ÿ3ï¾S‘»GPÛ Ìv'¿ÿ ±cuK<÷%ÎqéÀc™}PæÉu Š®<,ð *íwd‘eý‚®Aý«F€å¤Ž±ìz;™ÇÓ lÆ?د÷ ¨®;à7IkÒТ•×î}ïÝ]`©¨F¢®F#Ñ[[š(}Ý}‚TA`­à#"ö}w—]Ø]Pg’NÿË´L§QAÀV©é#šª<–}°¯ž•Äé?tj“Œÿø›ßììÜ;{眽çÜïçf¡¸AS`>¹½hwéÙ#ݱ8H¬ ´©^5E@«Íõ*ëq¹MKw&©´5©Ïýbýþ·I6FáήÖTÕpI.¸Œü¬ùR‰sPí–¸®Ñ®ap7Ÿ¡FBf:òË(á8Ãù8­“Ù•[Y”À©×Ix\w4Ò)™•þnõ”E6ìõ:J&š)“,f(zdªÀ˜EõÈfì«æýkøl6/#§¹pC¨«(æ?З•å ¬âÍ¿kÜ©+ܘ…¤b)x~VªÏ YD>†ë¬)^›žÇJL‡áŸW67é,‹uî‹ bÉ´¹0jT‡Å³úQ ·“¥0jQD»*ƒŒ, O›é˜^=k×D»hŸ$²2f*KB:E`@Oƒ€1*àyݦ˜TšU3% ðZÈ,5I©ÈÄZì3}°ø™ý€ ?@ôGEȤäLétÜt€ÍXAKgÌJŸ^×Hü⊀ Œ|¡}:Ã7¦³ìñè0•Iã7©Ã¶R¯A0RîÈÉNM†1ŠÇÆöæ­zpªÍW{úi5r¯¡Ù×Ô®n7ˆay?Êý½¬zª¹Õ_ÿáÃÚ¦Ù†³Ñc-×ß²bY ‰áä^ùkÜn<5Q{:¦mØÔòy}Ó|ןh8÷qùáÕ\œƒó¸|4…M¡èúµkF†FÀ‚žõÿ@"áXä¿í€çõ¼¾¥š³ÇD£ ªÁbŒÄ*ÇÂÓ³^pÀé衸ŒEe‰éhH–Åëw~ïðqÈhƒ€I.Ø!yÁyj³@.èB?ÔÕ ™»Z;ö‰2ð¥\6‹ÇA—¤¥ä¤apÞ»P«2~ôJ«eÁáø÷®X•XYµ·¥ýøÍLtŒ,I×A]žWÚz^ê` #é\ójDÿëÄ–6$w ‹/ÈaqùK{´*¾µæÈ‹ùýþ¹© z¼Ë€ÿÁÙh8RY^Á#)$ ‚,wåëU®Oåžq¥ã–úâ¨Ü=ªè‘÷ö«ÜwŽª¾áòÞìM2 !áUo¼YíþƒÄþWIßß$-}@(I$µdÙj©ãú\.Ç“Ý=ò$ÏœÿcKú‡e½CeîéÏg × Êq³ÜyWä¸]íPö (<{/ÿCâTzî(í#Of& zŽ^À'ÒÞA@¸íô Ù™h2 H,G€à…*7sƒdGqë!•­Qci(3kçÕˆ±hDf׊­ c]‰¾qwEá"n’¥80réâe§ÃÅJCHœHlj͇M%Ž«¥—nŠz®J<7dž›j÷-•säYiÄk,ò3ʰI RxÂr0`’E̲ѳJ.‰P0? Ê¶-Zù»D>»"¢“N›*ÝÊ-Wn›dÊc]û¶ŠüÙÀ^DvýÛ¼ñNÕ'…y<*!SˆìâüŸåÐ9C¿Å"SP"C±—ã(‚f pªK¶k²§K…×R2(ÃfuРˆÚˀ߼&PÇ £| ųFeP_:lÔÄÌŠ¨Y ô•FÀHh0@‘X÷¼ãyj0J@#`Ë€^³WLê^³Æo-›´ßmÒd‘)8‘ÁA©¥hªS.myZ„Ž}8QÛ|«FËÃár¹‰\r//û‰Ü[{òþ‰3ÿl>u³úhµpœ¶˜à Và¹w«N>ªoñ×™ÔžŠ9s¯ñÔçõÍ-ó]ßRP°*-ÃØ0Fr‘ôL„»×î‡þˆ‚‡˜ŽSä«a?™Å— §b·‡‡,æS© Åêݳ¿ÛÕ}cÀsœø2dŸ).Ý)öÜ•Z¯×›`BÒŠB’÷4Ù û®ï½<^â¹¶zç~„B¹jõòkŠ«W¬{gãö÷úŠ{†Ôî?«Ã¢¾Qµç/ f¨Ôý'±çÝ7®°Œì¡Ýƒ÷€¬ï}0`Lâ£{ÇT=Ãà'Ïœ%_³‹<×Uý#oUd¢(å ŸÏå¡(L`8E ØJç¾¶ù]%Å%­ J“Võ˜r¦QnÓÒÝÇ%öz‘µ´ÚÕŽh,¿¬¸Ð¸iÏ6ŒBI € T£ å!ðê(œÄa|æ‹*<®A©kLÓ3ªq Ë]7ókði5ÖR\·Ñȧ¿”…q„@ÙÆ‚õO›nµ?_¥²¨e(ž!Þ¼räWôChR/iÙ·•§`|ž$åxsAÄpHûS!EP‡Dñxq0"WÍMErþŽu›‚:å}óaíž 9x޲¹;I*Ú²f¸.B'žµk|&:È(A„|SÑü¼Ÿt¨S¶*kw½–É& s­[™ú7ûuÔdzÇüÅU·Õ IÞûHá´µ¬» UÑõÚª¨tv9rYO  G’pC8sduÛÎÎlëNgv¬hQ¹Ô¥¶ÿ¬]«€°\áJŸÈ”?:ãŽ;cw‡ß<“y’™¼ï“¼Ïó|?¼Ôv1o<_õB^<¶pTZüïÂÒ‰sù“YE¯Ò¸<<ëò°L¥:pX³X4Š1|‡ÛpöèqñîC›o”Ǭg»À¸6" d$«`JªšÎ¹òýåÈEå„´t"KõT¦Í.œÊ+W(F¥òAyqwVaæîƒ°;GÈ÷  G1°ç)rkKµTÿÿ5==½Ø_Œõ¡¡¡¤h±'FŠ \W>N»¢^k}ÊRj F ¤,Ñ/Óš–W¶@ePy+Tßüà\ݲ¼¢ÆY­Y^YéRßiuPR›¡º¶wªZÖ‹b0!³z=µië»G~CðÜX\îfóÚ’Šw*PµéÝ"½S¥~…FUé  s…Þ¥ÊèR®w.×ѯ—©Vm òÂhO‚B¯º¢@€ÿe- {A#ó/knÆñ!ˆ›ã!G=H”b»1|Ï­ÁG("¶ö‹ŒÝ‰–>Ð@€$ÙÒ¥ëŽ5ö\0Þ¤}·ŸLàd@ðþÓÍ·Úâ¯Ä)­$ߟFØ4‚3¨¿;Ò8ŽAq@‚@·Ü“\ûæ”i@tíq´å^rGo\ë­Ó×´öD·;â2NßÓÚ%2‚pìO0ö%šú“Ú¼uN¼aKìè‹5t ‚Žø$ÉFiRøÙÕö°È0†Ï縳<FÈ0›‘,ÀÝùè†}ûEÇ.g¤WÉRkåÉuò”†Üä&Efs~j­4©ìbHZ$½YÈ¡`á=ŠÜ`xpÈó«/ÿ 2l¶Ù-=mꌲvÇYÔ%š»ÁSH|õ8_W# lŽÉ4wýê@#`:ðiì³´£¯›bÿ¬—|º‰ƒ¹»b´¤ƒ'â.€]=q„AxÅCizþ^§"®}[Ÿþ>µÎg6ìK|î:yFìÞÚÄŠð½>ö¦óÚOFµñßÕ¥ö‹¾­J›hΘÔJ(2Ý,«‹jL™lˆŸi¿õøþ‰5{SÊpmìÆÌ@šEpRÛs4Ç¢§²‹ŸÈ.gÚd%/² ‡ÏæŽ*”SRå«4ò\ž÷âœÜ.W?‘–dï9äÉa!8N8|’ëMá<@°Œ`ÖVš¬ ./T”ŒËTCò‡/NæªÇrKGrŠÆäªùœÒ¡<åHvþØ…¼Éœâ®39|¼=6X(3Í×ÛÇb2ÏNÏØ—0²T?ªZ tЙ›slÒ`7TÔ2,w!ÎõÃ1Œ Û¦­+/JW×¶BÚv¨¸hdE£R7BUíËÕ&'µÒ´BÕG«}¤ ¤i_V÷9TTþ³ðHšñÞ¸öâÀÞn®Ð×õãP@§Š¨Ò°êŠÁ©Æè¤i^V ¾Õ.²¬Òä¬1,«Ò¹”i¹ûCÝ` Ü=}d†±Ï,þ„¹—eÿ¯F^®Á‰?ݸÆEÙ(î‡âã/Qw,R4Ð9g¸^E†ûÉ×ÿ!6Ü>‘™Ç§(pneQÞ§”†Óc‘u Óô·ÀÑ|gRÌÃ'8$áhx’¿O€+æ£ùCBÇ7Ú¯)Í"ÃŒ–Û m÷Nšï$º’twbÌw#Ì]¢¶>±î¡Dÿà´ñAª©_ï`‰åÑ[çĶX}'€œoðo6K€$ÁØçg¦fmÍzÝ®]»H ˜#¼ ô£H!9¸¹á×›w}rpoôáíaû÷…ìèï±QÈÁØx £vmÐ×??;è¿vÒ8 (ÂÔÎØü$Ã- ½x³C#€"ñ–n¼J#` ÌØ¦ªÊëpE ˜Â¹7²Â^7Å&ê%+ÓÒ÷löc³„(Ec|’ôq‡…‚KÐ|_¿.kN˜lŽÖ8p%*#ôƒ˜Lî‰-_É"_4Ÿ¯Ø«“ìÚ”áº[‹ÄÖ˜b«O›©K›«O±UŸšÓÆ,PdB+ P€d²^ôÖ³û§×æ«E#M’ÑÖäÊ“» `SÊË‹ûS~çdƒŠ’‘óùC åXvñ|¶jP^4’Uð*<Í+˜«f/)Ç/¨žæ–×…Çâ˜3̰ÙBÝ#QÛ>øcú™çŠ"û¥¼±K…@#㊒!iá`NÁìò YÁ 4ÿû󹳗Їs”SyUm‘â>X/(—„I§I*èÃÀÞî°dÀ¡lqc\ª¥úQØ{A²PàͤÝ~¯·'80u]çñàÂ4ÏwMx”KyÔü9¤¶¬VÞä¨mrªµ8Uš5æê6—2+¤6A•&¨Î¼ª¼v¥ªÑYm…š; êê•g2Öt£Áa6ýüP¨«´jhv.×A5¦¨¢Ò´¸ÔÏè¤W®1.¯jtMW`´ŸKù ¦¾øò†ƒ!ØF –ÛÿŒfÎ><ôÝÎ[yN#8Š{l;ÂØc"ñ¦žDKè€O@'ÉÜÑÒ%i»~xF1Á·„ˆ$ÖÞèŽ''ÍwËŒéò‹%àúüŒåf‚åæYóYUº¹3¬ÀìJýJˆÓBŽÛ/·8œš—Úúu¦õQ²q N×béIméŒ7ˆ-—ûuwÅú{k¿Øúð”±ï­sâ [ºµ'¶±ÓwoÅvR$ECƒÿš¶Ï‡a³Ùnß¼u €ÄaŠf0L£‡| 'Q”Ä1‚ÆŽ2J!àŽ/-às0œÓ8u,$ôÙ³g`S]8âñ)ØXe_šÐ1Ö ÆÐ/6öÄ[FzņWþŸ¯«p»iÇÄšV•ùƒ‘‰qþ"|ݳ·ÆŒÕF·¦þ^žzøý½^Þ4×ß“ @âÿÃ~™Ç6yÞqü ºjÒÚæ°ýú¶h`´Ú¦UX[¦¶”è€q|ÛIp¸Gˆ'&ØIpâ$¶ãøŒï+=þ[¥M¤m °påäê BTrùöëãÝc›¢i['!˜²¡üôÕãÇ~籞ßïù~žwtÖ:¿‘Ö}€Z˜Q?®å¥Œ‚¦*j`‡ UI§Ào¬œ3îjƤ_Óp-;ªc„t{CæJ!A+‹"`8€"Y-¸}?cBu¼€MѳæMG»†c Š1„"<]üÆ›ñ6ýtc»_ªÕË’v€"óÍÿE€æN*¦›Ûï×·†$³ÇÛ4wþMÚ1XÉ’oÞ¡x·fËÞ3u3²¾9±<ØØ•œˆ?åw™m–[da‰,ÐÔêo’¡÷¶N7«ö¿ù( ‡¡àÉx<(@.›373›øÅXŒÿ«&Ž H¶ÏÄC["€F É;³Ó¢ê}˜üB*™€`I)†ž¿ñíçÚ•?Ö~ uz >gN¯ê1A*+Ôç†úfúnì´_«vž©øƒŽ…Ò*Þa9†ƒã|zçC÷h•c¤fðªÈ|¦ì×[p…äU„b,‰R—®­ØÅV}¶ï“[|ç årûÒ^Ï$Ów÷Ñß7Î÷ŽeFŸd»'žTæ¯~rëçï Xl1Ú‘s_FRß“a2l}~vÆëuoß±B§©d,ž„©0‘N Ó*"ŒàW’¨4 ¡&¿²fVgD¾OÑÌÒ¢m29¸ ì·à¸]êữ°¼“\ǸÐ5ÊñMðí“OF’éÑSq…\ &I Ãdæ´øÃÇu±ù~bET¬h'eÛ6×ú™ˆ9cÅõlTµ5°3+dªJ˜¸‰~aÈÂõ›81û>¿Q0«ãÍ鄈ýHÐtÕscê=Iµ²cæ½@ +¤Û $jâeÛ°Ž5pÁ½ûÙSÊÀ7íALBÔxäO ¿_CYŽEd˜RŽÍ©m˜mR†¥±ü[ñ‰°Thhû!™>" J;ï7É-ŠPSûÜá¤Y’tÜ;&Ÿ“tÏŠ»âͽH}gðЉhú¶Öh£Òßxê^½tVÜ’hik™;*È”Q&޶lZÿ*žFÂÂD޼žX vçî.%bÛ`vo§ï‹±ÿé öülÒ>L]€Ö ‘h MZt%$ÔŒ¡i/æ¿üês@ZC®Öõ»r»MËz­KÕ¨× ”«v¬PÛWô ¤¿ª\iésA=¶¥0¨˜½iR9 ­êq/×dúªHmÊÜ :æ¼n[ŽÚ iÏsxl)à<¶°ügå“_ßÈšÿä?ý‹GXrë›oÊ×n(%®.~é%¶±NÊñ1œSYööÄqŽ‚>À ÐÚF8Þ©=®«|ÏÔ>Ó°È0Të¼T鞬óÞbw8qêêB,…X¾Sbäû&Yž\Ç=¡ûëjçdû&0A†é ¶ãl•m¤‚]SËDú¯vr9®³»­cÕÝb:/ð|—Y®‹ çÅ*÷(Ë=ÁrŽ ½ ÍO¬jוJËØ[5í$ „-¢á–†?zHÄh&’é$J§P MFÐøÐð°¢K¹å½÷_^µà±GÅJ $*™H`›Áò¹}ßÝ»ŸÈ<ô! èö­Û($2ŒÅ ai†¾q–{Šg4Âò2çÛ¯>5I&Â`ÜT¼ãd'†a"–J(üsýŽÇu±°‰52Q/a® «¢vßÄÈ‘°VGLûc}TS‰èªfÌ"?@Ž~^ÜPè…1 e¬EM5qéã¦ô Q¨™à}k`ÌÛ«&aX/L뇤eäEô€"q³(¦ã,¸}?c k¨“3Õ„•¬Ð€pW©SPŽ'á|Öú ÷›{æšs’¶ˆ´ã»yð˜ì‡h$Ù¢ —g$CšNÅ$íÓÇš§›ZQiW þ¤¿©mºA6/éˆËÔ&ż¸#(îœ˃':ÂYèˆ$*nŸ?¡¼&–{™Âõ<WP€Ç•ÒÊÊŠ(+ËVÿ|8ijuΕöóÿ”狱ÿ3’ö_vü@ õ#Y ‰&â—G.¾ýÖï¨8¦°[†# hE”‚m»rÝy½Hm4€ìKUÖ´–hìÚ x#§Û õØ¡>+dpåª\yJÔm[ÖéHÿÞï…úΩlàqHkYÚëT– ËãGõ­/lxÀãqØe7¨50çDÆæ’‰‡å–­»G(NuëpX˜ “Šqø•%«Í]"Ûד&€lÇ ¤®s”ç`û¦¸W«ã,Û0|ëÔoX "u%žR¾aóaÏ%Ž 8à„À>zØwV¨´üòݪu[_Ù´í]ÑIQßéÖÏÖlx_ðB½ì ûÌ.ÇhÍàÄæcê#ö/¹Î×z®€÷³½7¸¾ë|ïPÊBãÄ Ã}“Ýýi>L¡t"q]Y©?„d)$»"‰ÈŸÌ’¥W, ‘‘HäöíÛ=÷Õ—Ÿ>;|æîÝ»qÀ™«ñìR&S²,nÙÊÒz1ñõX/°û¸‘÷Ó3!´_j4’J¦O˜©¸BÞIÅãId,„9ÝðØ41£Æš`?¨Eõ,Dµ5ó-sÖP›0òQsõ¼qÿpÕÆé«üæºÄ?¢g%,܈þý:â:>˜å ÄÁ^ï13{ymŒÁG(ÎÑB A©Žˆµ÷Þõ$b¯¯=|Û°>ö>ìõ®½R þI¡HUZ…`lSu ‰T‰Ë°¶÷ïÑ·p¢´®dµ’âOŸžF³£™·zoæû}Ý¿!;hÉóêŽa&¡OÏ£GËÁ LÇ‹è…aµÀ£å„Š€Ä ¢¨FtB¿š·èåû9KÌŒÈÇ w ]ݧLÏ,„F§SÄ5E+]%ŠPyýƒù´¼i>Lœ–å-ž’Ÿ´ÎUV;!Uzª›'ʪŸ‘ÍNiuôX^¯T1U^‡U¶x+Î:¥5Ó²:¯¬Ö#­RœûâTeÕþƒLN& e=¤È{œrNFù~ÖNÎü{¶¥XŠÿã»wÎ$@?eÃ7ÛÏF‚XÄç‡@%O¦&N¬£2i± L˜SâZòÊŒ½/•Ô,ëp@mvè¼R™–NœïŠQÙcÎ÷.?gXÖf€Ôà¼jïYÖÚý‚Ê .€tæ—Z +õ/¶!-øÕµšW´ZW´ôEeÒi†Ôf’Ÿgˆ¬Tx ‚ ¿zó—w œ¥-ä ñ.`N#ø(2>>Ž¢(LŽeÒÁ$”D§¡É¯àUÿ!Z˜l·Á(êuȬO¸ö¿ÍžïÏ·‰­ÃëˆÄ1ÊïíçöÞå¨Û}‡2Ÿ:+ºp;Û6Tdâ÷ü¯ÿüÕôm0…šDŠcW’@›oØrøã”-o¥R 1ù¤áϼ‹ß|Ô`GTÒÆ}{% 'L_^¸Ë¶Ž²­#@#ù½ý‹Î‰ÿ2y¶¡\Ç·Eæ?¥n} |Ÿid2 AKJa ˆ6ôô; ã8ªˆ.žø.Û+<r™`y=Á¨…g¯ÿî;zùòe°ÈDxÊ»;wå÷ ×Íi$Û~3×v;ßúõÿP#Áè0 @, %îzÙ±…V±°ží7ð½æÂIµ  åFŒ·Z8m8Ñ ¸nƒÈ£ÍXø®¶Ì€EäÒs$€R0m5߯ût"@š@§ ¤G43*AD_„iEoÚç7@ÀƒÀõÑ'jøø½|?gé3J‚šãA}΄ö€êȶ(NDP ÃTiO ó‘´6"­÷•(#UÍßȪçÓÆ“ŠZwUƒ³¢vBVç”7L•VGÊÏ>Vœ}\¢ U4a¥užŠZ²ñQ©Â]Qï)mð)š•ÉR…[ÑôG^1'mKÊš8 eÐè(!€¤Z!Çßx‹Ba¼)‹6³GØ,H–b)žËøý¥Ï¶lÚLJ Ò©4„D¡RŒ.Ïä¼Ú¢ŽB¢Í(©MP›6¦Íò³v;¤²B­ÝÑ<ßsκ¢µëÅó²¶î›1f¨Uu^€T6‚²&”uø55‘B¡\½zÇR(š{ãæ›ä•+WÞÙ¾Ÿ$¨_ ”FG¨k“ÞIEê+Ŷ~Žy@Ø{Gà¸ꩨo(×6 ª›È>$èº)²Þ¨ØÇQðZÆéºÅ6}ÅíÀéRÒ3¾ë¸|5JbÀäM[ßÝÍ>¹iß!”E'ж1)0‚ÄfìÎö mƒ~Ë^KF`˜øö¾½oì?œ±ëОœ“Óç<Ç(Ïq¿ ÷6$‘}W¶ðy.P#SÑkj¨§Â$ Ì`‘ëÒ‹^¤é²‚ê£m¦_'òë 0 ³ÿEž•±‘ùz r]žé×J"ª#î΢€Q4e`cÚ¬ Žuˆ¿,;Ø|8Cÿñ±ûu_÷1—X+7¢áÏè?ñNuÜ€†í5I:¿¹hJËw넃ģåùô< A·‘1{ÛÙßgâ¹ô|—šÑ‹#‚`Ïm>c(:¸•O# Af]³•×ÿæýȽò³ÞÊ:weítù¼™/ïÉ”«êÜM²– ´Å'­›®T:• LÛ—4=”µ7~ÈIA¨"‰JO¤R©D"1==ýÚµkø†ë(—b)~"-áÈÃû²3³h(5ZëÉ0БšûæNBe5¤±@*ûŠ:ûÊvÔ¡iÖA*#¤µ@:ëò6kL‹RY ½m>@çŒ/hPk×Ëmæå¿ØIJ¤' à½;räˆßïÀG>Ÿï?Ouâá£Æú†´õˆ€&’HÉHúŽýgš$o€âži¿È4\xiŒkíçXDŽ1@!àu@ØÝuBï0Ï:@‚Ëd¾õÆ;yEL: Ó~-’‰?»“eê7nÞÎB`:Ùsª^`¾%6¦dÐHñ J••‹°b F)äu[s”¦âžÛ\û¨ðÂ×|Û(°xÏ|øDbsÈïâ[nr/ çô ˆ{‹m#N‹Î$`ø ÛÈ'½7ÒvH¡R“h(DQSSƒ;Ä=ûN†Cs»—ÉÓÓ³†á?}Ÿ%á/pÉÝ{O*•¿ŠE!X[$ç¯,iäÇ•Óz ¦É ëxnµÈ­•x5<§éxÅ&‹ZšulKœ4‰¼Æ‚£Ø§f;ÍnKáHÛï8o§!q¯¤&Ò’W¯>° ù¶£pÒÀëóB¹®±ÏtÜÛ™2p}ºkÄׯéD!$¨Í‹ÃúBL-Ä´o{6ðIÀPàR±CæB±xR-˜Ñåuz/qÕZâ*2Ú˜šÄ"£ëcã>ÝñÞÕ%d-žò&×å´T9Y¦tW5,T#’ڙʦ鲺‰OîŠoUãTyõTUµ·´ú‰¬¡¿¼&;}sju>Q#µ$®µ¶¹ºÝ1ÁðxŒ¢´¯¯/ÂZèë‚õ°–}k°¥ ÀéVß';ò·KDb`''Ä“4—ˆVlØzذÓÝ–ãéRºzäîn•§+»åj¶¯WåîÐzü9¾n­sB @#,BÀ´Yh<=¿.¬ÁIJ,„ã–%o*nÔ;?HÎ>!Ã`$Œ{饻•qu­aŠqˆÓAŮܖœ¹‹Y‹!²¹¼˜„Ÿïô´ªœj—?ËѹÍsM}¶ü¬ÖÑÎØ?P8¯äzz”M­*o›Æ×®óthlŒïÆSçÇc©µ_c|7S—™s~¥éœhå:ˆ$€GÓŒ¯KÞèïìbPdl4ô¤ “=Ù+{;Ð`‘ ýnK߆’|™Dˆ£Xâ&µóa¾½UW{~ËÛ–´ÊózG[ޝWýÎgÞn@#­³#×å×9;uÞn¥Û/o¹úÔùñX2î•vvKO†ç²êL‡Þòé’µAŒQœBx¼=ùù·nÞ †¾™9cc,)ª\Á;gû4ãã›=^&‚¸³‚Ç%d9§ßKwõNkäÙÊ¡ÓÊY ª¤A3Z›iß5k¾´ï«ÒllÎ\p³V?hÌŽ˜U·ù  ½°ž‹ófŒìY¿bkÒ<Cá"œôžPêÕàëFÍý&&Ш5Ë%¦ÚŸa«bتhPÝ7kG,º°-'ܨ1¦˜á¦ìqSVÄ,ÿÐÖMË"!x Ä$Åh>)ƒÉyêÌË<|,\V}iÿîÃ#Åå÷ŠËû‹*î:8x|ªùêPÙƒGF –”Ÿè/ªúxÏQýËkæqù(*ÄÄ4‰2‚^Ÿ¼¶µ³]Dì~øàäõ]ûátLÇÿ^€%ð`þOx'LR^vÂPJ$Ž‚…(‰aBÆ$ÌN‘sªOs|œZÆŒÇè2ùÁ)Û5Rcã˜là»"°)“ — ~ñ÷@ ðX7þŠƒÁÉ[ÇÙ®º®åK–Ó(@$Ž‘¢¹Tô²Í©™Õïíð¶ë›»®.…§7ËÓ#w÷Ÿ{°ü dòF¬7µg?R;/hO[#/LJß¹!ƒ*ZE.\žbþ½ÆÚ“^ê q _0ÆÈtc+Ór+ÓÝ•¼·‚ 8¾`~Òë™ï^Éò~¼4}'BQà©Á´ˆ'_­)Ê´´«|]öµçjŽ÷#¥­44g®ms^zêüx¼Ê»»r¼yžÎLë%ælŸÖÓ­3üv~rŠ˜¡ %¢`¾ L-„x9U§s\Ôz?™Öȳ•Ø0V/˜3"†´ˆ• Õ©UȰý«“Ê:yRîÚù÷ ¿ºãÞ—úJ¢DDƒù#†{SÂæí÷ŒÛ×,ÎCˆ(¯L]5`Ý6ÉCê{õê E9Ö ÖeOµ?÷#VͰE´¨ÃVõ`mÚ`MJÄÅ ˜rvnT©åk \,‹E #bqI’/R2©ÁQ›DÔ—%'û”Þ=X(2XRþÅÛÅý%Çú÷—† *§ª‘á ~TÜy»là­’Ðò»ÅÕn…~]tœ'DE4cRB´÷ÞááÁðÄ<ÊÎÓ¡¡!pÛã£çÄ阎ÿ‡~½ úȃRråò¥õ¯nâÑ4&[€R2¾‘Åp—®ü~AÙ_0:'(bpqê<£S]ÿ$Ìö¶×{C[µ©ª„–&å2¾½ØSB% |¬÷ž¾õ&Er*çŸÅ?ýôôÞ›ßÌ<ÍüÞïûyEœÏ[º®Äø‘ÀÒY죑gÍÅS‘ÏXä× ¼õݦ’ } ­Þ;-É$™8BRy³®Ðß\p¡|#ã a’ƒ-¼^»{Ò$¥UZÉf0L@‘õ‰ÐSe@/ %zñ¤®n‘Niå³]ߨð5‰h­˜n†›„´E²•ÝkPÜ<©ToZ CJ‡B± iI[ÆO9~üøOïÆ£.ÅEœÇ`Ýš8Rï©|×_©ñUUVqxâHíø¡šÇÕ³¥‘ŽMTU{öi<‡OºÕ”gmJ„¡hõ€,6B¥$¦ýã_ÿå/ ÐÁÀW«_ô\fžÖä9›³ï…¦Ýï”ê莈h}Ð:Méã'Þ‹ìc’)0AA(+!}ÁΜŸ¨‰i¶Ì«·?WkÿÁé¶½q&YP£ûùÖ@}pŒAAðº-›#o ÒQ‰t¿ìü_ N€ø§‘!#´?Š&)žC@LŒÉäQÀY0ÆŒO5¿LzêO%Ökê3n™µGæŒè,U7Eëe »‚¶^™Ý-u JÎöɬ—*ÍWvVä¶ËŠ3ƒíßÙD*7Ÿ»hÉv„;{…5˜“ˆ3<¾¼Þ)u¸7ä*ˆÁÌå[oT4¬ÜüÐ> ³ªÎ™/Û>y½â´òç¤æóJgÚ6ôãÇ×i¤c@lïV:ú•6·Ò>  K~v¤ÀÞµ×ÞYPëÊÜ¥zL‚)Žà$г0 pÅ–äçæ554öõôFA´á øC¡Ë/í/ß—±$…‘xç‘&üÌ¢šöb×€ÈÞ¸bŽFž-lÚûؤ~¨—ÿרj’oTfežÎY2H¼&ÕŽ_½Ì€SùdrÝÎ5ÁæœÏŒ‚¥‹I˜M%áp‹lû£ŒÖIîé+3ˆù<â"±®²l¿IÖËÀc=ºÂ€Y<¡Ÿõz¼Mr£„ÖËBEã ’‡ÖjJÊ7½L€#‹‘DÂà§S޳bHüDMíÄýGZ†®v T'6›M°S)Þ²w<á­¨¦½7YqôQå±ñõÎE€?:ttìmÍÄ‘÷ÿ"+ÍJJa2’ìA¸$[R |øùHÈ1¯œ«è`ˆþòPÍVpRû¶}ÎæìYµÐ´š?°"Z¦§h:С±›=oÙ¸î0B°y‹Hf¼ˆâÔ‹«6=_úî¼FWŒÖSß2¿Î4ü¤ìB¤!c)~çùCàÁ¯, ôTC¾H‚DÁ)öE$h‚:ä „þÑî›·JÔe’G²(@>|އpa'9c•`¿Àx5Ïõé‘»ÜQ³÷G[µõzŽc`ç¹¢Ž‰¥Kh¹&ë¸!² Éœ×å-}âö¾mbq*“Åâ¦ýZÚ1 i.¶u¯ÈÞÃÆ±‚¿*«ÔqMbùÏoDûAauÎÜ&løg©áüÉ‘¢S؇•gz¤u-•‹&¦¿©Û®#ß9~|ÍH\ÃBÇu¹kHÚÖ«p Zº$ÃÙgî7T­Õõ¶W6¾‰á\.F& à6I Át"Ø9=ƒ@pÖºõé‹—D‡` ÈôUÀ-•°X\k‘8z ­nY»[Ô~uŽFž-¿z¸È.Xa+XþÁÁÜègà/o[F=0ʧ´¹6u'1cWqá I5¡+56cÉc½¾ ñeã¦ßNš‹¿u-N’0Ž+W'y êp³$ •øM¢I]á¤I>ÛõLU>£Â¯Z}SSçÙ AÞa0Ãâa”d¢¥{Ëoß¾M‡½ðMÑ ÄѾ¬×^e#L ‡09¸bõ­êúÏß©Û,p¨v¼ª È· zÿ‘ÑŠƒU[6§â› %bœgÃ?‰ßÞÞ=†‘šÒÒCûŸ”>ŸÏ÷EÅ gLæ9›³ï“EwGQ€i4 ²(ŠÆq 0œ Q±ï§[·¿P[Ó`ŽÑžLó¾áGzëë[Ÿ«wÆÔµÅ4¶Ík4$/M'¹‹Å!¨=Jà0¨3BÇ·´(ÒD÷ïèèhYYCpQŒ‚PJ"0Îæ'oÏ+¯H[»”Ž~±µ‰òì°`Z‚¥ö2ç°Ô1$±Ší=û5¹½S鈨¤°­»òµ^)×­­4–Ø;sþ:"7|À[”¼cÄ"Ôkûs[º@LQëGñ/m|Â#Q?mÃï4â³BkW¾Ó]b»´&¿$ŽHÀÈøÔŒL~ZÌæ²lGvžþCÁoºÅç. ­Ÿ(£oÙûm#÷ººdö!±Ù-µ÷ËÚ;•öaikŸЂ­?2V¬Ù1$rŒlƒEŽn©³[is«¬·fRs¹ó&x¬ÂÚÿ–µWÙÖ:`>ÂŒñ¶^Ð9….7@YÓùõÒãÜ_îâ¡$uJ8á¢D< ã3±$Ábs‚ˆ€ ‰lˆ‰#xü|”¿|S¡üä9`Bðµ;FmÝKfK#b[„!EΡ—V¬LÀ1Â-‡B¾oH‘g‚F¦tâhëÕKÓ¢ìÑŠÀÖåѺ°>Ò÷ä“ÒÛ, Ä>­”6Â͹@Á'ZT~£Ä¯N6+Æ\ŸQè5€N±§)Ÿ6 BF_+kU„´ÙcͲ?W‰ëóWiòÖú› Bæ=!Cîc]ɘy÷XËÛãÚ]ÁV¥§1;¤UÒzeàT.mTÜi•zšòhsÁÝÕ–ÕK`.‹'òx ãc,>‰¢‰äÂÁZ­Ü×íÎ`£87b¡–ïð•÷wðw@ÿc¿Ìc£¸¯8îE-QÒ´ö®wgfgf/ØØ$\®šIh¸†l°wwööY›lcƒúæ06xO_{ÚÐ *µ"Q 4mpÀëc½vŒ©h¨K¢8¾w½gßf+7E¢R$úG#?=ž~šýýÞoö÷{ßÏã$aø*3¼†ƒ°û©ÜDúÓÜhæVæÆÏ)ŠùV‘»-Ë¥• @,’9½lN+ukÊcP.è9Ä‹:¹§U4(aï®ÖÌÐSCÍj$AuƬVqûlnök?çÑ~Âcãht4ŽÀÄét:ŸÏÏËËùúú<^x~tí:‹‰B"1!É?)Š]ŵî’ê¹#•óÇÜ%u“eU³¥å3Å•s%µsÇO}]ÚøåÉÆ/*êþQQ3YÜ8[\ç:QÿeÑÉÙêº/ŽWÌ—ÕŽ5¨óo‹MfGÒÙl‚†Á—@ø\Þ¯_sbbb©ï[âÿÒ…-Û²-Û’ÁÝ ßšÞÞÞÔÔT.AbA@E'14ñ©ØZλ+OG¨/E´tE4©#ZÚW6EV¶tü8óJàQtz Ç‹ypï~Ðð.zczáÜê# ¿øók‚É$™Åfã\&FÐ1¨É©¢ByëûRëXšùnšTÞžm¾ ¼AoË·”æ>…¹”NdqЬc({F€[à—vöJ:næÚìâÎ=Í,<)D;ë_Vÿ’ueLÖù‘ æw¹ú7ï+`!ñdÔ*’àîRÖÈ­=d»S`ü˜·îE‚Æ`(—ÅŠ…Úù å ?æ%òì5Y×ÜfϹü™¬ý3å{㇭ºúïݧLw“$ÖOEÖ~©mPb™ú( CaWõ K»ú%v¹Õ!뤬v€(i§ãQj.² -T7Îeé‡@zÑ #zö.· S6§Ðê”Ú9݃æ›ù†©3–Yåq[öÒÙ뢙1ÂÅYF`DÆ 4>B‹ea8´ÀÛ°e[Z™V~îJa÷ Ò6širNˆ€sÌß™FdV'ä?Ox~EX‘¼vã÷€FÀ}m à ‘%1‰F>£–º Ù †,Ýy­rN+ØpésüQ°™ÒH=š kÈ÷´AâÒH½ÍÀ*Ù‹íŠI­hJ-ö·åúÔâ 6ý“бŒHNí±|OgÞÌy‘K'Ý÷k3\-b_[¬åïTxÔY.}^x­év¹¿]ù•F%ÞH²Ù, ZÍ|’ýC’0É6“qN²- >ìî(8’úF’1NîÖ¤Y]Ö¬!Ú±‰ruöÎõACæCaÖ¶ÄzjïJñ‚Aµx!-Ø¡˜n•xÛ²ç›[E°/·žš5ˆgô¢9ȧ¥‚:™ç‚Ø×ž5£‘͵ÊàÍtJ- ´É.:²kÝæÓlúspÜX8þâîj ÃŽ=êt:çt B=Q *G L"Å0 ƒÆH_—2U~fº¨j±êŒûXÝdIõtyÍ×E'+Jë§ŽV/”6.–5ÌW»Šë/jœ¬¨PZå)­](¬p•48Ëj _Û¹6]ÉŒc,8œl2>!áìé3Aÿ¿û»pNé¡òµl˶lhz8øöÅ17ë^HHBQ&Çâ’‡òVqãé[_~âÄ©§šÚ"4Æ'[zVTwEhºVTT<»z3Š¢ ç솚:@‘Ðl@8ÿãMî¸×ëývà÷ÃÓã:0É~Å‘h„À9à|)¢q“7Ì“5ÿ>ÇxKe I›¸Û!±õK-·•æ[À$â.»Ð4*ê¾'6É{F¥6§ØØ/³ (»JË€ÌØb*j¾ºù@~LÊöŸ½ŸcìTÚRÞPa̸ƒõ†WóªA†9Œgø¼”ß´÷KzîŠkt&Î…d8ÏïïË«Û#+B‰ä5‡¾Šö«]ÙùÇ„mÀl“Sntu½¹GT=#bÓ°Ä2BYb ó-ª{à&ÒWZª®A…y ÛØŸ×Õ§êì}]¥.²ô=JÍaدØ6ò/,é”Xn?ÌvÊl‡¯–avd˜ìbË-Iw¯Ôä…æS‘þêþý«ÊâM»%oÞµ)e;“µ†¿æÅõ¯¼™”zð%eiz‹UÕ}2 „2ï qˆÀÆ “KLß™F(ÓP˜Y\.C9,îö»ƒï#Èÿ ¸4 ˆG/ƒ8pw·çøÚTÁv¹G- ¹VìÕJgôù3-B—F4gP.¶«@å}Ò]ZÅ¢>ËgȆÎ }:•WŸ5¯–{Z”@#c­ÒÄxLJ b?){kÞ@M¶Ò(‚ÚýAµÐ×)œÕÈ;rî7uòÝ%{6œ~{°ŠG¯¸Y%‹c< Ç8aœ¾2©-qJëÓ·Ñ ƒ³s-×­—ºµ2{…€ÇŠ}_‹ Ÿ«óç ™”¥ñé?brÉGþÞ$žmÚë·äÿ­5ïsu.,Ôgøšßò¨0b¹ÕBØuhû‰O'óëå¡/£•Í«%S%ð’ÿ|†§],Í8¼‰%œAÇ0çpHn ŽA’§È½wïÞ’Ö/Õ±ðH Á€Ï~÷Î8‰ÐLIDwfPS¥õ“ïTÍV4N–U-”ÕÍ”TÏ–Õ¹N6ΕÔμSá.ªž¨ž9^å-®ýêÝò¹òÆ™â†+TΖ8è6"ãQœË@8Fаb¸4…3Zúxkà²-Û÷Õº,o ”ñññtÁ>¥G2ž#x8NN¤ã äú•ûÓ"N7ý õòŠS—"ÎëžH¬a œ„;ž²~c¸Yp»½Pþ÷Éû‚þEß74~põ}Áû¸GXÑLŒ@Ñ6ÆCh Oy]H5ýQiZC:›irH¬ÃrÛ°Ü:Ôz#@!&± ‰ºì!,±:„ýÊnga=¿óŸì×{l÷ðý½M*BìóùîüNBDD… „Ð ZÁ y:~ž_qa<Ê# ¯ -ƒ@ž¶c;~Cè¶>”jl¥oâÄŽí$°M[ÕJ£!'~ûöu¼UUÕhBê?òÓWÖuºûÝé÷û~?ß?+ ŸkþÊã¶ |Uóç‹òòŠ„¯WDÖ‚lÉB:ðNôØo¿jnž¸0yøtèh¤u¢¹õë–ÖÉ·ß <7}êì×Í-á'Ÿ7·†O]ð¾u²z]Q.“. £g±p¡½\¸Ò¤ïMFãj¶KÌŽyŠÌùñB#UÓãñoŸÂRÉÙ¬ž¸ñÑÇK—¢4šzSE° Å/üÕO[~ÒݳðHË’Ü圬—x 2ÅÀGŸ¤o’˜p4úÎó›ŽãÛÙæM&"±Xâ¿þËÏÊ·—f³Ù&ƒE§áô,.›ƒà|wÅ+Ûªå—>ÔöÞÑ:ÇÄ®GÕö±Z›_æp“öû€ ˆÔæ%~…+\Ùo—=b‹›t¹ëœC•6Öõð¦ãyüBÊÙ[ð23‹Ãà®Ü©U[½š¾;ØêMÉtZS› pRç•:‡ÅöÏhôs TPk»­4Ë{Øk73˜†rôkPk‰¢•òöA#õ–@­ÙM^Uöyœc’þÑ* ÅµÇ)'Ø|)TØ2K¥øÀ/vÝŸ³š[F€"€Ò1 Søs®ëaª 4•# êó“F/™ÒN>ˆÒåQ؇d–AiÊix®Ð¨¶úk>ɵ€¢?†‘[݇OeõÁýÁ0Š~ŸÌ6¨v¸UöA™éhDn{Q(R1,wh(šƒ£Â,¯¨N&Bs®’‰FÒü€ŠÀiš%ÁNYX§œé‘…õdÜXÔ©'º¡:7;Ä”^ëC±BÄ{$Ó¦¦ë{w­ØúêJ.]ë !U28H!ÎmÛU’ÑÉ~ÉgÑÙ8MY²üi‡=|bâø™hó¹'Íï^¨®^Ãæ/Éä2 &‹%Àxt--/ ÿIy *Iå¢ïdÔ´Læq2?æÇÿ°wÒÛ–úfÅS‘˜‰Âþ C‡ÅQà8ÁFÑLÂ[º¨x3»¨˜À²&À üV•CÓJ b³÷Jýü ›ï{»Obv²áx ŒÇàÁ7oÜ(Û¹‹ËáAcˆ¡L.AôLcÉboÍkµÍ=ZÓ]•kTì¹|"—J°ÜæI‡Ì: 2IãDiõ'ª\¾*ë=ÅïÇ…®q¹ÝÝdùcYû@IÍÁÂ5%,<ËÊ_¶E^m¹Yëº'j5,dçrY(tpÒÓú†UZ}BçHùÂ` :Á[ÕÐïÖ¼?³nNÀDK,—‰dòÐ —½©¬®ýSqŸ¿îwŽÖ^þdýnÝõûe®"ûð>ó Ö:"µŽQÒp[xñrý€Úuk®j.¹:&´KùU¯È6d?Hlt®ëSîöØj«OÓ7¢µúá@aö¨z‡Á 4©kDâô*#õvß^ÛH½1 4 Áq½Ó+²Ü­³ß_®q<”Zî)¬HózÇP½Ã£°¸•v?XèE5"·r€… >4#¥‘²J*žs•üH4‘¦°ÅŽã½ªdg%eÅ»E‘κH·(Ü!„cÊ ‰éÄ”Ní*¨"]²¤žüçuU^ÊÈdáÁdçð²Y : £ó¹,XóK°¼µ8Í}Vyï¼cÐP¾`9A÷Ûªön`™/.ÌIèÕ±žšç]2٦Ǚ8®—¼þ¯¥kÏn‚–Åà.߸L0Ó¦HtÖM÷5þíbÃ/ )D±uË8SæCIƒæQ›8yiÇ2üý]ë§ 0áˆI¡ºªb]ÿf¿Ìc›¼Ï8þߘTMššÄ±ßûõë+wÂT…ŽA(é¸$i.Ç÷‰ÉEAM BÛ– är|ÄN›Ðªî¶+G $ØIÈÁ¤1•v IðùÆ~÷³ ÙØi•øcòè'ûyåã}~öïù~?O™×Rå7¤ÏîŸi‘Ó— €Cf[sí*À˜Ô×ZÊ´‹™¶¦¬Ò@[™·C>Û®}tNÑ\¶m-ñŠúy*%$‡t@P2/¥BW991vB!7ò0ÌÜó‘** Æ€¹\`‹ÉLB(h:p6^ÇÈ›ºÃ¾“ÍŽbŽ4¹ùÛ»§æêOÓÇšÕ'™ÃÁú³k‡êß^‘‘ ÇclÆ%>/¥¦ÿáŸ>ÓM€:>:¬D!Æë¼x$ƒ õ¼\Š¥ø?póçÍâó=ùpÛ‚~ „mÞí£½‘ôÆŸ®í|#[€ˆØ8,¢`Îb“‚á‰Mr'''ÌGF„p€§@ðeÕ¹0kD5':k„¯CÏn¥'" P È»ýôük_–äïÂ…8‚àÜD‡ã9,˜JÙ¸cOU£Îø™¡?êz…Õ©ìu©€_79“húG%ö‘|Ûˆä긲oPÖ}[aPZîëMƒ²þ¥ù®ÖrGe½#·;5WÇŠ.ÝÔÛoîS°a®çâ„hŶ2UËgJÓiÏÍÌíù"”Ëå`9e:ëí<ÃoqT˜±¨„;5µª ¿Ûa8žºމ…HÑ›²J•u\rexO³-9»dcv[Ý™—oŒ×õÖÏKí—ïËm®íš"“¤²¶åss0ê~—¾÷¶Öô…Þò%HdÖ2«s±÷+­£ ˰Ì씚ò^§€øq.9ÄýcRÛ¨ÒtOÝíÐt jÃÐ2(íÛï˯L”Úî•Zª+cJÛ7’ž!mï8€MïP„%\2ÓøB´û¡4¢² ƒ¢$Á‡ÙBäîÎc潋” üˆÒx4°æ.ˆýFµ§S7Ói˜é©š1êüJ¦«Ý]U³5 Ã…(O$J š4¹ŽúÂé ÚOëŠÖ ?a¡< †Î´è®~=‘‚` Á×jw2ÝŠ‡çd<,–O¥(ñø#…§]ìíVÙõo%A±œXhw&6gª¿xp=ñ~ÊGó×ó>Ñç´ªömß½ŠyÐø˜Õôy1mÖ|ñ~ñcSíSc…»Eæn-»£ÛÊç[ “L_TºÛuL·|¾[7s^JwéÁ#û•q·•Ó=wk`˜P§~ÆxèæûÊùëWAË çU1˜Ãæ(Îá¬YùÞ©Sžé9&ÜäŒ7ÈøÆ Ký&¿àûôsu‹ ȳ«³7wÅPÉÃCöæGÇߟ;Ñôô¼Ç~óä至ÇçŽ4¸5.:Þ9Ù¸cŸˆ—„ËàóD<†ÅÃ…|næ  ù½aÙôûýa-Š®à 5,AÈR,ÅÑV]p|Ð> ÁAy£EGýÝÿ”ñt~Ô“¾|†Æ‹`ƒ Ga(Æêêê˜øæéðGB‘ ú¥UíèpZHÀ]BóÁ(x‚þ@À•˜QذÀ&æA>ÿðáêÊj#a”@Q˜c‹ƒàTæælÕIMËç*‹¨Úê”™ï&(·G6˜‡•¶1©ið ùV…ePeø¶mªôÊ}©i@rù²wRsiDÚwWÜs£ºoJlú³0y…‰Dñ° Ž#$•øÚ¦­ü´t'y1q|29ï„Qf¹Ee„ ±Ù¥GÀ­÷ôO)?UTÓ,Â`®L7ti¬ûžãb$[˜°nKAõéU¥Ë7äíz·Sb•÷|µ©@˦)ÛŠ4‹¹¹l¡ëÆMùF^Æ.é/U'öÖ[ ÖE©@múFmU؇¥ýCâ~§ØvWbsHí.EÏ ÊâTÚ‡@.± %·…!°Ôr šÒî(ï¹­4»ØÆU]#2@šQ™m,iïEï(ø¸¶×õƒiÄâTÙ\åf ›•ÀìÉÝË„ü‹” G^ÀÏw©ŠLØiÔï«Ý½Aœ•\¼&ñÀ/Ò¬ºíßvôu˜íÔzŒ*O‡6lîí ¦¥x®»¢S³‹ãÂÎIC¿í¬dÚŠ˜ö²¿výuÖjg:]².ÐVT—³&‰c¼åÍ…)€y<ݺÍ+¹|Œ øäåæ§ªÙvéDKe ;†O¦òÐecM…³гùù›Â„³ýã½ RI4oÓÖâsñ¦¼ Lk)€wÛ~w‡œ¹PÈt(|åÞ6·³bÖ(óvÉé6m Uã3JæÛet¨¤ðz[J¼Ò§FùÜEiÀ\ñ]Oe_õ®¢×¨t$ž€ù$ORŠc…âܵY>niùþÉtäÿõ†|ð4µxÐúð.Št,ò‚Ÿ¦DÌ_@®ý—Cà„B¡DìÕ«j%}èÔw'Ïñ¼×ô}mÃß7N74› Ës„‰8P8 CœK"¼õ™Y×¾Žœ4/™¾ŠD%ˆ†ÂŠü÷2¢òµ„%K±/1hÌz­ŽK‚VzjšÇã¡éÂhüÿ…Ö‹êOT&&&jjjR’’AÁ(Œ€úIP;‚‚D$fV«?¾zÐ>Pn÷Èm#jó°®Ç¥5 è­.¹Å%ï•ÚFË­÷”6à³wÕö‡rÓ˜Þì2˜n©lÃE–úÇò¶r6J 9 «Êªêaa‹ÍæálËÓ”¼¦ VÒçÔ™¯ñ„ë…G±´M—µÖ¡â+)02]Å’(æÂ±bû}€C›òŠx\|%{™ !ÂI åð0hcIñÊÌœ´-»W'¥Çp9jù®çÕG¸Hë0@)­yPcu‚‚‹­ãŠÞI©ití¯JþÁ~7qpþ»™’V{k%Y–dÇ'P `Cˆ¡@lÇ€oke­nˆPÊQœLC±‰¡ ¶uK¶$˲C Ó é46Üà+>¦3mšvÊalÉ–,ÙÛç8C™vèL:ÌФþÍ›7;Ò›÷v÷½÷=4MN–.aH<…ý@ž™·¾XQÖv®¼ãsÿà—FÇõ‚²Ý¯ü¤©ä@•çªâWƒ:ß C×µÒNð@@;sTT¾>à4Ð=m`ðIŠ`<ÃÚÎÛ W¯éôhE{_¥XÕ=Xí½üM5 íïÑùFb†’;¶íÛËxåÏD#¬U4«Cv Û¦šl)™rj3€Æm ¸3m)ÚÓíêˆyWÔV9åÔMÙ¬[rjÃvú”jsÑR(L,‚ 1€ÏNÆ$0"{ßþÂe¡¶Êi³*Ôª ;kƒ­Õ¬£:f§Ç,Õ·O(P$5zNq¬8j/8”ù¥:7M Œ‰N–­ºçÙëÒnÄ0 ÅånÉYv”Gj½†B8NÑ9Ya÷>¶µ8b7mËâðD$ÆãuÕl šËï¶×,ZQB‚‹ÈQð)™í¬ÝrzOÆGadφ´¨SûHTA›Šu2¬]5í©#ãšrÕ­†°U7cgbVÅL«:faf¬ê9–Øé˜Su” ˜œP䯗‘Bƒ ’‚á“0Ã0Ayyy@`~?¾¼<…DgvëMb2‰“ÈbÈÎìÌÑw¢Ž7Lì;®?õÓÁ²¥+1æQ$¼ Š¢‚Áà?OC YÈBžUfÙñ±‡àúûó¶äðy€ ½í°V<>CŸ9Eæòèx2p„yø`¬áÇ2ÒÒ!.¬{)˜7 ‹¸h²|]añQ‡ÑI廯xô#tàíQ´õh¼=Z_Ê{Cè×t *Ún™¨ºú5ݽŠî¡ÒÀˆÎsqi-ƒy|T¸ü5ÕAÿï¶½ù®0'ÿyTšˆ%'$gl3¼et~ªúpØä»’±r;É“(NQ½»ÂuiWçîƒá²C­*¥A²P® ŒT$-ËÁq”Jøa\ÒryîVYN>$È|¹Ê@`Ù„0]H…òÉÅè’Ûót?+kô3m×T~`†!uGµ§Gí¤;µ}²¥kexb!átˆ“$Nr…b>Ÿ—¹¤ðæ7;n#m=âZ,.ÏÜPç¼Xá¬ñß©ñÍ5ep÷Ï££_5ž~`]×МÊ|}O"„®»OÕq]Óy“n»ªïú €q߬ûæù¶hdÖBG ‘ˆ­"êf´íyØqøï6SÄaœhUGÚ÷Þ¬ßù§÷´“vì];mQÎ8Õ“Íå!³rÒiøiþ’4|nhB8!A¥p‚J$1K–sŸûs³‘u«§lš)WMØ®ZéHKåŒÛøÐ¢ËHNa\5*òß3äë V­ð¸|œŸ%$‡OVO´–6Uñ‹eIÉ8Ý?Y3ëÞ5ŠáxH,{ã\<ÎŒyÕ÷ì{7É8\AR!Q®•…ÛÖYuÿóé[Ê–ŠÕ Eé­ôª¾&}Èl8>z¾&'—`‚&“ÉKFH_ŒKVlÔÖë=ËÊŽÏU[êÀØÁ®ªñ÷‚L¢÷_eº*;þ>E÷ˆöÌm“ýc[QX  ’;úõWª-×EÙ»h”àLhHŠã8Ńæ¼B¼ºò}‹Î3Ptü¢€¾ÅéÌ<ƒ·KÙ>Rꮸ6¢ôôÖºnþd÷RB#&ÉÚ,ÊÌKLYWxò½·»Ü3,÷j¯Œjܽjç}ÖÓóÎ{-„Ó(„’iç •íîqÇÀÁ'L‰Åh<‘{O4)Ü=ù姈 É-eu9Ø«U¾þª+p:`€ ƒ(`ø`=!”®Xá­²}XëíR].p¾ª4±hg¬Õa@ÅßUÛ$A‰”¼GFKøL&FÄI(IÔ剺.8§ö饒;¿8X&E…lu“J¹Võ×­µûòSŒ0~­óL`ƒy²ª&ÌQߟ3«#f`’kÕÙ‰‚8‘¨É@¯ q;RÃîÔ¡÷Ê·„[«¦MJÀH'öf#˜Áê÷fŒ•œCù‘2—!Q‘|ü \ ±X±5/]_¾]2tAÆY4!£&l2Û™nx{cÃÁÍÚœÕkˆâñ°äÝÉ ÁKUœ­:Ô¤˜sTOšÊg-ì”I3i­7)'-ZÀ<³MĤäÌ Î( ·hºÏªÿiæ:!P ¥¤|ŒÀIÃ¥”lÞ¼Ùh4~ýÍÓ¹…»»ˆ /Ä‘HäEµ‚0·*ÂeoÊÅ!&@¤yòD¯«KOË€aˆ"aåc| !I8tJÎŽ=ús¬ñ:ß`¥' pöV£÷*|4íªœ]€Lôî¡*Ó­}††5{­=T[ëë×´?f}+œAÖ`Û¬=ì¸ÄqÏpùa™} Ôß[iýlõÖ">O„Q""PÇáxšÙyô×J÷}m[÷ßR <„o-¯S;¾Pø‡inï?ìVw‰¤ ö+ÌÙ¨§Z5!»*lS†LeÓfÕ„½.øauGíþ]ëédô‡b8¸¼§(Tˆ%¢«„ŽZ}ûO×ç&ÇÁmpÏ&Âsÿᮾàh$šsžûô“ß‘B1A i’¦ f¢EDˆ}»hÿ­¾î…££²ØC€æææÛ˲–µ¬—¥™™™X b¯±j]Z°/]‘}oK±¶¸– ,ll|ÌÜlÌÙ°Aƒ‰Q†U ¦`ƱèÜ IÒÖ”W¼ï5x{Tî€Æß[æKá¼Ãzº—GËë\ÝG=7u®;†+£Ö^½¿¦= òõ•ûzÕ¶¾ê«£ÀÊužë’]ªð÷qÜÝû˦ÌBùêyëò ³d'Koè|Á÷@µ§OÉc`z$å >Öñ¥°ÆTûº´®G‡FÐ)Ø)½ªí^•ûK…7 k,sÕíÁêö~­»[áî+õ «ÁÜB P¥fäï;ÛTm¿¥q|QüîG4ž&N\IÑÌžzs·39cM¬~qð¬¹ÂÿpW¥ïž¶cTá‘û<4¾Ea]=1,y.\ –;oWz»k|=L^! 'RBé¡“¿ª48d¦UÇÙ5ÏšåcVƒrK:…Ó‰drCÑÚ)GM¨IjQOÙß:S*Û Å‰pøgd‘Æ¢pSiÁš7h*àòü¬½SÓ‘•)X…k¥´ïHg/™¶›6kCMŠy›:dÑÌØ«rL´T|kÑf¦¯‚ ÃÇíšmœ 7Ê9Sñ¸‘场)«žk‘‡Í7פ£ñàj aWƒ3—Ï´ÈGÁ³ ÞÝ Ûr¾bÛÃFu¤…å¬eÅx›6Ô¢œm”=kÑuÛž¾N¬LØÈÐ4Ÿ››uùãö£v]Ø$çÌŠg-Z@#œE6k,™uÂÍlØT¶éž¶Ö|þ«ý®Œ4‚ð‰ƒ‰’p’Fa„!qŒ—°nUÊçÎõ¿ÎFéc†›Ÿå@‚ò 0aÉø°xQÍa~>²ð͹¿è‚áŒR¤0 ’—ësyA‹ˆ1Pd.ÛÉ÷˜dYËZÖKÔb1.­Êÿ7á¾c¤Xö¶´,rÈâÀ ÂÓÜìh… -~òùõýŠECÃ-dp>,‚ùR`…(Æ&19[ØÓÇÌz×m@êön¥¿Oæ‘y‡*Ý=jo_Ô‹=CUþ‘Ú+Czï¿Ù/Óà&Î3Žì§ñ¡ÝÕjwuø]ޤœ.` ;@8Êm¬cW«Û6¶ Â@ÒJ` غmYÒJ2ÒtšÒ6-ÓÒàË’l& ™N‡q_:,iû§ž´¾tè4Íø?Ïì¼³ûî¾ÏîÎóþOÓÜÎÃæ@˜õ…OÈÌE`í¿ü`òê‚­Z®£:دs¶™Ý­&o›Îß«ôÜÛóó«Y%Ò¼ùzO»éjÂÛclê4xÛjšû7Ö^’bù ³–lÈ¡›î²þˆ¦e@Ôp!¶¹nÑ{Ø–!ƒ`á‚Õ(.c”„”ec²¹ÄÂoIä&“f‘…R-šÏØnt’¢|’šCP”Òò*0 ¼x}ÿY‹¡ù÷@ª`7  BE ¦PĬõ„Pø:ôø†¦çæ-*Ì¢t#ýÖ7•F’6j3d ݦzì0Ÿ.ß E³q‚T¬þî°ë0ïÔŽ¼§M¹jÒ6]ßóº"10n."<´c}ÊJÇíúºÒ%‚\ ø¤“¸T,#sŸ“ ) ~@—;yR9ÁÚtñeÜJ€ãG­š˜Û¬)[ÿ®H(®*[scï1I«"éÒ=¬×Œ5â-{cõª„Ñ”H¥ž/šÕ¨[;i§ãNfÔnNÔW&ÞÕN6i4Ç™±†Š¸ý`Ìzh¢Aw›5™4~}dׇo«¯¼¶iÐv$êz dÄ®·TðV%ßhµ˜'F¾‘‰Ú™‡ÎCIge×iʼn«–É%€ñ8)!…B2çyø 8"Ä…¤Xš_¶eË•_¼Ÿäc!ñd4ÅO×ᓘLC|µ‰˜®èg£T†1 ),èGsr ‡š=þÁƒ<¬ûD’O$“Ñnwÿ¶«<Ë|f4£ý§š²ò¯mIN%ö/¼ñDÓ(òåŽ1>‘™‘Ìti|†Jø»Ÿô}ëpqA‘'e*CrÁ_(D€#ˆD"AˆÂEÛô›O4ëÛt¾ˆšÔªÿÂz"ŒÜ\íÑžV­ç¶ÎVûúh—Êb¹C böµCèÜ!½ûS5×Í+ÜC†à}°x-w›õ·«ì<ë[TRB"øÊõÛÕÁ»Ê@Xªôö3ÁήgþVµX4{6g=]·k×ÃFÏÇZ_f µ¯Gïï6pÀ<¬¿‡öÞ‘a„ ¡rÐBòRVN~BIr(§Pr.%,«9®mÚæ7dN‘HˆäJVTïVºÃ/­Üfø¼tþŽÚú*w+°Ç®K•ýôúŽ‹¿eš;L-à< !o¿Áf½ý› '%$–·pIù…ßT»·°)+ЈrĪwUï*Âæä‚Ý/Ïû»ËÈ[öÄmƉËjÞ¾{Ô¦ŠÇ¾`$Ÿžä'MR™HdÎA㘮_(Ø©Vbº„Ÿ&Ÿ¬žY!žžŒ©=(âLùO‡2éA°*Gr2³$ãÉ/o_mgf4£Íè¿®T:Àù·½ºUB‰‘\ER±Dˆb`ÜE`„HT8oÕNý3W•ïÏ:'ãïÓúµ\ŸÎ×§õöêš#p„È ˆ?bâúÌžˆÑÝmfDh0tnˆößzÞPø»Nt\‘ ÃU·»ÂÙzÀq›ñܤa}!°fCS¸ÖÓVüŠ2 牨åß[§|Ûªl¼ù4+ßwîƒl¢¸ˆF•yãâÌo.Ù¦\¸ª4íþ%ÛM»~ìÕx#F.DŸ²ä‘-Z·EÛ|«Ú7”¿x£B–æ4þAí•ðžÃ?É—RÐE~gã>§³Â2{RÖ9¿ÁplmùÔ§¯Uº´×"¾>“¿UÑÒ§¶j®„ÔÞvMKŸÙwSèR#Z_HßÜÅr}»}å×ï+¯ôÓ> šˆ6ЫjêÖºÃ&n€ñ„4Ü}0ôÿB#“Ný°KËÛô#vý¤uoøä‚,‚,£³Ù+“Ví¸•‰ºÌq‹ÀàWÇv92R* I;Ñ ¿}lP®€*ÆÅ‡¶C|=›v2 ËÞ{õÇe†Hç y¢§èÔ%&m©±U&ì ¸u˜£6eû»5r åyÙ¹8ûÚ„».mQ<-Ï1»1î0¥œÚ´†ii‹*e¥Ó€–Š”Mµ«Gì˜S?á0&­€%†q;sh!¢VMÌÆÂ½cŽša{-IÂÁ>n`>¿¤óWmV­™_H YAà"1I‰„8¡d ph•úÆñxæ¯MaÆt/ð?ÔT&SY wttÌÐÅŒf4£¯¯Ò_ÄçŸÝ?÷ÎÙ’eË1ºZ2Ÿ‹QœÈEÅÐüy³q¹xÙ+¥ÚÊKÑÎ[l “y?¬ºÖ£âº"L¾°!ÐÃz»Xw—ÞÞÐx{hoHíË€¸3ãí„ÿó…ùÀ!0 ›» à$ÐÈÔ}ðžÁÛUV÷ŽtÁRQÖóTö ¸T^°fóÓhäÕƒgPŒ’ãˆ|é:£óOJO,Wí Õzo™\¿3pêÀ=MSçú(* Šªd®újHgïD©| Í’QRÖùGÖ׫ö÷~Ÿ>, òÄâå5žÎÚ_1—?\°t.ÉGá;`¹"RR´¼´¬ÂŒæ/ÞTúfðì×yLWð«ý£Ú ‡¹g >0Pm„¬¢() 4Ûn›³ ))ØØãñŒ1Ø¡!Ûv·i’¢®Ðª«F 3¾À7W´‡V9ö6›H —!æHJÔô­V-IxöwÙ(ýsÙHþêÉš7²Æ¿‘õÞïót¾[¬÷vÙkÆŸÖ¾÷jÃÃàí£;¯œüÈqòœóŒï¦Ñ~­öc»î\'c»b Ün™£Ý늜ÕûÇ¡ÉçE#Ñ^ú['#ðì’Ó$¸|ª)$¤ZH`ø|§EðXböƘƒŽ]Ò výŸÎÕ•`…R©GÄq¾1Á›–üm¤8‡@0Ïÿ•f7.õÔ }oõYK$Ű³`7.;Li—n±‡)WÀ*Eðëgëã6]âÒ1 ¡[êa.êö© BA ;HÚÍ&xfÑi~½¢XA (ÿÜ«‹—¸pçhª>X^š+òH¸F•{¿“ì4€Ä¢Óuh'·™„ÞKîfgã+nög·; Ë}VÁÓ´Ú]¿i©¼Àiî–˜Ûºìh^v4EæDÏé„Í*I84q§6êÒƒyÄ7 ÝÇ×ìº%ž}ȳ«뿜Ϳ?}¨­ZU*CåD rˆ’aJJ¦Î‘¢"ŠÂô'•;ßÿù{³‘°^«ñïVÐSÉ\ÿ/ïæÉ $ý$Å$“É--*›l²Éfó<¡ÈGZȘd9‘æ}û÷WIÀyœ‡"" ƒJ0)ð !!)yEYuÛ֋ºÎ«ÖPXïšlY`‡ç|“ÚÀ$ ë›h L°Á0çŸâ¼aÖ3 º<˜Ð†3É8 $3ÖïfµýáFðý‰SÞºO‡jÏûZzol¦‘’]U²î¤7Ø8ÿ°Ñ;fòŒ±ž)ËÀ,;t¿>pïÝÁ0Q¹,§ZèíŸÞ7Zûñ C* )«Ø €¤Ü3æÔ{Ž”â áµúØÐŒ®Ãár’ÉIõË{×ÿ:xð—6EYuL)Q’„Åoµû¯Øžk%£à|\^d Lq¾ÏÕÕµh¾HˆajŒT*`XŠBDQyÃÙnëàÇœÎaAý¡ñçE# Å/Ù¹d¯4î¸Ãëk:Z©À1Š€$ÃÖCñ®:Á]·êЀî·çL•<EUÊüÏ×ÕDùuɬð´éÀL ÁRYõKå¥ò—s±¥ &s^T²<ßÅÔ?öƨ]ÿ¸ß´ìhLõêÖøæ´­.ádBíÍ1—)a×­öênn³:×4 GÌ΄<æ¹G6&Æ€ˆ–슃YµÓI^—´‡Ó)Þ˜r˜»¬àw\Ô…,o6ìý± G0‘BnG9 Ã%„ä¼€Kò*Êwͧ¯_½–q{*‘Ì,–Ì5húOS$ƒ-̆F2Ó-×Q6Ùd“Í÷'olY™“Ôw÷S8G-ìË/ï··_¨¬¬ÀÅq“¡"¤PJ*a)Áa N*Ô{ªŽ´ý–¹xÙêù‡98fŽ0ƒó:ÿüBŒèB3thÞx2‚Cp’Žr‘ŒC þ0 iñL¶ /Ôûæ´C ôåZºK‡l¦¤ …Ä8¥ªýEp…aðŽqà;0äcÜ¡ý­oºÍûw‰²˜ÄÄ8"~ç³?0Á‰×Z{FÀ9wûžÃ†¡y}ð~«oVUAâ|ˆ4v_§}w^Ѿ¯@sŠÊª¶ùþF¦ÿÄ©žáÓè7(²µ y¦*PÌ3•g“M6Ùü¿%³Se6ϵ'Y¿ ÎyIpêÖâ©t|}œû°]%WQ8%“É0A11ŠH(·XIá³_çÏMœgÀÿ€NÛClI{ë°1Æ'G8p8¤¡b˜:Å`lkwµ«Ã²± MIÈ@šÐä€é¬ÓÈÒê²I§0Ó !”I lÉ–-Ù8éù ÓfX²N[}dQÓÆÓ™6 }çwÞ]­¤WÚ}÷ù,Ž*–—n|¦Ž{QyêW:‡ŸÆ•Âçj/cL)Œ)ãY“xð‡w©=c:$'ÆÐö µ¹Ç9÷$íž =AÚí½äøÊƼãÙ{äTÿ*Ýó;Ö7ó®çg<xo‹gTÓî4œarbQ(Bk¿XÚ@¿Iâ)•­ØoêCš“}(U ÅHT\Óío«Ü¡\ŠJd(¹~)]ã¼+¨u}²ìéȊĸ¤Dßwƒóúë_ëÅyq¾ªv›j`´Y”oª_ •mo;Î÷Ýèöú71/+Ge"lÕSû˜Þ+Êþ0cv¸Bªàâ‘i³*jP§ŒM ³.bÑ'z™wŸ §(öôŠŠCÏTׯ“/—•¢âbŒXZL ÞŽÝ)[ç=‹öK#1øøxS©¸PQô­*ô‘ÝëËŽ6lhÛzûÝñ3|Ê ÉØ»â=lÊÂÄ,ì=3›ìå“&.iRÒ½mð¸"nh‰Z#í³n¡yF-긕º¤ÍLÒÔšèiM§Y9ÐHv§‘»ûsÖÿÊþS-u;VËpÑ· —KÄrñ’2™”’.-(ÂQ‰x)!¢HK·¼î×_ü5(O¦ ƒ…‘=/øÜ©H§Ó¹A2™LÏež"™9¨üÏ–ì¿Ïü“EnV¹ùäA’O>ù|c7«¯~ˆƒ;X*{ †–N¤sƒ™ì öá給¼ª %1J!Gre’Ť¤Àp QR(_A­ÛQÇåÞv¾`¿|Xø¤Ý=ÄyF•îQ¥dÃj§ªpŽ"À’yd_êVÚ‡x!¬uê<÷&ßw]+Ò{î/p0möójv…UŽ«:ç5;Èúü*ßH«/D»F÷¼Ü#––Q¸b]íNTùÆží2ÊqT´d ‚(62GZüFeí6D,!%"|õV­p“v ®ß×!Çqس¶A§õ†šc:ß×óÁ’åë¡’vÇãÞs±LVZ.ÂÖlÜøk•nzŽ|ì)%k8nf~?ðùWl8R¨@5O6ðŽ™÷ÇtÎq­}¸ÙíX4%>iÔÍZ€F¦,q[«Gû}L‚ᤌBåÕèb”@ P¢œÄ+1b³üÑÞj™î=”éÑ$mºd¯jÆÂÞþ™Ê®Û<ÑrÏÚ=mäÀ 𱕈•Möñ)#1°q‹&fáb&æþ—š¹)—¶µG 4ŒS6  (uV ýBóœ2k65ÐeÆL§,ªh¯þ Û¡?[~tç$}¹kב]+Ÿ¬& )"Áq¥¨¬Y$EE†”\\$’‘GÓ‚Ó½™MÍNŦáLLg²dæœ>¿^`…þ_K|Ž÷_Ïúü/’CÈæê"”¿ôœNàk:“‰%(™ÌTúÚo®tñme%ÅI("G±)‘ˆâ")VHb…XÍ–êzÕΣ¿l¶|ÄzGXO$È!j1 !°°Ù2ð)“EÈ„Nq}Cj÷ï sîÉ5"„ôŽ@»s„÷L<´>¿Æ<àúLçð«V!ÌõÞü^ÿÖ½ôŠ-;W>Kk}“­ÎÍ{Êäx))–H¾#-%0 ‚a¥R‹JŸjñž‘Ý]oâ©@‘¹]u¬­?ÔxúÂÊÍÏQbI)ÊÊ;½AÎZßvE%2É¢Úïíd½“:G ê‰]58%®ñ'öפÆ3¶³ë‚¢(QIE-|øÕ&÷ ÞÒÙ‡[|ËFI£~ÖÚ5ðw-])»ò·/íÍžqEEÒRQü)ˆ”Ü_[Ñ£ÙΞýaú éá1KÓ=#Ÿ4©VzÖÂ|iPÅÏvÆŒZh ‡„»kV§lÌ¬ŽšuI«vƬŽðO¬—ƒÍx—éÕE{T9«¤,ÌŒ¹u¡yF­ºì1feÚBO™¸àëÍgš7iÖË@I¢‹)©X*C¥Û8Pš °òÊJ]{ç…‹—oÿíND"~ßß ’øtf&•™Í®Tföó0³à9úGâñøº.¿žÌOòŸVw>ùä“ÏÿGÒiàÈ}É$‰‹/l﨩ªÆ5’’€"Hh°‰¢(B)VÕíÚÝñjË[B·pý€gâ€g¼Õw‹öMО°R²®Q€Iñ´ý#*XbP ½w¸ÕT ·xç'L¨@)®0纄 i8à#ÐæÖ Ãjas rÞÁ…ôÒá×8ýzǵÆã&ÙêíE" HqyeÍÖÆÃaeFnmà:nªÝ“¶«²5ÛE E".‘)H1!CäÅ›öè]ŸªÜÃuìK„d1FÔ2‡Z\èpŒTm®GÐ̾×½ý3kh#Û%#"|ÙúÆ.­ý:í ©¼“Lï`»àX4±e%6Ò‹júÊd_÷­Óª®Ç¿ûz}•aÿ†ׇO4Muq³zƦJ˜ÔBÒÄ%Œ*賓4³Ð@,³&fkƒµh#mÔ¦±ª£&ÞïanÆ VQÇ,ì´ Žç¡Ålêi+?e¦£V:ac§-­1[×èIÆÞQ¯Ù±vu NI å(QŒÀUHÀ |ÊõÐàÊ\½rÕ±cÇ.]º”LfÿÔ\ŸO>ùä“ÏÃ’œF Ï=pHà©1•HN„Çßøéëk_÷üÜýŸ,ÂKPªŒ”“"ablYQTlY÷¼¶ñÅÓݦóÝö+m}×4žÎ7ÎxÇÕçþȸnÑŽ,9Ô®Æ1¢µ3Fx_@åb…!Nh]£m®°ÞùwöË5¶©ó À?÷oc!ŽÏ9ö±Ø!ÑnLÍÂ2 $tRË-ŒØ±ÏÕvì\HÃFÕÒi-í6Ú®äâ»ûøØq(ÚXÕUÛØŠ!ñ-‰´Ri¥ërñý²ÏX‹Âì×&éxOÍFÕÜœîÊ=zbé÷ŒúÊ¢Ž éÙÛ½c3¸ç&31wš ©€Ÿ?{á@§±Z¦Àખãú³¾)Ò=ó½Žó_*ª±ºàçL£1Üs«zg“°† åÉw‚†‰E½ª¹ã „5RE‹¦¯ÏûW‚Á¹á‹R\h«ØHÎi*ºMÀC²VmÞE­Yˆe3rö€ÃŒES°Q9 V  i;Pr³}VìIžr“k.â_NâKñOù;¾ê¤“NÄšIš©¬EŸ³òæ®’õDiøE (åË]]Y·!mÓ®\¶œYxƒ êŸýYëÓmõð.a&‰Q)&®CáZUbXƒX¢A("ÊaãΣ¡ëÊÄägŸ>…Z‰r¹n¨a !…Güÿ@<<<<<ÿ*}»’ƒf^>ÌåA{Ïe²•>_I@·ÿl95võc`ö>½ lCj¶að9Ékj”ˆ¸®üÇUZ-’nÉ‘úo=ÕÔÖ¬8õÚPŸíƒ3Ü-wºÓVûªñ{´‘ôÅqoLÃFˆ@” Á°6p‡æÊÁ°Ó@Wô•ð† lx3gê}!Ú7Ëxg™ÑíÓ®¨)p¯“×O.i¹09™ø ÑcýþÑÇyÝè 1®éàH¶›ŠC*‘îA¶Ôÿ‚䦨÷ÿFº¦4]‡UƒW‰Ñ°>kÒ¼ÒrŠ9øb·Öõg& }3GÞkxæð΃ÇÛ.™¸Û@¢¨ñ8ø@¥¶Š¤†éô•¶k–Δ]“s’Y3ž&ò ˆ‚ÏY´9™¶R)+“´ln562k%’êԈ˜LÁAdΦ]óô-;LË6ýªU—¶2yS› i€º$-ꢃ(ÙõŸ27/¨™£½ÏïûÎn±RZ…ÁÛ¥bH*•"¨¯Ù)‡„õ¨D‰±*x'Z÷\ë³—ßùM4ªØòcRÉyxxxx¶&À=J ÉŒÕt±˜/•²…l$z÷Ý·ÛÚZ@*ÁP „!\‡Š¥H**`× `YuínEÓѦÎþç^Ò]ëòý÷Ï09aÆæèÀ<Å-P¾yÒ» õÇp.†û#$¡}!êòÎ=³›Ùp˜Nvšàf˜@„ö‡Á%ÆÀ¼ÆïS£w¨Ñi­^í_¢G§vÅhÛ½ÿÓn¼Ônz·éx÷¤™Ö~  Ο,u² @ÿx‡—ÐqñÏínÿ^çŸ(˜tÅÿ>z»ß{Ãà¾üJ˜ŠÞ30z,¼Ul¤d7É9t„$$Ĭ-ÙËîQÑJ¤l89kg6µ‹1mëJY y‡)gÕ%/k2#Ú¼/ž* u”lÚ’‹ÊØñ”XsÐ+vfîmãÄÀÉWOjß¿»^ c"¡¼ª¯êP¬‘H †( ¡à+‘‹ ©Fªn:ÿʹ¯_øðaþÑ­\)ÇR.—æ¼~#³Ù솛Z¨HõÆ çááááy’]½’T„$ÿˆu3Éd2{~©P*fó`-GLÑR.]J­æÞ¿<;гï»{1‘#’:±¬–É L)”Ô 1HDXP¼C$F;÷îÛ÷cêG†óÄ›£½öºÙ)¦<ÐãÚ±%-Çý M Ñéƒ9PŠof# ·¨óÆu£ ¤'F%4\” Ìãl„r‡iÇÍ—Æ£¸'L?Q_þÞ³_W5о‚¾Z§TŠ„5âê¯að´aO³ªÛàœ¥ƒ‹øØ}=wßàMh=QÜ3qw;íaÓäÝÓã!}0†æLÞE"°HŒ/–_(˜f¢açÉ@\ŒWÙB6’·è€¤­TÆÁäLÁAgÍ8’5«1é0®Ù»Ò.ÓšC—uR2k¡6Û'9¬*¹è²oX5 2"ï¦WFT`5fÝ—6ÓÝËÆß¾üÂ[§¿O6×µ7~CK0!Tˆ°@$•@ˆ\(n@*‘a) !J‰ìèƒo¼üÚ&®~žÊ§€i”í·”/®×]ññ[X®ÕǪô?ltž' $›5íõçAÏ/ç…hñåÁ/O…òš4-ÀÀ-dóùôƒÿ7ûeúÜÄyÇñ¡i±±¤Ýg]>€4M$¡´a Ó™¦l0Á$>¤=´’%Ì‘6Óp$)-MÓĤ´`Ë’l,kÉΛÐf¦%Í0|è´|À ˜¦oʰ-iuõ'«xÚî;^0ÝÏ|gçÙgµ‡žç™ý}6‰ðœcãó›1aF "¤Ñ€¬jDd#†×tV}]F &„ɦMM¯´líz»ùý ¶ßü²'x½{ä+Ž3R”Q¦¡âƒ¨¬f#Ýò­éöáМs8åPf;FbŽÈŒKJ bÌIÙ†ÇY9ÅÉ3‡Ã)Gïè »ºê­M4iE:¬G&Álýζ¶c?£îÐ4+Æy)æIt‹³Œ2g“¦ÝÁÜÂ5:w@IrÊtg8æ‘v1Æ„Rò4دÌòbJÓ¼”`ái¥è“b#à¥Ag1àÊû„œvyÐHÞ[¯}ÑÏÝ÷Ú¡T¤äV»NÙk+¸¥ßw-ô9†Þ¾xgæ¬ëò‘×ß?°£ëåõÛÍuÏž²êk,$IÒæ=…a¸…0šõ„E‡êNê¾i¦ÖXpËŽ­;O¼óÞ_>¿ö{‹¹B9SªŒšª–‹¥J*R\Yo¥*å‡*R¥*$Ð ]=ª©ˆ†††ÆA6›ýGW^æ+/ÿ|Y-@í¬¤R–+A±TÈWÜdùÓ5_‘–Ê^.{n61 yŽº7nÞHQ‰C”U!#ŽWíê.aøº-M?ؽ­ãHóÉs¶ Ä9ƉÑÕläàg“íÊ8¯L±J”K¼%O¸ÆRÂð'ÇlJªLft<wHÓ¼2Ï„“-½—ZNžî?t\wŽ&;–eÞtF&@„ÀI:F§;" î‰2'™èM¢ct\¿âÄ©žPÚ®Äà²N)î‘âÝ¡œ„‡a#©'ÅFTP/“9Ï}Ý9¯ð Ë^ô<8ÊÚ˾.u ³p‘[òÙÕ!!ÛϨý«^gê,{éø¾OÚ·þdצ½[7 o™ µ4BàzŒÀ š¤¬nD˜‘",n1#‰€ÞyöÙöÎÎsgÏ}yõZ©¤VW)_Ìga[.ÜfË…L¹Y*–óå¥\9[QaXˆdE9TU­öT…deÅV°Ò©¡¡¡¡ñÎÝ»weY>vìØÎ;BP¥@O*~‚hTÛŽ,z¬',ˆ" È G´±á…—¿¿«¥í÷ég†‡¾è‰ÜäÃö±ä[cÓGÓÝrÜŠu+IAIØB“ ]JÔ‰»G®`Ü£¤¡(ø'Gy|ƒ ßf”9›4È3œ¼)ÍË3à]‘¤=œ]aåÈ /O rÚN@x%zÃK ˆCN:¥¤ Æ `#.9%(•@?íϺ¤˜KœÆè È@ZææÝ?.–2«LNÍÁ•?9ókJ_«£š°šë'^_ðñLnÀ®ú˜ìrr~ö_s`Õ€#3Àæý¬ê³eû:ò¾®¼·SâA*¼]?“õÛrûrlÙ lyЭö³y¯ppîb¿½0ä\h+Ø3¾vuоØß=K^®0Ô½4ÄÝóó×NíŽÝõQçþ‡›[¾÷üÓ¨Ž0à8"Á3!F‚‚6®3)º:Å+“[MkkëñãÇÇÆÆîܹ³" š-hhhhhýí¾–½Ö­¯ /h ­71ÂD)Ò„! šmÅñ=fÕQO£u[6lkÞÞÖ³ï𯘼oŽÛBqNJ°b|À%'øáI—>›·Ë©N)e“gmòœ]¹ÝºÅŽ}í¾æ Ý<¤LyäÉnq¼[žt+S|ð†32ÅËãñ¦Sžr+1—4%„&#㬜`¤8„S’¼œdÅJ8)®ÆÂHÉjX)Í(3lxÖ6švK΋aaÄñ}-Í0 «ŽO> CT,•Ï~ø›z ÇŒ Ýš?ÿlOÙË?2jÀ™ó YŸ£²õ ¹€¶Ø>yà|ÂRÀ•rç.zÀ^Ô>¦äs”]%¿÷ry¯¢öóK aÁkÏ Y¯­ìgK^[¡¯³4ì¹wž™û¸óOï¶´|ðæNáµ—ö¼¸î»ª é,ú:˜ #A›ŒVDXëôF0Iƒ@ r‚ôXƒÙ b¹¶¦Öj¶ìy}÷©'Å‘P*‘,æ °þky<Þõ§¡¡¡¡¡±LUHþ½îTJR ”J…b>§þýo_ÿñò•“ÇO´ìi6‘$8 Ô2d@˜£‘¦Ì˜žZ‡¬úº·€±”‘6á“fd ŸÛ¸íGÛZ˜W§^=ÖÛ|FrK_¹‚q˜r†=‘´KŽ»ÃIfø†K‰òJŒ•¢œ·+‰Ž‘˜MIÛGou*³Ý⼜ᆧ#3|hÎ!ÎóÒ¼ Ü9¤Iœ ÄJœRŒ§x)*(qW$éM: ^‰Ã•ÛBñCÊDÅ1ÔTÑ)ü@ë\¾´úðT†lä£3‚¬Å)“nÍçïµgöG&çå³ý\Áï„dúØ%/ZY80ï·LÖo[°f,øE?—ó²K˜Å~6ãsfîLàТ¿çÁ€ç^¿'õËö«ï¶Žmþ¸clj7¶ó¯½¸ç¥Æçê¿Ýˆ,M´Õ„fºµõ4iÄ §hÂ3b5$H²¶ÆjÐ5 ®3Ô›,à$úÚ:-7µµ¾qæç¿¸réòlz&—É¿ƒY©ÌøÃa¨ø×CïâÓÐÐÐÐЀú³Z¹)ýG `U£ óóóW®\éííÝ¿wÿúÆõF›3a’´Ð4Òë1½&)œÇiì&´Æ„×b5OAé·FÚ@Q:¨œþÉn™ÿFqÝü?hB!¶wæsìzÁæH Ð$4…¤j! ïÚÜ—Áfm“&=ÄQ5Á9l6ÐÐBHh*0fm RÕVUZÒv1 ”6äUU©jÓ$öî;ýÎŒ=lÖGª Urû>þúù;ß÷v<óÞJßÏ´YófÌ-»´îɪ­K^<¸lçÑê7~¹©õRí‘‹5­=O·_«íøcUÛ*Ûnlh¿ vQÓÑ[{êZUGïºäå5ï¯9yeCÛ•êäUˆªã½UǯU'¯C@’踺±½¬TwôfCòúÊŽ›‰Öžº£=ˆð(Wðy±Òr{ä–k»?Ь]»ÀF dåìä6|r¨vØÈ¼•H½^i¾Yeÿdcÿ¡õé7«¬·€{¤Ôõý´î¯Ößhˆwo_عu~çÖ§š%¯¬[ðÂêo<|õÜK¿žW„Â÷EY¾*‹Ri'J~(,Ó(QØG1&…dŽ)¡"Q™ɰψIÒDMcÌ)„AÌšñðŠeË_®©#Ù~ùRϧâšU žmº¦5xÊ`žC¿`ªétúÞ}ã@ h¹Ð‰ü1(ú•좷G;†ax½Ìùèoÿè|ïÜî†æçŸynñ‚Ò©Ñ)\":Q4ÌUÄŠ‰¦< b®È„Š W* UÕ/‚#…!ÎÔHDÆìHaªäiÓ”is¢³¿9ýÉŠ¹K7Í_·¹´nÇšm¯•¼’\½ÿW5GºjÛºkÚ/Õz?q¢gmÛyЕšŽíZÛz¢ªãfõ‰׵ݨj½³±írâø•D{ï@$¯­J~°)Ùûôñ«!ªRG˜ºbÉr÷}FÀt›t?,hÞ½W§²M‘gÍiY1oب^ðè²9Óⳋ*™{¤¸ü±)¥³&>QŒ£벤ÊHE”cFÇ l$¢‰Ëù EîæÈ˜kQ¦ËÃ…XÑ% {HeB ÜçS¡É÷ƒ¨rIáBØÉDBTg…}izy,¾±:±gßþŸý⮋½ÿìÏ€C€`øâaæ]½ôô 4öÞN3ȃ£ÑT@ ¸§ í89ú‘½Òí_ÐàlÛòfÝþ}m°»y± #õ—?ß9óÛw÷ïkÙ¾åù‹K¢S'3M“¥,LqD哈)æùay¼<á N9…V¬` ñ(?®ˆ±‰Œ*’ [‘)“yD)T ´0‰j4ÊP$¢O™>ã±Ùs¾>óÑ'fÆ7}uå÷æVnùZå–ùuõÛö­®}勾|ªlçÏWî·êðùš£—ëŽ]1q¤ç»­·ë¬;ôžŽJ¡ˆªWÄ*¬”9Òþ¤@Dl×Fw63)1*ÄyãaCcŒÊ2CH!„S¢r¦)œb¤Pa®`^(!]Æáb,M”BQ$M¢4‚Ï“x#¡T†P†$YWt‡©ÄÀ: 'ÏzjñªEe+ëZ^ÝÝr¦««ûÒïûŒ~× Ýí·3fÊ1RŽÑçXýÇ4x‚®Cf‚ÃrÉvÓ4³/}!bލ@ð_úQ¶œ˜†åd²§ Û®„8f&#„å…᤽ѱ§?m]ì¾ðö‰ä÷4½°ù[kâ gNÿJQ¤:,EcL)f* ¡N¸"H4¦¨”sL´iLÂfJW5ªªf!aÆ õƒ`Y¢&a9ñÝ,'êͧ“&è}“çÒ•a¡’’'׼_»^±¡±E£]aŠ®‡BœèÃÂ*ø†¢F„Ï—¨„ÂÃ\)HÒá5¥E 2&BÊG- ¢‚BDe,ñh¸¸tQ|Aéê5ëŸÝñÒî½ûœ:ùvçÙ3Þ¼n¦>r,s ÒýNÆ¿°Æ͇?p:ï0|ÙÈØFjÀFÀ(rô2çX}ñp<9rVÞ£¯’@ Ÿ´!¿õ mRÁ¥ßí2Ö@#³Ûr,Óh„¦}·)ºæÒgZ;NÚ4¡3zmÑm–®¢ô¥RwîÜé:×™lmûQóÞ›·­*«(‹—O™<ɘ1FA’Ì8Q1†÷P)h ñ#,cUFn êŸÕ1Ðû)Q 3Јâ‚q“qþ89\„îWI¾ªòX,6JÃM;žX™Æ]{ÁF0ÊÇЉÂIhØ#B—%ˆF:F’!*Ê—Äcåå±x¼,V[]ÝX_¿oWÓž¦†ƒo<Ûuöܹ3ÝÝÞ™}ŸþÝý·vÚ1ú\ë0Ràð¶áns:“²Àý2°Ë°§îþfüôÒ}Þ…“2`ÂuÃ;SÿE÷ð=Äù¬fä˜IÎú{ö `,tÏ[·n]¸páôéÓ‡njjjnÚµamåÒxøÊ¬«”C(„ÁˆC2$UE!r-HгÀ¬Æ(ÂÈ!‘ÊŠÀ Ýn>A/¾}ûv§ÇùóçÏLww·ÿ AÇÝ\ ‚1Šíá>qŒTÚ2LH 2–íØˆ«Wz/v_ø]g×oÞùõ±£­ûøZËîæM{š[_møÎ³ß^±lylqYYéb—”W”Çâþ—ñr¨ÛvgT_)HFìì‡÷B"ÁØ"ã14÷ ”À¯Ãhš¦_€Ü¯ŠɾƒaÁe*•ýy`q¶‡@žmCÉž…ÅBE@ [­<3ˆ_„¦sCÃôfs*ÃæþJL†_L1–¡À“øÏ6ºŠ8Yš”})`¬ðŸÙHŽr õ“ Ëòõ#ð¿ò¹àÿ‡@Brr˲‚)ÇsƒlÉQ¨XP÷oešfpÛàVA2,†ad/ðï6ÊúìYX,lD ‚1J Ý<ã©´e˜@d,Û±3nâUüâ@}°2bxŸõWÂmQ}áß”–à±Ï:ÒÝWÿ‹ük›_¡ endstream endobj 1 0 obj << /Type /Page /Parent 1704 0 R /Resources 8 0 R /Contents 9 0 R /Annots [ 2 0 R 3 0 R 4 0 R 5 0 R 6 0 R 7 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 2 0 obj << /A << /URI (http://www.synthesis.ch/)/S /URI >> /Type /Annot /Subtype /Link /Rect [ 156 670 280 684 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 3 0 obj << /A << /URI (http://sourceforge.net/projects/expat)/S /URI >> /Type /Annot /Subtype /Link /Rect [ 206 617 400 631 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 4 0 obj << /A << /URI (http://sourceforge.net/projects/syncml-ctoolkit/)/S /URI >> /Type /Annot /Subtype /Link /Rect [ 181 571 426 585 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 5 0 obj << /A << /URI (http://www.zlib.net/)/S /URI >> /Type /Annot /Subtype /Link /Rect [ 240 502 342 516 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 6 0 obj << /A << /URI (http://www.sqlite.org/)/S /URI >> /Type /Annot /Subtype /Link /Rect [ 252 456 365 470 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 7 0 obj << /A << /URI (http://www.pcre.org/license.txt)/S /URI >> /Type /Annot /Subtype /Link /Rect [ 170 421 331 435 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 8 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT6 1665 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 9 0 obj << /Length 3400 /Filter /FlateDecode >> stream H‰œWÛrÛÈ}çWLùiPE@¸_öM–U.mQ»ŽÉMœ¬ò‘ˆ50(™þüÃþcrº{P¤Öë¤T"€¹ôôôœ>}æíbr±XøÊS‹‡‰ç+x„Yà$¾«$‹œ8uµØL.®ÚT-[ãªvYO.ÞÏ=õØN\ÇuiÌrb÷¯Ï“_õ‡Ü²'Ô=}­|eýsñã$c™J\'‹±H:±+kð|ŸMÑ[‹¥ß}´Ú¾kÙ^àÄÚMÕýAÍu·F‹¯ –t[¶êòýTýã?–á{‡¾È‰ti¹z¹žªùsÙ}-v t^¯,;ÓêßüËŽñîyg¾ëÄøX¼C{ðüüìXãé–V-hY˜Æ’^]lnišÖléz1ñT©&~;Aì© qÒTÅž† { Sµ+&“·‹!‡!îËhŒ‘v)"ðrñWhÎËsÜPŽŒßúx&aL/c@ƒ¬hÊvëÒ²± ná6j“×û¼’6eyÏg c¢sÛVÏV„mîø—'gº“æSе™û`Ù±nа“>>,y]í°vËjnÁýDÄ“zy+ãf˜­®ëG3¸.Ô_-;•u0ÍeS«À§BG&¸ýSÎö5˜óÇOû˜S¨(JnWÁ-/`(¶ýæþËÖÄOT ðíò¶h»-}/ogªmºç|W¨;=gܤºØ=;ÕìÔUUuwg©UÑ.wå}±¢Xê²Ve§hβÙlƒSòÉ|òFŸ<ñiW>®»b5UÀüZåU¥¸¥ìZZqå¨Wܶb$—äÕ«^oòƒª›NÝêÈ!6ÞÏÄ>—äFñç”èe±Å^Z‹ÒS5Xeg…hÒ|dd)…ÚJsóT®DàÐì¥IÉÆòjVìùd —îB ©ª\µ±fšc _½øbV)¤A~+‹rù ¶Æ³ Ìî]'~‘Oª~< 26Ù³Ï;€=ÔÊFô€ùO·ü9£•ù YÒ0ÖcÃàŒl( 'TÑ*Î%ÏU<Ž´m,ÚÙžøN5Fõðñ[p¸3ÃG#=ÜVÈ`§–¯îb+½´ÿV,-,tÀ/œ¿@¾ñ7íÓàåÜñÊØ‹xÈÀN1á! @Õ–A–KÆT¡ÂoW&C±fH]£Ï¥" Q–µX"íqÑóÅUcÁiüD:kQ)é7Kp£—eé”~3B¨§ Ò>¬1'/ÕÏ4·¨-¢1®ó¾&‹ûÝœLo†É®xL‡löÀÀjÖ­NQt^%¢„"6z? ž82¨æâx€N:†œ¤:~6M…?—¼,5œ! 'ëÿoÀ’ø½ÁŠ@b`‚¡ÃòtSÌ‹` BZ <ñËvœK¦€ª®½hTÈhC›Ê>²ÛaGŸËnä›e!^P9~íü9¾B?„:ïÿ‡¯(´…ß,>.Ö,Õ<‚BðtCB·§Ï”\ŠGÂ7¯ÑëûÍèBúZV#ÄFƒ‚q¨'ˆ_*§f 3Z½œüdÙˆRÿU5[ófFAåši=TR½ÄI<÷ nÔoÔú=·ÞÔœ Õ­¼+eO…#‹ŸÊ#»7ÎÌNæŽU/‘ ÉJ¶ü{ í{&a „IYÎÏÿ' `odȱjÛ×;d Ëjh϶©§êæííTÍšnßNÕmÞµûv-Cº\]5!Mª×‘Þ×f2ï6"8×-°ڷ±›S½Lu…©Ì.ÞÁh#iïNö/"Ú>v²k8“wò¨ò©ú‰c!ߟ-ªÑ©Fó4Óšž®6<Û©—NßÑZ,i°LÅvç`zh"àå;H`Š´k&2®!kpA¤æœ$ ~$ÁQ”“Ó2¬.™±D .@¤l—bQèEbTÒ‘fáˆUÑþtéf%¡ËQF¢_+ŽP¤ïO }»áªnj[j†¨1B:óñõ€Óf"Fǽè)Ó å–ÔsføªÈ²øbéQþÕââR•”á¾wêÂJ¨¼lçXlçzN T»®QWVMC×pÕqx¾Ív¶—9Á1bI%ݧ˜‰Ù0 _)76gî…}ÔÿUyÏ\ââçCG $@RÓãRz¶ü{ ²ˆ%½é»S¿›a×b‘\ϸ*t"7>UC웹ŒþXäµ]5û­zŸSv&äáÌ|cŽw c·äL¬Wgàh£³e† Å-PPZÒÎ>‹¼¤\ôÀÀø ÚàOFÈÿèé( ‚Aè¿0dg%?:¾j¢àU V¹´ä÷y[¨‚n½‘\zm~ù¼#ç8º¯ÀÛ¢RrŽq ý/ÆuUv…Ãâ „8 –èÜÃ.å‘úþ.ÕÞáit^ùú„¤Ù3oÀÈy? „W¯)ÕM ïw2y”ýÇAJé¦2Æ(>BêRíl—;æ9•˜£’"*tÒr½,œî ñ º^Åq,ßeVˆ±\ú=ÑòSƒ%ßÿ^Vø þ’¡lÇGe;漎%¯Ó¡l‡ÇJ;¡|NN³)sßÏÆhžë‚_Do ^=üF|mÓ-µ‘PrÕët·»Ê7÷¦WšWÅIî“t £^íœhãoef'î‘ìó;ìËÑÕ©]Jª\žå¦0!±ü3mÄÛx¸ZzcMë/0¿´Àf¦ lÍ‚nëD…Ñ]—ÛKËåzOï"ϰçDÏh¬´6ð*’k wqé ˆÜVªi}9³;ðU¢Ï&-©¨H#ׇ²~i»úÐìA²¸læÜirúÍœ7Љ$rE G>îÛ5û¦ºñ°!7Ë®U«f¹ßu^Ãê‰.QÌ¡¼óNÑâ¨:UÍÑ~vèê†Êiº ™ÛÙ #4ŸsïÈ ™ºÓçÕ~Å;=ô_kPþBñ›¼ÞçÕ5å…¤±a0˜õ7y‰…Ê:Ç€r‚C“—Ã\¢V™_3xæC]¾ŸªòAåÛ-œßWÅ”ãN¶·»æ©\+õær®næo¤£^©ï tÙ­›}§àè.¯%‡p´ 7Kây"csˆøå{¥®?A8~ø(¸¾žÏgWïnæW³Ë›[u9›EЮ·æ…þ›ÈúKÔa-í?~¢{ãâæšÔR‚b‡äšÒbH nKõ'ø_Æ«m9q†þŠÍLÛi¹”eú<ìlìÀòÿ?²GC/<ô…ÄŠ, éI^Â/_凒ؠp‡º·{²KIˆ­ž7H»Zº™?l˜¹Kâ¡êíM^0zc q ¿8¯PÝ0tŸaüZêATRµÁš®ÍÕ‰h,o7É¥%‚Ýf»kÇÎ3ƒ:º°‰„ÅMìÿžQE¾X X?3¦£ÔÓÉD¶©U;GÝVä±—‰$ ¡\U—ôkG}à[" Çj8SÏ®m%Õ¨ê?Nöë}(³.16{w•âÍ…–W+7UNãlo#¸³s‰o,k矨„2àÑÀµ˜â3;ü—Þs×ÛN$ÒŸ|,/È7'¯piÁ-–ürÊÇoø¼gäõ–‘J|Èb™A¿÷4È™K×ìO}šƒð‹áo+ÛMË8ØÉÝðÍ,~úúÌ}쇂 ‚‡…Ž6nl£¯r^þ2ÎþŸjP¯O”x}w5Êw‘n]ÌþïŒópuÍ©9øŒZ(±Ö0wÌ Ú+f®PoÌ$„à†}^»“¥£øîqt¿³ßØ‚ðÂÚdô4ú‰ÌtB7Îx¦¥AŠ`.¼·-{Y8‚ÈVÛ.:$F.3Yÿ¥^ȧ³V `î|.AFï!eÛß“óÙD­³bÏ[uø]{I"“úP¤äx‹4ðû¬Cc¥àQ Ϲá::*)¢ÓÈG×m©mL9s–AfTŠàGÝbuï+£D%ÔäI‚ßéJúÒãX„zÂb+<m] "}- #`ób–¾˜•áy"Õ2ÃQ«GèJµ§¦Õ0Å$ºÅĹKTEØapclŠMffón{ãÝV#scÍÚXCÑ„#8ø ÕÓW ÏX0Jз‹z‚‹ê®+ç‘ÈÆ¾„̶ƒfíÒ øsa$ÂÀã–¿½CË\EþeÇ‚8¢‰¡ÂåÔëúÒpßc¸ ä8î¬Ùò‘BOMw5NºÓžFð"ìEl !6¶(WÖÏs{|Ì€?÷9\ Ñ‹Œã¸ý`ŠÖwŽ endstream endobj 10 0 obj << /Type /Page /Parent 1704 0 R /Resources 13 0 R /Contents 14 0 R /Annots [ 11 0 R 12 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 11 0 obj << /Dest [ 399 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 301 655 370 669 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 12 0 obj << /Dest [ 399 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 422 655 434 669 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 13 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 14 0 obj << /Length 2208 /Filter /FlateDecode >> stream H‰ŒWÛ’ÛÆ}çWté%ƒ*Â…ɧ”lYŽËVÕ2¥$R@pHŽ`\–Å|ˆÿÁÿ˜‡œî€+’ŽT[µƒžîÓݧ¾[O^®×1E´ÞM¢˜Büág¶J‚E¦´X̓t&´>N^~ß.)oeOHm^N^þøѾ„Aòž|â—§ÉGõ>óü$˜©½æßXQB޿׬ÄÀŠa°JqH² ÒО!ïÇbŠ¯æ©µô{ŒU?=?J‚T…KÚœéá\v¬ÄJ{°¤ZÓÒ«§ô¯ÿzþ÷ žÍƒ¹2^¨òÔN¦ûn 1’¨¬ÜzþJÑoò_“è%²8 Rܬ_cM<8N—‘jùTÍÇÂ4Ž p"¸Ü-ÄÒëID†&ñ< ’4¢d,—”FÁlFˆq¶¤FOv“ïÖ#I„-á—h\x¹þÌùš¹|Í‚pfS&Wž‹™dÏš¸JÍ܆ô¶ì¡Ty+D°íóÎxKÄP•{¥1§A¸üä|Y˯ŠÂfFÛ|ðMþî'ª›Šh§”F—]KYK'Ý™—âôÖ› E­nžtƒ‡¦MÖê-Á™ª‡§)£ºÈº]ÕÉ”[í»¤ùQ%’+Žpq va]ª56—Ýà‰.÷¦ô¢eãÇÁRäE¡Z{s qð"eZ¹´û4 ·yUî̾oàRo—L¹§ŒÜµ‡#Uî MÿÀ!v7íL¡§t:˜ü@Çì8χcù½ùXxC<Æ0¿IX£ëÂäYÇgV ;Á c³s€ Zœá~ðÅ8&»Òy±Ê €gÄ…Ê-öœÝKÁ\ëBtƒì˜á±—¶2ž¹nN‡æ ]ó¾õüšvçEøO窧¬ht¶=Ó!{ÒtªšG`Šæ<ͺÑO¦Àx'ÿpñµ …ʼnôü%Pï`s¥Pjv;:54¼+é¶×?1#$cJ‘œ›Úç£hpž¯ØyI9Ãæ¯³ªœ¢uÖÚ$“(Fï€uÇ>¥h&˜Âñìè'UêÓ'òCVóÓ•ê°ñÅa¦H²îOÎý¬O¶—/¸äël¯)b·#ó1ð^¢7à Ǭì³"¸) ›…嘅¥#ãÁíĺ ³Â-T3Ãâú¢ÿ]Ó²ë‰ò½x@7Q5Ÿ)›É­+ˆ)DƒMÄ^˜GäJšÞÙUÞ…Mìù”˜9Õ÷¶xoŸ“îòØÝOT<&*v‰BWÀ]ÇÆì5‰' vupÙšva€olÓÈ5À©ýÍÙ¿ZB¿‰³{ðÐMb[oß›­v;ƒkÆ|ÞÒWÍsÍXÑ¥Û]Õ½jiS¡Fªd/3¶æFÎN›¹–qÇuÆŽPnS*²µÓêœl‡žÉÁ²(Îr(hø~¾_<#¸¡€«ô¯œÜš£yЊs‡zx漜ÒÖìМΧ­ëì7ûÜ„ñä£Z` F—ýHÀÒ oD §Ëœa°cƒ§·RgÇÅ0…®F-¼Ý'c¦G(÷GIzIŒã²Ñ‡ xÞRV)ããÂùºÛ*ïÀ" - F ‹™&èSæEÏÕ#wì¶½”Þ\ yÛ…)Ó U|Ϋ#zmëÌbw'Çm-áÇ®ª¿¨¥cÕvcVž±ªÃKÎr ¹áâ†fÈMoU1€£ÌE9PØ’[êªÛé12’ÿœ’6½)P=½„QLEÇÁQ;c©_ëÇÃë¿ÝRžðÀl´Ï—lÿ—²8S]±(CLJŠ W<ÄS,¡º¶9¹·¸l“ŒÚÇÌs ¡؉eÂÌTÎØ‰]»‰Q” ²?=^Š 9!qì2ð^ÎìÈ(Ž¿@ÈTŒâBìáî•wb¿Ú@@ŒˆÈšwIñ¦oËŠnêò“\·Ú×ø)¾dΑíÛRBBiå©’]u@%O¦Ï'IKÌÓVñ²ÝÂL”=e n+ÿ5ýAÆ•ë2è¼Fì¾xÅæ<žÙlÉM0WPØPˆüãܓّéЪڕ[Yêuƒ á®|ºH¶…jì.cåÓ\}]']é¥=Áe‘ªÂcÍÀz—]o´Li^¬dâJ×YÀ‹#ËаIÅÚd'Uçn¾x¬ÉP:â­ÇZƒ» =XëCÖL_0,{ÍZ“*Û©z2ú„ôËÿ^ûG—"&6¼6¨~íz ½Ã4YÊðÊ ÓQì¦T§m.`AäJÿTüê®·–ØÝÕhÎæî„¬³Ñò;Ù6«;©U¼Ëå*[lÍÊ’'¢ÐÖZàÝ_ª“¶1/Ô”ËÆØç÷+õBG¡£#©-+¤ rˆ`Ñó¥Fg¯ÔéËöA«4`CtûDÌL»]~èƒÆè“—x"àóÆ–+ju¦NÙ¹e&†ŠÔÜ•×Ùø¨8Gn¹ck¢c{Kµõø3†¥E]è«~æ™v˜\[Ï5¢¨?H€¶k̦·°âœsM~›Îh»¬DêÊðàüŠZø?!7ò÷gn%é7üÍ SmýÛe|¢éadñt¦~ÐÌò¡ÕTîvØ4 ‹ê½Y²VØ QÜêŒU¤hËQN3˜÷…î¨smŒ¸õ˜¥1[öBʈ¶…ÏÐ=à¹G±˜Ë·Ã\bfM¿”IÅ_†4>ânæÂî3zÿúÍ31óO«wñÉ úoK+TèâsÉA–?òçMVž¥6m.´ Ûú#t(ÊTèS4$•ýqà @ÊìX‰/ ª˜ Þ{ìëk»o¼KÍ·êb=ÕÉêªi´{PWåÖ}–{þ…}ù@sÊé΀þî^åj–´ÉòÇ6`t‡|RÍEL?gZ>6¬Vxm—Þ¸0¦€t:"íôé¹êEŒeÓ»âúÜkâó<™º‘0 \À±J N‰ºÿs·ý~XOþ7ø‹fá endstream endobj 15 0 obj << /Type /Page /Parent 1704 0 R /Resources 64 0 R /Contents 65 0 R /Annots [ 16 0 R 17 0 R 18 0 R 19 0 R 20 0 R 21 0 R 22 0 R 23 0 R 24 0 R 25 0 R 26 0 R 27 0 R 28 0 R 29 0 R 30 0 R 31 0 R 32 0 R 33 0 R 34 0 R 35 0 R 36 0 R 37 0 R 38 0 R 39 0 R 40 0 R 41 0 R 42 0 R 43 0 R 44 0 R 45 0 R 46 0 R 47 0 R 48 0 R 49 0 R 50 0 R 51 0 R 52 0 R 53 0 R 54 0 R 55 0 R 56 0 R 57 0 R 58 0 R 59 0 R 60 0 R 61 0 R 62 0 R 63 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 16 0 obj << /Dest [ 10 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 70 722 527 736 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 17 0 obj << /Dest [ 15 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 706 527 720 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 18 0 obj << /Dest [ 399 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 688 527 702 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 19 0 obj << /Dest [ 399 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 671 527 685 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 20 0 obj << /Dest [ 399 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 658 527 672 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 21 0 obj << /Dest [ 399 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 644 527 658 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 22 0 obj << /Dest [ 411 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 631 527 645 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 23 0 obj << /Dest [ 425 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 617 527 631 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 24 0 obj << /Dest [ 450 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 604 527 618 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 25 0 obj << /Dest [ 450 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 587 527 601 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 26 0 obj << /Dest [ 450 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 574 527 588 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 27 0 obj << /Dest [ 463 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 560 527 574 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 28 0 obj << /Dest [ 463 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 547 527 561 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 29 0 obj << /Dest [ 469 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 533 527 547 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 30 0 obj << /Dest [ 469 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 516 527 530 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 31 0 obj << /Dest [ 469 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 502 527 516 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 32 0 obj << /Dest [ 479 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 489 527 503 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 33 0 obj << /Dest [ 479 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 475 527 489 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 34 0 obj << /Dest [ 485 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 462 527 476 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 35 0 obj << /Dest [ 485 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 448 527 462 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 36 0 obj << /Dest [ 489 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 435 527 449 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 37 0 obj << /Dest [ 489 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 418 527 432 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 38 0 obj << /Dest [ 489 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 405 527 419 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 39 0 obj << /Dest [ 507 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 391 527 405 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 40 0 obj << /Dest [ 519 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 378 527 392 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 41 0 obj << /Dest [ 519 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 361 527 375 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 42 0 obj << /Dest [ 519 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 347 527 361 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 43 0 obj << /Dest [ 525 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 334 527 348 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 44 0 obj << /Dest [ 525 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 320 527 334 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 45 0 obj << /Dest [ 525 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 307 527 321 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 46 0 obj << /Dest [ 525 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 293 527 307 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 47 0 obj << /Dest [ 525 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 280 527 294 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 48 0 obj << /Dest [ 529 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 266 527 280 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 49 0 obj << /Dest [ 529 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 253 527 267 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 50 0 obj << /Dest [ 537 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 239 527 253 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 51 0 obj << /Dest [ 537 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 226 527 240 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 52 0 obj << /Dest [ 537 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 212 527 226 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 53 0 obj << /Dest [ 543 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 199 527 213 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 54 0 obj << /Dest [ 547 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 185 527 199 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 55 0 obj << /Dest [ 547 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 172 527 186 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 56 0 obj << /Dest [ 554 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 158 527 172 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 57 0 obj << /Dest [ 554 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 145 527 159 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 58 0 obj << /Dest [ 559 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 131 527 145 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 59 0 obj << /Dest [ 559 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 118 527 132 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 60 0 obj << /Dest [ 563 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 104 527 118 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 61 0 obj << /Dest [ 563 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 91 527 105 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 62 0 obj << /Dest [ 567 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 77 527 91 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 63 0 obj << /Dest [ 567 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 64 527 78 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 64 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT10 1667 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 65 0 obj << /Length 2319 /Filter /FlateDecode >> stream H‰ÌWÛrãÆ}çWté%ƒ*‹¹àöäò^ãÔ:qY´ŠJHH€‚Ò®?$ÿôCºgp£€¥DФ£­Z$àœ>}úôëÙäÕl&€Ãl1á<ü‡¿T,ÝPx„±ï‘'a¶š¼z³‰ ݘk<ؤùäÕ‡k·›‰çz]“N¦ÍáÃäö}âL¥«Ø­¦ß‚石¿LbsƒBÏ|ˆŒÜÀ³Ï0/Ì­èÈìþ+ðÓ©ðœ)—nÀ¼n>Ãõ缺ÃOÓÞ‰m² |óá+øÇïÎÔÇó¿ó]ŸeŽÇÒ»¯àú!«~ÓåÒÜD²$Ÿ;Ó˜ÁÌÿæÅ zƒLxn€'³·ø™yƒ‡‡ב.gzª¦Çâ­ñ‘.z.­?º3wz7›pÈ`"üÀ•ºQw•Ĩ"(õd1y=kÉ/ñvÙè˜öˆ|ËÙ¿¨^ª®—r=eKfŽ>Ceª×êÅæÏßy¥ójcnÓ»ý3EÚ©CЕ4¶4p¾Í«²˜oÓ*+r¬«‡aîy~°Ž1Þ]J7÷,pb³­NjKô˜œ©¹hŠŒsºÐ 0ºú…½!}V8Ó€åô_…ú‰PE»ç¬(–Tœ ]gà1õÊg´ómÁáq±àç;:L:|²4 L 5ø¾Æšž 5>Ñcœž#ªiÔ@,d¶=јÈ.G0åPÝ¡'¬’|›P×{1ºÂ9` arNÏâC”Á!(e‡’·(yƒR4(ÑÓï>»ü6Ë5`zäúA—+¤íní /,)õª/"/õ8~q(¬èPX¢å×°„¹±ðN¯\¶°°|t®Ëd 'ëNò['Æ—×V©Ô—"Qãgç+âcðYr7ŽwæÂ#‚LÕÍ‹ 9r#>ÖÎzdKèè=¶îﵺ!Kªm©‘‘H]’Œ>!¾ÿeBv)ø¸r…ÿ,J:ÅtŒt„Høsñ@ª^e·¥£p'•†ŽëˆÙóbEŠ·ÂPØm‡ØÃ_ÙvmÔf.Q¿:ÎT…øÅñìØT€^G¿†Þî0Ád¸Çàekð»7^s¿Ï¬cË„ñYgXçéáÉ<}àv˜¼àu²ÉRÀ“êu…’äù’Ç8ÐÚþ†8ruÑáT-NÕà„p‘Ýn˵ÂPÂñ¹p]•[Йܥ> ±±°ù)åòs3Aá–Zø¥Ø÷M4 åðwœc7TgS°qzyá*7pm©­Éáü”Œq±!S}h/z¢ôúé.|eWM‹ Ít¸Öå=Îp+جuš-°ˆ¤í&¡µJ Žò}‹0`<>¨ {¬©IÖjVs¸OÊ,¹YêI(i‘Ï3ÃfÌè[œ÷iÿj³§3ÞŒ–ŸÌoÚ…³Y]qšÂu±-S|ÕEQâ‹/·xX, ~Ç ö!É )Œðưë1#Øü¸ÉòÛÝä&Ãb0¬Í.Ö– EFƒôdOŽUîñS…žr¥?­QnWTµk– $Ën¶–OqŒQç@7×§0 ^¸ì› Mä{Ìøz«Àœº£!>sa&ÖÚž–´Px¤¦ü©«4÷åIW$ƒ˜¿q¯Â~‹Øoûp•-ñ«lAè$Ëû'WÕ¥N£ÔÇï²ÚkHô«ÊìÆ^ˆb ­suü¹dby®õò®ÖˤBƒ²õ\¡®»ªñJVgßd¬8áÞÁlgÈÉ; Ñúaø÷ŒÑ‹þµØ}fÙJÃo®½¸%Î1ËÇl‰Î†]íŸtÂÒ*†Aþd#_ØÀÙTÉj ¥^ã^§MûrVÕ1ŠÎ¹å™$?ñd“ÇÇÉCMÁP¤•þT™Œw¦ù2Šp¼ŒÇúÑFÙSe“ÙLýê¹±Ú/뺠뺮éj× \¸NËl]Q€ø˜ä·[Då #é6&N·NжH¢Áá绤‚4ÉáËdéù×vž??Åx¬G0 x·ºÑó9UÊ 4Ïhü°1á›p®!Ëi¥ èêDÓߪð…àö9 ndnV+“Ä3”{VÄèˆqŸ·´"â,з١èÔ†wó!¼^é¿)Çx'çÄÂÎYT¾# tL]þQuµõô]¯©g÷®ö5ݺ}Õ˜¤ÂÇ–9€·I•@õy­ÏSËCˆðý–‡}"„£"Œ–#,ÿY,ˆ½þÒþ‚qµþêcVé2YÖ#ô‚ Û‹¿o=¥kì4íÅ!qÚì0ëBGA§x.:h"øX¬­ïˆÊãþê)ü?ÈÄkð"îµ»¿Óî¦ÛÑ0йÏÇx ~_­Óæ°æÓÈ[~øÉ‰ÐXä«%'P”ûïRüXR¸Ç-¼Úùz×L)ÁH‡µ7h7z3¢e¦#¦ãEÀÇ"ÅõÞ‰iy%V–¡X@÷ØÖ~ Ëé\/²\Ïa±ÍS»6ñ0:­eà-i»•Δ~ Ñû{ â`qHxŸéåî±YóÜZ\ZYL½sn…ìµ68ÿ²6,G{ô¡Ü >P=ô¢à›²L>·äpC”z¡Kí„nÀò”¸BªÄùS½¡F¸QØ3ÒGÑaHLŽpcyhˆ[qQüü?Ý?¥Ý?ýçšÊËÊ"Â\ M®4Ä8¨™€e¦†£è£!Eºò Wé‹dÀpÕI E¢¡¼6ôlñAË–Õ4ËûÊáÁehé¨9Âpƒçî¾¢Ú&R-? >,‹Ü_n¶55´80äõ‚¼¤xŠ*"®à“X1¬â’#ø)'·3õÍX ¾´¦¼›Mþ7ËvY endstream endobj 66 0 obj << /Type /Page /Parent 1704 0 R /Resources 119 0 R /Contents 120 0 R /Annots [ 67 0 R 68 0 R 69 0 R 70 0 R 71 0 R 72 0 R 73 0 R 74 0 R 75 0 R 76 0 R 77 0 R 78 0 R 79 0 R 80 0 R 81 0 R 82 0 R 83 0 R 84 0 R 85 0 R 86 0 R 87 0 R 88 0 R 89 0 R 90 0 R 91 0 R 92 0 R 93 0 R 94 0 R 95 0 R 96 0 R 97 0 R 98 0 R 99 0 R 100 0 R 101 0 R 102 0 R 103 0 R 104 0 R 105 0 R 106 0 R 107 0 R 108 0 R 109 0 R 110 0 R 111 0 R 112 0 R 113 0 R 114 0 R 115 0 R 116 0 R 117 0 R 118 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 67 0 obj << /Dest [ 573 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 757 527 771 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 68 0 obj << /Dest [ 576 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 743 527 757 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 69 0 obj << /Dest [ 576 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 730 527 744 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 70 0 obj << /Dest [ 595 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 716 527 730 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 71 0 obj << /Dest [ 604 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 703 527 717 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 72 0 obj << /Dest [ 615 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 689 527 703 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 73 0 obj << /Dest [ 638 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 676 527 690 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 74 0 obj << /Dest [ 656 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 662 527 676 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 75 0 obj << /Dest [ 662 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 646 527 660 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 76 0 obj << /Dest [ 662 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 632 527 646 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 77 0 obj << /Dest [ 669 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 619 527 633 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 78 0 obj << /Dest [ 672 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 605 527 619 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 79 0 obj << /Dest [ 675 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 592 527 606 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 80 0 obj << /Dest [ 682 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 578 527 592 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 81 0 obj << /Dest [ 686 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 565 527 579 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 82 0 obj << /Dest [ 686 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 547 527 561 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 83 0 obj << /Dest [ 686 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 534 527 548 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 84 0 obj << /Dest [ 686 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 520 527 534 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 85 0 obj << /Dest [ 691 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 507 527 521 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 86 0 obj << /Dest [ 691 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 493 527 507 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 87 0 obj << /Dest [ 691 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 480 527 494 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 88 0 obj << /Dest [ 691 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 466 527 480 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 89 0 obj << /Dest [ 697 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 453 527 467 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 90 0 obj << /Dest [ 697 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 439 527 453 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 91 0 obj << /Dest [ 697 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 426 527 440 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 92 0 obj << /Dest [ 697 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 412 527 426 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 93 0 obj << /Dest [ 706 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 399 527 413 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 94 0 obj << /Dest [ 706 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 385 527 399 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 95 0 obj << /Dest [ 706 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 372 527 386 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 96 0 obj << /Dest [ 713 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 358 527 372 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 97 0 obj << /Dest [ 713 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 345 527 359 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 98 0 obj << /Dest [ 721 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 331 527 345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 99 0 obj << /Dest [ 721 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 318 527 332 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 100 0 obj << /Dest [ 724 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 304 527 318 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 101 0 obj << /Dest [ 724 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 291 527 305 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 102 0 obj << /Dest [ 724 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 277 527 291 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 103 0 obj << /Dest [ 728 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 264 527 278 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 104 0 obj << /Dest [ 728 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 250 527 264 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 105 0 obj << /Dest [ 728 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 237 527 251 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 106 0 obj << /Dest [ 733 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 223 527 237 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 107 0 obj << /Dest [ 733 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 210 527 224 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 108 0 obj << /Dest [ 737 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 196 527 210 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 109 0 obj << /Dest [ 737 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 183 527 197 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 110 0 obj << /Dest [ 742 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 169 527 183 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 111 0 obj << /Dest [ 742 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 156 527 170 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 112 0 obj << /Dest [ 748 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 142 527 156 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 113 0 obj << /Dest [ 748 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 129 527 143 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 114 0 obj << /Dest [ 748 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 115 527 129 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 115 0 obj << /Dest [ 748 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 102 527 116 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 116 0 obj << /Dest [ 754 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 88 527 102 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 117 0 obj << /Dest [ 754 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 75 527 89 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 118 0 obj << /Dest [ 754 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 61 527 75 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 119 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT10 1667 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 120 0 obj << /Length 3058 /Filter /FlateDecode >> stream H‰¼W]oÛÈ}÷¯˜Ç!1~3 t“]7‹¤»¨U hÑšÉÜI¤Öv~HÿCÿczîÌ¢,Y¶"Ú¬IކçÜ{Ï=÷‡ùÅÛùÜe‚ÍÂeþáà'ž¹NÈ¢$°ÃØñؼ¼xû±YÖª=k³êâíå•`Ëö±‡öd³þôöâ_ü×Ôšy¶Ï—’Ž.g³þ=ÿù"QHXäØIˆ—x±:úê~W=ŠÎ‚P?é¿.Vg®cÍ„g‡Ü‰Ùõ=»º¯º¬¸\Zxo‹–ýùò ûçÿ¬Y€ë¿vÀ ËáÙÍvu[tßd³RñxZåÖ,áì?ê¯ú0…^!s;ÄÅüÖÔÜÞÞÚ–g ÞÒ[%½Æ+mœ:—™¥õ¤ç‚ì BÛ ó";ŽY(lßgÀèǬ‘‹‹æžÀg—-Ó1‚¯œÿ6ŠRâkþ¢Ð±ñ¿¾¬ 1„‚NéóC[ø¶`W]STK¶ØTYWÔUKTøøxû•þSÜxÂŽ"C.}¢Ž¶þÎÛg âè!º‚Gê^$«pt¶ú6÷!êÉÙ&óÌ ì˜Í„ ¢ú7=‹Ëþfái4s)]7«´a?Þ­ÙZx× õuµÃ^ðÒìiÆ|Û#ÆÜÆ(¹?äGØ^ò,~¼§øñا´“ÌÂkP4l>¢£”;tˆWI&Í *8–Ešõ•{ܸ¶L“;þC:¾Õ•Dq¯ÀRJ©w2g ²“ð 6Æ| ,|qÆz¶’c5§Èò±ŸHñó ÍÛMÐY:°Oòz³d«Zi%3#Š<>J!ñ:z¤‰qí8ÚQúíïJ}4)î~%©OÈ~ACiÆu”¼¦&¢œ$Ïå1+ÞCV<;‡X‰{VÂqªÌ¶¾alÀŠI”%5«6kŠuG©áâñ¯B üÁóƒ=|ôý[|ŠŸ¤ßƒŒ4H/@޼Q AF(}nÙ°Ÿè¬Xu’ŽR€u}÷ås€p"”xï^wU CºÎhNw§©ü¾c.ÛŽQïøšþ.g¿¦m‹†ëqVÖ¹¤Èúó—kÍ|•±{Màh0eìˆ.û!m‹Œ-( #“˜ÞXçõ ¹Ç©Ëôz{àb®gFÔhßã¸Ý#•Á|ÎeÕ‹B6-+*MÉ8”½±Èý+“ùJ…k´ Ú´KÜOö(HüSë@ü}öñò3ûIGÿÊD_įþÀ9/ÍGáLÑà ØÕZfEºbõZõ* ùG5ù$üÒ¢ðϦZ¶FÃø`ìºayÚ¥×i+±¨‡¶wœNˆ9왓ï.b@ç÷èB@… =™e5u;ŸW‹biÍbåÞà†x“x|T¿`€M ö¼Ç÷v!ámÈ5!mv)+Ù ¢—«úå?Öy£q²_Ö½9ƒž…'áEVÆ 0Øw §÷—mRÎÆY£¿¼_™¬ZY¥¥üðF]Z1Ekżwì‹Þ€ŠI ¦ª·è²ïÍȽzCr±÷ez—ÕU¶ièl+Û–B<ÛEÖ¯²UQÕJtb˜ œøl8J>èË=õåe»l‹oD™Z ¿#i̾~a%¾8]ê‘’6¼t$¾OÖ‘¹ E}ýÛ€â®(7%ÊÌ@<Äœ‚ÙÛ¶fýé€ZY “ÏÐ2¹¦Þnia‚pIm]Ì S„6õ³“ž=; °ô͆!Õ‹-ª€ð!?®í‡&ÇÇÓÁI¶æ5Q¯´ªi *e½é>(’ÞQT|>8ÚÀäÜ2òrçtÛ¹莠2ÁÛGz4NtTÙŸËë •ù':šé‚]I“ðnp~ï‚ÓŽjÖtE-Ô R/×N=ÇïndÑåwÀë6#ínØ¢n˜bq]²E±¢¸$c‰ûm]’@×q¦ªmo‹ÝGmËÊRîAõÌvœÆ°¼h­ñh¡2·UAMÚ§ 0ÅrÛ+n{·¾÷8BÅiõ-F©1Î UßKļL;d‰}L ÜE)¯,êýUfÑäÖYTÝCj0}'ZS4Ýœqˆ'ߎCƒxrAbÀ÷ä  ûÏ"Ç;.~‚F¬E½Ê©ño…Ïã,¿¯Ò²°(@3;TÝüeþBŽ))ÏêQáªp&!ƒªÆïÕ09¯vÜã}QÐ,F NI‘ð.-×(òXµT.-ª™Ñ†tµ2Y”ð›ú–n·Hv°E_²¢"Ž@NìŸ\pÊK‡–éÄã‘êÀœ¦+Xº›F¦y‘“–>ÔŠB©~bŸ± ø'#|HÝ är7¨åÏèp&OÊC¤3 ßÑ}¡ÿJ ê XQR/~Ðûv(*úµ‚˜DˆGD¹§' Ñò„a4âé4Fá«q*w®f*ýDsàqS0£ÝúÔ̺å¨éwգ׆Çkµ%Ù­×Æ|»§¸Ð¡dÄTsÐj`(LׯiÈ*ïjyWè‚ÂVÜgH€ ÁnìcÐÎúÙÜ6E'™6wÐWÜ`î&…5“ˆ¾U_è¿àŠfKFÂy®Ú jGs&1Oj ’ÔjWSeK3dí¶]x²ýMÝ`w+fª´pÂm+ Çè….o®µ\|ZIi±`)²@ EÍô>º RŠiÔÀì±ÞtlÑÔ%S©lžeQ͵C=2*Ä¡Frw¢x;ñqeš\cÙ*L=qÎ7pŽïX¾±Tý•kvu_e0É=ȓ̳¯9˜Ä0ãïqÿ…]{[ðXw× Æ¼cKÝÛ+Ù OLß—úÇC0 .8Ç'cJùƒ3IzÒQЍ÷ÔrýWùÀQþµ ÕR6Æ[’~Æ|½®›Næb›á‘‚ö÷¯ŒWÌå#ïùPTÆŸ¢• “Ä þ‘„šfðÒ ŸI^²·•&}8Ö(™­ ¿R‰´üëUÏ›0 Dw~…W¤&|0tËÐÂvè†bSeÀ–ê€D=ïÎÎB‚¦É–ħèÞ»wçwžÜuaÅ ¸S«¦§bÈ¢èÿÊãoHBG&.èß63ÈØK=1„Þ:ÇÇëúÖ@âý“¡¤wšPŒ³¥–oß¡4uCx˜rÒ†ž¸¯7z—îŸml5~Xct‰½Ÿ»¥·Mþµ}Ï©„ÁÛÇ’‡\æy1»bh endstream endobj 121 0 obj << /Type /Page /Parent 1704 0 R /Resources 171 0 R /Contents 172 0 R /Annots [ 122 0 R 123 0 R 124 0 R 125 0 R 126 0 R 127 0 R 128 0 R 129 0 R 130 0 R 131 0 R 132 0 R 133 0 R 134 0 R 135 0 R 136 0 R 137 0 R 138 0 R 139 0 R 140 0 R 141 0 R 142 0 R 143 0 R 144 0 R 145 0 R 146 0 R 147 0 R 148 0 R 149 0 R 150 0 R 151 0 R 152 0 R 153 0 R 154 0 R 155 0 R 156 0 R 157 0 R 158 0 R 159 0 R 160 0 R 161 0 R 162 0 R 163 0 R 164 0 R 165 0 R 166 0 R 167 0 R 168 0 R 169 0 R 170 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 122 0 obj << /Dest [ 763 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 757 527 771 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 123 0 obj << /Dest [ 763 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 740 527 754 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 124 0 obj << /Dest [ 766 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 727 527 741 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 125 0 obj << /Dest [ 766 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 713 527 727 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 126 0 obj << /Dest [ 769 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 700 527 714 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 127 0 obj << /Dest [ 769 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 686 527 700 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 128 0 obj << /Dest [ 769 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 673 527 687 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 129 0 obj << /Dest [ 772 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 659 527 673 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 130 0 obj << /Dest [ 772 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 646 527 660 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 131 0 obj << /Dest [ 775 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 632 527 646 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 132 0 obj << /Dest [ 779 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 615 527 629 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 133 0 obj << /Dest [ 779 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 601 527 615 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 134 0 obj << /Dest [ 792 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 588 527 602 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 135 0 obj << /Dest [ 795 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 574 527 588 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 136 0 obj << /Dest [ 795 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 561 527 575 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 137 0 obj << /Dest [ 804 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 547 527 561 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 138 0 obj << /Dest [ 817 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 534 527 548 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 139 0 obj << /Dest [ 827 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 520 527 534 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 140 0 obj << /Dest [ 831 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 507 527 521 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 141 0 obj << /Dest [ 842 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 493 527 507 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 142 0 obj << /Dest [ 854 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 480 527 494 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 143 0 obj << /Dest [ 854 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 466 527 480 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 144 0 obj << /Dest [ 858 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 453 527 467 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 145 0 obj << /Dest [ 858 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 439 527 453 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 146 0 obj << /Dest [ 858 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 426 527 440 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 147 0 obj << /Dest [ 865 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 412 527 426 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 148 0 obj << /Dest [ 865 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 399 527 413 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 149 0 obj << /Dest [ 865 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 385 527 399 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 150 0 obj << /Dest [ 865 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 372 527 386 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 151 0 obj << /Dest [ 868 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 358 527 372 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 152 0 obj << /Dest [ 874 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 345 527 359 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 153 0 obj << /Dest [ 874 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 331 527 345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 154 0 obj << /Dest [ 882 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 318 527 332 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 155 0 obj << /Dest [ 882 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 304 527 318 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 156 0 obj << /Dest [ 885 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 277 527 291 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 157 0 obj << /Dest [ 885 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 250 527 264 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 158 0 obj << /Dest [ 885 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 237 527 251 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 159 0 obj << /Dest [ 890 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 223 527 237 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 160 0 obj << /Dest [ 890 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 210 527 224 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 161 0 obj << /Dest [ 898 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 183 527 197 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 162 0 obj << /Dest [ 898 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 169 527 183 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 163 0 obj << /Dest [ 910 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 156 527 170 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 164 0 obj << /Dest [ 917 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 142 527 156 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 165 0 obj << /Dest [ 922 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 129 527 143 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 166 0 obj << /Dest [ 922 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 115 527 129 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 167 0 obj << /Dest [ 927 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 102 527 116 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 168 0 obj << /Dest [ 931 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 88 527 102 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 169 0 obj << /Dest [ 931 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 72 527 86 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 170 0 obj << /Dest [ 943 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 58 527 72 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 171 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT10 1667 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 172 0 obj << /Length 3331 /Filter /FlateDecode >> stream H‰ÌWÛnÛH}×WÔcˆ6ï w6 dL´‹ÁÌìE¶lîR$AQvœ™Ø܇­ªæM’mEëQ“l^ΩSU§ÞÏ'oçs$Ì—iƒ…ÿðÇ3°-‚È3ýÐr`¾š¼½^‡¬y뤘¼ýé‹„ÛõÄ2-‹ö$“i·|˜ü.>ÇÆÔ1]q«è×àƒñÏùß&? ‚À2#_Ωoéwðý6?ŠVž¯ŸôÏNm˘JÇô…Ââ¾<Íž±…2ðIb­á‡ŸÞÀoÿ5¦×xÍ3=‘–HîÞÀ—‡¬ù¦êœ∸Hi$àOþŸ?ŒÑ32Û2}<˜ÿˆçø LÃ1¥XÓ[½¯4qi!¸¤=uÇOº™O$d0±=ßt| N`†!øÒt]@Œnµš,'ïç=ŽÄ-Ö6Ó1‚_9ÿÅËÝWÇdàÑ{ÆTFCTZ.#ÍŽ‰œI³¦Žõ‰Bÿ¬©*}T¶T6Wï&\ÁœöËñ »[ášV²;Ñn[’‘ÝêÃM#Š\û dÛ÷Á¥É3›l—á¼ügL]úz_ßrŒHii&)<}¸óžíPï™:>nšJS´Qs*;¥ÒŠÙ5%Ìþ­T•”E¡’&+‹«wð×ùü3à0œ%¹‡?üà# …¿É?“=`òzL^‡É†Ùb³\ªºVMýH(õbý jD§/A¯ˆù$,K’‹'jÀ,ÄwÊ Sg ¸§àÆàQ¦ùÑyPªÛCu;¨̪ºlʤÌZR®V(Õ_[qdILуŠqùBïDp.¥Ó¹Á•g}9¦.ÌªJJn *&X¦¼ÂâŸÞßüúv~ýÖª¾Ç˜ÒN(˜ G¬ ÀWß º _`],|OdŸ³¬ŠÓ´6¨Ú¨õ±åÙºQ…2B.ý¶;}Ú‰Àhu¡¨9?ÏEm¿ˆÚ‡Y¹P_)PY¢ò§÷F€ ºùÚsPÄ+ÌAÛ‘¼ÿ3l£ˆö¿ó‘Àlmîj§ÍñWT!é¸È8ØZ$5Š5ÆR“¶r…òÞnì\— Úqð³_€%mKò5#2ªö“ëMAÈ L(ˆ±g’NÄ“ižCÈ…»Í C’Cg1 Jت–Á¥ò„cîˆP}SsZäŸëèã«’ÄŒŽ– Þ¤,šº$ĶÈA_#¡»,t[ûfÒZUªáCrq–Kp6vG¸ça?˜úèöïêè”ôßÊBõYL`‹U™RSøÇœSýþ/ÅGPo~ûôó ܪ‚Hr…~¦ ñAw ö±$0v©±ËýŠwá¸G0Û˼Œb`äxUéØë“ÈÀÆ8ÏŠ[@È·ÐºÉ 2¥{÷’Ü“¦ÙíàGÀKþÏíýŸÛ€U¿Q_›-ÿGóIˆ¸ÉFBû?4¾@µÓ[–­ÿ]Ø@ELƉN÷³]yÄÈ·ƒž}o¾ªùsÉüa,u„Õ*®ûŠŽ"šæ¨ÚW•ެŽ7ƒ_Ä:Èœ¾H‰XÅ> 8óþ±bÐ4IóÐÎ~=% 0œ#*«ÁíÔ°ÏÊ%KKv[£tcGV~ÖýPŠ…ÁI^ÃhJ@úNŠõ!Ø}8ö¾ï’ ÌŠ;ª_èRîvw$†6t6ä‹5Ö=ĬáO¥sj?‚6hMœ¯ :–¢hÏágëì{ĉѻ"Ï˵ªšG< ÄQãtI,[à-ñ¾RS÷îoŸ“ö>èSuñ rôƒ¬Š@O 64¹%.h¥¯§:ëïÉgÀ]Ì¿ƒïë¹ â¹ y䞈#!áï´€ iW*YÔGBdÀzµ,é²# ö²Ã˜ÒW?“Ò ïJŽƒ à—¿\>Ò@ѰmÌ,Y‹2Õ G§ªµ…žû jx’L\¹ÃJ[U#kŸ'zŠ—ü„Óû‰¡”bÂPãCiôf"Dw ?ƒts1¸8mb"ìÍB§:op Þ€ŒÆzžÍêÿø['>ÞLÔ«_°Øá´^ê΃öʺ-y¦ŸÑPãìžGF¢gçy”šˆêI°?ø]Ôxd(íqè­uŸÏ8‘x0º¿ŽëTg{M¹*ÒWýVí Þ.èž©i Ÿ£A[æÐùhtM…ýê ò£jCÒ´MÐxÉäã UJÅâEVÏѱ%á¢,8/{e À·¬jÇ¡Îü.²‚‹µÎ¦nHr¸)âE®Þ¦™¶½­‘^äÜ?è³wJ•dqÎ7%¥~ÛjÇdÿ!в˜êckÈ"Õ¥Àè­ƒå:kÔªuìT€‚“†³óÿtqÆ´xÊÐíîå±²œÝ {¦w¤Á{.¾ÇW‡!)w‘i‘•E®îUÞ†úúùmÀû¸¤±lÔ¶T^WKÅð ‘ÐÿSnÙ‚sF†ìÇüuqó[ÒŸ Û²gã%¿Ïs,ÎèÉÒ¸î*S\7ý¸öCž\J×`S¨")S•ÂBÏ»®NL_Ô<µ*(/ò.ç™Öíâ´ÇÃEg7 ØlSd„ÙŒS+ÍT£zŠËn±EeqqÅCÜ;Žü½Èh[„?_DЏÂp…°Ï7¯ãv/U§Ã!Ã!±kÁIU â¬Kb ĪËm=ÓYoE=8¢³iÔ¬¦ú|…Uz™%Ð>Tz,0__›“”áje¸çÒ1¶` #ÑXLXöâ–P¸--o8ê³rÓܖبǗÞÁõFS›Áª³B§¦Ü¿«²½‚¶.Qz­ÿg>¤y {ÉÞŽ ód¡£Ž¤ ÜkÎH‡£B߉~-’/T¶~óHÏÞnÑp?9F;|âì¬WÁŽÚ0½÷+|´¥¦"‰ã„jÕËõ²{a·@S—¢’ìÊ Uû÷}3㻤Ô\Hˆcð›y3ó„sïÃÀh+¬ôqå•Óå÷ê³™|YÉ"Ú55ü&åHL%Î]|fp! .N0qA£ëßì©VÄj¥¹S¼¢mÁ´Í…¶ã;Û5†³IpT¬µ2&Î^:_Cau9U›?tùã@ÀpSç$@÷¼‰P$ hn¥Ž¡(9ô2ƒS5ïÚȉ‰´¨pwiêÿ‰\Ï«©LÙx `FÖ¦"[& G" nÃav†lâXè7°=ÍöO¯ƒ9 ™Pƒ.õù¿È×þ¤Ù4þ+‰ˆÅÐ`¬3œ†Ãü›ëûEò‘(Ÿjù¾4‰%€AÆ– ­)$E62û¿S?›Q`ÓÙì*ðÕÞsB Ëäˆw¼SËåç»ÚšßBàmŸêøkªì‰2ybêhŒAtg Úb)sw€xhƒÙ0 Òwê¦ó᧤çêí†ò”“¢!®ò­0’ôF\&×<­oñrÛc­ïÉ=‚4é“<{9k 8Òå5©*÷<=xÏ}ª°.«Yýê~·u³¢’ëÃ[p·}ñÈ$¤Èi†áéýŠU·ƒÞ'çûlèó)–³± @>GuA:—šsì³{öÙ‰*È—è¨M;\)̸ïèà=jJ €厽![¥]û ê u™±Ç«t÷“š—:ÙÜqV¯ä3ù:N<ÜŒ™ÓÙåÁX<¾ù#ÀÄ?·/ endstream endobj 173 0 obj << /Type /Page /Parent 1704 0 R /Resources 217 0 R /Contents 218 0 R /Annots [ 174 0 R 175 0 R 176 0 R 177 0 R 178 0 R 179 0 R 180 0 R 181 0 R 182 0 R 183 0 R 184 0 R 185 0 R 186 0 R 187 0 R 188 0 R 189 0 R 190 0 R 191 0 R 192 0 R 193 0 R 194 0 R 195 0 R 196 0 R 197 0 R 198 0 R 199 0 R 200 0 R 201 0 R 202 0 R 203 0 R 204 0 R 205 0 R 206 0 R 207 0 R 208 0 R 209 0 R 210 0 R 211 0 R 212 0 R 213 0 R 214 0 R 215 0 R 216 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 174 0 obj << /Dest [ 943 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 757 527 771 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 175 0 obj << /Dest [ 943 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 743 527 757 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 176 0 obj << /Dest [ 948 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 730 527 744 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 177 0 obj << /Dest [ 948 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 716 527 730 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 178 0 obj << /Dest [ 952 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 703 527 717 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 179 0 obj << /Dest [ 952 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 689 527 703 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 180 0 obj << /Dest [ 952 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 676 527 690 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 181 0 obj << /Dest [ 956 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 662 527 676 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 182 0 obj << /Dest [ 956 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 649 527 663 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 183 0 obj << /Dest [ 956 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 635 527 649 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 184 0 obj << /Dest [ 961 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 622 527 636 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 185 0 obj << /Dest [ 961 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 595 527 609 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 186 0 obj << /Dest [ 961 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 568 527 582 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 187 0 obj << /Dest [ 966 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 541 527 555 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 188 0 obj << /Dest [ 970 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 514 527 528 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 189 0 obj << /Dest [ 970 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 500 527 514 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 190 0 obj << /Dest [ 970 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 487 527 501 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 191 0 obj << /Dest [ 974 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 473 527 487 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 192 0 obj << /Dest [ 974 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 460 527 474 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 193 0 obj << /Dest [ 974 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 446 527 460 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 194 0 obj << /Dest [ 974 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 433 527 447 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 195 0 obj << /Dest [ 979 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 419 527 433 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 196 0 obj << /Dest [ 979 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 392 527 406 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 197 0 obj << /Dest [ 979 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 379 527 393 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 198 0 obj << /Dest [ 986 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 352 527 366 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 199 0 obj << /Dest [ 986 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 338 527 352 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 200 0 obj << /Dest [ 986 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 325 527 339 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 201 0 obj << /Dest [ 991 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 311 527 325 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 202 0 obj << /Dest [ 991 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 298 527 312 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 203 0 obj << /Dest [ 1008 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 284 527 298 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 204 0 obj << /Dest [ 1008 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 271 527 285 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 205 0 obj << /Dest [ 1016 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 257 527 271 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 206 0 obj << /Dest [ 1026 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 244 527 258 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 207 0 obj << /Dest [ 1026 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 230 527 244 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 208 0 obj << /Dest [ 1032 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 217 527 231 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 209 0 obj << /Dest [ 1032 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 203 527 217 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 210 0 obj << /Dest [ 1032 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 190 527 204 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 211 0 obj << /Dest [ 1038 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 176 527 190 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 212 0 obj << /Dest [ 1038 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 163 527 177 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 213 0 obj << /Dest [ 1038 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 136 527 150 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 214 0 obj << /Dest [ 1042 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 109 527 123 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 215 0 obj << /Dest [ 1042 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 82 527 96 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 216 0 obj << /Dest [ 1046 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 68 527 82 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 217 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT8 1666 0 R /TT10 1667 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 218 0 obj << /Length 3304 /Filter /FlateDecode >> stream H‰¼WÝnÛ8½÷Sðn( VEý;0tÚEwlÑfnv±ŠDÛœ‘%¯DÅIdßaßq/ö|¤$»I'µ§ I$Eñ|çû9ßÏד7××>ìz1>óð‹K8 ÜÄ÷b–Ì"7N½€]¯'oÞµ)Ë[³Æcm^MÞ|ø"زx®çÑš|2n·“òO™3 Ü/%]}Îæüëúo“™Ù`ÆÏÅøHº±g¿aÞ÷ÍVtÅv§ÿúúž3s/e7÷ìË}¥Wñ¹t°oUËÞ~¸`ÿøŸ3ðÜ`.r#®ç« öe«ôWÙ”f“€gUáLgœýÇü73è 2ßsc<\¿Ç˜9Áv»uÀ¼¥¯Jú,¶Æ']Üz—÷C+³Ó_®'‚)6ñ£Ø bÁ‚ÄMS 7 0†)käd1ùùz4F °ÄûÖ;K{dœòúwâ+}ÈWê[K&±çâogJo4å@ŠnÀæüw'[½Îî´ZË«K†;F·lQÃ0OÃú5lãLS‡9cà«sÙ¶ªZâ)uSî¾üJ<.<ßX0„gq±›ŽÆÎ­ÅbšESá-ZpþÎÁ…;pªêÁeV •g%kËzËŠz[‘¼êô1Å3øÚɨ³ðé8ªˆÍå–M••]SR»‘¹3-jqÏ~ûü‘u­,˜®Y–ȦŸ²V6·Ôù¯Xp6ºÄH—Å#]²È:½ºº˜;1¾Û8è˜Q M8Óç׎©à#öó_?²·xC‚å<Óª&N“ä>i±¥§c žwńͩ®ê*'/üõ}䤈 fØRV²1çf”Bøº.V"xð÷»åÎÃ?•µ”ÍóºjuVé9Ü0Ö#lu£*ËÜ’<‰íĈÛ1w"¾#ÌÍyaÀ[*\ —UÑÈvÓ5êê‚üÕÜÖUy¿…÷Š Èb!x"¡M8Ìñ‹~ûü ƒIjÙ5ƒƒFÝóG‘†M‰¤y«Ö›RR°!g4„h7²ÙRn1éØ*%商YßpÎàe ÎFÔS¥L8ì-œiˆ“±ùº+µÒ«Ffp¼-)Û›±)¯”Û)$Jy'©`#ÿðÎ2Qû.4EíD˜GŠæ-u²Ý÷K\UJ·y£6ƒëÙdH*ÓÈ-´€ +ZòzO’;;¹`°0²#¸€ve\í`Ùa Œƒ[k–à¥qÁ¼ø0®#q"K8Ý†Ä µŠYÙ¨ìE®áÈ!oíSf/Y×£™TNÀ7{¯š\dfd.Õ­,Ì­ê÷„*9mlì)ŒÌö˜H¸þf{’É‘ß~`4·d¥¼•å ”' îZä¿B²´vÙ'•3ˆ®—’ió*_˜" о+ÔgÄÃ…¾ˆÐìŸ"<`µ”Ó ,ܵöQ×ë¥Ô›N·{Ó)o”i(@µ¾²vcvpÔ ÇÛØº‹Í¾Ùë²ßëò ‘õ‚åãV¦ªÍ÷c8ޱt‡#Ý¡µE/È>HÍ@6ûÔiPO>Ü'DG´GhjŠ{BS"!%h;9¥¶ ÎòÜ´{oF;nS„#³©aÖ³±øè,-Æ["Þ³š«ñ¡ |”ƒ…o D!€Œk’@Öü¨ÈèÇP=ðšžM$=©SKØ6SzQ7¶Õ eÂÙM6M·î‹]Ù»>[Z49‹ê¬ 2h5{|Dž ^pD¾Ï,¼F–÷u%³¦¼_g›–tnQ0¸"µ"p›M]ª~¼X¬DÕKøóÑ6–PoWBC[BC[B©Zù›ò¦[æ«®úcݵê+µ˜mtfTÃbÞ,åßo~—9|›–1ZÄJµ†Ü]±„iÙj#<’Ù!mù†3xV)ÍÎÆe4bŽF.}a¹,d)é|KZÿˆ‚ŸŠ0G0+dYÄNTu5•wÊ`cʺ¬vHFšõV$áˆñH8ú>›w¤æI‰ZÆ´Z˯€j„¥6­åO- .2JQÚ|--¢Ì'¾WÎ!y>C´Mgqû›g®ˆE¦¥ªò²k!ÌCŒÆ@dò²,lÊî4u¥[6.¦-}:ûeã°Ñ©{ŒÌÐnêF×N¯4m‘©Ò¤QäU€êe‰0²µÐT°ÇÉÔ¾§àཀ{ep:ÓdºGg:\L&Џ±ykͼª·¹Î³Í¦©7Ò¨k”%ûÙ+{¹´¯±á«Ù¶èVeY £ÝfS`AÂÆì§á ¸U¹Ü/óþÄbO­*8Ôš2"ù@_¯Âô´ÌÿÝ?V·¡™t›Ûw †ºoÕ|*ÙWwÏ“¶sÌéCÏŒÑa-Ié¹<éû¤j€˜"Æ„'m1nK%^*÷´ŠlÝ«ázdö_°WÀ«…aòDö!¦¦æd_ÜS¦c3%Â=eÓX s-:£têÃmªnݧNòI 5¡F]CÖdëÖ®½²—K»òP·– %¢Â6" ·É[˜¾/ì·¾gldV¡‰C2·Hã?õ{¡þZ¾…s›•lYÖ2<عÊÖ²wZªXa€ƒüÙÎ9 g8´â Äí€N÷‘’?¦È”q‘çr£Qânap´Vs¾5£Y…èFu·³¬Ÿf-\Ñø%l2 ž bƒ&:ÍÑéÏØ¼¬— ¤z:¼©æ9ùRˆds«À$f¡²î ºõ¶é‰ªó ÖôLÌXg`É*»){ZŠ©ÑR¦‘ÙðÐ茸lIpÿ0 Qö(Ô[¯-‰6ª ÚÂÛ±µ«> Ð4JÎ{Üìyp¯dË7l•Ù,IPF|€ä¤=e¿ÜJf•gŸ<õ|¨ö8 OälÌö^¸ã,0U…_ÝæÚè«‹~ ¬jWýà¥ÕÿŸ›=c>uÊëTÐ6u«§¥Ñ\!_:”ïQÞì‹-åî´ÀzXý,¶WŠÈ§’I œµºn(|Pù)U”¬dï‡ $EM} Õ…(8¢„_È%èUØü[ôP†ˆ1ëï#sª3 †ÌçRe­á択#~É2L¼DŸ eSQ ¦0¥Bhš½RöfLdnÑÒá՚ȎéΨÒó¸5µ‰¦ ñ#»D¯±ËXÅNž‰`ß2ˆÞâUÍ1+åÛ‚k,”à Ú”ÐZiö Lð÷gOPÌ f6[h†cî/z‚7%¹‚Ïï­g)”ؤFfáÒD,ZA6:GFNñÞ«¦ÇMˆÞû+¬½ÔHmHø°Tí©UU©=µ=m.ØÉàeóïûÆcb²lªlCi³‰=æ½ç™7Ü œ¾&‰gˆE:—(FpœáRÐQÚ '”ÈÒ´ú†Õò}Òé§åÓ‘ÈlÆ gÆ»cª]sŠâ ðv4¼6¼c £13퉈d¥Éh“â„Ë %œW\G0a¸k åÙÕeÅ‘€+¡”(9³b2§>.!‚©®ïŽûÓ}:d[@ç+ Ü \&z#쥕¸ópÁaßÙš[÷Ga¼&áü%:ÙLÚX*?M¨1)”ézΈ8N¨VP&}—·¼Ð ß+d&ÆQ„CW5.ÎSÑ §bu{æ~ŽŠ}æñ8sLR0ªèÒò l9ÚâÓ”[uMÅßù…d…[²MþT7ûF`Üý…‹°Â¸EeDøÛÌ¢â;f®o_'£¬ïhK~$ú­DÒŸkZ[Òß2š×f¾Ž zæ®T1êÜÝÐâ&„% 4)OØ5\¥ž«tÌ•²ö‡Iú@´)îp™¥gíÞ+^jKmŠ\×yj2Ïv…Ýþ@þò£ØÈÏ?ÝçM `js­…{y_›–/EPkzaÛÅ‹dF#2ó²äZ¹ ŸÔ@®{1‹ÙB…bÑFž˜TS&3õ:&/vfÜòƒmÁëÜ´º.z×~yµ=Úý{ÞÇœÂ{ÚøNÔYô½ çnûÐRw.¤¯q²†@ÖAÆÂY˶˜Pù ÷@¨llPúÖRïI bìܳFá?Q¹BINÕó"r •«E<•Jl³L$5C³ßQ/!¯9õToù»qo«¬ ¯JëÉ©i†Ü4oDNö*Z^ßH>ýxó[€Íœ4 endstream endobj 219 0 obj << /Type /Page /Parent 1704 0 R /Resources 267 0 R /Contents 268 0 R /Annots [ 220 0 R 221 0 R 222 0 R 223 0 R 224 0 R 225 0 R 226 0 R 227 0 R 228 0 R 229 0 R 230 0 R 231 0 R 232 0 R 233 0 R 234 0 R 235 0 R 236 0 R 237 0 R 238 0 R 239 0 R 240 0 R 241 0 R 242 0 R 243 0 R 244 0 R 245 0 R 246 0 R 247 0 R 248 0 R 249 0 R 250 0 R 251 0 R 252 0 R 253 0 R 254 0 R 255 0 R 256 0 R 257 0 R 258 0 R 259 0 R 260 0 R 261 0 R 262 0 R 263 0 R 264 0 R 265 0 R 266 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 220 0 obj << /Dest [ 1046 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 757 527 771 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 221 0 obj << /Dest [ 1054 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 743 527 757 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 222 0 obj << /Dest [ 1054 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 730 527 744 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 223 0 obj << /Dest [ 1054 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 716 527 730 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 224 0 obj << /Dest [ 1066 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 703 527 717 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 225 0 obj << /Dest [ 1066 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 689 527 703 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 226 0 obj << /Dest [ 1066 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 676 527 690 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 227 0 obj << /Dest [ 1074 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 662 527 676 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 228 0 obj << /Dest [ 1074 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 649 527 663 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 229 0 obj << /Dest [ 1074 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 635 527 649 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 230 0 obj << /Dest [ 1117 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 622 527 636 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 231 0 obj << /Dest [ 1126 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 595 527 609 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 232 0 obj << /Dest [ 1126 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 581 527 595 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 233 0 obj << /Dest [ 1126 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 568 527 582 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 234 0 obj << /Dest [ 1135 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 554 527 568 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 235 0 obj << /Dest [ 1135 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 541 527 555 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 236 0 obj << /Dest [ 1144 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 514 527 528 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 237 0 obj << /Dest [ 1144 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 500 527 514 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 238 0 obj << /Dest [ 1150 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 487 527 501 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 239 0 obj << /Dest [ 1150 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 473 527 487 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 240 0 obj << /Dest [ 1150 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 460 527 474 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 241 0 obj << /Dest [ 1159 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 446 527 460 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 242 0 obj << /Dest [ 1159 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 433 527 447 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 243 0 obj << /Dest [ 1163 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 419 527 433 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 244 0 obj << /Dest [ 1163 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 406 527 420 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 245 0 obj << /Dest [ 1163 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 392 527 406 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 246 0 obj << /Dest [ 1168 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 365 527 379 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 247 0 obj << /Dest [ 1168 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 352 527 366 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 248 0 obj << /Dest [ 1168 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 325 527 339 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 249 0 obj << /Dest [ 1174 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 311 527 325 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 250 0 obj << /Dest [ 1174 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 125 284 527 298 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 251 0 obj << /Dest [ 1204 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 107 271 527 285 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 252 0 obj << /Dest [ 1204 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 107 257 527 271 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 253 0 obj << /Dest [ 1212 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 107 244 527 258 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 254 0 obj << /Dest [ 1225 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 107 230 527 244 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 255 0 obj << /Dest [ 1233 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 107 217 527 231 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 256 0 obj << /Dest [ 1241 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 107 203 527 217 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 257 0 obj << /Dest [ 1241 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 190 527 204 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 258 0 obj << /Dest [ 1249 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 176 527 190 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 259 0 obj << /Dest [ 1249 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 163 527 177 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 260 0 obj << /Dest [ 1249 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 149 527 163 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 261 0 obj << /Dest [ 1254 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 136 527 150 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 262 0 obj << /Dest [ 1254 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 122 527 136 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 263 0 obj << /Dest [ 1254 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 109 527 123 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 264 0 obj << /Dest [ 1259 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 95 527 109 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 265 0 obj << /Dest [ 1259 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 82 527 96 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 266 0 obj << /Dest [ 1264 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 68 527 82 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 267 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT8 1666 0 R /TT10 1667 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 268 0 obj << /Length 3411 /Filter /FlateDecode >> stream H‰´WËŽÛÊÝë+Þ¤ X4ÉæÓ ÇÁ ‚àYå: Õša®D eÝñ‡äòYäTU“”4#ÏC²#‘ì»NU:õéfòáæ&R¡º™OÂHøÃO\?‹‚TeEâ§y`ÔÍròáO›\Už¨MÕL>üò%Tw›IàÍ©&Óþr7ùUÿ£ô¦Æõ¥ßH«\yÿºùë¤à •~‘â%&÷Ó@ÞÁë#ÞŠ®’Tvúo„§Ó(ð¦¡ñSäêöA}yhº{<‰´õ°“ÞÔõÇ_Þ«þÏ›&¸o1–ø‰®½@W÷ïÕ—]Ý}·í‚71ºlfÞ´Ðê?üÍcëÙ²(ðSÜÜ|Æ3>Án·ó=ã‡zCoµôZlWú¸ `\åÝóN¾™„ªV“(I}“†Êd~ž«4ôãXÁÆ8W­Ì'Ÿn0Lˆ)Á!#Ò!‚SÞü{ÏKE,øeiàã_–µptEè\†¾‰}¬¹Ún¼€áeúú£’;UªYÙy8®á³>ëÖddÁ4ÿg2cüÄ`N#8B_†ð=MB°†D+N– Ó{pÆ`žšÄÏÕ4$£i1Âr€ŠQW³—ø^3¯måîš HôGe¦êòva)ìä®’á¿ÿM}þ¢B?R²¶nîÎ@ANÑFá±½lÏh/ctÚh3VGfÇ0›,‰t‰c—Í%³ ½ålZ¯i,Ñ«¶»&Øv%¶­xîqtÞ4 5ì 3g`q>ÑóH$ê ‘Iì'ºªøÎ®;ñ(ì—'÷!b«ßTÝT«%¬TuÈrƒX c²|óöø)ŒÑp’RuE\P/lÓÍjº¬˜$ÊÖ‹ñ3ð±î‡¦D ý˜jV*« ˆÙ™ƒ$$ôk4-PÃÞ‹âß7ÑÊHÑ¥Bâ#dêj±:Èòr1»¢€%LA)“é[¹±ZÍ)UJ¹§¤@yÓ7„XBé¦ô”ä ;Ǚ،¡²Î!:¹ºª™cýM¼&Ks]ƒ#z<ò”£D¤Ë·~ŠGó‰KêNr&&û/Ãá%#å$yêŠéð›3‹ æ rzFåv‰)l¸&zd8fÓ‘)[.Ç=w˜ŸÍQà 0Áº¤\§ÿ¹GtØ'ØÎqéÙ“bôÐ/šFa|Žù#Eœiuô¼Õ¡«Ÿ°ºããw+áC+ìX7u·G–2Fþ6zM5õ䘪ÊÅDzkA0 ;Ø[•,,¯l¶,¦D<·¥¨¼i˜¿„i/†Ú+ñˆZ|€ZäP‹j°Op+ĶÃ&b{bÝÔ2…*o¦7•L”±D W²òp´‡±” …<ÌÐe:ôüí^·ŠÌ^¿~9ðK/uA1vSÅ~†µJ,ZµyÔÚrö@t‚€hk&^ˆ72™âç41T°ìîEüÙF•3’o…Æ^l¿úª»²½³,~Oì ±·,×òà«§ÊÖö=Ó$á<Œb ßI}î‡Ïå~Š'~=y˜1²cG¦~^¼²Ý8U@£˜´UÃWF+ÛÌäIE.ºæäßåâ»X|g·Õ–DVÙ± Á:n7™Ø`ALo…k(ž@¸´”ˆDy§Í©^ض{dôõS@ô¹ÝÛΰ”´:áœä§Aó‚DO,Z·vý(Ÿ”㨠+$ªŒ[o$ígÜåQ–Ñ7Z)^H~y0À䊙 I€É${ ‚¿A7]ÙmåJ¾b¡ƒgª[©û²™-¬#•êaU­fÖ]C7ÉÊM7¨×(>ÅmIz>$Ïu+ôxßVdÔ¾ÚúŠ@&§Mв9²¤LË·knd5J Àzrl †ýöj¿ËöðÃåÜ3`R1Æm§Üyé¨Ó' I´WHz Š Êã7|ÞRHŠ ’~GçÑ:ŒQæe½ î#W5w®Kmít˜ hƨºÙ5(øý½s>tÝÚmÕP ¿¾ˆ=é#.]H Z®æ&²mÛU×ïÙ~zh¥BtårMU÷°¶T5Yê9-*ì'3­Ôµ·Ö£Ql@&å/åÅ¡Z˜àR pÒþ¾! +éàßWN[Øë, •{j™Ïz™{h/ÉÀP?²šˆ.__E/€y& ºŠíA ·déjÛÁ剆ßåV.¿_Ð*‡•ð;M~¥OY]ÐíA>ÖÂüÀnÃnà,UÝ»peŽìÉ¥W¨ †»( ·e…fH¹aš ú&n¿µ žÎŽ¢d˜è–Ql€ÍA'²7~‘Üdb þtBˆ÷´gYgºPïÕöµÜ~tZ5‹øÔ@ Ô ÊÕ®æ(JÁX»6é8ö³Æ!fÔz²~ И+gbVÐi¹‡ T÷v=XvZqΩ‰)F/fRm¯åö#4áøeZ‰~a…]°^•¬; 5¯--š77LjèRŠ2³(>ÀR{Þ®–­]®:»jàËXl õv½^µ”B_äŠóB½ƒk &d¦»òAÑr%땬ƒž6øiªwO::?ß°8ÚIåÂ5šÐ†}M+¸ÂyÍ ¶ýeµ£üŸYó¬ƒvIiðŽÖpR”n¥7A!}ƒ!;  ýç$ÚÅýšŒ~MÌÏÅüHw+J»‡­gÔ<ÀωF̶2vMc꫆ƒ‡uÞ´ÀokÅöˆl×OìD›\õ@´ÛqBB°#v~{2wô}gäðôª”AÎ dךE±ßFÜ’ÏVb/ûH\£‚ç‘!-"ü¡mˆk/ÑÔÅòHo)¨³e¹†Ó¨­Ñ%+¸õš"–p§&†gýÁáêj/_—eÐÄCyN@/Fv”³ñÛ¢8~$ÚNÕ«³¤m#Ãß—R»Z;³s$B¤ hBɦŠXscÇF< õÌÉ–[WÀ\y“ÐÅÖ{ž‘ãðÞ4Íë,Þ^Ýú\îÇŒÐt:îSèF›š«åh™>dÁÌ¿¬ùŠSîs$tëðÍ›®’R;3¿½Ì8ÄŽÑòþç]ãéf9œØøË¨`î7…)¥{ƒ]ÉrƒœVèjלì[=$E@=Ë&‘þœý÷·æíë£ Üи­¿’·šŸžä ê0“ÿ; ¦SÕº<8ì‘øô‘h ãÖ4©fëOQ:¨j´†§UðýÏ ÷V"§ƒ’9YÛÈ#×ãÁ?ýþñG€‘4 endstream endobj 269 0 obj << /Type /Page /Parent 1704 0 R /Resources 315 0 R /Contents 316 0 R /Annots [ 270 0 R 271 0 R 272 0 R 273 0 R 274 0 R 275 0 R 276 0 R 277 0 R 278 0 R 279 0 R 280 0 R 281 0 R 282 0 R 283 0 R 284 0 R 285 0 R 286 0 R 287 0 R 288 0 R 289 0 R 290 0 R 291 0 R 292 0 R 293 0 R 294 0 R 295 0 R 296 0 R 297 0 R 298 0 R 299 0 R 300 0 R 301 0 R 302 0 R 303 0 R 304 0 R 305 0 R 306 0 R 307 0 R 308 0 R 309 0 R 310 0 R 311 0 R 312 0 R 313 0 R 314 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 270 0 obj << /Dest [ 1264 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 757 527 771 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 271 0 obj << /Dest [ 1264 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 743 527 757 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 272 0 obj << /Dest [ 1269 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 730 527 744 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 273 0 obj << /Dest [ 1269 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 703 527 717 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 274 0 obj << /Dest [ 1269 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 676 527 690 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 275 0 obj << /Dest [ 1273 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 662 527 676 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 276 0 obj << /Dest [ 1273 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 635 527 649 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 277 0 obj << /Dest [ 1273 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 622 527 636 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 278 0 obj << /Dest [ 1277 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 608 527 622 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 279 0 obj << /Dest [ 1277 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 595 527 609 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 280 0 obj << /Dest [ 1277 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 581 527 595 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 281 0 obj << /Dest [ 1277 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 568 527 582 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 282 0 obj << /Dest [ 1283 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 554 527 568 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 283 0 obj << /Dest [ 1283 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 541 527 555 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 284 0 obj << /Dest [ 1283 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 527 527 541 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 285 0 obj << /Dest [ 1283 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 514 527 528 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 286 0 obj << /Dest [ 1291 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 500 527 514 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 287 0 obj << /Dest [ 1291 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 487 527 501 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 288 0 obj << /Dest [ 1291 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 473 527 487 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 289 0 obj << /Dest [ 1297 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 443 527 457 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 290 0 obj << /Dest [ 1297 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 426 527 440 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 291 0 obj << /Dest [ 1305 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 412 527 426 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 292 0 obj << /Dest [ 1305 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 399 527 413 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 293 0 obj << /Dest [ 1323 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 385 527 399 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 294 0 obj << /Dest [ 1330 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 372 527 386 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 295 0 obj << /Dest [ 1340 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 358 527 372 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 296 0 obj << /Dest [ 1347 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 345 527 359 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 297 0 obj << /Dest [ 1347 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 331 527 345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 298 0 obj << /Dest [ 1352 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 318 527 332 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 299 0 obj << /Dest [ 1352 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 304 527 318 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 300 0 obj << /Dest [ 1352 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 291 527 305 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 301 0 obj << /Dest [ 1352 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 264 527 278 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 302 0 obj << /Dest [ 1357 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 250 527 264 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 303 0 obj << /Dest [ 1357 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 237 527 251 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 304 0 obj << /Dest [ 1357 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 223 527 237 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 305 0 obj << /Dest [ 1365 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 210 527 224 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 306 0 obj << /Dest [ 1365 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 196 527 210 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 307 0 obj << /Dest [ 1365 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 183 527 197 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 308 0 obj << /Dest [ 1371 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 156 527 170 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 309 0 obj << /Dest [ 1379 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 142 527 156 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 310 0 obj << /Dest [ 1385 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 129 527 143 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 311 0 obj << /Dest [ 1393 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 115 527 129 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 312 0 obj << /Dest [ 1393 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 102 527 116 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 313 0 obj << /Dest [ 1400 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 75 527 89 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 314 0 obj << /Dest [ 1400 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 61 527 75 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 315 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT10 1667 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 316 0 obj << /Length 3327 /Filter /FlateDecode >> stream H‰ÄWÛnãÈ|×W4æ%$`qx¿ŠÌÌb‘E‚ÝÀÊKy IJâ‚"µ$eÙû!ù‡ücRçtó"[’/’“Y¬E‘ÍVWÕé:Õ_æ“Ïó¹-,1_L,[˜ønämú"ˆ<ÃMGÌדÏ_›P$ 1E“”“Ï?ÞZbÙLLÃ4iL2™v—»Éwí—XŸ:†«-3ú´5 ýŸóŸ&O‰À4"?℆oÊßà÷mžŠ®<_Îôow§¶©O-Çð53wâö±lW¸ck™Ž™´&oÄŸ~¼ÿø>õð½Æ3Ïð´\7µdu%nwyû{V<‰£ÅeªO#Mü‹ÿòÂ=#³MÃÇ—ù7Üãìv;Cw KkèW3úYLŸ4pi\¢n­x¦æKäbb{¾áø–p# …o®+€Ñ EM“/óž ÇÂsŸi“Á*翎TŠ\É_à›þ—¯ÿÑ E$—oYX Ͷ›T·ˆ­¸Í’"×#\ VË6/zk ÈÔj'¿>ªçÉ͵Àûq«©Û½&0MV¶¤¸›Tu*_é¶ÎË¥8='hséÊ8ú#M‚Y®ÇÜ¢`-SV¬ãa/S"µ’, U=åASËc4ðAÁ>Ar©Y}ŸÕ=5=€ct¨—ä7z̼ƒó)£Äé) JÂ1%¡˜•Um ”J¨Å´ÂHK2ɇG|@vG“ß$)eF¨{jIFÀ•³¨ï\45Þ5ž¤ÆVÔx’š€©±éâ8+.Xñ/U(ÇX‰ÄLBY9ivŸ—‹uü€[¹\ÿïÉy”À€|½]‹…b¡HÅ“±àcSÕm–мTûêz¨fìaŠWñ°åPák”4b]pÅìb.ÙGéžOLôtÊXZ¬Fð‡ô› V2a‰ðB;ÚT–³Ç„'fm­» / PF݇¢iÒE(]ÎÖºÒPÑÍ%~ w÷~Œ&¯éî{´5J To¾¶ÀsDT®åØ57¹¾€ž”}‚·aËœÉÒP/îÀ’»Ç’¯XŠ˜¥H±(Û–K§ ˜ï¢låmÑVœD̉tωŒ˜°™‰@“#ˆ wÄMó÷9~¥ó óòzJNxÉ:Ò<Êô¤®ê žV•-œ~Q)8ØÙÔÈð°~u—K=ä’—pù©å»oÁvh³Ø,ƒãörûëqÛVY™"°IëÌËDYĶÒó{Jí'žîà”R2»;° &KY)¦,†yô©ßÛ©û"_ƒŸFž p„©¶í»aE¥`É.^«.ß‚€½†ßŠ4[ÄÛ¢ò-‘¬â:–1¡Åqo0 ŽÓ^G‚{> /…HÇ‚¼ÜȆâu[°TükU"ÚKƒüª¢ è–K‡´ýÁïÁ?fÁ¾`)ȣⴻñ€0ÍnhkÙR¶Ôäq]ñÁGÅeG»b*fEVR&ž^ .v¸%¯Eü€£­‚ï ‰$•ì¸e‚tˆwäГ˜/©ûQÄÅuö«Âœ´rYtxC’o @Ã<òû£U&ÌÄ.oW(…ûÝ\©Iy?ç¿RNíáéš½9x(&º– §H×¢ÕOŸ¤d[-ÿöoùüó·/_Å]Ü ·Ñf½Íj@(Û¯…\2l)£9œ~9©õ¦LƒvryZϤNHvRøª<ƒŒÉ~Õ])),@â¶EdYÓ¢±Íôi$‚%“¦Éi‹!L½³á¾¦êŽí úËk€ °¿±ŒdÙ Ù3«UªR¹‹¹»Žb…©ç¾"a½º2!ûA·;èκ'¡w°=†í °yõ¢¼³”Ï8<ªª³>˯͞G »çCQuç”ꀉ8QCÆ=J UK²­›ª.ò;ÀÚ6ñ2ÕBÚ¼|"ðˆœ&b§ ´¸~¤øÎ>tí3Ú/œ¾,öûY›=´ëxss%ø2Þ¶«îzãúZ°±­ „ØR1e%Šª\JÅ=FŽ´ßÇyßÔç"M‰| ¡ŽòÁ2"t%p¢ËÑjè€Q3´µƒ"FЦ¯}·¸Hx}i=–Fí]ð}zrFs:}ŠÉkz”° *—·!Iü×ožHóeÖô0[3–Ðl“`¾•>ª!˜X.XeX6-™Óˆ\vCÇ›ô¿´WËr1¼ç+TœViv¥ìœœ›/®äÖB`•¼ .þÞ=3Z„ Á pBÒH¥Ùõt«ºSXŽBŠäZø‡DÌ͉ %)räþ'`aÊäzÊ„DÖÌ÷ºÀ‹!Bðšêoœ§J̳nÅÓ ½3,$è-ç¼ÖÕ´µÌ _x²eó$ÿïØ…kꟲgツL5 Ù”â8ðg?޶¼=Ò¿÷t15¯ AòmçS‡§¡FÔ_/KŒU¤þ\(äöâ·ÝªA]®Öþu«¦à|¶2õÀŒÏü²èƒ£6Gäg <Î?lΙ +sQAi (›vîÙ»—Ž%òtk<¹¹âÅKd]è½I®g¿,4w¤_Ù³Xìr*RNÐŽ$ˆ»¾ž/7â’„]ìZ×™¸ ßÃóð ž5ä ©™/C‡*Ÿš*¿loƒüz{ ½J’åïGÍ×E¢MÓûT}«8HA‹IW šØ~ú-á«ÄzÅœÚßvíó; #IñBܰc²9ŠgÂô°:SgPývéïd<âõ¸¸âA3ú>j'OnôSféC=€¸HŠÖ¬Im6Aw¿w0ÈÒdtzœXòaÞ…ip|}A4–dÿê/÷Œ-“1_Æ "üŠCcP–Ÿ;@W4À$FL*M‹úW·Ó¶™xp§¦ªC‰YzYG—1႒銴Øs+W³æ˜'ø&z´tšÉiË™={ŽÍ^ŽŸíÁgá´?-ë_¾½ 0/ÒzÁ endstream endobj 317 0 obj << /Type /Page /Parent 1704 0 R /Resources 359 0 R /Contents 360 0 R /Annots [ 318 0 R 319 0 R 320 0 R 321 0 R 322 0 R 323 0 R 324 0 R 325 0 R 326 0 R 327 0 R 328 0 R 329 0 R 330 0 R 331 0 R 332 0 R 333 0 R 334 0 R 335 0 R 336 0 R 337 0 R 338 0 R 339 0 R 340 0 R 341 0 R 342 0 R 343 0 R 344 0 R 345 0 R 346 0 R 347 0 R 348 0 R 349 0 R 350 0 R 351 0 R 352 0 R 353 0 R 354 0 R 355 0 R 356 0 R 357 0 R 358 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 318 0 obj << /Dest [ 1411 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 743 527 757 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 319 0 obj << /Dest [ 1446 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 730 527 744 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 320 0 obj << /Dest [ 1446 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 716 527 730 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 321 0 obj << /Dest [ 1446 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 689 527 703 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 322 0 obj << /Dest [ 1458 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 676 527 690 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 323 0 obj << /Dest [ 1466 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 662 527 676 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 324 0 obj << /Dest [ 1466 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 649 527 663 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 325 0 obj << /Dest [ 1466 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 635 527 649 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 326 0 obj << /Dest [ 1472 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 622 527 636 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 327 0 obj << /Dest [ 1472 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 608 527 622 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 328 0 obj << /Dest [ 1472 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 595 527 609 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 329 0 obj << /Dest [ 1472 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 568 527 582 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 330 0 obj << /Dest [ 1476 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 554 527 568 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 331 0 obj << /Dest [ 1476 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 541 527 555 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 332 0 obj << /Dest [ 1485 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 514 527 528 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 333 0 obj << /Dest [ 1485 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 500 527 514 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 334 0 obj << /Dest [ 1495 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 460 527 474 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 335 0 obj << /Dest [ 1505 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 446 527 460 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 336 0 obj << /Dest [ 1513 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 433 527 447 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 337 0 obj << /Dest [ 1539 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 406 527 420 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 338 0 obj << /Dest [ 1539 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 392 527 406 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 339 0 obj << /Dest [ 1546 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 365 527 379 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 340 0 obj << /Dest [ 1546 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 352 527 366 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 341 0 obj << /Dest [ 1546 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 338 527 352 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 342 0 obj << /Dest [ 1552 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 308 527 322 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 343 0 obj << /Dest [ 1556 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 274 527 288 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 344 0 obj << /Dest [ 1556 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 257 527 271 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 345 0 obj << /Dest [ 1556 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 244 527 258 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 346 0 obj << /Dest [ 1562 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 230 527 244 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 347 0 obj << /Dest [ 1562 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 217 527 231 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 348 0 obj << /Dest [ 1562 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 203 527 217 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 349 0 obj << /Dest [ 1562 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 190 527 204 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 350 0 obj << /Dest [ 1562 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 176 527 190 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 351 0 obj << /Dest [ 1567 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 163 527 177 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 352 0 obj << /Dest [ 1567 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 149 527 163 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 353 0 obj << /Dest [ 1567 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 136 527 150 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 354 0 obj << /Dest [ 1567 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 122 552 136 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 355 0 obj << /Dest [ 1574 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 109 527 123 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 356 0 obj << /Dest [ 1574 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 95 527 109 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 357 0 obj << /Dest [ 1574 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 82 527 96 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 358 0 obj << /Dest [ 1579 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 68 527 82 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 359 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT10 1667 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 360 0 obj << /Length 3097 /Filter /FlateDecode >> stream H‰ÔWÛŽãÆ}Ÿ¯hø©¬h6ï(dwÇl¼ˆª¥¡A‘2EíìøCòùÇ<äTWó¢ÕÜ¥]Äc¯Hv7›]çÔåÔë˳¯//}¡ÄåòLùÂø„iêz©‹$‹Ü8õq¹>ûúÍ6ÅÖ¬ñĶ¨Ï¾þö½«í™çz­)ÎfýíÍÙOò]îÌ7”+MW_ å ç_—=ËÌ™H<7‹ñ• uc?b6ðÍ^tżÕ|ŒÎ|Ï™©À¥—Š«[ñþ¶î®1âKí`'¹-·âOß¾ÿü¯3‹ðÜb.r#Y:ž,®_‰÷7e÷›n+³I ózáÌ2)þm~ÍÁŒùÆ4ßsc<\¾Å˜9ÁÍÍë®’[úª¦Ïbk|ÒÅ­ë ;tmvúæòL‰RœùQì±A⦩ˆ•†6†©hõÙòìõåF °ÄÛGc„Ú#DpÊË_&4e!ã—Äž‹ü PSÑÀÝÒñq4˜ä‹ùÖ‰qØÛºè Ú•îð?þê(üVì‰ä…3óå«é fqí(å¦RߨWª ¬qRùɲÝf‘wz²Æâ;S.N°ÒáFŸQÖgèsã. mHmö¢ÎA»¤d]^$Öy¯œ Ü€Ø)׺îœY˜àÖ=͸Í2¸”Š#c‚Fy5A䦃§ì.LÔY3³ˆlzÛáÂC¼¤SŽ‚œÜ–P(×nêòõæÖòÜ™IbÙ´ë¼£‹Àb½¥¼V”µ3Kqæ¦.¿ªÈo=ßM¤Kï‡O‡Àzô‚гãɹŸšŠ9q.s²"‘ݺY,K]-ºÛ†åì—¸œ Ì”˜ZÃ…]îÐ0Ý­Y—f1E>Ùîoû@þ½õñ¦mê¢[ç›Ü>Uýî+…_YÛ—ZZ|0mb‘¢]ß1ûÔ¸D("áŽ>¥Î‰FGI Èò 9yjlŽˆ/Ý”þ ƒrŸ£>@OÆÑÄA÷<4æM‘ÊN/ËŠü2–”™þþ}ID)ÙiÌó«œWBD+ “AC™ÓX XpôÔN,> ¹«’*Q§ Õû Hö ¸ÚñÃ-d³#$R‘8Ï„E˃ÿ¹Sv*æ¿îš®¬WÈIl¶†Å”Æ®›ñ··¯MF~C2ùØær‡"©ÅK6_¯w"&¼ÇiAùZ^ia @‘oðL¶¿¶XlŠaËì»À.1IþNHÂã!=Ã=ßB’‰ùÂ-"adrF š;Ýø‰"¦T+ñ¿|ƒH å„S*¿“Q|Hé|ÇBÏ1o+ƒ£âÆ rB¹§¨a×¹9¿æâ•·ÕmѬ×eçÍ8Ô4rž¨êº^ˆfI:·øá{±Ö\ãø×ž@[ ý±¸ÎMôFj‡—»¡¢%Á‰ÁKÆØHöLWb¾ÞU]‰ZÈb×ÒñCÙÔ¨šz¥[ÁƒÄn(7›¦íàåðˆÚ./›Z.äLÐeñó2¶ñâÑf?Ê·où.˜XÃ(²ßš¹»8©–iׂf*5xì¹í(FGŠ—ÏD÷(`¼=hæH‚F‹ÂVŸòé1ΊðsHW²ûª¬A±Ñ%Ô¾aX VðFvˆ˼"ïÈ&j%ØÏA¶Më?œ™šÐ§菱ÓIœO1¼?ÝEâ Z‰ŸdbŽ©Ò*ìË4«JEª²\oS®¨|!Ý—rDf«ó…øÏJ¾ŽJò\Ï‘æG®í¦ã€!᳕ÝX¢ÃSÅã}õHEŒAf1𠪟<ø«©+Õ…)8œ† ­.š·mÖåbjOtlíqÇòs¤ùþ£}…Š÷º6Ü4¦€¹Ü%è½'•¯Œœ$ÿmC‚¬”J¸ •±½]æ¿9)EÜf²‡m3ÎÜ=²nZÒˆŒ:#-ºæS䩃=ú§2dÂªŽ›i,pèFÏà{½B»d·]Õ ÚŒ¼ÎWz­'ðåþúpŠ£»Âi ¦ø0˜Ttª`Bo²&Ý a²áÆTXÞLh€<è ´&ºZ­Í† 5)K]ÊGE/ _9½É?é玟[ ïÛ6¿…ñ}»Ê±³,ëÒè,të|ÚˆB£Ï¢%/«¾(îµ±»ÀHÒðy‚ulJ³ÏÝ”újdþc«7ÚÈOä¯ 8‰ /3SÖÅ~TwȤz½é l=æ­Ž^u6-Bì°æñYš A ¨ücç˜?s8?sƒè}êNb2UŸÒ»áscòîvÉG»T7¥!ÃæñHÚ^iYVHÑSÈ´ƒvdÑæ…8n°c:´úÔÊÔîP¦9…§•¦(Vä…Fƒ‘ú2u0Šåþªi‰±Ž­¹jT&ßïK]ƒ(¯Êñ]®[‡U|‰õñqºá$½å}xâÄþ¡ÇÉ“œ8x´ÏòC“Eâžê†Ÿn¹[2<‹Ù´g6¶™)bÀ Ìr{g©UbSçZ YÛUú\¬ª†0äz‚ }˜ØêšpE×@ݱþ{`´JФ‡vÆ'Á°–ÎÙÔŸ©Vq°L¸òtý•½o Ó䎦p,ÝÈ dÏ,Ý÷€â XýÄxðÿ–ÕÔùΊ¦k ´¾D¨ˆF€¢C€Âì™ý€‚ +-BÊÂèQû˜ÛÙuYäK£“DŸ ó 6ÞÓš—G'°ÙõQ/§Û|Í®sA9ñÿ7®î€æî¸:Hªþ˜Tý!©ŽÐ ªy—o»:®/tJœxWí¨R®^‰ÄûÖ¬„ÓÀ›hýv£‹rYÓ¼›Q‰yÀ^À|IÏK¢PîO’¨uxK9Lp¸RúlFŽèˆä‚ãAy_Ð ˜üÐ ² ù6ºGƨžä’Do•%þ\•ÅŸ$Îßgrx94úKxOM¹Ú­–U¾rúÊK…_¡'ÕÛ;°yb½ÜÆKGŸN°‰>‰¥ ‚ÓÀ“ÈŸ‘S8£¼\+o¼ö?Þ«¦7a†Þù=&¢: mzE€´Ü8 åCš´=ìl?xvS’~iÀT8ÇRìç÷ìgeÉ•°œZŒ´a4ùáú4t¥Wr–E%Û¯tRg׿ÔöŒGøùñ’ÿ‹)Çx Z€BéÛæÝõE£Ý¢Ñ/UuïÁ÷rDæØ”®É6Yú•íw?¸]Â?7È?ÉBÖwµwÀK|™¸w&çôbOÇÏCp±æµÑUbDôšñaÕwQâÙʸ.eáÕÒĆºûØ$ñ¨”@‘ä%°û‹m1Tã&6H¥îûÞŠÉUZB£ï p‹…á2 Yæ>Û¥¼À©Á#¢ëj ç!4›py›çÃwÞ aQRÓÓ3àÈ͘ÁÆ›ûE1^õ~t5Ó endstream endobj 361 0 obj << /Type /Page /Parent 1706 0 R /Resources 397 0 R /Contents 398 0 R /Annots [ 362 0 R 363 0 R 364 0 R 365 0 R 366 0 R 367 0 R 368 0 R 369 0 R 370 0 R 371 0 R 372 0 R 373 0 R 374 0 R 375 0 R 376 0 R 377 0 R 378 0 R 379 0 R 380 0 R 381 0 R 382 0 R 383 0 R 384 0 R 385 0 R 386 0 R 387 0 R 388 0 R 389 0 R 390 0 R 391 0 R 392 0 R 393 0 R 394 0 R 395 0 R 396 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 362 0 obj << /Dest [ 1579 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 757 527 771 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 363 0 obj << /Dest [ 1583 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 727 527 741 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 364 0 obj << /Dest [ 1583 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 696 527 710 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 365 0 obj << /Dest [ 1583 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 682 527 696 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 366 0 obj << /Dest [ 1583 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 669 527 683 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 367 0 obj << /Dest [ 1596 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 655 527 669 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 368 0 obj << /Dest [ 1596 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 639 527 653 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 369 0 obj << /Dest [ 1596 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 625 527 639 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 370 0 obj << /Dest [ 1596 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 612 527 626 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 371 0 obj << /Dest [ 1604 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 598 527 612 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 372 0 obj << /Dest [ 1604 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 585 527 599 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 373 0 obj << /Dest [ 1604 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 571 527 585 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 374 0 obj << /Dest [ 1604 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 558 527 572 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 375 0 obj << /Dest [ 1610 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 544 527 558 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 376 0 obj << /Dest [ 1610 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 531 527 545 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 377 0 obj << /Dest [ 1610 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 517 527 531 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 378 0 obj << /Dest [ 1610 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 504 527 518 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 379 0 obj << /Dest [ 1613 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 490 527 504 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 380 0 obj << /Dest [ 1613 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 477 527 491 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 381 0 obj << /Dest [ 1613 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 463 527 477 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 382 0 obj << /Dest [ 1613 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 450 527 464 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 383 0 obj << /Dest [ 1616 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 423 527 437 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 384 0 obj << /Dest [ 1616 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 409 527 423 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 385 0 obj << /Dest [ 1616 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 396 527 410 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 386 0 obj << /Dest [ 1616 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 382 527 396 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 387 0 obj << /Dest [ 1621 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 369 527 383 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 388 0 obj << /Dest [ 1621 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 355 527 369 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 389 0 obj << /Dest [ 1627 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 342 527 356 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 390 0 obj << /Dest [ 1627 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 95 328 527 342 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 391 0 obj << /Dest [ 1634 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 315 527 329 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 392 0 obj << /Dest [ 1637 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 298 527 312 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 393 0 obj << /Dest [ 1637 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 281 527 295 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 394 0 obj << /Dest [ 1643 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 268 527 282 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 395 0 obj << /Dest [ 1650 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 254 527 268 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 396 0 obj << /Dest [ 1650 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 83 237 527 251 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 397 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT10 1667 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 398 0 obj << /Length 2412 /Filter /FlateDecode >> stream H‰´WÙŽÛÈ}×WÔ[Š€E³Š»ÑhÀÛ ô†[1ò@Q%‰ŠTHªe͇äòyȹUÜzS/’mØ"«.É{î¹Ë©³ÉÛÙL2ÁfˉÌÁ_üxQd;‘°0öí r\6ÛLÞ~¬#–ÖÚÆauZLÞþz-تž8¶ãM:™v—ûÉwþ5±¦®íñ•¢_É™Ìúç쯓X¿!f¡cǾâFvà˜èHý.ºòóªÿJ¬N¥cM…k܉ØüÀ®E³ÆŠäÊ›xÕìý¯oØ?þgM}ÜWØómŸg–ÃÓõv½Ïš?U•ë—¸<)Ö4æì?ú혆¯¡IÇp3û„5íÁ~¿·-×¼¦¯*ú,^OÚ¸t€.m—ÖúMŸgÁ26‘~`»`nhG „íy ½ˆUj²œ|˜õÁpLœÛÑBíPDàåìM±gâŽæD qKr_x¶g öK–«Úò툳rÉ€ƒ-±RÎÿ`–pø¦\ìh*<ˆ€Œ€Ù?ï•ëÚ¾ÛÆš<–š|ã6Ù€v‡ òEð(Ò g…c’VÚ2ì‰êB„}ÏlO)ðl*@B÷9dªµÑñmÅåì"ÍõE¦ÿWEcøêå›v·V•^¸±¦L‘S!7k—±ÿÎX^[n:aÚ—¬UmÞZëUFiÃoÙ¥¿iÃ+öY¯+c_(6vj>þh2¾9¯XYûC—Ô€ï ‚oªk”žÁŸ–Å2[íª¤ÉÊ‚5ɪ>3ÏS7†ƒ"ŠïÒ§éèÓ´÷F‡áP„=ˆ6KÚ+Í!½ä>ò=ÇnoÙ…5õ¡¹%xV,uúë…-’f}iîÞ±¯¸a˲b[Uµ&YûÛ Xwm!•xÙÖ|¥9OVʰ‰’Jóld­ÈŸ7MV¬Ú%†¶ÃÝy6Y1bH¸=8ÓKÛX$ X1}÷¼¬¼ŒÂ¶Tãx(UÇ'?¿ó–cĈÉ$K;Õè=~åÑñ눾F%»˜·$&i“ݨËwLY¢Z€ð9Ïk-Ø<©•‰tˆ¢ØPmP ª4PA‹¯Ž…†=˜ÏÁKòYS®¡¹h=Uš®“b¥ªQ)U"Á+4¨ß>@f ²Ú²Þy&QIO 2~‡Çý~¢ƒjv\¿å$°©eRÊÃ×åfCÙghYfuŠ^t`÷Û <‰â»³]¾Åâhx^{púöàÈÞUÁ.j™ìò3<Ýä7Té:+t¨¯UÃÚ}’èÆ¤B~E…‹¶ú7˜kÿKV7IÕ°„ÕªîßïïÆ¬ ïÅbzyž`^ÌëÉX²CK» …–L{Ú¨f].ÈÏ3Lu`óh"ŸŒMÇæÞÂ¦Š´\dhžTÅ«ûHM±¯QåP8 œTz¤Xa+zqÍŸ å z·Pe‘’º—¤c~ikà‘Á©DRW Fy&‡æ=½Õ½Ûg…Ú×Ô°#^S)aÜVª©¨5C½€Íßk…ª‚Óf±1û¢ÕÍ'=yõˆÆCD´‡ùK±ÉŒd¥£Æ 0£§cñê÷¼Ý1`e•­²"ÉwU¶,)s}®Q4Á!oawfì÷o_:d#µÑkY•gbõq„!TñÝòV» <ºÛ(½c°¤iT y³(Л¤ÊôLáóÉ;#8·OY9¤ì01"v±Ý5 uM‘4u^îiráû|Ÿj}hªFÞ'˜¤Š}AJ(»n-¡AÅQX&}qÏÆÒ}åDLðÀšj ³‹¼L“|1ßá1ò4²…›—ð€¾Vê†DºñéÓ4¬ŸPOËÏD¥ñ^è »0rÅÌ>3õHž\±n…úÅ&AMAú¯‚Ð+ÃcÎ?‹…ûÙ¤ ôp×4Ì®*H¯]•É7µ)ÕªõZàÕëyò,öÎ5Ïl@M¨BƒÊmQµ%…¢ˆ9-Œ ©ÔÕC£‹Ž‚„|õ~3‡æŸÍrÌÓ(|ƒÂçeú¯z]Ö ØV0•¾à?z•ª§üqh=¥¾í¾2ånA Czeß:ŸPÀáŽ)l»ÙÈŒæ|Š_><[þ U%zÍ(¼¾§û((ôtI°»—ú°Òèsn•Ðd¥ûmY5»ö0o¨ ~ì„ÇÜ´?{ú^Ì)`f¡öW&g¡o¸Ñ‰>·aB^ê#=ÔZ3ç.²ÍwÞ„ ^ îÎþGûéBjÆ-y½úÎG”“ñïR.íHŒ(} o÷P4ŒJý{§tM~³Bä4ÍaèE}J… ä4Méº)+l?cJ‰BŸ×÷@ÍkÙ!õïöÕá˜0Æi †æ[Kh-¢Ï³[ü°Ò¬,-jI]rÕ–oKÒÕÈ•¿˜ƒZ_6íiü1]Ù”¤òÄlÂçaÆ5Îg£W b[áÀð$ Q¾)Á•Qtã‘n“øYWe‘ÓÄôÒÖ Ïº/Ï\A&âô éàpÇp)'QméÌGºGü’0Jt _Ê*¥s£¶A_ÇpÝ뛃± Ê“)<"6Â/øÙ©à­>â<É©6Ì’úѨÂ👠G?&¹Ûju“7]b$ÆŽj# Ú`å¶=ˆIÇ{D}"åÉãˆý#ö:Ä¡AìƒÎ‰‡ÄZȡͮ2 ´rÉæ;ødM#äÖC+&Û¨?ËB!s…ÎðS2˜ÜH—rtRøHžè!ÉQSëΑÍ>W2P|Îpˆ#÷¥8MIÁƒt4©aº'PÂcœ˜ÓåŠtªêºI ;ÙG0 ÝòŽ¡vå>ÖWJoÇí±º=Vɾ(Ž}U©Ršs”ôÜGjæ¬P‡£_ôHíIÿž‹mà\¨–÷s2sŒÆ¥s­täOÌÑ9ú>ß®“¹j²Ô@£¶’ä9j°Xf+öw´Á&YQ3qέPœ”ŽÁz–bÇéh¶?Ï&ÿE) † endstream endobj 399 0 obj << /Type /Page /Parent 1706 0 R /Resources 408 0 R /Contents 409 0 R /Annots [ 400 0 R 401 0 R 402 0 R 403 0 R 404 0 R 405 0 R 406 0 R 407 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 400 0 obj << /A << /S /GoToR /D [ 0 /XYZ null null null ] /F 410 0 R >> /Type /Annot /Subtype /Link /Rect [ 197 625 331 639 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 401 0 obj << /Dest [ 425 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 145 652 170 666 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 402 0 obj << /Dest [ 425 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 178 652 335 666 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 403 0 obj << /Dest [ 489 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 238 555 246 569 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 404 0 obj << /Dest [ 489 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 458 218 466 232 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 405 0 obj << /Dest [ 425 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 380 97 406 111 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 406 0 obj << /Dest [ 425 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 413 97 534 111 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 407 0 obj << /Dest [ 425 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 89 83 137 97 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 408 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 409 0 obj << /Length 3362 /Filter /FlateDecode >> stream H‰¤WÛŽÛÈE^õyIhÞIå%ðú›¬k³@<Ñ"[w(R!©‘g?$ÿÌCNU7I]Æ»@ŒF¼4«««N:õÝjöbµ „/V›™ø‰²Ìõ2/é2v“Ì Åj?{ñªËDÞñOty={ñî£/¶ÝÌs=Öä³Åpyš}’”³ÝHn5ý’,;ÿ\ýy¶d K‘zî2Á.aæ&žÙ„ l‹®âĘúO€§‹Às~è&ÒËÄúI||ªûžR;°$»²/ßÍÅ?þë,bÜ·x»±,O滹øx*û_t[±‘PªºpK)þÍÿÙ1>>-ðÜ7«×xÆœN'× ]_v´«¦ma[º¸ôpºÜ>Ú±¥7«™/J1 âÄ _„©›e"ñÝ(8c”‰VÏ6³ïVc0BK¼ËhL¡ö("ðrõ3%,² ‹\/29ã«!žiºipPÞÔ7§ \ñ’#;ˆ O9~‚SôNâ¦ò÷ø«>ýÑeØ%rÃ0K¯¶J–)n϶BjìV^2ìå;G&EY‹~‡<í?«ª2»¼x{ƒÂqä<"d Ëßq0ÞÚX ¦6ac”ƒÆ}J%`©oqºrDÁ®Ê—"ß©C¯['r3 .÷º.t!”“RÊi‰ÿ:–ùƒhíºÇ‡ëAo5ÖeR Ç÷äi§zaÌÖÓñéÖ| {¥Õô¥ ¼Ú ¬V™9DˆÅæ ›Ç‹„¾äeC ÌªíËüX©vnÌ,Ì× ß¥#¿žª4Ÿ×+¾SÛVv.¹¡¸s”£?ÁÑH68ž³ ÷[*žÄÚ^‹YÕ:TêÍ?±¡ëQ4B.܉B÷ª¬:œ^‹{‰E) VÈdi>9TTS>®î~-º^:²Ò«M¿¶DéÁtŒåxŒ¥9ÆñÇ -T-ôÄzAî÷eM~¦r ïý²^ÐãHªªR}ÙÔî÷<ðm9Á=ƒ°±Ä2Ø~)ðÿDf⟳ÎG²âR`ü¤ÁEHмà>A=§Õª0„‚ƒrgIä›<6'JÉ›Ÿõä¹éZ•övË¢5‡·gçvÊ@ÿ$M“óö˜—(°MÓrMñÓ#C&§Úæ{û³9VÅŸU;,E‰ûسÎoÚTÙ×ÚÐ|V¨EYê&¿%Ô‚ ¡f³ò†³‚^+Ú@`ŽAŒ ðh')©ͯ ”±4ýß³Ò ‚ }l“B¹LGâÑ–‹æ;]ëÁ$é^Õ[ÍÝo Æ¢4¾E0ÆgUtÛZ(>G' 2®ûµn©u0?5õ#Z ½¸—k¬9ì6m³ß—õñ‹xÐm­«é«{ç×R¶ ®ÄZ0ê½Àv’Š‚¬TC¹¦¶t‰˜˜zätˆÛ錫¶Ðºj¨äQÜ$͹º9Šíc¯žÄšê‹êp&fô‹JZCÜ @ÞTG|ÓŸQ6`køÁ5$fH8#·æAõHñ4‡ºÞðöÀou^š¯‰ÃQX"G?²ô5Ëz–÷ü5D·.ÌSB´¢NËægÔ½{÷kþö£QcGŒŸ7H­Í\w‰˜ÄõÏט` µCƒ(7\Ræ?‹dº°o©øc; Pë†‹í ³Ê¼£ ñ…{U Pè zHðM=$þÕqé5EÝkôÜa†Iy2 Ï3 ÈTŸ¨‹u½s˜†Õ d€§«GEE™oÌCŠ’3 ˜>‚ó~°œÎ8õ呈µ\ñ’†&ƒnnJTФà~šÚ ®!€½kÙ™M¦²Ø¡kÃJÕ[†*ë:Ò ˆŠ¹ÌÍŠÖ"yaäˆ0ŸÙuÞsžc˦§Æ¬~°«ÍbóßšÈK1‚}*{-â7µn¶4§…‘œºóYhÏÙ9¶ßžnß°ü Qc<–ûCÓö ¼ÁQÛêzaƒÅ¦®ÑÔq¬9ËïDíÂ4ÑÐ8VÖèÒ4n¢Û}Ie¢­¶«pJ#£’mTQ> Ó$¥-mð➻ڮI2G,}E0¹â=bŽ\8T‰V¡˜1 F¸m~°ÕZ£éS—ôç^Øø%FS5EV§¨óO+NU¸ç¼€óâQUD“Ž(NÊ,ª:¡—C=ÙÇÆ&cBÞÞ™wˆŸf11þ¸â§¯Ðµ~¬ËGëY oÌ[âÛHL¯šÆ,(ÊR²€J|Vç݆SU Y'¸˜I]“À‰ZÛtš†´3JO4À#‹ïÈ„šl¯¿€Àß×CBÈŠí\¢ëQÊå°Í³cÉ5©INWÄ…ôÄã[¦e+„%®Ó°E 6&4Ÿ¤ÜÙË$çî¨ÏQì¾&§’± $´=®Aú’‘n«düÎÔ·(‹±þÈó«v6JˆaíËM ׳>jìWXõ½ÊwzÕe­K!Î'ŽkeODÓcƒS`¦GX.Éœ¶’aþLŠ™ªª¹Xcè˜ØÅpÄœf:g9Ìr0 äW™OÖ|åYDÓ;[ŠÆÍK꾕uª;@tƒâŽÀs¤»ù!‚^uBk„®»MÕ0Nï˜uØÂ'ÖM_Ò Š(»ž´Õ bªßµÍq»ã™êkóÑmƒ"MIrMAh`Íj­rffJÍ…V¬¡Ô( ­Þ7ô>"b!é((xÉŠª¯Ì1g™7Ú”σšíaðãfß°D\\×qm”GÞ@eÊL1eÕ ¾ôå8;v½}²wXkŽ+jòCÃÿ¯šÞ´ zï¯Xq2 m€£E·*-UœrHÁØXÂ6²q€þüÞ¾™gc¤í%d¿fÆ»oÞ¼©›¬ 3>ÝùË}MóYpÍò2 ‘Bd,Å&‘Jž™4A]Ì7Q¸FEQZÅ‹Í"d¬"냳™§cÙØvWU]î_0ï˜u…‡¢°Èm!•¶žº¤¡údwT¥$…p ¨/×f/2VØÂœ¯ˆq 8³¦<êØåh‚­#çÑ~r=%ô;gÜÒ·½·Üà(\ãî¹½Ø|ŽWrV·àգݡãrf8gŽØ–áÒ¬Ù­C:r͈û›}ÖÂÊ¿¤°¥‘–ñ¬öyþÏñ+§pÃYPV•×­ZpCÂyöA•Ò=ál§.Ç5>eaMPPžQd•" ©î¢í®\JEÆŒJ½ZhÖYó~‡†ÀåùÀf> endobj 411 0 obj << /Type /Page /Parent 1706 0 R /Resources 423 0 R /Contents 424 0 R /Annots [ 412 0 R 413 0 R 414 0 R 415 0 R 416 0 R 417 0 R 418 0 R 419 0 R 420 0 R 421 0 R 422 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 412 0 obj << /Dest [ 489 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 350 610 358 624 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 413 0 obj << /Dest [ 595 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 201 542 231 556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 414 0 obj << /Dest [ 974 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 331 517 358 531 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 415 0 obj << /Dest [ 595 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 89 501 120 515 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 416 0 obj << /Dest [ 1150 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 391 462 432 476 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 417 0 obj << /Dest [ 1174 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 260 379 309 393 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 418 0 obj << /Dest [ 817 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 233 352 263 366 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 419 0 obj << /Dest [ 795 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 446 339 475 353 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 420 0 obj << /Dest [ 1233 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 307 271 356 285 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 421 0 obj << /Dest [ 576 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 89 217 120 231 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 422 0 obj << /Dest [ 567 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 456 94 478 108 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 423 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 424 0 obj << /Length 3453 /Filter /FlateDecode >> stream H‰ÄWÛrÛÈ­¼ò+¦ô’A–„p#n9[e[–£,;&ìÊÊÊEÄ ÀÂE\úCöòyÈéžH‘²+•r’òÖŠ˜KO_OŸ~ÎãØ®ˆ—×þáOE¶9NÇö$r|¯ç/ëH¤5ŸqDƒó×3WÜ×Çv:“FÝÏíà“|—X#ßä½¢¿ž®/¬¿Å?¦,a*BÇžNðŠÙG?Â<–E¿Æ-êVGžc\ßžH'ó˜íŠf…O* ’dÕâù롸ý§5ã»ÂÞØËÌrdºŠÙ6k¾¨*g!¾LŠ…5šJñÿŸcóÙ4ϱ'øˆ/°Æl·[ÛòmWÖôª¢g!OÚøéÀºÔ,­XÒ«xàŠL ¼ñÄö'®ðC;ŠÄĵƒ@ÀÆ •,/âÞ¾‹#Îcoì]íG eüw X`ØN€íûQ(ôgçÔp<¶CïÀ«nçTxMòlü³BxJܨ­¸TIÓVªÖ®8¿<ÉŠ^²3z I(É“¿cå.n°Ñ8°×:2mg¬wFûÄ9ÌÄ5}C)ÉkDR UÜg…E¹ÉC’åÉãêDÒ’Ç7MŲ¬º:$z¦üÒ®’*+Ûö& ήk[|¨3Ä­±F—žƒ0©.‚€±ÙÅŸaa[7åº[J6›¤ô!d–ðÐÏ𺀇ìB5öQ‘âÉ`*pÞ›ìv}˜/¹2¾¼~û<¾ºá>éË×Z mñ޼ùHç$B1aÞÞêk¼Ç[.Œ(Ü7è¡ü¨Qñèú‡™Y ¬IÇñø$?tº²˜@v~pe¯Œ~׬vn‹O.ZTÂOÞö޼x5»x›soo®9”üõ“þFéî&Ô¾¿²Fg:zÚÿ¼rÃÞ"2 žqyÞITO`T´_ë áwê AŸ'xÞ©J´ üÀ™Ê€= þ ÜG¶w@Ìž2X×r[ÖjˆPÏ4–h<†ìŸ`¹9£—€Ø£. ÄGxy냎="MØõ^/^±ëÞ°ÈW·¨'öë¡4n‘í»GÁ:íïEFzRÖuF¼¦)Ѻk}f’‘¼/ˆ©eÒ‚=0’Öd pžÐvLj£ªQ[×¹zP95ˆ¥ÿÖè¹MR4¯ž¤*§sXšg Wê!CÙQG¬Ñ𬔂LÍ­¼â—CvÜL ½PÈnvƒ6ÀXꕉ¨7*Í–èjè%pW$Í —³1=¾ÿH ¥"õfCC41!²ÍåÒkv”‘ ²áAFîÉžÛ |ÒÒ"bʉnKíåž#¾ì|œ”>¥‘«[(ôÀ”æ"G¶ÜI‘Á´1á±_+°š±NuúÃM•–a:N"½'JS"R <#MÚ&ÕŠP“F꟭™W9æ`?Ô‰üCýyF3ÆÿCœ¾wvÑ{…™h¡óHî2S9‘Ô^ ‘_ÜáˆC¢šÇß÷”}oŽJ½’pÄeg5´¸ײÊ0KÁã>_ˆƒÀ ÷Až”æo˜`ªŽ4âõð :3 *“M¢ E;dÙÓ•®~>2$«Àš —yiîôšÔYÝ”š-NWÉšcJ®í¹^)y2jQÛ„I†ÝhøyªN¬#ŒK0« «®Ó<I‚/òŽÑh½1¤×DO–ë¦"cxkˆb‚_e_HÿæÜuFšÊ=éf¤3ý†ÀØ<°_Åñ¨ Evê’5U$×b`º¹„Ê¡´]c[Z©¤Q"¾¥þËõÕë?ÅŒˆñíÕÅÓ®Ú·/'è¦Ô¼U<±=¼äyƒ3&©Î3~’GAŸQÞSL)¤¶ÙÊO õ]’²wCYtìv]. ù,¾=гNÁ³SB´ÇÑ!:žÅÐg*o©÷yòâ D“ëœÒ¤Ⱦ ùŽRòީŔ ™£‰…¾M$M*+Ò¼](bþ4?8zRí+Fèû>LÝÇ2‹p'å×=£™ž† -øØËŸäGtlî×>÷ëH÷kž9\VgÂõ¡<òl3¤ª—êÉÔ6L{H•íÜì•fšûdzRêEò fÄBYÄÒ"u=©½ƒu逗Â9Ä70r`¾„ŸŒÆÁTË`-ÙÙ¶)¿Côž†Ú¨‡ÚèphŠ04Ñdù£˜™öߘ{Ø4‡ýÖˆrM»YÓãs,áß&É *ïJå Å5Ñt Ï‚ÈT$?sœÀ7‚xЂ龪¦¾çªÙ’w3´[ˆÉšRŒ|¾ÓÁdù-H=7# ÍàÉ?B•SgôskF›ªDïej¸[£§Òg"¸B9ÜÑÏšN‚¹ÁÄ1¥Çviƒ«¹VM-ÐÏ*½ÜˆsEØð˜œ$É'.ÃHî(ýY¤È´†lȲ½_íIÈc (EA¨[2}ã ¦úZ¶i4+ µ -Š ßµ÷ÿWò+\V2[ <ºo-˜<ÑÝ]¨_7¼ÀgtØg!€iò/Ú«¥7m ßû+8®+ˆ‚M8.x1VýR¼IS)RÔB‘B‰Q•ßyÙ˜WNí vgv¼;o¾iñÀST£®yÿF}vþ»Ëü—"$G½c‹AñÄ«¬'pׯI`_›o1ZBb€ykΦù<Ë·UMA ™¸û<ïí½ç/»Íœr¢sË£¬Áf9R‘yxšÆYØ=³Ÿj;áán֥о5¸]IlÏèÓõ„}ÕU‡Â"ÑbÈVvb;ï‹ó$¤¿'!}¿5g¹Üа L³ø  f›Îh4„à†ÝíªjýAwfô™¯^·kìGàÉ5kh´Øbád[ :Óþ$º^¡˶o_¯ú%sc`É`97%3ƒÊî¬n–ÔŒûÌ‚<µd–\ðÏq-!ŠöÛè4ÓTPƒÁ—£,s¾ãÿ@Í$Z±ƒü7P‰ÓÃyÅ<*@©9‰‘U‹W ¹Ç˜?Àh_~¥¢aóùyE$€“ø2ø©çW¾„é§”5qÐ9åH^8ך‹Ä¿¾Ñ?œP/€ÝIRu䎂Y´cÒ Ju h<oY¹‡„àðk·ZW=p:AâF½­=Dˆ—ö'OIퟎNîÁu›¯³ òëæ[_eŽkšÜÞ¡ç T‰Õ•Ý¥Óœ>?R€Q˜}.XǧH2~r¨î¸}f±•¦y†j#%§f¢(Q(´¦w`§:NÊB®‚ÖìW Û  ›¸0Õß »N~R?ks¸3Á»Ôþ)Ó`' ‹TnfãT¶J ¹€€¶€‡¾Ú<£‘!Ô$z=³¼jݰ²”îZøF8Ž3jfÖæ<:âùS¤UJ´@.ç‹]rà ?»7็Új$ꬥÃÐjEÆÊ‘(>¹™÷ O(ÅïVø-}ƒ…e©DNãÄŠ¾l‰cå”݇\ä:‹x ñ·qä´d–øVcËÆYD°×c&€=í‘ÚUC¨ŒýòW€%5.H endstream endobj 425 0 obj << /Type /Page /Parent 1706 0 R /Resources 440 0 R /Contents 441 0 R /Annots [ 426 0 R 427 0 R 428 0 R 429 0 R 430 0 R 431 0 R 432 0 R 433 0 R 434 0 R 435 0 R 436 0 R 437 0 R 438 0 R 439 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 426 0 obj << /Dest [ 817 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 344 742 374 756 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 427 0 obj << /Dest [ 576 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 93 701 123 715 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 428 0 obj << /Dest [ 686 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 182 661 198 675 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 429 0 obj << /Dest [ 691 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 218 661 235 675 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 430 0 obj << /Dest [ 742 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 389 552 424 566 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 431 0 obj << /Dest [ 737 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 93 538 129 552 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 432 0 obj << /Dest [ 604 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 93 525 123 539 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 433 0 obj << /Dest [ 713 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 481 471 511 485 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 434 0 obj << /Dest [ 604 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 449 444 478 458 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 435 0 obj << /Dest [ 469 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 198 349 214 363 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 436 0 obj << /Dest [ 485 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 397 349 413 363 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 437 0 obj << /Dest [ 479 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 459 322 475 336 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 438 0 obj << /Dest [ 485 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 157 254 173 268 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 439 0 obj << /Dest [ 817 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 203 63 232 77 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 440 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 441 0 obj << /Length 3437 /Filter /FlateDecode >> stream H‰´WoÛÈEÿÕ§º,$†”D‘ ÛM¯µ“C¬´i㢠ɕĄ"’’ì||‡~ÇþÑ7³+R²œëáÐàp1µ?fwfÞ¼7ûjÖ{1› ɧټçÉÃø3Ž"׋¼ …ÓÀDÞˆf«Þ‹‹:¢¤–5ÕIÑ{ñúÖ§EÝó\Ïã5Io°ÿÜõ>ªŸbg0rÇj¡ùïP‘?&石?÷¦baJ¡çN'8e¹Ï"†b‹¿‚‰1õï!FCÏø#w¢¼ˆîéö±h–*íÀ’ª³šÎ_÷éÿq~W˜ Ü@eާ’eŸnwYóEW¹©¸HÁTÑWùW.&î‹kCÏàÇìcrƒÝnç:#×W5ŸªùX˜Æ‘.>=x—Ø¡¥Xºšõ|ʨ7 &îhâÓ(t£ˆ&¾;|GTéÞ¼÷jÖcäc‰w.ÔG·œ}ê½øãI¾ö ƒ)çMöªß˜Åc³gZ‡¬•Ù,²f\/03|$ÉŸ¿Øõ«b‰N©vcÄu³^—ˆmˆD4ŽÐ¼¬Èø?QHúIÏu‘Æ-‹F q–­bY6¶;k VA„ÝómÜIaªÐ\†¾R¡wlw««:+ Z•©®élç «Cäâ‘冀>ë›ÄØðˆ8s´7îG­qþdãgÃÈø’¥Øˆ‚“/ü:¾‹ñcž9Hw¤K³ö þ &Xâ`Ú‰àÔÆÌ”il>øfV–î§ vöÁ<‚´¦;%ã>p(ÏEÝ92Ò§‚]ôb`VsÜÝ`0 ¨³ßÆ*Í1²A¤U$fЬ( ³™ì]6I©Ø2à@ -ú“} 4:iê ]èJ*;Äٯܙª|Ú_¤·p)RH}ý’ί¯/ÏÿÎS‘º` …ê-.5TïßÌîÔÓ7ð¸9ÿË•YÔm/ØŸRàò#•RSÒóר/8pãçò­Ö`2±ÓÉÆ|†²X°+ÈøD|‘ ½¤wWïyp¤Þ½ÃP¤®Þ\8!BxeRü¯Ëó™,½2îýÏõoíü³Ïlkáp’•¶6$5X>qý±;ºsÜcŠÀŽñ”P Ã°Íæ¯ ‰Ù° ßЄì0Á‚œ¹¹¦•Ã;LˆöÈYÕu 8®õ© [ŠmA†LN°ù(‘‡Wšú\…ûY®â/¢¼ÿR}Ñ”g« 3.Ù3ózñ;ÍòE³pz¥©(wO"1Ú‹Á Ûf"šg‹Mßçúø(`èð¨ ;*°žnœ×H-g@Ú«øae~.ìèý‡–ÂBwvþ¨x9¶+…*°ÜaF7¨*0 Å…¡¯”"f׆õ%“ãtüZ ñ¢6/¶Ò.õýfAy¹Xd»=Q \8T¤¸ˆŒƒd&z‚ÔÅ4úYMø*)«Q¶cµ,w惚l¥Ígã°(Ä«5+½E/°¤U–ç™ÐÈ$˜Àî(_å›òâÒ+Éã`Êä³5`’8‘Œ×‘ÌÞu¾Û2Þ‚£$gºHPû#•—5’~F’ßèæTm³EÌç¾ÅgÙ°[fÉe’ÍËlå+€¼?mVkÆ è- Ýk·àÈ1Ô…Ê92ÿ,y‘ª<®…9¾`ñ>‡«”by)¢‡ U¦¾ÍŸdùøm$…ÿ'$…-’–t’‘¡ºæ>©à<Ë€ýI\hJm„,ÊÒ§ÐB›x€,¿Ëßvb<ãcîh6ö,Q#­sÔ®u5¨u-É}Ì­¨Ž>ÁÈi«Ì*„ƒ˜%Û;'\µ,݉às €×Þ³ ß›s°2Ø+f°²¯—Fße‘ð€¯8Ö4ß ¡ÊÊÂÌÐíÕL>n ‡SuûÚPÜåû›ŸÄì~ú3‚PšŸïð“;´ó7·×çfèê—j}ð½´þ[e'#ý€6IøIZ¶ŽÐ!ôH}³Ôàhx ‡]­ù]­%e.`›ˆœù3éõÌzÁ RLÊÕJ²gö™›ñ¾ÔŒ ^¸á¤%ej˜U›‰dÂ%ìMŸ€ãTVX2ö5ÎóGª?gë5לž2lCcN£0bZäKöÞ•e0 ‹Ún*7ÍzÓ°?ñ¶Ìر’VP{ª›8ËùE›ê9¿9ÁžÚäÍóUÚ…nâ{ægÑ:Z£a¡2ÿ"ÊÀ4Ä#.×’A3Èâ(!Ŭ/fÜ2°×ú†EcjÁ€&¹o¡Œ¥ †m“qXƒmÞ~¿$Ç¥D—W¯Þ¿¾ýÓÛ¿ý8»º1}?§ŒÖNýõU¨[™N„ßö½?óä¦6ùv¥¸í¤òícÕ <«§m*ì{²H(kôŠå•'2ˆdœÛE‰YTe‚8¶«ŒûBkÏj)J¦owØÍÔów—R¿­ißzÿvmÐMkVLæó*^éFWVñh^rðåu9Êï7YÞ 2+,KLçb’‰ )iÙñ˜†h¡Æ‚{Ú,±àÆÅ#Ç—ƒÅ˜çJ˜´m”@8úwµE Œma{ò$áœyVÎ:°1´êr¥íQpj}ܳZ¬v+Û®ìâ%âûðΪ&Ó©A·‰¿PJ©Ê•ÕŽÕŠ)%g_7µ<Ë0üõr¯¶wŠó‰oF¤˜›Aõº*`Ú:‘A¤!Iî€[BvGÓ`¹7ô¬´>]8N,lõ£ Ìl®ÙÙ­\ æ¶ ¯9¹èÙ Bs +©U}fÒgŸ¦#&€‚qPÓgýhýʳû*®‰sjÎùþO襥¨Eõa±˜&ClñDŠÂ£—ß©½¤ó¼-¹7×ÔÄ‹N PЊ….t•%ô_Ò«`·M ÞûȧEr‘ 1&¹Gê­•’c¥Šàu@5`a¨Ú|}gfplG=ô”ð¼°oßÎÌ›·¨dÛR³ppÉ µ¥ˆŠ…S9ŸºoÜoÒíõxxÝ$ò¾ï*x<ð TY>é]zé~ê¼+l×xÃê¤Ã«ð~´ô¦ja˜Ú+¿ä&º®íÜÛH€4z>…lþNÚ ÔÌ 8™Zvàé“î„dzJM •ÿŽ_À:mL}< °ŸyºjÜhð+<½Ü“ЛÚއl–»j¿·Õé&Ÿ/YcFøŽþãé?O°<ûÜñ÷Ø >Í9©ö)1|7A+: »(I²mà· a i^g˜S²ò«ç¬ T¤‰ì ½*n¸‚h(Ò³Xt!úYzrK¢º(ªã‚( ,tQOßÍp z@33m¨ Ê¿ M .ç·Y¯ü™²ÝÀñÇ.[%{?WóÞ¡äñ·.65ª 3ª9’ÁBçcKýå¦fмÕX`ÙZPØ]oI¼Rô_­‡è–wzÉ]D žBÁiš%îZ´î=‚cèòiúI ê= vÝ¡t’d>T2 k74šÝ;|¨ÌÔÂdh'@¢¬kã7>9Úî06mï¨J'âªÚ~~k›Ûæq=³píYØ…×`Ë0qÿîšÿ ð e4.¸a§dõ ÑèPÚ¡ñ,JWU­Ò{œpÈ߉€<ßFç¡j+¾É,BÁ2çÕ:ÖDbQÚÕˆÍOñ‹©•!–cödŸ‰Í«cÿÃEÿоÛÿïèýלøÔàêW=&¸§ ÖJUq´@ÜR8¯Â-C9´€òÁÚÕþd<õn\zgN—¼J£ä]W‹§®æ-÷²í~/;€ úñÓr #PƒVKßPøÁí?éÙË%Xr 䃃¦;d0tAþ+¯u¯±|(w _È>(¯LW€ÙЂƒ….â¾3CG-ßè€ ê£QÝvAp\ôo ¬ÚYõ¹pë?¾–+^±„™‰¤OÞ^<>ú+À]„WF endstream endobj 442 0 obj << /Type /Page /Parent 1706 0 R /Resources 445 0 R /Contents 446 0 R /Annots [ 443 0 R 444 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 443 0 obj << /Dest [ 1150 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 110 165 152 179 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 444 0 obj << /Dest [ 1150 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 110 151 152 165 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 445 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /F2 1668 0 R /F4 1669 0 R /F5 1671 0 R /TT2 2104 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 446 0 obj << /Length 3329 /Filter /FlateDecode >> stream H‰¬W_Û¸G_ý)X¿”ÖZ‰ÔßÃf\²wH{IŠ‹{ÉŦ½ºÚ’!É»pÞï+ô;ô;ö¡¿!iÉöÊrözX¬Eq8äo~3œ};]O§‚ùlºù‚yøÃ#H×K¼ˆÅièF‰'Ùt=º~U'lVë5«gÅèúû>[Ö#Ïõ–xÇltT{ÄPN=p¼”ä¥ÈsñoTú}ñfÁvå¶b³²XäËm•5yY0ö9«Õœa £X­7+µ_äø8”nÂÍê¬fsµÊT py¬?“®Ç ¨±îjÏåÄw’(?j1ùÖ©ô—ÕŠ­ò)'³+‡öÚ±ûì¶•œX†YóX²r¦×̀ʇ¨rB¼™_»¬˜©ÚÛœ• '@ܱ/e¡ìØü¹j~±ò©Z=³¨t|<´µfe<Õâc» ×8Õjî2#¹×Š=f;(äG»µ‹Y‘Ä b*³KçêpqzóBSJ.@œ2•UŽO€V¹²ÈZå¢là±#Bf {x•­¬s4q…Æ8Ϭ¶Í·fƒl©XV8šˆÝcæÄô¼j§æ,[­K³´Ñ7'²Ù*Ÿô¹Ù]è ãfU4¬Þn6eÕaÍ«K<àfp‚»Ã±]¥²[«¬È‹¥û„)4]øØˆvBx•¢“"tà˜¦dŸÛT 3äj“ÙL ùÜ!w–¬1Gjx<(íáÒ,Ì—yP/–¬É‰ùµÒ!JÌÑŒŽzEáÂßë©Y¶RÈ$¾Ïíq°M­Ï\‚Žß²3»ÏŠ¥AÑ8>aÚ4É7JDZ Á©C &ãÜ·8%æwß¿»£ÓA#t„åæµ½3üÂN§Å|L¡¾ÑšPZåµÞ»¹Õ›™•åšÙY‡™IsN±üF[†²‘˜²!…ë¥m®œ™„iRÕõw¾Y3‘ˆDIdÄ&ôot¸3A¦ãE¶V/ÆÓ7oµMc3Ùì6˜¬› î°S³r —b¶PH5ãëÛ=[¿RT“Li tùT]¢X¸©0ÙÑÀ¢äìQöY”¨tLg䃼üâ4jŇx8Zz‰+‚³úÄíéQê¢þ±gÄàúõ/ˆ;j¤»—ú0#85­WŒ‚wP¿RWPÅ‹BÑÖ/Ž+šZªê8„P:uEé³"HLjßÖQÙÀÄ*·§Ð!] \aÄŸø`Ô†PKƒó<k/ñ€—úõ/ˆÛÓEJùçwˆ58#ׯA|H?Cgäßöw­m8!JѵCOJÇT—ªÚ’禠ŸA+2˶æU™nÉ,¤Jó–ZÊß™²aro~sM0Ò†êƒäè¬Ì^6íš7ʨ!/+Tv’H‚/6ÑgÚà K§ë¼Ø6J_ˆÖry°Ö¹‘‘T=&„cQ+Û6£ÀP[„öé+ ¯•Ù¾d"b:ü¨ä"«·µ<Õ(Ê¡6 ’ýµŒƒC¢Ã\+4’óúôþþu-AȆLÓ÷¸ú0î»È£¬`ëÒÖôÃŽÊ4=¶‡A+9ÛV¶SBÓØ¶‹ã›™-7¶É2ýÎŽQ~Ñ]Ô‹}/H>||ëšNÕuo®Ï(ߎuÁ¥>b… ²bÛMoƒãÅÛ±1íg^nwdõöó¦*9ºs“ì~Ò}âQòŸîÞMÇì·[Ý•Œ){–Úž#Ö Z÷•3 øË„ûÝë—?b¶Ðÿ,‹ù-YšðñÏÎÓ–æ“îMñM ÃyM­št¸XÖ/[‡ª*KµAŽ¢d¦\çîcŒs\ >5¡fÞÆ ÆßØ[³/ ¨õaîË> }>¹B™v_RÇ÷ åÃrCIžn¤eõÕË4ãv~»^Ãʬ)«Ý‹±?~’þà ªábʰV|>Þѿ îNOº*ì?I°gÄ­6¾ZÛ@7UÇÚýbú¦}êÊÉÚ)>uÆ)Æ ÆÇÇn¸ûñÛ÷ïZ'x`§ê { àì•öÃD60½.vó![mÛPAxÛOÝc;èi B´maÆUòN=wF>L_‚¾}3Û]‘Û“¶6ô†=×/ÞkéýÒ °ãŽÎ®;ëdƒ–Ï®7ká%ÃÌž“{<@»=|¯‹þI«y6A…¶ª£eMâÄ6Í—“¦VxýxâDÆ=6ǃ=#¾à”°»ŠÅ=QÕ'êb ÏýâV;ZqÞ˜~ñcdw1à´?O&{× tNN’ý¢¬öC”䢩÷o“É“{ÃÌ÷‹/€GI°+î§iP—ös¥è$&ÿöæÝëvô©%rØiýâV[ ;­_|áÎyÓž™Ì8œ¢ô…wXÿz"Övc¿¸¾´ †Lû.гRFkŽÞ8 B§ŒžúÀš^’ÏSu8¼²÷Ö,Ùo}Å–=†u7éí ZYÓ°ÿ‚¿î²–Qom‚ ñ†Ã±_<P߀Aò)m>2ÔÌFÑ0V™ÿq« ÆÞñK£ÎEtÛO’{F<œµdØ‘ J»¬uÚ}Èh˜­~q«³Õ/¾]j¶‚?¼:È`˜ç~ñ°¢ãy¨:Lß¿~ÿ‡)‡}Ö/nµÅ°ÏúÅ"Ü;“]¿¾8H_g¢KµAúÃNìבöe¢ÿ«6HOçªg‡CýÅÁîúŒêp´ç³«ÃÞŠKåAzÃÙ/)‘ôõåA¤º»¸TD:þgÄ­v2~gÄ­vµâãeií¥TiÅ‘¼=ºW{XÚž8¸Sq¢}F^O§Â~ Í5ðœðÈ…Aê&^|^HÁ7ÙqÅ^®UY“?¨ÕΉù•qÂY¾`»rËæ%+Jǧ©†JÍYs¯ØÔ ]Áß8nŸ¹Œ,/P ÖØ§,0&ÝŠe›Í*Ÿé¹+öë¶ÖZ#8Ó·‰Æw}IŸsQÔ‹ ¸J­Ë¥lKÖ&3¦³˜»>GxPBC]O]É]¡:åHŠV6W‹¼È MÍP©ò ³…ãK7ÀE°K¹Ög!¡,òå!HÑ‚L ¤Gð8U—™OT묅›p¤ˆµ†¾ë2K³>Œì7¬ÑN“ý÷­ äÇ-4$:n <_ƒÈ€«­#aš™›9Ø—ß²¬Ð“sýk,è¸? ³âæ„çF±Y39°×ŽD“¯Š|€ãg’à‘­7Ûfvk昕Ý;>|QnWsöŒÞgÎÄ÷©ÐóK $8Ԭ빬A¤8¸ò1_;§þWyÕô¦ Ñ¿2ÇuE¶‹qª ¥®„DK$‡ˆ‹m°äØ–?Šèéïí›Ý8¤Ú Þ]{fgfß{³°< ÕTÖû§w8»°¯ÙÑ·’w/ž5*k¤(7áh8™\Ðï .¶Œw}Юk .Öìá̈BÝ]Ç.¥¬ÐtÊòœçu,O”š=Oi]dų3¯NG]Ð53æS*k³âùÒbÜJMiz„~OcßÒx«/B´ÆÕhBG[ÒÚõŒ:ûî`ÂIeÆÙu’çÑ–±BšªÊÓ½µÚM ^Ê×—ôSóXlqt¹¦;\©À'ž½˜Ó›^e:gââúøÇÌ××øý­7´~î·†]Ñ;ÿ?Åd÷С›GÇ÷Ւʺð[€ƒYæ¼ë¬j!€§¯ºbo «ŒÕºQØ!–”—[íÌ;e¨ÃÊLʺXGêð ËøM„ ÐÖ‰Ë{Ü{‘™ø_ÌŸ¼†L"ÏðìÞ­¡êac ÿZøcŸøòP‚þÅÿ*Y@\nÙÂR8ˆ¡ú2yLfëY¸F¾ÎÖ+£ÊÎðÂD¼$’—KhT#Ú²„T|Týdù ‘’_ðŽ}г­íèß¾6ùn>ˆ>ôÀs#bS¬„ÉX-f›ùc=ð>¨€×gÛRÓU•ùǃ˜[P#-ÎÌ ÚìM}SqÓ5¦m¥æ¦‹>Y …h×Iö¤°`dÂú„fó|N–éÈäB•cõ«”E>8ä™áõÖÚûYßóÒ£¥×uµíÜ íÒ{`Ì»7СÜ5ÄŽu Æ©ÅJ¾NôÔ7‡&±öÈm7‚¤„à Dcz¿»œÿrÙŒÞ endstream endobj 447 0 obj << /Type /Page /Parent 1706 0 R /Resources 448 0 R /Contents 449 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 448 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /TT2 2104 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 449 0 obj << /Length 909 /Filter /FlateDecode >> stream H‰¤VÝnÓ0¾ÏSœ;l´z¶“8 H]&ÐØ¦Ö å"K³5µÕZV•áxG.8¶»6ëšnšÖÚùŽÏÏwÎçæH{ûZK ¯µ6¦ùÈÛ?é ¸žzœqnlr¯u¿œ{_ÉEF[> Èua¾%¡€~Óï½ÄzH â,QÅ™â.ˆu ­/³ •sõGâÓ–ä´%|¦ár½Åh6Ä'’=‘i9…öÉ|ùK[!îo YHJÊI>܃޼œý*n+ëÄ'Ùh@[ ßöÓ&fË·¥IÎnô1>³ÌçsF}&ÈÔD-LXt!.9V—/ ­§T{Jðd¨˜¯ø‹cP‚`A ·…wåé¾@þ5ÕÜ0‚Yêïµ6a—âÀtIq†ÿî²&¢U/ÌÒ¤¿ÿ|QUP•? c¶2‘ ³;ŠéÄTÄb³ùƹµÉR #!îÜçÒl”Sªƒñ °j覧vÑ6‚h‹¾Ã3ù”¶{݃”#@úà0ßL²¥Oç*w»Òä‘ •döfå~Ùã[Ú®˜ÚäºLéÊ<d³l¶˜4BohKb£á®ƒB’U¶K’$3Hˆ5h&(ú„3ÀИ¹™!ˆcffS@žà²·ÅyB7“jÎAáâÜŒïŠƒÞØVX•£&†žÁØÙ–×å(«6fçúŽª«uÿ­pªLX&¡·Ü̔黬ŠÑM`uã¨è¦=ÚRÜ”ùú~Ñ9ÿpÑî¦}rÜÖéùÙéç>š¶õ;×¢NŸèv÷$ÕìX÷p¥û´O÷VóÌÍÜ ˆ|s9€âÚ(?NÔ xÄäƒãÌ矀×Ñ##\‹"ó<Ø<½62ÜA³ˆY(ÍÍÌuÓ·i7=ë¤uòúôÀHv}Ç¢ou¥Ž7à£5©×YÇ«LÍu7Öuï`}ûù'àUt‰úZñŠ!åÆñy¯Ýf “æþS‰½ÖÖ·Ùc™/åx[Lª •’¼˜_„g+Óð"ù?ålJå‘PV¤9kFMÃÚܯí§w£õȆö&‘4á»U¢p–y°E%[dq°1ÜJE&JcÂͰåÊÁ;ÈÚ~þ x=ªÝ8ÛèjÀ¶¿[Ý¿ô(|3Á#Éë—kíÿ``Äü endstream endobj 450 0 obj << /Type /Page /Parent 1706 0 R /Resources 454 0 R /Contents 455 0 R /Annots [ 451 0 R 452 0 R 453 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 451 0 obj << /Dest [ 686 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 313 228 321 242 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 452 0 obj << /Dest [ 763 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 504 139 511 153 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 453 0 obj << /Dest [ 775 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 299 111 313 125 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 454 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 455 0 obj << /Length 3169 /Filter /FlateDecode >> stream H‰œWË®ÛÈE¶úŠÞ¥ˆ´øIA€ñµgÆ ¶VgA‘-‰¹©!©+k>$ÿÌ"§ªš¤¬+OÃðÍêzœ:uúÕzöb½”¯ÖÛ™¨þá'JSo‘.b•¬–^œ.Bµ>Ì^‡,¼7ë×xÆœÏgÏ =_w´«¡ma[z¸\ ºÜ>Ú³¥7뙯J5 –±ƾ /MUì{Q¤c”ªÖ̶³Wë1¡%‹¯³1¥zA—ëRÁ"[°È[DR3¾ò™D¡—W õ—CB}[›ÐSžœ E@y‚c+ýTš³äá&FãALØÿ¨ÚÁTø@Œ¿­UÓ¦U}£NuÁ áa—yW™êLûdÚ?vX©òª4u뼩·åîÔf}ÙÔs•ÁÁ/'ö}&…Z5[… (Ç_èMÖ•¹ÚœÊª(ëÝPD×÷(Î×peS5ùc§hOÏͱïTYã{|b‘!èà*ÿN™zWÖö­Ý/÷¦:nO•7æç¦‘†irS‡‹èªxgë0¤ ˆrRl¥^q$ð‘ïÉQxòõÿ®HŒrCEx²­×ûoEgÔÑ´Û¦=tHDkÌšSVUuhZCU©LסLÇ å0ªÏºÇî¥ðGë g:ˆ)ÓúòƦ·í3bvp_òEuŸ5>:n„bŸÐ´uMEí%*IL]FT‚HŽmÓ;nŠ›&oP`Ù1lަV¥³Bõj‡¾+N]ß^TGèËÚ‚ÃŒLðÇ–b¦{£2ü¿ÅÑ7pžW&kUw4y¹-sÆ(SÞR~áȦ9õjßœ‡rë7y¬pImŒ*ÇÊІÜäª=ÕØRÉ]~Y^%o5ûªvëPâŒË_¹²x Ax`¤ùˆÂžÛ¸ËŽ$Ö 1šîѤUÓ£Û(Ë©¾jNzÀ´JɯUmLßíº…k§€Åè;bäDÁ3gâÞ±ìíæè¸F«í èÃ¥\ÁÆ'˜{_cÒ Q†h¦çw¢s9•|){Sç S ¨°4aõhXÐÿI0ªÈú YÈzB$fF¾o›ºüÍI¨D JŒq´¿FwÊè°*¬d¬„ú ßw¡M~Fâ'2jª-í] ýw5ê2?ó¾&o€öúB~ý_º¾>"XrÎkžòý¯Žmiú¬½ÌUô6Óº…Ù–lþr4…ìúOâ—?ùe÷ss6 ô9ysÈ…ų!‘¦.Š)2¦éÖîMËI‰ác›m*@·ì¥ºÓñØ´ø%œ„AØ:˜©ß¯ÒüNÚ(lȺ)² 5GI#¯…HŸM.Ù¹, ¸òÔ!rIÐ!ª¢u .V(/,Ê¿¥šºÏrŠw’þƒ- yÐ1–îÕÕŸØq˜ÛOYe \P±È&€ê{ôç?(+ìÆÃ#¤ºFkÅZø.£ËGôgUÒ¿™+™Çõé°1ö³FL)æ?Bö¤úá³>;i¨ ›±Z(s 9gÊjraòáàðKñâž‹úð¶<îŸkôŒ}Ôqâ¼i¾QÝ#}űÅ)Ǩ\PÆ.®»Â„¨›Kœ›/¸¨]ùtøÓðí (œ:‡Ô¦¥_ÔšøÁjKɦàœ,9Â20mKZªtXDVÌ©bP}Ö—æ¤rŒ3ôŒ áÖCÏØm©¡Ýè µüh¤}˜ŠÈÖ³N¸"{d¦2«ê¸o°‘€B„-¡ë&$omgt4¿¸-Ý"³r¿e©ùÒv<A˜E)ªÌáÞ¦÷õà U"Ø¡×Ð-Ç Ùr‘N_CÈa‡¹zÿöýW„n{/õ~ëPâÅë· 4Å¿¡„3eyPZ‰~6dì2ÜI¢L E?&å€úÑøpå“ðÆãgñ„•cçù¡’&©àÜ#kyL ,C˜fª¡Bcº¿-^X€ô°l²®ˆº³~øžzššŸ|lÎ,Ù\ccÇÌ>?ø;üã¶"˘´‡koÆçžºžMhŽÐ9èhnCÂÑÒàQ¿žèÌU¢IØ-i™/ìõ¦´¾º$œäœiÀÕ¡±[cd‘0¿O«1ó+‰ ;«2ÏÆGš'Gio”ý=m¡âJ™0Ü2Íðz…Dd¹Û÷$7±CÆ×E¹½(Æÿ R“¼2ÃåØÚ…O%é#k‹òE;JN*‘ HàwÓö\›5tP4æŠüÃëWîFúÃÇ*‘®ue)ÈÉà%ìúÒ*ºÑ<$•æí½Ü'–oÍK^Äß9*'}ç^ <1MÒæ¡d “¤òòVfÆ^\«Ìt-©XûÉÔ8åÓ-µÚUÍ&«F‘ø5ì°b99LI lRç8JtQ…1*ýì(¹9ña›Éýàã(*€5FQq•ÍïÌY2å,±ÒLý¹0›Ó µÔἚrfmÓŽÜN]QAÑV<ŸÿÛ{¹ô$ DQxï¯`ÙnJ 1®t­1îdÓ H`jZÐøï=çÞÛÒ¸@ã®03ÍÜG¿{OèhvwXÏ×À›ÊUžïF3Œÿ2–þ,G,¥+¶¨‘_#”F"º‚Õ±Þ¦ÃúHy 7ãtr±ö©+òuË=f>¤ïÓ³òñ‚lN¡ÝdB¡Ðm‘ØÏÀ•ÁŸÁ‚ǰBÁ’z—ÉÃ]E ËDŸ<…ƒÂK¨Ã*o]æ[”A¬H±iõ‡!eøü .ìÃ^bËí¼Š±³/T*® yË0ä‡jƒoÒ ÔϹVk_<ªŸ,ùBQ¥jT¶ÔÓ½¦iƒ%Ѭ¾5\g‘R=Ä¢xù’\T'oÇf “I£Â}4s¨¤t0xC16îmÍ¥^¦Oê\˜HÖ ì¶Î , ÎÙ1äQ 5SHÍÙ»RŒ(ašÿ…è§G±ê<­¿G oÑÑ|ˆGµ:’ã÷æëìóWt·.QuuÍ+ÁÜÆH½.Ò–!-\€XB]77Tmñ–s’*å‘®@qÒ§:;ù}ûv³ÿà3:¿ýqwØÂÇ nExïpÛš†ÿªê%%bÉÆÁ=€.QáÇ"{‡àG¾ãè$„˜ªH?‹?¥qÆ’xqŽsIúË~ x#ɶ¬Ô`Š$Õ60·¨ö…=|é¾’u<¼Ü|ô¢± endstream endobj 456 0 obj << /Type /Page /Parent 1706 0 R /Resources 461 0 R /Contents 462 0 R /Annots [ 457 0 R 458 0 R 459 0 R 460 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 457 0 obj << /Dest [ 931 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 428 673 442 687 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 458 0 obj << /Dest [ 1297 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 463 673 476 687 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 459 0 obj << /Dest [ 931 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 424 658 438 672 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 460 0 obj << /Dest [ 1297 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 458 658 472 672 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 461 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 462 0 obj << /Length 3017 /Filter /FlateDecode >> stream H‰¬WÙŽÛÈE^õ¿¤4ÙÜIx‡ƒ12ë)ã `K¥3\4"ÕrçCòùÇ<äÜ{‹¢¶¶Ñ@‹dUÝåÜíÔËÙäz6 U fËI*ø‰óÜós?UÙ4ñÒÜÔ¬ž\¿êr5ïx¯ºy3¹~÷1P÷ÝÄ÷|ŸöÌ'îð¸›ü¢*7òb}oè7Ô*È•óÙ_&S–0U™ïMSh‰r/õE Y=%©ˆúoˆ¯nè;ny©ösu÷¨>>6ý _BmHÒ]Ù©ï®Ôßÿç¸ Þ7XK¼D—ޝç«+õqWöÿ6›Š…DºhŽ;Õê?üŸ c÷ÙµÐ÷R¼Ì^ã[°Ûí<'òÝ‘VCj!*=<úðnn?­XÒ›Ù$P¥š„IêEi ¢ÌËs•^+øçjc&ËÉËÙŒ(ÀÿjŸ•³M®ßžÅ áb ³dJqã³ú²9–ÍÐi²Rư{~l]âA°#=’ëmcT»qb¯êmÕ—ëʨ›º¬ÍZ¾¶üÒKÀ3Õeen ½NÜôæsi#bèÊ èg:'ñrmæ}Ù6ò|¥v«r¾R 'hã†'§aÎëBÕÅz]6÷C]ìö…£G¡xtgú1*›Þe™n`Y¢ 'ÃÿÊ¡xª¥³¤Wµ ‹%EC¶$z¡ µ(ú‚7µ|VäÔNˆE¯î 9ÂVG8Ð6lëÞök¡}~C;í¯L¿v\¤]ÿ™ê&×ê“Y[€aŪ‡W…h\Hl2þT¹„þSŸcªM³(6ŸUëª(EA"=¢B™º(+ZmÚÞtŸï8ó =!af+d.eò;sîBïœ;H7B»\Sº¤5.·¶­t6iöùb–åؘRiÒÆ~[TµA¼ÒQ¸ ÇhY"Úª*»¾;Ë&w4öÐVd»úðþÃ÷õûŸÉhÆrMmIAâÛ%ª¢óDžgDî`D÷÷Öq:f½m¢ÀˆÈ倛c‚z@~㓼Àýêñ92ûÆî´{ìï­Tƒ˜ßøvä¡ÔLŠÒ”} ÍR‡¥¹µtêE‰˜*f¤ôĦTb 7ÐÍ£jr©$(`Ú>ïÅZpâËLêMÆ(|’ZŽQ@AˆRaû 3o:å(¤ß'ǧcŽOÅœyU𦷍K»Á7g:´  ØßRzŒX÷µ¿#¼‘æÝE€s/Ïö÷ûÙ^7U@Š fD9”CmŸOQN —oDù`ÆÎô;¶’ Íþ¨K«|p\ž:¶qRK0ž3š7öÈÆ x·Ýw+"öýöFÎÈè" ¾JEP4çmÓ£µÚ~½¢™>éj²¡·‹˜„‡X<úåì&=ÛÄ0Å04cq;ÐT™!Wf¬9Ù°bÙ|,ÄE+ZvxjƯ+‡Ù:ßK+¡_7¼Añ¬Ÿêö¡\kÚ˜¹}•ÿ…ŒsÙüh9Éãpêeñy£àüØ|dƒ+µ¤æaf–ͲÝÔµ@s &ÀÝšØdN‘bÐ`\ð8àJH‰ðòÆ¡ÒlkÕÓ{ª÷§ö³Cö÷Ìv8»€Å^1Ðæ…xm·Û Ueø!ÖÕò¤£ÈKòÓ”PdN»²ã˜dcÿ±=à­ ''à „¦¿¾~‰|Œõ+Ø -‹±i”£†×²µ%μ@d %½ìÁñÒ>•ͼÚRôù­¨*õño?B[¢•|ë-M25 ÈnkŒY`÷­Vg±¸Ru»(—|þQ>^],,?BÞ™MÏ1X˜ÊôFwÛNí‰S! ¢1Ÿ‘Kö”Õ$º-Ü¡\‹®+ïZƒ;nSÔÔ}Û“dQ—Ø…6ÉǹQzÔ?ÅcàÈ–N~£ÑH†ð2!Š÷ÃÅ‚~`õ‹ŸÞ[¢L•×ÿ©S,ÒSoA”îÚ~E\ 0rýµKq ½Ð€Í•õºÝôEÓKµØMé{¸Ô¡Î~=|°‹mùÞ¶\l;˜sѾÎWŦ˜u°Xënd- ÊB$ÃiÄÞ4ü⮈©‚>ŽKÙX;¸šžªN½8ú—€õ2Ë je6攳ãJ›}OÒ~^lG„æ˜ÁƒÔÄC¡a¾>6óùmk:á7<Â8áÎünUôÄòyB£ï2ݪÝ"MïÌÅŠóGþëüZÍ®DÖPËìr·2 IžJ±YP6LÄøîRàiQBk_lzHù¤q5RÅîIÅ]Å[ilp³ãéÏV¤AOGò=ê˜ÿ|ç‹T2: LšÝ<¤8íšœ)Èh4䛩qÉÛl+s‹“a®ù(üÃxœLgôÃé|~3êÖf^¢·ˆÆŽ’ÈÏ͆{9±#{'Q'}å¬X¨U(4 ²Ù€~þQý TõGº`’ yhË9ÜßyˆÉV€;Ê!€çYCô'AK 4¨?¢AGÇߤ¯â·!sônÚƒFWUj+kȸiŸ%™È{・‘ÅM‹ë©y(çÆTĸã´ÎG¹£ ÆËrŽBXe»ÝX`SËŽÇ“›æ×çÓŒÛþŠÇƒ¥®©^Ø©A.I©RјÊNašÓ¸X¯M1næÚj›¥ð”¹Æ ¦ê¢F U†Ä0šÔ¶©ìÒ TÙ(,Û<ˆ"ÐŒ¬2N]äÓÑè°MV„B¨mÀÔ6jKÔš=(`ÝŠ-ƒÈnO»5:O"âòNÀŒ…> ŸÏ‰ÏÛ²,Ô¢À¾­4sšÔ7ÖL`⑾%iWÊŠ“+ÿªl÷Ùˆ±Úë²v˜¤šµ`(td-ôVPÆuÎeÎ"HÆü˜©ù5¿ DauÊz{He޲çÎ=$FtײôèkI ÿ­ÞQ«ûRúþ˜À”ºÀÁSï “ÇÆl¨Ú¯Ž¹$ZÔ¼­kìp,H(¢D)WTI êÇj·}ÅÚFZ¦ïÚƒ\¢F]T]‹sæ2—¼Àä­}B¤‰°êš®—öÊÒ'‡y·'ÿ /÷ˆ3Öñ‹~Ѩg¦^÷ÏX· CÊ nÐNÃ,PUÛþ*»„ºÙ„á *lϦÜCÆì†É.J"È®1j7Ê|¦ÑªÖ=ô”Gí +²¸\õc|ßQŒÑgï¼¢8·Q—o”“ˆl±Pö¢»¯K7ö˜\cìï­å•v‘Å}ržŸ‡óñë·Á0Ö…$´ Fþð¹®@}_[.ñçg˜üÏäÓ·,÷Íl’GžŸ*Š}/ïôb\ùÿÆL–__MÒýjLùh=ñs/ŒŸ<þ•åÝDXx5à¡vúÒúËÙ$ "í+üä¸ ¤ÏêÊÏ©Pk¨{$‚÷OI» `¡¢$Uäü‰)——‡ÃH„üK§ŸX?r$ðq³$OÂ<#—"òDß,ÌÝöþ–òa46œBnþ´¾§Öõ™—±¾,öb_ô¹?º®àÅšåÑR6yqÝSðÂ<ö²pÔ—ž¤ÁSëOøŸ‚Ú‡ƒÿ×È‚ƒÌ¸ÀëÃñ$£•§?±þ„½<ñë7EÓÑ]UÐú?ãUƒ ÿâÉ“iK-4ÑÇÖÄDC"1áùniZ:o’aé0Ã:»>¯‡išvŸœÒÕ¼BÕ\”–îÞ»˜Ñy»gK˶V‚ˆ02È$Œÿ±ØºòÊ­¥9×pÞ|)§ã¤bÊ^æ,kKUk+ÆakÌ(ËÆúç@#^6Rš3Ý]jGZ»‰aÃ=DkûÖ ›²¦Y‡á@™³Š«]hR$Q§Š±áK¹nHFY€Îcõ¦ìèæ0éÒáÖõ»6••æÜ¥(PÅ?[ànÊҫܵ£ Wm߻ۭä½%Ú/KgiÂÖ!\ÉíÀ)·ZøØbx,·: ØÜè2šq5k-Ö8;^Þî5Ð ùyºŒ®1'8˜ ÌD3†¢b) Æ3‘D¤öÖü”ø+Àšy˜] endstream endobj 463 0 obj << /Type /Page /Parent 1706 0 R /Resources 464 0 R /Contents 465 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 464 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 465 0 obj << /Length 2585 /Filter /FlateDecode >> stream H‰¼WÛŽãÆE^õ½óÔ F’¢$j±`ìx ë À°‘Ý è¡ZR{)R&©ÑÈ’È?æ!§ªZ¢¤Ñìzí  ’}©{ªújÚ»™N«é¼'*Â4ËÂ(‹Fj<†£,¨éªwóu“©¼á3‘jò²wóí}¬M/ £ˆÎä½þþuÛ{¯ÿf‚þ LõÂÒ3Ñ*ž¨àÓ¿ô&La¢ÆQ8Ë G‘0a Ó¢·áHHý;Áj?‰‚~<G:ÊÔÃNÝïÊv‰•DÛ”tãu÷íµúû‚þß5ö†áP» ÒùòZÝo]û‹­ &2Цœý‰VÿâŒÕgÕ’(ácúg¬±Ûí6 a¬âj‰-Hƒeˆ×Úå~iÉ”¾™öbåT/ŽÂÁ(Vƒq˜ej‡iª cš©Úö潯¦c b‰N­Ñ™:"‹@ÊéO½›·ñ¹¿bÜ“%ÇÃI8Häò{ýæU¿ôAL7k›;SÈG½)¬¼Í«ÚïW+¿4³.÷ïýþí^™l€€ˆÕxã©X#5>»;vÓ$EHï£,LÒ¯fûÀ›=Æ›18¤ç—/nÃþGVŒlÅQŸŠõ››Ú®ªÖ’ÕnÉþGÖ"ÌTIË3¦/ìﯧI˜~âöåí‘‘§œAã8 ‡ÉAâf‡(Íÿ™WåÜ-Î…†úÉ‹V|i“È›ŸðßÅËŸÞÝóM²0K?á¾ö¿ºŒ_{`ã©Ï%Iž×Cœ Ä¾Äjŵ~°ªÒ0Ó6¯V+[ÎT[©MŒ´U€›8é¾oð^­ «ÈÔ¸k·Pþ«AiCG•ám€°ú­+j]¹²½V67Öó¸é¿ÔÏ×#â÷´Ç+Òf°×&J; NE›µ©ÛF}ÐÖ#@±S3Óš–ô˜ès¬×"éÌÎ]éZW•͇@m—._‚»UKˆ€œè`6Õd¼¶ÂÌëjxªM›/Cõ]©V¦Ü)³^.F¸a˜Úõ±´í;Ó‹¬«jf›`ŽÙNC­°àæÝL \ˆñ’¡ ú^Ë ˜[UÉI²Ÿ’CìŸLüãÉžrþ) JˆÈ¡#ŽÎ–­‚J[¸b¨Í.Er©¹4„¥#•†ƒA6Vò¹¾Šð¤«kñ¡®Å^eH#>~üþz0C}ݳx1ª‡“A8öÉξvn Ý)ÔJPŠ"ŽÁMÍTsŠLÖ%`eÚÖΔ+IˆkïwL¨¼É!£Z³XàLkŸZ%Tw°<Ñßɲ¹¶ªj®ì_ ÎøÈß^û¼ØÌ( ~p嬢ˆLõVrŠ×î® ,4Ð3„dnJd %#íZÎLb Áý. 0egOöÎÎ4*4hõ¾bޱ™Í8Ô¯÷ G¹gö/Ç Ú퟇ð{m¶‡ólÊ!±¯zü—’Ï5sçTt¿@ƒêÙm=ÖjÊ_•ˆþèìv~Ø´ª¬Äð0Î)¥3¨ùŠÜ—e¡#|VHµXK\Ä”Q\¾Cã„*ªš4`ûÁC1IB¬ÙK-ªZÛäÑ~PØL[û êjÛØZî£Uo]mçÕSø)8eˆñ1€wâ%xÉÀ |8ÿ©Y,ÉHjáá_T Ù*ïm]Í69ç‰2‘`Æ0,½1øý´ij“ƒŽÜn`9(jªMË÷PmŸÅ‹4t­y¢TË 9‘ ¥vÕFªX’¼sD½^¹Â™Zì†(7PwF–ëÝëçÞ:³ÔÍ[ |&ÑýÙñð8÷]®¿Ò¡ŽàÚ^I§ÇDô¸+%âRŽ8Bd³  !µFÚÉ£T¦]é˜Gš¢Ì‹Jî˜rQo/ ¦iòX‹y@GNs¨xÅ]0I_´Â›véšÛSàX:¡ÃÃÁo4‡&C×F­82Š­Ù5Tò,<]ÖÆÕÍkuÚ©w2zèѨëÆK¹vÛ•ò|°íÖÚòÍÈ/ÚþÏx¡bPÙ¼:Dš°ù€Š,!ýÕ×—ƒSŒ|ÀýŠ`”µ'\†}~µŸöÖÀ¿io»I„(“ °øS$¿ÃÊÒqø¤~ÁjfÏÈý­ §£&îK#r¯Í‰TÓ?^nФ©¸É!žC_ŽÙÔòÍøpԀ稊4*¦Š·÷¢õëW(tWújqp³¬(o[´:Ò }® m¼«Íð±|ç‘ Ò@;CõÂÈ…sýI•3o^JÃß㺠í$_šGß~·mí€èö‹R¢ðpÿOW¦ØØ+¿\rÀûÅäêö¬k{Éw ÇædšŠoûVtµ9i~Yd ~8€æØƒæ¬Ú<ÜrFâ½ÿ¼A’Sû®çb]êäÚ †æý~WB§Æ5ô–«{[?"¥©–Ž4w×|RÇvå2YÍ@GÛTT«R(Ä3âëZ5•ôV¿r|‘ÎÕã­[,[UTÕGª X?+‡gþŒ½Ûâ«n-9¸òæÜ—B4}qnù ©38<Š€Ç>z%CñI4i/!X|¿ËžO³\£3ÔhISz.šG]ÉÓ&…N¢ý<ÊÃ)¿ ¾-î?ïökÆX¦ÇNóªÏh%ÿŠúD¨ÝíïÞ ë/IÊWý¾¯ o¼*/¤|ôûÿ¯‚ñ6 >óbWMæœU‡.[~&ø íSn×í…¾\W_lØ x@L_ûs­“…s ¼©uÄè#ÅÌøt8Xm0á±mÎÌý^¯üøaeS'_ff0;n—2«!áK{R y–E‡J!sTS(ö“F=¬ Gèë´vHžŒ\I´VëBWdû‰†mPÈU{<,îñN4­žUï3°ú¥/À¡-IUš0«¢Åœ2›¶‚ÿ\ŽDÚQ׳4@ǦѢĘƒYB ¯TsìºÖÏ3ˆ%eS9˜Òp0ÈÆJ>ǘ•F˜®ââ¦\±òÒdÿG³× LƒŒÌ{¬¿æÒö<èSnÂl ù s'FιƒRóȲi Ÿ\Xuw€Ï?<örM&a”‰XöNǧïàžÖ÷SRžç>ñ+ê§Ù‰þž‡§w|\9r#O©l^5^!“ùÔ}ПÀƒœ,dUN~)0ÍRRNôeG¬l¨¥V…ªìši@x-¨ÀbŸÖæQ—">ÛÚ`>ŽíÒIÓ1Ðk“ƒ ÏÌ û—–UmWÕ#t™c8âdÆ]Qø© ³ö=¸Båžè5¨«BåKS{ÀPOû ö7ÓÞ=̨; endstream endobj 466 0 obj << /Type /Page /Parent 1706 0 R /Resources 467 0 R /Contents 468 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 467 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 468 0 obj << /Length 1382 /Filter /FlateDecode >> stream H‰¤VÍrÛ6ž^õ;ºœ±hðŸÌÍv›L;IÚ©yÈÔê"a‰ Eª"iÅ}¾Cß±‡î$ʉã:“ °Xì·ß· ]ç³Ë<÷Áƒü~æù ñ_ašº:Õ1$Y䯩 ßÎ.oúÊžm4ôe;»|sëÁºŸiWk²)g‹ãð0»S?Î"pCµ6ôöøœßòg{È Ñnã)AêÆZa>û¢Q‹«¿}œ]øÚYx+ÂênÛaƒ3¾2zR}ÝÃÕ› øõgá÷×"7Rµ£U¹¹€ÛC=üiö ; TÑVÎ"Sð?90†ÏÐ|íÆø‘‡sÁáppÀõTO§:]ã‘.5¢+íÔ†=}ŸÏ<¨aæG±Ä‰›¦{nb SØ›Ùýì:?%#ðÐD?ÍÆ”jMÁ(óßÏhòt, Lbíâ¿ìÁ´yበRüMÝ0mÕ;1‚€b";;y#_¦ráÖA\¡êÏM6¦…{\õíŒXnmŠa¨Û5`^àƒ“¡É;^|Ëæ ®e×(ÛJm]šæñ¶ÅGƒ&ÙŒhãYϘbŸ"}ìF¨ºöÛáHÑm|f†´æM²ó©ZíMñúaõP·CÛ±©wÊAQô›nl*XèZY€¥êÇrEU½7åÐíaW ›~鸜øË×¶P0‚ˆÂð+RT¢¾³PÌ0{VCBVZj+ÍÕ¡¬HäÑQï4B?7‹[ŽŠf4ý+»Û»qfµIGבp 9fÜG%zn*Ìb‰@Á 0½‘2 ³ƒ#ßX"(]LÏJŠ 1ÜñÛ:©0UX.h‹¤Õ-3~CŠT·¦gA¬ùj»¥èRÐi®]ÅÕ0µ(A{Óº`PDmp6uÏvÒŸ()VMÓЃzWå0ˆ'*Q9à$x:© ³õºí츺€Õ8pðŸ{¬)äcÊ›*‹§JÔè«?FÓ:—¼eÑÂJf¬ Œl_ ïsÅÞ©ºµ…&ê©XDÙ±Nv\'¦¬R¹±uZ”ƒ-M[¿5‡‘(<„`Ȭø;b4D¯$ˆI{Gñ†ÉI~8Ix¹à©ÜB7<“›o5VSO']XÌ(V¡ŠA·ë­$E–÷‰Iϯ¸9êJZÚˆ]Þ;ž Å«ƒlÿ ‡†X’lÂ⟰Ü!¼RÌÃi糘¾¸»Þ$‰9DÆ 7¿0LÅgõüB vÄ™máÅÔ>#øšEv¦(ÖÏQj"gb=EµÃ[Öòk¼¥ð“n%µä¶/7¦Z:GE¥¤(Ç£O|}=Ãé)Jï\,Ÿ>|x“?aòO˜èv&TôžpEÇ®p4 #K ÜÆœ*ç7Åu¬@ªú«Û›Ð…¯ä¹À4$ªì*ìð˜èË6æSQQñøTdÛ¢áö>ê©ÿ話j+ú÷Ý`¤9RL]9`Þwû-,—ýÖa¢ê¦X5¶?R?¡ösƒÝ0ãfHÜ Ñ¢‡÷?åл]·L%­QhÂ÷5.ÒçÄŽ\,—/R¡³ OvFEl©ˆŸPaE&E 2SS`àVTX©ôöT•Å¢‹B¾6Ç‚!¥…'‡6ÝÓuzeÿû>et“æ´”Þu×5uòµë48ëo§½V®0tRd…ïÑDÍ/`Žx¾Yè×å(ýšæ»Ÿ¤Å¹7ç7߆ë—lØOå`û»çjë{sÏtÎ|ôÖväS,‹æè‚ÒÄA 3ßzyÎÉ"Qh çÓÕüçÕz*éàü^´­A¦˜ðP5lg™Ä»ÿ­òò endstream endobj 469 0 obj << /Type /Page /Parent 1707 0 R /Resources 477 0 R /Contents 478 0 R /Annots [ 470 0 R 471 0 R 472 0 R 473 0 R 474 0 R 475 0 R 476 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 470 0 obj << /Dest [ 479 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 179 571 196 585 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 471 0 obj << /Dest [ 697 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 288 499 304 513 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 472 0 obj << /Dest [ 479 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 329 457 346 471 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 473 0 obj << /Dest [ 479 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 227 280 242 294 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 474 0 obj << /Dest [ 697 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 278 239 294 253 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 475 0 obj << /Dest [ 479 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 199 185 215 199 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 476 0 obj << /Dest [ 485 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 419 104 436 118 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 477 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 478 0 obj << /Length 2942 /Filter /FlateDecode >> stream H‰¬WÛŽãÆE^õAšÁˆË›Hjðîf ;¶a` ÈN8TKbL‘II;û!ûþG?äTUó2Ò |Áb€Ùì®®ë©SoV³W«U |µÚÌü@yøÃO”¦®—z±J– 7N½P­ö³WoÛTå-ïñT›W³WßÜùjÛÎ<×óhO>›÷çÙýSæÌC7Ò[C¿V¯œÿ®¾›-YÂR%ž»ŒqK˜º±'—°€€eÑÓ"Q¿Xž3÷C7Ö^ªÕÝcÕí°hã@’n‹V}ýÍ­úϯÎ|÷ßîBާóÝ­º;Ý'Ó”,$ÔYµvæK­>óVŒÍgÓÏñ²z‡5Öà|>»Nèúº¥[ ] ѸÒÅ£ër»´cIÿXÍ|U¨Y°ˆÝ0öU˜¸iªbß"£T5f¶™½Y Î}lñžzctµG–«ÿQÀ"°Èõ"‰?õþL¢ÐM‚‰C= Ž/öD®z[W›ÂIaÓöH¾Âý:sðêÎÁæDË׺R'‡m˲´)Ø»øµ4­"_¦8®òš«uÑu•ñK‰ÕŠŸ6Å–"çâN0<—’ƒmAL©É¶ù£{`™ FÒãy¦4gUT Q{ÍžÝÁ?Cxó>Æìø"#UD5Ôê”ÁÜØèàŒV÷ºn”<ïê¦S7½Â~¯1R+´¢¥è)µ© -PtÄ *Nxà„y€åÆ¡üFÆâ™®uJì ¯Dî2•+&Ö~Ð7÷ŽÊ]j£2 |¨ ûù9§K|”K‚=‡–:x¨“Cõú˜›µB•ì$ó táé¹ïúaoJoH¥TîE9©ó¾W¦Ú|]„û൮VYYÖguÈšloº¦øÔoÙ›T¤µCo{‡—G#k¬ ˜)Ž#Ÿ©MQ~ß4õ^ÝÐåõ±“ÅÚÜô•LZƒÖɨub ²qPUƬ‹jK:â¡S€š«éuËÄ$ôÆUÿ’:™ÃªÄæ|©ìæœ^åY±=Dbo)/*Éú‰ò£Ë/«W³RyV©£Ž-b¶AV®‹ÍÆ4¦êTkºã¡% º¦.K|ZæÓäÓÚ}S"¤qš\K `ñ¢)° H=⊵º«Mh€jðOB•TrÞ!ºªÞ(Š˜ÜÁË[ ô –úm ˆýØ ,ŒMcè¤ËÊA•¢‚bmx9¥²è6ø´ñ×£,"ÉÓè¥aï<¡ ¥¨Ñ²Q7œx“> ‚r’ס†D˯­ï{Ü6ˆŸâŽþ Gའ*ßvžî‡ó™YƬð­ïß3xP1ǵÁ¥q0òÎød‘°¦:vWµ§„ù,6 .¢OC%ú웲ø™œ"R”|²ùQ@K^:ñôEÞíd‰Šêdå¦Á‰GûåPfÝü2Û?hº!e0Ù…Þ;æëF¬uUÈ.îëH{Ù‡r«å©0²`M½ÞÓ¤zgö‡aï-µ7ˆÍ‡² òEkã²XS’\Ù§L—»@U+XÕp“}`*ß°•å³U‰Ü³Ðp0ºú›nLTß&*œÂ9‘g* $Tç%ƒ:ŒàöˆóÏ·ÑŦ —ÒŽîÞq/ÒlþeóÌÛª'mõ}c“k ø ’¦Ü —8UèûÉ4-yÕ~½]”¹Ô9ù2:_ó»#Åš ’´Ï*¥:4õ f ¥Íku*2~ûüµßƒÛÀ¤ŠjI( õb¾\¥ð³LäƒÎʺb0Ô^­›Wå|¦Øžl×½7¬œ<¹¢£Š·’~6ê¼3U—uéctÑJ?hN:%ùºV¿Q.>d’˜JøÝÃßÈýÚ¦,Ÿ¡»›Ä'F„>íïÞýS}ýö·(+P¯ÏÊÖÀääÁÞcéRgøÜºÎY“g emº¬(éë‹uòerŽ<Ô=ñ8aà 4xAù(ÿïÜÙí¡æPLôW²Ì¸J˜Iœh®G@¢K9 Ê,Ê SG»kMè»6,^TRÃשþ¾ÂáéE(.#ªBZ>ËD®‡¼+š¤í´G$IXd8áb£—-#*ô¡g}¸‚*›¢iAÌεb8o-³Èƒ60¹Ê‡ôFê:Ô sˆqÙ'wI™(1vv„JTÞuU>ªè:)ϲÇŨÖbjö3lê•8ALÅÔ²RËÃý{ÖzØ"ãÃUǹ‹ö…³„€í®£€fëU>‹4cΉ^V™yû˜¢ClC¢tàÖI»×mœhu~$"€Eý.Ñð^ ê²#î™ݾýV.}7ò¦¬2XeÔ³ÊÀ¡‰´›w-¬1¦É5ã/˜X}BÄ!¼J³éo2É0?‰F&ùL¾}>ܨÀ˜+0î Ù¸[Ð9Yv qYt¦Éʶ÷ï?8 ãQŒDÙ¾‹ú †Q/H'ãj úÃH8Ÿú£3;¬Å©XŒlS\Âú¯÷šêòÒ€<âcz Èýᧇ1$ö˜¨ û‰¤ Ø›~ 6Ÿ^œåz×H‹'Àé¹a| œZÔ·ë'“$ço¬˜ø¢O’) *ºÖá‘“œ³`ò•ÑCBÎ ‰¢M7mÉa+oµ¿=QÒNþge©ÆîÈ姦œK´•RÉËÿDKi/x „¶ÛMœün·ˆ¹½¶#èÂeíáém¼Ó«²)íì¶Áä¶³+{\†Úg¹àç»Ö%ô â]xù –ƒaY‹q¶,…«.Û¶ÒÙl˜}gŒuKg ²nšAÖIH§%ºpc_ÎÍÇë'·ÃR„õ£*ÚþF›éÈäåä vð]vï00Æt41eÁ¡_½­ŠOÒ`ÖÔ-S!# +v²ÂX[ÂŽÊ3Ì~ ¢ }–ÍE—ï „$wE?u“ä¢ý]÷™n¤­rcùH1¥HV©ÃZ-´Ý¡2ùíbЇy·¿p˜¼ßÕ‘çcËŸv|Äþß ñTWͶt_4Ü&™€Ä£†¡&§M:ýì¡uBq—@ŠœT)•IÊÜ횈æ‘O€;]¡.Hÿd°ãÑϱ ¶0ª”%XåúVíê³9™Æveâ·`A“Õ“úx†ï›¹áqÁRoù9ç}ï˜8Ó2ÓA¢qK}Íé¿bNõuk0õ£hû:uÿp_³·7Ä3Î]ƒ¬ªúy[ª…Ûí×̸-èè-F‰¦ì Nzuª9XÂ)+†e¶Õ])Ë\…åÒŽŽhÓRgdõÃYðN–îrÒÈ,*üI`y±Sò=¶¿ì—µL;¼p6e)¬ÙËR+^¥¡œêb­,mž”79L<^‰¾¾íÑH‘^„ëzˆp –õH3D‚¾ Al‘ y ¦ø#ŠE½DÕšŽ&+£å1 T»òÇó. IÄëμD‚ƒ›†œ1r¹0Á·ùþŒÌÈP“áM2_hõÈ6CB Ú9ÎðSÆD^HvWìì ³ý ]Î/m˜.Ÿzüˆ¬?g­BJþ¿ð²IA†‚ðÞSW]h!ˆ^@ô^ âF´j±×wæM~Z©¸*)-$/ß›7SCBëÎ=ס‰]Ù0”} ý úg0 "I«„z×ö¡3ž¥~Pò`F”J0OyH\§ÈRY–iNè‰2×E6ÈáX`JµºvîüI3E5^[±0Q$4V2þ)M*–›ºö|e¼Æ÷¤Óª:ï¦êœÆˆ1Òº¹8oõñÏ÷CÁŽß%å ‚™6åíxÙœmêMŸ|–t5t¹QÅ|³/sótY}kbõ endstream endobj 479 0 obj << /Type /Page /Parent 1707 0 R /Resources 483 0 R /Contents 484 0 R /Annots [ 480 0 R 481 0 R 482 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 480 0 obj << /Dest [ 469 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 345 725 361 739 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 481 0 obj << /Dest [ 691 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 199 448 215 462 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 482 0 obj << /Dest [ 691 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 220 394 236 408 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 483 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 484 0 obj << /Length 2574 /Filter /FlateDecode >> stream H‰¬WÛŽÛÈE^õ !@šÀæMeÄ ìÚëÅvÖXk7@ŸEO‹Hõomßµl/p"éÆbsïÏe{À_* 'É&kÄ·?\‰¿þײø]ãÛÂYÈÌrez¸ïOYûOUç|H “rkÙ+)þÍÿ306ŸMó]'Âõ+¼c§ÓɱÇ“ ݪèZ+<º°.5¯|Ò÷ë™'21ó‘Dž–N‹ÈsÂPÀÆ0µšífß­g–¸·½1ºÚ%åúÂBÇ ± t‚ ^ ý³wêr±p–¾9‡XYŒ-µMØg­@˜«ÏÇ„Ëí\X1ÌHÚ¶Îð´”þÐÁűl•vÔ¥ .öW<#t3]÷mž‹6Ù7¢=$­hºã±ª[‘Vå.ÛwuÒfU)n’:K69®ñ\I¨Ê&«ðŒ»Kq-¥`­m‰4)Å!¹¶@R|I‘ˆ¹aÿúl­ä‘!'d[³é¿­zªmÏñførøX[W¹ÈvgˆCu¢ÍÀDp"i‚_zx½KÅï¬ÔT–£»4ÿg–'Éi7IÞ)ýJì°66kk‹ò@ÓŒ¨GÆÌ­´*©-ÎõܘñÚ`¡Ô‰–ä$?2–¤Úù;ŽÂ×&ÌÆØ!<{?èèì=ŽùœyYÍÅs±­DYµBcÓGŒ œCXþ6&)`brÞdå>W„CYK„íIÆQ•)~«+±é,Îï¶ÚÖg´®VM—·"Ù'YyÏ…¿)zßÂ3èÏÌv,5~, àÔÐÀz$UÚé½2»Qù™W:dW¯|O•È_:?Ím0‹ô$dÅïjµU»¬ä_j+^Vú‘b2}¶ó«RüšÐ Ÿ´Ø¸ÐØ\5ë Dr¨My|<±×%vUžW'p/ò¬ajA I“º¬HƒÐ ±W¥ª“+•ÆV¶Wô½V¢ÈÄþЊÉv›‘I.H&½\Ùp5:j¥EBÜpì¨ %ÑŠ*Å)Aë5‰+Ò™b*D$ U¶ø”iÌz7^SiföZ6‘œÒ¡Ê&Ó9íf·_[Î='M2¨O”¸O/­j\ nTm‘XBr}I|Þ‰+Ô¶å"õAþªê†å“6ë§V‹*s³c;‰YË^¸ƒ2«ÉH„ŠV^î¦í 1÷w]áæ ÄÁmàgAšìOÒg3ÄÁ öÕÚõF6lÛ-ù˜˜¦}1Æß-<Œ¤?"iDàÛ›¬8WŒHß¾-Іú*8s³¹WC§¨&©v}/ŠäSU_‰¢xQd%ž ±ÅTÓ¼hº¹B»y±é²|ËýT ‡xÄˉIÙí’´í,›z˜š6€Mýú%÷¼íwתMËür«’bPrÅÌ› Q]™¥ Å:ŠA­Š ÍÅ1©Û ÚÕ—‚»)6*¸kÜ‘±U7Y Ž´Ì -û±D¾øPBJ(ƒ)5ñ ð%.ólS'¨P÷’gëA·éþ^oHBpVʱ€*oF„‰]£¡Ä ^É龃þAk§÷îMŸvÑñ·¨AÌñ­L¾D±j~Šj«rï2íÑÓSG¿¥Í@f hÃЀ1ÍæÈíæÇàåÿÑwmƒ#GêosÊeî ÉSšÓâa"í‹äE#yf*ºEø=&¿À!º? 9ðÄDt’_¾é_3…(¼Dž7†¯çõùM‡ž[ ˜ùÄ”õ¢IÊšªFâ#Ê QÃÃTüPÎ^ŠgÞÚk2úžåDüô~,×’í/Y¹­NpÕ›¬ì>_‰ìÝ¡*ÕOïÿ…ˆøR<Ž2çù—ñ‡ŒÁRª[ü¯„ÿaPa£>d IYÀ|¡KȨùÂñDÛJzËÀŸ“)Oà›زϫMºÛ<&í®}P3 u8ŽG áhÎM« û”mû0mN&yèÒUš—ϯ¯5)4ÅRIñLµéCLjÎ4˜ò*âÁ?‰ça?À`TôÊ{qÔ-\B¥9– k§:k©Û@´"¾¬UÚVzΡOP™jY¤¹ˆZMÇ]æù²Ê‡£Ê÷7=]æ8GC!Ay„Âq¤óÌHÇ6€Ò¢„9a´€šàRDêdNôl¢‹„Ir¤ü™„\PeYñp3¸ß*ýëIù?mŸ:nðЩףI«i˜^6é~YèM"îL… Àt"@×U¡L6DÆbz: ʼF&&~wçÛ¢îãFÏ™þ”qèVš=E˜{(dõ‘™žeâ§Quú= j€Œ±ƒz½¯ÎmîÈÕÇŽZÄÇóÀ¥È5RôËÏ?ö݈> øº¦Ó¶.äÙB(¡ÅüG‡¾ðÕ½_~~#P3Ë6ÛûŽ[ÏKž ä½¾~®ƒ×%ŽjTnâI ëMõšmæFê‹ãäåvôÏ“æË€ÖÅS­éR®ô‚ÛN²Í+RÔtãO ÔÅ]ÁBÂ|ZÆGkáý–åBϘŸ©àéžEmmôôÜù”ø™¶SÔG¨º6Åz¡‹õƒ=­.€»'ŒwU™ŸŸëòÍЩ6H£d޲Í苃ÄÝ)TöC‚Iº¤æIФPM“ìU㈗z¢hTḴ©©r5×¹mS¬¸wãj1„¥Iê+ØÑ“éUö%® “@¢+iAÓš%å¶/·æg½ímãTW4³Ñ—ÉŽÞѬ_æi£·çê ™³ .5Dsq¨/ÍÅáäâ"Û0@V­iPÔç¬i±–ªºß˜Aƒ®Ÿ[”å˜h-h„l”¾_Ïþ7c† endstream endobj 485 0 obj << /Type /Page /Parent 1707 0 R /Resources 487 0 R /Contents 488 0 R /Annots [ 486 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 486 0 obj << /Dest [ 485 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 206 712 222 726 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 487 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 488 0 obj << /Length 2335 /Filter /FlateDecode >> stream H‰´WÛnãÈE^õ>5‹æý2° ìlö‚`wÀ dœZjYL(J)É·ì?ä󰧪šuñz^v°ØÕ·ºœ:Uýy2ºLB¨É|„ÊÇüÄyîù¹Ÿª¬H¼4÷#5YŽn¿ms5my¯Úi3ºýá1P/íÈ÷|ŸÖLGãþs?ú¢ÿVºãÈ‹õ‹¡ßP«0Rî¿&|B¡2ß+RÜå^êË%|@ÈgÑW’ÊQÿ !‡¾;"/Õ~®žßÔã[Ó- µqq’n«V}óÃúçÿÝq‚ñs‰—èÊõõtq£÷U÷_³©ùH—ÍÌZýÊY16ŸM }/Å`òÈXƒý~﹑è–n5t-ŽÆ•>}X7µ¢ŸôÝd¨JÂ$õ¢4PQæå¹J/ŽlŒsµ1£ùèóäàŒ(ÀÿÔGWûäh9ù7,¶‹=?Ƃ؋¢Q–¥ªfweU»Á¨ ¼\?׆î7ì“–i#«ßÔ?à‡LÿÌ£Ÿ\è£UW¾( JMËF=µµ×ÎT%§6¬*•LTŒØeU[ Ô¾|S¥ÕŠý8f3¡Jõ¦^É1@Q9ëºìæ«ÍÒa#Ù>õ¤[c€ŒôÉUÝJ-ËÿÕœŸë)Ù´j5W´¡W/ÛMIR53kÓÆ©žAÅH›¦SOͦ+á›&¤Vh³c*)rÀHÓJÀn¿·8àåÈ,×’ `$‚Ͳ´{ì²iƱ3ùaO 3ó€3ƒ|~DqD‰D‰oQâ|¢(%6J ;ƒ¼¨îDºZ *Ÿ|† ` è&!‘LS.ãáKHšjOMøŒ…PzÈj_Õ5üí$´Î*ëú ·%æ¡…ç’}Gt‹ÚÓz;3ÐQÔƒB¹~`ä•„_][Š*Å –­\@3Õ\‘t{¤aË®Ýh³$ gHôWw2Û®j^ X—Fp~8H½#‹GX—àxöULÔ²sqU >Ž„‰|‘^gt¬æÊ…OP4ŽR/)È9E|@Þ€§È⩹lH~×x Ü›»4œÐ̮싙Kž72pn8(ÈUC®•dSn°(G]kìŒ é4Dô׋¸©W (ÑϨ^ zB^±çOì8þº]jIt¦­¦ÍªSæµb QKÕ$),Šc*p'0ö³£J™¥.nýÒ'Ÿ(éYëqGÍ<»ä‹ýé~$ÄÐ?ç ÙóHv•G²#Ü;H±ÐÆÂf'Ý=…9Ñ»²ÞŠÀ!Š Xå¥e¤™U2f•HX%;a•H/×åfŠaî"xáÀX?9¡n‚™=Ž"Zw¼Éó ˆÊSIºäšêV€l¨d^fsHŒtÚ1ü ?ôî¬)U½X¯]ë)§Šû“r„ýâ©o¸>gº^ííÄtEæB¦X:™³ZQên%™Vv5jæ=âQeS½· éÜõ¾—ù›ÕdÑ¡#î‡Î·A÷ñ>]´ cÔP?Ñý eÕ+d­ïÜqjZëÁ¿× ¼AòMͺS{À·4'«ˆ´¡<·;3´]]5Îe ¿Ö!Ú%±NÁcñ ßà˜jºÝ_ÐZF¤[à"@×—r³gW9Ríì‡,&Â{P«zöî´s¸­¬å$&ÙH¿Yq'¶Ôøì¤ÞÀÊèÝÜݯ¶õŒ ç–œžo6­ž%¦œ|0§¹¤«XDD‰ÞôØÄŽ%–š'×;äå×ôð‰òžzø±§}Ÿ¢ñ5p¢¶¯¢Ùðh9háy¥m;TÉ#nùkËéŒ÷a/ç!ð3xµõ-éßÛ-557Àö#Ÿõ&Ï?z6Ñ ϶)÷¡?ÿ„ŽtƒX«ÕFMëŠZÍÓnt^QÞ*tÉ/m 7ºn@UcåR –­îYgØí]‡vrŒz"*þ áì@î€BG°4v¸æ¡¥£ˆS„R”Æ ")ËúÝ[nóºRÆÊnƒöë²[ØÅ®Ï/ºÖôxËÁ‹m´Mt¡eK†•²º9^4CQuäò×9æ¿h´¨¢ÒØ‘ꑼa¼a¨&1‰Êƒe 2ñlï‚VÅô‰YŸÂò=i”ê1·0to¤×ÖKÂ0©žªg¼d8Gg3â£ò¢…À~þ‚ó%4ëZ^ô¢Á'Ý˽½óúúJT Fž"6¬Ò—A§7+ðø°o附±ñ.+¥Wd‡F´/‘tïYW1l/ž¯ýCPjjL-ÄG¨töU…£â†»dåÔU³}år¤¨’A²,¥Öç6¦èÏ‚ñQYH‘D »4R™Âž7_ì’E¹{'F¡çb&'1ÂA1J-ñeˆÑy p‘ðhpxˆH'[åÍZÊÀ0.ùÝb¨ö ,á'à'zÒÍ<8£øËBÖ÷§uÖ§uh+ì±.> endobj 490 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 491 0 obj << /Length 3356 /Filter /FlateDecode >> stream H‰¼WÍŽÛÈF®zІOMD¤ÙEQ¾ÍŽå…ï:ðÈ^`Ö9p¤–Ä,E $5šÙÙwÈ;î!_U5%J£dr lhÈfuWuý|õÕóÁÛù_- ƒ/ó÷Xc ‡Cà£ÒjI-ކÊ!n·pK>i6•«A4N‚QbÔh¤©JLÇ wŒSUÛÁjðÃü茑Hxî“«Cò¬œÿ“»€ÅAKÌø©óç$“¨çÐðèÐÐÈuÆšç[«~÷Ò ÕUi`<9úu‘—kñɵü8*ŠÊ±•NŸœ’`"Š~ÉÛ‚Ã$Z–b„§ÅOLŽô'¸t¬•-×9L€{‡Ê3¡ÎÔ¢Úî ÛÚ›ýìM(jû˜7v©Z¶œŒ&{aªgŒ^ã¥QÖ–],}˜‡ìIO¦¥bZN*¶¶léÈMÖª¬(*… 2Gm÷‹ÚVµU«Â>åy‘·Ï$ ƒŒ†^üBç C[øˆn3ûSd O)—žLïŒNFFbdÖ4Õ"ÏÚ¼*Õ}‰š6ÛîT^BïV>-«C©ÚJQAL¡Üª,`wn‹¥*ì£7Õ\‡#]/=ÄùA%Ç^·ë窵ïÔ‡ªVm÷»F-Ûui©¦pcÓ$ПºèŠ›$È”¥õÄö ßv2[,„,\œ;m£Vû¢x¾Ts²Ë8»(qà’\ý°¡`âÐRí)$pÀ’|è¡N'¨Sé÷”Ë·–2~„H½råÅ:_ïk/† 9X*(ëC—Öö‰3tawÊÞŠ¤TÆÂö Ü)žOè /–^ˆçža×òÁŒO÷Ëý¸…Á&ÂYŒm8uÇÆCÝã^Hµ™#Âê;êŒ>}¾eè‹ô¼ä<½Ÿ½¿¹û:gÑÛ¡ú‚‡±ž‘…‘ÛwH˜h‘=ßfý-ÝÓÍÛì¶í€j¬Í†W™ãE#‡PtÆTö(noäížIôçŸgŸ?`!Ñò{Çu8#u©λ§ÿMú#þ·øe&zn¨^審o3®ïîì/äŸ)ÝÔð†3QÙ=ûîyÔ¬‡9P$C¸ðv½ðM| t,÷/+UTåÚÖl‘ʳ¼ "‰%•F)(rnÌ@4ÑÈ\ÊÓ‰¦ü…ãó5g(å´+AÊNIoùLï ÛÌgÆšQ†!– c¾ÍyYôq0c$‹¾Ò‘[WùD)N dùÂ^O€+•,n[d¥zpu,÷VR29ƒŸÕYQm]±>Ba&¢n‚RíaPT„ÏØ¹7W›e+»Í~³½»ÒURïWñ<9á¦c2Hœ˜\GN2úÓÍü£ÔÒ-`EKØd¤_ÄhË!_õÐTÔ ƒcC¾èÿ(¶Q:¹ ã8Íè“€ñ‘Œ:`PÙ°}~ì)µåx`‚?¶9^þU.0ŽLÆ}}ÉQŸ»ûI w¥† „ UD¡›HJí²ºmÞ½Ú¡Þ~p–°LB"ú/òÁytîÈ›:ãÅmø"ˆÃŽyDë}¼jÚIO¦=icºk‡T’U>a âGŠ>fÅÞ^8- ¦G*¯“%…æäƒêÆ+ÀvnRKÔvWsöÅZ ó$YPIü·Š¤ðê¾ä†@"Û¼(r·î^ºl™XŸ¼J“v™ðùå™è¥’׎Ù,¬ò㉉üÐà¿ Ãwü_QÙT"J%‡êÝYK¼E‘´¨_6hÓÙ±B;qæ9ŽOÁüG[ÓÝm°^Ü%ÓuI¾ª«­¼áÒM[“[Ø•Ü áh/²g:ÜX)çyZ,¤s)&[,ÅVHŒcc´¼õõw.R8œHä­è/1‡8òjŸü«$õå•-ZDÌv…¨.a«ÍËݾ%èBƒyD×Y½x7€#e¡~ŸPvLtœ³ÇƒË4R *½<ÍùÌ€òwÇÒÿ›}VË|åS]ù²ó"/ŠekKiò`Û‘ô»nŽ24ºQùÆô¤{qs?¢‰nÔB¸”€ .ŽJñ±k{c1QòºO‚kõ9w–Ëðò«¶Y]䶪c9Gé9X€‘;·ªBŽÈx3ÞÂ-e´„y¥“¤”uœ¸È,%Ÿ8·É±.0(:>ž×Ï@=¦dûtôÿýˈêÓ(ƒ[¶ö©=W6 Æqì^f¶ ¾ü6–ÜØn? ¿„´ÊwywØl·Û3y NBÜAÓç™;`T2CbfÈ$¼âL pË]Rp0YLj"¦á»©á„Xt†’”ç+aù_Eðd »&,Œ1%$ýÏfÿj& ‚Ü—ecÔ¬*ÛcÂÚéJ‰Wsë wiôÊ`¾¼f–*ÍAºá:2zW+à8XBÇ®ØÌù÷þ4ÄhxwŠK9Á|ñ÷ÂÖ ™¯Ÿ¢: |ðÓ¿öb%:4OœRi««¡…|Ê77 $ë™8O«.‡*3‡´n¬ÒBžàüPfYy&ô;àU§>©kŸš"@s÷ØúM‚¨È²ªfòˆ8ºÂQÑ1–cVîñ—Oš‰ß¤Eà'ÓÑDÓçÛõõ‰‹nÖ‰©A|õé묘± FóùŸ~¬wX7~ C·+k¤yÞ¾ÖËÍÈiúÜÃEm@3v¸ˆ½ø@ìÂ)¡l©0èM»¤Üf)†Ññ Ÿxz¸ S!ᨮÚB매Á·~µ{4¼¹ß@Å Tææ›·,(ŠN¯µÊþÊÉ<ˆµÕ +³ êoÁ¹&‘5†˜lmw›“¹ùY·V –qÒ÷ñÍ}RN¶² +ÉþgZªç#D{c_$ €Hœˆpi‰ñG*( ¬ÇYQîò¡*xÅÛ J,›Ý§¿¿Ö M endstream endobj 492 0 obj << /Type /Page /Parent 1707 0 R /Resources 505 0 R /Contents 506 0 R /Annots [ 493 0 R 494 0 R 495 0 R 496 0 R 497 0 R 498 0 R 499 0 R 500 0 R 501 0 R 502 0 R 503 0 R 504 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 493 0 obj << /Dest [ 754 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 110 739 133 753 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 494 0 obj << /Dest [ 1174 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 353 653 402 667 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 495 0 obj << /Dest [ 1150 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 128 599 169 613 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 496 0 obj << /Dest [ 1150 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 480 599 521 613 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 497 0 obj << /Dest [ 1150 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 434 586 475 600 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 498 0 obj << /Dest [ 974 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 482 400 509 414 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 499 0 obj << /Dest [ 595 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 320 387 349 401 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 500 0 obj << /Dest [ 1008 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 299 360 326 374 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 501 0 obj << /Dest [ 1385 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 446 360 474 374 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 502 0 obj << /Dest [ 1174 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 89 124 139 138 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 503 0 obj << /Dest [ 1174 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 270 111 319 125 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 504 0 obj << /Dest [ 1150 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 463 84 504 98 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 505 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 506 0 obj << /Length 4270 /Filter /FlateDecode >> stream H‰¬WÛŽÛÈE^õ ?5ƒÍ›(*°XÛ³ ë$ÈÈ ²ž àP-‰1/ŠØyü!þ‡ücrªª)Jy×X,#‰ÍîêîªsNU½šžÏç‘ Õ|9 #à_I–ùA¤j:›øiÄj^ž¿î2Ut<'P]ÑŒžÿpªU7 ü  9ÅhÜÿÜ>è¿äÞ8ö½2ôiM”÷ÏùG3¶0SÓÀŸ¥Ø%Îü4MØ@Ķè×$Sÿ0:ŽoÆ~ªƒLÝ?ªÛÇÆ®1iãÁ’îÊN}÷ÕúéÞx‚ç-ÞMü‰.½@ë+u»/íg³­ØH¬ófágZ}áO>_Ÿ¯~ЇùŒñ öû½ïÅ~¨;ÚÕж0-}ü p»Â ­ÙÒÍ|ªR¢IêÇi¨â©Ÿe* ý$Q¸c’©­-G¯ægÄ!¦§Þ\GpÊù¿Â„(e E) |üËx ¯úXÐO:~ç‘G½q„›Ëƒõ"ªM­òmëÜ–E^U¾z‹·‘{«ŠÜ›"„º7ª}0[/Á¨|­˜·X˜†‚±£e³Rpzá6t[™Ú–µùÜ6æZy!ÂÑzag5K/Ñåj'q†¶Q6_õч>]à ,–Ñ­ôîŒQ™&wžÏ¾yþ½Ã2V&3Z?K\ ‰¤þÌKdBáâ,Î2Ç?Häl™ö˜ &ßä6ï¼qLXévk]SÑ=®8ž«5Ÿ¬/7:暟D€=Êæë0ÈØ €ÎÕÆlÇ ÚËzã >;߆7`¯î±zF@Œ ‡´z×™…Z¶[…ÐʤIp¼à ñRØl.Üçž3lfþ,>2šFò!K2IäŽY)BÍhYBQo<)Ö,ÍP™²®0Ž âå˜÷9ÙKȵäa_ý hÆi £ <ò.¿â{@“"-#´{¤óz#Õ܃v#»$÷ú̸Êqü²ÞTeQÚêQ٭ؤh ¤ ¦“[ÒÊÒ­p‹KAãA`ø–"%‡8ùÉq˜ÂÁ£!/9Ò±¥!4'¢D)”Ðøê»F™O…Ùˆ–nHEe”)Ë.Ì’¾¨9B tí68€WRLu¦.½±Îν{îúxªIx*×’ÐYŽx¶|¦îô²jÙµwžªÛ…QË*_õ`yQ{!‡ws-iQ¹sé Êù‰lì‡Xü…V¸W>¸3¯öˆë”âJ”wéH'@x}ñ$¦$ø3=†ÇúTçß‘Îk¤Æ.ûhœ5#¹µ‘ÄÖ¤¤ÇwÉ »Ë«C€eš[É v8=§œ1¯Z85ÌZ™û[·¨6ÇóÁò^~1…À ‡²`*§€NæÛÜ g„.‡7jYšj!9ž¼ïâ8¸ $–o‹§§8Ô3ðF=ƒâd8#Þ·Ë¥³iÿõéÓ§gðÝf#BÁuÓ£;„‘YwžGþ“ÐH…89Iš8fªŸª£?ýƬ¸>î² ‚-(àŸ”"µd„€CÑ)|¤7ìVzOaÊ$¬D­’Æ}lx¾)JYN˜‹É[=ÔUd¦O€v¦¯ Nã_¨˜zÀ"aÐd`PRýô=â%uY¨ë 6¹/«Ò> â6[Ƈ‡ Í’ª6)Ø–eeÄ¢zAGÛÙâúÂ&Hú”g¥[)_äœX—(Väyçqß´Tú@¿HšïwV5­ªÜX³2[¨~ÑÖµixÿEp:q2pì19»9?GuZÌŸâ 0èøl´s#èq™ÍŽïИ=¹ÅË$!ÆÔÿôŃêàæÄª§ôµ†G8ºˆ«=:æÕå*l2ÐÑõ1{SU¾š#ªJQ‚. .Õú+Ó HÂBSÀªMù‹ê…ªUÎ šp¦C©#«¬)Ö °Q)ZK´Ó•y ‰qo©)Dx@9•§ì*øÂ’yµ0eaz£ëÜ¢"eƒ˜Ú´NÜä÷•Oeþ7ªˆŽ)Lù@ƒ€œˆD³àdRJݱƥ}í¹z ×Tû¤ú31~JofC"K‚?¥r娹“â.s‚—*Þ³¢:£ ó÷µ¹\>³'3¹ éù®aöUm Ššjp—/'ŽÄY\iŸê+æÜíqwZÈ(QûˆÕõNŒÑݲM»ïÛzæÆÙjOÑyâÿ#Ñ<êÙ\·¶e¬N×±îêÒRâ:cVH©›XíL§ŽxÒ'/ÇÞ’õÕ«G\yéFw•…çû) µâŠÀ°†Ý' ýŠúŸ ‚†ã¨Ž;"šÍNçz¾˜Ší+™ó.½eæDwh‡võúT®ÑzUjáÐq†}Çɬ¥’–Ÿ =T*†£wU[ôE¶ë4?˜ž©ò “ >ô‹L´³ÔF"*Lc-? ´²d”<ìVý÷N¾w  5 ±a‹òÄ*¸ÏY,½1 ˪2ýø¨nï©ßÂk ;X³ˆºÍ¯hñÓ^æÐy}ûA×åjmYNPœv»åð&îÒIrp ²å˜Ãƒÿ³…N¶è2<Êd3]% åâз$%ŠðxªÜᯋútÁÏ´Û•z‚±ÆaKå‹E'•.͵DÇ ‘…(A[_‚¸øôÂD»MY{ª¹²•Š.Š.›_éJI ] µAõ-ÅYDäg!‘§‘‘9O{O‘ˆõíÍ_åù-Çç7j7?ýùO7wh_ÔQ£šú!úTŒÉH!]ŸtvÒ[n,å7”´]ëJQŸÉéh° 'í¡k-#õ‚4 ”ÕŸ­¡”ÿ@=¬Ck)ÚEü4=ƒòtØb*AzÁËðgéö‰¸Ì*7öšk L€àëe« Ú¥%æÊT$`}aAILmªX/Ö¦øxy&]j8¥4ö Õ®øÿ×–¼Óƒ&óíõ[kêo*y³#}Z¨ï9¡·\XI¥ Ìÿi/—Þ¶( ïû+^™µD½Ú&m ´;#@#oÆ%¥D•;é¯Ï¹!‡­,Ú¬l _3÷qÎw‰‚3z¿”+  NQ@ôY@T†'–Ý¥œžDYŸäg±Q¤èñ&6i¥““®RmÏfļÏjv%‹ þ.u» Í- ˜J‚FÈ{C¯ª9mAYÇ‹ëñÊZ"ÊjèBöoªAiÏìuÕ&ù¿Yà¹LYQƒ'i™xÒ3µÛ®/ÃGá!ax@x¶N˜­cI¨¿’lý=4Zýª°‚›˜vFÕ–àÃd`þ•~‰;?ü‰€_ðßC·mi¨K¿Mb$þ(!þÜB6rþI냎wî/4Ì ÔÏ4šO¿GNÖ62Š›(ùØd¤áèn(j“K¡Ô«×‡ZṂMNî<Œ¦~ÄCcòU¹`ÒÏ õÜ7S­&ß .ûwáûWàü“¬ýøî§¿þÅjhûÛ¹ü0y°öq(¶8+ÝšqÆµï ±ƒê‹É*š/ƒ&Ž»ÔÅœlPãÎó‡ × ŒÛ  !߈É8ÎL[h}³K8T-Eö‹§CdbþÍYÄÏJ~^@ÀP ÞÇk*ù–NÙz+sד{¦«ôÑ™Õõâ娣ÌiD ˜`œ]†Ç<'jäªY·Ã™ì°j«ôŸpGØ¢sçè/‚)j"Á\Áïï5Í ³xªÈ|ìcÝ!§uãÁݯÑE»¹¡ñ7}éVØ÷1ms9;Ës7eÜ-)ü;Ù:y&ÑA¿;þ,Z#Ó]ÿš¥ùÖW†AãÒÂ* õK.¨ªËŽ1ï‰|ÔÑÏ/8V¼#Æ•›ºDïæÕٕžƒQek¼ÓÒàc ¯íÖÕŽ Xn-‹fÿ¤ÃD‚Ò@‰hب…Š´‚¾´—RÈYqUU`DA_ÓÚÏ{|ÅDîÈ—µº”¨¸ò›žs‰ÿÿ䱃^A'=€Ï^Wf&!¿LOeZ!¤£[ò+'‘R»O£}dî?ýþŽÞái-pˤ…¸“¢gÞÒï$ªôt90òˆSmâ2¤ëùêÿ5æØ Z ÍÜ`ð†£y)3¥ô#/íÃ@ S’ÌM@¤Úk[]®õ¼ú·ÂÔÕ„’Ú3šúÙ:'EÒú†ŸŸÚ–‰SÁ§È.ÃÆ¢”´ ù lo¡š bçª.Êt l…@Ó©Ôīԃ%¦Ä.Í›ƒ;½%ðJ¬ä7‡n]ÒØKônnäÒ 0íÇ©v–ܲˆœid9ÝŽþ×jê0 ¡µÅs¨ûPW3*5€u·ç~êü’›LÞEÏŽE?ȱ"%݈ܨO¡Cd£²ª…©ª)û’ýc›4ë×H·ñUS3صìò9Û6N­bл8K˜9EÜ ÎÜУCñMåcs„“Þ/ x@½¥†‚ƒâ]Ù>¶>N…;æca€q(SƒÒ<¢ª$.ž\i6‘×ʨ×}+²Þ®ŠâÎ#¥„úœrÏû|mNwô1ú,5S¯%ÈàV­Ѐ»¹'RHY ãVì$§ŠÃpžÛ{ý™$5BñjÞnxãP+5oô× NW×5Âûy“ž®yÓˆp¬lIÁ/šÉ|ÛzCïŽšŽ±s¹.ŽýU)•YOFQ€ a:Ú|­í=Úà±Éòú"_mÊ ÛÉÝq߸} 3٥ͳ+³¢©ºûv n ¢ ©h+n³I«Šgžƒc¦ˆ T!§M|Ô8l3»Ð£ú¬/£e—ÁÛ®jƒ¢½„´a»¸Z°ïïø:X!» endstream endobj 507 0 obj << /Type /Page /Parent 1707 0 R /Resources 517 0 R /Contents 518 0 R /Annots [ 508 0 R 509 0 R 510 0 R 511 0 R 512 0 R 513 0 R 514 0 R 515 0 R 516 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 508 0 obj << /Dest [ 595 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 89 612 120 626 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 509 0 obj << /Dest [ 1634 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 359 598 372 612 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 510 0 obj << /Dest [ 754 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 242 552 264 566 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 511 0 obj << /Dest [ 595 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 494 508 523 522 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 512 0 obj << /Dest [ 754 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 269 446 291 460 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 513 0 obj << /Dest [ 595 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 218 433 247 447 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 514 0 obj << /Dest [ 595 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 257 392 286 406 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 515 0 obj << /Dest [ 817 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 198 328 228 342 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 516 0 obj << /Dest [ 595 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 89 224 120 238 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 517 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 518 0 obj << /Length 3070 /Filter /FlateDecode >> stream H‰¬WÛnÛHžê+~j&MREe8Ž“õ"N‚1'‹Éd± ©–Ô;)”åCæö÷aOu5IYV2ÁfÄb7Ù—:UçTÕótt‘¦¡Dº¡ðñ?Q’x~âÇb:›xqâEº]\5‰Èó/š¼]¼º IJùžïÓ7ùÈíw£_å»ÌqÇ^$—Š~C)ÂX8ÿLÿ>š™fbê{³§Œ/öù³Ahö¢§IÌ[ý'ĬúŽŒ½Xú‰¸ß‹»}Ù®0Jå`'ÙèF\¾:þ브k¼›x©_æ«sq·ÓígUf“±ÌʹãΤøÝü53æÓBß‹1H_`ÎÜ`·ÛyÎØ dC§*:[ãH>¬ËíÔÊìtŽ¡Å(œÄÞ8Äxê%‰ˆ/ŠlŒQ«Ñbô<íÁøÄŒÆµOˆà–é¿Éa‘uXäù>ˆ¼ñ8™ v N'o ŠwU?d›&ÞØIpe‘굟«R‰f£r3§:ÏZgJUÙèT°ô†3 ¾8N ¢>"è‘Lˆ {bc¦Dž•âÇ›ÑÆ ¼©T¹^8ÕN@ Ô\èRÌí$ÿ…B,¨1˜uƒ²»lÏ;=³×~ioí 7ðàökÎΕ1°¾´¨â,ëúïÄÚÌpÓbB1"Þ†éó½(³5.3¦Ëø0âÙl‡ëŸ2F¤+Eaß¾ª\j8d•5"÷[]´.Ì/tÓŠj!vU]ÌÝž+ÑvÎkÄnEPÅRç«ÑZ-\sÑùp™½A08ˆÏWµ*sà r•NIÓ)œå‰¨¢¿ÙùjWšƒMÐÍu¢I}âñ¦À•²Z‰³ŸÓ«³s»É³ww)ÏXcyEº0•×é™'n0Ó’.9þ ÌýÁÎ<ÛÎŒŒ^®ZÑdÚŒÊes.t{ƒ1çIÊ/ͭ݉pEJ N¸§Âæ‰0 ŠÅÕØdÚ)œaI@†’_Šz[(ûh®o¯NVä,ÿºUŸt^ñâ3šK mîSS³rFR*xtãLäíõ‡·o®íìN„ŸX8nŒã·q¬Ì ‡>ÚÛ¨/0÷©#gD^ôÑ^´ÛiXÿX ˆ™™Xj9¶´a1„v¬7^§ø6i„!²b_Jt)Çd—ßõл=öпì¤rjJŒ±låŠ>‘- ‚GI.7†[‡Ü`ÓÕ&rH¼DØ_eo¾Ê6-$0@Ý$§4Jï8áƒàÙrâR”Ûõ=öÁe¨ŽÐYÁØ‘C{ü8%4Ûͦª[(1$|QEµkž#‡KƧ‘ëºË‡MÆþÿRy01åÕÝ/wéõ­ýðÛöïb­Œ.e6XŠ*ïÌ†ÉœŽ»ú¸Ð'P˜:➯š}Óª5‚U=@š¶¶½¨ltÕµžÏ••#ÊàáQ'S'¶P%nÿ@åO(÷üƒí»”ù#œÐ8‘ Ø?:ÞQ‰D’ib2Œÿ”2)˜l_\¦×‘áÁàNÀ%\3±(ªŒÀâružµÊ­Jàô[[>±UXdì˜~·æZcã~ò5ˆ&ß^:.•)õ ´É¥ŠæÍ«#Ö ÄŽŒ„µ£7I‚šÅÆGv‚È Ù‰ô…+¦µQó@ÃSV-ΰ/ˆPm%ìˆ÷Û‘²°aÌì)u«ómÑ Ln|&B<þ“À4ÖÏËŸï®Jon¯MAó3=ôýDÔ(¹IrTémIó»nŸsÎ.œ'¶œø '§»ëÔŒøï ‰i—h8…DD—>70q©#2²Qn÷h*Uã :|³)öC Û‚N`¼dr`ÝSYÝ6Ô!å”1Cd|êÊV}jКzarŒô£K ‘å¦àX8%•IÔBEjù–üW±WÐUd¡föSÀûµ¯ùã½çvlßó€ÿšê)UùT‰PàöÒþý17h¥?éûµ÷é 4…Â_’Ï ®×œÀê)*K*ttn óㆅo<ýzŽx£v}¯Ôt I6Ÿ Ç]r0¼%x\:39JÇO{OÄ2A¼¨êuÖ"–3“ùQgÍÕÍ¥¡ˆ¾ÊL+È ( ¨ûá^í§—W"Œ¢ åˆt¥û«ÏaØF­”Ãä+ 'û·§š—WåB/·uf«´ø:Àˆ·EUdÔêÇsÑ(“+M¾Â]¨UšïKºt$×ÃùMNün,X<Ø~² gÖY½Ä’þ£ä„nm„ø‘ìVš=™så´28€YNýfÂAÊMKÐzk]n¶-…‰=êgæJ‡ÌŠøÀ¿¼>ÄpÜLr©S[™ÕÜñu ž%ÂÃ}¹}—QÒÐ(/u®Û‚3ƒ9ëw+Þ²ä%vE®4õµè3ê{®¸£ÍìZAæC¡[^¾v¨³w‚÷ÛL—´Á7VåC$32†Š† •©ºÛóÊdB„y¾$“¶ÖÊŠZeó½xL6~»GWS?EØTùP”Í•h³¥-úykrò;y€Ž;ÃDn´íKèt¯Am†Ýk©ªìQÒ鱯[ŸÒK÷q㘿[z2쇔Ì:s Ç(&gˆIÊx xÍÙ/¯ø0âƒã'ñf_èp´¡1¥{Ì¢ï(ÔOkxúáâÅå/FÅ^“À…TŽë¿¥bšÀ.pNhxäÅ_/0K850 SE"þˆ;3œ³·­,¨Sµ¤!+@"õƒk'G¥|4x%âc‰"©!ÍnÕÈÌ×Hî€}Ì© ®¢p,7†­ŠçZ݉Dòá*+ÀO’YSþѦ–«|%¬Àðµ]òÕ‡yÒ¦”´Yˆ§ì)¦Í;k?ŸÁPÔªY9gólox_èåª=û6šSVxPuCYWsÕò+A´%–xGaxÉøc²~W̹Cš8Ì—Tô²Ë¦h{U­sPva§Tûì¸Î:_jfû@„šN¾ZK ;D¥)ÕNðèá`©Jô•” ¹'È«õZÙtîõ›Ÿ‹¬º¨)z¡i:í\e( ‡"þ tcÈäÍäTÁ%H±\¯€C²Ãù¥jÁ•Bì•I ˆ¢BÝ#Ó嫬\¢àù_áeГ0Dỿ‚ã4’ÖËÙèQõè¥Â)áïûÞ¼m)PãìnwgwfÞ|<êv AÄ^¢ñá@¥HMuÀƒiƒµ ­âÌClraj“|“Ðþh‡ßxW²欪»ãlZnuæìbÜÈ›Ï Lä"^a'bÇ6ôJ •®ïRc †Ñ >÷—F@÷ëë®SåòÃ#÷ðÕO×ÖÊL”ç1Àˆ*ºúZ·É×ÿÆäL«.µêÜ¥¤Ñ¢æ€wN”ŠÌV¥,É¿ƒ×—Ðê_t A?² 1Äß(Î6qºuüÖ&º®Ïk˜ÏË :´0}@ÚȬêNq¤£^föÎ')íµ\E÷Z=®N·ÐúÆÌ^Ú³Gæc™eÇP÷ñyÏNf{öº&šÃg2%±"íz¼cÒZÇ -µ#áí\„ÕŽB{î1ŒEê 'eç€K‘NÞ³á‰×“¹ s¬ý–by¨p`%O¶Áð®Õ's™Ôµó|Ƀób,Zž>î~•ÂŒ endstream endobj 519 0 obj << /Type /Page /Parent 1707 0 R /Resources 523 0 R /Contents 524 0 R /Annots [ 520 0 R 521 0 R 522 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 520 0 obj << /A << /S /GoToR /D [ 0 /XYZ null null null ] /F 410 0 R >> /Type /Annot /Subtype /Link /Rect [ 77 383 210 397 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 521 0 obj << /Dest [ 827 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 668 102 682 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 522 0 obj << /Dest [ 529 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 436 451 452 465 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 523 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /TT2 2104 0 R /TT4 2109 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 524 0 obj << /Length 2783 /Filter /FlateDecode >> stream H‰¬WÛŽã¸}÷W0óP€­ÖÝò¦1Á\7YÌ&‹Œé´DÛÊÈ’aÑíö~Hþ!ÿ¸{ªHÙn·=³d.Ö…%²XUçœâëéàf:D(¦óA‰qIòÜò ãIêgy‹éjpó¦ËEѱM º¢Ü|ÿ1‹nøA@6Å`Ôßîwò'åb?‘ M×HŠh,¼OLx†‰þ$Ã*qîg]„'ˆx.ºK3;Õÿ"¼E7 c?“A.f{ñqߘ%ÞDR{˜IvU'^}?ÿúÅ¥xÞ`,õSYy,–CñqW™Ÿõ¦æIb©šÒM¤ø/ÿ²c¼}ÞZø¦oñŽ=Øív¾û¡ìhUMËbj,éã6Àî ÷jÉ3½›BQ‰A”f~œ…"ûy.²ÐO=&¹ØèÁ|ðzzFÂ$xc¨Š¼œþ‡–¸„%~Øœñ]Ïqûãè$ Á! Ah·“ùâc±©Ö¦j⃇%ÅÖÞ`'cìt¡mT.UÈa©(£J±Þ^.ƒéR‹Ÿþî,ÿ&ô¦«Ú¦í\ Ž‚¢'9“šò‡»âÇB7‹ªÁ ÆæZ™íF %fÛª6£ªŠeµXÖ{ÖóyUTº1CñfÔ™}­ûTŽB?Œ9ƒäÌøèרúÕy)Šsï"?—Q¾)ì›>85ÅE-™uÆCp\¡nJû˜×ú±šUueö¢jØ3åe‰ÂKeg2­ÐºÚ£^=x“ËÖT…(•ñP<‘dÄ„r¦ì´ýzµÚ·[Ó/¥6§[Œú-†ÇЇ.ô3½o›RìÈݪó2)Ö-]è?P̯üÉݳYrVÈÀx´6P¢6^‚»Ò a@ äGž£m|ñ#T]·;žޱP¶0ͤµCœÔje°ý4Rjñ ê-ÞYÕÐÇ5{ F—ò÷f·f¨ˆ±Ë;‰ ‰Uëî(v©Äš´ú#Y5Â~A„À.…ß…Ö…”] 18!m6Ry\â^î–U±æ˜iQ¶®8Á(Kq«›íꥵº%´~ž#r\‚+b?½÷|Æòé.?Klk7ê1¬K–ÞˆRw€òLw6u ë¾l5U#ŠW2DzÑUûÏ¿;lIϸR ”´±•jö(–ªm’jú¬²£kŽªÉ‡¢mæÕb»Q”%Nü¶3íªú顉ÝZ†y™)kBp †=B‹†ˆÐø{ ¥(t×±…ÂL¦XÒWÁpŒYèb¦ê—çÓšåŠr…PhSøbÊ÷KT.jÇh±®UtŒû7€’¶s!Ùw̱<ñwaÝb«$Mv¾²e$/‘'þÁòXI²Ê-Wê«kÌ0›i/ƒå-. m¬çÀ(-y`Ÿ(‰¬•ÁŒ”‹ÒD½k;3i³I¡œ Ãà¿Pä…«ôg~¹^þÚm!lN‹Zu•Œ-³Â Õ:W~nÚ]­K"d$•ÏÑÂô_WŸQÿÐ[,̰i¡@¡{~,îå_õÜt¾ÑÑY§ÿ?(r'–îú± kÈ2ÁhvJy&Í0óñ™>§Â{*šI/Ê!vŽý…£PüÀeÔ|O‹éòO_—ådZMN;€ð¼€,“ªnˆŠ7U»íH:Ö0h2Š%JiŶëYÅQÐÎ q^q÷Eà^oZ(yQ”‹b¹i›ª³µÓ®A?Kö‘Ð÷ÒÂ,†¦p2 h êÔ¾cñžÈ¦pÏÚ>Ûû[Q$À%é=¥\ÇIŸÙXùÂï˶ýüÕQYc/´ïªy²ÔÆHó†Âa-="®vt—̽—ÈéDÍl6˜4Q+¶[׿….¿h±ŽÍh¯Gúã 4Ë™ò“# $}ǃ ³\2—Lhë¤tm^:>³8ÀOàZ Á{Ä  =;rì ÃC úã䛜´ûOu™Z'ÏäL±œØlA ƒ®Ê,i°£(öó3|¾}GÉ”*Š¥j"Y•J¢zGôÏdOVâ/ÊâÉC¶õ ˜èG]l‰E‘w€Ê Æ­[T”• ²ýÕ§Óº‡Æ< n„SØøyÔ8ÄH›A+ÚG9‹µp¡+²ÍA€º&U ¢oTUwJE žßÖп՚I!06BìÑ”(šQÆh£mbmFG½ðf/œûè:/Q™? +ØAi ðü¬[€žYÊ›pœaþšÊZ£¨«¹6ÕJi²Ëìr8° -êz¥ù¶a9s%Uð1±b‘YFážêN—‡àüvá{Ö¿N¹®[ÛSCгµ½u**½@~sé í2®·,lgkM©—]צ:ÂKC%Èmÿ¡c!ó! „*¡ãäëµrÆßâXK%›È·Ì$ï=ºÇ٠خpe“{/>¿©GˆðCBÁêI7ò¤]ˆl»ðn…f°$ÕEA£]ES‰_buÑAœ p’$ñ9ÅñÏ?|½ˆCLœ4*ÏUúU];ñ-œ"¢N%›pB*4»j)òùIa^qòÑ©^q ¦3mv; {ÕµîC˜œ5~ß=? œAòæ}è6 ‚U”•¼5º3– ^’ª-ý€ª-€ÿ š5ª5ür±}u4Í£I„ÎùÉx€u“«Ÿeødí$q£(œ,yþõ¥ñ'8 œ)ÍÐÕ÷£wòæl’Úq{×_•½¸^Ð!Óy2û)Oº2|ÅŸ,$;pÕ –¬ýøÇóuÇ%ò0svÇkãOVÎs[ïQBÙ…åíÍÕˆ’ø ɹ>J…áF¯ƕϿ2ܯæÜ«…qmáøD1ŽM.#§úÆJp'ÿÜîH͇$ë6`Pð¹Ñ ËÖóåfm5µÇ b"»Î¾îª$ÔÈ{yËV/ï=AzɆ¥X©=Éñ '‰‹Rž(mØ·½tbUDPóÒ>‚ÚÉwË Ç¥zÐB¹£íšD ì^Tè:Vš™T5Ä®L›`ùL~­OäÎ èévlc-Ý$Ô\f¬ Î‹z/ì½.ÚÔ¡´ç*6ÕL„O&¾xjÓãÎ\¯üæí«)G畘Aš¤*>knº4+m.‹ºíØ'8¾IK2­¸²=l„Pt‰uéIPsss’Ëšl_ÿ_ööwwäõ«»§ˆ ÇÙµ’¾2DX¢¡ë@ºôá—Æë¡+‰®CèÚøe. SÄ9ûVnuFÊÝáäâ†Õ\×{÷ÒBË>Üíõ¥›­)-¼ Sa(|•~EAÄf–EåMºGyúVš’9û'<ǘ|¼7í¡Œì¸(Ö§9®SîKñ5êæhLlÖ(UÛ‰LwFgºÓ¯O>ë];Ø5s_mÊ:Ì®®Üñ°VfA€9‚ÜÍóÈNOfÂD—Un›ÎÄBÌøË!«Þè[5CºüG~z ²™10N¼¿«ý'F&ž¦poq¶ÓúŸ endstream endobj 525 0 obj << /Type /Page /Parent 1707 0 R /Resources 527 0 R /Contents 528 0 R /Annots [ 526 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 526 0 obj << /Dest [ 779 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 213 226 235 240 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 527 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 528 0 obj << /Length 2492 /Filter /FlateDecode >> stream H‰¬WënÛÈÆþÕSLýk¸°hÞI%݉7^¤X,ZX@FEAQ#‹5EjI*ŠºØ×è;ôû£ß93¼X–oQކs;÷ï|ó~>¹™Ï=áŠùzâzÂÁ?üIb;‰‰xÚQâøb¾ÜÜ6‰ÈÞãˆ&+'7?ܻ⡙8¶ãОl2톇É'ù§Ôšúv ýzRx‰°þ6ÿãdÆ7ÌDìØ³RüÄŽ-„/ðø.…‘¾êßf§žcM]ߎ¤“ˆåQÜËvƒO* 7É&oÄ»®Å_ÿcMC|×X íPæ–#³Íµ¸?äí?U]ð%¾LË•5Iñ/þŸcóÙ4ϱ#|Ì¿Çkp8lË·]ÙTEbq5DÚ:°.3S¾éÃ|âŠ\L¼0²ýÈ~l'‰ˆ\;l Q«Ézò~Þ;Ãw±ÅyêÁÕyZÎÿA LÀÛ °!°}?‰…þ윇¡{#¯Æ½WcWÛYÓXBÿ.õÅ- §·¢¡H‡²µ\¨y,”ȪíV•ms-ÚMÚŠ¼ÓöÎ(눩k{± l¦£+¿a¿Þ·"<&ö½Ã;Sµ¿é0Ù)k³Þ•GѨŸ÷ªÌ,r¦"³MZ§Y«x¦nDÓ¦5éÈ6/²r#n¾ÈGøÂr]¹ê§¿½9ÑÚ‡ÿGÜ¡j]d‚QÐ=èÛÙ’°-‹+Ù Œi¬J¤þ¤c|¶µw¶5¶ÈüDæeÊðaƒïεú$G5gUQ•b!ß.,Qù GzVÒ²¨²G»ÃG¤%ŠÉž!y´½—õ)º.ƽ5W³Û}J%Ì;»b–vÒÌ ¤\Qé±Z‰œ’£ä¿pýj‹ŸªVéWÛ¹õøÂ•½#C¼¾’½!d Ò¢¨¾YUæ9•QÌp’²¢‘;«²8ŸÏü3”¦®À;·+@]Àíú$onfŽƒNB±6ãÎ]+I|à©+„º±àö1j"_] £~5ðú­‡2=¸xü+Ë#ÙžYD‘FÁóÃg–Ñý†råàr #$~ЕSDnD4¾[Zä™·§A‚#˜›ÉÒÁÖ»ãaüÂÙs‹çUöA ¼®e³Â}XûPò'—Å© O¬ zþÂúyUÜ6kUä/”x#Aªø%g]X"Èu|B;HrÐÁL“G€´}ß3- o,úãá:¯›ö7d» IsFÛóËç• f€4¯S6{¢ìꬲiY1*¿^]ǣľÆ ëgÃÄ ]}Æ€7]vÌ¥õîxÚÁ §Ï/Ÿ×2˜õ^íRžðøø²¯áä%%.¬Ÿ×Üí«·'¾BeöN†Z—W 1Íêeļpü+Ëì»’ËyiýýüµôÈŸùô ð{^â>{¡Evháíóq…å`<¾\ÓSm&s…ùúäÇbÈs0Côë\á–\¢Hˇ}ŠöIBñ¨ŽFò Ÿ‰U½jÐn›}êÒˆwׂžVòÃ÷„j3{a]‹æ¸]VEž1a¤ÎܦÌö?§už. Õ0?8íñŸäz_fmŽý¶k–‡ô¨ykHS‰ÉÝ&]ªv“[3ÐÝL«×ÑxM`•ž¬¯YCÅ!gf lž+ôn‰àT>ÅÎã 4á“,÷Û¥ª™døTug©yB@åªûr…QVÕ0—]´_Xö3³5ó8!mN4¤A¤\*|ÚDô°z”‰DNÐÃe¦éi w­Ù–ÖJ0E–ê ¥w‹'_¥þÊÛü³B ÷e‘?*’p»°~'~õ÷¸¯k’p‘úGšÛŸ¶©h;õŠtö‚§5ãÅ ÌË1våtäT,÷yÑN-®‹\BþŠtÖxø!ÖÙ-á­« ¹¿×»”þê ¢[eΧtžù½‡£Jß&–)X~$Ía3¹‚lŸ¾‹™jÁ ©¤§+VXÐùX~†>‘T2‚^užÙ ™)­¶*VæægÔy”¼cJ5¿Gþ«ð±Rë¼Ì©ò8QÞJ¡-£s¯‘È+Õò!¼`І2ø]Qˆm4Ó­¹S‡ÏLÖp71yz7a/%X4jÕ~é0nnÚšûÒœoÔêüf йæ¨e¤eƒ„ë¢âð¤¥ëvÄÀßfÊürr™I¯{$ ª‘™l*Šˆ1Ã"ì€ÙÍ.ç’C´ó- OÔy{Ô(D×ÜZSÀ¾¼¶èµ yóÒll JÆ5ç_6Ï«ý±¬¥X×ÕVÜö…›~Öù}J,è½EÚë·)cö±›{¤ye­º ôq4n³¾Vã®Vc ¯ÖÛÏo~Ìéë:pÈ™¯(^×N;ØîFCñú\¼0­¹T"ݠݘyºá­T‘do+À‰+õ4@‚¦P°¢t(-÷y™àÑ.!£ûQcäÅ'ÏÄoô3ѸÇÀá‡áI÷€d_ce:@Ô¡>F‰ ÄUÁšM©´µjO]ƒ$ë/¤Ìj‹ÕŽÊfnórž™?”âjz…B.Šê Vby«ü!Gß»rM¼²í«™QŽºÒ$ŽË‘k²râ¹ÄocœÞ‡‘w”¦ŸÑŽApûbê%DûBÖG½Á•UyH‰Mèö× j#3ÃÁLÓ2n§Ô¡<”©'¨‚ `y¥¬XfÄB¹…ñ é|±mp8Lš¨e-ôá#}”múÂf~pxr·«èM°¬pÕrßrõUY«¯ÝLXFΚ²Ú}Q³Â^0BÞæ¨{rIxD8ýEs8Ô©Á§§Ù‡«Â“üŸsÏïsÏ0Ê?ï+2“-a¼ók%ñ W>° údLÎ&#`ÇMFaòŸ±Ö7â˜T«¾´¢Ù×uEtHg_µ'ðú™tÑû ° m †R¼èùkQ•…!bS-ì bžiùW‹ÅE+Íu',Òfı™©iß;Í8ŒÑT5*-ÑCÞ0¶çD•N8ü¸SUQÓ!ì宬{·!;ܪÛJ,•м`EŽh+¾ª{rýw"cA\ endstream endobj 529 0 obj << /Type /Page /Parent 1707 0 R /Resources 535 0 R /Contents 536 0 R /Annots [ 530 0 R 531 0 R 532 0 R 533 0 R 534 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 530 0 obj << /Dest [ 529 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 333 319 349 333 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 531 0 obj << /Dest [ 779 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 164 249 185 263 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 532 0 obj << /Dest [ 567 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 207 206 237 220 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 533 0 obj << /Dest [ 779 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 483 137 505 151 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 534 0 obj << /Dest [ 547 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 209 110 231 124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 535 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 536 0 obj << /Length 3490 /Filter /FlateDecode >> stream H‰´WÛrÛÈ­¼ò+ºø’A"À­Ú­-»¼µ«uEt¥¼V†àPÄhÍ|Hþ!ÿ˜‡ôe@P”Ö©ò*e™À\0Ó—Ó§»˜^Ìçh˜¯F:‚ÿá#NÓ LÃfÙ4HÒpóÍèÅË6…¼å=!´y5zñæFÃ]; ƒ0¤=ùÈï_÷£êñüI«;KÏHA”÷ù£ŒOÈ`Y‚·LÒ å> â³èmšÈQÿŽpÖBÏד Qa ‹Üªn3‘²ž¤Ú¢…Ë7ðë<ŠãצÁT^¨òõÜì‹îŸ¶)ù‰2ÕÒó3ÿâ_ŒÕgÕ¢0Hp0…s,Á~¿¼I UK·ZºÆ+| Q»ÜM­ù¤«ùHC£hš“DÃd¤)$:ˆc@ã;Z~˜1Ѹ%|hÁÔ!Y¥œÿvâ&ôÛo–„þ—OÈÑà‹HÄo»¦¨î`Wm›:·mk—°ªQs”¸ûÅl¶¥Ëz·(íç]ÝyZ3Å®›(¨@­aaòOmiÚ5]kËU×ugyiU—e½§Kœ)} ŒdÁàT¢^ /Áã·^„§Û¼0%X™ÊÍÖÓ<‹Eé@¦ÝèóÎV¹—â›Ûþ\÷âµ1ßÍœçrqŸúîÅëØí bç\±èIaìÜþ¦Õøö¶CÛ!vZÔ¸A‹•EeÁVK9©ƒ„}&Iä~݇½‰$Ý™$YüŸ…ˆŽB8/Ž=?V··žOðåúnÕ~m øŠÑhhº}í/‹»¢ƒ5¦–èñ ³C¦J¨vC(U c­lsë‘b²\ñëHhŨf´åk·ÞxË2Èé1Smc}Í;ŸB#jutl,š\Þ¼|ûÖY/Ñ™ŸwŽ—áµFÐ_Úªƒ®&!g U Î0çO¾ÍÊéÓVÎŽVÎD¶Wc  ]±AÕëªE#"±¢ó=?%…écL±XƒûÂ`À9´Nåd(*xëÅhûñá/i‚[˜ÖæäÉœ¶1Èì]2EF· œ'aÆsê$Î"4_¢"¢ –ÉQÈ “£8Ù ŽS´?HÇq&'D¿"¤èšDYË¢f(*á@$•%d Óæ2‚b‡z•µ•:T›¹´)JÙqë‰ µÂí”þpŸ'§?‰=ˆ­Elòú¢CÝ6H®E]‘—𾪅¿’ü $LØìÚ˜^ÙcV2äYäѯ£éþÀ ·žÄ±³Ý€0Ò9ÓžP­‹Ò92e†‰‰Ò“mÐH§`Ž/eËë5¯ —{S7dN§T)”K6nå &íq=”1 õ –uÜcYÇ=ïûdæƒçGxûfQ—E~Ô÷ ¿³ IøêÙQ1zeøÞ›rlj ~”ü­6{¦ÀäK9Ïÿöþê!IFAš|© À‡ª®›z×" ›€)ªÎÞ![Õ+ÐÈzÙ;ÆÊá9‰%f~T¯/|?¡Æ„x"“«3ãOn\­ð µáËäYÜME««Ÿßy3„髽t™f'ŽL ¹úò; ™`ŒhgÑòú§yÙò*Ÿr2͘ˆõˆVc ¤îi!¦Ä¡,bšêOÜk°®rçåüïѪ‚µ¹zßÈI¦rû:.8E&#ƒsñ:gîÁ#ÝUí(„Mð€u6˜žÕþgõð.’:J½¿¾¼¹yûæúêÕÃÂ2îk¥{gÕþQ­­L¹©‘H‰¨Zƒ Ñ´€ÎŸSÑ«°Øu\-MgvíV…-—-s0Z†¿4K_ ÷?LLÓá§"Á²èÔ‘ï6ÖTÄЈìqGBQ~aëñÉUMo+ž6˜ î*ª´iÚÞã4W%F–IæÂ`ã@4|*ß éÆY£h™¸a'O»BD¤jWR .ÝbÇ‚îÜÄš.bëQöžQõ̇pÜcRˆ‰Ò¡“B -o¼H]‡iT.‘ÕzÃtßЧ˜b1›bC–ÿ̳?ñv̹÷EnYۣ惊lðÊn¶ÝA쀜Bµ¢¾ÿþŠJÔ;ú=*,RŒj?âäÍÒd,MBÒ¸,@{NÂ’-ßÉ@”JI) V ÷RÔÞâ…ï¯éj­.©Ñ˜)D*Á•Ê…žQôu,GŽž¤3aßÏÆÔç¥' ­+œÅIzT´ÁMÞÛŽX“ÇýÒµ$C¬à¼;¶|Ç+&q0‹N®ì߸¢¥€Àâ•JŒiÿÀfÒóÕ2Üv-4» ܰÚ¢º=¡g»µ´›?q[VîÉsG9õPqNdÙ1–]ÊnIiW¾R©…v R u?Ó-{š|‡˜ÔN¿^{1–)š‰ª¹.ö‚ÐIVœôqYßwýuzBí é{Ad«•‡ü\èJ1çØÎÎ Â!„.Ðùã # ¨LwØråîÆäê1Kc»<€KhX o1CÌúö /ª»u½»[wD<È3Hö‹Íw]Áe2Šh«û¢©« µ*ç1æ$<ô²(%¿-¢Ÿø´<``m]Ž÷† RtÕdÎ3¹µC[hêϰ|íYuUsÁˆ¹mê­mºÂ¶ç…YømÉÿQKú$9þRY¬·™ƒÀñ£Ô½ã8#…géVsY•5ô7EÄ 3.lY£2Ȭœm~ï“£ß(‹›žLítÊ;²è]*û1oT|ûL(Õá+<ËD罆bÿ²hœ}ú{K®µü}]`o&þjO4ØÓWýøíÒÒž‰†¶lçù_F_©KÀbÝ™FW›;êùÚl;Û´MI‰”f»ÂC+dÿ©v¦ Î ô¾¾x&(Ä\¯q‰mÕ í‹aÝK„1áF‡¾ávï„4(23®¬¨+b>ÐÂZÉ/ñAìø€C\¦‡[€®ÖÑʹ¸+ä&+åÈâÁ¹»Õþ6ŸäÄŠã‚}#ßw¬yßì§AýЩOõÏ´äí–b²ai÷Xt&JO2C]•âÆ >Ÿù ÇÎ=ÿɶ°-Mnƒgó§~Ò¡4R/xïMSH9ý˜Ü§_oo ÆÒ.ZŠÓ);hxiW}<£û±hƒÅÁÅ<íΩ(à4ãÒÂŒ‰‚–.nŸµ€¦â ÛSÕ0çÙµç˃k¹UBRåÎÓš–e—DøqgY»ìÃ>t{6)-sSžV"„•0àcJã!¢è”³8×Tˆû™<7œnd2Ï­!¿VZ T$r$HNÔWï’5p´'#&b¬Æl/Èïâiö‡ùáéöº®0îkÎÐík„µT2nêÆöë >±õ:eœt@XÊ';Ž3dN‚8:ùî$ké¾–¹„%ÙÓµ…‰¢ƒ šky´ý\MKë±Úº‘Ô´Äü}ýk]ãSQ•P/~³9å±¢„ݹ~P'Á49k×XR‘‹‘ª† ÀBŸNKÙÝÿ¥½ZzÔ„Â辿Â%$£A  IÛ¤™4馻I»7ˆ×2¦ê¿ïùpñjnºîÇ}œï<¼>þ˜â¦©à²°©2®eLAŒ²Á‡u>Ù ‚6áˆ}[÷˜•¦âå«>‡lèfè,Ôü^MdžîAVwñ`ñz«ç:ÒL:b…p1râUÍ“q'p£VB/Ã` ý\8ÎÏ•g‘I¬ç÷³jL¹•4Šï8ˆ$EÈA«3Ê” ø‚ø5ADC#4EƒgkJ¶në“"a×JüKòÊ9–î-q217ñ´ÙJX·¥áÊ$}â:eŸ¿øê•Ì„ góÎÒêk_óuRµ»5ÜVét8p9jA0H{?.Êð߶UN[ /t9‰Å,Iïè˳÷u †6ZL,ÓXâ ?oj(ëøÌTÅœ¨½Ì%ï8¹gïX¨„ö"hå°áı“’b³.cm(ÊlMÄS¤ ÈX+æšô•|Ôû}Ýз9‚w“ÌKY¯1/Ý[}H´»áôÏÂöÏmVY)¯ZÒR"nõÐþ…`Ý#XRåLb-=Úié¥^üÈŠEP–J7LF4Br›tè­|/&©PExaD‚¶"$:ù™b?,}ž¤³„sÒÎ$¬1­2ï/(eüì͈» s¢ü`‚ËP6æ/\öfcµ$‚à\/#G1¤BÅÁäœ)^«š_žGESÎî% ÚYÑ…¾˜^™컳 Û#îý•/Â/\â‰ì£a…L\s»¬΀]ñºê[È“"ß‘è£/Dq4•.+[´òZ{Ÿ2–ÿùzG& £üâLäóPËO€#d¡Óleú8ð } ïÆ†t·'?Zºm%ë>ƒThJŒUÛH­+’Kc¯2–)sÚûÓ˜#§xĆºÎA[tÁmWÈRD@憹j9‹Ç–Ò2;ÏÐYÕ^þ%,v·Dȉ¢¤Ÿårxå+ÈVýŒ",K‡Ÿ'NV‘'Ÿ¦/Ï_pªoEµQݯå>£þýzBt{êÃUû °¸W:7ƒ¡PÓúOÂz̸ ¹+ÏÚvyM‘°ûÊÿ'bmÌP›ÉлúÃÉSœ Ñö²‚_8Q±Õ“dJÏÔ£§Z‚î´¿=}ø#À‡Ïöá endstream endobj 537 0 obj << /Type /Page /Parent 1707 0 R /Resources 541 0 R /Contents 542 0 R /Annots [ 538 0 R 539 0 R 540 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 538 0 obj << /Dest [ 525 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 496 712 511 726 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 539 0 obj << /Dest [ 563 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 299 203 321 217 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 540 0 obj << /Dest [ 529 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 317 106 333 120 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 541 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 542 0 obj << /Length 2810 /Filter /FlateDecode >> stream H‰¤WÛŽãÆ}×W4üDC›wÚðCÖ›5bq€ü?PTÏ cŠTDj´ò‡äò~È©®¦HQä c#’Õ—ºœª:õa½º_¯}!Åúi%}áá~Â4u½Ô‹E’EnœzXïV÷ß·©(Z½ÆmQ¯îø,Ås»ò\Ï£5ÅÊéO«럹ính=+úõ-xÂþeýã*Ó'd"ñÜ,Æ-AêÆ_¢ðõYôÅ|Ôÿ||u|ÏvdàÆ–—ŠÍY|>×Ý ¾ø–²q’Õ–­øËwâ_¿ÛN„÷d‘Y¥íYÅËø|*»ßÔ¡Ò‡V^om'³Äõ_­˜6_›æ{nŒ—õG|ÓœN'×\iµt«¢kq4®tñèÁºÂ|zÑ'ýu½’¢+?ŠÝ –"HÜ4±tÃPÀÆ0µzZ}X_œH,ñ®½1¸Ú#@Ëõ¿)`¡ Xèz!„n¤‰à×Þ©I¹‰?ò*dÆ«žÏ6ÅnæJ;…Òâû¦îÔ—Nè·ŸóC™ë§­Òªlè/ë—–}5‡›ËÝ~Føa( ÙôHw¯qd g0T«_”Èv À(ñjžJ["ù¦2K.WKswr i ù‚­²C«¨pPè&½l'z#ZÙ°™œÒØøG”µhj%š'#‡rßµxÎá(DÝÚ¨ª©ŸE׈ÜHEÁŽtá> êM§x}^UdUéh%22Žte@ èkeÖH'åä„¢ a<€ëãPEC„awl;±1¯7žòý?áš‘[åÅ1Òøe£ž[J$ÑA᥄Ž­Mªª­+4|6• )Ri¢e¢@ #2Êšjl$Ïæõ¹wð&ç…:aíßæ]Þ÷ÊðhNRJÄnüh³ÑNêÂhò¥Q9tY醬EH¶ç:ß•…ÈùÿjëÜuÒ"eø»jžðëÓÍyuÊ{9 É‹ÖOíöÝYð×ÿÍ‘Úh¬Ú˜³‹_UÇKîÌÒ=` +Š’O‡½ˆ`‘weÀ™éøÜ¬ç¿)QjU^tìK×LÂ逿”P+µU[QkG!²9!"+œXÛGû›ña¾)7¦ú|’&ë݈V°>âôû{ÛAÙ¶XÚþ{ôo[îö•âçWFÂjje ^H'ÒMQѨ>Žªä»Ò(¾HC?DÇË#/uýpqû;âÑÝAl¤(´qx»{NŽ?”GtU]ãµÍ”ø«DÁxF,µgvçú¸Û¨Ãݹ9øñ[–ôîN ?˜}7>DÇIü^òÍDÓù¼¦R5ì5m»RÝ„s¢VnÂÏÙeÖðú‰~!ºhü†~ òyýdæúi¯_§*µAÅ6žRU¯ä×FɪmÞS÷Ž_6ÇŽ(×/ç)gj :Ý[ÆÌ‹çmñ††ý`i;F__4»=ò¦íëp¤Ò_ßOÕ’±¦ýÅñì òYÅ¢ÌÇâ‹“Ëj»|·7N™ÇÁ°j¢˜çòdÆa r³=‚Néòîñ¼U1ŠçÅÝï–¯+¤ä‡õ‚kÓ¢$‚Ë>_’Ïk¡´†DÙ¦‰·#ETU¶ÝÃ/Sß×#õ&ÕWŸp£2iôF4–äó*ƒãÆélU«þˆª u- ‚7õyYJ½ÁH—{ÃÂöwÄýÝaºÜf…æÇ®ž>G>HSÌžä®;nÈó\µgš4jEV§ †0o ž·ìPJfxL’ä…zŽgx,8«í„ k4è‡ ýdz$…¹PÂuhˆL{ò©™gD¼cK {ªZè†ÉHµ81W‚ fë<AtËx‹ÊO8<3÷’É» ©zòn¨˜øQd‡&ƶ'ï1©xMÞ Á6Ote[²÷Á„õ/u%ŒüRåòoY;þh&1f_4@˜ño0zä'6z°ÙZ0µl/fÔs~Ø¢‹´äžÓ‹ªÁs›=»<¶€f=‡ÍéxÙ»¬»ËËZ_y€† ClÖe]j «íù³P_”^Y0“>v4V¬õ¢¦Îf%seCíÕ(;8XÒñæHþ9b“´xñå.UÝ‘[ (ùöúü…×2_Շ΀6@?£6V·dŽºm¿E“lÎtUλ&óñ€çØ€‹§Í«ØæZs[’ËHšYºæøü‚@“6¸ˆeš›†7  ‡äaÞ =Êæ­Uw†ÿ1§ð„&z¾Žùãv@ ­²AA3ºjÈ Ëã~ÞCzÁo„â-—Pn´˜$}‹?Úîì<#ƒZß÷s•o¹=ôR== H†Žüt’4Lùï¦SÀéô‰Éø4h  ¬÷óBÂ3ÈÝ¡ ›ñïo˜*xZ3æÓˆ•wÄØÁÀ$ÎVLÍ0|µMQæ˜vo¨%ìÊ²Ñ 1JøšmÞ1¯£9¸ÀÌÀ©;¦­S*¸áˆJŽÆ C$9­J+ (H½È7 ¾È/wÀ³‘—ñJLŠú£–C™œTØ ¹ÚXs í”Ô0¯¦('¾)'9s,ÿUÄ\‹¦VýuPïþ?M± î,DÐ -5KAcì‰ XQ‰©Ù endstream endobj 543 0 obj << /Type /Page /Parent 1708 0 R /Resources 545 0 R /Contents 546 0 R /Annots [ 544 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 544 0 obj << /Dest [ 779 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 92 217 115 231 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 545 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 546 0 obj << /Length 2635 /Filter /FlateDecode >> stream H‰ÔWÛnãÈE^õ?57&Íæï³;“A‚Í$È{´©–Ä,EjEzdMßÈ?äóª¾Å–7y X$«/U§n§¾].î–Ë€0²\/X@|øƒŸ(ËËî‹8Tòòzå¸9%ÿ”ÿ¥bÒ|iZà{ ¼,ßÁ7©ÁñxôœÐc´Å[^ GÕ<ú`]¡?måIï— FJ²âÄ FÂÔË2’0/ŠØeä ëÅ·ËŒÁÿj-—[ÜýæÂ_È4ÎÑor/ý…Z©Åp§6HŸ2¸Ýó#m* Î¢Þøˆ¦/ìÞ:ÌK© k'kSð¬¨V¤Q€BZ¹²‘+IÁ«J¬°pÓ×å^–ªëð&=­îé¸ôLŠŽ,èйn¸væ ^íŒÔfƒÚLGV¼ã¤ìÄŽf™ Jšƒšõ[Â1ÒéÈöcY×e½(cJ&–^¶ †ª­há-Y‰½¨WЕÃ(œEšZ:Ežæ˜ÈÄeª§ÍK†”ÕyV4u'^ºG`ªÉlf>åEᤈ—ã˜f-é‡g¯K šïôʪ© ]®†™k‚@^ÖÍÖA„É0€ ÚA­ ùÌ%ªÄ9þ±Œ6¨XdûVE¥¬C ÝõXä^I,‚+X U¸QžÄëĺ<ð‘:êP ¤Bzª›ú´kž[X¼?ˆuù"ZrñâÝÜ’ȈŒrÊÇž“îÔ‰QXÑñÃFtø5¢7žA)Ó å^÷…ÈãypC(+1Ú¤2Áÿ/2ÿ,»6”º˜ø8À˜œœ>Ê­9žè³Mñ±Ñ( › &ÐyBuÍþçTW[âÑ5FCJ›¦-kÇàÂÍEƳüŠÝ”Œr~5NuPBfzø_fzSW'ò„e17iN¸ÊúB´CTtÚ?·êB1dC;ŸMµ’)PIK7ÞÄIõÙ³ä Ã:7™2b-#Jè7 O%ÝEŠD^2D¹› zLÆ0ã•.ÊèÝWŽ -—ò¶}Þa–o²v©Ç²U¿u£~5xê¥/OòíÝòÓòퟖêå¨?Ćd!thF’²Ò™Àˆ¼*“^AMÎ䱟MÖí¯ˆû»UÖI)‹°RNvÏËÊ „ø£$$I”zi É6Ѷ=º3€AIQžÐÐ~Ç+ˆp~P¯Uù£øZ=~u74Îd5Sj!Pµ-r³=ŠPbßn‘Ï[ìÑ7Vë0ùæÌÜ_OÕ!õ‚áüdê3‹Ülò\³Þ"ŸU?Î'Xw£äètìïøÚsí³ÉçÐÇ&Þ•áV; ·J£îÌÍéäNÑñÃQÌ͘g‘Ï›—æH´MLBæÚb*Î}¬RV§Øäf{šH†cÓÚ&Ÿ×:†á"™)¨ï—ž%´â$ÀÙî†En¶G@W‚+Û-òy+ 9E‘±Â„V¹¾¨¸Ü[uÖˆ·õ´’fQ=uq¤àUÿqT`tƒC qÕ³PŸI×À,â@$à,ñÙÁû9RÏ„`®H´ë³ÞVê_T~sB )/OjÔ¢óÑ‘„†Ò{•RŽCA¢µ+ô5ûîÍ£ã‘~PÐc¸MNGÀÏC˜[Ôkêë´ðÁhŠVGf&PÃëM<èœ á|{8ð“cAš¤&8‰Ã\ 4·%“a`ˆs{.ÈÔíütðCªn{ªþ#¬T* _ØT ˜¾ú®àâÕ‘;=i„‹+Ǽ•œíʨ•DÒÔ¼‚AäTó]‰ãCJ 0D] †U0VŒ—Á±/™ªkûq¬ÔÆû¤Omú{r"%Kù²u¤!3SÆÌ|+*ötjx•ƒÐ“¡ÀáGÏB7rú¯?ÉYˆ“/£âO¢ãÊX|’Ï\/_A,®Ä‹ €g´Õ@ꦊ-Ü™¡áÐvgN ²ëãŽM>¯b2wžfUL§*fÝöª‚q>8ý"jíRÌ-µgŒeû+bsw^Í›ÜB]LK "Ü>¦.®€"]}ñ«ïokÂW« ‘Ô:<”Ôv/Š’W¸üš‘ÐETR]§Ÿ[¨­@%x¥Ú9Ä8‘ãf‹%”«gR•m7ß…˜VèK1‚@#c@ŽžÌµ%ö<ºlÝ|…5<Ô Ëò‰@ûv è? I®Ç2N÷ò][$×7ò –ò HY0>‰«¯ê¿l‹5: èU¼C6€cÙmÁâ_ÉEØHB`]„Ë’Í·‡È¼#ź@щákü4{!YÜJÚms¬ ÃZ7ÈÄP&^ óƒvØ«¿¾„üµn«ntÿK×ÕuJ £ANºT=¢_Õ“ë¾™dË™-ü-"Ì;Ù“nnã5YŸ?¶"|žl—ÏV*–Ä N²{ ÂðñYm®ž]Æ|Yá¶8бuñ~„=Fû77ßþþýúÐöð¡ípê½¹»pG ³ÔLµ¶É-j…™Evµ–ï¿ÿ+;Ó«ƒ½ß‘Q ÊVz¥ûÚäÕ z²ìºjÁÏV-®{Å‘ób‹bP°‚+®DÅŸ­XÀF!;ƒ™E>Ò9LA‘ê½ôþÎÒ>ñkn²Èõö4œx‘¡V!Ö%´W…ùÍ×¥úÞ<ò"{ž—þgDÜÆv endstream endobj 547 0 obj << /Type /Page /Parent 1708 0 R /Resources 552 0 R /Contents 553 0 R /Annots [ 548 0 R 549 0 R 550 0 R 551 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 548 0 obj << /Dest [ 525 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 398 507 414 521 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 549 0 obj << /Dest [ 529 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 89 491 106 505 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 550 0 obj << /Dest [ 543 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 127 491 151 505 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 551 0 obj << /Dest [ 563 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 248 491 269 505 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 552 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 553 0 obj << /Length 3626 /Filter /FlateDecode >> stream H‰´WÝŽÛÆFoõ“‹6C[â’Ã_9vÛ±ƒ©]Ä*Pt7 (j´bM‘Iy½AÐÇè;ô{ÑïÌ )Š¢ÖÆ: ÃKR3s~¾ó÷Í‹Åäb±Ìe‹õÄÌÁ?<ü8¶Ø Y4ì0v<¶ØN.^Ö1KkµÇauZL.¾ç²ëzâØŽC{Òɬ}½™\ò¿&Ö̳}~-é)8ó³~^üy2Wæ,rìy-^l‡ŽV¢%‹Þ‚P‹ú¯À¯3áX3׳CîÄlyËÞÝÍ¿.-HâuV³çßOÙ?þgÍ|WX ì€g–ÃÓÍ”½»Éš_e•+!OŠ•5›söõW¦ÜW® Çñ±ø¿) nnnl˳]^“VIj!*m¼:ð.5?m”¤W‹‰Ë26Ah{¡Ë¼ÈŽcº¶ï3øèǬ’“õäÅ¢Ãs±Å9FãµCˆÀÊÅ¿&¯Ýa¼.dÌmOè³—üâ‘5ƒ$^'Û].Í{Ze»F¿7¥~&i*ëÚü¶1™Ëݦ,Ìg±ß.ee6-oõ3+Vòcënì!e\E.žL¹Øsô“«AØ­úÂGÒõ×'¶…öø'–;Ý*¦jÑ…xxtÁÙGYø-ÎYQ72YiLÊõ1FE²5>ºB K;•ÁÀ¢3ëíq_Øþ§Ç—Çýqc;y-+ão†V‹ØŽïÒ{f}\±ãÓ‹Q<ȹdºœ¦'êQÒ">ˆ‡9pf½=î¸ö]/ÚF‘u %Úægú±xõã/îåcççoô÷ÅE[^™©¡lXpu—(Iýļ4³@ /¿g혽 ƒY"Çm×ScÓÚí(€«‡æóÚ ìˆ3¶zÓåbË4Kr¶ÆTy©~©,÷¸B{`%wÖ,ÆBBã#§hXY@¦4gi¾Ë|ÅJ}|%õ“e–‹þ«ìΆfʲæk£m¯Ÿ²S_jåZJ~Ë´h™–Û­„)«–7¢ÃA€†>ldѶ‘&[Jv½‡‰øNHlFÒH+"ý+›iɈ‡oâ᫪f¾íyqÄôgš À/zÊu[ å̵¡í:söêã®ÂÀÏʢ zàÍ‘2PEtdœçõå%•dË}–7,©ÙèÍA󼼩ÙßîÓ p/ÙË)v5¬ ÷CŸþâHž³r'«¤)«š•kö’%’,O¬ /sye=1¿6+äEdˆZªÙÿƒæI9ä¹ár†@ÜÕ¶aS®ñçE»Ëí¶ùf›ö;¦}—\~DjR:TÈŸk†ˆ¢uyý³‡¸˜I[V75S`Å|m J¼„ÕYqËN^kLdûóž@78¸ÝÈj;tÐ:K²¬ØvŸ7ÙŽ${‰ `è8+‘õPæÑ¾C®;*×9"\¼Ge4åµDÙU ´{ƒŠ•QªÃ!º(k·ç‘×9tÉK RAT4_¨«Ç‘”…=NiºlöÌÀÁ¡è8_î™*"Ö©2ôEãbx"-C{gí+9ŽFr&3½U›'©àwÖê³a9•œè×HN*.œ'¹éÅCk*›É"ÍËÁÌ ¶Kª„®>µ¬§Ö7!äèÐ"”sË^j½Ïå Ës¿°g‰ëðð%Wˆà¸” qeMG´££>q[kôFR>$„ 6C'W(ü+w÷Eèk3ÃÎÌÐÜ×V+öŠûíR¯¨ŒR‹.‰.OYà¿ÚQ7r‹ì|L`–ÕûeS%(qÀ‡6]t¦›iøn“­–Ë5ðôik”º®m,j_´ŽÁ?C2~½¡}ß~û–ž¹ ¾,·;sá3×AÜèڣ7¥þ4÷E˜Š&ìª.ütʾ}6UÝì)žÏÔñóPç_={xðwþ"kn¨¬ž¿ù–þ‰ 8¤÷§ÿ²3àïo"Fç`ÿ|xüÎÿØm†OfüöÐæv(9?ªN™·á8ßÉ€è`@tdÀÛŸ€ßŒ~RëöFzïjð¦l¤¦D]K=ÑäÇTîö˜ã: Ò‚Ö$«,5Dýz­©!nšhLM¶•¸alwD«IP±ªÁMÖÝ‡Ž†£ g)ú%O*P¨²iNi|Þ²T›Ï3"ب¿¥dÙv—giÖ ·+j«XGC¢#©OôP›o{^1ý†h¿BÌqÓ q±=™!&ÉÁW\+&‚ÿ“sS©Ú/-‡Ÿ~—.ãSá;޵ŠCõ›è ¡N« ˜Ëâ:+ðµßíʪ±f±"'Š3(¢QzÁÖ1eζ2Ý$EVoë!wpî—qñxåÍ;pL´~xŒ€«¬A‹Ÿ%ºMü"?â6Q׸Z´e¨papbAàÜלè¸1H²@G„½üÔT¹EÚy\žÜb˜‹1"V_‰ø“Ó‹€ß¿ºê¢&ÅDÜ Qð€T«ë©n¸1¿sì03lPT2Ý%&ÒËGî{AxÚlµ ˜XÔœgêº¦ß fu/ص̋¨¼†}˜–Èמpi7+\7Bòr_u{èÑÿÑvË‹²˜ý*«’!ÄàWöqÊ„¶ Çq¾ !b#“éÙxp¢óGg£jHɱœs<š’#ˆ©4{EÀ6Ùì ³ù V§›¨´G$*̸éÀgs¿wêûw¤=}þ¿õªij¢÷þ •™ÄäïöÔ2:e†NË\œà4œˆIèô×÷­$Û²ì@aà€Mˆµë}ûÞ¾~èô\Žœ&º%Ì€b—W¿.Ç2 %ßH„0‘k‰€õ'c¾]C ášÕZçm€”¨­¯ÌÞËÑq[u:R7ÛŽTÐÕ§KH}8•ž·pòùK„ôϛÝÍÌ5WØ¥__ÿ5ÒDÿ,ÃóÔ™Óä¡ir-Ô… iwŸe"…™‰¼“t×ý5tNoÖ!ÖÙŒylÃTšc©p[ºEDê+ÉYÁ~—{샫”zÐk A˜q½¼@PJ‹ê¨ðõÁPÊÁNgœt.™?m¶UÙÏTI>ôÔü¬UÃ)[ž°s*ßÌ$0gÀw»„môµšÐä;|¼S^cKz¤+S7ùšàʳg‹IÀ¾ÕlUœŽåÑŸ¶µ±cµ.nÂ]ª%–j Qm8‹ÃØIɨ[¾ *®6  `2£‡]QzC Ð#¡ëTÚÒ ÑS€ŒÒÆÆb×:­e¥V÷^nð¶æ¼[ÒóZ±eIσÝ{ó`¯í¹Ú šÏîL¶VÍ·íõ4z€öN=$³N3“ö ÌvÌ7f•:hlKØCZlí_ÓNczn±±9.PŽŒõ±Ó‚/Ÿ˜!®‚±Žøê~1Ô(‰ÎÈO+#`gì$ØŽTþ˜ûò+»umŒÌœd±Æ€`Eͪ²8ÖŒ„¶ Hæ˜'§E¿þ¼ü‚W ù÷A'Fnذ z̤V(ÿlk3‘ Ž~yóá/Óx* endstream endobj 554 0 obj << /Type /Page /Parent 1708 0 R /Resources 557 0 R /Contents 558 0 R /Annots [ 555 0 R 556 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 555 0 obj << /Dest [ 706 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 424 730 454 744 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 556 0 obj << /Dest [ 706 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 236 634 266 648 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 557 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 558 0 obj << /Length 2944 /Filter /FlateDecode >> stream H‰´WÝ®ÛÆFoõ‹Üt X{È刓“Ä©c¶‚µ‹‚ÒY1–H…¤||Zô5ú}Ç^ô›Ýå(RÎMaøˆäìîÌÎ|3óͳÕâfµ’Ìc«í“ÌÅ?üI"ÜÄXœ†"J\Ÿ­‹›oê„mj½Æeõ¦XÜ|ÿÆc÷õ®Kk6‹eûø°xËΜ¥/~¯èWræûÌùÛêÇEªOHYìŠ4‚?‘k”è¤>‹žÂÈõ‰¯Ké:KÏw¶~do‹f‡/’+'ñ:¯Ù×ß?aý¯³ ñ^AŠçŽË7»'ìÍCÞüCU{}ˆÏ³âÎY¦œý[ÿÕ†éëë«IWDxY}‹oÚ‚‡‡áøÂã5iU¤GC¥À£‹Ûmì§>évµðXÎ2Œ„yÌE’°ÈAÀpÇ a•ZlÏV3|KÜsoô®vÉ#°rõÛ Lˆ’ö_¹ÿÍ–©Xðç ÛdËöuÉ6eÑdy¡ÏBðüXø±½0¶y¡Ž€¹ú7¯^:!n¸Â ùsóüË­¾fžPÄ^¿ßõz Sùв:dûý#Šˆõoo®/²å(+S90=€½ eCÂÙM¿°|M’ˆ£I^nÞ_Ôãa9¾lÎjáZ¡€rDz…¥‘ʞǾ¥346¡¬ñ¸Á<=Kä<šÏ•C 0@ohÜ¥ª>¶G‚k‘`j¢ÝT'…¶ _v8}h³3VZgJãÌÀ:3èa°ô¥@bt¥Ñ^ïáZ”³Ä@i8×ëAâ°Cö8ÓfÑ;ø’Ã6ûìõ-°É¿v¨¼ñ¿\3W€ùvÜ`ÕÇÜôB '0»7m••Uç³¶""@énýþ'[ÿ%Ö¨]ÀéÖD'ԽغÐŽFý³¯)®­)W)CÖ8pÀÈ<~A ”¡¨! ¿àSýÒ빆g¹†®I8›xC±uVà™Ärê})1­üמëVüB¯¹5l‚‚bؘeÔóR{ÂÑð„Ío72‚ gêû-Csù{e ;”æÌÖŽ³ÅÙkKAôzxT«bæËô‘“D'ì×Ìq'æ–¶È!m9£,’(‹]‚õ-‘šŽ2ÒØu-ÑÔ ôŒQ«õùGBkÇ9rqP»fµé:Yž™‚PP ‚½(zElª²ÿ_âiºÈ_ß®~yýò¼Ø"4¯<ÃìuBNö/N¶élÏ×4nŠÜHš®$\ä&" †Ü@õìåŒNÈ(6äe¸eÙ.ؘU„ÃâyÞ,©ï£œh\ú\#"¶,Ò<löŠè™-ìdd€•cêðÈÈ"Ó5­¾ƒKlR.äf ‡Ç¶þc\ Ýü-͈ŒL<ÜlQfs2¯…¶upþQP›|‹1Ñ`ÚE?õE8ìþÞ>êÆIP¬P¢éÆ ªrÖêÂm¶ÅrÓöã=¦ "0Š*D 1+CÙ0EIµ¢œ<*d^ë–H¤£b<ß½å¥fÌœôçšOÕ±t–)̯á'tFÞ„Î;E‹Ö¦BОRÛƒ\ßæ÷§*Ói»ÙeG„²~çˆÖ “q¶ôô§ñõé‚ý¦<(tÅìpÜÛùy›Ó^›8&¥Ã1Ì‹FÝVËÈ5z²þBï»]-¢à CO ÍE€Uÿ­ÔbûIaµÂ@‚ȉC$“ æ6_—ôRšj)z<Àv±yJþl5Èî³\„äeDSNn"RZ¯qG}á ?ꌢr2¶yZ<­©¹F+Ïž†_P¤š¤$òÝF#U3òI]Aš¢"[]ë§r¬ËM…]Ñ5#·Ûƒ¬}~÷ŒxÚИFŽ677& D÷l@tšgT ƒYûêP5ë?e{ó¸0H0sóœ“O[Ò¦ÖÚÖžwˆæÓ5Zº~«Jiaž·Ù¾VcHQB>™wߌ¼Ý†WöN §¯âSÂŒOÇ<…æ‡ØN=¾@à‰àšKgäÓvx™‚Ù¬$hà5gÍȧu¹>uw{çþ®ÿ_äJ&ΈÏTzPå“N?-”ùò©ÛBf]©ìýL\ôÊàŠ3ò3â~êÜœ-½‘£ý$Æï|Pç䓎ö#:Ôjû×HQì‹+ך·›Ã´ìÊîù´•~H£@«&¾ß–œ……ƨ\ñÕŒ|Ú Ôõ¾Õ¯Hýô³²PŸ!âûR\Éñ´Øw0Õw>«¹Ú9°§y(/íñR=Ì4#Ÿ´H¢‹xÑ',ò‡í*5á#7$uó6ÍȧmJ¼®…m¢øœl—*­}UVÜ_š#㸇ÆË™—½²Òy~5³ýâVwê øE@µå|÷ŒŽ‹·"¾ëA0> 3¯±k½ç÷¥Þí¤#ùvd‘•N6Ë~Ê6UY³Ñ”Ї¤;ÔC´é3ÃåßäÅF± ßDÅÁ¢4@KÂåbì Ï·TL©â€¡w—¬>eÕÐhAö3½Yã² ƒ˜úé;~ªOz¨Òùû€yc&¨óZë(· Mã€"B^k«;b^€YCšÚ5wjKõ Ûq);rЬóew¯X­6z쀖=~7ìt¥'+=²è¹fãÄD³|ÌRZSè ±9ÔÖªjôȃ©,+[Ë׬ÈJ\ºa:4+š±ôÓj?díðvª]À8ž¦¿ìC™ß±»ÓqŸo²ö~5 B{„¬Ù=š™O[Rœ¿ŸòÊŒe“Nð{k|c .”d{v—o·ªB˜:d9Þ3`$äËãQÕ¢CåA½GlÁ¢þÒ { Iö-Å7×IœÒœX¤¼ÔÒÚññü?ÂË aˆ¢W!]Ñ I)MÔèÎ tA´1´±-÷÷Ï 51óy:ÿ]±-NûQ@žQÅîh­i5bPo”J´q7khYúÕ6N¥Æàøí> endobj 560 0 obj << /Dest [ 559 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 425 250 456 264 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 561 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /TT2 2104 0 R /TT4 2109 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 562 0 obj << /Length 1831 /Filter /FlateDecode >> stream H‰¤WÝnÛ6¾÷SœÁ@m¶BRÿm m·bC³ ‹lKz!Ët¬Õ–2IŽÛÝ÷ö{Ç]ìúMÚ銢­OäwþÏ‹éèt:åÀ`º1ÿáà C›†Ô‡ òl?¤L×£Ó—eI©¾¡P&ÙèôõƒÛrDmJå7ÉhÒ.·£kòSlMÛ%·B>9ÇëíôûQ¤Nˆ  vä#‹Ú>­IÔ\%Wž_õÇ·N­ slŸÐfàêCV-ñ '“H™–pñz ¿ÿkM<ü] æÙI-J’å®¶iõ—(Vê‡ÄÙÜšDþV•`J}¥§¶?¦¯ð’`»ÝÚ–c3RJV!iñh¤´qIQ»¤yµT'}31HaÄ=ßv|N`‡!øÌv]@Ý 1ZŒ^L;c8 ?¡­Ñ›šJ‹ ”Ó?njíøÔÆÿ½)o (WJü´ZâAEzW•cØ”iv ¨üziM|; oàì‹ë—ÖÄE»½º˜^\ÃÇ·oÏaV(F¨êAÞ‰ š…%m˜o²¹:§û ©6ñ Öí»"‡J¼¯à®÷"«ÊÖÖf£ÒÄ((s»ø‘K)ó]aIqòÙJ¬Kägj5ÔúÎbÈ$’©P ùåü‹a–,ãzgœT¢^5ÛWé;gc ÆÈ9`®É—j•6ÕÊâJK%Av»úõZ$ùz-²¹˜Ûµ˜?n“?®M]ôŒk;N@ý³óuí€}t>òj}‘–ÛÜ ¥—q‘ä·õճ C³—õ^ê¶|~ RXñ±>Œt–&?ˆ-¤`®>UÖ‡Êì4iÐÚæx#óeŒî-!‰3XJ³†$®“ý^Àæª#[j±–Ž·á—RÀ à ‡p)ë#³Œ 5žd1—ä0‹4K«<ƒ¸Qt¢äñât²°^ÖÄË*NÄ2_ÍkÿŠºú%l—¢½P.óÍj3åfVÊb–M«Mõ©Nõ9ÇŸC§FSƒS+$¨»L:h,vÔ–^Þ8ÐP`ÆG]6¥˜Ã š³jrcIŸ6)eº¾ÃƪÃ<_­â_Ýf°Àu¾ÅˆTʃ>©}‘C¯… WV„'Äc³Vúr¡1W*Ï—Š‹÷xæ$Ê!žsš*›Ô¥¶.r§ß²Æ0¶§¾ åWä¬ÖÏ;—_a•  sžïÙ +¶¬¬ƒúzõüu¹‹½nˆ{sÎ5n?wÜêØeòÝîn=Ž­¡ Fe‘Qáò&Öhë3å(¬à”é­çO.»¼xùóOÎe9W…¼mG­8³[Yñà‡¢h°‡b` ”ˆ‘f•¸ÅJ«äˆÇ³qòl—Չ̬ÌÀÊÂŽUög ™k?ŸY’w’fJ f DÃw”5aRëù¼~̾òö˜ñÖadÖ`;žvjO»‘Û1ìÅg§ÊÙ»qŸ¹4Ø.¼å©Rã†}P‘³SS޹‘9ttX»-0û^‡½ÐßI;a½ «‹“¾ô€|„‹PIž-R¼æÄ·%v›]üA8òVöP.=ÜnöÜ>á÷TÒR§®¢í«äàÅÑY]Ïd¬±ë ¬ft !ÆðšÛ““¦vìPa¦›©t  ·t:¶¹;ž|Í´Ùëbª›iu 6²ÈhY o£UHU_C7£²‡4¨¹‡¶[k`b¾¹‡˜pC*õsïR‰47¿íúý£™Ä¦–‡×¥¸ðÆ,@ûnÒûx…w,yñS¼mÿõ'X;Õµÿÿïfzü@#6£Ê5zÀúíGàŽ›¼˜p}.9<ú¤îëÈ‘ÒK:ÌÀŠ=ñÑÝ×á¾™Rƒ(©÷ÉÝ×Á+º‘Yƒé™¹ÌGŠWýÇ•+‡r3©Ó+²žóX±âv(×ofTÆzƒšcݰýÜrGt /ª¶³Y)UÜ÷íÐÝ/Uý<¸?}·èËn¨LqªÄ{Aã˜ÝÀ(pH\äÅ`D¼!8¦žpÛ¶O¢k %@>0ŒÈyŽ›“-l/D¯ŽöFTLÕû<‰•Í zWä÷é|8œâÐvq†¥(Ÿîéú™ƒçÎ:eFUÜÔè¸Ño?wÜü`4áúA‰Súyƒ§æk«ÓÏ, b,vŠ× {V/OOëç@Ì6"vÄb‘y¬ÑaúòÆÿà ̓ŒÓV5æ».X`dtX»Í7Ï$:ìÈpÁpýüႹѡá·›ß|óÕ‚‡‡ †= ÆL7ZÐc´Ÿjvn)³ñb·ƒ2v`¤Ñ‚zÖˆHÛ‘æ†7–1Ó’xµªWÛ´ZÖ«<‡Ó‹´ 69‚~(:ÔìïÀp`eÉ®AsÅÖo>Œ6¼axp&1ÀGú<‹‡ á¿ÓHó2 endstream endobj 563 0 obj << /Type /Page /Parent 1708 0 R /Resources 565 0 R /Contents 566 0 R /Annots [ 564 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 564 0 obj << /Dest [ 537 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 309 301 334 315 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 565 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /TT2 2104 0 R /TT4 2109 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 566 0 obj << /Length 2738 /Filter /FlateDecode >> stream H‰´WÍrÛȾó)&ºì Já`Öë*{mo%‡MjM_"åA#»È" ÑJÞcß!ï˜C¾žü‘„ä=¤T%¦g¦ÿ»¿~¿^\­×¾ðÄú~áùÂÅ~Â4UnêÆ"YE*NÝ@¬«ÅÕM*òÆœqE“׋«Ÿ>{â¡Y¸ÊuéL¾XvËÃâZþ=s– 僦__Š Î?×]¬Ì +‘¸jƒKªØe&æß¼E«(æ§þãcwé»ÎÒ T,ÝTÜ>‹ÏÏu»ÁŽ/µƒ—dS4âÝO—âÿu–¾÷ E*’…ãÊ|s)>Šö_z_šG™ÕwÎr%Åïæ¿̨oTó]ãcý{F‚Ãá œ@y²!®šØâi°TXºÐ.·[óÒÇõÂ…XøQ¬‚ØA¢ÒTÄž CÃTìõâ~ñ~Ý#ðpÄZc0µK”ë_Éa¡uX¨ÜBi"ø³3jE*ñGVÍZÕõY§Xy“Bfñé±ÎÛb[7l‡s1Ñ¿ë¯(6X><æy½ãiIï~rÈIpJ*í»N„µÈöNŠyV–úN<ò~Q?@ 8†-øˆ¨³J_Š{¼´’[v“e¹=àïx®Ìœ{"ßVU¶4üø-½³L²‡Ë‚w[±å§DOv–>~*ÝjÞ°"u Kæ1p>¼ñRF¡ÐèF H!¹‚hY+6Ù“õ–xf•ãy:› `ÚÀ½!~}lZðÜ]íÚg±ƒŠ,$%ЈÏçm¥Çú$ർïÙïuû¸¯E&ž²ò®QéùõÄ“¿üÌÓbcöZ“ ÿÀNfÖ¬ÍÜÇ{ —ùê|3Êî?˜Âl½¤Ï·Ä†yÐ:ãŠhÔ}o&ò…¸³©ìŽc˜çìD‰Î £1fJ ©– C!%÷–ÆÒ5yI·Zу„*÷Nj ïê±l‹]Ùù&¦67­§ƒo\ã™o«*¦—[¼+%Ê †hóƒþ:-ÙJ)ϼdjQ÷Qi‡ÊI«yPeŠ ÙÍË̦zA%ÚÐÔŠ‰ ÒQ +#%µntóiM?)çFVS²ä»cåܾäÎ)× i”¬¸fYµLTòúUÕN4•%o¨§ž­§¢hL\ ¶~sL-ÒgªP ‚p$}<ßb'Ç:&6Rû& Ý–Úà8é;ý1©ú£šAZ‰µ1ª„„]„Àxã̦ ²¤¡•q¯¢®0i .y¦¬ðdWYÊÐiRŸvEªD»®/Ú–Ç ¡î¿”XoŠêBÓqÕCœ>‘RJ’&OcIÏ¡ª2©…h Äá$SÊv–WÓpÏõR˜æ°)òi†•¶kƒ¤š“WûÂzÂg ×iBP)²n뼸7…“pŠéáyØèZäNÂiJ\–© •œ/ðK-$¤¤wíóì±Üî¹8ýQY"%ŒÌ™(·yVŠ'‡6->Ë‚PÄ$.†ÞÀñR°•F‚ÆèJÇÀ ÝQ‹j{w¬h‡<Ž4a5¡µ½KqûØŠ»­¶ºÕÛVd|ƒÿ±"^É{Sé ²„²ìî5Þ%3Ñ|çÆQ¤U ­g9î=Û‘MðöóeWóÏ'O†A˜b·1˜šJV6î’õ|šã¨]d{†ú7ÃyxêfÚë{½×u®/ c$F°×¹6×ùÿC)Ù5û¾ñœÎ¡­x¶å›G s(£7,cD˜U;‹Z{cÊ#J2Ô,ù`ÁûÙRÛåøŒ?&{ì û¬™9L6MNð&¢ŽJrÎ4rqLR=2'û6ìøfnâ=”üÀ3•TÒÆÄIÔ?b¢üdÐè‹Ör\µnPh`VSUsQ…lB©‰cC…7àßm J¨Àº@† %ã%þr„ì)ÒÇpA&j}8ï²ÓÙqüŒÃG1P¼œÄ<(ûïìðSƦ,) só±aèT?|Ë$võÉëð™Çã>,ä›&ßÛñ’N}\/Ò@¹)Î&(:˜T˜Š¥ù¿×‹ûשQÜSC‰;¡Gnªüpöú+äol1X%OoŸ£w×ãP¥aG&®ÏÐ߯5kWPpb@=/D;‹åÖŒÙËÛ7ºþñûõ»ë#£F0|úïú”75pÃÛOTè2ïkyu…(v]ÙÉÀ_vy(Ë‹Û祉Hþê  ‘¨QçE¡ÏˆJP5ìD-êV?è= €âº×8}w3¥d7αPˆ(/˜ÆÇ3CŸÊEé|÷ï#Oyî(ˆÎ¨?CŸr |b‹4Vñ‰£Z`§Î5å3¯ò ¥sÓ°>20€—]=ோìB™h…¶ô‚ÛfÈçÅNð¤ušÌ~È–Þ÷S#Åé'i:K¤ ÁÄùqþòËTË7¥Ìœ¯ÿió:žš endstream endobj 567 0 obj << /Type /Page /Parent 1708 0 R /Resources 571 0 R /Contents 572 0 R /Annots [ 568 0 R 569 0 R 570 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 568 0 obj << /Dest [ 567 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 144 289 166 303 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 569 0 obj << /Dest [ 1659 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 89 247 97 261 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 570 0 obj << /Dest [ 1659 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 275 151 283 165 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 571 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 572 0 obj << /Length 2134 /Filter /FlateDecode >> stream H‰¬WÍr㸮\õȰʄÉ]gªfv2Sµ‡T*ÃSì9Ð4,1‘)—H¬¤òûûŽ9¤»RMÈsȸj²îýóuóC¹X–eÌ$+2füÁÊså‘fY‘ G +ËŸ»œÕí‰XW·‹åç/’­ºE$¢÷Ô‹pXî7ü¯U&Bñ•Áߘ³D³àkùË¢ Ë"Qh°’äBGÖ)ˆI®RmUýÃÛ0Ž‚P&Bó(gwöåÐökxs€&Þ5{ÿùŠýý¿A˜Âód©HyD¼^_±/û¦ÿ—ÙmHI«ö> Î~¥ÿ ]Ÿ®GBÃCùÞ‚ý~/‚DHÞ¡UƒfA5˜°Œàvµ{µ&M.’5l§Z$Z²$yδJ1¸£ÊÙÎ,Êщ„-ѹ7Ž®ŽÐ#€²üÇbùINã%“XHôd–"‰íá¾\!¨‚ËWíÊÜۇͶ®6vùCõƒ]4ýÝ™þy×;+÷öá¹­ûfÛ{ºçM?\2O Q$Ë2 ¿Œ.vr½7¥©¥*Vj§ò4ÊE¬¼Çß¶)’$”`AMÏŠ!.sÞUP jð®u–sÕOS‡¤£b¼èÄ®G~nR"#À reÈÿƒIpbIÅB]04/>·A=™‹Ô¥ÿúõÝõrˆý»‰Ñ8ù%«ùpê2Îb= ©G>Zv;Ô×#âëßßüüñ}ùþf=’âR`æÅóqÑ,^•Ûy½é¬íjÛ»¸;„;ó`v¦­Ý›§jW=šÞì&i¤‘ˆ/øÙ'÷ÀÕ ÙÁ½7õÎ<š¶¿åMÛ›',¨nƒ)ŒL¡o¼|rŒ7ºxýû<:ZG"¿pßyñ|¹êD‹âUtúõÀv–»áµ °ãÆìþè^«vMu·1æjÊ|Ze€ìbÜ9¦œž@ÞLüTuÝÀÎÛÝù1‰FvŸ`M(4~¬¹kT`òa¬þT…ò§I,¡‰â9oÖxäóY“vC²Ïp ȱ±ú/æ‘ÏóIšC×ßÁ‚icW÷šõɇã6k¿|rjè(Cë›S­ìtÜ%qñ<Øï·“„í&‰š¦ñ±¥Ï¡óÈ=è ÅÑ€®ëwM»r³L³Z÷Û(ðôuw寢SZl_±bš`·¼€Ò#÷ ¤ñcžS˜N§…W™â‘ÏnÑÜ=÷\{zn6}Ø´sQìžïÀS.Ž.Œæ¥ßUõ”S)Ïzø+ïxäó˜Už M1·“0޼Žx0­ì vÛG‡~‚QØ¿ý}rÆ,¡gn<´^ƒ$»Ú˜vÕ¯au„íäÔtpT9öh¨}òù¤RÐ/‡Ž?%M•EgMûÕå=òyúQJŸ-IS¥Ø•/˜õȇã ^8¡†©‰><•,Ž“Èõ²«wÍS40… ãèèóW_~)~Ý8©ÿëÆsü ñ`;.ŽóÐë¯|±,Kå¾"ML‰$É3f³È:(ÉŽM¬GQã‡è ‡^œˆ8ÈEÆÙÇ Sþ Ã@þñfKò¶c”ã`2ž~¸ŽvTŽ-—š;š‘d&–{°øžµÏwÀÆ mnÅÙsÀg7øð¼aô€Jn3ÏJYeÏFÄÆ€Õ· †&fÅuÆ"ávO§cþ„x“>ˆÑTlÓÁJÚ¾$ˆÌÕtÇ O§¼ewæü ‘ôxÏÌ ÑæÀñMóO3¢¶&CrNÂa¨üH÷äx\î0­?Š{6TU'&©=—à¹ðxðä\¹†ï paÐvYx28 ÔGê–Ÿ\ˆHo¬ i$e¿³{\æ@^Abân—eîlSj…ø,(\a0?o¶wÕÆ¡ÂLäèznᡌ…æ¶éB:Ú>ÉŸH$…ÕOJ³c²dVÿ-ù Z1‡ —èð;<³•i]WA‘:`HhÏCùŸº\ÂD[Ù„[~UUߪfƒZà2‹AµÙZct($úUmb*$6 Žìc_ˆvAî}1†A©)Ó>«Ø¦±â^¸’ÂfRŠXöŠØ˜FÒ¦Q½…Y襷sGm¤N‚q¼£tw Á•’JKc„áI‘c>L9YÛa8¹¤¬µÂÆ/â'9.¾x²Òº©63Jíž“háÁm ±¦A1ªÕc  àT»UmÑ×.¶tå±`oïÂîÜâÆA ‹OÀÅDL@%ìÞíÄ,àø ¥üª½ÚlÛ1ŽÏ޵föbÞÊýÚX¥°õ0ÀóߪMs/ ¡ W%†À°J¼tãcöH!˜ê{°ùŽÝò•-쪽gä°£ù T4ø°»'thSßbì ßÓ†bègÃc1%ç4G IA5g'Ü \‡Øì>ÑŽ3µ«¿™ È–µy»SÉ\ŽƒèÉ ¡”ë¦cs.z <ÆRçÌŽ ‚“5ý üëRÕqJß~˜Ÿ 8ޏ…^´”†äz§É¥´ƒ¿l{c•ô#ç?VíÍ5yŒ¯t|ÜbCÒÜ`Q@ "Õä–š·"L6 É)€K±×æ'½6çŽÚw[âÐGãŸè‘ uX•õ¼5éÌ —´6~Å Úµ±Í]SA´5÷¢Ær‹h6åóc$së’ëø‡SNÞ~Çúj… ÀTÂhHº‚+I äÒo‘¶=är`¨;X‘§„HöºŽ‰3 ¸`vZùHø7Ä£@0»È¾¬ À+cÝÁlû¿âñ endstream endobj 573 0 obj << /Type /Page /Parent 1708 0 R /Resources 574 0 R /Contents 575 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 574 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 575 0 obj << /Length 5170 /Filter /FlateDecode >> stream H‰ìWËŽÛÈÝë+jYZ4‹Ï¢,†(O qÛ·u³‡¦ìëyÖtŒ ÔÓ V _WQ1¯¢eW©›¾ZU­øàͱ ¼öæ!’sónAU‘ËŸ=JƬ~Û#a™Ÿ!›ø"“7)«üS{sBy×Üy.(W¶‘Ø\ÍÝî8·Ï—»?´Ø2'6U³ò2Ôe¿»‡a‹ÊN—ûñh2Å ñ<‘*+Be¡ùOWžŽ ¿1DJu@å1mÛCå@ÜÚœæ˜FW›Šª‘¼ÆH•:.‡GɄלlGzT39â#Zá¿GñÄp¥—0T¾úï2d.œÜÚ<ìW|Pºº!3µÂ NȦ_‹ XE­(:Ã6Ø~³kæ¦îÅ®΀åλbtÁÉŠô…ä0f\‡£¦`)lÈ”Õàs,)M8mPCÖ¯Þ®)ó”l&“ƒH~Sõ o?Œæ97ø å@¤´æ•Žc"Y½ phý_­ ”3€,‹¨ÀÖXxs£Xó©0Âúè•ÓHúº!úÇE2»¤’jª’†¤ù…–HX“.(Q"ÉòœMÅràï¡’¬lµÛšeã¡O pÏV{‡\o¤FÎk§ X‰5vF¡àá¯`RHÏi“v•fCm‡–[»Þpyë¥T [r÷+–»¿þåúÓëW·$ƒ$:ø^ħŸ»é.µñX‰Y ÔHÛXä¹1(( &Ũ*s³ÙÌ7lrùhýÿ´Pþˆª‡n Û¥Øw0'ö£î9ÖÀ®ÇµE ûmm‡g?F#OÅŠ‚?²Õ6µê£/0ˆGGð£|Ö³Ô@Ÿ,`Qa}þøÑËPÔzS}gÔèí¥$¨±Ø Rk®ÆIÐHV¤Ö6|àÔ1‡ýÞ~Û–ük?ëI,í; ¿þü±üïáÑüz˜6L,í†teà‡À@kiŽØÍ¯Ÿ¸N~¡Ç¯H|"ùe^4†ô ½¹&;ÿÆ#_{g§0ã³11œ£,·»x'Zw¼.sŘÃÙRCWlàò–â+ÖŽ>*$YýªCJåɱ+l·výuщ]³y2^ª@I$F'b7?–=õ#®ê·•‰©–”J*$‰gÅõŠéU<ÀˆùÙWöñüžF™ šiI,YÚìŸøáÞ¾ìDw(ùrM ˆ“œKâe¶û _رãÈå Ñá(ÒŽ à@te3 a:*ÌÄé‹¶ÞTärp_:tcãAšNTCåÖp7öžiœ›­@\´¨ìøÐ¹Àj&Ï5¥CÑí‹® ›Ûn‘Ñݤ¦§N°íáþ–¢j–èËúФWs©er¿Þ5VþiÝ{Ó~@îFÚÐ:§Ç^œX‚Á¶,T”[%z¬û5 Š(6œ¥„W å¾h‹Þ˜Ò¥y¼ç£PÒ‘#ÓS”=ùí¾oé#!&µÆYm¨)¼'¾Å6ë/·‰ùÑ æ§An ³VéÛ‚æ_FÕvß? Z¯3®ßÅË=üwißÜyg&åR7:딆ñi7ùÖ°R,oÞÜqäÒT«RΡ^y ì)@éeÆÇÿL䩈A”©ÉÅÖì8JF~Jâz53>0Csåçád艣JŒ£’WκÓLÖ#4#ÓIìªû¢'þLL€*h›Ia ›4 þTÎR–3Äà°ºD5Ôñ,cHtA~G!¦ ¥QEÞ_‚thc×,Þy/Q)³ Д¶m,×?Ü*îÓUV'ÏË5I€Šì˜3D4¹†‹ÂIå`Ü%Á¯L£:m%OÞ¥^Ñ z¨[rH^/l›K{Srì IPê?ÑOÙT)ë?ß¼º½}ÿîæšG½µµl˜,¼jTfø©žGŸÅÓæfðŽAädª­šå•Øöö±î*v4ÄS”¡5 ÙﺺηÀoÕ0?Ú£8-âøûçª-8õø,ÐTp“éÔ`FŸ‘J!Ä’öq_­ê¦A™Áë©pŒÜ`DS?Õ#ª£çjÂ蟨,‘¿·9êC‰ÞM•Ç÷-·ˆ5÷½Í3ä®5Î *.ÒÆ\:&RSrWçì(={Z˹«eCðlO‰‘²çâ ãÐ.ΩÎêöGVkUvaG£,(U éËéøW+sr*:ûh?.Á/Eé9XÏŠÀ˜¯–·$|ß_Aø!±#AÝ|ÈÁëÆfÖ†í`8>P#JâF¢‘ÊØÿ~¿ªê&›™89íeF|WwÕ÷zN¢Íž{WjªÌÒ°“âk؃†WRGÊhâºxøõÑœÝ`Rß\Ø‚Þc(Ä"õåª9SÑkCsNî…6°*Й…˜DA Yz*S߬ ˆ ¡ËzZaÙ$Zó vÇ*’„Žk¶5¨Q/Ah3“áÍ]¸™@ZEîÍ\ ¿.áËK€LfB9gãÅ=£ñ“ 9ìv J‡@Æ“ "†1±~2$éôÒ{/YjOô”BÁó3´™uqÏ »–6"Π¡xLã²3¼JÍÝ Õñ½êø~Âôu#¤õÇ4««þh>íi>uhîÊŸPý”äcÒÕ¡mï¼èJ̳QɸëH)äM>üô‘óÉÆe$ò>m >|€hM!rÄEå\µ´G¦”dðlÁ¼Š³~˜¢,y±Ðìc7B&JHÜìÌŒ2ð-—ì)v¤¹®Ñ6þ²¤¹Þƒ}âyƒõGP«®OÚL¡÷¸¯àèÈ9ÓzI>‘bù¿œC²å#)c¡á/Â>ç¹â&Óg‡v4XáÒ噿Î*f|ÌoŒ¸?=µßè†ûͰ䴹/„šVîOM;i@2À’r¥îáÚ}LÄt%S‹<.ìOþ6†Œ=ÐŽg¢Ú—“#x5Þà@‡Ë±jf¡#¿òJ?d”k| BZæ¿ùÂOöï@Ë#ÿíûûW¢˜Ì’Ü*¯(žÈ@X,çíŠÎ)¿%žÎ“a¼Ô½°ùõõØEJñ(1LF6÷˜È ‰€Òb :[Dž=U„Ó« ù}ò »ªmFž)¤9Ÿ­Gw¢ÔuîÓ-O ágeÉiÖ-¥Ôdî¥.‚¶ÕáP^†Ûæát{èÁÐ:¸01îûÜ7Ïüûd(é–ˆ…h¯ ȵ’K¬Ø“Õ|×.x¢›Q?ÑÝ»OÿtÆþ ê2X§ÙçBþ÷TPì¿xñù³X®).³úÊ˜Ž—ž(±&$ ˜k4¶¼¼›×c€€Û©¥¢¯µe9}æÛË‡ŠÆKÞP0q¯ª§¬¬³Éx»èÆÈ£Î Ø`[13®"2䣔ŠâC¨æ†(RsXÈ€Á:ȹo)uõ·Û 힯ÌpV˜8œ5ÄÁ.ˆ8„hßá)ÞÊó±‹ñjªNûW|6Ás©k9W2›°1ƒ¥9ÉÉ-‹³·ÁýRsÎËHÍï–k$;Ñ9٧͉³¼¤£Ïï—¯˜ëË s´J/u>2laÔ·éÍöi!qÌö1ñS+W™, “ÜÀ°‚ó¤ÞÔå®h«ßËÛ€BÏÝé*‹hÏ×Ö³÷Êmëý÷*G-¸¸ÚVå¦7ˆ|¾ôªþ‰KµÛÏ<²ôÞL-Øl`Ó9ºŒkæê©ußüia…®pÈ*·¦-fX)Õç•ÇsûõÖ«OÞ¹Ølˆ+Q‚¤¬ÁzS¬wº¼+ÍIß°”¬²Ì]Qî{Wqr„"[®Î»Öã ͹@–kO4¦q7hÄëC>Zu07ðXüZrÿ/es=̹ × D#€R«'"SMZKß 1lR€f¡IªÊKãNõn9SHê왣Lo Ï»ß~6d‹Ú[K -éÓL¶Ü\9j‰Öp;~ó÷V+ú½e tâɹ±í…ð<¦xÄ+WSs )™mŽJ–Ø”Á˜Nƒåºôšýé±¾%Æ­¤‚Øé£¸:b·Ð‹T!£±èÆG®ó[¼m÷ñÿwjÃg›¥÷ŸªÝ˸Hš±k—]¶>Ék¤sLNôòöI½ìkeË2fÄÛxÅ1ôRn‰„a¾ë¯¼ã…w³¸aÞ†·X£»+t¬rWðhû‚N³ -ôÂêËö¼+,Ì¥ÊVË8q´áÝáZŽœ·…®&Ïu(ÉWL%˜¦ïºg‡ØÝÙ¨ÜÉ…H•#“¨a.ç¿¥â?}f„L¼¡ÂŽ:-Oº]6TûÒ#ÊPB1ðW9¬{.7R\ÊcY·æÌ‰H'â+˜l55Q˜êÄÆÐ~gDÙÔ¿´Á‚°ÒL£ìÀZD]Ílýâr)¾BsšÆé]Èà‚-†¸UýÜ*3·E[Ö )³aoDÜÄ?%ɳ¿‹1q·¼h!]^ºþGûEÂím]è·ñãH–yê:„ÌÙÌíA‚×·@O<(…Z‘”.Ó¢eq#áë;•6ÚRÕmIQˆ£ô±Ë{÷Šè5ñßQ(ÿ-!ñïèrdÿÝÓ-‘oî|Cÿ¾ïÌå×B®À âIá›[b¸èé\§c<Ñ GºKgJ¹óA›NeDƒ”¿Uw ª$矂ÚÎijh ëæ8‘®âéG®ì*cÉoó¸ÖïfChŒÖdsïq‹­ÑùÇr\E¦$~{ áÙR¢‘̽Ì5¨å±¨#ÛÑÍáQÏÖ“uîý%xé½+¨Á±iÊf*»Ëh0Ôjؽ…tor,$Tú‡…±Â`$G`=RAù¬[×óp°ÆM…q+ ÀÞû^ëLk·A¾ÙÀBâZ½ñ!šÜDølSš#ãò.ÕY$¹8";ÔíÔj€aÇ>Fýš}zhl÷RÀ¶bu£$î7XKÞÚzxÒàd쑳^ƒMΨöd­µLþί"¤Ûx»¢û‡@Ú$Ù:„,P² ›¥CUïÌcj5+»€BɃÕì×wì[½ûWÿº»»õ&`¢aÏt?z šI§‡ÃÇg'JhÚ/OQǟİNÉ©Ì<¬¬(Å*rAL¥Eͳ_ˆh'Ã×9²ÜÁ‡è•<êBO-‘ž¬©ï íw–ö@¾Gš‚hù„˜‰!JÅÕÓµ%礻0.sÕO္VÌ\þiëÙ!P½Ã ÿFÕ§á ÁÈøý¹vˆgÈ;!šGû‡±«ÐË•û¤ô;äÿv=µUMÚ™Ô5e»ØY“ˆñsË‘X!æ_Œùj‹D+êùÛµ²?7¿Æ!ß}üÛÿ…„÷6 endstream endobj 576 0 obj << /Type /Page /Parent 1708 0 R /Resources 578 0 R /Contents 579 0 R /Annots [ 577 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 577 0 obj << /A << /URI (http://www.pcre.org/)/S /URI >> /Type /Annot /Subtype /Link /Rect [ 287 631 393 645 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 578 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 579 0 obj << /Length 4641 /Filter /FlateDecode >> stream H‰¬WÛnÛH}÷W4öaÐ$šÍ;ÈC&ñz3È­‚µƒ€¦ZgiRKRQ<²ÿ°ÿ¸{ªº)R—›`'‹l’Õu9Uçô/‹‹ËÅÂJ,VÊþá'LS×K½X$Y䯩ˆÅÓÅå«.EÇïx¢+ê‹Ëë[%» ÏõwæÊGM¿¾A*œ‹_/2¶‰Äs³»©{f6à³-ºŠbcêß>Vç¾çÌUàÆÒKÅó¸}®û5V|©X’]Ù‰—×3ñ÷ÿ8ó÷-žEn$KÇ“Åz&nweÿ§n+6ȼ^:óLŠñ_vŒÃçÐ|Ïq³x5ö`·Û¹Nà*ÙÑ®š¶…iléâÒCt…]Z³¥«Å…¥¸ð£Ø b%‚ÄMS+7 b SÑê‹ÕÅ/‹}2…W¼ÃlŒ©ö(#ðrñ,´ ]/Ä ¡i"ÌíÔ$ŠÜÄŸdÏlV=ßÄ»øÄwRx-nôã¶Ê[qõ…ï7­îăx˦«m]ðz»Î$ëpö›ûÈAÛÒŽò]ÓkѯóÑ›íôÚ‰÷è¶›MÓöâ)uÓ‹-ŠæiSVz)ʺoD^Uâ³n;v¡YÁ6ÐTyJ'æÊU—âLFL&&d¼_üöVèú±¬õL8Ê#©V; ʸB‘#Ù´šÍ¯šªjveýÈ0ÁOüË?çeådn" êò¡Òî$rÄ'G ¢£}îä‚àË}ÕF7É,æl‘PòMÞ÷º­má훾„æM¶®ü¡²ÊVVt} ¯Mÿ!{‚!ÂQ’¹)¹˜÷/r™ù‰ ÕÞ ¸H֨𠬙üÛ…¿Ðo&/Ñ0×â¿Ë¦±‹Ø;ýø4vc´-­Øï[ 7‚>TP|%Ç=Z{a}ÝÒ^‘œsñU?¬ýé<:ÂÕ½ªPê¦Æÿ­xÚV}¹©p½1ñßËrö4ëf_f¿ðÔË{Ç/+*JÞ—ŸuõlaD˜Ö_øºÈëŒ5O{(ê6º(W%`¾,[]ôÕ3Á´Z7¸@”[J—’½Xêª|*±w7y'ªÈÄo‰'î–]Ÿ£‰èc‘‹Ë<{Äxþñ,x_é¼Óˆa¥[f{Ôµnó v #̸É']÷yÏé{h¶c“Ãcn;.zF5øVMû„oP0BÇþÓu³£ÎåIy½kZ‡Êÿ s¹×á@²¼À%6:‡hÀü ðææÎ þ];"ýc¶œ9MÄšM؉"¶æ YÃpš|ƒ™J7‚Ç~ë„ûKóêIɸNÙÌ–Ì¡FxEýÊ›+±[—å¼ 0b¹6ö0hPÃ-Žzh}£é†©ª)¼ƒö£ùˆ ‰–&cIMÙºï7?_:JÉK¢ÇMAÆN ÒHº¹{4Cár E?…O¡q€A å…¸%NŒ÷”8òI!k$Dâ¶üV$‡¸ÑQQ‘s?vÁ¶#˜h35Ó“3Æãp61¹Š¯(0JÌ#úà†FN ¯(ű¼¶¿h5–Ÿ(ÍJþõ †9~ß½¾Gyç”pž½&Jà&^êS<¾Ÿº!‘|ìQôSvö'‰íh£DnþÀ8ípJü°‰ÏšH‡8èŠìÌ PcÂãá}Æ­Àc™wƦ•bÆÜ†¹b²CZ 1z„ÊÍü³–Â}–CKRw3†  –T"‹»ö¼‹YB²èÐð‰‡]Ì¥í‹*˜K ®¹BŸœÔ§AÓÇ{çq‘:l‚ ±ã3‹-·ü,:裕¨Oû“–(¨ùS&VÌP¨ ôºybJ_b—:£¯Lðs?r¡è&€²›*•ÚM›¢Ø¶hqP.ÿ¥ "亃­¸ùN4Ì‘ÚÌ q¬4uÜüðÀN ”ÝüžÑ2a7š x`ì97rÃzîü´3s<ñU¥'ð ’M$éèxîÓÈ:Еq †Ð4Ê8äRôþùðü½þ?’èwú Ò#™bròÓ>£û*AÐ Œ ›cÊ¿ZÆÈ•;‡ðñÈg•‚‰Â##F’]0ÀÊ·ç§ñHv”"m‹å̰-cÚ˜n(""Ÿåo(Ͳy«7cÅŒ¨Æ¼uJ#˜ɤý³à9è÷ð”:< >9”õÉ>Áÿ—«Æ ¿Ÿ«öü¦‡ƒÕŠcüKLÄÇþü/Œæ E†¤íŪlé ¡˜ 2Ãa /ÝÒD¼1¼ÁÏhÂ=æ1×z`!j…Àš¥ììK–Z()þqo¸žu똬ø, nêצÁ´ÙØ…šB·½\.ù¼ªœL>Ïè3V^'‰óϩ҉G¤ ÍuLb“ô©Ã¢tF(':£ÍŸÅú.–eU‰¢1‡°XæB¼Aaèz |ÐÐDôÍ èË–‚4½Nž-í„!Â,{=ŠÖ ]i:óÍ¿IG<Ø äRlìBkMàŒêdF»òO²¸}Ø [0…O7ì¾ÖFÞ¤lß×®‡JÀ÷Ô^`šfÙ>túŸ[Ä#¨~¡¬¨! ±sÅ›•Ⱥzn2ÅÀÛä]‡`0NëíCCýx½­£ƒ&`å½øœ·eþPiûqÚC†Gb>N©å²Üð­ùKã2’5œ×%‹¶ÈLS„KÚ’¥#Ú߸ºÜs5‹Iû5q/I ÏT 1þ¡™:tÊ G¨{rÙucÇz·ÑE¹z68ê{:‚¥Ñ¸÷ŽhX‚Ž£Î;Ò¸{=hAÀ,˜æi¬è»!4'’A™Xˆž6=8¸}/¨Q0m*8Ì!:”¼Ò9kj=„ “,Ù½ZÒQ-²I+ˆä§bQÜPP¾¼"zˆäµýý@«‘üΕ·ïßR ù?rqO¢/¢Ó#žgÁYxF„ —Øû!ãðà5‘á ÚÚ*ª} µèíâX,z7gÝRGn‘z°Ro"ê›7ØâRúd÷ØWrP…SQ>µËOçµãW“69éØiÛjÙ0ŒÞ>,²EWÜEw3ñ_Ö«m·m#ˆ¾÷+y YØ„x'ô¡q„¢@ì±Ò6­ƒ‚–h›€$ iÃýúž™Ù]ñ– )òbqÍåÎì\Î9s[×çV Bm¨À?ÙCÙÉt4–Š1*˜-úw}"ù yhŸ—ì.E.Ò<|':  @æŠØuçóT5¦=]€‹óبÆëÃü4/\@}ß[„EVõ¡³jK°NÒ#°Â«"$‰(ýå–K!Ò¬Â;U±'t=}TËWŒ¿ZâîyÎ2gŒµHû¯E5C}:ln|§¤7¹úü#°rŽÔ€5†|’kT3š+PBâ<¸4½•L «ð˜gÍ…Ìš•¼Ó[üò¤ž˜v(Ók¡az¹üA›†8¦ä¿ÊX"BÍZ³ò—c%ï’õ~€Ø!ýÈy~d&T!?Q%Væ)XNܽ…"þOAù¡­îU.‰;®…ix¼$í»ž÷“Î)Ï)4gäœÒð¼äàoÍÛÉIœiUóþÉ© ŠAdÓ̲U7ÕsÜ:£h¤Ð&½u]ž) gÜ­òTéN ‚©Iå“ d™á•žjŸjÝ*ŒÑ9a4œ¡ Q&àµ>²Nž:—Déz]ÊR›‘–¬A¤PšÐÍ·å¨Ë 5\¤o¶¥aV~Z ìަ‘½áeßt}þ´:Á7ÔR·v´¡©„a·×ÔÑws}ß„,–±¡ºßÓ=[XVEø^Ä-1Ê Ÿ™ ‚Ó¸¡*—Šéù°üeùÇß–ï9„oEæÿì’» «7ŽKÕ8ùtVED€:šFÂf’߬"À‹q0{„¹NnÆ"i"*àF%Iÿ‚_a@ZoîÐ><‰DsÏS 9=Á ¿æo–Y·¾QÜD‹ŒèsxæÂ̲‡­nÑbÍ…1r(JÙœCA` ‚“~-Tw1Y–¢ïõo#l?뤤$O`'L0çh'ÉÌ€†[GFhN¸Å®ÏM9ôÚsÑ]ýÓÄk7~X¯™IÄå\»œ‰Ëù¼ËzAr56Ò×øˆp …8eAêâ]6E!}þLMy3ìxb­§2Bƒ1yjôÍ™FØûÀ9l‘ԣю„—ÓÙÄðÄÈo*Ss[+k#J8£vVíÐÕ' ê ú‰5º,\3›²í46ð¢I!ì ¸P‘M†MÜÚ"Šöõó~}ù ·y,êš« jÕÜñ/ÔU´…°IË$Å'oÌ¿¨·]@¡öÊG{¨1ý¶<:–âÍ®ºhI÷’$½#@ž“†ÝnŸYÖÂ;ÁB€ðÑS4*Ô©7¯9`*7ˆ•ªôê¹îÔ¾,7J[£ÂÓm9‘¸º±6f‡þ¹:°°vÌOˆb*+ñ“Qž}ÎsÎy~󚼎œ+ò7sÞÑ…}‡sŸHî£iîs/ögh*64õJòJùoôxü´Åm1˜!^šDŠ‚<ÈI§žß^x6ç­Z£ Ñ)þò­i—Å‘ž†" Ä)¨žŠ×”Á }]tGÛ’q¡7I¶G‚(‰£ßÓøX¬× z-/åïÅ)—UíÒÊ_µR:ë¢ÁejU<ÖÕFÊæ®nvGmÊû¦€ýŠî‚Ihÿ•{k>õÃ,·ÝËcƒ¾gÛÉrÏ·’;™†æƒÝ§wCN)6^Ë­žõŽõ%ðV6˜§ö¤G)ÄRVTtˆì{îÇžÆFÞ½ÔNI¤^4,€ÃœÏrÿmjÒýDöÊÍɈc[š#ËGÉaâtá@¡dõP7Ò$íºkÕ]Mz–e-Å^¬~ˆ• Ж/hSŠ^#l¹úm)¸…™8«Õ»?e©ß. ¨\Q} ( Æœ½W׈†ó©÷¼Òß\¾Õƒ­¼Æ@à­ÚdZ5BˆÉ„aÕa@6Âh1d`‹ôi®ç¥MͰùP> endobj 581 0 obj << /Dest [ 817 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 327 654 357 668 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 582 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 583 0 obj << /Length 4394 /Filter /FlateDecode >> stream H‰œWÛrÛÈ}çWLíËR"ŒëpÊ^[µQâ[EÜJ9Q “‹­(’È?æ!§»g@ˆ¢m*e—ˆÛÌôtŸ>çÌ/³É‹Ù,R¡š-'a¤üÃO’ç~FeEê›<ˆÕl3yñ¦ËÕ¼ãoÕ͛ɋ_¯Cu×M?è›ùdê.ï'ÓŸJoû‰¾«è7Ò*.”÷÷Ù'ÏP¨,ð ƒUâÜ7,ÂD<]¥F¦úO„§Ó(ð¦aìäêöA]?4ý O"]y˜Iwu§^ÿz¡þú_ošâ~‡w©ŸêÚ ô|u¡®ïëþ_Õn͓ĺlÞ´Ðêßü—ãíóÖ¢À7¸™½Å3ŽàþþÞ÷b?Ô­ZѲ˜Kú¸ °»¹}´â™.g“PÕj¥ÆM¨âÌÏseB?Iö˜äjWM–“_fC2⟳qHu@A”³PÁòスLf&À:£T♤’ªÉ¹~wyùéýõ®›¾º«vjS¯×5r€”tÕ¼mÝ÷’71‚F⇅ÍÍÙY³"—YUç%HùÞêÈßlQ•TW˜oÒ¦æûÝ®jz\ïªr¡–íŽßÕ_«F5ûÍ-j—Ó”ƒ@`I¦¦¡ÆÃò©,š"•å;/E $z¾ô)\«×s¬X>¨EµE ^Hɪmxéíºì—-í?һͅjÚ^•"ëµ}½ÛØATl;ÁÞ£²o·í®÷¦XŠc"šýîÐóɸ=vU×®÷}8( 2󺪶usw¡º–¢HV16Òïùް‹¸T_o*,x·êÕ¢^.«¯\Å,6¦‰ŸE”¶¬ ´q ¡ ! %š¥ëËÍV½}=»üøáõM¦?{4XߌÞóä ·ØÏ‚<"ÌEiNXè€ûh ºHêC‹è¾#Ì™Ì7ÉÑ(A÷gámAøq*˜“ æ.üÀ‚î%š¨ßïî@ªëÔ|\Õ¥ LÑ£À|™ê]OÈri í"%È5úã Ç‘¤Éýü¡Ã>`¥ËÎ3Hš*PéÒ˃¾šz´tÛ¬Ô×r½÷ÂŬԾ_Õ¸/ákª¨`=ŠhÏöh»ëà¤Hd½y‹ê¶Œu®”êÐrÝ–=¤µë­ð:xÐùŒñ³-wýç«?´÷Õ×jwA±—™£µ|ø¨ïÂĆç–LhO•ZñæCÚ¼\l=à]PSÃ%º\«%ò¾|{g?‹Føé)ï`æå¯}¿cú°7M_#FU÷vJyÙn°6o™'î=š›¿PÈó|¥jàÞ.¼°£[TæPÕ?§£]]½Mn މ×feÑÐLb‹u³¨ä^ à±.lª”U[~Ò©ŠHëÕºbº¸f&ù˜tè í]·2Bâµ.è[‚õO¥—Oû¾¥9úN•¦îRÓ|­d—’€š æÙ´‹êT.¾¾)×R<ÐfiÖ}µ‘ñѼ+c¥ð%”žÀô}â \aú1‘¼n<’슥£“¥<Û"/jvõDÅ÷ï>ßh\än¸éyÄÿôÌÈÈÓ–ùq„3±!ñ=—ÂŒèéxÔyæD t"0¦0"0 —+m;”Hÿ[Ä•ÇÏ$®02o—Wܹ‰æî°aΊœ5°Ux0_Ø*2GÒ\l`!k°&Ú]‰Âc~,Ù.QðÌjÙ¾©{ûüÔâ$š9éÜ¢!©û1¼ôƒÒ†v—Îé\Q~c´Û4Ôo_ãF[Õ3¤yéŠgmÕ‡Õ:.)4&:u\ŠÁ3Ø\þ~¬xFwª§¢" <£¹Tá§ê§pɆ©Ï‡Kz ’t¨¥!4V ÆÈÓÊD±_dG¥6”» gO ìÝÈo~-ò=»¢ßBü@µ¡½ôtDêF}Ïž°ÑHóàyö$ ŽF=¯XÃÞ^>)–ík L„{Ã4ºUÖ¬tY=J.<+C_½Å•|ËF‘F[[FG2å`å™3ņ•0§¤Òb"'ÿÁtcoH»"§]9i#‹ <-±?KTÌ[‰BtüeI# Œ$$„„ð y½ñ¦â.{_ͰøŠË[9•>Dös§¨AeP#3À10¬ v¹>©râ¦î’h0àlßo+UÂÏ{ìåV<ÿÙè˜IH|šH¢œLj9,P~Û!÷JðÚÂÄ3ø„è¶I•zÖ3‚ê§WÄ7XlgâLåÉøæ½ »¤¨‰—¼èôl'ŸeÂRi>CÔr#,5õ#àcÒt„uª]*gÀXïšG€G°e'ü €o[”œq†·ÀǪÊP»o,Ècß„‡ÂK¹‡cL`Ï1û®Zî×T<©j?‘*˜ëC º-ç_o-=¤×lCcê>ù _•=6³…ÅÆA•¶dÆÛOEg gË[qHb­pØ“tÀiÓñN ÖÛ*çqQ:׊…mEjÀ„0q XZËl=ñ :V$Öõ’š>5tDš‰ëE Y‰C?å™¶^¹n¦'/?4žõÃhÞÆu,oë¨=*£¶ýøÀ¨ ¯\ ¤¹#Û‚OðqFó=ÕÊ‘êS®i£¿¥-ßÕý¤Àñ ½‘˜â9ºŸQ#=už” >-Èœî c³žXÕ§³6ú‘ì›çÊ~xýpdá)“Uý£ÂdäWS´Ø¬¸95ÛÉ‘²5û ±@¨//ÿD½Y°[#yø,?Dˆx:˜Ãæ!ù6%Æ9ú”J‘äÏð ì}~4ê J¤$èq,¶ýÞ©]Ȳ†¹GéUU}YÐ!ÏèrȤªè÷ÂG“lí SIo×?„‰ž€G ǰXàå`ŒWݾ¡pèÐpÁOÜY)Jøð)ÂW›–Æ+ß÷™Ì+{ C‰Á[d7¤;_Îg™þÔ†VÕBéšDT¿!˜ÀÀxþðöøA礚% s)ÍY|JßRl{”ŸÍIä§æhÔyL»m9®u¦²ÃYŠù¡#» Œºè ‚;ˆ×–mg J]ÔÍÑêlÀÝ<œgc òd€N‡t. Ñ’ …_GºÇj‘•Ç ªnP•/Ôä\žNmÚ®Çnä¶qdHG–)Å ¦+ògn&HRævS;·îãÕ°’»Š¢·UOö±Ë€ØTOF£3˜³b!j\øòÔÙ`ˆ’Ž›ž£Cëû«wï®®/ß|ü@2šé·à øñƒfQvÀ§ñjR¬äÅYîÇѹxÍJÉãQç_0œAŠøÂ%6žM¯‚ºr†]z”Rµw ½Ñ‚fúN«­3ÏyÑXø ؘ6Å~£Õm%ŒlA€sR¥\¯j9LÌí-¸a–ɆàAoFH¦ÛÆ]Hüv–%›ù§[ üâÿmÎàМ5™¹Øá‚#ÝŽ¡}@t?`Yü` ¤rÈÉ·ÕR+ûŒnŒµ\KÈn¾çë,±ipD쳫÷—¿}¸š¡jñC ›Zy{²¢Dx8?åɨìÙc³4zÔh¤øxèY-áIaYï%3 ©99…ënh†%µ‰=³¨}Só$t|t£í€ÇÒõúah—ÿÑ^;n"Qð¾_Á$EÆiÑN¤´ÊJç°šäÀ0LÌÆ–ÁÉÌßoÕ{ ´Á#e{{pwÓݯª^+j ƒ¯« 5’eÈb×Ä›q/÷çÞ+‹F|:üúà+ Õ±R¾ÁïEÿˆ—bø±¸¯u_Wú.vk*ÿÀR<:NMkT:³ÌLîͳÃEº§îX•õc ?3^ [› ŽD„®¦³›·xÀ¤öäuçûþTHÜxr`Æ*,*¼t¹ƒE3YnÌ|«©öáeÍÞ–!×";óVÑż­S,5ã|@]>íÄéÙ1Jd‚˜ŠûÂíÈ@õ¥µKëø³ôCŠPç¾rDÞ¬ÏÛ'©”.ö¿ò$ÝàÌï(;þä‘Á¡ÅÆÿ]ɳUòdBŠ=“à9­—S¾jß7èHýk¹öݶNK™¾š"X:›÷s~@n8´/åŒí”ÃÒ:úϸ×ñ“8!Ffê÷K‡¥Ý:Í?_ž`ÚìÚîøê^ME|Ë6œY´Ü)fÛ^Î}Y«Ŧ‰ZÛaëóúf!Ϊ\t#¹ó¿|áU‚Ëø#kÂÌaØ`åL–^¤›]À|º÷)†f‡^;‚èRã›~—Š­Eµcªçâ©n*ûŸÐ}ÎqŒN\9Iæâ›`ê) ööÞb÷[W¶zÔ é\¾ Øs4BÆuWE3Ù Yú‡íäqHŸhå&¥ÇØ`Õ ##’SÒ†ÏV+pôj^£Þ ¨ Ç“ðXÿozt{>â=,cãNTßñ‹ÒÇWáØA fåíÛÈlÍ‹¨m`/¼¿eLÑðûšË—æUo†l’çz”ݾî¼Ç³¼¤Âztõ×MGjÕ ÂLò‘+ä‹"¸éâ$Ûì<Ù·<¿6*Z‡XÛºÝ}ܽýKUu·hØ.MšYåàÒ·4¹ÿîí÷½8œér_lOŽËœºPl»øfŸÒʵz¥eÙžáNMD1Ú¯5†¿1Ù¢ *ÅZ¤vc#ãp>óÞjݶ¨ ÇÆÁ_ü,Õ³/½zíñxíÖ‡ÂøÁóÑûU‡ùê‚èˆ:Ùtw.÷+q‰ÿœ»žOõ5XtêéïnŸê‡¦þºw S5\&Uȃ’iWïyÉ„B4.É\Åo6ùÚ{¯VE‚ÞVy=ŸLzÒ‡op/\-š®!ƒŽ,¼X"N.Çö8—·®•ÏÇÍK[žv©yê¼Îlœ×U´.´Œ‹™Ä‘hÍ¡q=´«%Ò©e&á6ê“ XaáFb .6ìÅÜD¨L>Ï“–“& íÉ$ ü¨»jå\5¹)ÕL ÛbÊ]òtÖøxaà¤4Sš#$ö„­¿óžˆ%ÀÈï÷89†Ñä:DÌ Ifõ¶+Îÿ±¯Ë=w¨V+P8[oM´†=%K|fa&š@ø ÒÞ> endobj 585 0 obj << /Dest [ 817 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 268 695 298 709 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 586 0 obj << /Dest [ 927 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 506 565 527 579 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 587 0 obj << /Dest [ 927 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 308 463 331 477 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 588 0 obj << /Dest [ 927 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 216 388 238 402 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 589 0 obj << /Dest [ 927 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 424 312 446 326 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 590 0 obj << /Dest [ 489 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 356 223 372 237 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 591 0 obj << /Dest [ 489 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 356 175 372 189 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 592 0 obj << /Dest [ 489 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 509 126 524 140 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 593 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 594 0 obj << /Length 5502 /Filter /FlateDecode >> stream H‰¬WëŽÛÆþ¯§¸@1VôÌð4{¤u›Â–´qp¥Ù]Ƶ¡(o7Òwè;öG¿sfxÅu×n`¬Å!gΜëw¾óÍjñ|µ2B‹ÕõB¡ð?qž‡*W©ÈŠ$Ls‰Õnñüå!ëïQⰮϿ}«ÅÍa¡B¥hÏz±ìï?È¿•Á2 cycé×H+ü¸úÓ¢` …ÈTX¤¸%ÊÃT¹KX€aYô”¤NÔ¿ Þ. –: S©rqõ Þ>Ôí-ÞiH’‡ê ^|{!þñŸ`™`Ýà[&² ”\ß^ˆ·÷Uû«m¶,$’e½ –…ÿâÿY16ŸM3*L±X½Â;Öàþþ> ¢PËÝjéZˆÆ•!¬[ûW·,érµÐ¢ “¤a”jeaž‹T‡q,`cœ‹Æ.®߬zgD[Ô©7W+ò´\ý< “6mE˜RâÏÛtì˜åÞïVA å_жÚÙ?·“ÊÝ[Š÷’5G>hŸYï «a¡NÞ>ˆas, ±}€g2yl×;#—õñ`›µßÔÚ¶h/9í½K‚ÓNÛ"vÒÅ×¢mŽö} î«íV\Ù # ×ûú£mZ»í^A‚(Ú†M¿bK.÷µÅî%ßFQ.ŒXêöø«tÖg)=Ò]×P2=ù’„”K8‘ã²[»þPÕ7bºA”PiS¹|W²>ëMé>#Ûà öq,CÑž;×q˜±NYÑéuÙž¦^¥¿¼øóå‹ €g_¿~hºþÅßÄQK ]R¹ p¢ˆ¤t¯KzsPÒ‹ßóÍœ,ŽÊ)]„1Њ Û`Öë¶Ú×Ï›.Ë 2*á,z1¦ðbzâVdw!ouW¸peé†VÀ@TUIo²îÍÏîÐÑá÷¡S„Àét¬~~’EF¹Û€=9…&#êRq Êêð¾Òý‘"Τzt™­Âô8»€Û1Þ-€_—T¥.(˜Éª…ˆD–W[Ë5ŸSaCfãêéHéIw‚pÁïDQq‹[>!Æ +ž•G÷ÂÉÛ”nÅ@“Ègl)öš´ïDºwP¦Ã(›@YgL’{k Ø>c 1¶!€,€QµØí7Ö½"¨_fl -­mÔßû ß1ˆÁ~yl4Ó.Y·ÆÁF-Nâcþ_Žz°Žž8Èåý®j Õ÷8Ø–Òð_+ÀÇ­›êúÚ6¶^[á=N0JwŽê¸1]ÙöÞ"¸Ÿ™ßfÓ¬ëPe¬4„»Š¾=yds¹9mBU|q)ÄÅp_ß¼ó®y£Ø[2¨ œ!¸ožàß@XUû~Îþª»+ë>‹ý5÷_±¡ÌŠeIgcùàv»HÇÒï9‹5ÞŽ<eg±6ŸˆµòCŒ]`J4)þ¨.î¤rUß¡>´îãµD/(ŠI¶G½S>|,·G §GÓ÷±! Ór$²™xç]¼+ª“fÜÔûÆn.8þeMD` g°Sÿiâx_Z+lqÚ[Ü50n8)9pkë›ö~uË5a”–¶¤*rïZ&«¥ûÐ^•çðG¿~»ðÝA4–‘ óiKR>€º¾¯]è/'åÛÓÄžîbwD»áWÄ× †-¯BJ¡ðç»ÆlÝŠ-¥•\—ÌʰåÁ nØ[w%˜$ùóÒþ“,›b˜¹DÙX±+7è Û}Iî ÁÏF™ô8½ó)ˆ[ /×£èb*fL|¯ïě˗ïÞ¼¹ü+/_ºZ¿üéÕ‹Õ%;öÝsǔԱªyþ¢sR‘¢–¢ô x^kGeÆ–c|Ò‘Ž;¦wh›ÊÏAÈ´Yr×ÌÊÃwC‰RŽèÉO×ýe¢Q¬b*ÊÄÚtʰ& 8È{{cç ^œÆçbœ:cZá£fÄ™è’(C,ïL—ˆqƒ4©—® 4¡éiAè¯õzv\rPS'Z¾AD»'lÓË®<¸*ý0QNç¹àÙÑK õŠ>ª‚‰#S9ßw~ÚîˆWF²ÃýÄ f_$½C‡Ì2ÖfßÒ f[z>n©û_ˆ=Tkî«ï›S…4¦&OÖМâñy¯":²m+o¾ݹBãlŽ[ËXè|"-û„ÅQKÆë Œ;~Nc „¸obPøxšU„<ÑøÅÖÿvbj´è…¸Æpññ%¡T"O¯ñ§jêÆ øE1ÜÓ4AAìâ Ì»Ÿwào™|}éäˆßHèõ¹ó¿Þ'$¦·ðè¿H½ÁØiË[ÿ¥3M5Èeê7LH‹ †öÁà' ÙZbh8¬›ên WƒÉöÇ 9‘¯z^=jô²i\_?>tØøsuÂ=š›óDàxëÓºA’{ꇩ45––ô4Q'ýHH 3—烡1G w m]óp-÷ÄÝ•”ƒ˜ý@„4¤_5 ¿Snj²0Í&ä´gåE60žÂn9f£Ú±Ñlôå÷ïðF®˜‘FžÌò½ÚSYù'U®ƒ'`‘ùßœ”—)+"×LÇ2>Ctǽˆ’¡ˆšr2¦!OaSe® (€ÖyüŒ’ª<Œgåu¼ZE=;LlRîZ_"å©Iâxê™l•‰4.‘^Eä(÷ùÙ¢Ó‹žz¾ãÉ*@LOÉêˆc=FUÁŠb≉Q4{|UÍ ÒoîhçÀøIT>/g¢óI:~8TV?%Ê#0±%ª#CñÝõ™1&'UÓæ?bºÁ2cbMŒúit·Ë&çEOw":^U²%–ž‚“/  4Wy1 „ûî?´G·¬™8ØM/‹ö; ™[ÏXóWê¤q÷Éí»w / l²õ>…­Ñ¡ÌÑ!ô4—4#~ú_öË­·qäˆÂïùÍ`,°›÷y3f5 #{!Ùdv€@–éYahI¡¤õúß頻nªyÑØÎå-/¢xkVwŸ:õU«Ÿ!¥²“’ª D-JÕsj{já³®ÜóR0³û~µ¾·àŽíZÖò¾-òD3Ò@¢ìá–Ø²r^ÓD(Û7•0QÕ—pÌ«Š°1 Nƒ`_Tè þ+$Ÿâ¬4ö±&•’@(ˆ52Èí†9¸b½ý«÷ ÀaöæoH'¥Ñ6êЋTü_ÌGزʯÂÈ´”§¨Ì\ÐAì¾ fù³(\ .L‹÷Â#9¯¸ÝV³×}.m?—¶ Ù„Ô ¡Ü"±J8Ûñ`ðJã^°ÞtÜ,$¤¬;ÎYjX$—–€á‚r8¢©ZÒÃÒÒhdÜMHÓpÃùÆíŽûp4ìvCuÙË%é Èu»vŽÚPúêp¥&r¥¦C{8¬—œ)M%å†y{u>Ÿ_üxEŸúaˆÖê[—¬µóõ¢ˆ=²54a2²wRñúŠ_£‚Oç›þs6»½œ­Q*ruÇ·1øï("šÉK\èbbŠÔÓ4lß0¥Êô‰'K…8'-_ÕQ&üB„±’°Çö ,ktµqdGŒ& dó(Õ8;ÇEŽ>: _4i$'VÌÐ=¸7é‰ÕզʴQ±Z ÊBêÒçäg§—[Æ:MËiKû2xßusQÅ^D%—âRIÅ$ì¹ uÞä“t­S·ÃQB\Û¿IÜÇnÖû"#Dì¾Òé@¢8*]¨-Á’FòbOHú#ú- iÕk† š>múÑ¿Œ­ÖQ`KëœïƒM;Û¡¶ÎdìUZ£FÃDáƒÍæÑò|eôÁà®Þ,¿‘/+»=bšuM­UZV¹u‚5"‚-ÈP@Ⱦ\Á_a0Ì+÷€¹Û2nnøIB!§¦,àë2€£¼4 `þ¿&|[ ÈA:û†Ø“· èÕ ‹}uÀ$ë€b-œ¾ßÞõ‡s%Ht7(ö»”¬4‘~['k¢F*½¯W—YY©`1Ø8¶Ï<Ÿ=¦PЯ¡…_•³›ÔX»Ù†€â pÏ¿ V¶ÇfGt:ÒÓ |vú³äGCXnú Ë´f‰ë]ˆ>¸QÈ%3ráäTí¹Qk(õ„=@›Õäj¬51zÃobpûÖ>¤—žká™Ù,ÌŠsð„WSµªkÿÜaK¸–-ÀQ¹-{ížvkÆÿ¸gCZQ–`yžä¸ÚÙ ï(ìLQ“‹¯p[‘RSAIjY“‘P{‘¢Ñh4 ¹ Ÿ¡‰ÙÃ-½S3ñsÒ·È9öï=µ+±Ò ìÀéæÌwEFìŠêN0%øé|6o1Æ]©&&ÕRWã¡ñ–;#ÏÇvßsò–€Á›QÑU¸¢ÂÄB%gE§ÊJlŒ Ð`LÓ ¦Kœ€—Çg¡],ÚÁS[߯Ö#!Éz#q‡’uzÕjÑìû˜§Rœ‡´qt–äkð—Q83E£ã˜Ô‹Ã6nW -r¤·Ït©ÑÂ*ýY•¹g¦g1nöÅ1_*̧ø„=‚&¹EàØ”´ž$×â0HáñU5Y9)Íè7^…|q G ç×zpù’@/¹|d4¶8Y»~hè2áqÛfz¡ñNLM·Ë§ˆ'`4.Á,²™ÐÑè^}êîdR$“¤èÏäeÄÓ-_ÅŽ¯Þ?…!©;<4.´¥™¤p­E/ËÔÝ}¨v[“9«?mÍʦ&åN ×Í FNü(æMi«æÑù»+.»`°ÖÚUûÞJÊÉê[í{°ô¸iû`£ÜÙ‰¼ì€ÍŠ™‘>EñúD]žµõë]ÚÄÚ<ŒÒ%ª_<€?gÆ/ 9 l>¼’9€"?9bÿ³”ÎðjÓ¦L_,F½›þÛZAnA;SÀŸbàëŒêí…(sns¨Ãä©x-\“"³Bd†£@¼ä“({òÒs üFÒóÝáDV8„2»ªvP!‘]X œÖ¶äbMÚΔm´Lãê°ˆÈÀŠx|æÂÆ 3âÈ0ÆÃ·z3JX8D㔩)bâǘ «ß·Õ`ˆl6Oˆ ó6oŒ5:[ã‹;iCm‹¡dó„¯k‚Z @#BÉpCM]ØÂ6yÄŠA-®ÖrÐÐWõ»kD1‡^ê–G»å‘¹M‚žð¯f|w0ϤÛ7è´K4^e1mÄàÝo¿q¢I;Ô7‘Ú.šÅcŸ£šàñ°ÛƒÌ[UÀVPqš=!Ïvƒ4¬Ù4ÕòÐ0 1¿Û%Šõ¼¥V×Ó[çâاj½ož1Œ÷pX/Éù00Aõެ™·}Þ¿¹ëgî/¯Árs¨ïyƼ‡|w¹¬äT~ L£uýŒümpRÚèX¹ÉºHTm¯‹˜øÉ'º£•H5ìt9I‹^ƒà´¢mkª¸ ñ9%cªfÓK*©:縱·–ÌRjÅê‹brkà‡Í(ÅÐxFÖ€â5&"«Úïz˜Ztößz6ØVàñx¸Ýr[™î¨ÕíÔÕ&¨7kZ‚Ýa»Ý4Öàê¶Hº¨rúÊ!|\ÚwÜîB*¶‡méÅüãåõù _¹À¯VW?~AðVÇÜÛô*pÞV`Ë&ÛfóÛê¾ÚI ¡„М¨õjÿü.¸;ìƒ-Zº¥Ïâ>‹» ®Òk_«uÕ,ê`ùëÓdZJcnq5‘‹Ïæ;ª~Z< ,²æö0–R­GY #9Š@·öÌêt}\ßà7¹6ÁIôR믉Üú̧7$ÕLC¡d©? Š¡Ë ‰ ,Ž\©3 È å·': ª&lÖ¥žÉk¥ç“¢è½õ*Â=)Õr¨3Lºì+–Ű“>ÐzI‰îs ­= S‹„±¼|ö¥5Q¤æ Ñpx–Sëb•Œòü_ÉoQ²q]H”çÐ>î±®@T|SS¦‹ :ß²nƒËëç—Ÿ§(‰¸óÃùüöæ´N]ÈÈ“Î4e´ãD7›²öx{æ7xßÑ~•bÓþ[ÿ‘M'E*ô÷l:<+‘åcJ§¶è(tG¨Q)€ÐeƒE}FQœ™ÌV̸jÙ: V{aIR¾_?0bõ®]˜B§ëªBëV /îÂ(Iy]=±pH‡û:'„¼hÞÚ3ûµ5ã’“­#^’-5†òLE9ƒ¥'ž±}óW»˜<õÇÅ7dá Àu·ÛÔ ´‰C¡\ · ±]¿Ød6V¬ªuHP°—| T¾†©ý˜ sŠáòš¯A·Ÿåß®'j*'š±ýc>¥šÞ°Ãô`ºíÐ&Ïå}_> endobj 596 0 obj << /Dest [ 489 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 509 743 524 757 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 597 0 obj << /Dest [ 489 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 481 694 497 708 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 598 0 obj << /Dest [ 489 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 509 646 524 660 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 599 0 obj << /Dest [ 489 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 107 445 124 459 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 600 0 obj << /Dest [ 1634 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 476 387 490 401 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 601 0 obj << /Dest [ 1634 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 320 316 334 330 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 602 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 603 0 obj << /Length 3170 /Filter /FlateDecode >> stream H‰ìW]sÛº¾êW`üpì˜ Áoæ-I•Œ;×IçŠÉLoÕZ†l¶©)»ÎéèìCÏ.@R’åÄíß:K,gÏž]¼-&¯Š"Jˉ „?|EYæù™Ÿˆ4½$óCQ¬'¯Þµ™X´<Çí¢ž¼ú0Sâ¦øžïÓœÅÄíï'‘*7ô"y£é;"RÂùkñÇIÎr‘ú^ž`—0óßl¶EOqbLý+À¨øŽ«B/‘~&®Äì¡în1HíÀ’l«V¼ùp.~ý·ãÆø½Å»Ø‹eåørq{.f÷U÷UoWl$”e}í¸¹ÿäOvŒÏG |/Áâcîïï='ô”liWMÛÂ4¶ôðèãt ;tË–¦ÅD‰JL‚8ñÂD‰0õ²L$Ê‹"3F™ØêÉrò¶À¦ø‡hŒPû„¼,þFËŽÖ#™&>ö±‹ ÉØ"¤±9Gç ¡—ɵ“xÂgKÃ¥Ù8‘—JñËôç7ÅÅ—©£”|3û\¼›K¼Žéžð”Æ]Äd? ÈÏ W^9êîyJNÊ®¥sާ }œ™;Ëaß c7ÅZšôšqS#˜^<Ėѱ„ý؈USßè­hw›M³íôµ¨j¸¯vx’ŽÛÀ3‹rKž(nµXîêEW5u¹ª:äPòÁIñi qT Wy*¶–”ʬ¥ `€B’N¯–7’¢2£¢î]vb2\k} §KûDÅÐ=@Ü—Ø;—¢±&ÌkwcÙÍꮪoDW­í@ÇÔ/×kx.íD-°l·ˆr×åßu+ªN4Wm³ÒöŽèë‚&?Í$3‹dœæü³iñë§ð8–ÓOïÊgó9 e6“‡!ˆé±i¶n»Òœ‹«]'6+ gÒV©VC’ËkðÙÉA,%Ê«f‡´U˜ÒW‡Ã\UCÅ£GWlw£k½-WÂQTuJÀC§‚ @B…#JHÆ›]1s7À gÏ,·äËfk&›A¤ä«¸3c~øžg¼{2¯Lð‚^ê|›X¼=Rd# íofVî9«âøö)ˆiIRÑz¾Œ«ähÕoã§ú¿Ž¿€Žû{I÷=l;y~4!Na– ó³ïLâúa`и¡Éómö$–DNF RÀeñµ©‘8nJž\•y¾¦ˆð¼†)2ízÙÁ.ÚkL°Ýþ‘kMƒM›%ÃÝè!1:¡dg¶_˜moË;-ÊawÕoŸ Ü4;Ä{‚ÞUð=F™r©Žij°h£vcu}qt–ˆˆ5Úê¹ežÈ Ø”d+’[û½ÖôM¾šï-ñݱ™Úyáãy¢ÝØÇ…ùBA%mZVv¸e »¾OL‰Ž„:ÑGÁ1ˆ"éË"½l* rµj÷Nj°äCûÚBû¾­6 Ò#rþŽ©ø>êå#²ÝûÐ2뙢åäàÒr«ktÔ¿îa[ÖóMÙ¶úúüˆ x¹àJÒl*"ǶY›Â³Ñ‹jICƒ5ïè8nžäÇœg,I}RÙóp¡M¹Û{òP­îD×ðøMu3õn}QEÜZM'NdS_·B—mGƒÇEÒµÇü—Å+TÇM†¢úŠ1´ÿ# ¦\¸ýãˆB-ôzÓ=ˆ;äsN£ûÚj&nÍ•…Õ=ÅNQb ª²9WçTš•éÂnÄ]IëÎÞóEèg'’Ÿ0+’o ^rÏ@~üpFúN2?˜OM[‡Ò‚nLÛ13aÇÚU'9°²VP%8B§Ú‘\æ@Îeå!ÉVM9Ö‚®ä«Üš¯n›¹ó´T£¨ø€–-_Q•€oÌèÆ#º\à 2gŸ)÷fÓ_ ž}Áíÿ%æsÃwfjh`0¦‡ÖÞKÝ Gx±#óôÏ£u'vví±~Þ/~ãlÄ83A Q69̰´3ßúú¥}Šâßç,¡ Lg$ºüóÌ0vj’á’WœÑy ÚhØË¾ÀfîÃ>©Sz} 2fº=ȵÿ4x?Hõצ¼n[ @]™²Dz)oªÚüªúä2Uu·âìíôÃÅÇ×_pû€¨ŠT¶zZÒŠ¦‰muË]]ß1Óë±|TŒ”-&Fv¹<&ÜùP1¥ô¸ë/@¨§ÛuÙ½0†{wŸ=¹êñŽb3)8­GúÕ%TÇd'^™É¶€–f¦×½Öæ¯b@€.ba¿Œ¬h»vn eW•Ýœ@ÁÝkÓÑ ªwC¨tîÒ> |¹h¶Ø5ŽâÝWÅ]ËeÐ^(¹G%WVÉI g2’‹®¼çë„‘ÎøˆY?áF,Pëèå Ÿ £¬ˆ½¡5ÃI ½´mŽ9YcÞ™OZª»C û.˜û q(g<ò)K€š™ÓðãÑÚ¡üèè†{ 81þQù8f‹mµéöºïî¶ìПwÐ ´g'ÄíD?Žûj´ß«ƒ~|mš[´âXν¸‚Gxž|3Lš ÍÁ…ùÒkn,2”ueq©£ãîÖÅ(ÿAYºÎ}A¡«$ë‚sⶃt2™Ô'MŽ’‹H‡î²HX-΂:q€Ö Îñ}Ñ¢=ôsv_ßçp=¹±b1tßíK»˜.æÖEºÒ¥Æz9¿t):ç~ Y.[ûÜeª»È­™Í(scľäSVÿ°+®Å炸ÈwÄá䔹olÞ¤ep*-qÚÌâ@“¢t‚Ò|¼™¦ÃÍ4=,_-9°CÐ*ŠOŽÈ @Ä*Q3ÔØ¹¤Þ—fî^-5OsX£¸ÒýÖAémÒ%Oÿ}ãùˆ ƒñÈOD¢' ˆ5ë±w²¿ì¸ÇN`”êË`È'¡ŸyypdÃÜMæÎ! ‚É7´×‡~g§š/¶:ÌžíjUÙAs¹åx$mP.5nÄcüJŽüc3uì¥ôŽí†)Ù¤àfƒÝÀÆ6MmçÛv¶ñ#+'dý%RÝð¥H|±‰é/çÒ¶ú¦% ùúaÚIºêXc¥Û°ÓQBO%h%ƨªäÄÉÇP)Ž-|2”ñ)åÉzåymŠŽ‘™vŒ5b9z ´•-žPèbñt“½ ˆžEsò^w2eu§× R„޲,’®Éô §µO0r5°\í8„`*5]Ô±"x9Ö»‚Ÿ.8˜—Üm™®S×Tâb»rËo¼áœ=³ä`TñrèC}2یϦQ‡04ô!1ð‘ÿ|·QdµæQM‰›"w\&÷-­PˆIøÓI!™Öµ,Ǿÿ‡ð69µÐ·é¡BßBˆ„E’’Ÿ¸‚ijâO²:Œb/ËNz4:DÌ:ô'LýÇù§Ü ò¬§t«»ÿt^í¼ Â@xï¯`„!(—B°Õ©CÛ¥J—ŒY’à$HW…(ê¿ïïÌÃI¥ª0gû»ïÑ„î *òö˜ætÀ¤@Í|&Â!Ó jЂKȼXFõr©@ ¾â¹Rƒ“i….ˆBÙ£JÜåÐ`Òhe;Ã>‘Þ¯í~[ó9ŽÈÈúÆ7 ] ôÕy5ë‹]ÊÚJk¨‰³‹íÈW5G2[×Sµ?Q¶)¤‚Ù·NrÜÇT×ààëÙlY4ÖPç…y‰†…Dîwò†­/´U¢¨Ihøy}I‹Â O'>š6Ú¹ñob1Žg‰v±ŽüS|8˜/Óì{+ië²§¿aš2jÜ$æ*Ly/é)Ö7É0Méc6æy²7UÓ™#:Uç'r (dñâ×wöIÏìÖòxõ¶!ŠD —ø‹ì¬…4è]ðEŽ©D_ýMsT¯9÷'Ñ[8YÿDˆW)¶¡ŒºÃ%>fAæË†Ì—¹RùD¨e¶íÔ«ÊËúáï÷È6 endstream endobj 604 0 obj << /Type /Page /Parent 1709 0 R /Resources 613 0 R /Contents 614 0 R /Annots [ 605 0 R 606 0 R 607 0 R 608 0 R 609 0 R 610 0 R 611 0 R 612 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 605 0 obj << /Dest [ 489 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 448 708 463 722 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 606 0 obj << /Dest [ 489 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 241 646 256 660 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 607 0 obj << /Dest [ 974 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 231 633 258 647 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 608 0 obj << /Dest [ 713 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 464 329 494 343 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 609 0 obj << /Dest [ 537 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 326 280 350 294 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 610 0 obj << /Dest [ 713 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 417 253 448 267 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 611 0 obj << /Dest [ 917 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 436 240 472 254 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 612 0 obj << /Dest [ 706 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 128 130 151 144 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 613 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 614 0 obj << /Length 4039 /Filter /FlateDecode >> stream H‰œW]oÛÈ}ׯø¡CÉ!Y, dÅp±±‹µ\ ‰÷–)‹­D"7ù!ûúûÐsïR¥Åf‡œûuÎ=óã|òj>7*Tóå$4*À~â,óƒ,°*ÍßfA¤æ›É«7M¦ Ï T³¨'¯®îBõÜL?hÎb2í_&õß où±~.é×håý2ÿÛ$çr•~nqJ”ù6CxÃ{ÑSbe«ÿ¼šÀ›†‘ou©Ç/êîKÝ®ðÆèÒÃNº©õúêR}øŸ7M0Þá[â'ºò½X]ª»—ªýZîÖ¼I¤‹úÉ›æZýÊÿÙ0vŸ]3o1˜¿Å;¶àååÅ÷"?Ô ZÒ±ØGúx àݽZñN³ù$T•š˜Äú‘ U”úY¦lèDZ‚q¦våd9ùqÞ# 1%8ŽÆ!ÔEVÎÿE ËÆ ë"™Úç¸Å~’Šíw³ù;/öSýÓíëùõÍÕƒn«MÙ´Åæ“ú›Ë;E~d†¶3Qâgñh?ÉmÆ©‘}‹¶BìàóÆ3ˆwyØŠ26ö3¶Šyðœ'®ô?J\¸qH˜Kþ›…rÒ_TëQ)­pÑ|*2áYÔ‚:JVÛ—`…¬£äàå^FŠR¦—’-ï(s5çÕ×Ð{~;ûp{3{Ðì,;´ä¾É6›¸ ÅeS;úp…'s³”ÃpÉ FÆÏ¬‚…aÔÏ: Dœ.Þ¹ô]€b凨ý-×[œ«…ÿ ëm«Š¦Ù.ª¢-ŸT»EP¿ô1ô€j«u¡^Cؤ ìºwÍÁpŠ:2dBš÷lÄàØõlAÓîPo9j× H°äþnöóüú=ªËo¤ú†?S¡%r ;¤'ç£|aw@žwÙ•íœgib¬Q«R-ö;÷¶¬[µoÊÝ NtS– 'rM‘³HŠáªjÊ–XVœú ÙôÆ}éÑÑ Àê{¯CMþñøšëâ½ø'`zðÔVâ¡~Ø7< ‘6ø‘·- ¬$#ÿê+Ùhå!ƺTH~* ¿F´,Òûu«*ÙH]ÜýóNÌä£}!ÿÒ˜ËÁ-ɶ4ØkJ̓üðÐF8c­3´ùT.ÔY>M#aB›¦hÃVÇ8ÐíWªÿuf™q¼à[¨3ûa’Û®.˜íM)‡=Qš%’‚ K-pGDä\IPW%Z)…²ØÖmùŸÖ•5Ðcйz CWŽÌHãªü\¬÷™Zo G‘^kìMyÄþ2ó“GÊEµGgÒ´™¿ä³zYU‹•¤~«ºU½XïŸJ€Vj þ¹ª /E–¨~0v€Ç«Ä¡vþçÉ]M˜»9fÍK%Àðr l :Ô\A…6ÂÐ…‘i'vjõÈÁZVÏû]É_žÆHcìA¤Cÿ 7Ž! åúÞÆLÀ38,;g{p„eN©°·—ãÑx”bØÍm‚ B•ÊP±Y@™¬Ðh&_ßó2ø=¬H wÜlÄf¦XR` ,E×Ķo¼)‘Ê-QC¢oþ!ßg³DÿLžÓOÒý¸©df·Ð­x8:…8»( s EБéd‘ t/bǤ‰b!e˜~¬e¢É F[mÔÔ ø öÁ®²¼ÙÕ¡¨¯H¼›žØCLFc·¦Ã¶D¡K†úxù¸Ý®K€ä\„â<$}n«%OÛ{˜’!,S¿Ayå‚#Éb™ ¸×ÓY˜à;éI t†ü‹úå”ÕÒ¡ˆ:z‰¢NI1É €lJ’ ½¯f ž¡ïÅ<޾C|p \~C“9ª x.wÜ%p bE÷a³Bb1µbäcʉx ýA3ÌQÚ™Áêr,ü8?•ȰÊDš¤í$²“ÃdÞ=rÊè©áá;Ðé£Ìa¼v’¹dⲎ¸p£±Wà, PSb‘>µ“{"«ßt‰upêÿKŽÚ®løëÞ#¹r}©ÖkâP )}bÞʨSò‡†MÙ ÚëDßB@|¼uN$®}Ü·°ñÌ„zB&«2ÉŸ»HÄT©ÇúÓºMÒÜ)£§j¹,w$¿]ƒ˜™ý ]C×WL@÷)ÕªøL«PnÊ!ÔXºÞJ×ÄŸÁï±tJQés_|­ˆp*LZðþŽ‹‘ìp¶å‰+#›; Xp¤–ËåFýJiÐÛŠšº/2T,Ú=©d¤`½öèø'vðè$uç ꌚ—î5Ç‘Q‡øe]mçæÐœ!OYÀ|¡•PFñX¢ï£nÚ•¯®—"uO—A¥â7d4!Ýšnkj5Ñ¿-èêHŠâŽ@造zý®ú!GIBÓž–[­{Ü1žöð‡Â,˜€"x…º‹¹«-Ôe~eˆ;G Ñòµ‚%éP´)žÊaå8Ô‰$䩟DDY2&‘¦XnQø‹UQ?s!¬Êj70mœ±ôpãJà÷Õ-Vî^*¹:Ÿ¹´¨`¥‡Ó—VIÌæó•¦†]…|˜º|Ê‘ý½›˜4²î²š†éH (ÙA 8aœ@1"P PóN1ÝTÜ Ž&}•·7î5.ttí8:êš½=¯ZÐÞs ‰sLˆ=Ùža±F±Vn§ MƒoÔTzñ¹­8p¤¤·¢–Î?+©9õ†6J¢ßìüœö–Û,ëî3튫 'ˆÉo¡z]2¸¦Õ©ÉœãÍj»k"QáKÉÅ–@žê•Åç6å2ˆEÓNõ|~ûA†<)cMJC$zÌ9(Çä;dÇ£ f¡Ó•ï~º}=¿¾¹º¸TnmwTêÇÍbì˜Ý¬¤‡ŸŠ3\f‡''ýÉ®)‘éÌ»Ÿóâ7¯®œ™eýR- ÉØÎ¸“‚ÌÜ2â02I|*ÿ£°“ÿ82Ò"ñO…'ð8ãëÑ‘z(únéÑ5ë–ÅØ%S ZîëE[mIú¬½ ~Ë×4»‘4Dt0ìþæõÝÝõÕÍì­ßQJÜ“;Ã*¸.Ã42RÜQâA}‰Žc­Ù‰ó¶|Ü?Cðè6ó ‡O¹†õÍ„‡rîO‹¹±Å]ë8ðQ¿ýxõ~vw÷újö ›vWQ$ *`'žEWèî£ã9õ©M©ô‰êš¦x.G]Í$ØÌŒ7ø ¹vÆ}7{¡NtÕ–ÿg¼ÚvÛ6‚è{¿b¡' ˆ “%ʤ¨šEã¢R›¿ÐäZ"@q’²“¿ï93KŠ’4€añ²Ü9öÃ⺠€ÎBŒƒ½ï­xŦ‘Ÿt‹ÜÆÁ¥qŒˆi'Hu,ç¾Ô­Zµ4ˬ>ì^9ª‰F0OÛÔ ô÷8¯Ô^–6›ôàÍ.l†/¯ÛÙ²—ò€?xx—2oèsû\À0ðÐA2ªaŠpÅ,¤:Ì¿*‹¦}‡fJj~ƒ‘Ô9ín,ü=Xx^ó¤­ªzñ/pUe¿TËJLD c­üØ©ûÛ ðú=xåâ )ª¶!sMöcª‚¢õ¿È9\ºGµû¦e{<¥Eþ I O QiSK§ie¦X,(àÍŸ¸[/ŽÙ®kúX𾣋é?6 {9AÉ5 ;™ˆ¨°XkI±q,‡ú®•Q‰ôäãøÆüîjCVwÛ@!I éžßÌeèi3Œ¯ÝÁÖiKl1í«ëÊ‹ˆ‚“Ûó7Û‹ ž±ªý>-íyŸ¹ýØR©Y“±œ?`r‡m 0ˆˆeâŸ)´ùèbQ8ÕöÃQÌCq.O SÛ [q¢cúLÜVð|¹Ê‹¡Pîûu PP; ŽV¢ ´z!¥£/‰¨Ô2S­íˆMì_ÈM•YiP­nd-·[å%´~ÒÌvWÄßÚwè9,‘–ºšX‘É:B*¥.››Q霎ëÚþŒTú$¨îÞ¢|j3re>’ ˆå•~ÎÜ#èTÚ1¡”˜*WïÓRØ@‚Ù[Õà’í_3z•`Šªâ œS_{ƒsØê¶Y~øJµÿj×~ü{ýH°=çdèþùàôâþôâm71 r3bs#™¿ä²åV±ͺþ8ù Û3/€©‚V]Ðü š 1z¶©ø}$Ÿ Ž›´Ê9¤)Ù.¯9ì5 ×¯jÅâ@ÿK-Å´b/iy”gºƒ‡¶¼úø™ÄwL°àš¨ódŸV„×0ïw]*¾nCLvö²¶ôghiúZERÞ¢~å÷È “ݰj<Ò’ógAùÝOÕåù¯Úâ…ûÔj©– Dÿ¿ÈÏ^eþ @êÉè%êPº±MCÀMÅxbU¨É§‚~M3öÂõq8ÈÀ¡†Ò«h< ,Hºe„ôª8NØ6°ÄÁaN”Ò‰^¥±Žâý5mLÃ. }³¡ƒÁˆáùX²ˆ$h¼ƒ«Óº€4ÌvGD\(GÏÊ1I ÃÎY T‡©öX"i(^tüy§y¯{;_z3¹^mÄÑý&šsõ«Üüóéá/}|¯Yø²––øÁh©¸±Œ(ÓV©Æ*ÜÕÈi#ÃZN®¶Rù®.ˆ¢3T/ZÕ®ôèd€ê#¹a¤«Í/ÿ ©¬¢P endstream endobj 615 0 obj << /Type /Page /Parent 1709 0 R /Resources 622 0 R /Contents 623 0 R /Annots [ 616 0 R 617 0 R 618 0 R 619 0 R 620 0 R 621 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 616 0 obj << /Dest [ 713 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 215 681 244 695 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 617 0 obj << /Dest [ 1008 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 324 619 351 633 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 618 0 obj << /Dest [ 737 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 390 606 426 620 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 619 0 obj << /Dest [ 1008 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 204 544 231 558 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 620 0 obj << /Dest [ 742 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 323 530 359 544 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 621 0 obj << /Dest [ 779 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 128 119 151 133 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 622 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 623 0 obj << /Length 4861 /Filter /FlateDecode >> stream H‰¬W[oÛÊ~÷¯XøiYX wy ÉI`œž8 "¥h›œJZÉliÒåÅŠûCúúûй,/¢”œS 0`-Éݙٹ|óÍëÕÅ‹ÕJ %V» ¥…ð$‰ë%^$â4t£ÄóÅêáâÅOM"6 íñD³)/^Ü.•Ø7žëy¸gs±è—‡‹/òcæ,|7{ƒ¿ZŠÀί«?^¤$!±ç¦hñ7òX Ð$ WaÄ¢þ­áíB{ÎBùn$½D¬ŸÅò¹lïá–ÆI²ÉñêöJüõ?Î"„ç¾…n(sÇ“›û+±<äí?M]_fåÖY¤Rü‹þ“at}ºšöÜVoàYp8\Çw•lP«Aµ Tº°ôàvûêž$½]](‘‹ F®)áÇn’ˆH¹A àŽA"js±»x½œá+Øâ{ctµ‡+WÀ%ó€õžŒ#ôØÃ …ç¾ÈåÛÕ›·¯?ßÞ½Z:`m qÚåW™—­Ù›šïO}7öRµ PƱXŠ XîCÖ8‹|ý÷ñ<¤åêàÜQ:)¿:/í]lò¿•u8êŒmèÔ&“h؊µ錤يª,žE[3›¶ªÈÄÖ¬»½“@ Äæ>+KSˆMUîò}Wg 2à ´P®ò}}ÆÅiÌúÚ¼*Åcmžòªk@I“=¾]]A¶€ÿ)$nG¿þâ ̹ª„)³uaDU‹mÞÐ’¬"ƒØ†Õl¦«>Óq…zKƒÉÉk²ÍÑðp… îѾµ{2üIdcÁ1ýjÉûÞò°‘¯IÚgüÉ[] ?|\ýüá½=àZEdä˜hàîX£Çâ=ÆUN¤êÒËÊú*›¶ÎË=¥ë<§|PJ© Õ¢r*ᜪÑ÷èæH–Ùƒ™gVª]¥Ï ðRv¦¢:óJ¬)^©¬ “•g“Ü|[;'òÂñ†Òá>d‰Ç®Ö’ß—ãÖ\/Mmìm9Â{H0-ó†DN ƒé@{ ÄÓó.Ê ïh°¦Ág­¨vU1î3|ç…ä¡‚ÝV¿ŠúœOÖmo™€¦ñUÀÅ‚ñ§ÒBÙ EjÃ…t:øë œ  LJ‡Ì&©ö¬=ª]ðÒ©/âÁýÕA‚lk’Ö™¯ŽØ×[ûóÕÑ\ÂÈ{ :FNl†M*5«©Íe†‡¹ftü £U880ްÓíÀ^_’4- ~‰Æ·ÙÞîÈKômB±¤…[‹PÚGl:B(Õ#”ŸX„D¹ Mš ̯H\tÈÔ.9oåp6ÁGÚBV‚Õ…oÀ†¬:íÀCSù–®¡dE‡ù+¥Ô%—è¥ÈZˆŒÂ÷ùºk \ªï£Ç™Ü@ÅóTÓjSôC,É…¥Ì ™²ÂeÔÇ÷†­ Á* 6…èË“G®²yÉ(«'A®™0È„’þO"ÀôEŒqš*i*,!˜’î¬/4´¤dÄÈ!·¨ùþùîXïC,`C(?½zwˆå’ºzÅ©·z BcvBHC¤MÕ÷± »¬Ø….‚»lƒ¦”¿ ³¬8Óœñû@¬¯•†sÓvæF![DpßÎA¦TR¾Š¬(ªCÃä(]_æíæ{ì€Jð­ån'uÞÂ{º @[ï$]ɤ›O{v mÑÖYÙlêü’yùL\ mß¡šloÀZPŒŸ7]]€Óªr&øÅ²ã]±º‡k © YÙ÷õóÅz¦’Ì·ìá± ¢Ae×EµÏKøk±$7 ¼,¨}läl‘ƒ|¥bÓk 7ˆO¦@èõå3Õü?¡oѱ˜Žhûï­—ô>Lµœ òžX"ûbó”oˆêtöcÍ!¶¸b ¦^{(Èõô æ@Ö">ûò†e¡ ë€þ€¼¿5m–|B`ûr]uíØÐ¼ctd5PªÞã©Ì D8t÷¦¦Ža@óÖý>ÁIN’È’ ùnyûæóÝGÄë’²‘ UÍf^¤^ÌŒ'ÄRû_h7ÔçNþfm.Fö߯&ʼn¹K«]wTŒ¢9ÌÊo‡˜èËØvø†.¬•‘IëYíéžVhm‡7 pPý@^„Y¶GþžÈþ5&ñ.gRZðÏðÉ–"?rAòšÊ²—kC]â‚ 7´£"h<É[­XµVd×KÙ2o öÕ7´s8ô€AŽäcѵZK<è[²>½æÏö&Õž¤ãÍ‹#´x û‹1ñ†P $à1¶Çü8Czχ&0@ €Ÿü©‡ˆ%ö\¿×sGzÞ9äB¤Œyø?ã:Ý›!Ö|Ô~8RMÈp–#°55•+wypì£EžYõïïÙ#’$í¹ñ#„^ŒDÖÆÒÊéñ„â– P‚¡{ŒP„¸}†e³?hëü{<<Iì¨Kê —ô,r‚p`@vÀ” ¸»Žž¨úxÕÌ1iÄAI¹©>™úçNkö ÿ6¬>H¾HÂDÆIë³0¥cl¦Z¼ €vs|òì,7=¨4%?œ‚R8€’e /EmÚ®.-&a`2´[#ÇfÑT²KhÚs¦—ºÁ”›©)Ñ{ʸòŠ~OX”r:¡òþwHk<ë V‰]M¾ü½®åí{DÍ@N¼ŽŒ»v°8Î;?öì¡'}[ŸG#„7‚JÀ+Ð8/±92`»ÄãÁä|ÊÍ1|ŒŠ¥ ðbº–ïÎR„3üH}‚²{ ØMü©2~¡²c =ÑdPc>²è—(àŠ—œyÂìÍÉAÀŸfÇ™5ÐuÔ¬ù±1Ó„ñüÑ¿þH9a¡Þ•P6ZœÖùiöúnøÉ^o„U¦*òÆ£™j¡ªåð÷Z:qÖµýd¦;æfŒé°¡E¿UA<]{'5S›ç¢cÜŠæ¸õ okÁëý›w¸òm!xêûD3Ïq-d$8ÍQ§ TF#”ÝÏ¡ÌOÜÈ;wP÷40Ò¶e‰/W‚íÁ$ÛÛßï”BwÔ3¹=1Ûcs|¨‹èì=*WùëiUÇjŽg° “±¨Kº4W6=–X·"³[¨¥›ÝV¢ì Íˇµ±CËÚ´cˆ6À 2ds“_( NÉÈ8SH«3æ‚“â”â ht…G$°Y1OsH»tZ\á©¿§Êt2Q–ŽÊ,'ëG½††ˆGàZšMŽ8#·ó1¶HÄx‡Á‡{œqÑw»5e·îMi&oÙVü袨@žÌ'Hi‚±ŠÆ™3¶F6­Ð|ÒÐè#Ó¥‰uÏp¸üË{úô*‰åÝ»?½ýÔÀQH~ ¡ð祘ÇHV<íß}jÅ=ðÑ81LÜËy(-¦W"ﺚ~tx2uƒËÓ è,±ú²-ž6b—wÔØ'‘J‡Ç³Þ8—¥vÀ¸T®wy%.•“BX\u‰£ ¼Ô—À5 £¨»ÿ²^-»mQt߯ ºh†€-ˆñÜÔ( ´N§]uCQtM”"U‘Rê¿ï=÷ÎP£!c i6–)‘œû<¶…lí«§/NNHpÖ4˜üÀã¡A#ë-Iý-&·š°må.Zf”5¢gwU»ÁSëê©`ëy¬»Ãþ2Ëi£ðh·Ÿ^Þüôpû…uyÿç™_òœ)ä@ù Q²­Íy4+ò¢'¹úºì6i‘Ów]$-F©·:I=ß{šŠœ€Âóøÿ'Ñy•§GÁtI³9s4I«=ÞO€†àÒ’ An•±§Ù9Ï\òÄeÙÑ"äÔ,¾rGžx9ßDF E‰ø¢÷ &Ïz艫Ä*cÑ‚¥ÇN•ï¾*z)XN® ÃÚK®zRï;¿¬t&i3¼:låqÞ™É;’¼3µqÁ6ºœðo:Ö²zG–X˜”`ë;ï€'vxi¤s.Îhœáwïûpóñ–°ÈРmLVBÍ!‰äefiãØq'kORöƒ†‘bœ9.d¨ýâqrRèœ'âΞ¹H}›‚¶ö&'¦Ä‘¤}¹fSr%a¾(fOR6pÚ’m³Úm<Í”­þ9ÍtÍ"ºçÂ#Ãé‘6'úÈ,–g±êg ŒO¯’o’kdv0MÌd¿®&÷[¤9ZÅ,-KÉÄ™Îäyb¸¸¦Îù4lÐæ1”9„ò+9‡'¯rƒ•÷£«–øØKÑLÒÉËèÁf$Ï™ŸsQp&¼K=¨·í@˜,'Ën»+h RµñIüª)´h'–B76ˆ‚Õ¹¥x‡¨#õž4Èý§Ñ^DêN»Œ’ ð;+õƒÀŽD¸"ËVj_릺šçؘ(¼ÆŒ3§¥· ÉÁ‰D» û‘k[ÌQœ\ƺëwÔž? 8‘D:àFâ dYôUÝöUÛ×C}t‹² Ô>Øë~ãÚÆ Zž ” *Âf@ÖöôìŸjØ*fp¦Îø§‹<¿pñ^6£:˜Ð¨÷ª<É™ÊåhÊlÄ#!¦²k‡¢nIÅ×­»+Dù6ð†¡»ž W®Ö~,Í‹°¦“µ™,)"HuÞ÷ï:há„ʇ¿Q8»³€JY·ß{Ûªh{ÚO~yâ» ¹˜Ô6_Ä—B苵åwfä·T7€”>ìÐZ.†=TM7×쥥ÙB[³I7§ÈtI5Üókjp´Ó*ZÆ×m$—Ô5‘æßg°$O6gUCZÍ•cU£Ì)RJn ÀáäµA4t“d«S±Ñ´^A©!=A›P=û™ºò¡"5uQQƒéô8©Aj²žógR,¾Ì[6ˆ1îë³.§Ëx  >¬û±£b×f&íÌ0Nä{dAà7Ö>ô\S­"¦cµ>yƒŠ}Vdа!©"*ß-&áÐ1ö€ØÛZ²™@ÆëQ¸ç®nç)P€N §w„jâ I[Ž`É,øS « ÐÏÛâoá;~á<ºOCUg&v|ІøìZ_1šO92…38w—bˆc¢Ñb&4 >Ü¢™ºÿ™àù‡£\pm"C„:á<ûö ²HİO ‡ì|°dÝÂyÛB çããÞ + øé$}±ÏU‡&¦jë‡%ßêÛéΦÖ/üñ \A-ו á– fg–Z³Dÿ2×¢Ÿ^\aXã¬z`¹ ¼PmWV¡g¼Ê’·³=È­ò×0ï ù¼Ô.Qˆ› ænx££ÿ¿|Žþ¦úw×Ôe=4xï³æô‡=:e kþ±!U³žOUó)’ÿÒH û$X5ì3qì©’¿{dbÏ%º.Þ-GF‘@M4Ï^q”H(²BâD,ÛŠï(ZyžJT ¨ë²í†ê¾mSë’jßR£9“•C@ µœD‚çs¡Ÿ±r ]e,²ß3¦WeEh#Ã×n¸ð¨*,Ã5^ WÀ%5µ8€tÌ[ מ|Àµ¬Ôn×É{¼ÐMxƒjêÓ¤7HÐÅñDêyáçXÄ;Æw4.Aô™žùäÁr[h&×HƾºâG½ÇC[5•f_ ‡}‹JEª÷†ý¡‚­y,šžðî¤×µ×œ-kµøkág{Rìå¾Þ ^ÓÉÃeÑp©ŽÅ¾ö…ÌyFgk>šÒܘRØÍû̪$è1ÎŒ ƒEÇeÇ¿B0̘PRéW¢Òˆå¹Áò+ï÷û›ôˆ:òp÷ËýíÏ(3 8]®j³R„…§¬S¤‹âž’ÍÁãÚåfíj=Àò±ãiçBÅ ˆ!•éÊ[¯…P$ÂGrÂ13åí§ïþê-" endstream endobj 624 0 obj << /Type /Page /Parent 1709 0 R /Resources 636 0 R /Contents 637 0 R /Annots [ 625 0 R 626 0 R 627 0 R 628 0 R 629 0 R 630 0 R 631 0 R 632 0 R 633 0 R 634 0 R 635 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 625 0 obj << /Dest [ 898 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 390 739 420 753 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 626 0 obj << /Dest [ 943 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 272 668 295 682 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 627 0 obj << /Dest [ 943 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 256 619 277 633 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 628 0 obj << /Dest [ 1273 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 375 584 416 598 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 629 0 obj << /Dest [ 1277 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 308 550 349 564 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 630 0 obj << /Dest [ 979 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 372 514 400 528 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 631 0 obj << /Dest [ 1254 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 483 436 511 450 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 632 0 obj << /Dest [ 1032 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 233 361 268 375 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 633 0 obj << /Dest [ 1074 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 128 347 170 361 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 634 0 obj << /Dest [ 956 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 146 242 174 256 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 635 0 obj << /Dest [ 537 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 387 242 411 256 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 636 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 637 0 obj << /Length 4286 /Filter /FlateDecode >> stream H‰œWÛrÛÈ}çWÌ[)Æ@Êå*­Ìu”’,G¢*qVyAD JV>dÿ!ÿ˜‡œî€ɲ7µkj̵ÏéÓg~šÞÎfžrÕl9r=åà?ü âØvb'R“$´£ØñÕl3z{ÞÆ*k¹£Ú¬½ýxëªU;rlÇ¡>ÙhÜ7G¿èÏ©5öí@¯rúëiÊúûìO£„gHÔı“«ø±9²Oàñ\Ô #™ê?ÞŽ=Ç»¾i'Vó'uûTuk¼ñtna&Ý­:ûøFýí¿Ö8Äsƒo¡êÂrt¶~£n‹îßySò$¾N«…5N´ú•yc||>šçØfðŽwðøøh[¾íê–VÍiYL%m4œ.3¯Ö<Ót6rU¡F^Ù~ä*bDZŠ\1ÀƒX5ùh9úi6ÃwÑÅ9ŽÆ>ÔE»œýã&×›PWÀ96þÉB 4t“P¶Ÿ>¤E™Î-l5ÖEYtOªh­PùgU?VjÙÔkã ÇÃî6u—¿áörWe]QWŠNª›¼Û5•;½úl'zÆO_l%µÅ«p`#éŠYh ”¯y¾~&öcׯ¡(ä8µøà¢aG½/­@ïJUTê]Qeõ¦¨Vò%k¬ÀžèbÛ½WW½«wݪ~ñó½¶ÖD›)sE;µ“{Kuµ¢jËÅÖeÄÆò°Ë´S‹´KÕ¢ ïô$ðÀ#é4>8„ߢÇÁzòª+ŸÔ"ßæÕ¢¨Ž•B,×ò€e–E^.Z•6¹jwÛmÝtùBýª–u£ò¯éf[檚•;L³Rm-Ï›œ7iEh? «$gWnÑ–yµ«x)B‰C š]Š.Ž_SW#:ĈEÞf I vù×Ζµ %±HÉ!ñhåI2êò²æÍôÏwÓÛÙÕÙ_-°]Ï.®,PYO-Ê tB,V |•SŒû1ÿ}{âÄ”ÊóÛ#­Š’ØŽƒqYF~Ñ›ôkÇdd$ ·aN#o’€f/Íàq°ô½õμ©´‰ÈÃÁJP×5Ú×­!F¼&D0ÔeY?¶Ä­6ï8‚~ý§ÿ±» ñŒpE¬®xH˜)GfÕKöÜ$Ý>É©E‹¶yó7ª]×»r!«·D4µmê,7ÚÙ¶D˜þ¯]Þv”ó‘VóôÂúF h™H2)…ÿÛG,Ð1ObQЬ,ÆßNàqß4ä·Õ-²íä v@´MúL’lì,ÊLm“s`ÞËgЏè?KP𱃼Éðÿ›‹Ÿ˜d3fä-™è«))Åo!£ '*…tß öT ‘º¤‹@”%:á)âàK3|‹Œˆ`<Ô*–o !e/âÊQJ¦MW,‹¬Àì‰ÊsHQ¤'.Úý¤,â0ªÉÛm]µy»‡~à%v¬y-“D¶1‡ŽzUÕÊÓ¦,ˆBkЩÊ5Auè‹î1‰¢Æl8:·G91tw“~ÝØ¤ƒ²>• Yàçë›óé¥5&"_ŸŸ]’GØæTNs¯çu]æ=DÏHî‹S‰fû^/‰­ è²LWi¹Ëí élè½4îjÇñbhnO-ÿáŽÑ`%’ËD—›û‰$­ vFÜëÄ{à;ˆÑ5uYÔù[¸Cr‡Á1Vî^Óú b“åe¥%€²È¾‡MhH¼B ëôÀÂþNs[~o()}-OÓ›ÙÅôe‰rwnùúµLxt}X„šóÙ껱xªgã^+BîȽ‰{rtr´ÏN‹=æ3Û¢Û׌8¹uàÝOÜ{= O°}î;:± Çü·°®³.c—‘J>ni/ügðõ6—†X“"—±½-!ΰºÜïoD:Yøƒ-Ñ5|˜J!þĹ»"G6ÑÌÛŸÏäŽ{ðwFZ>a\ºür¯ ¹ ¾d±àpí„l®ŸœÚcÖ1Ýä颮ʧwŒû^äœ sŒ<žª£ÐµÏæ8Ž{º^p ýì’…8\²‚à âÀ±RMÁîà~pÙÅó*¾àä&½“ŒYÛ_™ÈN³ °1Ÿñk®D¾¾›¾È5ô•ùezÁßµz,ʰ* à]qQe³Ð y@6ä8#Ä"£n%#vZtª%†Ò¥”r2Ýnq\¢“J+ÓÈpI]!.ó—hO'ÙkÙïZºH»tž¶9)û-öä÷¥?-ÛZÁ;Œ¹DøR[¡iÛÕM®ö4÷Ý~oýÑžT½í “d>IÆ,g¬‰FÇ&2u:LGÆ®H]I„Ø(b­xÃ]¶³´²Ãqò\%¨  Ä¸voò^,TBÉñaúÓÝÇËëßMŽ –{Ï–#ïÓ9ÊêIBèêœtý^BÚ(ÓâŒÈ«©¸¦JŒOJ^h.íRÎŵPZµàë ˃ŸÊàùIW¶\Ä y7Ì‡Ö fH-k­ÄŠ)\Q5¾Æò2Ù0…5žp:ÐÛa6›ásý"òONÌ?°ïÁãF¨×dÔüÿq^m­qaô½¿B}Š ÎV£ûB[éÒ‚q\ò`(Š2öŠìjI[Ûÿ>ç»ÌêjÜŒW×ÑÌ|ç;— §ƒ¸ç®Dâ!—ŠáÈ;(øß¦1ˆ´ÆƒAþ[á²Qá’…Âq%ž/Ý¿ª­c^ýÑjW¬gkÔ—ùÆI0ÆÝ:¹/tbÅ=7¨|pšg¢Ïgÿ‹{Ø=&Ü—®ÒlB}Crï˜}"l…})šŽL¢ I/þÝ=-8åúúýÇ«¿Þ|‚[éòÛ‹i’†>ìxL5P󢌡2cŠDé{\°SPe9n2Ø‹‘4ŸË¤1N&?Y1r¹Dcó;g"Ѹ7@kѨHŸ“ÿÕE NáÀ>v-'fN7¨W´U(bÎĘБ„}ÕdAÉh{ˆÈ#¸q*>kHŠñöÄ Ø%o¢ÐÑ*¨»‰Ïæ‰Eü®mË®¸UB³¬õñ²<(vΟ•¼&Ü“açî8ÀÓarѳY;R›_e€ÅÏVuÕµ¥~ñØý~©`æuŒõÉqCäê§Ea£l ©ïg¾²åjVZÎs>¤Ò¢¿r¦NbÝ¢,í°–Ã-¨dá|ù¶ÿ$ueȇß-ÀBpã±€ÀÁȰÕ틸°aµ·wÍaOD&‰ÍÁ¾`$ø5y!vT|}?ÞѺR{hÕ4§º¦¾Ðîá„B _#’òÏU_wŽ¥ìѶU‹MÓ÷hïàÛ_/9笂ܹú¢æ»ùfzþ¼ïÖí»ß¾;"‡¨S œòÜÊ»B>ÁþRIÉVÌù¯–¾@#¾žn&C$=CDÑîà1ëÑCñä¹cw[O-!9öå?a4õKŽ´·Š–Á³È¼œ÷j+&Ïh&‰ÈÓO'.Œb‡Ññh‹øžU-“›å°Âšk¹ÙÓÎ÷ à‚j˜» JëgU £z2ºS—œ=­æ×Ûs?ä}¤•œsO÷[ï¨#”‡ý±‚cC{ó²ô‘pôž'._žQ^ˆB$?šq]¦\—ûz ®ËU†Q$7ó(æç(òí`5ŒÅ·M:ùq<¦è¼iKží£S¾›«7P¼?¯68wèFMHä÷’˜#¶$K.üA6Ì$7y¯œâÂΆÌégÌžéÌ/ö|b/E¦"š‡ÈA“q‡Î‹§¹¤¤y:¨YìöG»ì L]ÊVè^4ª¦¦%CVXAýÐ)¬Zò3ƒÌM4øŒ™bƒPµ;‘é13< õÖ<˜~Ÿ”Vûè¶ÈOÌC™.¨4’ÈÑ3ÀÍÿpEÕüYÐÂþD P¦ëܱ-ûxi³kÂcâ¿c%Ý|ø°ù²y{Aááü‘øŸ7·>#£ØÉkÏZ·Ä% { ¿r“ïƒöL¦ Ð"D€0_xí5 ´Q/™É"sØj.Èõ8ðÖD.ä‡ñú‹Sâ|þ)ÁôÐþ ¶âàÀbßNg›'0†pŠft$Ó•mgiGÅçG©öïlÀÁ”¾å÷ûæp"íÎýúÛÝ®¸ŸÌ,1ðd>PìLï´SS‡.~€qõ:‚ʦ,çÔ;v•x ðtc·k¹WGÛÒokûSÛÙ=•&ó_µ^»µ»õ•}„‚uÊ ·uÁ óakÏpÄŒQÔ©ÆÉ¡¥5fjiYãµ"ÞCÕm ™óêd0lFmY‰7­Ä²B±¦SCdCn G i˜»ÖÔÊkîži3ÇÑî^S±¼ –,šŽ•Þë'äQË3 TGy>c‚ ÕD|D“º~·~=ÉÁWäëÙ[aÑ¢¨”%W=|ȯö{K§€GUÈux«@Ü ]ÞÑKÆ‚:ËÒèÖ{“JîvÛóíö´ë~“Ã@(h¢ä°*A>$¬Èè6÷N•ö†ý³lÁŸ͑qÆí§›³vòd©{H˜öÕýV(¡cÃ1; ^Å?Eµcƒ‡‡ ªÞ®èî`[ÚÄÄÿyŠMPG>ÀˆRY¾^»(«ö‘¾d¸ÐÆßÚæ¡j.‘Î}óù§¨p endstream endobj 638 0 obj << /Type /Page /Parent 1709 0 R /Resources 650 0 R /Contents 651 0 R /Annots [ 639 0 R 640 0 R 641 0 R 642 0 R 643 0 R 644 0 R 645 0 R 646 0 R 647 0 R 648 0 R 649 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 639 0 obj << /Dest [ 479 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 418 699 426 713 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 640 0 obj << /Dest [ 1264 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 487 619 523 633 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 641 0 obj << /Dest [ 1264 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 484 584 520 598 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 642 0 obj << /Dest [ 1277 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 395 550 436 564 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 643 0 obj << /Dest [ 1277 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 336 514 377 528 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 644 0 obj << /Dest [ 874 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 343 445 364 459 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 645 0 obj << /Dest [ 882 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 374 396 403 410 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 646 0 obj << /Dest [ 874 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 305 382 326 396 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 647 0 obj << /Dest [ 882 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 379 334 409 348 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 648 0 obj << /Dest [ 874 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 305 320 326 334 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 649 0 obj << /Dest [ 713 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 234 102 248 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 650 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 651 0 obj << /Length 3824 /Filter /FlateDecode >> stream H‰ÔWÛnÛH}×W4æ© X »y‚ž 1ëEâ1bff²ã} ©–Ì]ŠHÊŽçCöö÷aëÒ)ÉÉÌ>. ‹·îêê:çTUŸ/^å¹Jäë…Òƒ?¸Iâz‰‰8 Ý(ñ|‘o¯Þõ‰({㉾l¯~¼UbÓ/<×ópL¹XŽ·O‹ßäMá,}7ƒW-E çïù_)YHEì¹i«ø‰y¼Ðd ïˆMý[ÃÛ¥öœ¥òÝHz‰¸·ÏÍðo´4X’}Õ‹Ë/Äßþã,Cxîà[膲r\ˆÛ§jøÝt5ñeѬœe*ſ藣íÓÖ´çFðÿïȃ§§'×ñ]%{\Õà²`–táփݕöÕYÊò…•Xè0rýH ?v“DDÊ { Ñ™Åzñ}~†¯`ˆw)ÔF¼Ìÿ1ƒIé‡L‘çÂ?ϰ)ÅT:IÙýÛ¿dïÁýTòoæ,5Äñ×ìÝ§Ü Ýd|!åɧ¢zz+öÍPÕö+øÅƒ;¦®EÙn·A¼îj3;_ÁðFtNö š ä°çdž¦Û¡hÕF}©ÀU ¶ë©Ñeó¥ÀüʈvMNO3€³Ê’›X `ãoœ ”°Ž’­“À/8 [ÔtkÁð] ¨5 "K=•lE2ð(¦¤)÷ƒY¹"w`]ŠF* O1rämÕÓGÑîLG%‡ªÙþö \AÂÒÃ@´2[ûmÇFËj ! ¼¸ÒW`‹#‘( ̾qP–©R$ýq3žÝL¤v3ÃiœqÐ¥#ÄO"Àê­Ã/ÁKËd\>Ñ6–¤}½r”B4-î‚uohû¡äç#çۛ˕(ìࢮAÍÈh$ÿfÒ_‘Ðh'lÂNæ™{\6”ü¥¡ðªb F|© ¢tñÈCdÞÝ2vu8q•s]j•Fw¸Çëv0¯Å¾w–_³±ÆÈßeHÓ%cm3àøªÙÿ4v¦œeW$l”Ь«Í_Ʋ+†ªmø^¬«Úˆ?Ô”"Y ë¶Û:ಒ˙Êüƒç“RäÊìL³2Í€éeB¼ˆghŽ9%ê \LæóÌ`eÏ‚míÓ…Øc´U>ê‰÷Ý®7ç#·ßÆßW8%•÷dT'îìtcDpç Ì(Ø50qV@ãf%ªÁQ\ÒfN°ÓVë¡gùÙ—]µz@}DÄÞgŸ¡Ep@n”Ô|Œ{¿ï n„åÎsEÛÔÏ¢Û7=ÜÑ.»jz‰ @˜@›>CÄ›‰ »m‡Kî07)”ícée»¯‡ R®x,ºªhÀÛvÍšX#èDŠÙ®¦(hM4ëŠ3Nn¬Ñä4b*5·¿\ÞÜÉC½ {‰¦¢ãÅ®¯!µD!äžYÑñœø›¿ ¢ðŠûÚ(ZtV·BÅ…nb9uòB¼´ph›’³…ýÙ´l„˲î,ì ô‰ Úó±±91F‹ß9Ç2€8†3ÚÅp½¦ÒË'”s(‹?$ YPõ`ßN§¹6uÕ̶žçÚG UŒµÃ£V IEÉ#J¥Ae_oV Çåx 2§âl÷6:m²çÎ+ž{‹G°ÐìïBY}¾æ7Mgó´¶ø¿§ HOã w~êE•rQ@…©}²÷ÛvU­ŸÇ\Ξ©Ü`9 ‘Å *ÅÝ;*œò”J`±£*Î-Ér¼¥: ¼êlwƒ”¨kHxÐãJoÄ~·‚J©¨«(ë X5Ü.ÔÔL ‹³.¤)©,¿«ŠmšÒή¡›iÄûz •o÷µyKÇ…mZ '£ H¸ÔÈýj–±øO¥‡á¿Í>þœ½üyЩr½ñó k%sÜS ÇjI†ÿXù>xG/ÍÿþÉI€\®Ò#øãü±…U£1ΘfTØ@ð’ pÄxÆhdOʵšAßnñÖTš°ÔØ:Ù=š‘ÇëX"Ÿ›’qeÀðS œ¡jF™FSâPt•ƒõXáh%çø8§Ç£`–RrÄ%•ž KU*/©gQ2on1n û$ ”’?aC”Êw@Þä0xü˜_Ñ‹@~°Ö€<8+àue/5Û48(´c£À#_Î/”QäYAžþt~Ñ©æâv6ïüJæ f<‚è©kÇZzì©qx柧bcÙe‡M´™÷¶K½S|’nfÎrn$ÚЙb(FB•Ž$z’­¥ÌÈ®ÇSFÑ×·ÜõÎyEIƒÉþ¥f}›eÔÇì’ Ç%¶e¡¼ý”ÿQåðl }õ¿T@n{qÞW‘……ÔyéPÁ×JÇyÕ°8b’‡ž¦èsIøú€*$,ÿÕ©P1¯ý†JˆæR" Ùˆzír¬Z˜'BNèÇûi¬šê—‚€uˆ„„+Ý©oÕ„)Wh{bä;êÈQ¶x\R;‹ÉQоüÌ-ÉM†öåõ%?à ö-t°/@Å1 H©LÍ¥—°ûÅù”o´ŠØvfØwp SÂÙ|rØš±gžw楾’y¢f}™Òc‹Ë¹°†ö¶ÇÍ4¾³<¢ü¯4c¡›ªcEAÊÄŒ’ÐÆÝ’£r48 Q¿Ê³Pª/g‰Ì?ÓåÆÁò–9ž„à 1 '.i`»õÉ®}3LJO8=…£‚v¹ã(%t”•b|c†|‚~C¬l,‡ñЧ½k-&÷#6Êå¾ë  Õ`¶(+¨z:’@m¼$µq¸“t Û÷Øu³ nëX~Aë*H¾»®-MO‡ÈB¬X>ä'0¹`+àŠ°ºéß9®Èh.ÔòhÁ&ñ¨ 1°öÑ‚ÆHTÔ/Œz÷N¤LR?$LD‰*¹£“™)¡AáƒJ²IÅ'VÒ¸uóJÊIâ6› kƒ?€Öao"gû£°ã‘_Ä—Ž9¹Ñá6pý1Ò-ÿ|C‰=sÙkJåCñ!CÆÅ/óm~:¬›ÑŽ$ Ú„TÂ'µܪ]9˜5ìC†ñ†|K"e†3í2Ë@¸Z-χm D`8Ãõÿ̹I86q뎓§”C ‘rL_–È&@}]çêãl‡1ä æú·‚úZŸÜ› kŒÍð/Ðõm'ªí®ÆCUrXc€@Ž“è5h›g6ñ¢Šô¤"»¥{j}R¶ä3Þʼn2À•î÷ÂïaÞØ~<–$¡·ìwJÇV3wÎ’P5z4=Ó]U]=(4yÍ–Ý<¹Ã–Rp»W“DïQöž(ÂÉÝD`_Tá9Sx$,Ñ›#MŒÔ”¤bqä•ÌçÏ.4 ‹ôi=ÇÓϺ÷ãhÿÂ;$‰…$[ÑårPcVPÒ|á,ËK¥`ÎêåÀ“ij#?'³à-5Ò‘±¢8fg%¦Ý{ü{äþ©°ó8ÜrÀ!Ä8:ì^î7:WmáÞ\ L‚ÞÔãòÀÔþ…žû<*ø*WiÚ´)e©»ÖÜ4ÁòñCßIN3Á†ŸïO,Èk¥˜8ž *!Ù£«’~ˆ¬¶ç²K á‰6Û‡ëgÏ9xœM;¼óš¡«%> _î«™û¼t89$ÀÕUwñE¶Ì¶_Iª…ôSÜ÷…¯ ófµ+ý?N99jœÃlÙ {o…€»Tð™sYUHWï±ÈCŽHR·äéÐà>5U r†MUZòNž]@93ãôëÍÂÇãÉéLåÀ÷Ê!÷gÄÚ LêŠmš'v„;¢eˆë¥&ì„ÝotÎlòìúN¢Ó{íó© è'»®­§ñ‘OŒ¡#逗D6geÙ̼%žTò:kœÿCr»Xnñ÷yµ ±7øŠ6b?öªèj>‘Ä®0:ç+Œ&k#cí.<‚»®%šRiàk²ÔFr¬Hr{ÀÈgbÛJâcÿÐEj˜V'ç_gL°÷²Á’ûO¦ªQm_׃!û8Øqæå"gÜr¨_—'Î,”!JÆè(™.)±7SˆKFH]6>¨© ¼®IÀ1Á$B- MÉos Ô³ÅÏ´<ÓÊ !ByZg,QÖúúVe^p;bÉœ_¼Ó~ØÔ´J=°\’NÀ ›³ žú¶3¯DµeÙÆe)©3Ãá×j *u+Ù°ï‹sA¸°·d; Sƒ¦þ²ò h2[qUmç8ëÌFövj^¬}ª„²Õý©aÒ¯{%[þƒ8× a">ÇÙT’Ù£I^v“¼ˆ!XüÅgÒn«¥ G%ÛÅ·“ÿлëÊô²Ôáúpœ5×)Œo­’7õ›·jX-ÂÓyWÈæ]ÅŠ•Þ_Ÿ©ªVâTE£ŒÞ–¾÷¨L[Þ~¡ŸP¬¸4¬Øçšux^²þ7}tôxÏG“iZdÔ%eeþU~r­™‘ ¡ˆ'²™–ÄI“¡® MR¹¾©ÁUy¾>ýôß<È€E endstream endobj 652 0 obj << /Type /Page /Parent 1709 0 R /Resources 654 0 R /Contents 655 0 R /Annots [ 653 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 653 0 obj << /Dest [ 1556 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 178 622 192 636 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 654 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 655 0 obj << /Length 1089 /Filter /FlateDecode >> stream H‰lUÛ’£6}ç+úQª5ÄÍøqw’Úš­¤2•á)©}A`6X¸×ùüCþ1éVÃz/®) K÷ésŽZïÊà¡,cÐP6Ž!Â?|¤E¡¢"Êa»ËT^D ”Çàáq* šüš¦Êï_4´S©(¢5U®¯—àOñld˜¨T´–ž±€4ù±üì|„l#µË1KR¨<â$>@ìcÑ[–s¨c ãH†:Q¹ˆ Ø_áåêæŽÄÂJŒ$¦n‚·ï7ðÇ2Ìð{ĹLe¢“‘¨x¹tóßvì}DWËp'àÿßóåûÒâHåøQþ„cÁårQ2QZL”ÕRZ )¾FX]µ |¤ŸË@CAœå*É5$[Uk•¦€5¦Œ6h‚wå2K¢oÙ¸Q#ˆ²üô•L+Û> endobj 657 0 obj << /Dest [ 672 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 128 568 145 582 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 658 0 obj << /Dest [ 672 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 278 455 295 469 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 659 0 obj << /Dest [ 1466 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 399 238 434 252 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 660 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 661 0 obj << /Length 4432 /Filter /FlateDecode >> stream H‰ÄWËŽÛÈE¶úŠB¯Š€Äfñ-#pà§<@Öj¬,Ød©Å˜"’ݲæCòùÇ,rî­¢H=l`&‹Œ-¾êqï=÷œS?¬f÷«•/”XmfÊþá'LS×K½X$ËÈS/«ÝìþÇ.yÇßx¢ËëÙý‡G%ž»™çz}“ÏÃåaöYþ5sÊgM¿¾a"œ¿¯~š-y†¥Hž.|ÏY¨À¥—Ч£x<ÖýO|©Ì$»²ï>ÌÅ/ÿqî[¼‹ÜH–Ž'óí\<ÊþWÝV‡æ{nŒ›Õ{<ã× \%;ZUÓ²˜Kº¸ô]nmy¦?¯fJ”bæG±ÄJ‰›¦"Vn Ħ¢Õ³Íì‡Õ)Â'Þy6ÆT{”ìrõ*Xh º^hjÆWC>“0p’P/êE&œÄeÕkäÈ)w&·Àpšz 4•ŠNWvÖ•#[G¹©ÄÔ‘Ô"3?ý–qqÜëŽ?ÍÆ Qñà„Òì 5¯úmÖ‹<«Å“/æ™.ÞØ=>Ø-zb¡\?±EÊM¥ä8G6EHµ­ã)yé$@äÉK}Šˆ7Q¢˜i8‰rIS–klVɼzáßÕK‡€ý ø…’·7&N¡’~z1§ÉW³iiGûP!—ÿz#¦†§rRºÅJï°›Hî5Ä|!ö‘™Ÿãåv|¥\åß 1 iûí)M[õ1•‡ª¥¿îé ñv]ÙÔH@*»7—ðIÜejò¾`wÀÕÝJ­# À‚Ø0D¡7e­;‘7uQöX¡›¦¥Û¯±P©‹m"ý*ç?1Æ@>½®{Ñ7 ¾…² t»²ïuA/øºp×ôZìù®ís‚]÷1€XvóShjhÔlp¼¢ßgYÖ„é)ˆôbÀö"3>u28«2~EYcw ˜¯Ã²©IJÕ±âa ¥\tº·ƒN‹…Ó*ħ,Ù:‹µ¤•0Ž*Pöz×Ù Ô=³ª á'®J8ëþ°wÓ‹á’æË,4ö²~Ô¹±<š^©s'¥wÅÚqÅ_šƒ~uÄÄ+”s‘]gDO’ŒmΉîÊW}pL#¾À…<¡¬Ä.Œ˜ãïf«nzÀë&Aš3Fbƒ@7mc¯¹z§‚\ð*`5­É¨u¾E®k€#Ð!t€kPF)všfO%ªƒd‚·Ò^ž‹œ:Â›à‘‰´Üp •u×gu®y{yUjT'’h“¬juV©ÇúŒÉ++‰Î3ˆXKŠ õÙ·úµl^º!¸ŽvD QG£dS¯CßE#(aVXÏãÈñ,röYçpù¯õ› ó-Êl Gý©âPVÏŽö.4÷[¥©±›8”dibDxk€…ckí='tŽYú­e&ŠcíÊ\ M“ ¨IR‘FÔ¥èX°6ÐÃX^¡Øwýè{˜dHucŒçˆÝØ[@6KY¼Ì©ÍHZŸtÕ8Aü@š—ªà QBW`y¡D!c©äF<—TŠŠ»Ü«¬ø6–dØîµGøè'«Ù#…ˆì2NƒQù¿JP"T$w™ª²nªæù8ÇÕµºaFš8=|\¯D(N §žâ`IžUrU¥øŒ+Õ©ûM\eíí3Øò]anŠ2h­ÔÐŽ<Ó9| UšL®åêÝÃÚ¹"êhBtcÚ½œsb¬%êö:/7¥³D˜%ë `-S8µv‘õÙSÖi†ö>Æ.°q&~üð‘Z·Ï¾^>p—ÑïóS· ŸŽ…Oǧ(¼V Réc*½ÏVYoÆÅ$.uØ­oyŸŠ¸áQÖ52Ñsv›LÌß(2¤ûŒãÕ¨¢Êî²&Ò]²Ñ㋎Ð2Ù2_0zäúS]¶vÀ^±ÈR\YËF¤fâ,R>Z ‘+Ç€¨ü¥Ì^·¼%6øîtÓ×dûRò¢„zºdç,©ò„Š?>°U3)£×oy_WááI±iƽቷ¶Zôö{A¡+½Ãh~ð´¥\â ÌØÄnœ†ðvŪcöÓô¯YR¢3ú ‚ ~;}ßôGQU&vfÐßQ8¹tëêáV¼‹A“ãÙ¥ŸÇ!àúóSä±J~ck!àØ±R‘VLv|Mƨ£g{kÝ:=¸p‚âM׸ æ@÷4«Ÿá¬Õÿ|Ñ]Ï¿m›ºü•pÕÔÕ‘l¶¾PMsV_Ó ‹±d÷òd½æQ=-¥iVHu‡Vî\S¿ÿñÄwÅPÆyÞ‡ÞÆ|IÊူKsÕ•æEwùEn~þ;d.ÛWÔzj¸gÝÝ2·A2%Žy¶ø‘b©TgæŽ=¦b·EžC\º‡ëê¦É„—¯[î$*Üx{à &µpˆýHQiŒyknweŇLbç†UfÅoßÑžIŒ2ð‚¶¼¦–d{ÏÑ1nåðR-Wðÿg >IP=º²[Xýƒ]ÛÓ ‘‰ŒÜàT™³PXÞ"k ÷¦U#B•eëwµÐ¯Ìm~X?svRUÓÍEò 8VTå-îÜ{k6‰ê9üÿ½çSä¦\Ë÷+~ðˆú03·o}˜@/(‡žyäñôà—µs'Û2ßÞö¤×€1Ž–¤o˼?;†P¥L\‚íkÀDAÀêÙ˜'&: ýôR‘ŸGµöÂmMX“û¬¹\(²Œ¤·F]›H6ŠÈ&QB‹°bVcô%éŒË?†L!væ–PÆ€™”pS>›º$úÍ·«ÄUê»Ç3öa 0r¢YendzF12ø†èê¶6U‡ À‰‹ª¤¿f»Å‰È¯d~9.»4Ëî+mZ%B<{&ÁªìAäy³Û°ïàÏÝ¥ÔDÎwÆ &͈ISi†2­²–`¶;ýŠ1ä›ÒÃÞ|rGŸ,ɾë3óð‹}'°yŒ,w{ÓÖâµ4o¸G”|*±­ãmiG. mÓ6uOº·DÞHè*>†øöμæGç¹(XO‰3`›¡m|Áa)8® ˜0/ö<X%«('Ž¢Ð2£-f°? ¶kˆ ×UAÙ ¥°Ë2|úã^Cù;Qè×27gBÄA_'L«´\ʯ¥Ý2y¥7Ÿ%A€ªj¾1ï4ÏjH¹¶Ãa'ììPä-ÊR±Ó^?éë¤ !ef{Ú<íayäülUÁDÇi9 `Dðè'=dÆi–„ëæ¥¿Í^ר%3:_oÒ>Wb©ÿÒ^-»A𞯘#Ø„ø¥  öKb9¬/#‰+r—"’²ìÉ÷¦ú1$%ÊF ›"gzÝU]Åü ´ –‚̤ßò(-b¾11áW>b¿šq!èjÜGß &i¬Š²‘ò˜•&‡)ËÀÿì=±\õæRÓO7JLpEå4ãe7Fµ­'t2Ï¥Oת˜Dºâ(F¶A ®<²M˰7_O° HtM£²Š d$,QÅt—„v‚%S\YÔl^"öŠæ/S˄ʅåñ…ƒÁd¹žØOÓiyR(Ù›a„Ä8ä>Ûß™_[‰rß¿žä(#À‡ ÛÝZR>ò¶ÈLö ¹¡&o¦hkáÐ$Bmœ,®‡^Úã,seɘ‘(VX&M¼öÄ¢^öˆ¸i[HÇ<¦šG¾„X™?&„œ‹>Ÿ-ŸøËÕÔ¢¬ÆSŽ¾ã²†¢Ë–4Ç—!g‘ðŒ•êÙJ8⚆ú”õÊ­H‘ë æXòž !öržl«¬eÖŸžPZcA+ÔPLÑùÏ…èH¾ú(‰P8!Á½ã¢š#ñ(ú°!)ßk úä·;þH"qDõŸ%‚‘²RIØHP´€ n{ö~œ%/„˜ØLRNЇ³Çþ’BÌÊgN²ÆCéj#|^˜‚æ‚s•¹k&býÅå HuúàÊhtºƒjù‚†,îB¸ÛRþ»H’¨0õ“à WÁf_Z_…‚ŠÌ(W A…Túð*±{’±Ûe,»¤™Ôc/» ]èLpq_„#ôgÛñäÔóåõœŒ#?š $HGLýò&h¾Ø÷Cwá¸ý²ªkP;’—l öYk·hGemÙÆ¸PhdöŽIpøXùQ|…Qô;ÍËÊ «Rx#¢ÆÅ•Ñë¶•÷ç©p?¹k]síÞÈçJOèeò‹vÌ;‡(¥ãž *BkÅø <ݱÃFÕG^‚%¦í2ôÔ³0ϳ–á×g¸Áj<íJ¥`Nì‚©¬u 1¸º÷§ú sÓró¸3…t²/BQCüi5„þ2þ?~Ú cqz1Û:Hµ\xÍÕŠ4}k+QÒµG8bvIQYóøÛ¯æO¿/¨®&´™\•Ũ‚È]‹£Ùq%t guÍ÷xµü8Ú ú´¡û†W¶„”^C>!EõY’Ø™ÃÉ"}–‰rAÚ¨<¥ô´f\INd™xñòÀÒv¹ÿ“Ìj¡mKDt¤ë¯×Wp˜ƒ_ÌÅâøÄ¬‚lqõ\@Ò¥bå騆ý‘öù 7¹@Œè‡Ä Ä@òZ¦Nò â^_,£z–ž“ø©–Ôõ¹(«qíÝv…áxö«c›Q0ºÐlï_—•N²ºš€û±—±•˜¡;˜à 1¢Š€/s VÔãä(‚ƒÔŠQ 2U;±fKGÆÝì¢D¶¸èí>¯Ýï÷ —^n¡þv¹D>”šχ—5#@0Ag¨[c÷{ªÙL¸fë$<ë†ýBìý+¥Í¢ž˜¨+ü;6uÛ!ïÒ:¶CÚÏù§]¼$F?Ó&7Á¬:˜ÜšÝñžH°á"`|P—€‘O9‘Ì×U2&̉GbÎaÂeœP"¼†­å³'rOzeY×ßLY|íd:ØIzLjðjå÷âDòˆ´Òež ÂØñóâ{óÄãHGžçõ€ÃÄÓ%ÞdoUo_©ûBhNÍïR$¡'ô\“efÉìÚ¢é…]²×¦º!¨`HHÕò‹û âD¯ŸE͉:%òºM … k©üwëê—#@—¡ÓºníÎì‹6ÛõTãõØÕî©5<È’Ô®2C˜’P¤;fûæ)G±t"ÌèpP Öä§÷4ø]ib[ñ¼‰. Wôw7•ÅÆ½e8r¦;s¶oÈ#Ú&qrÅð¬2~'÷œäœíí!£‚Íú]Ž7_ÚÐDi”Ì „‹·‹Ô+K)¾rÁ)*35Y—sÑÏmg²×û›÷<סMi‘9H´mý‚€D¸‘™âI/ôì<3€qò®K[Ë`5òBÅ"s™û:ežŸ ôù•Lš Iâ¼Hp™j$§Êù Oßý=ƒ¨Ry endstream endobj 662 0 obj << /Type /Page /Parent 1709 0 R /Resources 667 0 R /Contents 668 0 R /Annots [ 663 0 R 664 0 R 665 0 R 666 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 663 0 obj << /Dest [ 898 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 209 743 244 757 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 664 0 obj << /Dest [ 662 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 308 590 324 604 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 665 0 obj << /Dest [ 669 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 380 352 395 366 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 666 0 obj << /Dest [ 662 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 228 280 244 294 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 667 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 668 0 obj << /Length 4471 /Filter /FlateDecode >> stream H‰¼WÛŽÛÈE^õ # š‹Í;)Ã6`{3‹ ìë)ë<ÐTkĘ"‘²Ú*óYÉ·²cwÊ»²±ûªóÎîf¹é+7T¿sÝtöeņÌçòCeúÒ-}9AÅ~Ö¦nNw;õ^ˇƨ§s£òE ·Å»C÷\•µBMc×÷Þ;7êé³þïšSµAèžÊ?5%%àŒüP¤¦6Ÿz—|1¾ºâ,z.²=¹^„jFnf©’Û¡®^ä¦Á¤1ü¨o Š”êšº>œ‰µZ›%¬7êMþÑ,»¾ÍÛVí›i‡]¯:½ß*I¹ãGíìÛv¾E³!ƒå@®:Ñ-’¾D{PooøÕküöµ2õ]YÊlwnÄ+ÇOôÎŒõïÖº‡vŠ©œAj°.Ô¿!ü?¾úe‘íQi Ä—Ùø$©ô1°cYI,”-ø°½i6ì Q¹s™(Œ†¼`ä8›µÞuðCA×`Ô¢©X÷yÅqÞpYö&¯±Š’¢¡hEÎ=Ç UæóáhÚmAÆòá*‘Ì®ÁŠMÞå’ %»C8É¥åÜ4¶’0½ÒC<ƒ¸À…èBº[ébbäû,O‰=øüEaª;gI)±?Yp‹.R ê²ONÕÅ^ªÙªîx²oÑ~½+½êÀ&Ð}moâ½£xAnú­¶v›Š ´î„°‡nšÞ¯dš8X#-6pmЗ Cä²ä×™t"9öý˜hjÇn—@§ E#Ð"1öD½kövy¹7í #ÎvÕþ„æßc;ÕžŽoZ@R hÕyUÝ£¤™Ks’3Q›cÞ^egöY¼ÿ€,Þ8}°Sø\V2Kœjù |æØåèkA²«~D‹ïJûº°«M¼¾ÀüÄX)0â°ÖÇF ¥0ÂØómy”eªÊv¬¿³>û}_xvõIŽ=YnÙ*œ8U71À{CøÙ•õ"—4Ýõ~˜ºEló/¬>ñbÕÂ&ù<¶WCI * ’ &ß0 â~fÝ÷éŠÜÏ©)©sÊ»zÙ5ËÝÇòBLOˆÏÀ>¤µ6ò¸¤Ïô¶4HÕqÀ}A1L§çS5畺ΠE г”Lªä|TSMeš_Ï¿aäçýÀçäö5[òªéq‰Ü’—”'4D&AL:…Iï3‹Kzj¸ºrË@Ù÷÷÷tŸ ÄßcRu;û‚N!>­3Ÿ;SË3{úˆ5Mx&"!0àôµGÃ8…G34XwÙEp†Ž‚WZö¿²cÒ'#àüéóÒ€!.fÇ ½UÜ~àÊ!¥…æf½9+=ÑÔÖÕU¹…±9,Û®¼CùåªÅÔ¬®Ûzw5µ™ 6YXôîáÿ~Þ’A8´nŸ;…"ì1~ËCu5Eq^Jæ ]ŽÞOwjêþ‡æ!.ä„ÚAgb|Õ,¢jó©—ÓtÆ{Á0·‚~n ;D3}W,ZWò˜äôAî!׈9:a‹æj”ƒr§¾‡c®\IРyœ'g€ü6ý+0>ÎkbµÕE8Iãe0± '¹€àÕ¸Wv€Á€ñõ{´¼}VoH`ýŒWýÔt,ˆ|ìH°'°ÃP[€RÕ#ùö'žœZÛ[¸Ìβ‚h}0$3¥Vùv÷71}5Ñ¢lšÈQ¡ðDÓC s÷^ Rï‚T®†ö%©øL*™%•ùJ_}…UÐKEÕÐx‡®<äǼFH¡ÕÉ·ú Šàúp~^ò¬ÎßPÉ€ È@¾Wó.˾Òè˜HMµ+Rã*+ËåŒf‚4-°'¥¢OAj‰Hó¼I(ÐX+[Юg›ƒ¼‘§³ uðÜíÄÿ·ãËt¥“t f'I©Î½þÕ36ñA'>w@ÂðþUqޏ§…ކB«9ꀛ3,n¡" o+Ñ5N‘Hs. f¤6qœ½'àíLî$X³+°Æ#4§Y1Ñ‘âÜçöøùé©4‘P2þDÉQ™¢±b¶š#«õç[>ù¼ 2©ÙÓŒ!EtÃê‡GÊÝÑŸÙ5ÕjSÊצè’½&ìøz‹› ¿¹xSà=„NDp0Ùt¿|FG5¤´ÚÈnö©,Å©Œr÷ԮĢª”eÝsgºÚ±9kÛjõwƒ)F‰Â‡Z1äñ%¹ªOû†ÿp4³-k ZÖx ä/üEùQÃÕP~YáR‹ä¿7]^ZËöcH¶Ô ¯hÜwãÿ„Åš‹S¶Ð¯ˆ "0Ñ{¹á¾÷…|!†` † '¿'_ˆ!ú¸LG‘ôåc¡¢,£p`Ã=p%W@Ïñüè@&ü~²?»yúüFá‡ÅÞS\>ë¯q®Hõ³™O™ëmd¹êGz³);žWƒÇ¿}¿›SÈ„ Lj}ñÞä5y|T8™F·:¡ÎKûðZ}£~k{5@“¯fŒ>—¨Ö¤z4ˆ`ð‘ì= ZÔhEÕ„nI|\)á˜`6xŽ'ŒÐ&úUƒvôCЉyT0;ËÓš{“d ?”ùh¯¶·0úÞ_1ø¡ƒm,Y¶å¥)”&¡’>4OÉRÐZ³¶ˆemmy7 ùñ=çûFKb)% d-F£™ïr.¥>Ô»âhAm‹5*Q лsl´-êƒ+E³¡±ìݳ·9ųTUÍ4 µ_£4€ìƺ{qtÙW³Ýó86Ùt–V³01ÅÐ<….[p@>}I5$ ±ã­TÞ½4þMVÐMà‰†x(޳Eˆbµž6‡H»Y^×r|Úb[%ëQ0!Wçlwœ–ÅôAïëa“˜uꘔÃð¬h7Œ (ÀI«Ùú®ubžöÙxƒoUí6H ô3Jd#¦,Lž€ÇÊÓÅç{Pf^¤J­š{¼° ¯ymÞðZ% 3Â-¨‹'Õt}À¹—½v+ݹÔ0¬$ ‘†<Üãøyjâf7±/ñ[Ëý,þºòêÅÂÀíÝÑHµ³ÊKûÌ,ƒx·Æw  ¡cñ¬e¼¢¦r"_9(ã®—(œ)J[8lŽõ“³Œé_8Š\w‡žî ·iSK<ìŸ=]€_z¦³&#Ÿ”¹d.ÖÇ©ò?qhÏZ‰íLX=7‰Ö¥IýE‰ªZÚj´½´Ë¡ãuõ\͸—)‡ö<]™Þ¡Z?ÎI©ƒôeþŽ™«Q¿–,rVg§[Ñ#ÕxU†üµ"Y×Ã=js´×¿°õñ5G~Ö›§ö·öú¸Ôb™wº¥«b-T1D¬&L&ƒÏ{Õš GÞÜ}iºŸ²ÃÁ7,1èšCÁi‹è…k›Æ®gl«‰ ƒ {L—˜¯!„Q´öî9e±îD×± ÇOÒGªüP”õÞ)ªžŠÓ—‰F~i{ ôÙú'ú7Sͼ;R!4‡Ò›Z¢†š>Qˆ—€¯«€wÄ!|‰;.z¯þPõýœÃ¿R†+ïÕ´ ”Of¤0û¶¢sèPß•{q0¦%x5ðæ£T="[Í6í­õa>Ûm!t~<— dô5=…³UÜz­©œ bߌl‹ä#:½xÓŽªc¬YGlÃ[?\}çOاFJס¥b¿£êëkØÄ¼úë¤+÷Ñ×°“1 Ed•ôâ–Ä) Â{áËЫܺUdLQbÛD/eª©œ‰Üùk˜£Ç~Í-þÛ¡û^µqzâ:øEMq×B€ÛŒÐèË ¬ý¥øEÑ ¨8w å2¨8?E õÁßé|`eB‹¡w º±GGÁ,?ŠN¼s ˜ãåtfÞé×RÚKÿ½¶ O:[1 –­~õG§æ@ %29û5ØwÍ,xŒ†Ã‘ê8ËÎÏ%= Mâ9£+Œ•#!®{Tù±0_ÀxF§â"ˆŽ-¦­w'p™fôãÞÇŒ¾éÏíxdòl·/‡q»«->[‰˜øT— É^ò;n1¿@]ã!"ï¨Ð“³IÑŒ9K]÷UYºæÏÌ‚a V“œ*CnÍS½êGöœ§|z© )>)°ß£GþD†þˆW˜H"%½ «sóqHX»µÏø—çiúqL±¶ßçùY®ôï'Õûš Á΄ˆÒ|FºB dInŠí\‰qüĨqSºÐ Ý›wwTKnoˆ~OáÑ<çzÏ·"uêÏI¿˜‹#5%âZø P{zQªÊ)N¦gÿ‚M«??DPhÈòÜ¥R‰ú–Dï7vë\Ê´FôC°Bà‘x¸¶ú²fK[$òc_¤]&ƒQ Öµ•P¬ZŒ"p³f”Å5@Õ‡ Ûg¡úFBØôẨÞ9JoVRâ')ݬ…nžn¼B]W µ)ÑMƒ§RÑ7=U=‹ªHsª}{Í(óÙjÓÒÜq­¹cojÁÓØa¨iBõ´PÔDþn'xkodfd«7¥|h"ejÉ»€êR&tüÄ* l/+q“”æ°ºÇXÇ/ª‘„·4ÛXD¨¨þW…²ÞŒ> endobj 670 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 671 0 obj << /Length 3844 /Filter /FlateDecode >> stream H‰¬WínÛØEÿê).üër!2üþ0𒨼H‚"V ´›¶ ¥«˜ŠòJ´}Ž}‡¾côÌÌ%)Ù’Õ`ɹsgΜ9÷õdôb2 U &óQ*ø‰óÜós?UY‘xiîGj²½x³ÎÕtÍc|µž6£o¯õy=ò=ß§1Ó‘Û=nF?ë?•Žy±þlè7Ô*.”ó÷ÉO£‚W(Tæ{EŠ]¢ÜK}Ù„y-zJRYê?!¾º¡ï¸Aä¥ÚÏÕõƒºzhÚ| µq°’^WkõêíXýí¿Ž›à}[â%ºr|=½««MÕþˬj^$Òe3sÜB«ßø?;ÆÇ磅¾—âer†oìÁf³ñœÈ ôšv5´-–Æ–}œnj?ÝðJç“Q *5 “Ô‹Ò@E™—ç* ¼8V8cœ«•ÍG¯'}0¢CüÝh ¡ö)"ðròËèÅEð8_H2K ¯e®¾¸<wvúÃËsšò9 T–øUìÖ'G­IÚ[ã0*¶í‰Ÿ{a|pús·7b…„³•=ë3žíŸ~ÄÜG…áÀÆ öüøñ±öš_ï/.$+)Yqâe©M4°}Ñ#ãÝnˆ2*›µ“x¹>u\›j¼·NˆAªšžò…Cr S Ïßñ·3UãT!«“Rí ’¤;'ê“>q2ýJ]U à\,“m'hÐV}D]}Cñ¶x7Ë»z†bk§7RèNâòL×õ¸ÿD>N—‹Û’šI¦+ù¼l”}RS;’=ˆº°ôïöÃòÉñØÝê- §eMÓ¯Õ,±WÅo­eîĺú:VvWžÅ.í%bHb!‡¤y©´Út«ÕnpL, h–­5µc9èô»‡ö†Òq€2÷¦á®[5öØV5¤zhÒ±4éÜ6éÆös ±f:tŵAðgfoºüA£øAOgë-67R· ˜˶lå=§eCçº&Zž¼Í£ùcÂ$ãïf¹iºEÿÏ¨Š²ˆõ'AÖªî|XÎ4m%Æ.0$G²^ŽÄE_oíˆ=q_6’oP”÷¿ù)<}ïj‰Ô!ØÒÊA+3™XŸ!³ýÓ˜íÞ ˆW”o¶’gÖzسÓ˜·¢ç‡ÅÄ!ûÂM²ÌKãoVIjÜûHàÆ„5zÓ"C!*$ï¢-Ö*~^\8|\ïÊêr?æãÁ»X¼ãÂMhùXSt#Ô)‘IܳH8V×w­dÙÔÛgµëRñš…ãB¶i:©«–Øjµ±öœ‘ >'¶N© Qmf½®˜±UYCÍT»‚ºÙTíÍ®,–³jþ@LW6[ˆ¯«ÃÉ$¶iåtûtå™’W\ÊŠ”2 €V/ºƒCü‰?™99QÀåŒx‚{ÍÜqcêu†-«5úÅ”mèŠ_;Ož¬Û>ÎqyÚêèÁŽÀ†ã‚š óšHÅ. ¿ðÇ—nDZ0%r¦G"0-ø±ÿÖL­>´ƒ™|K6S–¯¹a×'ú ™k±Í¨ùÑ„þH5Z{Éou½ÜPÈ-Rº¸otôN›ÜÉ«™í‡ðÓ«zžPpEÉj<ÊëéS„ ´«ˆd_\ØLøƒ ÖKÜÑv þcƒL™Lr›=,’Ÿ J`›] °¼5+`¿¡ËD,ÌécOÅö:Q¿ŽÜÁ…öþ’V¤ßŸ;.•{vù¢œôÊ56@h á0×3…9 þÔ:ÂuÅDú‹£îß`.µyZj‰bÏi0Ϥ†AZÐlgËþÚ ‘|V1®ÚÊ>­Õ’¹ÌnÉ'wùÀ»Âî)Ì·aE¨Y8„D@ô“®«/Æ‚ð’eãä>«3ù|å¸}ç—WåwÌ‘PW~ͯ?aÑó7ƒ A4íô“`â 8!¡óXÍÔ¬â÷i[é$¬ÒA¿¼4åÂx]Ò›õB7—´D¥Å^˜ÿ~hnqGȼ¢„jî-ðïÔ.`wF—L¬s4+ª0•ô`cG±ê·J¹€vP Æ½æ&Qi3[y$Âw ý¡¬ Ó™° ‚YÄ52ƒHB ÉÉ~ÆŸ¼a ==[,±£»XÊ,eâì 8ÓãÄáÿÒÁeóO(õб'‰Ù[çœï¤{Y9Á–iH;}³‰Ï(×d}’hL=šç%ÁiÎ~Wšó>͹M³eÊ/æa³\Í%‚¢ØJòSµÎ÷5È\—5§ãÚº&Ì„¡¿õ­~:E:ãôeÍ’’<`Q@¼]276Ââ»jÊZ\·¢Ê•]wS )³ •Ær÷#t{¾jáÿ@b@*¶@ßÕÊxkp¾¡±)›•©Í¹å祌U‹»º­\$;×â/߯Ðûo<´Ý^+ó˜;>@k³I½:ûHíþM)DÓp³Im“šüp¬ºywŽÏì@Xdú‹ Œ½(ÛB¢Œi îäÓ6áÛ[YïâXÕv*õ?Â;‰ëR½Qi2¾Á’24.§Ó )«fÔŽ°Ð~·>9ãýâ«¡èî[BzÍ«¯ØŽ[]È­ŽŽxrሠ¾ð>üóâòãÕ^¥úäi%f^­ÄÂó¿AÆ}%ƃ´ jÓÌÊÕ©ºš¼¢ê ôG9Íd¬Î?œ=QíÔ”ýg´‹úrh…m§©Ëº*í'RV?–9½‚ÙÕ.ÌqÖtþ#ÑgOc‰kjzTSà`ßÕ‚´—©éN,ÑfÔÅ+R•ª"./é'ÕïD«þUlcõöò/b?—¾ÿái ÑÁ‡@*¤ÛrtdÍË.Ô‘´lfâ0p*Q'E»Ð2˜‹­¶£Ûÿ±^>;mA¿÷)öD7Rp½k;¶EU‰E „&pj/&¸4RbÓÐò"}ÞΟµ½± …C%Ûãõ|3ßü¦‡Ç WÆ|£6>µÊÀÜmnËq©8©Ÿ´²ÁÃr]Ü]aŸº+rt2CÅ`IK„öw=Wâ¦ÐÖBïçÏDoÐaud"'[ÒÓéäê¢ ‰®~žP¦=^Ñ"´@´HRqÒpr|™œN¦£dVmLí<ÄŽ¿7:þŸ$àGxNèFF‹(râ`®ö@ãj·¢ï#ïø&ÇZ9NŽÇ½jaºµ ºKù`¶º#XÇ\ád™°ÊÒÜšËb¾ßÆa2Ðü0ë)t¯”MŒ9<ª&À l9G yeîÏVUÖ»Sãƒw¨VnžR£NCèš”j Ž{µ ¿ér±ÿ^¬¸Šañz#ÅíX–â§WϨ­ï¬Íg;ÍŠ…Æ¥6…©›­xyYC»€L¥œHÕ gË~mˆ¬¡iа~/ÆðŒÑp_‹0uóÄ/Hx›‰ó ·ba¦MVpâÀBÜö2“ÀœmæYuÉûñ‰¡Ô·Ç œ•fF‘› ·[~2Ý,Š\”‘3{:QPBiz…¸£ÿooŠCð¿È¼ÊQö¨ë˜Cœ]ŸË¶^-;øvØE¾Èo¡¿€`2±N©Å|y‹ Xÿƒ³ vªÎP¦ä1¾6Ú‚ªö ùz¤a(ð%P $rŽÏ‡G\ËõUO]º1^Ý-oŽ<¨NÞ.e,+üè@raDéê&HIq1o¾šB̓L·Õ0ÿV¬Ä0›g«kSšb°ù u e«±p”¼€ì‡’ëi÷nOÁíñ1_îü"GÌ2³ ¸»Ù×v¦Ë{8ʆÆ(ZÜí„Ñ€|ùáfý]~ï5|À íRnnkÚzYüvð¡äòÝ¿=Ú_ˆ endstream endobj 672 0 obj << /Type /Page /Parent 1709 0 R /Resources 673 0 R /Contents 674 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 673 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 674 0 obj << /Length 2965 /Filter /FlateDecode >> stream H‰¤WënÛØFÿê)ŒnpXX4ï—ÆÀ‰Ã…cok]ìºhêÈb+‘ªHÅñbŸcßaß±?ú͜ËdÙÉvÄ"y.sûfæ›·“ÑÑdâ WLf#×þá'HÛIœHÄihG‰ã‹Értô®ND^óGÔy9::¿qÅ}=rlÇ¡=ùhÜ>>Œ~”ßeÖØ·y¯èד"t„õÉ_F)ߊرÓRüÄŽ-„/ðø.z #}Õ¯¾Ž=Ç»¾I'wâæ±læøâIeá&Yµ89??üׇx_c-´CYXŽÌç‡âæ¡h~Rë_âˬœZãTŠ_ø/+Ææ³ižcGx™œâkððð`[¾íÊš¤*‹«!ÒÆ£ëróiÎ7MF®(ÄÈ #Û\áÇv’ˆÈµƒ@ÀÆ k5šÞN:gø.¶8ÛÞè]íG åä_££÷OâÕ:2SŠŸ•Л½2Aæ–É$\ãÛ±“xtBÿä. …v¦Gòɇ“ïo.¬Fÿ`=yv(>œà5‘ß¿»þh¹.ž®¬¾™À7ÆÅûàæy6ý‰L¯—éi™â÷×X‰<+EU.ÅËe襩(Jñîü‚å‹™ÈbѨµرÙ"ÂPþ?^b‹8½®íiMÇ0À÷ÄØµ]Ÿ@ÐŽ{”ÇZ¡ã`v·{òÍ¡¸Û4¢¬R¡5Ú5VÇvìé8è[†º¾ªn10ÖX„YäO|f§¡å~÷l*Ôç•~2Ó‘г* %\*òªäÓ÷}$kŠª4žS¶˜ðæ¹åÂØÎÿ™¹]¬Ì—Í´kï¥v³ó¼Îyiï¼T«[LUÙäÁZaÉ•¬zÀšF8Zª Õ“zALÕÖþ²(ïE&–Ùçb¹YŠ¢QK¡› ?)q+aãÝ#°ÈFéÕ[ËòèºÊ\»sE^mÊæPèE¤»‡#úàŠ•±ÅRmÕØÂˆ7 i¶¨!Õ…Åc ®G}±Æ¨¢TEB¸ròlq}ŸŒÜ¾ë䉱E½ È/ ÔúZB¥Ëkƒ.6z½¯(%Á Iµ¯Ãš ¦Ð¦¶ªïžA¥@Í’/T Ÿ}ür¹ðž/c?°ÝÖ×qÇÔñ«ÄÅ‚“Óú/'Ph …7(è˜x/gT+L™àq£š†ÒNµRjúœúÏ&[ˆ¦‚R·²Z‹ƒf½Q‚žÀƒ[K+?ù“‰~ØrÏhYoVÐPuMý¿"#dÀM¦!’ÓòœçÉ%ï-êÐ>Z‘¸¡ßPògþÓ_è…ºzšŸž ’Î ùSfÛ©ƒnô¡r–ĸ-¢T"ê‘@j.¨ È"ù`¾Ú» ÚqŸ_N/úwfZâFƒLsL¦¾½þnrA˜ŠäõÕÍóyy¶ìÜĹ=¶ÜA¿1ÛêÔu—LBc¯îç²O—b¡ªõ §êîÙHäm\bC™´]Á Ò'yô5)ÔwÜqoáÐÀ­ä©‘ µ(8¼hMÜg»æº›- {¥uòc•Õð„¨›5eQ53Æzvl·ÒÞÏF‹b¹Z¨%š©@Is§ò¥Ê¹Á&šsÅ9}Ëë¢ZÑn½Y74êW¡é¸þž~v7t‡f =‘G•xÚT\;z‰µPb ½ØmÌ ®]Ô.J¨Àöý$úµeºaŒú²…aoPÑç­„ $„½G€ÐƒÁRÖ<2d¼ôÙ"nð<'í…ð¾7€x¯½c8×ßçª{`­GTƒP0Íšì.«ñ™¸j(y@Šd3³jÝÂßµa6 ì‡T*÷Q ·º\SdHHµˆ®DLõ|É%¤æS‘áÚ* 8~¯aaúQ"ßµ Å€‚i %ôö\Õ¼\™œ‡,=¤‹ÅrCœ„¢I¬‘IÔw/±†™«iàEñoe¸¹/‡†yÛ…îG¹ÊÖÙRQ…yäS4èï¨ò¾([ËÔq—ªx–çš´¬šZ,«ºܱb°cVBQ­’±Båá¼é[g Ô§[‰lœm{¾gÊe‡Ã[Šs.[Í+hDi–SýòeÕZ`øœ‹i1›ùfA¾]¡ Á¶y5­ÑüżzPŸ!ÔYµ@B°žÆÎ'NÚOÿ5 o˜lC†žO™±r¨˜ÏWLâI©¬8¡lЦ0ÄžãÙߤK”™«þüÔ1}áåÞU3êÕŒ´š¯ÎþúšüžÄŽü^â;R³„[™x ƒÂüb#$—ú J~R-Yør:¼* ŠbAâ¢Ð‘ÿdyþ®6®|mªÈØE@þSî×LU¦3+%ȡҷ¶¹Æ6WKsµm.Ë£ü÷|ÆB=!ŒÛGmá9f!ta¶Æ†¦0ôMkèýšê@ûµÅ¡fDfóöœÕÏÅòü¬‹å›oQ[Ùž³ˆ°k7Ð [üûåX»_ ön „#Î^[)Y&ÖÐ'n]÷Ž@5*ò[˜>¨øˆyyÑOÓïÕ儳ä5×v~[X,Lz™$ÛŠGÊ>à_І¯5H« XXcÁcÃÂÂq‹­B,õßm¶½%¾Î {’î’!á9ðù1… é AòugÚB¤Að¥ìXß›o°Í$9ꂯ-O¤þûIg}¢u¤yû­Ö_õ qüfËzâ¯ÿ¯ÍdÞ<íÎ÷Ç»÷kXå³ÀâÓ k\å÷Ù·‡î¼zw}Ŷ¿!Ó¢½®³‚$-f©²~)| ïÝÅi>ºrз|½;¸ªcµµ.ê¬3>Œ¤y{)fšüws€Ž™1ÊrþH¿Ü;­TÍ3‡‘þ5¶q˜:ÁºÍ _¸ ì¿o›íƒJuŽÊ–«×âKˆjô/4 ÐÉ8mCwrujR‹Ø9Èò\;I»í×£p €þ¬­qä3DtÏà÷êòã„á !•\â|Q3ÁŨQdæØ/‘:"Š)‘5ÀµlŠY¡Ööþ îé„W//Éï„ÇVàpÂÊjñ)[l4÷VL²‰,UÜ”¯RNøòǹH¨%Ñ£„‡)Ì¢zÓEÓÞºÔ£ËmÑõñê俆èn ϯÎNYGw ›æ¤ ?-]& [ZêåNU^0‡ …°hŒ½/ÕôÀân=¤jþ ãíESJ"§Ó‚¦ÅÃv˜ùd¾“+M[Ì—uC³«yi'#ü_òtrÅK)&ƒqDã<HCz‰‘šå—%Í\zÂ~kvW#ê⾤“ã¯,^?ß=Šæ¡º=y_4b®>‹rÃÅuy‰˜0 âô˜æhba¡¬[2§ø>7ßפâvšËéÇg½™óÓNŠÓÉ K{g¹¸çÕTÄ>NÞ“¯-’5ê»*sE£g OjyµÆØ¹ªÊ)ù Õ6‘9–ÀÇ´ñdQ”ùâ…W±jÃ0Ýýš:â(®,_Z²”:èè¹A¡‹kˆ!ŸwÖ!hb5lгN§wï$Þÿ²È@D6FÇòGž·/* 3˜×Qæ8€{ó}îƤbs!D"îºC€È‚:x¾—5’™PÜÆÃïØç dµ[+Ä>âĪyõÊÜ%¶Û·_Ÿë{x2¼ þ}¬Þ&[práÄÉ·]A¯¥&Äӆ㠅H-§·wÅñ9ZÛ„šÊ”ö^kþNkCaVPTÓšûÙóøGW b>DåÆj«*iò¯}biÛ^…šïí#/ḙԲ ³Á<)ó“ÿGe]Ú°³Œd`²êºJ¤“¨it¤Æ¢ƒI¨QB §Ù‘F endstream endobj 675 0 obj << /Type /Page /Parent 1710 0 R /Resources 680 0 R /Contents 681 0 R /Annots [ 676 0 R 677 0 R 678 0 R 679 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 676 0 obj << /Dest [ 898 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 468 569 498 583 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 677 0 obj << /Dest [ 669 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 238 542 254 556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 678 0 obj << /Dest [ 910 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 376 481 412 495 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 679 0 obj << /Dest [ 1074 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 190 232 231 246 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 680 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 681 0 obj << /Length 3331 /Filter /FlateDecode >> stream H‰ŒWÛnãÈ}÷Wôc3ÑlÞ¹ð\v0AÖ³ˆµ@°v(ªeq—"‘²Gû!ù‡ücrªª)É’<;sɾVWÕ9uúÝôêz: •QÓÅ• U€¿xÄyîyª¬Hü4"5]]]¿ïsUõ<&P}Õ^]º3걿 ü  1ÕÕd|}¾º×?—Þ$òcýhéj•åýkú·«‚W(TøEŠ]¢ÜOÙ„y-zKRYê¿!Z'aàMLä§:ÈÕl§îví°DK¨­‡•t_÷êæÓõëÿ¼I‚ï ú?ѵèjùFÝ=×ÃvÓð"‘.Û¹7)´úÿ²a||>Zø)>¦ÐÆöìuêsH#“B6‰âØ#ëæõba7¶êr¨ÛG5³Ã³……f:1ºU§Q)|S9X•ä±_«ßDåer‡sš‘Ìà˜h¶ÚM·1~͉»HœmúYtlWt ²1Ó¼ ø!0 9@ÐB^ àé¹ìÂ.““üº××ó ñÊô„—dÔ G‚<$èÈË VÌÉ dΙY;$æ~t:G(êÍ~äaï§ó‡bb¹ð&Ž ,”WzÉ:®~ðN(aúqzä®Ë¥iºD­à¼^ÔHó’(ɪMÙ>RŠåìÜ í€a¤õÐÍËÝ"Š gâ¾9J¢0=ÂØÌ"¦F/:,›Ã1çïK^c¥Gù”¬Í]z`ÿ^I Ĥ¥‡$1zøÎ%¬“0$nqtó"9Ï39ŽG+ƒõBœ}ƒ2—èSò2~ç°Ùç°qxåj_hXêÞX.£˜²ÍÔ–ë¯<èÛî–®qð U7­¢raëz‰’pÒ|]ßQ§ªWëÆ®°ù³å°¸áj4„*m­Ç%úÑ£ì_ Ü„©Ü,Ç–¾I_2“ÙGcΡ콄ù™ê=ÅŒX*i´´G¢7OX¿µv.­®³rõš-~ÐnŽUoG8F¸Hô_i‡·´óà±ÈØ­­ å.ñ½Lj¥Ô>x¾ºi&GL}ƒi±oËÉÞ Ë¹T~¾}Ï«ä<ƒ¸@ž½ûøã—|TëÞnçÝ%^xP«²Erª-ÕwréÜ.ê–#r™ë“ƒ‰XPÎú®Ù"`oÖƒkTF' uä+ü“ÒQÞ|YÐêY±ÏÌ㔿njPß9!AÞ†ÄG êø¨ŽJ†þ}¶ààÎ3ç“GB/9E1¬GÓÒÉ 0N0Î S.ÀK`!×uÏJkn#²D¤g‘Ö )US¯êAI_ÇC7ÌU…ø- ,êyi[5'ÚH8KuÙÔÌ"¹~d]&ïjÝÉÊò+›Í Œš’–}¤ £¸P6ªnö›­“‘~aðÖ#áR-/Çÿ´È"þ”Ì`»*ëÆW#; ,J ÁCNŒÐ4HV=ÔàX`Ä?3‹s![PªáK¨ÆÕ|„*D+´ÖÜYr :gTð§ †˜¬På—®"Ћn"M9‚ö¨é$#°8;˜RדÀ\ë¹k‡a)vÑãçð§›Þ}þõœ_C3Ñ@Jчú¡¤ëë?¬džÿ]¨LPٽʀî?q\PÉß‹„Äé˜~@ \ÐíÜÐ>žŠh¥øt‰o‰éHZM’d|»¤Z'„!DUmv_MAœûj=ÉRzNaî9â=¨m[ñ%4cT)w>Ïô/’m¢6ލßÎgÅ@3ÈœB¤½å³ZÖöIª§·HæL‹ßJ“•)ªåœk°%è[<³ÌÝßBäÖSÝme†/FsJrCË‹K ¡Ící*Éi6¾¢>¼ûòóÔ›ò>³5_nïpyœPI#Qœê?ËÒÞŒ>ß*Ýeåû’3>Rl׸ÀÑ™p•9‘@¬,÷:Í„‡ø¸LQj–úŽÝ’ LŸ¡è~ùÜRÊ"øšù:Ñ2@¨BÐÅ/GqÄ•J>w‡¶Rö TNÕ@«ö@èTàt·[ÕHÔð™j;×*+¹Ñ£•ÁÞÄe É+ïnÌ¿·ÄŒÂ_ó(ºÍ#ì¡9£Ë×KÆ þmáº&ö²ìbÛpΆ,ëÕ3#a¼KÖ(lDÛ©O¿ð­ƒ+K>¡Ëe;+QìãšÛî÷ú•Áœ§‹ÐØ+8)õu[žp=»Tɧ~`UKšŸT-P‚ƒŒ ^LÌ•qÅgï—ݶ!¤©aÃB@‰s¦'4dzåëÖ×ÓMÚØ•ǵ[t3ìˆ{ÄÕß)ø€š³(,ÉóÕ[kÛ ˆB;o¨ Ûm½±ómÅv.uuTžÀÇÆ•¢¥ˆÅWpoŠÑuôF†Ü~¹¡Sdz:¥J$ °¥Ä 5áÞ@M®Ø—†…G²ß}Ì¡^œE†•ôH5ñƒ4¨qå}¸ÙŽíøê·  (Õô¤+šëìùC qØèÅ­¿”«½U½Ow£¿‹j£:¸*¿^¬„&À‡êXXTÇâ}Þ##,Ã&D†&É“JÒK+¼R Ñ—¤'‰S§%*ùaÉêŽY,FI¹¼„"Q#Ö9Â|nÌA£RgÇc‰e(Hév»šY÷ÝɌȤ”Äȳ‚;ìáÀÓ\3#ãA»mÜŠö+PêdðXcïõ|²*ÛÝ~OZoÕÉFÄt˜ì–¯ˆDYª•;”ü–¢!÷'uÈF±j;Ým븬~iMP“9TɱٳõIC}“ë­_ÆÚâ U'o£¾ñC[Æ&;±Ò@C¬å# L#áv!ZkDhHÄ\·_É2QûoÜ 7H”ŠštÿUbM:w=”qK—õf.ñàó™S§Fž'âMªÝÄfž/0¶knVÝ`‰cCòõÑp‰yÂ¥‰Q°ÒòI'gD˜ñŽ(†F …ŽuóÔœ‡Hƒ‚¹oU½*vã„~§ÌN3ïéWkΠ›E›%¨œþSc‹Åo}}+/“³À¥ƒ3ÆB.Sœ]0CjfLM;¤¦ õ­b³8¥fM·ù5MüQÓ/ß+ï>ô¨à¢ÐðPý!!ª)'è±nÃöºøŽ!Gº5hJɨMC¥J“`ZÂÉ7)X­7 b<dÈÇrqë$¡ ×â‹—Ð Ék%©HáÆf' 5Ï_ ®­‚ËoGáÐŽ³’L¤ð¢¡iQ“Á¸CPs%©p5òpÃ0Õ§·~ïa¡c¯n³t XXﯶçZ+"rGËà§Ø²&q/y¯ÉÚbkàV›=¥£úå|¨O¯wzªG£%KZÆÏÆÃ >n~|7÷ ìa{“'(!ÌŠ,É4:´š_›ýMy}Ôºn4Ó¥ŒÛ(_Æéìô+ÃÝÞXV ÌO¾8ümëéZeAî8GzU•åj±¡èÑÈr²Ç3š$,dpŠË“?Õ} ´î´}Rúi8wf@ôüë!r2$FÑ)$‚ðW€‘6X endstream endobj 682 0 obj << /Type /Page /Parent 1710 0 R /Resources 684 0 R /Contents 685 0 R /Annots [ 683 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 683 0 obj << /Dest [ 662 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 474 674 490 688 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 684 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 685 0 obj << /Length 829 /Filter /FlateDecode >> stream H‰dTËnÛ0¼ë+öHC½% (ФMÐ") D§&=04m«Q$C¢£¸Òè?öÐ%W~´µa‹ÏÝ™Y]ÔÁy]ÇA½ ¢$~ñ‘–¥¥Ì¡¨2‘—2ú98¿KУ?#aÔ]p~}Áj ¤ÒÑA¸NÁ=û¢x˜ˆ”­Œ{Æ ²ø·úSPùRT9¢$¥È%ø±åFYN¡~ŸÆ’‡Q"r&KxÜÁÝ®³k\‰™á‰Íï®Ïàëof8p/k¸dz}wSc˜¡õA¦º+?ý¿OÌ—ïK‹¥ÈqR¿Ç5ŸÁ4M‚'"b£C5C#¤À¡Äêô¼´ö‘>ÔA q–‹$ )DYB‰4¬1-a0Á2¸¨d$‘³q¤Z:F0Ëúû‰L{þŠ\ üÑ'@|Ô"¦ô?÷Ö€]+ Óºi ôÛú©I†<êÛÐmc: ›¡_lµáYíÜä¥YØŽf€¦³fX*ÍsQ0Ë~ÀˆfÄ`ÛôÝx¶'1Œfç¸Ã ¢èŒºdðÖ¦~à)jùÄCG 8kP#æÅÕ¼Àý[ê¹G•æ}!ªmûiä™(à¢ñ§)&*ŽJu+—,”UŠ¢n1†‡²kZ3<åŽÍÎÍ ™"Í©H’²š—©(âÇã³U0^"EpÕ´ÈØˆÄ.d®nнßë–Íj;`ÊS޼ü½¸ÇÌ ß“G‘«£ÈÏxXWÎP2ÿ4 OÈJxÏó¾åžÕNj7ß|4@£ £›es CT:ŽCG²†¥G¯ì°¤”uV½Â›30PˆÔcÿÂ+7àâÔ)ÉÁ)G£ìMÛ¡¹–(=Jì°Í«ugLÁõåGž±½õùV´iȘòëzZC»9g%lÛ.ÀûïY=Q¹"csÌÏÕJ°îÝѺ&q> endobj 687 0 obj << /Dest [ 686 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 475 88 489 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 688 0 obj << /Dest [ 686 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 439 283 455 297 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 689 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 690 0 obj << /Length 2294 /Filter /FlateDecode >> stream H‰ÌWÛŽÛF}×Wôcqx•¨1ˆdgwáM‚XyØÍ‡jIŒyÈæÈò‡ì?ì?æ!§ª›G#eÀÙ]‘¬îºuÕ©Óo–“ëå2¾X®'~ <üÃO”$®—x31_Äî,ñB±,'×_¶‰ÈZ^ã‰6«&×wï|±i'žëy´&›LûÇýäGù]êLC7’E¿q(œŸ–Ÿ,XÃBÌ=w1ƒ•0qgž1 ÖEOñ̨úO€¯ÓÀs¦~èΤ—ˆ‡ƒxw¨ô_©h’mÞŠ×wWâ_¿:Óï d±ËÜñd¶½ïö¹þ¨š‚•„2­VÎt!Å¿ù/;ÆáshçÎð²ü ߨƒý~ï:¡ëË–¬*2 Õ0éâÑCt™ý´eM_/'¾ÈÅ$ˆgn8óE8w“DÌ|7ŠbŒѨÉzòf9$#ô±Ä{šcª=ʼ\þBÙ‹\/2gÆO}>çQè΃QB!³ õNâŠ;U)JQ‚ ÒBÜõCê$ˆ üóe]­sNÉM7¬sü¹Ôx‘FRWâ[aûrçÀ’/u^W­Ifï]ä†a2?qq¶˜ãuìâ|p1î]ôáÊæU‘gªjU•–lTÝ^á7> ²zÅ+Õí¼5ßÈWrZàƒx’‘~ï…oœ@tšWj%òê†Oz.µ¶of*^£ÂlÕ:3x|°?Uös†¬:ª3ßÜžú7eMSß…‡Ðfò’ yI¬Ki%2ã–ñ(~Á#ï葬j½Í«M_HÏ ‡ƒaF»~”¯©™"©u“?tZµôêK²ì£‰^°Ì‡ £•ºh1èû¾5ø˜æN“EúàP£ÚFª›Ë¶N‹<âXóJÀòt¥ÊZ<ª¦5¥ 7NÂõŽéa±÷Ô/oqD¶…9‚¥XD§ûTt-¿(¡Óyi£Dg?¯„®J÷¡ÀŠ­ö³3 ðÓÀ-Q7"+rUi‘f(ßHš¿5koVtZP‘ Sìãíb×5Ù6ÅrÀÒX°rÅw…JŸ.^çE*î‘î¾í¹>FÛ~ä¬í/ÎÃúa&jo¥tÁ¡îÄ6}T@2xLfB™?"`Z¨ÝŠ>×€æDvõÊê5'b×Ô«Ð iF[~+Úm½¯ÈIZ1r4xZQb£ëº(ê=¥‰â$MY`¼Ë'}ýß"ƒÓª ¢UhÛ#â¨Û_j„D–(~͈‰a$ñõ‹¬.wiupñûêz¼¥Iˆ1ê‹8^¸h'†ýø¿(gƒ4 " â±<öyÑÅí/ˆÛ ©5R ô,:Ý}^޹uSÓ8<Ž9ÂfuüõûNƒðíÓ(~}7ýöûoâ!a¼€c”¯`áF]¾$äl±ðw’uvóïK{»‘™gSuAþæ<Åê'PìÇý§ÂÏßÖçÀ€›Ô6(Z#¦—p瓲ºA¯ê«cÿeZìmöuó„U=èp'oSM#>u|‘; è?u°s\(tÁKu ƺŒ±’Ó”d ŒÁã"LÝ3!) ‘’þ#³CªºòA™Õ@ˆ…‚bkÙn44ÍeªîìfŒÓ ªh@˜©xâŽÑùh(No!ÃÞ"ß…ÃüÏ.½êwžÇ/3ä¦ý£á9+¾©5͇TS d€&JÚ?ì¸4.ø•á“û˜Cæc?’æEÜKœ&//Ö˜¢ ÎedUصÖÒ½ãpPñè¼TS‡Hv‘—¹œ«G>ì´èLòa“½9oø´†A6\(è{ÙêzÇ%Gµ̦%þ ˆåWÄ(2Õha"¬øA«{ÇËÑl*Óƒ)p·Ç!´µØ4VIö¯iÈ®Tu0†hÞÐØQmKUÞÖhœµ²ë5ÏÝ®QíÕù<  ¥ÈßÛq?—‹ú€*0ê]Ñ9L7äU@A£%ú®Pf½P:s^sBëÏçpÏÆÄùHgCA9DÖÅ«2ý€ÒÎø­CïWüDü áSÅßÞPý³$ãEZXkÂË\:L|wüÿqéðsrégý‹SÕjƒš}Dƒ¼ÀrG¼ÚÆôg“ëð3ë üÕ¬P Œ d¢-êª8|ÊýÆ]N¾Rë´+ôÆzºQ0¢ùOÌäE`‡ °~mLMyí§{c{1ThOì·9¡ÙhšúĦƒžJY8£¹Òh2ovIa~ìÇûªÌy÷z*êDo[£Õ"Yöb«Ñ¾"¡f9Ý_¯vV™+]ìnphûTZóU/ê5ñ,¤M3-’6LëU_›·´Ü^]Ò>qm«FbŸ]çHü!‡Ã={IŽf›sO¤$¹wÐ ¾ÜŸLIÁèËÝÝg0*'TE ¯ÔšqæáÀô&d¦™©‰Â4Ç©›á™±:î¥]¡`¦Îél0IÆ`8 aÏâ7„o‰é²Ý´ùG,F%Ä_Ä;@Ü?ÞŠ’ù™¢sJïtƒ;$V¾ŒÇ˜¥oñøÂÁçDáÑîÃz Ã÷ÒpAºlÒÌ}8\ïOÿU|>ÅÁ!ðȦbň6óžÄÍÔóGë ‰kО¬È1ÒéõŠjä6öÖ¾|¶’”AžÔ^]»å¢ë…{Ëæ¶Ð¡Ù=ÏEi›¶¥L-*…´÷š™˜È@²7Š;¾¤î5f—ù›¢æp, Wÿ¨¸{®Nõ.ŒE^œHkÞ^’²ôÉ]ƺë­ÈË]¡Jä1í/ ì®>ßyÎñeèñÎL[\5@KûÑüM]A— €.[>=àŒäŠØ¬¶›5Sw«Îjz®£QEJ\~m.©îzÓ×lK™dWG£èmn儌ûçä~ÔÏÁÐÏv ÓŒR£iÑíãC^v%×Å„øvhîoªÚäÔ,†Í“¶3Ëû1_öÀm«µLAàoé*ðÙÑò¼_JUÖÍw5ö”OcÛ!mŒ­@iÂH¾Ùj”E×ÚÂ#~C G[E»­q7Ù(;¾^N~†6™ endstream endobj 691 0 obj << /Type /Page /Parent 1710 0 R /Resources 695 0 R /Contents 696 0 R /Annots [ 692 0 R 693 0 R 694 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 692 0 obj << /Dest [ 686 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 489 631 505 645 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 693 0 obj << /Dest [ 479 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 446 276 462 290 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 694 0 obj << /Dest [ 479 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 99 88 113 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 695 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 696 0 obj << /Length 2025 /Filter /FlateDecode >> stream H‰ä—ÛŽÛȆïõߤ ŒhžI Œl¯a$ˆƒr‘  È–Ô&9²öAòyÇ\ä¯jRÒÈsØEœÀ@|»›ÝÕÕUÕ_ß-g¯—Ë€|Z®g~@þâe™ëe^Bé"v“Ì iYÏ^¿ßeTìdŽG»¢™½þøÙ§Ín湞ÇsŠÙ|jîg?ª?æÎïMÿ³î*ª¼)ùBÑ?äW“ãËÑÏMÐYþ€1Ñ`¿ß»NèújÇ»jÞ¢±¥‹¦‡ÓãÐV$}XÎ|24 âÄ ŸÂÔÍ2J|7ŠgŒ2êôl={·<#ô1Å{h“©=¶´\þÄ‹F‡E®aBä†a–’íNFMãØMƒ3«zñdÕÉA™9ø¯èMiW?íÌÏúæÚIÝ;e8 †M=Èœš0AK³ßç…9ˆYëA±ì2’ŽÚ ލ“6þ¤Œouyß6}n]’i®Å¤©:Š4qÓÉ)%V„]þfç$n¦ã£)þZ´ÍÚ‰fss©ß\$±þ!K³æÉŽæÉF•ò† «–Õ(~A#{¨ùÔd¦éõFwtŸWƒ¦[Õ õ ÝvMŽï©Õ¡×»[çiõ‚£z~rvÚ·àpAß™ÕÜõ+é#°_P2•PjÚFOáôŒU|9’úA¯ó¡ê¯Ç£`\îà$Ø—[Â͈EQ“"Oþz‹ñ´N2ê7—ÕÇCzÇãÙ(÷NŠœ„ϧ&K_BÔÖñ#Rû|C¥îu¯gªv˜%ïl ×Äào´p/ÇtÑÃ/ÆÕˆûL¹dz]_Qeþ† â$ ¢¿’NNE^¡ `@€{ß8>ëP:lúÜnNºémë@º/\¸¸Àn#c:Ö Žq؃mó{íÒr œáßN÷Ô·”ßÝuíñ0.Fôé“)XZ׸ôÛ5ڡ㙕)òÞ´ móUyÇX: è#H^¨>—sîX2€6?Óì9“[{ª¶Á¥¿¢~k-Ï?Ûv¨JZi\ßÂNÒ9V*)/ÄÀEkßZ{™fS\úCÛ;€g6͆伧¡/€Ú[±=Sªæy¡bÉq&ˆ÷ÉNš27¼u®Øo–†QÍf{äœÃéã @ïnÈÞLèóndž¨ƒ U¶Ú®¡¦íáÊÁö8„—µ®[»æ0®çäMw“Üq™áÒ§q–p¹ÜŒæUÕ™àâ£>JO>/]ÛTÚouC¹“IV‚]ûrêÁŽP£uéH4MOb^ƪu¤Î˜ÝsðHsãÌ™z¼1î‘1¿$ÅIŒîy* Î`†Dƒ„‚íß0²ÍF:¦ÜníÜ\S¯¿ð5°M‰û%V38âÚ™GÐðÀ¬–÷ñrBŠ‘fƒï0!ß*!WRv9[”¯¨`×yt¾ú¹ ‰çÛæœ‹ãž7ñíâÛK'쳿’+YðOíÁ>õz¨˜ml%e‡î°Bf}@TÛ‘ÞaÖp”ᾘb{ÒýÝ`©[UìjØPÕnhm*=NAñHÐÁ·—9SÕݤLkÓ7º¤wæŒ=μȥ=%¶|NÈßà,šÖ-€Nwy×›bÀeD:Øí@và×hœ#:]´u­›Ñ XùÜ^L[šþBÄùû ñˆXL™6•rޱI®hmêkÆIº“¯¹m®$3 0<Œ+Ù€^½oOÓÿ¸)Ù^+‰|\Î2‡»G ? wqV$h‘Ç.ät[&äê“?DêÓÂEˆÐ{Á+÷×”Õ‘ç»Á–?V&r ~‡)«›aÚK1 »[:\3M¹d9R-9Q ¦Cì Û—J“±o™$¤ձä’îeÔ…iôðûê;AÝ7«½ÿ3Ô]ÖØÿ£òúT]cÃûÜ ’#Uå+‡µF®fŠ]¿pæ“'­+QOÑgù>Ň)·ŠO¿G)»êòîQ;’ á) ?]‚ÛïÇã§äÄâ,öàwg`iÌÅ.JÁÁY(mxE!æ·šN—AlßöÎï ð»â+“Ù…Ôwyc§¢„WMß[éê¯^[PêQóuÅýÄW«3Z«Ô÷¦@ B&ºiáÚÖÓ(§ùRßHµÍå/Ù2…!Ì¥!Šq¹G 6–û¼žõÕ]¸¢W'ß¼ýøêq"Ÿ€<æ ±ÁhK®Õðe ­­Ð(AŒë¼öà:¸FæDºª §BÌØyôR§ó’éÌo‘6Æœt?}.°”Îä«JKí‹pŒn_WaêÆÉ èL't¶¥®¸ð³ädNJÅ×"Œ¹ ý…­þBTX KµüV–°¯9èe€YÚäҬ픗Ápä}‡àü¿¨Ÿ<øwÎðipÿ5pòÕÀeœJ„&¯õ­óB5ƒS‚¬‘-ŸCè%•µ×j$-Cö!=íçd¢ìÓ_Ó³-Г‹ØD]2T"ÆWJkÁ'ö˜?tÿ š' óGãfê7tn,kä5Ù:;‚5°F ÖÂÒÖUœˆ|Ev>s4y‚£™å(WÇ‘²4ÍÏ*Û}mè³û,¡4õa9û÷¡Êë¤ endstream endobj 697 0 obj << /Type /Page /Parent 1710 0 R /Resources 704 0 R /Contents 705 0 R /Annots [ 698 0 R 699 0 R 700 0 R 701 0 R 702 0 R 703 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 698 0 obj << /Dest [ 469 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 348 685 356 699 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 699 0 obj << /Dest [ 479 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 92 587 109 601 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 700 0 obj << /Dest [ 485 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 168 409 184 423 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 701 0 obj << /Dest [ 479 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 190 382 205 396 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 702 0 obj << /Dest [ 563 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 276 133 306 147 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 703 0 obj << /Dest [ 563 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 141 79 172 93 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 704 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 705 0 obj << /Length 2256 /Filter /FlateDecode >> stream H‰ÜWÉŽãÈ…¯úŠDaI£ÈfrW¡ÐÀ¬ ÌÁ0ÐòÅ]†AQ)‰ŠÔ0©Zü!þÿ£~™$Uªr/ÆxE%2—`dÄ‹/¿Y-Þ¬V‘Pbµ]¨H„øÃORAX„™È—ia,V‡Å›oM!*ÃkBaªvñæÝ{%vfaHkª…?>>,>Èß–ž‰Üiú¤HSáýaõãbÉ–"ƒe†¯ÄE…ö#l b[ô”fÖÔ_#ŒúQèù*2bý$Þ?µÃ#‘Ô,ISñõ»kñû¿y~Š÷siÊÚ eµ¿ïêáϺoØH,ËvãùK)þÂÿÙ1>>- ƒ /«ï0Æ<<<^(i諚> Óød€Ç§«ÜО-}¿Z(Q‹E”fAœ)çAQˆLI"pƤ½^l߬¦`Ä KÂçјCRDàåêO”°Ä%,  ’ Ž‹\Ø×1¨yšytÕ0"d^äRÜV]»­w÷%¿öooÄFóã¶nµ¨ø‘Vx…Üúrðr Ð[׊û²¯Ëu£mÜàRq‰¡ÉhIXšýPcr•ì·];”øâFÔí 3—“YÍ,ÈÇt>¬ »ýÖxYPÈ'÷ÓV¤cy PïÞ^úç³%_*&kÖ¡Ìæk‚M"‡¡¯×§AzU’\R€ËÇ]RË þôH޵åA_#PÍɃLºXÍD^î(6»áìÜœ´)dwµ·r'ª²k-N¡:J^6%3;eɈ;i4å”VìQ-©,ƒîE"¶]/vºÕ}Ù x;”C —ëî4!ß•Æì29“Î~¥Ö¯g¼ó`L Pœ+S, Ddz[7ˆ ê|çEO‘OD|€ Ç S¡„sZýóI·ƒ37Z2º:woÛ%IZnð½ºÝñ¿º“p–rW©¦ËÇà,Ÿ“¥æœ;,sI&{0fò­çG€•Ø—ÆKQþ¼]Ôy Ù4!$‘ä\ üñ>BÚrãÀ÷ƒÃø&%_¢ìÂÍ_1AüŒËщ9&ùÒÍ\¹™bڣ쌥bÆcù¹…(ˆ“þ¯°ÿÕ`¤ÒVÑmùÔk\)å±t½Q{'Å^o4½Ýyׄ½'6ºÜÔ-mÈäN|Ű ø˾$6fv婜ƒ1È:™(üY§8ú e,¢HæŒ_2~’!|µ(:‹ÚËâ¾¢p¤L:àD‚fÇÀ#K`†Âd@QíÀEy6“ÆÔ»–Þ‡³-ˆ¶}XsÉ7:¿é*9·kÁ¶µMû8§$–G·¹åÍœ¯htЦÀ>„éHƲðQ\ÔäL‘¡£H4." y&…ý9Â%tôªÞÖ µ#i!®îqøLRD¯¦ôë`²A¡C¬¡‘ýìš*¤ž~¹nZt®Õ3N¥Dr랈ëUµýR^•éòŠÎŽcÒ®ˆ_)ZIPçÚk¢[x.›óÚ«çá=µætçà˜´ÃÙ6uÙò΢[,ºók¢ ¢«É; ¸ˆM‡@¶ÝÀq²õ|j'"¹D¶/jÍÑrÉykN&?£±5«›®¸5U_xжü75]£öÝ8È» !·ÑÖ W{0­Ñ|Ú1nF욎PÄwÝš¦Œm"Œ*Âw!͸š“/:jÇ£!óeWydÏÔèKF#ÌÊ£/ —¼(àÈÿÑ<Ó[1í“ß> endobj 707 0 obj << /Dest [ 554 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 346 712 376 726 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 708 0 obj << /Dest [ 554 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 115 658 145 672 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 709 0 obj << /Dest [ 559 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 481 644 511 658 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 710 0 obj << /Dest [ 547 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 366 508 388 522 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 711 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 712 0 obj << /Length 2159 /Filter /FlateDecode >> stream H‰ÜWÛŽÛÈE^õý–& ÑlÞDöz³ÉÂÆ=Y‡jI½æEàe4“É?ä÷!§ª›¤¬ÇN6›‡Àƈ}¯>uêTõ›íâÅv %¶û… E€ø‰³Ì² ëMâ§Y‰mµxñM—‰¢ã9èŠzñâ»[%Ý"ðƒ€æ‹Õøy^ü(ÿ˜{«ÈåAÓo(E’ ï/ÛïÞa#Ö¿IqJ”ùi`á BÞ‹¾°‚·úGˆÞUx+ù© 2q÷(nëþˆžPj;ÉÎtâõwKñ矽U‚v‹±ÄO¤ñY—âölú¿é¶äM"™×;oµ‘âïü— ãëóÕÂÀOÑØ¾E[p>Ÿ}/ò•ìèTMÇbkéã3Àí ×uä¾Ý.”0b&©¥JDk?ËDªü8¸cœ‰V/ö‹7Û ŒHaJð)3Ô!+·?‘Ãbç°ØbLˆý(ÊÖÂ6GP×Iâ¯C·yE=qPæ“ånSåEÛ¼z)vhš±Ü/JõÔ!xŽ 6dפ™7DžÙjô¦²Ç~ÓÔ}nj½¦~Éè­å´­ãbê¯Güiᆷ°Ëo:/ŠÖK`•9õ¦>¼º6kŬ”¯"ÚÄ^; ¡/¶$¯Ea­±†$ÿÊÉÙ-ν~ÀŸFÜi1t|Ñ€­°ãÝRtZ‹Ô/”?úî‰ád Jéˆåkâo,û¾5wC¯;j*I*xä P%Ì”:¯4ŸxÄ‚«Óg?ŽÚQø?06±ì¼À㢸óNïáBâ¼#Ö(Ò›Nôǘ5€¸È8LfhSÙé¢7MÝÙV³§¥ä’½9 m¾rQ9›OÖ­g"¯­¡´…/nG°½ lQbß´0Î-;¦Š/.¶›ï&äÚRh§3ÆjÔF½™AŽÃ dçÕyÚ…/,áV—ŒùèU‡`ç±Fñ½9À~KÆ¢ƒ6_ŠóÑà6©Kˆ09 07e°¿Ö!­ÞëV×…¦g¼yÌ­cè¹cé­˜æn©C,òÅt寗4 —1~©.êB]"ˆH})›Z¡KÝ =¤߉¬òS <©4ÉÎç1ý ‹®å®ZLËÝ”/éP²Æ¼øÿP‡ž‡Û"iA€Îg30¡Èjf†ÆY;¨SÀ!2Ô¥©L¯wþç¿Ö(Á/*ƲnjýYiœ1S|aùVïó¡ì_~u¸bh7žÒ[Î`3&:‘/BS~îò¹_굟ö¯á%M l‡[÷„¬SLPV”‘2yðhŽÜ Õé«üoÔL×Rt¥{Oj¦è³2lå Ï£ ;‘—¥hN¶È± è-T,†ò5é*Dq¯Ûާ¹2ˆß7š^5ø*Þ¿º^]nŸ©2 ôr:‰®äá@‘|Ì;eˆ¥H¢DëÌ¡6{ƒJ­Gôëúh§Ò»MÂ2ÊàÅj2oÞï ö¦Ô8ëÖCÔc'lD"N%®lËâg+·ÍléÆ=«LD9 ª¡8rM’BïB.(cJ\ ²X?Ø&.…WãÚ{”P×rà ^¥ÏTŠs;¸ã'"Jv2F©ÌwO«B¦Õ¬ôjTz•€ˆ"IÔú,bpµ!Å[‚kÀ˜§²¡lP"˲9“ h¥#„›æ)®íxL® ñl‚ŸC‰'$VA;ST|ïõt®vçøò“‘|÷l!­Ös¶#xióðï\Œðì0#à7vØÉ?.„¦géTs^ÏN-’ïp#‘·±9‹£Ñm^ ½#6L=X\–\Ã?"G¶¹ß¾!L½C>Ã÷]ÙÁ@°‡S*Riuž=È Ô„31åY> Z]ï\N=´Íp²1K<3O '…m. ÝRDÃw0˜Ü·D¥­+AÐåí NMÃõUiñŸ©¢™’.…Þö¸$<ÁYè8<Ñ¡˜u©´ƒ•Ç<Àê,÷ÚšóB˜‹¦lìL¦L(wâ÷[Ì|Ï}ïx?~Œ Jù]GŒOÇÉâÞ¤dòlÝ”×vøq'îìÆÍ™Žv+l—ïòy=­³ÞX»G%ì-ó^–/蔇 Ùòá8`ì$þ ‡ã\bÃy7˜²_Á¼ïóûÜÖ6<_¼3õG÷ü„8ü„¼ƒV_© ýYCF!ÏV oï9ø€š„¡U£\Û•(̈¢¶Do  n&Ûã‚¸Ðæ·"-È]—ȇ¾©ÀB+9íH ó(ò'øpØN~ÑîíÖÖ H^ˆqi7§˜¬Í¢lÆE¤¾ˆ{ŠaªSŽØ_XçV£J¶_>Ïù>HgF¦öšNJ*ñYy}`eqnP劼ù+ãÿŒ¼¾.{ÝÖ Ç½¶rд  ôHvÿ„Zªu‘­Kƒ”cXsk‹`w 5^ciÅËÆ”=‰ñ“æëX‰¶’øívñÏ×ñ¢M endstream endobj 713 0 obj << /Type /Page /Parent 1710 0 R /Resources 715 0 R /Contents 716 0 R /Annots [ 714 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 714 0 obj << /Dest [ 479 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 254 617 262 631 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 715 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 716 0 obj << /Length 3016 /Filter /FlateDecode >> stream H‰ÜWÙnãÈE^õ½L1°hî¤ Ç@/Ó3 &ƒA¬¼¤4Y’8¡H¤Zv>$ÿÌCνU\,y4ú)h´U¬åÖ]Ï=õ~5»\­<áŠÕzæzÂÁ?üIb;‰‰xÚQâøbµ›]~h‘µ¼ÇmVÍ.¸uŦ9¶ãОl¶è‡ÇÙgùKj-|;E¿ža,¬¿¯þ4[²„¥ˆ{á?±#G_Â<–E£0Ò¢þãavá9ÖÂõíH:‰¸·U·ÅŒ'•I²-Zñî‡ ñ·ÿZ‹ß ÖB;”…åÈl{!nE÷/Õ”,Ä—i•[‹¥ÿ濬›Ï¦yŽácõs¬Áñx´-ßveK·*º¢q¥¡ë23µeI߯f®(ÄÌ #Û\áÇv’ˆÈµƒ@ÀÆ š­gïWƒ3|[œ§Þ]íG åêW X`ØN€ íûI,ôgïÔ8 íØ›xÕ¼ê¸Ú¦Äv]ÛµpŸ×e½Ù§ÝöæJ`"”‹FñJÖÕÍ£ %½°®+¦9/«ûÃFà¬Y,JÕj_BÍä4¯ݼ%åר›Û«f4ûPW]ZT*EuÅŽå Ö¤kdÇ}ˆ(gX–×9)uÓ;Ëh±àý ìÓí’dpIb.N+‘éËõ½á÷ºÞ÷4$k+ÎȲԎëj‘À EþäÑ£8n•™¤­EIÛY&ê~ž•ÛâK¬YY=ËÊýÃHÞ²Òï~á=zJëz„}GÎä½Û§d}±–¸êztåž/‹ºÒƒ ±/UªÇf‹Ø¥ÿTBOQòû²AVoÓŽ5{²µù¢±oêLéiý÷;ZD“8˜½ 'A³ƒKE†¿ .se+˜ôWkAvû—<<<ˆC•ãÀÄÂ1‚1m!ù$0ÉY\oT\(yIN×ÞåNuۢ°n~Úç!ŸàÂÏuÇ¢Þ#Å\‚:ŠÕ\Ïì9ˆe¿ØßñJ"µbfÞÀ ‚Õ*%˜’™¥JÜ+ЦËH–3ª5@º®×ªQU§¤í{qÛVà&S¢®Îº#: (˳dtc~!{OºSmt°Ä¥¾µkmñŠOž‡ ß?¤;äü•†ÁO®élvH»½`ôYöÔZ ‹K(Á®ûÃüXT¾7¿ùpuw ‘ÝÝa_{}Ù·Ýž5$>:£ ªÛhíD&tá­Å0êEòd9t(úÒá×W‡{#{é™U„5 N?¿–3rPKæaèÒ€9ÀË^+‹êð0¿¹ü’6äªKrÝ®|ÙmAL·¾¤ÿ‹«ì8½úŠçž?þÆrwtK^ñÝ ëïW¿•ð…È á‹vLŸ¦†s­ªô¾T7â:癢åï·Ù[ @¢ÿ öfTç‹«ZCýKŸò«¯§V:.ë}WÒ}Sv]=~Ê®ðlʵ„ 1×í>–í’à˜Þl)!¹øêuÆðä ½ÅX›m£ÝÙ*ðh8n‹ Lùq]k$ÕÊ»Ûm}(sê&½Bè¹NלÛÐ`1ê0²›pÔ!Ô~Ø Â¶€*`')ýÕawOÜ]÷¶jŸ6)Ó䳫÷EöDNIÀ=2,mè=¤ i/˜YµõŽ:ZJ±iêþ}žŠø#ñµ:õšYšØ! ú‹¾-]jî”ÑÕÄ&ÉzšVš%•h󰔯£v 3h±à–]mJÍL…3Ó¼ÑäÍû:'Ê u­£í{˜LùE·y0È“=íʰ1DòöÄ•Ö"aZEéÅF.Èô+S&Ÿ¼‰ÜÐ=¹üwºí„SI§Z¹‡šYêB«¦ýPÀC¦?-Kßv½éo3óœ»Ì)bI2ÄÎ|@ýðÒ‚†D†ˆtlˆÄ0ÅÓ;h‰“MOˆ¶3+M^sóÙäâÇÕŸ­EŒM?Yî5©Kß;Úêõ7tòWßr†Ó ÓmVÍÜå4xæ…Ún-Q[Ao‹XêoÖUT<÷z‡ÅÙ–ë9Ã0I#ñ?:ÃýK{éšëÇÚ'éc{Þ“öñ_øÈŠ˜’ Žyù+Cïi¸œoënþ+=j±îïˆ+±«­Ìm'ŠÝ¾nº„²``÷½žOj|º#à —Ÿ.Þ;ËÖïˆÈy^•¢G1ê•1– þ9AÝT™Úwe=Ízܘ0v¼3+>ŸqŸª×k]Z\à„nèDT;‚bEIX>’RÀ„ HÃ*OuÒý¤UÕÆtl!„´Fn»ë´úý´eõ#uðÌ­‹ÓfF|oêïxbÒ=û9F†­ÓLUfäNÒxl(®áú±˜H²›ž.Y]2Ì¡€€¬ô:ãé)–ëe†Ñ¯Àá;·OЈ˜˜£³1ú6äù’öMÝÕ†*œc’¾š¢WâDÑc)ÄP×%8#lbâ5DDþiÐ×&¿9ê:)ö”Ü›S`‹üŸ‹Û†N¢â“hVȹ”:†1 ÏxLoŒ; szýdsÎí€nDš*a’¬.‹/§3b› ™\ª‘èp—Ëè$Ä_Ý‘‘"¸–O £‡oÛBië<Æ€¹drräŽ?ÄX»´J7j§Piçñ%jIDùçZ³©´}9W›³„ùqÓ£ë7h±‰ÆÙ4ßÕü”•¾eá÷@ÅGM»™ïlSt¤ZäµÐ´†„m×P³å&H}¨CàEžv) “`.éªl[7àd]ÚlT‡Á.ÝãL‡1ÙØä„•°¢µ"?Ub¹·¨6G& Ú!Í„„hÌPèy#ë¿©‹µ‡Éâ³V¶ôN³ox½èa‡wÑÄÍ[@CI;z(£6“ÞÚÑüSßÿ â©7ÝYà>ªé]Öñ£4¨$4úܱ@[ìûÚÒ;y"D£¾†3¢í cTyU>Šbm¹L@æ Ù û¡I ÃÒ{Ï…›îd«—\Ky¤¸›º€M®|£8úÀ}#¬wÚÕµèzrmÑc¢>¤ÜëíîJ¬¸Ûm‘…á53žú.c¤ úiÀ·Ášèއą't³Î¡¨é‰„*Ü/ŸôHÒ\€Éó\gQ·|üΈÏÕ—"S‘_½éÂdyòr8ëní/Aĸw/è R¢Jwꂳ oD ¯«Ù ˆöÿ8/›œ ï=;!ÑdƒpoàÈÐF‡1Ó3 oïû¡¡EMŒ;~šªžšê÷¾*âå(Æ›³äÛ˜=)Ây¿8 Šs?ã[@›™Ç›ê3_›-H`ß|wÈ[ÇŸº«gûÁÉÉÝg+1âï;%+õ`¦nP0޺˳†‡@8ÃóëXŒú"xPÕEêì&…Â7ðcpØÃmWzaž Loתݚ‹©œ§8äÛŠöSBŒ¸N£/»2„éW'04õßœxƒþÿuâ 3ÈYÃ)zþ ?`Ö2­—F\O^ˆ<#ñdtêÊĻɑ¡§LÅö€œÌö´oܾN`rµ ÂHŸOǃNZò¤¦ÝHc¿Jcï½XC˜ãüaÑMrÛRn—Ø’Ü—c¥QeUS­£r°WüŽçä4–êêh~‘ mE¥‘Új%×—Ò]ýŒÇ§«O¢ùŽ endstream endobj 717 0 obj << /Type /Page /Parent 1710 0 R /Resources 719 0 R /Contents 720 0 R /Annots [ 718 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 718 0 obj << /Dest [ 748 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 368 661 403 675 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 719 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 720 0 obj << /Length 4121 /Filter /FlateDecode >> stream H‰¬WÉ’ÛÈ _û+Ê}qÁÑ„°/ºI3žÅ!Ùr4OV; P$ᪧõ!þÿ£~™Y·–ì+j…Z²2_¾|ùvyój¹ ”¯–ë?Pþá'Ê2×˼D¥yì&™ªåîæÕwC¦Êçxj(Û›W?Þûj3Üx®çÑœòf1=>Ý|Ô gº‘Þú ´Š3åümùÇ›œwÈUê¹y‚SÂÌM<9„7x/zŠÙê_Fç,üÐM´—©Õ³ºnÇ-Fm줇zPo~¼Sý·³ˆñÞã[ìÆºv<]nïÔýS=~6}Û„ºh+g‘kõOþˆñõùjç&xY~1¶àééÉuB××jèXl#]Õ“ÃÒF"©`¯ù„ +ö·ªk›g\€æ¬ ê–v  nU·ç›€ð·Ô“i…DàXØ„¿ˆµ?1ggÊ•-Ž9/*dÃ{g‘p&äGñÚ‹ wý nÿ&^ ðÜÜ? ¤?Ÿ:¥+€Où´åìCäuŽÄæ`_íŒc ÊÔ;-­[¸µT«æ`&#¯ K£Ÿ ÿ ljÇßÈàóvì‹v îŽõþöÂÈÐMãSìGs "qÙkuÏp‰ˆü‰¬ º=‹û}ÇdíÛ¯#аǽ:ŸV©åwd…¯?¨²Ûí­]E™®,ítŠÃƒÃ‘°È—ºe4Ð@6¥øÕšëÖU¢Ü·ÓtáVɾßy®ÄÇ\‰åŽã`Ÿ÷FukÕt »°'B±ß›¢§P£Bqmšn…¬¢,ŠAÕ8|3ØÈ\d®ŸºÅ×sl‘ÐÙdެ`à×òT.<…ÊYîš¿÷ããSÅnšQ'¡]œÇ–iýýt[~›h¯"-!€óI”ïßñí—]×<Ö#‚X™«K¦n_à÷ÿº¥Y÷’s¹/1ŒÒz’]/Ä÷µzÓ>«Ñ šÕas¹)Ü¡QU<Ñv£Z㊈yAK×úbÕ}¬nONÉ·¨½ºÜ™˜a-îfw¿¸â=^dþÞŒEݨaØt}›Ÿ6%8_TÄÅôHa/I¡ã°¶ÈSê­êá…lÛòµÆNŠÍ¾.eÉ|Qxk4²4HÉ`¨4=‰B%¨¥£‡œHÓtùXX…ÑÐ&â6ú<†{l¸ž —ÀSôçõ9Y²cÿá,´8;0Ì é¤Ü]` ®8ÚÕi ”,xe.½¨v*{ƒ T]û¼«?# à›aBãŽ<À«~7°ÉTïý Ïeǃ3 9p§ªz(V !'|œu zæÌ} ŠYfoÚŠ…‡pZ%€.œTŪ €À¯‹ÒÜñÂÛjUìë[~Æ,"}‡ê ÿ;RHvÕò÷0fWo¶£’)t›û¿¼cÊÇév]Ô ™p‘IŸvëlþ"Fù·$R?"•;ž§ZH;áÜtÎÔtâ–Ÿ¥ŽEz®P1j„ ‚’fYõg'–RÑJ0€Á˜&"ò4€f@Füùû·\A#}'6­ÝfETéÔEð™%ê_\`'?b'—; <(ܤ\áû„›•í†Ù™v”!Y¸X¢å b,†¿Jú¶­y7° nFìfØ7‡ k%€¼8=©“9FÆäjöÔ¶l•ý  èLu)jíE±ég³ì³¹ñDN ‰¯êŘõdvÉàaGN3( Ô…RŒö½’÷DÛ5CÇ(ÝÙ½PCd:o5 ªÓ·Öþöv£Ñ¾S­µ‘S¿f”šna»0»ƒ]±v|Í:DF§[ÞZõ'[L»[-{zÆ-$üÙ†,±|päT×YÐ#ùnO8‰Dhûϱ¬¶"ï*ëúï¤*Ù”¡iú,»SÝnhû\_«þŒÒ57ÍDð{nž\)¢Sd’@T«ÂIðS²¨å7†-:Ø7"é?¼™þY´† °i ºP¡4«ÿ}Ý>~Qýû©›ýâßsƒK‰ø«I-R“Ä»bµ,š)èm÷UpÇò½ʆvuõ]Jw¼âB ÖâÏ¡`Èü~£æE+éÏ&Ç¿YtpÊAÌÝIõ~|þ:SÁ1eQ‚‚¦ÀÉ\JD‚øc.ϧlîìê=–Ñå ÷Nïï+@Só6 ®C'å̓uʨ¶ãJÛ>9ÂÃù:ñtjËUSd®öµu%°'“™Lò˜%UœþÝÔöha5eZ+Åuwvý®…~e,ü£9òÕý—Ð- ‚à’;«3)Q}gÜ­•ЫÆíÓ¥d=ºp+-¯¬Æ!Kk;÷Òè{åªIçDWèú9`Ô… $˃öƒ¯\ê2 ÜlWºûJæ1qtÿ#òE¦õ›D »¹¨'0?ñgÝϾp#EC$sG&2X‹9ºŽŽ•G&Ü÷$½©vT¯?hv:2©bçS$Ä•t·¼AÙ+óréÐz¤ÜuzB6^ÏPÙ¨{{“’ŽÐÚ¾Us§O¸íË"k¼¢¼Q“§/±©º¢NÆE³¥vî*á`]r©ÊV/I‘m}èžâÎþ¤2H¼Do±y¹"û‹iĆM[©¬Fv¿oÉgDG‚ìOC&‘¯¶¡S(® ß¢d·+ªÀŠé XíÅIZ"Î%­4P…Fî$ϽHϹ-ÿ¡þÿ¢ðçôð¦Ñ{ýרƒÞ”oœÌø”°yÓ"œ ê’æã)Ý•C¿{Ö0æù¥ïÁäÚÇ¥PâLTîXÕÖ‘·r´k· Çd;·Mçýö¡J¯V4N¿göI,À÷Àxä/ô­ÞÎ`Kî[qK@«ãÆ”öÑ–¬‡6p‹ôæ3»œ+½J? Ñú]iQL2Á †¢¹•åV¶Üê„G0ó8!æKMÌç ¶ßÚ)¯Óì«É¡x•Û ‚ÿXdLràš˜Ð®(‹æ–à<yƒ(ÐÏoV¦ª ŽÏ `øÜ¾Ž¤v’ ~´õûŒÚ6؇¹W×`¯®ßÔi6ÈS`îöêì8¥™^}­Ë‹¸´xlìT¨u„‚eò 𘣃´ ^iy”6‡Ãixíæ°" Òçïyv¿TPØY°B•ëZýÊh˜èr¸'eÜï’6µ‚ ×Åõæ$ ¡æ€ÆÌx âpß̉µ˜¹–˜ï[> endobj 722 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 723 0 obj << /Length 2541 /Filter /FlateDecode >> stream H‰ÜWËnãÈE¶úŠ7)b,šÅ·N3Ó=3iÌA¬ƒ¸{A‘%‰ŠDÊ|ÈüCþ1‹œ{«Hʲ‰7 X¬÷}ž{î7ËÙår%–ë™ „?üDYæù™Ÿˆt{Iæ‡b¹›]~Ûe¢èx/º¢™]~­Ä¦›ùžïÓžb6>ïf7ò¹;½Hn4ýRÄ á~Y~š-ø†…H}o‘à•0óß<Â|}ʼn¹êïfçïÎUè%ÒÏÄêA\?4ý3Ô.n’]Õ‰¯¿¿ù‡;1>`-öbY¹¾,¶âú®êÿ¦5_ʼ)ÝùBŠ_ù? Æê³jï%,?`Ž%¸»»óÜÐS²£W5=‹«ñ¤‡OÚvjË7}\Δ¨Ä,ˆ/L”S/ËD¢¼(Ð1ÊÄAÏÖ³o–£1B…-þckL¦öÉ"rù×ÙåwOü52ä7>+c6Gf3Þ´ Ù[–ËÌ^ãù‘Yaã«„žº‘ήjª]NÖR°–ÃjMÁy‰=Ňbc¥wâÓ±ë…Cá–y,‡–¯ä§¹Yn0a)ìü¶í‡æ±AÑyâ)˜Myij=R·üw:J§iÐб{GÍüʼnfé×ôi”$—Ë¥› ¸·n «Ž?E…H‚^vÔ»ô´®E©×n„à€æ<ÖféQÃM)Ì‘m{gÏ:°ïq.„£®"«\úßšZ(s³)ÇÀ…DN^ÂiÃ`o÷C³¾~Î1KzÎvžGž"ëªpPÆ“92JïÚ^Wͺu<±Ü"Ñ6Õ­îp™hoõá¶Òwân‹g½Tæ½Àú6ßïuS¹ ¨ÓlDy’X{ôØéƒ€Æ¹÷8 °#Z¼ip˜ØÐ÷½nJ]>‰ŽEzÁÁK—ÐÖ`ìAHd šæ‡ÝÌcŽ£á!óº¼Dçį"¯w­Ù×»ì*ô-ùÑaôÐoÉ ú¾pS a¡·Gî™3…ÙVí{¸[à¾Î×÷m_OzOS-JÙšÉY30æÜå÷Õs¹–f'ÖœÂNEƒ5?޲ƋAã(^la®¶¹€ÉHý…¬]Š£cIœÉ JÞ#lÓT’ÒÖ×|æg”´— ˆk]EÁ­¤(íGnÌ»ªñîjJ›tñ8o”šPF"?’C2€@ßn4J=˜H5¶,khd$¹…BÉôâ®=֥؛ýmy,4'¶jñÔ®µW×¢ÎÍ܆0Z‰ºÝ˜Å'~ë| ¬‡ËÕ™s/8ñíd™SÏZ§t÷°-é×·œæ«¼Ó"'÷ƲÐ]'>K<`K%ƒ]¹Ê÷Õˆ|õqS5®­[°m&?»Oìzé[šÁ`&0¸>rÄád?™ 5,ñ'Á™8XHÜð`<=Èãñ54OMÛ#P‘¾©ŒáÇÔ•n(ŠpÂõ=ì§Piæ„Ì »mƒëö ®Ü6’!¡š –´˜ Â÷xvÇè ³Ñlç†9Am£çb sôE‡ç‹vçÎI¸½K~ÊûjUÕ — Oá¿Õ'`b¥¤GJ$R‘­°°MWµÍ»3·òãqðF¡m©PÕë]GÔ$~ƒ@pO¢<ˆGï#%Êë*ïàðšµKÄ…!yp\Ã#TpÏ„ëyBÕàM‹[j¢´Ø6D^r¢ÈDçƒðL£†b5f%”Ž{óa&‰p ßPmžy‹gTƒÌo©Ú€Cú•ôL;$ûiNh4ÁkÇ™á4èIœ´¤çLxÐ'õ¦èa)!\Ñ6·OYÇi”M¾„§2•R™¢úµpš ¸%'¿ÄÒŒ©o¡ 6,°Ô«ã†ÑÔa¶³ÇB4lf´å‘¡ŸñPHˆ!pH†çª³†þ“œ· ñ0IÑoAuh!ø'p#‰Jâ‹ÕNƒF–m£Qå±_‹öP‚v{]TëJ—¢kQSÍ-Z ¨£ÚÏA# ›bå6n ø‰3>9É}ƒŠ³¯ÐØZR:M<°'<‚ÙðâÈ4jð`L×QžÀ%WFwŽæM¶ûØô»‰D^¾ÚÂ,D‹¦Dùh ·‚' á««q2®F*þ£õØÏ¼ zñø+ËÃÛá‚zU³ª¸Ï{|ú…uô²SGše¦#…®éHa#”œ§F"ƒsej$j(‚}q•dVÿ…‘ž?þÊòðvˆ&# â<>ýÂ:Œ4eõd®Ô7æ ‹Ñ\#bX,Á- ‘†Y*Ìp<ƒHÚƒçgñ;ó¨Â¸â+Càœ›IÞ÷ÙZ=±F”‰åºªipˆÿ¼“Ù2’v¨Ù‹:„(ÓÑ¡ÝICuÂü¾m´z w<ï¨" :+« 5 Ï€Ìçõû34óþyŒÞÙH;2û0ÚÕÂ> endobj 725 0 obj << /ProcSet [ /PDF /Text /ImageC /ImageI ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /XObject << /Im4 727 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R /Cs11 1673 0 R >> >> endobj 726 0 obj << /Length 1975 /Filter /FlateDecode >> stream H‰ìWËnãØÝë+ Þ Xl¾E†žö`ÒÁ  5›´³ ÉK‰ŠTø°ÚùüCþ1‹œª{)Ò¯¶{dm‘÷Qïsªøýfñn³ñÉ£M±ð|rñ?a’8nâÆ´ZGNœ¸mö‹wº„²NθÔeõâÝŸ<Úv ×q]>“-–ããqñÙúSj/'´¶Š}‹b—ì¿nþ¸X‹„5­\gCK8±«•ˆ_dñSkQÿò±ºô]{éNl¹ ÝÞÓ§ûºßaÅ·” IVWvôþÇsúË¿íe„÷{‘Y¥íZÙîœ>Ëþª­DH`¥un/×ýSþŠa⾸æ»NŒ—Í5ÖÄ‚ãñèØãYkU¬¢¡ÒÁ£ ï2³´I?l•´ð£Ø b‚•“${N| jÕ¢X|¿9#ðpÄ})Ô.GVnþ6KÓ¿Uì:ø/Wô¨ÿû"„]n(‡“˜Õ#«r>Ž×ŽÏ*2dõã>¤ëfñçE ç­¢•ãÛ8³ôÕÝ(>í†~ˆª™ïGnâøá‹×_Ù6ºã8qØùoÝeËÌîË–½pý•íYT¼Øì&kŽú¿žÛGúŸf3ÆáÀŸgÓ¥¥ÇÚ¹ ï„4O×æÆŽœ ÏCU+º,š*/ëíí›\Q®ze¯P˜í¾¬U'G Le]öeZ‘9Nz«·¹ˆÓ^]ÐYÖT•í¹pìcë O¨üŒöZdZŸä¥=¥UE·U“ýjÓV°bûƒ“ýUx†*XS ù1¤ŸÓ™W¬Õ·¾T•Û{wÆk‘¥õ'¢?žiO[;IJ"õåÀbmzh±JElmózNgéÐ7gt,ÙEˆ®lþK»ôN!p,—C‘ ˆ€q º”±ç|îÚ)5H߉ uݽ„6°a©½¢C£ôßÒæ‚‚Š{ªT½íw÷çėЦ¥ºi÷HÑ O*¼÷¤¹gmÍeH¬ÖV- =åîÀ=,(cÁ®9Ö4ÆZîåŽö] Ñ]`–,íG2’1? ¯W*íìe8êõ,¶Ké4pe1#ZEYÛË„C€‡Cõe²EPk½VÖt –8¬æøPdk^©©˜‡{i›íÔ¸Ï ïJóªGŠo+Ä8m{j J雟õæOÜ"ëIâ–'PÍ0•7Ù°Wu®uGœ=®;óf~¸¼ÐßÌû3FWPt&z?KkÎ òQ4ƒ„'±rgL€iÃ>Àã›Þó|Iѧ†Ê‚¥JÚOhŠk ¸ßÛ-ãYÄ.µ´øûœ$†Zâ>-9Ì­ªJÕ!äÔ)²ˆA.á‡ù¶E–T €ª*Y÷™îó„þ{h›Û”KYΫ®×$Ô7´OE9aÎj²i¥mRwª½ïņ Èõ9ØUÑãÊ…iï«^µuÚ—wªº—c猧H Ê`S 8iCû®Õéy1.ˆ PÇ™~°5ú–±¬ÙÒc&ûlñ‘ªÙRQ¢ÞŽ»2Û‰$™m4­Œ8ã•3Ç„[Žó/ÌÂüT xTçbP=!64s[¨Û:›çDvÂhºìKÔxŸîWl›ÄÓÑ%¿ô(5„f< º« Â# v¡ñ:2±FÃ`DèÀ9a%=L%¹xvl‡…PvÒî&.zÚCŒ:á8MhýÐÔ=Ja.ë AÄÊ¢G¸Š1#M°ò'Å—‚™«Gº—rþ5.ü2äE¹Ö½¢×‹¦æ™Ñ4`ÔšîÒjà®…yö1)OÆÌ+>¹ðÙzÏÜÆÞ–èLHˆ’Mâ¶ùu“4ö¬º©Õb Sf]«"ªþÂ\0‚A†º^ˆzCà®QKí èÆâgJFSäÞæYúpcŸSa–ªŽ;žpýËƳÕmð±[&’™ò=›©¾Æ‰ô€Ñ$§¨R”'§ºm*f_X€#xÆ„JR¡{Ø9ÃÑͧ4iìC½Òäñ„ gI…„N¾¡Vè13¡zio{â7?…PUÎäshUQ~ðɳRɆ¶E;£ÜÜ@¿6Oµ >¹„Ué|ŸUC~j"¯Çj1£dªó,…åúqdDëP¥=r·G8š¶×¨ì%_róqµ £eȃéøæÌ~þ‰$3èûýÒ à@Œl§„£áô_­´¤n(Š2+Ù‚çŠqšðG‚»‘n“«Â$ Ð;Uú;¿æOQÎØ~j´ѬÄ`s4ÀKæó~ת4/ó+›ãAšãeQŸúxͯ©û!e=ånŸã—í³3וÅýß‹ÿ÷¿•ÅÇâ«1zÈâEZ1 ØU&fóÌcZ§Ÿ1®HqÈ 0¬¯¿p|[aV¬¦ý'ļLÜÓà8}LºÁ›ˆ[S0s/£Äú5ÚühKç¹¶%ÀñœKŸ%Go–OA –¿‚\¤òÛë…1<ÏnSåÆ3Ä®læB=»å“>š0á«`ËÓnw%È•SG›?çlUÊÉÚLÍoƒ²ç­rÉÿ¡ü»€²9pÜd=Îc É·ï‡Íâ?&‡y endstream endobj 727 0 obj << /Type /XObject /Subtype /Image /Width 700 /Height 148 /BitsPerComponent 8 /ColorSpace 1673 0 R /Length 6568 /Filter /FlateDecode >> stream H‰ì— [㸆•PwPnà„´a»¤] Ã03;t[e!Éøÿ?©:GwYväfg}Žmé\dóúø˜ Ífó@‹Ÿ4Âv¬þ•O§’^KMPvà(ÃÁWJwÔ+¥Kz“j-*{ÙšX0Kø&mWYõ{ÍšØØú¤p|¿Ëî!é{Q£·šß=©²Éýë»wïµø‰5—èM*QÜpkj‚÷ÂWÇâ¹ "ö› Ûãò’Þ¬lpãZY¯)Þ±yh8EUÀj¤NuiN¥7É“!·nkµÇ»Ð›¹®%ìRJÕyémÑŽª=iwºT:ôzºôXGQƒj_j¨BöyB:cÜbз&© ÒëñŸšŸ )q…3–¨Rå½(ÈS’m3T%*µŽÕh4*žžn?.wRøe¼ÜúôˆÂ¨5Ç pIï˜ÿÇÖ@湕²KÈþ ÿÞ£Ú듾ÜÃ}L†Ú(âZû°¡ÙѶlKŽM>;Ø ³“Î?¹%ÒðŸVu-ë¸×dk‘‚C[3•ÑyYµU›ÝŸJIÆSûŒšÑCâÈýXUÅÊwºÀÖb7ó}*ØítÈ?~ûŸ'dÂ({ÚÄvÁ;ÎÏ œ’»Ž¡Ùµâ ZbLOê ƒ<®dr˜ëdSX«ÔoVgsÌžª´½¬º ±[¥óiå´h8ÿù/yº#»úhŒI¹dÈ®˜hÛõUÚ ãÜ$vC’#:8sb̤ Òâ¥'ÇìUÿäU¡cÞõ=Û¨å×6­WŒŠÏä+ö²êª.»§•öݦ6Ú™]Õz4Ü®À‘ËnC£Ã.î;™ø`³Ø=¦|ÑFõ ÚÞ‡*dÚ„Q/Éa§KBì¶ 6‰>‚ðuä'ÐØö»àG-ÚŠXèÓµ ç<¨ìU”nÂZÍAG*›4PÈ röt;-½c2É“Iޝ®cÓ’Ç^–Ô%¹¼Ä=îÄ™5r©„ìž_FWç|îýH úàëéèšøÇ§8ËO‘ù÷£é¾ùxІŸ°èJ#¤…Ë®ìº9ÀÝXžÁÎe¬³‹ì¶i_8ÙìæP'å¶lѸ0bWÚìòr|†Ÿp‚]èwûvQg9¥P£iû$‡¹£IOTYÚžÐ\Yk,Îh>ì´¡²MpZû™MÏ¥²¡Y—e•¥¼c2©fæ´ßר‘—%$Å?W’«GŒ2æõˆ÷ŸG77£Ïbl°NCÇȯ#@÷˾½>Å €í?S«˜—³{XñÙðÊ®>ôú],»:ìvN”—Å.ì'ÖT‡`\ ±k 2­—"¯KÝ2váŽbó`µùÐ#²}ìÐnß2±ü<¢HH2›ší;ˆªN&w±ñ—%e½´€U×2T<ÖÙÈÇÑçs‚«ø ¯ùLöª»Þ¦€tSÝè’ñá 78ð”g^ Ï¥víTZ«¹‚t64ÃFÖb÷H¼û±›E€¥l‹ÏM»æŽE<¯+E%3ûŽÔâ­ÞV½àeýtÊ«.¼ówÔ蓯O(ŒºÆc©ß ÚÿÆÛ$œÂ[®¥WÒ)dáe Yó WY±ðng7à”ô£JÀ›í]ÊYMtEf¯Û.ÈóÉRÙM2’ÐíW{EÍ­ù4‹Ýöv³{I$½ Ið²æN­Ñ”ôצ*óy¯fW³qÂëÜš]5©É[˜¿vüw&}Ö›ÍZŘ“9äš֨Ùu©”÷w3µ:ûJ¬Û­½Ì'±RèÌpúµš[Öëeb×­Jk,¦œ‘µ)ªæ?">ÖåWÚƒSÍîj%6`&cžØÃóƵ5Œ±¥W®¼[±Vf‡âÿú5»óLjTMªEhPW<èÚu]U>_ üR›ç{QX£ 箋±¯ë™uUæJ±½Ñ˘L,͵á2ïï\ëÀ[äk »îæšð‡^6»â]½4ße8x/¶Ò`e6¬ÔGãnß±ùÂ^™*¾4·ctÇëê3™– zäÕïYÔàû²0¡u…¯Ä—^îzøï|m[=óüËu‰õ£Hv3÷E©*E°˜Gv»ë ðc2躷ÝÏØÆzDJØõ‡rÛŽOìùiÆÖO%ìòƒ>·K^9 káBëªxXÜ«qnÿ1É®¼Ž {€üÚ:±Käå/¼›»qî‰E±ÂuïQ^žþÏ~Ù.É­â`˜ŸÛÉœìæ«*UÙ¿¹a 6”±ïÿ’Vâ·=Ý';ÉÉôè©j#°¸ûmYT¯aŸ2¥ t¥Ÿv/»9·>$ £ràhÝg×î+ åÅíÎ ­ üç®öS׺Þ×mí¦YÝ…×)зĶK]ãjw‡ ow_.xÜZ] •µ ZHo°S:(-µÞ¥WÚìÒ,È–6Е~Úf?Lk_ïâoæŽ~õðYDÕÈ0îjÛh·áO×ΛŒéÃ'{aÜNS´ÚB3ﱲѮИŸ­Øç]E¹+CÕ“NŒÄ™GæNíÖÔÖ¸”Ù¾@z}ª]uœwé3‡«Ø)YúLŠcÚûR]$Ï»ÊuæQ8Ô®Ù%GuNJVÔ¸ëG‚O´«=øRB7Ú¥B hKˆl°´¡il‚(ÞêÉÚ}ˈ'¦^h¾ÅÝZ] U” ZHo°Sé×Rŵ;ŒÚÝÚw{¨]]Юwhly#´h\/ µÝƒ5´žy7±ýÒo‰ùŒh /Ì‹Ø(o¢š¬X±ÍýF»ƒò$I¯t¬8ºÁB½ÌL½rµõ~«¾s©WÆ®jéö˜<›ÚFqúe~6ÈÌÿªð¿,0Ãx:[ ò¦ßϱ̷}æç°³îln;¶”ªããOîŠa†a†a†a†a L)]¤Œƒ‚Qc«iÆnMð|ô“qQ˜ u´O£øÍ@1¦°Š%Ç)6„Z§¿÷€ÌãbL´Î´KZ¤Ó$Ù9ʉð‡ÚµÅ: i(¢ƒ Ú–0¶ gcËö·MqÒ0â]† ÀÜ™]F‹j#C•ñõp®ñƒGãl ªYhŒ jÔ®N‹fμo•Ú¿W»Á)]Â3åbçÊÛíºe™ÔÃLc1¦m§¨«eÙÆëíøÌCr¦]*{ñãï&ÃÇ(&¸x:óAs¬£ë:×I\ï¾]µkvÉÑw µQq~WÚÍÚ;Ö®öàç}Äe£ëF‰7ÔÄa~6ðvP5ÀC´Æ ƒaLP„Ýi—*M·VC%æ€EƒÒ[#lÔO_ïb‘µ;ŒÚÝL·hèM~J]ª‰æõMTƒnÈ²ÅØè5H[n¿økaþ| #ZƒÄ sç"6Ê›XX°ê|K´Ú”§òÕ+3r2Xrh"Š B]K XÐÖ{’d11´óZ&©9¨]õùža~%6hï¥ÎY|^c~¡<äM¿»XæÛ> óBX‰Yw6·ïa|™0 Ã0 Ã0 Ã0 Ã0 #‚)屋”ÑaP0jl5ÍkÛ8þÜ곩vÜŒöƒZ§èï€th¬qi€nÖˆ­6Ç``¢u.½ …)Ku&cªm¡ `ï]¯|¶º›a©Ã® .0‡=IêL´æ`£p^ßµ8óÚ¹#I—Ñ¢ÆÈPiT=3CÿwVo®&½@µ’4ê¢jWh\ƒ§lÝ=‚ ³Öá¾µ™×Æ@íß«Ý`Œ¤ )'æöyçk{¯Ý4Í-kLµéÖk0åڕƱ6÷ÚÅÌì„këæ‘8Ó.U‰øqžDc° ˜÷.f¦¬&©Tµ-¥B ܬQVhûhj%›Ð±f ;U Bš)•Òimò¨;A´T5ì´«1ñ*#~¦öfþ|NónH{¨;’ ê/ ªq¡z7ÖR_j‹LÚaJŽ2‚Ö$ÅÜ\|:«%;ŒêšeËÚ×Ú¥ªa§]\j ÿÖî#rC»ý§wÁ”šªÐ\t¥ÁÕ䣈}ä`ªtâ«ywv¥ºmò®ÏÚ¥?ÙX5ìµ;•sóxܩݒ[—-³kˆE¥¼›û;í:u¾ ûèiÊÚ¡Þ]£Æ‡TïŠP·tûÛÙ̃q¨]³“ïШ8¿ŠÇ]›Ý:íæ(ÚƒŸ›þN»ø¢_ê0šËFÆo ²b&Ã). ëF»ö±™Ç@|ûö²ÛÀ ·VCä€EƒÒ[#ìTÚ}½›?ÃX¢lé5žûU_1ô7íïO~J÷\Ôk+Î'aO1/Ð=Bˆ›Ú~ñ÷Æüã@F´É$&¹â"6Jž(1«Ö¦-Úí8¯t‰†Qú©_Ë‘\DŒP™±dESåšQs,ˆÅ€E‚ty"Œí#4µŽâô˼6(ÊÿÖ5ïjÌ£j€AÞô{A–ù¶ÃÜÄâ«ÞÏæw.9Þva†a†a^1ÿºâŸÞÃÜk—y­ìÅÊÚe^ 'Ú½\.Büû¯ËBïÝå]׊÷O]Ò„.Á,Îí`nOsȸàåSCO››—ä’év¼ï ñt¹|Ž+âåóåËç¯{p§qù&æÛ·owùÞëÇÜÍ©v…øJ?æêêÃåéòáciIŸ¾-SÂ/ž»Á¦=v,!Ÿhô}|Ÿt\×ËA¾†m½Û)l¯¸§‹øò!ßø|ù.þ{¥ÉN»ïN#ñn·òýŠdí¾0Ïh÷é)þêüù¿£‘[Ç÷vJPFvîÅv;Çò¯&Þ§wq¬Ü¿ õ°Wféú”:Ïjòë—ÓȧÞÍ"¿]¬Ýÿ›Ü{F»!ã}I?kÐnlß·ù5ùçnPh÷ì—ënä …ùY!7"EJÞÿ9c.&!éD“Ù¶’4Ãj¿ScH‡è¸1Ç<¹c÷À×)»ÊåHë{Ť‘§‘OÝdJd¬ ˜Ýéev}«ìör”û›3™÷ƒµ\ŒF¸·cHe‚ñ2Ÿu+ÎØU8 W ÙÖR¥ŠÂz¹lm:H¹Xvwl;ÁäÐÂnÐS`7è‘ήótÇ9Ø`G$л Ãò"b¡Ëì¾­;ì6r8²k!O ˆÍûÁ»h¤ìºt¼ù'œ …*<Öªì0¡ž€ìí^ã¬ïÛrK!6+%¤ô^6“ŸìVƒYV6Äž"oÒκÉÑÒºüIs ‘KÃÖc|•Y7t‡]=‰#»Ð®Øõæý`Ýl,È$×±KªíUÞ-P¢[ÑßAîÉ'}ñ@Îp\ž"»j¾ˆ…¬KnºK%ïŠø¡3»è»Iý»Øfˆ¹¬±‹Æ<’î|b]É>‡z·¹Á.ô5ÉÆìbd uÿmÇn.LËX%ä Ëì~@¯³;·î?±÷÷3²T¶QØ ær°Æ.5–¡FriÈdÁ®»Öï°»ÂT†D¨³ë#‹®…‡bÌ·t©òK¥Ëìþ!»_(Q²ë&\ºêÛ}4KŸ§‚¹LmÅ¥m e¬š…jpИÎ tŸœ™¡³öôF_·ËzWZøpEж]Ó—ìnÁÞ$ò6ººãM®Ð€ßa/òepÇ9PÈ%»"<ÞN¬7t‘w{3n ÆJ‹Nf3,.×½ŸeJµRöñ7Yiõ@÷I÷6JceŸYË5îàúRÏ"ïè× ÊZ__øþ‹Çr_ØÝŸI;äÈ#^÷3®s.«`¸óœ8aw!ß¡ev×õ[í—è#§y(èwD.•ë1»oŠÙý1²û‹àýÈaä3Q—;z`?VÖ »,Ö¯³Ëú«ú:è§OÄb½&f—õWÅì²X,Ö§ôoöyž¢ endstream endobj 728 0 obj << /Type /Page /Parent 1711 0 R /Resources 731 0 R /Contents 732 0 R /Annots [ 729 0 R 730 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 729 0 obj << /Dest [ 728 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 397 479 427 493 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 730 0 obj << /Dest [ 728 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 321 295 351 309 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 731 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 732 0 obj << /Length 2153 /Filter /FlateDecode >> stream H‰ìWÙŽãÆE^õýTˆ5ÜDRF¶Ç6ì‡ÄÀHé`@IE‰1›Hj4ñ?äý»—^f‰À/žEdoݺë9U_o¯6›Ø‹ ÿâ#Î2ãg~éze’Ì`s¿xõM—Á®cº]½xõý›ÝÂ7¾O2»…7¼^oÕO¹ö"«ƒ¥g¨ @ÿsóãbÍÖúfà.Qf_6a!뢷U"ªþâ¬úÚ "“(?ƒí¼y¨û#΄ÊjÔ¤º²ƒ¯¾_Â?~ÕÞ Ç-~[™•*µ¯vÇ%¼¹”ý¿m[±’Håõ^{k¿ð/Æî³k¡ol^ã[p¹\ŒŽL :ÚÕÒ¶¨·4øê£w;7udMßn”°W‰‰Ðï(5Y†0q ècœAkÅâëÍŒ(@ÿq4¦Pû´ró¯Yš†ø¥‰oð¿,y9›£í,l›¦²y E•:Ø5uß6” GPç÷š:ÛueSCÅŽ¥ªÁà&ÊÉçeÍÂû¼gá]«1˜™²yOkäkÙ²23Õ Z‹±“Â!»ôFÆý­ì¸ÓלHÍò‘ —lÔв²ä-ïMvM{=ß'r9ÛIâ$d¡Y¯&+xë˜z*Oö]³ßîH ;!“NˆM¸ìgï[õk0Ñ’ ©M°òeÂC¶aj¦ÔÄɤ"X9Nп˽Æ2ħ9jô2S½ŽÔ}%Þß«ô‰Kâ÷Ü4wÈ8½RPïÔåh[cî°ZCìCà=3ì |BÙéîIQÔ) Œ¬ ä·äàc6~x}§ üµô^DÖi²œ¶—ÖUËœì˜Ëj˜KÝŸª¨µ‡µ¯rR›ª{»‡ªüÙþ†ìí1»ïh«Ô…#)÷K±ï‡còb‡„±Áñ!6Q”¥ áے02i8ƒ+©¥yAg†ò‰[¬Üte}¨ì¡j¶9ÏTUÃÏÃírøèÊãt{ <…)ÁˆbÔø¥²C „‰£($c?H§® ¦¨HÁãš~«45a6s$üp%ô4<桬¯À“:Oyž´Šq³·Ûóáö‰Ë?„lŒ_æ6FŒrh#û®>³¯ô—7¼’ŽëÞçÕY3ˆØQÇ3c¢Ñ˜ ]x«¾""‰Uß·åöÜcýâ0P× JÑgLòSîØº©íÄ@X½¶E~®úk·À)F EñŒ#ã¯C‡îP`Ï$ªê,Y˜)C„;ÄÌãåíÿ 0†w„Ÿà|ÛjÎ ³;F£³=ô ôíÙBO yU•½ˆå4íìžöR\ÓÚ ydOÅ}( CU ;6çj[ÔÒ–}Šž,ž2‹eÛç@0¬ÄŠš „›P!þ,g-ƒi[R…¤ŠÊN¦ˆÏÐ4]åPÛˤĽ5š¸õ$fóÝÑíÝëv‘=R¯`¾ÙÀ­~Ï8˜Ò *±ìmüh… æ[:“ç"'6ï9OP1¢…î/ Òyä[‚ö„ÏHæ;7Ó„;2ssXòÄ ‹¤êt²õ¾o쇲£ÐÝR¡Èâƒw¨ÆcãúNsÐܤΠÄÈLŸ€ü·ªyoÛ¡2þÁâør„ޝÔhà†4',eŧ־/©où(©sG ¨÷¦@—5&r>f<:Ò™ì*ØK}~°”(L÷\JTÐÅÑ=Ú#Büên^Sç1€S¶Î·•Ýj«} uÅèZÏ©+¡7žQ× Ußä.©<äÌjj[Jï5…?Ô{ªZúCn,:Ï߯%Ú£#zýi F& {Ô¬ÚºÏòY”$t‚þƒÏþà³YkN| |¦évx”ïx@Ý©*M÷¸ü #l×”QOlN¨$)‚Å™À¢^£u5 ä|»Vî1ˆN×Á÷ÍÞ Š˜ƒÂìN/óÊòÁÙ3 †<ÔïOÝÅf]ä!È\ûE¾@åÂeCWu}ÞöÝòc…tD8Np8’ÃÄþ$TÀ~Î ŒáFé¿0I’+Ö2 ]^Éñá’? 3'ÏÑó?a`®±\çøœ91Ïw¸AsŠêÜyH9¼“ð¨n+»ëÉ^E×ñ…Øš²|ÌRɘR¼GˆóQ ÃËÆê÷²èÿ dé”èTt\mÏÄ…þŧl¶X÷á0Ø_-áJ>cà1í1¶k¨h¶Á´ë T;‘¬ùì^}Ãߣ߉Áz€DzcH¼"˵%Gu. +–·î¹wOA2ü8HNH‘L-È~o¸´ 0 Çæ"M9ÀžÕŘ ÃyÌáÂ×.~ß9/yÛ0ybÑŸ8ß¹æÅ£ ±zÊøÒÕ#mpMK=–ÂI`ç,6I<ËÙ„<¾CñÂЋ\x†ç¢Š” (2„ÿ2:8.E„ (hÒ –ñJbÛ!…©ðº+š~m;./ÎUµœÁ¥ÇF?ÎÑs˜BD>wçïYxï)¯.A°ŒåæÒãt_Þ#oŽ(ŒÿÈÅ­íæÞк¦´âí„gfû%ÚÊ·9Æ ±ióçÅ Þv-m¥ŽVž¼ á„­{7Ã×íeÄ|SX$u¢n¦º@QU jVˆìS•;>N #=ÛwI‹-#"ï@y)ñ>ú"EF¹HÝôtñRTøöC¾ë)»|lO䦆§wwkÄ ¹4f*ç%Ðìvg™p’tÿ ÕÞÀÜ-µ\¯ú#qœÂ;=œÐÎ<¾8:w[E–¡¬‘Ѿëöo7‹ÿõì5 endstream endobj 733 0 obj << /Type /Page /Parent 1711 0 R /Resources 735 0 R /Contents 736 0 R /Annots [ 734 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 734 0 obj << /Dest [ 721 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 439 238 469 252 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 735 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 736 0 obj << /Length 2449 /Filter /FlateDecode >> stream H‰ÜWÉŽãÈ…¯úŠ„.N››HªÑn`6ÏŒaZ‡» #KLItSd™K©Ê2ÿàôÁ/"’¤jóÌøfW"s‹ŒõÅ㗻śÝ.R¡Úa¤üã‘ä¹äAª²íÆOó V»óâÍW]®öï T·¯o¾ýªc·ü  =ûÅz|½,>ê?oû‰>ZzFZ¥‘òþ²ûÝb˶* ümŠ[âÜO¹„D,‹Þ6©ˆúg„Ùuxë0öSäêæA}x¨ûf"m=HÒ]Ù©/¾]©?ÿË[o0n±¶ñ7ºô½?­Ô‡KÙÿö ‰µ© o½ÕêGþeÅØ|6- üƒÝטc .—‹ïÅ~¨;ºÕÒµ+}¼°nï¦N,é›Ý"T¥ZD›ÔÓPÅ™Ÿç* ý$Q°1ÉUk‡Å—»Éqˆ-ÁcoÌ®È#Ðr÷·Å›ß>‹×èÈl³¥¸ñYý+ÙœÈfÜé rRv»Ü‰ñƒDVØùá–®ú¨—‡jèÈ‘‰>-Ù¦9Sà‡Üy‡N„Sè镼¥ÊÎÛø¹VF›¦Pûæ|Ûz B×xkاÏnáucû‹µµZÞ ¸y«å×-ËQ7(¼0D–4Ê`LP(Õ²¹µõ¾jF¹N,}µãáɃçµUUsä"½¬ì¤èg{ÛK¬Ùº5îˆG áÚ)¹]FÒm+u3ô,³¬M{6}ÙÔ"1ÖŠýGo'[¨¾QÈu +Í¡·­¢´Ñöζ,ále³ür儨œ•’‰†3\Ù;o‹YêZæÊZíìbaª9Àñ.£Éh2$™ IȽoM‡Ú å*Óõ¤GgŽE–çy‹êNÍP˜WweWÞëj9íÉ.ÿI^E™Ÿ¥W‰%wÏWÔôÈ´T÷Vš ùãâ„d3ÆCM‘D‹FaôFÂ(Y$DYÅõ<:©sSXuq›Ài¡ß_Ú²§ÍÐßm¦(Y¬‘ $CEVwM5œ­:—ÇE¯ {l KŒ4£ˆU·¶åp³õÞ¾.*]y¬½æ–yìŒ{ü¦º‚gýà?©>”äf¦g¨°Nýí†îŒ2®öÿBSY­¯jp©žé´¹B„`3§ÙFL媈4gŒ¼‡xA—q/åd*RZ .e`¤ƒÆ­$ I6nb ï«G1¥€vÍɪF}È<Ô'–lcKU8·¶Ðµ6ÎÓ¥x«²&P‚{(…P"Y-ûžJ5×µ"ˆ‚í¨Uò%vÊQÌ¡6eMZ¦ R)9*Õ.k ¿“ËšºzIsgÊ &(AÁpµøb¶Es \@óÊý€U‘úS(]Š„‰dBâÇqž)Ž&EcŒ’«^}UÕî‚Ü'|= Žz× 7ý©µ¦à1,৥؇úý[Uªx þ¨ÞË8¨¼N sa7ƒ,ÜòÞA–@ §ã8"Ó ̦ºxdõ¡mÎ ºà8ê—ŽÃßP‹ÇÿÂ+zòEþZ‹Ýd1µéÙáDrÓWMÝ#¤ˆoY¿ené§Õ’NÈÈtgBý®°7Ãñý“Ò\§#F3šæ“ßsw±ArÉårïæ§îûvä”_"á®Ã-ºõ†òYÆò‹ŽK ºRn—½5²ËôvùÔs³ÎW ^aßÂ-ú¾-Qö–©F¨Ióðÿ?jd |uSÛŸá*2ýµ=˜¡êߺ•I¢ë&Å’c?ØÒS™eGî@[\Nü ‰®bŽë< Ô” c†ìN ª… 8#O:IûFQkWꀪš³rÿÀ()\žaƒ©m3t@„v¨k»©Êºg½†± ÆžIèHVìò ÊL `úÀ’=j$žW•q Á|zÔÇC¤œ¬ fMAŠp¿ÕrK½göèæ^}ÒÓtÊT•*{{v×  ž7ÞëžrüïCùhL•÷ ÿ¹bª³2ÑmCºÉØÊXòKÌE¶ÌU4wQ“ŒÐ éO¥Ì˜ÕÔÄ×ŪL¯„bíN“ó˜õ\ŸìÍgK†Y9¡i­Ø¿ZEN+›‡«Cã³àÂx’¯d#Ù#)§:T´¼¶îÙ$˜äQ1¢²Ù3Oo5óÀg›öc"³þLe=Xú8u¹wg¹[ã»ìÄygUÚºï¨"Puwxɹäpê¬úòLbP'Ÿ<ÿª¯ÌŽžv©ïW½‰ë{xàà )‰ûçÊ_Í¥H¬#C"#Ǫ„ó*°d £%ŒÁÄ'‹²Û›¶ ®FW7/EI9Óó04¥Nç¯oZnÜ$D&(±üg†qA+Š’Î;1Ö±«:ðŽÉl^WòžŽ¹[#' èWœþn+í¼%ê“ ‰µÛ(̤·îk‹q¬‹ïÚ;MFð`¾GRd^Y³§Œh½ð‘Â+u2wµ2}¤DË…½È}²™dsµ'Œ°úì>Æjƒ7# .«KвL>džïÏÝiù-¥zÄNˆ·rµüë=þ–îäÀ þp(ïq´ ~ãÒD}Ïõ5[Mi+c¾õ»þÃï_Æñ+s5ìèn®åCN=‘u\6mè&¢Z•D"ñù™C@Å(K’Ïä1Î0p9zÛ”(È«/?|Yq”˜û:°ÏÙî\ßLŠ@…Ò)ðbÞÏß áfÎ{"ú1þ™„à‘Èùæ"ËÊz¹äZä’k|¡Ú á—QÛ8Ba§ÂìžrçäšÚFLÛÕ;Êð$Bc{(ñLô½G´ëýŠy¢â_ËÓÝp·øööžå0¥ÜkD¬)¨¼Õ ì‘á™^¯°ÝWx¸Å &̈?ô—P)v?Mu£ýPÝ9–‘s©Ñ9½Xº=5ß{ýïY> endobj 738 0 obj << /Dest [ 604 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 92 128 123 142 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 739 0 obj << /Dest [ 1008 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 319 128 346 142 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 740 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 741 0 obj << /Length 2652 /Filter /FlateDecode >> stream H‰ÄWëŽÛÆFÿê)ûkX¬hÞIÆëÄN]x]#+ÀÙÚ…AQ#‰)/ 9ZíöAò}ÇþèwÎ )­v¸EÒÆ±Å¹ÛœùÎw^Î'Ïæó@øb¾šøðð?Q–¹^æ%"Ån’y¡˜×“gßô™(zÞ㉾h&Ͼ»öźŸx®çÑžb2>÷“ò}îLC7’kE¿I(œ¿Íÿ<™±„™H=w–@K˜¹‰g”°€€eÑWœQÿ 0; e®ï»~è@¡/Êf©Ýë®tRD¯Y_<X‚“˜jÖB·bÁ[m)v½âÁ’«¶öÉÀW"éˆ ª…a ¦ðÝóS ©1'csȹ¨Úâïýà]všŽ£KÞÌ ²#—üÁ#ëÐ7m£ó²QKQ6Ïù^R{³‡,OÜt¸YJµƒ/–j±[_œX1åý0vœ˜n¿XqÞˆÂ(7zã_ӌυ>IFÞÜ K%eôÎŒFA, G‹üdô㣼¤ô¤Æµ-vZõ4ô%ÙERÙ./åDkÚF}E |¾ù­Zå»J?·¬`<ýà$Ð!PÅFLè}+œÐ›y²w Zn€e¡ÌИ9e!£¯Þá¶Ø:ïôb¢ñb"£f¾(pR©l–œË˜D/)§)í¼ZÔªïóµê‡ÛäTŽï 9z[ö墺wÅkäüŸæWo)e»šˆ®ÞŠª]÷çB“Z )ë)b˜ô-LÂ_¹iwÕR,”ØoJº±Dn Rã1Ų‚ˆN%ŠœapÈ¡Ïs@Ÿ/.Z¬œŸ-¼L€}‘›!ÈêN³I›x/ŠMn–òáðaeÙfìXËÒeÏçd KU€„ eíÐqs ó8°¤éÈó`̬øP bãyÙôªÓq®¡t]6 ÝM»UéÌàuƒ{hÄðEݪîÞè_:üÂr]¶¨°P¹cV 4Æ)<Ž(EêƒAÅä¸vhŒq ñ®®t—7}•ó„VÏq-HÒ~Óî–V«²`LeãL©褌8y¾a-Žâ‡õï káo kþá’}{É‹¶­äÜæÕÎAPQ­¿ŒhÁÿÑÂÿѦ ¦ÍGî®N+ø2p¨ðyz³Â#‹¥¥NšªmΑE[Ó+!¼iwzÝÒ¨…½ô—)W ÊEñIO ài†ì1Lu FjÕ¶,Ê&Ç›úðÒñMªâÕ¹þäˆ}YU„O=d¢1Zd¬&HPÁ º*Ƥ\€ýáŠß:±)ú!Ф9UGh7»´7s¥&qTKls½Fò–Ï©¢4bJV5`vƪ;ÚÁ#ž&ÇZ«ªÝÈÉÉE¤‡‹HùºVe¥D“sÌûb£jõü´ôüÚåò³ú(ïðßçþææÆIåÑ¿pàæ3cqÈ eýîÝ»ÏWW¦h]}¶·ìL3¸°&jIˆô4ÊÎ)#~ƒA¡¹èXa…6ÇHaf†Êñ£JLf„¾1ãÃFuH¿d|ó¯íSâýAzò~j¯-|ƒ3Ú'¸›î˶ gäú¢˜°ÈSr½€ .W¥ê¸œpbuírWPí¡ÛÝ™È&ó±ãšVlDnEY™üÆ|¹-?·ËEqÆâ>PÅJ@Û½Ýý†ùšªA$/ß›áÓIwà‚žÔº¾¤÷~v·ÕGjÈê^ã¡äá™ÝÂq¶-·êhã%øÃÆ”I†´€¨ƒ³a~ªŽ$œ?ý̯Üv©êöŒŸRÆOÉä+`†È‘û©$«øC(]¸'—=ñÉý›çóß%Ap@ÏÀ¢ç e:µ'üË›á—òFivbä1¤ÆŒ™w"¨ix1¯°+ôIKöäã ’;”ß:á¡ ý^N>nÎLÐqœk‡êÄJ¡pBPû`='@©ÌZ•?è4–Œ–µ2‹æ_{`­Î¾äXò›8f8ûHßÉ1À1tJöëû¦@a"Ó¦ÛF• ]4»z·ü»}äèÅHÜɶ««+² Ñ!.N${E¦eò§ýh ók‡d)À!• l&;‡H÷¹Ø›á†–J{nC ~Üõšªýñv{¶&L ÎìÄÒd3¸%>?Ôso-©í,z²mÈÂ`'x,Í6d Q]|k‡¸,ÑlsâvÔH]Ñ –™ˆ$Ò·$27ueœ>bÙé’LÌdAcàle†Ã2Þ1keVûÞîn×à®@Og¦z8‡<ÇÈ?.ìI+ÞŠÝ EßÖös0d÷büê©­ó‡ÃT$‡%£åµƒènØcÑ)-wÃ"Ø ÎÂzkgù.aú¹õ­oEÝbL„ç<¦¦h×&·g¤€!òý ØË]½5É2E}i¨]ïíÉz˜ 7wk'«Ý0[—ëfp°3wà‘,{í z v¶áænì:;C¯77O–rMëöy Г E~HÔHžšwk'NóíÐ'é• 5Q¡à'ÈZÊ·„8ÿ"—í¼X•ì4uj1¦{N¯™ ú$GDçà ~¾¿k5ˆ"2ì–ûT´Š»ji £¡f–øu† R *߈- ¨òû&LÎ<ðŠ:Þ§”·Ê\EcøÌmÙµM]ç (¢ÔäGÙ©Ÿve§€W¢j5˜¿È—Ë’ìAa«Q¶»ûs”ïu—/± pЊÉ8)+@ *Å-D¾sXÕ½Øou‡õô{8êܶ•Ò ^ÔyE¢á) ¼Ï×H£Ì0îJ ·À’Zºâ&l› ¸åÓÆ7îc×ÄÔ&¿ï·Ô”Å×úÒ–”¢*:ª' Óô~bù4£~|¹—bݶËábqAT©Þÿ—qñjA(5?œ]oA9À§‰\УF£sZ¨JñÕ"H?“Ÿ&„ºËk¢€âÊ{ŽÁ“ëÀàÀ€–§ìPAz8k”#€·Ü F&ð‰tM‚âÿmÛäD²/YXNaÖ¨J3º&qýjŽöpþ=íñåå»ë·—óWh‡ºr«Åj×ìÊW6‹Ÿ¤é唉 @ˆÑo>î Ç ñ} ‚Ú»²ÁmdmÃÓ nõ…8¨@žA„á'Ç}ºƒùòÃö9{ä+cŠiüž½öªpJƒä tI¨¢|¹ê¢m^<{0AÇ_Í'Yèz„x(8fbÊÿþ{E©\i„eMÍà²&F@£È›™ Ní¤¡v[ëk’%Aî‚HâvvÍøe‘Ä&kT‰é#,Ò=?”. endstream endobj 742 0 obj << /Type /Page /Parent 1711 0 R /Resources 746 0 R /Contents 747 0 R /Annots [ 743 0 R 744 0 R 745 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 743 0 obj << /Dest [ 737 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 262 379 297 393 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 744 0 obj << /Dest [ 604 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 285 102 299 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 745 0 obj << /Dest [ 1008 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 298 285 325 299 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 746 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 747 0 obj << /Length 2771 /Filter /FlateDecode >> stream H‰´WÙŽÛÈE^õ…~I1hÑÜDQFm{Ƙ`Ú1bžN;0(ª$Õ€‹†K«{>dþ!ÿ˜‡œ{«Hª/d¼ˆµÞ­î=uêåròb¹ „/–›‰ñ‰’Äõ/óÅÌ/ËbòâU“ˆ¬á5žh²ròâÍ{_l›‰çz­É&Ó¾y˜ÜÈw©3 ÝHn})âH8ÿZþu²` 1÷ÜE -aâÆžQ–E­YlDý;Àè4𜩺±ô±ºïïËv‡‘@*’d£qùæTüó?Ît†~¹™;“Úñd¶;ïºýUÕ9 eZ®éBŠßø— c÷ÙµÀsct–¯1Æ× ]_6¤U‘Zˆ†JMÞevhÇ’¾[N|¡Å$˜Ånû"œ»I"bß"£DÔj²™¼\Á},ñFc µG•ËŸéÀ"{`‘ëEX¹a˜Ì…éöAÏfî<8Š*ÆlT±Š}J\ßwý™“ â¼h¶ë®Ø_œ‰5tü[8ØË=E;»úQ´uÊã›ÎD[ tfr£sgŽUЇ²1Ñ„¡Éã̬ ”a£u~oœol{U•mªKµº<ãÏå Ö&lìÎûC¢¬a ´[ž¯ÕªÛ^ôá²VLyý.‡´Ç%‚’XÅi)2£Üè}E¯?2Ÿš$cUU¹‚œÛ4ïÄú8$£1Á`Œ.ÜÈKJâH¶m­W]«êú’Lò鸾h’7çt)«R}C |޽|­6i—·gvƒŒŒ`SšåÐõÔ";EµÙk¦¼vpÉσðFµÃONü‰„K¤hä.eTKiv¯ÌØ©(TcšéÖŽ‰Ú‰°NeJß"_Œ 3VeþP^ɳ\;¾w4vÐy.VJP @Šï, åŒ:>g:–Ù:ï5ëR Ä>mw=‚ þßHZ”Ƚƒª‡uš6/pŽÐ4Ú‰ó¼Úî)E"™’)±lw¬Š§I¸ÙV±”<¯ºÜÚ1Ø!Ê~󜊕æŒÖŒ¤Er§ uvlZøù£ †ô3Ú³}‡?Ÿšëëk $~yýÉáB„¼}ûöÓÕ•3åÕ§ªk·•¶ETnÝÃê®ÈÅGYÕÂEë£óİߩH—YE¾Y÷deÈiy#?ìT ñP¸ßÛzàõA<ˆ’âzùÞB2 ÝÖáÖýíj°ºq<†ØÞq'äú‰Ðt~(pÀ‡^“·°¡lõF«Zlàç[]­»¬EºÒwf‡2yNÀM œíDjEX™©¹‡÷úSµ^e',îƒF¢Ç²\W»úTN,ßSæGòòé>M!²<°hp«êFWå©8¹Û·GjÈê¦E-¦9’]Ö`Ý^ïÕÑÂË}šíÌ!3m€A+ø»mÑÀOU“„ScÕò/ÏÊÉZՉŪŸÐ¢‚  ²{¦”ÉSÓªÍÜG‡¯gÎݤÐï;ü`äJåJ×”á¸ø%fòºÿR>À¨–Ø9§¤.MŸh´æŠ/y2Ím°3Ô¤ÿš½¯J.øˆ|í„ãòÄÉùÿÅIÌp¿Ïð¢aõ[Ã)N€åii†Ä p[æ—Á0u<°-ä©CÉ(´©—{Êþ™Ïx;G™0ù“OÙ"ÒÌôù)4¬Ï(ò¡èQ®¾T,û€áp¹2,·"˦”蔉>]p¢ìŠ ÿ³ÍœÏÀ·}›ŽWWWd‚Cì.E¦%ò—Î6ÊÌ|m—,’Ìå ËûÁÚ¡C<Ó%².µÝ·#?wM‹lÎŽ—Û½…á’À>;°f|°[so?Ðso-)ìhÓ°ý[Ba)XŒ–dK“s»uè’³ãvЈûý1𙈠´Ñ·´‘6Nî¹1“u«ÉD¾ˆ”sÓí§‘¢(kŠ*Í6]]•.™ëK±ÜÙ¡Î-(÷é}1tWv§oÅv½@ÑT…mö†ôýF -¤ÛœÍlF "ÙO-¬íE×ýûyZwý$ˆn§•õÖŽòYÂôSë[S‰¢êÅ<¹¢Hiߢ·»Ôfž‘&p‘ЂÎp0m Ú';ߨE?@µwkó®-ôv× K iäàIÝ´® Š°£%3¸ÓÕv„ª85¥Û¤2ODžsBó2b阰‘|lÞ­ø|Þó>*Ô¢¨Ð!Ät©§ôdÍ_ä´MAŸËÜ|ìpÃiÖ¿{{@ù&ŠdžLÃ뉌X:”%»(}h/e:ÍÌY™æù½Ø ûpðU¸Ì<Ôlq³ËºýñÀ¼“ûð’Ç~¢û,’I‚%±ÒeZßŸÚ {VœfÊö{,_ ž¤€3Ä’+^¾&êT¨vW`yB)õFÔö-jÿtåÐ1ÿˆß@~t¸L\±Ä]bîD¸áŽYZþ™8š¸ÕŠo±CÏúS\T~` %ë]+ÔZ·UͲáuVQ°æH5ú55gÖZÙEçXkÚæõqÄ´"mÕ•¡ãX„îT<°]<¿yú,Ñ{zä-Á%‘¹­^*T†æá(;J½ÅQåýI)%sì´,?'z™ð»*æª`òEWê,e Ú죂°¢ssž)=½ÇN…pŠ$œÒäÌzî@½ùèˆ- ÆŽ}Ò¡r9qw)å'¥$¡™é8@”–îÿò 2Ê4ëÉéÛªÅà ߈jÏ®fµÂÑQvçU F#šucL3W˜1q„†ˆæS\aÛ(´)ÛÈ•¶®~u×™/¯ ¢þ‚É7rוëZ­±×hTÓß‘!Ƨ Ì{UrÅTæÅ›xÜ‘ë´MéN-›ª!Ã}¾Æ—‚o_ —b[¡ô¬óÚˆ}çFýÝ!ˆú›eèsŽÿBé°à[¦3MÅá&……N“Ì´“&ùs•µú–qÑù /?b˜I£@¨»´Øµª À%Î~)tdõF× 1 H\_Þku ž÷˜A5þí«>¼z]Cæ¶ FDž@¿[^½óúWïD“ÕzßúµéÊŒõˆÿ|nûG ›d¨k¼pPeT_ v*b§âÑeyŠÎy^¡Zñ·møE‘Qøú ?¾Ü·dOÃT$ª9‘!Õ/ÃÎ×k4ÔTÇ<õ&saºsÏ]Ä^,‚º=" [C‹¡†lé&.!Bì€ œÛR€ÍřتRÕ¨&š²3‚¦,‘^.kAõžÀgPëÆEGjGb”¾ªÊà£è’>c&ÐgÈȯcw=÷Æœ¯ÕªÛ^ôq°VLyý#Äf¸¯R`„Qnôξ¢×Ÿ 132VU•ãÍî“ó£lûqHFcŽèn|”ñ—jÚ¶Ö«®5`áK2É•Ÿ1Éà¯,Aݾ!&£åkµI»¼={ø† Ý(‡ìëg¬g`aõªB%Ði ŠÒÄ«'¦ÀÆQñ{‚+4HÝ ­â¡MMPqT ­öu@9`†B®³!l„¦®¤Ín€ÖåeଫØË!tf Ô TË dÓóótÁ¹"V±"59âTˆšdpê+@m¬dBí€Ñ ¢ /¿Xó›/(+ë˜s°6 ÍX·(7¿\ –L© "TøU*$gBXÉ –¹Fi.²ÂļäThIâ£zZ endstream endobj 748 0 obj << /Type /Page /Parent 1711 0 R /Resources 752 0 R /Contents 753 0 R /Annots [ 749 0 R 750 0 R 751 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 749 0 obj << /Dest [ 728 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 461 706 491 720 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 750 0 obj << /Dest [ 728 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 385 528 420 542 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 751 0 obj << /Dest [ 754 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 270 127 292 141 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 752 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 753 0 obj << /Length 2001 /Filter /FlateDecode >> stream H‰ìWÛŽãÆ}×W4öÅM`Äeó®Í`ß`¬£$@t»É²üµ8¥1ÇWæLÁq±ùºkMQ·Œÿ. L>êgéŒ~8¥‘¼­ôæ]18+–|žr2œrï*ås§¸hEi•[½ÉzU2G=±26]×hÈy,šøç9$³1Ñ\éU%|IKcúzs2È<*I&)äÁ6)Ș Ú®ÕŸbìå7z[œóÁ}àƒžC+ø*k"?XN•ÃÆ,ùèäQ0‡ƒmž#NȇVÒÇ­´¦ƒÈk uÉzîkctë .[ü¥èÈ^—Ýá Û ™²ízqì»êTšúQ Ý>ÖHØ\ö]‹f¸ÅÀ‡\ ϶N˜-Ç%Dðɯíð ²Dd©t•eù†·uMÑï´øÛ©öVHØò§ærÃ/ÑJHó2F C”RÎy>”ÿ…èr{jÓåOׯ2z?ʪ;#·X]w^6úÊ"kÌJ6Á¦Á*õ0x e ‘#Ua ’ÚÚmâj‹"dèÆ[QTUM†Y³ s0Ösj'ö%ÕÌ+Ê¥¨ Ôà‹î,6º,N´£EmÄ—Æ#EÑœ ”È m wê]wÔmÙtüD>†ò¸m:*¬Tî¼%uö­£:¬þnè*}gysbMOŠ„¼h»wóôÝ`ŸÆÔåKZçºi@'O·f,Ç‘¯˜‰Ár'¶š‡+ÆÛ£J¥áªÛв××2±ÞÇ‚‡¢=úÜðR±7“lL³Ð9 9)q ýÄt  §= ©*í3j“®@0´õi±’¿ˆ-¢ ¥ëX<³…šAW]„ÜÅ-²~[ïø-AOx*dŸé¢ëƒLÁ'İJ·¼mg[ª°2,¤o’@˜¡C…¿. <½6`:ιoÐO[þ…ÌE¯dMìðZEþªô`E,¯eºï LºE|ä–qOp†òwy ß·]V‘œ˜:J´éUt® þUµö莺߸›£u¡‰ýWrÌL1PøXÔ¥TSlàd„N£(Á>¼A±3†*Ÿ¦;j)äDσǣGÑÐý8Ü`jú@æŒy“g¿Á€ùjfÀV?çÀðuœ‡Ëùf8vop Ùƒ”½„º¡jé(šG³.ëm­«f5ozéæ½ƒ `*,ì¾ý÷Ä“ÇF$}Ù¸÷Ä{˜0Ali§ÐnËG®kzïŽcq\>Ÿ„^Iw j¨`§¹O¤â E9Ûì=r²[Ÿ0‰E²‚¥¹ôÅk³ïNfDÕÖí$j‡«d¸³+ŸOnŸÏÝ_¸o §'.R)¢¨ŠñýKä=ÓÒÈKt!Ù\X:ÆÐ¾ nF¿¢N1\£¨Eô›JÝÀ_â¼×í5–{÷ÉüÝʈrÜm™owºò?6ç±k9.É µEÖ± ↰šQ䶸~à&Ñ[©éRÄÖ [ÍÐ=±¸ÞŠB”Mã†[*=¼8ÝÇs}ÆÖ¢Ó‘ì©Ä»J?âfã¡3aB§@!y–÷²ó¾.÷“šÊYÙYÿâÖ raEM2ä¦}¶’ÒÂ^½ØÌ/Üw”Ñ´ Œ^Q~ÑÃÅ~Õ–6⣾fÔB&ÜŒ w5iKäJ ƒó¥È¨¹¿*—*nìàÆqãñ޶[4”v9+F׿mqß"õ©<žŒÃ¾¹scÁuëèÁsiñízñïMt^ endstream endobj 754 0 obj << /Type /Page /Parent 1711 0 R /Resources 758 0 R /Contents 759 0 R /Annots [ 755 0 R 756 0 R 757 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 755 0 obj << /Dest [ 507 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 284 548 295 562 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 756 0 obj << /Dest [ 1634 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 428 324 442 338 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 757 0 obj << /Dest [ 489 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 221 283 229 297 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 758 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 759 0 obj << /Length 2178 /Filter /FlateDecode >> stream H‰ÌWmoÛÈþ®?Ñm>‘@ÄpùNs€_dÇEb_e:@ìM­,¶©’”uιÿpÿ±:3»"i™’R4(îr°HÎîÌì3Ï<»{ ÞE‘Å8‹fn1þÁ†˜óC×ðÓfÑbðî´ XRÑ“UI>xwqÃÙc50 ÓÄ1É`¸y\îµ_b}hŽö(ð×Ò˜ç1ýoÑ_!y™o¡QìÀðL„Xä Ÿ\OºúÝ‚¯CËÔ‡Ü6<Í ØÃ3»yÎë9|±4¡ƒ'­J+v|ñ–Ýý[ºð^‚Í5\-ÕM-™¿e7ë´þ&ÊŒœØZœOõa¨±ßè/%F˧¥Y¦áÁKtß(ƒõzmè¶Áµ £ ®!¤&¬.QŸæäi 8KÙÀr=Ãö8³}#˜Ç Ça°F'`¥Ì'Q†Íaˆùj,£`ÁU0Ç0à¶øL¾n@õ]×𭪦¿AÕt嚃Ûz€•9ÊÅ“(—«z*žÒœ¾Í~±ø©H§ì—Ûˆ3F¦™ r¶IÓ¶B$O˜oârö´Èë8ÍÅ”¥ùˆÐ󵯭â¢gøü‘Ò…œ~TéžhÏê'OþžùLw âéãÏÛù ÉÓÃRÑ›D"hTJqΙ–ÌÈ=wºs…æCQdü<ÅÙJç »“±šd¸×YÛ12×ÑêºLVµ¨ð•k˜ÆîOIÖWË‹\lxÒE%D!àSœê„Ìâ»"Ó£šX~Ð._Aˆåp5l (g©»àëIG …|aEž= m±µ31‹WY=RëQ¹€¨X2)N° 3Ä'Ì誈:¤±íÒ[ׄ‘ÙÆÞ4ÆFÄTU/g¬ž§,Ú¤ŽÙæi¢ÉgÔ7­fuk| Ãë|/¡±Ø:Í2F=Ö5åеr‡Ý•èˆYQ.â:-röfª©%á)Ðfo0H²Tä5KgázQ]fŽ\G^Ô¬ZŠ$¥Iœa% ý¸ú'táW ½AùB \V"Ÿ¦ù#»GЋÈäWÝh ÷=Òㆼv¥ÇkÎi¤Ç™ZUÏU-uºß ú” ž°*Ó)}°LšI;äÏä$†³¤›oDûCÚäzöP›¬©M=ÕGœ$DP¹iƒê"Û¾j•ìO_õïQÐÿ«hmKÃ}+ Cj‹!¬¥Š=YTj±‰+êŠRÀJ W§lV j·b)JhJh 5UŠË–®îÞJ¦Ì"‚Î÷á¼€(‘ªÕ(öƒ`+ùJÍ©žW:r‘Z·B‘Ôâyã_«ôÅ;d Bhù•&†UA'µŽCp¨ÆPkJήùòµgù©;Sµœ„ æÆjè’‚!³(6¸äÈmy’uhÚnƒ9,‰)”‡zËu<^1U)…–öˆÉ»Òz«JÊ…ª•¢¦ÜÔÿŒ9ÇYGÆx#^.¨ïh*f ôR£Jùê˜jENQÊp ¼p6–¬ªZ÷©<¸ŠFÁ¥`1=W€bs&5Û @‡›-„¶ÛéÀÏÑ¥>ô¡>ŸÈëøîúj|X m8ÜÛÞO èA­gKoLÕKIþÒœ}†ÂøÔ•–vùI‚(wcèBÔ¹ã"< I)ÁÃR=„\NÑjA—Â&*7ïXÞ}Ê·lr®s[;ívD{ð°[í°ÇEÞw„ëˆðÕß-Õí\;:= ÒG¢V«Ðñk «¦F|X¥Y=T*QãÕ!8fƒ{¥6›d/khu]î#Ö (YZÕ°|¸ßA¯ ûÀ’ën  ’ÒÕ %/Äž¢7!¸*nB ù³¤q¤V'b±dš•—¹Ë>G4õØáA›!Š!äC†F®Ð,ƒ]ò‰Ä[ÞÔ –«1 Tà+ðÖªµ¤‰ò¬¨9«’BoÖSÈ1ý‡@»e¾Ýè„â5ÐY$}'’Öç òp9(Oˆ%ì«å²(kAçÀs(Ò£ÈAh³‡Uø¿í«íªÝks8Ff¨ÉK¸#U õb†_°„ÄaN%lp×Ë9plÛ•†joΊ,+ÖTü/–t(V²šëŠÁ /õh— x×¹E|W|ÃE^ãÍÝ-øp´1¡Å ÅìTn9Þ°õ<¥ nNž6‡ËÛÂÃÞs,™«’<Ô3·Ñ)òGP>f1PuG7hŸ®J\ç4~ÎÒÇ9âcØ(+¶t}Bvý„ò‰“:}Ò7­02é¿­Àp£Ü¸ÏØرÛÀ“ÉíÇñè|2þëûO×Wч_~º¼ŠÆ“ÏÇßsë§“/gÇ_ÞùÍíV*®½'•>c*6ïVøúüüfO®?LëÕê=¤ê5ö‡äáëÑõÈä¯ZûxÕgìhvx5¾:ÛÅ*¾U}ÆÞh¡»Mb(àÇË‹ÑV8s—úŒ½á»ÃoÚ;8îáMŸ­7ªÏÿg{ÈÔgëÍÃí¡’dï+2¹ºÛ!Ò;¸?Hãîí¡ò~«Šëu9ŒŸ^ÎÝaþÏìÒ!ï endstream endobj 760 0 obj << /Type /Page /Parent 1711 0 R /Resources 761 0 R /Contents 762 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 761 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /TT2 2104 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 762 0 obj << /Length 516 /Filter /FlateDecode >> stream H‰„T]kÛ0}ׯ¸2Ô²¾,Ëešåc[3ˆ(4%ë4kqÀ´?¤ÿaÿq»–ë41NŠÁ’utϹ÷\ÉG"ç$pK"$p|pÐÖ2n¹$™±\{"ÑçÒBVú=ÊlM¢ÉLÀcI8ã¼Þ“‘°VäŽþ¸BÅ4}ÌëQR0  ÷•¤ž!…„³Ô Š²ÌðFÄHÏUÏbÓPý•¸J„B1C¹…ŸÏ0{^oW¸"i -‹.'g0ÿ„1~o‹YL‹€Ólu³ªØ¾ä›ßžDÑûõC¦^ýÛ'æË÷¥IÎ ~¸!®ù ªªbb‚–µj^Ë"5J2œr¬.{[Zy¦‘# 26L*aÖ‚LkÀµ…MN–dàvf([ø¡ïVóÚÌÒý"ÑXtû…íòF&MÓM,uóéx<97=çh_ŠYY…$Gð™ìåó!›ª¥Æ³±ÇÜ2©†ï´½õDCSÓ î…ÑÈ;´}·ct=<^Þ~»š|q/ℽãìèõýjʪݸ«ï£ùôzÔ‘Óñ ¹>°_Nâ!–Ü],.>EAˆ‡>äËbo‹§üåÏ:¿hc«.Ò£Î÷C¾åèwOà)¬ÕSj¯V]ÏCàƒþŸVû7Iêð· Ôܬþ¿¼Ð Ø endstream endobj 763 0 obj << /Type /Page /Parent 1711 0 R /Resources 764 0 R /Contents 765 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 764 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 765 0 obj << /Length 2637 /Filter /FlateDecode >> stream H‰¤WënãÆFÿê)Nýk˜49¼®g³I6HRÚ¢Ù¢ $ZbK“ŠHÚ«>Hß¡ïØ=—!EÉ¢"0` çr.ß¹5Ÿ]Íç<˜?Î< .þáO$Ž›¸ÄièD‰ëÃüivõ¡I`Ùðše5»úöÁƒu3s×¥;Ë™Ý/_f?«û̲}'Pëœ~µ‚(ëoóïg)SH!v4B.~âD®0ašiÑ*Œ„Ô4îÚÚµlÏw"å&°ØÃþj7¸£Un!%Õ Ü}{ ý¯e‡ø½Ã³Ð Ua¹j¹¹„‡—¢ýW¾+™ˆ¯²jeÙ©‚óŒÕgÕ´ëDø1ÿ÷X‚——ÇòO5Ä5'¶HY:¸tQ»¥ÙÚ0¥ó™Ìt9~ä;I‘ç ŽA»|ö8ûj>€á{xÅ=FãµKˆ ”óÁc°Àq±¯z<ãÀwb=Ôu=Q'uà¦%€Ä¡ÙÖ¸ 5jÑÞZ¨¯®an‘ˆ)Úðø|°¼TW…#ÒkD¸Ã­H’*ã©Ö²É.E]ÁC¾äóÑã„Ê$§Þ7¨¡#òƒ^¯…QâC]µYQå+(ªk6C¬²Æ©Q‡ÞäYBBžß4Vä$jo~ªåß—¨‘|ëÛSùl¦d{Žç5Á5pMŒHYKK$ ß‘ÈÕƒDêf»«ÛzY—·—7›¶Ý"âímoóWbèA /"?«;òû@µí®XtmÞЧ§H­õ¶»ˆj÷Ûœ9ž¨;ò?÷À]Í7sm¶†¼Z–u“7•%´;q—ÖÞåeÖ¢}ØbÝí²-ïŒÈø=äZ–s‹¢xcyb$Úd¨š(V¬" _ÙðԨé/äÃ)z$»š9Z<˜!J0,ò'‹ÜïaÔÝ=fËTÉ–ÍëE&„ØJžZÁѧÐyÆÇ¸eˆ~V.ªUý"ÑPåž´>‚ÿXíßd ?¼Øäy§‚»m¶Dïd÷Ç»¢›°=Æ K;¹@:>…ê,ǤñȦ¨º/—ð#o2Køãü¥×¾Wzœ¢ôi„rŠ $Ky~jÊéO5†N»ÉZö6¬£Ë€r¤*‹²è³*ü‰£áq't­”J8ÅPiqE ¢î«6ÇgXkÙ$Ìá±(eWÂ-—Qñ–¬ØG ­%Ÿº²-¶B×¼4õø$ßj“oµkls3äš[ “%¥—Æ;Œʾj8•Ïþ†è¾ª©¶!¯ªná)k— <‰6L7rÌÝ ›¦h²mq ¦€°‘­{{œ"ž9“Ô”ª—E"0"lGlòñ§m¹‡f°uUï0;}V ËN°åh¿Çý…*ä%,³NV”Íz´óÝ®Þ}¶¤APç|ƒÒ&6Fq["ˆcxeXšÖ&mFJpØ×Ý+¸¹€V‰ñ›ª~A*èLä ^‡ìà«'I¥(A¬$SOÈ¢ÌÏ%.Tyj9œÊ ºÏ &!H^1· ö)†µÀjÔ­PynrèA†} :·Ü¤N†6Ég„»Å±dç Û· qš $yFnƒ²;ÀŰફ©´T«=´dSÊâïyÓ³±YPŠ•F¼“b1ãæ½ú)êwëU'~z¸»ÿ$Ý-P;UÎCƒßv Ö«ž:uªÕád´ñtßQaÑ!oO8 hµ2_ã*ôX0ßmPCw /¦+GÇö¨ëÛÔ]ËžQåè§-GY¢à©^–£—ì‰ltèH<“бëNF¹X'£n-«ö¨ŠÏ•;QRò¸ŸÁm=ê«b£›—šq½BŠ;9ᣌú~Œ4)ʹk(Z’eÅIA’d[ÒŽš®Q¾ÅŽ­· ‚ÓÐ/u<»W=ÎÙÌì±êã— Ý6¿6õÜëë’Ôµp`9Nwh×åvíÜ7ÜöcGâcÚñ ˆÑ: ð¨18Þ= £á4Ðü3:ÝÄÑÁäówŽG¼µ9Ĺ% ^?>sŒ“ÒaBð\,=4"V¥@FDç÷¶-¸Ô[ÎóòñÈ‘‚‹®Ée±Øø6fãÐl™oöuYÛö+lÃqêe$ÌNT˜8ŸÐÁÇTlÆœÑðÝ|~s5|’kŒ$Þbîp‚·Öý†÷0s$îÍÕðqÂÙ×4Ãô£SÛOœñO™ð|=û«C-?áé%<«L*> endobj 767 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 768 0 obj << /Length 2537 /Filter /FlateDecode >> stream H‰ÔWÛŽÛÈžê+:ó°h^$Š8ìñz=Án2ÈØ žfï0Çl·Û(Ì¢$èH«&µ •†1nWù©–ôíl(£é8²èê·›õÚ¶.Ñ$0ͽú¤õzXÖæQ+ÓáÚ#Ì+³¢M%{! š0 œZZïœVamÛ…Ã)ÑT­mÈñæ’ˆÈ<¨U¿{nj­úшOGˆï½-2Ô¯ ðºÜ0‰’ìp‹ý%ävét£ª²Qvé.¢"¨wªTµY§ªÙÈäj®[ŶË0¡Ä­lÓh³ÊÛ°ò1.Ýàü=Ñ(gp:­Õ™7ÁÖr¥#uk•qÇF¦{#‘ÆÞJ‘™†gÒ~àØIÐ8SÖª±N9‹Ú5Yœór@¦°¡l!ûžìi•~ÔlPpÍT?ˆÌï©Jp‡Vÿ´éÕ9Üw¼PóS›^7äú!* 'šûú¯ÇûÂí1à‰AÊ2#µ¡Ò {-hµêt×aW$‚÷9ùcR’æ¾+)È/gwzšÝlÖè€R#±ðºaSÞ¬Ë ?p™¡ì’g;Ýbæðá^Ô”GHð®B(æšÜîZ[×H"àÜ…9 ¨©z§þbòƒ5ùÞ_Ks/œÁóÚ9ªZŠÐì÷mÚÒ9m6óî@Eò­³¬˜(ùìÑ6!7GGp+fûd¥aAiøj¾Y.uÛjþtí®Dê' n¶ÕíëK%Ëá„öÖ%–R¤Ðk;±Qo‘aŽ·´²dt·7¸8…²½•„ÀÇMá´¢¯àóÒ4p¹i.8&Á^¬~Mò£à?mQ¯\ ; ¸”Û­õï.LW®ÍÅk¯N²¸“ŒRÂWÀ˜Jl³Æ_0+ïÍ¢!ɘ[[kÈy,ë ¹;íaîœ1–&$´®ËyH ¶˜»/Ÿ×uÒíS•ëÛ7bíMHíàE@ßÀ²Gbã ÿt¶M½“‰ËIÉDÞée¹©ÝåçÎ’|‘qx2ôÕÜGGíàÍ‚4Ÿªã“ç€ÒQ#x&1¯ Ð J\×/8’ƒUFØÚ =©…1°T„9Wiæ>Ž\œ¨8Ûè“=Â&ç%£ÑÑy¢$×~ÐRSL¡¯’=›Z>ûåð *«hÞ2è\/éžÂSÈþQà…5ýÁùN49dàD,œ…t®'ÇÓÙS«›J«ukç%hšABѵwŒóå@ @–ýZôɇüω’Âü¼Ô탖|DzÄtdèBRCI¯î‚Ò/Ë‚Òå §2MŸ†`ß=†Gíƒ5² IO/)V–É'%€n Åv {WHÙ{FêƒÝ2§¢µ”„@|fkeö“\TŽ»•|ò3î¡tPKo«Ü)½SrxÏvlCž[qˆ›ï?â9ÎU"[îýdŸìã^ l±ËÞTÊ‘vzu+s,‚ƒ–Ru¯e‡EVD> endobj 770 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 771 0 obj << /Length 1712 /Filter /FlateDecode >> stream H‰ìWÛnÛF}×W ü´Ì5ïà ;i’"‰š@ÓÆ} ¨•Å‚"’’ã~Hÿ¡ÿ؇ÎÌ.)ùÞA‘… ‰\-gΞ=gxœM²Ì²ùÄõÀÁ?ü ’D:‰Aœ†2J²åäà¤K èxŽ]QO^Ÿ»pÙMé84§˜ØÃåÕä“8Ë-Û—¸Tôí ˆ°~ɾŸ¤!Å{™F˜ÅOdäè$ÀãXtF:ÔŽÚžcÙ®/#á$0½†óëº_àˆ'”…‘DWvðâõ>üü§e‡xßâo¡ Ei9¢XìÃùUÙÿ¦ÚŠƒø"¯g– ø?/Ÿ—æ92›ì%Ž1‚««+iùÒeU”CcJ‰—®®0C Žô*›¸PÂÄ #éG.ø±Lˆ\€k hÕd>9ÎF2|§87ÙØRí#ˆ2û•6,0H'À ôý$};‡¡Œ½Vt`Õ‰õšRX‰€£E߯VMkÅ¢~o²ì 8=~õñ€¨tEfc'V,cqÆ×Щv£ZÀçz¨×g9Å[^<"Ln—ÔËK©´¶°Ü•«A4uŸ—µšAY2·±ÚJd<ìÎÁÞ qÔ·V€[õçáÓug!‚VH£=ô×+õlïóªß{~°Í¡mWº>…×Ä%#q‰Á˜×PhœbøDa(Òüè ¼“ͳ¹gÓ‰^ýèû¶œ®{ÕéÝ œ.íÁ£´Ð.cÍÔM­Lë2‰˜p“—–‡)«|Êû\YX³B>‘k»Ã&”5t=–Q^,•®ljhêêÚŠð?LüîH…x©æùºêÍJ ”o§X7|¬¯ÄT8$Frlž¹]ò60sãl3s `[RŽ”!j·‹•Tv|}~ úrÅãª(çXb)‘6L[(Пúâìà­EÛJ' ¥Gf*†"á º:\ÃÑÍ8EãßÞè˜úÓ„âtZEÅïš§6‡L“†èv‚ vŸZvŒðŽ9j€or<^Zzëyã)ò4¥oçP7Ð`ÆE‡J;(=âG5½°ÌZ´Ê ²·ëº.ëK¬ ÆØå,ã©X*XæÅc°\F3].Ðè9ÖtÄÕ€‘¦ªë1K§3bÚ;€¹>‰YÞδ®Ÿ”ܤ¿°$|hz=1c1P輇®AM5C èIÅûwPTV"Qªºï`Y^.zXä«¶™VjI ÑA^ªëhUzÝÔ~8X+$æ´¥Ó€„®†«”ð]ÓjýÎNΈ\¶æsѬY±"QÍþv™WÕ5R‚PˆBG"öAû;fF!ÞîšM¤õ$•¡EÕGå*ŸÍZ\.ZL…' K^Õ$Š”ï-šO°Ðл§$DŸôþ Fâ}-#ÑÈÂq™!ë×È[÷„Êÿ;Žâ}ƒŽâ¹£ †’?ÁAúËwRG\ˆg9öD¸¦Šë¦ÑxÓ±ìáÒ ÛLÄ63š [L4XŒËã³ÅŒ£í%0öâ³'`{GÕ$z2?0z‹ËÞ =‘èéi*˼g~ß‘yšÜð9ŽèK8­æ Øj/`¹®ÊU¥à®¼@Æ#À˜Rß®?9³onöQÙHÅHŠ3®µ™?#D¬²ì»Atøeø1-µ©# ÂÒ£Dwhèf²±Ã'¤¤[ž¸/ªL׫| =(«wÄ|+Œº".„)'*ž[]È?î÷ýͶìã”:&_“|Ao‰üJ»ážéÍï²úÿ›À×}…{TîóŸ>œ¼gÓ×½xÛíö¥¦s¿`¡0ZÂj=\‘ÐT©M^÷Ze®Ð3bó ŠÏÑJÏlx oЦz>¹¡cÜ¡ía™ÑØ+‹ÄÇ-¦?ø'bO‚¾ï-:(«™SÃo"~|D6©rï´-1CcO.!£¦ÿñTjÕ¯©ÑÄ 'L岬ò–cGWó™†L=­~'1/DkÛÒoòjmQGŽ=÷ö̾Þö˜mÝÛ»H³÷4¹^{3Ÿ—E™W Çˆ6»hÔyý ‡™‘Dh}œcs=k¨m7í~Cï(Lb€$î›gp?µØ´¸DèF›´wߟMÜÖ¾Ô{ªÕÓ’…ãîÕ ¾5*í}ùÑ-Ÿ™w³WÙä¯ñëг endstream endobj 772 0 obj << /Type /Page /Parent 1712 0 R /Resources 773 0 R /Contents 774 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 773 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 774 0 obj << /Length 2111 /Filter /FlateDecode >> stream H‰ÌWÛŽÛÈE^õ}j"‡wRƒ]ÞKYÀI û;8TkĘ"’’<ùüÃþã>äTU“¢4³Y?Ä1‘Ýì®®®:uªêÛõân½U ÖÛE*xÄyîù¹Ÿªl•xiîGj½_Ü}×çªìy¯ú²YÜýø6PýÂ÷|ŸÖ” w|=/Þ鿎y±~4ô µÊåü}ýÓbÅV*ó½UŠS¢ÜK}9„„,‹Þ’TDýbÖ }Ç "/Õ~®žÔÛ§fØa&ÔÆ$ÝW½zýãRýíWÇM0îð-ñ]9¾.wKõö\ ÿ2]ÍB"]4Ç]iõoþeÅøú|µÐ÷R ÖßcŽ58ŸÏžyîéTCÇB4Žôðêãv¥Ú±¤Ö‹@Uj&©¥Š2/ÏUxq¬pÇ8WYlß®'cD–ø×Ö¸˜Ú'‹@Ëõ?Éa±uXìù1Ä^å™’áhÔ,I¼,œYÕÏF«ú‰ÜiåeNNŽùz_|váQ±é_Ý+¼&úMñQ5Çýƒ|èT»•ùÞô}Õ6Šö`¹0·:˜ÎšÑ‹£(T.nëQXM d¢@oº6º¶„D“YOà’ù-*§›ù+/Ìg7 F¹ˆý®m†¢jÌFUÍ=»g&Ö‚=õ²ÑÁ¤PzA¯…Ü×CW4ý¡í5<Ì7_ªƒùê•“·:º, ÷…–Ómóé¶¹U«hT)ª‰VÉÑJd„,ƒ¶köC7"àÙÁÑ´)໼ӯ) b= ]õpLOÃ@ÓÉÐÿ;ö`¬è¦mÌožŽ‹ƒÀx**'Ä‘uñàP„Õ Íý§œåÎqñúP”;£`q`Ñí†^®ÕCÑÃ¥3mS?ý¶fÖH&pXÔÿÙœÁGš±q­tÎfzŽbÙª°1ˆ}ýVtÀïQ)",àùÏtb¡×Ѓ‰[¿7ÛâX÷ÖÊ“&qxÑ$`à€<·PRö—N7ö/rÙmþ-&à “¡Zï@šCñ¨ð8’y‡–1Úµ5ä°‡z•+¡Ž-¼èÆï5:ÔFYBèáZwÇFë¸9"or4…ïªF1¬„p¯½¦£‚¡ þ¢ä‘êæÑqc  –!0‘R öö¥;Ñüjœï8!0±È„ïû÷Î=­Ìõ\ð%ãÝýÑ:ƒ×„ÌcúòÅ0ˆÎYß„I Ì|íñwÚò,q&n“êoäáÂcýB $« ƒ ƒÑ:Ícm\Jƒ+Èé¶ ûIâdɶ¶Ë üUŽþ‚ 7‚¿¥x9Q"kßn¬‹\VⱉÈ'N'E Ä>…=C>"—„˜¢I%„¡Ÿ˜Ál¶mgƨyïxöî£Ñq`ÂvOo|óy<Xv|ÁᜧT3z€­Åx†ùF³ƒ*ÔPí [ÜZ©@êØä¡ãX÷N{¶USÙIŠ5ØaÉnrDx/~rÓõèéÆz…@l€En-‘}ƯEÓ¢†éFx×xŸLŸ}^Ó¿úTÓO9~Ìödx¡%>Ñ7¶2[‚`ˆñ{",FÚÈh©J$ðD’R%ÓG‡JªgŒ•ÄC»ÊjëYP ù’ƒy j!þr}¦ ä·âˆ)òˆbáPÈ^{z]›úÖµá5ç»ã+Ý×Äv{VDušCe®ÝÔš_wÐõ®Ì«ñÉzÐÕìö²ÝïMCöâ(?éJHß™.dÝP9\Ø~TcÎv=]Öœl¤Ëøâ'Œ×Þ(b>L#ïÕ‰Ùá6 \À†ëšnßSɹ7û¶Cuª<-QõÇrG9†Šú ìc«ƒCí¬ôñ±B*z¯ùc! ÌbÄ¥õ…É*ÏòÀT¼Mu©Ã‡üü'Ö5ØKÕ-‘] %)Ê{ãÐ/BiNXL7NÄn‚ÄþVd½ÐB„À ‹êꛥ÷¾'I|gEX4(—>á˜çæž $w^!ñaB+&¨Uªb0„ºh®¶‘ÞÏo&ö™ãå„:;UX yÃLIfš»hVb, ¡ÿèŸ(g±çî€õËTˆ}ý@Î86Ыr),ã¾èÖç¥&™(Ed¢ª)ë#)Áà‘¯¶e*Ë<¢T`Â…ªI€ÕS!R=WvÓr¢“k l]™¦x 5Ïm÷Òb-Y‚×í^?ÐV¨Ï/WMR©Î Õ‘èɶ‡>'ãŒiIþT ­è1ÕFrå¶Þpfà\-âˆÛÙ¦»JõÇ5H—ìýi­i”‚÷ãywI««±5Íqã\ZS›¦º#O5ä«\S“JýéTzÂ÷@Ržl|x’^µ¸ô¤IÎ=iàß6KþUî¼IfÏúÏ(ȽÐÿ2ûÏ(þ¿ýgxcÒÏß^ìËë?gÖøbúÏè¦ ûßöŸ¿Çørðj2†ó?m¹…c P¿’wŸz´@/éM#ù€ ö•V³!xV¶©}A/©þH1fÐÊ·`H©l›ì{+µm”)(°’œÖtD‘±>‰>×¢¤»´ô.U¿kµHÝ@(U=`$EJ´„š««}ZU­*‘Û4"½pÒ£´g­±¾±ÆK™.˜ÕË–•¨ TIA§ò¥RMVß$Så\ ç\ÝÙ®-ÖSËÇù|’ºÂÈH™æTÉkÛ ¾¤ìƒ~WÂdŽ_*…fª)qsÁÄåÏyWÕ”í š§¶ÚP k†cQ¿XÀø—JÙ·•²­kS|è¹ð®¥$¤ò…-Ü—éÒcùeyDFCê 9‘S7º¤¥> endobj 776 0 obj << /Dest [ 779 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 334 358 355 372 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 777 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 778 0 obj << /Length 3094 /Filter /FlateDecode >> stream H‰´WÛŽÛÈE^õ¿¤ Œh’ºP2œfgÆŽß`+6Þ h‘­×)“Í‘µ’È?æ!§ªIJšQ¼q° ã¦Ô¬®:Uuêô÷‹ÁãÅ"¢«AQ€øÏf~0 ¦Ï'þtŒh±<¾ªg”Ô²' :)Ÿ¿é¶~ðžd0ì–»ÁGõV{Ñ?V·†?#EqDÞßÌÅœâÀŸOqÊhæOwˆˆÄ¯&Sgê_¾F7 GþT3Zîéý¾°k|)ãÁ’ª³š.Ÿ_Ðßþí 'x®ðÛÄŸ¨Ì T²¾ ÷»Ìþlª\ŒŒ”.Ro8WôOù+ŽIøZøS<,®ñx°Ûí|o䇪æS  Ó8ÒÇ2@tIûÕZ,Ý,!e4ˆ&S4 iû³MC<&Ä8žQe«Á÷‹ŒQˆ-Á)¨F^.~â„Û„ý`ìr&«Ïx<òãèÐ`ÒÚå.{±+zšj/œ- ÿÞéÓ~kêïžÐµ7;úIÓÂ>3µ µ5tm°a¬VY‘Y˜eȇ¼¡,j,|žÝ/²ÞÛhÊÅvð6ìœ ¯WeauV˜”²â‰ «Þl[»S?îòÅäL¸×ŸÖÞ”m?ŠäIY¬¼1BÉn¿»ïßP,qð#¶æà›õðÍZ—tA‰sËy4ù¸o^Š_ì 2yšgìÜXÙï.èé&Û˜måMPS¥©vWÎGŠ7¤Újë…ÜRÈÏW"ˆúÂé —Ü8ÌVÙ²±¦æÇPq!Úâëq‡*ÊÂH1Þƒë¨Lƒ{.ÒÚåu±FÃÖ&±YYPjP=¦&ô– k K(Y®A|­-é ‡†jj©B+&ëª,²Z³ Ÿ^•µeZH^½¤$Ï`£îûàbß}k°3¶Lõžj½ñ¸¡·Û²²tw¥«”~Tw¦r?JiO¸´å‘"?$P üàGOVwWøe¦tîͱÑ©®Î _ñ=Œz%WÇHŠóÕ›àiªÚ8ú3Lz1½7Ž º¿˜7œ HªÁ~]ÓÎä¹O,w¨6x†ý”YJäQØ:VHEI›&YÓ¦¬ä-ìXãC?t”ñ‹PFÊU“ç{Nâ*»m*½Ì m5‚çŽ3ÕcOèòÖ‚· Si[V´ÂÿW/^Ý ¯Ùë™zñŽ¿Úhk‘i.ŸÞ—-áK·ÉH)g´e÷p‚F‚>½_Ç Ñ®Øë¥q}@¨.·J™§Švî§Dx´ ʌݕ3RÃëï¹ gh¤˜ ŸÓ³Î€È7[d\õ¿Q{Ž'_µV†³¼~à‡`z”zôú1¦¦²{œ71 ™½ ¤|/“ª+{ÛeÄÉUš@¿BÛ¸Œp‰]@0y" Äx{G¨i‚tÕÿÊói¶Z!ý ÆBoD=Y +à5äKLm/D­£„6Y𿍗\×n7\¨›Õ*û"cr[ÁÑ/©\I:ô\ªHFkæŽÁ% ìNäƒ ã3+’¼I%åÌRQ~ÎÎy}8Ùedº2hsêF»Ì,&fsLì-&›ƒËEÏ}ÀêŠ8 è)kr³]ó½¨h6KŒ2n’sùQɨûo•…z¼Ë™¾WZ +@£q:ûeE<ÀN´˜µ‚0är =G–êÈýscŠÄàò"4e,G:î;÷W»ï%esi|–­1']Ö|Szë1·½{CŽU™MÙ»Z9ú¬µnˆÅ—fK©<„¾M“ªèYßYݺDÃlÌ0Í*ba îp<'€¼ê”yŽO„v:ßðK|4àÎT•OG'ˆ=PWw·Õ­þj¥-×î5ë4\9U·#«;PäÈ£âá.ø©A²µË¹P.Ì È}L¿,A½%.nwŽW%ª›É-V»LȈ«µÝT¦n%ÄãgmœvßËÃïêgãv?ž:(T—ƒ%?©€‡Óêo£÷9žp¹£òFèW„š0{J=óÈ ü¤·5Gâ²LîŽgq/Ãê$¼®Ò~…?ªãhçHvÂ7/ɽ혬ZŽT•I2Ú”G…gÉo‰¦üªãÿgBÎTí™Ø-SNl’¶¶Ê–•ëÓËË×ÏÿrùüqˆÀíè‚¥¶§W'geûÃÊ`ÙÎ7ÆngrwÈ»ôýšxŽÅo{(>7:ÏV{‰ž+ÝÃ÷Dž»,ú"\/xʘ^„œ^ñÁÁ¸ë Úä+è%žN Ayp¹y±zéñíë lØož5üû¸ŽÌ…¢#u󇿾Ñ9Rf¤Çx§éHzžA;$\"r‰³Ù/)kÝöÃ!Z´ï.³8Éʬé÷ãŒ?Têº'kN´0bm;d*I5ËvGÝЇśë7¢²>Ü|¸y½À¬4'ûœ¾:¯ÉÞ>\]¾” ËÍëëK\'êã5ˆ‘ÿ4^ÆJ Ã@íù’4ñ$C<©)è()i„#ˆ3‘=!ÏÞÞÉ’íÀÐ…`K‘t·zÏL¦•[úÆe¹Î«*õHŒ‡uE+céQ;‹ BAŽªN"6"ªš·¥;½…÷áLn“[.¹‹4Äøô?õ#Å5탻öâ®–î%ha¿ýmÏ a°ÿtƒ$õ‹‰¼ØK•ÜÎÁ-¤Ÿ¾¨¾ ÅöÌåä“¡“Ø$élxæÞÍVYV[…»Nzá a‹e;½”SµSq&4ÄîõÃ7}u;,vy¶Îö„b½„È„ ìd.a(œ½•šÆ°ªá~ Ì»í*êá é’fü§ ­øí| ÊÚdÏ"|¬PGžã·3Ì´wÿ7ímê±jkM7‘˜,|½ãyïyÞ¦!KÊÛî‹´XÚ£Ô“б]5R¢€â4ª{8ǯ6Òš~äõ…^1F2‡1a4}æ?ü˜éÏ j5ij@ölL¡ qÓ©ã¿f¯R€±?ZÉÇu Nò¥u>©\Ó¹§7ÖÓ"-QEÉT×Nê;A‘Ì7ˆ¡“r¯®³©­²Ÿï~°ó endstream endobj 779 0 obj << /Type /Page /Parent 1712 0 R /Resources 785 0 R /Contents 786 0 R /Annots [ 780 0 R 781 0 R 782 0 R 783 0 R 784 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 780 0 obj << /Dest [ 1046 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 469 716 510 730 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 781 0 obj << /Dest [ 792 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 77 553 98 567 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 782 0 obj << /Dest [ 1174 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 218 553 259 567 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 783 0 obj << /Dest [ 1174 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 218 472 259 486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 784 0 obj << /Dest [ 489 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 123 64 131 78 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 785 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 786 0 obj << /Length 3100 /Filter /FlateDecode >> stream H‰ÄWÝŽÛÆEoõõÂÃX¢9"EI cÇ?‹¦ l(÷‚KŽ$6©Ô*Ûé;ô{Ñó}ßâjÕMqVäp~¾ßsÎ|½½X¯gʨõfdf*Àø‰–K?X±Z¬æ~¼ BµÞ^¼n–*mxN š´½øæ£QÛføA@sÒÑ´{<¾×ß%Þ4ô#½µô;Ój*ï¯ëßV¼ÃJ-ã”péÇÂÌx/zšÇ²Õ?gÎojB?ÖÁRÝ=¨e»ÃÈL[;é&oÔ«o&ê/ÿò¦s¼×ø6÷ç:÷î&êã)oÿnë‚7 uRfÞt¥Õ?ø/Æî³k³Àñ²~ƒ1¶àt:ù^èÝЩ–ŽÅÖ8ÒÇcïR7´ãÞ®GFåj4›Ç~.üåRÅÆ"£¥ªíh3úzÝ#4˜<ŽÆ9ÔEV®ÿ6H²Äñ[ÄÿeÉõ\¼o¢“¨´Úï«R¥IcU»KZü±ªIöVêj“–¦Õvck[¦6£0gù†_[•%mÒ>ls£<è¼ìV°Îpj|XFqÃéfÞBdÈÆ‹{Ôx1¢6ñ(v´OíÍ5Îê*­ÚÚ’G‘?Ä5Ucoá/ô=ÞB&ô%ó ¾ŒÕ>ßÛ©éÞ—š¾TüÔ6Q§]›io©wý9Gù…§äÍ©:û(ßÇ÷ÓffÌž£t†þ†¿At|$þòYŒU[QŒïóŒ"O¶,à/ívð½­›¼*Um••¦øÞ¿ÆŠlò¯ùc9òMïÂg¨¤¶j“—IQÐa—ÙõŒÑhÔ¦¶‰,i=*äªîvp‰~yÞôx8Tu{«äͦ-¬VŸ´{µjlŒï­0òò®†ëJy HûäŠÝ«ä>á”çEr‡ “l"³]’U’¦.QòW*¥Ü¢Ð)2ØzXÄÕåâÄ‹âE>ò(ì.J^;TŠãÈŸ-°4ˆtjdÑxK˜£^nr[d^ Ì ×M{{ƒØµ–gÔpe¥‘6Mal®i ¯ÈT‘óCÓö6./Q¹7 `2Ÿ 3\:«^We›ä%õ ÃÓB÷Û:°àqe YþrØK}{iÑ”×ö5(Yv6БfıaþÌ¢·AK4oï®ö›˜V}¯_æGºmëüîØÂt¼M'ÍgNæ:Dnƒtâ…ƒì½ì÷s®€_)6ùD*3‹Æ³ÀÝ¢Ë::¿7@i@`²­)J4Ù%Ž-¥ã×h<1Œp§sOPúÇc^côÌ6¿¿ŽÀÁìlá̵ØÎmLdûc™lAŒ(`e ˆlA¥ºØdG {ô@m,‹ ßEÒÚš`âÛ÷ß¾¾yÿÁ›FÔÀ;+ºÇ0,É[‚8 …µ×Qtu¶yåP6„#„¼{B€•€ÖR9®{bÝÊâ¸Ã"ÀPdH =–UŸ¼+`z®¿kÉ–J닎ÌzD2Ì5¤6¨à”M:BªˆÑÙDàÓZnt`RÌÐJaôVíÃ÷®ƒ¥~yAu·ªM¶ì(͇£w¶¨$4§_âÞ€GŽü¡j*Ê„‚мVÈ'Žáay$_ ùêf€4#rž–‹P$O}Q?æäÿú1ŸxîdЗb¾ å¿#@ûBÌ·8áB¬§6ŸPÿΑùK=§&ÄHß¶¦TøºL0ÑÐZ³%hM—÷VVo)ŤíÙ’kÜú3 ô´IÖ\Ë ¤ŸgZԵΎÚf!0ºq8E+^WÕ‰‚L|ÊMå"G“o\ÄÞ¹€±E³øÂØßp~Þ¹6B]» ê.qnµ‘þ¢/ãÇ)Å#_äÎ;ë5ÈãàF4(•§ 6¾ÐøG~2Ì’ÌdZGëõ|Ob“xÑI]'—åcÌ |Îý¸~Ã×ï>ü‘ïž ]@ùAUÈ úᓇ{̆«L>t¿òcERqŠZoºàË5ÛÑNÔ žÜ¢´¶`ÙLøïˆ*k[²eÀ)‡\¾£{©Û¹¯Ãù쳚…oŠ0DÄÝdc]ub$q:‘Œí4Ì}R‘>bOÄ ip·ÕAdHš?<Ü&c,ÜYX0F£ñQ.îDÓgA$Û “¡§Š'‹¥×¬'¼‚­Óa ›3‡G‚1-ªN¬ÒôHÀ€}%Uº`¾+cMS Xkvó(•©[=BtºC!r>èíŸß¼$ë·´éœØ]Ý¿bÇ–¢T³D¶øäyt ¯þß}Bi½Üa9`ÅóÄtÕ°SBÇUH¨ Éä[O3ýx‘=k<#ßpä%µP ;¾ø'7¹h…¦Eªjä”É))Yél/DôãsÎ$0 #7ªÞ@I:f{;¿¼ó_æ×òÒ¯AÚ…ý±hs\œHU]Úñ…áàòaº…-‡dɆ{Ó%aTo¾cg™¡£7UMä(r_Ül\Cs'¬¾Ž1GÀ*7ˆ–¢Ð€AThãaÊv=¾ä>Eâ×,§LžA˜÷'¯KÛÁﶬêIFžÀè¶NhÚ–ÏVpF¦ø—2võ¿Ô_ƒÚœCrŸ»òWèE#½h {ØUåEC‚Ðç?Ï[7"gð¯È ”žL¶Ü ”³‰²?¥öÐJêN;&RæôÀ‘F¤Ú8«³€ª{£p :„/§]çñEÏ@8 ` ¨:™î’:á-S¹·B›AÕÖig›Ý¨À÷W¦À¯&ê·`@ÍäÑs_}¬ƒö;Â`ù>0û%ÌÎØ5“˜á¨@j­"õR©1pY˜ñ˜ý—ÛÇhÏED+¤Í¨( xFŒ¼c¡lõøydèâ©ñ=ŽƒÀ[aCÇ€+æ–þ˜Ú—ãp#¤c«ƒkW°XþSdNâ"™MÙ•¹-ÛFe ûý ¸¯çDo!~º¥åqGAÏË´8f¹»‡†zKFì“v:°c pû‹¥Ü,uK5‡$µ( >5[¬(Ÿµ—8øÅxqNëârý£&zZ­ÔD‰ôWÃ/ªûu5w}u}´£bþ‰Ú$Öç&ƒHî·èдíêu¸¥ ŠãO~ï;*6@%Tç\ò'T¥ä†ÂøïÚËf§A ŠÂ{Ÿ‚°¢‰„`Ó&vïhÂB7´3†YPŒÆúôžs.„ÆâÒE“¶s™{˜¹?ßý•xåïåïìÁ¢4â§Â“«±CÜlÅuPùSË´ šVq¹UU)N!J†¶!»Ì›îC›è»|XP§ ÿáÇ<Š"Mzù7wáëþê¡0m:­É5Ù˜*nÖòÔÉ>¿I’õqN8»‹å¥s6 B]ì§•ma€øs7îè‡Ïà{‚(hC’ ä;ƒ»$}ç³Eú¶aÞ¡¼îð޼oÒOðhúrÜâL¾Ü?ªmh½”¡ñfuÛßàÀuøï—cÛÏTwÀÀ‹N§DÚN¸é<³XÑ`- ­Á¬è•ô›Å%4²e”– 1Âê Æ(¦÷l}¾Æ«•æ•="Ù©D:ÑÑÑ0Ž?é#ÞrÔ˜$™RÑÔŠª³cóÇú±^nf´Á÷ÀĽ©’”§—»#¼à endstream endobj 787 0 obj << /Type /Page /Parent 1712 0 R /Resources 790 0 R /Contents 791 0 R /Annots [ 788 0 R 789 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 788 0 obj << /Dest [ 489 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 146 730 154 744 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 789 0 obj << /Dest [ 489 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 164 661 172 675 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 790 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 791 0 obj << /Length 4074 /Filter /FlateDecode >> stream H‰¬WË²ÛÆ­lùS\ R$„ñ v–d¹œEœòe¥*Ñ͇—°@€…‡(úCòùÇ,rº{ðòRrìRY¾Ä¼gºÏ9Ýýf3{µÙÊW›ýÌ”‡ÿð³JS×K½X%ëÈS/T›ãìÕÛ6UyËs<ÕæÕìÕ¾zjgžëy4'Ÿ-‡Ïóìƒþ[æ,Cw¥Ÿ ýZ%+åükó—ÙšwX«Äs×1N S7öäÞ à½è+Še«ÿè]ž³ôC7Ö^ª¶õp©ºzmì¤Û¢Ußý°Pÿü¯³ŒÐn0¹‘.O燅z8ݯ¦)y“PgÕÎY®µú7ÿå‹ñóùiçÆhlÞ¡op>Ÿ]'t}ÝÒ©†ŽÅÖ8Òŧ‡×å¶ëÀ;}¿™ùªP³ ŠÝ0öU˜¸iªbß]­Þ¸JUcfûÙ›ÍhŒÐÇï¹5&S{dÜróË•›|/&±çâYCˆ&gDrØæÇ‡ŸÒØóÕ£î[³ïKµ¯••¥¢è¼>n‹ÊìÔ.ëŒrЩ®8õÉY“½È‹¡.{Óª¢RŸÞfÍNÑ~ë,W0CV¢iSa7Õ»¬yt\õÎ,­—¾‹›“]q9oAs2Õ®¨žT])˜YåuÕ™ÏÝBÕŽïÃó`׃iœ~Uë ]ÒWã*X.M¸)ÀN¶E³MÕe]QW­Êl¯ê¹»”ÅG£~~?§xOŒóRlèë  “MÌ1+JšO¯z0F]=+´pÉ3À\vêL£"6ô“©L“•Ø­#ßAeÛºïØÆm—O­Lþk]™Öew¿zoé‰#":'ˆéý'\É eñ* ¹bµë­ìÈÜŽ¤ã_FÄ1cŒÜ»Cjçñ´Õ䳕øl®^3j–0ÜZ×Uy&˜9€1ã²ù60ªŠønÃóÌ]±w8ò—=æ³7×C£Êêj5ï Út¥pøŠ½‰A²Û\Òd²Žq»ž`Ú¡?+ÏÙeøŸ2‚+¿WÒ‰6©<Ÿ%/Êʞζ]õS? ]ʳJmÊÚ¶x²,r|z;?"Á±!Ø×;õŒi¯F†Åb­µ&¥ºwø, à¡Ë*¡ÏæÏrOº§?Üdl»†¨Ó˜ScÚèÂî/ÑŸ®¹LÉœ¢ÕÓ[ÁrÐÁIÉêÍ»ïþ¡ Ü ÞpÈB"Á=^ß ïÌ=fÃ#©þìª5‘ͽg°Æ&ZhKŒ½¢+éN¢ß³ ¼MƒÀšƒ­ÂTº¡û’¤t±`ºc w$>3iÉS‰˜$Ô/ 3l†HßR™<ú’Åtúh|%¿Ièô–Ðˉz^ÀœO¦™?çîÊõâ«Éòèë7ƒº e¹ªúã?:^©-pM/oMó Š»Œayݱnù²€wÚ\Ù—;¼¶hë£Æ%ŸÿÜî/±QÇ¢ƒGeCu*%ÞtdÝÖ‰ µŒTÑ’É7²¤à|[ÖÛ3‚–éW%𵺖6à•ølg!5ï3Ѷ‹*íד³ô8ÕÛ_LΪ±†¤’™s'Á7ËÂJ³¾ô²ŒE´ èЂÚJ&Ö]â¾ú¨j‘Tuu¨*Á4sGÄÓž³w=yh-ÏÛ8Èùq¤„jøíé±+--³G H4© Ô¼„N‡få³¼ÀмëeÀØj;©«²“GàñÌqÉX¡¾EBøÇpð»C¤p ~‚ =ßyi2A䎺̑tïjŠmß›‡²YšºlÕ¡>«}aʨœ=fGj†¬3§‰ûf[p,mKLç~‚ÊH·t¢Ûr ×±b_4­dv[Îì?“Xýµ¶‹9šÒH ˆù亥E Þv<§ÊÄ|š×“VÚŽ•Ó´!6>j»ózÜ*Ò5¶¤5Ð-4¢ðèˆIîÆ™;D”Ðe 7pB,)\r¡ÎÃô²ý™]„îJ=Ë?d ff—Ÿ(4‘#˜[¥MIòήÞõ²´à(‰©•%æ‘Cæ\†¬fÁÉ·l$óÉõ²ü áÀßÓònüšÞîÙ·Ÿê†d¥Ñ‘Ôʶ‰(ë€*‡£)aëVS½?š~‘¦»ëÊPX¹Ú`=Ö]¹°FüæTu7‘‰Ìç §ð•%g»Ú·æ¸H¿…jûü0*`òÜ´þT>ù¶|bt@Kç?ÿwäD šk N`­HÔ?:Tnv8}æH8fHRd5áIWö›Üâ2¢ÖÁ „ˆ ˆ€×á ˜yqRF7-¤3ø‹6/Í”(Žî#RT5ÍÁ(7Þ«î\Û¨ñÉ>ñ-T›Av\¤ØPf:çë©Ì·—[/¶r+²w«·~|’§”Ø÷G½ÝsARp '‚‡R=é×}¬dL{~´’IuEvy£’xãÛýÇê<ïe»/ [7³M™‹–€¸Ð’{#`®ZÚ²?Ž5Ê£w¤›¡·åʵÞOŽ÷QšËDÀ }Hð­ç“ÚüŸ*z_”øq¡$y“Òo(Ø:3ˆ-§,AçƒdÕxGÜ”–¨j7î¦æòAaFÔ²ÊçÊj¨š£Ž“”ÈssqÒÂê%ò÷­y©–¬aØÑ ~%ÿæJ'¶ý mÜt(LæÂ¢+$§Á­6>Óõ9ë×Va„A1_ßÈ9‰Ò@d±d¡MÏ|)i|=ÔN´q"ÑN–Í…Ú’> ¨Ùí ªn\òP™;›•òQ;tô˜}á’NioÓ ‘{ ã—Ï‚c>”‰¶%¦Q³>/9‰”>JU ™¨·ò‘O@?=ª™w2K ÐÍ|.¤Ùãž ÎPËyŸÈ˜½¸ÿ”z§¹2Am¸E™o4Ì¾ÒØû™Èf@²Í•æW„$.²Þ LbjŒ!‹ÞéL‚tq¤X>¨v±Ã[‹ý…•{»|Áá+-ÔÞ2„LhÄb ŠªêÂõ2΋¸ùÔÔÛl[^…Hs4Ù¼´aôX<ÐUì÷Ð$JEîf$Éd‰dÒ3ë*Ρ:AÆ”æt¨I(~ÑOÏJC•'AÜÁ´Êt¹K²6e¨Ù@ÿä:F¬ÇôÖÖ*¦ël{u5A5ÑÞY¦hVÓ–\lRМ¥O Vîf· ªåÄÑÚrj:žšZXgMS^rŒVMa[9’“jçÉ:ºG¨§îúx—uãâ]OSbÝv¹³$8F V¥ú,P¯2ʭɳÞvK8g¾pÒÚØ3_ä Á.2UŒ×‡Ñºâ‰¦‡Œý$šc“L8:ËR@d˜*¯¿5ÝÙP0¥Ø3$žÓZ#EѤ"#vµ2aÈ-ÜEMûÛ`ߘ¼nd \éÔ ¯äíP¹ p䕸5Ñ{Ô÷F†€(¼Ê=%l܆ŒØõ®ŠÍo/8 !ÌQ„»ÉŒÓë :¸–NùÎ"Òh –!E€€ôÓv÷¢4ÒBi²]‡ ƒ™ˆª&;RMF•të:ÀˆWi.Ó[Ú>XQi£‹$öä… zL‰‚à7“p’+ <”SârI:·ùòÿh¯šÅ(xϯ°8i ˜1°·(3‘rØDŠ6{š‹zÁ’±FóïSUïùƒÝìarÁ¸Ýýºû}TÕ£¶oRàÖßêý]º{É4€n_f=5Ù¤—Ìå.±óNj»‰¾‡eŽ6ŽZìÌH_<6B/pÕä¸È#žDm£W€~ß¡iLAÛˆ„"RàÙ¾¡¢%£ö‡šfÁθÕ[×55Z­åE6Ŭn€‘£åÌàï0œÊ·z}¤æÀ÷r©IJÎ=äõÑçßîP»>x%&LG Âkxmùü£~HšwЬÎOÃ…E¬+ªê@(“^éðÌ`ë…žågÛ]UlŠD±Èêr%ûH»™2¹Èð‡|ù2ìt?Kœº!¾£Q4ˆ5% ÐøFÑ?¢.oÇð\?É”¦PS×Ù<\öj#Hö¸8‚7ߣ€ÊšÄ6l¿ªª9D7sóR.d¥k›QtÙ¼%Ú×ðîã›¸Ä m. L=Ü»ŠÀ³¾ørAU;&®šÕµkGàB@Y—X}­W‹Ý F¨ û2@ È¡0éâ¦?=‹6¦÷"šÑ"œ(Ìru0„Ùuˆz¢6¿wÙ0Z\ý²ÀE ç£0R¿šRH ¯¤÷€yo4MÜ z´*‘Ý6/ªß*®C{ƒü[P´D2PGý×yì+·•5DæuK™>;ÉdãØ-¼éëÞqÚE,õˆ1Ès¶e6‚¥vS“ßx ‰t|ŠHJi¼²‰­ûÕ³#úsKpVÿÝfÙÂÚ dç+—¥@Ç-âeðÉ!£ØO…ëè‘ü¬åš~zä&¿ÒßiÐN¿eûÕ>on—ÆK ?ß³3ÝB+½£ËåÙ¼?«¯ûj=ì@œ!¸#ô¦>‹Zá¡r•í»µO¿~y¾ ºãZÆ-Ÿq£IüHñ‰—›Å¿ÛãùIÅÀÚR‡íú³Ø†Á^ö§Š»Z ›WU ß§êlHþÏ"{3»[Ÿdc@éè”Çàs6°ÝØ["{&Ò+±Š™9Úb8Î&ñ,M½ñDáfnà ’ÓŠ›Âæ¼è£íÑÛE“ˆº„·ƒÞúEHîa ,ƒKô9‡QôgåË}È2ú§ G ,KiÜzŒ/Lßõ±&Üf—k ÙV«ÐëB%ò~ Þ ÉYI§í•££KšÀi?Š(¢+¦HÓS$ŠLuì&ç}Ò.øŽ¾pÎ`V=˜žãË9g4ÅiŸŽödzUš¼dúnÃ~Mô•ß:µ¥ ùìß €M&ÿ†c+º¥Ï0عÀtöI:[pLU3o@¹ûF?+±à—YÒÂ+ã6ž7š¾£ŽMpéîÝ”Q „”¤—›4m´õ“³>ÔâÝFÆEwã…߸Ìá66p/ †ÙMNã1dà–×e³7RøRKû[UÕ›Qí$^“?°=£Z‰ŠДÙ«Mr‚>]¤ôC׿ýŸÂg¢tŽËêjý¬§{ÆNy+;ˆ>XÕ|Éëh;xc„35‰Œ rŽ&‰ºB“±0í%î¾5O‘8<)•Óý4>µåNÖš7vL̉ñÑ =H0¾ÊêVîLç]þ[Œ;ïzÙÌ™?—ƒ5’`Ö¢Û]ý~n&ͦ½p$]8’Rȉ‰8qÜpâXŽNä v‹q$Û$n)4+%–ŽDG GÏð«™™óæ2~ög\z'·rÜ'i‰ùÛ>^`LwÞ?ï²Úå†f2nQº@E‚Jçñ†!e4µƒ¸*ŒØÖlÑJåá`£ÉI–'%Ík¨ÑvÙ‰ž¿üòïl&Ö endstream endobj 792 0 obj << /Type /Page /Parent 1712 0 R /Resources 793 0 R /Contents 794 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 793 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 794 0 obj << /Length 3033 /Filter /FlateDecode >> stream H‰´WÛŽÛÈE^õ ½„ $Ù¼ˆ2’¶3³ëÄY/l!Ä,(ª5âš"’YùüCþ19UÝu£<Œ-‰ÝÍêêSUçT¿™ îf3)<1[<)\üá+ˆcÇÝHL¦¡Å®/fëÁÝÛ:iÍk\Q§Åàî»Ožxª®ãº´&ŒÛŸ»ÁgëÇÄûN`=)ú––˜„Âþûìƒ)[˜Š‰ëL#ìâÇNäêMØ€d[ô+Œ´©IŒŽ¥k=߉,7ó½ø´/šF¤¥lX²ê¬¯¿‰¿ýÛ‡x®0:¡•Ù®•®FâÓ.kþ¡ªœøVR,ìñÔÿäOvŒÏG“®áaöŒ±»Ýα}dzjÚUѶ0-ütqºÔ ­ØÒýlà‰L d9~ä âıˆ<'ÎÄ¢RƒåàÍì†ïa‰{ŠFµKˆÀËÙ/GaòÜH8‰\ÿl”Úûf•&«€—øE)f¨1ßCýåP°|lå¹ÖOö8ÂÐJ¿”aÆÊéCÑÒÐÍŠÇj[’MÀoL‰Ú¬(j^0×NÞ­›ªuÀ =Ùã@îÍ~³õw]ÖHõ ¿[íõÈxÌa¡‘ÊöðÙn´fCƸ9J#æíôÁh›b§˜õW ›”ÁÄ‚2…rÒ•Á¤Å>«íu Úï¢lÈY‘&z%ämòîÁ$,‡d^NL"¦:­_QÜ=zÒÉäªN£ŠvÜÀÌ ÍL|xÇÓ3ÚטŒ¶’Åb[À«1ƒ¡¿P>œB-´wëÈì©©˜ðäáäžÉºá+1³©WŒÊRüôSž}Qb¸Ìò\­7Í~ȉ‡J]1Dô°,ó¼ÜeÅ“XdË¥ªT‘ªW<“ˆç$·¹ü¶LJ´›”E¾×p"…c’RÜ)Ö®¦å&S ‘-EÖˆU‚L&Ó[²’Õ‚÷+ %Êù/*mØC´xx-ÜHKy„HÔ!bxlQ»g&áOd5B~VaEØÿòüù èöq»}\³9Lð•ø¨Øe{s)%ÚÔj>Ík>¢âtÔHIéÈè4¡=¯;„§«¯ rl5ó›b—§–þä”P0—ŠFèI=Z®‰.<ɬäQ]ph§ñ`Ó—<£_ê«=Åw²ÞØ 爹g©˦”zKL€zý¾¬HóíB7áŸnxTÇþ L‡³û÷C±©ÊªðØN}ÝäYš56áYÈ·:Ù’Wb]òܘò’8·Q¹ŽÄfE¹Tl×sU§‘D:LŽÒ(ì"rù·IqRëÒq½›91´#"ƒ Ô× ™Oð'© Z&&ý.(qU͉bÐäJ¤cL4„€¢SsÀzßjÏóèSôG¼¤K踂 e*³É½jÎJç v{³×:âSÉ49ö¥ãßdSIµJK”<([Eà¤å>|SŠz»Ù úÉÉñ4uÐ!ÁE)J£Oª³<ë,Îrä¢5Ï‘¿»U–k’¹&)]üݰ•%–YE¸Jp„Öjƒ täÝ:{Z‘ĉm±KŠÄ/‰bir$±Iן´¸%%Òjcެ·©-Ì -­¤Qk….—š™¯UM·«á®U±œZ&%( ø ºHO;šå©3š!/Ë Š¨íB£ÿ»"²[yV€9ÎLLã£B º#'²çAö¨Ô˜ =£þø~VÕ^lõƒZns:¨Xoó&Ónˆ“Êfí£ÅòøÃmð^7ÔÅç·(ÙGÛï–ú Í›æ=ñØT2‰ôI®0:DuDáÙ‹% g­9­¥ñ'¤P©I×Pg"ÈÙñ|¯žëÉ„ÖO,͵ÓsË»æbNò?5ä]îôø+¢%{8tÆzŒ$=¶rV­T;p'´.®’ge¸O|ÔÙo®çàgD±¬ 8s(¢‘ðz¯ÇTŠ[Úœ2ŸÚŽrۈŖ²?Ñú¶P(–çF†@òÒ$ç£×D$#êLW€""Àhmªã¤;‰_¶h]“ë¥=í|j_ µcóº¿Ùl¨~¸|Ûn¨¬²§¬€`c“,;ήˆÚ©‚B2бÔÙ†wM457¶­a uÀ=½¥[†kÕ}¥Ÿi›¡ÇõìTž;}Mì]²ñyÉŽ;:ìØ÷8/"MWI•¤ ùR²1©Y' ÝUÕ3WÕG´-$ƒ¥=޹ßëÑkä/‘–ëu2%uÈdœÙÚp³FyZÄñfŠ\bùñѶ©½'Vˆfnï«YÿTàb?ë8nE¸#Ø®Én¯vCNÆ¡(7MVÈé-‰tݨd¡;c"lÒgÎe¡³wD:¡‡QÕôÛ$4Ʊóý9Ù’Wvº$.ÕB:®Jц|àKÓ‚£ƒS"@¶Ç—Ï¢gó¾uh¦MÔQè­Žw)s&(¸¨»ýï5@3¥©ÂShÎÃ#¸¬cˆÀ;W÷ÃâKýÃT"ªöצbÛ{FÔÞ^¢¶™ž˜—™…#ö¡ }ovJfhveKmleD[ùšSѼ4oc¾4N1ê\ó0úf |&ªu£°œrK‹¤)ð¡ÏBÌ2ßfÐ¥D§âž3!zDümïwÕ /³ý¶O}À¤)ÃÙžg£qŒ™ ¹lvhHÑG”y¿]ÚZï—£!õ&CÌ-‰7ÒR7îÅÐ)òÁ 4˜o©Ä.}ÕX°$󿏫Ú㢥ퟆ)Ã0Ô?.¸ ŸÌˆ™A' ºe¼®]C5SàšrÚ¨•ìY·n—]æ½a¿G o·¸WI@·<Á=‹¦(¶XGVZkÄjSeÏHœˆî‹8nŒ¥nŒi.a!«¯ëãe;¾äka¦›‚^ùþÑ~ÕªŽ×Ö¸ðô蟭ßÎb#×µŠd­~7|K™“6Ãß³•ûÙ öqñD #–'óg¥ËoφÑa6Óx7º±#ƒÞ׿1}´·4“v._¾2ýf6º.þèÆåúŽ¡¶H.ra}@è÷êçf¿Ás“­UÝ 9†çp!/A#f[¦”S¯zæOÝ¢‹¹åÇt mÝ‚úB™°{¡ÐA’' ì!wç‘ó§q¿W'¯cãOÐÈ~l~øùýëO³xꦂҞcãÇ`ïà†O=ó=ØDüƒÝê Iò]²g0PàG[OP›G'ŽÎ2­o¾‘ Âê[ˆ<¼ûø2HÂI—¤W¹>݈÷äK |*‰þ{æ{ñ¦Î$ºÈïÞýõ%ˆøàº[‘ê™ïÁİš®¥Ç˜Ô9.]û"½DÅ‹œ[ \Ÿ¾Ž‰œJ'¼Q6³û÷?ÿáÏ÷§¼¢rÅ*q‹‹Žò–k=ó×a‘“Ø™^ÔšÖü XdþéeÀÈIèLd¾ôÍ÷zXýr`"Ét/0=ó=Àø1ÚùUôavÿ‚ ’ALûõ;Õ3߃‰·{!A‡Òþ¬UE:¤/bJ$}\nÐ\ßü‰Gÿ!¼\v†(ú+,m©:©ÁE©â3ºJ• Y‚P¥ðÿ½3cOÒÐÀ2ø‘ËØŽÏ ¼eÈ‘½¤%Ú­f¦Kƒ“¯ë~Çó­Ä-©už[f†?iÎï.Á§Š÷à2׎jŒ Në‚›‹ëâÞ=Š˜ê’}/™ faá{[V@Š…<ê@?ÜÌ™n@ÎJ›¡²@ðÝÜóÝÛ`.Çx²œÝîžzÛ´ÇØEþíJlê ™ÂÅ’ÿ À×Ò‘æ(éÙKO ò¨c<µô2ÁY5Óþ1ã¡[Í’á$öAm(v[[8Ö©~Ý ôè E!Mzåu3l…¢OÑË"Ÿ:ËS'Õú[Ž©máhþ 0‚±Ù endstream endobj 795 0 obj << /Type /Page /Parent 1712 0 R /Resources 802 0 R /Contents 803 0 R /Annots [ 796 0 R 797 0 R 798 0 R 799 0 R 800 0 R 801 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 796 0 obj << /Dest [ 795 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 324 743 354 757 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 797 0 obj << /Dest [ 874 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 284 688 306 702 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 798 0 obj << /Dest [ 779 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 410 674 432 688 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 799 0 obj << /Dest [ 795 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 437 496 467 510 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 800 0 obj << /Dest [ 804 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 421 384 451 398 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 801 0 obj << /Dest [ 817 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 436 67 466 81 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 802 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 803 0 obj << /Length 2649 /Filter /FlateDecode >> stream H‰ÔWÝnÛÌEoõ ]- ‰á¿(Ã5àÄNà¢qŠDðE’^Pe± H¤¬*Òwè;ö¢gf–¤,;‰?àË#.÷‡³sfΜy=¼šÍ<åªÙjàzÊÁ?üql;±©É4´£ØñÕl3xõ¦ŽÕ¢æ5ŽªÅàÕ»O®º¯Ží8´f1·ûÁý÷Äûv ïSúõ´šDÊúÇ쯃)Ÿ0UÇžFøŠÛ‘#á<>‹žÂHŽú‡·cϱƮoGÚ‰Õü >Šf7žN-œ¤ë¬V—ïFêó­qˆq…¹Ðuf9z±©Oû¬ù–V9âë¤XZã©VÿæÿÙ0¾>_ÍsìƒÙÞ±ûýÞ¶|ÛÕ5}5¥Ïâh|ÒÆ£ƒÛ-Ì«5Ÿt=¸*S/Œl?r•?±ãXE® w bU¥ƒÕàõ¬s†ïb‰óؽ«ò¬œýó¦Ö“ȱñÇ[¾èKõþæýõøêæ£ÚVå*ËSµLWÌsu‘Ö Ö«´h²*UuSíÍOåJÑ=tÒož'uºTˤIšÃkw‹µJjõð&©–­»Æ® ;ÈKËu» GòZYYð¢MyZ,Âeä1uc…phcy´d³«1ŒÛá¢,š$+TY¤ê|+ûJ þÓ+À0Õ¸Ö…jkB¦¾jÙœ¦j4€“5Å¢¡5¦Ã¾Zö±Á¾u!ØŠWOïâõwñä.ç›l“²%¶$„%رNèóˆ"ò-½•ù¸ŸÌ„eM߃Çh:}r9&¹ˆlëj¿ÎˆfºÐ¡»ÆÈ+b L›[†æŠâk6vÙê’‰ ‡¡žÎžQ˜€Ý 2hi1U›ÝØš5>Š[wæÎþ|å-vP…8¢Ó}–çàïUZ¥=üµš\­ªrƒÃ²v˜I’€ ð«=šhÚ`šÍL˜¸DC`û~¼C”FúÍåÇ+Ë%±<©•¬'ýM`:‘òW©¬1)E})‹îó9dzRJ€}}m^ú_£"wùqhQ^ÛÖ‰=ÑK½ÈýUÈBvTÈŒêéêð„RƒéÑÆ¾juzÉ ›p;ª&¨Á&YѤ÷iÅ@B /HþÖj]î>|PR&,È ÷-4Í¡C¡ÂÈGöôø¨>+ZKФuäΤˆ¸’n e5Ã12]”ß¾ŸS˜¦ò =…`¢¸êE®Î3éòéÆV·eµIrRR‘>Dž’:·\: ÁT›µíµÓ)/‡ýmB#Úw›9|7˜2JN¡¼ïòéhá:Ζ ½WyrÀ’ÕKá¶ÎÃ'Œç[ÏCöÐW šGÃ5øŒŸcçgú=*¢â&CbM¤gðµy/·áçÑQÛgfÓ%›-®‘ÑŒa iMß(D1yàf5¡³C†C¶¤6™ÃJÔ€²5§(›5¥wxbÏC’ïúSÍ×Òñ³ØLzl&r_Úȉ±.š32¹`Ž©Œä¥¦üv„oŒ ñئ 4#…”QÃ.)ް@Û—;ˆôyú¤ZŽ{1r¬Eê´¡¶Î¥m8:(~§œ]…È«E¹C”WiÞÎQÎù6E\›†FLQÌ<„;0ˆ‚jÀ<Ð/š9&Ç ]¨úO¼©¶=ªâ¶ˆ/÷1±ŸÔÛJoB¨ ´Òß?%*)òÈÔàN ¦)5”è)"åuÓ™Ê㉠Vf ãPKÀ›6Ô ý´ðB¤nü»öÂä½êF˜MHÿ³–üCõ¿ç>±½±;=4–OLùc~gñÿTsŸŒ¤šÚêÉß$W䆚ÛYË`-VîÔãŸ%‹ºœx1Z¨%/CË1ÍÁC“m,êWÒoÐUõ Ý䤎n]¿çß@§€ú×5w¹µ²|u•ì\Òd‹4dÕ°ž7Å‹X^@¢„¶”2¥¶‰<ÐK™!îè 7,°ßó4ó!b€  2§.ÌK–@¼W€LgÁ÷…õáT¤  ÁÌàÑL±àó]£Ï¢-oXß]Yd¹±•´*©áMÚ¤2®y(ý\4(êë5›øÎñ‚Ì¢þ³,þ2l¾eË!÷ª(D< ß=¸Žì†° à]êBT)–+ gDíõlð¿Êž.ã endstream endobj 804 0 obj << /Type /Page /Parent 1712 0 R /Resources 808 0 R /Contents 809 0 R /Annots [ 805 0 R 806 0 R 807 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 805 0 obj << /Dest [ 922 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 227 701 263 715 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 806 0 obj << /Dest [ 874 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 284 701 313 715 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 807 0 obj << /Dest [ 795 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 392 688 422 702 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 808 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT6 1665 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 809 0 obj << /Length 3484 /Filter /FlateDecode >> stream H‰ÌWÛŽÛÈE^õ =5‰æE¢(ÃkÀ;3»˜d/-8@ì"sAf8éÅÓÄov­—ÀzÖ‹àUÕV-ëÊfÐ"«ŽêÕ¶ñ&X íx ûޝ•Íîå¤úMÁîª2&'&ºûUOŸÅå\&³F›mY, [ÕÒ›1@x!³&÷ùàBèÈGþ,ì°ˆ^|ãöŒã)mÂÛ£mÔ’å‰,ÃÍCî܉i~0q+C·’ögœT1ߌý^WåqU7䄇Mýxr¶PpÄ q†Þxw½8Éî·+EpÕ­±ÊÖ2v[jWĺÌÝ·ªå†-ì×eô5ÑŒ ¶s·÷€€imS,mËÞ"1?b퀩既µ„¿mcÆlwÐu6e ņž€ð÷·ßߌ¯½qêÏôí[õQkh;RÆ¿÷R(HLÔjïÍ1¾³&¶ÃÍös„yurªQpÈGOÕ4›à]±Ÿju)"¶8™¾Ú_y,$öƒÑÓ\8QA^áHì’x L3ý >Ïlf[G0ZC€„™†pÒûS?Ä#S=!—!®B+™ÆìL‡2Kïl.€M‘mú°#mú%E$ûƒ®v› Õ~xw¤›c§°»2ñ's§.ëÍ9€¿T ð|†¸ÁlEË‚ìCÝx”~FzHµ[ÉÜond@q{dgá…úQpħ ])+QÞxFÞâOY’m€õë‘’Ûà !A‹4"Ip8|Ê óôY'Ìý8ý’Np¡W…)óÇW¤ÉÉèÁüÄÅù™Ù ük¼V´ü¡ê­-ê*+Uf-E׉.îvÖ¨eV)Ù²åýfY¬À²™>ÌqC»Ç`V¤zc£ÝkÙ¨2%ƒ‚àj¨L!„Ή #7É&÷ñ`¥ZÊ9 —·•îÖ‡`ødFÝÑ"uuÁºX®Hvò !ÎQ‚kê’ã¢,ËÏ L5¥V .sV9!ùêá‡"ØajGúÆð!^gÊú €[dÍRnºÄUâ§³gq•úñì áJïYïç`Çè|ë%ŽKjè8 UÇfÇ-aª…¹¦zäÁ”õ˜‹®sòg²Eþ:b†üiÜe[>Á8dy ¾éŽ+<‚âóX…X%'E†»Û÷Ÿ ¬ógmÊ3ú,Û3ø¦'NÅŠPhÃè‹´ZºêÊ8–P ™u‡ ¾‘î+ÃÃÚT´o|–ý8‹Ðt´¨î‘ŸT}÷ÐLÁ6ÖöÂtÉ'¤¤´ËHÉgî"Ãl‡¢,Ébe Š@‹µx(Ì5 g^Š[q·Rî)8Oô0!ß@æÓ'QxJϦdn%Nb"Æ,M±§XAÆ%‡yÜAÀmR¸Í.~tYMÆ;vÐÝ…ÕÑÉŒÎO¾3KVv([{JËŸcíß§]Éšc_}(ÍÞ”2ÿÄÏãcž¢7A§Îˆ«G?h=ê;iêÒXaH£J–Ì P”oú‹ªVe]Ý#ü"CIsÀý†×f®¡0Õ=ˆ¥²­78Qk¢—YYÊÝEæ†ìwÄ‘r‡9ÞPͦºÊw>ö^ÜWñ]óvjÄ OKÈ`Ûu-eU±©®ˆÂ¹ÙßV« ‚ɯz–k!Š®ÿ¥üCHžZåÁÜ_¨%m^n¤_ÖñÏ»œDTéT‚|²ã %ø^îÜ̹=‰þÝþß±þÓÝön/V­)ÍÒšœº”‡÷¹õ‰6ê…• Šš M©1å›þ²LD…œ‹ßˆ–d±Þš5µLpªKUØþ ‚ª¾óÆs¸ŽRdâšVZúè ȈYcœ ‘’³žµ·ê~ß™[¸D›“O‹VfœΖFHÅtè”O+Þ8¡Æ£;ÚnÿÅŸ…§Â*t•7 ù¨‡i˜R™KYkîs9?çr~*å<˜ÐýîÜ ºnWRw„Aº¦ 好ô´™ûÜÊoÍÒÙ|8<’J[IÁìÊuWÛµÚßPÉÛkTYîhÏ2Û©?±·ð{†[]J…¯ÆÆ VÓØö˜W§§:õéZ’š;Ð ÝD:õt§v‘h×RM—s;CÁ äŽÒÌeCìʸ¦®¤œÌÊÆd9Œï  D‡g>£ÐŠK׎)`ÃÉÁ38˜DZ€P(!4"­±$´'‹3€:v] ¬™qù‡sC‚hz£WRlÔ³‚ÑUŒÙ=pëó§ZÏUg©îzÞDŸâMïä×ä#à‰‡œõx'¥>š’&€íœQyWZwZž­$ºt×Áˬ»‘B.Ü€æÇ¾lM»Có4NÏë âj(ÑìPÕV57€UÿÚì¡@åÆÂ“B º½/–ðxÒ}ªÌÙÿö•òf]]R=Xü;êq;Fw‹Â wP¿žtÙŽ–ÒîqñÙãæò¸›_¨] u¶Ù–0êù—ªýY挛±µGA¤¢p%±,ä"“ÐÀïtûÝ>D,ÞA@åÁVïüôxÎ5ÈÅñ–ñûHµ@ï¯xÛïn~àÁµ|zdë·> endobj 811 0 obj << /Dest [ 922 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 227 700 263 714 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 812 0 obj << /Dest [ 874 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 284 700 313 714 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 813 0 obj << /Dest [ 1254 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 309 686 337 700 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 814 0 obj << /Dest [ 817 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 245 450 275 464 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 815 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 816 0 obj << /Length 4010 /Filter /FlateDecode >> stream H‰´WÛŽÛÈE^õ =5‰&)’¢ ǀמ]x±^,l âÉCÕÑ¡H¤FV>$ÿ°ÿ˜‡œªjŠš‘²³dacÔl»ërêTÕ7ËÑ‹å2R¡Z®Ga¤üÃOœe~©š/?Í‚™ZnG/Þ¶™Ê[– T›W£ß} Õ}; ü ™|4í—‡Ñgý“ñ¦3?Ö÷–~#­æ™òþ¾ü~´àjø‹·Ì2? ä> â³h•¤rÔÏv§QàMÙŸê SwGõéXuìDÚz8I·E«Þ|7Qû·7MðÜà]â'ºðo&êÓ¡èþi›’™iS­¼éB«ñ_VŒÍgÓ¢ÀOñ°|‡=Öàp8øÞÌuK·ZºGãJËÖånkÃ'Ý,G¡*Ô(JR–†j6÷³L¥¡Ç 6Æ™jìh=úfyrÆ,„HðØƒ«ò´\~½øö"^ó™8rž,(nü­þƒÇ"Œ;Aî”!ì~»7c÷&;}Ê KÄJTfkŸù3w‡?ŠóÆ/Õrƒèà?|§èU¯y½kêmº£ï$Ø›ˆ¥û™Vßî¾é6¦Sf·ó k+ð2M«°MAI!ªîì}QUEuOWp0¦‘?OÔ4ôÃ)ùYõáý‡›é»÷½iŒÛT}÷ÅæÝDµû|£L«ÆË›^ŽÕºn”Q-ínSË¥TÙoïlãóÑpBØ{!öƒä„™\€ó$dÓ€dU¢”=þkƒøóů R8ç ÕUy„öÛzõ$VÉ)V¡¸O5Zq¬È%¡~‰@øs­Þljn-\\ËÚ‰ÔŽu¹rÏ ÞrK ßLw†ž"]­Ü¢á êå'ˆBÞØ¶kмká.³_ È™þÙ@Œvò}kWê°±•ªjÕ<ºþäpðNè¼#øçTÙ{ | ¹õR9únúbmYŸ{y&o®jË’UÝ ^U´µãl![<ªèÑ@M¹äc˜Ï‹Î#¤"Wóggæ{y¿Œœ®ž¸Û5;]³Ô×êD­r8'&Ó¼ÐsêÏçÏæPe¢ùdÀ «Ê’ň(æ“ Nê`¾ïÔƒ¢$°ª%~7üFòOþr˜Ö^ËmM"’Ch&¸?0îÝyâÙr%͉O®d¿š-jŶfésÀÂè#þûàJêÎgTÓÒíj‡y€ò'Ö¨0ê¿ü/u`,5˜š_}¨˜•  D¤Ývö\ÊuD-P,D¢RwŽŒ¥zô¨*À½Lgûþ!æþÁ‘ÚN>¤.A¨ð)à²èII»$5 Œ\Â7ëj¢þ+.}q!r#Ä!oñoÆìC™Èn„ÇŒ@É +4HVÞYÔ9Þ¿Ú ÈršH¸Ær²m¼ˆÑ‹¥ê÷ÒË“%ð%`2%‹Ú£¹!!: ^¾ØÉ/ Z¨a„;¾,þaÕÇþ?»AÚi*‚"Ê^â•HSñ5(¼”LI!óIõkuTã>1é‚«e4‰XwK\¶ÐŸäçÍGùõe”RòD9žH ÷bi–È!Ž Èm$ ߢU5•{,¶[»*LGý,E;’[y% æÄêþJˆRñlãžù¿Wyf7íÜú¤£?U¯ëý‰üwŽñM'4ÚWh×ñð›ú€ðVÒ…%ñ\,Ÿ(ç­õ-FÓzí«o™ –. 1‘=@‡ .賓Sw4þñ帿F0v¤Î äŒ!nu÷©¤×ëV¯‹¦í&ª4ôw[¬Vt Ê'÷å3½öfºø:Qí~½.¾R¥¸š’G„É’Ã-ëáFƒ-nÆ€ã Eº„°P¬Yé‚\4ùFœ8ÇaWL6ƒQ¹—õGQK-tß¾kΩ ”À¶}­:Ù¸—†‹Ó/á©E«‚%+ë4’Ö—=Ú'd(Å™F&}j‘&U…ÑBNþ[-"˜êÆÀÄ̪‹Ç®Þž¹Gwò”$˜h€íÄÐj\ʶó[7V|¯Û¯;¨ufÔªdh@¸³×‡ªKDq_TmgÍŠçTUí·w`ošJι}S D}×}öØzÂ,£ì4XuÇ%᛫|6¤]èÒί¸Šuó×wo–üx#ÃØInê<<žGsÝøJ> ÿƺp‡ Ô©œ°€nVö†¨ÙþÆšüµGÙß¡ôR±F­s…XvÕ¥ñàÒX,9ézÀìXç˜)®½ÏºbËyˆ*YèMŸÌˆ‡:ÓÖ«]Ýò ðãÄó)¯×FЊàY6‡Aì†Toå‡CúÈxiÿ²) Õ¸tÒ€»‡/[Ù†ÜRsA³IR_ªûòŒâ¸øÓ7°á®¹îº¡ª®ª£Öûn·19Û•è“^t<ë½~ („ÊÔéÚ¢rò¨²ÈSIá3÷å'ê“ওÔaË.b2ºŠÚKΓÚç}½í›³’’õA:bZº¬†]–ØŒxÄ!öo¤wB€93—°ÕÀ”[ª÷‰”Ï.×§Oêîÿ¿AŽÎJ«E»c:°Ò£³RòYð è¤˸ l´uÇ™´GøeºŽú¤4×^GnÈå>w1/ÓZ>£ÒŒFwN嘙£¸‘ gä@óÚ«m7q$ˆ¾ç+,žÌб0vŒ™—™ EZ%Ò,o“Xã ò%,û!û½{ªªí6Æ0i^ ¡ÛåêêS§ÎðPö.ëFµkcH€œã©ÅF*ߺ½Ö;Wý Äw\ŸM‡Aqy§¼ |œ°$>—O•h#ðÓx'è‡fFFÄÓËxb  ‚R%_qþ‚¸›3\þî?.Ï_ȶxæ#ç¿ø› FnDɘüG”yâ;q€¢†E"¥Q#ÐmÉÃ6Û;n'‹ra–³ä€Âĸh·M†å‚¦I›iRô+»Íì"˜¥bÛÄ%a8uÑŽŸØ‡ÌŇò¡G0;XÓ¨w4ïªå;z%§ÆÊ­×丹þ¦53'éÖaÜ_US–{"^¡]×D¿<"˜CÂbÐe©Àó,Ì ;¨×RôKH÷JE7äþŒ÷ê<¯QIMóéÆ+÷DÑ.òoÊ´½†ŠÖɆÇ9j›µgÚk¹kcmt‚µP$NB¢†’±¨Â÷N£ª¨£Añï¢;ç¶Èë=J‘lú|çxºæÎ\°|e¯³é\Ìh¦ÑD KØQ‹Õ`“Wd–ØÝ¼u+“Ô•„n«—ÄÙ·Ž˜ÀOÛ¨"ÕÚwy_M9-ÅÊ%Öz]Ú\Ú«8JËøS‹pdIÖ‹Ri¼ÝUµ ÀDš¤s)` ×á|ÆŠz÷Í<ËÇå_ Æá Þ´Š+¤²Š`¶<2Qé1ë"2µøÂ)×u‚;É‹m˜Å%w&%Éw§Kè ùÜaØè3.'Æ—ØÜó_j)«x¦ßŸQ7·â`»iTOàp´ž¿<Ü¥ÇçCvŸ§{È.Ú½XÞè+0 ïó@¡ŽzÇŸEtóúÝEßo]›{½³|;õ­™{éáë«ú½®Z³gVà=:°úiycϘ"ð@êúèMïÖò]êƒôÆü¤*±¸òcTœÖÁ›1e çsq‘ê ‹—ë0üðõUõÞ9¸¾=ªcM{Ï^XþrLÀý endstream endobj 817 0 obj << /Type /Page /Parent 1712 0 R /Resources 819 0 R /Contents 820 0 R /Annots [ 818 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 818 0 obj << /Dest [ 795 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 376 132 406 146 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 819 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 820 0 obj << /Length 3260 /Filter /FlateDecode >> stream H‰´WÛŽÛÈE^õ ½¤ŒhÞ/ƒ{ì5f±Ø ÖÚYO8RK¢—" ’EþüCþ19UÝ$%&ã kØÐH}­®:uêÔÛùäÕ|î WÌW×þáO$¶“8‘ˆÓÐŽÇóíäÕm›ˆEËkÑ.ÊÉ«]±n'Ží8´f1™õ_÷“OòÏ™5óí@®ýõ$NÖßçßOR>!±c§nñ;rô%|€ÇgÑ·0ÒGýËÃèÌs¬™ëÛ‘tñpe·Áˆ'•…“d›·â͇+ñë¿­Yˆß æB;”¹åÈÅæJ|ÜçÝÕ|ˆ/³riÍR)þÉŸl?ŸŸæ9v„ówc öû½mù¶+[ºUѵ8WÚøêàu 3´á“ÞÏ'®ÈÅÄ #Û\áÇv’ˆÈµƒ@àA"5YMÞÎgø.–8§Þ]íG`åüóäÕwîy¼ÒÔö8\œè½ò­=¿›ÿðþZmë¢:(E{aVŠ8®ˆc!lÊ‘A/Î&É0¸Þv<:‰íÏnaz¸›}Ï“ðho¾8 O^ðGŒþxcüñPµí™/‚À£gíyv–}¡gÿ‹/.oaº¿;Œí(è_ë“×Nw?3ÿör^#­“€üâû6°¢ý r°ÝÆ ^ç°Û§ }£˜o”X7Õ®^åªXŠ­Zl²2o·b›ý¦ZÑî%ºMÖ‰ù5‹(ð5g’ ©&~ú™²Ò•`a­º¼Ë«²û¼(¬„Ö<(ÑvU£–"/qê3’ìò9ÉodOÛÕf[ut$v/Õ?Ľ̚&;ˆºjÍðŠ-ì= ‘ÁêmV׸¶«ïiï-‘-U³ÌË5â †¸£!ÆA°9o´‹D—­¯„zT|oµ°"Öb×ÐÕ®›¥jú§æå¢ÚÒäãmÖ,m}#˜@1"ˆùI,ôÏž<£Ð±cïˆ=p!bðà7RÜjþ݇HCÂH¦¤]}Ùl«²Ò¨-(=re­—r×p×àQ×`27¤Y¿NK4Ð×yJo Ïoh¼•) üTƒ¨w­®×Ô=È]Ë,‰É×ýåýÏ$ñ=ùÑ¢èÈ»Ÿ~<À+a8´Eþ›Ò]"éâKÜÛ¬På’x6ÕìÈæI¦ô‚2çhÛùß2Åu‡$K’ugŠ9¢‚¡uìåXŸÜÔOÁu`b¼Ò%ÌÁ3#i  ~ÞµPDU}¸·ìaWV@{uÇ‚l¥ã‚²2úbâ³ÄŽG¤ÆCœ-Šð¡¡>eQ"ë?µeJ98‹ñ‰úº<ElÇÁKÙ  ¾¥Òqú”RÏ7¾ŠqMPØ ×)G8–Ó+æÕ€ ¯ÐZΉ¬móu©I•˵iÎ2{¶Ç¸6 O+¾;6šnßh" )sG¨EWjxV‰þ© ¹+è:s?ëOŠ‘'×eߣ™b„Ø,é a?HÓ¼*Q˜Ëº§5Õ·£ôÅšŠ²~Ë{4Ù}9ÝDÕRoŒ¬Ç‘•SqÍ7ÒQŽhåĉƒÜ>îp ~T{–Š€„Âu¯„úýÁX«@cR9&©þŠàA¡”‚‘°×Q —‚ÛžLtЕÈúm­ÑB‹byEâ6ÔüÝóù?4ZQÝá˜üŽÉs/ù»sH×m^’j¨Vܱ‘E”Ϊ3N °:2ì^R[…ÿK^b9kÄü×ÚAIVB*`^­IÛ‹šö‚š`7L—Ù¡ §»ŒPW®7Ý÷’³©ð^TZZìÑ DòÞbÍqÅ +/:I‹Dê$ G½©Í/³ ìø‰â ‰Døñ–9ŽÞ¦o yƒ*/ à mü³Íº–jähéë"„ð¡n¡} ÎqÇcôª…]4˜Wf[²È§‡PCËÁG ~™ß~mçPénHjõ€ãÕ z„JªÍš%T~¸e‚%yÙ©µ2?Ÿ´l÷}oUŸôXæÓpñ›À¿è6òVü/=%¡ÔŽý—HÈýøß’„´Ÿ%a7`OOñOŠŒá«é9ý8vrDXn0¦GÀO2죙;OˆÇxà“¼³ ‡}Y²¤ìL¦²Ü«xH+@1H)Â’i´ÌÞL ïÞüí‡ÿÐ^6; QÞû6–… ma ‰šˆ`bÜHb" ƒ€qlk§eáƒø¼Þ;wÚéµþ¤Ë6C™9óÝ{ÎU?ÄdïYsß³˜_›ò¦Möø€Ó]ªæ³­6¸ *\.s¾Á°Pþµ.ˆuM°ÒÿÐ]CÈÌ bBáXPëFœ¡¥+æT2ÕPðÞ “ë(YœîwìKXoO ùìzz{?ÃLq Ú'¦,èFˆÊ«« ŸE oæ‹%®éŸqÐÿ­¯Âë3Û£ÖQǃý¸¦%í¥b[ýwþðªÀ0e¥o> endobj 822 0 obj << /Dest [ 1283 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 131 532 173 546 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 823 0 obj << /Dest [ 827 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 440 463 470 477 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 824 0 obj << /Dest [ 927 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 503 171 525 185 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 825 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 826 0 obj << /Length 4100 /Filter /FlateDecode >> stream H‰´WÛ’ÛÆ­¼ò+¦ø4HHw‚*¯ªV^J‘-Y*‰Iìhó€%‡KØ ÁÀåÒ’È?æ!§»¹¤JŽJª%03è™î>}úÌËiïÙt(_M=?Pþá'JS×K½DƱ›¤^¨¦«Þ³ïëTÍj^ã©z¶î={ýÉW÷uÏs=ÖÌzÃöq×û¬?dÎ0t#}oè7Ð*õ”ó¯é½1[«‘çŽì¦nâÉ&l `[ô'bê?F‡ç ýÐM´—ª»½ú´_7KŒÚ8°¤ë¼VׯêŸÿu†1Þ+ÌÅn¬sÇÓ³å@}ÚåÍï¦*ØH¨³õÜ޵ú7ÿ僱ûìZ๠^¦7ãìv;× ]_×´«¡ma[ºxôàÝÌ-ÙÒdÚóU®zAœ¸aâ«p䦩J|7Š|ŒRU™Þ¢÷rzFèc‰w.ÔE§œþÚ{öê,_c_9ŠÇ”7þVÿIG²{Z‡¬•.í®Ù™¾Ißø2Ãiñc:ÄgÝä+S#ĺq|­6ìpg/rc9úÆ?À‚)’ýçê•CY,„YŠð<ƒÅØMµBlU¹m6ÛF5¥º3*S²Í6N€µØRÝêyÖõž¼uÊ<8cäܬU¾€õ±XãÈV€dܾœÌ¬gf.FîØWCßõÃÖoÔ!{D.èEnйÚ2E§–ëb¯xеôm,Æn`4,=É"¡gЖAÂIø¿çMJS?dÅÖ4û95¹^ÐåËëòåuùš.á,û[oÌ,Ï 5+×NJá¬ê¼\«U976aÛÁD©-Õ߯ßþm¢6<Œ4“A¢«ÌAEè•ið¥*‡°Gá“°ÝI9I]®ŒÚTåÆTMnj€À¸÷.çàá@r€“ßg…AsiòÖ±®TàŒ5Õ«ön·…m›«H¿¬C´†²êä¤~wRßž”>b€ÇŒ´‘> xÌ(Šåu@ˆ° [ÐŽš¡^˜“WF*-©Á3Á!›±…2”×…¸¾WœöªÁñé4†SgÊ—b Ilw¦¶L¬EsØÄÒ$ùü;ÿc‹™)²è7ñï;'Ö“¾¸ laÆì’–1~<Œ‘“rZ%Ót¸u– ·•‡@pñ=d|höÔ±a´~‚¤ù±Á^Úmd|‹$ÖE6Ý¿¹–ÓOú2;=ëï{lXíòšÝnÍ…Q™zËÆ•Ymš½Ú-óÙRͲ­ä‡ÂŠ4Öj]¶å’UW‡ãRR£Þ5\ß6Ü-<Ðf>°›Ìͺl 6?°¡æbÊtÊ 9«tÏ/VDG_‰;â‚F߆¾ü„é‹òýÔBê­Ó|d@Ü@T ŸÂ[ÆHVwì}Ú?T6k¶W¯%6¶§ úÜ9@2}•ôƒ±Fß’ôýˆ£–m›ò;/ÈN—@ ¢HZr ,ÆœãHËóDº·,»qˆ;dú£¨"êÔêІÅüðiãvéê²¥WÙºQ¨•ÀòT{Æt×ø %îøÛ²Px`!$㜈PÑ&¢Ï&’Êpâm"¥öNw‰•.¨–Où*/2ÒÔwû–;ß꓾h‹e¹3",ÚŽ`çÔH±%¤Ñxª¢Ó7sþüpçÀR¸~ÊDçÝ=ë:¹9íÞà» |ñßö,©œ¶"H’lW©6y ŠðaižíJ¼ú®Í‘<ÒjLN¡;Q•¸¥,1òóâ„F.0ü­ª6F‘AÔNzë8ÞÎÑ&àv0\iÔñ¸h)œ‰K¬£”ø)¥€\íÄÀRá[Ô®f.![kóØßPÿçšêP$ÔžˆW—y#L²íï–˜ãòjÛ‚ PØÇö»ÉOô|stSáásy…ÑÓ;U(Éo)ª¤0ïòf•mžŠïXV·Dºr7YrÏj¯9¼Â·yØðšîÒxùæÁ×ǧmÐm̽ýàôÒc7áVr?ÚØ7Y`ÀŽ™ZoWw­)¸Ð‚.ó‚Û°¥VÏÖ"»¯ÕÝžÀ“W8Ï<Èç$ S2†èÕ®zÓXÇHÄu{h»+½–8C‘× Ývñ‰™®ÕðâãB_&™G”{a/s3CkO8(>:A¡r©þ5wP9…tcŸµíˆŠ# =±4Ï•÷(Ãô7Õ(Î]^$*³©lFúvßðÚH õ/ùGÒxg¥îBŸ,Šwf(iew²ŠÚel¥V´¢ý}À2ŸÖÉÇ{ùHm­÷WT$H9ùu»ž5t ÛªYªï ¢ÿš¢J™¨P×nLRJîV­,Û`\¾ vâÙÉŠ¢Ü)Ö&_ß«1£ë'– :mò9nkM¾ÈIð&D/IßTÃ)m)œùd¯–Ù\| ®ô‹)+²†6»¨•Î;Ý?Þüñ Šè¯ïß¡MÒ¤WþàÝ9¯¾ Pmׯe‚5J¬¯Â-~ÿ’»Ù¦Ö·HC¨'W‘@2»+¬:µX¥·XÚ ÐõÕ®ÜÊ© ‡fæ—cÚÁß³ðŸ•@¹)$HÅ¥êÃgHRéGÆ$˜Ÿ¬¾{ÿ’Ã6Öo'}R|è¸è%êŠsê=z ¡˜«#ƒHµyYkž÷bäVõýAÐg«ÒmÄ3ö+„_¶ßBÝv_êžDJ} ¦xø`8[2"s>Ë,Ç–¤Î/IJï1z리ŒšþòaaÑT9®¦&ˆ2o5Î0º¥ëLa6ËrmZ²#ŠZe9Ñ#žÍçˆpmê³ÎDn4þš6 Åñ·§ì¹^mI'åO›`šüaazÐ¥®/_žhѰûò‚~’ˬ\[[Óþf†½Ú@ˆV¤?¤ýÈd.ÜÜöÔ| Í6'fàëUh-¢Ù‚íÔµÓ'õ×!¾í†Ä£Y‘ƒ}€„¾è†¾Ü9™,çó\–Øk s`­Xl<øÒ.Õ¢*W8i°¸¡¾V!Pª’ʼn²Lº“$-»’§!¤‚G`+oÌ´yc*ôAnz2Œ€ýh,oÈÉ7x}À ]¤GãT¯å+iB!+À±„?dÃ×Jûj7¶ òu…\P‡~´~ë(¥KÄræ6Y•­LCÍ¡øíUûÛ¦‡¿ï¯8ñ¥XŠÑÀÁ˜hÚ‡v™)Zª´Ó*5Ò„ís‚B9Ï7þïûü^0œ¥Ýº(²áî8¿—ç%´¢p8f®†˜xËݶ(¨£Uä>ˆ×ͤ!·¦ƒ‹\ ò—ÆV‹ÀÌem-3ÐFÅÖ™E½¸ÍgвÂ9Šln‹¦ Å[5Þ‡ñ›ZƱìšVŸðçINQWŒ_¿ gþé ÞíKeÛ¸)úñ­]÷ÞibkOvlÇTl‡Š%zéˆJžˆå>ßúxÜœ¼GIOþ…"ÇLÇá2îÿIŒb—kôÒ€‹JfÕH£ÚÚ$brá6\¯Z®W¸:3 Ž)ÐËÉ6N¦ÏŽÈ$ö©&œ èY®¸¶·INµp­ØÀäŒ Hfõ–8[‘O”×V ËàŠyŒDú}È <⋌0k\Ñ·1ÂqNÐy? `Öjá¸B¹B£Ã´ð$-–œ#bl'ì+¹âKÇ|.|ïšgöôG‰ä9d“ÔÑÔ³LêX" «ß¨y¬I}kê”Ïž2]Léò%ƒNVþ´õôžD…¨†¨¹9š)xD¦éeÏO&®u¿”Ä0 @§ÿ¥‘Æm'u¡ó 2Éáw …È]®%»Æj+ôh0ÕÁÀ“%ÐÖv…ÞYⳄÚ9zù\mmE ôа‹wÒÞ²¼Êw–{Âõs=Û‰Kåqoi.| …µ 6§²˜ˆø‹¥²¨;_•`‹Wšø˜H £ðQó|¥ýw¦æO6¯ñb‰ö`~ù¤h`»7œ|t.Q9ÉÑJò4u$-Ì%òž÷–_cñ¢HúMü'±EÒP(ãˆË.ò ñ‰`§ÿƒ¤íþN…}e(zo³© Ûß"íè°“NÍ'4â?ØLíîšgí"Ϻòm¦µQoz³{“–ýkÉÏ,³¹½ýãú]µû’šI}hïlΦ‹4ž+!ƨjYæu’-´i 5M2Q™I¯É¯à'Í<“ +ãKìl¼Ý"ã_JšáG…1ž‡‹ñ6£˜³IŸ5Ÿ¼°¿«ˆ+S²qÎõؼ¶Ìè®×ùѽIú0ŠüL.;#hò'5©X4]$Ÿ²¾µÇŠ3mk7• `#là{é*MäTô6ðñ¾Pà4,E Plda¥˜dznŒèèˆÛ™U–l¡¬ê*î÷f’ww‹ÇÀ¼ƒ¦ ¹i~ ¦_«'©‚–¶B]l™`=×Ù‚ñÿÙS‚ þ¼pó¿æÓóÝJ:mµuÚJy·‚ôÝrИg 3‘O"Û®7«„³¸º"†°;¿–55+{v+™yÍC`\ÿF.ïFÒXø ‚#㉿Ö;™³åh›*ÇKUM^Ž›Šœ‡l(„Å8÷"iIå™+¶²"ˆIÐÙœêTû¬Ø-ÔÉÅ@${ÓE"/úv¥ÿõ Ïã—nð|‡úbÍ3féÿ›¤ì˜UPYQWK€„%ÀD$@¢ ‘@Ag²´â>˜ùHâPLÃp>ãˆ.ßÿðežÄÇâ endstream endobj 827 0 obj << /Type /Page /Parent 1713 0 R /Resources 829 0 R /Contents 830 0 R /Annots [ 828 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 828 0 obj << /Dest [ 827 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 167 686 197 700 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 829 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 830 0 obj << /Length 3228 /Filter /FlateDecode >> stream H‰¬WÝnãºFoý¬oJ–"ê_‹M€üív{rÎÄ.NÚM±Pd:Ö©,¹’¼^÷Aú}Ç^t†¤dY¡’¶hX¤†C~óÍpftµ˜œ-ad±š0‡Øð/Š,;²ƾD¶K›ÉÙu‘´klR§Åäì㜑çzb[¶kÒ‰Ù÷“/ôçÄ0]ˣϟ%#Æ_˜Äb‡˜„¶pŠY-8b/ùÜꟼ5Û0™kÔŽÈÓÌE³†7åìDë¬&—gäÏÿ2LæÈ|˧™aÓt=#ó}ÖüW¹ØÄ¥I±4̘’ˆ_L˜/Lsl+€ÉâÞ ûýÞ2\‹ÑOåx,l GZ0´ÁºT½Z‹nF22qüÀrFÜЊ"0ËóØèE¤â“ÕäjÑ‘á2XbŸ²q¤ÚFFåâ×ÉÙ‡þw "C?F¿ ]ú¹Ø“‹áLeÚåèvËö”dª$Q§Ã¤Dú5 ò¬àõp‹8RlÁ:t¡À”ÿ¦äIËÍSV SN¾%ùÇ.…Í€#Š•£Fð\V†¬x&X¸sNÒuR%iëwÒÁa^1ïȘ'“lIžC¬cˆC yð@† "7J¡éÀc›Hi‚S6|‰ê°N-ÛÌ )O3¢×£+XìàM1,EÜR=5µ¦ \1÷h8;R &ZÂDÓ«œŽzÉž}ÔVí•æ.ÀÙ!ÜéßD@DK1Ëór/‚à{²Ù怖¢ bu¹—#Ò”d'§\˜9Ýìò&Ûdß§dS.9É I“•2 a-WoÑ^_²çS ¨«Ôp4 m÷éΗ&¼çÅns!{¤5ç„ÙF ÇX®O‡ú¬é£a‘e%£ºá9ß®Kpt±3DÙ<ñ Á.nï¾þôǯnï ‘ÍIRUÉa&àö uœÚÇ ²Uáî.?Ρ|Y“„mcŠÒùôÀkõ¢9laa‡|zöfŽÃÔÈ´0m-‰×·P¹äð—Ï÷?¨!V2äyò¬èƒ´#X†ûôª·ÔE®lO”O5²ÕÖL=QŸѸ±™ÎXŸ½éQä_÷HV4ü™WÀGÃ(DLÑs´þH:b±¸ËɧùÄ’¡ð•ò™-yÑd«ƒœY*õ¤éÚ€"åŠü]‘ýmÇóÃ(ç¾ýŠA/e:ƒ\÷MΡËù_÷Ø8@Lr£ŽqÙõȱèiä°n*hòê¯to²çµJóëä¥ÕuÆQkd:ÔÌ“VÙνά4GC¬ãŽCÔÈZ5æ«id=ËÚ ëÅagµ, Ëq—ýJÝÐÈ”š'tL‡+½²5Ñé§BL Äñ_‚|€0 w<áédZ ,x zsÄÑqÆS¨N¦b‡Ú([UmEëšä¶‰¨¡c8íÑÌù¡À6ïùêAÅäƒ 5tÔ^0l£†¼-”ð»ÇÆÓ·Nvb\ ³‘÷ûþ<ƒD”ämÓހξ^eÄÌölUse.R3¸<ô\õ(Æèu²_)/™Îgnëƒgíóùt[ñU—¤d< tZ̺{[n<^Œt2=Nýƒ&¶úm“&¼®E‡u‡‹Ìü©Ã¡rf`mt½Zn4^çt2mh…ìÿZÎZ²O.7/‘:™Ökó_GWß?§Áåhƒ+/:™®’»þ±<Ò÷g⸋ÓÐ ÆK—N¦=ÆÓ÷üIšòm§EÛÛõ>fËÕ ãWm`ÆëY/6»@Ùœ†ŽhÂ{ÁSºÜ/‹:™ÖH÷¤,nË:k ãí¥ â[ž@ï& NÛÏšB6pšºézãuS'Ó´—®ôÞµ—CÇ»ã…Q'Óôð. ONR=üð (Dv¤6¿ýO‰q©tR,ÔÁ‰¼CªWCÜžíôJ$øÙjÈŠ³ÅÂ#Œ,Vø ³= Å³\7 ‰œÊOŒ€8¡;Á `ηmÛ'‹t"F@Û" ö[Èò(‰äâá…˜ï6\<á¶ÀE¤I×DÜᚈ°‘á×À£;Ù‹¬À–¾'³ö`&Ͻ.‹&Ö|I²âæ…´ÛÖ‘Ûb‡m7BÑqÄR]}D u1Dc =Ä좮4<ê €¤ ©!Ï÷ß8_™€Ú´(›uV< 5ÝÁNw08´¾ÐKÃô˦©²§]Ãkœ2Š'CNëdÞì£Ç¬>Þ0t˜´)!Éånì#zÛ>íücö´Xg5i’g€à§š$=ûfÀE§È>Ù&Ye‘Ë Ð\Ei æ Ä0+¢Ïà¢ZË·^-«mQ”þÉE«TÆ’¬GMè* x‘MÖÙȶR9È$Lÿ¾ç>Æ’íÐn ÆzÌÌ}œ{î™QÁåÝÍjswlªSq…%?ÅÝëø~$ÔÖÉc9ËáLá3›9Ô#6vΜú{Êœ§SwØut:ô=áœߟ:ß~$ýbôÆfÀ;F²v³!ùô´yzHî7Ï´mÌBœän/a6³`næ„g6ši˜go?Ç÷xLZ†)wÑpà²ðrðô¯pOŽNg­ÞòÅþT“íš6 ¯ºâÌ¢NÖ„dµNÕûvW¸$ÎñpgÐág¤ Dhܾµ;OÈw×…ØTÄ„@é*© úª`éŒZÆ-l¼9A™•5ßÅó( œ®›.]Da¶ï¸±L ][Yk.+/nì­æŽÊè³GN¥ÄK×jÍØ_³|V ¦ºÂçš{*½àä°ÿ²ÀË©ÀK+°Qfß0n…óvÝÚõMŠV²§äÏðŸpª¿_âÅ-xÿèØ[†8]3+ÒD¡¾O8»¤|ÿ Âü!GBÓ$^´6-z4)} vœUW1}ñ{\…i+S,TÑ ¤ºAñHt©—X“êH2 ¼HÛ¥4ƒYXª˜FkyÂ'IÓèþA|¶®»jh¼R›ëØ‹‹ÐCêIV-rɽ”Ñÿ™±ªÁužYöWÕç¼Q¤Âu1ïÈÒH,\¯±Ð·z1T@ø?‚˜Øh¯ÔÝ:›$wü)FgûFU¯PIªhzú?ŸUgFXÂþ¦=Oo endstream endobj 831 0 obj << /Type /Page /Parent 1713 0 R /Resources 834 0 R /Contents 835 0 R /Annots [ 832 0 R 833 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 832 0 obj << /Dest [ 842 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 467 742 497 756 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 833 0 obj << /Dest [ 817 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 346 488 376 502 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 834 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 835 0 obj << /Length 2921 /Filter /FlateDecode >> stream H‰ÌWënÛÈFÿê)ú5,$šÃ;Ä€ãhYd½A¬,ŠnŠ‚–F6»)P”÷Aú}ÇþèwÎð"Kb²@m7 ‹ä™9óÍ9ß¹½™.æsW(1_”+üÃǶ;¡ˆ’ÀcÇóõèâf‹Å–×8b»(Fßß)ñ°9¶ãКÅhÚ>îG¿È©5õl_>húu¥ˆ]aýeþÃ(a ‰ˆ; qŠÛ¡ca.뢧 4ªþéâëÔu¬©òìP:±¸wÏEýˆ/®Ô4Ém¶×ßOÄŸÿeM¼Wv 3Ë‘‹Ç‰¸Ûgõßu•³O¦ÅÒš&Rüƒÿ20¾>_Íuì/ó·øÆöû½my¶’[:UÓ±P#m<:¸Ý¢ùôÈšfó‘™¹Ah{¡^dDZ•íûwôcQéÑjôfÞÃSXâ¼´Foj‡,”ó¿.¾;ñWäCFAB~ã½òf±oãÌæB–Þí¶ã7’q#‰»=ÊHØ-Š0ü"7åÖšúÆ®0c•Ešó¥{¾­¢Æ|Dˆ¨çFdÌ9¾óGø ÿ§…(ÉK5ÊÄ}YæßÓº®²û]­…¥¹Ìbï÷–RpúÔµc)v[½u)ô—En%v$wK-ÊJdÅ"§ÇÔø– Çbªl嵸TKT ]Yt³:Í ñ”æ; …ºpÜ.¶V@èh,å œZ« ËÒZ,Ê¢6ºJKÁJùÁîڢͥ§ZEIÑõ;Ë´NÅgÙœ¨ÅX<;¶ì–­t·³²Û[Ù5÷¹-«ušçÏœKZ/ñ·¬É\÷€³Ñ‹l•éåDÀÈôñ1}ÒVH·x¥‹ÝúJäÙ¶Þ ΣXg_ôÒb®â¬ñÕ”ΰNÐC DN.¦;Ñ&ð™'EVÏ ¢³i·ÔR-_#;ºØ\˜= ©B Ê ™Ù¿{0˜%×åR¿ÔàÚ^ÜS_pLõÔ‡Ocd ¤™mù…¹F„Ò¾1ÆÎH ÃÍó†·‘À“D>}y,$ã) +“ÁlÏi~Íî’×çy¹o>–DÔ¥6â””‡r—×¢Åi‚ɵ£ä¥Ï]·sîXc{„ LÜ…%ÅÌJdž¥P8tæ×K£¸ó 3Ê:/ÿf:„ì·xÐd%YWi±¨#7¢Ì¸,î wn„•R2 Y—h"ø[mB]*8°Þk+Â59cD²EjEr¬„xh3L€ ƒÿ^%Ì{Pýw·„b×Éæ:Eº>²E@z[ø½-üÎûG]t·ÏбªÊuâÄ]Òº“Ä:­´ `8_î,¢«¦z°*w2’áY`ûîQnIúãs<1–bÇ7f9g†¬3”-uÉ9鯹j¨Ië‘Zˆ˜BŒ!šìËY\›ˆRÖ^‰=üˆhµ¦”Ò!œþzl%2S ´Á•Ð5æªõYfÊÂDp µŒï8ÿãùbÔd`ý Lš@í0?ÆÇÖåC©Ø¤æáE™ZŠæ«¹!%ó’Ò}S€ #ÌÑ%¥”™»úrMíà¿ÃDg-ù~ÇTTþOKÞ‘n|YX_/HÉT$N6è„”m (JOéèõl4窶WmýÆlÔ[“3Á9j~cÉÌ«¾%Ì·§FDN,W=ãÀµÌŠAºŽe´.a«˜d¬e«r©’;=6ïÈâFÊI·ûÏ©ÆÌù,3´ü¦™©U2{(Êê¤|GßJûÙ =¥¹$ÚÌ6¡3{4·³¯^¤|²,·¯YçÏÌ"<×ÀP`O¨Ú›ïyN•߀똇ì~£{Ílm‹6­_ŒÙ)åD” tÑ4¹©ÁW£·8L!z½©Ÿÿw®Q!»fSéUöåØ5þa쇽oÂÎ7Ôçâh(÷eõkóh~8uûrå)O€®¬( Œ¹hñ ªÛðÄc¹×OB B›FÃ¥ëŒ&¦±hÏK7›M« z¯ä- %‚l)‹ü¹s㑯¿†×'{ý%£&3pU)¶Á9C¾-†#,hˆg‹w+±-M¸Vzf‰K4Û›µi¥_f‚Óö÷ÐØÉ 'íD oƦû£Ñ%”MŸÊ%»x°ÅuÛZH!éz“ëK¦TÊ‘+ðß‚[ͦ}=nº]cSJaܯÂâ Q@­'îùzü†WŒ _ÏÎ>ªïITÓ“Á9#lùÓ”›Ù7°Ÿbؾ¬owë{„Déøy·ÜåK“±FFrË8ØKEÌDžhrù*c&—YêŽEiV°ŽsÓiWó†{…¶á0§L=?[Í$6ïÜLfl¶ꊮLŸ‘ÚBÜñWmÚž }”´ª÷•‘›AÇ$&öÎϘQ320»ù¨4CňHé­kT« ãX”ÅS#¥ÃšfÊ“"Úßä0780ÎшwìøSÏZ ~2ÌJ¹q{0%²iðÙæécvòÈk¸Nfî0‡ôŽp¸3³Ûµùùtw<·µê¾¹~ÏO³Û·×EV@Ž<ëûã/Ôº*0¼Á¶ºÊˆg8e«‹šsÎå‰%ŽŒtñjÇY“¶Z…:¿©Ê®jÌŒ¡ã4!r7¿žº_1´Ù|{¶+á»ØŒÈö1…ðßJVß–a'õ]Øå…R4Ó9?Êñl/Dåð’ZÉðk²é9Ù<«LçË×ãÛO?Î>¾»ùë´™íatý#0çÅ/±(d)Æ£b»?ËAë7ìÆ›Ÿ~üð~6?1Wt—Bþšäçq¹qDÉË4×ûÙ÷×§¸âS\n‘ q ÉÏçR7Âôé\òÕ{EéàÀا¢5|à€üÅ1ç#œ:ØÔ×V·ã#‘’Áj2,¥JÖH‡+ÙÀöoˆÛ³#‡.8XɆä0Æ¢fèÂwJ·s‘0¯Øh,¤úê6í› ~jú%n C+F #^mÒ ª¹mÖÕÕ%šA~6†ók³ÍS%–è‹ } «hZœ~¾ë½ÖbRqb{î&ÕBjÝ”ht²3HV\¢osº¶¿CDB? ºªë€¸Ëá^–0óCF,”ÏWÇЦ¬¤ë¢Œ}âÎ>qƒmÛ 2`‚o€1½| Æ4Ô‚^M^mÊ-Yªø ¯ƒ¢xÂýE^£xÑÈ‚ŽZÌ-½*IX ž_ÇÒFÎÁ`4!¯¥hÌ'b‹qw"Úu4¬€—æú\”…^oê³]9ƒ@½ ;éÂ&¨uá)\¸ì†()Ò6…¦éíý3‰Ú!LÉÌð)ÿ%výîÖ¶1Ϧ6ót¬7Ûztc<ùaª"³­EºÁ¥¸F!ó8=“«Ÿ{G6x\  p ~{h+Ã#RÏûì¬Bžm{·ðéÁtŸL¸ô³´Œz`  xñÒ]3i¤p” ¬ý(Â2€£‹’’؆©€sq1úËŠÖŒ‚Xæ¨TÝÎor@„ØU7,›ZF­‹‚H³üg2úb³ÿªÊ`T­ýÇ^Ô¨.t3C:aî…ƒ¾‰)ÆÄ`æD8Nã5ÁŒN…¦1æ"Ò‹ò`âJÛ endstream endobj 836 0 obj << /Type /Page /Parent 1713 0 R /Resources 840 0 R /Contents 841 0 R /Annots [ 837 0 R 838 0 R 839 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 837 0 obj << /Dest [ 842 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 116 659 145 673 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 838 0 obj << /Dest [ 922 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 227 547 263 561 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 839 0 obj << /Dest [ 874 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 284 547 313 561 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 840 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 841 0 obj << /Length 3330 /Filter /FlateDecode >> stream H‰´WínÛÈEÿê)úÓaaÑü”(o6@>´[w“n(ÒºXÐäÈâ†"’²V}¾Cß±?zî½CQ–Æ P$09£áÌý8÷Ü3¯—£Ëå2P¾Z®F~ <üÃ#J×K¼©šÍcwšx¡ZnF—oÚDe-¯ñT›U£Ë?ùê®y®çÑšl4é_÷£¿é©3 ÝHßzZ%¡rþ¾üÓhÎ;ÌÕÌsçSœ&îÔ“Cxƒ€÷¢·x*[ý+Àì$𜉺Sí%êö >ªn™@;é¶hÕ«/Ô_ÿíLbŒü»±.Ogë õi_tÿ0MÉ›„:­rg2×êŸü— c÷ÙµÀs§,ßbŽ-Øï÷®º¾néTCÇbkéâÕƒw™ZóN‹åÈW…ñÔ §¾ gn’¨©ïF‘‚Q¢3Z^/Á},ñFcµG•Ë_G—?<ÊWÈY<§¼ñ·úw²8’Å8Ó:dwÒîz‘uõé®ÚQ°´[A¬UËŸ ÎðëZ–˜œ¬aóS{ÊBNyÇ'ÿâøšNPb±Â~¡nwÂiz¿6ÕiTŠªÄ2èy˳ ¡H}ÿÇŸß/zsÉPuk2g¹`Všëw¿ÐrW} Ž3™ th ¼U›]Û=]&C û¶„ÓrŸ:38h©VëôžB3յ㣠7F½0°Í…ú¥êÒ;^»`uѨ% N›—ß¡è} Öš?5´Ð¨}Q–äÏŽ‡9ÆÝš=¦€½ Ò™Jáðæ¢Ç!›˜´¬£)}¡6F‘æÐ9sj|ãHͬ¨Jè”fWYªVu£ä•’îk†¢¯)õ¾&β ãLfåAŠÄ~K$•è,«›œÙ­¦Ðˤ€üd±+Nô”c£?ðÓË™‹~<$&_Prc-E„——È ‚EÝ’Cåã,ÊR¢K&ÀxOÆ¥]Gë  Òȶ´Žl¾6œ™ö¿S¢Û_’ã7¾ü"ýšq¯+xñpÀ):vÑ îŽ¯ÔÒɺ޳‹…`•±¯,îÔûë÷‹É[êÎ×Ñѵªo5YçªcKMRW’ pC|ðhx$/,_&F™ëÅXei¥n‰Qg‚ £Oà÷­Ã ²‚2èƒ]I‡w‡íÃÏ…éçÂôá‘éId ¬sĆ<™+±ˆ9(ÑþBíóžÚç f‚ë––PÖõ—§‹(#ß–µØ+ÅŽ‡zñî;y!fr—¹ŽûôOp1ÔW~Fñ5æ œ–K¿ÇCäFáI:O€~Ò‚Ñz¡ ?l`ñù³ÀæÏluUPë›:?Ã\|ÄœpItää΄¸à „KÝ÷z%½ 5¥›ßíp‡‡G™Û±îìkË…Ù¥4 t•Û—†%b¿þBºfcÚ®)²NšçQáà0ó[ó ûýúÛÆLÐñn9:39õæý5¾Œ´T ”£–ñG²~£Ç5ì¿PƽsH«¹ä‰Pi ßÐ2Há&W€îÏúÇÙÒ@"ûÔùó„ºQà°o-]·áR_7(Ó†}ª «±¹(nÀd@èzÿ]o¬I¾Ô,€ÙdPžv©­ÃPê0ÖÒúÕ}A!út}¸˜èˆÂ€:ƒ52í`ñe–<¼] â¯@€@ÆßPÏf[\~¨ÐþÒ]Ùî<8ÑòƒŠíɘXŒWo­¸¸­ëÒ`‚ú 7—*¢è˜ üP_P­Xº{À×]cÒÜCpDÑòz5„RÂÌâkØL^¨Ïð¶Øs®‡î¢^óÏi{O÷²Ù`êLL¶XÄSýk‚?EìÂ!]¤d°vp{jªŽíG¥Œ Á9ÑãG¬Ï¿V߈ÌüÿÙߤ¼q!–¨“æËÍ}Q­z“Ýnzzm}¬üÕÀpH°§é’u?ú˜ÝÈZXEÇðÝ OGêç't“ t“ tƒ4#9iYÖ{0Aä6; ±Þ~²z³M»â¶(‹î`¯Yt ÅSmVüQêpÎ ÏÂŒA@Í H!cF_„|†ôò0qcÿ `õ!5„2¹e(00Š@´·*<†^L‰Ôaµ=S­¶ÝXÚ•Ô‚|¹Î˜íºþƒll¥I×쌕[»EcŸBv`#Ž,Vg“°N>ÌÍ‘›áÅËØãðÒE+—;âKÖ¢´½ EZ.€”ºÔòÔ©’'èf ‘@BšÐÕR(ÑãËޝ »·+sâ4ÜÁOí‘åAϰ»u ò' Äê¡çóñ„4î» †Dâ­etné´ˆÉ8aÞÆ6ñrñnÌ*ðÕÛ·¬ofJ†n ýu&+ ćD]«Ní× Æ/(_U¯ž{ñíLi¶ë·[DüÖ4rå¼t¨lk{½EóNó¼±÷QùË™ÛÛó`¾¹Jdf‡ÍB½•Ö¹­›®¿Ö~ªÑKäpN›AÞÐúá—©ì"ÉvUwƒ~ÊjjS7†:%€~^Ý•Qhb _|SÀ¨ÅÈuµRy`ÓÖY]u)ã‡î‹ º Zȼµã< ÄãˆÞŒ]õçºãÃ;ÙDŠ¥…Y­p“dПoσ$ÑWEi.ÛÝ­}åØaP÷y—š$2·®ó…ŠÛ Ú·r’Iàw;o½•™±’58'°½jf{Õq“ǽŠtùW›à=ÿ–nõl1êK³"PN¨Å +Ñ–gÍ2evB⃠éà³´i§Ú­É84ІÀŠMßY Þ€ ÛäT›9M[ºƒÉYúâ!}–¸7 ;Ô­Až´áêÆy%R×2G)dnÀƒ¦PvL†´Ž¯ôòÚ«`7m ˆÞù +'ûã]ìõ¥‘¨D¹DôBn‘¢´rÚª1DUåïûÞìÚÛzéïÌμyó+Çó—Ýoª@ü æÙÈsÎt°NäÄÌÌMf‘3N±4(˜y8ÚÁ€.Ó™¾¸ØÔjÁ@ùŸ0P´Š¥ÀÝ(yÁý úípìÀ´îûì¿€€sÆÁaÀ÷8ë"„}Dõ(TÑÓ¾î 㲫;­¾ofééB³s[G )(Øöÿæ™aJÕ ær…¹W[KoƒÊ&ž>OA²öÕëKwØvç0$›· ª]¤:Nã½d¼|u#ë;W’íXÈwd·>C³L…βçÙð ªÉµ€ .>{tŸÉzÀH*»¶Ò× ’Òœ0ó(w—‘åŸçúíµº‰°=Q}Is˜ø§eV—MfÜXËãîúr ZYåɽ|]EËx½zX$\hW ^ ¨ä$AÖÙ‹ëÏ›%ûœVéô\¸œ±£oÕÁï@£}Èmû!U)uNl¡o®èäé~±^Q¥s¿‘þðà!ü[Ø=&7ÎÙô“j´¶.ú“÷¶AArm² ÇÔÕquu'',7;K3«"ClÚ V”Ï_Õäå²µ0­5×HÌ™½ÈlªóàëÌ­oÈ/oT`mÝyÔüq3QZ:±šÐTZÙtn¨kfÇ¡\R#eð¹™’£ç]€@³é_ `‘a"Ù6ˆ¶®§5"«‘:),z§Âô"7Ÿ‚-ªd jŽVвá@9LI¦e* ØÇS¢J›*_—øvÚ¦äŽLÑ9UÖò¼`Bö3§V Ÿ&Çÿ:Ÿ¾Sú.Mö6ÃVö…·†û"ðúsã»Ìßë‹€ù¯„Ëi6 endstream endobj 842 0 obj << /Type /Page /Parent 1713 0 R /Resources 843 0 R /Contents 844 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 843 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 844 0 obj << /Length 3626 /Filter /FlateDecode >> stream H‰¬WÛŽÛÈE^õ ½¸H4o")c2€×k/v7k!ÎÆÎGjè¥HA¤FV>$ÿÌCNU5/#É6‚»‘Íª:ýÝbôt±”¯ë‘(ÿá'JS×K½X%ó™§^¨ÛÑÓuª–5ïñT½,GOxë«ûz乞G{–£iûx½×o2gº‘¾7ôh•FÊùÇâ§Ñœ%ÌUâ¹óZÂÔ=Q–EO³XDý;Àê4𜩺±öRuwRoOe³ÁJ IºÎkõü‡‰úûœé ï{|›¹3;ž^n&êí1oþiö uV®œé\«ñ_6ŒÝg×Ïñ²øklÁñxtÐõuMZ ©…h¨tñèÁ»¥]Ú°¤—‹‘¯r5 f±ƾ 7MUì»Q¤àc”ª½­Gß-º`„>¶x£Ñ‡Ú£ˆÀÊÅGJXd¹^„ ‘†i¢äµ j2›¹I0ˆª×EÕóÅ'غ‰}ZÝìª:oòª¼}¦–¯•ü·ÙW…ª›jŸñë½QØéÀÕPó~Eqd{³3r$wÄŸ¾ÖXØœžƒ¬34˜ØzCýÖNk拪l²¼4+•—Ï8Ú‰îÄZìÆnÒæ«¿Ùí™›êjgä¡AS}ºÜì2YɶCÂ4vË-üHõ¹íSÖ2õ]?$MÕ´‹jjÍÍJDMkg_±Ö:L§uY5›¼¼o}¡8èû1z¯ŸØ#Ý4ûüîИš^}Mš}xôÍ—E»Éê‰Â2Qõ¦:âu›b5Q¨§Ø¥bãjÞ™ ;òr¹7ˆé2%¶yI§DïYÀ¼ÞOvÐë]êã0"t±AM7Ù½ÂÏ¡šêÞ üöŠ"«QÐÕ7+ò™m9‰Ü&j'¢,~ÐÕ^Ý›Òì³¢8)>DXÍ€Ó9bU¢{ K©Ýž Òä*«¶!ôÆ“YAoa ®ÌÐTä2 9æî7ƒt†À‰Þ&ß’ü©Êö†+ˬ>8®ú‘2Gèô ßK èδN+«f(`²ÍA¨kÖ×y=´¹‹ªßÛì[›²â PD×N¤ ‡ZØÁ”KƒåPl7Y£è[îpÈl…=E%‡ ¨(®örqÑCãø{BHô$‰ÓÀšVY“!ò"?²¹’“fE1˜A•,«¬]"‚Úd¶Ã–«¢µž Zfò‚˜PSR}=}—³8(‡ÙîËÊjµ=M¾+ŒZ¼üóQ¦jœÂ§‡Ù~¥ª»Æ‰áìRf^ã:È0#WKàóÓ©7‘‹ã&/襀ÿ3õ`ö'€ÿhöëC¡ªÕ ²á¯E]©}Æ•²¬¶pá¡èP®Ì¾n¨ôàrÕÛêj-Î{Cæv~HT¤ $nMɸ,ªêwã1” JELÐà=é¥V¸FÃMt~¯ìƒ¤c•Ë%<Ò"=w Õ×ÔËVR«½\Nql7>ÐFX#o(‘Nh 컟ªG4‹ì’ò}ªöäTã:–êf‹šEö×0üÖU‹ eÚV4pÉíŽþõ#T-yw€D÷… ÜÔÕ–Šá'Ø»€ÓýI`tµ€ã¾€-¢äá@A•‰¨,÷ n\í¶~_ ¾ßNJ.ìT·^ e; õ„rJÑŠuÛ2ÅÓ“–¨ù!ˆ%±¾UU¿ùf'϶CH²cŒ_©v_Sjl)?Ò¾-Ÿhú|Ðò僃:°‚ÌgÛtÔƒ7âp—m+ø¤¸B$¤­ÐMâ1íÐõ[> å© Ëéùœ¶ÅoOØ‹)êu±¯»Îü! ЮYñdˆ ç€Î „ì(ݲÎW¶Þe‚ú± ½3×Om?l3ǹHµôˆ¿n6öåH•hÔâ6á r¶ã6×ôØ™3è †BˆgS˜¶)L9…Ä "C;wõy³äQf1 ‡Ñþ«’3Û*›^Í×% £Ú©_•˜ÛýÌìøf7–Õ¡l¸„².Á4Nÿ×Î{>ô IàCìź*ŠêHÝ#ëøÖ3Á+‹ŒÊIâ3¥mQ»-²ùô…€tÓ™ÓVî ·'4¬ˆÏ\ÕäL!0+Oªêmaëüí{d×\ìÂøË”˜HDfÚ¶ó¤eTò‘z¹TòuÆwÛ²7:ˆÃÑáY+Œ|¶|Ohû#Eö¥”cK›–íáNÂã笲ßwÌcÞ»Ð6é›`0ñèG;òæmÄ]c"˜Á¶¶„0Â!så¶ÝZMû™/—kýî¢&yRpðØ~_oíM4ЬÖU¯ $·!fÃËææ\oÙ­ 5Hùhˆw§dŒÄÝgÜ ¾Í'ãÆNªß9‰~ýëÏcI—$þVÉY9da=^€ÔDú·7lÊË1`3½L É ŸŒ³n„3]‚ˆtѤÁ£Ìš£|Í+~&âCýÒ}£cÛÌûË 6ù¿ìghÐx“ Ù+ù¥>µ}hÎsÑ—.f‹Ú6²X™êîWüsJP“ZêÓ¡&n…š`,»bU–= Úq2$”LÆa6DWü¾¸Û3Óâ’¥‡º|}zB©@‡±öÒ³ Íg;æZvÖ¶Œ0›ß¥1 ;’ÄîOãÅoo$ãÇ¡ŸâÞs4?+>G;‘hÐ(ÚÓ 2%“ÈÍÛö#•8×§>Ð1;H‹¶˜"gx>¡6ÙÑ ²{ŠdJ©W Ž¾tÊè¢k ­ÅCœîpü׿:ÓHÿLü'ÁÜæùs[˜ð­¨Á׋NùÍÀÛBõPj‰þF„~ T»Q—0âÿÓkhíÇ”R Ñ™nɉEçŒú ÚØ¡“bŸêsŒ"šWAŠYœþòúû—¿LøñÕó¿!ô;„ü’y«GüwÍÅ#Ä™™±„°Ó˜ ¯ÞѺËÉ6;ñ¤»c”‘]ŠMP0Ð}Ì7>K8¹~SšÉ~Îå*So¤/ë ×7/îÙßL¾£ÌDë‹üw´|älkÂäqÝ„ÓÄøåbKpªwÖ“ÊV+ÆXVèÝvQk gÝ@BL¼óŠ¿,{y¥ZuËbmËFæ÷ºÄX4S"«»fÙ)IÛíL"MRñ.[4²¼­àµð‘Øa9¤ºvüËsj_¸”>T9ÍjS˜‹Yû™›ÓnCü£üÎìk•7jU!BeåLçЃ™!òµ)k3 ï_…=½þñÆ;˜Öx#‰@šÀ¥ïÌ’Ÿ!CŒPÜóÔ²ÈalHž‰@}ò\ÒQP-ëkI¢)KÐZ¢&?TÕ\/7`¾ØI<œ€íµ5S÷UºHF "Æ“±›,Êtö_Ú«¦·i(Þù'W"Q>ê& n Î .íÅØ/íS¿Èvõß3³»Ž¿šR q©Úg÷y?fgfmLu›XùBÃNF³Y?÷F¿¤:£aZ Xb¬.l ª!]Òè.=¨u86÷îøéKZåv~ò(±¬`+l7Ë„bGï% œ¯áRôÄp§í4v! V=°ù͘DZeúwOõ¶¥uç]‘¯ØÞôj8Å xä‡ßS\Vßç4ìíŠÊꤊ¶1EËØò+‚¢t=óß;zÑCŸzã kŽéû=òV#v…\W¶¤Ï¾n@zVoÓŠ)•Ô;CBšIfY¨r‚˜ö=2Õ‡ïÀB˜›/Q¿bÄœùWÏæÑ·p‚¨WçòmbÃ)j“†&›Ö‹ ºsWg•?0jr{(i*ViÀq]"œ…Tö¬rˆóZ#|ç "»Ï1£¼s(y7WÅgdñxÒúÞ º¸ –¯?É›odœa¿_à{Ømœ¶íñƒ!ÊÒ";i£;é&—ÿº¸ÁbÊ[^Ó“æäk¥ D`ÓÏgÑ`'µH|9…laa6“FÝÆA­ˆJãÀ– uÂÄn;Ÿ3„mLÏ‚÷½è’³ÉN*àÿÌy@’13Ûbsì>ì"WfEà5„ìA¿`¥ËЖ:ˆÅOàŠ×Ä2Ù ;þáDhoâ[¼H:(&Êo:Xm˜ÌÒ&™ßLŒÒ…lÌFËW]k·¦ïe P,›©¶þÎôåô¿³ÕIp­öº»§dëËV¡Ä®x–vµ®«Mf¹¯zš³JÙ “0$}–|ÚßÄÄ‚K èåŒÈ›%¹ÖkÁ´¤{ó³œÎud -Æ]\ëvã+@¾Ù#sœQKµðÂÎÎjõFÍÝÕ<úå«rW)QÐÜ4RžhçÒæXa÷|Ǩtp iŸ-cÁì Þ˜ „m2ï­xƸMЃÚß—€tTy0 k¡ŽICÐZôx$i1 ;ûÛÝ_4t¹QK^ÑsÅù VzÕ–O}âÔ–³õø… <¤'‚ïA…KйßÓg“ͶBæVQ,+3ïéA#•+‡ÅEáèi/úòÞþ×.€ô¿äÖ´Ió²D…!‰‰½¿àFž|î¢uÛ¶îªG1Ê ë¥àì…*°€¾þ|÷G€œ<} endstream endobj 845 0 obj << /Type /Page /Parent 1713 0 R /Resources 849 0 R /Contents 850 0 R /Annots [ 846 0 R 847 0 R 848 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 846 0 obj << /Dest [ 831 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 334 592 364 606 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 847 0 obj << /Dest [ 804 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 116 345 145 359 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 848 0 obj << /Dest [ 1264 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 338 331 373 345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 849 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 850 0 obj << /Length 3825 /Filter /FlateDecode >> stream H‰´WÛŽÛÈE^õ >5‰æMe8âÄ^ì&Ø5lÁf&ÕqM‘Z^,+’È?æ!§ªš"g,;~Ȱ†—fwÕ©ªS§^mfÏ6›Pj³Ÿ¡òñâ4õüÔOÔj½ô’ÔÔæ8{ö§6UyËk|ÕæÕìÙwïõÐÎ|Ï÷iM>[ —çÙ~›¹‹È‹õƒ¡¿¡VéR¹ÿØü0[ókµò½u‚S¢ÔK|9„7y/ºZ&²Õ¿C<]„¾»"/Ñ~ª¶õþRu< µq±“n‹Výñ»¹úûÜÅ÷ Þ-½¥.\_燹z.ºš¦äM"U;w±Öê_üˆ±ûìZè{ n6Æ3¶à|>{n亥S ‹­q¤‡KÞåöÑwz½™ªP³p™xQ¨h奩J/Ž|ŒSÕ˜Ù~öjs# °ÄŒÆµOˆÀÊÍ/“0!JŒß*ñ=ü—O€Z^cA—d~žuùÁ´n Õ¹nÜ%øØp[õÇ­‘'vÁ½îå Ðy©®Ô!“€—ÞJ;¾ûù­ã«×Þß~rƒH¿û‹sïº ®Ê³ }4Ê |)Gö7' Úd#oºNÞÛ¾3ªÞcÃD«È‚ãà)ż FÇqì9w…o²ŽÏÌpév#TØ9Õµ ÔµÚ%÷ˆ]ˆêj…Hª=º¶«Ê²>pWVžø™É Ú4¶›ªYÙÃtÞ‰–µÏÅàgol1±åáÊfP.i¤G|ö&¶k¼Ø&™DvRŠžÛ7Ž}“^¿ ä” ‡úN7ð*†ugú!õ© ŠÎˆQ×}CoÚ´¦B]5»8çÀ¤ —ÙÑd•½ìÀ·Ø3`§¦>™¦»¨:ÏûfX[S5†VVª®r3çÅ¥»F¾0H@€¼Ðׄc¬›Æ`½:e)(bqqè#²õNÛàEüm ëÆì<õcÝ1ÌšŒ´+¸cmowÅ~o°{§ö ˆoj¢Ù¶Ùg}ÙqDr˜kGíëùмB’>W7 ­‚¨Ýw4õI†"lWHc”> `x@YÆ!ç SbÁK’a˜+T—¡F’‹:{ÈŠj®ŠNQа Uu§ŽTè;c¿xqªåªXLŒŽ¾’]QW/•=„ ¢b5dŸ•Ó ÕQªU¦Ú~Ûš_{‚¹®Œ÷¤pÔ’‹!ù­‹!`ðuÖ4ÙåñHš`Ìû4â€óÞºÔ[Þý¤>‚ ãke ¹€sîä¬Ë˽{­“T¸Ú[~Ù©óÁTŒŰËd·¢NP_g§`:1åN û}ÉZùÍaÍ[=ùÈSßsD+a7)ôŸðIh×ch×6´bwBvË3b¢ç ¡U’øDÓ1¹2Tib«Ô~Ê`«2᪌¹*UQqâšÒ‘vu-ÙÌД›k]ÙoM¶£ìÁæ÷£­ùljuß/ï æ9ââÕ}¹oí³Î%3Û{wÈÀkž¬¼e:Í“tØ}hß“bHÁ ˆo O5³Hª›.CNÿˆ§è zÒ™çO(Å—NRk”A•A€‰ºZÀ-FBk›HPR-¥Æ‹D£ãc]¡ýÞ§ù˜FH s<-—2éd—m›XÝ4ÒÒµâîÀ_ A¬ûª3ͧèblP„Ž^nìMÖÜ–~ Ó)A…|(s®Õvõ©U¦2ôQ º š »I5céù¶ô&ì! 2äŽ2ŸŠ«^°[µ`<Æä Xzb´ÝA²&ã®Åä„iZnD­ùVEaKÐ0B4å®\ÖS¥ ‹[‰ɑYŠ®Âëlõ¢Áƒ’j$½páß4Š*ç{ýÇ`K%ÃÞT<7Ñ…žo3ÙiõP±9Ž"}EÒŠêò‹ í£d€ÌKÔbkŒ |x˜h¿KQ¢ÇÚK®u4¸ v§Ç¾›qg)¤Y´'(¥ý…l¦îéÁ ôîµψ ðw¸m¶-/Ê)*Y˜ Z ‡v#¢¬äŒ]kÊ=»:Ýtóó[škRýZ>uí5À~ÎÕQŠ6«H rCãä<«±–_4‘Þ–†ELÇl+¯x"äQc„z:sÆšS¿`…„Ô“´¯·Ÿa÷-A•@MzîúzwnÉ1¶ÚöwÀDL‰:Àò–PŠ$ȸÙÛ©®º*äÉ~Ê*Kýéd·¥»É—£hçפÜà`…Z“¼"LøÂšóò³HÝiiûh>8‘¼ˆƒ ARÈ eßÓá5?bU 5vt—J®uzJ¶ÖpÄ®z´¤Ô†ïI¦ARcƒáH¨v¾¨ù uQrog>¹YÈ«“|D ˜kD’óÈú¢ªÙ‰Ñ‡—T›/Љ”¦/Í0õ0ˆh„×]3,çC!T£ÏÃ䦨p¶'7‡Çp̨К1EÁFíŒ K¡ê¢£Yœ>Ɔý—óªém¢÷ü Ê¥D*„]cGN¤~*µ§ö–J7UlG`'ê¿ï›™]¾®ZE ˜aw–™73ïUœåÑ=vc QI™h{N(‘!ûÆÃÀ0 LÔK?u£H¹ ¤M¢²Þ2íÔ¼‰vö «0 ÙK=š]Àþ²OãYaù;ZÜ#• òŠñ‡Íè]Ò(Ô šôkãˆ?$ž:ë"1«Q½vÓQe>º9j€àa<'×ÌrAQ†¢äâ‰Z‰…—ʪ=¯ÚZzú ò ­Øƒ_G¹¡Hbæëzônó Xñµ§+÷•{»ò›H/þ~žÌÉ«ü_åU1¦!q—7bŸå†´N8VQfð¶ö¹JN™g ]8¢šQ%vœƒÇ£ä‘g Š[$•éH$±Ž•¤‚è5T4ÝÞ0  §Ü5b/p¦a¿äåÁo"D„žŽ?ÝëîåòÈv*äRXvu÷›vÙî™)ƒŠÓH]sûÖÑÙÓ¹í<‡å“g%íWhˆ½º‡³C¶“w_”ËQ`XU‚ó;ÔÌÊÇGÄX*…M£…:ë˜zƒ·1ñ’ƒf©õA&µ4ÒE„wÒJ‘l&¾`dPS¹#¨=À˜ñ• :dþ/¥Xo¢Í3Ö੟åg],MP  Í«"`vØ`LÛ`fHÆeð <ê<6È ¢/ WðW¹XISL÷rÍâhEݹŒd”N6§eÿdëg:¦‚{Ò'¾¢YêÚînmÇMœÖùÌCPwCÁ›#žN @y(7´ C˜Å`ŽhÖ•Ì„v7ÇŸ tO°Ç)œÿDäAù´¯Àȟˆw%¬Ë{;ÉՔ꺨rü›÷ǧy!¤ø $°•|{‹ö"J˜:ø¸™–’Ö‡à³áA–!£yC…gf`Øæ>VE’™.’bóÎeZ7s¾V$`œÁQA.‘Lp$üý9©P8iQe0T6Ú)â3ZêßnËê!(7Œ|°÷KßÅ•½${5ü˜›hý*Ž!|SðŦ9bØß»_ra?UsŸä]îÏ{¹aǽ—vüñÛY±HÒîW¬(Å$ƒ˜ãÿµ=»û»u™·ÖL#Kû2-Í.ÿ‹¹ç S¬ µž¿\=e÷í ™MñGÔg[åh™Ê¤‰ÑDê¶+ÄIµ³‰Kµ“«”Å­½‡¨ÅÕ­£Ñ)¦Œ3GX½#|üòöÓçêø–_zì9/Nxž2<…sœå­ã(ޝ©zN–ù 'SF¿0ËN,œ2NŸNë^XÖ^•I\våÖ^…ðz…>áÊ8ÌKŠöÈP}h¬¹Gõ*ƹÿ¡Â‹'Ч1eœ>ÁªDÀµòÉ3ÈCiüW¡=„o¡CÐӯ©c¦§`4eœLTÑCÑúÂçi„&\t6WÒ³Fê&bœo&Ó‹O[ßUÄôh¸vÆŒ ôDJ4‡ÑI–¹p.ŸlæM endstream endobj 851 0 obj << /Type /Page /Parent 1713 0 R /Resources 852 0 R /Contents 853 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 852 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /TT2 2104 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 853 0 obj << /Length 1899 /Filter /FlateDecode >> stream H‰´WínÛ6ýï§àòKlEÔ·‹¶@’¦]·´)wíÖ …lÓ±:Yò$¹^ö {‡½ã~Œ¤HY¤¯˜bë0¬‘|HÝÃËs/yÎg£ÓÙÌCÍV#ì!—þGÿI⸉¡x:Qâúh¶^Ô ZÔ|Œ‹êE1:}qƒÑ]=r×ec£‰|Ü>XoR{â;uGØ_ÏBI„ì_fߦü S»Î4¢QüĉÜ6ÿ€Ç¿ÅžÂ¨ýÔ_ýuâ¹öûNd¹ šß£›û¢YÓ_<‹ØôKVÕèìÅýü·= é{E±Ð ­Ìv­ÅzŒnöYó©rþßJ‹¥=™ZèOþ/'Æ—Ï—æ¹ND_fÏèoœÁ~¿wlßÁVÍ¢–~š†tè£KW·?­ù—.g#Œ24òÂÈñ#ŒüØIa']c ŠŒV£óY— Ó!®šCª]–Êrö©·M2qä:ô>¥㢠vèÆÞœç»{Ú¬MYþ±t¹Ìš¬,Òœ†äáЭU” añТÜlHÑÔ·ö#žƒÓçXèÚ yˆDlçBîéão&{B“m¥u½ÛdÅxkÿ¬2’/ó¬nÚW¶øö‰ï?Qæy¹ïæñ µÜÿħ5„QìÓ$ˆïyoçDèC/ UØÇC7q¼`púp/6ŽŠÙodz!œŠö AL¹µ"tc:°ákIVYA–m^²¢ý[“ßv¤XGzЍôéÇE Oc0…ˆv«…ÙåÕÇo¯_]ŽÛàìõÝõß÷^_]Ÿ¿¼êãÏÏÞunnhàÜè÷Tngo߼àìÝÓÞ}í=ÐØES˜*ìh›oÉŸ#gM&OYùô‚$ØåÄhj˜0» ¯¬Ç۪ܒª¹o3S¤ò䄿ç䩞›Ð *”Öƒ ºå.kùŒ·×ßòC³‘ÂÅQëM%«dËá E­¡Þ0¥;±]ÓÖï›´Ú2|± ŒûËøœæ»>ž|¾ž“Ó# žI9('º&å@ Ì=Lbx ~z£¥ŸžKâlË#A hÄCoáKÒŠž¤î6G]x85hUþþTðûm¿Îë#etŠhÏDyXåyû4hÝÐct9$–01h)šß¦­ÏF²ÅJ“"¹JwyóääžÔ'úF´¿1 ²A912ˆÕ%Òs(æK¤›iŠîC-rVDÛ.ž®ÒÓFW®¤h®HWþe¥/>0Ôªk}±¯_2åÝEЇo4$-z‰vÚ„žI‰¨•ŽG/-,’«(‘Ðêè‹nX!6‰ áàÁ›‚³{Ü5 ‚ÇSSð‹Ë««ãàAbPbSpzÃbÇqà@ì04Åþñúå°çAdÂÒ¿'íSHÛAhʉA 8ÀýK8iì€åдä‰)æn2ípýx&aA ܲÅ_Ìw‚ µ *0ÑRq&w•Ÿ² q,jœM†aξbHŽ®pêEéNûünMÄà;R*mXkÖ8šŒ pTŒIÇ­œ"‹F$‹W޶ûy]ЧåRÞ+šò°B•­o2* 8À6î7ÖÃ5N»h`¾ÉÄ€ \A~¨T<:Û°ë´'K÷Nõɻޘ·]”É l.}Å!Õër_Ëv÷…7ußd–@PN4™%Èë€Yú‰²¦Îä› hR1HÿogòMŽ aÎÞtúPg:¤¯ß™€Ê2y5„à©^ ¨,~mú²ÊòL áÊòf®,øV癜ʉ&£‚y ñ×®,]¹ú’MN Dª8-­.„_„ûêúüåUÿPR®grS 8aï!å¶mé+Ò™\¨¶ï²z m3Ã4ª\K=“åA9Ñd—@N ž~u‰vÝV¨Éj ¬Pÿ+…väŒòÄ&K‚Ù’'seGí ´jØdÕ@PN4¹,XLßv[õ t—S¾Ø47H©Öi²i 8 ¿/ëƒT—¥vCؤÍb-÷â–°Ò„ÓmÜÑž˜Ì!ÐUÌa½%‹l•-RRÖÖ¼ü¬ßì±Éßà@tÅßÝZõ®K‰ˆÞíÚ>k´ÌV+R‘BäñàJ½â±ÉÒ LSqt¢×Ü\^\¿~&¸•Õ¯â"·.7¤cÓîs9ÏrEz·¶ÎÓdë@橸º}– ýÏÉp‹bEööýG|TQ*E“•ûr'×3r]äÀQ&“g{زÉHŠc{]6äèè8”Z%ÀT>lÊê0¾8QMI9,0'Ãÿí·¾A0Œ$Г;R`¹Lx²qUÿHoêÜøŸG¾« endstream endobj 854 0 obj << /Type /Page /Parent 1713 0 R /Resources 856 0 R /Contents 857 0 R /Annots [ 855 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 855 0 obj << /Dest [ 489 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 455 220 472 234 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 856 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 857 0 obj << /Length 2037 /Filter /FlateDecode >> stream H‰ÌWÙŽÛFE^õ…~™"`±¹/mÀK'é ËæLÝl©$1¡H,YÝùüCþ1snUQ¤¨Å0 M²ÖSçž{ëèu6¹Î2¹,[L\9ø‡G$¶“8‹ÓÐŽÇgÙzrý¦MجUcÖΪÉõ—ï\¶l'Ží84f6™v¯»É=ÿgnM};àKAO³$fÖ³¯'©Z!e±c§vñ;rô&jO­Eoa¤—úÍCëÔs¬©ëÛwöðÄÞ=Ur… +ñ¶hÙ«/Ÿ±»ß­iˆï}¡òÂrølõŒ½ÛòÑ”jŸçÕÜš¦œýªþ*`êøêhžcGøÈÞ¢M!Øív¶åÛ.oiWAÛbiliãÕÁéf¦i¥VºÉ&.+ØÄ #Û\æÇv’°Èµƒ€áŒAÂ1YL^g{2|CœC6zªb(³Ÿ&×_¸ãx¹¡oÇÄ$þØN 'ßó¯êµxfM±ÿ¡n~6¯_äú¥nôó(KýVm×¢1ãÔ)éE<Ê&ïN•øP†ËâØÅ“©“ ÎóÑÞ0Ú÷^m ûC'±½àìôtï÷V¡SH'ŸìF NÑ$:5;š“¼1ääe[ë·VÖ˜ë÷¢q˜Ý|óã«ýG, QÎ!œ¥alGÁÚö©Î3 ýhú‡•0X–¢M.‹j9ÂV?ü$fÒD]e…ÒB=Æ„ðê<ƒqïñåóy!‹ºÊ¥(ÅfUWb¨È¶'}„É÷/`:Õy¤0ÀԶŲsCɺ¨ÚU½{qå\é†M#>ˆJ¶¹ÃòÜ °Nužå Ó9¯žLB®7òi¯«S½,D;¨ {§Ìéô嬓^{ªó,ê–%Ãdy¾©[Øä_\™4øÑ5L6b#rùâ*¸ŠÒ Ép²ó4¦®–(&CQͱFè^\uÁ½3%²³›_åÉÎCôî'…>ìeÉŸ_oò&_ )š—t pFäv²ó`;ÄMs8»iE=7Cy £sÕ÷|/U~Ó{¾òŸ™þ‘înï`¨UjÍ>ÓÿZ™ À\ªTœÀK`û>üŠþìŒJ˜Fvì œŠwNÅ µO€ðíÄJÈï<ÿ ‹µøÅl©P‰é±®çâåçìß™…ªãòÛooî¾ÿî†uõ¹Ö£Œ#±ß÷×7&?¢÷õÔ¾´¥ZNƒ,KÆÎ`<„GIÈݸ«q¿©+™(z¬¨>W–&6zƒˆÃw¦ˆ&Æ{ H÷5Nºi¬ÈkËã + çUŠ—ûE ¶©Zºî8nDKÝóWdÜ.eS­: Læ0‰Üž)uã‚fMÊžÖʼ¡ßlÑÔkEÆ>£Ôuãã.¾ãÜ=!9RÛn,m:d­šBUÉ" H*Mq[’Gb?Wõ®²÷ö§Ø7ßm7Ú7o`a”sK-*°ìù¶Z”u®>$ àÅçB]S A5¯-,áñM +·Ê«yYX ' %0>õ‚Ñ|¥Æ.{3&Ê̹NïEŒ­ “bñõ¦ý¨›óRçЇþ Üœ?ÊÞ?ßÍ üãusÓáU´€!‰xÙ í½ô¬ÑÁ޼w¡ß.X+ä32<¤ó;…4’«•·fU-Y»!õßÔ ý=/la3S«s}Ùà U5Ëîn©ôø°TŠCd*ZïX»],ŠÇ÷Ö±ã9]%w’N2×ÕMÿ-HÑ._’lLRX1v_[tþÃÔÄ!Tí3‹Ãj¹EÍxR tå³9šûÞ²áS ËwB0Í”ȶ¤¡ñ{ó+é=Ïêí°8ÀèJª!Dðñ­Í”ÇÆÿ­ÒƒcäÛRmöÖš¦üµj£ùøÂÛö3áÅr«Š™hÁªhÉZjàÏC\£&É—ÉIòÇ…—¬JrÔ ¶Þ¢Ä¡ ‰fC G¼’<^ \îšJdÎYŠˆ9+©"àtÖˆëc?JSo²Éÿ¹Ñ endstream endobj 858 0 obj << /Type /Page /Parent 1713 0 R /Resources 863 0 R /Contents 864 0 R /Annots [ 859 0 R 860 0 R 861 0 R 862 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 859 0 obj << /Dest [ 858 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 244 604 274 618 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 860 0 obj << /Dest [ 874 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 235 548 256 562 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 861 0 obj << /Dest [ 779 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 410 535 432 549 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 862 0 obj << /Dest [ 858 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 336 94 350 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 863 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 864 0 obj << /Length 2669 /Filter /FlateDecode >> stream H‰´WÉŽGÅ\ù ²€f©ö*6²lšƒÇ°x²4‡j2Ù¬q-²(ŠúÿÃüãü""k!›Vk02hVn‘‘±¼xñÝròr¹ ”¯–›‰(ø‰²Ìõ2/Qé,v“Ì Õ²š¼|}ÈÔêÀ{VçÕÓÍžAŸ~2J£W„ºd}ñpl!CŸp÷„Ïä‚—a’Š8RêNmH—² +A´¹ÊG¯×Aðñʽ7 Ó+EÀ§€|@!$.sè ðh;ÎK¹ô ÚF}Ð[“¯Íþƒ£(5ªÙåv%’|Ê2€q°­,~3œVœb®zÛvXp¸™7b®©jöª:–m±ƒVH-T›?J¬@)ù0F–»þÇ}·­~ |¤04ŽtãdGEPÛ\²_¡ò)š•õ²tiNEý¨ZrغŸÜ[·¿±^g-‚äJÁ¿qY{c«žd#£¯wA‘rG+/ìJÖŸñeE¿ŽCèR€*!ðS/¼¸WK6.Òf/¬É«£|´å¥z0JÆ;Þ%l " @?Ek !R‚íÖÎm<؉j ì+ Æ¡d©Yœê è±BŽÏžW’²¬[.Òl!%€Œ_¿×¬yªEÚ ÅŒUY7¸X©W†Â\æÙ5¡NÜ…_jÃ/Fj€Wmù‰óî2³ˆ\÷* +¤u(°‹ßëG¦ô¤ö ŒB²ÖFCXx£°Ø‚^"Zò~ëL3ødËH+Þ`h¨U^î  ¾>«µÙ(dp,ÌߩВÅxœ¹,xXÄ€L)Î Ý8º*¨ñ \,Ê=äÜ^«Ó¶Xm‰„ÁQfA J+è¥I(â07q©Ö‚&½*-Þ©š2 YGx©ã)ëÇ‹–¹ÅÆÆó§ö)ìÜFÜjO®Û›ÙŠ1¾˜® )¦´Úì› ² Ëád®¯ºuû*ò5 8JR«B5h³šŒý*ø "ФîÉ×=³VEØK ;Ð0·†GÄt©œÑë¹*˜ßñ™^­-åEU~œ·\EÄHn†Y*òüt ’C°e¶Ù¡ìgŸJr¸­xž&GèYâä›Òd6?¾¬1×€ŒC(Uâƒnh¾ƒ/Gà³°ÜÐïÛ<ÉgÜ@g¼¨+‡å™Ì‰:Zíò¶x(Jô¨…3}Àé=0jRLðb×ÁÙ+"7»‚x@`Ö%hLCðÅ+ró-(þl°ßÌÚ¯>VL%$ˆ’õ–Z¦HÑ`ž³¸sÄ9ó¼,›/RÁjמéÐÖ†\¶ IÆ#­n¤—vÒnùÍœO|"é`ȯêt¾ Ç›ÐÅXLíbI/ŠõúšÔ ôE@ˆšëÞâ)iü©iͽz[wÁuÁq×§·LsQEñ<‰Û[R·2¨´.öTí½jK 7Àà|-nŠsÐÉq™5PAðµ%«ªûµÜ•;0‚¿]ãLgZf­Ž‚¥¹§Wó,W+ì #Ûî…î§'Ér¾{Šn4Έ} Óð©ªU6õ£Ù+ q½7‰&aÂqé]ÊÅÙ(Ö‡NÏ·ùâ¢O%t(*,&§˜%’Ü+ ÅÓ-ˆC‡*˜h`)éD’WìÁžâ@èìYBMØŽD·\yE¥Ë2&á] “-!OêÜí×8NúÆ •}­,Ï’‘a+TØÚ­ÐvSÙË,ã«n·P Š'_ç\¤ç–bZ)‹+8 A<Ó‘µƒÍ\N“©ì¸•A×yó4ž˜ƒ€§ûપ( UâƒaÝeÒ÷C= š…ÔÁûº¶RrË.ìFLoFù?ÞJßÇuÉDÊ‘¥ê‹yÁ-‘"š•iÙ‚ñï#x}»ûøË)§Çˆ)”óZD6nzŸò¤ê°3«G…r“PÌŽí×ñ$3¢Bþ æàzpÞÎXjESCw9íÚ„ ½tÀ(ƒD™‘Ÿ™Õ+Û —1%RhˆÊ €–§u,߆ÞÍŽ4øXÒ=J[sÁ’{ܽúí U õ#?ZØ­Ú6'ÖÔ†åh}ê’:£üO2ð]јC&=+ˆF2@‘†¥û꾸W?y®z€Â 2wÄHê` ¡-+œlÏ2÷ŠÎ(–™ß›ëT=lhc‚aÁ!RáAZ<‘î÷«Üމ߅PÂû„_€ç·Ióòh”…jåÝQg•ÉkûÙnQrîþ*„5TÝ‹báH€÷æu{ôê^#‹;Á~ǵŸ«ˆïÝäLþ€&¾ÍSÖ€hEÀˆ•2bÍ$¹Þ'„ÜZÌ·B¬iˆÛŒx5w…wl75fñ>x4ìóñBÉ.å¾.ÍǼn)ÞɵÌÀÞ^Ø{óòÄäâ÷³^ƒ~­ÙM\Kozfh2<ÛdÅ¡•¾®-Ыߕùˆ: ¦R«b£v{# ´Ëåóª¾ËÛ䎢75¯³ @/×pãÇÌËɱK è endstream endobj 865 0 obj << /Type /Page /Parent 1713 0 R /Resources 866 0 R /Contents 867 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 866 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 867 0 obj << /Length 2275 /Filter /FlateDecode >> stream H‰ÜWÛnãÈE^õyjÍn^DŽÌŒ½ÈY3ÄÎ-µdn(R©hµ²ÿÌCNU7/¦¯Y,6Ùת®ªsúôÇÅä|±ÐB‰Åz¢´ð‡QšúA$b6ý$ B±ØNÎ?Õ©XÖ<'õ²œœóU‰M= ü  9ËÉ´ý(• ÷€è1ªF^‚ŠUHp^ãS4ÙFدý"EM%ÈGIÍÏ4Ë|íE€ÂÉ›jµk à‚käŽ'ßyž&ó’lÚ<`ÐCòîMQ•Ú>(9‰”æÅKyuËO…­F#lqÂv¬Üÿ²j|q=uÐí@çKú£:¡ýÛmb²hJ‘Ù–¶MÈwì\wFGT²1+J4ÂÞ¹¯V'јjdnHÃå†NÚm„x”Üâ0ˆ^sâð°Ï°?M°s<»óÐmÝ0ïœ \çöõwO>Í;[ƒ8t)·˜°7»=v!f4å ®J±E)æ;¶àÍÚÒM *` E¦lèĺ*VÔÜšåCVæv|ë‹P-Q0ݬóCÙÎo²¿µ›¾3a»"[®ìÐT۬ɗYáâ{?qUí=ÅÙ³! :ŒÚ†Ë«m”Kf›ÆE¶ô¨3+„]‘»¤+qtßE!²â˜y3Ì;µ1·¼ñ4çÖËÂ-¥ ·p~SÇsæ©£Žµô€©#T¢w‰ TG³E9]]îã†Xçð6åS ×…½NX‘:€Õv ¼%ZÜØ»à‹7‡ õ)ÕzÚØËúDo!%wVÑxŒU³¯Å\W{a~ȶ¸†Ï«!ܱumL}çùO.MK-ñ b z–$}¤Tû®ógó>T}ŽÜÝÒ)+ ®¤òÕrkFÑŽ|®Ý—¨HRœˆ8Ñ•å —ûÇi'5§Ü8®:(eq°‚{,+ˆD·ƒs )¸Ò|àþ·¼ˆÒÍK0ÑåXþÞlò²Ó4¼ù8NS;öqu„³n{ú´áBÎ5‰4þOzbÎCÖߊÛS1v&òF8%2ûßI.ºµµÜ”¶äžs8õƒù8øÌ¬ã¦|œàe¨ÞÚ»bÎ?vŸŽ–Ì>Ïzt›òVi:(GÈ¡)kI XYI<Ã}°E“D>.CŪx2ô Îô¾ø3a+„Ô$2Ä@‘·à#lA/SõTsåÁ#éCwÃÀÞîêÕÚã‘ U}\óýÂ) í(ô2†¤3| ˆŸgJÕ}¥ê¸+%I‡¾™C_úl©W5/¾«@<ÍC†‚§W…¤}êÈîÙ ík‡ä¹GDŒ`® ƒ°Ê^.½ÔuÒ´WBni_nPDd.vÈa4  ²_{”ìóŸYÚÖS{å­ÚcE9¬\[rdçøIúdo%¥öà ÊöØÑ­ÿáQ(X'Ùå=Ã"0±´¿ôC)ÙÆ…UóÏûlafÉíFµãbÒ‘Õ8íå N‹Èß}øzýÝçë/®xÓëÅ$ ý UBϦð£TLùwo&ë·Gã¤À^É£ñ8—G/.cx`;ŠÜ(ôS=]ýÜøÇÅ@$½£c@Ž.d§ª6W7ûj{qyÞwP`áIP“­ :õȇç‡_p!Ä“N·.䥵yÕìæò¼kŽìGd¨·ŒCøÂø#ÒÔj>Dµ²S^ž·mdQÍ_KÊ‹£\vô•‚x~ùíí0¢¿\/Œ#ïÔå*ê‡OР'åV³:O˜.Å%=åLsÚæ'z¸D$° CøñÀÎ_öZL‡ròEi®b0\ô#Í{ɦÜë‘£&(l¢´Ú”èXÓŒ£óËŠu+T\ZÞ«Õ§½xI«gEQk±®{*âœë€‡ë çÕsŠ7׳¥ÿÆRº«ST™s\Ž…¬-àγ°;ÓXvÅCö•:Ùu‡‡ãš¥KDrEÍwÁÙ5eS ‰q­‘hB¾öÆÍmPyn°¦[~W¸+G¼A…ð£CcBÀ×6]Ö¿ÄÁmaÉ>ョê•'ížqoÆGª¡5Xh`O²"åH2â¼ÉQšõÎ@L(¹´ù:_f”ßQÉj¼zZõ5º°Á²ÿúZkH endstream endobj 868 0 obj << /Type /Page /Parent 1713 0 R /Resources 872 0 R /Contents 873 0 R /Annots [ 869 0 R 870 0 R 871 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 869 0 obj << /Dest [ 868 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 262 728 292 742 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 870 0 obj << /Dest [ 868 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 441 688 471 702 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 871 0 obj << /Dest [ 858 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 160 509 181 523 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 872 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 873 0 obj << /Length 4132 /Filter /FlateDecode >> stream H‰¤WÛnãÈE^õýØ,š÷‹a˜uv°ÙÁŽò’qhªe3àE){œÉ?ä÷aOU5Eê2Àf‚ÁÈìf³».§Nþaµ¸^­å«ÕfáÊÃ?ü‰²Ìõ2/Qi»Iæ…jÕ,®ïûL•=¯ñT_¶‹ëŸ>ûê¹_x®çÑšr±ß_ô§ÂY†n¤Ÿ ý ´Ê=åücõ—EÎ;ä*õÜ<Á)aæ&žÂ¼=ʼnlõß³ËÀs–~è&ÚËÔÓ»úüÞ/˜ ´q°“î«^}øéJýý7gc¼Ã»Øuåxº|¹RŸßªáßfWó&¡.Úµ³Ìµúÿ²aì>»xn‚ÁêϘc ÞÞÞ\'t}ÝÓ©†ŽÅÖ8ÒÅ£ïJ;õÂ;ý¸ZøªR‹ NÜ0ñU˜ºY¦ß"£LíÌb³øauFèc‰w)ÔEV®þ¹¸þx–¯1iœSÞø[ý'YÉbœi²»¬V™ÝÆõ"yÃÁ÷s>ê©[¿Ûuö¸ÀõrZ6åÛ·ù¾Qeצz'ѪØ9‘›i£ûP f­ y§~ýˆ`fú> ‚ëŸùýƒ#)òü£2Má¤ÈtU+²D=êá¥TY´ªjK¼Êt¤‡z¿6Êñ=Ýìë¡ÚÖF–s–lñÒwÉ@ëŒÐ¢'²ú(ô®b°æºÅ®¾zu4^Ãa°åKCž>:®ƒ|iõ×n€«/ã2LJm’Ýv¨:˜' í°eý>îù ä8vTÑ(€w|´sOð«j±QŸ ,Ô¿Äý‹zåã¹ÂR½ëqR謹õf4¹’æOIóÅ}Ú““‘p28–þ÷ÎñY½uè—ü葦L#ò`Œú#7}tÔÐ)™”Õ¦¬6Yÿî ‘Vk3`_»¼êx%!”7ƒ`ÐÉ\Õ>³×Tc IejÃçµîÜËpôìp ¢L¼\91—&–i ‘Á|TÅÅ¿ñ«7ê­ªá:yí³JÖa! Šm.6•©×öíVö†Ï€ha¨†Hæ’(¢“¥äÔm]µ†ß5ø‰ÞÞ¹êa£å—R祓S©8%ÇW´)¢‹Ê(v»âýJJaã€èb ²Þ5Ø÷µÌ%vø Û°Á2ÔïÖw£dùü•¹= é'˜í‘ 9•ò²¼”Œ ›ò#v¨[ÊOS5fxß™´T\8púÞ®ª¼–™¢”uûv8[ýdêî×ë“zZWý‚ ØÞd‡ÊrõGó嵤{[„ Ö+Nˆ¸|5ÇœŸ"þíX»|èÄÎhDAzèD¥´£“F° |7MÉN,%†ÿNêrÔ»MxQzÊþùœýƒ)«ÁûSóþOGþO'þç·L9©¾§ƒ„sÚ²[wkª‰T¯]µâuT±±dmiukª¤}mA=öÊa¨·v$JÇŽç'dMùŒÄ“¶k—>ß?<¨ò¥Øå`v=•8—`ò¹Êa9±e?¼×fÆ™ ^k‡P¦ñáY>q¸ÿ|®V6c~$‰‰Ü0ÌR%ñÉã? …I.‰ óž&”ŒÎS¤™× ""à¦òø‰™è¹KõêÄÜsg8)šï§Ûò¾ PL7,ŽR}ØÖ¢)qÓd†¦)¾ÍÁ-UgQšD ˆP"UmîÀ·ëb F˜S‰Q‰*\ßÙ²õÒ äátØ…„soºÜl‹¡zªêjxç´B2¾¨Wä@ò5õñÀõZÑÉâÏT<%mñ¸ä–!D⥮üEx-*‡¨.žœÛ÷Ñ›oGOÜ8d`LÀú‰‚O Á°,P쥔o0•Á ý™ê<æ¾óÆJ²çF=´cŒâ1FWÒ!»ÌË]¼x–÷J½™Q\!ÙØb7c7\«uµ3åPCB>µêÖ®,†I¶ùNblé•Ýzü;oØÄ³UB<9‹3[nЖߊj%µ—õ/`ÿB÷+áÅYBµaæê¬~b7ÍçØ8Ôêˆô§ý ÚNÕ]ûlv¸`¿F®‰n×f}’{ø?'â`j¯M¾ HCéì2pðpÞƒÂtÖ„’Ik%Ҹ籒ÐEÿž€Á­ê†Œâ džƒÍŸä¡oå!á'ƒ6}¦[Õ‡Å9¥ð“ƒØ¦pÊ'¤‚ ’8¼Læð9Ó&UÈ¿12-¿…`ôÙœhâD~G7 Æ.~ƒ~7zÃL²Ã]qô«©ˆÖuCÂ–óš “kÁË%Gžôã0Š’?†â,]ü&ŸÙ1ŒÃ ÆálHâ™zôÁÊVÒÊÉÊ Â#’ ‚ ǶÞH‡[0ˆ¤ªL¸— ç²-:Cè ÎêÏËçG'Œ—OŒ—‹ ºíG‘nÐß!xU!cùýùªéQ܈‚÷ü kOFXÜþdå6‡•vr!‡r1`kÁ 03!¿>õêµíL†ÌN¤\LÓv·Ÿ_׫Weuê Ž‚lHclõWðÁvñ/v7¹Þ§¿â:ñuü¨[!Ŭ,f^e¯Ñ%R!ÍÍ›PÍÄ3üV;c( IJùé5#iï¡`€ÜS°r+ÎèC‡%ÿx2¸Ùí•~#•,êqÓ 9y³'ëaqÙë®8_z&&?ã½&P¢8u¬Q§ŒÚ0êQ§|„1§MÌ©ÿË—KBž´‰k%ÐÐŽ”Æ q‰á¦I/û…ÞéÅ2P0ù@j†Nj(ËÉ”…¿tLû*WÛ8h•ÉõÀ%u+•Í­¶ö Î )í É3Dä„bÚhA˜ë‚«j)=ºÂ{€$¾w8¢°Sïeæ æCz$NÇátIÔüÕ²ÞmZ£÷‘–Á&»S\¶"œ5\ÒJX‡ŠS×Hç+†rZQjÿ-hß"à c¬Ö$¶~ÑR¯€4õÅèXîmõCri¦âVÜÆº<—£ýýžÓP´þA¯ƒ¦- ëíJ5ˆôË$s(èˆÙ©.X ©L|ê¦È¶,®èNñM6NF?FÆ=òRŠ·Ãf•o1Û°ñá›Ý¾©¶“A8ïÃ&d½™»¦;~K¹)Wô8¯B»‰ÒnFÚÚÍìC:ÎÅØE|(äC–‘³†‘³F¸³ÿ #;H W.–é»Dh]b9m±œ:XŽ,G.–…Fǽ=hÆ™óc–åÒÙ>PœÁ9rØì Èá(ŒïÀYüLK ð–â[—›²1C Þ‰yšHŸ71äû}@ &¡Þwר¦ª}1%XI½U³å/©À,Þ¢¼¡l®”¬ŒÒ¬œ+c1™ñÿQξ‡JÔŒ$+M ³“7=á½Æ¯ðÞ¦§§jþô­!W´ø”ˆ4íû» l MiÂRÿe0öí˜^xóui›¶|ÖÖ«õ^^éÔ†-¿¬ÕŒy:)ÍÓ yJË×™fUÙnõZÖÏJÍü¿Cú˜Ë|Mùé÷!jÊ­ð9C1£)•t Þ Ò¥z¥Ì‰aùtÝ7(=Ü'MÂøBÎd]s²Gú\ä‹b?ò~ÝÖ…*ÿú™Ú?ö½æ7÷^Š=J}ñ’£“aCŽôëÍB-g]—ÕêA2'­U\Å¢]¾ÞÖR©ú®+öåNÖ¨ÇE–åJËÉvbïÎ.èÎ.ÐØ7ù÷ÂüRz%þ÷ÁP²¦9ÎùºLT—“à”ùD1HñG§¼E^ç³üìá‘7-°ófGu >N¢E˜oø€r[yKš-ްÙßÂßÔq¦+ ÊwkC•«‘-”NæîqHê½,”* Ͷ‹Sëeo2‘g£íoŒ6Ê*ý®¡,çÁaW\nmyìæ©ÿYc Õ±è ts¿S˜ ™¸´ÑÙÙÀÚÙ/ž0NB.2MóKYe£ä™œ©í®Ý I T½Ú.z³ürÁMèë•H™4M±nëïhK­µ1…q¨–CäÄ00M¿âÔWj?ê¶B¡]È#àÞ[µ²\ºM¥€|½¯×RËf†ïÛ×u)P–3õ^lüö\iîbÛËj¾¡sQ:ªiQ@híûo%öpœ?{vâ0P9PüY?xÏõfýàíëåƒk•†wx+óæ*påkâϘA$h¾=Võmdx±Õ –Ö{ŸP‡£8é[£A`4éÙxX€m,R‡BâÍ+0Л°“¶ OwÚüñÒþC)8i›=Z3|‡Ô¼QjZ¯ nÈÚ›Aö¨¹õJ †þª’:ìªãfhK€¹,Å®›Œm²fÅ^šTƒëRÀì-‘´…ö¨]¾Õ¡ ¯MðÚUq¥5)…{÷øÛOù‹ ™ endstream endobj 874 0 obj << /Type /Page /Parent 1714 0 R /Resources 880 0 R /Contents 881 0 R /Annots [ 875 0 R 876 0 R 877 0 R 878 0 R 879 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 875 0 obj << /Dest [ 1046 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 98 590 139 604 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 876 0 obj << /Dest [ 858 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 468 404 490 418 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 877 0 obj << /Dest [ 792 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 452 167 473 181 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 878 0 obj << /Dest [ 858 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 160 154 181 168 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 879 0 obj << /Dest [ 779 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 272 154 294 168 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 880 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 881 0 obj << /Length 3079 /Filter /FlateDecode >> stream H‰ÄWÛnãÈE^õ =5‹Ã;)Ã00ëÙYÌ;zÊ8”زH¤"Ròz?$ÿÌCNU5/¢'ž§I`À"›ÝÕu;§ª~ZÍÞ­VòÕj;óåá?Q–¹^æ%*]Æn’y¡ZfïšLmÞã©fSÍÞýòÅWOÍÌs=ölf‹îñyöUÿ%w¡é'C¿VK_9[ý:[²„¥J=w™à–0sO.aË¢§8Qÿ °º`5x~~vÐõuC·º¢q¥‹GÖmìÒŽ%ý¼šùªT³ NÜ0ñU˜ºY¦ß"£LÌl;ûiÕ;#ô±Å»öÆàj<-W§€E6`‘ëEعa˜¥J^;§¦qì¦ÁÈ«^Üyµ ôŽ RwEÞæíËÑÜߪ‚—`!Yµ-«²-ëJÕ¼ºulT¹Âk¬é¯·0¾q$țIÕ+,)¹ÅüN/_Ôz¨«6/+S¨²ºe了ks5qÓ.>”0"BŽ÷¶4Nâfú~ªÑ‚Ï’¾!ßd½o2«D^©(":ÄßÓ!ëpnœ1÷7rj¸4èx逘TŽ)g‘ľ§?mÕ:o ¡ÔóË&?sUŸÔ6-õ…‚ëM¾7HbvP~šßª»‹³Äº95Ywõµ¹ìç ¿™éæONLÑv ¸Ù!ø ÀÄ*ÁKj~(¦(ON„+éÂñû¡.ÈÞ»ÖRÍ S­|.«'úz1ò*߀MÜ[W¯vv€ì]&:†¤#ËZ&¢cÐë˜@ÃÖüÞ’fXs|dAy ’³k2M_Hƒ5˜ìzÔw{dá!?Þ+¹´vHžìArŽy[’÷C½i¾àu¹/Û"Ú)(AVGšà¸þZŸÙu`J0Œ|3J~wõy_¨µQ‡ú`´5 xG¦Oõ¶Ü›{UnÕ±–ÍôŸho1U-è M¯÷æÑéøä dø ñU¿'NÐÛS 5¡^}MÐðqÉÛÐðý!ßãºÊæfÈqRcŠMÂzSßFƒo#ñíj¨´ù!æÜˆ“ ƒ|Xçª#¸×‚¦UàÞ®ÔZ–¸V!¿NfkN¦Ú@JÓŸoÚúdTÞ09˜ªUÛút€œW^&cãÁîX”|¤œC„QsòÒ*š?:®z•FßôÂpÁa¾Í°Ä#]\¡æäæ¹(_jΘ¡¤bl`Ç\å(CßF•>«\–Œ²¿Dî™þǹ¼z/nmÔ?Ú ³rA:ÑûOœcmÉB鳉ѳ®ûZF_æ×i‰3¾|‘î€Ù‹SèZØ*%ÝkçÏ•8ÆC³) Ö!3@Ì4a¡§ ÛábNü¢Õ¹*@(Ï»r³ãqK¬sË‘¹e›Ìž ¬Z³ÿdA.âÇ~­’×6 ZËE§ÖAñ9W}E׬?k$ÅtOð‘ ø°=”ù=?÷€‰H?P)÷Q7 " [ÍŒI×/uA…‡ËX. 8?GQf4$ ’ú턈mù¤ˆŽw’PŽ5 ’RÜ@µpÞ"DS( ø– Ñ ã-—-»„!û#‰G¦9¦5ø¤Þ:h!SI–m½ß×ϨS<Ãމ±ÍÔ' Óº‰¥HÒ‘¡¯ë æ ¦t G®¤‘x@MD‚¸êÏuK¬ žÃ'»Šx#]4Õ¥|ßÔä¡ÛBêÛš¾RæèŽå»\õ'íÈ«¾ÍվϠ"3G)f$ Î”-×yzÌÕgþLmA¢?ÿ¼àýÁ ð&k¿Éü!½‚àÏç¼&8 ŒhJ !>–·ÎÚÕφ:ZG%á£/{~!¶Žô&—ï·s6Â8Q|}ux5ß¿.ÄdðPÇ|[ÇLtÞ—ì’G#r%¸ð–ä…ª\}lËCùG·™ìB7fÔöË‘¿Xâ ˜ø` î)™ŒRý$ûþ+zt"{Âíél¡ý•Ì7ã†{˜8ƒpHc'¥êG´¤À›@í …¤Ï"MÌ´—‡|ïpï"ÅØé:4ÄLmGcšþo*›ÏSˆîrÿJHè&S7-ºÇo"øÉTæTnÔçO€Æ‡O¿f’Œ.û€û¥ñ˜QRCS¾hiÊ”õ‚Z¸~„Ú¯zsF#t°ÍOc cŽÎ¨ª[ò-è¡‚ò²Q©"±>ýÿjƒÇ)£©ožJˆ—#:ý!Qf¨wL½£;*"‘ Ç'ZóŽŽrÞ"›%›Îå!9Ðʃ}¬-a)÷ît– @ìVqj€*JFÝù¡ÁT€‚Ê58Oª‘ õ™q±/ø­£åˆ$]÷þÒDŒ{ˆ¾+¦ñCˆV"“ˆ³Èh q¨“Þ2}/å" ‡§šM5£v;Çïoó»f.Ñ(÷™gê<ˆ—Ù6Ê¥„G§ÐõI½óú[27ˆGÀÉàdr 7ò¹äº |Ò—ÑØ÷hG)cÐ DýhÓ?"³ÅkþÒõ £Øô-6í¨x5ü¡¾.…ÖCÍsàr˜‰÷Iiy•ÜWv×2.™Ñcfô©f[³;n#8ô¥ÔǦÉz¯Šò›cª°Žg ©ÈÚM»¹™ ]TöÆP‡–ëܪ—ú ÷„x_ï¹RŠZõ &RS®c 5À”,ÕSÃì Á&Ï­ Döµ]ñ•oì´ÈʸÐP1ËúäZºßãFÉfƒ@@G$ïP_JQ²‹ûÂupùÝ9ŽbB¥7·#wôGª#}ón8RwL6~h‡Ú í»=öæ~@µe:Ð6„Yªä5õÜe†ø !&;ŒImŒ˜…=N“Á Û¾ (BiIS@‹€¤„[uä'òäRóW9JYž!»Zèñøq_6-™-Þv£WE¾gën“òÁ"@ÿ½ƒ®$Òm{*9”ŠÕˆ[æÛð›5Bs} ÄwZqiœTVïŠ=¿ƒu>ÊšS_FVÕÐÇëù “Œ‚I š1³4¶ë‹©Þâ(‘Wl±ÅÈéAÓñ/Õ÷ëÁ÷ukDùHzF¸!$põž4qQËÅK&:Nð>ŽpÚ#áù\ËYMDî,h2šÒ¹9É>ËáŽUð:ˆ£Þ†=aboèh=ÛÑr“ÖæOÔŸ[O¦,Å6@Câq³;E8ŒØÖ¤,Q%Õû¾×kú°pLý>Í3Å\åU¡æˆ\L¼J‹{| Åi®^M0¢jÜ£Á&E‘SÅG]›Óo i¨jm‡@šœÛ²š\Hgl;jO‚9‰¢z9\:ñmn7Ùþum×ÉMueYuìâoz?x£ ­¸àì¸N¡åÞ¸Ž0èÔá<®U¶8e/MXÔºÐìAÅ u¢Ê1‘Õ²Œ×£-I—²¶rö/ˆ,WIÙTrñ$ž»ëPD'ìA+‰ê‡mSþÃxì& ÃÐ;_8õ”¦%IÓ©p˜Äpã4iì´iqØçól'Y’± }±Ä~ö &ã™Ê–®»8è•ÉjßPé3+Á°¹Ó18…ìY‹‘Õë‰WŠÐÂ[nC,ÅAçÌ%Ë"=ÿ!‡È”Ssøyûº|rƒ±ÍK|JtIÇóKÂ$‡ÒðiaNë†ò°ãNôÞwù™¾oöìõp\yˆKßýÀYŒ;þ½žWÏQëj °Ý·ô5Uó'pŠkpœÉ­Ëøëq6z1½Õ–fo§;å´ÌÞf¢¦†~¶G?›Úø‡23»TÄØG÷tà,|/‡÷'•èHÚd‡ª?´Ž˜ 6ÏÐèᢾ ¼Ø¢³ð\óñÚX<ÙÁ½QþןËrVFƒ©uÊÕÒYè«—QÑôO0Ę€©Bl¿4­Àwsùº endstream endobj 882 0 obj << /Type /Page /Parent 1714 0 R /Resources 883 0 R /Contents 884 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 883 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 884 0 obj << /Length 2117 /Filter /FlateDecode >> stream H‰ÔWÛnã8}÷W~¢€˜)êÖp LgÓƒL ´Xìô>(6kaË¥Äùù‡ýÇ}ت"%ÙŽèì`bJ%VVÖåãb4],“l±IÅBøƒe"Ì„¥y,’,ŒØb7šÞÕ[ÖôMÈêe5šþøU²ÇzŠ0Äo–£I»<Ž~á-‚I$44ø«8Ë þ¹øi”“†œ¥¡È°e" ­R H®âĪú·‚·‰„‡{xe__«fo7hâuY³~¼aÿøO0‰áù²Xļ B¾Üܰ¯Ç²ùÕ¶¤$âEµ &9g¿ÑFǧ£©P$ð°ø ¼#ÇãQ‘¼F«Í‚j0)`Âé–îÕ†4Ý/F’•l¤âDD‰dQ*²Œ%RhÍàŒ:c3Z>.:gD> Ͻѻ:DÊÅ¿FÓOò2^.rdç"Rvï/|¶*š¢y}° WÅÎÜŽ«}cÆöÅCQߎó½Ï[àYÁ—,M%ü2{ù]iœtR­4ÐçT‡™PÚ»ýqg›¢CB ôåæA1øº÷˜ ä2 ×Ëžkç­ui¶«mY7ÎeÓ7î‰c<ö Ü#RxãŸaTêæPVs Íôi[”Õlzò‰p‚E+¡¯@{ÈLĪEòbu¹¯œUÊlzþêˆÊDv ‰Gîjäu›mY™]ñtŸÛñ׿}üéþnñ–¼póUÖJ. 摟+™"$—ðuë“êy‡P깜M»õ…B)®qcXì1žÂ¢ HYmL±2‡ùºØÖf6ížÏ$˜Á¯Â'÷@H´I ¡Øn÷G³{j^çÍá0œ¼¸@‘j4à‚O>L‡$Æ[SG‡K“I(²+ç{ F‰ÈÕUþ-îÿþ–|‰NÁعÇùŠà\’/ô’/‰È“~ó¹Ç|˜c]úôƒú‰º¼÷ȇ!Äy_]/ýÂë­ßù0â Ê{òýâ\a¡÷šôÉÏL¶åùÇá®´mã8:·Ø–h±ÐîkMiiEYÊìc·QöiÜvªiÛh†±m󠕃ÂdØ®¶Åoþ½Ü‡.-_±ýŸ¶¦¢VÅÁ"æî[ÛGžÌ‡^gºk8„l1H án_5PîÍŠ•Õj.SÞ©uNIàb¸öûå®õVVE×ù±‡šRèuA¨©ØÈ±yÄÔ"ôÛñË’pFì—Wã9œ’–¬ÕdÕ€¾âR‡“€’ fÔ£.ðÐ d­i«olæ—nšÐ@&#<” NÖ'sž)*¶´Þ±Ž‰ßq FµJ\€1’]ƒTN"Æ *>ÄêÐÉ„ÐY¥?àÀ¡y-ÑÃscj|”1JðÍ;‰ƒ¼ÚW†¸|ናÆ?ì!ÐFÙÎQg±¨)ü@'»bÍž­ÌÈÄš`’Ä LJâxê¨æ0á Õ:Þ%œ-Øç†¼~ØoÉé0hÍ6û#Cz µ²jÌáé`0 ƒU;NõÇ@—õ€¥üh*sm ÒDÁîÿÆ Xhà¶loá c1ß7ù1Å„)r‰ÏÕŒ•K±7¦J.vyÙK[pˆ -»=€M ›cÞ`ƒáÑ¢>G ¹ô,–*‡¶,|¿XF®Xž §7l—0–EXNÇŶZ~ùüåžQê“…ÐQŒ}€Ð2ì«€ìÑw%ÖÂ[a´×í´òÕUÙ—TV ¡ ¼¥(‚Šr…««PUwe@5 RE !´W+úCŠŸÅ¬»ÎB[èv¬M¯æ5˜hˆ`¥_VØ¢Ua…–p±_œÀú¼†ú!Å ““ê 4kö“úIü9Jæ@@¸M€±4.ŠXBí’ò¼xv’¶¢ÂýŽx`CÁ¾ÀWŸé–âêÞr¢'xÁ¨9‚»Ä@V:ÖªÚ“}”t—™c ¶ ÂLÍ7®ùr4c°Kã™ æà·Ý”ÚrÉ€–Dȱ-q¡-qüFýC½Ù?oWPOm ±¯¶¯l ÕÊåsÝìwt²z ^ÏÞ6n]2AL÷Pë Ê±ýœœ°­K‰òƒ#Ä'é.½ˆQµÒçVOîg0äűJÂE|Å7cû œhðñ¶sÄœt÷•Ô9N$ž¡Æ/ÅÊIý•gû;âÞ¶š²RaªoË“Ìízë°ÙôDr>sÊX›øÇ\ŸÜYØtíÔåì¸0›ž¿º€¢ "^A2,’'"WP èo)ƒDy:ì×Ð!™Ür<}Cœ0EJvÆ’Ëàzäg`²ÌV1ЩºM»¤p~ø>V>¶x…HT+ôótxóu©³›“›½<õˆÿ;÷4ì endstream endobj 885 0 obj << /Type /Page /Parent 1714 0 R /Resources 888 0 R /Contents 889 0 R /Annots [ 886 0 R 887 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 886 0 obj << /Dest [ 885 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 429 598 459 612 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 887 0 obj << /Dest [ 885 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 485 279 515 293 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 888 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 889 0 obj << /Length 2398 /Filter /FlateDecode >> stream H‰ÌW]oÛØ}ׯ¸È H4¿IŽ$›.¶hºE#4‹Æ} ¨+‹ŠTÉ++ÎÙÿÐÿ؇ž™¹¤dű“b± Èü¸œ;wæÌ™3/瓳ùZ³¥×óI *5 “Ô‹Ò@E™—ç* ¼8V8cœ«NOV“—ó1Q€%þýhBíSDàåüWJXl{~Œ±Ey¦ävj–$^EÏlT±ŠÏ¿/vsC]~ª¶[½\T ß/ SðÅ• Ÿ õº)µ>[V=þ»’ U¿ÕeUÔ6v^E¡ša¹d9Ù5ä]eòÝl;Ý÷z©`½49¢üÊ}‹òùº²TÞ£HÔ‚)‰ÁyÐ@ P—;‹ÝÈé‘Vj­Ë%“(3/"8vX.b݉ÃËvkªMõÉ6¹{ö8jmö­Ôîµ€Yf1ËÅžŽ—qfÁn…¬ÈïsW]ÈÅ NÌíVo d½§~–/û,»W+Sî7bzÙZ’èŒ> ,‘`1´há­n–ví)ø% Ɉ+ ®^w·ºc¬”u¥CÀßm·mgXÈKã;Õ‚gŽï±(åNF7sŒëK4¯ˆ½ßÁ1ÅG†¬º=B ·Â/æ(]J}_®õF{2¯è~èËC1ñ!¨lê1dáqûyW5KÝ›vQÕZÙÎç¦(?BæÏläð°žjŸw9’ܶʤ÷Ã=›``B=CÙרâ‡9è½{é³3´ËÙƶgªÜõ¦Ý0¦§Coé46ÕŒ|#õkMŒ¸ªn§{[ð)˜hd‚^íu]Oäo_x’y´ÐžýÑœ ^zß2BÅaD#ÙÑuÀct4B%PH±ŒPÒ”©£Kò¥_¨W-¯_ÊÔ"ø°’ÝašJrž¦ßâàÞˆ#ZÌ#ÚAßIñçÉ(Ê2 §ßá@}QòQø{DŸC¼Ùm =ßóοfù#Ç Ó~û cÄIrôfkîxSœN>ÉÒc™XYqIrL.·"Kô ÒIT‚zX´ÖjPÔÙ PåüÊò±\¯ÿyÓŠ"ù)¦Ÿüzª‚çP_Þj#7#+LyÊÃAj——…‡™18 ¶„ÏŸ“V÷Ke?¹ý%ç‚ñh$cgJ58JVÔ²b^»“'à„ýJ‘â&c Xz"fºb‰AZ?æ…ÙÙÝE#ò¢á:¦±r‰ZÓZ1­º$cñãÚ=ˆ½¯¡î0F'©;‹2>¢îT‰¸”áe[ ­ñ0q^ÔS»F7¼¦l—š/–äC*—²ÀÏhÒD’tCh‹ä{$Ýð; ÝôI7ú=I7HÕc忢mk ;·E½£‘‡dñWt€?”~£ÿŸ~E GòÕ é@ü{M_Â㔋£G¤ðO++ÆI‡®j°0nzmX¢u;}¤D E°-H;5âY‚†,ÖuS”ZŠéÁ`f º€la°v·p7YõÁ§–VOÑ©Š#I]êzj“˜$ØXQ¾ágÆ¥ÜÓL÷wŠNäüéþ;*Ì1JhYSÕ¬qe=›BšË5=ÛÀ–GbKBƒ™OËüÇŸ1ãlH1ëÕª*«‘PNðç%&à’'@]˜lDËéPg½V^t&ƒ„ä7<ë¡û-ˆÍÊzwx1S"éñ~‡ññÓêɾ$RžãÖéÔphÎ Lñyƒ…RÆXß½üSÍOŒ¿)zR †éЦ_AùôkûÁëùäê¯Ì endstream endobj 890 0 obj << /Type /Page /Parent 1714 0 R /Resources 896 0 R /Contents 897 0 R /Annots [ 891 0 R 892 0 R 893 0 R 894 0 R 895 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 891 0 obj << /Dest [ 898 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 374 220 403 234 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 892 0 obj << /Dest [ 898 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 142 207 150 221 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 893 0 obj << /Dest [ 910 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 278 207 313 221 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 894 0 obj << /Dest [ 917 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 426 207 462 221 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 895 0 obj << /Dest [ 922 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 166 193 202 207 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 896 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 897 0 obj << /Length 2272 /Filter /FlateDecode >> stream H‰ÔWÛnÛÊ}×W ÎK‡€Åð&Š INäÀNj¥§hÒ‡5’¦¡HBYv>¤ÿÐìC×Þ3ÔÅVííC‹ əٗµokÞN¯¦ÓDÄbºĉˆð?YQ„Qåb<…y¥bº¼z×¢ìxO$º²¼úp‹e7ˆÂ(¢=å`Ø?î_ä¯*¦a&—š~)&™þ:ýe0a 1ŽÂI-iæ‘S–EO£Ü‰úG‚¯Ã$ †qæ2*ÄìAÜ>Ôv…/‰Ô$ÉÎtâ͇ ñ—ÃÞ7X…#i‚H–« q»3ö»ÞT,$•ªžÉç¿l»Ï®%Q˜ãeú3¾±»Ý. Ò0–iÕ¤¢¡2ÄcïJÿiÅ’ÞO±0bŒò0Íc‘ŽÃ¢yf™€Y!6z°¼îÁHcl‰NÑ8@"°rú·£0õøó(Äÿ€QÒHOd>c¥ !<•7×¢¬Œ®­X4ñ›©çÍ®7ÍÌTZtÛ¶m6VÌL­6¢UÛñ>½V¦ä®TÖªrµ†„N˜Z@tà0aáv>)~Rm[™2ÈÃRLS¿º~7íp­»N-õOâ«„„¯(·mÖÂ>´úB VÂqŒC+Ä:—z£a’fÍZ·°»lê…YöæwX2š±ì‚‘ª;61íMtH‘mr§«*dˆQ™¯‰,Œ2 …iZŒ…{íqÏ'q˜Ǹï7Š»Ð? ÇB*Åå¶6e3×s~UV]]<ŽäåÌ,u=7Šj¤ëÕkñ9@:%üƧàŸ[¶@=“@ö¶ëwo`ž…£äÈÀ¸·Ï›÷®©­2µž#Н=Z{±¾-äÈ-_ „×xØy9W6È`¥ÿA¬‚ ~¯h+ž8dQ'³E_ä›;e‚Í¢R³€ª³ P+R¿~Þš3 ¶6Ë•uƒÖBAl“Pí®Í(HX…üËeU‰Î"µÔf.ÚM3ß–¶û÷6sÊ8UÅ>Ì…ÇQÕ”„¥ƒqôŒñho8=’ŒYÓTrîTµ¥TG[{@wu °0Oµž†èÙaÄŽ>rï¨ÕFç’uï>Ùð1 €HÙÉQSm ƒ¶C¾¹xJém/¨%H¾•KpNêÄBêJ¡Æ3ª$:&4]tbTY.m@ç½ô^‹·Ü²`÷ÜkE+¿ñs¶8¦Ò­QkAÏ͇MÖ™±¢\yEªžk™ñ¡èb_tNw£r‰Þí^”W¾ò‹p éýyŠ=¿'m…,ÄneÊ9‘;Ïéü+$×%Ÿ›œ¼º¶'2&:þÖK±À†X6ØK¯„ç?^ób(úö yì_‰vÌH”G(‘¬Ø?[êçÆÙ™ø—ê$¼ìÃgÎÅ—"x–xËOäH,—â=uÿZ4÷¹$ârÓXÿ±©”O%ÿ‡ sñ†—nYŠ“(\9ÁÀ‡$§ ùÆ}Lr“ë£3ÖVúɤtm/Û·½Ìy¿7ÃØð”Z*›v}ûV, 8XNÔ ÊR²#<lrÖ–O¥é®,Íqr¥±Vß´lêêA¸g†ÙàßÜßÞòóŸ ž1å 1FÅ”¿Rá$û?¦Ë|¦sBÞ²Öž%íurx×~ó7ˆÔÖٸ핣œ­‡Ýð<ê>©#j4¡b9TüäEǽ¥ h(kbL‘ª.üw¿}m†]íÆhKl ¤h ¿pûDe¾iñ©ùfÔïü—?ÝÜ~@¸ˆÓÝÞÜzyN^]îƒôƒ,(ûŒ²ct(“T€¿ A/MmlWnLk¯^ã úˆžDÄk rÒtÌ =jÄù0ýD»V—fáΔ‚eñ²%ÞÑ3`šŽ CG‡Îîú?Wå½}4èž2¨ŒîÑÿ ƒJÿ ê1gõÍ©÷ëi0§òâNo:D¢s÷sú?$G,#=B¨+©…Œäc+“­ý!‚6ÙÛ0ñ÷Î7áÃN’IgLþ-zZ¹s&“ègžTÒ…ESÏG¸ÆÈÿSâætôO;ÒæêÎ>¢PÉ£B;âQé3stʃÊq¢SâäiŠWnDA©ç0~§¾×å–HNS—¼ßÍÀæ)âNýÕ“°÷á땞ŒO>êg¨ëñhAsÑ‹ç>ëç¨WSjsg@LüÐ>%˜–X"õ¡pÄÑræ#çæâ™ë .5Û6ØFP¥^ù];·<¿ ¨ZàaŸ”HÇPøqpÂ+º• rèžéDÛt¡«å(ÔµètG¥OªÎÒÀ§Qì!sã0rõq{,¬‹¬Z]Q^qÍ3†¸Ÿ}Ž1ª²«f»\QFìLU!CÑàC Iöí5ñ®¯›Í•uFæäd¶v¯]ˆ¾½¿›E?Þ$}7ö}×1SŸ|A‚CðíbOˆ´•Bàêv¹„i<×e¥Ü~ÍAg*ÞO@EŒÁŽ8ó¥'P {±¨—ýù­ûÊ]€Ür:ܪhÝoSú³î¯“H€ƒì­ ù³ 5>$ÔØùK¶6[»lŽ£•ñõá’ß5G$ Iu‹ŽW]ˆKv,¡DܫւiÙ„Rýra*F-3v0óŸu^&6¿æ‡Xå‡áÈCR¸èe¯Ÿ¾A?WÙeë IÜJµ[u :\Éógİqìúß×  ¹»Uî„~þ¼#àljD%¸0q¢œ»«œÉ˵v_ú¸3l±Ï þƒÊø`2éeʤ*YÝûéà_n?Ï7 endstream endobj 898 0 obj << /Type /Page /Parent 1714 0 R /Resources 902 0 R /Contents 903 0 R /Annots [ 899 0 R 900 0 R 901 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 899 0 obj << /Dest [ 1400 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 256 517 283 531 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 900 0 obj << /Dest [ 656 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 515 333 523 347 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 901 0 obj << /Dest [ 672 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 437 319 452 333 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 902 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 903 0 obj << /Length 2932 /Filter /FlateDecode >> stream H‰ÔWÛnãF}×W4üÔ,¯50 83ž`N6ˆ,Ñ>´©¶ÄX"’Eùý‡ýÇ}ØSUMQ–íñ Xìf1‹—fuuÕ©S§¾™ÞL§‘ Õô~F*À?ü$YæY0RãIê² VÓõàÍ»&SyÃkÕäåàÍ··¡Z4ƒÀZ“†ÝånðIÿ`¼aì'zaé7Òj’*ïïÓ¿ &la¢Æ?a—8óGlÂ"¶EWéHLý3ÂÓaxÃ0öG:ÈÔÝ^ÝîËv‰'‘¶,é¦hÔÕ·çêçyÃ÷5Þ¥~ª /Ðùò\ÝîŠöw[¯ØH¬M9÷†­þÁÙ1>>- ün¦ïñŒ=Øív¾û¡nhWKÛÂ4¶ôqàt¹{´dK×ÓA¨ 5ˆÒ‘Bý,S£ÐO…3&™ªíà~ðÍôŒ8Ä’àq4úPx9ý…–¸„%~`AâÇq6VrÛuœ¦þ8:ŠjvQí¿'/CŽÔEQæÕº(MÎ(x8m±á»öò\]TÛvQÞØë§ËÚË·êݶiñ:ÑÕZmŽ_Û¡‹¯ŸÄq¤ð, Â1EW<˜uE1òÇ™â©|~17­—À;÷³ßX;êK»eúÔÁ!›¢xD¹=ú¤¯>›Â‹¯•¹ó›+!ÒöíËÞ û¢;NiQª~$øÇú¯ê³­›¢*U•«ýËîĽ½ì`/s!2¥Ê%L¡ô bñQ„l“êºð†‰Þ´¯„D|˜|˜ˆ•Û¼¾Ø û[ë XâÌè•t¡¤”ˆ±9“R¬[GN-²Æ¦_ØàkŽŽNyEñ†¥¶.î¶-ŠÛ= ±Ñ+2 tY•¶+î/ĦÃË{{o¶«V‚½–‘£ò“ÇØ œÂ1¥-OÎN&tœ@¶ièB:õF8ïkœžn¬’_ä?ÂOú˜û„y¥Œ<µÊþfsÄm®î¹Œ*6$/•†ùj¯Pm†K_ý²-jkŒ|׺•jnójN<žVŽÖ(»c½àúK3-”7tÌ߀õÀ‰ºÊZHÐ.gžbð¤ºô¨ æäP«îì}UÞcmcÊ–Gž0}z\B…0^Ì=nloä@ TÃ9aÛg6Íqö±Î«Z,WlÜ–Ççè³ÕwåÐ1„xôƉâ2B\†DŽBr¦bMÄ÷´<£´Œ8-mIôg¨|.}õ$†¯€(íÝJ{E ¢L@9qg°17rœ_1€R,"_6+“[ŠE¾•—­£ ¿[9V‚_ò‡,Ô†ìT¹ÛÕ¿³`„Xï¬-!ÂV÷¥Y1PcíìÙÕüÉù‡=ˆŽ1´*€“ÚnjÛØR’=Ñ-(šr›0œBÀ‰\†¸É¿»QónQ÷‹xûêûªÅÁ<æ—%Ô½ö˜rÚ%¤PÑ·ÈÐC„5éQ7ËŽX¬¬pð sIèƒÑ_„}Þä«ÇÑ/Ö›•]ãh\bw¦ñRâ"®o #Ôhv‡QoÖ >ÊB¬7sr^PÀÎÿHçD×D IJ²N^ ÓñÝ9’—‘Loå‰åˆð¥ê~‘àÖQs¢_´N†õ•Ý*yiwò[´V¾ÌÝ=ŠRÑ.ÆÅy»0òeËBÑwVHM´™?K7Ï”)ööŒ\ÍIMÒ¦£cZÖV²Â^RÁ \Œ¨›°ŠÈ‚™çÐð5ê1³=R½ÔÔc@Ÿ°.î‹…“ÄaQ-±ÇfCŠp¤I?ò^^ ß8j{Ë •´ù!PC¼“±òbù¾>Ȕѓ„Aü¸Í;;GH$Pq¿ª“%3úªÄøÏ¥£ÿ”Jìg‘ÃX‚6áImÛm]Râîªjea÷³Ym_ÖFñÿƒnŒþ7º1þoéÆèå–ß×hß:¤°ôߊvIDÖ€wåæœZx‹RêXÄ“AMYV$²úþ‰ŠÜ9ªi12š’¾jˆý@}c¨¦gä‡lØŸ ªHƒmi`"y_}¨j(TC/ΞZ›‡NÒa(¥ ¢MQ“‚0`97æn =ªjS.¬Z¡ÞÇ¢ùb½.Z¦fúŽ<ôø¸«ê¶mž*)J_¯F胣h¯sVhpÞl6Ôƺr¿…ôòMI )&;cû‰´—X»ÇéPîi%:Ùão¾¸~½•פÆÇº¢dhæ>¶ÖEQ¯UÏÊÕ°Ñ]U;n['`bàÿ‘Ñ„O…½»sM\,^T.E,@ F”ªÌ¹[Aôtã†,Ù‹2w÷VîåFþŠÙªôÕGN¿_Ö4<˜Ò¬öN­:/)PàúÃX³q“‘4¬m÷Æùø• ÙæKeu;½â&ééû«éõLÏ<À Ô ¯¿ß=a8Ü~üùúæãwiºÁjYIæ’Ä‹àzéø[M៮Uqÿ|ªŸ&‹EÍiо˜žõãAÐËÍjõê$Y€´éŒ’kŒ]¼É*¥Ø}`æsîùœֳ .þÒ¬Ž3\æ’Ç•yäÝË3ÔÞž€cjÄ€GI›$ãÎUAý3Xt˜»„xøpÖÜñ½ ‚Øä‰ügéÝËnš>‘â–¡5tC‚Ô¤ïºé"á\%#BÑ@í Jý,>IòSâj—•#áõ¥ù ·— Jò[B‹P¨SG5jçhÈJN|äÉ!·²Úv¾mùÓõÌ#Éi_Ä®ÚèÌ<Œ@"I&2pƧ­’wµýu[Ô.‘NÓrõ‘èlð:6hê§|б/ͺÈÏeMÖº[èE1'†©%ï±â>u_£í##7œÑŸÎ0Ç> ê, ¤ãÅÚ©¢}ƒ"„Ç–!žog½ø Ó®íOÔ611é3}]oQÆ‘^¹^‡3}Ébù‹¡BçLäøÂ(©èþåF¨T.d4µl×Ètt²ð™,Þ}E{´~`‹8$ãï•l€áR¾È]¼ã§LžØÜ…欗ÒÏv¸ƒ(ãŠ0ÂL?NB-7]^q qŠ*-¯¨­¢ Q-…–ÊÏÖ#IwÁ`âþêA12)•ÆŽQñ”–ç²'Š`@£Uaæ»:LP‡nÿ¼’ $»÷Ðmâj«æçÏ—ÑS1-9$͵v‹¸~¢6j¹]P‡EP'ºžÖ†H‰½·µ¥Ë™ÞNz/ªòªñšKoDºš¼§‚¤ õÔ½ š<Š˜ÿ’äHöžÎF zµBM"s¹Å¸t@ÒMÚñÇPL=JxÔƒ=J{ív‡8s+!h7À™Åf'Ñ4@1¥ÓcÇ~¸4sä‹å$%Íza¢óz1?‘òDŸÑѸpª¾?ifda],–-ÁaÄ9T¿na?Óà|ÕTkd¡®r*|H^¢¢ùS[]¸®hÀ èY®Íeç×pÑÉ{áëP( ž{š¨y!½íÃÕÍíõ¿/›a ï=…KJ‚$Ø àÊzbJÂpçõ÷^§`4Æ-C™ÿùºO»£Ý Ó#KÅî&ËÁ…¦1Ãi¨È<¿B Œ³–H$„¾²ŠªêÞ½Q@ñcÆ'Öe”U&Vòjí¼Zæ ` ¶ãN{–“ª8ÕêÚºA‚UçT«W+¡Oúh;R¼2•éX›z`¢ ´QFr­˜¡AéZû£ …ˉ–(„°¬E”OÂBþïÃcÂÀ¤«iùàÿW:ÐNÇäµsØÉÎÖ”:ðáB‰+}ÔlgûH’OD—ʼnáŠ4·Í ë˹ endstream endobj 904 0 obj << /Type /Page /Parent 1714 0 R /Resources 908 0 R /Contents 909 0 R /Annots [ 905 0 R 906 0 R 907 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 905 0 obj << /Dest [ 1074 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 311 650 352 664 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 906 0 obj << /Dest [ 672 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 208 637 223 651 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 907 0 obj << /Dest [ 1074 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 323 557 365 571 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 908 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /TT2 2104 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 909 0 obj << /Length 2928 /Filter /FlateDecode >> stream H‰”WÛrÛÈ}çWŒ÷a ¨!Ü/¶ä*Ù‚&²âˆpª²¦+C»  sål~#ÿÌCº{ Ðn¹,è™éÛéî3ï¢Ùi™Ì`Ñff˜L‡ðcû¾¦ûºË¼ÀÑ\_·Xô0;}_ú,)iÎÊ$›~X쾜隮ãšd6¯÷³/ʧX[š­Üsü5¸LýýyÐ ót-pA‹åk®.”Ð&…OŽ+Žú¯ _禮ΠKsÝgwÏlùœU[øb*\…“”2-ÙŇöÓÿÔ¹ïÈÍQRUW’í [îÓê;/vtˆ¥ÄÙZ ûý%ÃÈ}rÍÔ5^¢KøFì÷{Mµ4C)Q+Gµp4¨ÔàQïùiK'…ÑÌ`)›™Ž«Y®Á,Oó}æšm3ðÑöYÁg›Ù»¨ †eÀ½C¨uŒXýÜJS?ÏÕ5øO[ÄÍ V ý˜ÿ_øm9Ûä»]¾O³{¶yÊ’*ͳ’Ågñ·8ÝÅw;5Ð|…³4cà1[Ç• BàÔ¹ á­žU´@ôáÝSX’gÿµby¶{~]í°dLa"àθ£E¶S‹f'`á2Œ®TÌãâ: oÕ@¹@=Žr­ºô0å(+–˜b€êïy¡ÚZO •¥yºob¼LÝd`À ÌŠŒ1ŦðÆ»]7À&ääh…QlX©¯¥+²„5†€v ìâ†]å„W)ØÙ&ÝU¼H³´*Z>BÈ7Š–àÄcõVc‹ð”u¡êš!ÕP¹8‡ÐJÚùÎa©!íqjsÒ⹋èç P>‡'ïZ€Ö*Iü$^¹ü jÀI^¬å‡\Z978½•uTj7èÃGÔ+ñ—KC©TÄS.2ÇÙGH>J¡øK3”5X&–åªzŸî·„ͳ |`.TEÊÐA?¯km2#x-Œ˜¶Ôd˜28YÑÀª§*’ºC˜Æ\”©èªßñ#¶>!Û‰¯Rø bIÕo•:Çþ'A銀‹{±Y~-YY+†ÖP´wÏ‘_¥H—xO©¯BŠ ß#˜!6Ežˆr]YkYkx,‚o+”*ö‰$ð®$QO¿†£Ë¬ìÒ‡´bk¾¡Yã+O» "–(Êô;gbAÉ—w¸œ”[Ê pzûmšlY"%øÆò»z!:Že*õ{j®²†& ‚q„g·šžÙ…?/§Ùex¥¢"‚Ÿ¯ ¼AvI(]rl0Eñö‘P¼ËšŽÍVu…pMÂõÆJ=a¢ rìО,Æwè¥øÌ3Ö©®ŠÁ„Ü2ð ôt—®ÄG\¤Â­g´.½zYµ”–?Öæežf¯Têeµ? ,›ãO;IûXô?Äau‚5…ï–R‹¡ò¢4EÂ*,†‚‹ù|s±\Jñ‡›Pì»ü=…nšM󤑃•Œ öpÂà¸Y|T}x[`U»4jpîdÔ°@ïU„15ƒÑÉ£#ršé·‰Aq8î TØC{^>Ùc²VXIÝŠ’íb1{ð#¾±˜e|/¤˜CiòRNZñ‡º9?G{:G¯5š'.p!#&u$1´H».q`:~©ˆth¶H¢“‡ÆÂË:ÿÆ‹"]sêM.Í'@–?>+eŸó}4eÂ"¾ÄDÈ‘ùÝó\8w¶‰M”úÐðµ øíÖð5÷Ib‹SkÎñøçzãW„Ã"`vf§ˆÇ¼~ÄMë€òK‰™rZS…¯åC,ØÑÝŽK毓MI‚{IMäzs<ÅÂt ûêê±Ý!B×眇©¯ËÁ¶ÈX¼^§ØNˆB€öËY™¡.d‹–`uYAòSI›2š¼M«#¾J©Ý•¹ ®ÐmE^=îD)ï0·O½HKûÍÛ=pÙç°[m$+j9½ÕlZôY•ìåÔba}¾Pjgb“`+àLP@”â-‚®.ôYÅ€±0¸« í›Ü#fM€@;7’¼´Öcøœ¨øg÷ü8J /Ÿ× 8¯á\žB UÃQÄ7Æ¿ñ¬*EgD/ª|Ëו’âr¸_ˆÔ=,¹9¡‡UŸfP÷1ûö>Þñl éœ:.–nkãš! ä½ÄQø[˜9ˆã±Ü¿‹\¢\áÚkSÿ¥ß÷+;€!Ùfÿt?UÚü=)RˆùÙ«/ï//¢‹/x(\}KCþèè6ü2ºöµ./J·‘Ú0 ÜŽÜÑ}hD£Û_7º-¼ç’0èo<Ámµ À1@>îú¢œž<%Ùòäñ‰¦ß=¿çkñTåâWÄ’uœØ ¤°cá°tÂHèÜzmäâ& ?Àµ’”ß„áå]3ßô-ðabÔJ€Ü›=†Åõfœ=nÿ°xÜ׈ò‹!í$`]ÜFÑ9”øUyšËeáÍeOXÈã’išÖާOågP:îžã¶òsH‰ÐÞWíš“‰)‡û–6h·ý†d}Q^]¾ûÓÅÍåu¸üë§hyÇ?Šß:ø’»§J<çÙî¹ìËwò½*ùN~[ç0bEÂr¹q Øñz©\–<©àÀž×Ž=‰¨añ”×z R«.<^‡?EÿýöÛB¤|¥¾é¥¬â¢Ž‰ÄtnéL›P}çlw MƒÒq4Yf M@ì˜.®¯W-lÙËäCêQ’g‚½”uƒÃa){Îâ‡4V#A€W©¾ƒ–?‰Ùañ‘‹¦ ¬Œ|„¡pÀlíB•>ð“?Ò &â —ëòÈj}sÃâñÄn r·aôùöæ¸ w’òG§†iNáhPzdn3ûq›Ä‘òõëÛ³Ó£©ßö¶aO&yX\oÖÝÉX‹G·³‰uMW¦© \»&b7,MµåÛc÷ÜaÂeÚZ>»q½Ù7§b7"7ÞýœoPâé1.˺»"Óò¦øÌ°tÂÀŸ‘ñ<¿º¸^†oz)u')̈x\­c4ºohzk´I™¼ Ô¤CVr\þR¾Ø®Öéfà ؞6óc ïýð:“|kD<î©M|Ë–ð½zWÊ_7—çç?„o¢jfð¯#[¦¨Ñ°t|N[V›ÕA[Eìuq #ìùh ãTJ³ÞŒ+c,?‚¬=ɳFÄž˜þ|¶ñ7i@ÜŒ¢§žðÚÖ¸aKeË+¾–ØihXC«žyÕÀSÏ-k’Hˆ§ÜÒ[XÕ8L\-sŠå Kõžæ‘^£MsVÊeDîì¼ÅÓZäµgŠ1ÉGFÄÆè>¢³(™A½^dLr‰ñ±FÓ È Ü&ìp»¥@$í@¼=ïPÚ:Àf{¡Ð§8ðtÂ,ßïde¥ÜÞþóê6ü[C™»× ¹"ľÒYP³îZü¶ç yÔõÄ &ùLjx<©Ð&© òåNBM’°ŒˆG[®é™M>‚þÝÓçMñ“aé¸6÷ÀOÚè aˆwuÓ›$(#âÿ^.I‚0½’†@•ûñzƒ™­Ü§ãCHš›'E€¤«Û— úgÞF —üÍ}U5s»ÿþ¬s»òöëʾ:`‚&ÊÁà€,]ÒEŠÈÙt-µ.®s;Zª†>ÉÁ „ ÒY‚R£Z®d[Ûc Ðß8Øoâò6ö°äalêï6&sØd´S´ vC]½Ù$:3ÍÑß;=¿2rø4¦Bù¸æTñR¹½¼ƒŸ½GaQ&µÒ`;[ƒ«ó endstream endobj 910 0 obj << /Type /Page /Parent 1714 0 R /Resources 915 0 R /Contents 916 0 R /Annots [ 911 0 R 912 0 R 913 0 R 914 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 911 0 obj << /Dest [ 898 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 307 517 343 531 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 912 0 obj << /Dest [ 1042 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 128 187 170 201 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 913 0 obj << /Dest [ 1074 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 128 173 170 187 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 914 0 obj << /Dest [ 1032 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 486 89 522 103 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 915 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 916 0 obj << /Length 3646 /Filter /FlateDecode >> stream H‰ŒWÛnÛH}×W4ü²Ý€È°ygÈØÞY’qk±Ø÷¢Z³©!)+ž™Ø܇­KS”deÄÉf³ºúTSÕ?Í&¯f3_h1[N´/<ø—0M]/õb‘d‘§^ f›É«ë.EGs<ÑõäÕÏZ¬º‰çzÎ)&Îp»Ÿ|–sån(W¯¾Y"Ô¿g¿L2²‰Äs³V R7öx2à“-¼‹b6õ_FßSŽÜXz©˜?‹‡çº_È/K²+;ñîç©ø×ÿ”Ás ï"7’¥òd±žŠ‡}ÙÿnÚŠŒ2¯Êɤøƒ~É1Ú>mÍ÷Üf70Fì÷{W®–®jpY0 KºpëÁî ;´&K·³‰¥˜øQì±A⦩ˆµ†ö¦¢5“åä§ÙŒ@Ãïj/g_0`¡ Xèz!LÝ HÁ¨I¹‰„*€fQõ,ªàwäj­RØ–x³m›Ât]Ù›MWÐñ+·ýÛ×âz×õ*Ñf#¶Ç¯ù«z%–Mkatà ð¾õtbA’ÃçµËºh6e †2¹´¨üb Ødzž•‡y™ë§G;ÓÃÆ4Û¾nê>/k³eýšÂ“Œfm²Çn23.!üù›EÞ«Bj/Ï[£`EùVÁjé 2›­9M}–ïžòRù€Q•Ïæ\¥1óúÛÞ8#™Ž¹TÖâã'Lë@Þ‹'ÓveSw¢©«ço»ŒöÆÐ§¢¼ÃÄEßAÈ‹ÆFhCvE ™yÜïÚã?ošÊ€Ý§¼Ú™!U/ƒÄv²ƒW{õÀ&Ñ1óµWN `±{ñ÷Ü G÷B6¶ ù doe¨‡8’i¥5$,ð#Ðéø(3ÞaÀRß–ó]o:|Ô䡆…¾ã!¥˜¬›úG°2èÆ,ó]Õ3éŸ,áŒk w{\MØ0á’gûó;cañN“˜iå ·¸ÿÙ$Ö,É%P]à8f¾š Yˆ¹Y"‘3Ù€(‡²5R²‰.Àˆ˜ÿ(ûu溩èú¦%Ò ´ ãFóyÞ™G5ù Óã.—ž|Ù›6O¦îwy%|Ãn™Y+Lªoæ­+hkð‡‹n«¼0¢oD¹ÙVf„Íéz(y‹[\çOe³kÝ9#ÿ!ŠèÎ# J»b-r¾-àCårP¾˜¢Gx ÃÃÈK@Ö²W(‹¨ô]Ã3D¹ªí-~¸ÛRÆN!ôL_¸J,Aw0¨;׃-?`è#þ…R +Ö+WüUa¡=ùîŠç0 4´¸ºt H:±Ï‘€h¤¦´ùŽ/ÂÐB8á`Aų“`§›¼­«›^ìxÐ,8#Ê£iÆ, Nǯ¶°-M±Oe^ÑÅ!Ižó+QràbX_(̸'Ñq`…Ùäeå‘é‡x–Œ†Ë3…2³VZÒÖB†)d˜RÉ"I´Z‚ÔÖ¬ëfO©K±Ý—U%`_šÓ 2éÅ:%6Ä¿4Pa…ÝÔÎŽÁZ6UÕì)'YÅrWÎÅp¿ÔÞžÊÓ#èODB~£ÍcK?Q#Nk«ïzÉÎ#Kµe)ä÷~]ó‘ŠsÎÙ«|±¸29UÜU]µ9Š ´»¾¼šŠ«âÛ©Loaûk÷EO¢c7¦¢dg1g/>Ýþr{­°Sša?`;ùc ^(àßjÀ÷bBg ”ŒQxÖc­¬÷?Ô ïìsÑ,Ìyb‡ñ7lýXb=°Ÿ&‡ÄŽ)ccLëøÔ £·ÃÃhg®PãlVc΃ºÏ UVìh´°Xñmеƒ\ ¡yÄdK††_äåPtÖ¤ÇIGeK0|,ª¥´ƒÀõãcÉ€A–p?犬MmaÓ‡DÍŽ`ËΖ¥mxíÚ!¯]\;8êW‡î<Ël#°zfT;b®H¶~¹ÿ;eVHMƒ/§V Â{ͤ&XŸŒ5AUHËŠ^X{uÅž­Ù‘/üº€s ·} ÔÉÚ€“É\¦ÐÓä¼ÏŠvWöôÂÅEäœÎÂà5–m gÚ‚ï>þ-ì«—L ÝĉJËù¡].öbç ø=ƒ ËÃ?•ƒ÷ë5¾òåýGÔ£ˆ‹ 9 dà1E"k=J#¢OpÃs4 *¢OI_}yR8ТÖÔ…h¶gå,X‘>õ/۞ݫY±¤Ö¨!‹8‹+úoíG`³çêñÈ:8%ñéÃà§PÁàÿÕ•wHµ³(Ùí4´ÐÕ‚dòê{ˆã—ÁxL ¬‘®eh©û)a  Áï M¿¿‡ßëwïïnèZ‰Zò¨èr~zÂM=ž:t0¢Ï*²ƒÖ­%“¬1$W`!!ˆ¿”®ØþB³ª¦€ãÊøÈ…y¹oòä4Ólb³#·³÷˜L©¼‡ÍñÝVoöÖp éÛov5)Ì÷@¸ƒ0;n>Jr±\  ÷1ÀÊðÒW?$÷žíc¼ ú˜Ówh-öò|ääâµ#´º‘Ìn\ñ«m8q,¶é´g»¦FU1¿íÊvhÊôL¼OôÐQAoúdÚgÁÍÓ–{¦¢Ì±øØ†Š)Ä. šø;?îðä2›fQ.Ÿ‡öÚFù†kXer:¶l rbt‡;>Òñð3/¬ý¢AwŽ´œJH‡·{Ö˜”ž–0g¸µDB héDU*¬Ÿ!ЈtóÓí‡ûÙíÝ u)2/ç AŽÎ[Wg¸=èWkYŠ0Ûöu¤“a×#uh^k6˜wÔò {ü ì!/=éÐ{x;ÔUÝ¡Üoþœ2$?RÆOΚxîw%;ö‚3aäzé¥Ï¾Ë™c·Ñ†þ&iž2ÀÊ¥c¢0£Â3¢0?€pá¹:]I4_k¸l³ø–NtOö¡}¶eµÛÚ‘‚/%G1gmªøIØ—9hsgçwSÑíìø6@•¿é°xƇoªÒ~P÷¸çÑ-ÔJ˜Ë…°ï¾âš@‹ö U©—M»¡ûž”‹"$5$MjÛ©ƒ£ 8LOt¶Ð¦øˆ¸™ n¡²B"Ù®©ZØ&Jló~ý¨„ÙÌÍÛUhØþšÿ3^u-QôÝ_1ìS²t¥mÚh¡¢­,ˆ‚ È‚/Ód¬aÓ¤$©¥ÿ~ï¹÷¦iÜêî‹u&óqgæÜsÎå›Å w,âÎþ–‹YuWµ‹$CÕiåbVR.üªv Ž›ÇÞfÎ)wÿó&ZDO׬˜Ñ졽_”Ö• >§TŸ%ÒpDûAE†1ýH2‚CÐò‹Œ•¬ß÷¤íp²À[í?Ö —ÍÇåÄ™ › 3Ý£W§˜‚=˜ôìm†ùk–Ƶ©=d´Ýjïƒÿ“톾Y!©–è}“¾Üí\©FuœOŽœê± ÂF…vi.,_¥Ô/÷ð®¿?ø‚;ãâL$•ŸkêPi&  û³Ç€lnúŸllž˜¢ Dþ¦œ@‰;âðÄae+èØfõÉD4¦yr6¦9ä[¤JGñÓxVܸ|åxhYî ‹´ßïCƒ)©è‘*ÀkètL¼êáR([§²BVìäŸ}뎇ѼäJ*€ý•¡‰NŒß©l’ÊXX§k÷UÔêdh©âdsZÀC¹’ñE_¯„u@0êÓcQ‰²Ü›«Õ à ¼ˆ’tN© ‚¢Ö¬D7=¡#ô®#7òîè‰FÈV4Pp€[¦‰•Žš ÇÊ’•ÏH.J—æi]Åeº©9zçN¿bk9$ÖáàÅÿÔw9Ù ”TŸ?>‰s½ÅóÑÀ¶ÚÂùÀcú‚Τý‘S§Š§ ÿoÃ9>ÎyQÆ®2¶Íl÷îr“¾»¥ƒ2æEîÎM\;›W"¦¤£5ã›S!.֚פîái+FànDTøZkát‘éÕú³DCo½×ÜyAÕxØT'd u‚›ÓvÈN0_4#Ñ5jý¾ô'ç#O•£÷¤Ój3Ç\Ú›Ì!Ï}?kyñ@‘8â;# ³têK>Û¦,èV+Ò-B)bÈ¡°Y{†ÒUE¶åò“Ç&ÛÒ}¡J­k FG²tË&A*ž¶"€fÒ´ž+#ïaq T“×waSP¯à㇙GÞïÞLDk>öD•Ú¡k`–™›ð*›Ìrá;SP1Ç˧WÂaÉÇuO•¾³Š|´±ìj¬vììž;˜ê}.2;ƒáiii œƒd Ù(¿‚Nm Û<7Ô©Uø«ü Â#;£«4šD &7tØìŠnÏêz¦îqj5N2M¨dLLBÀ´ìTÏx™ÛٽϤI‹|EÏRŒ*£†°Õí’›aé\Û߈ɨjË[µ3A¤GŽé•©­žEgÜ|œV endstream endobj 917 0 obj << /Type /Page /Parent 1714 0 R /Resources 920 0 R /Contents 921 0 R /Annots [ 918 0 R 919 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 918 0 obj << /Dest [ 537 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 220 419 244 433 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 919 0 obj << /Dest [ 898 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 157 379 193 393 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 920 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 921 0 obj << /Length 3251 /Filter /FlateDecode >> stream H‰¬WÛnÜÈ}Ÿ¯h詘4ïÁ0 •´†ƒÄ¬Ù‰•ŠìÑp—"µ$G#ùCòùÇ<äTus87­; !»ÙÝÕU§Núi>{=ŸûÂóÅÌó…‹?ü„i긩‹$‹œ8u1¿Ÿ½>ïSQôü+ú¢™½~w퉻~æ:®Kß3{|\Ï>˫ܲ'”wŠ~})²TXÿœÿy–ñ™H\'‹qJ:±«á |Þ‹ž¢Xoõo£¶ïZ¶8±tSqû,®Ÿ›a‰_* ;ɾêÅÙ»Wâÿ±ìïæ"'’•åÊbùJ\¯«á‹êjÞ$ySZv&Å¿ø?Æ×ç«ù®ãe~1¶`½^;Vàx²§S‹­q¤ƒG·+ÌÐ’wºœÏ"V "/-ÏÃH)ªÅäÞ²U´Œ/”×ÊËg¡žlƒjr‹¿‰e2eª1°ê‚PޏúDè˜óëéIÂüöЩGrOá`³FY°a%|¨ת®1BÊÀÕÄ'[’ŒlÑ©ÎÆ˜{oÙ1ÀðNcâÃGà5D€/éÇ—¿\]œÑ¡œS~ûã8Ywº‡ÞÌ Â ½žAoà§½âœÜÁíJÿˆÎ 2EW%E A¡0´JOå4¤V-ù?”À þ›Õ€È-"q×´fŸRƒ˜7!$_þv°|3@¾³Ò ÂXéoA˜”,¥™ÉZ8'ÐÆ'áŠÃÉ„ÓxnÆ Ôõ Otj‚;›ý@“€ . üó9Œ8rB*Íú•þ¥¤8†8ÍB`œÂ· ÜžtÎЉq: ñØsbzTT c_¿‘¡’v{´ˆ‰=:â=Ûô0ºüåÊ åÅÙœ¿¾Ô©Ä.ܲvãs/Üä=’¹÷ùo”^H¡VÅ:ÓnÂLÛÔÏt)3AÙÌžà%‘#š2¦€ÐÔ˜s³i«ŠÕ@i¡ d((È Ÿx{äjrð49”SÚ…¦J„ŽKÉ:AFÒ¯cÁˆÆÄߪ½n8Ö^× GD&€ŠH¿A”•¾àw*±²zço™§OÅ9ˆºã3­ ôŠ?׋«¾mö¹á°”EiDd²Ì ó´]çm3äUGUÍ)áDŠ=ÄìÍ›2,âóóü ¬ ¿o©H¦ò€¼x«] xº¸ž=æ•E´Qç·)‹š©A¾l=I¦mÅT_}"r äGñ¨ºžà¡õ¢9þ´_ºÙ/5.N í&í¡è£{éEÞÆÎ,ûîky“HÝ Bu›¢#A°L)—ŒæàŽÐâÉ÷ÞÑv·dÜèUÜÑ>vIÛO?›Ðþ?^õ(ºé¦¢­KÕ™Ëí ÌÿPø&Òv i¿bÄgÒ¶ˆE3„ ÕújFÍGùm:ßéRIè·+P)¨6†Ä´©Î)S¡3'ÝOºhsM ›v<ÄÈËßšvÝ8{Ê}MôNÙf'£R® N:Ê`õ"M~ÇñW˜îˆ;´ÔŒÔ†ØáñÖTÉQwž†oá/Þ¢Ð3¢*ì4t<† ‰W-$ú 9²iõ ¾©öB-òU=h'¤_#3ƒ¢ÐÅih¦Ø§täÞýÜ r<½% >Ë9ôz¡öV½îc8u©«{ê€ ®~ÕL­׭jÕ;âÜ”AÍôÇÞØ í†¼Ž*(w"ޱV¬— ¨{æN¤÷ùP,¡PgSˆ¿uãpÑ¡k¹ÝP¢—éPZHAõu»èg‹WÞ0'H, ¶ÑöQytÈaÅJ³1™# ²X³z^`Á"/¨ºdªkõ ë·aÝjXk[iZKi™¼+92‡–ˆ$»=/t¿¤´Œ£5Ü0éWnA°ËÞÁâÑl¦G(ãù³u5,Ùs–Y÷tÀ½îñ¼ßbC±ÏOî6Y{œÝ~>((îaAùV>÷÷ÅšFã d¾(áõÖi± ¥žŠ´’ˆ´G£øÓp+ÂG“`Ròþ|s"õŠZ¤F:à²åçà"ö<ÿ ç‹ ì „çDÜ %Ì<´le[7ibQée"‡¶‚¬ª)‘üý)`| $Ò¬Áêdú tßEÑ5 ºsÌqpO*À[+`ÔDRKu4¥ÒÅØwèù[–¢Bëe×4UÔã^@–§æR˱\Ãx¼±pÐéaöïdâIþ(Œ7`ðã±W¤'-'Ž{*ïø7“8לý‘êš'ÿjÙÔP\YÔ?œÑK ?i‰wI?žü™§ÞÓT<ŽýŲ©¼ =yMÔéSç’l±ýXÛ’l”s„Mhò˜Ï=n'‘•ºI åBÔê7PÙ°$¶ r\"S Ðì¿T¢&LH5bð…Ù äȾ԰¸×(À¦~´‹„Mjy™ÓÔöhçFL0ÝoöfQhêJÏoÅ¢íx‚Çõèåè}ORšD4eg$ÍŽGu´1 ƒHÜÒNXœ€Ü†}Ï;i°ÕòŒíœ—Ä£Ž~Q@G? À¨ãçy­šÒ|Þn›úybè½:íÆ“ßã =“ÕeNéjôLä7£dtþØV¥Q˜_¨ ÑÓK]#a‹ª|oV­+ÄïN5ªÃþ¢\iaÿ¡¼95?Õt2î·>¨æºPoZÿLE· Ñ¿=ÕR;”âàÚL¯:÷öFük§ô|ó_«d7aˆÞù ¸q)Ä!j©D‰[X*0ê.)‹Š€R­Tõç;^€ÄÌ„ ±yæ1~³ØèM_SJ“VÜ͉4á¢Õ`4`E·Éé&KÛúÜ/ ËÛ¨œQÏõd¤pßã‘æ7à³o˜E#ƒ2ùmãO¢ *¦S”Éí@: ÞpU9ÚB˜;}Á_8Œ6㔇|t¯Â›ŠŠ ëôÓ®åÁNfòJ™!N•EõÕjU³œïôó·BÈ‹¹Þ™3Ö›iù­Ýiµõ¦7 ½ê„õ÷`ˆ!ybÁ3 ž~«;޹ÞÄb$šCQïÇ%˜i-Q@ó@0‚Gà§xÀijß ýh z¯Í!îðn¬fSû¬YèÑ$Œ á×òíKÝu6¿z»_¨zhÞIŽæüf‹Ùª–M0 ÅˆaA¥ªaCIâÕh8p4jÿgûöiEcXÖ7 +¡òíbŠ–%=õÇõÆd²dk²ÙÍ’+u§ÓKY´¯¥UË‘8‚Ä&ñÝ2£îi¹¹EÿG âÁ5+7GðF°r|„ÕÑhmõ9Û/’ƒ‰“ì[Éûj³:šXË>w‰›^ÉŽwy]µ9‹7ËÉÃy×±Qó»\l“Ãú”»ï£ÍÀÉIÃD ¯Y_uZó”õ7&=ÅŸJдœm½P¶àRDt?”WƒtßÅóQã7L§F¥dMqô_€Ù(§ endstream endobj 922 0 obj << /Type /Page /Parent 1714 0 R /Resources 925 0 R /Contents 926 0 R /Annots [ 923 0 R 924 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 923 0 obj << /Dest [ 537 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 320 478 343 492 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 924 0 obj << /Dest [ 898 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 157 356 193 370 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 925 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 926 0 obj << /Length 3164 /Filter /FlateDecode >> stream H‰¬WÛnÉ}çW4òÔ˜ãé¹×0 Ë´ÖW^Ht‰é‡Ù"'¹äȲä7òùÇ<äTuÏ…CJÚ bO_ªªërêôÛéèåtê %¦·#å ø ÓÔõR/I¹qêbº½<ß§b¾ç=žØÏ«ÑË‹k%–û‘çzí™ÆÍð~ôEþœ;ãÀ åRÓ¯/E– çëôO£Œ%d"ñÜ,†– ucÏ(a>Ë¢QQÿö1;ö=g¬7–^*nÄõCU¯0ãKí@’Ü{qvñBüõ?Î8Â÷k‘ÉÂñä|õB\ßõ?ô®d!Ì«…3ΤøÿgÃøú|5ßsc|LßaŽ-¸¿¿wÀUrOZ5©…h¨t1ôp»¹Z±¤Ét¤D!F~»A¬D¸i*b冡ÀÃTìôèvôvÚ:#PØâz£sµG•Ó¿^¾WÃx©0v#òdÃk¡9,ßM'Ÿ.?þe&¯&Ϧþ<9»þ<=ŸÉéÙÕÅdê¾›^c493ç †Íi€¸+‘$ ¿‚íìYûìj·«¡"súë‘—º~øèñg–[Ý^„»³xxøä2Ü|ÊYaúœu5y?¹š\žOúþ¸+JÜ8lÕL:µxhP໊ âΠ™óÃ@K=¡åÔâ¡IÏZ™VË?:‚à §Ñç7:¾À…ÓÏW—ÎiñõM…4J}õ„ÒS‹JUŒ"‰×Ëý¯_ß¼~9߬·ùNïç»b[¿9¼iœQ<–f¯RŠÛÕÇSü‘ãÏ,7îð²Þinà‘GÖß2–‡(ÆðOèAšóÙàm PJüàz-àzÊÀ -rUà‹¤x½Ö»¥q#OÔo^ "y~·¯7kQÔšçפR¬ñÅ ,qÌ +,K‡¨ÕšxÔm:sTc5æ|SÕyQé…(ªW ·‰lÅÚæ…5€M$aæøëE^;!,²?[ídø}Cæ¦rhà˜E®ßˆSlÑyö-/-­Ìoê!¥D—úÕãÖ ýk{cQ‰Ÿ¯¨Mò“ø¦wûbSíŦ*7Çï䥭¼Ôº(¯ÄܸÉx(zÂC,#èyhæ…””»Â‡r[?ãcCÖÚ)×\gl†þ^;ã®1ÆÄÏ„ ¹Ù’‡Ð[0ydmID¨±hG)ôv(ø-ŽRqï–gäoHªwÅÍ]­÷ô©ØBEYû´…œP²ÚTÚ4á'}ÓäË;}›ß•µqBú\DŒŽftOÚ„Á.V9¸Ÿ×ÞÌÐï0eMxÆýøLôð…Ü/öü!ÌÂïãg‡òA—pJQÌ‘T7ZÜ™M(¿z#è*²XoK½Ö¶ØÅšËX¨`)Kl„Wá-ìÏËåæ@x½Z›s®ø‰çuß>‹9ÑXÙYÀêïWº»þ9³¾á«•ߊjÙð¹Î]ä¿ó‰o|‚Œº-‹y½!êU^C£`éõý†`m½•6'Gl$zá0ß·;\Wçó•Ø€îxFMм,Ì%C6Éü-¯ê¾eÀt–)¿)€:wÅ,ã˜EðÇ­C$íº\ìyIlhÆëÎf³`l6ñHاä@Ž)ÕPd|‡ÄÏçs'ÁûmŽ›ÿvj!r+ôÀñ-7ÂÍL~Sjd÷‚n¯Ø°­Ù¥ùð÷¶ ”-ƒA”TÔù"²ä»¨*R`î°Š@ÊûEä·Ed9“·›ÛAΡ0S02¤,—=dïyµI…G[ dGÕÌ”ž¾´Çþ`&oÊk]×zgg´ÚaE)ƒÕoÝâ¢QagíºÌ0ì]θÆÂYI±Iåf³/*À6 ]<Z™µ˜æù0ÆS$Î`q\Ç^«E ]·&h”'eã7¼"&bÁDᆚ5§~ÅÛDìfnà—åÓ(¦ºT°~‹¾›Êš³:2y¯¿ëù]Jµ@«â5Ò0A–š}`/ÈÉÄ]$Í$½ Á _˜²m*Ôb&‡qP™›F¿K ÈÅqçíØ\]à1ÚôÕJºCªc4m9˜ýíö~» :–q Áö«Í]iùÓÂaª„пÞå%fe©ÚØ]ÐЃšôûtŠ %²NS;5b§Rëx3lα˼¯õ_Kˆ”5o Œ‡ïR®9 ëœà“¢{=1îR¤òCš>˜ŸËËfpqNÇ•üÑ!¶pfzû¥CѾ°ÞÍÈ ƒÐ¨ÔMžã²Îͽ˜4½Œ?="B©iöדéGRÉOŸ®?˜Ë™¼8ÿñŒ¾#˜9a+†FÀÌ~¬‡Y/L^ß9¹jN¹Þ¦ªhP–›{\ûWQ‹õfQ˜s”è¶ôЦTš ·ËcÌrYv¢àŽk?L~k;kgrcóyUì7&ŽÕü§B#ebôypzjS¯6÷¢¸’ìðZÛnªupÓm÷™QSžî‰o`7 Ûéõ¦Ö'[©aQ-¡"Sð¬^óí¶,L;')å†RK–‚:îM¾×ÿ;Jwïã¾½áq‰ÑåL‹Üšõy‘—£¦-•J˜àÒ1ŠyÖ‹9Z‡mºZäxŽÐK„•†–ô•™}¼Þ6ÚˆTÎÀ.áÁzE`áiÔôÀz¨y|ŠJhÒµ0ˆ$YS/´ì>Øun•0oLÏ0DZÅJs€ìGrò~ÍäTþÅ@õòÕqì1ꪖ7…Q[°~lÁ'ñãæ5Vk/KmÚñ¼„[ɉ•+SÏ´7“ï)EPws€€xôÎPØk*öWÃjWn|„ÕÅ™ÍW`qaañ’b«whÆkŠ”¡X-Ìã‚ÞR#žù®KÉ×ypÇEd3ÝìÙlM©æqóðTù “ÂÌ"3ô N9b$êõmêWr&á1õF4<‚ÍÒÌqÅ9PœÍXÙýâöÎä2…zC5îŒA L ÖÚnª›^ÔqúG›mY¯q3ÈL3Èšf5Í A3 Üçf‹éáHÍ€:ÄIF«£^à^Öà0·„CÆR´”¾íÔ¨ø¶(Ó·N7Ïû Áo,ISk {{ÖÐôý©rKòi*óe÷°=¤>,ä°+äÐȦTrŘ Ô@ë‚^8Û÷͵CÜÛ%m[- ðzáÝEqa’¬ó™Í9•©¤+È%ÞT¿˜Ð}°¼l&Àe…h徂 3}‚¥ÿßdœ+!ìSñ¦ÄÉ×TC ½wq\™G'Bú$$Í)™ÞeÚ»ü—ò²Ùm‚ð½O8Q©â˜`'JsIsÈ!—ª/@ j‘­òsèÛwvׯ@¥="À,ë™ñ·ýˆñØn¼m¹TÓB»u¦õÏó·x˜vÆuN¢É ÎL1Ì©™ÁÓ‰^K•]ýâOÙ(ÌyâU ú"»aÑ1­§µEÆ ×£¥(;zc…nÎE5NAÞCé ï“úñ™Kó„°8ÀqçôñA›¤’²¾w{“>*3š øÏãéEeIôSGôÕƒõßQ…¾8æã$x€cȵ(Î ¶HC4Sø†¶&’KPÈh{´qW»Å§þ¿ÆÎ1¹)¶\³¨«º,ª=‡FM±X.Ê%™Ya§¶›íúñyóÂýAØ—7ïg4¤Ò–BôŸvJê}´ÏÈÍ]Fƒ¦e#ÓÓ Œ¿ éøó Þ [åBí– ݽ·ÉS\WBîòÇÓ$¦Gu²> endobj 928 0 obj << /Dest [ 817 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 458 604 487 618 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 929 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 930 0 obj << /Length 2660 /Filter /FlateDecode >> stream H‰´WÛnãÈE^õ?5‘æM”dÄvvf6Ì,¶A2ÎEµ-®)RKRÒ*’È?æ!§ºš¢.v’5 ‹d_«NUªz7\Ïf!4{!ùøÃ#ž„^û §#/™øÍVƒëï› eYãS“•ƒëîzj¾çûÖd·{Ý ÔO铦À÷É™ý<˜šMSûÞ4ÁÁÑÄK|9×ì Ív~%¼û›úWˆQ7ô7ˆ¼Dùšïé~_¶KŒ„J;8I5yCßý0¤¿ýÛqGø®17òF*w|•-‡t¿ËÛèº0‡D*-Ž;UôOóëü}öçÑØhú^‚Ù{Œ v»çD^ ¾Uóµ8Wzxõ½PevhiNú0”Ó %^”½É„’HtŒ'TëÁãàÝìF`‰ŠF®Ïˆ(ƒ^o™¿qâ{ø—-@ÍàçW¶8múDxl½ ¶¢…~ÌKM­ãâfÈ(Ms½L·yµ©©z¤”þ°p ÜX¥mÚî1Ô\ó²?Òn™gKš;A RÇ5¸è†ª’€ =éR×yFW«|¥y}Õ¡ëÄfPÙ3’ÞI¬™ÛýZ{4s€Ëjztb/V•ù*Šj——O´M¹ØèƬ¥,-!:É×Zvf¹l…ùá2šxÞˆ,×­Ÿ¡Â±µt&æV¿c ¯?Æv[g E‰çÇvæÊÎL{™q{e¿©†]3P­qXx`Z/DžÃ‘ðï‰õ<¶_Ø›2®è†f@™Á‚ÒPy¬`4ÀŸfYU/ X÷˧/Ü÷Ÿî7Tô «ÂÌÁ°E…gã7CÒeVuãF¬÷§ÆTÑÁTçñüM­6E›»ˆ˜½ˆ± Ö‘ÒÅ–P8›YºæãáHª’U”-ÓÚa±Ò¬ÕòÆ+œ3ã@ˆ‘±OòÖö‘Q€èü€(:²Fƒoq¸:1Æ’Ã%‘ˆÛ¤È) yÖ”Kp¬kív¶!æ¦^¥mCÛïá zÁ1ðåŒø¨B³—4ñ¬}o÷öq{ÁŽåúÚ?à°otÛòÇ*}f'Y˪e/ɪ’¯çW#‹HF„Ìì;#Ž®fÍÁ”gi›W%\¦©(o©YV›bÁagÄšý^\¥wØÀ:ì¦q˜ŽA: à%b•->i»!N·ZrkÍ £Å€~2&ùì¨.‰"fÉ>WiÈulªèîîëçô˜ët1Uµ¨ÌLöLgQwIª‰?ÆÅ=©½^rÏ{CŠkÍÚÍSy1jpÈðj ã…†#Å–¼2d[`jÒ­¦ÝÌQÈé…WÓU]o }ÅFÚêZVp2ÃÉ«j¡MH=(»“Ó«¯{p†ÌÎ<—ÉáË úý¦Ø‰Ü«_6ùÉ7ŸÊHI^˜OcæÓ´`â)YSlõ5—ýËF—-ø€0ÂæHÝ$ÜlʳˆYÐRjWÊ’Ê\Í´/Ã7ǪDg¤`bÿ,ÉÀu[ÿ€Ç¹£ÄW÷mÍaÁþ±2Èmš—<’ —@‚¥cò_ÝH´õ¶ w˜ªÖÙ¦®A¡ú<¯tÌõÿgãr½U㣱ٔ‰“JǩӧÂ<¹L æ2ó8î„_ØÖ*³=«ÅÉ1îÆn-|ºG”zHï ·´Hób?4Á$?wZ?Ly±ÚËÖ!}‘«oMÈÁOQ-ñ¶¿¾X„“ƒ^üÊzÝÒ^CNä86ß¿ž~#p/ ‘{ wX¦œ¯ÉÈ"iÊ ™`o¥ŽÊÓšÃn~P¶0I3m`e´§ŠÁe$çò ùA;9P?/Ò½A¹°—·l‹[®|σÀíK…¾RP{>`ïÙ+Áà TÜè¬,»$𰋘OÐ'T%Ì2R­~ÒBä ˆÑ8Tç‘Ô:¨‰Ç¦–)N­Ý³N”þu}’$WØŒ!C !@SnVóîR®%À›eÞÚIy¬å*SüuB-zÞ‰•½Y*³HZwêë?é}Šc¾ƒª[øßÀŠþg°ØÖ©ù#½®¬ÒÏŽËj+n–ÆêË ñâK¥¬ÚklÚ–M©É,öƒ×TF¾Ža§õñ›‡Úq}oãÅÐÊþ†Þ·—XjýÛûM9<ã,¨Äaº½OÛ·å TŇ\2í„€; ÄÆãPc=Œx   Ûê©ér1)T’ý¹lmÌdëp &£¬)ÉN÷ŒoCf=Ï£Ó©ht;B}…¹·+£…ªLZ§G içÊ7d.“¢¨{ îHHŽ¿o¤@¦w¹¬o}¸ ä ¾:_afFêVå«\ å¥_ÉÆÓ姃MËÀbس—¼mz¹lž¤ b·I”´?’ôø­0-Ôþ@Õ& lcù9• èF‚[9LχìÒ!DgtvYÅ–* 7½P]ÐÑ3ɳm^mšnÛ|ÓR×FÚŠÈTO\vT+³mÌkl{ÙãJ,ùb›CiW–‡~÷)/YF½il]6(ÊJÄ^ Á*ÃiçtæÿFqðbGÀÑ<1fŒYG/³AxÌRÑð…íZ²Ü¶¿`ˆ±Ë‹‚Jˆ_;A Àk´«ó¶…wÎEÞ;íwŽƒM¾~æRg¤>0rØ%‡D#Uq¥pּ«ÌÓ LC’›Fse 'yÔ¦…5VÑ¿¶ì´FË †½~Â-u2–2MÔ)n¿~þМ;LxF=†a.z•àЫبÿ±:ÆŠšl©W,+ ÆaFaáK†•y€`XªÖ¦´¥uÕˆû6ù¼à´Ábr¸ÚÇW‰ ‘Äû§jÇØ)ç´µE°˜þ#b h^lTýQåH$6K‹¦âì§_4ñ ôi0ätÉòáÆy^€‰’€2µd nCx¶oàæ‚Òrq:‰Œ•¨“Îâˆxe ¥v-mMD§ŸE¾ðÌ÷%¤¯ûÇ+˽C¤ +»écþ„H*px,† Àfm…@Ó²ÚQJwÆ&‰±Æ¼¨¤ùϲ2ÁZŠ!ýŒ”Ô´Ì> endobj 932 0 obj << /Dest [ 1297 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 332 709 346 723 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 933 0 obj << /Dest [ 1596 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 506 709 519 723 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 934 0 obj << /Dest [ 1297 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 420 599 433 613 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 935 0 obj << /Dest [ 1556 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 326 584 340 598 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 936 0 obj << /Dest [ 1556 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 470 571 483 585 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 937 0 obj << /Dest [ 1574 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 250 557 271 571 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 938 0 obj << /Dest [ 1583 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 327 528 340 542 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 939 0 obj << /Dest [ 1596 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 138 486 151 500 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 940 0 obj << /Dest [ 1596 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 134 178 156 192 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 941 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 942 0 obj << /Length 2702 /Filter /FlateDecode >> stream H‰´W]oÛÊE_õ+~Z&Ã¥(J6 ‰\´pnzk=5. šZIì¥H…¤¬øþþ‡þÇ>ôÌÌ’ú°E/.n,.—³3gfΜ}7¼™N#eÔt>0‘ ñþÄ“(ˆã0Qã‹QL¡š®onš‰ÊÞª&+o~º7jÑ Â öd¿û¹迤 «Lh”7ýçà‚?ºPã0¸H`x8 ’Pìò7N¿F }ýYÿ;ª…žo†A¢Ã‰z|V÷Ïe»ÄJ¤­KºÉõö§sõ·ÿxþÏ5Þ‚‘νPgËsu¿ÍÛßl]°‘¡NË™ç_hõ/þ×ûûôÏŽ˜£‰Â ÁÃôkìÁv» ¼a`tC§Z:¦qd€ŸaéÌ--ÙÒûéÀ¨\ ¢Q £†ã`2Q‰’ 1ÆUÛÁ|ðnÚƒ14Ø¢±C7$D4£‡Å.GqÆ’&þÕá9އÁ8Ú4w€†# ǘÀÃ[uÕXàÇŒ~ò¢ `ClpP××çê*ó¢ *r[zÙ"H<__ªŸlI𠶦…º·ü+£ êLÕ («›"çÃlÙª{(™î¶ÍËE#à#®ÉqíõEINö"2]@F⹩Ê6ÍK;SyyÉëÞ¬+é$w9¥"òùUã%ÁD?»?eö¬*ç^ŒòÅõ±>[TÜ·âIñĹ”–*·Ä£Ñw<}݇C±Ñ¦žk 4³MVçŸj—¨ôlÉïÖ(î8?èÆZÅK…$©©ÁyU«/³-*à¶"w«!2fýfm³|žgª±.nc Ó3e’®7(ਃÏLv-î&ðFpˆó “€/¡æ¢YZÏJV*ÞP{TX*CiÚA…œ•­Xyð<êÑAîù–ZŸê `mZÛУф¿Ù7w²"„µtû¼¶Üh»Ã"G] †;8[IEèkÊá-™—òFbmÓ…²eVTòlÝ2 QnÅó#â­'Î'—Qãµ2ئéÁ.H‘¶}7Ñò½JÛ¼*uʇçofÝÑí²FÑüš—3·PÍ_${¿2™Ê÷θBúàà䯢ñ¬?ÈkGWhx‡vOd]à õÝu·kï± hæAß:$|*%«$YTή-þ)AR P”µß<½€Å¦N™¡&Ï)ÍQ5D-f¯^V8aš0Ç3êRªè:)fK]ÊK™óAÃò A×—“jÈÄ»Ób9 ¾Fk3 1f`Ñ R²‡ºTVmÈ,<Á)ÔF1z–Æîg¦¢ž‹ˆæe£X{r¯É”AÚkÏð)WRq׊ «?k¸Îé2 ×Gœì¤O¶Çÿ˜ñð¢g¾ ~¶Ës,õ(8$·¶ö¨£uq¢]Š ü¦eRº"üÞ’]ƒì†ÖU‹Ž’LuI6”d!2ž¡/é>ÈQ0§ b«nõþ—;^|ƒÅXº}Ço<Gz¾8|ÈuQÔáD¿Èi°Ä=}é_¨è"}—Ëck‰ûP ©È¡Æ-ÌT÷«~¢­ /?2¢Lÿ&A%ù†9%“·…˜uÖÝ' kåÌ÷ûÝ÷Ü}¾”GlN:þÝyXC¾ˆ#<­X]±çkwæf!)?²üZ`£xúJd‘tLÿ8Ø¡¿›Ñúçª -Ó–W謆èe„êöýÇOp‰é»¬¶*EL›E^ú(mÔJ_¶LI2ÂM â‚R]bónÖDß™5Âݹ(ªrQØsõ¸É‹Ö'æ±_[ž–&Š@3SøÌ|  ¼o¶ùø÷jóý”sm ׉¾Ç(âizй'‰a™êYøÛ¦+ ªû¯²òûŽ™h1ïñü«ÑŠ-‘«ŠüQŽªAçÖÏÇÚ=:VŒ~÷“ÜGŽD%Ú­íHò'&Z´ÞzOGnhL$:õÝ`뇢êøÞôY†Õ,'Þ€HÊÚü‰è1|¥‘¢[µ]æÙ’ÂÃbê¶ G CEZ'7˜¢ˆâ'·Ê&Òù½kà…Pæ¨Vž?Ö+§f]A’Ôñ4o™>9ͤSÊâù¼kÙàš¹©Ô_í—u¶Çã}ßzáÑÝ+Ð#¬w@[0*ªG¥Õ¦íF9Yxm’w¾|äJêWn°ìO‘'ä¨Òª­hÄó"k‘7‚E>z–0idkUæ¿Y3¦êäƒYÖ 1i5Úú 6ÿ"dLÉ ËDцýÁ矺 „»xCŽWï]ULˆ–vUä`ÚUÑ)Ž;àA4ꌄÀ™J!ó¥·Hë«Ü9ìüŒ¾Pk îÿ¹{5 ÔŸ<¾'p½9T×b]n.:.§EE ßHaÔ§°S1{ÛŽûëX4ÿ`sEÇ͵«_¿€?ÈD%Åñÿç­}óIXïöÝD´Ú4-UîTsgÕì1;ƒ&TgÍ—âìÿǧ]Žv.G‡.˨ìGêƒfªë¯0¼‡g,ñ¬ÌÙïüDLï,¤i~&f»¸úÂŒ¾]˜{w͸¿™¸ÂüÄr…’]«§T®›ÅÆ-5r‰u˵çîj±\ßÜžîó'÷cFóÙi¡ù¦ÝtU·á`¡kºpoëýù¬œ®¶ò”S1¢þ—êöm»Msçk&χqT{±BñÈNVSF¿¸7î ü¬÷‹Z7FõÝP±§’ˆžŽ›]A’p¡€·‡“±’Ç1.³ „Ï0¾LBlå2Ó+cWø(2òj•~mÀ¾«‚î= x}~µÊKZç]+QÏ…«¶ëK"l~“‘°ºÐï\ˆA<M(ÎØ„ÃSÒf,tuÛlÖëªna«Cio6’¼é’ÐFÁ8Úì(®šŽD¯— …x4Öc²k±¡ÙK.‚cšúD¢ŸÜßkÇîùlè°^Îï›´”)Õ94zÅ!B¨ëyOÇ»¾×›¶ÎË&ü¦®1°ŠçKu†ôœs¯ã§‚2ÞN øßbHôÙ·ƒˆv}œìAò– ½€3iŽ4R×—Üaà E—ÔÊ¡ì9…áL|Ö·vžnŠVК¼vÄK†L‹¢ƒªQùj]ØPBI:im»š£&¹C¾Ãrߘ"SÈmËš@5¤æÏиòÜy–#t{ÛÏ °3“2‚¤·58²¬×ûªYV›bæ\%}…êçª^!<¨;2pRoŒvîv7 ¾¹ 5ß¶` ÚÊb»àŒ7Tj í®Xòײò8 [ú¾d¡æµ‹…¿£€Ä3ÖƒF-ž+8ÅšŒ@ÇPS|Ì»“ò•í8í_³Ã×8|É Åë aYƒ+š%c¨róžœtÒX“¬‰EáÇú#o¿cYG^ó£|ë\‡‘íÒ–]ôh.Â"UòΊùî‰úÈ©Ðrå'õ;ÜWk^’«Në\%AEwË…Ê[µÊËöE?ã¢6îà9û¼)È›"_å-à ǤäU‚-‹.Ž­ѯ›f™]·$ôN¸¿+‰‰>§h#‚Xžeã!.$­ñÙÕ̹K½+ºld+ÿT¦O]ኊ.®>ÝÈ0kH(“R6N“¼Ÿþ;æä½G endstream endobj 943 0 obj << /Type /Page /Parent 1716 0 R /Resources 946 0 R /Contents 947 0 R /Annots [ 944 0 R 945 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 944 0 obj << /Dest [ 1291 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 317 305 358 319 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 945 0 obj << /Dest [ 615 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 365 224 396 238 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 946 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 947 0 obj << /Length 2771 /Filter /FlateDecode >> stream H‰ÜWÙŽÛÊ}×Wô[š€D“”DJÆÜ¼åâ^ÄÙ¬ AfòÐCµFŒ¹è²ÉÑ(’È?æ!§ªZ”f±ÇÎ[Ã#ö^ë©SoW£W«U¢bµÚŒâDEø‡ŸÙ" g³(UÙr¦‹hªVÕèÕ;·P¹ã=‘ry=zõã§XݺQFQŒ=ùhrüÜôïÍ­Uq”¨`õ÷Ñ’-U…ËOaɽ|&áãô5Oéô•þW‚ÙI“x¦:Z¨›ƒút¨»-fmܤ]áÔ›Çê¯ÿ&sŒ[¬Íù.‚HçÛ±ú´/ºضäK¦ÚÔë`²ÔêŸü7øÛêçkÌÚ$Q˜b°z9–`¿ß‡Á4Œµ£W-=‹«ñdˆÏ(Ltî§¶|Ó‡Õ(V…%ó4œ¦±šfáb¡Ò–TÐq¶P­mFoWƒ1¦1¶D­q²nDÑl=øhæ}4 £6ÌÂét‘)šÍça–œY5ÊŽVæ¢S‡I°€ìêÂY犦îŠÊ6=Ïu—¯ÕЇÂÄ\oš6È`7õõ¦¨ ·å½v­üN ãh,Y†ÑâL°ø(W,b½ƒ¦¨qiQ¿fëfz¸Ö‡gfGÿààT®ãb.´mƒ¡rç/2»~,Þ„/šÄ!Åé{o¨Å`¨…—ÈÔ*©D ù ‰­³ÓEÝÙ[Ûª;Sö&zL"á&Ì!Ù.ˆµÍ‹Í¡¨oUWKh-Ö/j¿ÅB†µ|~YdÐ#NϬò†rb¦»®-núÎ:Æš´‰Ù§/k£ë¦¶ÇüŠùbvÆ•~o7¦/;1Øâ+Oˆ™†œ1¦"_4V×z®ª¢&¹¯ᑾѠ©äHt’iˆ°ÉYˆ­`Ä ©JºŽª3·J>wˆN5A<|¥w¶^S´7"ã®4@¦Â£”±5@=Õk‰èÉŠppŠ¥ÑgkwX%«§ú$£Ø‰¼BrµªØ<1Û³åêJã­6˜Œ(x/Õp¥ª-|×5jƒ…Xûe(/ä½DÓÞ~Nu/ó° ¦®ƒpˆÿoïy¶@8ïSzÄxO¡D»hí/½u]ex|rüÈàÊÄ+s/M~ >ãÝ|RíÚ3HNS9ÙnyÉçó8\ÌþÏ‘ü„¢•&{®ûÖtc×”`¦€͆ Æ+))޶m¼EÇ*úqTUÑ}Hÿ÷ðûy3E° iËpÙWÿn œMÎñlEˆ•Ë@ÄÞIBºNé_ú"ÿ\¢z&°Äóà‘\& [wä–€«§0*ÀCnÛôåšnô¾ÂµŒ ™'Ð ¿ý€<ÑþJ{‹jè4xØs`kÓ™ã]”+!wÓòrÝW7XFgæƒ6*b1Š áŠ­*M{kCõS­žÛåI å€hTY s㿳R-ƒ±O+‚­Ùq‰"˜W©Àaq'«d$ž–¿…˜‘³!;óÙ*Y",¿¬ú|ËuJ©$`ïùG¾í7àÕÀ…¼,ˆÍ4Œµ—{èóÏçj]2ÔºÄÇŠ• l[¢n鎥‹FxÅù$$…G¢ò“ÌmN'tÇÝOϵwtl®C®éÃ*‘•s)ŽBø!²6ÃÙ½l~pEH×Îô³ÞŒOi{Uÿ\t[?ì‡{¼—–쥌Š,wÉd¡¸;‘UÈ>µkœ|¡7Âê à yT ç¦ão:{î¦ nš W]JtLµ<çIFÊÖ·@|.''Ö´“ÅFª¡\2yìU"+ zǨsùOEYyú‘Ê(r:Ž=¤ÖÍ7Õe{(=®@¿#æ1½Ê‚ÎÙcçRø¸´÷9ëç/e×éœã|ˆXäœY$ÄWžËÖ'àiª¦Gž3Rhœq=h¹ÊÔno>Ž5‡X%£¼3ŽüÝíššìkïÁϨM¾BÏòžKaQƒ»ò¦ª 8  —Ð*u*[[)!™¨Î(7&ÿ|ÛB|*úäG»3-•DTkÍ:|j…gëÀI¸ÙI¸™÷Û¦ó`r¢?÷Ü6ÍtËÂ.©N'>™é’â4Õ{a—Gð\‘Ð"(dò®<¨‰èJ¨ëº¦©⥭-\óÙßäÆ+í}vd¶ÎךÙ3P•À¿B-&bKñÅ<̲ ¹ûbLO{îkÀmûZ*QepÛ¶ýuÉÒìlkžd؉MÎIk…˜k±¨ 8§¢ûŽªæ…ø¼›sÞMOP³†§Z65LK±QÙî»]ý Ö½åt:H²¡èKJâþ—ðã︩jP?iÙU_bǵ>BÂY>+¢Ti˜LÁY@ÔÎ0ó $xà|&áâ®yDÿ€¦ÔÝ·FÒS6ÉP·£Öö®È9f¬/&à/4É1’[¤¦“o‡8÷ÍÓ˜àZ ¬C$&²oÃ+æöiŸÉž9åcìó˜¸5è´ˆg±r1õBø‹ íŠRܰd7Xù$ø-ž,Q®Ù;Sö< (OÖ¨å5MeTÕw;ð„õˆÿY°Û¿¦ä.œõÍÙrXñ0!s,)Ó©„Z¤¡X~›êÔ…o2/™ÀÙŽK&yƒkjÎBº9T¿“#¤]C}%r·†œ¢(ø"x°ÄA7Œ:Ï%nz&õ R+ödSž[ÑìÈ6I²•2¸Ñ”jzX®!EEöô ±þÅõÕµî]T: ÊÒ"¦b<ÐÕ²¹6Í„òª í·eøã^ÖWš_5œ=ÓxvŒ÷uEýñMþáO>­>¾ùËê§<¾ÖÔK­]Þ»NmznQ@ºrß“9k\< Óë€"…ŽÝ“ÎÔ€öRª¡Xr¥|¬ÄääÿÇ´Þ”®!CSÙ6e oÚF‚± ÈìJ$sáÐ4ͤi‚H(`‘LN™’a†#)\gq¸`›T§Z—=§Í`õPõŠš'È¥ ¢aÂÆ._Ãë(‡Jò¤ܧäAû÷wFëf_"ú–ŽŠð?ƒ\³9Ä<“k°Š7Ê;€ôQÅ—v1{¡]œÆg­í…cÉ „]wþ÷Ò÷#Ä{Ô@NN%í¼¢½ƒ›r‘Jšoÿz¥¹q…áÖ½¤)â Éï,î];„ xØM!Üt@gß ÑÒXE?ÔÀRºª¯¾¬Ë)äâôÌ2o¨C@aïÚâ¦ï€[Æú5w)Ó—4Êè"]¤S~Ý„1ë¥ßÛ£-¾×h:‚‘ΦDÅÓô|‰ì=uÅj[pÓK„ëlM4iC<Œp`moúÿÔ])‚@Ýwж-:F'¨ H "H‰“¾ÿ¥U{u`˜yÿé=©‘JFL o•«ùi¨’Œ>Ìä”,jì¶Þ¼úo~òø“’¾‰,.v ‡Y ݈šˆ°O®&ê|”Š\(ÃÄiDAzµ “É\rª8ˆ±Ù¥^Ž|%‹Yܲ /h&4Ÿ endstream endobj 948 0 obj << /Type /Page /Parent 1716 0 R /Resources 950 0 R /Contents 951 0 R /Annots [ 949 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 949 0 obj << /Dest [ 615 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 281 730 311 744 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 950 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 951 0 obj << /Length 2766 /Filter /FlateDecode >> stream H‰ÜW]oÛÊE_õ+~é~‰¢ #@îMz‘"IÛXyiÜš\Yl(R—¤¬¸?¤ÿ¡ÿ±=3³¤(ÙqR (Š"p¨ýž™sæìO«É‹Õ*P¾Z­'~ <üÃ'J7мX-–s7N¼P­¶“?·‰ÊZžã©6«&/~¹öÕ];ñ\Ïó1'›ÌúŸ‡‰þczg”µÎꯓ%/Zª…ç.cl&nìɾ¼&àåôkÓêÏúzgçÌüе—¨ÛuýPuôÚ8ØI·E«^ý2Uþ§3›£Ý`lîÎuáx:ÛLÕõ¡èþfš’7 uZåÎl©Õßùç/«ßOøÆ|›Àsc4V¯ÑÇ× ]_·tª¡c±5ŽtñÓsÙ® ïôf5ñU¡&Á‰æáÜ•†Zmìh‹;Ze4jWVjÓK™±Ã½iJW«ÖvÕW¹|+;¡}ào¥Z1§-¬×êªUížÇ6ý†{`‡ø©ÎÚoí²›Þ9³Ð]ÐÜGý> Xó­]vΗÑÕ– uµ·§Ù¹öÃ6÷É­áuÊ xÖ †§Ÿääô¶nº¢ºÃíp3ºRQ)JŒQÛ"ÏK3UyÑfuU™Œ§V²gNÆPNv'†ÙuóE™.sÕéZµ«±Ûmi\õ©¥%´ÙÈ¢ÐfiÖ§êG²ùxæOŸÞ\¯Þ¿ý°zûþ;qÄœVîœÑœ¹nŠ]§Öû Õ•ºÑ­1*výÈoœ©“š Â[fj¥nÍ&½/j2=Ô{gFŸFei¥Ò²­1¬ÒÝìI§ùG§ùbí®,LNÙ“™¦Ká°Áy5€ °Ww¤ËXV_ŒÊÍŽŽÄg‘®rr ,ß#©b,hâUïè>í㊷Àm‘å¶Èõ"@(rÃ0Y(iö`Š wŒÀä-z0yL¾ïÎá$Ö•ùÚ™¦JKgGî›òå¥jŒ'zg²bý >}|§0ƒ°ŽÖä䮈ñ’fîŠxò€ ãúͽi““s:ìœû®—ŒA?`^¬ü¹®ÈŸpnQ]2I-ô°­ey$[OsXú£,ºjq' ¤aŸÞÛïKký™y3ÞhÈFñ[2ø-±!A2±J š?cì{ØJ°Þ—%@‰U»3ò+“‘ l\¶›]LøDˆÀwß6;Žôã‘^ÑÂHw]SÜî;øñ5ï#åŸ÷¦ä®êÊ0oÓ[|*»Þ§…P¾§·1Béø”ê—ÏŸå'Ç‚kÝ"^Ì+>âÞ8„÷{‡©F@ 0õ#9f…~mÖé¾ì.í}¬-@a0ºÞ²¼ªêN9!:@.:ãUO˜T¹3âðlë[¶]9Tä7ð˜½å†êÒ;ÕÿÞËWÈÅÒw³ƒj™GOé|Ø ¸Ç+¡2€p%jѯkœŠMK•¾ª®?ž0 Ø,4€Í]ýŽ:9]v¹§õ)"ÔrÏ£¢L…#Ç>.ëêÎH¡ä* Kuï]^{ŠHÿH–#P7[ @2ü¨êf›dª2EçÌ Fô†‰<ؘ_÷EÇp 3!c²š±ìëíÖT4©s“O•ݯ–;ª]iRÛÅ>ˆØÏÒV#;„¶´Ú…/æã\.¥g…’‹HƒPÑá" ¶ ¢‚¼O¹HŸ¤üvf6šþZwE¦vMýõAÕÃ%sÜ1#©±ÖÕsÛŽ+ŒEDÕ! <‰çß®E´øïñùêâ?rÄ,°2=Vû™lzB³1A¶Œn¾$0•’CQ–’Óaïj&€MÚ䳬F°¸JÁÁEg‡®®ë}“¤²¯_^½«³Oß¾T Ÿt ©ª;;·I;ÊdaÕCŠðäPíÎČ͓ êÑ+*)sbÄ~´£`ŒÑ‹bçÔ&šÆ _qU&º³à‚¤-ĺµ#•‚% -é™ifÜg$•îùûGôC1îEcý0 Ö ý£ØW(Óv&O¹cÏZ B™%z™^Y¼q_žžŽ^Ò({o‹ªr8OÈúˆžYg’ð–Â…N¢‹ŒRס,«øÿï+ˆÞ\Þÿ¯Ò8iˆía½›ŠëÄo•Ú’º½ö¬sU¥[ó¿©+fca1TnòFò½#˜®ô6Ÿó g×½Eg{ßɇ?¬Þ\ ¯Eáâ 4Ý ÓV¶ĺåûÔL´K™0×øsCÆð•Lkâ[‘&âÎPo^ÚMH Ò~Ëm!¯ Û¶Ÿ¨«²SÃijͱ÷£—Ì7Š)ô¥”1W]תX«‡z¯†"†-©ØíwÂòwMÊO—µ4iO¿­Jí£±.s¸ vùCÑ ™Ñ§ãzi¿t]YÒŽ€Ðl‹55ÿ‡YžUïËœiYÝÌÎYﳦÒÇP&ãèŸÂÖ¹¾ ‌¯Jm\¸CQšGUðßÓpV1 œ•MòÙÉ0žSjâT˜áÅÖÎ¨šÆž–X^¯¯fÔ j´Â½)hÓs2Ðà”`€¾À<“­ÞóúwßÜ(›LE/š;S™†Ÿ±ŒôVô?fÛÓé»´mu“Ë[ Þt3¨]Ü–Yó°£ZX“^yò st#—v­ èô„0þ{¹öºí|}2RwgF#ô—c˜o9Î ®Xs­lë4êsD=¤Ô¿ÀY$ŠÁÛœE±«dÒk'ÐsA ]“–wô9%)¦n¥"™*“^¸ÛNVÇBý4”D ‡”Ž)(?¡kç¨,­(Q {(MPÄuÝÔ[¾!XL髲UµÃ:™yƒ¯Ž¡}¢>?AÇÏQíeiö˜±'¬Õu¨\Ò3êú×€.ON„•?À€Ì9š4ÜÕÕé°2ǰ­‰U¨Å‰P[á…>¨´C/óÁÅDC©&È÷-`pð#êbh]\Ž\ ë! TSpQ›W ŒXn6D.áÑkX×.!† ‘ endstream endobj 952 0 obj << /Type /Page /Parent 1716 0 R /Resources 954 0 R /Contents 955 0 R /Annots [ 953 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 953 0 obj << /Dest [ 1379 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 374 757 401 771 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 954 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 955 0 obj << /Length 2532 /Filter /FlateDecode >> stream H‰ÜWÛŽÛÈ}×W4æ© ŒhÞDJÆÀÀÚ³qv'‹±âÉEµDÆ)Sä(ʇäòyÈ©ª&)ÍÅÞl€ <›ÍªîªêS§ªß.'¯–Ë@ùj¹™øòðh¸QäÅ*YÌÜxî…j¹›¼zw˜«ìÀ2ž:dÕäÕû¾Ú&žëy>d²É´'ú§tk”ïEÊYþe²`¥…JD¼ËhŒÑõ("š£7žL¿$ö\üDÍ› á§!™ÿƒÁ¶CŽ«SÝ5j¶é*=83—â7Åôº6òªäÑ:®ÄXµ·’ò{$ùºY[ñ¢RngÓu±¥¸„zTW›ºÙ)о·Óƨ+ʯîk2E9øºëΔΌjÕMc¾tEc¦ö„¦¾ ×é`Ƚùèé\<]§]›¿Qm­®Ä= »r}íP൲“ªhUa‡Uݪ}-/V…„½*jrÂZöáwÊw=Z9ËMö™|VðÙÁy‘±›Xe8á†v¬î56:e©VæåMΜ ç¢Ñ¹È¢ðÂ_êtp+E´°ikš{Ç•åÌsI注IRöùå˲¿¯[£Ú§èmQ¹jÈ àI1sU>†Pdkfä"Q=…à†óDÉkOÒqºIpV弡Êõa@fu«ÅLÈåÍkõÁÁ×…¾ʘ)ú˜ÌáÔÖTÀaAÄ©®Ô®f­µyLO+Çl‘¸Þų̈Ç'ó®®Ú´¨ÌpÍAJôãØÄ(>¶VB1ô‡ø|Ò7Nw˜âû|c™ø‘yS^è)O!ÿ ËÄ*1hö ƒü±ú¶®êº4Xç!-;Šk ŸÄj4æŒ6ã3×¾£&#ÒmÛ«®%Î~¯9Âo˜ä%\Ιk,„¾Ÿ#úIßšMÚ•ík‹Õ—·8ƒ—h‡GDºÌÑCá/U‡½ÉŠ´Tõž1E% J¿©Ë³ÂÊäéCAýH "Uß>gk$Ò ›œéˆj€aâ'›ž)æâçà2¹«ÖÀ “jUË`£²BÆåx¤»ÕÓ9×]$CÞ]µäg.üºÎò –!ùéÔ#)XæóVÖ«eºs(¾ ŠBÖ‘ÒHî~`±[‡˜ö±¯J„­M¹Ù=_ÕŸ#zŸ˜0( >` Ö›:¯©Á¨HCÉ{hÁÎà .²ŽØUFS&µk’¦7Y7J·'ŠMç¼ùúÊ…µM¸F 6·Î\¯©—J4lI2\_XÜ}öÀ½ñšà…Š?" j ¿˜ ëê;`§û½©,²K)ô¨3,çrù’þfs-&.Ôêr×÷ì =Å¡­‘£0Ò!Z#îBÒ) b®ª³ºJ)åUK«ök+0ê2ÐÔªßh/@Î jäVÒ¬¥E%÷n¸ dü{¾ [‹¦8Ý>9ˆO¶3O¨3_™²>Rk²ä‚F¨ ù Ãwû†ï5ÏïìËÌ.¢ìa-²—¯öt­À‘j‡®®%o:+Dn ½,• dYÑS­! –é#Š/5<µCÙ³žð•PÃLÒpjxÒð sl­ƒ¨?âÁl9°B!ô~Ö ü’"y1^Ï‹ül¨_áPäç¨Ï(7„9žàjqµï¿À†ˆ¨Ï~Pnªí· {˜,Ü௰­—ý· »Œôp?f“ÒÆèÛ…õ¿Yσ__ÏYIʹÙíÛÓ£Š>[ÑG–é¬?|.óDciîÄ#ÄžCïiú3 éL !L[¹=Øœ,1“¥¾w S®^¸Û&£QÉPé‘\hZºR\Z‡ïÕ3å×õåA¸ÁEÊÆ2£!eÈ@ àæ`ª5®*û®)Þ\Kû}cßëª<s–ƒP±Ù˜Æð[EYZ‰¼¾s¸ŠÐëaÿóÝÖ 7 À<‰7VíKdzýëš7»Øçp` J}šnkŸµö³XÁ2ÕÖ™‹r8ý”‡ÏÒø7ØkU‡}-½n Ô„"ËÑw?àÜ{‘¦–æÁ”¨°¶`w?äãlÍ_[Û«ïÒ— ”€ÆÀ³sÀ ehjŸ=R$(ËPm×T†\‰õšÂèkêçÝ_Ú»¿å.ø$½»ZéíÕ .ƒ;sÞbÿ ¦õn¡ —¾.ƒÄóöD&Ù…Z.ŸrD-e>µçVkm{vùµ7 Y¡¿V´J>öwÑ霮»|×d%ÃüñJ±¶ 5Ûlï$)Íwüdýç.aÏ ':åë—ÎŒÙ誛øE*]+¦òµVËï@,<¨Ú7ãf î)DœãôeèCZ‰r}zî mc©æŸgçTsIM.3›íè¿_Nþ54 ¥ë endstream endobj 956 0 obj << /Type /Page /Parent 1716 0 R /Resources 959 0 R /Contents 960 0 R /Annots [ 957 0 R 958 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 957 0 obj << /Dest [ 1379 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 407 598 434 612 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 958 0 obj << /Dest [ 615 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 365 132 396 146 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 959 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 960 0 obj << /Length 2462 /Filter /FlateDecode >> stream H‰ÌWÛnãÈ}×W4Ð$šwRÀggf±‹Iv±V 3yhQm‹ŠÔ’”4ÚÉ?äóS]MR–åñl°Ã"Ù—êªS·Ó¯“«Å"¾XÜOü@xøÃ#Ê7мD¤óØM2/‹ÍäêÛ6ykÖx¢Í«ÉÕww¾xh'žëy>Öä“Yÿz˜ÈŸÔƒ¾ gñÉÜlš‹Ôsç ‡™›x,×ì Ìvz‹ÚýAþ+Àè,𜙺‰ô2±<Š»cÕ­1Hí@’l‹VÜ~7û·3‹ñÝ`.vcY8žÌ×Sqw(º_uS!¡TÕʙͥø§ùuþ¾øab,6Öž›àcñcFƒÃáà:¡ëË–NÕt,DãH¯žÈÜ­¤·‹‰/ 1 âÄ _„©›e"ñ¤€Q&=¹Ÿ¼^ `„>–xÑÑõiЃ"ë£Èõ",ˆÜ0ÌRÁŸ=¨i»ip‚*@³¨zUßw}ÏÉ`”¸n‹Í¶ÔjDi`ç`ìÓæ«¹™Ž+̈]¶=ܼmQ=”ZìúÅÂzDÝ( A#žŸž¬K`t1¡±©Wº7,;¾ÁoîÙ‰5~oŒÏ¶|[W**½Eõʸ$µ*Œ1¸iïTl ýA‡òºu¿Ô“ ¾ööyC(D£«ÞÌ‚MPp°hD7³©Jä¬+A!–1ÅVI@ÚTj£§b«ÚöP7«3 FMÂAŠŸœØuK©É®kŠå®Ó-}ú’ôñ‘_ÈKMÐUuuîŸKøFùò¾W»²c“³ŽðÇ:ÁúVu'Z‘+·i¨óâi—™$†s´3«½1–ŒžÞ¨Ùˆêl„õƒ|W76jg± ]‘ËÝNuE]µS(:±)ÖXjÑ­U‡-jÄÆÚñ),PB<ÔJÔ÷b­ö(0#•hõV5ªÃ6…8Šäéq3)½tÕ¹êf¶àŒVÁˆGÀª’Ð!2§àŒ ˆÂ> ±•æ¥ Xñ:¨Á•+ÞÁTÖ4¶s0¥ßÏ­™Úª¹²ç±€)ÙmGDw¨aԃݫʲ>ˆ®[[ï ä²B*E½`ø ÅшS3(®Å £¿¢Ñ_ƒ€R=d€+n©òç|/ò²š¢kŽ„Ôðês©È?¡ìÄúœ½…J‡&°JlT—?¦„ª½4@ëæj«LîÛ|ËëͲ¨Ôew„¯,ŠQ–4ª: Z Š<, ƒ'fö×¥ó)¾¯z· mØ Y¿Þ8A\ï 6Ÿô‘~)oÄG+Nkñ :‘: ß|tXŸŠ`  M¹À‘‚ú3æ,b5½ì“lôI6ú:5­ù­72C Lö8Š{Uîl" ¹2Á#K=,\ Åo‚h£;èùQþáÏ0¢¨Oí*¥K»ã—…À%ïxáX°ª)tëžÕ±Ð üÓú;êïœ|S›ü‚z³ˆÀãTèß)Ì»ØUe?Þ뤆ÛqʇPÚÒc%úè›—tÎ,#Ÿ˜2Hu‰r{.+÷¬ ©›¦UyTg!ºg6zò´<ŽAÌUþígEíý#ôηØiu âå S t¹AS鮯ÎI(Pº^æ‹8Š\t%C{NÈÏ‹³q2ÌFAîy:{ôzvû ÓÃÙ!‰åYð§$:ß}y¼mä(YÆ%ö³qÂ’t†Î ‚ðèY-Ÿ›4™É/àsqó—gûsƒ¹!˜Ï¢óÌüëÅ×’Ô(`Ä)I S &©>ˆe’º±( õLd£Õ äï±¼5}³¨YahöÄIKÞ=5¬X1°ˆÍ-bó¾%ª9í ì‘ü8ð\þ¦WLj@ÀͱüKœ u¶Óåñ2™IF&6̆¸**þÖðêÂt(tmo $ÝxY”EwD¹³ëpk0O³yÅAoOagøa,ƒ¡Bô!¯!#Ëã3~ G?…¬ë_Aq‡RHpY>.Ç\ënèL¶ºšÚHJú%¼~O—)~%nƒY³^®Ü*^ ˜Òeæü4Axûæb‘XɈ‰|-Vª#Ÿô2YÛm–e­VƒNGTåÝôänÈ÷Bsz,»)SÅñ.“i†÷Ô'â\emoc]{ß!kÃ¥HäL©øåÁ™qicGgO°¬÷ñ$ Ú3×V~¥õªW°6µñ¥)67»êÙ 7–a/o€æÒBçâÊZ›ÛŒ¬:¾{é½¹ñ´æQcv½ë\,Ǻû5M9@ûϲӦ<–åtlÊw_·ºmQŠªèÚ¼) õßò…ªC{¾ãi¤Ou„6U,¬Ýv/·Þ F’tüÝZo0¦TŽ ˜G×§½}Þp\LÅ5anòJóPÕݼП´ÁÛ½*J£R-º”–޹Œ½z©!Žt(ì£Aüô³3£Rò£€®„n‹LïkÝÿ”(á‰]-ÚXBP Éʧ½Äž6ù;RC¶÷V&y‘1Dƒ0ÓÆ¤Ç^ØÙ…ï&~rê(‚Õ®kŠå®£;]Œ GÊø§it1°˜Ȫ®ô³ÇžÓ¤ßÌÒÇ©ˆÓ†\¢ßob2šËeymê9·úÉO[_Nq\A<*•fH 5rð°¦LA©ô¾o0 ¥ÐðÛÃi{¡WúgyT!†ó¸k(Ãfb{,„»âû¡%g\ë—Ú¶¯•¼•ÎÍ9¥©ú®C%›ÊS¡(iêWý´×žÄÀ^5…Ói{2ÐÇ€æp‡í¾#ô°.Ð÷r‡f¡ydŒzÔTžCt¼oê%¦ì3 õXöbZCÅžŽ¼È[žÏ»·wwßÿø§¿Üþl̼sÈ%o©7, %¼£JÊqÕrW”Ý vÝïÀÈüž† e9íɤ [ ÓW°:¸­þgWXkë endstream endobj 961 0 obj << /Type /Page /Parent 1716 0 R /Resources 964 0 R /Contents 965 0 R /Annots [ 962 0 R 963 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 962 0 obj << /Dest [ 1135 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 465 420 506 434 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 963 0 obj << /Dest [ 1144 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 406 113 420 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 964 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 965 0 obj << /Length 1858 /Filter /FlateDecode >> stream H‰ìWÛŽÛF}×WÔcÑlÞe LlÇHà`Œöeí}àP­ŠÔÈ“ÙØ܇œêâÍš›‚lƒ‘Ô·êªSU§ª¿[/^¬×>iZoÚ'ø Sß C/¦d¹qê´Þ/^¼nSÊ[»Ç£6¯/Þ]jºnžëy{òÅrøy\¨Ùµ! !Îú—ÅÊZQ⹫sAêÆžÈµg|{œE1Ÿþ¨þëcvé{ÎRn¬¼”®îèò®êv˜ñ•q IµEKïÎè_ÿs–Æ Ö"7R…ã©|wF—Ç¢ûÍ4¥¨¬Ú8Ë•¢ÿØOçßëÖbkï¹1ë7˜³G× \­Z¾Õðµ+]üô\_åýÔÎJz»^h*háG±Äš‚ÄMSŠ5$ئԘÅvñÝz#ÐØâ}‰Æ„®Çˆ(‹|ö> ]/ĆР‚4! &Qä&þ U/Põ"±IkWN åé¼5m[ÔÕ¶¨Šv×:XZ©¼)nºW/éRÖ[#%; TS8 Æ7`µÒÓÐuñW®—Îtу*Z4y]W]VTfCEõÒš¨Ql‘±› .cd rÞ:‰2¹©ºí¿_Aì;£ó¼,ت@™ªºW§Š/íKFe¸F‹¦rÁÅmV8HUfW‡PéÀ¡Ê¼|\UA~Œg¯Wµ¨èÃÏ¥úAW†·¥º*ï×ɟ䥣¼´Ç/«( ¾è ø¬Œ`fW‹Øq]†8ôÑa5ê°)—6\¬æsç,S@#ÊÄÏ)ƒ°„…–.úh„ qÿ&:ž;Š¡ U×5ÅÕ¡3-µU†àéÀ’4QU]™G¯`øø¨Þ˜mv(;±7}ÖÞ)koUÛ„ºKOìóFË„¼“õ'²õÅþµÃü·Ct‚ýZ; ù‚§}@Ð8!2 ĈDÀ¥ðû Z÷;Íg“µ wœ1‘2•á|â#”õ‚Œ’|Š8xíS?qÈs3ß°E˜©CYÞ}ràÙ}¿F]ME7Ü]m\º(Kr´§n³¹žÙU9œ¨·Nˆs;3ÐöI~Œô2ðËOìÕ~¨”#wø¶+C‡ÖàúKc(sb\É¥‚)¿ùQ€v"åmë†6™W¶î\à!×}%wGq„á³ÜŽÜ]uEgöm—uàd_ìBÛ«òkLn„®oÍfØzhOx^´wà JÙ„P{ÁCœÓ×ä¡*”Ž’D @ÝÚázÍõµÄ•!к~¾DDú¤ øV"¾•ˆo%â*ÑT"¢¡D0Áq‰H¬ç!ùæ agÛàÉ´%JdQõÛí¶Î&¤åâÙ´ü”O‘2EÖK;šrô6à/ΜkËp¼sU³6F?k06ü_…®ŸXþßÜ+_õÆÔ¥å\:'o‡3ͽò54ÄiŸ°ûIþö¿û9ù<8ÜÀrÆ,À3‚|ʼnn‰ÆF¼Zí•zOn)ßdsùe‚Èôó˜Cß¾g^»–vþTöÞY&ç¥}6¬ú{zyÚ#T“À3ÛéÓ\÷|'U·MâH{¿6½±72»ÃûdoædòN¹6¼5ÆšC½¾½8ã*Œæd/ HèRcöug\ú‡ÌçlSš3üƒMÏäÁ#œ=’8y}(7Ô5ÈyZY—·û¢cßð¥<Ï j¬Z§ÈÆ«ú`KÀ¶,ò®%Óåî  °aÿ<É=z{°8 1x¡Ë= tÓšŠÖ(«šÉÿŸo©ØÞe-þñÒ„+Y¢ã¨Gdï]úÁî£-Uµ¥o¤ØÎ&CCß_¼¿|{F5Î5÷Kûr^Û宦¥Oª=Xj’ÆU*D¯JÓ÷•·?T[Ë-Àggò_ÍFºÖ?ž?$³kaAD[(sB¢UÎq4‹ë2´<èvJÖ NïËžè ò‘¥—BÖÏÙòv½ø}-¯õ­ endstream endobj 966 0 obj << /Type /Page /Parent 1716 0 R /Resources 968 0 R /Contents 969 0 R /Annots [ 967 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 967 0 obj << /Dest [ 961 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 320 92 347 106 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 968 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 969 0 obj << /Length 3309 /Filter /FlateDecode >> stream H‰”WËnÛJÝë+zÙ,†l¾Ào"$ÃR™dŠL˜Ȥ!Rñõ|ÈüÃüã,æTU7EQrâ ÃR‹ìG=N:ýÇbòf±0*T‹»IhT€?|Źñã8HUV$~š‘Z†oôÊ>ºçf‹I¨*51IêGi¨¢ÌÏs•†ˆ¤‚q®¶åänòÇ¢FbJp}tŠˆæè!Gù8G.’Yà»ñ bZ÷UÏg‹ùârñyþM{±ëªîÊu¹Å8´®ó^‘Ÿ¹¡ Ã<òsbGÉÍWÝvXœë¥|íð‰hìwb« â£M8Ãl–þæ½µYÐ!è¡zoa…=º¹Ú³=†”ü&DFDLå†.+%œ€^®o¹¿Q\—.Ç™C¤àc_{£Nj\ñQoÌA Ô³¶´å•7EÒ ÓŒ.ןdÚûK¼t¯xüC~èxá‡é¯¿ñ¨![§¤.c®K£Å_Éùûe·¼8ˆñTÛØ]>ô€iÂâ©ï=P­Ñ—‹K@•lhR:xÇè—ZP×&ÔÅêa€ºP`G&‘±#°ÆØâä²×õ»ã5<ˆÒ“PC„–ÒŒ.è‹xên,Ó@·í«qïÌ› ØÓô;ðlo(„O!óµ?!Ó5Ÿœâü©¾†ô?Í O¾\ƒ c`€ñkþ/ühìÀÔ ø?cœ%Œ³Ââì?/¶ó?~~,qrF¡4ʪWs]&Z6yðˆÊ—Üz9hÇД:ì9TP³G&9Ë硲ˆHá7qÊŒ1[Œ†±ê‹ÍE\¥A|(®œD{°b¥[Ú~–ßðu¤ÓâÂâv¼Õ«pkáãwÛA¼¹FúTØ/~k•õQĺ­– y}³òžƒÞ¶’©×ˆDÄÀP á#‚Þ4Ñp…Ï2(G˜ÜWÉ^“× ìÆ<$<÷j>ÿ<»þ¼ø¦¿7ͦ\Öª'˜AⳂ:aª’´ðóxHN¼Ér³ižî–Õf·-Gü$W‹++ÒÂ4àzÕgê˜"¼ícŞĽn¶%ßµ ê:h©úq¼È¤P÷§6zðŒ^˜dxï¨r€±eGb•H×<‘a•<‘O(ZêHn’:¿fèíº î°Ò6ök-Ô€†d$ÛÙzâÀ¿äïH.7»ÒCë…}ŒtÇ—Ø™”ÂÓ£Œgô>ÑÁEM^Qã=ë§K)Ù—òõåzF“³ûí.µd°é±¹ûMÙûÍœª"¤cS‚7ú&pµÚyÁ’Õþ 3|ZC®îŽJ© Š`Ï|GÀN>ó‰50ΛVNỾ(~îvãD7Ýw¼È^‰8côh°³w4¤N€²%1çäz+…üsö‘“¾ßöËݵ ·®t¤ËÝ%5v—Ô‡¦+É`bpU­© n9OÕfC¢[­–;y-’ÜŽ‰¢B-?ZËÿÌ;à?Þ’K)3l;Rù>[Þ®ùKâ$ï˜Ùò^•±«PVZT¦$3ÛÇ#E dpÐç¥ä%‘¼$’—ˆòbï0Ÿ#즗ã¶Os˜K3ø‰Û ù‡·äQ&qÁåö±A™ø1¯Á¿¹€Ê¡{ù. ûaö{†eZŠ‹˜tà_cØ 8µòu„æJ3ÊŠ!¡¥=¡åRØ%L¨,·Ÿ;Á¶›¤Î?”–ËhÁNžH‰§Ê15Ðe¯B0y8î©.ý¹±éÿþL75M:ŽwôaÀ_t¿º!>J@bÔ߉;Éôº&–3úVÊm´É'7`)ÀÌÙ_ä͵ÈìÈ1Ý[N1RˆPezö(¤Òƒ³(2î6« ‚ãÞî(jzP y°¯Õ–¬D‚!fb Ñ,#‘,­KËÍtiú`ëЕÙ]c9ŠRêáf„ÀÛûJÇ )² .t¸Ö•}IZæ! •Øn€ã¡­iÇCT¸v»AËP>™ˆGD` /$¨8¢®é£nsòN£ceÑaáQîåÇ™GDuC`E[TñI…‹PŠ#´[óWÊ8‰D(¯L]ÞCK÷g°]¹.Yãè&§L‰Ù“¦é=–‡ºÜv«æv¬Ó£8%•tb—×±KdmϲlÈ.¹e—Ìr Ú} Î/7¥ÌBÅ'sŠë‡HF>B¯ PVĶJïëî RÜÝB‡*Á9àŠ!`8WœÚ£#V{7¹¬šº[VuUË»µ0 — *Õª/ÐtÎâ’I„ûhÖ ¾­$ªâCl‡‡©Û4ÌÔŽB¢“„|pk•Põ(Ø7ÔHj$B±pRGžu ÁuŽê¹„¢-œ02ÍU6>$¶Y“e‡|?îÕÚI«Zʶ­öŒpB“¸ - ÇPð1Ê3%?³À/è&Åà™`X±\Á@naŠ¢‡¯vm×<¬ËΣŽr¿¬ùù-ÜmWÛê±»x‹èï@k!E©CPtó öS)÷ I†Ž´ü8Š˜}bn6aØGÀ¶ãùs½úôQ‡1>ŒÛk;–!ûšuš"§;;h)ˆ6|'HEBªú-¶ÇžE TP:®âþ–K›œS©Ú"ýi¿/ˆ" Øé|µ©¨EDÒâÑw±jâ#ÁÀ}ùsYv±Þ,¿Ø‘Þx$Ê·/›:›vD;Uµº¾‘nþw[ B­jêÍóË6 ™÷ûY xî·Õ.áK~>¹þ üjW$ ½­H©ßÌw|Ìwì9ÅhïÊ–­üNTA†û]=FÃü‚ý SV˜2ïŸõ§PôÆÉ`žØYv Þ8ô3b}#ˆ3L -Ѫ“€oDeü’[]Ä5Èü¹¾83à:¹w?áHW”1€9SéŸN­ÒSSÕhl“¸òˆ8Ä$+R—¹¼d"J•f]åq <…iRzŠØY_Ù¥$ÇëÑdXìÔ½š ØÐ~Î<ékUö¢ Htcñe©1ü»íªŠ1æCGjCuëeÈšF®Q²pßm#Ûƒô>h®'¸ñ~S½R•ò•ÛñPÄ5¶¹>:‚ÀRè¸î+’µið:úö2§x-ÛÙƒÁ ,¬™îöç4Ôx¾[òvf«xƒÌð ñ¬œjO¨ Cøº¬š§f…Ð,t&<på_­ÜÏ»hy®ƒ¼Q銿qñ7M?Û½÷·”—ü å|sHÜ#›9ãQ*WZÝsþt/õ¤t{É/ªòJ³MÍÒú^p†&`Xç9B ‚!ˆRªÇé#ŠÐ™‚æß´Ö•]|‰f‹»_»Ù\ê endstream endobj 970 0 obj << /Type /Page /Parent 1716 0 R /Resources 972 0 R /Contents 973 0 R /Annots [ 971 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 971 0 obj << /Dest [ 961 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 387 530 414 544 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 972 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 973 0 obj << /Length 2135 /Filter /FlateDecode >> stream H‰ÔWÛnãF}×Wôc°8¼“2“É$˜Å1låeÇû@SM«ŠÔò"Gû!ûùÇ<ì©ê¦(߯^ HvaÀbßêÖ§NU³š½[­á‹U9óáá?Q¸Qä%"]Än’y¡Xmgï>t™(:Þ㉮¨g﾿öÅ]7ó\Ï󱧘ÍÇÏû™¼Ìï”ð½L8«Ÿg >´©ç.37ñŒ\>ðqúŠ:ýEþ`vxÎÜÝDBÎíA\ê~ƒ™@*’d§;ñþû3ñ÷ßyŒq‹µØ¥v=7…Ú°¤«™/´˜q↉/ÂÔÍ2‘øˆ¤€Q&Z5+g߬ŽÁ}lñFcŠ®G‘=ÜQdï(r½"7 ³T˜áÔ4ŽÝ48‰ªQõBã“ï»~êdn$Ųº¾Ùî†ÞI1nU7Tý!ª0N¥j»¢Õ;ZŒåŹøÀ»Å†S é·Òõhø³tævÚ¨ºQbç=?¥˜{Ò£=±±ZüðY\ý»+9$+DÑl·Pœ‘¢ÎÑãu!Ùc´Ý÷n¸ïÚ|£ìCS÷¹®ÕZèúœï0ÄÚ$HÜtDÁ–G„’eçPpœÖííï„Áô3Ä´Òdn(•™ªû‹Ç†ÏYVaºUãK‚÷û\;7¿uµ•ƒ0Juþ²©óñŠ^¶®Åå%F(°µÓM݉¦®/ÛNò²£¼ÌÆ/¯q3C¾ø+ácá‰_Ò%Á‘V)r׿cÃâhÆAÉf¨_{gNÐ3Æ$¯ƒL…EÌPê($£°1Õ¾?9½( m$û¾Õ·C¯:úl àëÀ2™ ë¦V/ªÂ`ðñE~«ÊéaüÍ^õwʶ”ý­aršU>òÏ;zf8Ç{Ñ`â÷Àø¿rˆr7@'·ãÈ«ª¹·ßægÇëªÐ¥Ƀ3bÜ®fªu"d#xIûF0)¡{µµ!˜2x÷g./‘$©h8 –WNÊA°.˜L˜GhÜíá–ÄsÆÛ‚0…„Bçýi¤@Ü*1tª*Q6­ÐÛ]¥¶ šYÀ‚\4+Ê¡.zà,¯tpOµ/>|¶üF¹… Ap÷C[‹Õ—ÀHþôQèÑC;˵@Ã1”/ÕÖŸx‡9Ú‰ºa`ù²ß0¯·â»÷Ÿ¯?ž‰çÚ§†Ig~Ê:FWÛ‰py±POj×»Ö”–ã¶VûOuy㈼U¢Ø¨âµv`A(]!ž^Ç+j ùäĸ ÎÅ|½Öt„+2¦f298TÌåP r/x—pW ˜"©JòRïP©o¶wŠ+bºiÀ1Ø4;`¾ó¢B #ãçìDqÃVQªPœÍÎÏ!OrÈ@úÞ €L¦ˆÛVi˜` ‡§^ ðdY@¨/³nª~«Ìˆ¢cúñÞxÒ´6 öÊ—@ÚÅùc¾f»¢ø Wû–«åmÓT ¹òéúò§"rãœ[ª³|•º‹l¢D¬_‹,5~‰+&,ÈøÄ4¡ÌM$@NIÏg 9¸6Ññ£B€Šñ„öD"cpŽï*F¦fÇ‘DšåæGfɈYH(sKFÜÂ͈‰4ÉÃ;y=kÉ™(óÊÁf£&lë³¼RfêÈUÚ[ƒÞµ{ ý[ºÀ( @ì§]àD ÁÔfè¶P¿—÷¹î‘‹]ŸóJ*á¤á÷tÔ+·í°³Ÿkã€Å5ìu‰Ú©Mg—Ø{ÞUŸîZÃ8cìøÞ Ë=åÙù!î@qY€÷«`¸@ëüu€X·Å>Æ m{=¦à>¯² …ñ-m×ŸÚæ„Úœ©Ëy@¡OºÝl1Ö”¯c‚FÁ›êë¤ô¨ll2î "Ó õÇß\lôÝt¯ŠM­Á2 Ÿ–q Å œŽÊêP”ˆîm'4m "tPfî )½ˆ‘iþ!gà% td´+©1;„ú5§–‡—F¸i’IÇóµzjáF"xÀ˜›|M¦¡µá!%ƒéýÑnu“5X,‰Âj|ÐnÑ?çwŠû®Z©ugh„R èêzàTcv~¶˜E“I¶¹©©ßrx|iþçdG$ï:…{]U¸éžôPq+Žj|T¬Éœ‚ˆXÞfÈ ­îZµ×Í8»Ë[n‘Ìš|RÕ¶z¯þKÞ âGÏÏ“”N&Þ]€©´´ª: ˆy[詛ʜv(õýz¦¬S5O1}ÆÜ4ï°K  3÷ä!÷”ƒÝÉˉáés•ØÀÝr÷»·¿d_$ßôÆûë™ïä÷*óqðcK|Yb]e2Éàácú{K×üLÝ]mt¾{ê"Ãdá Õ•¢SÌjucºÜ(€›‘ÜS ÄS­~£:ÎÛVÍl<Ôòémö<;,&Ûƶü °©n^†/ykꟃª{Ãɉ¡ÜDš%ó_›fí„ÉúD>Sêtwi—¢SA¹=ÑŠר@¦@$¶@àaÈ÷^‹õ°«´ÞÊcþAsëìÄËÁ/’ yÝØˆUÍüá:´ûM]êv‹œ]þï.ì›.Æ›®•*{Ñìé‰Õâõi)‰-6Jâ?ÜR×Q[MÏñ³¼Uwº®ù%Xò¦f{ÊßÁŸ]ÛìllfÉ®¦Åö£«`©@*Þª'ì±x#Ç·£éø‘7Žåå«Ù¬¼¯R endstream endobj 974 0 obj << /Type /Page /Parent 1716 0 R /Resources 977 0 R /Contents 978 0 R /Annots [ 975 0 R 976 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 975 0 obj << /Dest [ 1634 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 359 318 372 332 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 976 0 obj << /Dest [ 595 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 341 237 370 251 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 977 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 978 0 obj << /Length 2019 /Filter /FlateDecode >> stream H‰ìWÙŽÛÈ}×WÜ·‰æ&Š2 3¶3 ì8ˆä—qçM•¤sQHªeõ‡äòyȹ·Š’,wǃ Ȇnˆµ×]Ϲõírôd¹Œ(¤åzFàŸ$‹ü$ RšÍ§~š1-«Ñ“]FE'kêŠzôä»EH›nøAbM1š ÍÃHý1ßh ƒ9yËŸGsÙ4§YàÏSg~ØseO$Û¹5My÷{õ·£“(ð&aì§*ÈèöH‹cÝo1)íá$ՙ޾ùnL?ýÝ›LÑo17õ§Êx*¶cZL¯ÛR‰U^¯¼É\Ñ_å×ûóòÇ‘h,ÚDŸ¢³|‰1‘àp8ø^쇪ã[5_‹£q¥fàGªpC[9éÕr’¡Q4Mý8 )žùYFiKtL2jõh=úvy2FbIð©5ÎÖ Ø"J¬%ÎG‰$XøqœÍÈv£Î¦S]XsΪAdu C&Í 4=[éÛý¦Øî¥[¨ð Uþ±3÷úùSz·™ÑòûÖc/Üþ¬‹žÎ{¨3tP÷šJS™ÞÙÔOâ8¢ T™X”E­릥^w=6¦ÊÔ»*f×axÒ+˜ûQv¡W8¨åŽ|ÑÔ}nj½"S?çÌÔéXÝ©?Ü{Š·Sèñ!Ï:o¦tëM¡Ïû>Çapô˜ž¥ñ`¼Xi;T÷ϯŸÈ˜…è¸Æz ;y s²æ5V^+êô ¢†çIJ'TùGê ÞL¦oÖpN¦Ø/p‰í4 Ûz ŸÿZ†roa“ÛX5ô[ëRS#½zOÂYó:º\ñ¸’ñIÉ0%­tßp&&ªï[s»‡Ÿ¹*V•úeUƒ™Ä|ÝÔzˆû_°m(–Q/õ:ß—ýS·ÁûItq°¸!öƒlîs^Ìu£V†Uªü¶Ô«ÏŠ8‘Nz' mFgY†ôrN2m¹6á?§­ÙlË#b¾ØÖ¦ÈK8y;g;3(õ=’À§ÖÔéžú† þ ÕŒ‰ãCåeIx©£I©‘>[ ‰<Ìw;]˜µAð×ûê³Íz€¶³ø,Xz–Ña,\®Ywøå`pÍ­&Û•˜#È908¬púÜbÜP7T5­>‹b§v@V¸{Èñ‘êÓR¶Þܺôæ@#íݽ|t¿5îžá £ˆ)i{/Â% Q“ MÅïÕÆÅ4/MpFµ+u¥‘p½i öA'Iñæ5½\6x_ˆ’¨(]5½¦]ÞöFÛC|VyôÎv÷pÉq,Æ'<`ìð"k]Ú>{ƒÄK°öÛ ÀlŒ¶ÔÊX=Q»Æv{ïïñ5Ÿ¬D´ a6âJ÷À­‡*± Ñ^C‡­®‡(²#µvÇøÎïÙpºõ{…¬2ŸøA²¯`d‹?—*ÿ”濆¶¦ÉÔæª¶ÎÆËÒ3o… îM˜{À^¥æÌ‘Á £‘ÖP—]ñ=¼Z2¿ ¤d±&¦;YËb$Ú#„u ÞN ýÑt|)¦/ÄyÕ}™¾’yÆ4ÿ¿J_Ós¬Lì4M©qÎ]^îY*ÐÐÍÄÓfR§*!Z  «<"Kñëäž(ã2yø>Ì4i=0Ǧâ2Eð'y/ôst˜1§ÐæÎ0„ ‘ŸÛdâRá„Fˆˆªbµ‡6"žÝ lE²èЉ¢§U3Ò5h¾‡;zâü’ùþ¤#àlϬ´jÅy<—ãÝý½¼[`xÿ}sÐwnÕØil×UúŠèF9 w²Df5äÛÆÑ©Ì¼xaý±ðäžÞmµxL×Èy]’'Ö¥=²UG«ÿ²7­î¬F-ªÒòlÁ+§ã§”ÔÍ0☀å…š¤fÇRÞâq‚(wÏ«·AäÞûNƒþ*}ߨJ_?÷äÉó”(Rxöw­Üû@¬,ÙAØ#Ï7H÷’c_BÈ8FDF ðïŽñ?!ƒ³¨•MomWçhݨNã……ÅS3ÕõÌk\žÖvLÚál¨`¿€jÿJ0¿LíÚÙ) fMQ1sÍÞYÂFжQY£ÀöS¹qº÷&üÚpnà †£ÇaøÂǧpâQŠû•^s%H0d„^{“l–smŸ)—Ö?¨~Ý›˜Ó´}Ž2ËV$\Å£ ݶMmî¹¼8˜~KˆHÀ’NTÊÇG%: çò¸Ûïøx*¦¹Þ½ Á¸ñÔæÚ=$Þ-_Üx>ý¢˜ºëSn™Äý\ jÛÚØºë=Vú3 Äbç(‹ÁÞ-^ýɆÙò‡7¯¬µ~âÏ\½õ8ÿþàoº+Z³ƒµöuáPš"õl ¦ gn> endobj 980 0 obj << /Dest [ 817 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 416 757 446 771 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 981 0 obj << /Dest [ 1283 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 464 703 505 717 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 982 0 obj << /Dest [ 615 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 369 288 399 302 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 983 0 obj << /Dest [ 1008 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 485 274 512 288 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 984 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 985 0 obj << /Length 2428 /Filter /FlateDecode >> stream H‰ìWÝnÛȾ×S |5$†ÿ¢‚ @b»)Ú$X«-к9²¦Kq’²¬þ·Gàµ`~r?=’úïÖ¢ßèÎKýD ³ëµi„fÍcéVí,‹ü\öSQ½÷E½WnÜ·¥iîUkW €ÎCÔÖTJ\ûÞ¨¦ª<ˆK¿·NºBôoÿøü7ö“[Ï?èº+_4îjU5Äbú0’B@†D£M‘µ©èD¿LøO²O‰]«îµÙã ¤ƒ—à/Ì8 ÝSWbmÚmÑw¢Ö¿Â²Ë¢v×F²ðf1´jEè¾€³t/MéE§\¾À%' a›—AÝ‹î\Ùø¤ìbTváòçÌTkdÀ8'“"xƒ zèYé[yØh¶¤Üˆ½Ý¹/j^©Éó¡„eN\ëÖ¾Ùó¤¼nÊz_á6x€¶u=« oÎgŸss8®Õ[Ý«¦‡jX㳇ä5Ω¼°ÊÌ¥U±„ÇQ2¹4^ÿµˆG*ÅÕ’?^¿¿;o–ãÑ~0öeÇ{•]ëµ²¢+Ï;úËLo¶ý¦èÏþqj÷º¹eÑP8¸z­¡)’¸;ÕÎ*d|<—¥«âQ¢;i{·)â¹¥ Û}­%;¬Èü0¿õ¬ÞÖÄkâ ê7ñã8Ÿ û:Tr–%~”ŸAáY@r‡…%^K¹,•¯Š•i{Ó¼Xס§-þ&²[ºVÕë—Bµ­iņ¿üj2ÀJ0¼¶ó¨ó§dpR€–FgІd»¼¹4M_è†Sï%Í\žÄ:ŽA {BýWG§æòÞý¾†0¨9¯ÊZ{!g‹]jú×OŸñ§ ·.ÍUé‰uE.”V_«jú UÃt,“ÔÊXS+È!À$­@J_W&>)f¬Œ•ñ†x+A‚¶zµï‘úx %©DVþ¶J¶dcÅ,ñÛ>9\òJ­‹}Ý¿tœ``s4 ŽÙÖØGþ9SŪå°Ðj4ãýcYž ²tõ`FŽ ,À›!quÇ/¢R=cÀYá*d’û¢×jÐ~S¥Ò÷\‡pÛí_ÃÂì³ €‚xµuí¥ôYtrtèœGl%§ J¬ €W€a‚h‰®6&¡|/\ŸZŠSÌ{ÃÀì`dÇD+z‚vJÊNW3ëæÙÿýÆ4 \l˜Z ÜîjÕ{ÜÍ;ûVɌӕÀu²>’GÚA‘ A<ÌRI É 1H·1¢6Íg^n9¸,苲û¿ iÀ»X ¬Á™9yœ»*¤(rGÄ~WPÔðIñÙÂ}bªç ˆ,f¸ÁØÏt7_LäÄmÂל?Z8++£:×,Tº¤¦¯w¨ïS‡pUµ\™Éý•YÕj{¢ã蘆dŒxDkóS¥#«¥U^us(ûAl /—©‡Ñ'ágµÑÒuûÝžSžhà ½®‡ûI38%A8 xdÕ¯$b~¾n˜ ×,vüáV«ø>^L¢9 ÿçÅàÅً稸$$c"Üý à[ë…pH€¹ÍÿžÀ“ꡳP%ûºrƒ)µ¹tfDSNtTtl+|Neg#ÊñŽ~`æ³ýö—Øýˆ½À[¾xÏ`[[eH‹XWnl³ýY ”¢3[Õë­5®PyaÁ.®ÆÊXœwõ˜*¦yçŠþÕ RÈ僭Œ*{õœŠt s¯îŠÓ½Ó¯®nà'Ã`ˆ~" .Ûê»Mÿ¼Ã¾DšªwDB=ÍTçáȬáènì[Á!jÈìÊ€÷v¦ëô À~hÁ:4YP¬+UêJ‘£¦›E…º:G žÏ9ñˑ՜©§ØôصVwR °1B²lmû–0`És膷#*M\l;r«R«ýx! ù<{™eÜ9&Hû¼g¯—›(¡eÁŒÅn äÆ¿§áàTEŸ0èS8¡¥Òê†ë}SrPo~þð×K«Öå›ùðñšyæÛèÙ/Ö„ë7ûe4ûaîKü ña5…'Îow¹ý9Ø«©*lž º}gßdv¬)Í®®Y¯íÛ Ù±v´eu¤ÕŽ‘PwmȇÔ3¨‡‚ZÆ"^Õ®îî "Èÿú®ä†Šõz qvʧÏxzË}l*+ÊŸ+a[Ö¶¦ È›?-çrùóÕ5}Éä_Þ]’oSymO¿»º•·Þ6QùiöÍf#;k6úãNuú“ÒpЦŒz0xÍq㞃÷< mcoÓ+B7c³‘r‹ž„AüØíÍ7è@ÿôG‚êÊã‰ã]³þvcΑVÑÿQcÿ/5ѧ±ˆ´±˜|†Îb1ÐMOzŠèë=…«ÁgÚWÜ¢& iPDôbh#hô<5SÞM‰Î‹²~¸õ¸¸a *L‰\w<2ýwÒ´nÊz_á¾Os@ÏæDº•eê{ª0ÆãÂa¾Ì‡¥óÅÛ#–Ù·®ë ÆC¡ñfT£–®ÅEc.¦ÐÏžvµïÔ3¦î™Íþnc=åàÆAî!Ba6¼ùÉQ ¦1䤮5U4ÚŽ&L…ÝHjÍåVQ˜ÌyŒ£/„Ц®@"(:jÈXÃëåä?ˆœŠ' endstream endobj 986 0 obj << /Type /Page /Parent 1718 0 R /Resources 989 0 R /Contents 990 0 R /Annots [ 987 0 R 988 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 987 0 obj << /Dest [ 615 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 440 439 471 453 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 988 0 obj << /Dest [ 1008 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 175 412 202 426 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 989 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 990 0 obj << /Length 2462 /Filter /FlateDecode >> stream H‰äWÛnÛÊ}×W üÒ!`1¼‰¤‚ €O잺HR#V ´qÆÔHâ Eêp(+:Òè?ö¡kïJ´¬y=8ÈE$ç¾öÚk¯ùi6z5›E"³Å(ŒD€?øIòÈO’ Ùtâ§y‹ÙzôêÉEa¸O LQ^ý|Š¥~„èSŒÆýãn$ïÔR‹0 …7ûe4åAS‘þ4ÅÄqî§—ÇD<œž&)þ"ÿáë8 ¼qû© rñ¸÷ûº[áK$µ‡™¤)¸úùRüó¿Þx‚÷m"K/ÅêRÜïÊî7ÝVö D¿ÈBoâSÜÆ±äÝ~£y5ZûA®Õ·Ïö)ó2?“ØX½hÚ5ï_ئïñ‘šŠj;×sD‹âÃ{ú(¼LV%Nmû#TJ7sˆÏQö‹ä‰¼ø¼Çÿ¡Ä”!cS©N·Ü@+àkð/-”J¡l£±Zð`û¿.:Mç£Y†¤²uc¹S{麤ÀÄòé%2Xò2>)Ða`xòÆ 1¡bíq/ë>ã‘"¡£Èn¥k¡žÃ]VêdÀ6LæÈ'˜®éÑ5!·Àù¹örùàùv)ˆHâD$ñƒ\Mü8Î3a_{Ö¦ŠiC'vOaèG™‡„@ÐÆ9Vz£ë횖ç…ÚVØìTv›–±l6ÕªµyûZ ÷YëÁsM;…ŸÄqDx$A˜"vù¼WÀ©Î¦m6ºíöbƒ¹BÊ:,V°Œ´¯ ÂŸŒxRÕ–;i#”‡‘õpäZó›9À”Ÿjí›ÏØ„ýÞB»µw R¹¬A¦²~Í Ôóú(á)DÁiØATúJ“¼1ÈŠ&óä~ßb2ÄõR¼)*0¤¶ŸêîíéÆÇ¼ÄX§0æn¯P‹Âî×nuò­ž=m×n±‰/ÅBÑrÎôŸÀNì1¶ï}‡C¼Ïí7>®•òbv¡+ª‰ìº¶|ÜvÚÐk(i×Ä÷2Ö躩5ëô÷a ùŒòÚóµà&Žý$À¤Aߨ¦Ë &43´ÇŒÑ$$Šä¶kÖ®µƒ&„²,<»ù1O}T¾ÃÙmm NƒyˆD .s Ö¯A?#VÍŽ¼Ï0Î@jÍB(ñáöÃÍøúö“ò˜’¤ZcdS©¨<‰Ù?înXÂÏ ô@Çßtè†JW"ßSéyz§Ú¹ˆü§-)äfW÷…i®ŸÊ•séTêâ‹Û•?;”«=¹ž\ꈈ—BU•Ø4ÔFÿJ[UH.I4>9ÅQw³£îfŽÜØPã ¥ˆË¡dùƒp šµße,úR)Q$É|6ÁpxÏØ°·u©?͇™6°¿Æ˜Œ¦ ¡k´ž°>ò£éÁÂÒ‘·_#8t°j3¥nVMiÎ f~QªÜïúd…ØÏ’A^…ÇÀ‡–ªZRµa.âo«Ý–-ÐÐþÒ'ghšµÍÁq_sRè£c"{îÍ×R‰ë{.ð,{«zdŠØÏƒ3Ù¬D 9‡ƒ$g-‚á¿P‡/yë¼è…Ó¡ ‹´ÍmâˆbQìÊÉ»·¾vÕ7+Â’¦nt=/ë¥h¬ZÀRi%¦UÒ¥‚¶Q‡Ó ·|O{H"ç# ¢9”š"„kI«í{Ý ã) wX˜Ú§‡ü¼I ŽÜ wo¾zÓ±Þ`s þF¥bQ¨H˜È£Ò+´J# [³e ‡sý¸].鸄F­wkkË-ó E€p;êhpÝšåœï®ôøvæ¬ÚÙ’hë‹ Œ?¨3Ç"d}&¬u+L x[ÍRLò¦„}(Â\¶å†÷³ØÖ[Ü›Ÿ?\ßüùêóû÷»óH²?ýíîîêÓÕ‡{”£µÒ‰Ÿ¢8ð ì©«ªÙ¹5Îà%à·ÈbE«wƒþ’?o ~b†‰"ÛBÒ{ ãQšq“2úPmtUêMÕ .ã³ 8C\íjÀ_$o/“¼J|)ÖʦòþQ?§öìk,?“«Käì/×7–z¿}G‰›J'·×ðôW?DæÄ5ü á' W24ü“ƒxÄG¿ŸÃ$#oTAÌ6º%kšuŠ«á"ôFߣ[ÁwE'n]hÑpÏ…õƒÂNa{ªŠ~÷"`kôñj$ .‚|3'Æî¥qQ¡sÖÂ?šqÿ?·ÊǦ©4æá …Wêß¿+§®ñÄ™ò{"@ŠúVF$žôf™ÌíÖ]&‰*8e(¨üÚû~ÀJ» µýâ–ö‚Þ&nŒ{¬<©÷‚Œ>·(“c[d÷A¢„ù°Õ¨*¿j^¥n옵ªÎÀ#Á‡:Ø®ënL*X²%¶ÙŠÐþc¹¡²Ú ßæ¨þƒúb{RØÁ{€\Ë¥væƒ[I6g-¹½ç:ý»x¶ö¿¼/Ý_}Dѵå‚~ êÆÝÖ¬®XŒZø–¦"…ábÁ—{ý`â7lai[­Œ+/,ifÅ•x©kÝrYo5Wþ_tѽÀo|¤ÙedAh‘öÉÞsúWCÏ—”D7²îöØÖ¹7BÜ>Õ…ý5—4UHÄ)í@ãEìDl»›%ÐM!úMXßü|Q;ÖuðÝÌ}ÎÿHÝ SãhXw^QR¦)h‰MRõ]”^B©Qa® ª,S{ÏëK\_ÑEtú[g‹Ê¡7ÇéTÞ^‰ q:ØÐªHœñTECiÕÑ5¨[±—%€+Ñ9{èï³`؉©`L]„„]äŠÅÍlô¿™lZ† endstream endobj 991 0 obj << /Type /Page /Parent 1718 0 R /Resources 1002 0 R /Contents 1003 0 R /Annots [ 992 0 R 993 0 R 994 0 R 995 0 R 996 0 R 997 0 R 998 0 R 999 0 R 1000 0 R 1001 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 992 0 obj << /Dest [ 991 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 359 743 386 757 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 993 0 obj << /Dest [ 1393 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 320 716 347 730 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 994 0 obj << /Dest [ 986 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 566 99 580 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 995 0 obj << /Dest [ 1393 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 249 566 277 580 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 996 0 obj << /Dest [ 1562 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 495 566 517 580 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 997 0 obj << /Dest [ 1008 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 338 539 365 553 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 998 0 obj << /Dest [ 1385 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 386 539 413 553 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 999 0 obj << /Dest [ 463 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 455 389 470 403 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1000 0 obj << /Dest [ 1016 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 462 267 490 281 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1001 0 obj << /Dest [ 1254 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 145 140 172 154 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1002 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1003 0 obj << /Length 2701 /Filter /FlateDecode >> stream H‰ÔWÛŽÛÈ}×W40Ò F4o¢(ÃÀëñ:ìfœ‡ìäC¶FL(RËËÈʇäòyÈ©ª¦¨ÑܼA 0Æ"›}©Ë©S§¿]N^/—òÕr5ñåá~¢$p£È‹Õ|1sãÄ Õr3yý¾MTÖòOµY5yýñÊW·íÄs=ÏÇœl2wý‡ôÖ(»9Ë¿N¼h¡æž»ˆ±q˜¸±'ûòš€—ÓÓ,¦Õ?éž3õC7Ö^¢nöêj_ukŒÚ8ØI·E«Þ}MHiàÎu·V]ÑÎ|éÔ Î/tQu­wë"[«Mß:>mÔ9r¢nŒÚ5N„Ç¢KoJsí¸ê;‡ÒUó±òM™ks:ÈÇAs|èR1Hö©ežQEuW—w&ÇÃ)œ”Ç@ö“NUëÄzOæºÊøÍÈ=ÒÀ€Ü×Õ+ë[eªŽLô^¥ô× dBV¬ðÉ·k` ´Vo±LÆkžÖ8>­ßÀz€ª;G€ø\»ú×–9>íP–$rz¦·[SåØîÖŸlCˆÜ w½ùÁ]z$w¯uO‘‹t‘¶²„J† gJGV·Ø®,*ÎÆïëÎñ)BÀ:í(¼iž]QWkh Ï Öœ©}Ý« V„ ì©ÒR¦ Úž‡IÀP[3IHÕÕ¿·3(½Ø¡3ÄüÑŒzcF=›QÔvuc8WEµª›MÊ–\vs]Áõx8(O¼´5ŠH‰0N ;àoˆ³Q3®¿ Hðé »È’]äzj*rÃ0™+yª+žÏÝypDOøféÉ ÄJJ´ç$pœÑa*xáàüüz‡/ÌÒÛwE··Ðã%é ÿ i‡UÉ)L™ù®—™â–Ø2/¥ÌEóÆFè°­eö\a©íÀµÚ¥MÞ¶Î\›†kòÎþžc38q¦ÞfeAÅRPi¨âO ŸòôJÐ’CÐkëH=bêìSýÙXð3Ù㦮Kƒ}îÒ²'«í§ Æø1#{¼£nxvMqÓw¦¥W_“Iäåó&IQꪮ sóó1^Öf•öe÷Æ.°‡nÈÆÓ±B×[ ¥ º¦·ÞMyòX;o¤Cœ2G2–U2¶ƒ·_ÚÁLÚ#רºQ¹ýÈa¡ÇoÉê&/ª[•fGF…:þ@ù¾>+˜em„9Á(ç¨ DVúŠ´ÙÖ˜ÇyaìgÐ)× Ö³ak©~*óýD~-ØËf Å„@"-]Æ÷´®ÌXª·o%Õ.DBN<îk»²³¿7vN;Ú!wS©¡Ð!iÔ¶ìoq”5%rƒy§3ÒL$Nƒ¿ q¶3¥FÑqˆ™¯UkºŽ’Çž<§vÅ©õEn„)ôd5xXVUv-ª5m‹¤µg å zË"² ÍfÍE¾!êdÕòû?^kÄtÕWÙôÑfýP’ È Tþu"2ÂÚ  Žâcuž­Mö·gç ¦Æ²BÅ*h>ο³À—9`@/Í)%½"WDÝÈj©‹ü‰D§ý@*G–Ô,¬L3å¸2«Ð èD¶®5ß|I7[ê´Û†qGµtK±n·ÔS 4ø‰‚i‘Ö4­2]ær~Q'‹’9^;ÙAhÕUèã8h‡ZkÔ1÷©w>*znÊ2È“_îckðÿÔÇ‚ÿV€ ,`Z4Ñ(Õ-•Ô×µ~ïÀ€…ž¶”&Õ Hf/´~íE=Œý£mèÙý‚ÿ¬ûù§ÀTð½‘B §M>¨SA_wj#EÝR½¡Bï×È0Õ‰ÏN;gøtçO<6žxìœ!:'õnŽeÉW^{ùqO©£—+é†o iw¸zF&»6}—ÝaQò!ëf´R¼‘¦ƒ¤ç½WeZe1 hã>½EF¢ïÚn°—7 Ô!<}±ÍL2$‚DP¨—>¸v¼‡7’åx-³ö|#)*ÑÿöÒÑtÊÞZ̪/Ouý{¶ªË²Þ1/ý¹7Ufìí„Ù|¸Ì »æoÀîC >ã͈VžÅô…,4Ò¯–¨À5€r[Cõû/‹QõJµ{\AÓ-?¥Œ‘ÚAÌ÷(—ý¦î[¹M¾jÍ’Š7y¬xù(Ø– !Ëlé¾½µí’bð’ÊéŠlC-!™ 3’H³­»µ©¬¾`W:Üݶ(µ¶Ï†–Ò‡æUÕZÃÏÖR ·Oìlr4ا\š/Nˆapª%B‹µYZ!ö¤gO(Cö Lpäð%&9°}Šªå—{ˆméÅÃJ¨Æ¯s0X;X]0¹¾èÚCÕ~ëmÛÕQUº!9Kµ‚Gêc‰Ô@;!ólóToóި󣥿ùf8Ú·gh)Éxx4¦DÓ‚ûd çfGwl¼bæ7ç P4'jñ‰ f"Ñ#! P¯ÁIÌÂã&õª¡˜4¤á0Ƭ1ÒÏÛUw­‹ô i•É åJÁ´sHòmàý¯ËaƒçrŒ`¾—ëòâ ñrßîGÔ1ÛÍ’…ø*Ñ·„™¥åàźÞArÅ"îí ‘ÃÖW“-ö„aÞR¥yngË€•ʲ4çÝäœü 3ÀÓ„ª˜ï‘tÂä!瞪LVfzSÜ®Ñ窬ìsƒZ»ßç¸õVêï?^ªzK¯-ÿ¾Â¸Ç¿è8ôÅ'!’3ÊFÏÊÆO‚ sW€8BuyXþtÉÀ¸•Ó2„£o{j¯¸+¢å¥êò‡—ªê77p‹þvMÄÖX™öë€tBŸD˜½€£±#ûó‡Þ03KÄ,}"Âb…¼¢iBÇCù“V4¯”Ǿ4ç$L¨5¨t»…²Ê9»u‘­Wò |Cl4'`ÑH&ë dœªqÑ ôÆœ?ìÏdõ˜ߦC0,øKô³µ“¶‰ þüLùx›Ó‘t„k–EöÜ”Î#ÛmLŠ‹¹Œˆ22Õ—,äR€±¥P-­´CP”7{œèø2??Ü"è+Á=ví9-yEüˆÅ1C$7¸B”¢É¾²q#äî“Ü ^Àûl´bfBu2ã–¦‘?#¨Üq ð7QÑ÷jÚ¦©ï@¥¹Äd(bN~f˜¯*ªÇSÿY :!úmÍ,3ˆÂã1ᣠkä´{£NÛò×ß0/ظå~KÞ®¨ß¦òÜäò»ÞÍŸ UïŒCàLç2õ»¢Ù:<žÄ:SWõª“a¨]»Ò~D^üðCe×ðæ$_ÁÜ íUèiÅ: Q·þ)˜1ô«Ïê~»>áˆ1̉Ï9D ù÷ Iì×.#$C endstream endobj 1004 0 obj << /Type /Page /Parent 1718 0 R /Resources 1006 0 R /Contents 1007 0 R /Annots [ 1005 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1005 0 obj << /Dest [ 706 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 442 305 463 319 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1006 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1007 0 obj << /Length 2087 /Filter /FlateDecode >> stream H‰¤WÛŽã6}÷W B¶FwËú!³ÉÌlìÃNçA-ÑÝZÈR¯HµÇùý‡ýÇ<¤ªHY’ï“ –H‘ŪS§.ü°š¼_­|æ±ÕzâùÌ…?x„‰ï„¡³ù"râÄ Øj3yÿ•°LÑ—©¬š¼ÿié±g5q×õ`M6™u¯Û ÿ5}–̃Xýg² M 6wE ‚ƒÄ‰]#—öø´ߢwæÿ÷avæ»bæNÌÝ„=íØrWé˜ñ¹ ‰«B±ïš²ÿ!fŒø9/„˳—)[n ý»lJð´ÊÅlÁÙÿèWü¶úyB“5¾ëÄ0Xýs¤Áv»uDàx\á©Ñp¤¯®ãóÌN½¤WlâG±Ä æN’°Ø$Ø&¬‘“õäÃjFàÁwŒF®‹ˆpB|”ú¨Cr»pÎJo?ów 1 ùÒÚû9tÂ…1Ô¬÷;èñ _êTÌB€SÈoËp<絘!ê¹4C¶®¦_À9lˆx·MiÀ—7ÝÂGî²bÍTkÙ‡ý¬Ôº-§,¯kÂ<Ét±±ßëVO™•]–¬&gà‡†u/MÝ(†[¹]×Tïη®žy’³3|¾7|n 3–ï8ŸW™y~úÈš†`jDÀ·àGÔæªGá  ×/ø ¿iû  ")Q'ÅZ‚ß!®¶k”&øH¨8+Œn•9íw2e7nöú3ÕÉQVH]±}}³´}1b5{±ÒÞ`žw ¾Õ·¶h[d`Ë‹õ—rR˜WºÃËGXΞ‚–Æ3â 9_PÀ°Àˆ5ß dÅò€¸¾ã%Câùà»±Ûùñ„Ù7;)‹t¸¯p ³9oaŠÛmö±? ˜l6L- B”âšAB)j¬ØÎi@qbN€¼9$Ì^Û¡×OgÓ9-µ*ãBÂï|`RÁl˜ ž$ØŒ©µ¥„›eÒ ÍïZ„¼-™|“Å7MÖU–¥uj¦´ AQoæ€jo’Uu5»~ÀPJª[L/ž]qž[IÏoÈ-…I!æ»Ñ+°y÷¸á |µôò’赫2H ¯M­ë¬.Ù›lTAø7Eõ ̹óÿnÊàáÝ1ðöˆá@Ý‘pÇ ðÅøûHuRau§gudÂ"˜÷&Ľ ëò_ÚlŠŒeu.‰d“ðBÀõ#=È0#óꀃß1ïÞsÜ)óááMYp/æ°ì=a è2rCMÙ,mU>_ŸN6Ÿ ö ¸”×bZ ×{½…!Ž·énÊ<ÕàƒÃG–Ù²ÉÊBB’òïÇÓJÄǸÞL½Aò’æõQœOa‡öé%µó+ö¹½}îÀ>½{%£2ý¾ª›MZN½{UÂDÀëí´/¥±J2UÂóÜ{àYÂÍbè689‡yÜVo¢v²º^—Hñ 5è÷Úc¨£H“YZ¤2–œü0=‰ÝQr/Ó¤otÍó½ãÍÆªÝ<‘?`g½–&œ•u––厥y¾7þ‹xÎDDù"ârƒì¸áBž9°A5£‹õ:Ð( :bHçF? ÞñQ5 *Ý‚š? ý2ub,B—ùÔÃ6Æ ÕéÐÊeIÄ’Xý±CÉFËíš-F@¡f^ì,®"uD´HnR êœH½øo@ÖÞÙW­}…²&‰l_C²ó൷‚·ïÓ]ªÍ§°³Êux®'ãrDøRR\^Íȼ‹-`‹03L10c^”À3$E(¼ |±…/¹)FýzòaØ£ž о±qý³Ì[§E‰ž¥V‹ áÐ/2ÿH©¼ø€8&W=î=*UTY½1ÝD#3Y¼QªÍêJcéÊé–ãÛ0ñ ÂyÄZK5¾šá’n)Ý+@j%5‰³¶ôBû•GÅ‚4÷HÚ®[~ÉÊ6G]1‡¤Õ› Œ }žða«TC3ñ"Ó‹ecàëQ¤äõ‡áuî/Á }ösm`U`ó£0æ;Àài÷Uhž”!¿Ìn„²AD0;ÍCøö …1IÝÃÅ)øôú~гýà?©Â.jMOd®8±CW¿~!œ2óI.%tZp+aØJ…VP ÝZ1’ôßVÂ…4ÁØ·R#O²´43f7K¡¥¤æ BD¦O¥¤}ßÑÌ!oÜÞ|‰á3…i®Íãü°” €Í–RQoÿðx¹UîwÆt]³uQå,¿7нֹ.—Oí3$¿ç5$“)ÜÓ$y ðnë•Æ]2^8AýÍ>ãKfà®a¡°Iuöɶ¨¨Id¦ ¼ZL‰2ÇÇzöð•MÇ@‹uYdZ±-àø´#º(ƒîM’qˆF¿ËP ³á´‡7¶kJØ{À e2å¡ìáZz?s<¥P§.ßR <ºåí+|ؤ9EÊÂ÷%Ÿã>œEßT›F=‘6ÅéR»q&9a‰M‡Øù-ð6á[1]k¸yP­Ó¾†QÀ<Ò­Êç}5£ÜJ ¶ºšñ‰}46rxäÓ€?Û©) QÕ²‰S›3ÒÊ,z­ÍXŸ®eÇ­r—i¿Q ó,: þÿ†ÉêM–5ÜÊrÓ¤¦9Õéma=êtýW;eóQ‡ô°¢™Z†MKÀ©¸ÙêõØÕ€“.psžŒÓ#ì¶Wj$êFcÑ–-ÿl®ä×K Jh?®&«% endstream endobj 1008 0 obj << /Type /Page /Parent 1718 0 R /Resources 1014 0 R /Contents 1015 0 R /Annots [ 1009 0 R 1010 0 R 1011 0 R 1012 0 R 1013 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1009 0 obj << /Dest [ 463 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 295 658 310 672 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1010 0 obj << /Dest [ 1379 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 158 379 186 393 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1011 0 obj << /Dest [ 1385 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 324 379 352 393 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1012 0 obj << /Dest [ 489 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 182 285 199 299 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1013 0 obj << /Dest [ 1330 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 401 258 431 272 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1014 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1015 0 obj << /Length 3173 /Filter /FlateDecode >> stream H‰ÌWÛnÜÈ}Ÿ¯hÐDš÷ᆭ­ì:Ù]{=ã—Xy È W#Î,É‘¬ýüCþ19UÕ¼h$Ë6 Ùì®®®>uêÔw«Ù‹Õ*TZ­gA¨|üá'ÎB/ŽýT͉—f~¤V7³¯ÛL-ÏñU[Ô³ß/uÕÎ|Ï÷Ì)fnÿx7Óïó+£‚ VÎê×Ù‚-ÔÜ÷) G™—úb—ׄ¼œž’”VÒÿ 1ꆾã‘—j?S—÷jy_wŒ„Ú8°¤ÛªUgߟ¨¿ÿÛq¼7ø–x‰®_›µ¼«ºßM³e#‘ÎëÒqZý“ÿ;ÿXýuÆ'æÓ„¾—âeõcìÁÝÝçD^ [ÚÕж0-=<ú^¨ ;´aKç«Y *5 “Ô‹Ò@Es/ËT ’ gŒ3Õ˜ÙzöÝjF`Šÿ0ct}ŠˆæèáŽb{G±çǘ{Q”Í•¼öA'‰7'QÅ7U?”3…N§ÕËíîj›_šmûêTaŒD_ºê¶êî>«Éy¨4üÓHÌàNv ™Á‡páùÙć w!^ïê.¯jSªª>å@Îõ`Ö"1õæýU Ø`BF^¶Î\›ÆI¼LßÚßW0†3œ¨—Ŷrè ÚÈPݽ:vÜå-ð•ÀúÆF+¢•Y_óZ⯸š<ãê'ݙϺЯ ‹‰vÛ®©ê« çË{‡ÃÞAÊ{˶gd ÖÖ_:ÓÒk É:ÔóÁòç ›zW›:Ï9àÛÑoÌ:?l»S»À޼8Þá&û«TŽù _%¥iÔzר¶CŽåMIèYW[Cƒ7yw¢J³7uÙª]­ZÓàÎ^à–LÝ)<¶FùT.ï9„Æ‚"yàî³÷ÉÈ9‰¸´rR\øÆ ˆªåÕåWJ÷Ü8”ût61`Œ‚÷¸în“wªßüŽmt©UÞû³1jêÍÀG°Û©-R™1„(ZªóI?w rØŠr|°â G<õT„ àüÒ¨ƒ=ˆ¬8lU·ëý7ôW¡GáÀbŒÑg:D~I‰˜é>DŽ Ÿsšžã#œå°ON8g8‡å/‚Ó # ¶bPÇg²3's1øÿÆq‰˜÷[ûÕ£¯ñ˜2ߢÉ"ÄëWY4Y´ªñ׵žT‚tµïœ9ªÖ+„'%JâYü}MžÅYÕnZõ#ÐEƒù á÷q± áB)ž½ßµ+±ñâ(É(@qàOBtÌY¼ lÂÖBwÄ©n¿NÝIœŒeèvLÈŒ¨š0Ú)“uÊ¡’¨¿BË#EoóÊ¡ËDÍr¨˜oÛX›Ó/û"·7( ß„çýâÔH¿ë釈i{ÿ-Lý«/yËgÞÒ|]Bwh¦+u¹Ûm ìÞæÛ÷¹¿¼ZˆWK1IŽ!¿7C°Ä½ô¿vO0eM}Ñ›ÿ“jöi,gtÚì™-ÜqþéŽvSö>hË£ó}­$cI ú’Dêd#hòÂP h3eþ4¸€Ê}Uæ³)D’—`åé¼c;2ÝXv£ Òìù#€mº†±•ÈÜZ{Ðî-enÉ9*Cð kÓSoº&19)<§¤Êp\“D õ±´L¹oŒUC\šöÍ®w;ܶХ5=ü}jpH¼×9½fúÆXYß?=¦ŠÉu¢—ˆƒÎzË}¾Þ®±CEZ‡*îÖnƒû®OÙÞSJÁV­ÀsýQ69?”ÝÌê´Þ·#JKô -¡*oíR»‚ÙSnìBk®– ;bM=]Ç÷A–ôD+tÕä5…nywèào ëƒ{µ>4ˆt#Ÿ·Ù]öžȨ)9z»²U9£öIÿ¸<‡®Àœ¢AmaÀŸäý ø«148ؘ_MÑ”ôèÑFO뇲\xÆM ®.w¦Uõ®çM’(GE„;U̪r‡ÚFžÊ#; £Üa’GI UlLqm'å2fTmPÝðPJNÜæxMô¶Â û+G/)ÓBÉ4 ,‡ÊK‡bú*·†%ß)……vàÕb¹¼²h³­Î‚”îì®cè^>ý¶}%5" ÅAÌë =Q9K„Ú¡¥¥å&œÒ#àîÃײ²Ë$Tc<-ó Ç{ý'¹r8?^LäÕ¦gȵ$‘FD‡\5F>ä ­»€v¬1 »·f«ò°ÕTmÞQô•TF.tc®Ð¡l ¸g' z 6þØuöÂA …Oòl“·"Ò«:ߪ6¿Wù%#¹è9| A‘“SÐ*»;¾S8 +M}O¯yy(ðÄâ›RŠMÇ¥ &a¼O î>…Œ'biSbÀº±©ÛúQܘ/9pp‹ðïRþOcX¢Ó(ሜ”Ù¦âÅ|˜‚#oíБÞQò¸Ow²o|ǹIZ@3Wë>A#êè§o­ä¸ â(™Ä¡[ñóQÙ‰²äccäáÀ¹Ñ3˜|ëÓ?ÒùJ†,«ž¨gð“O<§ ¯dØ®é×>™Åñ˜Å±ˆ¨L)ÍYÀZa>hê¨B–±®¹cëgÈ3%`I°°ÓlÊÐW àj·+Õ~›œì†x*gÖÚïЃÌ3²Þe‘!C{ÛWö›jŸË,æ± ßQ³ô.Ø}/À‚×FYë2¡cf2’,°šìiÖ€ hTWÝõ;¥n¯eEÚ•s/\Œ‚ñ †œp_â…O¹¼ð¥ë¬0Rψ:«À6ù-CÇ.±£¸ Ëò—ùú:€œÙG¨Ít]Ð]Rš/nvÉͳ U‚±˜­&"rÛ³Ò‹¸n DoRu×ëÁé‘çÕñ|TâI¯Q‚¤oº:s…Ûän $aEqõû¿]è çH¡g^”Lš€1ö}Oz*¹Ɔ¹ TI‚£AÃTY± ›¥MNÄ$ª&Ö%¿¥º)¥® .«úÚª0ú&Ëz2p„hb ýîÚ{Ô*²Ï$ä£R¢Ð·yè°ÑÙÇÕ—çøäÀ¼ðüxÚš<’z§Š)S0Föd.™²áQò›˜¬©@Õ 9nœpAgqq˜cßy[ò=;ºÿåùŠýùì§ó‹Þ{ò@ñ¢égpn6ÿOÝåÓÓ Dñ»Ÿbã©$•tAÚbÒ“Cb±‰ÑKERI,4€¾½oÞRØV=µ¡û‡¾™yó³ñûÆ]–¤V0/ÁdOL¡ÃˆaýuŸBV uè¾UÌýkº“iwcÝ8›Š¼–³ÃŽåÖ‘ÀÒŸ«õCrGÍooô‡Qcðµ]"º»j68µ0=ë,46 ƒzï(—†‚¯/+õÚʬɂ!°îÊF=ýÈxÄ/íã%áb Gý]ÂÉK±Æ~ ¯XFzË ƒJB†C™Ù5Ͱo³Zàþ¸³õ5a|{æèÐ;jn–z¢ïú鞟±)”­4_†îtf%ˆßÞEëJþˆ0Ád±)ʢݕŸ5$)J•V˜;ijhXhÕõ‹3Vz±ßtš D¼ŠŠ•·Xq iÍlQ¤Ë[êƒà‚':-çÜú¢i÷™2ên "Òf=À–ÏÞÀóN;ZŽŠ&æX6û\õ¯ Â{xºOeÁžŠ$”;bæžøHefƒ! Eñcr'Y#®C<Mç4Hfnå0 œNòƒá‚þò4S ?rL.ãw2/$FRHiÍ“ÙÌ…n “œo¯Ï~z”Åì endstream endobj 1016 0 obj << /Type /Page /Parent 1718 0 R /Resources 1024 0 R /Contents 1025 0 R /Annots [ 1017 0 R 1018 0 R 1019 0 R 1020 0 R 1021 0 R 1022 0 R 1023 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1017 0 obj << /Dest [ 1379 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 245 708 271 722 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1018 0 obj << /Dest [ 1371 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 284 652 312 666 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1019 0 obj << /Dest [ 1330 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 299 528 329 542 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1020 0 obj << /Dest [ 1150 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 317 425 358 439 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1021 0 obj << /Dest [ 1174 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 344 349 394 363 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1022 0 obj << /Dest [ 1174 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 473 274 522 288 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1023 0 obj << /Dest [ 1400 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 216 133 244 147 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1024 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1025 0 obj << /Length 4144 /Filter /FlateDecode >> stream H‰œWÛrÛF}çWLåiP%ÂÜár\åÈŒãõ–½kQÞu¬<@àPBL2JQ>dÿaÿqöt÷€)ºjk+ŽˆË\Ýçœ>óÓ|òl>•QóåÄ„*Àø‰óÐã UY‘øiDj¾ž<;ïrUu<&P]µ™<{saÔM7 ü 0SM¦ÃåÃDÿ­¼±Ê˜Dyóß'O*TøEŠ…£ÜOY—ç„<®’”fÑÿñtÞÔD~ªƒ\]?ª‹ÇM‹'¡¶VÒ]Ý©WoÎÔ¯ÿñ¦ î[¼KüD×^ «Û3uñP÷ÚvÅ‹DºÜ,¼i¡Õ¿ø¯÷Ûü/þbþš0ðSÜÌ_ãGðððà{‘otG»ZÚKcK—êÊ=ºå•fó‰Qµš„IêG©QQæç¹J 2©ðq®Z;YN~šï’ ³±Ïn@Ñœ=Ô(?®ÑÉ, °Ï(•AáRÑ}H½éímÕåûwï½i†È?üÛÆÈ×û×Ȳ;ûôVœ{ÓÈÏôìJ_yüU#xD~â$ûÄ»}bÙç9¾°ß¶›NÍ?R=b}9£eVõRõ·(þ!•jY£R)ЋQ—^õõÚÒd sÕÂÞמ·µÅ¼FUÍfÊQMs?GVOX{-4{‰gc«ž·õ?×J~PG€H‰ñÝ÷Þ” iåÎWÃ'»l#ö,¤m²bÿÙ©Æ‘lÓ!¾Íº¼˜}|7û|"s¹x—ìVH†Ä½±½d¦Ú¶­ÝôjÛÙö«}TWÚ3F—”ÆHwª³=óÀË;Nn¨çØY®8ë‰~縙ɜÏòŠÃÂJªi©JÈè½]¨kŒÌõ#†hÞ]’‹B›Ã䆻܆ñ‹mç¥ ±;¶íûœD‚åÕ·ÕKõmkåÕ£Œ;Sn¶26øƒ!æeÚ7é•w\ð+Ìv¬¬„šZ1+¦*(Ð|ˆ3`è‹Ù|W WšÀ伃<$™<óM ¥E°S9ï$h.G¶ç_¦Og g‘i!­«àG‰û†ov’ú_ õ¿/W[be&Óe¯ºÛf»B¥,Ab¡ÊNý0äÈ ÌLŽ–ïSåpt0 (d<êü#­™F$1 ÿ]‚ÃÔ‘>Ìâý(° zÐÝõÜ€M¹¾ñ˜ù¯¡-ç3.†¤OÙQøq8®°?ðê+œ 1JѪ=)fò`þÚ]|"ªçúí¹TÑ=}Gœ†»Ïô“3=¨AðttÀÜ#©É÷R“K¬Øžâ|qc{L5¢3Hœ¦x ó‰ðÞ%z+?n1$†dŽ! 1Ø7É J %‡ß£šXR",ƒ\ /ƒìºzPV:IROk¦Êè{®„ˆHŽ PÕÔ¡–gªh)ŒÚˆ$ ¦åÇÓþ’œâÈwØ!ËŽÉÉ‘í“võ˜Eö¿Ð¾$;¤‡4!H{’ï{¯GþÅꌾáVƒftþ w£Ùù»W—s¹FAˆIL qß+J˜ûy€PÉÇvʵ UŒzÜ‘€%°ãÙÃG¤ÜG ’ßÕа@|Ç!ì³&iîl^"# @=Ù=Úm¹ýs"€>(;ù®Q"¨»õ"9 #ŽŒ'âO…5WÞs6ul†H¥‚§¦ ÄkNng¹ÝT}ÝlT¹r¾M#ŠŽÔ$”¹Q–;1Y5äU`QëõÝÊ®¡|”þª¡»Þ®¡‡2 <2ݬUuk«¯õFtåÆÃÔfé¡©W-“Ü.hr5,»‘n«_¬š›ÚÙª€# w‘ /ÉÓÍuOúdÈû†,û‚Rø[}׿ôÕ[|_O6âÏaÉX@Œõ6Ø·H[ ®ÇãäÇÊúVö]°­]7½ÚÀºì±›F¤ÍÍ¿óHMmU¿,Ú¬dY[ê±^I‹}±ÍN‚ø‰óåÖz(ÆÌHÜLá ©ÂäÄâ¶ÚD£È·äÐ ŸwBäõ†#¡’™z§Sf§¬Y1ÞÀ™› â-žX¶}ÇƒÈ 0Pë­d™ð‡|A~m´\©;©o)F[Êß)j#u_«•-åVõöm½–#‰C‹CÃG#CÑŒÁj¢<“ØÀr/ÕkÖÍEòã?³%yõWv#3nó"Á‚\\§ñ•†4\‘T¦ÚIôó»’îèŽ;ÔnââÊÃ*·ü> ±RÔK±;¼@%­‹…Âàæ¸ûx‰|uŒJNô`®ÒÜ™«ËŽÕg[®@ú’iO÷=K‰ö-· aYÆT—«±úY¾oV÷V¦*8”a(4…ê%/ì°V¯–l¦ËCìí¶Fåu+FAyœò^ꤊD;É}«å¢ìËkN¢•ô"‹³zö™@çüâïž¡:Jñ”í+ÿL2,îȯ¼3u× u"ŠôõJPýHçÅ{WMRÐg‹¡2w¬¨œ‡ˆQLxhTsýD.ö&WYá$º/]‡yÔeÅ'. yÊ rº‡¦]£¤ lÊYnŸƒ4Ý’xNÉ,=Ôi¹E†¥Ø¤dXeQ>Qéé¨Õ6a2DGSC}í~;d(-eÁ ¡¢ü´“—D•~ïø/dªaÄn\iÜTrYô¾õPޝbùÁ#ý9“lÄiôü’ŒÇ=åÃ*…‚C™\|–1l¼ÙÅɰm˜¤pÈn¿ái/Q)yÚ£€< íÆ¸C(?‡|ºéÞV:-»k›»¶.©­úêçzCT;3ïQ£Ò¦šz¤4¿„38%Ýkk´<õÀöbÛJ[m­ŒÚ2W=Z1ìž8=~ñ }4uÈï0FÇ®OqEUV•½ëE½ÐÙ凩“êßmÕK—D“¤†Ž  ½9ômË¥Œ÷XûÇ :è„ìg‹=¶o꺶 aJz€¿åúNñù*רEãÑûO2`&ÅùHoCh~’áçuÚD¿~EC³á©»ûUæ»1ïÝ:W›Ó¾§‰'ŠM*©lÇ>)7c?e £ä¥õîq¬íM Þ‘dPd¦ç_ò õš^S§trR6‹fBƒ{j‚1y |“^[y×Q“sÚ¼`ªìÖìú¦µ?Ô0׬Àé`<ùŽA.g4ôÓÛ±É88÷D-èµAiÈ1ƒt¥_ž¹Ov«¡áŸ±Œá€ØH€ñbºczâ/ƒ]¶÷Uqå\4X=ÖŒ7¾*)QÑCá7.˜ƒ’á+.N;”UèTßní™" ñ©ÓBIFLCôòìH–s·^TŒtF4V«ˆtFnÕC½Z‘ã\ÖX²ØR ÏÖ HúRP2Ï0©GéUÅ‘k3ú¿Œ—_o›JÅßï§@y)HNêå«(RnS]UºI+Õ‘"lHêÊ$·ùö÷ÌÌî²^¨Ò‡(–Ýawæ7çõ»Ú9§#S{²‡N¦|álÚŸ«?‚¨­¼Øl—1´ÛϾÛO߶ײ]·Ô3¿n¿Üü­ŸÝm5ùˆy"­çÉGùB|HrœxêðA † :Ø U`N¤NÞRJ|¢::BVåó+gj5;G"s”»G±1‡êX¯­ÏÛT¡/ùQ,S¨%™5e=–î”4Œ¥+¡s3DúÑCÒ^žÛTL2wÊÅ]OɸMàá:lçÜ›6W®ì¯næ"‘=|×O,šÅ’ØýæxLN].’‘e$•`¡Ax¨¥ÉI²uU i§ ‡¦¾˜|tõÆñ~N_ºÙ=Úã; /±“_Õ‹Ògƒ¶ŒH˜U{öJkÆ! -Ïø|tY0ÍùGÖ‚^íô8 ßœ<ŒòêÖõÜ u|d@!Ó¾@Mš½éÅsê­ÐM…tÅNÿê‰0ø\yù׌à$Êñ^J‚ó"’Hkü‹ïšë|7s±pêf0‹\¥`Ý.'ÿEg¡¶Pql,”¸Mñ;&Hr@Á¾¨ ŽbdËE°ôšîñìx¨aPÄ ±áAœ-‚3‘!ñv¨èIbÄs}øEUó@“ž‰7[H/’‡ó¾Dr²Ä’æ‡I~JGãy;½ŒÁcÝÏNÎE§=x/S÷óFHÇ7«,ü Ìüo‘{âÔç6Êö¥ˆ¨RRâƒ\·¤O öߨn¿l?Ö‘/ix}û••÷}Èigò<ý-Q—eÌCüZÓ‘åŽNÜaæIŒÜŸ{Ï998´­Ï_z¥e¦;œªúOΙ…3¡!ü°ÿãºØhÈO­M?2¹Y=‹Ë€Œ¸8[)Ke*Eö9Ô‹,ƒIÔW\&5)0`¢‘ª ÆŠ™œïuË'´NX B­ºo\iµƒ°¤möµ”¢4[Nˆ¥ ±DÒ0éÎ/Wй{àà~ ðÍØ‘Æ ‘©-Á#E_ßJ)W±·ÎZ›×‰¥ù¯µQB,?·Î!óÎÂV2ÕƒÕź´—®,͉â<(EWIªYá2†ÏzB{ff¸ŃNA.„æéE*ìŽFuãkÁÜžî¶óƒ°¨^ð¢nËèG3‡©r6ásD–öɃ1®ˆ]dH¤ê¯ïJBñb¾/hÿ±IŒÿð`êÐ2õQ)>ü”¿!qü‰é©¸˜_¥ ØŽW˜Û_µr2Ô®‘Ð>H‰ ëTQ*V.A¥Ëå;A2ùFJx”¡Ë•>B«æùì#ÖÒìÀØö]}þ©øf]u07_è§2&‡ Mïw‚6Š’+wŰ BW7È21¤ZI`^-®.Ö`ålÕ%•!Ö±.zÑÿ¯¤1MšOtÚŸmbó/Ž»—¨$ ì€dcísX˜àñxØè4Èܧ×+éÒ—ý±ù+.À$|­÷ΈK” eéÁç¶mºá*(êÛÝáËιtû¶:Ÿ«‚XÙ b½µ"1ItP=탡x¢LÊ‘§òŸÊ}@–\¢(óp*föì$Y¯É¤á™záRi’¼±sjt˜¢“ºø £Ê_ª[å$Ç¥¸™pS=ÏÇAŽ,káq]y›FGwÃÊõyBú0ZBBÊlÞ^,GÂÁú\ÊÆE´ãÝbÛãð;VÀÄ=_Щò³åûÚ$¬3qF€¥~QVHÌ£¾)~"!Q+ư<@†î£A^ÏÞl˜ú²ñwÿåY©öU;L)ðèx¬öÁ;zÑsóÓº{êHÇê>‚ÀšÝ µ›]µoº²—Ûµ‡ûCÅ‹TG.˜~U]D¤¹ž´0ÁËÇ¢+ƒ¦£Ǫ.‹Ž¬ôiû×ÿÆHÑ endstream endobj 1026 0 obj << /Type /Page /Parent 1718 0 R /Resources 1030 0 R /Contents 1031 0 R /Annots [ 1027 0 R 1028 0 R 1029 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1027 0 obj << /Dest [ 1400 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 116 649 151 663 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1028 0 obj << /Dest [ 1400 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 120 527 147 541 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1029 0 obj << /Dest [ 1074 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 236 225 277 239 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1030 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1031 0 obj << /Length 2522 /Filter /FlateDecode >> stream H‰äWÛrÛÈ}çWLô4¨ Ü ºUÙòîfSönªÌ§Xy¡ˆ5 (ÄP´ü!ûùÇ<ätÏà"^$§*û”R‰¦gzúÞ§ßÍ'Wóy(1_N‚PøøÃ#ÎB/ŽýTLg‰—f~$æ›ÉÕm›‰¢å=¾h‹zrõÓ§@Ü·ßóý{Š‰Û½î'òoù½A gþÛdƇfbê{³Œ£ÌK}×τ|œÞ’”N–ÿ ±ê†¾ã‘—J?‹'ñé©Ö+¬„R9à$Ûªoºÿ·ã&øÞ‚–x‰¬_«Kñi_éoj»f&‘ÌëÒqgRüοÎ?æ°Æ¬Mè{)>æï±Æì÷{ω¼@¶t«¢kÁWzxõ½PviÅœ~˜OQ‰I˜¤^”"šzY&Ò–Ð1ÎÄVM–“wóÞQ€-þsk ÖõÉ"’­7x¦³ß4õ=üó³ÇnàaÉONÜa´y+®['ñ¦RmB?Úçã’¢Èká0[Së¼2ï›ÝZWk%®Ë\çæ¸nÌ9u#,¿B;l†ª©ÍŠÐ¥í३|xh7Ë9©¾°gN¼õÓƒ2G`\®¿4Z ½Êuç'R/²î):Á/¢Í7Ä‚/«{±¬ˆ¥ZVÎLÖªzßð -Wí¥hj%–ÍV°ž…nÅ|¼Í·å#=Y=ªDZÝÏæe«ú³.`éEÉ7F¤¶_ OŠÈTÚŵªKûº…ú©¼s¼;r©;äØbp*± ¤ Þ K€%Ei=#·Z¬h»§;o62 ¶̼$3YÀWNѱëœ&7ø”„ötWA¼ibS¨7‘;¶‘ȵÞV‹V—b¿‚‹À¬ ±R¹âIåƒç¢Z:ÈÙ)R© UÃë|£Ä®.Õ–˜+ŽU"tQšrŒÅ†ûj½6ZºAàEÑÈÜdÈpÈ“ÐȸP"/ gJ¡M¢E’XÎì/* Ä[ Æ–NÌ=•͆ÅBq*>òÂD±®BžøÑ!5¨•ØýB}å½$¹EEŒ½*s0+¦”ºØË¦^?qÙgÙ›å`Ø™‰Û¡Æ@,­¾jn/èM¹(h®­@UË!]ä­iÍf·Ý"MD«ÑEÐaN:~äcù°mÊ“'þÒìц¶—b¹Ó;ø©£pW*PÚ›MõM•Ãú¦º_iQ+¬‘4Öß"˜fTžƒç^;tZ8n~Ø;-ì*9Úˆì{ürwD³Ü>IÆ$6 VOS&«8F6Åf²‚…þäºÆ6Uݪ­6ïf£i£®(“Í÷Ju×=2b’a‚ë„!ãÈz†þLØ,3S`%`j§Àë«^¬rúèÎ8ñâ®C?-°?¥—θ§Ã/çai{AÆ]©»)=Œ‘3ôÓ~ŽfhÙçg?ö^róiòI£EWøª—£iÚ»ñ(CÎ)9 ñ|nž>ü2µ»wx~|>5ÏÑaTÜØV­˜÷ôê(› ó9õ­u¢JP‘ÝŒ±ÊgIÓ '£‰ë:_Wy{ó8Ÿ‡»Úñy$ º¦!`ÃŒ`XJ$j3¶1ÀGïæ6:‚Ì]O°€`pZ/–dæpkà·fÈT«ê7Ü™§G­&õ¦é؆QÕb0“?èSjZ˜4©n•Ì um(Êíó†•;”ßå›P[ÖwüÌŠŒ9ÁÎFo,ÂzEâ܆Ø_k'2`ƒ¦)*…+ȼ¹¥™ù-§= ™RžÖ"3­%¼Éxêœp ÒQo‹¾î °•Ú`8E@ØŒð,WŽ0À¶˜Ã¡® ìb[íZc<ôƒ³žÆäÍ!¹Ç ÈäÅ“8Ìœ[TM8°XWÀ帜ò²ìl{TnÊÌ¶­„i¹6•ê ~\刽Xýè„ñ¡?%]Nc¸5ò2’¾= &#uj€ÐïÎŒUh£)Ò?¿½Qˆ¾ö¿¯ÄþKEø¯¯†G¯K§Lº‹J‹]]ýs‡1—?ÌMj+ꦉTnÊLN}]ŠÍ®µs*Í(ßÔ¶ùÿ­­€Tÿ/¡4 endstream endobj 1032 0 obj << /Type /Page /Parent 1718 0 R /Resources 1036 0 R /Contents 1037 0 R /Annots [ 1033 0 R 1034 0 R 1035 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1033 0 obj << /Dest [ 1008 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 252 322 279 336 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1034 0 obj << /Dest [ 1074 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 105 308 146 322 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1035 0 obj << /Dest [ 910 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 312 130 348 144 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1036 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1037 0 obj << /Length 2253 /Filter /FlateDecode >> stream H‰ÜWÛŽÛÈ}×W4ö© ŒhÞDQŽ1€×3X8qÆ‹Œ€EâÉEµ¤Îò¢%[£Õ~Hþ!ÿ˜‡œêjŠI°×@€a ûRÕÕu9uúûùèÕ|‰PÌW£0þáO’E~’©˜Î&~š±˜W£WïºL݈®¨G¯~x ź~„ØSŒÆýç~$Ì×J„áTxóŒfVh&¦?K¡8Îü4`½V&²âô5IIú“üW„Ùqxã0öSdbq‡Úl0IåA“ìt'Þþp#þöoo<Á¸ÅÚÄŸHí²ØÜˆÇ½6¿©¶´Jb™×Ko<“âŸö×ûûü#{c{›(ðS æw˜³ì÷{ß‹ýPvtª¢c¡Gúø üHnjc5ÝÏG¡ÐbMR?NCOý,iO Ü1ÉD«F«Ñ÷ó£3â[‚—Þ¼G¤õÞ™ÞÓ4ðñŸEà5LõîœçÞWÞX?éÎDÿ—. [õËN·j)VMKž-þüA¨z­k%J½hóö 9 àòÔ,Eî¥~&·ÛR¹ÑMÍ˾8=L‰7Ë…9l•öfˆÜòöxl.âh¼ÐFÔ»jìÜ?}Ü‹¼N© Yñ5ªõ*Å~£‹ «BðvüÖ›F襪^y‰<¡8 ñËÜä¼Ëx44¬HA“ªE^xSŒøW±ïæ_¤B\¯…6gG:{¬Ý‹£ëµÛüÔ/)ñx÷'Qåõ./™Øx!r¦W28!&'p£¾ç„¥2¹7ŽÉ¬²îsÑìLÿ] .±,T×ÁÑ)6E> ‡,’|‡_”ïs^îÔ×árÚ$§¸<=ÂÌä—`)òï ¹lêòpûZ°F ¬äHZ_ò`L;ÛM Ï¿ø2'qü²iü@±½À3¡óó¢iJ=EJN8ê÷²»Ò7ŒÊÜ€¬ÿe³Z}*ŸÔû€ÉSK2cÆÆé%&O¥«uÓ›²¾¡š–jeSÇ-P-mâ2òžk·ÐZä;BÉ&7 Ýî½Z&xDLÂÊ ,8‰ š¨ä¾ÕF1ÜB™«—0tf>öUmMG[–À²ÆZAÑ”¢Ó]D¯kl'(èxBS«ðúã_ò£xVíÅû€œ7DOûgÅ•:#@ìô¢$Óx(:à1ø8ì8ºITÍR1ðàU GÂ÷eùhl•}ÎþO'…ÿ5.ñŽ(/óI>ÞÏ­÷oï>>|øë“|òDgÉžXíê†z)‰ãKÞmÏŒ¥{Û8ŧjøÝpEÙ…†Ü? ž@§g&~ú}MüTÒ™%Dq«J£Ó>Ëz'@̈́خ*•Q{4PàêÒN*~Hмh>Â΄yo†çkÇT·U`ÉÅP\bi”D~|+XKXýo°4þïbénvLÀÞEjOÒE›\ô/oûHM?úJ O‡0¥Î›*!H*’S¸Á{öUnSØRª‚|ËVáZnŸ‚àŸ˜t –w»¸š-‰ÎˆÒš…!$OÖ+p6A]˜¦§— ì9åÞ¾*-?Œä¡³pc—¨Jy4Ü:yžqG>««Dð k¥ªñÅOteRM8@Ô  ,ë¼ÅA3}Éh E^©òŸ•ûd@A»¨-x0Qå?NÒÞÕu ³qlØöŒ7[G}-É-œJþÕY‡®tF‡.ÄŒ¼·ÕÉïî?ÜÏïzÿðhÛÎs®ËœšÍ“¤^A~ ¢÷ÃÀM ^™þ:ͳ7#hl[½TÔorô.زUí…ǹFŽè9t±O^0y xL¾ ¸U4ʨÑ8E_ä]ïÜ—•ßÏGÿêù† endstream endobj 1038 0 obj << /Type /Page /Parent 1718 0 R /Resources 1040 0 R /Contents 1041 0 R /Annots [ 1039 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1039 0 obj << /Dest [ 1032 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 236 631 272 645 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1040 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1041 0 obj << /Length 2073 /Filter /FlateDecode >> stream H‰ÜWÛŽãÆ}×Wö© Œ¸¼‹2Ö Ø^É‘‹‘ ž1è"•‚³‚ÉÙMÓa³©à¿ qo˦h©ßOMß!}[{_tõ]û@u?XÊb´ÔÃÜ00•mc±BòËšbs9uÛ”SÓÝÉ:°Ò–åÛáÞTÙ¥£¢³Âl[rŽ DUC¦Zºa£w‡P"Ù ÐV ¿¦ãXÍ{oáA]?‘ŽX™®æo&f¦„ôÆóéÚ^‚ý÷§­û=+‘®{`hG·|èj–‡¡ƒX1;³Åغõd 5“Ý‘JsŠÀÍŠëÐ¥éçÈNå ˆÏ¦WTýNPWè®I@…·L˜—8ÆžšZGôüZgÛ‘z,í繺i'@cÆC¹Õ±šbFç+~0d–éî,cõûNŽoelb/¹N3m9¿²þ/ÍÎÍ•ˆ u|ò»¦i[²7¤5ÒÁ©ÔöPf {7Ô0ÝÆæ¶…<ÕNÇô¤®|tðj \ U0‰u²™÷¥08 yø<õÑ™#——$‰a‹Ô6'IÃfÝZ©æ<ÇÎÄqØQTՕƨ,°(4‡QÉ‚ŠIQjtH‚úÂÌTÍ\93S5sÅfn䛃14óîrøD®SÍ™‚°G†V‡=òVRYô™Ov‰‹òr‹ô÷é/œÐlêEq•ºªûX§ÔTïa¨oX6ºé<áì;\ðÜ)Š;TÑÜ Ò\½ üóà:;ÝyYÔØçz®Þ˜ñéÏÌaM­×Eã­çâŽ$Ò¸ÓJsìíP½æPám'•çƒÕ Ú@žs¹1™y9OÎ8Šcÿ*¿J†"L8o™ñÆmhÁ3‚Æ )쟠åÓ©Vü'ÍR ôƒäY³äê¬ÒãÊuLƒÝ÷ÃtꉘáØØH¿LvÍD˜L `–E>€}pQ?éËë-Q’'~ô›i‰¢ßRKÿwZ¢èW¶DZË ˆ_Ö™<Ïk;I á2Øu&ˆ´7]ÿF3^§˜»C³ßV¿ÝdRn ”7 ®ì äñì`Ë~¨Î³œêƒå8~žÈ¾ØÃôêåŠû…]ñwfË-÷K|ˆ;$‡´@ýí¶œFe¬çäW½hÏìKÿ„Àâ&©nºF¬‹öø"=>£rî@å¥mî‘4LÒvW4í'¬rªO{·îþÔ¿ 8H®—ÀÜô‡“."aŒW\º5,H%*Yj -G:åê€[w#gƒE¼ ¼ë+÷)ØBÌ}‘8Ÿ¶­F註âýÊ/¸9ÆqÌ7ÑäL†É)Ý£KFÌ…æèÝ®øØ§¥f‡6ycwv‹; VÄ´ÌIoþ;ì¨;èê[î™ø­—ßšû,i¸¦Be«½~§9„ÁEâGOØËÏHP€®:†|eþørŠ¼Î¶QŽž$»°Ûeøÿæ½Seœ ÆŒœôxô¿»ëÆŸswÙÀ kƒ’† ù»žÑã°6Ì£½:zLo—4}ÎÄ蜉ÑÅRnKè‚Gmtå*Y?ж?"9:´^“»JÁz«ñ–90ÚJÏ '®¤b”‡½åZZQÇÆÂ¸Â9/7‹Ïï·#øw…'Þç„Þq÷æ­ŒOß~—N~Ð&*¨Î:{,š2Ýt`¦Ž ÚþbT“ÑÝËĵ>ë³vUí¤2%3ú[h{§}m¦DšŸÀq»½v hÌ› ¢øNWÉñOB]'ù±@eú]¯›V®bX;d,/å‹Xb÷Æí}±Ê\”—föci¥rÑáF˜äèªYu8^bv_k!@š0aefËWj®ßAƒÐp ©ôæáàÈÌÉ¢\Ûêи-³@©ÝÅLÏn)ðâ›Áàó3£8çF`¶â(qû¢ãžÇ9Êú0•ýnßz°pö˜„«ÞŽrm›¸˜z½ÀúzÊכſ•“½8 endstream endobj 1042 0 obj << /Type /Page /Parent 1718 0 R /Resources 1044 0 R /Contents 1045 0 R /Annots [ 1043 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1043 0 obj << /Dest [ 779 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 452 137 474 151 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1044 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1045 0 obj << /Length 2996 /Filter /FlateDecode >> stream H‰ÔWÛŽãÆE^õ ½¸ŒhÞDR‹Å¶7^làGA€xóÐCµF´)R!©Q”ñ?äóSUMRÒÌî"€ @C6ûR—S§N½ž}¹^G*Tëí,ŒT€?üKòÈO’ UÙjé§y«õ~öå7]®ŠŽçª+êÙ—ïîCõØÍ?BÌ)f‹áñ4Ó4V…áJyëŸf+^´RYà¯Rlç~Ⱦ¼&âåô´LiõúŸFQà-ÂØOu«‡³º?×ý#‘¶vÒ]Ù©¯ÞÝ©¿üË[,ñÞâÛÒ_êÒ t±»S÷§²ÿ‡m+Þ$Ö¦Þx‹•V¿ð¯÷×õïgì1{~Š—õ[Œ±§ÓÉ÷b?ÔjéXl#}<~¤ 7´ã~·ž…ªT³h™úqª8óó\¥!"©àc’«Öζ³¯×c0âS‚ëhLÑ ("š£‡%.G‰$˜øqœgJ^‡ fË¥ŸEQ –CTƒX| C?Nü•—û‰V¯Mu2箳õ¦j 3U¹yóJѪ¼ÌÏtSþR½«ð°Ôô»?½‹ÇPð¼E‚!UÖÊÍòpp®e©‹°ŸÄq¤Df_±-m‹Ä¶æ`[Ó— ŸRwꃮå¹GœµÞÔÕY™Í¦ûàù²=b“ßâw H°ò£ü" ápf(G~ÓÔ½)k»¯8«ƒÕSY¤~6à‚¦ÎR_oLo:Y×}ÓzKƾõÊk¶2úäþ¿áà)òåƒwëÅ‚ÏC´àÇ«|ŒUî 7µ*Äx±{ù9»—“ÝKÙã¡i*‹}žLuô ÕljGc$®F¾¢ºKtß·åñ·½†šLÐ>cR1Â릶Ê?ƒs÷£~k·æXõâuþ‰#„W">£Ùn?zÄ…gc¹ !úÞž¼E¬:(DŸ‰r<ÆFÇ>8ÂøÜ‡.J;˜l˜ªb,²áÞö}Y?ª~Wv ÕP%µê5?[›«SYUªÜVÚÀfDÿ(Ÿ,VZåžéK¨[ ‘–_ ¢â_œ¸‘rc(àƒ®°'¶/dŠ1Ü)¢`{:V|ñ»¸ðƒ%’éiZT%½ÕMÏeA„®/þðšµÙxœê9O8 õ~&ïî §LÕ5jÛ´jþ‘@|¨LaA@1V`žš¿•7æ&|ïíÜËô3únÑ0‘…c‹ï›ž‚izEàÓœ™Ã9àž{Œ§Û’¢•ë¢'â*ЦÝp2›a G¹ÄþÊÒ兀€í«àŠi7ê—[Fö“…¾kNö‰b(Ls{²8%8Ã${èA€è®¼ñBö»Î_6å/“=[kªÅ©i«Ë¡=…~XðvvQ’a4ÆÕÿÎVÞ i=xèµä2HØ<5%GêÐ6®Ý>àse÷Ýÿä×e Nº R§­ˆ•=m‘R¡´º¡¶2 ¿€~„£dàÂzÊÐâ÷ÂÎ]´ÂÜ_ÅŸ­á¢aȪMñ/; ·>«}ÓZ_ý¹ìw °Lh¨¨á‚.4Å$Ñïa`¢Qafp 05í|j8@þpÑï$*§ë­Ù¨f ½±x±'„!\2w¼çiW;I&4iDÎ;*×΃¸Š4e:Ò` Ž`lš¶÷o[1dc2Š©ÿ-³D`£„â·Ÿ€WÌ.-è¦òk´ÃmU"=K[×CJà™„"‰/ýȳÎã›;4æª9A×<Ñ>ž1öIµòLI½Þ–mff¥³·²k l…½ÕhR“Ž®©Žnø»#Á|þçÅL’…¤M1]tòQÅdNÅ,IÅüoÄÉ3Dj‰‚6äGÕfÿq™ðÿ§N8ünQmO¬ S½ðˆï¡9¨–QÉHǰɳÏ$ÄTÞáL‡Œõ΢€{óØ©î`‹r{Vè T½;°ReÕî²?’gù46?Y ŸLªÚ”Ûèj¨•$ºöèW=4ýÜÀ’ .g"Äh²ÈQ¾p‰ø¡nWt¡êÇrd ªÝГ Üqñ)Q-u‰ºi÷¦âªsw½]ÛÔeǾÜQhí‹Òd –‹Õk¢7°/èˆ#ø¡§^±ÔbY.Éù¦Y{Œ'nK-³G-…… »Õ4C~Èô£üçâuëgìºÀ1K[´‰©*Ìpâd$ÑY)ßÁ9tkêÕdœœë,Q}IUDÊãzÝ⥼…SÞ†V]ìh?¢/6|%áŠF‚Ôl=›•J¾“Kð£:x‹Ü…ËÐÈUãfó ïÉù¥(XtÅa3×ûš«½9à±Ûò‰x>Ôn#‹Ì)å]P&Äàò]f ޏì>뜷—V×Ù¯ñIâ%³ëÞ<’¬X" !ÉÜ?œ‚-:¼Ì¯Å‘ ­`X‹¬­ ;; æÎÍÞOGr°ûÐÁ«ãnò*¼Œx'’a¼Óãz¡$Ó?Úó›çµóÑ+Ì tÍZs‡@与lÙ²†ß*œKõKwPë$iáå’ (bE÷>Èj/´©Cm^9Šý6ºPñQz£<~à þ­à-Ç£$´¤(ú2¿&}¬ /E,‡PoŽÐ&5þ«mb]t’ÕD+ È\½Rk/"ed` †nÇß•qÉ1¬ iuÏÕoªäèNÈ„¹Ø• ÉM™Ãe’Ê¥o‰;óº?¸þB2ì³¼Í'`£Ž[4æx‹a£E>ø ‡è¹%¨Ö¨¦·ÇN‰´¤†ZJÉÌÛòq×ÏiHø¾ákéÏÖĨõo§ã‡\’ ¾ämH:¬^Þäý×O9)¯©[)5GúD}úºÍ'~:ÿ¯Ô{¾yO»fq•uðÃߎV^ˆ¥ÒÛ.¿¦å;üž]hmX`ö¹ø`ó³H{FÐ^>@ 2—K¹× ‚°¢ä¦À/z¦kšäÆŠk ¼¹»ðG€yâ[“‘Ã褜ÎhYí° 8Ó½ouµqµ+°KÂwÀJÍô9¶¦Æ›¸êáÉTB>bK:OFÀ¡chrö/¥Ð8#Œ;u„{O:µožLY™:/¥ÎKížÜDL9\Všög~«ÊŸm®Y28ÖDrôÙ—Êz½¿>kMJýGÝYÜ23íÞÌ«'+k/ÖÏa­¦Ý^àyÀúž”,væÑãŽÕŸp9Ò4 שׁ“9»Ï'Q»‘Ôç“Ì‘|ÞÄ TÁñÊþÛ,/•ëÄê‚M¼Úй¬ótªót È7¼ø‹Ž!ùLÎuöztøÂW¸¸Lnľøø¢âO¦ƒ,ù¾é­”•J®‚«i„¾³i,ÉŠ^Õ¨´®3mIÅfM-³™&dî »YuåþP‘ Tþ?µ%îSmMGS_TýÙdU&VQÑÉb±¦ÍùOðÕý¹F$®¦¸ï÷¤ê3ÂÆ½Ü3vÆ}94àâí±‚í#²µ¦?¶nÇ=ÔòŠfOµ›i”0ÀmÅ«mÛì…T_¼<§£¹’5Z¸4p"=—Ñ¿û®bÕ†a(¸÷+„'{H!éД†lJ·vIc ²•ANp¾¾wïdbêÐÁ ,Ézº{~ïn]:ª‚Qqµ)šnÿÔõnK_XÙXÿHÍ>A*®×¥fͲ¢ÅVTs¶q£qãC½¥›ƒÖמã½C±Y}WÖù‰WVQpjwù™9H­C?µ,±m®VwІA/Y'Ž^k²%Qñ Ó8¥-"ÚYküx§J˜X&}ìÂ@a~WKÎÒûé¦ÀÓ‰–,àûœá!X“UF±Pó&¼ sH­²âƒb N$Þˆx9$èÇmµx¾¹}Jó…µW×$§×9‚º?xû`ßuê^/ød†´aÐ7ªJ‘k²xYÎPû*¡§‚Éã}ŽMÍ+g÷µ_Û² TÇsž¸ätK Z\ëT¡ëb¨ÇýúKg™ô‡»·Ï‡_ uš3 endstream endobj 1046 0 obj << /Type /Page /Parent 1718 0 R /Resources 1052 0 R /Contents 1053 0 R /Annots [ 1047 0 R 1048 0 R 1049 0 R 1050 0 R 1051 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1047 0 obj << /Dest [ 1074 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 195 730 236 744 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1048 0 obj << /Dest [ 775 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 89 593 103 607 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1049 0 obj << /Dest [ 874 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 307 347 328 361 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1050 0 obj << /Dest [ 1283 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 275 235 316 249 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1051 0 obj << /Dest [ 1254 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 475 153 502 167 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1052 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1053 0 obj << /Length 3111 /Filter /FlateDecode >> stream H‰´WÛŽÛÈE^õyIs!qIJ¢HcâÀ;± /œMÑKâÉCÙ1K‘IVùüCþ19UÕuÛûà…áÙìKuÕ©S§~X޾_.#ªåjF*À?üÌ’ÈŸÍ‚X-Ò¹'ÁT-7£ïïÚDe-Ï T›U£ïß߇ê©~„˜“&ýã~¤ÿjž,6 ”·ü×(åE©Z~cãiâÇìËk"^NOó˜VÒÿ0:‰oNýX‰z<¨ûCÕ­1iëa'Ý­zó~¬þñ?o2Ç{ƒos® /ÐÙz¬î÷E÷oÛ”¼ÉT›*÷&©Vÿá¿Þ?—?ŽøÆ|›(ðc¼,ÿ„1¶`¿ßûÞÔuK§Z:[ãHéÌ ­y§·ËQ¨ 5Šæ±?C5]øI¢âžT¸ã,Q­F?,Θ†˜œ{cðn@Ñì½!2½ÿqàã¿,ׂÁýÁTÌÿ©î¬ê֦ëLÖíL©Ú®1õb?ÑOµkm®Vu£ŒÂ3ÕÚ¶-êJÑýtf*eʶVVåvUT˜ëa¼¨T³«ºbcÕƒÎíÖVyQ=)Z&„>,…'ƒe§†áÔGu–µ8žOk”ýÅl¶¥}ð(л–ö$Ãïß.ïþòÓ»î–÷Ë¿Q˜§úÍòíû¿?hLm³¦ØvbðjWe™ iå‰9S+Ù~JÅœÛÜt¦õtÝÕ-ª¢“7„7ÂðW•A L‡þtæGáƒç+994s94óƒB5ó§Ód¡äµZœ†~”œ c½ofbŒì†^‚kªÛî°µín»­›îõ+…Á¹fkÉPžòûVá;?Ò$„Køx ðÓ-L.³ühV<óçщYaoU(FÝÕUg8þEõб¿ÐÇmyÄ€£ËJgÞáÌ¿˜@þõ(=íëK«&¼þ9ÉÑ;‰3Ìıcþ5;ÒSCv­· ~áôéñôcóI¿!ÈÍt×5Å㮳-½†šŽ)D_<>XpWue9/ny’á0 ÃM]–ð\ªŸè¢åÕ™'JMTJ”»*ë>í)ñA—ÙŸ½îü‘ç°ólÕ) ‰bpÉìmàš™v¯—{æ}Jq, a!™aÙ²æ5ííV=)³œŽã+^èß'¢Ã~K¹ ©Mcjj¿ˆÉµ‡ƒH3à)%Œ?Ï<ä£ !^F­šzfc'|TYYàæ¾—‚¸¯©á“Óp ÆÎcç.ð¹³k»“8ìÖ[èGÅ¡ÌhÝÁ>Ûæànà¡x0këȬcŽuyN,Kl$ÓÝWo®Ì‹ŽéÚçëq"wûÂÒ²+@°DeŦ(MW30%[+Óª¼X­lCÁT P'Ç–!¤ê•z¾3M_1øÒY÷rtÃÁ¡'7 ×þJ®œT2 WFŽ+p$þ¶Üð cÕ~g‹©ŸÌ¾)žzàŒÆ{'|z¾ñ_ÕÝšäsGß–ó®Û‘†«M[ÎܱÚ6Xkî´Ý…¾–ÑpHÔ'$eÎäyë@ïaW €ËIeTo e¡ž oÚTâBç ÓñZ‚yLӧ˜FMuPð&ôK¶k'/ Œ¹{ðtõÆ6“^BåLPÐý/Œ!%q•F/z`¨%…=%Á³WP/å¿;ZyeRY!¡§ºæ™¥Çp*=ú[ï (÷ ¢%ö´ê•‹ù;r6&Š/ìü#ìKo䯃…î¡×7’÷ôåæ”XÊé "©ŸfcÏwˆù—evÒ?’/n^á¢Óó#QmBfyÏE½k˃ӵ(c‘ÎO¡1ÈÏ[.+ í¾‘3ÀOT¹‘¿˜_ç².ª'd\‹²I¥PªZ>PtB ×TzCMuBàž(QÄ Ø! _æ°MÑâ7ßUsf_Æ(bt"hÎ"¡*­·äô' ½™ïÀ§ä3F‚6+H_$ÜÜY·Ð K%•W¬>tŸSíO»“7’¼®æåD%?6³NOP¹–iòjâðô«E˜ÃÇšñº¡\Ç>î…dr®näKç~É^·*™S:±6KõÞý>x¢ÆhËGÓÉqûãy,}Eª˜w‡@üèg{¤›ú]ýÏê7Oza6}¬çÛÀÒé ª®uò€«äWÂþ®Øk³“YGmÁc+Ÿ*¦ÐIcɲ¶fÊ jV³BÊ~ï6íì„ ÖWæQbRi$X¹`ì qœ Øùä e¯&Ÿà¨ã+¶¡ tíJÛdõ†$ä##—+Ê‹[ìåÕ%2†¬»Ø›xÃæãmŸ\+|õìO^Á‘}þ ™döi9Ih¨ÏK—th= Ú9“×õ‹1L‡À¥ç**<Ô!ƒ[>Lý`ŒïØòg/ÕwÞ„B㾩öƒi~&=ÍË=+I£—Áy-hDŽ0$"ÆGâþº¡üV8cgç„‘)0ÞYµ*Õ‚¹DR<Ì]íæPÑcLŽl‰bO)£²5Õ¢Êâ¼5ŸkУHK\Ô^!}?BZLûÅ$Ñ^ ¢ÿî„„ÇÜŠ^ ÂuE‚ë¹È¸úÆZ&nYJ8Òîgf¤8©ˆF)àN1ðεp÷˜¥}wAuSäø¤HZêuno2g¡'NºQÓ=é?]I_DN)-ÐIt+Gî}-ßNxNä+6 §ÎÈåw'Ч8uBBnp†¢ß²@?†`XLuË‘ä‘MÉw~tØ6e[óÍ º.0Ï€³6}GaÂýB¦â)J]Yý#'qÄŠøÃJ,Q”nÿHÖó žÝAŽV¤ú ýŠg«y‚ÌÝrFSp +M%6 ¥sîôõz‚ÈER¨»½,¾l1Òc‹‘Ëf'Ê@*·è±†9͉g°töEf ÿ§¼ r†à½¯È¤&ÂMâÚqë8r©ª€*U¤ ¡êó™õ’4¤E\¢4SÛkïîÌ8ø¡5´¤r{Ec²¦=Wã´lóMjOXtO¯Åu?@G¹r½é!ë»-¨+CêÕÃK௒‹£°Ì{Ûï“WGÇMc…·s9ÐHÁPó²*€7 BS®ûmB6*Í(*5O,·]Ÿº’=ƒ:ùìÛ®19–þPÞ¥óvGµîš±û¤ñ\Î{b?ˆ¬OüK v*•:`w§O¡\ 5 ~1mE¬K€•&rKSZ²8#}-J/Bdx–¬·dTËåŠ#³€—_:%Ú× ZΣ+bò挼íÄúÐ&ë `=Xdg?_ïMœÕÓ¼&<‘ÎôˆŸ%y›—EÀ™—­!çvFä³koaµOXµu_ õCÀ}ìÊЛ`Z³ö’Àÿ‚‘‚×Cš|µƒpÅÚ@ž™lgý`޳ endstream endobj 1054 0 obj << /Type /Page /Parent 1719 0 R /Resources 1064 0 R /Contents 1065 0 R /Annots [ 1055 0 R 1056 0 R 1057 0 R 1058 0 R 1059 0 R 1060 0 R 1061 0 R 1062 0 R 1063 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1055 0 obj << /Dest [ 672 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 507 577 523 591 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1056 0 obj << /Dest [ 675 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 456 412 472 426 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1057 0 obj << /Dest [ 669 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 221 399 238 413 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1058 0 obj << /Dest [ 898 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 276 385 312 399 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1059 0 obj << /Dest [ 1546 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 372 113 386 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1060 0 obj << /Dest [ 656 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 251 276 259 290 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1061 0 obj << /Dest [ 662 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 289 195 305 209 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1062 0 obj << /Dest [ 910 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 470 127 505 141 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1063 0 obj << /Dest [ 1066 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 137 100 178 114 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1064 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1065 0 obj << /Length 2334 /Filter /FlateDecode >> stream H‰ÜWÛnãÈ}×W4üÔ ,šÍ»3cÏb“$ÖSÆA@S-‹;I”/ùý‡ýÇ<äTu“ºX¾ä!ØE`Àjö¥º.§NU˜Îf3_(1[Œ”/<üá'L}7 ½X$“ÈS/³õèìc›Š¼å=žhórtöã•·íÈs=OaO>÷Ãû‘üKv«!L göËh‡&"ñÜI ÁAêÆž‘Ëg|>N£(¦Óßäo>fǾçŒUàÆÒKÅÍ£¸z,»%f|©H’mÑŠ÷?žŠ¿ÿÛGøn°¹‘,OæËSqu_tÿÒÍŠ…2+çÎx"ůüßùÇì§[ÌÖøžãcv9ÖàþþÞuWÉ–nÕt-DãJCÏõen§–,ér6R¢#?ŠÝ V"HÜ4±‚'l SÑèÑbôa68#PØâí{cë]<"Ù{gŸÔaˆ”ƒÈ“I4qßþ&Ï7-…09Ϻ¬{¬õ»“»·ÈPâÅtôðË«ý½~ê¦á @zfýsgh3t=ì¡i"ÌgOvqR8·l‡5Ëvžo¸F)7]8ð¤çóVù‹bÕ9 >uÓNš—Êìf¥‰ó?˜òå8*•BÁBÁ‰Tv &+Ê[CrÐ3=$A¹0qG9Õ릌j«²ËŠRÏEQþÀÌ—ÈA¬-±›ôÜé²MyO¢çÕÖÁÙUC䬧‡ZùüX¹T:.¬ÒÁG©U$+En”1zD¯è¡¢mMŠŒŒ›ªZiȹËVNG!y^PFÅ;&½§ZÊ®kŠ›M§[úT’TB_QÉK˜Õ˪ԆÙ_ôâX|“z‘mV±:}á ã9®¥²*ù†svªŠ·½MoÑ,ýì„(ª !ï–E‹øÅR¬ê¢ù4?`&?è*ü%78Ê>ÅYm·=šme.ty[”'³<nÃ^FÝYÉ=ίÝf²s@LòYpþ ¢›©]¨g^,Š<늪´B®­žZ ÜÑWý­C Î#ÓUCrIßbº‡kÀ¦œ¿_i"·˜‚‘Wë5 Ú|ꌩ+øGÒ,ÒÒ¦ ©+ò¬ÎnŠUÑ*7ÙLðF+~®ïÌZ®1MÖlÏ®ê/EíZ²ßØù_L쬫rõxí¸~ÞB^4ï[@sÚÞ¨öØ+¥Ä^ìÌÊ[þ¤RÀ®à±’¿˜ÇæfèP3Õi±=C.K0r˜½…ÊB0úäCeþ‰Ê‚߇Êüÿ•G©l›Ïþ¢¶À~^#B³–Jûi~8ƒÀRŒÎC`ýYzA0h±;’šî@>‰¬m…mˆ ”ä&ÈÈêgè„q†7}mWAQgóæZ‚iªšSŒ€€ åhö?ÍÅ«Ï?¼<ûpùéëßœ1 ½$MÁƒß5  ¾¯@¹z3oø€(áç zuˬYÞm²•°œXoÚNÜ€ˆÖõJó;*”kX‹£ìI›–,Èêñ‰µnªº)È çÆmÞu7È϶¶äøC•D‚¸Ê»vç ¸ùÜ8èP¹tõ×/öü¡×@V¾‹§žÁɈ4Yëp5ËV«G±ÎØI쫽hµb±)sº2[¹â ZQ¹¢M]G €ôA#š…¤ï8ô$ÜGݤ¶aT6Œ$ó»F°¨ˆÆrΧBó³ºÖØÌ,îÖœ¸†´@Å{"rŠ8ï^£€ÂZÖt[*b.“ÃRñßTŠ@!1ö*E0ðÞ~¡ˆ@éPûu_×kÌÞáéÆQ” îxó¥Î¿Ãœ+¯‚ËÙÝéuûz]ð'œMM÷ÿ_]ØÇö-ü`¨!ª8®j3Ò„žDšÿüÈñ7ŸÔ!~Ïòñö>õ)§ÌÐ<-ÑEIJ° wZ}ÛÅsHšU_#µÍ”UmâúþnÙ‰‡ÀÄæ*$ûƒÄsbWâ€}#ñ¦T;F¦[]mˆ íÏáØ@˜1CÓìÄXöt耱*8>ÒÂì¥&8Ì è ÑR–¢6U®Í–^èR¯]A|*­XÖxL4¼Z6˪3Ý;é)@qþEçÄû÷Ô¢¢m[ö]z ÞÞ´€ï\‹Mʵ›ÒVìgNq/ð6 4†rÔ×í¨wPØbÇ«{¼U3Û †¡o¡´³ÙÊ *ÇtêG0A}ïdÊp »ÐÂϲ4Óò˜Y´ff†©-_¯+‡:€ù!V;á‹X±ùq~:TÙ\"ÇP*[¼ÊG»‹ ’à­"L¤-"ÖC]= jw–ºGEL1ØË·#ÅÉ[dÖÔ9Ô¶‘lô$”  0Ø8Ômí‚Þb­ug]į*ó Ä–º3e«§±XN‰çEÿ¬K¥ûô!w5/=”fü.\ò»±ÛšÇnqøä±»±I³o³²*bè$«¢l¥Fi"Ñ8q´îªb.îÌ­_/¾¹s÷Õ¯Ðwè²ÆL8õ‘YòMh0ú€§‡&  ¤ÃfѶV [ÐâÎ S²ÝNp ‘*ìñS¶<ˆÃ"czØÊVœc«,/Ï6¶Ü˜ŸÁ ;€šÌÛÒJANšAf@ €XñGûà§¹ƒË¶°T½±g8k7ˆ¶ Y‚¶XĦ}û6§iu…0hÑÏîSn¿Þó:÷¦ =15¶ì¦µâÖVРoZÕ視÷{Ò¡›i1)kX-ê¤ÄÉ©\õ4S1/¬æê¬™ï–+sû ¯(wÝ¢³¹¨pa·iJŠáÏL«½õÜ©°n„N;rÇÇâõŠFÍĨ‘šÓÝæÄö1¹Éøér6úÏâ5‚× endstream endobj 1066 0 obj << /Type /Page /Parent 1719 0 R /Resources 1072 0 R /Contents 1073 0 R /Annots [ 1067 0 R 1068 0 R 1069 0 R 1070 0 R 1071 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1067 0 obj << /Dest [ 1054 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 426 652 467 666 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1068 0 obj << /Dest [ 656 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 251 555 259 569 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1069 0 obj << /Dest [ 662 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 289 474 305 488 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1070 0 obj << /Dest [ 656 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 251 270 259 284 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1071 0 obj << /Dest [ 662 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 289 189 305 203 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1072 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1073 0 obj << /Length 2341 /Filter /FlateDecode >> stream H‰ìWÛŽÛÈ}×WôcÑ¼Š”1À»qv7°ƒ$# @ì&¹jÍìaöÝj FbJp)ºEDsô£Äå(ñƒ?ŽóLÉpj–¦~Dï\T1‹} C?Nüpá出íleê~c»²h7w¯½ ‘Vn¨ê†gõª(ù¡4O½Ù(˳zøŽ˜]çâè'q)¼L‚0£(ŠK¶€!‡UÇÁ¥ü%ìF?‚¥å'~„ƒ¡xñ}S÷…­É˜ú5'#séœÐ¼ð³!„¯ÑŒúvSôEça‚î›Ö#¼˜»q¹³jÎëáìÉÇpæÎ¢V¥#v¤?cG˜Ne’Ê릩 öy.ª½rP¿lL<.N\zCðOtß·v½ïMGÃP“I!åù«&­njÙyáù ƒÉ¶ œ|q‰ùÉ£sP5¨¯~k;Œs ÈÌ—T­2’¨§ˆLV}£úÖK€©½¹ABËfgëGe{`KôÛ¢W›€ìÕS!/Ý' ºFqª[€”pI •ómÕÙ÷N}tó )ô½%coN5ŒbH?zª™Æ7"U(â F8xt<‚aT·/KÓuûJu}Ñï;–jM¿oØÕ°·UÄcd2Ÿ€³Æ}K¡§KHrZè§øv5ž¡hQ·USÕfÍ£ ?µä~®ï^+ SùÐ"‚XÑí×éU#+¼y‚0É,.ÔÌ@/k8Í¢s†ÿŸÖpü_­á ö²á-ñ†åæó“<‚S¦å—šRS;,f„Å ÈûÞùJ=¾ZêѸpêîA,v¬ê¢ì÷E%ÅUñê#P/ã~«dv'ÔÏî8Ù €ªšG[R‹>9èX:Cêgg±]Wæ¥ÑwW¢sÂlæ™êñ°µd(”À³h{m+Û!ôEÞ*ùGŽáªxÊBÅ-sõ1LQ%ú=5Ô¢~„Sè…zò˜³ÙñT·s dWŽ•§BjìwÝ%9¿(öëЗPÄúÎÐ zÔ¢“Õ—Û˜AHcÐ!’ßߊJ’FçÝ¥*Ä«rå²÷¨k®,+S©F¶•œ«9ý¦F‹,èX5ÊT)ƒpÄÄC³¯6ÄW“MYŒÜ•mk(°´Ú*æM3ýLGO2Ø>ôS+3ó´F2éT|QëP…Óuï^µl°Q}!¯>É!2¸‘B—V£jƒ´#Ú¥X` ðF¡PNËÐÒ2üõî’ʯg÷’h&À¦®Ž×K@nfã%öú}Óo† y%Ôâ_´À/_N,¶GJŽl:H¿mžZKÎüùG™ðöOoù[Y{Ù„ƒºÐnGÚýß)á¡á!Îf¾¶@™A¡»‡pê ¡ë ‹ìŒÕ@„Äzs.I‡Ö·&§ðkºÕÊŠ£°=];¨$rý™Ÿë5#"Vrú“Èu#K ïÎï‘òªúÏT}LÃSÉ$£$ŠÎ¤}Îj\ÝZâ>¦=ÙÚ£EÃÝ;¢ÖˆD!«jêßøŒÒD–ˆ¢=ô³j>ÊA ²çW5ÿ«šÿ¥ÔüéÕö¤D± rñ@Ê5¬ÈTÀG$šqºŒÄñR·ý‘¥ü$¼1£ÛWÔ¬U/}¹å®¶77_QõWš+vä¶=t¬€ÉNœ9É=òÖSn&Ç‘ñü«Ž‹Ÿâ"¼©Æ.=¥ü°c(ƒÎn ]!.9ôÒ’Ĭ‘ Ο9à4\S(©9Ù%d{E6¦d¡Œ?z‘”¯\À#€!ÿ¿º„'tž]]òáê’‹Œ ùêB–EñþÈŠÚ\ø{6æGÀP¦~´DX°ÛˆԻЩà|-8¾z=ù­ÁNÒ›•øšõ ð†oîÞ0Ü™F‰rgZ²Kúü-Ûy¶Ò‰DRåp‘ÿÂÑò=OyÇÇ©ùCi¸;ƒœRoÜ…®á¬¦—[ûlæ|Ð:•õÁh f7ÿ¦Û®¨77CÈË÷ï$¸ƒšÏX¹Úªb`‰P’V-Cú5µ—ºÊ«h‰ÿœn å·žFöû$ Ü]**‹\±érß0×ub6GærE›SkK9¸Ñp™u‘sœáQ3R`&ú&óG ×(T@3Å0Ò—å’û£‰od¶1ÌMGŽ'ñGEMá4Ÿ­{!ÿ¨`É4’¥y¢pûB¾ÃØX; öv5û÷Òòž… endstream endobj 1074 0 obj << /Type /Page /Parent 1719 0 R /Resources 1083 0 R /Contents 1084 0 R /Annots [ 1075 0 R 1076 0 R 1077 0 R 1078 0 R 1079 0 R 1080 0 R 1081 0 R 1082 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1075 0 obj << /Dest [ 656 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 251 712 259 726 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1076 0 obj << /Dest [ 662 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 380 671 395 685 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1077 0 obj << /Dest [ 656 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 251 535 259 549 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1078 0 obj << /Dest [ 662 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 380 494 395 508 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1079 0 obj << /Dest [ 1254 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 482 216 510 230 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1080 0 obj << /Dest [ 615 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 272 202 302 216 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1081 0 obj << /Dest [ 1126 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 452 175 494 189 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1082 0 obj << /Dest [ 672 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 220 104 237 118 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1083 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1084 0 obj << /Length 2795 /Filter /FlateDecode >> stream H‰ìWÛŽÛÈ}×Wô[šÁˆæý20 ø2;ðÂk’ÉE¶F\S¤@R3«|Hþ!ÿ˜‡œêjR”FãñX †ÙlërªÎé7‹Ù‹Å®X¬f®'üÃOxv8‘ˆÓÐŽÇ‹ÍìÅÛ.y§÷8¢ËëÙ‹ëWÜu3Çv{òÙ|¸|˜ÉÏÙ‚1_X‹_g©~)±c§ û‰9lW¿ãé×é*Œèí¿Ë{X{Ž5w};’N"–{q³¯û5V<©,X’]Ù‰××âoÿ±æ!î[< íP––#óõ…¸y(ûª¶ÒF|™Õ…5O¥ø—þkýcñóLG¬£ñ;ÂÍâÖ´¶åÛ®ì諊> Óø¤KÇödn–ÖÚÒÕbæŠR̼0²ýÈ~l'‰ˆ\dR Æ ­š­foc2|[œãl²ëPF¤Îj˜¶`C`û~ ¾’‡¡{“¬â™ÉªãqL®kûí¦V¿ÅËMöUÝ—]¹¬”^Y•UoŸPí«KAOycÙ« ®\¸C÷æÎ œKN4z䥶“Lã‡{À;[X+‰DUkôºúmËWªƒk±ä¿ͦ·æV)ßZOûì>»Ñ$òׄ÷@ö}[.w=>€[W’ç(ð3ž;±FVÝÔJ£ë$AÜ9™˜<-`Š |•¾+Qê4&Ò¬Öê‹;¾Óõ½t‡„¦JÙOþH4VÉ DÚ‹ Éù$½€qp±o£,‡ˆ£ƒãÚ’¼H›hêj¯áü€‡Þáåàu`¢Fc x4„\ªá\Wy›MË,6 Zœũg(›?AÑFG‰††íß‹USU… ò—.Å_תÀ.u('tîa^†“z’íC îÃŽL¤²·fäh$Ûn«ò<ª½€fÿÕÞêL„çD~Uó-]ÅÒ,tA=Fò=‚¹žßÓa6J›[ó7u±Àí?.¹‹i˜¬-—KH±F@ª67«¦e˜'(‡Y$N%²žµJdEàûFd‚ëÒ%²¥ž_µÍr$¨îi¥ÔìÛf„SOû ö⡬*±tC—Ï}9²Ïi¹ƒC½C㦔{AÔ(Åæ—Ì»2+Ä2ñÅ2ÿJ€‡'üž ˆcÜa3?¹× ¢øF-³£m¢b‹½ÙcëFx|¡‡qìL ý0ƒ)¡C&Qi­Dݪķ#YQ¶ÐUJ?8I¼¬ófƒ]Ôë´]DEî½ÿ<µ‡¡k'ÁjÿAí?¨ýì4f ΧH4ÐO¨=œP»ËÔ‚ÚßðVš&±Ä Všçëùïay´x946§!áÃȦù6Œ¯p‰¾Ô¨G&æñLŸx#ÿ=eòÑþ7ÇI¢‚ÃÑ1ð§U ÚR"¹ÕH4ZÈ("] ÿl%‚I?ûx3½rÜßË۶Üdm lQRÌâåÕ¢˜Ï¡)ë̼uÊheUö{=¨Ú¦z’&ÉÄPÍ`¨â„ ýoÀO1Ó°ÝCÙ¯tKf¼ Ùoð¦BgW‚ŸšÜb8›3(Ë•©0 ¢×'@‘ >é×âíõ{­4–gxxï,¿?†8Å€ (3"›kâ zÚùX"$ûwÑpึ7¥º#¦2 ì‰pšy ”¥J `€Òíz:mtÛ–ÛLÜå-mÙö"Ïô»U÷—J_ëvç`¨øen暎Ԁ5ËsÕuÔípÁ"™H¤T=Oå~؉óÿBåÞñÙ„xŸ•8²Ê– ª†Ž@êòi8Eþ˜"3V€ÔÏ_ˆb|ùI #»²©;¦Š?^Yhþ$/º(¢cz. |‡R˜”=e+79áI»¡~ëI¢’‰ž “ã•ÈPå;rOG(|îµÒetQ³g;Sû-ÎjU^ŠãO‘³˜üÇÙþÃ4Ñ3RÌ€îZe»ª¿4Jç9¨ÅÇ݈¯éþÞöOÊ0Îû©{¸‹uÙ K5É­€¤¨Ê‘’Büºƒ€Z*=9x¤’~reO¿R$Î?¦?„˜„Öqî¢SIÙ1ßwû:êÿ„øx¹c3Ƙ§SÕ ºîè@Ø× }Â@G8Æ9‚ Wé@I_[•mÇg]œ Ë 'y Œ'õ¨->6½&?~§å°QO=}ôd¹X…²§ìúÖ,öåýŸc¡OÜʪÅöf½½Ó¦ún°]3g©è‘ò$Ù²íP¼ÈªVeÅÆ¿âø¹­¬ý˜åÐp•ªIñÚç™ûŒ§7èÿ±ð¾kš¶É,é…¦(W{£ÑQ8µUuA|Ðh‚­ÚP u_âHQ¥g²¢NšhTiéØÍó‰Š2WÀ®±×î*4$7Ö(Ñ“äBXR Ñcž'É=œÁÊêB|¡º¤òŠ\Žä/ŸWfå/¤üpõñµ.â/W·•Xí꼀胑 V°ðå¦ÙöšèÜK ¼×Ùbô½B6w9dHÇ]„9Eª»ïÞð¨úôyñþ çP~ÔwCþ]à =[5·–-Þ÷º¯ªŽ5ÑXX’ÒÀ'÷£¯¸­š§FÊ Mr¤ÕqÊ€Ua»QëFš¢K–,ôP[¨žSNóåð2¿‰É“m¶š–ÅU­Ÿ‰—YÞã-æ(>àÏä¼LúÇ…R£ÉÌNaÄ”Oéx”úÉØ<;7½Q·xîØ7Ì1ð!Q.0[³¼¥ }œ¡®§Ydö˜Å?†shq:®PBp•P‹où =`EúXåŠb‡7õ F©û3‚±žþÕrLDÞq• _hذøÁ ៞DCiÂÙÉšÇDï¦dóœÈ3ڒϯñOšÜ•×Äü®¼Züôþã¿3å3`à»B€«tÃÙÇÆæ¶d"ØÑ–À¦ Zžö*‘³ Z¯ ˜'AŇ…FÄY@Gh€…Ì®1’@Ç…@À ÀŽ*ÉOOF|´u áòØÎ endstream endobj 1085 0 obj << /Type /Page /Parent 1719 0 R /Resources 1096 0 R /Contents 1097 0 R /Annots [ 1086 0 R 1087 0 R 1088 0 R 1089 0 R 1090 0 R 1091 0 R 1092 0 R 1093 0 R 1094 0 R 1095 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1086 0 obj << /Dest [ 656 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 297 646 305 660 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1087 0 obj << /Dest [ 672 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 251 571 267 585 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1088 0 obj << /Dest [ 656 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 212 501 220 515 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1089 0 obj << /Dest [ 1066 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 349 439 390 453 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1090 0 obj << /Dest [ 672 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 439 376 455 390 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1091 0 obj << /Dest [ 1026 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 197 280 233 294 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1092 0 obj << /Dest [ 672 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 316 196 332 210 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1093 0 obj << /Dest [ 672 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 183 148 199 162 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1094 0 obj << /Dest [ 672 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 320 112 335 126 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1095 0 obj << /Dest [ 672 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 183 64 199 78 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1096 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1097 0 obj << /Length 4172 /Filter /FlateDecode >> stream H‰¤WÛnãÈ}×W4æ©Xvó>xÆ^ÃA²»ë)ã<Ðm1)C¤Vã|Hþ!ÿ˜‡œªê¦¨ËÌ8°Ø÷îªS§N}œMÞÏfV5{œ«"üá')l˜$Q¦ò2 ³"ŠÕìyòþSW¨yÇs"ÕÍÛÉû›;£žºIF‘Áœùdê?wýkõTc³D³LJ^Tª< Ë ÇE˜E²/¯±¼œ¾ÒŒVÑÿ¶èÚ(˜š8ÌtT¨‡Wu÷ÚöKôX]ØIwM§.o.ÔßþLS´7KÃT7A¤çË u·kúÖ›oëª]ÓR«ñÿàï³?OøÅü…³+ôñ v»]Ä¡ÑZÓ±ØG†øŒB«ç®kÉ;]Ï&F5jbÓ,Œ3£â<, •XRáI¡6õäqòq6#6˜Zco݈,¢ÙzðQqì#oÉ<‹pŽ[LÖÏœ%Ë"‘wtý&Hñú&°a¡Û'us=›]~ÆÿŸ\UßS¸[ÿevýù^cf¦ï~Ñq˜¦Î8tF9œa䌊ÎH4Y ô[i¶8ÒêNÁ|j¾Ý¸9m¯üþÆP„q±ß?40Œúúùe½©6¯ÎnAÚ|XP–4ª¯6O5¶‡ƒôc³êk "ƒ U‡£îC(iÚ'Ì0°†º×• ©¦Åì¶Z­^a<‡Gª¯X ÷ü˜¾ØÄ5ë •/uLcpMÍTÃà„ÐL¦pº¾!;íGùZ?ÝÂÔ1ÌRërë®®Nv(`Z¿Á°6õãÁ4Á³ÝÅÜzp+¹Ý:ȱb'}ð:.kÀ;!ƒÌ–~UkÎ×Ï/n•ì0L–šýA ‘zÛ©Øæ1H|ì‹T«úë ýÖ¬ hð„+®±nÕ6˜8@zë…ªäë.e˜%#¸¤\¾ð­ í1sc€fŒ²Ä_u€@FÍ×­€¢éz‡Ž5(Ïx!Ð}_ ûDöŠõÍ­4/%œ>ûa¸†ìTÀ˘WjвûàäI¦K³¿\< ¢­ð›Ð&Uy’˜Æqå U;@ÕxZuqzsM—È ÀIEÚwái¹Ü–%M7ÆsùÚýñµ„üý1Ñ4K‡çåpx–Œür'xMè,ÉÅþç’ ÕÐ1`B ޼v£?Ýò0ŠƒÖøU×nú=ð甈nÀ““€Å  ÂÕ¬~ã˵™Eñ¼¨°D¥ÖfÄ¿™ÊJ /¥%Ãö¨ªÜé) ‹Ô=…é?ÁyÞÌÌ6/Ã<;ÚN…;pdÆ#ZµV¼e¢¼ð´Ú1Õ™}稉àç8˵üw³ÎÐkòõ~½NG¥‡¡Ò¯Oƒaòh_‰ ˆ™'‡%о¿]æ­PrÓjý[½™ ÆaþtOÇ<¿”Gä̶Û4=8^Uí+ø& Àm(ŽSÍÝîêÈ‹h…?@2ÃÀŽ€|IT,Ù“$Ç-(Ô4câa`²ÔœE­ä]κ eݳȋM‘Ðʲ˜¤ÀyÖ#Q6XC¡äDV?^CGGû½zÆé/“¹‡^µXP€åDǶ¤Ž¦gA„ƒ°«Õ™LžØSäbMƒ-Órá¯RZŸAH rˆi%‡ÐW-^•ÿxReH#”S‹þC´˜‹ÒÁqTe|‚ã'%÷‹Ç¬¶±ÐVÏÍüÕ6ÌGö͇cã½Ta˜<ѵ‘{N³”-SŸ-)ÕÜ뻺V9ÆÐ¯dxXí†tÉÿZd…Œ¹F;¯y燺ßÕu˜3ùÔdƒ×ø‰öø‰9žˆ8JõÿþNÊ^ íüÌ©a9Ž{3:´#Ü“×û€ÃÉ¡fÄ1ó=ue+@Ýàª.²‰3àÿ!/ŽÎ £¬t(˜-QJˆlܶ󾊪m¿~®úf^­ðtCš‰BïJ±«7}§^ªME•Ar®¡·R ¼Ãï;µ~©7U ×mçKÕS,%¨(T½’Š"FÃ"gX _¹‚û–ÅÒjÌduw’$Õ®Y­ ûT¿ÙÖjÝ®pýGõ°–Ñ~)ovøwüH¯hëÅ;4ØpÆttÏ‘ÂH‰!tÍWý:uT»œ#VÏõé÷ŠW¦|¯@)Ãd%䨶Ü×'cŠ ¢cªO¨‰h@KBß)ß9hÌW ¶»€Ú—Pÿts ôõ섦C½ŒTçw\2Ówb|;2~ê\d÷.:—ÙLž…QL”¦¤ºG™MÔÇ.ϤT9Ic¦„‚²G‹ß”ÆÓr¯Ÿœ2²„niê'âÍgOšuâîTÜm½»‹ÁÝ`ä3ljíYbó5鑚OGÂ߇D4„„è®%vòs nX97ÇH?uy/ £òˆòâ=l5µ” i äŽ7h¢Qiá4)¼E*iõ”ÔÙ™!#*ë• Þ•t®`ÓB¿Êr3[ñSWK·è*Y¶q¿-k%õ³´x€_»8h©w²JúïèG´}9=&Û,ÝŠ~)cäæ\«á8µ!ñ[÷7çðòOD ™ß?t<׿LèA«¨½+ê# ‹¦c¯uN1á¨oH:ˆ9§ãâ‡@FÀ‰¹om.MUmdûe‚‘æw™àêênv9» ˆ?‘xHX

, if (aParamInfo) { q= va_arg( args, char* ); if (q==NULL) break; ii++; } // if ii++; if (!err) { bool ok= d->GetFunction( p,q, *m, FuncConnectionError ); if (!ok) err= DB_NotFound; } // if m++; } // while if (err) return err; // check if table is too small or too long while (ii*sizeof(p)Disconnect()) err= DB_NotFound; FreeAssignedObject(d); aMod= NULL; // no longer access return err; } // DisconnectModule #ifdef __cplusplus } // namespace #endif /* eof */ libsynthesis-3.4.0.47.1/src/DB_interfaces/api_db/DLL_interface.h000077500000000000000000000062111226375725500241500ustar00rootroot00000000000000/* * File: DLL_interface.h * * Author: Beat Forster (bfo@synthesis.ch) * * * General interface to access the routines * of a DLL. * * Copyright (c) 2004-2011 by Synthesis AG + plan44.ch * * */ #ifndef DLL_INTERFACE_H #define DLL_INTERFACE_H #include "target_options.h" #include "platform_DLL.h" #include using namespace std; #include "generic_types.h" #include "syerror.h" #ifdef __cplusplus namespace sysync { #endif // base class for (internal) routine access class TAccess { public: TAccess() { fMod= NULL; fJNI= false; fLIB= false; } virtual ~TAccess() { }; // virtual destructor virtual bool Connect ( cAppCharP aModName, ErrReport, void* ref= NULL ) { fModName= aModName; ref= NULL; // dummy to avoid warning return true; } // Connect virtual bool GetFunction ( cAppCharP aFuncName, cAppCharP, appPointer &aFunc, ErrMReport, void* ref= NULL ) { if (aFuncName!=NULL) aFunc= (appPointer)aFuncName; // interpret it as address ref= NULL; // dummy to avoid warning return true; } // GetFunction virtual bool Disconnect () { return true; } bool fJNI; bool fLIB; protected: appPointer fMod; string fModName; }; // TAccess #ifdef PLUGIN_DLL //! derived class for DLL access class TDLL : public TAccess { public: virtual bool Connect ( cAppCharP aModName, ErrReport aReport, void* ref= NULL ); virtual bool GetFunction( cAppCharP aFuncName, cAppCharP aParams, appPointer &aFunc, ErrMReport aReport, void* ref= NULL ); virtual bool Disconnect (); }; // TDLL #endif // PLUGIN_DLL // -------------------------------------------------------------------------- /*! General error reporting */ void Report_Error( cAppCharP aText, ... ); /*! Error output, if can't be found */ void ModuleConnectionError( void* /* ref */, cAppCharP aModName ); /*! Error output, if can't be found */ void FuncConnectionError ( void* /* ref */, cAppCharP aFuncName, cAppCharP aModName ); /*! Connects library/DLL/JNI . * is the module reference pointer. */ TSyError ConnectModule( appPointer &aMod, cAppCharP aModName, bool is_jni= false ); /*! Connects a list of functions to module . * The functions will be filled into with . An error will be * returned if the list of functions is too long or too short. * The open parameter list will be interpreted - as function names for DLLs * (or if module name is LIB/JNI) - as function pointers for libraries * is the module reference pointer. * must be true, if each element contains a second param with parameter info. */ TSyError ConnectFunctions( appPointer aMod, appPointer aField, memSize aFieldSize, bool aParamInfo, ... ); /*! Disconnect a connected unit * If mode is a library, =NULL can be passed */ TSyError DisconnectModule( appPointer &aMod ); #ifdef __cplusplus } // namespace #endif #endif /* DLL_INTERFACE_H */ /* eof */ libsynthesis-3.4.0.47.1/src/DB_interfaces/api_db/dbapi.cpp000077500000000000000000002317561226375725500231450ustar00rootroot00000000000000/* * File: dbapi.cpp * * Author: Beat Forster (bfo@synthesis.ch) * * * Programming interface between Synthesis SyncML engine * and a database structure: C++ class interface * * Copyright (c) 2004-2011 by Synthesis AG + plan44.ch * */ #include "dbapi.h" #include "SDK_util.h" #include "SDK_support.h" #include "DLL_interface.h" #ifndef SYSYNC_ENGINE #include "stringutil.h" #endif #ifdef JNI_SUPPORT #include "JNI_interface.h" #endif // the simple demo adapter #ifdef DBAPI_DEMO namespace SDK_demodb { #include "dbapi_include.h" } // namespace #endif // more built-in adapters of the same kind can be used #ifdef DBAPI_EXAMPLE namespace example1 { #include "dbapi_include.h" } // namespace namespace example2 { #include "dbapi_include.h" } // namespace #endif // a silent adapter, which always returns OK #ifdef DBAPI_SILENT namespace silent { #include "dbapi_include.h" } // namespace #endif // the textdb adapter #ifdef DBAPI_TEXT namespace SDK_textdb { #include "dbapi_include.h" } // namespace #endif // the snowwhite/oceanblue adapter #ifdef DBAPI_SNOWWHITE namespace oceanblue { #include "dbapi_include.h" } // namespace #endif // the JNI bridge to Java #if defined JNI_SUPPORT && defined PLUGIN_DLL namespace SDK_jni { #include "dbapi_include.h" } // namespace #endif // the C# bridge #if defined CSHARP_SUPPORT && defined PLUGIN_DLL namespace SDK_csharp { #include "dbapi_include.h" } // namespace #endif // the bridge to OMA-DS 1.2 FILEOBJ #ifdef DBAPI_FILEOBJ namespace SDK_fileobj { #include "dbapi_include.h" } // namespace #endif // the dbapi logger bridge #ifdef DBAPI_LOGGER namespace logger { #include "dbapi_include.h" } // namespace #endif // some internal modules do not have the full set of routines #define DISABLE_PLUGIN_SESSIONAUTH 1 #define DISABLE_PLUGIN_DEVICEADMIN 1 #define DISABLE_PLUGIN_DATASTOREADMIN 1 #define DISABLE_PLUGIN_ADAPTITEM 1 // the bridge via tunnel to any datastore inside the engine #if defined DBAPI_TUNNEL && defined PLUGIN_DLL namespace SDK_tunnel { #include "dbapi_include.h" } // namespace #endif // iPhone plugins are AsKey only #define DISABLE_PLUGIN_DATASTOREDATA_STR // static plugins required for iPhoneOS (no DLLs allowed) #ifdef IPHONE_PLUGINS_STATIC #ifdef HARDCODED_CONTACTS namespace iPhone_addressbook { #include "dbapi_include.h" } // namespace #endif #ifdef HARDCODED_CALENDAR namespace iPhone_calendar { #include "dbapi_include.h" } // namespace #endif #ifdef HARDCODED_TODO namespace iPhone_todos { #include "dbapi_include.h" } // namespace #endif #ifdef HARDCODED_NOTES namespace iPhone_notes { #include "dbapi_include.h" } // namespace #endif #ifdef HARDCODED_EMAILS namespace iPhone_emails { #include "dbapi_include.h" } // namespace #endif #ifdef HARDCODED_CUSTOM namespace iPhone_dbplugin1 { #include "dbapi_include.h" } // namespace namespace iPhone_dbplugin2 { #include "dbapi_include.h" } // namespace namespace iPhone_dbplugin3 { #include "dbapi_include.h" } // namespace namespace iPhone_dbplugin4 { #include "dbapi_include.h" } // namespace #endif #endif #undef DISABLE_PLUGIN_DATASTOREDATA_STR #undef DISABLE_PLUGIN_ADAPTITEM #define DISABLE_PLUGIN_DATASTOREDATA 1 // the "adaptitem" module does not contain most of the routines #ifdef ADAPTITEM_SUPPORT namespace SDK_adapt { #include "dbapi_include.h" } // namespace #endif // the UI demo adapter is something special #define DISABLE_PLUGIN_ADAPTITEM 1 #define ENABLE_PLUGIN_UI 1 #ifdef UIAPI_DEMO namespace SDK_ui { #include "dbapi_include.h" } // namespace #endif #undef DISABLE_PLUGIN_ADAPTITEM #undef DISABLE_PLUGIN_SESSIONAUTH #undef DISABLE_PLUGIN_DEVICEADMIN #undef DISABLE_PLUGIN_DATASTOREADMIN #undef DISABLE_PLUGIN_DATASTOREDATA // all should be switched on now for "no_dbapi" // ------------------------------------------------------------ #define MyDB "DBApi" // identifier of the sandwich layer namespace no_dbapi { #include "dbapi_include.h" // combine the definitions of different namespaces using sysync::DB_Callback; using sysync::UI_Call_In; using sysync::ItemID; using sysync::MapID; using sysync::cItemID; using sysync::cMapID; using sysync::LOCERR_NOTIMP; using sysync::Password_Mode_Undefined; // default routines, if no context is available // all of them are returning false or 0 /* --- MODULE ------------------------------------------------------------------------------------ */ TSyError Module_CreateContext ( CContext* mc, cAppCharP /* moduleName */, cAppCharP /* subName */, cAppCharP /* mContextName */, DB_Callback /* mCB */ ) { *mc= 0; return LOCERR_OK; } CVersion Module_Version ( CContext /* mc */ ) /* invalid */ { return VP_BadVersion;} TSyError Module_Capabilities ( CContext /* mc */, appCharP *aCapaP ) { *aCapaP= NULL; return DB_NotFound; } TSyError Module_PluginParams ( CContext /* mc */, cAppCharP /* mConfigParams */, CVersion /* engineVersion */ ) { return DB_Error; } void Module_DisposeObj ( CContext /* mc */, void* /* memory */ ) { } TSyError Module_DeleteContext ( CContext /* mc */ ) { return LOCERR_OK; } /* --- SESSION ----------------------------------------------------------------------------------- */ TSyError Session_CreateContext ( CContext* /* sc */, cAppCharP /* sessionName */, DB_Callback /* sCB */ ) { return DB_Fatal; } TSyError Session_AdaptItem ( CContext /* sc */, appCharP* /* sItemData1 */, appCharP* /* sItemData2 */, appCharP* /* sLocalvars */, uInt32 /* sIdentifier */ ) { return DB_Forbidden; } TSyError Session_CheckDevice ( CContext /* sc */, cAppCharP /* aDeviceID */, appCharP* /* sDevKey */, appCharP* /* nonce */ ) { return DB_Forbidden; } sInt32 Session_PasswordMode ( CContext /* sc */ ) { return Password_Mode_Undefined; } TSyError Session_Login ( CContext /* sc */, cAppCharP /* sUsername */, appCharP* /* sPassword */, appCharP* /* sUsrKey */ ) { return DB_Forbidden; } TSyError Session_Logout ( CContext /* sc */ ) { return DB_Forbidden; } TSyError Session_GetNonce ( CContext /* sc */, appCharP* /* nonce */ ) { return DB_Forbidden; } TSyError Session_SaveNonce ( CContext /* sc */, cAppCharP /* nonce */ ) { return DB_Forbidden; } TSyError Session_SaveDeviceInfo ( CContext /* sc */, cAppCharP /* aDeviceInfo */ ) { return DB_Forbidden; } TSyError Session_GetDBTime ( CContext /* sc */, appCharP* /* currentDBTime */) { return DB_Forbidden; } void Session_DisposeObj ( CContext /* sc */, void* /* memory */ ) { } void Session_ThreadMayChangeNow( CContext /* sc */ ) { } void Session_DispItems ( CContext /* sc */, bool, cAppCharP ) { } TSyError Session_DeleteContext ( CContext /* sc */ ) { return DB_Fatal; } /* --- DATASTORE --------------------------------------------------------------------------------- */ /* ----- OPEN ------------------------ */ TSyError CreateContext ( CContext* /* co */, cAppCharP /* aContextName */, DB_Callback /* aCB */, cAppCharP /* sDevKey */, cAppCharP /* sUsrKey */ ) { return DB_Fatal; } uInt32 ContextSupport ( CContext /* co */, cAppCharP /* aContextRules */ ) { return 0; } uInt32 FilterSupport ( CContext /* co */, cAppCharP /* aFilterRules */ ) { return 0; } /* ----- ADMINISTRATION -------------- */ TSyError LoadAdminData ( CContext /* co */, cAppCharP /* aLocDB */, cAppCharP /* aRemDB */, appCharP* /* adminData */ ) { return DB_Forbidden; } TSyError LoadAdminDataAsKey( CContext /* co */, cAppCharP /* aLocDB */, cAppCharP /* aRemDB */, KeyH /* adminKey */ ) { return DB_Forbidden; } TSyError SaveAdminData ( CContext /* co */, cAppCharP /* adminData */ ) { return DB_Forbidden; } TSyError SaveAdminDataAsKey( CContext /* co */, KeyH /* adminKey */ ) { return DB_Forbidden; } bool ReadNextMapItem ( CContext /* co */, MapID /* mID */, bool /* aFirst */ ) { return false; } TSyError InsertMapItem ( CContext /* co */, cMapID /* mID */ ) { return DB_Forbidden; } TSyError UpdateMapItem ( CContext /* co */, cMapID /* mID */ ) { return DB_Forbidden; } TSyError DeleteMapItem ( CContext /* co */, cMapID /* mID */ ) { return DB_Forbidden; } /* ----- GENERAL --------------------- */ void DisposeObj ( CContext /* co */, void* /* memory */ ) { } void ThreadMayChangeNow ( CContext /* co */ ) { } void WriteLogData ( CContext /* co */, cAppCharP /* logData */ ) { } void DispItems ( CContext /* co */, bool, cAppCharP ) { } /* ----- "script-like" ADAPT --------- */ TSyError AdaptItem ( CContext /* co */, appCharP* /* aItemData1 */, appCharP* /* aItemData2 */, appCharP* /* aLocalvars */, uInt32 /* aIdentifier */ ) { return DB_Forbidden; } /* ----- READ ------------------------ */ TSyError StartDataRead ( CContext /* co */, cAppCharP /* lastToken */, cAppCharP /* resumeToken */ ) { return DB_Fatal; } TSyError ReadNextItem ( CContext /* co */, ItemID /* aID */, appCharP* /* aItemData */, sInt32* /* aStatus */, bool /* aFirst */ ) { return DB_Fatal; } TSyError ReadNextItemAsKey( CContext /* co */, ItemID /* aID */, KeyH /* aItemKey */, sInt32* /* aStatus */, bool /* aFirst */ ) { return DB_Fatal; } TSyError ReadItem ( CContext /* co */, cItemID /* aID */, appCharP* /* aItemData */ ) { return DB_Fatal; } TSyError ReadItemAsKey ( CContext /* co */, cItemID /* aID */, KeyH /* aItemKey */ ) { return DB_Fatal; } TSyError ReadBlob ( CContext /* co */, cItemID /* aID */, cAppCharP /* aBlobID */, appPointer* /* aBlkPtr */, memSize* /* aBlkSize */, memSize* /* aTotSize */, bool /* aFirst */, bool* /* aLast */ ) { return DB_Fatal; } TSyError EndDataRead ( CContext /* co */ ) { return DB_Fatal; } /* ----- WRITE ----------------------- */ TSyError StartDataWrite ( CContext /* co */ ) { return DB_Fatal; } TSyError InsertItem ( CContext /* co */, cAppCharP /* aItemData */, ItemID /* newID */ ) { return DB_Fatal; } TSyError InsertItemAsKey ( CContext /* co */, KeyH /* aItemKey */, ItemID /* newID */ ) { return DB_Fatal; } TSyError UpdateItem ( CContext /* co */, cAppCharP /* aItemData */, cItemID /* aID */, ItemID /* updID */ ) { return DB_Fatal; } TSyError UpdateItemAsKey ( CContext /* co */, KeyH /* aItemKey */, cItemID /* aID */, ItemID /* updID */ ) { return DB_Fatal; } TSyError MoveItem ( CContext /* co */, cItemID /* aID */, cAppCharP /* newParID */ ) { return DB_Fatal; } TSyError DeleteItem ( CContext /* co */, cItemID /* aID */ ) { return DB_Fatal; } TSyError FinalizeLocalID ( CContext /* co */, cItemID /* aID */, ItemID /* updID */ ) { return DB_Fatal; } TSyError DeleteSyncSet ( CContext /* co */ ) { return DB_Fatal; } TSyError WriteBlob ( CContext /* co */, cItemID /* aID */, cAppCharP /* aBlobID */, appPointer /* aBlkPtr */,memSize /* aBlkSize */, memSize /* aTotSize */, bool /* aFirst */, bool /* aLast */ ) { return DB_Fatal; } // There are older implementations, where "DeleteBlob" is not yet available. TSyError DeleteBlob ( CContext /* co */, cItemID /* aID */, cAppCharP /* aBlobID */ ) { return LOCERR_NOTIMP; } TSyError EndDataWrite ( CContext /* co */, bool /* success */, char** /* newToken */ ) { return DB_Fatal; } /* ----- CLOSE ----------------------- */ TSyError DeleteContext ( CContext /* co */ ) { return DB_Fatal; } /* ---- UI API ----------------------- */ TSyError UI_CreateContext ( CContext* /* co */, cAppCharP /* uiName */, UI_Call_In /* uCI */ ) { return DB_Fatal; } TSyError UI_RunContext ( CContext /* co */ ) { return DB_Fatal; } TSyError UI_DeleteContext ( CContext /* co */ ) { return DB_Fatal; } } // namespace no_dbapi /* ---- "TDB_Api_Str" implementation --------------------------------------- */ namespace sysync { TDB_Api_Str::TDB_Api_Str() { clear(); } // constructor TDB_Api_Str::TDB_Api_Str( string &s ) { clear(); fStr= (char*)s.c_str(); } // alternative constructor TDB_Api_Str::~TDB_Api_Str() { DisposeStr(); } // destructor void TDB_Api_Str::AssignStr( CContext aContext, DisposeProc aDisposeProc, bool itself ) { fContext= aContext; fItself = itself; if (fStr!=NULL) fDisposeProc= aDisposeProc; else { fDisposeProc= NULL; fStr= const_cast(""); /* this is okay because the string is not going to be disposed */ } } // AssignStr void TDB_Api_Str::DisposeStr() { // nothing to do, already disposed ? if (fStr !=NULL && fDisposeProc!=NULL) { void* ref= const_cast(fStr); if (fItself) ref= this; fDisposeProc( fContext,ref ); } // if clear(); // don't do it again !! } // DisposeStr /* Dispose a string which has been allocated with 'StrAlloc' * Used as handler for: * typedef void( *DisposeProc)( long aContext, void* s ); */ static void StrDispose_Handler( CContext /* aContext */, void* s ) { StrDispose( s ); } // StrDispose_Handler /* ---------- allocate local memory for a string ------------- */ void TDB_Api_Str::LocalAlloc( CContext aContext, cAppCharP str ) { fStr= StrAlloc( str ); AssignStr( aContext, (DisposeProc)StrDispose_Handler ); } // LocalAlloc /* ---- "DB_Api_Blk" implementation --------------------------------------- */ TDB_Api_Blk::TDB_Api_Blk() { clear(); } // constructor TDB_Api_Blk::~TDB_Api_Blk() { DisposeBlk(); } // destructor void TDB_Api_Blk::AssignBlk( CContext aContext, DisposeProc aDisposeProc, bool itself ) { fContext= aContext; fItself = itself; if (fPtr!=NULL) fDisposeProc= (DisposeProc)aDisposeProc; else { fDisposeProc= NULL; fSize= 0; } } // AssignBlk void TDB_Api_Blk::DisposeBlk() { // nothing to do, already disposed ? if (fPtr !=NULL && fDisposeProc!=NULL) { void* ref= fPtr; if (fItself) ref= this; fDisposeProc( fContext,ref ); } // if clear(); // don't do it again !! } // DisposeBlk // Returns true if is name or # static bool BuiltIn( string &ps, int &n, cAppCharP name ) { if (strucmp( ps.c_str(), name )==0) return true; string s= "#" + IntStr( n++ ); if (strucmp( ps.c_str(), s.c_str() )==0) { ps= name; return true; } return false; } // BuiltIn /* --- connect to library ------------------------------------------------- */ /*! These are the built-in linked libraries, which can be accessed directly * NOTE: Some of them are normally switched off with compile options * * SDK plugin modules can be also linked into the engine directly. * Normally the compiler must be able to link all SDK routines. * The SDK concept allows to have some routines unimplemented, * they will be provided by the "no_dbapi" built-in module. */ static TSyError DBApi_LibAssign( appPointer aMod, string &ps, appPointer aField, int aFSize, cAppCharP aKey= "" ) { TSyError err= DB_NotFound; int n= 0; // incremental counter starting with 0 // the blind adapter is always available and acts as default as well if (strucmp( ps.c_str(), "" )==0 || BuiltIn( ps,n, "no_dbapi" )) err= no_dbapi::AssignMethods( aMod, aField,aFSize, aKey ); #ifdef DBAPI_DEMO // demo (C) adapter, which will be delivered with SDK else if (BuiltIn( ps,n, "SDK_demodb" )) err= SDK_demodb::AssignMethods( aMod, aField,aFSize, aKey ); #endif #ifdef DBAPI_EXAMPLE // other (C++) linked versions of the demo adapter (for test) else if (BuiltIn( ps,n, "example1" )) err= example1::AssignMethods( aMod, aField,aFSize, aKey ); else if (BuiltIn( ps,n, "example2" )) err= example2::AssignMethods( aMod, aField,aFSize, aKey ); #endif #ifdef DBAPI_SILENT // a silent adapter, which always says, everthing is ok else if (BuiltIn( ps,n, "silent" )) err= silent::AssignMethods( aMod, aField,aFSize, aKey ); #endif #ifdef DBAPI_TEXT // "text_db" implementation, which emulates the "textdb" else if (BuiltIn( ps,n, "SDK_textdb" )) err= SDK_textdb::AssignMethods( aMod, aField,aFSize, aKey ); #endif #ifdef DBAPI_SNOWWHITE // "oceanblue/snowwhite" implementation else if (BuiltIn( ps,n, "snowwhite" )) err= oceanblue::AssignMethods( aMod, aField,aFSize, aKey ); #endif #ifdef PLUGIN_DLL // plugin bridges #ifdef JNI_SUPPORT // the Java (JNI) adapter else if (BuiltIn( ps,n, "JNI" )) err= SDK_jni::AssignMethods( aMod, aField,aFSize, aKey ); #endif #ifdef CSHARP_SUPPORT // the C# adapter else if (BuiltIn( ps,n, "CSHARP" )) err= SDK_csharp::AssignMethods( aMod, aField,aFSize, aKey ); #endif #ifdef DBAPI_TUNNEL // direct access to internal adapters else if (BuiltIn( ps,n, "tunnel" )) err= SDK_tunnel::AssignMethods( aMod, aField,aFSize, aKey ); #endif #ifdef DBAPI_LOGGER // dbapi logger bridge else if (BuiltIn( ps,n, "logger" )) err= logger::AssignMethods( aMod, aField,aFSize, aKey ); #endif #endif #ifdef DBAPI_FILEOBJ // dbapi fileobj else if (BuiltIn( ps,n, "FILEOBJ" )) err= SDK_fileobj::AssignMethods( aMod, aField,aFSize, aKey ); #endif #ifdef ADAPTITEM_SUPPORT // "script-like" adapt item else if (BuiltIn( ps,n, "ADAPTITEM" )) err= SDK_adapt::AssignMethods( aMod, aField,aFSize, aKey ); #endif #ifdef UIAPI_DEMO // demo (C++) UI interface adapter, which will be delivered with SDK else if (BuiltIn( ps,n, "SDK_ui" )) err= SDK_ui::AssignMethods( aMod, aField,aFSize, aKey ); #endif #ifdef IPHONE_PLUGINS_STATIC // iPhone OS does not allow DLL plugins at this time, so we must link them statically #ifdef HARDCODED_CONTACTS else if (BuiltIn( ps,n, "iPhone_addressbook")) err= iPhone_addressbook::AssignMethods( aMod, aField,aFSize, aKey ); #endif #ifdef HARDCODED_CALENDAR else if (BuiltIn( ps,n, "iPhone_calendar" )) err= iPhone_calendar::AssignMethods( aMod, aField,aFSize, aKey ); #endif #ifdef HARDCODED_TODO else if (BuiltIn( ps,n, "iPhone_todos" )) err= iPhone_todos::AssignMethods( aMod, aField,aFSize, aKey ); #endif #ifdef HARDCODED_NOTES else if (BuiltIn( ps,n, "iPhone_notes" )) err= iPhone_notes::AssignMethods( aMod, aField,aFSize, aKey ); #endif #ifdef HARDCODED_EMAILS else if (BuiltIn( ps,n, "iPhone_emails" )) err= iPhone_emails::AssignMethods( aMod, aField,aFSize, aKey ); #endif #ifdef HARDCODED_CUSTOM else if (BuiltIn( ps,n, "iPhone_dbplugin1" )) err= iPhone_dbplugin1::AssignMethods( aMod, aField,aFSize, aKey ); else if (BuiltIn( ps,n, "iPhone_dbplugin2" )) err= iPhone_dbplugin2::AssignMethods( aMod, aField,aFSize, aKey ); else if (BuiltIn( ps,n, "iPhone_dbplugin3" )) err= iPhone_dbplugin3::AssignMethods( aMod, aField,aFSize, aKey ); else if (BuiltIn( ps,n, "iPhone_dbplugin4" )) err= iPhone_dbplugin4::AssignMethods( aMod, aField,aFSize, aKey ); #endif #endif else if (strucmp( ps.c_str(), "#" )==0) err= LOCERR_UNKSUBSYSTEM; else if (!BuiltIn( ps,n, "" )) ModuleConnectionError( NULL, AddBracks( ps ).c_str() ); return err; } // DBApi_LibAssign /* ---- wrapper for DB_Callback -------------------------------------------- */ TDB_Api_Callback::TDB_Api_Callback() { InitCallback( &Callback, DB_Callback_Version, NULL,NULL ); } /* ---- "DB_Api_Config" implementation ------------------------------------- */ TDB_Api_Config::TDB_Api_Config() { fMod= NULL; clear(); fTSTversion= VP_BadVersion; } // constructor TDB_Api_Config::~TDB_Api_Config() { Disconnect(); } // destructor static void connect_no_dbapi( appPointer &aMod, API_Methods &m ) { string no_dbapi= ""; DisconnectModule( aMod ); // avoid memory leak ConnectModule ( aMod,"" ); // default: no db_api -> all methods return false //---- module -------------------------------- DBApi_LibAssign ( aMod,no_dbapi, &m.start, sizeof(m.start), Plugin_Start ); DBApi_LibAssign ( aMod,no_dbapi, &m.param, sizeof(m.param), Plugin_Param ); DBApi_LibAssign ( aMod,no_dbapi, &m, sizeof(m) ); //---- session ------------------------------- DBApi_LibAssign ( aMod,no_dbapi, &m.se, sizeof(m.se), Plugin_Session ); DBApi_LibAssign ( aMod,no_dbapi, &m.se.seAdapt, sizeof(m.se.seAdapt), Plugin_SE_Adapt ); DBApi_LibAssign ( aMod,no_dbapi, &m.se.seAuth, sizeof(m.se.seAuth), Plugin_SE_Auth ); DBApi_LibAssign ( aMod,no_dbapi, &m.se.dvAdmin, sizeof(m.se.dvAdmin), Plugin_DV_Admin ); DBApi_LibAssign ( aMod,no_dbapi, &m.se.dvTime, sizeof(m.se.dvTime), Plugin_DV_DBTime ); //---- datastore ----------------------------- DBApi_LibAssign ( aMod,no_dbapi, &m.ds, sizeof(m.ds), Plugin_Datastore ); DBApi_LibAssign ( aMod,no_dbapi, &m.ds.dsg, sizeof(m.ds.dsg), Plugin_DS_General ); DBApi_LibAssign ( aMod,no_dbapi, &m.ds.dsAdapt, sizeof(m.ds.dsAdapt), Plugin_DS_Adapt ); DBApi_LibAssign ( aMod,no_dbapi, &m.ds.dsAdm.str, sizeof(m.ds.dsAdm.str), Plugin_DS_Admin_Str ); DBApi_LibAssign ( aMod,no_dbapi, &m.ds.dsAdm.key, sizeof(m.ds.dsAdm.key), Plugin_DS_Admin_Key ); DBApi_LibAssign ( aMod,no_dbapi, &m.ds.dsAdm.map, sizeof(m.ds.dsAdm.map), Plugin_DS_Admin_Map ); DBApi_LibAssign ( aMod,no_dbapi, &m.ds.dsData, sizeof(m.ds.dsData), Plugin_DS_Data ); DBApi_LibAssign ( aMod,no_dbapi, &m.ds.dsData.str,sizeof(m.ds.dsData.str),Plugin_DS_Data_Str ); DBApi_LibAssign ( aMod,no_dbapi, &m.ds.dsData.key,sizeof(m.ds.dsData.key),Plugin_DS_Data_Key ); DBApi_LibAssign ( aMod,no_dbapi, &m.ds.dsBlob, sizeof(m.ds.dsBlob), Plugin_DS_Blob ); //---- ui context ---------------------------- DBApi_LibAssign ( aMod,no_dbapi, &m.ui, sizeof(m.ui), Plugin_UI ); DisconnectModule( aMod ); // no longer used, avoid memory leak } // connect_no_dbapi void TDB_Api_Config::clear() { connect_no_dbapi( fMod, m ); fConnected = false; fADMIN_Info= false; fSDKversion= VP_BadVersion; fMODversion= VP_BadVersion; mContext = 0; DB_Callback mCB= &fCB.Callback; mCB->cContext= 0; // set it to uninitialized default mCB->mContext= 0; } // clear // --------------------------------------------------------------------- //! Module string disposer void TDB_Api_Config::DisposeStr( TDB_Api_Str &s ) { fSList.remove( &s ); // remove it from the list first to avoid double free s.AssignStr( mContext, (DisposeProc)m.Module_DisposeObj ); s.DisposeStr(); } // DisposeStr //! Local wrapper, because it must be DisposeProc type and can't be C++ method static void Local_Module_DisposeStr( CContext mObj, void* memory ) { TDB_Api_Config* c= (TDB_Api_Config*)mObj; TDB_Api_Str* u= (TDB_Api_Str*)memory; c->DisposeStr( *u ); } // Local_Session_DisposeStr void TDB_Api_Config::AssignStr( TDB_Api_Str &s ) { if (s.fStr==NULL) return; s.AssignStr( (CContext)this, Local_Module_DisposeStr, true ); fSList.push_back( &s ); // add the element to the list } // AssignStr // --------------------------------------------------------------------- // general datastore access ? bool DSConnect( cAppCharP aItem ) { return FlagOK( aItem, Plugin_Datastore ) && ( FlagOK( aItem, Plugin_DS_Admin ) || FlagOK( aItem, Plugin_DS_Data ) || FlagOK( aItem, Plugin_DS_Adapt ) ); } // DSConnect TSyError TDB_Api_Config::DBApi_Assign( cAppCharP aItem, appPointer aField, memSize aFieldSize, cAppCharP aKey ) { TSyError err= LOCERR_OK; if (FlagOK( aItem,aKey )) { if (is_lib) err= DBApi_LibAssign( fMod, fPlugin, aField,aFieldSize, aKey ); else { err= DB_Forbidden; // only allowed, if PLUGIN_DLL is active #ifdef PLUGIN_DLL err= DBApi_DLLAssign( fMod, aField,aFieldSize, aKey, false ); #endif } // if DEBUG_Exotic_INT( &fCB.Callback,MyDB, "DBApi_Assign", "aKey='%s' (size=%d) err=%d", aKey, aFieldSize, err ); } // if return err; } // DBApi_Assign // Returns the engine's SDK version long TDB_Api_Config::EngineSDKVersion() { // If not changed ... if (fTSTversion==VP_BadVersion) return Plugin_Version( 0 ); // Called here it's the engine's SDK version else return fTSTversion; // modified for test } // EngineSDKVersion // Returns LOCERR_TOOOLD, if the version is too old TSyError TDB_Api_Config::MinVersionCheck( string capa, CVersion &vMin ) { TSyError err= LOCERR_OK; vMin= 0; string value; while (RemoveField( capa, CA_MinVersion, value )) { CVersion minVersion= VersionNr( value ); // the minimum required version of the plugin CVersion engVersion= EngineSDKVersion () | 0x000000ff; // the engine's version with max build number if (engVersion= %08X / err=%d", engVersion, minVersion, err ); if (err) break; } // while return err; } // MinVersionCheck // Connect to internally linked library or external DLL, dependent on and TSyError TDB_Api_Config::Connect( cAppCharP aModName, CContext &globContext, cAppCharP mContextName, bool aIsLib, bool allowDLL ) { TSyError err; string gcs; if (fConnected) Disconnect(); if (fConnected) return DB_Error; // still connected ? => error cAppCharP x= ""; DB_Callback mCB= &fCB.Callback; CContext* mc= &mCB->mContext; // store it at a temporary var *mc= 0; clear(); is_lib = IsLib( aModName ); fModName= aModName; // make a local copy if (aIsLib) { // && !is_lib) : special cases like "[aaa]!bbb" => "[[aaa]!bbb]" fModName= AddBracks( aModName ); is_lib = true; } // if GlobContext* g; GlobContext* gp; if (CB_OK( mCB,8 )) { // available ? mCB->gContext= globContext; for (int i= 1; i<=3; i++) { // create 3 empty elements gp= new GlobContext; // create and init a new record gp->ref = NULL; gp->next= NULL; gp->cnt = 0; strcpy( gp->refName,"" ); if (!mCB->gContext) mCB->gContext= (CContext)gp; // assign it else { g= (GlobContext*)mCB->gContext; // or add it to the end of the chain while (g->next!=NULL) g= (GlobContext*)g->next; g->next= gp; } // if } // for } // if do { // exit part if (!is_lib) { x= "(DLL)"; if (!allowDLL) { err= DB_Forbidden; break; } } // if WithSubSystem ( fModName, fModMain, fModSub ); bool in_bracks= CutBracks( fModMain ); // "[aaa xx]" => "aaa xx" fOptions= fModMain; NextToken ( fOptions, fModMain, " " ); // separate fModName= fModMain; CutBracks( fModMain ); fPlugin = fModMain; if (in_bracks) fModName = AddBracks( fModName ); /* this mode is no longer supported ( moduleName:globContext ) */ /* keep it for compatiblity */ if (globContext) { g= (GlobContext*)globContext; while (g!=NULL) { if (strcmp( g->refName,"" )!=0) { // at least one field is set fModMain+= ":" + RefStr( globContext ); break; } // if g= g->next; } // while } // if if (!fOptions.empty()) fModMain+= " " + fOptions; // create some downwards compatibility info if (CB_OK( mCB,4 )) { if (allowDLL) mCB->allow_DLL_legacy= 0xffff; // Assign DLL allowance info else mCB->allow_DLL_legacy= 0x0000; if (CB_OK( mCB,5 )) { mCB->allow_DLL= mCB->allow_DLL_legacy; } // if } // if // Connect "Module_CreateContext" and "Module_Version" first, to take decisions err= ConnectModule( fMod, fModName.c_str() ); if (err) break; err= DBApi_Assign( "", &m.start, sizeof(m.start), Plugin_Start ); if (err) break; Version_Func pv= (Version_Func)m.start.Module_Version; fSDKversion= pv( 0 ); // get the plugin's version before making the first tests DEBUG_INT( mCB,MyDB, "Connect", "fSDKversion=%s", VersionStr( fSDKversion ).c_str() ); string sn= fModSub; if (sn=="[#]" && !(fPlugin=="logger")) sn= ""; // remove the recursion breaker CreateM_Func p= (CreateM_Func)m.start.Module_CreateContext; err= p( &mContext, fModMain.c_str(), sn.c_str(), mContextName, mCB ); if (err==LOCERR_ALREADY) err= LOCERR_OK; // this is not an error, just avoid multiple assignment DEBUG_INT( mCB,MyDB, "Connect", "mContext=%08X err=%d", mContext,err ); if (err) break; fMODversion= pv( mContext ); // get the plugin's version before making the first tests mCB->cContext = mContext; // assign for the callback mechanism if (*mc==0) *mc= mContext; // assign for session & datastores, if not already in use (e.g. for JNI) //err= VersionCheck(); if (err) break; TDB_Api_Str aCapa; err= Capabilities( aCapa ); if (err) break; cAppCharP ca= aCapa.c_str(); CVersion vMin; err= MinVersionCheck( ca, vMin ); if (err) break; fADMIN_Info= FlagOK( ca, CA_ADMIN_Info, true ); GetField( ca, CA_Description, fDesc ); GetField( ca, CA_GlobContext, gcs ); // is there a global context inside ? // !Supported( VP_EngineVersionParam ): only JNI signature changes // !Supported( VP_MD5_Nonce_IN ): only JNI signature changes cAppCharP vda= Plugin_DS_Admin_Map; if (!Supported( VP_InsertMapItem )) vda= Plugin_DS_Admin_OLD; cAppCharP vdd= Plugin_DS_Data; if (!Supported( VP_FLI_DSS )) vdd= Plugin_DS_Data_OLD2; if (!Supported( VP_ResumeToken )) vdd= Plugin_DS_Data_OLD1; cAppCharP vdb= Plugin_DS_Blob; if (!Supported( VP_BLOB_JSignature )) vdb= Plugin_DS_Blob_OLD2; // new BLOB signature if (!Supported( VP_DeleteBlob )) vdb= Plugin_DS_Blob_OLD1; //---- module --------------------------------- if (!err) err= DBApi_Assign( "", &m.param, sizeof(m.param), Plugin_Param ); if (!err) err= DBApi_Assign( "", &m, sizeof(m) ); //---- session -------------------------------- if (!err && FlagOK ( ca, Plugin_Session )) { err= DBApi_Assign( ca, &m.se, sizeof(m.se), Plugin_Session ); if (!err && ( FlagOK ( ca, Plugin_SE_Auth ) || FlagOK ( ca, Plugin_DV_Admin ) )) { err= DBApi_Assign( ca, &m.se.seAuth, sizeof(m.se.seAuth), Plugin_SE_Auth ); if (!err) err= DBApi_Assign( ca, &m.se.dvAdmin, sizeof(m.se.dvAdmin), Plugin_DV_Admin ); if (!err && Supported( VP_GetDBTime )) { err= DBApi_Assign( ca, &m.se.dvTime, sizeof(m.se.dvTime), Plugin_DV_DBTime ); } // if } // if if (!err && Supported( VP_AdaptItem )) { err= DBApi_Assign( ca, &m.se.seAdapt, sizeof(m.se.seAdapt), Plugin_SE_Adapt ); } // if } // if //---- datastore ------------------------------ if (!err && FlagOK ( ca, Plugin_Datastore )) { if (!err && DSConnect( ca )) { err= DBApi_Assign( ca, &m.ds, sizeof(m.ds), Plugin_Datastore ); } // if if (!err && ( FlagOK ( ca, Plugin_DS_Admin ) || FlagOK ( ca, Plugin_DS_Data ) )) { err= DBApi_Assign( ca, &m.ds.dsg, sizeof(m.ds.dsg), Plugin_DS_General ); if (!err) err= DBApi_Assign( ca, &m.ds.dsBlob, sizeof(m.ds.dsBlob), vdb ); } // if if (!err && FlagOK ( ca, Plugin_DS_Admin )) { bool asK= FlagOK ( ca, CA_AdminAsKey, true ); if (asK) err= DBApi_Assign( ca, &m.ds.dsAdm.key, sizeof(m.ds.dsAdm.key),Plugin_DS_Admin_Key ); bool asS= !asK || FlagBoth( ca, CA_AdminAsKey ); if (asS) err= DBApi_Assign( ca, &m.ds.dsAdm.str, sizeof(m.ds.dsAdm.str),Plugin_DS_Admin_Str ); if (!err) err= DBApi_Assign( ca, &m.ds.dsAdm.map, sizeof(m.ds.dsAdm.map), vda ); } // if if (!err) err= DBApi_Assign( ca, &m.ds.dsData, sizeof(m.ds.dsData), vdd ); if (!err && FlagOK ( ca, Plugin_DS_Data )) { bool asK= FlagOK ( ca, CA_ItemAsKey, true ); if (asK) err= DBApi_Assign( ca, &m.ds.dsData.key,sizeof(m.ds.dsData.key),Plugin_DS_Data_Key ); bool asS= !asK || FlagBoth( ca, CA_ItemAsKey ); if (asS) err= DBApi_Assign( ca, &m.ds.dsData.str,sizeof(m.ds.dsData.str),Plugin_DS_Data_Str ); } // if if (!err && Supported( VP_AdaptItem )) { err= DBApi_Assign( ca, &m.ds.dsAdapt, sizeof(m.ds.dsAdapt), Plugin_DS_Adapt ); } // if } // if //---- ui context ----------------------------- if (!err && FlagOK( ca,Plugin_UI, true )) { err= DBApi_Assign( ca, &m.ui, sizeof(m.ui), Plugin_UI ); } // if } while (false); // end exit part if (err) clear(); if (CB_OK( mCB,8 )) { globContext= mCB->gContext; // available ? DeleteGlobContext ( globContext, mCB, true ); // remove elements with empty text and no ref mCB->gContext= globContext; // can be fully removed again (gContext==0) } else { // ---- the old fashioned way to do it ---- if (!gcs.empty()) { uIntPtr u; HexStrToUIntPtr( gcs.c_str(), u ); if (!globContext) globContext= (CContext)u; if (globContext!=(CContext)u) { // link it if more than one element GlobContext* gc= (GlobContext*)globContext; gc->next= (GlobContext*)u; } // if } // if // ----------------------------------------- } // if string s= "ok"; if (err) { char f[ 15 ]; sprintf( f, "err=%d", err ); s= f; } // if DEBUG_INT( mCB,MyDB,"Connect", "%s '%s' %-9s", s.c_str(), fModName.c_str(), x ); fConnected= !err; return err; } // Connect /* Get the plug-in's version number */ long TDB_Api_Config::Version() { return fMODversion; } /* Get the plug-in's capabilities */ TSyError TDB_Api_Config::Capabilities( TDB_Api_Str &aCapa ) { typedef TSyError (*CapabFunc)( CContext mContext, appCharP *mCapabilities ); aCapa.DisposeStr(); CapabFunc p= (CapabFunc)m.start.Module_Capabilities; TSyError err= p( mContext, const_cast(&aCapa.fStr) ); if (!err) AssignStr( aCapa ); return err; } // Capabilities /* Check, if is supported * NOTE: For the SyncML engine internally everything is supported * This will be reflected with the fact that the engine's * version is alway much much higher */ bool TDB_Api_Config::Supported( CVersion versionFeature ) { return Feature_Supported( versionFeature, fSDKversion ); } // Supported TSyError TDB_Api_Config::PluginParams( cAppCharP mConfigParams ) { typedef TSyError (*PlugProc)( CContext mContext, cAppCharP mConfigParams, CVersion engineVersion ); //typedef TSyError (*OLD_PlugProc)( CContext mContext, // cAppCharP mConfigParams ); // w/o TSyError err; if (!fConnected) return DB_Error; /* // new param supported for Plugin Version >= 1.0.X.4 if (Supported( VP_EngineVersionParam )) { PlugProc p= (PlugProc)m.param.Module_PluginParams; err= p( mContext, mConfigParams, EngineSDKVersion() ); } else { OLD_PlugProc p= (OLD_PlugProc)m.param.Module_PluginParams; // w/o the SDK version parameter err= p( mContext, mConfigParams ); } // if */ PlugProc p= (PlugProc)m.param.Module_PluginParams; err= p( mContext, mConfigParams, EngineSDKVersion() ); if (err==LOCERR_ALREADY) err= LOCERR_OK; return err; } // PluginParams // Set the SDK version // *** override the internal version number / for test only *** void TDB_Api_Config::SetVersion( long versionNr ) { fTSTversion= versionNr; DEBUG_INT( &fCB.Callback, MyDB,"SetVersion", "%08X", fTSTversion ); } // SetVersion TSyError TDB_Api_Config::Disconnect() { if (!fConnected) return DB_Error; // avoid double free // remove all still allocated elements before removing the content while (!fSList.empty()) DisposeStr( *fSList.front() ); Context_Func p= (Context_Func)m.Module_DeleteContext; TSyError err= p( mContext ); fModName= ""; DisconnectModule( fMod ); fConnected= false; return err; } // Disconnect /* ------------------------------------------------------------------------- */ void DispGlobContext( CContext &globContext, DB_Callback mCB ) { cAppCharP DGC= "DispGlobContext"; GlobContext* g= (GlobContext*)globContext; DEBUG_Exotic_DB ( mCB, MyDB,DGC, "g=%s mCB->gContext=%s", RefStr( g ).c_str(), RefStr( mCB->gContext ).c_str() ); while (g!=NULL) { GlobContext* nx= g->next; DEBUG_Exotic_DB( mCB, MyDB,DGC, "g=%s g->ref=%s g->cnt=%-3d '%s'", RefStr( g ).c_str(), RefStr( g->ref ).c_str(), g->cnt, g->refName ); g= nx; } // while DEBUG_Exotic_DB ( mCB, MyDB,DGC, "(eof)" ); } // DispGlobContext // mCB->gContext will not be touched here void DeleteGlobContext( CContext &globContext, DB_Callback mCB, bool emptyTextOnly ) { DispGlobContext( globContext, mCB ); DEBUG_Exotic_DB( mCB, "","DeleteGlobContext", "" ); GlobContext* ls= NULL; GlobContext* gs= (GlobContext*)globContext; GlobContext* g= gs; while (g!=NULL) { GlobContext* nx= g->next; bool remCond= g->ref==NULL && (!emptyTextOnly || strcmp( g->refName,"" )==0); if (remCond) { if (gs==g) gs = nx; // go forward if first element removed else ls->next= nx; delete g; g= ls; } // if ls= g; g = nx; } // while globContext= (CContext)gs; DispGlobContext( globContext, mCB ); } // DeleteGlobContext /* ---- "DB_Api_Session" implementation ------------------------------------ */ TDB_Api_Session::TDB_Api_Session() { sCreated= false; sContext= 0; appPointer modu= NULL; connect_no_dbapi( modu, sNo_dbapi ); // the empty connector is default as well dm= &sNo_dbapi; // and assign it sPwMode= Password_Mode_Undefined; } // constructor /* Create a context for a new session */ TSyError TDB_Api_Session::CreateContext( cAppCharP sessionName, TDB_Api_Config &config ) { if (sCreated) return DB_Forbidden; sSessionName= sessionName; // make a local copy dm= &config.m; // assign reference to the methods CreateS_Func p= (CreateS_Func)dm->se.Session_CreateContext; DB_Callback sCB= &fCB.Callback; CContext* sc= &sCB->sContext; // store it at a temporary var *sc= 0; // set it to check later, if changed string vers= VersionStr( config.fSDKversion ); if (config.fMODversion!=config.fSDKversion) vers+= " / " + VersionStr( config.fMODversion ); DEBUG_INT( sCB,MyDB,Se_CC, "desc='%s', vers=%s", config.fDesc.c_str(), vers.c_str() ); sCB->cContext= config.mContext; // inherit info sContext= 0; sCB->mContext= config.fCB.Callback.mContext; TSyError err= p( &sContext, sSessionName.c_str(), sCB ); if (!err) { sCreated= true; if (*sc==0) *sc= sContext; // assign for datastores, but only if not assigned in plug-in module } // if return LOCERR_OK; // workaround to avoid problems w/o a session return err; } // CreateContext // --------------------------------------------------------------------- void TDB_Api_Session::DisposeStr( TDB_Api_Str &s ) // Session str disposer { fSList.remove( &s ); // remove it from the list first to avoid double free s.AssignStr( sContext, (DisposeProc)dm->se.Session_DisposeObj ); s.DisposeStr(); } // DisposeStr static void Local_Session_DisposeStr( CContext sObj, void* memory ) /* Local wrapper, because it must be DisposeProc type and can't be C++ method */ { TDB_Api_Session* s= (TDB_Api_Session*)sObj; TDB_Api_Str* u= (TDB_Api_Str*)memory; s->DisposeStr ( *u ); } // Local_Session_DisposeStr void TDB_Api_Session::AssignStr( TDB_Api_Str &s ) { if (s.fStr==NULL) return; s.AssignStr( (CContext)this, Local_Session_DisposeStr, true ); fSList.push_back( &s ); // add the element to the list } // AssignStr // -------------------------------------------------------------------------------- TSyError TDB_Api_Session::CheckDevice( cAppCharP deviceID, TDB_Api_Str &sDevKey, TDB_Api_Str &nonce ) { typedef TSyError (*ChkDevFunc)( CContext sContext, cAppCharP deviceID, appCharP *sDevKey, appCharP *nonce ); sDevKey.DisposeStr(); nonce.DisposeStr(); ChkDevFunc p= (ChkDevFunc)dm->se.dvAdmin.Session_CheckDevice; TSyError err= p( sContext, deviceID, &sDevKey.fStr, &nonce.fStr ); if (!err) { AssignStr( sDevKey ); AssignStr( nonce ); } return err; } // CheckDevice TSyError TDB_Api_Session::GetNonce( TDB_Api_Str &nonce ) { typedef TSyError (*GetNcFunc)( CContext sContext, appCharP *nonce ); nonce.DisposeStr(); GetNcFunc p= (GetNcFunc)dm->se.dvAdmin.Session_GetNonce; TSyError err= p( sContext, &nonce.fStr ); if (!err) AssignStr( nonce ); return err; } // GetNonce TSyError TDB_Api_Session::SaveNonce( cAppCharP nonce ) { SvInfo_Func p= (SvInfo_Func)dm->se.dvAdmin.Session_SaveNonce; TSyError err= p( sContext, nonce ); return err; } // SaveNonce TSyError TDB_Api_Session::SaveDeviceInfo( cAppCharP aDeviceInfo ) { SvInfo_Func p= (SvInfo_Func)dm->se.dvAdmin.Session_SaveDeviceInfo; TSyError err= p( sContext, aDeviceInfo ); return err; } // SaveDeviceInfo TSyError TDB_Api_Session::GetDBTime( TDB_Api_Str ¤tDBTime ) { typedef TSyError (*DBTimeFunc)( CContext sContext, appCharP *currentDBTime ); currentDBTime.DisposeStr(); DBTimeFunc p= (DBTimeFunc)dm->se.dvTime.Session_GetDBTime; TSyError err= p( sContext, ¤tDBTime.fStr ); if (!err) AssignStr( currentDBTime ); return err; } // GetDBTime #ifdef SYSYNC_ENGINE // No 'lineartime_t' available for standalone TSyError TDB_Api_Session::GetDBTime( lineartime_t ¤tDBTime, GZones* g ) { timecontext_t tctx; TDB_Api_Str s; TSyError err= GetDBTime( s ); currentDBTime= 0; if (!err && !ISO8601StrToTimestamp ( s.c_str(), currentDBTime, tctx )) return DB_Error; TzConvertTimestamp( currentDBTime, tctx, TCTX_UTC, g, TCTX_SYSTEM ); return err; } // GetDBTime #endif /* ---- Login Handling ---------------------------------------- */ sInt32 TDB_Api_Session::PasswordMode() { if (sContext==0) return Password_Mode_Undefined; PwMode_Func p= (PwMode_Func)dm->se.seAuth.Session_PasswordMode; sPwMode= p( sContext ); /* calculate it always if (sPwMode==Password_Mode_Undefined) { ... } // if */ return sPwMode; } // PasswordMode /*! XXX_IN modes */ TSyError TDB_Api_Session::Login( cAppCharP sUsername, cAppCharP sPassword, TDB_Api_Str &sUsrKey ) { switch (PasswordMode()) { case Password_ClrText_IN : case Password_MD5_Nonce_IN : break; default : return DB_Forbidden; // !sCreated is covered here } // switch sUsrKey.DisposeStr(); Login_Func p= (Login_Func)dm->se.seAuth.Session_Login; TSyError err= p( sContext, sUsername, (char**)&sPassword, &sUsrKey.fStr ); if (!err) AssignStr( sUsrKey ); return err; } // Login /*! XXX_OUT modes */ TSyError TDB_Api_Session::Login( cAppCharP sUsername, TDB_Api_Str &sPassword, TDB_Api_Str &sUsrKey ) { switch (PasswordMode()) { case Password_ClrText_OUT : case Password_MD5_OUT : break; default : return DB_Forbidden; // !sCreated is covered here } // switch sPassword.DisposeStr(); sUsrKey.DisposeStr(); Login_Func p= (Login_Func)dm->se.seAuth.Session_Login; TSyError err= p( sContext, sUsername, &sPassword.fStr, &sUsrKey.fStr ); if (!err) { AssignStr( sPassword ); AssignStr( sUsrKey ); } return err; } // Login (overloaded) TSyError TDB_Api_Session::Logout() { if (sContext==0) return LOCERR_OK; Context_Func p= (Context_Func)dm->se.seAuth.Session_Logout; return p( sContext ); } // Logout /* ---- General session routines ------------------------------- */ void TDB_Api_Session::AssignChanged( string &a, TDB_Api_Str &u ) { if (a.c_str()!=u.fStr) { a= u.fStr; AssignStr( u ); } // assign for destruction afterwards } // AssignChanged TSyError TDB_Api_Session::AdaptItem( string &sItemData1, string &sItemData2, string &sLocalVars, uInt32 sIdentifier ) { TDB_Api_Str updItemData1( sItemData1 ); TDB_Api_Str updItemData2( sItemData2 ); TDB_Api_Str updLocalVars( sLocalVars ); Adapt_Func p= (Adapt_Func)dm->se.seAdapt.Session_AdaptItem; TSyError err= p( sContext, &updItemData1.fStr, &updItemData2.fStr, &updLocalVars.fStr, sIdentifier ); AssignChanged( sItemData1, updItemData1 ); AssignChanged( sItemData2, updItemData2 ); AssignChanged( sLocalVars, updLocalVars ); return err; } // AdaptItem void TDB_Api_Session::ThreadMayChangeNow() { VoidProc p= (VoidProc)dm->se.Session_ThreadMayChangeNow; p( sContext ); } // ThreadMayChangeNow void TDB_Api_Session::DispItems( bool allFields, cAppCharP specificItem ) { DispProc p= (DispProc)dm->se.Session_DispItems; p( sContext, allFields,specificItem ); } // DispItems /* ---- Delete the session context ---------------------------- */ TSyError TDB_Api_Session::DeleteContext() { if (!sCreated) return DB_Forbidden; // remove all still allocated elements before removing the content while (!fSList.empty()) DisposeStr( *fSList.front() ); Context_Func p= (Context_Func)dm->se.Session_DeleteContext; TSyError err= p( sContext ); if (!err) sCreated= false; return err; } // DeleteContext /* ---- "DB_Api" implementation ------------------------------------------- */ TDB_Api::TDB_Api() { fCreated= false; appPointer modu= NULL; connect_no_dbapi( modu, fNo_dbapi ); // the empty connector is default as well dm= &fNo_dbapi; // and assign it } // constructor TDB_Api::~TDB_Api() { DeleteContext(); } // destructor // --- open section ------------------------------------- TSyError TDB_Api::CreateContext( cAppCharP aContextName, bool asAdmin, TDB_Api_Config* config, cAppCharP sDevKey, cAppCharP sUsrKey, TDB_Api_Session* session ) { if (fCreated || !config || !config->fConnected) return DB_Forbidden; string cNam= aContextName; if (cNam.empty()) return DB_NotFound; // empty is not allowed fConfig= config; // make a local copy /* inherit the context information of module and session */ fCB.Callback.cContext= config->mContext; fCB.Callback.mContext= config->fCB.Callback.mContext; if (session) { fCB.Callback.sContext= session->fCB.Callback.sContext; } fDevKey = sDevKey; fUsrKey = sUsrKey; if (config->fADMIN_Info && asAdmin) cNam+= ADMIN_Ident; fContext= 0; dm= &config->m; CreateD_Func p= (CreateD_Func)dm->ds.CreateContext; TSyError err= p( &fContext, cNam.c_str(), &fCB.Callback, fDevKey.c_str(), fUsrKey.c_str() ); if (!err) fCreated= true; return err; } // CreateContext TSyError TDB_Api::RunContext( cAppCharP aContextName, bool asAdmin, SequenceProc sequence, string &token, TDB_Api_Config* config, cAppCharP sDevKey, cAppCharP sUsrKey, TDB_Api_Session* session ) { TSyError err= CreateContext( aContextName, asAdmin, config, sDevKey,sUsrKey, session ); if (err) return err; TSyError dErr; TDB_Api_Str newToken; err= StartDataRead( token.c_str() ); // no sequence is allowed as well if (!err && sequence!=NULL) { err = sequence( *this ); dErr= EndDataWrite( !err, newToken ); if (!err) err= dErr; token= newToken.c_str(); newToken.DisposeStr(); } // if dErr= DeleteContext(); if (!err) err= dErr; return err; } // RunContext // --------------------------------------------------------------------- // returns the nth config data field, which is supported (and activated) // result= 0: no filter supported. uInt32 TDB_Api::ContextSupport( cAppCharP aContextRules ) { Text_Func p= (Text_Func)dm->ds.dsg.ContextSupport; return p( fContext,aContextRules ); } // ContextSupport // returns the nth filter rule, which is supported (and activated) // result= 0: no filter supported. uInt32 TDB_Api::FilterSupport ( cAppCharP aFilterRules ) { Text_Func p= (Text_Func)dm->ds.dsg.FilterSupport; return p( fContext,aFilterRules ); } // FilterSupport // --------------------------------------------------------------------- // Str disposer void TDB_Api::DisposeStr( TDB_Api_Str &s ) { fSList.remove( &s ); // remove it from the list first to avoid double free s.AssignStr( fContext, (DisposeProc)dm->ds.DisposeObj ); s.DisposeStr(); } // DisposeStr // Local wrapper, because it must be DisposeProc type and can't be C++ method static void Local_DisposeStr( CContext aObj, void* memory ) { TDB_Api* a= (TDB_Api*)aObj; TDB_Api_Str* u= (TDB_Api_Str*)memory; a->DisposeStr( *u ); } // Local_DisposeStr void TDB_Api::AssignStr( TDB_Api_Str &s ) { if (s.fStr==NULL) return; s.AssignStr( (CContext)this, Local_DisposeStr, true ); fSList.push_back( &s ); // add the element to the list } // AssignStr // --------------------------------------------------------------------- // Blk disposer void TDB_Api::DisposeBlk( TDB_Api_Blk &b ) { fBList.remove( &b ); // remove it from the list first to avoid double free b.AssignBlk( fContext, (DisposeProc)dm->ds.DisposeObj ); b.DisposeBlk(); } // DisposeBlk // Local wrapper, because it must be DisposeProc type and can't be C++ method static void Local_DisposeBlk( CContext aObj, void* memory ) { TDB_Api* a= (TDB_Api*)aObj; TDB_Api_Blk* u= (TDB_Api_Blk*)memory; a->DisposeBlk( *u ); } // Local_DisposeBlk void TDB_Api::AssignBlk( TDB_Api_Blk &b ) { if (b.fPtr==NULL) return; b.AssignBlk( (CContext)this, Local_DisposeBlk, true ); fBList.push_back( &b ); // add the element to the list } // AssignBlk // --------------------------------------------------------------------- void TDB_Api::GetItemID( TDB_Api_ItemID &aID, TDB_Api_Str &aItemID ) { aItemID= aID.item; fSList.remove( &aID.item ); aID.item.fStr= NULL; // avoid double delete AssignStr ( aItemID ); aID.parent.DisposeStr(); // not used } // GetItemID // --- admin section ------------------------------- // This function gets the stored information about the record with the four paramters: // , (taken from the session context) // , . TSyError TDB_Api::LoadAdminData( cAppCharP aLocDB, cAppCharP aRemDB, TDB_Api_Str &adminData ) { adminData.DisposeStr(); LoadAdm_SFunc p= (LoadAdm_SFunc)dm->ds.dsAdm.str.LoadAdminData; TSyError err= p( fContext, aLocDB,aRemDB, &adminData.fStr ); if (!err) AssignStr( adminData ); return err; } // LoadAdminData TSyError TDB_Api::LoadAdminDataAsKey( cAppCharP aLocDB, cAppCharP aRemDB, KeyH aAdminKey ) { LoadAdm_KFunc p= (LoadAdm_KFunc)dm->ds.dsAdm.key.LoadAdminDataAsKey; TSyError err= p( fContext, aLocDB,aRemDB, aAdminKey ); return err; } // LoadAdminDataAsKey //! This functions stores the new for this context TSyError TDB_Api::SaveAdminData( cAppCharP adminData ) { SaveAdm_SFunc p= (SaveAdm_SFunc)dm->ds.dsAdm.str.SaveAdminData; return p( fContext, adminData ); } // SaveAdminData TSyError TDB_Api::SaveAdminData_AsKey( KeyH adminKey ) { SaveAdm_KFunc p= (SaveAdm_KFunc)dm->ds.dsAdm.key.SaveAdminDataAsKey; return p( fContext, adminKey ); } // SaveAdminDataAsKey // --- Map table handling ---------------------------- //! Get a map item of this context bool TDB_Api::ReadNextMapItem( TDB_Api_MapID &mID, bool aFirst ) { MapID_Struct u; mID.localID.DisposeStr(); mID.remoteID.DisposeStr(); RdNMap_Func p= (RdNMap_Func)dm->ds.dsAdm.map.ReadNextMapItem; bool ok= p( fContext, &u, aFirst ); if (ok) { mID.localID.fStr = u.localID; AssignStr( mID.localID ); mID.remoteID.fStr= u.remoteID; AssignStr( mID.remoteID ); mID.flags = u.flags; mID.ident = u.ident; } // if return ok; } // ReadNextMapItem // Insert a map item of this context TSyError TDB_Api::InsertMapItem( MapID mID ) { InsMap_Func p= (InsMap_Func)dm->ds.dsAdm.map.InsertMapItem; return p( fContext, mID ); } // InsertMapItem // Update a map item of this context TSyError TDB_Api::UpdateMapItem( MapID mID ) { UpdMap_Func p= (UpdMap_Func)dm->ds.dsAdm.map.UpdateMapItem; return p( fContext, mID ); } // UpdateMapItem // Delete a map item of this context TSyError TDB_Api::DeleteMapItem( MapID mID ) { DelMap_Func p= (DelMap_Func)dm->ds.dsAdm.map.DeleteMapItem; return p( fContext, mID ); } // DeleteMapItem // --- general ----------------------------------------- void TDB_Api::ThreadMayChangeNow() { VoidProc p= (VoidProc)dm->ds.dsg.ThreadMayChangeNow; p( fContext ); } // ThreadMayChangeNow //! This functions gets the for this datastore void TDB_Api::WriteLogData( cAppCharP logData ) { SvInfo_Func p= (SvInfo_Func)dm->ds.dsg.WriteLogData; p( fContext, logData ); } // WriteLogData void TDB_Api::DispItems( bool allFields, cAppCharP specificItem ) { DispProc p= (DispProc)dm->ds.dsg.DispItems; p( fContext, allFields, specificItem ); } // DispItems void TDB_Api::AssignChanged( string &a, TDB_Api_Str &u ) { if (a.c_str()!=u.fStr) { a= u.fStr; AssignStr( u ); } // assign for destruction afterwards } // AssignChanged TSyError TDB_Api::AdaptItem( string &sItemData1, string &sItemData2, string &sLocalVars, uInt32 sIdentifier ) { TDB_Api_Str updItemData1( sItemData1 ); TDB_Api_Str updItemData2( sItemData2 ); TDB_Api_Str updLocalVars( sLocalVars ); Adapt_Func p= (Adapt_Func)dm->ds.dsAdapt.AdaptItem; TSyError err= p( fContext, &updItemData1.fStr, &updItemData2.fStr, &updLocalVars.fStr, sIdentifier ); AssignChanged( sItemData1, updItemData1 ); AssignChanged( sItemData2, updItemData2 ); AssignChanged( sLocalVars, updLocalVars ); return err; } // AdaptItem // --- read section ------------------------------------ TSyError TDB_Api::StartDataRead( cAppCharP lastToken, cAppCharP resumeToken ) { typedef TSyError (*OLD_SDR_Func)( CContext aContext, cAppCharP lastToken ); if (!fCreated) return DB_Fatal; // is not defined, if not created // new param supported for Plugin Version >= 1.0.6.X if (fConfig->Supported( VP_ResumeToken )) { SDR_Func p= (SDR_Func)dm->ds.dsData.StartDataRead; return p( fContext, lastToken,resumeToken ); } else { OLD_SDR_Func p= (OLD_SDR_Func)dm->ds.dsData.StartDataRead; return p( fContext, lastToken ); } // if } // StartDataRead // overloaded for using DB:Api_ItemID class TSyError TDB_Api::ReadNextItem( TDB_Api_ItemID &aID, TDB_Api_Str &aItemData, int &aStatus, bool aFirst ) { ItemID_Struct u; sInt32 lStatus; aID.item.DisposeStr(); aID.parent.DisposeStr(); aItemData.DisposeStr(); u.parent= NULL; // works correctly, even if not implemented on user side RdNItemSFunc p= (RdNItemSFunc)dm->ds.dsData.str.ReadNextItem; TSyError err= p( fContext, &u, &aItemData.fStr, &lStatus, aFirst ); aStatus= (int)lStatus; if (err || aStatus==ReadNextItem_EOF) return err; aID.item.fStr = u.item; AssignStr( aID.item ); aID.parent.fStr= u.parent; AssignStr( aID.parent ); AssignStr( aItemData ); // additional info for test //DEBUG_Exotic_DB( fCB, aID.item.c_str(), "ReadNextItem", aItemData.c_str() ); return LOCERR_OK; } // ReadNextItem // overloaded for mode w/o aParentID TSyError TDB_Api::ReadNextItem( TDB_Api_Str &aItemID, TDB_Api_Str &aItemData, int &aStatus, bool aFirst ) { TDB_Api_ItemID aID; TSyError err= ReadNextItem( aID, aItemData, aStatus, aFirst ); if (err || aStatus==ReadNextItem_EOF) return err; GetItemID ( aID, aItemID ); return LOCERR_OK; } // ReadNextItem TSyError TDB_Api::ReadNextItemAsKey( TDB_Api_ItemID &aID, KeyH aItemKey, int &aStatus, bool aFirst ) { ItemID_Struct u; sInt32 lStatus; aID.item.DisposeStr(); aID.parent.DisposeStr(); u.parent= NULL; // works correctly, even if not implemented on user side RdNItemKFunc p= (RdNItemKFunc)dm->ds.dsData.key.ReadNextItemAsKey; TSyError err= p( fContext, &u, aItemKey, &lStatus, aFirst ); aStatus= (int) lStatus; if (err || aStatus==ReadNextItem_EOF) return err; aID.item.fStr = u.item; AssignStr( aID.item ); aID.parent.fStr= u.parent; AssignStr( aID.parent ); return LOCERR_OK; } // ReadNextItemAsKey // overloaded for using ItemID_Struct TSyError TDB_Api::ReadItem( ItemID_Struct aID, TDB_Api_Str &aItemData ) { aItemData.DisposeStr(); Rd_ItemSFunc p= (Rd_ItemSFunc)dm->ds.dsData.str.ReadItem; TSyError err= p( fContext, &aID, &aItemData.fStr ); if (!err) AssignStr ( aItemData ); return err; } // ReadItem // overloaded for , call TSyError TDB_Api::ReadItem( cAppCharP aItemID, cAppCharP aParentID, TDB_Api_Str &aItemData ) { ItemID_Struct a; a.item = (char*) aItemID; a.parent= (char*)aParentID; return ReadItem( a, aItemData ); } // ReadItem // overloaded for mode w/o aParentID TSyError TDB_Api::ReadItem( cAppCharP aItemID, TDB_Api_Str &aItemData ) { return ReadItem( aItemID,"", aItemData ); } // ReadItem TSyError TDB_Api::ReadItemAsKey( ItemID_Struct aID, KeyH aItemKey ) { Rd_ItemKFunc p= (Rd_ItemKFunc)dm->ds.dsData.key.ReadItemAsKey; TSyError err= p( fContext, &aID, aItemKey ); return err; } // ReadItemAsKey // overloaded for using ItemID_Struct TSyError TDB_Api::ReadBlob( ItemID_Struct aID, cAppCharP aBlobID, memSize blkSize, TDB_Api_Blk &aBlk, memSize &totSize, bool aFirst, bool &aLast ) { typedef TSyError (*Rd_Blob_Func)( CContext aContext, cItemID aID, cAppCharP aBlobID, appPointer *blkPtr, memSize *blkSize, memSize *totSize, bool aFirst, bool *aLast ); aBlk.DisposeBlk(); aBlk.fSize= blkSize; Rd_Blob_Func p= (Rd_Blob_Func)dm->ds.dsBlob.ReadBlob; TSyError err= p( fContext, &aID,aBlobID, &aBlk.fPtr,&aBlk.fSize, &totSize, aFirst,&aLast ); if (!err) aBlk.AssignBlk( fContext, (DisposeProc)dm->ds.DisposeObj ); return err; } // ReadBlob // overloaded for , call TSyError TDB_Api::ReadBlob( cAppCharP aItemID, cAppCharP aParentID, cAppCharP aBlobID, memSize blkSize, TDB_Api_Blk &aBlk, memSize &totSize, bool aFirst, bool &aLast ) { ItemID_Struct a; a.item = (char*)aItemID; a.parent= (char*)aParentID; return ReadBlob( a, aBlobID, blkSize,aBlk,totSize, aFirst,aLast ); } // ReadBlob // overloaded for mode w/o aParentID TSyError TDB_Api::ReadBlob( cAppCharP aItemID, cAppCharP aBlobID, memSize blkSize, TDB_Api_Blk &aBlk, memSize &totSize, bool aFirst, bool &aLast ) { return ReadBlob( aItemID,"", aBlobID, blkSize,aBlk,totSize, aFirst,aLast ); } // ReadBlob TSyError TDB_Api::EndDataRead() { EDR_Func p= (EDR_Func)dm->ds.dsData.EndDataRead; return p( fContext ); } // EndDataRead // --- write section ---------------------------------------------------------------------- TSyError TDB_Api::StartDataWrite() { SDW_Func p= (SDW_Func)dm->ds.dsData.StartDataWrite; return p( fContext ); } // StartDataWrite // Assign to , ignore new parent void TDB_Api::Assign_ItemID( TDB_Api_ItemID &newID, ItemID_Struct &a, cAppCharP parentID ) { newID.item.fStr= a.item; AssignStr ( newID.item ); if (a.parent!=parentID) { // remove it, if explicitely allocated newID.parent.fStr= a.parent; // parent can't be changed !! AssignStr( newID.parent ); newID.parent.DisposeStr(); } // if newID.parent.LocalAlloc( fContext, parentID ); } // Assign_ItemID // ------------------------------------------------------------------------- // overloaded for call TSyError TDB_Api::InsertItem( cAppCharP aItemData, cAppCharP parentID, TDB_Api_ItemID &newID ) { newID.item.DisposeStr(); newID.parent.DisposeStr(); ItemID_Struct a; a.item = NULL; a.parent= (char*)parentID; // works correctly, even if not implemented on user side InsItemSFunc p= (InsItemSFunc)dm->ds.dsData.str.InsertItem; TSyError err= p( fContext, aItemData, &a ); if (!err || err==DB_DataMerged || err==DB_DataReplaced || err==DB_Conflict) { Assign_ItemID( newID, a, parentID ); } // if return err; } // InsertItem // overloaded for mode w/o aParentID TSyError TDB_Api::InsertItem( cAppCharP aItemData, TDB_Api_Str &newItemID ) { TDB_Api_ItemID nID; TSyError err= InsertItem( aItemData, "",nID ); if (!err || err==DB_DataMerged || err==DB_DataReplaced || err==DB_Conflict) { GetItemID( nID, newItemID ); } // if return err; } // InsertItem TSyError TDB_Api::InsertItemAsKey( KeyH aItemKey, cAppCharP parentID, TDB_Api_ItemID &newID ) { newID.item.DisposeStr(); newID.parent.DisposeStr(); ItemID_Struct a; a.item = NULL; a.parent= (char*)parentID; // works correctly, even if not implemented on user side InsItemKFunc p= (InsItemKFunc)dm->ds.dsData.key.InsertItemAsKey; TSyError err= p( fContext, aItemKey, &a ); if (!err || err==DB_DataMerged || err==DB_DataReplaced || err==DB_Conflict) { Assign_ItemID( newID, a, parentID ); } // if return err; } // InsertItemAsKey // ------------------------------------------------------------------------- // overloaded for using ItemID_Struct TSyError TDB_Api::UpdateItem( cAppCharP aItemData, ItemID_Struct aID, TDB_Api_ItemID &updID ) { updID.item.DisposeStr(); updID.parent.DisposeStr(); ItemID_Struct u; u.item = NULL; u.parent= (char*)aID.parent; // works correctly, even if not implemented on user side UpdItemSFunc p= (UpdItemSFunc)dm->ds.dsData.str.UpdateItem; TSyError err= p( fContext, aItemData, &aID,&u ); if (!err) { Assign_ItemID( updID, u, aID.parent ); } // if return err; } // UpdateItem // overloaded for , call TSyError TDB_Api::UpdateItem( cAppCharP aItemData, cAppCharP aItemID, cAppCharP aParentID, TDB_Api_ItemID &updID ) { ItemID_Struct a; a.item = (char*)aItemID; a.parent= (char*)aParentID; return UpdateItem( aItemData, a,updID ); } // UpdateItem // overloaded for mode w/o aParentID TSyError TDB_Api::UpdateItem( cAppCharP aItemData, cAppCharP aItemID, TDB_Api_Str &updItemID ) { TDB_Api_ItemID uID; TSyError err= UpdateItem( aItemData, aItemID,"", uID ); if (!err) GetItemID( uID, updItemID ); return err; } // UpdateItem TSyError TDB_Api::UpdateItem( cAppCharP aItemData, TDB_Api_ItemID &aID, TDB_Api_ItemID &updID ) { return UpdateItem( aItemData, (char*)aID.item.c_str(), (char*)aID.parent.c_str(), updID ); } // UpdateItem TSyError TDB_Api::UpdateItemAsKey( KeyH aItemKey, ItemID_Struct aID, TDB_Api_ItemID &updID ) { updID.item.DisposeStr(); updID.parent.DisposeStr(); ItemID_Struct u; u.item = NULL; u.parent= (char*)aID.parent; // works correctly, even if not implemented on user side UpdItemKFunc p= (UpdItemKFunc)dm->ds.dsData.key.UpdateItemAsKey; TSyError err= p( fContext, aItemKey, &aID,&u ); if (!err) { Assign_ItemID( updID, u, aID.parent ); } // if return err; } // UpdateItemAsKey TSyError TDB_Api::UpdateItemAsKey( KeyH aItemKey, TDB_Api_ItemID &aID, TDB_Api_ItemID &updID ) { ItemID_Struct a; a.item = (char*)aID.item.c_str(); a.parent= (char*)aID.parent.c_str(); return UpdateItemAsKey( aItemKey, a, updID ); } // UpdateItemAsKey // ------------------------------------------------------------------------- // overloaded for using ItemID_Struct TSyError TDB_Api::MoveItem( ItemID_Struct aID, cAppCharP newParID ) { MovItem_Func p= (MovItem_Func)dm->ds.dsData.ind.MoveItem; return p( fContext, &aID,newParID ); } // MoveItem // overloaded for , call TSyError TDB_Api::MoveItem( cAppCharP aItemID, cAppCharP aParentID, cAppCharP newParID ) { ItemID_Struct a; a.item = (appCharP) aItemID; a.parent= (appCharP)aParentID; return MoveItem( a, newParID ); } // MoveItem // ------------------------------------------------------------------------- // overloaded for using ItemID_Struct TSyError TDB_Api::DeleteItem( ItemID_Struct aID ) { DelItem_Func p= (DelItem_Func)dm->ds.dsData.ind.DeleteItem; return p( fContext, &aID ); } // DeleteItem // overloaded for , call TSyError TDB_Api::DeleteItem( cAppCharP aItemID, cAppCharP aParentID ) { ItemID_Struct a; a.item = (char*)aItemID; a.parent= (char*)aParentID; return DeleteItem( a ); } // DeleteItem // overloaded for using TDB_Api_ItemID // object will not be removed here TSyError TDB_Api::DeleteItem( TDB_Api_ItemID &aID ) { return DeleteItem( (char*)aID.item.c_str(), (char*)aID.parent.c_str() ); } // DeleteItem // ------------------------------------------------------------------------- TSyError TDB_Api::FinalizeLocalID( ItemID_Struct aID, TDB_Api_ItemID &updID ) { updID.item.DisposeStr(); updID.parent.DisposeStr(); if (!fConfig->Supported( VP_FLI_DSS )) return LOCERR_NOTIMP; ItemID_Struct u; u.item = NULL; u.parent= (char*)aID.parent; // works correctly, even if not implemented on user side FLI_Func p= (FLI_Func)dm->ds.dsData.ind.FinalizeLocalID; TSyError err= p( fContext, &aID,&u ); if (!err) { Assign_ItemID( updID, u, aID.parent ); } // if return err; } // FinalizeLocalID TSyError TDB_Api::FinalizeLocalID( TDB_Api_ItemID &aID, TDB_Api_ItemID &updID ) { return FinalizeLocalID( (char*)aID.item.c_str(), (char*)aID.parent.c_str(), updID ); } // FinalizeLocalID TSyError TDB_Api::FinalizeLocalID( cAppCharP aItemID, TDB_Api_Str &updItemID ) { TDB_Api_ItemID uID; TSyError err= FinalizeLocalID( aItemID,"", uID ); if (!err) GetItemID( uID, updItemID ); return err; } // FinalizeLocalID TSyError TDB_Api::FinalizeLocalID( cAppCharP aItemID, cAppCharP aParentID, TDB_Api_ItemID &updID ) { ItemID_Struct a; a.item = (char*)aItemID; a.parent= (char*)aParentID; return FinalizeLocalID( a, updID ); } // FinalizeLocalID TSyError TDB_Api::DeleteSyncSet() { if (!fConfig->Supported( VP_FLI_DSS )) return LOCERR_NOTIMP; DelSS_Func p= (DelSS_Func)dm->ds.dsData.ind.DeleteSyncSet; return p( fContext ); } // DeleteSyncSet // ------------------------------------------------------------------------- // overloaded for using ItemID_Struct TSyError TDB_Api::WriteBlob( ItemID_Struct aID, cAppCharP aBlobID, appPointer blkPtr, memSize blkSize, memSize totSize, bool aFirst, bool aLast ) { typedef TSyError (*Wr_BlobFunc)( CContext aContext, cItemID aID, cAppCharP aBlobID, appPointer blkPtr, memSize blkSize, memSize totSize, bool aFirst, bool aLast ); Wr_BlobFunc p= (Wr_BlobFunc)dm->ds.dsBlob.WriteBlob; return p( fContext, &aID,aBlobID, blkPtr,blkSize,totSize, aFirst,aLast ); } // WriteBlob // overloaded for mode with and TSyError TDB_Api::WriteBlob( cAppCharP aItemID, cAppCharP aParentID, cAppCharP aBlobID, appPointer blkPtr, memSize blkSize, memSize totSize, bool aFirst, bool aLast ) { ItemID_Struct a; a.item = (char*)aItemID; a.parent= (char*)aParentID; return WriteBlob( a,aBlobID, blkPtr,blkSize,totSize, aFirst,aLast ); } // WriteBlob // overloaded for mode w/o TSyError TDB_Api::WriteBlob( cAppCharP aItemID, cAppCharP aBlobID, appPointer blkPtr, memSize blkSize, memSize totSize, bool aFirst, bool aLast ) { return WriteBlob( aItemID,"", aBlobID, blkPtr,blkSize,totSize, aFirst,aLast ); } // WriteBlob // overloaded for using TDB_Api_ItemID TSyError TDB_Api::WriteBlob( TDB_Api_ItemID &aID, cAppCharP aBlobID, appPointer blkPtr, memSize blkSize, memSize totSize, bool aFirst, bool aLast ) { return WriteBlob( (char*)aID.item.c_str(), (char*)aID.parent.c_str(), aBlobID, blkPtr,blkSize,totSize, aFirst,aLast ); } // WriteBlob // ------------------------------------------------------------------------- // overloaded for using ItemID_Struct TSyError TDB_Api::DeleteBlob( ItemID_Struct aID, cAppCharP aBlobID ) { typedef TSyError (*DelBlobFunc)( CContext aContext, cItemID aID, cAppCharP aBlobID ); DelBlobFunc p= (DelBlobFunc)dm->ds.dsBlob.DeleteBlob; return p( fContext, &aID,aBlobID ); } // DeleteBlob // overloaded for mode with and TSyError TDB_Api::DeleteBlob( cAppCharP aItemID, cAppCharP aParentID, cAppCharP aBlobID ) { ItemID_Struct a; a.item = (char*)aItemID; a.parent= (char*)aParentID; return DeleteBlob( a,aBlobID ); } // DeleteBlob // overloaded for mode w/o TSyError TDB_Api::DeleteBlob( cAppCharP aItemID, cAppCharP aBlobID ) { return DeleteBlob( aItemID,"", aBlobID ); } // DeleteBlob // overloaded for using TDB_Api_ItemID TSyError TDB_Api::DeleteBlob( TDB_Api_ItemID &aID, cAppCharP aBlobID ) { return DeleteBlob( (char*)aID.item.c_str(), (char*)aID.parent.c_str(), aBlobID ); } // DeleteBlob // ------------------------------------------------------------------------- TSyError TDB_Api::EndDataWrite( bool success, TDB_Api_Str &newToken ) { newToken.DisposeStr(); EDW_Func p= (EDW_Func)dm->ds.dsData.EndDataWrite; TSyError err= p( fContext, success, &newToken.fStr ); if (!err) { AssignStr( newToken ); if (!success) err= DB_Fatal; } // if return err; } // EndDataWrite // --- close section -------------------------------- TSyError TDB_Api::DeleteContext() { if (!fCreated) return DB_Forbidden; // remove all still allocated elements before removing the content while (!fSList.empty()) DisposeStr( *fSList.front() ); while (!fBList.empty()) DisposeBlk( *fBList.front() ); Context_Func p= (Context_Func)dm->ds.DeleteContext; TSyError err= p( fContext ); if (!err) fCreated= false; return err; } // DeleteContext } // namespace /* eof */ libsynthesis-3.4.0.47.1/src/DB_interfaces/api_db/dbapi.h000077500000000000000000000553711226375725500226070ustar00rootroot00000000000000/* * File: dbapi.h * * Author: Beat Forster (bfo@synthesis.ch) * * TDB_Api class * Bridge to user programmable interface * * Copyright (c) 2004-2011 by Synthesis AG + plan44.ch * * The "TDB_Api" class acts as a standard interface between * the SySync Server and a (user programmable) module "sync_dbapi". * * It is possible to have more than one (identical) interface module, * either packed into a DLL or directly linked to the server * (or combined). * * - In case of DLL, the object must be created with * = DLL file name, e.g "sync_dbapi.dll" * The constructor automatically creates the connection to the DLL, * the destructor releases the DLL. * * - In case of the directly linked module, it runs in a * specific namespace, which can be assigned by calling * = '['']', e.g. "[example1]". * (Of course an internal implementation for each namespace must * exist!) * * NOTE: The public method names are identical to the ones of the * user interface, but not all parameters are visible on the * object side, e.g. the context variable is held private * within the object. * The methods will be assigned internally (at API_Methods), * when the object is created. */ #ifndef DB_API_H #define DB_API_H // access to the definitions of the interface #include #include #include "sync_dbapiconnect.h" #include "sync_dbapidef.h" namespace sysync { /* -- Utility procs -- */ bool DSConnect( cAppCharP aItem ); /* -- handling for "sync_dbapi" returned strings -- */ class TDB_Api_Str { friend class TDB_Api_Config; friend class TDB_Api_Session; friend class TDB_Api; public: TDB_Api_Str(); // constructor TDB_Api_Str( string &s ); // alternative constructor ~TDB_Api_Str(); // destructor // the string reference cAppCharP c_str() const { return (fStr==NULL) ? "":fStr; } bool empty(void) { return *c_str()==0; } int length() const { return sizeof( c_str() ); }; // has the same effect as the destructor, but can be called earlier void DisposeStr(); private: void AssignStr ( CContext aContext, DisposeProc aDisposeProc, bool itself= false ); void LocalAlloc( CContext aContext, cAppCharP ); // if memory must be allocated locally CContext fContext; char* fStr; bool fItself; // if true: Dispose instead of DisposeProc fDisposeProc; void clear() { fDisposeProc= NULL; fStr= NULL; } }; // TDB_Api_Str /* -- handling for "sync_dbapi" returned itemID/parentID strings */ class TDB_Api_ItemID { public: TDB_Api_Str item; TDB_Api_Str parent; }; // TDB_Api_ItemID class TDB_Api_MapID { public: TDB_Api_Str localID; TDB_Api_Str remoteID; uInt16 flags; uInt8 ident; }; // TDB_Api_MapID /* -- handling for "sync_dbapi" returned blocks */ class TDB_Api_Blk { friend class TDB_Api_Config; friend class TDB_Api; public: TDB_Api_Blk(); // constructor ~TDB_Api_Blk(); // destructor appPointer fPtr; // the block reference memSize fSize; // the block size void DisposeBlk(); // has the same effect as the destructor, but can be called earlier protected: void AssignBlk( CContext aContext, DisposeProc aDisposeProc, bool itself= false ); private: CContext fContext; bool fItself; // if true: Dispose instead of DisposeProc fDisposeProc; void clear() { fDisposeProc= NULL; fPtr= NULL; fSize= 0; } }; // TDB_Api_Blk // -- internally used type definitions --------- typedef TSyError (*CreateM_Func)( CContext *mc, cAppCharP moduleName, cAppCharP subName, cAppCharP mContextName, DB_Callback mCB ); typedef CVersion (*Version_Func)( CContext mc ); typedef TSyError (*Context_Func)( CContext mc ); // --------------------------------------------- typedef TSyError (*CreateS_Func)( CContext *sc, cAppCharP sessionName, DB_Callback sCB ); typedef TSyError (*SvInfo_Func)( CContext sc, cAppCharP info ); typedef int (*PwMode_Func)( CContext sc ); typedef TSyError (*Login_Func)( CContext sc, cAppCharP sUsername, appCharP *sPassword, appCharP *sUsrKey ); // --------------------------------------------- typedef TSyError (*CreateD_Func)( CContext *ac, cAppCharP aContextName, DB_Callback aCB, cAppCharP sDevKey, cAppCharP sUsrKey ); typedef int (*Text_Func)( CContext ac, cAppCharP aText ); typedef void (*DispProc)( CContext ac, bool allFields, cAppCharP specificItem ); typedef TSyError (*LoadAdm_SFunc)( CContext ac, cAppCharP aLocDB, cAppCharP aRemDB, appCharP *adminData ); typedef TSyError (*LoadAdm_KFunc)( CContext ac, cAppCharP aLocDB, cAppCharP aRemDB, KeyH adminKey ); typedef TSyError (*SaveAdm_SFunc)( CContext sc, cAppCharP info ); typedef TSyError (*SaveAdm_KFunc)( CContext ac, KeyH adminKey ); typedef bool (*RdNMap_Func)( CContext ac, MapID mID, bool aFirst ); typedef TSyError (*InsMap_Func)( CContext ac, cMapID mID ); typedef TSyError (*UpdMap_Func)( CContext ac, cMapID mID ); typedef TSyError (*DelMap_Func)( CContext ac, cMapID mID ); typedef void (*VoidProc)( CContext ac ); typedef TSyError (*Adapt_Func)( CContext ac, appCharP *aItemData1, appCharP *aItemData2, appCharP *aLocalVars, sInt32 aIdentifier ); // --------------------------------------------- // wrapper for DB_Callback class TDB_Api_Callback { public: TDB_Api_Callback(); SDK_Interface_Struct Callback; }; // TDB_Api_Callback // the module context class class TDB_Api_Config { friend class TDB_Api_Session; friend class TDB_Api; friend class TUI_Api; public: TDB_Api_Config(); // constructor ~TDB_Api_Config(); // destructor // Connect to the plug-in with // must be 0 before called the first time TSyError Connect( cAppCharP moduleName, CContext &globContext, cAppCharP mContextName= "", bool aIsLib= false, bool allowDLL= true ); bool Connected() { return fConnected; } // read status of // The plug-in module's version, capabilities and plugin params from config file long Version(); // the plugin's SDK version number long EngineSDKVersion(); // the internal engine's SDK version number TSyError Capabilities( TDB_Api_Str &mCapabilities ); TSyError PluginParams( cAppCharP mConfigParams ); // Change the internal engine's SDK version; // *** override the version number / for test only *** void SetVersion( long versionNr ); /* Check the minimum required version */ TSyError MinVersionCheck( string capa, CVersion &vMin ); // Check, if MINVERSION is high enough // Disconnect the module(at the end TSyError Disconnect(); bool is_lib; // flag: as internal library TDB_Api_Callback fCB; // Callback wrapper cAppCharP ModName() { return fModName.c_str(); } // the cAppCharP ModOptions() { return fOptions.c_str(); } // the module's parameters cAppCharP ModPlugin() { return fPlugin.c_str(); } // the main module's name cAppCharP ModMainName() { return fModMain.c_str(); } // the main module's name (with optional extension ":..." cAppCharP ModSubName() { return fModSub.c_str(); } // the sub module's name (with params) void DisposeStr( TDB_Api_Str &s ); private: void AssignStr( TDB_Api_Str &s ); // for internal use void clear(); bool Supported( CVersion version_feature ); // Check, if is supported // Internal Api assignment TSyError DBApi_Assign( cAppCharP item, appPointer aField, memSize aFieldSize, cAppCharP aKey= "" ); CContext mContext; // the module's context API_Methods m; // set of Lib/DLL routines string fModName; // local copy of string fOptions; // local copy of module's paramters string fPlugin; // main part of w/o brackets w/o extension string fModMain; // main part of w/o brackets, with optional extension string fModSub; // sub part of w/o brackets string fDesc; // module's description bool fConnected; // if successful= API_Methods valid bool fADMIN_Info; // ADMIN info will be given with "CreateContext" CVersion fSDKversion; // The SDK's version (directly connected module) CVersion fMODversion; // The SDK's version (lowest of the chain) CVersion fTSTversion; // Modified version (*** for test only ***) appPointer fMod; // internal module reference list fSList; // list of currently allocated str objects of this session }; // class TDB_Api_Config // Display global context contents void DispGlobContext ( CContext &globContext, DB_Callback mCB ); // Delete the global context at the end void DeleteGlobContext( CContext &globContext, DB_Callback mCB, bool emptyTextOnly= false ); // the session context class class TDB_Api_Session { public: TDB_Api_Session(); // constructor TSyError CreateContext ( cAppCharP sessionName, TDB_Api_Config &config ); TSyError CheckDevice ( cAppCharP deviceID, TDB_Api_Str &sDevKey, TDB_Api_Str &nonce ); TSyError GetNonce ( TDB_Api_Str &nonce ); TSyError SaveNonce ( cAppCharP nonce ); TSyError SaveDeviceInfo( cAppCharP aDeviceInfo ); TSyError GetDBTime ( TDB_Api_Str ¤tDBTime ); #ifdef SYSYNC_ENGINE TSyError GetDBTime ( lineartime_t ¤tDBTime, GZones* g ); #endif sInt32 PasswordMode(); TSyError Login( cAppCharP sUsername, cAppCharP sPassword, TDB_Api_Str &sUsrKey ); // for password mode 0+3 TSyError Login( cAppCharP sUsername, TDB_Api_Str &sPassword, TDB_Api_Str &sUsrKey ); // for password mode 1+2 TSyError Logout(); TSyError AdaptItem( string &sItemData1, string &sItemData2, string &sLocalVars, uInt32 sIdentifier ); void ThreadMayChangeNow(); // notification for the context void DispItems( bool allFields= true, cAppCharP specificItem= "" ); // by default: all TSyError DeleteContext(); TDB_Api_Callback fCB; // Callback wrapper bool sCreated; CContext sContext; // the session context void DisposeStr( TDB_Api_Str &s ); private: void AssignStr ( TDB_Api_Str &s ); // for internal use void AssignChanged ( string &a, TDB_Api_Str &u ); API_Methods* dm; // local reference to the API methods API_Methods sNo_dbapi; // default connection for call methods string sSessionName; // local copy of sInt32 sPwMode; // local copy of password mode list fSList; // list of currently allocated str objects of this session }; // class TDB_Api_Session // for detailed description of the methods see // C interface definition at "sync_dbapi.h" // An object for each context must be created. // It is not possible to create more than one context per object // It is allowed to bind more than one context to the same module. class TDB_Api { public: TDB_Api(); // constructor ~TDB_Api(); // destructor // --- open section -------------------------------- //! Open a context, it is possible to do this w/o any session TSyError CreateContext( cAppCharP aContextName, bool asAdmin, TDB_Api_Config* config, cAppCharP sDevKey= "", cAppCharP sUsrKey= "", TDB_Api_Session* session= NULL ); /*! Gets true after calling 'CreateContext'. * Will return again false after 'DeleteContext' */ bool Created() { return fCreated; }; //! run a sequence: CreateContext -> StartDataRead -> sequence -> EndDataWrite -> DeleteContext //! as input: the token of the last session, "" if the first time. //! " as output: the new token, which must be given to the next session. typedef TSyError(*SequenceProc)( TDB_Api &dbApi ); TSyError RunContext( cAppCharP aContextName, bool asAdmin, SequenceProc sequence, string &token, TDB_Api_Config* config, cAppCharP sDevKey= "", cAppCharP sUsrKey= "", TDB_Api_Session* session= NULL ); //! returns the nth config data field, which is supported (and activated) //! result= 0: no filter supported. uInt32 ContextSupport( cAppCharP aContextRules ); //! returns the nth filter rule, which is supported (and activated) //! result= 0: no filter supported. uInt32 FilterSupport( cAppCharP aFilterRules ); // --- admin section ------------------------------- //! This function gets the stored information about the record with the four paramters: //! , (taken from the session context) //! , . //! And the same for AsKey (will be activated with ADMIN_AS_KEY) TSyError LoadAdminData ( cAppCharP aLocDB, cAppCharP aRemDB, TDB_Api_Str &adminData ); TSyError LoadAdminDataAsKey( cAppCharP aLocDB, cAppCharP aRemDB, KeyH adminKey ); //! This functions stores the new for this context //! And the same for AsKey (will be activated with ADMIN_AS_KEY) TSyError SaveAdminData ( cAppCharP adminData ); TSyError SaveAdminData_AsKey( KeyH adminKey ); // --- Map table handling //! Get a map item of this context bool ReadNextMapItem( TDB_Api_MapID &mID, bool aFirst= false ); //! Insert a map item of this context TSyError InsertMapItem( MapID mID ); //! Update a map item of this context TSyError UpdateMapItem( MapID mID ); //! Delete a map item of this context TSyError DeleteMapItem( MapID mID ); // --- utility section ----------------------------- //! Get the current context value CContext MyContext() { return fContext; } //! Notification for the context void ThreadMayChangeNow(); //! Write log information for the datastore access void WriteLogData( cAppCharP logData ); //! Display the current items (not used by the engine) void DispItems( bool allFields= true, cAppCharP specificItem= "" ); // by default: all //! Adapt ,, of script context, with TSyError AdaptItem( string &aItemData1, string &aItemData2, string &aLocalVars, uInt32 aIdentifier ); // --- read section -------------------------------- TSyError StartDataRead( cAppCharP lastToken, cAppCharP resumeToken= "" ); // / and will automatically be disposed at the beginning // 2 overloaded versions TSyError ReadNextItem ( TDB_Api_ItemID &aID, TDB_Api_Str &aItemData, int &aStatus, bool aFirst= false ); TSyError ReadNextItem ( TDB_Api_Str &aItemID, TDB_Api_Str &aItemData, int &aStatus, bool aFirst= false ); TSyError ReadNextItemAsKey( TDB_Api_ItemID &aID, KeyH aItemKey, int &aStatus, bool aFirst= false ); // will automatically be disposed at the beginning // 3 overloaded versions TSyError ReadItem ( ItemID_Struct aID, TDB_Api_Str &aItemData ); TSyError ReadItem ( cAppCharP aItemID, TDB_Api_Str &aItemData ); TSyError ReadItem ( cAppCharP aItemID, cAppCharP aParentID, TDB_Api_Str &aItemData ); TSyError ReadItemAsKey( ItemID_Struct aID, KeyH aItemKey ); // will automatically be disposed at the beginning // 3 overloaded versions TSyError ReadBlob( ItemID_Struct aID, cAppCharP aBlobID, memSize blkSize, TDB_Api_Blk &aBlk, memSize &totSize, bool aFirst, bool &aLast ); TSyError ReadBlob( cAppCharP aItemID, cAppCharP aBlobID, memSize blkSize, TDB_Api_Blk &aBlk, memSize &totSize, bool aFirst, bool &aLast ); TSyError ReadBlob( cAppCharP aItemID, cAppCharP aParentID, cAppCharP aBlobID, memSize blkSize, TDB_Api_Blk &aBlk, memSize &totSize, bool aFirst, bool &aLast ); TSyError EndDataRead(); // --- write section -------------------------------- TSyError StartDataWrite(); // will automatically be disposed at the beginning. // 2 overloaded versions TSyError InsertItem ( cAppCharP aItemData, cAppCharP parentID, TDB_Api_ItemID &newID ); TSyError InsertItem ( cAppCharP aItemData, TDB_Api_Str &newItemID ); TSyError InsertItemAsKey( KeyH aItemKey, cAppCharP parentID, TDB_Api_ItemID &newID ); TSyError FinalizeLocalID( ItemID_Struct aID, TDB_Api_ItemID &updID ); TSyError FinalizeLocalID( TDB_Api_ItemID &aID, TDB_Api_ItemID &updID );// obj will not be removed here TSyError FinalizeLocalID( cAppCharP aItemID, TDB_Api_Str &updItemID ); TSyError FinalizeLocalID( cAppCharP aItemID, cAppCharP aParentID, TDB_Api_ItemID &updID ); // will automatically be disposed at the beginning. // 4 overloaded versions TSyError UpdateItem( cAppCharP aItemData, ItemID_Struct aID, TDB_Api_ItemID &updID ); TSyError UpdateItem( cAppCharP aItemData, TDB_Api_ItemID &aID, TDB_Api_ItemID &updID ); // obj will not be removed here TSyError UpdateItem( cAppCharP aItemData, cAppCharP aItemID, TDB_Api_Str &updItemID ); TSyError UpdateItem( cAppCharP aItemData, cAppCharP aItemID, cAppCharP aParentID, TDB_Api_ItemID &updID ); TSyError UpdateItemAsKey( KeyH aItemKey, ItemID_Struct aID, TDB_Api_ItemID &updID ); TSyError UpdateItemAsKey( KeyH aItemKey, TDB_Api_ItemID &aID, TDB_Api_ItemID &updID ); // obj will not be removed here // 2 overloaded versions TSyError MoveItem ( ItemID_Struct aID, cAppCharP newParID ); TSyError MoveItem ( cAppCharP aItemID, cAppCharP aParentID, cAppCharP newParID ); // 3 overloaded versions TSyError DeleteItem( ItemID_Struct aID ); TSyError DeleteItem( cAppCharP aItemID, cAppCharP parentID="" ); TSyError DeleteItem( TDB_Api_ItemID &aID ); // obj will not be removed here TSyError DeleteSyncSet(); // , and can be omitted, their default values are 0,true,true // 4 overloaded versions TSyError WriteBlob ( ItemID_Struct aID, cAppCharP aBlobID, appPointer blkPtr, memSize blkSize, memSize totSize= 0, bool aFirst= true, bool aLast= true ); TSyError WriteBlob ( cAppCharP aItemID, cAppCharP aBlobID, appPointer blkPtr, memSize blkSize, memSize totSize= 0, bool aFirst= true, bool aLast= true ); TSyError WriteBlob ( cAppCharP aItemID, cAppCharP aParentID, cAppCharP aBlobID, appPointer blkPtr, memSize blkSize, memSize totSize= 0, bool aFirst= true, bool aLast= true ); TSyError WriteBlob ( TDB_Api_ItemID &aID, cAppCharP aBlobID, // obj will not be removed here appPointer blkPtr, memSize blkSize, memSize totSize= 0, bool aFirst= true, bool aLast= true ); // 4 overloaded versions TSyError DeleteBlob( ItemID_Struct aID, cAppCharP aBlobID ); TSyError DeleteBlob( cAppCharP aItemID, cAppCharP aBlobID ); TSyError DeleteBlob( cAppCharP aItemID, cAppCharP aParentID, cAppCharP aBlobID ); TSyError DeleteBlob( TDB_Api_ItemID &aID, cAppCharP aBlobID ); // obj will not be removed here TSyError EndDataWrite( bool success, TDB_Api_Str &newToken ); // --- close section -------------------------------- TSyError DeleteContext(); TDB_Api_Callback fCB; // Callback wrapper CContext fContext; // local copy of the context void DisposeStr ( TDB_Api_Str &s ); void DisposeBlk ( TDB_Api_Blk &b ); private: void AssignStr ( TDB_Api_Str &s ); // for internal use only void AssignBlk ( TDB_Api_Blk &b ); void AssignChanged( string &a, TDB_Api_Str &u ); void GetItemID ( TDB_Api_ItemID &aID, TDB_Api_Str &aItem ); void Assign_ItemID( TDB_Api_ItemID &newID, ItemID_Struct &aID, cAppCharP parentID ); API_Methods* dm; // connection field reference API_Methods fNo_dbapi; // default connection for call methods list fSList; // list of currently allocated str objects of this datastore list fBList; // " " " " blk " " " " TDB_Api_Config* fConfig; // assigned module bool fCreated; // true, as long is valid (between 'CreateContext' // and 'DeleteContext') string fDevKey; // local copies string fUsrKey; }; // TDB_Api } // namespace #endif // DB_API_H /* eof */ libsynthesis-3.4.0.47.1/src/DB_interfaces/api_db/dbapi_include.h000077500000000000000000000336041226375725500243050ustar00rootroot00000000000000/* * File: dbapi_include.h * * Author: Beat Forster * * DB_Api class * Bridge to user programmable interface * * Copyright (c) 2004-2011 by Synthesis AG + plan44.ch * */ /* include definitions for each namespace */ #undef SYNC_DBAPI_H #include "sync_dbapi.h" #undef SYNC_UIAPI_H #include "sync_uiapi.h" #if defined __cplusplus using sysync::ConnectFunctions; using sysync::LOCERR_OK; using sysync::DB_NotFound; using sysync::DB_Forbidden; using sysync::DB_Error; using sysync::DB_Fatal; using sysync::VP_BadVersion; #endif static TSyError AssignMethods( appPointer aMod, appPointer aField, memSize aFieldSize, cAppCharP aKey= "" ) { // ---- module ----------------------------------------------------------------- if (strcmp( aKey,Plugin_Start )==0) { return ConnectFunctions( aMod, aField,aFieldSize, false, // ---- start of plugin connection Module_CreateContext, Module_Version, Module_Capabilities, NULL ); } // if if (strcmp( aKey,Plugin_Param )==0) { return ConnectFunctions( aMod, aField,aFieldSize, false, // ---- plugin params Module_PluginParams, NULL ); } // if // ---- session ---------------------------------------------------------------- #if !defined DISABLE_PLUGIN_SESSIONAUTH || !defined DISABLE_PLUGIN_DEVICEADMIN if (strcmp( aKey,Plugin_Session )==0) { return ConnectFunctions( aMod, aField,aFieldSize, false, // ---- session ---- Session_CreateContext, XX, /*-----* adaptitem */ XX, /*-----* session auth */ XX, /* */ XX, /*-----*/ XX, /*-----* device admin */ XX, /* */ XX, /* */ XX, /* */ XX, /*-----*(dbtime) */ Session_DisposeObj, Session_ThreadMayChangeNow, Session_DispItems, Session_DeleteContext, NULL ); } // if if (strcmp( aKey,Plugin_SE_Adapt )==0) { return ConnectFunctions( aMod, aField,aFieldSize, false, // ---- device admin (GetDBTime) ---- Session_AdaptItem, NULL ); } // if #endif #ifndef DISABLE_PLUGIN_SESSIONAUTH if (strcmp( aKey,Plugin_SE_Auth )==0 || // new AND old strcmp( aKey,Plugin_SE_Auth_OLD )==0) { return ConnectFunctions( aMod, aField,aFieldSize, false, // ---- session auth ---- Session_PasswordMode, Session_Login, Session_Logout, NULL ); } // if #endif #ifndef DISABLE_PLUGIN_DEVICEADMIN if (strcmp( aKey,Plugin_DV_Admin )==0) { return ConnectFunctions( aMod, aField,aFieldSize, false, // ---- device admin ---- Session_CheckDevice, Session_GetNonce, Session_SaveNonce, Session_SaveDeviceInfo, NULL ); } // if if (strcmp( aKey,Plugin_DV_DBTime )==0) { return ConnectFunctions( aMod, aField,aFieldSize, false, // ---- device admin (GetDBTime) ---- Session_GetDBTime, NULL ); } // if #endif // ---- datastore -------------------------------------------------------------- #if !defined DISABLE_PLUGIN_DATASTOREADMIN || !defined DISABLE_PLUGIN_DATASTOREDATA if (strcmp( aKey,Plugin_DS_General )==0) { return ConnectFunctions( aMod, aField,aFieldSize, false, // ---- general datastore routines ---- ContextSupport, FilterSupport, ThreadMayChangeNow, WriteLogData, DispItems, NULL ); } // if #endif /* #ifndef DISABLE_PLUGIN_DATASTOREADMIN if (strcmp( aKey,Plugin_DS_Admin )==0 || // new AND old strcmp( aKey,Plugin_DS_Admin_OLD )==0) { return ConnectFunctions( aMod, aField,aFieldSize, false, // ---- datastore admin ---- LoadAdminData, SaveAdminData, ReadNextMapItem, InsertMapItem, UpdateMapItem, DeleteMapItem, NULL ); } // if #endif */ #ifndef DISABLE_PLUGIN_DATASTOREADMIN #ifndef DISABLE_PLUGIN_DATASTOREADMIN_STR if (strcmp( aKey,Plugin_DS_Admin_Str )==0) { return ConnectFunctions( aMod, aField,aFieldSize, false, // ---- aItemData functions ---- LoadAdminData, SaveAdminData, NULL ); } // if #endif #ifndef DISABLE_PLUGIN_DATASTOREADMIN_KEY if (strcmp( aKey,Plugin_DS_Admin_Key )==0) { return ConnectFunctions( aMod, aField,aFieldSize, false, // ---- aItemKey functions ---- LoadAdminDataAsKey, SaveAdminDataAsKey, NULL ); } // if #endif if (strcmp( aKey,Plugin_DS_Admin_Map )==0 || // new AND old strcmp( aKey,Plugin_DS_Admin_OLD )==0) { return ConnectFunctions( aMod, aField,aFieldSize, false, // ---- datastore admin ---- ReadNextMapItem, InsertMapItem, UpdateMapItem, DeleteMapItem, NULL ); } // if #endif #ifndef DISABLE_PLUGIN_ADAPTITEM if (strcmp( aKey,Plugin_DS_Adapt )==0) { return ConnectFunctions( aMod, aField,aFieldSize, false, AdaptItem, NULL ); } // if #endif #ifndef DISABLE_PLUGIN_DATASTOREDATA if (strcmp( aKey,Plugin_DS_Data )==0 || // new AND old strcmp( aKey,Plugin_DS_Data_OLD1 )==0 || strcmp( aKey,Plugin_DS_Data_OLD2 )==0) { return ConnectFunctions( aMod, aField,aFieldSize, false, // ---- datastore data ---- StartDataRead, // read EndDataRead, StartDataWrite, // write EndDataWrite, /*-----*/ XX, /* */ XX, /* str */ XX, /* */ XX, /* */ /*-----*/ XX, /* */ XX, /* key */ XX, /* */ XX, /* */ /*-----*/ FinalizeLocalID, // ind MoveItem, DeleteItem, DeleteSyncSet, NULL ); } // if #ifndef DISABLE_PLUGIN_DATASTOREDATA_STR if (strcmp( aKey,Plugin_DS_Data_Str )==0) { return ConnectFunctions( aMod, aField,aFieldSize, false, // ---- aItemData routines ---- ReadNextItem, ReadItem, InsertItem, UpdateItem, NULL ); } // if #endif #ifndef DISABLE_PLUGIN_DATASTOREDATA_KEY if (strcmp( aKey,Plugin_DS_Data_Key )==0) { return ConnectFunctions( aMod, aField,aFieldSize, false, // ---- aItemKey routines ---- ReadNextItemAsKey, ReadItemAsKey, InsertItemAsKey, UpdateItemAsKey, NULL ); } // if #endif #endif #if !defined DISABLE_PLUGIN_DATASTOREADMIN || !defined DISABLE_PLUGIN_DATASTOREDATA if (strcmp( aKey,Plugin_DS_Blob )==0 || // new AND old strcmp( aKey,Plugin_DS_Blob_OLD1 )==0 || strcmp( aKey,Plugin_DS_Blob_OLD2 )==0) { return ConnectFunctions( aMod, aField,aFieldSize, false, // ---- BLOBs ---- ReadBlob, WriteBlob, DeleteBlob, NULL ); } // if #endif #if !defined DISABLE_PLUGIN_DATASTOREADMIN || !defined DISABLE_PLUGIN_DATASTOREDATA || !defined DISABLE_PLUGIN_ADAPTITEM if (strcmp( aKey,Plugin_Datastore )==0) { return ConnectFunctions( aMod, aField,aFieldSize, false, CreateContext, // open XX, /*+*---- general */ XX, /*+*/ XX, /*+*/ XX, /*+*/ XX, /*+*/ /* */ /*-----* admin */ XX, /* str */ XX, /* */ /*-----*/ XX, /* key */ XX, /* */ /*-----*/ XX, /* */ XX, /* map */ XX, /* */ XX, /* */ /*-----*/ /* */ /*-----* data read/write */ XX, /* rd */ XX, /* */ /*-----*/ XX, /* wr */ XX, /* */ /*-----*/ XX, /* */ XX, /* str */ XX, /* */ XX, /* */ /*-----*/ XX, /* */ XX, /* key */ XX, /* */ XX, /* */ /*-----*/ XX, /* */ XX, /* ind */ XX, /* */ XX, /* */ /*-----*/ /* */ XX, /*-----* blobs */ XX, /* */ XX, /*-----*/ XX, /*-----* adaptitem */ DisposeObj, DeleteContext, // close NULL ); } // if #endif #ifdef ENABLE_PLUGIN_UI // ---- ui context ------------------------------------------------ if (strcmp( aKey,Plugin_UI )==0) { return ConnectFunctions( aMod, aField,aFieldSize, false, // ---- ui ---- UI_CreateContext, UI_RunContext, UI_DeleteContext, NULL ); } // if #endif // default settings if (*aKey=='\0') { return ConnectFunctions( aMod, aField,aFieldSize, false, // ---- module ---- XX, /*-----* start */ XX, /* */ XX, /*-----*/ XX, /*-----* plugin params */ Module_DisposeObj, Module_DeleteContext, // ---- session ---- XX, /*+*/ /* */ XX, /*-*---* login */ XX, /* */ XX, /*-*---*/ /* */ XX, /*-*---* dev admin */ XX, /* */ XX, /* */ XX, /* */ XX, /*-*---*(db time) */ /* */ XX, /*-*---* adaptitem */ /* */ XX, /*+*/ XX, /*+*/ XX, /*+*/ XX, /*+*/ // ---- datastore ---- XX, /*-* open */ XX, /*+*---- general */ XX, /*+*/ XX, /*+*/ XX, /*+*/ XX, /*+*/ /* */ /*-----* admin */ XX, /* str */ XX, /* */ /*-----*/ XX, /* key */ XX, /* */ /*-----*/ XX, /* */ XX, /* map */ XX, /* */ XX, /* */ /*-----*/ /* */ /*-----* data read/write */ XX, /* rd */ XX, /* */ /*-----*/ XX, /* wr */ XX, /* */ /*-----*/ XX, /* */ XX, /* str */ XX, /* */ XX, /* */ /*-----*/ XX, /* */ XX, /* key */ XX, /* */ XX, /* */ /*-----*/ XX, /* */ XX, /* ind */ XX, /* */ XX, /* */ /*-----*/ /* */ XX, /*-----* blobs */ XX, /* */ XX, /*-----*/ XX, /*-----* "script-like" adapt */ XX, /*-* DisposeObj */ XX, /*-* close */ // ---- ui context ---- XX, /*-* open */ XX, /*-* run */ XX, /*-* close */ NULL ); } // if return DB_NotFound; } // AssignMethods /* eof */ libsynthesis-3.4.0.47.1/src/DB_interfaces/api_db/pluginapiagent.cpp000066400000000000000000000650101226375725500250560ustar00rootroot00000000000000/** * @File pluginapiagent.cpp * * @Author Lukas Zeller (luz@plan44.ch) * * @brief TPluginApiAgent * Plugin based agent (client or server session) API implementation * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * @Date 2005-10-06 : luz : created from apidbagent */ // includes #include "pluginapiagent.h" #include "pluginapids.h" #ifdef SYSER_REGISTRATION #include "syserial.h" #endif #ifdef ENGINEINTERFACE_SUPPORT #include "engineentry.h" #endif namespace sysync { // Callback adaptor functions for session level logging // Note: appbase level logging functions are now in syncappbase.cpp as these are // needed even without DB plugins #ifdef SYDEBUG extern "C" void SessionLogDebugPuts(void *aCallbackRef, const char *aText) { if (aCallbackRef) { POBJDEBUGPUTSX(static_cast(aCallbackRef),DBG_DBAPI+DBG_PLUGIN,aText); } } // SessionLogDebugPuts extern "C" void SessionLogDebugExotic(void *aCallbackRef, const char *aText) { if (aCallbackRef) { POBJDEBUGPUTSX(static_cast(aCallbackRef),DBG_DBAPI+DBG_PLUGIN+DBG_EXOTIC,aText); } } // SessionLogDebugExotic extern "C" void SessionLogDebugBlock(void *aCallbackRef, const char *aTag, const char *aDesc, const char *aAttrText ) { if (aCallbackRef) { bool collapsed=false; if (aTag && aTag[0]=='-') { aTag++; collapsed=true; } static_cast(aCallbackRef)->getDbgLogger()->DebugOpenBlock(TDBG_LOCATION_NONE aTag,aDesc,collapsed,"%s",aAttrText); } } // SessionLogDebugBlock extern "C" void SessionLogDebugEndBlock(void *aCallbackRef, const char *aTag) { if (aCallbackRef) { if (aTag && aTag[0]=='-') aTag++; static_cast(aCallbackRef)->getDbgLogger()->DebugCloseBlock(TDBG_LOCATION_NONE aTag); } } // SessionLogDebugEndBlock extern "C" void SessionLogDebugEndThread(void *aCallbackRef) { if (aCallbackRef) { static_cast(aCallbackRef)->getDbgLogger()->DebugThreadOutputDone(false); // leave session thread record live until session dies } } // SessionLogDebugEndThread #endif #ifdef ENGINEINTERFACE_SUPPORT extern "C" TSyError SessionOpenSessionKey(void* aCB, SessionH aSessionH, KeyH *aKeyH, uInt16 aMode) { // Note: aSessionH must be NULL, as we are implicitly in a session context and cannot specify the session if (!aCB || !aKeyH || aSessionH!=NULL) return LOCERR_BADPARAM; DB_Callback cb = static_cast(aCB); if (!cb->callbackRef) return LOCERR_BADPARAM; // create settings key for the session TSyncSession *sessionP = static_cast(cb->callbackRef); *aKeyH = static_cast(sessionP->newSessionKey(sessionP->getSyncAppBase()->fEngineInterfaceP)); // done return LOCERR_OK; } // SessionOpenSessionKey #endif // ENGINEINTERFACE_SUPPORT // TApiParamConfig // =============== TApiParamConfig::TApiParamConfig(TConfigElement *aParentElement) : TConfigElement("plugin_config",aParentElement) { // nop so far } // TApiParamConfig::TPluginAgentConfig TApiParamConfig::~TApiParamConfig() { clear(); } // TApiParamConfig::~TApiParamConfig // init defaults void TApiParamConfig::clear(void) { // init defaults fConfigString.erase(); fLastTagName.erase(); fLastTagValue.erase(); // clear inherited inherited::clear(); } // TApiParamConfig::clear // store last tag's value void TApiParamConfig::storeLastTag(void) { // init defaults if (!fLastTagName.empty()) { fConfigString.append(fLastTagName); fConfigString+=':'; StrToCStrAppend(fLastTagValue.c_str(),fConfigString,true); // allow 8-bit chars to be represented as-is (no \xXX escape needed) fConfigString+="\r\n"; // CRLF at end } // done, erase them fLastTagName.erase(); fLastTagValue.erase(); } // TApiParamConfig::storeLastTag // config element parsing bool TApiParamConfig::localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine) { // all elements will be passed 1:1 into DBAPI // - make sure previous element is stored storeLastTag(); // - remember name of this tag fLastTagName=aElementName; // - contents is always a string expectString(fLastTagValue); // ok return true; } // TApiParamConfig::localStartElement // resolve void TApiParamConfig::localResolve(bool aLastPass) { // make sure previous element is stored, if any storeLastTag(); // resolve inherited inherited::localResolve(aLastPass); } // TApiParamConfig::localResolve // TPluginAgentConfig // ================== TPluginAgentConfig::TPluginAgentConfig(TConfigElement *aParentElement) : inherited(aParentElement), fPluginParams(this) { // nop so far } // TPluginAgentConfig::TPluginAgentConfig TPluginAgentConfig::~TPluginAgentConfig() { clear(); // - disconnect from the API module fDBApiConfig.Disconnect(); } // TPluginAgentConfig::~TPluginAgentConfig // init defaults void TPluginAgentConfig::clear(void) { // init defaults // - API Module fLoginAPIModule.erase(); // - use api session auth or not? fApiSessionAuth=false; // - use api device admin or not? fApiDeviceAdmin=false; // - default to use all debug flags set (if debug for plugin is enabled at all) fPluginDbgMask=0xFFFF; // - clear plugin params fPluginParams.clear(); // clear inherited inherited::clear(); } // TPluginAgentConfig::clear // config element parsing bool TPluginAgentConfig::localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine) { // checking the elements // - API connection if (strucmp(aElementName,"plugin_module")==0) expectMacroString(fLoginAPIModule); else if (strucmp(aElementName,"plugin_sessionauth")==0) expectBool(fApiSessionAuth); else if (strucmp(aElementName,"plugin_deviceadmin")==0) expectBool(fApiDeviceAdmin); else if (strucmp(aElementName,"plugin_params")==0) expectChildParsing(fPluginParams); else if (strucmp(aElementName,"plugin_debugflags")==0) expectUInt16(fPluginDbgMask); else return inherited::localStartElement(aElementName,aAttributes,aLine); // ok return true; } // TPluginAgentConfig::localStartElement // resolve void TPluginAgentConfig::localResolve(bool aLastPass) { // resolve plugin specific config leaf fPluginParams.Resolve(aLastPass); if (aLastPass) { if (!fLoginAPIModule.empty()) { // Determine if we may use non-built-in plugins bool allowDLL= true; // by default, it is allowed, but if PLUGIN_DLL is not set, it will be disabled anyway. #if defined(SYSER_REGISTRATION) && !defined(DLL_PLUGINS_ALWAYS_ALLOWED) // license flags present and DLL plugins not generally allowed: // -> license decides if DLL is allowed allowDLL= (getSyncAppBase()->fRegProductFlags & SYSER_PRODFLAG_SERVER_SDKAPI)!=0; // warn about DLL not allowed ONLY if this build actually supports DLL plugins #if defined(PLUGIN_DLL) if (!allowDLL) { SYSYNC_THROW(TConfigParseException("License does not allow using ")); } #endif // DLL support available in the code at all #endif // DLL plugins not generally allowed (or DLL support not compiled in) // Module level debug goes to appbase (global) log DB_Callback cb= &fDBApiConfig.fCB.Callback; cb->callbackRef = getSyncAppBase(); #ifdef ENGINEINTERFACE_SUPPORT cb->thisBase = getSyncAppBase()->fEngineInterfaceP; #endif #ifdef SYDEBUG cb->debugFlags= (getSyncAppBase()->getRootConfig()->fDebugConfig.fGlobalDebugLogs) && PDEBUGTEST(DBG_ADMIN+DBG_DBAPI+DBG_PLUGIN) ? fPluginDbgMask : 0; cb->DB_DebugPuts = AppBaseLogDebugPuts; cb->DB_DebugBlock = AppBaseLogDebugBlock; cb->DB_DebugEndBlock = AppBaseLogDebugEndBlock; cb->DB_DebugEndThread = AppBaseLogDebugEndThread; cb->DB_DebugExotic = AppBaseLogDebugExotic; #endif // check for required settings if (fDBApiConfig.Connect(fLoginAPIModule.c_str(), getSyncAppBase()->fApiInterModuleContext, "", false, allowDLL)!=LOCERR_OK) SYSYNC_THROW(TConfigParseException("Cannot connect to session handler module specified in ")); // now pass plugin-specific config if (fDBApiConfig.PluginParams(fPluginParams.fConfigString.c_str())!=LOCERR_OK) SYSYNC_THROW(TConfigParseException("Module does not understand params passed in ")); } } // resolve inherited inherited::localResolve(aLastPass); } // TPluginAgentConfig::localResolve // TPluginApiAgent // =============== TPluginApiAgent::TPluginApiAgent(TSyncAppBase *aAppBaseP, TSyncSessionHandle *aSessionHandleP, cAppCharP aSessionID) : inherited(aAppBaseP, aSessionHandleP, aSessionID), fPluginAgentConfigP(NULL), fApiLocked(false) { // get config for agent and save direct link to agent config for easy reference fPluginAgentConfigP = static_cast(getRootConfig()->fAgentConfigP); // Note: Datastores are already created from config if (fPluginAgentConfigP->fDBApiConfig.Connected()) { TSyError dberr; DB_Callback cb= &fDBApiSession.fCB.Callback; cb->callbackRef = this; // the session #ifdef ENGINEINTERFACE_SUPPORT cb->thisBase = getSyncAppBase()->fEngineInterfaceP; #endif #ifdef SYDEBUG // Agent Context level debug goes to session log cb->debugFlags = getDbgMask() ? 0xFFFF : 0; cb->DB_DebugPuts = SessionLogDebugPuts; cb->DB_DebugBlock = SessionLogDebugBlock; cb->DB_DebugEndBlock = SessionLogDebugEndBlock; cb->DB_DebugEndThread= SessionLogDebugEndThread; cb->DB_DebugExotic = SessionLogDebugExotic; #endif // SYDEBUG #ifdef ENGINEINTERFACE_SUPPORT // Data module can use Get/SetValue for "AsKey" routines and for session script var access // Note: these are essentially context free and work without a global call-in structure // (which is not necessarily there, for example in no-library case) CB_Connect_KeyAccess(cb); // connect generic key access routines // Version of OpenSessionKey that implicitly opens a key for the current session (DB plugins // do not have a session handle, as their use is always implicitly in a session context). cb->ui.OpenSessionKey = SessionOpenSessionKey; #endif // ENGINEINTERFACE_SUPPORT // Now create the context for running this session // - use session ID as session name dberr=fDBApiSession.CreateContext(getLocalSessionID(),fPluginAgentConfigP->fDBApiConfig); if (dberr!=LOCERR_OK) SYSYNC_THROW(TSyncException("Error creating context for API session module",dberr)); } } // TPluginApiAgent::TPluginApiAgent TPluginApiAgent::~TPluginApiAgent() { // make sure everything is terminated BEFORE destruction of hierarchy begins TerminateSession(); } // TPluginApiAgent::~TPluginApiAgent // Terminate session void TPluginApiAgent::TerminateSession() { if (!fTerminated) { // Make sure datastores know that the agent will go down soon (and give them opportunity to disconnect contexts) announceDestruction(); // Note that the following will happen BEFORE destruction of // individual datastores, so make sure datastore have their inherited stuff (e.g. ODBC) // stuff finished before disposing environment InternalResetSession(); // now we can destroy the session level API context (no connected DB context exist any more) fDBApiSession.DeleteContext(); } inherited::TerminateSession(); } // TPluginApiAgent::TerminateSession // Reset session void TPluginApiAgent::InternalResetSession(void) { // reset all datastores now to make sure all Plugin access is over (including log writing) // before the Plugin Agent is destroyed. // (Note: TerminateDatastores() will be called again by ancestors) TerminateDatastores(); // logout api LogoutApi(); } // TPluginApiAgent::InternalResetSession // Virtual version void TPluginApiAgent::ResetSession(void) { // do my own stuff InternalResetSession(); // let ancestor do its stuff TStdLogicAgent::ResetSession(); } // TPluginApiAgent::ResetSession // get time of DB server lineartime_t TPluginApiAgent::getDatabaseNowAs(timecontext_t aTimecontext) { #ifndef SDK_ONLY_SUPPORT // only handle here if we are in charge - otherwise let ancestor handle it if (!fPluginAgentConfigP->fApiDeviceAdmin) return inherited::getDatabaseNowAs(aTimecontext); #endif lineartime_t dbtime; #if defined RELEASE_VERSION && !defined _MSC_VER //#warning "GZones should not be passed NULL here" #endif if (fDBApiSession.GetDBTime( dbtime, NULL )!=LOCERR_OK) { dbtime=getSystemNowAs(TCTX_UTC); // just use time of this machine } // return it return dbtime; } // TPluginApiAgent::getDatabaseNowAs #ifdef SYSYNC_SERVER // info about requested auth type TAuthTypes TPluginApiAgent::requestedAuthType(void) { // if not checking via api, let inherited decide if (!fPluginAgentConfigP->fApiSessionAuth) return inherited::requestedAuthType(); // get default TAuthTypes auth = TSyncAgent::requestedAuthType(); // depending on possibilities of used module, we need to enforce basic int pwmode=fDBApiSession.PasswordMode(); if (pwmode==Password_ClrText_IN || (pwmode==Password_MD5_OUT && getSyncMLVersion()fApiDeviceAdmin) { // no device ID or no persistent nonce, use method of ancestor inherited::getAuthNonce(aDeviceID,aAuthNonce); } else { // we have a persistent nonce DEBUGPRINTFX(DBG_ADMIN,("getAuthNonce: current auth nonce='%s'",fLastNonce.c_str())); aAuthNonce=fLastNonce.c_str(); } } // TPluginApiAgent::getAuthNonce // get next nonce (to be sent to remote party for next auth of that remote party with us) // Must generate and persistently save a new nonce string which will be sent in // this session to the remote, and which will be used in the next session for // authenticating the remote device. void TPluginApiAgent::getNextNonce(const char *aDeviceID, string &aNextNonce) { if (!fPluginAgentConfigP->fApiDeviceAdmin) { // no persistent nonce, use method of ancestor inherited::getNextNonce(aDeviceID,aNextNonce); } else { // plugin is responsible for storing a persistent nonce per device // - check if plugin wants to generate the nonce itself TDB_Api_Str apiNonce; if (fDBApiSession.GetNonce(apiNonce)==LOCERR_OK) { // plugin has generated a nonce, use it aNextNonce = apiNonce.c_str(); } else { // plugin does not generate nonce itself, use our own generator // - create new one (pure 7bit ASCII) generateNonce(aNextNonce,aDeviceID,getSystemNowAs(TCTX_UTC)+rand()); } // - save it such that next CheckDevice() can retrieve it as fLastNonce (see below) TSyError sta=fDBApiSession.SaveNonce(aNextNonce.c_str()); if (sta!=LOCERR_OK) { PDEBUGPRINTFX(DBG_ERROR,("getNextNonce: SaveNonce failed with error = %hd",sta)); } } } // TPluginApiAgent::getNextNonce #endif // SYSYNC_CLIENT #ifndef BINFILE_ALWAYS_ACTIVE // check device related stuff // - Must retrieve device record for device identified by aDeviceID. // - If no such record exists, create a new one and set: // - fLastNonce to empty string // - If the record exists, the following fields must be retrieved from the DB: // - fLastNonce : opaque string used for MD5 auth // - In any case, the routine should set: // - fDeviceKey : identifier that can be used in other calls (like LoadAdminData/SaveAdminData // or dsLogSyncResult) to refer to this device void TPluginApiAgent::CheckDevice(const char *aDeviceID) { // do it here only if we have device info stuff implemented in ApiDB if (!fPluginAgentConfigP->fApiDeviceAdmin) { // let inherited process it inherited::CheckDevice(aDeviceID); } else { // Plugin will do the device checking and has stored the nonce generated in the previous session TDB_Api_Str lastNonce; TDB_Api_Str deviceKey; TSyError sta = fDBApiSession.CheckDevice(aDeviceID,deviceKey,lastNonce); if (sta!=LOCERR_OK) SYSYNC_THROW(TSyncException("TPluginApiAgent: checkdevice failed",sta)); #ifdef SYSYNC_SERVER if (IS_SERVER) { // save last nonce fLastNonce = lastNonce.c_str(); } #endif // SYSYNC_SERVER // device "key" is set to deviceID. Plugin internally maintains its key needed for storing Nonce or DevInf fDeviceKey = deviceKey.c_str(); } // if device table implemented in ApiDB } // TPluginApiAgent::CheckDevice // Device is now known as detailed as possible (i.e. we have the device information, if it was possible to get it) // The implementation can now save some of this information for logging and tracking purposes: // - getRemoteURI() : string, remote Device URI (usually IMEI or other globally unique ID) // - getRemoteDescName() : string, remote Device's descriptive name (constructed from DevInf and , or // as set by 's . // - getRemoteInfoString() : string, Remote Device Version Info ("Type (HWV, FWV, SWV) Oem") // - fUserKey : string, identifies user // - fDeviceKey : string, identifies device // - fDomainName : string, identifies domain (aka clientID, aka enterpriseID) // - fRemoteDevInf_mod : string, model name from remote devinf // - fRemoteDevInf_man : string, manufacturer name from remote devinf // - fRemoteDevInf_oem : string, OEM name from remote devinf // - fRemoteDevInf_fwv : string, firmware version from remote devinf // - fRemoteDevInf_swv : string, software version from remote devinf // - fRemoteDevInf_hwv : string, hardware version from remote devinf // fDeviceKey is normally used to re-identify the record in the database that was found or created at CheckDevice. void TPluginApiAgent::remoteAnalyzed(void) { // save basic device info used for associating targets and logentries with a device if (fPluginAgentConfigP->fApiDeviceAdmin) { // save device info stuff string devInf,val; devInf.erase(); // save as properties // - internals devInf += "REMOTE_URI:"; storeUTF8ToString(getRemoteURI(),val,fConfigP->fDataCharSet,fConfigP->fDataLineEndMode); StrToCStrAppend(val.c_str(),devInf,true); // allow 8-bit chars to be represented as-is (no \xXX escape needed) devInf += "\r\nREMOTE_DESC:"; storeUTF8ToString(getRemoteDescName(),val,fConfigP->fDataCharSet,fConfigP->fDataLineEndMode); StrToCStrAppend(val.c_str(),devInf,true); // allow 8-bit chars to be represented as-is (no \xXX escape needed) devInf += "\r\nREMOTE_INFO:"; storeUTF8ToString(getRemoteInfoString(),val,fConfigP->fDataCharSet,fConfigP->fDataLineEndMode); StrToCStrAppend(val.c_str(),devInf,true); // allow 8-bit chars to be represented as-is (no \xXX escape needed) #ifdef SCRIPT_SUPPORT devInf += "\r\nDOMAIN:"; storeUTF8ToString(fDomainName.c_str(),val,fConfigP->fDataCharSet,fConfigP->fDataLineEndMode); StrToCStrAppend(val.c_str(),devInf,true); // allow 8-bit chars to be represented as-is (no \xXX escape needed) #endif // - strictly from DevInf devInf += "\r\nMOD:"; storeUTF8ToString(fRemoteDevInf_mod.c_str(),val,fConfigP->fDataCharSet,fConfigP->fDataLineEndMode); StrToCStrAppend(val.c_str(),devInf,true); // allow 8-bit chars to be represented as-is (no \xXX escape needed) devInf += "\r\nMAN:"; storeUTF8ToString(fRemoteDevInf_man.c_str(),val,fConfigP->fDataCharSet,fConfigP->fDataLineEndMode); StrToCStrAppend(val.c_str(),devInf,true); // allow 8-bit chars to be represented as-is (no \xXX escape needed) devInf += "\r\nOEM:"; storeUTF8ToString(fRemoteDevInf_oem.c_str(),val,fConfigP->fDataCharSet,fConfigP->fDataLineEndMode); StrToCStrAppend(val.c_str(),devInf,true); // allow 8-bit chars to be represented as-is (no \xXX escape needed) devInf += "\r\nFWV:"; storeUTF8ToString(fRemoteDevInf_fwv.c_str(),val,fConfigP->fDataCharSet,fConfigP->fDataLineEndMode); StrToCStrAppend(val.c_str(),devInf,true); // allow 8-bit chars to be represented as-is (no \xXX escape needed) devInf += "\r\nSWV:"; storeUTF8ToString(fRemoteDevInf_swv.c_str(),val,fConfigP->fDataCharSet,fConfigP->fDataLineEndMode); StrToCStrAppend(val.c_str(),devInf,true); // allow 8-bit chars to be represented as-is (no \xXX escape needed) devInf += "\r\nHWV:"; storeUTF8ToString(fRemoteDevInf_hwv.c_str(),val,fConfigP->fDataCharSet,fConfigP->fDataLineEndMode); StrToCStrAppend(val.c_str(),devInf,true); // allow 8-bit chars to be represented as-is (no \xXX escape needed) devInf += "\r\n"; // last line end // now store TSyError sta = fDBApiSession.SaveDeviceInfo(devInf.c_str()); if (sta!=LOCERR_OK) SYSYNC_THROW(TSyncException("TPluginApiAgent: SaveDeviceInfo failed",sta)); } // if device table implemented in ApiDB else { // let inherited process it inherited::remoteAnalyzed(); } } // TPluginApiAgent::remoteAnalyzed // check login information bool TPluginApiAgent::CheckLogin(const char *aOriginalUserName, const char *aModifiedUserName, const char *aAuthString, TAuthSecretTypes aAuthStringType, const char *aDeviceID) { bool authok=false; string nonce; // - get nonce (if we have a device table, we should have read it by now) if (aAuthStringType==sectyp_md5_V10 || aAuthStringType==sectyp_md5_V11) getAuthNonce(aDeviceID,nonce); if (!fPluginAgentConfigP->fDBApiConfig.Connected() || !fPluginAgentConfigP->fApiSessionAuth) { // let inherited handle it (if direct ancestor is TCustomImplAgent, we'll fail here) return inherited::CheckLogin(aOriginalUserName, aModifiedUserName, aAuthString, aAuthStringType, aDeviceID); } // api auth required TDB_Api_Str userKey; TDB_Api_Str dbSecret; int pwmode = fDBApiSession.PasswordMode(); // check anonymous login if (aAuthStringType==sectyp_anonymous) { if (pwmode==Password_ClrText_IN || pwmode==Password_MD5_Nonce_IN) { // modes that pass in credential string - pass empty credential string to signal "anonymous" authok = fDBApiSession.Login(aModifiedUserName,"",userKey)==LOCERR_OK; } else { // modes that get credential string from API - check that API returns empty string to signal "anonymous" login is ok authok = fDBApiSession.Login(aModifiedUserName,dbSecret,userKey)==LOCERR_OK; authok = authok && dbSecret.empty(); // returned secret must be empty to allow anonymous login } } // check if we can auth at all else if (pwmode == Password_ClrText_IN) { // we can auth only if we have a cleartext password from the remote if (aAuthStringType!=sectyp_clearpass) return false; // auth not possible // login with clear text password authok = fDBApiSession.Login(aModifiedUserName,aAuthString,userKey)==LOCERR_OK; } else if (pwmode == Password_MD5_Nonce_IN) { if (aAuthStringType==sectyp_clearpass) { std::string p1, p2, p3; if (nonce == "") getAuthNonce(aDeviceID, nonce); p1 = aModifiedUserName; p1 += ":"; p1 += aAuthString; MD5B64(p1.c_str(), p1.length(), p2); p2 += ":"; p2 += nonce; MD5B64(p2.c_str(), p2.length(), p3); authok = fDBApiSession.Login(aModifiedUserName,p3.c_str(), userKey)==LOCERR_OK; } else { // login with MD5( MD5( user:pwd ):nonce ) authok = fDBApiSession.Login(aModifiedUserName,aAuthString,userKey)==LOCERR_OK; } } else { if (pwmode == Password_MD5_OUT) { // if the database has MD5, we can auth basic and SyncML 1.1 MD5, but not SyncML 1.0 MD5 if (aAuthStringType==sectyp_md5_V10) return false; // auth with SyncML 1.0 MD5 not possible } // get Secret and preliminary authok (w/o password check yet) from database authok = fDBApiSession.Login(aModifiedUserName,dbSecret,userKey)==LOCERR_OK; if (authok) { // check secret if (pwmode == Password_ClrText_OUT) { // we have the clear text password, check against what was transmitted from remote authok = checkAuthPlain(aOriginalUserName,dbSecret.c_str(),nonce.c_str(),aAuthString,aAuthStringType); } else { // whe have the MD5 of user:password, check against what was transmitted from remote // Note: this can't work with non-V1.1 type creds authok = checkAuthMD5(aOriginalUserName,dbSecret.c_str(),nonce.c_str(),aAuthString,aAuthStringType); } } } if (!authok) { // failed PDEBUGPRINTFX(DBG_ADMIN,( "==== api authentication for '%s' failed", aModifiedUserName )); return false; } else { // save user key as returned from dbapi login() fUserKey = userKey.c_str(); // authenticated successfully, sessionID is set PDEBUGPRINTFX(DBG_ADMIN,( "==== api authentication for '%s' (userkey='%s') successful", aModifiedUserName, fUserKey.c_str() )); return true; } } // TPluginApiAgent::CheckLogin #endif // not BINFILE_ALWAYS_ACTIVE // - logout api void TPluginApiAgent::LogoutApi(void) { if (fPluginAgentConfigP->fDBApiConfig.Connected() && fPluginAgentConfigP->fApiSessionAuth) { // log out from session fDBApiSession.Logout(); } } // TPluginApiAgent::LogoutApi #ifdef SYSYNC_SERVER void TPluginApiAgent::RequestEnded(bool &aHasData) { // first let ancestors finish their stuff // - this will include calling RequestEnded() in all datastores inherited::RequestEnded(aHasData); // let my API know as well, thread might change for next request (but not necessarily does!) if (fPluginAgentConfigP->fDBApiConfig.Connected()) { if (!fApiLocked) fDBApiSession.ThreadMayChangeNow(); } } // TPluginApiAgent::RequestEnded #endif // factory methods of Agent config // =============================== #ifdef SYSYNC_CLIENT TSyncAgent *TPluginAgentConfig::CreateClientSession(const char *aSessionID) { // return appropriate client session MP_RETURN_NEW(TPluginApiAgent,DBG_HOT,"TPluginApiAgent",TPluginApiAgent(getSyncAppBase(),NULL,aSessionID)); } // TPluginAgentConfig::CreateClientSession #endif #ifdef SYSYNC_SERVER TSyncAgent *TPluginAgentConfig::CreateServerSession(TSyncSessionHandle *aSessionHandle, const char *aSessionID) { // return XML2GO or ODBC-server session MP_RETURN_NEW(TPluginApiAgent,DBG_HOT,"TPluginApiAgent",TPluginApiAgent(getSyncAppBase(),aSessionHandle,aSessionID)); } // TPluginAgentConfig::CreateServerSession #endif } // namespace sysync /* end of TPluginApiAgent implementation */ // eof libsynthesis-3.4.0.47.1/src/DB_interfaces/api_db/pluginapiagent.h000077500000000000000000000127231226375725500245310ustar00rootroot00000000000000/** * @File pluginapiagent.h * * @Author Lukas Zeller (luz@plan44.ch) * * @brief TPluginApiAgent * Plugin based agent (client or server session) API implementation * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * @Date 2005-10-06 : luz : created from apidbagent */ #ifndef PLUGINAPIAGENT_H #define PLUGINAPIAGENT_H // includes #ifdef SQL_SUPPORT #include "odbcapiagent.h" #else #include "customimplagent.h" #endif namespace sysync { // plugin module generic config class TApiParamConfig: public TConfigElement { typedef TConfigElement inherited; public: TApiParamConfig(TConfigElement *aParentElement); virtual ~TApiParamConfig(); // Assembled tag:value type config lines string fConfigString; virtual void clear(); protected: // check config elements virtual bool localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine); virtual void localResolve(bool aLastPass); private: void storeLastTag(void); string fLastTagName; string fLastTagValue; }; // TApiParamConfig } // namespace sysync #include "pluginapids.h" using namespace sysync; namespace sysync { // Session level callback adaptor functions #ifdef SYDEBUG extern "C" void SessionLogDebugPuts(void *aCallbackRef, const char *aText); extern "C" void SessionLogDebugExotic(void *aCallbackRef, const char *aText); extern "C" void SessionLogDebugBlock(void *aCallbackRef, const char *aTag, const char *aDesc, const char *aAttrText ); extern "C" void SessionLogDebugEndBlock(void *aCallbackRef, const char *aTag); extern "C" void SessionLogDebugEndThread(void *aCallbackRef); #endif // SYDEBUG #ifdef ENGINEINTERFACE_SUPPORT extern "C" TSyError SessionOpenSessionKey(void* aCB, SessionH aSessionH, KeyH *aKeyH, uInt16 aMode); #endif // ENGINEINTERFACE_SUPPORT // forward class TPluginDSConfig; #ifdef SCRIPT_SUPPORT class TScriptContext; #endif // config class TPluginAgentConfig : #ifdef SQL_SUPPORT public TOdbcAgentConfig #else public TCustomAgentConfig #endif { #ifdef SQL_SUPPORT typedef TOdbcAgentConfig inherited; #else typedef TCustomAgentConfig inherited; #endif public: TPluginAgentConfig(TConfigElement *aParentElement); virtual ~TPluginAgentConfig(); // properties // - name of the login module string fLoginAPIModule; // - use Api session auth or not? bool fApiSessionAuth; // - use api device admin or not? bool fApiDeviceAdmin; // - the DB API config object TDB_Api_Config fDBApiConfig; // - generic module params TApiParamConfig fPluginParams; // - debug mask uInt16 fPluginDbgMask; protected: // check config elements virtual bool localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine); virtual void clear(); virtual void localResolve(bool aLastPass); public: #ifdef SYSYNC_CLIENT // create appropriate session (=agent) for this client virtual TSyncAgent *CreateClientSession(const char *aSessionID); #endif #ifdef SYSYNC_SERVER // create appropriate session (=agent) for this server virtual TSyncAgent *CreateServerSession(TSyncSessionHandle *aSessionHandle, const char *aSessionID); #endif }; // TPluginAgentConfig class TPluginApiAgent : #ifdef SQL_SUPPORT public TODBCApiAgent #else public TCustomImplAgent #endif { #ifdef SQL_SUPPORT typedef TODBCApiAgent inherited; #else typedef TCustomImplAgent inherited; #endif public: TPluginApiAgent(TSyncAppBase *aAppBaseP, TSyncSessionHandle *aSessionHandleP, cAppCharP aSessionID); virtual ~TPluginApiAgent(); virtual void TerminateSession(void); // Terminate session, like destructor, but without actually destructing object itself virtual void ResetSession(void); // Resets session (but unlike TerminateSession, session might be re-used) void InternalResetSession(void); // static implementation for calling through virtual destructor and virtual ResetSession(); // user authentication #ifdef SYSYNC_SERVER // - return auth type to be requested from remote virtual TAuthTypes requestedAuthType(void); // avoids MD5 when it cannot be checked // - get next nonce string top be sent to remote party for subsequent MD5 auth virtual void getNextNonce(const char *aDeviceID, string &aNextNonce); // - get nonce string, which is expected to be used by remote party for MD5 auth. virtual void getAuthNonce(const char *aDeviceID, string &aAuthNonce); #endif // SYSYNC_SERVER #ifndef BINFILE_ALWAYS_ACTIVE // - check device ID related stuff virtual void CheckDevice(const char *aDeviceID); // - remote device is analyzed, possibly save status virtual void remoteAnalyzed(void); // - check login for this session (everything else is done by CustomAgent's SessionLogin) virtual bool CheckLogin(const char *aOriginalUserName, const char *aModifiedUserName, const char *aAuthString, TAuthSecretTypes aAuthStringType, const char *aDeviceID); #endif // not BINFILE_ALWAYS_ACTIVE // - logout void LogoutApi(void); // current database date & time virtual lineartime_t getDatabaseNowAs(timecontext_t aTimecontext); // agent config TPluginAgentConfig *fPluginAgentConfigP; // set while Api access is locked because of a thread using it bool fApiLocked; // get API session object TDB_Api_Session *getDBApiSession() { return &fDBApiSession; }; protected: #ifdef SYSYNC_SERVER // - request end, used to clean up virtual void RequestEnded(bool &aHasData); #endif private: TDB_Api_Session fDBApiSession; }; // TPluginApiAgent } // namespace sysync #endif // PLUGINAPIAGENT_H // eof libsynthesis-3.4.0.47.1/src/DB_interfaces/api_db/pluginapids.cpp000077500000000000000000003362121226375725500243760ustar00rootroot00000000000000/** * @File pluginapids.cpp * * @Author Lukas Zeller (luz@plan44.ch) * * @brief TPluginApiDS * Plugin based datastore API implementation * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * @Date 2005-10-06 : luz : created from apidbdatastore */ // includes #include "sysync.h" #include "pluginapids.h" #include "pluginapiagent.h" #ifdef SYSER_REGISTRATION #include "syserial.h" #endif #ifdef ENGINEINTERFACE_SUPPORT #include "engineentry.h" #endif #include "SDK_support.h" namespace sysync { // Config // ====== // Helpers // ======= // Field Map item // ============== TApiFieldMapItem::TApiFieldMapItem(const char *aElementName, TConfigElement *aParentElement) : inherited(aElementName,aParentElement) { /* nop for now */ } // TApiFieldMapItem::TApiFieldMapItem void TApiFieldMapItem::checkAttrs(const char **aAttributes) { /* nop for now */ inherited::checkAttrs(aAttributes); } // TApiFieldMapItem::checkAttrs #ifdef ARRAYDBTABLES_SUPPORT // Array Map item // =============== TApiFieldMapArrayItem::TApiFieldMapArrayItem(TCustomDSConfig *aCustomDSConfigP, TConfigElement *aParentElement) : inherited(aCustomDSConfigP,aParentElement) { /* nop for now */ } // TApiFieldMapArrayItem::TApiFieldMapArrayItem void TApiFieldMapArrayItem::checkAttrs(const char **aAttributes) { /* nop for now */ inherited::checkAttrs(aAttributes); } // TApiFieldMapArrayItem::checkAttrs #endif // TPluginDSConfig // ============ TPluginDSConfig::TPluginDSConfig(const char* aName, TConfigElement *aParentElement) : inherited(aName,aParentElement), fPluginParams_Admin(this), fPluginParams_Data(this) { // nop so far clear(); } // TPluginDSConfig::TPluginDSConfig TPluginDSConfig::~TPluginDSConfig() { clear(); // disconnect from the API module fDBApiConfig_Data.Disconnect(); fDBApiConfig_Admin.Disconnect(); } // TPluginDSConfig::~TPluginDSConfig // init defaults void TPluginDSConfig::clear(void) { // init defaults fDBAPIModule_Admin.erase(); fDBAPIModule_Data.erase(); fDataModuleAlsoHandlesAdmin=false; fEarlyStartDataRead = false; // - default to use all debug flags set (if debug for plugin is enabled at all) fPluginDbgMask_Admin=0xFFFF; fPluginDbgMask_Data=0xFFFF; // - clear plugin params fPluginParams_Admin.clear(); fPluginParams_Data.clear(); // - clear capabilities fItemAsKey = false; fResumeSupported = true; fHasDeleteSyncSet = false; // clear inherited inherited::clear(); } // TPluginDSConfig::clear // config element parsing bool TPluginDSConfig::localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine) { // checking the elements if (strucmp(aElementName,"plugin_module")==0) expectMacroString(fDBAPIModule_Data); else if (strucmp(aElementName,"plugin_datastoreadmin")==0) expectBool(fDataModuleAlsoHandlesAdmin); else if (strucmp(aElementName,"plugin_earlystartdataread")==0) expectBool(fEarlyStartDataRead); else if (strucmp(aElementName,"plugin_params")==0) expectChildParsing(fPluginParams_Data); else if (strucmp(aElementName,"plugin_debugflags")==0) expectUInt16(fPluginDbgMask_Data); else if (strucmp(aElementName,"plugin_module_admin")==0) expectMacroString(fDBAPIModule_Admin); else if (strucmp(aElementName,"plugin_params_admin")==0) expectChildParsing(fPluginParams_Admin); else if (strucmp(aElementName,"plugin_debugflags_admin")==0) expectUInt16(fPluginDbgMask_Admin); else return inherited::localStartElement(aElementName,aAttributes,aLine); // ok return true; } // TPluginDSConfig::localStartElement // resolve void TPluginDSConfig::localResolve(bool aLastPass) { // resolve plugin specific config leaf fPluginParams_Admin.Resolve(aLastPass); fPluginParams_Data.Resolve(aLastPass); // try to resolve configured API-module name into set of function pointers if (aLastPass) { // Determine if we may use non-built-in plugins bool allowDLL= true; // by default, it is allowed, but if PLUGIN_DLL is not set, it will be disabled anyway. #if defined(SYSER_REGISTRATION) && !defined(DLL_PLUGINS_ALWAYS_ALLOWED) // license flags present and DLL plugins not generally allowed: // -> license decides if DLL is allowed allowDLL= (getSyncAppBase()->fRegProductFlags & SYSER_PRODFLAG_SERVER_SDKAPI)!=0; // warn about DLL not allowed ONLY if this build actually supports DLL plugins #if defined(PLUGIN_DLL) if (!allowDLL) { SYSYNC_THROW(TConfigParseException("License does not allow using ")); } #endif // DLL support available in the code at all #endif // DLL plugins not generally allowed (or DLL support not compiled in) // Connect module for handling data access if (!fDBAPIModule_Data.empty()) { // we have a module specified for data access DB_Callback cb= &fDBApiConfig_Data.fCB.Callback; cb->callbackRef = getSyncAppBase(); #ifdef ENGINEINTERFACE_SUPPORT cb->thisBase = getSyncAppBase()->fEngineInterfaceP; #endif #ifdef SYDEBUG // direct Module level debug to global log cb->debugFlags= (getSyncAppBase()->getRootConfig()->fDebugConfig.fGlobalDebugLogs) && PDEBUGTEST(DBG_DATA+DBG_DBAPI+DBG_PLUGIN) ? fPluginDbgMask_Data : 0; cb->DB_DebugPuts = AppBaseLogDebugPuts; cb->DB_DebugBlock = AppBaseLogDebugBlock; cb->DB_DebugEndBlock = AppBaseLogDebugEndBlock; cb->DB_DebugEndThread = AppBaseLogDebugEndThread; cb->DB_DebugExotic = AppBaseLogDebugExotic; #endif if (fDBApiConfig_Data.Connect(fDBAPIModule_Data.c_str(), getSyncAppBase()->fApiInterModuleContext, getName(), false, allowDLL)!=LOCERR_OK) SYSYNC_THROW(TConfigParseException("Cannot connect to datastore implementation module specified in ")); // now pass plugin-specific config if (fDBApiConfig_Data.PluginParams(fPluginParams_Data.fConfigString.c_str())!=LOCERR_OK) SYSYNC_THROW(TConfigParseException("Module does not understand params passed in ")); // Check module capabilities TDB_Api_Str capa; fDBApiConfig_Data.Capabilities(capa); string capaStr = capa.c_str(); // - check existence of DeleteSyncSet() fHasDeleteSyncSet = FlagOK(capaStr,CA_DeleteSyncSet,true); // - Check for new method for data access (as keys instead of as text items) fItemAsKey = FlagOK(capaStr,CA_ItemAsKey,true); // - Allow module to choose whether it wants to support suspend/resume. fResumeSupported = FlagOK(capaStr,CA_ResumeSupported,true); // Check if engine is compatible #ifndef DBAPI_TEXTITEMS if (!fItemAsKey) SYSYNC_THROW(TConfigParseException("This engine does not support data items in text format")); #endif #if !defined(DBAPI_ASKEYITEMS) || !defined(ENGINEINTERFACE_SUPPORT) if (fItemAsKey) SYSYNC_THROW(TConfigParseException("This engine does not support data items passed as key handles")); #endif } // connect module for handling admin access // - use same module and params as data if no separate module specified and plugin_datastoreadmin is set if (fDBAPIModule_Admin.empty() && fDataModuleAlsoHandlesAdmin) { fDBAPIModule_Admin=fDBAPIModule_Data; fPluginParams_Admin=fPluginParams_Data; fPluginDbgMask_Admin=fPluginDbgMask_Data; } // - now connect the admin module if (!fDBAPIModule_Admin.empty()) { // we have a module specified for data access DB_Callback cb= &fDBApiConfig_Admin.fCB.Callback; cb->callbackRef = getSyncAppBase(); #ifdef ENGINEINTERFACE_SUPPORT cb->thisBase = getSyncAppBase()->fEngineInterfaceP; #endif #ifdef SYDEBUG // direct Module level debug to global log cb->debugFlags= (getSyncAppBase()->getRootConfig()->fDebugConfig.fGlobalDebugLogs) && PDEBUGTEST(DBG_ADMIN+DBG_DBAPI+DBG_PLUGIN) ? fPluginDbgMask_Admin : 0; cb->DB_DebugPuts = AppBaseLogDebugPuts; cb->DB_DebugBlock = AppBaseLogDebugBlock; cb->DB_DebugEndBlock = AppBaseLogDebugEndBlock; cb->DB_DebugEndThread= AppBaseLogDebugEndThread; cb->DB_DebugExotic = AppBaseLogDebugExotic; #endif if (fDBApiConfig_Admin.Connect(fDBAPIModule_Admin.c_str(),getSyncAppBase()->fApiInterModuleContext,getName())!=LOCERR_OK) SYSYNC_THROW(TConfigParseException("Cannot connect to datastore implementation module specified in ")); // now pass plugin-specific config if (fDBApiConfig_Admin.PluginParams(fPluginParams_Admin.fConfigString.c_str())!=LOCERR_OK) SYSYNC_THROW(TConfigParseException("Module does not understand params passed in ")); } } // resolve inherited inherited::localResolve(aLastPass); } // TPluginDSConfig::localResolve // - create appropriate datastore from config, calls addTypeSupport as well TLocalEngineDS *TPluginDSConfig::newLocalDataStore(TSyncSession *aSessionP) { // Synccap defaults to normal set supported by the engine by default TLocalEngineDS *ldsP; if (IS_CLIENT) { ldsP = new TPluginApiDS(this,aSessionP,getName(),aSessionP->getSyncCapMask() & ~(isOneWayFromRemoteSupported() ? 0 : SCAP_MASK_ONEWAY_SERVER)); } else { ldsP = new TPluginApiDS(this,aSessionP,getName(),aSessionP->getSyncCapMask() & ~(isOneWayFromRemoteSupported() ? 0 : SCAP_MASK_ONEWAY_CLIENT)); } // do common stuff addTypes(ldsP,aSessionP); // return return ldsP; } // TPluginDSConfig::newLocalDataStore /* * Implementation of TPluginApiDS */ // constructor TPluginApiDS::TPluginApiDS( TPluginDSConfig *aConfigP, sysync::TSyncSession *aSessionP, const char *aName, uInt32 aCommonSyncCapMask ) : #ifdef SDK_ONLY_SUPPORT TCustomImplDS(aConfigP,aSessionP, aName, aCommonSyncCapMask) #else TODBCApiDS(aConfigP,aSessionP, aName, aCommonSyncCapMask) #endif { // save a type casted pointer to the agent fPluginAgentP=static_cast(aSessionP); // save pointer to config record fPluginDSConfigP=aConfigP; // make a local copy of the typed agent pointer (note that the agent itself does // NOT YET have its constructor completely run so we can't just copy the agents pointer) fPluginAgentConfigP = DYN_CAST( aSessionP->getRootConfig()->fAgentConfigP ); if (!fPluginAgentConfigP) SYSYNC_THROW(TSyncException(DEBUGTEXT("TPluginApiDS finds no AgentConfig","api1"))); // Note: do not create context here because Agent is not yet initialized. // clear rest InternalResetDataStore(); } // TPluginApiDS::TPluginApiDS TPluginApiDS::~TPluginApiDS() { InternalResetDataStore(); } // TPluginApiDS::~TPluginApiDS /// @brief called while agent is still fully ok, so we must clean up such that later call of destructor does NOT access agent any more void TPluginApiDS::announceAgentDestruction(void) { // reset myself InternalResetDataStore(); // make sure we don't access the agent any more engTerminateDatastore(); fPluginAgentP = NULL; // destroy API context fDBApi_Data.DeleteContext(); fDBApi_Admin.DeleteContext(); // call inherited inherited::announceAgentDestruction(); } // TPluginApiDS::announceAgentDestruction /// @brief called to reset datastore /// @note must be safe to be called multiple times and even after announceAgentDestruction() void TPluginApiDS::InternalResetDataStore(void) { // filtering capabilities need to be evaluated first fAPICanFilter = false; fAPIFiltersTested = false; } // TPluginApiDS::InternalResetDataStore #ifdef DBAPI_TEXTITEMS // store API key/value pair field in mapped field, if one is defined bool TPluginApiDS::storeField( cAppCharP aName, cAppCharP aParams, cAppCharP aValue, TMultiFieldItem &aItem, uInt16 aSetNo, sInt16 aArrayIndex ) { TFieldMapList *fmlP = &(fPluginDSConfigP->fFieldMappings.fFieldMapList); TFieldMapList::iterator pos; TApiFieldMapItem *fmiP; string s; bool stored=false; // search field map list for matching map entry for (pos=fmlP->begin(); pos!=fmlP->end(); pos++) { fmiP = static_cast(*pos); // check name if ( fmiP->readable && fmiP->setNo==aSetNo && strucmp(fmiP->getName(),aName)==0 ) { // DB-readable field with matching name TDBFieldType dbfty = fmiP->dbfieldtype; TItemField *fieldP; sInt16 fid = fmiP->fid; // determine leaf field fieldP = getMappedFieldOrVar(aItem,fid,aArrayIndex); // continue only if we have a field if (!fieldP) continue; // check if the field is proxyable and input defines a BLOB id #ifdef STREAMFIELD_SUPPORT if (fieldP->isBasedOn(fty_string)) { // - check if params contain a BLOBID string blobid; if (paramScan(aParams,"BLOBID",blobid)) { // this field is a blob, create a proxy for it TApiBlobProxy *apiProxyP = new TApiBlobProxy(this,!fieldP->isBasedOn(fty_blob),blobid.c_str(),aItem.getLocalID()); // attach it to the string or blob field static_cast(fieldP)->setBlobProxy(apiProxyP); // check if we must read it right now if (paramScan(aParams,"READNOW",blobid)) static_cast(fieldP)->pullFromProxy(); // check next mapping continue; } } #endif // store according to database field type switch (dbfty) { case dbft_string: // for explicit strings, perform character set and line feed conversion s.erase(); // - convert from database charset to UTF-8 and to C-string linefeeds appendStringAsUTF8(aValue, s, fPluginDSConfigP->fDataCharSet, lem_cstr); fieldP->setAsString(s.c_str()); break; case dbft_blob: // blob is treated as 1:1 string if there's no proxy for it default: // for all other DB types, string w/o charset conversion is enough (these are by definition all single-line, ASCII-only) if (fieldP->isBasedOn(fty_timestamp)) { // interpret timestamps in dataTimeZone context (or as floating if this field is mapped in "f" mode) TTimestampField *tsfP = static_cast(fieldP); tsfP->setAsISO8601(aValue, fmiP->floating_ts ? TCTX_UNKNOWN : fPluginDSConfigP->fDataTimeZone, false); // modify time zone if params contain a TZNAME if (paramScan(aParams,"TZNAME",s)) { // convert to time zone context timecontext_t tctx; TimeZoneNameToContext(s.c_str(), tctx, tsfP->getGZones(), true); tsfP->moveToContext(tctx, true); // move to new context, bind floating (and float fixed, if TZNAME=FLOATING) } } else { // just set as string fieldP->setAsString(aValue); } break; } // switch // field successfully stored, do NOT exit loop // because there could be a second map for the same attribute! stored=true; } // if map found for attribute } // for all field mappings return stored; } // TPluginApiDS::storeField // - parse text data into item // Note: generic implementation, using virtual storeField() method // to differentiate between use with mapped fields in DBApi and // direct (unmapped) TMultiFieldItem access in Tunnel API. bool TPluginApiDS::parseDBItemData( TMultiFieldItem &aItem, cAppCharP aItemData, uInt16 aSetNo ) { bool stored = parseItemData(aItem,aItemData,aSetNo); if (stored) { // post-process stored = postReadProcessItem(aItem,aSetNo); } return stored; } // TPluginApiDS::parseItemData // generate text representations of item's fields (BLOBs and parametrized fields not included) // - returns true if at least one field appended bool TPluginApiDS::generateDBItemData( bool aAssignedOnly, TMultiFieldItem &aItem, uInt16 aSetNo, string &aDataFields ) { TFieldMapList *fmlP = &(fPluginDSConfigP->fFieldMappings.fFieldMapList); TFieldMapList::iterator pos; TApiFieldMapItem *fmiP; string val; bool createdone=false; // pre-process (run scripts) if (!preWriteProcessItem(aItem)) return false; // create text representation for all mapped and writable fields for (pos=fmlP->begin(); pos!=fmlP->end(); pos++) { fmiP = static_cast(*pos); if ( fmiP->writable && fmiP->setNo==aSetNo ) { // get field TItemField *basefieldP; sInt16 fid = fmiP->fid; // determine base field (might be array) basefieldP = getMappedBaseFieldOrVar(aItem,fid); if (generateItemFieldData( aAssignedOnly, fPluginDSConfigP->fDataCharSet, fPluginDSConfigP->fDataLineEndMode, fPluginDSConfigP->fDataTimeZone, basefieldP, fmiP->getName(), aDataFields )) createdone=true; // we now have at least one field } // if writable field } // for all field mappings PDEBUGPRINTFX(DBG_USERDATA+DBG_DBAPI+DBG_EXOTIC+DBG_HOT,("generateDBItemData generated string for DBApi:")); PDEBUGPUTSXX(DBG_USERDATA+DBG_DBAPI+DBG_EXOTIC,aDataFields.c_str(),0,true); return createdone; } // TPluginApiDS::generateDBItemData #endif // DBAPI_TEXTITEMS // - post process item after reading from DB (run script) bool TPluginApiDS::postReadProcessItem(TMultiFieldItem &aItem, uInt16 aSetNo) { #if defined(DBAPI_ASKEYITEMS) && defined(STREAMFIELD_SUPPORT) // for ItemKey mode, we need to create a BLOB proxy for each as_param mapped field if (fPluginDSConfigP->fItemAsKey) { // find all asParam fields that can have proxies and create BLOB proxies for these TFieldMapList *fmlP = &(fPluginDSConfigP->fFieldMappings.fFieldMapList); TFieldMapList::iterator pos; TApiFieldMapItem *fmiP; // post-process all mapped and writable fields for (pos=fmlP->begin(); pos!=fmlP->end(); pos++) { fmiP = static_cast(*pos); if ( fmiP->readable && fmiP->setNo==aSetNo ) { // get field TItemField *basefieldP, *leaffieldP; #ifdef ARRAYFIELD_SUPPORT uInt16 arrayIndex=0; #endif sInt16 fid = fmiP->fid; // determine base field (might be array) basefieldP = getMappedBaseFieldOrVar(aItem,fid); // ignore map if we have no field for it if (!basefieldP) continue; // We have a base field for this, check what to do if (fPluginDSConfigP->fUserZoneOutput && !fmiP->floating_ts && basefieldP->elementsBasedOn(fty_timestamp)) { // userzoneoutput requested for non-floating timestamp field, move it! #ifdef ARRAYFIELD_SUPPORT arrayIndex=0; #endif do { #ifdef ARRAYFIELD_SUPPORT if (basefieldP->isArray()) { leaffieldP = basefieldP->getArrayField(arrayIndex,true); // get existing leaf fields only arrayIndex++; } else leaffieldP = basefieldP; // leaf is base field // if no leaf field, we'll need to exit here (we're done with the array) if (leaffieldP==NULL) break; #else leaffieldP = basefieldP; // no arrays: leaf is always base field #endif static_cast(leaffieldP)->moveToContext(fSessionP->fUserTimeContext, false); } while(basefieldP->isArray()); // only arrays do loop all array elements } if (fmiP->as_param && basefieldP->elementsBasedOn(fty_string)) { // string based field (string or BLOB) mapped as parameter // unlike with textItems that get the BLOBID from the DB, // in asKey mode, BLOBID is just map name plus a possible array index. // Plugin must be able to identify the BLOB using this plus the item ID. // Plugin must also make sure an array element exists (value does not matter, can be empty) // for each element that should be proxied here. // - create the proxies (one for each array element) #ifdef ARRAYFIELD_SUPPORT arrayIndex=0; #endif do { // first check if there is an element at all string blobid = fmiP->getName(); // map name #ifdef ARRAYFIELD_SUPPORT if (basefieldP->isArray()) { leaffieldP = basefieldP->getArrayField(arrayIndex,true); // get existing leaf fields only StringObjAppendPrintf(blobid,"[%d]",arrayIndex); // add array index to blobid arrayIndex++; } else leaffieldP = basefieldP; // leaf is base field // if no leaf field, we'll need to exit here (we're done with the array) if (leaffieldP==NULL) break; #else leaffieldP = basefieldP; // no arrays: leaf is always base field #endif // this array element exists, create the proxy TApiBlobProxy *apiProxyP = new TApiBlobProxy(this,!leaffieldP->isBasedOn(fty_blob),blobid.c_str(),aItem.getLocalID()); // Note: we do not support "READNOW" proxies here, as they are useless in ItemKey context: if the // BLOB cannot be read later, no need for as_aparam map exists and plugin should just put the value // directly via the SetKeyValue() API. // attach proxy to the string or blob field static_cast(leaffieldP)->setBlobProxy(apiProxyP); } while(basefieldP->isArray()); // only arrays do loop all array elements } } // readable field mapping with explicit as_param mark } // for all field mappings } // if AsKey access #endif // DBAPI_ASKEYITEMS // execute afterread script now #ifdef SCRIPT_SUPPORT // process afterread script fPluginAgentP->fScriptContextDatastore=this; if (!TScriptContext::execute(fScriptContextP,fPluginDSConfigP->fFieldMappings.fAfterReadScript,fPluginDSConfigP->getDSFuncTableP(),fPluginAgentP,&aItem,true)) SYSYNC_THROW(TSyncException(" fatal error")); #endif // always ok for now %%% return true; } // TPluginApiDS::postReadProcessItem // - pre-process item before writing to DB (run script) bool TPluginApiDS::preWriteProcessItem(TMultiFieldItem &aItem) { #ifdef SCRIPT_SUPPORT // process beforewrite script fWriting=true; fDeleting=false; fParentKey=aItem.getLocalID(); fPluginAgentP->fScriptContextDatastore=this; if (!TScriptContext::execute(fScriptContextP,fPluginDSConfigP->fFieldMappings.fBeforeWriteScript,fPluginDSConfigP->getDSFuncTableP(),fPluginAgentP,&aItem,true)) SYSYNC_THROW(TSyncException(" fatal error")); #endif // always ok for now %%% return true; } // TPluginApiDS::preWriteProcessItem // - send BLOBs of this item one by one. Returns true if we have a blob at all bool TPluginApiDS::writeBlobs( bool aAssignedOnly, TMultiFieldItem &aItem, uInt16 aSetNo ) { TFieldMapList *fmlP = &(fPluginDSConfigP->fFieldMappings.fFieldMapList); TFieldMapList::iterator pos; TApiFieldMapItem *fmiP; string blobfieldname; bool blobwritten=false; TSyError dberr; // store all parametrized fields or BLOBs one by one for (pos=fmlP->begin(); pos!=fmlP->end(); pos++) { fmiP = static_cast(*pos); if ( fmiP->writable && fmiP->setNo==aSetNo ) { TItemField *basefieldP,*leaffieldP; sInt16 fid = fmiP->fid; // determine base field (might be array) basefieldP = getMappedBaseFieldOrVar(aItem,fid); // ignore map if we have no field for it if (!basefieldP) continue; // ignore map if field is not assigned and assignedonly flag is set if (aAssignedOnly && basefieldP->isUnassigned()) continue; // omit all non-BLOB normal fields // Note: in ItemKey mode, blobs must have the as_aparam flag to be written as blobs. // in textItem mode, all fty_blob based fields will ALWAYS be written as blobs. if (!(fmiP->as_param || (basefieldP->elementsBasedOn(fty_blob) && !fPluginDSConfigP->fItemAsKey))) continue; // yes, we want to write this field as a BLOB #ifdef ARRAYFIELD_SUPPORT uInt16 arrayIndex; for (arrayIndex=0; true; arrayIndex++) #endif { // first create BLOB ID blobfieldname=fmiP->getName(); #ifdef ARRAYFIELD_SUPPORT // append array index if this is an array field if (basefieldP->isArray()) { StringObjAppendPrintf(blobfieldname,"[%d]",arrayIndex); // calculate leaf field leaffieldP = basefieldP->getArrayField(arrayIndex,true); // get existing leaf fields only } else { leaffieldP = basefieldP; // leaf is base field } // if no leaf field, we'll need to exit here (we're done with the array) if (leaffieldP==NULL) break; #else leaffieldP = basefieldP; // leaf is base field #endif // Now write this BLOB or string field size_t maxBlobWriteBlockSz; size_t blobsize; void *bufferP = NULL; string strDB; bool isString = !leaffieldP->isBasedOn(fty_blob); if (!isString) { #ifdef STREAMFIELD_SUPPORT leaffieldP->resetStream(); // this might be the wrong place to do this ... blobsize = leaffieldP->getStreamSize(); maxBlobWriteBlockSz = 16000; // allocate buffer if (blobsize) bufferP = new unsigned char[blobsize>maxBlobWriteBlockSz ? maxBlobWriteBlockSz : blobsize]; #else // we cannot stream, but just read string contents blobsize = leaffieldP->getStringSize(); maxBlobWriteBlockSz = blobsize; // all at once bufferP = (void *) leaffieldP->getCStr(); // get pointer to string #endif } else { // is string -> first convert to DB charset blobsize = leaffieldP->getStringSize(); maxBlobWriteBlockSz = blobsize; string s; leaffieldP->getAsString(s); // convert to DB charset and linefeeds appendUTF8ToString( s.c_str(), strDB, fPluginDSConfigP->fDataCharSet, fPluginDSConfigP->fDataLineEndMode ); bufferP = (void *)strDB.c_str(); } SYSYNC_TRY { // now read from stream field and send to API bool first=true; bool last=false; size_t remaining=blobsize; size_t bytes,actualbytes; while (!last) { // it's the last block when we can write remaining bytes now last = remaining<=maxBlobWriteBlockSz; // calculate block size of this iteration bytes = last ? remaining : maxBlobWriteBlockSz; #ifdef STREAMFIELD_SUPPORT if (!isString) { // read these from the stream field actualbytes = leaffieldP->readStream(bufferP,bytes); // we need to read } else #endif { // we have it already in the buffer actualbytes = bytes; } if (actualbytesisArray()) break; #endif } // for all array elements } // if writable BLOB/parametrized field } // for all field mappings return blobwritten; } // TPluginApiDS::writeBlobs bool TPluginApiDS::deleteBlobs( bool aAssignedOnly, TMultiFieldItem &aItem, uInt16 aSetNo ) { TFieldMapList *fmlP = &(fPluginDSConfigP->fFieldMappings.fFieldMapList); TFieldMapList::iterator pos; TApiFieldMapItem *fmiP; string blobfieldname; bool blobdeleted=false; TSyError dberr; // store all parametrized fields or BLOBs one by one for (pos=fmlP->begin(); pos!=fmlP->end(); pos++) { fmiP = static_cast(*pos); if (fmiP->writable && fmiP->setNo==aSetNo) { // get field TItemField *basefieldP,*leaffieldP; sInt16 fid = fmiP->fid; // determine base field (might be array) basefieldP = getMappedBaseFieldOrVar(aItem,fid); // ignore map if we have no field for it if (!basefieldP) continue; // %%% what is this, obsolete?? // ignore map if field is not assigned and assignedonly flag is set //if (aAssignedOnly && basefieldP->isUnassigned()) continue; // omit all non-BLOB normal fields // Note: in ItemKey mode, blobs must have the as_aparam flag to be written as blobs. // in textItem mode, all fty_blob based fields will ALWAYS be written as blobs. if (!(fmiP->as_param || (basefieldP->elementsBasedOn(fty_blob) && !fPluginDSConfigP->fItemAsKey))) continue; // yes, we want to write this field as a BLOB #ifdef ARRAYFIELD_SUPPORT uInt16 arrayIndex; for (arrayIndex=0; true; arrayIndex++) #endif { // first create BLOB ID blobfieldname=fmiP->getName(); #ifdef ARRAYFIELD_SUPPORT // append array index if this is an array field if (basefieldP->isArray()) { StringObjAppendPrintf(blobfieldname,"[%d]",arrayIndex); // calculate leaf field leaffieldP= basefieldP->getArrayField(arrayIndex,true); // get existing leaf fields only } else { leaffieldP= basefieldP; // leaf is base field } // if no leaf field, we'll need to exit here (we're done with the array) if (leaffieldP==NULL) break; #else leaffieldP= basefieldP; // leaf is base field #endif SYSYNC_TRY { dberr= fDBApi_Data.DeleteBlob( aItem.getLocalID(),blobfieldname.c_str() ); if (dberr==LOCERR_NOTIMP) dberr= LOCERR_OK; // Not implemented is not an error if (dberr!=LOCERR_OK) SYSYNC_THROW(TSyncException("DBapi::DeleteBlob fatal error")); } SYSYNC_CATCH (...) SYSYNC_RETHROW; SYSYNC_ENDCATCH // we now have at least one field blobdeleted= true; #ifdef ARRAYFIELD_SUPPORT // non-array do not loop if (!basefieldP->isArray()) break; #endif } // for all array elements } // if writable BLOB/parametrized field } // for all field mappings return blobdeleted; } // TPluginApiDS::deleteBlobs /// returns true if DB implementation supports resume (saving of resume marks, alert code, pending maps, tempGUIDs) bool TPluginApiDS::dsResumeSupportedInDB(void) { if (fPluginDSConfigP->fDBApiConfig_Admin.Connected()) { // we can do resume if plugin supports it return fPluginDSConfigP->fResumeSupported && fPluginDSConfigP->fDBApiConfig_Admin.Version()>=sInt32(VE_InsertMapItem); } return inherited::dsResumeSupportedInDB(); } // TPluginApiDS::dsResumeSupportedInDB #ifdef OBJECT_FILTERING // - returns true if DB implementation can also apply special filters like CGI-options // /dr(x,y) etc. during fetching bool TPluginApiDS::dsOptionFilterFetchesFromDB(void) { #ifndef SDK_ONLY_SUPPORT // if we are not connected, let immediate ancestor check it (e.g. SQL/ODBC) if (!fDBApi_Data.Created()) return inherited::dsOptionFilterFetchesFromDB(); #endif #ifdef SYSYNC_TARGET_OPTIONS string rangeFilter,s; // check range filtering // - date start end rangeFilter = "daterangestart:"; TimestampToISO8601Str(s, fDateRangeStart, TCTX_UTC, false, false); rangeFilter += s.c_str(); // - date range end rangeFilter += "\r\ndaterangeend:"; TimestampToISO8601Str(s, fDateRangeEnd, TCTX_UTC, false, false); rangeFilter += s.c_str(); // %%% tbd: // - attachments inhibit // - size limit #if (!defined _MSC_VER || defined WINCE) && !defined(__GNUC__) #warning "attachments and limit filters not yet supported" #endif // - let plugin know and check (we can filter at DBlevel if plugin understands both start/end) rangeFilter += "\r\n"; bool canfilter = (fDBApi_Data.FilterSupport(rangeFilter.c_str())>=2) || (fDateRangeStart==0 && fDateRangeEnd==0); // no range can always be "filtered" // if we can filter, that's sufficient if (canfilter) return true; #else // there is no range ever: yes, we can filter return true; #endif // otherwise, let implementation test (not immediate anchestor, which is a different API like ODBC) return TCustomImplDS::dsOptionFilterFetchesFromDB(); } // TPluginApiDS::dsOptionFilterFetchesFromDB // - returns true if DB implementation can filter the standard filters // (LocalDBFilter, TargetFilter and InvisibleFilter) during database fetch // - otherwise, fetched items will be filtered after being read from DB. bool TPluginApiDS::dsFilteredFetchesFromDB(bool aFilterChanged) { #ifndef SDK_ONLY_SUPPORT // if we are not connected, let immediate ancestor check it (e.g. SQL/ODBC) // Note that this can happen when dsFilteredFetchesFromDB() is called via Alertscript to resolve filter dependencies // before the DS is actually connected. In this case, the return value is not checked so that's ok. // Before actually laoding or zapping the sync set this is called once again with connected data plugin. if (!fDBApi_Data.Created()) return inherited::dsFilteredFetchesFromDB(aFilterChanged); #endif if (aFilterChanged || !fAPIFiltersTested) { fAPIFiltersTested = true; // Anyway, let DBApi know (even if all filters are empty) string filters; // - local DB filter (=static filter, from config) filters = "staticfilter:"; filters += fLocalDBFilter.c_str(); // - dynamic sync set filter filters += "\r\ndynamicfilter:"; filters += fSyncSetFilter.c_str(); // - invisible filter (those that MATCH this filter should NOT be included) filters += "\r\ninvisiblefilter:"; filters += fPluginDSConfigP->fInvisibleFilter.c_str(); // - let plugin know and check (we can filter at DBlevel if plugin understands both start/end) filters += "\r\n"; fAPICanFilter = (fDBApi_Data.FilterSupport(filters.c_str())>=3) || (fLocalDBFilter.empty() && fSyncSetFilter.empty() && fPluginDSConfigP->fInvisibleFilter.empty()); // no filter set = we can "filter" } // if we can filter, that's sufficient if (fAPICanFilter) return true; // otherwise, let implementation test (not immediate anchestor, which might be a different API like ODBC) return TCustomImplDS::dsFilteredFetchesFromDB(aFilterChanged); } // TPluginApiDS::dsFilteredFetchesFromDB #endif // can return 508 to force a slow sync. Other errors abort the sync localstatus TPluginApiDS::apiEarlyDataAccessStart(void) { TSyError dberr = LOCERR_OK; if (fPluginDSConfigP->fEarlyStartDataRead) { // prepare dberr = apiPrepareReadSyncSet(); if (dberr==LOCERR_OK) { // start the reading phase anyway (to make sure call order is always StartRead/EndRead/StartWrite/EndWrite) dberr = fDBApi_Data.StartDataRead(fPreviousToRemoteSyncIdentifier.c_str(),fPreviousSuspendIdentifier.c_str()); if (dberr!=LOCERR_OK) { PDEBUGPRINTFX(DBG_ERROR,("apiEarlyDataAccessStart - DBapi::StartDataRead error: %hd",dberr)); } } } return dberr; } // prepare for reading the sync set localstatus TPluginApiDS::apiPrepareReadSyncSet(void) { TSyError dberr = LOCERR_OK; #ifdef BASED_ON_BINFILE_CLIENT if (binfileDSActive()) { // we need to create the context for the data plugin here, as loadAdminData is not called in BASED_ON_BINFILE_CLIENT case. dberr = connectDataPlugin(); if (dberr==LOCERR_OK) { if (!fDBApi_Data.Created()) { // - use datastore name as context name and link with session context dberr = fDBApi_Data.CreateContext( getName(), false, &(fPluginDSConfigP->fDBApiConfig_Data), "anydevice", // no real device key "singleuser", // no real user key NULL // no associated session level // fPluginAgentP->getDBApiSession() ); if (dberr==LOCERR_OK) { // make sure plugin now sees filters before starting to read sync set // Note: due to late instantiation of the data plugin, previous calls to engFilteredFetchesFromDB() were not // evaluated by the plugin, so we need to do that here explicitly once again engFilteredFetchesFromDB(false); } } } else if (dberr==LOCERR_NOTIMP) dberr=LOCERR_OK; // we just don't have a data plugin, that's ok } // binfile active #endif // BASED_ON_BINFILE_CLIENT return dberr; } // read sync set IDs and mod dates (and rest of data if technically unavoidable or // requested by aNeedAll) localstatus TPluginApiDS::apiReadSyncSet(bool aNeedAll) { TSyError dberr=LOCERR_OK; #ifdef SYDEBUG string ts1,ts2; #endif if (!fPluginDSConfigP->fEarlyStartDataRead) { // normal sequence, start data read is not called before starting to read the sync set dberr = apiPrepareReadSyncSet(); if (dberr!=LOCERR_OK) goto endread; } #ifndef SDK_ONLY_SUPPORT // only handle here if we are in charge - otherwise let ancestor handle it if (!fDBApi_Data.Created()) return inherited::apiReadSyncSet(aNeedAll); #endif // just let plugin know if we want data (if it actually does is the plugin's choice) if (aNeedAll) { // we'll need all data in the datastore in the end, let datastore know // Note: this is a suggestion to the plugin only - plugin does not need to follow it // and can return only ID/changed or all data for both states of this flag, // even changing on a item-by-item basis (can make sense for optimization). // The Plugin will return "1" here only in case it really follows the suggestion // an WILL return all data at ReadNextItem(). Otherwise, it may or may // not return data on a item by item basis (which is handled by the code // below). Therefore, at this time, the engine does not make use of the // ContextSupport() return value here. fDBApi_Data.ContextSupport("ReadNextItem:allfields\n\r"); } #ifdef SCRIPT_SUPPORT // process init script fParentKey.erase(); fWriting=false; fPluginAgentP->fScriptContextDatastore=this; if (!TScriptContext::executeTest(true,fScriptContextP,fPluginDSConfigP->fFieldMappings.fInitScript,fPluginDSConfigP->getDSFuncTableP(),fPluginAgentP)) { PDEBUGPRINTFX(DBG_ERROR,(" failed")); goto endread; } #endif // start reading // - read list of all local IDs that are in the current sync set DeleteSyncSet(); #ifdef SYDEBUG StringObjTimestamp(ts1,getPreviousToRemoteSyncCmpRef()); StringObjTimestamp(ts2,getPreviousSuspendCmpRef()); PDEBUGPRINTFX(DBG_DATA,( "Now reading local sync set: report changes since reference1 at %s, and since reference2 at %s", ts1.c_str(), ts2.c_str() )); #endif if (!fPluginDSConfigP->fEarlyStartDataRead) { // start the reading phase anyway (to make sure call order is always StartRead/EndRead/StartWrite/EndWrite) dberr = fDBApi_Data.StartDataRead(fPreviousToRemoteSyncIdentifier.c_str(),fPreviousSuspendIdentifier.c_str()); if (dberr!=LOCERR_OK) { PDEBUGPRINTFX(DBG_ERROR,("DBapi::StartDataRead fatal error: %hd",dberr)); goto endread; } } // we don't need to load the syncset if we are only refreshing from remote // but we also must load it if we can't zap without it on slow refresh, or when we can't retrieve items on non-slow refresh // (we won't retrieve anything in case of slow refresh, because after zapping there's nothing left by definition) if (!fRefreshOnly || (fRefreshOnly && fCacheData) || (fSlowSync && apiNeedSyncSetToZap()) || (!fSlowSync && implNeedSyncSetToRetrieve())) { SYSYNC_TRY { // true for initial ReadNextItem*() call, false later on bool firstReadNextItem=true; // read the items #if defined(DBAPI_ASKEYITEMS) && defined(ENGINEINTERFACE_SUPPORT) TMultiFieldItem *mfitemP = NULL; #endif #ifdef DBAPI_TEXTITEMS TDB_Api_Str itemData; #endif do { // read next item int itemstatus; TSyncSetItem *syncSetItemP=NULL; TDB_Api_ItemID itemAndParentID; // two API variants #if defined(DBAPI_ASKEYITEMS) && defined(ENGINEINTERFACE_SUPPORT) if (fPluginDSConfigP->fItemAsKey) { // ALWAYS prepare a multifield item, in case plugin wants to return data (it normally does not // unless queried with ContextSupport("ReadNextItem:allfields"), but it's a per-item decision // of the plugin itself (and probably overall optimization considerations for speed or memory) // if it wants to follow the recommendation set with "ReadNextItem:allfields". // Note: check for canCreateItemForRemote() should be always true now as loading syncset has been // moved within the progress of client sync session to a point where types ARE known. // Pre-3.2 engines however called this routine early so types could be unknown here. if (mfitemP==NULL && canCreateItemForRemote()) { mfitemP = (TMultiFieldItem *) newItemForRemote( ity_multifield ); } // as key (Note: will be functional key but w/o any fields in case we pass NULL item pointer) TDBItemKey *itemKeyP = newDBItemKey(mfitemP); dberr=fDBApi_Data.ReadNextItemAsKey(itemAndParentID, (KeyH)itemKeyP, itemstatus, firstReadNextItem); // check if plugin wrote something to our key. If so, we assume this is the item and save // it, EVEN IF we did not request getting item data. if (!itemKeyP->isWritten()) { // nothing in this item, forget it delete itemKeyP; // key first if (mfitemP) delete mfitemP; // then item if we had one at all mfitemP=NULL; } else { // got item, delete the key delete itemKeyP; // post-process (run scripts, create BLOB proxies if needed) postReadProcessItem(*mfitemP,0); } } else #endif #ifdef DBAPI_TEXTITEMS { // as text item dberr=fDBApi_Data.ReadNextItem(itemAndParentID, itemData, itemstatus, firstReadNextItem); } #else return LOCERR_WRONGUSAGE; // completely wrong usage - should never happen as compatibility is tested at module connect #endif firstReadNextItem=false; if (dberr!=LOCERR_OK) { PDEBUGPRINTFX(DBG_ERROR,("DBapi::ReadNextItem fatal error = %hd",dberr)); #if defined(DBAPI_ASKEYITEMS) && defined(ENGINEINTERFACE_SUPPORT) if (mfitemP) delete mfitemP; #endif goto endread; } // check if we have seen all items if (itemstatus==ReadNextItem_EOF) break; // we have received an item // - save returned data as item in the syncsetlist syncSetItemP = new TSyncSetItem; // - copy item object ID syncSetItemP->localid = itemAndParentID.item.c_str(); // - copy parent ID // %%% tbd, now empty syncSetItemP->containerid = ""; // - set modified status syncSetItemP->isModifiedAfterSuspend = itemstatus==ReadNextItem_Resumed; syncSetItemP->isModified = syncSetItemP->isModifiedAfterSuspend || itemstatus==ReadNextItem_Changed; #ifdef SYDEBUG PDEBUGPRINTFX(DBG_DATA+DBG_EXOTIC,( "read local item info in sync set: localid='%s'%s%s", syncSetItemP->localid.c_str(), syncSetItemP->isModified ? ", MODIFIED since reference1" : "", syncSetItemP->isModifiedAfterSuspend ? " AND since reference2" : "" )); #endif // no data yet, no item yet syncSetItemP->itemP = NULL; // two API variants #if defined(DBAPI_ASKEYITEMS) && defined(ENGINEINTERFACE_SUPPORT) if (fPluginDSConfigP->fItemAsKey) { // as key if (mfitemP) { // we have read some data syncSetItemP->itemP = mfitemP; mfitemP = NULL; // now owned by syncSetItem syncSetItemP->itemP->setLocalID(itemAndParentID.item.c_str()); } } else #endif #ifdef DBAPI_TEXTITEMS { // as text item // - if we have received actual item data already, create and store an item here if (!itemData.empty()) { // store data in new item now // - create new empty TMultiFieldItem syncSetItemP->itemP = (TMultiFieldItem *) newItemForRemote( ity_multifield ); // - set localid as we might need it for reading specials or arrays syncSetItemP->itemP->setLocalID(itemAndParentID.item.c_str()); // - read data into item parseItemData(*(syncSetItemP->itemP),itemData.c_str(),0); } } #else return LOCERR_WRONGUSAGE; // completely wrong usage - should never happen as compatibility is tested at module connect #endif // now save syncset item fSyncSetList.push_back(syncSetItemP); } while (true); } // try SYSYNC_CATCH (...) dberr=LOCERR_EXCEPTION; SYSYNC_ENDCATCH } else { PDEBUGPRINTFX(DBG_DATA+DBG_EXOTIC,("skipped reading sync set because of refresh-from-peer sync")); } // if we need the syncset at all endread: // then end read here if (dberr==LOCERR_OK) { dberr=fDBApi_Data.EndDataRead(); if (dberr!=LOCERR_OK) { PDEBUGPRINTFX(DBG_ERROR,("DBapi::EndDataRead failed, err=%hd",dberr)); } } return dberr; } // TPluginApiDS::apiReadSyncSet // Check if we need the syncset to zap bool TPluginApiDS::apiNeedSyncSetToZap(void) { #ifndef SDK_ONLY_SUPPORT // only handle here if we are in charge - otherwise let ancestor handle it if (!fDBApi_Data.Created()) return inherited::apiNeedSyncSetToZap(); #endif // only if we have deleteSyncSet on API level AND api can also apply all filters, we don't need the syncset to zap the datastore return !(fPluginDSConfigP->fHasDeleteSyncSet && engFilteredFetchesFromDB(false)); } // TPluginApiDS::apiNeedSyncSetToZap // Zap all data in syncset (note that everything outside the sync set will remain intact) localstatus TPluginApiDS::apiZapSyncSet(void) { #ifndef SDK_ONLY_SUPPORT // only handle here if we are in charge - otherwise let ancestor handle it if (!fDBApi_Data.Created()) return inherited::apiZapSyncSet(); #endif TSyError dberr = LOCERR_OK; // API must be able to process current filters in order to execute a zap - otherwise we would delete // more than the sync set defined by local filters. bool apiCanZap = engFilteredFetchesFromDB(false); if (apiCanZap) { // try to use plugin's specialized implementation dberr = fDBApi_Data.DeleteSyncSet(); apiCanZap = dberr!=LOCERR_NOTIMP; // API claims to be able to zap (but still might have failed with a DBerr in this case!) } // do it one by one if DeleteAllItems() is not implemented or plugin cannot apply current filters if (!apiCanZap) { dberr = zapSyncSetOneByOne(); } // return status return dberr; } // TPluginApiDS::apiZapSyncSet // fetch actual record from DB by localID. SyncSetItem might be passed to give additional information // such as containerid localstatus TPluginApiDS::apiFetchItem(TMultiFieldItem &aItem, bool aReadPhase, TSyncSetItem *aSyncSetItemP) { #ifndef SDK_ONLY_SUPPORT // only handle here if we are in charge - otherwise let ancestor handle it if (!fDBApi_Data.Created()) return inherited::apiFetchItem(aItem, aReadPhase, aSyncSetItemP); #endif TSyError dberr=LOCERR_OK; ItemID_Struct itemAndParentID; // set up item ID and parent ID itemAndParentID.item=(appCharP)aItem.getLocalID(); itemAndParentID.parent=const_cast(""); // two API variants #if defined(DBAPI_ASKEYITEMS) && defined(ENGINEINTERFACE_SUPPORT) if (fPluginDSConfigP->fItemAsKey) { // get key TDBItemKey *itemKeyP = newDBItemKey(&aItem); // let plugin use it to fill item dberr=fDBApi_Data.ReadItemAsKey(itemAndParentID,(KeyH)itemKeyP); if (itemKeyP->isWritten()) { // post-process (run scripts, create BLOB proxies if needed) postReadProcessItem(aItem,0); } // done with the key delete itemKeyP; } else #endif #ifdef DBAPI_TEXTITEMS { TDB_Api_Str itemData; // read the item in text form from the DB dberr=fDBApi_Data.ReadItem(itemAndParentID,itemData); if (dberr==LOCERR_OK) { // put it into aItem parseItemData(aItem,itemData.c_str(),0); } } #else return LOCERR_WRONGUSAGE; // completely wrong usage - should never happen as compatibility is tested at module connect #endif // return status return dberr; } // TPluginApiDS::apiFetchItem // start of write localstatus TPluginApiDS::apiStartDataWrite(void) { #ifndef SDK_ONLY_SUPPORT // only handle here if we are in charge - otherwise let ancestor handle it if (!fDBApi_Data.Created()) return inherited::apiStartDataWrite(); #endif TSyError dberr=fDBApi_Data.StartDataWrite(); if (dberr!=LOCERR_OK) { PDEBUGPRINTFX(DBG_ERROR,("DBapi::StartDataWrite returns dberr=%hd",dberr)); } return dberr; } // TPluginApiDS::apiStartDataWrite struct TPluginItemAux : public TSyncItemAux { #if defined(DBAPI_ASKEYITEMS) && defined(ENGINEINTERFACE_SUPPORT) TDBItemKey *fItemKeyP; #endif #ifdef DBAPI_TEXTITEMS string fItemData; #endif }; // add new item to datastore, returns created localID localstatus TPluginApiDS::apiAddItem(TMultiFieldItem &aItem, string &aLocalID) { #ifndef SDK_ONLY_SUPPORT // only handle here if we are in charge - otherwise let ancestor handle it if (!fDBApi_Data.Created()) return inherited::apiAddItem(aItem, aLocalID); #endif TSyError dberr=LOCERR_OK; TDB_Api_ItemID itemAndParentID; #ifdef SCRIPT_SUPPORT fInserting=true; // flag for script, we are inserting new record #endif TPluginItemAux *aux = static_cast(aItem.getAux(TSyncItem::PLUGIN_API)); if (aux) { // Continue operation. #if defined(DBAPI_ASKEYITEMS) && defined(ENGINEINTERFACE_SUPPORT) if (fPluginDSConfigP->fItemAsKey) { dberr=fDBApi_Data.InsertItemAsKey((KeyH)aux->fItemKeyP,"",itemAndParentID); if (dberr == LOCERR_AGAIN) return dberr; // done with the key delete aux->fItemKeyP; aux->fItemKeyP=NULL; } else #endif #ifdef DBAPI_TEXTITEMS { dberr=fDBApi_Data.InsertItem(aux->fItemData.c_str(),"",itemAndParentID); if (dberr == LOCERR_AGAIN) return dberr; } #else return LOCERR_WRONGUSAGE; #endif } else { // Two API variants for starting the operation. #if defined(DBAPI_ASKEYITEMS) && defined(ENGINEINTERFACE_SUPPORT) if (fPluginDSConfigP->fItemAsKey) { // preprocess if (!preWriteProcessItem(aItem)) return 510; // DB error // get key TDBItemKey *itemKeyP = newDBItemKey(&aItem); // let plugin use it to obtain data to write dberr=fDBApi_Data.InsertItemAsKey((KeyH)itemKeyP,"",itemAndParentID); if (dberr == LOCERR_AGAIN) { TPluginItemAux *aux=new TPluginItemAux; aux->fItemKeyP=itemKeyP; aItem.setAux(TSyncItem::PLUGIN_API, aux); return LOCERR_AGAIN; } // done with the key delete itemKeyP; } else #endif #ifdef DBAPI_TEXTITEMS { string itemData; generateDBItemData( false, // all fields, not only assigned ones aItem, 0, // we do not use different sets for now itemData // here we'll get the data ); // now insert main record dberr=fDBApi_Data.InsertItem(itemData.c_str(),"",itemAndParentID); if (dberr == LOCERR_AGAIN) { TPluginItemAux *aux=new TPluginItemAux; aux->fItemData=itemData; aItem.setAux(TSyncItem::PLUGIN_API, aux); return LOCERR_AGAIN; } } #else return LOCERR_WRONGUSAGE; // completely wrong usage - should never happen as compatibility is tested at module connect #endif } // now check result if (dberr==LOCERR_OK || dberr==DB_Conflict || dberr==DB_DataReplaced || dberr==DB_DataMerged) { // save new ID aLocalID = itemAndParentID.item.c_str(); aItem.setLocalID(aLocalID.c_str()); // make sure item itself has correct ID as well if (dberr!=DB_Conflict) { // now write all the BLOBs writeBlobs(false,aItem,0); #ifdef SCRIPT_SUPPORT // process overall afterwrite script fWriting=true; fInserting=true; fDeleting=false; fPluginAgentP->fScriptContextDatastore=this; if (!TScriptContext::execute(fScriptContextP,fPluginDSConfigP->fFieldMappings.fAfterWriteScript,fPluginDSConfigP->getDSFuncTableP(),fPluginAgentP,&aItem,true)) { PDEBUGPRINTFX(DBG_ERROR,(" failed")); dberr = LOCERR_WRONGUSAGE; } #endif } } // return status return dberr; } // TPluginApiDS::apiAddItem #ifdef SYSYNC_CLIENT /// finalize local ID (for datastores that can't efficiently produce these at insert) bool TPluginApiDS::dsFinalizeLocalID(string &aLocalID) { #ifndef SDK_ONLY_SUPPORT // only handle here if we are in charge - otherwise let ancestor handle it if (!fDBApi_Data.Created()) return inherited::dsFinalizeLocalID(aLocalID); #else // still check for DBAPi to be ready at this point, because when peer messes up protocol, we // can get here before the datastore has been initialized at all if (!fDBApi_Data.Created()) return false; // no dataset loaded -> all localids are final (from last session) #endif TDB_Api_Str finalizedID; localstatus sta = fDBApi_Data.FinalizeLocalID(aLocalID.c_str(),finalizedID); if (sta==LOCERR_OK && !finalizedID.empty()) { // pass modified ID back aLocalID = finalizedID.c_str(); // ID was updated return true; } // no change - ID is ok as-is return false; } // TPluginApiDS::dsFinalizeLocalID #endif // SYSYNC_CLIENT // update existing item in datastore, returns 404 if item not found localstatus TPluginApiDS::apiUpdateItem(TMultiFieldItem &aItem) { #ifndef SDK_ONLY_SUPPORT // only handle here if we are in charge - otherwise let ancestor handle it if (!fDBApi_Data.Created()) return inherited::apiUpdateItem(aItem); #endif TSyError dberr=LOCERR_OK; TDB_Api_ItemID updItemAndParentID; ItemID_Struct itemAndParentID; // set up item ID and parent ID itemAndParentID.item=(appCharP)aItem.getLocalID(); itemAndParentID.parent=const_cast(""); #ifdef SCRIPT_SUPPORT fInserting=false; // flag for script, we are updating, not inserting now #endif TPluginItemAux *aux = static_cast(aItem.getAux(TSyncItem::PLUGIN_API)); if (aux) { // Continue operation. #if defined(DBAPI_ASKEYITEMS) && defined(ENGINEINTERFACE_SUPPORT) if (fPluginDSConfigP->fItemAsKey) { dberr=fDBApi_Data.UpdateItemAsKey((KeyH)aux->fItemKeyP,itemAndParentID,updItemAndParentID); if (dberr == LOCERR_AGAIN) return dberr; // done with the key delete aux->fItemKeyP; aux->fItemKeyP=NULL; } else #endif #ifdef DBAPI_TEXTITEMS { dberr=fDBApi_Data.UpdateItem(aux->fItemData.c_str(),itemAndParentID,updItemAndParentID); if (dberr == LOCERR_AGAIN) return dberr; } #else return LOCERR_WRONGUSAGE; // completely wrong usage - should never happen as compatibility is tested at module connect #endif } else { // Two API variants for starting the operation. #if defined(DBAPI_ASKEYITEMS) && defined(ENGINEINTERFACE_SUPPORT) if (fPluginDSConfigP->fItemAsKey) { // preprocess if (!preWriteProcessItem(aItem)) return 510; // DB error // get key TDBItemKey *itemKeyP = newDBItemKey(&aItem); // let plugin use it to obtain data to write dberr=fDBApi_Data.UpdateItemAsKey((KeyH)itemKeyP,itemAndParentID,updItemAndParentID); if (dberr == LOCERR_AGAIN) { TPluginItemAux *aux=new TPluginItemAux; aux->fItemKeyP=itemKeyP; aItem.setAux(TSyncItem::PLUGIN_API, aux); return LOCERR_AGAIN; } // done with the key delete itemKeyP; } else #endif #ifdef DBAPI_TEXTITEMS { string itemData; generateDBItemData( true, // only assigned fields aItem, 0, // we do not use different sets for now itemData // here we'll get the data ); // now update main record dberr=fDBApi_Data.UpdateItem(itemData.c_str(),itemAndParentID,updItemAndParentID); if (dberr == LOCERR_AGAIN) { TPluginItemAux *aux=new TPluginItemAux; aux->fItemData=itemData; aItem.setAux(TSyncItem::PLUGIN_API, aux); return LOCERR_AGAIN; } } #else return LOCERR_WRONGUSAGE; // completely wrong usage - should never happen as compatibility is tested at module connect #endif } if (dberr==LOCERR_OK) { // check if ID has changed if (!updItemAndParentID.item.empty() && strcmp(updItemAndParentID.item.c_str(),aItem.getLocalID())!=0) { if (IS_SERVER) { // update item ID and Map dsLocalIdHasChanged(aItem.getLocalID(),updItemAndParentID.item.c_str()); } // - update in this item we have here as well aItem.setLocalID(updItemAndParentID.item.c_str()); aItem.updateLocalIDDependencies(); } // now write all the BLOBs writeBlobs(true,aItem,0); #ifdef SCRIPT_SUPPORT // process overall afterwrite script fWriting=true; fInserting=false; fDeleting=false; fPluginAgentP->fScriptContextDatastore=this; if (!TScriptContext::execute(fScriptContextP,fPluginDSConfigP->fFieldMappings.fAfterWriteScript,fPluginDSConfigP->getDSFuncTableP(),fPluginAgentP,&aItem,true)) { PDEBUGPRINTFX(DBG_ERROR,(" failed")); dberr = LOCERR_WRONGUSAGE; } #endif } // return status return dberr; } // TPluginApiDS::apiUpdateItem // delete existing item in datastore, returns 211 if not existing any more localstatus TPluginApiDS::apiDeleteItem(TMultiFieldItem &aItem) { #ifndef SDK_ONLY_SUPPORT // only handle here if we are in charge - otherwise let ancestor handle it if (!fDBApi_Data.Created()) return inherited::apiDeleteItem(aItem); #endif TSyError dberr=LOCERR_OK; // delete item dberr=fDBApi_Data.DeleteItem( aItem.getLocalID() ); if (dberr==LOCERR_OK) { deleteBlobs(true,aItem,0); // Item related blobs must be removed as well #ifdef SCRIPT_SUPPORT // process overall afterwrite script fWriting=true; fInserting=false; fDeleting=true; fPluginAgentP->fScriptContextDatastore=this; if (!TScriptContext::execute(fScriptContextP,fPluginDSConfigP->fFieldMappings.fAfterWriteScript,fPluginDSConfigP->getDSFuncTableP(),fPluginAgentP,&aItem,true)) { PDEBUGPRINTFX(DBG_ERROR,(" failed")); dberr = LOCERR_WRONGUSAGE; } #endif } // if // return status return dberr; } // TPluginApiDS::apiDeleteItem // - end DB data write sequence (but not yet admin data), returns DB-specific identifier for this sync (if any) localstatus TPluginApiDS::apiEndDataWrite(string &aThisSyncIdentifier) { #ifndef SDK_ONLY_SUPPORT // only handle here if we are in charge - otherwise let ancestor handle it if (!fDBApi_Data.Created()) return inherited::apiEndDataWrite(aThisSyncIdentifier); #endif // nothing special to do in ODBC case, as we do not have a separate sync identifier TDB_Api_Str newSyncIdentifier; TSyError sta = fDBApi_Data.EndDataWrite(true, newSyncIdentifier); aThisSyncIdentifier=newSyncIdentifier.c_str(); return sta; } // TPluginApiDS::apiEndDataWrite // must be called before starting a thread. If returns false, starting a thread now // is not allowed and must be postponed. // Includes ThreadMayChange() call bool TPluginApiDS::startingThread(void) { // %%% tbd: if modules are completely independent, we might not need this in all cases if (!dbAccessLocked()) { static_cast(fSessionP)->fApiLocked=true; // Now post possible thread change to the API // - on the database level ThreadMayChangeNow(); // - on the session level as well (to make sure, and because we will post a change back // at the end of the thread, which will be called FROM the new thread, which constitutes // executing something in the session context. static_cast(fSessionP)->getDBApiSession()->ThreadMayChangeNow(); return true; } else return false; } // TPluginApiDS::startingThread // - must be called when a thread's activity has ended // BUT THE CALL MUST BE FROM THE ENDING THREAD, not the main thread! void TPluginApiDS::endingThread(void) { // thread may change for the API now again // - on the database level ThreadMayChangeNow(); // - on the session level as well static_cast(fSessionP)->getDBApiSession()->ThreadMayChangeNow(); // Now other threads are allowed to access the API again static_cast(fSessionP)->fApiLocked=false; } // TPluginApiDS::endingThread // should be called before doing DB accesses that might be locked (e.g. because another thread is using the DB resources) bool TPluginApiDS::dbAccessLocked(void) { return static_cast(fSessionP)->fApiLocked; } // TPluginApiDS::dbAccessLocked // - alert possible thread change to plugins // Does not check if API is locked or not, see dsThreadMayChangeNow() void TPluginApiDS::ThreadMayChangeNow(void) { // let API know, thread might change for next request (but not necessarily does!) if (fDBApi_Data.Created()) fDBApi_Data.ThreadMayChangeNow(); if (fDBApi_Admin.Created()) fDBApi_Admin.ThreadMayChangeNow(); } // TPluginApiDS::ThreadMayChangeNow // - engine Thread might change void TPluginApiDS::dsThreadMayChangeNow(void) { // Do not post thread change infos when DB access is locked. // If it is locked, the thread that locked it will call a // ThreadMayChangeNow() to the API when the thread terminates (in endingThread()). if (!dbAccessLocked()) { ThreadMayChangeNow(); } // let ancestor do it's own stuff inherited::dsThreadMayChangeNow(); } // TPluginApiDS::dsThreadMayChangeNow // - connect data handling part of plugin, Returns LOCERR_NOTIMPL when no data plugin is selected // Note: this is either called as part of apiLoadAdminData (even if plugin is NOT responsible for data!) // or directly before startDataRead (in BASED_ON_BINFILE_CLIENT binfileDSActive() case) TSyError TPluginApiDS::connectDataPlugin(void) { TSyError err = LOCERR_NOTIMP; // filtering capabilities need to be reevaluated anyway fAPICanFilter = false; fAPIFiltersTested = false; // only connect if we have plugin data support if (fPluginDSConfigP->fDBApiConfig_Data.Connected()) { err = LOCERR_OK; DB_Callback cb= &fDBApi_Data.fCB.Callback; cb->callbackRef = fSessionP; // the session #ifdef ENGINEINTERFACE_SUPPORT cb->thisBase = fPluginDSConfigP->getSyncAppBase()->fEngineInterfaceP; #endif #ifdef SYDEBUG // Datastore Data access debug goes to session log cb->debugFlags = PDEBUGTEST(DBG_DATA+DBG_DBAPI+DBG_PLUGIN) ? 0xFFFF : 0; cb->DB_DebugPuts = SessionLogDebugPuts; cb->DB_DebugBlock = SessionLogDebugBlock; cb->DB_DebugEndBlock = SessionLogDebugEndBlock; cb->DB_DebugEndThread = SessionLogDebugEndThread; cb->DB_DebugExotic = SessionLogDebugExotic; #endif // SYDEBUG #ifdef ENGINEINTERFACE_SUPPORT // Data module can use Get/SetValue for "AsKey" routines and for session script var access // Note: these are essentially context free and work without a global call-in structure // (which is not necessarily there, for example in no-library case) CB_Connect_KeyAccess(cb); // connect generic key access routines // Version of OpenSessionKey that implicitly opens a key for the current session (DB plugins // do not have a session handle, as their use is always implicitly in a session context). cb->ui.OpenSessionKey = SessionOpenSessionKey; #endif // ENGINEINTERFACE_SUPPORT } return err; } // connectDataPlugin #ifndef BINFILE_ALWAYS_ACTIVE /// @brief save admin data /// Must save the following items: /// - fRemoteSyncAnchor = anchor string used by remote party for this session /// - fThisLocalAnchor = anchor (beginning of session) timestamp for this sync /// - fThisSync = timestamp for this sync (same as fThisLocalAnchor unless fSyncTimeStampAtEnd config is set) /// - fLastToRemoteLocalAnchor = timestamp for anchor (beginning of session) of last session that sent data to remote /// (same as fThisLocalAnchor unless we did a refrehs-from-remote session) /// - fLastToRemoteSync = timestamp for last session that sent data to remote /// (same as fThisSync unless we did a refresh-from-remote session) /// - fLastToRemoteSyncIdentifier = string identifying last session that sent data to remote (needs only be saved /// if derived datastore cannot work with timestamps and has its own identifier). /// - fMapTable = list containing map entries. For each entry the implementation must: /// - if changed==false: the entry hasn't been changed, so no DB operation is required /// - if changed==true and remoteid is not empty: /// - if added==true, add the entry as a new record to the DB /// - if added==false, update the entry in the DB with matching localid /// - if changed==true and remoteid is empty and added==false: delete the entry(s) in the DB with matching localid /// For resumable datastores (fConfigP->fResumeSupport==true): /// - fMapTable = In addition to the above, the markforresume flag must be saved in the mapflags // when it is not equal to the savedmark flag - independently of added/deleted/changed. /// - fResumeAlertCode = alert code of current suspend state, 0 if none /// - fPreviousSuspendCmpRef = reference time of last suspend (used to detect items modified during a suspend / resume) /// - fPreviousSuspendIdentifier = identifier of last suspend (used to detect items modified during a suspend / resume) /// (needs only be saved if derived datastore cannot work with timestamps and has /// its own identifier) /// /// For datastores that can resume in middle of a chunked item (fConfigP->fResumeItemSupport==true): /// - fPartialItemState = state of partial item (TPartialItemState enum): /// - if pi_state_none: save params, delete BLOB data (empty data) /// - if pi_state_save_incoming: save params+BLOB, save as in DB such that we will get pi_state_loaded_incoming when loaded again /// - if pi_state_save_outgoing: save params+BLOB, save as in DB such that we will get pi_state_loaded_outgoing when loaded again /// - if pi_state_loaded_incoming: no need to save, as params+BLOB have not changed since last save (but currently saved params+BLOB in DB must be retained) /// - if pi_state_loaded_outgoing: no need to save, as params+BLOB have not changed since last save (but currently saved params+BLOB in DB must be retained) /// /// - fLastItemStatus = status code (TSyError) of last item /// - fLastSourceURI = item ID (string, if limited in length should be long enough for large IDs, >=64 chars recommended) /// - fLastTargetURI = item ID (string, if limited in length should be long enough for large IDs, >=64 chars recommended) /// - fPITotalSize = uInt32, total item size /// - fPIUnconfirmedSize= uInt32, unconfirmed part of item size /// - fPIStoredSize = uInt32, size of BLOB to store, 0=none /// - fPIStoredDataP = void *, BLOB data, NULL if none /// /// @param aDataCommitted[in] indicates if data has been committed to the database already or not /// @param aSessionFinished[in] indicates if this is a final, end-of-session admin save (otherwise, it's only a resume state save) localstatus TPluginApiDS::apiSaveAdminData(bool aDataCommitted, bool aSessionFinished) { // security - don't use API when locked if (dbAccessLocked()) return 503; // service unavailable const char* PIStored = "PIStored"; // blob name field #ifndef SDK_ONLY_SUPPORT // only handle here if we are in charge - otherwise let ancestor handle it if (!fDBApi_Admin.Created()) return inherited::apiSaveAdminData(aDataCommitted, aSessionFinished); #endif localstatus sta=LOCERR_OK; TMapContainer::iterator pos; // save the entire map list differentially pos=fMapTable.begin(); PDEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,("apiSaveAdminData: internal map table has %ld entries (normal and others)",(long)fMapTable.size())); while (pos!=fMapTable.end()) { DEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,( "apiSaveAdminData: entryType=%s, localid='%s', remoteID='%s', mapflags=0x%lX, changed=%d, deleted=%d, added=%d, markforresume=%d, savedmark=%d", MapEntryTypeNames[(*pos).entrytype], (*pos).localid.c_str(), (*pos).remoteid.c_str(), (long)(*pos).mapflags, (int)(*pos).changed, (int)(*pos).deleted, (int)(*pos).added, (int)(*pos).markforresume, (int)(*pos).savedmark )); // check if item has changed since map table was read, or if its markforresume has changed // or if this is a successful end of a session, when we can safely assume that any pending maps // are from adds to the client that have never reached the client (otherwise, we'd have got // a map for it, even if the add was in a previous session or session attempt) if ( (*pos).changed || (*pos).added || (*pos).deleted || // update of DB needed ((*pos).markforresume!=(*pos).savedmark) // mark for resume changed ) { // make sure it does not get written again if not really modified again (*pos).changed=false; // update new mapflags w/o changing mapflag_useforresume in the actual flags (as we still need it while session goes on) uInt32 newmapflags = (*pos).mapflags & ~mapflag_useforresume; if ((*pos).markforresume) newmapflags |= mapflag_useforresume; // remember last saved state (*pos).savedmark=(*pos).markforresume; // do something! MapID_Struct mapid; mapid.ident=(int)(*pos).entrytype; mapid.localID=(char *)((*pos).localid.c_str()); mapid.remoteID=(char *)((*pos).remoteid.c_str()); mapid.flags=newmapflags; if ((*pos).deleted) { if (!(*pos).added) { // delete this entry (only needed if it was not also added since last save - otherwise, map entry was never saved to the DB yet) sta=fDBApi_Admin.DeleteMapItem(&mapid); if (sta!=LOCERR_OK) break; } // now remove it from the list, such that we don't try to delete it again TMapContainer::iterator delpos=pos++; // that's the next to have a look at fMapTable.erase(delpos); // remove it now continue; // pos is already updated } // deleted else if ((*pos).added) { // add a new entry sta=fDBApi_Admin.InsertMapItem(&mapid); if (sta!=LOCERR_OK) break; // is now added, don't add again later (*pos).added=false; } else { // explicitly changed or needs update because of resume mark or pendingmap flag // change existing entry sta=fDBApi_Admin.UpdateMapItem(&mapid); if (sta!=LOCERR_OK) break; } } // if something changed // anyway - reset mark for resume, it must be reconstructed before next save (*pos).markforresume=false; // next pos++; } // while if (sta!=LOCERR_OK) return sta; // collect admin data in a string string adminData,s; adminData.erase(); // add remote sync anchor adminData+="remotesyncanchor:"; StrToCStrAppend(fLastRemoteAnchor.c_str(),adminData,true); // allow 8-bit chars to be represented as-is (no \xXX escape needed) /* not needed any more // add local anchor adminData+="\r\nlastlocalanchor:"; timeStampToISO8601(fThisLocalAnchor,s,true,true); adminData+=s.c_str(); */ // add last sync time adminData+="\r\nlastsync:"; TimestampToISO8601Str(s, fPreviousSyncTime, TCTX_UTC, false, false); adminData+=s.c_str(); /* not needed any more // add local anchor of last sync with sending data to remote adminData+="\r\nlasttoremotelocalanchor:"; timeStampToISO8601(fLastToRemoteLocalAnchor,s,true,true); adminData+=s.c_str(); */ // add last to remote sync time adminData+="\r\nlasttoremotesync:"; TimestampToISO8601Str(s, fPreviousToRemoteSyncCmpRef, TCTX_UTC, false, false); adminData+=s.c_str(); // add identifier needed by datastore to identify records changes since last to-remote-sync if (fPluginDSConfigP->fStoreSyncIdentifiers) { adminData+="\r\nlasttoremotesyncid:"; StrToCStrAppend(fPreviousToRemoteSyncIdentifier.c_str(),adminData,true); // allow 8-bit chars to be represented as-is (no \xXX escape needed) } // add resume alert code adminData+="\r\nresumealertcode:"; StringObjAppendPrintf(adminData,"%hd",fResumeAlertCode); // add last suspend time adminData+="\r\nlastsuspend:"; TimestampToISO8601Str(s, fPreviousSuspendCmpRef, TCTX_UTC, false, false); adminData+=s.c_str(); // add identifier needed by datastore to identify records changes since last suspend if (fPluginDSConfigP->fStoreSyncIdentifiers) { adminData+="\r\nlastsuspendid:"; StrToCStrAppend(fPreviousSuspendIdentifier.c_str(),adminData,true); // allow 8-bit chars to be represented as-is (no \xXX escape needed) } /// For datastores that can resume in middle of a chunked item (fConfigP->fResumeItemSupport==true): void* blPtr = fPIStoredDataP; // position memSize blSize= fPIStoredSize; // actualbytes if (dsResumeChunkedSupportedInDB()) { /// - fPartialItemState = state of partial item (TPartialItemState enum): /// - if pi_state_none: save params, delete BLOB data (empty data) /// - if pi_state_save_incoming: save params+BLOB, save as in DB such that we will get pi_state_loaded_incoming when loaded again /// - if pi_state_save_outgoing: save params+BLOB, save as in DB such that we will get pi_state_loaded_outgoing when loaded again /// - if pi_state_loaded_incoming or /// pi_state_loaded_outgoing: no need to save, as params+BLOB have not changed since last save /// (but currently saved params+BLOB in DB must be retained) if ( fPartialItemState!=pi_state_loaded_incoming && fPartialItemState!=pi_state_loaded_outgoing ) { // and create the new status for these cases TPartialItemState pp= fPartialItemState; if (pp==pi_state_save_incoming) pp= pi_state_loaded_incoming; // adapt them before if (pp==pi_state_save_outgoing) pp= pi_state_loaded_outgoing; adminData+="\r\npartialitemstate:"; StringObjAppendPrintf( adminData,"%d",pp ); // - fLastItemStatus = status code (TSyError) of last item adminData+="\r\nlastitemstatus:"; StringObjAppendPrintf( adminData,"%hd",fLastItemStatus ); // - fLastSourceURI = item ID (string, if limited in length should be long enough for large IDs, >=64 chars recommended) adminData+="\r\nlastsourceURI:"; StrToCStrAppend( fLastSourceURI.c_str(), adminData,true ); // - fLastTargetURI = item ID (string, if limited in length should be long enough for large IDs, >=64 chars recommended) adminData+="\r\nlasttargetURI:"; StrToCStrAppend( fLastTargetURI.c_str(), adminData,true ); // - fPITotalSize = uInt32, total item size adminData+="\r\ntotalsize:"; StringObjAppendPrintf( adminData,"%ld", (long)fPITotalSize ); // - fPIUnconfirmedSize= uInt32, unconfirmed part of item size adminData+="\r\nunconfirmedsize:"; StringObjAppendPrintf( adminData,"%ld", (long)fPIUnconfirmedSize ); // - fPIStoredSize = uInt32, size of BLOB to store, store it as well to make ReadBlob easier (mallloc) adminData+="\r\nstoredsize:"; StringObjAppendPrintf( adminData,"%ld", (long)blSize ); // - fPIStoredSize = uInt32, size of BLOB to store, 0=none // - fPIStoredDataP = void *, BLOB data, NULL if none adminData+="\r\nstored;BLOBID="; adminData+= PIStored; } // if } // if // CRLF at end adminData+="\r\n"; // save admin data sta= fDBApi_Admin.SaveAdminData(adminData.c_str()); if (sta) return sta; // now write all the BLOBs, currently there is only the PIStored object of ResumeChunkedSupport if (dsResumeChunkedSupportedInDB()) { TPartialItemState pis= fPartialItemState; if ( blSize==0 && (pis==pi_state_save_incoming || pis==pi_state_save_outgoing) ) pis= pi_state_none; // delete blob, if size==0 // handle BLOB switch (pis) { // make sure BLOB is deleted when it is empty case pi_state_none: sta = fDBApi_Admin.DeleteBlob( "", // aItem.getLocalID() PIStored // blobfieldname.c_str() ); if (sta==DB_NotFound) sta= LOCERR_OK; // no error, if not existing break; // save BLOB contents case pi_state_save_incoming: // Write the whole BLOB at once case pi_state_save_outgoing: sta = fDBApi_Admin.WriteBlob ( "", // aItem.getLocalID() PIStored, // blobfieldname.c_str() blPtr, // bufferP blSize, // actualbytes blSize, // blobsize true, // first true // last ); break; case pi_state_loaded_incoming: case pi_state_loaded_outgoing: // do nothing, as the blob is saved already break; } // switch } // if return sta; } // TPluginApiDS::apiSaveAdminData /// @brief Load admin data from Plugin-implemented database /// Must search for existing target record matching the triple (aDeviceID,aDatabaseID,aRemoteDBID) /// - if there is a matching record: load it /// - if there is no matching record, set fFirstTimeSync=true. The implementation may already create a /// new record with the key (aDeviceID,aDatabaseID,aRemoteDBID) and initialize it with the data from /// the items as shown below. At least, fTargetKey must be set to a value that will allow apiSaveAdminData to /// update the record. In case implementation chooses not create the record only in apiSaveAdminData, it must /// buffer the triple (aDeviceID,aDatabaseID,aRemoteDBID) such that it is available at apiSaveAdminData. /// If a record exists implementation must load the following items: /// - fTargetKey = some key value that can be used to re-identify the target record later at SaveAdminData. /// If the database implementation has other means to re-identify the target, this can be /// left unassigned. /// - fLastRemoteAnchor = anchor string used by remote party for last session (and saved to DB then) /// - fPreviousSyncTime = anchor (beginning of session) timestamp of last session. /// - fPreviousToRemoteSyncCmpRef = Reference time to determine items modified since last time sending data to remote /// (or last changelog update in case of BASED_ON_BINFILE_CLIENT && binfileDSActive()) /// - fPreviousToRemoteSyncIdentifier = string identifying last session that sent data to remote /// (or last changelog update in case of BASED_ON_BINFILE_CLIENT && binfileDSActive()). Needs /// only be saved if derived datastore cannot work with timestamps and has its own identifier. /// - fMapTable = list containing map entries. The implementation must load all map entries /// related to the current sync target identified by the triple of (aDeviceID,aDatabaseID,aRemoteDBID) /// or by fTargetKey. The entries added to fMapTable must have "changed", "added" and "deleted" flags /// set to false. /// For resumable datastores (fConfigP->fResumeSupport==true): /// - fMapTable = In addition to the above, the markforresume flag must be saved in the mapflags // when it is not equal to the savedmark flag - independently of added/deleted/changed. /// - fResumeAlertCode = alert code of current suspend state, 0 if none /// - fPreviousSuspendCmpRef = reference time of last suspend (used to detect items modified during a suspend / resume) /// - fPreviousSuspendIdentifier = identifier of last suspend (used to detect items modified during a suspend / resume) /// (needs only be saved if derived datastore cannot work with timestamps and has /// its own identifier) /// - fPendingAddMaps = map. The implementation must load all all pending maps (client only) into /// fPendingAddMaps (and fUnconfirmedMaps must be left empty). /// - fTempGUIDMap = map. The implementation must save all entries as temporary LUID to GUID mappings /// (server only) /// /// For datastores that can resume in middle of a chunked item (fConfigP->fResumeItemSupport==true): /// - fPartialItemState = state of partial item (TPartialItemState enum): /// - after load, value must always be pi_state_none, pi_state_loaded_incoming or pi_state_loaded_outgoing. /// - pi_state_save_xxx MUST NOT be set after loading (see apiSaveAdminData comments) /// - fLastItemStatus = status code (TSyError) of last item /// - fLastSourceURI = item ID (string, if limited in length should be long enough for large IDs, >=64 chars recommended) /// - fLastTargetURI = item ID (string, if limited in length should be long enough for large IDs, >=64 chars recommended) /// - fPITotalSize = uInt32, total item size /// - fPIUnconfirmedSize= uInt32, unconfirmed part of item size /// - fPIStoredSize = uInt32, size of BLOB, 0=none /// - fPIStoredDataP = void *, BLOB data. /// - If this is not NULL on entry AND fPIStoredDataAllocated is set, /// the current block must be freed using smlLibFree() (and NOT JUST free()!!). /// - If no BLOB is loaded, this must be set to NULL /// - If a BLOB is loaded, an appropriate memory block should be allocated for it /// using smlLibMalloc() (and NOT JUST malloc()!!) /// - fPIStoredDataAllocated: MUST BE SET to true when a memory block was allocated into fPIStoredDataP. /// @param aDeviceID[in] remote device URI (device ID) /// @param aDatabaseID[in] local database ID /// @param aRemoteDBID[in] database ID of remote device localstatus TPluginApiDS::apiLoadAdminData( const char *aDeviceID, const char *aDatabaseID, const char *aRemoteDBID ) { // security - don't use API when locked if (dbAccessLocked()) return 503; // service unavailable const char* PIStored = "PIStored"; // blob name field TSyError err = LOCERR_OK; // In any case - this is the time to create the contexts for the datastore // - admin if selected if (fPluginDSConfigP->fDBApiConfig_Admin.Connected()) { DB_Callback cb= &fDBApi_Admin.fCB.Callback; cb->callbackRef = fSessionP; // the session #ifdef ENGINEINTERFACE_SUPPORT cb->thisBase = fSessionP->getSyncAppBase()->fEngineInterfaceP; #endif #ifdef SYDEBUG // Datastore Admin debug goes to session log cb->debugFlags = PDEBUGTEST(DBG_ADMIN+DBG_DBAPI+DBG_PLUGIN) ? 0xFFFF : 0; cb->DB_DebugPuts = SessionLogDebugPuts; cb->DB_DebugBlock = SessionLogDebugBlock; cb->DB_DebugEndBlock = SessionLogDebugEndBlock; cb->DB_DebugEndThread = SessionLogDebugEndThread; cb->DB_DebugExotic = SessionLogDebugExotic; #endif // SYDEBUG #ifdef ENGINEINTERFACE_SUPPORT // Admin module can use Get/SetValue for session script var access // Note: these are essentially context free and work without a global call-in structure // (which is not necessarily there, for example in no-library case) CB_Connect_KeyAccess(cb); // connect generic key access routines // Version of OpenSessionKey that implicitly opens a key for the current session (DB plugins // do not have a session handle, as their use is always implicitly in a session context). cb->ui.OpenSessionKey = SessionOpenSessionKey; #endif // ENGINEINTERFACE_SUPPORT if (!fDBApi_Admin.Created()) { // - use datastore name as context name and link with session context err= fDBApi_Admin.CreateContext( getName(), true, &(fPluginDSConfigP->fDBApiConfig_Admin), fPluginAgentP->fDeviceKey.c_str(), fPluginAgentP->fUserKey.c_str(), fPluginAgentP->getDBApiSession() ); } if (err!=LOCERR_OK) SYSYNC_THROW(TSyncException("Error creating context for plugin module handling admin",err)); } // - data if selected err = connectDataPlugin(); if (err==LOCERR_OK) { if (!fDBApi_Data.Created()) { // - use datastore name as context name and link with session context err= fDBApi_Data.CreateContext( getName(), false, &(fPluginDSConfigP->fDBApiConfig_Data), fPluginAgentP->fDeviceKey.c_str(), fPluginAgentP->fUserKey.c_str(), fPluginAgentP->getDBApiSession() ); } } else if (err==LOCERR_NOTIMP) err=LOCERR_OK; // we just don't have a data plugin, that's ok, inherited (SQL) will handle data if (err!=LOCERR_OK) SYSYNC_THROW(TSyncException("Error creating context for plugin module handling data",err)); // Perform actual loading of admin data #ifndef SDK_ONLY_SUPPORT // only handle here if we are in charge - otherwise let ancestor handle it if (!fDBApi_Admin.Created()) return inherited::apiLoadAdminData(aDeviceID, aDatabaseID, aRemoteDBID); #endif // find and read (or create) the admin data TDB_Api_Str adminData; err=fDBApi_Admin.LoadAdminData(aDatabaseID,aRemoteDBID,adminData); if (err==404) { // this means that this admin data set did not exists before fFirstTimeSync=true; } else if (err!=LOCERR_OK) return err; // failed else fFirstTimeSync=false; // we already have admin data, so it can't be first sync // parse data const char *p = adminData.c_str(); // second check: if empty adminData returned, this is treated as first sync as well if (*p==0) fFirstTimeSync=true; const char *q; string fieldname,value; lineartime_t *ltP; string *strP; uInt16 *usP; uInt32 *ulP; // read all fields while(*p) { // find name for (q=p; *q && (*q!=':' && *q!=';');) q++; fieldname.assign(p,q-p); p=q; // p should now point to ':' or ';' if (*p==':' || *p==';') { p++; // consume colon or semicolon // get value value.erase(); p += CStrToStrAppend(p, value, true); // stop at quote or ctrl char // analyze and store now // - no storage location found yet ltP=NULL; strP=NULL; usP=NULL; ulP=NULL; // - find where we need to store this if (strucmp(fieldname.c_str(),"remotesyncanchor")==0) { strP=&fLastRemoteAnchor; } else if (strucmp(fieldname.c_str(),"lastsync")==0) { ltP=&fPreviousSyncTime; } else if (strucmp(fieldname.c_str(),"lasttoremotesync")==0) { ltP=&fPreviousToRemoteSyncCmpRef; } else if (strucmp(fieldname.c_str(),"lasttoremotesyncid")==0) { strP=&fPreviousToRemoteSyncIdentifier; } else if (strucmp(fieldname.c_str(),"resumealertcode")==0) { usP=&fResumeAlertCode; } else if (strucmp(fieldname.c_str(),"lastsuspend")==0) { ltP=&fPreviousSuspendCmpRef; } else if (strucmp(fieldname.c_str(),"lastsuspendid")==0) { strP=&fPreviousSuspendIdentifier; } /// For datastores that can resume in middle of a chunked item (fConfigP->fResumeItemSupport==true): else { if (dsResumeChunkedSupportedInDB()) { if (strucmp(fieldname.c_str(),"partialitemstate")==0) { usP = (TSyError*)&fPartialItemState; // enum } else if (strucmp(fieldname.c_str(),"lastitemstatus")==0) { usP= &fLastItemStatus; // status code (TSyError) of last item } else if (strucmp(fieldname.c_str(),"lastsourceURI" )==0) { strP= &fLastSourceURI; // item ID (string, if limited in len should be long enough for large IDs, >=64 chars recommended) } else if (strucmp(fieldname.c_str(),"lasttargetURI" )==0) { strP= &fLastTargetURI; // item ID (string, if limited in len should be long enough for large IDs, >=64 chars recommended) } else if (strucmp(fieldname.c_str(),"totalsize" )==0) { ulP= &fPITotalSize; // uInt32, total item size } else if (strucmp(fieldname.c_str(),"unconfirmedsize")==0) { ulP= &fPIUnconfirmedSize; // uInt32, unconfirmed part of item size } else if (strucmp(fieldname.c_str(),"storedsize")==0) { ulP= &fPIStoredSize; // uInt32, size of BLOB, 0=none } /// - fPIStoredDataP = void *, BLOB data. /// - If this is not NULL on entry AND fPIStoredDataAllocated is set, /// the current block must be freed using smlLibFree() (and NOT JUST free()!!). /// - If no BLOB is loaded, this must be set to NULL /// - If a BLOB is loaded, an appropriate memory block should be allocated for it /// using smlLibMalloc() (and NOT JUST malloc()!!) /// - fPIStoredDataAllocated: MUST BE SET to true when a memory block was allocated into fPIStoredDataP. else if (strucmp(fieldname.c_str(),"stored")==0) { if ( fPIStoredDataP!=NULL && fPIStoredDataAllocated ) smlLibFree(fPIStoredDataP); fPIStoredDataP= NULL; fPIStoredDataAllocated= false; TDB_Api_Blk b; memSize totSize; bool last; if (fPIStoredSize>0) { fPIStoredDataP= smlLibMalloc( fPIStoredSize ); // now prepare for the full blob fPIStoredDataAllocated= true; unsigned char* dp = (unsigned char*)fPIStoredDataP; unsigned char* lim = dp + fPIStoredSize; bool first= true; do { err= fDBApi_Admin.ReadBlob( "", // fParentObjectID.c_str(), // the item ID PIStored, // fBlobID.c_str(), // the ID of the blob 0, // neededBytes, // how much we need b, // blobData, // blob data totSize, // totalsize, // will receive total size or 0 if unknown first, // first, last // last ); if (err) break; memSize rema= b.fSize; if (dp+rema > lim) rema= lim-dp; // avoid overflow memcpy( dp, b.fPtr, rema ); dp+= rema; fDBApi_Admin.DisposeBlk( b ); // we have now a copy => remove it first= false; } while (!last); } // if } } // if (dsResume ...) } // if // - store if (strP) { // - is a string (*strP) = value; } else if (usP) { // - is a uInt16 StrToUShort(value.c_str(),*usP); } else if (ulP) { // - is a uInt32 StrToULong(value.c_str(),*ulP); } else if (ltP) { // - is a ISO8601 lineartime_t tim; timecontext_t tctx; if (ISO8601StrToTimestamp(value.c_str(), tim, tctx)!=0) { // converted ok, now make sure we get UTC TzConvertTimestamp(tim,tctx,TCTX_UTC,getSessionZones(),fPluginDSConfigP->fDataTimeZone); *ltP=tim; } else { // no valid date/time = empty *ltP=0; } } } // skip everything up to next end of line (in case value was terminated by a quote or other ctrl char) while (*p && *p!='\r' && *p!='\n') p++; // skip all line end chars up to beginning of next line or end of record while (*p && (*p=='\r' || *p=='\n')) p++; // p now points to next line's beginning }; // then read maps bool firstEntry=true; fMapTable.clear(); TDB_Api_MapID mapid; TMapEntry mapEntry; while (fDBApi_Admin.ReadNextMapItem(mapid, firstEntry)) { // get entry mapEntry.localid=mapid.localID.c_str(); mapEntry.remoteid=mapid.remoteID.c_str(); mapEntry.mapflags=mapid.flags; // check for old API which did not support entry types if (fPluginDSConfigP->fDBApiConfig_Admin.Version()=numMapEntryTypes) mapEntry.entrytype = mapentry_invalid; else mapEntry.entrytype = (TMapEntryType)mapid.ident; } PDEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,( "read map entry (type=%s): localid='%s', remoteid='%s', mapflags=0x%lX", MapEntryTypeNames[mapEntry.entrytype], mapEntry.localid.c_str(), mapEntry.remoteid.c_str(), (long)mapEntry.mapflags )); // save entry in list mapEntry.changed=false; // not yet changed mapEntry.added=false; // already there // remember saved state of suspend mark mapEntry.markforresume=false; // not yet marked for this session (mark of last session is in mapflag_useforresume!) mapEntry.savedmark=mapEntry.mapflags & mapflag_useforresume; // IMPORTANT: non-normal entries must be saved as deleted in the main map - they will be re-activated at the // next save if needed mapEntry.deleted = mapEntry.entrytype!=mapentry_normal; // only normal ones may be saved as existing in the main map // save to main map list anyway to allow differential updates to map table (instead of writing everything all the time) fMapTable.push_back(mapEntry); // now save special maps to extra lists according to type // Note: in the main map, these are marked deleted. Before the next saveAdminData, these will // be re-added (=re-activated) from the extra lists if they still exist. switch (mapEntry.entrytype) { #ifdef SYSYNC_SERVER case mapentry_tempidmap: if (IS_SERVER) { PDEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,( "fTempGUIDMap: restore mapping from %s to %s", mapEntry.remoteid.c_str(), mapEntry.localid.c_str() )); fTempGUIDMap[mapEntry.remoteid]=mapEntry.localid; // tempGUIDs are accessed by remoteID=tempID } break; #endif #ifdef SYSYNC_CLIENT case mapentry_pendingmap: if (IS_CLIENT) fPendingAddMaps[mapEntry.localid]=mapEntry.remoteid; break; #endif case mapentry_invalid: case mapentry_normal: case numMapEntryTypes: default: // nothing to do or should not occur break; } // next is not first entry any more firstEntry=false; } return LOCERR_OK; } // TPluginApiDS::apiLoadAdminData #endif // not BINFILE_ALWAYS_ACTIVE /// @brief log datastore sync result, called at end of sync with this datastore /// Available log information is: /// - fCurrentSyncTime : timestamp of start this sync session (anchor time) /// - fCurrentSyncCmpRef : timestamp used by next session to detect changes since this one /// (end of session time of last session that send data to remote) /// - fTargetKey : string, identifies target (user/device/datastore/remotedatastore)-tuple /// - fSessionP->fUserKey : string, identifies user /// - fSessionP->fDeviceKey : string, identifies device /// - fSessionP->fDomainName : string, identifies domain (aka clientID, aka enterpriseID) /// - getName() : string, local datastore's configured name (such as "contacts", "events" etc.) /// - getRemoteDBPath() : string, remote datastore's path (things like EriCalDB or "Z:\System\Contacts.cdb") /// - getRemoteViewOfLocalURI() : string, shows how remote specifies local datastore URI (including cgi, or /// in case of symbian "calendar", this can be different from getName(), as "calendar" /// is internally split-processed by "events" and "tasks". /// - fSessionP->getRemoteURI() : string, remote Device URI (usually IMEI or other globally unique ID) /// - fSessionP->getRemoteDescName() : string, remote Device's descriptive name (constructed from DevInf and , or /// as set by 's . /// - fSessionP->getRemoteInfoString() : string, Remote Device Version Info ("Type (HWV, FWV, SWV) Oem") /// - fSessionP->getSyncUserName() : string, User name as sent by the device /// - fSessionP->getLocalSessionID() : string, the local session ID (the one that is used to construct log file names) /// - fAbortStatusCode : TSyError, if == 0, sync with this datastore was ok, if <>0, there was an error. /// - fSessionP->getAbortReasonStatus() : TSyError, shows status of entire session at the point when datastore finishes syncing. /// - fSyncMode : TSyncModes, (smo_twoway,smo_fromserver,smo_fromclient) /// - isSlowSync() : boolean, true if slow sync (or refresh from sync, which is a one-way-slow-sync) /// - isFirstTimeSync() : boolean, true if first time sync of this device with this datastore /// - isResuming() : boolean, true if this is a resumed session /// - SyncMLVerDTDNames[fSessionP->getSyncMLVersion()] : SyncML version string ("1.0", "1.1". "1.2" ...) /// - fLocalItemsAdded : number of locally added Items /// - fRemoteItemsAdded : number of remotely added Items /// - fLocalItemsDeleted : number of locally deleted Items /// - fRemoteItemsDeleted : number of remotely deleted Items /// - fLocalItemsError : number of locally rejected Items (caused error to be sent to remote) /// - fRemoteItemsError : number of remotely rejected Items (returned error, will be resent) /// - fLocalItemsUpdated : number of locally updated Items /// - fRemoteItemsUpdated : number of remotely updated Items /// - fSlowSyncMatches : number of items matched in Slow Sync /// - fConflictsServerWins : number of server won conflicts /// - fConflictsClientWins : number of client won conflicts /// - fConflictsDuplicated : number of conflicts solved by duplicating item /// - fSessionP->getIncomingBytes() : total number of incoming bytes in this session so far /// - fSessionP->getOutgoingBytes() : total number of outgoing bytes in this session so far /// - fIncomingDataBytes : net incoming data bytes for this datastore (= payload data, without SyncML protocol overhead) /// - fOutgoingDataBytes : net outgoing data bytes for this datastore (= payload data, without SyncML protocol overhead) void TPluginApiDS::dsLogSyncResult(void) { // security - don't use API when locked if (dbAccessLocked()) return; // format for DB Api string logData,s; logData.erase(); logData+="lastsync:"; TimestampToISO8601Str(s,fCurrentSyncTime,TCTX_UTC); logData+=s.c_str(); logData+="\r\ntargetkey:"; StrToCStrAppend(fTargetKey.c_str(),logData,true); #ifndef BINFILE_ALWAYS_ACTIVE logData+="\r\nuserkey:"; StrToCStrAppend(fPluginAgentP->fUserKey.c_str(),logData,true); logData+="\r\ndevicekey:"; StrToCStrAppend(fPluginAgentP->fDeviceKey.c_str(),logData,true); #ifdef SCRIPT_SUPPORT logData+="\r\ndomain:"; StrToCStrAppend(fPluginAgentP->fDomainName.c_str(),logData,true); #endif #endif // BINFILE_ALWAYS_ACTIVE logData+="\r\ndsname:"; StrToCStrAppend(getName(),logData,true); #ifndef MINIMAL_CODE logData+="\r\ndsremotepath:"; StrToCStrAppend(getRemoteDBPath(),logData,true); #endif logData+="\r\ndslocalpath:"; StrToCStrAppend(getRemoteViewOfLocalURI(),logData,true); logData+="\r\nfolderkey:"; StrToCStrAppend(fFolderKey.c_str(),logData,true); logData+="\r\nremoteuri:"; StrToCStrAppend(fSessionP->getRemoteURI(),logData,true); logData+="\r\nremotedesc:"; StrToCStrAppend(fSessionP->getRemoteDescName(),logData,true); logData+="\r\nremoteinfo:"; StrToCStrAppend(fSessionP->getRemoteInfoString(),logData,true); logData+="\r\nremoteuser:"; StrToCStrAppend(fSessionP->getSyncUserName(),logData,true); logData+="\r\nsessionid:"; StrToCStrAppend(fSessionP->getLocalSessionID(),logData,true); logData+="\r\nsyncstatus:"; StringObjAppendPrintf(logData,"%hd",fAbortStatusCode); logData+="\r\nsessionstatus:"; StringObjAppendPrintf(logData,"%hd",fSessionP->getAbortReasonStatus()); logData+="\r\nsyncmlvers:"; StrToCStrAppend(SyncMLVerDTDNames[fSessionP->getSyncMLVersion()],logData,true); logData+="\r\nsyncmode:"; StringObjAppendPrintf(logData,"%hd",(uInt16)fSyncMode); logData+="\r\nsynctype:"; StringObjAppendPrintf(logData,"%d",(fSlowSync ? (fFirstTimeSync ? 2 : 1) : 0) + (isResuming() ? 10 : 0)); logData+="\r\nlocaladded:"; StringObjAppendPrintf(logData,"%ld",(long)fLocalItemsAdded); logData+="\r\ndeviceadded:"; StringObjAppendPrintf(logData,"%ld",(long)fRemoteItemsAdded); logData+="\r\nlocaldeleted:"; StringObjAppendPrintf(logData,"%ld",(long)fLocalItemsDeleted); logData+="\r\ndevicedeleted:"; StringObjAppendPrintf(logData,"%ld",(long)fRemoteItemsDeleted); logData+="\r\nlocalrejected:"; StringObjAppendPrintf(logData,"%ld",(long)fLocalItemsError); logData+="\r\ndevicerejected:"; StringObjAppendPrintf(logData,"%ld",(long)fRemoteItemsError); logData+="\r\nlocalupdated:"; StringObjAppendPrintf(logData,"%ld",(long)fLocalItemsUpdated); logData+="\r\ndeviceupdated:"; StringObjAppendPrintf(logData,"%ld",(long)fRemoteItemsUpdated); #ifdef SYSYNC_SERVER if (IS_SERVER) { logData+="\r\nslowsyncmatches:"; StringObjAppendPrintf(logData,"%ld",(long)fSlowSyncMatches); logData+="\r\nserverwins:"; StringObjAppendPrintf(logData,"%ld",(long)fConflictsServerWins); logData+="\r\nclientwins:"; StringObjAppendPrintf(logData,"%ld",(long)fConflictsClientWins); logData+="\r\nduplicated:"; StringObjAppendPrintf(logData,"%ld",(long)fConflictsDuplicated); } // server #endif // SYSYNC_SERVER logData+="\r\nsessionbytesin:"; StringObjAppendPrintf(logData,"%ld",(long)fSessionP->getIncomingBytes()); logData+="\r\nsessionbytesout:"; StringObjAppendPrintf(logData,"%ld",(long)fSessionP->getOutgoingBytes()); logData+="\r\ndatabytesin:"; StringObjAppendPrintf(logData,"%ld",(long)fIncomingDataBytes); logData+="\r\ndatabytesout:"; StringObjAppendPrintf(logData,"%ld",(long)fOutgoingDataBytes); logData+="\r\n"; if (fDBApi_Admin.Created()) { fDBApi_Admin.WriteLogData(logData.c_str()); if (fPluginDSConfigP->fDBAPIModule_Data != fPluginDSConfigP->fDBAPIModule_Admin) { // admin and data are different modules, show log to data module as well if (fDBApi_Data.Created()) fDBApi_Data.WriteLogData(logData.c_str()); } } else if (fDBApi_Data.Created()) { fDBApi_Data.WriteLogData(logData.c_str()); } // anyway: let ancestor save log info as well (if it is configured so) inherited::dsLogSyncResult(); } // TPluginApiDS::dsLogSyncResult #ifdef STREAMFIELD_SUPPORT // TApiBlobProxy // ============= TApiBlobProxy::TApiBlobProxy( TPluginApiDS *aApiDsP, bool aIsStringBLOB, const char *aBlobID, const char *aParentID ) { // save values fApiDsP = aApiDsP; fIsStringBLOB = aIsStringBLOB; fBlobID = aBlobID; fParentObjectID = aParentID; fBlobSize = 0; fBlobSizeKnown = false; fFetchedSize = 0; fBufferSize = 0; fBlobBuffer = NULL; // nothing retrieved yet } // TApiBlobProxy::TApiBlobProxy TApiBlobProxy::~TApiBlobProxy() { if (fBlobBuffer) delete (char *)fBlobBuffer; // gcc 3.2.2 needs cast to suppress warning fBlobBuffer=NULL; } // TApiBlobProxy::~TApiBlobProxy // fetch BLOB from DPAPI void TApiBlobProxy::fetchBlob(size_t aNeededSize, bool aNeedsTotalSize, bool aNeedsAllData) { TSyError dberr=LOCERR_OK; if (fBufferSize==0 || aNeededSize>fFetchedSize) { // if do not have anything yet or not enough yet, we need to read uInt8P bufP = NULL; bool last = false; bool first = fFetchedSize==0; // first if we haven't fetched anything so far TDB_Api_Blk blobData; memSize neededBytes = aNeededSize-fFetchedSize; // how much we need to read more memSize totalsize = 0; // not known if (fIsStringBLOB) aNeedsAllData = true; // strings must be fetched entirely, as they need to be converted before we can measure size or get data if (!fBlobBuffer && aNeededSize==0 && (aNeedsTotalSize || aNeedsAllData)) neededBytes=200; // just read a bit to possibly obtain the total size do { // read a block dberr = fApiDsP->fDBApi_Data.ReadBlob( fParentObjectID.c_str(), // the item ID fBlobID.c_str(), // the ID of the blob neededBytes, // how much we need blobData, // blob data totalsize, // will receive total size or 0 if unknown first, last ); if (dberr!=LOCERR_OK) SYSYNC_THROW(TSyncException("ReadBlob fatal error",dberr)); // sanity check if (blobData.fSize>neededBytes) SYSYNC_THROW(TSyncException("ReadBlob returned more data than requested")); // check if we know the total size reliably now if (totalsize) { // non-zero return means we know the total size now fBlobSize = totalsize; fBlobSizeKnown = true; } else { // could be unknown size OR zero blob if (neededBytes>0 && blobData.fSize==0) { // we tried to read, but got nothing, and total size is zero -> this means explicit zero size fBlobSize = 0; fBlobSizeKnown = true; } } // calculate how large the buffer needs to be size_t newBufSiz = (aNeededSize ? aNeededSize : fFetchedSize+blobData.fSize) + 1; // +1 for string terminator possibly needed if (fBufferSize will be set back to 0 here !! // check end of data from API if (last) { if (!fBlobSizeKnown) { fBlobSize = fFetchedSize; fBlobSizeKnown = true; } // end of BLOB: done fetching ANYWAY break; } // the BLOB is bigger than what we have fetched so far // - check if we are done even if not at end of blob if (!aNeedsAllData && fFetchedSize>=aNeededSize && (!aNeedsTotalSize || fBlobSizeKnown)) break; // we have what was requested // - we need to load more data if (aNeedsAllData) { if (fBlobSizeKnown) neededBytes = fBlobSize-fFetchedSize; // try to get rest in one chunk else neededBytes = 4096; // we don't know how much is coming, continue reading in 4k chunks } // we need to continue until we get the total size or last first=false; } while(true); // for strings, we need to convert the data and re-adjust the size if (fIsStringBLOB) { // we KNOW that we have the entire BLOB text here (because we set aNeedsAllData above when this is a string BLOB) // - set a terminator *((char *)fBlobBuffer+fFetchedSize) = 0; // set terminator // - convert to UTF8 and internal linefeeds string strUtf8; appendStringAsUTF8((const char *)fBlobBuffer, strUtf8, fApiDsP->fPluginDSConfigP->fDataCharSet, lem_cstr); // set actual size fBlobSize=strUtf8.size(); // copy from string to buffer if (fBlobSize+1<=fBufferSize) { bufP = fBlobBuffer; // use old buffer } else { fBufferSize=fBlobSize+1; bufP = new unsigned char [fBufferSize]; delete (unsigned char *)fBlobBuffer; fBlobBuffer = bufP; } memcpy(bufP,strUtf8.c_str(),strUtf8.size()); fFetchedSize=strUtf8.size(); *((char *)fBlobBuffer+fFetchedSize)=0; // set terminator } // if } } // TApiBlobProxy::fetchBlob // returns size of entire blob size_t TApiBlobProxy::getBlobSize(TStringField *aFieldP) { fetchBlob(0,true,false); // only needs the size, but no data return fBlobSize; } // TApiBlobProxy::getBlobSize // read from Blob from specified stream position and update stream pos size_t TApiBlobProxy::readBlobStream(TStringField *aFieldP, size_t &aPos, void *aBuffer, size_t aMaxBytes) { if (fFetchedSize fetch more fetchBlob(aPos+aMaxBytes,false,false); // fetch at least up to the given size (unless blob is actually smaller) } } // now copy from our buffer if (aPos>fFetchedSize) return 0; // position obviously out of range if (aPos+aMaxBytes>fFetchedSize) aMaxBytes=fFetchedSize-aPos; // reduce to what we have if (aMaxBytes==0) return 0; // safety // copy data from fBlobBuffer (which contains beginning or all of the BLOB) to caller's buffer memcpy(aBuffer,(char *)fBlobBuffer+aPos,aMaxBytes); aPos += aMaxBytes; return aMaxBytes; // return number of bytes actually read } // TApiBlobProxy::readBlobStream #endif // STREAMFIELD_SUPPORT } // namespace sysync /* end of TPluginApiDS implementation */ // eof libsynthesis-3.4.0.47.1/src/DB_interfaces/api_db/pluginapids.h000077500000000000000000000450331226375725500240410ustar00rootroot00000000000000/** * @File pluginapids.h * * @Author Lukas Zeller (luz@plan44.ch) * * @brief TPluginApiDS * Plugin based datastore API implementation * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * @Date 2005-10-06 : luz : created from apidbdatastore */ #ifndef PLUGINAPIDS_H #define PLUGINAPIDS_H // includes #ifdef SQL_SUPPORT #include "odbcapids.h" #undef SDK_ONLY_SUPPORT #else #include "customimplds.h" #define SDK_ONLY_SUPPORT 1 #endif #include "dbapi.h" #include "pluginapiagent.h" using namespace sysync; namespace sysync { // single field mapping class TApiFieldMapItem: #ifdef SDK_ONLY_SUPPORT public TFieldMapItem #else public TODBCFieldMapItem #endif { #ifdef SDK_ONLY_SUPPORT typedef TFieldMapItem inherited; #else typedef TODBCFieldMapItem inherited; #endif public: TApiFieldMapItem(const char *aElementName, TConfigElement *aParentElement); // - parser for extra attributes (for derived classes) virtual void checkAttrs(const char **aAttributes); // properties }; // TApiFieldMapItem #ifdef ARRAYDBTABLES_SUPPORT // array mapping class TApiFieldMapArrayItem: #ifdef SDK_ONLY_SUPPORT public TFieldMapArrayItem #else public TODBCFieldMapArrayItem #endif { #ifdef SDK_ONLY_SUPPORT typedef TFieldMapArrayItem inherited; #else typedef TODBCFieldMapArrayItem inherited; #endif public: TApiFieldMapArrayItem(TCustomDSConfig *aCustomDSConfigP, TConfigElement *aParentElement); // - parser for extra attributes (for derived classes) virtual void checkAttrs(const char **aAttributes); // properties }; // TApiFieldMapArrayItem #endif class TPluginDSConfig: #ifdef SDK_ONLY_SUPPORT public TCustomDSConfig #else public TOdbcDSConfig #endif { #ifdef SDK_ONLY_SUPPORT typedef TCustomDSConfig inherited; #else typedef TOdbcDSConfig inherited; #endif public: TPluginDSConfig(const char* aName, TConfigElement *aParentElement); virtual ~TPluginDSConfig(); // properties /// name of the DB API modules /// @{ string fDBAPIModule_Data; ///< name of the module which handles data - if fDataModuleAlsoHandlesAdmin is set this is used for admin as well string fDBAPIModule_Admin; ///< name of the module which handles admin /// @} /// flag to handle admin in same API module as data /// @Note this is only needed for old-style configs where we had only ONE module /// per datastore for both admin and data. Now the normal way is to configure /// either fDBAPIModule_Data or fDBAPIModule_Admin to select plugin handling of /// either data or admin independently. bool fDataModuleAlsoHandlesAdmin; // wants startDataRead() called as early as possible bool fEarlyStartDataRead; // - config object for API module TDB_Api_Config fDBApiConfig_Data; TDB_Api_Config fDBApiConfig_Admin; // - generic module params TApiParamConfig fPluginParams_Admin; TApiParamConfig fPluginParams_Data; // - debug flags uInt16 fPluginDbgMask_Data; uInt16 fPluginDbgMask_Admin; // capabilities of connected plugin bool fItemAsKey; // supports items as key bool fResumeSupported; // extends version check in dsResumeSupportedInDB(), not supported if false bool fHasDeleteSyncSet; // implements deleting sync set using DeleteSyncSet() // public methods // - create appropriate datastore from config, calls addTypeSupport as well virtual TLocalEngineDS *newLocalDataStore(TSyncSession *aSessionP); // factory functions for field map items virtual TFieldMapItem *newFieldMapItem(const char *aElementName, TConfigElement *aParentElement) { return new TApiFieldMapItem(aElementName,aParentElement); }; #ifdef ARRAYDBTABLES_SUPPORT virtual TFieldMapArrayItem *newFieldMapArrayItem(TCustomDSConfig *aCustomDSConfigP, TConfigElement *aParentElement) { return new TApiFieldMapArrayItem(aCustomDSConfigP,aParentElement); }; #endif protected: // check config elements virtual bool localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine); virtual void clear(); virtual void localResolve(bool aLastPass); private: }; // TPluginDSConfig // forward class TPluginAgentConfig; class TPluginApiAgent; #if defined(DBAPI_ASKEYITEMS) && defined(ENGINEINTERFACE_SUPPORT) class TDBItemKey; #endif // DBAPI_ASKEYITEMS + ENGINEINTERFACE_SUPPORT class TPluginApiDS: #ifdef SDK_ONLY_SUPPORT public TCustomImplDS #else public TODBCApiDS #endif { #ifdef SDK_ONLY_SUPPORT typedef TCustomImplDS inherited; #else typedef TODBCApiDS inherited; #endif friend class TApiBlobProxy; private: void InternalResetDataStore(void); // reset for re-use without re-creation public: TPluginApiDS( TPluginDSConfig *aConfigP, sysync::TSyncSession *aSessionP, const char *aName, uInt32 aCommonSyncCapMask=0); virtual void announceAgentDestruction(void); virtual void dsResetDataStore(void) { InternalResetDataStore(); inherited::dsResetDataStore(); }; virtual ~TPluginApiDS(); // override TSyncDataStore: the plugin must be able to return 404 // when an item is not found during delete virtual bool dsDeleteDetectsItemPresence() const { return true; } #ifndef BINFILE_ALWAYS_ACTIVE /// @name apiXXXX methods defining the interface from TCustomImplDS to TXXXApi actual API implementations /// @{ // /// @brief Load admin data from ODBC database /// @param aDeviceID[in] remote device URI (device ID) /// @param aDatabaseID[in] local database ID /// @param aRemoteDBID[in] database ID of remote device /// Must search for existing target record matching the triple (aDeviceID,aDatabaseID,aRemoteDBID) /// - if there is a matching record: load it /// - if there is no matching record, set fFirstTimeSync=true. The implementation may already create a /// new record with the key (aDeviceID,aDatabaseID,aRemoteDBID) and initialize it with the data from /// the items as shown below. At least, fTargetKey must be set to a value that will allow apiSaveAdminData to /// update the record. In case implementation chooses not create the record only in apiSaveAdminData, it must /// buffer the triple (aDeviceID,aDatabaseID,aRemoteDBID) such that it is available at apiSaveAdminData. /// If a record exists implementation must load the following items: /// - fTargetKey = some key value that can be used to re-identify the target record later at SaveAdminData. /// If the database implementation has other means to re-identify the target, this can be /// left unassigned. /// - fLastRemoteAnchor = anchor string used by remote party for last session (and saved to DB then) /// - fPreviousSyncTime = anchor (beginning of session) timestamp of last session. /// - fPreviousToRemoteSyncCmpRef = Reference time to determine items modified since last time sending data to remote /// (or last changelog update in case of BASED_ON_BINFILE_CLIENT) /// - fPreviousToRemoteSyncIdentifier = string identifying last session that sent data to remote /// (or last changelog update in case of BASED_ON_BINFILE_CLIENT). Needs only be saved /// if derived datastore cannot work with timestamps and has its own identifier. /// - fMapTable = list containing map entries. The implementation must load all map entries /// related to the current sync target identified by the triple of (aDeviceID,aDatabaseID,aRemoteDBID) /// or by fTargetKey. The entries added to fMapTable must have "changed", "added" and "deleted" flags /// set to false. /// For resumable datastores: /// - fMapTable = In addition to the above, the markforresume flag must be saved in the mapflags // when it is not equal to the savedmark flag - independently of added/deleted/changed. /// - fResumeAlertCode = alert code of current suspend state, 0 if none /// - fPreviousSuspendCmpRef = reference time of last suspend (used to detect items modified during a suspend / resume) /// - fPreviousSuspendIdentifier = identifier of last suspend (used to detect items modified during a suspend / resume) /// (needs only be saved if derived datastore cannot work with timestamps and has /// its own identifier) /// - fPendingAddMaps = map. The implementation must load all all pending maps (client only) into /// fPendingAddMaps (and fUnconfirmedMaps must be left empty). /// - fTempGUIDMap = map. The implementation must save all entries as temporary LUID to GUID mappings /// (server only) virtual localstatus apiLoadAdminData( const char *aDeviceID, // remote device URI (device ID) const char *aDatabaseID, // database ID const char *aRemoteDBID // database ID of remote device ); /// @brief Save admin data to ODBC database /// @param[in] aSessionFinished if true, this is a end-of-session save (and not only a suspend save) - but not necessarily a successful one /// @param[in] aSuccessful if true, this is a successful end-of-session /// Must save to the target record addressed at LoadAdminData() by the triple (aDeviceID,aDatabaseID,aRemoteDBID) /// Implementation must save the following items: /// - fLastRemoteAnchor = anchor string used by remote party for this session (and saved to DB then) /// - fPreviousSyncTime = anchor (beginning of session) timestamp of this session. /// - fPreviousToRemoteSyncCmpRef = Reference time to determine items modified since last time sending data to remote /// (or last changelog update in case of BASED_ON_BINFILE_CLIENT) /// - fPreviousToRemoteSyncIdentifier = string identifying last session that sent data to remote /// (or last changelog update in case of BASED_ON_BINFILE_CLIENT). Needs only be saved /// if derived datastore cannot work with timestamps and has its own identifier. /// - fMapTable = list containing map entries. The implementation must save all map entries /// that have changed, are new or are deleted. See below for additional resume requirements. /// For resumable datastores: /// - fMapTable = In addition to the above, the markforresume flag must be saved in the mapflags // when it is not equal to the savedmark flag - independently of added/deleted/changed. /// - fResumeAlertCode = alert code of current suspend state, 0 if none /// - fPreviousSuspendCmpRef = reference time of last suspend (used to detect items modified during a suspend / resume) /// - fPreviousSuspendIdentifier = identifier of last suspend (used to detect items modified during a suspend / resume) /// (needs only be saved if derived datastore cannot work with timestamps and has /// its own identifier) /// - fPendingAddMaps and fUnconfirmedMaps = map. The implementation must save all entries as /// pending maps (client only). Note that fPendingAddMaps might contain temporary localIDs, /// so call dsFinalizeLocalID() to ensure these are converted to final before saving. /// - fTempGUIDMap = map. The implementation must save all entries as temporary LUID to GUID mappings /// (server only) virtual localstatus apiSaveAdminData(bool aSessionFinished, bool aSuccessful); /// read sync set IDs and mod dates. /// @param[in] if set, all data fields are needed, so ReadSyncSet MAY /// read items here already. Note that ReadSyncSet MAY read items here /// even if aNeedAll is not set (if it is more efficient than reading /// them separately afterwards). #endif // not BINFILE_ALWAYS_ACTIVE /// perform early data access start (if datastore requests it by setting fEarlyStartDataRead config flag) virtual localstatus apiEarlyDataAccessStart(void); /// read the sync set virtual localstatus apiReadSyncSet(bool aNeedAll); /// Zap all data in syncset (note that everything outside the sync set will remain intact) virtual localstatus apiZapSyncSet(void); virtual bool apiNeedSyncSetToZap(void); /// fetch record contents from DB by localID. virtual localstatus apiFetchItem(TMultiFieldItem &aItem, bool aReadPhase, TSyncSetItem *aSyncSetItemP); /// add new item to datastore, returns created localID virtual localstatus apiAddItem(TMultiFieldItem &aItem, string &aLocalID); /// update existing item in datastore, returns 404 if item not found virtual localstatus apiUpdateItem(TMultiFieldItem &aItem); /// delete existing item in datastore, returns 211 if not existing any more virtual localstatus apiDeleteItem(TMultiFieldItem &aItem); /// end of syncset read virtual localstatus apiEndDataRead(void) { return LOCERR_OK; /* NOP at this time */ }; /// start of write virtual localstatus apiStartDataWrite(void); /// end DB data write sequence (but not yet admin data) virtual localstatus apiEndDataWrite(string &aThisSyncIdentifier); /// @} /// @name dsXXXX virtuals defined by TLocalEngineDS /// These are usually designed such that they should always call inherited::dsXXX to let the entire chain /// of ancestors see the calls /// @{ // /// end of message handling // virtual void dsEndOfMessage(void); #ifdef OBJECT_FILTERING /// test expression filtering capability of datastore /// @return true if DB implementation can filter the standard filters /// (LocalDBFilter, TargetFilter and InvisibleFilter) during database fetch /// otherwise, fetched items will be filtered after being read from DB. virtual bool dsFilteredFetchesFromDB(bool aFilterChanged=false); /// test special option filtering capability of datastore /// @return true if DB implementation can also apply special filters like CGI-options /// /dr(x,y) etc. during fetching virtual bool dsOptionFilterFetchesFromDB(void); #endif /// alert possible thread change virtual void dsThreadMayChangeNow(void); /// returns true if DB implementation supports resume (saving of resume marks, alert code, pending maps, tempGUIDs) virtual bool dsResumeSupportedInDB(void); #ifdef SYSYNC_CLIENT /// finalize local ID (for datastores that can't efficiently produce these at insert) virtual bool dsFinalizeLocalID(string &aLocalID); #endif /// @} // - must be called before starting a thread. If returns false, starting a thread now // is not allowed and must be postponed. virtual bool startingThread(void); // - must be called when a thread's activity has ended // BUT THE CALL MUST BE FROM THE ENDING THREAD, not the main thread! virtual void endingThread(void); // - should be called before doing DB accesses that might be locked (e.g. because another thread is using the DB resources) virtual bool dbAccessLocked(void); // - log datastore sync result, Called at end of sync with this datastore virtual void dsLogSyncResult(void); private: // - connect data handling part of plugin. Returns LOCERR_NOTIMPL when no data plugin is selected TSyError connectDataPlugin(void); // - prepare for reading syncset (is called early when fEarlyStartDataRead is set, otherwise from within apiReadSyncSet) localstatus apiPrepareReadSyncSet(void); // - alert possible thread change to plugins // Does not check if API is locked or not, see dsThreadMayChangeNow() void ThreadMayChangeNow(void); #ifdef DBAPI_TEXTITEMS // Text item handling // - store itemdata field into mapped TItemField virtual bool storeField( cAppCharP aName, cAppCharP aParams, cAppCharP aValue, TMultiFieldItem &aItem, uInt16 aSetNo, sInt16 aArrayIndex ); // - parse itemdata into item using DB mappings bool parseDBItemData( TMultiFieldItem &aItem, cAppCharP aItemData, uInt16 aSetNo ); // - create itemdata from mapped fields bool generateDBItemData( bool aAssignedOnly, TMultiFieldItem &aItem, uInt16 aSetNo, string &aDataFields ); #endif // - post process item after reading from DB (run script) bool postReadProcessItem(TMultiFieldItem &aItem, uInt16 aSetNo); // - pre-process item before writing to DB (run script) bool preWriteProcessItem(TMultiFieldItem &aItem); // - send BLOBs of this item one by one bool writeBlobs( bool aAssignedOnly, TMultiFieldItem &aItem, uInt16 aSetNo ); // - delete BLOBs of this item one by one bool deleteBlobs( bool aAssignedOnly, TMultiFieldItem &aItem, uInt16 aSetNo ); private: // agent (typed pointers for convenience) TPluginApiAgent *fPluginAgentP; // config (typed pointers for convenience) TPluginAgentConfig *fPluginAgentConfigP; // the actual API access instances TDB_Api fDBApi_Data; ///< access to data TDB_Api fDBApi_Admin; ///< access to admin // config pointer TPluginDSConfig *fPluginDSConfigP; // filter testing bool fAPICanFilter; bool fAPIFiltersTested; }; // TPluginApiDS #ifdef STREAMFIELD_SUPPORT // proxy for loading blobs class TApiBlobProxy : public TBlobProxy, noncopyable { typedef TBlobProxy inherited; public: TApiBlobProxy(TPluginApiDS *aApiDsP, bool aIsStringBLOB, const char *aBlobID, const char *aParentID); virtual ~TApiBlobProxy(); // - returns size of entire blob virtual size_t getBlobSize(TStringField *aFieldP); // - read from Blob from specified stream position and update stream pos virtual size_t readBlobStream(TStringField *aFieldP, size_t &aPos, void *aBuffer, size_t aMaxBytes); // - dependency on a local ID virtual void setParentLocalID(const char *aParentLocalID) { fParentObjectID=aParentLocalID; }; private: // fetch BLOB from DPAPI void fetchBlob(size_t aNeededSize, bool aNeedsTotalSize, bool aNeedsAllData); // Vars TPluginApiDS *fApiDsP; // datastore which can be asked to retrieve data bool fIsStringBLOB; // if set, the blob must be treated as a string (applying DB charset conversions) string fBlobID; // object ID of blob string fParentObjectID; // id of parent object (will be updated in case parent signals ID change) size_t fBlobSize; // total size of the BLOB bool fBlobSizeKnown; // set if fBlobSize is valid (can also be 0 for KNOWN empty blob) size_t fFetchedSize; // how much we have already retrieved (and is in fBlobBuffer) size_t fBufferSize; // how much room we have in the buffer uInt8P fBlobBuffer; // buffer for blob already retrieved (NULL if nothing yet) }; // TApiBlobProxy #endif } // namespace sysync #endif // PLUGINAPIDS_H // eof libsynthesis-3.4.0.47.1/src/DB_interfaces/api_db/plugindb.h000077500000000000000000000004651226375725500233260ustar00rootroot00000000000000/* * Common include file for all Plugin DB sources */ #ifndef PLUGINDB_H #define PLUGINDB_H // precompiled portion #include "plugindb_precomp.h" // other common includes #include "sysync.h" // Items used by ODBC DB interface #include "multifielditem.h" #include "mimediritemtype.h" #endif /* eof */ libsynthesis-3.4.0.47.1/src/DB_interfaces/api_db/plugindb_precomp.h000077500000000000000000000003261226375725500250470ustar00rootroot00000000000000/* * precompiled/precompilable headers */ #ifndef PLUGINDB_PRECOMP_H #define PLUGINDB_PRECOMP_H /* Specific headers for Plugin DB interface */ #ifdef _WIN32 #include #endif #endif /* eof */ libsynthesis-3.4.0.47.1/src/DB_interfaces/api_db/sync_dbapiconnect.cpp000077500000000000000000000445711226375725500255500ustar00rootroot00000000000000/* * File: sync_dbapiconnect.cpp * * Author: Beat Forster (bfo@synthesis.ch) * * C/C++ Programming interface between * the Synthesis SyncML engine * and the database layer * * Copyright (c) 2005-2011 by Synthesis AG + plan44.ch * * * This module contains the method table and connection * routines, which are used e.g. for the JNI plugin. * */ #include "sync_include.h" #include "sync_dbapidef.h" #include "sync_dbapiconnect.h" #include "DLL_interface.h" #ifdef __cplusplus namespace sysync { #endif // Support functions for creating Java signatures string LCP( string jP, string className ) { if (jP.empty()) jP = className; else jP+= '/' + className; return "L" + jP + ";"; } // LCP string JCS ( void ) { return LCP( "java/lang", "String" ); } static string Sgn ( string s, string ret ){ return "(" + s + ")" + ret; } string SgnS ( string s ) { return Sgn( s, "S" ); } string SgnI ( string s ) { return Sgn( s, "I" ); } string SgnV ( string s ) { return Sgn( s, "V" ); } class JSgn { public: JSgn() { f64bit= false; } bool f64bit; string fvr; string fr; string SgnS_V( string s= "" ) { return Sgn( fvr + s,"S" ); } string SgnS_X( string s= "" ) { return Sgn( fr + s,"S" ); } string SgnI_X( string s= "" ) { return Sgn( fr + s,"I" ); } string SgnZ_X( string s= "" ) { return Sgn( fr + s,"Z" ); } string SgnV_X( string s= "" ) { return Sgn( fr + s,"V" ); } }; // JSgn /*! connect the list of these functions, including JNI signatures, if required */ TSyError DBApi_DLLAssign( appPointer aMod, appPointer aField, memSize aFieldSize, string aKey, bool a64bit, string jP ) { bool keyCur, keyOld, keyOld2; string js1, js2, js3, js4, js5; string jt = JCS(); string jvt= LCP( jP, c_VAR_String ); string jvl= LCP( jP, c_VAR_long ); string jvi= LCP( jP, c_VAR_int ); string jdc= LCP( jP, c_JNI_DB_Callback ); string jmi= LCP( jP, c_JNI_MapID ); string jii= LCP( jP, c_JNI_ItemID ); JSgn j; j.f64bit= a64bit; if (j.f64bit) { j.fvr= jvl; j.fr= "J"; } else { j.fvr= jvi; j.fr= "I"; } string js_ = j.SgnS_X(); // "(I)S" string jsT = j.SgnS_X( jt ); // "(ILjava/lang/String;)S" string jsvT= j.SgnS_X( jvt ); // "(ILVAR_String;)S" string jsA = j.SgnS_X( jvt + jvt + jvt + "I" ); // "(ILVAR_String;LVAR_String;LVAR_String;I)S" // ----------------------------------------------------------------------------------------- if (strcmp( aKey.c_str(),Plugin_Start )==0) { // "(LVAR_xxx; ... (VAR_xxx = VAR_int/VAR_long) js1= j.SgnS_V( jt // ... Ljava/lang/String; ... + jt // ... Ljava/lang/String; ... + jt // ... Ljava/lang/String; ... + jdc ); // ... LDB_Callback;)S" js2= j.SgnI_X(); return ConnectFunctions( aMod, aField,aFieldSize, true, // ---- start of plugin connection Mo_CC, js1.c_str(), Mo_Ve, js2.c_str(), Mo_Ca,jsvT.c_str(), NULL ); } // if /* // compatibility to older version ( w/o ) keyOld= strcmp( aKey.c_str(),Plugin_Param_OLD )==0; keyCur= strcmp( aKey.c_str(),Plugin_Param )==0; if (keyCur || keyOld) { // additional param for newer version if (keyCur) js1= j.SgnS_X( jt + "I" ); // "(ILjava/lang/String;I)S" else js1= jsT; // "(ILjava/lang/String;)S" */ if (strcmp( aKey.c_str(),Plugin_Param )==0) { // additional param for newer version js1= j.SgnS_X( jt + "I" ); // "(ILjava/lang/String;I)S" return ConnectFunctions( aMod, aField,aFieldSize, true, // ---- start of plugin connection Mo_PP, js1.c_str(), NULL ); } // if // ---- session --------------------------------------------------- if (strcmp( aKey.c_str(),Plugin_Session )==0) { // "(LVAR_xxx; ... (VAR_xxx = VAR_int/VAR_long) js1= j.SgnS_V( jt // ... Ljava/lang/String; ... + jdc ); // ... LDB_Callback;)S" js2= j.SgnV_X(); js3= j.SgnV_X( "Z" + jt ); return ConnectFunctions( aMod, aField,aFieldSize, true, // ---- session ---- Se_CC, js1.c_str(), "", "", /*-----* adaptitem */ "", "", /*-----* session auth */ "", "", /* */ "", "", /*-----*/ "", "", /*-----* device admin */ "", "", /* */ "", "", /* */ "", "", /*-----*/ "", "", /*-----* dbtime */ Se_DO, "", /*~~~~~*/ Se_TC, js2.c_str(), Se_DI, js3.c_str(), Se_DC, js_.c_str(), NULL ); } // if if (strcmp( aKey.c_str(),Plugin_SE_Adapt )==0) { return ConnectFunctions( aMod, aField,aFieldSize, true, // ---- device admin (GetDBTime) ---- "Session_AdaptItem", jsA.c_str(), NULL ); } // if // The correct signature with VAR_String can be used now keyOld= strcmp( aKey.c_str(),Plugin_SE_Auth_OLD )==0; keyCur= strcmp( aKey.c_str(),Plugin_SE_Auth )==0; if (keyCur || keyOld) { js1= j.SgnI_X(); if (keyCur) js2= j.SgnS_X( jt // "(ILjava/lang/String; ... + jvt // ... LVAR_String; ... + jvt ); // ... LVAR_String;)S" if (keyOld) js2= j.SgnS_X( jt // "(ILjava/lang/String; ... + jt // ... Ljava/lang/String; ... + jvt ); // ... LVAR_String;)S" return ConnectFunctions( aMod, aField,aFieldSize, true, // ---- session auth ---- Se_PM, js1.c_str(), Se_LI, js2.c_str(), Se_LO, js_.c_str(), NULL ); } // if if (strcmp( aKey.c_str(),Plugin_DV_Admin )==0) { js1= j.SgnS_X( jt + jvt + jvt ); // "(ILjava/lang/String;LVAR_String;LVAR_String;)S" return ConnectFunctions( aMod, aField,aFieldSize, true, // ---- device admin ---- Se_CD, js1.c_str(), Se_GN,jsvT.c_str(), Se_SN, jsT.c_str(), Se_SD, jsT.c_str(), // the same NULL ); } // if if (strcmp( aKey.c_str(),Plugin_DV_DBTime )==0) { return ConnectFunctions( aMod, aField,aFieldSize, true, // ---- device admin (GetDBTime) ---- Se_GT, jsvT.c_str(), NULL ); } // if // ---- datastore ------------------------------------------------- if (strcmp( aKey.c_str(),Plugin_DS_General )==0) { js1= j.SgnI_X( jt ); js2= j.SgnV_X( ); js3= j.SgnV_X( jt ); js4= j.SgnV_X( "Z" + jt ); return ConnectFunctions( aMod, aField,aFieldSize, true, // ---- datastore general ---- Da_CS, js1.c_str(), Da_FS, js1.c_str(), Da_TC, js2.c_str(), Da_WL, js3.c_str(), Da_DI, js4.c_str(), NULL ); } // if if (strcmp( aKey.c_str(),Plugin_DS_Admin_Str )==0) { js1= j.SgnS_X( jt + jt + jvt ); // "(ILjava/lang/String;Ljava/lang/String;LVAR_String;)S" return ConnectFunctions( aMod, aField,aFieldSize, true, // ---- datastore admin asStr ---- Da_LA, js1.c_str(), Da_SA, jsT.c_str(), NULL ); } // if if (strcmp( aKey.c_str(),Plugin_DS_Admin_Key )==0) { js1= j.SgnS_X( jt + jt + j.fr ); // "(ILjava/lang/String;Ljava/lang/String;I)S" js2= j.SgnS_X ( j.fr ); // "(II)S" return ConnectFunctions( aMod, aField,aFieldSize, true, // ---- datastore admin asKey ---- Da_LAK, js1.c_str(), Da_SAK, js2.c_str(), NULL ); } // if // "InsertMapItem" can be used now keyOld= strcmp( aKey.c_str(),Plugin_DS_Admin_OLD )==0; keyCur= strcmp( aKey.c_str(),Plugin_DS_Admin_Map )==0; if (keyCur || keyOld) { cAppCharP proc_insM= ""; if (keyCur) proc_insM= Da_IM; js1= j.SgnZ_X( jmi + "Z" ); // "(ILMapID;Z)Z" js2= j.SgnS_X( jmi ); // "(ILMapID;)S" return ConnectFunctions( aMod, aField,aFieldSize, true, // ---- datastore admin ---- Da_RM, js1.c_str(), proc_insM, js2.c_str(), Da_UM, js2.c_str(), // 2nd Da_DM, js2.c_str(), // 3rd NULL ); } // if // "DeleteBlob" can be used now keyOld = strcmp( aKey.c_str(),Plugin_DS_Data_OLD1 )==0; keyOld2= strcmp( aKey.c_str(),Plugin_DS_Data_OLD2 )==0; keyCur = strcmp( aKey.c_str(),Plugin_DS_Data )==0; if (keyCur || keyOld || keyOld2) { if (keyOld) js1= jsT; // "(ILjava/lang/String;)S" else js1= j.SgnS_X( jt + jt ); // "(ILjava/lang/String;Ljava/lang/String;)S" cAppCharP proc_fli= ""; if (keyCur) proc_fli= Da_FLI; cAppCharP proc_dss= ""; if (keyCur) proc_dss= Da_DSS; js2= j.SgnS_X( "Z" + jvt ); // "(IZLVAR_String;)S" js3= j.SgnS_X( jii + jii ); // "(ILItemID;LItemID;)S" js4= j.SgnS_X( jii + jt ); // "(ILItemID;Ljava/lang/String;)S" js5= j.SgnS_X( jii ); // "(ILItemID;)S" return ConnectFunctions( aMod, aField,aFieldSize, true, // ---- datastore data ---- Da_SR, js1.c_str(), // read Da_ER, js_.c_str(), Da_SW, js_.c_str(), // write Da_EW, js2.c_str(), /*-----*/ "", "", /* */ "", "", /* str */ "", "", /* */ "", "", /* */ /*-----*/ "", "", /* */ "", "", /* key */ "", "", /* */ "", "", /* */ /*-----*/ proc_fli, js3.c_str(), // independent Da_MvI, js4.c_str(), Da_DeI, js5.c_str(), proc_dss, js_.c_str(), NULL ); } // if if (strcmp( aKey.c_str(),Plugin_DS_Data_Str )==0) { js1= j.SgnS_X( jii + jvt + jvi + "Z" ); // "(ILItemID;LVAR_String;LVAR_int;Z)S" js2= j.SgnS_X( jii + jvt ); // "(ILItemID;LVAR_String;)S" js3= j.SgnS_X( jt + jii ); // "(ILjava/lang/String;LItemID;)S" js4= j.SgnS_X( jt + jii + jii ); // "(ILjava/lang/String;LItemID;LItemID;)S" return ConnectFunctions( aMod, aField,aFieldSize, true, // ---- aItemData routines ---- Da_RN, js1.c_str(), Da_RI, js2.c_str(), Da_II, js3.c_str(), Da_UI, js4.c_str(), NULL ); } // if if (strcmp( aKey.c_str(),Plugin_DS_Data_Key )==0) { js1= j.SgnS_X( jii + j.fr + jvi + "Z" ); // "(ILItemID;ILVAR_int;Z)S" js2= j.SgnS_X( jii + j.fr ); // "(ILItemID;I)S" js3= j.SgnS_X( j.fr + jii ); // "(IILItemID;)S" js4= j.SgnS_X( j.fr + jii + jii ); // "(IILItemID;LItemID;)S" return ConnectFunctions( aMod, aField,aFieldSize, true, // ---- aItemKey routines ---- Da_RNK, js1.c_str(), Da_RIK, js2.c_str(), Da_IIK, js3.c_str(), Da_UIK, js4.c_str(), NULL ); } // if keyOld = strcmp( aKey.c_str(),Plugin_DS_Blob_OLD1 )==0; keyOld2= strcmp( aKey.c_str(),Plugin_DS_Blob_OLD2 )==0; keyCur = strcmp( aKey.c_str(),Plugin_DS_Blob )==0; if (keyCur || keyOld || keyOld2) { cAppCharP proc_delB= ""; if (keyCur) proc_delB= Da_DB; string bvsz= j.fvr; string bsz= j.fr; if (!keyCur) { bvsz= jvi; bsz= "I"; } js1 = j.SgnS_X( jii // "(ILItemID;Ljava/lang/String;LVAR_byteArray; ... + jt // ... LVAR_int;LVAR_int;ZLVAR_boolean;)S" + LCP( jP, c_VAR_byteArray ) + bvsz + bvsz + "Z" + LCP( jP, c_VAR_bool ) ); js2 = j.SgnS_X( jii + jt + "[B" + bsz + bsz + "ZZ" ); // "(ILItemID;Ljava/lang/String;[BIIZZ)S" js3 = j.SgnS_X( jii + jt ); // "(ILItemID;Ljava/lang/String;)S" return ConnectFunctions( aMod, aField,aFieldSize, true, // ---- datastore data ---- Da_RB, js1.c_str(), Da_WB, js2.c_str(), proc_delB, js3.c_str(), NULL ); } // if if (strcmp( aKey.c_str(),Plugin_DS_Adapt )==0) { return ConnectFunctions( aMod, aField,aFieldSize, true, "AdaptItem", jsA.c_str(), NULL ); } // if if (strcmp( aKey.c_str(),Plugin_Datastore )==0) { // "(LVAR_xxx; ... (VAR_xxx = VAR_int/VAR_long) js1= j.SgnS_V( jt // ... Ljava/lang/String; ... + jdc // ... LDB_Callback; ... + jt // ... Ljava/lang/String; ... + jt ); // ... Ljava/lang/String;)S" return ConnectFunctions( aMod, aField,aFieldSize, true, Da_CC, js1.c_str(), "", "", /*-----* general */ "", "", /* */ "", "", /* */ "", "", /* */ "", "", /*-----*/ /*-----* admin */ "", "", /* str */ "", "", /* */ /*-----*/ "", "", /* key */ "", "", /* */ /*-----*/ "", "", /* */ "", "", /* map */ "", "", /* */ "", "", /* */ /*-----*/ /*-----* data read/write */ "", "", /* rd */ "", "", /* */ /*-----*/ "", "", /* wr */ "", "", /* */ /*-----*/ "", "", /* */ "", "", /* str */ "", "", /* */ "", "", /* */ /*-----*/ "", "", /* */ "", "", /* key */ "", "", /* */ "", "", /* */ /*-----*/ "", "", /* */ "", "", /* ind */ "", "", /* */ "", "", /* */ /*-----*/ "", "", /*-----* blobs */ "", "", /* */ "", "", /*-----*/ "", "", /*-----* adaptitem */ Da_DO, "", /*~~~~~*/ // general Da_DC, js_.c_str(), // close NULL ); } // if // ---- ui context ------------------------------------------------ if (strcmp( aKey.c_str(),Plugin_UI )==0) { // "(LVAR_xxx; ... (VAR_xxx = VAR_int/VAR_long) js1= j.SgnS_V( jt // ... Ljava/lang/String; ... + jdc ); // ... LDB_Callback;)S" return ConnectFunctions( aMod, aField,aFieldSize, true, // ---- ui context ---- "UI_CreateContext", js1.c_str(), "UI_RunContext", js_.c_str(), "UI_DeleteContext", js_.c_str(), NULL ); } // if // default settings if (strcmp( aKey.c_str(),"" )==0) { return ConnectFunctions( aMod, aField,aFieldSize, true, // ---- module -------------------------------------------------- "", "", /*-----* start */ "", "", /* */ "", "", /*-----*/ "", "", /*-----* plugin params */ Mo_DO, "", /*~~~~~*/ Mo_DC, js_.c_str(), // ---- session ------------------------------------------------- "", "", /*+*/ "", "", /*-*---* adaptitem */ /* */ "", "", /*-*---* session auth */ "", "", /* */ "", "", /*-*---*/ /* */ "", "", /*-*---* device admin */ "", "", /* */ "", "", /* */ "", "", /* */ "", "", /*-*---*(dbtime) */ /* */ "", "", /*+*/ "", "", /*+*/ "", "", /*+*/ "", "", /*+*/ // ---- datastore ----------------------------------------------- "", "", /*-* open */ "", "", /*-----* general */ "", "", /* */ "", "", /* */ "", "", /* */ "", "", /*-----*/ /*-----* admin */ "", "", /* str */ "", "", /* */ /*-----*/ "", "", /* key */ "", "", /* */ /*-----*/ "", "", /* */ "", "", /* map */ "", "", /* */ "", "", /* */ /*-----*/ /*-----* data read/write */ "", "", /* rd */ "", "", /* */ /*-----*/ "", "", /* wr */ "", "", /* */ /*-----*/ "", "", /* */ "", "", /* str */ "", "", /* */ "", "", /* */ /*-----*/ "", "", /* */ "", "", /* key */ "", "", /* */ "", "", /* */ /*-----*/ "", "", /* */ "", "", /* ind */ "", "", /* */ "", "", /* */ /*-----*/ "", "", /*-----* blobs */ "", "", /* */ "", "", /*-----*/ "", "", /*-----* adaptitem */ "", "", /*-* general */ "", "", /*-* close */ // ---- ui context ------------------------------------------------ "", "", /*-* open */ "", "", /*-* run */ "", "", /*-* close */ NULL ); } // if return DB_NotFound; } // DBApi_DLLAssign #if defined __cplusplus } // namespace */ #endif /* eof */ libsynthesis-3.4.0.47.1/src/DB_interfaces/api_db/sync_dbapiconnect.h000077500000000000000000000142601226375725500252050ustar00rootroot00000000000000/* * File: sync_dbapiconnect.h * * Author: Beat Forster (bfo@synthesis.ch) * * C/C++ Programming interface between * the Synthesis SyncML engine * and the database layer * * Copyright (c) 2005-2011 by Synthesis AG + plan44.ch * * * This module contains the method table and connection * routines, which are used e.g. for the JNI plugin. * */ #ifndef SYNC_DBAPICONNECT_H #define SYNC_DBAPICONNECT_H #include "sync_include.h" #include #ifdef __cplusplus namespace sysync { #endif /* -- configuration for the DB_Api class ------------------------------------------- */ /* ---- MODULE ---------------- */ typedef struct { /* start */ void* Module_CreateContext; void* Module_Version; void* Module_Capabilities; } Start_Methods; typedef struct { /* plugin params */ void* Module_PluginParams; } Param_Methods; /* ---- SESSION --------------- */ typedef struct { void* Session_PasswordMode; /* session auth */ void* Session_Login; void* Session_Logout; } SE_Auth__Methods; typedef struct { void* Session_CheckDevice; /* device admin */ void* Session_GetNonce; void* Session_SaveNonce; void* Session_SaveDeviceInfo; } DV_Admin_Methods; typedef struct { void* Session_GetDBTime; /* dbtime */ } DV_Time__Methods; typedef struct { void* Session_AdaptItem; /* adaptitem */ } SE_Adapt_Methods; typedef struct { /* --- session handling --- */ void* Session_CreateContext; /* open */ SE_Adapt_Methods seAdapt; /* adaptitem */ SE_Auth__Methods seAuth; /* auth */ DV_Admin_Methods dvAdmin; /* admin */ DV_Time__Methods dvTime; /* dbtime */ void* Session_DisposeObj; /* general */ void* Session_ThreadMayChangeNow; void* Session_DispItems; void* Session_DeleteContext; /* close */ } SE_Methods; /* ---- DATASTORE ------------- */ typedef struct { void* ContextSupport; /* general */ void* FilterSupport; void* ThreadMayChangeNow; void* WriteLogData; void* DispItems; } DS_General_Methods; typedef struct { void* LoadAdminData; /* datastore admin str */ void* SaveAdminData; } DS_Adm_Str_Methods; typedef struct { void* LoadAdminDataAsKey; /* datastore admin key */ void* SaveAdminDataAsKey; } DS_Adm_Key_Methods; typedef struct { void* ReadNextMapItem; /* datastore admin map */ void* InsertMapItem; void* UpdateMapItem; void* DeleteMapItem; } DS_Adm_Map_Methods; typedef struct { DS_Adm_Str_Methods str; /* datastore admin */ DS_Adm_Key_Methods key; DS_Adm_Map_Methods map; } DS_Adm_Methods; typedef struct { /* string read/write */ void* ReadNextItem; void* ReadItem; void* InsertItem; void* UpdateItem; } DS_Str_Methods; typedef struct { /* key read/write */ void* ReadNextItemAsKey; void* ReadItemAsKey; void* InsertItemAsKey; void* UpdateItemAsKey; } DS_Key_Methods; typedef struct { /* independent */ void* FinalizeLocalID; void* MoveItem; void* DeleteItem; void* DeleteSyncSet; } DS_Ind_Methods; typedef struct { void* StartDataRead; /* read */ void* EndDataRead; void* StartDataWrite; /* write */ void* EndDataWrite; DS_Str_Methods str; DS_Key_Methods key; DS_Ind_Methods ind; } DS_Data_Methods; typedef struct { /* BLOBs */ void* ReadBlob; void* WriteBlob; void* DeleteBlob; } DS_Blob_Methods; typedef struct { /* adaptitem */ void* AdaptItem; } DS_Adapt_Methods; typedef struct { /* --- datastore handling --- */ void* CreateContext; /* open */ DS_General_Methods dsg; /* general */ DS_Adm_Methods dsAdm; /* data admin */ DS_Data_Methods dsData; /* data rd/wr */ DS_Blob_Methods dsBlob; /* BLOBs */ DS_Adapt_Methods dsAdapt; /* adaptitem */ void* DisposeObj; void* DeleteContext; /* close */ } DS_Methods; typedef struct { /* --- ui context handling --- */ void* UI_CreateContext; /* open */ void* UI_RunContext; /* run */ void* UI_DeleteContext; /* close */ } UI_Methods; /* ======= configuration for the DB_Api class ====== */ typedef struct { /* -- module ------------------------------------- */ Start_Methods start; /* start */ Param_Methods param; /* params */ void* Module_DisposeObj; /* general */ void* Module_DeleteContext; /* -- session ------------------------------------ */ SE_Methods se; /* -- datastore ---------------------------------- */ DS_Methods ds; /* -- ui context --------------------------------- */ UI_Methods ui; } API_Methods; // the Java interface classes #define c_VAR_short "VAR_short" #define c_VAR_int "VAR_int" #define c_VAR_long "VAR_long" #define c_VAR_bool "VAR_boolean" #define c_VAR_String "VAR_String" #define c_VAR_byteArray "VAR_byteArray" #define c_JNI_ItemID "ItemID" #define c_JNI_MapID "MapID" #define c_JNI_TPI "TEngineProgressInfo" #define c_JNI_DB_Callback "DB_Callback" #define c_JNI_JCallback "JCallback" #define c_JNI_JCallback64 "JCallback64" #ifdef __cplusplus // Support functions for creating Java signatures string LCP ( string jP, string className ); // "L/; string JCS ( void ); // "Ljava/lang/String;" string SgnS( string s= "" ); // "()S" string SgnI( string s= "" ); // "()I" string SgnV( string s= "" ); // "()V" /*! Assign the DB_API interface functions and JNI signatures */ /* (Call ConnectFunctions) */ TSyError DBApi_DLLAssign( appPointer aMod, appPointer aField, memSize aFieldSize, string aKey, bool a64bit, string jP= "" ); #endif #if defined __cplusplus } // namespace */ #endif #endif /* SYNC_DBAPICONNECT_H */ /* eof */ libsynthesis-3.4.0.47.1/src/DB_interfaces/odbc_db/000077500000000000000000000000001226375725500214775ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/DB_interfaces/odbc_db/odbcapiagent.cpp000066400000000000000000004050441226375725500246320ustar00rootroot00000000000000/** * @File odbcapiagent.cpp * * @Author Lukas Zeller (luz@plan44.ch) * * @brief TODBCApiAgent * ODBC based agent (client or server session) implementation * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * @Date 2005-10-06 : luz : created from odbcdbagent */ #include "prefix_file.h" #ifdef SQL_SUPPORT // includes #include "odbcapids.h" #include "odbcapiagent.h" #ifdef SYSYNC_TOOL #include "syncsessiondispatch.h" #endif namespace sysync { // Support for SySync Diagnostic Tool #ifdef SYSYNC_TOOL // execute SQL command int execSQL(int argc, const char *argv[]) { if (argc<0) { // help requested CONSOLEPRINTF((" execsql []")); CONSOLEPRINTF((" Execute SQL statement via ODBC on the server database")); return EXIT_SUCCESS; } TODBCApiAgent *odbcagentP = NULL; const char *sql = NULL; // show only one row by default sInt32 maxrows=1; // check for argument if (argc<1) { CONSOLEPRINTF(("argument containing SQL statement required")); return EXIT_FAILURE; } sql = argv[0]; if (argc>=2) { // second arg is maxrows StrToLong(argv[1],maxrows); } // get ODBC session to work with odbcagentP = dynamic_cast( static_cast(getSyncAppBase())->getSySyToolSession() ); if (!odbcagentP) { CONSOLEPRINTF(("Config does not contain an ODBC server section")); return EXIT_FAILURE; } // execute query // - show DB where we will exec it CONSOLEPRINTF(("Connecting to ODBC with connection string = '%s'",odbcagentP->fConfigP->fDBConnStr.c_str())); SQLRETURN res; SQLHSTMT statement=odbcagentP->newStatementHandle(odbcagentP->getODBCConnectionHandle()); try { // set parameter const int paramsiz=100; SQLCHAR paramval[paramsiz]; SQLINTEGER lenorind=SQL_NULL_DATA; res=SQLBindParameter( statement, 1, // parameter index SQL_PARAM_OUTPUT, // inout SQL_C_CHAR, // we want it as string SQL_INTEGER, // parameter type paramsiz, // column size 0, // decimal digits ¶mval, // parameter value paramsiz, // value buffer size (SQLLEN*)&lenorind // length or indicator ); odbcagentP->checkStatementError(res,statement); // issue res = SafeSQLExecDirect( statement, (SQLCHAR *)sql, SQL_NTS ); odbcagentP->checkStatementError(res,statement); // show param if (lenorind!=SQL_NULL_DATA || lenorind!=SQL_NO_TOTAL) { CONSOLEPRINTF(("Returned parameter = '%s'",paramval)); } // - get number of result columns SQLSMALLINT numcolumns; SQLSMALLINT stringlength; // - get number of columns res = SafeSQLNumResultCols(statement,&numcolumns); odbcagentP->checkStatementError(res,statement); // - fetch result row(s) int rownum=0; while (true) { // try to fetch row res=SafeSQLFetch(statement); if (!odbcagentP->checkStatementHasData(res,statement)) break; // done // we have a row to show if (rownum>=maxrows) { CONSOLEPRINTF(("\nMore rows in result than allowed to display")); break; } // Show Row no rownum++; CONSOLEPRINTF(("\nResult Row #%d: ",rownum)); // fetch data for (int i=1; i<=numcolumns; i++) { // - get name of the column const int maxnamelen=100; SQLCHAR colname[maxnamelen]; SQLSMALLINT colnamelen; SQLINTEGER dummy; res=SQLColAttribute ( statement, // statement handle i, // column number SQL_DESC_BASE_COLUMN_NAME, // return column base name colname, // col name return buffer maxnamelen, // col name return buffer size &colnamelen, // no string length expected (SQLLEN*)&dummy // dummy ); if (res!=SQL_SUCCESS) { strcpy((char *)colname,""); } // - get data of the column in this row const int maxdatalen=100; SQLCHAR databuf[maxdatalen]; SQLINTEGER actualLength; res = SQLGetData( statement, // statement handle i, // column number SQL_C_CHAR, // target type: string &databuf, // Target Value buffer pointer maxdatalen, // max size of value (SQLLEN*)&actualLength ); if (res!=SQL_SUCCESS) break; // no more columns if (actualLength==SQL_NULL_DATA || actualLength==SQL_NO_TOTAL) { strcpy((char *)databuf,""); } CONSOLEPRINTF((" %3d. %20s : %s",i,colname,databuf)); } } CONSOLEPRINTF(("")); SafeSQLCloseCursor(statement); // dispose statement handle SafeSQLFreeHandle(SQL_HANDLE_STMT,statement); } catch (exception &e) { // dispose statement handle SafeSQLCloseCursor(statement); SafeSQLFreeHandle(SQL_HANDLE_STMT,statement); // show error CONSOLEPRINTF(("ODBC Error : %s",e.what())); return EXIT_FAILURE; } catch (...) { // dispose statement handle SafeSQLCloseCursor(statement); SafeSQLFreeHandle(SQL_HANDLE_STMT,statement); // show error CONSOLEPRINTF(("ODBC caused unknown exception")); return EXIT_FAILURE; } return EXIT_SUCCESS; } // execSQL #endif // SYSYNC_TOOL // names for transaction isolation modes const char *TxnIsolModeNames[numTxnIsolModes] = { // Note: these MUST be in the same order as // Win32/ODBC defined SQL_TXN_READ_UNCOMMITTED..SQL_TXN_SERIALIZABLE // bits appear in the transaction bitmasks. "read-uncommitted", "read-committed", "repeatable", "serializable", // special values "none", "default" }; // Config TOdbcAgentConfig::TOdbcAgentConfig(TConfigElement *aParentElement) : TCustomAgentConfig(aParentElement) { // nop so far } // TOdbcAgentConfig::TOdbcAgentConfig TOdbcAgentConfig::~TOdbcAgentConfig() { clear(); } // TOdbcAgentConfig::~TOdbcAgentConfig // init defaults void TOdbcAgentConfig::clear(void) { // init defaults #ifdef ODBCAPI_SUPPORT // - ODBC data source fDataSource.erase(); fUsername.erase(); fPassword.erase(); #ifdef SCRIPT_SUPPORT fAfterConnectScript.erase(); #endif // - usually, SQLSetConnectAttr() is not problematic fNoConnectAttrs=false; // - use medium timeout by default fODBCTimeout=30; // - use DB default fODBCTxnMode=txni_default; // - cursor library usage fUseCursorLib=false; // use driver (this is also the ODBC default) // - device table fGetDeviceSQL.erase(); fNewDeviceSQL.erase(); fSaveNonceSQL.erase(); fSaveInfoSQL.erase(); fSaveDevInfSQL.erase(); fLoadDevInfSQL.erase(); // - auth fUserKeySQL.erase(); fClearTextPw=true; // otherwise, Nonce auth is not possible fMD5UserPass=false; // exclusive with ClearTextPw fMD5UPAsHex=false; // - datetime fGetCurrentDateTimeSQL.erase(); // - statement to save log info fWriteLogSQL.erase(); #endif // ODBCAPI_SUPPORT fQuotingMode=qm_duplsingle; // default to what was hard-coded before it became configurable in 2.1.1.5 // clear inherited inherited::clear(); } // TOdbcAgentConfig::clear #ifdef SCRIPT_SUPPORT // ODBC agent specific script functions // ==================================== class TODBCCommonFuncs { public: // string DBLITERAL(variant value, string dbfieldtype) static void func_DBLiteral(TItemField *&aTermP, TScriptContext *aFuncContextP) { TODBCApiAgent *agentP = static_cast(aFuncContextP->getCallerContext()); string tname,literal; TItemField *fieldP = aFuncContextP->getLocalVar(0); // the field to be converted aFuncContextP->getLocalVar(1)->getAsString(tname); // DB type string // search DB type, default to string sInt16 ty; TDBFieldType dbfty=dbft_string; if (StrToEnum(DBFieldTypeNames,numDBfieldTypes,ty,tname.c_str())) dbfty=(TDBFieldType)ty; // now create literal literal.erase(); TOdbcAgentConfig *cfgP = static_cast(aFuncContextP->getCallerContext())->fConfigP; timecontext_t tctx; TCharSets chs; TLineEndModes lem; TQuotingModes qm; if (agentP->fScriptContextDatastore) { TOdbcDSConfig *dsCfgP = static_cast( static_cast(agentP->fScriptContextDatastore)->fConfigP ); tctx=dsCfgP->fDataTimeZone; chs=dsCfgP->fDataCharSet; lem=dsCfgP->fDataLineEndMode; qm=dsCfgP->fQuotingMode; } else { tctx=cfgP->fCurrentDateTimeZone; chs=cfgP->fDataCharSet; lem=cfgP->fDataLineEndMode; qm=cfgP->fQuotingMode; } sInt32 s=0; agentP->appendFieldValueLiteral( *fieldP,dbfty,0,literal, chs, lem, qm, tctx, s ); // return it aTermP->setAsString(literal); }; // func_DBLiteral #ifdef ODBCAPI_SUPPORT // SETDBCONNECTSTRING(string dbconnectstring) // sets DB connect string, useful in to switch database // depending on user static void func_SetDBConnectString(TItemField *&aTermP, TScriptContext *aFuncContextP) { TODBCApiAgent *agentP = static_cast(aFuncContextP->getCallerContext()); // - close the current script statement (if any) agentP->commitAndCloseScriptStatement(); // - close the current connection (if any) agentP->closeODBCConnection(agentP->fODBCConnectionHandle); // - assign new DB connection string which will be used for next connection aFuncContextP->getLocalVar(0)->getAsString(agentP->fSessionDBConnStr); // override default DB connect string from config } // func_SetDBConnectString // SETDBPASSWORD(string password) // sets password, useful when using SETDBCONNECTSTRING() to switch databases // depending on user static void func_SetDBPassword(TItemField *&aTermP, TScriptContext *aFuncContextP) { TODBCApiAgent *agentP = static_cast(aFuncContextP->getCallerContext()); // - assign new DB connection password which will be used for next connection aFuncContextP->getLocalVar(0)->getAsString(agentP->fSessionDBPassword); // override default DB password from config } // func_SetDBPassword #endif // ODBCAPI_SUPPORT // integer SQLEXECUTE(string statement) // executes statement, returns 0 or ODBC error code static void func_SQLExecute(TItemField *&aTermP, TScriptContext *aFuncContextP) { string sql; #ifdef ODBCAPI_SUPPORT SQLRETURN res; #endif TODBCApiAgent *agentP = static_cast(aFuncContextP->getCallerContext()); TODBCApiDS *datastoreP = static_cast(agentP->fScriptContextDatastore); aFuncContextP->getLocalVar(0)->getAsString(sql); // get SQL to be executed bool ok = true; // assume ok SQLHSTMT stmt = SQL_NULL_HANDLE; try { if (datastoreP) { // do datastore-level substitutions and parameter mapping datastoreP->resetSQLParameterMaps(); datastoreP->DoDataSubstitutions( sql, datastoreP->fConfigP->fFieldMappings.fFieldMapList, 0, // standard set false, // not for write false, // not for update aFuncContextP->fTargetItemP // item in this context, if any ); #ifdef SQLITE_SUPPORT if (!datastoreP->fUseSQLite) #endif { #ifdef ODBCAPI_SUPPORT stmt = agentP->getScriptStatement(); #endif // ODBCAPI_SUPPORT } } else { #ifdef ODBCAPI_SUPPORT // do agent-level substitutions and parameter mapping stmt=agentP->getScriptStatement(); agentP->resetSQLParameterMaps(); agentP->DoSQLSubstitutions(sql); #else // %%% no session level SQLEXECUTE for now aTermP->setAsBoolean(false); POBJDEBUGPUTSX(aFuncContextP->getSession(),DBG_ERROR,"SQLEXECUTE() can only be used in datastore context for non-ODBC!"); return; #endif } // execute SQL statement #ifdef SYDEBUG if (POBJDEBUGTEST(aFuncContextP->getSession(),DBG_SCRIPTS+DBG_DBAPI)) { POBJDEBUGPUTSX(aFuncContextP->getSession(),DBG_DBAPI,"SQL issued by SQLEXECUTE() script function:"); POBJDEBUGPUTSX(aFuncContextP->getSession(),DBG_DBAPI,sql.c_str()); } else { POBJDEBUGPUTSX(aFuncContextP->getSession(),DBG_DBAPI,"SQLEXECUTE() executes a statement (hidden because script debugging is off)"); } #endif if (datastoreP) { datastoreP->prepareSQLStatement(stmt,sql.c_str(),true,NULL); datastoreP->bindSQLParameters(stmt,true); // execute in datastore datastoreP->execSQLStatement(stmt, sql, true, NULL, true); // do datastore-level parameter mapping datastoreP->saveAndCleanupSQLParameters(stmt,true); } #ifdef ODBCAPI_SUPPORT else { agentP->bindSQLParameters(stmt); // execute res = SafeSQLExecDirect( stmt, (SQLCHAR *)sql.c_str(), SQL_NTS ); agentP->checkStatementHasData(res,stmt); // treat NO_DATA error as ok // do agent-level parameter mapping agentP->saveAndCleanupSQLParameters(stmt); } #endif // ODBCAPI_SUPPORT } catch (exception &e) { POBJDEBUGPRINTFX(aFuncContextP->getSession(),DBG_ERROR,( "SQLEXECUTE() caused Error: %s", e.what() )); ok=false; } // return ok status aTermP->setAsBoolean(ok); }; // func_SQLExecute // integer SQLFETCHROW() // fetches next row, returns true if data found static void func_SQLFetchRow(TItemField *&aTermP, TScriptContext *aFuncContextP) { #ifdef ODBCAPI_SUPPORT SQLRETURN res; #endif TODBCApiAgent *agentP = static_cast(aFuncContextP->getCallerContext()); TODBCApiDS *datastoreP = static_cast(agentP->fScriptContextDatastore); bool ok = true; // assume ok try { if (datastoreP) { ok=datastoreP->fetchNextRow(agentP->fScriptStatement,true); // always data access } #ifdef ODBCAPI_SUPPORT else { // - fetch result row res=SafeSQLFetch(agentP->getScriptStatement()); ok=agentP->checkStatementHasData(res,agentP->getScriptStatement()); } #endif } catch (exception &e) { POBJDEBUGPRINTFX(aFuncContextP->getSession(),DBG_ERROR,( "SQLFETCHROW() caused Error: %s", e.what() )); ok=false; } // return ok status aTermP->setAsBoolean(ok); }; // func_SQLFetchRow // integer SQLGETCOLUMN(integer index, &field, string dbtype) // gets value of next column into specified variable // returns true if successful static void func_SQLGetColumn(TItemField *&aTermP, TScriptContext *aFuncContextP) { TODBCApiAgent *agentP = static_cast(aFuncContextP->getCallerContext()); TODBCApiDS *datastoreP = static_cast(agentP->fScriptContextDatastore); bool ok = true; // assume ok // get column index sInt16 colindex = aFuncContextP->getLocalVar(0)->getAsInteger(); // get field reference TItemField *fldP = aFuncContextP->getLocalVar(1); // get DB type for field string tname; aFuncContextP->getLocalVar(2)->getAsString(tname); // DB type string sInt16 ty; TDBFieldType dbfty=dbft_string; // default to string if (StrToEnum(DBFieldTypeNames,numDBfieldTypes,ty,tname.c_str())) dbfty=(TDBFieldType)ty; // get DB params TOdbcAgentConfig *cfgP = agentP->fConfigP; timecontext_t tctx; bool uzo; #ifdef SQLITE_SUPPORT bool sqlite=false; #endif TCharSets chs; if (datastoreP) { TOdbcDSConfig *dsCfgP = static_cast(datastoreP->fConfigP); tctx=dsCfgP->fDataTimeZone; chs=dsCfgP->fDataCharSet; uzo=dsCfgP->fUserZoneOutput; #ifdef SQLITE_SUPPORT sqlite=datastoreP->fUseSQLite; #endif } else { tctx=cfgP->fCurrentDateTimeZone; chs=cfgP->fDataCharSet; uzo=false; #ifdef SQLITE_SUPPORT sqlite=false; // no SQLite support at agent level #endif } // get value now try { #ifdef SQLITE_SUPPORT if (sqlite && datastoreP) { // - get column value as field if (!agentP->getSQLiteColValueAsField( datastoreP->fSQLiteStmtP, colindex-1, // SQLITE colindex starts at 0, not 1 like in ODBC dbfty, fldP, chs, tctx, uzo )) fldP->unAssign(); // NULL -> unassigned } else #endif { #ifdef ODBCAPI_SUPPORT // - get column value as field if (!agentP->getColumnValueAsField( agentP->getScriptStatement(), colindex, dbfty, fldP, chs, tctx, uzo )) fldP->unAssign(); // NULL -> unassigned #endif } } catch (exception &e) { POBJDEBUGPRINTFX(aFuncContextP->getSession(),DBG_ERROR,( "SQLGETCOLUMN() caused Error: %s", e.what() )); ok=false; } // return ok status aTermP->setAsBoolean(ok); }; // func_SQLGetColumn // SQLCOMMIT() // commits agent-level transactions static void func_SQLCommit(TItemField *&aTermP, TScriptContext *aFuncContextP) { TODBCApiAgent *agentP = static_cast(aFuncContextP->getCallerContext()); TODBCApiDS *datastoreP = static_cast(agentP->fScriptContextDatastore); if (datastoreP) { // we might need finalizing (for SQLite...) datastoreP->finalizeSQLStatement(agentP->fScriptStatement, true); } #ifdef ODBCAPI_SUPPORT try { agentP->commitAndCloseScriptStatement(); } catch (exception &e) { POBJDEBUGPRINTFX(aFuncContextP->getSession(),DBG_ERROR,( "SQLCOMMIT() caused Error: %s", e.what() )); } #endif // ODBCAPI_SUPPORT }; // func_SQLCommit // SQLROLLBACK() // rollback agent-level transactions static void func_SQLRollback(TItemField *&aTermP, TScriptContext *aFuncContextP) { TODBCApiAgent *agentP = static_cast(aFuncContextP->getCallerContext()); TODBCApiDS *datastoreP = static_cast(agentP->fScriptContextDatastore); if (datastoreP) { // we might need finalizing (for SQLite...) datastoreP->finalizeSQLStatement(agentP->fScriptStatement, true); } #ifdef ODBCAPI_SUPPORT try { if (agentP->fScriptStatement!=SQL_NULL_HANDLE) { // only roll back if we have used a statement at all in scripts SafeSQLFreeHandle(SQL_HANDLE_STMT,agentP->fScriptStatement); agentP->fScriptStatement=SQL_NULL_HANDLE; SafeSQLEndTran(SQL_HANDLE_DBC,agentP->getODBCConnectionHandle(),SQL_ROLLBACK); } } catch (exception &e) { POBJDEBUGPRINTFX(aFuncContextP->getSession(),DBG_ERROR,( "SQLROLLBACK() caused Error: %s", e.what() )); } #endif // ODBCAPI_SUPPORT }; // func_SQLRollback }; // TODBCCommonFuncs const uInt8 param_DBLiteral[] = { VAL(fty_none), VAL(fty_string) }; const uInt8 param_OneString[] = { VAL(fty_string) }; const uInt8 param_SQLGetColumn[] = { VAL(fty_integer), REF(fty_none), VAL(fty_string) }; // builtin function defs for ODBC database and login contexts const TBuiltInFuncDef ODBCAgentAndDSFuncDefs[] = { // generic DB access { "DBLITERAL", TODBCCommonFuncs::func_DBLiteral, fty_string, 2, param_DBLiteral }, // note that there's a second version of this in ODBCDatastore #ifdef ODBCAPI_SUPPORT { "SETDBCONNECTSTRING", TODBCCommonFuncs::func_SetDBConnectString, fty_none, 1, param_OneString }, { "SETDBPASSWORD", TODBCCommonFuncs::func_SetDBPassword, fty_none, 1, param_OneString }, #endif // ODBCAPI_SUPPORT { "SQLEXECUTE", TODBCCommonFuncs::func_SQLExecute, fty_integer, 1, param_OneString }, { "SQLFETCHROW", TODBCCommonFuncs::func_SQLFetchRow, fty_integer, 0, NULL }, { "SQLGETCOLUMN", TODBCCommonFuncs::func_SQLGetColumn, fty_integer, 3, param_SQLGetColumn }, { "SQLCOMMIT", TODBCCommonFuncs::func_SQLCommit, fty_none, 0, NULL }, { "SQLROLLBACK", TODBCCommonFuncs::func_SQLRollback, fty_none, 0, NULL } }; #ifdef BINFILE_ALWAYS_ACTIVE // Binfile based version just has the SQL access functions // function table for connectionscript const TFuncTable ODBCAgentFuncTable = { sizeof(ODBCAgentAndDSFuncDefs) / sizeof(TBuiltInFuncDef), // size of table ODBCAgentAndDSFuncDefs, // table pointer NULL // no chain func }; #else // Full range of functions for non-binfile-based version // chain from ODBC agent funcs to Custom agent Funcs extern const TFuncTable CustomAgentFuncTable2; static void *ODBCAgentChainFunc1(void *&aCtx) { // caller context remains unchanged // -> no change needed // next table is Custom Agent's general function table return (void *)&CustomAgentFuncTable2; } // ODBCAgentChainFunc1 // function table which is chained from login-context function table const TFuncTable ODBCAgentFuncTable2 = { sizeof(ODBCAgentAndDSFuncDefs) / sizeof(TBuiltInFuncDef), // size of table ODBCAgentAndDSFuncDefs, // table pointer ODBCAgentChainFunc1 // chain to non-ODBC specific agent Funcs }; // chain from login context agent funcs to general agent funcs extern const TFuncTable ODBCDSFuncTable2; static void *ODBCAgentChainFunc(void *&aCtx) { // caller context remains unchanged // -> no change needed // next table is Agent's general function table return (void *)&ODBCAgentFuncTable2; } // ODBCAgentChainFunc // function table for login context scripts // Note: ODBC agent has no login-context specific functions, but is just using those from customImplAgent const TFuncTable ODBCAgentFuncTable = { sizeof(CustomAgentFuncDefs) / sizeof(TBuiltInFuncDef), // size of table CustomAgentFuncDefs, // table pointer ODBCAgentChainFunc // chain to general agent funcs. }; #endif // not BASED_ON_BINFILE_CLIENT // chain from agent funcs to ODBC local datastore funcs (when chained via ODBCDSFuncTable1 extern const TFuncTable ODBCDSFuncTable2; static void *ODBCDSChainFunc1(void *&aCtx) { // caller context for datastore-level functions is the datastore pointer if (aCtx) aCtx = static_cast(aCtx)->fScriptContextDatastore; // next table is ODBC datastore's return (void *)&ODBCDSFuncTable2; } // ODBCDSChainFunc1 // function table for linking in Custom agent level functions between ODBC agent and ODBC DS level functions const TFuncTable ODBCAgentFuncTable3 = { sizeof(CustomAgentAndDSFuncDefs) / sizeof(TBuiltInFuncDef), // size of agent's table CustomAgentAndDSFuncDefs, // table pointer to agent's general purpose (non login-context specific) funcs ODBCDSChainFunc1 // NOW finally chain back to ODBC datastore level DB functions }; // chain from ODBC agent funcs to generic agent funcs and THEN back to ODBC DS funcs extern const TFuncTable ODBCDSFuncTable2; static void *ODBCDSChainFunc2(void *&aCtx) { // caller context remains unchanged // -> no change needed // next table is Agent's general function table return (void *)&ODBCAgentFuncTable3; } // ODBCDSChainFunc2 // function table which is used by ODBC datastore scripts to access agent-level funcs and then chain // back to datastore level funcs const TFuncTable ODBCDSFuncTable1 = { sizeof(ODBCAgentAndDSFuncDefs) / sizeof(TBuiltInFuncDef), // size of agent's table ODBCAgentAndDSFuncDefs, // table pointer to agent's general purpose (non login-context specific) funcs ODBCDSChainFunc2 // first chain to Custom Agent level functions, but then back to ODBC datastore level DB functions }; #endif // config element parsing bool TOdbcAgentConfig::localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine) { // checking the elements #ifdef ODBCAPI_SUPPORT // - ODBC connection if (strucmp(aElementName,"datasource")==0) expectString(fDataSource); else if (strucmp(aElementName,"dbuser")==0) expectString(fUsername); else if (strucmp(aElementName,"dbpass")==0) expectString(fPassword); else if (strucmp(aElementName,"dbconnectionstring")==0) expectString(fDBConnStr); // - odbc timeout else if (strucmp(aElementName,"dbtimeout")==0) expectInt32(fODBCTimeout); // - transaction mode else if (strucmp(aElementName,"transactionmode")==0) expectEnum(sizeof(fODBCTxnMode),&fODBCTxnMode,TxnIsolModeNames,numTxnIsolModes); // - preventing use of SQLSetConnectAttr() else if (strucmp(aElementName,"preventconnectattrs")==0) expectBool(fNoConnectAttrs); // - cursor library usage else if (strucmp(aElementName,"usecursorlib")==0) expectBool(fUseCursorLib); #ifdef SCRIPT_SUPPORT else if (strucmp(aElementName,"afterconnectscript")==0) expectScript(fAfterConnectScript,aLine,getAgentFuncTableP()); #endif #ifdef HAS_SQL_ADMIN // - device table else if (strucmp(aElementName,"getdevicesql")==0) expectString(fGetDeviceSQL); else if (strucmp(aElementName,"newdevicesql")==0) expectString(fNewDeviceSQL); else if (strucmp(aElementName,"savenoncesql")==0) expectString(fSaveNonceSQL); else if (strucmp(aElementName,"saveinfosql")==0) expectString(fSaveInfoSQL); else if (strucmp(aElementName,"savedevinfsql")==0) expectString(fSaveDevInfSQL); else if (strucmp(aElementName,"loaddevinfsql")==0) expectString(fLoadDevInfSQL); // - user auth SQL else if (strucmp(aElementName,"userkeysql")==0) expectString(fUserKeySQL); else if (strucmp(aElementName,"cleartextpw")==0) expectBool(fClearTextPw); else if (strucmp(aElementName,"md5userpass")==0) expectBool(fMD5UserPass); else if (strucmp(aElementName,"md5hex")==0) expectBool(fMD5UPAsHex); // - database time SQL else if (strucmp(aElementName,"timestampsql")==0) expectString(fGetCurrentDateTimeSQL); // - statement to save log info else if (strucmp(aElementName,"writelogsql")==0) expectString(fWriteLogSQL); else #endif // HAS_SQL_ADMIN #endif // ODBCAPI_SUPPORT // - quoting mode if (strucmp(aElementName,"quotingmode")==0) expectEnum(sizeof(fQuotingMode),&fQuotingMode,quotingModeNames,numQuotingModes); // - none known here else return inherited::localStartElement(aElementName,aAttributes,aLine); // ok return true; } // TOdbcAgentConfig::localStartElement // resolve void TOdbcAgentConfig::localResolve(bool aLastPass) { if (aLastPass) { #ifdef ODBCAPI_SUPPORT // check for required settings // - create fDBConnStr from dsn,user,pw if none specified explicitly if (fDBConnStr.empty()) { // Note: we do not add the password here as fDBConnStr is shown in logs. StringObjPrintf(fDBConnStr,"DSN=%s;UID=%s;",fDataSource.c_str(),fUsername.c_str()); } #ifdef HAS_SQL_ADMIN if (fClearTextPw && fMD5UserPass) throw TConfigParseException("only one of 'cleartextpw' and 'md5userpass' can be set"); #ifdef SYSYNC_SERVER if (IS_SERVER) { if (fAutoNonce && !fClearTextPw && !fMD5UserPass) throw TConfigParseException("if 'autononce' is set, 'cleartextpw' or 'md5userpass' MUST be set as well"); } #endif // SYSYNC_SERVER #ifdef SYSYNC_CLIENT if (IS_CLIENT) { #ifndef NO_LOCAL_DBLOGIN if (fNoLocalDBLogin && !fUserKeySQL.empty()) throw TConfigParseException("'nolocaldblogin' is not allowed when 'userkeysql' is defined"); #endif } #endif // SYSYNC_CLIENT #endif // HAS_SQL_ADMIN #endif // ODBCAPI_SUPPORT } // resolve inherited // - Note: this resolves the ancestor's scripts first inherited::localResolve(aLastPass); } // TOdbcAgentConfig::localResolve #ifdef SCRIPT_SUPPORT // resolve scripts void TOdbcAgentConfig::ResolveAPIScripts(void) { #ifdef ODBCAPI_SUPPORT // afterconnect script has it's own context as it might be called nested in other scripts (e.g. triggered by SQLEXECUTE) TScriptContext *ctxP = NULL; TScriptContext::resolveScript(getSyncAppBase(),fAfterConnectScript,ctxP,NULL); if (ctxP) delete ctxP; #endif } // TOdbcAgentConfig::localResolve #endif /* public TODBCApiAgent members */ // private init routine for both client and server constructor TODBCApiAgent::TODBCApiAgent(TSyncAppBase *aAppBaseP, TSyncSessionHandle *aSessionHandleP, cAppCharP aSessionID) : TCustomImplAgent(aAppBaseP, aSessionHandleP, aSessionID) { // init basics #ifdef ODBCAPI_SUPPORT fODBCConnectionHandle = SQL_NULL_HANDLE; fODBCEnvironmentHandle = SQL_NULL_HANDLE; #ifdef SCRIPT_SUPPORT fScriptStatement = SQL_NULL_HANDLE; fAfterConnectContext = NULL; #endif #endif // ODBCAPI_SUPPORT // get config for agent and save direct link to agent config for easy reference fConfigP = static_cast(getRootConfig()->fAgentConfigP); // Note: Datastores are already created from config #ifdef ODBCAPI_SUPPORT // - assign default DB connection string and password fSessionDBConnStr = fConfigP->fDBConnStr; fSessionDBPassword = fConfigP->fPassword; #ifdef SCRIPT_SUPPORT // - rebuild afterconnect script TScriptContext::rebuildContext(getSyncAppBase(),fConfigP->fAfterConnectScript,fAfterConnectContext,this,true); #endif #endif } // TODBCApiAgent::TODBCApiAgent // destructor TODBCApiAgent::~TODBCApiAgent() { // make sure everything is terminated BEFORE destruction of hierarchy begins TerminateSession(); } // TODBCApiAgent::~TODBCApiAgent // Terminate session void TODBCApiAgent::TerminateSession() { if (!fTerminated) { string msg,state; // Note that the following will happen BEFORE destruction of // individual datastores, so make sure datastore have their ODBC // stuff finished before disposing environment InternalResetSession(); #ifdef ODBCAPI_SUPPORT #ifdef SCRIPT_SUPPORT // get rid of afterconnect context if (fAfterConnectContext) delete fAfterConnectContext; #endif SQLRETURN res; if (fODBCEnvironmentHandle!=SQL_NULL_HANDLE) { // release the enviroment res=SafeSQLFreeHandle(SQL_HANDLE_ENV,fODBCEnvironmentHandle); if (getODBCError(res,msg,state,SQL_HANDLE_ENV,fODBCEnvironmentHandle)) { DEBUGPRINTFX(DBG_ERROR,("~TODBCApiAgent: SQLFreeHandle(ENV) failed: %s",msg.c_str())); } fODBCEnvironmentHandle=SQL_NULL_HANDLE; } #endif // Make sure datastores know that the agent will go down soon announceDestruction(); } inherited::TerminateSession(); } // TODBCApiAgent::TerminateSession // Reset session void TODBCApiAgent::InternalResetSession(void) { // reset all datastores now to make sure ODBC is reset before we close the // global connection and the environment handle (if called by destructor)! // (Note: TerminateDatastores() will be called again by ancestors) TerminateDatastores(); #ifdef ODBCAPI_SUPPORT #ifdef SCRIPT_SUPPORT // commit connection (possible scripted statements) commitAndCloseScriptStatement(); #endif // clear parameter maps resetSQLParameterMaps(); // close session level connection if not already closed closeODBCConnection(fODBCConnectionHandle); #endif // ODBCAPI_SUPPORT } // TODBCApiAgent::InternalResetSession // Virtual version void TODBCApiAgent::ResetSession(void) { // do my own stuff InternalResetSession(); // let ancestor do its stuff inherited::ResetSession(); } // TODBCApiAgent::ResetSession #ifdef ODBCAPI_SUPPORT #ifdef SCRIPT_SUPPORT // commit and close possibly open script statement void TODBCApiAgent::commitAndCloseScriptStatement(void) { if (fODBCConnectionHandle!=SQL_NULL_HANDLE) { // free script statement, if any still open if (fScriptStatement!=SQL_NULL_HANDLE) { PDEBUGPRINTFX(DBG_DBAPI+DBG_EXOTIC,("Script statement exists -> closing it now")); SafeSQLFreeHandle(SQL_HANDLE_STMT,fScriptStatement); fScriptStatement=SQL_NULL_HANDLE; } // now commit transaction SafeSQLEndTran(SQL_HANDLE_DBC,fODBCConnectionHandle,SQL_COMMIT); } } // TODBCApiAgent::commitAndCloseScriptStatement // get statement for executing scripted SQL HSTMT TODBCApiAgent::getScriptStatement(void) { if (fScriptStatement==SQL_NULL_HANDLE) { fScriptStatement=newStatementHandle(getODBCConnectionHandle()); } return fScriptStatement; } // TODBCApiAgent::getScriptStatement #endif #endif // ODBCAPI_SUPPORT #ifdef ODBCAPI_SUPPORT #if !defined(NO_AV_GUARDING) // && !__option(microsoft_exceptions) #ifndef _WIN32 #error "AV Guarding is only for Win32" #endif // SEH-aware versions of ODBC calls (to avoid that crashing drivers blame our server) // ================================================================================== // Special exception returning the SEH code TODBCSEHexception::TODBCSEHexception(uInt32 aCode) { StringObjPrintf(fMessage,"ODBC Driver caused SEH/AV Code=%08lX",aCode); } // TODBCSEHexception::TODBCSEHexception // define what object is to be thrown #define SEH_THROWN_OBJECT TODBCSEHexception(GetExceptionCode()) SQLRETURN SafeSQLAllocHandle( SQLSMALLINT HandleType, SQLHANDLE InputHandle, SQLHANDLE * OutputHandlePtr) { __try { /* #ifndef RELEASE_VERSION // %%% causes AV InputHandle=0; *((char *)(InputHandle)) = 'X'; #else #error "throw that out!! %%%%" #endif */ return SQLAllocHandle(HandleType,InputHandle,OutputHandlePtr); } __except(EXCEPTION_EXECUTE_HANDLER) { throw SEH_THROWN_OBJECT; } } // SafeSQLAllocHandle SQLRETURN SafeSQLFreeHandle( SQLSMALLINT HandleType, SQLHANDLE Handle) { __try { return SQLFreeHandle(HandleType,Handle); } __except(EXCEPTION_EXECUTE_HANDLER) { throw SEH_THROWN_OBJECT; } } // SafeSQLFreeHandle SQLRETURN SafeSQLSetEnvAttr( SQLHENV EnvironmentHandle, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLINTEGER StringLength) { __try { return SQLSetEnvAttr(EnvironmentHandle,Attribute,ValuePtr,StringLength); } __except(EXCEPTION_EXECUTE_HANDLER) { throw SEH_THROWN_OBJECT; } } // SafeSQLSetEnvAttr SQLRETURN SafeSQLSetConnectAttr( SQLHDBC ConnectionHandle, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLINTEGER StringLength) { __try { return SQLSetConnectAttr(ConnectionHandle,Attribute,ValuePtr,StringLength); } __except(EXCEPTION_EXECUTE_HANDLER) { throw SEH_THROWN_OBJECT; } } // SafeSQLSetConnectAttr SQLRETURN SafeSQLConnect( SQLHDBC ConnectionHandle, SQLCHAR * ServerName, SQLSMALLINT NameLength1, SQLCHAR * UserName, SQLSMALLINT NameLength2, SQLCHAR * Authentication, SQLSMALLINT NameLength3) { __try { return SQLConnect(ConnectionHandle,ServerName,NameLength1,UserName,NameLength2,Authentication,NameLength3); } __except(EXCEPTION_EXECUTE_HANDLER) { throw SEH_THROWN_OBJECT; } } // SafeSQLConnect SQLRETURN SafeSQLDriverConnect( SQLHDBC ConnectionHandle, SQLHWND WindowHandle, SQLCHAR * InConnectionString, SQLSMALLINT StringLength1, SQLCHAR * OutConnectionString, SQLSMALLINT BufferLength, SQLSMALLINT * StringLength2Ptr, SQLUSMALLINT DriverCompletion) { __try { return SQLDriverConnect(ConnectionHandle,WindowHandle,InConnectionString,StringLength1,OutConnectionString,BufferLength,StringLength2Ptr,DriverCompletion); } __except(EXCEPTION_EXECUTE_HANDLER) { throw SEH_THROWN_OBJECT; } } // SafeSQLDriverConnect SQLRETURN SafeSQLGetInfo( SQLHDBC ConnectionHandle, SQLUSMALLINT InfoType, SQLPOINTER InfoValuePtr, SQLSMALLINT BufferLength, SQLSMALLINT * StringLengthPtr) { __try { return SQLGetInfo(ConnectionHandle,InfoType,InfoValuePtr,BufferLength,StringLengthPtr); } __except(EXCEPTION_EXECUTE_HANDLER) { throw SEH_THROWN_OBJECT; } } // SafeSQLGetInfo SQLRETURN SafeSQLEndTran( SQLSMALLINT HandleType, SQLHANDLE Handle, SQLSMALLINT CompletionType) { __try { return SQLEndTran(HandleType,Handle,CompletionType); } __except(EXCEPTION_EXECUTE_HANDLER) { throw SEH_THROWN_OBJECT; } } // SafeSQLEndTran SQLRETURN SafeSQLExecDirect( SQLHSTMT StatementHandle, SQLCHAR * StatementText, SQLINTEGER TextLength) { __try { return SQLExecDirect(StatementHandle,StatementText,TextLength); } __except(EXCEPTION_EXECUTE_HANDLER) { throw SEH_THROWN_OBJECT; } } // SafeSQLExecDirect #ifdef ODBC_UNICODE SQLRETURN SafeSQLExecDirectW( SQLHSTMT StatementHandle, SQLWCHAR * StatementText, SQLINTEGER TextLength) { __try { return SQLExecDirectW(StatementHandle,StatementText,TextLength); } __except(EXCEPTION_EXECUTE_HANDLER) { throw SEH_THROWN_OBJECT; } } // SafeSQLExecDirectW #endif SQLRETURN SafeSQLFetch( SQLHSTMT StatementHandle) { __try { return SQLFetch(StatementHandle); } __except(EXCEPTION_EXECUTE_HANDLER) { throw SEH_THROWN_OBJECT; } } // SafeSQLFetch SQLRETURN SafeSQLNumResultCols( SQLHSTMT StatementHandle, SQLSMALLINT * ColumnCountPtr) { __try { return SQLNumResultCols(StatementHandle,ColumnCountPtr); } __except(EXCEPTION_EXECUTE_HANDLER) { throw SEH_THROWN_OBJECT; } } // SafeSQLNumResultCols SQLRETURN SafeSQLGetData( SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNumber, SQLSMALLINT TargetType, SQLPOINTER TargetValuePtr, SQLINTEGER BufferLength, SQLLEN * StrLen_or_IndPtr) { __try { return SQLGetData(StatementHandle,ColumnNumber,TargetType,TargetValuePtr,BufferLength,StrLen_or_IndPtr); } __except(EXCEPTION_EXECUTE_HANDLER) { throw SEH_THROWN_OBJECT; } } // SQLRETURN SafeSQLCloseCursor( SQLHSTMT StatementHandle) { __try { return SQLCloseCursor(StatementHandle); } __except(EXCEPTION_EXECUTE_HANDLER) { throw SEH_THROWN_OBJECT; } } // SafeSQLCloseCursor #endif // AV Guarding #endif // ODBCAPI_SUPPORT // append field value as literal to SQL text // - returns true if field(s) were not empty // - even non-existing or empty field will append at least NULL or '' to SQL bool TODBCApiAgent::appendFieldValueLiteral( TItemField &aField,TDBFieldType aDBFieldType, uInt32 aMaxSize, string &aSQL, TCharSets aDataCharSet, TLineEndModes aDataLineEndMode, TQuotingModes aQuotingMode, timecontext_t aTimeContext, sInt32 &aRecordSize ) { bool dat=false; bool tim=false; bool intts=false; string val; TTimestampField *tsFldP; sInt32 factor; sInt32 sz; sInt16 moffs; lineartime_t ts; timecontext_t tctx; bool isempty=aField.isEmpty(); if ( isempty && aDBFieldType!=dbft_string ) { // non-string field does not have a value: NULL aSQL+="NULL"; } else { switch (aDBFieldType) { // numeric time offsets case dbft_uctoffsfortime_hours: factor = 0; // special case, float goto timezone; case dbft_uctoffsfortime_mins: factor = 1; goto timezone; case dbft_uctoffsfortime_secs: factor = SecsPerMin;; goto timezone; case dbft_zonename: factor = -1; // name, not offset timezone: // get field if (!aField.isBasedOn(fty_timestamp)) goto nullfield; // no timestamp -> no zone tsFldP = static_cast(&aField); // get name or offset tctx = tsFldP->getTimeContext(); if (factor>=0) { // offset requested if (tsFldP->isFloating()) goto nullfield; // floating -> no offset if (!TzResolveToOffset(tctx,moffs,tsFldP->getTimestampAs(TCTX_UNKNOWN),false,tsFldP->getGZones())) goto nullfield; // cannot calc offset -> no zone if (factor==0) StringObjAppendPrintf(aSQL,"%g",(sInt32)moffs/60.0); // make hours with fraction else StringObjAppendPrintf(aSQL,"%ld",(long)moffs * factor); // mins or seconds } else { // name requested if (!TCTX_IS_DURATION(tctx) && !TCTX_IS_DATEONLY(tctx) && TCTX_IS_UNKNOWN(tctx)) goto nullfield; // really floating (not duration or dateonly) -> no zone (and not "FLOATING" string we'd get from TimeZoneContextToName) TimeZoneContextToName(tctx, val, tsFldP->getGZones()); goto asstring; } break; // date and time values case dbft_lineardate: case dbft_unixdate_s: case dbft_unixdate_ms: case dbft_unixdate_us: intts=true; // integer timestamp case dbft_date: // date-only field dat=true; goto settimestamp; case dbft_timefordate: case dbft_time: tim=true; goto settimestamp; case dbft_lineartime: case dbft_unixtime_s: case dbft_nsdate_s: case dbft_unixtime_ms: case dbft_unixtime_us: intts=true; // integer timestamp case dbft_dateonly: // date-only, but stored as timestamp case dbft_timestamp: dat=true; tim=true; settimestamp: // get timestamp in DB time zone if (aField.isBasedOn(fty_timestamp)) { // get it from field in specified zone (or floating) ts=static_cast(&aField)->getTimestampAs(aTimeContext,&tctx); } else { // try to convert ISO8601 string representation aField.getAsString(val); ISO8601StrToTimestamp(val.c_str(), ts, tctx); TzConvertTimestamp(ts,tctx,aTimeContext,getSessionZones(),aTimeContext); } // remove time part on date-only if (dat & !tim) ts = lineartime2dateonlyTime(ts); if (intts) { // Timestamp represented as integer in the DB // - add as integer timestamp // sInt64 ii = lineartimeToDbInt(ts,aDBFieldType); // PDEBUGPRINTFX(DBG_DBAPI+DBG_EXOTIC,( // "ts=%lld -> dbInteger=%lld/0x%llX (UnixToLineartimeOffset=%lld, secondToLinearTimeFactor=%lld)", // ts,ii,ii,UnixToLineartimeOffset,secondToLinearTimeFactor // )); // StringObjAppendPrintf(aSQL,PRINTF_LLD,PRINTF_LLD_ARG(ii)); StringObjAppendPrintf(aSQL,PRINTF_LLD,PRINTF_LLD_ARG(lineartimeToDbInt(ts,aDBFieldType))); } else { // add as ODBC date/time literal lineartimeToODBCLiteralAppend(ts, aSQL, dat, tim); } break; case dbft_numeric: // numeric fields are copied to SQL w/o quotes aField.getAsString(val); aSQL.append(val); // just append break; case dbft_blob: // BLOBs cannot be written literally (should never occur, as we automatically parametrize them) throw TSyncException("FATAL: BLOB fields must be written with parameters"); break; case dbft_string: default: // Database field is string (or unknown), add it as string literal aField.getAsString(val); // only net string sizes are counted sz=val.size(); // net size of string if (sz>sInt32(aMaxSize)) sz=aMaxSize; // limit to what can be actually stored aRecordSize+=sz; // add to count asstring: stringToODBCLiteralAppend( val.c_str(), aSQL, aDataCharSet, aDataLineEndMode, aQuotingMode, aMaxSize ); break; nullfield: aSQL+="NULL"; break; } // switch } // field has a value return !isempty; } // TODBCApiAgent::appendFieldValueLiteral // - make ODBC string literal from UTF8 string void TODBCApiAgent::stringToODBCLiteralAppend( cAppCharP aText, string &aLiteral, TCharSets aCharSet, TLineEndModes aLineEndMode, TQuotingModes aQuotingMode, size_t aMaxBytes ) { aLiteral+='\''; appendUTF8ToString( aText,aLiteral, aCharSet, // charset aLineEndMode, // line end mode aQuotingMode, // quoting mode aMaxBytes // max size (0 if unlimited) ); aLiteral+='\''; } // TODBCApiAgent::stringToODBCLiteralAppend // - make ODBC date/time literals from lineartime_t void TODBCApiAgent::lineartimeToODBCLiteralAppend( lineartime_t aTimestamp, string &aString, bool aWithDate, bool aWithTime, timecontext_t aTsContext, timecontext_t aDBContext ) { // make correct zone if needed if (!TCTX_IS_UNKNOWN(aTsContext)) { TzConvertTimestamp(aTimestamp,aTsContext,aDBContext,getSessionZones(),TCTX_UNKNOWN); } // calculate components sInt16 y,mo,d,h,mi,s,ms; lineartime2date(aTimestamp,&y,&mo,&d); lineartime2time(aTimestamp,&h,&mi,&s,&ms); // create prefix aString+='{'; if (aWithDate && aWithTime) aString+="ts"; else if (aWithTime) aString+="t"; else aString+="d"; aString+=" '"; // add date if selected if (aWithDate) { StringObjAppendPrintf( aString,"%04d-%02d-%02d", y, mo, d ); } // add time if selected if (aWithTime) { if (aWithDate) aString+=' '; // separate StringObjAppendPrintf(aString, "%02d:%02d:%02d", h, mi, s ); // microseconds, if any if (ms!=0) { StringObjAppendPrintf(aString,".%03d",ms); } } // suffix aString+="'}"; } // TODBCApiAgent::lineartimeToODBCLiteralAppend // - make integer-based literals from lineartime_t void TODBCApiAgent::lineartimeToIntLiteralAppend( lineartime_t aTimestamp, string &aString, TDBFieldType aDbfty, timecontext_t aTsContext, timecontext_t aDBContext ) { // make correct zone if needed if (!TCTX_IS_UNKNOWN(aTsContext)) { TzConvertTimestamp(aTimestamp,aTsContext,aDBContext,getSessionZones(),TCTX_UNKNOWN); } // - add as integer timestamp StringObjAppendPrintf(aString,PRINTF_LLD,PRINTF_LLD_ARG(lineartimeToDbInt(aTimestamp,aDbfty))); } // TODBCApiAgent::lineartimeToIntLiteralAppend /*%%% obsolete // - make ODBC date/time literals from UTC timestamp void TODBCApiAgent::timeStampToODBCLiteralAppend(lineartime_t aTimeStamp, string &aString, bool aAsUTC, bool aWithDate, bool aWithTime) { if (aTimeStamp!=0) { if (!aAsUTC) aTimeStamp=makeLocalTimestamp(aTimeStamp); // convert to local time struct tm tim; lineartime2tm(aTimeStamp,&tim); // format as ODBC date/time literal tmToODBCLiteralAppend(tim,aString,aWithDate,aWithTime); } else { aString.append("NULL"); } } // TODBCApiAgent::timeStampToODBCLiteralAppend // - make ODBC date/time literals from struct tm void TODBCApiAgent::tmToODBCLiteralAppend(const struct tm &tim, string &aString, bool aWithDate, bool aWithTime) { // create prefix aString+='{'; if (aWithDate && aWithTime) aString+="ts"; else if (aWithTime) aString+="t"; else aString+="d"; aString+=" '"; // add date if selected if (aWithDate) { StringObjAppendPrintf( aString,"%04d-%02d-%02d", tim.tm_year+1900, tim.tm_mon+1, tim.tm_mday ); } // add time if selected if (aWithTime) { if (aWithDate) aString+=' '; // separate StringObjAppendPrintf(aString, "%02d:%02d:%02d", tim.tm_hour, tim.tm_min, tim.tm_sec ); } // suffix aString+="'}"; } // TODBCApiAgent::tmToODBCLiteralAppend */ // - return quoted version of string if aDoQuote is set // bfo: Problems with XCode (expicit qualification), already within namespace ? //const char *sysync::quoteString(string &aIn, string &aOut, TQuotingModes aQuoteMode) const char *quoteString(string &aIn, string &aOut, TQuotingModes aQuoteMode) { return quoteString(aIn.c_str(),aOut,aQuoteMode); } // TODBCApiAgent::quoteString // - return quoted version of string if aDoQuote is set // bfo: Problems with XCode (expicit qualification), already within namespace ? //const char *sysync::quoteString(const char *aIn, string &aOut, TQuotingModes aQuoteMode) const char *quoteString(const char *aIn, string &aOut, TQuotingModes aQuoteMode) { aOut.erase(); quoteStringAppend(aIn,aOut,aQuoteMode); return aOut.c_str(); } // TODBCApiAgent::quoteString // - append quoted version of string if aDoQuote is set // bfo: Problems with XCode (expicit qualification), already within namespace ? //void sysync::quoteStringAppend(const char *aIn, string &aOut, TQuotingModes aQuoteMode) void quoteStringAppend(const char *aIn, string &aOut, TQuotingModes aQuoteMode) { if (!aQuoteMode!=qm_none) aOut.append(aIn); else { sInt16 n=strlen(aIn); aOut.reserve(n+2); aOut+='\''; appendUTF8ToString( aIn, aOut, chs_ascii, // charset lem_cstr, // line end mode aQuoteMode, // quoting mode 0 // max size (0 if unlimited) ); aOut+='\''; } } // TODBCApiAgent::quoteStringAppend // - append quoted version of string if aDoQuote is set // bfo: Problems with XCode (expicit qualification), already within namespace ? //void sysync::quoteStringAppend(string &aIn, string &aOut, TQuotingModes aQuoteMode) void quoteStringAppend(string &aIn, string &aOut, TQuotingModes aQuoteMode) { quoteStringAppend(aIn.c_str(),aOut,aQuoteMode); } // TODBCApiAgent::quoteStringAppend // reset all mapped parameters void TODBCApiAgent::resetSQLParameterMaps(TParameterMapList &aParamMapList) { TParameterMapList::iterator pos; for (pos=aParamMapList.begin();pos!=aParamMapList.end();++pos) { // clean up entry if (pos->mybuffer && pos->ParameterValuePtr) { // delete buffer if we have allocated one sysync_free(pos->ParameterValuePtr); pos->ParameterValuePtr=NULL; pos->mybuffer=false; } } // now clear list aParamMapList.clear(); } // TODBCApiAgent::resetSQLParameterMaps // parsing of %p(mode,var_or_field[,dbfieldtype[,maxcolsize]]) sequence bool TODBCApiAgent::ParseParamSubst( string &aSQL, // string to parse string::size_type &i, // input=position where % sequence starts in aSQL, output = if result==false: where to continue parsing, else: where to substitute string::size_type &n, // input=number of chars of % sequence possibly with "(" but nothing more, if result==true: output=number of chars to substitute at i in aSQL TParameterMapList &aParameterMaps, // parameter maps list to add params to TMultiFieldItem *aItemP // the involved item for field params #ifdef SCRIPT_SUPPORT ,TScriptContext *aScriptContextP // the script context for variable params #endif ) { string::size_type j,k,h; // %p(mode,fieldname,dbfieldtype) = field as SQL parameter, where mode can be "i","o" or "io" j=i+n; // find closing paranthesis k = aSQL.find(")",j); if (k==string::npos) { i=j; n=0; return false; } // no closing paranthesis, do not substitute // get mode bool paramin=false,paramout=false; paramin=false; paramout=false; if (tolower(aSQL[j]=='i')) { paramin=true; if (tolower(aSQL[j+1])=='o') { paramout=true; ++j; } ++j; } else if (tolower(aSQL[j]=='o')) { paramout=true; ++j; } // now get item field or variable name if (aSQL[j]!=',') { i=k+1; n=0; return false; } // continue after closing paranthesis ++j; // extract name (without possible array index) h = aSQL.find(",",j); if (h==string::npos) { h=k; } // no second comma, only field name, use default dbfieldtype string fldname; fldname.assign(aSQL,j,h-j); j=h+1; // after , or ) // get fieldtype (default if none specified) TDBFieldType dbfty=dbft_string; // default to string uInt32 colmaxsize=0; if (hgetIdentifierIndex(OBJ_AUTO, aItemP ? aItemP->getFieldDefinitions() : NULL ,fldname.c_str()); fldP=aScriptContextP->getFieldOrVar(aItemP,idx,0); } else #endif if (aItemP) fldP = aItemP->getArrayField(fldname.c_str(),0,true); if (!fldP) { i=k+1; n=0; return false; } // no suitable mapping // now map as parameter TParameterMap map; // assign basics map.inparam=paramin; map.outparam=paramout; map.parammode=param_field; map.mybuffer=false; map.ParameterValuePtr=NULL; map.BufferLength=0; map.StrLen_or_Ind=SQL_NULL_DATA; // note that this is not zero (but -1) map.itemP=aItemP; map.fieldP=fldP; map.maxSize=colmaxsize; map.dbFieldType=dbfty; // save in list aParameterMaps.push_back(map); // set substitution parameters n=k+1-i; // ok, substitute return true; } // TODBCApiAgent::ParseParamSubst // do generic substitutions void TODBCApiAgent::DoSQLSubstitutions(string &aSQL) { #ifndef BINFILE_ALWAYS_ACTIVE if (!binfilesActive()) { // substitute: %u = userkey StringSubst(aSQL,"%u",fUserKey,2,fConfigP->fDataCharSet,fConfigP->fDataLineEndMode,fConfigP->fQuotingMode); // substitute: %d = devicekey StringSubst(aSQL,"%d",fDeviceKey,2,fConfigP->fDataCharSet,fConfigP->fDataLineEndMode,fConfigP->fQuotingMode); #ifdef SCRIPT_SUPPORT // substitute: %C = domain name (such as company selector) StringSubst(aSQL,"%C",fDomainName,2,fConfigP->fDataCharSet,fConfigP->fDataLineEndMode,fConfigP->fQuotingMode); #endif } #endif // not BINFILE_ALWAYS_ACTIVE #ifdef SCRIPT_SUPPORT // substitute %sv(sessionvarname) = session variable by name string::size_type i=0; while((i=aSQL.find("%sv(",i))!=string::npos) { string s; // skip lead-in string::size_type j=i+4; // find closing paranthesis string::size_type k = aSQL.find(")",j); if (k==string::npos) { i=j; continue; } // no closing paranthesis sInt32 m = k; // assume end of name is here // extract name s.assign(aSQL,j,m-j); // find session var with this name if (!fSessionScriptContextP) { i=j; continue; } TItemField *fldP = fSessionScriptContextP->getFieldOrVar( NULL, fSessionScriptContextP->getIdentifierIndex(OBJ_LOCAL,NULL,s.c_str(),s.size()) ); if (!fldP) { i=j; continue; } // field not found, no action // get field contents fldP->getAsString(s); // subsititute (starting with "%v(", ending with ")" ) aSQL.replace(i,k+1-i,s); i+=s.size(); } // substitute %p(mode,var_or_field[,dbfieldtype]) = map field to parameter // - as the only source of params in session-level SQL is the %p() sequence, we // can clear the list here (to make sure no param from another call remains active) // - if this is called from Datastore context, %p() sequences are already substituted, and // therefore no parameter list mixing will occur resetSQLParameterMaps(); i=0; while((i=aSQL.find("%p(",i))!=string::npos) { string::size_type n=3; // size of base sequence %p( if (!ParseParamSubst( aSQL,i,n, fParameterMaps, NULL #ifdef SCRIPT_SUPPORT ,fAgentContext #endif )) break; // subsititute param spec with single question mark aSQL.replace(i,n,"?"); i+=1; } #endif } // TODBCApiAgent::DoSQLSubstitutions // reset all mapped parameters void TODBCApiAgent::resetSQLParameterMaps(void) { resetSQLParameterMaps(fParameterMaps); } // TODBCApiAgent::resetSQLParameterMaps // add parameter definition to the session level parameter list void TODBCApiAgent::addSQLParameterMap( bool aInParam, bool aOutParam, TParamMode aParamMode, TItemField *aFieldP, TDBFieldType aDbFieldType ) { TParameterMap map; // assign basics map.inparam=aInParam; map.outparam=aOutParam; map.parammode=aParamMode; map.mybuffer=false; map.ParameterValuePtr=NULL; map.BufferLength=0; map.StrLen_or_Ind=SQL_NULL_DATA; // note that this is not zero (but -1) map.itemP=NULL; // no item map.fieldP=aFieldP; map.maxSize=std_paramsize; map.dbFieldType=aDbFieldType; map.outSiz=0; // save in list fParameterMaps.push_back(map); } // TODBCApiAgent::addSQLParameterMap // ODBC Utils // ========== #ifdef ODBCAPI_SUPPORT // get existing or create new ODBC environment handle SQLHENV TODBCApiAgent::getODBCEnvironmentHandle(void) { if (fODBCEnvironmentHandle==SQL_NULL_HANDLE) { // create one environment handle for the session if (SafeSQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &fODBCEnvironmentHandle ) != SQL_SUCCESS) { // problem throw TSyncException("Cannot allocated ODBC environment handle"); } // Set ODBC 3.0 (needed, else function sequence error will occur) if (SafeSQLSetEnvAttr( fODBCEnvironmentHandle, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0 ) != SQL_SUCCESS) { // problem throw TSyncException("Cannot set environment to ODBC 3.0"); } } // return the handle return fODBCEnvironmentHandle; } // TODBCApiAgent::getODBCEnvironmentHandle // check for connection-level error void TODBCApiAgent::checkConnectionError(SQLRETURN aResult) { checkODBCError(aResult,SQL_HANDLE_DBC,fODBCConnectionHandle); } // TODBCApiAgent::checkConnectionError // get handle to open connection SQLHDBC TODBCApiAgent::getODBCConnectionHandle(void) { SQLRETURN res; if (fODBCConnectionHandle==SQL_NULL_HANDLE) { // no connection exists, allocate new Connection Handle PDEBUGPRINTFX(DBG_DBAPI,("Trying to open new ODBC connection with ConnStr = '%s'",fSessionDBConnStr.c_str())); // - get environment handle (session global) SQLHENV envhandle=getODBCEnvironmentHandle(); if (envhandle==SQL_NULL_HANDLE) throw TSyncException("No environment handle available"); // - allocate connection handle res=SafeSQLAllocHandle( SQL_HANDLE_DBC, envhandle, &fODBCConnectionHandle ); checkODBCError(res,SQL_HANDLE_ENV,envhandle); try { // Some ODBC drivers (apparently MyODBC 3.51 on Mac OS X 10.5.2) crash when using SQLSetConnectAttr if (!fConfigP->fNoConnectAttrs) { // Set Connection attributes // - Make sure no dialog boxes are ever shown res=SafeSQLSetConnectAttr(fODBCConnectionHandle,SQL_ATTR_QUIET_MODE,NULL,0); checkConnectionError(res); // - Cursor library usage (default is NO) res=SafeSQLSetConnectAttr(fODBCConnectionHandle,SQL_ATTR_ODBC_CURSORS,(void*)(fConfigP->fUseCursorLib ? SQL_CUR_USE_ODBC : SQL_CUR_USE_DRIVER),0); checkConnectionError(res); // - Commit mode manually res=SafeSQLSetConnectAttr(fODBCConnectionHandle,SQL_ATTR_AUTOCOMMIT,(void*)SQL_AUTOCOMMIT_OFF,0); checkConnectionError(res); // - Set a timeout res=SafeSQLSetConnectAttr(fODBCConnectionHandle,SQL_ATTR_CONNECTION_TIMEOUT,(void*)fConfigP->fODBCTimeout,0); checkConnectionError(res); } // Now connect, before setting transaction stuff // - append password to configured connection string string connstr; connstr=fSessionDBConnStr.c_str(); if (!fSessionDBPassword.empty()) { connstr+="PWD="; connstr+=fSessionDBPassword; connstr+=';'; } const SQLSMALLINT outStrMax=1024; SQLCHAR outStr[outStrMax]; SQLSMALLINT outStrSiz; res=SafeSQLDriverConnect( fODBCConnectionHandle, // connection handle NULL, // no windows handle (SQLCHAR *)connstr.c_str(), // input string connstr.size(), outStr, // output string outStrMax, &outStrSiz, SQL_DRIVER_NOPROMPT ); checkConnectionError(res); // Note: the following may show the password, so it MUST NOT be a PDEBUGxxx, but a DEBUGxxx ! DEBUGPRINTFX(DBG_DBAPI+DBG_EXOTIC,("SQLDriverConnect returns connection string = '%s'",outStr)); // Now configure transactions #ifdef SYDEBUG if (PDEBUGMASK) { string msg,state; // - check what DB can offer for isolation levels SQLUINTEGER txnmask; res=SafeSQLGetInfo(fODBCConnectionHandle,SQL_TXN_ISOLATION_OPTION,&txnmask,0,NULL); if (getODBCError(res,msg,state,SQL_HANDLE_DBC,fODBCConnectionHandle)) { PDEBUGPRINTFX(DBG_ERROR,("SQLGetInfo for SQL_TXN_ISOLATION_OPTION failed: %s",msg.c_str())); } else { PDEBUGPRINTFX(DBG_DBAPI,("ODBC source's Transaction support mask = 0x%04lX",txnmask)); } // - check standard isolation level SQLUINTEGER txn; res=SafeSQLGetInfo(fODBCConnectionHandle,SQL_DEFAULT_TXN_ISOLATION,&txn,0,NULL); if (getODBCError(res,msg,state,SQL_HANDLE_DBC,fODBCConnectionHandle)) { DEBUGPRINTFX(DBG_ERROR,("SQLGetInfo for SQL_DEFAULT_TXN_ISOLATION failed: %s",msg.c_str())); } else { DEBUGPRINTF(("ODBC source's standard isolation mask = 0x%04lX",txn)); } } #endif // - set isolation level if (fConfigP->fODBCTxnMode!=txni_default) { SQLUINTEGER txnmode = 0; // none by default if (fConfigP->fODBCTxnModefODBCTxnMode); } PDEBUGPRINTFX(DBG_DBAPI,("Setting SQL_ATTR_TXN_ISOLATION to = 0x%04lX",txnmode)); res=SafeSQLSetConnectAttr(fODBCConnectionHandle,SQL_ATTR_TXN_ISOLATION,(void*)txnmode,0); checkConnectionError(res); } // done! PDEBUGPRINTFX(DBG_DBAPI,("Created and opened new ODBC connection (timeout=%ld sec)",fConfigP->fODBCTimeout)); #ifdef SCRIPT_SUPPORT // save datastore context (as this script can be executed implicitly from another scripts SQLEXECUTE()) TCustomImplDS *currScriptDS = fScriptContextDatastore; // now execute afterconnect script, if any fScriptContextDatastore=NULL; // connecting is not datastore related TScriptContext::execute( fAfterConnectContext, fConfigP->fAfterConnectScript, fConfigP->getAgentFuncTableP(), // context function table (void *)this // context data (myself) ); // restore datastore context as it was before fScriptContextDatastore = currScriptDS; #endif } catch(...) { // connection is not usable, dispose handle again SafeSQLFreeHandle(SQL_HANDLE_DBC,fODBCConnectionHandle); fODBCConnectionHandle=SQL_NULL_HANDLE; throw; } } PDEBUGPRINTFX(DBG_DBAPI+DBG_EXOTIC,("Session: using connection handle 0x%lX",(uIntArch)fODBCConnectionHandle)); return fODBCConnectionHandle; } // TODBCApiAgent::getODBCConnectionHandle // pull connection handle out of session into another object (datastore) SQLHDBC TODBCApiAgent::pullODBCConnectionHandle(void) { #ifdef SCRIPT_SUPPORT // make sure possible script statement gets disposed, as connection will be owned by datastore from now on // Note: the script statement must be closed here already, because creating a new connection with getODBCConnectionHandle() // might trigger afterconnectscript, which in turn may use SQLEXECUTE() will ask for the current script statement. // If the script statement was not closed before that, SQLEXECUTE() would execute on the old statement and hence on // the old connection rather than on the new one. commitAndCloseScriptStatement(); #endif SQLHDBC connhandle = getODBCConnectionHandle(); fODBCConnectionHandle = SQL_NULL_HANDLE; // owner is caller, must do closing and disposing return connhandle; } // TODBCApiAgent::pullODBCConnectionHandle // close connection void TODBCApiAgent::closeODBCConnection(SQLHDBC &aConnHandle) { string msg,state; SQLRETURN res; if (aConnHandle!=SQL_NULL_HANDLE) { // Roll back to make sure we don't leave a unfinished transaction res=SafeSQLEndTran(SQL_HANDLE_DBC,aConnHandle,SQL_ROLLBACK); if (getODBCError(res,msg,state,SQL_HANDLE_DBC,aConnHandle)) { PDEBUGPRINTFX(DBG_ERROR,("closeODBCConnection: SQLEndTran failed: %s",msg.c_str())); } // Actually disconnect res=SQLDisconnect(aConnHandle); if (getODBCError(res,msg,state,SQL_HANDLE_DBC,aConnHandle)) { PDEBUGPRINTFX(DBG_ERROR,("closeODBCConnection: SQLDisconnect failed: %s",msg.c_str())); } // free the connection handle res=SafeSQLFreeHandle(SQL_HANDLE_DBC,aConnHandle); if (getODBCError(res,msg,state,SQL_HANDLE_DBC,aConnHandle)) { PDEBUGPRINTFX(DBG_ERROR,("closeODBCConnection: SQLFreeHandle(DBC) failed: %s",msg.c_str())); } aConnHandle=SQL_NULL_HANDLE; } } // TODBCApiAgent::closeODBCConnection // check if aResult signals error and throw exception if so void TODBCApiAgent::checkODBCError(SQLRETURN aResult,SQLSMALLINT aHandleType,SQLHANDLE aHandle) { string msg,state; if (getODBCError(aResult,msg,state,aHandleType,aHandle)) { // error throw TSyncException(msg.c_str()); } } // TODBCApiAgent::checkODBCError // - check if aResult signals error and throw exception if so void TODBCApiAgent::checkStatementError(SQLRETURN aResult,SQLHSTMT aHandle) { checkODBCError(aResult,SQL_HANDLE_STMT,aHandle); } // TODBCApiAgent::checkStatementError // - check if aResult signals error and throw exception if so // does not report NO_DATA error, but returns false if NO_DATA condition exists bool TODBCApiAgent::checkStatementHasData(SQLRETURN aResult,SQLHSTMT aHandle) { if (aResult==SQL_NO_DATA) return false; // signal NO DATA else checkStatementError(aResult,aHandle); return true; // signal ok } // TODBCApiAgent::checkStatementHasData // get ODBC error message for given result code // - returns false if no error bool TODBCApiAgent::getODBCError(SQLRETURN aResult,string &aMessage,string &aSQLState, SQLSMALLINT aHandleType,SQLHANDLE aHandle) { aSQLState.erase(); if(aResult==SQL_SUCCESS) return false; // no error else { StringObjPrintf(aMessage,"ODBC SQL return code = %ld\n",(sInt32)aResult); // get Diag Info SQLCHAR sqlstate[6]; // buffer for state message sqlstate[5]=0; // terminate SQLINTEGER nativeerror; SQLSMALLINT msgsize,recno; SQLRETURN res; recno=1; // message buffer sInt16 maxmsgsize = 200; SQLCHAR *messageP = (SQLCHAR *) malloc(maxmsgsize); do { if (messageP==NULL) { StringObjAppendPrintf(aMessage,"- SQLGetDiagRec[%hd] failed because needed buffer of %ld bytes cannot be allocated",(sInt16)recno,(sInt32)maxmsgsize); break; // don't continue } msgsize=0; // just to make sure res=SQLGetDiagRec( aHandleType, // handle Type aHandle, // statement handle recno, // record number sqlstate, // state buffer &nativeerror, // native error code messageP, // message buffer, gets message maxmsgsize, // message buffer size &msgsize // gets size of message buffer ); if (res==SQL_NO_DATA) break; // seen all diagnostic info if (res==SQL_SUCCESS_WITH_INFO) { if (msgsize>maxmsgsize) { // buffer is too small, allocate a bigger one and try again free(messageP); maxmsgsize=msgsize+1; // make buffer large enough for message messageP = (SQLCHAR *) malloc(maxmsgsize); // try again continue; } // SQL_SUCCESS_WITH_INFO, but buffer is large enough - strange... StringObjAppendPrintf(aMessage,"- SQLGetDiagRec[%hd] said SQL_SUCCESS_WITH_INFO, but buffer is large enough\n",(sInt16)recno); } // info found, append it to error text message else if (res==SQL_SUCCESS) { StringObjAppendPrintf(aMessage,"- SQLState = '%s', NativeError=%ld, Message = %s\n",sqlstate,(sInt32)nativeerror,messageP); // save latest SQLState aSQLState.assign((const char *)sqlstate,5); } else { StringObjAppendPrintf(aMessage,"- SQLGetDiagRec[%hd] failed, Result=%ld\n",(sInt16)recno,(sInt32)res); break; // abort on error, too } recno++; } while(true); // get rid of message buffer free(messageP); // if it's success with Info, this is not considered an error, but do show info in log if (aResult==SQL_SUCCESS_WITH_INFO) { // show info as exotics in debug logs, but treat as success // (note: MS-SQL is verbose here...) PDEBUGPRINTFX(DBG_DBAPI+DBG_EXOTIC,("SQL_SUCCESS_WITH_INFO: %s",aMessage.c_str())); return false; // this is no error } else { return true; // treat as error error } } } // TODBCApiAgent::getODBCError // get new statement handle SQLHSTMT TODBCApiAgent::newStatementHandle(SQLHDBC aConnection) { SQLRETURN res; SQLHSTMT statement; // Allocate Statement Handle res=SafeSQLAllocHandle(SQL_HANDLE_STMT,aConnection,&statement); checkODBCError(res,SQL_HANDLE_DBC,aConnection); // Statement Attributes // - row array size (ODBC 3.0, not really needed as default is 1 anyway) res=SQLSetStmtAttr( statement, SQL_ATTR_ROW_ARRAY_SIZE, (void*)1, SQL_IS_UINTEGER ); checkStatementError(res,statement); return statement; } // TODBCApiAgent::newStatementHandle /* About SQLGetData from WIN32_SDK: If the driver does not support extensions to SQLGetData, the function can only return data for unbound columns with a number greater than that of the last bound column. Furthermore, within a row of data, the value of the ColumnNumber argument in each call to SQLGetData must be greater than or equal to the value of ColumnNumber in the previous call; that is, data must be retrieved in increasing column number order. Finally, if no extensions are supported, SQLGetData cannot be called if the rowset size is greater than 1. */ // get value, returns false if no Data or Null bool TODBCApiAgent::getColumnValueAsULong( SQLHSTMT aStatement, sInt16 aColNumber, uInt32 &aLongValue ) { SQLRETURN res; SQLINTEGER ind; SQLSMALLINT numcols; // check if there aColNumber is in range res = SafeSQLNumResultCols(aStatement,&numcols); checkStatementError(res,aStatement); if (aColNumber<1 || aColNumber>numcols) throw TSyncException(DEBUGTEXT("getColumnValueAsULong with bad col index","odds1")); aLongValue=0; res = SafeSQLGetData( aStatement, // statement handle aColNumber, // column number SQL_C_ULONG, // target type: unsigned long &aLongValue, // where to store the long 4, // max size of value (not used here) (SQLLEN*)&ind // indicator ); checkStatementError(res,aStatement); // return true if real data returned return (ind!=SQL_NULL_DATA && ind!=SQL_NO_TOTAL); } // TODBCApiAgent::getColumnValueAsULong // get value, returns false if no Data or Null bool TODBCApiAgent::getColumnValueAsLong( SQLHSTMT aStatement, sInt16 aColNumber, sInt32 &aLongValue ) { SQLRETURN res; SQLINTEGER ind; SQLSMALLINT numcols; // check if there aColNumber is in range res = SafeSQLNumResultCols(aStatement,&numcols); checkStatementError(res,aStatement); if (aColNumber<1 || aColNumber>numcols) throw TSyncException(DEBUGTEXT("getColumnValueAsLong with bad col index","odds2")); aLongValue=0; res = SafeSQLGetData( aStatement, // statement handle aColNumber, // column number SQL_C_LONG, // target type: signed long &aLongValue, // where to store the long 4, // max size of value (not used here) (SQLLEN*)&ind // indicator ); checkStatementError(res,aStatement); // return true if real data returned return (ind!=SQL_NULL_DATA && ind!=SQL_NO_TOTAL); } // TODBCApiAgent::getColumnValueAsLong // get value, returns false if no Data or Null bool TODBCApiAgent::getColumnValueAsDouble( SQLHSTMT aStatement, sInt16 aColNumber, double &aDoubleValue ) { SQLRETURN res; SQLINTEGER ind; SQLSMALLINT numcols; // check if there aColNumber is in range res = SafeSQLNumResultCols(aStatement,&numcols); checkStatementError(res,aStatement); if (aColNumber<1 || aColNumber>numcols) throw TSyncException(DEBUGTEXT("getColumnValueAsDouble with bad col index","odds3")); aDoubleValue=0; res = SafeSQLGetData( aStatement, // statement handle aColNumber, // column number SQL_C_DOUBLE, // target type: signed long &aDoubleValue, // where to store the double 8, // max size of value (not used here) (SQLLEN*)&ind // indicator ); checkStatementError(res,aStatement); // return true if real data returned return (ind!=SQL_NULL_DATA && ind!=SQL_NO_TOTAL); } // TODBCApiAgent::getColumnValueAsDouble // get value, returns false if no Data or Null bool TODBCApiAgent::getColumnValueAsString( SQLHSTMT aStatement, sInt16 aColNumber, string &aStringValue, TCharSets aCharSet, // real charset, including UTF16! bool aAsBlob ) { SQLRETURN res; sInt32 maxstringlen=512; // enough to start with for most fields sInt32 nextbuflen; uInt8 *strbufP=NULL; SQLINTEGER siz; SQLSMALLINT numcols; bool gotData=false; #ifdef ODBC_UNICODE string wStr; #endif // check if there aColNumber is in range res = SafeSQLNumResultCols(aStatement,&numcols); checkStatementError(res,aStatement); if (aColNumber<1 || aColNumber>numcols) throw TSyncException(DEBUGTEXT("getColumnValueAsString with bad col index","odds4")); // get data // - start with empty string aStringValue.erase(); strbufP = new uInt8[maxstringlen+1]; try { bool gotAllData=false; do { // make sure we have the buffer if (!strbufP) throw TSyncException(DEBUGTEXT("getColumnValueAsString can't allocate enough buffer memory","odds4a")); strbufP[maxstringlen]=0; // make sure we have ALWAYS a terminator (for appendStringAsUTF8) nextbuflen=maxstringlen; // default to same size we already have // now get data res = SafeSQLGetData( aStatement, // statement handle aColNumber, // column number aAsBlob ? SQL_C_BINARY : #ifdef ODBC_UNICODE (aCharSet==chs_utf16 ? SQL_C_WCHAR : SQL_C_CHAR), // target type: Binary, 8-bit or 16-bit string #else SQL_C_CHAR, // no 16-bit chars #endif strbufP, // where to store the data maxstringlen, // max size of string (SQLLEN*)&siz // returns real remaining size of data (=what we got in this call + what still remains to be fetched) ); if (res==SQL_NO_DATA) { // no (more) data gotAllData=true; break; } if (res!=SQL_SUCCESS && res!=SQL_SUCCESS_WITH_INFO) { checkStatementError(res,aStatement); break; } // determine size if (siz==SQL_NULL_DATA) { // NULL data gotAllData=true; break; } else if (siz==SQL_NO_TOTAL) { // we do not know how much is remaining, so it's certainly at least a full buffer PDEBUGPRINTFX(DBG_DBAPI+DBG_EXOTIC,("SQLGetData returned SQL_NO_TOTAL and %ld bytes of data",maxstringlen)); siz=maxstringlen; nextbuflen=maxstringlen*2; // suggest next buffer twice as big as current one } else { // what we get is either the rest or a full buffer if (siz>maxstringlen) { PDEBUGPRINTFX(DBG_DBAPI+DBG_EXOTIC,("SQLGetData returned %ld bytes of %ld total remaining",maxstringlen,siz)); // that's how much we need for the remaining data. Plus one to avoid extra loop // at end for drivers that do not return state '01004' nextbuflen=siz-maxstringlen+1; // that's how much we got this time: one buffer full siz=maxstringlen; } } gotData=true; // not NULL // now copy data if (res==SQL_SUCCESS_WITH_INFO) { // probably data truncated string msg,sqlstate; getODBCError(res,msg,sqlstate,SQL_HANDLE_STMT,aStatement); if (sqlstate=="01004") { // data truncated. PDEBUGPRINTFX(DBG_DBAPI+DBG_EXOTIC,("SQLGetData returns state '01004' (truncated) -> more data to be fetched")); // - do not yet exit loop gotAllData=false; // not all... gotData=true; // ...but some } else { // otherwise treat as success PDEBUGPRINTFX(DBG_DBAPI+DBG_EXOTIC,("SQLGetData returns state '%s' -> ignore",sqlstate.c_str())); res=SQL_SUCCESS; } } if (res==SQL_SUCCESS) { // it seems that not all drivers return SQL_SUCCESS_WITH_INFO when there is more data to read // so only stop reading here already if we haven't got one buffer full. Otherwise, // loop one more time to try getting more. We'll get SQL_NULL_DATA or SQL_NO_DATA then and exit the loop. if (siz try to get more",(uInt32)siz)); } } // copy what we already have if (aAsBlob) aStringValue.append((const char *)strbufP,siz); // assign all data 1:1 to string #ifdef ODBC_UNICODE else if (aCharSet==chs_utf16) wStr.append((const char *)strbufP,siz); // assign all data 1:1 to wide string buffer, will be converted later #endif else appendStringAsUTF8((const char *)strbufP, aStringValue, aCharSet, lem_cstr); // Convert to app-charset (UTF8) and C-type lineends // get a bigger buffer in case there's more to fetch and we haven't got 64k already if (!gotAllData) { if (maxstringlen<65536 && nextbuflen>maxstringlen) { // we could need a larger buffer maxstringlen = nextbuflen>65536 ? 65536 : nextbuflen; delete strbufP; strbufP = new uInt8[maxstringlen+1]; PDEBUGPRINTFX(DBG_DBAPI+DBG_EXOTIC,("Allocating bigger buffer for next call to SQLGetData: %ld bytes",(uInt32)maxstringlen)); } } } while(!gotAllData); // done, we don't need the buffer any more if (strbufP) delete strbufP; } catch (...) { // clean up buffer if (strbufP) delete strbufP; throw; } // convert from Unicode to UTF-8 if we got unicode here #ifdef ODBC_UNICODE if (aCharSet==chs_utf16) { appendUTF16AsUTF8((const uInt16 *)wStr.c_str(), wStr.size()/2, ODBC_BIGENDIAN, aStringValue, true, false); } #endif // done return gotData; } // TODBCApiAgent::getColumnValueAsString // returns true if successfully and filled aODBCTimestamp bool TODBCApiAgent::getColumnAsODBCTimestamp( SQLHSTMT aStatement, sInt16 aColNumber, SQL_TIMESTAMP_STRUCT &aODBCTimestamp ) { SQLRETURN res; SQLINTEGER ind; SQLSMALLINT numcols; // check if there aColNumber is in range res = SafeSQLNumResultCols(aStatement,&numcols); checkStatementError(res,aStatement); if (aColNumber<1 || aColNumber>numcols) throw TSyncException(DEBUGTEXT("getColumnAsODBCTimestamp with bad col index","odds5")); // get data res = SafeSQLGetData( aStatement, // statement handle aColNumber, // column number SQL_C_TYPE_TIMESTAMP, // target type: timestamp &aODBCTimestamp, // where to store the timestamp 0, // n/a (SQLLEN*)&ind // returns indication if NULL ); checkStatementError(res,aStatement); // return true if data filled in return (ind!=SQL_NULL_DATA && ind!=SQL_NO_TOTAL); } // TODBCApiAgent::getColumnAsODBCTimestamp // get value (UTC timestamp), returns false if no Data or Null bool TODBCApiAgent::getColumnValueAsTimestamp( SQLHSTMT aStatement, sInt16 aColNumber, lineartime_t &aTimestamp ) { SQL_TIMESTAMP_STRUCT odbctimestamp; if (getColumnAsODBCTimestamp(aStatement,aColNumber,odbctimestamp)) { // there is a timestamp DEBUGPRINTFX(DBG_DBAPI+DBG_EXOTIC,( "ODBCTimestamp: %04hd-%02hd-%02hd %02hd:%02hd:%02hd.%03ld", odbctimestamp.year,odbctimestamp.month,odbctimestamp.day, odbctimestamp.hour,odbctimestamp.minute,odbctimestamp.second, odbctimestamp.fraction / 1000000 )); aTimestamp = date2lineartime(odbctimestamp.year,odbctimestamp.month,odbctimestamp.day) + time2lineartime(odbctimestamp.hour,odbctimestamp.minute,odbctimestamp.second, odbctimestamp.fraction / 1000000); return true; } // no data aTimestamp=0; return false; } // TODBCApiAgent::getColumnValueAsTimestamp // get value, returns false if no Data or Null bool TODBCApiAgent::getColumnValueAsTime( SQLHSTMT aStatement, sInt16 aColNumber, lineartime_t &aTime ) { SQL_TIMESTAMP_STRUCT odbctimestamp; if (getColumnAsODBCTimestamp(aStatement,aColNumber,odbctimestamp)) { // there is a timestamp aTime = time2lineartime( odbctimestamp.hour, odbctimestamp.minute, odbctimestamp.second, odbctimestamp.fraction / 1000000 ); return true; } // no data aTime=0; return false; } // TODBCApiAgent::getColumnValueAsTime // get value, returns false if no Data or Null bool TODBCApiAgent::getColumnValueAsDate( SQLHSTMT aStatement, sInt16 aColNumber, lineartime_t &aDate ) { SQL_TIMESTAMP_STRUCT odbctimestamp; if (getColumnAsODBCTimestamp(aStatement,aColNumber,odbctimestamp)) { // there is a timestamp aDate = date2lineartime( odbctimestamp.year, odbctimestamp.month, odbctimestamp.day ); return true; } // no data aDate=0; return false; } // TODBCApiAgent::getColumnValueAsDate // get column value as database field bool TODBCApiAgent::getColumnValueAsField( SQLHSTMT aStatement, sInt16 aColIndex, TDBFieldType aDbfty, TItemField *aFieldP, TCharSets aDataCharSet, timecontext_t aTimecontext, bool aMoveToUserContext ) { string val; lineartime_t ts, basedate=0; // no base date yet sInt32 dbts; timecontext_t tctx = TCTX_UNKNOWN; sInt16 moffs=0; sInt32 i=0; double hrs=0; bool notnull=false; // default to empty // get pointer if assigning into timestamp field TTimestampField *tsfP = NULL; if (aFieldP->isBasedOn(fty_timestamp)) { tsfP = static_cast(aFieldP); } // field available in multifielditem switch (aDbfty) { case dbft_uctoffsfortime_hours: notnull=getColumnValueAsDouble(aStatement,aColIndex,hrs); if (!notnull) goto assignzone; // assign TCTX_UNKNOWN moffs=(sInt16)(hrs*MinsPerHour); // convert to minutes goto assignoffs; case dbft_uctoffsfortime_mins: notnull=getColumnValueAsLong(aStatement,aColIndex,i); if (!notnull) goto assignzone; // assign TCTX_UNKNOWN moffs=i; // these are minutes goto assignoffs; case dbft_uctoffsfortime_secs: notnull=getColumnValueAsLong(aStatement,aColIndex,i); if (!notnull) goto assignzone; // assign TCTX_UNKNOWN moffs = i / SecsPerMin; goto assignoffs; case dbft_zonename: // get zone name as string notnull=getColumnValueAsString(aStatement,aColIndex,val,aDataCharSet, lem_cstr); if (!notnull) goto assignzone; // assign TCTX_UNKNOWN // convert to context TimeZoneNameToContext(val.c_str(), tctx, getSessionZones(), true); goto assignzone; assignoffs: tctx = TCTX_MINOFFSET(moffs); assignzone: // zone works only for timestamps // - move to new zone or assign zone if timestamp is still empty or floating if (tsfP) { // first move to original context (to compensate for possible move to // fUserTimeContext done when reading timestamp with aMoveToUserContext) // Note: this is important for cases where the new zone is floating or dateonly // Note: if timestamp field had the "f" flag, it is still floating here, and will not be // moved to non-floating aTimecontext(=DB context) here. tsfP->moveToContext(aTimecontext,false); // now move to specified zone, or assign zone if timestamp is still floating here tsfP->moveToContext(tctx,true); } break; case dbft_lineardate: case dbft_unixdate_s: case dbft_unixdate_ms: case dbft_unixdate_us: notnull=getColumnValueAsLong(aStatement,aColIndex,dbts); if (notnull) ts=dbIntToLineartime(dbts,aDbfty); goto dateonly; case dbft_dateonly: case dbft_date: notnull=getColumnValueAsDate(aStatement,aColIndex,ts); dateonly: tctx = TCTX_UNKNOWN | TCTX_DATEONLY; // dates are always floating goto assignval; case dbft_timefordate: // get base date used to build up datetime if (tsfP) { basedate = tsfP->getTimestampAs(TCTX_UNKNOWN); // unconverted, as-is } // otherwise handle like time case dbft_time: notnull=getColumnValueAsTime(aStatement,aColIndex,ts); // combine with date ts+=basedate; goto assigntimeval; case dbft_timestamp: notnull=getColumnValueAsTimestamp(aStatement,aColIndex,ts); goto assigntimeval; case dbft_lineartime: case dbft_unixtime_s: case dbft_nsdate_s: case dbft_unixtime_ms: case dbft_unixtime_us: notnull=getColumnValueAsLong(aStatement,aColIndex,dbts); if (notnull) ts=dbIntToLineartime(dbts,aDbfty); assigntimeval: // time values will be put into aTimecontext (usually , but can // be TCTX_UNKNOWN for field explicitly marked floating in DB with tctx = aTimecontext; assignval: // something convertible to lineartime_t if (notnull) { // first, if output in user zone is selected, move timestamp to user zone // Note: before moving to a field-specific zone, this will be reverted such that // field-specific TZ=DATE conversion will be done in the original (DB) TZ context if (aMoveToUserContext) { if (TzConvertTimestamp(ts,tctx,fUserTimeContext,getSessionZones())) tctx = fUserTimeContext; // moved to user zone } // now store in item field if (tsfP) { // assign timestamp and context passed (TCTX_UNKNOWN for floating) tsfP->setTimestampAndContext(ts,tctx); } else { // destination is NOT timestamp, assign ISO date/time string, // either UTC or qualified with local zone offset bool dateonly = aDbfty==dbft_date || aDbfty==dbft_dateonly; tctx = dateonly ? TCTX_UNKNOWN | TCTX_DATEONLY : aTimecontext; // - aWithTime, NOT aAsUTC, aWithOffset, offset, NOT aShowOffset TimestampToISO8601Str(val, ts, tctx, false, false); aFieldP->setAsString(val.c_str()); } } else aFieldP->assignEmpty(); // NULL value: not assigned break; case dbft_blob: // Database field is BLOB, assign it to item as binary string if ((notnull=getColumnValueAsString(aStatement,aColIndex,val,chs_unknown,true))) aFieldP->setAsString(val.c_str(),val.size()); else aFieldP->assignEmpty(); // NULL value: not assigned break; case dbft_string: case dbft_numeric: default: // Database field is string (or unknown), assign to item as string if ((notnull=getColumnValueAsString(aStatement,aColIndex,val,aDataCharSet))) aFieldP->setAsString(val.c_str()); else aFieldP->assignEmpty(); // NULL value: not assigned break; } // switch return notnull; } // TODBCApiAgent::getColumnValueAsField // bind parameters (and values for IN-Params) to the statement void TODBCApiAgent::bindSQLParameters( TSyncSession *aSessionP, SQLHSTMT aStatement, TParameterMapList &aParamMapList, // the list of mapped parameters TCharSets aDataCharSet, TLineEndModes aDataLineEndMode ) { SQLSMALLINT valueType,paramType; SQLUSMALLINT paramNo=1; SQLUINTEGER colSiz; string s1,s2; TParameterMapList::iterator pos; bool copyvalue; for (pos=aParamMapList.begin();pos!=aParamMapList.end();++pos) { // bind parameter to statement copyvalue=false; colSiz=std_paramsize; switch (pos->parammode) { case param_localid_str: case param_localid_int: case param_remoteid_str: case param_remoteid_int: pos->StrLen_or_Ind=0; // no size indication known yet // a item id, always as string valueType=SQL_C_CHAR; // but column could also be integer paramType=pos->parammode==param_localid_int || pos->parammode==param_remoteid_int ? SQL_INTEGER : SQL_VARCHAR; // get input value (if any) if (pos->inparam) { if (pos->itemP) { // item available pos->ParameterValuePtr=(void *)( pos->parammode==param_localid_str || pos->parammode==param_localid_int ? pos->itemP->getLocalID() : pos->itemP->getRemoteID() ); } else { // no item pos->ParameterValuePtr=(void *)""; // empty value } pos->StrLen_or_Ind = strlen((const char *)pos->ParameterValuePtr); // actual length } // maximum value size pos->BufferLength=std_paramsize+1; // %%% fixed value for ids, should be enough for all cases colSiz=std_paramsize; break; case param_field: pos->StrLen_or_Ind=0; // no size indication known for field yet (for buffer we use predefined values) case param_buffer: // determine value type and pointer switch (pos->dbFieldType) { case dbft_numeric: valueType=SQL_C_CHAR; paramType=SQL_INTEGER; break; case dbft_blob: valueType=SQL_C_BINARY; paramType=SQL_LONGVARBINARY; break; case dbft_string: default: #ifdef ODBC_UNICODE if (aDataCharSet==chs_utf16) { // 16-bit string valueType=SQL_C_WCHAR; paramType=SQL_WVARCHAR; } else #endif { // 8-bit string valueType=SQL_C_CHAR; paramType=SQL_VARCHAR; } break; } // that's all for param with already prepared buffer if (pos->parammode==param_buffer) break; // get maximum value size colSiz=pos->maxSize; if (pos->maxSize==0) { // no max size specified colSiz=std_paramsize; // default to standard size } // %%%no longer, we calc it below now%%% pos->BufferLength=colSiz+1; if (pos->inparam) { if (pos->fieldP) { // get actual value to pass as param into string s2 switch (pos->dbFieldType) { default: case dbft_string: case dbft_numeric: // get as app string pos->fieldP->getAsString(s1); // convert to database string s2.erase(); #ifdef ODBC_UNICODE if (aDataCharSet==chs_utf16) { // 16-bit string appendUTF8ToUTF16ByteString( s1.c_str(), s2, ODBC_BIGENDIAN, aDataLineEndMode, pos->maxSize // max size (0 = unlimited) ); } else #endif // ODBC_UNICODE { // 8-bit string appendUTF8ToString( s1.c_str(), s2, aDataCharSet, aDataLineEndMode, qm_none, // no quoting needed pos->maxSize // max size (0 = unlimited) ); } break; case dbft_blob: #ifndef _MSC_VER // does not understand warnings #warning "maybe we should store blobs using SQLPutData and SQL_DATA_AT_EXEC mode" #endif // get as unconverted binary chunk if (pos->fieldP->isBasedOn(fty_blob)) static_cast(pos->fieldP)->getBlobAsString(s2); else pos->fieldP->getAsString(s2); break; } // switch // s2 now contains the value pos->ParameterValuePtr=(void *)s2.c_str(); // value // default to full length of input string pos->StrLen_or_Ind=s2.size(); // size pos->BufferLength=s2.size(); // default to as long as string is // limit to max size if (pos->maxSize!=0 && pos->maxSizeBufferLength=pos->maxSize; pos->StrLen_or_Ind=pos->maxSize; } // expand buffer to colsiz if input is larger than default column size if (colSizBufferLength) colSiz=pos->BufferLength; // buffer for output must be at least colsiz (which is maxsize, or std_paramsize if no maxsize specified) if (pos->outparam) { // input/output param, make buffer minimally as large as indicated by colsiz if (pos->BufferLengthBufferLength=colSiz; } // plus one for terminator pos->BufferLength+=1; copyvalue=true; // we need to copy it } // if field } // if inparam break; } // switch parammode // if this is an out param, create a buffer of BufferLength if (pos->parammode!=param_buffer) { if (pos->outparam || copyvalue) { // create buffer void *bP = sysync_malloc(pos->BufferLength); pos->mybuffer=true; // this is now a buffer allocated by myself if (pos->inparam) { // init buffer with input value memcpy(bP,pos->ParameterValuePtr,pos->StrLen_or_Ind+1); } // pass buffer, not original value pos->ParameterValuePtr = bP; // make sure buffer contains a NUL terminator *((uInt8 *)bP+pos->StrLen_or_Ind)=0; } if (pos->outparam && !pos->inparam) pos->StrLen_or_Ind=SQL_NULL_DATA; // out only has no indicator for input } // now actually bind to parameter POBJDEBUGPRINTFX(aSessionP,DBG_DBAPI+DBG_EXOTIC,( "SQLBind: sizeof(SQLLEN)=%d, sizeof(SQLINTEGER)=%d, paramNo=%hd, in=%d, out=%d, parammode=%hd, valuetype=%hd, paramtype=%hd, lenorind=%d, valptr=%X, bufsiz=%d, maxcol=%d, colsiz=%d", sizeof(SQLLEN), sizeof(SQLINTEGER), // to debug, as there can be problematic 32bit/64bit mismatches between these (uInt16)paramNo, (int)pos->inparam, (int)pos->outparam, (uInt16)(pos->outparam ? (pos->inparam ? SQL_PARAM_INPUT_OUTPUT : SQL_PARAM_OUTPUT ) : SQL_PARAM_INPUT), // type of param (uInt16)valueType, (uInt16)paramType, (int)pos->StrLen_or_Ind, pos->ParameterValuePtr, (int)pos->BufferLength, (int)pos->maxSize, (int)colSiz )); /* SQLRETURN SQL_API SQLBindParameter( SQLHSTMT hstmt, SQLUSMALLINT ipar, SQLSMALLINT fParamType, SQLSMALLINT fCType, SQLSMALLINT fSqlType, SQLULEN cbColDef, SQLSMALLINT ibScale, SQLPOINTER rgbValue, SQLLEN cbValueMax, SQLLEN *pcbValue); */ SQLRETURN res=SQLBindParameter( aStatement, paramNo, // parameter number pos->outparam ? (pos->inparam ? SQL_PARAM_INPUT_OUTPUT : SQL_PARAM_OUTPUT ) : SQL_PARAM_INPUT, // type of param valueType, // value type: how we want it represented paramType, // parameter type (integer or char) (colSiz==0 ? 1 : colSiz), // column size, relevant for char parameter only (must never be 0, even for zero length input-only params) 0, // decimal digits pos->ParameterValuePtr, // parameter value pos->BufferLength, // value buffer size (for output params) &(pos->StrLen_or_Ind) // length or indicator ); checkStatementError(res,aStatement); // next param paramNo++; } // for all parametermaps } // TODBCApiAgent::bindSQLParameters // save out parameter values and clean up void TODBCApiAgent::saveAndCleanupSQLParameters( TSyncSession *aSessionP, SQLHSTMT aStatement, TParameterMapList &aParamMapList, // the list of mapped parameters TCharSets aDataCharSet, TLineEndModes aDataLineEndMode ) { SQLUSMALLINT paramNo=1; string s,s2; TParameterMapList::iterator pos; for (pos=aParamMapList.begin();pos!=aParamMapList.end();++pos) { // save output parameter value if (pos->outparam) { switch (pos->parammode) { case param_localid_str: case param_localid_int: case param_remoteid_str: case param_remoteid_int: // id output params are always strings POBJDEBUGPRINTFX(aSessionP,DBG_DBAPI+DBG_EXOTIC,( "Postprocessing Item ID param: in=%d, out=%d, lenorind=%ld, valptr=%lX, bufsiz=%ld", (int)pos->inparam, (int)pos->outparam, pos->StrLen_or_Ind, pos->ParameterValuePtr, pos->BufferLength )); /* Note: len or ind does not contain a useful value DEBUGPRINTFX(DBG_DBAPI,("%%%% saving remote or localid out param: len=%ld, '%s'",pos->StrLen_or_Ind, s.c_str())); if (pos->StrLen_or_Ind==SQL_NULL_DATA || pos->StrLen_or_Ind==SQL_NO_TOTAL) s.erase(); else s.assign((const char *)pos->ParameterValuePtr,pos->StrLen_or_Ind); */ // SQL_C_CHAR is null terminated, so just assign s=(const char *)pos->ParameterValuePtr; // assign to item if (pos->itemP) { if (pos->parammode==param_localid_str || pos->parammode==param_localid_int) pos->itemP->setLocalID(s.c_str()); else pos->itemP->setRemoteID(s.c_str()); } break; case param_buffer: // buffer will be processed externally if (pos->outSiz) { if (pos->StrLen_or_Ind==SQL_NULL_DATA || pos->StrLen_or_Ind==SQL_NO_TOTAL) *(pos->outSiz) = 0; // no output else *(pos->outSiz) = pos->StrLen_or_Ind; // indicate how much is in buffer } case param_field: // get value field if (pos->fieldP) { POBJDEBUGPRINTFX(aSessionP,DBG_DBAPI+DBG_EXOTIC,( "Postprocessing field param: in=%d, out=%d, lenorind=%ld, valptr=%lX, bufsiz=%ld", (int)pos->inparam, (int)pos->outparam, pos->StrLen_or_Ind, pos->ParameterValuePtr, pos->BufferLength )); // check for NULL if (pos->StrLen_or_Ind==SQL_NULL_DATA || pos->StrLen_or_Ind==SQL_NO_TOTAL) pos->fieldP->assignEmpty(); // NULL is empty else { // save value according to type switch (pos->dbFieldType) { default: case dbft_string: case dbft_numeric: // get as db string /* Note: len or ind does not contain a useful value DEBUGPRINTFX(DBG_DBAPI,("%%%% saving remote or localid out param: len=%ld, '%s'",pos->StrLen_or_Ind, s.c_str())); if (pos->StrLen_or_Ind==SQL_NULL_DATA || pos->StrLen_or_Ind==SQL_NO_TOTAL) s.erase(); else s.assign((const char *)pos->ParameterValuePtr,pos->StrLen_or_Ind); */ #ifdef ODBC_UNICODE if (aDataCharSet==chs_utf16) { // SQL_C_WCHAR is null terminated, so just assign appendUTF16AsUTF8( (const uInt16 *)pos->ParameterValuePtr, pos->StrLen_or_Ind, // num of 16-bit chars ODBC_BIGENDIAN, s2, true, // convert line ends false // no filemaker CRs ); } else #endif { // SQL_C_CHAR is null terminated, so just assign s=(const char *)pos->ParameterValuePtr; // convert to app string s2.erase(); appendStringAsUTF8( (const char *)s.c_str(), s2, aDataCharSet, aDataLineEndMode ); } pos->fieldP->setAsString(s2); break; case dbft_blob: // save as it comes from DB pos->fieldP->setAsString((const char *)pos->ParameterValuePtr,pos->StrLen_or_Ind); break; } // switch } // if not NULL } // if field break; } // switch parammode } // if outparam // if there is a buffer, free it if (pos->mybuffer && pos->ParameterValuePtr) { // delete buffer if we have allocated one sysync_free(pos->ParameterValuePtr); pos->ParameterValuePtr=NULL; pos->mybuffer=false; } // next param paramNo++; } // for all parametermaps } // TODBCApiAgent::saveAndCleanupSQLParameters // Parameter handling for session level statements // bind parameters (and values for IN-Params) to the statement void TODBCApiAgent::bindSQLParameters( SQLHSTMT aStatement ) { bindSQLParameters( this, aStatement, fParameterMaps, fConfigP->fDataCharSet, fConfigP->fDataLineEndMode ); } // TODBCApiAgent::bindSQLParameters // save out parameter values and clean up void TODBCApiAgent::saveAndCleanupSQLParameters( SQLHSTMT aStatement ) { saveAndCleanupSQLParameters( this, aStatement, fParameterMaps, fConfigP->fDataCharSet, fConfigP->fDataLineEndMode ); } // TODBCApiAgent::bindSQLParameters #endif // ODBCAPI_SUPPORT // SQLite utils // ============ #ifdef SQLITE_SUPPORT // get SQLite error message for given result code // - returns false if no error bool TODBCApiAgent::getSQLiteError(int aRc,string &aMessage, sqlite3 *aDb) { if (aRc == SQLITE_OK || aRc == SQLITE_ROW) return false; // no error StringObjPrintf(aMessage,"SQLite Error %d : %s",aRc,aDb==NULL ? "" : sqlite3_errmsg(aDb)); return true; } // getSQLiteError // check if aResult signals error and throw exception if so void TODBCApiAgent::checkSQLiteError(int aRc, sqlite3 *aDb) { string msg; if (getSQLiteError(aRc,msg,aDb)) { // error throw TSyncException(msg.c_str()); } } // TODBCApiAgent::checkSQLiteError // - check if aRc signals error and throw exception if so // returns true if data available, false if not bool TODBCApiAgent::checkSQLiteHasData(int aRc, sqlite3 *aDb) { if (aRc==SQLITE_DONE) return false; // signal NO DATA else if (aRc==SQLITE_ROW) return true; // signal data else checkSQLiteError(aRc,aDb); return true; // signal ok } // TODBCApiAgent::checkStatementHasData // get column value from SQLite result bool TODBCApiAgent::getSQLiteColValueAsField( sqlite3_stmt *aStatement, sInt16 aColIndex, TDBFieldType aDbfty, TItemField *aFieldP, TCharSets aDataCharSet, timecontext_t aTimecontext, bool aMoveToUserContext ) { string val; lineartime_t ts; timecontext_t tctx = TCTX_UNKNOWN; sInt16 moffs=0; size_t siz; double hrs=0; // get pointer if assigning into timestamp field TTimestampField *tsfP = NULL; if (aFieldP->isBasedOn(fty_timestamp)) { tsfP = static_cast(aFieldP); } // determine if NULL bool notnull=sqlite3_column_type(aStatement,aColIndex)!=SQLITE_NULL; // if column is not null // field available in multifielditem switch (aDbfty) { case dbft_uctoffsfortime_hours: if (!notnull) goto assignzone; // assign TCTX_UNKNOWN hrs = sqlite3_column_double(aStatement,aColIndex); moffs=(sInt16)(hrs*MinsPerHour); // convert to minutes goto assignoffs; case dbft_uctoffsfortime_mins: if (!notnull) goto assignzone; // assign TCTX_UNKNOWN moffs = sqlite3_column_int(aStatement,aColIndex); goto assignoffs; case dbft_uctoffsfortime_secs: if (!notnull) goto assignzone; // assign TCTX_UNKNOWN moffs = sqlite3_column_int(aStatement,aColIndex); moffs /= SecsPerMin; goto assignoffs; case dbft_zonename: if (!notnull) goto assignzone; // assign TCTX_UNKNOWN // get zone name as string appendStringAsUTF8((const char *)sqlite3_column_text(aStatement,aColIndex), val, aDataCharSet, lem_cstr); // convert to context TimeZoneNameToContext(val.c_str(), tctx, getSessionZones(), true); goto assignzone; assignoffs: tctx = TCTX_MINOFFSET(moffs); assignzone: // zone works only for timestamps // - move to new zone or assign zone if timestamp is still empty or floating if (tsfP) { // first move to original context (to compensate for possible move to // fUserTimeContext done when reading timestamp with aMoveToUserContext) // Note: this is important for cases where the new zone is floating or dateonly // Note: if timestamp field had the "f" flag, it is still floating here, and will not be // moved to non-floating aTimecontext(=DB context) here. tsfP->moveToContext(aTimecontext,false); // now move to specified zone, or assign zone if timestamp is still floating here tsfP->moveToContext(tctx,true); } break; case dbft_lineardate: case dbft_unixdate_s: case dbft_unixdate_ms: case dbft_unixdate_us: if (notnull) ts = dbIntToLineartime(sqlite3_column_int64(aStatement,aColIndex),aDbfty); tctx = TCTX_UNKNOWN | TCTX_DATEONLY; // dates are always floating goto assignval; case dbft_lineartime: case dbft_unixtime_s: case dbft_nsdate_s: case dbft_unixtime_ms: case dbft_unixtime_us: if (notnull) ts = dbIntToLineartime(sqlite3_column_int64(aStatement,aColIndex),aDbfty); // time values will be put into aTimecontext (usually , but can // be TCTX_UNKNOWN for field explicitly marked floating in DB with tctx = aTimecontext; assignval: // something convertible to lineartime_t if (notnull) { // first, if output in user zone is selected, move timestamp to user zone // Note: before moving to a field-specific zone, this will be reverted such that // field-specific TZ=DATE conversion will be done in the original (DB) TZ context if (aMoveToUserContext) { if (TzConvertTimestamp(ts,tctx,fUserTimeContext,getSessionZones())) tctx = fUserTimeContext; // moved to user zone } // now store in item field if (tsfP) { // assign timestamp and context (TCTX_UNKNOWN for floating) tsfP->setTimestampAndContext(ts,tctx); } else { // destination is NOT timestamp, assign ISO date/time string, // either UTC or qualified with local zone offset bool dateonly = aDbfty==dbft_date || aDbfty==dbft_dateonly; tctx = dateonly ? TCTX_UNKNOWN | TCTX_DATEONLY : aTimecontext; // - aWithTime, NOT aAsUTC, aWithOffset, offset, NOT aShowOffset TimestampToISO8601Str(val, ts, tctx, false, false); aFieldP->setAsString(val.c_str()); } } else aFieldP->assignEmpty(); // NULL value: not assigned break; case dbft_blob: // Database field is BLOB, assign it to item as binary string siz=0; if (notnull) { siz = sqlite3_column_bytes(aStatement,aColIndex); } if (siz>0) aFieldP->setAsString((cAppCharP)sqlite3_column_blob(aStatement,aColIndex),siz); else aFieldP->assignEmpty(); // NULL or empty value: not assigned break; case dbft_string: case dbft_numeric: default: // Database field is string (or unknown), assign to item as string if (notnull) { appendStringAsUTF8((const char *)sqlite3_column_text(aStatement,aColIndex), val, aDataCharSet, lem_cstr); // Convert to app-charset (UTF8) and C-type lineends aFieldP->setAsString(val.c_str()); } else aFieldP->assignEmpty(); // NULL value: not assigned break; } // switch return notnull; } // TODBCApiAgent::getSQLiteColValueAsField // - prepare SQLite statement void TODBCApiAgent::prepareSQLiteStatement( cAppCharP aSQL, sqlite3 *aDB, sqlite3_stmt *&aStatement ) { const char *sqltail; // discard possibly existing one if (aStatement) { sqlite3_finalize(aStatement); aStatement=NULL; } // make new one #if (SQLITE_VERSION_NUMBER>=3003009) // use new recommended v2 call with SQLite >=3.3.9 int rc = sqlite3_prepare_v2( aDB, /* Database handle */ aSQL, /* SQL statement, UTF-8 encoded */ -1, /* null terminated string */ &aStatement, /* OUT: Statement handle */ &sqltail /* OUT: Pointer to unused portion of zSql */ ); #else // use now deprecated call for older SQLite3 version compatibility int rc = sqlite3_prepare( aDB, /* Database handle */ aSQL, /* SQL statement, UTF-8 encoded */ -1, /* null terminated string */ &aStatement, /* OUT: Statement handle */ &sqltail /* OUT: Pointer to unused portion of zSql */ ); #endif checkSQLiteError(rc,aDB); } // TODBCApiAgent::prepareSQLiteStatement // bind parameter values to the statement (only IN-params for strings and BLOBs are supported at all) void TODBCApiAgent::bindSQLiteParameters( TSyncSession *aSessionP, sqlite3_stmt *aStatement, TParameterMapList &aParamMapList, // the list of mapped parameters TCharSets aDataCharSet, TLineEndModes aDataLineEndMode ) { string s1,s2; TParameterMapList::iterator pos; int paramno=1; int rc; for (pos=aParamMapList.begin();pos!=aParamMapList.end();++pos) { // bind parameter to statement rc=SQLITE_OK; if (pos->inparam) { // SQLite only supports input params switch (pos->parammode) { case param_field: if (pos->fieldP) { // get actual value to pass as param into string s2 switch (pos->dbFieldType) { default: case dbft_string: case dbft_numeric: // get as app string pos->fieldP->getAsString(s1); // convert to database string s2.erase(); appendUTF8ToString( s1.c_str(), s2, aDataCharSet, aDataLineEndMode, qm_none, // no quoting needed pos->maxSize // max size (0 = unlimited) ); // s2 is on the stack and will be deallocated on routine exit rc=sqlite3_bind_text(aStatement,paramno++,s2.c_str(),s2.size(),SQLITE_TRANSIENT); break; case dbft_blob: // get as unconverted binary chunk if (pos->fieldP->isBasedOn(fty_blob)) { void *ptr; size_t sz; static_cast(pos->fieldP)->getBlobDataPtrSz(ptr,sz); // BLOB buffer remains static as until statement is finalized rc=sqlite3_bind_blob(aStatement,paramno++,ptr,sz,SQLITE_STATIC); } else { pos->fieldP->getAsString(s2); // s2 is on the stack and will be deallocated on routine exit rc=sqlite3_bind_blob(aStatement,paramno++,s2.c_str(),s2.size(),SQLITE_TRANSIENT); } break; } // switch } // if field break; case param_buffer: // we already have buffer pointers switch (pos->dbFieldType) { default: case dbft_string: case dbft_numeric: // external buffer remains stable until statement finalizes rc=sqlite3_bind_text(aStatement,paramno++,(const char *)pos->ParameterValuePtr,pos->StrLen_or_Ind,SQLITE_STATIC); break; case dbft_blob: // external buffer remains stable until statement finalizes rc=sqlite3_bind_blob(aStatement,paramno++,pos->ParameterValuePtr,pos->StrLen_or_Ind,SQLITE_STATIC); break; } // switch break; case param_localid_int: case param_localid_str: case param_remoteid_int: case param_remoteid_str: // invalid break; } // switch parammode if (rc==SQLITE_OK) { POBJDEBUGPRINTFX(aSessionP,DBG_DBAPI+DBG_EXOTIC,( "Bound Param #%d to SQLite statement", paramno )); } else { } } // if inparam else { POBJDEBUGPRINTFX(aSessionP,DBG_ERROR,("SQLite only supports IN params")); } } // for all parametermaps } // TODBCApiAgent::bindSQLiteParameters #endif // SQLITE_SUPPORT // Session level DB access // ======================= #ifdef ODBCAPI_SUPPORT // get database time lineartime_t TODBCApiAgent::getDatabaseNowAs(timecontext_t aTimecontext) { lineartime_t now; if (fConfigP->fGetCurrentDateTimeSQL.empty()) { return inherited::getDatabaseNowAs(aTimecontext); // just use base class' implementation } else { // query database for current time SQLRETURN res; SQLHSTMT statement=newStatementHandle(getODBCConnectionHandle()); try { // issue PDEBUGPUTSX(DBG_DBAPI,"SQL for getting current date/time:"); PDEBUGPUTSX(DBG_DBAPI,fConfigP->fGetCurrentDateTimeSQL.c_str()); TP_DEFIDX(li); TP_SWITCH(li,fTPInfo,TP_database); res = SafeSQLExecDirect( statement, (SQLCHAR *)fConfigP->fGetCurrentDateTimeSQL.c_str(), SQL_NTS ); TP_START(fTPInfo,li); checkStatementError(res,statement); // - fetch result row res=SafeSQLFetch(statement); if (!checkStatementHasData(res,statement)) throw TSyncException("no data getting date/time from database"); // get datetime (in database time context) if (!getColumnValueAsTimestamp(statement,1,now)) throw TSyncException("bad data getting date/time from database"); SafeSQLCloseCursor(statement); // dispose statement handle SafeSQLFreeHandle(SQL_HANDLE_STMT,statement); } catch (...) { // dispose statement handle SafeSQLCloseCursor(statement); SafeSQLFreeHandle(SQL_HANDLE_STMT,statement); throw; } // convert to requested zone TzConvertTimestamp(now,fConfigP->fCurrentDateTimeZone,aTimecontext,getSessionZones(),TCTX_UNKNOWN); return now; } } // TODBCApiAgent::getDatabaseNowAs #ifdef SYSYNC_SERVER // info about requested auth type TAuthTypes TODBCApiAgent::requestedAuthType(void) { TAuthTypes auth = TSyncAgent::requestedAuthType(); // make sure that we don't request MD5 if we cannot check it: // either we need plain text passwords in the DB or SyncML V1.1 MD5 schema if (auth==auth_md5 && fSyncMLVersionfClearTextPw) { PDEBUGPRINTFX(DBG_ADMIN,("Switching down to Basic Auth because server cannot check pre-V1.1 MD5")); auth=auth_basic; // force basic auth, this can be checked } return auth; } // TODBCApiAgent::requestedAuthType // %%% note: make the following available in clients as well if they support more than // pseudo-auth by local config (that is, real nonce is needed) // - get nonce string, which is expected to be used by remote party for MD5 auth. void TODBCApiAgent::getAuthNonce(const char *aDeviceID, string &aAuthNonce) { if (!aDeviceID || fConfigP->fSaveNonceSQL.empty()) { // no device ID or no persistent nonce, use method of ancestor TStdLogicAgent::getAuthNonce(aDeviceID,aAuthNonce); } else { // we have a persistent nonce DEBUGPRINTFX(DBG_ADMIN,("getAuthNonce: current auth nonce='%s'",fLastNonce.c_str())); aAuthNonce=fLastNonce.c_str(); } } // TODBCApiAgent::getAuthNonce // get next nonce (to be sent to remote party) void TODBCApiAgent::getNextNonce(const char *aDeviceID, string &aNextNonce) { SQLRETURN res; SQLHSTMT statement; string sql; if (fConfigP->fSaveNonceSQL.empty()) { // no persistent nonce, use method of ancestor TStdLogicAgent::getNextNonce(aDeviceID,aNextNonce); } else { // we have persistent nonce, create a new one and save it // - create one (pure 7bit ASCII) generateNonce(aNextNonce,aDeviceID,getSystemNowAs(TCTX_UTC)+rand()); // - save it try { statement=newStatementHandle(getODBCConnectionHandle()); try { // get SQL sql = fConfigP->fSaveNonceSQL; // - substitute: %N = new nonce StringSubst(sql,"%N",aNextNonce,2,chs_ascii,lem_none,fConfigP->fQuotingMode); // - standard substitutions: %u=userkey, %d=devicekey resetSQLParameterMaps(); DoSQLSubstitutions(sql); bindSQLParameters(statement); // - issue PDEBUGPUTSX(DBG_ADMIN+DBG_DBAPI,"SQL for saving nonce"); PDEBUGPUTSX(DBG_ADMIN+DBG_DBAPI,sql.c_str()); TP_DEFIDX(li); TP_SWITCH(li,fTPInfo,TP_database); res = SafeSQLExecDirect( statement, (SQLCHAR *)sql.c_str(), SQL_NTS ); TP_START(fTPInfo,li); checkStatementError(res,statement); saveAndCleanupSQLParameters(statement); // commit saved nonce SafeSQLFreeHandle(SQL_HANDLE_STMT,statement); SafeSQLEndTran(SQL_HANDLE_DBC,getODBCConnectionHandle(),SQL_COMMIT); } // try catch (exception &e) { // release the statement handle SafeSQLFreeHandle(SQL_HANDLE_STMT,statement); SafeSQLEndTran(SQL_HANDLE_DBC,getODBCConnectionHandle(),SQL_ROLLBACK); throw; } } catch (exception &e) { PDEBUGPRINTFX(DBG_ERROR,("Failed saving nonce: %s",e.what())); aNextNonce=fLastNonce; // return last nonce again } } } // TODBCApiAgent::getNextNonce #endif // SYSYNC_SERVER #ifdef HAS_SQL_ADMIN // cleanup what is needed after login void TODBCApiAgent::LoginCleanUp(void) { SQLRETURN res; try { // close the transaction as well if (fODBCConnectionHandle!=SQL_NULL_HANDLE) { res=SafeSQLEndTran(SQL_HANDLE_DBC,getODBCConnectionHandle(),SQL_ROLLBACK); checkODBCError(res,SQL_HANDLE_DBC,getODBCConnectionHandle()); } } catch (exception &e) { // log error PDEBUGPRINTFX(DBG_ERROR,("TODBCApiAgent::LoginCleanUp: Exception: %s",e.what())); } } // TODBCApiAgent::LoginCleanUp // check device related stuff void TODBCApiAgent::CheckDevice(const char *aDeviceID) { // first let ancestor if (!fConfigP->fGetDeviceSQL.empty()) { SQLRETURN res; SQLHSTMT statement; string sql; statement=newStatementHandle(getODBCConnectionHandle()); try { bool creatednew=false; do { // get SQL sql = fConfigP->fGetDeviceSQL; // substitute: %D = deviceID StringSubst(sql,"%D",aDeviceID,2,-1,fConfigP->fDataCharSet,fConfigP->fDataLineEndMode,fConfigP->fQuotingMode); // issue PDEBUGPUTSX(DBG_ADMIN+DBG_DBAPI,"SQL for getting device key (and last nonce sent to device)"); PDEBUGPUTSX(DBG_ADMIN+DBG_DBAPI,sql.c_str()); TP_DEFIDX(li); TP_SWITCH(li,fTPInfo,TP_database); res = SafeSQLExecDirect( statement, (SQLCHAR *)sql.c_str(), SQL_NTS ); TP_START(fTPInfo,li); checkStatementHasData(res,statement); // - fetch result row res=SafeSQLFetch(statement); if (!checkStatementHasData(res,statement)) { if (creatednew) { throw TSyncException("Fatal: inserted device record cannot be found again"); } PDEBUGPRINTFX(DBG_ADMIN,("Unknown device '%.30s', creating new record",aDeviceID)); if (IS_SERVER) { #ifdef SYSYNC_SERVER // device does not exist yet fLastNonce.erase(); #endif } // create new device SafeSQLCloseCursor(statement); // - get SQL sql = fConfigP->fNewDeviceSQL; string dk; // temp device key // - substitute: %D = deviceID StringSubst(sql,"%D",aDeviceID,2,-1,fConfigP->fDataCharSet,fConfigP->fDataLineEndMode,fConfigP->fQuotingMode); // - issue PDEBUGPUTSX(DBG_ADMIN+DBG_DBAPI,"SQL for inserting new device (and last nonce sent to device)"); PDEBUGPUTSX(DBG_ADMIN+DBG_DBAPI,sql.c_str()); TP_DEFIDX(li); TP_SWITCH(li,fTPInfo,TP_database); res = SafeSQLExecDirect( statement, (SQLCHAR *)sql.c_str(), SQL_NTS ); TP_START(fTPInfo,li); checkStatementError(res,statement); // commit new device SafeSQLEndTran(SQL_HANDLE_DBC,getODBCConnectionHandle(),SQL_COMMIT); // try again to get device key creatednew=true; continue; } else { // device exists, read key and nonce #ifdef SCRIPT_SUPPORT fUnknowndevice=false; // we have seen it once before at least #endif // - device key getColumnValueAsString(statement,1,fDeviceKey,chs_ascii); // - nonce if (IS_CLIENT) { string dummy; getColumnValueAsString(statement,2,dummy,chs_ascii); } else { #ifdef SYSYNC_SERVER getColumnValueAsString(statement,2,fLastNonce,chs_ascii); #endif } // - done for now SafeSQLCloseCursor(statement); PDEBUGPRINTFX(DBG_ADMIN,("Device '%.30s' found, fDeviceKey='%.30s'",aDeviceID,fDeviceKey.c_str())); if (IS_SERVER) { #ifdef SYSYNC_SERVER DEBUGPRINTFX(DBG_ADMIN,("Last nonce saved for device='%.30s'",fLastNonce.c_str())); #endif } break; } } while (true); // do until device found or created new } // try catch (...) { // release the statement handle SafeSQLCloseCursor(statement); SafeSQLFreeHandle(SQL_HANDLE_STMT,statement); SafeSQLEndTran(SQL_HANDLE_DBC,getODBCConnectionHandle(),SQL_ROLLBACK); throw; } // release the statement handle SafeSQLCloseCursor(statement); SafeSQLFreeHandle(SQL_HANDLE_STMT,statement); } // if device table implemented } // TODBCApiAgent::CheckDevice // check credential string bool TODBCApiAgent::CheckLogin(const char *aOriginalUserName, const char *aModifiedUserName, const char *aAuthString, TAuthSecretTypes aAuthStringType, const char *aDeviceID) { bool authok = false; string nonce; SQLRETURN res; SQLHSTMT statement; // - if no userkey query, we cannot proceed and must fail auth now if (fConfigP->fUserKeySQL.empty()) return false; // - get nonce (if we have a device table, we should have read it by now) if (aAuthStringType==sectyp_md5_V10 || aAuthStringType==sectyp_md5_V11) getAuthNonce(aDeviceID,nonce); // - try to obtain an appropriate user key statement=newStatementHandle(getODBCConnectionHandle()); try { // get SQL string sql = fConfigP->fUserKeySQL; string uk; // temp user key // substitute: %U = original username as sent by remote, // %dU = username modified for DB search, // %M = authstring, %N = Nonce string StringSubst(sql,"%U",aOriginalUserName,2,-1,fConfigP->fDataCharSet,fConfigP->fDataLineEndMode,fConfigP->fQuotingMode); StringSubst(sql,"%dU",aModifiedUserName,3,-1,fConfigP->fDataCharSet,fConfigP->fDataLineEndMode,fConfigP->fQuotingMode); // %%% probably obsolete StringSubst(sql,"%M",aAuthString,2,-1,fConfigP->fDataCharSet,fConfigP->fDataLineEndMode,fConfigP->fQuotingMode); StringSubst(sql,"%N",nonce,2,fConfigP->fDataCharSet,fConfigP->fDataLineEndMode,fConfigP->fQuotingMode); // now do the standard stuff resetSQLParameterMaps(); DoSQLSubstitutions(sql); bindSQLParameters(statement); // issue PDEBUGPUTSX(DBG_ADMIN+DBG_DBAPI,"SQL for getting user key (and password/md5userpass if not checked in query):"); PDEBUGPUTSX(DBG_ADMIN+DBG_DBAPI,sql.c_str()); TP_DEFIDX(li); TP_SWITCH(li,fTPInfo,TP_database); res = SafeSQLExecDirect( statement, (SQLCHAR *)sql.c_str(), SQL_NTS ); TP_START(fTPInfo,li); checkStatementHasData(res,statement); saveAndCleanupSQLParameters(statement); // - fetch result row res=SafeSQLFetch(statement); if (fConfigP->fClearTextPw || fConfigP->fMD5UserPass) { authok=false; // go though all returned rows until match (same username might be used with 2 different pws) while (checkStatementHasData(res,statement)) { // read in ascending index order!! string secret; SQLSMALLINT col=1; // - user key getColumnValueAsString(statement,col,uk,chs_ascii); col++; #ifdef SCRIPT_SUPPORT TItemField *hfP; // also store it in first local context var if (fAgentContext) { hfP=fAgentContext->getLocalVar(0); if (hfP) hfP->setAsString(uk.c_str()); } #endif // also store it in fUserKey already for USERKEY() function fUserKey=uk; // - password or md5userpass getColumnValueAsString(statement,col,secret,chs_ascii); // - convert from hex to b64 if needed if (fConfigP->fMD5UPAsHex && secret.size()>=32) { uInt8 md5[16]; cAppCharP p=secret.c_str(); for (int k=0; k<16; k++) { uInt16 h; if (HexStrToUShort(p+(k*2),h,2)<2) break; md5[k]=(uInt8)h; } p = b64::encode(&md5[0],16); secret = p; // save converted string b64::free((void *)p); } col++; #ifdef SCRIPT_SUPPORT // also store it in second local context var if (fAgentContext) { hfP=fAgentContext->getLocalVar(1); if (hfP) hfP->setAsString(secret.c_str()); // if result set has more columns, save them as well SQLSMALLINT numcols; // - get number of columns res = SafeSQLNumResultCols(statement,&numcols); checkStatementError(res,statement); // - save remaining columns into defined variables while (col<=numcols) { // check if enough variables if (col>fAgentContext->getNumLocals()) break; // get variable hfP=fAgentContext->getLocalVar(col-1); if (!hfP) break; // timestamp is special if (hfP->getType()==fty_timestamp) { // get as timestamp lineartime_t ts; if (!getColumnValueAsTimestamp(statement,col,ts)) break; static_cast(hfP)->setTimestampAndContext(ts,fConfigP->fCurrentDateTimeZone); } else { // get and assign as string string v; if (!getColumnValueAsString(statement,col,v,chs_ascii)) break; hfP->setAsString(v.c_str()); } col++; } } #endif // make standard auth check if (fConfigP->fClearTextPw) { // we have the clear text password, check against what was transmitted from remote authok=checkAuthPlain(aOriginalUserName,secret.c_str(),nonce.c_str(),aAuthString,aAuthStringType); } else { // whe have the MD5 of user:password, check against what was transmitted from remote // Note: this can't work with non-V1.1 type creds authok=checkAuthMD5(aOriginalUserName,secret.c_str(),nonce.c_str(),aAuthString,aAuthStringType); } #ifdef SCRIPT_SUPPORT // if there is a script, call it to perform decision // - refresh auth status fStandardAuthOK=authok; // for AUTHOK() func // - call script (if any) fScriptContextDatastore=NULL; authok=TScriptContext::executeTest( authok, // default for no script, no result or script error is current auth fAgentContext, fConfigP->fLoginCheckScript, fConfigP->getAgentFuncTableP(), // context function table (void *)this // context data (myself) ); #endif if (authok) break; // found, authorized // fetch next res=SafeSQLFetch(statement); } } else { // AuthString was checked in SQL query // - no record found -> no auth if (res==SQL_NO_DATA) authok=false; } if (authok) { // now assign user key fUserKey=uk; PDEBUGPRINTFX(DBG_ADMIN,("Auth successful, fUserKey='%s'",fUserKey.c_str())); } else { // we do not have a valid user key fUserKey.erase(); } } catch (...) { // release the statement handle SafeSQLCloseCursor(statement); SafeSQLFreeHandle(SQL_HANDLE_STMT,statement); SafeSQLEndTran(SQL_HANDLE_DBC,getODBCConnectionHandle(),SQL_ROLLBACK); throw; } // release the statement handle SafeSQLCloseCursor(statement); SafeSQLFreeHandle(SQL_HANDLE_STMT,statement); // return auth status return authok; } // TODBCApiAgent::CheckLogin // do something with the analyzed data void TODBCApiAgent::remoteAnalyzed(void) { SQLRETURN res; SQLHSTMT statement; string sql; // call ancestor first inherited::remoteAnalyzed(); if (!fConfigP->fSaveInfoSQL.empty()) { // save info string statement=newStatementHandle(getODBCConnectionHandle()); try { // get SQL sql = fConfigP->fSaveInfoSQL; // %nR Remote name: [Manufacturer ]Model") StringSubst(sql,"%nR",getRemoteDescName(),3,-1,fConfigP->fDataCharSet,fConfigP->fDataLineEndMode,fConfigP->fQuotingMode); // %vR Remote Device Version Info ("Type (HWV, FWV, SWV) Oem") StringSubst(sql,"%vR",getRemoteInfoString(),3,-1,fConfigP->fDataCharSet,fConfigP->fDataLineEndMode,fConfigP->fQuotingMode); // - standard substitutions: %u=userkey, %d=devicekey resetSQLParameterMaps(); DoSQLSubstitutions(sql); bindSQLParameters(statement); // - issue PDEBUGPUTSX(DBG_ADMIN+DBG_DBAPI,"SQL for saving device info"); PDEBUGPUTSX(DBG_ADMIN+DBG_DBAPI,sql.c_str()); TP_DEFIDX(li); TP_SWITCH(li,fTPInfo,TP_database); res = SafeSQLExecDirect( statement, (SQLCHAR *)sql.c_str(), SQL_NTS ); TP_START(fTPInfo,li); checkStatementError(res,statement); saveAndCleanupSQLParameters(statement); // commit new device SafeSQLFreeHandle(SQL_HANDLE_STMT,statement); SafeSQLEndTran(SQL_HANDLE_DBC,getODBCConnectionHandle(),SQL_COMMIT); } // try catch (exception &e) { // release the statement handle SafeSQLFreeHandle(SQL_HANDLE_STMT,statement); SafeSQLEndTran(SQL_HANDLE_DBC,getODBCConnectionHandle(),SQL_ROLLBACK); PDEBUGPRINTFX(DBG_ERROR,("Failed saving device info: %s",e.what())); } } } // TODBCApiAgent::remoteAnalyzed #endif // HAS_SQL_ADMIN #endif // ODBCAPI_SUPPORT #ifdef SYSYNC_SERVER void TODBCApiAgent::RequestEnded(bool &aHasData) { // first let ancestors finish their stuff inherited::RequestEnded(aHasData); #ifdef ODBCAPI_SUPPORT // now close the ODBC connection if there is one left at the session level // and no script statement is still unfinished #ifdef SCRIPT_SUPPORT if (!fScriptStatement) #endif { closeODBCConnection(fODBCConnectionHandle); } #endif } // TODBCApiAgent::RequestEnded #endif // SYSYNC_SERVER // factory methods of Agent config // =============================== #ifdef SYSYNC_CLIENT TSyncAgent *TOdbcAgentConfig::CreateClientSession(const char *aSessionID) { // return appropriate client session MP_RETURN_NEW(TODBCApiAgent,DBG_HOT,"TODBCApiAgent",TODBCApiAgent(getSyncAppBase(),NULL,aSessionID)); } // TOdbcAgentConfig::CreateClientSession #endif #ifdef SYSYNC_SERVER TSyncAgent *TOdbcAgentConfig::CreateServerSession(TSyncSessionHandle *aSessionHandle, const char *aSessionID) { // return XML2GO or ODBC-server session MP_RETURN_NEW(TODBCApiAgent,DBG_HOT,"TODBCApiAgent",TODBCApiAgent(getSyncAppBase(),aSessionHandle,aSessionID)); } // TOdbcAgentConfig::CreateServerSession #endif } // namespace sysync /* end of TODBCApiAgent implementation */ #endif // SQL_SUPPORT // eof libsynthesis-3.4.0.47.1/src/DB_interfaces/odbc_db/odbcapiagent.h000077500000000000000000000460621226375725500243030ustar00rootroot00000000000000/** * @File odbcapiagent.h * * @Author Lukas Zeller (luz@plan44.ch) * * @brief TODBCApiAgent * ODBC based agent (client or server session) implementation * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * @Date 2005-10-06 : luz : created from odbcdbagent */ #ifdef SQL_SUPPORT #ifndef ODBCAPIAGENT_H #define ODBCAPIAGENT_H // includes #ifdef SQLITE_SUPPORT #include "sqlite3.h" #endif #include "odbcdb.h" #include "customimplagent.h" #include "customimplds.h" #include "multifielditem.h" #include "scriptcontext.h" using namespace sysync; namespace sysync { // Support for SySync Diagnostic Tool #ifdef SYSYNC_TOOL // - execute SQL command int execSQL(int argc, const char *argv[]); #endif // SYSYNC_TOOL #ifdef SCRIPT_SUPPORT // publish as derivates might need it extern const TFuncTable ODBCAgentFuncTable; // publish as ODBCDBDatastore uses this (chains back to Datastore level funcs) extern const TFuncTable ODBCDSFuncTable1; #endif // supported transaction isolation levels typedef enum { // Note: these MUST be in the same order as // Win32/ODBC defined SQL_TXN_READ_UNCOMMITTED..SQL_TXN_SERIALIZABLE // bits appear in the transaction bitmasks. txni_uncommitted, // read uncommitted (dirty reads possible) txni_committed, // read committed only txni_repeatable, // repeatable txni_serializable, // no dirty reads, repeatable, no phantoms // special values txni_none, // no transactions txni_default // default of data source } TTxnIsolModes; const sInt16 numTxnIsolModes = txni_default-txni_uncommitted+1; // standard size for parameter buffers if not specified const size_t std_paramsize = 512; // parameter value type typedef enum { param_field, param_localid_str, param_localid_int, param_remoteid_str, param_remoteid_int, param_buffer } TParamMode; // parameter mapping entry typedef struct { // parameter specification bool inparam; bool outparam; TParamMode parammode; // value source/target TDBFieldType dbFieldType; // field info for param_field TItemField *fieldP; size_t maxSize; TMultiFieldItem *itemP; // can be null if no item available // size info for param_buffer uInt32 *outSiz; // Parameter value buffer bool mybuffer; #ifdef ODBCAPI_SUPPORT SQLPOINTER ParameterValuePtr; SQLLEN BufferLength; SQLLEN StrLen_or_Ind; #elif defined(SQLITE_SUPPORT) appPointer ParameterValuePtr; memSize BufferLength; memSize StrLen_or_Ind; #endif } TParameterMap; // parameter mapping list typedef std::list TParameterMapList; #ifdef WIN32 // windows, has SEH, leave it on (unless set by target options etc.) #else // non-windows, no SEH anyway #define NO_AV_GUARDING #endif #ifdef ODBCAPI_SUPPORT #if defined(NO_AV_GUARDING) // || __option(microsoft_exceptions) // SEH is on (or we can't catch AV at all), we don't need extra crash-guarding #define SafeSQLAllocHandle SQLAllocHandle #define SafeSQLFreeHandle SQLFreeHandle #define SafeSQLSetEnvAttr SQLSetEnvAttr #define SafeSQLSetConnectAttr SQLSetConnectAttr #define SafeSQLConnect SQLConnect #define SafeSQLDriverConnect SQLDriverConnect #define SafeSQLGetInfo SQLGetInfo #define SafeSQLEndTran SQLEndTran #define SafeSQLExecDirect SQLExecDirect #define SafeSQLFetch SQLFetch #define SafeSQLNumResultCols SQLNumResultCols #define SafeSQLGetData SQLGetData #define SafeSQLCloseCursor SQLCloseCursor #ifdef ODBC_UNICODE #define SafeSQLExecDirectW SQLExecDirectW #endif #else // special exception for SEH class TODBCSEHexception : public TSyncException { typedef TSyncException inherited; public: TODBCSEHexception(uInt32 aCode); }; // TODBCSEHexception // prototypes SQLRETURN SafeSQLAllocHandle( SQLSMALLINT HandleType, SQLHANDLE InputHandle, SQLHANDLE * OutputHandlePtr); SQLRETURN SafeSQLFreeHandle( SQLSMALLINT HandleType, SQLHANDLE Handle); SQLRETURN SafeSQLSetEnvAttr( SQLHENV EnvironmentHandle, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLINTEGER StringLength); SQLRETURN SafeSQLSetConnectAttr( SQLHDBC ConnectionHandle, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLINTEGER StringLength); SQLRETURN SafeSQLConnect( SQLHDBC ConnectionHandle, SQLCHAR * ServerName, SQLSMALLINT NameLength1, SQLCHAR * UserName, SQLSMALLINT NameLength2, SQLCHAR * Authentication, SQLSMALLINT NameLength3); SQLRETURN SafeSQLDriverConnect( SQLHDBC ConnectionHandle, SQLHWND WindowHandle, SQLCHAR * InConnectionString, SQLSMALLINT StringLength1, SQLCHAR * OutConnectionString, SQLSMALLINT BufferLength, SQLSMALLINT * StringLength2Ptr, SQLUSMALLINT DriverCompletion); SQLRETURN SafeSQLGetInfo( SQLHDBC ConnectionHandle, SQLUSMALLINT InfoType, SQLPOINTER InfoValuePtr, SQLSMALLINT BufferLength, SQLSMALLINT * StringLengthPtr); SQLRETURN SafeSQLEndTran( SQLSMALLINT HandleType, SQLHANDLE Handle, SQLSMALLINT CompletionType); SQLRETURN SafeSQLExecDirect( SQLHSTMT StatementHandle, SQLCHAR * StatementText, SQLINTEGER TextLength); #ifdef ODBC_UNICODE SQLRETURN SafeSQLExecDirectW( SQLHSTMT StatementHandle, SQLWCHAR * StatementText, SQLINTEGER TextLength); #endif SQLRETURN SafeSQLFetch( SQLHSTMT StatementHandle); SQLRETURN SafeSQLNumResultCols( SQLHSTMT StatementHandle, SQLSMALLINT * ColumnCountPtr); SQLRETURN SafeSQLGetData( SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNumber, SQLSMALLINT TargetType, SQLPOINTER TargetValuePtr, SQLINTEGER BufferLength, SQLLEN * StrLen_or_IndPtr); SQLRETURN SafeSQLCloseCursor( SQLHSTMT StatementHandle); #endif #endif // ODBCAPI_SUPPORT // ODBC Utils // - return quoted version of string if aDoQuote is set const char *quoteString(string &aIn, string &aOut, TQuotingModes aQuoteMode); const char *quoteString(const char *aIn, string &aOut, TQuotingModes aQuoteMode); void quoteStringAppend(string &aIn, string &aOut, TQuotingModes aQuoteMode); void quoteStringAppend(const char *aIn, string &aOut, TQuotingModes aQuoteMode); // forward class TODBCDSConfig; #ifdef SCRIPT_SUPPORT class TScriptContext; #endif class TOdbcAgentConfig : public TCustomAgentConfig { typedef TCustomAgentConfig inherited; public: TOdbcAgentConfig(TConfigElement *aParentElement); virtual ~TOdbcAgentConfig(); // properties #ifdef ODBCAPI_SUPPORT // - ODBC datasource string fDataSource; #ifdef SCRIPT_SUPPORT // - scripts string fAfterConnectScript; // called after opening an ODBC connection #endif // - Server username / password string fUsername; string fPassword; // - connection string string fDBConnStr; // - preventing use of SQLSetConnectAttr (for drivers that crash when using it) bool fNoConnectAttrs; // - timeout sInt32 fODBCTimeout; // - transaction isolation mode sInt16 fODBCTxnMode; // - cursor library usage bool fUseCursorLib; // - statements to maintain device table string fGetDeviceSQL; // if set, fGetDeviceSQL must return device key and last saved nonce string fNewDeviceSQL; // create new device entry string fSaveNonceSQL; // save nonce into existing device entry string fSaveInfoSQL; // save extra device info string fSaveDevInfSQL; // save device information (such as name) into existing device entry string fLoadDevInfSQL; // load cached device information from DB // - statement to obtain user key (and password if fClearTextPw) from Database // replacements: %U=username, %M=user:pw: MD5 string fUserKeySQL; bool fClearTextPw; // if set, fUserKeySQL must return clear text PW in second column. bool fMD5UserPass; // if set, fUserKeySQL must return MD5B64("user:password") or HEX(MD5("user:password"))in second column. bool fMD5UPAsHex; // if set, format expected from DB is a hex string (not B64) // - statement to obtain database server's date and time (if none, local time is used) string fGetCurrentDateTimeSQL; // - statement to save log info string fWriteLogSQL; #endif // ODBCAPI_SUPPORT // - Literal string quoting mode TQuotingModes fQuotingMode; #ifdef SCRIPT_SUPPORT // provided to allow derivates to add API specific script functions to scripts called from customagent virtual const TFuncTable *getAgentFuncTableP(void) { return &ODBCAgentFuncTable; }; #endif protected: // check config elements virtual bool localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine); virtual void clear(); virtual void localResolve(bool aLastPass); #ifdef SCRIPT_SUPPORT virtual void ResolveAPIScripts(void); #endif #ifdef SYSYNC_CLIENT // create appropriate session (=agent) for this client virtual TSyncAgent *CreateClientSession(const char *aSessionID); #endif public: #ifdef SYSYNC_SERVER // create appropriate session (=agent) for this server virtual TSyncAgent *CreateServerSession(TSyncSessionHandle *aSessionHandle, const char *aSessionID); #endif }; // TOdbcAgentConfig class TODBCApiDS; class TODBCApiAgent: public TCustomImplAgent { friend class TODBCCommonFuncs; friend class TODBCAgentFuncs; typedef TCustomImplAgent inherited; public: TODBCApiAgent(TSyncAppBase *aAppBaseP, TSyncSessionHandle *aSessionHandleP, cAppCharP aSessionID); virtual ~TODBCApiAgent(); virtual void TerminateSession(void); // Terminate session, like destructor, but without actually destructing object itself virtual void ResetSession(void); // Resets session (but unlike TerminateSession, session might be re-used) void InternalResetSession(void); // static implementation for calling through virtual destructor and virtual ResetSession(); #ifdef HAS_SQL_ADMIN // Note: %%% for now, login is supported by ODBC only // user authentication #ifdef SYSYNC_SERVER // - return auth type to be requested from remote virtual TAuthTypes requestedAuthType(void); // avoids MD5 when it cannot be checked // - get next nonce string top be sent to remote party for subsequent MD5 auth virtual void getNextNonce(const char *aDeviceID, string &aNextNonce); // - get nonce string, which is expected to be used by remote party for MD5 auth. virtual void getAuthNonce(const char *aDeviceID, string &aAuthNonce); #endif // SYSYNC_SERVER // - clean up after all login activity is over (including finishscript) virtual void LoginCleanUp(void); #endif // HAS_SQL_ADMIN #ifdef ODBCAPI_SUPPORT // current date & time virtual lineartime_t getDatabaseNowAs(timecontext_t aTimecontext); #endif // SQL generic // - do substitutions (%x-type) in a SQL string void DoSQLSubstitutions(string &aSQL); // Parameter handling // - reset all mapped parameters void resetSQLParameterMaps(void); // - add parameter definition to the session level parameter list void addSQLParameterMap( bool aInParam, bool aOutParam, TParamMode aParamMode, TItemField *aFieldP, TDBFieldType aDbFieldType ); #ifdef ODBCAPI_SUPPORT // ODBC SQLHENV getODBCEnvironmentHandle(void); // - get handle to open connection (open it if not already open) SQLHDBC getODBCConnectionHandle(void); // - pull (=take ownership of) connection handle out of session into another object (datastore) SQLHDBC pullODBCConnectionHandle(void); // - check for connection-level error void checkConnectionError(SQLRETURN aResult); #endif // ODBCAPI_SUPPORT // SQL based agent config TOdbcAgentConfig *fConfigP; // %%% Script statement is always defined, as we need it as dummy even in SQLite only case for now #ifdef SCRIPT_SUPPORT HSTMT fScriptStatement; #endif // SQL generic utils // - make ODBC string from field bool appendFieldValueLiteral( TItemField &aField,TDBFieldType aDBFieldType, uInt32 aMaxSize, string &aSQL, TCharSets aDataCharSet, TLineEndModes aDataLineEndMode, TQuotingModes aQuotingMode, timecontext_t aTimeContext, sInt32 &aRecordSize ); // - make ODBC string literal from UTF8 string void stringToODBCLiteralAppend( cAppCharP aText, string &aLiteral, TCharSets aCharSet, TLineEndModes aLineEndMode, TQuotingModes aQuotingMode, size_t aMaxBytes=0 ); // - make ODBC date/time literals from lineartime_t void lineartimeToODBCLiteralAppend( lineartime_t aTimestamp, string &aString, bool aWithDate, bool aWithTime, timecontext_t aTsContext=TCTX_UNKNOWN, timecontext_t aDBContext=TCTX_UNKNOWN ); // - make integer-based literals from lineartime_t void lineartimeToIntLiteralAppend( lineartime_t aTimestamp, string &aString, TDBFieldType aDbfty, timecontext_t aTsContext=TCTX_UNKNOWN, timecontext_t aDBContext=TCTX_UNKNOWN ); /* obsolete // - make ODBC date/time literal from timestamp void timeStampToODBCLiteralAppend(lineartime_t aTimeStamp, string &aString, bool aAsUTC, bool aWithDate, bool aWithTime); // - make ODBC date/time literal from struct tm void tmToODBCLiteralAppend(const struct tm &tim, string &aString, bool aWithDate, bool aWithTime); */ #ifdef ODBCAPI_SUPPORT // ODBC utils // - commit and close possibly open script statement void commitAndCloseScriptStatement(void); #ifdef SCRIPT_SUPPORT // - get statement for executing scripted SQL HSTMT getScriptStatement(void); #endif // - close connection void closeODBCConnection(SQLHDBC &aConnHandle); // - check if aResult signals error and throw exception if so void checkODBCError(SQLRETURN aResult,SQLSMALLINT aHandleType,SQLHANDLE aHandle); // - check if aResult signals error and throw exception if so void checkStatementError(SQLRETURN aResult,SQLHSTMT aHandle); // - check if aResult is NO_DATA, return False if so, throw exception on error bool checkStatementHasData(SQLRETURN aResult,SQLHSTMT aHandle); // - get ODBC error message for given result code, returns false if no error bool getODBCError(SQLRETURN aResult, string &aMessage, string &aSQLState, SQLSMALLINT aHandleType, SQLHANDLE aHandle); // - get new statement handle SQLHSTMT newStatementHandle(SQLHDBC aConnection); // - get column value as database field bool getColumnValueAsField( SQLHSTMT aStatement, sInt16 aColIndex, TDBFieldType aDbfty, TItemField *aFieldP, TCharSets aDataCharSet, timecontext_t aTimecontext, bool aMoveToUserContext ); // - get integer value, returns false if no Data or Null bool getColumnValueAsULong( SQLHSTMT aStatement, sInt16 aColNumber, uInt32 &aLongValue ); bool getColumnValueAsLong( SQLHSTMT aStatement, sInt16 aColNumber, sInt32 &aLongValue ); // - get double value, returns false if no Data or Null bool getColumnValueAsDouble( SQLHSTMT aStatement, sInt16 aColNumber, double &aDoubleValue ); // - get string value, returns false if no Data or Null bool getColumnValueAsString( SQLHSTMT aStatement, sInt16 aColNumber, string &aStringValue, TCharSets aCharSet, bool aAsBlob=false ); // - get time/date values, returns false if no Data or Null bool getColumnAsODBCTimestamp( SQLHSTMT aStatement, sInt16 aColNumber, SQL_TIMESTAMP_STRUCT &aODBCTimestamp ); bool getColumnValueAsTimestamp( SQLHSTMT aStatement, sInt16 aColNumber, lineartime_t &aTimestamp ); bool getColumnValueAsTime( SQLHSTMT aStatement, sInt16 aColNumber, lineartime_t &aTime ); bool getColumnValueAsDate( SQLHSTMT aStatement, sInt16 aColNumber, lineartime_t &aDate ); // - bind parameters (and values for IN-Params) to the statement void bindSQLParameters( TSyncSession *aSessionP, SQLHSTMT aStatement, TParameterMapList &aParamMapList, // the list of mapped parameters TCharSets aDataCharSet, TLineEndModes aDataLineEndMode ); // - save out parameter values and clean up void saveAndCleanupSQLParameters( TSyncSession *aSessionP, SQLHSTMT aStatement, TParameterMapList &aParamMapList, // the list of mapped parameters TCharSets aDataCharSet, TLineEndModes aDataLineEndMode ); // - bind parameters (and values for IN-Params) to the statement for session level SQL void bindSQLParameters( SQLHSTMT aStatement ); // - save out parameter values and clean up for session level SQL void saveAndCleanupSQLParameters( SQLHSTMT aStatement ); #endif // ODBCAPI_SUPPORT // SQLite utils #ifdef SQLITE_SUPPORT // - get SQLite error message for given result code; returns false if no error bool getSQLiteError(int aRc,string &aMessage, sqlite3 *aDb); // - check if aResult signals error and throw exception if so void checkSQLiteError(int aRc, sqlite3 *aDb); // - check if aRc signals error and throw exception if so; returns true if data available, false if not bool checkSQLiteHasData(int aRc, sqlite3 *aDb); // - get column value into field bool getSQLiteColValueAsField( sqlite3_stmt *aStatement, sInt16 aColIndex, TDBFieldType aDbfty, TItemField *aFieldP, TCharSets aDataCharSet, timecontext_t aTimecontext, bool aMoveToUserContext ); // - prepare SQLite statement void prepareSQLiteStatement( cAppCharP aSQL, sqlite3 *aDB, sqlite3_stmt *&aStatement ); // - bind SQLite parameters (we have ONLY in-params)! void bindSQLiteParameters( TSyncSession *aSessionP, sqlite3_stmt *aStatement, TParameterMapList &aParamMapList, // the list of mapped parameters TCharSets aDataCharSet, TLineEndModes aDataLineEndMode ); #endif // SQLITE_SUPPORT // parameter handling routines // - reset all mapped parameters void resetSQLParameterMaps(TParameterMapList &aParamMapList); // - parsing of %p(fieldname,mode[,dbfieldtype]) sequence in SQL statements bool ParseParamSubst( string &aSQL, // string to parse string::size_type &i, // position where % sequence starts in aSQL string::size_type &n, // input=number of chars of % sequence without parameters, if result==true: output=number of chars to substitute at i in aSQL TParameterMapList &aParameterMaps, // parameter maps list to add params to TMultiFieldItem *aItemP // the involved item for field params #ifdef SCRIPT_SUPPORT ,TScriptContext *aScriptContextP // the script context for variable params #endif ); protected: #ifdef HAS_SQL_ADMIN // - check device ID related stuff virtual void CheckDevice(const char *aDeviceID); // - check user/pw (part of SessionLogin process) virtual bool CheckLogin(const char *aOriginalUserName, const char *aModifiedUserName, const char *aAuthString, TAuthSecretTypes aAuthStringType, const char *aDeviceID); // - remote device is analyzed, possibly save status virtual void remoteAnalyzed(void); #endif // HAS_SQL_ADMIN #ifdef SYSYNC_SERVER // - request end, used to clean up virtual void RequestEnded(bool &aHasData); #endif private: #ifdef ODBCAPI_SUPPORT // ODBC vars // - session-specific connection string string fSessionDBConnStr; string fSessionDBPassword; // - handles SQLHDBC fODBCConnectionHandle; SQLHENV fODBCEnvironmentHandle; #ifdef SCRIPT_SUPPORT // private context for afterconnect script as it might be called nested in other scripts (e.g. triggered by SQLEXECUTE) TScriptContext *fAfterConnectContext; #endif // SCRIPT_SUPPORT #endif // ODBCAPI_SUPPORT // parameter list for execution of commands TParameterMapList fParameterMaps; }; // TODBCApiAgent } // namespace sysync #endif // ODBCAPIAGENT_H #endif // SQL_SUPPORT // eof libsynthesis-3.4.0.47.1/src/DB_interfaces/odbc_db/odbcapids.cpp000077500000000000000000005066751226375725500241610ustar00rootroot00000000000000/** * @File odbcapids.cpp * * @Author Lukas Zeller (luz@plan44.ch) * * @brief TODBCApiDS * ODBC based datastore API implementation * @Note Currently also contains what will later become TCustomImplDS * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * @Date 2005-09-16 : luz : created from odbcdbdatastore */ #include "prefix_file.h" #ifdef SQL_SUPPORT // includes #include "sysync.h" #include "odbcapids.h" #include "odbcapiagent.h" // sanity check for current implementation - either SQLite or ODBC must be enabled #if !defined(ODBCAPI_SUPPORT) && !defined(SQLITE_SUPPORT) #error "ODBC or SQLite API must be enabled" #endif namespace sysync { // special ID mode names const char * const SpecialIDModeNames[numSpecialIDModes] = { "none", "unixmsrnd6" }; #ifdef SCRIPT_SUPPORT class TODBCDSfuncs { public: // ODBC datastore specific script functions // ======================================== // SETSQLFILTER(string filter) static void func_SetSQLFilter(TItemField *&aTermP, TScriptContext *aFuncContextP) { aFuncContextP->getLocalVar(0)->getAsString( static_cast(aFuncContextP->getCallerContext())->fSQLFilter ); }; // func_SetSQLFilter // ADDBYUPDATING(string idtoupdate) static void func_AddByUpdating(TItemField *&aTermP, TScriptContext *aFuncContextP) { TODBCApiDS *dsP = static_cast(aFuncContextP->getCallerContext()); // only if inserting, convert to updating an existing record if (dsP->fInserting) { string localid; aFuncContextP->getLocalVar(0)->getAsString(localid); aFuncContextP->fParentContextP->fTargetItemP->setLocalID(localid.c_str()); // switch off inserting from here on, such that UPDATE SQL will be used dsP->fInserting = false; } }; // func_AddByUpdating #ifdef SQLITE_SUPPORT // integer SQLITELASTID() // get ROWID created by last insert static void func_SQLGetLastID(TItemField *&aTermP, TScriptContext *aFuncContextP) { TODBCApiDS *dsP = static_cast(aFuncContextP->getCallerContext()); if (dsP->fUseSQLite && dsP->fSQLiteP) { aTermP->setAsInteger( sqlite3_last_insert_rowid(dsP->fSQLiteP) ); } else { aTermP->unAssign(); } }; // func_SQLGetLastID #endif // SQLITE_SUPPORT }; // TODBCDSfuncs const uInt8 param_OneStr[] = { VAL(fty_string) }; // builtin function table for datastore level const TBuiltInFuncDef ODBCDSFuncDefs[] = { { "SETSQLFILTER", TODBCDSfuncs::func_SetSQLFilter, fty_none, 1, param_OneStr }, { "ADDBYUPDATING", TODBCDSfuncs::func_AddByUpdating, fty_none, 1, param_OneStr }, #ifdef SQLITE_SUPPORT { "SQLITELASTID", TODBCDSfuncs::func_SQLGetLastID, fty_integer, 0, NULL }, #endif }; // chain to generic local datastore funcs static void *ODBCDSChainFunc2(void *&aCtx) { // context pointer for datastore-level funcs is the datastore // -> no change needed // next table is customimplds's (and then the localdatastore's from there) return (void *)&CustomDSFuncTable2; } // ODBCDSChainFunc const TFuncTable ODBCDSFuncTable2 = { sizeof(ODBCDSFuncDefs) / sizeof(TBuiltInFuncDef), // size of table ODBCDSFuncDefs, // table pointer ODBCDSChainFunc2 // chain generic DB functions }; #endif // SCRIPT_SUPPORT // Config // ====== TOdbcDSConfig::TOdbcDSConfig(const char* aName, TConfigElement *aParentElement) : inherited(aName,aParentElement) { // nop so far clear(); // except ensure we have a decent rand() srand((uInt32)time(NULL)); } // TOdbcDSConfig::TOdbcDSConfig TOdbcDSConfig::~TOdbcDSConfig() { // nop so far } // TOdbcDSConfig::~TOdbcDSConfig // init defaults void TOdbcDSConfig::clear(void) { // init defaults // - commit modes fCommitItems=false; // commit item changes all at end of write by default // - retries fInsertRetries=0; // none fUpdateRetries=0; // none // - folder key #ifdef HAS_SQL_ADMIN fFolderKeySQL.erase(); // - Sync target table fGetSyncTargetSQL.erase(); fNewSyncTargetSQL.erase(); fUpdateSyncTargetSQL.erase(); fDeleteSyncTargetSQL.erase(); fSyncTimestamp=true; #ifdef OLD_1_0_5_CONFIG_COMPATIBLE // Compatibility with old config files // - layout of map table fMapTableName.erase(); fRemoteIDMapField.erase(); fLocalIDMapField.erase(); fStringLocalID=true; fTargetKeyMapField.erase(); fStringTargetkey=true; // - layout of data table fLocalTableName.erase(); // - name of folderkey subselection field in data table, empty if none fFolderKeyField.erase(); fStringFolderkey=true; // - name of field which contains Local ID (GUID) fLocalIDField.erase(); // - mod date/time fModifiedDateField.erase(); fModifiedTimeField.erase(); #endif // OLD_1_0_5_CONFIG_COMPATIBLE // Map table access, new version // - SQL to fetch all map entries of a target fMapFetchAllSQL.erase(); // - SQL to insert new map entry by localid fMapInsertSQL.erase(); // - SQL to update existing map entry by localid fMapUpdateSQL.erase(); // - SQL to delete a map entry by localid fMapDeleteSQL.erase(); #endif // HAS_SQL_ADMIN // Data table access, new version // - SQL to fetch local ID and timestamp from data table fLocalIDAndTimestampFetchSQL.erase(); fModifiedTimestamp=true; // - SQL to fetch actual data fields from data table. SQL result must // contain mapped fields in the same order as they appear in fDataFetchSQL.erase(); // - SQL to insert new data in a record, including modification date fDataInsertSQL.erase(); // - SQL to update actual data in a record, including modification date fDataUpdateSQL.erase(); // - SQL to delete a record fDataDeleteSQL.erase(); // - SQL statement(s) to zap entire sync set fDataZapSQL.erase(); // Data table options // - try to translate filters to SQL if possible fFilterOnDBLevel=false; // don't try // - quoting mode for string literals fQuotingMode=qm_duplsingle; // default to what was hard-coded before it became configurable in 2.1.1.5 // - Obtaining ID for new records fDetermineNewIDOnce=false; fObtainNewIDAfterInsert=false; fObtainNewLocalIDSql.erase(); #ifdef SCRIPT_SUPPORT fLocalIDScript.erase(); #endif fMinNextID=1000000; fSpecialIDMode=sidm_none; fInsertReturnsID=false; fInsertIDAsOutParam=false; fIgnoreAffectedCount=false; fLastModDBFieldType=dbft_timestamp; // default to what we always had before 3.1 engine for ODBC // SQLite support #ifdef SQLITE_SUPPORT fSQLiteFileName.erase(); fSQLiteBusyTimeout=15; // 15 secs #endif // clear inherited inherited::clear(); } // TOdbcDSConfig::clear // config element parsing bool TOdbcDSConfig::localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine) { // commit modes if (strucmp(aElementName,"commititems")==0) expectBool(fCommitItems); // retries else if (strucmp(aElementName,"insertretries")==0) expectInt16(fInsertRetries); else if (strucmp(aElementName,"updateretries")==0) expectInt16(fUpdateRetries); #ifdef HAS_SQL_ADMIN // - folder key else if (strucmp(aElementName,"folderkeysql")==0) expectString(fFolderKeySQL); // - Sync target table handling else if (strucmp(aElementName,"synctargetgetsql")==0) expectString(fGetSyncTargetSQL); else if (strucmp(aElementName,"synctargetnewsql")==0) expectString(fNewSyncTargetSQL); else if (strucmp(aElementName,"synctargetupdatesql")==0) expectString(fUpdateSyncTargetSQL); else if (strucmp(aElementName,"synctargetdeletesql")==0) expectString(fDeleteSyncTargetSQL); else if (strucmp(aElementName,"synctimestamp")==0) expectBool(fSyncTimestamp); #ifdef OLD_1_0_5_CONFIG_COMPATIBLE // Compatibility with old config files // - layout of map table else if (strucmp(aElementName,"maptablename")==0) expectString(fMapTableName); else if (strucmp(aElementName,"remoteidmapfield")==0) expectString(fRemoteIDMapField); else if (strucmp(aElementName,"localidmapfield")==0) expectString(fLocalIDMapField); else if (strucmp(aElementName,"stringlocalid")==0) expectBool(fStringLocalID); else if (strucmp(aElementName,"targetkeymapfield")==0) expectString(fTargetKeyMapField); else if (strucmp(aElementName,"stringtargetkey")==0) expectBool(fStringTargetkey); // - layout of data table else if (strucmp(aElementName,"datatablename")==0) { ReportError(false,"Warning: old-style config - use full SQL statements with %%xx replacement sequences instead"); expectString(fLocalTableName); } else if (strucmp(aElementName,"folderkeyfield")==0) expectString(fFolderKeyField); else if (strucmp(aElementName,"stringfolderkey")==0) expectBool(fStringFolderkey); else if (strucmp(aElementName,"localidfield")==0) expectString(fLocalIDField); else if (strucmp(aElementName,"moddatefield")==0) expectString(fModifiedDateField); else if (strucmp(aElementName,"modtimefield")==0) expectString(fModifiedTimeField); // Note: was never documented so will be phased out right now // else if (strucmp(aElementName,"genselectcond")==0) // expectString(fGeneralSelectCondition); #endif // OLD_1_0_5_CONFIG_COMPATIBLE // Map table access, new version else if (strucmp(aElementName,"selectmapallsql")==0) expectString(fMapFetchAllSQL); else if (strucmp(aElementName,"insertmapsql")==0) expectString(fMapInsertSQL); else if (strucmp(aElementName,"updatemapsql")==0) expectString(fMapUpdateSQL); else if (strucmp(aElementName,"deletemapsql")==0) expectString(fMapDeleteSQL); #endif // HAS_SQL_ADMIN // Data table access, new version else if (strucmp(aElementName,"quotingmode")==0) expectEnum(sizeof(fQuotingMode),&fQuotingMode,quotingModeNames,numQuotingModes); else if (strucmp(aElementName,"dbcanfilter")==0) expectBool(fFilterOnDBLevel); else if (strucmp(aElementName,"selectidandmodifiedsql")==0) expectString(fLocalIDAndTimestampFetchSQL); else if (strucmp(aElementName,"modtimestamp")==0) expectBool(fModifiedTimestamp); else if (strucmp(aElementName,"selectdatasql")==0) expectString(fDataFetchSQL); else if (strucmp(aElementName,"insertdatasql")==0) expectString(fDataInsertSQL); else if (strucmp(aElementName,"updatedatasql")==0) expectString(fDataUpdateSQL); else if (strucmp(aElementName,"deletedatasql")==0) expectString(fDataDeleteSQL); else if (strucmp(aElementName,"zapdatasql")==0) expectString(fDataZapSQL); // - Obtaining ID for new records else if (strucmp(aElementName,"determineidonce")==0) expectBool(fDetermineNewIDOnce); else if (strucmp(aElementName,"obtainidafterinsert")==0) expectBool(fObtainNewIDAfterInsert); else if (strucmp(aElementName,"obtainlocalidsql")==0) expectString(fObtainNewLocalIDSql); else if (strucmp(aElementName,"minnextid")==0) expectInt32(fMinNextID); #ifdef SCRIPT_SUPPORT else if (strucmp(aElementName,"localidscript")==0) expectScript(fLocalIDScript, aLine, getDSFuncTableP()); #endif else if (strucmp(aElementName,"specialidmode")==0) expectEnum(sizeof(fSpecialIDMode),&fSpecialIDMode,SpecialIDModeNames,numSpecialIDModes); else if (strucmp(aElementName,"insertreturnsid")==0) expectBool(fInsertReturnsID); else if (strucmp(aElementName,"idasoutparam")==0) // %%% possibly obsolete, replaced by %pkos and %pkoi expectBool(fInsertIDAsOutParam); else if (strucmp(aElementName,"ignoreaffectedcount")==0) expectBool(fIgnoreAffectedCount); else if (strucmp(aElementName,"lastmodfieldtype")==0) expectEnum(sizeof(fLastModDBFieldType),&fLastModDBFieldType,DBFieldTypeNames,numDBfieldTypes); // - SQLite support #ifdef SQLITE_SUPPORT else if (strucmp(aElementName,"sqlitefile")==0) expectMacroString(fSQLiteFileName); else if (strucmp(aElementName,"sqlitebusytimeout")==0) expectUInt32(fSQLiteBusyTimeout); #endif // - field mappings else if (strucmp(aElementName,"fieldmap")==0) { // check reference argument const char* ref = getAttr(aAttributes,"fieldlist"); if (!ref) { ReportError(true,"fieldmap missing 'fieldlist' attribute"); } else { // look for field list TMultiFieldDatatypesConfig *mfcfgP = dynamic_cast(getSyncAppBase()->getRootConfig()->fDatatypesConfigP); if (!mfcfgP) throw TConfigParseException("no multifield config"); TFieldListConfig *cfgP = mfcfgP->getFieldList(ref); if (!cfgP) return fail("fieldlist '%s' not defined for fieldmap",ref); // - store field list reference in map fFieldMappings.fFieldListP=cfgP; // - let element handle parsing expectChildParsing(fFieldMappings); } } // - none known here else return inherited::localStartElement(aElementName,aAttributes,aLine); // ok return true; } // TOdbcDSConfig::localStartElement // resolve void TOdbcDSConfig::localResolve(bool aLastPass) { if (aLastPass) { #ifndef ODBC_UNICODE // make sure we don't try to use UTF-16 if (fDataCharSet==chs_utf16) SYSYNC_THROW(TConfigParseException("UTF-16 wide character set can only be used on ODBC-Unicode enabled platforms")); #endif #ifdef SQLITE_SUPPORT // %%% NOP at this time #endif #ifdef OLD_1_0_5_CONFIG_COMPATIBLE // generate new settings from old ones if (fLocalIDAndTimestampFetchSQL.empty()) { // SELECT localid,modifieddate(,modifiedtime)... fLocalIDAndTimestampFetchSQL="SELECT "; fLocalIDAndTimestampFetchSQL+=fLocalIDField; fLocalIDAndTimestampFetchSQL+=", "; fLocalIDAndTimestampFetchSQL += fModifiedDateField; if (!fModifiedTimestamp && !fModifiedTimeField.empty()) { fLocalIDAndTimestampFetchSQL += ", "; fLocalIDAndTimestampFetchSQL += fModifiedTimeField; } // ...FROM datatable fLocalIDAndTimestampFetchSQL+=" FROM "; fLocalIDAndTimestampFetchSQL+=fLocalTableName; // ...WHERE folderkey=x... fLocalIDAndTimestampFetchSQL+=" WHERE "; fLocalIDAndTimestampFetchSQL+=fFolderKeyField; fLocalIDAndTimestampFetchSQL+='='; quoteStringAppend("%f",fLocalIDAndTimestampFetchSQL,fStringFolderkey ? qm_backslash : qm_none); // ...AND filterclause fLocalIDAndTimestampFetchSQL+="%AF"; PDEBUGPRINTFX(DBG_EXOTIC,(" %s",fLocalIDAndTimestampFetchSQL.c_str())); } if (fDataFetchSQL.empty()) { // SELECT %N FROM datatable WHERE localid=%k AND folderkey=%f fDataFetchSQL="SELECT %N FROM "; fDataFetchSQL+=fLocalTableName; fDataFetchSQL+=" WHERE "; fDataFetchSQL+=fLocalIDField; fDataFetchSQL+='='; quoteStringAppend("%k",fDataFetchSQL,fStringLocalID ? qm_backslash : qm_none); fDataFetchSQL+=" AND "; fDataFetchSQL+=fFolderKeyField; fDataFetchSQL+='='; quoteStringAppend("%f",fDataFetchSQL,fStringFolderkey ? qm_backslash : qm_none); PDEBUGPRINTFX(DBG_EXOTIC,(" %s",fDataFetchSQL.c_str())); } if (fDataInsertSQL.empty()) { // INSERT INTO datatable (keyfield,modtimestamp,folderkey,%N) VALUES (%k,%M,%f,%v) fDataInsertSQL="INSERT INTO "; fDataInsertSQL+=fLocalTableName; fDataInsertSQL+=" ("; if (fDetermineNewIDOnce || !fObtainNewIDAfterInsert) { // insert key only if previously generated separately fDataInsertSQL+=fLocalIDField; fDataInsertSQL+=", "; } fDataInsertSQL += fModifiedDateField; if (!fModifiedTimestamp && !fModifiedTimeField.empty()) { fDataInsertSQL += ", "; fDataInsertSQL += fModifiedTimeField; } if (!fFolderKeyField.empty()) { fDataInsertSQL += ", "; fDataInsertSQL+=fFolderKeyField; } fDataInsertSQL+=", %N) VALUES ("; if (fDetermineNewIDOnce || !fObtainNewIDAfterInsert) { // insert key only if previously generated separately quoteStringAppend("%k",fDataInsertSQL,fStringLocalID ? qm_backslash : qm_none); fDataInsertSQL += ", "; } if (!fModifiedTimestamp) { fDataInsertSQL += "%dM"; if (!fModifiedTimeField.empty()) fDataInsertSQL += ", %tM"; } else { fDataInsertSQL += "%M"; } if (!fFolderKeyField.empty()) { fDataInsertSQL += ", %f"; } fDataInsertSQL+=", %v)"; PDEBUGPRINTFX(DBG_EXOTIC,(" %s",fDataInsertSQL.c_str())); } if (fDataUpdateSQL.empty()) { // UPDATE datatable SET modtimestamp=%M, %V WHERE localid=%k fDataUpdateSQL="UPDATE "; fDataUpdateSQL+=fLocalTableName; fDataUpdateSQL+=" SET "; if (!fModifiedTimestamp) { fDataUpdateSQL += fModifiedDateField; fDataUpdateSQL += "=%dM"; if (!fModifiedTimeField.empty()) { fDataUpdateSQL += ", "; fDataUpdateSQL += fModifiedTimeField; fDataUpdateSQL += "=%tM"; } } else { fDataUpdateSQL += fModifiedDateField; fDataUpdateSQL += "=%M"; } fDataUpdateSQL += ", %V WHERE "; fDataUpdateSQL+=fLocalIDField; fDataUpdateSQL += "="; quoteStringAppend("%k",fDataUpdateSQL,fStringLocalID ? qm_backslash : qm_none); PDEBUGPRINTFX(DBG_EXOTIC,(" %s",fDataUpdateSQL.c_str())); } if (fDataDeleteSQL.empty()) { // DELETE FROM datatable WHERE localid=%k fDataDeleteSQL="DELETE FROM "; fDataDeleteSQL+=fLocalTableName; fDataDeleteSQL+=" WHERE "; fDataDeleteSQL+=fLocalIDField; fDataDeleteSQL+="="; quoteStringAppend("%k",fDataDeleteSQL,fStringLocalID ? qm_backslash : qm_none); PDEBUGPRINTFX(DBG_EXOTIC,(" %s",fDataDeleteSQL.c_str())); } if (fDataZapSQL.empty() && !fLocalTableName.empty()) { // DELETE FROM datatable fDataZapSQL="DELETE FROM "; fDataZapSQL+=fLocalTableName; // ...WHERE folderkey=x... fDataZapSQL+=" WHERE "; fDataZapSQL+=fFolderKeyField; fDataZapSQL+='='; quoteStringAppend("%f",fDataZapSQL,fStringFolderkey ? qm_backslash : qm_none); // ...AND filterclause fDataZapSQL+="%AF"; PDEBUGPRINTFX(DBG_EXOTIC,(" %s",fDataZapSQL.c_str())); } // Map table if (fMapFetchAllSQL.empty()) { // SELECT localid,remoteid FROM maptable WHERE targetkey=%t fMapFetchAllSQL="SELECT "; fMapFetchAllSQL+=fLocalIDMapField; fMapFetchAllSQL+=", "; fMapFetchAllSQL+=fRemoteIDMapField; fMapFetchAllSQL+=" FROM "; fMapFetchAllSQL+=fMapTableName; fMapFetchAllSQL+=" WHERE "; fMapFetchAllSQL+=fTargetKeyMapField; fMapFetchAllSQL+="="; quoteStringAppend("%t",fMapFetchAllSQL,fStringTargetkey ? qm_backslash : qm_none); PDEBUGPRINTFX(DBG_EXOTIC,(" %s",fMapFetchAllSQL.c_str())); } if (fMapInsertSQL.empty()) { // INSERT INTO maptable (targetkey,localid,remoteid) VALUES (%t,%k,%r) fMapInsertSQL="INSERT INTO "; fMapInsertSQL+=fMapTableName; fMapInsertSQL+=" ("; fMapInsertSQL+=fTargetKeyMapField; fMapInsertSQL+=", "; fMapInsertSQL+=fLocalIDMapField; fMapInsertSQL+=", "; fMapInsertSQL+=fRemoteIDMapField; fMapInsertSQL+=") VALUES ("; quoteStringAppend("%t",fMapInsertSQL,fStringTargetkey ? qm_backslash : qm_none); fMapInsertSQL+=", "; quoteStringAppend("%k",fMapInsertSQL,fStringLocalID ? qm_backslash : qm_none); fMapInsertSQL+=", '%r')"; PDEBUGPRINTFX(DBG_EXOTIC,(" %s",fMapInsertSQL.c_str())); } if (fMapUpdateSQL.empty()) { // UPDATE maptable SET remoteid=%r WHERE targetkey=%t AND localid=%k fMapUpdateSQL="UPDATE "; fMapUpdateSQL+=fMapTableName; fMapUpdateSQL+=" SET "; fMapUpdateSQL+=fRemoteIDMapField; fMapUpdateSQL+="='%r' WHERE "; // is always a string fMapUpdateSQL+=fTargetKeyMapField; fMapUpdateSQL+="="; quoteStringAppend("%t",fMapUpdateSQL,fStringTargetkey ? qm_backslash : qm_none); fMapUpdateSQL+=" AND "; fMapUpdateSQL+=fLocalIDMapField; fMapUpdateSQL+="="; quoteStringAppend("%k",fMapUpdateSQL,fStringLocalID ? qm_backslash : qm_none); PDEBUGPRINTFX(DBG_EXOTIC,(" %s",fMapUpdateSQL.c_str())); } if (fMapDeleteSQL.empty()) { // DELETE FROM maptable WHERE targetkey=%t AND localid=%k fMapDeleteSQL="DELETE FROM "; fMapDeleteSQL+=fMapTableName; fMapDeleteSQL+=" WHERE "; fMapDeleteSQL+=fTargetKeyMapField; fMapDeleteSQL+="="; quoteStringAppend("%t",fMapDeleteSQL,fStringTargetkey ? qm_backslash : qm_none); // up to here, this is a DELETE all for one target, so we // can use this to extend fDeleteSyncTargetSQL fDeleteSyncTargetSQL+=" %GO "; fDeleteSyncTargetSQL+=fMapDeleteSQL; // now add clause for single item fMapDeleteSQL+=" AND "; fMapDeleteSQL+=fLocalIDMapField; fMapDeleteSQL+="="; quoteStringAppend("%k",fMapDeleteSQL,fStringLocalID ? qm_backslash : qm_none); PDEBUGPRINTFX(DBG_EXOTIC,(" %s",fMapDeleteSQL.c_str())); } #endif } // resolve inherited inherited::localResolve(aLastPass); } // TOdbcDSConfig::localResolve #ifdef SCRIPT_SUPPORT void TOdbcDSConfig::apiResolveScripts(void) { // resolve scripts which are API specific (in SAME ORDER AS IN apiRebuildScriptContexts()!) TScriptContext::resolveScript(getSyncAppBase(),fLocalIDScript,fResolveContextP,NULL); } #endif // - create appropriate datastore from config, calls addTypeSupport as well TLocalEngineDS *TOdbcDSConfig::newLocalDataStore(TSyncSession *aSessionP) { // Synccap defaults to normal set supported by the engine by default TLocalEngineDS *ldsP; if (IS_CLIENT) { ldsP = new TODBCApiDS(this,aSessionP,getName(),aSessionP->getSyncCapMask() & ~(isOneWayFromRemoteSupported() ? 0 : SCAP_MASK_ONEWAY_SERVER)); } else { ldsP = new TODBCApiDS(this,aSessionP,getName(),aSessionP->getSyncCapMask() & ~(isOneWayFromRemoteSupported() ? 0 : SCAP_MASK_ONEWAY_CLIENT)); } // do common stuff addTypes(ldsP,aSessionP); // return return ldsP; } // TOdbcDSConfig::newLocalDataStore // Field Map item // ============== TODBCFieldMapItem::TODBCFieldMapItem(const char *aElementName, TConfigElement *aParentElement) : inherited(aElementName,aParentElement) { #ifdef STREAMFIELD_SUPPORT fReadBlobSQL.erase(); fKeyFieldName.erase(); #endif } // TODBCFieldMapItem::TODBCFieldMapItem void TODBCFieldMapItem::checkAttrs(const char **aAttributes) { #ifdef STREAMFIELD_SUPPORT AssignString(fReadBlobSQL,getAttr(aAttributes,"readblobsql")); AssignString(fKeyFieldName,getAttr(aAttributes,"keyfield")); #endif inherited::checkAttrs(aAttributes); } // TODBCFieldMapItem::checkAttrs #ifdef ARRAYDBTABLES_SUPPORT // array container // =============== TODBCFieldMapArrayItem::TODBCFieldMapArrayItem(TCustomDSConfig *aCustomDSConfigP, TConfigElement *aParentElement) : inherited(aCustomDSConfigP,aParentElement) { clear(); } // TODBCFieldMapArrayItem::TODBCFieldMapArrayItem TODBCFieldMapArrayItem::~TODBCFieldMapArrayItem() { // nop so far clear(); } // TODBCFieldMapArrayItem::~TODBCFieldMapArrayItem // init defaults void TODBCFieldMapArrayItem::clear(void) { // init defaults // - clear values fSelectArraySQL.erase(); fInsertElementSQL.erase(); fDeleteArraySQL.erase(); fAlwaysCleanArray=false; // clear inherited inherited::clear(); } // TODBCFieldMapArrayItem::clear // config element parsing bool TODBCFieldMapArrayItem::localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine) { if (strucmp(aElementName,"selectarraysql")==0) expectString(fSelectArraySQL); else if (strucmp(aElementName,"deletearraysql")==0) expectString(fDeleteArraySQL); else if (strucmp(aElementName,"insertelementsql")==0) expectString(fInsertElementSQL); else if (strucmp(aElementName,"alwaysclean")==0) expectBool(fAlwaysCleanArray); // - none known here else return inherited::localStartElement(aElementName,aAttributes,aLine); // ok return true; } // TODBCFieldMapArrayItem::localStartElement // resolve void TODBCFieldMapArrayItem::localResolve(bool aLastPass) { if (aLastPass) { // check for required settings // %%% tbd } // resolve inherited inherited::localResolve(aLastPass); } // TODBCFieldMapArrayItem::localResolve #endif // ARRAYDBTABLES_SUPPORT /* * Implementation of TODBCApiDS */ // constructor TODBCApiDS::TODBCApiDS( TOdbcDSConfig *aConfigP, sysync::TSyncSession *aSessionP, const char *aName, uInt32 aCommonSyncCapMask ) : inherited(aConfigP,aSessionP, aName, aCommonSyncCapMask) #ifdef ODBCAPI_SUPPORT ,fODBCConnectionHandle(SQL_NULL_HANDLE) // no connection yet ,fODBCReadStatement(SQL_NULL_HANDLE) // no active statements either ,fODBCWriteStatement(SQL_NULL_HANDLE) #ifdef SCRIPT_SUPPORT ,fODBCScriptStatement(SQL_NULL_HANDLE) #endif #endif // ODBCAPI_SUPPORT #ifdef SQLITE_SUPPORT ,fSQLiteP(NULL) ,fSQLiteStmtP(NULL) ,fStepRc(SQLITE_OK) #endif { // save pointer to config record fConfigP=aConfigP; // make a local copy of the typed agent pointer fAgentP=static_cast(fSessionP); // make a local copy of the typed agent config pointer fAgentConfigP = dynamic_cast( aSessionP->getRootConfig()->fAgentConfigP ); if (!fAgentConfigP) throw TSyncException(DEBUGTEXT("TODBCApiDS finds no AgentConfig","odds7")); // init other stuff fODBCAdminData=false; // not known yet if we'll get admin data (target, map) from ODBC or not // - SQLite support #ifdef SQLITE_SUPPORT fUseSQLite = !fConfigP->fSQLiteFileName.empty(); // if we have a SQLite file name, use it instead of ODBC #endif // clear rest InternalResetDataStore(); } // TODBCApiDS::TODBCApiDS TODBCApiDS::~TODBCApiDS() { InternalResetDataStore(); } // TODBCApiDS::~TODBCApiDS /// @brief called while agent is still fully ok, so we must clean up such that later call of destructor does NOT access agent any more void TODBCApiDS::announceAgentDestruction(void) { // reset myself InternalResetDataStore(); // make sure we don't access the agent any more engTerminateDatastore(); fAgentP = NULL; // call inherited inherited::announceAgentDestruction(); } // TODBCApiDS::announceAgentDestruction /// @brief called to reset datastore /// @note must be safe to be called multiple times and even after announceAgentDestruction() void TODBCApiDS::InternalResetDataStore(void) { #ifdef OBJECT_FILTERING fFilterExpressionTested=false; // not tested yet fFilterWorksOnDBLevel=true; // but assume it works #endif #ifdef SCRIPT_SUPPORT // no SQL filter in place yet fSQLFilter.erase(); #endif #ifdef SQLITE_SUPPORT // clean up SQLite if (fSQLiteP) { // stop it in case something is still running sqlite3_interrupt(fSQLiteP); // if we have a statement, finalize it if (fSQLiteStmtP) { // discard it sqlite3_finalize(fSQLiteStmtP); fSQLiteStmtP=NULL; } int sqrc = sqlite3_close(fSQLiteP); if (sqrc!=SQLITE_OK) { PDEBUGPRINTFX(DBG_ERROR,("Error closing SQLite data file: sqlite3_close() returns %d",sqrc)); } else { PDEBUGPRINTFX(DBG_DBAPI,("Closed SQLite data file")); } fSQLiteP=NULL; } #endif // Clear map table and sync set lists if (fAgentP) { #ifdef ODBCAPI_SUPPORT // no active statements any more if (fODBCReadStatement) { SafeSQLFreeHandle(SQL_HANDLE_STMT,fODBCReadStatement); fODBCReadStatement=SQL_NULL_HANDLE; } if (fODBCWriteStatement) { SafeSQLFreeHandle(SQL_HANDLE_STMT,fODBCWriteStatement); fODBCWriteStatement=SQL_NULL_HANDLE; } // make sure connection is closed (and open transaction rolled back) fAgentP->closeODBCConnection(fODBCConnectionHandle); #endif // ODBCAPI_SUPPORT // clear parameter maps resetSQLParameterMaps(); } } // TODBCApiDS::InternalResetDataStore #ifdef SCRIPT_SUPPORT // called to rebuild script context for API level scripts in the datastore context // Note: rebuild order must be SAME AS resolve order in apiResolveScripts() void TODBCApiDS::apiRebuildScriptContexts(void) { // local ID generation script TScriptContext::rebuildContext(fSessionP->getSyncAppBase(),fConfigP->fLocalIDScript,fScriptContextP,fSessionP); } // TODBCApiDS::apiRebuildScriptContexts #endif #ifdef ODBCAPI_SUPPORT // - get (DB level) ODBC handle SQLHDBC TODBCApiDS::getODBCConnectionHandle(void) { if (fODBCConnectionHandle==SQL_NULL_HANDLE && fAgentP) { // get a handle PDEBUGPRINTFX(DBG_DBAPI+DBG_EXOTIC,("Datastore %s does not own a DB connection yet -> pulling connection from session level",getName())); fODBCConnectionHandle = fAgentP->pullODBCConnectionHandle(); } PDEBUGPRINTFX(DBG_DBAPI+DBG_EXOTIC,("Datastore %s: using connection handle 0x%lX",getName(),(uIntArch)fODBCConnectionHandle)); return fODBCConnectionHandle; } // TODBCApiDS::getODBCConnectionHandle // - check for connection-level error void TODBCApiDS::checkConnectionError(SQLRETURN aResult) { if (!fAgentP) return; if (fODBCConnectionHandle!=SQL_NULL_HANDLE) { // check on local connection fAgentP->checkODBCError(aResult,SQL_HANDLE_DBC,fODBCConnectionHandle); } // check on session level fAgentP->checkConnectionError(aResult); } // TODBCApiDS::checkConnectionError #endif // ODBCAPI_SUPPORT // helper for mapping field names bool TODBCApiDS::addFieldNameList(string &aSQL, bool aForWrite, bool aForUpdate, bool aAssignedOnly, TMultiFieldItem *aItemP, TFieldMapList &fml, uInt16 aSetNo, char aFirstSep) { TFieldMapList::iterator pos; TODBCFieldMapItem *fmiP; bool doit; bool allfields=true; // all fields listed (no array fields) for (pos=fml.begin(); pos!=fml.end(); pos++) { fmiP = (TODBCFieldMapItem *)*pos; if (!fmiP->isArray()) { doit= aSetNo==fmiP->setNo && (aForWrite ? (fmiP->writable && ((aForUpdate && fmiP->for_update) || (!aForUpdate && fmiP->for_insert))) : fmiP->readable #ifdef STREAMFIELD_SUPPORT && (fmiP->fReadBlobSQL.empty() || !fmiP->fKeyFieldName.empty()) // only read fields here that don't use a proxy or read a key FOR the proxy #endif ); if (doit && aAssignedOnly && aForWrite && aItemP) { // check base field is assigned // This should cover all cases (remember that MimeDirItem assigns empty values // to all "available" fields before parsing data) // - array fields are "assigned" if they have an element assigned or // been called assignEmpty() // - field blocks addressed by repeating properties will either be assigned all // or not at all, so we can safely check base field ID only // - negative FIDs except VARIDX_UNDEFINED address local vars, which // should be assigned only if they may also be written TItemField *fieldP=getMappedFieldOrVar(*aItemP,fmiP->fid,0,true); // existing only if (!fieldP || !(fieldP->isAssigned())) doit=false; // avoid writing unassigned or non-existing (array) fields } if (doit) { // add comma if (aFirstSep) { aSQL+=aFirstSep; aSQL+=' '; } aFirstSep=','; // further names are always comma separated #ifdef STREAMFIELD_SUPPORT if (fmiP->readable && !aForWrite && !fmiP->fKeyFieldName.empty()) { // the actual field contents will be read via proxy, but we read the record key here instead aSQL+=fmiP->fKeyFieldName; } else #endif { // just add field name aSQL+=fmiP->fElementName; } } } else allfields=false; // at least one array field } return allfields; } // TODBCApiDS::addFieldNameList // helper for mapping field values // - returns aNoData=true if there is no field (e.g. array index too high) for any of the values // - returns false if not all fields could be listed (i.e. there are array fields) bool TODBCApiDS::addFieldNameValueList(string &aSQL, bool aAssignedOnly, bool &aNoData, bool &aAllEmpty, TMultiFieldItem &aItem ,bool aForUpdate, TFieldMapList &fml, uInt16 aSetNo, sInt16 aRepOffset, char aFirstSep) { TFieldMapList::iterator pos; TODBCFieldMapItem *fmiP; bool allfields=true; bool doit; aNoData = true; // assume no data aAllEmpty = true; // assume empty fields only for (pos=fml.begin(); pos!=fml.end(); pos++) { fmiP = (TODBCFieldMapItem *)*pos; if (fmiP->isArray()) { allfields=false; // at least one array field } else if (aSetNo==fmiP->setNo && fmiP->writable && ((aForUpdate && fmiP->for_update) || (!aForUpdate && fmiP->for_insert)) ) { doit=true; if (aAssignedOnly) { // check base field is assigned (see notes in addFieldNameList()) TItemField *fieldP=getMappedFieldOrVar(aItem,fmiP->fid,0,true); // get existing fields only (for arrays) if (!fieldP || !(fieldP->isAssigned())) doit=false; // avoid writing unassigned fields } if (doit) { // add comma if (aFirstSep) { aSQL+=aFirstSep; aSQL+=' '; } aFirstSep=','; // further names are always comma separated // add field name and equal sign if for update if (aForUpdate) { // add field name aSQL+=fmiP->fElementName; aSQL+='='; } // check how to add field value if (fmiP->as_param || fmiP->dbfieldtype==dbft_blob) { // either explicitly marked as param or BLOB: pass value as in-param addSQLParameterMap(true,false,param_field,fmiP,&aItem,aRepOffset); // in-param // add parameter placeholder into SQL aSQL+='?'; } else { // add field value as literal // - get base field sInt16 fid=fmiP->fid; if (fid==VARIDX_UNDEFINED) return false; // field does not exist #ifndef SCRIPT_SUPPORT // check index before using it (should not be required, as map indices are resolved if (!aItem.getItemType()->isFieldIndexValid(fid)) return false; // field does not exist #endif if (appendFieldsLiteral(aItem,fid,aRepOffset,*fmiP,aSQL)) aAllEmpty=false; } } } } aNoData=false; // data for all non-array fields found return allfields; } // TODBCApiDS::addFieldNameValueList // helper for filling ODBC results into mapped fields // - if mapped field is an array, aRepOffset will be used as array index // - if mapped field is not an array, aRepOffset will be added to the base fid void TODBCApiDS::fillFieldsFromSQLResult(SQLHSTMT aStatement, sInt16 &aColIndex, TMultiFieldItem &aItem, TFieldMapList &fml, uInt16 aSetNo, sInt16 aRepOffset) { sInt16 fid; TFieldMapList::iterator pos; TODBCFieldMapItem *fmiP; bool notnull=false; // default to empty // get data for all mapped fields for (pos=fml.begin(); pos!=fml.end(); pos++) { fmiP = (TODBCFieldMapItem *)*pos; try { if ( !fmiP->isArray() && aSetNo==fmiP->setNo && fmiP->readable ) { // was specified in SELECT, so we can read it if ((fid=fmiP->fid)!=VARIDX_UNDEFINED) { TItemField *fieldP; TDBFieldType dbfty = fmiP->dbfieldtype; // single field mapping fieldP=getMappedFieldOrVar(aItem,fid,aRepOffset); if (fieldP) { #ifdef STREAMFIELD_SUPPORT if (!fmiP->fReadBlobSQL.empty()) { // retrieve key for this field if map specifies a "keyfield" string key; #ifdef SQLITE_SUPPORT // - always for data access if (fUseSQLite) { if (!fmiP->fKeyFieldName.empty()) { key = (const char *)sqlite3_column_text(fSQLiteStmtP,aColIndex-1); // read something, next column aColIndex++; } } else #endif { #ifdef ODBCAPI_SUPPORT if (!fmiP->fKeyFieldName.empty()) { fAgentP->getColumnValueAsString(aStatement,aColIndex,key,chs_ascii); // read something, next column aColIndex++; } #endif // ODBCAPI_SUPPORT } // use proxy for this field if (!fieldP->isBasedOn(fty_string)) { throw TSyncException(" allowed for string or BLOB fields only!"); } // create and install a proxy for this field PDEBUGPRINTFX(DBG_DBAPI+DBG_EXOTIC,( "Installed proxy for '%s' to retrieve data later when needed. MasterKey='%s', 'DetailKey='%s'", fmiP->getName(), aItem.getLocalID(), key.c_str() )); TODBCFieldProxy *odbcProxyP = new TODBCFieldProxy(this,fmiP,aItem.getLocalID(),key.c_str()); // attach it to the string or blob field static_cast(fieldP)->setBlobProxy(odbcProxyP); } else #endif // STREAMFIELD_SUPPORT { // Note: this will also select fields that may not // be available for the current remote party, but these // will be suppressed by the TMultiFieldItemType descendant. // As different items COULD theoretically use different // formats, filtering here already would be complicated. // so we live with reading probably more fields than really // needed. #ifdef SQLITE_SUPPORT // - always for data access if (fUseSQLite) { // SQLite notnull = fAgentP->getSQLiteColValueAsField( fSQLiteStmtP, // local sqlite statement aColIndex-1, // SQLITE colindex starts at 0, not 1 like in ODBC dbfty, fieldP, fConfigP->fDataCharSet, fmiP->floating_ts ? TCTX_UNKNOWN : fConfigP->fDataTimeZone, fConfigP->fUserZoneOutput ); } else #endif { #ifdef ODBCAPI_SUPPORT // ODBC notnull=fAgentP->getColumnValueAsField( aStatement, aColIndex, dbfty, fieldP, fConfigP->fDataCharSet, // real charset, including UTF16 fmiP->floating_ts ? TCTX_UNKNOWN : fConfigP->fDataTimeZone, fConfigP->fUserZoneOutput ); #endif // ODBCAPI_SUPPORT } // next column aColIndex++; } } // if field available else { // this can happen with array maps mapping to field blocks with a too high fMaxRepeat // it should not happen with array fields. throw TSyncException(DEBUGTEXT("FATAL: Field in map not found in item","odds6")); } } // if fid specified else { // no field mapped, skip column aColIndex++; } } // if readable, not array and correct set number (and thus SELECTed) field } catch (exception &e) { PDEBUGPRINTFX(DBG_ERROR,( "fillFieldsFromSQLResult field='%s', colindex=%hd, fid=%hd%s, setno=%hd, dbfty=%s,failed: %s", fmiP->fElementName.c_str(), aColIndex, fmiP->fid, fmiP->isArray() ? " (array)" : "", fmiP->setNo, DBFieldTypeNames[fmiP->dbfieldtype], e.what() )); throw; } } // field loop } // TODBCApiDS::fillFieldsFromSQLResult #ifdef ARRAYDBTABLES_SUPPORT // read an array field // NOTE: non-array fields are already read when this is called void TODBCApiDS::readArray(SQLHSTMT aStatement, TMultiFieldItem &aItem, TFieldMapArrayItem *aMapItemP) { string sql; sInt16 colindex,i; uInt16 setno; TODBCFieldMapArrayItem *fmaiP = dynamic_cast(aMapItemP); if (!fmaiP) return; // do nothing #ifdef SCRIPT_SUPPORT // process init script fArrIdx=0; // start at array index=0 fParentKey=aItem.getLocalID(); fWriting=false; fInserting=false; fDeleting=false; fAgentP->fScriptContextDatastore=this; if (!TScriptContext::executeTest( true, // read array if script returns nothing or no script present fScriptContextP, // context fmaiP->fInitScript, // the script fConfigP->getDSFuncTableP(),fAgentP, // funcdefs/context &aItem,true // target item, writeable )) { // prevented array reading by script returning false return; // do nothing for this array } #else fArrIdx=0; // start at array index=0 #endif // SCRIPT_SUPPORT // process SQL statement(s) i=0; while (getNextSQLStatement(fmaiP->fSelectArraySQL,i,sql,setno)) { // Apply substitutions resetSQLParameterMaps(); DoDataSubstitutions(sql,fmaiP->fArrayFieldMapList,setno,false,false,&aItem,fArrIdx*fmaiP->fRepeatInc); prepareSQLStatement(aStatement, sql.c_str(),true,"reading array"); // - prepare parameters bindSQLParameters(aStatement,true); // Execute try { execSQLStatement(aStatement,sql,true,NULL,true); } catch (exception &e) { PDEBUGPRINTFX(DBG_DATA+DBG_DBAPI,( "readarray:execSQLStatement sql='%s' failed: %s", sql.c_str(), e.what() )); throw; } // get out params saveAndCleanupSQLParameters(aStatement,true); // Fetch // - fetch result(s) now, at most fMaxRepeat while (fmaiP->fMaxRepeat==0 || fArrIdxfMaxRepeat) { colindex=1; // ODBC style, fillFieldsFromSQLResult will adjust for SQLite if needed if (!fetchNextRow(aStatement,true)) break; // all available rows fetched // now fill data into array's mapped fields (array fields or field blocks) fillFieldsFromSQLResult(aStatement,colindex,aItem,fmaiP->fArrayFieldMapList,setno,fArrIdx*fmaiP->fRepeatInc); #ifdef SCRIPT_SUPPORT // process afterread script fAgentP->fScriptContextDatastore=this; if (!TScriptContext::execute(fScriptContextP,fmaiP->fAfterReadScript,fConfigP->getDSFuncTableP(),fAgentP,&aItem,true)) throw TSyncException(" failed"); #endif // increment array index/count fArrIdx++; } // no more records finalizeSQLStatement(aStatement,true); // save size of array in "sizefrom" field (if it's not an array) TItemField *fldP = getMappedBaseFieldOrVar(aItem,fmaiP->fid); if (fldP && !fldP->isArray()) fldP->setAsInteger(fArrIdx); // make pass filter if there are no items in the array #ifdef OBJECT_FILTERING if (fArrIdx==0) aItem.makePassFilter(fmaiP->fNoItemsFilter.c_str()); // item is made pass filter, if possible #endif #ifdef SCRIPT_SUPPORT // process finish script, can perform more elaborated stuff that makePassFilter can fAgentP->fScriptContextDatastore=this; if (!TScriptContext::execute(fScriptContextP,fmaiP->fFinishScript,fConfigP->getDSFuncTableP(),fAgentP,&aItem,true)) throw TSyncException(" failed"); #endif } } // TODBCApiDS::readArray // write or delete an array field // NOTE: non-array fields are already written when this is called void TODBCApiDS::writeArray(bool aDelete, bool aInsert, SQLHSTMT aStatement, TMultiFieldItem &aItem, TFieldMapArrayItem *aMapItemP) { string sql; sInt16 i; uInt16 setno; bool done, allempty; TODBCFieldMapArrayItem *fmaiP = dynamic_cast(aMapItemP); PDEBUGPRINTFX(DBG_DATA+DBG_DBAPI+DBG_EXOTIC,("Writing Array, fmaiP=0x%lX",(long)fmaiP)); if (!fmaiP) return; // do nothing PDEBUGPRINTFX(DBG_DATA+DBG_DBAPI+DBG_EXOTIC,("Writing Array")); // Check initscript first. If it returns false, we do not insert anything bool doit; #ifdef SCRIPT_SUPPORT // process init script fArrIdx=0; // start at array index=0 fParentKey=aItem.getLocalID(); fWriting=true; fInserting=aInsert; fDeleting=aDelete; fAgentP->fScriptContextDatastore=this; doit = TScriptContext::executeTest( true, // write array if script returns nothing or no script present fScriptContextP, // context fmaiP->fInitScript, // the script &ODBCDSFuncTable1,fAgentP, // funcdefs/context &aItem,true // target item, writeable ); #else doit=true; // no script, always do it fArrIdx=0; // start at array index=0 #endif // SCRIPT_SUPPORT PDEBUGPRINTFX(DBG_DATA+DBG_DBAPI+DBG_EXOTIC,("Writing Array: doit=%d, aDelete=%d, aInsert=%d",(int) doit,(int) aDelete,(int) aInsert)); // check if we need delete first if (doit && aDelete) { i=0; while (getNextSQLStatement(fmaiP->fDeleteArraySQL,i,sql,setno)) { // apply data substitutions resetSQLParameterMaps(); DoDataSubstitutions(sql,fmaiP->fArrayFieldMapList,setno,true,false,&aItem,0); // - prepare parameters prepareSQLStatement(aStatement, sql.c_str(),true,"array erase"); bindSQLParameters(aStatement,true); // issue execSQLStatement(aStatement,sql,true,NULL,true); // get out params saveAndCleanupSQLParameters(aStatement,true); // done finalizeSQLStatement(aStatement,true); } } // check if we need to insert the array elements doit=doit && aInsert; #ifdef OBJECT_FILTERING if (doit) { // test filter doit = fmaiP->fNoItemsFilter.empty() || // no filter, always generate !aItem.testFilter(fmaiP->fNoItemsFilter.c_str()); // if item passes filter, array should not be written } #endif if (doit) { // do array write sInt32 numElements=0; // unlimited to begin with // - see if we have a sizefrom field TItemField *fldP = getMappedBaseFieldOrVar(aItem,fmaiP->fid); if (fldP) { if (fldP->isArray()) numElements=fldP->arraySize(); // number of detail records to write is size of this array else numElements=fldP->getAsInteger(); // number of detail records to write are specified in integer variable } else { // entire array (=up to INSERT statement that would contain only empty fields) // Note: we cannot use the size of a single array field, as there might be // more than one with different sizes. End of array is when // DoDataSubstitutions() returns allempty==true numElements=REP_ARRAY; // this is a big number } // - limit to maxrepeat if (fmaiP->fMaxRepeat!=0 && numElements>fmaiP->fMaxRepeat) numElements=fmaiP->fMaxRepeat; // - now write #ifdef SCRIPT_SUPPORT fDeleting=false; // no longer deleting records #endif while (fArrIdxfScriptContextDatastore=this; if (!TScriptContext::executeTest(true,fScriptContextP,fmaiP->fBeforeWriteScript,fConfigP->getDSFuncTableP(),fAgentP,&aItem,true)) goto endarray; #endif // perform insert statement(s) i=0; bool firststatement=true; while (getNextSQLStatement(fmaiP->fInsertElementSQL,i,sql,setno)) { // do substitutions and find out if empty resetSQLParameterMaps(); DoDataSubstitutions(sql,fmaiP->fArrayFieldMapList,setno,true,false,&aItem,fArrIdx*fmaiP->fRepeatInc,&allempty,&done); // stop here if FIRST STATEMENT in (unlimited) array insert is all empty if (firststatement && fmaiP->fMaxRepeat==0 && allempty) goto endarray; // store if not empty or empty storage allowed if (fmaiP->fStoreEmpty || !allempty) { // - prepare parameters prepareSQLStatement(aStatement, sql.c_str(),true,"array element insert"); bindSQLParameters(aStatement,true); // issue execSQLStatement(aStatement,sql,false,NULL,true); // get out params saveAndCleanupSQLParameters(aStatement,true); // no more records finalizeSQLStatement(aStatement,true); } firststatement=false; } #ifdef SCRIPT_SUPPORT // process afterwrite script, end of array if it returns false fAgentP->fScriptContextDatastore=this; if (!TScriptContext::executeTest(true,fScriptContextP,fmaiP->fAfterWriteScript,fConfigP->getDSFuncTableP(),fAgentP,&aItem,true)) goto endarray; #endif // next fArrIdx++; } // while endarray: #ifdef SCRIPT_SUPPORT // process finish script fAgentP->fScriptContextDatastore=this; if (!TScriptContext::execute(fScriptContextP,fmaiP->fFinishScript,fConfigP->getDSFuncTableP(),fAgentP,&aItem,true)) throw TSyncException(" failed"); #endif ; } } // TODBCApiDS::writeArray // read array fields. // - if aStatement is passed NULL, routine will allocate/destroy its // own statement for reading the array fields void TODBCApiDS::readArrayFields(SQLHSTMT aStatement, TMultiFieldItem &aItem, TFieldMapList &fml) { TFieldMapList::iterator pos; // get data for all array table fields for (pos=fml.begin(); pos!=fml.end(); pos++) { if ((*pos)->isArray()) { readArray(aStatement,aItem,(TFieldMapArrayItem *)*pos); } } } // TODBCApiDS::readArrayFields void TODBCApiDS::writeArrayFields(SQLHSTMT aStatement, TMultiFieldItem &aItem, TFieldMapList &fml, bool aInsert) { TFieldMapList::iterator pos; // write all array table fields for (pos=fml.begin(); pos!=fml.end(); pos++) { if ((*pos)->isArray()) { // delete first, then insert writeArray(!aInsert || static_cast(*pos)->fAlwaysCleanArray,true,aStatement,aItem,(TFieldMapArrayItem *)*pos); } } } // TODBCApiDS::writeArrayFields void TODBCApiDS::deleteArrayFields(SQLHSTMT aStatement, TMultiFieldItem &aItem, TFieldMapList &fml) { TFieldMapList::iterator pos; // delete all array table fields for (pos=fml.begin(); pos!=fml.end(); pos++) { if ((*pos)->isArray()) { // only delete, no insert writeArray(true,false,aStatement,aItem,(TFieldMapArrayItem *)*pos); } } } // TODBCApiDS::deleteArrayFields #endif // ARRAYDBTABLES_SUPPORT // append field value(s) as single literal to SQL text // - returns true if field(s) were not empty // - even non-existing or empty field will append at least NULL or '' to SQL bool TODBCApiDS::appendFieldsLiteral(TMultiFieldItem &aItem, sInt16 aFid, sInt16 aRepOffset,TODBCFieldMapItem &aFieldMapping, string &aSQL) { string val; bool notempty=false; TItemField *fieldP; // get mapped item field or local script variable fieldP=getMappedFieldOrVar(aItem,aFid,aRepOffset,true); // existing (array fields) only // now process single field if (!fieldP) goto novalue; // no data -> empty notempty=appendFieldValueLiteral(*fieldP, aFieldMapping.dbfieldtype, aFieldMapping.maxsize, aFieldMapping.floating_ts, aSQL); return notempty; novalue: // no value was produced aSQL+="NULL"; return false; } // TODBCApiDS::appendFieldsLiteral // append field value as literal to SQL text // - returns true if field(s) were not empty // - even non-existing or empty field will append at least NULL or '' to SQL bool TODBCApiDS::appendFieldValueLiteral(TItemField &aField,TDBFieldType aDBFieldType, uInt32 aMaxSize, bool aIsFloating, string &aSQL) { return fAgentP->appendFieldValueLiteral( aField, aDBFieldType, aMaxSize, aSQL, fConfigP->sqlPrepCharSet(), fConfigP->fDataLineEndMode, fConfigP->fQuotingMode, aIsFloating ? TCTX_UNKNOWN : fConfigP->fDataTimeZone, fRecordSize ); } // TODBCApiDS::appendFieldValueLiteral // issue single (or multiple) data update statements // NOTE: returns false if no rows affected. If no information about rows affected // is found, returns false if all statements return SQL_NODATA. // If config fIgnoreAffectedCount is set, always returns true (unless we have an error). bool TODBCApiDS::IssueDataWriteSQL( SQLHSTMT aStatement, const string &aSQL, const char *aComment, bool aForUpdate, TFieldMapList &aFieldMapList, // field map list for %N,%V and %v TMultiFieldItem *aItemP // item to read values and localid from ) { uInt16 setno=0; // default to 0 string sql; bool d,hasdata=false; SQLLEN affectedRows,totalAffected=-1; sInt16 i=0; // add field values fRecordSize=0; // reset count, appendFieldValueLiteral will update size while (getNextSQLStatement(aSQL,i,sql,setno)) { // - do substitutions resetSQLParameterMaps(); PDEBUGPRINTFX(DBG_DBAPI+DBG_EXOTIC,("SQL before substitutions: %s",aSQL.c_str())); DoDataSubstitutions( sql, // string to apply substitutions to aFieldMapList, // field map list for %N,%V and %v setno, // set number true, // for write aForUpdate, // for update? aItemP // item to read values and localid from ); // - prepare parameters prepareSQLStatement(aStatement, sql.c_str(),true,aComment); bindSQLParameters(aStatement,true); // - execute it d = execSQLStatement(aStatement,sql,true,NULL,true); // - get number of affected rows #ifdef SQLITE_SUPPORT if (fUseSQLite) { affectedRows = sqlite3_changes(fSQLiteP); } else #endif { #ifdef ODBCAPI_SUPPORT SQLRETURN res = SQLRowCount(aStatement,&affectedRows); if (res!=SQL_SUCCESS && res!=SQL_SUCCESS_WITH_INFO) affectedRows = -1; // unknown #else affectedRows=0; // no API, no rows affected #endif } // - count affected rows if (totalAffected<0) totalAffected = affectedRows; else if (affectedRows>0) totalAffected += affectedRows; PDEBUGPRINTFX(DBG_DBAPI+DBG_EXOTIC,("IssueDataWriteSQL: Statement reports %ld affected rows - totalAffected=%ld",affectedRows,totalAffected)); // get out params saveAndCleanupSQLParameters(aStatement,true); // done with statement finalizeSQLStatement(aStatement,true); hasdata = hasdata || d; } if (fConfigP->fIgnoreAffectedCount) return true; // assume always successful else if (totalAffected<0) return hasdata; // no reliable info about affected rows - use hasdata instead else return totalAffected>0; // assume modified something if any row was affected } // TODBCApiDS::IssueDataWriteSQL #ifdef HAS_SQL_ADMIN // issue single (or multiple) map access statements // NOTE: if all return SQL_NODATA, function will return false. bool TODBCApiDS::IssueMapSQL( SQLHSTMT aStatement, const string &aSQL, const char *aComment, TMapEntryType aEntryType, const char *aLocalID, const char *aRemoteID, uInt32 aMapFlags ) { uInt16 setno=0; // default to 0 string sql; bool d,hasdata=false; sInt16 i=0; while (getNextSQLStatement(aSQL,i,sql,setno)) { // - do substitutions DoMapSubstitutions(sql,aEntryType,aLocalID,aRemoteID,aMapFlags); // - execute it d = execSQLStatement(aStatement,sql,true,aComment,false); hasdata = hasdata || d; } return hasdata; } // TODBCApiDS::IssueMapSQL #endif // HAS_SQL_ADMIN // execute SQL statement as-is, without any substitutions bool TODBCApiDS::execSQLStatement(SQLHSTMT aStatement, string &aSQL, bool aNoDataAllowed, const char *aComment, bool aForData) { #ifdef ODBCAPI_SUPPORT SQLRETURN res; #endif // show what statement will be executed #ifdef SYDEBUG if (aComment && PDEBUGTEST(DBG_DBAPI)) { PDEBUGPRINTFX(DBG_DBAPI,("SQL for %s:",aComment)); PDEBUGPUTSX(DBG_DBAPI,aSQL.c_str()); } #endif // avoid executing empty statement if (aSQL.empty()) return true; // "ok", nothing to execute #ifdef SQLITE_SUPPORT if (fUseSQLite && aForData) { // execute (possibly already prepared) statement in SQLite if (!fSQLiteStmtP) { // not yet prepared, do it now fAgentP->prepareSQLiteStatement(aSQL.c_str(),fSQLiteP,fSQLiteStmtP); } // do first step fStepRc = sqlite3_step(fSQLiteStmtP); // clean up right now if we don't have data if (fStepRc!=SQLITE_ROW) { fStepRc=sqlite3_finalize(fSQLiteStmtP); fSQLiteStmtP=NULL; fAgentP->checkSQLiteError(fStepRc,fSQLiteP); } // check if we MUST have data here if (!aNoDataAllowed) { if (fStepRc!=SQLITE_ROW) { // we're not happy because we have no data return false; } } return true; // ok } #endif { #ifdef ODBCAPI_SUPPORT // execute statement TP_DEFIDX(li); TP_SWITCH(li,fSessionP->fTPInfo,TP_database); #ifdef ODBC_UNICODE if (fConfigP->fDataCharSet==chs_utf16) { // aSQL is UTF-8 here // make UCS2 string to pass to wide char API string wSQL; appendUTF8ToUTF16ByteString(aSQL.c_str(), wSQL, ODBC_BIGENDIAN); wSQL += (char)0; // together with the implicit 8-bit NUL terminator, this makes a 16-bit NUL terminator // execute it with the "W" version res = SafeSQLExecDirectW( aStatement, (SQLWCHAR *)wSQL.c_str(), wSQL.size()/2 // actual number of Unicode chars ); } else #endif // ODBC_UNICODE { res = SafeSQLExecDirect( aStatement, (SQLCHAR *)aSQL.c_str(), aSQL.size() ); } TP_START(fSessionP->fTPInfo,li); // check if (aNoDataAllowed) return fAgentP->checkStatementHasData(res,aStatement); else { fAgentP->checkStatementError(res,aStatement); return true; } #endif // ODBCAPI_SUPPORT } // should never happen return false; } // TODBCApiDS::execSQLStatement // get next statment from statement list // - may begin with %GO(setno) bool TODBCApiDS::getNextSQLStatement(const string &aSQL, sInt16 &aStartAt, string &aOneSQL, uInt16 &aSetNo) { aSetNo=0; // default to set 0 string::size_type e; bool foundone=false; sInt32 n=aSQL.size(); // check for %GO while (aStartAtstring::size_type(aStartAt)) { // Not-empty statement aOneSQL.assign(aSQL,aStartAt,e-aStartAt); // Next statement starts here aStartAt=e; // statement found foundone=true; break; } } // while more in input and empty statement return foundone; } // TODBCApiDS::getNextSQLStatement // inform logic of coming state change localstatus TODBCApiDS::dsBeforeStateChange(TLocalEngineDSState aOldState,TLocalEngineDSState aNewState) { // let inherited do its stuff as well return inherited::dsBeforeStateChange(aOldState,aNewState); } // TODBCApiDS::dsBeforeStateChange // inform logic of happened state change localstatus TODBCApiDS::dsAfterStateChange(TLocalEngineDSState aOldState,TLocalEngineDSState aNewState) { // let inherited do its stuff as well return inherited::dsAfterStateChange(aOldState,aNewState); } // TODBCApiDS::dsAfterStateChange #ifdef ODBCAPI_SUPPORT // Routine mapping #define lineartimeToLiteralAppend lineartimeToODBCLiteralAppend #endif // ODBCAPI_SUPPORT #ifdef HAS_SQL_ADMIN // log datastore sync result // - Called at end of sync with this datastore void TODBCApiDS::dsLogSyncResult(void) { uInt16 setno=0; // default to 0 string sql; sInt16 i=0; // if we have a SQL statement and logging of this session is enabled, log if (fSessionP->logEnabled() && !fAgentConfigP->fWriteLogSQL.empty()) { // execute SQL statement for logging try { SQLHSTMT statement=fAgentP->newStatementHandle(getODBCConnectionHandle()); try { while (getNextSQLStatement(fAgentConfigP->fWriteLogSQL,i,sql,setno)) { // - do substitutions DoLogSubstitutions(sql,false); execSQLStatement(statement,sql,true,"Log Entry Write",false); finalizeSQLStatement(statement,false); } // release the statement handle SafeSQLFreeHandle(SQL_HANDLE_STMT,statement); // commit the transaction (this is called AFTER the data transactions probably have been // rolled back in EndDataWrite SafeSQLEndTran(SQL_HANDLE_DBC,getODBCConnectionHandle(),SQL_COMMIT); } catch (exception &e) { // release the statement handle SafeSQLFreeHandle(SQL_HANDLE_STMT,statement); throw; } } catch (exception &e) { // release the statement handle PDEBUGPRINTFX(DBG_ERROR,("Failed to issue Log SQL statement: %s",e.what())); } } // let ancestor process TStdLogicDS::dsLogSyncResult(); } // TODBCApiDS::dsLogSyncResult // Do logfile SQL/plaintext substitutions void TODBCApiDS::DoLogSubstitutions(string &aLog,bool aPlaintext) { string s; size_t i; // logging if (!aPlaintext) { // only for SQL text // Note: we need to do free form strings here to ensure correct DB string escaping // %rD Datastore remote path StringSubst(aLog,"%rD",getRemoteDBPath(),3,chs_ascii,lem_cstr,fConfigP->fQuotingMode); // %nR Remote name: [Manufacturer ]Model") StringSubst(aLog,"%nR",fSessionP->getRemoteDescName(),3,chs_ascii,lem_cstr,fConfigP->fQuotingMode); // %vR Remote Device Version Info ("Type (HWV, FWV, SWV) Oem") StringSubst(aLog,"%vR",fSessionP->getRemoteInfoString(),3,chs_ascii,lem_cstr,fConfigP->fQuotingMode); // %U User Name StringSubst(aLog,"%U",fSessionP->getSyncUserName(),2,chs_ascii,lem_cstr,fConfigP->fQuotingMode); // %lD Datastore local path (complete with all CGI) StringSubst(aLog,"%lD",getRemoteViewOfLocalURI(),3,chs_ascii,lem_cstr,fConfigP->fQuotingMode); // %iR Remote Device ID (URI) StringSubst(aLog,"%iR",fSessionP->getRemoteURI(),3,chs_ascii,lem_cstr,fConfigP->fQuotingMode); // %dT Sync date i=0; while((i=aLog.find("%dT",i))!=string::npos) { s.erase(); fAgentP->lineartimeToLiteralAppend(fCurrentSyncTime, s, true, false, TCTX_UTC, fConfigP->fDataTimeZone); aLog.replace(i,3,s); i+=s.size(); } // %tT Sync time i=0; while((i=aLog.find("%tT",i))!=string::npos) { s.erase(); fAgentP->lineartimeToLiteralAppend(fCurrentSyncTime, s, false, true, TCTX_UTC, fConfigP->fDataTimeZone); aLog.replace(i,3,s); i+=s.size(); } // %T Sync timestamp i=0; while((i=aLog.find("%T",i))!=string::npos) { s.erase(); fAgentP->lineartimeToLiteralAppend(fCurrentSyncTime, s, true, true, TCTX_UTC, fConfigP->fDataTimeZone); aLog.replace(i,2,s); i+=s.size(); } // %ssT Sync start time timestamp i=0; while((i=aLog.find("%ssT",i))!=string::npos) { s.erase(); fAgentP->lineartimeToLiteralAppend(fSessionP->getSessionStarted(), s, true, true, TCTX_UTC, fConfigP->fDataTimeZone); aLog.replace(i,4,s); i+=s.size(); } // %seT Sync end time timestamp i=0; while((i=aLog.find("%seT",i))!=string::npos) { s.erase(); fAgentP->lineartimeToLiteralAppend(getEndOfSyncTime(), s, true, true, TCTX_UTC, fConfigP->fDataTimeZone); aLog.replace(i,4,s); i+=s.size(); } } // - let ancestor process its own substitutions TStdLogicDS::DoLogSubstitutions(aLog,aPlaintext); // %t Target Key // %f Folder Key // %u User key // %d device key // - let standard SQL substitution handle this DoSQLSubstitutions(aLog); } // TODBCApiDS::DoLogSubstitutions // do substitutions for map table access void TODBCApiDS::DoMapSubstitutions( string &aSQL, // string to apply substitutions to TMapEntryType aEntryType, // the entry type const char *aLocalID, // local ID const char *aRemoteID, // remote ID uInt32 aMapFlags // map flags ) { // can be empty, but we don't do NULLs if (!aLocalID) aLocalID=""; if (!aRemoteID) aRemoteID=""; // %k = data key (local ID) StringSubst(aSQL,"%k",aLocalID,2,-1,fConfigP->sqlPrepCharSet(),fConfigP->fDataLineEndMode,fConfigP->fQuotingMode); // %r = remote ID (always a string) StringSubst(aSQL,"%r",aRemoteID,2,-1,fConfigP->sqlPrepCharSet(),fConfigP->fDataLineEndMode,fConfigP->fQuotingMode); // %x = flags (a uInt32) StringSubst(aSQL,"%x",(sInt32)aMapFlags,2); // %e = entry type (a small number, uInt8 is enough) StringSubst(aSQL,"%e",(sInt32)aEntryType,2); // now substitute standard: %f=folderkey, %u=userkey, %t=targetkey DoSQLSubstitutions(aSQL); } // TODBCApiDS::DoMapSubstitutions #endif // HAS_SQL_ADMIN // Do the SQL substitutions common for all SQL statements void TODBCApiDS::DoSQLSubstitutions(string &aSQL) { string::size_type i; // let session substitute session level stuff first fAgentP->DoSQLSubstitutions(aSQL); StringSubst(aSQL,"%f",fFolderKey,2,fConfigP->sqlPrepCharSet(),fConfigP->fDataLineEndMode,fConfigP->fQuotingMode); StringSubst(aSQL,"%t",fTargetKey,2,fConfigP->sqlPrepCharSet(),fConfigP->fDataLineEndMode,fConfigP->fQuotingMode); // ID generator // - new ID i=0; while((i=aSQL.find("%X",i))!=string::npos) { // - generate new one nextLocalID(fConfigP->fSpecialIDMode,SQL_NULL_HANDLE); // - use it aSQL.replace(i,2,fLastGeneratedLocalID); i+=fLastGeneratedLocalID.size(); } // last used ID StringSubst(aSQL,"%x",fLastGeneratedLocalID,2,fConfigP->sqlPrepCharSet(),fConfigP->fDataLineEndMode,fConfigP->fQuotingMode); } // TODBCApiDS::DoSQLSubstitutions typedef struct { const char *substTag; int substCode; } TSubstHandlerDef; typedef enum { dsh_datakey, dsh_datakey_outparam_string, dsh_datakey_outparam_integer, dsh_fieldnamelist, dsh_fieldnamelist_a, dsh_namevaluelist, dsh_namevaluelist_a, dsh_valuelist, dsh_valuelist_a, dsh_param, dsh_field, dsh_recordsize, dsh_moddate, dsh_modtime, dsh_moddatetime, dsh_andfilter, dsh_wherefilter, // number of enums dsh_NUMENTRIES } TDataSubstHandlers; static TSubstHandlerDef DataSubstHandlers[dsh_NUMENTRIES] = { { "k", dsh_datakey }, { "pkos", dsh_datakey_outparam_string }, { "pkoi", dsh_datakey_outparam_integer }, { "N", dsh_fieldnamelist }, { "aN", dsh_fieldnamelist_a }, { "V", dsh_namevaluelist }, { "aV", dsh_namevaluelist_a }, { "v", dsh_valuelist }, { "av", dsh_valuelist_a }, { "p(", dsh_param }, { "d(", dsh_field }, { "S", dsh_recordsize }, { "dM", dsh_moddate }, { "tM", dsh_modtime }, { "M", dsh_moddatetime }, { "AF", dsh_andfilter }, { "WF", dsh_wherefilter } }; // do substitutions for data table access void TODBCApiDS::DoDataSubstitutions( string &aSQL, // string to apply substitutions to TFieldMapList &aFieldMapList, // field map list for %N,%V and %v uInt16 aSetNo, // Map Set number bool aForWrite, // set if read-enabled or write-enabled fields are shown in %N,%V and %v bool aForUpdate, // set if for update (only assigned fields will be shown if !fUpdateAllFields) TMultiFieldItem *aItemP, // item to read values and localid from sInt16 aRepOffset, // array index/repeat offset bool *aAllEmptyP, // true if all %V or %v empty bool *aDoneP // true if no data at specified aRepOffset ) { string::size_type i,j,k,m,m2,n; string s,s2; string inStr; int handlerid; // default settings of flags bool done=true; // default, in case %V or %v is missing (which could limit repetitions for arrays) bool allempty=false; // not all empty unless we see that %V has all empty fields // substitute one by one in the order the escape sequences appear in the SQL string // (this is important for correct parameter mapping!!) i=0; inStr=aSQL; aSQL.erase(); // will be rebuilt later while((i=inStr.find("%",i))!=string::npos) { // potential escape sequence found // - search in table for (handlerid=0; handleridgetLocalID(); break; case dsh_datakey_outparam_string: // generated key output (string key) addSQLParameterMap(false,true,param_localid_str,NULL,aItemP,aRepOffset); goto paramsubst; case dsh_datakey_outparam_integer: // generated key output (integer key) addSQLParameterMap(false,true,param_localid_int,NULL,aItemP,aRepOffset); goto paramsubst; case dsh_fieldnamelist: case dsh_fieldnamelist_a: // %N and %aN = field name list addFieldNameList(s,aForWrite,aForUpdate,substCode!=dsh_fieldnamelist_a && !fConfigP->fUpdateAllFields && aForUpdate && aItemP,aItemP,aFieldMapList,aSetNo); break; case dsh_namevaluelist: case dsh_namevaluelist_a: if (!aItemP) break; // needs an item // %V,%aV = data field=value list addFieldNameValueList(s,substCode!=dsh_namevaluelist_a && !fConfigP->fUpdateAllFields && aForUpdate,done,allempty,*aItemP,true,aFieldMapList,aSetNo,aRepOffset,allempty); break; case dsh_valuelist: case dsh_valuelist_a: if (!aItemP) break; // needs an item // %v,%av = data value list addFieldNameValueList(s,substCode!=dsh_valuelist_a && !fConfigP->fUpdateAllFields && aForUpdate,done,allempty,*aItemP,false,aFieldMapList,aSetNo,aRepOffset,allempty); break; case dsh_param: // handle with global routine used in different substitution places // i=start of % sequence, n=size of matched basic sequence = %+identifier+( = %p( if (!fAgentP->ParseParamSubst( inStr,i,n, fParameterMaps, aItemP #ifdef SCRIPT_SUPPORT ,fScriptContextP #endif )) break; // i=start of % sequence, n=size of entire sequence including params and closing paranthesis paramsubst: s="?"; break; case dsh_field: // init options upc=false; lowc=false; asci=false; // skip lead-in j=i+n; // find closing paranthesis k = inStr.find(")",j); if (k==string::npos) { i=j; n=0; break; } // no closing paranthesis m = k; // assume end of name is here m2 = k; // look for dbfieldtype dbfty=dbft_numeric; // default to numeric (no quotes, to be compatible with old %d() definition) m2 = inStr.find(",",j); if (m2!=string::npos) { // get dbfieldtype if (StrToEnum(DBFieldTypeNames,numDBfieldTypes,ty,inStr.c_str()+m2+1,k-m2-1)) dbfty=(TDBFieldType)ty; } else m2=k; // set end of name to closing paranthesis again #ifdef ARRAYFIELD_SUPPORT // also look for array index m = inStr.find("#",j); if (m!=string::npos && mgetIdentifierIndex(OBJ_AUTO, aItemP->getFieldDefinitions(),s.c_str()); fldP=fScriptContextP->getFieldOrVar(aItemP,idx,arrindex); } else #endif fldP = aItemP->getArrayField(s.c_str(),arrindex,true); if (!fldP) { i=k+1; n=0; break; } // field not found, no action // produce DB literal sz=0; s.erase(); fAgentP->appendFieldValueLiteral( *fldP, dbfty, 0, // unlimited s, asci ? chs_ascii : fConfigP->sqlPrepCharSet(), fConfigP->fDataLineEndMode, fConfigP->fQuotingMode, fConfigP->fDataTimeZone, sz ); // apply options if (upc) StringUpper(s); else if (lowc) StringLower(s); fRecordSize+=s.size(); // set substitution parameters n=k+1-i; break; case dsh_recordsize: if (aItemP) StringObjPrintf(s,"%ld",(long)fRecordSize); break; #ifdef ODBCAPI_SUPPORT case dsh_moddate: // %dM = modified date fAgentP->lineartimeToODBCLiteralAppend(fCurrentSyncTime,s,true,false,TCTX_UTC,fConfigP->fDataTimeZone); break; case dsh_modtime: // %tM = modified time fAgentP->lineartimeToODBCLiteralAppend(fCurrentSyncTime,s,false,true,TCTX_UTC,fConfigP->fDataTimeZone); break; #endif // ODBCAPI_SUPPORT case dsh_moddatetime: // %M = modified datetimestamp #ifdef SQLITE_SUPPORT if (fUseSQLite) { // integer timestamp modes fAgentP->lineartimeToIntLiteralAppend(fCurrentSyncTime,s,fConfigP->fLastModDBFieldType,TCTX_UTC,fConfigP->fDataTimeZone); } #ifdef ODBCAPI_SUPPORT else #endif #endif #ifdef ODBCAPI_SUPPORT { if (fConfigP->fLastModDBFieldType==dbft_timestamp) fAgentP->lineartimeToODBCLiteralAppend(fCurrentSyncTime,s,true,true,TCTX_UTC,fConfigP->fDataTimeZone); else fAgentP->lineartimeToIntLiteralAppend(fCurrentSyncTime,s,fConfigP->fLastModDBFieldType,TCTX_UTC,fConfigP->fDataTimeZone); } #endif // ODBCAPI_SUPPORT ; // make sure we can't else out the break break; #ifdef OBJECT_FILTERING case dsh_andfilter: if (fFilterWorksOnDBLevel && fFilterExpressionTested) appendFiltersClause(s,"AND"); break; case dsh_wherefilter: if (fFilterWorksOnDBLevel && fFilterExpressionTested) appendFiltersClause(s,"WHERE"); break; #endif default: i+=n; // continue parsing after unhandled tag n=0; // no replacement break; } // switch // apply substitution if any (n>0) // - i=pos of %, n=size of text to be replaced, s=replacement string // Note: if n==0, i must point to where parsing should continue if (n>0) { // get everything up to this % sequence string intermediateStr; intermediateStr.assign(inStr,0,i); // have non-processed sequences processed for the other substitution possibilities now // %f=folderkey, %u=userkey, %d=devicekey, %t=targetkey, %C=domain // Note: it is important that %t and %d is checked here, after %d(), %tL and %tS above!! //DEBUGPRINTFX(DBG_DBAPI+DBG_EXOTIC,("Intermediate before applying basic substitutions: '%s'",intermediateStr.c_str())); DoSQLSubstitutions(intermediateStr); //DEBUGPRINTFX(DBG_DBAPI+DBG_EXOTIC,("Intermediate after applying basic substitutions: '%s'",intermediateStr.c_str())); // add it to the output string aSQL+=intermediateStr; // add the substitution (will NOT BE PROCESSED AGAIN!!) aSQL+=s; // have the rest of the inStr processed inStr.erase(0,i+n); // remove already processed stuff and escape sequence now // reset parsing position in inStr i=0; //DEBUGPRINTFX(DBG_DBAPI+DBG_EXOTIC,("- substitution with '%s' done, SQL so far: '%s'",s.c_str(),aSQL.c_str())); //DEBUGPRINTFX(DBG_DBAPI+DBG_EXOTIC,("Remaining input string to process: '%s'",inStr.c_str())); } // sequence substitution done break; } } // for if (handlerid>=dsh_NUMENTRIES) { // unknown sequence // - check if this is an explicit literal % (two % in sequence) if (inStr[i+1]=='%') { // yes, replace %% by % in output inStr.replace(i,2,"%"); i+=1; } else { // no, just leave % in input as it is i+=1; } } } // while % found in string // process rest of inStr (not containing any of the above sequences, but probably some from // parent implementation // have non-processed sequences processed for the other substitution possibilities now // %f=folderkey, %u=userkey, %d=devicekey, %t=targetkey, %C=domain // Note: it is important that %t and %d is checked here, after %d(), %tL and %tS above!! DoSQLSubstitutions(inStr); // Append end of inStr to output aSQL+=inStr; // return flags if (aAllEmptyP) *aAllEmptyP=allempty; if (aDoneP) *aDoneP=done; } // TODBCApiDS::DoDataSubstitutions // insert additional data selection conditions, if any. Returns true if something appended bool TODBCApiDS::appendFiltersClause(string &aSQL, const char *linktext) { #ifndef OBJECT_FILTERING return false; // no filters #else if ( (!fConfigP->fFilterOnDBLevel || (fLocalDBFilter.empty() && fSyncSetFilter.empty() && fConfigP->fInvisibleFilter.empty())) #ifdef SCRIPT_SUPPORT && fSQLFilter.empty() #endif ) return false; // no filter clause needed // some conditions, add link text if (linktext) { aSQL+=' '; aSQL+=linktext; aSQL+=' '; } linktext=NULL; // link within paranthesis #ifdef SCRIPT_SUPPORT // - Explicit SQL filter if (!fSQLFilter.empty()) { if (linktext) aSQL+=linktext; linktext=" AND "; aSQL+='('; aSQL+=fSQLFilter; aSQL+=')'; } #endif // - hardcoded filter conditions if (!fLocalDBFilter.empty()) { if (linktext) aSQL+=linktext; linktext=" AND "; aSQL+='('; if (!appendFilterConditions(aSQL,fLocalDBFilter)) throw TSyncException(" incompatible with SQL database"); aSQL+=')'; } // - filter invisible items if (!fConfigP->fInvisibleFilter.empty()) { if (linktext) aSQL+=linktext; linktext=" AND "; aSQL+="NOT ("; if (!appendFilterConditions(aSQL,fConfigP->fInvisibleFilter)) throw TSyncException(" incompatible with SQL database"); aSQL+=')'; } // - sync set filter conditions if (!fSyncSetFilter.empty()) { if (linktext) aSQL+=linktext; linktext=" AND "; aSQL+='('; if (!appendFilterConditions(aSQL,fSyncSetFilter)) throw TSyncException("sync set filter incompatible with SQL database"); aSQL+=')'; } return true; // something appended #endif // OBJECT_FILTERING } // TODBCApiDS::appendFiltersClause // reset all mapped parameters void TODBCApiDS::resetSQLParameterMaps(void) { #ifdef SQLITE_SUPPORT if (fUseSQLite) { // resetting the parameter map finalizes any possibly running statement if (fSQLiteStmtP) { sqlite3_finalize(fSQLiteStmtP); fSQLiteStmtP=NULL; } } #endif fAgentP->resetSQLParameterMaps(fParameterMaps); } // TODBCApiDS::resetSQLParameterMaps // add parameter definition to the datastore level parameter list void TODBCApiDS::addSQLParameterMap( bool aInParam, bool aOutParam, TParamMode aParamMode, TODBCFieldMapItem *aFieldMapP, TMultiFieldItem *aItemP, sInt16 aRepOffset ) { TParameterMap map; // assign basics map.inparam=aInParam; map.outparam=aOutParam; map.parammode=aParamMode; map.mybuffer=false; map.ParameterValuePtr=NULL; map.BufferLength=0; map.StrLen_or_Ind=SQL_NULL_DATA; // note that this is not zero (but -1) map.itemP=aItemP; map.outSiz=NULL; // get things from field map if (aFieldMapP) { map.fieldP=getMappedFieldOrVar(*aItemP,aFieldMapP->fid,aRepOffset); map.maxSize=aFieldMapP->maxsize; map.dbFieldType=aFieldMapP->dbfieldtype; } else { map.fieldP=NULL; map.maxSize=0; map.dbFieldType=dbft_string; } // save in list fParameterMaps.push_back(map); } // TODBCApiDS::addSQLParameterMap // prepare SQL statment as far as needed for parameter binding void TODBCApiDS::prepareSQLStatement(SQLHSTMT aStatement, cAppCharP aSQL, bool aForData, cAppCharP aComment) { // show what statement will be executed #ifdef SYDEBUG if (aComment && aSQL && PDEBUGTEST(DBG_DBAPI)) { PDEBUGPRINTFX(DBG_DBAPI,("SQL for %s:",aComment)); PDEBUGPUTSX(DBG_DBAPI,aSQL); } #endif #ifdef SQLITE_SUPPORT if (fUseSQLite && aForData) { // bind params fAgentP->prepareSQLiteStatement( aSQL, fSQLiteP, fSQLiteStmtP ); } #endif } // TODBCApiDS::prepareSQLStatement // bind parameters (and values for IN-Params) to the statement void TODBCApiDS::bindSQLParameters(SQLHSTMT aStatement, bool aForData) { #ifdef SQLITE_SUPPORT if (fUseSQLite && aForData) { // bind params fAgentP->bindSQLiteParameters( fSessionP, fSQLiteStmtP, fParameterMaps, fConfigP->fDataCharSet, fConfigP->fDataLineEndMode ); } else #endif { #ifdef ODBCAPI_SUPPORT fAgentP->bindSQLParameters( fSessionP, aStatement, fParameterMaps, fConfigP->fDataCharSet, // actual charset, including utf16, bindSQLiteParameters handles UTF16 case fConfigP->fDataLineEndMode ); #endif } } // TODBCApiDS::bindSQLParameters // save out parameter values and clean up void TODBCApiDS::saveAndCleanupSQLParameters( SQLHSTMT aStatement, bool aForData ) { #ifdef SQLITE_SUPPORT if (fUseSQLite && aForData) { // NOP here because SQLite has no out params return; } else #endif { #ifdef ODBCAPI_SUPPORT fAgentP->saveAndCleanupSQLParameters( fSessionP, aStatement, fParameterMaps, fConfigP->fDataCharSet, // actual charset, including utf16, saveAndCleanupSQLParameters handles UTF16 case fConfigP->fDataLineEndMode ); #endif } } // TODBCApiDS::bindSQLParameters // Fetch next row from SQL statement, returns true if there is any bool TODBCApiDS::fetchNextRow(SQLHSTMT aStatement, bool aForData) { #ifdef SQLITE_SUPPORT if (fUseSQLite && aForData) { int rc = fStepRc; if (rc!=SQLITE_ROW) { if (rc==SQLITE_OK) { // last step was ok, we need to do next step first rc = sqlite3_step(fSQLiteStmtP); } } // clean up right now if we don't have data if (rc!=SQLITE_ROW) { rc=sqlite3_finalize(fSQLiteStmtP); fStepRc = rc; fSQLiteStmtP=NULL; fAgentP->checkSQLiteError(rc,fSQLiteP); return false; // no more data } else { // we are reporting data now, make sure we fetch data in next call fStepRc=SQLITE_OK; } // more data found return true; // ok } else #endif #ifdef ODBCAPI_SUPPORT { if (aStatement==SQL_NULL_HANDLE) return false; // no statement, nothing fetched SQLRETURN res=SafeSQLFetch(aStatement); // check for end return fAgentP->checkStatementHasData(res,aStatement); } #else return false; // no API, no result #endif // ODBCAPI_SUPPORT } // TODBCApiDS::fetchNextRow // SQL statement complete, finalize it void TODBCApiDS::finalizeSQLStatement(SQLHSTMT aStatement, bool aForData) { #ifdef SQLITE_SUPPORT if (fUseSQLite && aForData) { // finalize if not already done if (fSQLiteStmtP) { sqlite3_finalize(fSQLiteStmtP); fSQLiteStmtP=NULL; } } else #endif { #ifdef ODBCAPI_SUPPORT // just close cursor of the statement SafeSQLCloseCursor(aStatement); #endif // ODBCAPI_SUPPORT } } // TODBCApiDS::prepareSQLStatement #ifdef OBJECT_FILTERING // - returns true if DB implementation can filter the standard filters // (LocalDBFilter, TargetFilter and InvisibleFilter) during database fetch // - otherwise, fetched items will be filtered after being read from DB. bool TODBCApiDS::dsFilteredFetchesFromDB(bool aFilterChanged) { // can do filtering while fetching from DB, such that items that get (in)visible // because of changed filter conditions are correctly detected as added/deleted if (aFilterChanged || !fFilterExpressionTested) { fFilterExpressionTested=true; if (fConfigP->fFilterOnDBLevel) { // try to dummy-append the filterclause to check if this will work string s; try { appendFiltersClause(s,""); fFilterWorksOnDBLevel=true; } catch(exception &e) { PDEBUGPRINTFX(DBG_FILTER+DBG_HOT,("%s -> filter will be applied to fetched records",e.what())); fFilterWorksOnDBLevel=false; } } else fFilterWorksOnDBLevel=false; // reject all DB level filtering } // if we can filter, that's sufficient if (fFilterWorksOnDBLevel) return true; // otherwise, let ancestor test return inherited::dsFilteredFetchesFromDB(aFilterChanged); } // TODBCApiDS::dsfilteredFetchesFromDB // - appends logical condition to SQL from filter string bool TODBCApiDS::appendFilterConditions(string &aSQL, const string &aFilter) { const char *p=aFilter.c_str(); return appendFilterTerm(aSQL,p,p+aFilter.size()); } // TODBCApiDS::appendFilterConditions // - appends logical condition term to SQL from filter string bool TODBCApiDS::appendFilterTerm(string &aSQL, const char *&aPos, const char *aStop) { char c=0; const char *st; string str,cmp,val; bool result; sInt16 fid; bool specialValue; bool caseInsensitive; // determine max length if (aStop==NULL) aStop=aPos+strlen(aPos); // empty expression is ok do { result=true; // process simple term () // - get first non-space while (aPos<=aStop) { c=*aPos; if (c!=' ') break; aPos++; } // Term starts here, first char is c, aPos points to it // - check subexpression paranthesis if (c=='(') { // boolean term is grouped subexpression aSQL+='('; aPos++; result=appendFilterTerm(aSQL,aPos,aStop); // check if matching paranthesis if (*(aPos++)!=')') { PDEBUGPRINTFX(DBG_EXOTIC,("Filter expression syntax error at: %s",--aPos)); aPos=aStop; // skip rest return false; // always fail } aSQL+=')'; } else if (c==0) { // empty term, is ok return true; } else { // must be simple boolean term // - remember start of ident st=aPos; // - search end of ident while (isFilterIdent(c)) c=*(++aPos); // - c/aPos=char after ident, get ident str.assign(st,aPos-st); // - check for subscript index uInt16 subsIndex=0; // no index (is 1-based in DS 1.2 filter specs) if (c=='[') { // expect numeric index aPos++; // next aPos+=StrToUShort(aPos,subsIndex); if (*aPos!=']') { PDEBUGPRINTFX(DBG_ERROR,("Filter expression error (missing \"]\") at: %s",--aPos)); return false; // syntax error, does not pass } c=*(++aPos); // process next after subscript } // - get operator while (isspace(c)) c=*(++aPos); if (c==':') c=*(++aPos); // ignore assign-to-make-true modifier specialValue = c=='*'; // special-value modifier if (specialValue) c=*(++aPos); caseInsensitive = c=='^'; // case insensitive modifier if (caseInsensitive) c=*(++aPos); aPos++; // one char at least cmp.erase(); bool cmplike=c=='%' || c=='$'; if (cmplike) cmp= (c=='%') ? " LIKE " : " NOT LIKE "; // "contains" special case, use SQL LIKE %val% else { cmp+=c; // simply use first char as is if (c=='>' || c=='<') { if (*aPos=='=' || *aPos=='>') { c=*aPos++; cmp+=c; // >=, <= and <> } } } // - get comparison value while (isspace(c)) c=*(++aPos); st=aPos; // should start here while (aPos(getLocalSendType()); if (mfitP) fid=mfitP->getFilterIdentifierFieldIndex(str.c_str(),subsIndex); else return false; // field not known, bad syntax if (fid==FID_NOT_SUPPORTED) return false; // unknown field // search for map for that field id to obtain DB field name TFieldMapList &fml = fConfigP->fFieldMappings.fFieldMapList; TFieldMapList::iterator mainpos; TFieldMapList::iterator pos; bool mainfound=false; for (pos=fml.begin(); pos!=fml.end(); pos++) { // check field id, but search in setNo==0 only (fields of other sets are // not available when SELECTing syncset. if ((*pos)->setNo==0 && fid==(*pos)->fid) { if ((*pos)->isArray()) return false; // array fields cannot be used in filters // found if (mainfound) break; // second match just breaks loop (time for date, possibly) // main mainpos=pos; // save position of main field mainfound=true; // search for further fields with same fid (possibly needed for timefordate) } } if (!mainfound) { PDEBUGPRINTFX(DBG_EXOTIC,("Could not find DB field for fid=%hd",fid)); return false; // no such field } // - translate for special values if (specialValue) { if ((*mainpos)->dbfieldtype==dbft_string && val=="E") { // Empty is not NULL for strings val="''"; } else if (val=="N" || val=="E") { // for other types, NULL and EMPTY are the same val="NULL"; if (cmp!="=") cmp=" IS NOT "; else cmp=" IS "; } // now append (no check for caseInsensitive needed as NULL check does not need it aSQL+=(*mainpos)->fElementName; aSQL+=cmp; aSQL+=val; } else { // create field to convert value string correctly TItemField *valfldP = newItemField( mfitP->getFieldDefinition(fid)->type, getSessionZones() ); // assign value as string valfldP->setAsString(val.c_str()); // check for special case when timestamp is mapped to separate date/time fields if ( pos!=fml.end() && ( // if there is another map with the same fid ((*mainpos)->dbfieldtype==dbft_date && (*pos)->dbfieldtype==dbft_timefordate) ) ) { // separate date & time aSQL+='('; if (cmp=="=" || cmp=="<>") { // (datefield=val AND timefield=val) // (datefield<>val OR timefield<>val) aSQL+=(*mainpos)->fElementName; aSQL+=cmp; appendFieldValueLiteral(*valfldP, (*mainpos)->dbfieldtype,(*mainpos)->maxsize, (*mainpos)->floating_ts, aSQL); if (cmp=="=") aSQL+=" AND "; else aSQL+=" OR "; // - time field aSQL+=(*pos)->fElementName; aSQL+=cmp; appendFieldValueLiteral(*valfldP, (*pos)->dbfieldtype,(*pos)->maxsize, (*mainpos)->floating_ts, aSQL); } else { // (datefield >< val OR (datefield = val AND timefield >< val)) aSQL+=(*mainpos)->fElementName; aSQL+=cmp; appendFieldValueLiteral(*valfldP, (*mainpos)->dbfieldtype,(*mainpos)->maxsize, (*mainpos)->floating_ts, aSQL); aSQL+=" OR ("; aSQL+=(*mainpos)->fElementName; aSQL+='='; appendFieldValueLiteral(*valfldP, (*mainpos)->dbfieldtype,(*mainpos)->maxsize, (*mainpos)->floating_ts, aSQL); aSQL+=" AND "; // - time field aSQL+=(*pos)->fElementName; aSQL+=cmp; appendFieldValueLiteral(*valfldP, (*pos)->dbfieldtype,(*pos)->maxsize, (*mainpos)->floating_ts, aSQL); aSQL+=')'; } aSQL+=')'; } else { // standard case // field ><= val if (caseInsensitive) { aSQL+="LOWER("; aSQL+=(*mainpos)->fElementName; aSQL+=')'; aSQL+=cmp; // operator aSQL+="LOWER("; appendFieldValueLiteral(*valfldP, (*mainpos)->dbfieldtype,(*mainpos)->maxsize, (*mainpos)->floating_ts, aSQL); aSQL+=')'; } else { aSQL+=(*mainpos)->fElementName; aSQL+=cmp; appendFieldValueLiteral(*valfldP, (*mainpos)->dbfieldtype,(*mainpos)->maxsize, (*mainpos)->floating_ts, aSQL); } } // field can be deleted now delete valfldP; } // not special value } // refers to field } // simple boolean term // now check logical operators // - skip spaces c=*aPos++; while (c==' ') c=*(++aPos); // - check char at aPos if (c=='|') aSQL+=" OR "; else if (c=='&') aSQL+= " AND "; else { aPos--; // let caller check it break; // end of logical term } } while (true); // process terms until all done // conversion ok return true; } // TODBCApiDS::appendFilterTerm #endif // OBJECT_FILTERING #ifdef ODBCAPI_SUPPORT // get one or two successive columns as time stamp depending on config void TODBCApiDS::getColumnsAsTimestamp( SQLHSTMT aStatement, sInt16 &aColNumber, // will be updated by 1 or 2 bool aCombined, lineartime_t &aTimestamp, timecontext_t aTargetContext ) { lineartime_t t; if (aCombined) { // combined date/time fAgentP->getColumnValueAsTimestamp(aStatement,aColNumber++,aTimestamp); } else { // date, then time fAgentP->getColumnValueAsDate(aStatement,aColNumber++,aTimestamp); fAgentP->getColumnValueAsTime(aStatement,aColNumber++,t); aTimestamp+=t; // add time to date } // convert to target zone requested if (!TCTX_IS_UNKNOWN(aTargetContext)) { TzConvertTimestamp(aTimestamp,fConfigP->fDataTimeZone,aTargetContext,getSessionZones(),TCTX_UNKNOWN); } } // TODBCApiDS::getColumnsAsTimestamp #endif // ODBCAPI_SUPPORT // - get a column as integer based timestamp lineartime_t TODBCApiDS::dbIntToLineartimeAs( sInt64 aDBInt, TDBFieldType aDbfty, timecontext_t aTargetContext ) { lineartime_t ts = dbIntToLineartime(aDBInt, aDbfty); // convert to target zone requested if (!TCTX_IS_UNKNOWN(aTargetContext)) { TzConvertTimestamp(ts,fConfigP->fDataTimeZone,aTargetContext,getSessionZones(),TCTX_UNKNOWN); } return ts; } // TODBCApiDS::dbIntToLineartimeAs // create local ID with special algorithm void TODBCApiDS::createLocalID(string &aLocalID,TSpecialIDMode aSpecialIDMode) { lineartime_t unixms; switch (aSpecialIDMode) { case sidm_unixmsrnd6: // ID is generated by UNIX time in milliseconds, with 6 digits of random // appended. // - get Unix time in milliseconds: unixms = (getSession()->getSystemNowAs(TCTX_SYSTEM)-UnixToLineartimeOffset) // unix time in lineartime_t units *(1000/secondToLinearTimeFactor); // convert into ms unixms*=1000000; // room for 6 more digits // - add random number between 0 and 999999 unixms+=(sInt32)rand()*1000000/RAND_MAX; // - make numeric ID out of this StringObjPrintf(aLocalID,"%lld",(long long)unixms); break; default: aLocalID=""; } } // TODBCApiDS::createLocalID #ifdef HAS_SQL_ADMIN // update sync target localstatus TODBCApiDS::updateSyncTarget(SQLHSTMT aStatement, bool aSessionFinished) { string sql,s; localstatus sta=LOCERR_OK; resetSQLParameterMaps(); sql = fConfigP->fUpdateSyncTargetSQL; sInt32 i; // Suspend/Resume // - alert code for next resume StringSubst(sql,"%SUA",fResumeAlertCode,4); // - suspend reference time i=0; while((i=sql.find("%dSU",i))!=string::npos) { s.erase(); fAgentP->lineartimeToLiteralAppend(fPreviousSuspendCmpRef, s, true, false, TCTX_UTC, fConfigP->fDataTimeZone); sql.replace(i,4,s); i+=s.size(); } // - suspend reference time i=0; while((i=sql.find("%tSU",i))!=string::npos) { s.erase(); fAgentP->lineartimeToLiteralAppend(fPreviousSuspendCmpRef, s, false, true, TCTX_UTC, fConfigP->fDataTimeZone); sql.replace(i,4,s); i+=s.size(); } // - suspend reference time i=0; while((i=sql.find("%SU",i))!=string::npos) { s.erase(); fAgentP->lineartimeToLiteralAppend(fPreviousSuspendCmpRef, s, true, true, TCTX_UTC, fConfigP->fDataTimeZone); sql.replace(i,3,s); i+=s.size(); } // - last suspend identifier (for derived datastores that might need another token than time) StringSubst(sql,"%iSU",fPreviousSuspendIdentifier,4,fConfigP->sqlPrepCharSet(),fConfigP->fDataLineEndMode,fConfigP->fQuotingMode); // - anchor StringSubst(sql,"%A",fLastRemoteAnchor,2,fConfigP->sqlPrepCharSet(),fConfigP->fDataLineEndMode,fConfigP->fQuotingMode); // Suspend/Resume in mid-chunk // - lastitem StringSubst(sql,"%pSU",fLastSourceURI,4,fConfigP->sqlPrepCharSet(),fConfigP->fDataLineEndMode,fConfigP->fQuotingMode); StringSubst(sql,"%pTU",fLastTargetURI,4,fConfigP->sqlPrepCharSet(),fConfigP->fDataLineEndMode,fConfigP->fQuotingMode); // - lastitemstatus StringSubst(sql,"%pSt",fLastItemStatus,4); // - partial item State/Mode long pista; if (fPartialItemState==pi_state_save_incoming) pista=(long)pi_state_loaded_incoming; else if (fPartialItemState==pi_state_save_outgoing) pista=(long)pi_state_loaded_outgoing; else pista=(long)pi_state_none; StringSubst(sql,"%pM",pista,3); // - size info StringSubst(sql,"%pTS",fPITotalSize,4); StringSubst(sql,"%pUS",fPIUnconfirmedSize,4); StringSubst(sql,"%pSS",fPIStoredSize,4); // - buffered data i=0; while((i=sql.find("%pDAT",i))!=string::npos) { sql.replace(i,5,"?"); i+=1; // now bind data to param TParameterMap map; map.inparam=true; map.outparam=false; map.parammode=param_buffer; map.outSiz=NULL; map.dbFieldType=dbft_blob; // - pass the buffer map.mybuffer=false; // not owned by ODBC api if (fPIStoredDataP) { map.BufferLength=fPIStoredSize; map.StrLen_or_Ind=fPIStoredSize; map.ParameterValuePtr=fPIStoredDataP; // the BLOB data to store } else { map.BufferLength=0; map.StrLen_or_Ind=SQL_NULL_DATA; // no data map.ParameterValuePtr=NULL; } // save in list fParameterMaps.push_back(map); } // - last to remote sync reference date // Note: If we DON'T HAVE fSyncTimeStampAtEnd, but HAVE fOneWayFromRemoteSupported, // we MUST NOT store the reference time here, but save save session start time. // The reference time will be saved under %dRS lineartime_t dltime; if (!fConfigP->fSyncTimeStampAtEnd && fConfigP->fOneWayFromRemoteSupported) dltime = fPreviousSyncTime; else dltime = fPreviousToRemoteSyncCmpRef; i=0; while((i=sql.find("%dL",i))!=string::npos) { s.erase(); fAgentP->lineartimeToLiteralAppend(dltime, s, true, false, TCTX_UTC, fConfigP->fDataTimeZone); sql.replace(i,3,s); i+=s.size(); } // - last to remote sync reference time i=0; while((i=sql.find("%tL",i))!=string::npos) { s.erase(); fAgentP->lineartimeToLiteralAppend(dltime, s, false, true, TCTX_UTC, fConfigP->fDataTimeZone); sql.replace(i,3,s); i+=s.size(); } // - last to remote sync reference date/timestamp i=0; while((i=sql.find("%L",i))!=string::npos) { s.erase(); fAgentP->lineartimeToLiteralAppend(dltime, s, true, true, TCTX_UTC, fConfigP->fDataTimeZone); sql.replace(i,2,s); i+=s.size(); } // - last sync session start date i=0; while((i=sql.find("%dS",i))!=string::npos) { s.erase(); fAgentP->lineartimeToLiteralAppend(fPreviousSyncTime, s, true, false, TCTX_UTC, fConfigP->fDataTimeZone); sql.replace(i,3,s); i+=s.size(); } // - last sync session start time i=0; while((i=sql.find("%tS",i))!=string::npos) { s.erase(); fAgentP->lineartimeToLiteralAppend(fPreviousSyncTime, s, false, true, TCTX_UTC, fConfigP->fDataTimeZone); sql.replace(i,3,s); i+=s.size(); } // - last sync session start date/timestamp i=0; while((i=sql.find("%S",i))!=string::npos) { s.erase(); fAgentP->lineartimeToLiteralAppend(fPreviousSyncTime, s, true, true, TCTX_UTC, fConfigP->fDataTimeZone); sql.replace(i,2,s); i+=s.size(); } // - last sync with data to remote date i=0; while((i=sql.find("%dRL",i))!=string::npos) { s.erase(); fAgentP->lineartimeToLiteralAppend(fPreviousToRemoteSyncCmpRef, s, true, false, TCTX_UTC, fConfigP->fDataTimeZone); sql.replace(i,4,s); i+=s.size(); } // - last sync with data to remote time i=0; while((i=sql.find("%tRL",i))!=string::npos) { s.erase(); fAgentP->lineartimeToLiteralAppend(fPreviousToRemoteSyncCmpRef, s, false, true, TCTX_UTC, fConfigP->fDataTimeZone); sql.replace(i,4,s); i+=s.size(); } // - last sync with data to remote date/timestamp i=0; while((i=sql.find("%RL",i))!=string::npos) { s.erase(); fAgentP->lineartimeToLiteralAppend(fPreviousToRemoteSyncCmpRef, s, true, true, TCTX_UTC, fConfigP->fDataTimeZone); sql.replace(i,3,s); i+=s.size(); } // - last sync with data to remote identifier (for derived datastores that might need another token than time) StringSubst(sql,"%iRL",fPreviousToRemoteSyncIdentifier,4,fConfigP->sqlPrepCharSet(),fConfigP->fDataLineEndMode,fConfigP->fQuotingMode); // - last anchor for sync with data to remote date // Note: this is only needed if we DON'T HAVE fSyncTimeStampAtEnd, but HAVE fOneWayFromRemoteSupported, // because then the %L cannot be used as reference time (it must save session time) i=0; while((i=sql.find("%dRS",i))!=string::npos) { s.erase(); fAgentP->lineartimeToLiteralAppend(fPreviousToRemoteSyncCmpRef, s, true, false, TCTX_UTC, fConfigP->fDataTimeZone); sql.replace(i,4,s); i+=s.size(); } // - last server anchor with data to remote time i=0; while((i=sql.find("%tRS",i))!=string::npos) { s.erase(); fAgentP->lineartimeToLiteralAppend(fPreviousToRemoteSyncCmpRef, s, false, true, TCTX_UTC, fConfigP->fDataTimeZone); sql.replace(i,4,s); i+=s.size(); } // - last server anchor with data to remote date/timestamp i=0; while((i=sql.find("%RS",i))!=string::npos) { s.erase(); fAgentP->lineartimeToLiteralAppend(fPreviousToRemoteSyncCmpRef, s, true, true, TCTX_UTC, fConfigP->fDataTimeZone); sql.replace(i,3,s); i+=s.size(); } // now substitute standard: %f=folderkey, %u=userkey, %d=devicekey, %t=targetkey // - Note: it is important that %t,%d is checked here, after %dL, %dS, %tL and %tS above!! DoSQLSubstitutions(sql); // - bind possible params bindSQLParameters(aStatement,false); // - issue execSQLStatement(aStatement,sql,false,"updating anchor/lastsync",false); return LOCERR_OK; } // TODBCApiDS::updateSyncTarget // update map changes from memory list into actual map table localstatus TODBCApiDS::updateODBCMap(SQLHSTMT aStatement, bool aSessionFinishedSuccessfully) { string sql,s; localstatus sta=LOCERR_OK; TMapContainer::iterator pos; // now save the entire list differentially pos=fMapTable.begin(); DEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,("updateODBCMap: internal map table has %ld entries (normal and others)",fMapTable.size())); while (pos!=fMapTable.end()) { DEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,( "updateODBCMap: entryType=%s, localid='%s', remoteID='%s', mapflags=0x%lX, changed=%d, deleted=%d, added=%d, markforresume=%d, savedmark=%d", MapEntryTypeNames[(*pos).entrytype], (*pos).localid.c_str(), (*pos).remoteid.c_str(), (*pos).mapflags, (int)(*pos).changed, (int)(*pos).deleted, (int)(*pos).added, (int)(*pos).markforresume, (int)(*pos).savedmark )); try { // check if item has changed since map table was read, or if its markforresume has changed // or if this is a successful end of a session, when we can safely assume that any pending maps // are from adds to the client that have never reached the client (otherwise, we'd have got // a map for it, even if the add was in a previous session or session attempt) if ( (*pos).changed || (*pos).added || (*pos).deleted || // update of DB needed ((*pos).markforresume!=(*pos).savedmark) // mark for resume changed ) { // make sure it does not get written again if not really modified again (*pos).changed=false; // update new mapflags w/o changing mapflag_useforresume in the actual flags (as we still need it while session goes on) uInt32 newmapflags = (*pos).mapflags & ~mapflag_useforresume; if ((*pos).markforresume) newmapflags |= mapflag_useforresume; // remember last saved state (*pos).savedmark=(*pos).markforresume; // do something! if ((*pos).deleted) { if (!(*pos).added) { // delete this entry (only needed if it was not also added since last save - otherwise, map entry was never saved to the DB yet) IssueMapSQL(aStatement,fConfigP->fMapDeleteSQL,"deleting a map entry",(*pos).entrytype,(*pos).localid.c_str(),NULL,newmapflags); } // now remove it from the list, such that we don't try to delete it again TMapContainer::iterator delpos=pos++; // that's the next to have a look at fMapTable.erase(delpos); // remove it now continue; // pos is already updated } // deleted else if ((*pos).added) { // add a new entry IssueMapSQL(aStatement,fConfigP->fMapInsertSQL,"inserting a map entry",(*pos).entrytype,(*pos).localid.c_str(),(*pos).remoteid.c_str(),newmapflags); // is now added, don't add again later (*pos).added=false; } else { // explicitly changed or needs update because of resume mark or pendingmap flag // change existing entry IssueMapSQL(aStatement,fConfigP->fMapUpdateSQL,"changing a map entry",(*pos).entrytype,(*pos).localid.c_str(),(*pos).remoteid.c_str(),newmapflags); } } // if something changed // anyway - reset mark for resume, it must be reconstructed before next save (*pos).markforresume=false; // next pos++; } // catch exceptions, but nevertheless continue writing catch (exception &e) { PDEBUGPRINTFX(DBG_ERROR,("******** TODBCApiDS::updateODBCMap exception: %s",e.what())); sta=510; break; } catch (...) { DEBUGPRINTFX(DBG_ERROR,("******** TODBCApiDS::updateODBCMap unknown exception")); sta=510; break; } } // while return sta; } // TODBCApiDS::updateMap #endif // HAS_SQL_ADMIN // called when message processing void TODBCApiDS::dsEndOfMessage(void) { string msg,state; #ifdef ODBCAPI_SUPPORT SQLRETURN res; // commit data if not anyway committed at end of every item if ( fODBCConnectionHandle!=SQL_NULL_HANDLE && !fConfigP->fCommitItems ) { DEBUGPRINTFX(DBG_DATA+DBG_DBAPI,("dsEndOfMessage - committing transactions at end of message")); res=SafeSQLEndTran(SQL_HANDLE_DBC,getODBCConnectionHandle(),SQL_COMMIT); if (fAgentP->getODBCError(res,msg,state,SQL_HANDLE_DBC,getODBCConnectionHandle())) { DEBUGPRINTFX(DBG_ERROR,("dsEndOfMessage: SQLEndTran failed: %s",msg.c_str())); } } #endif // ODBCAPI_SUPPORT // let ancestor do things inherited::dsEndOfMessage(); } // TODBCApiDS::dsEndOfMessage // Simple DB API access interface methods // Zap all data in syncset (note that everything outside the sync set will remain intact) localstatus TODBCApiDS::apiZapSyncSet(void) { localstatus sta = LOCERR_OK; try { string sql=fConfigP->fDataZapSQL; if (sql.empty()) { // we have no statement that can zap everything at once, so we'll have to do // use generic one by one syncset deletion sta = zapSyncSetOneByOne(); } else { // we have SQL statement(s) for zapping, use it sInt16 i=0; uInt16 setno; while (getNextSQLStatement(fConfigP->fDataZapSQL,i,sql,setno)) { DoDataSubstitutions(sql,fConfigP->fFieldMappings.fFieldMapList,0,false,false); // - issue prepareSQLStatement(fODBCWriteStatement, sql.c_str(), true, "slow-refresh from remote: deleting all records in sync set first"); execSQLStatement(fODBCWriteStatement, sql, true, NULL, true); finalizeSQLStatement(fODBCWriteStatement, true); } // while more statements } } catch (exception &e) { PDEBUGPRINTFX(DBG_ERROR,("apiZapSyncSet exception: %s",e.what())); return 510; } // done return sta; } // TODBCApiDS::apiZapSyncSet // read sync set IDs and mod dates. // - If aNeedAll is set, all data fields are needed, so apiReadSyncSet MAY // read items here already. Note that apiReadSyncSet MAY read items here // even if aNeedAll is not set (if it is more efficient than reading // them separately afterwards). localstatus TODBCApiDS::apiReadSyncSet(bool aNeedAll) { string sql; localstatus sta = LOCERR_OK; // get field map list TFieldMapList &fml = fConfigP->fFieldMappings.fFieldMapList; #ifdef SQLITE_SUPPORT // start reading if (fUseSQLite) { // open the SQLite file PDEBUGPRINTFX(DBG_DBAPI,("Opening SQLite3 file '%s'",fConfigP->fSQLiteFileName.c_str())); int rc = sqlite3_open(fConfigP->fSQLiteFileName.c_str(), &fSQLiteP); fAgentP->checkSQLiteError(rc,fSQLiteP); // set the database (lock) timeout rc = sqlite3_busy_timeout(fSQLiteP, fConfigP->fSQLiteBusyTimeout*1000); fAgentP->checkSQLiteError(rc,fSQLiteP); } else #endif #ifdef ODBCAPI_SUPPORT { fODBCReadStatement = fAgentP->newStatementHandle(getODBCConnectionHandle()); } #else return 510; // no API -> DB error #endif // ODBCAPI_SUPPORT #ifdef SCRIPT_SUPPORT // process mappings init script fWriting=false; fInserting=false; fDeleting=false; fAgentP->fScriptContextDatastore=this; if (!TScriptContext::executeTest(true,fScriptContextP,fConfigP->fFieldMappings.fInitScript,fConfigP->getDSFuncTableP(),fAgentP)) throw TSyncException(" failed"); #endif // read list of all local IDs that are in the current sync set DeleteSyncSet(); #ifdef SYDEBUG string ts; StringObjTimestamp(ts,getPreviousToRemoteSyncCmpRef()); PDEBUGPRINTFX(DBG_DATA,( "Now reading local sync set: last sync to remote was at %s", ts.c_str() )); #endif // we don't need to load the syncset if we are only refreshing from remote // but we also must load it if we can't zap without it on slow refresh // or if the syncset is needed to retrieve items if (!fRefreshOnly || (fSlowSync && apiNeedSyncSetToZap()) || implNeedSyncSetToRetrieve()) { // %%% add checking for aNeedAll and decide to use another (tbd) SQL to get all // records with all fields with this single query // - SELECT localid,modifieddate(,modifiedtime) FROM data WHERE // NOTE: this must always be a SINGLE statement (no %GO() are allowed) ! // Expects 2 or 3 (when date&time are separate) columns: localid,modifieddate(,modifiedtime) sql=fConfigP->fLocalIDAndTimestampFetchSQL; DoDataSubstitutions(sql,fml,0,false); // - prepare prepareSQLStatement(fODBCReadStatement, sql.c_str(), true, "reading of all localIDs/moddates in sync set"); // - issue execSQLStatement(fODBCReadStatement, sql, true, NULL, true); // - fetch data while (fetchNextRow(fODBCReadStatement, true)) { // get local ID and mod date TSyncSetItem *syncsetitemP = new TSyncSetItem; if (!syncsetitemP) throw TSyncException(DEBUGTEXT("cannot allocate new syncsetitem","odds12")); syncsetitemP->isModified=false; syncsetitemP->isModifiedAfterSuspend=false; lineartime_t lastmodified = 0; #ifdef SQLITE_SUPPORT if (fUseSQLite) { // SQLite sInt16 col=0; // SQLite has 0 based column index // - localid syncsetitemP->localid = (const char *)sqlite3_column_text(fSQLiteStmtP,col++); // - modified timestamp lastmodified = dbIntToLineartimeAs(sqlite3_column_int64(fSQLiteStmtP,col++), fConfigP->fLastModDBFieldType, TCTX_UTC); } else #endif { #ifdef ODBCAPI_SUPPORT // ODBC sInt16 col=1; // ODBC has 1 based column index fAgentP->getColumnValueAsString(fODBCReadStatement, col++, syncsetitemP->localid, chs_ascii); // get modified timestamp if (fConfigP->fLastModDBFieldType==dbft_timestamp) getColumnsAsTimestamp(fODBCReadStatement, col, fConfigP->fModifiedTimestamp, lastmodified, TCTX_UTC); else { uInt32 u; fAgentP->getColumnValueAsULong(fODBCReadStatement, col, u); lastmodified = dbIntToLineartimeAs(u, fConfigP->fLastModDBFieldType, TCTX_UTC); } #endif // ODBCAPI_SUPPORT } // compare now syncsetitemP->isModified = lastmodified > getPreviousToRemoteSyncCmpRef(); syncsetitemP->isModifiedAfterSuspend = lastmodified > getPreviousSuspendCmpRef(); #ifdef SYDEBUG StringObjTimestamp(ts,lastmodified); PDEBUGPRINTFX(DBG_DATA+DBG_EXOTIC,( "read local item info in sync set: localid='%s', last modified %s%s%s", syncsetitemP->localid.c_str(), ts.c_str(), syncsetitemP->isModified ? " -> MODIFIED since last sync" : "", syncsetitemP->isModifiedAfterSuspend ? " AND since last suspend" : "" )); #endif // %%% for now, we do not read item contents yet syncsetitemP->itemP=NULL; // no item data // save ID in list fSyncSetList.push_back(syncsetitemP); } // - no more records finalizeSQLStatement(fODBCReadStatement, true); } // not refreshing PDEBUGPRINTFX(DBG_DATA,( "Fetched %ld items from database (not necessarily all visible in SyncSet!)", (long)fSyncSetList.size() )); return sta; } // TODBCApiDS::apiReadSyncSet // fetch actual record from DB by localID localstatus TODBCApiDS::apiFetchItem(TMultiFieldItem &aItem, bool aReadPhase, TSyncSetItem *aSyncSetItemP) { // decide what statement to use SQLHSTMT statement = SQL_NULL_HANDLE; #ifdef SQLITE_SUPPORT if (!fUseSQLite) #endif { #ifdef ODBCAPI_SUPPORT if (aReadPhase) statement = fODBCReadStatement; // we can reuse the statement that is already here else statement = fAgentP->newStatementHandle(getODBCConnectionHandle()); #endif // ODBCAPI_SUPPORT } // get field map list TFieldMapList &fml = fConfigP->fFieldMappings.fFieldMapList; // assume ok localstatus sta=LOCERR_OK; // now fetch try { string sql; TMultiFieldItem *myitemP = (TMultiFieldItem *)&aItem; // execute statements needed to fetch record data sInt16 i=0; uInt16 setno; while (getNextSQLStatement(fConfigP->fDataFetchSQL,i,sql,setno)) { // - something like: SELECT %N FROM datatable WHERE localid=%k AND folderkey=%f resetSQLParameterMaps(); DoDataSubstitutions(sql,fml,setno,false,false,myitemP); // item needed for %k // - prepare parameters prepareSQLStatement(statement, sql.c_str(), true, "getting item data"); bindSQLParameters(statement,true); // - issue execSQLStatement(statement,sql,true,NULL,true); // fetch if (!fetchNextRow(statement,true)) { // - close cursor anyway finalizeSQLStatement(statement,true); // No data for select statement // This is ignored for all setno except setno=0 if (setno==0) { // this record cannot be found sta=404; // not found break; // no need to execute further statements } // setno==0, that is, non-optional data // if optional data is not present, just NOP } // has no data else { // - fill item with fields from SQL query sInt16 col=1; fillFieldsFromSQLResult(statement,col,*myitemP,fml,setno,0); // close cursor of main fetch finalizeSQLStatement(statement,true); // get out params saveAndCleanupSQLParameters(statement,true); } } // while more statements // Finish reading record (if one fetched at all, and not converted to delete etc.) if (sta==LOCERR_OK) { #ifdef ARRAYDBTABLES_SUPPORT // - also read array fields from auxiliary tables, if any if (fHasArrayFields) { // get data from linked array tables as well readArrayFields( statement, *myitemP, fml ); } #endif #ifdef SCRIPT_SUPPORT // - finally process afterread script of entire record fArrIdx=0; // base item fParentKey=myitemP->getLocalID(); fAgentP->fScriptContextDatastore=this; if (!TScriptContext::execute(fScriptContextP,fConfigP->fFieldMappings.fAfterReadScript,fConfigP->getDSFuncTableP(),fAgentP,myitemP,true)) throw TSyncException(" failed"); #endif } #ifdef SQLITE_SUPPORT if (!fUseSQLite) #endif { #ifdef ODBCAPI_SUPPORT // dispose statement handle if we have allocated it if (!aReadPhase) SafeSQLFreeHandle(SQL_HANDLE_STMT,statement); #endif } } catch (...) { #ifdef SQLITE_SUPPORT if (!fUseSQLite) #endif { #ifdef ODBCAPI_SUPPORT // dispose statement handle if we have allocated it if (!aReadPhase) SafeSQLFreeHandle(SQL_HANDLE_STMT,statement); #endif } // re-throw throw; } // return status return sta; } // TODBCApiDS::apiFetchItem /// end of syncset reading phase localstatus TODBCApiDS::apiEndDataRead(void) { #ifdef ODBCAPI_SUPPORT SQLRETURN res=SQL_SUCCESS; #endif localstatus sta = LOCERR_OK; #ifdef ODBCAPI_SUPPORT // release the statement handle (if any) try { DEBUGPRINTFX(DBG_DATA+DBG_DBAPI,("EndDataRead: committing read phase")); if (fODBCReadStatement!=SQL_NULL_HANDLE) { res=SafeSQLFreeHandle(SQL_HANDLE_STMT,fODBCReadStatement); fODBCReadStatement=SQL_NULL_HANDLE; checkConnectionError(res); // Commit the transaction (to make sure a new one begins when starting to write) SafeSQLEndTran(SQL_HANDLE_DBC,getODBCConnectionHandle(),SQL_COMMIT); checkConnectionError(res); } } catch (exception &e) { PDEBUGPRINTFX(DBG_ERROR,("******** EndDataRead exception: %s",e.what())); sta=510; } #endif // ODBCAPI_SUPPORT return sta; } // TODBCApiDS::apiEndDataRead // start of data write localstatus TODBCApiDS::apiStartDataWrite(void) { // create statement handle for writing if we don't have one already #ifdef SQLITE_SUPPORT if (!fUseSQLite) #endif { #ifdef ODBCAPI_SUPPORT // for ODBC only if (fODBCWriteStatement==SQL_NULL_HANDLE) fODBCWriteStatement = fAgentP->newStatementHandle(getODBCConnectionHandle()); #endif } return LOCERR_OK; } // TODBCApiDS::apiStartDataWrite // generate new LocalID into fLastGeneratedLocalID. // - can be used with %X,%x escape in SQL statements. void TODBCApiDS::nextLocalID(TSpecialIDMode aMode,SQLHSTMT aStatement) { if (aMode!=sidm_none) { createLocalID(fLastGeneratedLocalID,aMode); } else { if (fConfigP->fDetermineNewIDOnce) { // we use incremented starting value StringObjPrintf(fLastGeneratedLocalID,"%ld",(long)fNextLocalID++); } else { #ifdef SCRIPT_SUPPORT // first check for script if (!fConfigP->fLocalIDScript.empty()) { // call script tro obtain new localID TItemField *resP=NULL; fAgentP->fScriptContextDatastore=this; if (!TScriptContext::executeWithResult( resP, // can be default result or NULL, will contain result or NULL if no result fScriptContextP, fConfigP->fLocalIDScript, fConfigP->getDSFuncTableP(), // context function table fAgentP, // context data (myself) NULL, false, NULL, false )) throw TSyncException(" failed"); if (resP) { // get ID resP->getAsString(fLastGeneratedLocalID); delete resP; } } #endif // get new statement if none was passed string sql=fConfigP->fObtainNewLocalIDSql; // obtainNewLocalIDSql can be empty, for example if ID is returned in an // out param from the inserting statement(s) or generated by fLocalIDScript if (!sql.empty()) { #ifdef SQLITE_SUPPORT if (fUseSQLite) { throw TSyncException("SQLite does not support "); } else #endif { #ifdef ODBCAPI_SUPPORT // there is a statement to execute SQLHSTMT statement=aStatement; if (!statement) statement=fAgentP->newStatementHandle(getODBCConnectionHandle()); // issue the SQL try { // execute query BEFORE insert to get unique ID value for new record DoSQLSubstitutions(sql); execSQLStatement(statement,sql,true,"getting local ID for new record",true); // - fetch result row SQLRETURN res=SafeSQLFetch(statement); fAgentP->checkStatementError(res,statement); // - get value of first field as string if (!fAgentP->getColumnValueAsString(statement,1,fLastGeneratedLocalID,chs_ascii)) { throw TSyncException("Failed getting new localID"); } // close cursor (for re-using statement handle, this is needed) SafeSQLCloseCursor(statement); } catch (...) { if (!aStatement) SafeSQLFreeHandle(SQL_HANDLE_STMT,statement); throw; } // get rid of local statement if (!aStatement) SafeSQLFreeHandle(SQL_HANDLE_STMT,statement); #endif } } } } PDEBUGPRINTFX(DBG_DATA,("Generated new localID: %s",fLastGeneratedLocalID.c_str())); } // TODBCApiDS::nextLocalID // private helper: start writing item void TODBCApiDS::startWriteItem(void) { // make sure transaction is complete if we are in item commit mode #ifdef ODBCAPI_SUPPORT SQLRETURN res; if (fConfigP->fCommitItems) { PDEBUGPRINTFX(DBG_DATA+DBG_DBAPI,("startWriteItem: commititems=true, item processing starts with new transaction")); res=SafeSQLEndTran(SQL_HANDLE_DBC,getODBCConnectionHandle(),SQL_COMMIT); checkConnectionError(res); } #endif } // TODBCApiDS::startWriteItem // private helper: end writing item void TODBCApiDS::endWriteItem(void) { #ifdef ODBCAPI_SUPPORT SQLRETURN res; if (fConfigP->fCommitItems) { PDEBUGPRINTFX(DBG_DATA+DBG_DBAPI,("endWriteItem: commititems=true, commit changes to DB")); res=SafeSQLEndTran(SQL_HANDLE_DBC,getODBCConnectionHandle(),SQL_COMMIT); checkConnectionError(res); } #endif } // TODBCApiDS::endWriteItem // add new item to datastore, returns created localID localstatus TODBCApiDS::apiAddItem(TMultiFieldItem &aItem, string &aLocalID) { localstatus sta=LOCERR_OK; startWriteItem(); // get field map list TFieldMapList &fml = fConfigP->fFieldMappings.fFieldMapList; try { // determine ID aLocalID.erase(); // make sure we don't assign bogus ID (fObtainNewIDAfterInsert case) if (fConfigP->fSpecialIDMode==sidm_none && !fConfigP->fObtainNewIDAfterInsert) { // No repeatable ID creator, and not obtain-after-insert: do it once here // - create next local ID using standard method nextLocalID(sidm_none,fODBCWriteStatement); // - use it aLocalID=fLastGeneratedLocalID; } // if no special algorithm for IDs (such as system time/random based) // add new record sInt16 rep=0; do { try { // - make sure we have a new ID in case it is time based if (fConfigP->fSpecialIDMode!=sidm_none) { // - create next local ID using special method nextLocalID(fConfigP->fSpecialIDMode,fODBCWriteStatement); // - use it aLocalID=fLastGeneratedLocalID; } // - assign localID to be used (empty here if fObtainNewIDAfterInsert=true) aItem.setLocalID(aLocalID.c_str()); #ifdef SCRIPT_SUPPORT // - process beforewrite script fWriting=true; fInserting=true; // might be reset by ADDBYUPDATING() fDeleting=false; fAgentP->fScriptContextDatastore=this; if (!TScriptContext::execute(fScriptContextP,fConfigP->fFieldMappings.fBeforeWriteScript,fConfigP->getDSFuncTableP(),fAgentP,&aItem,true)) throw TSyncException(" failed"); if (!fInserting) { // inserting was turned off by beforewritescript, in particular by ADDBYUPDATING() // -> perform an update using the localid set by ADDBYUPDATING() PDEBUGPRINTFX(DBG_DATA+DBG_DBAPI,("Updating existing DB row '%s' instead of inserting (ADDBYUPDATING)",aItem.getLocalID())); // - return localID to caller (for caller, this looks like a regular add) aLocalID = aItem.getLocalID(); // - perform update instead of insert if (!IssueDataWriteSQL( fODBCWriteStatement, fConfigP->fDataUpdateSQL, "updating instead of inserting", true, // for update fml, // field map &aItem // item to read values and localid from )) { // not found in data table - do a normal add (even if ADDBYUPDATING() wanted an update) fInserting = true; // revert back to inserting PDEBUGPRINTFX(DBG_ERROR,("Updating existing not possible -> reverting to insert")); } } // check if we still need to insert if (fInserting) #endif { // Normal insert // - issue statement(s) #ifdef ODBCAPI_SUPPORT bool hasdata= #endif IssueDataWriteSQL( fODBCWriteStatement, fConfigP->fDataInsertSQL, "adding record", false, // not for update fml, // field map &aItem // item to read values and localid from ); // copy ID in case we've got it via an output param aLocalID=aItem.getLocalID(); #ifdef SQLITE_SUPPORT if (!fUseSQLite) #endif { #ifdef ODBCAPI_SUPPORT if (fConfigP->fInsertReturnsID) { // insert statement should return ID of record inserted if (hasdata) { SQLRETURN res=SafeSQLFetch(fODBCWriteStatement); if (fAgentP->checkStatementHasData(res,fODBCWriteStatement)) { // get id (must be in first result column of first and only result row) if (!fAgentP->getColumnValueAsString(fODBCWriteStatement,1,fLastGeneratedLocalID,chs_ascii)) { throw TSyncException("Failed getting localID from result set"); } // - use it aLocalID=fLastGeneratedLocalID; } else hasdata=false; // - close cursor anyway SafeSQLCloseCursor(fODBCWriteStatement); } if (!hasdata) throw TSyncException(" statement did not return insert ID"); } #endif // ODBCAPI_SUPPORT } } // normal insert // done ok break; } catch (TSyncException &e) { // error while issuing write if (++rep>fConfigP->fInsertRetries) throw; // error, let it show PDEBUGPRINTFX(DBG_DATA+DBG_DBAPI,( "Insert failed with localid='%s': %s --> retrying", aLocalID.c_str(), e.what() )); // repeat once more continue; } } while(true); // check if we want to use local ID created implicitly by inserting row #ifdef SCRIPT_SUPPORT if (fInserting) // only if really inserting (but not in ADDBYUPDATING() case) #endif { if (!fConfigP->fInsertReturnsID && fConfigP->fSpecialIDMode==sidm_none && fConfigP->fObtainNewIDAfterInsert) { // determine new ID AFTER insert #ifdef SQLITE_SUPPORT if (fUseSQLite) { // For SQLite, localID is always autocreated ROWID, get it now StringObjPrintf(aLocalID,"%lld",sqlite3_last_insert_rowid(fSQLiteP)); PDEBUGPRINTFX(DBG_DBAPI,("sqlite3_last_insert_rowid() returned %s",aLocalID.c_str())); } else #endif // SQLITE_SUPPORT { #ifdef ODBCAPI_SUPPORT // get local ID using standard method (SQL statement to get ID) nextLocalID(sidm_none,fODBCWriteStatement); // - use it aLocalID=fLastGeneratedLocalID; #endif // ODBCAPI_SUPPORT } } // make sure localID is known now aItem.setLocalID(aLocalID.c_str()); } // determine ID of inserted record // also write array fields, if any #ifdef ARRAYDBTABLES_SUPPORT if (fHasArrayFields) { // write data to linked array tables as well // - now write writeArrayFields( fODBCWriteStatement, aItem, fml, #ifdef SCRIPT_SUPPORT fInserting // if really performed insert (i.e. not ADDBYUPDATING()), child record cleaning is not necessary (but can be forced by fAlwaysCleanArray) #else true // is an insert, so child record cleaning not necessary (but can be forced by fAlwaysCleanArray) #endif ); } #endif #ifdef SCRIPT_SUPPORT // process oevrall afterwrite script // Note: fInserting is still valid from above (and can be false in ADDBYUPDATING() case) fWriting=true; fDeleting=false; fAgentP->fScriptContextDatastore=this; if (!TScriptContext::execute(fScriptContextP,fConfigP->fFieldMappings.fAfterWriteScript,fConfigP->getDSFuncTableP(),fAgentP,&aItem,true)) throw TSyncException(" failed"); #endif } catch (...) { endWriteItem(); throw; } // end writing endWriteItem(); return sta; } // TODBCApiDS::apiAddItem // update existing item in datastore, returns 404 if item not found localstatus TODBCApiDS::apiUpdateItem(TMultiFieldItem &aItem) { localstatus sta=LOCERR_OK; startWriteItem(); // get field map list TFieldMapList &fml = fConfigP->fFieldMappings.fFieldMapList; try { // update record with this localID #ifdef SCRIPT_SUPPORT // - process beforewrite script fWriting=true; fInserting=false; fDeleting=false; fAgentP->fScriptContextDatastore=this; if (!TScriptContext::execute(fScriptContextP,fConfigP->fFieldMappings.fBeforeWriteScript,fConfigP->getDSFuncTableP(),fAgentP,&aItem,true)) throw TSyncException(" failed"); #endif // - issue if (!IssueDataWriteSQL( fODBCWriteStatement, fConfigP->fDataUpdateSQL, "replacing record", true, // for update fml, // field map &aItem // item to read values and localid from )) { // not found in data table sta=404; } else { // also write array fields, if any #ifdef ARRAYDBTABLES_SUPPORT if (fHasArrayFields) { // write data to linked array tables as well writeArrayFields( fODBCWriteStatement, aItem, // item to read values from fml, false // is not an insert, update needs erasing first in all cases! ); } #endif #ifdef SCRIPT_SUPPORT // process oevrall afterwrite script fWriting=true; fInserting=false; fDeleting=false; fAgentP->fScriptContextDatastore=this; if (!TScriptContext::execute(fScriptContextP,fConfigP->fFieldMappings.fAfterWriteScript,fConfigP->getDSFuncTableP(),fAgentP,&aItem,true)) throw TSyncException(" failed"); #endif } } catch (...) { endWriteItem(); throw; } // end writing endWriteItem(); return sta; } // TODBCApiDS::apiUpdateItem // delete existing item in datastore, returns 211 if not existing any more localstatus TODBCApiDS::apiDeleteItem(TMultiFieldItem &aItem) { localstatus sta=LOCERR_OK; startWriteItem(); // get field map list TFieldMapList &fml = fConfigP->fFieldMappings.fFieldMapList; try { // - issue statements for delete (could be UPDATE or DELETE) if (!IssueDataWriteSQL( fODBCWriteStatement, fConfigP->fDataDeleteSQL, "deleting record", false, // not for update fml, // field map &aItem // item to read values and localid from )) { sta=211; // item not deleted, was not there any more } else { // also delete array fields, if any #ifdef ARRAYDBTABLES_SUPPORT // get data from linked array tables as well deleteArrayFields( fODBCWriteStatement, aItem, fConfigP->fFieldMappings.fFieldMapList ); #endif #ifdef SCRIPT_SUPPORT // process overall afterwrite script fWriting=true; fInserting=false; fDeleting=true; fAgentP->fScriptContextDatastore=this; if (!TScriptContext::execute(fScriptContextP,fConfigP->fFieldMappings.fAfterWriteScript,fConfigP->getDSFuncTableP(),fAgentP,&aItem,true)) throw TSyncException(" failed"); #endif } } catch (...) { endWriteItem(); throw; } // end writing endWriteItem(); return sta; } // TODBCApiDS::apiDeleteItem /// @brief Load admin data from ODBC database /// Must search for existing target record matching the triple (aDeviceID,aDatabaseID,aRemoteDBID) /// - if there is a matching record: load it /// - if there is no matching record, set fFirstTimeSync=true. The implementation may already create a /// new record with the key (aDeviceID,aDatabaseID,aRemoteDBID) and initialize it with the data from /// the items as shown below. At least, fTargetKey must be set to a value that will allow apiSaveAdminData to /// update the record. In case implementation chooses not create the record only in apiSaveAdminData, it must /// buffer the triple (aDeviceID,aDatabaseID,aRemoteDBID) such that it is available at apiSaveAdminData. /// If a record exists implementation must load the following items: /// - fTargetKey = some key value that can be used to re-identify the target record later at SaveAdminData. /// If the database implementation has other means to re-identify the target, this can be /// left unassigned. /// - fLastRemoteAnchor = anchor string used by remote party for last session (and saved to DB then) /// - fPreviousSyncTime = anchor (beginning of session) timestamp of last session. /// - fPreviousToRemoteSyncCmpRef = Reference time to determine items modified since last time sending data to remote /// - fPreviousToRemoteSyncIdentifier = string identifying last session that sent data to remote (needs only be saved /// if derived datastore cannot work with timestamps and has its own identifier). /// - fMapTable = list containing map entries. The implementation must load all map entries /// related to the current sync target identified by the triple of (aDeviceID,aDatabaseID,aRemoteDBID) /// or by fTargetKey. The entries added to fMapTable must have "changed", "added" and "deleted" flags /// set to false. /// For resumable datastores: /// - fMapTable = In addition to the above, the markforresume flag must be saved in the mapflags // when it is not equal to the savedmark flag - independently of added/deleted/changed. /// - fResumeAlertCode = alert code of current suspend state, 0 if none /// - fPreviousSuspendCmpRef = reference time of last suspend (used to detect items modified during a suspend / resume) /// - fPreviousSuspendIdentifier = identifier of last suspend (used to detect items modified during a suspend / resume) /// (needs only be saved if derived datastore cannot work with timestamps and has /// its own identifier) /// - fPendingAddMaps = map. The implementation must load all all pending maps (client only) into /// fPendingAddMaps (and fUnconfirmedMaps must be left empty). /// - fTempGUIDMap = map. The implementation must save all entries as temporary LUID to GUID mappings /// (server only) localstatus TODBCApiDS::apiLoadAdminData( const char *aDeviceID, // remote device URI (device ID) const char *aDatabaseID, // database ID const char *aRemoteDBID // database ID of remote device ) { #ifndef HAS_SQL_ADMIN return 510; // must use plugin, no ODBC #else // HAS_SQL_ADMIN localstatus sta=0; // assume ok string sql; // ODBC based target/map fODBCAdminData=true; // determine Folder key, if any sta=LOCERR_OK; // - determine folder name, if any string bname,foldername; analyzeName(aDatabaseID,&bname,&foldername); // - search on foldername SQLRETURN res; SQLHSTMT statement=fAgentP->newStatementHandle(getODBCConnectionHandle()); try { // get SQL sql = fConfigP->fFolderKeySQL; if (!sql.empty()) { // substitute: %F = foldername StringSubst(sql,"%F",foldername,2,fConfigP->sqlPrepCharSet(),fConfigP->fDataLineEndMode,fConfigP->fQuotingMode); DoSQLSubstitutions(sql); // for %u = userkey, %d=devicekey // issue execSQLStatement(statement,sql,true,"getting folder key",false); // - fetch result row res=SafeSQLFetch(statement); if (!fAgentP->checkStatementHasData(res,statement)) { // No data: user does not have permission for this folder PDEBUGPRINTFX(DBG_ERROR,("apiLoadAdminData: User has no permission for acessing folder '%s'",foldername.c_str())); sta=403; } else { // get folder key fAgentP->getColumnValueAsString(statement,1,fFolderKey,chs_ascii); PDEBUGPRINTFX(DBG_ADMIN,("apiLoadAdminData: Folder key is '%s'",fFolderKey.c_str())); } SafeSQLCloseCursor(statement); } // if folderkeySQL else { // no folderkey, just copy user key fFolderKey=fAgentP->getUserKey(); } if (sta==LOCERR_OK) { // now determine sync target key bool madenew=false; do { // get SQL sql=fConfigP->fGetSyncTargetSQL; // substitute standard: %f=folderkey, %u=userkey, %d=devicekey, %t=targetkey DoSQLSubstitutions(sql); // substitute specific: %D=deviceid, %P=devicedbpath StringSubst(sql,"%D",aDeviceID,2,-1,fConfigP->sqlPrepCharSet(),fConfigP->fDataLineEndMode,fConfigP->fQuotingMode); StringSubst(sql,"%P",aRemoteDBID,2,-1,fConfigP->sqlPrepCharSet(),fConfigP->fDataLineEndMode,fConfigP->fQuotingMode); // issue execSQLStatement(statement,sql,true,"getting target info",false); // - fetch result row res=SafeSQLFetch(statement); if (!fAgentP->checkStatementHasData(res,statement)) { if (madenew) throw TSyncException("apiLoadAdminData: new created SyncTarget is not accessible"); // target does not yet exist, create new DEBUGPRINTFX(DBG_ADMIN,("apiLoadAdminData: Target does not yet exist, create new")); SafeSQLCloseCursor(statement); // create new sync target entry sql=fConfigP->fNewSyncTargetSQL; // substitute standard: %f=folderkey, %u=userkey, %d=devicekey, %t=targetkey DoSQLSubstitutions(sql); // substitute specific: %D=deviceid, %P=devicedbpath StringSubst(sql,"%D",aDeviceID,2,-1,fConfigP->sqlPrepCharSet(),fConfigP->fDataLineEndMode,fConfigP->fQuotingMode); StringSubst(sql,"%P",aRemoteDBID,2,-1,fConfigP->sqlPrepCharSet(),fConfigP->fDataLineEndMode,fConfigP->fQuotingMode); // now issue execSQLStatement(statement,sql,false,"creating new target info",false); // try to read again madenew=true; continue; } else { // get data: IN ASCENDING COL ORDER!!! sInt16 col=1; fAgentP->getColumnValueAsString(statement,col++,fTargetKey,chs_ascii); fAgentP->getColumnValueAsString(statement,col++,fLastRemoteAnchor,chs_ascii); PDEBUGPRINTFX(DBG_ADMIN,("apiLoadAdminData: Target key is '%s'",fTargetKey.c_str())); PDEBUGPRINTFX(DBG_ADMIN,("apiLoadAdminData: Saved Remote Sync Anchor is '%s'",fLastRemoteAnchor.c_str())); // first sync if target record is new or if remote anchor is (still) empty // NOTE: this is because only a successful sync makes next attempt non-firsttime! fFirstTimeSync=madenew || fLastRemoteAnchor.empty(); // last to remote sync reference date/time OR start of last session date/time // Note: If we DON'T HAVE fSyncTimeStampAtEnd, but HAVE fOneWayFromRemoteSupported, // this is NOT the reference time here, but the session start time; // the reference time is saved separately (see below) lineartime_t dltime; getColumnsAsTimestamp(statement,col,fConfigP->fSyncTimestamp,dltime, TCTX_UTC); if (!fConfigP->fSyncTimeStampAtEnd && fConfigP->fOneWayFromRemoteSupported) fPreviousSyncTime = dltime; else { fPreviousToRemoteSyncCmpRef = dltime; } // In case we DON'T HAVE fSyncTimeStampAtEnd, and DON'T HAVE fOneWayFromRemoteSupported, // the above loaded fPreviousToRemoteSyncCmpRef is the ONLY time we get, so for this // case we won't get separate session start time below, so initialize it here. fPreviousSyncTime = dltime; // check for separate start-of-session time if (fConfigP->fSyncTimeStampAtEnd) { // @note For new V3.0 architecture, this is now a bit the wrong way around, as // we only need the anchor (fPreviousSyncTime) and a reference for the // last-to-remote sync (fPreviousToRemoteSyncCmpRef). However, to remain compatible with // existing DB schemas we need to swap values a bit. // In case database cannot explicitly set modification timestamps, we need the start-of-session // (which is used for creation of anchor for remote) and we need a comparison reference. // - override anchor time with separately stored value getColumnsAsTimestamp(statement,col,fConfigP->fSyncTimestamp,fPreviousSyncTime, TCTX_UTC); } // get date and time of last two-way-sync if database has it stored separately // Note: when we have fSyncTimeStampAtEnd, fPreviousToRemoteSyncCmpRef is already set here, // but we'll get it again (it is redundantly stored if we have both fSyncTimeStampAtEnd and fPreviousToRemoteSyncCmpRef) // - get from DB if available if (fConfigP->fOneWayFromRemoteSupported) { // one-way from remote is supported: we have a separate date for last sync that sent changes to remote // - override fPreviousToRemoteSyncCmpRef (when one-way-from-remote is supported, this is not // necessarily same as start of last session (fPreviousSyncTime) any more) getColumnsAsTimestamp(statement,col,fConfigP->fSyncTimestamp,fPreviousToRemoteSyncCmpRef, TCTX_UTC); if (fConfigP->fSyncTimeStampAtEnd) { // Note: for V3.0, this may be redundant and already loaded in case we also have fSyncTimeStampAtEnd getColumnsAsTimestamp(statement,col,fConfigP->fSyncTimestamp,fPreviousToRemoteSyncCmpRef, TCTX_UTC); } } // get opaque reference identifier from DB, if it stores them // (otherwise, implMakeAdminReady will create ISO timestamp strings as standard identifiers) if (fConfigP->fStoreSyncIdentifiers) { // we have stored the identifier (and do now know its meaning, it's just a string that // the DB implementation needs to sort out changed items in the datastore fAgentP->getColumnValueAsString(statement,col++,fPreviousToRemoteSyncIdentifier,chs_ascii); } // Summarize #ifdef SYDEBUG string ts; StringObjTimestamp(ts,fPreviousSyncTime); DEBUGPRINTFX(DBG_ADMIN,("apiLoadAdminData: start time of last sync is: %s",ts.c_str())); StringObjTimestamp(ts,fPreviousToRemoteSyncCmpRef); DEBUGPRINTFX(DBG_ADMIN,("apiLoadAdminData: compare reference time of last-to-remote-sync is: %s",ts.c_str())); DEBUGPRINTFX(DBG_ADMIN,("apiLoadAdminData: stored reference identifier of last-to-remote-sync is: '%s'",fPreviousToRemoteSyncIdentifier.c_str())); #endif // Resume support if there if (fConfigP->fResumeSupport) { // next column is alert code for resuming uInt32 templong; fAgentP->getColumnValueAsULong(statement,col++,templong); fResumeAlertCode=templong; PDEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,("apiLoadAdminData: fResumeAlertCode is %hd",fResumeAlertCode)); // next column(s) is/are last suspend date/time getColumnsAsTimestamp(statement,col,fConfigP->fSyncTimestamp,fPreviousSuspendCmpRef, TCTX_UTC); #ifdef SYDEBUG StringObjTimestamp(ts,fPreviousSuspendCmpRef); PDEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,("apiLoadAdminData: compare reference time of last suspend is %s",ts.c_str())); #endif // Get last suspend identifier from DB if (fConfigP->fStoreSyncIdentifiers) { // next line is opaque string idenifier of last sync with transfer to remote fAgentP->getColumnValueAsString(statement,col++,fPreviousSuspendIdentifier,chs_ascii); PDEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,("apiLoadAdminData: stored reference identifier of last suspend is '%s'",fPreviousSuspendIdentifier.c_str())); } // get partial item suspend data, if any: // - Source,Target,LastStatus,PIState,Totalsize,Unconfirmedsize,StoredSize,BLOB if (fConfigP->fResumeItemSupport) { // - last item URIs fAgentP->getColumnValueAsString(statement,col++,fLastSourceURI,chs_ascii); fAgentP->getColumnValueAsString(statement,col++,fLastTargetURI,chs_ascii); // - last status fAgentP->getColumnValueAsULong(statement,col++,templong); fLastItemStatus=templong; // - partial item state fAgentP->getColumnValueAsULong(statement,col++,templong); fPartialItemState=(TPartialItemState)templong; // - sizes fAgentP->getColumnValueAsULong(statement,col++,fPITotalSize); fAgentP->getColumnValueAsULong(statement,col++,fPIUnconfirmedSize); fAgentP->getColumnValueAsULong(statement,col++,fPIStoredSize); // - the BLOB data itself string blob; fAgentP->getColumnValueAsString(statement,col++,blob,chs_ascii,true); // - move it into data if (fPIStoredDataP && fPIStoredDataAllocated) smlLibFree(fPIStoredDataP); fPIStoredDataAllocated=false; fPIStoredDataP=smlLibMalloc(blob.size()+1); // plus terminator for string interpretation if (fPIStoredDataP) { fPIStoredDataAllocated=true; smlLibMemcpy(fPIStoredDataP,blob.c_str(),blob.size()); if (fPIStoredSize>blob.size()) fPIStoredSize=blob.size(); // security *((uInt8 *)fPIStoredDataP+fPIStoredSize)=0; // string terminator } PDEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,( "apiLoadAdminData: partial item resume info: src='%s', targ='%s', lastStatus=%hd, state=%hd, totalSz=%ld, unconfSz=%ld, storedSz=%ld", fLastSourceURI.c_str(), fLastTargetURI.c_str(), fLastItemStatus, (TSyError)fPartialItemState, fPITotalSize, fPIUnconfirmedSize, fPIStoredSize )); } } SafeSQLCloseCursor(statement); // now read current map entries of target sql=fConfigP->fMapFetchAllSQL; DoSQLSubstitutions(sql); // only folderkey,targetkey,userkey is available // - issue execSQLStatement(statement,sql,true,"reading map into internal list",false); // - fetch results do { res=SafeSQLFetch(statement); // check for end if (!fAgentP->checkStatementHasData(res,statement)) break; // get map entry TMapEntry entry; fAgentP->getColumnValueAsString(statement,1,entry.localid,chs_ascii); fAgentP->getColumnValueAsString(statement,2,entry.remoteid,chs_ascii); if (fConfigP->fResumeSupport) { // we have a separate entry type uInt32 et; fAgentP->getColumnValueAsULong(statement,3,et); if (et>=numMapEntryTypes) entry.entrytype = mapentry_invalid; else entry.entrytype = (TMapEntryType)et; // and some map flags fAgentP->getColumnValueAsULong(statement,4,entry.mapflags); } else { entry.mapflags=0; // no flags stored entry.entrytype=mapentry_normal; // normal entry } PDEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,( "read map entry (type=%s): localid='%s', remoteid='%s', mapflags=0x%lX", MapEntryTypeNames[entry.entrytype], entry.localid.c_str(), entry.remoteid.c_str(), entry.mapflags )); // save entry in list entry.changed=false; // not yet changed entry.added=false; // already there // remember saved state of suspend mark entry.markforresume=false; // not yet marked for this session (mark of last session is in mapflag_useforresume!) entry.savedmark=entry.mapflags & mapflag_useforresume; // IMPORTANT: non-normal entries must be saved as deleted in the main map - they will be re-activated at the // next save if needed entry.deleted = entry.entrytype!=mapentry_normal; // only normal ones may be saved as existing in the main map // save to main map list anyway to allow differential SQL updates to map table (instead of writing everything all the time) fMapTable.push_back(entry); // now save special maps to extra lists according to type // Note: in the main map, these are marked deleted. Before the next saveAdminData, these will // be re-added (=re-activated) from the extra lists if they still exist. switch (entry.entrytype) { #ifdef SYSYNC_SERVER case mapentry_tempidmap: if (IS_SERVER) fTempGUIDMap[entry.remoteid]=entry.localid; // tempGUIDs are accessed by remoteID=tempID break; #endif #ifdef SYSYNC_CLIENT case mapentry_pendingmap: if (IS_CLIENT) fPendingAddMaps[entry.localid]=entry.remoteid; break; #endif } } while(true); // no more records SafeSQLCloseCursor(statement); // done break; } // target record found } while(true); } // if ok if (sta==LOCERR_OK) { // determine how to create new IDs for database fNextLocalID=-1; // no global ID, must be determined at actual insert // for some databases w/o usable ID variable (FMPro), starting point for ids // might be some "SELECT MAX()" query, which would be executed here if (fConfigP->fDetermineNewIDOnce) { uInt32 maxid; SQLRETURN res; sql=fConfigP->fObtainNewLocalIDSql.c_str(); DoSQLSubstitutions(sql); execSQLStatement(statement,sql,true,"Next-to-be-used localID (determined once in makeAdminReady)",false); // - fetch result row res=SafeSQLFetch(statement); fAgentP->checkStatementError(res,statement); // - get value of first field as long if (fAgentP->getColumnValueAsULong(statement,1,maxid)) { // next ID found if (maxidfMinNextID) maxid=fConfigP->fMinNextID; // don't use value smaller than defined minimum } else { // no max value found, start at MinNextID maxid=fConfigP->fMinNextID; } SafeSQLCloseCursor(statement); // now assign fNextLocalID=maxid; #ifdef SYDEBUG PDEBUGPRINTFX(DBG_ADMIN,("apiLoadAdminData: next local ID is %ld",fNextLocalID)); #endif } } // if ok // release the statement handle SafeSQLFreeHandle(SQL_HANDLE_STMT,statement); } catch (...) { // release the statement handle SafeSQLFreeHandle(SQL_HANDLE_STMT,statement); throw; } PDEBUGPRINTFX(DBG_ADMIN,("apiLoadAdminData: Number of map entries read = %ld",fMapTable.size())); return sta; #endif // HAS_SQL_ADMIN } // TODBCApiDS::apiLoadAdminData /// @brief Save admin data to ODBC database /// @param[in] aSessionFinished if true, this is a end-of-session save (and not only a suspend save) /// Must save to the target record addressed at LoadAdminData() by the triple (aDeviceID,aDatabaseID,aRemoteDBID) /// Implementation must save the following items: /// - fLastRemoteAnchor = anchor string used by remote party for this session (and saved to DB then) /// - fPreviousSyncTime = anchor (beginning of session) timestamp of this session. /// - fPreviousToRemoteSyncCmpRef = Reference time to determine items modified since last time sending data to remote /// - fPreviousToRemoteSyncIdentifier = string identifying last session that sent data to remote (needs only be saved /// if derived datastore cannot work with timestamps and has its own identifier). /// - fMapTable = list containing map entries. The implementation must save all map entries /// that have changed, are new or are deleted. See below for additional resume requirements. /// For resumable datastores: /// - fMapTable = In addition to the above, the markforresume flag must be saved in the mapflags // when it is not equal to the savedmark flag - independently of added/deleted/changed. /// - fResumeAlertCode = alert code of current suspend state, 0 if none /// - fPreviousSuspendCmpRef = reference time of last suspend (used to detect items modified during a suspend / resume) /// - fPreviousSuspendIdentifier = identifier of last suspend (used to detect items modified during a suspend / resume) /// (needs only be saved if derived datastore cannot work with timestamps and has /// its own identifier) /// - fPendingAddMaps and fUnconfirmedMaps = map. The implementation must save all entries as /// pending maps (client only). Note that fPendingAddMaps might contain temporary localIDs, /// so call dsFinalizeLocalID() to ensure these are converted to final before saving. /// - fTempGUIDMap = map. The implementation must save all entries as temporary LUID to GUID mappings /// (server only) localstatus TODBCApiDS::apiSaveAdminData(bool aSessionFinished, bool aSuccessful) { #ifndef HAS_SQL_ADMIN return 510; // must use plugin, no ODBC #else SQLRETURN res; localstatus sta=LOCERR_OK; try { // if data is not handled by ODBC, we might have no write statement here, so open one if (fODBCWriteStatement==SQL_NULL_HANDLE) fODBCWriteStatement = fAgentP->newStatementHandle(getODBCConnectionHandle()); // now save target head record admin data sta=updateSyncTarget(fODBCWriteStatement,aSessionFinished && aSuccessful); if (sta==LOCERR_OK) { // then apply Map modifications (target detail records) sta=updateODBCMap(fODBCWriteStatement,aSessionFinished && aSuccessful); } // dispose of Write statement handle if (fODBCWriteStatement!=SQL_NULL_HANDLE && aSessionFinished) { DEBUGPRINTFX(DBG_DBAPI,("SaveAdminData: End of session - Freeing Write statement handle...")); res=SafeSQLFreeHandle(SQL_HANDLE_STMT,fODBCWriteStatement); fODBCWriteStatement=SQL_NULL_HANDLE; checkConnectionError(res); } // commit transaction if (fODBCConnectionHandle!=SQL_NULL_HANDLE) { // commit DB transaction DEBUGPRINTFX(DBG_DBAPI,("SaveAdminData(commit): Committing DB transaction...")); res=SafeSQLEndTran(SQL_HANDLE_DBC,getODBCConnectionHandle(),SQL_COMMIT); checkConnectionError(res); } } catch (exception &e) { PDEBUGPRINTFX(DBG_ERROR,("******** SaveAdminData exception: %s",e.what())); sta=510; // failed, DB error } // return status return sta; #endif // HAS_SQL_ADMIN } // TODBCApiDS::apiSaveAdminData // - end DB data write sequence (but not yet admin data) localstatus TODBCApiDS::apiEndDataWrite(string &aThisSyncIdentifier) { // we do not have a separate sync identifier aThisSyncIdentifier.erase(); // make sure we commit the transaction here in case admin data is not in ODBC #ifdef ODBCAPI_SUPPORT try { SQLRETURN res; if (fODBCWriteStatement!=SQL_NULL_HANDLE) { DEBUGPRINTFX(DBG_DBAPI,("EndDBDataWrite: we have no ODBC admin data, freeing Write statement handle now...")); res=SafeSQLFreeHandle(SQL_HANDLE_STMT,fODBCWriteStatement); fODBCWriteStatement=SQL_NULL_HANDLE; checkConnectionError(res); } // commit DB transaction if (fODBCConnectionHandle!=SQL_NULL_HANDLE) { DEBUGPRINTFX(DBG_DBAPI,("EndDBDataWrite: ...and commit DB transaction")); res=SafeSQLEndTran(SQL_HANDLE_DBC,getODBCConnectionHandle(),SQL_COMMIT); checkConnectionError(res); } } catch (exception &e) { PDEBUGPRINTFX(DBG_ERROR,("******** EndDBDataWrite exception: %s",e.what())); return 510; } #endif // ODBCAPI_SUPPORT return LOCERR_OK; } // TODBCApiDS::apiEndDataWrite /* end of TODBCApiDS implementation */ #ifdef STREAMFIELD_SUPPORT // TODBCFieldProxy // =============== TODBCFieldProxy::TODBCFieldProxy( TODBCApiDS *aODBCdsP, TODBCFieldMapItem *aFieldMapP, const char *aMasterKey, const char *aDetailKey ) { // save values fODBCdsP = aODBCdsP; fFieldMapP = aFieldMapP; fMasterKey = aMasterKey; fDetailKey = aDetailKey; fFetched = false; fValue.erase(); } // TODBCFieldProxy::TODBCFieldProxy TODBCFieldProxy::~TODBCFieldProxy() { // nop at this time } // TODBCFieldProxy::~TODBCFieldProxy // fetch BLOB from DPAPI void TODBCFieldProxy::fetchBlob(void) { if (!fFetched) { // if do not have anything yet and need something, read it now string sql = fFieldMapP->fReadBlobSQL; // the only possible substitutions are %k and %K StringSubst(sql,"%k",fMasterKey,2); // the localID of the entire record StringSubst(sql,"%K",fDetailKey,2); // the key of this specific array element // fetch now SQLHSTMT statement = 0; #ifdef SQLITE_SUPPORT if (!fODBCdsP->fUseSQLite) #endif { #ifdef ODBCAPI_SUPPORT statement=fODBCdsP->fAgentP->newStatementHandle(fODBCdsP->getODBCConnectionHandle()); #endif } try { fODBCdsP->prepareSQLStatement(statement, sql.c_str(), true, "Proxy Field Fetch"); fODBCdsP->execSQLStatement(statement, sql, true, NULL, true); if (!fODBCdsP->fetchNextRow(statement, true)) { // no data fValue.erase(); } else { // get data #ifdef SQLITE_SUPPORT if (fODBCdsP->fUseSQLite) { size_t siz = sqlite3_column_bytes(fODBCdsP->fSQLiteStmtP,0); if (siz>0) { if (fFieldMapP->dbfieldtype==dbft_blob) fValue.assign((cAppCharP)sqlite3_column_blob(fODBCdsP->fSQLiteStmtP,0),siz); else appendStringAsUTF8((const char *)sqlite3_column_text(fODBCdsP->fSQLiteStmtP,0), fValue, fODBCdsP->fConfigP->sqlPrepCharSet(), lem_cstr); // Convert to app-charset (UTF8) and C-type lineends } else { fValue.erase(); } } else #endif { #ifdef ODBCAPI_SUPPORT // pass in actual charset (including utf16 - getColumnValueAsString handles UTF16 case internally) fODBCdsP->fAgentP->getColumnValueAsString(statement,1,fValue,fODBCdsP->fConfigP->fDataCharSet,fFieldMapP->dbfieldtype==dbft_blob); #endif } } // fetched now fFetched=true; // done fODBCdsP->finalizeSQLStatement(statement,true); // release the statement handle #ifdef SQLITE_SUPPORT if (!fODBCdsP->fUseSQLite) #endif { #ifdef ODBCAPI_SUPPORT SafeSQLFreeHandle(SQL_HANDLE_STMT,statement); #endif } } catch (exception &e) { // release the statement handle #ifdef SQLITE_SUPPORT if (!fODBCdsP->fUseSQLite) #endif { #ifdef ODBCAPI_SUPPORT SafeSQLFreeHandle(SQL_HANDLE_STMT,statement); #endif } throw; } } } // TODBCFieldProxy::fetchBlob // returns size of entire blob size_t TODBCFieldProxy::getBlobSize(TStringField *aFieldP) { fetchBlob(); return fValue.size(); } // TODBCFieldProxy::getBlobSize // read from Blob from specified stream position and update stream pos size_t TODBCFieldProxy::readBlobStream(TStringField *aFieldP, size_t &aPos, void *aBuffer, size_t aMaxBytes) { if (!fFetched) { // we need to read the body fetchBlob(); } // now copy from our value if (aPos>fValue.size()) return 0; if (aPos+aMaxBytes>fValue.size()) aMaxBytes=fValue.size()-aPos; if (aMaxBytes==0) return 0; // copy data from ODBC answer buffer to caller's buffer memcpy(aBuffer,fValue.c_str()+aPos,aMaxBytes); aPos+= aMaxBytes; return aMaxBytes; // return number of bytes actually read } // TODBCFieldProxy::readBlobStream #endif // STREAMFIELD_SUPPORT } // namespace #endif // SQL_SUPPORT // eof libsynthesis-3.4.0.47.1/src/DB_interfaces/odbc_db/odbcapids.h000077500000000000000000000777341226375725500236250ustar00rootroot00000000000000/** * @File odbcapids.h * * @Author Lukas Zeller (luz@plan44.ch) * * @brief TODBCApiDS * ODBC based datastore API implementation * @Note Currently also contains what will later become TCustomImplDS * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * @Date 2005-09-16 : luz : created from odbcdbdatastore */ #include "prefix_file.h" #ifndef ODBCAPIDS_H #define ODBCAPIDS_H #ifdef SQL_SUPPORT // includes #include "odbcdb.h" #include "stdlogicds.h" #include "multifielditem.h" #include "odbcapiagent.h" using namespace sysync; namespace sysync { #ifdef SCRIPT_SUPPORT // publish as derivates might need it extern const TFuncTable ODBCDSFuncTable2; #endif // the datastore config // special ID generation modes typedef enum { sidm_none, // none sidm_unixmsrnd6 // UNIX milliseconds and 6-digit random } TSpecialIDMode; const sInt16 numSpecialIDModes = sidm_unixmsrnd6-sidm_none+1; // ODBC variant of field map class TODBCFieldMapItem : public TFieldMapItem { typedef TFieldMapItem inherited; public: TODBCFieldMapItem(const char *aElementName, TConfigElement *aParentElement); // - parser for extra attributes (for derived classes) virtual void checkAttrs(const char **aAttributes); #ifdef STREAMFIELD_SUPPORT // properties string fReadBlobSQL; // read field when needed trough field proxy string fKeyFieldName; // if set, this field name will be used in %N when reading the record rather than the actual data field -> to get record key for array elements for proxies #endif }; // TODBCFieldMapItem #ifdef ARRAYDBTABLES_SUPPORT // special field map item: Array map class TODBCFieldMapArrayItem : public TFieldMapArrayItem { typedef TFieldMapArrayItem inherited; public: TODBCFieldMapArrayItem(TCustomDSConfig *aCustomDSConfigP, TConfigElement *aParentElement); virtual ~TODBCFieldMapArrayItem(); // SQL properties // %k = record key of associated main table record // %i = index of current element (0 based) // %N = field name list for INSERT and SELECT // %V = value list for INSERT // %d([opt]fieldname#arrayindex) // %dM,%tM,%M = modified date/time/timestamp // %f=folderkey, %u=userkey, %t=targetkey // %S = size of record (sum of all field literal sizes) // - SQL for selecting all elements of the array // NOTE: %N must be first in (and is probably entire) SELECT field list! string fSelectArraySQL; // - SQL for clearing the array, must clear all subrecords of the array string fDeleteArraySQL; bool fAlwaysCleanArray; // if set, fDeleteArraySQL will be executed even if master record is inserted new // - SQL to insert a new array element string fInsertElementSQL; // Methods virtual void clear(); protected: // check config elements virtual bool localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine); virtual void localResolve(bool aLastPass); }; // TODBCFieldMapArrayItem #endif class TOdbcDSConfig: public TCustomDSConfig { typedef TCustomDSConfig inherited; public: TOdbcDSConfig(const char* aName, TConfigElement *aParentElement); virtual ~TOdbcDSConfig(); // properties // - set this if every item modification needs to be committed separately // (for DBs such as Achil where any insert will block the size accumulation // record). bool fCommitItems; // - define how many times an insert is retried in case of ODBC error, 0=no retry sInt16 fInsertRetries; // - define how many times an update is retried in case of ODBC error, 0=no retry sInt16 fUpdateRetries; #ifdef HAS_SQL_ADMIN // - statement to obtain folder key from Database, empty if none // replacements: %F=foldername, %u=userkey, %d=devicekey // Note: see fFolderKeyField and %f substitute to use folderkey for subselecting data string fFolderKeySQL; // - sqls for handling Sync Target Table // - replacements: %f=folderkey, %u=userkey, %D=deviceID, %P=deviceDBpath string fGetSyncTargetSQL; // must return SYNCTARGETKEY,ANCHOR,LASTSYNC string fNewSyncTargetSQL; // - additional replacements: %L=last sync timestamp, %dL=last sync date, %tL=last sync time string fUpdateSyncTargetSQL; string fDeleteSyncTargetSQL; // should also delete all associated map entries! bool fSyncTimestamp; // if set, target table SELECT expects single timestamp, date & time otherwise #ifdef OLD_1_0_5_CONFIG_COMPATIBLE // Map table access, old version // - layout of map table string fMapTableName; // name string fRemoteIDMapField; // remote ID string fLocalIDMapField; // local ID bool fStringLocalID; // if set, local ID is quoted as string literal in SQL string fTargetKeyMapField; // target key bool fStringTargetkey; // if set, target key is quoted as string literal in SQL // Data table access, old version // - name of table containing the data string fLocalTableName; /* never documented (only used in achil), so not supported any more // - additional constant insert values (appended to INSERT field/value lists, resp.) // %d([opt]fieldname#arrayindex) // %dM,%tM,%M = modified date/time/timestamp // %f=folderkey, %u=userkey, %t=targetkey // %S = size of record (sum of all field literal sizes) string fConstInsFields; string fConstInsValues; // - additional constant update terms (appended to UPDATE SET list) // %d([opt]fieldname#arrayindex) // %dM,%tM,%M = modified date/time/timestamp // %f=folderkey, %u=userkey, %t=targetkey // %S = size of record (sum of all field literal sizes) string fConstUpdates; */ // - name of folderkey subselection field in data table, empty if none string fFolderKeyField; bool fStringFolderkey; // if set, folder key is quoted as string literal in SQL // - name of field which contains Local ID (GUID) string fLocalIDField; // - modified date & time fields string fModifiedDateField; // this field is used as modified date or datetime string fModifiedTimeField; // if set, this field is used as modified time // - additional select clause (to be used for all selects BUT NOT INSERTS!) // NOTE: can contain %x-type substitutions (see DoSQLSubstitutions()) // Note: was never documented so will be phased out right now // string fGeneralSelectCondition; #endif // OLD_1_0_5_CONFIG_COMPATIBLE // Map table access, new version // Substitutions: // from agent's DoSQLSubstitutions: // %u = userkey // %d = devicekey // from datastore's DoSQLSubstitutions: // %f = folderkey // %t = targetkey // from DoMapSubstitutions: // %e = entry type // %k = data key (local ID) // %r = remote ID (always a string) // - SQL to fetch all map entries of a target: order= localid,remoteid string fMapFetchAllSQL; // - SQL to insert new map entry by localid string fMapInsertSQL; // - SQL to update existing map entry by localid string fMapUpdateSQL; // - SQL to delete a map entry by localid string fMapDeleteSQL; // Data table access, new version // Substitutions: // from agent's DoSQLSubstitutions: // %u = userkey // %d = devicekey // from datastore's DoSQLSubstitutions: // %f = folderkey // %t = targetkey // from DoDataSubstitutions: // %dM,%tM,%M = modified date,time,timestamp // %d([opts]fieldname#arrindex) = contents of field, opts l=lowercase, u=uppercase, a=ascii-only // %S = size of all string field literal sizes // %AF = filter conditions preceeded by AND (can be empty) // %WF = filter conditions preceeded by WHERE (can be empty) // %k = data key (local ID) // %N = data field name list // %aN = data field name list with all field, regardless of possible unassigned state of fields in update statements // %V = data field=value list // %aV = data field=value list with all field // %v = data value list // %aV = data value list with all field // for Array fields only: // %i = 0 based index of array elements #endif // HAS_SQL_ADMIN // - single(!) SQL statement to fetch local ID and timestamp from data table string fLocalIDAndTimestampFetchSQL; bool fModifiedTimestamp; // if set, above statement returns separate date and time // Note: the following data access SQL strings may consist of multiple SQL statements // separated by %GO or %GO(setno). Default setno=0 without preceeding %GO(setno) // - SQL statement(s) to fetch actual data fields from data table. SQL result must // contain mapped fields in the same order as they appear in // Note: Statement(s) executed with setno==0 returning no data are interpreted // as "record does not exist (any more)". Statements with setno!=0 returning // no data are just ignored (assuming optional data not present) string fDataFetchSQL; // - SQL statement(s) to insert new data in a record, including modification date string fDataInsertSQL; // - SQL statement(s) to update actual data in a record, including modification date string fDataUpdateSQL; // - SQL statement(s) to delete a record string fDataDeleteSQL; // - SQL statement(s) to zap entire sync set string fDataZapSQL; // Data table options // - try to translate filters to SQL if possible bool fFilterOnDBLevel; // - Literal string quoting mode TQuotingModes fQuotingMode; // Local ID generation // - if set, fObtainNextIDSql is executed only ONCE per write phase, and // IDs generated by incrementing the ID by 1 for every record added. // This is NOT MULTI-USER-SAFE, but can be useful for slow DBs like FMPro // Setting this excludes fObtainNextIDAfterInsert bool fDetermineNewIDOnce; // - if set, fObtainNewLocalIDSql is used AFTER inserting without a GUID // to obtain the GUID generated by the DB (such as MS-SQL autoincrement) bool fObtainNewIDAfterInsert; // - This SQL query is used to obtain the local ID // for adds. It is expected to return the ID in the first result column. // - if (fDetermineNextIDOnce), it is executed once at implimplSyncLogin, // further IDs are generated by incrementing it (for single-User DBs only!) // - if (fObtainNextIDAfterInsert), this is executed AFTER inserting // without a local ID specified in INSERT statement to determine DB-assigned ID string fObtainNewLocalIDSql; #ifdef SCRIPT_SUPPORT // - This script is called when a new localID must be generated (fObtainNextIDAfterInsert == false) // before adding a record. If it returns non-undefined, the return value is used as localID string fLocalIDScript; #endif // - if This specifies the minimum ID to be used if fObtainNextIDSql // returns something lower. This is also dangerous, but also needed // for FMPro to keep FMPro generated IDs far (much lower) from Sync // generated IDs sInt32 fMinNextID; // - specifies special ID calculation method TSpecialIDMode fSpecialIDMode; // - if set, the fDataInsertSQL statement is expected to return the new ID as // the first column of the result set (for example if insert is implemented // with a stored procedue) bool fInsertReturnsID; bool fInsertIDAsOutParam; // - if set, SQLRowCount result is ignored and write statements are always assumed to be successful // (unless they fail with an error, of course) bool fIgnoreAffectedCount; // - type of the last-modified date column TDBFieldType fLastModDBFieldType; // SQLite support #ifdef SQLITE_SUPPORT // - name of the SQLite file that contains the user data for this datastore string fSQLiteFileName; // - busy timeout, 0 = no wait uInt32 fSQLiteBusyTimeout; #endif // public methods // - return charset used to create SQL statments (will return UTF-8 when using UTF-16/UCS-2 // to allow SQL statement construction in 8-bit mode, and only converting before // actually calling ODBC TCharSets sqlPrepCharSet(void) { return fDataCharSet==chs_utf16 ? chs_utf8 : fDataCharSet; }; // - create appropriate datastore from config, calls addTypeSupport as well virtual TLocalEngineDS *newLocalDataStore(TSyncSession *aSessionP); #ifdef SCRIPT_SUPPORT // provided to allow derivates to add API specific script functions to scripts called from CustomImplDS virtual const TFuncTable *getDSFuncTableP(void) { return &ODBCDSFuncTable1; }; #endif // factory functions for field map items virtual TFieldMapItem *newFieldMapItem(const char *aElementName, TConfigElement *aParentElement) { return new TODBCFieldMapItem(aElementName,aParentElement); }; #ifdef ARRAYDBTABLES_SUPPORT virtual TFieldMapArrayItem *newFieldMapArrayItem(TCustomDSConfig *aCustomDSConfigP, TConfigElement *aParentElement) { return new TODBCFieldMapArrayItem(aCustomDSConfigP,aParentElement); }; #endif protected: // check config elements virtual bool localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine); virtual void clear(); virtual void localResolve(bool aLastPass); #ifdef SCRIPT_SUPPORT virtual void apiResolveScripts(void); #endif }; // TOdbcDSConfig class TODBCApiDS: public TCustomImplDS { friend class TODBCDSfuncs; friend class TODBCCommonFuncs; friend class TODBCFieldProxy; typedef TCustomImplDS inherited; private: void InternalResetDataStore(void); // reset for re-use without re-creation public: TODBCApiDS( TOdbcDSConfig *aConfigP, sysync::TSyncSession *aSessionP, const char *aName, uInt32 aCommonSyncCapMask=0); virtual void announceAgentDestruction(void); virtual void dsResetDataStore(void) { InternalResetDataStore(); inherited::dsResetDataStore(); }; virtual ~TODBCApiDS(); /// @name apiXXXX methods defining the interface from TCustomImplDS to TXXXApi actual API implementations /// @{ // /// @brief Load admin data from ODBC database /// @param aDeviceID[in] remote device URI (device ID) /// @param aDatabaseID[in] local database ID /// @param aRemoteDBID[in] database ID of remote device /// Must search for existing target record matching the triple (aDeviceID,aDatabaseID,aRemoteDBID) /// - if there is a matching record: load it /// - if there is no matching record, set fFirstTimeSync=true. The implementation may already create a /// new record with the key (aDeviceID,aDatabaseID,aRemoteDBID) and initialize it with the data from /// the items as shown below. At least, fTargetKey must be set to a value that will allow apiSaveAdminData to /// update the record. In case implementation chooses not create the record only in apiSaveAdminData, it must /// buffer the triple (aDeviceID,aDatabaseID,aRemoteDBID) such that it is available at apiSaveAdminData. /// If a record exists implementation must load the following items: /// - fTargetKey = some key value that can be used to re-identify the target record later at SaveAdminData. /// If the database implementation has other means to re-identify the target, this can be /// left unassigned. /// - fLastRemoteAnchor = anchor string used by remote party for last session (and saved to DB then) /// - fPreviousSyncTime = anchor (beginning of session) timestamp of last session. /// - fPreviousToRemoteSyncCmpRef = Reference time to determine items modified since last time sending data to remote /// (or last changelog update in case of BASED_ON_BINFILE_CLIENT) /// - fPreviousToRemoteSyncIdentifier = string identifying last session that sent data to remote /// (or last changelog update in case of BASED_ON_BINFILE_CLIENT). Needs only be saved /// if derived datastore cannot work with timestamps and has its own identifier. /// - fMapTable = list containing map entries. The implementation must load all map entries /// related to the current sync target identified by the triple of (aDeviceID,aDatabaseID,aRemoteDBID) /// or by fTargetKey. The entries added to fMapTable must have "changed", "added" and "deleted" flags /// set to false. /// For resumable datastores: /// - fMapTable = In addition to the above, the markforresume flag must be saved in the mapflags // when it is not equal to the savedmark flag - independently of added/deleted/changed. /// - fResumeAlertCode = alert code of current suspend state, 0 if none /// - fPreviousSuspendCmpRef = reference time of last suspend (used to detect items modified during a suspend / resume) /// - fPreviousSuspendIdentifier = identifier of last suspend (used to detect items modified during a suspend / resume) /// (needs only be saved if derived datastore cannot work with timestamps and has /// its own identifier) /// - fPendingAddMaps = map. The implementation must load all all pending maps (client only) into /// fPendingAddMaps (and fUnconfirmedMaps must be left empty). /// - fTempGUIDMap = map. The implementation must save all entries as temporary LUID to GUID mappings /// (server only) virtual localstatus apiLoadAdminData( const char *aDeviceID, // remote device URI (device ID) const char *aDatabaseID, // database ID const char *aRemoteDBID // database ID of remote device ); /// @brief Save admin data to ODBC database /// @param[in] aSessionFinished if true, this is a end-of-session save (and not only a suspend save) - but not necessarily a successful one /// @param[in] aSuccessful if true, this is a successful end-of-session /// Must save to the target record addressed at LoadAdminData() by the triple (aDeviceID,aDatabaseID,aRemoteDBID) /// Implementation must save the following items: /// - fLastRemoteAnchor = anchor string used by remote party for this session (and saved to DB then) /// - fPreviousSyncTime = anchor (beginning of session) timestamp of this session. /// - fPreviousToRemoteSyncCmpRef = Reference time to determine items modified since last time sending data to remote /// (or last changelog update in case of BASED_ON_BINFILE_CLIENT) /// - fPreviousToRemoteSyncIdentifier = string identifying last session that sent data to remote /// (or last changelog update in case of BASED_ON_BINFILE_CLIENT). Needs only be saved /// if derived datastore cannot work with timestamps and has its own identifier. /// - fMapTable = list containing map entries. The implementation must save all map entries /// that have changed, are new or are deleted. See below for additional resume requirements. /// For resumable datastores: /// - fMapTable = In addition to the above, the markforresume flag must be saved in the mapflags // when it is not equal to the savedmark flag - independently of added/deleted/changed. /// - fResumeAlertCode = alert code of current suspend state, 0 if none /// - fPreviousSuspendCmpRef = reference time of last suspend (used to detect items modified during a suspend / resume) /// - fPreviousSuspendIdentifier = identifier of last suspend (used to detect items modified during a suspend / resume) /// (needs only be saved if derived datastore cannot work with timestamps and has /// its own identifier) /// - fPendingAddMaps and fUnconfirmedMaps = map. The implementation must save all entries as /// pending maps (client only). Note that fPendingAddMaps might contain temporary localIDs, /// so call dsFinalizeLocalID() to ensure these are converted to final before saving. /// - fTempGUIDMap = map. The implementation must save all entries as temporary LUID to GUID mappings /// (server only) virtual localstatus apiSaveAdminData(bool aSessionFinished, bool aSuccessful); /// read sync set IDs and mod dates. /// @param[in] if set, all data fields are needed, so ReadSyncSet MAY /// read items here already. Note that ReadSyncSet MAY read items here /// even if aNeedAll is not set (if it is more efficient than reading /// them separately afterwards). virtual localstatus apiReadSyncSet(bool aNeedAll); /// Zap all data in syncset (note that everything outside the sync set will remain intact) virtual localstatus apiZapSyncSet(void); virtual bool apiNeedSyncSetToZap(void) { return fConfigP->fDataZapSQL.empty(); }; // we need it if we don't have a zap SQL /// fetch record contents from DB by localID. virtual localstatus apiFetchItem(TMultiFieldItem &aItem, bool aReadPhase, TSyncSetItem *aSyncSetItemP); /// add new item to datastore, returns created localID virtual localstatus apiAddItem(TMultiFieldItem &aItem, string &aLocalID); /// update existing item in datastore, returns 404 if item not found virtual localstatus apiUpdateItem(TMultiFieldItem &aItem); /// delete existing item in datastore, returns 211 if not existing any more virtual localstatus apiDeleteItem(TMultiFieldItem &aItem); /// end of syncset reading phase virtual localstatus apiEndDataRead(void); /// start of write virtual localstatus apiStartDataWrite(void); /// end DB data write sequence (but not yet admin data) virtual localstatus apiEndDataWrite(string &aThisSyncIdentifier); /// @} public: /// @name dsXXXX virtuals defined by TLocalEngineDS /// These are usually designed such that they should always call inherited::dsXXX to let the entire chain /// of ancestors see the calls /// @{ // /// end of message handling virtual void dsEndOfMessage(void); /// inform logic of coming state change virtual localstatus dsBeforeStateChange(TLocalEngineDSState aOldState,TLocalEngineDSState aNewState); /// inform logic of happened state change virtual localstatus dsAfterStateChange(TLocalEngineDSState aOldState,TLocalEngineDSState aNewState); // log datastore sync result #ifdef HAS_SQL_ADMIN // - Called at end of sync with this datastore virtual void dsLogSyncResult(void); #endif // HAS_SQL_ADMIN /// @} /// @name dsHelpers private/protected helper routines /// @{ // private: #ifdef HAS_SQL_ADMIN /// update sync target head record localstatus updateSyncTarget(SQLHSTMT aStatement, bool aSessionFinishedSuccessfully); /// update map changes from memory list into actual map table localstatus updateODBCMap(SQLHSTMT aStatement, bool aSessionFinishedSuccessfully); // - log substitutions virtual void DoLogSubstitutions(string &aLog,bool aPlaintext); #endif // HAS_SQL_ADMIN /// @} // Publics for context funcs // - generate new LocalID into fLastGeneratedLocalID. void nextLocalID(TSpecialIDMode aMode,SQLHSTMT aStatement); // agent TODBCApiAgent *fAgentP; // access to agent (casted fSessionP for convenience) // config (typed pointers for convenience) TOdbcDSConfig *fConfigP; TOdbcAgentConfig *fAgentConfigP; protected: // some vars string fLastGeneratedLocalID; #ifdef SCRIPT_SUPPORT string fSQLFilter; // run-time calculated filter expression for SELECT WHERE clause SQLHSTMT fODBCScriptStatement; // statement used for executing SQL in scripts virtual void apiRebuildScriptContexts(void); #endif #ifdef OBJECT_FILTERING // - returns true if DB implementation can filter the standard filters // (LocalDBFilter, TargetFilter and InvisibleFilter) during database fetch // - otherwise, fetched items will be filtered after being read from DB. virtual bool dsFilteredFetchesFromDB(bool aFilterChanged=false); #endif protected: #ifdef ODBCAPI_SUPPORT // ODBC // - get (session level) ODBC handle SQLHDBC getODBCConnectionHandle(void); // - check for connection-level error void checkConnectionError(SQLRETURN aResult); #ifdef HAS_SQL_ADMIN // - issue single (or multiple) map access statements // NOTE: if all return SQL_NODATA, function will return false. bool IssueMapSQL( SQLHSTMT aStatement, const string &aSQL, const char *aComment, TMapEntryType aEntryType, const char *aLocalID, const char *aRemoteID, uInt32 aMapFlags ); // - do substitutions for map table access void DoMapSubstitutions( string &aSQL, // string to apply substitutions to TMapEntryType aEntryType, // the entry type const char *aLocalID, // local ID const char *aRemoteID, // remote ID uInt32 aMapFlags // map flags ); #endif // HAS_SQL_ADMIN #endif // ODBCAPI_SUPPORT // Generic SQL // - get next statement and setno from statement list (may begin with %GO(setno)) bool getNextSQLStatement(const string &aSQL, sInt16 &aStartAt, string &aOneSQL, uInt16 &aSetNo); // - execute single SQL statements bool execSQLStatement(SQLHSTMT aStatement, string &aSQL, bool aNoDataAllowed, const char *aComment, bool aForData); // - issue single (or multiple) data write (or delete) statements // NOTE: if all return SQL_NODATA, function will return false. bool IssueDataWriteSQL( SQLHSTMT aStatement, const string &aSQL, const char *aComment, bool aForUpdate, // for update TFieldMapList &aFieldMapList, // field map list for %N,%V and %v TMultiFieldItem *aItemP // item to read values and localid from ); // - do standard substitutions (%x-type) in a SQL string void DoSQLSubstitutions(string &aSQL); // insert additional data selection conditions, if any. bool appendFiltersClause(string &aSQL, const char *linktext); public: // - do substitutions for data table access void DoDataSubstitutions( string &aSQL, // string to apply substitutions to TFieldMapList &aFieldMapList, // field map list for %N,%V and %v uInt16 aSetNo, // Map Set number bool aForWrite, // set if read-enabled or write-enabled fields are shown in %N,%V and %v bool aForUpdate=false, // set if for update (only assigned fields will be shown if !fUpdateAllFields) TMultiFieldItem *aItemP=NULL, // item to read values and localid from sInt16 aRepOffset=0, // array index/repeat offset bool *aAllEmptyP=NULL, // true if all %V or %v empty bool *aDoneP=NULL // true if no data at specified aRepOffset ); // Parameter handling // - reset all mapped parameters void resetSQLParameterMaps(void); // - add parameter definition to the datastore level parameter list void addSQLParameterMap( bool aInParam, bool aOutParam, TParamMode aParamMode, TODBCFieldMapItem *aFieldMapP, TMultiFieldItem *aItemP, sInt16 aRepOffset ); // - prepare SQL statment as far as needed for parameter binding void prepareSQLStatement(SQLHSTMT aStatement, cAppCharP aSQL, bool aForData, cAppCharP aComment); // - bind parameters (and values for IN-Params) to the statement void bindSQLParameters(SQLHSTMT aStatement, bool aForData); // - save out parameter values and clean up void saveAndCleanupSQLParameters(SQLHSTMT aStatement, bool aForData); // - fetch next row from SQL statement, returns true if there is any bool fetchNextRow(SQLHSTMT aStatement, bool aForData); // - SQL statement complete, finalize it void finalizeSQLStatement(SQLHSTMT aStatement, bool aForData); protected: #ifdef OBJECT_FILTERING // - convert filter expression into SQL WHERE clause condition bool appendFilterConditions(string &aSQL, const string &aFilter); // - appends logical condition term to SQL from filter string bool appendFilterTerm(string &aSQL, const char *&aPos, const char *aStop); #endif #ifdef ODBCAPI_SUPPORT // - get one or two successive columns as time stamp depending on config void getColumnsAsTimestamp( SQLHSTMT aStatement, sInt16 &aColNumber, // will be updated by 1 or 2 bool aCombined, lineartime_t &aTimestamp, timecontext_t aTargetContext ); #endif // - get a column as integer based timestamp lineartime_t dbIntToLineartimeAs( sInt64 aDBInt, TDBFieldType aDbfty, timecontext_t aTargetContext ); // - helpers for mapping field values bool addFieldNameList(string &aSQL, bool aForWrite, bool aForUpdate, bool aAssignedOnly, TMultiFieldItem *aItemP, TFieldMapList &fml,uInt16 aSetNo, char aFirstSep=0); bool addFieldNameValueList(string &aSQL, bool aAssignedOnly, bool &aNoData, bool &aAllEmpty, TMultiFieldItem &aItem, bool aForUpdate,TFieldMapList &fml, uInt16 aSetNo, sInt16 aRepOffset=0, char aFirstSep=0); void fillFieldsFromSQLResult(SQLHSTMT aStatement, sInt16 &aColIndex, TMultiFieldItem &aItem, TFieldMapList &fml, uInt16 aSetNo, sInt16 aRepOffset=0); // - add field value as literal to SQL text bool appendFieldsLiteral(TMultiFieldItem &aItem, sInt16 aFid, sInt16 aRepOffset,TODBCFieldMapItem &aFieldMapping, string &aSQL); public: bool appendFieldValueLiteral(TItemField &aField,TDBFieldType aDBFieldType, uInt32 aMaxSize, bool aIsFloating, string &aSQL); protected: #ifdef ARRAYDBTABLES_SUPPORT // array table field access basic functions void readArray(SQLHSTMT aStatement, TMultiFieldItem &aItem, TFieldMapArrayItem *aMapItemP); void writeArray(bool aDelete, bool aInsert, SQLHSTMT aStatement, TMultiFieldItem &aItem, TFieldMapArrayItem *aMapItemP); // accessing all array fields of a item void readArrayFields(SQLHSTMT aStatement, TMultiFieldItem &aItem, TFieldMapList &fml); void writeArrayFields(SQLHSTMT aStatement, TMultiFieldItem &aItem, TFieldMapList &fml, bool aInsert); void deleteArrayFields(SQLHSTMT aStatement, TMultiFieldItem &aItem, TFieldMapList &fml); #endif // other private utils // - private helper: start writing item void startWriteItem(void); // - private helper: end writing item void endWriteItem(void); // - create local ID with special algorithm void createLocalID(string &aLocalID,TSpecialIDMode aSpecialIDMode); protected: // Fully ODBC based DB bool fODBCAdminData; // set if admin data is actually in ODBC tables (and not managed in derived class' implementation) // StartDataRead/GetItem vars sInt32 fNextLocalID; // Parameters TParameterMapList fParameterMaps; // Sum of all string sizes per record sInt32 fRecordSize; // Filtering #ifdef OBJECT_FILTERING bool fFilterExpressionTested; bool fFilterWorksOnDBLevel; // set if filter can be executed by DB #endif // ODBC #ifdef ODBCAPI_SUPPORT SQLHDBC fODBCConnectionHandle; #endif // Note: %%% we need the statements as dummies even if ODBC is not compiled in SQLHSTMT fODBCReadStatement; SQLHSTMT fODBCWriteStatement; // SQLite #ifdef SQLITE_SUPPORT bool fUseSQLite; sqlite3 *fSQLiteP; sqlite3_stmt *fSQLiteStmtP; int fStepRc; #endif }; // TODBCApiDS #ifdef STREAMFIELD_SUPPORT // proxy for loading blobs class TODBCFieldProxy : public TBlobProxy { typedef TBlobProxy inherited; public: TODBCFieldProxy(TODBCApiDS *aODBCdsP, TODBCFieldMapItem *aFieldMapP, const char *aMasterKey, const char *aDetailKey); virtual ~TODBCFieldProxy(); // - returns size of entire blob virtual size_t getBlobSize(TStringField *aFieldP); // - read from Blob from specified stream position and update stream pos virtual size_t readBlobStream(TStringField *aFieldP, size_t &aPos, void *aBuffer, size_t aMaxBytes); // - dependency on a local ID virtual void setParentLocalID(const char *aParentLocalID) { fMasterKey=aParentLocalID; }; private: // fetch BLOB from DPAPI void fetchBlob(void); // Vars TODBCApiDS *fODBCdsP; // datastore which can be asked to retrieve data TODBCFieldMapItem *fFieldMapP; // field map item config (contains SQL needed to fetch BLOB field) bool fIsStringBLOB; // if set, the blob must be treated as a string (applying DB charset conversions) string fMasterKey; // key of master (main) record containing the field to be retrieved string fDetailKey; // optional key of detail record, available only when "keyfield" attribute is present in bool fFetched; // already fetched (if value is empty, fBlobBuffer may still be NULL) string fValue; // string or binary value }; // TODBCFieldProxy #endif } // namespace sysync #endif // ODBCAPIDS_H #endif // SQL_SUPPORT // eof libsynthesis-3.4.0.47.1/src/DB_interfaces/odbc_db/odbcdb.h000077500000000000000000000012461226375725500230730ustar00rootroot00000000000000/* * Common include file for all ODBC_H sources */ #ifndef ODBCDB_H #define ODBCDB_H // precompiled portion #include "odbcdb_precomp.h" // derived defines and sanity checks #ifdef ODBC_SUPPORT #error "ODBC_SUPPORT no longer exists, is now called SQL_SUPPORT. ODBCAPI_SUPPORT exists." #endif // SQL based admin #if defined (SQL_SUPPORT) && defined(ODBCAPI_SUPPORT) && !defined(BINFILE_ALWAYS_ACTIVE) #define HAS_SQL_ADMIN 1 #endif // other common includes #include "sysync.h" // Items used by ODBC DB interface #include "multifielditem.h" #include "mimediritemtype.h" #define TEXTMAP_FILE_EXTENSION ".txt" #define USERAUTH_FILE_EXTENSION ".txt" #endif /* eof */ libsynthesis-3.4.0.47.1/src/DB_interfaces/odbc_db/odbcdb_precomp.h000077500000000000000000000020311226375725500246110ustar00rootroot00000000000000/* * precompiled/precompilable headers */ #ifndef ODBCDB_PRECOMP_H #define ODBCDB_PRECOMP_H /* Specific headers for ODBC DB interface */ #ifdef ODBCAPI_SUPPORT // Real ODBC support, include headers #ifdef _WIN32 #include #include #include #else // ODBC HEADERS (MacOSX and Linux: in /usr/include) #include #include #ifdef OBDC_UNICODE // unicode ODBC #include #endif // it seems that SQLLEN is not defined on all platforms, in particular, Mac OS X #ifdef MACOSX #ifndef SQLLEN #define SQLLEN SQLINTEGER #endif // SQLLEN #endif // MACOSX #endif // not _WIN32 #else // Some fake definitions to make SQLite-only versions compile w/o having ODBC headers #define HSTMT long #define SQLHSTMT HSTMT #define SQL_NULL_HANDLE 0 #define SQLRETURN long #define SQL_NULL_DATA (-1) #define SQLLEN long #define SQL_SUCCESS 0 #endif // ODBCAPI_SUPPORT #endif // ODBCDB_PRECOMP_H /* eof */ libsynthesis-3.4.0.47.1/src/Doxyfile000066400000000000000000001640561226375725500171550ustar00rootroot00000000000000# Doxyfile 1.5.6 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a hash (#) is considered a comment and will be ignored # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = libsynthesis # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek, # Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages), # Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish, # Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, # and Ukrainian. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful is your file systems # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = NO # If the QT_AUTOBRIEF tag is set to YES then Doxygen will # interpret the first line (until the first dot) of a Qt-style # comment as the brief description. If set to NO, the comments # will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the DETAILS_AT_TOP tag is set to YES then Doxygen # will output the detailed description near the top, like JavaDoc. # If set to NO, the detailed description appears after the member # documentation. DETAILS_AT_TOP = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = NO # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for # Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = YES # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. # Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate getter # and setter methods for a property. Setting this option to YES (the default) # will make doxygen to replace the get and set methods by a property in the # documentation. This will only work if the methods are indeed getting or # setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically # be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = YES # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = YES # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = YES # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default # anonymous namespace are hidden. EXTRACT_ANON_NSPACES = YES # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or define consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and defines in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = YES # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the # Namespaces page. This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be abled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = $(INPUT) # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # also the default input encoding. Doxygen uses libiconv (or the iconv built # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 FILE_PATTERNS = # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = YES # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix filesystem feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the # filter if there is a match. The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = YES # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = NO # If the REFERENCED_BY_RELATION tag is set to YES # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = YES # If the REFERENCES_RELATION tag is set to YES # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = YES # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. Otherwise they will link to the documentstion. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = YES # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). # To create a documentation set, doxygen will generate a Makefile in the # HTML output directory. Running make will produce the docset in that # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. GENERATE_DOCSET = NO # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the # feed. A documentation feed provides an umbrella under which multiple # documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Doxygen generated docs" # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that # should uniquely identify the documentation set bundle. This should be a # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.doxygen.Project # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. For this to work a browser that supports # JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox # Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). HTML_DYNAMIC_SECTIONS = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING # is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. CHM_INDEX_ENCODING = # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. # If the tag value is set to FRAME, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, # Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are # probably better off using the HTML help feature. Other possible values # for this tag are: HIERARCHIES, which will generate the Groups, Directories, # and Class Hiererachy pages using a tree view instead of an ordered list; # ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which # disables this behavior completely. For backwards compatibility with previous # releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE # respectively. GENERATE_TREEVIEW = NONE # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need # to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. FORMULA_FONTSIZE = 10 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. This is useful # if you want to understand what is going on. On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = $(INCLUDE_PATH) # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = $(PREDEFINED) # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all function-like macros that are alone # on a line, have an all uppercase name, and do not end with a semicolon. Such # function macros are typically used for boiler-plate code, and will confuse # the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = libsynthesis.tags # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option is superseded by the HAVE_DOT option below. This is only a # fallback. It is recommended to install and use dot, since it yields more # powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the # documentation. The MSCGEN_PATH tag allows you to specify the directory where # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = YES # By default doxygen will write a font called FreeSans.ttf to the output # directory and reference it in all dot files that doxygen generates. This # font does not include all possible unicode characters however, so when you need # these (or just want a differently looking font) you can specify the font name # using DOT_FONTNAME. You need need to make sure dot is able to find the font, # which can be done by putting it in a standard location or by setting the # DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory # containing the font. DOT_FONTNAME = FreeSans # By default doxygen will tell dot to use the output directory to look for the # FreeSans.ttf font (which doxygen will put there itself). If you specify a # different font using DOT_FONTNAME you can set the path where dot # can find it using this tag. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT options are set to YES then # doxygen will generate a call dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then # doxygen will generate a caller dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen if the # number of direct children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is enabled by default, which results in a transparent # background. Warning: Depending on the platform used, enabling this option # may lead to badly anti-aliased labels on the edges of a graph (i.e. they # become hard to read). DOT_TRANSPARENT = YES # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = YES # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Configuration::additions related to the search engine #--------------------------------------------------------------------------- # The SEARCHENGINE tag specifies whether or not a search engine should be # used. If set to NO the values of all tags below this one will be ignored. SEARCHENGINE = NO libsynthesis-3.4.0.47.1/src/Makefile.am.in000066400000000000000000000173351226375725500201050ustar00rootroot00000000000000# The Makefile.am is generated from Makefile.am.in by autogen.sh # because the list of files to compile has to be determined # dynamically. # # When adding new files or changing options rerun autogen.sh. # Beware that changes made to Makefile.am will get lost, always # edit Makefile.am.in! The following rule ensures that make # itself will rebuild its makefiles when Makefile.am.in is edited. $(srcdir)/Makefile.am: $(srcdir)/Makefile.am.in $(srcdir)/gen-makefile-am.sh cd $(srcdir) && sh ./gen-makefile-am.sh # versioning for *all* libs # # CURRENT - most recent interface version # REVISION - minor version number of that interface implementation # AGE - number of previous interface versions supported in addition # to the current one # # When adding to the interface, increment CURRENT and AGE and reset # REVISION to zero. When breaking the interface in a backwards # incompatible way, increment CURRENT and reset AGE and REVISION to # zero. When fixing something without interface change, increment # REVISION. ENGINE_CURRENT = 6 ENGINE_REVISION = 0 ENGINE_AGE = 6 CLEANFILES = EXTRA_DIST = lib_LTLIBRARIES = libsmltk.la libsynthesis.la libsynthesissdk.la libsynthesisstubs.la nobase_include_HEADERS = @LIBSYNTHESISSDK_HEADERS@ synthesis/target_options.h # Configuration header files are searched in this order: # - Targets/ReleasedProducts/autotools: files only used when compiling with autotools # - Targets/ReleasedProducts/[combiEngine_opensource_linux|serverEngine_opensource_linux|SDK]: files also used with Synthesis Linux makefile # # Always included first via -include: # - config.h: configure result (top directory) # - Targets/ReleasedProducts/combiEngine_opensource_linux/clientengine_demo_x86_linux_prefix.h resp. Targets/ReleasedProducts/serverEngine_opensource_linux/serverengine_opensource_linux_prefix.h # # Included as needed: # - define.h: hard-coded SyncML Toolkit config (from search path above) libsynthesis_la_SOURCES = @LIBSYNTHESIS_SOURCES@ \ $(XMLPARSE_SOURCES) libsynthesis_la_CPPFLAGS = -I$(srcdir)/sysync_SDK/Sources libsynthesis_la_CFLAGS = \ $(SYNTHESIS_WFLAGS) \ -include $(top_builddir)/config.h \ -include $(srcdir)/Targets/ReleasedProducts/combiEngine_opensource_linux/combiengine_opensource_linux_prefix.h \ -I$(srcdir)/Targets/ReleasedProducts/clientEngine_autotools/ \ -I$(srcdir)/Targets/ReleasedProducts/combiEngine_opensource_linux/ \ -I$(srcdir)/platform_adapters/linux/ \ -I$(srcdir)/platform_adapters/unix_common/ \ -I$(srcdir)/platform_adapters/ \ -I$(srcdir)/syncapps/clientEngine_custom/ \ -I$(srcdir)/syncapps/serverEngine_custom/ \ -I$(srcdir)/sysync/ \ -I$(srcdir)/Transport_interfaces/engine/ \ -I$(srcdir)/ \ -I$(srcdir)/syncml_tk/src/sml/inc/ \ -I$(srcdir)/syncml_tk/src/sml/lib/inc/ \ -I$(srcdir)/syncml_tk/src/sml/lib/ \ -I$(srcdir)/syncml_tk/src/sml/mgr/inc/ \ -I$(srcdir)/syncml_tk/src/sml/mgr/ \ -I$(srcdir)/syncml_tk/src/sml/wsm/inc/ \ -I$(srcdir)/syncml_tk/src/sml/xlt/inc \ -I$(srcdir)/syncml_tk/src/sml/xlt/all \ -I$(srcdir)/DB_interfaces/odbc_db/ \ -I$(srcdir)/DB_interfaces/api_db/ \ -I$(srcdir)/sysync_SDK/Sources/ \ $(PCRE_CFLAGS) \ $(DLT_CFLAGS) \ $(SQLITE3_CFLAGS) \ $(ZLIB_CFLAGS) \ $(XMLPARSE_CFLAGS) \ $(XMLPARSE_CFLAGS_BUILTIN) \ $(LIBICAL_CFLAGS) \ $(LIBECAL_CFLAGS) libsynthesis_la_CXXFLAGS = $(libsynthesis_la_CFLAGS) libsynthesis_la_LIBADD = $(PCRE_LIBS) $(DLT_LIBS) $(SQLITE3_LIBS) $(XMLPARSE_LIBS) $(LIBICAL_LIBS) $(LIBECAL_LIBS) libsmltk.la -lz -ldl -lpthread libsynthesis_la_LDFLAGS = -version-info $(ENGINE_CURRENT):$(ENGINE_REVISION):$(ENGINE_AGE) \ -Wl,--version-script=$(srcdir)/synthesis-linker.map libsynthesis_la_DEPENDENCIES = $(srcdir)/synthesis-linker.map libsmltk.la if COND_XMLPARSE XMLPARSE_CFLAGS_BUILTIN = -I$(srcdir)/expat -I$(srcdir)/expat/xmltok -I$(srcdir)/expat/xmlparse XMLPARSE_SOURCES = \ expat/xmlparse/xmlparse.c \ expat/xmlparse/xmlparse.h \ expat/xmltok/ascii.h \ expat/xmltok/asciitab.h \ expat/xmltok/iasciitab.h \ expat/xmltok/latin1tab.h \ expat/xmltok/nametab.h \ expat/xmltok/utf8tab.h \ expat/xmltok/xmldef.h \ expat/xmltok/xmlrole.c \ expat/xmltok/xmlrole.h \ expat/xmltok/xmltok.c \ expat/xmltok/xmltok.h \ expat/xmltok/xmltok_impl.h EXTRA_DIST += \ expat/xmltok/xmltok_impl.c \ expat/xmltok/xmltok_ns.c else # add path to xmlparse.h which includes the system's xmltok/xmlparse.h XMLPARSE_CFLAGS_BUILTIN = -I$(srcdir)/Targets/ReleasedProducts/clientEngine_autotools/systemxml endif libsynthesissdk_la_LIBADD = libsmltk.la # san.cpp calls sml* functions directly libsynthesissdk_la_LDFLAGS = -static libsynthesissdk_la_CFLAGS = $(PIC_CXXFLAGS) $(SYNTHESIS_WFLAGS) libsynthesissdk_la_CXXFLAGS = $(PIC_CXXFLAGS) $(SYNTHESIS_WFLAGS) libsynthesissdk_la_SOURCES = @LIBSYNTHESISSDK_HEADERS@ if COND_STATIC libsynthesissdk_la_SOURCES += @LIBSYNTHESISSDK_SOURCES_SDK_ONLY@ else libsynthesissdk_la_SOURCES += @LIBSYNTHESISSDK_SOURCES_BOTH@ endif libsynthesissdk_la_CPPFLAGS = \ -D_GNU_SOURCE=1 \ -include $(top_builddir)/config.h \ -I$(srcdir)/Targets/ReleasedProducts/SDK \ -I$(srcdir)/sysync_SDK/Sources \ -I$(srcdir)/platform_adapters/linux/ \ -I$(srcdir)/platform_adapters/unix_common/ \ -I$(srcdir)/platform_adapters/ \ -I$(srcdir)/sysync/ \ -I$(srcdir)/syncml_tk/src/sml/inc/ \ -I$(srcdir)/syncml_tk/src/sml/lib/inc/ \ -I$(srcdir)/syncml_tk/src/sml/mgr/inc/ libsynthesisstubs_la_LDFLAGS = -static libsynthesisstubs_la_CFLAGS = $(libsynthesissdk_la_CXXFLAGS) libsynthesisstubs_la_CXXFLAGS = $(libsynthesissdk_la_CXXFLAGS) libsynthesisstubs_la_SOURCES = sysync_SDK/Sources/enginestubs.c libsynthesisstubs_la_CPPFLAGS = $(libsynthesissdk_la_CPPFLAGS) # All files needed by libsynthesissdk.a come from either # sysync_SDK/Sources (shared between engine and SDK) or # sysync_SDK/SDK (only in SDK). We patch the files so that # they include their own files via #include "synthesis/..." vpath %.cpp $(srcdir)/sysync_SDK/Sources $(srcdir)/sysync_SDK/SDK vpath %.c $(srcdir)/sysync_SDK/Sources $(srcdir)/sysync_SDK/SDK vpath %.h $(srcdir)/sysync_SDK/Sources $(srcdir)/sysync_SDK/SDK @LIBSYNTHESISSDK_HEADERS@: synthesis/%: % mkdir -p synthesis sed -e 's;# *include *";#include "synthesis/;' -e 's/defined(HAVE_STDINT_H)/1/' $< >$@ synthesis/target_options.h: $(srcdir)/Targets/ReleasedProducts/SDK/target_options.h mkdir -p synthesis cp $< $@ # ensure that the header file is in place before compiling the SDK @LIBSYNTHESISSDK_SOURCES@: synthesis/target_options.h # libsmltk: compiled just like libsynthesis libsmltk_la_SOURCES = @LIBSMLTK_SOURCES@ libsmltk_la_CFLAGS = $(libsynthesis_la_CFLAGS) libsmltk_la_CXXFLAGS = $(libsmltk_la_CFLAGS) # versioning: same as of engine! changes in libsmltk are not tracked separately. libsmltk_la_LDFLAGS = -version-info $(ENGINE_CURRENT):$(ENGINE_REVISION):$(ENGINE_AGE) \ -Wl,--version-script=$(srcdir)/smltk-linker.map libsmltk_la_DEPENDENCIES = $(srcdir)/smltk-linker.map # Doxygen for complete source code as used in autotools build. # The dependency on the libs ensures that doxygen is invoked # anew when any input file for those changes, reusing the # automatic dependency tracking. A side effect (both good # and bad) is that doxygen will not be invoked on code # which does not compile. html/index.html: Doxyfile libsynthesis.la libsynthesissdk.la rm -rf html INPUT="$(srcdir)/platform_adapters $(srcdir)/syncml_tk $(srcdir)/sysync_SDK $(srcdir)/sysync $(srcdir)/DB_interfaces" \ INCLUDE_PATH="$(srcdir)/Targets/ReleasedProducts/autotools $(srcdir)/Targets/ReleasedProducts/combiEngine_opensource_linux $(srcdir)/sysync_SDK/Sources" \ PREDEFINED="`cat $(srcdir)/Targets/ReleasedProducts/combiEngine_opensource_linux/target_options.h | grep '^#define' | grep '1 *$$' | sed -e 's/#define //' -e 's/ 1//'`" \ doxygen $< .PHONY: doxygen doxygen: html/index.html clean-doxygen: rm -rf html if COND_DOXYGEN all: doxygen clean-local: clean-doxygen endiflibsynthesis-3.4.0.47.1/src/Targets/000077500000000000000000000000001226375725500170445ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/Targets/ReleasedProducts/000077500000000000000000000000001226375725500223145ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/Targets/ReleasedProducts/SDK/000077500000000000000000000000001226375725500227355ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/Targets/ReleasedProducts/SDK/define.h000066400000000000000000000077741226375725500243570ustar00rootroot00000000000000 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // NOTE: this is a local copy for this specific target // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! /*************************************************************************/ /* module: Compiler Flag Definition File */ /* file: define.h */ /* target system: win */ /* target OS: win */ /*************************************************************************/ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ /** * File for Windows Specific Compiler Flags */ #ifndef _DEFINE_H #define _DEFINE_H #define __ANSI_C__ /* thread safety (added by luz@synthesis.ch, 2001-10-29) */ /* Note: moved define of this to target_options.h of every target */ #undef __MAKE_THREADSAFE /* enable Alloc helpers */ #define __USE_ALLOCFUNCS__ /* do we need WBXML (binary XML) processing ? */ #define __SML_WBXML__ /* do we need the capability to decode plain text tokens in WBXML? */ #define __SML_WBXML_TEXTTOKENS__ /* do we need XML processing ? */ #define __SML_XML__ /* are we using a 'light' toolkit ? */ //#define __SML_LITE__ /* do we use Sub DTD extensions ? */ #define __USE_EXTENSIONS__ /* do we need Metainformation DTD parsing ? */ #define __USE_METINF__ /* do we use Device Info DTD ? */ #define __USE_DEVINF__ /* which of the following optional commands should be included ? */ #define ADD_SEND //#define ATOMIC_SEND //#define ATOMIC_RECEIVE //#define COPY_SEND //#define COPY_RECEIVE //#define EXEC_SEND //#define EXEC_RECEIVE #define GET_SEND #define MAP_RECEIVE #define MAPITEM_RECEIVE #define RESULT_RECEIVE //#define SEARCH_SEND //#define SEARCH_RECEIVE //#define SEQUENCE_SEND //#define SEQUENCE_RECEIVE /* TK: to improve interoperability and handling we * switched to using .def files instead of compiler * specific per function definitions. As long as we only * use C this is the easiest and cleanes way */ #define SML_API #define SML_API_DEF #define XPT_API #define XPT_API_DEF /* Multi segment macro for Palm OS */ #define LIB_FUNC #define MGR_FUNC #define WSM_FUNC #define XLT_FUNC #endif libsynthesis-3.4.0.47.1/src/Targets/ReleasedProducts/SDK/target_options.h000066400000000000000000000023501226375725500261470ustar00rootroot00000000000000/* * File: target_options.h * * Author: Beat Forster (bfo@synthesis.ch), * Patrick Ohly (patrick.ohly@intel.com) * * Programming interface between Synthesis SyncML engine * and a database structure or client. * * Options for the client side which links against * libsynthesissdk. * * Copyright (c) 2009-2011 by Synthesis AG + plan44.ch * */ #ifndef TARGET_OPTIONS_H #define TARGET_OPTIONS_H /* - find out target platform */ #if defined (__MACH__) && defined(__APPLE__) #define MACOSX #else #if defined __MWERKS__ || defined _MSC_VER #ifndef _WIN32 #define _WIN32 #endif #else #define LINUX #endif #endif /* - we are not at the SyncML engine's side here */ #undef SYSYNC_ENGINE /* - but we link directly to the module */ #define DBAPI_LINKED 1 /* * The libsynthesis shared library uses SySync_ as prefix for C * functions. TEngineModuleBridge checks for the name with and without * the prefix, so clients are compatible with the current shared * libraries and (potentially older) commercial releases. */ #define SYSYNC_EXTERNAL(_x) SySync_ ## _x #define SYSYNC_PREFIX "SySync_" /* activate debug output */ #define SYDEBUG 2 #define NOWSM 1 #endif /* TARGET_OPTIONS_H */ /* eof */ libsynthesis-3.4.0.47.1/src/Targets/ReleasedProducts/clientEngine_DEMO_linux/000077500000000000000000000000001226375725500267435ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/Targets/ReleasedProducts/clientEngine_DEMO_linux/clientengine_demo++.pch000077500000000000000000000031431226375725500332410ustar00rootroot00000000000000/* precompiled headers source file * =============================== * * CVS: * $Author: bfo $ * $Date: 2007/11/08 15:58:02 $ * $Revision: 1.1 $ * $Source: /usr/local/cvsroot/sysync/Source/Targets/ReleasedProducts/clientEngine_DEMO_linux/clientengine_demo++.pch,v $ * $State: Exp $ * $Name: $ (Tag) * $Locker: $ (who has reserved checkout) * Log: * $Log: clientengine_demo++.pch,v $ * Revision 1.1 2007/11/08 15:58:02 bfo * project files added * * Revision 1.1 2007/10/02 10:12:57 luz * Added clientEngine_DEMO target to xcode * * Revision 1.1 2007/09/13 18:55:30 luz * New DEMO client engine (SQLite, TextDB but no ODBC nor DBPlugins) release target * * Revision 1.1 2007/09/05 14:03:05 luz * client engine with custom datastores (SQL, ODBC, SQLite and PluginAPI) * * Revision 1.2 2007/04/25 11:59:30 luz * Moved platform specific includes to syncclient_outlook_precomp.h - it belongs there so that file can be used in MW precompiled header source files (.pch) as well as in prefix_file.h for VC++. * * Revision 1.1 2004/02/04 14:24:06 luz * 2.0.5.3 s2g/ONE client release (and Oracle release candidate) checkin * * */ // SySync is a C++ project, make sure precomp headers // are compiled as C++! #pragma cplusplus on // determine target file name #pragma precompile_target "clientengine_demo_x86_linux++.mch" // include all headers that are suitable for precompiled use // - target options can incfluence everything #include "target_options.h" // - precompilable headers #include "clientengine_custom_precomp.h" // eof libsynthesis-3.4.0.47.1/src/Targets/ReleasedProducts/clientEngine_DEMO_linux/clientengine_demo.pch000077500000000000000000000023031226375725500331100ustar00rootroot00000000000000/* precompiled headers source file * =============================== * * CVS: * $Author: bfo $ * $Date: 2007/11/08 15:58:02 $ * $Revision: 1.1 $ * $Source: /usr/local/cvsroot/sysync/Source/Targets/ReleasedProducts/clientEngine_DEMO_linux/clientengine_demo.pch,v $ * $State: Exp $ * $Name: $ (Tag) * $Locker: $ (who has reserved checkout) * Log: * $Log: clientengine_demo.pch,v $ * Revision 1.1 2007/11/08 15:58:02 bfo * project files added * * Revision 1.1 2007/10/02 10:12:57 luz * Added clientEngine_DEMO target to xcode * * Revision 1.1 2007/09/13 18:55:30 luz * New DEMO client engine (SQLite, TextDB but no ODBC nor DBPlugins) release target * * Revision 1.1 2007/09/05 14:03:05 luz * client engine with custom datastores (SQL, ODBC, SQLite and PluginAPI) * * */ // C-version for SyncML toolkit files #pragma cplusplus off // determine target file name #pragma precompile_target "clientengine_demo_x86_linux.mch" // include all headers that are suitable for precompiled // C version use // - target options can incfluence everything #include "target_options.h" // standard SyncML TK stuff #include "smltk_precomp.h" // eof clientengine_demo_x86_linux_prefix.h000066400000000000000000000010661226375725500360110ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/Targets/ReleasedProducts/clientEngine_DEMO_linux/* prefix file * =========== * */ #ifdef __cplusplus // include all headers that are suitable for precompiled use // - target options can incfluence everything #include "target_options.h" // - platform specifics #include "platform_headers.h" // - precompilable headers #include "clientengine_custom_precomp.h" #else // include all headers that are suitable for precompiled // C version use // - target options can incfluence everything #include "target_options.h" // - platform specifics #include "platform_headers.h" #endif /* eof */ libsynthesis-3.4.0.47.1/src/Targets/ReleasedProducts/clientEngine_DEMO_linux/define.h000077500000000000000000000077741226375725500303700ustar00rootroot00000000000000 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // NOTE: this is a local copy for this specific target // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! /*************************************************************************/ /* module: Compiler Flag Definition File */ /* file: define.h */ /* target system: win */ /* target OS: win */ /*************************************************************************/ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ /** * File for Windows Specific Compiler Flags */ #ifndef _DEFINE_H #define _DEFINE_H #define __ANSI_C__ /* thread safety (added by luz@synthesis.ch, 2001-10-29) */ /* Note: moved define of this to target_options.h of every target */ #undef __MAKE_THREADSAFE /* enable Alloc helpers */ #define __USE_ALLOCFUNCS__ /* do we need WBXML (binary XML) processing ? */ #define __SML_WBXML__ /* do we need the capability to decode plain text tokens in WBXML? */ #define __SML_WBXML_TEXTTOKENS__ /* do we need XML processing ? */ #define __SML_XML__ /* are we using a 'light' toolkit ? */ //#define __SML_LITE__ /* do we use Sub DTD extensions ? */ #define __USE_EXTENSIONS__ /* do we need Metainformation DTD parsing ? */ #define __USE_METINF__ /* do we use Device Info DTD ? */ #define __USE_DEVINF__ /* which of the following optional commands should be included ? */ #define ADD_SEND //#define ATOMIC_SEND //#define ATOMIC_RECEIVE //#define COPY_SEND //#define COPY_RECEIVE //#define EXEC_SEND //#define EXEC_RECEIVE #define GET_SEND #define MAP_RECEIVE #define MAPITEM_RECEIVE #define RESULT_RECEIVE //#define SEARCH_SEND //#define SEARCH_RECEIVE //#define SEQUENCE_SEND //#define SEQUENCE_RECEIVE /* TK: to improve interoperability and handling we * switched to using .def files instead of compiler * specific per function definitions. As long as we only * use C this is the easiest and cleanes way */ #define SML_API #define SML_API_DEF #define XPT_API #define XPT_API_DEF /* Multi segment macro for Palm OS */ #define LIB_FUNC #define MGR_FUNC #define WSM_FUNC #define XLT_FUNC #endif libsynthesis-3.4.0.47.1/src/Targets/ReleasedProducts/clientEngine_DEMO_linux/target_options.h000077500000000000000000000134521226375725500321650ustar00rootroot00000000000000/* Target options * ============== * * */ // SYNCML CLIENT ENGINE LIBRARY DEMO Linux // ####################################### // - define to make release version // define platform #define LINUX // Release version status #undef RELEASE_VERSION #define RELEASE_SYDEBUG 2 // extended DBG included //#define OPTIONAL_SYDEBUG 1 // now include platform independent product options (which include global_options.h) #include "product_options.h" // Identification strings #define CUST_SYNC_MAN SYSYNC_OEM // manufactured by ourselves #define CUST_SYNC_MODEL "SySync Client Library DEMO Linux" #define CUST_SYNC_FIRMWARE NULL // no firmware #define CUST_SYNC_HARDWARE NULL // no hardware // String used to construct logfile names #define TARGETID "sysynclib_linux" // Configuration // ============= // Default profile #undef HARD_CODED_SERVER_URI #undef HARD_CODED_DBNAMES #define DEFAULT_SERVER_URI "" #define DEFAULT_LOCALDB_PROFILE "" #define DEFAULT_SERVER_USER "" #define DEFAULT_SERVER_PASSWD "" #define DEFAULT_ENCODING SML_WBXML #define DEFAULT_TRANSPORT_USER NULL #define DEFAULT_TRANSPORT_PASSWD NULL #define DEFAULT_SOCKS_HOST NULL #define DEFAULT_PROXY_HOST NULL #define DEFAULT_DATASTORES_ENABLED false #define DEFAULT_EVENTS_DAYSBEFORE 30 #define DEFAULT_EVENTS_DAYSAFTER 90 #define DEFAULT_EVENTS_LIMITED false #define DEFAULT_EMAILS_LIMITED true #define DEFAULT_EMAILS_HDRONLY true #define DEFAULT_EMAILS_MAXKB 2 #define DEFAULT_EMAILS_ONLYLAST true #define DEFAULT_EMAILS_DAYSBEFORE 10 // Eval limit options // ================== // Note: Hard expiration date settings moved to product_options.h // - if defined, server will stop working after defined date #undef VERSION_COMMENTS #define VERSION_COMMENTS "Demo Version Expiring after " EXPIRY_DATE_STRING #define EXPIRES_AFTER_DATE 1 // - if defined, software will stop specified number of days after // first use #undef EXPIRES_AFTER_DAYS // - if defined, software will run without valid license until hard // expiry date (EXPIRES_AFTER_DATE) and then continue only with a valid license #define NO_LICENSE_UNTIL_HARDEXPIRY 1 // - Identification for update check and demo period #define SYSER_VARIANT_CODE SYSER_VARIANT_DEMO #define SYSER_PRODUCT_CODE SYSER_PRODCODE_CLIENT_LIB_WIN32 #define SYSER_EXTRA_ID SYSER_EXTRA_ID_NONE // - if defined, software can be registered #define SYSER_REGISTRATION 1 // - define allowed product codes #define SYSER_PRODUCT_CODE_MAIN SYSER_PRODCODE_CLIENT_DEMO // a permanent DEMO license #define SYSER_PRODUCT_CODE_ALT1 SYSER_PRODCODE_CLIENT_LIB_LINUX // ..or a library license for MacOSX #define SYSER_PRODUCT_CODE_ALT2 SYSER_PRODCODE_CLIENT_LIB_ALL // ..or for all platforms #define SYSER_PRODUCT_CODE_ALT3 SYSER_PRODCODE_CLIENT_LIB_DESK // ..or for desktop platforms #define SYSER_PRODUCT_CODE_ALT4 SYSER_PRODCODE_CLIENT_ODBC_PRO_LINUX // ..or a PRO console client for MacOSX // - define needed product flags // only licenses that are release date limited (or explicitly NOT release date limited, // or time limited) are allowed #define SYSER_NEEDED_PRODUCT_FLAGS SYSER_PRODFLAG_MAXRELDATE #define SYSER_FORBIDDEN_PRODUCT_FLAGS 0 // Database support options // ======================== // - if defined, SQL support is included #define SQL_SUPPORT 1 #undef ODBCAPI_SUPPORT #define SQLITE_SUPPORT 1 // - if defined, ODBC DB mapping of arrays to aux tables is supported #define ARRAYDBTABLES_SUPPORT 1 // - if defined, SDK support is included #define SDK_SUPPORT 1 #undef PLUGIN_DLL // - define what SDK modules are linked in //#define DBAPI_DEMO 1 #define DBAPI_TEXT 1 #define FILEOBJ_SUPPORT 1 #define ADAPTITEM_SUPPORT 1 #define JNI_SUPPORT 1 // JNI needed for GUI, but without PLUGIN_DLL, JNI is not available for DB plugins (correct for DEMO!) // Datastore Options // ----------------- // - link in customimplds on top of binfile #define BASED_ON_BINFILE_CLIENT 1 // - SQL and API datastores have changedetection, so build binfile for that #define CHANGEDETECTION_AVAILABLE 1 // - we need a separate changelog mechanism #define CHECKSUM_CHANGELOG 1 // - string localIDs with sufficiently large size #define STRING_LOCALID_MAXLEN 256 // SySync options // ============== // - enhanced profile record #define ENHANCED_PROFILES_2004 1 #define CLIENTFEATURES_2008 1 // - NO support for automatic syncing (timed, IPP, server alerted...) #undef AUTOSYNC_SUPPORT // - support for intelligent push & poll (IPP) //#define IPP_SUPPORT 1 //#define IPP_SUPPORT_ALWAYS 1 // regardless of license flags // - support for timed sync #undef TIMEDSYNC_SUPPORT // - support for WAP push alerted sync #undef SERVERALERT_SUPPORT // - support for Proxy #define PROXY_SUPPORT 1 // - support for multiple profiles #define MULTI_PROFILE_SUPPORT 1 // - show progress events #define PROGRESS_EVENTS 1 // - we do not need to squeeze code #undef MINIMAL_CODE // - script with regex support #define SCRIPT_SUPPORT #define REGEX_SUPPORT // - client does not need target options #undef SYSYNC_TARGET_OPTIONS // - filters #define OBJECT_FILTERING // - client does not need superdatastores #undef SUPERDATASTORES // general options needed for email #define EMAIL_FORMAT_SUPPORT 1 #define EMAIL_ATTACHMENT_SUPPORT 1 #define ARRAYFIELD_SUPPORT 1 // - if defined, stream field support will be included #define STREAMFIELD_SUPPORT 1 // - if defined, semi-proprietary zipped-binary for items (any type) can be used // (enabled on a by type basis in the config) #define ZIPPED_BINDATA_SUPPORT 1 // - where to save application data by default (if not otherwise configured) // APPDATA_SUBDIR is a subdirectory of the user's "application data" dir. #define APPDATA_SUBDIR "synthesis.ch/SySyncLib" // - if defined, code for incoming and outgoing SyncML dumping into (WB)XML logfiles is included #define MSGDUMP 1 /* eof */ libsynthesis-3.4.0.47.1/src/Targets/ReleasedProducts/clientEngine_autotools/000077500000000000000000000000001226375725500270315ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/Targets/ReleasedProducts/clientEngine_autotools/systemxml/000077500000000000000000000000001226375725500310765ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/Targets/ReleasedProducts/clientEngine_autotools/systemxml/xmlparse.h000066400000000000000000000001551226375725500331030ustar00rootroot00000000000000/* redirect #include as used in the source to xmltok/xmlparse.h */ #include libsynthesis-3.4.0.47.1/src/Targets/ReleasedProducts/clientEngine_opensource_ios/000077500000000000000000000000001226375725500300345ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/Targets/ReleasedProducts/clientEngine_opensource_ios/define.h000066400000000000000000000100351226375725500314360ustar00rootroot00000000000000 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // NOTE: this is a local copy for this specific target // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! /*************************************************************************/ /* module: Compiler Flag Definition File */ /* file: define.h */ /* target system: win */ /* target OS: win */ /*************************************************************************/ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ /** * File for Windows Specific Compiler Flags */ #ifndef _DEFINE_H #define _DEFINE_H #define __ANSI_C__ /* thread safety (added by luz@synthesis.ch, 2001-10-29) */ /* Note: moved define of this to target_options.h of every target */ #undef __MAKE_THREADSAFE /* enable Alloc helpers */ #define __USE_ALLOCFUNCS__ /* do we need WBXML (binary XML) processing ? */ #define __SML_WBXML__ /* do we need the capability to decode plain text tokens in WBXML? */ #define __SML_WBXML_TEXTTOKENS__ /* do we need XML processing ? */ #define __SML_XML__ /* are we using a 'light' toolkit ? */ //#define __SML_LITE__ /* do we use Sub DTD extensions ? */ #define __USE_EXTENSIONS__ /* do we need Metainformation DTD parsing ? */ #define __USE_METINF__ /* do we use Device Info DTD ? */ #define __USE_DEVINF__ /* which of the following optional commands should be included ? */ #define ADD_SEND //#define ATOMIC_SEND //#define ATOMIC_RECEIVE //#define COPY_SEND //#define COPY_RECEIVE //#define EXEC_SEND //#define EXEC_RECEIVE #define GET_SEND #define MAP_RECEIVE #define MAPITEM_RECEIVE #define RESULT_RECEIVE //#define SEARCH_SEND //#define SEARCH_RECEIVE //#define SEQUENCE_SEND //#define SEQUENCE_RECEIVE /* TK: to improve interoperability and handling we * switched to using .def files instead of compiler * specific per function definitions. As long as we only * use C this is the easiest and cleanes way */ #define SML_API #define SML_API_DEF #define XPT_API #define XPT_API_DEF /* Multi segment macro for Palm OS */ #define LIB_FUNC #define MGR_FUNC #define WSM_FUNC #define XLT_FUNC #endif libsynthesis-3.4.0.47.1/src/Targets/ReleasedProducts/clientEngine_opensource_ios/prefix_file.h000066400000000000000000000010121226375725500324730ustar00rootroot00000000000000#ifndef __PREFIX_FILE_H #define __PREFIX_FILE_H #ifdef __cplusplus // include all headers that are suitable for precompiled use // - target options can incfluence everything #include "target_options.h" // - precompilable headers #include "clientengine_custom_precomp.h" #else // include all headers that are suitable for precompiled // C version use // - target options can incfluence everything #include "target_options.h" // - SML toolkit WITHOUT xpt part #include "smltk_precomp.h" #endif #endifsyncml_tk_prefix_file.h000066400000000000000000000003341226375725500345050ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/Targets/ReleasedProducts/clientEngine_opensource_ios#ifndef __SMLTK_PREFIX_FILE_H #define __SMLTK_PREFIX_FILE_H // C version use // - target options can incfluence everything #include "target_options.h" // - SML toolkit WITHOUT xpt part #include "smltk_precomp.h" #endiflibsynthesis-3.4.0.47.1/src/Targets/ReleasedProducts/clientEngine_opensource_ios/target_options.h000066400000000000000000000151221226375725500332470ustar00rootroot00000000000000/* Target options * ============== */ // SYNCML CLIENT ENGINE LIBRARY OPENSOURCE iOS // ########################################### // define platform // - we are on MACOSX (but on the mobile variant aka iOS of it) #define MACOSX 1 #define MOBOSX 1 // - XCode does support exceptions #define TARGET_HAS_EXCEPTIONS 1 // Release version status #if !DEBUG #define RELEASE_VERSION #endif #define RELEASE_SYDEBUG 1 // no extended DBG included //#define OPTIONAL_SYDEBUG 1 // Eval limit options // ================== // Opensource version does not have any licensing checks #define NEVER_EXPIRES_IS_OK 1 // to explicitly override check in SyncAppBase // now include platform independent product options (which include global_options.h) #include "product_options.h" // turn on console for XCode debug builds #if DEBUG #define CONSOLEINFO 1 // sysync enables console output with this #define CONSOLEDBG 1 // our Cocoa wrapper code and plugins enables some debug message with this #define SYDEBUG_LOCATION "" // source code links enabled #endif // enable tunnel API for direct access to backend datastores #define DBAPI_TUNNEL_SUPPORT 1 // Identification strings #define CUST_SYNC_MAN SYSYNC_OEM // manufactured by ourselves #define CUST_SYNC_MODEL "SySync Client Library Opensource iOS" #define CUST_SYNC_FIRMWARE NULL // no firmware #define CUST_SYNC_HARDWARE NULL // no hardware #define SYNCML_CLIENT_DEVTYP "pda"; // iPhone and iPod Touch can be seen as PDA (better than "smartphone", the iPod is not a phone) // String used to construct logfile names #define TARGETID "sysynclib_client_iphoneos" // Configuration // ============= // Default profile #undef HARD_CODED_SERVER_URI #undef HARD_CODED_DBNAMES #define DEFAULT_SERVER_URI "http://" #define DEFAULT_LOCALDB_PROFILE "" #define DEFAULT_SERVER_USER "" #define DEFAULT_SERVER_PASSWD "" #define DEFAULT_ENCODING SML_WBXML #define DEFAULT_TRANSPORT_USER NULL #define DEFAULT_TRANSPORT_PASSWD NULL #define DEFAULT_SOCKS_HOST NULL #define DEFAULT_PROXY_HOST NULL #define DEFAULT_DATASTORES_ENABLED false #define DEFAULT_EVENTS_DAYSBEFORE 30 #define DEFAULT_EVENTS_DAYSAFTER 90 #define DEFAULT_EVENTS_LIMITED false #define DEFAULT_EMAILS_LIMITED true #define DEFAULT_EMAILS_HDRONLY true #define DEFAULT_EMAILS_MAXKB 2 #define DEFAULT_EMAILS_ONLYLAST true #define DEFAULT_EMAILS_DAYSBEFORE 10 // Eval limit options // ================== // Note: Hard expiration date settings moved to product_options.h // - if defined, software will stop specified number of days after // first use #undef EXPIRES_AFTER_DAYS // Engine does not have auto-demo // Identification for update check and demo period #define SYSER_VARIANT_CODE SYSER_VARIANT_PRO #define SYSER_PRODUCT_CODE SYSER_PRODCODE_CLIENT_LIB_IPHONEOS #define SYSER_EXTRA_ID SYSER_EXTRA_ID_NONE // This is a static library hard-linked with the plan44.ch app sold via AppStore and thus needs no licensing // and may not expire #undef SYSER_REGISTRATION #undef VERSION_COMMENTS #define VERSION_COMMENTS "plan44.ch libsynthesis opensource" #undef EXPIRES_AFTER_DATE // - define allowed product codes #define SYSER_PRODUCT_CODE_MAIN SYSER_PRODUCT_CODE // license specifically for the product we are #define SYSER_PRODUCT_CODE_ALT1 SYSER_PRODCODE_CLIENT_PDA_PRO // a PRO license for a PDA client works as well #define SYSER_PRODUCT_CODE_ALT2 SYSER_PRODCODE_CLIENT_LIB_ALL #define SYSER_PRODUCT_CODE_ALT3 SYSER_PRODCODE_CLIENT_LIB_MOBILE #undef SYSER_PRODUCT_CODE_ALT4 // - define needed product flags // only licenses that are release date limited (or explicitly NOT release date limited, // or time limited) are allowed #define SYSER_NEEDED_PRODUCT_FLAGS SYSER_PRODFLAG_MAXRELDATE #define SYSER_FORBIDDEN_PRODUCT_FLAGS 0 // for the internal version, DLL plugins are always allowed // (even with licenses that do not have SYSER_PRODFLAG_SERVER_SDKAPI set) // because we do not use a license at all! #define DLL_PLUGINS_ALWAYS_ALLOWED 1 // SySync options // ============== // - we can rely on iOS devices to have a unique device ID // (disables userhash-for-Oracle server workarounds we need e.g. for WinMobile with all those crappy // OEM implementations like MotoQ and SGH i780 that return same ID for all devices). #define GUARANTEED_UNIQUE_DEVICID 1 // - enhanced profile record #define ENHANCED_PROFILES_2004 1 #define CLIENTFEATURES_2008 1 // - support for Proxy #define PROXY_SUPPORT 1 // - support for multiple profiles #define MULTI_PROFILE_SUPPORT 1 // - show progress events #define PROGRESS_EVENTS 1 // - we do not need to squeeze code #undef MINIMAL_CODE // - script with regex support #define SCRIPT_SUPPORT #define REGEX_SUPPORT // - client does not need target options #undef SYSYNC_TARGET_OPTIONS // - filters #define OBJECT_FILTERING // - client does not need superdatastores #undef SUPERDATASTORES // general options needed for email #define EMAIL_FORMAT_SUPPORT 1 #define EMAIL_ATTACHMENT_SUPPORT 1 #define ARRAYFIELD_SUPPORT 1 // - if defined, stream field support will be included #define STREAMFIELD_SUPPORT 1 // - if defined, semi-proprietary zipped-binary for items (any type) can be used // (enabled on a by type basis in the config) #define ZIPPED_BINDATA_SUPPORT 1 // - where to save application data by default (if not otherwise configured) // APPDATA_SUBDIR is a subdirectory of the user's "application data" dir. #define APPDATA_SUBDIR "plan44.ch/sysynclib_client" #if RELEASE_SYDEBUG>0 // - if defined, code for incoming and outgoing SyncML dumping into (WB)XML logfiles is included #define MSGDUMP 1 #else #undef MSGDUMP #endif // Datastore Options // ----------------- // - link in customimplds on top of binfile #define BASED_ON_BINFILE_CLIENT 1 // - SQL and API datastores have changedetection, so build binfile for that #define CHANGEDETECTION_AVAILABLE 1 // - we need a separate changelog mechanism #define CHECKSUM_CHANGELOG 1 // - string localIDs with sufficiently large size #define STRING_LOCALID_MAXLEN 256 // - supports SQL, but no ODBC, SQLite and DBApi #define SQL_SUPPORT 1 #undef ODBCAPI_SUPPORT #define SQLITE_SUPPORT 1 // - master detail (array) tables supported #define ARRAYDBTABLES_SUPPORT 1 // - Plugin SDK support is included #define SDK_SUPPORT 1 #undef PLUGIN_DLL // no external dylib plugins, iOS SDK does not allow them #define IPHONE_PLUGINS_STATIC 1 // iOS SDK needs statically linked plugins // - always link 4 custom plugins. A separate project provides a set of // 4 dummy plugins that can be linked if no real custom plugins are needed // (e.g. in a SQLite3 only sync) #define HARDCODED_CUSTOM 1 // - always link the TAB separate text file plugin #define DBAPI_TEXT 1 /* eof */ libsynthesis-3.4.0.47.1/src/Targets/ReleasedProducts/clientEngine_opensource_linux/000077500000000000000000000000001226375725500304015ustar00rootroot00000000000000clientengine_demo++.pch000066400000000000000000000007501226375725500346160ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/Targets/ReleasedProducts/clientEngine_opensource_linux/* precompiled headers source file * =============================== * * */ // SySync is a C++ project, make sure precomp headers // are compiled as C++! #pragma cplusplus on // determine target file name #pragma precompile_target "clientengine_demo_x86_linux++.mch" // include all headers that are suitable for precompiled use // - target options can incfluence everything #include "target_options.h" // - precompilable headers #include "clientengine_custom_precomp.h" // eof clientengine_demo.pch000066400000000000000000000006731226375725500344740ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/Targets/ReleasedProducts/clientEngine_opensource_linux/* precompiled headers source file * =============================== * */ // C-version for SyncML toolkit files #pragma cplusplus off // determine target file name #pragma precompile_target "clientengine_demo_x86_linux.mch" // include all headers that are suitable for precompiled // C version use // - target options can incfluence everything #include "target_options.h" // standard SyncML TK stuff #include "smltk_precomp.h" // eof clientengine_demo_x86_linux_prefix.h000066400000000000000000000017261226375725500374520ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/Targets/ReleasedProducts/clientEngine_opensource_linux/* prefix file * =========== * */ // override default in global_options.h: // use SySync_ as prefix for external C functions #define SYSYNC_EXTERNAL(_x) SySync_ ## _x #define SYSYNC_PREFIX "SySync_" // required before time.h to get tm_gmtoff in struct tm: // this is used to find standard and daylight saving offset // of the system, see timezones.cpp #define _BSD_SOURCE 1 #define USE_TM_GMTOFF 1 // required for vasprintf #define _GNU_SOURCE 1 #ifdef __cplusplus // include all headers that are suitable for precompiled use // - target options can incfluence everything #include "target_options.h" // - platform specifics #include "platform_headers.h" // - precompilable headers #include "clientengine_custom_precomp.h" #else // include all headers that are suitable for precompiled // C version use // - target options can incfluence everything #include "target_options.h" // - platform specifics #include "platform_headers.h" #endif /* eof */ libsynthesis-3.4.0.47.1/src/Targets/ReleasedProducts/clientEngine_opensource_linux/define.h000077500000000000000000000077741226375725500320260ustar00rootroot00000000000000 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // NOTE: this is a local copy for this specific target // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! /*************************************************************************/ /* module: Compiler Flag Definition File */ /* file: define.h */ /* target system: win */ /* target OS: win */ /*************************************************************************/ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ /** * File for Windows Specific Compiler Flags */ #ifndef _DEFINE_H #define _DEFINE_H #define __ANSI_C__ /* thread safety (added by luz@synthesis.ch, 2001-10-29) */ /* Note: moved define of this to target_options.h of every target */ #undef __MAKE_THREADSAFE /* enable Alloc helpers */ #define __USE_ALLOCFUNCS__ /* do we need WBXML (binary XML) processing ? */ #define __SML_WBXML__ /* do we need the capability to decode plain text tokens in WBXML? */ #define __SML_WBXML_TEXTTOKENS__ /* do we need XML processing ? */ #define __SML_XML__ /* are we using a 'light' toolkit ? */ //#define __SML_LITE__ /* do we use Sub DTD extensions ? */ #define __USE_EXTENSIONS__ /* do we need Metainformation DTD parsing ? */ #define __USE_METINF__ /* do we use Device Info DTD ? */ #define __USE_DEVINF__ /* which of the following optional commands should be included ? */ #define ADD_SEND //#define ATOMIC_SEND //#define ATOMIC_RECEIVE //#define COPY_SEND //#define COPY_RECEIVE //#define EXEC_SEND //#define EXEC_RECEIVE #define GET_SEND #define MAP_RECEIVE #define MAPITEM_RECEIVE #define RESULT_RECEIVE //#define SEARCH_SEND //#define SEARCH_RECEIVE //#define SEQUENCE_SEND //#define SEQUENCE_RECEIVE /* TK: to improve interoperability and handling we * switched to using .def files instead of compiler * specific per function definitions. As long as we only * use C this is the easiest and cleanes way */ #define SML_API #define SML_API_DEF #define XPT_API #define XPT_API_DEF /* Multi segment macro for Palm OS */ #define LIB_FUNC #define MGR_FUNC #define WSM_FUNC #define XLT_FUNC #endif libsynthesis-3.4.0.47.1/src/Targets/ReleasedProducts/clientEngine_opensource_linux/target_options.h000077500000000000000000000136231226375725500336230ustar00rootroot00000000000000/* Target options * ============== * * */ // SYNCML CLIENT ENGINE LIBRARY OPENSOURCE LINUX // ############################################# // define platform #define LINUX // Release version status #define RELEASE_VERSION #define RELEASE_SYDEBUG 2 // extended DBG included //#define OPTIONAL_SYDEBUG 1 // Eval limit options // ================== // OpenSource Library does not have any expiry mechanisms #define NEVER_EXPIRES_IS_OK 1 // to explicitly override check in SyncAppBase // now include platform independent product options (which include global_options.h) #include "product_options.h" // Identification strings #define CUST_SYNC_MAN SYSYNC_OEM // manufactured by ourselves #define CUST_SYNC_MODEL "SySync Client Library OpenSource Linux" #define CUST_SYNC_FIRMWARE NULL // no firmware #define CUST_SYNC_HARDWARE NULL // no hardware #define SYNCML_CLIENT_DEVTYP "pda"; // Linux mobiles are probably more "PDA"s than pure "smartphones" // String used to construct logfile names #define TARGETID "sysynclib_linux" // Configuration // ============= // Default profile #undef HARD_CODED_SERVER_URI #undef HARD_CODED_DBNAMES #define DEFAULT_SERVER_URI "http://" #define DEFAULT_LOCALDB_PROFILE "" #define DEFAULT_SERVER_USER "" #define DEFAULT_SERVER_PASSWD "" #define DEFAULT_ENCODING SML_WBXML #define DEFAULT_TRANSPORT_USER NULL #define DEFAULT_TRANSPORT_PASSWD NULL #define DEFAULT_SOCKS_HOST NULL #define DEFAULT_PROXY_HOST NULL #define DEFAULT_DATASTORES_ENABLED false #define DEFAULT_EVENTS_DAYSBEFORE 30 #define DEFAULT_EVENTS_DAYSAFTER 90 #define DEFAULT_EVENTS_LIMITED false #define DEFAULT_EMAILS_LIMITED true #define DEFAULT_EMAILS_HDRONLY true #define DEFAULT_EMAILS_MAXKB 2 #define DEFAULT_EMAILS_ONLYLAST true #define DEFAULT_EMAILS_DAYSBEFORE 10 // Eval limit options // ================== // Note: Hard expiration date settings moved to product_options.h // - if defined, software will stop specified number of days after // first use #undef EXPIRES_AFTER_DAYS // Engine does not have auto-demo // Identification for update check and demo period #define SYSER_VARIANT_CODE SYSER_VARIANT_PRO #define SYSER_PRODUCT_CODE SYSER_PRODCODE_CLIENT_LIB_LINUX #define SYSER_EXTRA_ID SYSER_EXTRA_ID_NONE // This is the opensource Linux library, and needs no registration #undef SYSER_REGISTRATION #undef VERSION_COMMENTS #define VERSION_COMMENTS "Synthesis OpenSource" #undef EXPIRES_AFTER_DATE // - define allowed product codes #define SYSER_PRODUCT_CODE_MAIN SYSER_PRODCODE_CLIENT_DEMO // a permanent DEMO license #define SYSER_PRODUCT_CODE_ALT1 SYSER_PRODCODE_CLIENT_LIB_LINUX // ..or a library license for Linux #define SYSER_PRODUCT_CODE_ALT2 SYSER_PRODCODE_CLIENT_LIB_ALL // ..or for all platforms #define SYSER_PRODUCT_CODE_ALT3 SYSER_PRODCODE_CLIENT_LIB_DESK // ..or for desktop platforms #define SYSER_PRODUCT_CODE_ALT4 SYSER_PRODCODE_CLIENT_ODBC_PRO_LINUX // ..or a PRO console client for Linux // - define needed product flags // only licenses that are release date limited (or explicitly NOT release date limited, // or time limited) are allowed #define SYSER_NEEDED_PRODUCT_FLAGS SYSER_PRODFLAG_MAXRELDATE #define SYSER_FORBIDDEN_PRODUCT_FLAGS 0 // for the opensource version, DLL plugins are always allowed // (even with licenses that do not have SYSER_PRODFLAG_SERVER_SDKAPI set) // because we do not use a license at all! #define DLL_PLUGINS_ALWAYS_ALLOWED 1 // Database support options // ======================== // - if defined, SQL support is included #define SQL_SUPPORT 1 #undef ODBCAPI_SUPPORT #define SQLITE_SUPPORT 1 // - if defined, ODBC DB mapping of arrays to aux tables is supported #define ARRAYDBTABLES_SUPPORT 1 // - if defined, SDK support is included #define SDK_SUPPORT 1 // - id defined, code allows calling of subsequent DLLs #define PLUGIN_DLL 1 // Datastore Options // ----------------- // - link in customimplds on top of binfile #define BASED_ON_BINFILE_CLIENT 1 // - SQL and API datastores have changedetection, so build binfile for that #define CHANGEDETECTION_AVAILABLE 1 // - we need a separate changelog mechanism #define CHECKSUM_CHANGELOG 1 // - string localIDs with sufficiently large size #define STRING_LOCALID_MAXLEN 256 // SySync options // ============== // - enhanced profile record #define ENHANCED_PROFILES_2004 1 #define CLIENTFEATURES_2008 1 // - NO support for automatic syncing (timed, IPP, server alerted...) #undef AUTOSYNC_SUPPORT // - support for intelligent push & poll (IPP) //#define IPP_SUPPORT 1 //#define IPP_SUPPORT_ALWAYS 1 // regardless of license flags // - support for timed sync #undef TIMEDSYNC_SUPPORT // - support for WAP push alerted sync #undef SERVERALERT_SUPPORT // - support for Proxy #define PROXY_SUPPORT 1 // - support for multiple profiles #define MULTI_PROFILE_SUPPORT 1 // - show progress events #define PROGRESS_EVENTS 1 // - we do not need to squeeze code #undef MINIMAL_CODE // - script with regex support #define SCRIPT_SUPPORT #define REGEX_SUPPORT // - client does not need target options #undef SYSYNC_TARGET_OPTIONS // - filters #define OBJECT_FILTERING // - client does not need superdatastores #undef SUPERDATASTORES // general options needed for email #define EMAIL_FORMAT_SUPPORT 1 #define EMAIL_ATTACHMENT_SUPPORT 1 #define ARRAYFIELD_SUPPORT 1 // - if defined, stream field support will be included #define STREAMFIELD_SUPPORT 1 // - if defined, semi-proprietary zipped-binary for items (any type) can be used // (enabled on a by type basis in the config) #define ZIPPED_BINDATA_SUPPORT 1 // - where to save application data by default (if not otherwise configured) // APPDATA_SUBDIR is a subdirectory of the user's "application data" dir. #define APPDATA_SUBDIR "synthesis.ch/SySyncLib" // - if defined, code for incoming and outgoing SyncML dumping into (WB)XML logfiles is included #define MSGDUMP 1 // - enable support for remote rules, despite being a client #undef NO_REMOTE_RULES /* eof */ libsynthesis-3.4.0.47.1/src/Targets/ReleasedProducts/combiEngine_opensource_ios/000077500000000000000000000000001226375725500276475ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/Targets/ReleasedProducts/combiEngine_opensource_ios/define.h000066400000000000000000000100351226375725500312510ustar00rootroot00000000000000 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // NOTE: this is a local copy for this specific target // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! /*************************************************************************/ /* module: Compiler Flag Definition File */ /* file: define.h */ /* target system: win */ /* target OS: win */ /*************************************************************************/ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ /** * File for Windows Specific Compiler Flags */ #ifndef _DEFINE_H #define _DEFINE_H #define __ANSI_C__ /* thread safety (added by luz@synthesis.ch, 2001-10-29) */ /* Note: moved define of this to target_options.h of every target */ #undef __MAKE_THREADSAFE /* enable Alloc helpers */ #define __USE_ALLOCFUNCS__ /* do we need WBXML (binary XML) processing ? */ #define __SML_WBXML__ /* do we need the capability to decode plain text tokens in WBXML? */ #define __SML_WBXML_TEXTTOKENS__ /* do we need XML processing ? */ #define __SML_XML__ /* are we using a 'light' toolkit ? */ //#define __SML_LITE__ /* do we use Sub DTD extensions ? */ #define __USE_EXTENSIONS__ /* do we need Metainformation DTD parsing ? */ #define __USE_METINF__ /* do we use Device Info DTD ? */ #define __USE_DEVINF__ /* which of the following optional commands should be included ? */ #define ADD_SEND //#define ATOMIC_SEND //#define ATOMIC_RECEIVE //#define COPY_SEND //#define COPY_RECEIVE //#define EXEC_SEND //#define EXEC_RECEIVE #define GET_SEND #define MAP_RECEIVE #define MAPITEM_RECEIVE #define RESULT_RECEIVE //#define SEARCH_SEND //#define SEARCH_RECEIVE //#define SEQUENCE_SEND //#define SEQUENCE_RECEIVE /* TK: to improve interoperability and handling we * switched to using .def files instead of compiler * specific per function definitions. As long as we only * use C this is the easiest and cleanes way */ #define SML_API #define SML_API_DEF #define XPT_API #define XPT_API_DEF /* Multi segment macro for Palm OS */ #define LIB_FUNC #define MGR_FUNC #define WSM_FUNC #define XLT_FUNC #endif libsynthesis-3.4.0.47.1/src/Targets/ReleasedProducts/combiEngine_opensource_ios/prefix_file.h000066400000000000000000000010121226375725500323060ustar00rootroot00000000000000#ifndef __PREFIX_FILE_H #define __PREFIX_FILE_H #ifdef __cplusplus // include all headers that are suitable for precompiled use // - target options can incfluence everything #include "target_options.h" // - precompilable headers #include "serverengine_custom_precomp.h" #else // include all headers that are suitable for precompiled // C version use // - target options can incfluence everything #include "target_options.h" // - SML toolkit WITHOUT xpt part #include "smltk_precomp.h" #endif #endifsyncml_tk_prefix_file.h000066400000000000000000000003341226375725500343200ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/Targets/ReleasedProducts/combiEngine_opensource_ios#ifndef __SMLTK_PREFIX_FILE_H #define __SMLTK_PREFIX_FILE_H // C version use // - target options can incfluence everything #include "target_options.h" // - SML toolkit WITHOUT xpt part #include "smltk_precomp.h" #endiflibsynthesis-3.4.0.47.1/src/Targets/ReleasedProducts/combiEngine_opensource_ios/target_options.h000066400000000000000000000153521226375725500330670ustar00rootroot00000000000000/* Target options * ============== */ // SYNCML UNIFIED CLIENT/SERVER ENGINE LIBRARY OPENSOURCE iOS // ########################################################## // define platform // - we are on MACOSX (but on the mobile variant aka iPhoneOS of it) #define MACOSX 1 #define MOBOSX 1 // - XCode does support exceptions #define TARGET_HAS_EXCEPTIONS 1 // Release version status #if !DEBUG #define RELEASE_VERSION #endif #define RELEASE_SYDEBUG 1 // no extended DBG included //#define OPTIONAL_SYDEBUG 1 // Eval limit options // ================== // Opensource version does not have any licensing checks #define NEVER_EXPIRES_IS_OK 1 // to explicitly override check in SyncAppBase // now include platform independent product options (which include global_options.h) #include "combi_product_options.h" // turn on console and source linking for XCode debug builds #if DEBUG #define CONSOLEINFO 1 // sysync enables console output with this #define CONSOLEDBG 1 // our Cocoa wrapper code and plugins enables some debug message with this #define SYDEBUG_LOCATION "" // source code links enabled #endif // enable tunnel API for direct access to backend datastores #define DBAPI_TUNNEL_SUPPORT 1 // Identification strings #define CUST_SYNC_MAN SYSYNC_OEM // manufactured by ourselves #define CUST_SYNC_MODEL "SySync SyncML Library Opensource iOS" #define CUST_SYNC_FIRMWARE NULL // no firmware #define CUST_SYNC_HARDWARE NULL // no hardware #define SYNCML_CLIENT_DEVTYP "pda"; // iPhone and iPod Touch can be seen as PDA (better than "smartphone", the iPod is not a phone) // String used to construct logfile names #define TARGETID "sysynclib_combi_iphoneos" // Configuration // ============= // Default profile #undef HARD_CODED_SERVER_URI #undef HARD_CODED_DBNAMES #define DEFAULT_SERVER_URI "http://" #define DEFAULT_LOCALDB_PROFILE "" #define DEFAULT_SERVER_USER "" #define DEFAULT_SERVER_PASSWD "" #define DEFAULT_ENCODING SML_WBXML #define DEFAULT_TRANSPORT_USER NULL #define DEFAULT_TRANSPORT_PASSWD NULL #define DEFAULT_SOCKS_HOST NULL #define DEFAULT_PROXY_HOST NULL #define DEFAULT_DATASTORES_ENABLED false #define DEFAULT_EVENTS_DAYSBEFORE 30 #define DEFAULT_EVENTS_DAYSAFTER 90 #define DEFAULT_EVENTS_LIMITED false #define DEFAULT_EMAILS_LIMITED true #define DEFAULT_EMAILS_HDRONLY true #define DEFAULT_EMAILS_MAXKB 2 #define DEFAULT_EMAILS_ONLYLAST true #define DEFAULT_EMAILS_DAYSBEFORE 10 // Eval limit options // ================== // Note: Hard expiration date settings moved to product_options.h // - if defined, software will stop specified number of days after // first use #undef EXPIRES_AFTER_DAYS // Engine does not have auto-demo // Identification for update check and demo period #define SYSER_VARIANT_CODE SYSER_VARIANT_PRO #define SYSER_PRODUCT_CODE SYSER_PRODCODE_SERVER_LIB_IPHONEOS // needs a server=unilib license #define SYSER_EXTRA_ID SYSER_EXTRA_ID_NONE // This is a static library hard-linked with the plan44.ch app sold via AppStore and thus needs no licensing // and may not expire #undef SYSER_REGISTRATION #undef VERSION_COMMENTS #define VERSION_COMMENTS "plan44.ch libsynthesis opensource" #undef EXPIRES_AFTER_DATE // - define allowed product codes #define SYSER_PRODUCT_CODE_MAIN SYSER_PRODUCT_CODE // license specifically for the product we are #define SYSER_PRODUCT_CODE_ALT1 SYSER_PRODCODE_CLIENT_PDA_PRO // a PRO license for a PDA client works for unilib as well #define SYSER_PRODUCT_CODE_ALT3 SYSER_PRODCODE_SERVER_LIB_MOBILE // server=unilib license needed #define SYSER_PRODUCT_CODE_ALT4 SYSER_PRODCODE_SERVER_LIB_ALL // server=unilib license needed // - define needed product flags // only licenses that are release date limited (or explicitly NOT release date limited, // or time limited) are allowed #define SYSER_NEEDED_PRODUCT_FLAGS SYSER_PRODFLAG_MAXRELDATE #define SYSER_FORBIDDEN_PRODUCT_FLAGS 0 // for the internal version, DLL plugins are always allowed // (even with licenses that do not have SYSER_PRODFLAG_SERVER_SDKAPI set) // because we do not use a license at all! #define DLL_PLUGINS_ALWAYS_ALLOWED 1 // SySync options // ============== // - we can rely on iOS devices to have a unique device ID // (disables userhash-for-Oracle server workarounds we need e.g. for WinMobile with all those crappy // OEM implementations like MotoQ and SGH i780 that return same ID for all devices). #define GUARANTEED_UNIQUE_DEVICID 1 // - enhanced profile record #define ENHANCED_PROFILES_2004 1 #define CLIENTFEATURES_2008 1 // - support for Proxy #define PROXY_SUPPORT 1 // - support for multiple profiles #define MULTI_PROFILE_SUPPORT 1 // - show progress events #define PROGRESS_EVENTS 1 // - we do not need to squeeze code #undef MINIMAL_CODE // - script with regex support #define SCRIPT_SUPPORT #define REGEX_SUPPORT // - server does support target options #define SYSYNC_TARGET_OPTIONS // - filters #define OBJECT_FILTERING 1 // - superdatastores #define SUPERDATASTORES 1 // general options needed for email #define EMAIL_FORMAT_SUPPORT 1 #define EMAIL_ATTACHMENT_SUPPORT 1 #define ARRAYFIELD_SUPPORT 1 // - if defined, stream field support will be included #define STREAMFIELD_SUPPORT 1 // - if defined, semi-proprietary zipped-binary for items (any type) can be used // (enabled on a by type basis in the config) #define ZIPPED_BINDATA_SUPPORT 1 // - where to save application data by default (if not otherwise configured) // APPDATA_SUBDIR is a subdirectory of the user's "application data" dir. #define APPDATA_SUBDIR "plan44.ch/sysynclib_combi" #if RELEASE_SYDEBUG>0 // - if defined, code for incoming and outgoing SyncML dumping into (WB)XML logfiles is included #define MSGDUMP 1 #else #undef MSGDUMP #endif // Datastore Options // ----------------- // - link in customimplds on top of binfile #define BASED_ON_BINFILE_CLIENT 1 // - SQL and API datastores have changedetection, so build binfile for that #define CHANGEDETECTION_AVAILABLE 1 // - we need a separate changelog mechanism #define CHECKSUM_CHANGELOG 1 // - string localIDs with sufficiently large size #define STRING_LOCALID_MAXLEN 256 // - supports SQL, but no ODBC, SQLite and DBApi #define SQL_SUPPORT 1 #undef ODBCAPI_SUPPORT #define SQLITE_SUPPORT 1 // - master detail (array) tables supported #define ARRAYDBTABLES_SUPPORT 1 // - Plugin SDK support is included #define SDK_SUPPORT 1 #undef PLUGIN_DLL // no external dylib plugins, iOS SDK does not allow them #define IPHONE_PLUGINS_STATIC 1 // iOS SDK needs statically linked plugins // - always link 4 custom plugins. A separate project provides a set of // 4 dummy plugins that can be linked if no real custom plugins are needed // (e.g. in a SQLite3 only sync) #define HARDCODED_CUSTOM 1 // - always link the TAB separate text file plugin (required for server admin data) #define DBAPI_TEXT 1 /* eof */ libsynthesis-3.4.0.47.1/src/Targets/ReleasedProducts/combiEngine_opensource_linux/000077500000000000000000000000001226375725500302145ustar00rootroot00000000000000combiengine_demo++.pch000066400000000000000000000007441226375725500342470ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/Targets/ReleasedProducts/combiEngine_opensource_linux/* precompiled headers source file * =============================== * */ // SySync is a C++ project, make sure precomp headers // are compiled as C++! #pragma cplusplus on // determine target file name #pragma precompile_target "combiengine_opensource_linux++.mch" // include all headers that are suitable for precompiled use // - target options can incfluence everything #include "target_options.h" // - precompilable headers #include "combiengine_custom_precomp.h" // eof combiengine_demo.pch000066400000000000000000000006731226375725500341220ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/Targets/ReleasedProducts/combiEngine_opensource_linux/* precompiled headers source file * =============================== * */ // C-version for SyncML toolkit files #pragma cplusplus off // determine target file name #pragma precompile_target "combiengine_opensource_linux.mch" // include all headers that are suitable for precompiled // C version use // - target options can incfluence everything #include "target_options.h" // standard SyncML TK stuff #include "smltk_precomp.h" // eof combiengine_opensource_linux_prefix.h000066400000000000000000000021761226375725500376310ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/Targets/ReleasedProducts/combiEngine_opensource_linux/* prefix file * =========== * */ // override default in global_options.h: // always use SySync_ as prefix for external C functions // - client #define SYSYNC_EXTERNAL(_x) SySync_ ## _x #define SYSYNC_PREFIX "SySync_" // - server #define SYSYNC_EXTERNAL_SRV(_x) SySync_srv_ ## _x #define SYSYNC_PREFIX_SRV "SySync_srv_" // required before time.h to get tm_gmtoff in struct tm: // this is used to find standard and daylight saving offset // of the system, see timezones.cpp #define _BSD_SOURCE 1 #define USE_TM_GMTOFF 1 // required for vasprintf #define _GNU_SOURCE 1 #ifdef __cplusplus // include all headers that are suitable for precompiled use // - target options can incfluence everything #include "target_options.h" // - platform specifics #include "platform_headers.h" // - precompilable headers (use those of server, but client is the same) #include "serverengine_custom_precomp.h" #else // include all headers that are suitable for precompiled // C version use // - target options can incfluence everything #include "target_options.h" // - platform specifics #include "platform_headers.h" #endif /* eof */ libsynthesis-3.4.0.47.1/src/Targets/ReleasedProducts/combiEngine_opensource_linux/define.h000066400000000000000000000077741226375725500316360ustar00rootroot00000000000000 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // NOTE: this is a local copy for this specific target // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! /*************************************************************************/ /* module: Compiler Flag Definition File */ /* file: define.h */ /* target system: win */ /* target OS: win */ /*************************************************************************/ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ /** * File for Windows Specific Compiler Flags */ #ifndef _DEFINE_H #define _DEFINE_H #define __ANSI_C__ /* thread safety (added by luz@synthesis.ch, 2001-10-29) */ /* Note: moved define of this to target_options.h of every target */ #undef __MAKE_THREADSAFE /* enable Alloc helpers */ #define __USE_ALLOCFUNCS__ /* do we need WBXML (binary XML) processing ? */ #define __SML_WBXML__ /* do we need the capability to decode plain text tokens in WBXML? */ #define __SML_WBXML_TEXTTOKENS__ /* do we need XML processing ? */ #define __SML_XML__ /* are we using a 'light' toolkit ? */ //#define __SML_LITE__ /* do we use Sub DTD extensions ? */ #define __USE_EXTENSIONS__ /* do we need Metainformation DTD parsing ? */ #define __USE_METINF__ /* do we use Device Info DTD ? */ #define __USE_DEVINF__ /* which of the following optional commands should be included ? */ #define ADD_SEND //#define ATOMIC_SEND //#define ATOMIC_RECEIVE //#define COPY_SEND //#define COPY_RECEIVE //#define EXEC_SEND //#define EXEC_RECEIVE #define GET_SEND #define MAP_RECEIVE #define MAPITEM_RECEIVE #define RESULT_RECEIVE //#define SEARCH_SEND //#define SEARCH_RECEIVE //#define SEQUENCE_SEND //#define SEQUENCE_RECEIVE /* TK: to improve interoperability and handling we * switched to using .def files instead of compiler * specific per function definitions. As long as we only * use C this is the easiest and cleanes way */ #define SML_API #define SML_API_DEF #define XPT_API #define XPT_API_DEF /* Multi segment macro for Palm OS */ #define LIB_FUNC #define MGR_FUNC #define WSM_FUNC #define XLT_FUNC #endif libsynthesis-3.4.0.47.1/src/Targets/ReleasedProducts/combiEngine_opensource_linux/target_options.h000066400000000000000000000152341226375725500334330ustar00rootroot00000000000000/* Target options * ============== * */ // Many of the options below can also be configured via config.h. // If ONOFF_ is defined, then the feature is on if // ONOFF_ is != 0, otherwise it is off. If that // define is not set, then the default setting in this file applies. #ifdef HAVE_CONFIG_H # include #endif // SYNCML SERVER ENGINE LIBRARY OPENSOURCE LINUX // ############################################# // define platform #define LINUX // Release version status #define RELEASE_VERSION #define RELEASE_SYDEBUG 2 // extended DBG included //#define OPTIONAL_SYDEBUG 1 // enable printing to console via libc by default, // might be turned off again in product_options.h #define CONSOLEINFO #define CONSOLEINFO_LIBC // Eval limit options // ================== // OpenSource Library does not have any expiry mechanisms #define NEVER_EXPIRES_IS_OK 1 // to explicitly override check in SyncAppBase // now include platform independent product options (which include global_options.h) #include "combi_product_options.h" // Identification strings #define CUST_SYNC_MAN SYSYNC_OEM // manufactured by ourselves #define CUST_SYNC_MODEL "SySync SyncML Library OpenSource Linux" #define CUST_SYNC_FIRMWARE NULL // no firmware #define CUST_SYNC_HARDWARE NULL // no hardware // String used to construct logfile names #define TARGETID "sysynclib_uni_linux" // Configuration // ============= // Default profile #undef HARD_CODED_SERVER_URI #undef HARD_CODED_DBNAMES #define DEFAULT_SERVER_URI "" #define DEFAULT_LOCALDB_PROFILE "" #define DEFAULT_SERVER_USER "" #define DEFAULT_SERVER_PASSWD "" #define DEFAULT_ENCODING SML_WBXML #define DEFAULT_TRANSPORT_USER NULL #define DEFAULT_TRANSPORT_PASSWD NULL #define DEFAULT_SOCKS_HOST NULL #define DEFAULT_PROXY_HOST NULL #define DEFAULT_DATASTORES_ENABLED false #define DEFAULT_EVENTS_DAYSBEFORE 30 #define DEFAULT_EVENTS_DAYSAFTER 90 #define DEFAULT_EVENTS_LIMITED false #define DEFAULT_EMAILS_LIMITED true #define DEFAULT_EMAILS_HDRONLY true #define DEFAULT_EMAILS_MAXKB 2 #define DEFAULT_EMAILS_ONLYLAST true #define DEFAULT_EMAILS_DAYSBEFORE 10 // Note: Hard expiration date settings moved to product_options.h // This is the opensource Linux library, and needs no registration #undef SYSER_REGISTRATION #undef VERSION_COMMENTS #define VERSION_COMMENTS "Synthesis OpenSource" #undef EXPIRES_AFTER_DATE // - if defined, software will stop specified number of days after // first use #undef EXPIRES_AFTER_DAYS // Engine does not have auto-demo // Identification for update check and demo period #define SYSER_VARIANT_CODE SYSER_VARIANT_PRO #define SYSER_PRODUCT_CODE SYSER_PRODCODE_SERVER_LIB_LINUX #define SYSER_EXTRA_ID SYSER_EXTRA_ID_NONE // - define allowed product codes #define SYSER_PRODUCT_CODE_MAIN SYSER_PRODCODE_SERVER_DEMO // a permanent DEMO license #define SYSER_PRODUCT_CODE_ALT1 SYSER_PRODCODE_SERVER_LIB_LINUX // ..or a library license for Linux #define SYSER_PRODUCT_CODE_ALT2 SYSER_PRODCODE_SERVER_LIB_ALL // ..or for all platforms #define SYSER_PRODUCT_CODE_ALT3 SYSER_PRODCODE_SERVER_LIB_DESK // ..or for desktop platforms #define SYSER_PRODUCT_CODE_ALT4 SYSER_PRODCODE_SERVER_ODBC_PRO_LINUX // ..or a PRO server for Linux // - define needed product flags // only licenses that are release date limited (or explicitly NOT release date limited, // or time limited) are allowed #define SYSER_NEEDED_PRODUCT_FLAGS SYSER_PRODFLAG_MAXRELDATE #define SYSER_FORBIDDEN_PRODUCT_FLAGS 0 // for the opensource version, DLL plugins are always allowed // (even with licenses that do not have SYSER_PRODFLAG_SERVER_SDKAPI set) // because we do not use a license at all! #define DLL_PLUGINS_ALWAYS_ALLOWED 1 // SySync options // ============== // - enhanced profile record #define ENHANCED_PROFILES_2004 1 #define CLIENTFEATURES_2008 1 // - NO support for automatic syncing (timed, IPP, server alerted...) #undef AUTOSYNC_SUPPORT // - support for intelligent push & poll (IPP) //#define IPP_SUPPORT 1 //#define IPP_SUPPORT_ALWAYS 1 // regardless of license flags // - support for timed sync #undef TIMEDSYNC_SUPPORT // - support for WAP push alerted sync #undef SERVERALERT_SUPPORT // - support for Proxy #define PROXY_SUPPORT 1 // - support for multiple profiles #define MULTI_PROFILE_SUPPORT 1 // - show progress events #define PROGRESS_EVENTS 1 // - we do not need to squeeze code #undef MINIMAL_CODE // - script with regex support #define SCRIPT_SUPPORT 1 #define REGEX_SUPPORT 1 #if defined(ONOFF_REGEX_SUPPORT) # if ONOFF_REGEX_SUPPORT # define REGEX_SUPPORT 1 # else # undef REGEX_SUPPORT # endif #endif // - server does support target options #define SYSYNC_TARGET_OPTIONS 1 // - filters #define OBJECT_FILTERING 1 // - server does need superdatastores #define SUPERDATASTORES 1 // general options needed for email #define EMAIL_FORMAT_SUPPORT 1 #define EMAIL_ATTACHMENT_SUPPORT 1 #define ARRAYFIELD_SUPPORT 1 // - if defined, stream field support will be included #define STREAMFIELD_SUPPORT 1 // - if defined, semi-proprietary zipped-binary for items (any type) can be used // (enabled on a by type basis in the config) #define ZIPPED_BINDATA_SUPPORT 1 // - where to save application data by default (if not otherwise configured) // APPDATA_SUBDIR is a subdirectory of the user's "application data" dir. #define APPDATA_SUBDIR "synthesis.ch/SySyncLib_uni" // - if defined, code for incoming and outgoing SyncML dumping into (WB)XML logfiles is included #define MSGDUMP 1 // Database support options // ======================== // - link in customimplds on top of binfile #define BASED_ON_BINFILE_CLIENT 1 // - SQL and API datastores have changedetection, so build binfile for that #define CHANGEDETECTION_AVAILABLE 1 // - we need a separate changelog mechanism #define CHECKSUM_CHANGELOG 1 // - string localIDs with sufficiently large size #define STRING_LOCALID_MAXLEN 256 // - multithreaded #define MULTI_THREAD_SUPPORT 1 #define MULTI_THREAD_DATASTORE 1 // - if defined, SQL support is included #undef ODBCAPI_SUPPORT #define SQLITE_SUPPORT 1 #if defined(ONOFF_SQLITE_SUPPORT) # if ONOFF_SQLITE_SUPPORT # define SQLITE_SUPPORT 1 # else # undef SQLITE_SUPPORT # endif #endif #if defined(SQLITE_SUPPORT) || defined(ODBCAPI_SUPPORT) # define SQL_SUPPORT 1 #else # undef SQL_SUPPORT #endif // - if defined, ODBC DB mapping of arrays to aux tables is supported #define ARRAYDBTABLES_SUPPORT 1 // - if defined, SDK support is included #define SDK_SUPPORT 1 // - id defined, code allows calling of subsequent DLLs #define PLUGIN_DLL 1 // - define what SDK modules are linked in //#define DBAPI_DEMO 1 #define DBAPI_TEXT 1 //#define DBAPI_SILENT 1 //#define DBAPI_EXAMPLE 1 /* eof */ libsynthesis-3.4.0.47.1/src/Targets/ReleasedProducts/serverEngine_opensource_linux/000077500000000000000000000000001226375725500304315ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/Targets/ReleasedProducts/serverEngine_opensource_linux/define.h000066400000000000000000000077741226375725500320530ustar00rootroot00000000000000 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // NOTE: this is a local copy for this specific target // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! /*************************************************************************/ /* module: Compiler Flag Definition File */ /* file: define.h */ /* target system: win */ /* target OS: win */ /*************************************************************************/ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ /** * File for Windows Specific Compiler Flags */ #ifndef _DEFINE_H #define _DEFINE_H #define __ANSI_C__ /* thread safety (added by luz@synthesis.ch, 2001-10-29) */ /* Note: moved define of this to target_options.h of every target */ #undef __MAKE_THREADSAFE /* enable Alloc helpers */ #define __USE_ALLOCFUNCS__ /* do we need WBXML (binary XML) processing ? */ #define __SML_WBXML__ /* do we need the capability to decode plain text tokens in WBXML? */ #define __SML_WBXML_TEXTTOKENS__ /* do we need XML processing ? */ #define __SML_XML__ /* are we using a 'light' toolkit ? */ //#define __SML_LITE__ /* do we use Sub DTD extensions ? */ #define __USE_EXTENSIONS__ /* do we need Metainformation DTD parsing ? */ #define __USE_METINF__ /* do we use Device Info DTD ? */ #define __USE_DEVINF__ /* which of the following optional commands should be included ? */ #define ADD_SEND //#define ATOMIC_SEND //#define ATOMIC_RECEIVE //#define COPY_SEND //#define COPY_RECEIVE //#define EXEC_SEND //#define EXEC_RECEIVE #define GET_SEND #define MAP_RECEIVE #define MAPITEM_RECEIVE #define RESULT_RECEIVE //#define SEARCH_SEND //#define SEARCH_RECEIVE //#define SEQUENCE_SEND //#define SEQUENCE_RECEIVE /* TK: to improve interoperability and handling we * switched to using .def files instead of compiler * specific per function definitions. As long as we only * use C this is the easiest and cleanes way */ #define SML_API #define SML_API_DEF #define XPT_API #define XPT_API_DEF /* Multi segment macro for Palm OS */ #define LIB_FUNC #define MGR_FUNC #define WSM_FUNC #define XLT_FUNC #endif serverengine_opensource++.pch000066400000000000000000000007471226375725500361420ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/Targets/ReleasedProducts/serverEngine_opensource_linux/* precompiled headers source file * =============================== * */ // SySync is a C++ project, make sure precomp headers // are compiled as C++! #pragma cplusplus on // determine target file name #pragma precompile_target "serverengine_opensource_linux++.mch" // include all headers that are suitable for precompiled use // - target options can incfluence everything #include "target_options.h" // - precompilable headers #include "serverengine_custom_precomp.h" // eof serverengine_opensource.pch000066400000000000000000000006751226375725500360140ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/Targets/ReleasedProducts/serverEngine_opensource_linux/* precompiled headers source file * =============================== * */ // C-version for SyncML toolkit files #pragma cplusplus off // determine target file name #pragma precompile_target "serverengine_opensource_linux.mch" // include all headers that are suitable for precompiled // C version use // - target options can incfluence everything #include "target_options.h" // standard SyncML TK stuff #include "smltk_precomp.h" // eof serverengine_opensource_linux_prefix.h000066400000000000000000000016611226375725500402610ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/Targets/ReleasedProducts/serverEngine_opensource_linux/* prefix file * =========== * */ // override default in global_options.h: // use SySync_srv_ as prefix for external C functions #define SYSYNC_EXTERNAL(_x) SySync_srv_ ## _x #define SYSYNC_PREFIX "SySync_srv_" // required before time.h to get tm_gmtoff in struct tm: // this is used to find standard and daylight saving offset // of the system, see timezones.cpp #define _BSD_SOURCE 1 #define USE_TM_GMTOFF 1 #ifdef __cplusplus // include all headers that are suitable for precompiled use // - target options can incfluence everything #include "target_options.h" // - platform specifics #include "platform_headers.h" // - precompilable headers #include "serverengine_custom_precomp.h" #else // include all headers that are suitable for precompiled // C version use // - target options can incfluence everything #include "target_options.h" // - platform specifics #include "platform_headers.h" #endif /* eof */ libsynthesis-3.4.0.47.1/src/Targets/ReleasedProducts/serverEngine_opensource_linux/target_options.h000066400000000000000000000103551226375725500336470ustar00rootroot00000000000000/* Target options * ============== * */ // SYNCML SERVER ENGINE LIBRARY OPENSOURCE LINUX // ############################################# // define platform #define LINUX // Release version status #define RELEASE_VERSION #define RELEASE_SYDEBUG 2 // extended DBG included //#define OPTIONAL_SYDEBUG 1 // Eval limit options // ================== // OpenSource Library does not have any expiry mechanisms #define NEVER_EXPIRES_IS_OK 1 // to explicitly override check in SyncAppBase // now include platform independent product options (which include global_options.h) #include "product_options.h" // Identification strings #define CUST_SYNC_MAN SYSYNC_OEM // manufactured by ourselves #define CUST_SYNC_MODEL "SySync Server Library OpenSource Linux" #define CUST_SYNC_FIRMWARE NULL // no firmware #define CUST_SYNC_HARDWARE NULL // no hardware // String used to construct logfile names #define TARGETID "sysynclib_srv_linux" // Note: Hard expiration date settings moved to product_options.h // - if defined, software will stop specified number of days after // first use #undef EXPIRES_AFTER_DAYS // Engine does not have auto-demo // Identification for update check and demo period #define SYSER_VARIANT_CODE SYSER_VARIANT_PRO #define SYSER_PRODUCT_CODE SYSER_PRODCODE_SERVER_LIB_LINUX #define SYSER_EXTRA_ID SYSER_EXTRA_ID_NONE // This is the opensource Linux library, and needs no registration #undef SYSER_REGISTRATION #undef VERSION_COMMENTS #define VERSION_COMMENTS "Synthesis OpenSource" #undef EXPIRES_AFTER_DATE // - define allowed product codes #define SYSER_PRODUCT_CODE_MAIN SYSER_PRODCODE_SERVER_DEMO // a permanent DEMO license #define SYSER_PRODUCT_CODE_ALT1 SYSER_PRODCODE_SERVER_LIB_LINUX // ..or a library license for Linux #define SYSER_PRODUCT_CODE_ALT2 SYSER_PRODCODE_SERVER_LIB_ALL // ..or for all platforms #define SYSER_PRODUCT_CODE_ALT3 SYSER_PRODCODE_SERVER_LIB_DESK // ..or for desktop platforms #define SYSER_PRODUCT_CODE_ALT4 SYSER_PRODCODE_SERVER_ODBC_PRO_LINUX // ..or a PRO server for Linux // - define needed product flags // only licenses that are release date limited (or explicitly NOT release date limited, // or time limited) are allowed #define SYSER_NEEDED_PRODUCT_FLAGS SYSER_PRODFLAG_MAXRELDATE #define SYSER_FORBIDDEN_PRODUCT_FLAGS 0 // for the opensource version, DLL plugins are always allowed // (even with licenses that do not have SYSER_PRODFLAG_SERVER_SDKAPI set) // because we do not use a license at all! #define DLL_PLUGINS_ALWAYS_ALLOWED 1 // Database support options // ======================== // - if defined, SQL support is included #define SQL_SUPPORT 1 #undef ODBCAPI_SUPPORT #define SQLITE_SUPPORT 1 // - if defined, ODBC DB mapping of arrays to aux tables is supported #define ARRAYDBTABLES_SUPPORT 1 // - if defined, SDK support is included #define SDK_SUPPORT 1 // - id defined, code allows calling of subsequent DLLs #define PLUGIN_DLL 1 // - define what SDK modules are linked in //#define DBAPI_DEMO 1 #define DBAPI_TEXT 1 //#define DBAPI_SILENT 1 //#define DBAPI_EXAMPLE 1 // SySync options // ============== // - no progress events (server engine code does not handle them at this time) #undef PROGRESS_EVENTS // - we do not need to squeeze code #undef MINIMAL_CODE // - script with regex support #define SCRIPT_SUPPORT 1 #define REGEX_SUPPORT 1 // - server does support target options #define SYSYNC_TARGET_OPTIONS 1 // - filters #define OBJECT_FILTERING 1 // - server does need superdatastores #define SUPERDATASTORES 1 // general options needed for email #define EMAIL_FORMAT_SUPPORT 1 #define EMAIL_ATTACHMENT_SUPPORT 1 #define ARRAYFIELD_SUPPORT 1 // - if defined, stream field support will be included #define STREAMFIELD_SUPPORT 1 // - if defined, semi-proprietary zipped-binary for items (any type) can be used // (enabled on a by type basis in the config) #define ZIPPED_BINDATA_SUPPORT 1 // - where to save application data by default (if not otherwise configured) // APPDATA_SUBDIR is a subdirectory of the user's "application data" dir. #define APPDATA_SUBDIR "synthesis.ch/SySyncLib_srv" // - if defined, code for incoming and outgoing SyncML dumping into (WB)XML logfiles is included #define MSGDUMP 1 /* eof */ libsynthesis-3.4.0.47.1/src/Targets/ReleasedProducts/sysytool_linux/000077500000000000000000000000001226375725500254405ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/Targets/ReleasedProducts/sysytool_linux/define.h000077500000000000000000000077761226375725500270670ustar00rootroot00000000000000 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // NOTE: this is a local copy for this specific target // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! /*************************************************************************/ /* module: Compiler Flag Definition File */ /* file: define.h */ /* target system: mac os x */ /* target OS: mac os x */ /*************************************************************************/ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ /** * File for MacOS X Specific Compiler Flags */ #ifndef _DEFINE_H #define _DEFINE_H //#define __ANSI_C__ /* thread safety (added by luz@synthesis.ch, 2001-10-29) */ /* Note: moved define of this to target_options.h of every target */ #undef __MAKE_THREADSAFE /* enable Alloc helpers */ #define __USE_ALLOCFUNCS__ /* do we need WBXML (binary XML) processing ? */ #define __SML_WBXML__ /* do we need the capability to decode plain text tokens in WBXML? */ #define __SML_WBXML_TEXTTOKENS__ /* do we need XML processing ? */ #define __SML_XML__ /* are we using a 'light' toolkit ? */ //#define __SML_LITE__ /* do we use Sub DTD extensions ? */ #define __USE_EXTENSIONS__ /* do we need Metainformation DTD parsing ? */ #define __USE_METINF__ /* do we use Device Info DTD ? */ #define __USE_DEVINF__ /* which of the following optional commands should be included ? */ #define ADD_SEND //#define ATOMIC_SEND //#define ATOMIC_RECEIVE //#define COPY_SEND //#define COPY_RECEIVE //#define EXEC_SEND //#define EXEC_RECEIVE #define GET_SEND #define MAP_RECEIVE #define MAPITEM_RECEIVE #define RESULT_RECEIVE //#define SEARCH_SEND //#define SEARCH_RECEIVE //#define SEQUENCE_SEND //#define SEQUENCE_RECEIVE /* TK: to improve interoperability and handling we * switched to using .def files instead of compiler * specific per function definitions. As long as we only * use C this is the easiest and cleanes way */ #define SML_API #define SML_API_DEF #define XPT_API #define XPT_API_DEF /* Multi segment macro for Palm OS */ #define LIB_FUNC #define MGR_FUNC #define WSM_FUNC #define XLT_FUNC #endif libsynthesis-3.4.0.47.1/src/Targets/ReleasedProducts/sysytool_linux/sysytool_linux_x86_prefix.h000077500000000000000000000011621226375725500330220ustar00rootroot00000000000000/* prefix file * =========== * */ #ifdef __cplusplus // include all headers that are suitable for precompiled use // - target options can incfluence everything #include "target_options.h" // - platform specifics #include "platform_headers.h" // - precompilable headers #include "sysytool_precomp.h" #else // include all headers that are suitable for precompiled // C version use // - target options can incfluence everything #include "target_options.h" // - platform specifics #include "platform_headers.h" // - SML toolkit including xpt part #include "smltk_precomp_xpt.h" #endif /* eof */ libsynthesis-3.4.0.47.1/src/Targets/ReleasedProducts/sysytool_linux/target_options.h000077500000000000000000000114611226375725500306600ustar00rootroot00000000000000/* Target options * ============== * * */ // Most hyperglobal definitions, might even influence global_options.h: // - THIS IS THE DIAGNOSTIC TOOL #define SYSYNC_TOOL // - this is the LINUX version of the sysytool #define LINUX // now include global switches #include "global_options.h" // - is a standalone APP #define STANDALONE_APP 1 // Identification strings #define CUST_SYNC_MAN SYSYNC_OEM // manufactured by ourselves #define CUST_SYNC_MODEL "SySync SyncML Diagnostic Tool" #define CUST_SYNC_FIRMWARE NULL // no firmware #define CUST_SYNC_HARDWARE NULL // no hardware // String used to construct logfile names #define TARGETID "sysytool" // general comments #define VERSION_COMMENTS "Internal Synthesis AG Version" // Eval limit options // ================== // - if defined, server will have a restriction on concurrent sessions // from different devices. #define VERSION_COMMENTS "Limited to 1 simultaneous sync sessions" // - if defined, software will stop working as demo after defined date #define EXPIRES_AFTER_DATE 1 // - if defined, software will stop specified number of days after // first use #undef EXPIRES_AFTER_DAYS // - variant #define SYSER_VARIANT_CODE SYSER_VARIANT_PRO // - if defined, software can be registered #define SYSER_REGISTRATION 1 // - define allowed product codes (any server) #define SYSER_PRODUCT_CODE_MAIN SYSER_PRODCODE_SERVER_PRO #define SYSER_PRODUCT_CODE_ALT1 SYSER_PRODCODE_SERVER_STD #define SYSER_PRODUCT_CODE_ALT2 SYSER_PRODCODE_SERVER_DEMO #define SYSER_PRODUCT_CODE_ALT3 SYSER_PRODCODE_SERVER_XML2GO #undef SYSER_PRODUCT_CODE_ALT4 // - define needed product flags #define SYSER_NEEDED_PRODUCT_FLAGS 0 // no ISAPI/APACHE flag needed for XPT #define SYSER_FORBIDDEN_PRODUCT_FLAGS 0 // Database support options // ======================== // - if defined, SQL support is included #define SQL_SUPPORT 1 #define ODBCAPI_SUPPORT 1 #define SQLITE_SUPPORT 1 // - if defined, ODBC DB mapping of arrays to aux tables is supported #define ARRAYDBTABLES_SUPPORT 1 // - if defined, SDK support is included //#define SDK_SUPPORT 1 //#define PLUGIN_DLL 1 // - define what SDK modules are linked in //#define DBAPI_DEMO 1 #define DBAPI_TEXT 1 #define FILEOBJ_SUPPORT 1 #define ADAPTITEM_SUPPORT 1 #define JNI_SUPPORT 1 // SySync options // ============== // - if defined, debug code is included (not necessarily enabled, see gDebug) // if 1, only "public" debugging is enabled, if >1, all debugging is enabled #ifdef RELEASE_VERSION #define SYDEBUG 1 #else #define SYDEBUG 2 #endif #define CONSOLEINFO 1 // %%% include all profiling //#define TIME_PROFILING 1 //#define MEMORY_PROFILING 1 // - if defined, support for configurable types will be included #define CONFIGURABLE_TYPE_SUPPORT 1 // - if defined, object filtering will be included #define OBJECT_FILTERING 1 // - if defined, procedure interpreter features will be included #define SCRIPT_SUPPORT 1 // - if defined, superdatastores will be included #define SUPERDATASTORES 1 // - if defined, array field support will be included #define ARRAYFIELD_SUPPORT 1 // do not modify remote IDs in any way while processing them #define DONT_STRIP_PATHPREFIX_FROM_REMOTEIDS 1 // ODBC options // ============ // No SEH around ODBC calls #define NO_AV_GUARDING 1 // if both text and ODBC maps are supported, mode can be switched // in config. #define USE_TEXTMAPS 1 #define USE_ODBCMAPS 1 // SyncML Toolkit options // ====================== // if defined, the entire complicated and thread-unsafe workspace manager // is completely bypassed #define NOWSM 1 /* correct tagging of payload with 1sec for lock, 2=log all lock enter/leave ops */ //#define __DEBUG_LOCKS 1 // we want the toolkit linked static #define __LINK_TOOLKIT_STATIC__ 1 // we want the XPT linked static #define LINK_TRANSPORT_STATICALLY 1 // - select transports #define INCLUDE_HTTP_STATICALLY //#define INCLUDE_OBEX_STATICALLY //#define INCLUDE_WSP_STATICALLY // Verbose XPT debug only if high debug level #if SYDEBUG>2 // switch on tracing for XPT #define TRACE 1 #define TRACE_TO_STDOUT 1 // use global localOutput() function // Debug options for OBEX (smlobex) // - define one or several of these //#define DEBUGALL // also hex-dumps all!! IrDA traffic #define DEBUGFLOW #define DEBUGINFO #define DEBUGERROR #endif libsynthesis-3.4.0.47.1/src/Targets/clientEngine_dbg/000077500000000000000000000000001226375725500222645ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/Targets/clientEngine_dbg/clientengine_dbg++.pch000077500000000000000000000024231226375725500263720ustar00rootroot00000000000000/* precompiled headers source file * =============================== * * CVS: * $Author: luz $ * $Date: 2007/09/05 14:03:05 $ * $Revision: 1.1 $ * $Source: /usr/local/cvsroot/sysync/Source/Targets/clientEngine_dbg/clientengine_dbg++.pch,v $ * $State: Exp $ * $Name: $ (Tag) * $Locker: $ (who has reserved checkout) * Log: * $Log: clientengine_dbg++.pch,v $ * Revision 1.1 2007/09/05 14:03:05 luz * client engine with custom datastores (SQL, ODBC, SQLite and PluginAPI) * * Revision 1.2 2007/04/25 11:59:30 luz * Moved platform specific includes to syncclient_outlook_precomp.h - it belongs there so that file can be used in MW precompiled header source files (.pch) as well as in prefix_file.h for VC++. * * Revision 1.1 2004/02/04 14:24:06 luz * 2.0.5.3 s2g/ONE client release (and Oracle release candidate) checkin * * */ // SySync is a C++ project, make sure precomp headers // are compiled as C++! #pragma cplusplus on // determine target file name #pragma precompile_target "clientengine_dbg_x86++.mch" // include all headers that are suitable for precompiled use // - target options can incfluence everything #include "target_options.h" // - precompilable headers #include "clientengine_custom_precomp.h" // eof libsynthesis-3.4.0.47.1/src/Targets/clientEngine_dbg/clientengine_dbg.pch000077500000000000000000000016331226375725500262460ustar00rootroot00000000000000/* precompiled headers source file * =============================== * * CVS: * $Author: luz $ * $Date: 2007/09/05 14:03:05 $ * $Revision: 1.1 $ * $Source: /usr/local/cvsroot/sysync/Source/Targets/clientEngine_dbg/clientengine_dbg.pch,v $ * $State: Exp $ * $Name: $ (Tag) * $Locker: $ (who has reserved checkout) * Log: * $Log: clientengine_dbg.pch,v $ * Revision 1.1 2007/09/05 14:03:05 luz * client engine with custom datastores (SQL, ODBC, SQLite and PluginAPI) * * */ // C-version for SyncML toolkit files #pragma cplusplus off // determine target file name #if __INTEL__ #pragma precompile_target "clientengine_dbg_x86.mch" #else #error "undefined target, cannot set precompiled header file name" #endif // include all headers that are suitable for precompiled // C version use // - target options can incfluence everything #include "target_options.h" // eof libsynthesis-3.4.0.47.1/src/Targets/clientEngine_dbg/clientengine_dbg_x86_prefix.h000077500000000000000000000002741226375725500300050ustar00rootroot00000000000000/* prefix file * =========== * */ #ifdef __cplusplus #include "clientEngine_dbg_x86++.mch" #else #include "clientEngine_dbg_x86.mch" #endif #include "target_options.h" /* eof */ libsynthesis-3.4.0.47.1/src/Targets/clientEngine_dbg/target_options.h000077500000000000000000000132651226375725500255100ustar00rootroot00000000000000/* Target options * ============== * * */ // SYNCML CLIENT ENGINE LIBRARY WIN32 // ################################## // define platform // - we are on Windows #ifndef _WIN32 #define _WIN32 // needed for MWERKS #endif #ifndef WIN32 #define WIN32 // needed for others #endif // Release version status #undef RELEASE_VERSION #define RELEASE_SYDEBUG 2 // extended DBG included //#define OPTIONAL_SYDEBUG 1 // now include platform independent product options (which include global_options.h) #include "product_options.h" // Identification strings #define CUST_SYNC_MAN SYSYNC_OEM // manufactured by ourselves #define CUST_SYNC_MODEL "SySync Client Library PROTO Win32" #define CUST_SYNC_FIRMWARE NULL // no firmware #define CUST_SYNC_HARDWARE NULL // no hardware // String used to construct logfile names #define TARGETID "sysynclib_win32" // Configuration // ============= // Default profile #undef HARD_CODED_SERVER_URI #undef HARD_CODED_DBNAMES #define DEFAULT_SERVER_URI "http://www.synthesis.ch/sync" #define DEFAULT_LOCALDB_PROFILE "" #define DEFAULT_SERVER_USER "" #define DEFAULT_SERVER_PASSWD "" #define DEFAULT_ENCODING SML_WBXML #define DEFAULT_TRANSPORT_USER NULL #define DEFAULT_TRANSPORT_PASSWD NULL #define DEFAULT_SOCKS_HOST NULL #define DEFAULT_PROXY_HOST NULL #define DEFAULT_DATASTORES_ENABLED false #define DEFAULT_EVENTS_DAYSBEFORE 30 #define DEFAULT_EVENTS_DAYSAFTER 90 #define DEFAULT_EVENTS_LIMITED false #define DEFAULT_EMAILS_LIMITED true #define DEFAULT_EMAILS_HDRONLY true #define DEFAULT_EMAILS_MAXKB 2 #define DEFAULT_EMAILS_ONLYLAST true #define DEFAULT_EMAILS_DAYSBEFORE 10 // Eval limit options // ================== // Note: Hard expiration date settings moved to product_options.h // - if defined, software will stop specified number of days after // first use #undef EXPIRES_AFTER_DAYS // Engine does not have auto-demo // Identification for update check and demo period #define SYSER_VARIANT_CODE SYSER_VARIANT_PRO #define SYSER_PRODUCT_CODE SYSER_PRODCODE_CLIENT_LIB_WIN32 #define SYSER_EXTRA_ID SYSER_EXTRA_ID_PROTO // - if defined, software can be registered #define SYSER_REGISTRATION 1 // - define allowed product codes #define SYSER_PRODUCT_CODE_MAIN SYSER_PRODCODE_CLIENT_LIB_WIN32 // we need a sysync library license for windows #define SYSER_PRODUCT_CODE_ALT1 SYSER_PRODCODE_CLIENT_ODBC_PRO_WIN32 // a PRO license for the Win console client is ok as well #define SYSER_PRODUCT_CODE_ALT2 SYSER_PRODCODE_CLIENT_LIB_ALL #define SYSER_PRODUCT_CODE_ALT3 SYSER_PRODCODE_CLIENT_LIB_DESK #undef SYSER_PRODUCT_CODE_ALT4 // - define needed product flags // only licenses that are release date limited (or explicitly NOT release date limited, // or time limited) are allowed #define SYSER_NEEDED_PRODUCT_FLAGS SYSER_PRODFLAG_MAXRELDATE #define SYSER_FORBIDDEN_PRODUCT_FLAGS 0 // for this DBG variant, DLL plugins are always allowed // (even with licenses that do not have SYSER_PRODFLAG_SERVER_SDKAPI set) #define DLL_PLUGINS_ALWAYS_ALLOWED 1 // SySync options // ============== // - enhanced profile record #define ENHANCED_PROFILES_2004 1 #define CLIENTFEATURES_2008 1 // - support for automatic syncing (timed, IPP, server alerted...) #define AUTOSYNC_SUPPORT 1 // - support for intelligent push & poll (IPP) //#define IPP_SUPPORT 1 //#define IPP_SUPPORT_ALWAYS 1 // regardless of license flags // - support for timed sync #define TIMEDSYNC_SUPPORT 1 // - support for WAP push alerted sync #define SERVERALERT_SUPPORT 1 // - support for Proxy #define PROXY_SUPPORT 1 // - support for multiple profiles #define MULTI_PROFILE_SUPPORT 1 // - show progress events #define PROGRESS_EVENTS 1 // - we do not need to squeeze code #undef MINIMAL_CODE // - script with regex support #define SCRIPT_SUPPORT #define REGEX_SUPPORT // - client does not need target options #undef SYSYNC_TARGET_OPTIONS // - filters #define OBJECT_FILTERING // - client does not need superdatastores #undef SUPERDATASTORES // general options needed for email #define EMAIL_FORMAT_SUPPORT 1 #define EMAIL_ATTACHMENT_SUPPORT 1 #define ARRAYFIELD_SUPPORT 1 // - if defined, stream field support will be included #define STREAMFIELD_SUPPORT 1 // - if defined, semi-proprietary zipped-binary for items (any type) can be used // (enabled on a by type basis in the config) #define ZIPPED_BINDATA_SUPPORT 1 // - where to save application data by default (if not otherwise configured) // APPDATA_SUBDIR is a subdirectory of the user's "application data" dir. #define APPDATA_SUBDIR "synthesis.ch\\SySyncLib" // - if defined, code for incoming and outgoing SyncML dumping into (WB)XML logfiles is included #define MSGDUMP 1 // Datastore Options // ----------------- // - support DBApi tunnel #define DBAPI_TUNNEL_SUPPORT 1 // - link in customimplds on top of binfile #define BASED_ON_BINFILE_CLIENT 1 // - SQL and API datastores have changedetection, so build binfile for that #define CHANGEDETECTION_AVAILABLE 1 // - we need a separate changelog mechanism #define CHECKSUM_CHANGELOG 1 // - string localIDs with sufficiently large size #define STRING_LOCALID_MAXLEN 256 // - supports ODBC, SQLite and DBApi #define SQL_SUPPORT 1 #define ODBCAPI_SUPPORT 1 #define SQLITE_SUPPORT 1 // - master detail (array) tables supported #define ARRAYDBTABLES_SUPPORT 1 // - if defined, SDK support is included #define SDK_SUPPORT 1 #define PLUGIN_DLL 1 // external DLL allowed as well // - define what SDK modules are linked in //#define DBAPI_DEMO 1 #define DBAPI_TEXT 1 //#define DBAPI_SILENT 1 #define DBAPI_LOGGER 1 #define DBAPI_SNOWWHITE 1 #define JNI_SUPPORT 1 #define FILEOBJ_SUPPORT 1 #define ADAPTITEM_SUPPORT 1 #ifdef _WIN32 #define CSHARP_SUPPORT 1 #endif /* eof */ libsynthesis-3.4.0.47.1/src/Targets/sysytool/000077500000000000000000000000001226375725500207515ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/Targets/sysytool/define.h000077500000000000000000000077761226375725500224000ustar00rootroot00000000000000 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // NOTE: this is a local copy for this specific target // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! /*************************************************************************/ /* module: Compiler Flag Definition File */ /* file: define.h */ /* target system: mac os x */ /* target OS: mac os x */ /*************************************************************************/ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ /** * File for MacOS X Specific Compiler Flags */ #ifndef _DEFINE_H #define _DEFINE_H //#define __ANSI_C__ /* thread safety (added by luz@synthesis.ch, 2001-10-29) */ /* Note: moved define of this to target_options.h of every target */ #undef __MAKE_THREADSAFE /* enable Alloc helpers */ #define __USE_ALLOCFUNCS__ /* do we need WBXML (binary XML) processing ? */ #define __SML_WBXML__ /* do we need the capability to decode plain text tokens in WBXML? */ #define __SML_WBXML_TEXTTOKENS__ /* do we need XML processing ? */ #define __SML_XML__ /* are we using a 'light' toolkit ? */ //#define __SML_LITE__ /* do we use Sub DTD extensions ? */ #define __USE_EXTENSIONS__ /* do we need Metainformation DTD parsing ? */ #define __USE_METINF__ /* do we use Device Info DTD ? */ #define __USE_DEVINF__ /* which of the following optional commands should be included ? */ #define ADD_SEND //#define ATOMIC_SEND //#define ATOMIC_RECEIVE //#define COPY_SEND //#define COPY_RECEIVE //#define EXEC_SEND //#define EXEC_RECEIVE #define GET_SEND #define MAP_RECEIVE #define MAPITEM_RECEIVE #define RESULT_RECEIVE //#define SEARCH_SEND //#define SEARCH_RECEIVE //#define SEQUENCE_SEND //#define SEQUENCE_RECEIVE /* TK: to improve interoperability and handling we * switched to using .def files instead of compiler * specific per function definitions. As long as we only * use C this is the easiest and cleanes way */ #define SML_API #define SML_API_DEF #define XPT_API #define XPT_API_DEF /* Multi segment macro for Palm OS */ #define LIB_FUNC #define MGR_FUNC #define WSM_FUNC #define XLT_FUNC #endif libsynthesis-3.4.0.47.1/src/Targets/sysytool/sysytool++.pch000077500000000000000000000007761226375725500235150ustar00rootroot00000000000000// precompiled headers source file // SySync is a C++ project, make sure precomp headers // are compiled as C++! #pragma cplusplus on // determine target file name #if __INTEL__ #pragma precompile_target "sysytool_x86++.mch" #else #error "undefined target, cannot set precompiled header file name" #endif // include all headers that are suitable for precompiled use // - target options can incfluence everything #include "target_options.h" // - precompilable headers #include "sysytool_precomp.h" // eof libsynthesis-3.4.0.47.1/src/Targets/sysytool/sysytool.pch000077500000000000000000000007541226375725500233630ustar00rootroot00000000000000// precompiled headers source file // C-version for SyncML toolkit files #pragma cplusplus off // determine target file name #if __INTEL__ #pragma precompile_target "sysytool_x86.mch" #else #error "undefined target, cannot set precompiled header file name" #endif // include all headers that are suitable for precompiled // C version use // - target options can incfluence everything #include "target_options.h" // - SML toolkit including xpt part #include "smltk_precomp_xpt.h" // eof libsynthesis-3.4.0.47.1/src/Targets/sysytool/sysytool_linux_x86_prefix.h000077500000000000000000000011621226375725500263330ustar00rootroot00000000000000/* prefix file * =========== * */ #ifdef __cplusplus // include all headers that are suitable for precompiled use // - target options can incfluence everything #include "target_options.h" // - platform specifics #include "platform_headers.h" // - precompilable headers #include "sysytool_precomp.h" #else // include all headers that are suitable for precompiled // C version use // - target options can incfluence everything #include "target_options.h" // - platform specifics #include "platform_headers.h" // - SML toolkit including xpt part #include "smltk_precomp_xpt.h" #endif /* eof */ libsynthesis-3.4.0.47.1/src/Targets/sysytool/sysytool_x86_prefix.h000077500000000000000000000002211226375725500251070ustar00rootroot00000000000000// prefix file #ifdef __cplusplus #include "sysytool_x86++.mch" #else #include "sysytool_x86.mch" #endif #include "target_options.h" /* eof */ libsynthesis-3.4.0.47.1/src/Targets/sysytool/target_options.h000077500000000000000000000113341226375725500241700ustar00rootroot00000000000000/* Target options * ============== * * */ // Most hyperglobal definitions, might even influence global_options.h: // - THIS IS THE DIAGNOSTIC TOOL #define SYSYNC_TOOL // - find out target platform #ifdef __MWERKS__ #define _WIN32 #else #define LINUX #endif // now include global switches #include "global_options.h" // - is a standalone APP #define STANDALONE_APP 1 // Identification strings #define CUST_SYNC_MAN SYSYNC_OEM // manufactured by ourselves #define CUST_SYNC_MODEL "SySync SyncML Diagnostic Tool" #define CUST_SYNC_FIRMWARE NULL // no firmware #define CUST_SYNC_HARDWARE NULL // no hardware // String used to construct logfile names #define TARGETID "sysytool" // general comments #define VERSION_COMMENTS "Internal Synthesis AG Version" // Eval limit options // ================== // - if defined, server will have a restriction on concurrent sessions // from different devices. #define VERSION_COMMENTS "Limited to 1 simultaneous sync sessions" // - if defined, software will stop working as demo after defined date #define EXPIRES_AFTER_DATE 1 // - if defined, software will stop specified number of days after // first use #undef EXPIRES_AFTER_DAYS // - variant #define SYSER_VARIANT_CODE SYSER_VARIANT_PRO // - if defined, software can be registered #define SYSER_REGISTRATION 1 // - define allowed product codes (any server) #define SYSER_PRODUCT_CODE_MAIN SYSER_PRODCODE_SERVER_PRO #define SYSER_PRODUCT_CODE_ALT1 SYSER_PRODCODE_SERVER_STD #define SYSER_PRODUCT_CODE_ALT2 SYSER_PRODCODE_SERVER_DEMO #define SYSER_PRODUCT_CODE_ALT3 SYSER_PRODCODE_SERVER_XML2GO #undef SYSER_PRODUCT_CODE_ALT4 // - define needed product flags #define SYSER_NEEDED_PRODUCT_FLAGS 0 // no ISAPI/APACHE flag needed for XPT #define SYSER_FORBIDDEN_PRODUCT_FLAGS 0 // Database support options // ======================== // - if defined, SQL support is included #define SQL_SUPPORT 1 #define ODBCAPI_SUPPORT 1 #define SQLITE_SUPPORT 1 // - if defined, ODBC DB mapping of arrays to aux tables is supported #define ARRAYDBTABLES_SUPPORT 1 // - if defined, SDK support is included // #define SDK_SUPPORT 1 // #define PLUGIN_DLL 1 // - define what SDK modules are linked in //#define DBAPI_DEMO 1 #define DBAPI_TEXT 1 //#define FILEOBJ_SUPPORT 1 #define ADAPTITEM_SUPPORT 1 #define JNI_SUPPORT 1 // SySync options // ============== // - if defined, debug code is included (not necessarily enabled, depending on debug mask) // if 1, only "public" debugging is enabled, if >1, all debugging is enabled #ifdef RELEASE_VERSION #define SYDEBUG 1 #else #define SYDEBUG 2 #endif #define CONSOLEINFO 1 // %%% include all profiling //#define TIME_PROFILING 1 //#define MEMORY_PROFILING 1 // - if defined, support for configurable types will be included #define CONFIGURABLE_TYPE_SUPPORT 1 // - if defined, object filtering will be included #define OBJECT_FILTERING 1 // - if defined, procedure interpreter features will be included #define SCRIPT_SUPPORT 1 // - if defined, superdatastores will be included #define SUPERDATASTORES 1 // - if defined, array field support will be included #define ARRAYFIELD_SUPPORT 1 // do not modify remote IDs in any way while processing them #define DONT_STRIP_PATHPREFIX_FROM_REMOTEIDS 1 // ODBC options // ============ // No SEH around ODBC calls #define NO_AV_GUARDING 1 // SyncML Toolkit options // ====================== // if defined, the entire complicated and thread-unsafe workspace manager // is completely bypassed #define NOWSM 1 /* correct tagging of payload with 1sec for lock, 2=log all lock enter/leave ops */ //#define __DEBUG_LOCKS 1 // we want the toolkit linked static #define __LINK_TOOLKIT_STATIC__ 1 // we want the XPT linked static #define LINK_TRANSPORT_STATICALLY 1 // - select transports #define INCLUDE_HTTP_STATICALLY //#define INCLUDE_OBEX_STATICALLY //#define INCLUDE_WSP_STATICALLY // Verbose XPT debug only if high debug level #if SYDEBUG>2 // switch on tracing for XPT #define TRACE 1 #define TRACE_TO_STDOUT 1 // use global localOutput() function // Debug options for OBEX (smlobex) // - define one or several of these //#define DEBUGALL // also hex-dumps all!! IrDA traffic #define DEBUGFLOW #define DEBUGINFO #define DEBUGERROR #endif libsynthesis-3.4.0.47.1/src/Targets/sysytool/version.rc000077500000000000000000000024101226375725500227640ustar00rootroot00000000000000/////////////////////////////////////////////////////////////////////// // // Version // #include #include "target_options.h" 1 VERSIONINFO FILEVERSION SYSYNC_VERSION_MAJOR,SYSYNC_VERSION_MINOR,SYSYNC_SUBVERSION,SYSYNC_BUILDNUMBER PRODUCTVERSION SYSYNC_VERSION_MAJOR,SYSYNC_VERSION_MINOR,SYSYNC_SUBVERSION,SYSYNC_BUILDNUMBER FILEFLAGSMASK VS_FFI_FILEFLAGSMASK #if SYDEBUG>1 FILEFLAGS VS_FF_DEBUG #else FILEFLAGS 0x0L #endif FILEOS VOS__WINDOWS32 FILETYPE VFT_DLL FILESUBTYPE VFT2_UNKNOWN BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904b0" BEGIN VALUE "Comments", VERSION_COMMENTS "\0" VALUE "CompanyName", "Synthesis AG - www.synthesis.ch\0" VALUE "FileDescription", "Synthesis SyncML Diagnostic Tool\0" VALUE "FileVersion", SYSYNC_VERSION_STRING "\0" VALUE "InternalName", "sysytool\0" VALUE "LegalCopyright", "Copyright (C) 2004-" RELEASE_YEAR_TXT " by Synthesis AG\0" VALUE "OriginalFilename", "sysytool.exe\0" VALUE "ProductName", "Synthesis SyncML Diagnostic Tool\0" VALUE "ProductVersion", SYSYNC_VERSION_STRING "\0" END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x409, 1200 END END libsynthesis-3.4.0.47.1/src/Transport_interfaces/000077500000000000000000000000001226375725500216325ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/Transport_interfaces/engine/000077500000000000000000000000001226375725500230775ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/Transport_interfaces/engine/engine_client.h000077500000000000000000000007761226375725500260700ustar00rootroot00000000000000/* client engine (w/o internal transport) generic header file * */ #ifndef ENGINE_CLIENT_H #define ENGINE_CLIENT_H /* Headers that might be available in precompiled form * (standard libraries, SyncML toolkit...) */ #include "engine_client_precomp.h" /* headers not suitable for / entirely included in precompilation */ // sysync core #include "sysync.h" // platform utilities //#include "platform_utils.h" // classes #include "engineclientbase.h" /* globals */ #endif // ENGINE_CLIENT_H /* eof */ libsynthesis-3.4.0.47.1/src/Transport_interfaces/engine/engine_client_precomp.h000077500000000000000000000013321226375725500276020ustar00rootroot00000000000000/* Headers that might be available in precompiled form * (standard libraries, SyncML toolkit...) * */ #ifndef ENGINE_CLIENT_PRECOMP_H #define ENGINE_CLIENT_PRECOMP_H /* precompiled portion for SySync Core */ #include "sysync_precomp.h" #ifdef __EPOC_OS__ // Symbian/EPOC: #elif __INTEL__ // Windows32: nothing special #elif defined(__MC68K__) // PalmOS: nothing special #elif defined(LINUX) // Linux: nothing special #elif defined(MACOSX) // MacOSX: nothing special #elif defined(WINCE) // WinCE/PocketPC: nothing special #elif defined(_MSC_VER) // Visual C++: nothing special #else #error "Engine Client is Win32/PalmOS/PocketPC/Linux only at this time" #endif #endif // ENGINE_CLIENT_PRECOMP_H // eof libsynthesis-3.4.0.47.1/src/Transport_interfaces/engine/engine_server.h000066400000000000000000000007771226375725500261160ustar00rootroot00000000000000/* server engine (w/o internal transport) generic header file */ #ifndef ENGINE_SERVER_H #define ENGINE_SERVER_H /* Headers that might be available in precompiled form * (standard libraries, SyncML toolkit...) */ #include "engine_server_precomp.h" /* headers not suitable for / entirely included in precompilation */ // sysync core #include "sysync.h" // platform utilities //#include "platform_utils.h" // classes #include "enginesessiondispatch.h" /* globals */ #endif // ENGINE_SERVER_H /* eof */ libsynthesis-3.4.0.47.1/src/Transport_interfaces/engine/engine_server_precomp.h000066400000000000000000000013361226375725500276330ustar00rootroot00000000000000/* Headers that might be available in precompiled form * (standard libraries, SyncML toolkit...) */ #ifndef ENGINE_SERVER_PRECOMP_H #define ENGINE_SERVER_PRECOMP_H /* precompiled portion for SySync Core */ #include "sysync_precomp.h" #ifdef __EPOC_OS__ // Symbian/EPOC: #elif __INTEL__ // Windows32: nothing special #elif defined(__MC68K__) // PalmOS: nothing special #elif defined(LINUX) // Linux: nothing special #elif defined(MACOSX) // MacOSX: nothing special #elif defined(WINCE) // WinCE/PocketPC: nothing special #elif defined(_MSC_VER) // Visual C++: nothing special #else #error "Engine Client is Win32/PalmOS/MacOS/PocketPC/Linux only at this time" #endif #endif // ENGINE_SERVER_PRECOMP_H // eof libsynthesis-3.4.0.47.1/src/Transport_interfaces/engine/engineclientbase.cpp000077500000000000000000000057331226375725500271150ustar00rootroot00000000000000/* * TEngineClientBase * Engine library specific descendant of TSyncClientBase * Global object, manages starting of client sessions. * * Copyright (c) 2002-2011 by Synthesis AG + plan44.ch * * 2007-09-04 : luz : Created * */ #include "prefix_file.h" #include "engine_client.h" #include "engineclientbase.h" namespace sysync { #ifndef SYSYNC_SERVER // if there is also a server in the system, it will define AppConsolePuts so we don't need it here // write to platform's "console", whatever that is void AppConsolePuts(const char *aText) { // Just print to platform's console PlatformConsolePuts(aText); } // AppConsolePuts #endif // no SYSYNC_SERVER included // TEngineClientCommConfig // ======================= // (dummy at this time) // config constructor TEngineClientCommConfig::TEngineClientCommConfig(TConfigElement *aParentElementP) : TCommConfig("engineclient",aParentElementP) { // do not call clear(), because this is virtual! } // TEngineClientCommConfig::TEngineClientCommConfig // config destructor TEngineClientCommConfig::~TEngineClientCommConfig() { // nop by now } // TEngineClientCommConfig::~TEngineClientCommConfig // init defaults void TEngineClientCommConfig::clear(void) { // init defaults // %%% none for now // clear inherited inherited::clear(); } // TEngineClientCommConfig::clear #ifndef HARDCODED_CONFIG // XPT transport config element parsing bool TEngineClientCommConfig::localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine) { // checking the elements /* if (strucmp(aElementName,"xxx")==0) expectBool(fXXX); else */ return inherited::localStartElement(aElementName,aAttributes,aLine); // ok return true; } // TEngineClientCommConfig::localStartElement #endif // resolve void TEngineClientCommConfig::localResolve(bool aLastPass) { if (aLastPass) { // check for required settings // %%% tbd } // resolve inherited inherited::localResolve(aLastPass); } // TEngineClientCommConfig::localResolve // TEngineClientBase // ================= // constructor TEngineClientBase::TEngineClientBase() : TSyncClientBase() { // init } // TEngineClientBase::TEngineClientBase // destructor TEngineClientBase::~TEngineClientBase() { fDeleting=true; // flag deletion to block calling critical (virtual) methods // clean up // %%% } // TEngineClientBase::~TEngineClientBase // factory methods of Rootconfig // ============================= // create default transport config void TEngineClientRootConfig::installCommConfig(void) { // engine API needs no config at this time, commconfig is a NOP dummy for now fCommConfigP=new TEngineClientCommConfig(this); } // TEngineClientRootConfig::installCommConfig #ifndef HARDCODED_CONFIG bool TEngineClientRootConfig::parseCommConfig(const char **aAttributes, sInt32 aLine) { // engine API needs no config at this time return false; } // TEngineClientRootConfig::parseCommConfig #endif } // namespace sysync // eof libsynthesis-3.4.0.47.1/src/Transport_interfaces/engine/engineclientbase.h000077500000000000000000000033551226375725500265600ustar00rootroot00000000000000/* * TEngineClientBase * client library specific descendant of TSyncClientBase * Global object, manages starting of client sessions. * * Copyright (c) 2002-2011 by Synthesis AG + plan44.ch * * 2002-05-03 : luz : Created * */ #ifndef ENGINECLIENTBASE_H #define ENGINECLIENTBASE_H // required headers #include "syncappbase.h" #include "syncclientbase.h" #include "syncagent.h" namespace sysync { // engine client root config class TEngineClientRootConfig : public TRootConfig { typedef TRootConfig inherited; public: TEngineClientRootConfig(TSyncAppBase *aSyncAppBaseP) : inherited(aSyncAppBaseP) {}; // factory methods virtual void installCommConfig(void); // Config parsing #ifndef HARDCODED_CONFIG virtual bool parseCommConfig(const char **aAttributes, sInt32 aLine); #endif }; // TEngineClientRootConfig // engine client transport config class TEngineClientCommConfig: public TCommConfig { typedef TCommConfig inherited; public: TEngineClientCommConfig(TConfigElement *aParentElementP); virtual ~TEngineClientCommConfig(); protected: // check config elements #ifndef HARDCODED_CONFIG virtual bool localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine); #endif virtual void clear(); virtual void localResolve(bool aLastPass); }; // TXPTCommConfig // forward declarations class TSyncSession; class TEngineClientBase; // AppBase class for all client engines (libararies with API to build custom clients) class TEngineClientBase : public TSyncClientBase { typedef TSyncClientBase inherited; public: // constructors/destructors TEngineClientBase(); virtual ~TEngineClientBase(); private: }; // TEngineClientBase } // namespace sysync #endif // ENGINECLIENTBASE_H // eof libsynthesis-3.4.0.47.1/src/Transport_interfaces/engine/enginesessiondispatch.cpp000066400000000000000000000403471226375725500302040ustar00rootroot00000000000000/* * TEngineSessionDispatch * Server library specific descendant of TSyncSessionDispatch * * Copyright (c) 2009-2011 by Synthesis AG + plan44.ch * * 2009-02-06 : luz : Created * */ #include "prefix_file.h" #include "engine_server.h" #include "enginesessiondispatch.h" namespace sysync { // write to platform's "console", whatever that is void AppConsolePuts(const char *aText) { // Just print to platform's console PlatformConsolePuts(aText); } // AppConsolePuts // TEngineServerCommConfig // ======================= // config constructor TEngineServerCommConfig::TEngineServerCommConfig(TConfigElement *aParentElementP) : TCommConfig("engineserver",aParentElementP) { // do not call clear(), because this is virtual! } // TEngineServerCommConfig::TEngineServerCommConfig // config destructor TEngineServerCommConfig::~TEngineServerCommConfig() { // nop by now } // TEngineServerCommConfig::~TEngineServerCommConfig // init defaults void TEngineServerCommConfig::clear(void) { // init defaults fSessionIDCGIPrefix = "sessionid="; fSessionIDCGI = true; fBuffersRetryAnswer = false; // we don't know if the app driving the engine implements this, so default is off // clear inherited inherited::clear(); } // TEngineServerCommConfig::clear #ifndef HARDCODED_CONFIG // XPT transport config element parsing bool TEngineServerCommConfig::localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine) { // checking the elements if (strucmp(aElementName,"buffersretryanswer")==0) expectBool(fBuffersRetryAnswer); if (strucmp(aElementName,"sessionidcgiprefix")==0) expectString(fSessionIDCGIPrefix); if (strucmp(aElementName,"sessionidcgi")==0) expectBool(fSessionIDCGI); else return inherited::localStartElement(aElementName,aAttributes,aLine); // ok return true; } // TEngineServerCommConfig::localStartElement #endif // resolve void TEngineServerCommConfig::localResolve(bool aLastPass) { if (aLastPass) { // check for required settings // NOP for now } // resolve inherited inherited::localResolve(aLastPass); } // TEngineServerCommConfig::localResolve // TEngineSessionDispatch // ====================== // constructor TEngineSessionDispatch::TEngineSessionDispatch() : TSyncAppBase() { // this is a server engine fIsServer = true; } // TEngineSessionDispatch::TEngineSessionDispatch // destructor TEngineSessionDispatch::~TEngineSessionDispatch() { fDeleting=true; // flag deletion to block calling critical (virtual) methods // clean up // %%% } // TEngineSessionDispatch::~TEngineSessionDispatch // Called from SyncML toolkit when a new SyncML message arrives // - dispatches to session's StartMessage Ret_t TEngineSessionDispatch::StartMessage( InstanceID_t aSmlWorkspaceID, // SyncML toolkit workspace instance ID VoidPtr_t aUserData, // pointer to a TSyncAgent descendant SmlSyncHdrPtr_t aContentP // SyncML tookit's decoded form of the element ) { TSyncSession *sessionP = static_cast(aUserData); // the server session SYSYNC_TRY { // let session handle details of StartMessage callback return sessionP->StartMessage(aContentP); } SYSYNC_CATCH (exception &e) return HandleDecodingException(sessionP,"StartMessage",&e); SYSYNC_ENDCATCH SYSYNC_CATCH (...) return HandleDecodingException(sessionP,"StartMessage",NULL); SYSYNC_ENDCATCH } // TEngineSessionDispatch::StartMessage // Test if message buffering is available bool TEngineSessionDispatch::canBufferRetryAnswer(void) { // basically, we can buffer, we do it if configured return dynamic_cast(getRootConfig()->fCommConfigP)->fBuffersRetryAnswer; } // TEngineSessionDispatch::canBufferRetryAnswer // Combine URI and session ID to make a RespURI according to transport void TEngineSessionDispatch::generateRespURI( string &aRespURI, cAppCharP aLocalURI, cAppCharP aSessionID ) { TEngineServerCommConfig *commCfgP = static_cast(getRootConfig()->fCommConfigP); if (aLocalURI && aSessionID && commCfgP && commCfgP->fSessionIDCGI) { // include session ID as CGI into RespURI aRespURI=aLocalURI; // see if there is already a sessionid in this localURI string::size_type n=aRespURI.find(commCfgP->fSessionIDCGIPrefix); if (n!=string::npos) { n+=commCfgP->fSessionIDCGIPrefix.size(); // char after prefix // is already there, replace value with new value string::size_type m=aRespURI.find_first_of("&?\n\r",n); if (m==string::npos) aRespURI.replace(n,999,aSessionID); else aRespURI.replace(n,m-n,aSessionID); } else { // no sessionID yet if (strchr(aLocalURI,'?')) { // already has CGI param aRespURI+="&"; } else { // is first CGI param aRespURI+='?'; } // append session ID as CGI parameter aRespURI+=commCfgP->fSessionIDCGIPrefix; aRespURI+=aSessionID; } } } // TEngineSessionDispatch::generateRespURI // Handle exception happening while decoding commands for a session Ret_t TEngineSessionDispatch::HandleDecodingException(TSyncSession *aSessionP, const char *aRoutine, exception *aExceptionP) { #ifdef SYDEBUG // determine session name const char *sname = ""; SYSYNC_TRY { if (aSessionP) { sname = aSessionP->getLocalSessionID(); } } SYSYNC_CATCH (...) sname = ""; aSessionP=NULL; // prevent attempt to write to session's log SYSYNC_ENDCATCH // determine routine name if (!aRoutine) aRoutine=""; // show details if (aExceptionP) { // known exception // - show it in global log PDEBUGPRINTFX(DBG_ERROR,( "******** Exception in %s, sessionID=%s: %s", aRoutine, sname, aExceptionP->what() )); // - and also in session log #ifdef SYDEBUG if (aSessionP) { POBJDEBUGPRINTFX(aSessionP,DBG_ERROR,( "******** Warning: Exception in %s: %s", aRoutine, aExceptionP->what() )); } #endif } else { // unknown exception // - show it in global log PDEBUGPRINTFX(DBG_ERROR,( "******** Unknown Exception in %s, sessionID=%s", aRoutine, sname )); // - and also in session log #ifdef SYDEBUG if (aSessionP) { POBJDEBUGPRINTFX(aSessionP,DBG_ERROR,( "******** Warning: Unknown Exception in %s", aRoutine )); } #endif } #endif // try to kill session DEBUGPRINTFX(DBG_SESSION,("******** Exception aborts session")); aSessionP->AbortSession(412,true); // incomplete command // return error DEBUGPRINTFX(DBG_SESSION,("******** Exception: returning SML_ERR_UNSPECIFIC to abort smlProcessData")); return SML_ERR_UNSPECIFIC; } // TEngineSessionDispatch::HandleDecodingException // factory methods of Rootconfig // ============================= // create default transport config void TEngineServerRootConfig::installCommConfig(void) { // engine API needs no config at this time, commconfig is a NOP dummy for now fCommConfigP=new TEngineServerCommConfig(this); } // TEngineServerRootConfig::installCommConfig #ifndef HARDCODED_CONFIG bool TEngineServerRootConfig::parseCommConfig(const char **aAttributes, sInt32 aLine) { // engine API needs no config at this time return false; } // TEngineServerRootConfig::parseCommConfig #endif // TEngineServerSessionHandle // ========================== // Note: this is not a relative of TSyncSessionHandle, but only a container for TSyncAgent also // holding some engine-related status. TSyncAgent is run with a NULL TSyncSessionHandle // when called via engine, as all session dispatching is outside the engine. TEngineServerSessionHandle::TEngineServerSessionHandle(TServerEngineInterface *aServerEngineInterface) { fServerSessionP = NULL; fSmlInstanceID = 0; fServerSessionStatus = LOCERR_WRONGUSAGE; fServerEngineInterface = aServerEngineInterface; } TEngineServerSessionHandle::~TEngineServerSessionHandle() { // remove the session if still existing if (fServerSessionP) delete fServerSessionP; fServerSessionP = NULL; // also release the toolkit instance fServerEngineInterface->getSyncAppBase()->freeSmlInstance(fSmlInstanceID); fSmlInstanceID=NULL; } // TServerEngineInterface // ====================== /// @brief Open a session /// @param aNewSessionH[out] receives session handle for all session execution calls /// @param aSelector[in] selector, depending on session type. /// @param aSessionName[in] a text name/id to identify the session. If NULL, session gets a standard ID based on time and memory location /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure TSyError TServerEngineInterface::OpenSessionInternal(SessionH &aNewSessionH, uInt32 aSelector, cAppCharP aSessionName) { TEngineSessionDispatch *sessionDispatchP = static_cast(getSyncAppBase()); // check type of session if (aSelector == SESSIONSEL_DBAPI_TUNNEL) { // initiate a DBAPI tunnel session. /* #ifdef DBAPI_TUNNEL_SUPPORT #error "%%% tbi" // Create a new session, sessionName selects datastore sessionHandleP->fServerSessionStatus = sessionDispatchP->CreateTunnelSession(aSessionName); if (sessionHandleP->fServerSessionStatus==LOCERR_OK) { // return the session pointer as handle %%%aNewSessionH=clientBaseP->fClientSessionP; } #else return LOCERR_NOTIMP; // tunnel not implemented #endif */ // %%% for now: not implemented return LOCERR_NOTIMP; // tunnel not implemented } else { // create a new server session TEngineServerSessionHandle *sessionHandleP = NULL; TSyncAgent *sessionP=NULL; SYSYNC_TRY { // - create a handle sessionHandleP = new TEngineServerSessionHandle(this); // - create session ID if none passed string SessionIDString; if (aSessionName && *aSessionName) { SessionIDString = aSessionName; } else { // - create unique server-side session ID // format = aaaabbbbccccdddd // - aaaa = low word of time(NULL) >> 1 (to make sure MSB is cleared) // - dddd = high word of time(NULL) // - bbbbcccc = memory address of session handle uInt64 sid = time(NULL); sid = ((sid >> 16) & 0xFFFF) + ((sid << 47) & 0x7FFF000000000000LL) + // aaaa00000000dddd ((((uIntPtr)sessionHandleP)&0xFFFFFFFF) << 16); // 0000bbbbcccc0000 // - make a string of it StringObjPrintf(SessionIDString,"%llu",(long long unsigned)sid); } // - create session object sessionP = static_cast(sessionDispatchP->getRootConfig()->fAgentConfigP) ->CreateServerSession(NULL,SessionIDString.c_str()); if (sessionP) { // assign to handle sessionHandleP->fServerSessionP = sessionP; sessionHandleP->fServerSessionStatus = LOCERR_OK; // also create a toolkit instance for the session (so we can start receiving data) if (!getSyncAppBase()->newSmlInstance( SML_XML, sessionDispatchP->getRootConfig()->fLocalMaxMsgSize * 2, // twice the message size sessionHandleP->fSmlInstanceID )) { // failed creating instance (must be memory problem) delete sessionP; return LOCERR_OUTOFMEM; } // link session with toolkit instance back and forth getSyncAppBase()->setSmlInstanceUserData(sessionHandleP->fSmlInstanceID,sessionP); // toolkit must know session (as userData) sessionP->setSmlWorkspaceID(sessionHandleP->fSmlInstanceID); // session must know toolkit workspace // created session ok aNewSessionH = (SessionH)sessionHandleP; return LOCERR_OK; } } SYSYNC_CATCH (...) // error creating session if (sessionHandleP) delete sessionHandleP; return LOCERR_EXCEPTION; SYSYNC_ENDCATCH } return LOCERR_WRONGUSAGE; } /// @brief open session specific runtime parameter/settings key /// @note key handle obtained with this call must be closed BEFORE SESSION IS CLOSED! /// @param aNewKeyH[out] receives the opened key's handle on success /// @param aSessionH[in] session handle obtained with OpenSession /// @param aMode[in] the open mode /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure TSyError TServerEngineInterface::OpenSessionKey(SessionH aSessionH, KeyH &aNewKeyH, uInt16 aMode) { if (!aSessionH) return LOCERR_WRONGUSAGE; TEngineServerSessionHandle *sessionHandleP = reinterpret_cast(aSessionH); // create settings key for the session aNewKeyH = (KeyH)sessionHandleP->fServerSessionP->newSessionKey(this); // done return LOCERR_OK; } /// @brief Close a session /// @note terminates and destroys the session (if not already terminated) /// @param aSessionH[in] session handle obtained with OpenSession /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure TSyError TServerEngineInterface::CloseSession(SessionH aSessionH) { if (!aSessionH) return LOCERR_WRONGUSAGE; TSyError sta = LOCERR_OK; TEngineServerSessionHandle *sessionHandleP = reinterpret_cast(aSessionH); TSyncAgent *serverSessionP = sessionHandleP->fServerSessionP; if (serverSessionP) { // session still exists if (!serverSessionP->isAborted()) { // if not already aborted otherwise (e.g. by writing "abortstatus" in session key), let it be "timeout" serverSessionP->AbortSession(408, true); } SYSYNC_TRY { // - terminate (might hang a while until subthreads properly terminate) serverSessionP->TerminateSession(); // - delete sessionHandleP->fServerSessionP = NULL; // consider deleted, whatever happens delete serverSessionP; // might hang until subthreads have terminated } SYSYNC_CATCH(...) sessionHandleP->fServerSessionP = NULL; // consider deleted, even if failed sta = LOCERR_EXCEPTION; SYSYNC_ENDCATCH } // forget session handle (and toolkit instance) delete sessionHandleP; // done return LOCERR_OK; } /// @brief Executes sync session or other sync related activity step by step /// @param aSessionH[in] session handle obtained with OpenSession /// @param aStepCmd[in/out] step command (STEPCMD_xxx): /// - tells caller to send or receive data or end the session etc. /// - instructs engine to suspend or abort the session etc. /// @param aInfoP[in] pointer to a TEngineProgressInfo structure, NULL if no progress info needed /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure TSyError TServerEngineInterface::SessionStep(SessionH aSessionH, uInt16 &aStepCmd, TEngineProgressInfo *aInfoP) { if (!aSessionH) return LOCERR_WRONGUSAGE; TEngineServerSessionHandle *sessionHandleP = reinterpret_cast(aSessionH); TSyncAgent *serverSessionP = sessionHandleP->fServerSessionP; // preprocess general step codes switch (aStepCmd) { case STEPCMD_TRANSPFAIL : // directly abort serverSessionP->AbortSession(LOCERR_TRANSPFAIL,true); goto abort; case STEPCMD_TIMEOUT : // directly abort serverSessionP->AbortSession(408,true); abort: aStepCmd = STEPCMD_STEP; // convert to normal step break; } // let server session handle it sessionHandleP->fServerSessionStatus = serverSessionP->SessionStep(aStepCmd, aInfoP); // return step status return sessionHandleP->fServerSessionStatus; } // TServerEngineInterface::SessionStep /// @brief returns the SML instance for a given session handle /// (internal helper to allow TEngineInterface to provide the access to the SyncML buffer) InstanceID_t TServerEngineInterface::getSmlInstanceOfSession(SessionH aSessionH) { if (!aSessionH) return 0; // something wrong with session handle -> no SML instance TEngineServerSessionHandle *sessionHandleP = reinterpret_cast(aSessionH); TSyncAgent *serverSessionP = sessionHandleP->fServerSessionP; if (!serverSessionP) return 0; // something wrong with session handle -> no SML instance // return SML instance associated with that session return serverSessionP->getSmlWorkspaceID(); } // TServerEngineInterface::getSmlInstanceOfSession } // namespace sysync // eof libsynthesis-3.4.0.47.1/src/Transport_interfaces/engine/enginesessiondispatch.h000066400000000000000000000137411226375725500276470ustar00rootroot00000000000000/* * TEngineSessionDispatch * Server library specific descendant of TSyncSessionDispatch * * Copyright (c) 2009-2011 by Synthesis AG + plan44.ch * * 2009-02-06 : luz : Created * */ #ifndef ENGINESESSIONDISPATCH_H #define ENGINESESSIONDISPATCH_H // required headers #include "syncappbase.h" #include "syncagent.h" namespace sysync { // Engine module class class TServerEngineInterface : public TEngineInterface { typedef TEngineInterface inherited; public: // constructor TServerEngineInterface() {}; // no appbase factory at this level (must be implemented in non-virtual descendants) virtual TSyncAppBase *newSyncAppBase(void) = 0; // Running a Server Sync Session // ----------------------------- /// @brief Open a session /// @param aNewSessionH[out] receives session handle for all session execution calls /// @param aSelector[in] selector, depending on session type. /// @param aSessionName[in] a text name/id to identify a session, useage depending on session type. /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure virtual TSyError OpenSessionInternal(SessionH &aNewSessionH, uInt32 aSelector, cAppCharP aSessionName); /// @brief open session specific runtime parameter/settings key /// @note key handle obtained with this call must be closed BEFORE SESSION IS CLOSED! /// @param aNewKeyH[out] receives the opened key's handle on success /// @param aSessionH[in] session handle obtained with OpenSession /// @param aMode[in] the open mode /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure virtual TSyError OpenSessionKey(SessionH aSessionH, KeyH &aNewKeyH, uInt16 aMode); /// @brief Close a session /// @note It depends on session type if this also destroys the session or if it may persist and can be re-opened. /// @param aSessionH[in] session handle obtained with OpenSession /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure virtual TSyError CloseSession(SessionH aSessionH); /// @brief Executes sync session or other sync related activity step by step /// @param aSessionH[in] session handle obtained with OpenSession /// @param aStepCmd[in/out] step command (STEPCMD_xxx): /// - tells caller to send or receive data or end the session etc. /// - instructs engine to suspend or abort the session etc. /// @param aInfoP[in] pointer to a TEngineProgressInfo structure, NULL if no progress info needed /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure virtual TSyError SessionStep(SessionH aSessionH, uInt16 &aStepCmd, TEngineProgressInfo *aInfoP = NULL); protected: /// @brief returns the SML instance for a given session handle virtual InstanceID_t getSmlInstanceOfSession(SessionH aSessionH); }; // TServerEngineInterface // engine client root config class TEngineServerRootConfig : public TRootConfig { typedef TRootConfig inherited; public: TEngineServerRootConfig(TSyncAppBase *aSyncAppBaseP) : inherited(aSyncAppBaseP) {}; // factory methods virtual void installCommConfig(void); // Config parsing #ifndef HARDCODED_CONFIG virtual bool parseCommConfig(const char **aAttributes, sInt32 aLine); #endif }; // TEngineClientRootConfig // engine server transport config class TEngineServerCommConfig: public TCommConfig { typedef TCommConfig inherited; public: TEngineServerCommConfig(TConfigElement *aParentElementP); virtual ~TEngineServerCommConfig(); // config vars // - session ID CGI config bool fSessionIDCGI; string fSessionIDCGIPrefix; // - indicates transport can buffer answer to client until next client response, so it can be resent in case we detect a client resend. bool fBuffersRetryAnswer; protected: // check config elements #ifndef HARDCODED_CONFIG virtual bool localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine); #endif virtual void clear(); virtual void localResolve(bool aLastPass); }; // TXPTCommConfig // forward declarations class TSyncAgent; class TSyncSession; // session handle for engine sessions // containing engine-specific session status class TEngineServerSessionHandle : noncopyable { public: TEngineServerSessionHandle(TServerEngineInterface *aServerEngineInterface); virtual ~TEngineServerSessionHandle(); // the server engine interface TServerEngineInterface *fServerEngineInterface; // the session itself TSyncAgent *fServerSessionP; // the toolkit instance used by the session InstanceID_t fSmlInstanceID; // status of the session localstatus fServerSessionStatus; }; // AppBase class for all server engines (libararies with API to build custom servers) // Note: unlike non-engine servers, the server library bypasses TSyncSessionDispatch // completely. All actual session dispatch, thread locking, session timeout // stuff must be implemented outside the library for engine-based servers. class TEngineSessionDispatch : public TSyncAppBase { typedef TSyncAppBase inherited; public: // constructors/destructors TEngineSessionDispatch(); virtual ~TEngineSessionDispatch(); // handlers for SyncML toolkit callbacks // - Start/End Message: identifies Session, and creates new or assigns existing session Ret_t StartMessage( InstanceID_t aSmlWorkspaceID, // SyncML toolkit workspace instance ID VoidPtr_t aUserData, // pointer to a TSyncAgent descendant SmlSyncHdrPtr_t aContentP // SyncML tookit's decoded form of the element ); // - Handle exception happening while decoding commands for a session virtual Ret_t HandleDecodingException(TSyncSession *aSessionP, const char *aRoutine, exception *aExceptionP); // test if message buffering is available virtual bool canBufferRetryAnswer(void); // combine URI and session ID to make a RespURI according to transport virtual void generateRespURI( string &aRespURI, cAppCharP aLocalURI, cAppCharP aSessionID ); }; // TEngineSessionDispatch } // namespace sysync #endif // ENGINESESSIONDISPATCH_H // eof libsynthesis-3.4.0.47.1/src/client_engine_linux.mk000066400000000000000000000136361226375725500220170ustar00rootroot00000000000000# Makefile generated by Metrowerks CodeWarrior IDE # adapted for standalone use 09/02/05 by bfo@synthesis.ch all: clientEngine clean: clean_clientEngine ####### common definitions WD=$(shell echo `pwd`) WD_OBJS=$(WD)/../OBJS CC="gcc" LD="gcc" AR="ar -crs" SIZE="size" CFLAGS= -m32 -Wall -O2 -c -MMD LDFLAGS= -m32 MAKEFILE= "client_engine_linux.mk" SYNCML_TK_SML=\ syncml_tk/src/sml/lib/all/liblock.c\ syncml_tk/src/sml/lib/all/libmem.c\ syncml_tk/src/sml/lib/all/libstr.c\ syncml_tk/src/sml/lib/all/libutil.c\ syncml_tk/src/sml/mgr/all/mgr.c\ syncml_tk/src/sml/mgr/all/mgrcmdbuilder.c\ syncml_tk/src/sml/mgr/all/mgrcmddispatcher.c\ syncml_tk/src/sml/mgr/all/mgrinstancelist.c\ syncml_tk/src/sml/mgr/all/mgrinstancemgr.c\ syncml_tk/src/sml/mgr/all/mgrutil.c\ syncml_tk/src/sml/xlt/all/xltdec.c\ syncml_tk/src/sml/xlt/all/xltdecwbxml.c\ syncml_tk/src/sml/xlt/all/xltdecxml.c\ syncml_tk/src/sml/xlt/all/xltdevinf.c\ syncml_tk/src/sml/xlt/all/xltenc.c\ syncml_tk/src/sml/xlt/all/xltenccom.c\ syncml_tk/src/sml/xlt/all/xltencwbxml.c\ syncml_tk/src/sml/xlt/all/xltencxml.c\ syncml_tk/src/sml/xlt/all/xltmetinf.c\ syncml_tk/src/sml/xlt/all/xlttags.c\ syncml_tk/src/sml/xlt/all/xltutilstack.c EXPAT=\ expat/xmltok/xmltok.c\ expat/xmltok/xmlrole.c\ expat/xmlparse/xmlparse.c ZLIB=\ zlib/adler32.c\ zlib/compress.c\ zlib/crc32.c\ zlib/deflate.c\ zlib/gzio.c\ zlib/infback.c\ zlib/inffast.c\ zlib/inflate.c\ zlib/inftrees.c\ zlib/trees.c\ zlib/uncompr.c\ zlib/zutil.c C_BASICS=\ $(SYNCML_TK_SML)\ $(EXPAT)\ platform_adapters/linux/platform_exec.c\ sysync_SDK/Sources/SDK_util.c\ SQLite/sqlite3.c PLATFORM=\ platform_adapters/linux/configfiles.cpp\ platform_adapters/linux/profiling.cpp\ platform_adapters/linux/platform_time.cpp\ platform_adapters/unix_common/platform_mutex.cpp\ platform_adapters/sysyncinit.cpp PLATFORM_EXT=\ $(PLATFORM)\ platform_adapters/linux/platform_DLL.cpp\ platform_adapters/unix_common/platform_thread.cpp\ platform_adapters/unix_common/platform_file.cpp BINFILES=\ platform_adapters/binfile.cpp\ sysync/binfileimplds.cpp\ sysync/binfileimplclient.cpp\ sysync/binfilebase.cpp SYSYNC=\ sysync/sysync_utils.cpp\ sysync/sysync_b64.cpp\ sysync/sysync_md5.cpp\ sysync/syncsession.cpp\ sysync/syncappbase.cpp\ sysync/lineartime.cpp\ sysync/iso8601.cpp\ sysync/stringutils.cpp\ sysync/superdatastore.cpp\ sysync/scriptcontext.cpp\ sysync/itemfield.cpp\ sysync/mimediritemtype.cpp\ sysync/mimedirprofile.cpp\ sysync/multifielditem.cpp\ sysync/multifielditemtype.cpp\ sysync/remotedatastore.cpp\ sysync/syncitem.cpp\ sysync/syncitemtype.cpp\ sysync/simpleitem.cpp\ sysync/synccommand.cpp\ sysync/syncdatastore.cpp\ sysync/textitemtype.cpp\ sysync/vcalendaritemtype.cpp\ sysync/vcarditemtype.cpp\ sysync/syncexception.cpp\ sysync/configelement.cpp\ sysync/sysync_crc16.cpp\ sysync/timezones.cpp\ sysync/rrules.cpp\ sysync/localengineds.cpp\ sysync/debuglogger.cpp\ sysync/textprofile.cpp\ sysync/dataobjtype.cpp\ sysync/stdlogicds.cpp\ sysync/stdlogicagent.cpp\ sysync/customimplagent.cpp\ sysync/customimplds.cpp\ sysync/vtimezone.cpp CLIENTENGINE=\ $(SYSYNC)\ syncapps/clientEngine_custom/clientengine_custom_Base.cpp\ Transport_interfaces/engine/engineclientbase.cpp\ sysync_SDK/Sources/enginemodulebase.cpp\ sysync/engineentry.cpp\ sysync/engineinterface.cpp\ sysync/syncagent.cpp\ sysync/syncclientbase.cpp ODBC_DB=\ DB_interfaces/odbc_db/odbcapiagent.cpp\ DB_interfaces/odbc_db/odbcapids.cpp API_DB=\ DB_interfaces/api_db/pluginapiagent.cpp\ DB_interfaces/api_db/pluginapids.cpp\ DB_interfaces/api_db/dbapi.cpp\ DB_interfaces/api_db/DLL_interface.cpp\ DB_interfaces/api_db/sync_dbapiconnect.cpp\ sysync_SDK/Sources/SDK_support.cpp # -------------------------------------------------------- INCLUDE_PLATFORM=\ -I platform_adapters/linux/\ -I platform_adapters/unix_common/\ -I platform_adapters/ INCLUDE_SYNCML_TK_SML=\ -I syncml_tk/src/sml/inc/\ -I syncml_tk/src/sml/lib/inc/\ -I syncml_tk/src/sml/lib/\ -I syncml_tk/src/sml/mgr/inc/\ -I syncml_tk/src/sml/mgr/\ -I syncml_tk/src/sml/wsm/inc/\ -I syncml_tk/src/sml/xlt/inc/\ -I syncml_tk/src/sml/xlt/all/ INCLUDE_EXPAT=\ -I expat/xmltok/\ -I expat/xmlparse/ INCLUDE_CLIENTENGINE=\ -I syncapps/clientEngine_custom/\ -I Transport_interfaces/engine/\ -I sysync_SDK/Sources\ -I sysync/\ -I ./ ############################# ####### TARGET: clientEngine ############################# WD_OBJS_clientEngine=$(WD_OBJS)/clientEngine c_SRC_clientEngine=\ $(C_BASICS) $(ZLIB) cpp_SRC_clientEngine=\ $(PLATFORM_EXT)\ $(CLIENTENGINE)\ $(BINFILES)\ $(ODBC_DB)\ $(API_DB) OBJS_clientEngine+= $(c_SRC_clientEngine:.c=.c.o) OBJS_clientEngine+=$(cpp_SRC_clientEngine:.cpp=.cpp.o) INCLUDE_clientEngine=\ -include Targets/ReleasedProducts/clientEngine_opensource_linux/clientengine_demo_x86_linux_prefix.h\ -I Targets/ReleasedProducts/clientEngine_opensource_linux/\ $(INCLUDE_PLATFORM)\ $(INCLUDE_SYNCML_TK_SML)\ $(INCLUDE_EXPAT)\ $(INCLUDE_CLIENTENGINE)\ -I DB_interfaces/odbc_db/\ -I DB_interfaces/api_db/\ -I SQLite/\ -I zlib/\ -I /usr/include/ clientEngine: $(MAKE) -f $(MAKEFILE) sysync_client_engine.so TARGET=sysync_client_engine.so\ WDOP="$(WD_OBJS_clientEngine)"\ OBJS="$(addprefix $(WD_OBJS_clientEngine)/,$(OBJS_clientEngine))"\ LIBS="-L/usr/lib32 -L/usr/lib -lstdc++ -lpthread -lltdl -lpcre"\ INCL="$(INCLUDE_clientEngine)" sysync_client_engine.so: $(OBJS) $(LD) -shared -Xlinker -soname=sysync_client_engine $(LDFLAGS) $(OBJS) $(LIBS)\ -o sysync_SDK/bin/Linux/sysync_client_engine.so ifeq ($(TARGET), sysync_client_engine.so) $(WDOP)/%.c.o: $(WD)/%.c mkdir -p $(dir $@) $(CC) -fPIC $(CFLAGS) $(INCL) $< -o $@ $(WDOP)/%.cpp.o: $(WD)/%.cpp mkdir -p $(dir $@) $(CC) -fPIC $(CFLAGS) $(INCL) $< -o $@ endif clean_clientEngine: rm -f -r $(WD_OBJS_clientEngine) libsynthesis-3.4.0.47.1/src/combi_engine_linux.mk000066400000000000000000000143101226375725500216200ustar00rootroot00000000000000# Makefile generated by Metrowerks CodeWarrior IDE # adapted for standalone client library use 2009/02/05 by bfo@synthesis.ch # adapted for standalone server library use 2009/09/22 by luz@synthesis.ch # adapted for standalone combi (client+server) library use 2009/10/03 by luz@synthesis.ch all: combiEngine clean: clean_combiEngine ####### common definitions WD=$(shell echo `pwd`) WD_OBJS=$(WD)/../OBJS CC="gcc" LD="gcc" AR="ar -crs" SIZE="size" CFLAGS= -m32 -Wall -O2 -c -MMD LDFLAGS= -m32 MAKEFILE= "combi_engine_linux.mk" SYNCML_TK_SML=\ syncml_tk/src/sml/lib/all/liblock.c\ syncml_tk/src/sml/lib/all/libmem.c\ syncml_tk/src/sml/lib/all/libstr.c\ syncml_tk/src/sml/lib/all/libutil.c\ syncml_tk/src/sml/mgr/all/mgr.c\ syncml_tk/src/sml/mgr/all/mgrcmdbuilder.c\ syncml_tk/src/sml/mgr/all/mgrcmddispatcher.c\ syncml_tk/src/sml/mgr/all/mgrinstancelist.c\ syncml_tk/src/sml/mgr/all/mgrinstancemgr.c\ syncml_tk/src/sml/mgr/all/mgrutil.c\ syncml_tk/src/sml/xlt/all/xltdec.c\ syncml_tk/src/sml/xlt/all/xltdecwbxml.c\ syncml_tk/src/sml/xlt/all/xltdecxml.c\ syncml_tk/src/sml/xlt/all/xltdevinf.c\ syncml_tk/src/sml/xlt/all/xltenc.c\ syncml_tk/src/sml/xlt/all/xltenccom.c\ syncml_tk/src/sml/xlt/all/xltencwbxml.c\ syncml_tk/src/sml/xlt/all/xltencxml.c\ syncml_tk/src/sml/xlt/all/xltmetinf.c\ syncml_tk/src/sml/xlt/all/xlttags.c\ syncml_tk/src/sml/xlt/all/xltutilstack.c EXPAT=\ expat/xmltok/xmltok.c\ expat/xmltok/xmlrole.c\ expat/xmlparse/xmlparse.c ZLIB=\ zlib/adler32.c\ zlib/compress.c\ zlib/crc32.c\ zlib/deflate.c\ zlib/gzio.c\ zlib/infback.c\ zlib/inffast.c\ zlib/inflate.c\ zlib/inftrees.c\ zlib/trees.c\ zlib/uncompr.c\ zlib/zutil.c C_BASICS=\ $(SYNCML_TK_SML)\ $(EXPAT)\ platform_adapters/linux/platform_exec.c\ sysync_SDK/Sources/SDK_util.c PLATFORM=\ platform_adapters/linux/configfiles.cpp\ platform_adapters/linux/profiling.cpp\ platform_adapters/linux/platform_time.cpp\ platform_adapters/unix_common/platform_mutex.cpp\ platform_adapters/sysyncinit.cpp PLATFORM_EXT=\ $(PLATFORM)\ platform_adapters/linux/platform_DLL.cpp\ platform_adapters/unix_common/platform_thread.cpp\ platform_adapters/unix_common/platform_file.cpp SYSYNC=\ sysync/sysync_utils.cpp\ sysync/sysync_b64.cpp\ sysync/sysync_md5.cpp\ sysync/syncsession.cpp\ sysync/syncappbase.cpp\ sysync/lineartime.cpp\ sysync/iso8601.cpp\ sysync/stringutils.cpp\ sysync/superdatastore.cpp\ sysync/scriptcontext.cpp\ sysync/itemfield.cpp\ sysync/mimediritemtype.cpp\ sysync/mimedirprofile.cpp\ sysync/multifielditem.cpp\ sysync/multifielditemtype.cpp\ sysync/remotedatastore.cpp\ sysync/syncitem.cpp\ sysync/syncitemtype.cpp\ sysync/simpleitem.cpp\ sysync/synccommand.cpp\ sysync/syncdatastore.cpp\ sysync/textitemtype.cpp\ sysync/vcalendaritemtype.cpp\ sysync/vcarditemtype.cpp\ sysync/syncexception.cpp\ sysync/configelement.cpp\ sysync/sysync_crc16.cpp\ sysync/timezones.cpp\ sysync/rrules.cpp\ sysync/localengineds.cpp\ sysync/debuglogger.cpp\ sysync/textprofile.cpp\ sysync/dataobjtype.cpp\ sysync/stdlogicds.cpp\ sysync/stdlogicagent.cpp\ sysync/customimplagent.cpp\ sysync/customimplds.cpp\ sysync/vtimezone.cpp COMBIENGINE=\ $(SYSYNC)\ syncapps/serverEngine_custom/serverengine_custom_Base.cpp\ syncapps/clientEngine_custom/clientengine_custom_Base.cpp\ Transport_interfaces/engine/enginesessiondispatch.cpp\ Transport_interfaces/engine/engineclientbase.cpp\ sysync_SDK/Sources/enginemodulebase.cpp\ sysync/engineentry.cpp\ sysync/engineinterface.cpp\ sysync/syncclientbase.cpp\ sysync/syncagent.cpp ODBC_DB=\ DB_interfaces/odbc_db/odbcapiagent.cpp\ DB_interfaces/odbc_db/odbcapids.cpp API_DB=\ DB_interfaces/api_db/pluginapiagent.cpp\ DB_interfaces/api_db/pluginapids.cpp\ DB_interfaces/api_db/dbapi.cpp\ DB_interfaces/api_db/DLL_interface.cpp\ DB_interfaces/api_db/sync_dbapiconnect.cpp\ sysync_SDK/Sources/SDK_support.cpp\ sysync_SDK/DB_Interfaces/text_db/sync_dbapi_text.cpp\ sysync_SDK/Sources/admindata.cpp\ sysync_SDK/Sources/dbitem.cpp\ sysync_SDK/Sources/blobs.cpp # -------------------------------------------------------- INCLUDE_PLATFORM=\ -I platform_adapters/linux/\ -I platform_adapters/unix_common/\ -I platform_adapters/ INCLUDE_SYNCML_TK_SML=\ -I syncml_tk/src/sml/inc/\ -I syncml_tk/src/sml/lib/inc/\ -I syncml_tk/src/sml/lib/\ -I syncml_tk/src/sml/mgr/inc/\ -I syncml_tk/src/sml/mgr/\ -I syncml_tk/src/sml/wsm/inc/\ -I syncml_tk/src/sml/xlt/inc/\ -I syncml_tk/src/sml/xlt/all/ INCLUDE_EXPAT=\ -I expat/xmltok/\ -I expat/xmlparse/ INCLUDE_COMBIENGINE=\ -I syncapps/serverEngine_custom/\ -I syncapps/clientEngine_custom/\ -I Transport_interfaces/engine/\ -I sysync_SDK/Sources\ -I sysync/\ -I ./ ############################ ####### TARGET: combiEngine ############################ WD_OBJS_combiEngine=$(WD_OBJS)/combiEngine c_SRC_combiEngine=\ $(C_BASICS) $(ZLIB) cpp_SRC_combiEngine=\ $(PLATFORM_EXT)\ $(COMBIENGINE)\ $(ODBC_DB)\ $(API_DB) OBJS_combiEngine+= $(c_SRC_combiEngine:.c=.c.o) OBJS_combiEngine+=$(cpp_SRC_combiEngine:.cpp=.cpp.o) INCLUDE_combiEngine=\ -include Targets/ReleasedProducts/combiEngine_opensource_linux/combiengine_opensource_linux_prefix.h\ -I Targets/ReleasedProducts/combiEngine_opensource_linux/\ $(INCLUDE_PLATFORM)\ $(INCLUDE_SYNCML_TK_SML)\ $(INCLUDE_EXPAT)\ $(INCLUDE_COMBIENGINE)\ -I DB_interfaces/odbc_db/\ -I DB_interfaces/api_db/\ -I SQLite/\ -I zlib/\ -I /usr/include/ combiEngine: $(MAKE) -f $(MAKEFILE) sysync_combi_engine.so TARGET=sysync_combi_engine.so \ WDOP="$(WD_OBJS_combiEngine)"\ OBJS="$(addprefix $(WD_OBJS_combiEngine)/,$(OBJS_combiEngine))"\ LIBS="-L/usr/lib32 -L/usr/lib -lstdc++ -lpthread -lltdl -lpcre"\ INCL="$(INCLUDE_combiEngine)" sysync_combi_engine.so: $(OBJS) $(LD) -shared -Xlinker -soname=sysync_combi_engine $(LDFLAGS) $(OBJS) $(LIBS) \ -o sysync_SDK/bin/Linux/sysync_combi_engine.so ifeq ($(TARGET), sysync_combi_engine.so) $(WDOP)/%.c.o: $(WD)/%.c mkdir -p $(dir $@) $(CC) -fPIC $(CFLAGS) $(INCL) $< -o $@ $(WDOP)/%.cpp.o: $(WD)/%.cpp mkdir -p $(dir $@) $(CC) -fPIC $(CFLAGS) $(INCL) $< -o $@ endif clean_combiEngine: rm -f -r $(WD_OBJS_combiEngine) libsynthesis-3.4.0.47.1/src/gen-makefile-am.sh000077500000000000000000000071271226375725500207200ustar00rootroot00000000000000#! /bin/sh # # Turns Makefile.am.in into a Makefile.am which can be processed by # automake. This is necessary because automake cannot build a list # of source files dynamically. # directories which contain sources for the sync engine ENGINE_SOURCES="sysync DB_interfaces sysync_SDK/Sources Transport_interfaces/engine platform_adapters" # files needed exclusively for libsynthesissdk.a cat > SDK_FILES < SDK_EXCLUDE_FILES <CLIENT_FILES < SERVER_FILES < EXTRA_FILES < EXCLUDE_FILES LIBSYNTHESIS_SOURCES=`find ${ENGINE_SOURCES} \ syncapps/clientEngine_custom \ syncapps/serverEngine_custom \ sysync_SDK/DB_Interfaces/text_db \ \( -name '*.cpp' -o -name '*.[ch]' \) | grep -v -E -f EXCLUDE_FILES | sort` LIBSYNTHESIS_SOURCES=`echo $LIBSYNTHESIS_SOURCES` # files to be included in both libsynthesis and libsynthesissdk; # necessary when building as shared libraries with these files not # being exposed by libsynthesis cat SERVER_FILES CLIENT_FILES EXTRA_FILES > EXCLUDE_FILES LIBSYNTHESISSDK_SOURCES_BOTH=`find sysync_SDK/Sources \ \( -name '*.cpp' -o -name '*.c' \) | grep -v -E -f EXCLUDE_FILES | sort` LIBSYNTHESISSDK_SOURCES_BOTH=`echo $LIBSYNTHESISSDK_SOURCES_BOTH` # files only needed in libsynthesissdk cat SERVER_FILES CLIENT_FILES EXTRA_FILES > EXCLUDE_FILES LIBSYNTHESISSDK_SOURCES_ONLY=`find sysync_SDK/Sources \ \( -name '*.cpp' -o -name '*.c' \) | grep -E -f SDK_FILES | grep -v -E -f EXCLUDE_FILES | sort` LIBSYNTHESISSDK_SOURCES_ONLY=`echo $LIBSYNTHESISSDK_SOURCES_ONLY` # files needed in libsmltk LIBSMLTK_SOURCES=`find syncml_tk \ \( -name '*.cpp' -o -name '*.[ch]' \) \ \! \( -path syncml_tk/src/sml/\*/palm/\* -o \ -path syncml_tk/src/sml/\*/win/\* \) | sort` LIBSMLTK_SOURCES=`echo $LIBSMLTK_SOURCES` # header files required for using libsynthesissdk, # with "synthesis/" prefix LIBSYNTHESISSDK_HEADERS=`find sysync_SDK/Sources -name '*.h' | sed -e 's;.*/;synthesis/;' | sort` LIBSYNTHESISSDK_HEADERS=`echo $LIBSYNTHESISSDK_HEADERS` sed -e "s;@LIBSYNTHESIS_SOURCES@;$LIBSYNTHESIS_SOURCES;" \ -e "s;@LIBSYNTHESISSDK_SOURCES_BOTH@;$LIBSYNTHESISSDK_SOURCES_BOTH;" \ -e "s;@LIBSYNTHESISSDK_SOURCES_SDK_ONLY@;$LIBSYNTHESISSDK_SOURCES_ONLY;" \ -e "s;@LIBSMLTK_SOURCES@;$LIBSMLTK_SOURCES;" \ -e "s;@LIBSYNTHESISSDK_HEADERS@;$LIBSYNTHESISSDK_HEADERS;" \ Makefile.am.in >Makefile.am libsynthesis-3.4.0.47.1/src/global_options.h000066400000000000000000000230121226375725500206150ustar00rootroot00000000000000/* SySync entirely global options (affects all targets) * ==================================================== * * (c) 2001-2012 by Synthesis AG + plan44.ch * */ #ifndef GLOBAL_OPTIONS_H #define GLOBAL_OPTIONS_H // the following should be defined BEFORE including this file // - SYSYNC_CLIENT : defined if client functionality should be included // - SYSYNC_SERVER : defined if server functionality should be included // If not defined, and SYSYNC_CLIENT is also not defined, build // defaults to SYSYNC_SERVER // - platform defines, like MACOSX, MOBOSX, LINUX, WINCE, _WIN32 // __PALM_OS__, __EPOC_OS__ etc. // - RELEASE_VERSION : define in targets that are real product releases // not internal debug/test/experimental releases // - RELEASE_SYDEBUG : define the debug level for RELEASE_VERSION // (0=no debug code at all, 1=basic debug, 2=extended, 3=developer only) // Non-release versions (RELEASE_VERSION undefined) usually have // a debug level of 2 or 3 (defined in target or product options). // signal that we are compiling with the SYSYNC engine #define SYSYNC_ENGINE 1 // Expiry date for products (those that have use EXPIRES_AFTER_DATE at all) #if defined(EXPIRY_YEAR) && defined(SYSER_REGISTRATION) #error "it seems that this target still defines it's own private expiry date - please update target_options.h" #endif #if defined(EXPIRY_YEAR) && EXPIRY_YEAR<2014 #warning "Target has a dangerously early expiry year - please check if it is correct" #endif // global expiry date (usually applies for unregistered demos or regular products in trial mode) #ifndef EXPIRY_YEAR #define EXPIRY_DATE_STRING "2016-03-31" #define EXPIRY_YEAR 2016 #define EXPIRY_MONTH 3 #define EXPIRY_DAY 31 #endif // Release date (date relevant for licenses that are valid only up to a certain release date) #if !defined(RELEASE_YEAR) || !defined(RELEASE_MONTH) // define one globally in case target or product does not specify it's own date #define RELEASE_YEAR 2010 #define RELEASE_YEAR_TXT "2010" #define RELEASE_MONTH 1 #define RELEASE_MONTH_TXT "1" #endif // Real Release date (shown in some texts) #if !defined(REAL_RELEASE_YEAR) #define REAL_RELEASE_YEAR 2012 #define REAL_RELEASE_YEAR_TXT "2012" #endif // For old targets that do not have product_options.h yet // - Set common Version information #ifndef SYSYNC_VERSION_MAJOR #define SYSYNC_VERSION_MAJOR 3 #define SYSYNC_VERSION_MAJOR_TXT "3" #endif #ifndef SYSYNC_VERSION_MINOR #define SYSYNC_VERSION_MINOR 4 #define SYSYNC_VERSION_MINOR_TXT "4" #endif #ifndef SYSYNC_SUBVERSION #define SYSYNC_SUBVERSION 0 #define SYSYNC_SUBVERSION_TXT "0" #endif #ifndef SYSYNC_BUILDNUMBER #define SYSYNC_BUILDNUMBER 47 #define SYSYNC_BUILDNUMBER_TXT "47" #endif // Platform name #ifndef SYSYNC_PLATFORM_NAME #if defined(__EPOC_OS__) #define SYSYNC_PLATFORM_NAME "SymbianOS" #elif defined(MOBOSX) #define SYSYNC_PLATFORM_NAME "iOS" #elif defined(MACOSX) #define SYSYNC_PLATFORM_NAME "MacOSX" #elif defined(ANDROID) #define SYSYNC_PLATFORM_NAME "Android" #elif defined(LINUX) #define SYSYNC_PLATFORM_NAME "Linux" #elif defined(__PALM_OS__) #define SYSYNC_PLATFORM_NAME "PalmOS" #elif defined(WINCE) #define SYSYNC_PLATFORM_NAME "WinCE" #elif defined(_WIN32) #define SYSYNC_PLATFORM_NAME "Win32" #endif #endif // product version string #define SYSYNC_VERSION_STRING SYSYNC_VERSION_MAJOR_TXT "." SYSYNC_VERSION_MINOR_TXT "." SYSYNC_SUBVERSION_TXT // full version string #define SYSYNC_FULL_VERSION_STRING SYSYNC_VERSION_MAJOR_TXT "." SYSYNC_VERSION_MINOR_TXT "." SYSYNC_SUBVERSION_TXT "." SYSYNC_BUILDNUMBER_TXT // full version string #define SYSYNC_MAIN_VERSION_STRING SYSYNC_VERSION_MAJOR_TXT "." SYSYNC_VERSION_MINOR_TXT // uInt32 format of version (8 bits per dotted group) #define SYSYNC_VERSION_UINT32 (((uInt32)SYSYNC_VERSION_MAJOR<<24)+((uInt32)SYSYNC_VERSION_MINOR<<16)+((uInt32)SYSYNC_SUBVERSION<<8)+(uInt32)SYSYNC_BUILDNUMBER) // client and server strings for XPT-based apps #define SERVER_NAME "Synthesis SyncML Server/" SYSYNC_FULL_VERSION_STRING #define CLIENT_NAME "Synthesis SyncML Client/" SYSYNC_FULL_VERSION_STRING " [en] (" SYSYNC_PLATFORM_NAME "; I)" // FPI product identifier #define SYSYNC_FPI "-//Synthesis AG//NONSGML SyncML Engine V" SYSYNC_FULL_VERSION_STRING "//EN" // Global feature switches (might be overridden in individual targets) // ################################################################### // server or client macros // - make sure we have either SYSYNC_CLIENT, SYSYNC_SERVER or both // - if combined build, define SERVER_CLIENT_BUILD as well #if defined(SYSYNC_CLIENT) && defined(SYSYNC_SERVER) #define SERVER_CLIENT_BUILD 1 #elif !defined(SYSYNC_CLIENT) #define SYSYNC_SERVER 1 #endif // build differentiation macros #ifdef SERVER_CLIENT_BUILD // dynamically switching between server and client #define IS_CLIENT (!getSyncAppBase()->isServer()) #define IS_SERVER (getSyncAppBase()->isServer()) #else // static, built as either server or client #ifdef SYSYNC_CLIENT // client #define IS_CLIENT 1 #define IS_SERVER 0 #else // server #define IS_CLIENT 0 #define IS_SERVER 1 #endif #endif // build type #ifdef ENGINE_LIBRARY // SySync engine with API // - may not have any globals #undef DIRECT_APPBASE_GLOBALACCESS // - has Engine Interface #define ENGINEINTERFACE_SUPPORT 1 // - should support constant XML config #define CONSTANTXML_CONFIG 1 #else // Classic SySync build // - needs direct accessors to syncAppBase and maybe other global vars #define DIRECT_APPBASE_GLOBALACCESS 1 #endif // binfile layer specifics #if defined(BASED_ON_BINFILE_CLIENT) && !defined(SYSYNC_SERVER) // client-only build with binfiles included -> binfile must be always active // (and customimpl does not need a lot of stuff it would otherwise include) #define BINFILE_ALWAYS_ACTIVE 1 #endif // default datatype support #define MIMEDIR_SUPPORT 1 #define TEXTTYPE_SUPPORT 1 #define DATAOBJ_SUPPORT 1 #define RAWTYPE_SUPPORT 1 // intermediate stuff for v3.x development /// @todo /// the following defines are for v3.x development only and must be cleared out or moved to a permanent location for a final version! // default to ODBC support (if and only if SQL_SUPPORT is selected in the target) #define ODBCAPI_SUPPORT 1 // default to both text and AsKey variants of item passing in Api datastores #define DBAPI_TEXTITEMS 1 #define DBAPI_ASKEYITEMS 1 // SyncML version support #define MAX_SYNCML_VERSION syncml_vers_1_2 #ifdef SYSYNC_CLIENT // these are normally client options, servers don't have them by default // client provides GUI suport for CGI server options such as TAF and/or /li(x) /dr(x,y)... #define CGI_SERVER_OPTIONS 1 #undef CHINESE_SUPPORT #else // these are normally server options, clients don't have them by default // include large-footprint conversions between chinese and UTF-8 #define CHINESE_SUPPORT 1 // if defined, TAF option chars will be used like syncset filter /fi(...) // (that's how it always was before 1.0.8.9 server) // Was globally defined 1 until and including server 2.0.5.12 // Starting with 2.0.5.13 server, real TAF is now (partially) available, so we // switch this off #undef TAF_AS_SYNCSETFILTER // real SyncML-like TAF #define SYNCML_TAF_SUPPORT 1 // if defined, we support Synthesis style target options (/opt(args) style) #define SYSYNC_TARGET_OPTIONS 1 // object is enabled by default for now (standard version turns it off) #define OBJECT_FILTERING 1 // array field support is enabled by default for now (standard version turns it off) #define ARRAYFIELD_SUPPORT 1 // array field support is enabled by default for now (standard version turns it off) #define STREAMFIELD_SUPPORT 1 // full support for email in textitem #define EMAIL_FORMAT_SUPPORT 1 #define EMAIL_ATTACHMENT_SUPPORT 1 // script support is enabled by default for now (standard version turns it off) #define SCRIPT_SUPPORT 1 #define REGEX_SUPPORT 1 // superdatastore support is enabled by default #define SUPERDATASTORES 1 #endif // ODBC not compatible with 1.0.5.x type config any more #undef OLD_1_0_5_CONFIG_COMPATIBLE // Settings that have proven globally correct by now // ################################################# // SySync options // ============== // s2g does not need these extras any more, everything is solved with scripts // #define SPACE2GO_EXTRAS 1 // use new space evaluation method #define USE_SML_EVALUATION 1 // do not modify remote IDs in any way while processing them #define DONT_STRIP_PATHPREFIX_FROM_REMOTEIDS 1 // Time options // - if defined, querying current lineartime will return millisecond // accuray value. #define NOW_WITH_MILLISECONDS 1 // activate the new timezone system #define NEW_TIMEZONES 1 // - if defined, code for incoming and outgoing SyncML dumping into (WB)XML logfiles is included #define MSGDUMP 1 // - if defined, code for incoming message simulation from "i_" prefixed incoming message dump file is included #undef SIMMSGREAD // - allow keep connection #define HTTP_KEEP_CONNECTION 1 // SyncML Toolkit options // ====================== // if defined, the entire complicated and thread-unsafe workspace manager // is completely bypassed #define NOWSM 1 /* correct tagging of XML payload with $s =~ s/>/>/g; $s =~ s"\\fI(.*?)\\f[RP]"$1"g; $s =~ s"\\fB(.*?)\\f[RP]"$1"g; $s =~ s"\\e"\\"g; $s =~ s/(?<=Copyright )\(c\)/©/g; $s; } # Subroutine to ensure not in a paragraph sub end_para { if ($inpara) { print TEMP "\n" if ($inpre); print TEMP "

\n"; } $inpara = $inpre = 0; $wrotetext = 0; } # Subroutine to start a new paragraph sub new_para { &end_para(); print TEMP "

\n"; $inpara = 1; } # Main program $innf = 0; $inpara = 0; $inpre = 0; $wrotetext = 0; $toc = 0; $ref = 1; while ($#ARGV >= 0 && $ARGV[0] =~ /^-/) { $toc = 1 if $ARGV[0] eq "-toc"; shift; } # Initial output to STDOUT print < $ARGV[0] specification

$ARGV[0] man page

Return to the PCRE index page.

This page is part of the PCRE HTML documentation. It was generated automatically from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.
End print "

    \n" if ($toc); open(TEMP, ">/tmp/$$") || die "Can't open /tmp/$$ for output\n"; while () { # Handle lines beginning with a dot if (/^\./) { # Some of the PCRE man pages used to contain instances of .br. However, # they should have all been removed because they cause trouble in some # (other) automated systems that translate man pages to HTML. Complain if # we find .br or .in (another macro that is deprecated). if (/^\.br/ || /^\.in/) { print STDERR "\n*** Deprecated macro encountered - rewrite needed\n"; print STDERR "*** $_\n"; die "*** Processing abandoned\n"; } # Instead of .br, relevent "literal" sections are enclosed in .nf/.fi. elsif (/^\.nf/) { $innf = 1; } elsif (/^\.fi/) { $innf = 0; } # Handling .sp is subtle. If it is inside a literal section, do nothing if # the next line is a non literal text line; similarly, if not inside a # literal section, do nothing if a literal follows. The point being that # the
     and 
    that delimit literal sections will do the spacing. # Always skip if no previous output. elsif (/^\.sp/) { if ($wrotetext) { $_ = ; if ($inpre) { print TEMP "\n" if (/^[\s.]/); } else { print TEMP "
    \n
    \n" if (!/^[\s.]/); } redo; # Now process the lookahead line we just read } } elsif (/^\.TP/ || /^\.PP/ || /^\.P/) { &new_para(); } elsif (/^\.SH\s*("?)(.*)\1/) { # Ignore the NAME section if ($2 =~ /^NAME\b/) { ; next; } &end_para(); my($title) = &do_line($2); if ($toc) { printf("
  • $title\n", $ref, $ref); printf TEMP ("
    $title
    \n", $ref, $ref); $ref++; } else { print TEMP "
    \n$title\n
    \n"; } } elsif (/^\.SS\s*("?)(.*)\1/) { &end_para(); my($title) = &do_line($2); print TEMP "
    \n$title\n
    \n"; } elsif (/^\.B\s*(.*)/) { &new_para() if (!$inpara); $_ = &do_line($1); s/"(.*?)"/$1/g; print TEMP "$_\n"; $wrotetext = 1; } elsif (/^\.I\s*(.*)/) { &new_para() if (!$inpara); $_ = &do_line($1); s/"(.*?)"/$1/g; print TEMP "$_\n"; $wrotetext = 1; } # A comment that starts "HREF" takes the next line as a name that # is turned into a hyperlink, using the text given, which might be # in a special font. If it ends in () or (digits) or punctuation, they # aren't part of the link. elsif (/^\.\\"\s*HREF/) { $_=; chomp; $_ = &do_line($_); $_ =~ s/\s+$//; $_ =~ /^(?:<.>)?([^<(]+)(?:\(\))?(?:<\/.>)?(?:\(\d+\))?[.,;:]?$/; print TEMP "$_\n"; } # A comment that starts "HTML" inserts literal HTML elsif (/^\.\\"\s*HTML\s*(.*)/) { print TEMP $1; } # A comment that starts < inserts that HTML at the end of the # *next* input line - so as not to get a newline between them. elsif (/^\.\\"\s*(<.*>)/) { my($markup) = $1; $_=; chomp; $_ = &do_line($_); $_ =~ s/\s+$//; print TEMP "$_$markup\n"; } # A comment that starts JOIN joins the next two lines together, with one # space between them. Then that line is processed. This is used in some # displays where two lines are needed for the "man" version. JOINSH works # the same, except that it assumes this is a shell command, so removes # continuation backslashes. elsif (/^\.\\"\s*JOIN(SH)?/) { my($one,$two); $one = ; $two = ; $one =~ s/\s*\\e\s*$// if (defined($1)); chomp($one); $two =~ s/^\s+//; $_ = "$one $two"; redo; # Process the joined lines } # Ignore anything not recognized next; } # Line does not begin with a dot. Replace blank lines with new paragraphs if (/^\s*$/) { &end_para() if ($wrotetext); next; } # Convert fonts changes and output an ordinary line. Ensure that indented # lines are marked as literal. $_ = &do_line($_); &new_para() if (!$inpara); if (/^\s/) { if (!$inpre) { print TEMP "
    \n";
          $inpre = 1;
          }
        }
      elsif ($inpre)
        {
        print TEMP "
    \n"; $inpre = 0; } # Add
    to the end of a non-literal line if we are within .nf/.fi $_ .= "
    \n" if (!$inpre && $innf); print TEMP; $wrotetext = 1; } # The TOC, if present, will have been written - terminate it print "
\n" if ($toc); # Copy the remainder to the standard output close(TEMP); open(TEMP, "/tmp/$$") || die "Can't open /tmp/$$ for input\n"; print while (); print < Return to the PCRE index page.

End close(TEMP); unlink("/tmp/$$"); # End libsynthesis-3.4.0.47.1/src/pcre/AUTHORS000066400000000000000000000006161226375725500174370ustar00rootroot00000000000000THE MAIN PCRE LIBRARY --------------------- Written by: Philip Hazel Email local part: ph10 Email domain: cam.ac.uk University of Cambridge Computing Service, Cambridge, England. Copyright (c) 1997-2007 University of Cambridge All rights reserved THE C++ WRAPPER LIBRARY ----------------------- Written by: Google Inc. Copyright (c) 2007 Google Inc All rights reserved #### libsynthesis-3.4.0.47.1/src/pcre/CMakeLists.txt000066400000000000000000000213471226375725500211330ustar00rootroot00000000000000# CMakeLists.txt # # This file allows building PCRE with the CMake configuration and build # tool. Download CMake in source or binary form from http://www.cmake.org/ # # Original listfile by Christian Ehrlicher # Refined and expanded by Daniel Richard G. # PROJECT(PCRE C CXX) CMAKE_MINIMUM_REQUIRED(VERSION 2.4.6) # Configuration checks INCLUDE(CheckIncludeFile) INCLUDE(CheckIncludeFileCXX) INCLUDE(CheckFunctionExists) INCLUDE(CheckTypeSize) CHECK_INCLUDE_FILE(dirent.h HAVE_DIRENT_H) CHECK_INCLUDE_FILE(unistd.h HAVE_UNISTD_H) CHECK_INCLUDE_FILE(sys/stat.h HAVE_SYS_STAT_H) CHECK_INCLUDE_FILE(sys/types.h HAVE_SYS_TYPES_H) CHECK_INCLUDE_FILE_CXX(type_traits.h HAVE_TYPE_TRAITS_H) CHECK_INCLUDE_FILE_CXX(bits/type_traits.h HAVE_BITS_TYPE_TRAITS_H) CHECK_FUNCTION_EXISTS(bcopy HAVE_BCOPY) CHECK_FUNCTION_EXISTS(memmove HAVE_MEMMOVE) CHECK_FUNCTION_EXISTS(strerror HAVE_STRERROR) CHECK_TYPE_SIZE("long long" LONG_LONG) CHECK_TYPE_SIZE("unsigned long long" UNSIGNED_LONG_LONG) # User-configurable options # # (Note: CMakeSetup displays these in alphabetical order, regardless of # the order we use here) SET(BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared libraries instead of static ones.") OPTION(PCRE_BUILD_PCRECPP "Build the PCRE C++ library (pcrecpp)." ON) SET(PCRE_EBCDIC OFF CACHE BOOL "Use EBCDIC coding instead of ASCII. (This is rarely used outside of mainframe systems)") SET(PCRE_LINK_SIZE "2" CACHE STRING "Internal link size (2, 3 or 4 allowed). See LINK_SIZE in config.h.in for details.") SET(PCRE_MATCH_LIMIT "10000000" CACHE STRING "Default limit on internal looping. See MATCH_LIMIT in config.h.in for details.") SET(PCRE_MATCH_LIMIT_RECURSION "MATCH_LIMIT" CACHE STRING "Default limit on internal recursion. See MATCH_LIMIT_RECURSION in config.h.in for details.") SET(PCRE_NEWLINE "LF" CACHE STRING "What to recognize as a newline (one of CR, LF, CRLF, ANY).") SET(PCRE_NO_RECURSE OFF CACHE BOOL "If ON, then don't use stack recursion when matching. See NO_RECURSE in config.h.in for details.") SET(PCRE_POSIX_MALLOC_THRESHOLD "10" CACHE STRING "Threshold for malloc() usage. See POSIX_MALLOC_THRESHOLD in config.h.in for details.") SET(PCRE_SUPPORT_UNICODE_PROPERTIES OFF CACHE BOOL "Enable support for Unicode properties. (If set, UTF-8 support will be enabled as well)") SET(PCRE_SUPPORT_UTF8 OFF CACHE BOOL "Enable support for the Unicode UTF-8 encoding.") # Prepare build configuration SET(pcre_have_type_traits 0) SET(pcre_have_bits_type_traits 0) IF(HAVE_TYPE_TRAITS_H) SET(pcre_have_type_traits 1) ENDIF(HAVE_TYPE_TRAITS_H) IF(HAVE_BITS_TYPE_TRAITS_H) SET(pcre_have_bits_type_traits 1) ENDIF(HAVE_BITS_TYPE_TRAITS_H) SET(pcre_have_long_long 0) SET(pcre_have_ulong_long 0) IF(HAVE_LONG_LONG) SET(pcre_have_long_long 1) ENDIF(HAVE_LONG_LONG) IF(HAVE_UNSIGNED_LONG_LONG) SET(pcre_have_ulong_long 1) ENDIF(HAVE_UNSIGNED_LONG_LONG) IF(NOT BUILD_SHARED_LIBS) SET(PCRE_STATIC 1) ENDIF(NOT BUILD_SHARED_LIBS) IF(PCRE_SUPPORT_UTF8 OR PCRE_SUPPORT_UNICODE_PROPERTIES) SET(SUPPORT_UTF8 1) ENDIF(PCRE_SUPPORT_UTF8 OR PCRE_SUPPORT_UNICODE_PROPERTIES) IF(PCRE_SUPPORT_UNICODE_PROPERTIES) SET(SUPPORT_UCP 1) ENDIF(PCRE_SUPPORT_UNICODE_PROPERTIES) SET(NEWLINE "") IF(PCRE_NEWLINE STREQUAL "LF") SET(NEWLINE "10") ENDIF(PCRE_NEWLINE STREQUAL "LF") IF(PCRE_NEWLINE STREQUAL "CR") SET(NEWLINE "13") ENDIF(PCRE_NEWLINE STREQUAL "CR") IF(PCRE_NEWLINE STREQUAL "CRLF") SET(NEWLINE "3338") ENDIF(PCRE_NEWLINE STREQUAL "CRLF") IF(PCRE_NEWLINE STREQUAL "ANY") SET(NEWLINE "-1") ENDIF(PCRE_NEWLINE STREQUAL "ANY") IF(NEWLINE STREQUAL "") MESSAGE(FATAL_ERROR "The PCRE_NEWLINE variable must be set to one of the following values: \"LF\", \"CR\", \"CRLF\", \"ANY\".") ENDIF(NEWLINE STREQUAL "") IF(PCRE_EBCDIC) SET(EBCDIC 1) ENDIF(PCRE_EBCDIC) IF(PCRE_NO_RECURSE) SET(NO_RECURSE 1) ENDIF(PCRE_NO_RECURSE) # Output files CONFIGURE_FILE(config-cmake.h.in ${CMAKE_BINARY_DIR}/config.h @ONLY) CONFIGURE_FILE(pcre.h.generic ${CMAKE_BINARY_DIR}/pcre.h COPYONLY) # What about pcre-config and libpcre.pc? IF(PCRE_BUILD_PCRECPP) CONFIGURE_FILE(pcre_stringpiece.h.in ${CMAKE_BINARY_DIR}/pcre_stringpiece.h @ONLY) CONFIGURE_FILE(pcrecpparg.h.in ${CMAKE_BINARY_DIR}/pcrecpparg.h @ONLY) ENDIF(PCRE_BUILD_PCRECPP) # Character table generation ADD_EXECUTABLE(dftables dftables.c) GET_TARGET_PROPERTY(DFTABLES_EXE dftables LOCATION) ADD_CUSTOM_COMMAND( COMMENT "Generating character tables (pcre_chartables.c) for current locale" DEPENDS dftables COMMAND ${DFTABLES_EXE} ARGS ${CMAKE_BINARY_DIR}/pcre_chartables.c OUTPUT ${CMAKE_BINARY_DIR}/pcre_chartables.c ) # Source code SET(PCRE_HEADERS ${CMAKE_BINARY_DIR}/pcre.h) SET(PCRE_SOURCES ${CMAKE_BINARY_DIR}/pcre_chartables.c pcre_compile.c pcre_config.c pcre_dfa_exec.c pcre_exec.c pcre_fullinfo.c pcre_get.c pcre_globals.c pcre_info.c pcre_newline.c pcre_maketables.c pcre_ord2utf8.c pcre_refcount.c pcre_study.c pcre_tables.c pcre_try_flipped.c pcre_ucp_searchfuncs.c pcre_valid_utf8.c pcre_version.c pcre_xclass.c ) SET(PCREPOSIX_HEADERS pcreposix.h) SET(PCREPOSIX_SOURCES pcreposix.c) SET(PCRECPP_HEADERS pcrecpp.h pcre_scanner.h ${CMAKE_BINARY_DIR}/pcrecpparg.h ${CMAKE_BINARY_DIR}/pcre_stringpiece.h ) SET(PCRECPP_SOURCES pcrecpp.cc pcre_scanner.cc pcre_stringpiece.cc ) # Build setup ADD_DEFINITIONS(-DHAVE_CONFIG_H) IF(WIN32) ADD_DEFINITIONS(-D_CRT_SECURE_NO_DEPRECATE) ENDIF(WIN32) SET(CMAKE_INCLUDE_CURRENT_DIR 1) #SET(CMAKE_DEBUG_POSTFIX "d") # Libraries ADD_LIBRARY(pcre ${PCRE_HEADERS} ${PCRE_SOURCES}) ADD_LIBRARY(pcreposix ${PCREPOSIX_HEADERS} ${PCREPOSIX_SOURCES}) TARGET_LINK_LIBRARIES(pcreposix pcre) IF(PCRE_BUILD_PCRECPP) ADD_LIBRARY(pcrecpp ${PCRECPP_HEADERS} ${PCRECPP_SOURCES}) TARGET_LINK_LIBRARIES(pcrecpp pcre) IF(MINGW) SET_TARGET_PROPERTIES(pcrecpp PROPERTIES PREFIX "mingw-") ENDIF(MINGW) ENDIF(PCRE_BUILD_PCRECPP) # Executables ADD_EXECUTABLE(pcretest pcretest.c) TARGET_LINK_LIBRARIES(pcretest pcreposix) ADD_EXECUTABLE(pcregrep pcregrep.c) TARGET_LINK_LIBRARIES(pcregrep pcreposix) IF(PCRE_BUILD_PCRECPP) ADD_EXECUTABLE(pcrecpp_unittest pcrecpp_unittest.cc) TARGET_LINK_LIBRARIES(pcrecpp_unittest pcrecpp) ADD_EXECUTABLE(pcre_scanner_unittest pcre_scanner_unittest.cc) TARGET_LINK_LIBRARIES(pcre_scanner_unittest pcrecpp) ADD_EXECUTABLE(pcre_stringpiece_unittest pcre_stringpiece_unittest.cc) TARGET_LINK_LIBRARIES(pcre_stringpiece_unittest pcrecpp) ENDIF(PCRE_BUILD_PCRECPP) # Testing ENABLE_TESTING() GET_TARGET_PROPERTY(PCREGREP_EXE pcregrep DEBUG_LOCATION) GET_TARGET_PROPERTY(PCRETEST_EXE pcretest DEBUG_LOCATION) # Write out a CTest configuration file that sets some needed environment # variables for the test scripts. # FILE(WRITE ${CMAKE_BINARY_DIR}/CTestCustom.ctest "# This is a generated file. SET(ENV{srcdir} ${CMAKE_SOURCE_DIR}) SET(ENV{pcregrep} ${PCREGREP_EXE}) SET(ENV{pcretest} ${PCRETEST_EXE}) ") IF(UNIX) ADD_TEST(pcre_test ${CMAKE_SOURCE_DIR}/RunTest) ADD_TEST(pcre_grep_test ${CMAKE_SOURCE_DIR}/RunGrepTest) ENDIF(UNIX) IF(WIN32) ADD_TEST(pcre_test cmd /C ${CMAKE_SOURCE_DIR}/RunTest.bat) ENDIF(WIN32) GET_TARGET_PROPERTY(PCRECPP_UNITTEST_EXE pcrecpp_unittest DEBUG_LOCATION) GET_TARGET_PROPERTY(PCRE_SCANNER_UNITTEST_EXE pcre_scanner_unittest DEBUG_LOCATION) GET_TARGET_PROPERTY(PCRE_STRINGPIECE_UNITTEST_EXE pcre_stringpiece_unittest DEBUG_LOCATION) ADD_TEST(pcrecpp_test ${PCRECPP_UNITTEST_EXE}) ADD_TEST(pcre_scanner_test ${PCRE_SCANNER_UNITTEST_EXE}) ADD_TEST(pcre_stringpiece_test ${PCRE_STRINGPIECE_UNITTEST_EXE}) # Installation SET(CMAKE_INSTALL_ALWAYS 1) INSTALL(TARGETS pcre pcreposix pcregrep pcretest RUNTIME DESTINATION bin LIBRARY DESTINATION lib ARCHIVE DESTINATION lib) INSTALL(FILES ${PCRE_HEADERS} ${PCREPOSIX_HEADERS} DESTINATION include) FILE(GLOB html ${CMAKE_SOURCE_DIR}/doc/html/*.html) FILE(GLOB man1 ${CMAKE_SOURCE_DIR}/doc/*.1) FILE(GLOB man3 ${CMAKE_SOURCE_DIR}/doc/*.3) IF(PCRE_BUILD_PCRECPP) INSTALL(TARGETS pcrecpp RUNTIME DESTINATION bin LIBRARY DESTINATION lib ARCHIVE DESTINATION lib) INSTALL(FILES ${PCRECPP_HEADERS} DESTINATION include) ELSE(PCRE_BUILD_PCRECPP) # Remove pcrecpp.3 FOREACH(man ${man3}) GET_FILENAME_COMPONENT(man_tmp ${man} NAME) IF(NOT man_tmp STREQUAL "pcrecpp.3") SET(man3_new ${man3} ${man}) ENDIF(NOT man_tmp STREQUAL "pcrecpp.3") ENDFOREACH(man ${man3}) SET(man3 ${man3_new}) ENDIF(PCRE_BUILD_PCRECPP) INSTALL(FILES ${man1} DESTINATION man/man1) INSTALL(FILES ${man3} DESTINATION man/man3) INSTALL(FILES ${html} DESTINATION share/doc/pcre/html) # end CMakeLists.txt libsynthesis-3.4.0.47.1/src/pcre/COPYING000066400000000000000000000001371226375725500174200ustar00rootroot00000000000000PCRE LICENCE Please see the file LICENCE in the PCRE distribution for licensing details. End libsynthesis-3.4.0.47.1/src/pcre/ChangeLog000066400000000000000000004164771226375725500201610ustar00rootroot00000000000000ChangeLog for PCRE ------------------ Version 7.3 28-Aug-07 --------------------- 1. In the rejigging of the build system that eventually resulted in 7.1, the line "#include " was included in pcre_internal.h. The use of angle brackets there is not right, since it causes compilers to look for an installed pcre.h, not the version that is in the source that is being compiled (which of course may be different). I have changed it back to: #include "pcre.h" I have a vague recollection that the change was concerned with compiling in different directories, but in the new build system, that is taken care of by the VPATH setting the Makefile. 2. The pattern .*$ when run in not-DOTALL UTF-8 mode with newline=any failed when the subject happened to end in the byte 0x85 (e.g. if the last character was \x{1ec5}). *Character* 0x85 is one of the "any" newline characters but of course it shouldn't be taken as a newline when it is part of another character. The bug was that, for an unlimited repeat of . in not-DOTALL UTF-8 mode, PCRE was advancing by bytes rather than by characters when looking for a newline. 3. A small performance improvement in the DOTALL UTF-8 mode .* case. 4. Debugging: adjusted the names of opcodes for different kinds of parentheses in debug output. 5. Arrange to use "%I64d" instead of "%lld" and "%I64u" instead of "%llu" for long printing in the pcrecpp unittest when running under MinGW. 6. ESC_K was left out of the EBCDIC table. 7. Change 7.0/38 introduced a new limit on the number of nested non-capturing parentheses; I made it 1000, which seemed large enough. Unfortunately, the limit also applies to "virtual nesting" when a pattern is recursive, and in this case 1000 isn't so big. I have been able to remove this limit at the expense of backing off one optimization in certain circumstances. Normally, when pcre_exec() would call its internal match() function recursively and immediately return the result unconditionally, it uses a "tail recursion" feature to save stack. However, when a subpattern that can match an empty string has an unlimited repetition quantifier, it no longer makes this optimization. That gives it a stack frame in which to save the data for checking that an empty string has been matched. Previously this was taken from the 1000-entry workspace that had been reserved. So now there is no explicit limit, but more stack is used. 8. Applied Daniel's patches to solve problems with the import/export magic syntax that is required for Windows, and which was going wrong for the pcreposix and pcrecpp parts of the library. These were overlooked when this problem was solved for the main library. 9. There were some crude static tests to avoid integer overflow when computing the size of patterns that contain repeated groups with explicit upper limits. As the maximum quantifier is 65535, the maximum group length was set at 30,000 so that the product of these two numbers did not overflow a 32-bit integer. However, it turns out that people want to use groups that are longer than 30,000 bytes (though not repeat them that many times). Change 7.0/17 (the refactoring of the way the pattern size is computed) has made it possible to implement the integer overflow checks in a much more dynamic way, which I have now done. The artificial limitation on group length has been removed - we now have only the limit on the total length of the compiled pattern, which depends on the LINK_SIZE setting. 10. Fixed a bug in the documentation for get/copy named substring when duplicate names are permitted. If none of the named substrings are set, the functions return PCRE_ERROR_NOSUBSTRING (7); the doc said they returned an empty string. 11. Because Perl interprets \Q...\E at a high level, and ignores orphan \E instances, patterns such as [\Q\E] or [\E] or even [^\E] cause an error, because the ] is interpreted as the first data character and the terminating ] is not found. PCRE has been made compatible with Perl in this regard. Previously, it interpreted [\Q\E] as an empty class, and [\E] could cause memory overwriting. 10. Like Perl, PCRE automatically breaks an unlimited repeat after an empty string has been matched (to stop an infinite loop). It was not recognizing a conditional subpattern that could match an empty string if that subpattern was within another subpattern. For example, it looped when trying to match (((?(1)X|))*) but it was OK with ((?(1)X|)*) where the condition was not nested. This bug has been fixed. 12. A pattern like \X?\d or \P{L}?\d in non-UTF-8 mode could cause a backtrack past the start of the subject in the presence of bytes with the top bit set, for example "\x8aBCD". 13. Added Perl 5.10 experimental backtracking controls (*FAIL), (*F), (*PRUNE), (*SKIP), (*THEN), (*COMMIT), and (*ACCEPT). 14. Optimized (?!) to (*FAIL). 15. Updated the test for a valid UTF-8 string to conform to the later RFC 3629. This restricts code points to be within the range 0 to 0x10FFFF, excluding the "low surrogate" sequence 0xD800 to 0xDFFF. Previously, PCRE allowed the full range 0 to 0x7FFFFFFF, as defined by RFC 2279. Internally, it still does: it's just the validity check that is more restrictive. 16. Inserted checks for integer overflows during escape sequence (backslash) processing, and also fixed erroneous offset values for syntax errors during backslash processing. 17. Fixed another case of looking too far back in non-UTF-8 mode (cf 12 above) for patterns like [\PPP\x8a]{1,}\x80 with the subject "A\x80". 18. An unterminated class in a pattern like (?1)\c[ with a "forward reference" caused an overrun. 19. A pattern like (?:[\PPa*]*){8,} which had an "extended class" (one with something other than just ASCII characters) inside a group that had an unlimited repeat caused a loop at compile time (while checking to see whether the group could match an empty string). 20. Debugging a pattern containing \p or \P could cause a crash. For example, [\P{Any}] did so. (Error in the code for printing property names.) 21. An orphan \E inside a character class could cause a crash. 22. A repeated capturing bracket such as (A)? could cause a wild memory reference during compilation. 23. There are several functions in pcre_compile() that scan along a compiled expression for various reasons (e.g. to see if it's fixed length for look behind). There were bugs in these functions when a repeated \p or \P was present in the pattern. These operators have additional parameters compared with \d, etc, and these were not being taken into account when moving along the compiled data. Specifically: (a) A item such as \p{Yi}{3} in a lookbehind was not treated as fixed length. (b) An item such as \pL+ within a repeated group could cause crashes or loops. (c) A pattern such as \p{Yi}+(\P{Yi}+)(?1) could give an incorrect "reference to non-existent subpattern" error. (d) A pattern like (\P{Yi}{2}\277)? could loop at compile time. 24. A repeated \S or \W in UTF-8 mode could give wrong answers when multibyte characters were involved (for example /\S{2}/8g with "A\x{a3}BC"). 25. Using pcregrep in multiline, inverted mode (-Mv) caused it to loop. 26. Patterns such as [\P{Yi}A] which include \p or \P and just one other character were causing crashes (broken optimization). 27. Patterns such as (\P{Yi}*\277)* (group with possible zero repeat containing \p or \P) caused a compile-time loop. 28. More problems have arisen in unanchored patterns when CRLF is a valid line break. For example, the unstudied pattern [\r\n]A does not match the string "\r\nA" because change 7.0/46 below moves the current point on by two characters after failing to match at the start. However, the pattern \nA *does* match, because it doesn't start till \n, and if [\r\n]A is studied, the same is true. There doesn't seem any very clean way out of this, but what I have chosen to do makes the common cases work: PCRE now takes note of whether there can be an explicit match for \r or \n anywhere in the pattern, and if so, 7.0/46 no longer applies. As part of this change, there's a new PCRE_INFO_HASCRORLF option for finding out whether a compiled pattern has explicit CR or LF references. 29. Added (*CR) etc for changing newline setting at start of pattern. Version 7.2 19-Jun-07 --------------------- 1. If the fr_FR locale cannot be found for test 3, try the "french" locale, which is apparently normally available under Windows. 2. Re-jig the pcregrep tests with different newline settings in an attempt to make them independent of the local environment's newline setting. 3. Add code to configure.ac to remove -g from the CFLAGS default settings. 4. Some of the "internals" tests were previously cut out when the link size was not 2, because the output contained actual offsets. The recent new "Z" feature of pcretest means that these can be cut out, making the tests usable with all link sizes. 5. Implemented Stan Switzer's goto replacement for longjmp() when not using stack recursion. This gives a massive performance boost under BSD, but just a small improvement under Linux. However, it saves one field in the frame in all cases. 6. Added more features from the forthcoming Perl 5.10: (a) (?-n) (where n is a string of digits) is a relative subroutine or recursion call. It refers to the nth most recently opened parentheses. (b) (?+n) is also a relative subroutine call; it refers to the nth next to be opened parentheses. (c) Conditions that refer to capturing parentheses can be specified relatively, for example, (?(-2)... or (?(+3)... (d) \K resets the start of the current match so that everything before is not part of it. (e) \k{name} is synonymous with \k and \k'name' (.NET compatible). (f) \g{name} is another synonym - part of Perl 5.10's unification of reference syntax. (g) (?| introduces a group in which the numbering of parentheses in each alternative starts with the same number. (h) \h, \H, \v, and \V match horizontal and vertical whitespace. 7. Added two new calls to pcre_fullinfo(): PCRE_INFO_OKPARTIAL and PCRE_INFO_JCHANGED. 8. A pattern such as (.*(.)?)* caused pcre_exec() to fail by either not terminating or by crashing. Diagnosed by Viktor Griph; it was in the code for detecting groups that can match an empty string. 9. A pattern with a very large number of alternatives (more than several hundred) was running out of internal workspace during the pre-compile phase, where pcre_compile() figures out how much memory will be needed. A bit of new cunning has reduced the workspace needed for groups with alternatives. The 1000-alternative test pattern now uses 12 bytes of workspace instead of running out of the 4096 that are available. 10. Inserted some missing (unsigned int) casts to get rid of compiler warnings. 11. Applied patch from Google to remove an optimization that didn't quite work. The report of the bug said: pcrecpp::RE("a*").FullMatch("aaa") matches, while pcrecpp::RE("a*?").FullMatch("aaa") does not, and pcrecpp::RE("a*?\\z").FullMatch("aaa") does again. 12. If \p or \P was used in non-UTF-8 mode on a character greater than 127 it matched the wrong number of bytes. Version 7.1 24-Apr-07 --------------------- 1. Applied Bob Rossi and Daniel G's patches to convert the build system to one that is more "standard", making use of automake and other Autotools. There is some re-arrangement of the files and adjustment of comments consequent on this. 2. Part of the patch fixed a problem with the pcregrep tests. The test of -r for recursive directory scanning broke on some systems because the files are not scanned in any specific order and on different systems the order was different. A call to "sort" has been inserted into RunGrepTest for the approprate test as a short-term fix. In the longer term there may be an alternative. 3. I had an email from Eric Raymond about problems translating some of PCRE's man pages to HTML (despite the fact that I distribute HTML pages, some people do their own conversions for various reasons). The problems concerned the use of low-level troff macros .br and .in. I have therefore removed all such uses from the man pages (some were redundant, some could be replaced by .nf/.fi pairs). The 132html script that I use to generate HTML has been updated to handle .nf/.fi and to complain if it encounters .br or .in. 4. Updated comments in configure.ac that get placed in config.h.in and also arranged for config.h to be included in the distribution, with the name config.h.generic, for the benefit of those who have to compile without Autotools (compare pcre.h, which is now distributed as pcre.h.generic). 5. Updated the support (such as it is) for Virtual Pascal, thanks to Stefan Weber: (1) pcre_internal.h was missing some function renames; (2) updated makevp.bat for the current PCRE, using the additional files makevp_c.txt, makevp_l.txt, and pcregexp.pas. 6. A Windows user reported a minor discrepancy with test 2, which turned out to be caused by a trailing space on an input line that had got lost in his copy. The trailing space was an accident, so I've just removed it. 7. Add -Wl,-R... flags in pcre-config.in for *BSD* systems, as I'm told that is needed. 8. Mark ucp_table (in ucptable.h) and ucp_gentype (in pcre_ucp_searchfuncs.c) as "const" (a) because they are and (b) because it helps the PHP maintainers who have recently made a script to detect big data structures in the php code that should be moved to the .rodata section. I remembered to update Builducptable as well, so it won't revert if ucptable.h is ever re-created. 9. Added some extra #ifdef SUPPORT_UTF8 conditionals into pcretest.c, pcre_printint.src, pcre_compile.c, pcre_study.c, and pcre_tables.c, in order to be able to cut out the UTF-8 tables in the latter when UTF-8 support is not required. This saves 1.5-2K of code, which is important in some applications. Later: more #ifdefs are needed in pcre_ord2utf8.c and pcre_valid_utf8.c so as not to refer to the tables, even though these functions will never be called when UTF-8 support is disabled. Otherwise there are problems with a shared library. 10. Fixed two bugs in the emulated memmove() function in pcre_internal.h: (a) It was defining its arguments as char * instead of void *. (b) It was assuming that all moves were upwards in memory; this was true a long time ago when I wrote it, but is no longer the case. The emulated memove() is provided for those environments that have neither memmove() nor bcopy(). I didn't think anyone used it these days, but that is clearly not the case, as these two bugs were recently reported. 11. The script PrepareRelease is now distributed: it calls 132html, CleanTxt, and Detrail to create the HTML documentation, the .txt form of the man pages, and it removes trailing spaces from listed files. It also creates pcre.h.generic and config.h.generic from pcre.h and config.h. In the latter case, it wraps all the #defines with #ifndefs. This script should be run before "make dist". 12. Fixed two fairly obscure bugs concerned with quantified caseless matching with Unicode property support. (a) For a maximizing quantifier, if the two different cases of the character were of different lengths in their UTF-8 codings (there are some cases like this - I found 11), and the matching function had to back up over a mixture of the two cases, it incorrectly assumed they were both the same length. (b) When PCRE was configured to use the heap rather than the stack for recursion during matching, it was not correctly preserving the data for the other case of a UTF-8 character when checking ahead for a match while processing a minimizing repeat. If the check also involved matching a wide character, but failed, corruption could cause an erroneous result when trying to check for a repeat of the original character. 13. Some tidying changes to the testing mechanism: (a) The RunTest script now detects the internal link size and whether there is UTF-8 and UCP support by running ./pcretest -C instead of relying on values substituted by "configure". (The RunGrepTest script already did this for UTF-8.) The configure.ac script no longer substitutes the relevant variables. (b) The debugging options /B and /D in pcretest show the compiled bytecode with length and offset values. This means that the output is different for different internal link sizes. Test 2 is skipped for link sizes other than 2 because of this, bypassing the problem. Unfortunately, there was also a test in test 3 (the locale tests) that used /B and failed for link sizes other than 2. Rather than cut the whole test out, I have added a new /Z option to pcretest that replaces the length and offset values with spaces. This is now used to make test 3 independent of link size. (Test 2 will be tidied up later.) 14. If erroroffset was passed as NULL to pcre_compile, it provoked a segmentation fault instead of returning the appropriate error message. 15. In multiline mode when the newline sequence was set to "any", the pattern ^$ would give a match between the \r and \n of a subject such as "A\r\nB". This doesn't seem right; it now treats the CRLF combination as the line ending, and so does not match in that case. It's only a pattern such as ^$ that would hit this one: something like ^ABC$ would have failed after \r and then tried again after \r\n. 16. Changed the comparison command for RunGrepTest from "diff -u" to "diff -ub" in an attempt to make files that differ only in their line terminators compare equal. This works on Linux. 17. Under certain error circumstances pcregrep might try to free random memory as it exited. This is now fixed, thanks to valgrind. 19. In pcretest, if the pattern /(?m)^$/g was matched against the string "abc\r\n\r\n", it found an unwanted second match after the second \r. This was because its rules for how to advance for /g after matching an empty string at the end of a line did not allow for this case. They now check for it specially. 20. pcretest is supposed to handle patterns and data of any length, by extending its buffers when necessary. It was getting this wrong when the buffer for a data line had to be extended. 21. Added PCRE_NEWLINE_ANYCRLF which is like ANY, but matches only CR, LF, or CRLF as a newline sequence. 22. Code for handling Unicode properties in pcre_dfa_exec() wasn't being cut out by #ifdef SUPPORT_UCP. This did no harm, as it could never be used, but I have nevertheless tidied it up. 23. Added some casts to kill warnings from HP-UX ia64 compiler. 24. Added a man page for pcre-config. Version 7.0 19-Dec-06 --------------------- 1. Fixed a signed/unsigned compiler warning in pcre_compile.c, shown up by moving to gcc 4.1.1. 2. The -S option for pcretest uses setrlimit(); I had omitted to #include sys/time.h, which is documented as needed for this function. It doesn't seem to matter on Linux, but it showed up on some releases of OS X. 3. It seems that there are systems where bytes whose values are greater than 127 match isprint() in the "C" locale. The "C" locale should be the default when a C program starts up. In most systems, only ASCII printing characters match isprint(). This difference caused the output from pcretest to vary, making some of the tests fail. I have changed pcretest so that: (a) When it is outputting text in the compiled version of a pattern, bytes other than 32-126 are always shown as hex escapes. (b) When it is outputting text that is a matched part of a subject string, it does the same, unless a different locale has been set for the match (using the /L modifier). In this case, it uses isprint() to decide. 4. Fixed a major bug that caused incorrect computation of the amount of memory required for a compiled pattern when options that changed within the pattern affected the logic of the preliminary scan that determines the length. The relevant options are -x, and -i in UTF-8 mode. The result was that the computed length was too small. The symptoms of this bug were either the PCRE error "internal error: code overflow" from pcre_compile(), or a glibc crash with a message such as "pcretest: free(): invalid next size (fast)". Examples of patterns that provoked this bug (shown in pcretest format) are: /(?-x: )/x /(?x)(?-x: \s*#\s*)/ /((?i)[\x{c0}])/8 /(?i:[\x{c0}])/8 HOWEVER: Change 17 below makes this fix obsolete as the memory computation is now done differently. 5. Applied patches from Google to: (a) add a QuoteMeta function to the C++ wrapper classes; (b) implement a new function in the C++ scanner that is more efficient than the old way of doing things because it avoids levels of recursion in the regex matching; (c) add a paragraph to the documentation for the FullMatch() function. 6. The escape sequence \n was being treated as whatever was defined as "newline". Not only was this contrary to the documentation, which states that \n is character 10 (hex 0A), but it also went horribly wrong when "newline" was defined as CRLF. This has been fixed. 7. In pcre_dfa_exec.c the value of an unsigned integer (the variable called c) was being set to -1 for the "end of line" case (supposedly a value that no character can have). Though this value is never used (the check for end of line is "zero bytes in current character"), it caused compiler complaints. I've changed it to 0xffffffff. 8. In pcre_version.c, the version string was being built by a sequence of C macros that, in the event of PCRE_PRERELEASE being defined as an empty string (as it is for production releases) called a macro with an empty argument. The C standard says the result of this is undefined. The gcc compiler treats it as an empty string (which was what was wanted) but it is reported that Visual C gives an error. The source has been hacked around to avoid this problem. 9. On the advice of a Windows user, included and in Windows builds of pcretest, and changed the call to _setmode() to use _O_BINARY instead of 0x8000. Made all the #ifdefs test both _WIN32 and WIN32 (not all of them did). 10. Originally, pcretest opened its input and output without "b"; then I was told that "b" was needed in some environments, so it was added for release 5.0 to both the input and output. (It makes no difference on Unix-like systems.) Later I was told that it is wrong for the input on Windows. I've now abstracted the modes into two macros, to make it easier to fiddle with them, and removed "b" from the input mode under Windows. 11. Added pkgconfig support for the C++ wrapper library, libpcrecpp. 12. Added -help and --help to pcretest as an official way of being reminded of the options. 13. Removed some redundant semicolons after macro calls in pcrecpparg.h.in and pcrecpp.cc because they annoy compilers at high warning levels. 14. A bit of tidying/refactoring in pcre_exec.c in the main bumpalong loop. 15. Fixed an occurrence of == in configure.ac that should have been = (shell scripts are not C programs :-) and which was not noticed because it works on Linux. 16. pcretest is supposed to handle any length of pattern and data line (as one line or as a continued sequence of lines) by extending its input buffer if necessary. This feature was broken for very long pattern lines, leading to a string of junk being passed to pcre_compile() if the pattern was longer than about 50K. 17. I have done a major re-factoring of the way pcre_compile() computes the amount of memory needed for a compiled pattern. Previously, there was code that made a preliminary scan of the pattern in order to do this. That was OK when PCRE was new, but as the facilities have expanded, it has become harder and harder to keep it in step with the real compile phase, and there have been a number of bugs (see for example, 4 above). I have now found a cunning way of running the real compile function in a "fake" mode that enables it to compute how much memory it would need, while actually only ever using a few hundred bytes of working memory and without too many tests of the mode. This should make future maintenance and development easier. A side effect of this work is that the limit of 200 on the nesting depth of parentheses has been removed (though this was never a serious limitation, I suspect). However, there is a downside: pcre_compile() now runs more slowly than before (30% or more, depending on the pattern). I hope this isn't a big issue. There is no effect on runtime performance. 18. Fixed a minor bug in pcretest: if a pattern line was not terminated by a newline (only possible for the last line of a file) and it was a pattern that set a locale (followed by /Lsomething), pcretest crashed. 19. Added additional timing features to pcretest. (1) The -tm option now times matching only, not compiling. (2) Both -t and -tm can be followed, as a separate command line item, by a number that specifies the number of repeats to use when timing. The default is 50000; this gives better precision, but takes uncomfortably long for very large patterns. 20. Extended pcre_study() to be more clever in cases where a branch of a subpattern has no definite first character. For example, (a*|b*)[cd] would previously give no result from pcre_study(). Now it recognizes that the first character must be a, b, c, or d. 21. There was an incorrect error "recursive call could loop indefinitely" if a subpattern (or the entire pattern) that was being tested for matching an empty string contained only one non-empty item after a nested subpattern. For example, the pattern (?>\x{100}*)\d(?R) provoked this error incorrectly, because the \d was being skipped in the check. 22. The pcretest program now has a new pattern option /B and a command line option -b, which is equivalent to adding /B to every pattern. This causes it to show the compiled bytecode, without the additional information that -d shows. The effect of -d is now the same as -b with -i (and similarly, /D is the same as /B/I). 23. A new optimization is now able automatically to treat some sequences such as a*b as a*+b. More specifically, if something simple (such as a character or a simple class like \d) has an unlimited quantifier, and is followed by something that cannot possibly match the quantified thing, the quantifier is automatically "possessified". 24. A recursive reference to a subpattern whose number was greater than 39 went wrong under certain circumstances in UTF-8 mode. This bug could also have affected the operation of pcre_study(). 25. Realized that a little bit of performance could be had by replacing (c & 0xc0) == 0xc0 with c >= 0xc0 when processing UTF-8 characters. 26. Timing data from pcretest is now shown to 4 decimal places instead of 3. 27. Possessive quantifiers such as a++ were previously implemented by turning them into atomic groups such as ($>a+). Now they have their own opcodes, which improves performance. This includes the automatically created ones from 23 above. 28. A pattern such as (?=(\w+))\1: which simulates an atomic group using a lookahead was broken if it was not anchored. PCRE was mistakenly expecting the first matched character to be a colon. This applied both to named and numbered groups. 29. The ucpinternal.h header file was missing its idempotency #ifdef. 30. I was sent a "project" file called libpcre.a.dev which I understand makes building PCRE on Windows easier, so I have included it in the distribution. 31. There is now a check in pcretest against a ridiculously large number being returned by pcre_exec() or pcre_dfa_exec(). If this happens in a /g or /G loop, the loop is abandoned. 32. Forward references to subpatterns in conditions such as (?(2)...) where subpattern 2 is defined later cause pcre_compile() to search forwards in the pattern for the relevant set of parentheses. This search went wrong when there were unescaped parentheses in a character class, parentheses escaped with \Q...\E, or parentheses in a #-comment in /x mode. 33. "Subroutine" calls and backreferences were previously restricted to referencing subpatterns earlier in the regex. This restriction has now been removed. 34. Added a number of extra features that are going to be in Perl 5.10. On the whole, these are just syntactic alternatives for features that PCRE had previously implemented using the Python syntax or my own invention. The other formats are all retained for compatibility. (a) Named groups can now be defined as (?...) or (?'name'...) as well as (?P...). The new forms, as well as being in Perl 5.10, are also .NET compatible. (b) A recursion or subroutine call to a named group can now be defined as (?&name) as well as (?P>name). (c) A backreference to a named group can now be defined as \k or \k'name' as well as (?P=name). The new forms, as well as being in Perl 5.10, are also .NET compatible. (d) A conditional reference to a named group can now use the syntax (?() or (?('name') as well as (?(name). (e) A "conditional group" of the form (?(DEFINE)...) can be used to define groups (named and numbered) that are never evaluated inline, but can be called as "subroutines" from elsewhere. In effect, the DEFINE condition is always false. There may be only one alternative in such a group. (f) A test for recursion can be given as (?(R1).. or (?(R&name)... as well as the simple (?(R). The condition is true only if the most recent recursion is that of the given number or name. It does not search out through the entire recursion stack. (g) The escape \gN or \g{N} has been added, where N is a positive or negative number, specifying an absolute or relative reference. 35. Tidied to get rid of some further signed/unsigned compiler warnings and some "unreachable code" warnings. 36. Updated the Unicode property tables to Unicode version 5.0.0. Amongst other things, this adds five new scripts. 37. Perl ignores orphaned \E escapes completely. PCRE now does the same. There were also incompatibilities regarding the handling of \Q..\E inside character classes, for example with patterns like [\Qa\E-\Qz\E] where the hyphen was adjacent to \Q or \E. I hope I've cleared all this up now. 38. Like Perl, PCRE detects when an indefinitely repeated parenthesized group matches an empty string, and forcibly breaks the loop. There were bugs in this code in non-simple cases. For a pattern such as ^(a()*)* matched against aaaa the result was just "a" rather than "aaaa", for example. Two separate and independent bugs (that affected different cases) have been fixed. 39. Refactored the code to abolish the use of different opcodes for small capturing bracket numbers. This is a tidy that I avoided doing when I removed the limit on the number of capturing brackets for 3.5 back in 2001. The new approach is not only tidier, it makes it possible to reduce the memory needed to fix the previous bug (38). 40. Implemented PCRE_NEWLINE_ANY to recognize any of the Unicode newline sequences (http://unicode.org/unicode/reports/tr18/) as "newline" when processing dot, circumflex, or dollar metacharacters, or #-comments in /x mode. 41. Add \R to match any Unicode newline sequence, as suggested in the Unicode report. 42. Applied patch, originally from Ari Pollak, modified by Google, to allow copy construction and assignment in the C++ wrapper. 43. Updated pcregrep to support "--newline=any". In the process, I fixed a couple of bugs that could have given wrong results in the "--newline=crlf" case. 44. Added a number of casts and did some reorganization of signed/unsigned int variables following suggestions from Dair Grant. Also renamed the variable "this" as "item" because it is a C++ keyword. 45. Arranged for dftables to add #include "pcre_internal.h" to pcre_chartables.c because without it, gcc 4.x may remove the array definition from the final binary if PCRE is built into a static library and dead code stripping is activated. 46. For an unanchored pattern, if a match attempt fails at the start of a newline sequence, and the newline setting is CRLF or ANY, and the next two characters are CRLF, advance by two characters instead of one. Version 6.7 04-Jul-06 --------------------- 1. In order to handle tests when input lines are enormously long, pcretest has been re-factored so that it automatically extends its buffers when necessary. The code is crude, but this _is_ just a test program. The default size has been increased from 32K to 50K. 2. The code in pcre_study() was using the value of the re argument before testing it for NULL. (Of course, in any sensible call of the function, it won't be NULL.) 3. The memmove() emulation function in pcre_internal.h, which is used on systems that lack both memmove() and bcopy() - that is, hardly ever - was missing a "static" storage class specifier. 4. When UTF-8 mode was not set, PCRE looped when compiling certain patterns containing an extended class (one that cannot be represented by a bitmap because it contains high-valued characters or Unicode property items, e.g. [\pZ]). Almost always one would set UTF-8 mode when processing such a pattern, but PCRE should not loop if you do not (it no longer does). [Detail: two cases were found: (a) a repeated subpattern containing an extended class; (b) a recursive reference to a subpattern that followed a previous extended class. It wasn't skipping over the extended class correctly when UTF-8 mode was not set.] 5. A negated single-character class was not being recognized as fixed-length in lookbehind assertions such as (?<=[^f]), leading to an incorrect compile error "lookbehind assertion is not fixed length". 6. The RunPerlTest auxiliary script was showing an unexpected difference between PCRE and Perl for UTF-8 tests. It turns out that it is hard to write a Perl script that can interpret lines of an input file either as byte characters or as UTF-8, which is what "perltest" was being required to do for the non-UTF-8 and UTF-8 tests, respectively. Essentially what you can't do is switch easily at run time between having the "use utf8;" pragma or not. In the end, I fudged it by using the RunPerlTest script to insert "use utf8;" explicitly for the UTF-8 tests. 7. In multiline (/m) mode, PCRE was matching ^ after a terminating newline at the end of the subject string, contrary to the documentation and to what Perl does. This was true of both matching functions. Now it matches only at the start of the subject and immediately after *internal* newlines. 8. A call of pcre_fullinfo() from pcretest to get the option bits was passing a pointer to an int instead of a pointer to an unsigned long int. This caused problems on 64-bit systems. 9. Applied a patch from the folks at Google to pcrecpp.cc, to fix "another instance of the 'standard' template library not being so standard". 10. There was no check on the number of named subpatterns nor the maximum length of a subpattern name. The product of these values is used to compute the size of the memory block for a compiled pattern. By supplying a very long subpattern name and a large number of named subpatterns, the size computation could be caused to overflow. This is now prevented by limiting the length of names to 32 characters, and the number of named subpatterns to 10,000. 11. Subpatterns that are repeated with specific counts have to be replicated in the compiled pattern. The size of memory for this was computed from the length of the subpattern and the repeat count. The latter is limited to 65535, but there was no limit on the former, meaning that integer overflow could in principle occur. The compiled length of a repeated subpattern is now limited to 30,000 bytes in order to prevent this. 12. Added the optional facility to have named substrings with the same name. 13. Added the ability to use a named substring as a condition, using the Python syntax: (?(name)yes|no). This overloads (?(R)... and names that are numbers (not recommended). Forward references are permitted. 14. Added forward references in named backreferences (if you see what I mean). 15. In UTF-8 mode, with the PCRE_DOTALL option set, a quantified dot in the pattern could run off the end of the subject. For example, the pattern "(?s)(.{1,5})"8 did this with the subject "ab". 16. If PCRE_DOTALL or PCRE_MULTILINE were set, pcre_dfa_exec() behaved as if PCRE_CASELESS was set when matching characters that were quantified with ? or *. 17. A character class other than a single negated character that had a minimum but no maximum quantifier - for example [ab]{6,} - was not handled correctly by pce_dfa_exec(). It would match only one character. 18. A valid (though odd) pattern that looked like a POSIX character class but used an invalid character after [ (for example [[,abc,]]) caused pcre_compile() to give the error "Failed: internal error: code overflow" or in some cases to crash with a glibc free() error. This could even happen if the pattern terminated after [[ but there just happened to be a sequence of letters, a binary zero, and a closing ] in the memory that followed. 19. Perl's treatment of octal escapes in the range \400 to \777 has changed over the years. Originally (before any Unicode support), just the bottom 8 bits were taken. Thus, for example, \500 really meant \100. Nowadays the output from "man perlunicode" includes this: The regular expression compiler produces polymorphic opcodes. That is, the pattern adapts to the data and automatically switches to the Unicode character scheme when presented with Unicode data--or instead uses a traditional byte scheme when presented with byte data. Sadly, a wide octal escape does not cause a switch, and in a string with no other multibyte characters, these octal escapes are treated as before. Thus, in Perl, the pattern /\500/ actually matches \100 but the pattern /\500|\x{1ff}/ matches \500 or \777 because the whole thing is treated as a Unicode string. I have not perpetrated such confusion in PCRE. Up till now, it took just the bottom 8 bits, as in old Perl. I have now made octal escapes with values greater than \377 illegal in non-UTF-8 mode. In UTF-8 mode they translate to the appropriate multibyte character. 29. Applied some refactoring to reduce the number of warnings from Microsoft and Borland compilers. This has included removing the fudge introduced seven years ago for the OS/2 compiler (see 2.02/2 below) because it caused a warning about an unused variable. 21. PCRE has not included VT (character 0x0b) in the set of whitespace characters since release 4.0, because Perl (from release 5.004) does not. [Or at least, is documented not to: some releases seem to be in conflict with the documentation.] However, when a pattern was studied with pcre_study() and all its branches started with \s, PCRE still included VT as a possible starting character. Of course, this did no harm; it just caused an unnecessary match attempt. 22. Removed a now-redundant internal flag bit that recorded the fact that case dependency changed within the pattern. This was once needed for "required byte" processing, but is no longer used. This recovers a now-scarce options bit. Also moved the least significant internal flag bit to the most- significant bit of the word, which was not previously used (hangover from the days when it was an int rather than a uint) to free up another bit for the future. 23. Added support for CRLF line endings as well as CR and LF. As well as the default being selectable at build time, it can now be changed at runtime via the PCRE_NEWLINE_xxx flags. There are now options for pcregrep to specify that it is scanning data with non-default line endings. 24. Changed the definition of CXXLINK to make it agree with the definition of LINK in the Makefile, by replacing LDFLAGS to CXXFLAGS. 25. Applied Ian Taylor's patches to avoid using another stack frame for tail recursions. This makes a big different to stack usage for some patterns. 26. If a subpattern containing a named recursion or subroutine reference such as (?P>B) was quantified, for example (xxx(?P>B)){3}, the calculation of the space required for the compiled pattern went wrong and gave too small a value. Depending on the environment, this could lead to "Failed: internal error: code overflow at offset 49" or "glibc detected double free or corruption" errors. 27. Applied patches from Google (a) to support the new newline modes and (b) to advance over multibyte UTF-8 characters in GlobalReplace. 28. Change free() to pcre_free() in pcredemo.c. Apparently this makes a difference for some implementation of PCRE in some Windows version. 29. Added some extra testing facilities to pcretest: \q in a data line sets the "match limit" value \Q in a data line sets the "match recursion limt" value -S sets the stack size, where is in megabytes The -S option isn't available for Windows. Version 6.6 06-Feb-06 --------------------- 1. Change 16(a) for 6.5 broke things, because PCRE_DATA_SCOPE was not defined in pcreposix.h. I have copied the definition from pcre.h. 2. Change 25 for 6.5 broke compilation in a build directory out-of-tree because pcre.h is no longer a built file. 3. Added Jeff Friedl's additional debugging patches to pcregrep. These are not normally included in the compiled code. Version 6.5 01-Feb-06 --------------------- 1. When using the partial match feature with pcre_dfa_exec(), it was not anchoring the second and subsequent partial matches at the new starting point. This could lead to incorrect results. For example, with the pattern /1234/, partially matching against "123" and then "a4" gave a match. 2. Changes to pcregrep: (a) All non-match returns from pcre_exec() were being treated as failures to match the line. Now, unless the error is PCRE_ERROR_NOMATCH, an error message is output. Some extra information is given for the PCRE_ERROR_MATCHLIMIT and PCRE_ERROR_RECURSIONLIMIT errors, which are probably the only errors that are likely to be caused by users (by specifying a regex that has nested indefinite repeats, for instance). If there are more than 20 of these errors, pcregrep is abandoned. (b) A binary zero was treated as data while matching, but terminated the output line if it was written out. This has been fixed: binary zeroes are now no different to any other data bytes. (c) Whichever of the LC_ALL or LC_CTYPE environment variables is set is used to set a locale for matching. The --locale=xxxx long option has been added (no short equivalent) to specify a locale explicitly on the pcregrep command, overriding the environment variables. (d) When -B was used with -n, some line numbers in the output were one less than they should have been. (e) Added the -o (--only-matching) option. (f) If -A or -C was used with -c (count only), some lines of context were accidentally printed for the final match. (g) Added the -H (--with-filename) option. (h) The combination of options -rh failed to suppress file names for files that were found from directory arguments. (i) Added the -D (--devices) and -d (--directories) options. (j) Added the -F (--fixed-strings) option. (k) Allow "-" to be used as a file name for -f as well as for a data file. (l) Added the --colo(u)r option. (m) Added Jeffrey Friedl's -S testing option, but within #ifdefs so that it is not present by default. 3. A nasty bug was discovered in the handling of recursive patterns, that is, items such as (?R) or (?1), when the recursion could match a number of alternatives. If it matched one of the alternatives, but subsequently, outside the recursion, there was a failure, the code tried to back up into the recursion. However, because of the way PCRE is implemented, this is not possible, and the result was an incorrect result from the match. In order to prevent this happening, the specification of recursion has been changed so that all such subpatterns are automatically treated as atomic groups. Thus, for example, (?R) is treated as if it were (?>(?R)). 4. I had overlooked the fact that, in some locales, there are characters for which isalpha() is true but neither isupper() nor islower() are true. In the fr_FR locale, for instance, the \xAA and \xBA characters (ordmasculine and ordfeminine) are like this. This affected the treatment of \w and \W when they appeared in character classes, but not when they appeared outside a character class. The bit map for "word" characters is now created separately from the results of isalnum() instead of just taking it from the upper, lower, and digit maps. (Plus the underscore character, of course.) 5. The above bug also affected the handling of POSIX character classes such as [[:alpha:]] and [[:alnum:]]. These do not have their own bit maps in PCRE's permanent tables. Instead, the bit maps for such a class were previously created as the appropriate unions of the upper, lower, and digit bitmaps. Now they are created by subtraction from the [[:word:]] class, which has its own bitmap. 6. The [[:blank:]] character class matches horizontal, but not vertical space. It is created by subtracting the vertical space characters (\x09, \x0a, \x0b, \x0c) from the [[:space:]] bitmap. Previously, however, the subtraction was done in the overall bitmap for a character class, meaning that a class such as [\x0c[:blank:]] was incorrect because \x0c would not be recognized. This bug has been fixed. 7. Patches from the folks at Google: (a) pcrecpp.cc: "to handle a corner case that may or may not happen in real life, but is still worth protecting against". (b) pcrecpp.cc: "corrects a bug when negative radixes are used with regular expressions". (c) pcre_scanner.cc: avoid use of std::count() because not all systems have it. (d) Split off pcrecpparg.h from pcrecpp.h and had the former built by "configure" and the latter not, in order to fix a problem somebody had with compiling the Arg class on HP-UX. (e) Improve the error-handling of the C++ wrapper a little bit. (f) New tests for checking recursion limiting. 8. The pcre_memmove() function, which is used only if the environment does not have a standard memmove() function (and is therefore rarely compiled), contained two bugs: (a) use of int instead of size_t, and (b) it was not returning a result (though PCRE never actually uses the result). 9. In the POSIX regexec() interface, if nmatch is specified as a ridiculously large number - greater than INT_MAX/(3*sizeof(int)) - REG_ESPACE is returned instead of calling malloc() with an overflowing number that would most likely cause subsequent chaos. 10. The debugging option of pcretest was not showing the NO_AUTO_CAPTURE flag. 11. The POSIX flag REG_NOSUB is now supported. When a pattern that was compiled with this option is matched, the nmatch and pmatch options of regexec() are ignored. 12. Added REG_UTF8 to the POSIX interface. This is not defined by POSIX, but is provided in case anyone wants to the the POSIX interface with UTF-8 strings. 13. Added CXXLDFLAGS to the Makefile parameters to provide settings only on the C++ linking (needed for some HP-UX environments). 14. Avoid compiler warnings in get_ucpname() when compiled without UCP support (unused parameter) and in the pcre_printint() function (omitted "default" switch label when the default is to do nothing). 15. Added some code to make it possible, when PCRE is compiled as a C++ library, to replace subject pointers for pcre_exec() with a smart pointer class, thus making it possible to process discontinuous strings. 16. The two macros PCRE_EXPORT and PCRE_DATA_SCOPE are confusing, and perform much the same function. They were added by different people who were trying to make PCRE easy to compile on non-Unix systems. It has been suggested that PCRE_EXPORT be abolished now that there is more automatic apparatus for compiling on Windows systems. I have therefore replaced it with PCRE_DATA_SCOPE. This is set automatically for Windows; if not set it defaults to "extern" for C or "extern C" for C++, which works fine on Unix-like systems. It is now possible to override the value of PCRE_DATA_ SCOPE with something explicit in config.h. In addition: (a) pcreposix.h still had just "extern" instead of either of these macros; I have replaced it with PCRE_DATA_SCOPE. (b) Functions such as _pcre_xclass(), which are internal to the library, but external in the C sense, all had PCRE_EXPORT in their definitions. This is apparently wrong for the Windows case, so I have removed it. (It makes no difference on Unix-like systems.) 17. Added a new limit, MATCH_LIMIT_RECURSION, which limits the depth of nesting of recursive calls to match(). This is different to MATCH_LIMIT because that limits the total number of calls to match(), not all of which increase the depth of recursion. Limiting the recursion depth limits the amount of stack (or heap if NO_RECURSE is set) that is used. The default can be set when PCRE is compiled, and changed at run time. A patch from Google adds this functionality to the C++ interface. 18. Changes to the handling of Unicode character properties: (a) Updated the table to Unicode 4.1.0. (b) Recognize characters that are not in the table as "Cn" (undefined). (c) I revised the way the table is implemented to a much improved format which includes recognition of ranges. It now supports the ranges that are defined in UnicodeData.txt, and it also amalgamates other characters into ranges. This has reduced the number of entries in the table from around 16,000 to around 3,000, thus reducing its size considerably. I realized I did not need to use a tree structure after all - a binary chop search is just as efficient. Having reduced the number of entries, I extended their size from 6 bytes to 8 bytes to allow for more data. (d) Added support for Unicode script names via properties such as \p{Han}. 19. In UTF-8 mode, a backslash followed by a non-Ascii character was not matching that character. 20. When matching a repeated Unicode property with a minimum greater than zero, (for example \pL{2,}), PCRE could look past the end of the subject if it reached it while seeking the minimum number of characters. This could happen only if some of the characters were more than one byte long, because there is a check for at least the minimum number of bytes. 21. Refactored the implementation of \p and \P so as to be more general, to allow for more different types of property in future. This has changed the compiled form incompatibly. Anybody with saved compiled patterns that use \p or \P will have to recompile them. 22. Added "Any" and "L&" to the supported property types. 23. Recognize \x{...} as a code point specifier, even when not in UTF-8 mode, but give a compile time error if the value is greater than 0xff. 24. The man pages for pcrepartial, pcreprecompile, and pcre_compile2 were accidentally not being installed or uninstalled. 25. The pcre.h file was built from pcre.h.in, but the only changes that were made were to insert the current release number. This seemed silly, because it made things harder for people building PCRE on systems that don't run "configure". I have turned pcre.h into a distributed file, no longer built by "configure", with the version identification directly included. There is no longer a pcre.h.in file. However, this change necessitated a change to the pcre-config script as well. It is built from pcre-config.in, and one of the substitutions was the release number. I have updated configure.ac so that ./configure now finds the release number by grepping pcre.h. 26. Added the ability to run the tests under valgrind. Version 6.4 05-Sep-05 --------------------- 1. Change 6.0/10/(l) to pcregrep introduced a bug that caused separator lines "--" to be printed when multiple files were scanned, even when none of the -A, -B, or -C options were used. This is not compatible with Gnu grep, so I consider it to be a bug, and have restored the previous behaviour. 2. A couple of code tidies to get rid of compiler warnings. 3. The pcretest program used to cheat by referring to symbols in the library whose names begin with _pcre_. These are internal symbols that are not really supposed to be visible externally, and in some environments it is possible to suppress them. The cheating is now confined to including certain files from the library's source, which is a bit cleaner. 4. Renamed pcre.in as pcre.h.in to go with pcrecpp.h.in; it also makes the file's purpose clearer. 5. Reorganized pcre_ucp_findchar(). Version 6.3 15-Aug-05 --------------------- 1. The file libpcre.pc.in did not have general read permission in the tarball. 2. There were some problems when building without C++ support: (a) If C++ support was not built, "make install" and "make test" still tried to test it. (b) There were problems when the value of CXX was explicitly set. Some changes have been made to try to fix these, and ... (c) --disable-cpp can now be used to explicitly disable C++ support. (d) The use of @CPP_OBJ@ directly caused a blank line preceded by a backslash in a target when C++ was disabled. This confuses some versions of "make", apparently. Using an intermediate variable solves this. (Same for CPP_LOBJ.) 3. $(LINK_FOR_BUILD) now includes $(CFLAGS_FOR_BUILD) and $(LINK) (non-Windows) now includes $(CFLAGS) because these flags are sometimes necessary on certain architectures. 4. Added a setting of -export-symbols-regex to the link command to remove those symbols that are exported in the C sense, but actually are local within the library, and not documented. Their names all begin with "_pcre_". This is not a perfect job, because (a) we have to except some symbols that pcretest ("illegally") uses, and (b) the facility isn't always available (and never for static libraries). I have made a note to try to find a way round (a) in the future. Version 6.2 01-Aug-05 --------------------- 1. There was no test for integer overflow of quantifier values. A construction such as {1111111111111111} would give undefined results. What is worse, if a minimum quantifier for a parenthesized subpattern overflowed and became negative, the calculation of the memory size went wrong. This could have led to memory overwriting. 2. Building PCRE using VPATH was broken. Hopefully it is now fixed. 3. Added "b" to the 2nd argument of fopen() in dftables.c, for non-Unix-like operating environments where this matters. 4. Applied Giuseppe Maxia's patch to add additional features for controlling PCRE options from within the C++ wrapper. 5. Named capturing subpatterns were not being correctly counted when a pattern was compiled. This caused two problems: (a) If there were more than 100 such subpatterns, the calculation of the memory needed for the whole compiled pattern went wrong, leading to an overflow error. (b) Numerical back references of the form \12, where the number was greater than 9, were not recognized as back references, even though there were sufficient previous subpatterns. 6. Two minor patches to pcrecpp.cc in order to allow it to compile on older versions of gcc, e.g. 2.95.4. Version 6.1 21-Jun-05 --------------------- 1. There was one reference to the variable "posix" in pcretest.c that was not surrounded by "#if !defined NOPOSIX". 2. Make it possible to compile pcretest without DFA support, UTF8 support, or the cross-check on the old pcre_info() function, for the benefit of the cut-down version of PCRE that is currently imported into Exim. 3. A (silly) pattern starting with (?i)(?-i) caused an internal space allocation error. I've done the easy fix, which wastes 2 bytes for sensible patterns that start (?i) but I don't think that matters. The use of (?i) is just an example; this all applies to the other options as well. 4. Since libtool seems to echo the compile commands it is issuing, the output from "make" can be reduced a bit by putting "@" in front of each libtool compile command. 5. Patch from the folks at Google for configure.in to be a bit more thorough in checking for a suitable C++ installation before trying to compile the C++ stuff. This should fix a reported problem when a compiler was present, but no suitable headers. 6. The man pages all had just "PCRE" as their title. I have changed them to be the relevant file name. I have also arranged that these names are retained in the file doc/pcre.txt, which is a concatenation in text format of all the man pages except the little individual ones for each function. 7. The NON-UNIX-USE file had not been updated for the different set of source files that come with release 6. I also added a few comments about the C++ wrapper. Version 6.0 07-Jun-05 --------------------- 1. Some minor internal re-organization to help with my DFA experiments. 2. Some missing #ifdef SUPPORT_UCP conditionals in pcretest and printint that didn't matter for the library itself when fully configured, but did matter when compiling without UCP support, or within Exim, where the ucp files are not imported. 3. Refactoring of the library code to split up the various functions into different source modules. The addition of the new DFA matching code (see below) to a single monolithic source would have made it really too unwieldy, quite apart from causing all the code to be include in a statically linked application, when only some functions are used. This is relevant even without the DFA addition now that patterns can be compiled in one application and matched in another. The downside of splitting up is that there have to be some external functions and data tables that are used internally in different modules of the library but which are not part of the API. These have all had their names changed to start with "_pcre_" so that they are unlikely to clash with other external names. 4. Added an alternate matching function, pcre_dfa_exec(), which matches using a different (DFA) algorithm. Although it is slower than the original function, it does have some advantages for certain types of matching problem. 5. Upgrades to pcretest in order to test the features of pcre_dfa_exec(), including restarting after a partial match. 6. A patch for pcregrep that defines INVALID_FILE_ATTRIBUTES if it is not defined when compiling for Windows was sent to me. I have put it into the code, though I have no means of testing or verifying it. 7. Added the pcre_refcount() auxiliary function. 8. Added the PCRE_FIRSTLINE option. This constrains an unanchored pattern to match before or at the first newline in the subject string. In pcretest, the /f option on a pattern can be used to set this. 9. A repeated \w when used in UTF-8 mode with characters greater than 256 would behave wrongly. This has been present in PCRE since release 4.0. 10. A number of changes to the pcregrep command: (a) Refactored how -x works; insert ^(...)$ instead of setting PCRE_ANCHORED and checking the length, in preparation for adding something similar for -w. (b) Added the -w (match as a word) option. (c) Refactored the way lines are read and buffered so as to have more than one at a time available. (d) Implemented a pcregrep test script. (e) Added the -M (multiline match) option. This allows patterns to match over several lines of the subject. The buffering ensures that at least 8K, or the rest of the document (whichever is the shorter) is available for matching (and similarly the previous 8K for lookbehind assertions). (f) Changed the --help output so that it now says -w, --word-regex(p) instead of two lines, one with "regex" and the other with "regexp" because that confused at least one person since the short forms are the same. (This required a bit of code, as the output is generated automatically from a table. It wasn't just a text change.) (g) -- can be used to terminate pcregrep options if the next thing isn't an option but starts with a hyphen. Could be a pattern or a path name starting with a hyphen, for instance. (h) "-" can be given as a file name to represent stdin. (i) When file names are being printed, "(standard input)" is used for the standard input, for compatibility with GNU grep. Previously "" was used. (j) The option --label=xxx can be used to supply a name to be used for stdin when file names are being printed. There is no short form. (k) Re-factored the options decoding logic because we are going to add two more options that take data. Such options can now be given in four different ways, e.g. "-fname", "-f name", "--file=name", "--file name". (l) Added the -A, -B, and -C options for requesting that lines of context around matches be printed. (m) Added the -L option to print the names of files that do not contain any matching lines, that is, the complement of -l. (n) The return code is 2 if any file cannot be opened, but pcregrep does continue to scan other files. (o) The -s option was incorrectly implemented. For compatibility with other greps, it now suppresses the error message for a non-existent or non- accessible file (but not the return code). There is a new option called -q that suppresses the output of matching lines, which was what -s was previously doing. (p) Added --include and --exclude options to specify files for inclusion and exclusion when recursing. 11. The Makefile was not using the Autoconf-supported LDFLAGS macro properly. Hopefully, it now does. 12. Missing cast in pcre_study(). 13. Added an "uninstall" target to the makefile. 14. Replaced "extern" in the function prototypes in Makefile.in with "PCRE_DATA_SCOPE", which defaults to 'extern' or 'extern "C"' in the Unix world, but is set differently for Windows. 15. Added a second compiling function called pcre_compile2(). The only difference is that it has an extra argument, which is a pointer to an integer error code. When there is a compile-time failure, this is set non-zero, in addition to the error test pointer being set to point to an error message. The new argument may be NULL if no error number is required (but then you may as well call pcre_compile(), which is now just a wrapper). This facility is provided because some applications need a numeric error indication, but it has also enabled me to tidy up the way compile-time errors are handled in the POSIX wrapper. 16. Added VPATH=.libs to the makefile; this should help when building with one prefix path and installing with another. (Or so I'm told by someone who knows more about this stuff than I do.) 17. Added a new option, REG_DOTALL, to the POSIX function regcomp(). This passes PCRE_DOTALL to the pcre_compile() function, making the "." character match everything, including newlines. This is not POSIX-compatible, but somebody wanted the feature. From pcretest it can be activated by using both the P and the s flags. 18. AC_PROG_LIBTOOL appeared twice in Makefile.in. Removed one. 19. libpcre.pc was being incorrectly installed as executable. 20. A couple of places in pcretest check for end-of-line by looking for '\n'; it now also looks for '\r' so that it will work unmodified on Windows. 21. Added Google's contributed C++ wrapper to the distribution. 22. Added some untidy missing memory free() calls in pcretest, to keep Electric Fence happy when testing. Version 5.0 13-Sep-04 --------------------- 1. Internal change: literal characters are no longer packed up into items containing multiple characters in a single byte-string. Each character is now matched using a separate opcode. However, there may be more than one byte in the character in UTF-8 mode. 2. The pcre_callout_block structure has two new fields: pattern_position and next_item_length. These contain the offset in the pattern to the next match item, and its length, respectively. 3. The PCRE_AUTO_CALLOUT option for pcre_compile() requests the automatic insertion of callouts before each pattern item. Added the /C option to pcretest to make use of this. 4. On the advice of a Windows user, the lines #if defined(_WIN32) || defined(WIN32) _setmode( _fileno( stdout ), 0x8000 ); #endif /* defined(_WIN32) || defined(WIN32) */ have been added to the source of pcretest. This apparently does useful magic in relation to line terminators. 5. Changed "r" and "w" in the calls to fopen() in pcretest to "rb" and "wb" for the benefit of those environments where the "b" makes a difference. 6. The icc compiler has the same options as gcc, but "configure" doesn't seem to know about it. I have put a hack into configure.in that adds in code to set GCC=yes if CC=icc. This seems to end up at a point in the generated configure script that is early enough to affect the setting of compiler options, which is what is needed, but I have no means of testing whether it really works. (The user who reported this had patched the generated configure script, which of course I cannot do.) LATER: After change 22 below (new libtool files), the configure script seems to know about icc (and also ecc). Therefore, I have commented out this hack in configure.in. 7. Added support for pkg-config (2 patches were sent in). 8. Negated POSIX character classes that used a combination of internal tables were completely broken. These were [[:^alpha:]], [[:^alnum:]], and [[:^ascii]]. Typically, they would match almost any characters. The other POSIX classes were not broken in this way. 9. Matching the pattern "\b.*?" against "ab cd", starting at offset 1, failed to find the match, as PCRE was deluded into thinking that the match had to start at the start point or following a newline. The same bug applied to patterns with negative forward assertions or any backward assertions preceding ".*" at the start, unless the pattern required a fixed first character. This was a failing pattern: "(?!.bcd).*". The bug is now fixed. 10. In UTF-8 mode, when moving forwards in the subject after a failed match starting at the last subject character, bytes beyond the end of the subject string were read. 11. Renamed the variable "class" as "classbits" to make life easier for C++ users. (Previously there was a macro definition, but it apparently wasn't enough.) 12. Added the new field "tables" to the extra data so that tables can be passed in at exec time, or the internal tables can be re-selected. This allows a compiled regex to be saved and re-used at a later time by a different program that might have everything at different addresses. 13. Modified the pcre-config script so that, when run on Solaris, it shows a -R library as well as a -L library. 14. The debugging options of pcretest (-d on the command line or D on a pattern) showed incorrect output for anything following an extended class that contained multibyte characters and which was followed by a quantifier. 15. Added optional support for general category Unicode character properties via the \p, \P, and \X escapes. Unicode property support implies UTF-8 support. It adds about 90K to the size of the library. The meanings of the inbuilt class escapes such as \d and \s have NOT been changed. 16. Updated pcredemo.c to include calls to free() to release the memory for the compiled pattern. 17. The generated file chartables.c was being created in the source directory instead of in the building directory. This caused the build to fail if the source directory was different from the building directory, and was read-only. 18. Added some sample Win commands from Mark Tetrode into the NON-UNIX-USE file. No doubt somebody will tell me if they don't make sense... Also added Dan Mooney's comments about building on OpenVMS. 19. Added support for partial matching via the PCRE_PARTIAL option for pcre_exec() and the \P data escape in pcretest. 20. Extended pcretest with 3 new pattern features: (i) A pattern option of the form ">rest-of-line" causes pcretest to write the compiled pattern to the file whose name is "rest-of-line". This is a straight binary dump of the data, with the saved pointer to the character tables forced to be NULL. The study data, if any, is written too. After writing, pcretest reads a new pattern. (ii) If, instead of a pattern, ": new target : new target : use native compiler : use native linker : handle Windows platform correctly : ditto : ditto copy DLL to top builddir before testing As part of these changes, -no-undefined was removed again. This was reported to give trouble on HP-UX 11.0, so getting rid of it seems like a good idea in any case. 3. Some tidies to get rid of compiler warnings: . In the match_data structure, match_limit was an unsigned long int, whereas match_call_count was an int. I've made them both unsigned long ints. . In pcretest the fact that a const uschar * doesn't automatically cast to a void * provoked a warning. . Turning on some more compiler warnings threw up some "shadow" variables and a few more missing casts. 4. If PCRE was complied with UTF-8 support, but called without the PCRE_UTF8 option, a class that contained a single character with a value between 128 and 255 (e.g. /[\xFF]/) caused PCRE to crash. 5. If PCRE was compiled with UTF-8 support, but called without the PCRE_UTF8 option, a class that contained several characters, but with at least one whose value was between 128 and 255 caused PCRE to crash. Version 4.1 12-Mar-03 --------------------- 1. Compiling with gcc -pedantic found a couple of places where casts were needed, and a string in dftables.c that was longer than standard compilers are required to support. 2. Compiling with Sun's compiler found a few more places where the code could be tidied up in order to avoid warnings. 3. The variables for cross-compiling were called HOST_CC and HOST_CFLAGS; the first of these names is deprecated in the latest Autoconf in favour of the name CC_FOR_BUILD, because "host" is typically used to mean the system on which the compiled code will be run. I can't find a reference for HOST_CFLAGS, but by analogy I have changed it to CFLAGS_FOR_BUILD. 4. Added -no-undefined to the linking command in the Makefile, because this is apparently helpful for Windows. To make it work, also added "-L. -lpcre" to the linking step for the pcreposix library. 5. PCRE was failing to diagnose the case of two named groups with the same name. 6. A problem with one of PCRE's optimizations was discovered. PCRE remembers a literal character that is needed in the subject for a match, and scans along to ensure that it is present before embarking on the full matching process. This saves time in cases of nested unlimited repeats that are never going to match. Problem: the scan can take a lot of time if the subject is very long (e.g. megabytes), thus penalizing straightforward matches. It is now done only if the amount of subject to be scanned is less than 1000 bytes. 7. A lesser problem with the same optimization is that it was recording the first character of an anchored pattern as "needed", thus provoking a search right along the subject, even when the first match of the pattern was going to fail. The "needed" character is now not set for anchored patterns, unless it follows something in the pattern that is of non-fixed length. Thus, it still fulfils its original purpose of finding quick non-matches in cases of nested unlimited repeats, but isn't used for simple anchored patterns such as /^abc/. Version 4.0 17-Feb-03 --------------------- 1. If a comment in an extended regex that started immediately after a meta-item extended to the end of string, PCRE compiled incorrect data. This could lead to all kinds of weird effects. Example: /#/ was bad; /()#/ was bad; /a#/ was not. 2. Moved to autoconf 2.53 and libtool 1.4.2. 3. Perl 5.8 no longer needs "use utf8" for doing UTF-8 things. Consequently, the special perltest8 script is no longer needed - all the tests can be run from a single perltest script. 4. From 5.004, Perl has not included the VT character (0x0b) in the set defined by \s. It has now been removed in PCRE. This means it isn't recognized as whitespace in /x regexes too, which is the same as Perl. Note that the POSIX class [:space:] *does* include VT, thereby creating a mess. 5. Added the class [:blank:] (a GNU extension from Perl 5.8) to match only space and tab. 6. Perl 5.005 was a long time ago. It's time to amalgamate the tests that use its new features into the main test script, reducing the number of scripts. 7. Perl 5.8 has changed the meaning of patterns like /a(?i)b/. Earlier versions were backward compatible, and made the (?i) apply to the whole pattern, as if /i were given. Now it behaves more logically, and applies the option setting only to what follows. PCRE has been changed to follow suit. However, if it finds options settings right at the start of the pattern, it extracts them into the global options, as before. Thus, they show up in the info data. 8. Added support for the \Q...\E escape sequence. Characters in between are treated as literals. This is slightly different from Perl in that $ and @ are also handled as literals inside the quotes. In Perl, they will cause variable interpolation. Note the following examples: Pattern PCRE matches Perl matches \Qabc$xyz\E abc$xyz abc followed by the contents of $xyz \Qabc\$xyz\E abc\$xyz abc\$xyz \Qabc\E\$\Qxyz\E abc$xyz abc$xyz For compatibility with Perl, \Q...\E sequences are recognized inside character classes as well as outside them. 9. Re-organized 3 code statements in pcretest to avoid "overflow in floating-point constant arithmetic" warnings from a Microsoft compiler. Added a (size_t) cast to one statement in pcretest and one in pcreposix to avoid signed/unsigned warnings. 10. SunOS4 doesn't have strtoul(). This was used only for unpicking the -o option for pcretest, so I've replaced it by a simple function that does just that job. 11. pcregrep was ending with code 0 instead of 2 for the commands "pcregrep" or "pcregrep -". 12. Added "possessive quantifiers" ?+, *+, ++, and {,}+ which come from Sun's Java package. This provides some syntactic sugar for simple cases of what my documentation calls "once-only subpatterns". A pattern such as x*+ is the same as (?>x*). In other words, if what is inside (?>...) is just a single repeated item, you can use this simplified notation. Note that only makes sense with greedy quantifiers. Consequently, the use of the possessive quantifier forces greediness, whatever the setting of the PCRE_UNGREEDY option. 13. A change of greediness default within a pattern was not taking effect at the current level for patterns like /(b+(?U)a+)/. It did apply to parenthesized subpatterns that followed. Patterns like /b+(?U)a+/ worked because the option was abstracted outside. 14. PCRE now supports the \G assertion. It is true when the current matching position is at the start point of the match. This differs from \A when the starting offset is non-zero. Used with the /g option of pcretest (or similar code), it works in the same way as it does for Perl's /g option. If all alternatives of a regex begin with \G, the expression is anchored to the start match position, and the "anchored" flag is set in the compiled expression. 15. Some bugs concerning the handling of certain option changes within patterns have been fixed. These applied to options other than (?ims). For example, "a(?x: b c )d" did not match "XabcdY" but did match "Xa b c dY". It should have been the other way round. Some of this was related to change 7 above. 16. PCRE now gives errors for /[.x.]/ and /[=x=]/ as unsupported POSIX features, as Perl does. Previously, PCRE gave the warnings only for /[[.x.]]/ and /[[=x=]]/. PCRE now also gives an error for /[:name:]/ because it supports POSIX classes only within a class (e.g. /[[:alpha:]]/). 17. Added support for Perl's \C escape. This matches one byte, even in UTF8 mode. Unlike ".", it always matches newline, whatever the setting of PCRE_DOTALL. However, PCRE does not permit \C to appear in lookbehind assertions. Perl allows it, but it doesn't (in general) work because it can't calculate the length of the lookbehind. At least, that's the case for Perl 5.8.0 - I've been told they are going to document that it doesn't work in future. 18. Added an error diagnosis for escapes that PCRE does not support: these are \L, \l, \N, \P, \p, \U, \u, and \X. 19. Although correctly diagnosing a missing ']' in a character class, PCRE was reading past the end of the pattern in cases such as /[abcd/. 20. PCRE was getting more memory than necessary for patterns with classes that contained both POSIX named classes and other characters, e.g. /[[:space:]abc/. 21. Added some code, conditional on #ifdef VPCOMPAT, to make life easier for compiling PCRE for use with Virtual Pascal. 22. Small fix to the Makefile to make it work properly if the build is done outside the source tree. 23. Added a new extension: a condition to go with recursion. If a conditional subpattern starts with (?(R) the "true" branch is used if recursion has happened, whereas the "false" branch is used only at the top level. 24. When there was a very long string of literal characters (over 255 bytes without UTF support, over 250 bytes with UTF support), the computation of how much memory was required could be incorrect, leading to segfaults or other strange effects. 25. PCRE was incorrectly assuming anchoring (either to start of subject or to start of line for a non-DOTALL pattern) when a pattern started with (.*) and there was a subsequent back reference to those brackets. This meant that, for example, /(.*)\d+\1/ failed to match "abc123bc". Unfortunately, it isn't possible to check for precisely this case. All we can do is abandon the optimization if .* occurs inside capturing brackets when there are any back references whatsoever. (See below for a better fix that came later.) 26. The handling of the optimization for finding the first character of a non-anchored pattern, and for finding a character that is required later in the match were failing in some cases. This didn't break the matching; it just failed to optimize when it could. The way this is done has been re-implemented. 27. Fixed typo in error message for invalid (?R item (it said "(?p"). 28. Added a new feature that provides some of the functionality that Perl provides with (?{...}). The facility is termed a "callout". The way it is done in PCRE is for the caller to provide an optional function, by setting pcre_callout to its entry point. Like pcre_malloc and pcre_free, this is a global variable. By default it is unset, which disables all calling out. To get the function called, the regex must include (?C) at appropriate points. This is, in fact, equivalent to (?C0), and any number <= 255 may be given with (?C). This provides a means of identifying different callout points. When PCRE reaches such a point in the regex, if pcre_callout has been set, the external function is called. It is provided with data in a structure called pcre_callout_block, which is defined in pcre.h. If the function returns 0, matching continues; if it returns a non-zero value, the match at the current point fails. However, backtracking will occur if possible. [This was changed later and other features added - see item 49 below.] 29. pcretest is upgraded to test the callout functionality. It provides a callout function that displays information. By default, it shows the start of the match and the current position in the text. There are some new data escapes to vary what happens: \C+ in addition, show current contents of captured substrings \C- do not supply a callout function \C!n return 1 when callout number n is reached \C!n!m return 1 when callout number n is reached for the mth time 30. If pcregrep was called with the -l option and just a single file name, it output "" if a match was found, instead of the file name. 31. Improve the efficiency of the POSIX API to PCRE. If the number of capturing slots is less than POSIX_MALLOC_THRESHOLD, use a block on the stack to pass to pcre_exec(). This saves a malloc/free per call. The default value of POSIX_MALLOC_THRESHOLD is 10; it can be changed by --with-posix-malloc-threshold when configuring. 32. The default maximum size of a compiled pattern is 64K. There have been a few cases of people hitting this limit. The code now uses macros to handle the storing of links as offsets within the compiled pattern. It defaults to 2-byte links, but this can be changed to 3 or 4 bytes by --with-link-size when configuring. Tests 2 and 5 work only with 2-byte links because they output debugging information about compiled patterns. 33. Internal code re-arrangements: (a) Moved the debugging function for printing out a compiled regex into its own source file (printint.c) and used #include to pull it into pcretest.c and, when DEBUG is defined, into pcre.c, instead of having two separate copies. (b) Defined the list of op-code names for debugging as a macro in internal.h so that it is next to the definition of the opcodes. (c) Defined a table of op-code lengths for simpler skipping along compiled code. This is again a macro in internal.h so that it is next to the definition of the opcodes. 34. Added support for recursive calls to individual subpatterns, along the lines of Robin Houston's patch (but implemented somewhat differently). 35. Further mods to the Makefile to help Win32. Also, added code to pcregrep to allow it to read and process whole directories in Win32. This code was contributed by Lionel Fourquaux; it has not been tested by me. 36. Added support for named subpatterns. The Python syntax (?P...) is used to name a group. Names consist of alphanumerics and underscores, and must be unique. Back references use the syntax (?P=name) and recursive calls use (?P>name) which is a PCRE extension to the Python extension. Groups still have numbers. The function pcre_fullinfo() can be used after compilation to extract a name/number map. There are three relevant calls: PCRE_INFO_NAMEENTRYSIZE yields the size of each entry in the map PCRE_INFO_NAMECOUNT yields the number of entries PCRE_INFO_NAMETABLE yields a pointer to the map. The map is a vector of fixed-size entries. The size of each entry depends on the length of the longest name used. The first two bytes of each entry are the group number, most significant byte first. There follows the corresponding name, zero terminated. The names are in alphabetical order. 37. Make the maximum literal string in the compiled code 250 for the non-UTF-8 case instead of 255. Making it the same both with and without UTF-8 support means that the same test output works with both. 38. There was a case of malloc(0) in the POSIX testing code in pcretest. Avoid calling malloc() with a zero argument. 39. Change 25 above had to resort to a heavy-handed test for the .* anchoring optimization. I've improved things by keeping a bitmap of backreferences with numbers 1-31 so that if .* occurs inside capturing brackets that are not in fact referenced, the optimization can be applied. It is unlikely that a relevant occurrence of .* (i.e. one which might indicate anchoring or forcing the match to follow \n) will appear inside brackets with a number greater than 31, but if it does, any back reference > 31 suppresses the optimization. 40. Added a new compile-time option PCRE_NO_AUTO_CAPTURE. This has the effect of disabling numbered capturing parentheses. Any opening parenthesis that is not followed by ? behaves as if it were followed by ?: but named parentheses can still be used for capturing (and they will acquire numbers in the usual way). 41. Redesigned the return codes from the match() function into yes/no/error so that errors can be passed back from deep inside the nested calls. A malloc failure while inside a recursive subpattern call now causes the PCRE_ERROR_NOMEMORY return instead of quietly going wrong. 42. It is now possible to set a limit on the number of times the match() function is called in a call to pcre_exec(). This facility makes it possible to limit the amount of recursion and backtracking, though not in a directly obvious way, because the match() function is used in a number of different circumstances. The count starts from zero for each position in the subject string (for non-anchored patterns). The default limit is, for compatibility, a large number, namely 10 000 000. You can change this in two ways: (a) When configuring PCRE before making, you can use --with-match-limit=n to set a default value for the compiled library. (b) For each call to pcre_exec(), you can pass a pcre_extra block in which a different value is set. See 45 below. If the limit is exceeded, pcre_exec() returns PCRE_ERROR_MATCHLIMIT. 43. Added a new function pcre_config(int, void *) to enable run-time extraction of things that can be changed at compile time. The first argument specifies what is wanted and the second points to where the information is to be placed. The current list of available information is: PCRE_CONFIG_UTF8 The output is an integer that is set to one if UTF-8 support is available; otherwise it is set to zero. PCRE_CONFIG_NEWLINE The output is an integer that it set to the value of the code that is used for newline. It is either LF (10) or CR (13). PCRE_CONFIG_LINK_SIZE The output is an integer that contains the number of bytes used for internal linkage in compiled expressions. The value is 2, 3, or 4. See item 32 above. PCRE_CONFIG_POSIX_MALLOC_THRESHOLD The output is an integer that contains the threshold above which the POSIX interface uses malloc() for output vectors. See item 31 above. PCRE_CONFIG_MATCH_LIMIT The output is an unsigned integer that contains the default limit of the number of match() calls in a pcre_exec() execution. See 42 above. 44. pcretest has been upgraded by the addition of the -C option. This causes it to extract all the available output from the new pcre_config() function, and to output it. The program then exits immediately. 45. A need has arisen to pass over additional data with calls to pcre_exec() in order to support additional features. One way would have been to define pcre_exec2() (for example) with extra arguments, but this would not have been extensible, and would also have required all calls to the original function to be mapped to the new one. Instead, I have chosen to extend the mechanism that is used for passing in "extra" data from pcre_study(). The pcre_extra structure is now exposed and defined in pcre.h. It currently contains the following fields: flags a bitmap indicating which of the following fields are set study_data opaque data from pcre_study() match_limit a way of specifying a limit on match() calls for a specific call to pcre_exec() callout_data data for callouts (see 49 below) The flag bits are also defined in pcre.h, and are PCRE_EXTRA_STUDY_DATA PCRE_EXTRA_MATCH_LIMIT PCRE_EXTRA_CALLOUT_DATA The pcre_study() function now returns one of these new pcre_extra blocks, with the actual study data pointed to by the study_data field, and the PCRE_EXTRA_STUDY_DATA flag set. This can be passed directly to pcre_exec() as before. That is, this change is entirely upwards-compatible and requires no change to existing code. If you want to pass in additional data to pcre_exec(), you can either place it in a pcre_extra block provided by pcre_study(), or create your own pcre_extra block. 46. pcretest has been extended to test the PCRE_EXTRA_MATCH_LIMIT feature. If a data string contains the escape sequence \M, pcretest calls pcre_exec() several times with different match limits, until it finds the minimum value needed for pcre_exec() to complete. The value is then output. This can be instructive; for most simple matches the number is quite small, but for pathological cases it gets very large very quickly. 47. There's a new option for pcre_fullinfo() called PCRE_INFO_STUDYSIZE. It returns the size of the data block pointed to by the study_data field in a pcre_extra block, that is, the value that was passed as the argument to pcre_malloc() when PCRE was getting memory in which to place the information created by pcre_study(). The fourth argument should point to a size_t variable. pcretest has been extended so that this information is shown after a successful pcre_study() call when information about the compiled regex is being displayed. 48. Cosmetic change to Makefile: there's no need to have / after $(DESTDIR) because what follows is always an absolute path. (Later: it turns out that this is more than cosmetic for MinGW, because it doesn't like empty path components.) 49. Some changes have been made to the callout feature (see 28 above): (i) A callout function now has three choices for what it returns: 0 => success, carry on matching > 0 => failure at this point, but backtrack if possible < 0 => serious error, return this value from pcre_exec() Negative values should normally be chosen from the set of PCRE_ERROR_xxx values. In particular, returning PCRE_ERROR_NOMATCH forces a standard "match failed" error. The error number PCRE_ERROR_CALLOUT is reserved for use by callout functions. It will never be used by PCRE itself. (ii) The pcre_extra structure (see 45 above) has a void * field called callout_data, with corresponding flag bit PCRE_EXTRA_CALLOUT_DATA. The pcre_callout_block structure has a field of the same name. The contents of the field passed in the pcre_extra structure are passed to the callout function in the corresponding field in the callout block. This makes it easier to use the same callout-containing regex from multiple threads. For testing, the pcretest program has a new data escape \C*n pass the number n (may be negative) as callout_data If the callout function in pcretest receives a non-zero value as callout_data, it returns that value. 50. Makefile wasn't handling CFLAGS properly when compiling dftables. Also, there were some redundant $(CFLAGS) in commands that are now specified as $(LINK), which already includes $(CFLAGS). 51. Extensions to UTF-8 support are listed below. These all apply when (a) PCRE has been compiled with UTF-8 support *and* pcre_compile() has been compiled with the PCRE_UTF8 flag. Patterns that are compiled without that flag assume one-byte characters throughout. Note that case-insensitive matching applies only to characters whose values are less than 256. PCRE doesn't support the notion of cases for higher-valued characters. (i) A character class whose characters are all within 0-255 is handled as a bit map, and the map is inverted for negative classes. Previously, a character > 255 always failed to match such a class; however it should match if the class was a negative one (e.g. [^ab]). This has been fixed. (ii) A negated character class with a single character < 255 is coded as "not this character" (OP_NOT). This wasn't working properly when the test character was multibyte, either singly or repeated. (iii) Repeats of multibyte characters are now handled correctly in UTF-8 mode, for example: \x{100}{2,3}. (iv) The character escapes \b, \B, \d, \D, \s, \S, \w, and \W (either singly or repeated) now correctly test multibyte characters. However, PCRE doesn't recognize any characters with values greater than 255 as digits, spaces, or word characters. Such characters always match \D, \S, and \W, and never match \d, \s, or \w. (v) Classes may now contain characters and character ranges with values greater than 255. For example: [ab\x{100}-\x{400}]. (vi) pcregrep now has a --utf-8 option (synonym -u) which makes it call PCRE in UTF-8 mode. 52. The info request value PCRE_INFO_FIRSTCHAR has been renamed PCRE_INFO_FIRSTBYTE because it is a byte value. However, the old name is retained for backwards compatibility. (Note that LASTLITERAL is also a byte value.) 53. The single man page has become too large. I have therefore split it up into a number of separate man pages. These also give rise to individual HTML pages; these are now put in a separate directory, and there is an index.html page that lists them all. Some hyperlinking between the pages has been installed. 54. Added convenience functions for handling named capturing parentheses. 55. Unknown escapes inside character classes (e.g. [\M]) and escapes that aren't interpreted therein (e.g. [\C]) are literals in Perl. This is now also true in PCRE, except when the PCRE_EXTENDED option is set, in which case they are faulted. 56. Introduced HOST_CC and HOST_CFLAGS which can be set in the environment when calling configure. These values are used when compiling the dftables.c program which is run to generate the source of the default character tables. They default to the values of CC and CFLAGS. If you are cross-compiling PCRE, you will need to set these values. 57. Updated the building process for Windows DLL, as provided by Fred Cox. Version 3.9 02-Jan-02 --------------------- 1. A bit of extraneous text had somehow crept into the pcregrep documentation. 2. If --disable-static was given, the building process failed when trying to build pcretest and pcregrep. (For some reason it was using libtool to compile them, which is not right, as they aren't part of the library.) Version 3.8 18-Dec-01 --------------------- 1. The experimental UTF-8 code was completely screwed up. It was packing the bytes in the wrong order. How dumb can you get? Version 3.7 29-Oct-01 --------------------- 1. In updating pcretest to check change 1 of version 3.6, I screwed up. This caused pcretest, when used on the test data, to segfault. Unfortunately, this didn't happen under Solaris 8, where I normally test things. 2. The Makefile had to be changed to make it work on BSD systems, where 'make' doesn't seem to recognize that ./xxx and xxx are the same file. (This entry isn't in ChangeLog distributed with 3.7 because I forgot when I hastily made this fix an hour or so after the initial 3.7 release.) Version 3.6 23-Oct-01 --------------------- 1. Crashed with /(sens|respons)e and \1ibility/ and "sense and sensibility" if offsets passed as NULL with zero offset count. 2. The config.guess and config.sub files had not been updated when I moved to the latest autoconf. Version 3.5 15-Aug-01 --------------------- 1. Added some missing #if !defined NOPOSIX conditionals in pcretest.c that had been forgotten. 2. By using declared but undefined structures, we can avoid using "void" definitions in pcre.h while keeping the internal definitions of the structures private. 3. The distribution is now built using autoconf 2.50 and libtool 1.4. From a user point of view, this means that both static and shared libraries are built by default, but this can be individually controlled. More of the work of handling this static/shared cases is now inside libtool instead of PCRE's make file. 4. The pcretest utility is now installed along with pcregrep because it is useful for users (to test regexs) and by doing this, it automatically gets relinked by libtool. The documentation has been turned into a man page, so there are now .1, .txt, and .html versions in /doc. 5. Upgrades to pcregrep: (i) Added long-form option names like gnu grep. (ii) Added --help to list all options with an explanatory phrase. (iii) Added -r, --recursive to recurse into sub-directories. (iv) Added -f, --file to read patterns from a file. 6. pcre_exec() was referring to its "code" argument before testing that argument for NULL (and giving an error if it was NULL). 7. Upgraded Makefile.in to allow for compiling in a different directory from the source directory. 8. Tiny buglet in pcretest: when pcre_fullinfo() was called to retrieve the options bits, the pointer it was passed was to an int instead of to an unsigned long int. This mattered only on 64-bit systems. 9. Fixed typo (3.4/1) in pcre.h again. Sigh. I had changed pcre.h (which is generated) instead of pcre.in, which it its source. Also made the same change in several of the .c files. 10. A new release of gcc defines printf() as a macro, which broke pcretest because it had an ifdef in the middle of a string argument for printf(). Fixed by using separate calls to printf(). 11. Added --enable-newline-is-cr and --enable-newline-is-lf to the configure script, to force use of CR or LF instead of \n in the source. On non-Unix systems, the value can be set in config.h. 12. The limit of 200 on non-capturing parentheses is a _nesting_ limit, not an absolute limit. Changed the text of the error message to make this clear, and likewise updated the man page. 13. The limit of 99 on the number of capturing subpatterns has been removed. The new limit is 65535, which I hope will not be a "real" limit. Version 3.4 22-Aug-00 --------------------- 1. Fixed typo in pcre.h: unsigned const char * changed to const unsigned char *. 2. Diagnose condition (?(0) as an error instead of crashing on matching. Version 3.3 01-Aug-00 --------------------- 1. If an octal character was given, but the value was greater than \377, it was not getting masked to the least significant bits, as documented. This could lead to crashes in some systems. 2. Perl 5.6 (if not earlier versions) accepts classes like [a-\d] and treats the hyphen as a literal. PCRE used to give an error; it now behaves like Perl. 3. Added the functions pcre_free_substring() and pcre_free_substring_list(). These just pass their arguments on to (pcre_free)(), but they are provided because some uses of PCRE bind it to non-C systems that can call its functions, but cannot call free() or pcre_free() directly. 4. Add "make test" as a synonym for "make check". Corrected some comments in the Makefile. 5. Add $(DESTDIR)/ in front of all the paths in the "install" target in the Makefile. 6. Changed the name of pgrep to pcregrep, because Solaris has introduced a command called pgrep for grepping around the active processes. 7. Added the beginnings of support for UTF-8 character strings. 8. Arranged for the Makefile to pass over the settings of CC, CFLAGS, and RANLIB to ./ltconfig so that they are used by libtool. I think these are all the relevant ones. (AR is not passed because ./ltconfig does its own figuring out for the ar command.) Version 3.2 12-May-00 --------------------- This is purely a bug fixing release. 1. If the pattern /((Z)+|A)*/ was matched agained ZABCDEFG it matched Z instead of ZA. This was just one example of several cases that could provoke this bug, which was introduced by change 9 of version 2.00. The code for breaking infinite loops after an iteration that matches an empty string was't working correctly. 2. The pcretest program was not imitating Perl correctly for the pattern /a*/g when matched against abbab (for example). After matching an empty string, it wasn't forcing anchoring when setting PCRE_NOTEMPTY for the next attempt; this caused it to match further down the string than it should. 3. The code contained an inclusion of sys/types.h. It isn't clear why this was there because it doesn't seem to be needed, and it causes trouble on some systems, as it is not a Standard C header. It has been removed. 4. Made 4 silly changes to the source to avoid stupid compiler warnings that were reported on the Macintosh. The changes were from while ((c = *(++ptr)) != 0 && c != '\n'); to while ((c = *(++ptr)) != 0 && c != '\n') ; Totally extraordinary, but if that's what it takes... 5. PCRE is being used in one environment where neither memmove() nor bcopy() is available. Added HAVE_BCOPY and an autoconf test for it; if neither HAVE_MEMMOVE nor HAVE_BCOPY is set, use a built-in emulation function which assumes the way PCRE uses memmove() (always moving upwards). 6. PCRE is being used in one environment where strchr() is not available. There was only one use in pcre.c, and writing it out to avoid strchr() probably gives faster code anyway. Version 3.1 09-Feb-00 --------------------- The only change in this release is the fixing of some bugs in Makefile.in for the "install" target: (1) It was failing to install pcreposix.h. (2) It was overwriting the pcre.3 man page with the pcreposix.3 man page. Version 3.0 01-Feb-00 --------------------- 1. Add support for the /+ modifier to perltest (to output $` like it does in pcretest). 2. Add support for the /g modifier to perltest. 3. Fix pcretest so that it behaves even more like Perl for /g when the pattern matches null strings. 4. Fix perltest so that it doesn't do unwanted things when fed an empty pattern. Perl treats empty patterns specially - it reuses the most recent pattern, which is not what we want. Replace // by /(?#)/ in order to avoid this effect. 5. The POSIX interface was broken in that it was just handing over the POSIX captured string vector to pcre_exec(), but (since release 2.00) PCRE has required a bigger vector, with some working space on the end. This means that the POSIX wrapper now has to get and free some memory, and copy the results. 6. Added some simple autoconf support, placing the test data and the documentation in separate directories, re-organizing some of the information files, and making it build pcre-config (a GNU standard). Also added libtool support for building PCRE as a shared library, which is now the default. 7. Got rid of the leading zero in the definition of PCRE_MINOR because 08 and 09 are not valid octal constants. Single digits will be used for minor values less than 10. 8. Defined REG_EXTENDED and REG_NOSUB as zero in the POSIX header, so that existing programs that set these in the POSIX interface can use PCRE without modification. 9. Added a new function, pcre_fullinfo() with an extensible interface. It can return all that pcre_info() returns, plus additional data. The pcre_info() function is retained for compatibility, but is considered to be obsolete. 10. Added experimental recursion feature (?R) to handle one common case that Perl 5.6 will be able to do with (?p{...}). 11. Added support for POSIX character classes like [:alpha:], which Perl is adopting. Version 2.08 31-Aug-99 ---------------------- 1. When startoffset was not zero and the pattern began with ".*", PCRE was not trying to match at the startoffset position, but instead was moving forward to the next newline as if a previous match had failed. 2. pcretest was not making use of PCRE_NOTEMPTY when repeating for /g and /G, and could get into a loop if a null string was matched other than at the start of the subject. 3. Added definitions of PCRE_MAJOR and PCRE_MINOR to pcre.h so the version can be distinguished at compile time, and for completeness also added PCRE_DATE. 5. Added Paul Sokolovsky's minor changes to make it easy to compile a Win32 DLL in GnuWin32 environments. Version 2.07 29-Jul-99 ---------------------- 1. The documentation is now supplied in plain text form and HTML as well as in the form of man page sources. 2. C++ compilers don't like assigning (void *) values to other pointer types. In particular this affects malloc(). Although there is no problem in Standard C, I've put in casts to keep C++ compilers happy. 3. Typo on pcretest.c; a cast of (unsigned char *) in the POSIX regexec() call should be (const char *). 4. If NOPOSIX is defined, pcretest.c compiles without POSIX support. This may be useful for non-Unix systems who don't want to bother with the POSIX stuff. However, I haven't made this a standard facility. The documentation doesn't mention it, and the Makefile doesn't support it. 5. The Makefile now contains an "install" target, with editable destinations at the top of the file. The pcretest program is not installed. 6. pgrep -V now gives the PCRE version number and date. 7. Fixed bug: a zero repetition after a literal string (e.g. /abcde{0}/) was causing the entire string to be ignored, instead of just the last character. 8. If a pattern like /"([^\\"]+|\\.)*"/ is applied in the normal way to a non-matching string, it can take a very, very long time, even for strings of quite modest length, because of the nested recursion. PCRE now does better in some of these cases. It does this by remembering the last required literal character in the pattern, and pre-searching the subject to ensure it is present before running the real match. In other words, it applies a heuristic to detect some types of certain failure quickly, and in the above example, if presented with a string that has no trailing " it gives "no match" very quickly. 9. A new runtime option PCRE_NOTEMPTY causes null string matches to be ignored; other alternatives are tried instead. Version 2.06 09-Jun-99 ---------------------- 1. Change pcretest's output for amount of store used to show just the code space, because the remainder (the data block) varies in size between 32-bit and 64-bit systems. 2. Added an extra argument to pcre_exec() to supply an offset in the subject to start matching at. This allows lookbehinds to work when searching for multiple occurrences in a string. 3. Added additional options to pcretest for testing multiple occurrences: /+ outputs the rest of the string that follows a match /g loops for multiple occurrences, using the new startoffset argument /G loops for multiple occurrences by passing an incremented pointer 4. PCRE wasn't doing the "first character" optimization for patterns starting with \b or \B, though it was doing it for other lookbehind assertions. That is, it wasn't noticing that a match for a pattern such as /\bxyz/ has to start with the letter 'x'. On long subject strings, this gives a significant speed-up. Version 2.05 21-Apr-99 ---------------------- 1. Changed the type of magic_number from int to long int so that it works properly on 16-bit systems. 2. Fixed a bug which caused patterns starting with .* not to work correctly when the subject string contained newline characters. PCRE was assuming anchoring for such patterns in all cases, which is not correct because .* will not pass a newline unless PCRE_DOTALL is set. It now assumes anchoring only if DOTALL is set at top level; otherwise it knows that patterns starting with .* must be retried after every newline in the subject. Version 2.04 18-Feb-99 ---------------------- 1. For parenthesized subpatterns with repeats whose minimum was zero, the computation of the store needed to hold the pattern was incorrect (too large). If such patterns were nested a few deep, this could multiply and become a real problem. 2. Added /M option to pcretest to show the memory requirement of a specific pattern. Made -m a synonym of -s (which does this globally) for compatibility. 3. Subpatterns of the form (regex){n,m} (i.e. limited maximum) were being compiled in such a way that the backtracking after subsequent failure was pessimal. Something like (a){0,3} was compiled as (a)?(a)?(a)? instead of ((a)((a)(a)?)?)? with disastrous performance if the maximum was of any size. Version 2.03 02-Feb-99 ---------------------- 1. Fixed typo and small mistake in man page. 2. Added 4th condition (GPL supersedes if conflict) and created separate LICENCE file containing the conditions. 3. Updated pcretest so that patterns such as /abc\/def/ work like they do in Perl, that is the internal \ allows the delimiter to be included in the pattern. Locked out the use of \ as a delimiter. If \ immediately follows the final delimiter, add \ to the end of the pattern (to test the error). 4. Added the convenience functions for extracting substrings after a successful match. Updated pcretest to make it able to test these functions. Version 2.02 14-Jan-99 ---------------------- 1. Initialized the working variables associated with each extraction so that their saving and restoring doesn't refer to uninitialized store. 2. Put dummy code into study.c in order to trick the optimizer of the IBM C compiler for OS/2 into generating correct code. Apparently IBM isn't going to fix the problem. 3. Pcretest: the timing code wasn't using LOOPREPEAT for timing execution calls, and wasn't printing the correct value for compiling calls. Increased the default value of LOOPREPEAT, and the number of significant figures in the times. 4. Changed "/bin/rm" in the Makefile to "-rm" so it works on Windows NT. 5. Renamed "deftables" as "dftables" to get it down to 8 characters, to avoid a building problem on Windows NT with a FAT file system. Version 2.01 21-Oct-98 ---------------------- 1. Changed the API for pcre_compile() to allow for the provision of a pointer to character tables built by pcre_maketables() in the current locale. If NULL is passed, the default tables are used. Version 2.00 24-Sep-98 ---------------------- 1. Since the (>?) facility is in Perl 5.005, don't require PCRE_EXTRA to enable it any more. 2. Allow quantification of (?>) groups, and make it work correctly. 3. The first character computation wasn't working for (?>) groups. 4. Correct the implementation of \Z (it is permitted to match on the \n at the end of the subject) and add 5.005's \z, which really does match only at the very end of the subject. 5. Remove the \X "cut" facility; Perl doesn't have it, and (?> is neater. 6. Remove the ability to specify CASELESS, MULTILINE, DOTALL, and DOLLAR_END_ONLY at runtime, to make it possible to implement the Perl 5.005 localized options. All options to pcre_study() were also removed. 7. Add other new features from 5.005: $(?<= positive lookbehind $(?a*))*/ (a PCRE_EXTRA facility). Version 1.00 18-Nov-97 ---------------------- 1. Added compile-time macros to support systems such as SunOS4 which don't have memmove() or strerror() but have other things that can be used instead. 2. Arranged that "make clean" removes the executables. Version 0.99 27-Oct-97 ---------------------- 1. Fixed bug in code for optimizing classes with only one character. It was initializing a 32-byte map regardless, which could cause it to run off the end of the memory it had got. 2. Added, conditional on PCRE_EXTRA, the proposed (?>REGEX) construction. Version 0.98 22-Oct-97 ---------------------- 1. Fixed bug in code for handling temporary memory usage when there are more back references than supplied space in the ovector. This could cause segfaults. Version 0.97 21-Oct-97 ---------------------- 1. Added the \X "cut" facility, conditional on PCRE_EXTRA. 2. Optimized negated single characters not to use a bit map. 3. Brought error texts together as macro definitions; clarified some of them; fixed one that was wrong - it said "range out of order" when it meant "invalid escape sequence". 4. Changed some char * arguments to const char *. 5. Added PCRE_NOTBOL and PCRE_NOTEOL (from POSIX). 6. Added the POSIX-style API wrapper in pcreposix.a and testing facilities in pcretest. Version 0.96 16-Oct-97 ---------------------- 1. Added a simple "pgrep" utility to the distribution. 2. Fixed an incompatibility with Perl: "{" is now treated as a normal character unless it appears in one of the precise forms "{ddd}", "{ddd,}", or "{ddd,ddd}" where "ddd" means "one or more decimal digits". 3. Fixed serious bug. If a pattern had a back reference, but the call to pcre_exec() didn't supply a large enough ovector to record the related identifying subpattern, the match always failed. PCRE now remembers the number of the largest back reference, and gets some temporary memory in which to save the offsets during matching if necessary, in order to ensure that backreferences always work. 4. Increased the compatibility with Perl in a number of ways: (a) . no longer matches \n by default; an option PCRE_DOTALL is provided to request this handling. The option can be set at compile or exec time. (b) $ matches before a terminating newline by default; an option PCRE_DOLLAR_ENDONLY is provided to override this (but not in multiline mode). The option can be set at compile or exec time. (c) The handling of \ followed by a digit other than 0 is now supposed to be the same as Perl's. If the decimal number it represents is less than 10 or there aren't that many previous left capturing parentheses, an octal escape is read. Inside a character class, it's always an octal escape, even if it is a single digit. (d) An escaped but undefined alphabetic character is taken as a literal, unless PCRE_EXTRA is set. Currently this just reserves the remaining escapes. (e) {0} is now permitted. (The previous item is removed from the compiled pattern). 5. Changed all the names of code files so that the basic parts are no longer than 10 characters, and abolished the teeny "globals.c" file. 6. Changed the handling of character classes; they are now done with a 32-byte bit map always. 7. Added the -d and /D options to pcretest to make it possible to look at the internals of compilation without having to recompile pcre. Version 0.95 23-Sep-97 ---------------------- 1. Fixed bug in pre-pass concerning escaped "normal" characters such as \x5c or \x20 at the start of a run of normal characters. These were being treated as real characters, instead of the source characters being re-checked. Version 0.94 18-Sep-97 ---------------------- 1. The functions are now thread-safe, with the caveat that the global variables containing pointers to malloc() and free() or alternative functions are the same for all threads. 2. Get pcre_study() to generate a bitmap of initial characters for non- anchored patterns when this is possible, and use it if passed to pcre_exec(). Version 0.93 15-Sep-97 ---------------------- 1. /(b)|(:+)/ was computing an incorrect first character. 2. Add pcre_study() to the API and the passing of pcre_extra to pcre_exec(), but not actually doing anything yet. 3. Treat "-" characters in classes that cannot be part of ranges as literals, as Perl does (e.g. [-az] or [az-]). 4. Set the anchored flag if a branch starts with .* or .*? because that tests all possible positions. 5. Split up into different modules to avoid including unneeded functions in a compiled binary. However, compile and exec are still in one module. The "study" function is split off. 6. The character tables are now in a separate module whose source is generated by an auxiliary program - but can then be edited by hand if required. There are now no calls to isalnum(), isspace(), isdigit(), isxdigit(), tolower() or toupper() in the code. 7. Turn the malloc/free funtions variables into pcre_malloc and pcre_free and make them global. Abolish the function for setting them, as the caller can now set them directly. Version 0.92 11-Sep-97 ---------------------- 1. A repeat with a fixed maximum and a minimum of 1 for an ordinary character (e.g. /a{1,3}/) was broken (I mis-optimized it). 2. Caseless matching was not working in character classes if the characters in the pattern were in upper case. 3. Make ranges like [W-c] work in the same way as Perl for caseless matching. 4. Make PCRE_ANCHORED public and accept as a compile option. 5. Add an options word to pcre_exec() and accept PCRE_ANCHORED and PCRE_CASELESS at run time. Add escapes \A and \I to pcretest to cause it to pass them. 6. Give an error if bad option bits passed at compile or run time. 7. Add PCRE_MULTILINE at compile and exec time, and (?m) as well. Add \M to pcretest to cause it to pass that flag. 8. Add pcre_info(), to get the number of identifying subpatterns, the stored options, and the first character, if set. 9. Recognize C+ or C{n,m} where n >= 1 as providing a fixed starting character. Version 0.91 10-Sep-97 ---------------------- 1. PCRE was failing to diagnose unlimited repeats of subpatterns that could match the empty string as in /(a*)*/. It was looping and ultimately crashing. 2. PCRE was looping on encountering an indefinitely repeated back reference to a subpattern that had matched an empty string, e.g. /(a|)\1*/. It now does what Perl does - treats the match as successful. **** libsynthesis-3.4.0.47.1/src/pcre/CleanTxt000066400000000000000000000055751226375725500200450ustar00rootroot00000000000000#! /usr/bin/perl -w # Script to take the output of nroff -man and remove all the backspacing and # the page footers and the screen commands etc so that it is more usefully # readable online. In fact, in the latest nroff, intermediate footers don't # seem to be generated any more. $blankcount = 0; $lastwascut = 0; $firstheader = 1; # Input on STDIN; output to STDOUT. while () { s/\x1b\[\d+m//g; # Remove screen controls "ESC [ number m" s/.\x8//g; # Remove "char, backspace" # Handle header lines. Retain only the first one we encounter, but remove # the blank line that follows. Any others (e.g. at end of document) and the # following blank line are dropped. if (/^PCRE(\w*)\(([13])\)\s+PCRE\1\(\2\)$/) { if ($firstheader) { $firstheader = 0; print; $lastprinted = $_; $lastwascut = 0; } $_=; # Remove a blank that follows next; } # Count runs of empty lines if (/^\s*$/) { $blankcount++; $lastwascut = 0; next; } # If a chunk of lines has been cut out (page footer) and the next line # has a different indentation, put back one blank line. if ($lastwascut && $blankcount < 1 && defined($lastprinted)) { ($a) = $lastprinted =~ /^(\s*)/; ($b) = $_ =~ /^(\s*)/; $blankcount++ if ($a ne $b); } # We get here only when we have a non-blank line in hand. If it was preceded # by 3 or more blank lines, read the next 3 lines and see if they are blank. # If so, remove all 7 lines, and remember that we have just done a cut. if ($blankcount >= 3) { for ($i = 0; $i < 3; $i++) { $next[$i] = ; $next[$i] = "" if !defined $next[$i]; $next[$i] =~ s/\x1b\[\d+m//g; # Remove screen controls "ESC [ number m" $next[$i] =~ s/.\x8//g; # Remove "char, backspace" } # Cut out chunks of the form <3 blanks><3 blanks> if ($next[0] =~ /^\s*$/ && $next[1] =~ /^\s*$/ && $next[2] =~ /^\s*$/) { $blankcount -= 3; $lastwascut = 1; } # Otherwise output the saved blanks, the current, and the next three # lines. Remember the last printed line. else { for ($i = 0; $i < $blankcount; $i++) { print "\n"; } print; for ($i = 0; $i < 3; $i++) { $next[$i] =~ s/.\x8//g; print $next[$i]; $lastprinted = $_; } $lastwascut = 0; $blankcount = 0; } } # This non-blank line is not preceded by 3 or more blank lines. Output # any blanks there are, and the line. Remember it. Force two blank lines # before headings. else { $blankcount = 2 if /^\S/ && !/^Last updated/ && !/^Copyright/ && defined($lastprinted); for ($i = 0; $i < $blankcount; $i++) { print "\n"; } print; $lastprinted = $_; $lastwascut = 0; $blankcount = 0; } } # End libsynthesis-3.4.0.47.1/src/pcre/Detrail000066400000000000000000000012031226375725500176670ustar00rootroot00000000000000#!/usr/bin/perl # This is a script for removing trailing whitespace from lines in files that # are listed on the command line. # This subroutine does the work for one file. sub detrail { my($file) = $_[0]; my($changed) = 0; open(IN, "$file") || die "Can't open $file for input"; @lines = ; close(IN); foreach (@lines) { if (/\s+\n$/) { s/\s+\n$/\n/; $changed = 1; } } if ($changed) { open(OUT, ">$file") || die "Can't open $file for output"; print OUT @lines; close(OUT); } } # This is the main program $, = ""; # Output field separator for ($i = 0; $i < @ARGV; $i++) { &detrail($ARGV[$i]); } # End libsynthesis-3.4.0.47.1/src/pcre/HACKING000066400000000000000000000421711226375725500173600ustar00rootroot00000000000000Technical Notes about PCRE -------------------------- These are very rough technical notes that record potentially useful information about PCRE internals. Historical note 1 ----------------- Many years ago I implemented some regular expression functions to an algorithm suggested by Martin Richards. These were not Unix-like in form, and were quite restricted in what they could do by comparison with Perl. The interesting part about the algorithm was that the amount of space required to hold the compiled form of an expression was known in advance. The code to apply an expression did not operate by backtracking, as the original Henry Spencer code and current Perl code does, but instead checked all possibilities simultaneously by keeping a list of current states and checking all of them as it advanced through the subject string. In the terminology of Jeffrey Friedl's book, it was a "DFA algorithm", though it was not a traditional Finite State Machine (FSM). When the pattern was all used up, all remaining states were possible matches, and the one matching the longest subset of the subject string was chosen. This did not necessarily maximize the individual wild portions of the pattern, as is expected in Unix and Perl-style regular expressions. Historical note 2 ----------------- By contrast, the code originally written by Henry Spencer (which was subsequently heavily modified for Perl) compiles the expression twice: once in a dummy mode in order to find out how much store will be needed, and then for real. (The Perl version probably doesn't do this any more; I'm talking about the original library.) The execution function operates by backtracking and maximizing (or, optionally, minimizing in Perl) the amount of the subject that matches individual wild portions of the pattern. This is an "NFA algorithm" in Friedl's terminology. OK, here's the real stuff ------------------------- For the set of functions that form the "basic" PCRE library (which are unrelated to those mentioned above), I tried at first to invent an algorithm that used an amount of store bounded by a multiple of the number of characters in the pattern, to save on compiling time. However, because of the greater complexity in Perl regular expressions, I couldn't do this. In any case, a first pass through the pattern is helpful for other reasons. Computing the memory requirement: how it was -------------------------------------------- Up to and including release 6.7, PCRE worked by running a very degenerate first pass to calculate a maximum store size, and then a second pass to do the real compile - which might use a bit less than the predicted amount of memory. The idea was that this would turn out faster than the Henry Spencer code because the first pass is degenerate and the second pass can just store stuff straight into the vector, which it knows is big enough. Computing the memory requirement: how it is ------------------------------------------- By the time I was working on a potential 6.8 release, the degenerate first pass had become very complicated and hard to maintain. Indeed one of the early things I did for 6.8 was to fix Yet Another Bug in the memory computation. Then I had a flash of inspiration as to how I could run the real compile function in a "fake" mode that enables it to compute how much memory it would need, while actually only ever using a few hundred bytes of working memory, and without too many tests of the mode that might slow it down. So I re-factored the compiling functions to work this way. This got rid of about 600 lines of source. It should make future maintenance and development easier. As this was such a major change, I never released 6.8, instead upping the number to 7.0 (other quite major changes are also present in the 7.0 release). A side effect of this work is that the previous limit of 200 on the nesting depth of parentheses was removed. However, there is a downside: pcre_compile() runs more slowly than before (30% or more, depending on the pattern) because it is doing a full analysis of the pattern. My hope is that this is not a big issue. Traditional matching function ----------------------------- The "traditional", and original, matching function is called pcre_exec(), and it implements an NFA algorithm, similar to the original Henry Spencer algorithm and the way that Perl works. Not surprising, since it is intended to be as compatible with Perl as possible. This is the function most users of PCRE will use most of the time. Supplementary matching function ------------------------------- From PCRE 6.0, there is also a supplementary matching function called pcre_dfa_exec(). This implements a DFA matching algorithm that searches simultaneously for all possible matches that start at one point in the subject string. (Going back to my roots: see Historical Note 1 above.) This function intreprets the same compiled pattern data as pcre_exec(); however, not all the facilities are available, and those that are do not always work in quite the same way. See the user documentation for details. The algorithm that is used for pcre_dfa_exec() is not a traditional FSM, because it may have a number of states active at one time. More work would be needed at compile time to produce a traditional FSM where only one state is ever active at once. I believe some other regex matchers work this way. Format of compiled patterns --------------------------- The compiled form of a pattern is a vector of bytes, containing items of variable length. The first byte in an item is an opcode, and the length of the item is either implicit in the opcode or contained in the data bytes that follow it. In many cases below LINK_SIZE data values are specified for offsets within the compiled pattern. The default value for LINK_SIZE is 2, but PCRE can be compiled to use 3-byte or 4-byte values for these offsets (impairing the performance). This is necessary only when patterns whose compiled length is greater than 64K are going to be processed. In this description, we assume the "normal" compilation options. Data values that are counts (e.g. for quantifiers) are always just two bytes long. A list of the opcodes follows: Opcodes with no following data ------------------------------ These items are all just one byte long OP_END end of pattern OP_ANY match any character OP_ANYBYTE match any single byte, even in UTF-8 mode OP_SOD match start of data: \A OP_SOM, start of match (subject + offset): \G OP_SET_SOM, set start of match (\K) OP_CIRC ^ (start of data, or after \n in multiline) OP_NOT_WORD_BOUNDARY \W OP_WORD_BOUNDARY \w OP_NOT_DIGIT \D OP_DIGIT \d OP_NOT_HSPACE \H OP_HSPACE \h OP_NOT_WHITESPACE \S OP_WHITESPACE \s OP_NOT_VSPACE \V OP_VSPACE \v OP_NOT_WORDCHAR \W OP_WORDCHAR \w OP_EODN match end of data or \n at end: \Z OP_EOD match end of data: \z OP_DOLL $ (end of data, or before \n in multiline) OP_EXTUNI match an extended Unicode character OP_ANYNL match any Unicode newline sequence OP_ACCEPT ) OP_COMMIT ) OP_FAIL ) These are Perl 5.10's "backtracking OP_PRUNE ) control verbs". OP_SKIP ) OP_THEN ) Repeating single characters --------------------------- The common repeats (*, +, ?) when applied to a single character use the following opcodes: OP_STAR OP_MINSTAR OP_POSSTAR OP_PLUS OP_MINPLUS OP_POSPLUS OP_QUERY OP_MINQUERY OP_POSQUERY In ASCII mode, these are two-byte items; in UTF-8 mode, the length is variable. Those with "MIN" in their name are the minimizing versions. Those with "POS" in their names are possessive versions. Each is followed by the character that is to be repeated. Other repeats make use of OP_UPTO OP_MINUPTO OP_POSUPTO OP_EXACT which are followed by a two-byte count (most significant first) and the repeated character. OP_UPTO matches from 0 to the given number. A repeat with a non-zero minimum and a fixed maximum is coded as an OP_EXACT followed by an OP_UPTO (or OP_MINUPTO or OPT_POSUPTO). Repeating character types ------------------------- Repeats of things like \d are done exactly as for single characters, except that instead of a character, the opcode for the type is stored in the data byte. The opcodes are: OP_TYPESTAR OP_TYPEMINSTAR OP_TYPEPOSSTAR OP_TYPEPLUS OP_TYPEMINPLUS OP_TYPEPOSPLUS OP_TYPEQUERY OP_TYPEMINQUERY OP_TYPEPOSQUERY OP_TYPEUPTO OP_TYPEMINUPTO OP_TYPEPOSUPTO OP_TYPEEXACT Match by Unicode property ------------------------- OP_PROP and OP_NOTPROP are used for positive and negative matches of a character by testing its Unicode property (the \p and \P escape sequences). Each is followed by two bytes that encode the desired property as a type and a value. Repeats of these items use the OP_TYPESTAR etc. set of opcodes, followed by three bytes: OP_PROP or OP_NOTPROP and then the desired property type and value. Matching literal characters --------------------------- The OP_CHAR opcode is followed by a single character that is to be matched casefully. For caseless matching, OP_CHARNC is used. In UTF-8 mode, the character may be more than one byte long. (Earlier versions of PCRE used multi-character strings, but this was changed to allow some new features to be added.) Character classes ----------------- If there is only one character, OP_CHAR or OP_CHARNC is used for a positive class, and OP_NOT for a negative one (that is, for something like [^a]). However, in UTF-8 mode, the use of OP_NOT applies only to characters with values < 128, because OP_NOT is confined to single bytes. Another set of repeating opcodes (OP_NOTSTAR etc.) are used for a repeated, negated, single-character class. The normal ones (OP_STAR etc.) are used for a repeated positive single-character class. When there's more than one character in a class and all the characters are less than 256, OP_CLASS is used for a positive class, and OP_NCLASS for a negative one. In either case, the opcode is followed by a 32-byte bit map containing a 1 bit for every character that is acceptable. The bits are counted from the least significant end of each byte. The reason for having both OP_CLASS and OP_NCLASS is so that, in UTF-8 mode, subject characters with values greater than 256 can be handled correctly. For OP_CLASS they don't match, whereas for OP_NCLASS they do. For classes containing characters with values > 255, OP_XCLASS is used. It optionally uses a bit map (if any characters lie within it), followed by a list of pairs and single characters. There is a flag character than indicates whether it's a positive or a negative class. Back references --------------- OP_REF is followed by two bytes containing the reference number. Repeating character classes and back references ----------------------------------------------- Single-character classes are handled specially (see above). This section applies to OP_CLASS and OP_REF. In both cases, the repeat information follows the base item. The matching code looks at the following opcode to see if it is one of OP_CRSTAR OP_CRMINSTAR OP_CRPLUS OP_CRMINPLUS OP_CRQUERY OP_CRMINQUERY OP_CRRANGE OP_CRMINRANGE All but the last two are just single-byte items. The others are followed by four bytes of data, comprising the minimum and maximum repeat counts. There are no special possessive opcodes for these repeats; a possessive repeat is compiled into an atomic group. Brackets and alternation ------------------------ A pair of non-capturing (round) brackets is wrapped round each expression at compile time, so alternation always happens in the context of brackets. [Note for North Americans: "bracket" to some English speakers, including myself, can be round, square, curly, or pointy. Hence this usage.] Non-capturing brackets use the opcode OP_BRA. Originally PCRE was limited to 99 capturing brackets and it used a different opcode for each one. From release 3.5, the limit was removed by putting the bracket number into the data for higher-numbered brackets. From release 7.0 all capturing brackets are handled this way, using the single opcode OP_CBRA. A bracket opcode is followed by LINK_SIZE bytes which give the offset to the next alternative OP_ALT or, if there aren't any branches, to the matching OP_KET opcode. Each OP_ALT is followed by LINK_SIZE bytes giving the offset to the next one, or to the OP_KET opcode. For capturing brackets, the bracket number immediately follows the offset, always as a 2-byte item. OP_KET is used for subpatterns that do not repeat indefinitely, while OP_KETRMIN and OP_KETRMAX are used for indefinite repetitions, minimally or maximally respectively. All three are followed by LINK_SIZE bytes giving (as a positive number) the offset back to the matching bracket opcode. If a subpattern is quantified such that it is permitted to match zero times, it is preceded by one of OP_BRAZERO or OP_BRAMINZERO. These are single-byte opcodes which tell the matcher that skipping this subpattern entirely is a valid branch. A subpattern with an indefinite maximum repetition is replicated in the compiled data its minimum number of times (or once with OP_BRAZERO if the minimum is zero), with the final copy terminating with OP_KETRMIN or OP_KETRMAX as appropriate. A subpattern with a bounded maximum repetition is replicated in a nested fashion up to the maximum number of times, with OP_BRAZERO or OP_BRAMINZERO before each replication after the minimum, so that, for example, (abc){2,5} is compiled as (abc)(abc)((abc)((abc)(abc)?)?)?, except that each bracketed group has the same number. When a repeated subpattern has an unbounded upper limit, it is checked to see whether it could match an empty string. If this is the case, the opcode in the final replication is changed to OP_SBRA or OP_SCBRA. This tells the matcher that it needs to check for matching an empty string when it hits OP_KETRMIN or OP_KETRMAX, and if so, to break the loop. Assertions ---------- Forward assertions are just like other subpatterns, but starting with one of the opcodes OP_ASSERT or OP_ASSERT_NOT. Backward assertions use the opcodes OP_ASSERTBACK and OP_ASSERTBACK_NOT, and the first opcode inside the assertion is OP_REVERSE, followed by a two byte count of the number of characters to move back the pointer in the subject string. When operating in UTF-8 mode, the count is a character count rather than a byte count. A separate count is present in each alternative of a lookbehind assertion, allowing them to have different fixed lengths. Once-only (atomic) subpatterns ------------------------------ These are also just like other subpatterns, but they start with the opcode OP_ONCE. The check for matching an empty string in an unbounded repeat is handled entirely at runtime, so there is just this one opcode. Conditional subpatterns ----------------------- These are like other subpatterns, but they start with the opcode OP_COND, or OP_SCOND for one that might match an empty string in an unbounded repeat. If the condition is a back reference, this is stored at the start of the subpattern using the opcode OP_CREF followed by two bytes containing the reference number. If the condition is "in recursion" (coded as "(?(R)"), or "in recursion of group x" (coded as "(?(Rx)"), the group number is stored at the start of the subpattern using the opcode OP_RREF, and a value of zero for "the whole pattern". For a DEFINE condition, just the single byte OP_DEF is used (it has no associated data). Otherwise, a conditional subpattern always starts with one of the assertions. Recursion --------- Recursion either matches the current regex, or some subexpression. The opcode OP_RECURSE is followed by an value which is the offset to the starting bracket from the start of the whole pattern. From release 6.5, OP_RECURSE is automatically wrapped inside OP_ONCE brackets (because otherwise some patterns broke it). OP_RECURSE is also used for "subroutine" calls, even though they are not strictly a recursion. Callout ------- OP_CALLOUT is followed by one byte of data that holds a callout number in the range 0 to 254 for manual callouts, or 255 for an automatic callout. In both cases there follows a two-byte value giving the offset in the pattern to the start of the following item, and another two-byte item giving the length of the next item. Changing options ---------------- If any of the /i, /m, or /s options are changed within a pattern, an OP_OPT opcode is compiled, followed by one byte containing the new settings of these flags. If there are several alternatives, there is an occurrence of OP_OPT at the start of all those following the first options change, to set appropriate options for the start of the alternative. Immediately after the end of the group there is another such item to reset the flags to their previous values. A change of flag right at the very start of the pattern can be handled entirely at compile time, and so does not cause anything to be put into the compiled data. Philip Hazel August 2007 libsynthesis-3.4.0.47.1/src/pcre/INSTALL000066400000000000000000000223101226375725500174130ustar00rootroot00000000000000Installation Instructions ************************* Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, 2006 Free Software Foundation, Inc. This file is free documentation; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. Basic Installation ================== Briefly, the shell commands `./configure; make; make install' should configure, build, and install this package. The following more-detailed instructions are generic; see the `README' file for instructions specific to this package. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a `Makefile' in each directory of the package. It may also create one or more `.h' files containing system-dependent definitions. Finally, it creates a shell script `config.status' that you can run in the future to recreate the current configuration, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). It can also use an optional file (typically called `config.cache' and enabled with `--cache-file=config.cache' or simply `-C') that saves the results of its tests to speed up reconfiguring. Caching is disabled by default to prevent problems with accidental use of stale cache files. If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the `README' so they can be considered for the next release. If you are using the cache, and at some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.ac' (or `configure.in') is used to create `configure' by a program called `autoconf'. You need `configure.ac' if you want to change it or regenerate `configure' using a newer version of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type `./configure' to configure the package for your system. Running `configure' might take a while. While running, it prints some messages telling which features it is checking for. 2. Type `make' to compile the package. 3. Optionally, type `make check' to run any self-tests that come with the package. 4. Type `make install' to install the programs and any data files and documentation. 5. You can remove the program binaries and object files from the source code directory by typing `make clean'. To also remove the files that `configure' created (so you can compile the package for a different kind of computer), type `make distclean'. There is also a `make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the `configure' script does not know about. Run `./configure --help' for details on some of the pertinent environment variables. You can give `configure' initial values for configuration parameters by setting variables in the command line or in the environment. Here is an example: ./configure CC=c99 CFLAGS=-g LIBS=-lposix *Note Defining Variables::, for more details. Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you can use GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. With a non-GNU `make', it is safer to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use `make distclean' before reconfiguring for another architecture. Installation Names ================== By default, `make install' installs the package's commands under `/usr/local/bin', include files under `/usr/local/include', etc. You can specify an installation prefix other than `/usr/local' by giving `configure' the option `--prefix=PREFIX'. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you pass the option `--exec-prefix=PREFIX' to `configure', the package uses PREFIX as the prefix for installing programs and libraries. Documentation and other data files still use the regular prefix. In addition, if you use an unusual directory layout you can give options like `--bindir=DIR' to specify different values for particular kinds of files. Run `configure --help' for a list of the directories you can set and what kinds of files go in them. If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving `configure' the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. Optional Features ================= Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE is something like `gnu-as' or `x' (for the X Window System). The `README' should mention any `--enable-' and `--with-' options that the package recognizes. For packages that use the X Window System, `configure' can usually find the X include and library files automatically, but if it doesn't, you can use the `configure' options `--x-includes=DIR' and `--x-libraries=DIR' to specify their locations. Specifying the System Type ========================== There may be some features `configure' cannot figure out automatically, but needs to determine by the type of machine the package will run on. Usually, assuming the package is built to be run on the _same_ architectures, `configure' can figure that out, but if it prints a message saying it cannot guess the machine type, give it the `--build=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name which has the form: CPU-COMPANY-SYSTEM where SYSTEM can have one of these forms: OS KERNEL-OS See the file `config.sub' for the possible values of each field. If `config.sub' isn't included in this package, then this package doesn't need to know the machine type. If you are _building_ compiler tools for cross-compiling, you should use the option `--target=TYPE' to select the type of system they will produce code for. If you want to _use_ a cross compiler, that generates code for a platform different from the build platform, you should specify the "host" platform (i.e., that on which the generated programs will eventually be run) with `--host=TYPE'. Sharing Defaults ================ If you want to set default values for `configure' scripts to share, you can create a site shell script called `config.site' that gives default values for variables like `CC', `cache_file', and `prefix'. `configure' looks for `PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it exists. Or, you can set the `CONFIG_SITE' environment variable to the location of the site script. A warning: not all `configure' scripts look for a site script. Defining Variables ================== Variables not defined in a site shell script can be set in the environment passed to `configure'. However, some packages may run configure again during the build, and the customized values of these variables may be lost. In order to avoid this problem, you should set them in the `configure' command line, using `VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc causes the specified `gcc' to be used as the C compiler (unless it is overridden in the site shell script). Unfortunately, this technique does not work for `CONFIG_SHELL' due to an Autoconf bug. Until the bug is fixed you can use this workaround: CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash `configure' Invocation ====================== `configure' recognizes the following options to control how it operates. `--help' `-h' Print a summary of the options to `configure', and exit. `--version' `-V' Print the version of Autoconf used to generate the `configure' script, and exit. `--cache-file=FILE' Enable the cache: use and save the results of the tests in FILE, traditionally `config.cache'. FILE defaults to `/dev/null' to disable caching. `--config-cache' `-C' Alias for `--cache-file=config.cache'. `--quiet' `--silent' `-q' Do not print messages saying which checks are being made. To suppress all normal output, redirect it to `/dev/null' (any error messages will still be shown). `--srcdir=DIR' Look for the package's source code in directory DIR. Usually `configure' can determine that directory automatically. `configure' also accepts some other, not widely useful, options. Run `configure --help' for more details. libsynthesis-3.4.0.47.1/src/pcre/LICENCE000066400000000000000000000046731226375725500173630ustar00rootroot00000000000000PCRE LICENCE ------------ PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Release 7 of PCRE is distributed under the terms of the "BSD" licence, as specified below. The documentation for PCRE, supplied in the "doc" directory, is distributed under the same terms as the software itself. The basic library functions are written in C and are freestanding. Also included in the distribution is a set of C++ wrapper functions. THE BASIC LIBRARY FUNCTIONS --------------------------- Written by: Philip Hazel Email local part: ph10 Email domain: cam.ac.uk University of Cambridge Computing Service, Cambridge, England. Copyright (c) 1997-2007 University of Cambridge All rights reserved. THE C++ WRAPPER FUNCTIONS ------------------------- Contributed by: Google Inc. Copyright (c) 2007, Google Inc. All rights reserved. THE "BSD" LICENCE ----------------- 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 name of the University of Cambridge nor the name of Google Inc. nor the names of their 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. End libsynthesis-3.4.0.47.1/src/pcre/Makefile.am000066400000000000000000000215511226375725500204240ustar00rootroot00000000000000## Process this file with automake to produce Makefile.in. dist_doc_DATA = \ doc/pcre.txt \ doc/pcre-config.txt \ doc/pcregrep.txt \ doc/pcretest.txt \ AUTHORS \ COPYING \ ChangeLog \ LICENCE \ NEWS \ README dist_html_DATA = \ doc/html/index.html \ doc/html/pcre.html \ doc/html/pcre-config.html \ doc/html/pcre_compile.html \ doc/html/pcre_compile2.html \ doc/html/pcre_config.html \ doc/html/pcre_copy_named_substring.html \ doc/html/pcre_copy_substring.html \ doc/html/pcre_dfa_exec.html \ doc/html/pcre_exec.html \ doc/html/pcre_free_substring.html \ doc/html/pcre_free_substring_list.html \ doc/html/pcre_fullinfo.html \ doc/html/pcre_get_named_substring.html \ doc/html/pcre_get_stringnumber.html \ doc/html/pcre_get_stringtable_entries.html \ doc/html/pcre_get_substring.html \ doc/html/pcre_get_substring_list.html \ doc/html/pcre_info.html \ doc/html/pcre_maketables.html \ doc/html/pcre_refcount.html \ doc/html/pcre_study.html \ doc/html/pcre_version.html \ doc/html/pcreapi.html \ doc/html/pcrebuild.html \ doc/html/pcrecallout.html \ doc/html/pcrecompat.html \ doc/html/pcregrep.html \ doc/html/pcrematching.html \ doc/html/pcrepartial.html \ doc/html/pcrepattern.html \ doc/html/pcreperform.html \ doc/html/pcreposix.html \ doc/html/pcreprecompile.html \ doc/html/pcresample.html \ doc/html/pcrestack.html \ doc/html/pcretest.html pcrecpp_html = doc/html/pcrecpp.html dist_noinst_DATA = $(pcrecpp_html) if WITH_PCRE_CPP html_DATA = $(pcrecpp_html) endif # The Libtool libraries to install. We'll add to this later. lib_LTLIBRARIES = # Unit tests you want to run when people type 'make check'. # TESTS is for binary unit tests, check_SCRIPTS for script-based tests TESTS = check_SCRIPTS = dist_noinst_SCRIPTS = # Some of the binaries we make are to be installed, and others are # (non-user-visible) helper programs needed to build libpcre. bin_PROGRAMS = noinst_PROGRAMS = # Additional files to delete on 'make clean' and 'make maintainer-clean'. CLEANFILES = MAINTAINERCLEANFILES = # Additional files to bundle with the distribution, over and above what # the Autotools include by default. EXTRA_DIST = # These files contain maintenance information EXTRA_DIST += \ doc/perltest.txt \ NON-UNIX-USE \ HACKING # These files are used in the preparation of a release EXTRA_DIST += \ PrepareRelease \ CleanTxt \ Detrail \ 132html \ doc/index.html.src # These files are to do with building for Virtual Pascal EXTRA_DIST += \ makevp.bat \ makevp_c.txt \ makevp_l.txt \ pcregexp.pas # These files are usable versions of pcre.h and config.h that are distributed # for the benefit of people who are building PCRE manually, without the # Autotools support. EXTRA_DIST += \ pcre.h.generic \ config.h.generic pcre.h.generic: configure.ac rm -f $@ cp -p pcre.h $@ MAINTAINERCLEANFILES += pcre.h.generic # These are the header files we'll install. We do not distribute pcre.h because # it is generated from pcre.h.in. nodist_include_HEADERS = \ pcre.h include_HEADERS = \ pcreposix.h # These additional headers will be be installed if C++ support is enabled. We # do not distribute pcrecpparg.h or pcre_stringpiece.h, as these are generated # from corresponding .h.in files (which we do distribute). if WITH_PCRE_CPP nodist_include_HEADERS += \ pcrecpparg.h \ pcre_stringpiece.h include_HEADERS += \ pcrecpp.h \ pcre_scanner.h endif # WITH_PCRE_CPP bin_SCRIPTS = pcre-config ## --------------------------------------------------------------- ## The dftables program is used to rebuild character tables before compiling ## PCRE, if --enable-rebuild-chartables is specified. It is not a user-visible ## program. The default (when --enable-rebuild-chartables is not specified) is ## to copy a distributed set of tables that are defined for ASCII code. In this ## case, dftables is not needed. if WITH_REBUILD_CHARTABLES noinst_PROGRAMS += dftables dftables_SOURCES = dftables.c pcre_chartables.c: dftables$(EXEEXT) ./dftables$(EXEEXT) $@ else pcre_chartables.c: $(srcdir)/pcre_chartables.c.dist rm -f $@ $(LN_S) $(srcdir)/pcre_chartables.c.dist $@ endif # WITH_REBUILD_CHARTABLES ## The main pcre library lib_LTLIBRARIES += libpcre.la libpcre_la_SOURCES = \ pcre_compile.c \ pcre_config.c \ pcre_dfa_exec.c \ pcre_exec.c \ pcre_fullinfo.c \ pcre_get.c \ pcre_globals.c \ pcre_info.c \ pcre_internal.h \ pcre_maketables.c \ pcre_newline.c \ pcre_ord2utf8.c \ pcre_refcount.c \ pcre_study.c \ pcre_tables.c \ pcre_try_flipped.c \ pcre_ucp_searchfuncs.c \ pcre_valid_utf8.c \ pcre_version.c \ pcre_xclass.c \ ucp.h \ ucpinternal.h \ ucptable.h ## This file is generated as part of the building process, so don't distribute. nodist_libpcre_la_SOURCES = \ pcre_chartables.c # The pcre_printint.src file is #included by some source files, so it must be # distributed. The pcre_chartables.c.dist file is the default version of # pcre_chartables.c, used unless --enable-rebuild-chartables is specified. EXTRA_DIST += pcre_printint.src pcre_chartables.c.dist libpcre_la_LDFLAGS = $(EXTRA_LIBPCRE_LDFLAGS) CLEANFILES += pcre_chartables.c ## A version of the main pcre library that has a posix re API. lib_LTLIBRARIES += libpcreposix.la libpcreposix_la_SOURCES = \ pcreposix.c libpcreposix_la_LDFLAGS = $(EXTRA_LIBPCREPOSIX_LDFLAGS) libpcreposix_la_LIBADD = libpcre.la ## There's a C++ library as well. if WITH_PCRE_CPP lib_LTLIBRARIES += libpcrecpp.la libpcrecpp_la_SOURCES = \ pcrecpp_internal.h \ pcrecpp.cc \ pcre_scanner.cc \ pcre_stringpiece.cc libpcrecpp_la_LDFLAGS = $(EXTRA_LIBPCRECPP_LDFLAGS) libpcrecpp_la_LIBADD = libpcre.la TESTS += pcrecpp_unittest noinst_PROGRAMS += pcrecpp_unittest pcrecpp_unittest_SOURCES = pcrecpp_unittest.cc pcrecpp_unittest_LDADD = libpcrecpp.la TESTS += pcre_scanner_unittest noinst_PROGRAMS += pcre_scanner_unittest pcre_scanner_unittest_SOURCES = pcre_scanner_unittest.cc pcre_scanner_unittest_LDADD = libpcrecpp.la TESTS += pcre_stringpiece_unittest noinst_PROGRAMS += pcre_stringpiece_unittest pcre_stringpiece_unittest_SOURCES = pcre_stringpiece_unittest.cc pcre_stringpiece_unittest_LDADD = libpcrecpp.la endif # WITH_PCRE_CPP ## The main unit tests # Each unit test is a binary plus a script that runs that binary in various # ways. We install these test binaries in case folks find it helpful. TESTS += RunTest dist_noinst_SCRIPTS += RunTest EXTRA_DIST += RunTest.bat bin_PROGRAMS += pcretest pcretest_SOURCES = pcretest.c pcretest_LDADD = libpcreposix.la TESTS += RunGrepTest dist_noinst_SCRIPTS += RunGrepTest bin_PROGRAMS += pcregrep pcregrep_SOURCES = pcregrep.c pcregrep_LDADD = libpcreposix.la EXTRA_DIST += \ testdata/grepinput \ testdata/grepinput8 \ testdata/grepinputv \ testdata/grepinputx \ testdata/greplist \ testdata/grepoutput \ testdata/grepoutput8 \ testdata/grepoutputN \ testdata/testinput1 \ testdata/testinput2 \ testdata/testinput3 \ testdata/testinput4 \ testdata/testinput5 \ testdata/testinput6 \ testdata/testinput7 \ testdata/testinput8 \ testdata/testinput9 \ testdata/testinput10 \ testdata/testoutput1 \ testdata/testoutput2 \ testdata/testoutput3 \ testdata/testoutput4 \ testdata/testoutput5 \ testdata/testoutput6 \ testdata/testoutput7 \ testdata/testoutput8 \ testdata/testoutput9 \ testdata/testoutput10 \ perltest.pl CLEANFILES += \ testsavedregex \ teststderr \ testtry \ testNinput # PCRE demonstration program noinst_PROGRAMS += pcredemo pcredemo_SOURCES = pcredemo.c pcredemo_LDADD = libpcre.la ## Utility rules, documentation, etc. # A compatibility line, the old build system worked with 'make test' test: check ; # We have .pc files for pkg-config users. pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libpcre.pc if WITH_PCRE_CPP pkgconfig_DATA += libpcrecpp.pc endif dist_man_MANS = \ doc/pcre.3 \ doc/pcre-config.1 \ doc/pcre_compile.3 \ doc/pcre_compile2.3 \ doc/pcre_config.3 \ doc/pcre_copy_named_substring.3 \ doc/pcre_copy_substring.3 \ doc/pcre_dfa_exec.3 \ doc/pcre_exec.3 \ doc/pcre_free_substring.3 \ doc/pcre_free_substring_list.3 \ doc/pcre_fullinfo.3 \ doc/pcre_get_named_substring.3 \ doc/pcre_get_stringnumber.3 \ doc/pcre_get_stringtable_entries.3 \ doc/pcre_get_substring.3 \ doc/pcre_get_substring_list.3 \ doc/pcre_info.3 \ doc/pcre_maketables.3 \ doc/pcre_refcount.3 \ doc/pcre_study.3 \ doc/pcre_version.3 \ doc/pcreapi.3 \ doc/pcrebuild.3 \ doc/pcrecallout.3 \ doc/pcrecompat.3 \ doc/pcregrep.1 \ doc/pcrematching.3 \ doc/pcrepartial.3 \ doc/pcrepattern.3 \ doc/pcreperform.3 \ doc/pcreposix.3 \ doc/pcreprecompile.3 \ doc/pcresample.3 \ doc/pcrestack.3 \ doc/pcretest.1 pcrecpp_man = doc/pcrecpp.3 EXTRA_DIST += $(pcrecpp_man) if WITH_PCRE_CPP man_MANS = $(pcrecpp_man) endif ## CMake support EXTRA_DIST += \ CMakeLists.txt \ config-cmake.h.in ## end Makefile.am libsynthesis-3.4.0.47.1/src/pcre/NEWS000066400000000000000000000370601226375725500170710ustar00rootroot00000000000000News about PCRE releases ------------------------ Release 7.3 28-Aug-07 --------------------- Most changes are bug fixes. Some that are not: 1. There is some support for Perl 5.10's experimental "backtracking control verbs" such as (*PRUNE). 2. UTF-8 checking is now as per RFC 3629 instead of RFC 2279; this is more restrictive in the strings it accepts. 3. Checking for potential integer overflow has been made more dynamic, and as a consequence there is no longer a hard limit on the size of a subpattern that has a limited repeat count. 4. When CRLF is a valid line-ending sequence, pcre_exec() and pcre_dfa_exec() no longer advance by two characters instead of one when an unanchored match fails at CRLF if there are explicit CR or LF matches within the pattern. This gets rid of some anomalous effects that previously occurred. 5. Some PCRE-specific settings for varying the newline options at the start of a pattern have been added. Release 7.2 19-Jun-07 --------------------- WARNING: saved patterns that were compiled by earlier versions of PCRE must be recompiled for use with 7.2 (necessitated by the addition of \K, \h, \H, \v, and \V). Correction to the notes for 7.1: the note about shared libraries for Windows is wrong. Previously, three libraries were built, but each could function independently. For example, the pcreposix library also included all the functions from the basic pcre library. The change is that the three libraries are no longer independent. They are like the Unix libraries. To use the pcreposix functions, for example, you need to link with both the pcreposix and the basic pcre library. Some more features from Perl 5.10 have been added: (?-n) and (?+n) relative references for recursion and subroutines. (?(-n) and (?(+n) relative references as conditions. \k{name} and \g{name} are synonyms for \k. \K to reset the start of the matched string; for example, (foo)\Kbar matches bar preceded by foo, but only sets bar as the matched string. (?| introduces a group where the capturing parentheses in each alternative start from the same number; for example, (?|(abc)|(xyz)) sets capturing parentheses number 1 in both cases. \h, \H, \v, \V match horizontal and vertical whitespace, respectively. Release 7.1 24-Apr-07 --------------------- There is only one new feature in this release: a linebreak setting of PCRE_NEWLINE_ANYCRLF. It is a cut-down version of PCRE_NEWLINE_ANY, which recognizes only CRLF, CR, and LF as linebreaks. A few bugs are fixed (see ChangeLog for details), but the major change is a complete re-implementation of the build system. This now has full Autotools support and so is now "standard" in some sense. It should help with compiling PCRE in a wide variety of environments. NOTE: when building shared libraries for Windows, three dlls are now built, called libpcre, libpcreposix, and libpcrecpp. Previously, everything was included in a single dll. Another important change is that the dftables auxiliary program is no longer compiled and run at "make" time by default. Instead, a default set of character tables (assuming ASCII coding) is used. If you want to use dftables to generate the character tables as previously, add --enable-rebuild-chartables to the "configure" command. You must do this if you are compiling PCRE to run on a system that uses EBCDIC code. There is a discussion about character tables in the README file. The default is not to use dftables so that that there is no problem when cross-compiling. Release 7.0 19-Dec-06 --------------------- This release has a new major number because there have been some internal upheavals to facilitate the addition of new optimizations and other facilities, and to make subsequent maintenance and extension easier. Compilation is likely to be a bit slower, but there should be no major effect on runtime performance. Previously compiled patterns are NOT upwards compatible with this release. If you have saved compiled patterns from a previous release, you will have to re-compile them. Important changes that are visible to users are: 1. The Unicode property tables have been updated to Unicode 5.0.0, which adds some more scripts. 2. The option PCRE_NEWLINE_ANY causes PCRE to recognize any Unicode newline sequence as a newline. 3. The \R escape matches a single Unicode newline sequence as a single unit. 4. New features that will appear in Perl 5.10 are now in PCRE. These include alternative Perl syntax for named parentheses, and Perl syntax for recursion. 5. The C++ wrapper interface has been extended by the addition of a QuoteMeta function and the ability to allow copy construction and assignment. For a complete list of changes, see the ChangeLog file. Release 6.7 04-Jul-06 --------------------- The main additions to this release are the ability to use the same name for multiple sets of parentheses, and support for CRLF line endings in both the library and pcregrep (and in pcretest for testing). Thanks to Ian Taylor, the stack usage for many kinds of pattern has been significantly reduced for certain subject strings. Release 6.5 01-Feb-06 --------------------- Important changes in this release: 1. A number of new features have been added to pcregrep. 2. The Unicode property tables have been updated to Unicode 4.1.0, and the supported properties have been extended with script names such as "Arabic", and the derived properties "Any" and "L&". This has necessitated a change to the interal format of compiled patterns. Any saved compiled patterns that use \p or \P must be recompiled. 3. The specification of recursion in patterns has been changed so that all recursive subpatterns are automatically treated as atomic groups. Thus, for example, (?R) is treated as if it were (?>(?R)). This is necessary because otherwise there are situations where recursion does not work. See the ChangeLog for a complete list of changes, which include a number of bug fixes and tidies. Release 6.0 07-Jun-05 --------------------- The release number has been increased to 6.0 because of the addition of several major new pieces of functionality. A new function, pcre_dfa_exec(), which implements pattern matching using a DFA algorithm, has been added. This has a number of advantages for certain cases, though it does run more slowly, and lacks the ability to capture substrings. On the other hand, it does find all matches, not just the first, and it works better for partial matching. The pcrematching man page discusses the differences. The pcretest program has been enhanced so that it can make use of the new pcre_dfa_exec() matching function and the extra features it provides. The distribution now includes a C++ wrapper library. This is built automatically if a C++ compiler is found. The pcrecpp man page discusses this interface. The code itself has been re-organized into many more files, one for each function, so it no longer requires everything to be linked in when static linkage is used. As a consequence, some internal functions have had to have their names exposed. These functions all have names starting with _pcre_. They are undocumented, and are not intended for use by outside callers. The pcregrep program has been enhanced with new functionality such as multiline-matching and options for output more matching context. See the ChangeLog for a complete list of changes to the library and the utility programs. Release 5.0 13-Sep-04 --------------------- The licence under which PCRE is released has been changed to the more conventional "BSD" licence. In the code, some bugs have been fixed, and there are also some major changes in this release (which is why I've increased the number to 5.0). Some changes are internal rearrangements, and some provide a number of new facilities. The new features are: 1. There's an "automatic callout" feature that inserts callouts before every item in the regex, and there's a new callout field that gives the position in the pattern - useful for debugging and tracing. 2. The extra_data structure can now be used to pass in a set of character tables at exec time. This is useful if compiled regex are saved and re-used at a later time when the tables may not be at the same address. If the default internal tables are used, the pointer saved with the compiled pattern is now set to NULL, which means that you don't need to do anything special unless you are using custom tables. 3. It is possible, with some restrictions on the content of the regex, to request "partial" matching. A special return code is given if all of the subject string matched part of the regex. This could be useful for testing an input field as it is being typed. 4. There is now some optional support for Unicode character properties, which means that the patterns items such as \p{Lu} and \X can now be used. Only the general category properties are supported. If PCRE is compiled with this support, an additional 90K data structure is include, which increases the size of the library dramatically. 5. There is support for saving compiled patterns and re-using them later. 6. There is support for running regular expressions that were compiled on a different host with the opposite endianness. 7. The pcretest program has been extended to accommodate the new features. The main internal rearrangement is that sequences of literal characters are no longer handled as strings. Instead, each character is handled on its own. This makes some UTF-8 handling easier, and makes the support of partial matching possible. Compiled patterns containing long literal strings will be larger as a result of this change; I hope that performance will not be much affected. Release 4.5 01-Dec-03 --------------------- Again mainly a bug-fix and tidying release, with only a couple of new features: 1. It's possible now to compile PCRE so that it does not use recursive function calls when matching. Instead it gets memory from the heap. This slows things down, but may be necessary on systems with limited stacks. 2. UTF-8 string checking has been tightened to reject overlong sequences and to check that a starting offset points to the start of a character. Failure of the latter returns a new error code: PCRE_ERROR_BADUTF8_OFFSET. 3. PCRE can now be compiled for systems that use EBCDIC code. Release 4.4 21-Aug-03 --------------------- This is mainly a bug-fix and tidying release. The only new feature is that PCRE checks UTF-8 strings for validity by default. There is an option to suppress this, just in case anybody wants that teeny extra bit of performance. Releases 4.1 - 4.3 ------------------ Sorry, I forgot about updating the NEWS file for these releases. Please take a look at ChangeLog. Release 4.0 17-Feb-03 --------------------- There have been a lot of changes for the 4.0 release, adding additional functionality and mending bugs. Below is a list of the highlights of the new functionality. For full details of these features, please consult the documentation. For a complete list of changes, see the ChangeLog file. 1. Support for Perl's \Q...\E escapes. 2. "Possessive quantifiers" ?+, *+, ++, and {,}+ which come from Sun's Java package. They provide some syntactic sugar for simple cases of "atomic grouping". 3. Support for the \G assertion. It is true when the current matching position is at the start point of the match. 4. A new feature that provides some of the functionality that Perl provides with (?{...}). The facility is termed a "callout". The way it is done in PCRE is for the caller to provide an optional function, by setting pcre_callout to its entry point. To get the function called, the regex must include (?C) at appropriate points. 5. Support for recursive calls to individual subpatterns. This makes it really easy to get totally confused. 6. Support for named subpatterns. The Python syntax (?P...) is used to name a group. 7. Several extensions to UTF-8 support; it is now fairly complete. There is an option for pcregrep to make it operate in UTF-8 mode. 8. The single man page has been split into a number of separate man pages. These also give rise to individual HTML pages which are put in a separate directory. There is an index.html page that lists them all. Some hyperlinking between the pages has been installed. Release 3.5 15-Aug-01 --------------------- 1. The configuring system has been upgraded to use later versions of autoconf and libtool. By default it builds both a shared and a static library if the OS supports it. You can use --disable-shared or --disable-static on the configure command if you want only one of them. 2. The pcretest utility is now installed along with pcregrep because it is useful for users (to test regexs) and by doing this, it automatically gets relinked by libtool. The documentation has been turned into a man page, so there are now .1, .txt, and .html versions in /doc. 3. Upgrades to pcregrep: (i) Added long-form option names like gnu grep. (ii) Added --help to list all options with an explanatory phrase. (iii) Added -r, --recursive to recurse into sub-directories. (iv) Added -f, --file to read patterns from a file. 4. Added --enable-newline-is-cr and --enable-newline-is-lf to the configure script, to force use of CR or LF instead of \n in the source. On non-Unix systems, the value can be set in config.h. 5. The limit of 200 on non-capturing parentheses is a _nesting_ limit, not an absolute limit. Changed the text of the error message to make this clear, and likewise updated the man page. 6. The limit of 99 on the number of capturing subpatterns has been removed. The new limit is 65535, which I hope will not be a "real" limit. Release 3.3 01-Aug-00 --------------------- There is some support for UTF-8 character strings. This is incomplete and experimental. The documentation describes what is and what is not implemented. Otherwise, this is just a bug-fixing release. Release 3.0 01-Feb-00 --------------------- 1. A "configure" script is now used to configure PCRE for Unix systems. It builds a Makefile, a config.h file, and the pcre-config script. 2. PCRE is built as a shared library by default. 3. There is support for POSIX classes such as [:alpha:]. 5. There is an experimental recursion feature. ---------------------------------------------------------------------------- IMPORTANT FOR THOSE UPGRADING FROM VERSIONS BEFORE 2.00 Please note that there has been a change in the API such that a larger ovector is required at matching time, to provide some additional workspace. The new man page has details. This change was necessary in order to support some of the new functionality in Perl 5.005. IMPORTANT FOR THOSE UPGRADING FROM VERSION 2.00 Another (I hope this is the last!) change has been made to the API for the pcre_compile() function. An additional argument has been added to make it possible to pass over a pointer to character tables built in the current locale by pcre_maketables(). To use the default tables, this new arguement should be passed as NULL. IMPORTANT FOR THOSE UPGRADING FROM VERSION 2.05 Yet another (and again I hope this really is the last) change has been made to the API for the pcre_exec() function. An additional argument has been added to make it possible to start the match other than at the start of the subject string. This is important if there are lookbehinds. The new man page has the details, but you just want to convert existing programs, all you need to do is to stick in a new fifth argument to pcre_exec(), with a value of zero. For example, change pcre_exec(pattern, extra, subject, length, options, ovec, ovecsize) to pcre_exec(pattern, extra, subject, length, 0, options, ovec, ovecsize) **** libsynthesis-3.4.0.47.1/src/pcre/NON-UNIX-USE000066400000000000000000000313741226375725500201640ustar00rootroot00000000000000Compiling PCRE on non-Unix systems ---------------------------------- This document contains the following sections: General Generic instructions for the PCRE C library The C++ wrapper functions Building for virtual Pascal Stack size in Windows environments Comments about Win32 builds Building under Windows with BCC5.5 Building PCRE on OpenVMS GENERAL I (Philip Hazel) have no experience of Windows or VMS sytems and how their libraries work. The items in the PCRE distribution and Makefile that relate to anything other than Unix-like systems are untested by me. There are some other comments and files in the Contrib directory on the ftp site that you may find useful. See ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/Contrib If you want to compile PCRE for a non-Unix system (especially for a system that does not support "configure" and "make" files), note that the basic PCRE library consists entirely of code written in Standard C, and so should compile successfully on any system that has a Standard C compiler and library. The C++ wrapper functions are a separate issue (see below). The PCRE distribution contains some experimental support for "cmake", but this is incomplete and not documented. However if you are a "cmake" user you might like to try building with "cmake". GENERIC INSTRUCTIONS FOR THE PCRE C LIBRARY The following are generic comments about building the PCRE C library "by hand". (1) Copy or rename the file config.h.generic as config.h, and edit the macro settings that it contains to whatever is appropriate for your environment. In particular, if you want to force a specific value for newline, you can define the NEWLINE macro. An alternative approach is not to edit config.h, but to use -D on the compiler command line to make any changes that you need. NOTE: There have been occasions when the way in which certain parameters in config.h are used has changed between releases. (In the configure/make world, this is handled automatically.) When upgrading to a new release, you are strongly advised to review config.h.generic before re-using what you had previously. (2) Copy or rename the file pcre.h.generic as pcre.h. (3) EITHER: Copy or rename file pcre_chartables.c.dist as pcre_chartables.c. OR: Compile dftables.c as a stand-alone program, and then run it with the single argument "pcre_chartables.c". This generates a set of standard character tables and writes them to that file. The tables are generated using the default C locale for your system. If you want to use a locale that is specified by LC_xxx environment variables, add the -L option to the dftables command. You must use this method if you are building on a system that uses EBCDIC code. The tables in pcre_chartables.c are defaults. The caller of PCRE can specify alternative tables at run time. (4) Ensure that you have the following header files: pcre_internal.h ucp.h ucpinternal.h ucptable.h (5) Also ensure that you have the following file, which is #included as source when building a debugging version of PCRE and is also used by pcretest. pcre_printint.src (6) Compile the following source files: pcre_chartables.c pcre_compile.c pcre_config.c pcre_dfa_exec.c pcre_exec.c pcre_fullinfo.c pcre_get.c pcre_globals.c pcre_info.c pcre_maketables.c pcre_newline.c pcre_ord2utf8.c pcre_refcount.c pcre_study.c pcre_tables.c pcre_try_flipped.c pcre_ucp_searchfuncs.c pcre_valid_utf8.c pcre_version.c pcre_xclass.c Make sure that you include -I. in the compiler command (or equivalent for an unusual compiler) so that all included PCRE header files are first sought in the current directory. Otherwise you run the risk of picking up a previously-installed file from somewhere else. (7) Now link all the compiled code into an object library in whichever form your system keeps such libraries. This is the basic PCRE C library. If your system has static and shared libraries, you may have to do this once for each type. (8) Similarly, compile pcreposix.c and link the result (on its own) as the pcreposix library. (9) Compile the test program pcretest.c. This needs the functions in the pcre and pcreposix libraries when linking. It also needs the pcre_printint.src source file, which it #includes. (10) Run pcretest on the testinput files in the testdata directory, and check that the output matches the corresponding testoutput files. Note that the supplied files are in Unix format, with just LF characters as line terminators. You may need to edit them to change this if your system uses a different convention. (11) If you want to use the pcregrep command, compile and link pcregrep.c; it uses only the basic PCRE library (it does not need the pcreposix library). THE C++ WRAPPER FUNCTIONS The PCRE distribution also contains some C++ wrapper functions and tests, contributed by Google Inc. On a system that can use "configure" and "make", the functions are automatically built into a library called pcrecpp. It should be straightforward to compile the .cc files manually on other systems. The files called xxx_unittest.cc are test programs for each of the corresponding xxx.cc files. BUILDING FOR VIRTUAL PASCAL A script for building PCRE using Borland's C++ compiler for use with VPASCAL was contributed by Alexander Tokarev. Stefan Weber updated the script and added additional files. The following files in the distribution are for building PCRE for use with VP/Borland: makevp_c.txt, makevp_l.txt, makevp.bat, pcregexp.pas. STACK SIZE IN WINDOWS ENVIRONMENTS The default processor stack size of 1Mb in some Windows environments is too small for matching patterns that need much recursion. In particular, test 2 may fail because of this. Normally, running out of stack causes a crash, but there have been cases where the test program has just died silently. See your linker documentation for how to increase stack size if you experience problems. The Linux default of 8Mb is a reasonable choice for the stack, though even that can be too small for some pattern/subject combinations. There is more about stack usage in the "pcrestack" documentation. COMMENTS ABOUT WIN32 BUILDS There are two ways of building PCRE using the "configure, make, make install" paradigm on Windows systems: using MinGW or using Cygwin. These are not at all the same thing; they are completely different from each other. There is also some experimental, undocumented support for building using "cmake", which you might like to try if you are familiar with "cmake". However, at the present time, the "cmake" process builds only a static library (not a dll), and the tests are not automatically run. The MinGW home page (http://www.mingw.org/) says this: MinGW: A collection of freely available and freely distributable Windows specific header files and import libraries combined with GNU toolsets that allow one to produce native Windows programs that do not rely on any 3rd-party C runtime DLLs. The Cygwin home page (http://www.cygwin.com/) says this: Cygwin is a Linux-like environment for Windows. It consists of two parts: . A DLL (cygwin1.dll) which acts as a Linux API emulation layer providing substantial Linux API functionality . A collection of tools which provide Linux look and feel. The Cygwin DLL currently works with all recent, commercially released x86 32 bit and 64 bit versions of Windows, with the exception of Windows CE. On both MinGW and Cygwin, PCRE should build correctly using: ./configure && make && make install This should create two libraries called libpcre and libpcreposix, and, if you have enabled building the C++ wrapper, a third one called libpcrecpp. These are independent libraries: when you like with libpcreposix or libpcrecpp you must also link with libpcre, which contains the basic functions. (Some earlier releases of PCRE included the basic libpcre functions in libpcreposix. This no longer happens.) If you want to statically link your program against a non-dll .a file, you must define PCRE_STATIC before including pcre.h, otherwise the pcre_malloc() and pcre_free() exported functions will be declared __declspec(dllimport), with unwanted results. Using Cygwin's compiler generates libraries and executables that depend on cygwin1.dll. If a library that is generated this way is distributed, cygwin1.dll has to be distributed as well. Since cygwin1.dll is under the GPL licence, this forces not only PCRE to be under the GPL, but also the entire application. A distributor who wants to keep their own code proprietary must purchase an appropriate Cygwin licence. MinGW has no such restrictions. The MinGW compiler generates a library or executable that can run standalone on Windows without any third party dll or licensing issues. But there is more complication: If a Cygwin user uses the -mno-cygwin Cygwin gcc flag, what that really does is to tell Cygwin's gcc to use the MinGW gcc. Cygwin's gcc is only acting as a front end to MinGW's gcc (if you install Cygwin's gcc, you get both Cygwin's gcc and MinGW's gcc). So, a user can: . Build native binaries by using MinGW or by getting Cygwin and using -mno-cygwin. . Build binaries that depend on cygwin1.dll by using Cygwin with the normal compiler flags. The test files that are supplied with PCRE are in Unix format, with LF characters as line terminators. It may be necessary to change the line terminators in order to get some of the tests to work. We hope to improve things in this area in future. BUILDING UNDER WINDOWS WITH BCC5.5 Michael Roy sent these comments about building PCRE under Windows with BCC5.5: Some of the core BCC libraries have a version of PCRE from 1998 built in, which can lead to pcre_exec() giving an erroneous PCRE_ERROR_NULL from a version mismatch. I'm including an easy workaround below, if you'd like to include it in the non-unix instructions: When linking a project with BCC5.5, pcre.lib must be included before any of the libraries cw32.lib, cw32i.lib, cw32mt.lib, and cw32mti.lib on the command line. BUILDING PCRE ON OPENVMS Dan Mooney sent the following comments about building PCRE on OpenVMS. They relate to an older version of PCRE that used fewer source files, so the exact commands will need changing. See the current list of source files above. "It was quite easy to compile and link the library. I don't have a formal make file but the attached file [reproduced below] contains the OpenVMS DCL commands I used to build the library. I had to add #define POSIX_MALLOC_THRESHOLD 10 to pcre.h since it was not defined anywhere. The library was built on: O/S: HP OpenVMS v7.3-1 Compiler: Compaq C v6.5-001-48BCD Linker: vA13-01 The test results did not match 100% due to the issues you mention in your documentation regarding isprint(), iscntrl(), isgraph() and ispunct(). I modified some of the character tables temporarily and was able to get the results to match. Tests using the fr locale did not match since I don't have that locale loaded. The study size was always reported to be 3 less than the value in the standard test output files." ========================= $! This DCL procedure builds PCRE on OpenVMS $! $! I followed the instructions in the non-unix-use file in the distribution. $! $ COMPILE == "CC/LIST/NOMEMBER_ALIGNMENT/PREFIX_LIBRARY_ENTRIES=ALL_ENTRIES $ COMPILE DFTABLES.C $ LINK/EXE=DFTABLES.EXE DFTABLES.OBJ $ RUN DFTABLES.EXE/OUTPUT=CHARTABLES.C $ COMPILE MAKETABLES.C $ COMPILE GET.C $ COMPILE STUDY.C $! I had to set POSIX_MALLOC_THRESHOLD to 10 in PCRE.H since the symbol $! did not seem to be defined anywhere. $! I edited pcre.h and added #DEFINE SUPPORT_UTF8 to enable UTF8 support. $ COMPILE PCRE.C $ LIB/CREATE PCRE MAKETABLES.OBJ, GET.OBJ, STUDY.OBJ, PCRE.OBJ $! I had to set POSIX_MALLOC_THRESHOLD to 10 in PCRE.H since the symbol $! did not seem to be defined anywhere. $ COMPILE PCREPOSIX.C $ LIB/CREATE PCREPOSIX PCREPOSIX.OBJ $ COMPILE PCRETEST.C $ LINK/EXE=PCRETEST.EXE PCRETEST.OBJ, PCRE/LIB, PCREPOSIX/LIB $! C programs that want access to command line arguments must be $! defined as a symbol $ PCRETEST :== "$ SYS$ROADSUSERS:[DMOONEY.REGEXP]PCRETEST.EXE" $! Arguments must be enclosed in quotes. $ PCRETEST "-C" $! Test results: $! $! The test results did not match 100%. The functions isprint(), iscntrl(), $! isgraph() and ispunct() on OpenVMS must not produce the same results $! as the system that built the test output files provided with the $! distribution. $! $! The study size did not match and was always 3 less on OpenVMS. $! $! Locale could not be set to fr $! ========================= Last Updated: 01 August 2007 **** libsynthesis-3.4.0.47.1/src/pcre/PrepareRelease000066400000000000000000000127051226375725500212130ustar00rootroot00000000000000#/bin/sh # Script to prepare the files for building a PCRE release. It does some # processing of the documentation, detrails files, and creates pcre.h.generic # and config.h.generic (for use by builders who can't run ./configure). # You must run this script before runnning "make dist". It makes use of the # following files: # 132html A Perl script that converts a .1 or .3 man page into HTML. It # is called from MakeRelease. It "knows" the relevant troff # constructs that are used in the PCRE man pages. # CleanTxt A Perl script that cleans up the output of "nroff -man" by # removing backspaces and other redundant text so as to produce # a readable .txt file. # Detrail A Perl script that removes trailing spaces from files. # doc/index.html.src # A file that is copied as index.html into the doc/html directory # when the HTML documentation is built. It works like this so that # doc/html can be deleted and re-created from scratch. # First, sort out the documentation cd doc echo Processing documentation # Make Text form of the documentation. It needs some mangling to make it # tidy for online reading. Concatenate all the .3 stuff, but omit the # individual function pages. cat <pcre.txt ----------------------------------------------------------------------------- This file contains a concatenation of the PCRE man pages, converted to plain text format for ease of searching with a text editor, or for use on systems that do not have a man page processor. The small individual files that give synopses of each function in the library have not been included. There are separate text files for the pcregrep and pcretest commands. ----------------------------------------------------------------------------- End echo "Making pcre.txt" for file in pcre pcrebuild pcrematching pcreapi pcrecallout pcrecompat \ pcrepattern pcresyntax pcrepartial pcreprecompile \ pcreperform pcreposix pcrecpp pcresample pcrestack ; do echo " Processing $file.3" nroff -c -man $file.3 >$file.rawtxt ../CleanTxt <$file.rawtxt >>pcre.txt /bin/rm $file.rawtxt echo "------------------------------------------------------------------------------" >>pcre.txt if [ "$file" != "pcresample" ] ; then echo " " >>pcre.txt echo " " >>pcre.txt fi done # The three commands for file in pcretest pcregrep pcre-config ; do echo Making $file.txt nroff -c -man $file.1 >$file.rawtxt ../CleanTxt <$file.rawtxt >$file.txt /bin/rm $file.rawtxt done # Make HTML form of the documentation. echo "Making HTML documentation" /bin/rm html/* cp index.html.src html/index.html for file in *.1 ; do base=`basename $file .1` echo " Making $base.html" ../132html -toc $base <$file >html/$base.html done # Exclude table of contents for function summaries. It seems that expr # forces an anchored regex. Also exclude them for small pages that have # only one section. for file in *.3 ; do base=`basename $file .3` toc=-toc if [ `expr $base : '.*_'` -ne 0 ] ; then toc="" ; fi if [ "$base" = "pcresample" ] || \ [ "$base" = "pcrestack" ] || \ [ "$base" = "pcrecompat" ] || \ [ "$base" = "pcreperform" ] ; then toc="" fi echo " Making $base.html" ../132html $toc $base <$file >html/$base.html if [ $? != 0 ] ; then exit 1; fi done # End of documentation processing cd .. echo Documentation done # These files are detrailed; do not detrail the test data because there may be # significant trailing spaces. The configure files are also omitted from the # detrailing. files="\ Makefile.am \ Makefile.in \ configure.ac \ README \ LICENCE \ COPYING \ AUTHORS \ NEWS \ NON-UNIX-USE \ INSTALL \ 132html \ CleanTxt \ Detrail \ ChangeLog \ CMakeLists.txt \ RunGrepTest \ RunTest \ RunTest.bat \ pcre-config.in \ libpcre.pc.in \ libpcrecpp.pc.in \ config.h \ config.h.in \ pcre_printint.src \ pcre_chartables.c.dist \ pcredemo.c \ pcregrep.c \ pcretest.c \ dftables.c \ pcreposix.c \ pcreposix.h \ pcre.h.in \ pcre_internal.h pcre_compile.c \ pcre_config.c \ pcre_dfa_exec.c \ pcre_exec.c \ pcre_fullinfo.c \ pcre_get.c \ pcre_globals.c \ pcre_info.c \ pcre_maketables.c \ pcre_newline.c \ pcre_ord2utf8.c \ pcre_refcount.c \ pcre_study.c \ pcre_tables.c \ pcre_try_flipped.c \ pcre_ucp_searchfuncs.c \ pcre_valid_utf8.c \ pcre_version.c \ pcre_xclass.c \ pcre_scanner.cc \ pcre_scanner.h \ pcre_scanner_unittest.cc \ pcrecpp.cc \ pcrecpp.h \ pcrecpparg.h.in \ pcrecpp_unittest.cc \ pcre_stringpiece.cc \ pcre_stringpiece.h.in \ pcre_stringpiece_unittest.cc \ perltest.pl \ ucp.h \ ucpinternal.h \ ucptable.h \ makevp.bat \ pcre.def \ libpcre.def \ libpcreposix.def" echo Detrailing ./Detrail $files doc/p* doc/html/* echo Doing basic configure to get default pcre.h and config.h # This is in case the caller has set aliases (as I do - PH) unset cp ls mv rm ./configure >/dev/null echo Converting pcre.h and config.h to generic forms cp -f pcre.h pcre.h.generic perl <<'END' open(IN, "config.h.generic") || die "Can't open config.h.generic: $!\n"; while () { if (/^#define\s(?!PACKAGE)(\w+)/) { print OUT "#ifndef $1\n"; print OUT; print OUT "#endif\n"; } else { print OUT; } } close IN; close OUT; END echo Done #End libsynthesis-3.4.0.47.1/src/pcre/README000066400000000000000000000771721226375725500172620ustar00rootroot00000000000000README file for PCRE (Perl-compatible regular expression library) ----------------------------------------------------------------- The latest release of PCRE is always available from ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-xxx.tar.gz There is a mailing list for discussion about the development of PCRE at pcre-dev@exim.org Please read the NEWS file if you are upgrading from a previous release. The contents of this README file are: The PCRE APIs Documentation for PCRE Contributions by users of PCRE Building PCRE on non-Unix systems Building PCRE on Unix-like systems Retrieving configuration information on Unix-like systems Shared libraries on Unix-like systems Cross-compiling on Unix-like systems Using HP's ANSI C++ compiler (aCC) Making new tarballs Testing PCRE Character tables File manifest The PCRE APIs ------------- PCRE is written in C, and it has its own API. The distribution also includes a set of C++ wrapper functions (see the pcrecpp man page for details), courtesy of Google Inc. In addition, there is a set of C wrapper functions that are based on the POSIX regular expression API (see the pcreposix man page). These end up in the library called libpcreposix. Note that this just provides a POSIX calling interface to PCRE; the regular expressions themselves still follow Perl syntax and semantics. The POSIX API is restricted, and does not give full access to all of PCRE's facilities. The header file for the POSIX-style functions is called pcreposix.h. The official POSIX name is regex.h, but I did not want to risk possible problems with existing files of that name by distributing it that way. To use PCRE with an existing program that uses the POSIX API, pcreposix.h will have to be renamed or pointed at by a link. If you are using the POSIX interface to PCRE and there is already a POSIX regex library installed on your system, as well as worrying about the regex.h header file (as mentioned above), you must also take care when linking programs to ensure that they link with PCRE's libpcreposix library. Otherwise they may pick up the POSIX functions of the same name from the other library. One way of avoiding this confusion is to compile PCRE with the addition of -Dregcomp=PCREregcomp (and similarly for the other POSIX functions) to the compiler flags (CFLAGS if you are using "configure" -- see below). This has the effect of renaming the functions so that the names no longer clash. Of course, you have to do the same thing for your applications, or write them using the new names. Documentation for PCRE ---------------------- If you install PCRE in the normal way on a Unix-like system, you will end up with a set of man pages whose names all start with "pcre". The one that is just called "pcre" lists all the others. In addition to these man pages, the PCRE documentation is supplied in two other forms: 1. There are files called doc/pcre.txt, doc/pcregrep.txt, and doc/pcretest.txt in the source distribution. The first of these is a concatenation of the text forms of all the section 3 man pages except those that summarize individual functions. The other two are the text forms of the section 1 man pages for the pcregrep and pcretest commands. These text forms are provided for ease of scanning with text editors or similar tools. They are installed in /share/doc/pcre, where is the installation prefix (defaulting to /usr/local). 2. A set of files containing all the documentation in HTML form, hyperlinked in various ways, and rooted in a file called index.html, is distributed in doc/html and installed in /share/doc/pcre/html. Contributions by users of PCRE ------------------------------ You can find contributions from PCRE users in the directory ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/Contrib There is a README file giving brief descriptions of what they are. Some are complete in themselves; others are pointers to URLs containing relevant files. Some of this material is likely to be well out-of-date. Several of the earlier contributions provided support for compiling PCRE on various flavours of Windows (I myself do not use Windows). Nowadays there is more Windows support in the standard distribution, so these contibutions have been archived. Building PCRE on non-Unix systems --------------------------------- For a non-Unix system, please read the comments in the file NON-UNIX-USE, though if your system supports the use of "configure" and "make" you may be able to build PCRE in the same way as for Unix-like systems. PCRE has been compiled on many different operating systems. It should be straightforward to build PCRE on any system that has a Standard C compiler and library, because it uses only Standard C functions. Building PCRE on Unix-like systems ---------------------------------- If you are using HP's ANSI C++ compiler (aCC), please see the special note in the section entitled "Using HP's ANSI C++ compiler (aCC)" below. The following instructions assume the use of the widely used "configure, make, make install" process. There is also some experimental support for "cmake" in the PCRE distribution, but it is incomplete and not documented. However, if you are a "cmake" user, you might want to try it. To build PCRE on a Unix-like system, first run the "configure" command from the PCRE distribution directory, with your current directory set to the directory where you want the files to be created. This command is a standard GNU "autoconf" configuration script, for which generic instructions are supplied in the file INSTALL. Most commonly, people build PCRE within its own distribution directory, and in this case, on many systems, just running "./configure" is sufficient. However, the usual methods of changing standard defaults are available. For example: CFLAGS='-O2 -Wall' ./configure --prefix=/opt/local specifies that the C compiler should be run with the flags '-O2 -Wall' instead of the default, and that "make install" should install PCRE under /opt/local instead of the default /usr/local. If you want to build in a different directory, just run "configure" with that directory as current. For example, suppose you have unpacked the PCRE source into /source/pcre/pcre-xxx, but you want to build it in /build/pcre/pcre-xxx: cd /build/pcre/pcre-xxx /source/pcre/pcre-xxx/configure PCRE is written in C and is normally compiled as a C library. However, it is possible to build it as a C++ library, though the provided building apparatus does not have any features to support this. There are some optional features that can be included or omitted from the PCRE library. You can read more about them in the pcrebuild man page. . If you want to suppress the building of the C++ wrapper library, you can add --disable-cpp to the "configure" command. Otherwise, when "configure" is run, it will try to find a C++ compiler and C++ header files, and if it succeeds, it will try to build the C++ wrapper. . If you want to make use of the support for UTF-8 character strings in PCRE, you must add --enable-utf8 to the "configure" command. Without it, the code for handling UTF-8 is not included in the library. (Even when included, it still has to be enabled by an option at run time.) . If, in addition to support for UTF-8 character strings, you want to include support for the \P, \p, and \X sequences that recognize Unicode character properties, you must add --enable-unicode-properties to the "configure" command. This adds about 30K to the size of the library (in the form of a property table); only the basic two-letter properties such as Lu are supported. . You can build PCRE to recognize either CR or LF or the sequence CRLF or any of the preceding, or any of the Unicode newline sequences as indicating the end of a line. Whatever you specify at build time is the default; the caller of PCRE can change the selection at run time. The default newline indicator is a single LF character (the Unix standard). You can specify the default newline indicator by adding --enable-newline-is-cr or --enable-newline-is-lf or --enable-newline-is-crlf or --enable-newline-is-anycrlf or --enable-newline-is-any to the "configure" command, respectively. If you specify --enable-newline-is-cr or --enable-newline-is-crlf, some of the standard tests will fail, because the lines in the test files end with LF. Even if the files are edited to change the line endings, there are likely to be some failures. With --enable-newline-is-anycrlf or --enable-newline-is-any, many tests should succeed, but there may be some failures. . When called via the POSIX interface, PCRE uses malloc() to get additional storage for processing capturing parentheses if there are more than 10 of them in a pattern. You can increase this threshold by setting, for example, --with-posix-malloc-threshold=20 on the "configure" command. . PCRE has a counter that can be set to limit the amount of resources it uses. If the limit is exceeded during a match, the match fails. The default is ten million. You can change the default by setting, for example, --with-match-limit=500000 on the "configure" command. This is just the default; individual calls to pcre_exec() can supply their own value. There is more discussion on the pcreapi man page. . There is a separate counter that limits the depth of recursive function calls during a matching process. This also has a default of ten million, which is essentially "unlimited". You can change the default by setting, for example, --with-match-limit-recursion=500000 Recursive function calls use up the runtime stack; running out of stack can cause programs to crash in strange ways. There is a discussion about stack sizes in the pcrestack man page. . The default maximum compiled pattern size is around 64K. You can increase this by adding --with-link-size=3 to the "configure" command. You can increase it even more by setting --with-link-size=4, but this is unlikely ever to be necessary. Increasing the internal link size will reduce performance. . You can build PCRE so that its internal match() function that is called from pcre_exec() does not call itself recursively. Instead, it uses memory blocks obtained from the heap via the special functions pcre_stack_malloc() and pcre_stack_free() to save data that would otherwise be saved on the stack. To build PCRE like this, use --disable-stack-for-recursion on the "configure" command. PCRE runs more slowly in this mode, but it may be necessary in environments with limited stack sizes. This applies only to the pcre_exec() function; it does not apply to pcre_dfa_exec(), which does not use deeply nested recursion. There is a discussion about stack sizes in the pcrestack man page. . For speed, PCRE uses four tables for manipulating and identifying characters whose code point values are less than 256. By default, it uses a set of tables for ASCII encoding that is part of the distribution. If you specify --enable-rebuild-chartables a program called dftables is compiled and run in the default C locale when you obey "make". It builds a source file called pcre_chartables.c. If you do not specify this option, pcre_chartables.c is created as a copy of pcre_chartables.c.dist. See "Character tables" below for further information. . It is possible to compile PCRE for use on systems that use EBCDIC as their default character code (as opposed to ASCII) by specifying --enable-ebcdic This automatically implies --enable-rebuild-chartables (see above). The "configure" script builds the following files for the basic C library: . Makefile is the makefile that builds the library . config.h contains build-time configuration options for the library . pcre.h is the public PCRE header file . pcre-config is a script that shows the settings of "configure" options . libpcre.pc is data for the pkg-config command . libtool is a script that builds shared and/or static libraries . RunTest is a script for running tests on the basic C library . RunGrepTest is a script for running tests on the pcregrep command Versions of config.h and pcre.h are distributed in the PCRE tarballs under the names config.h.generic and pcre.h.generic. These are provided for the benefit of those who have to built PCRE without the benefit of "configure". If you use "configure", the .generic versions are not used. If a C++ compiler is found, the following files are also built: . libpcrecpp.pc is data for the pkg-config command . pcrecpparg.h is a header file for programs that call PCRE via the C++ wrapper . pcre_stringpiece.h is the header for the C++ "stringpiece" functions The "configure" script also creates config.status, which is an executable script that can be run to recreate the configuration, and config.log, which contains compiler output from tests that "configure" runs. Once "configure" has run, you can run "make". It builds two libraries, called libpcre and libpcreposix, a test program called pcretest, a demonstration program called pcredemo, and the pcregrep command. If a C++ compiler was found on your system, "make" also builds the C++ wrapper library, which is called libpcrecpp, and some test programs called pcrecpp_unittest, pcre_scanner_unittest, and pcre_stringpiece_unittest. Building the C++ wrapper can be disabled by adding --disable-cpp to the "configure" command. The command "make check" runs all the appropriate tests. Details of the PCRE tests are given below in a separate section of this document. You can use "make install" to install PCRE into live directories on your system. The following are installed (file names are all relative to the that is set when "configure" is run): Commands (bin): pcretest pcregrep pcre-config Libraries (lib): libpcre libpcreposix libpcrecpp (if C++ support is enabled) Configuration information (lib/pkgconfig): libpcre.pc libpcrecpp.pc (if C++ support is enabled) Header files (include): pcre.h pcreposix.h pcre_scanner.h ) pcre_stringpiece.h ) if C++ support is enabled pcrecpp.h ) pcrecpparg.h ) Man pages (share/man/man{1,3}): pcregrep.1 pcretest.1 pcre.3 pcre*.3 (lots more pages, all starting "pcre") HTML documentation (share/doc/pcre/html): index.html *.html (lots more pages, hyperlinked from index.html) Text file documentation (share/doc/pcre): AUTHORS COPYING ChangeLog LICENCE NEWS README pcre.txt (a concatenation of the man(3) pages) pcretest.txt the pcretest man page pcregrep.txt the pcregrep man page Note that the pcredemo program that is built by "configure" is *not* installed anywhere. It is a demonstration for programmers wanting to use PCRE. If you want to remove PCRE from your system, you can run "make uninstall". This removes all the files that "make install" installed. However, it does not remove any directories, because these are often shared with other programs. Retrieving configuration information on Unix-like systems --------------------------------------------------------- Running "make install" installs the command pcre-config, which can be used to recall information about the PCRE configuration and installation. For example: pcre-config --version prints the version number, and pcre-config --libs outputs information about where the library is installed. This command can be included in makefiles for programs that use PCRE, saving the programmer from having to remember too many details. The pkg-config command is another system for saving and retrieving information about installed libraries. Instead of separate commands for each library, a single command is used. For example: pkg-config --cflags pcre The data is held in *.pc files that are installed in a directory called /lib/pkgconfig. Shared libraries on Unix-like systems ------------------------------------- The default distribution builds PCRE as shared libraries and static libraries, as long as the operating system supports shared libraries. Shared library support relies on the "libtool" script which is built as part of the "configure" process. The libtool script is used to compile and link both shared and static libraries. They are placed in a subdirectory called .libs when they are newly built. The programs pcretest and pcregrep are built to use these uninstalled libraries (by means of wrapper scripts in the case of shared libraries). When you use "make install" to install shared libraries, pcregrep and pcretest are automatically re-built to use the newly installed shared libraries before being installed themselves. However, the versions left in the build directory still use the uninstalled libraries. To build PCRE using static libraries only you must use --disable-shared when configuring it. For example: ./configure --prefix=/usr/gnu --disable-shared Then run "make" in the usual way. Similarly, you can use --disable-static to build only shared libraries. Cross-compiling on Unix-like systems ------------------------------------ You can specify CC and CFLAGS in the normal way to the "configure" command, in order to cross-compile PCRE for some other host. However, you should NOT specify --enable-rebuild-chartables, because if you do, the dftables.c source file is compiled and run on the local host, in order to generate the inbuilt character tables (the pcre_chartables.c file). This will probably not work, because dftables.c needs to be compiled with the local compiler, not the cross compiler. When --enable-rebuild-chartables is not specified, pcre_chartables.c is created by making a copy of pcre_chartables.c.dist, which is a default set of tables that assumes ASCII code. Cross-compiling with the default tables should not be a problem. If you need to modify the character tables when cross-compiling, you should move pcre_chartables.c.dist out of the way, then compile dftables.c by hand and run it on the local host to make a new version of pcre_chartables.c.dist. Then when you cross-compile PCRE this new version of the tables will be used. Using HP's ANSI C++ compiler (aCC) ---------------------------------- Unless C++ support is disabled by specifying the "--disable-cpp" option of the "configure" script, you must include the "-AA" option in the CXXFLAGS environment variable in order for the C++ components to compile correctly. Also, note that the aCC compiler on PA-RISC platforms may have a defect whereby needed libraries fail to get included when specifying the "-AA" compiler option. If you experience unresolved symbols when linking the C++ programs, use the workaround of specifying the following environment variable prior to running the "configure" script: CXXLDFLAGS="-lstd_v2 -lCsup_v2" Making new tarballs ------------------- The command "make dist" creates three PCRE tarballs, in tar.gz, tar.bz2, and zip formats. The command "make distcheck" does the same, but then does a trial build of the new distribution to ensure that it works. If you have modified any of the man page sources in the doc directory, you should first run the PrepareRelease script before making a distribution. This script creates the .txt and HTML forms of the documentation from the man pages. Testing PCRE ------------ To test the basic PCRE library on a Unix system, run the RunTest script that is created by the configuring process. There is also a script called RunGrepTest that tests the options of the pcregrep command. If the C++ wrapper library is built, three test programs called pcrecpp_unittest, pcre_scanner_unittest, and pcre_stringpiece_unittest are also built. Both the scripts and all the program tests are run if you obey "make check" or "make test". For other systems, see the instructions in NON-UNIX-USE. The RunTest script runs the pcretest test program (which is documented in its own man page) on each of the testinput files in the testdata directory in turn, and compares the output with the contents of the corresponding testoutput files. A file called testtry is used to hold the main output from pcretest (testsavedregex is also used as a working file). To run pcretest on just one of the test files, give its number as an argument to RunTest, for example: RunTest 2 The first test file can also be fed directly into the perltest.pl script to check that Perl gives the same results. The only difference you should see is in the first few lines, where the Perl version is given instead of the PCRE version. The second set of tests check pcre_fullinfo(), pcre_info(), pcre_study(), pcre_copy_substring(), pcre_get_substring(), pcre_get_substring_list(), error detection, and run-time flags that are specific to PCRE, as well as the POSIX wrapper API. It also uses the debugging flags to check some of the internals of pcre_compile(). If you build PCRE with a locale setting that is not the standard C locale, the character tables may be different (see next paragraph). In some cases, this may cause failures in the second set of tests. For example, in a locale where the isprint() function yields TRUE for characters in the range 128-255, the use of [:isascii:] inside a character class defines a different set of characters, and this shows up in this test as a difference in the compiled code, which is being listed for checking. Where the comparison test output contains [\x00-\x7f] the test will contain [\x00-\xff], and similarly in some other cases. This is not a bug in PCRE. The third set of tests checks pcre_maketables(), the facility for building a set of character tables for a specific locale and using them instead of the default tables. The tests make use of the "fr_FR" (French) locale. Before running the test, the script checks for the presence of this locale by running the "locale" command. If that command fails, or if it doesn't include "fr_FR" in the list of available locales, the third test cannot be run, and a comment is output to say why. If running this test produces instances of the error ** Failed to set locale "fr_FR" in the comparison output, it means that locale is not available on your system, despite being listed by "locale". This does not mean that PCRE is broken. [If you are trying to run this test on Windows, you may be able to get it to work by changing "fr_FR" to "french" everywhere it occurs.] The fourth test checks the UTF-8 support. It is not run automatically unless PCRE is built with UTF-8 support. To do this you must set --enable-utf8 when running "configure". This file can be also fed directly to the perltest script, provided you are running Perl 5.8 or higher. (For Perl 5.6, a small patch, commented in the script, can be be used.) The fifth test checks error handling with UTF-8 encoding, and internal UTF-8 features of PCRE that are not relevant to Perl. The sixth test checks the support for Unicode character properties. It it not run automatically unless PCRE is built with Unicode property support. To to this you must set --enable-unicode-properties when running "configure". The seventh, eighth, and ninth tests check the pcre_dfa_exec() alternative matching function, in non-UTF-8 mode, UTF-8 mode, and UTF-8 mode with Unicode property support, respectively. The eighth and ninth tests are not run automatically unless PCRE is build with the relevant support. Character tables ---------------- For speed, PCRE uses four tables for manipulating and identifying characters whose code point values are less than 256. The final argument of the pcre_compile() function is a pointer to a block of memory containing the concatenated tables. A call to pcre_maketables() can be used to generate a set of tables in the current locale. If the final argument for pcre_compile() is passed as NULL, a set of default tables that is built into the binary is used. The source file called pcre_chartables.c contains the default set of tables. By default, this is created as a copy of pcre_chartables.c.dist, which contains tables for ASCII coding. However, if --enable-rebuild-chartables is specified for ./configure, a different version of pcre_chartables.c is built by the program dftables (compiled from dftables.c), which uses the ANSI C character handling functions such as isalnum(), isalpha(), isupper(), islower(), etc. to build the table sources. This means that the default C locale which is set for your system will control the contents of these default tables. You can change the default tables by editing pcre_chartables.c and then re-building PCRE. If you do this, you should take care to ensure that the file does not get automatically re-generated. The best way to do this is to move pcre_chartables.c.dist out of the way and replace it with your customized tables. When the dftables program is run as a result of --enable-rebuild-chartables, it uses the default C locale that is set on your system. It does not pay attention to the LC_xxx environment variables. In other words, it uses the system's default locale rather than whatever the compiling user happens to have set. If you really do want to build a source set of character tables in a locale that is specified by the LC_xxx variables, you can run the dftables program by hand with the -L option. For example: ./dftables -L pcre_chartables.c.special The first two 256-byte tables provide lower casing and case flipping functions, respectively. The next table consists of three 32-byte bit maps which identify digits, "word" characters, and white space, respectively. These are used when building 32-byte bit maps that represent character classes for code points less than 256. The final 256-byte table has bits indicating various character types, as follows: 1 white space character 2 letter 4 decimal digit 8 hexadecimal digit 16 alphanumeric or '_' 128 regular expression metacharacter or binary zero You should not alter the set of characters that contain the 128 bit, as that will cause PCRE to malfunction. File manifest ------------- The distribution should contain the following files: (A) Source files of the PCRE library functions and their headers: dftables.c auxiliary program for building pcre_chartables.c when --enable-rebuild-chartables is specified pcre_chartables.c.dist a default set of character tables that assume ASCII coding; used, unless --enable-rebuild-chartables is specified, by copying to pcre_chartables.c pcreposix.c ) pcre_compile.c ) pcre_config.c ) pcre_dfa_exec.c ) pcre_exec.c ) pcre_fullinfo.c ) pcre_get.c ) sources for the functions in the library, pcre_globals.c ) and some internal functions that they use pcre_info.c ) pcre_maketables.c ) pcre_newline.c ) pcre_ord2utf8.c ) pcre_refcount.c ) pcre_study.c ) pcre_tables.c ) pcre_try_flipped.c ) pcre_ucp_searchfuncs.c ) pcre_valid_utf8.c ) pcre_version.c ) pcre_xclass.c ) pcre_printint.src ) debugging function that is #included in pcretest, ) and can also be #included in pcre_compile() pcre.h.in template for pcre.h when built by "configure" pcreposix.h header for the external POSIX wrapper API pcre_internal.h header for internal use ucp.h ) headers concerned with ucpinternal.h ) Unicode property handling ucptable.h ) (this one is the data table) config.h.in template for config.h, which is built by "configure" pcrecpp.h public header file for the C++ wrapper pcrecpparg.h.in template for another C++ header file pcre_scanner.h public header file for C++ scanner functions pcrecpp.cc ) pcre_scanner.cc ) source for the C++ wrapper library pcre_stringpiece.h.in template for pcre_stringpiece.h, the header for the C++ stringpiece functions pcre_stringpiece.cc source for the C++ stringpiece functions (B) Source files for programs that use PCRE: pcredemo.c simple demonstration of coding calls to PCRE pcregrep.c source of a grep utility that uses PCRE pcretest.c comprehensive test program (C) Auxiliary files: 132html script to turn "man" pages into HTML AUTHORS information about the author of PCRE ChangeLog log of changes to the code CleanTxt script to clean nroff output for txt man pages Detrail script to remove trailing spaces HACKING some notes about the internals of PCRE INSTALL generic installation instructions LICENCE conditions for the use of PCRE COPYING the same, using GNU's standard name Makefile.in ) template for Unix Makefile, which is built by ) "configure" Makefile.am ) the automake input that was used to create ) Makefile.in NEWS important changes in this release NON-UNIX-USE notes on building PCRE on non-Unix systems PrepareRelease script to make preparations for "make dist" README this file RunTest a Unix shell script for running tests RunGrepTest a Unix shell script for pcregrep tests aclocal.m4 m4 macros (generated by "aclocal") config.guess ) files used by libtool, config.sub ) used only when building a shared library configure a configuring shell script (built by autoconf) configure.ac ) the autoconf input that was used to build ) "configure" and config.h depcomp ) script to find program dependencies, generated by ) automake doc/*.3 man page sources for the PCRE functions doc/*.1 man page sources for pcregrep and pcretest doc/index.html.src the base HTML page doc/html/* HTML documentation doc/pcre.txt plain text version of the man pages doc/pcretest.txt plain text documentation of test program doc/perltest.txt plain text documentation of Perl test program install-sh a shell script for installing files libpcre.pc.in template for libpcre.pc for pkg-config libpcrecpp.pc.in template for libpcrecpp.pc for pkg-config ltmain.sh file used to build a libtool script missing ) common stub for a few missing GNU programs while ) installing, generated by automake mkinstalldirs script for making install directories perltest.pl Perl test program pcre-config.in source of script which retains PCRE information pcrecpp_unittest.cc ) pcre_scanner_unittest.cc ) test programs for the C++ wrapper pcre_stringpiece_unittest.cc ) testdata/testinput* test data for main library tests testdata/testoutput* expected test results testdata/grep* input and output for pcregrep tests (D) Auxiliary files for cmake support CMakeLists.txt config-cmake.h.in (E) Auxiliary files for VPASCAL makevp.bat makevp_c.txt makevp_l.txt pcregexp.pas (F) Auxiliary files for building PCRE "by hand" pcre.h.generic ) a version of the public PCRE header file ) for use in non-"configure" environments config.h.generic ) a version of config.h for use in non-"configure" ) environments (F) Miscellaneous RunTest.bat a script for running tests under Windows Philip Hazel Email local part: ph10 Email domain: cam.ac.uk Last updated: 24 April 2007 libsynthesis-3.4.0.47.1/src/pcre/RunGrepTest000066400000000000000000000304171226375725500205360ustar00rootroot00000000000000#! /bin/sh # Run pcregrep tests. The assumption is that the PCRE tests check the library # itself. What we are checking here is the file handling and options that are # supported by pcregrep. # Set the C locale, so that sort(1) behaves predictably. LC_ALL=C export LC_ALL pcregrep=`pwd`/pcregrep echo " " echo "Testing pcregrep" $pcregrep -V cf="diff -ub" valgrind= while [ $# -gt 0 ] ; do case $1 in valgrind) valgrind="valgrind -q --leak-check=no";; *) echo "Unknown argument $1"; exit 1;; esac shift done # If PCRE has been built in a directory other than the source directory, and # this test is being run from "make check" as usual, then $(srcdir) will be # set. If not, set it to the current directory. We then arrange to run the # pcregrep command in the source directory so that the file names that appear # in the output are always the same. if [ -z "$srcdir" -o ! -d "$srcdir/testdata" ] ; then srcdir=. fi # Check for the availability of UTF-8 support ./pcretest -C | ./pcregrep "No UTF-8 support" >/dev/null utf8=$? echo "---------------------------- Test 1 ------------------------------" >testtry (cd $srcdir; $valgrind $pcregrep PATTERN ./testdata/grepinput) >>testtry echo "---------------------------- Test 2 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep '^PATTERN' ./testdata/grepinput) >>testtry echo "---------------------------- Test 3 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -in PATTERN ./testdata/grepinput) >>testtry echo "---------------------------- Test 4 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -ic PATTERN ./testdata/grepinput) >>testtry echo "---------------------------- Test 5 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -in PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtry echo "---------------------------- Test 6 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -inh PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtry echo "---------------------------- Test 7 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -il PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtry echo "---------------------------- Test 8 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -l PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtry echo "---------------------------- Test 9 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -q PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 10 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -q NEVER-PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 11 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -vn pattern ./testdata/grepinputx) >>testtry echo "---------------------------- Test 12 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -ix pattern ./testdata/grepinputx) >>testtry echo "---------------------------- Test 13 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -f./testdata/greplist ./testdata/grepinputx) >>testtry echo "---------------------------- Test 14 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -w pat ./testdata/grepinput ./testdata/grepinputx) >>testtry echo "---------------------------- Test 15 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep 'abc^*' ./testdata/grepinput) 2>>testtry >>testtry echo "---------------------------- Test 16 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep abc ./testdata/grepinput ./testdata/nonexistfile) 2>>testtry >>testtry echo "---------------------------- Test 17 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -M 'the\noutput' ./testdata/grepinput) >>testtry echo "---------------------------- Test 18 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -Mn '(the\noutput|dog\.\n--)' ./testdata/grepinput) >>testtry echo "---------------------------- Test 19 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -Mix 'Pattern' ./testdata/grepinputx) >>testtry echo "---------------------------- Test 20 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -Mixn 'complete pair\nof lines' ./testdata/grepinputx) >>testtry echo "---------------------------- Test 21 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -nA3 'four' ./testdata/grepinputx) >>testtry echo "---------------------------- Test 22 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -nB3 'four' ./testdata/grepinputx) >>testtry echo "---------------------------- Test 23 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -C3 'four' ./testdata/grepinputx) >>testtry echo "---------------------------- Test 24 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -A9 'four' ./testdata/grepinputx) >>testtry echo "---------------------------- Test 25 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -nB9 'four' ./testdata/grepinputx) >>testtry echo "---------------------------- Test 26 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -A9 -B9 'four' ./testdata/grepinputx) >>testtry echo "---------------------------- Test 27 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -A10 'four' ./testdata/grepinputx) >>testtry echo "---------------------------- Test 28 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -nB10 'four' ./testdata/grepinputx) >>testtry echo "---------------------------- Test 29 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -C12 -B10 'four' ./testdata/grepinputx) >>testtry echo "---------------------------- Test 30 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -inB3 'pattern' ./testdata/grepinput ./testdata/grepinputx) >>testtry echo "---------------------------- Test 31 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -inA3 'pattern' ./testdata/grepinput ./testdata/grepinputx) >>testtry echo "---------------------------- Test 32 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -L 'fox' ./testdata/grepinput ./testdata/grepinputx) >>testtry echo "---------------------------- Test 33 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep 'fox' ./testdata/grepnonexist) >>testtry 2>&1 echo "RC=$?" >>testtry echo "---------------------------- Test 34 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -s 'fox' ./testdata/grepnonexist) >>testtry 2>&1 echo "RC=$?" >>testtry echo "---------------------------- Test 35 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -L -r --include=grepinputx 'fox' ./testdata) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 36 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -L -r --include=grepinput --exclude 'grepinput$' 'fox' ./testdata | sort) >>testtry echo "RC=$?" >>testtry echo "---------------------------- Test 37 -----------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep '^(a+)*\d' ./testdata/grepinput) >>testtry 2>teststderr echo "RC=$?" >>testtry echo "======== STDERR ========" >>testtry cat teststderr >>testtry echo "---------------------------- Test 38 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep '>\x00<' ./testdata/grepinput) >>testtry echo "---------------------------- Test 39 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -A1 'before the binary zero' ./testdata/grepinput) >>testtry echo "---------------------------- Test 40 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -B1 'after the binary zero' ./testdata/grepinput) >>testtry echo "---------------------------- Test 41 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -B1 -o '\w+ the binary zero' ./testdata/grepinput) >>testtry echo "---------------------------- Test 41 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -B1 -onH '\w+ the binary zero' ./testdata/grepinput) >>testtry echo "---------------------------- Test 42 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -on 'before|zero|after' ./testdata/grepinput) >>testtry echo "---------------------------- Test 43 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -on -e before -e zero -e after ./testdata/grepinput) >>testtry echo "---------------------------- Test 44 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -on -f ./testdata/greplist -e binary ./testdata/grepinput) >>testtry echo "---------------------------- Test 45 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -e abc -e '(unclosed' ./testdata/grepinput) 2>>testtry >>testtry echo "---------------------------- Test 46 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -Fx "AB.VE elephant" ./testdata/grepinput) >>testtry echo "---------------------------- Test 47 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -F "AB.VE elephant" ./testdata/grepinput) >>testtry echo "---------------------------- Test 48 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -F -e DATA -e "AB.VE elephant" ./testdata/grepinput) >>testtry echo "---------------------------- Test 49 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep "^(abc|def|ghi|jkl)" ./testdata/grepinputx) >>testtry echo "---------------------------- Test 50 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -Mv "brown\sfox" ./testdata/grepinputv) >>testtry # Now compare the results. $cf $srcdir/testdata/grepoutput testtry if [ $? != 0 ] ; then exit 1; fi # These tests require UTF-8 support if [ $utf8 -ne 0 ] ; then echo "Testing pcregrep UTF-8 features" echo "---------------------------- Test U1 ------------------------------" >testtry (cd $srcdir; $valgrind $pcregrep -n -u --newline=any "^X" ./testdata/grepinput8) >>testtry echo "---------------------------- Test U2 ------------------------------" >>testtry (cd $srcdir; $valgrind $pcregrep -n -u -C 3 --newline=any "Match" ./testdata/grepinput8) >>testtry $cf $srcdir/testdata/grepoutput8 testtry if [ $? != 0 ] ; then exit 1; fi else echo "Skipping pcregrep UTF-8 tests: no UTF-8 support in PCRE library" fi # We go to some contortions to try to ensure that the tests for the various # newline settings will work in environments where the normal newline sequence # is not \n. Do not use exported files, whose line endings might be changed. # Instead, create an input file using printf so that its contents are exactly # what we want. Note the messy fudge to get printf to write a string that # starts with a hyphen. echo "Testing pcregrep newline settings" printf "abc\rdef\r\nghi\njkl" >testNinput printf "%c--------------------------- Test N1 ------------------------------\r\n" - >testtry $valgrind $pcregrep -n -N CR "^(abc|def|ghi|jkl)" testNinput >>testtry printf "%c--------------------------- Test N2 ------------------------------\r\n" - >>testtry $valgrind $pcregrep -n --newline=crlf "^(abc|def|ghi|jkl)" testNinput >>testtry printf "%c--------------------------- Test N3 ------------------------------\r\n" - >>testtry pattern=`printf 'def\rjkl'` $valgrind $pcregrep -n --newline=cr -F "$pattern" testNinput >>testtry printf "%c--------------------------- Test N4 ------------------------------\r\n" - >>testtry pattern=`printf 'xxx\r\njkl'` $valgrind $pcregrep -n --newline=crlf -F "$pattern" testNinput >>testtry printf "%c--------------------------- Test N5 ------------------------------\r\n" - >>testtry $valgrind $pcregrep -n --newline=any "^(abc|def|ghi|jkl)" testNinput >>testtry printf "%c--------------------------- Test N6 ------------------------------\r\n" - >>testtry $valgrind $pcregrep -n --newline=anycrlf "^(abc|def|ghi|jkl)" testNinput >>testtry $cf $srcdir/testdata/grepoutputN testtry if [ $? != 0 ] ; then exit 1; fi exit 0 # End libsynthesis-3.4.0.47.1/src/pcre/RunTest000066400000000000000000000153431226375725500177210ustar00rootroot00000000000000#! /bin/sh # Run PCRE tests cf="diff -u" valgrind= testdata=testdata if [ -n "$srcdir" -a -d "$srcdir" ] ; then testdata="$srcdir/testdata" fi # Find which optional facilities are available case `./pcretest -C | ./pcregrep 'Internal link size'` in *2) link_size=2;; *3) link_size=3;; *4) link_size=4;; *) echo "Failed to find internal link size"; exit 1;; esac ./pcretest -C | ./pcregrep 'No UTF-8 support' >/dev/null utf8=$? ./pcretest -C | ./pcregrep 'No Unicode properties support' >/dev/null ucp=$? # Select which tests to run; for those that are explicitly requested, check # that the necessary optional facilities are available. do1=no do2=no do3=no do4=no do5=no do6=no do7=no do8=no do9=no do10=no while [ $# -gt 0 ] ; do case $1 in 1) do1=yes;; 2) do2=yes;; 3) do3=yes;; 4) do4=yes;; 5) do5=yes;; 6) do6=yes;; 7) do7=yes;; 8) do8=yes;; 9) do9=yes;; 10) do10=yes;; valgrind) valgrind="valgrind -q";; *) echo "Unknown test number $1"; exit 1;; esac shift done if [ $utf8 -eq 0 ] ; then if [ $do4 = yes ] ; then echo "Can't run test 4 because UTF-8 support is not configured" exit 1 fi if [ $do5 = yes ] ; then echo "Can't run test 5 because UTF-8 support is not configured" exit 1 fi if [ $do8 = yes ] ; then echo "Can't run test 8 because UTF-8 support is not configured" exit 1 fi fi if [ $ucp -eq 0 ] ; then if [ $do6 = yes ] ; then echo "Can't run test 6 because Unicode property support is not configured" exit 1 fi if [ $do9 = yes ] ; then echo "Can't run test 9 because Unicode property support is not configured" exit 1 fi if [ $do10 = yes ] ; then echo "Can't run test 10 because Unicode property support is not configured" exit 1 fi fi if [ $link_size -ne 2 ] ; then if [ $do10 = yes ] ; then echo "Can't run test 10 because the link size ($link_size) is not 2" exit 1 fi fi # If no specific tests were requested, select all that are relevant. if [ $do1 = no -a $do2 = no -a $do3 = no -a $do4 = no -a \ $do5 = no -a $do6 = no -a $do7 = no -a $do8 = no -a \ $do9 = no -a $do10 = no ] ; then do1=yes do2=yes do3=yes if [ $utf8 -ne 0 ] ; then do4=yes; fi if [ $utf8 -ne 0 ] ; then do5=yes; fi if [ $utf8 -ne 0 -a $ucp -ne 0 ] ; then do6=yes; fi do7=yes if [ $utf8 -ne 0 ] ; then do8=yes; fi if [ $utf8 -ne 0 -a $ucp -ne 0 ] ; then do9=yes; fi if [ $link_size -eq 2 -a $ucp -ne 0 ] ; then do10=yes; fi fi # Show which release echo "" echo PCRE C library tests ./pcretest /dev/null # Primary test, Perl-compatible if [ $do1 = yes ] ; then echo "Test 1: main functionality (Perl compatible)" $valgrind ./pcretest -q $testdata/testinput1 testtry if [ $? = 0 ] ; then $cf $testdata/testoutput1 testtry if [ $? != 0 ] ; then exit 1; fi else exit 1 fi echo "OK" fi # PCRE tests that are not Perl-compatible - API & error tests, mostly if [ $do2 = yes ] ; then echo "Test 2: API and error handling (not Perl compatible)" $valgrind ./pcretest -q $testdata/testinput2 testtry if [ $? = 0 ] ; then $cf $testdata/testoutput2 testtry if [ $? != 0 ] ; then exit 1; fi else exit 1 fi echo "OK" fi # Locale-specific tests, provided that either the "fr_FR" or the "french" # locale is available. The former is the Unix-like standard; the latter is # for Windows. if [ $do3 = yes ] ; then locale -a | grep '^fr_FR$' >/dev/null if [ $? -eq 0 ] ; then locale=fr_FR infile=$testdata/testinput3 outfile=$testdata/testoutput3 else locale -a | grep '^french$' >/dev/null if [ $? -eq 0 ] ; then locale=french sed 's/fr_FR/french/' $testdata/testinput3 >test3input sed 's/fr_FR/french/' $testdata/testoutput3 >test3output infile=test3input outfile=test3output else locale= fi fi if [ "$locale" != "" ] ; then echo "Test 3: locale-specific features (using '$locale' locale)" $valgrind ./pcretest -q $infile testtry if [ $? = 0 ] ; then $cf $outfile testtry if [ $? != 0 ] ; then echo " " echo "Locale test did not run entirely successfully." echo "This usually means that there is a problem with the locale" echo "settings rather than a bug in PCRE." else echo "OK" fi else exit 1 fi else echo "Cannot test locale-specific features - neither the 'fr_FR' nor the" echo "'french' locale exists, or the \"locale\" command is not available" echo "to check for them." echo " " fi fi # Additional tests for UTF8 support if [ $do4 = yes ] ; then echo "Test 4: UTF-8 support (Perl compatible)" $valgrind ./pcretest -q $testdata/testinput4 testtry if [ $? = 0 ] ; then $cf $testdata/testoutput4 testtry if [ $? != 0 ] ; then exit 1; fi else exit 1 fi echo "OK" fi if [ $do5 = yes ] ; then echo "Test 5: API and internals for UTF-8 support (not Perl compatible)" $valgrind ./pcretest -q $testdata/testinput5 testtry if [ $? = 0 ] ; then $cf $testdata/testoutput5 testtry if [ $? != 0 ] ; then exit 1; fi else exit 1 fi echo "OK" fi if [ $do6 = yes ] ; then echo "Test 6: Unicode property support" $valgrind ./pcretest -q $testdata/testinput6 testtry if [ $? = 0 ] ; then $cf $testdata/testoutput6 testtry if [ $? != 0 ] ; then exit 1; fi else exit 1 fi echo "OK" fi # Tests for DFA matching support if [ $do7 = yes ] ; then echo "Test 7: DFA matching" $valgrind ./pcretest -q -dfa $testdata/testinput7 testtry if [ $? = 0 ] ; then $cf $testdata/testoutput7 testtry if [ $? != 0 ] ; then exit 1; fi else exit 1 fi echo "OK" fi if [ $do8 = yes ] ; then echo "Test 8: DFA matching with UTF-8" $valgrind ./pcretest -q -dfa $testdata/testinput8 testtry if [ $? = 0 ] ; then $cf $testdata/testoutput8 testtry if [ $? != 0 ] ; then exit 1; fi else exit 1 fi echo "OK" fi if [ $do9 = yes ] ; then echo "Test 9: DFA matching with Unicode properties" $valgrind ./pcretest -q -dfa $testdata/testinput9 testtry if [ $? = 0 ] ; then $cf $testdata/testoutput9 testtry if [ $? != 0 ] ; then exit 1; fi else exit 1 fi echo "OK" fi # Test of internal offsets and code sizes. This test is run only when there # is Unicode property support and the link size is 2. The actual tests are # mostly the same as in some of the above, but in this test we inspect some # offsets and sizes that require a known link size. This is a doublecheck for # the maintainer, just in case something changes unexpectely. if [ $do10 = yes ] ; then echo "Test 10: Internal offsets and code size tests" $valgrind ./pcretest -q $testdata/testinput10 testtry if [ $? = 0 ] ; then $cf $testdata/testoutput10 testtry if [ $? != 0 ] ; then exit 1; fi else exit 1 fi echo "OK" fi # End libsynthesis-3.4.0.47.1/src/pcre/RunTest.bat000066400000000000000000000032141226375725500204600ustar00rootroot00000000000000@rem This file was contributed by Ralf Junker, and touched up by @rem Daniel Richard G. Test 10 added by Philip H. @rem @rem MS Windows batch file to run pcretest on testfiles with the correct @rem options. @rem @rem Output is written to a newly created subfolder named "testdata". setlocal if [%srcdir%]==[] set srcdir=. if [%pcretest%]==[] set pcretest=pcretest if not exist testout md testout %pcretest% -q %srcdir%\testdata\testinput1 > testout\testoutput1 %pcretest% -q %srcdir%\testdata\testinput2 > testout\testoutput2 %pcretest% -q %srcdir%\testdata\testinput3 > testout\testoutput3 %pcretest% -q %srcdir%\testdata\testinput4 > testout\testoutput4 %pcretest% -q %srcdir%\testdata\testinput5 > testout\testoutput5 %pcretest% -q %srcdir%\testdata\testinput6 > testout\testoutput6 %pcretest% -q -dfa %srcdir%\testdata\testinput7 > testout\testoutput7 %pcretest% -q -dfa %srcdir%\testdata\testinput8 > testout\testoutput8 %pcretest% -q -dfa %srcdir%\testdata\testinput9 > testout\testoutput9 %pcretest% -q %srcdir%\testdata\testinput10 > testout\testoutput10 fc /n %srcdir%\testdata\testoutput1 testout\testoutput1 fc /n %srcdir%\testdata\testoutput2 testout\testoutput2 rem fc /n %srcdir%\testdata\testoutput3 testout\testoutput3 fc /n %srcdir%\testdata\testoutput4 testout\testoutput4 fc /n %srcdir%\testdata\testoutput5 testout\testoutput5 fc /n %srcdir%\testdata\testoutput6 testout\testoutput6 fc /n %srcdir%\testdata\testoutput7 testout\testoutput7 fc /n %srcdir%\testdata\testoutput8 testout\testoutput8 fc /n %srcdir%\testdata\testoutput9 testout\testoutput9 fc /n %srcdir%\testdata\testoutput10 testout\testoutput10 libsynthesis-3.4.0.47.1/src/pcre/config-cmake.h.in000066400000000000000000000013341226375725500214660ustar00rootroot00000000000000/* config.h for CMake builds */ #cmakedefine HAVE_DIRENT_H #cmakedefine HAVE_UNISTD_H #cmakedefine HAVE_SYS_STAT_H #cmakedefine HAVE_SYS_TYPES_H #cmakedefine HAVE_TYPE_TRAITS_H #cmakedefine HAVE_BITS_TYPE_TRAITS_H #cmakedefine HAVE_BCOPY #cmakedefine HAVE_MEMMOVE #cmakedefine HAVE_STRERROR #cmakedefine PCRE_STATIC #cmakedefine SUPPORT_UTF8 #cmakedefine SUPPORT_UCP #cmakedefine EBCDIC #cmakedefine NO_RECURSE #define NEWLINE @NEWLINE@ #define POSIX_MALLOC_THRESHOLD @PCRE_POSIX_MALLOC_THRESHOLD@ #define LINK_SIZE @PCRE_LINK_SIZE@ #define MATCH_LIMIT @PCRE_MATCH_LIMIT@ #define MATCH_LIMIT_RECURSION @PCRE_MATCH_LIMIT_RECURSION@ #define MAX_NAME_SIZE 32 #define MAX_NAME_COUNT 10000 /* end config.h for CMake builds */ libsynthesis-3.4.0.47.1/src/pcre/config.h000066400000000000000000000221461226375725500200070ustar00rootroot00000000000000/* config.h. Generated from config.h.in by configure. */ /* config.h.in. Generated from configure.ac by autoheader. */ /* On Unix-like systems config.h.in is converted by "configure" into config.h. Some other environments also support the use of "configure". PCRE is written in Standard C, but there are a few non-standard things it can cope with, allowing it to run on SunOS4 and other "close to standard" systems. If you are going to build PCRE "by hand" on a system without "configure" you should copy the distributed config.h.generic to config.h, and then set up the macros the way you need them. Alternatively, you can avoid editing by using -D on the compiler command line to set the macro values. PCRE uses memmove() if HAVE_MEMMOVE is set to 1; otherwise it uses bcopy() if HAVE_BCOPY is set to 1. If your system has neither bcopy() nor memmove(), set them both to 0; an emulation function will be used. */ /* If you are compiling for a system that uses EBCDIC instead of ASCII character codes, define this macro as 1. On systems that can use "configure", this can be done via --enable-ebcdic. */ /* #undef EBCDIC */ /* Define to 1 if you have the `bcopy' function. */ #ifndef HAVE_BCOPY #define HAVE_BCOPY 0 // MWerks CW 9 Win MSL does not seem to have it #endif /* Define to 1 if you have the header file. */ /* #undef HAVE_BITS_TYPE_TRAITS_H */ /* Define to 1 if you have the header file. */ #ifndef HAVE_DIRENT_H #define HAVE_DIRENT_H 0 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_DLFCN_H #define HAVE_DLFCN_H 0 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_INTTYPES_H #define HAVE_INTTYPES_H 1 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_LIMITS_H #define HAVE_LIMITS_H 1 #endif /* Define to 1 if the system has the type `long long'. */ #ifndef HAVE_LONG_LONG #define HAVE_LONG_LONG 1 #endif /* Define to 1 if you have the `memmove' function. */ #ifndef HAVE_MEMMOVE #define HAVE_MEMMOVE 1 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_MEMORY_H #define HAVE_MEMORY_H 0 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_STDINT_H #define HAVE_STDINT_H 1 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_STDLIB_H #define HAVE_STDLIB_H 1 #endif /* Define to 1 if you have the `strerror' function. */ #ifndef HAVE_STRERROR #define HAVE_STRERROR 1 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_STRING #define HAVE_STRING 1 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_STRINGS_H #define HAVE_STRINGS_H 0 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_STRING_H #define HAVE_STRING_H 1 #endif /* Define to 1 if you have the `strtoll' function. */ #ifndef HAVE_STRTOLL #define HAVE_STRTOLL 0 #endif /* Define to 1 if you have the `strtoq' function. */ #ifndef HAVE_STRTOQ #define HAVE_STRTOQ 0 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_SYS_STAT_H #define HAVE_SYS_STAT_H 0 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_SYS_TYPES_H #define HAVE_SYS_TYPES_H 0 #endif /* Define to 1 if you have the header file. */ /* #undef HAVE_TYPE_TRAITS_H */ /* Define to 1 if you have the header file. */ #ifndef HAVE_UNISTD_H #define HAVE_UNISTD_H 0 #endif /* Define to 1 if the system has the type `unsigned long long'. */ #ifndef HAVE_UNSIGNED_LONG_LONG #define HAVE_UNSIGNED_LONG_LONG 1 #endif /* Define to 1 if you have the header file. */ /* #undef HAVE_WINDOWS_H */ /* The value of LINK_SIZE determines the number of bytes used to store links as offsets within the compiled regex. The default is 2, which allows for compiled patterns up to 64K long. This covers the vast majority of cases. However, PCRE can also be compiled to use 3 or 4 bytes instead. This allows for longer patterns in extreme cases. On systems that support it, "configure" can be used to override this default. */ #ifndef LINK_SIZE #define LINK_SIZE 2 #endif /* The value of MATCH_LIMIT determines the default number of times the internal match() function can be called during a single execution of pcre_exec(). There is a runtime interface for setting a different limit. The limit exists in order to catch runaway regular expressions that take for ever to determine that they do not match. The default is set very large so that it does not accidentally catch legitimate cases. On systems that support it, "configure" can be used to override this default default. */ #ifndef MATCH_LIMIT #define MATCH_LIMIT 10000000 #endif /* The above limit applies to all calls of match(), whether or not they increase the recursion depth. In some environments it is desirable to limit the depth of recursive calls of match() more strictly, in order to restrict the maximum amount of stack (or heap, if NO_RECURSE is defined) that is used. The value of MATCH_LIMIT_RECURSION applies only to recursive calls of match(). To have any useful effect, it must be less than the value of MATCH_LIMIT. The default is to use the same value as MATCH_LIMIT. There is a runtime method for setting a different limit. On systems that support it, "configure" can be used to override the default. */ #ifndef MATCH_LIMIT_RECURSION #define MATCH_LIMIT_RECURSION MATCH_LIMIT #endif /* This limit is parameterized just in case anybody ever wants to change it. Care must be taken if it is increased, because it guards against integer overflow caused by enormously large patterns. */ #ifndef MAX_NAME_COUNT #define MAX_NAME_COUNT 10000 #endif /* This limit is parameterized just in case anybody ever wants to change it. Care must be taken if it is increased, because it guards against integer overflow caused by enormously large patterns. */ #ifndef MAX_NAME_SIZE #define MAX_NAME_SIZE 32 #endif /* The value of NEWLINE determines the newline character sequence. On Unix-like systems, "configure" can be used to override the default, which is 10. The possible values are 10 (LF), 13 (CR), 3338 (CRLF), -1 (ANY), or -2 (ANYCRLF). */ #ifndef NEWLINE #define NEWLINE 10 #endif /* PCRE uses recursive function calls to handle backtracking while matching. This can sometimes be a problem on systems that have stacks of limited size. Define NO_RECURSE to get a version that doesn't use recursion in the match() function; instead it creates its own stack by steam using pcre_recurse_malloc() to obtain memory from the heap. For more detail, see the comments and other stuff just above the match() function. On systems that support it, "configure" can be used to set this in the Makefile (use --disable-stack-for-recursion). */ /* #undef NO_RECURSE */ /* Name of package */ #define PACKAGE "pcre" /* Define to the address where bug reports for this package should be sent. */ #define PACKAGE_BUGREPORT "" /* Define to the full name of this package. */ #define PACKAGE_NAME "PCRE" /* Define to the full name and version of this package. */ #define PACKAGE_STRING "PCRE 7.3" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "pcre" /* Define to the version of this package. */ #define PACKAGE_VERSION "7.3" /* If you are compiling for a system other than a Unix-like system or Win32, and it needs some magic to be inserted before the definition of a function that is exported by the library, define this macro to contain the relevant magic. If you do not define this macro, it defaults to "extern" for a C compiler and "extern C" for a C++ compiler on non-Win32 systems. This macro apears at the start of every exported function that is part of the external API. It does not appear on functions that are "external" in the C sense, but which are internal to the library. */ /* #undef PCRE_EXP_DEFN */ /* Define if linking statically (TODO: make nice with Libtool) */ /* #undef PCRE_STATIC */ /* When calling PCRE via the POSIX interface, additional working storage is required for holding the pointers to capturing substrings because PCRE requires three integers per substring, whereas the POSIX interface provides only two. If the number of expected substrings is small, the wrapper function uses space on the stack, because this is faster than using malloc() for each call. The threshold above which the stack is no longer used is defined by POSIX_MALLOC_THRESHOLD. On systems that support it, "configure" can be used to override this default. */ #ifndef POSIX_MALLOC_THRESHOLD #define POSIX_MALLOC_THRESHOLD 10 #endif /* Define to 1 if you have the ANSI C header files. */ #ifndef STDC_HEADERS #define STDC_HEADERS 1 #endif /* Define to enable support for Unicode properties */ /* #undef SUPPORT_UCP */ /* Define to enable support for the UTF-8 Unicode encoding. */ #define SUPPORT_UTF8 1 /* Version number of package */ #ifndef VERSION #define VERSION "7.3" #endif /* Define to empty if `const' does not conform to ANSI C. */ /* #undef const */ /* Define to `unsigned int' if does not define. */ /* #undef size_t */ libsynthesis-3.4.0.47.1/src/pcre/config.h.generic000066400000000000000000000220711226375725500214170ustar00rootroot00000000000000/* config.h. Generated from config.h.in by configure. */ /* config.h.in. Generated from configure.ac by autoheader. */ /* On Unix-like systems config.h.in is converted by "configure" into config.h. Some other environments also support the use of "configure". PCRE is written in Standard C, but there are a few non-standard things it can cope with, allowing it to run on SunOS4 and other "close to standard" systems. If you are going to build PCRE "by hand" on a system without "configure" you should copy the distributed config.h.generic to config.h, and then set up the macros the way you need them. Alternatively, you can avoid editing by using -D on the compiler command line to set the macro values. PCRE uses memmove() if HAVE_MEMMOVE is set to 1; otherwise it uses bcopy() if HAVE_BCOPY is set to 1. If your system has neither bcopy() nor memmove(), set them both to 0; an emulation function will be used. */ /* If you are compiling for a system that uses EBCDIC instead of ASCII character codes, define this macro as 1. On systems that can use "configure", this can be done via --enable-ebcdic. */ /* #undef EBCDIC */ /* Define to 1 if you have the `bcopy' function. */ #ifndef HAVE_BCOPY #define HAVE_BCOPY 1 #endif /* Define to 1 if you have the header file. */ /* #undef HAVE_BITS_TYPE_TRAITS_H */ /* Define to 1 if you have the header file. */ #ifndef HAVE_DIRENT_H #define HAVE_DIRENT_H 1 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_DLFCN_H #define HAVE_DLFCN_H 1 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_INTTYPES_H #define HAVE_INTTYPES_H 1 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_LIMITS_H #define HAVE_LIMITS_H 1 #endif /* Define to 1 if the system has the type `long long'. */ #ifndef HAVE_LONG_LONG #define HAVE_LONG_LONG 1 #endif /* Define to 1 if you have the `memmove' function. */ #ifndef HAVE_MEMMOVE #define HAVE_MEMMOVE 1 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_MEMORY_H #define HAVE_MEMORY_H 1 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_STDINT_H #define HAVE_STDINT_H 1 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_STDLIB_H #define HAVE_STDLIB_H 1 #endif /* Define to 1 if you have the `strerror' function. */ #ifndef HAVE_STRERROR #define HAVE_STRERROR 1 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_STRING #define HAVE_STRING 1 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_STRINGS_H #define HAVE_STRINGS_H 1 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_STRING_H #define HAVE_STRING_H 1 #endif /* Define to 1 if you have the `strtoll' function. */ #ifndef HAVE_STRTOLL #define HAVE_STRTOLL 1 #endif /* Define to 1 if you have the `strtoq' function. */ #ifndef HAVE_STRTOQ #define HAVE_STRTOQ 1 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_SYS_STAT_H #define HAVE_SYS_STAT_H 1 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_SYS_TYPES_H #define HAVE_SYS_TYPES_H 1 #endif /* Define to 1 if you have the header file. */ /* #undef HAVE_TYPE_TRAITS_H */ /* Define to 1 if you have the header file. */ #ifndef HAVE_UNISTD_H #define HAVE_UNISTD_H 1 #endif /* Define to 1 if the system has the type `unsigned long long'. */ #ifndef HAVE_UNSIGNED_LONG_LONG #define HAVE_UNSIGNED_LONG_LONG 1 #endif /* Define to 1 if you have the header file. */ /* #undef HAVE_WINDOWS_H */ /* The value of LINK_SIZE determines the number of bytes used to store links as offsets within the compiled regex. The default is 2, which allows for compiled patterns up to 64K long. This covers the vast majority of cases. However, PCRE can also be compiled to use 3 or 4 bytes instead. This allows for longer patterns in extreme cases. On systems that support it, "configure" can be used to override this default. */ #ifndef LINK_SIZE #define LINK_SIZE 2 #endif /* The value of MATCH_LIMIT determines the default number of times the internal match() function can be called during a single execution of pcre_exec(). There is a runtime interface for setting a different limit. The limit exists in order to catch runaway regular expressions that take for ever to determine that they do not match. The default is set very large so that it does not accidentally catch legitimate cases. On systems that support it, "configure" can be used to override this default default. */ #ifndef MATCH_LIMIT #define MATCH_LIMIT 10000000 #endif /* The above limit applies to all calls of match(), whether or not they increase the recursion depth. In some environments it is desirable to limit the depth of recursive calls of match() more strictly, in order to restrict the maximum amount of stack (or heap, if NO_RECURSE is defined) that is used. The value of MATCH_LIMIT_RECURSION applies only to recursive calls of match(). To have any useful effect, it must be less than the value of MATCH_LIMIT. The default is to use the same value as MATCH_LIMIT. There is a runtime method for setting a different limit. On systems that support it, "configure" can be used to override the default. */ #ifndef MATCH_LIMIT_RECURSION #define MATCH_LIMIT_RECURSION MATCH_LIMIT #endif /* This limit is parameterized just in case anybody ever wants to change it. Care must be taken if it is increased, because it guards against integer overflow caused by enormously large patterns. */ #ifndef MAX_NAME_COUNT #define MAX_NAME_COUNT 10000 #endif /* This limit is parameterized just in case anybody ever wants to change it. Care must be taken if it is increased, because it guards against integer overflow caused by enormously large patterns. */ #ifndef MAX_NAME_SIZE #define MAX_NAME_SIZE 32 #endif /* The value of NEWLINE determines the newline character sequence. On Unix-like systems, "configure" can be used to override the default, which is 10. The possible values are 10 (LF), 13 (CR), 3338 (CRLF), -1 (ANY), or -2 (ANYCRLF). */ #ifndef NEWLINE #define NEWLINE 10 #endif /* PCRE uses recursive function calls to handle backtracking while matching. This can sometimes be a problem on systems that have stacks of limited size. Define NO_RECURSE to get a version that doesn't use recursion in the match() function; instead it creates its own stack by steam using pcre_recurse_malloc() to obtain memory from the heap. For more detail, see the comments and other stuff just above the match() function. On systems that support it, "configure" can be used to set this in the Makefile (use --disable-stack-for-recursion). */ /* #undef NO_RECURSE */ /* Name of package */ #define PACKAGE "pcre" /* Define to the address where bug reports for this package should be sent. */ #define PACKAGE_BUGREPORT "" /* Define to the full name of this package. */ #define PACKAGE_NAME "PCRE" /* Define to the full name and version of this package. */ #define PACKAGE_STRING "PCRE 7.3" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "pcre" /* Define to the version of this package. */ #define PACKAGE_VERSION "7.3" /* If you are compiling for a system other than a Unix-like system or Win32, and it needs some magic to be inserted before the definition of a function that is exported by the library, define this macro to contain the relevant magic. If you do not define this macro, it defaults to "extern" for a C compiler and "extern C" for a C++ compiler on non-Win32 systems. This macro apears at the start of every exported function that is part of the external API. It does not appear on functions that are "external" in the C sense, but which are internal to the library. */ /* #undef PCRE_EXP_DEFN */ /* Define if linking statically (TODO: make nice with Libtool) */ /* #undef PCRE_STATIC */ /* When calling PCRE via the POSIX interface, additional working storage is required for holding the pointers to capturing substrings because PCRE requires three integers per substring, whereas the POSIX interface provides only two. If the number of expected substrings is small, the wrapper function uses space on the stack, because this is faster than using malloc() for each call. The threshold above which the stack is no longer used is defined by POSIX_MALLOC_THRESHOLD. On systems that support it, "configure" can be used to override this default. */ #ifndef POSIX_MALLOC_THRESHOLD #define POSIX_MALLOC_THRESHOLD 10 #endif /* Define to 1 if you have the ANSI C header files. */ #ifndef STDC_HEADERS #define STDC_HEADERS 1 #endif /* Define to enable support for Unicode properties */ /* #undef SUPPORT_UCP */ /* Define to enable support for the UTF-8 Unicode encoding. */ /* #undef SUPPORT_UTF8 */ /* Version number of package */ #ifndef VERSION #define VERSION "7.3" #endif /* Define to empty if `const' does not conform to ANSI C. */ /* #undef const */ /* Define to `unsigned int' if does not define. */ /* #undef size_t */ libsynthesis-3.4.0.47.1/src/pcre/configure.ac000066400000000000000000000430401226375725500206530ustar00rootroot00000000000000dnl Process this file with autoconf to produce a configure script. dnl NOTE FOR MAINTAINERS: Do not use major or minor version numbers with dnl leading zeros, because they may be treated as octal constants. The dnl PCRE_PRERELEASE feature is for identifying release candidates. It might dnl be defined as -RC2, for example. For real releases, it should be defined dnl empty. m4_define(pcre_major, [7]) m4_define(pcre_minor, [3]) m4_define(pcre_prerelease, []) m4_define(pcre_date, [2007-08-28]) # Libtool shared library interface versions (current:revision:age) m4_define(libpcre_version, [0:1:0]) m4_define(libpcreposix_version, [0:0:0]) m4_define(libpcrecpp_version, [0:0:0]) AC_PREREQ(2.57) AC_INIT(PCRE, pcre_major.pcre_minor[]pcre_prerelease, , pcre) AC_CONFIG_SRCDIR([pcre.h.in]) AM_INIT_AUTOMAKE([dist-bzip2 dist-zip]) AC_CONFIG_HEADERS(config.h) # The default CFLAGS and CXXFLAGS in Autoconf are "-g -O2" for gcc and just # "-g" for any other compiler. There doesn't seem to be a standard way of # getting rid of the -g (which I don't think is needed for a production # library). This fudge seems to achieve the necessary. First, we remember the # externally set values of CFLAGS and CXXFLAGS. Then call the AC_PROG_CC and # AC_PROG_CXX macros to find the compilers - if CFLAGS and CXXFLAGS are not # set, they will be set to Autoconf's defaults. Afterwards, if the original # values were not set, remove the -g from the Autoconf defaults. # (PH 02-May-07) remember_set_CFLAGS="$CFLAGS" remember_set_CXXFLAGS="$CXXFLAGS" AC_PROG_CC AC_PROG_CXX if test "x$remember_set_CFLAGS" = "x" then if test "$CFLAGS" = "-g -O2" then CFLAGS="-O2" elif test "$CFLAGS" = "-g" then CFLAGS="" fi fi if test "x$remember_set_CXXFLAGS" = "x" then if test "$CXXFLAGS" = "-g -O2" then CXXFLAGS="-O2" elif test "$CXXFLAGS" = "-g" then CXXFLAGS="" fi fi AC_PROG_INSTALL AC_LIBTOOL_WIN32_DLL AC_PROG_LIBTOOL AC_PROG_LN_S PCRE_MAJOR="pcre_major" PCRE_MINOR="pcre_minor" PCRE_PRERELEASE="pcre_prerelease" PCRE_DATE="pcre_date" AC_SUBST(PCRE_MAJOR) AC_SUBST(PCRE_MINOR) AC_SUBST(PCRE_PRERELEASE) AC_SUBST(PCRE_DATE) # Set a more sensible default value for $(htmldir). if test "x$htmldir" = 'x${docdir}' then htmldir='${docdir}/html' fi # Handle --disable-cpp AC_ARG_ENABLE(cpp, AS_HELP_STRING([--disable-cpp], [disable C++ support]), , enable_cpp=yes) # Handle --enable-rebuild-chartables AC_ARG_ENABLE(rebuild-chartables, AS_HELP_STRING([--enable-rebuild-chartables], [rebuild character tables in current locale]), , enable_rebuild_chartables=no) # Handle --enable-utf8 (disabled by default) AC_ARG_ENABLE(utf8, AS_HELP_STRING([--enable-utf8], [enable UTF-8 support]), , enable_utf8=unset) # Handle --enable-unicode-properties AC_ARG_ENABLE(unicode-properties, AS_HELP_STRING([--enable-unicode-properties], [enable Unicode properties support (implies --enable-utf8)]), , enable_unicode_properties=no) # Handle --enable-newline=NL dnl AC_ARG_ENABLE(newline, dnl AS_HELP_STRING([--enable-newline=NL], dnl [use NL as newline (lf, cr, crlf, anycrlf, any; default=lf)]), dnl , enable_newline=lf) # Separate newline options ac_pcre_newline=lf AC_ARG_ENABLE(newline-is-cr, AS_HELP_STRING([--enable-newline-is-cr], [use CR as newline character]), ac_pcre_newline=cr) AC_ARG_ENABLE(newline-is-lf, AS_HELP_STRING([--enable-newline-is-lf], [use LF as newline character (default)]), ac_pcre_newline=lf) AC_ARG_ENABLE(newline-is-crlf, AS_HELP_STRING([--enable-newline-is-crlf], [use CRLF as newline sequence]), ac_pcre_newline=crlf) AC_ARG_ENABLE(newline-is-anycrlf, AS_HELP_STRING([--enable-newline-is-anycrlf], [use CR, LF, or CRLF as newline sequence]), ac_pcre_newline=anycrlf) AC_ARG_ENABLE(newline-is-any, AS_HELP_STRING([--enable-newline-is-any], [use any valid Unicode newline sequence]), ac_pcre_newline=any) enable_newline="$ac_pcre_newline" # Handle --enable-ebcdic AC_ARG_ENABLE(ebcdic, AS_HELP_STRING([--enable-ebcdic], [assume EBCDIC coding rather than ASCII; use this only in (uncommon) EBCDIC environments; it implies --enable-rebuild-chartables]), , enable_ebcdic=no) # Handle --disable-stack-for-recursion AC_ARG_ENABLE(stack-for-recursion, AS_HELP_STRING([--disable-stack-for-recursion], [don't use stack recursion when matching]), , enable_stack_for_recursion=yes) # Handle --with-posix-malloc-threshold=NBYTES AC_ARG_WITH(posix-malloc-threshold, AS_HELP_STRING([--with-posix-malloc-threshold=NBYTES], [threshold for POSIX malloc usage (default=10)]), , with_posix_malloc_threshold=10) # Handle --with-link-size=N AC_ARG_WITH(link-size, AS_HELP_STRING([--with-link-size=N], [internal link size (2, 3, or 4 allowed; default=2)]), , with_link_size=2) # Handle --with-match-limit=N AC_ARG_WITH(match-limit, AS_HELP_STRING([--with-match-limit=N], [default limit on internal looping (default=10000000)]), , with_match_limit=10000000) # Handle --with-match-limit_recursion=N # # Note: In config.h, the default is to define MATCH_LIMIT_RECURSION # symbolically as MATCH_LIMIT, which in turn is defined to be some numeric # value (e.g. 10000000). MATCH_LIMIT_RECURSION can otherwise be set to some # different numeric value (or even the same numeric value as MATCH_LIMIT, # though no longer defined in terms of the latter). # AC_ARG_WITH(match-limit-recursion, AS_HELP_STRING([--with-match-limit-recursion=N], [default limit on internal recursion (default=MATCH_LIMIT)]), , with_match_limit_recursion=MATCH_LIMIT) # Make sure that if enable_unicode_properties was set, that UTF-8 support # is enabled. # if test "x$enable_unicode_properties" = "xyes" then if test "x$enable_utf8" = "xno" then AC_MSG_ERROR([support for Unicode properties requires UTF-8 support]) fi enable_utf8=yes fi if test "x$enable_utf8" = "xunset" then enable_utf8=no fi # Make sure that if enable_ebcdic is set, rebuild_chartables is also enabled. # if test "x$enable_ebcdic" = "xyes" then enable_rebuild_chartables=yes fi # Convert the newline identifier into the appropriate integer value. case "$enable_newline" in lf) ac_pcre_newline_value=10 ;; cr) ac_pcre_newline_value=13 ;; crlf) ac_pcre_newline_value=3338 ;; anycrlf) ac_pcre_newline_value=-2 ;; any) ac_pcre_newline_value=-1 ;; *) AC_MSG_ERROR([invalid argument \"$enable_newline\" to --enable-newline option]) ;; esac # Check argument to --with-link-size case "$with_link_size" in 2|3|4) ;; *) AC_MSG_ERROR([invalid argument \"$with_link_size\" to --with-link-size option]) ;; esac AH_TOP([ /* On Unix-like systems config.h.in is converted by "configure" into config.h. Some other environments also support the use of "configure". PCRE is written in Standard C, but there are a few non-standard things it can cope with, allowing it to run on SunOS4 and other "close to standard" systems. If you are going to build PCRE "by hand" on a system without "configure" you should copy the distributed config.h.generic to config.h, and then set up the macros the way you need them. Alternatively, you can avoid editing by using -D on the compiler command line to set the macro values. PCRE uses memmove() if HAVE_MEMMOVE is set to 1; otherwise it uses bcopy() if HAVE_BCOPY is set to 1. If your system has neither bcopy() nor memmove(), set them both to 0; an emulation function will be used. */]) # Checks for header files. AC_HEADER_STDC AC_CHECK_HEADERS(limits.h sys/types.h sys/stat.h dirent.h windows.h) # The files below are C++ header files. pcre_have_type_traits="0" pcre_have_bits_type_traits="0" if test "x$enable_cpp" = "xyes" -a -n "$CXX" then AC_LANG_PUSH(C++) # We could be more clever here, given we're doing AC_SUBST with this # (eg set a var to be the name of the include file we want). But we're not # so it's easy to change back to 'regular' autoconf vars if we needed to. AC_CHECK_HEADERS(string, [pcre_have_cpp_headers="1"], [pcre_have_cpp_headers="0"]) AC_CHECK_HEADERS(bits/type_traits.h, [pcre_have_bits_type_traits="1"], [pcre_have_bits_type_traits="0"]) AC_CHECK_HEADERS(type_traits.h, [pcre_have_type_traits="1"], [pcre_have_type_traits="0"]) AC_LANG_POP fi # Using AC_SUBST eliminates the need to include config.h in a public .h file AC_SUBST(pcre_have_type_traits) AC_SUBST(pcre_have_bits_type_traits) # Conditional compilation AM_CONDITIONAL(WITH_PCRE_CPP, test "x$enable_cpp" = "xyes") AM_CONDITIONAL(WITH_REBUILD_CHARTABLES, test "x$enable_rebuild_chartables" = "xyes") # Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_TYPE_SIZE_T AC_CHECK_TYPES([long long], [pcre_have_long_long="1"], [pcre_have_long_long="0"]) AC_CHECK_TYPES([unsigned long long], [pcre_have_ulong_long="1"], [pcre_have_ulong_long="0"]) AC_SUBST(pcre_have_long_long) AC_SUBST(pcre_have_ulong_long) # Checks for library functions. AC_CHECK_FUNCS(bcopy memmove strerror strtoq strtoll) # This facilitates -ansi builds under Linux dnl AC_DEFINE([_GNU_SOURCE], [], [Enable GNU extensions in glibc]) if test "x$enable_shared" = "xno" ; then AC_DEFINE([PCRE_STATIC], [1], [ Define if linking statically (TODO: make nice with Libtool)]) fi # Here is where pcre specific defines are handled if test "$enable_utf8" = "yes"; then AC_DEFINE([SUPPORT_UTF8], [], [ Define to enable support for the UTF-8 Unicode encoding.]) fi if test "$enable_unicode_properties" = "yes"; then AC_DEFINE([SUPPORT_UCP], [], [ Define to enable support for Unicode properties]) fi if test "$enable_stack_for_recursion" = "no"; then AC_DEFINE([NO_RECURSE], [], [ PCRE uses recursive function calls to handle backtracking while matching. This can sometimes be a problem on systems that have stacks of limited size. Define NO_RECURSE to get a version that doesn't use recursion in the match() function; instead it creates its own stack by steam using pcre_recurse_malloc() to obtain memory from the heap. For more detail, see the comments and other stuff just above the match() function. On systems that support it, "configure" can be used to set this in the Makefile (use --disable-stack-for-recursion).]) fi AC_DEFINE_UNQUOTED([NEWLINE], [$ac_pcre_newline_value], [ The value of NEWLINE determines the newline character sequence. On Unix-like systems, "configure" can be used to override the default, which is 10. The possible values are 10 (LF), 13 (CR), 3338 (CRLF), -1 (ANY), or -2 (ANYCRLF).]) AC_DEFINE_UNQUOTED([LINK_SIZE], [$with_link_size], [ The value of LINK_SIZE determines the number of bytes used to store links as offsets within the compiled regex. The default is 2, which allows for compiled patterns up to 64K long. This covers the vast majority of cases. However, PCRE can also be compiled to use 3 or 4 bytes instead. This allows for longer patterns in extreme cases. On systems that support it, "configure" can be used to override this default.]) AC_DEFINE_UNQUOTED([POSIX_MALLOC_THRESHOLD], [$with_posix_malloc_threshold], [ When calling PCRE via the POSIX interface, additional working storage is required for holding the pointers to capturing substrings because PCRE requires three integers per substring, whereas the POSIX interface provides only two. If the number of expected substrings is small, the wrapper function uses space on the stack, because this is faster than using malloc() for each call. The threshold above which the stack is no longer used is defined by POSIX_MALLOC_THRESHOLD. On systems that support it, "configure" can be used to override this default.]) AC_DEFINE_UNQUOTED([MATCH_LIMIT], [$with_match_limit], [ The value of MATCH_LIMIT determines the default number of times the internal match() function can be called during a single execution of pcre_exec(). There is a runtime interface for setting a different limit. The limit exists in order to catch runaway regular expressions that take for ever to determine that they do not match. The default is set very large so that it does not accidentally catch legitimate cases. On systems that support it, "configure" can be used to override this default default.]) AC_DEFINE_UNQUOTED([MATCH_LIMIT_RECURSION], [$with_match_limit_recursion], [ The above limit applies to all calls of match(), whether or not they increase the recursion depth. In some environments it is desirable to limit the depth of recursive calls of match() more strictly, in order to restrict the maximum amount of stack (or heap, if NO_RECURSE is defined) that is used. The value of MATCH_LIMIT_RECURSION applies only to recursive calls of match(). To have any useful effect, it must be less than the value of MATCH_LIMIT. The default is to use the same value as MATCH_LIMIT. There is a runtime method for setting a different limit. On systems that support it, "configure" can be used to override the default.]) AC_DEFINE([MAX_NAME_SIZE], [32], [ This limit is parameterized just in case anybody ever wants to change it. Care must be taken if it is increased, because it guards against integer overflow caused by enormously large patterns.]) AC_DEFINE([MAX_NAME_COUNT], [10000], [ This limit is parameterized just in case anybody ever wants to change it. Care must be taken if it is increased, because it guards against integer overflow caused by enormously large patterns.]) AH_VERBATIM([PCRE_EXP_DEFN], [ /* If you are compiling for a system other than a Unix-like system or Win32, and it needs some magic to be inserted before the definition of a function that is exported by the library, define this macro to contain the relevant magic. If you do not define this macro, it defaults to "extern" for a C compiler and "extern C" for a C++ compiler on non-Win32 systems. This macro apears at the start of every exported function that is part of the external API. It does not appear on functions that are "external" in the C sense, but which are internal to the library. */ #undef PCRE_EXP_DEFN]) if test "$enable_ebcdic" = "yes"; then AC_DEFINE_UNQUOTED([EBCDIC], [], [ If you are compiling for a system that uses EBCDIC instead of ASCII character codes, define this macro as 1. On systems that can use "configure", this can be done via --enable-ebcdic.]) fi # Platform specific issues NO_UNDEFINED= EXPORT_ALL_SYMBOLS= case $host_os in cygwin* | mingw* ) if test X"$enable_shared" = Xyes; then NO_UNDEFINED="-no-undefined" EXPORT_ALL_SYMBOLS="-Wl,--export-all-symbols" fi ;; esac # The extra LDFLAGS for each particular library # (Note: The libpcre*_version bits are m4 variables, assigned above) EXTRA_LIBPCRE_LDFLAGS="$NO_UNDEFINED -version-info libpcre_version" EXTRA_LIBPCREPOSIX_LDFLAGS="$NO_UNDEFINED -version-info libpcreposix_version" EXTRA_LIBPCRECPP_LDFLAGS="$NO_UNDEFINED $EXPORT_ALL_SYMBOLS -version-info libpcrecpp_version" AC_SUBST(EXTRA_LIBPCRE_LDFLAGS) AC_SUBST(EXTRA_LIBPCREPOSIX_LDFLAGS) AC_SUBST(EXTRA_LIBPCRECPP_LDFLAGS) # When we run 'make distcheck', use these arguments. DISTCHECK_CONFIGURE_FLAGS="--enable-cpp --enable-unicode-properties" AC_SUBST(DISTCHECK_CONFIGURE_FLAGS) # Produce these files, in addition to config.h. AC_CONFIG_FILES( Makefile libpcre.pc libpcrecpp.pc pcre-config pcre.h pcre_stringpiece.h pcrecpparg.h ) # Make the generated script files executable. AC_CONFIG_COMMANDS([script-chmod], [chmod a+x pcre-config]) # Make sure that pcre_chartables.c is removed in case the method for # creating it was changed by reconfiguration. AC_CONFIG_COMMANDS([delete-old-chartables], [rm -f pcre_chartables.c]) AC_OUTPUT # Print out a nice little message after configure is run displaying your # chosen options. # cat < #endif #include #include #include #include #include "pcre_internal.h" #define DFTABLES /* pcre_maketables.c notices this */ #include "pcre_maketables.c" int main(int argc, char **argv) { FILE *f; int i = 1; const unsigned char *tables; const unsigned char *base_of_tables; /* By default, the default C locale is used rather than what the building user happens to have set. However, if the -L option is given, set the locale from the LC_xxx environment variables. */ if (argc > 1 && strcmp(argv[1], "-L") == 0) { setlocale(LC_ALL, ""); /* Set from environment variables */ i++; } if (argc < i + 1) { fprintf(stderr, "dftables: one filename argument is required\n"); return 1; } tables = pcre_maketables(); base_of_tables = tables; f = fopen(argv[i], "wb"); if (f == NULL) { fprintf(stderr, "dftables: failed to open %s for writing\n", argv[1]); return 1; } /* There are several fprintf() calls here, because gcc in pedantic mode complains about the very long string otherwise. */ fprintf(f, "/*************************************************\n" "* Perl-Compatible Regular Expressions *\n" "*************************************************/\n\n" "/* This file was automatically written by the dftables auxiliary\n" "program. It contains character tables that are used when no external\n" "tables are passed to PCRE by the application that calls it. The tables\n" "are used only for characters whose code values are less than 256.\n\n"); fprintf(f, "The following #includes are present because without them gcc 4.x may remove\n" "the array definition from the final binary if PCRE is built into a static\n" "library and dead code stripping is activated. This leads to link errors.\n" "Pulling in the header ensures that the array gets flagged as \"someone\n" "outside this compilation unit might reference this\" and so it will always\n" "be supplied to the linker. */\n\n" "#ifdef HAVE_CONFIG_H\n" "#include \n" "#endif\n\n" "#include \"pcre_internal.h\"\n\n"); fprintf(f, "const unsigned char _pcre_default_tables[] = {\n\n" "/* This table is a lower casing table. */\n\n"); fprintf(f, " "); for (i = 0; i < 256; i++) { if ((i & 7) == 0 && i != 0) fprintf(f, "\n "); fprintf(f, "%3d", *tables++); if (i != 255) fprintf(f, ","); } fprintf(f, ",\n\n"); fprintf(f, "/* This table is a case flipping table. */\n\n"); fprintf(f, " "); for (i = 0; i < 256; i++) { if ((i & 7) == 0 && i != 0) fprintf(f, "\n "); fprintf(f, "%3d", *tables++); if (i != 255) fprintf(f, ","); } fprintf(f, ",\n\n"); fprintf(f, "/* This table contains bit maps for various character classes.\n" "Each map is 32 bytes long and the bits run from the least\n" "significant end of each byte. The classes that have their own\n" "maps are: space, xdigit, digit, upper, lower, word, graph\n" "print, punct, and cntrl. Other classes are built from combinations. */\n\n"); fprintf(f, " "); for (i = 0; i < cbit_length; i++) { if ((i & 7) == 0 && i != 0) { if ((i & 31) == 0) fprintf(f, "\n"); fprintf(f, "\n "); } fprintf(f, "0x%02x", *tables++); if (i != cbit_length - 1) fprintf(f, ","); } fprintf(f, ",\n\n"); fprintf(f, "/* This table identifies various classes of character by individual bits:\n" " 0x%02x white space character\n" " 0x%02x letter\n" " 0x%02x decimal digit\n" " 0x%02x hexadecimal digit\n" " 0x%02x alphanumeric or '_'\n" " 0x%02x regular expression metacharacter or binary zero\n*/\n\n", ctype_space, ctype_letter, ctype_digit, ctype_xdigit, ctype_word, ctype_meta); fprintf(f, " "); for (i = 0; i < 256; i++) { if ((i & 7) == 0 && i != 0) { fprintf(f, " /* "); if (isprint(i-8)) fprintf(f, " %c -", i-8); else fprintf(f, "%3d-", i-8); if (isprint(i-1)) fprintf(f, " %c ", i-1); else fprintf(f, "%3d", i-1); fprintf(f, " */\n "); } fprintf(f, "0x%02x", *tables++); if (i != 255) fprintf(f, ","); } fprintf(f, "};/* "); if (isprint(i-8)) fprintf(f, " %c -", i-8); else fprintf(f, "%3d-", i-8); if (isprint(i-1)) fprintf(f, " %c ", i-1); else fprintf(f, "%3d", i-1); fprintf(f, " */\n\n/* End of pcre_chartables.c */\n"); fclose(f); free((void *)base_of_tables); return 0; } /* End of dftables.c */ libsynthesis-3.4.0.47.1/src/pcre/libpcre.pc.in000066400000000000000000000004251226375725500207360ustar00rootroot00000000000000# Package Information for pkg-config prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: libpcre Description: PCRE - Perl compatible regular expressions C library Version: @PACKAGE_VERSION@ Libs: -L${libdir} -lpcre Cflags: -I${includedir} libsynthesis-3.4.0.47.1/src/pcre/libpcrecpp.pc.in000066400000000000000000000004141226375725500214370ustar00rootroot00000000000000# Package Information for pkg-config prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: libpcrecpp Description: PCRECPP - C++ wrapper for PCRE Version: @PACKAGE_VERSION@ Libs: -L${libdir} -lpcre -lpcrecpp Cflags: -I${includedir} libsynthesis-3.4.0.47.1/src/pcre/makevp.bat000066400000000000000000000036021226375725500203400ustar00rootroot00000000000000@echo off :: AH 20-12-06 modified for new PCRE-7.0 and VP/BCC :: PH 19-03-07 renamed !compile.txt and !linklib.txt as makevp-compile.txt and :: makevp-linklib.txt :: PH 26-03-07 re-renamed !compile.txt and !linklib.txt as makevp-c.txt and :: makevp-l.txt :: PH 29-03-07 hopefully the final rename to makevp_c and makevp_l REM This file was contributed by Alexander Tokarev for building PCRE for use REM with Virtual Pascal. It has not been tested with the latest PCRE release. REM CHANGE THIS FOR YOUR BORLAND C++ COMPILER PATH SET BORLAND=F:\bcc SET PATH=%PATH%;%BORLAND%\bin;f:\tasm\bin SET PCRE_VER=70 :: sh configure bcc32 -DDFTABLES -DSTATIC -I%BORLAND%\include -L%BORLAND%\lib dftables.c :: bcc32 -DDFTABLES -DSTATIC -DVPCOMPAT -I%BORLAND%\include -L%BORLAND%\lib dftables.c IF ERRORLEVEL 1 EXIT :: dftables > chartables.c dftables pcre_chartables.c REM compile and link the PCRE library into lib: option -B for ASM compile works too bcc32 -a4 -c -RT- -y- -v- -u- -R- -Q- -X -d -fp -ff -P- -O2 -Oc -Ov -3 -w-8004 -w-8064 -w-8065 -w-8012 -DSTATIC -DVPCOMPAT -UDFTABLES -I%BORLAND%\include @makevp_c.txt :: bcc32 -c -RT- -y- -v- -u- -P- -O2 -5 -DSTATIC -DVPCOMPAT -UDFTABLES -I%BORLAND%\include get.c maketables.c pcre.c study.c IF ERRORLEVEL 1 EXIT tlib %BORLAND%\lib\cw32.lib *calloc *del *strncmp *memcpy *memmove *memset *memcmp *strlen :: tlib %BORLAND%\lib\cw32.lib *calloc *del *strncmp *memcpy *memmove *memset IF ERRORLEVEL 1 EXIT tlib pcre%PCRE_VER%.lib @makevp_l.txt +calloc.obj +del.obj +strncmp.obj +memcpy.obj +memmove.obj +memset.obj +memcmp.obj +strlen.obj :: tlib pcre.lib +get.obj +maketables.obj +pcre.obj +study.obj +calloc.obj +del.obj +strncmp.obj +memcpy.obj +memmove.obj +memset.obj IF ERRORLEVEL 1 EXIT del *.obj *.tds *.bak >nul 2>nul echo --- echo Now the library should be complete. Please check all messages above. echo Don't care for warnings, it's OK. libsynthesis-3.4.0.47.1/src/pcre/makevp_c.txt000066400000000000000000000004661226375725500207200ustar00rootroot00000000000000pcre_chartables.c pcre_compile.c pcre_config.c pcre_dfa_exec.c pcre_exec.c pcre_fullinfo.c pcre_get.c pcre_globals.c pcre_info.c pcre_maketables.c pcre_newline.c pcre_ord2utf8.c pcre_refcount.c pcre_study.c pcre_tables.c pcre_try_flipped.c pcre_ucp_searchfuncs.c pcre_valid_utf8.c pcre_version.c pcre_xclass.c libsynthesis-3.4.0.47.1/src/pcre/makevp_l.txt000066400000000000000000000010411226375725500207170ustar00rootroot00000000000000+pcre_chartables.obj & +pcre_compile.obj & +pcre_config.obj & +pcre_dfa_exec.obj & +pcre_exec.obj & +pcre_fullinfo.obj & +pcre_get.obj & +pcre_globals.obj & +pcre_info.obj & +pcre_maketables.obj & +pcre_newline.obj & +pcre_ord2utf8.obj & +pcre_refcount.obj & +pcre_study.obj & +pcre_tables.obj & +pcre_try_flipped.obj & +pcre_ucp_searchfuncs.obj & +pcre_valid_utf8.obj & +pcre_version.obj & +pcre_xclass.obj libsynthesis-3.4.0.47.1/src/pcre/pcre-config.in000066400000000000000000000022751226375725500211160ustar00rootroot00000000000000#!/bin/sh prefix=@prefix@ exec_prefix=@exec_prefix@ exec_prefix_set=no usage="\ Usage: pcre-config [--prefix] [--exec-prefix] [--version] [--libs] [--libs-posix] [--cflags] [--cflags-posix]" if test $# -eq 0; then echo "${usage}" 1>&2 exit 1 fi libR= case `uname -s` in *SunOS*) libR=" -R@libdir@" ;; *BSD*) libR=" -Wl,-R@libdir@" ;; esac while test $# -gt 0; do case "$1" in -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;; *) optarg= ;; esac case $1 in --prefix=*) prefix=$optarg if test $exec_prefix_set = no ; then exec_prefix=$optarg fi ;; --prefix) echo $prefix ;; --exec-prefix=*) exec_prefix=$optarg exec_prefix_set=yes ;; --exec-prefix) echo $exec_prefix ;; --version) echo @PACKAGE_VERSION@ ;; --cflags | --cflags-posix) if test @includedir@ != /usr/include ; then includes=-I@includedir@ fi echo $includes ;; --libs-posix) echo -L@libdir@$libR -lpcreposix -lpcre ;; --libs) echo -L@libdir@$libR -lpcre ;; *) echo "${usage}" 1>&2 exit 1 ;; esac shift done libsynthesis-3.4.0.47.1/src/pcre/pcre.h000066400000000000000000000277631226375725500175050ustar00rootroot00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* This is the public header file for the PCRE library, to be #included by applications that call the PCRE functions. Copyright (c) 1997-2007 University of Cambridge ----------------------------------------------------------------------------- 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 name of the University of Cambridge 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. ----------------------------------------------------------------------------- */ #ifndef _PCRE_H #define _PCRE_H /* The current PCRE version information. */ #define PCRE_MAJOR 7 #define PCRE_MINOR 3 #define PCRE_PRERELEASE #define PCRE_DATE 2007-08-28 /* When an application links to a PCRE DLL in Windows, the symbols that are imported have to be identified as such. When building PCRE, the appropriate export setting is defined in pcre_internal.h, which includes this file. So we don't change existing definitions of PCRE_EXP_DECL and PCRECPP_EXP_DECL. */ #if defined(_WIN32) && !defined(PCRE_STATIC) # ifndef PCRE_EXP_DECL # define PCRE_EXP_DECL extern __declspec(dllimport) # endif # ifdef __cplusplus # ifndef PCRECPP_EXP_DECL # define PCRECPP_EXP_DECL extern __declspec(dllimport) # endif # ifndef PCRECPP_EXP_DEFN # define PCRECPP_EXP_DEFN __declspec(dllimport) # endif # endif #endif /* By default, we use the standard "extern" declarations. */ #ifndef PCRE_EXP_DECL # ifdef __cplusplus # define PCRE_EXP_DECL extern "C" # else # define PCRE_EXP_DECL extern # endif #endif #ifdef __cplusplus # ifndef PCRECPP_EXP_DECL # define PCRECPP_EXP_DECL extern # endif # ifndef PCRECPP_EXP_DEFN # define PCRECPP_EXP_DEFN # endif #endif /* Have to include stdlib.h in order to ensure that size_t is defined; it is needed here for malloc. */ #include /* Allow for C++ users */ #ifdef __cplusplus extern "C" { #endif /* Options */ #define PCRE_CASELESS 0x00000001 #define PCRE_MULTILINE 0x00000002 #define PCRE_DOTALL 0x00000004 #define PCRE_EXTENDED 0x00000008 #define PCRE_ANCHORED 0x00000010 #define PCRE_DOLLAR_ENDONLY 0x00000020 #define PCRE_EXTRA 0x00000040 #define PCRE_NOTBOL 0x00000080 #define PCRE_NOTEOL 0x00000100 #define PCRE_UNGREEDY 0x00000200 #define PCRE_NOTEMPTY 0x00000400 #define PCRE_UTF8 0x00000800 #define PCRE_NO_AUTO_CAPTURE 0x00001000 #define PCRE_NO_UTF8_CHECK 0x00002000 #define PCRE_AUTO_CALLOUT 0x00004000 #define PCRE_PARTIAL 0x00008000 #define PCRE_DFA_SHORTEST 0x00010000 #define PCRE_DFA_RESTART 0x00020000 #define PCRE_FIRSTLINE 0x00040000 #define PCRE_DUPNAMES 0x00080000 #define PCRE_NEWLINE_CR 0x00100000 #define PCRE_NEWLINE_LF 0x00200000 #define PCRE_NEWLINE_CRLF 0x00300000 #define PCRE_NEWLINE_ANY 0x00400000 #define PCRE_NEWLINE_ANYCRLF 0x00500000 /* Exec-time and get/set-time error codes */ #define PCRE_ERROR_NOMATCH (-1) #define PCRE_ERROR_NULL (-2) #define PCRE_ERROR_BADOPTION (-3) #define PCRE_ERROR_BADMAGIC (-4) #define PCRE_ERROR_UNKNOWN_OPCODE (-5) #define PCRE_ERROR_UNKNOWN_NODE (-5) /* For backward compatibility */ #define PCRE_ERROR_NOMEMORY (-6) #define PCRE_ERROR_NOSUBSTRING (-7) #define PCRE_ERROR_MATCHLIMIT (-8) #define PCRE_ERROR_CALLOUT (-9) /* Never used by PCRE itself */ #define PCRE_ERROR_BADUTF8 (-10) #define PCRE_ERROR_BADUTF8_OFFSET (-11) #define PCRE_ERROR_PARTIAL (-12) #define PCRE_ERROR_BADPARTIAL (-13) #define PCRE_ERROR_INTERNAL (-14) #define PCRE_ERROR_BADCOUNT (-15) #define PCRE_ERROR_DFA_UITEM (-16) #define PCRE_ERROR_DFA_UCOND (-17) #define PCRE_ERROR_DFA_UMLIMIT (-18) #define PCRE_ERROR_DFA_WSSIZE (-19) #define PCRE_ERROR_DFA_RECURSE (-20) #define PCRE_ERROR_RECURSIONLIMIT (-21) #define PCRE_ERROR_NOTUSED (-22) #define PCRE_ERROR_BADNEWLINE (-23) /* Request types for pcre_fullinfo() */ #define PCRE_INFO_OPTIONS 0 #define PCRE_INFO_SIZE 1 #define PCRE_INFO_CAPTURECOUNT 2 #define PCRE_INFO_BACKREFMAX 3 #define PCRE_INFO_FIRSTBYTE 4 #define PCRE_INFO_FIRSTCHAR 4 /* For backwards compatibility */ #define PCRE_INFO_FIRSTTABLE 5 #define PCRE_INFO_LASTLITERAL 6 #define PCRE_INFO_NAMEENTRYSIZE 7 #define PCRE_INFO_NAMECOUNT 8 #define PCRE_INFO_NAMETABLE 9 #define PCRE_INFO_STUDYSIZE 10 #define PCRE_INFO_DEFAULT_TABLES 11 #define PCRE_INFO_OKPARTIAL 12 #define PCRE_INFO_JCHANGED 13 #define PCRE_INFO_HASCRORLF 14 /* Request types for pcre_config(). Do not re-arrange, in order to remain compatible. */ #define PCRE_CONFIG_UTF8 0 #define PCRE_CONFIG_NEWLINE 1 #define PCRE_CONFIG_LINK_SIZE 2 #define PCRE_CONFIG_POSIX_MALLOC_THRESHOLD 3 #define PCRE_CONFIG_MATCH_LIMIT 4 #define PCRE_CONFIG_STACKRECURSE 5 #define PCRE_CONFIG_UNICODE_PROPERTIES 6 #define PCRE_CONFIG_MATCH_LIMIT_RECURSION 7 /* Bit flags for the pcre_extra structure. Do not re-arrange or redefine these bits, just add new ones on the end, in order to remain compatible. */ #define PCRE_EXTRA_STUDY_DATA 0x0001 #define PCRE_EXTRA_MATCH_LIMIT 0x0002 #define PCRE_EXTRA_CALLOUT_DATA 0x0004 #define PCRE_EXTRA_TABLES 0x0008 #define PCRE_EXTRA_MATCH_LIMIT_RECURSION 0x0010 /* Types */ struct real_pcre; /* declaration; the definition is private */ typedef struct real_pcre pcre; /* When PCRE is compiled as a C++ library, the subject pointer type can be replaced with a custom type. For conventional use, the public interface is a const char *. */ #ifndef PCRE_SPTR #define PCRE_SPTR const char * #endif /* The structure for passing additional data to pcre_exec(). This is defined in such as way as to be extensible. Always add new fields at the end, in order to remain compatible. */ typedef struct pcre_extra { unsigned long int flags; /* Bits for which fields are set */ void *study_data; /* Opaque data from pcre_study() */ unsigned long int match_limit; /* Maximum number of calls to match() */ void *callout_data; /* Data passed back in callouts */ const unsigned char *tables; /* Pointer to character tables */ unsigned long int match_limit_recursion; /* Max recursive calls to match() */ } pcre_extra; /* The structure for passing out data via the pcre_callout_function. We use a structure so that new fields can be added on the end in future versions, without changing the API of the function, thereby allowing old clients to work without modification. */ typedef struct pcre_callout_block { int version; /* Identifies version of block */ /* ------------------------ Version 0 ------------------------------- */ int callout_number; /* Number compiled into pattern */ int *offset_vector; /* The offset vector */ PCRE_SPTR subject; /* The subject being matched */ int subject_length; /* The length of the subject */ int start_match; /* Offset to start of this match attempt */ int current_position; /* Where we currently are in the subject */ int capture_top; /* Max current capture */ int capture_last; /* Most recently closed capture */ void *callout_data; /* Data passed in with the call */ /* ------------------- Added for Version 1 -------------------------- */ int pattern_position; /* Offset to next item in the pattern */ int next_item_length; /* Length of next item in the pattern */ /* ------------------------------------------------------------------ */ } pcre_callout_block; /* Indirection for store get and free functions. These can be set to alternative malloc/free functions if required. Special ones are used in the non-recursive case for "frames". There is also an optional callout function that is triggered by the (?) regex item. For Virtual Pascal, these definitions have to take another form. */ #ifndef VPCOMPAT PCRE_EXP_DECL void *(*pcre_malloc)(size_t); PCRE_EXP_DECL void (*pcre_free)(void *); PCRE_EXP_DECL void *(*pcre_stack_malloc)(size_t); PCRE_EXP_DECL void (*pcre_stack_free)(void *); PCRE_EXP_DECL int (*pcre_callout)(pcre_callout_block *); #else /* VPCOMPAT */ PCRE_EXP_DECL void *pcre_malloc(size_t); PCRE_EXP_DECL void pcre_free(void *); PCRE_EXP_DECL void *pcre_stack_malloc(size_t); PCRE_EXP_DECL void pcre_stack_free(void *); PCRE_EXP_DECL int pcre_callout(pcre_callout_block *); #endif /* VPCOMPAT */ /* Exported PCRE functions */ PCRE_EXP_DECL pcre *pcre_compile(const char *, int, const char **, int *, const unsigned char *); PCRE_EXP_DECL pcre *pcre_compile2(const char *, int, int *, const char **, int *, const unsigned char *); PCRE_EXP_DECL int pcre_config(int, void *); PCRE_EXP_DECL int pcre_copy_named_substring(const pcre *, const char *, int *, int, const char *, char *, int); PCRE_EXP_DECL int pcre_copy_substring(const char *, int *, int, int, char *, int); PCRE_EXP_DECL int pcre_dfa_exec(const pcre *, const pcre_extra *, const char *, int, int, int, int *, int , int *, int); PCRE_EXP_DECL int pcre_exec(const pcre *, const pcre_extra *, PCRE_SPTR, int, int, int, int *, int); PCRE_EXP_DECL void pcre_free_substring(const char *); PCRE_EXP_DECL void pcre_free_substring_list(const char **); PCRE_EXP_DECL int pcre_fullinfo(const pcre *, const pcre_extra *, int, void *); PCRE_EXP_DECL int pcre_get_named_substring(const pcre *, const char *, int *, int, const char *, const char **); PCRE_EXP_DECL int pcre_get_stringnumber(const pcre *, const char *); PCRE_EXP_DECL int pcre_get_stringtable_entries(const pcre *, const char *, char **, char **); PCRE_EXP_DECL int pcre_get_substring(const char *, int *, int, int, const char **); PCRE_EXP_DECL int pcre_get_substring_list(const char *, int *, int, const char ***); PCRE_EXP_DECL int pcre_info(const pcre *, int *, int *); PCRE_EXP_DECL const unsigned char *pcre_maketables(void); PCRE_EXP_DECL int pcre_refcount(pcre *, int); PCRE_EXP_DECL pcre_extra *pcre_study(const pcre *, int, const char **); PCRE_EXP_DECL const char *pcre_version(void); #ifdef __cplusplus } /* extern "C" */ #endif #endif /* End of pcre.h */ libsynthesis-3.4.0.47.1/src/pcre/pcre.h.generic000066400000000000000000000277631226375725500211200ustar00rootroot00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* This is the public header file for the PCRE library, to be #included by applications that call the PCRE functions. Copyright (c) 1997-2007 University of Cambridge ----------------------------------------------------------------------------- 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 name of the University of Cambridge 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. ----------------------------------------------------------------------------- */ #ifndef _PCRE_H #define _PCRE_H /* The current PCRE version information. */ #define PCRE_MAJOR 7 #define PCRE_MINOR 3 #define PCRE_PRERELEASE #define PCRE_DATE 2007-08-28 /* When an application links to a PCRE DLL in Windows, the symbols that are imported have to be identified as such. When building PCRE, the appropriate export setting is defined in pcre_internal.h, which includes this file. So we don't change existing definitions of PCRE_EXP_DECL and PCRECPP_EXP_DECL. */ #if defined(_WIN32) && !defined(PCRE_STATIC) # ifndef PCRE_EXP_DECL # define PCRE_EXP_DECL extern __declspec(dllimport) # endif # ifdef __cplusplus # ifndef PCRECPP_EXP_DECL # define PCRECPP_EXP_DECL extern __declspec(dllimport) # endif # ifndef PCRECPP_EXP_DEFN # define PCRECPP_EXP_DEFN __declspec(dllimport) # endif # endif #endif /* By default, we use the standard "extern" declarations. */ #ifndef PCRE_EXP_DECL # ifdef __cplusplus # define PCRE_EXP_DECL extern "C" # else # define PCRE_EXP_DECL extern # endif #endif #ifdef __cplusplus # ifndef PCRECPP_EXP_DECL # define PCRECPP_EXP_DECL extern # endif # ifndef PCRECPP_EXP_DEFN # define PCRECPP_EXP_DEFN # endif #endif /* Have to include stdlib.h in order to ensure that size_t is defined; it is needed here for malloc. */ #include /* Allow for C++ users */ #ifdef __cplusplus extern "C" { #endif /* Options */ #define PCRE_CASELESS 0x00000001 #define PCRE_MULTILINE 0x00000002 #define PCRE_DOTALL 0x00000004 #define PCRE_EXTENDED 0x00000008 #define PCRE_ANCHORED 0x00000010 #define PCRE_DOLLAR_ENDONLY 0x00000020 #define PCRE_EXTRA 0x00000040 #define PCRE_NOTBOL 0x00000080 #define PCRE_NOTEOL 0x00000100 #define PCRE_UNGREEDY 0x00000200 #define PCRE_NOTEMPTY 0x00000400 #define PCRE_UTF8 0x00000800 #define PCRE_NO_AUTO_CAPTURE 0x00001000 #define PCRE_NO_UTF8_CHECK 0x00002000 #define PCRE_AUTO_CALLOUT 0x00004000 #define PCRE_PARTIAL 0x00008000 #define PCRE_DFA_SHORTEST 0x00010000 #define PCRE_DFA_RESTART 0x00020000 #define PCRE_FIRSTLINE 0x00040000 #define PCRE_DUPNAMES 0x00080000 #define PCRE_NEWLINE_CR 0x00100000 #define PCRE_NEWLINE_LF 0x00200000 #define PCRE_NEWLINE_CRLF 0x00300000 #define PCRE_NEWLINE_ANY 0x00400000 #define PCRE_NEWLINE_ANYCRLF 0x00500000 /* Exec-time and get/set-time error codes */ #define PCRE_ERROR_NOMATCH (-1) #define PCRE_ERROR_NULL (-2) #define PCRE_ERROR_BADOPTION (-3) #define PCRE_ERROR_BADMAGIC (-4) #define PCRE_ERROR_UNKNOWN_OPCODE (-5) #define PCRE_ERROR_UNKNOWN_NODE (-5) /* For backward compatibility */ #define PCRE_ERROR_NOMEMORY (-6) #define PCRE_ERROR_NOSUBSTRING (-7) #define PCRE_ERROR_MATCHLIMIT (-8) #define PCRE_ERROR_CALLOUT (-9) /* Never used by PCRE itself */ #define PCRE_ERROR_BADUTF8 (-10) #define PCRE_ERROR_BADUTF8_OFFSET (-11) #define PCRE_ERROR_PARTIAL (-12) #define PCRE_ERROR_BADPARTIAL (-13) #define PCRE_ERROR_INTERNAL (-14) #define PCRE_ERROR_BADCOUNT (-15) #define PCRE_ERROR_DFA_UITEM (-16) #define PCRE_ERROR_DFA_UCOND (-17) #define PCRE_ERROR_DFA_UMLIMIT (-18) #define PCRE_ERROR_DFA_WSSIZE (-19) #define PCRE_ERROR_DFA_RECURSE (-20) #define PCRE_ERROR_RECURSIONLIMIT (-21) #define PCRE_ERROR_NOTUSED (-22) #define PCRE_ERROR_BADNEWLINE (-23) /* Request types for pcre_fullinfo() */ #define PCRE_INFO_OPTIONS 0 #define PCRE_INFO_SIZE 1 #define PCRE_INFO_CAPTURECOUNT 2 #define PCRE_INFO_BACKREFMAX 3 #define PCRE_INFO_FIRSTBYTE 4 #define PCRE_INFO_FIRSTCHAR 4 /* For backwards compatibility */ #define PCRE_INFO_FIRSTTABLE 5 #define PCRE_INFO_LASTLITERAL 6 #define PCRE_INFO_NAMEENTRYSIZE 7 #define PCRE_INFO_NAMECOUNT 8 #define PCRE_INFO_NAMETABLE 9 #define PCRE_INFO_STUDYSIZE 10 #define PCRE_INFO_DEFAULT_TABLES 11 #define PCRE_INFO_OKPARTIAL 12 #define PCRE_INFO_JCHANGED 13 #define PCRE_INFO_HASCRORLF 14 /* Request types for pcre_config(). Do not re-arrange, in order to remain compatible. */ #define PCRE_CONFIG_UTF8 0 #define PCRE_CONFIG_NEWLINE 1 #define PCRE_CONFIG_LINK_SIZE 2 #define PCRE_CONFIG_POSIX_MALLOC_THRESHOLD 3 #define PCRE_CONFIG_MATCH_LIMIT 4 #define PCRE_CONFIG_STACKRECURSE 5 #define PCRE_CONFIG_UNICODE_PROPERTIES 6 #define PCRE_CONFIG_MATCH_LIMIT_RECURSION 7 /* Bit flags for the pcre_extra structure. Do not re-arrange or redefine these bits, just add new ones on the end, in order to remain compatible. */ #define PCRE_EXTRA_STUDY_DATA 0x0001 #define PCRE_EXTRA_MATCH_LIMIT 0x0002 #define PCRE_EXTRA_CALLOUT_DATA 0x0004 #define PCRE_EXTRA_TABLES 0x0008 #define PCRE_EXTRA_MATCH_LIMIT_RECURSION 0x0010 /* Types */ struct real_pcre; /* declaration; the definition is private */ typedef struct real_pcre pcre; /* When PCRE is compiled as a C++ library, the subject pointer type can be replaced with a custom type. For conventional use, the public interface is a const char *. */ #ifndef PCRE_SPTR #define PCRE_SPTR const char * #endif /* The structure for passing additional data to pcre_exec(). This is defined in such as way as to be extensible. Always add new fields at the end, in order to remain compatible. */ typedef struct pcre_extra { unsigned long int flags; /* Bits for which fields are set */ void *study_data; /* Opaque data from pcre_study() */ unsigned long int match_limit; /* Maximum number of calls to match() */ void *callout_data; /* Data passed back in callouts */ const unsigned char *tables; /* Pointer to character tables */ unsigned long int match_limit_recursion; /* Max recursive calls to match() */ } pcre_extra; /* The structure for passing out data via the pcre_callout_function. We use a structure so that new fields can be added on the end in future versions, without changing the API of the function, thereby allowing old clients to work without modification. */ typedef struct pcre_callout_block { int version; /* Identifies version of block */ /* ------------------------ Version 0 ------------------------------- */ int callout_number; /* Number compiled into pattern */ int *offset_vector; /* The offset vector */ PCRE_SPTR subject; /* The subject being matched */ int subject_length; /* The length of the subject */ int start_match; /* Offset to start of this match attempt */ int current_position; /* Where we currently are in the subject */ int capture_top; /* Max current capture */ int capture_last; /* Most recently closed capture */ void *callout_data; /* Data passed in with the call */ /* ------------------- Added for Version 1 -------------------------- */ int pattern_position; /* Offset to next item in the pattern */ int next_item_length; /* Length of next item in the pattern */ /* ------------------------------------------------------------------ */ } pcre_callout_block; /* Indirection for store get and free functions. These can be set to alternative malloc/free functions if required. Special ones are used in the non-recursive case for "frames". There is also an optional callout function that is triggered by the (?) regex item. For Virtual Pascal, these definitions have to take another form. */ #ifndef VPCOMPAT PCRE_EXP_DECL void *(*pcre_malloc)(size_t); PCRE_EXP_DECL void (*pcre_free)(void *); PCRE_EXP_DECL void *(*pcre_stack_malloc)(size_t); PCRE_EXP_DECL void (*pcre_stack_free)(void *); PCRE_EXP_DECL int (*pcre_callout)(pcre_callout_block *); #else /* VPCOMPAT */ PCRE_EXP_DECL void *pcre_malloc(size_t); PCRE_EXP_DECL void pcre_free(void *); PCRE_EXP_DECL void *pcre_stack_malloc(size_t); PCRE_EXP_DECL void pcre_stack_free(void *); PCRE_EXP_DECL int pcre_callout(pcre_callout_block *); #endif /* VPCOMPAT */ /* Exported PCRE functions */ PCRE_EXP_DECL pcre *pcre_compile(const char *, int, const char **, int *, const unsigned char *); PCRE_EXP_DECL pcre *pcre_compile2(const char *, int, int *, const char **, int *, const unsigned char *); PCRE_EXP_DECL int pcre_config(int, void *); PCRE_EXP_DECL int pcre_copy_named_substring(const pcre *, const char *, int *, int, const char *, char *, int); PCRE_EXP_DECL int pcre_copy_substring(const char *, int *, int, int, char *, int); PCRE_EXP_DECL int pcre_dfa_exec(const pcre *, const pcre_extra *, const char *, int, int, int, int *, int , int *, int); PCRE_EXP_DECL int pcre_exec(const pcre *, const pcre_extra *, PCRE_SPTR, int, int, int, int *, int); PCRE_EXP_DECL void pcre_free_substring(const char *); PCRE_EXP_DECL void pcre_free_substring_list(const char **); PCRE_EXP_DECL int pcre_fullinfo(const pcre *, const pcre_extra *, int, void *); PCRE_EXP_DECL int pcre_get_named_substring(const pcre *, const char *, int *, int, const char *, const char **); PCRE_EXP_DECL int pcre_get_stringnumber(const pcre *, const char *); PCRE_EXP_DECL int pcre_get_stringtable_entries(const pcre *, const char *, char **, char **); PCRE_EXP_DECL int pcre_get_substring(const char *, int *, int, int, const char **); PCRE_EXP_DECL int pcre_get_substring_list(const char *, int *, int, const char ***); PCRE_EXP_DECL int pcre_info(const pcre *, int *, int *); PCRE_EXP_DECL const unsigned char *pcre_maketables(void); PCRE_EXP_DECL int pcre_refcount(pcre *, int); PCRE_EXP_DECL pcre_extra *pcre_study(const pcre *, int, const char **); PCRE_EXP_DECL const char *pcre_version(void); #ifdef __cplusplus } /* extern "C" */ #endif #endif /* End of pcre.h */ libsynthesis-3.4.0.47.1/src/pcre/pcre.h.in000066400000000000000000000300331226375725500200720ustar00rootroot00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* This is the public header file for the PCRE library, to be #included by applications that call the PCRE functions. Copyright (c) 1997-2007 University of Cambridge ----------------------------------------------------------------------------- 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 name of the University of Cambridge 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. ----------------------------------------------------------------------------- */ #ifndef _PCRE_H #define _PCRE_H /* The current PCRE version information. */ #define PCRE_MAJOR @PCRE_MAJOR@ #define PCRE_MINOR @PCRE_MINOR@ #define PCRE_PRERELEASE @PCRE_PRERELEASE@ #define PCRE_DATE @PCRE_DATE@ /* When an application links to a PCRE DLL in Windows, the symbols that are imported have to be identified as such. When building PCRE, the appropriate export setting is defined in pcre_internal.h, which includes this file. So we don't change existing definitions of PCRE_EXP_DECL and PCRECPP_EXP_DECL. */ #if defined(_WIN32) && !defined(PCRE_STATIC) # ifndef PCRE_EXP_DECL # define PCRE_EXP_DECL extern __declspec(dllimport) # endif # ifdef __cplusplus # ifndef PCRECPP_EXP_DECL # define PCRECPP_EXP_DECL extern __declspec(dllimport) # endif # ifndef PCRECPP_EXP_DEFN # define PCRECPP_EXP_DEFN __declspec(dllimport) # endif # endif #endif /* By default, we use the standard "extern" declarations. */ #ifndef PCRE_EXP_DECL # ifdef __cplusplus # define PCRE_EXP_DECL extern "C" # else # define PCRE_EXP_DECL extern # endif #endif #ifdef __cplusplus # ifndef PCRECPP_EXP_DECL # define PCRECPP_EXP_DECL extern # endif # ifndef PCRECPP_EXP_DEFN # define PCRECPP_EXP_DEFN # endif #endif /* Have to include stdlib.h in order to ensure that size_t is defined; it is needed here for malloc. */ #include /* Allow for C++ users */ #ifdef __cplusplus extern "C" { #endif /* Options */ #define PCRE_CASELESS 0x00000001 #define PCRE_MULTILINE 0x00000002 #define PCRE_DOTALL 0x00000004 #define PCRE_EXTENDED 0x00000008 #define PCRE_ANCHORED 0x00000010 #define PCRE_DOLLAR_ENDONLY 0x00000020 #define PCRE_EXTRA 0x00000040 #define PCRE_NOTBOL 0x00000080 #define PCRE_NOTEOL 0x00000100 #define PCRE_UNGREEDY 0x00000200 #define PCRE_NOTEMPTY 0x00000400 #define PCRE_UTF8 0x00000800 #define PCRE_NO_AUTO_CAPTURE 0x00001000 #define PCRE_NO_UTF8_CHECK 0x00002000 #define PCRE_AUTO_CALLOUT 0x00004000 #define PCRE_PARTIAL 0x00008000 #define PCRE_DFA_SHORTEST 0x00010000 #define PCRE_DFA_RESTART 0x00020000 #define PCRE_FIRSTLINE 0x00040000 #define PCRE_DUPNAMES 0x00080000 #define PCRE_NEWLINE_CR 0x00100000 #define PCRE_NEWLINE_LF 0x00200000 #define PCRE_NEWLINE_CRLF 0x00300000 #define PCRE_NEWLINE_ANY 0x00400000 #define PCRE_NEWLINE_ANYCRLF 0x00500000 /* Exec-time and get/set-time error codes */ #define PCRE_ERROR_NOMATCH (-1) #define PCRE_ERROR_NULL (-2) #define PCRE_ERROR_BADOPTION (-3) #define PCRE_ERROR_BADMAGIC (-4) #define PCRE_ERROR_UNKNOWN_OPCODE (-5) #define PCRE_ERROR_UNKNOWN_NODE (-5) /* For backward compatibility */ #define PCRE_ERROR_NOMEMORY (-6) #define PCRE_ERROR_NOSUBSTRING (-7) #define PCRE_ERROR_MATCHLIMIT (-8) #define PCRE_ERROR_CALLOUT (-9) /* Never used by PCRE itself */ #define PCRE_ERROR_BADUTF8 (-10) #define PCRE_ERROR_BADUTF8_OFFSET (-11) #define PCRE_ERROR_PARTIAL (-12) #define PCRE_ERROR_BADPARTIAL (-13) #define PCRE_ERROR_INTERNAL (-14) #define PCRE_ERROR_BADCOUNT (-15) #define PCRE_ERROR_DFA_UITEM (-16) #define PCRE_ERROR_DFA_UCOND (-17) #define PCRE_ERROR_DFA_UMLIMIT (-18) #define PCRE_ERROR_DFA_WSSIZE (-19) #define PCRE_ERROR_DFA_RECURSE (-20) #define PCRE_ERROR_RECURSIONLIMIT (-21) #define PCRE_ERROR_NOTUSED (-22) #define PCRE_ERROR_BADNEWLINE (-23) /* Request types for pcre_fullinfo() */ #define PCRE_INFO_OPTIONS 0 #define PCRE_INFO_SIZE 1 #define PCRE_INFO_CAPTURECOUNT 2 #define PCRE_INFO_BACKREFMAX 3 #define PCRE_INFO_FIRSTBYTE 4 #define PCRE_INFO_FIRSTCHAR 4 /* For backwards compatibility */ #define PCRE_INFO_FIRSTTABLE 5 #define PCRE_INFO_LASTLITERAL 6 #define PCRE_INFO_NAMEENTRYSIZE 7 #define PCRE_INFO_NAMECOUNT 8 #define PCRE_INFO_NAMETABLE 9 #define PCRE_INFO_STUDYSIZE 10 #define PCRE_INFO_DEFAULT_TABLES 11 #define PCRE_INFO_OKPARTIAL 12 #define PCRE_INFO_JCHANGED 13 #define PCRE_INFO_HASCRORLF 14 /* Request types for pcre_config(). Do not re-arrange, in order to remain compatible. */ #define PCRE_CONFIG_UTF8 0 #define PCRE_CONFIG_NEWLINE 1 #define PCRE_CONFIG_LINK_SIZE 2 #define PCRE_CONFIG_POSIX_MALLOC_THRESHOLD 3 #define PCRE_CONFIG_MATCH_LIMIT 4 #define PCRE_CONFIG_STACKRECURSE 5 #define PCRE_CONFIG_UNICODE_PROPERTIES 6 #define PCRE_CONFIG_MATCH_LIMIT_RECURSION 7 /* Bit flags for the pcre_extra structure. Do not re-arrange or redefine these bits, just add new ones on the end, in order to remain compatible. */ #define PCRE_EXTRA_STUDY_DATA 0x0001 #define PCRE_EXTRA_MATCH_LIMIT 0x0002 #define PCRE_EXTRA_CALLOUT_DATA 0x0004 #define PCRE_EXTRA_TABLES 0x0008 #define PCRE_EXTRA_MATCH_LIMIT_RECURSION 0x0010 /* Types */ struct real_pcre; /* declaration; the definition is private */ typedef struct real_pcre pcre; /* When PCRE is compiled as a C++ library, the subject pointer type can be replaced with a custom type. For conventional use, the public interface is a const char *. */ #ifndef PCRE_SPTR #define PCRE_SPTR const char * #endif /* The structure for passing additional data to pcre_exec(). This is defined in such as way as to be extensible. Always add new fields at the end, in order to remain compatible. */ typedef struct pcre_extra { unsigned long int flags; /* Bits for which fields are set */ void *study_data; /* Opaque data from pcre_study() */ unsigned long int match_limit; /* Maximum number of calls to match() */ void *callout_data; /* Data passed back in callouts */ const unsigned char *tables; /* Pointer to character tables */ unsigned long int match_limit_recursion; /* Max recursive calls to match() */ } pcre_extra; /* The structure for passing out data via the pcre_callout_function. We use a structure so that new fields can be added on the end in future versions, without changing the API of the function, thereby allowing old clients to work without modification. */ typedef struct pcre_callout_block { int version; /* Identifies version of block */ /* ------------------------ Version 0 ------------------------------- */ int callout_number; /* Number compiled into pattern */ int *offset_vector; /* The offset vector */ PCRE_SPTR subject; /* The subject being matched */ int subject_length; /* The length of the subject */ int start_match; /* Offset to start of this match attempt */ int current_position; /* Where we currently are in the subject */ int capture_top; /* Max current capture */ int capture_last; /* Most recently closed capture */ void *callout_data; /* Data passed in with the call */ /* ------------------- Added for Version 1 -------------------------- */ int pattern_position; /* Offset to next item in the pattern */ int next_item_length; /* Length of next item in the pattern */ /* ------------------------------------------------------------------ */ } pcre_callout_block; /* Indirection for store get and free functions. These can be set to alternative malloc/free functions if required. Special ones are used in the non-recursive case for "frames". There is also an optional callout function that is triggered by the (?) regex item. For Virtual Pascal, these definitions have to take another form. */ #ifndef VPCOMPAT PCRE_EXP_DECL void *(*pcre_malloc)(size_t); PCRE_EXP_DECL void (*pcre_free)(void *); PCRE_EXP_DECL void *(*pcre_stack_malloc)(size_t); PCRE_EXP_DECL void (*pcre_stack_free)(void *); PCRE_EXP_DECL int (*pcre_callout)(pcre_callout_block *); #else /* VPCOMPAT */ PCRE_EXP_DECL void *pcre_malloc(size_t); PCRE_EXP_DECL void pcre_free(void *); PCRE_EXP_DECL void *pcre_stack_malloc(size_t); PCRE_EXP_DECL void pcre_stack_free(void *); PCRE_EXP_DECL int pcre_callout(pcre_callout_block *); #endif /* VPCOMPAT */ /* Exported PCRE functions */ PCRE_EXP_DECL pcre *pcre_compile(const char *, int, const char **, int *, const unsigned char *); PCRE_EXP_DECL pcre *pcre_compile2(const char *, int, int *, const char **, int *, const unsigned char *); PCRE_EXP_DECL int pcre_config(int, void *); PCRE_EXP_DECL int pcre_copy_named_substring(const pcre *, const char *, int *, int, const char *, char *, int); PCRE_EXP_DECL int pcre_copy_substring(const char *, int *, int, int, char *, int); PCRE_EXP_DECL int pcre_dfa_exec(const pcre *, const pcre_extra *, const char *, int, int, int, int *, int , int *, int); PCRE_EXP_DECL int pcre_exec(const pcre *, const pcre_extra *, PCRE_SPTR, int, int, int, int *, int); PCRE_EXP_DECL void pcre_free_substring(const char *); PCRE_EXP_DECL void pcre_free_substring_list(const char **); PCRE_EXP_DECL int pcre_fullinfo(const pcre *, const pcre_extra *, int, void *); PCRE_EXP_DECL int pcre_get_named_substring(const pcre *, const char *, int *, int, const char *, const char **); PCRE_EXP_DECL int pcre_get_stringnumber(const pcre *, const char *); PCRE_EXP_DECL int pcre_get_stringtable_entries(const pcre *, const char *, char **, char **); PCRE_EXP_DECL int pcre_get_substring(const char *, int *, int, int, const char **); PCRE_EXP_DECL int pcre_get_substring_list(const char *, int *, int, const char ***); PCRE_EXP_DECL int pcre_info(const pcre *, int *, int *); PCRE_EXP_DECL const unsigned char *pcre_maketables(void); PCRE_EXP_DECL int pcre_refcount(pcre *, int); PCRE_EXP_DECL pcre_extra *pcre_study(const pcre *, int, const char **); PCRE_EXP_DECL const char *pcre_version(void); #ifdef __cplusplus } /* extern "C" */ #endif #endif /* End of pcre.h */ libsynthesis-3.4.0.47.1/src/pcre/pcre_chartables.c000066400000000000000000000172221226375725500216550ustar00rootroot00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* This file contains character tables that are used when no external tables are passed to PCRE by the application that calls it. The tables are used only for characters whose code values are less than 256. This is a default version of the tables that assumes ASCII encoding. A program called dftables (which is distributed with PCRE) can be used to build alternative versions of this file. This is necessary if you are running in an EBCDIC environment, or if you want to default to a different encoding, for example ISO-8859-1. When dftables is run, it creates these tables in the current locale. If PCRE is configured with --enable-rebuild-chartables, this happens automatically. The following #includes are present because without the gcc 4.x may remove the array definition from the final binary if PCRE is built into a static library and dead code stripping is activated. This leads to link errors. Pulling in the header ensures that the array gets flagged as "someone outside this compilation unit might reference this" and so it will always be supplied to the linker. */ #include "pcre_setup.h" #include "pcre_internal.h" const unsigned char _pcre_default_tables[] = { /* This table is a lower casing table. */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 97, 98, 99,100,101,102,103, 104,105,106,107,108,109,110,111, 112,113,114,115,116,117,118,119, 120,121,122, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103, 104,105,106,107,108,109,110,111, 112,113,114,115,116,117,118,119, 120,121,122,123,124,125,126,127, 128,129,130,131,132,133,134,135, 136,137,138,139,140,141,142,143, 144,145,146,147,148,149,150,151, 152,153,154,155,156,157,158,159, 160,161,162,163,164,165,166,167, 168,169,170,171,172,173,174,175, 176,177,178,179,180,181,182,183, 184,185,186,187,188,189,190,191, 192,193,194,195,196,197,198,199, 200,201,202,203,204,205,206,207, 208,209,210,211,212,213,214,215, 216,217,218,219,220,221,222,223, 224,225,226,227,228,229,230,231, 232,233,234,235,236,237,238,239, 240,241,242,243,244,245,246,247, 248,249,250,251,252,253,254,255, /* This table is a case flipping table. */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 97, 98, 99,100,101,102,103, 104,105,106,107,108,109,110,111, 112,113,114,115,116,117,118,119, 120,121,122, 91, 92, 93, 94, 95, 96, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,123,124,125,126,127, 128,129,130,131,132,133,134,135, 136,137,138,139,140,141,142,143, 144,145,146,147,148,149,150,151, 152,153,154,155,156,157,158,159, 160,161,162,163,164,165,166,167, 168,169,170,171,172,173,174,175, 176,177,178,179,180,181,182,183, 184,185,186,187,188,189,190,191, 192,193,194,195,196,197,198,199, 200,201,202,203,204,205,206,207, 208,209,210,211,212,213,214,215, 216,217,218,219,220,221,222,223, 224,225,226,227,228,229,230,231, 232,233,234,235,236,237,238,239, 240,241,242,243,244,245,246,247, 248,249,250,251,252,253,254,255, /* This table contains bit maps for various character classes. Each map is 32 bytes long and the bits run from the least significant end of each byte. The classes that have their own maps are: space, xdigit, digit, upper, lower, word, graph, print, punct, and cntrl. Other classes are built from combinations. */ 0x00,0x3e,0x00,0x00,0x01,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, 0x7e,0x00,0x00,0x00,0x7e,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0xfe,0xff,0xff,0x07,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0x07, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, 0xfe,0xff,0xff,0x87,0xfe,0xff,0xff,0x07, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0xfe,0xff,0x00,0xfc, 0x01,0x00,0x00,0xf8,0x01,0x00,0x00,0x78, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* This table identifies various classes of character by individual bits: 0x01 white space character 0x02 letter 0x04 decimal digit 0x08 hexadecimal digit 0x10 alphanumeric or '_' 0x80 regular expression metacharacter or binary zero */ 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */ 0x00,0x01,0x01,0x00,0x01,0x01,0x00,0x00, /* 8- 15 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */ 0x01,0x00,0x00,0x00,0x80,0x00,0x00,0x00, /* - ' */ 0x80,0x80,0x80,0x80,0x00,0x00,0x80,0x00, /* ( - / */ 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c, /* 0 - 7 */ 0x1c,0x1c,0x00,0x00,0x00,0x00,0x00,0x80, /* 8 - ? */ 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* @ - G */ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* H - O */ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* P - W */ 0x12,0x12,0x12,0x80,0x80,0x00,0x80,0x10, /* X - _ */ 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* ` - g */ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* h - o */ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* p - w */ 0x12,0x12,0x12,0x80,0x80,0x00,0x00,0x00, /* x -127 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 128-135 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144-151 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 152-159 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160-167 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168-175 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176-183 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 192-199 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 200-207 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 208-215 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 216-223 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 224-231 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 232-239 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240-247 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */ /* End of pcre_chartables.c */ libsynthesis-3.4.0.47.1/src/pcre/pcre_chartables.c.dist000066400000000000000000000172521226375725500226220ustar00rootroot00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* This file contains character tables that are used when no external tables are passed to PCRE by the application that calls it. The tables are used only for characters whose code values are less than 256. This is a default version of the tables that assumes ASCII encoding. A program called dftables (which is distributed with PCRE) can be used to build alternative versions of this file. This is necessary if you are running in an EBCDIC environment, or if you want to default to a different encoding, for example ISO-8859-1. When dftables is run, it creates these tables in the current locale. If PCRE is configured with --enable-rebuild-chartables, this happens automatically. The following #includes are present because without the gcc 4.x may remove the array definition from the final binary if PCRE is built into a static library and dead code stripping is activated. This leads to link errors. Pulling in the header ensures that the array gets flagged as "someone outside this compilation unit might reference this" and so it will always be supplied to the linker. */ #ifdef HAVE_CONFIG_H #include #endif #include "pcre_internal.h" const unsigned char _pcre_default_tables[] = { /* This table is a lower casing table. */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 97, 98, 99,100,101,102,103, 104,105,106,107,108,109,110,111, 112,113,114,115,116,117,118,119, 120,121,122, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103, 104,105,106,107,108,109,110,111, 112,113,114,115,116,117,118,119, 120,121,122,123,124,125,126,127, 128,129,130,131,132,133,134,135, 136,137,138,139,140,141,142,143, 144,145,146,147,148,149,150,151, 152,153,154,155,156,157,158,159, 160,161,162,163,164,165,166,167, 168,169,170,171,172,173,174,175, 176,177,178,179,180,181,182,183, 184,185,186,187,188,189,190,191, 192,193,194,195,196,197,198,199, 200,201,202,203,204,205,206,207, 208,209,210,211,212,213,214,215, 216,217,218,219,220,221,222,223, 224,225,226,227,228,229,230,231, 232,233,234,235,236,237,238,239, 240,241,242,243,244,245,246,247, 248,249,250,251,252,253,254,255, /* This table is a case flipping table. */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 97, 98, 99,100,101,102,103, 104,105,106,107,108,109,110,111, 112,113,114,115,116,117,118,119, 120,121,122, 91, 92, 93, 94, 95, 96, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,123,124,125,126,127, 128,129,130,131,132,133,134,135, 136,137,138,139,140,141,142,143, 144,145,146,147,148,149,150,151, 152,153,154,155,156,157,158,159, 160,161,162,163,164,165,166,167, 168,169,170,171,172,173,174,175, 176,177,178,179,180,181,182,183, 184,185,186,187,188,189,190,191, 192,193,194,195,196,197,198,199, 200,201,202,203,204,205,206,207, 208,209,210,211,212,213,214,215, 216,217,218,219,220,221,222,223, 224,225,226,227,228,229,230,231, 232,233,234,235,236,237,238,239, 240,241,242,243,244,245,246,247, 248,249,250,251,252,253,254,255, /* This table contains bit maps for various character classes. Each map is 32 bytes long and the bits run from the least significant end of each byte. The classes that have their own maps are: space, xdigit, digit, upper, lower, word, graph, print, punct, and cntrl. Other classes are built from combinations. */ 0x00,0x3e,0x00,0x00,0x01,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, 0x7e,0x00,0x00,0x00,0x7e,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0xfe,0xff,0xff,0x07,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0x07, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, 0xfe,0xff,0xff,0x87,0xfe,0xff,0xff,0x07, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0xfe,0xff,0x00,0xfc, 0x01,0x00,0x00,0xf8,0x01,0x00,0x00,0x78, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* This table identifies various classes of character by individual bits: 0x01 white space character 0x02 letter 0x04 decimal digit 0x08 hexadecimal digit 0x10 alphanumeric or '_' 0x80 regular expression metacharacter or binary zero */ 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */ 0x00,0x01,0x01,0x00,0x01,0x01,0x00,0x00, /* 8- 15 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */ 0x01,0x00,0x00,0x00,0x80,0x00,0x00,0x00, /* - ' */ 0x80,0x80,0x80,0x80,0x00,0x00,0x80,0x00, /* ( - / */ 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c, /* 0 - 7 */ 0x1c,0x1c,0x00,0x00,0x00,0x00,0x00,0x80, /* 8 - ? */ 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* @ - G */ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* H - O */ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* P - W */ 0x12,0x12,0x12,0x80,0x80,0x00,0x80,0x10, /* X - _ */ 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* ` - g */ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* h - o */ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* p - w */ 0x12,0x12,0x12,0x80,0x80,0x00,0x00,0x00, /* x -127 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 128-135 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144-151 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 152-159 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160-167 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168-175 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176-183 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 192-199 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 200-207 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 208-215 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 216-223 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 224-231 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 232-239 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240-247 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */ /* End of pcre_chartables.c */ libsynthesis-3.4.0.47.1/src/pcre/pcre_compile.c000066400000000000000000005643711226375725500212110ustar00rootroot00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2007 University of Cambridge ----------------------------------------------------------------------------- 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 name of the University of Cambridge 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. ----------------------------------------------------------------------------- */ /* This module contains the external function pcre_compile(), along with supporting internal functions that are not used by other modules. */ #include "pcre_setup.h" #define NLBLOCK cd /* Block containing newline information */ #define PSSTART start_pattern /* Field containing processed string start */ #define PSEND end_pattern /* Field containing processed string end */ #include "pcre_internal.h" /* When DEBUG is defined, we need the pcre_printint() function, which is also used by pcretest. DEBUG is not defined when building a production library. */ #ifdef DEBUG #include "pcre_printint.src" #endif /* Macro for setting individual bits in class bitmaps. */ #define SETBIT(a,b) a[b/8] |= (1 << (b%8)) /* Maximum length value to check against when making sure that the integer that holds the compiled pattern length does not overflow. We make it a bit less than INT_MAX to allow for adding in group terminating bytes, so that we don't have to check them every time. */ #define OFLOW_MAX (INT_MAX - 20) /************************************************* * Code parameters and static tables * *************************************************/ /* This value specifies the size of stack workspace that is used during the first pre-compile phase that determines how much memory is required. The regex is partly compiled into this space, but the compiled parts are discarded as soon as they can be, so that hopefully there will never be an overrun. The code does, however, check for an overrun. The largest amount I've seen used is 218, so this number is very generous. The same workspace is used during the second, actual compile phase for remembering forward references to groups so that they can be filled in at the end. Each entry in this list occupies LINK_SIZE bytes, so even when LINK_SIZE is 4 there is plenty of room. */ #define COMPILE_WORK_SIZE (4096) /* Table for handling escaped characters in the range '0'-'z'. Positive returns are simple data values; negative values are for special things like \d and so on. Zero means further processing is needed (for things like \x), or the escape is invalid. */ #ifndef EBCDIC /* This is the "normal" table for ASCII systems */ static const short int escapes[] = { 0, 0, 0, 0, 0, 0, 0, 0, /* 0 - 7 */ 0, 0, ':', ';', '<', '=', '>', '?', /* 8 - ? */ '@', -ESC_A, -ESC_B, -ESC_C, -ESC_D, -ESC_E, 0, -ESC_G, /* @ - G */ -ESC_H, 0, 0, -ESC_K, 0, 0, 0, 0, /* H - O */ -ESC_P, -ESC_Q, -ESC_R, -ESC_S, 0, 0, -ESC_V, -ESC_W, /* P - W */ -ESC_X, 0, -ESC_Z, '[', '\\', ']', '^', '_', /* X - _ */ '`', 7, -ESC_b, 0, -ESC_d, ESC_e, ESC_f, 0, /* ` - g */ -ESC_h, 0, 0, -ESC_k, 0, 0, ESC_n, 0, /* h - o */ -ESC_p, 0, ESC_r, -ESC_s, ESC_tee, 0, -ESC_v, -ESC_w, /* p - w */ 0, 0, -ESC_z /* x - z */ }; #else /* This is the "abnormal" table for EBCDIC systems */ static const short int escapes[] = { /* 48 */ 0, 0, 0, '.', '<', '(', '+', '|', /* 50 */ '&', 0, 0, 0, 0, 0, 0, 0, /* 58 */ 0, 0, '!', '$', '*', ')', ';', '~', /* 60 */ '-', '/', 0, 0, 0, 0, 0, 0, /* 68 */ 0, 0, '|', ',', '%', '_', '>', '?', /* 70 */ 0, 0, 0, 0, 0, 0, 0, 0, /* 78 */ 0, '`', ':', '#', '@', '\'', '=', '"', /* 80 */ 0, 7, -ESC_b, 0, -ESC_d, ESC_e, ESC_f, 0, /* 88 */-ESC_h, 0, 0, '{', 0, 0, 0, 0, /* 90 */ 0, 0, -ESC_k, 'l', 0, ESC_n, 0, -ESC_p, /* 98 */ 0, ESC_r, 0, '}', 0, 0, 0, 0, /* A0 */ 0, '~', -ESC_s, ESC_tee, 0,-ESC_v, -ESC_w, 0, /* A8 */ 0,-ESC_z, 0, 0, 0, '[', 0, 0, /* B0 */ 0, 0, 0, 0, 0, 0, 0, 0, /* B8 */ 0, 0, 0, 0, 0, ']', '=', '-', /* C0 */ '{',-ESC_A, -ESC_B, -ESC_C, -ESC_D,-ESC_E, 0, -ESC_G, /* C8 */-ESC_H, 0, 0, 0, 0, 0, 0, 0, /* D0 */ '}', 0, -ESC_K, 0, 0, 0, 0, -ESC_P, /* D8 */-ESC_Q,-ESC_R, 0, 0, 0, 0, 0, 0, /* E0 */ '\\', 0, -ESC_S, 0, 0,-ESC_V, -ESC_W, -ESC_X, /* E8 */ 0,-ESC_Z, 0, 0, 0, 0, 0, 0, /* F0 */ 0, 0, 0, 0, 0, 0, 0, 0, /* F8 */ 0, 0, 0, 0, 0, 0, 0, 0 }; #endif /* Table of special "verbs" like (*PRUNE) */ typedef struct verbitem { const char *name; int len; int op; } verbitem; static verbitem verbs[] = { { "ACCEPT", 6, OP_ACCEPT }, { "COMMIT", 6, OP_COMMIT }, { "F", 1, OP_FAIL }, { "FAIL", 4, OP_FAIL }, { "PRUNE", 5, OP_PRUNE }, { "SKIP", 4, OP_SKIP }, { "THEN", 4, OP_THEN } }; static int verbcount = sizeof(verbs)/sizeof(verbitem); /* Tables of names of POSIX character classes and their lengths. The list is terminated by a zero length entry. The first three must be alpha, lower, upper, as this is assumed for handling case independence. */ static const char *const posix_names[] = { "alpha", "lower", "upper", "alnum", "ascii", "blank", "cntrl", "digit", "graph", "print", "punct", "space", "word", "xdigit" }; static const uschar posix_name_lengths[] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 6, 0 }; /* Table of class bit maps for each POSIX class. Each class is formed from a base map, with an optional addition or removal of another map. Then, for some classes, there is some additional tweaking: for [:blank:] the vertical space characters are removed, and for [:alpha:] and [:alnum:] the underscore character is removed. The triples in the table consist of the base map offset, second map offset or -1 if no second map, and a non-negative value for map addition or a negative value for map subtraction (if there are two maps). The absolute value of the third field has these meanings: 0 => no tweaking, 1 => remove vertical space characters, 2 => remove underscore. */ static const int posix_class_maps[] = { cbit_word, cbit_digit, -2, /* alpha */ cbit_lower, -1, 0, /* lower */ cbit_upper, -1, 0, /* upper */ cbit_word, -1, 2, /* alnum - word without underscore */ cbit_print, cbit_cntrl, 0, /* ascii */ cbit_space, -1, 1, /* blank - a GNU extension */ cbit_cntrl, -1, 0, /* cntrl */ cbit_digit, -1, 0, /* digit */ cbit_graph, -1, 0, /* graph */ cbit_print, -1, 0, /* print */ cbit_punct, -1, 0, /* punct */ cbit_space, -1, 0, /* space */ cbit_word, -1, 0, /* word - a Perl extension */ cbit_xdigit,-1, 0 /* xdigit */ }; #define STRING(a) # a #define XSTRING(s) STRING(s) /* The texts of compile-time error messages. These are "char *" because they are passed to the outside world. Do not ever re-use any error number, because they are documented. Always add a new error instead. Messages marked DEAD below are no longer used. */ static const char *error_texts[] = { "no error", "\\ at end of pattern", "\\c at end of pattern", "unrecognized character follows \\", "numbers out of order in {} quantifier", /* 5 */ "number too big in {} quantifier", "missing terminating ] for character class", "invalid escape sequence in character class", "range out of order in character class", "nothing to repeat", /* 10 */ "operand of unlimited repeat could match the empty string", /** DEAD **/ "internal error: unexpected repeat", "unrecognized character after (?", "POSIX named classes are supported only within a class", "missing )", /* 15 */ "reference to non-existent subpattern", "erroffset passed as NULL", "unknown option bit(s) set", "missing ) after comment", "parentheses nested too deeply", /** DEAD **/ /* 20 */ "regular expression is too large", "failed to get memory", "unmatched parentheses", "internal error: code overflow", "unrecognized character after (?<", /* 25 */ "lookbehind assertion is not fixed length", "malformed number or name after (?(", "conditional group contains more than two branches", "assertion expected after (?(", "(?R or (?[+-]digits must be followed by )", /* 30 */ "unknown POSIX class name", "POSIX collating elements are not supported", "this version of PCRE is not compiled with PCRE_UTF8 support", "spare error", /** DEAD **/ "character value in \\x{...} sequence is too large", /* 35 */ "invalid condition (?(0)", "\\C not allowed in lookbehind assertion", "PCRE does not support \\L, \\l, \\N, \\U, or \\u", "number after (?C is > 255", "closing ) for (?C expected", /* 40 */ "recursive call could loop indefinitely", "unrecognized character after (?P", "syntax error in subpattern name (missing terminator)", "two named subpatterns have the same name", "invalid UTF-8 string", /* 45 */ "support for \\P, \\p, and \\X has not been compiled", "malformed \\P or \\p sequence", "unknown property name after \\P or \\p", "subpattern name is too long (maximum " XSTRING(MAX_NAME_SIZE) " characters)", "too many named subpatterns (maximum " XSTRING(MAX_NAME_COUNT) ")", /* 50 */ "repeated subpattern is too long", /** DEAD **/ "octal value is greater than \\377 (not in UTF-8 mode)", "internal error: overran compiling workspace", "internal error: previously-checked referenced subpattern not found", "DEFINE group contains more than one branch", /* 55 */ "repeating a DEFINE group is not allowed", "inconsistent NEWLINE options", "\\g is not followed by a braced name or an optionally braced non-zero number", "(?+ or (?- or (?(+ or (?(- must be followed by a non-zero number", "(*VERB) with an argument is not supported", /* 60 */ "(*VERB) not recognized", "number is too big" }; /* Table to identify digits and hex digits. This is used when compiling patterns. Note that the tables in chartables are dependent on the locale, and may mark arbitrary characters as digits - but the PCRE compiling code expects to handle only 0-9, a-z, and A-Z as digits when compiling. That is why we have a private table here. It costs 256 bytes, but it is a lot faster than doing character value tests (at least in some simple cases I timed), and in some applications one wants PCRE to compile efficiently as well as match efficiently. For convenience, we use the same bit definitions as in chartables: 0x04 decimal digit 0x08 hexadecimal digit Then we can use ctype_digit and ctype_xdigit in the code. */ #ifndef EBCDIC /* This is the "normal" case, for ASCII systems */ static const unsigned char digitab[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 8- 15 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - ' */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ( - / */ 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c, /* 0 - 7 */ 0x0c,0x0c,0x00,0x00,0x00,0x00,0x00,0x00, /* 8 - ? */ 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, /* @ - G */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* H - O */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* P - W */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* X - _ */ 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, /* ` - g */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* h - o */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p - w */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* x -127 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 128-135 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144-151 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 152-159 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160-167 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168-175 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176-183 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 192-199 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 200-207 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 208-215 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 216-223 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 224-231 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 232-239 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240-247 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */ #else /* This is the "abnormal" case, for EBCDIC systems */ static const unsigned char digitab[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 0 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 8- 15 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 10 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 32- 39 20 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 40- 47 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 48- 55 30 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 56- 63 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - 71 40 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 72- | */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* & - 87 50 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 88- 95 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - -103 60 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 104- ? */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 112-119 70 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 120- " */ 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, /* 128- g 80 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* h -143 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144- p 90 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* q -159 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160- x A0 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* y -175 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ^ -183 B0 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */ 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, /* { - G C0 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* H -207 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* } - P D0 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* Q -223 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* \ - X E0 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* Y -239 */ 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c, /* 0 - 7 F0 */ 0x0c,0x0c,0x00,0x00,0x00,0x00,0x00,0x00};/* 8 -255 */ static const unsigned char ebcdic_chartab[] = { /* chartable partial dup */ 0x80,0x00,0x00,0x00,0x00,0x01,0x00,0x00, /* 0- 7 */ 0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00, /* 8- 15 */ 0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00, /* 16- 23 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */ 0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00, /* 32- 39 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 40- 47 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 48- 55 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 56- 63 */ 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - 71 */ 0x00,0x00,0x00,0x80,0x00,0x80,0x80,0x80, /* 72- | */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* & - 87 */ 0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00, /* 88- 95 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - -103 */ 0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x80, /* 104- ? */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 112-119 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 120- " */ 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* 128- g */ 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* h -143 */ 0x00,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* 144- p */ 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* q -159 */ 0x00,0x00,0x12,0x12,0x12,0x12,0x12,0x12, /* 160- x */ 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* y -175 */ 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ^ -183 */ 0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00, /* 184-191 */ 0x80,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* { - G */ 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* H -207 */ 0x00,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* } - P */ 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* Q -223 */ 0x00,0x00,0x12,0x12,0x12,0x12,0x12,0x12, /* \ - X */ 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* Y -239 */ 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c, /* 0 - 7 */ 0x1c,0x1c,0x00,0x00,0x00,0x00,0x00,0x00};/* 8 -255 */ #endif /* Definition to allow mutual recursion */ static BOOL compile_regex(int, int, uschar **, const uschar **, int *, BOOL, BOOL, int, int *, int *, branch_chain *, compile_data *, int *); /************************************************* * Handle escapes * *************************************************/ /* This function is called when a \ has been encountered. It either returns a positive value for a simple escape such as \n, or a negative value which encodes one of the more complicated things such as \d. A backreference to group n is returned as -(ESC_REF + n); ESC_REF is the highest ESC_xxx macro. When UTF-8 is enabled, a positive value greater than 255 may be returned. On entry, ptr is pointing at the \. On exit, it is on the final character of the escape sequence. Arguments: ptrptr points to the pattern position pointer errorcodeptr points to the errorcode variable bracount number of previous extracting brackets options the options bits isclass TRUE if inside a character class Returns: zero or positive => a data character negative => a special escape sequence on error, errorcodeptr is set */ static int check_escape(const uschar **ptrptr, int *errorcodeptr, int bracount, int options, BOOL isclass) { BOOL utf8 = (options & PCRE_UTF8) != 0; const uschar *ptr = *ptrptr + 1; int c, i; GETCHARINCTEST(c, ptr); /* Get character value, increment pointer */ ptr--; /* Set pointer back to the last byte */ /* If backslash is at the end of the pattern, it's an error. */ if (c == 0) *errorcodeptr = ERR1; /* Non-alphamerics are literals. For digits or letters, do an initial lookup in a table. A non-zero result is something that can be returned immediately. Otherwise further processing may be required. */ #ifndef EBCDIC /* ASCII coding */ else if (c < '0' || c > 'z') {} /* Not alphameric */ else if ((i = escapes[c - '0']) != 0) c = i; #else /* EBCDIC coding */ else if (c < 'a' || (ebcdic_chartab[c] & 0x0E) == 0) {} /* Not alphameric */ else if ((i = escapes[c - 0x48]) != 0) c = i; #endif /* Escapes that need further processing, or are illegal. */ else { const uschar *oldptr; BOOL braced, negated; switch (c) { /* A number of Perl escapes are not handled by PCRE. We give an explicit error. */ case 'l': case 'L': case 'N': case 'u': case 'U': *errorcodeptr = ERR37; break; /* \g must be followed by a number, either plain or braced. If positive, it is an absolute backreference. If negative, it is a relative backreference. This is a Perl 5.10 feature. Perl 5.10 also supports \g{name} as a reference to a named group. This is part of Perl's movement towards a unified syntax for back references. As this is synonymous with \k{name}, we fudge it up by pretending it really was \k. */ case 'g': if (ptr[1] == '{') { const uschar *p; for (p = ptr+2; *p != 0 && *p != '}'; p++) if (*p != '-' && (digitab[*p] & ctype_digit) == 0) break; if (*p != 0 && *p != '}') { c = -ESC_k; break; } braced = TRUE; ptr++; } else braced = FALSE; if (ptr[1] == '-') { negated = TRUE; ptr++; } else negated = FALSE; c = 0; while ((digitab[ptr[1]] & ctype_digit) != 0) c = c * 10 + *(++ptr) - '0'; if (c < 0) { *errorcodeptr = ERR61; break; } if (c == 0 || (braced && *(++ptr) != '}')) { *errorcodeptr = ERR57; break; } if (negated) { if (c > bracount) { *errorcodeptr = ERR15; break; } c = bracount - (c - 1); } c = -(ESC_REF + c); break; /* The handling of escape sequences consisting of a string of digits starting with one that is not zero is not straightforward. By experiment, the way Perl works seems to be as follows: Outside a character class, the digits are read as a decimal number. If the number is less than 10, or if there are that many previous extracting left brackets, then it is a back reference. Otherwise, up to three octal digits are read to form an escaped byte. Thus \123 is likely to be octal 123 (cf \0123, which is octal 012 followed by the literal 3). If the octal value is greater than 377, the least significant 8 bits are taken. Inside a character class, \ followed by a digit is always an octal number. */ case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (!isclass) { oldptr = ptr; c -= '0'; while ((digitab[ptr[1]] & ctype_digit) != 0) c = c * 10 + *(++ptr) - '0'; if (c < 0) { *errorcodeptr = ERR61; break; } if (c < 10 || c <= bracount) { c = -(ESC_REF + c); break; } ptr = oldptr; /* Put the pointer back and fall through */ } /* Handle an octal number following \. If the first digit is 8 or 9, Perl generates a binary zero byte and treats the digit as a following literal. Thus we have to pull back the pointer by one. */ if ((c = *ptr) >= '8') { ptr--; c = 0; break; } /* \0 always starts an octal number, but we may drop through to here with a larger first octal digit. The original code used just to take the least significant 8 bits of octal numbers (I think this is what early Perls used to do). Nowadays we allow for larger numbers in UTF-8 mode, but no more than 3 octal digits. */ case '0': c -= '0'; while(i++ < 2 && ptr[1] >= '0' && ptr[1] <= '7') c = c * 8 + *(++ptr) - '0'; if (!utf8 && c > 255) *errorcodeptr = ERR51; break; /* \x is complicated. \x{ddd} is a character number which can be greater than 0xff in utf8 mode, but only if the ddd are hex digits. If not, { is treated as a data character. */ case 'x': if (ptr[1] == '{') { const uschar *pt = ptr + 2; int count = 0; c = 0; while ((digitab[*pt] & ctype_xdigit) != 0) { register int cc = *pt++; if (c == 0 && cc == '0') continue; /* Leading zeroes */ count++; #ifndef EBCDIC /* ASCII coding */ if (cc >= 'a') cc -= 32; /* Convert to upper case */ c = (c << 4) + cc - ((cc < 'A')? '0' : ('A' - 10)); #else /* EBCDIC coding */ if (cc >= 'a' && cc <= 'z') cc += 64; /* Convert to upper case */ c = (c << 4) + cc - ((cc >= '0')? '0' : ('A' - 10)); #endif } if (*pt == '}') { if (c < 0 || count > (utf8? 8 : 2)) *errorcodeptr = ERR34; ptr = pt; break; } /* If the sequence of hex digits does not end with '}', then we don't recognize this construct; fall through to the normal \x handling. */ } /* Read just a single-byte hex-defined char */ c = 0; while (i++ < 2 && (digitab[ptr[1]] & ctype_xdigit) != 0) { int cc; /* Some compilers don't like ++ */ cc = *(++ptr); /* in initializers */ #ifndef EBCDIC /* ASCII coding */ if (cc >= 'a') cc -= 32; /* Convert to upper case */ c = c * 16 + cc - ((cc < 'A')? '0' : ('A' - 10)); #else /* EBCDIC coding */ if (cc <= 'z') cc += 64; /* Convert to upper case */ c = c * 16 + cc - ((cc >= '0')? '0' : ('A' - 10)); #endif } break; /* For \c, a following letter is upper-cased; then the 0x40 bit is flipped. This coding is ASCII-specific, but then the whole concept of \cx is ASCII-specific. (However, an EBCDIC equivalent has now been added.) */ case 'c': c = *(++ptr); if (c == 0) { *errorcodeptr = ERR2; break; } #ifndef EBCDIC /* ASCII coding */ if (c >= 'a' && c <= 'z') c -= 32; c ^= 0x40; #else /* EBCDIC coding */ if (c >= 'a' && c <= 'z') c += 64; c ^= 0xC0; #endif break; /* PCRE_EXTRA enables extensions to Perl in the matter of escapes. Any other alphameric following \ is an error if PCRE_EXTRA was set; otherwise, for Perl compatibility, it is a literal. This code looks a bit odd, but there used to be some cases other than the default, and there may be again in future, so I haven't "optimized" it. */ default: if ((options & PCRE_EXTRA) != 0) switch(c) { default: *errorcodeptr = ERR3; break; } break; } } *ptrptr = ptr; return c; } #ifdef SUPPORT_UCP /************************************************* * Handle \P and \p * *************************************************/ /* This function is called after \P or \p has been encountered, provided that PCRE is compiled with support for Unicode properties. On entry, ptrptr is pointing at the P or p. On exit, it is pointing at the final character of the escape sequence. Argument: ptrptr points to the pattern position pointer negptr points to a boolean that is set TRUE for negation else FALSE dptr points to an int that is set to the detailed property value errorcodeptr points to the error code variable Returns: type value from ucp_type_table, or -1 for an invalid type */ static int get_ucp(const uschar **ptrptr, BOOL *negptr, int *dptr, int *errorcodeptr) { int c, i, bot, top; const uschar *ptr = *ptrptr; char name[32]; c = *(++ptr); if (c == 0) goto ERROR_RETURN; *negptr = FALSE; /* \P or \p can be followed by a name in {}, optionally preceded by ^ for negation. */ if (c == '{') { if (ptr[1] == '^') { *negptr = TRUE; ptr++; } for (i = 0; i < (int)sizeof(name) - 1; i++) { c = *(++ptr); if (c == 0) goto ERROR_RETURN; if (c == '}') break; name[i] = c; } if (c !='}') goto ERROR_RETURN; name[i] = 0; } /* Otherwise there is just one following character */ else { name[0] = c; name[1] = 0; } *ptrptr = ptr; /* Search for a recognized property name using binary chop */ bot = 0; top = _pcre_utt_size; while (bot < top) { i = (bot + top) >> 1; c = strcmp(name, _pcre_utt[i].name); if (c == 0) { *dptr = _pcre_utt[i].value; return _pcre_utt[i].type; } if (c > 0) bot = i + 1; else top = i; } *errorcodeptr = ERR47; *ptrptr = ptr; return -1; ERROR_RETURN: *errorcodeptr = ERR46; *ptrptr = ptr; return -1; } #endif /************************************************* * Check for counted repeat * *************************************************/ /* This function is called when a '{' is encountered in a place where it might start a quantifier. It looks ahead to see if it really is a quantifier or not. It is only a quantifier if it is one of the forms {ddd} {ddd,} or {ddd,ddd} where the ddds are digits. Arguments: p pointer to the first char after '{' Returns: TRUE or FALSE */ static BOOL is_counted_repeat(const uschar *p) { if ((digitab[*p++] & ctype_digit) == 0) return FALSE; while ((digitab[*p] & ctype_digit) != 0) p++; if (*p == '}') return TRUE; if (*p++ != ',') return FALSE; if (*p == '}') return TRUE; if ((digitab[*p++] & ctype_digit) == 0) return FALSE; while ((digitab[*p] & ctype_digit) != 0) p++; return (*p == '}'); } /************************************************* * Read repeat counts * *************************************************/ /* Read an item of the form {n,m} and return the values. This is called only after is_counted_repeat() has confirmed that a repeat-count quantifier exists, so the syntax is guaranteed to be correct, but we need to check the values. Arguments: p pointer to first char after '{' minp pointer to int for min maxp pointer to int for max returned as -1 if no max errorcodeptr points to error code variable Returns: pointer to '}' on success; current ptr on error, with errorcodeptr set non-zero */ static const uschar * read_repeat_counts(const uschar *p, int *minp, int *maxp, int *errorcodeptr) { int min = 0; int max = -1; /* Read the minimum value and do a paranoid check: a negative value indicates an integer overflow. */ while ((digitab[*p] & ctype_digit) != 0) min = min * 10 + *p++ - '0'; if (min < 0 || min > 65535) { *errorcodeptr = ERR5; return p; } /* Read the maximum value if there is one, and again do a paranoid on its size. Also, max must not be less than min. */ if (*p == '}') max = min; else { if (*(++p) != '}') { max = 0; while((digitab[*p] & ctype_digit) != 0) max = max * 10 + *p++ - '0'; if (max < 0 || max > 65535) { *errorcodeptr = ERR5; return p; } if (max < min) { *errorcodeptr = ERR4; return p; } } } /* Fill in the required variables, and pass back the pointer to the terminating '}'. */ *minp = min; *maxp = max; return p; } /************************************************* * Find forward referenced subpattern * *************************************************/ /* This function scans along a pattern's text looking for capturing subpatterns, and counting them. If it finds a named pattern that matches the name it is given, it returns its number. Alternatively, if the name is NULL, it returns when it reaches a given numbered subpattern. This is used for forward references to subpatterns. We know that if (?P< is encountered, the name will be terminated by '>' because that is checked in the first pass. Arguments: ptr current position in the pattern count current count of capturing parens so far encountered name name to seek, or NULL if seeking a numbered subpattern lorn name length, or subpattern number if name is NULL xmode TRUE if we are in /x mode Returns: the number of the named subpattern, or -1 if not found */ static int find_parens(const uschar *ptr, int count, const uschar *name, int lorn, BOOL xmode) { const uschar *thisname; for (; *ptr != 0; ptr++) { int term; /* Skip over backslashed characters and also entire \Q...\E */ if (*ptr == '\\') { if (*(++ptr) == 0) return -1; if (*ptr == 'Q') for (;;) { while (*(++ptr) != 0 && *ptr != '\\'); if (*ptr == 0) return -1; if (*(++ptr) == 'E') break; } continue; } /* Skip over character classes */ if (*ptr == '[') { while (*(++ptr) != ']') { if (*ptr == 0) return -1; if (*ptr == '\\') { if (*(++ptr) == 0) return -1; if (*ptr == 'Q') for (;;) { while (*(++ptr) != 0 && *ptr != '\\'); if (*ptr == 0) return -1; if (*(++ptr) == 'E') break; } continue; } } continue; } /* Skip comments in /x mode */ if (xmode && *ptr == '#') { while (*(++ptr) != 0 && *ptr != '\n'); if (*ptr == 0) return -1; continue; } /* An opening parens must now be a real metacharacter */ if (*ptr != '(') continue; if (ptr[1] != '?' && ptr[1] != '*') { count++; if (name == NULL && count == lorn) return count; continue; } ptr += 2; if (*ptr == 'P') ptr++; /* Allow optional P */ /* We have to disambiguate (? */ if ((*ptr != '<' || ptr[1] == '!' || ptr[1] == '=') && *ptr != '\'') continue; count++; if (name == NULL && count == lorn) return count; term = *ptr++; if (term == '<') term = '>'; thisname = ptr; while (*ptr != term) ptr++; if (name != NULL && lorn == ptr - thisname && strncmp((const char *)name, (const char *)thisname, lorn) == 0) return count; } return -1; } /************************************************* * Find first significant op code * *************************************************/ /* This is called by several functions that scan a compiled expression looking for a fixed first character, or an anchoring op code etc. It skips over things that do not influence this. For some calls, a change of option is important. For some calls, it makes sense to skip negative forward and all backward assertions, and also the \b assertion; for others it does not. Arguments: code pointer to the start of the group options pointer to external options optbit the option bit whose changing is significant, or zero if none are skipassert TRUE if certain assertions are to be skipped Returns: pointer to the first significant opcode */ static const uschar* first_significant_code(const uschar *code, int *options, int optbit, BOOL skipassert) { for (;;) { switch ((int)*code) { case OP_OPT: if (optbit > 0 && ((int)code[1] & optbit) != (*options & optbit)) *options = (int)code[1]; code += 2; break; case OP_ASSERT_NOT: case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: if (!skipassert) return code; do code += GET(code, 1); while (*code == OP_ALT); code += _pcre_OP_lengths[*code]; break; case OP_WORD_BOUNDARY: case OP_NOT_WORD_BOUNDARY: if (!skipassert) return code; /* Fall through */ case OP_CALLOUT: case OP_CREF: case OP_RREF: case OP_DEF: code += _pcre_OP_lengths[*code]; break; default: return code; } } /* Control never reaches here */ } /************************************************* * Find the fixed length of a pattern * *************************************************/ /* Scan a pattern and compute the fixed length of subject that will match it, if the length is fixed. This is needed for dealing with backward assertions. In UTF8 mode, the result is in characters rather than bytes. Arguments: code points to the start of the pattern (the bracket) options the compiling options Returns: the fixed length, or -1 if there is no fixed length, or -2 if \C was encountered */ static int find_fixedlength(uschar *code, int options) { int length = -1; register int branchlength = 0; register uschar *cc = code + 1 + LINK_SIZE; /* Scan along the opcodes for this branch. If we get to the end of the branch, check the length against that of the other branches. */ for (;;) { int d; register int op = *cc; switch (op) { case OP_CBRA: case OP_BRA: case OP_ONCE: case OP_COND: d = find_fixedlength(cc + ((op == OP_CBRA)? 2:0), options); if (d < 0) return d; branchlength += d; do cc += GET(cc, 1); while (*cc == OP_ALT); cc += 1 + LINK_SIZE; break; /* Reached end of a branch; if it's a ket it is the end of a nested call. If it's ALT it is an alternation in a nested call. If it is END it's the end of the outer call. All can be handled by the same code. */ case OP_ALT: case OP_KET: case OP_KETRMAX: case OP_KETRMIN: case OP_END: if (length < 0) length = branchlength; else if (length != branchlength) return -1; if (*cc != OP_ALT) return length; cc += 1 + LINK_SIZE; branchlength = 0; break; /* Skip over assertive subpatterns */ case OP_ASSERT: case OP_ASSERT_NOT: case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: do cc += GET(cc, 1); while (*cc == OP_ALT); /* Fall through */ /* Skip over things that don't match chars */ case OP_REVERSE: case OP_CREF: case OP_RREF: case OP_DEF: case OP_OPT: case OP_CALLOUT: case OP_SOD: case OP_SOM: case OP_EOD: case OP_EODN: case OP_CIRC: case OP_DOLL: case OP_NOT_WORD_BOUNDARY: case OP_WORD_BOUNDARY: cc += _pcre_OP_lengths[*cc]; break; /* Handle literal characters */ case OP_CHAR: case OP_CHARNC: case OP_NOT: branchlength++; cc += 2; #ifdef SUPPORT_UTF8 if ((options & PCRE_UTF8) != 0) { while ((*cc & 0xc0) == 0x80) cc++; } #endif break; /* Handle exact repetitions. The count is already in characters, but we need to skip over a multibyte character in UTF8 mode. */ case OP_EXACT: branchlength += GET2(cc,1); cc += 4; #ifdef SUPPORT_UTF8 if ((options & PCRE_UTF8) != 0) { while((*cc & 0x80) == 0x80) cc++; } #endif break; case OP_TYPEEXACT: branchlength += GET2(cc,1); if (cc[3] == OP_PROP || cc[3] == OP_NOTPROP) cc += 2; cc += 4; break; /* Handle single-char matchers */ case OP_PROP: case OP_NOTPROP: cc += 2; /* Fall through */ case OP_NOT_DIGIT: case OP_DIGIT: case OP_NOT_WHITESPACE: case OP_WHITESPACE: case OP_NOT_WORDCHAR: case OP_WORDCHAR: case OP_ANY: branchlength++; cc++; break; /* The single-byte matcher isn't allowed */ case OP_ANYBYTE: return -2; /* Check a class for variable quantification */ #ifdef SUPPORT_UTF8 case OP_XCLASS: cc += GET(cc, 1) - 33; /* Fall through */ #endif case OP_CLASS: case OP_NCLASS: cc += 33; switch (*cc) { case OP_CRSTAR: case OP_CRMINSTAR: case OP_CRQUERY: case OP_CRMINQUERY: return -1; case OP_CRRANGE: case OP_CRMINRANGE: if (GET2(cc,1) != GET2(cc,3)) return -1; branchlength += GET2(cc,1); cc += 5; break; default: branchlength++; } break; /* Anything else is variable length */ default: return -1; } } /* Control never gets here */ } /************************************************* * Scan compiled regex for numbered bracket * *************************************************/ /* This little function scans through a compiled pattern until it finds a capturing bracket with the given number. Arguments: code points to start of expression utf8 TRUE in UTF-8 mode number the required bracket number Returns: pointer to the opcode for the bracket, or NULL if not found */ static const uschar * find_bracket(const uschar *code, BOOL utf8, int number) { for (;;) { register int c = *code; if (c == OP_END) return NULL; /* XCLASS is used for classes that cannot be represented just by a bit map. This includes negated single high-valued characters. The length in the table is zero; the actual length is stored in the compiled code. */ if (c == OP_XCLASS) code += GET(code, 1); /* Handle capturing bracket */ else if (c == OP_CBRA) { int n = GET2(code, 1+LINK_SIZE); if (n == number) return (uschar *)code; code += _pcre_OP_lengths[c]; } /* Otherwise, we can get the item's length from the table, except that for repeated character types, we have to test for \p and \P, which have an extra two bytes of parameters. */ else { switch(c) { case OP_TYPESTAR: case OP_TYPEMINSTAR: case OP_TYPEPLUS: case OP_TYPEMINPLUS: case OP_TYPEQUERY: case OP_TYPEMINQUERY: case OP_TYPEPOSSTAR: case OP_TYPEPOSPLUS: case OP_TYPEPOSQUERY: if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2; break; case OP_TYPEUPTO: case OP_TYPEMINUPTO: case OP_TYPEEXACT: case OP_TYPEPOSUPTO: if (code[3] == OP_PROP || code[3] == OP_NOTPROP) code += 2; break; } /* Add in the fixed length from the table */ code += _pcre_OP_lengths[c]; /* In UTF-8 mode, opcodes that are followed by a character may be followed by a multi-byte character. The length in the table is a minimum, so we have to arrange to skip the extra bytes. */ #ifdef SUPPORT_UTF8 if (utf8) switch(c) { case OP_CHAR: case OP_CHARNC: case OP_EXACT: case OP_UPTO: case OP_MINUPTO: case OP_POSUPTO: case OP_STAR: case OP_MINSTAR: case OP_POSSTAR: case OP_PLUS: case OP_MINPLUS: case OP_POSPLUS: case OP_QUERY: case OP_MINQUERY: case OP_POSQUERY: if (code[-1] >= 0xc0) code += _pcre_utf8_table4[code[-1] & 0x3f]; break; } #endif } } } /************************************************* * Scan compiled regex for recursion reference * *************************************************/ /* This little function scans through a compiled pattern until it finds an instance of OP_RECURSE. Arguments: code points to start of expression utf8 TRUE in UTF-8 mode Returns: pointer to the opcode for OP_RECURSE, or NULL if not found */ static const uschar * find_recurse(const uschar *code, BOOL utf8) { for (;;) { register int c = *code; if (c == OP_END) return NULL; if (c == OP_RECURSE) return code; /* XCLASS is used for classes that cannot be represented just by a bit map. This includes negated single high-valued characters. The length in the table is zero; the actual length is stored in the compiled code. */ if (c == OP_XCLASS) code += GET(code, 1); /* Otherwise, we can get the item's length from the table, except that for repeated character types, we have to test for \p and \P, which have an extra two bytes of parameters. */ else { switch(c) { case OP_TYPESTAR: case OP_TYPEMINSTAR: case OP_TYPEPLUS: case OP_TYPEMINPLUS: case OP_TYPEQUERY: case OP_TYPEMINQUERY: case OP_TYPEPOSSTAR: case OP_TYPEPOSPLUS: case OP_TYPEPOSQUERY: if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2; break; case OP_TYPEPOSUPTO: case OP_TYPEUPTO: case OP_TYPEMINUPTO: case OP_TYPEEXACT: if (code[3] == OP_PROP || code[3] == OP_NOTPROP) code += 2; break; } /* Add in the fixed length from the table */ code += _pcre_OP_lengths[c]; /* In UTF-8 mode, opcodes that are followed by a character may be followed by a multi-byte character. The length in the table is a minimum, so we have to arrange to skip the extra bytes. */ #ifdef SUPPORT_UTF8 if (utf8) switch(c) { case OP_CHAR: case OP_CHARNC: case OP_EXACT: case OP_UPTO: case OP_MINUPTO: case OP_POSUPTO: case OP_STAR: case OP_MINSTAR: case OP_POSSTAR: case OP_PLUS: case OP_MINPLUS: case OP_POSPLUS: case OP_QUERY: case OP_MINQUERY: case OP_POSQUERY: if (code[-1] >= 0xc0) code += _pcre_utf8_table4[code[-1] & 0x3f]; break; } #endif } } } /************************************************* * Scan compiled branch for non-emptiness * *************************************************/ /* This function scans through a branch of a compiled pattern to see whether it can match the empty string or not. It is called from could_be_empty() below and from compile_branch() when checking for an unlimited repeat of a group that can match nothing. Note that first_significant_code() skips over assertions. If we hit an unclosed bracket, we return "empty" - this means we've struck an inner bracket whose current branch will already have been scanned. Arguments: code points to start of search endcode points to where to stop utf8 TRUE if in UTF8 mode Returns: TRUE if what is matched could be empty */ static BOOL could_be_empty_branch(const uschar *code, const uschar *endcode, BOOL utf8) { register int c; for (code = first_significant_code(code + _pcre_OP_lengths[*code], NULL, 0, TRUE); code < endcode; code = first_significant_code(code + _pcre_OP_lengths[c], NULL, 0, TRUE)) { const uschar *ccode; c = *code; /* Groups with zero repeats can of course be empty; skip them. */ if (c == OP_BRAZERO || c == OP_BRAMINZERO) { code += _pcre_OP_lengths[c]; do code += GET(code, 1); while (*code == OP_ALT); c = *code; continue; } /* For other groups, scan the branches. */ if (c == OP_BRA || c == OP_CBRA || c == OP_ONCE || c == OP_COND) { BOOL empty_branch; if (GET(code, 1) == 0) return TRUE; /* Hit unclosed bracket */ /* Scan a closed bracket */ empty_branch = FALSE; do { if (!empty_branch && could_be_empty_branch(code, endcode, utf8)) empty_branch = TRUE; code += GET(code, 1); } while (*code == OP_ALT); if (!empty_branch) return FALSE; /* All branches are non-empty */ c = *code; continue; } /* Handle the other opcodes */ switch (c) { /* Check for quantifiers after a class. XCLASS is used for classes that cannot be represented just by a bit map. This includes negated single high-valued characters. The length in _pcre_OP_lengths[] is zero; the actual length is stored in the compiled code, so we must update "code" here. */ #ifdef SUPPORT_UTF8 case OP_XCLASS: ccode = code += GET(code, 1); goto CHECK_CLASS_REPEAT; #endif case OP_CLASS: case OP_NCLASS: ccode = code + 33; #ifdef SUPPORT_UTF8 CHECK_CLASS_REPEAT: #endif switch (*ccode) { case OP_CRSTAR: /* These could be empty; continue */ case OP_CRMINSTAR: case OP_CRQUERY: case OP_CRMINQUERY: break; default: /* Non-repeat => class must match */ case OP_CRPLUS: /* These repeats aren't empty */ case OP_CRMINPLUS: return FALSE; case OP_CRRANGE: case OP_CRMINRANGE: if (GET2(ccode, 1) > 0) return FALSE; /* Minimum > 0 */ break; } break; /* Opcodes that must match a character */ case OP_PROP: case OP_NOTPROP: case OP_EXTUNI: case OP_NOT_DIGIT: case OP_DIGIT: case OP_NOT_WHITESPACE: case OP_WHITESPACE: case OP_NOT_WORDCHAR: case OP_WORDCHAR: case OP_ANY: case OP_ANYBYTE: case OP_CHAR: case OP_CHARNC: case OP_NOT: case OP_PLUS: case OP_MINPLUS: case OP_POSPLUS: case OP_EXACT: case OP_NOTPLUS: case OP_NOTMINPLUS: case OP_NOTPOSPLUS: case OP_NOTEXACT: case OP_TYPEPLUS: case OP_TYPEMINPLUS: case OP_TYPEPOSPLUS: case OP_TYPEEXACT: return FALSE; /* These are going to continue, as they may be empty, but we have to fudge the length for the \p and \P cases. */ case OP_TYPESTAR: case OP_TYPEMINSTAR: case OP_TYPEPOSSTAR: case OP_TYPEQUERY: case OP_TYPEMINQUERY: case OP_TYPEPOSQUERY: if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2; break; /* Same for these */ case OP_TYPEUPTO: case OP_TYPEMINUPTO: case OP_TYPEPOSUPTO: if (code[3] == OP_PROP || code[3] == OP_NOTPROP) code += 2; break; /* End of branch */ case OP_KET: case OP_KETRMAX: case OP_KETRMIN: case OP_ALT: return TRUE; /* In UTF-8 mode, STAR, MINSTAR, POSSTAR, QUERY, MINQUERY, POSQUERY, UPTO, MINUPTO, and POSUPTO may be followed by a multibyte character */ #ifdef SUPPORT_UTF8 case OP_STAR: case OP_MINSTAR: case OP_POSSTAR: case OP_QUERY: case OP_MINQUERY: case OP_POSQUERY: case OP_UPTO: case OP_MINUPTO: case OP_POSUPTO: if (utf8) while ((code[2] & 0xc0) == 0x80) code++; break; #endif } } return TRUE; } /************************************************* * Scan compiled regex for non-emptiness * *************************************************/ /* This function is called to check for left recursive calls. We want to check the current branch of the current pattern to see if it could match the empty string. If it could, we must look outwards for branches at other levels, stopping when we pass beyond the bracket which is the subject of the recursion. Arguments: code points to start of the recursion endcode points to where to stop (current RECURSE item) bcptr points to the chain of current (unclosed) branch starts utf8 TRUE if in UTF-8 mode Returns: TRUE if what is matched could be empty */ static BOOL could_be_empty(const uschar *code, const uschar *endcode, branch_chain *bcptr, BOOL utf8) { while (bcptr != NULL && bcptr->current >= code) { if (!could_be_empty_branch(bcptr->current, endcode, utf8)) return FALSE; bcptr = bcptr->outer; } return TRUE; } /************************************************* * Check for POSIX class syntax * *************************************************/ /* This function is called when the sequence "[:" or "[." or "[=" is encountered in a character class. It checks whether this is followed by an optional ^ and then a sequence of letters, terminated by a matching ":]" or ".]" or "=]". Argument: ptr pointer to the initial [ endptr where to return the end pointer cd pointer to compile data Returns: TRUE or FALSE */ static BOOL check_posix_syntax(const uschar *ptr, const uschar **endptr, compile_data *cd) { int terminator; /* Don't combine these lines; the Solaris cc */ terminator = *(++ptr); /* compiler warns about "non-constant" initializer. */ if (*(++ptr) == '^') ptr++; while ((cd->ctypes[*ptr] & ctype_letter) != 0) ptr++; if (*ptr == terminator && ptr[1] == ']') { *endptr = ptr; return TRUE; } return FALSE; } /************************************************* * Check POSIX class name * *************************************************/ /* This function is called to check the name given in a POSIX-style class entry such as [:alnum:]. Arguments: ptr points to the first letter len the length of the name Returns: a value representing the name, or -1 if unknown */ static int check_posix_name(const uschar *ptr, int len) { register int yield = 0; while (posix_name_lengths[yield] != 0) { if (len == posix_name_lengths[yield] && strncmp((const char *)ptr, posix_names[yield], len) == 0) return yield; yield++; } return -1; } /************************************************* * Adjust OP_RECURSE items in repeated group * *************************************************/ /* OP_RECURSE items contain an offset from the start of the regex to the group that is referenced. This means that groups can be replicated for fixed repetition simply by copying (because the recursion is allowed to refer to earlier groups that are outside the current group). However, when a group is optional (i.e. the minimum quantifier is zero), OP_BRAZERO is inserted before it, after it has been compiled. This means that any OP_RECURSE items within it that refer to the group itself or any contained groups have to have their offsets adjusted. That one of the jobs of this function. Before it is called, the partially compiled regex must be temporarily terminated with OP_END. This function has been extended with the possibility of forward references for recursions and subroutine calls. It must also check the list of such references for the group we are dealing with. If it finds that one of the recursions in the current group is on this list, it adjusts the offset in the list, not the value in the reference (which is a group number). Arguments: group points to the start of the group adjust the amount by which the group is to be moved utf8 TRUE in UTF-8 mode cd contains pointers to tables etc. save_hwm the hwm forward reference pointer at the start of the group Returns: nothing */ static void adjust_recurse(uschar *group, int adjust, BOOL utf8, compile_data *cd, uschar *save_hwm) { uschar *ptr = group; while ((ptr = (uschar *)find_recurse(ptr, utf8)) != NULL) { int offset; uschar *hc; /* See if this recursion is on the forward reference list. If so, adjust the reference. */ for (hc = save_hwm; hc < cd->hwm; hc += LINK_SIZE) { offset = GET(hc, 0); if (cd->start_code + offset == ptr + 1) { PUT(hc, 0, offset + adjust); break; } } /* Otherwise, adjust the recursion offset if it's after the start of this group. */ if (hc >= cd->hwm) { offset = GET(ptr, 1); if (cd->start_code + offset >= group) PUT(ptr, 1, offset + adjust); } ptr += 1 + LINK_SIZE; } } /************************************************* * Insert an automatic callout point * *************************************************/ /* This function is called when the PCRE_AUTO_CALLOUT option is set, to insert callout points before each pattern item. Arguments: code current code pointer ptr current pattern pointer cd pointers to tables etc Returns: new code pointer */ static uschar * auto_callout(uschar *code, const uschar *ptr, compile_data *cd) { *code++ = OP_CALLOUT; *code++ = 255; PUT(code, 0, ptr - cd->start_pattern); /* Pattern offset */ PUT(code, LINK_SIZE, 0); /* Default length */ return code + 2*LINK_SIZE; } /************************************************* * Complete a callout item * *************************************************/ /* A callout item contains the length of the next item in the pattern, which we can't fill in till after we have reached the relevant point. This is used for both automatic and manual callouts. Arguments: previous_callout points to previous callout item ptr current pattern pointer cd pointers to tables etc Returns: nothing */ static void complete_callout(uschar *previous_callout, const uschar *ptr, compile_data *cd) { int length = ptr - cd->start_pattern - GET(previous_callout, 2); PUT(previous_callout, 2 + LINK_SIZE, length); } #ifdef SUPPORT_UCP /************************************************* * Get othercase range * *************************************************/ /* This function is passed the start and end of a class range, in UTF-8 mode with UCP support. It searches up the characters, looking for internal ranges of characters in the "other" case. Each call returns the next one, updating the start address. Arguments: cptr points to starting character value; updated d end value ocptr where to put start of othercase range odptr where to put end of othercase range Yield: TRUE when range returned; FALSE when no more */ static BOOL get_othercase_range(unsigned int *cptr, unsigned int d, unsigned int *ocptr, unsigned int *odptr) { unsigned int c, othercase, next; for (c = *cptr; c <= d; c++) { if ((othercase = _pcre_ucp_othercase(c)) != NOTACHAR) break; } if (c > d) return FALSE; *ocptr = othercase; next = othercase + 1; for (++c; c <= d; c++) { if (_pcre_ucp_othercase(c) != next) break; next++; } *odptr = next - 1; *cptr = c; return TRUE; } #endif /* SUPPORT_UCP */ /************************************************* * Check if auto-possessifying is possible * *************************************************/ /* This function is called for unlimited repeats of certain items, to see whether the next thing could possibly match the repeated item. If not, it makes sense to automatically possessify the repeated item. Arguments: op_code the repeated op code this data for this item, depends on the opcode utf8 TRUE in UTF-8 mode utf8_char used for utf8 character bytes, NULL if not relevant ptr next character in pattern options options bits cd contains pointers to tables etc. Returns: TRUE if possessifying is wanted */ static BOOL check_auto_possessive(int op_code, int item, BOOL utf8, uschar *utf8_char, const uschar *ptr, int options, compile_data *cd) { int next; /* Skip whitespace and comments in extended mode */ if ((options & PCRE_EXTENDED) != 0) { for (;;) { while ((cd->ctypes[*ptr] & ctype_space) != 0) ptr++; if (*ptr == '#') { while (*(++ptr) != 0) if (IS_NEWLINE(ptr)) { ptr += cd->nllen; break; } } else break; } } /* If the next item is one that we can handle, get its value. A non-negative value is a character, a negative value is an escape value. */ if (*ptr == '\\') { int temperrorcode = 0; next = check_escape(&ptr, &temperrorcode, cd->bracount, options, FALSE); if (temperrorcode != 0) return FALSE; ptr++; /* Point after the escape sequence */ } else if ((cd->ctypes[*ptr] & ctype_meta) == 0) { #ifdef SUPPORT_UTF8 if (utf8) { GETCHARINC(next, ptr); } else #endif next = *ptr++; } else return FALSE; /* Skip whitespace and comments in extended mode */ if ((options & PCRE_EXTENDED) != 0) { for (;;) { while ((cd->ctypes[*ptr] & ctype_space) != 0) ptr++; if (*ptr == '#') { while (*(++ptr) != 0) if (IS_NEWLINE(ptr)) { ptr += cd->nllen; break; } } else break; } } /* If the next thing is itself optional, we have to give up. */ if (*ptr == '*' || *ptr == '?' || strncmp((char *)ptr, "{0,", 3) == 0) return FALSE; /* Now compare the next item with the previous opcode. If the previous is a positive single character match, "item" either contains the character or, if "item" is greater than 127 in utf8 mode, the character's bytes are in utf8_char. */ /* Handle cases when the next item is a character. */ if (next >= 0) switch(op_code) { case OP_CHAR: #ifdef SUPPORT_UTF8 if (utf8 && item > 127) { GETCHAR(item, utf8_char); } #endif return item != next; /* For CHARNC (caseless character) we must check the other case. If we have Unicode property support, we can use it to test the other case of high-valued characters. */ case OP_CHARNC: #ifdef SUPPORT_UTF8 if (utf8 && item > 127) { GETCHAR(item, utf8_char); } #endif if (item == next) return FALSE; #ifdef SUPPORT_UTF8 if (utf8) { unsigned int othercase; if (next < 128) othercase = cd->fcc[next]; else #ifdef SUPPORT_UCP othercase = _pcre_ucp_othercase((unsigned int)next); #else othercase = NOTACHAR; #endif return (unsigned int)item != othercase; } else #endif /* SUPPORT_UTF8 */ return (item != cd->fcc[next]); /* Non-UTF-8 mode */ /* For OP_NOT, "item" must be a single-byte character. */ case OP_NOT: if (next < 0) return FALSE; /* Not a character */ if (item == next) return TRUE; if ((options & PCRE_CASELESS) == 0) return FALSE; #ifdef SUPPORT_UTF8 if (utf8) { unsigned int othercase; if (next < 128) othercase = cd->fcc[next]; else #ifdef SUPPORT_UCP othercase = _pcre_ucp_othercase(next); #else othercase = NOTACHAR; #endif return (unsigned int)item == othercase; } else #endif /* SUPPORT_UTF8 */ return (item == cd->fcc[next]); /* Non-UTF-8 mode */ case OP_DIGIT: return next > 127 || (cd->ctypes[next] & ctype_digit) == 0; case OP_NOT_DIGIT: return next <= 127 && (cd->ctypes[next] & ctype_digit) != 0; case OP_WHITESPACE: return next > 127 || (cd->ctypes[next] & ctype_space) == 0; case OP_NOT_WHITESPACE: return next <= 127 && (cd->ctypes[next] & ctype_space) != 0; case OP_WORDCHAR: return next > 127 || (cd->ctypes[next] & ctype_word) == 0; case OP_NOT_WORDCHAR: return next <= 127 && (cd->ctypes[next] & ctype_word) != 0; case OP_HSPACE: case OP_NOT_HSPACE: switch(next) { case 0x09: case 0x20: case 0xa0: case 0x1680: case 0x180e: case 0x2000: case 0x2001: case 0x2002: case 0x2003: case 0x2004: case 0x2005: case 0x2006: case 0x2007: case 0x2008: case 0x2009: case 0x200A: case 0x202f: case 0x205f: case 0x3000: return op_code != OP_HSPACE; default: return op_code == OP_HSPACE; } case OP_VSPACE: case OP_NOT_VSPACE: switch(next) { case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x85: case 0x2028: case 0x2029: return op_code != OP_VSPACE; default: return op_code == OP_VSPACE; } default: return FALSE; } /* Handle the case when the next item is \d, \s, etc. */ switch(op_code) { case OP_CHAR: case OP_CHARNC: #ifdef SUPPORT_UTF8 if (utf8 && item > 127) { GETCHAR(item, utf8_char); } #endif switch(-next) { case ESC_d: return item > 127 || (cd->ctypes[item] & ctype_digit) == 0; case ESC_D: return item <= 127 && (cd->ctypes[item] & ctype_digit) != 0; case ESC_s: return item > 127 || (cd->ctypes[item] & ctype_space) == 0; case ESC_S: return item <= 127 && (cd->ctypes[item] & ctype_space) != 0; case ESC_w: return item > 127 || (cd->ctypes[item] & ctype_word) == 0; case ESC_W: return item <= 127 && (cd->ctypes[item] & ctype_word) != 0; case ESC_h: case ESC_H: switch(item) { case 0x09: case 0x20: case 0xa0: case 0x1680: case 0x180e: case 0x2000: case 0x2001: case 0x2002: case 0x2003: case 0x2004: case 0x2005: case 0x2006: case 0x2007: case 0x2008: case 0x2009: case 0x200A: case 0x202f: case 0x205f: case 0x3000: return -next != ESC_h; default: return -next == ESC_h; } case ESC_v: case ESC_V: switch(item) { case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x85: case 0x2028: case 0x2029: return -next != ESC_v; default: return -next == ESC_v; } default: return FALSE; } case OP_DIGIT: return next == -ESC_D || next == -ESC_s || next == -ESC_W || next == -ESC_h || next == -ESC_v; case OP_NOT_DIGIT: return next == -ESC_d; case OP_WHITESPACE: return next == -ESC_S || next == -ESC_d || next == -ESC_w; case OP_NOT_WHITESPACE: return next == -ESC_s || next == -ESC_h || next == -ESC_v; case OP_HSPACE: return next == -ESC_S || next == -ESC_H || next == -ESC_d || next == -ESC_w; case OP_NOT_HSPACE: return next == -ESC_h; /* Can't have \S in here because VT matches \S (Perl anomaly) */ case OP_VSPACE: return next == -ESC_V || next == -ESC_d || next == -ESC_w; case OP_NOT_VSPACE: return next == -ESC_v; case OP_WORDCHAR: return next == -ESC_W || next == -ESC_s || next == -ESC_h || next == -ESC_v; case OP_NOT_WORDCHAR: return next == -ESC_w || next == -ESC_d; default: return FALSE; } /* Control does not reach here */ } /************************************************* * Compile one branch * *************************************************/ /* Scan the pattern, compiling it into the a vector. If the options are changed during the branch, the pointer is used to change the external options bits. This function is used during the pre-compile phase when we are trying to find out the amount of memory needed, as well as during the real compile phase. The value of lengthptr distinguishes the two phases. Arguments: optionsptr pointer to the option bits codeptr points to the pointer to the current code point ptrptr points to the current pattern pointer errorcodeptr points to error code variable firstbyteptr set to initial literal character, or < 0 (REQ_UNSET, REQ_NONE) reqbyteptr set to the last literal character required, else < 0 bcptr points to current branch chain cd contains pointers to tables etc. lengthptr NULL during the real compile phase points to length accumulator during pre-compile phase Returns: TRUE on success FALSE, with *errorcodeptr set non-zero on error */ static BOOL compile_branch(int *optionsptr, uschar **codeptr, const uschar **ptrptr, int *errorcodeptr, int *firstbyteptr, int *reqbyteptr, branch_chain *bcptr, compile_data *cd, int *lengthptr) { int repeat_type, op_type; int repeat_min = 0, repeat_max = 0; /* To please picky compilers */ int bravalue = 0; int greedy_default, greedy_non_default; int firstbyte, reqbyte; int zeroreqbyte, zerofirstbyte; int req_caseopt, reqvary, tempreqvary; int options = *optionsptr; int after_manual_callout = 0; int length_prevgroup = 0; register int c; register uschar *code = *codeptr; uschar *last_code = code; uschar *orig_code = code; uschar *tempcode; BOOL inescq = FALSE; BOOL groupsetfirstbyte = FALSE; const uschar *ptr = *ptrptr; const uschar *tempptr; uschar *previous = NULL; uschar *previous_callout = NULL; uschar *save_hwm = NULL; uschar classbits[32]; #ifdef SUPPORT_UTF8 BOOL class_utf8; BOOL utf8 = (options & PCRE_UTF8) != 0; uschar *class_utf8data; uschar utf8_char[6]; #else BOOL utf8 = FALSE; uschar *utf8_char = NULL; #endif #ifdef DEBUG if (lengthptr != NULL) DPRINTF((">> start branch\n")); #endif /* Set up the default and non-default settings for greediness */ greedy_default = ((options & PCRE_UNGREEDY) != 0); greedy_non_default = greedy_default ^ 1; /* Initialize no first byte, no required byte. REQ_UNSET means "no char matching encountered yet". It gets changed to REQ_NONE if we hit something that matches a non-fixed char first char; reqbyte just remains unset if we never find one. When we hit a repeat whose minimum is zero, we may have to adjust these values to take the zero repeat into account. This is implemented by setting them to zerofirstbyte and zeroreqbyte when such a repeat is encountered. The individual item types that can be repeated set these backoff variables appropriately. */ firstbyte = reqbyte = zerofirstbyte = zeroreqbyte = REQ_UNSET; /* The variable req_caseopt contains either the REQ_CASELESS value or zero, according to the current setting of the caseless flag. REQ_CASELESS is a bit value > 255. It is added into the firstbyte or reqbyte variables to record the case status of the value. This is used only for ASCII characters. */ req_caseopt = ((options & PCRE_CASELESS) != 0)? REQ_CASELESS : 0; /* Switch on next character until the end of the branch */ for (;; ptr++) { BOOL negate_class; BOOL possessive_quantifier; BOOL is_quantifier; BOOL is_recurse; BOOL reset_bracount; int class_charcount; int class_lastchar; int newoptions; int recno; int refsign; int skipbytes; int subreqbyte; int subfirstbyte; int terminator; int mclength; uschar mcbuffer[8]; /* Get next byte in the pattern */ c = *ptr; /* If we are in the pre-compile phase, accumulate the length used for the previous cycle of this loop. */ if (lengthptr != NULL) { #ifdef DEBUG if (code > cd->hwm) cd->hwm = code; /* High water info */ #endif if (code > cd->start_workspace + COMPILE_WORK_SIZE) /* Check for overrun */ { *errorcodeptr = ERR52; goto FAILED; } /* There is at least one situation where code goes backwards: this is the case of a zero quantifier after a class (e.g. [ab]{0}). At compile time, the class is simply eliminated. However, it is created first, so we have to allow memory for it. Therefore, don't ever reduce the length at this point. */ if (code < last_code) code = last_code; /* Paranoid check for integer overflow */ if (OFLOW_MAX - *lengthptr < code - last_code) { *errorcodeptr = ERR20; goto FAILED; } *lengthptr += code - last_code; DPRINTF(("length=%d added %d c=%c\n", *lengthptr, code - last_code, c)); /* If "previous" is set and it is not at the start of the work space, move it back to there, in order to avoid filling up the work space. Otherwise, if "previous" is NULL, reset the current code pointer to the start. */ if (previous != NULL) { if (previous > orig_code) { memmove(orig_code, previous, code - previous); code -= previous - orig_code; previous = orig_code; } } else code = orig_code; /* Remember where this code item starts so we can pick up the length next time round. */ last_code = code; } /* In the real compile phase, just check the workspace used by the forward reference list. */ else if (cd->hwm > cd->start_workspace + COMPILE_WORK_SIZE) { *errorcodeptr = ERR52; goto FAILED; } /* If in \Q...\E, check for the end; if not, we have a literal */ if (inescq && c != 0) { if (c == '\\' && ptr[1] == 'E') { inescq = FALSE; ptr++; continue; } else { if (previous_callout != NULL) { if (lengthptr == NULL) /* Don't attempt in pre-compile phase */ complete_callout(previous_callout, ptr, cd); previous_callout = NULL; } if ((options & PCRE_AUTO_CALLOUT) != 0) { previous_callout = code; code = auto_callout(code, ptr, cd); } goto NORMAL_CHAR; } } /* Fill in length of a previous callout, except when the next thing is a quantifier. */ is_quantifier = c == '*' || c == '+' || c == '?' || (c == '{' && is_counted_repeat(ptr+1)); if (!is_quantifier && previous_callout != NULL && after_manual_callout-- <= 0) { if (lengthptr == NULL) /* Don't attempt in pre-compile phase */ complete_callout(previous_callout, ptr, cd); previous_callout = NULL; } /* In extended mode, skip white space and comments */ if ((options & PCRE_EXTENDED) != 0) { if ((cd->ctypes[c] & ctype_space) != 0) continue; if (c == '#') { while (*(++ptr) != 0) { if (IS_NEWLINE(ptr)) { ptr += cd->nllen - 1; break; } } if (*ptr != 0) continue; /* Else fall through to handle end of string */ c = 0; } } /* No auto callout for quantifiers. */ if ((options & PCRE_AUTO_CALLOUT) != 0 && !is_quantifier) { previous_callout = code; code = auto_callout(code, ptr, cd); } switch(c) { /* ===================================================================*/ case 0: /* The branch terminates at string end */ case '|': /* or | or ) */ case ')': *firstbyteptr = firstbyte; *reqbyteptr = reqbyte; *codeptr = code; *ptrptr = ptr; if (lengthptr != NULL) { if (OFLOW_MAX - *lengthptr < code - last_code) { *errorcodeptr = ERR20; goto FAILED; } *lengthptr += code - last_code; /* To include callout length */ DPRINTF((">> end branch\n")); } return TRUE; /* ===================================================================*/ /* Handle single-character metacharacters. In multiline mode, ^ disables the setting of any following char as a first character. */ case '^': if ((options & PCRE_MULTILINE) != 0) { if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE; } previous = NULL; *code++ = OP_CIRC; break; case '$': previous = NULL; *code++ = OP_DOLL; break; /* There can never be a first char if '.' is first, whatever happens about repeats. The value of reqbyte doesn't change either. */ case '.': if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE; zerofirstbyte = firstbyte; zeroreqbyte = reqbyte; previous = code; *code++ = OP_ANY; break; /* ===================================================================*/ /* Character classes. If the included characters are all < 256, we build a 32-byte bitmap of the permitted characters, except in the special case where there is only one such character. For negated classes, we build the map as usual, then invert it at the end. However, we use a different opcode so that data characters > 255 can be handled correctly. If the class contains characters outside the 0-255 range, a different opcode is compiled. It may optionally have a bit map for characters < 256, but those above are are explicitly listed afterwards. A flag byte tells whether the bitmap is present, and whether this is a negated class or not. */ case '[': previous = code; /* PCRE supports POSIX class stuff inside a class. Perl gives an error if they are encountered at the top level, so we'll do that too. */ if ((ptr[1] == ':' || ptr[1] == '.' || ptr[1] == '=') && check_posix_syntax(ptr, &tempptr, cd)) { *errorcodeptr = (ptr[1] == ':')? ERR13 : ERR31; goto FAILED; } /* If the first character is '^', set the negation flag and skip it. Also, if the first few characters (either before or after ^) are \Q\E or \E we skip them too. This makes for compatibility with Perl. */ negate_class = FALSE; for (;;) { c = *(++ptr); if (c == '\\') { if (ptr[1] == 'E') ptr++; else if (strncmp((const char *)ptr+1, "Q\\E", 3) == 0) ptr += 3; else break; } else if (!negate_class && c == '^') negate_class = TRUE; else break; } /* Keep a count of chars with values < 256 so that we can optimize the case of just a single character (as long as it's < 256). However, For higher valued UTF-8 characters, we don't yet do any optimization. */ class_charcount = 0; class_lastchar = -1; /* Initialize the 32-char bit map to all zeros. We build the map in a temporary bit of memory, in case the class contains only 1 character (less than 256), because in that case the compiled code doesn't use the bit map. */ memset(classbits, 0, 32 * sizeof(uschar)); #ifdef SUPPORT_UTF8 class_utf8 = FALSE; /* No chars >= 256 */ class_utf8data = code + LINK_SIZE + 2; /* For UTF-8 items */ #endif /* Process characters until ] is reached. By writing this as a "do" it means that an initial ] is taken as a data character. At the start of the loop, c contains the first byte of the character. */ if (c != 0) do { const uschar *oldptr; #ifdef SUPPORT_UTF8 if (utf8 && c > 127) { /* Braces are required because the */ GETCHARLEN(c, ptr, ptr); /* macro generates multiple statements */ } #endif /* Inside \Q...\E everything is literal except \E */ if (inescq) { if (c == '\\' && ptr[1] == 'E') /* If we are at \E */ { inescq = FALSE; /* Reset literal state */ ptr++; /* Skip the 'E' */ continue; /* Carry on with next */ } goto CHECK_RANGE; /* Could be range if \E follows */ } /* Handle POSIX class names. Perl allows a negation extension of the form [:^name:]. A square bracket that doesn't match the syntax is treated as a literal. We also recognize the POSIX constructions [.ch.] and [=ch=] ("collating elements") and fault them, as Perl 5.6 and 5.8 do. */ if (c == '[' && (ptr[1] == ':' || ptr[1] == '.' || ptr[1] == '=') && check_posix_syntax(ptr, &tempptr, cd)) { BOOL local_negate = FALSE; int posix_class, taboffset, tabopt; register const uschar *cbits = cd->cbits; uschar pbits[32]; if (ptr[1] != ':') { *errorcodeptr = ERR31; goto FAILED; } ptr += 2; if (*ptr == '^') { local_negate = TRUE; ptr++; } posix_class = check_posix_name(ptr, tempptr - ptr); if (posix_class < 0) { *errorcodeptr = ERR30; goto FAILED; } /* If matching is caseless, upper and lower are converted to alpha. This relies on the fact that the class table starts with alpha, lower, upper as the first 3 entries. */ if ((options & PCRE_CASELESS) != 0 && posix_class <= 2) posix_class = 0; /* We build the bit map for the POSIX class in a chunk of local store because we may be adding and subtracting from it, and we don't want to subtract bits that may be in the main map already. At the end we or the result into the bit map that is being built. */ posix_class *= 3; /* Copy in the first table (always present) */ memcpy(pbits, cbits + posix_class_maps[posix_class], 32 * sizeof(uschar)); /* If there is a second table, add or remove it as required. */ taboffset = posix_class_maps[posix_class + 1]; tabopt = posix_class_maps[posix_class + 2]; if (taboffset >= 0) { if (tabopt >= 0) for (c = 0; c < 32; c++) pbits[c] |= cbits[c + taboffset]; else for (c = 0; c < 32; c++) pbits[c] &= ~cbits[c + taboffset]; } /* Not see if we need to remove any special characters. An option value of 1 removes vertical space and 2 removes underscore. */ if (tabopt < 0) tabopt = -tabopt; if (tabopt == 1) pbits[1] &= ~0x3c; else if (tabopt == 2) pbits[11] &= 0x7f; /* Add the POSIX table or its complement into the main table that is being built and we are done. */ if (local_negate) for (c = 0; c < 32; c++) classbits[c] |= ~pbits[c]; else for (c = 0; c < 32; c++) classbits[c] |= pbits[c]; ptr = tempptr + 1; class_charcount = 10; /* Set > 1; assumes more than 1 per class */ continue; /* End of POSIX syntax handling */ } /* Backslash may introduce a single character, or it may introduce one of the specials, which just set a flag. The sequence \b is a special case. Inside a class (and only there) it is treated as backspace. Elsewhere it marks a word boundary. Other escapes have preset maps ready to 'or' into the one we are building. We assume they have more than one character in them, so set class_charcount bigger than one. */ if (c == '\\') { c = check_escape(&ptr, errorcodeptr, cd->bracount, options, TRUE); if (*errorcodeptr != 0) goto FAILED; if (-c == ESC_b) c = '\b'; /* \b is backslash in a class */ else if (-c == ESC_X) c = 'X'; /* \X is literal X in a class */ else if (-c == ESC_R) c = 'R'; /* \R is literal R in a class */ else if (-c == ESC_Q) /* Handle start of quoted string */ { if (ptr[1] == '\\' && ptr[2] == 'E') { ptr += 2; /* avoid empty string */ } else inescq = TRUE; continue; } else if (-c == ESC_E) continue; /* Ignore orphan \E */ if (c < 0) { register const uschar *cbits = cd->cbits; class_charcount += 2; /* Greater than 1 is what matters */ /* Save time by not doing this in the pre-compile phase. */ if (lengthptr == NULL) switch (-c) { case ESC_d: for (c = 0; c < 32; c++) classbits[c] |= cbits[c+cbit_digit]; continue; case ESC_D: for (c = 0; c < 32; c++) classbits[c] |= ~cbits[c+cbit_digit]; continue; case ESC_w: for (c = 0; c < 32; c++) classbits[c] |= cbits[c+cbit_word]; continue; case ESC_W: for (c = 0; c < 32; c++) classbits[c] |= ~cbits[c+cbit_word]; continue; case ESC_s: for (c = 0; c < 32; c++) classbits[c] |= cbits[c+cbit_space]; classbits[1] &= ~0x08; /* Perl 5.004 onwards omits VT from \s */ continue; case ESC_S: for (c = 0; c < 32; c++) classbits[c] |= ~cbits[c+cbit_space]; classbits[1] |= 0x08; /* Perl 5.004 onwards omits VT from \s */ continue; case ESC_E: /* Perl ignores an orphan \E */ continue; default: /* Not recognized; fall through */ break; /* Need "default" setting to stop compiler warning. */ } /* In the pre-compile phase, just do the recognition. */ else if (c == -ESC_d || c == -ESC_D || c == -ESC_w || c == -ESC_W || c == -ESC_s || c == -ESC_S) continue; /* We need to deal with \H, \h, \V, and \v in both phases because they use extra memory. */ if (-c == ESC_h) { SETBIT(classbits, 0x09); /* VT */ SETBIT(classbits, 0x20); /* SPACE */ SETBIT(classbits, 0xa0); /* NSBP */ #ifdef SUPPORT_UTF8 if (utf8) { class_utf8 = TRUE; *class_utf8data++ = XCL_SINGLE; class_utf8data += _pcre_ord2utf8(0x1680, class_utf8data); *class_utf8data++ = XCL_SINGLE; class_utf8data += _pcre_ord2utf8(0x180e, class_utf8data); *class_utf8data++ = XCL_RANGE; class_utf8data += _pcre_ord2utf8(0x2000, class_utf8data); class_utf8data += _pcre_ord2utf8(0x200A, class_utf8data); *class_utf8data++ = XCL_SINGLE; class_utf8data += _pcre_ord2utf8(0x202f, class_utf8data); *class_utf8data++ = XCL_SINGLE; class_utf8data += _pcre_ord2utf8(0x205f, class_utf8data); *class_utf8data++ = XCL_SINGLE; class_utf8data += _pcre_ord2utf8(0x3000, class_utf8data); } #endif continue; } if (-c == ESC_H) { for (c = 0; c < 32; c++) { int x = 0xff; switch (c) { case 0x09/8: x ^= 1 << (0x09%8); break; case 0x20/8: x ^= 1 << (0x20%8); break; case 0xa0/8: x ^= 1 << (0xa0%8); break; default: break; } classbits[c] |= x; } #ifdef SUPPORT_UTF8 if (utf8) { class_utf8 = TRUE; *class_utf8data++ = XCL_RANGE; class_utf8data += _pcre_ord2utf8(0x0100, class_utf8data); class_utf8data += _pcre_ord2utf8(0x167f, class_utf8data); *class_utf8data++ = XCL_RANGE; class_utf8data += _pcre_ord2utf8(0x1681, class_utf8data); class_utf8data += _pcre_ord2utf8(0x180d, class_utf8data); *class_utf8data++ = XCL_RANGE; class_utf8data += _pcre_ord2utf8(0x180f, class_utf8data); class_utf8data += _pcre_ord2utf8(0x1fff, class_utf8data); *class_utf8data++ = XCL_RANGE; class_utf8data += _pcre_ord2utf8(0x200B, class_utf8data); class_utf8data += _pcre_ord2utf8(0x202e, class_utf8data); *class_utf8data++ = XCL_RANGE; class_utf8data += _pcre_ord2utf8(0x2030, class_utf8data); class_utf8data += _pcre_ord2utf8(0x205e, class_utf8data); *class_utf8data++ = XCL_RANGE; class_utf8data += _pcre_ord2utf8(0x2060, class_utf8data); class_utf8data += _pcre_ord2utf8(0x2fff, class_utf8data); *class_utf8data++ = XCL_RANGE; class_utf8data += _pcre_ord2utf8(0x3001, class_utf8data); class_utf8data += _pcre_ord2utf8(0x7fffffff, class_utf8data); } #endif continue; } if (-c == ESC_v) { SETBIT(classbits, 0x0a); /* LF */ SETBIT(classbits, 0x0b); /* VT */ SETBIT(classbits, 0x0c); /* FF */ SETBIT(classbits, 0x0d); /* CR */ SETBIT(classbits, 0x85); /* NEL */ #ifdef SUPPORT_UTF8 if (utf8) { class_utf8 = TRUE; *class_utf8data++ = XCL_RANGE; class_utf8data += _pcre_ord2utf8(0x2028, class_utf8data); class_utf8data += _pcre_ord2utf8(0x2029, class_utf8data); } #endif continue; } if (-c == ESC_V) { for (c = 0; c < 32; c++) { int x = 0xff; switch (c) { case 0x0a/8: x ^= 1 << (0x0a%8); x ^= 1 << (0x0b%8); x ^= 1 << (0x0c%8); x ^= 1 << (0x0d%8); break; case 0x85/8: x ^= 1 << (0x85%8); break; default: break; } classbits[c] |= x; } #ifdef SUPPORT_UTF8 if (utf8) { class_utf8 = TRUE; *class_utf8data++ = XCL_RANGE; class_utf8data += _pcre_ord2utf8(0x0100, class_utf8data); class_utf8data += _pcre_ord2utf8(0x2027, class_utf8data); *class_utf8data++ = XCL_RANGE; class_utf8data += _pcre_ord2utf8(0x2029, class_utf8data); class_utf8data += _pcre_ord2utf8(0x7fffffff, class_utf8data); } #endif continue; } /* We need to deal with \P and \p in both phases. */ #ifdef SUPPORT_UCP if (-c == ESC_p || -c == ESC_P) { BOOL negated; int pdata; int ptype = get_ucp(&ptr, &negated, &pdata, errorcodeptr); if (ptype < 0) goto FAILED; class_utf8 = TRUE; *class_utf8data++ = ((-c == ESC_p) != negated)? XCL_PROP : XCL_NOTPROP; *class_utf8data++ = ptype; *class_utf8data++ = pdata; class_charcount -= 2; /* Not a < 256 character */ continue; } #endif /* Unrecognized escapes are faulted if PCRE is running in its strict mode. By default, for compatibility with Perl, they are treated as literals. */ if ((options & PCRE_EXTRA) != 0) { *errorcodeptr = ERR7; goto FAILED; } class_charcount -= 2; /* Undo the default count from above */ c = *ptr; /* Get the final character and fall through */ } /* Fall through if we have a single character (c >= 0). This may be greater than 256 in UTF-8 mode. */ } /* End of backslash handling */ /* A single character may be followed by '-' to form a range. However, Perl does not permit ']' to be the end of the range. A '-' character at the end is treated as a literal. Perl ignores orphaned \E sequences entirely. The code for handling \Q and \E is messy. */ CHECK_RANGE: while (ptr[1] == '\\' && ptr[2] == 'E') { inescq = FALSE; ptr += 2; } oldptr = ptr; if (!inescq && ptr[1] == '-') { int d; ptr += 2; while (*ptr == '\\' && ptr[1] == 'E') ptr += 2; /* If we hit \Q (not followed by \E) at this point, go into escaped mode. */ while (*ptr == '\\' && ptr[1] == 'Q') { ptr += 2; if (*ptr == '\\' && ptr[1] == 'E') { ptr += 2; continue; } inescq = TRUE; break; } if (*ptr == 0 || (!inescq && *ptr == ']')) { ptr = oldptr; goto LONE_SINGLE_CHARACTER; } #ifdef SUPPORT_UTF8 if (utf8) { /* Braces are required because the */ GETCHARLEN(d, ptr, ptr); /* macro generates multiple statements */ } else #endif d = *ptr; /* Not UTF-8 mode */ /* The second part of a range can be a single-character escape, but not any of the other escapes. Perl 5.6 treats a hyphen as a literal in such circumstances. */ if (!inescq && d == '\\') { d = check_escape(&ptr, errorcodeptr, cd->bracount, options, TRUE); if (*errorcodeptr != 0) goto FAILED; /* \b is backslash; \X is literal X; \R is literal R; any other special means the '-' was literal */ if (d < 0) { if (d == -ESC_b) d = '\b'; else if (d == -ESC_X) d = 'X'; else if (d == -ESC_R) d = 'R'; else { ptr = oldptr; goto LONE_SINGLE_CHARACTER; /* A few lines below */ } } } /* Check that the two values are in the correct order. Optimize one-character ranges */ if (d < c) { *errorcodeptr = ERR8; goto FAILED; } if (d == c) goto LONE_SINGLE_CHARACTER; /* A few lines below */ /* In UTF-8 mode, if the upper limit is > 255, or > 127 for caseless matching, we have to use an XCLASS with extra data items. Caseless matching for characters > 127 is available only if UCP support is available. */ #ifdef SUPPORT_UTF8 if (utf8 && (d > 255 || ((options & PCRE_CASELESS) != 0 && d > 127))) { class_utf8 = TRUE; /* With UCP support, we can find the other case equivalents of the relevant characters. There may be several ranges. Optimize how they fit with the basic range. */ #ifdef SUPPORT_UCP if ((options & PCRE_CASELESS) != 0) { unsigned int occ, ocd; unsigned int cc = c; unsigned int origd = d; while (get_othercase_range(&cc, origd, &occ, &ocd)) { if (occ >= (unsigned int)c && ocd <= (unsigned int)d) continue; /* Skip embedded ranges */ if (occ < (unsigned int)c && ocd >= (unsigned int)c - 1) /* Extend the basic range */ { /* if there is overlap, */ c = occ; /* noting that if occ < c */ continue; /* we can't have ocd > d */ } /* because a subrange is */ if (ocd > (unsigned int)d && occ <= (unsigned int)d + 1) /* always shorter than */ { /* the basic range. */ d = ocd; continue; } if (occ == ocd) { *class_utf8data++ = XCL_SINGLE; } else { *class_utf8data++ = XCL_RANGE; class_utf8data += _pcre_ord2utf8(occ, class_utf8data); } class_utf8data += _pcre_ord2utf8(ocd, class_utf8data); } } #endif /* SUPPORT_UCP */ /* Now record the original range, possibly modified for UCP caseless overlapping ranges. */ *class_utf8data++ = XCL_RANGE; class_utf8data += _pcre_ord2utf8(c, class_utf8data); class_utf8data += _pcre_ord2utf8(d, class_utf8data); /* With UCP support, we are done. Without UCP support, there is no caseless matching for UTF-8 characters > 127; we can use the bit map for the smaller ones. */ #ifdef SUPPORT_UCP continue; /* With next character in the class */ #else if ((options & PCRE_CASELESS) == 0 || c > 127) continue; /* Adjust upper limit and fall through to set up the map */ d = 127; #endif /* SUPPORT_UCP */ } #endif /* SUPPORT_UTF8 */ /* We use the bit map for all cases when not in UTF-8 mode; else ranges that lie entirely within 0-127 when there is UCP support; else for partial ranges without UCP support. */ class_charcount += d - c + 1; class_lastchar = d; /* We can save a bit of time by skipping this in the pre-compile. */ if (lengthptr == NULL) for (; c <= d; c++) { classbits[c/8] |= (1 << (c&7)); if ((options & PCRE_CASELESS) != 0) { int uc = cd->fcc[c]; /* flip case */ classbits[uc/8] |= (1 << (uc&7)); } } continue; /* Go get the next char in the class */ } /* Handle a lone single character - we can get here for a normal non-escape char, or after \ that introduces a single character or for an apparent range that isn't. */ LONE_SINGLE_CHARACTER: /* Handle a character that cannot go in the bit map */ #ifdef SUPPORT_UTF8 if (utf8 && (c > 255 || ((options & PCRE_CASELESS) != 0 && c > 127))) { class_utf8 = TRUE; *class_utf8data++ = XCL_SINGLE; class_utf8data += _pcre_ord2utf8(c, class_utf8data); #ifdef SUPPORT_UCP if ((options & PCRE_CASELESS) != 0) { unsigned int othercase; if ((othercase = _pcre_ucp_othercase(c)) != NOTACHAR) { *class_utf8data++ = XCL_SINGLE; class_utf8data += _pcre_ord2utf8(othercase, class_utf8data); } } #endif /* SUPPORT_UCP */ } else #endif /* SUPPORT_UTF8 */ /* Handle a single-byte character */ { classbits[c/8] |= (1 << (c&7)); if ((options & PCRE_CASELESS) != 0) { c = cd->fcc[c]; /* flip case */ classbits[c/8] |= (1 << (c&7)); } class_charcount++; class_lastchar = c; } } /* Loop until ']' reached. This "while" is the end of the "do" above. */ while ((c = *(++ptr)) != 0 && (c != ']' || inescq)); if (c == 0) /* Missing terminating ']' */ { *errorcodeptr = ERR6; goto FAILED; } /* Remember whether \r or \n are in this class */ if (negate_class) { if ((classbits[1] & 0x24) != 0x24) cd->external_options |= PCRE_HASCRORLF; } else { if ((classbits[1] & 0x24) != 0) cd->external_options |= PCRE_HASCRORLF; } /* If class_charcount is 1, we saw precisely one character whose value is less than 256. As long as there were no characters >= 128 and there was no use of \p or \P, in other words, no use of any XCLASS features, we can optimize. In UTF-8 mode, we can optimize the negative case only if there were no characters >= 128 because OP_NOT and the related opcodes like OP_NOTSTAR operate on single-bytes only. This is an historical hangover. Maybe one day we can tidy these opcodes to handle multi-byte characters. The optimization throws away the bit map. We turn the item into a 1-character OP_CHAR[NC] if it's positive, or OP_NOT if it's negative. Note that OP_NOT does not support multibyte characters. In the positive case, it can cause firstbyte to be set. Otherwise, there can be no first char if this item is first, whatever repeat count may follow. In the case of reqbyte, save the previous value for reinstating. */ #ifdef SUPPORT_UTF8 if (class_charcount == 1 && !class_utf8 && (!utf8 || !negate_class || class_lastchar < 128)) #else if (class_charcount == 1) #endif { zeroreqbyte = reqbyte; /* The OP_NOT opcode works on one-byte characters only. */ if (negate_class) { if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE; zerofirstbyte = firstbyte; *code++ = OP_NOT; *code++ = class_lastchar; break; } /* For a single, positive character, get the value into mcbuffer, and then we can handle this with the normal one-character code. */ #ifdef SUPPORT_UTF8 if (utf8 && class_lastchar > 127) mclength = _pcre_ord2utf8(class_lastchar, mcbuffer); else #endif { mcbuffer[0] = class_lastchar; mclength = 1; } goto ONE_CHAR; } /* End of 1-char optimization */ /* The general case - not the one-char optimization. If this is the first thing in the branch, there can be no first char setting, whatever the repeat count. Any reqbyte setting must remain unchanged after any kind of repeat. */ if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE; zerofirstbyte = firstbyte; zeroreqbyte = reqbyte; /* If there are characters with values > 255, we have to compile an extended class, with its own opcode. If there are no characters < 256, we can omit the bitmap in the actual compiled code. */ #ifdef SUPPORT_UTF8 if (class_utf8) { *class_utf8data++ = XCL_END; /* Marks the end of extra data */ *code++ = OP_XCLASS; code += LINK_SIZE; *code = negate_class? XCL_NOT : 0; /* If the map is required, move up the extra data to make room for it; otherwise just move the code pointer to the end of the extra data. */ if (class_charcount > 0) { *code++ |= XCL_MAP; memmove(code + 32, code, class_utf8data - code); memcpy(code, classbits, 32); code = class_utf8data + 32; } else code = class_utf8data; /* Now fill in the complete length of the item */ PUT(previous, 1, code - previous); break; /* End of class handling */ } #endif /* If there are no characters > 255, negate the 32-byte map if necessary, and copy it into the code vector. If this is the first thing in the branch, there can be no first char setting, whatever the repeat count. Any reqbyte setting must remain unchanged after any kind of repeat. */ if (negate_class) { *code++ = OP_NCLASS; if (lengthptr == NULL) /* Save time in the pre-compile phase */ for (c = 0; c < 32; c++) code[c] = ~classbits[c]; } else { *code++ = OP_CLASS; memcpy(code, classbits, 32); } code += 32; break; /* ===================================================================*/ /* Various kinds of repeat; '{' is not necessarily a quantifier, but this has been tested above. */ case '{': if (!is_quantifier) goto NORMAL_CHAR; ptr = read_repeat_counts(ptr+1, &repeat_min, &repeat_max, errorcodeptr); if (*errorcodeptr != 0) goto FAILED; goto REPEAT; case '*': repeat_min = 0; repeat_max = -1; goto REPEAT; case '+': repeat_min = 1; repeat_max = -1; goto REPEAT; case '?': repeat_min = 0; repeat_max = 1; REPEAT: if (previous == NULL) { *errorcodeptr = ERR9; goto FAILED; } if (repeat_min == 0) { firstbyte = zerofirstbyte; /* Adjust for zero repeat */ reqbyte = zeroreqbyte; /* Ditto */ } /* Remember whether this is a variable length repeat */ reqvary = (repeat_min == repeat_max)? 0 : REQ_VARY; op_type = 0; /* Default single-char op codes */ possessive_quantifier = FALSE; /* Default not possessive quantifier */ /* Save start of previous item, in case we have to move it up to make space for an inserted OP_ONCE for the additional '+' extension. */ tempcode = previous; /* If the next character is '+', we have a possessive quantifier. This implies greediness, whatever the setting of the PCRE_UNGREEDY option. If the next character is '?' this is a minimizing repeat, by default, but if PCRE_UNGREEDY is set, it works the other way round. We change the repeat type to the non-default. */ if (ptr[1] == '+') { repeat_type = 0; /* Force greedy */ possessive_quantifier = TRUE; ptr++; } else if (ptr[1] == '?') { repeat_type = greedy_non_default; ptr++; } else repeat_type = greedy_default; /* If previous was a character match, abolish the item and generate a repeat item instead. If a char item has a minumum of more than one, ensure that it is set in reqbyte - it might not be if a sequence such as x{3} is the first thing in a branch because the x will have gone into firstbyte instead. */ if (*previous == OP_CHAR || *previous == OP_CHARNC) { /* Deal with UTF-8 characters that take up more than one byte. It's easier to write this out separately than try to macrify it. Use c to hold the length of the character in bytes, plus 0x80 to flag that it's a length rather than a small character. */ #ifdef SUPPORT_UTF8 if (utf8 && (code[-1] & 0x80) != 0) { uschar *lastchar = code - 1; while((*lastchar & 0xc0) == 0x80) lastchar--; c = code - lastchar; /* Length of UTF-8 character */ memcpy(utf8_char, lastchar, c); /* Save the char */ c |= 0x80; /* Flag c as a length */ } else #endif /* Handle the case of a single byte - either with no UTF8 support, or with UTF-8 disabled, or for a UTF-8 character < 128. */ { c = code[-1]; if (repeat_min > 1) reqbyte = c | req_caseopt | cd->req_varyopt; } /* If the repetition is unlimited, it pays to see if the next thing on the line is something that cannot possibly match this character. If so, automatically possessifying this item gains some performance in the case where the match fails. */ if (!possessive_quantifier && repeat_max < 0 && check_auto_possessive(*previous, c, utf8, utf8_char, ptr + 1, options, cd)) { repeat_type = 0; /* Force greedy */ possessive_quantifier = TRUE; } goto OUTPUT_SINGLE_REPEAT; /* Code shared with single character types */ } /* If previous was a single negated character ([^a] or similar), we use one of the special opcodes, replacing it. The code is shared with single- character repeats by setting opt_type to add a suitable offset into repeat_type. We can also test for auto-possessification. OP_NOT is currently used only for single-byte chars. */ else if (*previous == OP_NOT) { op_type = OP_NOTSTAR - OP_STAR; /* Use "not" opcodes */ c = previous[1]; if (!possessive_quantifier && repeat_max < 0 && check_auto_possessive(OP_NOT, c, utf8, NULL, ptr + 1, options, cd)) { repeat_type = 0; /* Force greedy */ possessive_quantifier = TRUE; } goto OUTPUT_SINGLE_REPEAT; } /* If previous was a character type match (\d or similar), abolish it and create a suitable repeat item. The code is shared with single-character repeats by setting op_type to add a suitable offset into repeat_type. Note the the Unicode property types will be present only when SUPPORT_UCP is defined, but we don't wrap the little bits of code here because it just makes it horribly messy. */ else if (*previous < OP_EODN) { uschar *oldcode; int prop_type, prop_value; op_type = OP_TYPESTAR - OP_STAR; /* Use type opcodes */ c = *previous; if (!possessive_quantifier && repeat_max < 0 && check_auto_possessive(c, 0, utf8, NULL, ptr + 1, options, cd)) { repeat_type = 0; /* Force greedy */ possessive_quantifier = TRUE; } OUTPUT_SINGLE_REPEAT: if (*previous == OP_PROP || *previous == OP_NOTPROP) { prop_type = previous[1]; prop_value = previous[2]; } else prop_type = prop_value = -1; oldcode = code; code = previous; /* Usually overwrite previous item */ /* If the maximum is zero then the minimum must also be zero; Perl allows this case, so we do too - by simply omitting the item altogether. */ if (repeat_max == 0) goto END_REPEAT; /* All real repeats make it impossible to handle partial matching (maybe one day we will be able to remove this restriction). */ if (repeat_max != 1) cd->nopartial = TRUE; /* Combine the op_type with the repeat_type */ repeat_type += op_type; /* A minimum of zero is handled either as the special case * or ?, or as an UPTO, with the maximum given. */ if (repeat_min == 0) { if (repeat_max == -1) *code++ = OP_STAR + repeat_type; else if (repeat_max == 1) *code++ = OP_QUERY + repeat_type; else { *code++ = OP_UPTO + repeat_type; PUT2INC(code, 0, repeat_max); } } /* A repeat minimum of 1 is optimized into some special cases. If the maximum is unlimited, we use OP_PLUS. Otherwise, the original item is left in place and, if the maximum is greater than 1, we use OP_UPTO with one less than the maximum. */ else if (repeat_min == 1) { if (repeat_max == -1) *code++ = OP_PLUS + repeat_type; else { code = oldcode; /* leave previous item in place */ if (repeat_max == 1) goto END_REPEAT; *code++ = OP_UPTO + repeat_type; PUT2INC(code, 0, repeat_max - 1); } } /* The case {n,n} is just an EXACT, while the general case {n,m} is handled as an EXACT followed by an UPTO. */ else { *code++ = OP_EXACT + op_type; /* NB EXACT doesn't have repeat_type */ PUT2INC(code, 0, repeat_min); /* If the maximum is unlimited, insert an OP_STAR. Before doing so, we have to insert the character for the previous code. For a repeated Unicode property match, there are two extra bytes that define the required property. In UTF-8 mode, long characters have their length in c, with the 0x80 bit as a flag. */ if (repeat_max < 0) { #ifdef SUPPORT_UTF8 if (utf8 && c >= 128) { memcpy(code, utf8_char, c & 7); code += c & 7; } else #endif { *code++ = c; if (prop_type >= 0) { *code++ = prop_type; *code++ = prop_value; } } *code++ = OP_STAR + repeat_type; } /* Else insert an UPTO if the max is greater than the min, again preceded by the character, for the previously inserted code. If the UPTO is just for 1 instance, we can use QUERY instead. */ else if (repeat_max != repeat_min) { #ifdef SUPPORT_UTF8 if (utf8 && c >= 128) { memcpy(code, utf8_char, c & 7); code += c & 7; } else #endif *code++ = c; if (prop_type >= 0) { *code++ = prop_type; *code++ = prop_value; } repeat_max -= repeat_min; if (repeat_max == 1) { *code++ = OP_QUERY + repeat_type; } else { *code++ = OP_UPTO + repeat_type; PUT2INC(code, 0, repeat_max); } } } /* The character or character type itself comes last in all cases. */ #ifdef SUPPORT_UTF8 if (utf8 && c >= 128) { memcpy(code, utf8_char, c & 7); code += c & 7; } else #endif *code++ = c; /* For a repeated Unicode property match, there are two extra bytes that define the required property. */ #ifdef SUPPORT_UCP if (prop_type >= 0) { *code++ = prop_type; *code++ = prop_value; } #endif } /* If previous was a character class or a back reference, we put the repeat stuff after it, but just skip the item if the repeat was {0,0}. */ else if (*previous == OP_CLASS || *previous == OP_NCLASS || #ifdef SUPPORT_UTF8 *previous == OP_XCLASS || #endif *previous == OP_REF) { if (repeat_max == 0) { code = previous; goto END_REPEAT; } /* All real repeats make it impossible to handle partial matching (maybe one day we will be able to remove this restriction). */ if (repeat_max != 1) cd->nopartial = TRUE; if (repeat_min == 0 && repeat_max == -1) *code++ = OP_CRSTAR + repeat_type; else if (repeat_min == 1 && repeat_max == -1) *code++ = OP_CRPLUS + repeat_type; else if (repeat_min == 0 && repeat_max == 1) *code++ = OP_CRQUERY + repeat_type; else { *code++ = OP_CRRANGE + repeat_type; PUT2INC(code, 0, repeat_min); if (repeat_max == -1) repeat_max = 0; /* 2-byte encoding for max */ PUT2INC(code, 0, repeat_max); } } /* If previous was a bracket group, we may have to replicate it in certain cases. */ else if (*previous == OP_BRA || *previous == OP_CBRA || *previous == OP_ONCE || *previous == OP_COND) { register int i; int ketoffset = 0; int len = code - previous; uschar *bralink = NULL; /* Repeating a DEFINE group is pointless */ if (*previous == OP_COND && previous[LINK_SIZE+1] == OP_DEF) { *errorcodeptr = ERR55; goto FAILED; } /* If the maximum repeat count is unlimited, find the end of the bracket by scanning through from the start, and compute the offset back to it from the current code pointer. There may be an OP_OPT setting following the final KET, so we can't find the end just by going back from the code pointer. */ if (repeat_max == -1) { register uschar *ket = previous; do ket += GET(ket, 1); while (*ket != OP_KET); ketoffset = code - ket; } /* The case of a zero minimum is special because of the need to stick OP_BRAZERO in front of it, and because the group appears once in the data, whereas in other cases it appears the minimum number of times. For this reason, it is simplest to treat this case separately, as otherwise the code gets far too messy. There are several special subcases when the minimum is zero. */ if (repeat_min == 0) { /* If the maximum is also zero, we just omit the group from the output altogether. */ if (repeat_max == 0) { code = previous; goto END_REPEAT; } /* If the maximum is 1 or unlimited, we just have to stick in the BRAZERO and do no more at this point. However, we do need to adjust any OP_RECURSE calls inside the group that refer to the group itself or any internal or forward referenced group, because the offset is from the start of the whole regex. Temporarily terminate the pattern while doing this. */ if (repeat_max <= 1) { *code = OP_END; adjust_recurse(previous, 1, utf8, cd, save_hwm); memmove(previous+1, previous, len); code++; *previous++ = OP_BRAZERO + repeat_type; } /* If the maximum is greater than 1 and limited, we have to replicate in a nested fashion, sticking OP_BRAZERO before each set of brackets. The first one has to be handled carefully because it's the original copy, which has to be moved up. The remainder can be handled by code that is common with the non-zero minimum case below. We have to adjust the value or repeat_max, since one less copy is required. Once again, we may have to adjust any OP_RECURSE calls inside the group. */ else { int offset; *code = OP_END; adjust_recurse(previous, 2 + LINK_SIZE, utf8, cd, save_hwm); memmove(previous + 2 + LINK_SIZE, previous, len); code += 2 + LINK_SIZE; *previous++ = OP_BRAZERO + repeat_type; *previous++ = OP_BRA; /* We chain together the bracket offset fields that have to be filled in later when the ends of the brackets are reached. */ offset = (bralink == NULL)? 0 : previous - bralink; bralink = previous; PUTINC(previous, 0, offset); } repeat_max--; } /* If the minimum is greater than zero, replicate the group as many times as necessary, and adjust the maximum to the number of subsequent copies that we need. If we set a first char from the group, and didn't set a required char, copy the latter from the former. If there are any forward reference subroutine calls in the group, there will be entries on the workspace list; replicate these with an appropriate increment. */ else { if (repeat_min > 1) { /* In the pre-compile phase, we don't actually do the replication. We just adjust the length as if we had. Do some paranoid checks for potential integer overflow. */ if (lengthptr != NULL) { int delta = (repeat_min - 1)*length_prevgroup; if ((double)(repeat_min - 1)*(double)length_prevgroup > (double)INT_MAX || OFLOW_MAX - *lengthptr < delta) { *errorcodeptr = ERR20; goto FAILED; } *lengthptr += delta; } /* This is compiling for real */ else { if (groupsetfirstbyte && reqbyte < 0) reqbyte = firstbyte; for (i = 1; i < repeat_min; i++) { uschar *hc; uschar *this_hwm = cd->hwm; memcpy(code, previous, len); for (hc = save_hwm; hc < this_hwm; hc += LINK_SIZE) { PUT(cd->hwm, 0, GET(hc, 0) + len); cd->hwm += LINK_SIZE; } save_hwm = this_hwm; code += len; } } } if (repeat_max > 0) repeat_max -= repeat_min; } /* This code is common to both the zero and non-zero minimum cases. If the maximum is limited, it replicates the group in a nested fashion, remembering the bracket starts on a stack. In the case of a zero minimum, the first one was set up above. In all cases the repeat_max now specifies the number of additional copies needed. Again, we must remember to replicate entries on the forward reference list. */ if (repeat_max >= 0) { /* In the pre-compile phase, we don't actually do the replication. We just adjust the length as if we had. For each repetition we must add 1 to the length for BRAZERO and for all but the last repetition we must add 2 + 2*LINKSIZE to allow for the nesting that occurs. Do some paranoid checks to avoid integer overflow. */ if (lengthptr != NULL && repeat_max > 0) { int delta = repeat_max * (length_prevgroup + 1 + 2 + 2*LINK_SIZE) - 2 - 2*LINK_SIZE; /* Last one doesn't nest */ if ((double)repeat_max * (double)(length_prevgroup + 1 + 2 + 2*LINK_SIZE) > (double)INT_MAX || OFLOW_MAX - *lengthptr < delta) { *errorcodeptr = ERR20; goto FAILED; } *lengthptr += delta; } /* This is compiling for real */ else for (i = repeat_max - 1; i >= 0; i--) { uschar *hc; uschar *this_hwm = cd->hwm; *code++ = OP_BRAZERO + repeat_type; /* All but the final copy start a new nesting, maintaining the chain of brackets outstanding. */ if (i != 0) { int offset; *code++ = OP_BRA; offset = (bralink == NULL)? 0 : code - bralink; bralink = code; PUTINC(code, 0, offset); } memcpy(code, previous, len); for (hc = save_hwm; hc < this_hwm; hc += LINK_SIZE) { PUT(cd->hwm, 0, GET(hc, 0) + len + ((i != 0)? 2+LINK_SIZE : 1)); cd->hwm += LINK_SIZE; } save_hwm = this_hwm; code += len; } /* Now chain through the pending brackets, and fill in their length fields (which are holding the chain links pro tem). */ while (bralink != NULL) { int oldlinkoffset; int offset = code - bralink + 1; uschar *bra = code - offset; oldlinkoffset = GET(bra, 1); bralink = (oldlinkoffset == 0)? NULL : bralink - oldlinkoffset; *code++ = OP_KET; PUTINC(code, 0, offset); PUT(bra, 1, offset); } } /* If the maximum is unlimited, set a repeater in the final copy. We can't just offset backwards from the current code point, because we don't know if there's been an options resetting after the ket. The correct offset was computed above. Then, when we are doing the actual compile phase, check to see whether this group is a non-atomic one that could match an empty string. If so, convert the initial operator to the S form (e.g. OP_BRA -> OP_SBRA) so that runtime checking can be done. [This check is also applied to atomic groups at runtime, but in a different way.] */ else { uschar *ketcode = code - ketoffset; uschar *bracode = ketcode - GET(ketcode, 1); *ketcode = OP_KETRMAX + repeat_type; if (lengthptr == NULL && *bracode != OP_ONCE) { uschar *scode = bracode; do { if (could_be_empty_branch(scode, ketcode, utf8)) { *bracode += OP_SBRA - OP_BRA; break; } scode += GET(scode, 1); } while (*scode == OP_ALT); } } } /* Else there's some kind of shambles */ else { *errorcodeptr = ERR11; goto FAILED; } /* If the character following a repeat is '+', or if certain optimization tests above succeeded, possessive_quantifier is TRUE. For some of the simpler opcodes, there is an special alternative opcode for this. For anything else, we wrap the entire repeated item inside OP_ONCE brackets. The '+' notation is just syntactic sugar, taken from Sun's Java package, but the special opcodes can optimize it a bit. The repeated item starts at tempcode, not at previous, which might be the first part of a string whose (former) last char we repeated. Possessifying an 'exact' quantifier has no effect, so we can ignore it. But an 'upto' may follow. We skip over an 'exact' item, and then test the length of what remains before proceeding. */ if (possessive_quantifier) { int len; if (*tempcode == OP_EXACT || *tempcode == OP_TYPEEXACT || *tempcode == OP_NOTEXACT) tempcode += _pcre_OP_lengths[*tempcode]; len = code - tempcode; if (len > 0) switch (*tempcode) { case OP_STAR: *tempcode = OP_POSSTAR; break; case OP_PLUS: *tempcode = OP_POSPLUS; break; case OP_QUERY: *tempcode = OP_POSQUERY; break; case OP_UPTO: *tempcode = OP_POSUPTO; break; case OP_TYPESTAR: *tempcode = OP_TYPEPOSSTAR; break; case OP_TYPEPLUS: *tempcode = OP_TYPEPOSPLUS; break; case OP_TYPEQUERY: *tempcode = OP_TYPEPOSQUERY; break; case OP_TYPEUPTO: *tempcode = OP_TYPEPOSUPTO; break; case OP_NOTSTAR: *tempcode = OP_NOTPOSSTAR; break; case OP_NOTPLUS: *tempcode = OP_NOTPOSPLUS; break; case OP_NOTQUERY: *tempcode = OP_NOTPOSQUERY; break; case OP_NOTUPTO: *tempcode = OP_NOTPOSUPTO; break; default: memmove(tempcode + 1+LINK_SIZE, tempcode, len); code += 1 + LINK_SIZE; len += 1 + LINK_SIZE; tempcode[0] = OP_ONCE; *code++ = OP_KET; PUTINC(code, 0, len); PUT(tempcode, 1, len); break; } } /* In all case we no longer have a previous item. We also set the "follows varying string" flag for subsequently encountered reqbytes if it isn't already set and we have just passed a varying length item. */ END_REPEAT: previous = NULL; cd->req_varyopt |= reqvary; break; /* ===================================================================*/ /* Start of nested parenthesized sub-expression, or comment or lookahead or lookbehind or option setting or condition or all the other extended parenthesis forms. */ case '(': newoptions = options; skipbytes = 0; bravalue = OP_CBRA; save_hwm = cd->hwm; reset_bracount = FALSE; /* First deal with various "verbs" that can be introduced by '*'. */ if (*(++ptr) == '*' && (cd->ctypes[ptr[1]] & ctype_letter) != 0) { int i, namelen; const uschar *name = ++ptr; previous = NULL; while ((cd->ctypes[*++ptr] & ctype_letter) != 0); if (*ptr == ':') { *errorcodeptr = ERR59; /* Not supported */ goto FAILED; } if (*ptr != ')') { *errorcodeptr = ERR60; goto FAILED; } namelen = ptr - name; for (i = 0; i < verbcount; i++) { if (namelen == verbs[i].len && strncmp((char *)name, verbs[i].name, namelen) == 0) { *code = verbs[i].op; if (*code++ == OP_ACCEPT) cd->had_accept = TRUE; break; } } if (i < verbcount) continue; *errorcodeptr = ERR60; goto FAILED; } /* Deal with the extended parentheses; all are introduced by '?', and the appearance of any of them means that this is not a capturing group. */ else if (*ptr == '?') { int i, set, unset, namelen; int *optset; const uschar *name; uschar *slot; switch (*(++ptr)) { case '#': /* Comment; skip to ket */ ptr++; while (*ptr != 0 && *ptr != ')') ptr++; if (*ptr == 0) { *errorcodeptr = ERR18; goto FAILED; } continue; /* ------------------------------------------------------------ */ case '|': /* Reset capture count for each branch */ reset_bracount = TRUE; /* Fall through */ /* ------------------------------------------------------------ */ case ':': /* Non-capturing bracket */ bravalue = OP_BRA; ptr++; break; /* ------------------------------------------------------------ */ case '(': bravalue = OP_COND; /* Conditional group */ /* A condition can be an assertion, a number (referring to a numbered group), a name (referring to a named group), or 'R', referring to recursion. R and R&name are also permitted for recursion tests. There are several syntaxes for testing a named group: (?(name)) is used by Python; Perl 5.10 onwards uses (?() or (?('name')). There are two unfortunate ambiguities, caused by history. (a) 'R' can be the recursive thing or the name 'R' (and similarly for 'R' followed by digits), and (b) a number could be a name that consists of digits. In both cases, we look for a name first; if not found, we try the other cases. */ /* For conditions that are assertions, check the syntax, and then exit the switch. This will take control down to where bracketed groups, including assertions, are processed. */ if (ptr[1] == '?' && (ptr[2] == '=' || ptr[2] == '!' || ptr[2] == '<')) break; /* Most other conditions use OP_CREF (a couple change to OP_RREF below), and all need to skip 3 bytes at the start of the group. */ code[1+LINK_SIZE] = OP_CREF; skipbytes = 3; refsign = -1; /* Check for a test for recursion in a named group. */ if (ptr[1] == 'R' && ptr[2] == '&') { terminator = -1; ptr += 2; code[1+LINK_SIZE] = OP_RREF; /* Change the type of test */ } /* Check for a test for a named group's having been set, using the Perl syntax (?() or (?('name') */ else if (ptr[1] == '<') { terminator = '>'; ptr++; } else if (ptr[1] == '\'') { terminator = '\''; ptr++; } else { terminator = 0; if (ptr[1] == '-' || ptr[1] == '+') refsign = *(++ptr); } /* We now expect to read a name; any thing else is an error */ if ((cd->ctypes[ptr[1]] & ctype_word) == 0) { ptr += 1; /* To get the right offset */ *errorcodeptr = ERR28; goto FAILED; } /* Read the name, but also get it as a number if it's all digits */ recno = 0; name = ++ptr; while ((cd->ctypes[*ptr] & ctype_word) != 0) { if (recno >= 0) recno = ((digitab[*ptr] & ctype_digit) != 0)? recno * 10 + *ptr - '0' : -1; ptr++; } namelen = ptr - name; if ((terminator > 0 && *ptr++ != terminator) || *ptr++ != ')') { ptr--; /* Error offset */ *errorcodeptr = ERR26; goto FAILED; } /* Do no further checking in the pre-compile phase. */ if (lengthptr != NULL) break; /* In the real compile we do the work of looking for the actual reference. If the string started with "+" or "-" we require the rest to be digits, in which case recno will be set. */ if (refsign > 0) { if (recno <= 0) { *errorcodeptr = ERR58; goto FAILED; } if (refsign == '-') { recno = cd->bracount - recno + 1; if (recno <= 0) { *errorcodeptr = ERR15; goto FAILED; } } else recno += cd->bracount; PUT2(code, 2+LINK_SIZE, recno); break; } /* Otherwise (did not start with "+" or "-"), start by looking for the name. */ slot = cd->name_table; for (i = 0; i < cd->names_found; i++) { if (strncmp((char *)name, (char *)slot+2, namelen) == 0) break; slot += cd->name_entry_size; } /* Found a previous named subpattern */ if (i < cd->names_found) { recno = GET2(slot, 0); PUT2(code, 2+LINK_SIZE, recno); } /* Search the pattern for a forward reference */ else if ((i = find_parens(ptr, cd->bracount, name, namelen, (options & PCRE_EXTENDED) != 0)) > 0) { PUT2(code, 2+LINK_SIZE, i); } /* If terminator == 0 it means that the name followed directly after the opening parenthesis [e.g. (?(abc)...] and in this case there are some further alternatives to try. For the cases where terminator != 0 [things like (?(... or (?('name')... or (?(R&name)... ] we have now checked all the possibilities, so give an error. */ else if (terminator != 0) { *errorcodeptr = ERR15; goto FAILED; } /* Check for (?(R) for recursion. Allow digits after R to specify a specific group number. */ else if (*name == 'R') { recno = 0; for (i = 1; i < namelen; i++) { if ((digitab[name[i]] & ctype_digit) == 0) { *errorcodeptr = ERR15; goto FAILED; } recno = recno * 10 + name[i] - '0'; } if (recno == 0) recno = RREF_ANY; code[1+LINK_SIZE] = OP_RREF; /* Change test type */ PUT2(code, 2+LINK_SIZE, recno); } /* Similarly, check for the (?(DEFINE) "condition", which is always false. */ else if (namelen == 6 && strncmp((char *)name, "DEFINE", 6) == 0) { code[1+LINK_SIZE] = OP_DEF; skipbytes = 1; } /* Check for the "name" actually being a subpattern number. */ else if (recno > 0) { PUT2(code, 2+LINK_SIZE, recno); } /* Either an unidentified subpattern, or a reference to (?(0) */ else { *errorcodeptr = (recno == 0)? ERR35: ERR15; goto FAILED; } break; /* ------------------------------------------------------------ */ case '=': /* Positive lookahead */ bravalue = OP_ASSERT; ptr++; break; /* ------------------------------------------------------------ */ case '!': /* Negative lookahead */ ptr++; if (*ptr == ')') /* Optimize (?!) */ { *code++ = OP_FAIL; previous = NULL; continue; } bravalue = OP_ASSERT_NOT; break; /* ------------------------------------------------------------ */ case '<': /* Lookbehind or named define */ switch (ptr[1]) { case '=': /* Positive lookbehind */ bravalue = OP_ASSERTBACK; ptr += 2; break; case '!': /* Negative lookbehind */ bravalue = OP_ASSERTBACK_NOT; ptr += 2; break; default: /* Could be name define, else bad */ if ((cd->ctypes[ptr[1]] & ctype_word) != 0) goto DEFINE_NAME; ptr++; /* Correct offset for error */ *errorcodeptr = ERR24; goto FAILED; } break; /* ------------------------------------------------------------ */ case '>': /* One-time brackets */ bravalue = OP_ONCE; ptr++; break; /* ------------------------------------------------------------ */ case 'C': /* Callout - may be followed by digits; */ previous_callout = code; /* Save for later completion */ after_manual_callout = 1; /* Skip one item before completing */ *code++ = OP_CALLOUT; { int n = 0; while ((digitab[*(++ptr)] & ctype_digit) != 0) n = n * 10 + *ptr - '0'; if (*ptr != ')') { *errorcodeptr = ERR39; goto FAILED; } if (n > 255) { *errorcodeptr = ERR38; goto FAILED; } *code++ = n; PUT(code, 0, ptr - cd->start_pattern + 1); /* Pattern offset */ PUT(code, LINK_SIZE, 0); /* Default length */ code += 2 * LINK_SIZE; } previous = NULL; continue; /* ------------------------------------------------------------ */ case 'P': /* Python-style named subpattern handling */ if (*(++ptr) == '=' || *ptr == '>') /* Reference or recursion */ { is_recurse = *ptr == '>'; terminator = ')'; goto NAMED_REF_OR_RECURSE; } else if (*ptr != '<') /* Test for Python-style definition */ { *errorcodeptr = ERR41; goto FAILED; } /* Fall through to handle (?P< as (?< is handled */ /* ------------------------------------------------------------ */ DEFINE_NAME: /* Come here from (?< handling */ case '\'': { terminator = (*ptr == '<')? '>' : '\''; name = ++ptr; while ((cd->ctypes[*ptr] & ctype_word) != 0) ptr++; namelen = ptr - name; /* In the pre-compile phase, just do a syntax check. */ if (lengthptr != NULL) { if (*ptr != terminator) { *errorcodeptr = ERR42; goto FAILED; } if (cd->names_found >= MAX_NAME_COUNT) { *errorcodeptr = ERR49; goto FAILED; } if (namelen + 3 > cd->name_entry_size) { cd->name_entry_size = namelen + 3; if (namelen > MAX_NAME_SIZE) { *errorcodeptr = ERR48; goto FAILED; } } } /* In the real compile, create the entry in the table */ else { slot = cd->name_table; for (i = 0; i < cd->names_found; i++) { int crc = memcmp(name, slot+2, namelen); if (crc == 0) { if (slot[2+namelen] == 0) { if ((options & PCRE_DUPNAMES) == 0) { *errorcodeptr = ERR43; goto FAILED; } } else crc = -1; /* Current name is substring */ } if (crc < 0) { memmove(slot + cd->name_entry_size, slot, (cd->names_found - i) * cd->name_entry_size); break; } slot += cd->name_entry_size; } PUT2(slot, 0, cd->bracount + 1); memcpy(slot + 2, name, namelen); slot[2+namelen] = 0; } } /* In both cases, count the number of names we've encountered. */ ptr++; /* Move past > or ' */ cd->names_found++; goto NUMBERED_GROUP; /* ------------------------------------------------------------ */ case '&': /* Perl recursion/subroutine syntax */ terminator = ')'; is_recurse = TRUE; /* Fall through */ /* We come here from the Python syntax above that handles both references (?P=name) and recursion (?P>name), as well as falling through from the Perl recursion syntax (?&name). */ NAMED_REF_OR_RECURSE: name = ++ptr; while ((cd->ctypes[*ptr] & ctype_word) != 0) ptr++; namelen = ptr - name; /* In the pre-compile phase, do a syntax check and set a dummy reference number. */ if (lengthptr != NULL) { if (*ptr != terminator) { *errorcodeptr = ERR42; goto FAILED; } if (namelen > MAX_NAME_SIZE) { *errorcodeptr = ERR48; goto FAILED; } recno = 0; } /* In the real compile, seek the name in the table */ else { slot = cd->name_table; for (i = 0; i < cd->names_found; i++) { if (strncmp((char *)name, (char *)slot+2, namelen) == 0) break; slot += cd->name_entry_size; } if (i < cd->names_found) /* Back reference */ { recno = GET2(slot, 0); } else if ((recno = /* Forward back reference */ find_parens(ptr, cd->bracount, name, namelen, (options & PCRE_EXTENDED) != 0)) <= 0) { *errorcodeptr = ERR15; goto FAILED; } } /* In both phases, we can now go to the code than handles numerical recursion or backreferences. */ if (is_recurse) goto HANDLE_RECURSION; else goto HANDLE_REFERENCE; /* ------------------------------------------------------------ */ case 'R': /* Recursion */ ptr++; /* Same as (?0) */ /* Fall through */ /* ------------------------------------------------------------ */ case '-': case '+': case '0': case '1': case '2': case '3': case '4': /* Recursion or */ case '5': case '6': case '7': case '8': case '9': /* subroutine */ { const uschar *called; if ((refsign = *ptr) == '+') ptr++; else if (refsign == '-') { if ((digitab[ptr[1]] & ctype_digit) == 0) goto OTHER_CHAR_AFTER_QUERY; ptr++; } recno = 0; while((digitab[*ptr] & ctype_digit) != 0) recno = recno * 10 + *ptr++ - '0'; if (*ptr != ')') { *errorcodeptr = ERR29; goto FAILED; } if (refsign == '-') { if (recno == 0) { *errorcodeptr = ERR58; goto FAILED; } recno = cd->bracount - recno + 1; if (recno <= 0) { *errorcodeptr = ERR15; goto FAILED; } } else if (refsign == '+') { if (recno == 0) { *errorcodeptr = ERR58; goto FAILED; } recno += cd->bracount; } /* Come here from code above that handles a named recursion */ HANDLE_RECURSION: previous = code; called = cd->start_code; /* When we are actually compiling, find the bracket that is being referenced. Temporarily end the regex in case it doesn't exist before this point. If we end up with a forward reference, first check that the bracket does occur later so we can give the error (and position) now. Then remember this forward reference in the workspace so it can be filled in at the end. */ if (lengthptr == NULL) { *code = OP_END; if (recno != 0) called = find_bracket(cd->start_code, utf8, recno); /* Forward reference */ if (called == NULL) { if (find_parens(ptr, cd->bracount, NULL, recno, (options & PCRE_EXTENDED) != 0) < 0) { *errorcodeptr = ERR15; goto FAILED; } called = cd->start_code + recno; PUTINC(cd->hwm, 0, code + 2 + LINK_SIZE - cd->start_code); } /* If not a forward reference, and the subpattern is still open, this is a recursive call. We check to see if this is a left recursion that could loop for ever, and diagnose that case. */ else if (GET(called, 1) == 0 && could_be_empty(called, code, bcptr, utf8)) { *errorcodeptr = ERR40; goto FAILED; } } /* Insert the recursion/subroutine item, automatically wrapped inside "once" brackets. Set up a "previous group" length so that a subsequent quantifier will work. */ *code = OP_ONCE; PUT(code, 1, 2 + 2*LINK_SIZE); code += 1 + LINK_SIZE; *code = OP_RECURSE; PUT(code, 1, called - cd->start_code); code += 1 + LINK_SIZE; *code = OP_KET; PUT(code, 1, 2 + 2*LINK_SIZE); code += 1 + LINK_SIZE; length_prevgroup = 3 + 3*LINK_SIZE; } /* Can't determine a first byte now */ if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE; continue; /* ------------------------------------------------------------ */ default: /* Other characters: check option setting */ OTHER_CHAR_AFTER_QUERY: set = unset = 0; optset = &set; while (*ptr != ')' && *ptr != ':') { switch (*ptr++) { case '-': optset = &unset; break; case 'J': /* Record that it changed in the external options */ *optset |= PCRE_DUPNAMES; cd->external_options |= PCRE_JCHANGED; break; case 'i': *optset |= PCRE_CASELESS; break; case 'm': *optset |= PCRE_MULTILINE; break; case 's': *optset |= PCRE_DOTALL; break; case 'x': *optset |= PCRE_EXTENDED; break; case 'U': *optset |= PCRE_UNGREEDY; break; case 'X': *optset |= PCRE_EXTRA; break; default: *errorcodeptr = ERR12; ptr--; /* Correct the offset */ goto FAILED; } } /* Set up the changed option bits, but don't change anything yet. */ newoptions = (options | set) & (~unset); /* If the options ended with ')' this is not the start of a nested group with option changes, so the options change at this level. If this item is right at the start of the pattern, the options can be abstracted and made external in the pre-compile phase, and ignored in the compile phase. This can be helpful when matching -- for instance in caseless checking of required bytes. If the code pointer is not (cd->start_code + 1 + LINK_SIZE), we are definitely *not* at the start of the pattern because something has been compiled. In the pre-compile phase, however, the code pointer can have that value after the start, because it gets reset as code is discarded during the pre-compile. However, this can happen only at top level - if we are within parentheses, the starting BRA will still be present. At any parenthesis level, the length value can be used to test if anything has been compiled at that level. Thus, a test for both these conditions is necessary to ensure we correctly detect the start of the pattern in both phases. If we are not at the pattern start, compile code to change the ims options if this setting actually changes any of them. We also pass the new setting back so that it can be put at the start of any following branches, and when this group ends (if we are in a group), a resetting item can be compiled. */ if (*ptr == ')') { if (code == cd->start_code + 1 + LINK_SIZE && (lengthptr == NULL || *lengthptr == 2 + 2*LINK_SIZE)) { cd->external_options = newoptions; options = newoptions; } else { if ((options & PCRE_IMS) != (newoptions & PCRE_IMS)) { *code++ = OP_OPT; *code++ = newoptions & PCRE_IMS; } /* Change options at this level, and pass them back for use in subsequent branches. Reset the greedy defaults and the case value for firstbyte and reqbyte. */ *optionsptr = options = newoptions; greedy_default = ((newoptions & PCRE_UNGREEDY) != 0); greedy_non_default = greedy_default ^ 1; req_caseopt = ((options & PCRE_CASELESS) != 0)? REQ_CASELESS : 0; } previous = NULL; /* This item can't be repeated */ continue; /* It is complete */ } /* If the options ended with ':' we are heading into a nested group with possible change of options. Such groups are non-capturing and are not assertions of any kind. All we need to do is skip over the ':'; the newoptions value is handled below. */ bravalue = OP_BRA; ptr++; } /* End of switch for character following (? */ } /* End of (? handling */ /* Opening parenthesis not followed by '?'. If PCRE_NO_AUTO_CAPTURE is set, all unadorned brackets become non-capturing and behave like (?:...) brackets. */ else if ((options & PCRE_NO_AUTO_CAPTURE) != 0) { bravalue = OP_BRA; } /* Else we have a capturing group. */ else { NUMBERED_GROUP: cd->bracount += 1; PUT2(code, 1+LINK_SIZE, cd->bracount); skipbytes = 2; } /* Process nested bracketed regex. Assertions may not be repeated, but other kinds can be. All their opcodes are >= OP_ONCE. We copy code into a non-register variable in order to be able to pass its address because some compilers complain otherwise. Pass in a new setting for the ims options if they have changed. */ previous = (bravalue >= OP_ONCE)? code : NULL; *code = bravalue; tempcode = code; tempreqvary = cd->req_varyopt; /* Save value before bracket */ length_prevgroup = 0; /* Initialize for pre-compile phase */ if (!compile_regex( newoptions, /* The complete new option state */ options & PCRE_IMS, /* The previous ims option state */ &tempcode, /* Where to put code (updated) */ &ptr, /* Input pointer (updated) */ errorcodeptr, /* Where to put an error message */ (bravalue == OP_ASSERTBACK || bravalue == OP_ASSERTBACK_NOT), /* TRUE if back assert */ reset_bracount, /* True if (?| group */ skipbytes, /* Skip over bracket number */ &subfirstbyte, /* For possible first char */ &subreqbyte, /* For possible last char */ bcptr, /* Current branch chain */ cd, /* Tables block */ (lengthptr == NULL)? NULL : /* Actual compile phase */ &length_prevgroup /* Pre-compile phase */ )) goto FAILED; /* At the end of compiling, code is still pointing to the start of the group, while tempcode has been updated to point past the end of the group and any option resetting that may follow it. The pattern pointer (ptr) is on the bracket. */ /* If this is a conditional bracket, check that there are no more than two branches in the group, or just one if it's a DEFINE group. We do this in the real compile phase, not in the pre-pass, where the whole group may not be available. */ if (bravalue == OP_COND && lengthptr == NULL) { uschar *tc = code; int condcount = 0; do { condcount++; tc += GET(tc,1); } while (*tc != OP_KET); /* A DEFINE group is never obeyed inline (the "condition" is always false). It must have only one branch. */ if (code[LINK_SIZE+1] == OP_DEF) { if (condcount > 1) { *errorcodeptr = ERR54; goto FAILED; } bravalue = OP_DEF; /* Just a flag to suppress char handling below */ } /* A "normal" conditional group. If there is just one branch, we must not make use of its firstbyte or reqbyte, because this is equivalent to an empty second branch. */ else { if (condcount > 2) { *errorcodeptr = ERR27; goto FAILED; } if (condcount == 1) subfirstbyte = subreqbyte = REQ_NONE; } } /* Error if hit end of pattern */ if (*ptr != ')') { *errorcodeptr = ERR14; goto FAILED; } /* In the pre-compile phase, update the length by the length of the group, less the brackets at either end. Then reduce the compiled code to just a set of non-capturing brackets so that it doesn't use much memory if it is duplicated by a quantifier.*/ if (lengthptr != NULL) { if (OFLOW_MAX - *lengthptr < length_prevgroup - 2 - 2*LINK_SIZE) { *errorcodeptr = ERR20; goto FAILED; } *lengthptr += length_prevgroup - 2 - 2*LINK_SIZE; *code++ = OP_BRA; PUTINC(code, 0, 1 + LINK_SIZE); *code++ = OP_KET; PUTINC(code, 0, 1 + LINK_SIZE); break; /* No need to waste time with special character handling */ } /* Otherwise update the main code pointer to the end of the group. */ code = tempcode; /* For a DEFINE group, required and first character settings are not relevant. */ if (bravalue == OP_DEF) break; /* Handle updating of the required and first characters for other types of group. Update for normal brackets of all kinds, and conditions with two branches (see code above). If the bracket is followed by a quantifier with zero repeat, we have to back off. Hence the definition of zeroreqbyte and zerofirstbyte outside the main loop so that they can be accessed for the back off. */ zeroreqbyte = reqbyte; zerofirstbyte = firstbyte; groupsetfirstbyte = FALSE; if (bravalue >= OP_ONCE) { /* If we have not yet set a firstbyte in this branch, take it from the subpattern, remembering that it was set here so that a repeat of more than one can replicate it as reqbyte if necessary. If the subpattern has no firstbyte, set "none" for the whole branch. In both cases, a zero repeat forces firstbyte to "none". */ if (firstbyte == REQ_UNSET) { if (subfirstbyte >= 0) { firstbyte = subfirstbyte; groupsetfirstbyte = TRUE; } else firstbyte = REQ_NONE; zerofirstbyte = REQ_NONE; } /* If firstbyte was previously set, convert the subpattern's firstbyte into reqbyte if there wasn't one, using the vary flag that was in existence beforehand. */ else if (subfirstbyte >= 0 && subreqbyte < 0) subreqbyte = subfirstbyte | tempreqvary; /* If the subpattern set a required byte (or set a first byte that isn't really the first byte - see above), set it. */ if (subreqbyte >= 0) reqbyte = subreqbyte; } /* For a forward assertion, we take the reqbyte, if set. This can be helpful if the pattern that follows the assertion doesn't set a different char. For example, it's useful for /(?=abcde).+/. We can't set firstbyte for an assertion, however because it leads to incorrect effect for patterns such as /(?=a)a.+/ when the "real" "a" would then become a reqbyte instead of a firstbyte. This is overcome by a scan at the end if there's no firstbyte, looking for an asserted first char. */ else if (bravalue == OP_ASSERT && subreqbyte >= 0) reqbyte = subreqbyte; break; /* End of processing '(' */ /* ===================================================================*/ /* Handle metasequences introduced by \. For ones like \d, the ESC_ values are arranged to be the negation of the corresponding OP_values. For the back references, the values are ESC_REF plus the reference number. Only back references and those types that consume a character may be repeated. We can test for values between ESC_b and ESC_Z for the latter; this may have to change if any new ones are ever created. */ case '\\': tempptr = ptr; c = check_escape(&ptr, errorcodeptr, cd->bracount, options, FALSE); if (*errorcodeptr != 0) goto FAILED; if (c < 0) { if (-c == ESC_Q) /* Handle start of quoted string */ { if (ptr[1] == '\\' && ptr[2] == 'E') ptr += 2; /* avoid empty string */ else inescq = TRUE; continue; } if (-c == ESC_E) continue; /* Perl ignores an orphan \E */ /* For metasequences that actually match a character, we disable the setting of a first character if it hasn't already been set. */ if (firstbyte == REQ_UNSET && -c > ESC_b && -c < ESC_Z) firstbyte = REQ_NONE; /* Set values to reset to if this is followed by a zero repeat. */ zerofirstbyte = firstbyte; zeroreqbyte = reqbyte; /* \k or \k'name' is a back reference by name (Perl syntax). We also support \k{name} (.NET syntax) */ if (-c == ESC_k && (ptr[1] == '<' || ptr[1] == '\'' || ptr[1] == '{')) { is_recurse = FALSE; terminator = (*(++ptr) == '<')? '>' : (*ptr == '\'')? '\'' : '}'; goto NAMED_REF_OR_RECURSE; } /* Back references are handled specially; must disable firstbyte if not set to cope with cases like (?=(\w+))\1: which would otherwise set ':' later. */ if (-c >= ESC_REF) { recno = -c - ESC_REF; HANDLE_REFERENCE: /* Come here from named backref handling */ if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE; previous = code; *code++ = OP_REF; PUT2INC(code, 0, recno); cd->backref_map |= (recno < 32)? (1 << recno) : 1; if (recno > cd->top_backref) cd->top_backref = recno; } /* So are Unicode property matches, if supported. */ #ifdef SUPPORT_UCP else if (-c == ESC_P || -c == ESC_p) { BOOL negated; int pdata; int ptype = get_ucp(&ptr, &negated, &pdata, errorcodeptr); if (ptype < 0) goto FAILED; previous = code; *code++ = ((-c == ESC_p) != negated)? OP_PROP : OP_NOTPROP; *code++ = ptype; *code++ = pdata; } #else /* If Unicode properties are not supported, \X, \P, and \p are not allowed. */ else if (-c == ESC_X || -c == ESC_P || -c == ESC_p) { *errorcodeptr = ERR45; goto FAILED; } #endif /* For the rest (including \X when Unicode properties are supported), we can obtain the OP value by negating the escape value. */ else { previous = (-c > ESC_b && -c < ESC_Z)? code : NULL; *code++ = -c; } continue; } /* We have a data character whose value is in c. In UTF-8 mode it may have a value > 127. We set its representation in the length/buffer, and then handle it as a data character. */ #ifdef SUPPORT_UTF8 if (utf8 && c > 127) mclength = _pcre_ord2utf8(c, mcbuffer); else #endif { mcbuffer[0] = c; mclength = 1; } goto ONE_CHAR; /* ===================================================================*/ /* Handle a literal character. It is guaranteed not to be whitespace or # when the extended flag is set. If we are in UTF-8 mode, it may be a multi-byte literal character. */ default: NORMAL_CHAR: mclength = 1; mcbuffer[0] = c; #ifdef SUPPORT_UTF8 if (utf8 && c >= 0xc0) { while ((ptr[1] & 0xc0) == 0x80) mcbuffer[mclength++] = *(++ptr); } #endif /* At this point we have the character's bytes in mcbuffer, and the length in mclength. When not in UTF-8 mode, the length is always 1. */ ONE_CHAR: previous = code; *code++ = ((options & PCRE_CASELESS) != 0)? OP_CHARNC : OP_CHAR; for (c = 0; c < mclength; c++) *code++ = mcbuffer[c]; /* Remember if \r or \n were seen */ if (mcbuffer[0] == '\r' || mcbuffer[0] == '\n') cd->external_options |= PCRE_HASCRORLF; /* Set the first and required bytes appropriately. If no previous first byte, set it from this character, but revert to none on a zero repeat. Otherwise, leave the firstbyte value alone, and don't change it on a zero repeat. */ if (firstbyte == REQ_UNSET) { zerofirstbyte = REQ_NONE; zeroreqbyte = reqbyte; /* If the character is more than one byte long, we can set firstbyte only if it is not to be matched caselessly. */ if (mclength == 1 || req_caseopt == 0) { firstbyte = mcbuffer[0] | req_caseopt; if (mclength != 1) reqbyte = code[-1] | cd->req_varyopt; } else firstbyte = reqbyte = REQ_NONE; } /* firstbyte was previously set; we can set reqbyte only the length is 1 or the matching is caseful. */ else { zerofirstbyte = firstbyte; zeroreqbyte = reqbyte; if (mclength == 1 || req_caseopt == 0) reqbyte = code[-1] | req_caseopt | cd->req_varyopt; } break; /* End of literal character handling */ } } /* end of big loop */ /* Control never reaches here by falling through, only by a goto for all the error states. Pass back the position in the pattern so that it can be displayed to the user for diagnosing the error. */ FAILED: *ptrptr = ptr; return FALSE; } /************************************************* * Compile sequence of alternatives * *************************************************/ /* On entry, ptr is pointing past the bracket character, but on return it points to the closing bracket, or vertical bar, or end of string. The code variable is pointing at the byte into which the BRA operator has been stored. If the ims options are changed at the start (for a (?ims: group) or during any branch, we need to insert an OP_OPT item at the start of every following branch to ensure they get set correctly at run time, and also pass the new options into every subsequent branch compile. This function is used during the pre-compile phase when we are trying to find out the amount of memory needed, as well as during the real compile phase. The value of lengthptr distinguishes the two phases. Arguments: options option bits, including any changes for this subpattern oldims previous settings of ims option bits codeptr -> the address of the current code pointer ptrptr -> the address of the current pattern pointer errorcodeptr -> pointer to error code variable lookbehind TRUE if this is a lookbehind assertion reset_bracount TRUE to reset the count for each branch skipbytes skip this many bytes at start (for brackets and OP_COND) firstbyteptr place to put the first required character, or a negative number reqbyteptr place to put the last required character, or a negative number bcptr pointer to the chain of currently open branches cd points to the data block with tables pointers etc. lengthptr NULL during the real compile phase points to length accumulator during pre-compile phase Returns: TRUE on success */ static BOOL compile_regex(int options, int oldims, uschar **codeptr, const uschar **ptrptr, int *errorcodeptr, BOOL lookbehind, BOOL reset_bracount, int skipbytes, int *firstbyteptr, int *reqbyteptr, branch_chain *bcptr, compile_data *cd, int *lengthptr) { const uschar *ptr = *ptrptr; uschar *code = *codeptr; uschar *last_branch = code; uschar *start_bracket = code; uschar *reverse_count = NULL; int firstbyte, reqbyte; int branchfirstbyte, branchreqbyte; int length; int orig_bracount; int max_bracount; branch_chain bc; bc.outer = bcptr; bc.current = code; firstbyte = reqbyte = REQ_UNSET; /* Accumulate the length for use in the pre-compile phase. Start with the length of the BRA and KET and any extra bytes that are required at the beginning. We accumulate in a local variable to save frequent testing of lenthptr for NULL. We cannot do this by looking at the value of code at the start and end of each alternative, because compiled items are discarded during the pre-compile phase so that the work space is not exceeded. */ length = 2 + 2*LINK_SIZE + skipbytes; /* WARNING: If the above line is changed for any reason, you must also change the code that abstracts option settings at the start of the pattern and makes them global. It tests the value of length for (2 + 2*LINK_SIZE) in the pre-compile phase to find out whether anything has yet been compiled or not. */ /* Offset is set zero to mark that this bracket is still open */ PUT(code, 1, 0); code += 1 + LINK_SIZE + skipbytes; /* Loop for each alternative branch */ orig_bracount = max_bracount = cd->bracount; for (;;) { /* For a (?| group, reset the capturing bracket count so that each branch uses the same numbers. */ if (reset_bracount) cd->bracount = orig_bracount; /* Handle a change of ims options at the start of the branch */ if ((options & PCRE_IMS) != oldims) { *code++ = OP_OPT; *code++ = options & PCRE_IMS; length += 2; } /* Set up dummy OP_REVERSE if lookbehind assertion */ if (lookbehind) { *code++ = OP_REVERSE; reverse_count = code; PUTINC(code, 0, 0); length += 1 + LINK_SIZE; } /* Now compile the branch; in the pre-compile phase its length gets added into the length. */ if (!compile_branch(&options, &code, &ptr, errorcodeptr, &branchfirstbyte, &branchreqbyte, &bc, cd, (lengthptr == NULL)? NULL : &length)) { *ptrptr = ptr; return FALSE; } /* Keep the highest bracket count in case (?| was used and some branch has fewer than the rest. */ if (cd->bracount > max_bracount) max_bracount = cd->bracount; /* In the real compile phase, there is some post-processing to be done. */ if (lengthptr == NULL) { /* If this is the first branch, the firstbyte and reqbyte values for the branch become the values for the regex. */ if (*last_branch != OP_ALT) { firstbyte = branchfirstbyte; reqbyte = branchreqbyte; } /* If this is not the first branch, the first char and reqbyte have to match the values from all the previous branches, except that if the previous value for reqbyte didn't have REQ_VARY set, it can still match, and we set REQ_VARY for the regex. */ else { /* If we previously had a firstbyte, but it doesn't match the new branch, we have to abandon the firstbyte for the regex, but if there was previously no reqbyte, it takes on the value of the old firstbyte. */ if (firstbyte >= 0 && firstbyte != branchfirstbyte) { if (reqbyte < 0) reqbyte = firstbyte; firstbyte = REQ_NONE; } /* If we (now or from before) have no firstbyte, a firstbyte from the branch becomes a reqbyte if there isn't a branch reqbyte. */ if (firstbyte < 0 && branchfirstbyte >= 0 && branchreqbyte < 0) branchreqbyte = branchfirstbyte; /* Now ensure that the reqbytes match */ if ((reqbyte & ~REQ_VARY) != (branchreqbyte & ~REQ_VARY)) reqbyte = REQ_NONE; else reqbyte |= branchreqbyte; /* To "or" REQ_VARY */ } /* If lookbehind, check that this branch matches a fixed-length string, and put the length into the OP_REVERSE item. Temporarily mark the end of the branch with OP_END. */ if (lookbehind) { int fixed_length; *code = OP_END; fixed_length = find_fixedlength(last_branch, options); DPRINTF(("fixed length = %d\n", fixed_length)); if (fixed_length < 0) { *errorcodeptr = (fixed_length == -2)? ERR36 : ERR25; *ptrptr = ptr; return FALSE; } PUT(reverse_count, 0, fixed_length); } } /* Reached end of expression, either ')' or end of pattern. In the real compile phase, go back through the alternative branches and reverse the chain of offsets, with the field in the BRA item now becoming an offset to the first alternative. If there are no alternatives, it points to the end of the group. The length in the terminating ket is always the length of the whole bracketed item. If any of the ims options were changed inside the group, compile a resetting op-code following, except at the very end of the pattern. Return leaving the pointer at the terminating char. */ if (*ptr != '|') { if (lengthptr == NULL) { int branch_length = code - last_branch; do { int prev_length = GET(last_branch, 1); PUT(last_branch, 1, branch_length); branch_length = prev_length; last_branch -= branch_length; } while (branch_length > 0); } /* Fill in the ket */ *code = OP_KET; PUT(code, 1, code - start_bracket); code += 1 + LINK_SIZE; /* Resetting option if needed */ if ((options & PCRE_IMS) != oldims && *ptr == ')') { *code++ = OP_OPT; *code++ = oldims; length += 2; } /* Retain the highest bracket number, in case resetting was used. */ cd->bracount = max_bracount; /* Set values to pass back */ *codeptr = code; *ptrptr = ptr; *firstbyteptr = firstbyte; *reqbyteptr = reqbyte; if (lengthptr != NULL) { if (OFLOW_MAX - *lengthptr < length) { *errorcodeptr = ERR20; return FALSE; } *lengthptr += length; } return TRUE; } /* Another branch follows. In the pre-compile phase, we can move the code pointer back to where it was for the start of the first branch. (That is, pretend that each branch is the only one.) In the real compile phase, insert an ALT node. Its length field points back to the previous branch while the bracket remains open. At the end the chain is reversed. It's done like this so that the start of the bracket has a zero offset until it is closed, making it possible to detect recursion. */ if (lengthptr != NULL) { code = *codeptr + 1 + LINK_SIZE + skipbytes; length += 1 + LINK_SIZE; } else { *code = OP_ALT; PUT(code, 1, code - last_branch); bc.current = last_branch = code; code += 1 + LINK_SIZE; } ptr++; } /* Control never reaches here */ } /************************************************* * Check for anchored expression * *************************************************/ /* Try to find out if this is an anchored regular expression. Consider each alternative branch. If they all start with OP_SOD or OP_CIRC, or with a bracket all of whose alternatives start with OP_SOD or OP_CIRC (recurse ad lib), then it's anchored. However, if this is a multiline pattern, then only OP_SOD counts, since OP_CIRC can match in the middle. We can also consider a regex to be anchored if OP_SOM starts all its branches. This is the code for \G, which means "match at start of match position, taking into account the match offset". A branch is also implicitly anchored if it starts with .* and DOTALL is set, because that will try the rest of the pattern at all possible matching points, so there is no point trying again.... er .... .... except when the .* appears inside capturing parentheses, and there is a subsequent back reference to those parentheses. We haven't enough information to catch that case precisely. At first, the best we could do was to detect when .* was in capturing brackets and the highest back reference was greater than or equal to that level. However, by keeping a bitmap of the first 31 back references, we can catch some of the more common cases more precisely. Arguments: code points to start of expression (the bracket) options points to the options setting bracket_map a bitmap of which brackets we are inside while testing; this handles up to substring 31; after that we just have to take the less precise approach backref_map the back reference bitmap Returns: TRUE or FALSE */ static BOOL is_anchored(register const uschar *code, int *options, unsigned int bracket_map, unsigned int backref_map) { do { const uschar *scode = first_significant_code(code + _pcre_OP_lengths[*code], options, PCRE_MULTILINE, FALSE); register int op = *scode; /* Non-capturing brackets */ if (op == OP_BRA) { if (!is_anchored(scode, options, bracket_map, backref_map)) return FALSE; } /* Capturing brackets */ else if (op == OP_CBRA) { int n = GET2(scode, 1+LINK_SIZE); int new_map = bracket_map | ((n < 32)? (1 << n) : 1); if (!is_anchored(scode, options, new_map, backref_map)) return FALSE; } /* Other brackets */ else if (op == OP_ASSERT || op == OP_ONCE || op == OP_COND) { if (!is_anchored(scode, options, bracket_map, backref_map)) return FALSE; } /* .* is not anchored unless DOTALL is set and it isn't in brackets that are or may be referenced. */ else if ((op == OP_TYPESTAR || op == OP_TYPEMINSTAR || op == OP_TYPEPOSSTAR) && (*options & PCRE_DOTALL) != 0) { if (scode[1] != OP_ANY || (bracket_map & backref_map) != 0) return FALSE; } /* Check for explicit anchoring */ else if (op != OP_SOD && op != OP_SOM && ((*options & PCRE_MULTILINE) != 0 || op != OP_CIRC)) return FALSE; code += GET(code, 1); } while (*code == OP_ALT); /* Loop for each alternative */ return TRUE; } /************************************************* * Check for starting with ^ or .* * *************************************************/ /* This is called to find out if every branch starts with ^ or .* so that "first char" processing can be done to speed things up in multiline matching and for non-DOTALL patterns that start with .* (which must start at the beginning or after \n). As in the case of is_anchored() (see above), we have to take account of back references to capturing brackets that contain .* because in that case we can't make the assumption. Arguments: code points to start of expression (the bracket) bracket_map a bitmap of which brackets we are inside while testing; this handles up to substring 31; after that we just have to take the less precise approach backref_map the back reference bitmap Returns: TRUE or FALSE */ static BOOL is_startline(const uschar *code, unsigned int bracket_map, unsigned int backref_map) { do { const uschar *scode = first_significant_code(code + _pcre_OP_lengths[*code], NULL, 0, FALSE); register int op = *scode; /* Non-capturing brackets */ if (op == OP_BRA) { if (!is_startline(scode, bracket_map, backref_map)) return FALSE; } /* Capturing brackets */ else if (op == OP_CBRA) { int n = GET2(scode, 1+LINK_SIZE); int new_map = bracket_map | ((n < 32)? (1 << n) : 1); if (!is_startline(scode, new_map, backref_map)) return FALSE; } /* Other brackets */ else if (op == OP_ASSERT || op == OP_ONCE || op == OP_COND) { if (!is_startline(scode, bracket_map, backref_map)) return FALSE; } /* .* means "start at start or after \n" if it isn't in brackets that may be referenced. */ else if (op == OP_TYPESTAR || op == OP_TYPEMINSTAR || op == OP_TYPEPOSSTAR) { if (scode[1] != OP_ANY || (bracket_map & backref_map) != 0) return FALSE; } /* Check for explicit circumflex */ else if (op != OP_CIRC) return FALSE; /* Move on to the next alternative */ code += GET(code, 1); } while (*code == OP_ALT); /* Loop for each alternative */ return TRUE; } /************************************************* * Check for asserted fixed first char * *************************************************/ /* During compilation, the "first char" settings from forward assertions are discarded, because they can cause conflicts with actual literals that follow. However, if we end up without a first char setting for an unanchored pattern, it is worth scanning the regex to see if there is an initial asserted first char. If all branches start with the same asserted char, or with a bracket all of whose alternatives start with the same asserted char (recurse ad lib), then we return that char, otherwise -1. Arguments: code points to start of expression (the bracket) options pointer to the options (used to check casing changes) inassert TRUE if in an assertion Returns: -1 or the fixed first char */ static int find_firstassertedchar(const uschar *code, int *options, BOOL inassert) { register int c = -1; do { int d; const uschar *scode = first_significant_code(code + 1+LINK_SIZE, options, PCRE_CASELESS, TRUE); register int op = *scode; switch(op) { default: return -1; case OP_BRA: case OP_CBRA: case OP_ASSERT: case OP_ONCE: case OP_COND: if ((d = find_firstassertedchar(scode, options, op == OP_ASSERT)) < 0) return -1; if (c < 0) c = d; else if (c != d) return -1; break; case OP_EXACT: /* Fall through */ scode += 2; case OP_CHAR: case OP_CHARNC: case OP_PLUS: case OP_MINPLUS: case OP_POSPLUS: if (!inassert) return -1; if (c < 0) { c = scode[1]; if ((*options & PCRE_CASELESS) != 0) c |= REQ_CASELESS; } else if (c != scode[1]) return -1; break; } code += GET(code, 1); } while (*code == OP_ALT); return c; } /************************************************* * Compile a Regular Expression * *************************************************/ /* This function takes a string and returns a pointer to a block of store holding a compiled version of the expression. The original API for this function had no error code return variable; it is retained for backwards compatibility. The new function is given a new name. Arguments: pattern the regular expression options various option bits errorcodeptr pointer to error code variable (pcre_compile2() only) can be NULL if you don't want a code value errorptr pointer to pointer to error text erroroffset ptr offset in pattern where error was detected tables pointer to character tables or NULL Returns: pointer to compiled data block, or NULL on error, with errorptr and erroroffset set */ PCRE_EXP_DEFN pcre * pcre_compile(const char *pattern, int options, const char **errorptr, int *erroroffset, const unsigned char *tables) { return pcre_compile2(pattern, options, NULL, errorptr, erroroffset, tables); } PCRE_EXP_DEFN pcre * pcre_compile2(const char *pattern, int options, int *errorcodeptr, const char **errorptr, int *erroroffset, const unsigned char *tables) { real_pcre *re; int length = 1; /* For final END opcode */ int firstbyte, reqbyte, newline; int errorcode = 0; int skipatstart = 0; #ifdef SUPPORT_UTF8 BOOL utf8; #endif size_t size; uschar *code; const uschar *codestart; const uschar *ptr; compile_data compile_block; compile_data *cd = &compile_block; /* This space is used for "compiling" into during the first phase, when we are computing the amount of memory that is needed. Compiled items are thrown away as soon as possible, so that a fairly large buffer should be sufficient for this purpose. The same space is used in the second phase for remembering where to fill in forward references to subpatterns. */ uschar cworkspace[COMPILE_WORK_SIZE]; /* Set this early so that early errors get offset 0. */ ptr = (const uschar *)pattern; /* We can't pass back an error message if errorptr is NULL; I guess the best we can do is just return NULL, but we can set a code value if there is a code pointer. */ if (errorptr == NULL) { if (errorcodeptr != NULL) *errorcodeptr = 99; return NULL; } *errorptr = NULL; if (errorcodeptr != NULL) *errorcodeptr = ERR0; /* However, we can give a message for this error */ if (erroroffset == NULL) { errorcode = ERR16; goto PCRE_EARLY_ERROR_RETURN2; } *erroroffset = 0; /* Can't support UTF8 unless PCRE has been compiled to include the code. */ #ifdef SUPPORT_UTF8 utf8 = (options & PCRE_UTF8) != 0; if (utf8 && (options & PCRE_NO_UTF8_CHECK) == 0 && (*erroroffset = _pcre_valid_utf8((uschar *)pattern, -1)) >= 0) { errorcode = ERR44; goto PCRE_EARLY_ERROR_RETURN2; } #else if ((options & PCRE_UTF8) != 0) { errorcode = ERR32; goto PCRE_EARLY_ERROR_RETURN; } #endif if ((options & ~PUBLIC_OPTIONS) != 0) { errorcode = ERR17; goto PCRE_EARLY_ERROR_RETURN; } /* Set up pointers to the individual character tables */ if (tables == NULL) tables = _pcre_default_tables; cd->lcc = tables + lcc_offset; cd->fcc = tables + fcc_offset; cd->cbits = tables + cbits_offset; cd->ctypes = tables + ctypes_offset; /* Check for newline settings at the start of the pattern, and remember the offset for later. */ if (ptr[0] == '(' && ptr[1] == '*') { int newnl = 0; if (strncmp((char *)(ptr+2), "CR)", 3) == 0) { skipatstart = 5; newnl = PCRE_NEWLINE_CR; } else if (strncmp((char *)(ptr+2), "LF)", 3) == 0) { skipatstart = 5; newnl = PCRE_NEWLINE_LF; } else if (strncmp((char *)(ptr+2), "CRLF)", 5) == 0) { skipatstart = 7; newnl = PCRE_NEWLINE_CR + PCRE_NEWLINE_LF; } else if (strncmp((char *)(ptr+2), "ANY)", 4) == 0) { skipatstart = 6; newnl = PCRE_NEWLINE_ANY; } else if (strncmp((char *)(ptr+2), "ANYCRLF)", 8) == 0) { skipatstart = 10; newnl = PCRE_NEWLINE_ANYCRLF; } if (skipatstart > 0) options = (options & ~PCRE_NEWLINE_BITS) | newnl; } /* Handle different types of newline. The three bits give seven cases. The current code allows for fixed one- or two-byte sequences, plus "any" and "anycrlf". */ switch (options & PCRE_NEWLINE_BITS) { case 0: newline = NEWLINE; break; /* Build-time default */ case PCRE_NEWLINE_CR: newline = '\r'; break; case PCRE_NEWLINE_LF: newline = '\n'; break; case PCRE_NEWLINE_CR+ PCRE_NEWLINE_LF: newline = ('\r' << 8) | '\n'; break; case PCRE_NEWLINE_ANY: newline = -1; break; case PCRE_NEWLINE_ANYCRLF: newline = -2; break; default: errorcode = ERR56; goto PCRE_EARLY_ERROR_RETURN; } if (newline == -2) { cd->nltype = NLTYPE_ANYCRLF; } else if (newline < 0) { cd->nltype = NLTYPE_ANY; } else { cd->nltype = NLTYPE_FIXED; if (newline > 255) { cd->nllen = 2; cd->nl[0] = (newline >> 8) & 255; cd->nl[1] = newline & 255; } else { cd->nllen = 1; cd->nl[0] = newline; } } /* Maximum back reference and backref bitmap. The bitmap records up to 31 back references to help in deciding whether (.*) can be treated as anchored or not. */ cd->top_backref = 0; cd->backref_map = 0; /* Reflect pattern for debugging output */ DPRINTF(("------------------------------------------------------------------\n")); DPRINTF(("%s\n", pattern)); /* Pretend to compile the pattern while actually just accumulating the length of memory required. This behaviour is triggered by passing a non-NULL final argument to compile_regex(). We pass a block of workspace (cworkspace) for it to compile parts of the pattern into; the compiled code is discarded when it is no longer needed, so hopefully this workspace will never overflow, though there is a test for its doing so. */ cd->bracount = 0; cd->names_found = 0; cd->name_entry_size = 0; cd->name_table = NULL; cd->start_workspace = cworkspace; cd->start_code = cworkspace; cd->hwm = cworkspace; cd->start_pattern = (const uschar *)pattern; cd->end_pattern = (const uschar *)(pattern + strlen(pattern)); cd->req_varyopt = 0; cd->nopartial = FALSE; cd->external_options = options; /* Now do the pre-compile. On error, errorcode will be set non-zero, so we don't need to look at the result of the function here. The initial options have been put into the cd block so that they can be changed if an option setting is found within the regex right at the beginning. Bringing initial option settings outside can help speed up starting point checks. */ ptr += skipatstart; code = cworkspace; *code = OP_BRA; (void)compile_regex(cd->external_options, cd->external_options & PCRE_IMS, &code, &ptr, &errorcode, FALSE, FALSE, 0, &firstbyte, &reqbyte, NULL, cd, &length); if (errorcode != 0) goto PCRE_EARLY_ERROR_RETURN; DPRINTF(("end pre-compile: length=%d workspace=%d\n", length, cd->hwm - cworkspace)); if (length > MAX_PATTERN_SIZE) { errorcode = ERR20; goto PCRE_EARLY_ERROR_RETURN; } /* Compute the size of data block needed and get it, either from malloc or externally provided function. Integer overflow should no longer be possible because nowadays we limit the maximum value of cd->names_found and cd->name_entry_size. */ size = length + sizeof(real_pcre) + cd->names_found * (cd->name_entry_size + 3); re = (real_pcre *)(pcre_malloc)(size); if (re == NULL) { errorcode = ERR21; goto PCRE_EARLY_ERROR_RETURN; } /* Put in the magic number, and save the sizes, initial options, and character table pointer. NULL is used for the default character tables. The nullpad field is at the end; it's there to help in the case when a regex compiled on a system with 4-byte pointers is run on another with 8-byte pointers. */ re->magic_number = MAGIC_NUMBER; re->size = size; re->options = cd->external_options; re->dummy1 = 0; re->first_byte = 0; re->req_byte = 0; re->name_table_offset = sizeof(real_pcre); re->name_entry_size = cd->name_entry_size; re->name_count = cd->names_found; re->ref_count = 0; re->tables = (tables == _pcre_default_tables)? NULL : tables; re->nullpad = NULL; /* The starting points of the name/number translation table and of the code are passed around in the compile data block. The start/end pattern and initial options are already set from the pre-compile phase, as is the name_entry_size field. Reset the bracket count and the names_found field. Also reset the hwm field; this time it's used for remembering forward references to subpatterns. */ cd->bracount = 0; cd->names_found = 0; cd->name_table = (uschar *)re + re->name_table_offset; codestart = cd->name_table + re->name_entry_size * re->name_count; cd->start_code = codestart; cd->hwm = cworkspace; cd->req_varyopt = 0; cd->nopartial = FALSE; cd->had_accept = FALSE; /* Set up a starting, non-extracting bracket, then compile the expression. On error, errorcode will be set non-zero, so we don't need to look at the result of the function here. */ ptr = (const uschar *)pattern + skipatstart; code = (uschar *)codestart; *code = OP_BRA; (void)compile_regex(re->options, re->options & PCRE_IMS, &code, &ptr, &errorcode, FALSE, FALSE, 0, &firstbyte, &reqbyte, NULL, cd, NULL); re->top_bracket = cd->bracount; re->top_backref = cd->top_backref; if (cd->nopartial) re->options |= PCRE_NOPARTIAL; if (cd->had_accept) reqbyte = -1; /* Must disable after (*ACCEPT) */ /* If not reached end of pattern on success, there's an excess bracket. */ if (errorcode == 0 && *ptr != 0) errorcode = ERR22; /* Fill in the terminating state and check for disastrous overflow, but if debugging, leave the test till after things are printed out. */ *code++ = OP_END; #ifndef DEBUG if (code - codestart > length) errorcode = ERR23; #endif /* Fill in any forward references that are required. */ while (errorcode == 0 && cd->hwm > cworkspace) { int offset, recno; const uschar *groupptr; cd->hwm -= LINK_SIZE; offset = GET(cd->hwm, 0); recno = GET(codestart, offset); groupptr = find_bracket(codestart, (re->options & PCRE_UTF8) != 0, recno); if (groupptr == NULL) errorcode = ERR53; else PUT(((uschar *)codestart), offset, groupptr - codestart); } /* Give an error if there's back reference to a non-existent capturing subpattern. */ if (errorcode == 0 && re->top_backref > re->top_bracket) errorcode = ERR15; /* Failed to compile, or error while post-processing */ if (errorcode != 0) { (pcre_free)(re); PCRE_EARLY_ERROR_RETURN: *erroroffset = ptr - (const uschar *)pattern; PCRE_EARLY_ERROR_RETURN2: *errorptr = error_texts[errorcode]; if (errorcodeptr != NULL) *errorcodeptr = errorcode; return NULL; } /* If the anchored option was not passed, set the flag if we can determine that the pattern is anchored by virtue of ^ characters or \A or anything else (such as starting with .* when DOTALL is set). Otherwise, if we know what the first byte has to be, save it, because that speeds up unanchored matches no end. If not, see if we can set the PCRE_STARTLINE flag. This is helpful for multiline matches when all branches start with ^. and also when all branches start with .* for non-DOTALL matches. */ if ((re->options & PCRE_ANCHORED) == 0) { int temp_options = re->options; /* May get changed during these scans */ if (is_anchored(codestart, &temp_options, 0, cd->backref_map)) re->options |= PCRE_ANCHORED; else { if (firstbyte < 0) firstbyte = find_firstassertedchar(codestart, &temp_options, FALSE); if (firstbyte >= 0) /* Remove caseless flag for non-caseable chars */ { int ch = firstbyte & 255; re->first_byte = ((firstbyte & REQ_CASELESS) != 0 && cd->fcc[ch] == ch)? ch : firstbyte; re->options |= PCRE_FIRSTSET; } else if (is_startline(codestart, 0, cd->backref_map)) re->options |= PCRE_STARTLINE; } } /* For an anchored pattern, we use the "required byte" only if it follows a variable length item in the regex. Remove the caseless flag for non-caseable bytes. */ if (reqbyte >= 0 && ((re->options & PCRE_ANCHORED) == 0 || (reqbyte & REQ_VARY) != 0)) { int ch = reqbyte & 255; re->req_byte = ((reqbyte & REQ_CASELESS) != 0 && cd->fcc[ch] == ch)? (reqbyte & ~REQ_CASELESS) : reqbyte; re->options |= PCRE_REQCHSET; } /* Print out the compiled data if debugging is enabled. This is never the case when building a production library. */ #ifdef DEBUG printf("Length = %d top_bracket = %d top_backref = %d\n", length, re->top_bracket, re->top_backref); printf("Options=%08x\n", re->options); if ((re->options & PCRE_FIRSTSET) != 0) { int ch = re->first_byte & 255; const char *caseless = ((re->first_byte & REQ_CASELESS) == 0)? "" : " (caseless)"; if (isprint(ch)) printf("First char = %c%s\n", ch, caseless); else printf("First char = \\x%02x%s\n", ch, caseless); } if ((re->options & PCRE_REQCHSET) != 0) { int ch = re->req_byte & 255; const char *caseless = ((re->req_byte & REQ_CASELESS) == 0)? "" : " (caseless)"; if (isprint(ch)) printf("Req char = %c%s\n", ch, caseless); else printf("Req char = \\x%02x%s\n", ch, caseless); } pcre_printint(re, stdout, TRUE); /* This check is done here in the debugging case so that the code that was compiled can be seen. */ if (code - codestart > length) { (pcre_free)(re); *errorptr = error_texts[ERR23]; *erroroffset = ptr - (uschar *)pattern; if (errorcodeptr != NULL) *errorcodeptr = ERR23; return NULL; } #endif /* DEBUG */ return (pcre *)re; } /* End of pcre_compile.c */ libsynthesis-3.4.0.47.1/src/pcre/pcre_config.c000066400000000000000000000067071226375725500210200ustar00rootroot00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2007 University of Cambridge ----------------------------------------------------------------------------- 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 name of the University of Cambridge 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. ----------------------------------------------------------------------------- */ /* This module contains the external function pcre_config(). */ #include "pcre_setup.h" #include "pcre_internal.h" /************************************************* * Return info about what features are configured * *************************************************/ /* This function has an extensible interface so that additional items can be added compatibly. Arguments: what what information is required where where to put the information Returns: 0 if data returned, negative on error */ PCRE_EXP_DEFN int pcre_config(int what, void *where) { switch (what) { case PCRE_CONFIG_UTF8: #ifdef SUPPORT_UTF8 *((int *)where) = 1; #else *((int *)where) = 0; #endif break; case PCRE_CONFIG_UNICODE_PROPERTIES: #ifdef SUPPORT_UCP *((int *)where) = 1; #else *((int *)where) = 0; #endif break; case PCRE_CONFIG_NEWLINE: *((int *)where) = NEWLINE; break; case PCRE_CONFIG_LINK_SIZE: *((int *)where) = LINK_SIZE; break; case PCRE_CONFIG_POSIX_MALLOC_THRESHOLD: *((int *)where) = POSIX_MALLOC_THRESHOLD; break; case PCRE_CONFIG_MATCH_LIMIT: *((unsigned int *)where) = MATCH_LIMIT; break; case PCRE_CONFIG_MATCH_LIMIT_RECURSION: *((unsigned int *)where) = MATCH_LIMIT_RECURSION; break; case PCRE_CONFIG_STACKRECURSE: #ifdef NO_RECURSE *((int *)where) = 0; #else *((int *)where) = 1; #endif break; default: return PCRE_ERROR_BADOPTION; } return 0; } /* End of pcre_config.c */ libsynthesis-3.4.0.47.1/src/pcre/pcre_config_android.h000066400000000000000000000220521226375725500225140ustar00rootroot00000000000000/* config-win32.h. Manually adapted for Android compiling */ /* On Unix-like systems config.h.in is converted by "configure" into config.h. Some other environments also support the use of "configure". PCRE is written in Standard C, but there are a few non-standard things it can cope with, allowing it to run on SunOS4 and other "close to standard" systems. If you are going to build PCRE "by hand" on a system without "configure" you should copy the distributed config.h.generic to config.h, and then set up the macros the way you need them. Alternatively, you can avoid editing by using -D on the compiler command line to set the macro values. PCRE uses memmove() if HAVE_MEMMOVE is set to 1; otherwise it uses bcopy() if HAVE_BCOPY is set to 1. If your system has neither bcopy() nor memmove(), set them both to 0; an emulation function will be used. */ /* If you are compiling for a system that uses EBCDIC instead of ASCII character codes, define this macro as 1. On systems that can use "configure", this can be done via --enable-ebcdic. */ /* #undef EBCDIC */ /* Define to 1 if you have the `bcopy' function. */ #ifndef HAVE_BCOPY #define HAVE_BCOPY 0 // MWerks CW 9 Win MSL does not seem to have it #endif /* Define to 1 if you have the header file. */ /* #undef HAVE_BITS_TYPE_TRAITS_H */ /* Define to 1 if you have the header file. */ #ifndef HAVE_DIRENT_H #define HAVE_DIRENT_H 0 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_DLFCN_H #define HAVE_DLFCN_H 0 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_INTTYPES_H #define HAVE_INTTYPES_H 1 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_LIMITS_H #define HAVE_LIMITS_H 1 #endif /* Define to 1 if the system has the type `long long'. */ #ifndef HAVE_LONG_LONG #define HAVE_LONG_LONG 1 #endif /* Define to 1 if you have the `memmove' function. */ #ifndef HAVE_MEMMOVE #define HAVE_MEMMOVE 1 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_MEMORY_H #define HAVE_MEMORY_H 0 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_STDINT_H #define HAVE_STDINT_H 1 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_STDLIB_H #define HAVE_STDLIB_H 1 #endif /* Define to 1 if you have the `strerror' function. */ #ifndef HAVE_STRERROR #define HAVE_STRERROR 1 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_STRING #define HAVE_STRING 1 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_STRINGS_H #define HAVE_STRINGS_H 0 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_STRING_H #define HAVE_STRING_H 1 #endif /* Define to 1 if you have the `strtoll' function. */ #ifndef HAVE_STRTOLL #define HAVE_STRTOLL 0 #endif /* Define to 1 if you have the `strtoq' function. */ #ifndef HAVE_STRTOQ #define HAVE_STRTOQ 0 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_SYS_STAT_H #define HAVE_SYS_STAT_H 0 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_SYS_TYPES_H #define HAVE_SYS_TYPES_H 0 #endif /* Define to 1 if you have the header file. */ /* #undef HAVE_TYPE_TRAITS_H */ /* Define to 1 if you have the header file. */ #ifndef HAVE_UNISTD_H #define HAVE_UNISTD_H 0 #endif /* Define to 1 if the system has the type `unsigned long long'. */ #ifndef HAVE_UNSIGNED_LONG_LONG #define HAVE_UNSIGNED_LONG_LONG 1 #endif /* Define to 1 if you have the header file. */ /* #undef HAVE_WINDOWS_H */ /* The value of LINK_SIZE determines the number of bytes used to store links as offsets within the compiled regex. The default is 2, which allows for compiled patterns up to 64K long. This covers the vast majority of cases. However, PCRE can also be compiled to use 3 or 4 bytes instead. This allows for longer patterns in extreme cases. On systems that support it, "configure" can be used to override this default. */ #ifndef LINK_SIZE #define LINK_SIZE 2 #endif /* The value of MATCH_LIMIT determines the default number of times the internal match() function can be called during a single execution of pcre_exec(). There is a runtime interface for setting a different limit. The limit exists in order to catch runaway regular expressions that take for ever to determine that they do not match. The default is set very large so that it does not accidentally catch legitimate cases. On systems that support it, "configure" can be used to override this default default. */ #ifndef MATCH_LIMIT #define MATCH_LIMIT 10000000 #endif /* The above limit applies to all calls of match(), whether or not they increase the recursion depth. In some environments it is desirable to limit the depth of recursive calls of match() more strictly, in order to restrict the maximum amount of stack (or heap, if NO_RECURSE is defined) that is used. The value of MATCH_LIMIT_RECURSION applies only to recursive calls of match(). To have any useful effect, it must be less than the value of MATCH_LIMIT. The default is to use the same value as MATCH_LIMIT. There is a runtime method for setting a different limit. On systems that support it, "configure" can be used to override the default. */ #ifndef MATCH_LIMIT_RECURSION #define MATCH_LIMIT_RECURSION MATCH_LIMIT #endif /* This limit is parameterized just in case anybody ever wants to change it. Care must be taken if it is increased, because it guards against integer overflow caused by enormously large patterns. */ #ifndef MAX_NAME_COUNT #define MAX_NAME_COUNT 10000 #endif /* This limit is parameterized just in case anybody ever wants to change it. Care must be taken if it is increased, because it guards against integer overflow caused by enormously large patterns. */ #ifndef MAX_NAME_SIZE #define MAX_NAME_SIZE 32 #endif /* The value of NEWLINE determines the newline character sequence. On Unix-like systems, "configure" can be used to override the default, which is 10. The possible values are 10 (LF), 13 (CR), 3338 (CRLF), -1 (ANY), or -2 (ANYCRLF). */ #ifndef NEWLINE #define NEWLINE 10 #endif /* PCRE uses recursive function calls to handle backtracking while matching. This can sometimes be a problem on systems that have stacks of limited size. Define NO_RECURSE to get a version that doesn't use recursion in the match() function; instead it creates its own stack by steam using pcre_recurse_malloc() to obtain memory from the heap. For more detail, see the comments and other stuff just above the match() function. On systems that support it, "configure" can be used to set this in the Makefile (use --disable-stack-for-recursion). */ /* #undef NO_RECURSE */ /* Name of package */ #define PACKAGE "pcre" /* Define to the address where bug reports for this package should be sent. */ #define PACKAGE_BUGREPORT "" /* Define to the full name of this package. */ #define PACKAGE_NAME "PCRE" /* Define to the full name and version of this package. */ #define PACKAGE_STRING "PCRE 7.3" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "pcre" /* Define to the version of this package. */ #define PACKAGE_VERSION "7.3" /* If you are compiling for a system other than a Unix-like system or Win32, and it needs some magic to be inserted before the definition of a function that is exported by the library, define this macro to contain the relevant magic. If you do not define this macro, it defaults to "extern" for a C compiler and "extern C" for a C++ compiler on non-Win32 systems. This macro apears at the start of every exported function that is part of the external API. It does not appear on functions that are "external" in the C sense, but which are internal to the library. */ /* #undef PCRE_EXP_DEFN */ /* Define if linking statically (TODO: make nice with Libtool) */ /* #undef PCRE_STATIC */ /* When calling PCRE via the POSIX interface, additional working storage is required for holding the pointers to capturing substrings because PCRE requires three integers per substring, whereas the POSIX interface provides only two. If the number of expected substrings is small, the wrapper function uses space on the stack, because this is faster than using malloc() for each call. The threshold above which the stack is no longer used is defined by POSIX_MALLOC_THRESHOLD. On systems that support it, "configure" can be used to override this default. */ #ifndef POSIX_MALLOC_THRESHOLD #define POSIX_MALLOC_THRESHOLD 10 #endif /* Define to 1 if you have the ANSI C header files. */ #ifndef STDC_HEADERS #define STDC_HEADERS 1 #endif /* Define to enable support for Unicode properties */ /* #undef SUPPORT_UCP */ /* Define to enable support for the UTF-8 Unicode encoding. */ #define SUPPORT_UTF8 1 /* Version number of package */ #ifndef VERSION #define VERSION "7.3" #endif /* Define to empty if `const' does not conform to ANSI C. */ /* #undef const */ /* Define to `unsigned int' if does not define. */ /* #undef size_t */ libsynthesis-3.4.0.47.1/src/pcre/pcre_config_macosx.h000066400000000000000000000220651226375725500223720ustar00rootroot00000000000000/* config-win32.h. Manually adapted for Win32 MWerks CW9.3 compiling */ /* On Unix-like systems config.h.in is converted by "configure" into config.h. Some other environments also support the use of "configure". PCRE is written in Standard C, but there are a few non-standard things it can cope with, allowing it to run on SunOS4 and other "close to standard" systems. If you are going to build PCRE "by hand" on a system without "configure" you should copy the distributed config.h.generic to config.h, and then set up the macros the way you need them. Alternatively, you can avoid editing by using -D on the compiler command line to set the macro values. PCRE uses memmove() if HAVE_MEMMOVE is set to 1; otherwise it uses bcopy() if HAVE_BCOPY is set to 1. If your system has neither bcopy() nor memmove(), set them both to 0; an emulation function will be used. */ /* If you are compiling for a system that uses EBCDIC instead of ASCII character codes, define this macro as 1. On systems that can use "configure", this can be done via --enable-ebcdic. */ /* #undef EBCDIC */ /* Define to 1 if you have the `bcopy' function. */ #ifndef HAVE_BCOPY #define HAVE_BCOPY 0 // MWerks CW 9 Win MSL does not seem to have it #endif /* Define to 1 if you have the header file. */ /* #undef HAVE_BITS_TYPE_TRAITS_H */ /* Define to 1 if you have the header file. */ #ifndef HAVE_DIRENT_H #define HAVE_DIRENT_H 0 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_DLFCN_H #define HAVE_DLFCN_H 0 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_INTTYPES_H #define HAVE_INTTYPES_H 1 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_LIMITS_H #define HAVE_LIMITS_H 1 #endif /* Define to 1 if the system has the type `long long'. */ #ifndef HAVE_LONG_LONG #define HAVE_LONG_LONG 1 #endif /* Define to 1 if you have the `memmove' function. */ #ifndef HAVE_MEMMOVE #define HAVE_MEMMOVE 1 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_MEMORY_H #define HAVE_MEMORY_H 0 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_STDINT_H #define HAVE_STDINT_H 1 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_STDLIB_H #define HAVE_STDLIB_H 1 #endif /* Define to 1 if you have the `strerror' function. */ #ifndef HAVE_STRERROR #define HAVE_STRERROR 1 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_STRING #define HAVE_STRING 1 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_STRINGS_H #define HAVE_STRINGS_H 0 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_STRING_H #define HAVE_STRING_H 1 #endif /* Define to 1 if you have the `strtoll' function. */ #ifndef HAVE_STRTOLL #define HAVE_STRTOLL 0 #endif /* Define to 1 if you have the `strtoq' function. */ #ifndef HAVE_STRTOQ #define HAVE_STRTOQ 0 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_SYS_STAT_H #define HAVE_SYS_STAT_H 0 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_SYS_TYPES_H #define HAVE_SYS_TYPES_H 0 #endif /* Define to 1 if you have the header file. */ /* #undef HAVE_TYPE_TRAITS_H */ /* Define to 1 if you have the header file. */ #ifndef HAVE_UNISTD_H #define HAVE_UNISTD_H 0 #endif /* Define to 1 if the system has the type `unsigned long long'. */ #ifndef HAVE_UNSIGNED_LONG_LONG #define HAVE_UNSIGNED_LONG_LONG 1 #endif /* Define to 1 if you have the header file. */ /* #undef HAVE_WINDOWS_H */ /* The value of LINK_SIZE determines the number of bytes used to store links as offsets within the compiled regex. The default is 2, which allows for compiled patterns up to 64K long. This covers the vast majority of cases. However, PCRE can also be compiled to use 3 or 4 bytes instead. This allows for longer patterns in extreme cases. On systems that support it, "configure" can be used to override this default. */ #ifndef LINK_SIZE #define LINK_SIZE 2 #endif /* The value of MATCH_LIMIT determines the default number of times the internal match() function can be called during a single execution of pcre_exec(). There is a runtime interface for setting a different limit. The limit exists in order to catch runaway regular expressions that take for ever to determine that they do not match. The default is set very large so that it does not accidentally catch legitimate cases. On systems that support it, "configure" can be used to override this default default. */ #ifndef MATCH_LIMIT #define MATCH_LIMIT 10000000 #endif /* The above limit applies to all calls of match(), whether or not they increase the recursion depth. In some environments it is desirable to limit the depth of recursive calls of match() more strictly, in order to restrict the maximum amount of stack (or heap, if NO_RECURSE is defined) that is used. The value of MATCH_LIMIT_RECURSION applies only to recursive calls of match(). To have any useful effect, it must be less than the value of MATCH_LIMIT. The default is to use the same value as MATCH_LIMIT. There is a runtime method for setting a different limit. On systems that support it, "configure" can be used to override the default. */ #ifndef MATCH_LIMIT_RECURSION #define MATCH_LIMIT_RECURSION MATCH_LIMIT #endif /* This limit is parameterized just in case anybody ever wants to change it. Care must be taken if it is increased, because it guards against integer overflow caused by enormously large patterns. */ #ifndef MAX_NAME_COUNT #define MAX_NAME_COUNT 10000 #endif /* This limit is parameterized just in case anybody ever wants to change it. Care must be taken if it is increased, because it guards against integer overflow caused by enormously large patterns. */ #ifndef MAX_NAME_SIZE #define MAX_NAME_SIZE 32 #endif /* The value of NEWLINE determines the newline character sequence. On Unix-like systems, "configure" can be used to override the default, which is 10. The possible values are 10 (LF), 13 (CR), 3338 (CRLF), -1 (ANY), or -2 (ANYCRLF). */ #ifndef NEWLINE #define NEWLINE 10 #endif /* PCRE uses recursive function calls to handle backtracking while matching. This can sometimes be a problem on systems that have stacks of limited size. Define NO_RECURSE to get a version that doesn't use recursion in the match() function; instead it creates its own stack by steam using pcre_recurse_malloc() to obtain memory from the heap. For more detail, see the comments and other stuff just above the match() function. On systems that support it, "configure" can be used to set this in the Makefile (use --disable-stack-for-recursion). */ /* #undef NO_RECURSE */ /* Name of package */ #define PACKAGE "pcre" /* Define to the address where bug reports for this package should be sent. */ #define PACKAGE_BUGREPORT "" /* Define to the full name of this package. */ #define PACKAGE_NAME "PCRE" /* Define to the full name and version of this package. */ #define PACKAGE_STRING "PCRE 7.3" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "pcre" /* Define to the version of this package. */ #define PACKAGE_VERSION "7.3" /* If you are compiling for a system other than a Unix-like system or Win32, and it needs some magic to be inserted before the definition of a function that is exported by the library, define this macro to contain the relevant magic. If you do not define this macro, it defaults to "extern" for a C compiler and "extern C" for a C++ compiler on non-Win32 systems. This macro apears at the start of every exported function that is part of the external API. It does not appear on functions that are "external" in the C sense, but which are internal to the library. */ /* #undef PCRE_EXP_DEFN */ /* Define if linking statically (TODO: make nice with Libtool) */ /* #undef PCRE_STATIC */ /* When calling PCRE via the POSIX interface, additional working storage is required for holding the pointers to capturing substrings because PCRE requires three integers per substring, whereas the POSIX interface provides only two. If the number of expected substrings is small, the wrapper function uses space on the stack, because this is faster than using malloc() for each call. The threshold above which the stack is no longer used is defined by POSIX_MALLOC_THRESHOLD. On systems that support it, "configure" can be used to override this default. */ #ifndef POSIX_MALLOC_THRESHOLD #define POSIX_MALLOC_THRESHOLD 10 #endif /* Define to 1 if you have the ANSI C header files. */ #ifndef STDC_HEADERS #define STDC_HEADERS 1 #endif /* Define to enable support for Unicode properties */ /* #undef SUPPORT_UCP */ /* Define to enable support for the UTF-8 Unicode encoding. */ #define SUPPORT_UTF8 1 /* Version number of package */ #ifndef VERSION #define VERSION "7.3" #endif /* Define to empty if `const' does not conform to ANSI C. */ /* #undef const */ /* Define to `unsigned int' if does not define. */ /* #undef size_t */ libsynthesis-3.4.0.47.1/src/pcre/pcre_config_win32.h000066400000000000000000000220651226375725500220420ustar00rootroot00000000000000/* config-win32.h. Manually adapted for Win32 MWerks CW9.3 compiling */ /* On Unix-like systems config.h.in is converted by "configure" into config.h. Some other environments also support the use of "configure". PCRE is written in Standard C, but there are a few non-standard things it can cope with, allowing it to run on SunOS4 and other "close to standard" systems. If you are going to build PCRE "by hand" on a system without "configure" you should copy the distributed config.h.generic to config.h, and then set up the macros the way you need them. Alternatively, you can avoid editing by using -D on the compiler command line to set the macro values. PCRE uses memmove() if HAVE_MEMMOVE is set to 1; otherwise it uses bcopy() if HAVE_BCOPY is set to 1. If your system has neither bcopy() nor memmove(), set them both to 0; an emulation function will be used. */ /* If you are compiling for a system that uses EBCDIC instead of ASCII character codes, define this macro as 1. On systems that can use "configure", this can be done via --enable-ebcdic. */ /* #undef EBCDIC */ /* Define to 1 if you have the `bcopy' function. */ #ifndef HAVE_BCOPY #define HAVE_BCOPY 0 // MWerks CW 9 Win MSL does not seem to have it #endif /* Define to 1 if you have the header file. */ /* #undef HAVE_BITS_TYPE_TRAITS_H */ /* Define to 1 if you have the header file. */ #ifndef HAVE_DIRENT_H #define HAVE_DIRENT_H 0 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_DLFCN_H #define HAVE_DLFCN_H 0 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_INTTYPES_H #define HAVE_INTTYPES_H 1 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_LIMITS_H #define HAVE_LIMITS_H 1 #endif /* Define to 1 if the system has the type `long long'. */ #ifndef HAVE_LONG_LONG #define HAVE_LONG_LONG 1 #endif /* Define to 1 if you have the `memmove' function. */ #ifndef HAVE_MEMMOVE #define HAVE_MEMMOVE 1 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_MEMORY_H #define HAVE_MEMORY_H 0 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_STDINT_H #define HAVE_STDINT_H 1 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_STDLIB_H #define HAVE_STDLIB_H 1 #endif /* Define to 1 if you have the `strerror' function. */ #ifndef HAVE_STRERROR #define HAVE_STRERROR 1 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_STRING #define HAVE_STRING 1 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_STRINGS_H #define HAVE_STRINGS_H 0 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_STRING_H #define HAVE_STRING_H 1 #endif /* Define to 1 if you have the `strtoll' function. */ #ifndef HAVE_STRTOLL #define HAVE_STRTOLL 0 #endif /* Define to 1 if you have the `strtoq' function. */ #ifndef HAVE_STRTOQ #define HAVE_STRTOQ 0 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_SYS_STAT_H #define HAVE_SYS_STAT_H 0 #endif /* Define to 1 if you have the header file. */ #ifndef HAVE_SYS_TYPES_H #define HAVE_SYS_TYPES_H 0 #endif /* Define to 1 if you have the header file. */ /* #undef HAVE_TYPE_TRAITS_H */ /* Define to 1 if you have the header file. */ #ifndef HAVE_UNISTD_H #define HAVE_UNISTD_H 0 #endif /* Define to 1 if the system has the type `unsigned long long'. */ #ifndef HAVE_UNSIGNED_LONG_LONG #define HAVE_UNSIGNED_LONG_LONG 1 #endif /* Define to 1 if you have the header file. */ /* #undef HAVE_WINDOWS_H */ /* The value of LINK_SIZE determines the number of bytes used to store links as offsets within the compiled regex. The default is 2, which allows for compiled patterns up to 64K long. This covers the vast majority of cases. However, PCRE can also be compiled to use 3 or 4 bytes instead. This allows for longer patterns in extreme cases. On systems that support it, "configure" can be used to override this default. */ #ifndef LINK_SIZE #define LINK_SIZE 2 #endif /* The value of MATCH_LIMIT determines the default number of times the internal match() function can be called during a single execution of pcre_exec(). There is a runtime interface for setting a different limit. The limit exists in order to catch runaway regular expressions that take for ever to determine that they do not match. The default is set very large so that it does not accidentally catch legitimate cases. On systems that support it, "configure" can be used to override this default default. */ #ifndef MATCH_LIMIT #define MATCH_LIMIT 10000000 #endif /* The above limit applies to all calls of match(), whether or not they increase the recursion depth. In some environments it is desirable to limit the depth of recursive calls of match() more strictly, in order to restrict the maximum amount of stack (or heap, if NO_RECURSE is defined) that is used. The value of MATCH_LIMIT_RECURSION applies only to recursive calls of match(). To have any useful effect, it must be less than the value of MATCH_LIMIT. The default is to use the same value as MATCH_LIMIT. There is a runtime method for setting a different limit. On systems that support it, "configure" can be used to override the default. */ #ifndef MATCH_LIMIT_RECURSION #define MATCH_LIMIT_RECURSION MATCH_LIMIT #endif /* This limit is parameterized just in case anybody ever wants to change it. Care must be taken if it is increased, because it guards against integer overflow caused by enormously large patterns. */ #ifndef MAX_NAME_COUNT #define MAX_NAME_COUNT 10000 #endif /* This limit is parameterized just in case anybody ever wants to change it. Care must be taken if it is increased, because it guards against integer overflow caused by enormously large patterns. */ #ifndef MAX_NAME_SIZE #define MAX_NAME_SIZE 32 #endif /* The value of NEWLINE determines the newline character sequence. On Unix-like systems, "configure" can be used to override the default, which is 10. The possible values are 10 (LF), 13 (CR), 3338 (CRLF), -1 (ANY), or -2 (ANYCRLF). */ #ifndef NEWLINE #define NEWLINE 10 #endif /* PCRE uses recursive function calls to handle backtracking while matching. This can sometimes be a problem on systems that have stacks of limited size. Define NO_RECURSE to get a version that doesn't use recursion in the match() function; instead it creates its own stack by steam using pcre_recurse_malloc() to obtain memory from the heap. For more detail, see the comments and other stuff just above the match() function. On systems that support it, "configure" can be used to set this in the Makefile (use --disable-stack-for-recursion). */ /* #undef NO_RECURSE */ /* Name of package */ #define PACKAGE "pcre" /* Define to the address where bug reports for this package should be sent. */ #define PACKAGE_BUGREPORT "" /* Define to the full name of this package. */ #define PACKAGE_NAME "PCRE" /* Define to the full name and version of this package. */ #define PACKAGE_STRING "PCRE 7.3" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "pcre" /* Define to the version of this package. */ #define PACKAGE_VERSION "7.3" /* If you are compiling for a system other than a Unix-like system or Win32, and it needs some magic to be inserted before the definition of a function that is exported by the library, define this macro to contain the relevant magic. If you do not define this macro, it defaults to "extern" for a C compiler and "extern C" for a C++ compiler on non-Win32 systems. This macro apears at the start of every exported function that is part of the external API. It does not appear on functions that are "external" in the C sense, but which are internal to the library. */ /* #undef PCRE_EXP_DEFN */ /* Define if linking statically (TODO: make nice with Libtool) */ /* #undef PCRE_STATIC */ /* When calling PCRE via the POSIX interface, additional working storage is required for holding the pointers to capturing substrings because PCRE requires three integers per substring, whereas the POSIX interface provides only two. If the number of expected substrings is small, the wrapper function uses space on the stack, because this is faster than using malloc() for each call. The threshold above which the stack is no longer used is defined by POSIX_MALLOC_THRESHOLD. On systems that support it, "configure" can be used to override this default. */ #ifndef POSIX_MALLOC_THRESHOLD #define POSIX_MALLOC_THRESHOLD 10 #endif /* Define to 1 if you have the ANSI C header files. */ #ifndef STDC_HEADERS #define STDC_HEADERS 1 #endif /* Define to enable support for Unicode properties */ /* #undef SUPPORT_UCP */ /* Define to enable support for the UTF-8 Unicode encoding. */ #define SUPPORT_UTF8 1 /* Version number of package */ #ifndef VERSION #define VERSION "7.3" #endif /* Define to empty if `const' does not conform to ANSI C. */ /* #undef const */ /* Define to `unsigned int' if does not define. */ /* #undef size_t */ libsynthesis-3.4.0.47.1/src/pcre/pcre_dfa_exec.c000066400000000000000000002703001226375725500213010ustar00rootroot00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2007 University of Cambridge ----------------------------------------------------------------------------- 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 name of the University of Cambridge 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. ----------------------------------------------------------------------------- */ /* This module contains the external function pcre_dfa_exec(), which is an alternative matching function that uses a sort of DFA algorithm (not a true FSM). This is NOT Perl- compatible, but it has advantages in certain applications. */ #include "pcre_setup.h" #define NLBLOCK md /* Block containing newline information */ #define PSSTART start_subject /* Field containing processed string start */ #define PSEND end_subject /* Field containing processed string end */ #include "pcre_internal.h" /* For use to indent debugging output */ #define SP " " /************************************************* * Code parameters and static tables * *************************************************/ /* These are offsets that are used to turn the OP_TYPESTAR and friends opcodes into others, under special conditions. A gap of 20 between the blocks should be enough. The resulting opcodes don't have to be less than 256 because they are never stored, so we push them well clear of the normal opcodes. */ #define OP_PROP_EXTRA 300 #define OP_EXTUNI_EXTRA 320 #define OP_ANYNL_EXTRA 340 #define OP_HSPACE_EXTRA 360 #define OP_VSPACE_EXTRA 380 /* This table identifies those opcodes that are followed immediately by a character that is to be tested in some way. This makes is possible to centralize the loading of these characters. In the case of Type * etc, the "character" is the opcode for \D, \d, \S, \s, \W, or \w, which will always be a small value. ***NOTE*** If the start of this table is modified, the two tables that follow must also be modified. */ static uschar coptable[] = { 0, /* End */ 0, 0, 0, 0, 0, /* \A, \G, \K, \B, \b */ 0, 0, 0, 0, 0, 0, /* \D, \d, \S, \s, \W, \w */ 0, 0, /* Any, Anybyte */ 0, 0, 0, /* NOTPROP, PROP, EXTUNI */ 0, 0, 0, 0, 0, /* \R, \H, \h, \V, \v */ 0, 0, 0, 0, 0, /* \Z, \z, Opt, ^, $ */ 1, /* Char */ 1, /* Charnc */ 1, /* not */ /* Positive single-char repeats */ 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */ 3, 3, 3, /* upto, minupto, exact */ 1, 1, 1, 3, /* *+, ++, ?+, upto+ */ /* Negative single-char repeats - only for chars < 256 */ 1, 1, 1, 1, 1, 1, /* NOT *, *?, +, +?, ?, ?? */ 3, 3, 3, /* NOT upto, minupto, exact */ 1, 1, 1, 3, /* NOT *+, ++, ?+, updo+ */ /* Positive type repeats */ 1, 1, 1, 1, 1, 1, /* Type *, *?, +, +?, ?, ?? */ 3, 3, 3, /* Type upto, minupto, exact */ 1, 1, 1, 3, /* Type *+, ++, ?+, upto+ */ /* Character class & ref repeats */ 0, 0, 0, 0, 0, 0, /* *, *?, +, +?, ?, ?? */ 0, 0, /* CRRANGE, CRMINRANGE */ 0, /* CLASS */ 0, /* NCLASS */ 0, /* XCLASS - variable length */ 0, /* REF */ 0, /* RECURSE */ 0, /* CALLOUT */ 0, /* Alt */ 0, /* Ket */ 0, /* KetRmax */ 0, /* KetRmin */ 0, /* Assert */ 0, /* Assert not */ 0, /* Assert behind */ 0, /* Assert behind not */ 0, /* Reverse */ 0, 0, 0, 0, /* ONCE, BRA, CBRA, COND */ 0, 0, 0, /* SBRA, SCBRA, SCOND */ 0, /* CREF */ 0, /* RREF */ 0, /* DEF */ 0, 0, /* BRAZERO, BRAMINZERO */ 0, 0, 0, 0, /* PRUNE, SKIP, THEN, COMMIT */ 0, 0 /* FAIL, ACCEPT */ }; /* These 2 tables allow for compact code for testing for \D, \d, \S, \s, \W, and \w */ static uschar toptable1[] = { 0, 0, 0, 0, 0, 0, ctype_digit, ctype_digit, ctype_space, ctype_space, ctype_word, ctype_word, 0 /* OP_ANY */ }; static uschar toptable2[] = { 0, 0, 0, 0, 0, 0, ctype_digit, 0, ctype_space, 0, ctype_word, 0, 1 /* OP_ANY */ }; /* Structure for holding data about a particular state, which is in effect the current data for an active path through the match tree. It must consist entirely of ints because the working vector we are passed, and which we put these structures in, is a vector of ints. */ typedef struct stateblock { int offset; /* Offset to opcode */ int count; /* Count for repeats */ int ims; /* ims flag bits */ int data; /* Some use extra data */ } stateblock; #define INTS_PER_STATEBLOCK (sizeof(stateblock)/sizeof(int)) #ifdef DEBUG /************************************************* * Print character string * *************************************************/ /* Character string printing function for debugging. Arguments: p points to string length number of bytes f where to print Returns: nothing */ static void pchars(unsigned char *p, int length, FILE *f) { int c; while (length-- > 0) { if (isprint(c = *(p++))) fprintf(f, "%c", c); else fprintf(f, "\\x%02x", c); } } #endif /************************************************* * Execute a Regular Expression - DFA engine * *************************************************/ /* This internal function applies a compiled pattern to a subject string, starting at a given point, using a DFA engine. This function is called from the external one, possibly multiple times if the pattern is not anchored. The function calls itself recursively for some kinds of subpattern. Arguments: md the match_data block with fixed information this_start_code the opening bracket of this subexpression's code current_subject where we currently are in the subject string start_offset start offset in the subject string offsets vector to contain the matching string offsets offsetcount size of same workspace vector of workspace wscount size of same ims the current ims flags rlevel function call recursion level recursing regex recursive call level Returns: > 0 => = 0 => -1 => failed to match < -1 => some kind of unexpected problem The following macros are used for adding states to the two state vectors (one for the current character, one for the following character). */ #define ADD_ACTIVE(x,y) \ if (active_count++ < wscount) \ { \ next_active_state->offset = (x); \ next_active_state->count = (y); \ next_active_state->ims = ims; \ next_active_state++; \ DPRINTF(("%.*sADD_ACTIVE(%d,%d)\n", rlevel*2-2, SP, (x), (y))); \ } \ else return PCRE_ERROR_DFA_WSSIZE #define ADD_ACTIVE_DATA(x,y,z) \ if (active_count++ < wscount) \ { \ next_active_state->offset = (x); \ next_active_state->count = (y); \ next_active_state->ims = ims; \ next_active_state->data = (z); \ next_active_state++; \ DPRINTF(("%.*sADD_ACTIVE_DATA(%d,%d,%d)\n", rlevel*2-2, SP, (x), (y), (z))); \ } \ else return PCRE_ERROR_DFA_WSSIZE #define ADD_NEW(x,y) \ if (new_count++ < wscount) \ { \ next_new_state->offset = (x); \ next_new_state->count = (y); \ next_new_state->ims = ims; \ next_new_state++; \ DPRINTF(("%.*sADD_NEW(%d,%d)\n", rlevel*2-2, SP, (x), (y))); \ } \ else return PCRE_ERROR_DFA_WSSIZE #define ADD_NEW_DATA(x,y,z) \ if (new_count++ < wscount) \ { \ next_new_state->offset = (x); \ next_new_state->count = (y); \ next_new_state->ims = ims; \ next_new_state->data = (z); \ next_new_state++; \ DPRINTF(("%.*sADD_NEW_DATA(%d,%d,%d)\n", rlevel*2-2, SP, (x), (y), (z))); \ } \ else return PCRE_ERROR_DFA_WSSIZE /* And now, here is the code */ static int internal_dfa_exec( dfa_match_data *md, const uschar *this_start_code, const uschar *current_subject, int start_offset, int *offsets, int offsetcount, int *workspace, int wscount, int ims, int rlevel, int recursing) { stateblock *active_states, *new_states, *temp_states; stateblock *next_active_state, *next_new_state; const uschar *ctypes, *lcc, *fcc; const uschar *ptr; const uschar *end_code, *first_op; int active_count, new_count, match_count; /* Some fields in the md block are frequently referenced, so we load them into independent variables in the hope that this will perform better. */ const uschar *start_subject = md->start_subject; const uschar *end_subject = md->end_subject; const uschar *start_code = md->start_code; #ifdef SUPPORT_UTF8 BOOL utf8 = (md->poptions & PCRE_UTF8) != 0; #else BOOL utf8 = FALSE; #endif rlevel++; offsetcount &= (-2); wscount -= 2; wscount = (wscount - (wscount % (INTS_PER_STATEBLOCK * 2))) / (2 * INTS_PER_STATEBLOCK); DPRINTF(("\n%.*s---------------------\n" "%.*sCall to internal_dfa_exec f=%d r=%d\n", rlevel*2-2, SP, rlevel*2-2, SP, rlevel, recursing)); ctypes = md->tables + ctypes_offset; lcc = md->tables + lcc_offset; fcc = md->tables + fcc_offset; match_count = PCRE_ERROR_NOMATCH; /* A negative number */ active_states = (stateblock *)(workspace + 2); next_new_state = new_states = active_states + wscount; new_count = 0; first_op = this_start_code + 1 + LINK_SIZE + ((*this_start_code == OP_CBRA || *this_start_code == OP_SCBRA)? 2:0); /* The first thing in any (sub) pattern is a bracket of some sort. Push all the alternative states onto the list, and find out where the end is. This makes is possible to use this function recursively, when we want to stop at a matching internal ket rather than at the end. If the first opcode in the first alternative is OP_REVERSE, we are dealing with a backward assertion. In that case, we have to find out the maximum amount to move back, and set up each alternative appropriately. */ if (*first_op == OP_REVERSE) { int max_back = 0; int gone_back; end_code = this_start_code; do { int back = GET(end_code, 2+LINK_SIZE); if (back > max_back) max_back = back; end_code += GET(end_code, 1); } while (*end_code == OP_ALT); /* If we can't go back the amount required for the longest lookbehind pattern, go back as far as we can; some alternatives may still be viable. */ #ifdef SUPPORT_UTF8 /* In character mode we have to step back character by character */ if (utf8) { for (gone_back = 0; gone_back < max_back; gone_back++) { if (current_subject <= start_subject) break; current_subject--; while (current_subject > start_subject && (*current_subject & 0xc0) == 0x80) current_subject--; } } else #endif /* In byte-mode we can do this quickly. */ { gone_back = (current_subject - max_back < start_subject)? current_subject - start_subject : max_back; current_subject -= gone_back; } /* Now we can process the individual branches. */ end_code = this_start_code; do { int back = GET(end_code, 2+LINK_SIZE); if (back <= gone_back) { int bstate = end_code - start_code + 2 + 2*LINK_SIZE; ADD_NEW_DATA(-bstate, 0, gone_back - back); } end_code += GET(end_code, 1); } while (*end_code == OP_ALT); } /* This is the code for a "normal" subpattern (not a backward assertion). The start of a whole pattern is always one of these. If we are at the top level, we may be asked to restart matching from the same point that we reached for a previous partial match. We still have to scan through the top-level branches to find the end state. */ else { end_code = this_start_code; /* Restarting */ if (rlevel == 1 && (md->moptions & PCRE_DFA_RESTART) != 0) { do { end_code += GET(end_code, 1); } while (*end_code == OP_ALT); new_count = workspace[1]; if (!workspace[0]) memcpy(new_states, active_states, new_count * sizeof(stateblock)); } /* Not restarting */ else { int length = 1 + LINK_SIZE + ((*this_start_code == OP_CBRA || *this_start_code == OP_SCBRA)? 2:0); do { ADD_NEW(end_code - start_code + length, 0); end_code += GET(end_code, 1); length = 1 + LINK_SIZE; } while (*end_code == OP_ALT); } } workspace[0] = 0; /* Bit indicating which vector is current */ DPRINTF(("%.*sEnd state = %d\n", rlevel*2-2, SP, end_code - start_code)); /* Loop for scanning the subject */ ptr = current_subject; for (;;) { int i, j; int clen, dlen; unsigned int c, d; /* Make the new state list into the active state list and empty the new state list. */ temp_states = active_states; active_states = new_states; new_states = temp_states; active_count = new_count; new_count = 0; workspace[0] ^= 1; /* Remember for the restarting feature */ workspace[1] = active_count; #ifdef DEBUG printf("%.*sNext character: rest of subject = \"", rlevel*2-2, SP); pchars((uschar *)ptr, strlen((char *)ptr), stdout); printf("\"\n"); printf("%.*sActive states: ", rlevel*2-2, SP); for (i = 0; i < active_count; i++) printf("%d/%d ", active_states[i].offset, active_states[i].count); printf("\n"); #endif /* Set the pointers for adding new states */ next_active_state = active_states + active_count; next_new_state = new_states; /* Load the current character from the subject outside the loop, as many different states may want to look at it, and we assume that at least one will. */ if (ptr < end_subject) { clen = 1; /* Number of bytes in the character */ #ifdef SUPPORT_UTF8 if (utf8) { GETCHARLEN(c, ptr, clen); } else #endif /* SUPPORT_UTF8 */ c = *ptr; } else { clen = 0; /* This indicates the end of the subject */ c = NOTACHAR; /* This value should never actually be used */ } /* Scan up the active states and act on each one. The result of an action may be to add more states to the currently active list (e.g. on hitting a parenthesis) or it may be to put states on the new list, for considering when we move the character pointer on. */ for (i = 0; i < active_count; i++) { stateblock *current_state = active_states + i; const uschar *code; int state_offset = current_state->offset; int count, codevalue; #ifdef SUPPORT_UCP int chartype, script; #endif #ifdef DEBUG printf ("%.*sProcessing state %d c=", rlevel*2-2, SP, state_offset); if (clen == 0) printf("EOL\n"); else if (c > 32 && c < 127) printf("'%c'\n", c); else printf("0x%02x\n", c); #endif /* This variable is referred to implicity in the ADD_xxx macros. */ ims = current_state->ims; /* A negative offset is a special case meaning "hold off going to this (negated) state until the number of characters in the data field have been skipped". */ if (state_offset < 0) { if (current_state->data > 0) { DPRINTF(("%.*sSkipping this character\n", rlevel*2-2, SP)); ADD_NEW_DATA(state_offset, current_state->count, current_state->data - 1); continue; } else { current_state->offset = state_offset = -state_offset; } } /* Check for a duplicate state with the same count, and skip if found. */ for (j = 0; j < i; j++) { if (active_states[j].offset == state_offset && active_states[j].count == current_state->count) { DPRINTF(("%.*sDuplicate state: skipped\n", rlevel*2-2, SP)); goto NEXT_ACTIVE_STATE; } } /* The state offset is the offset to the opcode */ code = start_code + state_offset; codevalue = *code; /* If this opcode is followed by an inline character, load it. It is tempting to test for the presence of a subject character here, but that is wrong, because sometimes zero repetitions of the subject are permitted. We also use this mechanism for opcodes such as OP_TYPEPLUS that take an argument that is not a data character - but is always one byte long. We have to take special action to deal with \P, \p, \H, \h, \V, \v and \X in this case. To keep the other cases fast, convert these ones to new opcodes. */ if (coptable[codevalue] > 0) { dlen = 1; #ifdef SUPPORT_UTF8 if (utf8) { GETCHARLEN(d, (code + coptable[codevalue]), dlen); } else #endif /* SUPPORT_UTF8 */ d = code[coptable[codevalue]]; if (codevalue >= OP_TYPESTAR) { switch(d) { case OP_ANYBYTE: return PCRE_ERROR_DFA_UITEM; case OP_NOTPROP: case OP_PROP: codevalue += OP_PROP_EXTRA; break; case OP_ANYNL: codevalue += OP_ANYNL_EXTRA; break; case OP_EXTUNI: codevalue += OP_EXTUNI_EXTRA; break; case OP_NOT_HSPACE: case OP_HSPACE: codevalue += OP_HSPACE_EXTRA; break; case OP_NOT_VSPACE: case OP_VSPACE: codevalue += OP_VSPACE_EXTRA; break; default: break; } } } else { dlen = 0; /* Not strictly necessary, but compilers moan */ d = NOTACHAR; /* if these variables are not set. */ } /* Now process the individual opcodes */ switch (codevalue) { /* ========================================================================== */ /* Reached a closing bracket. If not at the end of the pattern, carry on with the next opcode. Otherwise, unless we have an empty string and PCRE_NOTEMPTY is set, save the match data, shifting up all previous matches so we always have the longest first. */ case OP_KET: case OP_KETRMIN: case OP_KETRMAX: if (code != end_code) { ADD_ACTIVE(state_offset + 1 + LINK_SIZE, 0); if (codevalue != OP_KET) { ADD_ACTIVE(state_offset - GET(code, 1), 0); } } else if (ptr > current_subject || (md->moptions & PCRE_NOTEMPTY) == 0) { if (match_count < 0) match_count = (offsetcount >= 2)? 1 : 0; else if (match_count > 0 && ++match_count * 2 >= offsetcount) match_count = 0; count = ((match_count == 0)? offsetcount : match_count * 2) - 2; if (count > 0) memmove(offsets + 2, offsets, count * sizeof(int)); if (offsetcount >= 2) { offsets[0] = current_subject - start_subject; offsets[1] = ptr - start_subject; DPRINTF(("%.*sSet matched string = \"%.*s\"\n", rlevel*2-2, SP, offsets[1] - offsets[0], current_subject)); } if ((md->moptions & PCRE_DFA_SHORTEST) != 0) { DPRINTF(("%.*sEnd of internal_dfa_exec %d: returning %d\n" "%.*s---------------------\n\n", rlevel*2-2, SP, rlevel, match_count, rlevel*2-2, SP)); return match_count; } } break; /* ========================================================================== */ /* These opcodes add to the current list of states without looking at the current character. */ /*-----------------------------------------------------------------*/ case OP_ALT: do { code += GET(code, 1); } while (*code == OP_ALT); ADD_ACTIVE(code - start_code, 0); break; /*-----------------------------------------------------------------*/ case OP_BRA: case OP_SBRA: do { ADD_ACTIVE(code - start_code + 1 + LINK_SIZE, 0); code += GET(code, 1); } while (*code == OP_ALT); break; /*-----------------------------------------------------------------*/ case OP_CBRA: case OP_SCBRA: ADD_ACTIVE(code - start_code + 3 + LINK_SIZE, 0); code += GET(code, 1); while (*code == OP_ALT) { ADD_ACTIVE(code - start_code + 1 + LINK_SIZE, 0); code += GET(code, 1); } break; /*-----------------------------------------------------------------*/ case OP_BRAZERO: case OP_BRAMINZERO: ADD_ACTIVE(state_offset + 1, 0); code += 1 + GET(code, 2); while (*code == OP_ALT) code += GET(code, 1); ADD_ACTIVE(code - start_code + 1 + LINK_SIZE, 0); break; /*-----------------------------------------------------------------*/ case OP_CIRC: if ((ptr == start_subject && (md->moptions & PCRE_NOTBOL) == 0) || ((ims & PCRE_MULTILINE) != 0 && ptr != end_subject && WAS_NEWLINE(ptr))) { ADD_ACTIVE(state_offset + 1, 0); } break; /*-----------------------------------------------------------------*/ case OP_EOD: if (ptr >= end_subject) { ADD_ACTIVE(state_offset + 1, 0); } break; /*-----------------------------------------------------------------*/ case OP_OPT: ims = code[1]; ADD_ACTIVE(state_offset + 2, 0); break; /*-----------------------------------------------------------------*/ case OP_SOD: if (ptr == start_subject) { ADD_ACTIVE(state_offset + 1, 0); } break; /*-----------------------------------------------------------------*/ case OP_SOM: if (ptr == start_subject + start_offset) { ADD_ACTIVE(state_offset + 1, 0); } break; /* ========================================================================== */ /* These opcodes inspect the next subject character, and sometimes the previous one as well, but do not have an argument. The variable clen contains the length of the current character and is zero if we are at the end of the subject. */ /*-----------------------------------------------------------------*/ case OP_ANY: if (clen > 0 && ((ims & PCRE_DOTALL) != 0 || !IS_NEWLINE(ptr))) { ADD_NEW(state_offset + 1, 0); } break; /*-----------------------------------------------------------------*/ case OP_EODN: if (clen == 0 || (IS_NEWLINE(ptr) && ptr == end_subject - md->nllen)) { ADD_ACTIVE(state_offset + 1, 0); } break; /*-----------------------------------------------------------------*/ case OP_DOLL: if ((md->moptions & PCRE_NOTEOL) == 0) { if (clen == 0 || (IS_NEWLINE(ptr) && ((ims & PCRE_MULTILINE) != 0 || ptr == end_subject - md->nllen) )) { ADD_ACTIVE(state_offset + 1, 0); } } else if ((ims & PCRE_MULTILINE) != 0 && IS_NEWLINE(ptr)) { ADD_ACTIVE(state_offset + 1, 0); } break; /*-----------------------------------------------------------------*/ case OP_DIGIT: case OP_WHITESPACE: case OP_WORDCHAR: if (clen > 0 && c < 256 && ((ctypes[c] & toptable1[codevalue]) ^ toptable2[codevalue]) != 0) { ADD_NEW(state_offset + 1, 0); } break; /*-----------------------------------------------------------------*/ case OP_NOT_DIGIT: case OP_NOT_WHITESPACE: case OP_NOT_WORDCHAR: if (clen > 0 && (c >= 256 || ((ctypes[c] & toptable1[codevalue]) ^ toptable2[codevalue]) != 0)) { ADD_NEW(state_offset + 1, 0); } break; /*-----------------------------------------------------------------*/ case OP_WORD_BOUNDARY: case OP_NOT_WORD_BOUNDARY: { int left_word, right_word; if (ptr > start_subject) { const uschar *temp = ptr - 1; #ifdef SUPPORT_UTF8 if (utf8) BACKCHAR(temp); #endif GETCHARTEST(d, temp); left_word = d < 256 && (ctypes[d] & ctype_word) != 0; } else left_word = 0; if (clen > 0) right_word = c < 256 && (ctypes[c] & ctype_word) != 0; else right_word = 0; if ((left_word == right_word) == (codevalue == OP_NOT_WORD_BOUNDARY)) { ADD_ACTIVE(state_offset + 1, 0); } } break; /*-----------------------------------------------------------------*/ /* Check the next character by Unicode property. We will get here only if the support is in the binary; otherwise a compile-time error occurs. */ #ifdef SUPPORT_UCP case OP_PROP: case OP_NOTPROP: if (clen > 0) { BOOL OK; int category = _pcre_ucp_findprop(c, &chartype, &script); switch(code[1]) { case PT_ANY: OK = TRUE; break; case PT_LAMP: OK = chartype == ucp_Lu || chartype == ucp_Ll || chartype == ucp_Lt; break; case PT_GC: OK = category == code[2]; break; case PT_PC: OK = chartype == code[2]; break; case PT_SC: OK = script == code[2]; break; /* Should never occur, but keep compilers from grumbling. */ default: OK = codevalue != OP_PROP; break; } if (OK == (codevalue == OP_PROP)) { ADD_NEW(state_offset + 3, 0); } } break; #endif /* ========================================================================== */ /* These opcodes likewise inspect the subject character, but have an argument that is not a data character. It is one of these opcodes: OP_ANY, OP_DIGIT, OP_NOT_DIGIT, OP_WHITESPACE, OP_NOT_SPACE, OP_WORDCHAR, OP_NOT_WORDCHAR. The value is loaded into d. */ case OP_TYPEPLUS: case OP_TYPEMINPLUS: case OP_TYPEPOSPLUS: count = current_state->count; /* Already matched */ if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); } if (clen > 0) { if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) || (c < 256 && (d != OP_ANY || (ims & PCRE_DOTALL) != 0 || !IS_NEWLINE(ptr) ) && ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0)) { if (count > 0 && codevalue == OP_TYPEPOSPLUS) { active_count--; /* Remove non-match possibility */ next_active_state--; } count++; ADD_NEW(state_offset, count); } } break; /*-----------------------------------------------------------------*/ case OP_TYPEQUERY: case OP_TYPEMINQUERY: case OP_TYPEPOSQUERY: ADD_ACTIVE(state_offset + 2, 0); if (clen > 0) { if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) || (c < 256 && (d != OP_ANY || (ims & PCRE_DOTALL) != 0 || !IS_NEWLINE(ptr) ) && ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0)) { if (codevalue == OP_TYPEPOSQUERY) { active_count--; /* Remove non-match possibility */ next_active_state--; } ADD_NEW(state_offset + 2, 0); } } break; /*-----------------------------------------------------------------*/ case OP_TYPESTAR: case OP_TYPEMINSTAR: case OP_TYPEPOSSTAR: ADD_ACTIVE(state_offset + 2, 0); if (clen > 0) { if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) || (c < 256 && (d != OP_ANY || (ims & PCRE_DOTALL) != 0 || !IS_NEWLINE(ptr) ) && ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0)) { if (codevalue == OP_TYPEPOSSTAR) { active_count--; /* Remove non-match possibility */ next_active_state--; } ADD_NEW(state_offset, 0); } } break; /*-----------------------------------------------------------------*/ case OP_TYPEEXACT: count = current_state->count; /* Number already matched */ if (clen > 0) { if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) || (c < 256 && (d != OP_ANY || (ims & PCRE_DOTALL) != 0 || !IS_NEWLINE(ptr) ) && ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0)) { if (++count >= GET2(code, 1)) { ADD_NEW(state_offset + 4, 0); } else { ADD_NEW(state_offset, count); } } } break; /*-----------------------------------------------------------------*/ case OP_TYPEUPTO: case OP_TYPEMINUPTO: case OP_TYPEPOSUPTO: ADD_ACTIVE(state_offset + 4, 0); count = current_state->count; /* Number already matched */ if (clen > 0) { if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) || (c < 256 && (d != OP_ANY || (ims & PCRE_DOTALL) != 0 || !IS_NEWLINE(ptr) ) && ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0)) { if (codevalue == OP_TYPEPOSUPTO) { active_count--; /* Remove non-match possibility */ next_active_state--; } if (++count >= GET2(code, 1)) { ADD_NEW(state_offset + 4, 0); } else { ADD_NEW(state_offset, count); } } } break; /* ========================================================================== */ /* These are virtual opcodes that are used when something like OP_TYPEPLUS has OP_PROP, OP_NOTPROP, OP_ANYNL, or OP_EXTUNI as its argument. It keeps the code above fast for the other cases. The argument is in the d variable. */ #ifdef SUPPORT_UCP case OP_PROP_EXTRA + OP_TYPEPLUS: case OP_PROP_EXTRA + OP_TYPEMINPLUS: case OP_PROP_EXTRA + OP_TYPEPOSPLUS: count = current_state->count; /* Already matched */ if (count > 0) { ADD_ACTIVE(state_offset + 4, 0); } if (clen > 0) { BOOL OK; int category = _pcre_ucp_findprop(c, &chartype, &script); switch(code[2]) { case PT_ANY: OK = TRUE; break; case PT_LAMP: OK = chartype == ucp_Lu || chartype == ucp_Ll || chartype == ucp_Lt; break; case PT_GC: OK = category == code[3]; break; case PT_PC: OK = chartype == code[3]; break; case PT_SC: OK = script == code[3]; break; /* Should never occur, but keep compilers from grumbling. */ default: OK = codevalue != OP_PROP; break; } if (OK == (d == OP_PROP)) { if (count > 0 && codevalue == OP_PROP_EXTRA + OP_TYPEPOSPLUS) { active_count--; /* Remove non-match possibility */ next_active_state--; } count++; ADD_NEW(state_offset, count); } } break; /*-----------------------------------------------------------------*/ case OP_EXTUNI_EXTRA + OP_TYPEPLUS: case OP_EXTUNI_EXTRA + OP_TYPEMINPLUS: case OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS: count = current_state->count; /* Already matched */ if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); } if (clen > 0 && _pcre_ucp_findprop(c, &chartype, &script) != ucp_M) { const uschar *nptr = ptr + clen; int ncount = 0; if (count > 0 && codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS) { active_count--; /* Remove non-match possibility */ next_active_state--; } while (nptr < end_subject) { int nd; int ndlen = 1; GETCHARLEN(nd, nptr, ndlen); if (_pcre_ucp_findprop(nd, &chartype, &script) != ucp_M) break; ncount++; nptr += ndlen; } count++; ADD_NEW_DATA(-state_offset, count, ncount); } break; #endif /*-----------------------------------------------------------------*/ case OP_ANYNL_EXTRA + OP_TYPEPLUS: case OP_ANYNL_EXTRA + OP_TYPEMINPLUS: case OP_ANYNL_EXTRA + OP_TYPEPOSPLUS: count = current_state->count; /* Already matched */ if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); } if (clen > 0) { int ncount = 0; switch (c) { case 0x000d: if (ptr + 1 < end_subject && ptr[1] == 0x0a) ncount = 1; /* Fall through */ case 0x000a: case 0x000b: case 0x000c: case 0x0085: case 0x2028: case 0x2029: if (count > 0 && codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSPLUS) { active_count--; /* Remove non-match possibility */ next_active_state--; } count++; ADD_NEW_DATA(-state_offset, count, ncount); break; default: break; } } break; /*-----------------------------------------------------------------*/ case OP_VSPACE_EXTRA + OP_TYPEPLUS: case OP_VSPACE_EXTRA + OP_TYPEMINPLUS: case OP_VSPACE_EXTRA + OP_TYPEPOSPLUS: count = current_state->count; /* Already matched */ if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); } if (clen > 0) { BOOL OK; switch (c) { case 0x000a: case 0x000b: case 0x000c: case 0x000d: case 0x0085: case 0x2028: case 0x2029: OK = TRUE; break; default: OK = FALSE; break; } if (OK == (d == OP_VSPACE)) { if (count > 0 && codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSPLUS) { active_count--; /* Remove non-match possibility */ next_active_state--; } count++; ADD_NEW_DATA(-state_offset, count, 0); } } break; /*-----------------------------------------------------------------*/ case OP_HSPACE_EXTRA + OP_TYPEPLUS: case OP_HSPACE_EXTRA + OP_TYPEMINPLUS: case OP_HSPACE_EXTRA + OP_TYPEPOSPLUS: count = current_state->count; /* Already matched */ if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); } if (clen > 0) { BOOL OK; switch (c) { case 0x09: /* HT */ case 0x20: /* SPACE */ case 0xa0: /* NBSP */ case 0x1680: /* OGHAM SPACE MARK */ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ case 0x2000: /* EN QUAD */ case 0x2001: /* EM QUAD */ case 0x2002: /* EN SPACE */ case 0x2003: /* EM SPACE */ case 0x2004: /* THREE-PER-EM SPACE */ case 0x2005: /* FOUR-PER-EM SPACE */ case 0x2006: /* SIX-PER-EM SPACE */ case 0x2007: /* FIGURE SPACE */ case 0x2008: /* PUNCTUATION SPACE */ case 0x2009: /* THIN SPACE */ case 0x200A: /* HAIR SPACE */ case 0x202f: /* NARROW NO-BREAK SPACE */ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ case 0x3000: /* IDEOGRAPHIC SPACE */ OK = TRUE; break; default: OK = FALSE; break; } if (OK == (d == OP_HSPACE)) { if (count > 0 && codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSPLUS) { active_count--; /* Remove non-match possibility */ next_active_state--; } count++; ADD_NEW_DATA(-state_offset, count, 0); } } break; /*-----------------------------------------------------------------*/ #ifdef SUPPORT_UCP case OP_PROP_EXTRA + OP_TYPEQUERY: case OP_PROP_EXTRA + OP_TYPEMINQUERY: case OP_PROP_EXTRA + OP_TYPEPOSQUERY: count = 4; goto QS1; case OP_PROP_EXTRA + OP_TYPESTAR: case OP_PROP_EXTRA + OP_TYPEMINSTAR: case OP_PROP_EXTRA + OP_TYPEPOSSTAR: count = 0; QS1: ADD_ACTIVE(state_offset + 4, 0); if (clen > 0) { BOOL OK; int category = _pcre_ucp_findprop(c, &chartype, &script); switch(code[2]) { case PT_ANY: OK = TRUE; break; case PT_LAMP: OK = chartype == ucp_Lu || chartype == ucp_Ll || chartype == ucp_Lt; break; case PT_GC: OK = category == code[3]; break; case PT_PC: OK = chartype == code[3]; break; case PT_SC: OK = script == code[3]; break; /* Should never occur, but keep compilers from grumbling. */ default: OK = codevalue != OP_PROP; break; } if (OK == (d == OP_PROP)) { if (codevalue == OP_PROP_EXTRA + OP_TYPEPOSSTAR || codevalue == OP_PROP_EXTRA + OP_TYPEPOSQUERY) { active_count--; /* Remove non-match possibility */ next_active_state--; } ADD_NEW(state_offset + count, 0); } } break; /*-----------------------------------------------------------------*/ case OP_EXTUNI_EXTRA + OP_TYPEQUERY: case OP_EXTUNI_EXTRA + OP_TYPEMINQUERY: case OP_EXTUNI_EXTRA + OP_TYPEPOSQUERY: count = 2; goto QS2; case OP_EXTUNI_EXTRA + OP_TYPESTAR: case OP_EXTUNI_EXTRA + OP_TYPEMINSTAR: case OP_EXTUNI_EXTRA + OP_TYPEPOSSTAR: count = 0; QS2: ADD_ACTIVE(state_offset + 2, 0); if (clen > 0 && _pcre_ucp_findprop(c, &chartype, &script) != ucp_M) { const uschar *nptr = ptr + clen; int ncount = 0; if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSSTAR || codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSQUERY) { active_count--; /* Remove non-match possibility */ next_active_state--; } while (nptr < end_subject) { int nd; int ndlen = 1; GETCHARLEN(nd, nptr, ndlen); if (_pcre_ucp_findprop(nd, &chartype, &script) != ucp_M) break; ncount++; nptr += ndlen; } ADD_NEW_DATA(-(state_offset + count), 0, ncount); } break; #endif /*-----------------------------------------------------------------*/ case OP_ANYNL_EXTRA + OP_TYPEQUERY: case OP_ANYNL_EXTRA + OP_TYPEMINQUERY: case OP_ANYNL_EXTRA + OP_TYPEPOSQUERY: count = 2; goto QS3; case OP_ANYNL_EXTRA + OP_TYPESTAR: case OP_ANYNL_EXTRA + OP_TYPEMINSTAR: case OP_ANYNL_EXTRA + OP_TYPEPOSSTAR: count = 0; QS3: ADD_ACTIVE(state_offset + 2, 0); if (clen > 0) { int ncount = 0; switch (c) { case 0x000d: if (ptr + 1 < end_subject && ptr[1] == 0x0a) ncount = 1; /* Fall through */ case 0x000a: case 0x000b: case 0x000c: case 0x0085: case 0x2028: case 0x2029: if (codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSSTAR || codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSQUERY) { active_count--; /* Remove non-match possibility */ next_active_state--; } ADD_NEW_DATA(-(state_offset + count), 0, ncount); break; default: break; } } break; /*-----------------------------------------------------------------*/ case OP_VSPACE_EXTRA + OP_TYPEQUERY: case OP_VSPACE_EXTRA + OP_TYPEMINQUERY: case OP_VSPACE_EXTRA + OP_TYPEPOSQUERY: count = 2; goto QS4; case OP_VSPACE_EXTRA + OP_TYPESTAR: case OP_VSPACE_EXTRA + OP_TYPEMINSTAR: case OP_VSPACE_EXTRA + OP_TYPEPOSSTAR: count = 0; QS4: ADD_ACTIVE(state_offset + 2, 0); if (clen > 0) { BOOL OK; switch (c) { case 0x000a: case 0x000b: case 0x000c: case 0x000d: case 0x0085: case 0x2028: case 0x2029: OK = TRUE; break; default: OK = FALSE; break; } if (OK == (d == OP_VSPACE)) { if (codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSSTAR || codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSQUERY) { active_count--; /* Remove non-match possibility */ next_active_state--; } ADD_NEW_DATA(-(state_offset + count), 0, 0); } } break; /*-----------------------------------------------------------------*/ case OP_HSPACE_EXTRA + OP_TYPEQUERY: case OP_HSPACE_EXTRA + OP_TYPEMINQUERY: case OP_HSPACE_EXTRA + OP_TYPEPOSQUERY: count = 2; goto QS5; case OP_HSPACE_EXTRA + OP_TYPESTAR: case OP_HSPACE_EXTRA + OP_TYPEMINSTAR: case OP_HSPACE_EXTRA + OP_TYPEPOSSTAR: count = 0; QS5: ADD_ACTIVE(state_offset + 2, 0); if (clen > 0) { BOOL OK; switch (c) { case 0x09: /* HT */ case 0x20: /* SPACE */ case 0xa0: /* NBSP */ case 0x1680: /* OGHAM SPACE MARK */ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ case 0x2000: /* EN QUAD */ case 0x2001: /* EM QUAD */ case 0x2002: /* EN SPACE */ case 0x2003: /* EM SPACE */ case 0x2004: /* THREE-PER-EM SPACE */ case 0x2005: /* FOUR-PER-EM SPACE */ case 0x2006: /* SIX-PER-EM SPACE */ case 0x2007: /* FIGURE SPACE */ case 0x2008: /* PUNCTUATION SPACE */ case 0x2009: /* THIN SPACE */ case 0x200A: /* HAIR SPACE */ case 0x202f: /* NARROW NO-BREAK SPACE */ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ case 0x3000: /* IDEOGRAPHIC SPACE */ OK = TRUE; break; default: OK = FALSE; break; } if (OK == (d == OP_HSPACE)) { if (codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSSTAR || codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSQUERY) { active_count--; /* Remove non-match possibility */ next_active_state--; } ADD_NEW_DATA(-(state_offset + count), 0, 0); } } break; /*-----------------------------------------------------------------*/ #ifdef SUPPORT_UCP case OP_PROP_EXTRA + OP_TYPEEXACT: case OP_PROP_EXTRA + OP_TYPEUPTO: case OP_PROP_EXTRA + OP_TYPEMINUPTO: case OP_PROP_EXTRA + OP_TYPEPOSUPTO: if (codevalue != OP_PROP_EXTRA + OP_TYPEEXACT) { ADD_ACTIVE(state_offset + 6, 0); } count = current_state->count; /* Number already matched */ if (clen > 0) { BOOL OK; int category = _pcre_ucp_findprop(c, &chartype, &script); switch(code[4]) { case PT_ANY: OK = TRUE; break; case PT_LAMP: OK = chartype == ucp_Lu || chartype == ucp_Ll || chartype == ucp_Lt; break; case PT_GC: OK = category == code[5]; break; case PT_PC: OK = chartype == code[5]; break; case PT_SC: OK = script == code[5]; break; /* Should never occur, but keep compilers from grumbling. */ default: OK = codevalue != OP_PROP; break; } if (OK == (d == OP_PROP)) { if (codevalue == OP_PROP_EXTRA + OP_TYPEPOSUPTO) { active_count--; /* Remove non-match possibility */ next_active_state--; } if (++count >= GET2(code, 1)) { ADD_NEW(state_offset + 6, 0); } else { ADD_NEW(state_offset, count); } } } break; /*-----------------------------------------------------------------*/ case OP_EXTUNI_EXTRA + OP_TYPEEXACT: case OP_EXTUNI_EXTRA + OP_TYPEUPTO: case OP_EXTUNI_EXTRA + OP_TYPEMINUPTO: case OP_EXTUNI_EXTRA + OP_TYPEPOSUPTO: if (codevalue != OP_EXTUNI_EXTRA + OP_TYPEEXACT) { ADD_ACTIVE(state_offset + 4, 0); } count = current_state->count; /* Number already matched */ if (clen > 0 && _pcre_ucp_findprop(c, &chartype, &script) != ucp_M) { const uschar *nptr = ptr + clen; int ncount = 0; if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSUPTO) { active_count--; /* Remove non-match possibility */ next_active_state--; } while (nptr < end_subject) { int nd; int ndlen = 1; GETCHARLEN(nd, nptr, ndlen); if (_pcre_ucp_findprop(nd, &chartype, &script) != ucp_M) break; ncount++; nptr += ndlen; } if (++count >= GET2(code, 1)) { ADD_NEW_DATA(-(state_offset + 4), 0, ncount); } else { ADD_NEW_DATA(-state_offset, count, ncount); } } break; #endif /*-----------------------------------------------------------------*/ case OP_ANYNL_EXTRA + OP_TYPEEXACT: case OP_ANYNL_EXTRA + OP_TYPEUPTO: case OP_ANYNL_EXTRA + OP_TYPEMINUPTO: case OP_ANYNL_EXTRA + OP_TYPEPOSUPTO: if (codevalue != OP_ANYNL_EXTRA + OP_TYPEEXACT) { ADD_ACTIVE(state_offset + 4, 0); } count = current_state->count; /* Number already matched */ if (clen > 0) { int ncount = 0; switch (c) { case 0x000d: if (ptr + 1 < end_subject && ptr[1] == 0x0a) ncount = 1; /* Fall through */ case 0x000a: case 0x000b: case 0x000c: case 0x0085: case 0x2028: case 0x2029: if (codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSUPTO) { active_count--; /* Remove non-match possibility */ next_active_state--; } if (++count >= GET2(code, 1)) { ADD_NEW_DATA(-(state_offset + 4), 0, ncount); } else { ADD_NEW_DATA(-state_offset, count, ncount); } break; default: break; } } break; /*-----------------------------------------------------------------*/ case OP_VSPACE_EXTRA + OP_TYPEEXACT: case OP_VSPACE_EXTRA + OP_TYPEUPTO: case OP_VSPACE_EXTRA + OP_TYPEMINUPTO: case OP_VSPACE_EXTRA + OP_TYPEPOSUPTO: if (codevalue != OP_VSPACE_EXTRA + OP_TYPEEXACT) { ADD_ACTIVE(state_offset + 4, 0); } count = current_state->count; /* Number already matched */ if (clen > 0) { BOOL OK; switch (c) { case 0x000a: case 0x000b: case 0x000c: case 0x000d: case 0x0085: case 0x2028: case 0x2029: OK = TRUE; break; default: OK = FALSE; } if (OK == (d == OP_VSPACE)) { if (codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSUPTO) { active_count--; /* Remove non-match possibility */ next_active_state--; } if (++count >= GET2(code, 1)) { ADD_NEW_DATA(-(state_offset + 4), 0, 0); } else { ADD_NEW_DATA(-state_offset, count, 0); } } } break; /*-----------------------------------------------------------------*/ case OP_HSPACE_EXTRA + OP_TYPEEXACT: case OP_HSPACE_EXTRA + OP_TYPEUPTO: case OP_HSPACE_EXTRA + OP_TYPEMINUPTO: case OP_HSPACE_EXTRA + OP_TYPEPOSUPTO: if (codevalue != OP_HSPACE_EXTRA + OP_TYPEEXACT) { ADD_ACTIVE(state_offset + 4, 0); } count = current_state->count; /* Number already matched */ if (clen > 0) { BOOL OK; switch (c) { case 0x09: /* HT */ case 0x20: /* SPACE */ case 0xa0: /* NBSP */ case 0x1680: /* OGHAM SPACE MARK */ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ case 0x2000: /* EN QUAD */ case 0x2001: /* EM QUAD */ case 0x2002: /* EN SPACE */ case 0x2003: /* EM SPACE */ case 0x2004: /* THREE-PER-EM SPACE */ case 0x2005: /* FOUR-PER-EM SPACE */ case 0x2006: /* SIX-PER-EM SPACE */ case 0x2007: /* FIGURE SPACE */ case 0x2008: /* PUNCTUATION SPACE */ case 0x2009: /* THIN SPACE */ case 0x200A: /* HAIR SPACE */ case 0x202f: /* NARROW NO-BREAK SPACE */ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ case 0x3000: /* IDEOGRAPHIC SPACE */ OK = TRUE; break; default: OK = FALSE; break; } if (OK == (d == OP_HSPACE)) { if (codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSUPTO) { active_count--; /* Remove non-match possibility */ next_active_state--; } if (++count >= GET2(code, 1)) { ADD_NEW_DATA(-(state_offset + 4), 0, 0); } else { ADD_NEW_DATA(-state_offset, count, 0); } } } break; /* ========================================================================== */ /* These opcodes are followed by a character that is usually compared to the current subject character; it is loaded into d. We still get here even if there is no subject character, because in some cases zero repetitions are permitted. */ /*-----------------------------------------------------------------*/ case OP_CHAR: if (clen > 0 && c == d) { ADD_NEW(state_offset + dlen + 1, 0); } break; /*-----------------------------------------------------------------*/ case OP_CHARNC: if (clen == 0) break; #ifdef SUPPORT_UTF8 if (utf8) { if (c == d) { ADD_NEW(state_offset + dlen + 1, 0); } else { unsigned int othercase; if (c < 128) othercase = fcc[c]; else /* If we have Unicode property support, we can use it to test the other case of the character. */ #ifdef SUPPORT_UCP othercase = _pcre_ucp_othercase(c); #else othercase = NOTACHAR; #endif if (d == othercase) { ADD_NEW(state_offset + dlen + 1, 0); } } } else #endif /* SUPPORT_UTF8 */ /* Non-UTF-8 mode */ { if (lcc[c] == lcc[d]) { ADD_NEW(state_offset + 2, 0); } } break; #ifdef SUPPORT_UCP /*-----------------------------------------------------------------*/ /* This is a tricky one because it can match more than one character. Find out how many characters to skip, and then set up a negative state to wait for them to pass before continuing. */ case OP_EXTUNI: if (clen > 0 && _pcre_ucp_findprop(c, &chartype, &script) != ucp_M) { const uschar *nptr = ptr + clen; int ncount = 0; while (nptr < end_subject) { int nclen = 1; GETCHARLEN(c, nptr, nclen); if (_pcre_ucp_findprop(c, &chartype, &script) != ucp_M) break; ncount++; nptr += nclen; } ADD_NEW_DATA(-(state_offset + 1), 0, ncount); } break; #endif /*-----------------------------------------------------------------*/ /* This is a tricky like EXTUNI because it too can match more than one character (when CR is followed by LF). In this case, set up a negative state to wait for one character to pass before continuing. */ case OP_ANYNL: if (clen > 0) switch(c) { case 0x000a: case 0x000b: case 0x000c: case 0x0085: case 0x2028: case 0x2029: ADD_NEW(state_offset + 1, 0); break; case 0x000d: if (ptr + 1 < end_subject && ptr[1] == 0x0a) { ADD_NEW_DATA(-(state_offset + 1), 0, 1); } else { ADD_NEW(state_offset + 1, 0); } break; } break; /*-----------------------------------------------------------------*/ case OP_NOT_VSPACE: if (clen > 0) switch(c) { case 0x000a: case 0x000b: case 0x000c: case 0x000d: case 0x0085: case 0x2028: case 0x2029: break; default: ADD_NEW(state_offset + 1, 0); break; } break; /*-----------------------------------------------------------------*/ case OP_VSPACE: if (clen > 0) switch(c) { case 0x000a: case 0x000b: case 0x000c: case 0x000d: case 0x0085: case 0x2028: case 0x2029: ADD_NEW(state_offset + 1, 0); break; default: break; } break; /*-----------------------------------------------------------------*/ case OP_NOT_HSPACE: if (clen > 0) switch(c) { case 0x09: /* HT */ case 0x20: /* SPACE */ case 0xa0: /* NBSP */ case 0x1680: /* OGHAM SPACE MARK */ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ case 0x2000: /* EN QUAD */ case 0x2001: /* EM QUAD */ case 0x2002: /* EN SPACE */ case 0x2003: /* EM SPACE */ case 0x2004: /* THREE-PER-EM SPACE */ case 0x2005: /* FOUR-PER-EM SPACE */ case 0x2006: /* SIX-PER-EM SPACE */ case 0x2007: /* FIGURE SPACE */ case 0x2008: /* PUNCTUATION SPACE */ case 0x2009: /* THIN SPACE */ case 0x200A: /* HAIR SPACE */ case 0x202f: /* NARROW NO-BREAK SPACE */ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ case 0x3000: /* IDEOGRAPHIC SPACE */ break; default: ADD_NEW(state_offset + 1, 0); break; } break; /*-----------------------------------------------------------------*/ case OP_HSPACE: if (clen > 0) switch(c) { case 0x09: /* HT */ case 0x20: /* SPACE */ case 0xa0: /* NBSP */ case 0x1680: /* OGHAM SPACE MARK */ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ case 0x2000: /* EN QUAD */ case 0x2001: /* EM QUAD */ case 0x2002: /* EN SPACE */ case 0x2003: /* EM SPACE */ case 0x2004: /* THREE-PER-EM SPACE */ case 0x2005: /* FOUR-PER-EM SPACE */ case 0x2006: /* SIX-PER-EM SPACE */ case 0x2007: /* FIGURE SPACE */ case 0x2008: /* PUNCTUATION SPACE */ case 0x2009: /* THIN SPACE */ case 0x200A: /* HAIR SPACE */ case 0x202f: /* NARROW NO-BREAK SPACE */ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ case 0x3000: /* IDEOGRAPHIC SPACE */ ADD_NEW(state_offset + 1, 0); break; } break; /*-----------------------------------------------------------------*/ /* Match a negated single character. This is only used for one-byte characters, that is, we know that d < 256. The character we are checking (c) can be multibyte. */ case OP_NOT: if (clen > 0) { unsigned int otherd = ((ims & PCRE_CASELESS) != 0)? fcc[d] : d; if (c != d && c != otherd) { ADD_NEW(state_offset + dlen + 1, 0); } } break; /*-----------------------------------------------------------------*/ case OP_PLUS: case OP_MINPLUS: case OP_POSPLUS: case OP_NOTPLUS: case OP_NOTMINPLUS: case OP_NOTPOSPLUS: count = current_state->count; /* Already matched */ if (count > 0) { ADD_ACTIVE(state_offset + dlen + 1, 0); } if (clen > 0) { unsigned int otherd = NOTACHAR; if ((ims & PCRE_CASELESS) != 0) { #ifdef SUPPORT_UTF8 if (utf8 && d >= 128) { #ifdef SUPPORT_UCP otherd = _pcre_ucp_othercase(d); #endif /* SUPPORT_UCP */ } else #endif /* SUPPORT_UTF8 */ otherd = fcc[d]; } if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR)) { if (count > 0 && (codevalue == OP_POSPLUS || codevalue == OP_NOTPOSPLUS)) { active_count--; /* Remove non-match possibility */ next_active_state--; } count++; ADD_NEW(state_offset, count); } } break; /*-----------------------------------------------------------------*/ case OP_QUERY: case OP_MINQUERY: case OP_POSQUERY: case OP_NOTQUERY: case OP_NOTMINQUERY: case OP_NOTPOSQUERY: ADD_ACTIVE(state_offset + dlen + 1, 0); if (clen > 0) { unsigned int otherd = NOTACHAR; if ((ims & PCRE_CASELESS) != 0) { #ifdef SUPPORT_UTF8 if (utf8 && d >= 128) { #ifdef SUPPORT_UCP otherd = _pcre_ucp_othercase(d); #endif /* SUPPORT_UCP */ } else #endif /* SUPPORT_UTF8 */ otherd = fcc[d]; } if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR)) { if (codevalue == OP_POSQUERY || codevalue == OP_NOTPOSQUERY) { active_count--; /* Remove non-match possibility */ next_active_state--; } ADD_NEW(state_offset + dlen + 1, 0); } } break; /*-----------------------------------------------------------------*/ case OP_STAR: case OP_MINSTAR: case OP_POSSTAR: case OP_NOTSTAR: case OP_NOTMINSTAR: case OP_NOTPOSSTAR: ADD_ACTIVE(state_offset + dlen + 1, 0); if (clen > 0) { unsigned int otherd = NOTACHAR; if ((ims & PCRE_CASELESS) != 0) { #ifdef SUPPORT_UTF8 if (utf8 && d >= 128) { #ifdef SUPPORT_UCP otherd = _pcre_ucp_othercase(d); #endif /* SUPPORT_UCP */ } else #endif /* SUPPORT_UTF8 */ otherd = fcc[d]; } if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR)) { if (codevalue == OP_POSSTAR || codevalue == OP_NOTPOSSTAR) { active_count--; /* Remove non-match possibility */ next_active_state--; } ADD_NEW(state_offset, 0); } } break; /*-----------------------------------------------------------------*/ case OP_EXACT: case OP_NOTEXACT: count = current_state->count; /* Number already matched */ if (clen > 0) { unsigned int otherd = NOTACHAR; if ((ims & PCRE_CASELESS) != 0) { #ifdef SUPPORT_UTF8 if (utf8 && d >= 128) { #ifdef SUPPORT_UCP otherd = _pcre_ucp_othercase(d); #endif /* SUPPORT_UCP */ } else #endif /* SUPPORT_UTF8 */ otherd = fcc[d]; } if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR)) { if (++count >= GET2(code, 1)) { ADD_NEW(state_offset + dlen + 3, 0); } else { ADD_NEW(state_offset, count); } } } break; /*-----------------------------------------------------------------*/ case OP_UPTO: case OP_MINUPTO: case OP_POSUPTO: case OP_NOTUPTO: case OP_NOTMINUPTO: case OP_NOTPOSUPTO: ADD_ACTIVE(state_offset + dlen + 3, 0); count = current_state->count; /* Number already matched */ if (clen > 0) { unsigned int otherd = NOTACHAR; if ((ims & PCRE_CASELESS) != 0) { #ifdef SUPPORT_UTF8 if (utf8 && d >= 128) { #ifdef SUPPORT_UCP otherd = _pcre_ucp_othercase(d); #endif /* SUPPORT_UCP */ } else #endif /* SUPPORT_UTF8 */ otherd = fcc[d]; } if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR)) { if (codevalue == OP_POSUPTO || codevalue == OP_NOTPOSUPTO) { active_count--; /* Remove non-match possibility */ next_active_state--; } if (++count >= GET2(code, 1)) { ADD_NEW(state_offset + dlen + 3, 0); } else { ADD_NEW(state_offset, count); } } } break; /* ========================================================================== */ /* These are the class-handling opcodes */ case OP_CLASS: case OP_NCLASS: case OP_XCLASS: { BOOL isinclass = FALSE; int next_state_offset; const uschar *ecode; /* For a simple class, there is always just a 32-byte table, and we can set isinclass from it. */ if (codevalue != OP_XCLASS) { ecode = code + 33; if (clen > 0) { isinclass = (c > 255)? (codevalue == OP_NCLASS) : ((code[1 + c/8] & (1 << (c&7))) != 0); } } /* An extended class may have a table or a list of single characters, ranges, or both, and it may be positive or negative. There's a function that sorts all this out. */ else { ecode = code + GET(code, 1); if (clen > 0) isinclass = _pcre_xclass(c, code + 1 + LINK_SIZE); } /* At this point, isinclass is set for all kinds of class, and ecode points to the byte after the end of the class. If there is a quantifier, this is where it will be. */ next_state_offset = ecode - start_code; switch (*ecode) { case OP_CRSTAR: case OP_CRMINSTAR: ADD_ACTIVE(next_state_offset + 1, 0); if (isinclass) { ADD_NEW(state_offset, 0); } break; case OP_CRPLUS: case OP_CRMINPLUS: count = current_state->count; /* Already matched */ if (count > 0) { ADD_ACTIVE(next_state_offset + 1, 0); } if (isinclass) { count++; ADD_NEW(state_offset, count); } break; case OP_CRQUERY: case OP_CRMINQUERY: ADD_ACTIVE(next_state_offset + 1, 0); if (isinclass) { ADD_NEW(next_state_offset + 1, 0); } break; case OP_CRRANGE: case OP_CRMINRANGE: count = current_state->count; /* Already matched */ if (count >= GET2(ecode, 1)) { ADD_ACTIVE(next_state_offset + 5, 0); } if (isinclass) { int max = GET2(ecode, 3); if (++count >= max && max != 0) /* Max 0 => no limit */ { ADD_NEW(next_state_offset + 5, 0); } else { ADD_NEW(state_offset, count); } } break; default: if (isinclass) { ADD_NEW(next_state_offset, 0); } break; } } break; /* ========================================================================== */ /* These are the opcodes for fancy brackets of various kinds. We have to use recursion in order to handle them. */ case OP_ASSERT: case OP_ASSERT_NOT: case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: { int rc; int local_offsets[2]; int local_workspace[1000]; const uschar *endasscode = code + GET(code, 1); while (*endasscode == OP_ALT) endasscode += GET(endasscode, 1); rc = internal_dfa_exec( md, /* static match data */ code, /* this subexpression's code */ ptr, /* where we currently are */ ptr - start_subject, /* start offset */ local_offsets, /* offset vector */ sizeof(local_offsets)/sizeof(int), /* size of same */ local_workspace, /* workspace vector */ sizeof(local_workspace)/sizeof(int), /* size of same */ ims, /* the current ims flags */ rlevel, /* function recursion level */ recursing); /* pass on regex recursion */ if ((rc >= 0) == (codevalue == OP_ASSERT || codevalue == OP_ASSERTBACK)) { ADD_ACTIVE(endasscode + LINK_SIZE + 1 - start_code, 0); } } break; /*-----------------------------------------------------------------*/ case OP_COND: case OP_SCOND: { int local_offsets[1000]; int local_workspace[1000]; int condcode = code[LINK_SIZE+1]; /* Back reference conditions are not supported */ if (condcode == OP_CREF) return PCRE_ERROR_DFA_UCOND; /* The DEFINE condition is always false */ if (condcode == OP_DEF) { ADD_ACTIVE(state_offset + GET(code, 1) + LINK_SIZE + 1, 0); } /* The only supported version of OP_RREF is for the value RREF_ANY, which means "test if in any recursion". We can't test for specifically recursed groups. */ else if (condcode == OP_RREF) { int value = GET2(code, LINK_SIZE+2); if (value != RREF_ANY) return PCRE_ERROR_DFA_UCOND; if (recursing > 0) { ADD_ACTIVE(state_offset + LINK_SIZE + 4, 0); } else { ADD_ACTIVE(state_offset + GET(code, 1) + LINK_SIZE + 1, 0); } } /* Otherwise, the condition is an assertion */ else { int rc; const uschar *asscode = code + LINK_SIZE + 1; const uschar *endasscode = asscode + GET(asscode, 1); while (*endasscode == OP_ALT) endasscode += GET(endasscode, 1); rc = internal_dfa_exec( md, /* fixed match data */ asscode, /* this subexpression's code */ ptr, /* where we currently are */ ptr - start_subject, /* start offset */ local_offsets, /* offset vector */ sizeof(local_offsets)/sizeof(int), /* size of same */ local_workspace, /* workspace vector */ sizeof(local_workspace)/sizeof(int), /* size of same */ ims, /* the current ims flags */ rlevel, /* function recursion level */ recursing); /* pass on regex recursion */ if ((rc >= 0) == (condcode == OP_ASSERT || condcode == OP_ASSERTBACK)) { ADD_ACTIVE(endasscode + LINK_SIZE + 1 - start_code, 0); } else { ADD_ACTIVE(state_offset + GET(code, 1) + LINK_SIZE + 1, 0); } } } break; /*-----------------------------------------------------------------*/ case OP_RECURSE: { int local_offsets[1000]; int local_workspace[1000]; int rc; DPRINTF(("%.*sStarting regex recursion %d\n", rlevel*2-2, SP, recursing + 1)); rc = internal_dfa_exec( md, /* fixed match data */ start_code + GET(code, 1), /* this subexpression's code */ ptr, /* where we currently are */ ptr - start_subject, /* start offset */ local_offsets, /* offset vector */ sizeof(local_offsets)/sizeof(int), /* size of same */ local_workspace, /* workspace vector */ sizeof(local_workspace)/sizeof(int), /* size of same */ ims, /* the current ims flags */ rlevel, /* function recursion level */ recursing + 1); /* regex recurse level */ DPRINTF(("%.*sReturn from regex recursion %d: rc=%d\n", rlevel*2-2, SP, recursing + 1, rc)); /* Ran out of internal offsets */ if (rc == 0) return PCRE_ERROR_DFA_RECURSE; /* For each successful matched substring, set up the next state with a count of characters to skip before trying it. Note that the count is in characters, not bytes. */ if (rc > 0) { for (rc = rc*2 - 2; rc >= 0; rc -= 2) { const uschar *p = start_subject + local_offsets[rc]; const uschar *pp = start_subject + local_offsets[rc+1]; int charcount = local_offsets[rc+1] - local_offsets[rc]; while (p < pp) if ((*p++ & 0xc0) == 0x80) charcount--; if (charcount > 0) { ADD_NEW_DATA(-(state_offset + LINK_SIZE + 1), 0, (charcount - 1)); } else { ADD_ACTIVE(state_offset + LINK_SIZE + 1, 0); } } } else if (rc != PCRE_ERROR_NOMATCH) return rc; } break; /*-----------------------------------------------------------------*/ case OP_ONCE: { int local_offsets[2]; int local_workspace[1000]; int rc = internal_dfa_exec( md, /* fixed match data */ code, /* this subexpression's code */ ptr, /* where we currently are */ ptr - start_subject, /* start offset */ local_offsets, /* offset vector */ sizeof(local_offsets)/sizeof(int), /* size of same */ local_workspace, /* workspace vector */ sizeof(local_workspace)/sizeof(int), /* size of same */ ims, /* the current ims flags */ rlevel, /* function recursion level */ recursing); /* pass on regex recursion */ if (rc >= 0) { const uschar *end_subpattern = code; int charcount = local_offsets[1] - local_offsets[0]; int next_state_offset, repeat_state_offset; do { end_subpattern += GET(end_subpattern, 1); } while (*end_subpattern == OP_ALT); next_state_offset = end_subpattern - start_code + LINK_SIZE + 1; /* If the end of this subpattern is KETRMAX or KETRMIN, we must arrange for the repeat state also to be added to the relevant list. Calculate the offset, or set -1 for no repeat. */ repeat_state_offset = (*end_subpattern == OP_KETRMAX || *end_subpattern == OP_KETRMIN)? end_subpattern - start_code - GET(end_subpattern, 1) : -1; /* If we have matched an empty string, add the next state at the current character pointer. This is important so that the duplicate checking kicks in, which is what breaks infinite loops that match an empty string. */ if (charcount == 0) { ADD_ACTIVE(next_state_offset, 0); } /* Optimization: if there are no more active states, and there are no new states yet set up, then skip over the subject string right here, to save looping. Otherwise, set up the new state to swing into action when the end of the substring is reached. */ else if (i + 1 >= active_count && new_count == 0) { ptr += charcount; clen = 0; ADD_NEW(next_state_offset, 0); /* If we are adding a repeat state at the new character position, we must fudge things so that it is the only current state. Otherwise, it might be a duplicate of one we processed before, and that would cause it to be skipped. */ if (repeat_state_offset >= 0) { next_active_state = active_states; active_count = 0; i = -1; ADD_ACTIVE(repeat_state_offset, 0); } } else { const uschar *p = start_subject + local_offsets[0]; const uschar *pp = start_subject + local_offsets[1]; while (p < pp) if ((*p++ & 0xc0) == 0x80) charcount--; ADD_NEW_DATA(-next_state_offset, 0, (charcount - 1)); if (repeat_state_offset >= 0) { ADD_NEW_DATA(-repeat_state_offset, 0, (charcount - 1)); } } } else if (rc != PCRE_ERROR_NOMATCH) return rc; } break; /* ========================================================================== */ /* Handle callouts */ case OP_CALLOUT: if (pcre_callout != NULL) { int rrc; pcre_callout_block cb; cb.version = 1; /* Version 1 of the callout block */ cb.callout_number = code[1]; cb.offset_vector = offsets; cb.subject = (PCRE_SPTR)start_subject; cb.subject_length = end_subject - start_subject; cb.start_match = current_subject - start_subject; cb.current_position = ptr - start_subject; cb.pattern_position = GET(code, 2); cb.next_item_length = GET(code, 2 + LINK_SIZE); cb.capture_top = 1; cb.capture_last = -1; cb.callout_data = md->callout_data; if ((rrc = (*pcre_callout)(&cb)) < 0) return rrc; /* Abandon */ if (rrc == 0) { ADD_ACTIVE(state_offset + 2 + 2*LINK_SIZE, 0); } } break; /* ========================================================================== */ default: /* Unsupported opcode */ return PCRE_ERROR_DFA_UITEM; } NEXT_ACTIVE_STATE: continue; } /* End of loop scanning active states */ /* We have finished the processing at the current subject character. If no new states have been set for the next character, we have found all the matches that we are going to find. If we are at the top level and partial matching has been requested, check for appropriate conditions. */ if (new_count <= 0) { if (match_count < 0 && /* No matches found */ rlevel == 1 && /* Top level match function */ (md->moptions & PCRE_PARTIAL) != 0 && /* Want partial matching */ ptr >= end_subject && /* Reached end of subject */ ptr > current_subject) /* Matched non-empty string */ { if (offsetcount >= 2) { offsets[0] = current_subject - start_subject; offsets[1] = end_subject - start_subject; } match_count = PCRE_ERROR_PARTIAL; } DPRINTF(("%.*sEnd of internal_dfa_exec %d: returning %d\n" "%.*s---------------------\n\n", rlevel*2-2, SP, rlevel, match_count, rlevel*2-2, SP)); break; /* In effect, "return", but see the comment below */ } /* One or more states are active for the next character. */ ptr += clen; /* Advance to next subject character */ } /* Loop to move along the subject string */ /* Control gets here from "break" a few lines above. We do it this way because if we use "return" above, we have compiler trouble. Some compilers warn if there's nothing here because they think the function doesn't return a value. On the other hand, if we put a dummy statement here, some more clever compilers complain that it can't be reached. Sigh. */ return match_count; } /************************************************* * Execute a Regular Expression - DFA engine * *************************************************/ /* This external function applies a compiled re to a subject string using a DFA engine. This function calls the internal function multiple times if the pattern is not anchored. Arguments: argument_re points to the compiled expression extra_data points to extra data or is NULL subject points to the subject string length length of subject string (may contain binary zeros) start_offset where to start in the subject string options option bits offsets vector of match offsets offsetcount size of same workspace workspace vector wscount size of same Returns: > 0 => number of match offset pairs placed in offsets = 0 => offsets overflowed; longest matches are present -1 => failed to match < -1 => some kind of unexpected problem */ PCRE_EXP_DEFN int pcre_dfa_exec(const pcre *argument_re, const pcre_extra *extra_data, const char *subject, int length, int start_offset, int options, int *offsets, int offsetcount, int *workspace, int wscount) { real_pcre *re = (real_pcre *)argument_re; dfa_match_data match_block; dfa_match_data *md = &match_block; BOOL utf8, anchored, startline, firstline; const uschar *current_subject, *end_subject, *lcc; pcre_study_data internal_study; const pcre_study_data *study = NULL; real_pcre internal_re; const uschar *req_byte_ptr; const uschar *start_bits = NULL; BOOL first_byte_caseless = FALSE; BOOL req_byte_caseless = FALSE; int first_byte = -1; int req_byte = -1; int req_byte2 = -1; int newline; /* Plausibility checks */ if ((options & ~PUBLIC_DFA_EXEC_OPTIONS) != 0) return PCRE_ERROR_BADOPTION; if (re == NULL || subject == NULL || workspace == NULL || (offsets == NULL && offsetcount > 0)) return PCRE_ERROR_NULL; if (offsetcount < 0) return PCRE_ERROR_BADCOUNT; if (wscount < 20) return PCRE_ERROR_DFA_WSSIZE; /* We need to find the pointer to any study data before we test for byte flipping, so we scan the extra_data block first. This may set two fields in the match block, so we must initialize them beforehand. However, the other fields in the match block must not be set until after the byte flipping. */ md->tables = re->tables; md->callout_data = NULL; if (extra_data != NULL) { unsigned int flags = extra_data->flags; if ((flags & PCRE_EXTRA_STUDY_DATA) != 0) study = (const pcre_study_data *)extra_data->study_data; if ((flags & PCRE_EXTRA_MATCH_LIMIT) != 0) return PCRE_ERROR_DFA_UMLIMIT; if ((flags & PCRE_EXTRA_MATCH_LIMIT_RECURSION) != 0) return PCRE_ERROR_DFA_UMLIMIT; if ((flags & PCRE_EXTRA_CALLOUT_DATA) != 0) md->callout_data = extra_data->callout_data; if ((flags & PCRE_EXTRA_TABLES) != 0) md->tables = extra_data->tables; } /* Check that the first field in the block is the magic number. If it is not, test for a regex that was compiled on a host of opposite endianness. If this is the case, flipped values are put in internal_re and internal_study if there was study data too. */ if (re->magic_number != MAGIC_NUMBER) { re = _pcre_try_flipped(re, &internal_re, study, &internal_study); if (re == NULL) return PCRE_ERROR_BADMAGIC; if (study != NULL) study = &internal_study; } /* Set some local values */ current_subject = (const unsigned char *)subject + start_offset; end_subject = (const unsigned char *)subject + length; req_byte_ptr = current_subject - 1; #ifdef SUPPORT_UTF8 utf8 = (re->options & PCRE_UTF8) != 0; #else utf8 = FALSE; #endif anchored = (options & (PCRE_ANCHORED|PCRE_DFA_RESTART)) != 0 || (re->options & PCRE_ANCHORED) != 0; /* The remaining fixed data for passing around. */ md->start_code = (const uschar *)argument_re + re->name_table_offset + re->name_count * re->name_entry_size; md->start_subject = (const unsigned char *)subject; md->end_subject = end_subject; md->moptions = options; md->poptions = re->options; /* Handle different types of newline. The three bits give eight cases. If nothing is set at run time, whatever was used at compile time applies. */ switch ((((options & PCRE_NEWLINE_BITS) == 0)? re->options : (pcre_uint32)options) & PCRE_NEWLINE_BITS) { case 0: newline = NEWLINE; break; /* Compile-time default */ case PCRE_NEWLINE_CR: newline = '\r'; break; case PCRE_NEWLINE_LF: newline = '\n'; break; case PCRE_NEWLINE_CR+ PCRE_NEWLINE_LF: newline = ('\r' << 8) | '\n'; break; case PCRE_NEWLINE_ANY: newline = -1; break; case PCRE_NEWLINE_ANYCRLF: newline = -2; break; default: return PCRE_ERROR_BADNEWLINE; } if (newline == -2) { md->nltype = NLTYPE_ANYCRLF; } else if (newline < 0) { md->nltype = NLTYPE_ANY; } else { md->nltype = NLTYPE_FIXED; if (newline > 255) { md->nllen = 2; md->nl[0] = (newline >> 8) & 255; md->nl[1] = newline & 255; } else { md->nllen = 1; md->nl[0] = newline; } } /* Check a UTF-8 string if required. Unfortunately there's no way of passing back the character offset. */ #ifdef SUPPORT_UTF8 if (utf8 && (options & PCRE_NO_UTF8_CHECK) == 0) { if (_pcre_valid_utf8((uschar *)subject, length) >= 0) return PCRE_ERROR_BADUTF8; if (start_offset > 0 && start_offset < length) { int tb = ((uschar *)subject)[start_offset]; if (tb > 127) { tb &= 0xc0; if (tb != 0 && tb != 0xc0) return PCRE_ERROR_BADUTF8_OFFSET; } } } #endif /* If the exec call supplied NULL for tables, use the inbuilt ones. This is a feature that makes it possible to save compiled regex and re-use them in other programs later. */ if (md->tables == NULL) md->tables = _pcre_default_tables; /* The lower casing table and the "must be at the start of a line" flag are used in a loop when finding where to start. */ lcc = md->tables + lcc_offset; startline = (re->options & PCRE_STARTLINE) != 0; firstline = (re->options & PCRE_FIRSTLINE) != 0; /* Set up the first character to match, if available. The first_byte value is never set for an anchored regular expression, but the anchoring may be forced at run time, so we have to test for anchoring. The first char may be unset for an unanchored pattern, of course. If there's no first char and the pattern was studied, there may be a bitmap of possible first characters. */ if (!anchored) { if ((re->options & PCRE_FIRSTSET) != 0) { first_byte = re->first_byte & 255; if ((first_byte_caseless = ((re->first_byte & REQ_CASELESS) != 0)) == TRUE) first_byte = lcc[first_byte]; } else { if (startline && study != NULL && (study->options & PCRE_STUDY_MAPPED) != 0) start_bits = study->start_bits; } } /* For anchored or unanchored matches, there may be a "last known required character" set. */ if ((re->options & PCRE_REQCHSET) != 0) { req_byte = re->req_byte & 255; req_byte_caseless = (re->req_byte & REQ_CASELESS) != 0; req_byte2 = (md->tables + fcc_offset)[req_byte]; /* case flipped */ } /* Call the main matching function, looping for a non-anchored regex after a failed match. Unless restarting, optimize by moving to the first match character if possible, when not anchored. Then unless wanting a partial match, check for a required later character. */ for (;;) { int rc; if ((options & PCRE_DFA_RESTART) == 0) { const uschar *save_end_subject = end_subject; /* Advance to a unique first char if possible. If firstline is TRUE, the start of the match is constrained to the first line of a multiline string. Implement this by temporarily adjusting end_subject so that we stop scanning at a newline. If the match fails at the newline, later code breaks this loop. */ if (firstline) { const uschar *t = current_subject; while (t < md->end_subject && !IS_NEWLINE(t)) t++; end_subject = t; } if (first_byte >= 0) { if (first_byte_caseless) while (current_subject < end_subject && lcc[*current_subject] != first_byte) current_subject++; else while (current_subject < end_subject && *current_subject != first_byte) current_subject++; } /* Or to just after a linebreak for a multiline match if possible */ else if (startline) { if (current_subject > md->start_subject + start_offset) { while (current_subject <= end_subject && !WAS_NEWLINE(current_subject)) current_subject++; /* If we have just passed a CR and the newline option is ANY or ANYCRLF, and we are now at a LF, advance the match position by one more character. */ if (current_subject[-1] == '\r' && (md->nltype == NLTYPE_ANY || md->nltype == NLTYPE_ANYCRLF) && current_subject < end_subject && *current_subject == '\n') current_subject++; } } /* Or to a non-unique first char after study */ else if (start_bits != NULL) { while (current_subject < end_subject) { register unsigned int c = *current_subject; if ((start_bits[c/8] & (1 << (c&7))) == 0) current_subject++; else break; } } /* Restore fudged end_subject */ end_subject = save_end_subject; } /* If req_byte is set, we know that that character must appear in the subject for the match to succeed. If the first character is set, req_byte must be later in the subject; otherwise the test starts at the match point. This optimization can save a huge amount of work in patterns with nested unlimited repeats that aren't going to match. Writing separate code for cased/caseless versions makes it go faster, as does using an autoincrement and backing off on a match. HOWEVER: when the subject string is very, very long, searching to its end can take a long time, and give bad performance on quite ordinary patterns. This showed up when somebody was matching /^C/ on a 32-megabyte string... so we don't do this when the string is sufficiently long. ALSO: this processing is disabled when partial matching is requested. */ if (req_byte >= 0 && end_subject - current_subject < REQ_BYTE_MAX && (options & PCRE_PARTIAL) == 0) { register const uschar *p = current_subject + ((first_byte >= 0)? 1 : 0); /* We don't need to repeat the search if we haven't yet reached the place we found it at last time. */ if (p > req_byte_ptr) { if (req_byte_caseless) { while (p < end_subject) { register int pp = *p++; if (pp == req_byte || pp == req_byte2) { p--; break; } } } else { while (p < end_subject) { if (*p++ == req_byte) { p--; break; } } } /* If we can't find the required character, break the matching loop, which will cause a return or PCRE_ERROR_NOMATCH. */ if (p >= end_subject) break; /* If we have found the required character, save the point where we found it, so that we don't search again next time round the loop if the start hasn't passed this character yet. */ req_byte_ptr = p; } } /* OK, now we can do the business */ rc = internal_dfa_exec( md, /* fixed match data */ md->start_code, /* this subexpression's code */ current_subject, /* where we currently are */ start_offset, /* start offset in subject */ offsets, /* offset vector */ offsetcount, /* size of same */ workspace, /* workspace vector */ wscount, /* size of same */ re->options & (PCRE_CASELESS|PCRE_MULTILINE|PCRE_DOTALL), /* ims flags */ 0, /* function recurse level */ 0); /* regex recurse level */ /* Anything other than "no match" means we are done, always; otherwise, carry on only if not anchored. */ if (rc != PCRE_ERROR_NOMATCH || anchored) return rc; /* Advance to the next subject character unless we are at the end of a line and firstline is set. */ if (firstline && IS_NEWLINE(current_subject)) break; current_subject++; if (utf8) { while (current_subject < end_subject && (*current_subject & 0xc0) == 0x80) current_subject++; } if (current_subject > end_subject) break; /* If we have just passed a CR and we are now at a LF, and the pattern does not contain any explicit matches for \r or \n, and the newline option is CRLF or ANY or ANYCRLF, advance the match position by one more character. */ if (current_subject[-1] == '\r' && current_subject < end_subject && *current_subject == '\n' && (re->options & PCRE_HASCRORLF) == 0 && (md->nltype == NLTYPE_ANY || md->nltype == NLTYPE_ANYCRLF || md->nllen == 2)) current_subject++; } /* "Bumpalong" loop */ return PCRE_ERROR_NOMATCH; } /* End of pcre_dfa_exec.c */ libsynthesis-3.4.0.47.1/src/pcre/pcre_exec.c000066400000000000000000004432241226375725500204760ustar00rootroot00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2007 University of Cambridge ----------------------------------------------------------------------------- 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 name of the University of Cambridge 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. ----------------------------------------------------------------------------- */ /* This module contains pcre_exec(), the externally visible function that does pattern matching using an NFA algorithm, trying to mimic Perl as closely as possible. There are also some static supporting functions. */ #include "pcre_setup.h" #define NLBLOCK md /* Block containing newline information */ #define PSSTART start_subject /* Field containing processed string start */ #define PSEND end_subject /* Field containing processed string end */ #include "pcre_internal.h" /* Undefine some potentially clashing cpp symbols */ #undef min #undef max /* Flag bits for the match() function */ #define match_condassert 0x01 /* Called to check a condition assertion */ #define match_cbegroup 0x02 /* Could-be-empty unlimited repeat group */ /* Non-error returns from the match() function. Error returns are externally defined PCRE_ERROR_xxx codes, which are all negative. */ #define MATCH_MATCH 1 #define MATCH_NOMATCH 0 /* Special internal returns from the match() function. Make them sufficiently negative to avoid the external error codes. */ #define MATCH_COMMIT (-999) #define MATCH_PRUNE (-998) #define MATCH_SKIP (-997) #define MATCH_THEN (-996) /* Maximum number of ints of offset to save on the stack for recursive calls. If the offset vector is bigger, malloc is used. This should be a multiple of 3, because the offset vector is always a multiple of 3 long. */ #define REC_STACK_SAVE_MAX 30 /* Min and max values for the common repeats; for the maxima, 0 => infinity */ static const char rep_min[] = { 0, 0, 1, 1, 0, 0 }; static const char rep_max[] = { 0, 0, 0, 0, 1, 1 }; #ifdef DEBUG /************************************************* * Debugging function to print chars * *************************************************/ /* Print a sequence of chars in printable format, stopping at the end of the subject if the requested. Arguments: p points to characters length number to print is_subject TRUE if printing from within md->start_subject md pointer to matching data block, if is_subject is TRUE Returns: nothing */ static void pchars(const uschar *p, int length, BOOL is_subject, match_data *md) { unsigned int c; if (is_subject && length > md->end_subject - p) length = md->end_subject - p; while (length-- > 0) if (isprint(c = *(p++))) printf("%c", c); else printf("\\x%02x", c); } #endif /************************************************* * Match a back-reference * *************************************************/ /* If a back reference hasn't been set, the length that is passed is greater than the number of characters left in the string, so the match fails. Arguments: offset index into the offset vector eptr points into the subject length length to be matched md points to match data block ims the ims flags Returns: TRUE if matched */ static BOOL match_ref(int offset, register USPTR eptr, int length, match_data *md, unsigned long int ims) { USPTR p = md->start_subject + md->offset_vector[offset]; #ifdef DEBUG if (eptr >= md->end_subject) printf("matching subject "); else { printf("matching subject "); pchars(eptr, length, TRUE, md); } printf(" against backref "); pchars(p, length, FALSE, md); printf("\n"); #endif /* Always fail if not enough characters left */ if (length > md->end_subject - eptr) return FALSE; /* Separate the caselesss case for speed */ if ((ims & PCRE_CASELESS) != 0) { while (length-- > 0) if (md->lcc[*p++] != md->lcc[*eptr++]) return FALSE; } else { while (length-- > 0) if (*p++ != *eptr++) return FALSE; } return TRUE; } /*************************************************************************** **************************************************************************** RECURSION IN THE match() FUNCTION The match() function is highly recursive, though not every recursive call increases the recursive depth. Nevertheless, some regular expressions can cause it to recurse to a great depth. I was writing for Unix, so I just let it call itself recursively. This uses the stack for saving everything that has to be saved for a recursive call. On Unix, the stack can be large, and this works fine. It turns out that on some non-Unix-like systems there are problems with programs that use a lot of stack. (This despite the fact that every last chip has oodles of memory these days, and techniques for extending the stack have been known for decades.) So.... There is a fudge, triggered by defining NO_RECURSE, which avoids recursive calls by keeping local variables that need to be preserved in blocks of memory obtained from malloc() instead instead of on the stack. Macros are used to achieve this so that the actual code doesn't look very different to what it always used to. The original heap-recursive code used longjmp(). However, it seems that this can be very slow on some operating systems. Following a suggestion from Stan Switzer, the use of longjmp() has been abolished, at the cost of having to provide a unique number for each call to RMATCH. There is no way of generating a sequence of numbers at compile time in C. I have given them names, to make them stand out more clearly. Crude tests on x86 Linux show a small speedup of around 5-8%. However, on FreeBSD, avoiding longjmp() more than halves the time taken to run the standard tests. Furthermore, not using longjmp() means that local dynamic variables don't have indeterminate values; this has meant that the frame size can be reduced because the result can be "passed back" by straight setting of the variable instead of being passed in the frame. **************************************************************************** ***************************************************************************/ /* Numbers for RMATCH calls. When this list is changed, the code at HEAP_RETURN below must be updated in sync. */ enum { RM1=1, RM2, RM3, RM4, RM5, RM6, RM7, RM8, RM9, RM10, RM11, RM12, RM13, RM14, RM15, RM16, RM17, RM18, RM19, RM20, RM21, RM22, RM23, RM24, RM25, RM26, RM27, RM28, RM29, RM30, RM31, RM32, RM33, RM34, RM35, RM36, RM37, RM38, RM39, RM40, RM41, RM42, RM43, RM44, RM45, RM46, RM47, RM48, RM49, RM50, RM51, RM52, RM53, RM54 }; /* These versions of the macros use the stack, as normal. There are debugging versions and production versions. Note that the "rw" argument of RMATCH isn't actuall used in this definition. */ #ifndef NO_RECURSE #define REGISTER register #ifdef DEBUG #define RMATCH(ra,rb,rc,rd,re,rf,rg,rw) \ { \ printf("match() called in line %d\n", __LINE__); \ rrc = match(ra,rb,mstart,rc,rd,re,rf,rg,rdepth+1); \ printf("to line %d\n", __LINE__); \ } #define RRETURN(ra) \ { \ printf("match() returned %d from line %d ", ra, __LINE__); \ return ra; \ } #else #define RMATCH(ra,rb,rc,rd,re,rf,rg,rw) \ rrc = match(ra,rb,mstart,rc,rd,re,rf,rg,rdepth+1) #define RRETURN(ra) return ra #endif #else /* These versions of the macros manage a private stack on the heap. Note that the "rd" argument of RMATCH isn't actually used in this definition. It's the md argument of match(), which never changes. */ #define REGISTER #define RMATCH(ra,rb,rc,rd,re,rf,rg,rw)\ {\ heapframe *newframe = (pcre_stack_malloc)(sizeof(heapframe));\ frame->Xwhere = rw; \ newframe->Xeptr = ra;\ newframe->Xecode = rb;\ newframe->Xmstart = mstart;\ newframe->Xoffset_top = rc;\ newframe->Xims = re;\ newframe->Xeptrb = rf;\ newframe->Xflags = rg;\ newframe->Xrdepth = frame->Xrdepth + 1;\ newframe->Xprevframe = frame;\ frame = newframe;\ DPRINTF(("restarting from line %d\n", __LINE__));\ goto HEAP_RECURSE;\ L_##rw:\ DPRINTF(("jumped back to line %d\n", __LINE__));\ } #define RRETURN(ra)\ {\ heapframe *newframe = frame;\ frame = newframe->Xprevframe;\ (pcre_stack_free)(newframe);\ if (frame != NULL)\ {\ rrc = ra;\ goto HEAP_RETURN;\ }\ return ra;\ } /* Structure for remembering the local variables in a private frame */ typedef struct heapframe { struct heapframe *Xprevframe; /* Function arguments that may change */ const uschar *Xeptr; const uschar *Xecode; const uschar *Xmstart; int Xoffset_top; long int Xims; eptrblock *Xeptrb; int Xflags; unsigned int Xrdepth; /* Function local variables */ const uschar *Xcallpat; const uschar *Xcharptr; const uschar *Xdata; const uschar *Xnext; const uschar *Xpp; const uschar *Xprev; const uschar *Xsaved_eptr; recursion_info Xnew_recursive; BOOL Xcur_is_word; BOOL Xcondition; BOOL Xprev_is_word; unsigned long int Xoriginal_ims; #ifdef SUPPORT_UCP int Xprop_type; int Xprop_value; int Xprop_fail_result; int Xprop_category; int Xprop_chartype; int Xprop_script; int Xoclength; uschar Xocchars[8]; #endif int Xctype; unsigned int Xfc; int Xfi; int Xlength; int Xmax; int Xmin; int Xnumber; int Xoffset; int Xop; int Xsave_capture_last; int Xsave_offset1, Xsave_offset2, Xsave_offset3; int Xstacksave[REC_STACK_SAVE_MAX]; eptrblock Xnewptrb; /* Where to jump back to */ int Xwhere; } heapframe; #endif /*************************************************************************** ***************************************************************************/ /************************************************* * Match from current position * *************************************************/ /* This function is called recursively in many circumstances. Whenever it returns a negative (error) response, the outer incarnation must also return the same response. Performance note: It might be tempting to extract commonly used fields from the md structure (e.g. utf8, end_subject) into individual variables to improve performance. Tests using gcc on a SPARC disproved this; in the first case, it made performance worse. Arguments: eptr pointer to current character in subject ecode pointer to current position in compiled code mstart pointer to the current match start position (can be modified by encountering \K) offset_top current top pointer md pointer to "static" info for the match ims current /i, /m, and /s options eptrb pointer to chain of blocks containing eptr at start of brackets - for testing for empty matches flags can contain match_condassert - this is an assertion condition match_cbegroup - this is the start of an unlimited repeat group that can match an empty string rdepth the recursion depth Returns: MATCH_MATCH if matched ) these values are >= 0 MATCH_NOMATCH if failed to match ) a negative PCRE_ERROR_xxx value if aborted by an error condition (e.g. stopped by repeated call or recursion limit) */ static int match(REGISTER USPTR eptr, REGISTER const uschar *ecode, const uschar *mstart, int offset_top, match_data *md, unsigned long int ims, eptrblock *eptrb, int flags, unsigned int rdepth) { /* These variables do not need to be preserved over recursion in this function, so they can be ordinary variables in all cases. Mark some of them with "register" because they are used a lot in loops. */ register int rrc; /* Returns from recursive calls */ register int i; /* Used for loops not involving calls to RMATCH() */ register unsigned int c; /* Character values not kept over RMATCH() calls */ register BOOL utf8; /* Local copy of UTF-8 flag for speed */ BOOL minimize, possessive; /* Quantifier options */ /* When recursion is not being used, all "local" variables that have to be preserved over calls to RMATCH() are part of a "frame" which is obtained from heap storage. Set up the top-level frame here; others are obtained from the heap whenever RMATCH() does a "recursion". See the macro definitions above. */ #ifdef NO_RECURSE heapframe *frame = (pcre_stack_malloc)(sizeof(heapframe)); frame->Xprevframe = NULL; /* Marks the top level */ /* Copy in the original argument variables */ frame->Xeptr = eptr; frame->Xecode = ecode; frame->Xmstart = mstart; frame->Xoffset_top = offset_top; frame->Xims = ims; frame->Xeptrb = eptrb; frame->Xflags = flags; frame->Xrdepth = rdepth; /* This is where control jumps back to to effect "recursion" */ HEAP_RECURSE: /* Macros make the argument variables come from the current frame */ #define eptr frame->Xeptr #define ecode frame->Xecode #define mstart frame->Xmstart #define offset_top frame->Xoffset_top #define ims frame->Xims #define eptrb frame->Xeptrb #define flags frame->Xflags #define rdepth frame->Xrdepth /* Ditto for the local variables */ #ifdef SUPPORT_UTF8 #define charptr frame->Xcharptr #endif #define callpat frame->Xcallpat #define data frame->Xdata #define next frame->Xnext #define pp frame->Xpp #define prev frame->Xprev #define saved_eptr frame->Xsaved_eptr #define new_recursive frame->Xnew_recursive #define cur_is_word frame->Xcur_is_word #define condition frame->Xcondition #define prev_is_word frame->Xprev_is_word #define original_ims frame->Xoriginal_ims #ifdef SUPPORT_UCP #define prop_type frame->Xprop_type #define prop_value frame->Xprop_value #define prop_fail_result frame->Xprop_fail_result #define prop_category frame->Xprop_category #define prop_chartype frame->Xprop_chartype #define prop_script frame->Xprop_script #define oclength frame->Xoclength #define occhars frame->Xocchars #endif #define ctype frame->Xctype #define fc frame->Xfc #define fi frame->Xfi #define length frame->Xlength #define max frame->Xmax #define min frame->Xmin #define number frame->Xnumber #define offset frame->Xoffset #define op frame->Xop #define save_capture_last frame->Xsave_capture_last #define save_offset1 frame->Xsave_offset1 #define save_offset2 frame->Xsave_offset2 #define save_offset3 frame->Xsave_offset3 #define stacksave frame->Xstacksave #define newptrb frame->Xnewptrb /* When recursion is being used, local variables are allocated on the stack and get preserved during recursion in the normal way. In this environment, fi and i, and fc and c, can be the same variables. */ #else /* NO_RECURSE not defined */ #define fi i #define fc c #ifdef SUPPORT_UTF8 /* Many of these variables are used only */ const uschar *charptr; /* in small blocks of the code. My normal */ #endif /* style of coding would have declared */ const uschar *callpat; /* them within each of those blocks. */ const uschar *data; /* However, in order to accommodate the */ const uschar *next; /* version of this code that uses an */ USPTR pp; /* external "stack" implemented on the */ const uschar *prev; /* heap, it is easier to declare them all */ USPTR saved_eptr; /* here, so the declarations can be cut */ /* out in a block. The only declarations */ recursion_info new_recursive; /* within blocks below are for variables */ /* that do not have to be preserved over */ BOOL cur_is_word; /* a recursive call to RMATCH(). */ BOOL condition; BOOL prev_is_word; unsigned long int original_ims; #ifdef SUPPORT_UCP int prop_type; int prop_value; int prop_fail_result; int prop_category; int prop_chartype; int prop_script; int oclength; uschar occhars[8]; #endif int ctype; int length; int max; int min; int number; int offset; int op; int save_capture_last; int save_offset1, save_offset2, save_offset3; int stacksave[REC_STACK_SAVE_MAX]; eptrblock newptrb; #endif /* NO_RECURSE */ /* These statements are here to stop the compiler complaining about unitialized variables. */ #ifdef SUPPORT_UCP prop_value = 0; prop_fail_result = 0; #endif /* This label is used for tail recursion, which is used in a few cases even when NO_RECURSE is not defined, in order to reduce the amount of stack that is used. Thanks to Ian Taylor for noticing this possibility and sending the original patch. */ TAIL_RECURSE: /* OK, now we can get on with the real code of the function. Recursive calls are specified by the macro RMATCH and RRETURN is used to return. When NO_RECURSE is *not* defined, these just turn into a recursive call to match() and a "return", respectively (possibly with some debugging if DEBUG is defined). However, RMATCH isn't like a function call because it's quite a complicated macro. It has to be used in one particular way. This shouldn't, however, impact performance when true recursion is being used. */ #ifdef SUPPORT_UTF8 utf8 = md->utf8; /* Local copy of the flag */ #else utf8 = FALSE; #endif /* First check that we haven't called match() too many times, or that we haven't exceeded the recursive call limit. */ if (md->match_call_count++ >= md->match_limit) RRETURN(PCRE_ERROR_MATCHLIMIT); if (rdepth >= md->match_limit_recursion) RRETURN(PCRE_ERROR_RECURSIONLIMIT); original_ims = ims; /* Save for resetting on ')' */ /* At the start of a group with an unlimited repeat that may match an empty string, the match_cbegroup flag is set. When this is the case, add the current subject pointer to the chain of such remembered pointers, to be checked when we hit the closing ket, in order to break infinite loops that match no characters. When match() is called in other circumstances, don't add to the chain. The match_cbegroup flag must NOT be used with tail recursion, because the memory block that is used is on the stack, so a new one may be required for each match(). */ if ((flags & match_cbegroup) != 0) { newptrb.epb_saved_eptr = eptr; newptrb.epb_prev = eptrb; eptrb = &newptrb; } /* Now start processing the opcodes. */ for (;;) { minimize = possessive = FALSE; op = *ecode; /* For partial matching, remember if we ever hit the end of the subject after matching at least one subject character. */ if (md->partial && eptr >= md->end_subject && eptr > mstart) md->hitend = TRUE; switch(op) { case OP_FAIL: RRETURN(MATCH_NOMATCH); case OP_PRUNE: RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims, eptrb, flags, RM51); if (rrc != MATCH_NOMATCH) RRETURN(rrc); RRETURN(MATCH_PRUNE); case OP_COMMIT: RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims, eptrb, flags, RM52); if (rrc != MATCH_NOMATCH) RRETURN(rrc); RRETURN(MATCH_COMMIT); case OP_SKIP: RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims, eptrb, flags, RM53); if (rrc != MATCH_NOMATCH) RRETURN(rrc); md->start_match_ptr = eptr; /* Pass back current position */ RRETURN(MATCH_SKIP); case OP_THEN: RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims, eptrb, flags, RM54); if (rrc != MATCH_NOMATCH) RRETURN(rrc); RRETURN(MATCH_THEN); /* Handle a capturing bracket. If there is space in the offset vector, save the current subject position in the working slot at the top of the vector. We mustn't change the current values of the data slot, because they may be set from a previous iteration of this group, and be referred to by a reference inside the group. If the bracket fails to match, we need to restore this value and also the values of the final offsets, in case they were set by a previous iteration of the same bracket. If there isn't enough space in the offset vector, treat this as if it were a non-capturing bracket. Don't worry about setting the flag for the error case here; that is handled in the code for KET. */ case OP_CBRA: case OP_SCBRA: number = GET2(ecode, 1+LINK_SIZE); offset = number << 1; #ifdef DEBUG printf("start bracket %d\n", number); printf("subject="); pchars(eptr, 16, TRUE, md); printf("\n"); #endif if (offset < md->offset_max) { save_offset1 = md->offset_vector[offset]; save_offset2 = md->offset_vector[offset+1]; save_offset3 = md->offset_vector[md->offset_end - number]; save_capture_last = md->capture_last; DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3)); md->offset_vector[md->offset_end - number] = eptr - md->start_subject; flags = (op == OP_SCBRA)? match_cbegroup : 0; do { RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims, eptrb, flags, RM1); if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc); md->capture_last = save_capture_last; ecode += GET(ecode, 1); } while (*ecode == OP_ALT); DPRINTF(("bracket %d failed\n", number)); md->offset_vector[offset] = save_offset1; md->offset_vector[offset+1] = save_offset2; md->offset_vector[md->offset_end - number] = save_offset3; RRETURN(MATCH_NOMATCH); } /* FALL THROUGH ... Insufficient room for saving captured contents. Treat as a non-capturing bracket. */ /* VVVVVVVVVVVVVVVVVVVVVVVVV */ /* VVVVVVVVVVVVVVVVVVVVVVVVV */ DPRINTF(("insufficient capture room: treat as non-capturing\n")); /* VVVVVVVVVVVVVVVVVVVVVVVVV */ /* VVVVVVVVVVVVVVVVVVVVVVVVV */ /* Non-capturing bracket. Loop for all the alternatives. When we get to the final alternative within the brackets, we would return the result of a recursive call to match() whatever happened. We can reduce stack usage by turning this into a tail recursion, except in the case when match_cbegroup is set.*/ case OP_BRA: case OP_SBRA: DPRINTF(("start non-capturing bracket\n")); flags = (op >= OP_SBRA)? match_cbegroup : 0; for (;;) { if (ecode[GET(ecode, 1)] != OP_ALT) /* Final alternative */ { if (flags == 0) /* Not a possibly empty group */ { ecode += _pcre_OP_lengths[*ecode]; DPRINTF(("bracket 0 tail recursion\n")); goto TAIL_RECURSE; } /* Possibly empty group; can't use tail recursion. */ RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims, eptrb, flags, RM48); RRETURN(rrc); } /* For non-final alternatives, continue the loop for a NOMATCH result; otherwise return. */ RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims, eptrb, flags, RM2); if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc); ecode += GET(ecode, 1); } /* Control never reaches here. */ /* Conditional group: compilation checked that there are no more than two branches. If the condition is false, skipping the first branch takes us past the end if there is only one branch, but that's OK because that is exactly what going to the ket would do. As there is only one branch to be obeyed, we can use tail recursion to avoid using another stack frame. */ case OP_COND: case OP_SCOND: if (ecode[LINK_SIZE+1] == OP_RREF) /* Recursion test */ { offset = GET2(ecode, LINK_SIZE + 2); /* Recursion group number*/ condition = md->recursive != NULL && (offset == RREF_ANY || offset == md->recursive->group_num); ecode += condition? 3 : GET(ecode, 1); } else if (ecode[LINK_SIZE+1] == OP_CREF) /* Group used test */ { offset = GET2(ecode, LINK_SIZE+2) << 1; /* Doubled ref number */ condition = offset < offset_top && md->offset_vector[offset] >= 0; ecode += condition? 3 : GET(ecode, 1); } else if (ecode[LINK_SIZE+1] == OP_DEF) /* DEFINE - always false */ { condition = FALSE; ecode += GET(ecode, 1); } /* The condition is an assertion. Call match() to evaluate it - setting the final argument match_condassert causes it to stop at the end of an assertion. */ else { RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, match_condassert, RM3); if (rrc == MATCH_MATCH) { condition = TRUE; ecode += 1 + LINK_SIZE + GET(ecode, LINK_SIZE + 2); while (*ecode == OP_ALT) ecode += GET(ecode, 1); } else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) { RRETURN(rrc); /* Need braces because of following else */ } else { condition = FALSE; ecode += GET(ecode, 1); } } /* We are now at the branch that is to be obeyed. As there is only one, we can use tail recursion to avoid using another stack frame, except when match_cbegroup is required for an unlimited repeat of a possibly empty group. If the second alternative doesn't exist, we can just plough on. */ if (condition || *ecode == OP_ALT) { ecode += 1 + LINK_SIZE; if (op == OP_SCOND) /* Possibly empty group */ { RMATCH(eptr, ecode, offset_top, md, ims, eptrb, match_cbegroup, RM49); RRETURN(rrc); } else /* Group must match something */ { flags = 0; goto TAIL_RECURSE; } } else /* Condition false & no 2nd alternative */ { ecode += 1 + LINK_SIZE; } break; /* End of the pattern, either real or forced. If we are in a top-level recursion, we should restore the offsets appropriately and continue from after the call. */ case OP_ACCEPT: case OP_END: if (md->recursive != NULL && md->recursive->group_num == 0) { recursion_info *rec = md->recursive; DPRINTF(("End of pattern in a (?0) recursion\n")); md->recursive = rec->prevrec; memmove(md->offset_vector, rec->offset_save, rec->saved_max * sizeof(int)); mstart = rec->save_start; ims = original_ims; ecode = rec->after_call; break; } /* Otherwise, if PCRE_NOTEMPTY is set, fail if we have matched an empty string - backtracking will then try other alternatives, if any. */ if (md->notempty && eptr == mstart) RRETURN(MATCH_NOMATCH); md->end_match_ptr = eptr; /* Record where we ended */ md->end_offset_top = offset_top; /* and how many extracts were taken */ md->start_match_ptr = mstart; /* and the start (\K can modify) */ RRETURN(MATCH_MATCH); /* Change option settings */ case OP_OPT: ims = ecode[1]; ecode += 2; DPRINTF(("ims set to %02lx\n", ims)); break; /* Assertion brackets. Check the alternative branches in turn - the matching won't pass the KET for an assertion. If any one branch matches, the assertion is true. Lookbehind assertions have an OP_REVERSE item at the start of each branch to move the current point backwards, so the code at this level is identical to the lookahead case. */ case OP_ASSERT: case OP_ASSERTBACK: do { RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0, RM4); if (rrc == MATCH_MATCH) break; if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc); ecode += GET(ecode, 1); } while (*ecode == OP_ALT); if (*ecode == OP_KET) RRETURN(MATCH_NOMATCH); /* If checking an assertion for a condition, return MATCH_MATCH. */ if ((flags & match_condassert) != 0) RRETURN(MATCH_MATCH); /* Continue from after the assertion, updating the offsets high water mark, since extracts may have been taken during the assertion. */ do ecode += GET(ecode,1); while (*ecode == OP_ALT); ecode += 1 + LINK_SIZE; offset_top = md->end_offset_top; continue; /* Negative assertion: all branches must fail to match */ case OP_ASSERT_NOT: case OP_ASSERTBACK_NOT: do { RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0, RM5); if (rrc == MATCH_MATCH) RRETURN(MATCH_NOMATCH); if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc); ecode += GET(ecode,1); } while (*ecode == OP_ALT); if ((flags & match_condassert) != 0) RRETURN(MATCH_MATCH); ecode += 1 + LINK_SIZE; continue; /* Move the subject pointer back. This occurs only at the start of each branch of a lookbehind assertion. If we are too close to the start to move back, this match function fails. When working with UTF-8 we move back a number of characters, not bytes. */ case OP_REVERSE: #ifdef SUPPORT_UTF8 if (utf8) { i = GET(ecode, 1); while (i-- > 0) { eptr--; if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH); BACKCHAR(eptr); } } else #endif /* No UTF-8 support, or not in UTF-8 mode: count is byte count */ { eptr -= GET(ecode, 1); if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH); } /* Skip to next op code */ ecode += 1 + LINK_SIZE; break; /* The callout item calls an external function, if one is provided, passing details of the match so far. This is mainly for debugging, though the function is able to force a failure. */ case OP_CALLOUT: if (pcre_callout != NULL) { pcre_callout_block cb; cb.version = 1; /* Version 1 of the callout block */ cb.callout_number = ecode[1]; cb.offset_vector = md->offset_vector; cb.subject = (PCRE_SPTR)md->start_subject; cb.subject_length = md->end_subject - md->start_subject; cb.start_match = mstart - md->start_subject; cb.current_position = eptr - md->start_subject; cb.pattern_position = GET(ecode, 2); cb.next_item_length = GET(ecode, 2 + LINK_SIZE); cb.capture_top = offset_top/2; cb.capture_last = md->capture_last; cb.callout_data = md->callout_data; if ((rrc = (*pcre_callout)(&cb)) > 0) RRETURN(MATCH_NOMATCH); if (rrc < 0) RRETURN(rrc); } ecode += 2 + 2*LINK_SIZE; break; /* Recursion either matches the current regex, or some subexpression. The offset data is the offset to the starting bracket from the start of the whole pattern. (This is so that it works from duplicated subpatterns.) If there are any capturing brackets started but not finished, we have to save their starting points and reinstate them after the recursion. However, we don't know how many such there are (offset_top records the completed total) so we just have to save all the potential data. There may be up to 65535 such values, which is too large to put on the stack, but using malloc for small numbers seems expensive. As a compromise, the stack is used when there are no more than REC_STACK_SAVE_MAX values to store; otherwise malloc is used. A problem is what to do if the malloc fails ... there is no way of returning to the top level with an error. Save the top REC_STACK_SAVE_MAX values on the stack, and accept that the rest may be wrong. There are also other values that have to be saved. We use a chained sequence of blocks that actually live on the stack. Thanks to Robin Houston for the original version of this logic. */ case OP_RECURSE: { callpat = md->start_code + GET(ecode, 1); new_recursive.group_num = (callpat == md->start_code)? 0 : GET2(callpat, 1 + LINK_SIZE); /* Add to "recursing stack" */ new_recursive.prevrec = md->recursive; md->recursive = &new_recursive; /* Find where to continue from afterwards */ ecode += 1 + LINK_SIZE; new_recursive.after_call = ecode; /* Now save the offset data. */ new_recursive.saved_max = md->offset_end; if (new_recursive.saved_max <= REC_STACK_SAVE_MAX) new_recursive.offset_save = stacksave; else { new_recursive.offset_save = (int *)(pcre_malloc)(new_recursive.saved_max * sizeof(int)); if (new_recursive.offset_save == NULL) RRETURN(PCRE_ERROR_NOMEMORY); } memcpy(new_recursive.offset_save, md->offset_vector, new_recursive.saved_max * sizeof(int)); new_recursive.save_start = mstart; mstart = eptr; /* OK, now we can do the recursion. For each top-level alternative we restore the offset and recursion data. */ DPRINTF(("Recursing into group %d\n", new_recursive.group_num)); flags = (*callpat >= OP_SBRA)? match_cbegroup : 0; do { RMATCH(eptr, callpat + _pcre_OP_lengths[*callpat], offset_top, md, ims, eptrb, flags, RM6); if (rrc == MATCH_MATCH) { DPRINTF(("Recursion matched\n")); md->recursive = new_recursive.prevrec; if (new_recursive.offset_save != stacksave) (pcre_free)(new_recursive.offset_save); RRETURN(MATCH_MATCH); } else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) { DPRINTF(("Recursion gave error %d\n", rrc)); RRETURN(rrc); } md->recursive = &new_recursive; memcpy(md->offset_vector, new_recursive.offset_save, new_recursive.saved_max * sizeof(int)); callpat += GET(callpat, 1); } while (*callpat == OP_ALT); DPRINTF(("Recursion didn't match\n")); md->recursive = new_recursive.prevrec; if (new_recursive.offset_save != stacksave) (pcre_free)(new_recursive.offset_save); RRETURN(MATCH_NOMATCH); } /* Control never reaches here */ /* "Once" brackets are like assertion brackets except that after a match, the point in the subject string is not moved back. Thus there can never be a move back into the brackets. Friedl calls these "atomic" subpatterns. Check the alternative branches in turn - the matching won't pass the KET for this kind of subpattern. If any one branch matches, we carry on as at the end of a normal bracket, leaving the subject pointer. */ case OP_ONCE: prev = ecode; saved_eptr = eptr; do { RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0, RM7); if (rrc == MATCH_MATCH) break; if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc); ecode += GET(ecode,1); } while (*ecode == OP_ALT); /* If hit the end of the group (which could be repeated), fail */ if (*ecode != OP_ONCE && *ecode != OP_ALT) RRETURN(MATCH_NOMATCH); /* Continue as from after the assertion, updating the offsets high water mark, since extracts may have been taken. */ do ecode += GET(ecode, 1); while (*ecode == OP_ALT); offset_top = md->end_offset_top; eptr = md->end_match_ptr; /* For a non-repeating ket, just continue at this level. This also happens for a repeating ket if no characters were matched in the group. This is the forcible breaking of infinite loops as implemented in Perl 5.005. If there is an options reset, it will get obeyed in the normal course of events. */ if (*ecode == OP_KET || eptr == saved_eptr) { ecode += 1+LINK_SIZE; break; } /* The repeating kets try the rest of the pattern or restart from the preceding bracket, in the appropriate order. The second "call" of match() uses tail recursion, to avoid using another stack frame. We need to reset any options that changed within the bracket before re-running it, so check the next opcode. */ if (ecode[1+LINK_SIZE] == OP_OPT) { ims = (ims & ~PCRE_IMS) | ecode[4]; DPRINTF(("ims set to %02lx at group repeat\n", ims)); } if (*ecode == OP_KETRMIN) { RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0, RM8); if (rrc != MATCH_NOMATCH) RRETURN(rrc); ecode = prev; flags = 0; goto TAIL_RECURSE; } else /* OP_KETRMAX */ { RMATCH(eptr, prev, offset_top, md, ims, eptrb, match_cbegroup, RM9); if (rrc != MATCH_NOMATCH) RRETURN(rrc); ecode += 1 + LINK_SIZE; flags = 0; goto TAIL_RECURSE; } /* Control never gets here */ /* An alternation is the end of a branch; scan along to find the end of the bracketed group and go to there. */ case OP_ALT: do ecode += GET(ecode,1); while (*ecode == OP_ALT); break; /* BRAZERO and BRAMINZERO occur just before a bracket group, indicating that it may occur zero times. It may repeat infinitely, or not at all - i.e. it could be ()* or ()? in the pattern. Brackets with fixed upper repeat limits are compiled as a number of copies, with the optional ones preceded by BRAZERO or BRAMINZERO. */ case OP_BRAZERO: { next = ecode+1; RMATCH(eptr, next, offset_top, md, ims, eptrb, 0, RM10); if (rrc != MATCH_NOMATCH) RRETURN(rrc); do next += GET(next,1); while (*next == OP_ALT); ecode = next + 1 + LINK_SIZE; } break; case OP_BRAMINZERO: { next = ecode+1; do next += GET(next, 1); while (*next == OP_ALT); RMATCH(eptr, next + 1+LINK_SIZE, offset_top, md, ims, eptrb, 0, RM11); if (rrc != MATCH_NOMATCH) RRETURN(rrc); ecode++; } break; /* End of a group, repeated or non-repeating. */ case OP_KET: case OP_KETRMIN: case OP_KETRMAX: prev = ecode - GET(ecode, 1); /* If this was a group that remembered the subject start, in order to break infinite repeats of empty string matches, retrieve the subject start from the chain. Otherwise, set it NULL. */ if (*prev >= OP_SBRA) { saved_eptr = eptrb->epb_saved_eptr; /* Value at start of group */ eptrb = eptrb->epb_prev; /* Backup to previous group */ } else saved_eptr = NULL; /* If we are at the end of an assertion group, stop matching and return MATCH_MATCH, but record the current high water mark for use by positive assertions. Do this also for the "once" (atomic) groups. */ if (*prev == OP_ASSERT || *prev == OP_ASSERT_NOT || *prev == OP_ASSERTBACK || *prev == OP_ASSERTBACK_NOT || *prev == OP_ONCE) { md->end_match_ptr = eptr; /* For ONCE */ md->end_offset_top = offset_top; RRETURN(MATCH_MATCH); } /* For capturing groups we have to check the group number back at the start and if necessary complete handling an extraction by setting the offsets and bumping the high water mark. Note that whole-pattern recursion is coded as a recurse into group 0, so it won't be picked up here. Instead, we catch it when the OP_END is reached. Other recursion is handled here. */ if (*prev == OP_CBRA || *prev == OP_SCBRA) { number = GET2(prev, 1+LINK_SIZE); offset = number << 1; #ifdef DEBUG printf("end bracket %d", number); printf("\n"); #endif md->capture_last = number; if (offset >= md->offset_max) md->offset_overflow = TRUE; else { md->offset_vector[offset] = md->offset_vector[md->offset_end - number]; md->offset_vector[offset+1] = eptr - md->start_subject; if (offset_top <= offset) offset_top = offset + 2; } /* Handle a recursively called group. Restore the offsets appropriately and continue from after the call. */ if (md->recursive != NULL && md->recursive->group_num == number) { recursion_info *rec = md->recursive; DPRINTF(("Recursion (%d) succeeded - continuing\n", number)); md->recursive = rec->prevrec; mstart = rec->save_start; memcpy(md->offset_vector, rec->offset_save, rec->saved_max * sizeof(int)); ecode = rec->after_call; ims = original_ims; break; } } /* For both capturing and non-capturing groups, reset the value of the ims flags, in case they got changed during the group. */ ims = original_ims; DPRINTF(("ims reset to %02lx\n", ims)); /* For a non-repeating ket, just continue at this level. This also happens for a repeating ket if no characters were matched in the group. This is the forcible breaking of infinite loops as implemented in Perl 5.005. If there is an options reset, it will get obeyed in the normal course of events. */ if (*ecode == OP_KET || eptr == saved_eptr) { ecode += 1 + LINK_SIZE; break; } /* The repeating kets try the rest of the pattern or restart from the preceding bracket, in the appropriate order. In the second case, we can use tail recursion to avoid using another stack frame, unless we have an unlimited repeat of a group that can match an empty string. */ flags = (*prev >= OP_SBRA)? match_cbegroup : 0; if (*ecode == OP_KETRMIN) { RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0, RM12); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (flags != 0) /* Could match an empty string */ { RMATCH(eptr, prev, offset_top, md, ims, eptrb, flags, RM50); RRETURN(rrc); } ecode = prev; goto TAIL_RECURSE; } else /* OP_KETRMAX */ { RMATCH(eptr, prev, offset_top, md, ims, eptrb, flags, RM13); if (rrc != MATCH_NOMATCH) RRETURN(rrc); ecode += 1 + LINK_SIZE; flags = 0; goto TAIL_RECURSE; } /* Control never gets here */ /* Start of subject unless notbol, or after internal newline if multiline */ case OP_CIRC: if (md->notbol && eptr == md->start_subject) RRETURN(MATCH_NOMATCH); if ((ims & PCRE_MULTILINE) != 0) { if (eptr != md->start_subject && (eptr == md->end_subject || !WAS_NEWLINE(eptr))) RRETURN(MATCH_NOMATCH); ecode++; break; } /* ... else fall through */ /* Start of subject assertion */ case OP_SOD: if (eptr != md->start_subject) RRETURN(MATCH_NOMATCH); ecode++; break; /* Start of match assertion */ case OP_SOM: if (eptr != md->start_subject + md->start_offset) RRETURN(MATCH_NOMATCH); ecode++; break; /* Reset the start of match point */ case OP_SET_SOM: mstart = eptr; ecode++; break; /* Assert before internal newline if multiline, or before a terminating newline unless endonly is set, else end of subject unless noteol is set. */ case OP_DOLL: if ((ims & PCRE_MULTILINE) != 0) { if (eptr < md->end_subject) { if (!IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); } else { if (md->noteol) RRETURN(MATCH_NOMATCH); } ecode++; break; } else { if (md->noteol) RRETURN(MATCH_NOMATCH); if (!md->endonly) { if (eptr != md->end_subject && (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen)) RRETURN(MATCH_NOMATCH); ecode++; break; } } /* ... else fall through for endonly */ /* End of subject assertion (\z) */ case OP_EOD: if (eptr < md->end_subject) RRETURN(MATCH_NOMATCH); ecode++; break; /* End of subject or ending \n assertion (\Z) */ case OP_EODN: if (eptr != md->end_subject && (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen)) RRETURN(MATCH_NOMATCH); ecode++; break; /* Word boundary assertions */ case OP_NOT_WORD_BOUNDARY: case OP_WORD_BOUNDARY: { /* Find out if the previous and current characters are "word" characters. It takes a bit more work in UTF-8 mode. Characters > 255 are assumed to be "non-word" characters. */ #ifdef SUPPORT_UTF8 if (utf8) { if (eptr == md->start_subject) prev_is_word = FALSE; else { const uschar *lastptr = eptr - 1; while((*lastptr & 0xc0) == 0x80) lastptr--; GETCHAR(c, lastptr); prev_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0; } if (eptr >= md->end_subject) cur_is_word = FALSE; else { GETCHAR(c, eptr); cur_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0; } } else #endif /* More streamlined when not in UTF-8 mode */ { prev_is_word = (eptr != md->start_subject) && ((md->ctypes[eptr[-1]] & ctype_word) != 0); cur_is_word = (eptr < md->end_subject) && ((md->ctypes[*eptr] & ctype_word) != 0); } /* Now see if the situation is what we want */ if ((*ecode++ == OP_WORD_BOUNDARY)? cur_is_word == prev_is_word : cur_is_word != prev_is_word) RRETURN(MATCH_NOMATCH); } break; /* Match a single character type; inline for speed */ case OP_ANY: if ((ims & PCRE_DOTALL) == 0) { if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); } if (eptr++ >= md->end_subject) RRETURN(MATCH_NOMATCH); if (utf8) while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++; ecode++; break; /* Match a single byte, even in UTF-8 mode. This opcode really does match any byte, even newline, independent of the setting of PCRE_DOTALL. */ case OP_ANYBYTE: if (eptr++ >= md->end_subject) RRETURN(MATCH_NOMATCH); ecode++; break; case OP_NOT_DIGIT: if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINCTEST(c, eptr); if ( #ifdef SUPPORT_UTF8 c < 256 && #endif (md->ctypes[c] & ctype_digit) != 0 ) RRETURN(MATCH_NOMATCH); ecode++; break; case OP_DIGIT: if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINCTEST(c, eptr); if ( #ifdef SUPPORT_UTF8 c >= 256 || #endif (md->ctypes[c] & ctype_digit) == 0 ) RRETURN(MATCH_NOMATCH); ecode++; break; case OP_NOT_WHITESPACE: if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINCTEST(c, eptr); if ( #ifdef SUPPORT_UTF8 c < 256 && #endif (md->ctypes[c] & ctype_space) != 0 ) RRETURN(MATCH_NOMATCH); ecode++; break; case OP_WHITESPACE: if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINCTEST(c, eptr); if ( #ifdef SUPPORT_UTF8 c >= 256 || #endif (md->ctypes[c] & ctype_space) == 0 ) RRETURN(MATCH_NOMATCH); ecode++; break; case OP_NOT_WORDCHAR: if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINCTEST(c, eptr); if ( #ifdef SUPPORT_UTF8 c < 256 && #endif (md->ctypes[c] & ctype_word) != 0 ) RRETURN(MATCH_NOMATCH); ecode++; break; case OP_WORDCHAR: if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINCTEST(c, eptr); if ( #ifdef SUPPORT_UTF8 c >= 256 || #endif (md->ctypes[c] & ctype_word) == 0 ) RRETURN(MATCH_NOMATCH); ecode++; break; case OP_ANYNL: if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINCTEST(c, eptr); switch(c) { default: RRETURN(MATCH_NOMATCH); case 0x000d: if (eptr < md->end_subject && *eptr == 0x0a) eptr++; break; case 0x000a: case 0x000b: case 0x000c: case 0x0085: case 0x2028: case 0x2029: break; } ecode++; break; case OP_NOT_HSPACE: if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINCTEST(c, eptr); switch(c) { default: break; case 0x09: /* HT */ case 0x20: /* SPACE */ case 0xa0: /* NBSP */ case 0x1680: /* OGHAM SPACE MARK */ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ case 0x2000: /* EN QUAD */ case 0x2001: /* EM QUAD */ case 0x2002: /* EN SPACE */ case 0x2003: /* EM SPACE */ case 0x2004: /* THREE-PER-EM SPACE */ case 0x2005: /* FOUR-PER-EM SPACE */ case 0x2006: /* SIX-PER-EM SPACE */ case 0x2007: /* FIGURE SPACE */ case 0x2008: /* PUNCTUATION SPACE */ case 0x2009: /* THIN SPACE */ case 0x200A: /* HAIR SPACE */ case 0x202f: /* NARROW NO-BREAK SPACE */ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ case 0x3000: /* IDEOGRAPHIC SPACE */ RRETURN(MATCH_NOMATCH); } ecode++; break; case OP_HSPACE: if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINCTEST(c, eptr); switch(c) { default: RRETURN(MATCH_NOMATCH); case 0x09: /* HT */ case 0x20: /* SPACE */ case 0xa0: /* NBSP */ case 0x1680: /* OGHAM SPACE MARK */ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ case 0x2000: /* EN QUAD */ case 0x2001: /* EM QUAD */ case 0x2002: /* EN SPACE */ case 0x2003: /* EM SPACE */ case 0x2004: /* THREE-PER-EM SPACE */ case 0x2005: /* FOUR-PER-EM SPACE */ case 0x2006: /* SIX-PER-EM SPACE */ case 0x2007: /* FIGURE SPACE */ case 0x2008: /* PUNCTUATION SPACE */ case 0x2009: /* THIN SPACE */ case 0x200A: /* HAIR SPACE */ case 0x202f: /* NARROW NO-BREAK SPACE */ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ case 0x3000: /* IDEOGRAPHIC SPACE */ break; } ecode++; break; case OP_NOT_VSPACE: if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINCTEST(c, eptr); switch(c) { default: break; case 0x0a: /* LF */ case 0x0b: /* VT */ case 0x0c: /* FF */ case 0x0d: /* CR */ case 0x85: /* NEL */ case 0x2028: /* LINE SEPARATOR */ case 0x2029: /* PARAGRAPH SEPARATOR */ RRETURN(MATCH_NOMATCH); } ecode++; break; case OP_VSPACE: if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINCTEST(c, eptr); switch(c) { default: RRETURN(MATCH_NOMATCH); case 0x0a: /* LF */ case 0x0b: /* VT */ case 0x0c: /* FF */ case 0x0d: /* CR */ case 0x85: /* NEL */ case 0x2028: /* LINE SEPARATOR */ case 0x2029: /* PARAGRAPH SEPARATOR */ break; } ecode++; break; #ifdef SUPPORT_UCP /* Check the next character by Unicode property. We will get here only if the support is in the binary; otherwise a compile-time error occurs. */ case OP_PROP: case OP_NOTPROP: if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINCTEST(c, eptr); { int chartype, script; int category = _pcre_ucp_findprop(c, &chartype, &script); switch(ecode[1]) { case PT_ANY: if (op == OP_NOTPROP) RRETURN(MATCH_NOMATCH); break; case PT_LAMP: if ((chartype == ucp_Lu || chartype == ucp_Ll || chartype == ucp_Lt) == (op == OP_NOTPROP)) RRETURN(MATCH_NOMATCH); break; case PT_GC: if ((ecode[2] != category) == (op == OP_PROP)) RRETURN(MATCH_NOMATCH); break; case PT_PC: if ((ecode[2] != chartype) == (op == OP_PROP)) RRETURN(MATCH_NOMATCH); break; case PT_SC: if ((ecode[2] != script) == (op == OP_PROP)) RRETURN(MATCH_NOMATCH); break; default: RRETURN(PCRE_ERROR_INTERNAL); } ecode += 3; } break; /* Match an extended Unicode sequence. We will get here only if the support is in the binary; otherwise a compile-time error occurs. */ case OP_EXTUNI: if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINCTEST(c, eptr); { int chartype, script; int category = _pcre_ucp_findprop(c, &chartype, &script); if (category == ucp_M) RRETURN(MATCH_NOMATCH); while (eptr < md->end_subject) { int len = 1; if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); } category = _pcre_ucp_findprop(c, &chartype, &script); if (category != ucp_M) break; eptr += len; } } ecode++; break; #endif /* Match a back reference, possibly repeatedly. Look past the end of the item to see if there is repeat information following. The code is similar to that for character classes, but repeated for efficiency. Then obey similar code to character type repeats - written out again for speed. However, if the referenced string is the empty string, always treat it as matched, any number of times (otherwise there could be infinite loops). */ case OP_REF: { offset = GET2(ecode, 1) << 1; /* Doubled ref number */ ecode += 3; /* Advance past item */ /* If the reference is unset, set the length to be longer than the amount of subject left; this ensures that every attempt at a match fails. We can't just fail here, because of the possibility of quantifiers with zero minima. */ length = (offset >= offset_top || md->offset_vector[offset] < 0)? md->end_subject - eptr + 1 : md->offset_vector[offset+1] - md->offset_vector[offset]; /* Set up for repetition, or handle the non-repeated case */ switch (*ecode) { case OP_CRSTAR: case OP_CRMINSTAR: case OP_CRPLUS: case OP_CRMINPLUS: case OP_CRQUERY: case OP_CRMINQUERY: c = *ecode++ - OP_CRSTAR; minimize = (c & 1) != 0; min = rep_min[c]; /* Pick up values from tables; */ max = rep_max[c]; /* zero for max => infinity */ if (max == 0) max = INT_MAX; break; case OP_CRRANGE: case OP_CRMINRANGE: minimize = (*ecode == OP_CRMINRANGE); min = GET2(ecode, 1); max = GET2(ecode, 3); if (max == 0) max = INT_MAX; ecode += 5; break; default: /* No repeat follows */ if (!match_ref(offset, eptr, length, md, ims)) RRETURN(MATCH_NOMATCH); eptr += length; continue; /* With the main loop */ } /* If the length of the reference is zero, just continue with the main loop. */ if (length == 0) continue; /* First, ensure the minimum number of matches are present. We get back the length of the reference string explicitly rather than passing the address of eptr, so that eptr can be a register variable. */ for (i = 1; i <= min; i++) { if (!match_ref(offset, eptr, length, md, ims)) RRETURN(MATCH_NOMATCH); eptr += length; } /* If min = max, continue at the same level without recursion. They are not both allowed to be zero. */ if (min == max) continue; /* If minimizing, keep trying and advancing the pointer */ if (minimize) { for (fi = min;; fi++) { RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM14); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max || !match_ref(offset, eptr, length, md, ims)) RRETURN(MATCH_NOMATCH); eptr += length; } /* Control never gets here */ } /* If maximizing, find the longest string and work backwards */ else { pp = eptr; for (i = min; i < max; i++) { if (!match_ref(offset, eptr, length, md, ims)) break; eptr += length; } while (eptr >= pp) { RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM15); if (rrc != MATCH_NOMATCH) RRETURN(rrc); eptr -= length; } RRETURN(MATCH_NOMATCH); } } /* Control never gets here */ /* Match a bit-mapped character class, possibly repeatedly. This op code is used when all the characters in the class have values in the range 0-255, and either the matching is caseful, or the characters are in the range 0-127 when UTF-8 processing is enabled. The only difference between OP_CLASS and OP_NCLASS occurs when a data character outside the range is encountered. First, look past the end of the item to see if there is repeat information following. Then obey similar code to character type repeats - written out again for speed. */ case OP_NCLASS: case OP_CLASS: { data = ecode + 1; /* Save for matching */ ecode += 33; /* Advance past the item */ switch (*ecode) { case OP_CRSTAR: case OP_CRMINSTAR: case OP_CRPLUS: case OP_CRMINPLUS: case OP_CRQUERY: case OP_CRMINQUERY: c = *ecode++ - OP_CRSTAR; minimize = (c & 1) != 0; min = rep_min[c]; /* Pick up values from tables; */ max = rep_max[c]; /* zero for max => infinity */ if (max == 0) max = INT_MAX; break; case OP_CRRANGE: case OP_CRMINRANGE: minimize = (*ecode == OP_CRMINRANGE); min = GET2(ecode, 1); max = GET2(ecode, 3); if (max == 0) max = INT_MAX; ecode += 5; break; default: /* No repeat follows */ min = max = 1; break; } /* First, ensure the minimum number of matches are present. */ #ifdef SUPPORT_UTF8 /* UTF-8 mode */ if (utf8) { for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINC(c, eptr); if (c > 255) { if (op == OP_CLASS) RRETURN(MATCH_NOMATCH); } else { if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH); } } } else #endif /* Not UTF-8 mode */ { for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); c = *eptr++; if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH); } } /* If max == min we can continue with the main loop without the need to recurse. */ if (min == max) continue; /* If minimizing, keep testing the rest of the expression and advancing the pointer while it matches the class. */ if (minimize) { #ifdef SUPPORT_UTF8 /* UTF-8 mode */ if (utf8) { for (fi = min;; fi++) { RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM16); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINC(c, eptr); if (c > 255) { if (op == OP_CLASS) RRETURN(MATCH_NOMATCH); } else { if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH); } } } else #endif /* Not UTF-8 mode */ { for (fi = min;; fi++) { RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM17); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); c = *eptr++; if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH); } } /* Control never gets here */ } /* If maximizing, find the longest possible run, then work backwards. */ else { pp = eptr; #ifdef SUPPORT_UTF8 /* UTF-8 mode */ if (utf8) { for (i = min; i < max; i++) { int len = 1; if (eptr >= md->end_subject) break; GETCHARLEN(c, eptr, len); if (c > 255) { if (op == OP_CLASS) break; } else { if ((data[c/8] & (1 << (c&7))) == 0) break; } eptr += len; } for (;;) { RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM18); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (eptr-- == pp) break; /* Stop if tried at original pos */ BACKCHAR(eptr); } } else #endif /* Not UTF-8 mode */ { for (i = min; i < max; i++) { if (eptr >= md->end_subject) break; c = *eptr; if ((data[c/8] & (1 << (c&7))) == 0) break; eptr++; } while (eptr >= pp) { RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM19); if (rrc != MATCH_NOMATCH) RRETURN(rrc); eptr--; } } RRETURN(MATCH_NOMATCH); } } /* Control never gets here */ /* Match an extended character class. This opcode is encountered only in UTF-8 mode, because that's the only time it is compiled. */ #ifdef SUPPORT_UTF8 case OP_XCLASS: { data = ecode + 1 + LINK_SIZE; /* Save for matching */ ecode += GET(ecode, 1); /* Advance past the item */ switch (*ecode) { case OP_CRSTAR: case OP_CRMINSTAR: case OP_CRPLUS: case OP_CRMINPLUS: case OP_CRQUERY: case OP_CRMINQUERY: c = *ecode++ - OP_CRSTAR; minimize = (c & 1) != 0; min = rep_min[c]; /* Pick up values from tables; */ max = rep_max[c]; /* zero for max => infinity */ if (max == 0) max = INT_MAX; break; case OP_CRRANGE: case OP_CRMINRANGE: minimize = (*ecode == OP_CRMINRANGE); min = GET2(ecode, 1); max = GET2(ecode, 3); if (max == 0) max = INT_MAX; ecode += 5; break; default: /* No repeat follows */ min = max = 1; break; } /* First, ensure the minimum number of matches are present. */ for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINC(c, eptr); if (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH); } /* If max == min we can continue with the main loop without the need to recurse. */ if (min == max) continue; /* If minimizing, keep testing the rest of the expression and advancing the pointer while it matches the class. */ if (minimize) { for (fi = min;; fi++) { RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM20); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINC(c, eptr); if (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH); } /* Control never gets here */ } /* If maximizing, find the longest possible run, then work backwards. */ else { pp = eptr; for (i = min; i < max; i++) { int len = 1; if (eptr >= md->end_subject) break; GETCHARLEN(c, eptr, len); if (!_pcre_xclass(c, data)) break; eptr += len; } for(;;) { RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM21); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (eptr-- == pp) break; /* Stop if tried at original pos */ if (utf8) BACKCHAR(eptr); } RRETURN(MATCH_NOMATCH); } /* Control never gets here */ } #endif /* End of XCLASS */ /* Match a single character, casefully */ case OP_CHAR: #ifdef SUPPORT_UTF8 if (utf8) { length = 1; ecode++; GETCHARLEN(fc, ecode, length); if (length > md->end_subject - eptr) RRETURN(MATCH_NOMATCH); while (length-- > 0) if (*ecode++ != *eptr++) RRETURN(MATCH_NOMATCH); } else #endif /* Non-UTF-8 mode */ { if (md->end_subject - eptr < 1) RRETURN(MATCH_NOMATCH); if (ecode[1] != *eptr++) RRETURN(MATCH_NOMATCH); ecode += 2; } break; /* Match a single character, caselessly */ case OP_CHARNC: #ifdef SUPPORT_UTF8 if (utf8) { length = 1; ecode++; GETCHARLEN(fc, ecode, length); if (length > md->end_subject - eptr) RRETURN(MATCH_NOMATCH); /* If the pattern character's value is < 128, we have only one byte, and can use the fast lookup table. */ if (fc < 128) { if (md->lcc[*ecode++] != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH); } /* Otherwise we must pick up the subject character */ else { unsigned int dc; GETCHARINC(dc, eptr); ecode += length; /* If we have Unicode property support, we can use it to test the other case of the character, if there is one. */ if (fc != dc) { #ifdef SUPPORT_UCP if (dc != _pcre_ucp_othercase(fc)) #endif RRETURN(MATCH_NOMATCH); } } } else #endif /* SUPPORT_UTF8 */ /* Non-UTF-8 mode */ { if (md->end_subject - eptr < 1) RRETURN(MATCH_NOMATCH); if (md->lcc[ecode[1]] != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH); ecode += 2; } break; /* Match a single character repeatedly. */ case OP_EXACT: min = max = GET2(ecode, 1); ecode += 3; goto REPEATCHAR; case OP_POSUPTO: possessive = TRUE; /* Fall through */ case OP_UPTO: case OP_MINUPTO: min = 0; max = GET2(ecode, 1); minimize = *ecode == OP_MINUPTO; ecode += 3; goto REPEATCHAR; case OP_POSSTAR: possessive = TRUE; min = 0; max = INT_MAX; ecode++; goto REPEATCHAR; case OP_POSPLUS: possessive = TRUE; min = 1; max = INT_MAX; ecode++; goto REPEATCHAR; case OP_POSQUERY: possessive = TRUE; min = 0; max = 1; ecode++; goto REPEATCHAR; case OP_STAR: case OP_MINSTAR: case OP_PLUS: case OP_MINPLUS: case OP_QUERY: case OP_MINQUERY: c = *ecode++ - OP_STAR; minimize = (c & 1) != 0; min = rep_min[c]; /* Pick up values from tables; */ max = rep_max[c]; /* zero for max => infinity */ if (max == 0) max = INT_MAX; /* Common code for all repeated single-character matches. We can give up quickly if there are fewer than the minimum number of characters left in the subject. */ REPEATCHAR: #ifdef SUPPORT_UTF8 if (utf8) { length = 1; charptr = ecode; GETCHARLEN(fc, ecode, length); if (min * length > md->end_subject - eptr) RRETURN(MATCH_NOMATCH); ecode += length; /* Handle multibyte character matching specially here. There is support for caseless matching if UCP support is present. */ if (length > 1) { #ifdef SUPPORT_UCP unsigned int othercase; if ((ims & PCRE_CASELESS) != 0 && (othercase = _pcre_ucp_othercase(fc)) != NOTACHAR) oclength = _pcre_ord2utf8(othercase, occhars); else oclength = 0; #endif /* SUPPORT_UCP */ for (i = 1; i <= min; i++) { if (memcmp(eptr, charptr, length) == 0) eptr += length; #ifdef SUPPORT_UCP /* Need braces because of following else */ else if (oclength == 0) { RRETURN(MATCH_NOMATCH); } else { if (memcmp(eptr, occhars, oclength) != 0) RRETURN(MATCH_NOMATCH); eptr += oclength; } #else /* without SUPPORT_UCP */ else { RRETURN(MATCH_NOMATCH); } #endif /* SUPPORT_UCP */ } if (min == max) continue; if (minimize) { for (fi = min;; fi++) { RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM22); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); if (memcmp(eptr, charptr, length) == 0) eptr += length; #ifdef SUPPORT_UCP /* Need braces because of following else */ else if (oclength == 0) { RRETURN(MATCH_NOMATCH); } else { if (memcmp(eptr, occhars, oclength) != 0) RRETURN(MATCH_NOMATCH); eptr += oclength; } #else /* without SUPPORT_UCP */ else { RRETURN (MATCH_NOMATCH); } #endif /* SUPPORT_UCP */ } /* Control never gets here */ } else /* Maximize */ { pp = eptr; for (i = min; i < max; i++) { if (eptr > md->end_subject - length) break; if (memcmp(eptr, charptr, length) == 0) eptr += length; #ifdef SUPPORT_UCP else if (oclength == 0) break; else { if (memcmp(eptr, occhars, oclength) != 0) break; eptr += oclength; } #else /* without SUPPORT_UCP */ else break; #endif /* SUPPORT_UCP */ } if (possessive) continue; for(;;) { RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM23); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (eptr == pp) RRETURN(MATCH_NOMATCH); #ifdef SUPPORT_UCP eptr--; BACKCHAR(eptr); #else /* without SUPPORT_UCP */ eptr -= length; #endif /* SUPPORT_UCP */ } } /* Control never gets here */ } /* If the length of a UTF-8 character is 1, we fall through here, and obey the code as for non-UTF-8 characters below, though in this case the value of fc will always be < 128. */ } else #endif /* SUPPORT_UTF8 */ /* When not in UTF-8 mode, load a single-byte character. */ { if (min > md->end_subject - eptr) RRETURN(MATCH_NOMATCH); fc = *ecode++; } /* The value of fc at this point is always less than 256, though we may or may not be in UTF-8 mode. The code is duplicated for the caseless and caseful cases, for speed, since matching characters is likely to be quite common. First, ensure the minimum number of matches are present. If min = max, continue at the same level without recursing. Otherwise, if minimizing, keep trying the rest of the expression and advancing one matching character if failing, up to the maximum. Alternatively, if maximizing, find the maximum number of characters and work backwards. */ DPRINTF(("matching %c{%d,%d} against subject %.*s\n", fc, min, max, max, eptr)); if ((ims & PCRE_CASELESS) != 0) { fc = md->lcc[fc]; for (i = 1; i <= min; i++) if (fc != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH); if (min == max) continue; if (minimize) { for (fi = min;; fi++) { RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM24); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max || eptr >= md->end_subject || fc != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH); } /* Control never gets here */ } else /* Maximize */ { pp = eptr; for (i = min; i < max; i++) { if (eptr >= md->end_subject || fc != md->lcc[*eptr]) break; eptr++; } if (possessive) continue; while (eptr >= pp) { RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM25); eptr--; if (rrc != MATCH_NOMATCH) RRETURN(rrc); } RRETURN(MATCH_NOMATCH); } /* Control never gets here */ } /* Caseful comparisons (includes all multi-byte characters) */ else { for (i = 1; i <= min; i++) if (fc != *eptr++) RRETURN(MATCH_NOMATCH); if (min == max) continue; if (minimize) { for (fi = min;; fi++) { RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM26); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max || eptr >= md->end_subject || fc != *eptr++) RRETURN(MATCH_NOMATCH); } /* Control never gets here */ } else /* Maximize */ { pp = eptr; for (i = min; i < max; i++) { if (eptr >= md->end_subject || fc != *eptr) break; eptr++; } if (possessive) continue; while (eptr >= pp) { RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM27); eptr--; if (rrc != MATCH_NOMATCH) RRETURN(rrc); } RRETURN(MATCH_NOMATCH); } } /* Control never gets here */ /* Match a negated single one-byte character. The character we are checking can be multibyte. */ case OP_NOT: if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); ecode++; GETCHARINCTEST(c, eptr); if ((ims & PCRE_CASELESS) != 0) { #ifdef SUPPORT_UTF8 if (c < 256) #endif c = md->lcc[c]; if (md->lcc[*ecode++] == c) RRETURN(MATCH_NOMATCH); } else { if (*ecode++ == c) RRETURN(MATCH_NOMATCH); } break; /* Match a negated single one-byte character repeatedly. This is almost a repeat of the code for a repeated single character, but I haven't found a nice way of commoning these up that doesn't require a test of the positive/negative option for each character match. Maybe that wouldn't add very much to the time taken, but character matching *is* what this is all about... */ case OP_NOTEXACT: min = max = GET2(ecode, 1); ecode += 3; goto REPEATNOTCHAR; case OP_NOTUPTO: case OP_NOTMINUPTO: min = 0; max = GET2(ecode, 1); minimize = *ecode == OP_NOTMINUPTO; ecode += 3; goto REPEATNOTCHAR; case OP_NOTPOSSTAR: possessive = TRUE; min = 0; max = INT_MAX; ecode++; goto REPEATNOTCHAR; case OP_NOTPOSPLUS: possessive = TRUE; min = 1; max = INT_MAX; ecode++; goto REPEATNOTCHAR; case OP_NOTPOSQUERY: possessive = TRUE; min = 0; max = 1; ecode++; goto REPEATNOTCHAR; case OP_NOTPOSUPTO: possessive = TRUE; min = 0; max = GET2(ecode, 1); ecode += 3; goto REPEATNOTCHAR; case OP_NOTSTAR: case OP_NOTMINSTAR: case OP_NOTPLUS: case OP_NOTMINPLUS: case OP_NOTQUERY: case OP_NOTMINQUERY: c = *ecode++ - OP_NOTSTAR; minimize = (c & 1) != 0; min = rep_min[c]; /* Pick up values from tables; */ max = rep_max[c]; /* zero for max => infinity */ if (max == 0) max = INT_MAX; /* Common code for all repeated single-byte matches. We can give up quickly if there are fewer than the minimum number of bytes left in the subject. */ REPEATNOTCHAR: if (min > md->end_subject - eptr) RRETURN(MATCH_NOMATCH); fc = *ecode++; /* The code is duplicated for the caseless and caseful cases, for speed, since matching characters is likely to be quite common. First, ensure the minimum number of matches are present. If min = max, continue at the same level without recursing. Otherwise, if minimizing, keep trying the rest of the expression and advancing one matching character if failing, up to the maximum. Alternatively, if maximizing, find the maximum number of characters and work backwards. */ DPRINTF(("negative matching %c{%d,%d} against subject %.*s\n", fc, min, max, max, eptr)); if ((ims & PCRE_CASELESS) != 0) { fc = md->lcc[fc]; #ifdef SUPPORT_UTF8 /* UTF-8 mode */ if (utf8) { register unsigned int d; for (i = 1; i <= min; i++) { GETCHARINC(d, eptr); if (d < 256) d = md->lcc[d]; if (fc == d) RRETURN(MATCH_NOMATCH); } } else #endif /* Not UTF-8 mode */ { for (i = 1; i <= min; i++) if (fc == md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH); } if (min == max) continue; if (minimize) { #ifdef SUPPORT_UTF8 /* UTF-8 mode */ if (utf8) { register unsigned int d; for (fi = min;; fi++) { RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM28); if (rrc != MATCH_NOMATCH) RRETURN(rrc); GETCHARINC(d, eptr); if (d < 256) d = md->lcc[d]; if (fi >= max || eptr >= md->end_subject || fc == d) RRETURN(MATCH_NOMATCH); } } else #endif /* Not UTF-8 mode */ { for (fi = min;; fi++) { RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM29); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max || eptr >= md->end_subject || fc == md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH); } } /* Control never gets here */ } /* Maximize case */ else { pp = eptr; #ifdef SUPPORT_UTF8 /* UTF-8 mode */ if (utf8) { register unsigned int d; for (i = min; i < max; i++) { int len = 1; if (eptr >= md->end_subject) break; GETCHARLEN(d, eptr, len); if (d < 256) d = md->lcc[d]; if (fc == d) break; eptr += len; } if (possessive) continue; for(;;) { RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM30); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (eptr-- == pp) break; /* Stop if tried at original pos */ BACKCHAR(eptr); } } else #endif /* Not UTF-8 mode */ { for (i = min; i < max; i++) { if (eptr >= md->end_subject || fc == md->lcc[*eptr]) break; eptr++; } if (possessive) continue; while (eptr >= pp) { RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM31); if (rrc != MATCH_NOMATCH) RRETURN(rrc); eptr--; } } RRETURN(MATCH_NOMATCH); } /* Control never gets here */ } /* Caseful comparisons */ else { #ifdef SUPPORT_UTF8 /* UTF-8 mode */ if (utf8) { register unsigned int d; for (i = 1; i <= min; i++) { GETCHARINC(d, eptr); if (fc == d) RRETURN(MATCH_NOMATCH); } } else #endif /* Not UTF-8 mode */ { for (i = 1; i <= min; i++) if (fc == *eptr++) RRETURN(MATCH_NOMATCH); } if (min == max) continue; if (minimize) { #ifdef SUPPORT_UTF8 /* UTF-8 mode */ if (utf8) { register unsigned int d; for (fi = min;; fi++) { RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM32); if (rrc != MATCH_NOMATCH) RRETURN(rrc); GETCHARINC(d, eptr); if (fi >= max || eptr >= md->end_subject || fc == d) RRETURN(MATCH_NOMATCH); } } else #endif /* Not UTF-8 mode */ { for (fi = min;; fi++) { RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM33); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max || eptr >= md->end_subject || fc == *eptr++) RRETURN(MATCH_NOMATCH); } } /* Control never gets here */ } /* Maximize case */ else { pp = eptr; #ifdef SUPPORT_UTF8 /* UTF-8 mode */ if (utf8) { register unsigned int d; for (i = min; i < max; i++) { int len = 1; if (eptr >= md->end_subject) break; GETCHARLEN(d, eptr, len); if (fc == d) break; eptr += len; } if (possessive) continue; for(;;) { RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM34); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (eptr-- == pp) break; /* Stop if tried at original pos */ BACKCHAR(eptr); } } else #endif /* Not UTF-8 mode */ { for (i = min; i < max; i++) { if (eptr >= md->end_subject || fc == *eptr) break; eptr++; } if (possessive) continue; while (eptr >= pp) { RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM35); if (rrc != MATCH_NOMATCH) RRETURN(rrc); eptr--; } } RRETURN(MATCH_NOMATCH); } } /* Control never gets here */ /* Match a single character type repeatedly; several different opcodes share code. This is very similar to the code for single characters, but we repeat it in the interests of efficiency. */ case OP_TYPEEXACT: min = max = GET2(ecode, 1); minimize = TRUE; ecode += 3; goto REPEATTYPE; case OP_TYPEUPTO: case OP_TYPEMINUPTO: min = 0; max = GET2(ecode, 1); minimize = *ecode == OP_TYPEMINUPTO; ecode += 3; goto REPEATTYPE; case OP_TYPEPOSSTAR: possessive = TRUE; min = 0; max = INT_MAX; ecode++; goto REPEATTYPE; case OP_TYPEPOSPLUS: possessive = TRUE; min = 1; max = INT_MAX; ecode++; goto REPEATTYPE; case OP_TYPEPOSQUERY: possessive = TRUE; min = 0; max = 1; ecode++; goto REPEATTYPE; case OP_TYPEPOSUPTO: possessive = TRUE; min = 0; max = GET2(ecode, 1); ecode += 3; goto REPEATTYPE; case OP_TYPESTAR: case OP_TYPEMINSTAR: case OP_TYPEPLUS: case OP_TYPEMINPLUS: case OP_TYPEQUERY: case OP_TYPEMINQUERY: c = *ecode++ - OP_TYPESTAR; minimize = (c & 1) != 0; min = rep_min[c]; /* Pick up values from tables; */ max = rep_max[c]; /* zero for max => infinity */ if (max == 0) max = INT_MAX; /* Common code for all repeated single character type matches. Note that in UTF-8 mode, '.' matches a character of any length, but for the other character types, the valid characters are all one-byte long. */ REPEATTYPE: ctype = *ecode++; /* Code for the character type */ #ifdef SUPPORT_UCP if (ctype == OP_PROP || ctype == OP_NOTPROP) { prop_fail_result = ctype == OP_NOTPROP; prop_type = *ecode++; prop_value = *ecode++; } else prop_type = -1; #endif /* First, ensure the minimum number of matches are present. Use inline code for maximizing the speed, and do the type test once at the start (i.e. keep it out of the loop). Also we can test that there are at least the minimum number of bytes before we start. This isn't as effective in UTF-8 mode, but it does no harm. Separate the UTF-8 code completely as that is tidier. Also separate the UCP code, which can be the same for both UTF-8 and single-bytes. */ if (min > md->end_subject - eptr) RRETURN(MATCH_NOMATCH); if (min > 0) { #ifdef SUPPORT_UCP if (prop_type >= 0) { switch(prop_type) { case PT_ANY: if (prop_fail_result) RRETURN(MATCH_NOMATCH); for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINCTEST(c, eptr); } break; case PT_LAMP: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINCTEST(c, eptr); prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script); if ((prop_chartype == ucp_Lu || prop_chartype == ucp_Ll || prop_chartype == ucp_Lt) == prop_fail_result) RRETURN(MATCH_NOMATCH); } break; case PT_GC: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINCTEST(c, eptr); prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script); if ((prop_category == prop_value) == prop_fail_result) RRETURN(MATCH_NOMATCH); } break; case PT_PC: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINCTEST(c, eptr); prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script); if ((prop_chartype == prop_value) == prop_fail_result) RRETURN(MATCH_NOMATCH); } break; case PT_SC: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINCTEST(c, eptr); prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script); if ((prop_script == prop_value) == prop_fail_result) RRETURN(MATCH_NOMATCH); } break; default: RRETURN(PCRE_ERROR_INTERNAL); } } /* Match extended Unicode sequences. We will get here only if the support is in the binary; otherwise a compile-time error occurs. */ else if (ctype == OP_EXTUNI) { for (i = 1; i <= min; i++) { GETCHARINCTEST(c, eptr); prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script); if (prop_category == ucp_M) RRETURN(MATCH_NOMATCH); while (eptr < md->end_subject) { int len = 1; if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); } prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script); if (prop_category != ucp_M) break; eptr += len; } } } else #endif /* SUPPORT_UCP */ /* Handle all other cases when the coding is UTF-8 */ #ifdef SUPPORT_UTF8 if (utf8) switch(ctype) { case OP_ANY: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject || ((ims & PCRE_DOTALL) == 0 && IS_NEWLINE(eptr))) RRETURN(MATCH_NOMATCH); eptr++; while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++; } break; case OP_ANYBYTE: eptr += min; break; case OP_ANYNL: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINC(c, eptr); switch(c) { default: RRETURN(MATCH_NOMATCH); case 0x000d: if (eptr < md->end_subject && *eptr == 0x0a) eptr++; break; case 0x000a: case 0x000b: case 0x000c: case 0x0085: case 0x2028: case 0x2029: break; } } break; case OP_NOT_HSPACE: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINC(c, eptr); switch(c) { default: break; case 0x09: /* HT */ case 0x20: /* SPACE */ case 0xa0: /* NBSP */ case 0x1680: /* OGHAM SPACE MARK */ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ case 0x2000: /* EN QUAD */ case 0x2001: /* EM QUAD */ case 0x2002: /* EN SPACE */ case 0x2003: /* EM SPACE */ case 0x2004: /* THREE-PER-EM SPACE */ case 0x2005: /* FOUR-PER-EM SPACE */ case 0x2006: /* SIX-PER-EM SPACE */ case 0x2007: /* FIGURE SPACE */ case 0x2008: /* PUNCTUATION SPACE */ case 0x2009: /* THIN SPACE */ case 0x200A: /* HAIR SPACE */ case 0x202f: /* NARROW NO-BREAK SPACE */ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ case 0x3000: /* IDEOGRAPHIC SPACE */ RRETURN(MATCH_NOMATCH); } } break; case OP_HSPACE: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINC(c, eptr); switch(c) { default: RRETURN(MATCH_NOMATCH); case 0x09: /* HT */ case 0x20: /* SPACE */ case 0xa0: /* NBSP */ case 0x1680: /* OGHAM SPACE MARK */ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ case 0x2000: /* EN QUAD */ case 0x2001: /* EM QUAD */ case 0x2002: /* EN SPACE */ case 0x2003: /* EM SPACE */ case 0x2004: /* THREE-PER-EM SPACE */ case 0x2005: /* FOUR-PER-EM SPACE */ case 0x2006: /* SIX-PER-EM SPACE */ case 0x2007: /* FIGURE SPACE */ case 0x2008: /* PUNCTUATION SPACE */ case 0x2009: /* THIN SPACE */ case 0x200A: /* HAIR SPACE */ case 0x202f: /* NARROW NO-BREAK SPACE */ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ case 0x3000: /* IDEOGRAPHIC SPACE */ break; } } break; case OP_NOT_VSPACE: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINC(c, eptr); switch(c) { default: break; case 0x0a: /* LF */ case 0x0b: /* VT */ case 0x0c: /* FF */ case 0x0d: /* CR */ case 0x85: /* NEL */ case 0x2028: /* LINE SEPARATOR */ case 0x2029: /* PARAGRAPH SEPARATOR */ RRETURN(MATCH_NOMATCH); } } break; case OP_VSPACE: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINC(c, eptr); switch(c) { default: RRETURN(MATCH_NOMATCH); case 0x0a: /* LF */ case 0x0b: /* VT */ case 0x0c: /* FF */ case 0x0d: /* CR */ case 0x85: /* NEL */ case 0x2028: /* LINE SEPARATOR */ case 0x2029: /* PARAGRAPH SEPARATOR */ break; } } break; case OP_NOT_DIGIT: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINC(c, eptr); if (c < 128 && (md->ctypes[c] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH); } break; case OP_DIGIT: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject || *eptr >= 128 || (md->ctypes[*eptr++] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH); /* No need to skip more bytes - we know it's a 1-byte character */ } break; case OP_NOT_WHITESPACE: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject || (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0)) RRETURN(MATCH_NOMATCH); while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80); } break; case OP_WHITESPACE: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject || *eptr >= 128 || (md->ctypes[*eptr++] & ctype_space) == 0) RRETURN(MATCH_NOMATCH); /* No need to skip more bytes - we know it's a 1-byte character */ } break; case OP_NOT_WORDCHAR: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject || (*eptr < 128 && (md->ctypes[*eptr] & ctype_word) != 0)) RRETURN(MATCH_NOMATCH); while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80); } break; case OP_WORDCHAR: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject || *eptr >= 128 || (md->ctypes[*eptr++] & ctype_word) == 0) RRETURN(MATCH_NOMATCH); /* No need to skip more bytes - we know it's a 1-byte character */ } break; default: RRETURN(PCRE_ERROR_INTERNAL); } /* End switch(ctype) */ else #endif /* SUPPORT_UTF8 */ /* Code for the non-UTF-8 case for minimum matching of operators other than OP_PROP and OP_NOTPROP. We can assume that there are the minimum number of bytes present, as this was tested above. */ switch(ctype) { case OP_ANY: if ((ims & PCRE_DOTALL) == 0) { for (i = 1; i <= min; i++) { if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); eptr++; } } else eptr += min; break; case OP_ANYBYTE: eptr += min; break; /* Because of the CRLF case, we can't assume the minimum number of bytes are present in this case. */ case OP_ANYNL: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); switch(*eptr++) { default: RRETURN(MATCH_NOMATCH); case 0x000d: if (eptr < md->end_subject && *eptr == 0x0a) eptr++; break; case 0x000a: case 0x000b: case 0x000c: case 0x0085: break; } } break; case OP_NOT_HSPACE: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); switch(*eptr++) { default: break; case 0x09: /* HT */ case 0x20: /* SPACE */ case 0xa0: /* NBSP */ RRETURN(MATCH_NOMATCH); } } break; case OP_HSPACE: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); switch(*eptr++) { default: RRETURN(MATCH_NOMATCH); case 0x09: /* HT */ case 0x20: /* SPACE */ case 0xa0: /* NBSP */ break; } } break; case OP_NOT_VSPACE: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); switch(*eptr++) { default: break; case 0x0a: /* LF */ case 0x0b: /* VT */ case 0x0c: /* FF */ case 0x0d: /* CR */ case 0x85: /* NEL */ RRETURN(MATCH_NOMATCH); } } break; case OP_VSPACE: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); switch(*eptr++) { default: RRETURN(MATCH_NOMATCH); case 0x0a: /* LF */ case 0x0b: /* VT */ case 0x0c: /* FF */ case 0x0d: /* CR */ case 0x85: /* NEL */ break; } } break; case OP_NOT_DIGIT: for (i = 1; i <= min; i++) if ((md->ctypes[*eptr++] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH); break; case OP_DIGIT: for (i = 1; i <= min; i++) if ((md->ctypes[*eptr++] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH); break; case OP_NOT_WHITESPACE: for (i = 1; i <= min; i++) if ((md->ctypes[*eptr++] & ctype_space) != 0) RRETURN(MATCH_NOMATCH); break; case OP_WHITESPACE: for (i = 1; i <= min; i++) if ((md->ctypes[*eptr++] & ctype_space) == 0) RRETURN(MATCH_NOMATCH); break; case OP_NOT_WORDCHAR: for (i = 1; i <= min; i++) if ((md->ctypes[*eptr++] & ctype_word) != 0) RRETURN(MATCH_NOMATCH); break; case OP_WORDCHAR: for (i = 1; i <= min; i++) if ((md->ctypes[*eptr++] & ctype_word) == 0) RRETURN(MATCH_NOMATCH); break; default: RRETURN(PCRE_ERROR_INTERNAL); } } /* If min = max, continue at the same level without recursing */ if (min == max) continue; /* If minimizing, we have to test the rest of the pattern before each subsequent match. Again, separate the UTF-8 case for speed, and also separate the UCP cases. */ if (minimize) { #ifdef SUPPORT_UCP if (prop_type >= 0) { switch(prop_type) { case PT_ANY: for (fi = min;; fi++) { RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM36); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINC(c, eptr); if (prop_fail_result) RRETURN(MATCH_NOMATCH); } /* Control never gets here */ case PT_LAMP: for (fi = min;; fi++) { RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM37); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINC(c, eptr); prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script); if ((prop_chartype == ucp_Lu || prop_chartype == ucp_Ll || prop_chartype == ucp_Lt) == prop_fail_result) RRETURN(MATCH_NOMATCH); } /* Control never gets here */ case PT_GC: for (fi = min;; fi++) { RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM38); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINC(c, eptr); prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script); if ((prop_category == prop_value) == prop_fail_result) RRETURN(MATCH_NOMATCH); } /* Control never gets here */ case PT_PC: for (fi = min;; fi++) { RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM39); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINC(c, eptr); prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script); if ((prop_chartype == prop_value) == prop_fail_result) RRETURN(MATCH_NOMATCH); } /* Control never gets here */ case PT_SC: for (fi = min;; fi++) { RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM40); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINC(c, eptr); prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script); if ((prop_script == prop_value) == prop_fail_result) RRETURN(MATCH_NOMATCH); } /* Control never gets here */ default: RRETURN(PCRE_ERROR_INTERNAL); } } /* Match extended Unicode sequences. We will get here only if the support is in the binary; otherwise a compile-time error occurs. */ else if (ctype == OP_EXTUNI) { for (fi = min;; fi++) { RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM41); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINCTEST(c, eptr); prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script); if (prop_category == ucp_M) RRETURN(MATCH_NOMATCH); while (eptr < md->end_subject) { int len = 1; if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); } prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script); if (prop_category != ucp_M) break; eptr += len; } } } else #endif /* SUPPORT_UCP */ #ifdef SUPPORT_UTF8 /* UTF-8 mode */ if (utf8) { for (fi = min;; fi++) { RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM42); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max || eptr >= md->end_subject || (ctype == OP_ANY && (ims & PCRE_DOTALL) == 0 && IS_NEWLINE(eptr))) RRETURN(MATCH_NOMATCH); GETCHARINC(c, eptr); switch(ctype) { case OP_ANY: /* This is the DOTALL case */ break; case OP_ANYBYTE: break; case OP_ANYNL: switch(c) { default: RRETURN(MATCH_NOMATCH); case 0x000d: if (eptr < md->end_subject && *eptr == 0x0a) eptr++; break; case 0x000a: case 0x000b: case 0x000c: case 0x0085: case 0x2028: case 0x2029: break; } break; case OP_NOT_HSPACE: switch(c) { default: break; case 0x09: /* HT */ case 0x20: /* SPACE */ case 0xa0: /* NBSP */ case 0x1680: /* OGHAM SPACE MARK */ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ case 0x2000: /* EN QUAD */ case 0x2001: /* EM QUAD */ case 0x2002: /* EN SPACE */ case 0x2003: /* EM SPACE */ case 0x2004: /* THREE-PER-EM SPACE */ case 0x2005: /* FOUR-PER-EM SPACE */ case 0x2006: /* SIX-PER-EM SPACE */ case 0x2007: /* FIGURE SPACE */ case 0x2008: /* PUNCTUATION SPACE */ case 0x2009: /* THIN SPACE */ case 0x200A: /* HAIR SPACE */ case 0x202f: /* NARROW NO-BREAK SPACE */ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ case 0x3000: /* IDEOGRAPHIC SPACE */ RRETURN(MATCH_NOMATCH); } break; case OP_HSPACE: switch(c) { default: RRETURN(MATCH_NOMATCH); case 0x09: /* HT */ case 0x20: /* SPACE */ case 0xa0: /* NBSP */ case 0x1680: /* OGHAM SPACE MARK */ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ case 0x2000: /* EN QUAD */ case 0x2001: /* EM QUAD */ case 0x2002: /* EN SPACE */ case 0x2003: /* EM SPACE */ case 0x2004: /* THREE-PER-EM SPACE */ case 0x2005: /* FOUR-PER-EM SPACE */ case 0x2006: /* SIX-PER-EM SPACE */ case 0x2007: /* FIGURE SPACE */ case 0x2008: /* PUNCTUATION SPACE */ case 0x2009: /* THIN SPACE */ case 0x200A: /* HAIR SPACE */ case 0x202f: /* NARROW NO-BREAK SPACE */ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ case 0x3000: /* IDEOGRAPHIC SPACE */ break; } break; case OP_NOT_VSPACE: switch(c) { default: break; case 0x0a: /* LF */ case 0x0b: /* VT */ case 0x0c: /* FF */ case 0x0d: /* CR */ case 0x85: /* NEL */ case 0x2028: /* LINE SEPARATOR */ case 0x2029: /* PARAGRAPH SEPARATOR */ RRETURN(MATCH_NOMATCH); } break; case OP_VSPACE: switch(c) { default: RRETURN(MATCH_NOMATCH); case 0x0a: /* LF */ case 0x0b: /* VT */ case 0x0c: /* FF */ case 0x0d: /* CR */ case 0x85: /* NEL */ case 0x2028: /* LINE SEPARATOR */ case 0x2029: /* PARAGRAPH SEPARATOR */ break; } break; case OP_NOT_DIGIT: if (c < 256 && (md->ctypes[c] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH); break; case OP_DIGIT: if (c >= 256 || (md->ctypes[c] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH); break; case OP_NOT_WHITESPACE: if (c < 256 && (md->ctypes[c] & ctype_space) != 0) RRETURN(MATCH_NOMATCH); break; case OP_WHITESPACE: if (c >= 256 || (md->ctypes[c] & ctype_space) == 0) RRETURN(MATCH_NOMATCH); break; case OP_NOT_WORDCHAR: if (c < 256 && (md->ctypes[c] & ctype_word) != 0) RRETURN(MATCH_NOMATCH); break; case OP_WORDCHAR: if (c >= 256 || (md->ctypes[c] & ctype_word) == 0) RRETURN(MATCH_NOMATCH); break; default: RRETURN(PCRE_ERROR_INTERNAL); } } } else #endif /* Not UTF-8 mode */ { for (fi = min;; fi++) { RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM43); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max || eptr >= md->end_subject || ((ims & PCRE_DOTALL) == 0 && IS_NEWLINE(eptr))) RRETURN(MATCH_NOMATCH); c = *eptr++; switch(ctype) { case OP_ANY: /* This is the DOTALL case */ break; case OP_ANYBYTE: break; case OP_ANYNL: switch(c) { default: RRETURN(MATCH_NOMATCH); case 0x000d: if (eptr < md->end_subject && *eptr == 0x0a) eptr++; break; case 0x000a: case 0x000b: case 0x000c: case 0x0085: break; } break; case OP_NOT_HSPACE: switch(c) { default: break; case 0x09: /* HT */ case 0x20: /* SPACE */ case 0xa0: /* NBSP */ RRETURN(MATCH_NOMATCH); } break; case OP_HSPACE: switch(c) { default: RRETURN(MATCH_NOMATCH); case 0x09: /* HT */ case 0x20: /* SPACE */ case 0xa0: /* NBSP */ break; } break; case OP_NOT_VSPACE: switch(c) { default: break; case 0x0a: /* LF */ case 0x0b: /* VT */ case 0x0c: /* FF */ case 0x0d: /* CR */ case 0x85: /* NEL */ RRETURN(MATCH_NOMATCH); } break; case OP_VSPACE: switch(c) { default: RRETURN(MATCH_NOMATCH); case 0x0a: /* LF */ case 0x0b: /* VT */ case 0x0c: /* FF */ case 0x0d: /* CR */ case 0x85: /* NEL */ break; } break; case OP_NOT_DIGIT: if ((md->ctypes[c] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH); break; case OP_DIGIT: if ((md->ctypes[c] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH); break; case OP_NOT_WHITESPACE: if ((md->ctypes[c] & ctype_space) != 0) RRETURN(MATCH_NOMATCH); break; case OP_WHITESPACE: if ((md->ctypes[c] & ctype_space) == 0) RRETURN(MATCH_NOMATCH); break; case OP_NOT_WORDCHAR: if ((md->ctypes[c] & ctype_word) != 0) RRETURN(MATCH_NOMATCH); break; case OP_WORDCHAR: if ((md->ctypes[c] & ctype_word) == 0) RRETURN(MATCH_NOMATCH); break; default: RRETURN(PCRE_ERROR_INTERNAL); } } } /* Control never gets here */ } /* If maximizing, it is worth using inline code for speed, doing the type test once at the start (i.e. keep it out of the loop). Again, keep the UTF-8 and UCP stuff separate. */ else { pp = eptr; /* Remember where we started */ #ifdef SUPPORT_UCP if (prop_type >= 0) { switch(prop_type) { case PT_ANY: for (i = min; i < max; i++) { int len = 1; if (eptr >= md->end_subject) break; GETCHARLEN(c, eptr, len); if (prop_fail_result) break; eptr+= len; } break; case PT_LAMP: for (i = min; i < max; i++) { int len = 1; if (eptr >= md->end_subject) break; GETCHARLEN(c, eptr, len); prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script); if ((prop_chartype == ucp_Lu || prop_chartype == ucp_Ll || prop_chartype == ucp_Lt) == prop_fail_result) break; eptr+= len; } break; case PT_GC: for (i = min; i < max; i++) { int len = 1; if (eptr >= md->end_subject) break; GETCHARLEN(c, eptr, len); prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script); if ((prop_category == prop_value) == prop_fail_result) break; eptr+= len; } break; case PT_PC: for (i = min; i < max; i++) { int len = 1; if (eptr >= md->end_subject) break; GETCHARLEN(c, eptr, len); prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script); if ((prop_chartype == prop_value) == prop_fail_result) break; eptr+= len; } break; case PT_SC: for (i = min; i < max; i++) { int len = 1; if (eptr >= md->end_subject) break; GETCHARLEN(c, eptr, len); prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script); if ((prop_script == prop_value) == prop_fail_result) break; eptr+= len; } break; } /* eptr is now past the end of the maximum run */ if (possessive) continue; for(;;) { RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM44); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (eptr-- == pp) break; /* Stop if tried at original pos */ if (utf8) BACKCHAR(eptr); } } /* Match extended Unicode sequences. We will get here only if the support is in the binary; otherwise a compile-time error occurs. */ else if (ctype == OP_EXTUNI) { for (i = min; i < max; i++) { if (eptr >= md->end_subject) break; GETCHARINCTEST(c, eptr); prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script); if (prop_category == ucp_M) break; while (eptr < md->end_subject) { int len = 1; if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); } prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script); if (prop_category != ucp_M) break; eptr += len; } } /* eptr is now past the end of the maximum run */ if (possessive) continue; for(;;) { RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM45); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (eptr-- == pp) break; /* Stop if tried at original pos */ for (;;) /* Move back over one extended */ { int len = 1; if (!utf8) c = *eptr; else { BACKCHAR(eptr); GETCHARLEN(c, eptr, len); } prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script); if (prop_category != ucp_M) break; eptr--; } } } else #endif /* SUPPORT_UCP */ #ifdef SUPPORT_UTF8 /* UTF-8 mode */ if (utf8) { switch(ctype) { case OP_ANY: if (max < INT_MAX) { if ((ims & PCRE_DOTALL) == 0) { for (i = min; i < max; i++) { if (eptr >= md->end_subject || IS_NEWLINE(eptr)) break; eptr++; while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++; } } else { for (i = min; i < max; i++) { if (eptr >= md->end_subject) break; eptr++; while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++; } } } /* Handle unlimited UTF-8 repeat */ else { if ((ims & PCRE_DOTALL) == 0) { for (i = min; i < max; i++) { if (eptr >= md->end_subject || IS_NEWLINE(eptr)) break; eptr++; while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++; } } else { eptr = md->end_subject; } } break; /* The byte case is the same as non-UTF8 */ case OP_ANYBYTE: c = max - min; if (c > (unsigned int)(md->end_subject - eptr)) c = md->end_subject - eptr; eptr += c; break; case OP_ANYNL: for (i = min; i < max; i++) { int len = 1; if (eptr >= md->end_subject) break; GETCHARLEN(c, eptr, len); if (c == 0x000d) { if (++eptr >= md->end_subject) break; if (*eptr == 0x000a) eptr++; } else { if (c != 0x000a && c != 0x000b && c != 0x000c && c != 0x0085 && c != 0x2028 && c != 0x2029) break; eptr += len; } } break; case OP_NOT_HSPACE: case OP_HSPACE: for (i = min; i < max; i++) { BOOL gotspace; int len = 1; if (eptr >= md->end_subject) break; GETCHARLEN(c, eptr, len); switch(c) { default: gotspace = FALSE; break; case 0x09: /* HT */ case 0x20: /* SPACE */ case 0xa0: /* NBSP */ case 0x1680: /* OGHAM SPACE MARK */ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ case 0x2000: /* EN QUAD */ case 0x2001: /* EM QUAD */ case 0x2002: /* EN SPACE */ case 0x2003: /* EM SPACE */ case 0x2004: /* THREE-PER-EM SPACE */ case 0x2005: /* FOUR-PER-EM SPACE */ case 0x2006: /* SIX-PER-EM SPACE */ case 0x2007: /* FIGURE SPACE */ case 0x2008: /* PUNCTUATION SPACE */ case 0x2009: /* THIN SPACE */ case 0x200A: /* HAIR SPACE */ case 0x202f: /* NARROW NO-BREAK SPACE */ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ case 0x3000: /* IDEOGRAPHIC SPACE */ gotspace = TRUE; break; } if (gotspace == (ctype == OP_NOT_HSPACE)) break; eptr += len; } break; case OP_NOT_VSPACE: case OP_VSPACE: for (i = min; i < max; i++) { BOOL gotspace; int len = 1; if (eptr >= md->end_subject) break; GETCHARLEN(c, eptr, len); switch(c) { default: gotspace = FALSE; break; case 0x0a: /* LF */ case 0x0b: /* VT */ case 0x0c: /* FF */ case 0x0d: /* CR */ case 0x85: /* NEL */ case 0x2028: /* LINE SEPARATOR */ case 0x2029: /* PARAGRAPH SEPARATOR */ gotspace = TRUE; break; } if (gotspace == (ctype == OP_NOT_VSPACE)) break; eptr += len; } break; case OP_NOT_DIGIT: for (i = min; i < max; i++) { int len = 1; if (eptr >= md->end_subject) break; GETCHARLEN(c, eptr, len); if (c < 256 && (md->ctypes[c] & ctype_digit) != 0) break; eptr+= len; } break; case OP_DIGIT: for (i = min; i < max; i++) { int len = 1; if (eptr >= md->end_subject) break; GETCHARLEN(c, eptr, len); if (c >= 256 ||(md->ctypes[c] & ctype_digit) == 0) break; eptr+= len; } break; case OP_NOT_WHITESPACE: for (i = min; i < max; i++) { int len = 1; if (eptr >= md->end_subject) break; GETCHARLEN(c, eptr, len); if (c < 256 && (md->ctypes[c] & ctype_space) != 0) break; eptr+= len; } break; case OP_WHITESPACE: for (i = min; i < max; i++) { int len = 1; if (eptr >= md->end_subject) break; GETCHARLEN(c, eptr, len); if (c >= 256 ||(md->ctypes[c] & ctype_space) == 0) break; eptr+= len; } break; case OP_NOT_WORDCHAR: for (i = min; i < max; i++) { int len = 1; if (eptr >= md->end_subject) break; GETCHARLEN(c, eptr, len); if (c < 256 && (md->ctypes[c] & ctype_word) != 0) break; eptr+= len; } break; case OP_WORDCHAR: for (i = min; i < max; i++) { int len = 1; if (eptr >= md->end_subject) break; GETCHARLEN(c, eptr, len); if (c >= 256 || (md->ctypes[c] & ctype_word) == 0) break; eptr+= len; } break; default: RRETURN(PCRE_ERROR_INTERNAL); } /* eptr is now past the end of the maximum run */ if (possessive) continue; for(;;) { RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM46); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (eptr-- == pp) break; /* Stop if tried at original pos */ BACKCHAR(eptr); } } else #endif /* SUPPORT_UTF8 */ /* Not UTF-8 mode */ { switch(ctype) { case OP_ANY: if ((ims & PCRE_DOTALL) == 0) { for (i = min; i < max; i++) { if (eptr >= md->end_subject || IS_NEWLINE(eptr)) break; eptr++; } break; } /* For DOTALL case, fall through and treat as \C */ case OP_ANYBYTE: c = max - min; if (c > (unsigned int)(md->end_subject - eptr)) c = md->end_subject - eptr; eptr += c; break; case OP_ANYNL: for (i = min; i < max; i++) { if (eptr >= md->end_subject) break; c = *eptr; if (c == 0x000d) { if (++eptr >= md->end_subject) break; if (*eptr == 0x000a) eptr++; } else { if (c != 0x000a && c != 0x000b && c != 0x000c && c != 0x0085) break; eptr++; } } break; case OP_NOT_HSPACE: for (i = min; i < max; i++) { if (eptr >= md->end_subject) break; c = *eptr; if (c == 0x09 || c == 0x20 || c == 0xa0) break; eptr++; } break; case OP_HSPACE: for (i = min; i < max; i++) { if (eptr >= md->end_subject) break; c = *eptr; if (c != 0x09 && c != 0x20 && c != 0xa0) break; eptr++; } break; case OP_NOT_VSPACE: for (i = min; i < max; i++) { if (eptr >= md->end_subject) break; c = *eptr; if (c == 0x0a || c == 0x0b || c == 0x0c || c == 0x0d || c == 0x85) break; eptr++; } break; case OP_VSPACE: for (i = min; i < max; i++) { if (eptr >= md->end_subject) break; c = *eptr; if (c != 0x0a && c != 0x0b && c != 0x0c && c != 0x0d && c != 0x85) break; eptr++; } break; case OP_NOT_DIGIT: for (i = min; i < max; i++) { if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_digit) != 0) break; eptr++; } break; case OP_DIGIT: for (i = min; i < max; i++) { if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_digit) == 0) break; eptr++; } break; case OP_NOT_WHITESPACE: for (i = min; i < max; i++) { if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_space) != 0) break; eptr++; } break; case OP_WHITESPACE: for (i = min; i < max; i++) { if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_space) == 0) break; eptr++; } break; case OP_NOT_WORDCHAR: for (i = min; i < max; i++) { if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_word) != 0) break; eptr++; } break; case OP_WORDCHAR: for (i = min; i < max; i++) { if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_word) == 0) break; eptr++; } break; default: RRETURN(PCRE_ERROR_INTERNAL); } /* eptr is now past the end of the maximum run */ if (possessive) continue; while (eptr >= pp) { RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM47); eptr--; if (rrc != MATCH_NOMATCH) RRETURN(rrc); } } /* Get here if we can't make it match with any permitted repetitions */ RRETURN(MATCH_NOMATCH); } /* Control never gets here */ /* There's been some horrible disaster. Arrival here can only mean there is something seriously wrong in the code above or the OP_xxx definitions. */ default: DPRINTF(("Unknown opcode %d\n", *ecode)); RRETURN(PCRE_ERROR_UNKNOWN_OPCODE); } /* Do not stick any code in here without much thought; it is assumed that "continue" in the code above comes out to here to repeat the main loop. */ } /* End of main loop */ /* Control never reaches here */ /* When compiling to use the heap rather than the stack for recursive calls to match(), the RRETURN() macro jumps here. The number that is saved in frame->Xwhere indicates which label we actually want to return to. */ #ifdef NO_RECURSE #define LBL(val) case val: goto L_RM##val; HEAP_RETURN: switch (frame->Xwhere) { LBL( 1) LBL( 2) LBL( 3) LBL( 4) LBL( 5) LBL( 6) LBL( 7) LBL( 8) LBL( 9) LBL(10) LBL(11) LBL(12) LBL(13) LBL(14) LBL(15) LBL(16) LBL(17) LBL(18) LBL(19) LBL(20) LBL(21) LBL(22) LBL(23) LBL(24) LBL(25) LBL(26) LBL(27) LBL(28) LBL(29) LBL(30) LBL(31) LBL(32) LBL(33) LBL(34) LBL(35) LBL(36) LBL(37) LBL(38) LBL(39) LBL(40) LBL(41) LBL(42) LBL(43) LBL(44) LBL(45) LBL(46) LBL(47) LBL(48) LBL(49) LBL(50) LBL(51) LBL(52) LBL(53) LBL(54) default: DPRINTF(("jump error in pcre match: label %d non-existent\n", frame->Xwhere)); return PCRE_ERROR_INTERNAL; } #undef LBL #endif /* NO_RECURSE */ } /*************************************************************************** **************************************************************************** RECURSION IN THE match() FUNCTION Undefine all the macros that were defined above to handle this. */ #ifdef NO_RECURSE #undef eptr #undef ecode #undef mstart #undef offset_top #undef ims #undef eptrb #undef flags #undef callpat #undef charptr #undef data #undef next #undef pp #undef prev #undef saved_eptr #undef new_recursive #undef cur_is_word #undef condition #undef prev_is_word #undef original_ims #undef ctype #undef length #undef max #undef min #undef number #undef offset #undef op #undef save_capture_last #undef save_offset1 #undef save_offset2 #undef save_offset3 #undef stacksave #undef newptrb #endif /* These two are defined as macros in both cases */ #undef fc #undef fi /*************************************************************************** ***************************************************************************/ /************************************************* * Execute a Regular Expression * *************************************************/ /* This function applies a compiled re to a subject string and picks out portions of the string if it matches. Two elements in the vector are set for each substring: the offsets to the start and end of the substring. Arguments: argument_re points to the compiled expression extra_data points to extra data or is NULL subject points to the subject string length length of subject string (may contain binary zeros) start_offset where to start in the subject string options option bits offsets points to a vector of ints to be filled in with offsets offsetcount the number of elements in the vector Returns: > 0 => success; value is the number of elements filled in = 0 => success, but offsets is not big enough -1 => failed to match < -1 => some kind of unexpected problem */ PCRE_EXP_DEFN int pcre_exec(const pcre *argument_re, const pcre_extra *extra_data, PCRE_SPTR subject, int length, int start_offset, int options, int *offsets, int offsetcount) { int rc, resetcount, ocount; int first_byte = -1; int req_byte = -1; int req_byte2 = -1; int newline; unsigned long int ims; BOOL using_temporary_offsets = FALSE; BOOL anchored; BOOL startline; BOOL firstline; BOOL first_byte_caseless = FALSE; BOOL req_byte_caseless = FALSE; BOOL utf8; match_data match_block; match_data *md = &match_block; const uschar *tables; const uschar *start_bits = NULL; USPTR start_match = (USPTR)subject + start_offset; USPTR end_subject; USPTR req_byte_ptr = start_match - 1; pcre_study_data internal_study; const pcre_study_data *study; real_pcre internal_re; const real_pcre *external_re = (const real_pcre *)argument_re; const real_pcre *re = external_re; /* Plausibility checks */ if ((options & ~PUBLIC_EXEC_OPTIONS) != 0) return PCRE_ERROR_BADOPTION; if (re == NULL || subject == NULL || (offsets == NULL && offsetcount > 0)) return PCRE_ERROR_NULL; if (offsetcount < 0) return PCRE_ERROR_BADCOUNT; /* Fish out the optional data from the extra_data structure, first setting the default values. */ study = NULL; md->match_limit = MATCH_LIMIT; md->match_limit_recursion = MATCH_LIMIT_RECURSION; md->callout_data = NULL; /* The table pointer is always in native byte order. */ tables = external_re->tables; if (extra_data != NULL) { register unsigned int flags = extra_data->flags; if ((flags & PCRE_EXTRA_STUDY_DATA) != 0) study = (const pcre_study_data *)extra_data->study_data; if ((flags & PCRE_EXTRA_MATCH_LIMIT) != 0) md->match_limit = extra_data->match_limit; if ((flags & PCRE_EXTRA_MATCH_LIMIT_RECURSION) != 0) md->match_limit_recursion = extra_data->match_limit_recursion; if ((flags & PCRE_EXTRA_CALLOUT_DATA) != 0) md->callout_data = extra_data->callout_data; if ((flags & PCRE_EXTRA_TABLES) != 0) tables = extra_data->tables; } /* If the exec call supplied NULL for tables, use the inbuilt ones. This is a feature that makes it possible to save compiled regex and re-use them in other programs later. */ if (tables == NULL) tables = _pcre_default_tables; /* Check that the first field in the block is the magic number. If it is not, test for a regex that was compiled on a host of opposite endianness. If this is the case, flipped values are put in internal_re and internal_study if there was study data too. */ if (re->magic_number != MAGIC_NUMBER) { re = _pcre_try_flipped(re, &internal_re, study, &internal_study); if (re == NULL) return PCRE_ERROR_BADMAGIC; if (study != NULL) study = &internal_study; } /* Set up other data */ anchored = ((re->options | options) & PCRE_ANCHORED) != 0; startline = (re->options & PCRE_STARTLINE) != 0; firstline = (re->options & PCRE_FIRSTLINE) != 0; /* The code starts after the real_pcre block and the capture name table. */ md->start_code = (const uschar *)external_re + re->name_table_offset + re->name_count * re->name_entry_size; md->start_subject = (USPTR)subject; md->start_offset = start_offset; md->end_subject = md->start_subject + length; end_subject = md->end_subject; md->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0; utf8 = md->utf8 = (re->options & PCRE_UTF8) != 0; md->notbol = (options & PCRE_NOTBOL) != 0; md->noteol = (options & PCRE_NOTEOL) != 0; md->notempty = (options & PCRE_NOTEMPTY) != 0; md->partial = (options & PCRE_PARTIAL) != 0; md->hitend = FALSE; md->recursive = NULL; /* No recursion at top level */ md->lcc = tables + lcc_offset; md->ctypes = tables + ctypes_offset; /* Handle different types of newline. The three bits give eight cases. If nothing is set at run time, whatever was used at compile time applies. */ switch ((((options & PCRE_NEWLINE_BITS) == 0)? re->options : (pcre_uint32)options) & PCRE_NEWLINE_BITS) { case 0: newline = NEWLINE; break; /* Compile-time default */ case PCRE_NEWLINE_CR: newline = '\r'; break; case PCRE_NEWLINE_LF: newline = '\n'; break; case PCRE_NEWLINE_CR+ PCRE_NEWLINE_LF: newline = ('\r' << 8) | '\n'; break; case PCRE_NEWLINE_ANY: newline = -1; break; case PCRE_NEWLINE_ANYCRLF: newline = -2; break; default: return PCRE_ERROR_BADNEWLINE; } if (newline == -2) { md->nltype = NLTYPE_ANYCRLF; } else if (newline < 0) { md->nltype = NLTYPE_ANY; } else { md->nltype = NLTYPE_FIXED; if (newline > 255) { md->nllen = 2; md->nl[0] = (newline >> 8) & 255; md->nl[1] = newline & 255; } else { md->nllen = 1; md->nl[0] = newline; } } /* Partial matching is supported only for a restricted set of regexes at the moment. */ if (md->partial && (re->options & PCRE_NOPARTIAL) != 0) return PCRE_ERROR_BADPARTIAL; /* Check a UTF-8 string if required. Unfortunately there's no way of passing back the character offset. */ #ifdef SUPPORT_UTF8 if (utf8 && (options & PCRE_NO_UTF8_CHECK) == 0) { if (_pcre_valid_utf8((uschar *)subject, length) >= 0) return PCRE_ERROR_BADUTF8; if (start_offset > 0 && start_offset < length) { int tb = ((uschar *)subject)[start_offset]; if (tb > 127) { tb &= 0xc0; if (tb != 0 && tb != 0xc0) return PCRE_ERROR_BADUTF8_OFFSET; } } } #endif /* The ims options can vary during the matching as a result of the presence of (?ims) items in the pattern. They are kept in a local variable so that restoring at the exit of a group is easy. */ ims = re->options & (PCRE_CASELESS|PCRE_MULTILINE|PCRE_DOTALL); /* If the expression has got more back references than the offsets supplied can hold, we get a temporary chunk of working store to use during the matching. Otherwise, we can use the vector supplied, rounding down its size to a multiple of 3. */ ocount = offsetcount - (offsetcount % 3); if (re->top_backref > 0 && re->top_backref >= ocount/3) { ocount = re->top_backref * 3 + 3; md->offset_vector = (int *)(pcre_malloc)(ocount * sizeof(int)); if (md->offset_vector == NULL) return PCRE_ERROR_NOMEMORY; using_temporary_offsets = TRUE; DPRINTF(("Got memory to hold back references\n")); } else md->offset_vector = offsets; md->offset_end = ocount; md->offset_max = (2*ocount)/3; md->offset_overflow = FALSE; md->capture_last = -1; /* Compute the minimum number of offsets that we need to reset each time. Doing this makes a huge difference to execution time when there aren't many brackets in the pattern. */ resetcount = 2 + re->top_bracket * 2; if (resetcount > offsetcount) resetcount = ocount; /* Reset the working variable associated with each extraction. These should never be used unless previously set, but they get saved and restored, and so we initialize them to avoid reading uninitialized locations. */ if (md->offset_vector != NULL) { register int *iptr = md->offset_vector + ocount; register int *iend = iptr - resetcount/2 + 1; while (--iptr >= iend) *iptr = -1; } /* Set up the first character to match, if available. The first_byte value is never set for an anchored regular expression, but the anchoring may be forced at run time, so we have to test for anchoring. The first char may be unset for an unanchored pattern, of course. If there's no first char and the pattern was studied, there may be a bitmap of possible first characters. */ if (!anchored) { if ((re->options & PCRE_FIRSTSET) != 0) { first_byte = re->first_byte & 255; if ((first_byte_caseless = ((re->first_byte & REQ_CASELESS) != 0)) == TRUE) first_byte = md->lcc[first_byte]; } else if (!startline && study != NULL && (study->options & PCRE_STUDY_MAPPED) != 0) start_bits = study->start_bits; } /* For anchored or unanchored matches, there may be a "last known required character" set. */ if ((re->options & PCRE_REQCHSET) != 0) { req_byte = re->req_byte & 255; req_byte_caseless = (re->req_byte & REQ_CASELESS) != 0; req_byte2 = (tables + fcc_offset)[req_byte]; /* case flipped */ } /* ==========================================================================*/ /* Loop for handling unanchored repeated matching attempts; for anchored regexs the loop runs just once. */ for(;;) { USPTR save_end_subject = end_subject; USPTR new_start_match; /* Reset the maximum number of extractions we might see. */ if (md->offset_vector != NULL) { register int *iptr = md->offset_vector; register int *iend = iptr + resetcount; while (iptr < iend) *iptr++ = -1; } /* Advance to a unique first char if possible. If firstline is TRUE, the start of the match is constrained to the first line of a multiline string. That is, the match must be before or at the first newline. Implement this by temporarily adjusting end_subject so that we stop scanning at a newline. If the match fails at the newline, later code breaks this loop. */ if (firstline) { USPTR t = start_match; while (t < md->end_subject && !IS_NEWLINE(t)) t++; end_subject = t; } /* Now test for a unique first byte */ if (first_byte >= 0) { if (first_byte_caseless) while (start_match < end_subject && md->lcc[*start_match] != first_byte) start_match++; else while (start_match < end_subject && *start_match != first_byte) start_match++; } /* Or to just after a linebreak for a multiline match if possible */ else if (startline) { if (start_match > md->start_subject + start_offset) { while (start_match <= end_subject && !WAS_NEWLINE(start_match)) start_match++; /* If we have just passed a CR and the newline option is ANY or ANYCRLF, and we are now at a LF, advance the match position by one more character. */ if (start_match[-1] == '\r' && (md->nltype == NLTYPE_ANY || md->nltype == NLTYPE_ANYCRLF) && start_match < end_subject && *start_match == '\n') start_match++; } } /* Or to a non-unique first char after study */ else if (start_bits != NULL) { while (start_match < end_subject) { register unsigned int c = *start_match; if ((start_bits[c/8] & (1 << (c&7))) == 0) start_match++; else break; } } /* Restore fudged end_subject */ end_subject = save_end_subject; #ifdef DEBUG /* Sigh. Some compilers never learn. */ printf(">>>> Match against: "); pchars(start_match, end_subject - start_match, TRUE, md); printf("\n"); #endif /* If req_byte is set, we know that that character must appear in the subject for the match to succeed. If the first character is set, req_byte must be later in the subject; otherwise the test starts at the match point. This optimization can save a huge amount of backtracking in patterns with nested unlimited repeats that aren't going to match. Writing separate code for cased/caseless versions makes it go faster, as does using an autoincrement and backing off on a match. HOWEVER: when the subject string is very, very long, searching to its end can take a long time, and give bad performance on quite ordinary patterns. This showed up when somebody was matching something like /^\d+C/ on a 32-megabyte string... so we don't do this when the string is sufficiently long. ALSO: this processing is disabled when partial matching is requested. */ if (req_byte >= 0 && end_subject - start_match < REQ_BYTE_MAX && !md->partial) { register USPTR p = start_match + ((first_byte >= 0)? 1 : 0); /* We don't need to repeat the search if we haven't yet reached the place we found it at last time. */ if (p > req_byte_ptr) { if (req_byte_caseless) { while (p < end_subject) { register int pp = *p++; if (pp == req_byte || pp == req_byte2) { p--; break; } } } else { while (p < end_subject) { if (*p++ == req_byte) { p--; break; } } } /* If we can't find the required character, break the matching loop, forcing a match failure. */ if (p >= end_subject) { rc = MATCH_NOMATCH; break; } /* If we have found the required character, save the point where we found it, so that we don't search again next time round the loop if the start hasn't passed this character yet. */ req_byte_ptr = p; } } /* OK, we can now run the match. */ md->start_match_ptr = start_match; md->match_call_count = 0; rc = match(start_match, md->start_code, start_match, 2, md, ims, NULL, 0, 0); switch(rc) { /* NOMATCH and PRUNE advance by one character. THEN at this level acts exactly like PRUNE. */ case MATCH_NOMATCH: case MATCH_PRUNE: case MATCH_THEN: new_start_match = start_match + 1; #ifdef SUPPORT_UTF8 if (utf8) while(new_start_match < end_subject && (*new_start_match & 0xc0) == 0x80) new_start_match++; #endif break; /* SKIP passes back the next starting point explicitly. */ case MATCH_SKIP: new_start_match = md->start_match_ptr; break; /* COMMIT disables the bumpalong, but otherwise behaves as NOMATCH. */ case MATCH_COMMIT: rc = MATCH_NOMATCH; goto ENDLOOP; /* Any other return is some kind of error. */ default: goto ENDLOOP; } /* Control reaches here for the various types of "no match at this point" result. Reset the code to MATCH_NOMATCH for subsequent checking. */ rc = MATCH_NOMATCH; /* If PCRE_FIRSTLINE is set, the match must happen before or at the first newline in the subject (though it may continue over the newline). Therefore, if we have just failed to match, starting at a newline, do not continue. */ if (firstline && IS_NEWLINE(start_match)) break; /* Advance to new matching position */ start_match = new_start_match; /* Break the loop if the pattern is anchored or if we have passed the end of the subject. */ if (anchored || start_match > end_subject) break; /* If we have just passed a CR and we are now at a LF, and the pattern does not contain any explicit matches for \r or \n, and the newline option is CRLF or ANY or ANYCRLF, advance the match position by one more character. */ if (start_match[-1] == '\r' && start_match < end_subject && *start_match == '\n' && (re->options & PCRE_HASCRORLF) == 0 && (md->nltype == NLTYPE_ANY || md->nltype == NLTYPE_ANYCRLF || md->nllen == 2)) start_match++; } /* End of for(;;) "bumpalong" loop */ /* ==========================================================================*/ /* We reach here when rc is not MATCH_NOMATCH, or if one of the stopping conditions is true: (1) The pattern is anchored or the match was failed by (*COMMIT); (2) We are past the end of the subject; (3) PCRE_FIRSTLINE is set and we have failed to match at a newline, because this option requests that a match occur at or before the first newline in the subject. When we have a match and the offset vector is big enough to deal with any backreferences, captured substring offsets will already be set up. In the case where we had to get some local store to hold offsets for backreference processing, copy those that we can. In this case there need not be overflow if certain parts of the pattern were not used, even though there are more capturing parentheses than vector slots. */ ENDLOOP: if (rc == MATCH_MATCH) { if (using_temporary_offsets) { if (offsetcount >= 4) { memcpy(offsets + 2, md->offset_vector + 2, (offsetcount - 2) * sizeof(int)); DPRINTF(("Copied offsets from temporary memory\n")); } if (md->end_offset_top > offsetcount) md->offset_overflow = TRUE; DPRINTF(("Freeing temporary memory\n")); (pcre_free)(md->offset_vector); } /* Set the return code to the number of captured strings, or 0 if there are too many to fit into the vector. */ rc = md->offset_overflow? 0 : md->end_offset_top/2; /* If there is space, set up the whole thing as substring 0. The value of md->start_match_ptr might be modified if \K was encountered on the success matching path. */ if (offsetcount < 2) rc = 0; else { offsets[0] = md->start_match_ptr - md->start_subject; offsets[1] = md->end_match_ptr - md->start_subject; } DPRINTF((">>>> returning %d\n", rc)); return rc; } /* Control gets here if there has been an error, or if the overall match attempt has failed at all permitted starting positions. */ if (using_temporary_offsets) { DPRINTF(("Freeing temporary memory\n")); (pcre_free)(md->offset_vector); } if (rc != MATCH_NOMATCH) { DPRINTF((">>>> error: returning %d\n", rc)); return rc; } else if (md->partial && md->hitend) { DPRINTF((">>>> returning PCRE_ERROR_PARTIAL\n")); return PCRE_ERROR_PARTIAL; } else { DPRINTF((">>>> returning PCRE_ERROR_NOMATCH\n")); return PCRE_ERROR_NOMATCH; } } /* End of pcre_exec.c */ libsynthesis-3.4.0.47.1/src/pcre/pcre_fullinfo.c000066400000000000000000000121671226375725500213660ustar00rootroot00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /*PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2007 University of Cambridge ----------------------------------------------------------------------------- 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 name of the University of Cambridge 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. ----------------------------------------------------------------------------- */ /* This module contains the external function pcre_fullinfo(), which returns information about a compiled pattern. */ #include "pcre_setup.h" #include "pcre_internal.h" /************************************************* * Return info about compiled pattern * *************************************************/ /* This is a newer "info" function which has an extensible interface so that additional items can be added compatibly. Arguments: argument_re points to compiled code extra_data points extra data, or NULL what what information is required where where to put the information Returns: 0 if data returned, negative on error */ PCRE_EXP_DEFN int pcre_fullinfo(const pcre *argument_re, const pcre_extra *extra_data, int what, void *where) { real_pcre internal_re; pcre_study_data internal_study; const real_pcre *re = (const real_pcre *)argument_re; const pcre_study_data *study = NULL; if (re == NULL || where == NULL) return PCRE_ERROR_NULL; if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_STUDY_DATA) != 0) study = (const pcre_study_data *)extra_data->study_data; if (re->magic_number != MAGIC_NUMBER) { re = _pcre_try_flipped(re, &internal_re, study, &internal_study); if (re == NULL) return PCRE_ERROR_BADMAGIC; if (study != NULL) study = &internal_study; } switch (what) { case PCRE_INFO_OPTIONS: *((unsigned long int *)where) = re->options & PUBLIC_OPTIONS; break; case PCRE_INFO_SIZE: *((size_t *)where) = re->size; break; case PCRE_INFO_STUDYSIZE: *((size_t *)where) = (study == NULL)? 0 : study->size; break; case PCRE_INFO_CAPTURECOUNT: *((int *)where) = re->top_bracket; break; case PCRE_INFO_BACKREFMAX: *((int *)where) = re->top_backref; break; case PCRE_INFO_FIRSTBYTE: *((int *)where) = ((re->options & PCRE_FIRSTSET) != 0)? re->first_byte : ((re->options & PCRE_STARTLINE) != 0)? -1 : -2; break; /* Make sure we pass back the pointer to the bit vector in the external block, not the internal copy (with flipped integer fields). */ case PCRE_INFO_FIRSTTABLE: *((const uschar **)where) = (study != NULL && (study->options & PCRE_STUDY_MAPPED) != 0)? ((const pcre_study_data *)extra_data->study_data)->start_bits : NULL; break; case PCRE_INFO_LASTLITERAL: *((int *)where) = ((re->options & PCRE_REQCHSET) != 0)? re->req_byte : -1; break; case PCRE_INFO_NAMEENTRYSIZE: *((int *)where) = re->name_entry_size; break; case PCRE_INFO_NAMECOUNT: *((int *)where) = re->name_count; break; case PCRE_INFO_NAMETABLE: *((const uschar **)where) = (const uschar *)re + re->name_table_offset; break; case PCRE_INFO_DEFAULT_TABLES: *((const uschar **)where) = (const uschar *)(_pcre_default_tables); break; case PCRE_INFO_OKPARTIAL: *((int *)where) = (re->options & PCRE_NOPARTIAL) == 0; break; case PCRE_INFO_JCHANGED: *((int *)where) = (re->options & PCRE_JCHANGED) != 0; break; case PCRE_INFO_HASCRORLF: *((int *)where) = (re->options & PCRE_HASCRORLF) != 0; break; default: return PCRE_ERROR_BADOPTION; } return 0; } /* End of pcre_fullinfo.c */ libsynthesis-3.4.0.47.1/src/pcre/pcre_get.c000066400000000000000000000355431226375725500203320ustar00rootroot00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2007 University of Cambridge ----------------------------------------------------------------------------- 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 name of the University of Cambridge 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. ----------------------------------------------------------------------------- */ /* This module contains some convenience functions for extracting substrings from the subject string after a regex match has succeeded. The original idea for these functions came from Scott Wimer. */ #include "pcre_setup.h" #include "pcre_internal.h" /************************************************* * Find number for named string * *************************************************/ /* This function is used by the get_first_set() function below, as well as being generally available. It assumes that names are unique. Arguments: code the compiled regex stringname the name whose number is required Returns: the number of the named parentheses, or a negative number (PCRE_ERROR_NOSUBSTRING) if not found */ int pcre_get_stringnumber(const pcre *code, const char *stringname) { int rc; int entrysize; int top, bot; uschar *nametable; if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0) return rc; if (top <= 0) return PCRE_ERROR_NOSUBSTRING; if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0) return rc; if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0) return rc; bot = 0; while (top > bot) { int mid = (top + bot) / 2; uschar *entry = nametable + entrysize*mid; int c = strcmp(stringname, (char *)(entry + 2)); if (c == 0) return (entry[0] << 8) + entry[1]; if (c > 0) bot = mid + 1; else top = mid; } return PCRE_ERROR_NOSUBSTRING; } /************************************************* * Find (multiple) entries for named string * *************************************************/ /* This is used by the get_first_set() function below, as well as being generally available. It is used when duplicated names are permitted. Arguments: code the compiled regex stringname the name whose entries required firstptr where to put the pointer to the first entry lastptr where to put the pointer to the last entry Returns: the length of each entry, or a negative number (PCRE_ERROR_NOSUBSTRING) if not found */ int pcre_get_stringtable_entries(const pcre *code, const char *stringname, char **firstptr, char **lastptr) { int rc; int entrysize; int top, bot; uschar *nametable, *lastentry; if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0) return rc; if (top <= 0) return PCRE_ERROR_NOSUBSTRING; if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0) return rc; if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0) return rc; lastentry = nametable + entrysize * (top - 1); bot = 0; while (top > bot) { int mid = (top + bot) / 2; uschar *entry = nametable + entrysize*mid; int c = strcmp(stringname, (char *)(entry + 2)); if (c == 0) { uschar *first = entry; uschar *last = entry; while (first > nametable) { if (strcmp(stringname, (char *)(first - entrysize + 2)) != 0) break; first -= entrysize; } while (last < lastentry) { if (strcmp(stringname, (char *)(last + entrysize + 2)) != 0) break; last += entrysize; } *firstptr = (char *)first; *lastptr = (char *)last; return entrysize; } if (c > 0) bot = mid + 1; else top = mid; } return PCRE_ERROR_NOSUBSTRING; } /************************************************* * Find first set of multiple named strings * *************************************************/ /* This function allows for duplicate names in the table of named substrings. It returns the number of the first one that was set in a pattern match. Arguments: code the compiled regex stringname the name of the capturing substring ovector the vector of matched substrings Returns: the number of the first that is set, or the number of the last one if none are set, or a negative number on error */ static int get_first_set(const pcre *code, const char *stringname, int *ovector) { const real_pcre *re = (const real_pcre *)code; int entrysize; char *first, *last; uschar *entry; if ((re->options & (PCRE_DUPNAMES | PCRE_JCHANGED)) == 0) return pcre_get_stringnumber(code, stringname); entrysize = pcre_get_stringtable_entries(code, stringname, &first, &last); if (entrysize <= 0) return entrysize; for (entry = (uschar *)first; entry <= (uschar *)last; entry += entrysize) { int n = (entry[0] << 8) + entry[1]; if (ovector[n*2] >= 0) return n; } return (first[0] << 8) + first[1]; } /************************************************* * Copy captured string to given buffer * *************************************************/ /* This function copies a single captured substring into a given buffer. Note that we use memcpy() rather than strncpy() in case there are binary zeros in the string. Arguments: subject the subject string that was matched ovector pointer to the offsets table stringcount the number of substrings that were captured (i.e. the yield of the pcre_exec call, unless that was zero, in which case it should be 1/3 of the offset table size) stringnumber the number of the required substring buffer where to put the substring size the size of the buffer Returns: if successful: the length of the copied string, not including the zero that is put on the end; can be zero if not successful: PCRE_ERROR_NOMEMORY (-6) buffer too small PCRE_ERROR_NOSUBSTRING (-7) no such captured substring */ int pcre_copy_substring(const char *subject, int *ovector, int stringcount, int stringnumber, char *buffer, int size) { int yield; if (stringnumber < 0 || stringnumber >= stringcount) return PCRE_ERROR_NOSUBSTRING; stringnumber *= 2; yield = ovector[stringnumber+1] - ovector[stringnumber]; if (size < yield + 1) return PCRE_ERROR_NOMEMORY; memcpy(buffer, subject + ovector[stringnumber], yield); buffer[yield] = 0; return yield; } /************************************************* * Copy named captured string to given buffer * *************************************************/ /* This function copies a single captured substring into a given buffer, identifying it by name. If the regex permits duplicate names, the first substring that is set is chosen. Arguments: code the compiled regex subject the subject string that was matched ovector pointer to the offsets table stringcount the number of substrings that were captured (i.e. the yield of the pcre_exec call, unless that was zero, in which case it should be 1/3 of the offset table size) stringname the name of the required substring buffer where to put the substring size the size of the buffer Returns: if successful: the length of the copied string, not including the zero that is put on the end; can be zero if not successful: PCRE_ERROR_NOMEMORY (-6) buffer too small PCRE_ERROR_NOSUBSTRING (-7) no such captured substring */ int pcre_copy_named_substring(const pcre *code, const char *subject, int *ovector, int stringcount, const char *stringname, char *buffer, int size) { int n = get_first_set(code, stringname, ovector); if (n <= 0) return n; return pcre_copy_substring(subject, ovector, stringcount, n, buffer, size); } /************************************************* * Copy all captured strings to new store * *************************************************/ /* This function gets one chunk of store and builds a list of pointers and all of the captured substrings in it. A NULL pointer is put on the end of the list. Arguments: subject the subject string that was matched ovector pointer to the offsets table stringcount the number of substrings that were captured (i.e. the yield of the pcre_exec call, unless that was zero, in which case it should be 1/3 of the offset table size) listptr set to point to the list of pointers Returns: if successful: 0 if not successful: PCRE_ERROR_NOMEMORY (-6) failed to get store */ int pcre_get_substring_list(const char *subject, int *ovector, int stringcount, const char ***listptr) { int i; int size = sizeof(char *); int double_count = stringcount * 2; char **stringlist; char *p; for (i = 0; i < double_count; i += 2) size += sizeof(char *) + ovector[i+1] - ovector[i] + 1; stringlist = (char **)(pcre_malloc)(size); if (stringlist == NULL) return PCRE_ERROR_NOMEMORY; *listptr = (const char **)stringlist; p = (char *)(stringlist + stringcount + 1); for (i = 0; i < double_count; i += 2) { int len = ovector[i+1] - ovector[i]; memcpy(p, subject + ovector[i], len); *stringlist++ = p; p += len; *p++ = 0; } *stringlist = NULL; return 0; } /************************************************* * Free store obtained by get_substring_list * *************************************************/ /* This function exists for the benefit of people calling PCRE from non-C programs that can call its functions, but not free() or (pcre_free)() directly. Argument: the result of a previous pcre_get_substring_list() Returns: nothing */ void pcre_free_substring_list(const char **pointer) { (pcre_free)((void *)pointer); } /************************************************* * Copy captured string to new store * *************************************************/ /* This function copies a single captured substring into a piece of new store Arguments: subject the subject string that was matched ovector pointer to the offsets table stringcount the number of substrings that were captured (i.e. the yield of the pcre_exec call, unless that was zero, in which case it should be 1/3 of the offset table size) stringnumber the number of the required substring stringptr where to put a pointer to the substring Returns: if successful: the length of the string, not including the zero that is put on the end; can be zero if not successful: PCRE_ERROR_NOMEMORY (-6) failed to get store PCRE_ERROR_NOSUBSTRING (-7) substring not present */ int pcre_get_substring(const char *subject, int *ovector, int stringcount, int stringnumber, const char **stringptr) { int yield; char *substring; if (stringnumber < 0 || stringnumber >= stringcount) return PCRE_ERROR_NOSUBSTRING; stringnumber *= 2; yield = ovector[stringnumber+1] - ovector[stringnumber]; substring = (char *)(pcre_malloc)(yield + 1); if (substring == NULL) return PCRE_ERROR_NOMEMORY; memcpy(substring, subject + ovector[stringnumber], yield); substring[yield] = 0; *stringptr = substring; return yield; } /************************************************* * Copy named captured string to new store * *************************************************/ /* This function copies a single captured substring, identified by name, into new store. If the regex permits duplicate names, the first substring that is set is chosen. Arguments: code the compiled regex subject the subject string that was matched ovector pointer to the offsets table stringcount the number of substrings that were captured (i.e. the yield of the pcre_exec call, unless that was zero, in which case it should be 1/3 of the offset table size) stringname the name of the required substring stringptr where to put the pointer Returns: if successful: the length of the copied string, not including the zero that is put on the end; can be zero if not successful: PCRE_ERROR_NOMEMORY (-6) couldn't get memory PCRE_ERROR_NOSUBSTRING (-7) no such captured substring */ int pcre_get_named_substring(const pcre *code, const char *subject, int *ovector, int stringcount, const char *stringname, const char **stringptr) { int n = get_first_set(code, stringname, ovector); if (n <= 0) return n; return pcre_get_substring(subject, ovector, stringcount, n, stringptr); } /************************************************* * Free store obtained by get_substring * *************************************************/ /* This function exists for the benefit of people calling PCRE from non-C programs that can call its functions, but not free() or (pcre_free)() directly. Argument: the result of a previous pcre_get_substring() Returns: nothing */ void pcre_free_substring(const char *pointer) { (pcre_free)((void *)pointer); } /* End of pcre_get.c */ libsynthesis-3.4.0.47.1/src/pcre/pcre_globals.c000066400000000000000000000056421226375725500211730ustar00rootroot00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2007 University of Cambridge ----------------------------------------------------------------------------- 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 name of the University of Cambridge 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. ----------------------------------------------------------------------------- */ /* This module contains global variables that are exported by the PCRE library. PCRE is thread-clean and doesn't use any global variables in the normal sense. However, it calls memory allocation and freeing functions via the four indirections below, and it can optionally do callouts, using the fifth indirection. These values can be changed by the caller, but are shared between all threads. However, when compiling for Virtual Pascal, things are done differently, and global variables are not used (see pcre.in). */ #include "pcre_setup.h" #include "pcre_internal.h" #ifndef VPCOMPAT PCRE_EXP_DATA_DEFN void *(*pcre_malloc)(size_t) = malloc; PCRE_EXP_DATA_DEFN void (*pcre_free)(void *) = free; PCRE_EXP_DATA_DEFN void *(*pcre_stack_malloc)(size_t) = malloc; PCRE_EXP_DATA_DEFN void (*pcre_stack_free)(void *) = free; PCRE_EXP_DATA_DEFN int (*pcre_callout)(pcre_callout_block *) = NULL; #endif /* End of pcre_globals.c */ libsynthesis-3.4.0.47.1/src/pcre/pcre_info.c000066400000000000000000000074341226375725500205040ustar00rootroot00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2007 University of Cambridge ----------------------------------------------------------------------------- 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 name of the University of Cambridge 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. ----------------------------------------------------------------------------- */ /* This module contains the external function pcre_info(), which gives some information about a compiled pattern. However, use of this function is now deprecated, as it has been superseded by pcre_fullinfo(). */ #include "pcre_setup.h" #include "pcre_internal.h" /************************************************* * (Obsolete) Return info about compiled pattern * *************************************************/ /* This is the original "info" function. It picks potentially useful data out of the private structure, but its interface was too rigid. It remains for backwards compatibility. The public options are passed back in an int - though the re->options field has been expanded to a long int, all the public options at the low end of it, and so even on 16-bit systems this will still be OK. Therefore, I haven't changed the API for pcre_info(). Arguments: argument_re points to compiled code optptr where to pass back the options first_byte where to pass back the first character, or -1 if multiline and all branches start ^, or -2 otherwise Returns: number of capturing subpatterns or negative values on error */ PCRE_EXP_DEFN int pcre_info(const pcre *argument_re, int *optptr, int *first_byte) { real_pcre internal_re; const real_pcre *re = (const real_pcre *)argument_re; if (re == NULL) return PCRE_ERROR_NULL; if (re->magic_number != MAGIC_NUMBER) { re = _pcre_try_flipped(re, &internal_re, NULL, NULL); if (re == NULL) return PCRE_ERROR_BADMAGIC; } if (optptr != NULL) *optptr = (int)(re->options & PUBLIC_OPTIONS); if (first_byte != NULL) *first_byte = ((re->options & PCRE_FIRSTSET) != 0)? re->first_byte : ((re->options & PCRE_STARTLINE) != 0)? -1 : -2; return re->top_bracket; } /* End of pcre_info.c */ libsynthesis-3.4.0.47.1/src/pcre/pcre_internal.h000066400000000000000000001310771226375725500213730ustar00rootroot00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2007 University of Cambridge ----------------------------------------------------------------------------- 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 name of the University of Cambridge 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. ----------------------------------------------------------------------------- */ /* This header contains definitions that are shared between the different modules, but which are not relevant to the exported API. This includes some functions whose names all begin with "_pcre_". */ #ifndef PCRE_INTERNAL_H #define PCRE_INTERNAL_H /* Define DEBUG to get debugging output on stdout. */ #if 0 #define DEBUG #endif /* Use a macro for debugging printing, 'cause that eliminates the use of #ifdef inline, and there are *still* stupid compilers about that don't like indented pre-processor statements, or at least there were when I first wrote this. After all, it had only been about 10 years then... It turns out that the Mac Debugging.h header also defines the macro DPRINTF, so be absolutely sure we get our version. */ #undef DPRINTF #ifdef DEBUG #define DPRINTF(p) printf p #else #define DPRINTF(p) /* Nothing */ #endif /* Standard C headers plus the external interface definition. The only time setjmp and stdarg are used is when NO_RECURSE is set. */ #include #include #include #include #include #include #include #include /* When compiling a DLL for Windows, the exported symbols have to be declared using some MS magic. I found some useful information on this web page: http://msdn2.microsoft.com/en-us/library/y4h7bcy6(VS.80).aspx. According to the information there, using __declspec(dllexport) without "extern" we have a definition; with "extern" we have a declaration. The settings here override the setting in pcre.h (which is included below); it defines only PCRE_EXP_DECL, which is all that is needed for applications (they just import the symbols). We use: PCRE_EXP_DECL for declarations PCRE_EXP_DEFN for definitions of exported functions PCRE_EXP_DATA_DEFN for definitions of exported variables The reason for the two DEFN macros is that in non-Windows environments, one does not want to have "extern" before variable definitions because it leads to compiler warnings. So we distinguish between functions and variables. In Windows, the two should always be the same. The reason for wrapping this in #ifndef PCRE_EXP_DECL is so that pcretest, which is an application, but needs to import this file in order to "peek" at internals, can #include pcre.h first to get an application's-eye view. In principle, people compiling for non-Windows, non-Unix-like (i.e. uncommon, special-purpose environments) might want to stick other stuff in front of exported symbols. That's why, in the non-Windows case, we set PCRE_EXP_DEFN and PCRE_EXP_DATA_DEFN only if they are not already set. */ #ifndef PCRE_EXP_DECL # ifdef _WIN32 # ifndef PCRE_STATIC # define PCRE_EXP_DECL extern __declspec(dllexport) # define PCRE_EXP_DEFN __declspec(dllexport) # define PCRE_EXP_DATA_DEFN __declspec(dllexport) # else # define PCRE_EXP_DECL extern # define PCRE_EXP_DEFN # define PCRE_EXP_DATA_DEFN # endif # else # ifdef __cplusplus # define PCRE_EXP_DECL extern "C" # else # define PCRE_EXP_DECL extern # endif # ifndef PCRE_EXP_DEFN # define PCRE_EXP_DEFN PCRE_EXP_DECL # endif # ifndef PCRE_EXP_DATA_DEFN # define PCRE_EXP_DATA_DEFN # endif # endif #endif /* We need to have types that specify unsigned 16-bit and 32-bit integers. We cannot determine these outside the compilation (e.g. by running a program as part of "configure") because PCRE is often cross-compiled for use on other systems. Instead we make use of the maximum sizes that are available at preprocessor time in standard C environments. */ #if USHRT_MAX == 65535 typedef unsigned short pcre_uint16; #elif UINT_MAX == 65535 typedef unsigned int pcre_uint16; #else #error Cannot determine a type for 16-bit unsigned integers #endif #if UINT_MAX == 4294967295 typedef unsigned int pcre_uint32; #elif ULONG_MAX == 4294967295 typedef unsigned long int pcre_uint32; #else #error Cannot determine a type for 32-bit unsigned integers #endif /* All character handling must be done as unsigned characters. Otherwise there are problems with top-bit-set characters and functions such as isspace(). However, we leave the interface to the outside world as char *, because that should make things easier for callers. We define a short type for unsigned char to save lots of typing. I tried "uchar", but it causes problems on Digital Unix, where it is defined in sys/types, so use "uschar" instead. */ typedef unsigned char uschar; /* This is an unsigned int value that no character can ever have. UTF-8 characters only go up to 0x7fffffff (though Unicode doesn't go beyond 0x0010ffff). */ #define NOTACHAR 0xffffffff /* PCRE is able to support several different kinds of newline (CR, LF, CRLF, "any" and "anycrlf" at present). The following macros are used to package up testing for newlines. NLBLOCK, PSSTART, and PSEND are defined in the various modules to indicate in which datablock the parameters exist, and what the start/end of string field names are. */ #define NLTYPE_FIXED 0 /* Newline is a fixed length string */ #define NLTYPE_ANY 1 /* Newline is any Unicode line ending */ #define NLTYPE_ANYCRLF 2 /* Newline is CR, LF, or CRLF */ /* This macro checks for a newline at the given position */ #define IS_NEWLINE(p) \ ((NLBLOCK->nltype != NLTYPE_FIXED)? \ ((p) < NLBLOCK->PSEND && \ _pcre_is_newline((p), NLBLOCK->nltype, NLBLOCK->PSEND, &(NLBLOCK->nllen),\ utf8)) \ : \ ((p) <= NLBLOCK->PSEND - NLBLOCK->nllen && \ (p)[0] == NLBLOCK->nl[0] && \ (NLBLOCK->nllen == 1 || (p)[1] == NLBLOCK->nl[1]) \ ) \ ) /* This macro checks for a newline immediately preceding the given position */ #define WAS_NEWLINE(p) \ ((NLBLOCK->nltype != NLTYPE_FIXED)? \ ((p) > NLBLOCK->PSSTART && \ _pcre_was_newline((p), NLBLOCK->nltype, NLBLOCK->PSSTART, \ &(NLBLOCK->nllen), utf8)) \ : \ ((p) >= NLBLOCK->PSSTART + NLBLOCK->nllen && \ (p)[-NLBLOCK->nllen] == NLBLOCK->nl[0] && \ (NLBLOCK->nllen == 1 || (p)[-NLBLOCK->nllen+1] == NLBLOCK->nl[1]) \ ) \ ) /* When PCRE is compiled as a C++ library, the subject pointer can be replaced with a custom type. This makes it possible, for example, to allow pcre_exec() to process subject strings that are discontinuous by using a smart pointer class. It must always be possible to inspect all of the subject string in pcre_exec() because of the way it backtracks. Two macros are required in the normal case, for sign-unspecified and unsigned char pointers. The former is used for the external interface and appears in pcre.h, which is why its name must begin with PCRE_. */ #ifdef CUSTOM_SUBJECT_PTR #define PCRE_SPTR CUSTOM_SUBJECT_PTR #define USPTR CUSTOM_SUBJECT_PTR #else #define PCRE_SPTR const char * #define USPTR const unsigned char * #endif /* Include the public PCRE header and the definitions of UCP character property values. */ #include "pcre.h" #include "ucp.h" /* When compiling for use with the Virtual Pascal compiler, these functions need to have their names changed. PCRE must be compiled with the -DVPCOMPAT option on the command line. */ #ifdef VPCOMPAT #define strlen(s) _strlen(s) #define strncmp(s1,s2,m) _strncmp(s1,s2,m) #define memcmp(s,c,n) _memcmp(s,c,n) #define memcpy(d,s,n) _memcpy(d,s,n) #define memmove(d,s,n) _memmove(d,s,n) #define memset(s,c,n) _memset(s,c,n) #else /* VPCOMPAT */ /* To cope with SunOS4 and other systems that lack memmove() but have bcopy(), define a macro for memmove() if HAVE_MEMMOVE is false, provided that HAVE_BCOPY is set. Otherwise, include an emulating function for those systems that have neither (there some non-Unix environments where this is the case). */ #ifndef HAVE_MEMMOVE #undef memmove /* some systems may have a macro */ #ifdef HAVE_BCOPY #define memmove(a, b, c) bcopy(b, a, c) #else /* HAVE_BCOPY */ static void * pcre_memmove(void *d, const void *s, size_t n) { size_t i; unsigned char *dest = (unsigned char *)d; const unsigned char *src = (const unsigned char *)s; if (dest > src) { dest += n; src += n; for (i = 0; i < n; ++i) *(--dest) = *(--src); return (void *)dest; } else { for (i = 0; i < n; ++i) *dest++ = *src++; return (void *)(dest - n); } } #define memmove(a, b, c) pcre_memmove(a, b, c) #endif /* not HAVE_BCOPY */ #endif /* not HAVE_MEMMOVE */ #endif /* not VPCOMPAT */ /* PCRE keeps offsets in its compiled code as 2-byte quantities (always stored in big-endian order) by default. These are used, for example, to link from the start of a subpattern to its alternatives and its end. The use of 2 bytes per offset limits the size of the compiled regex to around 64K, which is big enough for almost everybody. However, I received a request for an even bigger limit. For this reason, and also to make the code easier to maintain, the storing and loading of offsets from the byte string is now handled by the macros that are defined here. The macros are controlled by the value of LINK_SIZE. This defaults to 2 in the config.h file, but can be overridden by using -D on the command line. This is automated on Unix systems via the "configure" command. */ #if LINK_SIZE == 2 #define PUT(a,n,d) \ (a[n] = (d) >> 8), \ (a[(n)+1] = (d) & 255) #define GET(a,n) \ (((a)[n] << 8) | (a)[(n)+1]) #define MAX_PATTERN_SIZE (1 << 16) #elif LINK_SIZE == 3 #define PUT(a,n,d) \ (a[n] = (d) >> 16), \ (a[(n)+1] = (d) >> 8), \ (a[(n)+2] = (d) & 255) #define GET(a,n) \ (((a)[n] << 16) | ((a)[(n)+1] << 8) | (a)[(n)+2]) #define MAX_PATTERN_SIZE (1 << 24) #elif LINK_SIZE == 4 #define PUT(a,n,d) \ (a[n] = (d) >> 24), \ (a[(n)+1] = (d) >> 16), \ (a[(n)+2] = (d) >> 8), \ (a[(n)+3] = (d) & 255) #define GET(a,n) \ (((a)[n] << 24) | ((a)[(n)+1] << 16) | ((a)[(n)+2] << 8) | (a)[(n)+3]) #define MAX_PATTERN_SIZE (1 << 30) /* Keep it positive */ #else #error LINK_SIZE must be either 2, 3, or 4 #endif /* Convenience macro defined in terms of the others */ #define PUTINC(a,n,d) PUT(a,n,d), a += LINK_SIZE /* PCRE uses some other 2-byte quantities that do not change when the size of offsets changes. There are used for repeat counts and for other things such as capturing parenthesis numbers in back references. */ #define PUT2(a,n,d) \ a[n] = (d) >> 8; \ a[(n)+1] = (d) & 255 #define GET2(a,n) \ (((a)[n] << 8) | (a)[(n)+1]) #define PUT2INC(a,n,d) PUT2(a,n,d), a += 2 /* When UTF-8 encoding is being used, a character is no longer just a single byte. The macros for character handling generate simple sequences when used in byte-mode, and more complicated ones for UTF-8 characters. BACKCHAR should never be called in byte mode. To make sure it can never even appear when UTF-8 support is omitted, we don't even define it. */ #ifndef SUPPORT_UTF8 #define GETCHAR(c, eptr) c = *eptr; #define GETCHARTEST(c, eptr) c = *eptr; #define GETCHARINC(c, eptr) c = *eptr++; #define GETCHARINCTEST(c, eptr) c = *eptr++; #define GETCHARLEN(c, eptr, len) c = *eptr; /* #define BACKCHAR(eptr) */ #else /* SUPPORT_UTF8 */ /* Get the next UTF-8 character, not advancing the pointer. This is called when we know we are in UTF-8 mode. */ #define GETCHAR(c, eptr) \ c = *eptr; \ if (c >= 0xc0) \ { \ int gcii; \ int gcaa = _pcre_utf8_table4[c & 0x3f]; /* Number of additional bytes */ \ int gcss = 6*gcaa; \ c = (c & _pcre_utf8_table3[gcaa]) << gcss; \ for (gcii = 1; gcii <= gcaa; gcii++) \ { \ gcss -= 6; \ c |= (eptr[gcii] & 0x3f) << gcss; \ } \ } /* Get the next UTF-8 character, testing for UTF-8 mode, and not advancing the pointer. */ #define GETCHARTEST(c, eptr) \ c = *eptr; \ if (utf8 && c >= 0xc0) \ { \ int gcii; \ int gcaa = _pcre_utf8_table4[c & 0x3f]; /* Number of additional bytes */ \ int gcss = 6*gcaa; \ c = (c & _pcre_utf8_table3[gcaa]) << gcss; \ for (gcii = 1; gcii <= gcaa; gcii++) \ { \ gcss -= 6; \ c |= (eptr[gcii] & 0x3f) << gcss; \ } \ } /* Get the next UTF-8 character, advancing the pointer. This is called when we know we are in UTF-8 mode. */ #define GETCHARINC(c, eptr) \ c = *eptr++; \ if (c >= 0xc0) \ { \ int gcaa = _pcre_utf8_table4[c & 0x3f]; /* Number of additional bytes */ \ int gcss = 6*gcaa; \ c = (c & _pcre_utf8_table3[gcaa]) << gcss; \ while (gcaa-- > 0) \ { \ gcss -= 6; \ c |= (*eptr++ & 0x3f) << gcss; \ } \ } /* Get the next character, testing for UTF-8 mode, and advancing the pointer */ #define GETCHARINCTEST(c, eptr) \ c = *eptr++; \ if (utf8 && c >= 0xc0) \ { \ int gcaa = _pcre_utf8_table4[c & 0x3f]; /* Number of additional bytes */ \ int gcss = 6*gcaa; \ c = (c & _pcre_utf8_table3[gcaa]) << gcss; \ while (gcaa-- > 0) \ { \ gcss -= 6; \ c |= (*eptr++ & 0x3f) << gcss; \ } \ } /* Get the next UTF-8 character, not advancing the pointer, incrementing length if there are extra bytes. This is called when we know we are in UTF-8 mode. */ #define GETCHARLEN(c, eptr, len) \ c = *eptr; \ if (c >= 0xc0) \ { \ int gcii; \ int gcaa = _pcre_utf8_table4[c & 0x3f]; /* Number of additional bytes */ \ int gcss = 6*gcaa; \ c = (c & _pcre_utf8_table3[gcaa]) << gcss; \ for (gcii = 1; gcii <= gcaa; gcii++) \ { \ gcss -= 6; \ c |= (eptr[gcii] & 0x3f) << gcss; \ } \ len += gcaa; \ } /* If the pointer is not at the start of a character, move it back until it is. This is called only in UTF-8 mode - we don't put a test within the macro because almost all calls are already within a block of UTF-8 only code. */ #define BACKCHAR(eptr) while((*eptr & 0xc0) == 0x80) eptr-- #endif /* In case there is no definition of offsetof() provided - though any proper Standard C system should have one. */ #ifndef offsetof #define offsetof(p_type,field) ((size_t)&(((p_type *)0)->field)) #endif /* These are the public options that can change during matching. */ #define PCRE_IMS (PCRE_CASELESS|PCRE_MULTILINE|PCRE_DOTALL) /* Private options flags start at the most significant end of the four bytes. The public options defined in pcre.h start at the least significant end. Make sure they don't overlap! The bits are getting a bit scarce now -- when we run out, there is a dummy word in the structure that could be used for the private bits. */ #define PCRE_NOPARTIAL 0x80000000 /* can't use partial with this regex */ #define PCRE_FIRSTSET 0x40000000 /* first_byte is set */ #define PCRE_REQCHSET 0x20000000 /* req_byte is set */ #define PCRE_STARTLINE 0x10000000 /* start after \n for multiline */ #define PCRE_JCHANGED 0x08000000 /* j option changes within regex */ #define PCRE_HASCRORLF 0x04000000 /* explicit \r or \n in pattern */ /* Options for the "extra" block produced by pcre_study(). */ #define PCRE_STUDY_MAPPED 0x01 /* a map of starting chars exists */ /* Masks for identifying the public options that are permitted at compile time, run time, or study time, respectively. */ #define PCRE_NEWLINE_BITS (PCRE_NEWLINE_CR|PCRE_NEWLINE_LF|PCRE_NEWLINE_ANY| \ PCRE_NEWLINE_ANYCRLF) #define PUBLIC_OPTIONS \ (PCRE_CASELESS|PCRE_EXTENDED|PCRE_ANCHORED|PCRE_MULTILINE| \ PCRE_DOTALL|PCRE_DOLLAR_ENDONLY|PCRE_EXTRA|PCRE_UNGREEDY|PCRE_UTF8| \ PCRE_NO_AUTO_CAPTURE|PCRE_NO_UTF8_CHECK|PCRE_AUTO_CALLOUT|PCRE_FIRSTLINE| \ PCRE_DUPNAMES|PCRE_NEWLINE_BITS) #define PUBLIC_EXEC_OPTIONS \ (PCRE_ANCHORED|PCRE_NOTBOL|PCRE_NOTEOL|PCRE_NOTEMPTY|PCRE_NO_UTF8_CHECK| \ PCRE_PARTIAL|PCRE_NEWLINE_BITS) #define PUBLIC_DFA_EXEC_OPTIONS \ (PCRE_ANCHORED|PCRE_NOTBOL|PCRE_NOTEOL|PCRE_NOTEMPTY|PCRE_NO_UTF8_CHECK| \ PCRE_PARTIAL|PCRE_DFA_SHORTEST|PCRE_DFA_RESTART|PCRE_NEWLINE_BITS) #define PUBLIC_STUDY_OPTIONS 0 /* None defined */ /* Magic number to provide a small check against being handed junk. Also used to detect whether a pattern was compiled on a host of different endianness. */ #define MAGIC_NUMBER 0x50435245UL /* 'PCRE' */ /* Negative values for the firstchar and reqchar variables */ #define REQ_UNSET (-2) #define REQ_NONE (-1) /* The maximum remaining length of subject we are prepared to search for a req_byte match. */ #define REQ_BYTE_MAX 1000 /* Flags added to firstbyte or reqbyte; a "non-literal" item is either a variable-length repeat, or a anything other than literal characters. */ #define REQ_CASELESS 0x0100 /* indicates caselessness */ #define REQ_VARY 0x0200 /* reqbyte followed non-literal item */ /* Miscellaneous definitions */ typedef int BOOL; #define FALSE 0 #define TRUE 1 /* Escape items that are just an encoding of a particular data value. */ #ifndef ESC_e #define ESC_e 27 #endif #ifndef ESC_f #define ESC_f '\f' #endif #ifndef ESC_n #define ESC_n '\n' #endif #ifndef ESC_r #define ESC_r '\r' #endif /* We can't officially use ESC_t because it is a POSIX reserved identifier (presumably because of all the others like size_t). */ #ifndef ESC_tee #define ESC_tee '\t' #endif /* Codes for different types of Unicode property */ #define PT_ANY 0 /* Any property - matches all chars */ #define PT_LAMP 1 /* L& - the union of Lu, Ll, Lt */ #define PT_GC 2 /* General characteristic (e.g. L) */ #define PT_PC 3 /* Particular characteristic (e.g. Lu) */ #define PT_SC 4 /* Script (e.g. Han) */ /* Flag bits and data types for the extended class (OP_XCLASS) for classes that contain UTF-8 characters with values greater than 255. */ #define XCL_NOT 0x01 /* Flag: this is a negative class */ #define XCL_MAP 0x02 /* Flag: a 32-byte map is present */ #define XCL_END 0 /* Marks end of individual items */ #define XCL_SINGLE 1 /* Single item (one multibyte char) follows */ #define XCL_RANGE 2 /* A range (two multibyte chars) follows */ #define XCL_PROP 3 /* Unicode property (2-byte property code follows) */ #define XCL_NOTPROP 4 /* Unicode inverted property (ditto) */ /* These are escaped items that aren't just an encoding of a particular data value such as \n. They must have non-zero values, as check_escape() returns their negation. Also, they must appear in the same order as in the opcode definitions below, up to ESC_z. There's a dummy for OP_ANY because it corresponds to "." rather than an escape sequence. The final one must be ESC_REF as subsequent values are used for backreferences (\1, \2, \3, etc). There are two tests in the code for an escape greater than ESC_b and less than ESC_Z to detect the types that may be repeated. These are the types that consume characters. If any new escapes are put in between that don't consume a character, that code will have to change. */ enum { ESC_A = 1, ESC_G, ESC_K, ESC_B, ESC_b, ESC_D, ESC_d, ESC_S, ESC_s, ESC_W, ESC_w, ESC_dum1, ESC_C, ESC_P, ESC_p, ESC_R, ESC_H, ESC_h, ESC_V, ESC_v, ESC_X, ESC_Z, ESC_z, ESC_E, ESC_Q, ESC_k, ESC_REF }; /* Opcode table: Starting from 1 (i.e. after OP_END), the values up to OP_EOD must correspond in order to the list of escapes immediately above. *** NOTE NOTE NOTE *** Whenever this list is updated, the two macro definitions that follow must also be updated to match. There is also a table called "coptable" in pcre_dfa_exec.c that must be updated. */ enum { OP_END, /* 0 End of pattern */ /* Values corresponding to backslashed metacharacters */ OP_SOD, /* 1 Start of data: \A */ OP_SOM, /* 2 Start of match (subject + offset): \G */ OP_SET_SOM, /* 3 Set start of match (\K) */ OP_NOT_WORD_BOUNDARY, /* 4 \B */ OP_WORD_BOUNDARY, /* 5 \b */ OP_NOT_DIGIT, /* 6 \D */ OP_DIGIT, /* 7 \d */ OP_NOT_WHITESPACE, /* 8 \S */ OP_WHITESPACE, /* 9 \s */ OP_NOT_WORDCHAR, /* 10 \W */ OP_WORDCHAR, /* 11 \w */ OP_ANY, /* 12 Match any character */ OP_ANYBYTE, /* 13 Match any byte (\C); different to OP_ANY for UTF-8 */ OP_NOTPROP, /* 14 \P (not Unicode property) */ OP_PROP, /* 15 \p (Unicode property) */ OP_ANYNL, /* 16 \R (any newline sequence) */ OP_NOT_HSPACE, /* 17 \H (not horizontal whitespace) */ OP_HSPACE, /* 18 \h (horizontal whitespace) */ OP_NOT_VSPACE, /* 19 \V (not vertical whitespace) */ OP_VSPACE, /* 20 \v (vertical whitespace) */ OP_EXTUNI, /* 21 \X (extended Unicode sequence */ OP_EODN, /* 22 End of data or \n at end of data: \Z. */ OP_EOD, /* 23 End of data: \z */ OP_OPT, /* 24 Set runtime options */ OP_CIRC, /* 25 Start of line - varies with multiline switch */ OP_DOLL, /* 26 End of line - varies with multiline switch */ OP_CHAR, /* 27 Match one character, casefully */ OP_CHARNC, /* 28 Match one character, caselessly */ OP_NOT, /* 29 Match one character, not the following one */ OP_STAR, /* 30 The maximizing and minimizing versions of */ OP_MINSTAR, /* 31 these six opcodes must come in pairs, with */ OP_PLUS, /* 32 the minimizing one second. */ OP_MINPLUS, /* 33 This first set applies to single characters.*/ OP_QUERY, /* 34 */ OP_MINQUERY, /* 35 */ OP_UPTO, /* 36 From 0 to n matches */ OP_MINUPTO, /* 37 */ OP_EXACT, /* 38 Exactly n matches */ OP_POSSTAR, /* 39 Possessified star */ OP_POSPLUS, /* 40 Possessified plus */ OP_POSQUERY, /* 41 Posesssified query */ OP_POSUPTO, /* 42 Possessified upto */ OP_NOTSTAR, /* 43 The maximizing and minimizing versions of */ OP_NOTMINSTAR, /* 44 these six opcodes must come in pairs, with */ OP_NOTPLUS, /* 45 the minimizing one second. They must be in */ OP_NOTMINPLUS, /* 46 exactly the same order as those above. */ OP_NOTQUERY, /* 47 This set applies to "not" single characters. */ OP_NOTMINQUERY, /* 48 */ OP_NOTUPTO, /* 49 From 0 to n matches */ OP_NOTMINUPTO, /* 50 */ OP_NOTEXACT, /* 51 Exactly n matches */ OP_NOTPOSSTAR, /* 52 Possessified versions */ OP_NOTPOSPLUS, /* 53 */ OP_NOTPOSQUERY, /* 54 */ OP_NOTPOSUPTO, /* 55 */ OP_TYPESTAR, /* 56 The maximizing and minimizing versions of */ OP_TYPEMINSTAR, /* 57 these six opcodes must come in pairs, with */ OP_TYPEPLUS, /* 58 the minimizing one second. These codes must */ OP_TYPEMINPLUS, /* 59 be in exactly the same order as those above. */ OP_TYPEQUERY, /* 60 This set applies to character types such as \d */ OP_TYPEMINQUERY, /* 61 */ OP_TYPEUPTO, /* 62 From 0 to n matches */ OP_TYPEMINUPTO, /* 63 */ OP_TYPEEXACT, /* 64 Exactly n matches */ OP_TYPEPOSSTAR, /* 65 Possessified versions */ OP_TYPEPOSPLUS, /* 66 */ OP_TYPEPOSQUERY, /* 67 */ OP_TYPEPOSUPTO, /* 68 */ OP_CRSTAR, /* 69 The maximizing and minimizing versions of */ OP_CRMINSTAR, /* 70 all these opcodes must come in pairs, with */ OP_CRPLUS, /* 71 the minimizing one second. These codes must */ OP_CRMINPLUS, /* 72 be in exactly the same order as those above. */ OP_CRQUERY, /* 73 These are for character classes and back refs */ OP_CRMINQUERY, /* 74 */ OP_CRRANGE, /* 75 These are different to the three sets above. */ OP_CRMINRANGE, /* 76 */ OP_CLASS, /* 77 Match a character class, chars < 256 only */ OP_NCLASS, /* 78 Same, but the bitmap was created from a negative class - the difference is relevant only when a UTF-8 character > 255 is encountered. */ OP_XCLASS, /* 79 Extended class for handling UTF-8 chars within the class. This does both positive and negative. */ OP_REF, /* 80 Match a back reference */ OP_RECURSE, /* 81 Match a numbered subpattern (possibly recursive) */ OP_CALLOUT, /* 82 Call out to external function if provided */ OP_ALT, /* 83 Start of alternation */ OP_KET, /* 84 End of group that doesn't have an unbounded repeat */ OP_KETRMAX, /* 85 These two must remain together and in this */ OP_KETRMIN, /* 86 order. They are for groups the repeat for ever. */ /* The assertions must come before BRA, CBRA, ONCE, and COND.*/ OP_ASSERT, /* 87 Positive lookahead */ OP_ASSERT_NOT, /* 88 Negative lookahead */ OP_ASSERTBACK, /* 89 Positive lookbehind */ OP_ASSERTBACK_NOT, /* 90 Negative lookbehind */ OP_REVERSE, /* 91 Move pointer back - used in lookbehind assertions */ /* ONCE, BRA, CBRA, and COND must come after the assertions, with ONCE first, as there's a test for >= ONCE for a subpattern that isn't an assertion. */ OP_ONCE, /* 92 Atomic group */ OP_BRA, /* 93 Start of non-capturing bracket */ OP_CBRA, /* 94 Start of capturing bracket */ OP_COND, /* 95 Conditional group */ /* These three must follow the previous three, in the same order. There's a check for >= SBRA to distinguish the two sets. */ OP_SBRA, /* 96 Start of non-capturing bracket, check empty */ OP_SCBRA, /* 97 Start of capturing bracket, check empty */ OP_SCOND, /* 98 Conditional group, check empty */ OP_CREF, /* 99 Used to hold a capture number as condition */ OP_RREF, /* 100 Used to hold a recursion number as condition */ OP_DEF, /* 101 The DEFINE condition */ OP_BRAZERO, /* 102 These two must remain together and in this */ OP_BRAMINZERO, /* 103 order. */ /* These are backtracking control verbs */ OP_PRUNE, /* 104 */ OP_SKIP, /* 105 */ OP_THEN, /* 106 */ OP_COMMIT, /* 107 */ /* These are forced failure and success verbs */ OP_FAIL, /* 108 */ OP_ACCEPT /* 109 */ }; /* This macro defines textual names for all the opcodes. These are used only for debugging. The macro is referenced only in pcre_printint.c. */ #define OP_NAME_LIST \ "End", "\\A", "\\G", "\\K", "\\B", "\\b", "\\D", "\\d", \ "\\S", "\\s", "\\W", "\\w", "Any", "Anybyte", \ "notprop", "prop", "\\R", "\\H", "\\h", "\\V", "\\v", \ "extuni", "\\Z", "\\z", \ "Opt", "^", "$", "char", "charnc", "not", \ "*", "*?", "+", "+?", "?", "??", "{", "{", "{", \ "*+","++", "?+", "{", \ "*", "*?", "+", "+?", "?", "??", "{", "{", "{", \ "*+","++", "?+", "{", \ "*", "*?", "+", "+?", "?", "??", "{", "{", "{", \ "*+","++", "?+", "{", \ "*", "*?", "+", "+?", "?", "??", "{", "{", \ "class", "nclass", "xclass", "Ref", "Recurse", "Callout", \ "Alt", "Ket", "KetRmax", "KetRmin", "Assert", "Assert not", \ "AssertB", "AssertB not", "Reverse", \ "Once", "Bra", "CBra", "Cond", "SBra", "SCBra", "SCond", \ "Cond ref", "Cond rec", "Cond def", "Brazero", "Braminzero", \ "*PRUNE", "*SKIP", "*THEN", "*COMMIT", "*FAIL", "*ACCEPT" /* This macro defines the length of fixed length operations in the compiled regex. The lengths are used when searching for specific things, and also in the debugging printing of a compiled regex. We use a macro so that it can be defined close to the definitions of the opcodes themselves. As things have been extended, some of these are no longer fixed lenths, but are minima instead. For example, the length of a single-character repeat may vary in UTF-8 mode. The code that uses this table must know about such things. */ #define OP_LENGTHS \ 1, /* End */ \ 1, 1, 1, 1, 1, /* \A, \G, \K, \B, \b */ \ 1, 1, 1, 1, 1, 1, /* \D, \d, \S, \s, \W, \w */ \ 1, 1, /* Any, Anybyte */ \ 3, 3, 1, /* NOTPROP, PROP, EXTUNI */ \ 1, 1, 1, 1, 1, /* \R, \H, \h, \V, \v */ \ 1, 1, 2, 1, 1, /* \Z, \z, Opt, ^, $ */ \ 2, /* Char - the minimum length */ \ 2, /* Charnc - the minimum length */ \ 2, /* not */ \ /* Positive single-char repeats ** These are */ \ 2, 2, 2, 2, 2, 2, /* *, *?, +, +?, ?, ?? ** minima in */ \ 4, 4, 4, /* upto, minupto, exact ** UTF-8 mode */ \ 2, 2, 2, 4, /* *+, ++, ?+, upto+ */ \ /* Negative single-char repeats - only for chars < 256 */ \ 2, 2, 2, 2, 2, 2, /* NOT *, *?, +, +?, ?, ?? */ \ 4, 4, 4, /* NOT upto, minupto, exact */ \ 2, 2, 2, 4, /* Possessive *, +, ?, upto */ \ /* Positive type repeats */ \ 2, 2, 2, 2, 2, 2, /* Type *, *?, +, +?, ?, ?? */ \ 4, 4, 4, /* Type upto, minupto, exact */ \ 2, 2, 2, 4, /* Possessive *+, ++, ?+, upto+ */ \ /* Character class & ref repeats */ \ 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */ \ 5, 5, /* CRRANGE, CRMINRANGE */ \ 33, /* CLASS */ \ 33, /* NCLASS */ \ 0, /* XCLASS - variable length */ \ 3, /* REF */ \ 1+LINK_SIZE, /* RECURSE */ \ 2+2*LINK_SIZE, /* CALLOUT */ \ 1+LINK_SIZE, /* Alt */ \ 1+LINK_SIZE, /* Ket */ \ 1+LINK_SIZE, /* KetRmax */ \ 1+LINK_SIZE, /* KetRmin */ \ 1+LINK_SIZE, /* Assert */ \ 1+LINK_SIZE, /* Assert not */ \ 1+LINK_SIZE, /* Assert behind */ \ 1+LINK_SIZE, /* Assert behind not */ \ 1+LINK_SIZE, /* Reverse */ \ 1+LINK_SIZE, /* ONCE */ \ 1+LINK_SIZE, /* BRA */ \ 3+LINK_SIZE, /* CBRA */ \ 1+LINK_SIZE, /* COND */ \ 1+LINK_SIZE, /* SBRA */ \ 3+LINK_SIZE, /* SCBRA */ \ 1+LINK_SIZE, /* SCOND */ \ 3, /* CREF */ \ 3, /* RREF */ \ 1, /* DEF */ \ 1, 1, /* BRAZERO, BRAMINZERO */ \ 1, 1, 1, 1, /* PRUNE, SKIP, THEN, COMMIT, */ \ 1, 1 /* FAIL, ACCEPT */ /* A magic value for OP_RREF to indicate the "any recursion" condition. */ #define RREF_ANY 0xffff /* Error code numbers. They are given names so that they can more easily be tracked. */ enum { ERR0, ERR1, ERR2, ERR3, ERR4, ERR5, ERR6, ERR7, ERR8, ERR9, ERR10, ERR11, ERR12, ERR13, ERR14, ERR15, ERR16, ERR17, ERR18, ERR19, ERR20, ERR21, ERR22, ERR23, ERR24, ERR25, ERR26, ERR27, ERR28, ERR29, ERR30, ERR31, ERR32, ERR33, ERR34, ERR35, ERR36, ERR37, ERR38, ERR39, ERR40, ERR41, ERR42, ERR43, ERR44, ERR45, ERR46, ERR47, ERR48, ERR49, ERR50, ERR51, ERR52, ERR53, ERR54, ERR55, ERR56, ERR57, ERR58, ERR59, ERR60, ERR61 }; /* The real format of the start of the pcre block; the index of names and the code vector run on as long as necessary after the end. We store an explicit offset to the name table so that if a regex is compiled on one host, saved, and then run on another where the size of pointers is different, all might still be well. For the case of compiled-on-4 and run-on-8, we include an extra pointer that is always NULL. For future-proofing, a few dummy fields were originally included - even though you can never get this planning right - but there is only one left now. NOTE NOTE NOTE: Because people can now save and re-use compiled patterns, any additions to this structure should be made at the end, and something earlier (e.g. a new flag in the options or one of the dummy fields) should indicate that the new fields are present. Currently PCRE always sets the dummy fields to zero. NOTE NOTE NOTE: */ typedef struct real_pcre { pcre_uint32 magic_number; pcre_uint32 size; /* Total that was malloced */ pcre_uint32 options; pcre_uint32 dummy1; /* For future use, maybe */ pcre_uint16 top_bracket; pcre_uint16 top_backref; pcre_uint16 first_byte; pcre_uint16 req_byte; pcre_uint16 name_table_offset; /* Offset to name table that follows */ pcre_uint16 name_entry_size; /* Size of any name items */ pcre_uint16 name_count; /* Number of name items */ pcre_uint16 ref_count; /* Reference count */ const unsigned char *tables; /* Pointer to tables or NULL for std */ const unsigned char *nullpad; /* NULL padding */ } real_pcre; /* The format of the block used to store data from pcre_study(). The same remark (see NOTE above) about extending this structure applies. */ typedef struct pcre_study_data { pcre_uint32 size; /* Total that was malloced */ pcre_uint32 options; uschar start_bits[32]; } pcre_study_data; /* Structure for passing "static" information around between the functions doing the compiling, so that they are thread-safe. */ typedef struct compile_data { const uschar *lcc; /* Points to lower casing table */ const uschar *fcc; /* Points to case-flipping table */ const uschar *cbits; /* Points to character type table */ const uschar *ctypes; /* Points to table of type maps */ const uschar *start_workspace;/* The start of working space */ const uschar *start_code; /* The start of the compiled code */ const uschar *start_pattern; /* The start of the pattern */ const uschar *end_pattern; /* The end of the pattern */ uschar *hwm; /* High watermark of workspace */ uschar *name_table; /* The name/number table */ int names_found; /* Number of entries so far */ int name_entry_size; /* Size of each entry */ int bracount; /* Count of capturing parens */ int top_backref; /* Maximum back reference */ unsigned int backref_map; /* Bitmap of low back refs */ int external_options; /* External (initial) options */ int req_varyopt; /* "After variable item" flag for reqbyte */ BOOL nopartial; /* Set TRUE if partial won't work */ BOOL had_accept; /* (*ACCEPT) encountered */ int nltype; /* Newline type */ int nllen; /* Newline string length */ uschar nl[4]; /* Newline string when fixed length */ } compile_data; /* Structure for maintaining a chain of pointers to the currently incomplete branches, for testing for left recursion. */ typedef struct branch_chain { struct branch_chain *outer; uschar *current; } branch_chain; /* Structure for items in a linked list that represents an explicit recursive call within the pattern. */ typedef struct recursion_info { struct recursion_info *prevrec; /* Previous recursion record (or NULL) */ int group_num; /* Number of group that was called */ const uschar *after_call; /* "Return value": points after the call in the expr */ USPTR save_start; /* Old value of mstart */ int *offset_save; /* Pointer to start of saved offsets */ int saved_max; /* Number of saved offsets */ } recursion_info; /* Structure for building a chain of data for holding the values of the subject pointer at the start of each subpattern, so as to detect when an empty string has been matched by a subpattern - to break infinite loops. */ typedef struct eptrblock { struct eptrblock *epb_prev; USPTR epb_saved_eptr; } eptrblock; /* Structure for passing "static" information around between the functions doing traditional NFA matching, so that they are thread-safe. */ typedef struct match_data { unsigned long int match_call_count; /* As it says */ unsigned long int match_limit; /* As it says */ unsigned long int match_limit_recursion; /* As it says */ int *offset_vector; /* Offset vector */ int offset_end; /* One past the end */ int offset_max; /* The maximum usable for return data */ int nltype; /* Newline type */ int nllen; /* Newline string length */ uschar nl[4]; /* Newline string when fixed */ const uschar *lcc; /* Points to lower casing table */ const uschar *ctypes; /* Points to table of type maps */ BOOL offset_overflow; /* Set if too many extractions */ BOOL notbol; /* NOTBOL flag */ BOOL noteol; /* NOTEOL flag */ BOOL utf8; /* UTF8 flag */ BOOL endonly; /* Dollar not before final \n */ BOOL notempty; /* Empty string match not wanted */ BOOL partial; /* PARTIAL flag */ BOOL hitend; /* Hit the end of the subject at some point */ const uschar *start_code; /* For use when recursing */ USPTR start_subject; /* Start of the subject string */ USPTR end_subject; /* End of the subject string */ USPTR start_match_ptr; /* Start of matched string */ USPTR end_match_ptr; /* Subject position at end match */ int end_offset_top; /* Highwater mark at end of match */ int capture_last; /* Most recent capture number */ int start_offset; /* The start offset value */ eptrblock *eptrchain; /* Chain of eptrblocks for tail recursions */ int eptrn; /* Next free eptrblock */ recursion_info *recursive; /* Linked list of recursion data */ void *callout_data; /* To pass back to callouts */ } match_data; /* A similar structure is used for the same purpose by the DFA matching functions. */ typedef struct dfa_match_data { const uschar *start_code; /* Start of the compiled pattern */ const uschar *start_subject; /* Start of the subject string */ const uschar *end_subject; /* End of subject string */ const uschar *tables; /* Character tables */ int moptions; /* Match options */ int poptions; /* Pattern options */ int nltype; /* Newline type */ int nllen; /* Newline string length */ uschar nl[4]; /* Newline string when fixed */ void *callout_data; /* To pass back to callouts */ } dfa_match_data; /* Bit definitions for entries in the pcre_ctypes table. */ #define ctype_space 0x01 #define ctype_letter 0x02 #define ctype_digit 0x04 #define ctype_xdigit 0x08 #define ctype_word 0x10 /* alphameric or '_' */ #define ctype_meta 0x80 /* regexp meta char or zero (end pattern) */ /* Offsets for the bitmap tables in pcre_cbits. Each table contains a set of bits for a class map. Some classes are built by combining these tables. */ #define cbit_space 0 /* [:space:] or \s */ #define cbit_xdigit 32 /* [:xdigit:] */ #define cbit_digit 64 /* [:digit:] or \d */ #define cbit_upper 96 /* [:upper:] */ #define cbit_lower 128 /* [:lower:] */ #define cbit_word 160 /* [:word:] or \w */ #define cbit_graph 192 /* [:graph:] */ #define cbit_print 224 /* [:print:] */ #define cbit_punct 256 /* [:punct:] */ #define cbit_cntrl 288 /* [:cntrl:] */ #define cbit_length 320 /* Length of the cbits table */ /* Offsets of the various tables from the base tables pointer, and total length. */ #define lcc_offset 0 #define fcc_offset 256 #define cbits_offset 512 #define ctypes_offset (cbits_offset + cbit_length) #define tables_length (ctypes_offset + 256) /* Layout of the UCP type table that translates property names into types and codes. */ typedef struct { const char *name; pcre_uint16 type; pcre_uint16 value; } ucp_type_table; /* Internal shared data tables. These are tables that are used by more than one of the exported public functions. They have to be "external" in the C sense, but are not part of the PCRE public API. The data for these tables is in the pcre_tables.c module. */ extern const int _pcre_utf8_table1[]; extern const int _pcre_utf8_table2[]; extern const int _pcre_utf8_table3[]; extern const uschar _pcre_utf8_table4[]; extern const int _pcre_utf8_table1_size; extern const ucp_type_table _pcre_utt[]; extern const int _pcre_utt_size; extern const uschar _pcre_default_tables[]; extern const uschar _pcre_OP_lengths[]; /* Internal shared functions. These are functions that are used by more than one of the exported public functions. They have to be "external" in the C sense, but are not part of the PCRE public API. */ extern BOOL _pcre_is_newline(const uschar *, int, const uschar *, int *, BOOL); extern int _pcre_ord2utf8(int, uschar *); extern real_pcre *_pcre_try_flipped(const real_pcre *, real_pcre *, const pcre_study_data *, pcre_study_data *); extern int _pcre_ucp_findprop(const unsigned int, int *, int *); extern unsigned int _pcre_ucp_othercase(const unsigned int); extern int _pcre_valid_utf8(const uschar *, int); extern BOOL _pcre_was_newline(const uschar *, int, const uschar *, int *, BOOL); extern BOOL _pcre_xclass(int, const uschar *); #endif /* End of pcre_internal.h */ libsynthesis-3.4.0.47.1/src/pcre/pcre_maketables.c000066400000000000000000000125621226375725500216570ustar00rootroot00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2007 University of Cambridge ----------------------------------------------------------------------------- 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 name of the University of Cambridge 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. ----------------------------------------------------------------------------- */ /* This module contains the external function pcre_maketables(), which builds character tables for PCRE in the current locale. The file is compiled on its own as part of the PCRE library. However, it is also included in the compilation of dftables.c, in which case the macro DFTABLES is defined. */ #ifndef DFTABLES # include "pcre_setup.h" # include "pcre_internal.h" #endif /************************************************* * Create PCRE character tables * *************************************************/ /* This function builds a set of character tables for use by PCRE and returns a pointer to them. They are build using the ctype functions, and consequently their contents will depend upon the current locale setting. When compiled as part of the library, the store is obtained via pcre_malloc(), but when compiled inside dftables, use malloc(). Arguments: none Returns: pointer to the contiguous block of data */ const unsigned char * pcre_maketables(void) { unsigned char *yield, *p; int i; #ifndef DFTABLES yield = (unsigned char*)(pcre_malloc)(tables_length); #else yield = (unsigned char*)malloc(tables_length); #endif if (yield == NULL) return NULL; p = yield; /* First comes the lower casing table */ for (i = 0; i < 256; i++) *p++ = tolower(i); /* Next the case-flipping table */ for (i = 0; i < 256; i++) *p++ = islower(i)? toupper(i) : tolower(i); /* Then the character class tables. Don't try to be clever and save effort on exclusive ones - in some locales things may be different. Note that the table for "space" includes everything "isspace" gives, including VT in the default locale. This makes it work for the POSIX class [:space:]. Note also that it is possible for a character to be alnum or alpha without being lower or upper, such as "male and female ordinals" (\xAA and \xBA) in the fr_FR locale (at least under Debian Linux's locales as of 12/2005). So we must test for alnum specially. */ memset(p, 0, cbit_length); for (i = 0; i < 256; i++) { if (isdigit(i)) p[cbit_digit + i/8] |= 1 << (i&7); if (isupper(i)) p[cbit_upper + i/8] |= 1 << (i&7); if (islower(i)) p[cbit_lower + i/8] |= 1 << (i&7); if (isalnum(i)) p[cbit_word + i/8] |= 1 << (i&7); if (i == '_') p[cbit_word + i/8] |= 1 << (i&7); if (isspace(i)) p[cbit_space + i/8] |= 1 << (i&7); if (isxdigit(i))p[cbit_xdigit + i/8] |= 1 << (i&7); if (isgraph(i)) p[cbit_graph + i/8] |= 1 << (i&7); if (isprint(i)) p[cbit_print + i/8] |= 1 << (i&7); if (ispunct(i)) p[cbit_punct + i/8] |= 1 << (i&7); if (iscntrl(i)) p[cbit_cntrl + i/8] |= 1 << (i&7); } p += cbit_length; /* Finally, the character type table. In this, we exclude VT from the white space chars, because Perl doesn't recognize it as such for \s and for comments within regexes. */ for (i = 0; i < 256; i++) { int x = 0; if (i != 0x0b && isspace(i)) x += ctype_space; if (isalpha(i)) x += ctype_letter; if (isdigit(i)) x += ctype_digit; if (isxdigit(i)) x += ctype_xdigit; if (isalnum(i) || i == '_') x += ctype_word; /* Note: strchr includes the terminating zero in the characters it considers. In this instance, that is ok because we want binary zero to be flagged as a meta-character, which in this sense is any character that terminates a run of data characters. */ if (strchr("\\*+?{^.$|()[", i) != 0) x += ctype_meta; *p++ = x; } return yield; } /* End of pcre_maketables.c */ libsynthesis-3.4.0.47.1/src/pcre/pcre_newline.c000066400000000000000000000131701226375725500212040ustar00rootroot00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2007 University of Cambridge ----------------------------------------------------------------------------- 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 name of the University of Cambridge 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. ----------------------------------------------------------------------------- */ /* This module contains internal functions for testing newlines when more than one kind of newline is to be recognized. When a newline is found, its length is returned. In principle, we could implement several newline "types", each referring to a different set of newline characters. At present, PCRE supports only NLTYPE_FIXED, which gets handled without these functions, NLTYPE_ANYCRLF, and NLTYPE_ANY. The full list of Unicode newline characters is taken from http://unicode.org/unicode/reports/tr18/. */ #include "pcre_setup.h" #include "pcre_internal.h" /************************************************* * Check for newline at given position * *************************************************/ /* It is guaranteed that the initial value of ptr is less than the end of the string that is being processed. Arguments: ptr pointer to possible newline type the newline type endptr pointer to the end of the string lenptr where to return the length utf8 TRUE if in utf8 mode Returns: TRUE or FALSE */ BOOL _pcre_is_newline(const uschar *ptr, int type, const uschar *endptr, int *lenptr, BOOL utf8) { int c; if (utf8) { GETCHAR(c, ptr); } else c = *ptr; if (type == NLTYPE_ANYCRLF) switch(c) { case 0x000a: *lenptr = 1; return TRUE; /* LF */ case 0x000d: *lenptr = (ptr < endptr - 1 && ptr[1] == 0x0a)? 2 : 1; return TRUE; /* CR */ default: return FALSE; } /* NLTYPE_ANY */ else switch(c) { case 0x000a: /* LF */ case 0x000b: /* VT */ case 0x000c: *lenptr = 1; return TRUE; /* FF */ case 0x000d: *lenptr = (ptr < endptr - 1 && ptr[1] == 0x0a)? 2 : 1; return TRUE; /* CR */ case 0x0085: *lenptr = utf8? 2 : 1; return TRUE; /* NEL */ case 0x2028: /* LS */ case 0x2029: *lenptr = 3; return TRUE; /* PS */ default: return FALSE; } } /************************************************* * Check for newline at previous position * *************************************************/ /* It is guaranteed that the initial value of ptr is greater than the start of the string that is being processed. Arguments: ptr pointer to possible newline type the newline type startptr pointer to the start of the string lenptr where to return the length utf8 TRUE if in utf8 mode Returns: TRUE or FALSE */ BOOL _pcre_was_newline(const uschar *ptr, int type, const uschar *startptr, int *lenptr, BOOL utf8) { int c; ptr--; #ifdef SUPPORT_UTF8 if (utf8) { BACKCHAR(ptr); GETCHAR(c, ptr); } else c = *ptr; #else /* no UTF-8 support */ c = *ptr; #endif /* SUPPORT_UTF8 */ if (type == NLTYPE_ANYCRLF) switch(c) { case 0x000a: *lenptr = (ptr > startptr && ptr[-1] == 0x0d)? 2 : 1; return TRUE; /* LF */ case 0x000d: *lenptr = 1; return TRUE; /* CR */ default: return FALSE; } else switch(c) { case 0x000a: *lenptr = (ptr > startptr && ptr[-1] == 0x0d)? 2 : 1; return TRUE; /* LF */ case 0x000b: /* VT */ case 0x000c: /* FF */ case 0x000d: *lenptr = 1; return TRUE; /* CR */ case 0x0085: *lenptr = utf8? 2 : 1; return TRUE; /* NEL */ case 0x2028: /* LS */ case 0x2029: *lenptr = 3; return TRUE; /* PS */ default: return FALSE; } } /* End of pcre_newline.c */ libsynthesis-3.4.0.47.1/src/pcre/pcre_ord2utf8.c000066400000000000000000000061151226375725500212210ustar00rootroot00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2007 University of Cambridge ----------------------------------------------------------------------------- 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 name of the University of Cambridge 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. ----------------------------------------------------------------------------- */ /* This file contains a private PCRE function that converts an ordinal character value into a UTF8 string. */ #include "pcre_setup.h" #include "pcre_internal.h" /************************************************* * Convert character value to UTF-8 * *************************************************/ /* This function takes an integer value in the range 0 - 0x7fffffff and encodes it as a UTF-8 character in 0 to 6 bytes. Arguments: cvalue the character value buffer pointer to buffer for result - at least 6 bytes long Returns: number of characters placed in the buffer */ int _pcre_ord2utf8(int cvalue, uschar *buffer) { #ifdef SUPPORT_UTF8 register int i, j; for (i = 0; i < _pcre_utf8_table1_size; i++) if (cvalue <= _pcre_utf8_table1[i]) break; buffer += i; for (j = i; j > 0; j--) { *buffer-- = 0x80 | (cvalue & 0x3f); cvalue >>= 6; } *buffer = _pcre_utf8_table2[i] | cvalue; return i + 1; #else return 0; /* Keep compiler happy; this function won't ever be */ #endif /* called when SUPPORT_UTF8 is not defined. */ } /* End of pcre_ord2utf8.c */ libsynthesis-3.4.0.47.1/src/pcre/pcre_printint.src000066400000000000000000000340361226375725500217630ustar00rootroot00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2007 University of Cambridge ----------------------------------------------------------------------------- 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 name of the University of Cambridge 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. ----------------------------------------------------------------------------- */ /* This module contains a PCRE private debugging function for printing out the internal form of a compiled regular expression, along with some supporting local functions. This source file is used in two places: (1) It is #included by pcre_compile.c when it is compiled in debugging mode (DEBUG defined in pcre_internal.h). It is not included in production compiles. (2) It is always #included by pcretest.c, which can be asked to print out a compiled regex for debugging purposes. */ /* Macro that decides whether a character should be output as a literal or in hexadecimal. We don't use isprint() because that can vary from system to system (even without the use of locales) and we want the output always to be the same, for testing purposes. This macro is used in pcretest as well as in this file. */ #define PRINTABLE(c) ((c) >= 32 && (c) < 127) /* The table of operator names. */ static const char *OP_names[] = { OP_NAME_LIST }; /************************************************* * Print single- or multi-byte character * *************************************************/ static int print_char(FILE *f, uschar *ptr, BOOL utf8) { int c = *ptr; #ifndef SUPPORT_UTF8 utf8 = utf8; /* Avoid compiler warning */ if (PRINTABLE(c)) fprintf(f, "%c", c); else fprintf(f, "\\x%02x", c); return 0; #else if (!utf8 || (c & 0xc0) != 0xc0) { if (PRINTABLE(c)) fprintf(f, "%c", c); else fprintf(f, "\\x%02x", c); return 0; } else { int i; int a = _pcre_utf8_table4[c & 0x3f]; /* Number of additional bytes */ int s = 6*a; c = (c & _pcre_utf8_table3[a]) << s; for (i = 1; i <= a; i++) { /* This is a check for malformed UTF-8; it should only occur if the sanity check has been turned off. Rather than swallow random bytes, just stop if we hit a bad one. Print it with \X instead of \x as an indication. */ if ((ptr[i] & 0xc0) != 0x80) { fprintf(f, "\\X{%x}", c); return i - 1; } /* The byte is OK */ s -= 6; c |= (ptr[i] & 0x3f) << s; } if (c < 128) fprintf(f, "\\x%02x", c); else fprintf(f, "\\x{%x}", c); return a; } #endif } /************************************************* * Find Unicode property name * *************************************************/ static const char * get_ucpname(int ptype, int pvalue) { #ifdef SUPPORT_UCP int i; for (i = _pcre_utt_size - 1; i >= 0; i--) { if (ptype == _pcre_utt[i].type && pvalue == _pcre_utt[i].value) break; } return (i >= 0)? _pcre_utt[i].name : "??"; #else /* It gets harder and harder to shut off unwanted compiler warnings. */ ptype = ptype * pvalue; return (ptype == pvalue)? "??" : "??"; #endif } /************************************************* * Print compiled regex * *************************************************/ /* Make this function work for a regex with integers either byte order. However, we assume that what we are passed is a compiled regex. The print_lengths flag controls whether offsets and lengths of items are printed. They can be turned off from pcretest so that automatic tests on bytecode can be written that do not depend on the value of LINK_SIZE. */ static void pcre_printint(pcre *external_re, FILE *f, BOOL print_lengths) { real_pcre *re = (real_pcre *)external_re; uschar *codestart, *code; BOOL utf8; unsigned int options = re->options; int offset = re->name_table_offset; int count = re->name_count; int size = re->name_entry_size; if (re->magic_number != MAGIC_NUMBER) { offset = ((offset << 8) & 0xff00) | ((offset >> 8) & 0xff); count = ((count << 8) & 0xff00) | ((count >> 8) & 0xff); size = ((size << 8) & 0xff00) | ((size >> 8) & 0xff); options = ((options << 24) & 0xff000000) | ((options << 8) & 0x00ff0000) | ((options >> 8) & 0x0000ff00) | ((options >> 24) & 0x000000ff); } code = codestart = (uschar *)re + offset + count * size; utf8 = (options & PCRE_UTF8) != 0; for(;;) { uschar *ccode; int c; int extra = 0; if (print_lengths) fprintf(f, "%3d ", (int)(code - codestart)); else fprintf(f, " "); switch(*code) { case OP_END: fprintf(f, " %s\n", OP_names[*code]); fprintf(f, "------------------------------------------------------------------\n"); return; case OP_OPT: fprintf(f, " %.2x %s", code[1], OP_names[*code]); break; case OP_CHAR: fprintf(f, " "); do { code++; code += 1 + print_char(f, code, utf8); } while (*code == OP_CHAR); fprintf(f, "\n"); continue; case OP_CHARNC: fprintf(f, " NC "); do { code++; code += 1 + print_char(f, code, utf8); } while (*code == OP_CHARNC); fprintf(f, "\n"); continue; case OP_CBRA: case OP_SCBRA: if (print_lengths) fprintf(f, "%3d ", GET(code, 1)); else fprintf(f, " "); fprintf(f, "%s %d", OP_names[*code], GET2(code, 1+LINK_SIZE)); break; case OP_BRA: case OP_SBRA: case OP_KETRMAX: case OP_KETRMIN: case OP_ALT: case OP_KET: case OP_ASSERT: case OP_ASSERT_NOT: case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: case OP_ONCE: case OP_COND: case OP_SCOND: case OP_REVERSE: if (print_lengths) fprintf(f, "%3d ", GET(code, 1)); else fprintf(f, " "); fprintf(f, "%s", OP_names[*code]); break; case OP_CREF: fprintf(f, "%3d %s", GET2(code,1), OP_names[*code]); break; case OP_RREF: c = GET2(code, 1); if (c == RREF_ANY) fprintf(f, " Cond recurse any"); else fprintf(f, " Cond recurse %d", c); break; case OP_DEF: fprintf(f, " Cond def"); break; case OP_STAR: case OP_MINSTAR: case OP_POSSTAR: case OP_PLUS: case OP_MINPLUS: case OP_POSPLUS: case OP_QUERY: case OP_MINQUERY: case OP_POSQUERY: case OP_TYPESTAR: case OP_TYPEMINSTAR: case OP_TYPEPOSSTAR: case OP_TYPEPLUS: case OP_TYPEMINPLUS: case OP_TYPEPOSPLUS: case OP_TYPEQUERY: case OP_TYPEMINQUERY: case OP_TYPEPOSQUERY: fprintf(f, " "); if (*code >= OP_TYPESTAR) { fprintf(f, "%s", OP_names[code[1]]); if (code[1] == OP_PROP || code[1] == OP_NOTPROP) { fprintf(f, " %s ", get_ucpname(code[2], code[3])); extra = 2; } } else extra = print_char(f, code+1, utf8); fprintf(f, "%s", OP_names[*code]); break; case OP_EXACT: case OP_UPTO: case OP_MINUPTO: case OP_POSUPTO: fprintf(f, " "); extra = print_char(f, code+3, utf8); fprintf(f, "{"); if (*code != OP_EXACT) fprintf(f, "0,"); fprintf(f, "%d}", GET2(code,1)); if (*code == OP_MINUPTO) fprintf(f, "?"); else if (*code == OP_POSUPTO) fprintf(f, "+"); break; case OP_TYPEEXACT: case OP_TYPEUPTO: case OP_TYPEMINUPTO: case OP_TYPEPOSUPTO: fprintf(f, " %s", OP_names[code[3]]); if (code[3] == OP_PROP || code[3] == OP_NOTPROP) { fprintf(f, " %s ", get_ucpname(code[4], code[5])); extra = 2; } fprintf(f, "{"); if (*code != OP_TYPEEXACT) fprintf(f, "0,"); fprintf(f, "%d}", GET2(code,1)); if (*code == OP_TYPEMINUPTO) fprintf(f, "?"); else if (*code == OP_TYPEPOSUPTO) fprintf(f, "+"); break; case OP_NOT: c = code[1]; if (PRINTABLE(c)) fprintf(f, " [^%c]", c); else fprintf(f, " [^\\x%02x]", c); break; case OP_NOTSTAR: case OP_NOTMINSTAR: case OP_NOTPOSSTAR: case OP_NOTPLUS: case OP_NOTMINPLUS: case OP_NOTPOSPLUS: case OP_NOTQUERY: case OP_NOTMINQUERY: case OP_NOTPOSQUERY: c = code[1]; if (PRINTABLE(c)) fprintf(f, " [^%c]", c); else fprintf(f, " [^\\x%02x]", c); fprintf(f, "%s", OP_names[*code]); break; case OP_NOTEXACT: case OP_NOTUPTO: case OP_NOTMINUPTO: case OP_NOTPOSUPTO: c = code[3]; if (PRINTABLE(c)) fprintf(f, " [^%c]{", c); else fprintf(f, " [^\\x%02x]{", c); if (*code != OP_NOTEXACT) fprintf(f, "0,"); fprintf(f, "%d}", GET2(code,1)); if (*code == OP_NOTMINUPTO) fprintf(f, "?"); else if (*code == OP_NOTPOSUPTO) fprintf(f, "+"); break; case OP_RECURSE: if (print_lengths) fprintf(f, "%3d ", GET(code, 1)); else fprintf(f, " "); fprintf(f, "%s", OP_names[*code]); break; case OP_REF: fprintf(f, " \\%d", GET2(code,1)); ccode = code + _pcre_OP_lengths[*code]; goto CLASS_REF_REPEAT; case OP_CALLOUT: fprintf(f, " %s %d %d %d", OP_names[*code], code[1], GET(code,2), GET(code, 2 + LINK_SIZE)); break; case OP_PROP: case OP_NOTPROP: fprintf(f, " %s %s", OP_names[*code], get_ucpname(code[1], code[2])); break; /* OP_XCLASS can only occur in UTF-8 mode. However, there's no harm in having this code always here, and it makes it less messy without all those #ifdefs. */ case OP_CLASS: case OP_NCLASS: case OP_XCLASS: { int i, min, max; BOOL printmap; fprintf(f, " ["); if (*code == OP_XCLASS) { extra = GET(code, 1); ccode = code + LINK_SIZE + 1; printmap = (*ccode & XCL_MAP) != 0; if ((*ccode++ & XCL_NOT) != 0) fprintf(f, "^"); } else { printmap = TRUE; ccode = code + 1; } /* Print a bit map */ if (printmap) { for (i = 0; i < 256; i++) { if ((ccode[i/8] & (1 << (i&7))) != 0) { int j; for (j = i+1; j < 256; j++) if ((ccode[j/8] & (1 << (j&7))) == 0) break; if (i == '-' || i == ']') fprintf(f, "\\"); if (PRINTABLE(i)) fprintf(f, "%c", i); else fprintf(f, "\\x%02x", i); if (--j > i) { if (j != i + 1) fprintf(f, "-"); if (j == '-' || j == ']') fprintf(f, "\\"); if (PRINTABLE(j)) fprintf(f, "%c", j); else fprintf(f, "\\x%02x", j); } i = j; } } ccode += 32; } /* For an XCLASS there is always some additional data */ if (*code == OP_XCLASS) { int ch; while ((ch = *ccode++) != XCL_END) { if (ch == XCL_PROP) { int ptype = *ccode++; int pvalue = *ccode++; fprintf(f, "\\p{%s}", get_ucpname(ptype, pvalue)); } else if (ch == XCL_NOTPROP) { int ptype = *ccode++; int pvalue = *ccode++; fprintf(f, "\\P{%s}", get_ucpname(ptype, pvalue)); } else { ccode += 1 + print_char(f, ccode, TRUE); if (ch == XCL_RANGE) { fprintf(f, "-"); ccode += 1 + print_char(f, ccode, TRUE); } } } } /* Indicate a non-UTF8 class which was created by negation */ fprintf(f, "]%s", (*code == OP_NCLASS)? " (neg)" : ""); /* Handle repeats after a class or a back reference */ CLASS_REF_REPEAT: switch(*ccode) { case OP_CRSTAR: case OP_CRMINSTAR: case OP_CRPLUS: case OP_CRMINPLUS: case OP_CRQUERY: case OP_CRMINQUERY: fprintf(f, "%s", OP_names[*ccode]); extra += _pcre_OP_lengths[*ccode]; break; case OP_CRRANGE: case OP_CRMINRANGE: min = GET2(ccode,1); max = GET2(ccode,3); if (max == 0) fprintf(f, "{%d,}", min); else fprintf(f, "{%d,%d}", min, max); if (*ccode == OP_CRMINRANGE) fprintf(f, "?"); extra += _pcre_OP_lengths[*ccode]; break; /* Do nothing if it's not a repeat; this code stops picky compilers warning about the lack of a default code path. */ default: break; } } break; /* Anything else is just an item with no data*/ default: fprintf(f, " %s", OP_names[*code]); break; } code += _pcre_OP_lengths[*code] + extra; fprintf(f, "\n"); } } /* End of pcre_printint.src */ libsynthesis-3.4.0.47.1/src/pcre/pcre_refcount.c000066400000000000000000000064131226375725500213720ustar00rootroot00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2007 University of Cambridge ----------------------------------------------------------------------------- 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 name of the University of Cambridge 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. ----------------------------------------------------------------------------- */ /* This module contains the external function pcre_refcount(), which is an auxiliary function that can be used to maintain a reference count in a compiled pattern data block. This might be helpful in applications where the block is shared by different users. */ #include "pcre_setup.h" #include "pcre_internal.h" /************************************************* * Maintain reference count * *************************************************/ /* The reference count is a 16-bit field, initialized to zero. It is not possible to transfer a non-zero count from one host to a different host that has a different byte order - though I can't see why anyone in their right mind would ever want to do that! Arguments: argument_re points to compiled code adjust value to add to the count Returns: the (possibly updated) count value (a non-negative number), or a negative error number */ PCRE_EXP_DEFN int pcre_refcount(pcre *argument_re, int adjust) { real_pcre *re = (real_pcre *)argument_re; if (re == NULL) return PCRE_ERROR_NULL; re->ref_count = (-adjust > re->ref_count)? 0 : (adjust + re->ref_count > 65535)? 65535 : re->ref_count + adjust; return re->ref_count; } /* End of pcre_refcount.c */ libsynthesis-3.4.0.47.1/src/pcre/pcre_scanner.cc000066400000000000000000000126341226375725500213430ustar00rootroot00000000000000// Copyright (c) 2005, Google Inc. // 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 name of Google Inc. 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. // // Author: Sanjay Ghemawat #ifdef HAVE_CONFIG_H #include #endif #include #include #include "pcrecpp_internal.h" #include "pcre_scanner.h" using std::vector; namespace pcrecpp { Scanner::Scanner() : data_(), input_(data_), skip_(NULL), should_skip_(false), skip_repeat_(false), save_comments_(false), comments_(NULL), comments_offset_(0) { } Scanner::Scanner(const string& in) : data_(in), input_(data_), skip_(NULL), should_skip_(false), skip_repeat_(false), save_comments_(false), comments_(NULL), comments_offset_(0) { } Scanner::~Scanner() { delete skip_; delete comments_; } void Scanner::SetSkipExpression(const char* re) { delete skip_; if (re != NULL) { skip_ = new RE(re); should_skip_ = true; skip_repeat_ = true; ConsumeSkip(); } else { skip_ = NULL; should_skip_ = false; skip_repeat_ = false; } } void Scanner::Skip(const char* re) { delete skip_; if (re != NULL) { skip_ = new RE(re); should_skip_ = true; skip_repeat_ = false; ConsumeSkip(); } else { skip_ = NULL; should_skip_ = false; skip_repeat_ = false; } } void Scanner::DisableSkip() { assert(skip_ != NULL); should_skip_ = false; } void Scanner::EnableSkip() { assert(skip_ != NULL); should_skip_ = true; ConsumeSkip(); } int Scanner::LineNumber() const { // TODO: Make it more efficient by keeping track of the last point // where we computed line numbers and counting newlines since then. // We could use std:count, but not all systems have it. :-( int count = 1; for (const char* p = data_.data(); p < input_.data(); ++p) if (*p == '\n') ++count; return count; } int Scanner::Offset() const { return input_.data() - data_.c_str(); } bool Scanner::LookingAt(const RE& re) const { int consumed; return re.DoMatch(input_, RE::ANCHOR_START, &consumed, 0, 0); } bool Scanner::Consume(const RE& re, const Arg& arg0, const Arg& arg1, const Arg& arg2) { const bool result = re.Consume(&input_, arg0, arg1, arg2); if (result && should_skip_) ConsumeSkip(); return result; } // helper function to consume *skip_ and honour save_comments_ void Scanner::ConsumeSkip() { const char* start_data = input_.data(); while (skip_->Consume(&input_)) { if (!skip_repeat_) { // Only one skip allowed. break; } } if (save_comments_) { if (comments_ == NULL) { comments_ = new vector; } // already pointing one past end, so no need to +1 int length = input_.data() - start_data; if (length > 0) { comments_->push_back(StringPiece(start_data, length)); } } } void Scanner::GetComments(int start, int end, vector *ranges) { // short circuit out if we've not yet initialized comments_ // (e.g., when save_comments is false) if (!comments_) { return; } // TODO: if we guarantee that comments_ will contain StringPieces // that are ordered by their start, then we can do a binary search // for the first StringPiece at or past start and then scan for the // ones contained in the range, quit early (use equal_range or // lower_bound) for (vector::const_iterator it = comments_->begin(); it != comments_->end(); ++it) { if ((it->data() >= data_.c_str() + start && it->data() + it->size() <= data_.c_str() + end)) { ranges->push_back(*it); } } } void Scanner::GetNextComments(vector *ranges) { // short circuit out if we've not yet initialized comments_ // (e.g., when save_comments is false) if (!comments_) { return; } for (vector::const_iterator it = comments_->begin() + comments_offset_; it != comments_->end(); ++it) { ranges->push_back(*it); ++comments_offset_; } } } // namespace pcrecpp libsynthesis-3.4.0.47.1/src/pcre/pcre_scanner.h000066400000000000000000000146741226375725500212130ustar00rootroot00000000000000// Copyright (c) 2005, Google Inc. // 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 name of Google Inc. 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. // // Author: Sanjay Ghemawat // // Regular-expression based scanner for parsing an input stream. // // Example 1: parse a sequence of "var = number" entries from input: // // Scanner scanner(input); // string var; // int number; // scanner.SetSkipExpression("\\s+"); // Skip any white space we encounter // while (scanner.Consume("(\\w+) = (\\d+)", &var, &number)) { // ...; // } #ifndef _PCRE_SCANNER_H #define _PCRE_SCANNER_H #include #include #include #include #include namespace pcrecpp { class PCRECPP_EXP_DEFN Scanner { public: Scanner(); explicit Scanner(const std::string& input); ~Scanner(); // Return current line number. The returned line-number is // one-based. I.e. it returns 1 + the number of consumed newlines. // // Note: this method may be slow. It may take time proportional to // the size of the input. int LineNumber() const; // Return the byte-offset that the scanner is looking in the // input data; int Offset() const; // Return true iff the start of the remaining input matches "re" bool LookingAt(const RE& re) const; // Return true iff all of the following are true // a. the start of the remaining input matches "re", // b. if any arguments are supplied, matched sub-patterns can be // parsed and stored into the arguments. // If it returns true, it skips over the matched input and any // following input that matches the "skip" regular expression. bool Consume(const RE& re, const Arg& arg0 = no_arg, const Arg& arg1 = no_arg, const Arg& arg2 = no_arg // TODO: Allow more arguments? ); // Set the "skip" regular expression. If after consuming some data, // a prefix of the input matches this RE, it is automatically // skipped. For example, a programming language scanner would use // a skip RE that matches white space and comments. // // scanner.SetSkipExpression("\\s+|//.*|/[*](.|\n)*?[*]/"); // // Skipping repeats as long as it succeeds. We used to let people do // this by writing "(...)*" in the regular expression, but that added // up to lots of recursive calls within the pcre library, so now we // control repetition explicitly via the function call API. // // You can pass NULL for "re" if you do not want any data to be skipped. void Skip(const char* re); // DEPRECATED; does *not* repeat void SetSkipExpression(const char* re); // Temporarily pause "skip"ing. This // Skip("Foo"); code ; DisableSkip(); code; EnableSkip() // is similar to // Skip("Foo"); code ; Skip(NULL); code ; Skip("Foo"); // but avoids creating/deleting new RE objects. void DisableSkip(); // Reenable previously paused skipping. Any prefix of the input // that matches the skip pattern is immediately dropped. void EnableSkip(); /***** Special wrappers around SetSkip() for some common idioms *****/ // Arranges to skip whitespace, C comments, C++ comments. // The overall RE is a disjunction of the following REs: // \\s whitespace // //.*\n C++ comment // /[*](.|\n)*?[*]/ C comment (x*? means minimal repetitions of x) // We get repetition via the semantics of SetSkipExpression, not by using * void SkipCXXComments() { SetSkipExpression("\\s|//.*\n|/[*](?:\n|.)*?[*]/"); } void set_save_comments(bool comments) { save_comments_ = comments; } bool save_comments() { return save_comments_; } // Append to vector ranges the comments found in the // byte range [start,end] (inclusive) of the input data. // Only comments that were extracted entirely within that // range are returned: no range splitting of atomically-extracted // comments is performed. void GetComments(int start, int end, std::vector *ranges); // Append to vector ranges the comments added // since the last time this was called. This // functionality is provided for efficiency when // interleaving scanning with parsing. void GetNextComments(std::vector *ranges); private: std::string data_; // All the input data StringPiece input_; // Unprocessed input RE* skip_; // If non-NULL, RE for skipping input bool should_skip_; // If true, use skip_ bool skip_repeat_; // If true, repeat skip_ as long as it works bool save_comments_; // If true, aggregate the skip expression // the skipped comments // TODO: later consider requiring that the StringPieces be added // in order by their start position std::vector *comments_; // the offset into comments_ that has been returned by GetNextComments int comments_offset_; // helper function to consume *skip_ and honour // save_comments_ void ConsumeSkip(); }; } // namespace pcrecpp #endif /* _PCRE_SCANNER_H */ libsynthesis-3.4.0.47.1/src/pcre/pcre_scanner_unittest.cc000066400000000000000000000121631226375725500232770ustar00rootroot00000000000000// Copyright (c) 2005, Google Inc. // 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 name of Google Inc. 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. // // Author: Greg J. Badros // // Unittest for scanner, especially GetNextComments and GetComments() // functionality. #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #ifdef _WIN32 # define snprintf _snprintf #endif #define FLAGS_unittest_stack_size 49152 // Dies with a fatal error if the two values are not equal. #define CHECK_EQ(a, b) do { \ if ( (a) != (b) ) { \ fprintf(stderr, "%s:%d: Check failed because %s != %s\n", \ __FILE__, __LINE__, #a, #b); \ exit(1); \ } \ } while (0) using std::vector; using pcrecpp::StringPiece; using pcrecpp::Scanner; static void TestScanner() { const char input[] = "\n" "alpha = 1; // this sets alpha\n" "bravo = 2; // bravo is set here\n" "gamma = 33; /* and here is gamma */\n"; const char *re = "(\\w+) = (\\d+);"; Scanner s(input); string var; int number; s.SkipCXXComments(); s.set_save_comments(true); vector comments; s.Consume(re, &var, &number); CHECK_EQ(var, "alpha"); CHECK_EQ(number, 1); CHECK_EQ(s.LineNumber(), 3); s.GetNextComments(&comments); CHECK_EQ(comments.size(), 1); CHECK_EQ(comments[0].as_string(), " // this sets alpha\n"); comments.resize(0); s.Consume(re, &var, &number); CHECK_EQ(var, "bravo"); CHECK_EQ(number, 2); s.GetNextComments(&comments); CHECK_EQ(comments.size(), 1); CHECK_EQ(comments[0].as_string(), " // bravo is set here\n"); comments.resize(0); s.Consume(re, &var, &number); CHECK_EQ(var, "gamma"); CHECK_EQ(number, 33); s.GetNextComments(&comments); CHECK_EQ(comments.size(), 1); CHECK_EQ(comments[0].as_string(), " /* and here is gamma */\n"); comments.resize(0); s.GetComments(0, sizeof(input), &comments); CHECK_EQ(comments.size(), 3); CHECK_EQ(comments[0].as_string(), " // this sets alpha\n"); CHECK_EQ(comments[1].as_string(), " // bravo is set here\n"); CHECK_EQ(comments[2].as_string(), " /* and here is gamma */\n"); comments.resize(0); s.GetComments(0, strchr(input, '/') - input, &comments); CHECK_EQ(comments.size(), 0); comments.resize(0); s.GetComments(strchr(input, '/') - input - 1, sizeof(input), &comments); CHECK_EQ(comments.size(), 3); CHECK_EQ(comments[0].as_string(), " // this sets alpha\n"); CHECK_EQ(comments[1].as_string(), " // bravo is set here\n"); CHECK_EQ(comments[2].as_string(), " /* and here is gamma */\n"); comments.resize(0); s.GetComments(strchr(input, '/') - input - 1, strchr(input + 1, '\n') - input + 1, &comments); CHECK_EQ(comments.size(), 1); CHECK_EQ(comments[0].as_string(), " // this sets alpha\n"); comments.resize(0); } static void TestBigComment() { string input; for (int i = 0; i < 1024; ++i) { char buf[1024]; snprintf(buf, sizeof(buf), " # Comment %d\n", i); input += buf; } input += "name = value;\n"; Scanner s(input.c_str()); s.SetSkipExpression("\\s+|#.*\n"); string name; string value; s.Consume("(\\w+) = (\\w+);", &name, &value); CHECK_EQ(name, "name"); CHECK_EQ(value, "value"); } // TODO: also test scanner and big-comment in a thread with a // small stack size int main(int argc, char** argv) { TestScanner(); TestBigComment(); // Done printf("OK\n"); return 0; } libsynthesis-3.4.0.47.1/src/pcre/pcre_setup.h000066400000000000000000000015421226375725500207100ustar00rootroot00000000000000/* common include file for all PCRE sources * Added by luz 2007-09-03 to allow more flexibility for * multi-platform static linking with platforms w/o config.h * mechanisms */ /* Note: target_options may define PCRE_HAS_CONFIG_H if environment * has generic config.h that works for PCRE and does not conflict * with other components. */ #include "target_options.h" // to get platform defines #ifdef PCRE_HAS_CONFIG_H #include #else #if defined(WIN32) /* hand-modified win32 config.h! */ #include "pcre_config_win32.h" #elif defined(MACOSX) /* hand-modified MacOS config.h! */ #include "pcre_config_macosx.h" #elif defined(ANDROID) /* hand-modified MacOS config.h! */ #include "pcre_config_android.h" #else #error "PCRE not yet prepared for this platform" #endif #endif /* not PCRE_HAS_CONFIG_H */ libsynthesis-3.4.0.47.1/src/pcre/pcre_stringpiece.cc000066400000000000000000000035021226375725500222200ustar00rootroot00000000000000// Copyright (c) 2005, Google Inc. // 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 name of Google Inc. 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. // // Author: wilsonh@google.com (Wilson Hsieh) // #ifdef HAVE_CONFIG_H #include #endif #include #include "pcrecpp_internal.h" #include "pcre_stringpiece.h" std::ostream& operator<<(std::ostream& o, const pcrecpp::StringPiece& piece) { return (o << piece.as_string()); } libsynthesis-3.4.0.47.1/src/pcre/pcre_stringpiece.h.in000066400000000000000000000137561226375725500225030ustar00rootroot00000000000000// Copyright (c) 2005, Google Inc. // 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 name of Google Inc. 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. // // Author: Sanjay Ghemawat // // A string like object that points into another piece of memory. // Useful for providing an interface that allows clients to easily // pass in either a "const char*" or a "string". // // Arghh! I wish C++ literals were automatically of type "string". #ifndef _PCRE_STRINGPIECE_H #define _PCRE_STRINGPIECE_H #include #include #include // for ostream forward-declaration #if @pcre_have_type_traits@ #define HAVE_TYPE_TRAITS #include #elif @pcre_have_bits_type_traits@ #define HAVE_TYPE_TRAITS #include #endif #include using std::string; namespace pcrecpp { class PCRECPP_EXP_DEFN StringPiece { private: const char* ptr_; int length_; public: // We provide non-explicit singleton constructors so users can pass // in a "const char*" or a "string" wherever a "StringPiece" is // expected. StringPiece() : ptr_(NULL), length_(0) { } StringPiece(const char* str) : ptr_(str), length_(static_cast(strlen(str))) { } StringPiece(const string& str) : ptr_(str.data()), length_(static_cast(str.size())) { } StringPiece(const char* offset, int len) : ptr_(offset), length_(len) { } // data() may return a pointer to a buffer with embedded NULs, and the // returned buffer may or may not be null terminated. Therefore it is // typically a mistake to pass data() to a routine that expects a NUL // terminated string. Use "as_string().c_str()" if you really need to do // this. Or better yet, change your routine so it does not rely on NUL // termination. const char* data() const { return ptr_; } int size() const { return length_; } bool empty() const { return length_ == 0; } void clear() { ptr_ = NULL; length_ = 0; } void set(const char* buffer, int len) { ptr_ = buffer; length_ = len; } void set(const char* str) { ptr_ = str; length_ = static_cast(strlen(str)); } void set(const void* buffer, int len) { ptr_ = reinterpret_cast(buffer); length_ = len; } char operator[](int i) const { return ptr_[i]; } void remove_prefix(int n) { ptr_ += n; length_ -= n; } void remove_suffix(int n) { length_ -= n; } bool operator==(const StringPiece& x) const { return ((length_ == x.length_) && (memcmp(ptr_, x.ptr_, length_) == 0)); } bool operator!=(const StringPiece& x) const { return !(*this == x); } #define STRINGPIECE_BINARY_PREDICATE(cmp,auxcmp) \ bool operator cmp (const StringPiece& x) const { \ int r = memcmp(ptr_, x.ptr_, length_ < x.length_ ? length_ : x.length_); \ return ((r auxcmp 0) || ((r == 0) && (length_ cmp x.length_))); \ } STRINGPIECE_BINARY_PREDICATE(<, <); STRINGPIECE_BINARY_PREDICATE(<=, <); STRINGPIECE_BINARY_PREDICATE(>=, >); STRINGPIECE_BINARY_PREDICATE(>, >); #undef STRINGPIECE_BINARY_PREDICATE int compare(const StringPiece& x) const { int r = memcmp(ptr_, x.ptr_, length_ < x.length_ ? length_ : x.length_); if (r == 0) { if (length_ < x.length_) r = -1; else if (length_ > x.length_) r = +1; } return r; } string as_string() const { return string(data(), size()); } void CopyToString(string* target) const { target->assign(ptr_, length_); } // Does "this" start with "x" bool starts_with(const StringPiece& x) const { return ((length_ >= x.length_) && (memcmp(ptr_, x.ptr_, x.length_) == 0)); } }; } // namespace pcrecpp // ------------------------------------------------------------------ // Functions used to create STL containers that use StringPiece // Remember that a StringPiece's lifetime had better be less than // that of the underlying string or char*. If it is not, then you // cannot safely store a StringPiece into an STL container // ------------------------------------------------------------------ #ifdef HAVE_TYPE_TRAITS // This makes vector really fast for some STL implementations template<> struct __type_traits { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; #endif // allow StringPiece to be logged std::ostream& operator<<(std::ostream& o, const pcrecpp::StringPiece& piece); #endif /* _PCRE_STRINGPIECE_H */ libsynthesis-3.4.0.47.1/src/pcre/pcre_stringpiece_unittest.cc000066400000000000000000000070121226375725500241570ustar00rootroot00000000000000// Copyright 2003 and onwards Google Inc. // Author: Sanjay Ghemawat #ifdef HAVE_CONFIG_H #include #endif #include #include #include // for make_pair #include #include // CHECK dies with a fatal error if condition is not true. It is *not* // controlled by NDEBUG, so the check will be executed regardless of // compilation mode. Therefore, it is safe to do things like: // CHECK(fp->Write(x) == 4) #define CHECK(condition) do { \ if (!(condition)) { \ fprintf(stderr, "%s:%d: Check failed: %s\n", \ __FILE__, __LINE__, #condition); \ exit(1); \ } \ } while (0) using std::map; using std::make_pair; using pcrecpp::StringPiece; static void CheckSTLComparator() { string s1("foo"); string s2("bar"); string s3("baz"); StringPiece p1(s1); StringPiece p2(s2); StringPiece p3(s3); typedef map TestMap; TestMap map; map.insert(make_pair(p1, 0)); map.insert(make_pair(p2, 1)); map.insert(make_pair(p3, 2)); CHECK(map.size() == 3); TestMap::const_iterator iter = map.begin(); CHECK(iter->second == 1); ++iter; CHECK(iter->second == 2); ++iter; CHECK(iter->second == 0); ++iter; CHECK(iter == map.end()); TestMap::iterator new_iter = map.find("zot"); CHECK(new_iter == map.end()); new_iter = map.find("bar"); CHECK(new_iter != map.end()); map.erase(new_iter); CHECK(map.size() == 2); iter = map.begin(); CHECK(iter->second == 2); ++iter; CHECK(iter->second == 0); ++iter; CHECK(iter == map.end()); } static void CheckComparisonOperators() { #define CMP_Y(op, x, y) \ CHECK( (StringPiece((x)) op StringPiece((y)))); \ CHECK( (StringPiece((x)).compare(StringPiece((y))) op 0)) #define CMP_N(op, x, y) \ CHECK(!(StringPiece((x)) op StringPiece((y)))); \ CHECK(!(StringPiece((x)).compare(StringPiece((y))) op 0)) CMP_Y(==, "", ""); CMP_Y(==, "a", "a"); CMP_Y(==, "aa", "aa"); CMP_N(==, "a", ""); CMP_N(==, "", "a"); CMP_N(==, "a", "b"); CMP_N(==, "a", "aa"); CMP_N(==, "aa", "a"); CMP_N(!=, "", ""); CMP_N(!=, "a", "a"); CMP_N(!=, "aa", "aa"); CMP_Y(!=, "a", ""); CMP_Y(!=, "", "a"); CMP_Y(!=, "a", "b"); CMP_Y(!=, "a", "aa"); CMP_Y(!=, "aa", "a"); CMP_Y(<, "a", "b"); CMP_Y(<, "a", "aa"); CMP_Y(<, "aa", "b"); CMP_Y(<, "aa", "bb"); CMP_N(<, "a", "a"); CMP_N(<, "b", "a"); CMP_N(<, "aa", "a"); CMP_N(<, "b", "aa"); CMP_N(<, "bb", "aa"); CMP_Y(<=, "a", "a"); CMP_Y(<=, "a", "b"); CMP_Y(<=, "a", "aa"); CMP_Y(<=, "aa", "b"); CMP_Y(<=, "aa", "bb"); CMP_N(<=, "b", "a"); CMP_N(<=, "aa", "a"); CMP_N(<=, "b", "aa"); CMP_N(<=, "bb", "aa"); CMP_N(>=, "a", "b"); CMP_N(>=, "a", "aa"); CMP_N(>=, "aa", "b"); CMP_N(>=, "aa", "bb"); CMP_Y(>=, "a", "a"); CMP_Y(>=, "b", "a"); CMP_Y(>=, "aa", "a"); CMP_Y(>=, "b", "aa"); CMP_Y(>=, "bb", "aa"); CMP_N(>, "a", "a"); CMP_N(>, "a", "b"); CMP_N(>, "a", "aa"); CMP_N(>, "aa", "b"); CMP_N(>, "aa", "bb"); CMP_Y(>, "b", "a"); CMP_Y(>, "aa", "a"); CMP_Y(>, "b", "aa"); CMP_Y(>, "bb", "aa"); #undef CMP_Y #undef CMP_N } int main(int argc, char** argv) { CheckComparisonOperators(); CheckSTLComparator(); printf("OK\n"); return 0; } libsynthesis-3.4.0.47.1/src/pcre/pcre_study.c000066400000000000000000000424351226375725500207210ustar00rootroot00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2007 University of Cambridge ----------------------------------------------------------------------------- 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 name of the University of Cambridge 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. ----------------------------------------------------------------------------- */ /* This module contains the external function pcre_study(), along with local supporting functions. */ #include "pcre_setup.h" #include "pcre_internal.h" /* Returns from set_start_bits() */ enum { SSB_FAIL, SSB_DONE, SSB_CONTINUE }; /************************************************* * Set a bit and maybe its alternate case * *************************************************/ /* Given a character, set its bit in the table, and also the bit for the other version of a letter if we are caseless. Arguments: start_bits points to the bit map c is the character caseless the caseless flag cd the block with char table pointers Returns: nothing */ static void set_bit(uschar *start_bits, unsigned int c, BOOL caseless, compile_data *cd) { start_bits[c/8] |= (1 << (c&7)); if (caseless && (cd->ctypes[c] & ctype_letter) != 0) start_bits[cd->fcc[c]/8] |= (1 << (cd->fcc[c]&7)); } /************************************************* * Create bitmap of starting bytes * *************************************************/ /* This function scans a compiled unanchored expression recursively and attempts to build a bitmap of the set of possible starting bytes. As time goes by, we may be able to get more clever at doing this. The SSB_CONTINUE return is useful for parenthesized groups in patterns such as (a*)b where the group provides some optional starting bytes but scanning must continue at the outer level to find at least one mandatory byte. At the outermost level, this function fails unless the result is SSB_DONE. Arguments: code points to an expression start_bits points to a 32-byte table, initialized to 0 caseless the current state of the caseless flag utf8 TRUE if in UTF-8 mode cd the block with char table pointers Returns: SSB_FAIL => Failed to find any starting bytes SSB_DONE => Found mandatory starting bytes SSB_CONTINUE => Found optional starting bytes */ static int set_start_bits(const uschar *code, uschar *start_bits, BOOL caseless, BOOL utf8, compile_data *cd) { register int c; int yield = SSB_DONE; #if 0 /* ========================================================================= */ /* The following comment and code was inserted in January 1999. In May 2006, when it was observed to cause compiler warnings about unused values, I took it out again. If anybody is still using OS/2, they will have to put it back manually. */ /* This next statement and the later reference to dummy are here in order to trick the optimizer of the IBM C compiler for OS/2 into generating correct code. Apparently IBM isn't going to fix the problem, and we would rather not disable optimization (in this module it actually makes a big difference, and the pcre module can use all the optimization it can get). */ volatile int dummy; /* ========================================================================= */ #endif do { const uschar *tcode = code + (((int)*code == OP_CBRA)? 3:1) + LINK_SIZE; BOOL try_next = TRUE; while (try_next) /* Loop for items in this branch */ { int rc; switch(*tcode) { /* Fail if we reach something we don't understand */ default: return SSB_FAIL; /* If we hit a bracket or a positive lookahead assertion, recurse to set bits from within the subpattern. If it can't find anything, we have to give up. If it finds some mandatory character(s), we are done for this branch. Otherwise, carry on scanning after the subpattern. */ case OP_BRA: case OP_SBRA: case OP_CBRA: case OP_SCBRA: case OP_ONCE: case OP_ASSERT: rc = set_start_bits(tcode, start_bits, caseless, utf8, cd); if (rc == SSB_FAIL) return SSB_FAIL; if (rc == SSB_DONE) try_next = FALSE; else { do tcode += GET(tcode, 1); while (*tcode == OP_ALT); tcode += 1 + LINK_SIZE; } break; /* If we hit ALT or KET, it means we haven't found anything mandatory in this branch, though we might have found something optional. For ALT, we continue with the next alternative, but we have to arrange that the final result from subpattern is SSB_CONTINUE rather than SSB_DONE. For KET, return SSB_CONTINUE: if this is the top level, that indicates failure, but after a nested subpattern, it causes scanning to continue. */ case OP_ALT: yield = SSB_CONTINUE; try_next = FALSE; break; case OP_KET: case OP_KETRMAX: case OP_KETRMIN: return SSB_CONTINUE; /* Skip over callout */ case OP_CALLOUT: tcode += 2 + 2*LINK_SIZE; break; /* Skip over lookbehind and negative lookahead assertions */ case OP_ASSERT_NOT: case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: do tcode += GET(tcode, 1); while (*tcode == OP_ALT); tcode += 1 + LINK_SIZE; break; /* Skip over an option setting, changing the caseless flag */ case OP_OPT: caseless = (tcode[1] & PCRE_CASELESS) != 0; tcode += 2; break; /* BRAZERO does the bracket, but carries on. */ case OP_BRAZERO: case OP_BRAMINZERO: if (set_start_bits(++tcode, start_bits, caseless, utf8, cd) == SSB_FAIL) return SSB_FAIL; /* ========================================================================= See the comment at the head of this function concerning the next line, which was an old fudge for the benefit of OS/2. dummy = 1; ========================================================================= */ do tcode += GET(tcode,1); while (*tcode == OP_ALT); tcode += 1 + LINK_SIZE; break; /* Single-char * or ? sets the bit and tries the next item */ case OP_STAR: case OP_MINSTAR: case OP_POSSTAR: case OP_QUERY: case OP_MINQUERY: case OP_POSQUERY: set_bit(start_bits, tcode[1], caseless, cd); tcode += 2; #ifdef SUPPORT_UTF8 if (utf8 && tcode[-1] >= 0xc0) tcode += _pcre_utf8_table4[tcode[-1] & 0x3f]; #endif break; /* Single-char upto sets the bit and tries the next */ case OP_UPTO: case OP_MINUPTO: case OP_POSUPTO: set_bit(start_bits, tcode[3], caseless, cd); tcode += 4; #ifdef SUPPORT_UTF8 if (utf8 && tcode[-1] >= 0xc0) tcode += _pcre_utf8_table4[tcode[-1] & 0x3f]; #endif break; /* At least one single char sets the bit and stops */ case OP_EXACT: /* Fall through */ tcode += 2; case OP_CHAR: case OP_CHARNC: case OP_PLUS: case OP_MINPLUS: case OP_POSPLUS: set_bit(start_bits, tcode[1], caseless, cd); try_next = FALSE; break; /* Single character type sets the bits and stops */ case OP_NOT_DIGIT: for (c = 0; c < 32; c++) start_bits[c] |= ~cd->cbits[c+cbit_digit]; try_next = FALSE; break; case OP_DIGIT: for (c = 0; c < 32; c++) start_bits[c] |= cd->cbits[c+cbit_digit]; try_next = FALSE; break; /* The cbit_space table has vertical tab as whitespace; we have to discard it. */ case OP_NOT_WHITESPACE: for (c = 0; c < 32; c++) { int d = cd->cbits[c+cbit_space]; if (c == 1) d &= ~0x08; start_bits[c] |= ~d; } try_next = FALSE; break; /* The cbit_space table has vertical tab as whitespace; we have to discard it. */ case OP_WHITESPACE: for (c = 0; c < 32; c++) { int d = cd->cbits[c+cbit_space]; if (c == 1) d &= ~0x08; start_bits[c] |= d; } try_next = FALSE; break; case OP_NOT_WORDCHAR: for (c = 0; c < 32; c++) start_bits[c] |= ~cd->cbits[c+cbit_word]; try_next = FALSE; break; case OP_WORDCHAR: for (c = 0; c < 32; c++) start_bits[c] |= cd->cbits[c+cbit_word]; try_next = FALSE; break; /* One or more character type fudges the pointer and restarts, knowing it will hit a single character type and stop there. */ case OP_TYPEPLUS: case OP_TYPEMINPLUS: tcode++; break; case OP_TYPEEXACT: tcode += 3; break; /* Zero or more repeats of character types set the bits and then try again. */ case OP_TYPEUPTO: case OP_TYPEMINUPTO: case OP_TYPEPOSUPTO: tcode += 2; /* Fall through */ case OP_TYPESTAR: case OP_TYPEMINSTAR: case OP_TYPEPOSSTAR: case OP_TYPEQUERY: case OP_TYPEMINQUERY: case OP_TYPEPOSQUERY: switch(tcode[1]) { case OP_ANY: return SSB_FAIL; case OP_NOT_DIGIT: for (c = 0; c < 32; c++) start_bits[c] |= ~cd->cbits[c+cbit_digit]; break; case OP_DIGIT: for (c = 0; c < 32; c++) start_bits[c] |= cd->cbits[c+cbit_digit]; break; /* The cbit_space table has vertical tab as whitespace; we have to discard it. */ case OP_NOT_WHITESPACE: for (c = 0; c < 32; c++) { int d = cd->cbits[c+cbit_space]; if (c == 1) d &= ~0x08; start_bits[c] |= ~d; } break; /* The cbit_space table has vertical tab as whitespace; we have to discard it. */ case OP_WHITESPACE: for (c = 0; c < 32; c++) { int d = cd->cbits[c+cbit_space]; if (c == 1) d &= ~0x08; start_bits[c] |= d; } break; case OP_NOT_WORDCHAR: for (c = 0; c < 32; c++) start_bits[c] |= ~cd->cbits[c+cbit_word]; break; case OP_WORDCHAR: for (c = 0; c < 32; c++) start_bits[c] |= cd->cbits[c+cbit_word]; break; } tcode += 2; break; /* Character class where all the information is in a bit map: set the bits and either carry on or not, according to the repeat count. If it was a negative class, and we are operating with UTF-8 characters, any byte with a value >= 0xc4 is a potentially valid starter because it starts a character with a value > 255. */ case OP_NCLASS: #ifdef SUPPORT_UTF8 if (utf8) { start_bits[24] |= 0xf0; /* Bits for 0xc4 - 0xc8 */ memset(start_bits+25, 0xff, 7); /* Bits for 0xc9 - 0xff */ } #endif /* Fall through */ case OP_CLASS: { tcode++; /* In UTF-8 mode, the bits in a bit map correspond to character values, not to byte values. However, the bit map we are constructing is for byte values. So we have to do a conversion for characters whose value is > 127. In fact, there are only two possible starting bytes for characters in the range 128 - 255. */ #ifdef SUPPORT_UTF8 if (utf8) { for (c = 0; c < 16; c++) start_bits[c] |= tcode[c]; for (c = 128; c < 256; c++) { if ((tcode[c/8] && (1 << (c&7))) != 0) { int d = (c >> 6) | 0xc0; /* Set bit for this starter */ start_bits[d/8] |= (1 << (d&7)); /* and then skip on to the */ c = (c & 0xc0) + 0x40 - 1; /* next relevant character. */ } } } /* In non-UTF-8 mode, the two bit maps are completely compatible. */ else #endif { for (c = 0; c < 32; c++) start_bits[c] |= tcode[c]; } /* Advance past the bit map, and act on what follows */ tcode += 32; switch (*tcode) { case OP_CRSTAR: case OP_CRMINSTAR: case OP_CRQUERY: case OP_CRMINQUERY: tcode++; break; case OP_CRRANGE: case OP_CRMINRANGE: if (((tcode[1] << 8) + tcode[2]) == 0) tcode += 5; else try_next = FALSE; break; default: try_next = FALSE; break; } } break; /* End of bitmap class handling */ } /* End of switch */ } /* End of try_next loop */ code += GET(code, 1); /* Advance to next branch */ } while (*code == OP_ALT); return yield; } /************************************************* * Study a compiled expression * *************************************************/ /* This function is handed a compiled expression that it must study to produce information that will speed up the matching. It returns a pcre_extra block which then gets handed back to pcre_exec(). Arguments: re points to the compiled expression options contains option bits errorptr points to where to place error messages; set NULL unless error Returns: pointer to a pcre_extra block, with study_data filled in and the appropriate flag set; NULL on error or if no optimization possible */ PCRE_EXP_DEFN pcre_extra * pcre_study(const pcre *external_re, int options, const char **errorptr) { uschar start_bits[32]; pcre_extra *extra; pcre_study_data *study; const uschar *tables; uschar *code; compile_data compile_block; const real_pcre *re = (const real_pcre *)external_re; *errorptr = NULL; if (re == NULL || re->magic_number != MAGIC_NUMBER) { *errorptr = "argument is not a compiled regular expression"; return NULL; } if ((options & ~PUBLIC_STUDY_OPTIONS) != 0) { *errorptr = "unknown or incorrect option bit(s) set"; return NULL; } code = (uschar *)re + re->name_table_offset + (re->name_count * re->name_entry_size); /* For an anchored pattern, or an unanchored pattern that has a first char, or a multiline pattern that matches only at "line starts", no further processing at present. */ if ((re->options & (PCRE_ANCHORED|PCRE_FIRSTSET|PCRE_STARTLINE)) != 0) return NULL; /* Set the character tables in the block that is passed around */ tables = re->tables; if (tables == NULL) (void)pcre_fullinfo(external_re, NULL, PCRE_INFO_DEFAULT_TABLES, (void *)(&tables)); compile_block.lcc = tables + lcc_offset; compile_block.fcc = tables + fcc_offset; compile_block.cbits = tables + cbits_offset; compile_block.ctypes = tables + ctypes_offset; /* See if we can find a fixed set of initial characters for the pattern. */ memset(start_bits, 0, 32 * sizeof(uschar)); if (set_start_bits(code, start_bits, (re->options & PCRE_CASELESS) != 0, (re->options & PCRE_UTF8) != 0, &compile_block) != SSB_DONE) return NULL; /* Get a pcre_extra block and a pcre_study_data block. The study data is put in the latter, which is pointed to by the former, which may also get additional data set later by the calling program. At the moment, the size of pcre_study_data is fixed. We nevertheless save it in a field for returning via the pcre_fullinfo() function so that if it becomes variable in the future, we don't have to change that code. */ extra = (pcre_extra *)(pcre_malloc) (sizeof(pcre_extra) + sizeof(pcre_study_data)); if (extra == NULL) { *errorptr = "failed to get memory"; return NULL; } study = (pcre_study_data *)((char *)extra + sizeof(pcre_extra)); extra->flags = PCRE_EXTRA_STUDY_DATA; extra->study_data = study; study->size = sizeof(pcre_study_data); study->options = PCRE_STUDY_MAPPED; memcpy(study->start_bits, start_bits, sizeof(start_bits)); return extra; } /* End of pcre_study.c */ libsynthesis-3.4.0.47.1/src/pcre/pcre_tables.c000066400000000000000000000216331226375725500210200ustar00rootroot00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2007 University of Cambridge ----------------------------------------------------------------------------- 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 name of the University of Cambridge 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. ----------------------------------------------------------------------------- */ /* This module contains some fixed tables that are used by more than one of the PCRE code modules. The tables are also #included by the pcretest program, which uses macros to change their names from _pcre_xxx to xxxx, thereby avoiding name clashes with the library. */ #include "pcre_setup.h" #include "pcre_internal.h" /* Table of sizes for the fixed-length opcodes. It's defined in a macro so that the definition is next to the definition of the opcodes in pcre_internal.h. */ const uschar _pcre_OP_lengths[] = { OP_LENGTHS }; /************************************************* * Tables for UTF-8 support * *************************************************/ /* These are the breakpoints for different numbers of bytes in a UTF-8 character. */ #ifdef SUPPORT_UTF8 const int _pcre_utf8_table1[] = { 0x7f, 0x7ff, 0xffff, 0x1fffff, 0x3ffffff, 0x7fffffff}; const int _pcre_utf8_table1_size = sizeof(_pcre_utf8_table1)/sizeof(int); /* These are the indicator bits and the mask for the data bits to set in the first byte of a character, indexed by the number of additional bytes. */ const int _pcre_utf8_table2[] = { 0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc}; const int _pcre_utf8_table3[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01}; /* Table of the number of extra bytes, indexed by the first byte masked with 0x3f. The highest number for a valid UTF-8 first byte is in fact 0x3d. */ const uschar _pcre_utf8_table4[] = { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 }; /* This table translates Unicode property names into type and code values. It is searched by binary chop, so must be in collating sequence of name. */ const ucp_type_table _pcre_utt[] = { { "Any", PT_ANY, 0 }, { "Arabic", PT_SC, ucp_Arabic }, { "Armenian", PT_SC, ucp_Armenian }, { "Balinese", PT_SC, ucp_Balinese }, { "Bengali", PT_SC, ucp_Bengali }, { "Bopomofo", PT_SC, ucp_Bopomofo }, { "Braille", PT_SC, ucp_Braille }, { "Buginese", PT_SC, ucp_Buginese }, { "Buhid", PT_SC, ucp_Buhid }, { "C", PT_GC, ucp_C }, { "Canadian_Aboriginal", PT_SC, ucp_Canadian_Aboriginal }, { "Cc", PT_PC, ucp_Cc }, { "Cf", PT_PC, ucp_Cf }, { "Cherokee", PT_SC, ucp_Cherokee }, { "Cn", PT_PC, ucp_Cn }, { "Co", PT_PC, ucp_Co }, { "Common", PT_SC, ucp_Common }, { "Coptic", PT_SC, ucp_Coptic }, { "Cs", PT_PC, ucp_Cs }, { "Cuneiform", PT_SC, ucp_Cuneiform }, { "Cypriot", PT_SC, ucp_Cypriot }, { "Cyrillic", PT_SC, ucp_Cyrillic }, { "Deseret", PT_SC, ucp_Deseret }, { "Devanagari", PT_SC, ucp_Devanagari }, { "Ethiopic", PT_SC, ucp_Ethiopic }, { "Georgian", PT_SC, ucp_Georgian }, { "Glagolitic", PT_SC, ucp_Glagolitic }, { "Gothic", PT_SC, ucp_Gothic }, { "Greek", PT_SC, ucp_Greek }, { "Gujarati", PT_SC, ucp_Gujarati }, { "Gurmukhi", PT_SC, ucp_Gurmukhi }, { "Han", PT_SC, ucp_Han }, { "Hangul", PT_SC, ucp_Hangul }, { "Hanunoo", PT_SC, ucp_Hanunoo }, { "Hebrew", PT_SC, ucp_Hebrew }, { "Hiragana", PT_SC, ucp_Hiragana }, { "Inherited", PT_SC, ucp_Inherited }, { "Kannada", PT_SC, ucp_Kannada }, { "Katakana", PT_SC, ucp_Katakana }, { "Kharoshthi", PT_SC, ucp_Kharoshthi }, { "Khmer", PT_SC, ucp_Khmer }, { "L", PT_GC, ucp_L }, { "L&", PT_LAMP, 0 }, { "Lao", PT_SC, ucp_Lao }, { "Latin", PT_SC, ucp_Latin }, { "Limbu", PT_SC, ucp_Limbu }, { "Linear_B", PT_SC, ucp_Linear_B }, { "Ll", PT_PC, ucp_Ll }, { "Lm", PT_PC, ucp_Lm }, { "Lo", PT_PC, ucp_Lo }, { "Lt", PT_PC, ucp_Lt }, { "Lu", PT_PC, ucp_Lu }, { "M", PT_GC, ucp_M }, { "Malayalam", PT_SC, ucp_Malayalam }, { "Mc", PT_PC, ucp_Mc }, { "Me", PT_PC, ucp_Me }, { "Mn", PT_PC, ucp_Mn }, { "Mongolian", PT_SC, ucp_Mongolian }, { "Myanmar", PT_SC, ucp_Myanmar }, { "N", PT_GC, ucp_N }, { "Nd", PT_PC, ucp_Nd }, { "New_Tai_Lue", PT_SC, ucp_New_Tai_Lue }, { "Nko", PT_SC, ucp_Nko }, { "Nl", PT_PC, ucp_Nl }, { "No", PT_PC, ucp_No }, { "Ogham", PT_SC, ucp_Ogham }, { "Old_Italic", PT_SC, ucp_Old_Italic }, { "Old_Persian", PT_SC, ucp_Old_Persian }, { "Oriya", PT_SC, ucp_Oriya }, { "Osmanya", PT_SC, ucp_Osmanya }, { "P", PT_GC, ucp_P }, { "Pc", PT_PC, ucp_Pc }, { "Pd", PT_PC, ucp_Pd }, { "Pe", PT_PC, ucp_Pe }, { "Pf", PT_PC, ucp_Pf }, { "Phags_Pa", PT_SC, ucp_Phags_Pa }, { "Phoenician", PT_SC, ucp_Phoenician }, { "Pi", PT_PC, ucp_Pi }, { "Po", PT_PC, ucp_Po }, { "Ps", PT_PC, ucp_Ps }, { "Runic", PT_SC, ucp_Runic }, { "S", PT_GC, ucp_S }, { "Sc", PT_PC, ucp_Sc }, { "Shavian", PT_SC, ucp_Shavian }, { "Sinhala", PT_SC, ucp_Sinhala }, { "Sk", PT_PC, ucp_Sk }, { "Sm", PT_PC, ucp_Sm }, { "So", PT_PC, ucp_So }, { "Syloti_Nagri", PT_SC, ucp_Syloti_Nagri }, { "Syriac", PT_SC, ucp_Syriac }, { "Tagalog", PT_SC, ucp_Tagalog }, { "Tagbanwa", PT_SC, ucp_Tagbanwa }, { "Tai_Le", PT_SC, ucp_Tai_Le }, { "Tamil", PT_SC, ucp_Tamil }, { "Telugu", PT_SC, ucp_Telugu }, { "Thaana", PT_SC, ucp_Thaana }, { "Thai", PT_SC, ucp_Thai }, { "Tibetan", PT_SC, ucp_Tibetan }, { "Tifinagh", PT_SC, ucp_Tifinagh }, { "Ugaritic", PT_SC, ucp_Ugaritic }, { "Yi", PT_SC, ucp_Yi }, { "Z", PT_GC, ucp_Z }, { "Zl", PT_PC, ucp_Zl }, { "Zp", PT_PC, ucp_Zp }, { "Zs", PT_PC, ucp_Zs } }; const int _pcre_utt_size = sizeof(_pcre_utt)/sizeof(ucp_type_table); #endif /* SUPPORT_UTF8 */ /* End of pcre_tables.c */ libsynthesis-3.4.0.47.1/src/pcre/pcre_try_flipped.c000066400000000000000000000124031226375725500220620ustar00rootroot00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2007 University of Cambridge ----------------------------------------------------------------------------- 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 name of the University of Cambridge 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. ----------------------------------------------------------------------------- */ /* This module contains an internal function that tests a compiled pattern to see if it was compiled with the opposite endianness. If so, it uses an auxiliary local function to flip the appropriate bytes. */ #include "pcre_setup.h" #include "pcre_internal.h" /************************************************* * Flip bytes in an integer * *************************************************/ /* This function is called when the magic number in a regex doesn't match, in order to flip its bytes to see if we are dealing with a pattern that was compiled on a host of different endianness. If so, this function is used to flip other byte values. Arguments: value the number to flip n the number of bytes to flip (assumed to be 2 or 4) Returns: the flipped value */ static unsigned long int byteflip(unsigned long int value, int n) { if (n == 2) return ((value & 0x00ff) << 8) | ((value & 0xff00) >> 8); return ((value & 0x000000ff) << 24) | ((value & 0x0000ff00) << 8) | ((value & 0x00ff0000) >> 8) | ((value & 0xff000000) >> 24); } /************************************************* * Test for a byte-flipped compiled regex * *************************************************/ /* This function is called from pcre_exec(), pcre_dfa_exec(), and also from pcre_fullinfo(). Its job is to test whether the regex is byte-flipped - that is, it was compiled on a system of opposite endianness. The function is called only when the native MAGIC_NUMBER test fails. If the regex is indeed flipped, we flip all the relevant values into a different data block, and return it. Arguments: re points to the regex study points to study data, or NULL internal_re points to a new regex block internal_study points to a new study block Returns: the new block if is is indeed a byte-flipped regex NULL if it is not */ real_pcre * _pcre_try_flipped(const real_pcre *re, real_pcre *internal_re, const pcre_study_data *study, pcre_study_data *internal_study) { if (byteflip(re->magic_number, sizeof(re->magic_number)) != MAGIC_NUMBER) return NULL; *internal_re = *re; /* To copy other fields */ internal_re->size = byteflip(re->size, sizeof(re->size)); internal_re->options = byteflip(re->options, sizeof(re->options)); internal_re->top_bracket = (pcre_uint16)byteflip(re->top_bracket, sizeof(re->top_bracket)); internal_re->top_backref = (pcre_uint16)byteflip(re->top_backref, sizeof(re->top_backref)); internal_re->first_byte = (pcre_uint16)byteflip(re->first_byte, sizeof(re->first_byte)); internal_re->req_byte = (pcre_uint16)byteflip(re->req_byte, sizeof(re->req_byte)); internal_re->name_table_offset = (pcre_uint16)byteflip(re->name_table_offset, sizeof(re->name_table_offset)); internal_re->name_entry_size = (pcre_uint16)byteflip(re->name_entry_size, sizeof(re->name_entry_size)); internal_re->name_count = (pcre_uint16)byteflip(re->name_count, sizeof(re->name_count)); if (study != NULL) { *internal_study = *study; /* To copy other fields */ internal_study->size = byteflip(study->size, sizeof(study->size)); internal_study->options = byteflip(study->options, sizeof(study->options)); } return internal_re; } /* End of pcre_tryflipped.c */ libsynthesis-3.4.0.47.1/src/pcre/pcre_ucp_searchfuncs.c000066400000000000000000000137051226375725500227220ustar00rootroot00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2007 University of Cambridge ----------------------------------------------------------------------------- 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 name of the University of Cambridge 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. ----------------------------------------------------------------------------- */ /* This module contains code for searching the table of Unicode character properties. */ #include "pcre_setup.h" #include "pcre_internal.h" #include "ucp.h" /* Category definitions */ #include "ucpinternal.h" /* Internal table details */ #include "ucptable.h" /* The table itself */ /* Table to translate from particular type value to the general value. */ static const int ucp_gentype[] = { ucp_C, ucp_C, ucp_C, ucp_C, ucp_C, /* Cc, Cf, Cn, Co, Cs */ ucp_L, ucp_L, ucp_L, ucp_L, ucp_L, /* Ll, Lu, Lm, Lo, Lt */ ucp_M, ucp_M, ucp_M, /* Mc, Me, Mn */ ucp_N, ucp_N, ucp_N, /* Nd, Nl, No */ ucp_P, ucp_P, ucp_P, ucp_P, ucp_P, /* Pc, Pd, Pe, Pf, Pi */ ucp_P, ucp_P, /* Ps, Po */ ucp_S, ucp_S, ucp_S, ucp_S, /* Sc, Sk, Sm, So */ ucp_Z, ucp_Z, ucp_Z /* Zl, Zp, Zs */ }; /************************************************* * Search table and return type * *************************************************/ /* Three values are returned: the category is ucp_C, ucp_L, etc. The detailed character type is ucp_Lu, ucp_Nd, etc. The script is ucp_Latin, etc. Arguments: c the character value type_ptr the detailed character type is returned here script_ptr the script is returned here Returns: the character type category */ int _pcre_ucp_findprop(const unsigned int c, int *type_ptr, int *script_ptr) { int bot = 0; int top = sizeof(ucp_table)/sizeof(cnode); int mid; /* The table is searched using a binary chop. You might think that using intermediate variables to hold some of the common expressions would speed things up, but tests with gcc 3.4.4 on Linux showed that, on the contrary, it makes things a lot slower. */ for (;;) { if (top <= bot) { *type_ptr = ucp_Cn; *script_ptr = ucp_Common; return ucp_C; } mid = (bot + top) >> 1; if (c == (ucp_table[mid].f0 & f0_charmask)) break; if (c < (ucp_table[mid].f0 & f0_charmask)) top = mid; else { if ((ucp_table[mid].f0 & f0_rangeflag) != 0 && c <= (ucp_table[mid].f0 & f0_charmask) + (ucp_table[mid].f1 & f1_rangemask)) break; bot = mid + 1; } } /* Found an entry in the table. Set the script and detailed type values, and return the general type. */ *script_ptr = (ucp_table[mid].f0 & f0_scriptmask) >> f0_scriptshift; *type_ptr = (ucp_table[mid].f1 & f1_typemask) >> f1_typeshift; return ucp_gentype[*type_ptr]; } /************************************************* * Search table and return other case * *************************************************/ /* If the given character is a letter, and there is another case for the letter, return the other case. Otherwise, return -1. Arguments: c the character value Returns: the other case or NOTACHAR if none */ unsigned int _pcre_ucp_othercase(const unsigned int c) { int bot = 0; int top = sizeof(ucp_table)/sizeof(cnode); int mid, offset; /* The table is searched using a binary chop. You might think that using intermediate variables to hold some of the common expressions would speed things up, but tests with gcc 3.4.4 on Linux showed that, on the contrary, it makes things a lot slower. */ for (;;) { if (top <= bot) return -1; mid = (bot + top) >> 1; if (c == (ucp_table[mid].f0 & f0_charmask)) break; if (c < (ucp_table[mid].f0 & f0_charmask)) top = mid; else { if ((ucp_table[mid].f0 & f0_rangeflag) != 0 && c <= (ucp_table[mid].f0 & f0_charmask) + (ucp_table[mid].f1 & f1_rangemask)) break; bot = mid + 1; } } /* Found an entry in the table. Return NOTACHAR for a range entry. Otherwise return the other case if there is one, else NOTACHAR. */ if ((ucp_table[mid].f0 & f0_rangeflag) != 0) return NOTACHAR; offset = ucp_table[mid].f1 & f1_casemask; if ((offset & f1_caseneg) != 0) offset |= f1_caseneg; return (offset == 0)? NOTACHAR : c + offset; } /* End of pcre_ucp_searchfuncs.c */ libsynthesis-3.4.0.47.1/src/pcre/pcre_valid_utf8.c000066400000000000000000000125411226375725500216110ustar00rootroot00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2007 University of Cambridge ----------------------------------------------------------------------------- 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 name of the University of Cambridge 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. ----------------------------------------------------------------------------- */ /* This module contains an internal function for validating UTF-8 character strings. */ #include "pcre_setup.h" #include "pcre_internal.h" /************************************************* * Validate a UTF-8 string * *************************************************/ /* This function is called (optionally) at the start of compile or match, to validate that a supposed UTF-8 string is actually valid. The early check means that subsequent code can assume it is dealing with a valid string. The check can be turned off for maximum performance, but the consequences of supplying an invalid string are then undefined. Originally, this function checked according to RFC 2279, allowing for values in the range 0 to 0x7fffffff, up to 6 bytes long, but ensuring that they were in the canonical format. Once somebody had pointed out RFC 3629 to me (it obsoletes 2279), additional restrictions were applies. The values are now limited to be between 0 and 0x0010ffff, no more than 4 bytes long, and the subrange 0xd000 to 0xdfff is excluded. Arguments: string points to the string length length of string, or -1 if the string is zero-terminated Returns: < 0 if the string is a valid UTF-8 string >= 0 otherwise; the value is the offset of the bad byte */ int _pcre_valid_utf8(const uschar *string, int length) { #ifdef SUPPORT_UTF8 register const uschar *p; if (length < 0) { for (p = string; *p != 0; p++); length = p - string; } for (p = string; length-- > 0; p++) { register int ab; register int c = *p; if (c < 128) continue; if (c < 0xc0) return p - string; ab = _pcre_utf8_table4[c & 0x3f]; /* Number of additional bytes */ if (length < ab || ab > 3) return p - string; length -= ab; /* Check top bits in the second byte */ if ((*(++p) & 0xc0) != 0x80) return p - string; /* Check for overlong sequences for each different length, and for the excluded range 0xd000 to 0xdfff. */ switch (ab) { /* Check for xx00 000x (overlong sequence) */ case 1: if ((c & 0x3e) == 0) return p - string; continue; /* We know there aren't any more bytes to check */ /* Check for 1110 0000, xx0x xxxx (overlong sequence) or 1110 1101, 1010 xxxx (0xd000 - 0xdfff) */ case 2: if ((c == 0xe0 && (*p & 0x20) == 0) || (c == 0xed && *p >= 0xa0)) return p - string; break; /* Check for 1111 0000, xx00 xxxx (overlong sequence) or greater than 0x0010ffff (f4 8f bf bf) */ case 3: if ((c == 0xf0 && (*p & 0x30) == 0) || (c > 0xf4 ) || (c == 0xf4 && *p > 0x8f)) return p - string; break; #if 0 /* These cases can no longer occur, as we restrict to a maximum of four bytes nowadays. Leave the code here in case we ever want to add an option for longer sequences. */ /* Check for 1111 1000, xx00 0xxx */ case 4: if (c == 0xf8 && (*p & 0x38) == 0) return p - string; break; /* Check for leading 0xfe or 0xff, and then for 1111 1100, xx00 00xx */ case 5: if (c == 0xfe || c == 0xff || (c == 0xfc && (*p & 0x3c) == 0)) return p - string; break; #endif } /* Check for valid bytes after the 2nd, if any; all must start 10 */ while (--ab > 0) { if ((*(++p) & 0xc0) != 0x80) return p - string; } } #endif return -1; } /* End of pcre_valid_utf8.c */ libsynthesis-3.4.0.47.1/src/pcre/pcre_version.c000066400000000000000000000075301226375725500212330ustar00rootroot00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2007 University of Cambridge ----------------------------------------------------------------------------- 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 name of the University of Cambridge 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. ----------------------------------------------------------------------------- */ /* This module contains the external function pcre_version(), which returns a string that identifies the PCRE version that is in use. */ #include "pcre_setup.h" #include "pcre_internal.h" /************************************************* * Return version string * *************************************************/ /* These macros are the standard way of turning unquoted text into C strings. They allow macros like PCRE_MAJOR to be defined without quotes, which is convenient for user programs that want to test its value. */ #define STRING(a) # a #define XSTRING(s) STRING(s) /* A problem turned up with PCRE_PRERELEASE, which is defined empty for production releases. Originally, it was used naively in this code: return XSTRING(PCRE_MAJOR) "." XSTRING(PCRE_MINOR) XSTRING(PCRE_PRERELEASE) " " XSTRING(PCRE_DATE); However, when PCRE_PRERELEASE is empty, this leads to an attempted expansion of STRING(). The C standard states: "If (before argument substitution) any argument consists of no preprocessing tokens, the behavior is undefined." It turns out the gcc treats this case as a single empty string - which is what we really want - but Visual C grumbles about the lack of an argument for the macro. Unfortunately, both are within their rights. To cope with both ways of handling this, I had resort to some messy hackery that does a test at run time. I could find no way of detecting that a macro is defined as an empty string at pre-processor time. This hack uses a standard trick for avoiding calling the STRING macro with an empty argument when doing the test. */ PCRE_EXP_DEFN const char * pcre_version(void) { return (XSTRING(Z PCRE_PRERELEASE)[1] == 0)? XSTRING(PCRE_MAJOR.PCRE_MINOR PCRE_DATE) : XSTRING(PCRE_MAJOR.PCRE_MINOR) XSTRING(PCRE_PRERELEASE PCRE_DATE); } /* End of pcre_version.c */ libsynthesis-3.4.0.47.1/src/pcre/pcre_xclass.c000066400000000000000000000110301226375725500210310ustar00rootroot00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2007 University of Cambridge ----------------------------------------------------------------------------- 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 name of the University of Cambridge 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. ----------------------------------------------------------------------------- */ /* This module contains an internal function that is used to match an extended class (one that contains characters whose values are > 255). It is used by both pcre_exec() and pcre_def_exec(). */ #include "pcre_setup.h" #include "pcre_internal.h" /************************************************* * Match character against an XCLASS * *************************************************/ /* This function is called to match a character against an extended class that might contain values > 255. Arguments: c the character data points to the flag byte of the XCLASS data Returns: TRUE if character matches, else FALSE */ BOOL _pcre_xclass(int c, const uschar *data) { int t; BOOL negated = (*data & XCL_NOT) != 0; /* Character values < 256 are matched against a bitmap, if one is present. If not, we still carry on, because there may be ranges that start below 256 in the additional data. */ if (c < 256) { if ((*data & XCL_MAP) != 0 && (data[1 + c/8] & (1 << (c&7))) != 0) return !negated; /* char found */ } /* First skip the bit map if present. Then match against the list of Unicode properties or large chars or ranges that end with a large char. We won't ever encounter XCL_PROP or XCL_NOTPROP when UCP support is not compiled. */ if ((*data++ & XCL_MAP) != 0) data += 32; while ((t = *data++) != XCL_END) { int x, y; if (t == XCL_SINGLE) { GETCHARINC(x, data); if (c == x) return !negated; } else if (t == XCL_RANGE) { GETCHARINC(x, data); GETCHARINC(y, data); if (c >= x && c <= y) return !negated; } #ifdef SUPPORT_UCP else /* XCL_PROP & XCL_NOTPROP */ { int chartype, script; int category = _pcre_ucp_findprop(c, &chartype, &script); switch(*data) { case PT_ANY: if (t == XCL_PROP) return !negated; break; case PT_LAMP: if ((chartype == ucp_Lu || chartype == ucp_Ll || chartype == ucp_Lt) == (t == XCL_PROP)) return !negated; break; case PT_GC: if ((data[1] == category) == (t == XCL_PROP)) return !negated; break; case PT_PC: if ((data[1] == chartype) == (t == XCL_PROP)) return !negated; break; case PT_SC: if ((data[1] == script) == (t == XCL_PROP)) return !negated; break; /* This should never occur, but compilers may mutter if there is no default. */ default: return FALSE; } data += 2; } #endif /* SUPPORT_UCP */ } return negated; /* char did not match */ } /* End of pcre_xclass.c */ libsynthesis-3.4.0.47.1/src/pcre/pcrecpp.cc000066400000000000000000000706251226375725500203410ustar00rootroot00000000000000// Copyright (c) 2005, Google Inc. // 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 name of Google Inc. 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. // // Author: Sanjay Ghemawat #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include /* for SHRT_MIN, USHRT_MAX, etc */ #include #include #include #include #include "pcrecpp_internal.h" #include #include "pcrecpp.h" #include "pcre_stringpiece.h" namespace pcrecpp { // Maximum number of args we can set static const int kMaxArgs = 16; static const int kVecSize = (1 + kMaxArgs) * 3; // results + PCRE workspace // Special object that stands-in for no argument PCRECPP_EXP_DEFN Arg no_arg((void*)NULL); // If a regular expression has no error, its error_ field points here static const string empty_string; // If the user doesn't ask for any options, we just use this one static RE_Options default_options; void RE::Init(const string& pat, const RE_Options* options) { pattern_ = pat; if (options == NULL) { options_ = default_options; } else { options_ = *options; } error_ = &empty_string; re_full_ = NULL; re_partial_ = NULL; re_partial_ = Compile(UNANCHORED); if (re_partial_ != NULL) { re_full_ = Compile(ANCHOR_BOTH); } } void RE::Cleanup() { if (re_full_ != NULL) (*pcre_free)(re_full_); if (re_partial_ != NULL) (*pcre_free)(re_partial_); if (error_ != &empty_string) delete error_; } RE::~RE() { Cleanup(); } pcre* RE::Compile(Anchor anchor) { // First, convert RE_Options into pcre options int pcre_options = 0; pcre_options = options_.all_options(); // Special treatment for anchoring. This is needed because at // runtime pcre only provides an option for anchoring at the // beginning of a string (unless you use offset). // // There are three types of anchoring we want: // UNANCHORED Compile the original pattern, and use // a pcre unanchored match. // ANCHOR_START Compile the original pattern, and use // a pcre anchored match. // ANCHOR_BOTH Tack a "\z" to the end of the original pattern // and use a pcre anchored match. const char* compile_error; int eoffset; pcre* re; if (anchor != ANCHOR_BOTH) { re = pcre_compile(pattern_.c_str(), pcre_options, &compile_error, &eoffset, NULL); } else { // Tack a '\z' at the end of RE. Parenthesize it first so that // the '\z' applies to all top-level alternatives in the regexp. string wrapped = "(?:"; // A non-counting grouping operator wrapped += pattern_; wrapped += ")\\z"; re = pcre_compile(wrapped.c_str(), pcre_options, &compile_error, &eoffset, NULL); } if (re == NULL) { if (error_ == &empty_string) error_ = new string(compile_error); } return re; } /***** Matching interfaces *****/ bool RE::FullMatch(const StringPiece& text, const Arg& ptr1, const Arg& ptr2, const Arg& ptr3, const Arg& ptr4, const Arg& ptr5, const Arg& ptr6, const Arg& ptr7, const Arg& ptr8, const Arg& ptr9, const Arg& ptr10, const Arg& ptr11, const Arg& ptr12, const Arg& ptr13, const Arg& ptr14, const Arg& ptr15, const Arg& ptr16) const { const Arg* args[kMaxArgs]; int n = 0; if (&ptr1 == &no_arg) goto done; args[n++] = &ptr1; if (&ptr2 == &no_arg) goto done; args[n++] = &ptr2; if (&ptr3 == &no_arg) goto done; args[n++] = &ptr3; if (&ptr4 == &no_arg) goto done; args[n++] = &ptr4; if (&ptr5 == &no_arg) goto done; args[n++] = &ptr5; if (&ptr6 == &no_arg) goto done; args[n++] = &ptr6; if (&ptr7 == &no_arg) goto done; args[n++] = &ptr7; if (&ptr8 == &no_arg) goto done; args[n++] = &ptr8; if (&ptr9 == &no_arg) goto done; args[n++] = &ptr9; if (&ptr10 == &no_arg) goto done; args[n++] = &ptr10; if (&ptr11 == &no_arg) goto done; args[n++] = &ptr11; if (&ptr12 == &no_arg) goto done; args[n++] = &ptr12; if (&ptr13 == &no_arg) goto done; args[n++] = &ptr13; if (&ptr14 == &no_arg) goto done; args[n++] = &ptr14; if (&ptr15 == &no_arg) goto done; args[n++] = &ptr15; if (&ptr16 == &no_arg) goto done; args[n++] = &ptr16; done: int consumed; int vec[kVecSize]; return DoMatchImpl(text, ANCHOR_BOTH, &consumed, args, n, vec, kVecSize); } bool RE::PartialMatch(const StringPiece& text, const Arg& ptr1, const Arg& ptr2, const Arg& ptr3, const Arg& ptr4, const Arg& ptr5, const Arg& ptr6, const Arg& ptr7, const Arg& ptr8, const Arg& ptr9, const Arg& ptr10, const Arg& ptr11, const Arg& ptr12, const Arg& ptr13, const Arg& ptr14, const Arg& ptr15, const Arg& ptr16) const { const Arg* args[kMaxArgs]; int n = 0; if (&ptr1 == &no_arg) goto done; args[n++] = &ptr1; if (&ptr2 == &no_arg) goto done; args[n++] = &ptr2; if (&ptr3 == &no_arg) goto done; args[n++] = &ptr3; if (&ptr4 == &no_arg) goto done; args[n++] = &ptr4; if (&ptr5 == &no_arg) goto done; args[n++] = &ptr5; if (&ptr6 == &no_arg) goto done; args[n++] = &ptr6; if (&ptr7 == &no_arg) goto done; args[n++] = &ptr7; if (&ptr8 == &no_arg) goto done; args[n++] = &ptr8; if (&ptr9 == &no_arg) goto done; args[n++] = &ptr9; if (&ptr10 == &no_arg) goto done; args[n++] = &ptr10; if (&ptr11 == &no_arg) goto done; args[n++] = &ptr11; if (&ptr12 == &no_arg) goto done; args[n++] = &ptr12; if (&ptr13 == &no_arg) goto done; args[n++] = &ptr13; if (&ptr14 == &no_arg) goto done; args[n++] = &ptr14; if (&ptr15 == &no_arg) goto done; args[n++] = &ptr15; if (&ptr16 == &no_arg) goto done; args[n++] = &ptr16; done: int consumed; int vec[kVecSize]; return DoMatchImpl(text, UNANCHORED, &consumed, args, n, vec, kVecSize); } bool RE::Consume(StringPiece* input, const Arg& ptr1, const Arg& ptr2, const Arg& ptr3, const Arg& ptr4, const Arg& ptr5, const Arg& ptr6, const Arg& ptr7, const Arg& ptr8, const Arg& ptr9, const Arg& ptr10, const Arg& ptr11, const Arg& ptr12, const Arg& ptr13, const Arg& ptr14, const Arg& ptr15, const Arg& ptr16) const { const Arg* args[kMaxArgs]; int n = 0; if (&ptr1 == &no_arg) goto done; args[n++] = &ptr1; if (&ptr2 == &no_arg) goto done; args[n++] = &ptr2; if (&ptr3 == &no_arg) goto done; args[n++] = &ptr3; if (&ptr4 == &no_arg) goto done; args[n++] = &ptr4; if (&ptr5 == &no_arg) goto done; args[n++] = &ptr5; if (&ptr6 == &no_arg) goto done; args[n++] = &ptr6; if (&ptr7 == &no_arg) goto done; args[n++] = &ptr7; if (&ptr8 == &no_arg) goto done; args[n++] = &ptr8; if (&ptr9 == &no_arg) goto done; args[n++] = &ptr9; if (&ptr10 == &no_arg) goto done; args[n++] = &ptr10; if (&ptr11 == &no_arg) goto done; args[n++] = &ptr11; if (&ptr12 == &no_arg) goto done; args[n++] = &ptr12; if (&ptr13 == &no_arg) goto done; args[n++] = &ptr13; if (&ptr14 == &no_arg) goto done; args[n++] = &ptr14; if (&ptr15 == &no_arg) goto done; args[n++] = &ptr15; if (&ptr16 == &no_arg) goto done; args[n++] = &ptr16; done: int consumed; int vec[kVecSize]; if (DoMatchImpl(*input, ANCHOR_START, &consumed, args, n, vec, kVecSize)) { input->remove_prefix(consumed); return true; } else { return false; } } bool RE::FindAndConsume(StringPiece* input, const Arg& ptr1, const Arg& ptr2, const Arg& ptr3, const Arg& ptr4, const Arg& ptr5, const Arg& ptr6, const Arg& ptr7, const Arg& ptr8, const Arg& ptr9, const Arg& ptr10, const Arg& ptr11, const Arg& ptr12, const Arg& ptr13, const Arg& ptr14, const Arg& ptr15, const Arg& ptr16) const { const Arg* args[kMaxArgs]; int n = 0; if (&ptr1 == &no_arg) goto done; args[n++] = &ptr1; if (&ptr2 == &no_arg) goto done; args[n++] = &ptr2; if (&ptr3 == &no_arg) goto done; args[n++] = &ptr3; if (&ptr4 == &no_arg) goto done; args[n++] = &ptr4; if (&ptr5 == &no_arg) goto done; args[n++] = &ptr5; if (&ptr6 == &no_arg) goto done; args[n++] = &ptr6; if (&ptr7 == &no_arg) goto done; args[n++] = &ptr7; if (&ptr8 == &no_arg) goto done; args[n++] = &ptr8; if (&ptr9 == &no_arg) goto done; args[n++] = &ptr9; if (&ptr10 == &no_arg) goto done; args[n++] = &ptr10; if (&ptr11 == &no_arg) goto done; args[n++] = &ptr11; if (&ptr12 == &no_arg) goto done; args[n++] = &ptr12; if (&ptr13 == &no_arg) goto done; args[n++] = &ptr13; if (&ptr14 == &no_arg) goto done; args[n++] = &ptr14; if (&ptr15 == &no_arg) goto done; args[n++] = &ptr15; if (&ptr16 == &no_arg) goto done; args[n++] = &ptr16; done: int consumed; int vec[kVecSize]; if (DoMatchImpl(*input, UNANCHORED, &consumed, args, n, vec, kVecSize)) { input->remove_prefix(consumed); return true; } else { return false; } } bool RE::Replace(const StringPiece& rewrite, string *str) const { int vec[kVecSize]; int matches = TryMatch(*str, 0, UNANCHORED, vec, kVecSize); if (matches == 0) return false; string s; if (!Rewrite(&s, rewrite, *str, vec, matches)) return false; assert(vec[0] >= 0); assert(vec[1] >= 0); str->replace(vec[0], vec[1] - vec[0], s); return true; } // Returns PCRE_NEWLINE_CRLF, PCRE_NEWLINE_CR, or PCRE_NEWLINE_LF. // Note that PCRE_NEWLINE_CRLF is defined to be P_N_CR | P_N_LF. static int NewlineMode(int pcre_options) { // TODO: if we can make it threadsafe, cache this var int newline_mode = 0; /* if (newline_mode) return newline_mode; */ // do this once it's cached if (pcre_options & (PCRE_NEWLINE_CRLF|PCRE_NEWLINE_CR|PCRE_NEWLINE_LF)) { newline_mode = (pcre_options & (PCRE_NEWLINE_CRLF|PCRE_NEWLINE_CR|PCRE_NEWLINE_LF)); } else { int newline; pcre_config(PCRE_CONFIG_NEWLINE, &newline); if (newline == 10) newline_mode = PCRE_NEWLINE_LF; else if (newline == 13) newline_mode = PCRE_NEWLINE_CR; else if (newline == 3338) newline_mode = PCRE_NEWLINE_CRLF; else assert("" == "Unexpected return value from pcre_config(NEWLINE)"); } return newline_mode; } int RE::GlobalReplace(const StringPiece& rewrite, string *str) const { int count = 0; int vec[kVecSize]; string out; int start = 0; int lastend = -1; for (; start <= static_cast(str->length()); count++) { int matches = TryMatch(*str, start, UNANCHORED, vec, kVecSize); if (matches <= 0) break; int matchstart = vec[0], matchend = vec[1]; assert(matchstart >= start); assert(matchend >= matchstart); if (matchstart == matchend && matchstart == lastend) { // advance one character if we matched an empty string at the same // place as the last match occurred matchend = start + 1; // If the current char is CR and we're in CRLF mode, skip LF too. // Note it's better to call pcre_fullinfo() than to examine // all_options(), since options_ could have changed bewteen // compile-time and now, but this is simpler and safe enough. if (start+1 < static_cast(str->length()) && (*str)[start] == '\r' && (*str)[start+1] == '\n' && NewlineMode(options_.all_options()) == PCRE_NEWLINE_CRLF) { matchend++; } // We also need to advance more than one char if we're in utf8 mode. #ifdef SUPPORT_UTF8 if (options_.utf8()) { while (matchend < static_cast(str->length()) && ((*str)[matchend] & 0xc0) == 0x80) matchend++; } #endif if (matchend <= static_cast(str->length())) out.append(*str, start, matchend - start); start = matchend; } else { out.append(*str, start, matchstart - start); Rewrite(&out, rewrite, *str, vec, matches); start = matchend; lastend = matchend; count++; } } if (count == 0) return 0; if (start < static_cast(str->length())) out.append(*str, start, str->length() - start); swap(out, *str); return count; } bool RE::Extract(const StringPiece& rewrite, const StringPiece& text, string *out) const { int vec[kVecSize]; int matches = TryMatch(text, 0, UNANCHORED, vec, kVecSize); if (matches == 0) return false; out->erase(); return Rewrite(out, rewrite, text, vec, matches); } /*static*/ string RE::QuoteMeta(const StringPiece& unquoted) { string result; // Escape any ascii character not in [A-Za-z_0-9]. // // Note that it's legal to escape a character even if it has no // special meaning in a regular expression -- so this function does // that. (This also makes it identical to the perl function of the // same name; see `perldoc -f quotemeta`.) for (int ii = 0; ii < unquoted.size(); ++ii) { // Note that using 'isalnum' here raises the benchmark time from // 32ns to 58ns: if ((unquoted[ii] < 'a' || unquoted[ii] > 'z') && (unquoted[ii] < 'A' || unquoted[ii] > 'Z') && (unquoted[ii] < '0' || unquoted[ii] > '9') && unquoted[ii] != '_' && // If this is the part of a UTF8 or Latin1 character, we need // to copy this byte without escaping. Experimentally this is // what works correctly with the regexp library. !(unquoted[ii] & 128)) { result += '\\'; } result += unquoted[ii]; } return result; } /***** Actual matching and rewriting code *****/ int RE::TryMatch(const StringPiece& text, int startpos, Anchor anchor, int *vec, int vecsize) const { pcre* re = (anchor == ANCHOR_BOTH) ? re_full_ : re_partial_; if (re == NULL) { //fprintf(stderr, "Matching against invalid re: %s\n", error_->c_str()); return 0; } pcre_extra extra = { 0, 0, 0, 0, 0, 0 }; if (options_.match_limit() > 0) { extra.flags |= PCRE_EXTRA_MATCH_LIMIT; extra.match_limit = options_.match_limit(); } if (options_.match_limit_recursion() > 0) { extra.flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION; extra.match_limit_recursion = options_.match_limit_recursion(); } int rc = pcre_exec(re, // The regular expression object &extra, (text.data() == NULL) ? "" : text.data(), text.size(), startpos, (anchor == UNANCHORED) ? 0 : PCRE_ANCHORED, vec, vecsize); // Handle errors if (rc == PCRE_ERROR_NOMATCH) { return 0; } else if (rc < 0) { //fprintf(stderr, "Unexpected return code: %d when matching '%s'\n", // re, pattern_.c_str()); return 0; } else if (rc == 0) { // pcre_exec() returns 0 as a special case when the number of // capturing subpatterns exceeds the size of the vector. // When this happens, there is a match and the output vector // is filled, but we miss out on the positions of the extra subpatterns. rc = vecsize / 2; } return rc; } bool RE::DoMatchImpl(const StringPiece& text, Anchor anchor, int* consumed, const Arg* const* args, int n, int* vec, int vecsize) const { assert((1 + n) * 3 <= vecsize); // results + PCRE workspace int matches = TryMatch(text, 0, anchor, vec, vecsize); assert(matches >= 0); // TryMatch never returns negatives if (matches == 0) return false; *consumed = vec[1]; if (n == 0 || args == NULL) { // We are not interested in results return true; } if (NumberOfCapturingGroups() < n) { // RE has fewer capturing groups than number of arg pointers passed in return false; } // If we got here, we must have matched the whole pattern. // We do not need (can not do) any more checks on the value of 'matches' here // -- see the comment for TryMatch. for (int i = 0; i < n; i++) { const int start = vec[2*(i+1)]; const int limit = vec[2*(i+1)+1]; if (!args[i]->Parse(text.data() + start, limit-start)) { // TODO: Should we indicate what the error was? return false; } } return true; } bool RE::DoMatch(const StringPiece& text, Anchor anchor, int* consumed, const Arg* const args[], int n) const { assert(n >= 0); size_t const vecsize = (1 + n) * 3; // results + PCRE workspace // (as for kVecSize) int space[21]; // use stack allocation for small vecsize (common case) int* vec = vecsize <= 21 ? space : new int[vecsize]; bool retval = DoMatchImpl(text, anchor, consumed, args, n, vec, vecsize); if (vec != space) delete [] vec; return retval; } bool RE::Rewrite(string *out, const StringPiece &rewrite, const StringPiece &text, int *vec, int veclen) const { for (const char *s = rewrite.data(), *end = s + rewrite.size(); s < end; s++) { int c = *s; if (c == '\\') { c = *++s; if (isdigit(c)) { int n = (c - '0'); if (n >= veclen) { //fprintf(stderr, requested group %d in regexp %.*s\n", // n, rewrite.size(), rewrite.data()); return false; } int start = vec[2 * n]; if (start >= 0) out->append(text.data() + start, vec[2 * n + 1] - start); } else if (c == '\\') { out->push_back('\\'); } else { //fprintf(stderr, "invalid rewrite pattern: %.*s\n", // rewrite.size(), rewrite.data()); return false; } } else { out->push_back(c); } } return true; } // Return the number of capturing subpatterns, or -1 if the // regexp wasn't valid on construction. int RE::NumberOfCapturingGroups() const { if (re_partial_ == NULL) return -1; int result; int pcre_retval = pcre_fullinfo(re_partial_, // The regular expression object NULL, // We did not study the pattern PCRE_INFO_CAPTURECOUNT, &result); assert(pcre_retval == 0); return result; } /***** Parsers for various types *****/ bool Arg::parse_null(const char* str, int n, void* dest) { // We fail if somebody asked us to store into a non-NULL void* pointer return (dest == NULL); } bool Arg::parse_string(const char* str, int n, void* dest) { reinterpret_cast(dest)->assign(str, n); return true; } bool Arg::parse_stringpiece(const char* str, int n, void* dest) { reinterpret_cast(dest)->set(str, n); return true; } bool Arg::parse_char(const char* str, int n, void* dest) { if (n != 1) return false; *(reinterpret_cast(dest)) = str[0]; return true; } bool Arg::parse_uchar(const char* str, int n, void* dest) { if (n != 1) return false; *(reinterpret_cast(dest)) = str[0]; return true; } // Largest number spec that we are willing to parse static const int kMaxNumberLength = 32; // REQUIRES "buf" must have length at least kMaxNumberLength+1 // REQUIRES "n > 0" // Copies "str" into "buf" and null-terminates if necessary. // Returns one of: // a. "str" if no termination is needed // b. "buf" if the string was copied and null-terminated // c. "" if the input was invalid and has no hope of being parsed static const char* TerminateNumber(char* buf, const char* str, int n) { if ((n > 0) && isspace(*str)) { // We are less forgiving than the strtoxxx() routines and do not // allow leading spaces. return ""; } // See if the character right after the input text may potentially // look like a digit. if (isdigit(str[n]) || ((str[n] >= 'a') && (str[n] <= 'f')) || ((str[n] >= 'A') && (str[n] <= 'F'))) { if (n > kMaxNumberLength) return ""; // Input too big to be a valid number memcpy(buf, str, n); buf[n] = '\0'; return buf; } else { // We can parse right out of the supplied string, so return it. return str; } } bool Arg::parse_long_radix(const char* str, int n, void* dest, int radix) { if (n == 0) return false; char buf[kMaxNumberLength+1]; str = TerminateNumber(buf, str, n); char* end; errno = 0; long r = strtol(str, &end, radix); if (end != str + n) return false; // Leftover junk if (errno) return false; *(reinterpret_cast(dest)) = r; return true; } bool Arg::parse_ulong_radix(const char* str, int n, void* dest, int radix) { if (n == 0) return false; char buf[kMaxNumberLength+1]; str = TerminateNumber(buf, str, n); if (str[0] == '-') return false; // strtoul() on a negative number?! char* end; errno = 0; unsigned long r = strtoul(str, &end, radix); if (end != str + n) return false; // Leftover junk if (errno) return false; *(reinterpret_cast(dest)) = r; return true; } bool Arg::parse_short_radix(const char* str, int n, void* dest, int radix) { long r; if (!parse_long_radix(str, n, &r, radix)) return false; // Could not parse if (r < SHRT_MIN || r > SHRT_MAX) return false; // Out of range *(reinterpret_cast(dest)) = r; return true; } bool Arg::parse_ushort_radix(const char* str, int n, void* dest, int radix) { unsigned long r; if (!parse_ulong_radix(str, n, &r, radix)) return false; // Could not parse if (r > USHRT_MAX) return false; // Out of range *(reinterpret_cast(dest)) = r; return true; } bool Arg::parse_int_radix(const char* str, int n, void* dest, int radix) { long r; if (!parse_long_radix(str, n, &r, radix)) return false; // Could not parse if (r < INT_MIN || r > INT_MAX) return false; // Out of range *(reinterpret_cast(dest)) = r; return true; } bool Arg::parse_uint_radix(const char* str, int n, void* dest, int radix) { unsigned long r; if (!parse_ulong_radix(str, n, &r, radix)) return false; // Could not parse if (r > UINT_MAX) return false; // Out of range *(reinterpret_cast(dest)) = r; return true; } bool Arg::parse_longlong_radix(const char* str, int n, void* dest, int radix) { #ifndef HAVE_LONG_LONG return false; #else if (n == 0) return false; char buf[kMaxNumberLength+1]; str = TerminateNumber(buf, str, n); char* end; errno = 0; #if defined HAVE_STRTOQ long long r = strtoq(str, &end, radix); #elif defined HAVE_STRTOLL long long r = strtoll(str, &end, radix); #else #error parse_longlong_radix: cannot convert input to a long-long #endif if (end != str + n) return false; // Leftover junk if (errno) return false; *(reinterpret_cast(dest)) = r; return true; #endif /* HAVE_LONG_LONG */ } bool Arg::parse_ulonglong_radix(const char* str, int n, void* dest, int radix) { #ifndef HAVE_UNSIGNED_LONG_LONG return false; #else if (n == 0) return false; char buf[kMaxNumberLength+1]; str = TerminateNumber(buf, str, n); if (str[0] == '-') return false; // strtoull() on a negative number?! char* end; errno = 0; #if defined HAVE_STRTOQ unsigned long long r = strtouq(str, &end, radix); #elif defined HAVE_STRTOLL unsigned long long r = strtoull(str, &end, radix); #else #error parse_ulonglong_radix: cannot convert input to a long-long #endif if (end != str + n) return false; // Leftover junk if (errno) return false; *(reinterpret_cast(dest)) = r; return true; #endif /* HAVE_UNSIGNED_LONG_LONG */ } bool Arg::parse_double(const char* str, int n, void* dest) { if (n == 0) return false; static const int kMaxLength = 200; char buf[kMaxLength]; if (n >= kMaxLength) return false; memcpy(buf, str, n); buf[n] = '\0'; errno = 0; char* end; double r = strtod(buf, &end); if (end != buf + n) return false; // Leftover junk if (errno) return false; *(reinterpret_cast(dest)) = r; return true; } bool Arg::parse_float(const char* str, int n, void* dest) { double r; if (!parse_double(str, n, &r)) return false; *(reinterpret_cast(dest)) = static_cast(r); return true; } #define DEFINE_INTEGER_PARSERS(name) \ bool Arg::parse_##name(const char* str, int n, void* dest) { \ return parse_##name##_radix(str, n, dest, 10); \ } \ bool Arg::parse_##name##_hex(const char* str, int n, void* dest) { \ return parse_##name##_radix(str, n, dest, 16); \ } \ bool Arg::parse_##name##_octal(const char* str, int n, void* dest) { \ return parse_##name##_radix(str, n, dest, 8); \ } \ bool Arg::parse_##name##_cradix(const char* str, int n, void* dest) { \ return parse_##name##_radix(str, n, dest, 0); \ } DEFINE_INTEGER_PARSERS(short) /* */ DEFINE_INTEGER_PARSERS(ushort) /* */ DEFINE_INTEGER_PARSERS(int) /* Don't use semicolons after these */ DEFINE_INTEGER_PARSERS(uint) /* statements because they can cause */ DEFINE_INTEGER_PARSERS(long) /* compiler warnings if the checking */ DEFINE_INTEGER_PARSERS(ulong) /* level is turned up high enough. */ DEFINE_INTEGER_PARSERS(longlong) /* */ DEFINE_INTEGER_PARSERS(ulonglong) /* */ #undef DEFINE_INTEGER_PARSERS } // namespace pcrecpp libsynthesis-3.4.0.47.1/src/pcre/pcrecpp.h000066400000000000000000000624131226375725500201770ustar00rootroot00000000000000// Copyright (c) 2005, Google Inc. // 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 name of Google Inc. 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. // // Author: Sanjay Ghemawat // Support for PCRE_XXX modifiers added by Giuseppe Maxia, July 2005 #ifndef _PCRECPP_H #define _PCRECPP_H // C++ interface to the pcre regular-expression library. RE supports // Perl-style regular expressions (with extensions like \d, \w, \s, // ...). // // ----------------------------------------------------------------------- // REGEXP SYNTAX: // // This module is part of the pcre library and hence supports its syntax // for regular expressions. // // The syntax is pretty similar to Perl's. For those not familiar // with Perl's regular expressions, here are some examples of the most // commonly used extensions: // // "hello (\\w+) world" -- \w matches a "word" character // "version (\\d+)" -- \d matches a digit // "hello\\s+world" -- \s matches any whitespace character // "\\b(\\w+)\\b" -- \b matches empty string at a word boundary // "(?i)hello" -- (?i) turns on case-insensitive matching // "/\\*(.*?)\\*/" -- .*? matches . minimum no. of times possible // // ----------------------------------------------------------------------- // MATCHING INTERFACE: // // The "FullMatch" operation checks that supplied text matches a // supplied pattern exactly. // // Example: successful match // pcrecpp::RE re("h.*o"); // re.FullMatch("hello"); // // Example: unsuccessful match (requires full match): // pcrecpp::RE re("e"); // !re.FullMatch("hello"); // // Example: creating a temporary RE object: // pcrecpp::RE("h.*o").FullMatch("hello"); // // You can pass in a "const char*" or a "string" for "text". The // examples below tend to use a const char*. // // You can, as in the different examples above, store the RE object // explicitly in a variable or use a temporary RE object. The // examples below use one mode or the other arbitrarily. Either // could correctly be used for any of these examples. // // ----------------------------------------------------------------------- // MATCHING WITH SUB-STRING EXTRACTION: // // You can supply extra pointer arguments to extract matched subpieces. // // Example: extracts "ruby" into "s" and 1234 into "i" // int i; // string s; // pcrecpp::RE re("(\\w+):(\\d+)"); // re.FullMatch("ruby:1234", &s, &i); // // Example: does not try to extract any extra sub-patterns // re.FullMatch("ruby:1234", &s); // // Example: does not try to extract into NULL // re.FullMatch("ruby:1234", NULL, &i); // // Example: integer overflow causes failure // !re.FullMatch("ruby:1234567891234", NULL, &i); // // Example: fails because there aren't enough sub-patterns: // !pcrecpp::RE("\\w+:\\d+").FullMatch("ruby:1234", &s); // // Example: fails because string cannot be stored in integer // !pcrecpp::RE("(.*)").FullMatch("ruby", &i); // // The provided pointer arguments can be pointers to any scalar numeric // type, or one of // string (matched piece is copied to string) // StringPiece (StringPiece is mutated to point to matched piece) // T (where "bool T::ParseFrom(const char*, int)" exists) // NULL (the corresponding matched sub-pattern is not copied) // // CAVEAT: An optional sub-pattern that does not exist in the matched // string is assigned the empty string. Therefore, the following will // return false (because the empty string is not a valid number): // int number; // pcrecpp::RE::FullMatch("abc", "[a-z]+(\\d+)?", &number); // // ----------------------------------------------------------------------- // DO_MATCH // // The matching interface supports at most 16 arguments per call. // If you need more, consider using the more general interface // pcrecpp::RE::DoMatch(). See pcrecpp.h for the signature for DoMatch. // // ----------------------------------------------------------------------- // PARTIAL MATCHES // // You can use the "PartialMatch" operation when you want the pattern // to match any substring of the text. // // Example: simple search for a string: // pcrecpp::RE("ell").PartialMatch("hello"); // // Example: find first number in a string: // int number; // pcrecpp::RE re("(\\d+)"); // re.PartialMatch("x*100 + 20", &number); // assert(number == 100); // // ----------------------------------------------------------------------- // UTF-8 AND THE MATCHING INTERFACE: // // By default, pattern and text are plain text, one byte per character. // The UTF8 flag, passed to the constructor, causes both pattern // and string to be treated as UTF-8 text, still a byte stream but // potentially multiple bytes per character. In practice, the text // is likelier to be UTF-8 than the pattern, but the match returned // may depend on the UTF8 flag, so always use it when matching // UTF8 text. E.g., "." will match one byte normally but with UTF8 // set may match up to three bytes of a multi-byte character. // // Example: // pcrecpp::RE_Options options; // options.set_utf8(); // pcrecpp::RE re(utf8_pattern, options); // re.FullMatch(utf8_string); // // Example: using the convenience function UTF8(): // pcrecpp::RE re(utf8_pattern, pcrecpp::UTF8()); // re.FullMatch(utf8_string); // // NOTE: The UTF8 option is ignored if pcre was not configured with the // --enable-utf8 flag. // // ----------------------------------------------------------------------- // PASSING MODIFIERS TO THE REGULAR EXPRESSION ENGINE // // PCRE defines some modifiers to change the behavior of the regular // expression engine. // The C++ wrapper defines an auxiliary class, RE_Options, as a vehicle // to pass such modifiers to a RE class. // // Currently, the following modifiers are supported // // modifier description Perl corresponding // // PCRE_CASELESS case insensitive match /i // PCRE_MULTILINE multiple lines match /m // PCRE_DOTALL dot matches newlines /s // PCRE_DOLLAR_ENDONLY $ matches only at end N/A // PCRE_EXTRA strict escape parsing N/A // PCRE_EXTENDED ignore whitespaces /x // PCRE_UTF8 handles UTF8 chars built-in // PCRE_UNGREEDY reverses * and *? N/A // PCRE_NO_AUTO_CAPTURE disables matching parens N/A (*) // // (For a full account on how each modifier works, please check the // PCRE API reference manual). // // (*) Both Perl and PCRE allow non matching parentheses by means of the // "?:" modifier within the pattern itself. e.g. (?:ab|cd) does not // capture, while (ab|cd) does. // // For each modifier, there are two member functions whose name is made // out of the modifier in lowercase, without the "PCRE_" prefix. For // instance, PCRE_CASELESS is handled by // bool caseless(), // which returns true if the modifier is set, and // RE_Options & set_caseless(bool), // which sets or unsets the modifier. // // Moreover, PCRE_EXTRA_MATCH_LIMIT can be accessed through the // set_match_limit() and match_limit() member functions. // Setting match_limit to a non-zero value will limit the executation of // pcre to keep it from doing bad things like blowing the stack or taking // an eternity to return a result. A value of 5000 is good enough to stop // stack blowup in a 2MB thread stack. Setting match_limit to zero will // disable match limiting. Alternately, you can set match_limit_recursion() // which uses PCRE_EXTRA_MATCH_LIMIT_RECURSION to limit how much pcre // recurses. match_limit() caps the number of matches pcre does; // match_limit_recrusion() caps the depth of recursion. // // Normally, to pass one or more modifiers to a RE class, you declare // a RE_Options object, set the appropriate options, and pass this // object to a RE constructor. Example: // // RE_options opt; // opt.set_caseless(true); // // if (RE("HELLO", opt).PartialMatch("hello world")) ... // // RE_options has two constructors. The default constructor takes no // arguments and creates a set of flags that are off by default. // // The optional parameter 'option_flags' is to facilitate transfer // of legacy code from C programs. This lets you do // RE(pattern, RE_Options(PCRE_CASELESS|PCRE_MULTILINE)).PartialMatch(str); // // But new code is better off doing // RE(pattern, // RE_Options().set_caseless(true).set_multiline(true)).PartialMatch(str); // (See below) // // If you are going to pass one of the most used modifiers, there are some // convenience functions that return a RE_Options class with the // appropriate modifier already set: // CASELESS(), UTF8(), MULTILINE(), DOTALL(), EXTENDED() // // If you need to set several options at once, and you don't want to go // through the pains of declaring a RE_Options object and setting several // options, there is a parallel method that give you such ability on the // fly. You can concatenate several set_xxxxx member functions, since each // of them returns a reference to its class object. e.g.: to pass // PCRE_CASELESS, PCRE_EXTENDED, and PCRE_MULTILINE to a RE with one // statement, you may write // // RE(" ^ xyz \\s+ .* blah$", RE_Options() // .set_caseless(true) // .set_extended(true) // .set_multiline(true)).PartialMatch(sometext); // // ----------------------------------------------------------------------- // SCANNING TEXT INCREMENTALLY // // The "Consume" operation may be useful if you want to repeatedly // match regular expressions at the front of a string and skip over // them as they match. This requires use of the "StringPiece" type, // which represents a sub-range of a real string. Like RE, StringPiece // is defined in the pcrecpp namespace. // // Example: read lines of the form "var = value" from a string. // string contents = ...; // Fill string somehow // pcrecpp::StringPiece input(contents); // Wrap in a StringPiece // // string var; // int value; // pcrecpp::RE re("(\\w+) = (\\d+)\n"); // while (re.Consume(&input, &var, &value)) { // ...; // } // // Each successful call to "Consume" will set "var/value", and also // advance "input" so it points past the matched text. // // The "FindAndConsume" operation is similar to "Consume" but does not // anchor your match at the beginning of the string. For example, you // could extract all words from a string by repeatedly calling // pcrecpp::RE("(\\w+)").FindAndConsume(&input, &word) // // ----------------------------------------------------------------------- // PARSING HEX/OCTAL/C-RADIX NUMBERS // // By default, if you pass a pointer to a numeric value, the // corresponding text is interpreted as a base-10 number. You can // instead wrap the pointer with a call to one of the operators Hex(), // Octal(), or CRadix() to interpret the text in another base. The // CRadix operator interprets C-style "0" (base-8) and "0x" (base-16) // prefixes, but defaults to base-10. // // Example: // int a, b, c, d; // pcrecpp::RE re("(.*) (.*) (.*) (.*)"); // re.FullMatch("100 40 0100 0x40", // pcrecpp::Octal(&a), pcrecpp::Hex(&b), // pcrecpp::CRadix(&c), pcrecpp::CRadix(&d)); // will leave 64 in a, b, c, and d. // // ----------------------------------------------------------------------- // REPLACING PARTS OF STRINGS // // You can replace the first match of "pattern" in "str" with // "rewrite". Within "rewrite", backslash-escaped digits (\1 to \9) // can be used to insert text matching corresponding parenthesized // group from the pattern. \0 in "rewrite" refers to the entire // matching text. E.g., // // string s = "yabba dabba doo"; // pcrecpp::RE("b+").Replace("d", &s); // // will leave "s" containing "yada dabba doo". The result is true if // the pattern matches and a replacement occurs, or false otherwise. // // GlobalReplace() is like Replace(), except that it replaces all // occurrences of the pattern in the string with the rewrite. // Replacements are not subject to re-matching. E.g., // // string s = "yabba dabba doo"; // pcrecpp::RE("b+").GlobalReplace("d", &s); // // will leave "s" containing "yada dada doo". It returns the number // of replacements made. // // Extract() is like Replace(), except that if the pattern matches, // "rewrite" is copied into "out" (an additional argument) with // substitutions. The non-matching portions of "text" are ignored. // Returns true iff a match occurred and the extraction happened // successfully. If no match occurs, the string is left unaffected. #include #include #include // defines the Arg class // This isn't technically needed here, but we include it // anyway so folks who include pcrecpp.h don't have to. #include namespace pcrecpp { #define PCRE_SET_OR_CLEAR(b, o) \ if (b) all_options_ |= (o); else all_options_ &= ~(o); \ return *this #define PCRE_IS_SET(o) \ (all_options_ & o) == o // We convert user-passed pointers into special Arg objects PCRECPP_EXP_DECL Arg no_arg; /***** Compiling regular expressions: the RE class *****/ // RE_Options allow you to set options to be passed along to pcre, // along with other options we put on top of pcre. // Only 9 modifiers, plus match_limit and match_limit_recursion, // are supported now. class PCRECPP_EXP_DEFN RE_Options { public: // constructor RE_Options() : match_limit_(0), match_limit_recursion_(0), all_options_(0) {} // alternative constructor. // To facilitate transfer of legacy code from C programs // // This lets you do // RE(pattern, RE_Options(PCRE_CASELESS|PCRE_MULTILINE)).PartialMatch(str); // But new code is better off doing // RE(pattern, // RE_Options().set_caseless(true).set_multiline(true)).PartialMatch(str); RE_Options(int option_flags) : match_limit_(0), match_limit_recursion_(0), all_options_(option_flags) {} // we're fine with the default destructor, copy constructor, etc. // accessors and mutators int match_limit() const { return match_limit_; }; RE_Options &set_match_limit(int limit) { match_limit_ = limit; return *this; } int match_limit_recursion() const { return match_limit_recursion_; }; RE_Options &set_match_limit_recursion(int limit) { match_limit_recursion_ = limit; return *this; } bool caseless() const { return PCRE_IS_SET(PCRE_CASELESS); } RE_Options &set_caseless(bool x) { PCRE_SET_OR_CLEAR(x, PCRE_CASELESS); } bool multiline() const { return PCRE_IS_SET(PCRE_MULTILINE); } RE_Options &set_multiline(bool x) { PCRE_SET_OR_CLEAR(x, PCRE_MULTILINE); } bool dotall() const { return PCRE_IS_SET(PCRE_DOTALL); } RE_Options &set_dotall(bool x) { PCRE_SET_OR_CLEAR(x,PCRE_DOTALL); } bool extended() const { return PCRE_IS_SET(PCRE_EXTENDED); } RE_Options &set_extended(bool x) { PCRE_SET_OR_CLEAR(x,PCRE_EXTENDED); } bool dollar_endonly() const { return PCRE_IS_SET(PCRE_DOLLAR_ENDONLY); } RE_Options &set_dollar_endonly(bool x) { PCRE_SET_OR_CLEAR(x,PCRE_DOLLAR_ENDONLY); } bool extra() const { return PCRE_IS_SET( PCRE_EXTRA); } RE_Options &set_extra(bool x) { PCRE_SET_OR_CLEAR(x, PCRE_EXTRA); } bool ungreedy() const { return PCRE_IS_SET(PCRE_UNGREEDY); } RE_Options &set_ungreedy(bool x) { PCRE_SET_OR_CLEAR(x, PCRE_UNGREEDY); } bool utf8() const { return PCRE_IS_SET(PCRE_UTF8); } RE_Options &set_utf8(bool x) { PCRE_SET_OR_CLEAR(x, PCRE_UTF8); } bool no_auto_capture() const { return PCRE_IS_SET(PCRE_NO_AUTO_CAPTURE); } RE_Options &set_no_auto_capture(bool x) { PCRE_SET_OR_CLEAR(x, PCRE_NO_AUTO_CAPTURE); } RE_Options &set_all_options(int opt) { all_options_ = opt; return *this; } int all_options() const { return all_options_ ; } // TODO: add other pcre flags private: int match_limit_; int match_limit_recursion_; int all_options_; }; // These functions return some common RE_Options static inline RE_Options UTF8() { return RE_Options().set_utf8(true); } static inline RE_Options CASELESS() { return RE_Options().set_caseless(true); } static inline RE_Options MULTILINE() { return RE_Options().set_multiline(true); } static inline RE_Options DOTALL() { return RE_Options().set_dotall(true); } static inline RE_Options EXTENDED() { return RE_Options().set_extended(true); } // Interface for regular expression matching. Also corresponds to a // pre-compiled regular expression. An "RE" object is safe for // concurrent use by multiple threads. class PCRECPP_EXP_DEFN RE { public: // We provide implicit conversions from strings so that users can // pass in a string or a "const char*" wherever an "RE" is expected. RE(const char* pat) { Init(pat, NULL); } RE(const char *pat, const RE_Options& option) { Init(pat, &option); } RE(const string& pat) { Init(pat, NULL); } RE(const string& pat, const RE_Options& option) { Init(pat, &option); } // Copy constructor & assignment - note that these are expensive // because they recompile the expression. RE(const RE& re) { Init(re.pattern_, &re.options_); } const RE& operator=(const RE& re) { if (this != &re) { Cleanup(); // This is the code that originally came from Google // Init(re.pattern_.c_str(), &re.options_); // This is the replacement from Ari Pollak Init(re.pattern_, &re.options_); } return *this; } ~RE(); // The string specification for this RE. E.g. // RE re("ab*c?d+"); // re.pattern(); // "ab*c?d+" const string& pattern() const { return pattern_; } // If RE could not be created properly, returns an error string. // Else returns the empty string. const string& error() const { return *error_; } /***** The useful part: the matching interface *****/ // This is provided so one can do pattern.ReplaceAll() just as // easily as ReplaceAll(pattern-text, ....) bool FullMatch(const StringPiece& text, const Arg& ptr1 = no_arg, const Arg& ptr2 = no_arg, const Arg& ptr3 = no_arg, const Arg& ptr4 = no_arg, const Arg& ptr5 = no_arg, const Arg& ptr6 = no_arg, const Arg& ptr7 = no_arg, const Arg& ptr8 = no_arg, const Arg& ptr9 = no_arg, const Arg& ptr10 = no_arg, const Arg& ptr11 = no_arg, const Arg& ptr12 = no_arg, const Arg& ptr13 = no_arg, const Arg& ptr14 = no_arg, const Arg& ptr15 = no_arg, const Arg& ptr16 = no_arg) const; bool PartialMatch(const StringPiece& text, const Arg& ptr1 = no_arg, const Arg& ptr2 = no_arg, const Arg& ptr3 = no_arg, const Arg& ptr4 = no_arg, const Arg& ptr5 = no_arg, const Arg& ptr6 = no_arg, const Arg& ptr7 = no_arg, const Arg& ptr8 = no_arg, const Arg& ptr9 = no_arg, const Arg& ptr10 = no_arg, const Arg& ptr11 = no_arg, const Arg& ptr12 = no_arg, const Arg& ptr13 = no_arg, const Arg& ptr14 = no_arg, const Arg& ptr15 = no_arg, const Arg& ptr16 = no_arg) const; bool Consume(StringPiece* input, const Arg& ptr1 = no_arg, const Arg& ptr2 = no_arg, const Arg& ptr3 = no_arg, const Arg& ptr4 = no_arg, const Arg& ptr5 = no_arg, const Arg& ptr6 = no_arg, const Arg& ptr7 = no_arg, const Arg& ptr8 = no_arg, const Arg& ptr9 = no_arg, const Arg& ptr10 = no_arg, const Arg& ptr11 = no_arg, const Arg& ptr12 = no_arg, const Arg& ptr13 = no_arg, const Arg& ptr14 = no_arg, const Arg& ptr15 = no_arg, const Arg& ptr16 = no_arg) const; bool FindAndConsume(StringPiece* input, const Arg& ptr1 = no_arg, const Arg& ptr2 = no_arg, const Arg& ptr3 = no_arg, const Arg& ptr4 = no_arg, const Arg& ptr5 = no_arg, const Arg& ptr6 = no_arg, const Arg& ptr7 = no_arg, const Arg& ptr8 = no_arg, const Arg& ptr9 = no_arg, const Arg& ptr10 = no_arg, const Arg& ptr11 = no_arg, const Arg& ptr12 = no_arg, const Arg& ptr13 = no_arg, const Arg& ptr14 = no_arg, const Arg& ptr15 = no_arg, const Arg& ptr16 = no_arg) const; bool Replace(const StringPiece& rewrite, string *str) const; int GlobalReplace(const StringPiece& rewrite, string *str) const; bool Extract(const StringPiece &rewrite, const StringPiece &text, string *out) const; // Escapes all potentially meaningful regexp characters in // 'unquoted'. The returned string, used as a regular expression, // will exactly match the original string. For example, // 1.5-2.0? // may become: // 1\.5\-2\.0\? static string QuoteMeta(const StringPiece& unquoted); /***** Generic matching interface *****/ // Type of match (TODO: Should be restructured as part of RE_Options) enum Anchor { UNANCHORED, // No anchoring ANCHOR_START, // Anchor at start only ANCHOR_BOTH // Anchor at start and end }; // General matching routine. Stores the length of the match in // "*consumed" if successful. bool DoMatch(const StringPiece& text, Anchor anchor, int* consumed, const Arg* const* args, int n) const; // Return the number of capturing subpatterns, or -1 if the // regexp wasn't valid on construction. int NumberOfCapturingGroups() const; private: void Init(const string& pattern, const RE_Options* options); void Cleanup(); // Match against "text", filling in "vec" (up to "vecsize" * 2/3) with // pairs of integers for the beginning and end positions of matched // text. The first pair corresponds to the entire matched text; // subsequent pairs correspond, in order, to parentheses-captured // matches. Returns the number of pairs (one more than the number of // the last subpattern with a match) if matching was successful // and zero if the match failed. // I.e. for RE("(foo)|(bar)|(baz)") it will return 2, 3, and 4 when matching // against "foo", "bar", and "baz" respectively. // When matching RE("(foo)|hello") against "hello", it will return 1. // But the values for all subpattern are filled in into "vec". int TryMatch(const StringPiece& text, int startpos, Anchor anchor, int *vec, int vecsize) const; // Append the "rewrite" string, with backslash subsitutions from "text" // and "vec", to string "out". bool Rewrite(string *out, const StringPiece& rewrite, const StringPiece& text, int *vec, int veclen) const; // internal implementation for DoMatch bool DoMatchImpl(const StringPiece& text, Anchor anchor, int* consumed, const Arg* const args[], int n, int* vec, int vecsize) const; // Compile the regexp for the specified anchoring mode pcre* Compile(Anchor anchor); string pattern_; RE_Options options_; pcre* re_full_; // For full matches pcre* re_partial_; // For partial matches const string* error_; // Error indicator (or points to empty string) }; } // namespace pcrecpp #endif /* _PCRECPP_H */ libsynthesis-3.4.0.47.1/src/pcre/pcrecpp_internal.h000066400000000000000000000054041226375725500220700ustar00rootroot00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* ----------------------------------------------------------------------------- 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 name of the University of Cambridge 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. ----------------------------------------------------------------------------- */ #ifndef PCRECPP_INTERNAL_H #define PCRECPP_INTERNAL_H /* When compiling a DLL for Windows, the exported symbols have to be declared using some MS magic. I found some useful information on this web page: http://msdn2.microsoft.com/en-us/library/y4h7bcy6(VS.80).aspx. According to the information there, using __declspec(dllexport) without "extern" we have a definition; with "extern" we have a declaration. The settings here override the setting in pcre.h. We use: PCRECPP_EXP_DECL for declarations PCRECPP_EXP_DEFN for definitions of exported functions */ #ifndef PCRECPP_EXP_DECL # ifdef _WIN32 # ifndef PCRECPP_STATIC # define PCRECPP_EXP_DECL extern __declspec(dllexport) # define PCRECPP_EXP_DEFN __declspec(dllexport) # else # define PCRECPP_EXP_DECL extern # define PCRECPP_EXP_DEFN # endif # else # define PCRECPP_EXP_DECL extern # define PCRECPP_EXP_DEFN # endif #endif #endif /* PCRECPP_INTERNAL_H */ /* End of pcrecpp_internal.h */ libsynthesis-3.4.0.47.1/src/pcre/pcrecpp_unittest.cc000066400000000000000000001114651226375725500222760ustar00rootroot00000000000000// -*- coding: utf-8 -*- // // Copyright (c) 2005 - 2006, Google Inc. // 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 name of Google Inc. 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. // // Author: Sanjay Ghemawat // // TODO: Test extractions for PartialMatch/Consume #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include "pcrecpp.h" using pcrecpp::StringPiece; using pcrecpp::RE; using pcrecpp::RE_Options; using pcrecpp::Hex; using pcrecpp::Octal; using pcrecpp::CRadix; static bool VERBOSE_TEST = false; // CHECK dies with a fatal error if condition is not true. It is *not* // controlled by NDEBUG, so the check will be executed regardless of // compilation mode. Therefore, it is safe to do things like: // CHECK_EQ(fp->Write(x), 4) #define CHECK(condition) do { \ if (!(condition)) { \ fprintf(stderr, "%s:%d: Check failed: %s\n", \ __FILE__, __LINE__, #condition); \ exit(1); \ } \ } while (0) #define CHECK_EQ(a, b) CHECK(a == b) static void Timing1(int num_iters) { // Same pattern lots of times RE pattern("ruby:\\d+"); StringPiece p("ruby:1234"); for (int j = num_iters; j > 0; j--) { CHECK(pattern.FullMatch(p)); } } static void Timing2(int num_iters) { // Same pattern lots of times RE pattern("ruby:(\\d+)"); int i; for (int j = num_iters; j > 0; j--) { CHECK(pattern.FullMatch("ruby:1234", &i)); CHECK_EQ(i, 1234); } } static void Timing3(int num_iters) { string text_string; for (int j = num_iters; j > 0; j--) { text_string += "this is another line\n"; } RE line_matcher(".*\n"); string line; StringPiece text(text_string); int counter = 0; while (line_matcher.Consume(&text)) { counter++; } printf("Matched %d lines\n", counter); } #if 0 // uncomment this if you have a way of defining VirtualProcessSize() static void LeakTest() { // Check for memory leaks unsigned long long initial_size = 0; for (int i = 0; i < 100000; i++) { if (i == 50000) { initial_size = VirtualProcessSize(); printf("Size after 50000: %llu\n", initial_size); } char buf[100]; snprintf(buf, sizeof(buf), "pat%09d", i); RE newre(buf); } uint64 final_size = VirtualProcessSize(); printf("Size after 100000: %llu\n", final_size); const double growth = double(final_size - initial_size) / final_size; printf("Growth: %0.2f%%", growth * 100); CHECK(growth < 0.02); // Allow < 2% growth } #endif static void RadixTests() { printf("Testing hex\n"); #define CHECK_HEX(type, value) \ do { \ type v; \ CHECK(RE("([0-9a-fA-F]+)[uUlL]*").FullMatch(#value, Hex(&v))); \ CHECK_EQ(v, 0x ## value); \ CHECK(RE("([0-9a-fA-FxX]+)[uUlL]*").FullMatch("0x" #value, CRadix(&v))); \ CHECK_EQ(v, 0x ## value); \ } while(0) CHECK_HEX(short, 2bad); CHECK_HEX(unsigned short, 2badU); CHECK_HEX(int, dead); CHECK_HEX(unsigned int, deadU); CHECK_HEX(long, 7eadbeefL); CHECK_HEX(unsigned long, deadbeefUL); #ifdef HAVE_LONG_LONG CHECK_HEX(long long, 12345678deadbeefLL); #endif #ifdef HAVE_UNSIGNED_LONG_LONG CHECK_HEX(unsigned long long, cafebabedeadbeefULL); #endif #undef CHECK_HEX printf("Testing octal\n"); #define CHECK_OCTAL(type, value) \ do { \ type v; \ CHECK(RE("([0-7]+)[uUlL]*").FullMatch(#value, Octal(&v))); \ CHECK_EQ(v, 0 ## value); \ CHECK(RE("([0-9a-fA-FxX]+)[uUlL]*").FullMatch("0" #value, CRadix(&v))); \ CHECK_EQ(v, 0 ## value); \ } while(0) CHECK_OCTAL(short, 77777); CHECK_OCTAL(unsigned short, 177777U); CHECK_OCTAL(int, 17777777777); CHECK_OCTAL(unsigned int, 37777777777U); CHECK_OCTAL(long, 17777777777L); CHECK_OCTAL(unsigned long, 37777777777UL); #ifdef HAVE_LONG_LONG CHECK_OCTAL(long long, 777777777777777777777LL); #endif #ifdef HAVE_UNSIGNED_LONG_LONG CHECK_OCTAL(unsigned long long, 1777777777777777777777ULL); #endif #undef CHECK_OCTAL printf("Testing decimal\n"); #define CHECK_DECIMAL(type, value) \ do { \ type v; \ CHECK(RE("(-?[0-9]+)[uUlL]*").FullMatch(#value, &v)); \ CHECK_EQ(v, value); \ CHECK(RE("(-?[0-9a-fA-FxX]+)[uUlL]*").FullMatch(#value, CRadix(&v))); \ CHECK_EQ(v, value); \ } while(0) CHECK_DECIMAL(short, -1); CHECK_DECIMAL(unsigned short, 9999); CHECK_DECIMAL(int, -1000); CHECK_DECIMAL(unsigned int, 12345U); CHECK_DECIMAL(long, -10000000L); CHECK_DECIMAL(unsigned long, 3083324652U); #ifdef HAVE_LONG_LONG CHECK_DECIMAL(long long, -100000000000000LL); #endif #ifdef HAVE_UNSIGNED_LONG_LONG CHECK_DECIMAL(unsigned long long, 1234567890987654321ULL); #endif #undef CHECK_DECIMAL } static void TestReplace() { printf("Testing Replace\n"); struct ReplaceTest { const char *regexp; const char *rewrite; const char *original; const char *single; const char *global; }; static const ReplaceTest tests[] = { { "(qu|[b-df-hj-np-tv-z]*)([a-z]+)", "\\2\\1ay", "the quick brown fox jumps over the lazy dogs.", "ethay quick brown fox jumps over the lazy dogs.", "ethay ickquay ownbray oxfay umpsjay overay ethay azylay ogsday." }, { "\\w+", "\\0-NOSPAM", "paul.haahr@google.com", "paul-NOSPAM.haahr@google.com", "paul-NOSPAM.haahr-NOSPAM@google-NOSPAM.com-NOSPAM" }, { "^", "(START)", "foo", "(START)foo", "(START)foo" }, { "^", "(START)", "", "(START)", "(START)" }, { "$", "(END)", "", "(END)", "(END)" }, { "b", "bb", "ababababab", "abbabababab", "abbabbabbabbabb" }, { "b", "bb", "bbbbbb", "bbbbbbb", "bbbbbbbbbbbb" }, { "b+", "bb", "bbbbbb", "bb", "bb" }, { "b*", "bb", "bbbbbb", "bb", "bb" }, { "b*", "bb", "aaaaa", "bbaaaaa", "bbabbabbabbabbabb" }, { "b*", "bb", "aa\naa\n", "bbaa\naa\n", "bbabbabb\nbbabbabb\nbb" }, { "b*", "bb", "aa\raa\r", "bbaa\raa\r", "bbabbabb\rbbabbabb\rbb" }, { "b*", "bb", "aa\r\naa\r\n", "bbaa\r\naa\r\n", "bbabbabb\r\nbbabbabb\r\nbb" }, #ifdef SUPPORT_UTF8 { "b*", "bb", "\xE3\x83\x9B\xE3\x83\xBC\xE3\x83\xA0\xE3\x81\xB8", // utf8 "bb\xE3\x83\x9B\xE3\x83\xBC\xE3\x83\xA0\xE3\x81\xB8", "bb\xE3\x83\x9B""bb""\xE3\x83\xBC""bb""\xE3\x83\xA0""bb""\xE3\x81\xB8""bb" }, { "b*", "bb", "\xE3\x83\x9B\r\n\xE3\x83\xBC\r\xE3\x83\xA0\n\xE3\x81\xB8\r\n", // utf8 "bb\xE3\x83\x9B\r\n\xE3\x83\xBC\r\xE3\x83\xA0\n\xE3\x81\xB8\r\n", ("bb\xE3\x83\x9B""bb\r\nbb""\xE3\x83\xBC""bb\rbb""\xE3\x83\xA0" "bb\nbb""\xE3\x81\xB8""bb\r\nbb") }, #endif { "", NULL, NULL, NULL, NULL } }; #ifdef SUPPORT_UTF8 const bool support_utf8 = true; #else const bool support_utf8 = false; #endif for (const ReplaceTest *t = tests; t->original != NULL; ++t) { RE re(t->regexp, RE_Options(PCRE_NEWLINE_CRLF).set_utf8(support_utf8)); assert(re.error().empty()); string one(t->original); CHECK(re.Replace(t->rewrite, &one)); CHECK_EQ(one, t->single); string all(t->original); CHECK(re.GlobalReplace(t->rewrite, &all) > 0); CHECK_EQ(all, t->global); } // One final test: test \r\n replacement when we're not in CRLF mode { RE re("b*", RE_Options(PCRE_NEWLINE_CR).set_utf8(support_utf8)); assert(re.error().empty()); string all("aa\r\naa\r\n"); CHECK(re.GlobalReplace("bb", &all) > 0); CHECK_EQ(all, string("bbabbabb\rbb\nbbabbabb\rbb\nbb")); } { RE re("b*", RE_Options(PCRE_NEWLINE_LF).set_utf8(support_utf8)); assert(re.error().empty()); string all("aa\r\naa\r\n"); CHECK(re.GlobalReplace("bb", &all) > 0); CHECK_EQ(all, string("bbabbabb\rbb\nbbabbabb\rbb\nbb")); } // TODO: test what happens when no PCRE_NEWLINE_* flag is set. // Alas, the answer depends on how pcre was compiled. } static void TestExtract() { printf("Testing Extract\n"); string s; CHECK(RE("(.*)@([^.]*)").Extract("\\2!\\1", "boris@kremvax.ru", &s)); CHECK_EQ(s, "kremvax!boris"); // check the RE interface as well CHECK(RE(".*").Extract("'\\0'", "foo", &s)); CHECK_EQ(s, "'foo'"); CHECK(!RE("bar").Extract("'\\0'", "baz", &s)); CHECK_EQ(s, "'foo'"); } static void TestConsume() { printf("Testing Consume\n"); string word; string s(" aaa b!@#$@#$cccc"); StringPiece input(s); RE r("\\s*(\\w+)"); // matches a word, possibly proceeded by whitespace CHECK(r.Consume(&input, &word)); CHECK_EQ(word, "aaa"); CHECK(r.Consume(&input, &word)); CHECK_EQ(word, "b"); CHECK(! r.Consume(&input, &word)); } static void TestFindAndConsume() { printf("Testing FindAndConsume\n"); string word; string s(" aaa b!@#$@#$cccc"); StringPiece input(s); RE r("(\\w+)"); // matches a word CHECK(r.FindAndConsume(&input, &word)); CHECK_EQ(word, "aaa"); CHECK(r.FindAndConsume(&input, &word)); CHECK_EQ(word, "b"); CHECK(r.FindAndConsume(&input, &word)); CHECK_EQ(word, "cccc"); CHECK(! r.FindAndConsume(&input, &word)); } static void TestMatchNumberPeculiarity() { printf("Testing match-number peculiaraity\n"); string word1; string word2; string word3; RE r("(foo)|(bar)|(baz)"); CHECK(r.PartialMatch("foo", &word1, &word2, &word3)); CHECK_EQ(word1, "foo"); CHECK_EQ(word2, ""); CHECK_EQ(word3, ""); CHECK(r.PartialMatch("bar", &word1, &word2, &word3)); CHECK_EQ(word1, ""); CHECK_EQ(word2, "bar"); CHECK_EQ(word3, ""); CHECK(r.PartialMatch("baz", &word1, &word2, &word3)); CHECK_EQ(word1, ""); CHECK_EQ(word2, ""); CHECK_EQ(word3, "baz"); CHECK(!r.PartialMatch("f", &word1, &word2, &word3)); string a; CHECK(RE("(foo)|hello").FullMatch("hello", &a)); CHECK_EQ(a, ""); } static void TestRecursion() { printf("Testing recursion\n"); // Get one string that passes (sometimes), one that never does. string text_good("abcdefghijk"); string text_bad("acdefghijkl"); // According to pcretest, matching text_good against (\w+)*b // requires match_limit of at least 8192, and match_recursion_limit // of at least 37. RE_Options options_ml; options_ml.set_match_limit(8192); RE re("(\\w+)*b", options_ml); CHECK(re.PartialMatch(text_good) == true); CHECK(re.PartialMatch(text_bad) == false); CHECK(re.FullMatch(text_good) == false); CHECK(re.FullMatch(text_bad) == false); options_ml.set_match_limit(1024); RE re2("(\\w+)*b", options_ml); CHECK(re2.PartialMatch(text_good) == false); // because of match_limit CHECK(re2.PartialMatch(text_bad) == false); CHECK(re2.FullMatch(text_good) == false); CHECK(re2.FullMatch(text_bad) == false); RE_Options options_mlr; options_mlr.set_match_limit_recursion(50); RE re3("(\\w+)*b", options_mlr); CHECK(re3.PartialMatch(text_good) == true); CHECK(re3.PartialMatch(text_bad) == false); CHECK(re3.FullMatch(text_good) == false); CHECK(re3.FullMatch(text_bad) == false); options_mlr.set_match_limit_recursion(10); RE re4("(\\w+)*b", options_mlr); CHECK(re4.PartialMatch(text_good) == false); CHECK(re4.PartialMatch(text_bad) == false); CHECK(re4.FullMatch(text_good) == false); CHECK(re4.FullMatch(text_bad) == false); } // A meta-quoted string, interpreted as a pattern, should always match // the original unquoted string. static void TestQuoteMeta(string unquoted, RE_Options options = RE_Options()) { string quoted = RE::QuoteMeta(unquoted); RE re(quoted, options); CHECK(re.FullMatch(unquoted)); } // A string containing meaningful regexp characters, which is then meta- // quoted, should not generally match a string the unquoted string does. static void NegativeTestQuoteMeta(string unquoted, string should_not_match, RE_Options options = RE_Options()) { string quoted = RE::QuoteMeta(unquoted); RE re(quoted, options); CHECK(!re.FullMatch(should_not_match)); } // Tests that quoted meta characters match their original strings, // and that a few things that shouldn't match indeed do not. static void TestQuotaMetaSimple() { TestQuoteMeta("foo"); TestQuoteMeta("foo.bar"); TestQuoteMeta("foo\\.bar"); TestQuoteMeta("[1-9]"); TestQuoteMeta("1.5-2.0?"); TestQuoteMeta("\\d"); TestQuoteMeta("Who doesn't like ice cream?"); TestQuoteMeta("((a|b)c?d*e+[f-h]i)"); TestQuoteMeta("((?!)xxx).*yyy"); TestQuoteMeta("(["); } static void TestQuoteMetaSimpleNegative() { NegativeTestQuoteMeta("foo", "bar"); NegativeTestQuoteMeta("...", "bar"); NegativeTestQuoteMeta("\\.", "."); NegativeTestQuoteMeta("\\.", ".."); NegativeTestQuoteMeta("(a)", "a"); NegativeTestQuoteMeta("(a|b)", "a"); NegativeTestQuoteMeta("(a|b)", "(a)"); NegativeTestQuoteMeta("(a|b)", "a|b"); NegativeTestQuoteMeta("[0-9]", "0"); NegativeTestQuoteMeta("[0-9]", "0-9"); NegativeTestQuoteMeta("[0-9]", "[9]"); NegativeTestQuoteMeta("((?!)xxx)", "xxx"); } static void TestQuoteMetaLatin1() { TestQuoteMeta("3\xb2 = 9"); } static void TestQuoteMetaUtf8() { #ifdef SUPPORT_UTF8 TestQuoteMeta("Pl\xc3\xa1\x63ido Domingo", pcrecpp::UTF8()); TestQuoteMeta("xyz", pcrecpp::UTF8()); // No fancy utf8 TestQuoteMeta("\xc2\xb0", pcrecpp::UTF8()); // 2-byte utf8 (degree symbol) TestQuoteMeta("27\xc2\xb0 degrees", pcrecpp::UTF8()); // As a middle character TestQuoteMeta("\xe2\x80\xb3", pcrecpp::UTF8()); // 3-byte utf8 (double prime) TestQuoteMeta("\xf0\x9d\x85\x9f", pcrecpp::UTF8()); // 4-byte utf8 (music note) TestQuoteMeta("27\xc2\xb0"); // Interpreted as Latin-1, but should still work NegativeTestQuoteMeta("27\xc2\xb0", // 2-byte utf (degree symbol) "27\\\xc2\\\xb0", pcrecpp::UTF8()); #endif } static void TestQuoteMetaAll() { printf("Testing QuoteMeta\n"); TestQuotaMetaSimple(); TestQuoteMetaSimpleNegative(); TestQuoteMetaLatin1(); TestQuoteMetaUtf8(); } // // Options tests contributed by // Giuseppe Maxia, CTO, Stardata s.r.l. // July 2005 // static void GetOneOptionResult( const char *option_name, const char *regex, const char *str, RE_Options options, bool full, string expected) { printf("Testing Option <%s>\n", option_name); if(VERBOSE_TEST) printf("/%s/ finds \"%s\" within \"%s\" \n", regex, expected.c_str(), str); string captured(""); if (full) RE(regex,options).FullMatch(str, &captured); else RE(regex,options).PartialMatch(str, &captured); CHECK_EQ(captured, expected); } static void TestOneOption( const char *option_name, const char *regex, const char *str, RE_Options options, bool full, bool assertive = true) { printf("Testing Option <%s>\n", option_name); if (VERBOSE_TEST) printf("'%s' %s /%s/ \n", str, (assertive? "matches" : "doesn't match"), regex); if (assertive) { if (full) CHECK(RE(regex,options).FullMatch(str)); else CHECK(RE(regex,options).PartialMatch(str)); } else { if (full) CHECK(!RE(regex,options).FullMatch(str)); else CHECK(!RE(regex,options).PartialMatch(str)); } } static void Test_CASELESS() { RE_Options options; RE_Options options2; options.set_caseless(true); TestOneOption("CASELESS (class)", "HELLO", "hello", options, false); TestOneOption("CASELESS (class2)", "HELLO", "hello", options2.set_caseless(true), false); TestOneOption("CASELESS (class)", "^[A-Z]+$", "Hello", options, false); TestOneOption("CASELESS (function)", "HELLO", "hello", pcrecpp::CASELESS(), false); TestOneOption("CASELESS (function)", "^[A-Z]+$", "Hello", pcrecpp::CASELESS(), false); options.set_caseless(false); TestOneOption("no CASELESS", "HELLO", "hello", options, false, false); } static void Test_MULTILINE() { RE_Options options; RE_Options options2; const char *str = "HELLO\n" "cruel\n" "world\n"; options.set_multiline(true); TestOneOption("MULTILINE (class)", "^cruel$", str, options, false); TestOneOption("MULTILINE (class2)", "^cruel$", str, options2.set_multiline(true), false); TestOneOption("MULTILINE (function)", "^cruel$", str, pcrecpp::MULTILINE(), false); options.set_multiline(false); TestOneOption("no MULTILINE", "^cruel$", str, options, false, false); } static void Test_DOTALL() { RE_Options options; RE_Options options2; const char *str = "HELLO\n" "cruel\n" "world"; options.set_dotall(true); TestOneOption("DOTALL (class)", "HELLO.*world", str, options, true); TestOneOption("DOTALL (class2)", "HELLO.*world", str, options2.set_dotall(true), true); TestOneOption("DOTALL (function)", "HELLO.*world", str, pcrecpp::DOTALL(), true); options.set_dotall(false); TestOneOption("no DOTALL", "HELLO.*world", str, options, true, false); } static void Test_DOLLAR_ENDONLY() { RE_Options options; RE_Options options2; const char *str = "HELLO world\n"; TestOneOption("no DOLLAR_ENDONLY", "world$", str, options, false); options.set_dollar_endonly(true); TestOneOption("DOLLAR_ENDONLY 1", "world$", str, options, false, false); TestOneOption("DOLLAR_ENDONLY 2", "world$", str, options2.set_dollar_endonly(true), false, false); } static void Test_EXTRA() { RE_Options options; const char *str = "HELLO"; options.set_extra(true); TestOneOption("EXTRA 1", "\\HELL\\O", str, options, true, false ); TestOneOption("EXTRA 2", "\\HELL\\O", str, RE_Options().set_extra(true), true, false ); options.set_extra(false); TestOneOption("no EXTRA", "\\HELL\\O", str, options, true ); } static void Test_EXTENDED() { RE_Options options; RE_Options options2; const char *str = "HELLO world"; options.set_extended(true); TestOneOption("EXTENDED (class)", "HELLO world", str, options, false, false); TestOneOption("EXTENDED (class2)", "HELLO world", str, options2.set_extended(true), false, false); TestOneOption("EXTENDED (class)", "^ HE L{2} O " "\\s+ " "\\w+ $ ", str, options, false); TestOneOption("EXTENDED (function)", "HELLO world", str, pcrecpp::EXTENDED(), false, false); TestOneOption("EXTENDED (function)", "^ HE L{2} O " "\\s+ " "\\w+ $ ", str, pcrecpp::EXTENDED(), false); options.set_extended(false); TestOneOption("no EXTENDED", "HELLO world", str, options, false); } static void Test_NO_AUTO_CAPTURE() { RE_Options options; const char *str = "HELLO world"; string captured; printf("Testing Option \n"); if (VERBOSE_TEST) printf("parentheses capture text\n"); RE re("(world|universe)$", options); CHECK(re.Extract("\\1", str , &captured)); CHECK_EQ(captured, "world"); options.set_no_auto_capture(true); printf("testing Option \n"); if (VERBOSE_TEST) printf("parentheses do not capture text\n"); re.Extract("\\1",str, &captured ); CHECK_EQ(captured, "world"); } static void Test_UNGREEDY() { RE_Options options; const char *str = "HELLO, 'this' is the 'world'"; options.set_ungreedy(true); GetOneOptionResult("UNGREEDY 1", "('.*')", str, options, false, "'this'" ); GetOneOptionResult("UNGREEDY 2", "('.*')", str, RE_Options().set_ungreedy(true), false, "'this'" ); GetOneOptionResult("UNGREEDY", "('.*?')", str, options, false, "'this' is the 'world'" ); options.set_ungreedy(false); GetOneOptionResult("no UNGREEDY", "('.*')", str, options, false, "'this' is the 'world'" ); GetOneOptionResult("no UNGREEDY", "('.*?')", str, options, false, "'this'" ); } static void Test_all_options() { const char *str = "HELLO\n" "cruel\n" "world"; RE_Options options; options.set_all_options(PCRE_CASELESS | PCRE_DOTALL); TestOneOption("all_options (CASELESS|DOTALL)", "^hello.*WORLD", str , options, false); options.set_all_options(0); TestOneOption("all_options (0)", "^hello.*WORLD", str , options, false, false); options.set_all_options(PCRE_MULTILINE | PCRE_EXTENDED); TestOneOption("all_options (MULTILINE|EXTENDED)", " ^ c r u e l $ ", str, options, false); TestOneOption("all_options (MULTILINE|EXTENDED) with constructor", " ^ c r u e l $ ", str, RE_Options(PCRE_MULTILINE | PCRE_EXTENDED), false); TestOneOption("all_options (MULTILINE|EXTENDED) with concatenation", " ^ c r u e l $ ", str, RE_Options() .set_multiline(true) .set_extended(true), false); options.set_all_options(0); TestOneOption("all_options (0)", "^ c r u e l $", str, options, false, false); } static void TestOptions() { printf("Testing Options\n"); Test_CASELESS(); Test_MULTILINE(); Test_DOTALL(); Test_DOLLAR_ENDONLY(); Test_EXTENDED(); Test_NO_AUTO_CAPTURE(); Test_UNGREEDY(); Test_EXTRA(); Test_all_options(); } static void TestConstructors() { printf("Testing constructors\n"); RE_Options options; options.set_dotall(true); const char *str = "HELLO\n" "cruel\n" "world"; RE orig("HELLO.*world", options); CHECK(orig.FullMatch(str)); RE copy1(orig); CHECK(copy1.FullMatch(str)); RE copy2("not a match"); CHECK(!copy2.FullMatch(str)); copy2 = copy1; CHECK(copy2.FullMatch(str)); copy2 = orig; CHECK(copy2.FullMatch(str)); // Make sure when we assign to ourselves, nothing bad happens orig = orig; copy1 = copy1; copy2 = copy2; CHECK(orig.FullMatch(str)); CHECK(copy1.FullMatch(str)); CHECK(copy2.FullMatch(str)); } int main(int argc, char** argv) { // Treat any flag as --help if (argc > 1 && argv[1][0] == '-') { printf("Usage: %s [timing1|timing2|timing3 num-iters]\n" " If 'timingX ###' is specified, run the given timing test\n" " with the given number of iterations, rather than running\n" " the default corectness test.\n", argv[0]); return 0; } if (argc > 1) { if ( argc == 2 || atoi(argv[2]) == 0) { printf("timing mode needs a num-iters argument\n"); return 1; } if (!strcmp(argv[1], "timing1")) Timing1(atoi(argv[2])); else if (!strcmp(argv[1], "timing2")) Timing2(atoi(argv[2])); else if (!strcmp(argv[1], "timing3")) Timing3(atoi(argv[2])); else printf("Unknown argument '%s'\n", argv[1]); return 0; } printf("Testing FullMatch\n"); int i; string s; /***** FullMatch with no args *****/ CHECK(RE("h.*o").FullMatch("hello")); CHECK(!RE("h.*o").FullMatch("othello")); // Must be anchored at front CHECK(!RE("h.*o").FullMatch("hello!")); // Must be anchored at end CHECK(RE("a*").FullMatch("aaaa")); // Fullmatch with normal op CHECK(RE("a*?").FullMatch("aaaa")); // Fullmatch with nongreedy op CHECK(RE("a*?\\z").FullMatch("aaaa")); // Two unusual ops /***** FullMatch with args *****/ // Zero-arg CHECK(RE("\\d+").FullMatch("1001")); // Single-arg CHECK(RE("(\\d+)").FullMatch("1001", &i)); CHECK_EQ(i, 1001); CHECK(RE("(-?\\d+)").FullMatch("-123", &i)); CHECK_EQ(i, -123); CHECK(!RE("()\\d+").FullMatch("10", &i)); CHECK(!RE("(\\d+)").FullMatch("1234567890123456789012345678901234567890", &i)); // Digits surrounding integer-arg CHECK(RE("1(\\d*)4").FullMatch("1234", &i)); CHECK_EQ(i, 23); CHECK(RE("(\\d)\\d+").FullMatch("1234", &i)); CHECK_EQ(i, 1); CHECK(RE("(-\\d)\\d+").FullMatch("-1234", &i)); CHECK_EQ(i, -1); CHECK(RE("(\\d)").PartialMatch("1234", &i)); CHECK_EQ(i, 1); CHECK(RE("(-\\d)").PartialMatch("-1234", &i)); CHECK_EQ(i, -1); // String-arg CHECK(RE("h(.*)o").FullMatch("hello", &s)); CHECK_EQ(s, string("ell")); // StringPiece-arg StringPiece sp; CHECK(RE("(\\w+):(\\d+)").FullMatch("ruby:1234", &sp, &i)); CHECK_EQ(sp.size(), 4); CHECK(memcmp(sp.data(), "ruby", 4) == 0); CHECK_EQ(i, 1234); // Multi-arg CHECK(RE("(\\w+):(\\d+)").FullMatch("ruby:1234", &s, &i)); CHECK_EQ(s, string("ruby")); CHECK_EQ(i, 1234); // Ignored arg CHECK(RE("(\\w+)(:)(\\d+)").FullMatch("ruby:1234", &s, (void*)NULL, &i)); CHECK_EQ(s, string("ruby")); CHECK_EQ(i, 1234); // Type tests { char c; CHECK(RE("(H)ello").FullMatch("Hello", &c)); CHECK_EQ(c, 'H'); } { unsigned char c; CHECK(RE("(H)ello").FullMatch("Hello", &c)); CHECK_EQ(c, static_cast('H')); } { short v; CHECK(RE("(-?\\d+)").FullMatch("100", &v)); CHECK_EQ(v, 100); CHECK(RE("(-?\\d+)").FullMatch("-100", &v)); CHECK_EQ(v, -100); CHECK(RE("(-?\\d+)").FullMatch("32767", &v)); CHECK_EQ(v, 32767); CHECK(RE("(-?\\d+)").FullMatch("-32768", &v)); CHECK_EQ(v, -32768); CHECK(!RE("(-?\\d+)").FullMatch("-32769", &v)); CHECK(!RE("(-?\\d+)").FullMatch("32768", &v)); } { unsigned short v; CHECK(RE("(\\d+)").FullMatch("100", &v)); CHECK_EQ(v, 100); CHECK(RE("(\\d+)").FullMatch("32767", &v)); CHECK_EQ(v, 32767); CHECK(RE("(\\d+)").FullMatch("65535", &v)); CHECK_EQ(v, 65535); CHECK(!RE("(\\d+)").FullMatch("65536", &v)); } { int v; static const int max_value = 0x7fffffff; static const int min_value = -max_value - 1; CHECK(RE("(-?\\d+)").FullMatch("100", &v)); CHECK_EQ(v, 100); CHECK(RE("(-?\\d+)").FullMatch("-100", &v)); CHECK_EQ(v, -100); CHECK(RE("(-?\\d+)").FullMatch("2147483647", &v)); CHECK_EQ(v, max_value); CHECK(RE("(-?\\d+)").FullMatch("-2147483648", &v)); CHECK_EQ(v, min_value); CHECK(!RE("(-?\\d+)").FullMatch("-2147483649", &v)); CHECK(!RE("(-?\\d+)").FullMatch("2147483648", &v)); } { unsigned int v; static const unsigned int max_value = 0xfffffffful; CHECK(RE("(\\d+)").FullMatch("100", &v)); CHECK_EQ(v, 100); CHECK(RE("(\\d+)").FullMatch("4294967295", &v)); CHECK_EQ(v, max_value); CHECK(!RE("(\\d+)").FullMatch("4294967296", &v)); } #ifdef HAVE_LONG_LONG # if defined(__MINGW__) || defined(__MINGW32__) # define LLD "%I64d" # define LLU "%I64u" # else # define LLD "%lld" # define LLU "%llu" # endif { long long v; static const long long max_value = 0x7fffffffffffffffLL; static const long long min_value = -max_value - 1; char buf[32]; CHECK(RE("(-?\\d+)").FullMatch("100", &v)); CHECK_EQ(v, 100); CHECK(RE("(-?\\d+)").FullMatch("-100",&v)); CHECK_EQ(v, -100); snprintf(buf, sizeof(buf), LLD, max_value); CHECK(RE("(-?\\d+)").FullMatch(buf,&v)); CHECK_EQ(v, max_value); snprintf(buf, sizeof(buf), LLD, min_value); CHECK(RE("(-?\\d+)").FullMatch(buf,&v)); CHECK_EQ(v, min_value); snprintf(buf, sizeof(buf), LLD, max_value); assert(buf[strlen(buf)-1] != '9'); buf[strlen(buf)-1]++; CHECK(!RE("(-?\\d+)").FullMatch(buf, &v)); snprintf(buf, sizeof(buf), LLD, min_value); assert(buf[strlen(buf)-1] != '9'); buf[strlen(buf)-1]++; CHECK(!RE("(-?\\d+)").FullMatch(buf, &v)); } #endif #if defined HAVE_UNSIGNED_LONG_LONG && defined HAVE_LONG_LONG { unsigned long long v; long long v2; static const unsigned long long max_value = 0xffffffffffffffffULL; char buf[32]; CHECK(RE("(-?\\d+)").FullMatch("100",&v)); CHECK_EQ(v, 100); CHECK(RE("(-?\\d+)").FullMatch("-100",&v2)); CHECK_EQ(v2, -100); snprintf(buf, sizeof(buf), LLU, max_value); CHECK(RE("(-?\\d+)").FullMatch(buf,&v)); CHECK_EQ(v, max_value); assert(buf[strlen(buf)-1] != '9'); buf[strlen(buf)-1]++; CHECK(!RE("(-?\\d+)").FullMatch(buf, &v)); } #endif { float v; CHECK(RE("(.*)").FullMatch("100", &v)); CHECK(RE("(.*)").FullMatch("-100.", &v)); CHECK(RE("(.*)").FullMatch("1e23", &v)); } { double v; CHECK(RE("(.*)").FullMatch("100", &v)); CHECK(RE("(.*)").FullMatch("-100.", &v)); CHECK(RE("(.*)").FullMatch("1e23", &v)); } // Check that matching is fully anchored CHECK(!RE("(\\d+)").FullMatch("x1001", &i)); CHECK(!RE("(\\d+)").FullMatch("1001x", &i)); CHECK(RE("x(\\d+)").FullMatch("x1001", &i)); CHECK_EQ(i, 1001); CHECK(RE("(\\d+)x").FullMatch("1001x", &i)); CHECK_EQ(i, 1001); // Braces CHECK(RE("[0-9a-f+.-]{5,}").FullMatch("0abcd")); CHECK(RE("[0-9a-f+.-]{5,}").FullMatch("0abcde")); CHECK(!RE("[0-9a-f+.-]{5,}").FullMatch("0abc")); // Complicated RE CHECK(RE("foo|bar|[A-Z]").FullMatch("foo")); CHECK(RE("foo|bar|[A-Z]").FullMatch("bar")); CHECK(RE("foo|bar|[A-Z]").FullMatch("X")); CHECK(!RE("foo|bar|[A-Z]").FullMatch("XY")); // Check full-match handling (needs '$' tacked on internally) CHECK(RE("fo|foo").FullMatch("fo")); CHECK(RE("fo|foo").FullMatch("foo")); CHECK(RE("fo|foo$").FullMatch("fo")); CHECK(RE("fo|foo$").FullMatch("foo")); CHECK(RE("foo$").FullMatch("foo")); CHECK(!RE("foo\\$").FullMatch("foo$bar")); CHECK(!RE("fo|bar").FullMatch("fox")); // Uncomment the following if we change the handling of '$' to // prevent it from matching a trailing newline if (false) { // Check that we don't get bitten by pcre's special handling of a // '\n' at the end of the string matching '$' CHECK(!RE("foo$").PartialMatch("foo\n")); } // Number of args int a[16]; CHECK(RE("").FullMatch("")); memset(a, 0, sizeof(0)); CHECK(RE("(\\d){1}").FullMatch("1", &a[0])); CHECK_EQ(a[0], 1); memset(a, 0, sizeof(0)); CHECK(RE("(\\d)(\\d)").FullMatch("12", &a[0], &a[1])); CHECK_EQ(a[0], 1); CHECK_EQ(a[1], 2); memset(a, 0, sizeof(0)); CHECK(RE("(\\d)(\\d)(\\d)").FullMatch("123", &a[0], &a[1], &a[2])); CHECK_EQ(a[0], 1); CHECK_EQ(a[1], 2); CHECK_EQ(a[2], 3); memset(a, 0, sizeof(0)); CHECK(RE("(\\d)(\\d)(\\d)(\\d)").FullMatch("1234", &a[0], &a[1], &a[2], &a[3])); CHECK_EQ(a[0], 1); CHECK_EQ(a[1], 2); CHECK_EQ(a[2], 3); CHECK_EQ(a[3], 4); memset(a, 0, sizeof(0)); CHECK(RE("(\\d)(\\d)(\\d)(\\d)(\\d)").FullMatch("12345", &a[0], &a[1], &a[2], &a[3], &a[4])); CHECK_EQ(a[0], 1); CHECK_EQ(a[1], 2); CHECK_EQ(a[2], 3); CHECK_EQ(a[3], 4); CHECK_EQ(a[4], 5); memset(a, 0, sizeof(0)); CHECK(RE("(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)").FullMatch("123456", &a[0], &a[1], &a[2], &a[3], &a[4], &a[5])); CHECK_EQ(a[0], 1); CHECK_EQ(a[1], 2); CHECK_EQ(a[2], 3); CHECK_EQ(a[3], 4); CHECK_EQ(a[4], 5); CHECK_EQ(a[5], 6); memset(a, 0, sizeof(0)); CHECK(RE("(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)").FullMatch("1234567", &a[0], &a[1], &a[2], &a[3], &a[4], &a[5], &a[6])); CHECK_EQ(a[0], 1); CHECK_EQ(a[1], 2); CHECK_EQ(a[2], 3); CHECK_EQ(a[3], 4); CHECK_EQ(a[4], 5); CHECK_EQ(a[5], 6); CHECK_EQ(a[6], 7); memset(a, 0, sizeof(0)); CHECK(RE("(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)" "(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)").FullMatch( "1234567890123456", &a[0], &a[1], &a[2], &a[3], &a[4], &a[5], &a[6], &a[7], &a[8], &a[9], &a[10], &a[11], &a[12], &a[13], &a[14], &a[15])); CHECK_EQ(a[0], 1); CHECK_EQ(a[1], 2); CHECK_EQ(a[2], 3); CHECK_EQ(a[3], 4); CHECK_EQ(a[4], 5); CHECK_EQ(a[5], 6); CHECK_EQ(a[6], 7); CHECK_EQ(a[7], 8); CHECK_EQ(a[8], 9); CHECK_EQ(a[9], 0); CHECK_EQ(a[10], 1); CHECK_EQ(a[11], 2); CHECK_EQ(a[12], 3); CHECK_EQ(a[13], 4); CHECK_EQ(a[14], 5); CHECK_EQ(a[15], 6); /***** PartialMatch *****/ printf("Testing PartialMatch\n"); CHECK(RE("h.*o").PartialMatch("hello")); CHECK(RE("h.*o").PartialMatch("othello")); CHECK(RE("h.*o").PartialMatch("hello!")); CHECK(RE("((((((((((((((((((((x))))))))))))))))))))").PartialMatch("x")); /***** other tests *****/ RadixTests(); TestReplace(); TestExtract(); TestConsume(); TestFindAndConsume(); TestQuoteMetaAll(); TestMatchNumberPeculiarity(); // Check the pattern() accessor { const string kPattern = "http://([^/]+)/.*"; const RE re(kPattern); CHECK_EQ(kPattern, re.pattern()); } // Check RE error field. { RE re("foo"); CHECK(re.error().empty()); // Must have no error } #ifdef SUPPORT_UTF8 // Check UTF-8 handling { printf("Testing UTF-8 handling\n"); // Three Japanese characters (nihongo) const char utf8_string[] = { 0xe6, 0x97, 0xa5, // 65e5 0xe6, 0x9c, 0xac, // 627c 0xe8, 0xaa, 0x9e, // 8a9e 0 }; const char utf8_pattern[] = { '.', 0xe6, 0x9c, 0xac, // 627c '.', 0 }; // Both should match in either mode, bytes or UTF-8 RE re_test1("........."); CHECK(re_test1.FullMatch(utf8_string)); RE re_test2("...", pcrecpp::UTF8()); CHECK(re_test2.FullMatch(utf8_string)); // Check that '.' matches one byte or UTF-8 character // according to the mode. string ss; RE re_test3("(.)"); CHECK(re_test3.PartialMatch(utf8_string, &ss)); CHECK_EQ(ss, string("\xe6")); RE re_test4("(.)", pcrecpp::UTF8()); CHECK(re_test4.PartialMatch(utf8_string, &ss)); CHECK_EQ(ss, string("\xe6\x97\xa5")); // Check that string matches itself in either mode RE re_test5(utf8_string); CHECK(re_test5.FullMatch(utf8_string)); RE re_test6(utf8_string, pcrecpp::UTF8()); CHECK(re_test6.FullMatch(utf8_string)); // Check that pattern matches string only in UTF8 mode RE re_test7(utf8_pattern); CHECK(!re_test7.FullMatch(utf8_string)); RE re_test8(utf8_pattern, pcrecpp::UTF8()); CHECK(re_test8.FullMatch(utf8_string)); } // Check that ungreedy, UTF8 regular expressions don't match when they // oughtn't -- see bug 82246. { // This code always worked. const char* pattern = "\\w+X"; const string target = "a aX"; RE match_sentence(pattern); RE match_sentence_re(pattern, pcrecpp::UTF8()); CHECK(!match_sentence.FullMatch(target)); CHECK(!match_sentence_re.FullMatch(target)); } { const char* pattern = "(?U)\\w+X"; const string target = "a aX"; RE match_sentence(pattern); RE match_sentence_re(pattern, pcrecpp::UTF8()); CHECK(!match_sentence.FullMatch(target)); CHECK(!match_sentence_re.FullMatch(target)); } #endif /* def SUPPORT_UTF8 */ printf("Testing error reporting\n"); { RE re("a\\1"); CHECK(!re.error().empty()); } { RE re("a[x"); CHECK(!re.error().empty()); } { RE re("a[z-a]"); CHECK(!re.error().empty()); } { RE re("a[[:foobar:]]"); CHECK(!re.error().empty()); } { RE re("a(b"); CHECK(!re.error().empty()); } { RE re("a\\"); CHECK(!re.error().empty()); } // Test that recursion is stopped TestRecursion(); // Test Options if (getenv("VERBOSE_TEST") != NULL) VERBOSE_TEST = true; TestOptions(); // Test the constructors TestConstructors(); // Done printf("OK\n"); return 0; } libsynthesis-3.4.0.47.1/src/pcre/pcrecpparg.h.in000066400000000000000000000152561226375725500213010ustar00rootroot00000000000000// Copyright (c) 2005, Google Inc. // 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 name of Google Inc. 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. // // Author: Sanjay Ghemawat #ifndef _PCRECPPARG_H #define _PCRECPPARG_H #include // for NULL #include #include namespace pcrecpp { class StringPiece; // Hex/Octal/Binary? // Special class for parsing into objects that define a ParseFrom() method template class _RE_MatchObject { public: static inline bool Parse(const char* str, int n, void* dest) { T* object = reinterpret_cast(dest); return object->ParseFrom(str, n); } }; class PCRECPP_EXP_DEFN Arg { public: // Empty constructor so we can declare arrays of Arg Arg(); // Constructor specially designed for NULL arguments Arg(void*); typedef bool (*Parser)(const char* str, int n, void* dest); // Type-specific parsers #define PCRE_MAKE_PARSER(type,name) \ Arg(type* p) : arg_(p), parser_(name) { } \ Arg(type* p, Parser parser) : arg_(p), parser_(parser) { } PCRE_MAKE_PARSER(char, parse_char); PCRE_MAKE_PARSER(unsigned char, parse_uchar); PCRE_MAKE_PARSER(short, parse_short); PCRE_MAKE_PARSER(unsigned short, parse_ushort); PCRE_MAKE_PARSER(int, parse_int); PCRE_MAKE_PARSER(unsigned int, parse_uint); PCRE_MAKE_PARSER(long, parse_long); PCRE_MAKE_PARSER(unsigned long, parse_ulong); #if @pcre_have_long_long@ PCRE_MAKE_PARSER(long long, parse_longlong); #endif #if @pcre_have_ulong_long@ PCRE_MAKE_PARSER(unsigned long long, parse_ulonglong); #endif PCRE_MAKE_PARSER(float, parse_float); PCRE_MAKE_PARSER(double, parse_double); PCRE_MAKE_PARSER(std::string, parse_string); PCRE_MAKE_PARSER(StringPiece, parse_stringpiece); #undef PCRE_MAKE_PARSER // Generic constructor template Arg(T*, Parser parser); // Generic constructor template template Arg(T* p) : arg_(p), parser_(_RE_MatchObject::Parse) { } // Parse the data bool Parse(const char* str, int n) const; private: void* arg_; Parser parser_; static bool parse_null (const char* str, int n, void* dest); static bool parse_char (const char* str, int n, void* dest); static bool parse_uchar (const char* str, int n, void* dest); static bool parse_float (const char* str, int n, void* dest); static bool parse_double (const char* str, int n, void* dest); static bool parse_string (const char* str, int n, void* dest); static bool parse_stringpiece (const char* str, int n, void* dest); #define PCRE_DECLARE_INTEGER_PARSER(name) \ private: \ static bool parse_ ## name(const char* str, int n, void* dest); \ static bool parse_ ## name ## _radix( \ const char* str, int n, void* dest, int radix); \ public: \ static bool parse_ ## name ## _hex(const char* str, int n, void* dest); \ static bool parse_ ## name ## _octal(const char* str, int n, void* dest); \ static bool parse_ ## name ## _cradix(const char* str, int n, void* dest) PCRE_DECLARE_INTEGER_PARSER(short); PCRE_DECLARE_INTEGER_PARSER(ushort); PCRE_DECLARE_INTEGER_PARSER(int); PCRE_DECLARE_INTEGER_PARSER(uint); PCRE_DECLARE_INTEGER_PARSER(long); PCRE_DECLARE_INTEGER_PARSER(ulong); PCRE_DECLARE_INTEGER_PARSER(longlong); PCRE_DECLARE_INTEGER_PARSER(ulonglong); #undef PCRE_DECLARE_INTEGER_PARSER }; inline Arg::Arg() : arg_(NULL), parser_(parse_null) { } inline Arg::Arg(void* p) : arg_(p), parser_(parse_null) { } inline bool Arg::Parse(const char* str, int n) const { return (*parser_)(str, n, arg_); } // This part of the parser, appropriate only for ints, deals with bases #define MAKE_INTEGER_PARSER(type, name) \ inline Arg Hex(type* ptr) { \ return Arg(ptr, Arg::parse_ ## name ## _hex); } \ inline Arg Octal(type* ptr) { \ return Arg(ptr, Arg::parse_ ## name ## _octal); } \ inline Arg CRadix(type* ptr) { \ return Arg(ptr, Arg::parse_ ## name ## _cradix); } MAKE_INTEGER_PARSER(short, short) /* */ MAKE_INTEGER_PARSER(unsigned short, ushort) /* */ MAKE_INTEGER_PARSER(int, int) /* Don't use semicolons */ MAKE_INTEGER_PARSER(unsigned int, uint) /* after these statement */ MAKE_INTEGER_PARSER(long, long) /* because they can cause */ MAKE_INTEGER_PARSER(unsigned long, ulong) /* compiler warnings if */ #if @pcre_have_long_long@ /* the checking level is */ MAKE_INTEGER_PARSER(long long, longlong) /* turned up high enough. */ #endif /* */ #if @pcre_have_ulong_long@ /* */ MAKE_INTEGER_PARSER(unsigned long long, ulonglong) /* */ #endif #undef PCRE_IS_SET #undef PCRE_SET_OR_CLEAR #undef MAKE_INTEGER_PARSER } // namespace pcrecpp #endif /* _PCRECPPARG_H */ libsynthesis-3.4.0.47.1/src/pcre/pcredemo.c000066400000000000000000000270441226375725500203350ustar00rootroot00000000000000/************************************************* * PCRE DEMONSTRATION PROGRAM * *************************************************/ /* This is a demonstration program to illustrate the most straightforward ways of calling the PCRE regular expression library from a C program. See the pcresample documentation for a short discussion. Compile thuswise: gcc -Wall pcredemo.c -I/usr/local/include -L/usr/local/lib \ -R/usr/local/lib -lpcre Replace "/usr/local/include" and "/usr/local/lib" with wherever the include and library files for PCRE are installed on your system. You don't need -I and -L if PCRE is installed in the standard system libraries. Only some operating systems (e.g. Solaris) use the -R option. */ #include #include #include #define OVECCOUNT 30 /* should be a multiple of 3 */ int main(int argc, char **argv) { pcre *re; const char *error; char *pattern; char *subject; unsigned char *name_table; int erroffset; int find_all; int namecount; int name_entry_size; int ovector[OVECCOUNT]; int subject_length; int rc, i; /************************************************************************** * First, sort out the command line. There is only one possible option at * * the moment, "-g" to request repeated matching to find all occurrences, * * like Perl's /g option. We set the variable find_all to a non-zero value * * if the -g option is present. Apart from that, there must be exactly two * * arguments. * **************************************************************************/ find_all = 0; for (i = 1; i < argc; i++) { if (strcmp(argv[i], "-g") == 0) find_all = 1; else break; } /* After the options, we require exactly two arguments, which are the pattern, and the subject string. */ if (argc - i != 2) { printf("Two arguments required: a regex and a subject string\n"); return 1; } pattern = argv[i]; subject = argv[i+1]; subject_length = (int)strlen(subject); /************************************************************************* * Now we are going to compile the regular expression pattern, and handle * * and errors that are detected. * *************************************************************************/ re = pcre_compile( pattern, /* the pattern */ 0, /* default options */ &error, /* for error message */ &erroffset, /* for error offset */ NULL); /* use default character tables */ /* Compilation failed: print the error message and exit */ if (re == NULL) { printf("PCRE compilation failed at offset %d: %s\n", erroffset, error); return 1; } /************************************************************************* * If the compilation succeeded, we call PCRE again, in order to do a * * pattern match against the subject string. This does just ONE match. If * * further matching is needed, it will be done below. * *************************************************************************/ rc = pcre_exec( re, /* the compiled pattern */ NULL, /* no extra data - we didn't study the pattern */ subject, /* the subject string */ subject_length, /* the length of the subject */ 0, /* start at offset 0 in the subject */ 0, /* default options */ ovector, /* output vector for substring information */ OVECCOUNT); /* number of elements in the output vector */ /* Matching failed: handle error cases */ if (rc < 0) { switch(rc) { case PCRE_ERROR_NOMATCH: printf("No match\n"); break; /* Handle other special cases if you like */ default: printf("Matching error %d\n", rc); break; } pcre_free(re); /* Release memory used for the compiled pattern */ return 1; } /* Match succeded */ printf("\nMatch succeeded at offset %d\n", ovector[0]); /************************************************************************* * We have found the first match within the subject string. If the output * * vector wasn't big enough, set its size to the maximum. Then output any * * substrings that were captured. * *************************************************************************/ /* The output vector wasn't big enough */ if (rc == 0) { rc = OVECCOUNT/3; printf("ovector only has room for %d captured substrings\n", rc - 1); } /* Show substrings stored in the output vector by number. Obviously, in a real application you might want to do things other than print them. */ for (i = 0; i < rc; i++) { char *substring_start = subject + ovector[2*i]; int substring_length = ovector[2*i+1] - ovector[2*i]; printf("%2d: %.*s\n", i, substring_length, substring_start); } /************************************************************************** * That concludes the basic part of this demonstration program. We have * * compiled a pattern, and performed a single match. The code that follows * * first shows how to access named substrings, and then how to code for * * repeated matches on the same subject. * **************************************************************************/ /* See if there are any named substrings, and if so, show them by name. First we have to extract the count of named parentheses from the pattern. */ (void)pcre_fullinfo( re, /* the compiled pattern */ NULL, /* no extra data - we didn't study the pattern */ PCRE_INFO_NAMECOUNT, /* number of named substrings */ &namecount); /* where to put the answer */ if (namecount <= 0) printf("No named substrings\n"); else { unsigned char *tabptr; printf("Named substrings\n"); /* Before we can access the substrings, we must extract the table for translating names to numbers, and the size of each entry in the table. */ (void)pcre_fullinfo( re, /* the compiled pattern */ NULL, /* no extra data - we didn't study the pattern */ PCRE_INFO_NAMETABLE, /* address of the table */ &name_table); /* where to put the answer */ (void)pcre_fullinfo( re, /* the compiled pattern */ NULL, /* no extra data - we didn't study the pattern */ PCRE_INFO_NAMEENTRYSIZE, /* size of each entry in the table */ &name_entry_size); /* where to put the answer */ /* Now we can scan the table and, for each entry, print the number, the name, and the substring itself. */ tabptr = name_table; for (i = 0; i < namecount; i++) { int n = (tabptr[0] << 8) | tabptr[1]; printf("(%d) %*s: %.*s\n", n, name_entry_size - 3, tabptr + 2, ovector[2*n+1] - ovector[2*n], subject + ovector[2*n]); tabptr += name_entry_size; } } /************************************************************************* * If the "-g" option was given on the command line, we want to continue * * to search for additional matches in the subject string, in a similar * * way to the /g option in Perl. This turns out to be trickier than you * * might think because of the possibility of matching an empty string. * * What happens is as follows: * * * * If the previous match was NOT for an empty string, we can just start * * the next match at the end of the previous one. * * * * If the previous match WAS for an empty string, we can't do that, as it * * would lead to an infinite loop. Instead, a special call of pcre_exec() * * is made with the PCRE_NOTEMPTY and PCRE_ANCHORED flags set. The first * * of these tells PCRE that an empty string is not a valid match; other * * possibilities must be tried. The second flag restricts PCRE to one * * match attempt at the initial string position. If this match succeeds, * * an alternative to the empty string match has been found, and we can * * proceed round the loop. * *************************************************************************/ if (!find_all) { pcre_free(re); /* Release the memory used for the compiled pattern */ return 0; /* Finish unless -g was given */ } /* Loop for second and subsequent matches */ for (;;) { int options = 0; /* Normally no options */ int start_offset = ovector[1]; /* Start at end of previous match */ /* If the previous match was for an empty string, we are finished if we are at the end of the subject. Otherwise, arrange to run another match at the same point to see if a non-empty match can be found. */ if (ovector[0] == ovector[1]) { if (ovector[0] == subject_length) break; options = PCRE_NOTEMPTY | PCRE_ANCHORED; } /* Run the next matching operation */ rc = pcre_exec( re, /* the compiled pattern */ NULL, /* no extra data - we didn't study the pattern */ subject, /* the subject string */ subject_length, /* the length of the subject */ start_offset, /* starting offset in the subject */ options, /* options */ ovector, /* output vector for substring information */ OVECCOUNT); /* number of elements in the output vector */ /* This time, a result of NOMATCH isn't an error. If the value in "options" is zero, it just means we have found all possible matches, so the loop ends. Otherwise, it means we have failed to find a non-empty-string match at a point where there was a previous empty-string match. In this case, we do what Perl does: advance the matching position by one, and continue. We do this by setting the "end of previous match" offset, because that is picked up at the top of the loop as the point at which to start again. */ if (rc == PCRE_ERROR_NOMATCH) { if (options == 0) break; ovector[1] = start_offset + 1; continue; /* Go round the loop again */ } /* Other matching errors are not recoverable. */ if (rc < 0) { printf("Matching error %d\n", rc); pcre_free(re); /* Release memory used for the compiled pattern */ return 1; } /* Match succeded */ printf("\nMatch succeeded again at offset %d\n", ovector[0]); /* The match succeeded, but the output vector wasn't big enough. */ if (rc == 0) { rc = OVECCOUNT/3; printf("ovector only has room for %d captured substrings\n", rc - 1); } /* As before, show substrings stored in the output vector by number, and then also any named substrings. */ for (i = 0; i < rc; i++) { char *substring_start = subject + ovector[2*i]; int substring_length = ovector[2*i+1] - ovector[2*i]; printf("%2d: %.*s\n", i, substring_length, substring_start); } if (namecount <= 0) printf("No named substrings\n"); else { unsigned char *tabptr = name_table; printf("Named substrings\n"); for (i = 0; i < namecount; i++) { int n = (tabptr[0] << 8) | tabptr[1]; printf("(%d) %*s: %.*s\n", n, name_entry_size - 3, tabptr + 2, ovector[2*n+1] - ovector[2*n], subject + ovector[2*n]); tabptr += name_entry_size; } } } /* End of loop to find second and subsequent matches */ printf("\n"); pcre_free(re); /* Release memory used for the compiled pattern */ return 0; } /* End of pcredemo.c */ libsynthesis-3.4.0.47.1/src/pcre/pcregexp.pas000066400000000000000000000550651226375725500207210ustar00rootroot00000000000000{ pcRegExp - Perl compatible regular expressions for Virtual Pascal (c) 2001 Peter S. Voronov aka Chem O'Dun Based on PCRE library interface unit for Virtual Pascal. (c) 2001 Alexander Tokarev The current PCRE version is: 3.7 This software must be distributed as Freeware. The PCRE library is written by: Philip Hazel Copyright (c) 1997-2004 University of Cambridge AngelsHolocaust 4-11-04 updated to use version v5.0 (INFO: this is regex-directed, NFA) AH: 9-11-04 - pcre_free: removed var, pcre already gives the ptr, now everything works as it should (no more crashes) -> removed CheckRegExp because pcre handles errors perfectly 10-11-04 - added pcError (errorhandling), pcInit 13-11-04 - removed the ErrorPos = 0 check -> always print erroroffset 17-10-05 - support for \1-\9 backreferences in TpcRegExp.GetReplStr 17-02-06 - added RunTimeOptions: caller can set options while searching 19-02-06 - added SearchOfs(): let PCRE use the complete string and offset into the string itself 20-12-06 - support for version 7.0 } {$H+} {$DEFINE PCRE_3_7} {$DEFINE PCRE_5_0} {$DEFINE PCRE_7_0} Unit pcregexp; Interface uses objects; Type PpcRegExp = ^TpcRegExp; // TpcRegExp = object TpcRegExp = object(TObject) MatchesCount: integer; RegExpC, RegExpExt : Pointer; Matches:Pointer; RegExp: shortstring; SourceLen: integer; PartialMatch : boolean; Error : boolean; ErrorMsg : Pchar; ErrorPos : integer; RunTimeOptions: Integer; // options which can be set by the caller constructor Init(const ARegExp : shortstring; AOptions : integer; ALocale : Pointer); function Search(AStr: Pchar; ALen : longint) : boolean; virtual; function SearchNext( AStr: Pchar; ALen : longint) : boolean; virtual; function SearchOfs ( AStr: Pchar; ALen, AOfs : longint) : boolean; virtual; function MatchSub(ANom: integer; var Pos, Len : longint) : boolean; virtual; function MatchFull(var Pos, Len : longint) : boolean; virtual; function GetSubStr(ANom: integer; AStr: Pchar) : string; virtual; function GetFullStr(AStr: Pchar) : string; virtual; function GetReplStr(AStr: Pchar; const ARepl: string) : string; virtual; function GetPreSubStr(AStr: Pchar) : string; virtual; function GetPostSubStr(AStr: Pchar) : string; virtual; function ErrorStr : string; virtual; destructor Done; virtual; end; function pcGrepMatch(WildCard, aStr: string; AOptions:integer; ALocale : Pointer): Boolean; function pcGrepSub(WildCard, aStr, aRepl: string; AOptions:integer; ALocale : Pointer): string; function pcFastGrepMatch(WildCard, aStr: string): Boolean; function pcFastGrepSub(WildCard, aStr, aRepl: string): string; {$IFDEF PCRE_5_0} function pcGetVersion : pchar; {$ENDIF} function pcError (var pRegExp : Pointer) : Boolean; function pcInit (const Pattern: Shortstring; CaseSens: Boolean) : Pointer; Const { Options } PCRE_CASELESS = $0001; PCRE_MULTILINE = $0002; PCRE_DOTALL = $0004; PCRE_EXTENDED = $0008; PCRE_ANCHORED = $0010; PCRE_DOLLAR_ENDONLY = $0020; PCRE_EXTRA = $0040; PCRE_NOTBOL = $0080; PCRE_NOTEOL = $0100; PCRE_UNGREEDY = $0200; PCRE_NOTEMPTY = $0400; {$IFDEF PCRE_5_0} PCRE_UTF8 = $0800; PCRE_NO_AUTO_CAPTURE = $1000; PCRE_NO_UTF8_CHECK = $2000; PCRE_AUTO_CALLOUT = $4000; PCRE_PARTIAL = $8000; {$ENDIF} {$IFDEF PCRE_7_0} PCRE_DFA_SHORTEST = $00010000; PCRE_DFA_RESTART = $00020000; PCRE_FIRSTLINE = $00040000; PCRE_DUPNAMES = $00080000; PCRE_NEWLINE_CR = $00100000; PCRE_NEWLINE_LF = $00200000; PCRE_NEWLINE_CRLF = $00300000; PCRE_NEWLINE_ANY = $00400000; PCRE_NEWLINE_ANYCRLF = $00500000; {$ENDIF} PCRE_COMPILE_ALLOWED_OPTIONS = PCRE_ANCHORED + PCRE_AUTO_CALLOUT + PCRE_CASELESS + PCRE_DOLLAR_ENDONLY + PCRE_DOTALL + PCRE_EXTENDED + PCRE_EXTRA + PCRE_MULTILINE + PCRE_NO_AUTO_CAPTURE + PCRE_UNGREEDY + PCRE_UTF8 + PCRE_NO_UTF8_CHECK {$IFDEF PCRE_7_0} + PCRE_DUPNAMES + PCRE_FIRSTLINE + PCRE_NEWLINE_CRLF + PCRE_NEWLINE_ANY + PCRE_NEWLINE_CRLF {$ENDIF} ; PCRE_EXEC_ALLOWED_OPTIONS = PCRE_ANCHORED + PCRE_NOTBOL + PCRE_NOTEOL + PCRE_NOTEMPTY + PCRE_NO_UTF8_CHECK + PCRE_PARTIAL {$IFDEF PCRE_7_0} + PCRE_NEWLINE_CRLF + PCRE_NEWLINE_ANY +PCRE_NEWLINE_ANYCRLF {$ENDIF} ; {$IFDEF PCRE_7_0} PCRE_DFA_EXEC_ALLOWED_OPTIONS = PCRE_ANCHORED + PCRE_NOTBOL + PCRE_NOTEOL + PCRE_NOTEMPTY + PCRE_NO_UTF8_CHECK + PCRE_PARTIAL + PCRE_DFA_SHORTEST + PCRE_DFA_RESTART + PCRE_NEWLINE_CR + PCRE_NEWLINE_LF + PCRE_NEWLINE_CRLF + PCRE_NEWLINE_ANY + PCRE_NEWLINE_ANYCRLF {$ENDIF} { Exec-time and get/set-time error codes } PCRE_ERROR_NOMATCH = -1; PCRE_ERROR_NULL = -2; PCRE_ERROR_BADOPTION = -3; PCRE_ERROR_BADMAGIC = -4; PCRE_ERROR_UNKNOWN_MODE = -5; PCRE_ERROR_NOMEMORY = -6; PCRE_ERROR_NOSUBSTRING = -7; {$IFDEF PCRE_5_0} PCRE_ERROR_MATCHLIMIT = -8; PCRE_ERROR_CALLOUT = -9; { Never used by PCRE itself } PCRE_ERROR_BADUTF8 = -10; PCRE_ERROR_BADUTF8_OFFSET = -11; PCRE_ERROR_PARTIAL = -12; PCRE_ERROR_BADPARTIAL = -13; PCRE_ERROR_INTERNAL = -14; PCRE_ERROR_BADCOUNT = -15; {$ENDIF} {$IFDEF PCRE_7_0} PCRE_ERROR_DFA_UITEM = -16; PCRE_ERROR_DFA_UCOND = -17; PCRE_ERROR_DFA_UMLIMIT = -18; PCRE_ERROR_DFA_WSSIZE = -19; PCRE_ERROR_DFA_RECURSE = -20; PCRE_ERROR_RECURSIONLIMIT = -21; PCRE_ERROR_NULLWSLIMIT = -22; PCRE_ERROR_BADNEWLINE = -23; {$ENDIF} { Request types for pcre_fullinfo() } PCRE_INFO_OPTIONS = 0; PCRE_INFO_SIZE = 1; PCRE_INFO_CAPTURECOUNT = 2; PCRE_INFO_BACKREFMAX = 3; PCRE_INFO_FIRSTBYTE = 4; PCRE_INFO_FIRSTCHAR = 4; { For backwards compatibility } PCRE_INFO_FIRSTTABLE = 5; {$IFDEF PCRE_5_0} PCRE_INFO_LASTLITERAL = 6; PCRE_INFO_NAMEENTRYSIZE = 7; PCRE_INFO_NAMECOUNT = 8; PCRE_INFO_NAMETABLE = 9; PCRE_INFO_STUDYSIZE = 10; PCRE_INFO_DEFAULT_TABLES = 11; {$ENDIF PCRE_5_0} { Request types for pcre_config() } {$IFDEF PCRE_5_0} PCRE_CONFIG_UTF8 = 0; PCRE_CONFIG_NEWLINE = 1; PCRE_CONFIG_LINK_SIZE = 2; PCRE_CONFIG_POSIX_MALLOC_THRESHOLD = 3; PCRE_CONFIG_MATCH_LIMIT = 4; PCRE_CONFIG_STACKRECURSE = 5; PCRE_CONFIG_UNICODE_PROPERTIES = 6; {$ENDIF PCRE_5_0} {$IFDEF PCRE_7_0} PCRE_CONFIG_MATCH_LIMIT_RECURSION = 7; {$ENDIF} { Bit flags for the pcre_extra structure } {$IFDEF PCRE_5_0} PCRE_EXTRA_STUDY_DATA = $0001; PCRE_EXTRA_MATCH_LIMIT = $0002; PCRE_EXTRA_CALLOUT_DATA = $0004; PCRE_EXTRA_TABLES = $0008; {$ENDIF PCRE_5_0} {$IFDEF PCRE_7_0} PCRE_EXTRA_MATCH_LIMIT_RECURSION = $0010; {$ENDIF} Const // DefaultOptions : integer = 0; DefaultLocaleTable : pointer = nil; {$IFDEF PCRE_5_0} { The structure for passing additional data to pcre_exec(). This is defined in such as way as to be extensible. Always add new fields at the end, in order to remain compatible. } type ppcre_extra = ^tpcre_extra; tpcre_extra = record flags : longint; { Bits for which fields are set } study_data : pointer; { Opaque data from pcre_study() } match_limit : longint; { Maximum number of calls to match() } callout_data : pointer; { Data passed back in callouts } tables : pointer; { Pointer to character tables } match_limit_recursion: longint; { Max recursive calls to match() } end; type ppcre_callout_block = ^pcre_callout_block; pcre_callout_block = record version, (* ------------------------ Version 0 ------------------------------- *) callout_number : integer; offset_vector : pointer; subject : pchar; subject_length, start_match, current_position, capture_top, capture_last : integer; callout_data : pointer; (* ------------------- Added for Version 1 -------------------------- *) pattern_position, next_item_length : integer; end; {$ENDIF PCRE_5_0} {$OrgName+} {$IFDEF VIRTUALPASCAL} {&Cdecl+} {$ENDIF VIRTUALPASCAL} { local replacement of external pcre memory management functions } function pcre_malloc( size : integer ) : pointer; procedure pcre_free( {var} p : pointer ); {$IFDEF PCRE_5_0} const pcre_stack_malloc: function ( size : integer ): pointer = pcre_malloc; pcre_stack_free: procedure ( {var} p : pointer ) = pcre_free; function pcre_callout(var p : ppcre_callout_block) : integer; {$ENDIF PCRE_5_0} {$IFDEF VIRTUALPASCAL} {&Cdecl-} {$ENDIF VIRTUALPASCAL} Implementation Uses strings, collect, messages, dnapp, commands, advance0, stringsx {$IFDEF VIRTUALPASCAL} ,vpsyslow {$ENDIF VIRTUALPASCAL}; Const MAGIC_NUMBER = $50435245; { 'PCRE' } MAX_MATCHES = 90; { changed in 3.5 version; should be divisible by 3, was 64} Type PMatchArray = ^TMatchArray; TMatchArray = array[0..( MAX_MATCHES * 3 )] of integer; PRegExpCollection = ^TRegExpCollection; TRegExpCollection = object(TSortedCollection) MaxRegExp : integer; SearchRegExp : shortstring; CompareModeInsert : boolean; constructor Init(AMaxRegExp:integer); procedure FreeItem(P: Pointer); virtual; function Compare(P1, P2: Pointer): Integer; virtual; function Find(ARegExp:shortstring;var P: PpcRegExp):boolean; virtual; function CheckNew(ARegExp:shortstring):PpcRegExp;virtual; end; Var PRegExpCache : PRegExpCollection; {$IFDEF VIRTUALPASCAL} {&Cdecl+} {$ENDIF VIRTUALPASCAL} { imported original pcre functions } function pcre_compile( const pattern : PChar; options : integer; var errorptr : PChar; var erroroffset : integer; const tables : PChar ) : pointer {pcre}; external; {$IFDEF PCRE_7_0} function pcre_compile2( const pattern : PChar; options : integer; var errorcodeptr : Integer; var errorptr : PChar; var erroroffset : integer; const tables : PChar ) : pointer {pcre}; external; {$ENDIF} {$IFDEF PCRE_5_0} function pcre_config( what : integer; where : pointer) : integer; external; function pcre_copy_named_substring( const code : pointer {pcre}; const subject : pchar; var ovector : integer; stringcount : integer; const stringname : pchar; var buffer : pchar; size : integer) : integer; external; function pcre_copy_substring( const subject : pchar; var ovector : integer; stringcount, stringnumber : integer; var buffer : pchar; size : integer ) : integer; external; function pcre_exec( const argument_re : pointer {pcre}; const extra_data : pointer {pcre_extra}; {$ELSE} function pcre_exec( const external_re : pointer; const external_extra : pointer; {$ENDIF} const subject : PChar; length, start_offset, options : integer; offsets : pointer; offsetcount : integer ) : integer; external; {$IFDEF PCRE_7_0} function pcre_dfa_exec( const argument_re : pointer {pcre}; const extra_data : pointer {pcre_extra}; const subject : pchar; length, start_offset, options : integer; offsets : pointer; offsetcount : integer; workspace : pointer; wscount : integer ) : integer; external; {$ENDIF} {$IFDEF PCRE_5_0} procedure pcre_free_substring( const p : pchar ); external; procedure pcre_free_substring_list( var p : pchar ); external; function pcre_fullinfo( const argument_re : pointer {pcre}; const extra_data : pointer {pcre_extra}; what : integer; where : pointer ) : integer; external; function pcre_get_named_substring( const code : pointer {pcre}; const subject : pchar; var ovector : integer; stringcount : integer; const stringname : pchar; var stringptr : pchar ) : integer; external; function pcre_get_stringnumber( const code : pointer {pcre}; const stringname : pchar ) : integer; external; function pcre_get_stringtable_entries( const code : pointer {pcre}; const stringname : pchar; var firstptr, lastptr : pchar ) : integer; external; function pcre_get_substring( const subject : pchar; var ovector : integer; stringcount, stringnumber : integer; var stringptr : pchar ) : integer; external; function pcre_get_substring_list( const subject : pchar; var ovector : integer; stringcount : integer; listptr : pointer {const char ***listptr}) : integer; external; function pcre_info( const argument_re : pointer {pcre}; var optptr : integer; var first_byte : integer ) : integer; external; function pcre_maketables : pchar; external; {$ENDIF} {$IFDEF PCRE_7_0} function pcre_refcount( const argument_re : pointer {pcre}; adjust : integer ) : pchar; external; {$ENDIF} function pcre_study( const external_re : pointer {pcre}; options : integer; var errorptr : PChar ) : pointer {pcre_extra}; external; {$IFDEF PCRE_5_0} function pcre_version : pchar; external; {$ENDIF} function pcre_malloc( size : integer ) : pointer; begin GetMem( result, size ); end; procedure pcre_free( {var} p : pointer ); begin if (p <> nil) then FreeMem( p, 0 ); {@p := nil;} end; {$IFDEF PCRE_5_0} (* Called from PCRE as a result of the (?C) item. We print out where we are in the match. Yield zero unless more callouts than the fail count, or the callout data is not zero. *) function pcre_callout; begin end; {$ENDIF} {$IFDEF VIRTUALPASCAL} {&Cdecl-} {$ENDIF VIRTUALPASCAL} // Always include the newest version of the library {$IFDEF PCRE_3_7} {$IFNDEF PCRE_5_0} {$IFNDEF PCRE_7_0} {$L pcre37.lib} {$ENDIF PCRE_7_0} {$ENDIF PCRE_5_0} {$ENDIF PCRE_3_7} {$IFDEF PCRE_5_0} {$IFNDEF PCRE_7_0} {$L pcre50.lib} {$ENDIF PCRE_7_0} {$ENDIF PCRE_5_0} {$IFDEF PCRE_7_0} {$L pcre70.lib} {$ENDIF PCRE_7_0} {TpcRegExp} constructor TpcRegExp.Init(const ARegExp:shortstring; AOptions:integer; ALocale : Pointer); var pRegExp : PChar; begin RegExp:=ARegExp; RegExpC:=nil; RegExpExt:=nil; Matches:=nil; MatchesCount:=0; Error:=true; ErrorMsg:=nil; ErrorPos:=0; RunTimeOptions := 0; if length(RegExp) < 255 then begin RegExp[length(RegExp)+1]:=#0; pRegExp:=@RegExp[1]; end else begin GetMem(pRegExp,length(RegExp)+1); pRegExp:=strpcopy(pRegExp,RegExp); end; RegExpC := pcre_compile( pRegExp, AOptions and PCRE_COMPILE_ALLOWED_OPTIONS, ErrorMsg, ErrorPos, ALocale); if length(RegExp) = 255 then StrDispose(pRegExp); if RegExpC = nil then exit; ErrorMsg:=nil; RegExpExt := pcre_study( RegExpC, 0, ErrorMsg ); if (RegExpExt = nil) and (ErrorMsg <> nil) then begin pcre_free(RegExpC); exit; end; GetMem(Matches,SizeOf(TMatchArray)); Error:=false; end; destructor TpcRegExp.Done; begin if RegExpC <> nil then pcre_free(RegExpC); if RegExpExt <> nil then pcre_free(RegExpExt); if Matches <> nil then FreeMem(Matches,SizeOf(TMatchArray)); end; function TpcRegExp.SearchNext( AStr: Pchar; ALen : longint ) : boolean; var Options: Integer; begin // must handle PCRE_ERROR_PARTIAL here Options := (RunTimeOptions or startup.MiscMultiData.cfgRegEx.DefaultOptions) and PCRE_EXEC_ALLOWED_OPTIONS; if MatchesCount > 0 then MatchesCount:=pcre_exec( RegExpC, RegExpExt, AStr, ALen, PMatchArray(Matches)^[1], Options, Matches, MAX_MATCHES ) else MatchesCount:=pcre_exec( RegExpC, RegExpExt, AStr, ALen, 0, Options, Matches, MAX_MATCHES ); { if MatchesCount = 0 then MatchesCount := MatchesCount div 3;} PartialMatch := MatchesCount = PCRE_ERROR_PARTIAL; SearchNext := MatchesCount > 0; end; function TpcRegExp.Search( AStr: Pchar; ALen : longint):boolean; begin MatchesCount:=0; Search:=SearchNext(AStr,ALen); SourceLen:=ALen; end; function TpcRegExp.SearchOfs( AStr: Pchar; ALen, AOfs: longint ) : boolean; var Options: Integer; begin MatchesCount:=0; Options := (RunTimeOptions or startup.MiscMultiData.cfgRegEx.DefaultOptions) and PCRE_EXEC_ALLOWED_OPTIONS; MatchesCount:=pcre_exec( RegExpC, RegExpExt, AStr, ALen, AOfs, Options, Matches, MAX_MATCHES ); PartialMatch := MatchesCount = PCRE_ERROR_PARTIAL; SearchOfs := MatchesCount > 0; SourceLen := ALen-AOfs; end; function TpcRegExp.MatchSub(ANom:integer; var Pos,Len:longint):boolean; begin if (MatchesCount > 0) and (ANom <= (MatchesCount-1)) then begin ANom:=ANom*2; Pos:=PMatchArray(Matches)^[ANom]; Len:=PMatchArray(Matches)^[ANom+1]-Pos; MatchSub:=true; end else MatchSub:=false; end; function TpcRegExp.MatchFull(var Pos,Len:longint):boolean; begin MatchFull:=MatchSub(0,Pos,Len); end; function TpcRegExp.GetSubStr(ANom: integer; AStr: Pchar):string; var s: ansistring; pos,len: longint; begin s:=''; if MatchSub(ANom, pos, len) then begin setlength(s, len); Move(AStr[pos], s[1], len); end; GetSubStr:=s; end; function TpcRegExp.GetPreSubStr(AStr: Pchar):string; var s: ansistring; l: longint; begin s:=''; if (MatchesCount > 0) then begin l:=PMatchArray(Matches)^[0]-1; if l > 0 then begin setlength(s,l); Move(AStr[1],s[1],l); end; end; GetPreSubStr:=s; end; function TpcRegExp.GetPostSubStr(AStr: Pchar):string; var s: ansistring; l: longint; ANom: integer; begin s:=''; if (MatchesCount > 0) then begin ANom:=(MatchesCount-1){*2} shl 1; l:=SourceLen-PMatchArray(Matches)^[ANom+1]+1; if l > 0 then begin setlength(s,l); Move(AStr[PMatchArray(Matches)^[ANom+1]],s[1],l); end; end; GetPostSubStr:=s; end; function TpcRegExp.GetFullStr(AStr: Pchar):string; var s: ansistring; l: longint; begin GetFullStr:=GetSubStr(0,AStr); end; function TpcRegExp.GetReplStr(AStr: Pchar; const ARepl: string):string; var s: ansistring; l,i,lasti: longint; begin l:=length(ARepl); i:=1; lasti:=1; s:=''; while i <= l do begin case ARepl[i] of '\' : begin if i < l then begin s:=s+copy(ARepl,lasti,i-lasti){+ARepl[i+1]}; {AH 17-10-05 support for POSIX \1-\9 backreferences} case ARepl[i+1] of '0' : s:=s+GetFullStr(AStr); '1'..'9' : s:=s+GetSubStr(ord(ARepl[i+1])-ord('0'),AStr); else s:=s+ARepl[i+1]; // copy the escaped character end; end; inc(i); lasti:=i+1; end; '$' : begin if i < l then begin s:=s+copy(ARepl,lasti,i-lasti); case ARepl[i+1] of '&' : s:=s+GetFullStr(AStr); '1'..'9' : s:=s+GetSubStr(ord(ARepl[i+1])-ord('0'),AStr); '`' : s:=s+GetPreSubStr(AStr); #39 : s:=s+GetPostSubStr(AStr); end; end; inc(i); lasti:=i+1; end; end; inc(i); end; if lasti <= {AH 25-10-2004 added =, else l==1 won't work} l then s:=s+copy(ARepl,lasti,l-lasti+1); GetReplStr:=s; end; function TpcRegExp.ErrorStr:string; begin ErrorStr:=StrPas(ErrorMsg); end; {TRegExpCollection} constructor TRegExpCollection.Init(AMaxRegExp: integer); begin Inherited Init(1,1); MaxRegExp:=AMaxRegExp; CompareModeInsert:=true; end; procedure TRegExpCollection.FreeItem(P: Pointer); begin if P <> nil then begin Dispose(PpcRegExp(P),Done); end; end; function TRegExpCollection.Compare(P1, P2: Pointer): Integer; //var // l,l1,l2,i : byte; //// wPos: pchar; begin if CompareModeInsert then begin // l1:=length(PpcRegExp(P1)^.RegExp); // l2:=length(PpcRegExp(P2)^.RegExp); // if l1 > l2 then l:=l2 else // l:=l1; // for i:=1 to l do // if PpcRegExp(P1).RegExp[i] <> PpcRegExp(P2).RegExp[i] then break; // if i <=l then // Compare:=ord(PpcRegExp(P1).RegExp[i])-ord(PpcRegExp(P2).RegExp[i]) else // Compare:=l1-l2; Compare := stringsx.PasStrCmp(PpcRegExp(P1).RegExp, PpcRegExp(P2).RegExp, False); end else begin // l1:=length(PpcRegExp(P1)^.RegExp); // l2:=length(SearchRegExp); // if l1 > l2 then l:=l2 else // l:=l1; // for i:=1 to l do // if PpcRegExp(P1).RegExp[i] <> SearchRegExp[i] then // begin // Compare:=ord(PpcRegExp(P1).RegExp[i])-ord(SearchRegExp[i]); // break; // end; // if i > l then Compare:=l1-l2; Compare := stringsx.PasStrCmp(PpcRegExp(P1).RegExp, SearchRegExp, False); end; end; function TRegExpCollection.Find(ARegExp:shortstring;var P: PpcRegExp):boolean; var I : integer; begin CompareModeInsert:=false; SearchRegExp:=ARegExp; if Search(nil,I) then begin P:=PpcRegExp(At(I)); Find:=true; end else begin P:=nil; Find:=false; end; CompareModeInsert:=true; end; function TRegExpCollection.CheckNew(ARegExp:shortstring):PpcRegExp; var P : PpcRegExp; begin if not Find(ARegExp,P) then begin if Count = MaxRegExp then AtFree(0); P:=New(ppcRegExp,Init(ARegExp,PCRE_CASELESS,nil)); Insert(P); end; CheckNew:=P; end; function pcGrepMatch(WildCard, aStr: string; AOptions:integer; ALocale : Pointer): Boolean; var PpcRE:PpcRegExp; begin PpcRE:=New(ppcRegExp,Init(WildCard,AOptions,Alocale)); pcGrepMatch:=PpcRE^.Search(pchar(AStr),Length(AStr)); Dispose(PpcRE,Done); end; function pcGrepSub(WildCard, aStr, aRepl: string; AOptions:integer; ALocale : Pointer): string; var PpcRE:PpcRegExp; begin PpcRE:=New(ppcRegExp,Init(WildCard,AOptions,Alocale)); if PpcRE^.Search(pchar(AStr),Length(AStr)) then pcGrepSub:=PpcRE^.GetReplStr(pchar(AStr),ARepl) else pcGrepSub:=''; Dispose(PpcRE,Done); end; function pcFastGrepMatch(WildCard, aStr: string): Boolean; var PpcRE:PpcRegExp; begin PpcRE:=PRegExpCache^.CheckNew(WildCard); pcFastGrepMatch:=PpcRE^.Search(pchar(AStr),Length(AStr)); end; function pcFastGrepSub(WildCard, aStr, aRepl: string): string; var PpcRE:PpcRegExp; begin PpcRE:=PRegExpCache^.CheckNew(WildCard); if PpcRE^.Search(pchar(AStr),Length(AStr)) then pcFastGrepSub:=PpcRE^.GetReplStr(pchar(AStr),ARepl) else pcFastGrepSub:=''; end; {$IFDEF PCRE_5_0} function pcGetVersion : pchar; assembler; {$FRAME-}{$USES none} asm call pcre_version end; {$ENDIF PCRE_5_0} function pcError; var P: ppcRegExp absolute pRegExp; begin Result := (P = nil) or P^.Error; If Result and (P <> nil) then begin { if P^.ErrorPos = 0 then MessageBox(GetString(erRegExpCompile)+'"'+P^.ErrorStr+'"', nil,mfConfirmation+mfOkButton) else} MessageBox(GetString(erRegExpCompile)+'"'+P^.ErrorStr+'"'+GetString(erRegExpCompPos), @P^.ErrorPos,mfConfirmation+mfOkButton); Dispose(P, Done); P:=nil; end; end; function pcInit; var Options : Integer; begin If CaseSens then Options := 0 else Options := PCRE_CASELESS; Result := New( PpcRegExp, Init( Pattern, {DefaultOptions} startup.MiscMultiData.cfgRegEx.DefaultOptions or Options, DefaultLocaleTable) ); end; Initialization PRegExpCache:=New(PRegExpCollection,Init(64)); Finalization Dispose(PRegExpCache,Done); End. libsynthesis-3.4.0.47.1/src/pcre/pcregrep.c000066400000000000000000001641121226375725500203440ustar00rootroot00000000000000/************************************************* * pcregrep program * *************************************************/ /* This is a grep program that uses the PCRE regular expression library to do its pattern matching. On a Unix or Win32 system it can recurse into directories. Copyright (c) 1997-2007 University of Cambridge ----------------------------------------------------------------------------- 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 name of the University of Cambridge 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. ----------------------------------------------------------------------------- */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include #ifdef HAVE_UNISTD_H #include #endif #include #define FALSE 0 #define TRUE 1 typedef int BOOL; #define MAX_PATTERN_COUNT 100 #if BUFSIZ > 8192 #define MBUFTHIRD BUFSIZ #else #define MBUFTHIRD 8192 #endif /* Values for the "filenames" variable, which specifies options for file name output. The order is important; it is assumed that a file name is wanted for all values greater than FN_DEFAULT. */ enum { FN_NONE, FN_DEFAULT, FN_ONLY, FN_NOMATCH_ONLY, FN_FORCE }; /* Actions for the -d and -D options */ enum { dee_READ, dee_SKIP, dee_RECURSE }; enum { DEE_READ, DEE_SKIP }; /* Actions for special processing options (flag bits) */ #define PO_WORD_MATCH 0x0001 #define PO_LINE_MATCH 0x0002 #define PO_FIXED_STRINGS 0x0004 /* Line ending types */ enum { EL_LF, EL_CR, EL_CRLF, EL_ANY, EL_ANYCRLF }; /************************************************* * Global variables * *************************************************/ /* Jeffrey Friedl has some debugging requirements that are not part of the regular code. */ #ifdef JFRIEDL_DEBUG static int S_arg = -1; static unsigned int jfriedl_XR = 0; /* repeat regex attempt this many times */ static unsigned int jfriedl_XT = 0; /* replicate text this many times */ static const char *jfriedl_prefix = ""; static const char *jfriedl_postfix = ""; #endif static int endlinetype; static char *colour_string = (char *)"1;31"; static char *colour_option = NULL; static char *dee_option = NULL; static char *DEE_option = NULL; static char *newline = NULL; static char *pattern_filename = NULL; static char *stdin_name = (char *)"(standard input)"; static char *locale = NULL; static const unsigned char *pcretables = NULL; static int pattern_count = 0; static pcre **pattern_list = NULL; static pcre_extra **hints_list = NULL; static char *include_pattern = NULL; static char *exclude_pattern = NULL; static pcre *include_compiled = NULL; static pcre *exclude_compiled = NULL; static int after_context = 0; static int before_context = 0; static int both_context = 0; static int dee_action = dee_READ; static int DEE_action = DEE_READ; static int error_count = 0; static int filenames = FN_DEFAULT; static int process_options = 0; static BOOL count_only = FALSE; static BOOL do_colour = FALSE; static BOOL hyphenpending = FALSE; static BOOL invert = FALSE; static BOOL multiline = FALSE; static BOOL number = FALSE; static BOOL only_matching = FALSE; static BOOL quiet = FALSE; static BOOL silent = FALSE; static BOOL utf8 = FALSE; /* Structure for options and list of them */ enum { OP_NODATA, OP_STRING, OP_OP_STRING, OP_NUMBER, OP_OP_NUMBER, OP_PATLIST }; typedef struct option_item { int type; int one_char; void *dataptr; const char *long_name; const char *help_text; } option_item; /* Options without a single-letter equivalent get a negative value. This can be used to identify them. */ #define N_COLOUR (-1) #define N_EXCLUDE (-2) #define N_HELP (-3) #define N_INCLUDE (-4) #define N_LABEL (-5) #define N_LOCALE (-6) #define N_NULL (-7) static option_item optionlist[] = { { OP_NODATA, N_NULL, NULL, "", " terminate options" }, { OP_NODATA, N_HELP, NULL, "help", "display this help and exit" }, { OP_NUMBER, 'A', &after_context, "after-context=number", "set number of following context lines" }, { OP_NUMBER, 'B', &before_context, "before-context=number", "set number of prior context lines" }, { OP_OP_STRING, N_COLOUR, &colour_option, "color=option", "matched text color option" }, { OP_NUMBER, 'C', &both_context, "context=number", "set number of context lines, before & after" }, { OP_NODATA, 'c', NULL, "count", "print only a count of matching lines per FILE" }, { OP_OP_STRING, N_COLOUR, &colour_option, "colour=option", "matched text colour option" }, { OP_STRING, 'D', &DEE_option, "devices=action","how to handle devices, FIFOs, and sockets" }, { OP_STRING, 'd', &dee_option, "directories=action", "how to handle directories" }, { OP_PATLIST, 'e', NULL, "regex(p)", "specify pattern (may be used more than once)" }, { OP_NODATA, 'F', NULL, "fixed_strings", "patterns are sets of newline-separated strings" }, { OP_STRING, 'f', &pattern_filename, "file=path", "read patterns from file" }, { OP_NODATA, 'H', NULL, "with-filename", "force the prefixing filename on output" }, { OP_NODATA, 'h', NULL, "no-filename", "suppress the prefixing filename on output" }, { OP_NODATA, 'i', NULL, "ignore-case", "ignore case distinctions" }, { OP_NODATA, 'l', NULL, "files-with-matches", "print only FILE names containing matches" }, { OP_NODATA, 'L', NULL, "files-without-match","print only FILE names not containing matches" }, { OP_STRING, N_LABEL, &stdin_name, "label=name", "set name for standard input" }, { OP_STRING, N_LOCALE, &locale, "locale=locale", "use the named locale" }, { OP_NODATA, 'M', NULL, "multiline", "run in multiline mode" }, { OP_STRING, 'N', &newline, "newline=type", "specify newline type (CR, LF, CRLF, ANYCRLF or ANY)" }, { OP_NODATA, 'n', NULL, "line-number", "print line number with output lines" }, { OP_NODATA, 'o', NULL, "only-matching", "show only the part of the line that matched" }, { OP_NODATA, 'q', NULL, "quiet", "suppress output, just set return code" }, { OP_NODATA, 'r', NULL, "recursive", "recursively scan sub-directories" }, { OP_STRING, N_EXCLUDE,&exclude_pattern, "exclude=pattern","exclude matching files when recursing" }, { OP_STRING, N_INCLUDE,&include_pattern, "include=pattern","include matching files when recursing" }, #ifdef JFRIEDL_DEBUG { OP_OP_NUMBER, 'S', &S_arg, "jeffS", "replace matched (sub)string with X" }, #endif { OP_NODATA, 's', NULL, "no-messages", "suppress error messages" }, { OP_NODATA, 'u', NULL, "utf-8", "use UTF-8 mode" }, { OP_NODATA, 'V', NULL, "version", "print version information and exit" }, { OP_NODATA, 'v', NULL, "invert-match", "select non-matching lines" }, { OP_NODATA, 'w', NULL, "word-regex(p)", "force patterns to match only as words" }, { OP_NODATA, 'x', NULL, "line-regex(p)", "force patterns to match only whole lines" }, { OP_NODATA, 0, NULL, NULL, NULL } }; /* Tables for prefixing and suffixing patterns, according to the -w, -x, and -F options. These set the 1, 2, and 4 bits in process_options, respectively. Note that the combination of -w and -x has the same effect as -x on its own, so we can treat them as the same. */ static const char *prefix[] = { "", "\\b", "^(?:", "^(?:", "\\Q", "\\b\\Q", "^(?:\\Q", "^(?:\\Q" }; static const char *suffix[] = { "", "\\b", ")$", ")$", "\\E", "\\E\\b", "\\E)$", "\\E)$" }; /* UTF-8 tables - used only when the newline setting is "any". */ const int utf8_table3[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01}; const char utf8_table4[] = { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 }; /************************************************* * OS-specific functions * *************************************************/ /* These functions are defined so that they can be made system specific, although at present the only ones are for Unix, Win32, and for "no support". */ /************* Directory scanning in Unix ***********/ #if defined HAVE_SYS_STAT_H && defined HAVE_DIRENT_H && defined HAVE_SYS_TYPES_H #include #include #include typedef DIR directory_type; static int isdirectory(char *filename) { struct stat statbuf; if (stat(filename, &statbuf) < 0) return 0; /* In the expectation that opening as a file will fail */ return ((statbuf.st_mode & S_IFMT) == S_IFDIR)? '/' : 0; } static directory_type * opendirectory(char *filename) { return opendir(filename); } static char * readdirectory(directory_type *dir) { for (;;) { struct dirent *dent = readdir(dir); if (dent == NULL) return NULL; if (strcmp(dent->d_name, ".") != 0 && strcmp(dent->d_name, "..") != 0) return dent->d_name; } /* Control never reaches here */ } static void closedirectory(directory_type *dir) { closedir(dir); } /************* Test for regular file in Unix **********/ static int isregfile(char *filename) { struct stat statbuf; if (stat(filename, &statbuf) < 0) return 1; /* In the expectation that opening as a file will fail */ return (statbuf.st_mode & S_IFMT) == S_IFREG; } /************* Test stdout for being a terminal in Unix **********/ static BOOL is_stdout_tty(void) { return isatty(fileno(stdout)); } /************* Directory scanning in Win32 ***********/ /* I (Philip Hazel) have no means of testing this code. It was contributed by Lionel Fourquaux. David Burgess added a patch to define INVALID_FILE_ATTRIBUTES when it did not exist. */ #elif HAVE_WINDOWS_H #ifndef STRICT # define STRICT #endif #ifndef WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN #endif #ifndef INVALID_FILE_ATTRIBUTES #define INVALID_FILE_ATTRIBUTES 0xFFFFFFFF #endif #include typedef struct directory_type { HANDLE handle; BOOL first; WIN32_FIND_DATA data; } directory_type; int isdirectory(char *filename) { DWORD attr = GetFileAttributes(filename); if (attr == INVALID_FILE_ATTRIBUTES) return 0; return ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) ? '/' : 0; } directory_type * opendirectory(char *filename) { size_t len; char *pattern; directory_type *dir; DWORD err; len = strlen(filename); pattern = (char *) malloc(len + 3); dir = (directory_type *) malloc(sizeof(*dir)); if ((pattern == NULL) || (dir == NULL)) { fprintf(stderr, "pcregrep: malloc failed\n"); exit(2); } memcpy(pattern, filename, len); memcpy(&(pattern[len]), "\\*", 3); dir->handle = FindFirstFile(pattern, &(dir->data)); if (dir->handle != INVALID_HANDLE_VALUE) { free(pattern); dir->first = TRUE; return dir; } err = GetLastError(); free(pattern); free(dir); errno = (err == ERROR_ACCESS_DENIED) ? EACCES : ENOENT; return NULL; } char * readdirectory(directory_type *dir) { for (;;) { if (!dir->first) { if (!FindNextFile(dir->handle, &(dir->data))) return NULL; } else { dir->first = FALSE; } if (strcmp(dir->data.cFileName, ".") != 0 && strcmp(dir->data.cFileName, "..") != 0) return dir->data.cFileName; } #ifndef _MSC_VER return NULL; /* Keep compiler happy; never executed */ #endif } void closedirectory(directory_type *dir) { FindClose(dir->handle); free(dir); } /************* Test for regular file in Win32 **********/ /* I don't know how to do this, or if it can be done; assume all paths are regular if they are not directories. */ int isregfile(char *filename) { return !isdirectory(filename) } /************* Test stdout for being a terminal in Win32 **********/ /* I don't know how to do this; assume never */ static BOOL is_stdout_tty(void) { FALSE; } /************* Directory scanning when we can't do it ***********/ /* The type is void, and apart from isdirectory(), the functions do nothing. */ #else typedef void directory_type; int isdirectory(char *filename) { return 0; } directory_type * opendirectory(char *filename) { return (directory_type*)0;} char *readdirectory(directory_type *dir) { return (char*)0;} void closedirectory(directory_type *dir) {} /************* Test for regular when we can't do it **********/ /* Assume all files are regular. */ int isregfile(char *filename) { return 1; } /************* Test stdout for being a terminal when we can't do it **********/ static BOOL is_stdout_tty(void) { return FALSE; } #endif #ifndef HAVE_STRERROR /************************************************* * Provide strerror() for non-ANSI libraries * *************************************************/ /* Some old-fashioned systems still around (e.g. SunOS4) don't have strerror() in their libraries, but can provide the same facility by this simple alternative function. */ extern int sys_nerr; extern char *sys_errlist[]; char * strerror(int n) { if (n < 0 || n >= sys_nerr) return "unknown error number"; return sys_errlist[n]; } #endif /* HAVE_STRERROR */ /************************************************* * Find end of line * *************************************************/ /* The length of the endline sequence that is found is set via lenptr. This may be zero at the very end of the file if there is no line-ending sequence there. Arguments: p current position in line endptr end of available data lenptr where to put the length of the eol sequence Returns: pointer to the last byte of the line */ static char * end_of_line(char *p, char *endptr, int *lenptr) { switch(endlinetype) { default: /* Just in case */ case EL_LF: while (p < endptr && *p != '\n') p++; if (p < endptr) { *lenptr = 1; return p + 1; } *lenptr = 0; return endptr; case EL_CR: while (p < endptr && *p != '\r') p++; if (p < endptr) { *lenptr = 1; return p + 1; } *lenptr = 0; return endptr; case EL_CRLF: for (;;) { while (p < endptr && *p != '\r') p++; if (++p >= endptr) { *lenptr = 0; return endptr; } if (*p == '\n') { *lenptr = 2; return p + 1; } } break; case EL_ANYCRLF: while (p < endptr) { int extra = 0; register int c = *((unsigned char *)p); if (utf8 && c >= 0xc0) { int gcii, gcss; extra = utf8_table4[c & 0x3f]; /* Number of additional bytes */ gcss = 6*extra; c = (c & utf8_table3[extra]) << gcss; for (gcii = 1; gcii <= extra; gcii++) { gcss -= 6; c |= (p[gcii] & 0x3f) << gcss; } } p += 1 + extra; switch (c) { case 0x0a: /* LF */ *lenptr = 1; return p; case 0x0d: /* CR */ if (p < endptr && *p == 0x0a) { *lenptr = 2; p++; } else *lenptr = 1; return p; default: break; } } /* End of loop for ANYCRLF case */ *lenptr = 0; /* Must have hit the end */ return endptr; case EL_ANY: while (p < endptr) { int extra = 0; register int c = *((unsigned char *)p); if (utf8 && c >= 0xc0) { int gcii, gcss; extra = utf8_table4[c & 0x3f]; /* Number of additional bytes */ gcss = 6*extra; c = (c & utf8_table3[extra]) << gcss; for (gcii = 1; gcii <= extra; gcii++) { gcss -= 6; c |= (p[gcii] & 0x3f) << gcss; } } p += 1 + extra; switch (c) { case 0x0a: /* LF */ case 0x0b: /* VT */ case 0x0c: /* FF */ *lenptr = 1; return p; case 0x0d: /* CR */ if (p < endptr && *p == 0x0a) { *lenptr = 2; p++; } else *lenptr = 1; return p; case 0x85: /* NEL */ *lenptr = utf8? 2 : 1; return p; case 0x2028: /* LS */ case 0x2029: /* PS */ *lenptr = 3; return p; default: break; } } /* End of loop for ANY case */ *lenptr = 0; /* Must have hit the end */ return endptr; } /* End of overall switch */ } /************************************************* * Find start of previous line * *************************************************/ /* This is called when looking back for before lines to print. Arguments: p start of the subsequent line startptr start of available data Returns: pointer to the start of the previous line */ static char * previous_line(char *p, char *startptr) { switch(endlinetype) { default: /* Just in case */ case EL_LF: p--; while (p > startptr && p[-1] != '\n') p--; return p; case EL_CR: p--; while (p > startptr && p[-1] != '\n') p--; return p; case EL_CRLF: for (;;) { p -= 2; while (p > startptr && p[-1] != '\n') p--; if (p <= startptr + 1 || p[-2] == '\r') return p; } return p; /* But control should never get here */ case EL_ANY: case EL_ANYCRLF: if (*(--p) == '\n' && p > startptr && p[-1] == '\r') p--; if (utf8) while ((*p & 0xc0) == 0x80) p--; while (p > startptr) { register int c; char *pp = p - 1; if (utf8) { int extra = 0; while ((*pp & 0xc0) == 0x80) pp--; c = *((unsigned char *)pp); if (c >= 0xc0) { int gcii, gcss; extra = utf8_table4[c & 0x3f]; /* Number of additional bytes */ gcss = 6*extra; c = (c & utf8_table3[extra]) << gcss; for (gcii = 1; gcii <= extra; gcii++) { gcss -= 6; c |= (pp[gcii] & 0x3f) << gcss; } } } else c = *((unsigned char *)pp); if (endlinetype == EL_ANYCRLF) switch (c) { case 0x0a: /* LF */ case 0x0d: /* CR */ return p; default: break; } else switch (c) { case 0x0a: /* LF */ case 0x0b: /* VT */ case 0x0c: /* FF */ case 0x0d: /* CR */ case 0x85: /* NEL */ case 0x2028: /* LS */ case 0x2029: /* PS */ return p; default: break; } p = pp; /* Back one character */ } /* End of loop for ANY case */ return startptr; /* Hit start of data */ } /* End of overall switch */ } /************************************************* * Print the previous "after" lines * *************************************************/ /* This is called if we are about to lose said lines because of buffer filling, and at the end of the file. The data in the line is written using fwrite() so that a binary zero does not terminate it. Arguments: lastmatchnumber the number of the last matching line, plus one lastmatchrestart where we restarted after the last match endptr end of available data printname filename for printing Returns: nothing */ static void do_after_lines(int lastmatchnumber, char *lastmatchrestart, char *endptr, char *printname) { if (after_context > 0 && lastmatchnumber > 0) { int count = 0; while (lastmatchrestart < endptr && count++ < after_context) { int ellength; char *pp = lastmatchrestart; if (printname != NULL) fprintf(stdout, "%s-", printname); if (number) fprintf(stdout, "%d-", lastmatchnumber++); pp = end_of_line(pp, endptr, &ellength); fwrite(lastmatchrestart, 1, pp - lastmatchrestart, stdout); lastmatchrestart = pp; } hyphenpending = TRUE; } } /************************************************* * Grep an individual file * *************************************************/ /* This is called from grep_or_recurse() below. It uses a buffer that is three times the value of MBUFTHIRD. The matching point is never allowed to stray into the top third of the buffer, thus keeping more of the file available for context printing or for multiline scanning. For large files, the pointer will be in the middle third most of the time, so the bottom third is available for "before" context printing. Arguments: in the fopened FILE stream printname the file name if it is to be printed for each match or NULL if the file name is not to be printed it cannot be NULL if filenames[_nomatch]_only is set Returns: 0 if there was at least one match 1 otherwise (no matches) */ static int pcregrep(FILE *in, char *printname) { int rc = 1; int linenumber = 1; int lastmatchnumber = 0; int count = 0; int offsets[99]; char *lastmatchrestart = NULL; char buffer[3*MBUFTHIRD]; char *ptr = buffer; char *endptr; size_t bufflength; BOOL endhyphenpending = FALSE; /* Do the first read into the start of the buffer and set up the pointer to end of what we have. */ bufflength = fread(buffer, 1, 3*MBUFTHIRD, in); endptr = buffer + bufflength; /* Loop while the current pointer is not at the end of the file. For large files, endptr will be at the end of the buffer when we are in the middle of the file, but ptr will never get there, because as soon as it gets over 2/3 of the way, the buffer is shifted left and re-filled. */ while (ptr < endptr) { int i, endlinelength; int mrc = 0; BOOL match = FALSE; char *t = ptr; size_t length, linelength; /* At this point, ptr is at the start of a line. We need to find the length of the subject string to pass to pcre_exec(). In multiline mode, it is the length remainder of the data in the buffer. Otherwise, it is the length of the next line. After matching, we always advance by the length of the next line. In multiline mode the PCRE_FIRSTLINE option is used for compiling, so that any match is constrained to be in the first line. */ t = end_of_line(t, endptr, &endlinelength); linelength = t - ptr - endlinelength; length = multiline? (size_t)(endptr - ptr) : linelength; /* Extra processing for Jeffrey Friedl's debugging. */ #ifdef JFRIEDL_DEBUG if (jfriedl_XT || jfriedl_XR) { #include #include struct timeval start_time, end_time; struct timezone dummy; if (jfriedl_XT) { unsigned long newlen = length * jfriedl_XT + strlen(jfriedl_prefix) + strlen(jfriedl_postfix); const char *orig = ptr; ptr = malloc(newlen + 1); if (!ptr) { printf("out of memory"); exit(2); } endptr = ptr; strcpy(endptr, jfriedl_prefix); endptr += strlen(jfriedl_prefix); for (i = 0; i < jfriedl_XT; i++) { strncpy(endptr, orig, length); endptr += length; } strcpy(endptr, jfriedl_postfix); endptr += strlen(jfriedl_postfix); length = newlen; } if (gettimeofday(&start_time, &dummy) != 0) perror("bad gettimeofday"); for (i = 0; i < jfriedl_XR; i++) match = (pcre_exec(pattern_list[0], hints_list[0], ptr, length, 0, 0, offsets, 99) >= 0); if (gettimeofday(&end_time, &dummy) != 0) perror("bad gettimeofday"); double delta = ((end_time.tv_sec + (end_time.tv_usec / 1000000.0)) - (start_time.tv_sec + (start_time.tv_usec / 1000000.0))); printf("%s TIMER[%.4f]\n", match ? "MATCH" : "FAIL", delta); return 0; } #endif /* Run through all the patterns until one matches. Note that we don't include the final newline in the subject string. */ for (i = 0; i < pattern_count; i++) { mrc = pcre_exec(pattern_list[i], hints_list[i], ptr, length, 0, 0, offsets, 99); if (mrc >= 0) { match = TRUE; break; } if (mrc != PCRE_ERROR_NOMATCH) { fprintf(stderr, "pcregrep: pcre_exec() error %d while matching ", mrc); if (pattern_count > 1) fprintf(stderr, "pattern number %d to ", i+1); fprintf(stderr, "this line:\n"); fwrite(ptr, 1, linelength, stderr); /* In case binary zero included */ fprintf(stderr, "\n"); if (error_count == 0 && (mrc == PCRE_ERROR_MATCHLIMIT || mrc == PCRE_ERROR_RECURSIONLIMIT)) { fprintf(stderr, "pcregrep: error %d means that a resource limit " "was exceeded\n", mrc); fprintf(stderr, "pcregrep: check your regex for nested unlimited loops\n"); } if (error_count++ > 20) { fprintf(stderr, "pcregrep: too many errors - abandoned\n"); exit(2); } match = invert; /* No more matching; don't show the line again */ break; } } /* If it's a match or a not-match (as required), do what's wanted. */ if (match != invert) { BOOL hyphenprinted = FALSE; /* We've failed if we want a file that doesn't have any matches. */ if (filenames == FN_NOMATCH_ONLY) return 1; /* Just count if just counting is wanted. */ if (count_only) count++; /* If all we want is a file name, there is no need to scan any more lines in the file. */ else if (filenames == FN_ONLY) { fprintf(stdout, "%s\n", printname); return 0; } /* Likewise, if all we want is a yes/no answer. */ else if (quiet) return 0; /* The --only-matching option prints just the substring that matched, and does not pring any context. */ else if (only_matching) { if (printname != NULL) fprintf(stdout, "%s:", printname); if (number) fprintf(stdout, "%d:", linenumber); fwrite(ptr + offsets[0], 1, offsets[1] - offsets[0], stdout); fprintf(stdout, "\n"); } /* This is the default case when none of the above options is set. We print the matching lines(s), possibly preceded and/or followed by other lines of context. */ else { /* See if there is a requirement to print some "after" lines from a previous match. We never print any overlaps. */ if (after_context > 0 && lastmatchnumber > 0) { int ellength; int linecount = 0; char *p = lastmatchrestart; while (p < ptr && linecount < after_context) { p = end_of_line(p, ptr, &ellength); linecount++; } /* It is important to advance lastmatchrestart during this printing so that it interacts correctly with any "before" printing below. Print each line's data using fwrite() in case there are binary zeroes. */ while (lastmatchrestart < p) { char *pp = lastmatchrestart; if (printname != NULL) fprintf(stdout, "%s-", printname); if (number) fprintf(stdout, "%d-", lastmatchnumber++); pp = end_of_line(pp, endptr, &ellength); fwrite(lastmatchrestart, 1, pp - lastmatchrestart, stdout); lastmatchrestart = pp; } if (lastmatchrestart != ptr) hyphenpending = TRUE; } /* If there were non-contiguous lines printed above, insert hyphens. */ if (hyphenpending) { fprintf(stdout, "--\n"); hyphenpending = FALSE; hyphenprinted = TRUE; } /* See if there is a requirement to print some "before" lines for this match. Again, don't print overlaps. */ if (before_context > 0) { int linecount = 0; char *p = ptr; while (p > buffer && (lastmatchnumber == 0 || p > lastmatchrestart) && linecount < before_context) { linecount++; p = previous_line(p, buffer); } if (lastmatchnumber > 0 && p > lastmatchrestart && !hyphenprinted) fprintf(stdout, "--\n"); while (p < ptr) { int ellength; char *pp = p; if (printname != NULL) fprintf(stdout, "%s-", printname); if (number) fprintf(stdout, "%d-", linenumber - linecount--); pp = end_of_line(pp, endptr, &ellength); fwrite(p, 1, pp - p, stdout); p = pp; } } /* Now print the matching line(s); ensure we set hyphenpending at the end of the file if any context lines are being output. */ if (after_context > 0 || before_context > 0) endhyphenpending = TRUE; if (printname != NULL) fprintf(stdout, "%s:", printname); if (number) fprintf(stdout, "%d:", linenumber); /* In multiline mode, we want to print to the end of the line in which the end of the matched string is found, so we adjust linelength and the line number appropriately, but only when there actually was a match (invert not set). Because the PCRE_FIRSTLINE option is set, the start of the match will always be before the first newline sequence. */ if (multiline) { int ellength; char *endmatch = ptr; if (!invert) { endmatch += offsets[1]; t = ptr; while (t < endmatch) { t = end_of_line(t, endptr, &ellength); if (t <= endmatch) linenumber++; else break; } } endmatch = end_of_line(endmatch, endptr, &ellength); linelength = endmatch - ptr - ellength; } /*** NOTE: Use only fwrite() to output the data line, so that binary zeroes are treated as just another data character. */ /* This extra option, for Jeffrey Friedl's debugging requirements, replaces the matched string, or a specific captured string if it exists, with X. When this happens, colouring is ignored. */ #ifdef JFRIEDL_DEBUG if (S_arg >= 0 && S_arg < mrc) { int first = S_arg * 2; int last = first + 1; fwrite(ptr, 1, offsets[first], stdout); fprintf(stdout, "X"); fwrite(ptr + offsets[last], 1, linelength - offsets[last], stdout); } else #endif /* We have to split the line(s) up if colouring. */ if (do_colour) { fwrite(ptr, 1, offsets[0], stdout); fprintf(stdout, "%c[%sm", 0x1b, colour_string); fwrite(ptr + offsets[0], 1, offsets[1] - offsets[0], stdout); fprintf(stdout, "%c[00m", 0x1b); fwrite(ptr + offsets[1], 1, linelength - offsets[1], stdout); } else fwrite(ptr, 1, linelength + endlinelength, stdout); } /* End of doing what has to be done for a match */ rc = 0; /* Had some success */ /* Remember where the last match happened for after_context. We remember where we are about to restart, and that line's number. */ lastmatchrestart = ptr + linelength + endlinelength; lastmatchnumber = linenumber + 1; } /* For a match in multiline inverted mode (which of course did not cause anything to be printed), we have to move on to the end of the match before proceeding. */ if (multiline && invert && match) { int ellength; char *endmatch = ptr + offsets[1]; t = ptr; while (t < endmatch) { t = end_of_line(t, endptr, &ellength); if (t <= endmatch) linenumber++; else break; } endmatch = end_of_line(endmatch, endptr, &ellength); linelength = endmatch - ptr - ellength; } /* Advance to after the newline and increment the line number. */ ptr += linelength + endlinelength; linenumber++; /* If we haven't yet reached the end of the file (the buffer is full), and the current point is in the top 1/3 of the buffer, slide the buffer down by 1/3 and refill it. Before we do this, if some unprinted "after" lines are about to be lost, print them. */ if (bufflength >= sizeof(buffer) && ptr > buffer + 2*MBUFTHIRD) { if (after_context > 0 && lastmatchnumber > 0 && lastmatchrestart < buffer + MBUFTHIRD) { do_after_lines(lastmatchnumber, lastmatchrestart, endptr, printname); lastmatchnumber = 0; } /* Now do the shuffle */ memmove(buffer, buffer + MBUFTHIRD, 2*MBUFTHIRD); ptr -= MBUFTHIRD; bufflength = 2*MBUFTHIRD + fread(buffer + 2*MBUFTHIRD, 1, MBUFTHIRD, in); endptr = buffer + bufflength; /* Adjust any last match point */ if (lastmatchnumber > 0) lastmatchrestart -= MBUFTHIRD; } } /* Loop through the whole file */ /* End of file; print final "after" lines if wanted; do_after_lines sets hyphenpending if it prints something. */ if (!only_matching && !count_only) { do_after_lines(lastmatchnumber, lastmatchrestart, endptr, printname); hyphenpending |= endhyphenpending; } /* Print the file name if we are looking for those without matches and there were none. If we found a match, we won't have got this far. */ if (filenames == FN_NOMATCH_ONLY) { fprintf(stdout, "%s\n", printname); return 0; } /* Print the match count if wanted */ if (count_only) { if (printname != NULL) fprintf(stdout, "%s:", printname); fprintf(stdout, "%d\n", count); } return rc; } /************************************************* * Grep a file or recurse into a directory * *************************************************/ /* Given a path name, if it's a directory, scan all the files if we are recursing; if it's a file, grep it. Arguments: pathname the path to investigate dir_recurse TRUE if recursing is wanted (-r or -drecurse) only_one_at_top TRUE if the path is the only one at toplevel Returns: 0 if there was at least one match 1 if there were no matches 2 there was some kind of error However, file opening failures are suppressed if "silent" is set. */ static int grep_or_recurse(char *pathname, BOOL dir_recurse, BOOL only_one_at_top) { int rc = 1; int sep; FILE *in; /* If the file name is "-" we scan stdin */ if (strcmp(pathname, "-") == 0) { return pcregrep(stdin, (filenames > FN_DEFAULT || (filenames == FN_DEFAULT && !only_one_at_top))? stdin_name : NULL); } /* If the file is a directory, skip if skipping or if we are recursing, scan each file within it, subject to any include or exclude patterns that were set. The scanning code is localized so it can be made system-specific. */ if ((sep = isdirectory(pathname)) != 0) { if (dee_action == dee_SKIP) return 1; if (dee_action == dee_RECURSE) { char buffer[1024]; char *nextfile; directory_type *dir = opendirectory(pathname); if (dir == NULL) { if (!silent) fprintf(stderr, "pcregrep: Failed to open directory %s: %s\n", pathname, strerror(errno)); return 2; } while ((nextfile = readdirectory(dir)) != NULL) { int frc, blen; sprintf(buffer, "%.512s%c%.128s", pathname, sep, nextfile); blen = strlen(buffer); if (exclude_compiled != NULL && pcre_exec(exclude_compiled, NULL, buffer, blen, 0, 0, NULL, 0) >= 0) continue; if (include_compiled != NULL && pcre_exec(include_compiled, NULL, buffer, blen, 0, 0, NULL, 0) < 0) continue; frc = grep_or_recurse(buffer, dir_recurse, FALSE); if (frc > 1) rc = frc; else if (frc == 0 && rc == 1) rc = 0; } closedirectory(dir); return rc; } } /* If the file is not a directory and not a regular file, skip it if that's been requested. */ else if (!isregfile(pathname) && DEE_action == DEE_SKIP) return 1; /* Control reaches here if we have a regular file, or if we have a directory and recursion or skipping was not requested, or if we have anything else and skipping was not requested. The scan proceeds. If this is the first and only argument at top level, we don't show the file name, unless we are only showing the file name, or the filename was forced (-H). */ in = fopen(pathname, "r"); if (in == NULL) { if (!silent) fprintf(stderr, "pcregrep: Failed to open %s: %s\n", pathname, strerror(errno)); return 2; } rc = pcregrep(in, (filenames > FN_DEFAULT || (filenames == FN_DEFAULT && !only_one_at_top))? pathname : NULL); fclose(in); return rc; } /************************************************* * Usage function * *************************************************/ static int usage(int rc) { option_item *op; fprintf(stderr, "Usage: pcregrep [-"); for (op = optionlist; op->one_char != 0; op++) { if (op->one_char > 0) fprintf(stderr, "%c", op->one_char); } fprintf(stderr, "] [long options] [pattern] [files]\n"); fprintf(stderr, "Type `pcregrep --help' for more information.\n"); return rc; } /************************************************* * Help function * *************************************************/ static void help(void) { option_item *op; printf("Usage: pcregrep [OPTION]... [PATTERN] [FILE1 FILE2 ...]\n"); printf("Search for PATTERN in each FILE or standard input.\n"); printf("PATTERN must be present if neither -e nor -f is used.\n"); printf("\"-\" can be used as a file name to mean STDIN.\n\n"); printf("Example: pcregrep -i 'hello.*world' menu.h main.c\n\n"); printf("Options:\n"); for (op = optionlist; op->one_char != 0; op++) { int n; char s[4]; if (op->one_char > 0) sprintf(s, "-%c,", op->one_char); else strcpy(s, " "); printf(" %s --%s%n", s, op->long_name, &n); n = 30 - n; if (n < 1) n = 1; printf("%.*s%s\n", n, " ", op->help_text); } printf("\nWhen reading patterns from a file instead of using a command line option,\n"); printf("trailing white space is removed and blank lines are ignored.\n"); printf("There is a maximum of %d patterns.\n", MAX_PATTERN_COUNT); printf("\nWith no FILEs, read standard input. If fewer than two FILEs given, assume -h.\n"); printf("Exit status is 0 if any matches, 1 if no matches, and 2 if trouble.\n"); } /************************************************* * Handle a single-letter, no data option * *************************************************/ static int handle_option(int letter, int options) { switch(letter) { case N_HELP: help(); exit(0); case 'c': count_only = TRUE; break; case 'F': process_options |= PO_FIXED_STRINGS; break; case 'H': filenames = FN_FORCE; break; case 'h': filenames = FN_NONE; break; case 'i': options |= PCRE_CASELESS; break; case 'l': filenames = FN_ONLY; break; case 'L': filenames = FN_NOMATCH_ONLY; break; case 'M': multiline = TRUE; options |= PCRE_MULTILINE|PCRE_FIRSTLINE; break; case 'n': number = TRUE; break; case 'o': only_matching = TRUE; break; case 'q': quiet = TRUE; break; case 'r': dee_action = dee_RECURSE; break; case 's': silent = TRUE; break; case 'u': options |= PCRE_UTF8; utf8 = TRUE; break; case 'v': invert = TRUE; break; case 'w': process_options |= PO_WORD_MATCH; break; case 'x': process_options |= PO_LINE_MATCH; break; case 'V': fprintf(stderr, "pcregrep version %s\n", pcre_version()); exit(0); break; default: fprintf(stderr, "pcregrep: Unknown option -%c\n", letter); exit(usage(2)); } return options; } /************************************************* * Construct printed ordinal * *************************************************/ /* This turns a number into "1st", "3rd", etc. */ static char * ordin(int n) { static char buffer[8]; char *p = buffer; sprintf(p, "%d", n); while (*p != 0) p++; switch (n%10) { case 1: strcpy(p, "st"); break; case 2: strcpy(p, "nd"); break; case 3: strcpy(p, "rd"); break; default: strcpy(p, "th"); break; } return buffer; } /************************************************* * Compile a single pattern * *************************************************/ /* When the -F option has been used, this is called for each substring. Otherwise it's called for each supplied pattern. Arguments: pattern the pattern string options the PCRE options filename the file name, or NULL for a command-line pattern count 0 if this is the only command line pattern, or number of the command line pattern, or linenumber for a pattern from a file Returns: TRUE on success, FALSE after an error */ static BOOL compile_single_pattern(char *pattern, int options, char *filename, int count) { char buffer[MBUFTHIRD + 16]; const char *error; int errptr; if (pattern_count >= MAX_PATTERN_COUNT) { fprintf(stderr, "pcregrep: Too many %spatterns (max %d)\n", (filename == NULL)? "command-line " : "", MAX_PATTERN_COUNT); return FALSE; } sprintf(buffer, "%s%.*s%s", prefix[process_options], MBUFTHIRD, pattern, suffix[process_options]); pattern_list[pattern_count] = pcre_compile(buffer, options, &error, &errptr, pcretables); if (pattern_list[pattern_count] != NULL) { pattern_count++; return TRUE; } /* Handle compile errors */ errptr -= (int)strlen(prefix[process_options]); if (errptr > (int)strlen(pattern)) errptr = (int)strlen(pattern); if (filename == NULL) { if (count == 0) fprintf(stderr, "pcregrep: Error in command-line regex " "at offset %d: %s\n", errptr, error); else fprintf(stderr, "pcregrep: Error in %s command-line regex " "at offset %d: %s\n", ordin(count), errptr, error); } else { fprintf(stderr, "pcregrep: Error in regex in line %d of %s " "at offset %d: %s\n", count, filename, errptr, error); } return FALSE; } /************************************************* * Compile one supplied pattern * *************************************************/ /* When the -F option has been used, each string may be a list of strings, separated by line breaks. They will be matched literally. Arguments: pattern the pattern string options the PCRE options filename the file name, or NULL for a command-line pattern count 0 if this is the only command line pattern, or number of the command line pattern, or linenumber for a pattern from a file Returns: TRUE on success, FALSE after an error */ static BOOL compile_pattern(char *pattern, int options, char *filename, int count) { if ((process_options & PO_FIXED_STRINGS) != 0) { char *eop = pattern + strlen(pattern); char buffer[MBUFTHIRD]; for(;;) { int ellength; char *p = end_of_line(pattern, eop, &ellength); if (ellength == 0) return compile_single_pattern(pattern, options, filename, count); sprintf(buffer, "%.*s", (int)(p - pattern - ellength), pattern); pattern = p; if (!compile_single_pattern(buffer, options, filename, count)) return FALSE; } } else return compile_single_pattern(pattern, options, filename, count); } /************************************************* * Main program * *************************************************/ /* Returns 0 if something matched, 1 if nothing matched, 2 after an error. */ int main(int argc, char **argv) { int i, j; int rc = 1; int pcre_options = 0; int cmd_pattern_count = 0; int hint_count = 0; int errptr; BOOL only_one_at_top; char *patterns[MAX_PATTERN_COUNT]; const char *locale_from = "--locale"; const char *error; /* Set the default line ending value from the default in the PCRE library; "lf", "cr", "crlf", and "any" are supported. Anything else is treated as "lf". */ (void)pcre_config(PCRE_CONFIG_NEWLINE, &i); switch(i) { default: newline = (char *)"lf"; break; case '\r': newline = (char *)"cr"; break; case ('\r' << 8) | '\n': newline = (char *)"crlf"; break; case -1: newline = (char *)"any"; break; case -2: newline = (char *)"anycrlf"; break; } /* Process the options */ for (i = 1; i < argc; i++) { option_item *op = NULL; char *option_data = (char *)""; /* default to keep compiler happy */ BOOL longop; BOOL longopwasequals = FALSE; if (argv[i][0] != '-') break; /* If we hit an argument that is just "-", it may be a reference to STDIN, but only if we have previously had -e or -f to define the patterns. */ if (argv[i][1] == 0) { if (pattern_filename != NULL || pattern_count > 0) break; else exit(usage(2)); } /* Handle a long name option, or -- to terminate the options */ if (argv[i][1] == '-') { char *arg = argv[i] + 2; char *argequals = strchr(arg, '='); if (*arg == 0) /* -- terminates options */ { i++; break; /* out of the options-handling loop */ } longop = TRUE; /* Some long options have data that follows after =, for example file=name. Some options have variations in the long name spelling: specifically, we allow "regexp" because GNU grep allows it, though I personally go along with Jeffrey Friedl and Larry Wall in preferring "regex" without the "p". These options are entered in the table as "regex(p)". No option is in both these categories, fortunately. */ for (op = optionlist; op->one_char != 0; op++) { char *opbra = strchr(op->long_name, '('); char *equals = strchr(op->long_name, '='); if (opbra == NULL) /* Not a (p) case */ { if (equals == NULL) /* Not thing=data case */ { if (strcmp(arg, op->long_name) == 0) break; } else /* Special case xxx=data */ { int oplen = equals - op->long_name; int arglen = (argequals == NULL)? (int)strlen(arg) : argequals - arg; if (oplen == arglen && strncmp(arg, op->long_name, oplen) == 0) { option_data = arg + arglen; if (*option_data == '=') { option_data++; longopwasequals = TRUE; } break; } } } else /* Special case xxxx(p) */ { char buff1[24]; char buff2[24]; int baselen = opbra - op->long_name; sprintf(buff1, "%.*s", baselen, op->long_name); sprintf(buff2, "%s%.*s", buff1, (int)strlen(op->long_name) - baselen - 2, opbra + 1); if (strcmp(arg, buff1) == 0 || strcmp(arg, buff2) == 0) break; } } if (op->one_char == 0) { fprintf(stderr, "pcregrep: Unknown option %s\n", argv[i]); exit(usage(2)); } } /* Jeffrey Friedl's debugging harness uses these additional options which are not in the right form for putting in the option table because they use only one hyphen, yet are more than one character long. By putting them separately here, they will not get displayed as part of the help() output, but I don't think Jeffrey will care about that. */ #ifdef JFRIEDL_DEBUG else if (strcmp(argv[i], "-pre") == 0) { jfriedl_prefix = argv[++i]; continue; } else if (strcmp(argv[i], "-post") == 0) { jfriedl_postfix = argv[++i]; continue; } else if (strcmp(argv[i], "-XT") == 0) { sscanf(argv[++i], "%d", &jfriedl_XT); continue; } else if (strcmp(argv[i], "-XR") == 0) { sscanf(argv[++i], "%d", &jfriedl_XR); continue; } #endif /* One-char options; many that have no data may be in a single argument; we continue till we hit the last one or one that needs data. */ else { char *s = argv[i] + 1; longop = FALSE; while (*s != 0) { for (op = optionlist; op->one_char != 0; op++) { if (*s == op->one_char) break; } if (op->one_char == 0) { fprintf(stderr, "pcregrep: Unknown option letter '%c' in \"%s\"\n", *s, argv[i]); exit(usage(2)); } if (op->type != OP_NODATA || s[1] == 0) { option_data = s+1; break; } pcre_options = handle_option(*s++, pcre_options); } } /* At this point we should have op pointing to a matched option. If the type is NO_DATA, it means that there is no data, and the option might set something in the PCRE options. */ if (op->type == OP_NODATA) { pcre_options = handle_option(op->one_char, pcre_options); continue; } /* If the option type is OP_OP_STRING or OP_OP_NUMBER, it's an option that either has a value or defaults to something. It cannot have data in a separate item. At the moment, the only such options are "colo(u)r" and Jeffrey Friedl's special -S debugging option. */ if (*option_data == 0 && (op->type == OP_OP_STRING || op->type == OP_OP_NUMBER)) { switch (op->one_char) { case N_COLOUR: colour_option = (char *)"auto"; break; #ifdef JFRIEDL_DEBUG case 'S': S_arg = 0; break; #endif } continue; } /* Otherwise, find the data string for the option. */ if (*option_data == 0) { if (i >= argc - 1 || longopwasequals) { fprintf(stderr, "pcregrep: Data missing after %s\n", argv[i]); exit(usage(2)); } option_data = argv[++i]; } /* If the option type is OP_PATLIST, it's the -e option, which can be called multiple times to create a list of patterns. */ if (op->type == OP_PATLIST) { if (cmd_pattern_count >= MAX_PATTERN_COUNT) { fprintf(stderr, "pcregrep: Too many command-line patterns (max %d)\n", MAX_PATTERN_COUNT); return 2; } patterns[cmd_pattern_count++] = option_data; } /* Otherwise, deal with single string or numeric data values. */ else if (op->type != OP_NUMBER && op->type != OP_OP_NUMBER) { *((char **)op->dataptr) = option_data; } else { char *endptr; int n = strtoul(option_data, &endptr, 10); if (*endptr != 0) { if (longop) { char *equals = strchr(op->long_name, '='); int nlen = (equals == NULL)? (int)strlen(op->long_name) : equals - op->long_name; fprintf(stderr, "pcregrep: Malformed number \"%s\" after --%.*s\n", option_data, nlen, op->long_name); } else fprintf(stderr, "pcregrep: Malformed number \"%s\" after -%c\n", option_data, op->one_char); exit(usage(2)); } *((int *)op->dataptr) = n; } } /* Options have been decoded. If -C was used, its value is used as a default for -A and -B. */ if (both_context > 0) { if (after_context == 0) after_context = both_context; if (before_context == 0) before_context = both_context; } /* If a locale has not been provided as an option, see if the LC_CTYPE or LC_ALL environment variable is set, and if so, use it. */ if (locale == NULL) { locale = getenv("LC_ALL"); locale_from = "LCC_ALL"; } if (locale == NULL) { locale = getenv("LC_CTYPE"); locale_from = "LC_CTYPE"; } /* If a locale has been provided, set it, and generate the tables the PCRE needs. Otherwise, pcretables==NULL, which causes the use of default tables. */ if (locale != NULL) { if (setlocale(LC_CTYPE, locale) == NULL) { fprintf(stderr, "pcregrep: Failed to set locale %s (obtained from %s)\n", locale, locale_from); return 2; } pcretables = pcre_maketables(); } /* Sort out colouring */ if (colour_option != NULL && strcmp(colour_option, "never") != 0) { if (strcmp(colour_option, "always") == 0) do_colour = TRUE; else if (strcmp(colour_option, "auto") == 0) do_colour = is_stdout_tty(); else { fprintf(stderr, "pcregrep: Unknown colour setting \"%s\"\n", colour_option); return 2; } if (do_colour) { char *cs = getenv("PCREGREP_COLOUR"); if (cs == NULL) cs = getenv("PCREGREP_COLOR"); if (cs != NULL) colour_string = cs; } } /* Interpret the newline type; the default settings are Unix-like. */ if (strcmp(newline, "cr") == 0 || strcmp(newline, "CR") == 0) { pcre_options |= PCRE_NEWLINE_CR; endlinetype = EL_CR; } else if (strcmp(newline, "lf") == 0 || strcmp(newline, "LF") == 0) { pcre_options |= PCRE_NEWLINE_LF; endlinetype = EL_LF; } else if (strcmp(newline, "crlf") == 0 || strcmp(newline, "CRLF") == 0) { pcre_options |= PCRE_NEWLINE_CRLF; endlinetype = EL_CRLF; } else if (strcmp(newline, "any") == 0 || strcmp(newline, "ANY") == 0) { pcre_options |= PCRE_NEWLINE_ANY; endlinetype = EL_ANY; } else if (strcmp(newline, "anycrlf") == 0 || strcmp(newline, "ANYCRLF") == 0) { pcre_options |= PCRE_NEWLINE_ANYCRLF; endlinetype = EL_ANYCRLF; } else { fprintf(stderr, "pcregrep: Invalid newline specifier \"%s\"\n", newline); return 2; } /* Interpret the text values for -d and -D */ if (dee_option != NULL) { if (strcmp(dee_option, "read") == 0) dee_action = dee_READ; else if (strcmp(dee_option, "recurse") == 0) dee_action = dee_RECURSE; else if (strcmp(dee_option, "skip") == 0) dee_action = dee_SKIP; else { fprintf(stderr, "pcregrep: Invalid value \"%s\" for -d\n", dee_option); return 2; } } if (DEE_option != NULL) { if (strcmp(DEE_option, "read") == 0) DEE_action = DEE_READ; else if (strcmp(DEE_option, "skip") == 0) DEE_action = DEE_SKIP; else { fprintf(stderr, "pcregrep: Invalid value \"%s\" for -D\n", DEE_option); return 2; } } /* Check the values for Jeffrey Friedl's debugging options. */ #ifdef JFRIEDL_DEBUG if (S_arg > 9) { fprintf(stderr, "pcregrep: bad value for -S option\n"); return 2; } if (jfriedl_XT != 0 || jfriedl_XR != 0) { if (jfriedl_XT == 0) jfriedl_XT = 1; if (jfriedl_XR == 0) jfriedl_XR = 1; } #endif /* Get memory to store the pattern and hints lists. */ pattern_list = (pcre **)malloc(MAX_PATTERN_COUNT * sizeof(pcre *)); hints_list = (pcre_extra **)malloc(MAX_PATTERN_COUNT * sizeof(pcre_extra *)); if (pattern_list == NULL || hints_list == NULL) { fprintf(stderr, "pcregrep: malloc failed\n"); goto EXIT2; } /* If no patterns were provided by -e, and there is no file provided by -f, the first argument is the one and only pattern, and it must exist. */ if (cmd_pattern_count == 0 && pattern_filename == NULL) { if (i >= argc) return usage(2); patterns[cmd_pattern_count++] = argv[i++]; } /* Compile the patterns that were provided on the command line, either by multiple uses of -e or as a single unkeyed pattern. */ for (j = 0; j < cmd_pattern_count; j++) { if (!compile_pattern(patterns[j], pcre_options, NULL, (j == 0 && cmd_pattern_count == 1)? 0 : j + 1)) goto EXIT2; } /* Compile the regular expressions that are provided in a file. */ if (pattern_filename != NULL) { int linenumber = 0; FILE *f; char *filename; char buffer[MBUFTHIRD]; if (strcmp(pattern_filename, "-") == 0) { f = stdin; filename = stdin_name; } else { f = fopen(pattern_filename, "r"); if (f == NULL) { fprintf(stderr, "pcregrep: Failed to open %s: %s\n", pattern_filename, strerror(errno)); goto EXIT2; } filename = pattern_filename; } while (fgets(buffer, MBUFTHIRD, f) != NULL) { char *s = buffer + (int)strlen(buffer); while (s > buffer && isspace((unsigned char)(s[-1]))) s--; *s = 0; linenumber++; if (buffer[0] == 0) continue; /* Skip blank lines */ if (!compile_pattern(buffer, pcre_options, filename, linenumber)) goto EXIT2; } if (f != stdin) fclose(f); } /* Study the regular expressions, as we will be running them many times */ for (j = 0; j < pattern_count; j++) { hints_list[j] = pcre_study(pattern_list[j], 0, &error); if (error != NULL) { char s[16]; if (pattern_count == 1) s[0] = 0; else sprintf(s, " number %d", j); fprintf(stderr, "pcregrep: Error while studying regex%s: %s\n", s, error); goto EXIT2; } hint_count++; } /* If there are include or exclude patterns, compile them. */ if (exclude_pattern != NULL) { exclude_compiled = pcre_compile(exclude_pattern, 0, &error, &errptr, pcretables); if (exclude_compiled == NULL) { fprintf(stderr, "pcregrep: Error in 'exclude' regex at offset %d: %s\n", errptr, error); goto EXIT2; } } if (include_pattern != NULL) { include_compiled = pcre_compile(include_pattern, 0, &error, &errptr, pcretables); if (include_compiled == NULL) { fprintf(stderr, "pcregrep: Error in 'include' regex at offset %d: %s\n", errptr, error); goto EXIT2; } } /* If there are no further arguments, do the business on stdin and exit. */ if (i >= argc) { rc = pcregrep(stdin, (filenames > FN_DEFAULT)? stdin_name : NULL); goto EXIT; } /* Otherwise, work through the remaining arguments as files or directories. Pass in the fact that there is only one argument at top level - this suppresses the file name if the argument is not a directory and filenames are not otherwise forced. */ only_one_at_top = i == argc - 1; /* Catch initial value of i */ for (; i < argc; i++) { int frc = grep_or_recurse(argv[i], dee_action == dee_RECURSE, only_one_at_top); if (frc > 1) rc = frc; else if (frc == 0 && rc == 1) rc = 0; } EXIT: if (pattern_list != NULL) { for (i = 0; i < pattern_count; i++) free(pattern_list[i]); free(pattern_list); } if (hints_list != NULL) { for (i = 0; i < hint_count; i++) free(hints_list[i]); free(hints_list); } return rc; EXIT2: rc = 2; goto EXIT; } /* End of pcregrep */ libsynthesis-3.4.0.47.1/src/pcre/pcreposix.c000066400000000000000000000301361226375725500205470ustar00rootroot00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Copyright (c) 1997-2007 University of Cambridge ----------------------------------------------------------------------------- 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 name of the University of Cambridge 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. ----------------------------------------------------------------------------- */ /* This module is a wrapper that provides a POSIX API to the underlying PCRE functions. */ #ifdef HAVE_CONFIG_H #include #endif /* Ensure that the PCREPOSIX_EXP_xxx macros are set appropriately for compiling these functions. This must come before including pcreposix.h, where they are set for an application (using these functions) if they have not previously been set. */ #if defined(_WIN32) && !defined(PCRE_STATIC) # define PCREPOSIX_EXP_DECL extern __declspec(dllexport) # define PCREPOSIX_EXP_DEFN __declspec(dllexport) #endif #include #include "pcre_internal.h" #include "pcreposix.h" /* Table to translate PCRE compile time error codes into POSIX error codes. */ static const int eint[] = { 0, /* no error */ REG_EESCAPE, /* \ at end of pattern */ REG_EESCAPE, /* \c at end of pattern */ REG_EESCAPE, /* unrecognized character follows \ */ REG_BADBR, /* numbers out of order in {} quantifier */ REG_BADBR, /* number too big in {} quantifier */ REG_EBRACK, /* missing terminating ] for character class */ REG_ECTYPE, /* invalid escape sequence in character class */ REG_ERANGE, /* range out of order in character class */ REG_BADRPT, /* nothing to repeat */ REG_BADRPT, /* operand of unlimited repeat could match the empty string */ REG_ASSERT, /* internal error: unexpected repeat */ REG_BADPAT, /* unrecognized character after (? */ REG_BADPAT, /* POSIX named classes are supported only within a class */ REG_EPAREN, /* missing ) */ REG_ESUBREG, /* reference to non-existent subpattern */ REG_INVARG, /* erroffset passed as NULL */ REG_INVARG, /* unknown option bit(s) set */ REG_EPAREN, /* missing ) after comment */ REG_ESIZE, /* parentheses nested too deeply */ REG_ESIZE, /* regular expression too large */ REG_ESPACE, /* failed to get memory */ REG_EPAREN, /* unmatched brackets */ REG_ASSERT, /* internal error: code overflow */ REG_BADPAT, /* unrecognized character after (?< */ REG_BADPAT, /* lookbehind assertion is not fixed length */ REG_BADPAT, /* malformed number or name after (?( */ REG_BADPAT, /* conditional group contains more than two branches */ REG_BADPAT, /* assertion expected after (?( */ REG_BADPAT, /* (?R or (?[+-]digits must be followed by ) */ REG_ECTYPE, /* unknown POSIX class name */ REG_BADPAT, /* POSIX collating elements are not supported */ REG_INVARG, /* this version of PCRE is not compiled with PCRE_UTF8 support */ REG_BADPAT, /* spare error */ REG_BADPAT, /* character value in \x{...} sequence is too large */ REG_BADPAT, /* invalid condition (?(0) */ REG_BADPAT, /* \C not allowed in lookbehind assertion */ REG_EESCAPE, /* PCRE does not support \L, \l, \N, \U, or \u */ REG_BADPAT, /* number after (?C is > 255 */ REG_BADPAT, /* closing ) for (?C expected */ REG_BADPAT, /* recursive call could loop indefinitely */ REG_BADPAT, /* unrecognized character after (?P */ REG_BADPAT, /* syntax error in subpattern name (missing terminator) */ REG_BADPAT, /* two named subpatterns have the same name */ REG_BADPAT, /* invalid UTF-8 string */ REG_BADPAT, /* support for \P, \p, and \X has not been compiled */ REG_BADPAT, /* malformed \P or \p sequence */ REG_BADPAT, /* unknown property name after \P or \p */ REG_BADPAT, /* subpattern name is too long (maximum 32 characters) */ REG_BADPAT, /* too many named subpatterns (maximum 10,000) */ REG_BADPAT, /* repeated subpattern is too long */ REG_BADPAT, /* octal value is greater than \377 (not in UTF-8 mode) */ REG_BADPAT, /* internal error: overran compiling workspace */ REG_BADPAT, /* internal error: previously-checked referenced subpattern not found */ REG_BADPAT, /* DEFINE group contains more than one branch */ REG_BADPAT, /* repeating a DEFINE group is not allowed */ REG_INVARG, /* inconsistent NEWLINE options */ REG_BADPAT, /* \g is not followed followed by an (optionally braced) non-zero number */ REG_BADPAT, /* (?+ or (?- must be followed by a non-zero number */ REG_BADPAT /* number is too big */ }; /* Table of texts corresponding to POSIX error codes */ static const char *const pstring[] = { "", /* Dummy for value 0 */ "internal error", /* REG_ASSERT */ "invalid repeat counts in {}", /* BADBR */ "pattern error", /* BADPAT */ "? * + invalid", /* BADRPT */ "unbalanced {}", /* EBRACE */ "unbalanced []", /* EBRACK */ "collation error - not relevant", /* ECOLLATE */ "bad class", /* ECTYPE */ "bad escape sequence", /* EESCAPE */ "empty expression", /* EMPTY */ "unbalanced ()", /* EPAREN */ "bad range inside []", /* ERANGE */ "expression too big", /* ESIZE */ "failed to get memory", /* ESPACE */ "bad back reference", /* ESUBREG */ "bad argument", /* INVARG */ "match failed" /* NOMATCH */ }; /************************************************* * Translate error code to string * *************************************************/ PCREPOSIX_EXP_DEFN size_t regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size) { const char *message, *addmessage; size_t length, addlength; message = (errcode >= (int)(sizeof(pstring)/sizeof(char *)))? "unknown error code" : pstring[errcode]; length = strlen(message) + 1; addmessage = " at offset "; addlength = (preg != NULL && (int)preg->re_erroffset != -1)? strlen(addmessage) + 6 : 0; if (errbuf_size > 0) { if (addlength > 0 && errbuf_size >= length + addlength) sprintf(errbuf, "%s%s%-6d", message, addmessage, (int)preg->re_erroffset); else { strncpy(errbuf, message, errbuf_size - 1); errbuf[errbuf_size-1] = 0; } } return length + addlength; } /************************************************* * Free store held by a regex * *************************************************/ PCREPOSIX_EXP_DEFN void regfree(regex_t *preg) { (pcre_free)(preg->re_pcre); } /************************************************* * Compile a regular expression * *************************************************/ /* Arguments: preg points to a structure for recording the compiled expression pattern the pattern to compile cflags compilation flags Returns: 0 on success various non-zero codes on failure */ PCREPOSIX_EXP_DEFN int regcomp(regex_t *preg, const char *pattern, int cflags) { const char *errorptr; int erroffset; int errorcode; int options = 0; if ((cflags & REG_ICASE) != 0) options |= PCRE_CASELESS; if ((cflags & REG_NEWLINE) != 0) options |= PCRE_MULTILINE; if ((cflags & REG_DOTALL) != 0) options |= PCRE_DOTALL; if ((cflags & REG_NOSUB) != 0) options |= PCRE_NO_AUTO_CAPTURE; if ((cflags & REG_UTF8) != 0) options |= PCRE_UTF8; preg->re_pcre = pcre_compile2(pattern, options, &errorcode, &errorptr, &erroffset, NULL); preg->re_erroffset = erroffset; if (preg->re_pcre == NULL) return eint[errorcode]; preg->re_nsub = pcre_info((const pcre *)preg->re_pcre, NULL, NULL); return 0; } /************************************************* * Match a regular expression * *************************************************/ /* Unfortunately, PCRE requires 3 ints of working space for each captured substring, so we have to get and release working store instead of just using the POSIX structures as was done in earlier releases when PCRE needed only 2 ints. However, if the number of possible capturing brackets is small, use a block of store on the stack, to reduce the use of malloc/free. The threshold is in a macro that can be changed at configure time. If REG_NOSUB was specified at compile time, the PCRE_NO_AUTO_CAPTURE flag will be set. When this is the case, the nmatch and pmatch arguments are ignored, and the only result is yes/no/error. */ PCREPOSIX_EXP_DEFN int regexec(const regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags) { int rc; int options = 0; int *ovector = NULL; int small_ovector[POSIX_MALLOC_THRESHOLD * 3]; BOOL allocated_ovector = FALSE; BOOL nosub = (((const pcre *)preg->re_pcre)->options & PCRE_NO_AUTO_CAPTURE) != 0; if ((eflags & REG_NOTBOL) != 0) options |= PCRE_NOTBOL; if ((eflags & REG_NOTEOL) != 0) options |= PCRE_NOTEOL; ((regex_t *)preg)->re_erroffset = (size_t)(-1); /* Only has meaning after compile */ /* When no string data is being returned, ensure that nmatch is zero. Otherwise, ensure the vector for holding the return data is large enough. */ if (nosub) nmatch = 0; else if (nmatch > 0) { if (nmatch <= POSIX_MALLOC_THRESHOLD) { ovector = &(small_ovector[0]); } else { if (nmatch > INT_MAX/(sizeof(int) * 3)) return REG_ESPACE; ovector = (int *)malloc(sizeof(int) * nmatch * 3); if (ovector == NULL) return REG_ESPACE; allocated_ovector = TRUE; } } rc = pcre_exec((const pcre *)preg->re_pcre, NULL, string, (int)strlen(string), 0, options, ovector, nmatch * 3); if (rc == 0) rc = nmatch; /* All captured slots were filled in */ if (rc >= 0) { size_t i; if (!nosub) { for (i = 0; i < (size_t)rc; i++) { pmatch[i].rm_so = ovector[i*2]; pmatch[i].rm_eo = ovector[i*2+1]; } if (allocated_ovector) free(ovector); for (; i < nmatch; i++) pmatch[i].rm_so = pmatch[i].rm_eo = -1; } return 0; } else { if (allocated_ovector) free(ovector); switch(rc) { case PCRE_ERROR_NOMATCH: return REG_NOMATCH; case PCRE_ERROR_NULL: return REG_INVARG; case PCRE_ERROR_BADOPTION: return REG_INVARG; case PCRE_ERROR_BADMAGIC: return REG_INVARG; case PCRE_ERROR_UNKNOWN_NODE: return REG_ASSERT; case PCRE_ERROR_NOMEMORY: return REG_ESPACE; case PCRE_ERROR_MATCHLIMIT: return REG_ESPACE; case PCRE_ERROR_BADUTF8: return REG_INVARG; case PCRE_ERROR_BADUTF8_OFFSET: return REG_INVARG; default: return REG_ASSERT; } } } /* End of pcreposix.c */ libsynthesis-3.4.0.47.1/src/pcre/pcreposix.h000066400000000000000000000115261226375725500205560ustar00rootroot00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ #ifndef _PCREPOSIX_H #define _PCREPOSIX_H /* This is the header for the POSIX wrapper interface to the PCRE Perl- Compatible Regular Expression library. It defines the things POSIX says should be there. I hope. Copyright (c) 1997-2007 University of Cambridge ----------------------------------------------------------------------------- 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 name of the University of Cambridge 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. ----------------------------------------------------------------------------- */ /* Have to include stdlib.h in order to ensure that size_t is defined. */ #include /* Allow for C++ users */ #ifdef __cplusplus extern "C" { #endif /* Options, mostly defined by POSIX, but with a couple of extras. */ #define REG_ICASE 0x0001 #define REG_NEWLINE 0x0002 #define REG_NOTBOL 0x0004 #define REG_NOTEOL 0x0008 #define REG_DOTALL 0x0010 /* NOT defined by POSIX. */ #define REG_NOSUB 0x0020 #define REG_UTF8 0x0040 /* NOT defined by POSIX. */ /* This is not used by PCRE, but by defining it we make it easier to slot PCRE into existing programs that make POSIX calls. */ #define REG_EXTENDED 0 /* Error values. Not all these are relevant or used by the wrapper. */ enum { REG_ASSERT = 1, /* internal error ? */ REG_BADBR, /* invalid repeat counts in {} */ REG_BADPAT, /* pattern error */ REG_BADRPT, /* ? * + invalid */ REG_EBRACE, /* unbalanced {} */ REG_EBRACK, /* unbalanced [] */ REG_ECOLLATE, /* collation error - not relevant */ REG_ECTYPE, /* bad class */ REG_EESCAPE, /* bad escape sequence */ REG_EMPTY, /* empty expression */ REG_EPAREN, /* unbalanced () */ REG_ERANGE, /* bad range inside [] */ REG_ESIZE, /* expression too big */ REG_ESPACE, /* failed to get memory */ REG_ESUBREG, /* bad back reference */ REG_INVARG, /* bad argument */ REG_NOMATCH /* match failed */ }; /* The structure representing a compiled regular expression. */ typedef struct { void *re_pcre; size_t re_nsub; size_t re_erroffset; } regex_t; /* The structure in which a captured offset is returned. */ typedef int regoff_t; typedef struct { regoff_t rm_so; regoff_t rm_eo; } regmatch_t; /* When an application links to a PCRE DLL in Windows, the symbols that are imported have to be identified as such. When building PCRE, the appropriate export settings are needed, and are set in pcreposix.c before including this file. */ #if defined(_WIN32) && !defined(PCRE_STATIC) && !defined(PCREPOSIX_EXP_DECL) # define PCREPOSIX_EXP_DECL extern __declspec(dllimport) # define PCREPOSIX_EXP_DEFN __declspec(dllimport) #endif /* By default, we use the standard "extern" declarations. */ #ifndef PCREPOSIX_EXP_DECL # ifdef __cplusplus # define PCREPOSIX_EXP_DECL extern "C" # define PCREPOSIX_EXP_DEFN extern "C" # else # define PCREPOSIX_EXP_DECL extern # define PCREPOSIX_EXP_DEFN extern # endif #endif /* The functions */ PCREPOSIX_EXP_DECL int regcomp(regex_t *, const char *, int); PCREPOSIX_EXP_DECL int regexec(const regex_t *, const char *, size_t, regmatch_t *, int); PCREPOSIX_EXP_DECL size_t regerror(int, const regex_t *, char *, size_t); PCREPOSIX_EXP_DECL void regfree(regex_t *); #ifdef __cplusplus } /* extern "C" */ #endif #endif /* End of pcreposix.h */ libsynthesis-3.4.0.47.1/src/pcre/pcretest.c000066400000000000000000002073331226375725500203710ustar00rootroot00000000000000/************************************************* * PCRE testing program * *************************************************/ /* This program was hacked up as a tester for PCRE. I really should have written it more tidily in the first place. Will I ever learn? It has grown and been extended and consequently is now rather, er, *very* untidy in places. ----------------------------------------------------------------------------- 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 name of the University of Cambridge 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. ----------------------------------------------------------------------------- */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include /* A number of things vary for Windows builds. Originally, pcretest opened its input and output without "b"; then I was told that "b" was needed in some environments, so it was added for release 5.0 to both the input and output. (It makes no difference on Unix-like systems.) Later I was told that it is wrong for the input on Windows. I've now abstracted the modes into two macros that are set here, to make it easier to fiddle with them, and removed "b" from the input mode under Windows. */ #if defined(_WIN32) || defined(WIN32) #include /* For _setmode() */ #include /* For _O_BINARY */ #define INPUT_MODE "r" #define OUTPUT_MODE "wb" #else #include /* These two includes are needed */ #include /* for setrlimit(). */ #define INPUT_MODE "rb" #define OUTPUT_MODE "wb" #endif /* We have to include pcre_internal.h because we need the internal info for displaying the results of pcre_study() and we also need to know about the internal macros, structures, and other internal data values; pcretest has "inside information" compared to a program that strictly follows the PCRE API. Although pcre_internal.h does itself include pcre.h, we explicitly include it here before pcre_internal.h so that the PCRE_EXP_xxx macros get set appropriately for an application, not for building PCRE. */ #include "pcre.h" #include "pcre_internal.h" /* We need access to the data tables that PCRE uses. So as not to have to keep two copies, we include the source file here, changing the names of the external symbols to prevent clashes. */ #define _pcre_utf8_table1 utf8_table1 #define _pcre_utf8_table1_size utf8_table1_size #define _pcre_utf8_table2 utf8_table2 #define _pcre_utf8_table3 utf8_table3 #define _pcre_utf8_table4 utf8_table4 #define _pcre_utt utt #define _pcre_utt_size utt_size #define _pcre_OP_lengths OP_lengths #include "pcre_tables.c" /* We also need the pcre_printint() function for printing out compiled patterns. This function is in a separate file so that it can be included in pcre_compile.c when that module is compiled with debugging enabled. The definition of the macro PRINTABLE, which determines whether to print an output character as-is or as a hex value when showing compiled patterns, is contained in this file. We uses it here also, in cases when the locale has not been explicitly changed, so as to get consistent output from systems that differ in their output from isprint() even in the "C" locale. */ #include "pcre_printint.src" #define PRINTHEX(c) (locale_set? isprint(c) : PRINTABLE(c)) /* It is possible to compile this test program without including support for testing the POSIX interface, though this is not available via the standard Makefile. */ #if !defined NOPOSIX #include "pcreposix.h" #endif /* It is also possible, for the benefit of the version currently imported into Exim, to build pcretest without support for UTF8 (define NOUTF8), without the interface to the DFA matcher (NODFA), and without the doublecheck of the old "info" function (define NOINFOCHECK). In fact, we automatically cut out the UTF8 support if PCRE is built without it. */ #ifndef SUPPORT_UTF8 #ifndef NOUTF8 #define NOUTF8 #endif #endif /* Other parameters */ #ifndef CLOCKS_PER_SEC #ifdef CLK_TCK #define CLOCKS_PER_SEC CLK_TCK #else #define CLOCKS_PER_SEC 100 #endif #endif /* This is the default loop count for timing. */ #define LOOPREPEAT 500000 /* Static variables */ static FILE *outfile; static int log_store = 0; static int callout_count; static int callout_extra; static int callout_fail_count; static int callout_fail_id; static int debug_lengths; static int first_callout; static int locale_set = 0; static int show_malloc; static int use_utf8; static size_t gotten_store; /* The buffers grow automatically if very long input lines are encountered. */ static int buffer_size = 50000; static uschar *buffer = NULL; static uschar *dbuffer = NULL; static uschar *pbuffer = NULL; /************************************************* * Read or extend an input line * *************************************************/ /* Input lines are read into buffer, but both patterns and data lines can be continued over multiple input lines. In addition, if the buffer fills up, we want to automatically expand it so as to be able to handle extremely large lines that are needed for certain stress tests. When the input buffer is expanded, the other two buffers must also be expanded likewise, and the contents of pbuffer, which are a copy of the input for callouts, must be preserved (for when expansion happens for a data line). This is not the most optimal way of handling this, but hey, this is just a test program! Arguments: f the file to read start where in buffer to start (this *must* be within buffer) Returns: pointer to the start of new data could be a copy of start, or could be moved NULL if no data read and EOF reached */ static uschar * extend_inputline(FILE *f, uschar *start) { uschar *here = start; for (;;) { int rlen = buffer_size - (here - buffer); if (rlen > 1000) { int dlen; if (fgets((char *)here, rlen, f) == NULL) return (here == start)? NULL : start; dlen = (int)strlen((char *)here); if (dlen > 0 && here[dlen - 1] == '\n') return start; here += dlen; } else { int new_buffer_size = 2*buffer_size; uschar *new_buffer = (unsigned char *)malloc(new_buffer_size); uschar *new_dbuffer = (unsigned char *)malloc(new_buffer_size); uschar *new_pbuffer = (unsigned char *)malloc(new_buffer_size); if (new_buffer == NULL || new_dbuffer == NULL || new_pbuffer == NULL) { fprintf(stderr, "pcretest: malloc(%d) failed\n", new_buffer_size); exit(1); } memcpy(new_buffer, buffer, buffer_size); memcpy(new_pbuffer, pbuffer, buffer_size); buffer_size = new_buffer_size; start = new_buffer + (start - buffer); here = new_buffer + (here - buffer); free(buffer); free(dbuffer); free(pbuffer); buffer = new_buffer; dbuffer = new_dbuffer; pbuffer = new_pbuffer; } } return NULL; /* Control never gets here */ } /************************************************* * Read number from string * *************************************************/ /* We don't use strtoul() because SunOS4 doesn't have it. Rather than mess around with conditional compilation, just do the job by hand. It is only used for unpicking arguments, so just keep it simple. Arguments: str string to be converted endptr where to put the end pointer Returns: the unsigned long */ static int get_value(unsigned char *str, unsigned char **endptr) { int result = 0; while(*str != 0 && isspace(*str)) str++; while (isdigit(*str)) result = result * 10 + (int)(*str++ - '0'); *endptr = str; return(result); } /************************************************* * Convert UTF-8 string to value * *************************************************/ /* This function takes one or more bytes that represents a UTF-8 character, and returns the value of the character. Argument: utf8bytes a pointer to the byte vector vptr a pointer to an int to receive the value Returns: > 0 => the number of bytes consumed -6 to 0 => malformed UTF-8 character at offset = (-return) */ #if !defined NOUTF8 static int utf82ord(unsigned char *utf8bytes, int *vptr) { int c = *utf8bytes++; int d = c; int i, j, s; for (i = -1; i < 6; i++) /* i is number of additional bytes */ { if ((d & 0x80) == 0) break; d <<= 1; } if (i == -1) { *vptr = c; return 1; } /* ascii character */ if (i == 0 || i == 6) return 0; /* invalid UTF-8 */ /* i now has a value in the range 1-5 */ s = 6*i; d = (c & utf8_table3[i]) << s; for (j = 0; j < i; j++) { c = *utf8bytes++; if ((c & 0xc0) != 0x80) return -(j+1); s -= 6; d |= (c & 0x3f) << s; } /* Check that encoding was the correct unique one */ for (j = 0; j < utf8_table1_size; j++) if (d <= utf8_table1[j]) break; if (j != i) return -(i+1); /* Valid value */ *vptr = d; return i+1; } #endif /************************************************* * Convert character value to UTF-8 * *************************************************/ /* This function takes an integer value in the range 0 - 0x7fffffff and encodes it as a UTF-8 character in 0 to 6 bytes. Arguments: cvalue the character value utf8bytes pointer to buffer for result - at least 6 bytes long Returns: number of characters placed in the buffer */ #if !defined NOUTF8 static int ord2utf8(int cvalue, uschar *utf8bytes) { register int i, j; for (i = 0; i < utf8_table1_size; i++) if (cvalue <= utf8_table1[i]) break; utf8bytes += i; for (j = i; j > 0; j--) { *utf8bytes-- = 0x80 | (cvalue & 0x3f); cvalue >>= 6; } *utf8bytes = utf8_table2[i] | cvalue; return i + 1; } #endif /************************************************* * Print character string * *************************************************/ /* Character string printing function. Must handle UTF-8 strings in utf8 mode. Yields number of characters printed. If handed a NULL file, just counts chars without printing. */ static int pchars(unsigned char *p, int length, FILE *f) { int c = 0; int yield = 0; while (length-- > 0) { #if !defined NOUTF8 if (use_utf8) { int rc = utf82ord(p, &c); if (rc > 0 && rc <= length + 1) /* Mustn't run over the end */ { length -= rc - 1; p += rc; if (PRINTHEX(c)) { if (f != NULL) fprintf(f, "%c", c); yield++; } else { int n = 4; if (f != NULL) fprintf(f, "\\x{%02x}", c); yield += (n <= 0x000000ff)? 2 : (n <= 0x00000fff)? 3 : (n <= 0x0000ffff)? 4 : (n <= 0x000fffff)? 5 : 6; } continue; } } #endif /* Not UTF-8, or malformed UTF-8 */ c = *p++; if (PRINTHEX(c)) { if (f != NULL) fprintf(f, "%c", c); yield++; } else { if (f != NULL) fprintf(f, "\\x%02x", c); yield += 4; } } return yield; } /************************************************* * Callout function * *************************************************/ /* Called from PCRE as a result of the (?C) item. We print out where we are in the match. Yield zero unless more callouts than the fail count, or the callout data is not zero. */ static int callout(pcre_callout_block *cb) { FILE *f = (first_callout | callout_extra)? outfile : NULL; int i, pre_start, post_start, subject_length; if (callout_extra) { fprintf(f, "Callout %d: last capture = %d\n", cb->callout_number, cb->capture_last); for (i = 0; i < cb->capture_top * 2; i += 2) { if (cb->offset_vector[i] < 0) fprintf(f, "%2d: \n", i/2); else { fprintf(f, "%2d: ", i/2); (void)pchars((unsigned char *)cb->subject + cb->offset_vector[i], cb->offset_vector[i+1] - cb->offset_vector[i], f); fprintf(f, "\n"); } } } /* Re-print the subject in canonical form, the first time or if giving full datails. On subsequent calls in the same match, we use pchars just to find the printed lengths of the substrings. */ if (f != NULL) fprintf(f, "--->"); pre_start = pchars((unsigned char *)cb->subject, cb->start_match, f); post_start = pchars((unsigned char *)(cb->subject + cb->start_match), cb->current_position - cb->start_match, f); subject_length = pchars((unsigned char *)cb->subject, cb->subject_length, NULL); (void)pchars((unsigned char *)(cb->subject + cb->current_position), cb->subject_length - cb->current_position, f); if (f != NULL) fprintf(f, "\n"); /* Always print appropriate indicators, with callout number if not already shown. For automatic callouts, show the pattern offset. */ if (cb->callout_number == 255) { fprintf(outfile, "%+3d ", cb->pattern_position); if (cb->pattern_position > 99) fprintf(outfile, "\n "); } else { if (callout_extra) fprintf(outfile, " "); else fprintf(outfile, "%3d ", cb->callout_number); } for (i = 0; i < pre_start; i++) fprintf(outfile, " "); fprintf(outfile, "^"); if (post_start > 0) { for (i = 0; i < post_start - 1; i++) fprintf(outfile, " "); fprintf(outfile, "^"); } for (i = 0; i < subject_length - pre_start - post_start + 4; i++) fprintf(outfile, " "); fprintf(outfile, "%.*s", (cb->next_item_length == 0)? 1 : cb->next_item_length, pbuffer + cb->pattern_position); fprintf(outfile, "\n"); first_callout = 0; if (cb->callout_data != NULL) { int callout_data = *((int *)(cb->callout_data)); if (callout_data != 0) { fprintf(outfile, "Callout data = %d\n", callout_data); return callout_data; } } return (cb->callout_number != callout_fail_id)? 0 : (++callout_count >= callout_fail_count)? 1 : 0; } /************************************************* * Local malloc functions * *************************************************/ /* Alternative malloc function, to test functionality and show the size of the compiled re. */ static void *new_malloc(size_t size) { void *block = malloc(size); gotten_store = size; if (show_malloc) fprintf(outfile, "malloc %3d %p\n", (int)size, block); return block; } static void new_free(void *block) { if (show_malloc) fprintf(outfile, "free %p\n", block); free(block); } /* For recursion malloc/free, to test stacking calls */ static void *stack_malloc(size_t size) { void *block = malloc(size); if (show_malloc) fprintf(outfile, "stack_malloc %3d %p\n", (int)size, block); return block; } static void stack_free(void *block) { if (show_malloc) fprintf(outfile, "stack_free %p\n", block); free(block); } /************************************************* * Call pcre_fullinfo() * *************************************************/ /* Get one piece of information from the pcre_fullinfo() function */ static void new_info(pcre *re, pcre_extra *study, int option, void *ptr) { int rc; if ((rc = pcre_fullinfo(re, study, option, ptr)) < 0) fprintf(outfile, "Error %d from pcre_fullinfo(%d)\n", rc, option); } /************************************************* * Byte flipping function * *************************************************/ static unsigned long int byteflip(unsigned long int value, int n) { if (n == 2) return ((value & 0x00ff) << 8) | ((value & 0xff00) >> 8); return ((value & 0x000000ff) << 24) | ((value & 0x0000ff00) << 8) | ((value & 0x00ff0000) >> 8) | ((value & 0xff000000) >> 24); } /************************************************* * Check match or recursion limit * *************************************************/ static int check_match_limit(pcre *re, pcre_extra *extra, uschar *bptr, int len, int start_offset, int options, int *use_offsets, int use_size_offsets, int flag, unsigned long int *limit, int errnumber, const char *msg) { int count; int min = 0; int mid = 64; int max = -1; extra->flags |= flag; for (;;) { *limit = mid; count = pcre_exec(re, extra, (char *)bptr, len, start_offset, options, use_offsets, use_size_offsets); if (count == errnumber) { /* fprintf(outfile, "Testing %s limit = %d\n", msg, mid); */ min = mid; mid = (mid == max - 1)? max : (max > 0)? (min + max)/2 : mid*2; } else if (count >= 0 || count == PCRE_ERROR_NOMATCH || count == PCRE_ERROR_PARTIAL) { if (mid == min + 1) { fprintf(outfile, "Minimum %s limit = %d\n", msg, mid); break; } /* fprintf(outfile, "Testing %s limit = %d\n", msg, mid); */ max = mid; mid = (min + mid)/2; } else break; /* Some other error */ } extra->flags &= ~flag; return count; } /************************************************* * Case-independent strncmp() function * *************************************************/ /* Arguments: s first string t second string n number of characters to compare Returns: < 0, = 0, or > 0, according to the comparison */ static int strncmpic(uschar *s, uschar *t, int n) { while (n--) { int c = tolower(*s++) - tolower(*t++); if (c) return c; } return 0; } /************************************************* * Check newline indicator * *************************************************/ /* This is used both at compile and run-time to check for escapes, where xxx is LF, CR, CRLF, ANYCRLF, or ANY. Print a message and return 0 if there is no match. Arguments: p points after the leading '<' f file for error message Returns: appropriate PCRE_NEWLINE_xxx flags, or 0 */ static int check_newline(uschar *p, FILE *f) { if (strncmpic(p, (uschar *)"cr>", 3) == 0) return PCRE_NEWLINE_CR; if (strncmpic(p, (uschar *)"lf>", 3) == 0) return PCRE_NEWLINE_LF; if (strncmpic(p, (uschar *)"crlf>", 5) == 0) return PCRE_NEWLINE_CRLF; if (strncmpic(p, (uschar *)"anycrlf>", 8) == 0) return PCRE_NEWLINE_ANYCRLF; if (strncmpic(p, (uschar *)"any>", 4) == 0) return PCRE_NEWLINE_ANY; fprintf(f, "Unknown newline type at: <%s\n", p); return 0; } /************************************************* * Usage function * *************************************************/ static void usage(void) { printf("Usage: pcretest [options] [ []]\n"); printf(" -b show compiled code (bytecode)\n"); printf(" -C show PCRE compile-time options and exit\n"); printf(" -d debug: show compiled code and information (-b and -i)\n"); #if !defined NODFA printf(" -dfa force DFA matching for all subjects\n"); #endif printf(" -help show usage information\n"); printf(" -i show information about compiled patterns\n" " -m output memory used information\n" " -o set size of offsets vector to \n"); #if !defined NOPOSIX printf(" -p use POSIX interface\n"); #endif printf(" -q quiet: do not output PCRE version number at start\n"); printf(" -S set stack size to megabytes\n"); printf(" -s output store (memory) used information\n" " -t time compilation and execution\n"); printf(" -t time compilation and execution, repeating times\n"); printf(" -tm time execution (matching) only\n"); printf(" -tm time execution (matching) only, repeating times\n"); } /************************************************* * Main Program * *************************************************/ /* Read lines from named file or stdin and write to named file or stdout; lines consist of a regular expression, in delimiters and optionally followed by options, followed by a set of test data, terminated by an empty line. */ int main(int argc, char **argv) { FILE *infile = stdin; int options = 0; int study_options = 0; int op = 1; int timeit = 0; int timeitm = 0; int showinfo = 0; int showstore = 0; int quiet = 0; int size_offsets = 45; int size_offsets_max; int *offsets = NULL; #if !defined NOPOSIX int posix = 0; #endif int debug = 0; int done = 0; int all_use_dfa = 0; int yield = 0; int stack_size; /* These vectors store, end-to-end, a list of captured substring names. Assume that 1024 is plenty long enough for the few names we'll be testing. */ uschar copynames[1024]; uschar getnames[1024]; uschar *copynamesptr; uschar *getnamesptr; /* Get buffers from malloc() so that Electric Fence will check their misuse when I am debugging. They grow automatically when very long lines are read. */ buffer = (unsigned char *)malloc(buffer_size); dbuffer = (unsigned char *)malloc(buffer_size); pbuffer = (unsigned char *)malloc(buffer_size); /* The outfile variable is static so that new_malloc can use it. */ outfile = stdout; /* The following _setmode() stuff is some Windows magic that tells its runtime library to translate CRLF into a single LF character. At least, that's what I've been told: never having used Windows I take this all on trust. Originally it set 0x8000, but then I was advised that _O_BINARY was better. */ #if defined(_WIN32) || defined(WIN32) _setmode( _fileno( stdout ), _O_BINARY ); #endif /* Scan options */ while (argc > 1 && argv[op][0] == '-') { unsigned char *endptr; if (strcmp(argv[op], "-s") == 0 || strcmp(argv[op], "-m") == 0) showstore = 1; else if (strcmp(argv[op], "-q") == 0) quiet = 1; else if (strcmp(argv[op], "-b") == 0) debug = 1; else if (strcmp(argv[op], "-i") == 0) showinfo = 1; else if (strcmp(argv[op], "-d") == 0) showinfo = debug = 1; #if !defined NODFA else if (strcmp(argv[op], "-dfa") == 0) all_use_dfa = 1; #endif else if (strcmp(argv[op], "-o") == 0 && argc > 2 && ((size_offsets = get_value((unsigned char *)argv[op+1], &endptr)), *endptr == 0)) { op++; argc--; } else if (strcmp(argv[op], "-t") == 0 || strcmp(argv[op], "-tm") == 0) { int both = argv[op][2] == 0; int temp; if (argc > 2 && (temp = get_value((unsigned char *)argv[op+1], &endptr), *endptr == 0)) { timeitm = temp; op++; argc--; } else timeitm = LOOPREPEAT; if (both) timeit = timeitm; } else if (strcmp(argv[op], "-S") == 0 && argc > 2 && ((stack_size = get_value((unsigned char *)argv[op+1], &endptr)), *endptr == 0)) { #if defined(_WIN32) || defined(WIN32) printf("PCRE: -S not supported on this OS\n"); exit(1); #else int rc; struct rlimit rlim; getrlimit(RLIMIT_STACK, &rlim); rlim.rlim_cur = stack_size * 1024 * 1024; rc = setrlimit(RLIMIT_STACK, &rlim); if (rc != 0) { printf("PCRE: setrlimit() failed with error %d\n", rc); exit(1); } op++; argc--; #endif } #if !defined NOPOSIX else if (strcmp(argv[op], "-p") == 0) posix = 1; #endif else if (strcmp(argv[op], "-C") == 0) { int rc; printf("PCRE version %s\n", pcre_version()); printf("Compiled with\n"); (void)pcre_config(PCRE_CONFIG_UTF8, &rc); printf(" %sUTF-8 support\n", rc? "" : "No "); (void)pcre_config(PCRE_CONFIG_UNICODE_PROPERTIES, &rc); printf(" %sUnicode properties support\n", rc? "" : "No "); (void)pcre_config(PCRE_CONFIG_NEWLINE, &rc); printf(" Newline sequence is %s\n", (rc == '\r')? "CR" : (rc == '\n')? "LF" : (rc == ('\r'<<8 | '\n'))? "CRLF" : (rc == -2)? "ANYCRLF" : (rc == -1)? "ANY" : "???"); (void)pcre_config(PCRE_CONFIG_LINK_SIZE, &rc); printf(" Internal link size = %d\n", rc); (void)pcre_config(PCRE_CONFIG_POSIX_MALLOC_THRESHOLD, &rc); printf(" POSIX malloc threshold = %d\n", rc); (void)pcre_config(PCRE_CONFIG_MATCH_LIMIT, &rc); printf(" Default match limit = %d\n", rc); (void)pcre_config(PCRE_CONFIG_MATCH_LIMIT_RECURSION, &rc); printf(" Default recursion depth limit = %d\n", rc); (void)pcre_config(PCRE_CONFIG_STACKRECURSE, &rc); printf(" Match recursion uses %s\n", rc? "stack" : "heap"); goto EXIT; } else if (strcmp(argv[op], "-help") == 0 || strcmp(argv[op], "--help") == 0) { usage(); goto EXIT; } else { printf("** Unknown or malformed option %s\n", argv[op]); usage(); yield = 1; goto EXIT; } op++; argc--; } /* Get the store for the offsets vector, and remember what it was */ size_offsets_max = size_offsets; offsets = (int *)malloc(size_offsets_max * sizeof(int)); if (offsets == NULL) { printf("** Failed to get %d bytes of memory for offsets vector\n", (int)(size_offsets_max * sizeof(int))); yield = 1; goto EXIT; } /* Sort out the input and output files */ if (argc > 1) { infile = fopen(argv[op], INPUT_MODE); if (infile == NULL) { printf("** Failed to open %s\n", argv[op]); yield = 1; goto EXIT; } } if (argc > 2) { outfile = fopen(argv[op+1], OUTPUT_MODE); if (outfile == NULL) { printf("** Failed to open %s\n", argv[op+1]); yield = 1; goto EXIT; } } /* Set alternative malloc function */ pcre_malloc = new_malloc; pcre_free = new_free; pcre_stack_malloc = stack_malloc; pcre_stack_free = stack_free; /* Heading line unless quiet, then prompt for first regex if stdin */ if (!quiet) fprintf(outfile, "PCRE version %s\n\n", pcre_version()); /* Main loop */ while (!done) { pcre *re = NULL; pcre_extra *extra = NULL; #if !defined NOPOSIX /* There are still compilers that require no indent */ regex_t preg; int do_posix = 0; #endif const char *error; unsigned char *p, *pp, *ppp; unsigned char *to_file = NULL; const unsigned char *tables = NULL; unsigned long int true_size, true_study_size = 0; size_t size, regex_gotten_store; int do_study = 0; int do_debug = debug; int do_G = 0; int do_g = 0; int do_showinfo = showinfo; int do_showrest = 0; int do_flip = 0; int erroroffset, len, delimiter, poffset; use_utf8 = 0; debug_lengths = 1; if (infile == stdin) printf(" re> "); if (extend_inputline(infile, buffer) == NULL) break; if (infile != stdin) fprintf(outfile, "%s", (char *)buffer); fflush(outfile); p = buffer; while (isspace(*p)) p++; if (*p == 0) continue; /* See if the pattern is to be loaded pre-compiled from a file. */ if (*p == '<' && strchr((char *)(p+1), '<') == NULL) { unsigned long int magic, get_options; uschar sbuf[8]; FILE *f; p++; pp = p + (int)strlen((char *)p); while (isspace(pp[-1])) pp--; *pp = 0; f = fopen((char *)p, "rb"); if (f == NULL) { fprintf(outfile, "Failed to open %s: %s\n", p, strerror(errno)); continue; } if (fread(sbuf, 1, 8, f) != 8) goto FAIL_READ; true_size = (sbuf[0] << 24) | (sbuf[1] << 16) | (sbuf[2] << 8) | sbuf[3]; true_study_size = (sbuf[4] << 24) | (sbuf[5] << 16) | (sbuf[6] << 8) | sbuf[7]; re = (real_pcre *)new_malloc(true_size); regex_gotten_store = gotten_store; if (fread(re, 1, true_size, f) != true_size) goto FAIL_READ; magic = ((real_pcre *)re)->magic_number; if (magic != MAGIC_NUMBER) { if (byteflip(magic, sizeof(magic)) == MAGIC_NUMBER) { do_flip = 1; } else { fprintf(outfile, "Data in %s is not a compiled PCRE regex\n", p); fclose(f); continue; } } fprintf(outfile, "Compiled regex%s loaded from %s\n", do_flip? " (byte-inverted)" : "", p); /* Need to know if UTF-8 for printing data strings */ new_info(re, NULL, PCRE_INFO_OPTIONS, &get_options); use_utf8 = (get_options & PCRE_UTF8) != 0; /* Now see if there is any following study data */ if (true_study_size != 0) { pcre_study_data *psd; extra = (pcre_extra *)new_malloc(sizeof(pcre_extra) + true_study_size); extra->flags = PCRE_EXTRA_STUDY_DATA; psd = (pcre_study_data *)(((char *)extra) + sizeof(pcre_extra)); extra->study_data = psd; if (fread(psd, 1, true_study_size, f) != true_study_size) { FAIL_READ: fprintf(outfile, "Failed to read data from %s\n", p); if (extra != NULL) new_free(extra); if (re != NULL) new_free(re); fclose(f); continue; } fprintf(outfile, "Study data loaded from %s\n", p); do_study = 1; /* To get the data output if requested */ } else fprintf(outfile, "No study data\n"); fclose(f); goto SHOW_INFO; } /* In-line pattern (the usual case). Get the delimiter and seek the end of the pattern; if is isn't complete, read more. */ delimiter = *p++; if (isalnum(delimiter) || delimiter == '\\') { fprintf(outfile, "** Delimiter must not be alphameric or \\\n"); goto SKIP_DATA; } pp = p; poffset = p - buffer; for(;;) { while (*pp != 0) { if (*pp == '\\' && pp[1] != 0) pp++; else if (*pp == delimiter) break; pp++; } if (*pp != 0) break; if (infile == stdin) printf(" > "); if ((pp = extend_inputline(infile, pp)) == NULL) { fprintf(outfile, "** Unexpected EOF\n"); done = 1; goto CONTINUE; } if (infile != stdin) fprintf(outfile, "%s", (char *)pp); } /* The buffer may have moved while being extended; reset the start of data pointer to the correct relative point in the buffer. */ p = buffer + poffset; /* If the first character after the delimiter is backslash, make the pattern end with backslash. This is purely to provide a way of testing for the error message when a pattern ends with backslash. */ if (pp[1] == '\\') *pp++ = '\\'; /* Terminate the pattern at the delimiter, and save a copy of the pattern for callouts. */ *pp++ = 0; strcpy((char *)pbuffer, (char *)p); /* Look for options after final delimiter */ options = 0; study_options = 0; log_store = showstore; /* default from command line */ while (*pp != 0) { switch (*pp++) { case 'f': options |= PCRE_FIRSTLINE; break; case 'g': do_g = 1; break; case 'i': options |= PCRE_CASELESS; break; case 'm': options |= PCRE_MULTILINE; break; case 's': options |= PCRE_DOTALL; break; case 'x': options |= PCRE_EXTENDED; break; case '+': do_showrest = 1; break; case 'A': options |= PCRE_ANCHORED; break; case 'B': do_debug = 1; break; case 'C': options |= PCRE_AUTO_CALLOUT; break; case 'D': do_debug = do_showinfo = 1; break; case 'E': options |= PCRE_DOLLAR_ENDONLY; break; case 'F': do_flip = 1; break; case 'G': do_G = 1; break; case 'I': do_showinfo = 1; break; case 'J': options |= PCRE_DUPNAMES; break; case 'M': log_store = 1; break; case 'N': options |= PCRE_NO_AUTO_CAPTURE; break; #if !defined NOPOSIX case 'P': do_posix = 1; break; #endif case 'S': do_study = 1; break; case 'U': options |= PCRE_UNGREEDY; break; case 'X': options |= PCRE_EXTRA; break; case 'Z': debug_lengths = 0; break; case '8': options |= PCRE_UTF8; use_utf8 = 1; break; case '?': options |= PCRE_NO_UTF8_CHECK; break; case 'L': ppp = pp; /* The '\r' test here is so that it works on Windows. */ /* The '0' test is just in case this is an unterminated line. */ while (*ppp != 0 && *ppp != '\n' && *ppp != '\r' && *ppp != ' ') ppp++; *ppp = 0; if (setlocale(LC_CTYPE, (const char *)pp) == NULL) { fprintf(outfile, "** Failed to set locale \"%s\"\n", pp); goto SKIP_DATA; } locale_set = 1; tables = pcre_maketables(); pp = ppp; break; case '>': to_file = pp; while (*pp != 0) pp++; while (isspace(pp[-1])) pp--; *pp = 0; break; case '<': { int x = check_newline(pp, outfile); if (x == 0) goto SKIP_DATA; options |= x; while (*pp++ != '>'); } break; case '\r': /* So that it works in Windows */ case '\n': case ' ': break; default: fprintf(outfile, "** Unknown option '%c'\n", pp[-1]); goto SKIP_DATA; } } /* Handle compiling via the POSIX interface, which doesn't support the timing, showing, or debugging options, nor the ability to pass over local character tables. */ #if !defined NOPOSIX if (posix || do_posix) { int rc; int cflags = 0; if ((options & PCRE_CASELESS) != 0) cflags |= REG_ICASE; if ((options & PCRE_MULTILINE) != 0) cflags |= REG_NEWLINE; if ((options & PCRE_DOTALL) != 0) cflags |= REG_DOTALL; if ((options & PCRE_NO_AUTO_CAPTURE) != 0) cflags |= REG_NOSUB; if ((options & PCRE_UTF8) != 0) cflags |= REG_UTF8; rc = regcomp(&preg, (char *)p, cflags); /* Compilation failed; go back for another re, skipping to blank line if non-interactive. */ if (rc != 0) { (void)regerror(rc, &preg, (char *)buffer, buffer_size); fprintf(outfile, "Failed: POSIX code %d: %s\n", rc, buffer); goto SKIP_DATA; } } /* Handle compiling via the native interface */ else #endif /* !defined NOPOSIX */ { if (timeit > 0) { register int i; clock_t time_taken; clock_t start_time = clock(); for (i = 0; i < timeit; i++) { re = pcre_compile((char *)p, options, &error, &erroroffset, tables); if (re != NULL) free(re); } time_taken = clock() - start_time; fprintf(outfile, "Compile time %.4f milliseconds\n", (((double)time_taken * 1000.0) / (double)timeit) / (double)CLOCKS_PER_SEC); } re = pcre_compile((char *)p, options, &error, &erroroffset, tables); /* Compilation failed; go back for another re, skipping to blank line if non-interactive. */ if (re == NULL) { fprintf(outfile, "Failed: %s at offset %d\n", error, erroroffset); SKIP_DATA: if (infile != stdin) { for (;;) { if (extend_inputline(infile, buffer) == NULL) { done = 1; goto CONTINUE; } len = (int)strlen((char *)buffer); while (len > 0 && isspace(buffer[len-1])) len--; if (len == 0) break; } fprintf(outfile, "\n"); } goto CONTINUE; } /* Compilation succeeded; print data if required. There are now two info-returning functions. The old one has a limited interface and returns only limited data. Check that it agrees with the newer one. */ if (log_store) fprintf(outfile, "Memory allocation (code space): %d\n", (int)(gotten_store - sizeof(real_pcre) - ((real_pcre *)re)->name_count * ((real_pcre *)re)->name_entry_size)); /* Extract the size for possible writing before possibly flipping it, and remember the store that was got. */ true_size = ((real_pcre *)re)->size; regex_gotten_store = gotten_store; /* If /S was present, study the regexp to generate additional info to help with the matching. */ if (do_study) { if (timeit > 0) { register int i; clock_t time_taken; clock_t start_time = clock(); for (i = 0; i < timeit; i++) extra = pcre_study(re, study_options, &error); time_taken = clock() - start_time; if (extra != NULL) free(extra); fprintf(outfile, " Study time %.4f milliseconds\n", (((double)time_taken * 1000.0) / (double)timeit) / (double)CLOCKS_PER_SEC); } extra = pcre_study(re, study_options, &error); if (error != NULL) fprintf(outfile, "Failed to study: %s\n", error); else if (extra != NULL) true_study_size = ((pcre_study_data *)(extra->study_data))->size; } /* If the 'F' option was present, we flip the bytes of all the integer fields in the regex data block and the study block. This is to make it possible to test PCRE's handling of byte-flipped patterns, e.g. those compiled on a different architecture. */ if (do_flip) { real_pcre *rre = (real_pcre *)re; rre->magic_number = byteflip(rre->magic_number, sizeof(rre->magic_number)); rre->size = byteflip(rre->size, sizeof(rre->size)); rre->options = byteflip(rre->options, sizeof(rre->options)); rre->top_bracket = byteflip(rre->top_bracket, sizeof(rre->top_bracket)); rre->top_backref = byteflip(rre->top_backref, sizeof(rre->top_backref)); rre->first_byte = byteflip(rre->first_byte, sizeof(rre->first_byte)); rre->req_byte = byteflip(rre->req_byte, sizeof(rre->req_byte)); rre->name_table_offset = byteflip(rre->name_table_offset, sizeof(rre->name_table_offset)); rre->name_entry_size = byteflip(rre->name_entry_size, sizeof(rre->name_entry_size)); rre->name_count = byteflip(rre->name_count, sizeof(rre->name_count)); if (extra != NULL) { pcre_study_data *rsd = (pcre_study_data *)(extra->study_data); rsd->size = byteflip(rsd->size, sizeof(rsd->size)); rsd->options = byteflip(rsd->options, sizeof(rsd->options)); } } /* Extract information from the compiled data if required */ SHOW_INFO: if (do_debug) { fprintf(outfile, "------------------------------------------------------------------\n"); pcre_printint(re, outfile, debug_lengths); } if (do_showinfo) { unsigned long int get_options, all_options; #if !defined NOINFOCHECK int old_first_char, old_options, old_count; #endif int count, backrefmax, first_char, need_char, okpartial, jchanged, hascrorlf; int nameentrysize, namecount; const uschar *nametable; new_info(re, NULL, PCRE_INFO_OPTIONS, &get_options); new_info(re, NULL, PCRE_INFO_SIZE, &size); new_info(re, NULL, PCRE_INFO_CAPTURECOUNT, &count); new_info(re, NULL, PCRE_INFO_BACKREFMAX, &backrefmax); new_info(re, NULL, PCRE_INFO_FIRSTBYTE, &first_char); new_info(re, NULL, PCRE_INFO_LASTLITERAL, &need_char); new_info(re, NULL, PCRE_INFO_NAMEENTRYSIZE, &nameentrysize); new_info(re, NULL, PCRE_INFO_NAMECOUNT, &namecount); new_info(re, NULL, PCRE_INFO_NAMETABLE, (void *)&nametable); new_info(re, NULL, PCRE_INFO_OKPARTIAL, &okpartial); new_info(re, NULL, PCRE_INFO_JCHANGED, &jchanged); new_info(re, NULL, PCRE_INFO_HASCRORLF, &hascrorlf); #if !defined NOINFOCHECK old_count = pcre_info(re, &old_options, &old_first_char); if (count < 0) fprintf(outfile, "Error %d from pcre_info()\n", count); else { if (old_count != count) fprintf(outfile, "Count disagreement: pcre_fullinfo=%d pcre_info=%d\n", count, old_count); if (old_first_char != first_char) fprintf(outfile, "First char disagreement: pcre_fullinfo=%d pcre_info=%d\n", first_char, old_first_char); if (old_options != (int)get_options) fprintf(outfile, "Options disagreement: pcre_fullinfo=%ld pcre_info=%d\n", get_options, old_options); } #endif if (size != regex_gotten_store) fprintf(outfile, "Size disagreement: pcre_fullinfo=%d call to malloc for %d\n", (int)size, (int)regex_gotten_store); fprintf(outfile, "Capturing subpattern count = %d\n", count); if (backrefmax > 0) fprintf(outfile, "Max back reference = %d\n", backrefmax); if (namecount > 0) { fprintf(outfile, "Named capturing subpatterns:\n"); while (namecount-- > 0) { fprintf(outfile, " %s %*s%3d\n", nametable + 2, nameentrysize - 3 - (int)strlen((char *)nametable + 2), "", GET2(nametable, 0)); nametable += nameentrysize; } } if (!okpartial) fprintf(outfile, "Partial matching not supported\n"); if (hascrorlf) fprintf(outfile, "Contains explicit CR or LF match\n"); all_options = ((real_pcre *)re)->options; if (do_flip) all_options = byteflip(all_options, sizeof(all_options)); if (get_options == 0) fprintf(outfile, "No options\n"); else fprintf(outfile, "Options:%s%s%s%s%s%s%s%s%s%s%s%s%s\n", ((get_options & PCRE_ANCHORED) != 0)? " anchored" : "", ((get_options & PCRE_CASELESS) != 0)? " caseless" : "", ((get_options & PCRE_EXTENDED) != 0)? " extended" : "", ((get_options & PCRE_MULTILINE) != 0)? " multiline" : "", ((get_options & PCRE_FIRSTLINE) != 0)? " firstline" : "", ((get_options & PCRE_DOTALL) != 0)? " dotall" : "", ((get_options & PCRE_DOLLAR_ENDONLY) != 0)? " dollar_endonly" : "", ((get_options & PCRE_EXTRA) != 0)? " extra" : "", ((get_options & PCRE_UNGREEDY) != 0)? " ungreedy" : "", ((get_options & PCRE_NO_AUTO_CAPTURE) != 0)? " no_auto_capture" : "", ((get_options & PCRE_UTF8) != 0)? " utf8" : "", ((get_options & PCRE_NO_UTF8_CHECK) != 0)? " no_utf8_check" : "", ((get_options & PCRE_DUPNAMES) != 0)? " dupnames" : ""); if (jchanged) fprintf(outfile, "Duplicate name status changes\n"); switch (get_options & PCRE_NEWLINE_BITS) { case PCRE_NEWLINE_CR: fprintf(outfile, "Forced newline sequence: CR\n"); break; case PCRE_NEWLINE_LF: fprintf(outfile, "Forced newline sequence: LF\n"); break; case PCRE_NEWLINE_CRLF: fprintf(outfile, "Forced newline sequence: CRLF\n"); break; case PCRE_NEWLINE_ANYCRLF: fprintf(outfile, "Forced newline sequence: ANYCRLF\n"); break; case PCRE_NEWLINE_ANY: fprintf(outfile, "Forced newline sequence: ANY\n"); break; default: break; } if (first_char == -1) { fprintf(outfile, "First char at start or follows newline\n"); } else if (first_char < 0) { fprintf(outfile, "No first char\n"); } else { int ch = first_char & 255; const char *caseless = ((first_char & REQ_CASELESS) == 0)? "" : " (caseless)"; if (PRINTHEX(ch)) fprintf(outfile, "First char = \'%c\'%s\n", ch, caseless); else fprintf(outfile, "First char = %d%s\n", ch, caseless); } if (need_char < 0) { fprintf(outfile, "No need char\n"); } else { int ch = need_char & 255; const char *caseless = ((need_char & REQ_CASELESS) == 0)? "" : " (caseless)"; if (PRINTHEX(ch)) fprintf(outfile, "Need char = \'%c\'%s\n", ch, caseless); else fprintf(outfile, "Need char = %d%s\n", ch, caseless); } /* Don't output study size; at present it is in any case a fixed value, but it varies, depending on the computer architecture, and so messes up the test suite. (And with the /F option, it might be flipped.) */ if (do_study) { if (extra == NULL) fprintf(outfile, "Study returned NULL\n"); else { uschar *start_bits = NULL; new_info(re, extra, PCRE_INFO_FIRSTTABLE, &start_bits); if (start_bits == NULL) fprintf(outfile, "No starting byte set\n"); else { int i; int c = 24; fprintf(outfile, "Starting byte set: "); for (i = 0; i < 256; i++) { if ((start_bits[i/8] & (1<<(i&7))) != 0) { if (c > 75) { fprintf(outfile, "\n "); c = 2; } if (PRINTHEX(i) && i != ' ') { fprintf(outfile, "%c ", i); c += 2; } else { fprintf(outfile, "\\x%02x ", i); c += 5; } } } fprintf(outfile, "\n"); } } } } /* If the '>' option was present, we write out the regex to a file, and that is all. The first 8 bytes of the file are the regex length and then the study length, in big-endian order. */ if (to_file != NULL) { FILE *f = fopen((char *)to_file, "wb"); if (f == NULL) { fprintf(outfile, "Unable to open %s: %s\n", to_file, strerror(errno)); } else { uschar sbuf[8]; sbuf[0] = (true_size >> 24) & 255; sbuf[1] = (true_size >> 16) & 255; sbuf[2] = (true_size >> 8) & 255; sbuf[3] = (true_size) & 255; sbuf[4] = (true_study_size >> 24) & 255; sbuf[5] = (true_study_size >> 16) & 255; sbuf[6] = (true_study_size >> 8) & 255; sbuf[7] = (true_study_size) & 255; if (fwrite(sbuf, 1, 8, f) < 8 || fwrite(re, 1, true_size, f) < true_size) { fprintf(outfile, "Write error on %s: %s\n", to_file, strerror(errno)); } else { fprintf(outfile, "Compiled regex written to %s\n", to_file); if (extra != NULL) { if (fwrite(extra->study_data, 1, true_study_size, f) < true_study_size) { fprintf(outfile, "Write error on %s: %s\n", to_file, strerror(errno)); } else fprintf(outfile, "Study data written to %s\n", to_file); } } fclose(f); } new_free(re); if (extra != NULL) new_free(extra); if (tables != NULL) new_free((void *)tables); continue; /* With next regex */ } } /* End of non-POSIX compile */ /* Read data lines and test them */ for (;;) { uschar *q; uschar *bptr; int *use_offsets = offsets; int use_size_offsets = size_offsets; int callout_data = 0; int callout_data_set = 0; int count, c; int copystrings = 0; int find_match_limit = 0; int getstrings = 0; int getlist = 0; int gmatched = 0; int start_offset = 0; int g_notempty = 0; int use_dfa = 0; options = 0; *copynames = 0; *getnames = 0; copynamesptr = copynames; getnamesptr = getnames; pcre_callout = callout; first_callout = 1; callout_extra = 0; callout_count = 0; callout_fail_count = 999999; callout_fail_id = -1; show_malloc = 0; if (extra != NULL) extra->flags &= ~(PCRE_EXTRA_MATCH_LIMIT|PCRE_EXTRA_MATCH_LIMIT_RECURSION); len = 0; for (;;) { if (infile == stdin) printf("data> "); if (extend_inputline(infile, buffer + len) == NULL) { if (len > 0) break; done = 1; goto CONTINUE; } if (infile != stdin) fprintf(outfile, "%s", (char *)buffer); len = (int)strlen((char *)buffer); if (buffer[len-1] == '\n') break; } while (len > 0 && isspace(buffer[len-1])) len--; buffer[len] = 0; if (len == 0) break; p = buffer; while (isspace(*p)) p++; bptr = q = dbuffer; while ((c = *p++) != 0) { int i = 0; int n = 0; if (c == '\\') switch ((c = *p++)) { case 'a': c = 7; break; case 'b': c = '\b'; break; case 'e': c = 27; break; case 'f': c = '\f'; break; case 'n': c = '\n'; break; case 'r': c = '\r'; break; case 't': c = '\t'; break; case 'v': c = '\v'; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': c -= '0'; while (i++ < 2 && isdigit(*p) && *p != '8' && *p != '9') c = c * 8 + *p++ - '0'; #if !defined NOUTF8 if (use_utf8 && c > 255) { unsigned char buff8[8]; int ii, utn; utn = ord2utf8(c, buff8); for (ii = 0; ii < utn - 1; ii++) *q++ = buff8[ii]; c = buff8[ii]; /* Last byte */ } #endif break; case 'x': /* Handle \x{..} specially - new Perl thing for utf8 */ #if !defined NOUTF8 if (*p == '{') { unsigned char *pt = p; c = 0; while (isxdigit(*(++pt))) c = c * 16 + tolower(*pt) - ((isdigit(*pt))? '0' : 'W'); if (*pt == '}') { unsigned char buff8[8]; int ii, utn; utn = ord2utf8(c, buff8); for (ii = 0; ii < utn - 1; ii++) *q++ = buff8[ii]; c = buff8[ii]; /* Last byte */ p = pt + 1; break; } /* Not correct form; fall through */ } #endif /* Ordinary \x */ c = 0; while (i++ < 2 && isxdigit(*p)) { c = c * 16 + tolower(*p) - ((isdigit(*p))? '0' : 'W'); p++; } break; case 0: /* \ followed by EOF allows for an empty line */ p--; continue; case '>': while(isdigit(*p)) start_offset = start_offset * 10 + *p++ - '0'; continue; case 'A': /* Option setting */ options |= PCRE_ANCHORED; continue; case 'B': options |= PCRE_NOTBOL; continue; case 'C': if (isdigit(*p)) /* Set copy string */ { while(isdigit(*p)) n = n * 10 + *p++ - '0'; copystrings |= 1 << n; } else if (isalnum(*p)) { uschar *npp = copynamesptr; while (isalnum(*p)) *npp++ = *p++; *npp++ = 0; *npp = 0; n = pcre_get_stringnumber(re, (char *)copynamesptr); if (n < 0) fprintf(outfile, "no parentheses with name \"%s\"\n", copynamesptr); copynamesptr = npp; } else if (*p == '+') { callout_extra = 1; p++; } else if (*p == '-') { pcre_callout = NULL; p++; } else if (*p == '!') { callout_fail_id = 0; p++; while(isdigit(*p)) callout_fail_id = callout_fail_id * 10 + *p++ - '0'; callout_fail_count = 0; if (*p == '!') { p++; while(isdigit(*p)) callout_fail_count = callout_fail_count * 10 + *p++ - '0'; } } else if (*p == '*') { int sign = 1; callout_data = 0; if (*(++p) == '-') { sign = -1; p++; } while(isdigit(*p)) callout_data = callout_data * 10 + *p++ - '0'; callout_data *= sign; callout_data_set = 1; } continue; #if !defined NODFA case 'D': #if !defined NOPOSIX if (posix || do_posix) printf("** Can't use dfa matching in POSIX mode: \\D ignored\n"); else #endif use_dfa = 1; continue; case 'F': options |= PCRE_DFA_SHORTEST; continue; #endif case 'G': if (isdigit(*p)) { while(isdigit(*p)) n = n * 10 + *p++ - '0'; getstrings |= 1 << n; } else if (isalnum(*p)) { uschar *npp = getnamesptr; while (isalnum(*p)) *npp++ = *p++; *npp++ = 0; *npp = 0; n = pcre_get_stringnumber(re, (char *)getnamesptr); if (n < 0) fprintf(outfile, "no parentheses with name \"%s\"\n", getnamesptr); getnamesptr = npp; } continue; case 'L': getlist = 1; continue; case 'M': find_match_limit = 1; continue; case 'N': options |= PCRE_NOTEMPTY; continue; case 'O': while(isdigit(*p)) n = n * 10 + *p++ - '0'; if (n > size_offsets_max) { size_offsets_max = n; free(offsets); use_offsets = offsets = (int *)malloc(size_offsets_max * sizeof(int)); if (offsets == NULL) { printf("** Failed to get %d bytes of memory for offsets vector\n", (int)(size_offsets_max * sizeof(int))); yield = 1; goto EXIT; } } use_size_offsets = n; if (n == 0) use_offsets = NULL; /* Ensures it can't write to it */ continue; case 'P': options |= PCRE_PARTIAL; continue; case 'Q': while(isdigit(*p)) n = n * 10 + *p++ - '0'; if (extra == NULL) { extra = (pcre_extra *)malloc(sizeof(pcre_extra)); extra->flags = 0; } extra->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION; extra->match_limit_recursion = n; continue; case 'q': while(isdigit(*p)) n = n * 10 + *p++ - '0'; if (extra == NULL) { extra = (pcre_extra *)malloc(sizeof(pcre_extra)); extra->flags = 0; } extra->flags |= PCRE_EXTRA_MATCH_LIMIT; extra->match_limit = n; continue; #if !defined NODFA case 'R': options |= PCRE_DFA_RESTART; continue; #endif case 'S': show_malloc = 1; continue; case 'Z': options |= PCRE_NOTEOL; continue; case '?': options |= PCRE_NO_UTF8_CHECK; continue; case '<': { int x = check_newline(p, outfile); if (x == 0) goto NEXT_DATA; options |= x; while (*p++ != '>'); } continue; } *q++ = c; } *q = 0; len = q - dbuffer; if ((all_use_dfa || use_dfa) && find_match_limit) { printf("**Match limit not relevant for DFA matching: ignored\n"); find_match_limit = 0; } /* Handle matching via the POSIX interface, which does not support timing or playing with the match limit or callout data. */ #if !defined NOPOSIX if (posix || do_posix) { int rc; int eflags = 0; regmatch_t *pmatch = NULL; if (use_size_offsets > 0) pmatch = (regmatch_t *)malloc(sizeof(regmatch_t) * use_size_offsets); if ((options & PCRE_NOTBOL) != 0) eflags |= REG_NOTBOL; if ((options & PCRE_NOTEOL) != 0) eflags |= REG_NOTEOL; rc = regexec(&preg, (const char *)bptr, use_size_offsets, pmatch, eflags); if (rc != 0) { (void)regerror(rc, &preg, (char *)buffer, buffer_size); fprintf(outfile, "No match: POSIX code %d: %s\n", rc, buffer); } else if ((((const pcre *)preg.re_pcre)->options & PCRE_NO_AUTO_CAPTURE) != 0) { fprintf(outfile, "Matched with REG_NOSUB\n"); } else { size_t i; for (i = 0; i < (size_t)use_size_offsets; i++) { if (pmatch[i].rm_so >= 0) { fprintf(outfile, "%2d: ", (int)i); (void)pchars(dbuffer + pmatch[i].rm_so, pmatch[i].rm_eo - pmatch[i].rm_so, outfile); fprintf(outfile, "\n"); if (i == 0 && do_showrest) { fprintf(outfile, " 0+ "); (void)pchars(dbuffer + pmatch[i].rm_eo, len - pmatch[i].rm_eo, outfile); fprintf(outfile, "\n"); } } } } free(pmatch); } /* Handle matching via the native interface - repeats for /g and /G */ else #endif /* !defined NOPOSIX */ for (;; gmatched++) /* Loop for /g or /G */ { if (timeitm > 0) { register int i; clock_t time_taken; clock_t start_time = clock(); #if !defined NODFA if (all_use_dfa || use_dfa) { int workspace[1000]; for (i = 0; i < timeitm; i++) count = pcre_dfa_exec(re, NULL, (char *)bptr, len, start_offset, options | g_notempty, use_offsets, use_size_offsets, workspace, sizeof(workspace)/sizeof(int)); } else #endif for (i = 0; i < timeitm; i++) count = pcre_exec(re, extra, (char *)bptr, len, start_offset, options | g_notempty, use_offsets, use_size_offsets); time_taken = clock() - start_time; fprintf(outfile, "Execute time %.4f milliseconds\n", (((double)time_taken * 1000.0) / (double)timeitm) / (double)CLOCKS_PER_SEC); } /* If find_match_limit is set, we want to do repeated matches with varying limits in order to find the minimum value for the match limit and for the recursion limit. */ if (find_match_limit) { if (extra == NULL) { extra = (pcre_extra *)malloc(sizeof(pcre_extra)); extra->flags = 0; } (void)check_match_limit(re, extra, bptr, len, start_offset, options|g_notempty, use_offsets, use_size_offsets, PCRE_EXTRA_MATCH_LIMIT, &(extra->match_limit), PCRE_ERROR_MATCHLIMIT, "match()"); count = check_match_limit(re, extra, bptr, len, start_offset, options|g_notempty, use_offsets, use_size_offsets, PCRE_EXTRA_MATCH_LIMIT_RECURSION, &(extra->match_limit_recursion), PCRE_ERROR_RECURSIONLIMIT, "match() recursion"); } /* If callout_data is set, use the interface with additional data */ else if (callout_data_set) { if (extra == NULL) { extra = (pcre_extra *)malloc(sizeof(pcre_extra)); extra->flags = 0; } extra->flags |= PCRE_EXTRA_CALLOUT_DATA; extra->callout_data = &callout_data; count = pcre_exec(re, extra, (char *)bptr, len, start_offset, options | g_notempty, use_offsets, use_size_offsets); extra->flags &= ~PCRE_EXTRA_CALLOUT_DATA; } /* The normal case is just to do the match once, with the default value of match_limit. */ #if !defined NODFA else if (all_use_dfa || use_dfa) { int workspace[1000]; count = pcre_dfa_exec(re, NULL, (char *)bptr, len, start_offset, options | g_notempty, use_offsets, use_size_offsets, workspace, sizeof(workspace)/sizeof(int)); if (count == 0) { fprintf(outfile, "Matched, but too many subsidiary matches\n"); count = use_size_offsets/2; } } #endif else { count = pcre_exec(re, extra, (char *)bptr, len, start_offset, options | g_notempty, use_offsets, use_size_offsets); if (count == 0) { fprintf(outfile, "Matched, but too many substrings\n"); count = use_size_offsets/3; } } /* Matched */ if (count >= 0) { int i, maxcount; #if !defined NODFA if (all_use_dfa || use_dfa) maxcount = use_size_offsets/2; else #endif maxcount = use_size_offsets/3; /* This is a check against a lunatic return value. */ if (count > maxcount) { fprintf(outfile, "** PCRE error: returned count %d is too big for offset size %d\n", count, use_size_offsets); count = use_size_offsets/3; if (do_g || do_G) { fprintf(outfile, "** /%c loop abandoned\n", do_g? 'g' : 'G'); do_g = do_G = FALSE; /* Break g/G loop */ } } for (i = 0; i < count * 2; i += 2) { if (use_offsets[i] < 0) fprintf(outfile, "%2d: \n", i/2); else { fprintf(outfile, "%2d: ", i/2); (void)pchars(bptr + use_offsets[i], use_offsets[i+1] - use_offsets[i], outfile); fprintf(outfile, "\n"); if (i == 0) { if (do_showrest) { fprintf(outfile, " 0+ "); (void)pchars(bptr + use_offsets[i+1], len - use_offsets[i+1], outfile); fprintf(outfile, "\n"); } } } } for (i = 0; i < 32; i++) { if ((copystrings & (1 << i)) != 0) { char copybuffer[256]; int rc = pcre_copy_substring((char *)bptr, use_offsets, count, i, copybuffer, sizeof(copybuffer)); if (rc < 0) fprintf(outfile, "copy substring %d failed %d\n", i, rc); else fprintf(outfile, "%2dC %s (%d)\n", i, copybuffer, rc); } } for (copynamesptr = copynames; *copynamesptr != 0; copynamesptr += (int)strlen((char*)copynamesptr) + 1) { char copybuffer[256]; int rc = pcre_copy_named_substring(re, (char *)bptr, use_offsets, count, (char *)copynamesptr, copybuffer, sizeof(copybuffer)); if (rc < 0) fprintf(outfile, "copy substring %s failed %d\n", copynamesptr, rc); else fprintf(outfile, " C %s (%d) %s\n", copybuffer, rc, copynamesptr); } for (i = 0; i < 32; i++) { if ((getstrings & (1 << i)) != 0) { const char *substring; int rc = pcre_get_substring((char *)bptr, use_offsets, count, i, &substring); if (rc < 0) fprintf(outfile, "get substring %d failed %d\n", i, rc); else { fprintf(outfile, "%2dG %s (%d)\n", i, substring, rc); pcre_free_substring(substring); } } } for (getnamesptr = getnames; *getnamesptr != 0; getnamesptr += (int)strlen((char*)getnamesptr) + 1) { const char *substring; int rc = pcre_get_named_substring(re, (char *)bptr, use_offsets, count, (char *)getnamesptr, &substring); if (rc < 0) fprintf(outfile, "copy substring %s failed %d\n", getnamesptr, rc); else { fprintf(outfile, " G %s (%d) %s\n", substring, rc, getnamesptr); pcre_free_substring(substring); } } if (getlist) { const char **stringlist; int rc = pcre_get_substring_list((char *)bptr, use_offsets, count, &stringlist); if (rc < 0) fprintf(outfile, "get substring list failed %d\n", rc); else { for (i = 0; i < count; i++) fprintf(outfile, "%2dL %s\n", i, stringlist[i]); if (stringlist[i] != NULL) fprintf(outfile, "string list not terminated by NULL\n"); /* free((void *)stringlist); */ pcre_free_substring_list(stringlist); } } } /* There was a partial match */ else if (count == PCRE_ERROR_PARTIAL) { fprintf(outfile, "Partial match"); #if !defined NODFA if ((all_use_dfa || use_dfa) && use_size_offsets > 2) fprintf(outfile, ": %.*s", use_offsets[1] - use_offsets[0], bptr + use_offsets[0]); #endif fprintf(outfile, "\n"); break; /* Out of the /g loop */ } /* Failed to match. If this is a /g or /G loop and we previously set g_notempty after a null match, this is not necessarily the end. We want to advance the start offset, and continue. We won't be at the end of the string - that was checked before setting g_notempty. Complication arises in the case when the newline option is "any" or "anycrlf". If the previous match was at the end of a line terminated by CRLF, an advance of one character just passes the \r, whereas we should prefer the longer newline sequence, as does the code in pcre_exec(). Fudge the offset value to achieve this. Otherwise, in the case of UTF-8 matching, the advance must be one character, not one byte. */ else { if (g_notempty != 0) { int onechar = 1; unsigned int obits = ((real_pcre *)re)->options; use_offsets[0] = start_offset; if ((obits & PCRE_NEWLINE_BITS) == 0) { int d; (void)pcre_config(PCRE_CONFIG_NEWLINE, &d); obits = (d == '\r')? PCRE_NEWLINE_CR : (d == '\n')? PCRE_NEWLINE_LF : (d == ('\r'<<8 | '\n'))? PCRE_NEWLINE_CRLF : (d == -2)? PCRE_NEWLINE_ANYCRLF : (d == -1)? PCRE_NEWLINE_ANY : 0; } if (((obits & PCRE_NEWLINE_BITS) == PCRE_NEWLINE_ANY || (obits & PCRE_NEWLINE_BITS) == PCRE_NEWLINE_ANYCRLF) && start_offset < len - 1 && bptr[start_offset] == '\r' && bptr[start_offset+1] == '\n') onechar++; else if (use_utf8) { while (start_offset + onechar < len) { int tb = bptr[start_offset+onechar]; if (tb <= 127) break; tb &= 0xc0; if (tb != 0 && tb != 0xc0) onechar++; } } use_offsets[1] = start_offset + onechar; } else { if (count == PCRE_ERROR_NOMATCH) { if (gmatched == 0) fprintf(outfile, "No match\n"); } else fprintf(outfile, "Error %d\n", count); break; /* Out of the /g loop */ } } /* If not /g or /G we are done */ if (!do_g && !do_G) break; /* If we have matched an empty string, first check to see if we are at the end of the subject. If so, the /g loop is over. Otherwise, mimic what Perl's /g options does. This turns out to be rather cunning. First we set PCRE_NOTEMPTY and PCRE_ANCHORED and try the match again at the same point. If this fails (picked up above) we advance to the next character. */ g_notempty = 0; if (use_offsets[0] == use_offsets[1]) { if (use_offsets[0] == len) break; g_notempty = PCRE_NOTEMPTY | PCRE_ANCHORED; } /* For /g, update the start offset, leaving the rest alone */ if (do_g) start_offset = use_offsets[1]; /* For /G, update the pointer and length */ else { bptr += use_offsets[1]; len -= use_offsets[1]; } } /* End of loop for /g and /G */ NEXT_DATA: continue; } /* End of loop for data lines */ CONTINUE: #if !defined NOPOSIX if (posix || do_posix) regfree(&preg); #endif if (re != NULL) new_free(re); if (extra != NULL) new_free(extra); if (tables != NULL) { new_free((void *)tables); setlocale(LC_CTYPE, "C"); locale_set = 0; } } if (infile == stdin) fprintf(outfile, "\n"); EXIT: if (infile != NULL && infile != stdin) fclose(infile); if (outfile != NULL && outfile != stdout) fclose(outfile); free(buffer); free(dbuffer); free(pbuffer); free(offsets); return yield; } /* End of pcretest.c */ libsynthesis-3.4.0.47.1/src/pcre/perltest.pl000066400000000000000000000113201226375725500205600ustar00rootroot00000000000000#! /usr/bin/env perl # Program for testing regular expressions with perl to check that PCRE handles # them the same. This is the version that supports /8 for UTF-8 testing. As it # stands, it requires at least Perl 5.8 for UTF-8 support. However, it needs to # have "use utf8" at the start for running the UTF-8 tests, but *not* for the # other tests. The only way I've found for doing this is to cat this line in # explicitly in the RunPerlTest script. # use locale; # With this included, \x0b matches \s! # Function for turning a string into a string of printing chars. There are # currently problems with UTF-8 strings; this fudges round them. sub pchars { my($t) = ""; if ($utf8) { @p = unpack('U*', $_[0]); foreach $c (@p) { if ($c >= 32 && $c < 127) { $t .= chr $c; } else { $t .= sprintf("\\x{%02x}", $c); } } } else { foreach $c (split(//, $_[0])) { if (ord $c >= 32 && ord $c < 127) { $t .= $c; } else { $t .= sprintf("\\x%02x", ord $c); } } } $t; } # Read lines from named file or stdin and write to named file or stdout; lines # consist of a regular expression, in delimiters and optionally followed by # options, followed by a set of test data, terminated by an empty line. # Sort out the input and output files if (@ARGV > 0) { open(INFILE, "<$ARGV[0]") || die "Failed to open $ARGV[0]\n"; $infile = "INFILE"; } else { $infile = "STDIN"; } if (@ARGV > 1) { open(OUTFILE, ">$ARGV[1]") || die "Failed to open $ARGV[1]\n"; $outfile = "OUTFILE"; } else { $outfile = "STDOUT"; } printf($outfile "Perl $] Regular Expressions\n\n"); # Main loop NEXT_RE: for (;;) { printf " re> " if $infile eq "STDIN"; last if ! ($_ = <$infile>); printf $outfile "$_" if $infile ne "STDIN"; next if ($_ eq ""); $pattern = $_; while ($pattern !~ /^\s*(.).*\1/s) { printf " > " if $infile eq "STDIN"; last if ! ($_ = <$infile>); printf $outfile "$_" if $infile ne "STDIN"; $pattern .= $_; } chomp($pattern); $pattern =~ s/\s+$//; # The private /+ modifier means "print $' afterwards". $showrest = ($pattern =~ s/\+(?=[a-z]*$)//); # Remove /8 from a UTF-8 pattern. $utf8 = $pattern =~ s/8(?=[a-z]*$)//; # Check that the pattern is valid eval "\$_ =~ ${pattern}"; if ($@) { printf $outfile "Error: $@"; next NEXT_RE; } # If the /g modifier is present, we want to put a loop round the matching; # otherwise just a single "if". $cmd = ($pattern =~ /g[a-z]*$/)? "while" : "if"; # If the pattern is actually the null string, Perl uses the most recently # executed (and successfully compiled) regex is used instead. This is a # nasty trap for the unwary! The PCRE test suite does contain null strings # in places - if they are allowed through here all sorts of weird and # unexpected effects happen. To avoid this, we replace such patterns with # a non-null pattern that has the same effect. $pattern = "/(?#)/$2" if ($pattern =~ /^(.)\1(.*)$/); # Read data lines and test them for (;;) { printf "data> " if $infile eq "STDIN"; last NEXT_RE if ! ($_ = <$infile>); chomp; printf $outfile "$_\n" if $infile ne "STDIN"; s/\s+$//; s/^\s+//; last if ($_ eq ""); $x = eval "\"$_\""; # To get escapes processed # Empty array for holding results, then do the matching. @subs = (); $pushes = "push \@subs,\$&;" . "push \@subs,\$1;" . "push \@subs,\$2;" . "push \@subs,\$3;" . "push \@subs,\$4;" . "push \@subs,\$5;" . "push \@subs,\$6;" . "push \@subs,\$7;" . "push \@subs,\$8;" . "push \@subs,\$9;" . "push \@subs,\$10;" . "push \@subs,\$11;" . "push \@subs,\$12;" . "push \@subs,\$13;" . "push \@subs,\$14;" . "push \@subs,\$15;" . "push \@subs,\$16;" . "push \@subs,\$'; }"; eval "${cmd} (\$x =~ ${pattern}) {" . $pushes; if ($@) { printf $outfile "Error: $@\n"; next NEXT_RE; } elsif (scalar(@subs) == 0) { printf $outfile "No match\n"; } else { while (scalar(@subs) != 0) { printf $outfile (" 0: %s\n", &pchars($subs[0])); printf $outfile (" 0+ %s\n", &pchars($subs[17])) if $showrest; $last_printed = 0; for ($i = 1; $i <= 16; $i++) { if (defined $subs[$i]) { while ($last_printed++ < $i-1) { printf $outfile ("%2d: \n", $last_printed); } printf $outfile ("%2d: %s\n", $i, &pchars($subs[$i])); $last_printed = $i; } } splice(@subs, 0, 18); } } } } # printf $outfile "\n"; # End libsynthesis-3.4.0.47.1/src/pcre/ucp.h000066400000000000000000000057231226375725500173330ustar00rootroot00000000000000/************************************************* * Unicode Property Table handler * *************************************************/ #ifndef _UCP_H #define _UCP_H /* This file contains definitions of the property values that are returned by the function _pcre_ucp_findprop(). New values that are added for new releases of Unicode should always be at the end of each enum, for backwards compatibility. */ /* These are the general character categories. */ enum { ucp_C, /* Other */ ucp_L, /* Letter */ ucp_M, /* Mark */ ucp_N, /* Number */ ucp_P, /* Punctuation */ ucp_S, /* Symbol */ ucp_Z /* Separator */ }; /* These are the particular character types. */ enum { ucp_Cc, /* Control */ ucp_Cf, /* Format */ ucp_Cn, /* Unassigned */ ucp_Co, /* Private use */ ucp_Cs, /* Surrogate */ ucp_Ll, /* Lower case letter */ ucp_Lm, /* Modifier letter */ ucp_Lo, /* Other letter */ ucp_Lt, /* Title case letter */ ucp_Lu, /* Upper case letter */ ucp_Mc, /* Spacing mark */ ucp_Me, /* Enclosing mark */ ucp_Mn, /* Non-spacing mark */ ucp_Nd, /* Decimal number */ ucp_Nl, /* Letter number */ ucp_No, /* Other number */ ucp_Pc, /* Connector punctuation */ ucp_Pd, /* Dash punctuation */ ucp_Pe, /* Close punctuation */ ucp_Pf, /* Final punctuation */ ucp_Pi, /* Initial punctuation */ ucp_Po, /* Other punctuation */ ucp_Ps, /* Open punctuation */ ucp_Sc, /* Currency symbol */ ucp_Sk, /* Modifier symbol */ ucp_Sm, /* Mathematical symbol */ ucp_So, /* Other symbol */ ucp_Zl, /* Line separator */ ucp_Zp, /* Paragraph separator */ ucp_Zs /* Space separator */ }; /* These are the script identifications. */ enum { ucp_Arabic, ucp_Armenian, ucp_Bengali, ucp_Bopomofo, ucp_Braille, ucp_Buginese, ucp_Buhid, ucp_Canadian_Aboriginal, ucp_Cherokee, ucp_Common, ucp_Coptic, ucp_Cypriot, ucp_Cyrillic, ucp_Deseret, ucp_Devanagari, ucp_Ethiopic, ucp_Georgian, ucp_Glagolitic, ucp_Gothic, ucp_Greek, ucp_Gujarati, ucp_Gurmukhi, ucp_Han, ucp_Hangul, ucp_Hanunoo, ucp_Hebrew, ucp_Hiragana, ucp_Inherited, ucp_Kannada, ucp_Katakana, ucp_Kharoshthi, ucp_Khmer, ucp_Lao, ucp_Latin, ucp_Limbu, ucp_Linear_B, ucp_Malayalam, ucp_Mongolian, ucp_Myanmar, ucp_New_Tai_Lue, ucp_Ogham, ucp_Old_Italic, ucp_Old_Persian, ucp_Oriya, ucp_Osmanya, ucp_Runic, ucp_Shavian, ucp_Sinhala, ucp_Syloti_Nagri, ucp_Syriac, ucp_Tagalog, ucp_Tagbanwa, ucp_Tai_Le, ucp_Tamil, ucp_Telugu, ucp_Thaana, ucp_Thai, ucp_Tibetan, ucp_Tifinagh, ucp_Ugaritic, ucp_Yi, ucp_Balinese, /* New for Unicode 5.0.0 */ ucp_Cuneiform, /* New for Unicode 5.0.0 */ ucp_Nko, /* New for Unicode 5.0.0 */ ucp_Phags_Pa, /* New for Unicode 5.0.0 */ ucp_Phoenician /* New for Unicode 5.0.0 */ }; #endif /* End of ucp.h */ libsynthesis-3.4.0.47.1/src/pcre/ucpinternal.h000066400000000000000000000065741226375725500210750ustar00rootroot00000000000000/************************************************* * Unicode Property Table handler * *************************************************/ #ifndef _UCPINTERNAL_H #define _UCPINTERNAL_H /* Internal header file defining the layout of the bits in each pair of 32-bit words that form a data item in the table. */ typedef struct cnode { pcre_uint32 f0; pcre_uint32 f1; } cnode; /* Things for the f0 field */ #define f0_scriptmask 0xff000000 /* Mask for script field */ #define f0_scriptshift 24 /* Shift for script value */ #define f0_rangeflag 0x00f00000 /* Flag for a range item */ #define f0_charmask 0x001fffff /* Mask for code point value */ /* Things for the f1 field */ #define f1_typemask 0xfc000000 /* Mask for char type field */ #define f1_typeshift 26 /* Shift for the type field */ #define f1_rangemask 0x0000ffff /* Mask for a range offset */ #define f1_casemask 0x0000ffff /* Mask for a case offset */ #define f1_caseneg 0xffff8000 /* Bits for negation */ /* The data consists of a vector of structures of type cnode. The two unsigned 32-bit integers are used as follows: (f0) (1) The most significant byte holds the script number. The numbers are defined by the enum in ucp.h. (2) The 0x00800000 bit is set if this entry defines a range of characters. It is not set if this entry defines a single character (3) The 0x00600000 bits are spare. (4) The 0x001fffff bits contain the code point. No Unicode code point will ever be greater than 0x0010ffff, so this should be OK for ever. (f1) (1) The 0xfc000000 bits contain the character type number. The numbers are defined by an enum in ucp.h. (2) The 0x03ff0000 bits are spare. (3) The 0x0000ffff bits contain EITHER the unsigned offset to the top of range if this entry defines a range, OR the *signed* offset to the character's "other case" partner if this entry defines a single character. There is no partner if the value is zero. ------------------------------------------------------------------------------- | script (8) |.|.|.| codepoint (21) || type (6) |.|.| spare (8) | offset (16) | ------------------------------------------------------------------------------- | | | | | | | |-> spare | |-> spare | | | | |-> spare |-> spare | |-> range flag The upper/lower casing information is set only for characters that come in pairs. The non-one-to-one mappings in the Unicode data are ignored. When searching the data, proceed as follows: (1) Set up for a binary chop search. (2) If the top is not greater than the bottom, the character is not in the table. Its type must therefore be "Cn" ("Undefined"). (3) Find the middle vector element. (4) Extract the code point and compare. If equal, we are done. (5) If the test character is smaller, set the top to the current point, and goto (2). (6) If the current entry defines a range, compute the last character by adding the offset, and see if the test character is within the range. If it is, we are done. (7) Otherwise, set the bottom to one element past the current point and goto (2). */ #endif /* _UCPINTERNAL_H */ /* End of ucpinternal.h */ libsynthesis-3.4.0.47.1/src/pcre/ucptable.h000066400000000000000000002636701226375725500203520ustar00rootroot00000000000000/* This source module is automatically generated from the Unicode property table. See ucpinternal.h for a description of the layout. This version was made from the Unicode 5.0.0 tables. */ static const cnode ucp_table[] = { { 0x09800000, 0x0000001f }, { 0x09000020, 0x74000000 }, { 0x09800021, 0x54000002 }, { 0x09000024, 0x5c000000 }, { 0x09800025, 0x54000002 }, { 0x09000028, 0x58000000 }, { 0x09000029, 0x48000000 }, { 0x0900002a, 0x54000000 }, { 0x0900002b, 0x64000000 }, { 0x0900002c, 0x54000000 }, { 0x0900002d, 0x44000000 }, { 0x0980002e, 0x54000001 }, { 0x09800030, 0x34000009 }, { 0x0980003a, 0x54000001 }, { 0x0980003c, 0x64000002 }, { 0x0980003f, 0x54000001 }, { 0x21000041, 0x24000020 }, { 0x21000042, 0x24000020 }, { 0x21000043, 0x24000020 }, { 0x21000044, 0x24000020 }, { 0x21000045, 0x24000020 }, { 0x21000046, 0x24000020 }, { 0x21000047, 0x24000020 }, { 0x21000048, 0x24000020 }, { 0x21000049, 0x24000020 }, { 0x2100004a, 0x24000020 }, { 0x2100004b, 0x24000020 }, { 0x2100004c, 0x24000020 }, { 0x2100004d, 0x24000020 }, { 0x2100004e, 0x24000020 }, { 0x2100004f, 0x24000020 }, { 0x21000050, 0x24000020 }, { 0x21000051, 0x24000020 }, { 0x21000052, 0x24000020 }, { 0x21000053, 0x24000020 }, { 0x21000054, 0x24000020 }, { 0x21000055, 0x24000020 }, { 0x21000056, 0x24000020 }, { 0x21000057, 0x24000020 }, { 0x21000058, 0x24000020 }, { 0x21000059, 0x24000020 }, { 0x2100005a, 0x24000020 }, { 0x0900005b, 0x58000000 }, { 0x0900005c, 0x54000000 }, { 0x0900005d, 0x48000000 }, { 0x0900005e, 0x60000000 }, { 0x0900005f, 0x40000000 }, { 0x09000060, 0x60000000 }, { 0x21000061, 0x1400ffe0 }, { 0x21000062, 0x1400ffe0 }, { 0x21000063, 0x1400ffe0 }, { 0x21000064, 0x1400ffe0 }, { 0x21000065, 0x1400ffe0 }, { 0x21000066, 0x1400ffe0 }, { 0x21000067, 0x1400ffe0 }, { 0x21000068, 0x1400ffe0 }, { 0x21000069, 0x1400ffe0 }, { 0x2100006a, 0x1400ffe0 }, { 0x2100006b, 0x1400ffe0 }, { 0x2100006c, 0x1400ffe0 }, { 0x2100006d, 0x1400ffe0 }, { 0x2100006e, 0x1400ffe0 }, { 0x2100006f, 0x1400ffe0 }, { 0x21000070, 0x1400ffe0 }, { 0x21000071, 0x1400ffe0 }, { 0x21000072, 0x1400ffe0 }, { 0x21000073, 0x1400ffe0 }, { 0x21000074, 0x1400ffe0 }, { 0x21000075, 0x1400ffe0 }, { 0x21000076, 0x1400ffe0 }, { 0x21000077, 0x1400ffe0 }, { 0x21000078, 0x1400ffe0 }, { 0x21000079, 0x1400ffe0 }, { 0x2100007a, 0x1400ffe0 }, { 0x0900007b, 0x58000000 }, { 0x0900007c, 0x64000000 }, { 0x0900007d, 0x48000000 }, { 0x0900007e, 0x64000000 }, { 0x0980007f, 0x00000020 }, { 0x090000a0, 0x74000000 }, { 0x090000a1, 0x54000000 }, { 0x098000a2, 0x5c000003 }, { 0x098000a6, 0x68000001 }, { 0x090000a8, 0x60000000 }, { 0x090000a9, 0x68000000 }, { 0x210000aa, 0x14000000 }, { 0x090000ab, 0x50000000 }, { 0x090000ac, 0x64000000 }, { 0x090000ad, 0x04000000 }, { 0x090000ae, 0x68000000 }, { 0x090000af, 0x60000000 }, { 0x090000b0, 0x68000000 }, { 0x090000b1, 0x64000000 }, { 0x098000b2, 0x3c000001 }, { 0x090000b4, 0x60000000 }, { 0x090000b5, 0x140002e7 }, { 0x090000b6, 0x68000000 }, { 0x090000b7, 0x54000000 }, { 0x090000b8, 0x60000000 }, { 0x090000b9, 0x3c000000 }, { 0x210000ba, 0x14000000 }, { 0x090000bb, 0x4c000000 }, { 0x098000bc, 0x3c000002 }, { 0x090000bf, 0x54000000 }, { 0x210000c0, 0x24000020 }, { 0x210000c1, 0x24000020 }, { 0x210000c2, 0x24000020 }, { 0x210000c3, 0x24000020 }, { 0x210000c4, 0x24000020 }, { 0x210000c5, 0x24000020 }, { 0x210000c6, 0x24000020 }, { 0x210000c7, 0x24000020 }, { 0x210000c8, 0x24000020 }, { 0x210000c9, 0x24000020 }, { 0x210000ca, 0x24000020 }, { 0x210000cb, 0x24000020 }, { 0x210000cc, 0x24000020 }, { 0x210000cd, 0x24000020 }, { 0x210000ce, 0x24000020 }, { 0x210000cf, 0x24000020 }, { 0x210000d0, 0x24000020 }, { 0x210000d1, 0x24000020 }, { 0x210000d2, 0x24000020 }, { 0x210000d3, 0x24000020 }, { 0x210000d4, 0x24000020 }, { 0x210000d5, 0x24000020 }, { 0x210000d6, 0x24000020 }, { 0x090000d7, 0x64000000 }, { 0x210000d8, 0x24000020 }, { 0x210000d9, 0x24000020 }, { 0x210000da, 0x24000020 }, { 0x210000db, 0x24000020 }, { 0x210000dc, 0x24000020 }, { 0x210000dd, 0x24000020 }, { 0x210000de, 0x24000020 }, { 0x210000df, 0x14000000 }, { 0x210000e0, 0x1400ffe0 }, { 0x210000e1, 0x1400ffe0 }, { 0x210000e2, 0x1400ffe0 }, { 0x210000e3, 0x1400ffe0 }, { 0x210000e4, 0x1400ffe0 }, { 0x210000e5, 0x1400ffe0 }, { 0x210000e6, 0x1400ffe0 }, { 0x210000e7, 0x1400ffe0 }, { 0x210000e8, 0x1400ffe0 }, { 0x210000e9, 0x1400ffe0 }, { 0x210000ea, 0x1400ffe0 }, { 0x210000eb, 0x1400ffe0 }, { 0x210000ec, 0x1400ffe0 }, { 0x210000ed, 0x1400ffe0 }, { 0x210000ee, 0x1400ffe0 }, { 0x210000ef, 0x1400ffe0 }, { 0x210000f0, 0x1400ffe0 }, { 0x210000f1, 0x1400ffe0 }, { 0x210000f2, 0x1400ffe0 }, { 0x210000f3, 0x1400ffe0 }, { 0x210000f4, 0x1400ffe0 }, { 0x210000f5, 0x1400ffe0 }, { 0x210000f6, 0x1400ffe0 }, { 0x090000f7, 0x64000000 }, { 0x210000f8, 0x1400ffe0 }, { 0x210000f9, 0x1400ffe0 }, { 0x210000fa, 0x1400ffe0 }, { 0x210000fb, 0x1400ffe0 }, { 0x210000fc, 0x1400ffe0 }, { 0x210000fd, 0x1400ffe0 }, { 0x210000fe, 0x1400ffe0 }, { 0x210000ff, 0x14000079 }, { 0x21000100, 0x24000001 }, { 0x21000101, 0x1400ffff }, { 0x21000102, 0x24000001 }, { 0x21000103, 0x1400ffff }, { 0x21000104, 0x24000001 }, { 0x21000105, 0x1400ffff }, { 0x21000106, 0x24000001 }, { 0x21000107, 0x1400ffff }, { 0x21000108, 0x24000001 }, { 0x21000109, 0x1400ffff }, { 0x2100010a, 0x24000001 }, { 0x2100010b, 0x1400ffff }, { 0x2100010c, 0x24000001 }, { 0x2100010d, 0x1400ffff }, { 0x2100010e, 0x24000001 }, { 0x2100010f, 0x1400ffff }, { 0x21000110, 0x24000001 }, { 0x21000111, 0x1400ffff }, { 0x21000112, 0x24000001 }, { 0x21000113, 0x1400ffff }, { 0x21000114, 0x24000001 }, { 0x21000115, 0x1400ffff }, { 0x21000116, 0x24000001 }, { 0x21000117, 0x1400ffff }, { 0x21000118, 0x24000001 }, { 0x21000119, 0x1400ffff }, { 0x2100011a, 0x24000001 }, { 0x2100011b, 0x1400ffff }, { 0x2100011c, 0x24000001 }, { 0x2100011d, 0x1400ffff }, { 0x2100011e, 0x24000001 }, { 0x2100011f, 0x1400ffff }, { 0x21000120, 0x24000001 }, { 0x21000121, 0x1400ffff }, { 0x21000122, 0x24000001 }, { 0x21000123, 0x1400ffff }, { 0x21000124, 0x24000001 }, { 0x21000125, 0x1400ffff }, { 0x21000126, 0x24000001 }, { 0x21000127, 0x1400ffff }, { 0x21000128, 0x24000001 }, { 0x21000129, 0x1400ffff }, { 0x2100012a, 0x24000001 }, { 0x2100012b, 0x1400ffff }, { 0x2100012c, 0x24000001 }, { 0x2100012d, 0x1400ffff }, { 0x2100012e, 0x24000001 }, { 0x2100012f, 0x1400ffff }, { 0x21000130, 0x2400ff39 }, { 0x21000131, 0x1400ff18 }, { 0x21000132, 0x24000001 }, { 0x21000133, 0x1400ffff }, { 0x21000134, 0x24000001 }, { 0x21000135, 0x1400ffff }, { 0x21000136, 0x24000001 }, { 0x21000137, 0x1400ffff }, { 0x21000138, 0x14000000 }, { 0x21000139, 0x24000001 }, { 0x2100013a, 0x1400ffff }, { 0x2100013b, 0x24000001 }, { 0x2100013c, 0x1400ffff }, { 0x2100013d, 0x24000001 }, { 0x2100013e, 0x1400ffff }, { 0x2100013f, 0x24000001 }, { 0x21000140, 0x1400ffff }, { 0x21000141, 0x24000001 }, { 0x21000142, 0x1400ffff }, { 0x21000143, 0x24000001 }, { 0x21000144, 0x1400ffff }, { 0x21000145, 0x24000001 }, { 0x21000146, 0x1400ffff }, { 0x21000147, 0x24000001 }, { 0x21000148, 0x1400ffff }, { 0x21000149, 0x14000000 }, { 0x2100014a, 0x24000001 }, { 0x2100014b, 0x1400ffff }, { 0x2100014c, 0x24000001 }, { 0x2100014d, 0x1400ffff }, { 0x2100014e, 0x24000001 }, { 0x2100014f, 0x1400ffff }, { 0x21000150, 0x24000001 }, { 0x21000151, 0x1400ffff }, { 0x21000152, 0x24000001 }, { 0x21000153, 0x1400ffff }, { 0x21000154, 0x24000001 }, { 0x21000155, 0x1400ffff }, { 0x21000156, 0x24000001 }, { 0x21000157, 0x1400ffff }, { 0x21000158, 0x24000001 }, { 0x21000159, 0x1400ffff }, { 0x2100015a, 0x24000001 }, { 0x2100015b, 0x1400ffff }, { 0x2100015c, 0x24000001 }, { 0x2100015d, 0x1400ffff }, { 0x2100015e, 0x24000001 }, { 0x2100015f, 0x1400ffff }, { 0x21000160, 0x24000001 }, { 0x21000161, 0x1400ffff }, { 0x21000162, 0x24000001 }, { 0x21000163, 0x1400ffff }, { 0x21000164, 0x24000001 }, { 0x21000165, 0x1400ffff }, { 0x21000166, 0x24000001 }, { 0x21000167, 0x1400ffff }, { 0x21000168, 0x24000001 }, { 0x21000169, 0x1400ffff }, { 0x2100016a, 0x24000001 }, { 0x2100016b, 0x1400ffff }, { 0x2100016c, 0x24000001 }, { 0x2100016d, 0x1400ffff }, { 0x2100016e, 0x24000001 }, { 0x2100016f, 0x1400ffff }, { 0x21000170, 0x24000001 }, { 0x21000171, 0x1400ffff }, { 0x21000172, 0x24000001 }, { 0x21000173, 0x1400ffff }, { 0x21000174, 0x24000001 }, { 0x21000175, 0x1400ffff }, { 0x21000176, 0x24000001 }, { 0x21000177, 0x1400ffff }, { 0x21000178, 0x2400ff87 }, { 0x21000179, 0x24000001 }, { 0x2100017a, 0x1400ffff }, { 0x2100017b, 0x24000001 }, { 0x2100017c, 0x1400ffff }, { 0x2100017d, 0x24000001 }, { 0x2100017e, 0x1400ffff }, { 0x2100017f, 0x1400fed4 }, { 0x21000180, 0x140000c3 }, { 0x21000181, 0x240000d2 }, { 0x21000182, 0x24000001 }, { 0x21000183, 0x1400ffff }, { 0x21000184, 0x24000001 }, { 0x21000185, 0x1400ffff }, { 0x21000186, 0x240000ce }, { 0x21000187, 0x24000001 }, { 0x21000188, 0x1400ffff }, { 0x21000189, 0x240000cd }, { 0x2100018a, 0x240000cd }, { 0x2100018b, 0x24000001 }, { 0x2100018c, 0x1400ffff }, { 0x2100018d, 0x14000000 }, { 0x2100018e, 0x2400004f }, { 0x2100018f, 0x240000ca }, { 0x21000190, 0x240000cb }, { 0x21000191, 0x24000001 }, { 0x21000192, 0x1400ffff }, { 0x21000193, 0x240000cd }, { 0x21000194, 0x240000cf }, { 0x21000195, 0x14000061 }, { 0x21000196, 0x240000d3 }, { 0x21000197, 0x240000d1 }, { 0x21000198, 0x24000001 }, { 0x21000199, 0x1400ffff }, { 0x2100019a, 0x140000a3 }, { 0x2100019b, 0x14000000 }, { 0x2100019c, 0x240000d3 }, { 0x2100019d, 0x240000d5 }, { 0x2100019e, 0x14000082 }, { 0x2100019f, 0x240000d6 }, { 0x210001a0, 0x24000001 }, { 0x210001a1, 0x1400ffff }, { 0x210001a2, 0x24000001 }, { 0x210001a3, 0x1400ffff }, { 0x210001a4, 0x24000001 }, { 0x210001a5, 0x1400ffff }, { 0x210001a6, 0x240000da }, { 0x210001a7, 0x24000001 }, { 0x210001a8, 0x1400ffff }, { 0x210001a9, 0x240000da }, { 0x218001aa, 0x14000001 }, { 0x210001ac, 0x24000001 }, { 0x210001ad, 0x1400ffff }, { 0x210001ae, 0x240000da }, { 0x210001af, 0x24000001 }, { 0x210001b0, 0x1400ffff }, { 0x210001b1, 0x240000d9 }, { 0x210001b2, 0x240000d9 }, { 0x210001b3, 0x24000001 }, { 0x210001b4, 0x1400ffff }, { 0x210001b5, 0x24000001 }, { 0x210001b6, 0x1400ffff }, { 0x210001b7, 0x240000db }, { 0x210001b8, 0x24000001 }, { 0x210001b9, 0x1400ffff }, { 0x210001ba, 0x14000000 }, { 0x210001bb, 0x1c000000 }, { 0x210001bc, 0x24000001 }, { 0x210001bd, 0x1400ffff }, { 0x210001be, 0x14000000 }, { 0x210001bf, 0x14000038 }, { 0x218001c0, 0x1c000003 }, { 0x210001c4, 0x24000002 }, { 0x210001c5, 0x2000ffff }, { 0x210001c6, 0x1400fffe }, { 0x210001c7, 0x24000002 }, { 0x210001c8, 0x2000ffff }, { 0x210001c9, 0x1400fffe }, { 0x210001ca, 0x24000002 }, { 0x210001cb, 0x2000ffff }, { 0x210001cc, 0x1400fffe }, { 0x210001cd, 0x24000001 }, { 0x210001ce, 0x1400ffff }, { 0x210001cf, 0x24000001 }, { 0x210001d0, 0x1400ffff }, { 0x210001d1, 0x24000001 }, { 0x210001d2, 0x1400ffff }, { 0x210001d3, 0x24000001 }, { 0x210001d4, 0x1400ffff }, { 0x210001d5, 0x24000001 }, { 0x210001d6, 0x1400ffff }, { 0x210001d7, 0x24000001 }, { 0x210001d8, 0x1400ffff }, { 0x210001d9, 0x24000001 }, { 0x210001da, 0x1400ffff }, { 0x210001db, 0x24000001 }, { 0x210001dc, 0x1400ffff }, { 0x210001dd, 0x1400ffb1 }, { 0x210001de, 0x24000001 }, { 0x210001df, 0x1400ffff }, { 0x210001e0, 0x24000001 }, { 0x210001e1, 0x1400ffff }, { 0x210001e2, 0x24000001 }, { 0x210001e3, 0x1400ffff }, { 0x210001e4, 0x24000001 }, { 0x210001e5, 0x1400ffff }, { 0x210001e6, 0x24000001 }, { 0x210001e7, 0x1400ffff }, { 0x210001e8, 0x24000001 }, { 0x210001e9, 0x1400ffff }, { 0x210001ea, 0x24000001 }, { 0x210001eb, 0x1400ffff }, { 0x210001ec, 0x24000001 }, { 0x210001ed, 0x1400ffff }, { 0x210001ee, 0x24000001 }, { 0x210001ef, 0x1400ffff }, { 0x210001f0, 0x14000000 }, { 0x210001f1, 0x24000002 }, { 0x210001f2, 0x2000ffff }, { 0x210001f3, 0x1400fffe }, { 0x210001f4, 0x24000001 }, { 0x210001f5, 0x1400ffff }, { 0x210001f6, 0x2400ff9f }, { 0x210001f7, 0x2400ffc8 }, { 0x210001f8, 0x24000001 }, { 0x210001f9, 0x1400ffff }, { 0x210001fa, 0x24000001 }, { 0x210001fb, 0x1400ffff }, { 0x210001fc, 0x24000001 }, { 0x210001fd, 0x1400ffff }, { 0x210001fe, 0x24000001 }, { 0x210001ff, 0x1400ffff }, { 0x21000200, 0x24000001 }, { 0x21000201, 0x1400ffff }, { 0x21000202, 0x24000001 }, { 0x21000203, 0x1400ffff }, { 0x21000204, 0x24000001 }, { 0x21000205, 0x1400ffff }, { 0x21000206, 0x24000001 }, { 0x21000207, 0x1400ffff }, { 0x21000208, 0x24000001 }, { 0x21000209, 0x1400ffff }, { 0x2100020a, 0x24000001 }, { 0x2100020b, 0x1400ffff }, { 0x2100020c, 0x24000001 }, { 0x2100020d, 0x1400ffff }, { 0x2100020e, 0x24000001 }, { 0x2100020f, 0x1400ffff }, { 0x21000210, 0x24000001 }, { 0x21000211, 0x1400ffff }, { 0x21000212, 0x24000001 }, { 0x21000213, 0x1400ffff }, { 0x21000214, 0x24000001 }, { 0x21000215, 0x1400ffff }, { 0x21000216, 0x24000001 }, { 0x21000217, 0x1400ffff }, { 0x21000218, 0x24000001 }, { 0x21000219, 0x1400ffff }, { 0x2100021a, 0x24000001 }, { 0x2100021b, 0x1400ffff }, { 0x2100021c, 0x24000001 }, { 0x2100021d, 0x1400ffff }, { 0x2100021e, 0x24000001 }, { 0x2100021f, 0x1400ffff }, { 0x21000220, 0x2400ff7e }, { 0x21000221, 0x14000000 }, { 0x21000222, 0x24000001 }, { 0x21000223, 0x1400ffff }, { 0x21000224, 0x24000001 }, { 0x21000225, 0x1400ffff }, { 0x21000226, 0x24000001 }, { 0x21000227, 0x1400ffff }, { 0x21000228, 0x24000001 }, { 0x21000229, 0x1400ffff }, { 0x2100022a, 0x24000001 }, { 0x2100022b, 0x1400ffff }, { 0x2100022c, 0x24000001 }, { 0x2100022d, 0x1400ffff }, { 0x2100022e, 0x24000001 }, { 0x2100022f, 0x1400ffff }, { 0x21000230, 0x24000001 }, { 0x21000231, 0x1400ffff }, { 0x21000232, 0x24000001 }, { 0x21000233, 0x1400ffff }, { 0x21800234, 0x14000005 }, { 0x2100023a, 0x24002a2b }, { 0x2100023b, 0x24000001 }, { 0x2100023c, 0x1400ffff }, { 0x2100023d, 0x2400ff5d }, { 0x2100023e, 0x24002a28 }, { 0x2180023f, 0x14000001 }, { 0x21000241, 0x24000001 }, { 0x21000242, 0x1400ffff }, { 0x21000243, 0x2400ff3d }, { 0x21000244, 0x24000045 }, { 0x21000245, 0x24000047 }, { 0x21000246, 0x24000001 }, { 0x21000247, 0x1400ffff }, { 0x21000248, 0x24000001 }, { 0x21000249, 0x1400ffff }, { 0x2100024a, 0x24000001 }, { 0x2100024b, 0x1400ffff }, { 0x2100024c, 0x24000001 }, { 0x2100024d, 0x1400ffff }, { 0x2100024e, 0x24000001 }, { 0x2100024f, 0x1400ffff }, { 0x21800250, 0x14000002 }, { 0x21000253, 0x1400ff2e }, { 0x21000254, 0x1400ff32 }, { 0x21000255, 0x14000000 }, { 0x21000256, 0x1400ff33 }, { 0x21000257, 0x1400ff33 }, { 0x21000258, 0x14000000 }, { 0x21000259, 0x1400ff36 }, { 0x2100025a, 0x14000000 }, { 0x2100025b, 0x1400ff35 }, { 0x2180025c, 0x14000003 }, { 0x21000260, 0x1400ff33 }, { 0x21800261, 0x14000001 }, { 0x21000263, 0x1400ff31 }, { 0x21800264, 0x14000003 }, { 0x21000268, 0x1400ff2f }, { 0x21000269, 0x1400ff2d }, { 0x2100026a, 0x14000000 }, { 0x2100026b, 0x140029f7 }, { 0x2180026c, 0x14000002 }, { 0x2100026f, 0x1400ff2d }, { 0x21800270, 0x14000001 }, { 0x21000272, 0x1400ff2b }, { 0x21800273, 0x14000001 }, { 0x21000275, 0x1400ff2a }, { 0x21800276, 0x14000006 }, { 0x2100027d, 0x140029e7 }, { 0x2180027e, 0x14000001 }, { 0x21000280, 0x1400ff26 }, { 0x21800281, 0x14000001 }, { 0x21000283, 0x1400ff26 }, { 0x21800284, 0x14000003 }, { 0x21000288, 0x1400ff26 }, { 0x21000289, 0x1400ffbb }, { 0x2100028a, 0x1400ff27 }, { 0x2100028b, 0x1400ff27 }, { 0x2100028c, 0x1400ffb9 }, { 0x2180028d, 0x14000004 }, { 0x21000292, 0x1400ff25 }, { 0x21000293, 0x14000000 }, { 0x21000294, 0x1c000000 }, { 0x21800295, 0x1400001a }, { 0x218002b0, 0x18000011 }, { 0x098002c2, 0x60000003 }, { 0x098002c6, 0x1800000b }, { 0x098002d2, 0x6000000d }, { 0x218002e0, 0x18000004 }, { 0x098002e5, 0x60000008 }, { 0x090002ee, 0x18000000 }, { 0x098002ef, 0x60000010 }, { 0x1b800300, 0x30000044 }, { 0x1b000345, 0x30000054 }, { 0x1b800346, 0x30000029 }, { 0x13800374, 0x60000001 }, { 0x1300037a, 0x18000000 }, { 0x1300037b, 0x14000082 }, { 0x1300037c, 0x14000082 }, { 0x1300037d, 0x14000082 }, { 0x0900037e, 0x54000000 }, { 0x13800384, 0x60000001 }, { 0x13000386, 0x24000026 }, { 0x09000387, 0x54000000 }, { 0x13000388, 0x24000025 }, { 0x13000389, 0x24000025 }, { 0x1300038a, 0x24000025 }, { 0x1300038c, 0x24000040 }, { 0x1300038e, 0x2400003f }, { 0x1300038f, 0x2400003f }, { 0x13000390, 0x14000000 }, { 0x13000391, 0x24000020 }, { 0x13000392, 0x24000020 }, { 0x13000393, 0x24000020 }, { 0x13000394, 0x24000020 }, { 0x13000395, 0x24000020 }, { 0x13000396, 0x24000020 }, { 0x13000397, 0x24000020 }, { 0x13000398, 0x24000020 }, { 0x13000399, 0x24000020 }, { 0x1300039a, 0x24000020 }, { 0x1300039b, 0x24000020 }, { 0x1300039c, 0x24000020 }, { 0x1300039d, 0x24000020 }, { 0x1300039e, 0x24000020 }, { 0x1300039f, 0x24000020 }, { 0x130003a0, 0x24000020 }, { 0x130003a1, 0x24000020 }, { 0x130003a3, 0x24000020 }, { 0x130003a4, 0x24000020 }, { 0x130003a5, 0x24000020 }, { 0x130003a6, 0x24000020 }, { 0x130003a7, 0x24000020 }, { 0x130003a8, 0x24000020 }, { 0x130003a9, 0x24000020 }, { 0x130003aa, 0x24000020 }, { 0x130003ab, 0x24000020 }, { 0x130003ac, 0x1400ffda }, { 0x130003ad, 0x1400ffdb }, { 0x130003ae, 0x1400ffdb }, { 0x130003af, 0x1400ffdb }, { 0x130003b0, 0x14000000 }, { 0x130003b1, 0x1400ffe0 }, { 0x130003b2, 0x1400ffe0 }, { 0x130003b3, 0x1400ffe0 }, { 0x130003b4, 0x1400ffe0 }, { 0x130003b5, 0x1400ffe0 }, { 0x130003b6, 0x1400ffe0 }, { 0x130003b7, 0x1400ffe0 }, { 0x130003b8, 0x1400ffe0 }, { 0x130003b9, 0x1400ffe0 }, { 0x130003ba, 0x1400ffe0 }, { 0x130003bb, 0x1400ffe0 }, { 0x130003bc, 0x1400ffe0 }, { 0x130003bd, 0x1400ffe0 }, { 0x130003be, 0x1400ffe0 }, { 0x130003bf, 0x1400ffe0 }, { 0x130003c0, 0x1400ffe0 }, { 0x130003c1, 0x1400ffe0 }, { 0x130003c2, 0x1400ffe1 }, { 0x130003c3, 0x1400ffe0 }, { 0x130003c4, 0x1400ffe0 }, { 0x130003c5, 0x1400ffe0 }, { 0x130003c6, 0x1400ffe0 }, { 0x130003c7, 0x1400ffe0 }, { 0x130003c8, 0x1400ffe0 }, { 0x130003c9, 0x1400ffe0 }, { 0x130003ca, 0x1400ffe0 }, { 0x130003cb, 0x1400ffe0 }, { 0x130003cc, 0x1400ffc0 }, { 0x130003cd, 0x1400ffc1 }, { 0x130003ce, 0x1400ffc1 }, { 0x130003d0, 0x1400ffc2 }, { 0x130003d1, 0x1400ffc7 }, { 0x138003d2, 0x24000002 }, { 0x130003d5, 0x1400ffd1 }, { 0x130003d6, 0x1400ffca }, { 0x130003d7, 0x14000000 }, { 0x130003d8, 0x24000001 }, { 0x130003d9, 0x1400ffff }, { 0x130003da, 0x24000001 }, { 0x130003db, 0x1400ffff }, { 0x130003dc, 0x24000001 }, { 0x130003dd, 0x1400ffff }, { 0x130003de, 0x24000001 }, { 0x130003df, 0x1400ffff }, { 0x130003e0, 0x24000001 }, { 0x130003e1, 0x1400ffff }, { 0x0a0003e2, 0x24000001 }, { 0x0a0003e3, 0x1400ffff }, { 0x0a0003e4, 0x24000001 }, { 0x0a0003e5, 0x1400ffff }, { 0x0a0003e6, 0x24000001 }, { 0x0a0003e7, 0x1400ffff }, { 0x0a0003e8, 0x24000001 }, { 0x0a0003e9, 0x1400ffff }, { 0x0a0003ea, 0x24000001 }, { 0x0a0003eb, 0x1400ffff }, { 0x0a0003ec, 0x24000001 }, { 0x0a0003ed, 0x1400ffff }, { 0x0a0003ee, 0x24000001 }, { 0x0a0003ef, 0x1400ffff }, { 0x130003f0, 0x1400ffaa }, { 0x130003f1, 0x1400ffb0 }, { 0x130003f2, 0x14000007 }, { 0x130003f3, 0x14000000 }, { 0x130003f4, 0x2400ffc4 }, { 0x130003f5, 0x1400ffa0 }, { 0x130003f6, 0x64000000 }, { 0x130003f7, 0x24000001 }, { 0x130003f8, 0x1400ffff }, { 0x130003f9, 0x2400fff9 }, { 0x130003fa, 0x24000001 }, { 0x130003fb, 0x1400ffff }, { 0x130003fc, 0x14000000 }, { 0x130003fd, 0x2400ff7e }, { 0x130003fe, 0x2400ff7e }, { 0x130003ff, 0x2400ff7e }, { 0x0c000400, 0x24000050 }, { 0x0c000401, 0x24000050 }, { 0x0c000402, 0x24000050 }, { 0x0c000403, 0x24000050 }, { 0x0c000404, 0x24000050 }, { 0x0c000405, 0x24000050 }, { 0x0c000406, 0x24000050 }, { 0x0c000407, 0x24000050 }, { 0x0c000408, 0x24000050 }, { 0x0c000409, 0x24000050 }, { 0x0c00040a, 0x24000050 }, { 0x0c00040b, 0x24000050 }, { 0x0c00040c, 0x24000050 }, { 0x0c00040d, 0x24000050 }, { 0x0c00040e, 0x24000050 }, { 0x0c00040f, 0x24000050 }, { 0x0c000410, 0x24000020 }, { 0x0c000411, 0x24000020 }, { 0x0c000412, 0x24000020 }, { 0x0c000413, 0x24000020 }, { 0x0c000414, 0x24000020 }, { 0x0c000415, 0x24000020 }, { 0x0c000416, 0x24000020 }, { 0x0c000417, 0x24000020 }, { 0x0c000418, 0x24000020 }, { 0x0c000419, 0x24000020 }, { 0x0c00041a, 0x24000020 }, { 0x0c00041b, 0x24000020 }, { 0x0c00041c, 0x24000020 }, { 0x0c00041d, 0x24000020 }, { 0x0c00041e, 0x24000020 }, { 0x0c00041f, 0x24000020 }, { 0x0c000420, 0x24000020 }, { 0x0c000421, 0x24000020 }, { 0x0c000422, 0x24000020 }, { 0x0c000423, 0x24000020 }, { 0x0c000424, 0x24000020 }, { 0x0c000425, 0x24000020 }, { 0x0c000426, 0x24000020 }, { 0x0c000427, 0x24000020 }, { 0x0c000428, 0x24000020 }, { 0x0c000429, 0x24000020 }, { 0x0c00042a, 0x24000020 }, { 0x0c00042b, 0x24000020 }, { 0x0c00042c, 0x24000020 }, { 0x0c00042d, 0x24000020 }, { 0x0c00042e, 0x24000020 }, { 0x0c00042f, 0x24000020 }, { 0x0c000430, 0x1400ffe0 }, { 0x0c000431, 0x1400ffe0 }, { 0x0c000432, 0x1400ffe0 }, { 0x0c000433, 0x1400ffe0 }, { 0x0c000434, 0x1400ffe0 }, { 0x0c000435, 0x1400ffe0 }, { 0x0c000436, 0x1400ffe0 }, { 0x0c000437, 0x1400ffe0 }, { 0x0c000438, 0x1400ffe0 }, { 0x0c000439, 0x1400ffe0 }, { 0x0c00043a, 0x1400ffe0 }, { 0x0c00043b, 0x1400ffe0 }, { 0x0c00043c, 0x1400ffe0 }, { 0x0c00043d, 0x1400ffe0 }, { 0x0c00043e, 0x1400ffe0 }, { 0x0c00043f, 0x1400ffe0 }, { 0x0c000440, 0x1400ffe0 }, { 0x0c000441, 0x1400ffe0 }, { 0x0c000442, 0x1400ffe0 }, { 0x0c000443, 0x1400ffe0 }, { 0x0c000444, 0x1400ffe0 }, { 0x0c000445, 0x1400ffe0 }, { 0x0c000446, 0x1400ffe0 }, { 0x0c000447, 0x1400ffe0 }, { 0x0c000448, 0x1400ffe0 }, { 0x0c000449, 0x1400ffe0 }, { 0x0c00044a, 0x1400ffe0 }, { 0x0c00044b, 0x1400ffe0 }, { 0x0c00044c, 0x1400ffe0 }, { 0x0c00044d, 0x1400ffe0 }, { 0x0c00044e, 0x1400ffe0 }, { 0x0c00044f, 0x1400ffe0 }, { 0x0c000450, 0x1400ffb0 }, { 0x0c000451, 0x1400ffb0 }, { 0x0c000452, 0x1400ffb0 }, { 0x0c000453, 0x1400ffb0 }, { 0x0c000454, 0x1400ffb0 }, { 0x0c000455, 0x1400ffb0 }, { 0x0c000456, 0x1400ffb0 }, { 0x0c000457, 0x1400ffb0 }, { 0x0c000458, 0x1400ffb0 }, { 0x0c000459, 0x1400ffb0 }, { 0x0c00045a, 0x1400ffb0 }, { 0x0c00045b, 0x1400ffb0 }, { 0x0c00045c, 0x1400ffb0 }, { 0x0c00045d, 0x1400ffb0 }, { 0x0c00045e, 0x1400ffb0 }, { 0x0c00045f, 0x1400ffb0 }, { 0x0c000460, 0x24000001 }, { 0x0c000461, 0x1400ffff }, { 0x0c000462, 0x24000001 }, { 0x0c000463, 0x1400ffff }, { 0x0c000464, 0x24000001 }, { 0x0c000465, 0x1400ffff }, { 0x0c000466, 0x24000001 }, { 0x0c000467, 0x1400ffff }, { 0x0c000468, 0x24000001 }, { 0x0c000469, 0x1400ffff }, { 0x0c00046a, 0x24000001 }, { 0x0c00046b, 0x1400ffff }, { 0x0c00046c, 0x24000001 }, { 0x0c00046d, 0x1400ffff }, { 0x0c00046e, 0x24000001 }, { 0x0c00046f, 0x1400ffff }, { 0x0c000470, 0x24000001 }, { 0x0c000471, 0x1400ffff }, { 0x0c000472, 0x24000001 }, { 0x0c000473, 0x1400ffff }, { 0x0c000474, 0x24000001 }, { 0x0c000475, 0x1400ffff }, { 0x0c000476, 0x24000001 }, { 0x0c000477, 0x1400ffff }, { 0x0c000478, 0x24000001 }, { 0x0c000479, 0x1400ffff }, { 0x0c00047a, 0x24000001 }, { 0x0c00047b, 0x1400ffff }, { 0x0c00047c, 0x24000001 }, { 0x0c00047d, 0x1400ffff }, { 0x0c00047e, 0x24000001 }, { 0x0c00047f, 0x1400ffff }, { 0x0c000480, 0x24000001 }, { 0x0c000481, 0x1400ffff }, { 0x0c000482, 0x68000000 }, { 0x0c800483, 0x30000003 }, { 0x0c800488, 0x2c000001 }, { 0x0c00048a, 0x24000001 }, { 0x0c00048b, 0x1400ffff }, { 0x0c00048c, 0x24000001 }, { 0x0c00048d, 0x1400ffff }, { 0x0c00048e, 0x24000001 }, { 0x0c00048f, 0x1400ffff }, { 0x0c000490, 0x24000001 }, { 0x0c000491, 0x1400ffff }, { 0x0c000492, 0x24000001 }, { 0x0c000493, 0x1400ffff }, { 0x0c000494, 0x24000001 }, { 0x0c000495, 0x1400ffff }, { 0x0c000496, 0x24000001 }, { 0x0c000497, 0x1400ffff }, { 0x0c000498, 0x24000001 }, { 0x0c000499, 0x1400ffff }, { 0x0c00049a, 0x24000001 }, { 0x0c00049b, 0x1400ffff }, { 0x0c00049c, 0x24000001 }, { 0x0c00049d, 0x1400ffff }, { 0x0c00049e, 0x24000001 }, { 0x0c00049f, 0x1400ffff }, { 0x0c0004a0, 0x24000001 }, { 0x0c0004a1, 0x1400ffff }, { 0x0c0004a2, 0x24000001 }, { 0x0c0004a3, 0x1400ffff }, { 0x0c0004a4, 0x24000001 }, { 0x0c0004a5, 0x1400ffff }, { 0x0c0004a6, 0x24000001 }, { 0x0c0004a7, 0x1400ffff }, { 0x0c0004a8, 0x24000001 }, { 0x0c0004a9, 0x1400ffff }, { 0x0c0004aa, 0x24000001 }, { 0x0c0004ab, 0x1400ffff }, { 0x0c0004ac, 0x24000001 }, { 0x0c0004ad, 0x1400ffff }, { 0x0c0004ae, 0x24000001 }, { 0x0c0004af, 0x1400ffff }, { 0x0c0004b0, 0x24000001 }, { 0x0c0004b1, 0x1400ffff }, { 0x0c0004b2, 0x24000001 }, { 0x0c0004b3, 0x1400ffff }, { 0x0c0004b4, 0x24000001 }, { 0x0c0004b5, 0x1400ffff }, { 0x0c0004b6, 0x24000001 }, { 0x0c0004b7, 0x1400ffff }, { 0x0c0004b8, 0x24000001 }, { 0x0c0004b9, 0x1400ffff }, { 0x0c0004ba, 0x24000001 }, { 0x0c0004bb, 0x1400ffff }, { 0x0c0004bc, 0x24000001 }, { 0x0c0004bd, 0x1400ffff }, { 0x0c0004be, 0x24000001 }, { 0x0c0004bf, 0x1400ffff }, { 0x0c0004c0, 0x2400000f }, { 0x0c0004c1, 0x24000001 }, { 0x0c0004c2, 0x1400ffff }, { 0x0c0004c3, 0x24000001 }, { 0x0c0004c4, 0x1400ffff }, { 0x0c0004c5, 0x24000001 }, { 0x0c0004c6, 0x1400ffff }, { 0x0c0004c7, 0x24000001 }, { 0x0c0004c8, 0x1400ffff }, { 0x0c0004c9, 0x24000001 }, { 0x0c0004ca, 0x1400ffff }, { 0x0c0004cb, 0x24000001 }, { 0x0c0004cc, 0x1400ffff }, { 0x0c0004cd, 0x24000001 }, { 0x0c0004ce, 0x1400ffff }, { 0x0c0004cf, 0x1400fff1 }, { 0x0c0004d0, 0x24000001 }, { 0x0c0004d1, 0x1400ffff }, { 0x0c0004d2, 0x24000001 }, { 0x0c0004d3, 0x1400ffff }, { 0x0c0004d4, 0x24000001 }, { 0x0c0004d5, 0x1400ffff }, { 0x0c0004d6, 0x24000001 }, { 0x0c0004d7, 0x1400ffff }, { 0x0c0004d8, 0x24000001 }, { 0x0c0004d9, 0x1400ffff }, { 0x0c0004da, 0x24000001 }, { 0x0c0004db, 0x1400ffff }, { 0x0c0004dc, 0x24000001 }, { 0x0c0004dd, 0x1400ffff }, { 0x0c0004de, 0x24000001 }, { 0x0c0004df, 0x1400ffff }, { 0x0c0004e0, 0x24000001 }, { 0x0c0004e1, 0x1400ffff }, { 0x0c0004e2, 0x24000001 }, { 0x0c0004e3, 0x1400ffff }, { 0x0c0004e4, 0x24000001 }, { 0x0c0004e5, 0x1400ffff }, { 0x0c0004e6, 0x24000001 }, { 0x0c0004e7, 0x1400ffff }, { 0x0c0004e8, 0x24000001 }, { 0x0c0004e9, 0x1400ffff }, { 0x0c0004ea, 0x24000001 }, { 0x0c0004eb, 0x1400ffff }, { 0x0c0004ec, 0x24000001 }, { 0x0c0004ed, 0x1400ffff }, { 0x0c0004ee, 0x24000001 }, { 0x0c0004ef, 0x1400ffff }, { 0x0c0004f0, 0x24000001 }, { 0x0c0004f1, 0x1400ffff }, { 0x0c0004f2, 0x24000001 }, { 0x0c0004f3, 0x1400ffff }, { 0x0c0004f4, 0x24000001 }, { 0x0c0004f5, 0x1400ffff }, { 0x0c0004f6, 0x24000001 }, { 0x0c0004f7, 0x1400ffff }, { 0x0c0004f8, 0x24000001 }, { 0x0c0004f9, 0x1400ffff }, { 0x0c0004fa, 0x24000001 }, { 0x0c0004fb, 0x1400ffff }, { 0x0c0004fc, 0x24000001 }, { 0x0c0004fd, 0x1400ffff }, { 0x0c0004fe, 0x24000001 }, { 0x0c0004ff, 0x1400ffff }, { 0x0c000500, 0x24000001 }, { 0x0c000501, 0x1400ffff }, { 0x0c000502, 0x24000001 }, { 0x0c000503, 0x1400ffff }, { 0x0c000504, 0x24000001 }, { 0x0c000505, 0x1400ffff }, { 0x0c000506, 0x24000001 }, { 0x0c000507, 0x1400ffff }, { 0x0c000508, 0x24000001 }, { 0x0c000509, 0x1400ffff }, { 0x0c00050a, 0x24000001 }, { 0x0c00050b, 0x1400ffff }, { 0x0c00050c, 0x24000001 }, { 0x0c00050d, 0x1400ffff }, { 0x0c00050e, 0x24000001 }, { 0x0c00050f, 0x1400ffff }, { 0x0c000510, 0x24000001 }, { 0x0c000511, 0x1400ffff }, { 0x0c000512, 0x24000001 }, { 0x0c000513, 0x1400ffff }, { 0x01000531, 0x24000030 }, { 0x01000532, 0x24000030 }, { 0x01000533, 0x24000030 }, { 0x01000534, 0x24000030 }, { 0x01000535, 0x24000030 }, { 0x01000536, 0x24000030 }, { 0x01000537, 0x24000030 }, { 0x01000538, 0x24000030 }, { 0x01000539, 0x24000030 }, { 0x0100053a, 0x24000030 }, { 0x0100053b, 0x24000030 }, { 0x0100053c, 0x24000030 }, { 0x0100053d, 0x24000030 }, { 0x0100053e, 0x24000030 }, { 0x0100053f, 0x24000030 }, { 0x01000540, 0x24000030 }, { 0x01000541, 0x24000030 }, { 0x01000542, 0x24000030 }, { 0x01000543, 0x24000030 }, { 0x01000544, 0x24000030 }, { 0x01000545, 0x24000030 }, { 0x01000546, 0x24000030 }, { 0x01000547, 0x24000030 }, { 0x01000548, 0x24000030 }, { 0x01000549, 0x24000030 }, { 0x0100054a, 0x24000030 }, { 0x0100054b, 0x24000030 }, { 0x0100054c, 0x24000030 }, { 0x0100054d, 0x24000030 }, { 0x0100054e, 0x24000030 }, { 0x0100054f, 0x24000030 }, { 0x01000550, 0x24000030 }, { 0x01000551, 0x24000030 }, { 0x01000552, 0x24000030 }, { 0x01000553, 0x24000030 }, { 0x01000554, 0x24000030 }, { 0x01000555, 0x24000030 }, { 0x01000556, 0x24000030 }, { 0x01000559, 0x18000000 }, { 0x0180055a, 0x54000005 }, { 0x01000561, 0x1400ffd0 }, { 0x01000562, 0x1400ffd0 }, { 0x01000563, 0x1400ffd0 }, { 0x01000564, 0x1400ffd0 }, { 0x01000565, 0x1400ffd0 }, { 0x01000566, 0x1400ffd0 }, { 0x01000567, 0x1400ffd0 }, { 0x01000568, 0x1400ffd0 }, { 0x01000569, 0x1400ffd0 }, { 0x0100056a, 0x1400ffd0 }, { 0x0100056b, 0x1400ffd0 }, { 0x0100056c, 0x1400ffd0 }, { 0x0100056d, 0x1400ffd0 }, { 0x0100056e, 0x1400ffd0 }, { 0x0100056f, 0x1400ffd0 }, { 0x01000570, 0x1400ffd0 }, { 0x01000571, 0x1400ffd0 }, { 0x01000572, 0x1400ffd0 }, { 0x01000573, 0x1400ffd0 }, { 0x01000574, 0x1400ffd0 }, { 0x01000575, 0x1400ffd0 }, { 0x01000576, 0x1400ffd0 }, { 0x01000577, 0x1400ffd0 }, { 0x01000578, 0x1400ffd0 }, { 0x01000579, 0x1400ffd0 }, { 0x0100057a, 0x1400ffd0 }, { 0x0100057b, 0x1400ffd0 }, { 0x0100057c, 0x1400ffd0 }, { 0x0100057d, 0x1400ffd0 }, { 0x0100057e, 0x1400ffd0 }, { 0x0100057f, 0x1400ffd0 }, { 0x01000580, 0x1400ffd0 }, { 0x01000581, 0x1400ffd0 }, { 0x01000582, 0x1400ffd0 }, { 0x01000583, 0x1400ffd0 }, { 0x01000584, 0x1400ffd0 }, { 0x01000585, 0x1400ffd0 }, { 0x01000586, 0x1400ffd0 }, { 0x01000587, 0x14000000 }, { 0x09000589, 0x54000000 }, { 0x0100058a, 0x44000000 }, { 0x19800591, 0x3000002c }, { 0x190005be, 0x54000000 }, { 0x190005bf, 0x30000000 }, { 0x190005c0, 0x54000000 }, { 0x198005c1, 0x30000001 }, { 0x190005c3, 0x54000000 }, { 0x198005c4, 0x30000001 }, { 0x190005c6, 0x54000000 }, { 0x190005c7, 0x30000000 }, { 0x198005d0, 0x1c00001a }, { 0x198005f0, 0x1c000002 }, { 0x198005f3, 0x54000001 }, { 0x09800600, 0x04000003 }, { 0x0000060b, 0x5c000000 }, { 0x0980060c, 0x54000001 }, { 0x0080060e, 0x68000001 }, { 0x00800610, 0x30000005 }, { 0x0900061b, 0x54000000 }, { 0x0080061e, 0x54000001 }, { 0x00800621, 0x1c000019 }, { 0x09000640, 0x18000000 }, { 0x00800641, 0x1c000009 }, { 0x1b80064b, 0x30000013 }, { 0x09800660, 0x34000009 }, { 0x0080066a, 0x54000003 }, { 0x0080066e, 0x1c000001 }, { 0x1b000670, 0x30000000 }, { 0x00800671, 0x1c000062 }, { 0x000006d4, 0x54000000 }, { 0x000006d5, 0x1c000000 }, { 0x008006d6, 0x30000006 }, { 0x090006dd, 0x04000000 }, { 0x000006de, 0x2c000000 }, { 0x008006df, 0x30000005 }, { 0x008006e5, 0x18000001 }, { 0x008006e7, 0x30000001 }, { 0x000006e9, 0x68000000 }, { 0x008006ea, 0x30000003 }, { 0x008006ee, 0x1c000001 }, { 0x008006f0, 0x34000009 }, { 0x008006fa, 0x1c000002 }, { 0x008006fd, 0x68000001 }, { 0x000006ff, 0x1c000000 }, { 0x31800700, 0x5400000d }, { 0x3100070f, 0x04000000 }, { 0x31000710, 0x1c000000 }, { 0x31000711, 0x30000000 }, { 0x31800712, 0x1c00001d }, { 0x31800730, 0x3000001a }, { 0x3180074d, 0x1c000020 }, { 0x37800780, 0x1c000025 }, { 0x378007a6, 0x3000000a }, { 0x370007b1, 0x1c000000 }, { 0x3f8007c0, 0x34000009 }, { 0x3f8007ca, 0x1c000020 }, { 0x3f8007eb, 0x30000008 }, { 0x3f8007f4, 0x18000001 }, { 0x3f0007f6, 0x68000000 }, { 0x3f8007f7, 0x54000002 }, { 0x3f0007fa, 0x18000000 }, { 0x0e800901, 0x30000001 }, { 0x0e000903, 0x28000000 }, { 0x0e800904, 0x1c000035 }, { 0x0e00093c, 0x30000000 }, { 0x0e00093d, 0x1c000000 }, { 0x0e80093e, 0x28000002 }, { 0x0e800941, 0x30000007 }, { 0x0e800949, 0x28000003 }, { 0x0e00094d, 0x30000000 }, { 0x0e000950, 0x1c000000 }, { 0x0e800951, 0x30000003 }, { 0x0e800958, 0x1c000009 }, { 0x0e800962, 0x30000001 }, { 0x09800964, 0x54000001 }, { 0x0e800966, 0x34000009 }, { 0x09000970, 0x54000000 }, { 0x0e80097b, 0x1c000004 }, { 0x02000981, 0x30000000 }, { 0x02800982, 0x28000001 }, { 0x02800985, 0x1c000007 }, { 0x0280098f, 0x1c000001 }, { 0x02800993, 0x1c000015 }, { 0x028009aa, 0x1c000006 }, { 0x020009b2, 0x1c000000 }, { 0x028009b6, 0x1c000003 }, { 0x020009bc, 0x30000000 }, { 0x020009bd, 0x1c000000 }, { 0x028009be, 0x28000002 }, { 0x028009c1, 0x30000003 }, { 0x028009c7, 0x28000001 }, { 0x028009cb, 0x28000001 }, { 0x020009cd, 0x30000000 }, { 0x020009ce, 0x1c000000 }, { 0x020009d7, 0x28000000 }, { 0x028009dc, 0x1c000001 }, { 0x028009df, 0x1c000002 }, { 0x028009e2, 0x30000001 }, { 0x028009e6, 0x34000009 }, { 0x028009f0, 0x1c000001 }, { 0x028009f2, 0x5c000001 }, { 0x028009f4, 0x3c000005 }, { 0x020009fa, 0x68000000 }, { 0x15800a01, 0x30000001 }, { 0x15000a03, 0x28000000 }, { 0x15800a05, 0x1c000005 }, { 0x15800a0f, 0x1c000001 }, { 0x15800a13, 0x1c000015 }, { 0x15800a2a, 0x1c000006 }, { 0x15800a32, 0x1c000001 }, { 0x15800a35, 0x1c000001 }, { 0x15800a38, 0x1c000001 }, { 0x15000a3c, 0x30000000 }, { 0x15800a3e, 0x28000002 }, { 0x15800a41, 0x30000001 }, { 0x15800a47, 0x30000001 }, { 0x15800a4b, 0x30000002 }, { 0x15800a59, 0x1c000003 }, { 0x15000a5e, 0x1c000000 }, { 0x15800a66, 0x34000009 }, { 0x15800a70, 0x30000001 }, { 0x15800a72, 0x1c000002 }, { 0x14800a81, 0x30000001 }, { 0x14000a83, 0x28000000 }, { 0x14800a85, 0x1c000008 }, { 0x14800a8f, 0x1c000002 }, { 0x14800a93, 0x1c000015 }, { 0x14800aaa, 0x1c000006 }, { 0x14800ab2, 0x1c000001 }, { 0x14800ab5, 0x1c000004 }, { 0x14000abc, 0x30000000 }, { 0x14000abd, 0x1c000000 }, { 0x14800abe, 0x28000002 }, { 0x14800ac1, 0x30000004 }, { 0x14800ac7, 0x30000001 }, { 0x14000ac9, 0x28000000 }, { 0x14800acb, 0x28000001 }, { 0x14000acd, 0x30000000 }, { 0x14000ad0, 0x1c000000 }, { 0x14800ae0, 0x1c000001 }, { 0x14800ae2, 0x30000001 }, { 0x14800ae6, 0x34000009 }, { 0x14000af1, 0x5c000000 }, { 0x2b000b01, 0x30000000 }, { 0x2b800b02, 0x28000001 }, { 0x2b800b05, 0x1c000007 }, { 0x2b800b0f, 0x1c000001 }, { 0x2b800b13, 0x1c000015 }, { 0x2b800b2a, 0x1c000006 }, { 0x2b800b32, 0x1c000001 }, { 0x2b800b35, 0x1c000004 }, { 0x2b000b3c, 0x30000000 }, { 0x2b000b3d, 0x1c000000 }, { 0x2b000b3e, 0x28000000 }, { 0x2b000b3f, 0x30000000 }, { 0x2b000b40, 0x28000000 }, { 0x2b800b41, 0x30000002 }, { 0x2b800b47, 0x28000001 }, { 0x2b800b4b, 0x28000001 }, { 0x2b000b4d, 0x30000000 }, { 0x2b000b56, 0x30000000 }, { 0x2b000b57, 0x28000000 }, { 0x2b800b5c, 0x1c000001 }, { 0x2b800b5f, 0x1c000002 }, { 0x2b800b66, 0x34000009 }, { 0x2b000b70, 0x68000000 }, { 0x2b000b71, 0x1c000000 }, { 0x35000b82, 0x30000000 }, { 0x35000b83, 0x1c000000 }, { 0x35800b85, 0x1c000005 }, { 0x35800b8e, 0x1c000002 }, { 0x35800b92, 0x1c000003 }, { 0x35800b99, 0x1c000001 }, { 0x35000b9c, 0x1c000000 }, { 0x35800b9e, 0x1c000001 }, { 0x35800ba3, 0x1c000001 }, { 0x35800ba8, 0x1c000002 }, { 0x35800bae, 0x1c00000b }, { 0x35800bbe, 0x28000001 }, { 0x35000bc0, 0x30000000 }, { 0x35800bc1, 0x28000001 }, { 0x35800bc6, 0x28000002 }, { 0x35800bca, 0x28000002 }, { 0x35000bcd, 0x30000000 }, { 0x35000bd7, 0x28000000 }, { 0x35800be6, 0x34000009 }, { 0x35800bf0, 0x3c000002 }, { 0x35800bf3, 0x68000005 }, { 0x35000bf9, 0x5c000000 }, { 0x35000bfa, 0x68000000 }, { 0x36800c01, 0x28000002 }, { 0x36800c05, 0x1c000007 }, { 0x36800c0e, 0x1c000002 }, { 0x36800c12, 0x1c000016 }, { 0x36800c2a, 0x1c000009 }, { 0x36800c35, 0x1c000004 }, { 0x36800c3e, 0x30000002 }, { 0x36800c41, 0x28000003 }, { 0x36800c46, 0x30000002 }, { 0x36800c4a, 0x30000003 }, { 0x36800c55, 0x30000001 }, { 0x36800c60, 0x1c000001 }, { 0x36800c66, 0x34000009 }, { 0x1c800c82, 0x28000001 }, { 0x1c800c85, 0x1c000007 }, { 0x1c800c8e, 0x1c000002 }, { 0x1c800c92, 0x1c000016 }, { 0x1c800caa, 0x1c000009 }, { 0x1c800cb5, 0x1c000004 }, { 0x1c000cbc, 0x30000000 }, { 0x1c000cbd, 0x1c000000 }, { 0x1c000cbe, 0x28000000 }, { 0x1c000cbf, 0x30000000 }, { 0x1c800cc0, 0x28000004 }, { 0x1c000cc6, 0x30000000 }, { 0x1c800cc7, 0x28000001 }, { 0x1c800cca, 0x28000001 }, { 0x1c800ccc, 0x30000001 }, { 0x1c800cd5, 0x28000001 }, { 0x1c000cde, 0x1c000000 }, { 0x1c800ce0, 0x1c000001 }, { 0x1c800ce2, 0x30000001 }, { 0x1c800ce6, 0x34000009 }, { 0x1c800cf1, 0x68000001 }, { 0x24800d02, 0x28000001 }, { 0x24800d05, 0x1c000007 }, { 0x24800d0e, 0x1c000002 }, { 0x24800d12, 0x1c000016 }, { 0x24800d2a, 0x1c00000f }, { 0x24800d3e, 0x28000002 }, { 0x24800d41, 0x30000002 }, { 0x24800d46, 0x28000002 }, { 0x24800d4a, 0x28000002 }, { 0x24000d4d, 0x30000000 }, { 0x24000d57, 0x28000000 }, { 0x24800d60, 0x1c000001 }, { 0x24800d66, 0x34000009 }, { 0x2f800d82, 0x28000001 }, { 0x2f800d85, 0x1c000011 }, { 0x2f800d9a, 0x1c000017 }, { 0x2f800db3, 0x1c000008 }, { 0x2f000dbd, 0x1c000000 }, { 0x2f800dc0, 0x1c000006 }, { 0x2f000dca, 0x30000000 }, { 0x2f800dcf, 0x28000002 }, { 0x2f800dd2, 0x30000002 }, { 0x2f000dd6, 0x30000000 }, { 0x2f800dd8, 0x28000007 }, { 0x2f800df2, 0x28000001 }, { 0x2f000df4, 0x54000000 }, { 0x38800e01, 0x1c00002f }, { 0x38000e31, 0x30000000 }, { 0x38800e32, 0x1c000001 }, { 0x38800e34, 0x30000006 }, { 0x09000e3f, 0x5c000000 }, { 0x38800e40, 0x1c000005 }, { 0x38000e46, 0x18000000 }, { 0x38800e47, 0x30000007 }, { 0x38000e4f, 0x54000000 }, { 0x38800e50, 0x34000009 }, { 0x38800e5a, 0x54000001 }, { 0x20800e81, 0x1c000001 }, { 0x20000e84, 0x1c000000 }, { 0x20800e87, 0x1c000001 }, { 0x20000e8a, 0x1c000000 }, { 0x20000e8d, 0x1c000000 }, { 0x20800e94, 0x1c000003 }, { 0x20800e99, 0x1c000006 }, { 0x20800ea1, 0x1c000002 }, { 0x20000ea5, 0x1c000000 }, { 0x20000ea7, 0x1c000000 }, { 0x20800eaa, 0x1c000001 }, { 0x20800ead, 0x1c000003 }, { 0x20000eb1, 0x30000000 }, { 0x20800eb2, 0x1c000001 }, { 0x20800eb4, 0x30000005 }, { 0x20800ebb, 0x30000001 }, { 0x20000ebd, 0x1c000000 }, { 0x20800ec0, 0x1c000004 }, { 0x20000ec6, 0x18000000 }, { 0x20800ec8, 0x30000005 }, { 0x20800ed0, 0x34000009 }, { 0x20800edc, 0x1c000001 }, { 0x39000f00, 0x1c000000 }, { 0x39800f01, 0x68000002 }, { 0x39800f04, 0x5400000e }, { 0x39800f13, 0x68000004 }, { 0x39800f18, 0x30000001 }, { 0x39800f1a, 0x68000005 }, { 0x39800f20, 0x34000009 }, { 0x39800f2a, 0x3c000009 }, { 0x39000f34, 0x68000000 }, { 0x39000f35, 0x30000000 }, { 0x39000f36, 0x68000000 }, { 0x39000f37, 0x30000000 }, { 0x39000f38, 0x68000000 }, { 0x39000f39, 0x30000000 }, { 0x39000f3a, 0x58000000 }, { 0x39000f3b, 0x48000000 }, { 0x39000f3c, 0x58000000 }, { 0x39000f3d, 0x48000000 }, { 0x39800f3e, 0x28000001 }, { 0x39800f40, 0x1c000007 }, { 0x39800f49, 0x1c000021 }, { 0x39800f71, 0x3000000d }, { 0x39000f7f, 0x28000000 }, { 0x39800f80, 0x30000004 }, { 0x39000f85, 0x54000000 }, { 0x39800f86, 0x30000001 }, { 0x39800f88, 0x1c000003 }, { 0x39800f90, 0x30000007 }, { 0x39800f99, 0x30000023 }, { 0x39800fbe, 0x68000007 }, { 0x39000fc6, 0x30000000 }, { 0x39800fc7, 0x68000005 }, { 0x39000fcf, 0x68000000 }, { 0x39800fd0, 0x54000001 }, { 0x26801000, 0x1c000021 }, { 0x26801023, 0x1c000004 }, { 0x26801029, 0x1c000001 }, { 0x2600102c, 0x28000000 }, { 0x2680102d, 0x30000003 }, { 0x26001031, 0x28000000 }, { 0x26001032, 0x30000000 }, { 0x26801036, 0x30000001 }, { 0x26001038, 0x28000000 }, { 0x26001039, 0x30000000 }, { 0x26801040, 0x34000009 }, { 0x2680104a, 0x54000005 }, { 0x26801050, 0x1c000005 }, { 0x26801056, 0x28000001 }, { 0x26801058, 0x30000001 }, { 0x100010a0, 0x24001c60 }, { 0x100010a1, 0x24001c60 }, { 0x100010a2, 0x24001c60 }, { 0x100010a3, 0x24001c60 }, { 0x100010a4, 0x24001c60 }, { 0x100010a5, 0x24001c60 }, { 0x100010a6, 0x24001c60 }, { 0x100010a7, 0x24001c60 }, { 0x100010a8, 0x24001c60 }, { 0x100010a9, 0x24001c60 }, { 0x100010aa, 0x24001c60 }, { 0x100010ab, 0x24001c60 }, { 0x100010ac, 0x24001c60 }, { 0x100010ad, 0x24001c60 }, { 0x100010ae, 0x24001c60 }, { 0x100010af, 0x24001c60 }, { 0x100010b0, 0x24001c60 }, { 0x100010b1, 0x24001c60 }, { 0x100010b2, 0x24001c60 }, { 0x100010b3, 0x24001c60 }, { 0x100010b4, 0x24001c60 }, { 0x100010b5, 0x24001c60 }, { 0x100010b6, 0x24001c60 }, { 0x100010b7, 0x24001c60 }, { 0x100010b8, 0x24001c60 }, { 0x100010b9, 0x24001c60 }, { 0x100010ba, 0x24001c60 }, { 0x100010bb, 0x24001c60 }, { 0x100010bc, 0x24001c60 }, { 0x100010bd, 0x24001c60 }, { 0x100010be, 0x24001c60 }, { 0x100010bf, 0x24001c60 }, { 0x100010c0, 0x24001c60 }, { 0x100010c1, 0x24001c60 }, { 0x100010c2, 0x24001c60 }, { 0x100010c3, 0x24001c60 }, { 0x100010c4, 0x24001c60 }, { 0x100010c5, 0x24001c60 }, { 0x108010d0, 0x1c00002a }, { 0x090010fb, 0x54000000 }, { 0x100010fc, 0x18000000 }, { 0x17801100, 0x1c000059 }, { 0x1780115f, 0x1c000043 }, { 0x178011a8, 0x1c000051 }, { 0x0f801200, 0x1c000048 }, { 0x0f80124a, 0x1c000003 }, { 0x0f801250, 0x1c000006 }, { 0x0f001258, 0x1c000000 }, { 0x0f80125a, 0x1c000003 }, { 0x0f801260, 0x1c000028 }, { 0x0f80128a, 0x1c000003 }, { 0x0f801290, 0x1c000020 }, { 0x0f8012b2, 0x1c000003 }, { 0x0f8012b8, 0x1c000006 }, { 0x0f0012c0, 0x1c000000 }, { 0x0f8012c2, 0x1c000003 }, { 0x0f8012c8, 0x1c00000e }, { 0x0f8012d8, 0x1c000038 }, { 0x0f801312, 0x1c000003 }, { 0x0f801318, 0x1c000042 }, { 0x0f00135f, 0x30000000 }, { 0x0f001360, 0x68000000 }, { 0x0f801361, 0x54000007 }, { 0x0f801369, 0x3c000013 }, { 0x0f801380, 0x1c00000f }, { 0x0f801390, 0x68000009 }, { 0x088013a0, 0x1c000054 }, { 0x07801401, 0x1c00026b }, { 0x0780166d, 0x54000001 }, { 0x0780166f, 0x1c000007 }, { 0x28001680, 0x74000000 }, { 0x28801681, 0x1c000019 }, { 0x2800169b, 0x58000000 }, { 0x2800169c, 0x48000000 }, { 0x2d8016a0, 0x1c00004a }, { 0x098016eb, 0x54000002 }, { 0x2d8016ee, 0x38000002 }, { 0x32801700, 0x1c00000c }, { 0x3280170e, 0x1c000003 }, { 0x32801712, 0x30000002 }, { 0x18801720, 0x1c000011 }, { 0x18801732, 0x30000002 }, { 0x09801735, 0x54000001 }, { 0x06801740, 0x1c000011 }, { 0x06801752, 0x30000001 }, { 0x33801760, 0x1c00000c }, { 0x3380176e, 0x1c000002 }, { 0x33801772, 0x30000001 }, { 0x1f801780, 0x1c000033 }, { 0x1f8017b4, 0x04000001 }, { 0x1f0017b6, 0x28000000 }, { 0x1f8017b7, 0x30000006 }, { 0x1f8017be, 0x28000007 }, { 0x1f0017c6, 0x30000000 }, { 0x1f8017c7, 0x28000001 }, { 0x1f8017c9, 0x3000000a }, { 0x1f8017d4, 0x54000002 }, { 0x1f0017d7, 0x18000000 }, { 0x1f8017d8, 0x54000002 }, { 0x1f0017db, 0x5c000000 }, { 0x1f0017dc, 0x1c000000 }, { 0x1f0017dd, 0x30000000 }, { 0x1f8017e0, 0x34000009 }, { 0x1f8017f0, 0x3c000009 }, { 0x25801800, 0x54000005 }, { 0x25001806, 0x44000000 }, { 0x25801807, 0x54000003 }, { 0x2580180b, 0x30000002 }, { 0x2500180e, 0x74000000 }, { 0x25801810, 0x34000009 }, { 0x25801820, 0x1c000022 }, { 0x25001843, 0x18000000 }, { 0x25801844, 0x1c000033 }, { 0x25801880, 0x1c000028 }, { 0x250018a9, 0x30000000 }, { 0x22801900, 0x1c00001c }, { 0x22801920, 0x30000002 }, { 0x22801923, 0x28000003 }, { 0x22801927, 0x30000001 }, { 0x22801929, 0x28000002 }, { 0x22801930, 0x28000001 }, { 0x22001932, 0x30000000 }, { 0x22801933, 0x28000005 }, { 0x22801939, 0x30000002 }, { 0x22001940, 0x68000000 }, { 0x22801944, 0x54000001 }, { 0x22801946, 0x34000009 }, { 0x34801950, 0x1c00001d }, { 0x34801970, 0x1c000004 }, { 0x27801980, 0x1c000029 }, { 0x278019b0, 0x28000010 }, { 0x278019c1, 0x1c000006 }, { 0x278019c8, 0x28000001 }, { 0x278019d0, 0x34000009 }, { 0x278019de, 0x54000001 }, { 0x1f8019e0, 0x6800001f }, { 0x05801a00, 0x1c000016 }, { 0x05801a17, 0x30000001 }, { 0x05801a19, 0x28000002 }, { 0x05801a1e, 0x54000001 }, { 0x3d801b00, 0x30000003 }, { 0x3d001b04, 0x28000000 }, { 0x3d801b05, 0x1c00002e }, { 0x3d001b34, 0x30000000 }, { 0x3d001b35, 0x28000000 }, { 0x3d801b36, 0x30000004 }, { 0x3d001b3b, 0x28000000 }, { 0x3d001b3c, 0x30000000 }, { 0x3d801b3d, 0x28000004 }, { 0x3d001b42, 0x30000000 }, { 0x3d801b43, 0x28000001 }, { 0x3d801b45, 0x1c000006 }, { 0x3d801b50, 0x34000009 }, { 0x3d801b5a, 0x54000006 }, { 0x3d801b61, 0x68000009 }, { 0x3d801b6b, 0x30000008 }, { 0x3d801b74, 0x68000008 }, { 0x21801d00, 0x1400002b }, { 0x21801d2c, 0x18000035 }, { 0x21801d62, 0x14000015 }, { 0x0c001d78, 0x18000000 }, { 0x21801d79, 0x14000003 }, { 0x21001d7d, 0x14000ee6 }, { 0x21801d7e, 0x1400001c }, { 0x21801d9b, 0x18000024 }, { 0x1b801dc0, 0x3000000a }, { 0x1b801dfe, 0x30000001 }, { 0x21001e00, 0x24000001 }, { 0x21001e01, 0x1400ffff }, { 0x21001e02, 0x24000001 }, { 0x21001e03, 0x1400ffff }, { 0x21001e04, 0x24000001 }, { 0x21001e05, 0x1400ffff }, { 0x21001e06, 0x24000001 }, { 0x21001e07, 0x1400ffff }, { 0x21001e08, 0x24000001 }, { 0x21001e09, 0x1400ffff }, { 0x21001e0a, 0x24000001 }, { 0x21001e0b, 0x1400ffff }, { 0x21001e0c, 0x24000001 }, { 0x21001e0d, 0x1400ffff }, { 0x21001e0e, 0x24000001 }, { 0x21001e0f, 0x1400ffff }, { 0x21001e10, 0x24000001 }, { 0x21001e11, 0x1400ffff }, { 0x21001e12, 0x24000001 }, { 0x21001e13, 0x1400ffff }, { 0x21001e14, 0x24000001 }, { 0x21001e15, 0x1400ffff }, { 0x21001e16, 0x24000001 }, { 0x21001e17, 0x1400ffff }, { 0x21001e18, 0x24000001 }, { 0x21001e19, 0x1400ffff }, { 0x21001e1a, 0x24000001 }, { 0x21001e1b, 0x1400ffff }, { 0x21001e1c, 0x24000001 }, { 0x21001e1d, 0x1400ffff }, { 0x21001e1e, 0x24000001 }, { 0x21001e1f, 0x1400ffff }, { 0x21001e20, 0x24000001 }, { 0x21001e21, 0x1400ffff }, { 0x21001e22, 0x24000001 }, { 0x21001e23, 0x1400ffff }, { 0x21001e24, 0x24000001 }, { 0x21001e25, 0x1400ffff }, { 0x21001e26, 0x24000001 }, { 0x21001e27, 0x1400ffff }, { 0x21001e28, 0x24000001 }, { 0x21001e29, 0x1400ffff }, { 0x21001e2a, 0x24000001 }, { 0x21001e2b, 0x1400ffff }, { 0x21001e2c, 0x24000001 }, { 0x21001e2d, 0x1400ffff }, { 0x21001e2e, 0x24000001 }, { 0x21001e2f, 0x1400ffff }, { 0x21001e30, 0x24000001 }, { 0x21001e31, 0x1400ffff }, { 0x21001e32, 0x24000001 }, { 0x21001e33, 0x1400ffff }, { 0x21001e34, 0x24000001 }, { 0x21001e35, 0x1400ffff }, { 0x21001e36, 0x24000001 }, { 0x21001e37, 0x1400ffff }, { 0x21001e38, 0x24000001 }, { 0x21001e39, 0x1400ffff }, { 0x21001e3a, 0x24000001 }, { 0x21001e3b, 0x1400ffff }, { 0x21001e3c, 0x24000001 }, { 0x21001e3d, 0x1400ffff }, { 0x21001e3e, 0x24000001 }, { 0x21001e3f, 0x1400ffff }, { 0x21001e40, 0x24000001 }, { 0x21001e41, 0x1400ffff }, { 0x21001e42, 0x24000001 }, { 0x21001e43, 0x1400ffff }, { 0x21001e44, 0x24000001 }, { 0x21001e45, 0x1400ffff }, { 0x21001e46, 0x24000001 }, { 0x21001e47, 0x1400ffff }, { 0x21001e48, 0x24000001 }, { 0x21001e49, 0x1400ffff }, { 0x21001e4a, 0x24000001 }, { 0x21001e4b, 0x1400ffff }, { 0x21001e4c, 0x24000001 }, { 0x21001e4d, 0x1400ffff }, { 0x21001e4e, 0x24000001 }, { 0x21001e4f, 0x1400ffff }, { 0x21001e50, 0x24000001 }, { 0x21001e51, 0x1400ffff }, { 0x21001e52, 0x24000001 }, { 0x21001e53, 0x1400ffff }, { 0x21001e54, 0x24000001 }, { 0x21001e55, 0x1400ffff }, { 0x21001e56, 0x24000001 }, { 0x21001e57, 0x1400ffff }, { 0x21001e58, 0x24000001 }, { 0x21001e59, 0x1400ffff }, { 0x21001e5a, 0x24000001 }, { 0x21001e5b, 0x1400ffff }, { 0x21001e5c, 0x24000001 }, { 0x21001e5d, 0x1400ffff }, { 0x21001e5e, 0x24000001 }, { 0x21001e5f, 0x1400ffff }, { 0x21001e60, 0x24000001 }, { 0x21001e61, 0x1400ffff }, { 0x21001e62, 0x24000001 }, { 0x21001e63, 0x1400ffff }, { 0x21001e64, 0x24000001 }, { 0x21001e65, 0x1400ffff }, { 0x21001e66, 0x24000001 }, { 0x21001e67, 0x1400ffff }, { 0x21001e68, 0x24000001 }, { 0x21001e69, 0x1400ffff }, { 0x21001e6a, 0x24000001 }, { 0x21001e6b, 0x1400ffff }, { 0x21001e6c, 0x24000001 }, { 0x21001e6d, 0x1400ffff }, { 0x21001e6e, 0x24000001 }, { 0x21001e6f, 0x1400ffff }, { 0x21001e70, 0x24000001 }, { 0x21001e71, 0x1400ffff }, { 0x21001e72, 0x24000001 }, { 0x21001e73, 0x1400ffff }, { 0x21001e74, 0x24000001 }, { 0x21001e75, 0x1400ffff }, { 0x21001e76, 0x24000001 }, { 0x21001e77, 0x1400ffff }, { 0x21001e78, 0x24000001 }, { 0x21001e79, 0x1400ffff }, { 0x21001e7a, 0x24000001 }, { 0x21001e7b, 0x1400ffff }, { 0x21001e7c, 0x24000001 }, { 0x21001e7d, 0x1400ffff }, { 0x21001e7e, 0x24000001 }, { 0x21001e7f, 0x1400ffff }, { 0x21001e80, 0x24000001 }, { 0x21001e81, 0x1400ffff }, { 0x21001e82, 0x24000001 }, { 0x21001e83, 0x1400ffff }, { 0x21001e84, 0x24000001 }, { 0x21001e85, 0x1400ffff }, { 0x21001e86, 0x24000001 }, { 0x21001e87, 0x1400ffff }, { 0x21001e88, 0x24000001 }, { 0x21001e89, 0x1400ffff }, { 0x21001e8a, 0x24000001 }, { 0x21001e8b, 0x1400ffff }, { 0x21001e8c, 0x24000001 }, { 0x21001e8d, 0x1400ffff }, { 0x21001e8e, 0x24000001 }, { 0x21001e8f, 0x1400ffff }, { 0x21001e90, 0x24000001 }, { 0x21001e91, 0x1400ffff }, { 0x21001e92, 0x24000001 }, { 0x21001e93, 0x1400ffff }, { 0x21001e94, 0x24000001 }, { 0x21001e95, 0x1400ffff }, { 0x21801e96, 0x14000004 }, { 0x21001e9b, 0x1400ffc5 }, { 0x21001ea0, 0x24000001 }, { 0x21001ea1, 0x1400ffff }, { 0x21001ea2, 0x24000001 }, { 0x21001ea3, 0x1400ffff }, { 0x21001ea4, 0x24000001 }, { 0x21001ea5, 0x1400ffff }, { 0x21001ea6, 0x24000001 }, { 0x21001ea7, 0x1400ffff }, { 0x21001ea8, 0x24000001 }, { 0x21001ea9, 0x1400ffff }, { 0x21001eaa, 0x24000001 }, { 0x21001eab, 0x1400ffff }, { 0x21001eac, 0x24000001 }, { 0x21001ead, 0x1400ffff }, { 0x21001eae, 0x24000001 }, { 0x21001eaf, 0x1400ffff }, { 0x21001eb0, 0x24000001 }, { 0x21001eb1, 0x1400ffff }, { 0x21001eb2, 0x24000001 }, { 0x21001eb3, 0x1400ffff }, { 0x21001eb4, 0x24000001 }, { 0x21001eb5, 0x1400ffff }, { 0x21001eb6, 0x24000001 }, { 0x21001eb7, 0x1400ffff }, { 0x21001eb8, 0x24000001 }, { 0x21001eb9, 0x1400ffff }, { 0x21001eba, 0x24000001 }, { 0x21001ebb, 0x1400ffff }, { 0x21001ebc, 0x24000001 }, { 0x21001ebd, 0x1400ffff }, { 0x21001ebe, 0x24000001 }, { 0x21001ebf, 0x1400ffff }, { 0x21001ec0, 0x24000001 }, { 0x21001ec1, 0x1400ffff }, { 0x21001ec2, 0x24000001 }, { 0x21001ec3, 0x1400ffff }, { 0x21001ec4, 0x24000001 }, { 0x21001ec5, 0x1400ffff }, { 0x21001ec6, 0x24000001 }, { 0x21001ec7, 0x1400ffff }, { 0x21001ec8, 0x24000001 }, { 0x21001ec9, 0x1400ffff }, { 0x21001eca, 0x24000001 }, { 0x21001ecb, 0x1400ffff }, { 0x21001ecc, 0x24000001 }, { 0x21001ecd, 0x1400ffff }, { 0x21001ece, 0x24000001 }, { 0x21001ecf, 0x1400ffff }, { 0x21001ed0, 0x24000001 }, { 0x21001ed1, 0x1400ffff }, { 0x21001ed2, 0x24000001 }, { 0x21001ed3, 0x1400ffff }, { 0x21001ed4, 0x24000001 }, { 0x21001ed5, 0x1400ffff }, { 0x21001ed6, 0x24000001 }, { 0x21001ed7, 0x1400ffff }, { 0x21001ed8, 0x24000001 }, { 0x21001ed9, 0x1400ffff }, { 0x21001eda, 0x24000001 }, { 0x21001edb, 0x1400ffff }, { 0x21001edc, 0x24000001 }, { 0x21001edd, 0x1400ffff }, { 0x21001ede, 0x24000001 }, { 0x21001edf, 0x1400ffff }, { 0x21001ee0, 0x24000001 }, { 0x21001ee1, 0x1400ffff }, { 0x21001ee2, 0x24000001 }, { 0x21001ee3, 0x1400ffff }, { 0x21001ee4, 0x24000001 }, { 0x21001ee5, 0x1400ffff }, { 0x21001ee6, 0x24000001 }, { 0x21001ee7, 0x1400ffff }, { 0x21001ee8, 0x24000001 }, { 0x21001ee9, 0x1400ffff }, { 0x21001eea, 0x24000001 }, { 0x21001eeb, 0x1400ffff }, { 0x21001eec, 0x24000001 }, { 0x21001eed, 0x1400ffff }, { 0x21001eee, 0x24000001 }, { 0x21001eef, 0x1400ffff }, { 0x21001ef0, 0x24000001 }, { 0x21001ef1, 0x1400ffff }, { 0x21001ef2, 0x24000001 }, { 0x21001ef3, 0x1400ffff }, { 0x21001ef4, 0x24000001 }, { 0x21001ef5, 0x1400ffff }, { 0x21001ef6, 0x24000001 }, { 0x21001ef7, 0x1400ffff }, { 0x21001ef8, 0x24000001 }, { 0x21001ef9, 0x1400ffff }, { 0x13001f00, 0x14000008 }, { 0x13001f01, 0x14000008 }, { 0x13001f02, 0x14000008 }, { 0x13001f03, 0x14000008 }, { 0x13001f04, 0x14000008 }, { 0x13001f05, 0x14000008 }, { 0x13001f06, 0x14000008 }, { 0x13001f07, 0x14000008 }, { 0x13001f08, 0x2400fff8 }, { 0x13001f09, 0x2400fff8 }, { 0x13001f0a, 0x2400fff8 }, { 0x13001f0b, 0x2400fff8 }, { 0x13001f0c, 0x2400fff8 }, { 0x13001f0d, 0x2400fff8 }, { 0x13001f0e, 0x2400fff8 }, { 0x13001f0f, 0x2400fff8 }, { 0x13001f10, 0x14000008 }, { 0x13001f11, 0x14000008 }, { 0x13001f12, 0x14000008 }, { 0x13001f13, 0x14000008 }, { 0x13001f14, 0x14000008 }, { 0x13001f15, 0x14000008 }, { 0x13001f18, 0x2400fff8 }, { 0x13001f19, 0x2400fff8 }, { 0x13001f1a, 0x2400fff8 }, { 0x13001f1b, 0x2400fff8 }, { 0x13001f1c, 0x2400fff8 }, { 0x13001f1d, 0x2400fff8 }, { 0x13001f20, 0x14000008 }, { 0x13001f21, 0x14000008 }, { 0x13001f22, 0x14000008 }, { 0x13001f23, 0x14000008 }, { 0x13001f24, 0x14000008 }, { 0x13001f25, 0x14000008 }, { 0x13001f26, 0x14000008 }, { 0x13001f27, 0x14000008 }, { 0x13001f28, 0x2400fff8 }, { 0x13001f29, 0x2400fff8 }, { 0x13001f2a, 0x2400fff8 }, { 0x13001f2b, 0x2400fff8 }, { 0x13001f2c, 0x2400fff8 }, { 0x13001f2d, 0x2400fff8 }, { 0x13001f2e, 0x2400fff8 }, { 0x13001f2f, 0x2400fff8 }, { 0x13001f30, 0x14000008 }, { 0x13001f31, 0x14000008 }, { 0x13001f32, 0x14000008 }, { 0x13001f33, 0x14000008 }, { 0x13001f34, 0x14000008 }, { 0x13001f35, 0x14000008 }, { 0x13001f36, 0x14000008 }, { 0x13001f37, 0x14000008 }, { 0x13001f38, 0x2400fff8 }, { 0x13001f39, 0x2400fff8 }, { 0x13001f3a, 0x2400fff8 }, { 0x13001f3b, 0x2400fff8 }, { 0x13001f3c, 0x2400fff8 }, { 0x13001f3d, 0x2400fff8 }, { 0x13001f3e, 0x2400fff8 }, { 0x13001f3f, 0x2400fff8 }, { 0x13001f40, 0x14000008 }, { 0x13001f41, 0x14000008 }, { 0x13001f42, 0x14000008 }, { 0x13001f43, 0x14000008 }, { 0x13001f44, 0x14000008 }, { 0x13001f45, 0x14000008 }, { 0x13001f48, 0x2400fff8 }, { 0x13001f49, 0x2400fff8 }, { 0x13001f4a, 0x2400fff8 }, { 0x13001f4b, 0x2400fff8 }, { 0x13001f4c, 0x2400fff8 }, { 0x13001f4d, 0x2400fff8 }, { 0x13001f50, 0x14000000 }, { 0x13001f51, 0x14000008 }, { 0x13001f52, 0x14000000 }, { 0x13001f53, 0x14000008 }, { 0x13001f54, 0x14000000 }, { 0x13001f55, 0x14000008 }, { 0x13001f56, 0x14000000 }, { 0x13001f57, 0x14000008 }, { 0x13001f59, 0x2400fff8 }, { 0x13001f5b, 0x2400fff8 }, { 0x13001f5d, 0x2400fff8 }, { 0x13001f5f, 0x2400fff8 }, { 0x13001f60, 0x14000008 }, { 0x13001f61, 0x14000008 }, { 0x13001f62, 0x14000008 }, { 0x13001f63, 0x14000008 }, { 0x13001f64, 0x14000008 }, { 0x13001f65, 0x14000008 }, { 0x13001f66, 0x14000008 }, { 0x13001f67, 0x14000008 }, { 0x13001f68, 0x2400fff8 }, { 0x13001f69, 0x2400fff8 }, { 0x13001f6a, 0x2400fff8 }, { 0x13001f6b, 0x2400fff8 }, { 0x13001f6c, 0x2400fff8 }, { 0x13001f6d, 0x2400fff8 }, { 0x13001f6e, 0x2400fff8 }, { 0x13001f6f, 0x2400fff8 }, { 0x13001f70, 0x1400004a }, { 0x13001f71, 0x1400004a }, { 0x13001f72, 0x14000056 }, { 0x13001f73, 0x14000056 }, { 0x13001f74, 0x14000056 }, { 0x13001f75, 0x14000056 }, { 0x13001f76, 0x14000064 }, { 0x13001f77, 0x14000064 }, { 0x13001f78, 0x14000080 }, { 0x13001f79, 0x14000080 }, { 0x13001f7a, 0x14000070 }, { 0x13001f7b, 0x14000070 }, { 0x13001f7c, 0x1400007e }, { 0x13001f7d, 0x1400007e }, { 0x13001f80, 0x14000008 }, { 0x13001f81, 0x14000008 }, { 0x13001f82, 0x14000008 }, { 0x13001f83, 0x14000008 }, { 0x13001f84, 0x14000008 }, { 0x13001f85, 0x14000008 }, { 0x13001f86, 0x14000008 }, { 0x13001f87, 0x14000008 }, { 0x13001f88, 0x2000fff8 }, { 0x13001f89, 0x2000fff8 }, { 0x13001f8a, 0x2000fff8 }, { 0x13001f8b, 0x2000fff8 }, { 0x13001f8c, 0x2000fff8 }, { 0x13001f8d, 0x2000fff8 }, { 0x13001f8e, 0x2000fff8 }, { 0x13001f8f, 0x2000fff8 }, { 0x13001f90, 0x14000008 }, { 0x13001f91, 0x14000008 }, { 0x13001f92, 0x14000008 }, { 0x13001f93, 0x14000008 }, { 0x13001f94, 0x14000008 }, { 0x13001f95, 0x14000008 }, { 0x13001f96, 0x14000008 }, { 0x13001f97, 0x14000008 }, { 0x13001f98, 0x2000fff8 }, { 0x13001f99, 0x2000fff8 }, { 0x13001f9a, 0x2000fff8 }, { 0x13001f9b, 0x2000fff8 }, { 0x13001f9c, 0x2000fff8 }, { 0x13001f9d, 0x2000fff8 }, { 0x13001f9e, 0x2000fff8 }, { 0x13001f9f, 0x2000fff8 }, { 0x13001fa0, 0x14000008 }, { 0x13001fa1, 0x14000008 }, { 0x13001fa2, 0x14000008 }, { 0x13001fa3, 0x14000008 }, { 0x13001fa4, 0x14000008 }, { 0x13001fa5, 0x14000008 }, { 0x13001fa6, 0x14000008 }, { 0x13001fa7, 0x14000008 }, { 0x13001fa8, 0x2000fff8 }, { 0x13001fa9, 0x2000fff8 }, { 0x13001faa, 0x2000fff8 }, { 0x13001fab, 0x2000fff8 }, { 0x13001fac, 0x2000fff8 }, { 0x13001fad, 0x2000fff8 }, { 0x13001fae, 0x2000fff8 }, { 0x13001faf, 0x2000fff8 }, { 0x13001fb0, 0x14000008 }, { 0x13001fb1, 0x14000008 }, { 0x13001fb2, 0x14000000 }, { 0x13001fb3, 0x14000009 }, { 0x13001fb4, 0x14000000 }, { 0x13801fb6, 0x14000001 }, { 0x13001fb8, 0x2400fff8 }, { 0x13001fb9, 0x2400fff8 }, { 0x13001fba, 0x2400ffb6 }, { 0x13001fbb, 0x2400ffb6 }, { 0x13001fbc, 0x2000fff7 }, { 0x13001fbd, 0x60000000 }, { 0x13001fbe, 0x1400e3db }, { 0x13801fbf, 0x60000002 }, { 0x13001fc2, 0x14000000 }, { 0x13001fc3, 0x14000009 }, { 0x13001fc4, 0x14000000 }, { 0x13801fc6, 0x14000001 }, { 0x13001fc8, 0x2400ffaa }, { 0x13001fc9, 0x2400ffaa }, { 0x13001fca, 0x2400ffaa }, { 0x13001fcb, 0x2400ffaa }, { 0x13001fcc, 0x2000fff7 }, { 0x13801fcd, 0x60000002 }, { 0x13001fd0, 0x14000008 }, { 0x13001fd1, 0x14000008 }, { 0x13801fd2, 0x14000001 }, { 0x13801fd6, 0x14000001 }, { 0x13001fd8, 0x2400fff8 }, { 0x13001fd9, 0x2400fff8 }, { 0x13001fda, 0x2400ff9c }, { 0x13001fdb, 0x2400ff9c }, { 0x13801fdd, 0x60000002 }, { 0x13001fe0, 0x14000008 }, { 0x13001fe1, 0x14000008 }, { 0x13801fe2, 0x14000002 }, { 0x13001fe5, 0x14000007 }, { 0x13801fe6, 0x14000001 }, { 0x13001fe8, 0x2400fff8 }, { 0x13001fe9, 0x2400fff8 }, { 0x13001fea, 0x2400ff90 }, { 0x13001feb, 0x2400ff90 }, { 0x13001fec, 0x2400fff9 }, { 0x13801fed, 0x60000002 }, { 0x13001ff2, 0x14000000 }, { 0x13001ff3, 0x14000009 }, { 0x13001ff4, 0x14000000 }, { 0x13801ff6, 0x14000001 }, { 0x13001ff8, 0x2400ff80 }, { 0x13001ff9, 0x2400ff80 }, { 0x13001ffa, 0x2400ff82 }, { 0x13001ffb, 0x2400ff82 }, { 0x13001ffc, 0x2000fff7 }, { 0x13801ffd, 0x60000001 }, { 0x09802000, 0x7400000a }, { 0x0980200b, 0x04000004 }, { 0x09802010, 0x44000005 }, { 0x09802016, 0x54000001 }, { 0x09002018, 0x50000000 }, { 0x09002019, 0x4c000000 }, { 0x0900201a, 0x58000000 }, { 0x0980201b, 0x50000001 }, { 0x0900201d, 0x4c000000 }, { 0x0900201e, 0x58000000 }, { 0x0900201f, 0x50000000 }, { 0x09802020, 0x54000007 }, { 0x09002028, 0x6c000000 }, { 0x09002029, 0x70000000 }, { 0x0980202a, 0x04000004 }, { 0x0900202f, 0x74000000 }, { 0x09802030, 0x54000008 }, { 0x09002039, 0x50000000 }, { 0x0900203a, 0x4c000000 }, { 0x0980203b, 0x54000003 }, { 0x0980203f, 0x40000001 }, { 0x09802041, 0x54000002 }, { 0x09002044, 0x64000000 }, { 0x09002045, 0x58000000 }, { 0x09002046, 0x48000000 }, { 0x09802047, 0x5400000a }, { 0x09002052, 0x64000000 }, { 0x09002053, 0x54000000 }, { 0x09002054, 0x40000000 }, { 0x09802055, 0x54000009 }, { 0x0900205f, 0x74000000 }, { 0x09802060, 0x04000003 }, { 0x0980206a, 0x04000005 }, { 0x09002070, 0x3c000000 }, { 0x21002071, 0x14000000 }, { 0x09802074, 0x3c000005 }, { 0x0980207a, 0x64000002 }, { 0x0900207d, 0x58000000 }, { 0x0900207e, 0x48000000 }, { 0x2100207f, 0x14000000 }, { 0x09802080, 0x3c000009 }, { 0x0980208a, 0x64000002 }, { 0x0900208d, 0x58000000 }, { 0x0900208e, 0x48000000 }, { 0x21802090, 0x18000004 }, { 0x098020a0, 0x5c000015 }, { 0x1b8020d0, 0x3000000c }, { 0x1b8020dd, 0x2c000003 }, { 0x1b0020e1, 0x30000000 }, { 0x1b8020e2, 0x2c000002 }, { 0x1b8020e5, 0x3000000a }, { 0x09802100, 0x68000001 }, { 0x09002102, 0x24000000 }, { 0x09802103, 0x68000003 }, { 0x09002107, 0x24000000 }, { 0x09802108, 0x68000001 }, { 0x0900210a, 0x14000000 }, { 0x0980210b, 0x24000002 }, { 0x0980210e, 0x14000001 }, { 0x09802110, 0x24000002 }, { 0x09002113, 0x14000000 }, { 0x09002114, 0x68000000 }, { 0x09002115, 0x24000000 }, { 0x09802116, 0x68000002 }, { 0x09802119, 0x24000004 }, { 0x0980211e, 0x68000005 }, { 0x09002124, 0x24000000 }, { 0x09002125, 0x68000000 }, { 0x13002126, 0x2400e2a3 }, { 0x09002127, 0x68000000 }, { 0x09002128, 0x24000000 }, { 0x09002129, 0x68000000 }, { 0x2100212a, 0x2400df41 }, { 0x2100212b, 0x2400dfba }, { 0x0980212c, 0x24000001 }, { 0x0900212e, 0x68000000 }, { 0x0900212f, 0x14000000 }, { 0x09802130, 0x24000001 }, { 0x21002132, 0x2400001c }, { 0x09002133, 0x24000000 }, { 0x09002134, 0x14000000 }, { 0x09802135, 0x1c000003 }, { 0x09002139, 0x14000000 }, { 0x0980213a, 0x68000001 }, { 0x0980213c, 0x14000001 }, { 0x0980213e, 0x24000001 }, { 0x09802140, 0x64000004 }, { 0x09002145, 0x24000000 }, { 0x09802146, 0x14000003 }, { 0x0900214a, 0x68000000 }, { 0x0900214b, 0x64000000 }, { 0x0980214c, 0x68000001 }, { 0x2100214e, 0x1400ffe4 }, { 0x09802153, 0x3c00000c }, { 0x09002160, 0x38000010 }, { 0x09002161, 0x38000010 }, { 0x09002162, 0x38000010 }, { 0x09002163, 0x38000010 }, { 0x09002164, 0x38000010 }, { 0x09002165, 0x38000010 }, { 0x09002166, 0x38000010 }, { 0x09002167, 0x38000010 }, { 0x09002168, 0x38000010 }, { 0x09002169, 0x38000010 }, { 0x0900216a, 0x38000010 }, { 0x0900216b, 0x38000010 }, { 0x0900216c, 0x38000010 }, { 0x0900216d, 0x38000010 }, { 0x0900216e, 0x38000010 }, { 0x0900216f, 0x38000010 }, { 0x09002170, 0x3800fff0 }, { 0x09002171, 0x3800fff0 }, { 0x09002172, 0x3800fff0 }, { 0x09002173, 0x3800fff0 }, { 0x09002174, 0x3800fff0 }, { 0x09002175, 0x3800fff0 }, { 0x09002176, 0x3800fff0 }, { 0x09002177, 0x3800fff0 }, { 0x09002178, 0x3800fff0 }, { 0x09002179, 0x3800fff0 }, { 0x0900217a, 0x3800fff0 }, { 0x0900217b, 0x3800fff0 }, { 0x0900217c, 0x3800fff0 }, { 0x0900217d, 0x3800fff0 }, { 0x0900217e, 0x3800fff0 }, { 0x0900217f, 0x3800fff0 }, { 0x09802180, 0x38000002 }, { 0x09002183, 0x24000001 }, { 0x21002184, 0x1400ffff }, { 0x09802190, 0x64000004 }, { 0x09802195, 0x68000004 }, { 0x0980219a, 0x64000001 }, { 0x0980219c, 0x68000003 }, { 0x090021a0, 0x64000000 }, { 0x098021a1, 0x68000001 }, { 0x090021a3, 0x64000000 }, { 0x098021a4, 0x68000001 }, { 0x090021a6, 0x64000000 }, { 0x098021a7, 0x68000006 }, { 0x090021ae, 0x64000000 }, { 0x098021af, 0x6800001e }, { 0x098021ce, 0x64000001 }, { 0x098021d0, 0x68000001 }, { 0x090021d2, 0x64000000 }, { 0x090021d3, 0x68000000 }, { 0x090021d4, 0x64000000 }, { 0x098021d5, 0x6800001e }, { 0x098021f4, 0x6400010b }, { 0x09802300, 0x68000007 }, { 0x09802308, 0x64000003 }, { 0x0980230c, 0x68000013 }, { 0x09802320, 0x64000001 }, { 0x09802322, 0x68000006 }, { 0x09002329, 0x58000000 }, { 0x0900232a, 0x48000000 }, { 0x0980232b, 0x68000050 }, { 0x0900237c, 0x64000000 }, { 0x0980237d, 0x6800001d }, { 0x0980239b, 0x64000018 }, { 0x098023b4, 0x68000027 }, { 0x098023dc, 0x64000005 }, { 0x098023e2, 0x68000005 }, { 0x09802400, 0x68000026 }, { 0x09802440, 0x6800000a }, { 0x09802460, 0x3c00003b }, { 0x0980249c, 0x68000019 }, { 0x090024b6, 0x6800001a }, { 0x090024b7, 0x6800001a }, { 0x090024b8, 0x6800001a }, { 0x090024b9, 0x6800001a }, { 0x090024ba, 0x6800001a }, { 0x090024bb, 0x6800001a }, { 0x090024bc, 0x6800001a }, { 0x090024bd, 0x6800001a }, { 0x090024be, 0x6800001a }, { 0x090024bf, 0x6800001a }, { 0x090024c0, 0x6800001a }, { 0x090024c1, 0x6800001a }, { 0x090024c2, 0x6800001a }, { 0x090024c3, 0x6800001a }, { 0x090024c4, 0x6800001a }, { 0x090024c5, 0x6800001a }, { 0x090024c6, 0x6800001a }, { 0x090024c7, 0x6800001a }, { 0x090024c8, 0x6800001a }, { 0x090024c9, 0x6800001a }, { 0x090024ca, 0x6800001a }, { 0x090024cb, 0x6800001a }, { 0x090024cc, 0x6800001a }, { 0x090024cd, 0x6800001a }, { 0x090024ce, 0x6800001a }, { 0x090024cf, 0x6800001a }, { 0x090024d0, 0x6800ffe6 }, { 0x090024d1, 0x6800ffe6 }, { 0x090024d2, 0x6800ffe6 }, { 0x090024d3, 0x6800ffe6 }, { 0x090024d4, 0x6800ffe6 }, { 0x090024d5, 0x6800ffe6 }, { 0x090024d6, 0x6800ffe6 }, { 0x090024d7, 0x6800ffe6 }, { 0x090024d8, 0x6800ffe6 }, { 0x090024d9, 0x6800ffe6 }, { 0x090024da, 0x6800ffe6 }, { 0x090024db, 0x6800ffe6 }, { 0x090024dc, 0x6800ffe6 }, { 0x090024dd, 0x6800ffe6 }, { 0x090024de, 0x6800ffe6 }, { 0x090024df, 0x6800ffe6 }, { 0x090024e0, 0x6800ffe6 }, { 0x090024e1, 0x6800ffe6 }, { 0x090024e2, 0x6800ffe6 }, { 0x090024e3, 0x6800ffe6 }, { 0x090024e4, 0x6800ffe6 }, { 0x090024e5, 0x6800ffe6 }, { 0x090024e6, 0x6800ffe6 }, { 0x090024e7, 0x6800ffe6 }, { 0x090024e8, 0x6800ffe6 }, { 0x090024e9, 0x6800ffe6 }, { 0x098024ea, 0x3c000015 }, { 0x09802500, 0x680000b6 }, { 0x090025b7, 0x64000000 }, { 0x098025b8, 0x68000008 }, { 0x090025c1, 0x64000000 }, { 0x098025c2, 0x68000035 }, { 0x098025f8, 0x64000007 }, { 0x09802600, 0x6800006e }, { 0x0900266f, 0x64000000 }, { 0x09802670, 0x6800002c }, { 0x098026a0, 0x68000012 }, { 0x09802701, 0x68000003 }, { 0x09802706, 0x68000003 }, { 0x0980270c, 0x6800001b }, { 0x09802729, 0x68000022 }, { 0x0900274d, 0x68000000 }, { 0x0980274f, 0x68000003 }, { 0x09002756, 0x68000000 }, { 0x09802758, 0x68000006 }, { 0x09802761, 0x68000006 }, { 0x09002768, 0x58000000 }, { 0x09002769, 0x48000000 }, { 0x0900276a, 0x58000000 }, { 0x0900276b, 0x48000000 }, { 0x0900276c, 0x58000000 }, { 0x0900276d, 0x48000000 }, { 0x0900276e, 0x58000000 }, { 0x0900276f, 0x48000000 }, { 0x09002770, 0x58000000 }, { 0x09002771, 0x48000000 }, { 0x09002772, 0x58000000 }, { 0x09002773, 0x48000000 }, { 0x09002774, 0x58000000 }, { 0x09002775, 0x48000000 }, { 0x09802776, 0x3c00001d }, { 0x09002794, 0x68000000 }, { 0x09802798, 0x68000017 }, { 0x098027b1, 0x6800000d }, { 0x098027c0, 0x64000004 }, { 0x090027c5, 0x58000000 }, { 0x090027c6, 0x48000000 }, { 0x098027c7, 0x64000003 }, { 0x098027d0, 0x64000015 }, { 0x090027e6, 0x58000000 }, { 0x090027e7, 0x48000000 }, { 0x090027e8, 0x58000000 }, { 0x090027e9, 0x48000000 }, { 0x090027ea, 0x58000000 }, { 0x090027eb, 0x48000000 }, { 0x098027f0, 0x6400000f }, { 0x04802800, 0x680000ff }, { 0x09802900, 0x64000082 }, { 0x09002983, 0x58000000 }, { 0x09002984, 0x48000000 }, { 0x09002985, 0x58000000 }, { 0x09002986, 0x48000000 }, { 0x09002987, 0x58000000 }, { 0x09002988, 0x48000000 }, { 0x09002989, 0x58000000 }, { 0x0900298a, 0x48000000 }, { 0x0900298b, 0x58000000 }, { 0x0900298c, 0x48000000 }, { 0x0900298d, 0x58000000 }, { 0x0900298e, 0x48000000 }, { 0x0900298f, 0x58000000 }, { 0x09002990, 0x48000000 }, { 0x09002991, 0x58000000 }, { 0x09002992, 0x48000000 }, { 0x09002993, 0x58000000 }, { 0x09002994, 0x48000000 }, { 0x09002995, 0x58000000 }, { 0x09002996, 0x48000000 }, { 0x09002997, 0x58000000 }, { 0x09002998, 0x48000000 }, { 0x09802999, 0x6400003e }, { 0x090029d8, 0x58000000 }, { 0x090029d9, 0x48000000 }, { 0x090029da, 0x58000000 }, { 0x090029db, 0x48000000 }, { 0x098029dc, 0x6400001f }, { 0x090029fc, 0x58000000 }, { 0x090029fd, 0x48000000 }, { 0x098029fe, 0x64000101 }, { 0x09802b00, 0x6800001a }, { 0x09802b20, 0x68000003 }, { 0x11002c00, 0x24000030 }, { 0x11002c01, 0x24000030 }, { 0x11002c02, 0x24000030 }, { 0x11002c03, 0x24000030 }, { 0x11002c04, 0x24000030 }, { 0x11002c05, 0x24000030 }, { 0x11002c06, 0x24000030 }, { 0x11002c07, 0x24000030 }, { 0x11002c08, 0x24000030 }, { 0x11002c09, 0x24000030 }, { 0x11002c0a, 0x24000030 }, { 0x11002c0b, 0x24000030 }, { 0x11002c0c, 0x24000030 }, { 0x11002c0d, 0x24000030 }, { 0x11002c0e, 0x24000030 }, { 0x11002c0f, 0x24000030 }, { 0x11002c10, 0x24000030 }, { 0x11002c11, 0x24000030 }, { 0x11002c12, 0x24000030 }, { 0x11002c13, 0x24000030 }, { 0x11002c14, 0x24000030 }, { 0x11002c15, 0x24000030 }, { 0x11002c16, 0x24000030 }, { 0x11002c17, 0x24000030 }, { 0x11002c18, 0x24000030 }, { 0x11002c19, 0x24000030 }, { 0x11002c1a, 0x24000030 }, { 0x11002c1b, 0x24000030 }, { 0x11002c1c, 0x24000030 }, { 0x11002c1d, 0x24000030 }, { 0x11002c1e, 0x24000030 }, { 0x11002c1f, 0x24000030 }, { 0x11002c20, 0x24000030 }, { 0x11002c21, 0x24000030 }, { 0x11002c22, 0x24000030 }, { 0x11002c23, 0x24000030 }, { 0x11002c24, 0x24000030 }, { 0x11002c25, 0x24000030 }, { 0x11002c26, 0x24000030 }, { 0x11002c27, 0x24000030 }, { 0x11002c28, 0x24000030 }, { 0x11002c29, 0x24000030 }, { 0x11002c2a, 0x24000030 }, { 0x11002c2b, 0x24000030 }, { 0x11002c2c, 0x24000030 }, { 0x11002c2d, 0x24000030 }, { 0x11002c2e, 0x24000030 }, { 0x11002c30, 0x1400ffd0 }, { 0x11002c31, 0x1400ffd0 }, { 0x11002c32, 0x1400ffd0 }, { 0x11002c33, 0x1400ffd0 }, { 0x11002c34, 0x1400ffd0 }, { 0x11002c35, 0x1400ffd0 }, { 0x11002c36, 0x1400ffd0 }, { 0x11002c37, 0x1400ffd0 }, { 0x11002c38, 0x1400ffd0 }, { 0x11002c39, 0x1400ffd0 }, { 0x11002c3a, 0x1400ffd0 }, { 0x11002c3b, 0x1400ffd0 }, { 0x11002c3c, 0x1400ffd0 }, { 0x11002c3d, 0x1400ffd0 }, { 0x11002c3e, 0x1400ffd0 }, { 0x11002c3f, 0x1400ffd0 }, { 0x11002c40, 0x1400ffd0 }, { 0x11002c41, 0x1400ffd0 }, { 0x11002c42, 0x1400ffd0 }, { 0x11002c43, 0x1400ffd0 }, { 0x11002c44, 0x1400ffd0 }, { 0x11002c45, 0x1400ffd0 }, { 0x11002c46, 0x1400ffd0 }, { 0x11002c47, 0x1400ffd0 }, { 0x11002c48, 0x1400ffd0 }, { 0x11002c49, 0x1400ffd0 }, { 0x11002c4a, 0x1400ffd0 }, { 0x11002c4b, 0x1400ffd0 }, { 0x11002c4c, 0x1400ffd0 }, { 0x11002c4d, 0x1400ffd0 }, { 0x11002c4e, 0x1400ffd0 }, { 0x11002c4f, 0x1400ffd0 }, { 0x11002c50, 0x1400ffd0 }, { 0x11002c51, 0x1400ffd0 }, { 0x11002c52, 0x1400ffd0 }, { 0x11002c53, 0x1400ffd0 }, { 0x11002c54, 0x1400ffd0 }, { 0x11002c55, 0x1400ffd0 }, { 0x11002c56, 0x1400ffd0 }, { 0x11002c57, 0x1400ffd0 }, { 0x11002c58, 0x1400ffd0 }, { 0x11002c59, 0x1400ffd0 }, { 0x11002c5a, 0x1400ffd0 }, { 0x11002c5b, 0x1400ffd0 }, { 0x11002c5c, 0x1400ffd0 }, { 0x11002c5d, 0x1400ffd0 }, { 0x11002c5e, 0x1400ffd0 }, { 0x21002c60, 0x24000001 }, { 0x21002c61, 0x1400ffff }, { 0x21002c62, 0x2400d609 }, { 0x21002c63, 0x2400f11a }, { 0x21002c64, 0x2400d619 }, { 0x21002c65, 0x1400d5d5 }, { 0x21002c66, 0x1400d5d8 }, { 0x21002c67, 0x24000001 }, { 0x21002c68, 0x1400ffff }, { 0x21002c69, 0x24000001 }, { 0x21002c6a, 0x1400ffff }, { 0x21002c6b, 0x24000001 }, { 0x21002c6c, 0x1400ffff }, { 0x21002c74, 0x14000000 }, { 0x21002c75, 0x24000001 }, { 0x21002c76, 0x1400ffff }, { 0x21002c77, 0x14000000 }, { 0x0a002c80, 0x24000001 }, { 0x0a002c81, 0x1400ffff }, { 0x0a002c82, 0x24000001 }, { 0x0a002c83, 0x1400ffff }, { 0x0a002c84, 0x24000001 }, { 0x0a002c85, 0x1400ffff }, { 0x0a002c86, 0x24000001 }, { 0x0a002c87, 0x1400ffff }, { 0x0a002c88, 0x24000001 }, { 0x0a002c89, 0x1400ffff }, { 0x0a002c8a, 0x24000001 }, { 0x0a002c8b, 0x1400ffff }, { 0x0a002c8c, 0x24000001 }, { 0x0a002c8d, 0x1400ffff }, { 0x0a002c8e, 0x24000001 }, { 0x0a002c8f, 0x1400ffff }, { 0x0a002c90, 0x24000001 }, { 0x0a002c91, 0x1400ffff }, { 0x0a002c92, 0x24000001 }, { 0x0a002c93, 0x1400ffff }, { 0x0a002c94, 0x24000001 }, { 0x0a002c95, 0x1400ffff }, { 0x0a002c96, 0x24000001 }, { 0x0a002c97, 0x1400ffff }, { 0x0a002c98, 0x24000001 }, { 0x0a002c99, 0x1400ffff }, { 0x0a002c9a, 0x24000001 }, { 0x0a002c9b, 0x1400ffff }, { 0x0a002c9c, 0x24000001 }, { 0x0a002c9d, 0x1400ffff }, { 0x0a002c9e, 0x24000001 }, { 0x0a002c9f, 0x1400ffff }, { 0x0a002ca0, 0x24000001 }, { 0x0a002ca1, 0x1400ffff }, { 0x0a002ca2, 0x24000001 }, { 0x0a002ca3, 0x1400ffff }, { 0x0a002ca4, 0x24000001 }, { 0x0a002ca5, 0x1400ffff }, { 0x0a002ca6, 0x24000001 }, { 0x0a002ca7, 0x1400ffff }, { 0x0a002ca8, 0x24000001 }, { 0x0a002ca9, 0x1400ffff }, { 0x0a002caa, 0x24000001 }, { 0x0a002cab, 0x1400ffff }, { 0x0a002cac, 0x24000001 }, { 0x0a002cad, 0x1400ffff }, { 0x0a002cae, 0x24000001 }, { 0x0a002caf, 0x1400ffff }, { 0x0a002cb0, 0x24000001 }, { 0x0a002cb1, 0x1400ffff }, { 0x0a002cb2, 0x24000001 }, { 0x0a002cb3, 0x1400ffff }, { 0x0a002cb4, 0x24000001 }, { 0x0a002cb5, 0x1400ffff }, { 0x0a002cb6, 0x24000001 }, { 0x0a002cb7, 0x1400ffff }, { 0x0a002cb8, 0x24000001 }, { 0x0a002cb9, 0x1400ffff }, { 0x0a002cba, 0x24000001 }, { 0x0a002cbb, 0x1400ffff }, { 0x0a002cbc, 0x24000001 }, { 0x0a002cbd, 0x1400ffff }, { 0x0a002cbe, 0x24000001 }, { 0x0a002cbf, 0x1400ffff }, { 0x0a002cc0, 0x24000001 }, { 0x0a002cc1, 0x1400ffff }, { 0x0a002cc2, 0x24000001 }, { 0x0a002cc3, 0x1400ffff }, { 0x0a002cc4, 0x24000001 }, { 0x0a002cc5, 0x1400ffff }, { 0x0a002cc6, 0x24000001 }, { 0x0a002cc7, 0x1400ffff }, { 0x0a002cc8, 0x24000001 }, { 0x0a002cc9, 0x1400ffff }, { 0x0a002cca, 0x24000001 }, { 0x0a002ccb, 0x1400ffff }, { 0x0a002ccc, 0x24000001 }, { 0x0a002ccd, 0x1400ffff }, { 0x0a002cce, 0x24000001 }, { 0x0a002ccf, 0x1400ffff }, { 0x0a002cd0, 0x24000001 }, { 0x0a002cd1, 0x1400ffff }, { 0x0a002cd2, 0x24000001 }, { 0x0a002cd3, 0x1400ffff }, { 0x0a002cd4, 0x24000001 }, { 0x0a002cd5, 0x1400ffff }, { 0x0a002cd6, 0x24000001 }, { 0x0a002cd7, 0x1400ffff }, { 0x0a002cd8, 0x24000001 }, { 0x0a002cd9, 0x1400ffff }, { 0x0a002cda, 0x24000001 }, { 0x0a002cdb, 0x1400ffff }, { 0x0a002cdc, 0x24000001 }, { 0x0a002cdd, 0x1400ffff }, { 0x0a002cde, 0x24000001 }, { 0x0a002cdf, 0x1400ffff }, { 0x0a002ce0, 0x24000001 }, { 0x0a002ce1, 0x1400ffff }, { 0x0a002ce2, 0x24000001 }, { 0x0a002ce3, 0x1400ffff }, { 0x0a002ce4, 0x14000000 }, { 0x0a802ce5, 0x68000005 }, { 0x0a802cf9, 0x54000003 }, { 0x0a002cfd, 0x3c000000 }, { 0x0a802cfe, 0x54000001 }, { 0x10002d00, 0x1400e3a0 }, { 0x10002d01, 0x1400e3a0 }, { 0x10002d02, 0x1400e3a0 }, { 0x10002d03, 0x1400e3a0 }, { 0x10002d04, 0x1400e3a0 }, { 0x10002d05, 0x1400e3a0 }, { 0x10002d06, 0x1400e3a0 }, { 0x10002d07, 0x1400e3a0 }, { 0x10002d08, 0x1400e3a0 }, { 0x10002d09, 0x1400e3a0 }, { 0x10002d0a, 0x1400e3a0 }, { 0x10002d0b, 0x1400e3a0 }, { 0x10002d0c, 0x1400e3a0 }, { 0x10002d0d, 0x1400e3a0 }, { 0x10002d0e, 0x1400e3a0 }, { 0x10002d0f, 0x1400e3a0 }, { 0x10002d10, 0x1400e3a0 }, { 0x10002d11, 0x1400e3a0 }, { 0x10002d12, 0x1400e3a0 }, { 0x10002d13, 0x1400e3a0 }, { 0x10002d14, 0x1400e3a0 }, { 0x10002d15, 0x1400e3a0 }, { 0x10002d16, 0x1400e3a0 }, { 0x10002d17, 0x1400e3a0 }, { 0x10002d18, 0x1400e3a0 }, { 0x10002d19, 0x1400e3a0 }, { 0x10002d1a, 0x1400e3a0 }, { 0x10002d1b, 0x1400e3a0 }, { 0x10002d1c, 0x1400e3a0 }, { 0x10002d1d, 0x1400e3a0 }, { 0x10002d1e, 0x1400e3a0 }, { 0x10002d1f, 0x1400e3a0 }, { 0x10002d20, 0x1400e3a0 }, { 0x10002d21, 0x1400e3a0 }, { 0x10002d22, 0x1400e3a0 }, { 0x10002d23, 0x1400e3a0 }, { 0x10002d24, 0x1400e3a0 }, { 0x10002d25, 0x1400e3a0 }, { 0x3a802d30, 0x1c000035 }, { 0x3a002d6f, 0x18000000 }, { 0x0f802d80, 0x1c000016 }, { 0x0f802da0, 0x1c000006 }, { 0x0f802da8, 0x1c000006 }, { 0x0f802db0, 0x1c000006 }, { 0x0f802db8, 0x1c000006 }, { 0x0f802dc0, 0x1c000006 }, { 0x0f802dc8, 0x1c000006 }, { 0x0f802dd0, 0x1c000006 }, { 0x0f802dd8, 0x1c000006 }, { 0x09802e00, 0x54000001 }, { 0x09002e02, 0x50000000 }, { 0x09002e03, 0x4c000000 }, { 0x09002e04, 0x50000000 }, { 0x09002e05, 0x4c000000 }, { 0x09802e06, 0x54000002 }, { 0x09002e09, 0x50000000 }, { 0x09002e0a, 0x4c000000 }, { 0x09002e0b, 0x54000000 }, { 0x09002e0c, 0x50000000 }, { 0x09002e0d, 0x4c000000 }, { 0x09802e0e, 0x54000008 }, { 0x09002e17, 0x44000000 }, { 0x09002e1c, 0x50000000 }, { 0x09002e1d, 0x4c000000 }, { 0x16802e80, 0x68000019 }, { 0x16802e9b, 0x68000058 }, { 0x16802f00, 0x680000d5 }, { 0x09802ff0, 0x6800000b }, { 0x09003000, 0x74000000 }, { 0x09803001, 0x54000002 }, { 0x09003004, 0x68000000 }, { 0x16003005, 0x18000000 }, { 0x09003006, 0x1c000000 }, { 0x16003007, 0x38000000 }, { 0x09003008, 0x58000000 }, { 0x09003009, 0x48000000 }, { 0x0900300a, 0x58000000 }, { 0x0900300b, 0x48000000 }, { 0x0900300c, 0x58000000 }, { 0x0900300d, 0x48000000 }, { 0x0900300e, 0x58000000 }, { 0x0900300f, 0x48000000 }, { 0x09003010, 0x58000000 }, { 0x09003011, 0x48000000 }, { 0x09803012, 0x68000001 }, { 0x09003014, 0x58000000 }, { 0x09003015, 0x48000000 }, { 0x09003016, 0x58000000 }, { 0x09003017, 0x48000000 }, { 0x09003018, 0x58000000 }, { 0x09003019, 0x48000000 }, { 0x0900301a, 0x58000000 }, { 0x0900301b, 0x48000000 }, { 0x0900301c, 0x44000000 }, { 0x0900301d, 0x58000000 }, { 0x0980301e, 0x48000001 }, { 0x09003020, 0x68000000 }, { 0x16803021, 0x38000008 }, { 0x1b80302a, 0x30000005 }, { 0x09003030, 0x44000000 }, { 0x09803031, 0x18000004 }, { 0x09803036, 0x68000001 }, { 0x16803038, 0x38000002 }, { 0x1600303b, 0x18000000 }, { 0x0900303c, 0x1c000000 }, { 0x0900303d, 0x54000000 }, { 0x0980303e, 0x68000001 }, { 0x1a803041, 0x1c000055 }, { 0x1b803099, 0x30000001 }, { 0x0980309b, 0x60000001 }, { 0x1a80309d, 0x18000001 }, { 0x1a00309f, 0x1c000000 }, { 0x090030a0, 0x44000000 }, { 0x1d8030a1, 0x1c000059 }, { 0x090030fb, 0x54000000 }, { 0x098030fc, 0x18000002 }, { 0x1d0030ff, 0x1c000000 }, { 0x03803105, 0x1c000027 }, { 0x17803131, 0x1c00005d }, { 0x09803190, 0x68000001 }, { 0x09803192, 0x3c000003 }, { 0x09803196, 0x68000009 }, { 0x038031a0, 0x1c000017 }, { 0x098031c0, 0x6800000f }, { 0x1d8031f0, 0x1c00000f }, { 0x17803200, 0x6800001e }, { 0x09803220, 0x3c000009 }, { 0x0980322a, 0x68000019 }, { 0x09003250, 0x68000000 }, { 0x09803251, 0x3c00000e }, { 0x17803260, 0x6800001f }, { 0x09803280, 0x3c000009 }, { 0x0980328a, 0x68000026 }, { 0x098032b1, 0x3c00000e }, { 0x098032c0, 0x6800003e }, { 0x09803300, 0x680000ff }, { 0x16803400, 0x1c0019b5 }, { 0x09804dc0, 0x6800003f }, { 0x16804e00, 0x1c0051bb }, { 0x3c80a000, 0x1c000014 }, { 0x3c00a015, 0x18000000 }, { 0x3c80a016, 0x1c000476 }, { 0x3c80a490, 0x68000036 }, { 0x0980a700, 0x60000016 }, { 0x0980a717, 0x18000003 }, { 0x0980a720, 0x60000001 }, { 0x3080a800, 0x1c000001 }, { 0x3000a802, 0x28000000 }, { 0x3080a803, 0x1c000002 }, { 0x3000a806, 0x30000000 }, { 0x3080a807, 0x1c000003 }, { 0x3000a80b, 0x30000000 }, { 0x3080a80c, 0x1c000016 }, { 0x3080a823, 0x28000001 }, { 0x3080a825, 0x30000001 }, { 0x3000a827, 0x28000000 }, { 0x3080a828, 0x68000003 }, { 0x4080a840, 0x1c000033 }, { 0x4080a874, 0x54000003 }, { 0x1780ac00, 0x1c002ba3 }, { 0x0980d800, 0x1000037f }, { 0x0980db80, 0x1000007f }, { 0x0980dc00, 0x100003ff }, { 0x0980e000, 0x0c0018ff }, { 0x1680f900, 0x1c00012d }, { 0x1680fa30, 0x1c00003a }, { 0x1680fa70, 0x1c000069 }, { 0x2180fb00, 0x14000006 }, { 0x0180fb13, 0x14000004 }, { 0x1900fb1d, 0x1c000000 }, { 0x1900fb1e, 0x30000000 }, { 0x1980fb1f, 0x1c000009 }, { 0x1900fb29, 0x64000000 }, { 0x1980fb2a, 0x1c00000c }, { 0x1980fb38, 0x1c000004 }, { 0x1900fb3e, 0x1c000000 }, { 0x1980fb40, 0x1c000001 }, { 0x1980fb43, 0x1c000001 }, { 0x1980fb46, 0x1c00006b }, { 0x0080fbd3, 0x1c00016a }, { 0x0900fd3e, 0x58000000 }, { 0x0900fd3f, 0x48000000 }, { 0x0080fd50, 0x1c00003f }, { 0x0080fd92, 0x1c000035 }, { 0x0080fdf0, 0x1c00000b }, { 0x0000fdfc, 0x5c000000 }, { 0x0900fdfd, 0x68000000 }, { 0x1b80fe00, 0x3000000f }, { 0x0980fe10, 0x54000006 }, { 0x0900fe17, 0x58000000 }, { 0x0900fe18, 0x48000000 }, { 0x0900fe19, 0x54000000 }, { 0x1b80fe20, 0x30000003 }, { 0x0900fe30, 0x54000000 }, { 0x0980fe31, 0x44000001 }, { 0x0980fe33, 0x40000001 }, { 0x0900fe35, 0x58000000 }, { 0x0900fe36, 0x48000000 }, { 0x0900fe37, 0x58000000 }, { 0x0900fe38, 0x48000000 }, { 0x0900fe39, 0x58000000 }, { 0x0900fe3a, 0x48000000 }, { 0x0900fe3b, 0x58000000 }, { 0x0900fe3c, 0x48000000 }, { 0x0900fe3d, 0x58000000 }, { 0x0900fe3e, 0x48000000 }, { 0x0900fe3f, 0x58000000 }, { 0x0900fe40, 0x48000000 }, { 0x0900fe41, 0x58000000 }, { 0x0900fe42, 0x48000000 }, { 0x0900fe43, 0x58000000 }, { 0x0900fe44, 0x48000000 }, { 0x0980fe45, 0x54000001 }, { 0x0900fe47, 0x58000000 }, { 0x0900fe48, 0x48000000 }, { 0x0980fe49, 0x54000003 }, { 0x0980fe4d, 0x40000002 }, { 0x0980fe50, 0x54000002 }, { 0x0980fe54, 0x54000003 }, { 0x0900fe58, 0x44000000 }, { 0x0900fe59, 0x58000000 }, { 0x0900fe5a, 0x48000000 }, { 0x0900fe5b, 0x58000000 }, { 0x0900fe5c, 0x48000000 }, { 0x0900fe5d, 0x58000000 }, { 0x0900fe5e, 0x48000000 }, { 0x0980fe5f, 0x54000002 }, { 0x0900fe62, 0x64000000 }, { 0x0900fe63, 0x44000000 }, { 0x0980fe64, 0x64000002 }, { 0x0900fe68, 0x54000000 }, { 0x0900fe69, 0x5c000000 }, { 0x0980fe6a, 0x54000001 }, { 0x0080fe70, 0x1c000004 }, { 0x0080fe76, 0x1c000086 }, { 0x0900feff, 0x04000000 }, { 0x0980ff01, 0x54000002 }, { 0x0900ff04, 0x5c000000 }, { 0x0980ff05, 0x54000002 }, { 0x0900ff08, 0x58000000 }, { 0x0900ff09, 0x48000000 }, { 0x0900ff0a, 0x54000000 }, { 0x0900ff0b, 0x64000000 }, { 0x0900ff0c, 0x54000000 }, { 0x0900ff0d, 0x44000000 }, { 0x0980ff0e, 0x54000001 }, { 0x0980ff10, 0x34000009 }, { 0x0980ff1a, 0x54000001 }, { 0x0980ff1c, 0x64000002 }, { 0x0980ff1f, 0x54000001 }, { 0x2100ff21, 0x24000020 }, { 0x2100ff22, 0x24000020 }, { 0x2100ff23, 0x24000020 }, { 0x2100ff24, 0x24000020 }, { 0x2100ff25, 0x24000020 }, { 0x2100ff26, 0x24000020 }, { 0x2100ff27, 0x24000020 }, { 0x2100ff28, 0x24000020 }, { 0x2100ff29, 0x24000020 }, { 0x2100ff2a, 0x24000020 }, { 0x2100ff2b, 0x24000020 }, { 0x2100ff2c, 0x24000020 }, { 0x2100ff2d, 0x24000020 }, { 0x2100ff2e, 0x24000020 }, { 0x2100ff2f, 0x24000020 }, { 0x2100ff30, 0x24000020 }, { 0x2100ff31, 0x24000020 }, { 0x2100ff32, 0x24000020 }, { 0x2100ff33, 0x24000020 }, { 0x2100ff34, 0x24000020 }, { 0x2100ff35, 0x24000020 }, { 0x2100ff36, 0x24000020 }, { 0x2100ff37, 0x24000020 }, { 0x2100ff38, 0x24000020 }, { 0x2100ff39, 0x24000020 }, { 0x2100ff3a, 0x24000020 }, { 0x0900ff3b, 0x58000000 }, { 0x0900ff3c, 0x54000000 }, { 0x0900ff3d, 0x48000000 }, { 0x0900ff3e, 0x60000000 }, { 0x0900ff3f, 0x40000000 }, { 0x0900ff40, 0x60000000 }, { 0x2100ff41, 0x1400ffe0 }, { 0x2100ff42, 0x1400ffe0 }, { 0x2100ff43, 0x1400ffe0 }, { 0x2100ff44, 0x1400ffe0 }, { 0x2100ff45, 0x1400ffe0 }, { 0x2100ff46, 0x1400ffe0 }, { 0x2100ff47, 0x1400ffe0 }, { 0x2100ff48, 0x1400ffe0 }, { 0x2100ff49, 0x1400ffe0 }, { 0x2100ff4a, 0x1400ffe0 }, { 0x2100ff4b, 0x1400ffe0 }, { 0x2100ff4c, 0x1400ffe0 }, { 0x2100ff4d, 0x1400ffe0 }, { 0x2100ff4e, 0x1400ffe0 }, { 0x2100ff4f, 0x1400ffe0 }, { 0x2100ff50, 0x1400ffe0 }, { 0x2100ff51, 0x1400ffe0 }, { 0x2100ff52, 0x1400ffe0 }, { 0x2100ff53, 0x1400ffe0 }, { 0x2100ff54, 0x1400ffe0 }, { 0x2100ff55, 0x1400ffe0 }, { 0x2100ff56, 0x1400ffe0 }, { 0x2100ff57, 0x1400ffe0 }, { 0x2100ff58, 0x1400ffe0 }, { 0x2100ff59, 0x1400ffe0 }, { 0x2100ff5a, 0x1400ffe0 }, { 0x0900ff5b, 0x58000000 }, { 0x0900ff5c, 0x64000000 }, { 0x0900ff5d, 0x48000000 }, { 0x0900ff5e, 0x64000000 }, { 0x0900ff5f, 0x58000000 }, { 0x0900ff60, 0x48000000 }, { 0x0900ff61, 0x54000000 }, { 0x0900ff62, 0x58000000 }, { 0x0900ff63, 0x48000000 }, { 0x0980ff64, 0x54000001 }, { 0x1d80ff66, 0x1c000009 }, { 0x0900ff70, 0x18000000 }, { 0x1d80ff71, 0x1c00002c }, { 0x0980ff9e, 0x18000001 }, { 0x1780ffa0, 0x1c00001e }, { 0x1780ffc2, 0x1c000005 }, { 0x1780ffca, 0x1c000005 }, { 0x1780ffd2, 0x1c000005 }, { 0x1780ffda, 0x1c000002 }, { 0x0980ffe0, 0x5c000001 }, { 0x0900ffe2, 0x64000000 }, { 0x0900ffe3, 0x60000000 }, { 0x0900ffe4, 0x68000000 }, { 0x0980ffe5, 0x5c000001 }, { 0x0900ffe8, 0x68000000 }, { 0x0980ffe9, 0x64000003 }, { 0x0980ffed, 0x68000001 }, { 0x0980fff9, 0x04000002 }, { 0x0980fffc, 0x68000001 }, { 0x23810000, 0x1c00000b }, { 0x2381000d, 0x1c000019 }, { 0x23810028, 0x1c000012 }, { 0x2381003c, 0x1c000001 }, { 0x2381003f, 0x1c00000e }, { 0x23810050, 0x1c00000d }, { 0x23810080, 0x1c00007a }, { 0x09810100, 0x54000001 }, { 0x09010102, 0x68000000 }, { 0x09810107, 0x3c00002c }, { 0x09810137, 0x68000008 }, { 0x13810140, 0x38000034 }, { 0x13810175, 0x3c000003 }, { 0x13810179, 0x68000010 }, { 0x1301018a, 0x3c000000 }, { 0x29810300, 0x1c00001e }, { 0x29810320, 0x3c000003 }, { 0x12810330, 0x1c000010 }, { 0x12010341, 0x38000000 }, { 0x12810342, 0x1c000007 }, { 0x1201034a, 0x38000000 }, { 0x3b810380, 0x1c00001d }, { 0x3b01039f, 0x54000000 }, { 0x2a8103a0, 0x1c000023 }, { 0x2a8103c8, 0x1c000007 }, { 0x2a0103d0, 0x54000000 }, { 0x2a8103d1, 0x38000004 }, { 0x0d010400, 0x24000028 }, { 0x0d010401, 0x24000028 }, { 0x0d010402, 0x24000028 }, { 0x0d010403, 0x24000028 }, { 0x0d010404, 0x24000028 }, { 0x0d010405, 0x24000028 }, { 0x0d010406, 0x24000028 }, { 0x0d010407, 0x24000028 }, { 0x0d010408, 0x24000028 }, { 0x0d010409, 0x24000028 }, { 0x0d01040a, 0x24000028 }, { 0x0d01040b, 0x24000028 }, { 0x0d01040c, 0x24000028 }, { 0x0d01040d, 0x24000028 }, { 0x0d01040e, 0x24000028 }, { 0x0d01040f, 0x24000028 }, { 0x0d010410, 0x24000028 }, { 0x0d010411, 0x24000028 }, { 0x0d010412, 0x24000028 }, { 0x0d010413, 0x24000028 }, { 0x0d010414, 0x24000028 }, { 0x0d010415, 0x24000028 }, { 0x0d010416, 0x24000028 }, { 0x0d010417, 0x24000028 }, { 0x0d010418, 0x24000028 }, { 0x0d010419, 0x24000028 }, { 0x0d01041a, 0x24000028 }, { 0x0d01041b, 0x24000028 }, { 0x0d01041c, 0x24000028 }, { 0x0d01041d, 0x24000028 }, { 0x0d01041e, 0x24000028 }, { 0x0d01041f, 0x24000028 }, { 0x0d010420, 0x24000028 }, { 0x0d010421, 0x24000028 }, { 0x0d010422, 0x24000028 }, { 0x0d010423, 0x24000028 }, { 0x0d010424, 0x24000028 }, { 0x0d010425, 0x24000028 }, { 0x0d010426, 0x24000028 }, { 0x0d010427, 0x24000028 }, { 0x0d010428, 0x1400ffd8 }, { 0x0d010429, 0x1400ffd8 }, { 0x0d01042a, 0x1400ffd8 }, { 0x0d01042b, 0x1400ffd8 }, { 0x0d01042c, 0x1400ffd8 }, { 0x0d01042d, 0x1400ffd8 }, { 0x0d01042e, 0x1400ffd8 }, { 0x0d01042f, 0x1400ffd8 }, { 0x0d010430, 0x1400ffd8 }, { 0x0d010431, 0x1400ffd8 }, { 0x0d010432, 0x1400ffd8 }, { 0x0d010433, 0x1400ffd8 }, { 0x0d010434, 0x1400ffd8 }, { 0x0d010435, 0x1400ffd8 }, { 0x0d010436, 0x1400ffd8 }, { 0x0d010437, 0x1400ffd8 }, { 0x0d010438, 0x1400ffd8 }, { 0x0d010439, 0x1400ffd8 }, { 0x0d01043a, 0x1400ffd8 }, { 0x0d01043b, 0x1400ffd8 }, { 0x0d01043c, 0x1400ffd8 }, { 0x0d01043d, 0x1400ffd8 }, { 0x0d01043e, 0x1400ffd8 }, { 0x0d01043f, 0x1400ffd8 }, { 0x0d010440, 0x1400ffd8 }, { 0x0d010441, 0x1400ffd8 }, { 0x0d010442, 0x1400ffd8 }, { 0x0d010443, 0x1400ffd8 }, { 0x0d010444, 0x1400ffd8 }, { 0x0d010445, 0x1400ffd8 }, { 0x0d010446, 0x1400ffd8 }, { 0x0d010447, 0x1400ffd8 }, { 0x0d010448, 0x1400ffd8 }, { 0x0d010449, 0x1400ffd8 }, { 0x0d01044a, 0x1400ffd8 }, { 0x0d01044b, 0x1400ffd8 }, { 0x0d01044c, 0x1400ffd8 }, { 0x0d01044d, 0x1400ffd8 }, { 0x0d01044e, 0x1400ffd8 }, { 0x0d01044f, 0x1400ffd8 }, { 0x2e810450, 0x1c00004d }, { 0x2c8104a0, 0x34000009 }, { 0x0b810800, 0x1c000005 }, { 0x0b010808, 0x1c000000 }, { 0x0b81080a, 0x1c00002b }, { 0x0b810837, 0x1c000001 }, { 0x0b01083c, 0x1c000000 }, { 0x0b01083f, 0x1c000000 }, { 0x41810900, 0x1c000015 }, { 0x41810916, 0x3c000003 }, { 0x4101091f, 0x54000000 }, { 0x1e010a00, 0x1c000000 }, { 0x1e810a01, 0x30000002 }, { 0x1e810a05, 0x30000001 }, { 0x1e810a0c, 0x30000003 }, { 0x1e810a10, 0x1c000003 }, { 0x1e810a15, 0x1c000002 }, { 0x1e810a19, 0x1c00001a }, { 0x1e810a38, 0x30000002 }, { 0x1e010a3f, 0x30000000 }, { 0x1e810a40, 0x3c000007 }, { 0x1e810a50, 0x54000008 }, { 0x3e812000, 0x1c00036e }, { 0x3e812400, 0x38000062 }, { 0x3e812470, 0x54000003 }, { 0x0981d000, 0x680000f5 }, { 0x0981d100, 0x68000026 }, { 0x0981d12a, 0x6800003a }, { 0x0981d165, 0x28000001 }, { 0x1b81d167, 0x30000002 }, { 0x0981d16a, 0x68000002 }, { 0x0981d16d, 0x28000005 }, { 0x0981d173, 0x04000007 }, { 0x1b81d17b, 0x30000007 }, { 0x0981d183, 0x68000001 }, { 0x1b81d185, 0x30000006 }, { 0x0981d18c, 0x6800001d }, { 0x1b81d1aa, 0x30000003 }, { 0x0981d1ae, 0x6800002f }, { 0x1381d200, 0x68000041 }, { 0x1381d242, 0x30000002 }, { 0x1301d245, 0x68000000 }, { 0x0981d300, 0x68000056 }, { 0x0981d360, 0x3c000011 }, { 0x0981d400, 0x24000019 }, { 0x0981d41a, 0x14000019 }, { 0x0981d434, 0x24000019 }, { 0x0981d44e, 0x14000006 }, { 0x0981d456, 0x14000011 }, { 0x0981d468, 0x24000019 }, { 0x0981d482, 0x14000019 }, { 0x0901d49c, 0x24000000 }, { 0x0981d49e, 0x24000001 }, { 0x0901d4a2, 0x24000000 }, { 0x0981d4a5, 0x24000001 }, { 0x0981d4a9, 0x24000003 }, { 0x0981d4ae, 0x24000007 }, { 0x0981d4b6, 0x14000003 }, { 0x0901d4bb, 0x14000000 }, { 0x0981d4bd, 0x14000006 }, { 0x0981d4c5, 0x1400000a }, { 0x0981d4d0, 0x24000019 }, { 0x0981d4ea, 0x14000019 }, { 0x0981d504, 0x24000001 }, { 0x0981d507, 0x24000003 }, { 0x0981d50d, 0x24000007 }, { 0x0981d516, 0x24000006 }, { 0x0981d51e, 0x14000019 }, { 0x0981d538, 0x24000001 }, { 0x0981d53b, 0x24000003 }, { 0x0981d540, 0x24000004 }, { 0x0901d546, 0x24000000 }, { 0x0981d54a, 0x24000006 }, { 0x0981d552, 0x14000019 }, { 0x0981d56c, 0x24000019 }, { 0x0981d586, 0x14000019 }, { 0x0981d5a0, 0x24000019 }, { 0x0981d5ba, 0x14000019 }, { 0x0981d5d4, 0x24000019 }, { 0x0981d5ee, 0x14000019 }, { 0x0981d608, 0x24000019 }, { 0x0981d622, 0x14000019 }, { 0x0981d63c, 0x24000019 }, { 0x0981d656, 0x14000019 }, { 0x0981d670, 0x24000019 }, { 0x0981d68a, 0x1400001b }, { 0x0981d6a8, 0x24000018 }, { 0x0901d6c1, 0x64000000 }, { 0x0981d6c2, 0x14000018 }, { 0x0901d6db, 0x64000000 }, { 0x0981d6dc, 0x14000005 }, { 0x0981d6e2, 0x24000018 }, { 0x0901d6fb, 0x64000000 }, { 0x0981d6fc, 0x14000018 }, { 0x0901d715, 0x64000000 }, { 0x0981d716, 0x14000005 }, { 0x0981d71c, 0x24000018 }, { 0x0901d735, 0x64000000 }, { 0x0981d736, 0x14000018 }, { 0x0901d74f, 0x64000000 }, { 0x0981d750, 0x14000005 }, { 0x0981d756, 0x24000018 }, { 0x0901d76f, 0x64000000 }, { 0x0981d770, 0x14000018 }, { 0x0901d789, 0x64000000 }, { 0x0981d78a, 0x14000005 }, { 0x0981d790, 0x24000018 }, { 0x0901d7a9, 0x64000000 }, { 0x0981d7aa, 0x14000018 }, { 0x0901d7c3, 0x64000000 }, { 0x0981d7c4, 0x14000005 }, { 0x0901d7ca, 0x24000000 }, { 0x0901d7cb, 0x14000000 }, { 0x0981d7ce, 0x34000031 }, { 0x16820000, 0x1c00a6d6 }, { 0x1682f800, 0x1c00021d }, { 0x090e0001, 0x04000000 }, { 0x098e0020, 0x0400005f }, { 0x1b8e0100, 0x300000ef }, { 0x098f0000, 0x0c00fffd }, { 0x09900000, 0x0c00fffd }, }; libsynthesis-3.4.0.47.1/src/platform_adapters/000077500000000000000000000000001226375725500211425ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/platform_adapters/binfile.cpp000077500000000000000000000061641226375725500232700ustar00rootroot00000000000000/** * @File binfile.cpp * * @Author Lukas Zeller (luz@plan44.ch) * * @brief TBinFile * Standard C file implementation of TBinFile * * Copyright (c) 2003-2011 by Synthesis AG + plan44.ch * * @Date 2006-03-28 : luz : created */ /* */ #include "prefix_file.h" #include "binfile.h" #ifdef WINCE #include "win32_utils.h" #endif namespace sysync { // @brief constructor TBinFile::TBinFile() : fCBinFile(NULL) { } // TBinFile // @brief destructor TBinFile::~TBinFile() { destruct(); } // TBinFile::~TBinFile // @brief test if platform file open bool TBinFile::platformFileIsOpen(void) { return fCBinFile!=NULL; } // TBinFile::platformFileIsOpen /// @brief Open a platform file bool TBinFile::platformOpenFile(cAppCharP aFilePath, TFileOpenModes aMode) { switch (aMode) { case fopm_update : fCBinFile = fopen(aFilePath,"r+b"); break; case fopm_create : fCBinFile = fopen(aFilePath,"w+b"); break; } return fCBinFile!=NULL; } // TBinFile::platformOpenFile /// @brief close file bool TBinFile::platformCloseFile(void) { fclose(fCBinFile); fCBinFile=NULL; return true; } // TBinFile::platformCloseFile /// @brief seek in file bool TBinFile::platformSeekFile(uInt32 aPos, bool aFromEnd) { return fseek(fCBinFile,aPos,aFromEnd ? SEEK_END : SEEK_SET) == 0; } // TBinFile::platformSeekFile /// @brief read from file bool TBinFile::platformReadFile(void *aBuffer, uInt32 aMaxRead) { return fread(aBuffer,aMaxRead,1,fCBinFile) == 1; } // TBinFile::platformReadFile /// @brief write to file bool TBinFile::platformWriteFile(const void *aBuffer, uInt32 aBytes) { return fwrite(aBuffer,aBytes,1,fCBinFile) == 1; } // TBinFile::platformWriteFile /// @brief flush all buffers bool TBinFile::platformFlushFile(void) { return fflush(fCBinFile)==0; } // TBinFile::platformFlushFile /// @brief truncate file to a specific length bool TBinFile::platformTruncateFile(uInt32 aNewSize) { #if defined(LINUX) || defined(MACOSX) fflush(fCBinFile); // unbuffer everything int fd = fileno(fCBinFile); // get file descriptor if (ftruncate(fd,aNewSize)) { ; // error ignored } #elif defined(WIN32) fflush(fCBinFile); // unbuffer everything HANDLE h = (HANDLE)fileno(fCBinFile); // get file descriptor SetFilePointer(h,aNewSize,NULL,FILE_BEGIN); SetEndOfFile(h); #elif defined(__EPOC_OS__) #ifdef RELEASE_VERSION #warning "%%% we need file truncation for symbian here" #endif return false; #else #error "file truncation not implemented for this platform" #endif // successfully truncated return true; } // TBinFile::platformTruncateFile /// @delete file entirely bool TBinFile::platformDeleteFile(cAppCharP aFilePath) { #if defined(LINUX) || defined(MACOSX) unlink(aFilePath); #elif defined(WINCE) TCHAR filename[MAX_PATH]; UTF8toWCharBuf(aFilePath,filename,MAX_PATH); DeleteFileW(filename); #elif defined(WIN32) unlink(aFilePath); #else #error "file delete not implemented for this platform" #endif // successfully deleted return true; } // TBinFile::platformDeleteFile } // namespace sysync // eof libsynthesis-3.4.0.47.1/src/platform_adapters/binfile.h000077500000000000000000000025731226375725500227350ustar00rootroot00000000000000/** * @File binfile.h * * @Author Lukas Zeller (luz@plan44.ch) * * @brief TBinFile * Standard C file implementation of TBinFile * * Copyright (c) 2003-2011 by Synthesis AG + plan44.ch * * @Date 2006-03-28 : luz : created */ /* */ #ifndef BINFILE_H #define BINFILE_H #include "binfilebase.h" #ifdef ANDROID #include #include #endif namespace sysync { class TBinFile : public TBinFileBase { typedef TBinFileBase inherited; public: TBinFile(); virtual ~TBinFile(); protected: // Platform file implementation abstraction // - test if platform file open virtual bool platformFileIsOpen(void); // - open file virtual bool platformOpenFile(cAppCharP aFilePath, TFileOpenModes aMode); // - close file virtual bool platformCloseFile(void); // - seek in file virtual bool platformSeekFile(uInt32 aPos, bool aFromEnd=false); // - read from file virtual bool platformReadFile(void *aBuffer, uInt32 aMaxRead); // - write to file virtual bool platformWriteFile(const void *aBuffer, uInt32 aBytes); // - flush all buffers virtual bool platformFlushFile(void); // - truncate file to a specific length virtual bool platformTruncateFile(uInt32 aNewSize); // - delete file entirely virtual bool platformDeleteFile(cAppCharP aFilePath); private: FILE *fCBinFile; }; // TBinFile } // namespace sysync #endif // BINFILE_H libsynthesis-3.4.0.47.1/src/platform_adapters/configfiles.h000077500000000000000000000065461226375725500236210ustar00rootroot00000000000000/* * File: configfiles.h * * Author: Lukas Zeller (luz@plan44.ch) * * Platform adaptors for accessing config files * * Copyright (c) 2002-2011 by Synthesis AG + plan44.ch * * 2002-11-18 : luz : created * * */ // conditional field length specs for Xprintf #ifdef __PALM_OS__ // PalmOS do not support all formatting #define FMT_LENGTH(n) #define FMT_LENGTH_LIMITED(n,p) ((string(p,strlen(p)>n ? n : strlen(p))).c_str()) #define PRINTF_LLD "%ld" #define PRINTF_LLD_ARG(x) ((long)x) #ifdef NO64BITINT #define LONGLONGTOSTR(s,ll) %%%%%%% // cause compiling error #else #define LONGLONGTOSTR(s,ll) LongLongToStr(s,ll) // need a function to do that void LongLongToStr(string &s, sInt64 ll); #endif #else #define PRINTF_LLD "%lld" #define PRINTF_LLD_ARG(x) static_cast(x) #define FMT_LENGTH(n) n #define FMT_LENGTH_LIMITED(n,p) p #define LONGLONGTOSTR(s,ll) StringObjPrintf(s,"%lld",ll) #endif /* %%% replaced by getPlatformString() // get default paths // - for writing logs (when we have no configured log dir) bool getDefaultWritePath(string &aString); // - for reading local config (first try) bool getDefaultLocalConfigPath(string &aString); // - for reading global config (second try) bool getDefaultGlobalConfigPath(string &aString); */ // IDs to request platform-specific strings (mostly paths) // Note: paths do NOT have a trailing separator! typedef enum { pfs_platformvers, // version string of the current platform (as from getFirmwareVersion()) pfs_globcfg_path, // global system-wide config path (such as C:\Windows or /etc) pfs_loccfg_path, // local config path (such as exedir or user's dir) pfs_defout_path, // default path to writable directory to write default logs pfs_temp_path, // path where we can write temp files pfs_exedir_path, // path to directory where executable resides pfs_userdir_path, // path to the user's home directory for user-visible documents and files pfs_appdata_path, // path to the user's preference directory for this application pfs_prefs_path, // path to directory where all application prefs reside (not just mine) pfs_device_uri, // URI of the device (as from former getDeviceInfo) pfs_device_name, // Name of the device (as from former getHardwareVersion()) pfs_user_name, // Name of the current user numPlatformStrings } TPlatformStringID; /// @brief get platform specific string by ID /// @return false if string is not available for this platform /// @param aStringID string selector ID /// @param aString will receive the requested string bool getPlatformString(TPlatformStringID aStringID, string &aString); /// @brief update string such that it can be used as target OS directory path /// (filename can be appended without any separator) /// @param aPath path to be updated /// @param aMakeDirs if set, directories along path are created if not existing /// @return false if directory does not exist or could not be created (when aMakeDirs is set) bool makeOSDirPath(string &aPath, bool aMakeDirs=false); // returns timestamp (UTC) of last file modification or 0 if none known lineartime_t getFileModificationDate(const char *aFileName); // get local device URI (returns false if ID cannot be guaranteed unique) bool getLocalDeviceID(string &aURI); // write to platform's "console", whatever that is void PlatformConsolePuts(const char *aText); /* eof */ libsynthesis-3.4.0.47.1/src/platform_adapters/linux/000077500000000000000000000000001226375725500223015ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/platform_adapters/linux/configfiles.cpp000077500000000000000000000170401226375725500253020ustar00rootroot00000000000000/* * File: configfiles.cpp * * Author: Lukas Zeller (luz@plan44.ch) * * Linux Platform adaptor for accessing config files * * Copyright (c) 2002-2011 by Synthesis AG + plan44.ch * * 2002-11-18 : luz : created * * */ #include "sysync.h" #ifdef ANDROID #include #endif #include #include // determine OS version static bool getOSVersion(string &aOSVersion) { // Obtain OS Version //%%%% for now aOSVersion="unknown"; return false; } // getOSVersion // determine hardware name static bool getHardwareName(string &aHardwareName) { // Obtain Device name #ifdef ANDROID aHardwareName="Android Device"; #else aHardwareName="Linux PC"; #endif return true; } // getHardwareName /// @brief get platform specific string by ID /// @return false if string is not available for this platform /// @param aStringID string selector ID /// @param aString will receive the requested string bool getPlatformString(TPlatformStringID aStringID, string &aString) { const sInt16 bufsiz=1024; char buffer[bufsiz]; buffer[0]=0; // terminate for safety string str; string aSub; struct passwd *userInfoP=NULL; switch (aStringID) { case pfs_platformvers: // Platform OS version string getOSVersion(aString); break; case pfs_device_uri: getLocalDeviceID(aString); break; case pfs_device_name: getHardwareName(aString); break; case pfs_loccfg_path: #ifdef STANDALONE_APP // default path for local config for XPT standalones is the current dir aString = "."; break; #endif // for server modules, it is same as the global config path #ifndef STANDALONE_APP case pfs_globcfg_path: // global config directory path aString = "/etc"; break; #endif case pfs_defout_path: // default output path (formerly: default write path) #ifdef STANDALONE_APP // default path for local config for XPT standalones is the current dir aString = "."; #else // for server modules, default log path is /var/log aString = "/var/log"; #endif break; case pfs_temp_path: // temp path aString = "/temp"; break; case pfs_userdir_path: // user's home dir for user-visible documents and files userInfoP = getpwuid(getuid()); aString = userInfoP->pw_dir; // home dir break; #ifdef APPDATA_SUBDIR case pfs_appdata_path: // My specific subdirectory for storing my app data/prefs userInfoP = getpwuid(getuid()); aString = userInfoP->pw_dir; // user home dir aSub = APPDATA_SUBDIR; #ifdef ANDROID aString += "/data/com.sysync"; // application specific subdir for android if (!aSub.empty()) aString+= "/"; // slash only if subdir is really there #else aString += "/.sysync/"; // application specific subdir // don't adapt it here to avoid potential problems on other platforms #endif aString += aSub; break; #endif /* case pfs_prefs_path: // general directory where all applications store data & prefs (for current user) aString = %%% break; */ /* case pfs_exedir_path: exedir: // path where module file resides aString = %%% break; */ default: // unknown ID return false; } // ok return true; } // getPlatformString extern "C" { #ifndef ANDROID #include #endif #include } /// @brief update string such that it can be used as target OS directory path /// (filename can be appended without any separator) /// @param aPath path to be updated /// @param aMakeDirs if set, directories along path are created if not existing /// @return false if directory does not exist or could not be created (when aMakeDirs is set) bool makeOSDirPath(string &aPath, bool aMakeDirs) { // make sure path ends with backslash string::size_type n=aPath.size(); if (n>=1 && aPath[n-1]!='/') aPath+='/'; // now make sure path exists if requested if (aMakeDirs) { // no slash at the end string tmppath; tmppath.assign(aPath,0,aPath.size()-1); // optimization check if entire path exists struct stat statinfo; int rc=stat(aPath.c_str(),&statinfo); if(rc!=0 || !S_ISDIR(statinfo.st_mode)) { #ifdef ANDROID rc = 0; // BFO_INCOMPLETE #else rc = errno; #endif // path does not exist yet - start from beginning to create it n=0; bool knownmissing=false; // skip first slash for absolute paths if (aPath[0]=='/') n+=1; // skip do { // find first directory in path n=aPath.find("/",n); // if no more separators to find, all dirs exist now if (n==string::npos) break; tmppath.assign(aPath,0,n); n+=1; // skip separator if (!knownmissing) { // test if this dir exists rc=stat(tmppath.c_str(),&statinfo); if(rc!=0 || !S_ISDIR(statinfo.st_mode)) { #ifdef ANDROID rc = 0; // BFO_INCOMPLETE #else rc = errno; #endif knownmissing=true; } } if (knownmissing) { // create the subdir (might fail if part of path already exists) if (mkdir(tmppath.c_str(),S_IRWXU)!=0) return false; // failure to create directory } } while(true); } // path does not exist yet entirely } // make path existing return true; } // makeOSDirPath // returns timestamp (UTC) of last file modification or 0 if none known lineartime_t getFileModificationDate(const char *aFileName) { struct stat st; lineartime_t res; if (stat(aFileName,&st)!=0) res=0; else { // stat ok, get modification date res= ((lineartime_t)st.st_mtime * secondToLinearTimeFactor) + UnixToLineartimeOffset; } // return timestamp return res; } // getFileModificationDate #include #include // get local device URI/name info bool getLocalDeviceID(string &aURI) { char szHostname[100]; string hostName; // get name of own machine if (gethostname(szHostname, sizeof(szHostname))!=0) { hostName="_unknown_"; } else { // A network lookup of the domain name is not likely // to yield any good result on most Linux consumer // devices. It just causes a slowdown, in particular // when the device is not currently connected (which // does not necessarily prevent syncing, for example // when using Bluetooth); 10 second delays have // been observed while the network stack waits for // a timeout (FDO #70771). // // To avoid that timeout, disable this code unconditionally. #if 0 struct hostent *pHostEnt=NULL; // get host entry pHostEnt = gethostbyname(szHostname); // return fully qualified name of machine as ID if (pHostEnt) hostName=pHostEnt->h_name; // DNS name of machine else #endif hostName=szHostname; // just name of machine } // generate URI from name #ifdef ANDROID aURI="android:"; #else aURI="linux:"; // %%% SCTS does not like http:// here, so we take os:xxxx #endif // add name of this machine (fully qualified if possible) aURI+=hostName; // this is more or less unique return true; } // getLocalDeviceID // write to platform's "console", whatever that is void PlatformConsolePuts(const char *aText) { // generic output #ifdef ANDROID //__android_log_write( ANDROID_LOG_DEBUG, "ConsolePuts", aText ); #else puts(aText); // appends newline itself #endif } // PlatformConsolePuts /* eof */ libsynthesis-3.4.0.47.1/src/platform_adapters/linux/ctype000077500000000000000000000001201226375725500233440ustar00rootroot00000000000000// platform has no new C++ type header for this include file #include libsynthesis-3.4.0.47.1/src/platform_adapters/linux/platform_DLL.cpp000077500000000000000000000120771226375725500253360ustar00rootroot00000000000000/* * File: platform_DLL.cpp * * Author: Beat Forster (bfo@synthesis.ch) * * * General interface to access the routines * of a DLL (LINUX platform) * * Copyright (c) 2004-2011 by Synthesis AG + plan44.ch * * */ #define DLOPEN_NO_WARN 1 #define GNU_SOURCE 1 #include // the Linux DLL functionality #include "platform_DLL.h" #include #include #include #include using namespace std; /** * Instances of this class are returned * as DLL handles to the caller of ConnectDLL. * * Loadable modules are opened dlopen() and * functions are found via dlsym(). If the * platform supports RTLD_DEFAULT and finds * a _Module_Version, then dlopen() * isn't used and all functions are searched * via RTLD_DEFAULT. */ class DLWrapper { /** * name of shared object, including suffix, * or function prefix (when functions were * linked in) * * As a special case, "//static/=
/..." is supported, * with being the name of a symbol at an address * specified as decimal value in
. */ string aDLLName; /** dlopen() result, NULL if not opened */ void *aDLL; /** result of parsing aDLLName when it contains the "static:" format. */ map fSymbols; public: DLWrapper(const char *name) : aDLLName(name), aDLL(NULL) {} /** check for linked function or open shared object, return true for success */ bool connect() { string prefix = "//static/"; if (aDLLName.substr(0, prefix.size()) == prefix) { const char *token = aDLLName.c_str() + prefix.size(); string sym; uintptr_t adr = 0; bool done = false; while (!done) { // scan name switch (*token) { case 0: // premature end done = true; break; default: sym += *token; token++; break; case '/': // symbol without address?! sym = ""; token++; break; case '=': token++; // scan decimal address while (!done && sym.size()) { switch (*token) { case 0: done = true; // fall through case '/': if (sym.size() && adr) fSymbols[sym] = (void *)adr; sym = ""; adr = 0; token++; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': adr = adr * 10 + *token - '0'; token++; break; default: // ??? token++; break; } } break; } } return true; } #ifdef RTLD_NEXT string fullname = aDLLName + "_Module_Version"; if (dlsym(RTLD_DEFAULT, fullname.c_str())) return true; #endif const char* DSuff= ".so"; string lName; string aName= aDLLName; do { aDLL = dlopen(aName.c_str(), RTLD_LAZY); if (!dlerror()) break; aName+= DSuff; aDLL = dlopen(aName.c_str(), RTLD_LAZY); if (!dlerror()) break; lName= "./"; lName+= aName; // try Linux current path as well aDLL = dlopen( lName.c_str(), RTLD_LAZY ); if (!dlerror()) break; aDLL = dlopen( aDLLName.c_str(), RTLD_LAZY ); if (!dlerror()) break; lName= "./"; lName+= aDLLName; // try Linux current path as well aDLL = dlopen( lName.c_str(), RTLD_LAZY ); } while (false); return !dlerror(); } bool destroy() { bool ok = true; if (this) { if (aDLL) { int err = dlclose(aDLL); ok = !err; } delete this; } return ok; } bool function(const char *aFuncName, void *&aFunc) { map::const_iterator it = fSymbols.find(aFuncName); if ((it) != fSymbols.end()) { aFunc = it->second; return true; } #ifdef RTLD_DEFAULT if (!aDLL) { string fullname = aDLLName + '_' + aFuncName; aFunc = dlsym(RTLD_DEFAULT, fullname.c_str()); } else #endif aFunc = dlsym(aDLL, aFuncName); return aFunc!=NULL && dlerror()==NULL; } }; bool ConnectDLL( void* &aDLL, const char* aDLLname, ErrReport aReport, void* ref ) /* Connect to , result is reference */ /* Returns true, if successful */ { DLWrapper *wrapper = new DLWrapper(aDLLname); bool ok = false; if (wrapper) { ok = wrapper->connect(); if (ok) aDLL = (void *)wrapper; else delete wrapper; } if (!ok && aReport) aReport( ref, aDLLname ); return ok; } // ConnectDLL bool DisconnectDLL( void* aDLL ) /* Disconnect */ { return ((DLWrapper *)aDLL)->destroy(); } // DisonnectDLL bool DLL_Function( void* aDLL, const char* aFuncName, void* &aFunc ) /* Get of */ /* Returns true, if available */ { return ((DLWrapper *)aDLL)->function(aFuncName, aFunc); } // DLL_Function /* eof */ libsynthesis-3.4.0.47.1/src/platform_adapters/linux/platform_exec.c000077500000000000000000000042351226375725500253040ustar00rootroot00000000000000/* * File: platform_exec.c * * Author: Lukas Zeller (luz@plan44.ch) * * Platform specific implementation for executing external commands * * Copyright (c) 2004-2011 by Synthesis AG + plan44.ch * * 2004-07-21 : luz : created * */ #include "platform_exec.h" #include #include #include // returns -1 if command could not be started, exit code of the command otherwise. // if used with aBackground==true, the return code is always 0 in case sInt32 shellExecCommand(cAppCharP aCommandName, cAppCharP aCommandParams, int aBackground) { int status; uInt32 cmdlen; char *cmd; if (!aCommandName || *aCommandName==0) return 0; // no command -> exec "successful" // simply use system() // - prepare command line cmdlen= strlen(aCommandName) + (aCommandParams ? strlen(aCommandParams) : 0) + 2; // for separator and terminator cmd=malloc(cmdlen); strcpy(cmd,aCommandName); if (aCommandParams) { strcat(cmd," "); strcat(cmd,aCommandParams); } // - execute status=system(cmd); free(cmd); return status; /* does not work ok // fork pid = fork(); alarm(0); // make sure we have no alarm running if (pid == -1) return -1; // fork failed if (pid == 0) { // forked process // prepare command line cmdlen= strlen(aCommandName) + (aCommandParams ? strlen(aCommandParams) : 0) + 2; // for separator and terminator cmd=malloc(cmdlen); strcpy(cmd,aCommandName); if (aCommandParams) { strcat(cmd," "); strcat(cmd,aCommandParams); } // prepare for execve argv[0] = "sh"; argv[1] = "-c"; argv[2] = cmd; argv[3] = 0; envp[1] = 0; // no environment execve("/bin/sh", argv, envp); // replace process, will exit with command's exit code exit(-1); // problem executing } else { // process that called fork() do { if (waitpid(pid, &status, 0) == -1) { // keep waiting if it's EINTR if (errno != EINTR) return -1; } else { // return exit status of executed process return status; } } while(1); } */ } // shellExecCommand /* eof */ libsynthesis-3.4.0.47.1/src/platform_adapters/linux/platform_exec.h000077500000000000000000000011451226375725500253060ustar00rootroot00000000000000/* * File: platform_exec.h * * Author: Lukas Zeller (luz@plan44.ch) * * Platform specific implementation for executing external commands * * Copyright (c) 2004-2011 by Synthesis AG + plan44.ch * * 2004-07-21 : luz : created * */ #include #ifdef __cplusplus extern "C" { #endif // returns -1 if command could not be started, exit code of the command otherwise. // if used with aBackground==true, the return code is always 0 in case sInt32 shellExecCommand(cAppCharP aCommandName, cAppCharP aCommandParams, int aBackground); #ifdef __cplusplus } #endif /* eof */ libsynthesis-3.4.0.47.1/src/platform_adapters/linux/platform_headers.h000077500000000000000000000011421226375725500257720ustar00rootroot00000000000000/* * File: platform_headers.h * * Author: Lukas Zeller (luz@plan44.ch) * * Common include files for all platform-related standard headers * (suitable for precompiled headers and/or prefix file) * * Copyright (c) 2003-2011 by Synthesis AG + plan44.ch * * NOTE: this file is part of the mod_sysync source files. * */ #ifndef __PLATFORM_HEADERS_H #define __PLATFORM_HEADERS_H // ANSI C #include #include #include #include #include #include // C++ #ifdef __cplusplus #endif // __cplusplus #endif // eof libsynthesis-3.4.0.47.1/src/platform_adapters/linux/platform_time.cpp000077500000000000000000000054531226375725500256610ustar00rootroot00000000000000/* * File: platform_time.cpp * * Platform specific time implementations * * Author: Lukas Zeller (luz@plan44.ch) * * Copyright (c) 2002-2011 by Synthesis AG + plan44.ch * * 2004-11-15 : luz : extracted from lineartime.h */ // For tm_gmtoff on Linux. #ifndef _BSD_SOURCE # define _BSD_SOURCE 1 #endif #include #include "prefix_file.h" #include "lineartime.h" #include "timezones.h" // Linux uses standard c time stuff //#warning "probably better use here" #ifndef ANDROID #include #include #include #endif #include #include // - Linux specific time stuff #include // - we need some library extras #define __USE_MISC 1 #ifndef ANDROID #include #endif namespace sysync { /// @brief get system real time /// @return system's real time in lineartime_t scale, in specified time zone context /// @param[in] aTimeContext desired output time zone lineartime_t getSystemNowAs(timecontext_t aTimeContext,GZones *aGZones, bool noOffset) { #ifdef NOW_WITH_MILLISECONDS // high precision time, UTC based struct timeval tv; // gettimeofday return seconds and milliseconds since start of the UNIX epoch gettimeofday(&tv,NULL); lineartime_t systime = (tv.tv_sec*secondToLinearTimeFactor+UnixToLineartimeOffset) + (tv.tv_usec*secondToLinearTimeFactor/1000000); #else // standard precision time (unix time), base is UTC time_t t = time(NULL); lineartime_t systime = t*secondToLinearTimeFactor+UnixToLineartimeOffset; #endif // - return as-is if requested time zone is UTC if (noOffset || TCTX_IS_UTC(aTimeContext)) return systime; // return as-is #ifndef ANDROID // - shortcut: conversion to system time is faster when done using // glibc. tm_gmtoff is a glibc extension, so don't try to use it on // Android. if (TCTX_IS_SYSTEM(aTimeContext)) { struct tm tm; if (localtime_r( #ifdef NOW_WITH_MILLISECONDS &tv.tv_sec #else &t #endif , &tm)) { return systime + (tm.tm_gmtoff * secondToLinearTimeFactor); } } #endif // - convert to requested zone sInt32 aOffsSeconds; if (!TzOffsetSeconds(systime,TCTX_UTC,aTimeContext,aOffsSeconds,aGZones)) return noLinearTime; // no time // return time with offset return systime + (aOffsSeconds * secondToLinearTimeFactor); } // getSystemNowAs /// @brief fine resolution sleep support /// @param[in] aHowLong desired time to wait in lineartime_t units void sleepLineartime(lineartime_t aHowLong) { // Linux has nanosleep in nanoseconds timespec sleeptime; sleeptime.tv_sec=aHowLong/secondToLinearTimeFactor; sleeptime.tv_nsec=(aHowLong % secondToLinearTimeFactor)*1000000L; nanosleep(&sleeptime,NULL); } // sleepLineartime } // namespace sysync /* eof */ libsynthesis-3.4.0.47.1/src/platform_adapters/linux/platform_time.h000077500000000000000000000026761226375725500253320ustar00rootroot00000000000000/* * File: platform_time.h * * Platform specific time implementations * * Author: Lukas Zeller (luz@plan44.ch) * * Copyright (c) 2002-2011 by Synthesis AG + plan44.ch * * 2004-11-15 : luz : extracted from lineartime.h */ #ifndef PLATFORM_TIME_H #define PLATFORM_TIME_H //#include #include "math.h" // for floor() needed in lineartime.cpp /* obsolete using namespace std; namespace sysync { // define a type for it typedef struct std::tm struct_tm; // Windows and Linux/MacOSX have UNIX-time compatible origin // which is 1970-01-01 00:00:00 // but as we have 64bit ints, we use our own linear time // in milliseconds (=24*60*60*1000*lineardate) typedef sInt32 lineardate_t; // standard Linux/Win32/MacOSX typedef sInt64 lineartime_t; const lineartime_t noLinearTime = 0x0; // undefined lineartime value const lineartime_t maxLinearTime = 0x7FFFFFFFFFFFFFFFLL; // signed 64 bit // date origin definition relative to algorithm's origin -4712-01-01 00:00:00 const lineardate_t linearDateOriginOffset=0; // no offset const sInt16 linearDateOriginWeekday=1; // Monday // scaling of lineartime relative to seconds const lineartime_t secondToLinearTimeFactor = 1000; // unit is milliseconds // On Linux, we always need the new timezones implementation #define NEW_TIMEZONES 1 // fine resolution sleep support void sleepLineartime(lineartime_t aHowLong); } // namespace sysync */ #endif // PLATFORM_TIME_H /* eof */ libsynthesis-3.4.0.47.1/src/platform_adapters/linux/platform_timezones.cpp000066400000000000000000000244061226375725500267340ustar00rootroot00000000000000/* * File: platform_timezones.cpp * * Authors: Lukas Zeller / Patrick Ohly * Beat Forster * * Time zone dependent routines for Linux * * Copyright (c) 2004-2011 by Synthesis AG + plan44.ch * * 2009-04-02 : Created by Lukas Zeller from timezones.cpp work by Patrick Ohly * */ // must be first in file, everything above is ignored by MVC compilers #include "prefix_file.h" #ifdef HAVE_CONFIG_H # include #endif #if defined(HAVE_LIBICAL) && defined(EVOLUTION_COMPATIBILITY) # ifndef _GNU_SOURCE # define _GNU_SOURCE 1 # endif # include #endif #include "timezones.h" #include "vtimezone.h" #include "sysync_debug.h" #ifdef HAVE_LIBICAL # ifndef HANDLE_LIBICAL_MEMORY # define HANDLE_LIBICAL_MEMORY 1 # endif # include #endif #ifdef LINUX extern char *tzname[ 2 ]; #ifndef BSD extern long timezone; #endif extern int daylight; #endif #ifdef EVOLUTION_COMPATIBILITY // Avoid calling libical directly. This way libsynthesis does not // depend on a specific version of libecal (which changed its soname // frequently, without affecting libical much!) or libical. The user // of libsynthesis has to make sure that the necessary ical functions // can be found via dlsym(RTLD_DEFAULT) when // loadSystemZoneDefinitions() is invoked during the initialization of // a Synthesis engine. static struct { icalarray *(* icaltimezone_get_builtin_timezones_p)(); void *(* icalarray_element_at_p)(icalarray *array, unsigned index); icalcomponent *(* icaltimezone_get_component_p)(icaltimezone *zone); char *(* icalcomponent_as_ical_string_p)(icalcomponent *comp); bool must_free_strings; } icalcontext; static icalarray *ICALTIMEZONE_GET_BUILTIN_TIMEZONES() { // Called once by loadSystemZoneDefinitions(), so initialize context // now. Redoing this on each invocation allows unloading libical // because we won't reuse stale pointers. memset(&icalcontext, 0, sizeof(icalcontext)); icalcontext.icaltimezone_get_builtin_timezones_p = (typeof(icalcontext.icaltimezone_get_builtin_timezones_p))dlsym(RTLD_DEFAULT, "icaltimezone_get_builtin_timezones"); icalcontext.icalarray_element_at_p = (typeof(icalcontext.icalarray_element_at_p))dlsym(RTLD_DEFAULT, "icalarray_element_at"); icalcontext.icaltimezone_get_component_p = (typeof(icalcontext.icaltimezone_get_component_p))dlsym(RTLD_DEFAULT, "icaltimezone_get_component"); icalcontext.icalcomponent_as_ical_string_p = (typeof(icalcontext.icalcomponent_as_ical_string_p))dlsym(RTLD_DEFAULT, "icalcomponent_as_ical_string_r"); if (icalcontext.icalcomponent_as_ical_string_p) { // found icalcomponent_as_ical_string_r() which always requires freeing icalcontext.must_free_strings = TRUE; } else { // fall back to older icalcomponent_as_ical_string() which may or may not // require freeing the returned string; this can be determined by checking // for "ical_memfixes" (EDS libical) icalcontext.icalcomponent_as_ical_string_p = (typeof(icalcontext.icalcomponent_as_ical_string_p))dlsym(RTLD_DEFAULT, "icalcomponent_as_ical_string"); icalcontext.must_free_strings = dlsym(RTLD_DEFAULT, "ical_memfixes") != NULL; } return icalcontext.icaltimezone_get_builtin_timezones_p ? icalcontext.icaltimezone_get_builtin_timezones_p() : NULL; } static void *ICALARRAY_ELEMENT_AT(icalarray *array, unsigned index) { return icalcontext.icalarray_element_at_p ? icalcontext.icalarray_element_at_p(array, index) : NULL; } static icalcomponent *ICALTIMEZONE_GET_COMPONENT(icaltimezone *zone) { return icalcontext.icaltimezone_get_component_p ? icalcontext.icaltimezone_get_component_p(zone) : NULL; } static char *ICALCOMPONENT_AS_ICAL_STRING(icalcomponent *comp) { return icalcontext.icalcomponent_as_ical_string_p ? icalcontext.icalcomponent_as_ical_string_p(comp) : NULL; } static void ICAL_FREE(char *str) { if (icalcontext.must_free_strings && str) free(str); } #else // call functions directly # define ICALTIMEZONE_GET_BUILTIN_TIMEZONES icaltimezone_get_builtin_timezones # define ICALARRAY_ELEMENT_AT icalarray_element_at # define ICALTIMEZONE_GET_COMPONENT icaltimezone_get_component # if defined(HAVE_LIBICAL) && !defined(HAVE_LIBECAL) # // new-style libical _r version which requires freeing the string # define ICALCOMPONENT_AS_ICAL_STRING icalcomponent_as_ical_string_r # define ICAL_FREE(_x) free(_x) # else # define ICALCOMPONENT_AS_ICAL_STRING icalcomponent_as_ical_string # ifdef LIBICAL_MEMFIXES // new-style Evolution libical: memory must be freed by caller # define ICAL_FREE(_x) free(_x) # else // old-style libical: memory is stored in buffers owned by libical # define ICAL_FREE(_x) # endif # endif #endif namespace sysync { /*! @brief platform specific loading of time zone definitions * @return true if this list is considered complete (i.e. no built-in zones should be used additionally) * @param[in/out] aGZones : the GZones object where system zones should be loaded into */ bool loadSystemZoneDefinitions(GZones* aGZones) { // always add the builtin time zones return false; } // loadSystemZoneDefinitions /*! @brief we use this callback to add and log libical time zone handling * * The advantage is that this handling can be logged. The disadvantage * is that these time zones cannot be used in the configuration. Builtin * time zones (if any) have to be used there. */ void finalizeSystemZoneDefinitions(GZones* aGZones) { // load zones from system here #ifdef HAVE_LIBICAL PLOGDEBUGBLOCKDESCCOLL(aGZones->getDbgLogger, "loadSystemZoneDefinitions", "Linux system time zones"); icalarray *builtin = ICALTIMEZONE_GET_BUILTIN_TIMEZONES(); #ifdef EVOLUTION_COMPATIBILITY PLOGDEBUGPRINTFX(aGZones->getDbgLogger, DBG_PARSE+DBG_EXOTIC, ("runtime check: libical %s", icalcontext.icaltimezone_get_builtin_timezones_p ? "available" : "unavailable")) #endif if (!builtin) { PLOGDEBUGPUTSX(aGZones->getDbgLogger, DBG_PARSE+DBG_ERROR, "could not read timezone information from libical"); return; } PLOGDEBUGPRINTFX(aGZones->getDbgLogger, DBG_PARSE+DBG_EXOTIC, ("%d time zones from libical", builtin->num_elements)); for (unsigned i = 0; builtin && i < builtin->num_elements; i++) { icaltimezone *zone = (icaltimezone *)ICALARRAY_ELEMENT_AT(builtin, i); if (!zone) continue; icalcomponent *comp = ICALTIMEZONE_GET_COMPONENT(zone); if (!comp) continue; char *vtimezone = ICALCOMPONENT_AS_ICAL_STRING(comp); if (!vtimezone) continue; PLOGDEBUGPUTSX(aGZones->getDbgLogger, DBG_PARSE+DBG_EXOTIC, vtimezone); tz_entry t; if (VTIMEZONEtoTZEntry( vtimezone, t, #ifdef SYDEBUG aGZones->getDbgLogger #endif )) { t.ident = ""; t.dynYear = ""; // expect Olson /// TZIDs and // extract the trailing location (which might contain // several slashes, so a backwards search doesn't work) std::string::size_type off; if (t.name.size() > 2 && t.name[0] == '/' && (off = t.name.find('/', 1)) != t.name.npos && (off = t.name.find('/', off + 1)) != t.name.npos) { t.location = t.name.substr(off + 1); // also use that simplified location as TZID (shorter, // some (broken) storages like the N900 calendar can only // handle such shortened TZIDs while correct storages // should be able to handle both) t.name = t.location; } aGZones->tzP.push_back(t); } ICAL_FREE(vtimezone); } PLOGDEBUGENDBLOCK(aGZones->getDbgLogger, "loadSystemZoneDefinitions"); #else PLOGDEBUGPUTSX(aGZones->getDbgLogger, DBG_PARSE+DBG_EXOTIC, "support for libical not compiled"); #endif // HAVE_LIBICAL } // finalizeSystemZoneDefinitions /*! @brief get current system time zone * @return true if successful * @param[out] aContext : the time zone context representing the current system time zone. * @param[in] aGZones : the GZones object. */ bool getSystemTimeZoneContext(timecontext_t &aContext, GZones* aGZones) { tz_entry t; bool ok = true; #ifdef ANDROID time_t rawtime; time( &rawtime ); struct tm* timeinfo= localtime( &rawtime ); //struct tm* utc_info= gmtime( &rawtime ); //if (timeinfo) t.name= timeinfo->tm_zone; //__android_log_write( ANDROID_LOG_DEBUG, "tzname[ 0 ]", tzname[ 0 ] ); //__android_log_write( ANDROID_LOG_DEBUG, "tzname[ 1 ]", tzname[ 1 ] ); #else tzset(); #endif if (t.name=="") { t.name = tzname[ 0 ]; if (strcmp( t.name.c_str(), tzname[ 1 ] )!=0) { t.name+= "/"; t.name+= tzname[ 1 ]; } // if } // if //if (isDbg) PNCDEBUGPRINTFX( DBG_SESSION, ( "Timezone: %s", sName.c_str() )); // search based on name before potentially using offset search if (TimeZoneNameToContext( t.name.c_str(),aContext, aGZones )) { //#ifdef ANDROID // __android_log_print( ANDROID_LOG_DEBUG, "tz ok", "'%s' %d\n", t.name.c_str(), aContext ); //#endif return true; // found, done } #if defined USE_TM_GMTOFF else { // We can use tm_gmtoff as fallback when the name computed above doesn't // match: identify offsets, then search based on offsets. time_t now = time(NULL); bool have_dst = false, have_std = false; // start searching for offsets today, moving ahead one week at a time int week = 0; do { struct tm tm; time_t day = now + 60 * 60 * 24 * 7 * week; localtime_r(&day, &tm); if (tm.tm_isdst) { if (!have_dst) { t.biasDST = tm.tm_gmtoff / 60; have_dst = true; } } else { if (!have_std) { t.bias = tm.tm_gmtoff / 60; have_std = true; } } week++; } while ((!have_std || !have_dst) && week <= 54); if (have_dst) { if (have_std) { // make biasDST relative to bias t.biasDST -= t.bias; } else { // daylight saving without standard?! } } // search for name based on offsets t.ident="o"; if (FoundTZ(t, t.name, aContext, aGZones)) goto done; } #endif // USE_TM_GMTOFF // not enough information to create a new time zone below, give up ok = false; done: return ok; } // getSystemTimeZoneContext } // namespace sysync /* eof */ libsynthesis-3.4.0.47.1/src/platform_adapters/linux/profiling.cpp000077500000000000000000000010051226375725500247750ustar00rootroot00000000000000/* * File: profiling.cpp * * Author: Lukas Zeller (luz@plan44.ch) * * Platform-dependent profiling implementation * * Copyright (c) 2002-2011 by Synthesis AG + plan44.ch * * 2002-10-01 : luz : created * */ #include "profiling.h" #include "sysync_globs.h" #ifdef TIME_PROFILING #error "No time profiling for linux yet" #endif // TIME_PROFILING #ifdef MEMORY_PROFILING #error "No memory profiling for linux yet" #error "Seems to be dangerous" #endif // MEMORY_PROFILING /* eof */ libsynthesis-3.4.0.47.1/src/platform_adapters/macosx/000077500000000000000000000000001226375725500224345ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/platform_adapters/macosx/configfiles.mm000066400000000000000000000245701226375725500252670ustar00rootroot00000000000000/* * File: configfiles.mm * * Author: Lukas Zeller (luz@plan44.ch) * * iPhoneOS Platform adaptor * * Copyright (c) 2008-2012 by plan44.ch + Synthesis AG * * 2008-06-12 : luz : created * */ #import #import #import #include "sysync.h" #ifdef MOBOSX #import #else #include #include extern "C" { #include #include #include } #endif #ifdef MOBOSX // iPhone // determine OS version static bool getOSVersion(string &aOSVersion) { UIDevice *theDevice = [UIDevice currentDevice]; // Obtain OS Version // - Name aOSVersion = [theDevice.systemName UTF8String]; aOSVersion += "/"; // - Version aOSVersion += [theDevice.systemVersion UTF8String]; return true; } // getOSVersion // determine hardware name static bool getHardwareName(string &aHardwareName) { UIDevice *theDevice = [UIDevice currentDevice]; // device name aHardwareName = [theDevice.model UTF8String]; return true; } // getHardwareName static void getMacDir(string &aString, bool aIsTemp) { // get home or temp directory NSString *dir; if (aIsTemp) dir = NSTemporaryDirectory(); else dir = NSHomeDirectory(); aString = [dir UTF8String]; } // getMacDir #else // Mac OS X // determine OS version static bool getOSVersion(string &aOSVersion) { // Obtain OS Version int mib[2]; size_t len; char *p; mib[0] = CTL_KERN; // - %%% we can't easily get the 10.x.x string, so what we show here is the Darwin version mib[1] = KERN_OSTYPE; sysctl(mib, 2, NULL, &len, NULL, 0); p = (char *)malloc(len); sysctl(mib, 2, p, &len, NULL, 0); aOSVersion = p; free(p); aOSVersion += "/"; mib[1] = KERN_OSRELEASE; sysctl(mib, 2, NULL, &len, NULL, 0); p = (char *)malloc(len); sysctl(mib, 2, p, &len, NULL, 0); aOSVersion += p; free(p); return true; } // getOSVersion // determine hardware name static bool getHardwareName(string &aHardwareName) { // device name // - use sysctl to get machine/model name int mib[2]; size_t len; char *p; mib[0] = CTL_HW; // - the machine (is the name on MOBOSX "iPod1,1", but the CPU Architecture for MacOSX "i386") mib[1] = HW_MACHINE; sysctl(mib, 2, NULL, &len, NULL, 0); p = (char *)malloc(len); sysctl(mib, 2, p, &len, NULL, 0); aHardwareName = p; free(p); aHardwareName += "/"; // - the model (is the model number on MOBOSX "N45AP", "M68xx", but the model of MacOSX "MacBookPro1,2" mib[1] = HW_MODEL; sysctl(mib, 2, NULL, &len, NULL, 0); p = (char *)malloc(len); sysctl(mib, 2, p, &len, NULL, 0); aHardwareName += p; free(p); return true; } // getHardwareName static void getMacDir(string &aString, bool aIsTemp) { #ifdef xxxxxyyyyGUGUS // %%% probably use getEnv(HOME) and TEMP resp. CFStringRef cfstr; if (aIsTemp) cfstr = (CFStringRef)NSTemporaryDirectory(); else cfstr = (CFStringRef)NSHomeDirectory(); // convert to UTF8 application string CFStringGetCString(cfstr,buffer,bufsiz,kCFStringEncodingUTF8); CFRelease(cfstr); aString = buffer; #else #ifdef MOBOSX #warning "must get real HOME and TMP env vars or leave these undefined" // %%% hoping for app starting in its HOME dir anyway if (aIsTemp) aString = "./tmp"; else aString = "."; #else // Mac OS X is unix style if (aIsTemp) { aString = "/tmp"; } else { struct passwd *userInfoP=NULL; userInfoP = getpwuid(getuid()); aString = userInfoP->pw_dir; // home dir } #endif // mac os x #endif // q&d methods } // getMacDir #endif /// @brief get platform specific string by ID /// @return false if string is not available for this platform /// @param aStringID string selector ID /// @param aString will receive the requested string bool getPlatformString(TPlatformStringID aStringID, string &aString) { const sInt16 bufsiz=1024; char buffer[bufsiz]; buffer[0]=0; // terminate for safety string str; switch (aStringID) { case pfs_platformvers: // Platform OS version string getOSVersion(aString); break; case pfs_device_uri: getLocalDeviceID(aString); break; case pfs_device_name: getHardwareName(aString); break; case pfs_loccfg_path: #ifdef STANDALONE_APP // default path for local config for XPT standalones is the current dir aString = "."; break; #endif // for server modules, it is same as the global config path #ifndef STANDALONE_APP case pfs_globcfg_path: // global config directory path aString = "/etc"; break; #endif case pfs_defout_path: // default output path (formerly: default write path) #ifdef STANDALONE_APP // default path for local config for XPT standalones is the current dir aString = "."; #else // for server modules, default log path is /var/log aString = "/var/log"; #endif break; case pfs_temp_path: // temp path, common for Mac OS X and iPhoneOS getMacDir(aString,true); break; case pfs_userdir_path: getMacDir(aString,false); break; // iPhone OS, with sandboxed apps case pfs_prefs_path: // "application support" is also in sandbox Documents case pfs_appdata_path: // appdata for iPhone is just Documents in the app Sandbox getMacDir(aString,false); aString += "/Documents"; break; case pfs_exedir_path: exedir: // path where module file resides (bundle path) aString = [[[NSBundle mainBundle] bundlePath] UTF8String]; break; default: // unknown ID return false; } // ok return true; } // getPlatformString extern "C" { #include #include } /// @brief update string such that it can be used as target OS directory path /// (filename can be appended without any separator) /// @param aPath path to be updated /// @param aMakeDirs if set, directories along path are created if not existing /// @return false if directory does not exist or could not be created (when aMakeDirs is set) bool makeOSDirPath(string &aPath, bool aMakeDirs) { // make sure path ends with backslash uInt32 n=aPath.size(); if (n>2 && aPath[n-1]!='/') aPath+='/'; // now make sure path exists if requested if (aMakeDirs) { // no slash at the end string tmppath; tmppath.assign(aPath,0,aPath.size()-1); // optimization check if entire path exists struct stat statinfo; int rc=stat(aPath.c_str(),&statinfo); if(rc!=0 || !S_ISDIR(statinfo.st_mode)) { // path does not exist yet - start from beginning to create it n=0; bool knownmissing=false; // skip first slash for absolute paths if (aPath[0]=='/') n+=1; // skip do { // find first directory in path n=aPath.find("/",n); // if no more separators to find, all dirs exist now if (n==string::npos) break; tmppath.assign(aPath,0,n); n+=1; // skip separator if (!knownmissing) { // test if this dir exists rc=stat(tmppath.c_str(),&statinfo); if(rc!=0 || !S_ISDIR(statinfo.st_mode)) { knownmissing=true; } } if (knownmissing) { // create the subdir (might fail if part of path already exists) if (mkdir(tmppath.c_str(),S_IRWXU)!=0) return false; // failure to create directory } } while(true); } // path does not exist yet entirely } // make path existing return true; } // makeOSDirPath // returns timestamp (UTC) of last file modification or 0 if none known lineartime_t getFileModificationDate(const char *aFileName) { struct stat st; lineartime_t res; if (stat(aFileName,&st)!=0) res=0; else { // stat ok, get modification date res= ((lineartime_t)st.st_mtime * secondToLinearTimeFactor) + UnixToLineartimeOffset; } // return timestamp return res; } // getFileModificationDate #ifdef MOBOSX // iOS // get local device URI/ID bool getLocalDeviceID(string &aURI) { UIDevice *theDevice = [UIDevice currentDevice]; NSString *deviceID = nil; #ifdef __IPHONE_6_0 if ([theDevice respondsToSelector:@selector(identifierForVendor)]) { // iOS 6 style identifier NSUUID *ifv = [theDevice identifierForVendor]; if (ifv) { deviceID = [ifv UUIDString]; if (deviceID && [deviceID isEqualToString:@"00000000-0000-0000-0000-000000000000"]) { deviceID = nil; // not valid, forget it! } } } #endif if (deviceID==nil) { // Obtain old-style unique ID, in disguise because we should not use it any more // "uniqueIdentifier" SEL uiSEL = NSSelectorFromString([NSString stringWithFormat:@"un%c%cu%1xI%2xnti%1xier",'i','q',0x0E,0xDE,0x0F]); deviceID = [theDevice performSelector:uiSEL]; } // now return if ok if (deviceID) { aURI = [deviceID UTF8String]; return true; } else { aURI = "iOSDev-without-unique-ID"; return false; // no unique device ID } } // getLocalDeviceID #else // Mac OS X // get local device URI/ID bool getLocalDeviceID(string &aURI) { // Get serial number from IOKit CFStringRef serialNumber = NULL; io_service_t platformExpert = IOServiceGetMatchingService( kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice") ); if (platformExpert) { CFTypeRef serialNumberAsCFString = IORegistryEntryCreateCFProperty( platformExpert, CFSTR(kIOPlatformSerialNumberKey), kCFAllocatorDefault, 0 ); if (serialNumberAsCFString) { serialNumber = (CFStringRef)serialNumberAsCFString; } IOObjectRelease(platformExpert); } if (serialNumber) { // found serial number // - get as C string const size_t bufSiz=100; char serialBuf[bufSiz]; if (CFStringGetCString( serialNumber, serialBuf, bufSiz, kCFStringEncodingUTF8 )) { // now put into STL string aURI = "OSX:"; aURI += serialBuf; } // release the CFString CFRelease(serialNumber); // unique number found return true; } // no serial aURI = "OSX_without_serial"; return false; } // getLocalDeviceID #endif // write to platform's "console", whatever that is void PlatformConsolePuts(const char *aText) { // generic standard output puts(aText); // appends newline itself } // PlatformConsolePuts /* eof */ libsynthesis-3.4.0.47.1/src/platform_adapters/macosx/platform_exec.c000066400000000000000000000021761226375725500254360ustar00rootroot00000000000000/* * File: platform_exec.c * * Author: Lukas Zeller (luz@plan44.ch) * * Platform specific implementation for executing external commands * * Copyright (c) 2004-2011 by Synthesis AG + plan44.ch * * 2004-07-21 : luz : created * */ #include "platform_exec.h" #include #include #include // returns -1 if command could not be started, exit code of the command otherwise. // if used with aBackground==true, the return code is always 0 in case sInt32 shellExecCommand(cAppCharP aCommandName, cAppCharP aCommandParams, int aBackground) { int status; uInt32 cmdlen; char *cmd; if (!aCommandName || *aCommandName==0) return 0; // no command -> exec "successful" // simply use system() // - prepare command line cmdlen= strlen(aCommandName) + (aCommandParams ? strlen(aCommandParams) : 0) + 2; // for separator and terminator cmd= (char*)malloc(cmdlen); strcpy(cmd,aCommandName); if (aCommandParams) { strcat(cmd," "); strcat(cmd,aCommandParams); } // - execute status=system(cmd); free(cmd); return status; } // shellExecCommand /* eof */libsynthesis-3.4.0.47.1/src/platform_adapters/macosx/platform_exec.h000066400000000000000000000011461226375725500254370ustar00rootroot00000000000000/* * File: platform_exec.h * * Author: Lukas Zeller (luz@plan44.ch) * * Platform specific implementation for executing external commands * * Copyright (c) 2004-2011 by Synthesis AG + plan44.ch * * 2004-07-21 : luz : created * */ #include #ifdef __cplusplus extern "C" { #endif // returns -1 if command could not be started, exit code of the command otherwise. // if used with aBackground==true, the return code is always 0 in case sInt32 shellExecCommand(cAppCharP aCommandName, cAppCharP aCommandParams, int aBackground); #ifdef __cplusplus } #endif /* eof */libsynthesis-3.4.0.47.1/src/platform_adapters/macosx/platform_headers.h000077500000000000000000000011751226375725500261330ustar00rootroot00000000000000/* * File: platform_headers.h * * Author: Lukas Zeller (luz@plan44.ch) * * Common include files for all platform-related standard headers * (suitable for precompiled headers and/or prefix file) * * Copyright (c) 2003-2011 by Synthesis AG + plan44.ch * * 2003-08-12 : luz : created * */ #ifndef __PLATFORM_HEADERS_H #define __PLATFORM_HEADERS_H // ANSI C #ifndef __GNUC__ #include "MacHeadersMach-O.c" #endif // for the pipes #include #include // C++ #ifdef __cplusplus // These are the C++ MSL headers #ifndef __GNUC__ #include "MSLHeaders++.cp" #endif #endif #endiflibsynthesis-3.4.0.47.1/src/platform_adapters/macosx/platform_time.cpp000066400000000000000000000041621226375725500260050ustar00rootroot00000000000000/* * File: platform_time.cpp * * Platform specific time implementations * * Author: Lukas Zeller (luz@plan44.ch) * * Copyright (c) 2002-2011 by Synthesis AG + plan44.ch * * 2004-11-15 : luz : extracted from lineartime.h */ #include "prefix_file.h" #include "lineartime.h" #include "timezones.h" // MacOS X uses standard c time stuff // - now include #include "math.h" #include "limits.h" #include "stdarg.h" #include "stdlib.h" #include "stdio.h" #include "string.h" #include namespace sysync { /// @brief get system real time /// @return system's real time in lineartime_t scale, in specified time zone context /// @param[in] aTimeContext desired output time zone lineartime_t getSystemNowAs(timecontext_t aTimeContext,GZones *aGZones, bool noOffset) { #ifdef NOW_WITH_MILLISECONDS // high precision time, UTC based struct timeval tv; struct timezone tz; // gettimeofday return seconds and milliseconds since start of the UNIX epoch gettimeofday(&tv,&tz); lineartime_t systime = (tv.tv_sec*secondToLinearTimeFactor+UnixToLineartimeOffset) + (tv.tv_usec*secondToLinearTimeFactor/1000000); #else // standard precision time (unix time), base is UTC lineartime_t systime = time(NULL)*secondToLinearTimeFactor+UnixToLineartimeOffset; #endif // - return as-is if requested time zone is UTC if (noOffset || TCTX_IS_UTC(aTimeContext)) return systime; // return as-is // - convert to requested zone sInt32 aOffsSeconds; if (!TzOffsetSeconds(systime,TCTX_UTC,aTimeContext,aOffsSeconds,aGZones)) return noLinearTime; // no time // return time with offset return systime + (aOffsSeconds * secondToLinearTimeFactor); } // getSystemNowAs /// @brief fine resolution sleep support /// @param[in] aHowLong desired time to wait in lineartime_t units void sleepLineartime(lineartime_t aHowLong) { // Linux has nanosleep in nanoseconds timespec sleeptime; sleeptime.tv_sec=aHowLong/secondToLinearTimeFactor; sleeptime.tv_nsec=(aHowLong % secondToLinearTimeFactor)*1000000L; nanosleep(&sleeptime,NULL); } // sleepLineartime } // namespace sysync /* eof */libsynthesis-3.4.0.47.1/src/platform_adapters/macosx/platform_time.h000066400000000000000000000025011226375725500254450ustar00rootroot00000000000000/* * File: platform_time.h * * Platform specific time implementations * * Author: Lukas Zeller (luz@plan44.ch) * * Copyright (c) 2002-2011 by Synthesis AG + plan44.ch * * 2004-11-15 : luz : extracted from lineartime.h */ #ifndef PLATFORM_TIME_H #define PLATFORM_TIME_H #include /* obsolete using namespace std; namespace sysync { // define a type for it typedef struct tm struct_tm; // Windows and Linux/MacOSX have UNIX-time compatible origin // which is 1970-01-01 00:00:00 // but as we have 64bit ints, we use our own linear time // in milliseconds (=24*60*60*1000*lineardate) typedef sInt32 lineardate_t; // standard Linux/Win32/MacOSX typedef sInt64 lineartime_t; const lineartime_t noLinearTime = 0x0; // undefined lineartime value const lineartime_t maxLinearTime = 0x7FFFFFFFFFFFFFFFLL; // signed 64 bit, defined as long long // date origin definition relative to algorithm's origin -4712-01-01 00:00:00 const lineardate_t linearDateOriginOffset=0; // no offset const sInt16 linearDateOriginWeekday=1; // Monday // scaling of lineartime relative to seconds const lineartime_t secondToLinearTimeFactor = 1000; // unit is milliseconds // fine resolution sleep support void sleepLineartime(lineartime_t aHowLong); } // namespace sysync */ #endif // PLATFORM_TIME_H /* eof */ libsynthesis-3.4.0.47.1/src/platform_adapters/macosx/platform_timezones.mm000066400000000000000000000105531226375725500267140ustar00rootroot00000000000000/* * File: platform_timezones.mm * * Author: Lukas Zeller * * Time zone dependent routines for Mac OS X * * Copyright (c) 2004-2011 by Synthesis AG + plan44.ch * * 2009-04-02 : Created by Lukas Zeller * */ #include "prefix_file.h" #include "timezones.h" #import namespace sysync { /* Note: this is ugly poor man's implementation and only uses plain Unix facilities to hopefully * find the time zone (by name). * The plan is to enhance this using Foundation APIs later */ /*! @brief platform specific loading of time zone definitions * @return true if this list is considered complete (i.e. no built-in zones should be used additionally) * @param[in/out] aGZones : the GZones object where system zones should be loaded into */ bool loadSystemZoneDefinitions(GZones* aGZones) { // load zones from system here // ... // return true if this list is considered complete (i.e. no built-in zones should be used additionally) return false; // we need the built-in zones } // loadSystemZoneDefinitions /*! @brief we use this callback to add and log libical time zone handling * * The advantage is that this handling can be logged. The disadvantage * is that these time zones cannot be used in the configuration. Builtin * time zones (if any) have to be used there. */ void finalizeSystemZoneDefinitions(GZones* aGZones) { /* nop for now */ } // finalizeSystemZoneDefinitions // Get system time zone information via NSTimeZone static bool getSystemTimeZone(string &aZoneName, sInt16 &aStdBias, sInt16 &aDstBias, lineartime_t &aStdStart, lineartime_t &aDstStart) { NSTimeZone *sysZone = [NSTimeZone systemTimeZone]; // get name // Note: we use the oldfashioned tzset() way to make sure we don't break what already works // Probably we could construct the same string using abbreviationForDate: tzset(); aZoneName = tzname[0]; if (strcmp(aZoneName.c_str(),tzname[1])!=0) { aZoneName += "/"; aZoneName += tzname[1]; } // get info per now bool isDaylightNow = [sysZone isDaylightSavingTime]; sInt32 utcOffsetNow = [sysZone secondsFromGMT]; // next transition (away from current state) NSDate *nextTransition = [sysZone nextDaylightSavingTimeTransition]; // the transition after that NSDate *backTransition = [sysZone nextDaylightSavingTimeTransitionAfterDate:[nextTransition dateByAddingTimeInterval:24*60*60]]; // depends on current daylight or not if (isDaylightNow) { // DST active, next transition is start of STD sInt32 daylightOffset = (sInt32)[sysZone daylightSavingTimeOffset]; aDstBias = daylightOffset/60; aStdBias = (utcOffsetNow-daylightOffset)/60; aStdStart = (lineartime_t)([nextTransition timeIntervalSince1970]*1000.0)+UnixToLineartimeOffset + (aStdBias+aDstBias)*60*secondToLinearTimeFactor; aDstStart = (lineartime_t)([backTransition timeIntervalSince1970]*1000.0)+UnixToLineartimeOffset + aStdBias*60*secondToLinearTimeFactor; } else { // STD active, next transition is start of DST // Note: backTransition IS NO LONGER (iOS 4.2.1 at least!) in DST, so use a time one day after to-DST transition which MUST be in DST! sInt32 daylightOffset = (sInt32)[sysZone daylightSavingTimeOffsetForDate:[nextTransition dateByAddingTimeInterval:24*60*60]]; aStdBias = utcOffsetNow/60; aDstBias = daylightOffset/60; aDstStart = (lineartime_t)([nextTransition timeIntervalSince1970]*1000.0)+UnixToLineartimeOffset + aStdBias*60*secondToLinearTimeFactor; aStdStart = (lineartime_t)([backTransition timeIntervalSince1970]*1000.0)+UnixToLineartimeOffset + (aStdBias+aDstBias)*60*secondToLinearTimeFactor; } return true; } // getSystemTimeZone /*! @brief get current system time zone * @return true if successful * @param[out] aContext : the time zone context representing the current system time zone. * @param[in] aGZones : the GZones object. */ bool getSystemTimeZoneContext(timecontext_t &aContext, GZones* aGZones) { tz_entry t; t.name = ""; t.bias = 0; t.biasDST = 0; t.dst.wMonth= 0; sInt16 y; lineartime_t stdTime, dstTime; if (getSystemTimeZone( t.name, t.bias,t.biasDST, stdTime,dstTime )) { Get_tChange( stdTime, t.std, y ); Get_tChange( dstTime, t.dst, y ); } // search entry, first by rule return ContextForEntry(aContext, t, false, aGZones); } // getSystemTimeZoneContext } // namespace sysync /* eof */libsynthesis-3.4.0.47.1/src/platform_adapters/macosx/profiling.cpp000077500000000000000000000007561226375725500251440ustar00rootroot00000000000000/* * File: profiling.cpp * * Author: Lukas Zeller (luz@plan44.ch) * * Platform-dependent profiling implementation * * Copyright (c) 2002-2011 by Synthesis AG + plan44.ch * * 2002-10-01 : luz : created * */ #include "profiling.h" #ifdef TIME_PROFILING #error "No time profiling for macosx yet" #endif // TIME_PROFILING #ifdef MEMORY_PROFILING #error "No memory profiling for macosx yet" #error "Seems to be dangerous" #endif // MEMORY_PROFILING /* eof */libsynthesis-3.4.0.47.1/src/platform_adapters/platform_DLL.h000077500000000000000000000020461226375725500236370ustar00rootroot00000000000000/* * File: platform_DLL.h * * Author: Beat Forster (bfo@synthesis.ch) * * * General interface to access the routines * of a DLL. * * Copyright (c) 2004-2011 by Synthesis AG + plan44.ch * * */ #ifndef PLATFORM_DLL_H #define PLATFORM_DLL_H #include "target_options.h" #include // NULL #include using namespace std; // ------------------------------------------------------------------ // Error handler procedure type typedef void (*ErrReport)( void* ref, const char* aName ); typedef void (*ErrMReport)( void* ref, const char* aName, const char* aModName ); bool ConnectDLL( void* &aMod, const char* aModName, ErrReport aReport, void* ref= NULL ); /* Connect to , result is reference */ /* Returns 0, if successful */ bool DLL_Function( void* aMod, const char* aFuncName, void* &aFunc ); /* Get of at */ /* Returns 0, if available */ bool DisconnectDLL( void* aMod ); /* Disconnect . Returns 0, if operation successful */ #endif /* PLATFORM_DLL_H */ /* eof */ libsynthesis-3.4.0.47.1/src/platform_adapters/platform_file.h000077500000000000000000000016321226375725500241430ustar00rootroot00000000000000/* * File: platform_file.h * * Author: Beat Forster (bfo@synthesis.ch) * * * General interface to get/set file info * like date/attributes/... * * Copyright (c) 2005-2011 by Synthesis AG + plan44.ch * * */ #ifndef PLATFORM_FILE_H #define PLATFORM_FILE_H #include "sync_dbapidef.h" #include using namespace std; namespace sysync { /*! File attributes */ struct TAttr { bool h,s,a,d,w,r,x; }; // TAttr /*! File dates */ struct TDates { /* ISO8601 format, usually as localtime */ string created, modified, accessed; }; // TDates /* Get/set attributes */ TSyError Get_FileAttr( string pathName, TAttr &aAttr, bool &isFolder ); TSyError Set_FileAttr( string pathName, TAttr aAttr ); /* Get/set file dates */ TSyError Get_FileDate( string pathName, TDates &aDate ); TSyError Set_FileDate( string pathName, TDates aDate ); } // namespace #endif /* PLATFORM_FILE_H */ /* eof */ libsynthesis-3.4.0.47.1/src/platform_adapters/platform_headers.h000077500000000000000000000010201226375725500246260ustar00rootroot00000000000000/* * File: platform_headers.h * * Author: Lukas Zeller (luz@plan44.ch) * * Common include files for all platform-related standard headers * (suitable for precompiled headers and/or prefix file) * * Copyright (c) 2003-2011 by Synthesis AG + plan44.ch * * 2003-08-12 : luz : created * */ #ifndef __PLATFORM_HEADERS_H #define __PLATFORM_HEADERS_H // ANSI C #warning "platform_headers.h should be platform-specific!" // C++ #ifdef __cplusplus // These are the C++ MSL headers #endif #endif libsynthesis-3.4.0.47.1/src/platform_adapters/platform_mutex.h000077500000000000000000000007241226375725500243670ustar00rootroot00000000000000/* * File: platform_mutex.h * * Author: Beat Forster (bfo@synthesis.ch) * * * Mutex handling * * Copyright (c) 2005-2011 by Synthesis AG + plan44.ch * * */ #ifndef PLATFORM_MUTEX_H #define PLATFORM_MUTEX_H typedef void* MutexPtr_t; MutexPtr_t newMutex(); bool lockMutex( MutexPtr_t m ); bool tryLockMutex( MutexPtr_t m ); bool unlockMutex( MutexPtr_t m ); void freeMutex( MutexPtr_t m ); #endif /* PLATFORM_MUTEX_H */ /* eof */ libsynthesis-3.4.0.47.1/src/platform_adapters/platform_thread.h000077500000000000000000000061011226375725500244670ustar00rootroot00000000000000/* * File: platform_thread.h * * Author: Lukas Zeller (luz@plan44.ch) * * Platform specific thread object implementation * * Copyright (c) 2004-2011 by Synthesis AG + plan44.ch * * 2004-04-15 : luz : created * */ #ifndef PLATFORM_THREAD_H #define PLATFORM_THREAD_H #include #ifdef _WIN32 #include #endif #if defined(ANDROID) || defined(LINUX) #include #endif #if defined(LINUX) # include typedef unsigned long uIntArch; // Used for pid_t, pointers and pthread_t. #endif /* #ifndef _MSC_VER using namespace sysync; #endif */ namespace sysync { // get id of the running process uIntArch myProcessID(); // get id of the running thread uIntArch myThreadID(); class TThreadObject; // forward // function executed by thread typedef uInt32 (*TThreadFunc)(TThreadObject *aThreadObject, uIntArch aParam); // wrapper class for thread class TThreadObject { public: // creates thread object. Thread ist not started yet, must use launch() for this TThreadObject(); // destroys the thread object virtual ~TThreadObject(); // starts thread (or re-starts it again after termination) bool launch( TThreadFunc aThreadFunc=NULL, // the function to execute in the thread uIntArch aThreadFuncParam=0, // a parameter to pass to the thread size_t aStackSize=0, // if 0, default stack size is used bool aAutoDispose=false // if true, the thread object will dispose itself when thread has finished running ); // get thread ID uIntArch getid(void); // soft-terminates thread (sets a flag which requests execute() to terminate void terminate(void) { fTerminationRequested=true; }; // hard (emergency) terminate (aborts processing on the OS level) void kill(void); // wait for termination of the thread, returns true if so within specified time // negative wait time means waiting infinitely. bool waitfor(sInt32 aMilliSecondsToWait=0); // get exit code of the thread (valid only if thread has already terminated uInt32 exitcode(void) { return fExitCode; }; // This method is the thread function itself // - can be derived to create special threads // default behaviour is to call the fThreadFunc with this and fThreadFuncParam virtual uInt32 execute(void); // checks for termination request bool terminationRequested(void) { return fTerminationRequested; }; private: // thread options uInt32 fStackSize; // the thread function TThreadFunc fThreadFunc; uIntArch fThreadFuncParam; // the termination request flag bool fTerminationRequested; // the exit code uInt32 fExitCode; public: // auto disposal of the thread object when thread exits bool fAutoDisposeThreadObj; private: #ifdef _WIN32 // the windows thread HANDLE fWinThreadHandle; DWORD fWinThreadId; #endif #if defined LINUX || defined MACOSX // the linux POSIX thread public: pthread_t fPosixThread; pthread_mutex_t fDoneCondMutex; pthread_cond_t fDoneCond; bool fTerminated; // really finished #endif }; } // namespace sysync #endif // PLATFORM_THREAD_H /* eof */ libsynthesis-3.4.0.47.1/src/platform_adapters/profiling.h000077500000000000000000000130141226375725500233060ustar00rootroot00000000000000/* * File: profiling.h * * Author: Lukas Zeller (luz@plan44.ch) * * Platform-dependent profiling implementation * * Copyright (c) 2002-2011 by Synthesis AG + plan44.ch * * 2002-10-01 : luz : created * */ #ifndef _PROFILING_H #define _PROFILING_H #ifdef __cplusplus //#include "sysync.h" #include "generic_types.h" #include "lineartime.h" #include "sysync_globs.h" #endif #ifdef TIME_PROFILING #ifdef __cplusplus typedef enum { TP_general, TP_database, TP_configread, TP_scripts, TP_dbgout, TP_none, // does not count } TTP_Types; const sInt16 numTPTypes = TP_none-TP_general; // do not count TP_none extern const char * const TP_TypeNames[numTPTypes]; // a profiling timer typedef struct { long long kerneltime; long long usertime; } TTP_Timer; // profiling info packet typedef struct { TTP_Timer fTP_last; TTP_Timer fTP_total; TTP_Timer fTP_times[numTPTypes]; bool fTP_started; TTP_Types fTP_lastindex; lineartime_t fTP_startrealtime; } TTP_info; // opaque pointer typedef void *TTP_infoP; // initialize time profiling void TP_Init(TTP_infoP aTpinfoP); // start profiling a certain part of the code TTP_Types TP_Start(TTP_infoP aTpinfoP, TTP_Types aTimerIdx); // stop profiling void TP_Stop(TTP_infoP aTpinfoP); // get profiled information uInt32 TP_GetSystemMS(TTP_infoP aTpinfoP,TTP_Types aTimerIdx=TP_none); uInt32 TP_GetUserMS(TTP_infoP aTpinfoP,TTP_Types aTimerIdx=TP_none); uInt32 TP_GetRealtimeMS(TTP_infoP aTpinfoP); #endif // C++ // active macros #define TP_DEFINFO(x) TTP_info x; #define TP_DEFIDX(i) TTP_Types i #define TP_INIT(i) TP_Init(&i) #define TP_START(i,x) { if (PDEBUGMASK & DBG_PROFILE) TP_Start(&i,x); } #define TP_SWITCH(l,i,x) { if (PDEBUGMASK & DBG_PROFILE) l=TP_Start(&i,x); } #define TP_STOP(i) { if (PDEBUGMASK & DBG_PROFILE) TP_Stop(&i); } #define TP_GETSYSTEMMS(i,x) TP_GetSystemMS(&i,x) #define TP_GETUSERMS(i,x) TP_GetUserMS(&i,x) #define TP_GETTOTALSYSTEMMS(i) TP_GetSystemMS(&i) #define TP_GETTOTALUSERMS(i) TP_GetUserMS(&i) #define TP_GETREALTIME(i) TP_GetRealtimeMS(&i) #else // TIME_PROFILING // dummy macros #define TP_DEFINFO(x) #define TP_DEFIDX(x) #define TP_INIT(i) #define TP_START(i,x) #define TP_SWITCH(l,i,x) #define TP_STOP(i) #define TP_GETSYSTEMMS(i,x) 0 #define TP_GETUSERMS(i,x) 0 #define TP_GETTOTALSYSTEMMS(i) 0 #define TP_GETTOTALUSERMS(i) 0 #define TP_GETREALTIME(i) 0 #endif // TIME_PROFILING #ifdef MEMORY_PROFILING #warning "Probably obsolete and dangerous" #ifdef __cplusplus #define SYSYNC_CDECL "C" #else #define SYSYNC_CDECL #endif extern SYSYNC_CDECL size_t gAllocatedMem; extern SYSYNC_CDECL size_t gMaxAllocatedMem; extern SYSYNC_CDECL int gMemProfilingInUse; extern SYSYNC_CDECL void *sysync_malloc(size_t size); extern SYSYNC_CDECL void *sysync_realloc(void *mem, size_t newsize); extern SYSYNC_CDECL void sysync_free(void *mem); #ifdef __cplusplus void* operator new (std::size_t size) throw(std::bad_alloc); void* operator new (std::size_t size, const std::nothrow_t&) throw(); void* operator new[](std::size_t size) throw(std::bad_alloc); void* operator new[](std::size_t size, const std::nothrow_t&) throw(); void operator delete(void* ptr) throw(); void operator delete(void* ptr, const std::nothrow_t&) throw(); void operator delete[](void* ptr) throw(); void operator delete[](void* ptr, const std::nothrow_t&) throw(); #ifdef MP_SHOW_NEW_AND_DELETE #define MP_NEW(p,lvl,msg,x) {\ size_t MP_before=gAllocatedMem;\ if (!gMemProfilingInUse) {\ gMemProfilingInUse=1;\ PDEBUGPRINTFX((lvl|DBG_PROFILE),(\ "+++ %-30s : before calling new: %10ld total, %10ld max",\ msg,\ gAllocatedMem,\ gMaxAllocatedMem\ ));\ gMemProfilingInUse=0;\ }\ p = new x;\ if (!gMemProfilingInUse) {\ gMemProfilingInUse=1;\ PDEBUGPRINTFX((lvl|DBG_PROFILE),(\ "+++ %-30s : %10ld bytes allocated, %10ld total, %10ld max",\ msg,\ gAllocatedMem-MP_before,\ gAllocatedMem,\ gMaxAllocatedMem\ ));\ gMemProfilingInUse=0;\ }\ } #define MP_RETURN_NEW(t,lvl,msg,x) {\ t *obj;\ MP_NEW(obj,lvl,msg,x);\ return obj;\ } #define MP_DELETE(lvl,msg,x) {\ size_t MP_before=gAllocatedMem;\ if (!gMemProfilingInUse) {\ gMemProfilingInUse=1;\ PDEBUGPRINTFX((lvl|DBG_PROFILE),(\ "--- %-30s : before calling delete: %10ld total, %10ld max",\ msg,\ gAllocatedMem,\ gMaxAllocatedMem\ ));\ gMemProfilingInUse=0;\ }\ delete x;\ if (!gMemProfilingInUse) {\ gMemProfilingInUse=1;\ PDEBUGPRINTFX((lvl|DBG_PROFILE),(\ "--- %-30s : %10ld bytes freed, %10ld total, %10ld max",\ msg,\ MP_before-gAllocatedMem,\ gAllocatedMem,\ gMaxAllocatedMem\ ));\ gMemProfilingInUse=0;\ }\ } #else // MP_SHOW_NEW_AND_DELETE // let new and delete only count, but not show #define MP_NEW(p,lvl,msg,x) p = new x #define MP_RETURN_NEW(t,lvl,msg,x) return new x #define MP_DELETE(lvl,msg,x) delete x #endif // MP_SHOW_NEW_AND_DELETE #define MP_SHOWCURRENT(lvl,msg) \ PDEBUGPRINTFX((lvl|DBG_PROFILE),(\ "=== %-30s : Current memory usage: %10ld total, %10ld max",\ msg,\ gAllocatedMem,\ gMaxAllocatedMem\ )) #endif #else // MEMORY_PROFILING #define sysync_malloc(m) malloc(m) #define sysync_realloc(m,n) realloc(m,n) #define sysync_free(m) free(m) #ifdef __cplusplus #define MP_NEW(p,lvl,msg,x) p = new x #define MP_RETURN_NEW(t,lvl,msg,x) return new x #define MP_DELETE(lvl,msg,x) delete x #define MP_SHOWCURRENT(lvl,msg) #endif #endif // MEMORY_PROFILING #endif // _PROFILING_H /* eof */ libsynthesis-3.4.0.47.1/src/platform_adapters/sysync_glob_vars.h000077500000000000000000000013521226375725500247050ustar00rootroot00000000000000/* * File: sysync_glob_vars.h * * Author: Lukas Zeller (luz@plan44.ch) * * Global variables * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * 2004-08-09 : luz : created * */ #ifndef SYSYNC_GLOB_VARS_H #define SYSYNC_GLOB_VARS_H #include "generic_types.h" namespace sysync { #ifdef DIRECT_APPBASE_GLOBALACCESS // init and deinit global sysync stuff void sysync_glob_init(void); void sysync_glob_deinit(void); void *sysync_glob_anchor(void); void sysync_glob_setanchor(void *aAnchor); #else // DIRECT_APPBASE_GLOBALACCESS // define dummies #define sysync_glob_init() #define sysync_glob_deinit() #endif // not DIRECT_APPBASE_GLOBALACCESS } // namespace sysync #endif // SYSYNC_GLOB_VARS_H // eof libsynthesis-3.4.0.47.1/src/platform_adapters/sysyncinit.cpp000077500000000000000000000040021226375725500240610ustar00rootroot00000000000000/* * File: sysyncinit.cpp * * Global variables instantiation * * Author: Lukas Zeller (luz@plan44.ch) * * Copyright (c) 2004-2011 by Synthesis AG + plan44.ch * * 2004-08-09 : luz : created * * */ #include "prefix_file.h" #define _IMPLEMENTS_DEBUG_GLOBALS #include "sysync.h" #undef _IMPLEMENTS_DEBUG_GLOBALS // note: this is the generic implementation assuming an environment that supports // static global vars. namespace sysync { #ifdef DIRECT_APPBASE_GLOBALACCESS /* %%% obsolete // globals for debugging purposes // Note: These are duplicates of the values in TSyncAppBase.fRootConfig.fDebugConfig // which are here for convenience #ifdef SYDEBUG uInt16 gDebug; // if <>0 (and #defined SYDEBUG), debug output is generated, value is used as mask bool gGlobalDebugLogs; // if set, global debug output is generated bool gMsgDump; // if set (and #defined MSGDUMP), messages sent and received are logged; bool gXMLtranslate; // if set, communication will be translated to XML and logged bool gSimMsgRead; // if set (and #defined SIMMSGREAD), simulated input with "i_" prefixed incoming messages are supported bool gSeparateSessionLogs; // if set, session-specific logs are generated in separate files string gDebugLogPath; // path to store debug files #endif */ // static global for anchoring singluar syncappbase object void *gSySyncGlobAnchor=NULL; // get the global anchor for the sysync framework void *sysync_glob_anchor(void) { return gSySyncGlobAnchor; } // sysync_glob_anchor // get the global anchor for the sysync framework void sysync_glob_setanchor(void *aAnchor) { gSySyncGlobAnchor=aAnchor; } // sysync_glob_setanchor // global initialisation routine void sysync_glob_init(void) { gSySyncGlobAnchor=NULL; } // sysync_glob_init // global de-initialisation routine void sysync_glob_deinit(void) { // get rid of global stuff outside the SyncAppBase framework /* none here */ } // sysync_glob_deinit #endif // DIRECT_APPBASE_GLOBALACCESS } // namespace sysync /* eof */ libsynthesis-3.4.0.47.1/src/platform_adapters/unix_common/000077500000000000000000000000001226375725500234755ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/platform_adapters/unix_common/platform_file.cpp000077500000000000000000000060621226375725500270330ustar00rootroot00000000000000/* * File: platform_file.cpp * * Author: Beat Forster (bfo@synthesis.ch) * * * General interface to get/set file info * like date/attributes/... * >>>> UNIX Version <<<< * * Copyright (c) 2005-2011 by Synthesis AG + plan44.ch * * */ #include "platform_file.h" #include namespace sysync { TSyError Get_FileAttr( string /* pathName */, TAttr &attr, bool &isFolder ) { /* WIN32_FIND_DATA data; TSyError err= FileData( pathName, data ); if (!err) { DWORD att= data.dwFileAttributes; attr.h= att & FILE_ATTRIBUTE_HIDDEN; attr.s= att & FILE_ATTRIBUTE_SYSTEM; attr.a= att & FILE_ATTRIBUTE_ARCHIVE; attr.d= false; // delete attr.w= true; attr.r= true; attr.x= false; } // if return err; */ attr.h= false; attr.s= false; attr.a= false; attr.d= false; // delete attr.w= true; attr.r= true; attr.x= false; isFolder= false; return LOCERR_OK; } // Get_FileAttr TSyError Set_FileAttr( string /* pathName */, TAttr /* aAttr */ ) { return LOCERR_OK; } // Set_FileAttr static void FTime( time_t u, string &utcStr ) { char f[ 20 ]; struct tm* t= localtime( &u ); sprintf( f, "%04d%02d%02dT%02d%02d%02d", t->tm_year+1900, t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec ); utcStr= f; } // FTime extern "C" { #include #include #include } static TSyError FSTime( string tStr, time_t &u ) // UTC is currently not supported { string tt= tStr.substr( 8,1 ); if (!(tt=="T")) return DB_Forbidden; tt= tStr.substr( 15,1 ); //bool usUTC= tt=="Z"; time( &u ); // get some defaults struct tm* t= localtime( &u ); t->tm_year = atoi( tStr.substr( 0,4 ).c_str() )-1900; t->tm_mon = atoi( tStr.substr( 4,2 ).c_str() )-1; t->tm_mday = atoi( tStr.substr( 6,2 ).c_str() ); // "T" t->tm_hour = atoi( tStr.substr( 9,2 ).c_str() ); t->tm_min = atoi( tStr.substr( 11,2 ).c_str() ); t->tm_sec = atoi( tStr.substr( 13,2 ).c_str() ); t->tm_wday = 0; // avoid troubles t->tm_yday = 0; //t->tm_isdst = 1; u= mktime( t ); return LOCERR_OK; } // FSTime TSyError Get_FileDate( string pathName, TDates &aDate ) { struct stat info; TSyError err= stat( pathName.c_str(), &info ); if (!err) { FTime( info.st_ctime, aDate.created ); FTime( info.st_mtime, aDate.modified ); FTime( info.st_atime, aDate.accessed ); } // if return err; } // Get_FileDate TSyError Set_FileDate( string pathName, TDates aDate ) { TSyError err; struct utimbuf buf; err= FSTime( aDate.created, buf.modtime ); if (err) return err; err= FSTime( aDate.modified, buf.modtime ); if (err) return err; err= FSTime( aDate.accessed, buf.actime ); if (err) return err; //string uu; //FTime( buf.modtime, uu ); printf( "uum='%s'\n", uu.c_str() ); //FTime( buf.actime, uu ); printf( "uua='%s'\n", uu.c_str() ); return utime( pathName.c_str(), &buf ); return err; } // Set_FileDate } /* namespace */ /* eof */ libsynthesis-3.4.0.47.1/src/platform_adapters/unix_common/platform_mutex.cpp000077500000000000000000000016451226375725500272600ustar00rootroot00000000000000/* * File: platform_mutex.cpp * * Author: Beat Forster (bfo@synthesis.ch) * * * Mutex handling * (Unix implementation) * * Copyright (c) 2005-2011 by Synthesis AG + plan44.ch * * */ #include #include "platform_mutex.h" MutexPtr_t newMutex() { pthread_mutex_t* m= new pthread_mutex_t; pthread_mutex_init ( (pthread_mutex_t*)m, NULL ); return m; } bool lockMutex( MutexPtr_t m ) { return pthread_mutex_lock ( (pthread_mutex_t*)m ) == 0; } bool tryLockMutex( MutexPtr_t m ) { return pthread_mutex_trylock( (pthread_mutex_t*)m ) == 0; } bool unlockMutex( MutexPtr_t m ) { return pthread_mutex_unlock ( (pthread_mutex_t*)m ) == 0; } void freeMutex( MutexPtr_t m ) { pthread_mutex_destroy( (pthread_mutex_t*)m ); delete (pthread_mutex_t*)m; } /* eof */ libsynthesis-3.4.0.47.1/src/platform_adapters/unix_common/platform_pipe.c000077500000000000000000000037261226375725500265150ustar00rootroot00000000000000/* * File: platform_pipe.c * * Author: Lukas Zeller (luz@plan44.ch) * * Platform specific utility routines * * Copyright (c) 2003-2011 by Synthesis AG + plan44.ch * * NOTE: this file is part of the mod_sysync source files. * */ #include #include "platform_headers.h" #include "platform_pipe.h" // create new pipe. Fails if it already exists int createPipe(const char *aPipePathName) { if (mkfifo(aPipePathName,0620)!=0) { // error return appFalse; } // ok return appTrue; } // createPipe int deletePipe(const char *aPipePathName) { if (unlink(aPipePathName)!=0) { // error return appFalse; } // ok return appTrue; } // deletePipe pipeDescriptor_t openPipeForRead(const char *aPipePathName) { return open(aPipePathName, O_RDONLY); } // openPipeForRead pipeDescriptor_t openPipeForWrite(const char *aPipePathName) { return open(aPipePathName, O_WRONLY); } // openPipeForWrite int closePipe(pipeDescriptor_t aPipeDesc) { return (close(aPipeDesc)!=0); } // closePipe long readPipe(pipeDescriptor_t aPipeDesc,void *aBuffer, long aMaxBytes, int aReadAll) { long gotBytes=0; long bytes; do { bytes=read(aPipeDesc,aBuffer,aMaxBytes); if (bytes<0) return bytes; // error if (bytes==0) return gotBytes; // no error, but end of pipe - abort reading and return number of bytes already read gotBytes+=bytes; // add them up aMaxBytes-=bytes; // reduce max aBuffer = (void *)((char *)aBuffer + bytes); } while(aReadAll && aMaxBytes>0); return gotBytes; // return total } // readPipe long writePipe(pipeDescriptor_t aPipeDesc,void *aBuffer, long aNumBytes) { long sentBytes=0; long bytes; do { bytes=write(aPipeDesc,aBuffer,aNumBytes); if (bytes<0) return bytes; // error sentBytes+=bytes; // add them up aNumBytes-=bytes; // reduce max aBuffer = (void *)((char *)aBuffer + bytes); } while(aNumBytes>0); return sentBytes; // return total } // writePipe /* eof */ libsynthesis-3.4.0.47.1/src/platform_adapters/unix_common/platform_pipe.h000077500000000000000000000016761226375725500265240ustar00rootroot00000000000000/* * File: platform_pipe.h * * Author: Lukas Zeller (luz@plan44.ch) * * Platform specific pipe implementation * * Copyright (c) 2003-2011 by Synthesis AG + plan44.ch * * NOTE: this file is part of the mod_sysync source files. */ #include #include "generic_types.h" #ifdef __cplusplus extern "C" { #endif typedef int pipeDescriptor_t; #define PIPEDESCRIPTORVALID(pd) (pd>=0) #define PIPEERRORCODE ((int)errno) #define PIPEINVALIDDESC -1 #define PIPEPATHDELIM '/' int createPipe(const char *aPipePathName); int deletePipe(const char *aPipePathName); pipeDescriptor_t openPipeForRead(const char *aPipePathName); pipeDescriptor_t openPipeForWrite(const char *aPipePathName); int closePipe(pipeDescriptor_t aPipeDesc); long readPipe(pipeDescriptor_t aPipeDesc,void *aBuffer, long aMaxBytes, int aReadAll); long writePipe(pipeDescriptor_t aPipeDesc,void *aBuffer, long aNumBytes); #ifdef __cplusplus } #endif /* eof */ libsynthesis-3.4.0.47.1/src/platform_adapters/unix_common/platform_thread.cpp000077500000000000000000000200541226375725500273600ustar00rootroot00000000000000/* * File: platform_thread.cpp * * Author: Lukas Zeller (luz@plan44.ch) * * Platform specific thread object implementation * * Copyright (c) 2004-2011 by Synthesis AG + plan44.ch * * 2004-05-24 : luz : created from Win version * */ #include "prefix_file.h" #include "platform_thread.h" #include "platform_time.h" #include "lineartime.h" #include "timezones.h" // private includes needed #include #include #ifdef ANDROID #include #endif namespace sysync { // get id of the running process uIntArch myProcessID() { return (uIntArch)getpid(); } // myProcessID // get id of the running thread uIntArch myThreadID() { return (uIntArch)pthread_self(); } // myThreadID // The POSIX thread function, must be passed the Thread Object address as parameter extern "C" void * PosixThreadFunc(void *aParam); void* PosixThreadFunc(void *aParam) { // get Thread Object pointer TThreadObject *threadObjP = static_cast(aParam); PNCDEBUGPRINTFX(DBG_HOT,("thread object %p: starting", threadObjP)); // call thread execution method uInt32 retval = threadObjP->execute(); // signal thread termination condition pthread_mutex_lock (&(threadObjP->fDoneCondMutex)); pthread_cond_signal (&(threadObjP->fDoneCond)); threadObjP->fTerminated= true; // no longer valid pthread_mutex_unlock(&(threadObjP->fDoneCondMutex)); // auto-dispose the thread object if requested if (threadObjP->fAutoDisposeThreadObj) { PNCDEBUGPRINTFX(DBG_HOT,("auto-disposing thread object %p", threadObjP)); delete threadObjP; } // Exit thread now. // Avoid "cast to pointer from integer of different size" warning with // intermediate cast. PNCDEBUGPRINTFX(DBG_HOT,("thread object %p: terminating", threadObjP)); return (void *)(uIntArch)retval; } // PosixThreadFunc // creates thread object. Thread ist not started yet, must use launch() for this TThreadObject::TThreadObject(void) : fStackSize(0), fThreadFunc(NULL), fThreadFuncParam(0), fTerminationRequested(false), fExitCode(0), fAutoDisposeThreadObj(false), fPosixThread(0), fTerminated(false) { // init cond and mutex required to implement WaitFor pthread_mutex_init(&fDoneCondMutex,NULL); pthread_cond_init(&fDoneCond,NULL); } // TThreadObject::TThreadObject // destroys thread object. This will kill the thread if it still active. TThreadObject::~TThreadObject() { // kill thread (only if not auto-disposed at end of thread) if (!fAutoDisposeThreadObj) kill(); // destroy cond/mutex pthread_mutex_destroy(&fDoneCondMutex); pthread_cond_destroy(&fDoneCond); } // TThreadObject::TThreadObject // launches thread. Returns false if thread could not be started. exitcode() will // contain the platform error code for the failure to start the thread bool TThreadObject::launch( TThreadFunc aThreadFunc, // the function to execute in the thread uIntArch aThreadFuncParam, // a parameter to pass to the thread size_t aStackSize, // if 0, default stack size is used bool aAutoDispose // if true, the thread object will dispose itself when thread has finished running ) { PNCDEBUGPRINTFX(DBG_HOT,("thread object %p: launching", this)); // save parameters fThreadFunc=aThreadFunc; fThreadFuncParam=aThreadFuncParam; fStackSize=aStackSize; fAutoDisposeThreadObj=aAutoDispose; // assume ok exit errno.h fExitCode=0; fTerminationRequested=false; // thread must not exist yet if (fPosixThread!=0 && !fTerminated) { fExitCode=EEXIST; // we use this to signal thread is already started return false; } // now create a POSIX thread fPosixThread= 0; fTerminated= false; fExitCode = pthread_create( &fPosixThread, // pointer to returned thread identifier NULL, // default attributes = joinable, not realtime PosixThreadFunc, // pointer to thread function this // pass the pointer to the thread object ); if (fExitCode==0) { PNCDEBUGPRINTFX(DBG_HOT,("thread object %p: launched okay", this)); // thread created successfully return true; // ok } else { // could not create thread fTerminated= true; return false; // not ok } } // TThreadObject::launch uIntArch TThreadObject::getid(void) { return (uIntArch)fPosixThread; } // TThreadObject::getid // kills the thread void TThreadObject::kill(void) { if (fPosixThread!=0 && !fTerminated) { PNCDEBUGPRINTFX(DBG_HOT,("thread object %p: killing", this)); // the thread is actually running fExitCode=EINTR; // nearest match, interrupted // kill it pthread_kill(fPosixThread, SIGKILL); fTerminated= true; } else { PNCDEBUGPRINTFX(DBG_HOT,("thread object %p: skipped killing, not running", this)); } } // TThreadObject::kill static int CondTimedWait(pthread_cond_t *cond, pthread_mutex_t *mutex, bool &aTerminated, long aMilliSecondsToWait) { int retval; if (aMilliSecondsToWait<0) { // wait indefinitely retval= pthread_cond_wait(cond, mutex); } else { // wait specified amount of time struct timespec timeout; /* this conversion might be implemented in time module later */ #define milli 1E-3 #define msToLinearTimeFactor (secondToLinearTimeFactor*milli) // is usually 1 again lineartime_t ltm = getSystemNowAs(TCTX_UTC,NULL) - UnixToLineartimeOffset; // starting 1970 ltm = (lineartime_t)(ltm/msToLinearTimeFactor); // as milliSeconds ltm+= aMilliSecondsToWait; // add the offset from now timeout.tv_sec = (unsigned int)(ltm * milli); timeout.tv_nsec= ( ltm % 1000 )*1000000; // ns retval= pthread_cond_timedwait(cond, mutex, &timeout); } /* if */ return retval; } extern "C" { /** * Wait until thread terminates or timeout occurs. * * Can use pthread_cond_[timed]wait with the given condition variable * and mutex to be worken up by the terminating thread. However, aTerminated * must be checked before each such pthread call, because the thread may * already have signaled termination. * * If the implementation does not use pthread_cond_[timed]wait, then it * must unlock the mutex. Otherwise the thread will never be able to lock * it and set aTerminated. * * @param aMilliSecondsToWait < 0 for infinite wait, otherwise maximum time to wait since entering the function in ms */ int (*SySync_CondTimedWait)(pthread_cond_t *cond, pthread_mutex_t *mutex, bool &aTerminated, long aMilliSecondsToWait) = CondTimedWait; } // waits for the thread to stop bool TThreadObject::waitfor(sInt32 aMilliSecondsToWait) { PNCDEBUGPRINTFX(DBG_HOT,("thread object %p: waitfor %d", this, aMilliSecondsToWait)); int retval= 0; if (fPosixThread==0) { PNCDEBUGPRINTFX(DBG_HOT,("thread object %p: not running", this)); return true; // thread not running } // thread is running // wait for termination condition of the thread pthread_mutex_lock(&fDoneCondMutex); if (!fTerminated) { // catch also, if signalled already retval= SySync_CondTimedWait(&fDoneCond, &fDoneCondMutex, fTerminated, aMilliSecondsToWait); } /* if */ pthread_mutex_unlock(&fDoneCondMutex); if (retval!=0) { PNCDEBUGPRINTFX(DBG_HOT,("thread object %p: still running", this)); return false; // check if thread has completed => no, not yet } // thread has terminated (or is terminating) -> join and get exit code void* threadret; PNCDEBUGPRINTFX(DBG_HOT,("thread object %p: join thread", this)); int ret= pthread_join(fPosixThread,&threadret); if (ret==0) fExitCode= (uInt32)(uIntPtr)threadret; else fExitCode= ret; fTerminated= true; // thread has ended fPosixThread= 0; // don't join thread again (doesn't work reliably) when waitfor() is called again PNCDEBUGPRINTFX(DBG_HOT,("thread object %p: joined thread", this)); return true; } // TThreadObject::waitfor // Thread execution method uInt32 TThreadObject::execute() { // standard implementation simply starts the predefined thread function, if any if (fThreadFunc) { uInt32 err= fThreadFunc(this,fThreadFuncParam); return err; } else { return 0; } } // TThreadObject::execute } // namespace sysync /* eof */ libsynthesis-3.4.0.47.1/src/prefix_file.h000077500000000000000000000006141226375725500201040ustar00rootroot00000000000000// dummy prefix file, used for CW based projects which do // not need the prefix file here, but in the target settings #ifdef _MSC_VER #error "this is not the right prefix_file.h -> reorder include paths such that project-specific prefix is used!" #endif #ifdef __PALM_OS__ #error "this is not the right prefix_file.h -> reorder access paths such that project-specific prefix is used!" #endif libsynthesis-3.4.0.47.1/src/server_engine_linux.mk000066400000000000000000000137321226375725500220440ustar00rootroot00000000000000# Makefile generated by Metrowerks CodeWarrior IDE # adapted for standalone client library use 09/02/05 by bfo@synthesis.ch # adapted for standalone server library use 09/09/22 by luz@synthesis.ch all: serverEngine clean: clean_serverEngine ####### common definitions WD=$(shell echo `pwd`) WD_OBJS=$(WD)/../OBJS CC="gcc" LD="gcc" AR="ar -crs" SIZE="size" CFLAGS= -m32 -Wall -O2 -c -MMD LDFLAGS= -m32 MAKEFILE= "server_engine_linux.mk" SYNCML_TK_SML=\ syncml_tk/src/sml/lib/all/liblock.c\ syncml_tk/src/sml/lib/all/libmem.c\ syncml_tk/src/sml/lib/all/libstr.c\ syncml_tk/src/sml/lib/all/libutil.c\ syncml_tk/src/sml/mgr/all/mgr.c\ syncml_tk/src/sml/mgr/all/mgrcmdbuilder.c\ syncml_tk/src/sml/mgr/all/mgrcmddispatcher.c\ syncml_tk/src/sml/mgr/all/mgrinstancelist.c\ syncml_tk/src/sml/mgr/all/mgrinstancemgr.c\ syncml_tk/src/sml/mgr/all/mgrutil.c\ syncml_tk/src/sml/xlt/all/xltdec.c\ syncml_tk/src/sml/xlt/all/xltdecwbxml.c\ syncml_tk/src/sml/xlt/all/xltdecxml.c\ syncml_tk/src/sml/xlt/all/xltdevinf.c\ syncml_tk/src/sml/xlt/all/xltenc.c\ syncml_tk/src/sml/xlt/all/xltenccom.c\ syncml_tk/src/sml/xlt/all/xltencwbxml.c\ syncml_tk/src/sml/xlt/all/xltencxml.c\ syncml_tk/src/sml/xlt/all/xltmetinf.c\ syncml_tk/src/sml/xlt/all/xlttags.c\ syncml_tk/src/sml/xlt/all/xltutilstack.c EXPAT=\ expat/xmltok/xmltok.c\ expat/xmltok/xmlrole.c\ expat/xmlparse/xmlparse.c ZLIB=\ zlib/adler32.c\ zlib/compress.c\ zlib/crc32.c\ zlib/deflate.c\ zlib/gzio.c\ zlib/infback.c\ zlib/inffast.c\ zlib/inflate.c\ zlib/inftrees.c\ zlib/trees.c\ zlib/uncompr.c\ zlib/zutil.c C_BASICS=\ $(SYNCML_TK_SML)\ $(EXPAT)\ platform_adapters/linux/platform_exec.c\ sysync_SDK/Sources/SDK_util.c PLATFORM=\ platform_adapters/linux/configfiles.cpp\ platform_adapters/linux/profiling.cpp\ platform_adapters/linux/platform_time.cpp\ platform_adapters/unix_common/platform_mutex.cpp\ platform_adapters/sysyncinit.cpp PLATFORM_EXT=\ $(PLATFORM)\ platform_adapters/linux/platform_DLL.cpp\ platform_adapters/unix_common/platform_thread.cpp\ platform_adapters/unix_common/platform_file.cpp SYSYNC=\ sysync/sysync_utils.cpp\ sysync/sysync_b64.cpp\ sysync/sysync_md5.cpp\ sysync/syncsession.cpp\ sysync/syncappbase.cpp\ sysync/lineartime.cpp\ sysync/iso8601.cpp\ sysync/stringutils.cpp\ sysync/superdatastore.cpp\ sysync/scriptcontext.cpp\ sysync/itemfield.cpp\ sysync/mimediritemtype.cpp\ sysync/mimedirprofile.cpp\ sysync/multifielditem.cpp\ sysync/multifielditemtype.cpp\ sysync/remotedatastore.cpp\ sysync/syncitem.cpp\ sysync/syncitemtype.cpp\ sysync/simpleitem.cpp\ sysync/synccommand.cpp\ sysync/syncdatastore.cpp\ sysync/textitemtype.cpp\ sysync/vcalendaritemtype.cpp\ sysync/vcarditemtype.cpp\ sysync/syncexception.cpp\ sysync/configelement.cpp\ sysync/sysync_crc16.cpp\ sysync/timezones.cpp\ sysync/rrules.cpp\ sysync/localengineds.cpp\ sysync/debuglogger.cpp\ sysync/textprofile.cpp\ sysync/dataobjtype.cpp\ sysync/stdlogicds.cpp\ sysync/stdlogicagent.cpp\ sysync/customimplagent.cpp\ sysync/customimplds.cpp\ sysync/vtimezone.cpp SERVERENGINE=\ $(SYSYNC)\ syncapps/serverEngine_custom/serverengine_custom_Base.cpp\ Transport_interfaces/engine/enginesessiondispatch.cpp\ sysync_SDK/Sources/enginemodulebase.cpp\ sysync/engineentry.cpp\ sysync/engineinterface.cpp\ sysync/syncagent.cpp ODBC_DB=\ DB_interfaces/odbc_db/odbcapiagent.cpp\ DB_interfaces/odbc_db/odbcapids.cpp API_DB=\ DB_interfaces/api_db/pluginapiagent.cpp\ DB_interfaces/api_db/pluginapids.cpp\ DB_interfaces/api_db/dbapi.cpp\ DB_interfaces/api_db/DLL_interface.cpp\ DB_interfaces/api_db/sync_dbapiconnect.cpp\ sysync_SDK/Sources/SDK_support.cpp\ sysync_SDK/DB_Interfaces/text_db/sync_dbapi_text.cpp\ sysync_SDK/Sources/admindata.cpp\ sysync_SDK/Sources/dbitem.cpp\ sysync_SDK/Sources/blobs.cpp # -------------------------------------------------------- INCLUDE_PLATFORM=\ -I platform_adapters/linux/\ -I platform_adapters/unix_common/\ -I platform_adapters/ INCLUDE_SYNCML_TK_SML=\ -I syncml_tk/src/sml/inc/\ -I syncml_tk/src/sml/lib/inc/\ -I syncml_tk/src/sml/lib/\ -I syncml_tk/src/sml/mgr/inc/\ -I syncml_tk/src/sml/mgr/\ -I syncml_tk/src/sml/wsm/inc/\ -I syncml_tk/src/sml/xlt/inc/\ -I syncml_tk/src/sml/xlt/all/ INCLUDE_EXPAT=\ -I expat/xmltok/\ -I expat/xmlparse/ INCLUDE_SERVERENGINE=\ -I syncapps/serverEngine_custom/\ -I Transport_interfaces/engine/\ -I sysync_SDK/Sources\ -I sysync/\ -I ./ ############################# ####### TARGET: serverEngine ############################# WD_OBJS_serverEngine=$(WD_OBJS)/serverEngine c_SRC_serverEngine=\ $(C_BASICS) $(ZLIB) cpp_SRC_serverEngine=\ $(PLATFORM_EXT)\ $(SERVERENGINE)\ $(ODBC_DB)\ $(API_DB) OBJS_serverEngine+= $(c_SRC_serverEngine:.c=.c.o) OBJS_serverEngine+=$(cpp_SRC_serverEngine:.cpp=.cpp.o) INCLUDE_serverEngine=\ -include Targets/ReleasedProducts/serverEngine_opensource_linux/serverengine_opensource_linux_prefix.h\ -I Targets/ReleasedProducts/serverEngine_opensource_linux/\ $(INCLUDE_PLATFORM)\ $(INCLUDE_SYNCML_TK_SML)\ $(INCLUDE_EXPAT)\ $(INCLUDE_SERVERENGINE)\ -I DB_interfaces/odbc_db/\ -I DB_interfaces/api_db/\ -I SQLite/\ -I zlib/\ -I /usr/include/ serverEngine: $(MAKE) -f $(MAKEFILE) sysync_server_engine.so TARGET=sysync_server_engine.so \ WDOP="$(WD_OBJS_serverEngine)"\ OBJS="$(addprefix $(WD_OBJS_serverEngine)/,$(OBJS_serverEngine))"\ LIBS="-L/usr/lib32 -L/usr/lib -lstdc++ -lpthread -lltdl -lpcre"\ INCL="$(INCLUDE_serverEngine)" sysync_server_engine.so: $(OBJS) $(LD) -shared -Xlinker -soname=sysync_server_engine $(LDFLAGS) $(OBJS) $(LIBS) \ -o sysync_SDK/bin/Linux/sysync_server_engine.so ifeq ($(TARGET), sysync_server_engine.so) $(WDOP)/%.c.o: $(WD)/%.c mkdir -p $(dir $@) $(CC) -fPIC $(CFLAGS) $(INCL) $< -o $@ $(WDOP)/%.cpp.o: $(WD)/%.cpp mkdir -p $(dir $@) $(CC) -fPIC $(CFLAGS) $(INCL) $< -o $@ endif clean_serverEngine: rm -f -r $(WD_OBJS_serverEngine) libsynthesis-3.4.0.47.1/src/smltk-linker.map000066400000000000000000000001761226375725500205520ustar00rootroot00000000000000VER_1.0 { global: sml*; xltDecInit; xltDecTerminate; xltDecNext; local: *; }; libsynthesis-3.4.0.47.1/src/syncapps/000077500000000000000000000000001226375725500172735ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/syncapps/clientEngine_custom/000077500000000000000000000000001226375725500232715ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/syncapps/clientEngine_custom/clientengine_custom.h000077500000000000000000000007671226375725500275150ustar00rootroot00000000000000/* */ #ifndef CLIENTENGINE_CUSTOM_H #define CLIENTENGINE_CUSTOM_H /* Headers that might be available in precompiled form * (standard libraries, SyncML toolkit...) */ #include "clientengine_custom_precomp.h" /* headers not suitable for / entirely included in precompilation */ // DB interface related includes #ifdef SQL_SUPPORT #include "odbcdb.h" #endif #ifdef SDK_SUPPORT #include "plugindb.h" #endif #ifdef OUTLOOK_SUPPORT #include "outlookdb.h" #endif #endif // CLIENTENGINE_CUSTOM_H libsynthesis-3.4.0.47.1/src/syncapps/clientEngine_custom/clientengine_custom_Base.cpp000066400000000000000000000023631226375725500307710ustar00rootroot00000000000000/* * TCustomClientEngineBase, TCustomClientEngineInterface * SyncML client engine for custom clients - base classes * * Copyright (c) 2004-2011 by Synthesis AG + plan44.ch * * 2007-09-04 : luz : Created * */ // includes #include "clientengine_custom.h" #include "clientengine_custom_Base.h" // common includes #include "engineclientbase.h" namespace sysync { // factory function implementation - declared in TEngineInterface ENGINE_IF_CLASS *newClientEngine(void) { return new TCustomClientEngineInterface; } // newClientEngine /* * Implementation of TCustomClientEngineInterface */ /// @brief returns a new application base. TSyncAppBase *TCustomClientEngineInterface::newSyncAppBase(void) { return new TCustomClientEngineBase; } // TCustomClientEngineInterface::newSyncAppBase /* * Implementation of TCustomClientEngineBase */ TCustomClientEngineBase::TCustomClientEngineBase() { // create config root fConfigP=new TEngineClientRootConfig(this); } // TCustomClientEngineBase::TCustomClientEngineBase TCustomClientEngineBase::~TCustomClientEngineBase() { fDeleting=true; // flag deletion to block calling critical (virtual) methods } // TCustomClientEngineBase::~TCustomClientEngineBase } // namespace sysync // eof libsynthesis-3.4.0.47.1/src/syncapps/clientEngine_custom/clientengine_custom_Base.h000077500000000000000000000017461226375725500304450ustar00rootroot00000000000000/* * TCustomClientEngineBase, TCustomClientEngineInterface * SyncML client engine for custom clients - base classes * * Copyright (c) 2004-2011 by Synthesis AG + plan44.ch * * 2007-09-04 : luz : Created * * */ #ifndef CLIENTENGINE_CUSTOM_BASE_H #define CLIENTENGINE_CUSTOM_BASE_H // directly based on syncclient base #include "engineclientbase.h" // using binfile engine interface #include "binfileimplclient.h" namespace sysync { // Appbase class class TCustomClientEngineBase: public TEngineClientBase { typedef TEngineClientBase inherited; public: TCustomClientEngineBase(); virtual ~TCustomClientEngineBase(); }; // TCustomClientEngineBase // Engine interface class class TCustomClientEngineInterface: public TBinfileEngineInterface { typedef TBinfileEngineInterface inherited; public: /// @brief returns a new application base. virtual TSyncAppBase *newSyncAppBase(void); }; // TCustomClientEngineInterface } #endif // CLIENTENGINE_CUSTOM_BASE_H // eof libsynthesis-3.4.0.47.1/src/syncapps/clientEngine_custom/clientengine_custom_precomp.h000077500000000000000000000007551226375725500312370ustar00rootroot00000000000000/* Headers that might be available in precompiled form * (standard libraries, SyncML toolkit...) * */ #ifndef CLIENTENGINE_CUSTOM_PRECOMP_H #define CLIENTENGINE_CUSTOM_PRECOMP_H // Needed for Engine #include "sysync_precomp.h" // DB interface related includes #ifdef SQL_SUPPORT #include "odbcdb_precomp.h" #endif #ifdef SDK_SUPPORT #include "plugindb_precomp.h" #endif #ifdef OUTLOOK_SUPPORT #include "outlookdb_precomp.h" #endif #endif // CLIENTENGINE_CUSTOM_PRECOMP_H // eof libsynthesis-3.4.0.47.1/src/syncapps/clientEngine_custom/product_options.h000077500000000000000000000065441226375725500267110ustar00rootroot00000000000000/* Common Product options * ====================== * */ // Custom Client Library Products // ############################## // Separate Version // ================ // Note: for now, client library has NO SEPARATE VERSION, but shows engine version /* #define SYSYNC_VERSION_MAJOR 1 #define SYSYNC_VERSION_MAJOR_TXT "1" #define SYSYNC_VERSION_MINOR 1 #define SYSYNC_VERSION_MINOR_TXT "1" #define SYSYNC_SUBVERSION 0 #define SYSYNC_SUBVERSION_TXT "0" #define SYSYNC_BUILDNUMBER 0 #define SYSYNC_BUILDNUMBER_TXT "0" */ // new major or minor gives a new demo period #define SYSER_VERSCHECK_MASK 0xFFFF0000 // Most hyperglobal definition, might even influence global_options.h: // - THIS IS A CLIENT #define SYSYNC_CLIENT 1 // - is a engine library #define ENGINE_LIBRARY 1 // - ...which is used in standalone apps #define STANDALONE_APP 1 // global options #include "global_options.h" // Product (but not target) specific options // ######################################### // Hard expiration date, software will stop working after defined date // if not registered #undef VERSION_COMMENTS #define VERSION_COMMENTS "Demo expires after " EXPIRY_DATE_STRING " if not registered" #define EXPIRES_AFTER_DATE 1 // SySync options // ============== // - use precise time when possible #define NOW_WITH_MILLISECONDS 1 // - if defined, debug code is included (not necessarily enabled, see gDebug) // if 1, only "public" debugging is enabled, if >1, all debugging is enabled #ifdef RELEASE_VERSION #if RELEASE_SYDEBUG #define SYDEBUG RELEASE_SYDEBUG #else #undef SYDEBUG // absolutely no debug code for release! #endif #undef CONSOLEINFO #else #define SYDEBUG 2 // 3=including XPT trace, 4=including memory leak detection #undef CONSOLEINFO #endif // local Database options #define DESKTOP_CLIENT 1 // selects different binfile format (actually, will merge with mobile format at version 5) // separate files for outlook - different from old 1.0 client to make sure we don't import old problems #define SETTINGS_BFI_PREFIX "sysynclib_" // - if defined, local DB does not require any login in client mode #define NO_LOCAL_DBLOGIN 1 // - if defined, config file might contain s which will // allow a client to run directly from config w/o additionally // provided parameters. #undef PRECONFIGURED_SYNCREQUESTS // - if defined, XML config parsing is completely disabled, // all config must be set programmatically #undef HARDCODED_CONFIG // - if defined, remoterule mechanism is not included #undef NO_REMOTE_RULES // - if defined, support for hardcoded (predefined) // type definitions will be included #undef HARDCODED_TYPE_SUPPORT // - if defined, support for configurable types will be included #define CONFIGURABLE_TYPE_SUPPORT 1 // do not modify remote IDs in any way while processing them #define DONT_STRIP_PATHPREFIX_FROM_REMOTEIDS 1 // if defined, session continues after 401/407 //#define AUTH_RETRY_USES_SAME_CLIENT_SESSION // SyncML Toolkit options // ====================== // if defined, the entire complicated and thread-unsafe workspace manager // is completely bypassed #define NOWSM 1 /* if defined, avoids using 1, all debugging is enabled #ifdef RELEASE_VERSION #if RELEASE_SYDEBUG #define SYDEBUG RELEASE_SYDEBUG #else #undef SYDEBUG // absolutely no debug code for release! #undef CONSOLEINFO #endif #else #define SYDEBUG 2 // 3=including XPT trace, 4=including memory leak detection #undef CONSOLEINFO #endif // local Database options #define DESKTOP_CLIENT 1 // selects different binfile format (actually, will merge with mobile format at version 5) // separate files for outlook - different from old 1.0 client to make sure we don't import old problems #define SETTINGS_BFI_PREFIX "sysynclib_" // - if defined, local DB does not require any login in client mode #define NO_LOCAL_DBLOGIN 1 // - if defined, config file might contain s which will // allow a client to run directly from config w/o additionally // provided parameters. #undef PRECONFIGURED_SYNCREQUESTS // - if defined, XML config parsing is completely disabled, // all config must be set programmatically #undef HARDCODED_CONFIG // - if defined, remoterule mechanism is not included #undef NO_REMOTE_RULES // - if defined, support for hardcoded (predefined) // type definitions will be included #undef HARDCODED_TYPE_SUPPORT // - if defined, support for configurable types will be included #define CONFIGURABLE_TYPE_SUPPORT 1 // do not modify remote IDs in any way while processing them #define DONT_STRIP_PATHPREFIX_FROM_REMOTEIDS 1 // if defined, session continues after 401/407 //#define AUTH_RETRY_USES_SAME_CLIENT_SESSION // SyncML Toolkit options // ====================== // if defined, the entire complicated and thread-unsafe workspace manager // is completely bypassed #define NOWSM 1 /* if defined, avoids using 1, all debugging is enabled #ifdef RELEASE_VERSION #if RELEASE_SYDEBUG #define SYDEBUG RELEASE_SYDEBUG #else #undef SYDEBUG // absolutely no debug code for release! #endif #undef CONSOLEINFO #else #define SYDEBUG 2 // 3=including XPT trace, 4=including memory leak detection #undef CONSOLEINFO #endif // - if defined, XML config parsing is completely disabled, // all config must be set programmatically #undef HARDCODED_CONFIG // - if defined, remoterule mechanism is not included #undef NO_REMOTE_RULES // - if defined, support for hardcoded (predefined) // type definitions will be included #undef HARDCODED_TYPE_SUPPORT // - if defined, support for configurable types will be included #define CONFIGURABLE_TYPE_SUPPORT 1 // do not modify remote IDs in any way while processing them #define DONT_STRIP_PATHPREFIX_FROM_REMOTEIDS 1 // if defined, session continues after 401/407 //#define AUTH_RETRY_USES_SAME_CLIENT_SESSION // SyncML Toolkit options // ====================== // if defined, the entire complicated and thread-unsafe workspace manager // is completely bypassed #define NOWSM 1 /* if defined, avoids using #include #include "sysytool.h" // include files where commands are implemented #include "odbcapiagent.h" #include "syncagent.h" #include "sysync_utils.h" #include "rrules.h" static void cleanup(void) { NCDEBUGPRINTFX(DBG_ERROR,("Program aborted, atexit handler will now kill syncappbase")); // kill base object if any (will cause all current sessions to die) freeSyncAppBase(); } static void sighandler(int sig) { cleanup(); } // global options const char *gConfigFile = NULL; // -f, not optional const char *gUserName = NULL; // -u const char *gDeviceID = NULL; // -d bool gVerbose = false; // -v bool gSilent = false; // -s static void printTitle(void) { CONSOLEPRINTF(( "Synthesis SyncML Diagnostic Tool %d.%d.%d.%d - (c) 2004-" REAL_RELEASE_YEAR_TXT " by Synthesis AG\n", SYSYNC_VERSION_MAJOR, SYSYNC_VERSION_MINOR, SYSYNC_SUBVERSION, SYSYNC_BUILDNUMBER )); } // printTitle static void printUsage(const char *aCmdName) { printTitle(); CONSOLEPRINTF(("Usage:")); CONSOLEPRINTF((" %s [] [ ...]",aCmdName)); CONSOLEPRINTF(("Options:")); CONSOLEPRINTF((" -f configfile : (required) server's xml configuration file")); CONSOLEPRINTF(("Commands:")); CONSOLEPRINTF((" check")); CONSOLEPRINTF((" check config for syntax errors")); // let them show their own help text #ifdef SQL_SUPPORT execSQL(-1,NULL); #endif convertData(-1,NULL); testLogin(-1,NULL); charConv(-1,NULL); timeConv(-1,NULL); rruleConv(-1,NULL); parse2822AddrSpec(-1,NULL); wbxmlConv(-1,NULL); } int main(int argc, char *argv[]) { Ret_t err; #ifdef MEMORY_PROFILING size_t mematstart = gAllocatedMem; #endif // init hyper global stuff sysync_glob_init(); // set exit handler atexit(cleanup); signal(SIGABRT,sighandler); const int maxcmdargs=5; int cmdargc=-1; // number of non-option command arguments (-1 = command not found) const char *command = NULL; const char *cmdargv[maxcmdargs]; int idx=1; const char *p; while (idxreadXMLConfigStandard(gConfigFile,false,true); // local and global try // test if config is ok if (err!=LOCERR_OK) { CONSOLEPRINTF(("Fatal error in configuration (Error=%hd)\n",err)); exit(EXIT_FAILURE); } // override config's debug options to make it suitable for console output TDebugLogger *loggerP = sessionDispatchP->getDbgLogger(); TDbgOptions *optsP = (TDbgOptions *)(loggerP->getOptions()); optsP->fIndentString.erase(); optsP->fOutputFormat=dbgfmt_text; optsP->fTimestampForAll=false; optsP->fTimestampStructure=true; if (gVerbose) { sessionDispatchP->getDbgLogger()->setMask(DBG_TOOL); sessionDispatchP->getDbgLogger()->setEnabled(true); } else { sessionDispatchP->getDbgLogger()->setMask(0); sessionDispatchP->getDbgLogger()->setEnabled(false); } // now execute command if (strucmp(command,"check")==0) exit(EXIT_SUCCESS); // ok if we get that far #ifdef SQL_SUPPORT else if (strucmp(command,"execsql")==0) exit(sysync::execSQL(cmdargc,cmdargv)); #endif else if (strucmp(command,"convert")==0) exit(sysync::convertData(cmdargc,cmdargv)); else if (strucmp(command,"login")==0) exit(sysync::testLogin(cmdargc,cmdargv)); else if (strucmp(command,"charconv")==0) exit(sysync::charConv(cmdargc,cmdargv)); else if (strucmp(command,"addrparse")==0) exit(sysync::parse2822AddrSpec(cmdargc,cmdargv)); else if (strucmp(command,"time")==0) exit(sysync::timeConv(cmdargc,cmdargv)); else if (strucmp(command,"rrule")==0) exit(sysync::rruleConv(cmdargc,cmdargv)); else if (strucmp(command,"wbxml2xml")==0) exit(sysync::wbxmlConv(cmdargc,cmdargv)); else { CONSOLEPRINTF(("Unknown Command '%s'\n",command)); printUsage(argv[0]); exit(EXIT_FAILURE); } } // eof libsynthesis-3.4.0.47.1/src/syncapps/sysytool/sysytool.h000077500000000000000000000010411226375725500232550ustar00rootroot00000000000000/* syncserver xpt generic header file */ #ifndef SYSYTOOL_H #define SYSYTOOL_H /* Headers that might be available in precompiled form * (standard libraries, SyncML toolkit...) */ #include "sysytool_precomp.h" /* headers not suitable for / entirely included in precompilation */ // transport related includes #include "xpt_server.h" // DB interface related includes #ifdef XML2GO_SUPPORT #include "xml2godb.h" #endif #ifdef SQL_SUPPORT #include "odbcdb.h" #endif #ifdef SDK_SUPPORT #include "plugindb.h" #endif #endif // SYSYTOOL_H libsynthesis-3.4.0.47.1/src/syncapps/sysytool/sysytool_dispatch.cpp000077500000000000000000000026411226375725500254760ustar00rootroot00000000000000/** * @File sysytool_dispatch.cpp * * @Author Lukas Zeller (luz@plan44.ch) * * @brief TSySyncToolDispatch * Pseudo "Dispatcher" for SySyTool (debugging aid tool operating on a server session) * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * @Date 2005-12-07 : luz : created from old version */ // includes #include "sysytool.h" #include "sysytool_dispatch.h" // common includes #include "syncappbase.h" #ifdef XML2GO_SUPPORT #include "curl.h" #endif namespace sysync { // dispatcher creation function TXPTSessionDispatch *newXPTSessionDispatch(void) { // create new app-sepcific dispatcher MP_RETURN_NEW(TSySyncToolDispatch,DBG_OBJINST,"TSySyncToolDispatch",TSySyncToolDispatch()); } // newXPTSessionDispatch /* * Implementation of TSySyncToolDispatch */ /* public TSySyncToolDispatch members */ TSySyncToolDispatch::TSySyncToolDispatch() { // create config root fConfigP=new TXPTServerRootConfig(this); #ifdef XML2GO_SUPPORT // xml2go needs cURL curl_global_init(CURL_GLOBAL_ALL); #endif } // TSySyncToolDispatch::TSySyncToolDispatch TSySyncToolDispatch::~TSySyncToolDispatch() { fDeleting=true; // flag deletion to block calling critical (virtual) methods #ifdef XML2GO_SUPPORT // xml2go needs cURL curl_global_cleanup(); #endif } // TSySyncToolDispatch::TSySyncToolDispatch } // namespace sysync /* end of TSySyncToolDispatch implementation */ // eof libsynthesis-3.4.0.47.1/src/syncapps/sysytool/sysytool_dispatch.h000077500000000000000000000016031226375725500251400ustar00rootroot00000000000000/** * @File sysytool_dispatch.h * * @Author Lukas Zeller (luz@plan44.ch) * * @brief TSySyncToolDispatch * Pseudo "Dispatcher" for SySyTool (debugging aid tool operating on a server session) * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * @Date 2005-12-07 : luz : created from old version */ #ifndef SYSYTOOL_DISPATCH_H #define SYSYTOOL_DISPATCH_H // required headers // - based on XPT transport session dispatcher #include "xptsessiondispatch.h" namespace sysync { class TSySyncToolDispatch: public TXPTSessionDispatch { typedef TXPTSessionDispatch inherited; public: TSySyncToolDispatch(); virtual ~TSySyncToolDispatch(); protected: // return output channel handle for debug virtual TDbgOut *newDbgOutputter(bool aGlobal) { return new TConsoleDbgOut; }; }; // TSySyncToolDispatch } // namespace sysync #endif // SYSYTOOL_DISPATCH_H // eof libsynthesis-3.4.0.47.1/src/syncapps/sysytool/sysytool_precomp.h000077500000000000000000000007251226375725500250120ustar00rootroot00000000000000/* Headers that might be available in precompiled form * (standard libraries, SyncML toolkit...) */ #ifndef SYSYTOOL_PRECOMP_H #define SYSYTOOL_PRECOMP_H // transport related includes #include "xpt_server_precomp.h" // DB interface related includes #ifdef XML2GO_SUPPORT #include "xml2godb_precomp.h" #endif #ifdef SQL_SUPPORT #include "odbcdb_precomp.h" #endif #ifdef SDK_SUPPORT #include "plugindb_precomp.h" #endif #endif // SYSYTOOL_PRECOMP_H // eof libsynthesis-3.4.0.47.1/src/syncml_tk/000077500000000000000000000000001226375725500174365ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/syncml_tk/Synthesis_RTK_history.txt000077500000000000000000000201421226375725500244730ustar00rootroot00000000000000Synthesis' changes to SyncML RTK - History ------------------------------------------ 2002-09-03 - changed message size calculation from inaccurate estimation to RTK's built-in space_evaluation method. This is accurate, but RTK code had a few nasty bug that took many hours to find and fix. 2002-11-27 - fixed bug in sml which prevented creating CTCap without Properties (but e.g. P800 email sends this). 2003-04-24 - Fixed RTK to generate MaxObjSize - Fixed to send namespace according to SyncML version and accept all namespaces beginning with "SYNCML:SYNCML" as namespace for document. 2003-04-28 - Fixed a zillion bugs in the RTK that made SyncML 1.1 fail (Nokia 7250). Encoder support for new DevInf flags (NOC, UTC, LargeObjSupport) was completely missing (interestingly, the TN_DEVINF_xx were defined but not listed in the tag table). Hopefully corrected all these now. - engine/rtk: RTK was using incorrect FPI's in WBXML when using SyncML 1.1. Introduced "vers" parameter for encoder to handle all these version dependencies neatly - SyncML RTK PPC: xptitcp.c for PocketPC did rely on send() to send the entire buffer, which is not something that can be guaranteed (altough it is normally the case). - SyncML RTK PPC: xptitcp.c tcpSendData() allowed a timeout of only 5 seconds for the socket to get ready for send(). In the HTC SmartPhone2003 this timeout gets exhaused after around 20k of data sent over GPRS, so sending failed. Now added a loop retrying the select() for about 4 minutes (interruptable). Made HTC work! 2003-06-26 - Reorganized xpt-tcp.c/h and xptitcp.c/h to have all platform-specific code in xptitcp.c. Standard (generic) implementation of TCP read and write is still in xpt-tcp.c but can be disabled if xptitcp.h defines PLATFORM_TCPxxxx symbols. A tcpEnableSSL() dummy is now also in xpt-tcp.c, so for a 100% standard xpt the xptitcp.c (which we added to the toolkit) is not a requirement any more. - Moved WINCE-specific timeout extensions for tcp read/write to win/xptitcp.c 2003-09-03 - Palm: Fixed bug in xptitcp.c: when send() did not send all bytes at once (PalmOS seems to send only 16k per call) we got a "Sending Error...". Now implemented a loop that send()s until all data is transmitted. 2003-11-12 - PalmOS client: Fixed problem in xptitcp.c which caused the net connection to be shut down even if it was already open when starting the client. 2004-02-23 - XPT: HTTP send was moving data in the send buffer (copyBlock(), called by encodeData()). Changed to only update the buffer pointer instead - send buffer should REALLY be read-only for sending routines!! 2004-04-28 - xpt-http: implemented CONNECT for proxy with SSL case. - PALM: implemented new stuff in xptitcp.c to allow deferred SSL handshake for SSL/Proxy case. Could not be fully tested because Palm emulator occasionally crashes on SslRead and SslReceive, however we could run one SSL session through the proxy so we assume its ok. Needs testing on real PalmOS >=5.2 device to verify. 2004-10-12 - working gzip (receiving only!) support now in xpt. 2005-01-10 - Added new error codes in xpt to pass through user abort from TCP level down to xptclientbase: TCP_TC_USER_ABORT in TCP, HTTP_RC_USERABORT in HTTP. 2005-01-11 - Made sure USER ABORT condition is also checked when opening connection, not only in message exchange. 2005-03-07 - RTK: Found catastropic bug in xltdec.c in routine concatPCData(), which was called only when (WB)XML contents were encoded not as a single string, but consisting of multiple, adjacent strings. The routine just did it plain wrong by using strcat into a buffer that did not have correct size allocated first. - RTK: Added #ifdef to RTK sml part to include the strings for the XML tags even if only WBXML is included in a client to allow decoding tags that are not represented by their WBXML token but by their XML tag string. 2005-04-29 - xpt http: Added HTTP_KEEP_CONNECTION #define 2005-05-18 - xpt: finished HTTP 1.1 "Connection: keep-alive". Now both XPT servers and XPT clients support this. The #define HTTP_KEEP_CONNECTION now only affects the config default for clients. For XPT servers, keep connection is always supported. 2005-06-07 - PalmOS: fixed error checking in xptitcp.c when sending or receiving data which caused that the app did not notice when the socket closed early (e.g. due to SSL timeout in HTTP 1.1 keepalive case) and then hung in waiting for receive on a closed socket. 2005-08-16 - Updated sml part of RTK from current sourceforce version - mainly change to doxygen style docs, no substantial code changes at all. 2005-08-17 - Many changes to adapt RTK for DS 1.2. 2005-09-29 - RTK: missing VerCT for CTCap, now added it. 2005-11-11 - SyncML RTK: made xml parser understand xml where metInf tags are used w/o namespace attribute (as in sync4j PDA clients). 2006-07-11 - xpt: Made HTTP auth support work in Basic and Digest mode (various little problems in xpt). 2006-09-07 - xltenc(XML): Finally implemented a real safe (= XML nestable) " in input string is escaped by exiting and re-entering CDATA and becomes "]]>]". This breaks the contained ]]> sequence so it is no longer visible to the surrounding CDATA parsing process. - xltenc(XML): Now checking strings passed as SML_PCDATA_STRING for invalid XML chars (&,<,>) and auto-switch to SML_PCDATA_CDATA generation mode if so. This mostly because of filter strings which now often contain pseudo-entities like "&iCON;" or "&NULL;". - xltdec(XML): Made parsing PCDATA sections that contain normal PCDATA and CDATA mixed actually work. The design was prepared for it, but was apparently not properly debugged. - Fixed bugs in xltdevinf, FilterRx parsing was missing, FilterCap parsing did not really work. - Added workaround in xltdevinf.c to allow extra rx-pref and tx-pref (as some clients send these). 2006-11-02 - Added detail parsing error logging for sml toolkit decoder. 2006-11-08 - xpt: gzip receiving did not work correctly when sender did not use chunked transfer, but sent gzipped message in a normal response (where content-length is the size of the compressed data). 2006-12-06 - XPT: fixed httpRead to make sure it always waits until it can return some data except if connection or document ends. This is important for chunked mode, because there are cases where the server sends some data (e.g. a chunk header only) that does not decode to any output of data. In this case, httpRead now repeats reading from the TCP socket until data arrives or connection ends. 2007-06-20 - xpt/http: Enhanced parsing of Connection: header, must be prepared for multiple tokens in http 1.1, of which only one might be the "close" token. 2007-08-14 - Made SML generator accept a with s AND a , when the latter is an empty string. Still, only ValEnums will be generated. This is to correctly translate WBXML back to XML from devices like E90. libsynthesis-3.4.0.47.1/src/syncml_tk/doc/000077500000000000000000000000001226375725500202035ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/syncml_tk/doc/ReadmeMaintenance4_1.doc000066400000000000000000003030001226375725500245320ustar00rootroot00000000000000ÐÏࡱá>þÿ ¾Àþÿÿÿ¼½ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿì¥Áq¿Û bjbjt+t+8<AApcÿÿÿÿÿÿ]ÀÀÀÀ444HHHH8€”4H¶¬ìÜÜ(ÀÀÀ{¬}¬}¬}¬}¬}¬}¬$¢¯ô–±Œ¡¬4À€€@ÀÀ¡¬j ÀÀ|Üj j j ÀXÀÀR{¬HHÀÀÀÀÀ{¬j äj N'’’ÊÀ"W¬$È€‹ ´ ßÁHH RYªþSyncML Reference Toolkit Specification READ ME Copyright Notice Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). All Rights Reserved. Implementation of all or part of any Specification may require licenses under third party intellectual property rights, including without limitation, patent rights (such a third party may or may not be a Supporter). The Sponsors of the Specification are not responsible and shall not be held responsible in any manner for identifying or failing to identify any or all such third party intellectual property rights. THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. The above notice and this paragraph must be included on all copies of this document that are made. File and Directory Structure The SyncML Reference Toolkit file tree is structured as shown in the following figure. Within syncml/src/sml the files of the toolkit itself are found. The transport handlers are stored in the directory syncml/src/xpt. Demos showing syncml at work will be organized within syncml/src/app. syncml ------ docs ----- internal ! !---- bin ------ win Binary files (like dlls) ! !---- src ------ sml ------ inc ------ win Public Headers ! ! ! ! ! !--- palm ! ! ! ! ! !--- mgr ------ inc SyncML Core (Manager) ! ! ! ! ! !--- all ! ! ! ! ! !--- win ! ! ! !--- wsm ------ inc SyncML Workspace ! ! ! ! !--- all ! ! !--- palm ! ! !--- win ! ! !--- linux ! ! !--- epoc ! ! ! !--- xlt ------ inc SyncML En-/Decoder ! ! ! ! ! !--- all ! ! ! ! ! !--- lib ------ inc SyncML Library Funct. ! ! ! !--- all ! !--- palm ! !--- win ! !--- linux ! !--- epoc ! !--- xpt -- !--- bindings Transport Handlers ! !--- manager Supported Platforms The SyncML Reference Toolkit has been implemented to be portable to as many hardware platforms and operating systems as possible. Nevertheless it is not possible to achieve an full platform independent code. The SyncML consortium therefore focusses on the following platforms: Windows 32 The deliverables target Windows 95 and NT 4.0 and comprise: Source Files. Several subdirectories named ../win hold files specific to the Windows target (e.g. syncml/src/sml/wsm/win). When compiling all these Windows-directories must be included. All other directories, which hold files specific to other targets must be excluded (e.g. ../palm; ../epoc)! The source code was developed using the following development environments : Microsoft Visual Studio C++ IBM Visual C++ GCC Palm-OS The deliverables target Palm OS 3.5 and comprise: Source Files. Several subdirectories named ../palm hold files specific to the Palm target (e.g. syncml/src/sml/wsm/palm). When compiling all these Palm-directories must be included. All other directories, which hold files specific to other targets must be excluded (e.g. ../win; ../epoc)! The source code was developed using the following development environments : Metrowerks GCC The Toolkit for Palm runs on Palm OS 3.1 too. Due to limitations of that version of the operating system, the size of the workspace is restricted to maximim 50kBytes. LINUX To compile and run SyncML under a Linux Platform, the Win32 source code is used. Please follow the instructions in the README.linux file in the “src/bld” directory. Changes in the Maintenance 4 Release Obex transport binding was fixed to work properly with the XPT communication API. Sofar it’s only tested on Win32 systems running Windows 2000 (OBEX / IR and OBEX / TCP/IP) Implementing several DTD changes to support device management Implementing new extension for “Progress Information” usind a new tag “NumberOfChanges” Implementing new extension for “Large Object Handling” using a new flag MoreData for Item-Tags Implementing new extension for “Large Object Handling”, new API to calculate remaining space for data after setting up the tag-structure skeleton Implementing new extension to transport toolkit to support cryptographic security against manipulation during transport, new header field “x-syncml-hmac” (HTTP and OBEX only, not WSP) Bug fix for an Microsoft IIS-Hack in HTTP transport binding Bug fix for a minor bug causing the HTTP transport binding toolkit part to crash if message type string is longer than allowed 4.1: Declarating function ltoa() in linux-special file src/xpt/bindings/http/linux/xptihttp.h 4.1: Adding support for ‘SupportLargeObjs' and 'SupportNumberOfChanges' tags in device information dtd  SyncML Reference Toolkit Read Me  SPEICHERDAT \@ "jjjj-MM-tt" \* FORMATVERBINDEN 2001-09-18 Copyright © Ericsson, IBM, Lotus, Matsushita Communication Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). All Rights Reserved.  SyncML Reference Toolkit Read Me  SPEICHERDAT \@ "jjjj-MM-tt" \* FORMATVERBINDEN 2001-09-18 Copyright © Ericsson, IBM, Lotus, Matsushita Communication Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). All Rights Reserved.   &'/?" # % B   ®  S a b c d w … ® Ç  B 5EÌÞ¶ÊËQc¶Ìáëì(4TZ‹¡<LËûóûéáÜÕéÏÉÏÃÏÉϻճթթթ¡Õ©Õ©Õ©šÕ©Õé’ˆ††OJQJ55B*CJOJQJ5B*OJQJ CJOJQJ6CJOJQJ56CJOJQJ<CJOJQJB*CJOJQJ B*OJQJ B*OJQJ B*OJQJ CJOJQJOJQJCJOJQJh5B*CJOJQJ5CJ$mH nH 5CJ$2'/@~¾úO‰Ê KŠ´µö;z»ü=Á I † ôôéççççççççççççççççççççççç $1$¤hH$7$8$ $1$¤€H$7$8$'/@~¾úO‰Ê KŠ´µö;z»ü=Á I † Ç O “ ¾ ¿  # % B c d † É Ó ] ’ ³ Ô L«ÞÿFr¥Ù Au–ß >_€Ìø+_’Çûe‡´µ¶·Ìáì(OP¹ÈÌÔüöðê              [† Ç O “ ¾ ¿  # % B c d † É Ó ] ’ ³ Ô LýýýýýýýýõâÒõÇÇÇÇÇÇÇÇÇÇÇ 1$d@ÿH$7$8$1$¤x¤xH$7$8$ Æ&$1$„°„Pþ¤ H$7$8$ Æ@1$H$7$8$«ÞÿFr¥Ù Au–ß >_€Ìø+_’Çûe‡´µôôôôôôôôôôôôôôôôôôôôôôôôôôôô 1$d@ÿH$7$8$µ¶·Ìáì(OP¹ÈÌÔ()v…†ôááÙÆÙ³ÙÙ³³³ÆÙ³ÙÙ³³Ù & F 1$„h„˜þH$7$8$ Æh$1$„°„Pþ¤ H$7$8$ ÆÐ1$H$7$8$$1$„°„Pþ¤ H$7$8$ Æ@ 1$d@ÿH$7$8$ËÌÓÔ29g~%v„-23ØÙÚÜ"opq–—ÇÈÒÓዟ ¡¢ÇÈøù   ¼ Ó Ô Ö × Ú Û øîìçççìøîßÕÕÏÃϾ¾¾¾¸¶³¾¾¾¾¸¬¥Ï jp2CJU jCJUCJh hmH nH jUB*OJQJhmHnH B*OJQJ5B*CJOJQJB*CJOJQJOJQJ55B*CJOJQJ5B*OJQJ4()v…†-3ØÙÛܰîF¥7ï+ªpÇÔÕ ¡¼Å  L Ñ Ò Ó Õ Ö Ø Ù Ú Û úôîëåßÙÓÍÇÁ»µ³°®®®®°°°®®®®³³µ                                                   ,†-3ØÙÛܰîF¥7ï+ªp÷ä÷ÔÈ÷¹®           & F 1$dðH$7$8$ 1$dðH$7$8$$1$¤ H$7$8$ Æ@ 1$H$7$8$ Æh1$¤x¤xH$7$8$ Æ&$1$„°„Pþ¤ H$7$8$ ÆÐ1$H$7$8$p‹”ÔÕ ¡¼Å  L Ñ Ò Ó Õ Ö Ø Ù Ú Û ûûûùööùûûûùööùùùùùùùè & F 1$dðH$7$8$$¤ 6 00P P &P °‚. °ÆA!°8"°8#p$R%°°Þ°2p2Dd&&`+`+ffð<² ð C ðA¿ÿðÂbðà1„oœÅr<,;ÖFQ[‡¬bÿ¼1D6nð´1„oœÅr<,;ÖFQ[‡¬bÿ‰PNG  IHDR&&è¬ÖgAMA±ˆ•˜ô¦ pHYs ø øf&<ý IDATxœíÝytU¢Çñºˆö"$ÄƃèÂ.Žì0 ‹¨Œ ›(F‘a—qæ Ûˆ ‚ìˆG}"¢(úØQGD-ÀŒ$  D ô}Ü¡^Ñtª·Û ù~þð`§êÖ­êêúÕ½u«Ê0Üà„¡®ܨÂöZ!Ô(¹±Âv«@Ø’R†!„Pÿ+á9Jxn/sá|²¾‘ãp8âããC] ¸ÁüòË/N§3Ôµ(Y˜FŽ”2>>>+++Ô€LBBBvvvx¶u¡® ¼ rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBäØ"¥tùG™S\9¶!\þ¡¸Œ9Ù.*„º7)¥âÂ… §N:~üøéÓ§333 OŸ>m†ÓéT“ !TÒÔ¬Y³R¥JIII5jÔ¸õÖ[ãããëׯo–€"rJ ¥,,,|áÂãZl¨h1ÿaåÒÐQÓDFF&$$$$$4lذQ£FÉÉÉ­ZµºõÖ[ !„ÊùóçKk‹ !ªU«vCì™RÊüüü¢¢¢ÿêp8ªU«Vâ\çÏŸwù0**ªråʯ"œÚÑëׯ/µ+**Ú²eËàÁƒ+Uª$„B8ŽÀþðÌ2G\\܈#þõ¯é_S”gN§SJ™ Jáp8<êjÚråʕڵk—¶"Íš5S+ëâܹsê—h=zt‰ßpTŸJxž1p-ç¿òòò^|ñŤ¤¤6mÚ¬\¹²°°Ð0 !„ÙiªÅ£†‘““³lÙ²Ž;¶k×nñâÅ—.] ಀҨƒ‘uo´Rýè£B]M[–.]zöìY÷µ0,«YâŒÒ2&Èe‘c†±bÅŠ;ï¼óå—_>qâ„qm_T{¡Ãá  T»µu)ßÿýèÑ£[¶l¹aÆ@- ð¬´[í“~ø¡æúøàÊ•+Ó§O/mET“¥´yÝÿÀ_:JSN#ÇÜ·V¯^Ý´iÓ!C†;vÌ¥M­& l+Ç0 §Ó©ÊtY”ò§Ÿ~êÞ½{‹-V¯^Ø…î<a322–-[f*å‰'fee•ø§2ë,¯u0¡^(U9Ã0Š‹‹Ç׿ÿ„º.ÿ¥ú4222ú÷ï?lØ05Z )åSO=uîÜ9#\»›233ßxãP×Þ)‘#¥¼råJ·nÝæÍ›g„ÓÏIõ­«3¯wß}·mÛ¶G u¥P~åçç¿òÊ+¡®E©V­Ze„q %*‘ãt:‡þå—_šÿë[9%Ž1?÷¡@ë5LÕÏÖºuëÍ›7ûV=À>—}ظ¶7¾þúëÿþ÷¿C[·]¾|yÉ’%êßî•GØ*‘3uêÔ÷ßß°âýdŒýU gÏžíÛ·ïÙ³gý¯$`“õwqùòå7ß|3´õ)ÑìÙ³­YHØÜ(Ê]äüðÃ/½ô’ˆö¸‡Q•þ:0ögÏž4hPÀG1Vê,Çá¸î€ ZÛ|ðAqqq¨*æÂüQL:Õ°üŠé^»Q”£§H)sss|ðAkç•EIMkܸqƒ êÖ­[«V-óÃâââ“'Oæåå?þàÁƒyyyòÚ£ „Çx¨³a›6mJKKãJ)‚Gí–ÉÉÉõë×߸q£aÙÛ³²²fÍš5qâÄVð:?þxAA¼þɃþæ›oÔ}€DО>0iÒ$ßêãp8Ôý4qqq¯¼òŠºõ¬Ä•Í‹ŠŠ80kÖ¬:”xÉÇ>µè-[¶|ƒ qß]+UªtìØ±P×÷¿Ö¯_ïò#BÔ©S''''!!Áå·“’’Rb!j$ž‹Q£Fi^— áéa¡¨¨héÒ¥¾Íët:£££§OŸ~øðáñãÇ׬YÓ(å5?ŒˆˆhÒ¤Éøñã¿ùæ›Ï>û¬^½z†O# ÌVѧŸ~*Ãû& Üè„]ºt‰u¹$YXX¨:²ÂÁßÿþw—‘”rüøñµk׿§þÊQä8pàÌ™3>Ì(¥Œß¾}ûĉcbb ïú={öܳgOÿþýÍOì¼Ö{ Nî$EÐH)£££'L˜`žÜ˜»Ü²eË233C]AcË–-[·nuùV«Ví±Ç3Âõ¼Vå(r¾ýö[¯¦7{bbbÖ¬Y“œœlýÜÛ¥W¯^ýÃ?|æ™g|h©¨‰322víÚåÕ¥ ¸ ÉÖóm¡¡ú¢Ÿx≻îºË¬ƒÂét^½zuøðá!G0oÞðã?ú6ã”)Sî¾ûî€Ôáå—_Þ¸qã?þèà Ã0–/_~×]w…éœÿ­à• -Ã4rss/_¾\§Nˆˆ5½¶­g­žËB =zäÈ‘¬¬¬Ó§OçääK)Ïž=UµjU§ÓÓ¸q㤤¤;î¸Cõå×f àºXK‹ŽŽ~ï½÷Ìs,s¹›7oÞ´iÓý÷ߨ…z+++kåÊ•âÚÓHk[cìØ±†÷ÃA§r9'Nœðê$HíÙÑÑÑ<òˆúÄÿyddäôéÓ{öìéÛ ç~øÁÛY‚ÔçC™Ö“SßJ0J?Ž«ÏwìØ±iÓ¦½{÷feeíß¿_½@ÏL÷F5mÚ´aÆÉÉÉ=zôPWׂǥz?ÿü³:doÛ¶mß¾}fÅÌꙉhÝKÍÿ­Q£Fûöí;wîܱcÇfÍšEDDõðzÇw´mÛöûï¿7+£ª·jÕªPEŽ”rÚ´iW¯^µF‹¢k×®76§ IÝ`_y‰)¥·rÔšZ½zõ¶Ù»uëvß}÷}ñÅ>Ì›žžžŸŸ¿~ýúE‹Ù¬¸6üoÙ²e>,±DRÊM›6͘1ðñ#7-Z´˜>}ºú÷ÁƒÇg“¦¥¥õêÕË()¨öïß¿fÍš7îÚµËý¥[†a8N5×áÇ>l~žœœÜ¼yóÞ½{÷îÝ;/ær:{öìÙ²eËæÍ›7oÞüŸÿüÇe3i¬Í/—mbþonnîš5kÖ¬YcFݺuÛ·oߦM›öíÛ£Õ«ê3vìØï¿ÿÞzùPJ¹bÅŠI“&ÝvÛm]¢_}õ•zÜ€uÕªUkñâÅæÿÒÊ/Ì£¤·C=kÑ¢…W{¤: ôìÙS–2Ú7N§såÊ•¾m‡Ã±sçÎììla·mgc:Ž;vj¤”C‡µÓah»xñbsöôôt¯¾‹… º×aíÚµMš4ñ¹;Å|Q^•*Už{î¹ .øö-«¹\æýç?ÿÙ²eKõùP·2™;@jjê¶mÛÜ+`‡u´*ÓR¬.Þ$%%™_Ÿ¹Ð=zø°•üdVÆ¥ÂóçÏ·NÆ i%œI‡£ð‰‡Ã‘ØjH)8àÛÞ „X·n”rÈ!êXfó ïp8†¨ú™ïa´³ •“'Oš%ø9ÇŽ{衇ì箇º™Û'55õ—_~ñmƒX÷{÷îMMMõ³nv*oÖÜápôîÝ[õ{<"Gµ`Áë&2ªBN§ 6¸ïo±±±—/_¶NFä(DŽwÂ'r”¹sç–x&ë3ŸË1«‘™™©^Mo¿™žžµ˜?¾°÷Šnó˜8iÒ$õ¢ U‚Ï‘sìØ±?ýéO·Ür‹º˜ásǸþ¨­þ[­Zµ—^z)//χMät:<8vìØÊ•+[ÎÁk师5kÖ¯¿þj¿Îž[9ª¡Ó®];÷eµhÑ¢°°ÐÛMä?üáîßõ¤I“\&#r"Ç;AŠuîé[}¾ùæ›ÀVÆÓ§Oˆˆðj-ºtéâÿr ëÕ«g3rTÞÔ©SçâÅ‹ÖB|‹œ#GŽ$&&ÚŸËBˆ;ï¼Óú(ä¿p!DRRRff¦Í:{nå(‡ªP¡‚58Õ¡õêÕ6—â¿ýû÷[—®v¼Š+fgg»LIä(á9åè¾s˜©üõ×_®.ðøã×®]Û«Y¾øâ ?ßG'¥üøã­¯ë.sz)åøñ㣣£ýY®aééé;w.í"„سgÏ´iÓÌÿõ0±¹6nÜøÇ?þ1¨+“J‚cÇŽõë×ïÒ¥K*¶qãÆ;w¶~¢Öú½÷Þ Ô"Ê4~üx— !}ôÑ`9D0”£Èq9§óÊ©S§ÔøÔwß}7??߃á˜UªT?~¼ýõC;w®? BÌŸ?ß«YªT©2jÔ(jÆéÓ§¨óågQž©­ôÆoØR¯6þçŸÞ§OŸüüüОTšµÝ»woïÞ½˜: °þ¯ZÍÿýßÿÕðN )ezzúúõë]>ŠŠšùäÛo¿‘‘árõBt¤µiòäÉöGK«ÉfÍšåóâ&NœèÕ~œ˜˜XTTä¾âÞFŽ~Bˆ‰'JßÚÊ•+ý/ç²ÿX‡ Š’xU¸a·ß~»ûNhe3r¤”+V¬p¯ÃáØ°aC0öjÅét®^½Z¸ ÁhÖ¬™zXƒ;"G!r¼¤È)..6ïRH%Åõ£l]~*THMM}衇^xá…/¾øâÌ™3ªý‰îܹӿ!ɬdçÎ}^ÜwÞéÕ~Ÿ[97~æ™g–/_¾sçÎóçÏËk»¨Yþ¹sçvïÞý?ÿó?ÇWâ}¨Æ UC§Äµ°ßÊ‘R~÷Ýw*Tp?Á Þе]»vEEE¹ìržCŽÈQˆï#rLcÇŽ ê=z>HIIyúé§?ýôSÏÝ ¥9sæL¥J•¼Zø° ó]se–¯&ëׯ_iEù9Âr—¥¢FÆ [´hѦM›vïÞ}üøñôôôo¿ývîܹýúõ«R¥ŠKöÛ_Šâïÿ{‰õߺu«ý¢\ZÀIIIï¾ûî•+Wìoù¼¼¼É“'W¨PÁlÙ_úsÏ=WZ±^EŽ”òÏþ³Ëft8¿ûÝï쯈WRSS]¾!Ä{ï½çáT‰ÈQˆï5r.\¸àÏSR‚Áü9ÅÅÅ;vóæÍ¥uU—f̘1^]¦r8Gõª•³{÷nóÐigu‡‡×˜ú9jî¹çž 6zX‘‚‚õF/ßR§´G6ôèÑër̘¼ÿþû½º[SQ+øÚk¯9¯nÆ2 #..®´qÞFNNNN¥J•\f‰ŠŠ ì CUU]F©©}/&&F½Ü½4DŽBäx'¨‘#¥û¬o—¬ï»ï>ë¶µ³¸F¹—3eÊo[K‡cúôé>ÔÙyg•ýµ¨_¿~‰[ÌÛVŽ”R½$к'¨ÿ.X° k§Œ3ÆeÕÔo¡Ì‰…ÈñN°#G0žËÉÉ‰ŽŽvœo¿ý¶Ìy‰%œ#§=}ÀE:u6lØ0aÂó“°ú†ÔÁQJ©|0{öliyÙ¥ûÄ-[¶LLL,ñ¯¥•¿aÃ;Sæåå}üñÇ6‹U%»Ü¯î?yíUf/¾ø¢Ï…tíÚ566Ö0 ‡ÃauÜíÛ·ÏۼƎëí5˜ !*T¨Ð·o_ÛÝU±k×.ÿ—®üõ¯UÇ5ë‡ÇŽ Ô ™V¯^}ùòe—3§æÍ›·k×. 宂ÚÊq&ô?þøüóÏÿæ7¿ «VŽõž å…^0ûôK\£µk×ÚΤ ŒŠŠ²Ók·hÑ"¯¶LíڵϞ=ë¹LZ9‡cäȑқœNçóÏ?ïUsÖ}'— ®ÃÛù1«Õ¬Y³yóæÂö56û¼*0°G)åèÑ£]Z9RÊŒŒŒ+Vø\æK/½tìØ1—Ï[¶lùä“Oú^W L!låØqúô鯾újΜ9ÇoÙ²¥ûýíÖ6Ëç.õv³(óæÍóP½O>ùĺt;Å–öÈáS§NEEEÙ,Ç0Œ&MšØÜ†>´r ¼þªJbË%í„¿ýíoíÌn~׿ÿýïRí`ð§•ãt:­÷ÚÄf3×]vv¶{óQ±ÿ~û…ÐÊQhåÜTbcc;uê”––¶dÉ’mÛ¶]¸páàÁƒüñ¤I“†ªNiÝû߬©ãymÄÚÆ=LÖ¥K—¸¸8aïȪ>îï#QæÍ›wåÊÃÞ µ¢W¯^eN曺uëÞrË-,ÐΕ(;;Û«&K||¼o sBˆ_|ѽ—òôéÓê”ÈN!ÖÉV­Z%¯o> !Ú´isÇw°Ú9"ÇwæÏ£qãÆ}ûö2eÊ;ï¼³k×®üüü={ö¼ýöÛiii=zôˆ‹‹3®?/¥§§{øIGGG?óÌ3†í£ªbݺuîŸ-]ºÔ«Šýáðjzûj×®ísHÖùóçmN©’ÉŸwц¹V­ZuíÚÕý{ùÇ?þ¡^cX&ë¯àwÞ1ÜvÚ€¶GÈ9¾³þ<Ì4)etttÓ¦M~øáW_}õ³Ï>;yòdVVÖ§Ÿ~:uêÔ:×zù}^îÉ“'wîÜéa‚'žxâÎ;ï´¿ëÖ­;~ü¸Ë‡6lP/œ¶©M›6Öç0Vdddxöx&„P=“7%)åk¯½V¹re—¯æÜ¹sê¥ öËY±b…z ‡õóZµj=òÈ#F¼DäøÎ¥áâáÃzõêõêÕëÙgŸýúë¯úé§.]º¸÷¼Ù!¯ =úúë¯=L=cÆ ûÅ^ºtéå—_6Ø*>?øàƒ2g´®Å’%Kû¼°åÕ·¦z&oJBˆÆ<ØýOóçÏ·¿‰òóóÏ{9IDATÓÒÒÌ}ÛìþÇ?þ¡Fë܈g(M¹8F>(éÜ*99yýúõ P/¾ýœŽ=êy‚®]»¶jÕªÌrÌu|çwÔ­†a!Š‹‹ÿùÏÚŸ½[·nå¤Ï=::ÚÎŽaNSâeꛆ”ràÀî$33³´ „.³†1þüÓ§O›ªßE³fÍÜÇaã&P^"Çð5uœNg`ë ª±páÂFùüä•'NxžQJ9þüÈÈHÏå˜?é‚‚‚©S§šÆ—-[vòäÉ2«¡fŽŽ~õÕWÕŒ7}H£FìLfnØÌÌÌ`V'Ä„;wnÓ¦ûŸÒÒÒìÄíž={¦M›f)eddä›o¾G!ÜTut8}úô}÷ÝçÛÑpàÀþ<×Ë…ùÓªQ£Æ /¼ðÈ#x5üÉTTTäùPѼyóîÝ»¯Y³F}RâRäµg— !fÏž–––˜˜xåÊ•—^zÉ(åynîÆg6qnúÓÒÄÄÄ={ö”9™¹a·mÛV\\Ú£§Ïi;"""–,Y’œœìp8œN§¹;effNž· löíôéÓç³Ï>3»ËJKãÚQiþüùÓ¦M[³fÍ/¿übs)ãÇ÷znXêÙ©†£&ÈÏÏÏÈÈhÑ¢EëpéÒ¥™3gÚœX}ï-[¶ìÞ½{ë`Õ¤I“!C†|ðÁf°©uë­·¦L™R⛜Ôþ–‘‘±uëVÕÖ7·gDDÄäÉ“ƒTU "з‚úp­^MÛm·ðõSVN§SÝÖàÃ&0`€ûó=Ýýúë¯êigÝ…UªT9qâ„:cµ9KiïÍôÌÛ[A[´háÓ6.ý…%í„j”„W•>|x x£ÊÙºu«¸ö@Ï‹V_bioëñçVPk}¤”ÙÙÙ±±±.ûŒ¢Ä·Ã™¢9r¤ûÎ9lØ0¶ŒÂ­  ·‚†XTTTƒ |›÷çŸÞ¶m[`룘/$öaÞøøx;‘3cÆ û}w?þøì×dذaö'¾ øðýåË—Ÿ={6 KWßøæÍ›ÕwZæ×jN’’ ”XÃ0êÕ«7gÎ÷¥/Z´Èýj¨ªüÙ³gß}÷]÷2Ÿzê©`Ta¢\DŽa>Œ§2O^ýõ@UÃzŒØ³g·§!æ)aÆ {_<ð@Ó¦Mí¤ŽZÙÕ«WKËÙ«çj$$$Ü{ï½^­Â®I“&U«VõvhûG}À:¬_¿Þóä^û÷iùlРA¬¬·ÞzË}b!Ä /¼péÒ%s-ÔÕºuëæÍ›»ª¡ò9)))>73W¬XqèС€TÃZu²_+k³æî»ï¶9oDDĤI“¼ZýúŒ;¶B…rq9Ðê·¿ý­·mÓ… jéÇŽó|W–»5jÔ«W/P(MDDD¿~ýÜw³)S¦¸ßœäEjF5n7±ò9}úôñ­ Ë0 !Ę1c.\¸ÀúìØ±Ã|:§ÍỶ+W®|Ï=÷ØŸkàÀ·ß~»-]JJÊ“O>éóV½qÝÿýÞβ{÷îG}TÔû³èììì^½zy5רQ£ô ™=z´õD¥È±cÇþú׿šJ)‹‹‹{ì1—’R<ØÛ—|ðáJݺu}>ÓB4mÚÔ«‡Úz““Ó¸qcáýƒ>UC§sçÎÞ.qöìÙf#Éÿ掺"½nÝ:Ÿ·À;|@J¹{÷nsKzÕHMMM5/àùàäÉ“III6‡u˜Ó!Ž;Vbþpát:ÇŒc\ÿ[UëoG]‹rhP¹reÿ_*Êð…áa¡]»vþ|û÷ïoÞ¼ùÔ©S/]º¤>‘Þßü(¥üòË/[µj•™™éÃìJÇŽ½š^JùÀ¨û|ó©‹ tëÖÍÿrnDÍš5KNN׆JÛÜ©¤”[·n:tèÕ«WÝÿTÚ,æ¿/]º4hР¬¬,ûõT‡õ^½z¹ˆƒD1iÒ$—ÇÊ©ƒ õæ¶>øÀ}•ûöí[«V-µ\©•³fÍß"G\/11ñ‰'žX¾|ù‘#GTÉæ Oëâ¬ÿ{éÒ¥íÛ·Ï;W½ÔÙŸjDFFzÛØRé'Mšä> Õ7Bˆ)S¦øó]ÜЭ)åÚµk£¢¢¼Ý˜jú[o½õé§ŸÞ»w¯‡JZ÷¨#GŽLš4)>>ÞúRZ; BDEEíÚµKá­ LŸ>ݽžBˆï¾ûNJ™­Æ_XGx«¿ú?”œVŽέœrtí·G))){÷îõ³œ¬¬¬yóæ©W®\¹yóæ5jРAll¬õ®·ÜÜÜììì'N9rdÇŽ/^4,1>=}ÇápŒ1ÂÛÑwjÏ›4iÒ’%KÔh]–îbøðá~–pCëÞ½ûèÑ£çÎkxÿmžß ¢veÃ0&Nœø›ßüFóI‘7ŠaÆ=ýôÓ~"ÝRPX&¸ÿÕ!DŸ>},Xª7%%%¥¥¥¹îò¶P!Dbbâ+¯¼¢«^½rt-Ç|Û¶m‹-2?ñí‡TÂò6!ÄСCGŽé±-[¶lÒ¤ÉÁƒ¥—W•TM*Uª4jÔ(ÿ«qsRΘ1#''G½DÙüЫ¨°~Ñæ¼Òò¬UŠjÞ¼ùûï¿ÂÇW !ÆÿÆoäçç[OMÜÏTž}öÙðyqê?üð·¿ý-$‹nܸñƒ>’E#ˆ×rL¿þúk›6mÄõÃfŠuxÒØ±cøhÑÉ“'›½dö[*jÊßÿþ÷©ÃÍѱ¦º‹ŠŠFmݤ¡Ú¯Ô¢“’’Ô¿2{>ƒ×±¦<û쳞»k×®}ùòå.ÑÏŽµêÙ³g·káEJY¥J•¯¾úê­·ÞªW¯^¦Žyº·téÒyóæ°’#FŒ°ùjK÷Zýñ T5nêkŠˆˆX°`Ák¯½mý<$UjÛ¶íÆkÖ¬’¥›ÔêOž<¹~ýú|#FŒ¨X±¢Æz!ôÂîh«:튊Š6lØŽ;zöìê¹’RFFF¦¥¥eff>úè£-¼AƒãÆóaÆÛn»­OŸ>­ÌÎ<žŽ7nß¾}êöØäMåÊ•/^üí·ßÞ~ûíf¬þj(jÑ111=ö˜,ý²ßO<¡·^½ò9VqqqkÖ¬Ùºuë]wÝ¥:FT{ÂÚ!¤Ÿ®{WŒùïîÝ»gff¾úê«111ÁXô„ \n)³’†aüå/ á·Ô¨Ü2¿SF‹%&&®]»væÌ™êÌÝå;õ¡ÀkeÖÍ\u~ݺuúÓŸ|(ÍŒ¤0`€KÉæf9rdP6jç+öÀ¡ÿµoÜ(nø#H@´jÕjÛ¶m_~ùå‹/¾Ø©S§J•*×?'*à„åÍ’æÛ´i3}úôíÛ·þù牉‰ÁX®ZPaa¡ýk¶ªzÍ›7ÔíŸN{ˬF@–n³(RÊ &dee-\¸P= /€ûË)¥¬X±âÀׯ_äÈ^äãR¸uŸ ”F©§®Y©‹ S§N à‚Jäù )¬Žò¡ê‰Õ¯Xó,22²cÇŽ:u2 ãÌ™3ŸþùÆ7lØ››Œ½AZF£uïÞýèÑ£‡z¯¢ÌýO-wêÔ©çγó“3¯*ÍŸ??222 ÇP!D­ZµFm5u€°?âNQ½zuõòVûåK)k×®=räÈ#Fdgg¯X±bÆ _}õ•ý¨+³VÑÑÑ}úôyàºuëf^@òÁƒ>xþüykÉñññþ×ÐJ1sæL—·´ !þD5µg:477×\Š”2>>¾Ä¶bÅŠjt:á=Íš5 u4 ý¶v§ö•úõë{õÃ`¸råÊÞ½{·mÛ¶cÇŽ½{÷îÛ·¯  @^?¤UM)¯96ç5/ÖiÔ¿o»í¶Ö­[·jÕªU«V)))Aê=+Mnnnݺu¯^½jç¨Úºuëï¿ÿ^CÝnV'NœøôÓO·lÙ²yóæ£Gª­{‘´Œ‡–aÓ†e·iß¾}Ë–-;tèpï½÷V©R%D«‚@BBBvvv‡±x@äØbòóóÏ;wêÔ©‹/æäääçç«cwnn®Ë,¥Œ‰‰QÝúÕ«W­^½z\\\\\\DD„õø¢yE^}õÕ &Øœ^±}ûvÞÕèk–äääüüóÏ999yyyN§3//Ïú5‡ÃQ½zu‡ÃQ­Zµ5jÔ©S§nݺµjÕRñ§äsDŽwÂ0r\xõË«ÃÄÅ‹7n|âÄ ›Ó;Žûî»oãÆA­U¹âmOà­pŽv}_x!á“7†aLœ8ñ—_~±?½”²_¿~Á«O9DÞ ftæÌ™Þ>ì rð_j|Aß¾}Ÿ~úéP×À͉k7÷§\+.Àvy¨¨ú°Aƒo¾ù¦ö*(/håÜ$\Þ-èòVë'Ö7Kš³·hÑbΜ9qqqú*  œ¡•sSqiܘOð0e—.]ÆŽÛ»wï`¿ˆœ›Ä°aÃÚ¶m[PP ^Áb>.://ïüùóæ«kÔ¨Q­Zµøøø:uꤦ¦vèÐÁú²/ò@P97‰¡C‡ú_¶T\ËhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9MˆÀ¶ÿÖµÁ÷”hèIEND®B`‚p2Dd&&`+`+ffð<² ð C ðA¿ÿðÂbðà1„oœÅr<,;ÖFQ[‡¬bÿ¼1´26nð´1„oœÅr<,;ÖFQ[‡¬bÿ‰PNG  IHDR&&è¬ÖgAMA±ˆ•˜ô¦ pHYs ø øf&<ý IDATxœíÝytU¢Çñºˆö"$ÄƃèÂ.Žì0 ‹¨Œ ›(F‘a—qæ Ûˆ ‚ìˆG}"¢(úØQGD-ÀŒ$  D ô}Ü¡^Ñtª·Û ù~þð`§êÖ­êêúÕ½u«Ê0Üà„¡®ܨÂöZ!Ô(¹±Âv«@Ø’R†!„Pÿ+á9Jxn/sá|²¾‘ãp8âããC] ¸ÁüòË/N§3Ôµ(Y˜FŽ”2>>>+++Ô€LBBBvvvx¶u¡® ¼ rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBäØ"¥tùG™S\9¶!\þ¡¸Œ9Ù.*„º7)¥âÂ… §N:~üøéÓ§333 OŸ>m†ÓéT“ !TÒÔ¬Y³R¥JIII5jÔ¸õÖ[ãããëׯo–€"rJ ¥,,,|áÂãZl¨h1ÿaåÒÐQÓDFF&$$$$$4lذQ£FÉÉÉ­ZµºõÖ[ !„ÊùóçKk‹ !ªU«vCì™RÊüüü¢¢¢ÿêp8ªU«Vâ\çÏŸwù0**ªråʯ"œÚÑëׯ/µ+**Ú²eËàÁƒ+Uª$„B8ŽÀþðÌ2G\\܈#þõ¯é_S”gN§SJ™ Jáp8<êjÚråʕڵk—¶"Íš5S+ëâܹsê—h=zt‰ßpTŸJxž1p-ç¿òòò^|ñŤ¤¤6mÚ¬\¹²°°Ð0 !„ÙiªÅ£†‘““³lÙ²Ž;¶k×nñâÅ—.] ಀҨƒ‘uo´Rýè£B]M[–.]zöìY÷µ0,«YâŒÒ2&Èe‘c†±bÅŠ;ï¼óå—_>qâ„qm_T{¡Ãá  T»µu)ßÿýèÑ£[¶l¹aÆ@- ð¬´[í“~ø¡æúøàÊ•+Ó§O/mET“¥´yÝÿÀ_:JSN#ÇÜ·V¯^Ý´iÓ!C†;vÌ¥M­& l+Ç0 §Ó©ÊtY”ò§Ÿ~êÞ½{‹-V¯^Ø…î<a322–-[f*å‰'fee•ø§2ë,¯u0¡^(U9Ã0Š‹‹Ç׿ÿ„º.ÿ¥ú4222ú÷ï?lØ05Z )åSO=uîÜ9#\»›233ßxãP×Þ)‘#¥¼råJ·nÝæÍ›g„ÓÏIõ­«3¯wß}·mÛ¶G u¥P~åçç¿òÊ+¡®E©V­Ze„q %*‘ãt:‡þå—_šÿë[9%Ž1?÷¡@ë5LÕÏÖºuëÍ›7ûV=À>—}ظ¶7¾þúëÿþ÷¿C[·]¾|yÉ’%êßî•GØ*‘3uêÔ÷ßß°âýdŒýU gÏžíÛ·ïÙ³gý¯$`“õwqùòå7ß|3´õ)ÑìÙ³­YHØÜ(Ê]äüðÃ/½ô’ˆö¸‡Q•þ:0ögÏž4hPÀG1Vê,Çá¸î€ ZÛ|ðAqqq¨*æÂüQL:Õ°üŠé^»Q”£§H)sss|ðAkç•EIMkܸqƒ êÖ­[«V-óÃâââ“'Oæåå?þàÁƒyyyòÚ£ „Çx¨³a›6mJKKãJ)‚Gí–ÉÉÉõë×߸q£aÙÛ³²²fÍš5qâÄVð:?þxAA¼þɃþæ›oÔ}€DО>0iÒ$ßêãp8Ôý4qqq¯¼òŠºõ¬Ä•Í‹ŠŠ80kÖ¬:”xÉÇ>µè-[¶|ƒ qß]+UªtìØ±P×÷¿Ö¯_ïò#BÔ©S''''!!Áå·“’’Rb!j$ž‹Q£Fi^— áéa¡¨¨héÒ¥¾Íët:£££§OŸ~øðáñãÇ׬YÓ(å5?ŒˆˆhÒ¤Éøñã¿ùæ›Ï>û¬^½z†O# ÌVѧŸ~*Ãû& Üè„]ºt‰u¹$YXX¨:²ÂÁßÿþw—‘”rüøñµk׿§þÊQä8pàÌ™3>Ì(¥Œß¾}ûĉcbb ïú={öܳgOÿþýÍOì¼Ö{ Nî$EÐH)£££'L˜`žÜ˜»Ü²eË233C]AcË–-[·nuùV«Ví±Ç3Âõ¼Vå(r¾ýö[¯¦7{bbbÖ¬Y“œœlýÜÛ¥W¯^ýÃ?|æ™g|h©¨‰322víÚåÕ¥ ¸ ÉÖóm¡¡ú¢Ÿx≻îºË¬ƒÂét^½zuøðá!G0oÞðã?ú6ã”)Sî¾ûî€Ôáå—_Þ¸qã?þèà Ã0–/_~×]w…éœÿ­à• -Ã4rss/_¾\§Nˆˆ5½¶­g­žËB =zäÈ‘¬¬¬Ó§OçääK)Ïž=UµjU§ÓÓ¸q㤤¤;î¸Cõå×f àºXK‹ŽŽ~ï½÷Ìs,s¹›7oÞ´iÓý÷ߨ…z+++kåÊ•âÚÓHk[cìØ±†÷ÃA§r9'Nœðê$HíÙÑÑÑ<òˆúÄÿyddäôéÓ{öìéÛ ç~øÁÛY‚ÔçC™Ö“SßJ0J?Ž«ÏwìØ±iÓ¦½{÷feeíß¿_½@ÏL÷F5mÚ´aÆÉÉÉ=zôPWׂǥz?ÿü³:doÛ¶mß¾}fÅÌꙉhÝKÍÿ­Q£Fûöí;wîܱcÇfÍšEDDõðzÇw´mÛöûï¿7+£ª·jÕªPEŽ”rÚ´iW¯^µF‹¢k×®76§ IÝ`_y‰)¥·rÔšZ½zõ¶Ù»uëvß}÷}ñÅ>Ì›žžžŸŸ¿~ýúE‹Ù¬¸6üoÙ²e>,±DRÊM›6͘1ðñ#7-Z´˜>}ºú÷ÁƒÇg“¦¥¥õêÕË()¨öïß¿fÍš7îÚµËý¥[†a8N5×áÇ>l~žœœÜ¼yóÞ½{÷îÝ;/ær:{öìÙ²eËæÍ›7oÞüŸÿüÇe3i¬Í/—mbþonnîš5kÖ¬YcFݺuÛ·oߦM›öíÛ£Õ«ê3vìØï¿ÿÞzùPJ¹bÅŠI“&ÝvÛm]¢_}õ•zÜ€uÕªUkñâÅæÿÒÊ/Ì£¤·C=kÑ¢…W{¤: ôìÙS–2Ú7N§såÊ•¾m‡Ã±sçÎììla·mgc:Ž;vj¤”C‡µÓah»xñbsöôôt¯¾‹… º×aíÚµMš4ñ¹;Å|Q^•*Už{î¹ .øö-«¹\æýç?ÿÙ²eKõùP·2™;@jjê¶mÛÜ+`‡u´*ÓR¬.Þ$%%™_Ÿ¹Ð=zø°•üdVÆ¥ÂóçÏ·NÆ i%œI‡£ð‰‡Ã‘ØjH)8àÛÞ „X·n”rÈ!êXfó ïp8†¨ú™ïa´³ •“'Oš%ø9ÇŽ{衇ì箇º™Û'55õ—_~ñmƒX÷{÷îMMMõ³nv*oÖÜápôîÝ[õ{<"Gµ`Áë&2ªBN§ 6¸ïo±±±—/_¶NFä(DŽwÂ'r”¹sç–x&ë3ŸË1«‘™™©^Mo¿™žžµ˜?¾°÷Šnó˜8iÒ$õ¢ U‚Ï‘sìØ±?ýéO·Ür‹º˜ásǸþ¨­þ[­Zµ—^z)//χMät:<8vìØÊ•+[ÎÁk师5kÖ¯¿þj¿Îž[9ª¡Ó®];÷eµhÑ¢°°ÐÛMä?üáîßõ¤I“\&#r"Ç;AŠuîé[}¾ùæ›ÀVÆÓ§Oˆˆðj-ºtéâÿr ëÕ«g3rTÞÔ©SçâÅ‹ÖB|‹œ#GŽ$&&ÚŸËBˆ;ï¼Óú(ä¿p!DRRRff¦Í:{nå(‡ªP¡‚58Õ¡õêÕ6—â¿ýû÷[—®v¼Š+fgg»LIä(á9åè¾s˜©üõ×_®.ðøã×®]Û«Y¾øâ ?ßG'¥üøã­¯ë.sz)åøñ㣣£ýY®aééé;w.í"„سgÏ´iÓÌÿõ0±¹6nÜøÇ?þ1¨+“J‚cÇŽõë×ïÒ¥K*¶qãÆ;w¶~¢Öú½÷Þ Ô"Ê4~üx— !}ôÑ`9D0”£Èq9§óÊ©S§ÔøÔwß}7??߃á˜UªT?~¼ýõC;w®? BÌŸ?ß«YªT©2jÔ(jÆéÓ§¨óågQž©­ôÆoØR¯6þçŸÞ§OŸüüüОTšµÝ»woïÞ½˜: °þ¯ZÍÿýßÿÕðN )ezzúúõë]>ŠŠšùäÛo¿‘‘árõBt¤µiòäÉöGK«ÉfÍšåóâ&NœèÕ~œ˜˜XTTä¾âÞFŽ~Bˆ‰'JßÚÊ•+ý/ç²ÿX‡ Š’xU¸a·ß~»ûNhe3r¤”+V¬p¯ÃáØ°aC0öjÅét®^½Z¸ ÁhÖ¬™zXƒ;"G!r¼¤È)..6ïRH%Åõ£l]~*THMM}衇^xá…/¾øâÌ™3ªý‰îܹӿ!ɬdçÎ}^ÜwÞéÕ~Ÿ[97~æ™g–/_¾sçÎóçÏËk»¨Yþ¹sçvïÞý?ÿó?ÇWâ}¨Æ UC§Äµ°ßÊ‘R~÷Ýw*Tp?Á Þе]»vEEE¹ìržCŽÈQˆï#rLcÇŽ ê=z>HIIyúé§?ýôSÏÝ ¥9sæL¥J•¼Zø° ó]se–¯&ëׯ_iEù9Âr—¥¢FÆ [´hѦM›vïÞ}üøñôôôo¿ývîܹýúõ«R¥ŠKöÛ_Šâïÿ{‰õߺu«ý¢\ZÀIIIï¾ûî•+Wìoù¼¼¼É“'W¨PÁlÙ_úsÏ=WZ±^EŽ”òÏþ³Ëft8¿ûÝï쯈WRSS]¾!Ä{ï½çáT‰ÈQˆï5r.\¸àÏSR‚Áü9ÅÅÅ;vóæÍ¥uU—f̘1^]¦r8Gõª•³{÷nóÐigu‡‡×˜ú9jî¹çž 6zX‘‚‚õF/ßR§´G6ôèÑër̘¼ÿþû½º[SQ+øÚk¯9¯nÆ2 #..®´qÞFNNNN¥J•\f‰ŠŠ ì CUU]F©©}/&&F½Ü½4DŽBäx'¨‘#¥û¬o—¬ï»ï>ë¶µ³¸F¹—3eÊo[K‡cúôé>ÔÙyg•ýµ¨_¿~‰[ÌÛVŽ”R½$к'¨ÿ.X° k§Œ3ÆeÕÔo¡Ì‰…ÈñN°#G0žËÉÉ‰ŽŽvœo¿ý¶Ìy‰%œ#§=}ÀE:u6lØ0aÂó“°ú†ÔÁQJ©|0{öliyÙ¥ûÄ-[¶LLL,ñ¯¥•¿aÃ;Sæåå}üñÇ6‹U%»Ü¯î?yíUf/¾ø¢Ï…tíÚ566Ö0 ‡ÃauÜíÛ·ÏۼƎëí5˜ !*T¨Ð·o_ÛÝU±k×.ÿ—®üõ¯UÇ5ë‡ÇŽ Ô ™V¯^}ùòe—3§æÍ›·k×. 宂ÚÊq&ô?þøüóÏÿæ7¿ «VŽõž å…^0ûôK\£µk×ÚΤ ŒŠŠ²Ók·hÑ"¯¶LíڵϞ=ë¹LZ9‡cäȑқœNçóÏ?ïUsÖ}'— ®ÃÛù1«Õ¬Y³yóæÂö56û¼*0°G)åèÑ£]Z9RÊŒŒŒ+Vø\æK/½tìØ1—Ï[¶lùä“Oú^W L!låØqúô鯾újΜ9ÇoÙ²¥ûýíÖ6Ëç.õv³(óæÍóP½O>ùĺt;Å–öÈáS§NEEEÙ,Ç0Œ&MšØÜ†>´r ¼þªJbË%í„¿ýíoíÌn~׿ÿýïRí`ð§•ãt:­÷ÚÄf3×]vv¶{óQ±ÿ~û…ÐÊQhåÜTbcc;uê”––¶dÉ’mÛ¶]¸páàÁƒüñ¤I“†ªNiÝû߬©ãymÄÚÆ=LÖ¥K—¸¸8aïȪ>îï#QæÍ›wåÊÃÞ µ¢W¯^eN曺uëÞrË-,ÐΕ(;;Û«&K||¼o sBˆ_|ѽ—òôéÓê”ÈN!ÖÉV­Z%¯o> !Ú´isÇw°Ú9"ÇwæÏ£qãÆ}ûö2eÊ;ï¼³k×®üüü={ö¼ýöÛiii=zôˆ‹‹3®?/¥§§{øIGGG?óÌ3†í£ªbݺuîŸ-]ºÔ«Šýáðjzûj×®ísHÖùóçmN©’ÉŸwц¹V­ZuíÚÕý{ùÇ?þ¡^cX&ë¯àwÞ1ÜvÚ€¶GÈ9¾³þ<Ì4)etttÓ¦M~øáW_}õ³Ï>;yòdVVÖ§Ÿ~:uêÔ:×zù}^îÉ“'wîÜéa‚'žxâÎ;ï´¿ëÖ­;~ü¸Ë‡6lP/œ¶©M›6Öç0Vdddxöx&„P=“7%)åk¯½V¹re—¯æÜ¹sê¥ öËY±b…z ‡õóZµj=òÈ#F¼DäøÎ¥áâáÃzõêõêÕëÙgŸýúë¯úé§.]º¸÷¼Ù!¯ =úúë¯=L=cÆ ûÅ^ºtéå—_6Ø*>?øàƒ2g´®Å’%Kû¼°åÕ·¦z&oJBˆÆ<ØýOóçÏ·¿‰òóóÏ{9IDATÓÒÒÌ}ÛìþÇ?þ¡Fë܈g(M¹8F>(éÜ*99yýúõ P/¾ýœŽ=êy‚®]»¶jÕªÌrÌu|çwÔ­†a!Š‹‹ÿùÏÚŸ½[·nå¤Ï=::ÚÎŽaNSâeꛆ”ràÀî$33³´ „.³†1þüÓ§O›ªßE³fÍÜÇaã&P^"Çð5uœNg`ë ª±páÂFùüä•'NxžQJ9þüÈÈHÏå˜?é‚‚‚©S§šÆ—-[vòäÉ2«¡fŽŽ~õÕWÕŒ7}H£FìLfnØÌÌÌ`V'Ä„;wnÓ¦ûŸÒÒÒìÄíž={¦M›f)eddä›o¾G!ÜTut8}úô}÷ÝçÛÑpàÀþ<×Ë…ùÓªQ£Æ /¼ðÈ#x5üÉTTTäùPѼyóîÝ»¯Y³F}RâRäµg— !fÏž–––˜˜xåÊ•—^zÉ(åynîÆg6qnúÓÒÄÄÄ={ö”9™¹a·mÛV\\Ú£§Ïi;"""–,Y’œœìp8œN§¹;effNž· löíôéÓç³Ï>3»ËJKãÚQiþüùÓ¦M[³fÍ/¿übs)ãÇ÷znXêÙ©†£&ÈÏÏÏÈÈhÑ¢EëpéÒ¥™3gÚœX}ï-[¶ìÞ½{ë`Õ¤I“!C†|ðÁf°©uë­·¦L™R⛜Ôþ–‘‘±uëVÕÖ7·gDDÄäÉ“ƒTU "з‚úp­^MÛm·ðõSVN§SÝÖàÃ&0`€ûó=Ýýúë¯êigÝ…UªT9qâ„:cµ9KiïÍôÌÛ[A[´háÓ6.ý…%í„j”„W•>|x x£ÊÙºu«¸ö@Ï‹V_bioëñçVPk}¤”ÙÙÙ±±±.ûŒ¢Ä·Ã™¢9r¤ûÎ9lØ0¶ŒÂ­  ·‚†XTTTƒ |›÷çŸÞ¶m[`룘/$öaÞøøx;‘3cÆ û}w?þøì×dذaö'¾ øðýåË—Ÿ={6 KWßøæÍ›ÕwZæ×jN’’ ”XÃ0êÕ«7gÎ÷¥/Z´Èýj¨ªüÙ³gß}÷]÷2Ÿzê©`Ta¢\DŽa>Œ§2O^ýõ@UÃzŒØ³g·§!æ)aÆ {_<ð@Ó¦Mí¤ŽZÙÕ«WKËÙ«çj$$$Ü{ï½^­Â®I“&U«VõvhûG}À:¬_¿Þóä^û÷iùlРA¬¬·ÞzË}b!Ä /¼péÒ%s-ÔÕºuëæÍ›»ª¡ò9)))>73W¬XqèС€TÃZu²_+k³æî»ï¶9oDDĤI“¼ZýúŒ;¶B…rq9Ðê·¿ý­·mÓ… jéÇŽó|W–»5jÔ«W/P(MDDD¿~ýÜw³)S¦¸ßœäEjF5n7±ò9}úôñ­ Ë0 !Ę1c.\¸ÀúìØ±Ã|:§ÍỶ+W®|Ï=÷ØŸkàÀ·ß~»-]JJÊ“O>éóV½qÝÿýÞβ{÷îG}TÔû³èììì^½zy5רQ£ô ™=z´õD¥È±cÇþú׿šJ)‹‹‹{ì1—’R<ØÛ—|ðáJݺu}>ÓB4mÚÔ«‡Úz““Ó¸qcáýƒ>UC§sçÎÞ.qöìÙf#Éÿ掺"½nÝ:Ÿ·À;|@J¹{÷nsKzÕHMMM5/àùàäÉ“III6‡u˜Ó!Ž;Vbþpát:ÇŒc\ÿ[UëoG]‹rhP¹reÿ_*Êð…áa¡]»vþ|û÷ïoÞ¼ùÔ©S/]º¤>‘Þßü(¥üòË/[µj•™™éÃìJÇŽ½š^JùÀ¨û|ó©‹ tëÖÍÿrnDÍš5KNN׆JÛÜ©¤”[·n:tèÕ«WÝÿTÚ,æ¿/]º4hР¬¬,ûõT‡õ^½z¹ˆƒD1iÒ$—ÇÊ©ƒ õæ¶>øÀ}•ûöí[«V-µ\©•³fÍß"G\/11ñ‰'žX¾|ù‘#GTÉæ Oëâ¬ÿ{éÒ¥íÛ·Ï;W½ÔÙŸjDFFzÛØRé'Mšä> Õ7Bˆ)S¦øó]ÜЭ)åÚµk£¢¢¼Ý˜jú[o½õé§ŸÞ»w¯‡JZ÷¨#GŽLš4)>>ÞúRZ; BDEEíÚµKá­ LŸ>ݽžBˆï¾ûNJ™­Æ_XGx«¿ú?”œVŽέœrtí·G))){÷îõ³œ¬¬¬yóæ©W®\¹yóæ5jРAll¬õ®·ÜÜÜììì'N9rdÇŽ/^4,1>=}ÇápŒ1ÂÛÑwjÏ›4iÒ’%KÔh]–îbøðá~–pCëÞ½ûèÑ£çÎkxÿmžß ¢veÃ0&Nœø›ßüFóI‘7ŠaÆ=ýôÓ~"ÝRPX&¸ÿÕ!DŸ>},Xª7%%%¥¥¥¹îò¶P!Dbbâ+¯¼¢«^½rt-Ç|Û¶m‹-2?ñí‡TÂò6!ÄСCGŽé±-[¶lÒ¤ÉÁƒ¥—W•TM*Uª4jÔ(ÿ«qsRΘ1#''G½DÙüЫ¨°~Ñæ¼Òò¬UŠjÞ¼ùûï¿ÂÇW !ÆÿÆoäçç[OMÜÏTž}öÙðyqê?üð·¿ý-$‹nܸñƒ>’E#ˆ×rL¿þúk›6mÄõÃfŠuxÒØ±cøhÑÉ“'›½dö[*jÊßÿþ÷©ÃÍѱ¦º‹ŠŠFmݤ¡Ú¯Ô¢“’’Ô¿2{>ƒ×±¦<û쳞»k×®}ùòå.ÑÏŽµêÙ³g·káEJY¥J•¯¾úê­·ÞªW¯^¦Žyº·téÒyóæ°’#FŒ°ùjK÷Zýñ T5nêkŠˆˆX°`Ák¯½mý<$UjÛ¶íÆkÖ¬’¥›ÔêOž<¹~ýú|#FŒ¨X±¢Æz!ôÂîh«:튊Š6lØŽ;zöìê¹’RFFF¦¥¥eff>úè£-¼AƒãÆóaÆÛn»­OŸ>­ÌÎ<žŽ7nß¾}êöØäMåÊ•/^üí·ßÞ~ûíf¬þj(jÑ111=ö˜,ý²ßO<¡·^½ò9VqqqkÖ¬Ùºuë]wÝ¥:FT{ÂÚ!¤Ÿ®{WŒùïîÝ»gff¾úê«111ÁXô„ \n)³’†aüå/ á·Ô¨Ü2¿SF‹%&&®]»væÌ™êÌÝå;õ¡ÀkeÖÍ\u~ݺuúÓŸ|(ÍŒ¤0`€KÉæf9rdP6jç+öÀ¡ÿµoÜ(nø#H@´jÕjÛ¶m_~ùå‹/¾Ø©S§J•*×?'*à„åÍ’æÛ´i3}úôíÛ·þù牉‰ÁX®ZPaa¡ýk¶ªzÍ›7ÔíŸN{ˬF@–n³(RÊ &dee-\¸P= /€ûË)¥¬X±âÀׯ_äÈ^äãR¸uŸ ”F©§®Y©‹ S§N à‚Jäù )¬Žò¡ê‰Õ¯Xó,22²cÇŽ:u2 ãÌ™3ŸþùÆ7lØ››Œ½AZF£uïÞýèÑ£‡z¯¢ÌýO-wêÔ©çγó“3¯*ÍŸ??222 ÇP!D­ZµFm5u€°?âNQ½zuõòVûåK)k×®=räÈ#Fdgg¯X±bÆ _}õ•ý¨+³VÑÑÑ}úôyàºuëf^@òÁƒ>xþüykÉñññþ×ÐJ1sæL—·´ !þD5µg:477×\Š”2>>¾Ä¶bÅŠjt:á=Íš5 u4 ý¶v§ö•úõë{õÃ`¸råÊÞ½{·mÛ¶cÇŽ½{÷îÛ·¯  @^?¤UM)¯96ç5/ÖiÔ¿o»í¶Ö­[·jÕªU«V)))Aê=+Mnnnݺu¯^½jç¨Úºuëï¿ÿ^CÝnV'NœøôÓO·lÙ²yóæ£Gª­{‘´Œ‡–aÓ†e·iß¾}Ë–-;tèpï½÷V©R%D«‚@BBBvvv‡±x@äØbòóóÏ;wêÔ©‹/æäääçç«cwnn®Ë,¥Œ‰‰QÝúÕ«W­^½z\\\\\\DD„õø¢yE^}õÕ &Øœ^±}ûvÞÕèk–äääüüóÏ999yyyN§3//Ïú5‡ÃQ½zu‡ÃQ­Zµ5jÔ©S§nݺµjÕRñ§äsDŽwÂ0r\xõË«ÃÄÅ‹7n|âÄ ›Ó;Žûî»oãÆA­U¹âmOà­pŽv}_x!á“7†aLœ8ñ—_~±?½”²_¿~Á«O9DÞ ftæÌ™Þ>ì rð_j|Aß¾}Ÿ~úéP×À͉k7÷§\+.Àvy¨¨ú°Aƒo¾ù¦ö*(/håÜ$\Þ-èòVë'Ö7Kš³·hÑbΜ9qqqú*  œ¡•sSqiܘOð0e—.]ÆŽÛ»wï`¿ˆœ›Ä°aÃÚ¶m[PP ^Áb>.://ïüùóæ«kÔ¨Q­Zµøøø:uꤦ¦vèÐÁú²/ò@P97‰¡C‡ú_¶T\ËhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9MˆÀ¶ÿÖµÁ÷”hèIEND®B`‚e [D@ñÿDStandardOJQJ_HmHnHsH tH ujòj Überschrift 1$ & F¤ð¤ @& Æ75B*CJ OJQJmH sH uRòR Überschrift 2!$ & F¤ ¤@& Æ7@CJF!òF Überschrift 3 & F@& Æ@ÐCJZ1òZ Überschrift 4. & F ÆÐ`„Є0ý¤ð¤P@&^„Ð`„0ýFF Überschrift 5¤<¤@& Æð5:: Überschrift 6 @& Æ€:: Überschrift 7 @& Æ:: Überschrift 8 @& Æ : : Überschrift 9 @& Æ0BA@òÿ¡B Absatz-StandardschriftartFþòF Body¤x¤x Æ&B*CJOJQJmH sH u:þ: 11 BodyText„¤Ü^„CJ> >Fußzeile$d Æ9r OJQJ<@"< Kopfzeile Æ  ø%OJQJ6þ26 22 BodyText„% ¤Ü^„% 6Q6 Verzeichnis 1OJQJVþRV Heading 1TOC! Æâ‘ „â„ý¤x^„â`„ý 5B*CJ¢þb¢ Bulleted - 1t & Fÿ„w„›þ¤Ü>ÆTÿe-ð^„w`„›þCJ¤þr¤Numbered List 1t & Fÿ„w„›þ¤Ü>ÆT€e.^„w`„›þ>þq‚>Numbered List 2 „Š ^„Š CJ,’, Fußnotentextžþ¢ž Bulleted - 2t & Fÿ„Š „›þ¤Ü>ÆTÿe-ð^„Š `„›þFÁF Verzeichnis 2„‰„Xý^„‰`„XýOJQJTþÂT Heading 2TOC! Æ‹‘ „‹„Wý¤(^„‹`„WýB*CJ>á> Verzeichnis 3„Ý„­ü^„Ý`„­üTþâT Heading 3TOC! ÆÜ‘ „Ü„¯ü¤P^„Ü`„¯üB*CJ<þò<Document Title¤€5CJ$LL Verzeichnis 4 Æ ‘ ‰‡ „  „<ü^„  `„<üPþP Heading 4TOC! Æ¢ ‘ „¢ „:ü^„¢ `„:üB*CJBB Verzeichnis 5 "„ ^„  CJOJQJBB Verzeichnis 6 #„è^„è CJOJQJBB Verzeichnis 7 $„°^„° CJOJQJBB Verzeichnis 8 %„x^„x CJOJQJBB Verzeichnis 9 &„@^„@ CJOJQJ@Yr@Dokumentstruktur'-D OJQJBþ‚B CellBody (¤P¤PB*OJQJmH sH uLþ’L CellHeading )¤x¤x5B*OJQJmH sH uNþòN Heading 02 *$¤h5B*CJOJQJmH sH uLþ²L Nonum Heading +1$¤x¤d5CJ$htH u(U@¢Á( Hyperlink>*B*>V@¢Ñ> GesichteterHyperlink>*B* HþâH Abstract .d,¤ðB*CJOJQJmH sH u´þò´ Bulleted/ & Fÿ Æh„„åþ¤x>ÆTÿ·ð·······^„`„åþB*CJmH sH uJþJ BulletedCont0„¤P^„B*CJmH sH uJþJEquation1d¤È¤x Æ‘  B*OJ QJ :þ": Figure 2¤x¤6B*mH sH uNþ2N Footnote3 Æä„ä„ÿ¤<^„ä`„ÿB*mH sH uZþòZ Heading 014$$¤ð¤@&d5B*CJ OJQJmH sH uN#NAbbildungsverzeichnis5„„pþ^„`„pþJþbJ Numbered6 & F>¤x ÆB*CJmH sH u¨þr¨ Reference|7 & Fÿ Æ7„„åþ¤x>ÆT€[]^„`„åþB*CJJþ‚J SubTitle8$$d@a$5B*CJmH sH uFþòF TableTitle9¤x ÆT6B*mH sH u$X@òÿ¡$ Emphasis66þOòÿ±6 EquationVariables66þOòÿÁ6 ProgramCodeCJOJQJkH'&þOòÿÑ& SubscriptH**þOòÿá* SuperscriptH*,þOòÿñ, SymbolCJOJQJkH*6þOòÿ6 Underline>*CJOJQJkH'8"8 Beschriftung A¤x¤x6$)@¢!$ Seitenzahl:þñ2: DocumentOwnersC$a$CJ8ZB8 Nur TextDOJQJmH sH u\þb\ Definition List E„h1$^„hCJOJQJhmH sH tH uXþRX Definition Term F1$¤d¤dOJQJhmH sH tH u@þñr@ Editors NotesG6B*CJOJQJ:þñ‚: Code SnipetH¤x CJOJQJVþV H1I$ & F1$¤ð¤d@&%5CJ(KH$OJQJhmH sH tH uRþR H2J$ & F1$¤d¤d@&!5CJ$OJQJhmH sH tH u(þOòÿ±( Definition6LþL H3L$1$¤d¤d@&!5CJOJQJhmH sH tH uLþL H4M$1$¤d¤d@&!5CJOJQJhmH sH tH uHþH H5N$1$¤d¤d@&5OJQJhmH sH tH uLþL H6O$1$¤d¤d@&!5CJOJQJhmH sH tH uHþH AddressP1$!6CJOJQJhmH sH tH ubþb BlockquoteQ„h„h¤d¤d1$]„h^„hCJOJQJhmH sH tH uþOòÿ! CITE6$þOòÿ1$ CODE CJOJQJ0þOòÿA0 Keyboard5CJOJQJpþRp Preformatted+U1$ Æ# ¿~= ü»z9ø·!v%OJQJhmH sH tH ufþñÿfz-Bottom of FormV$$d1$a$"<CJOJQJ_HhmH sH tH `þñÿ` z-Top of FormW$&d1$a$"<CJOJQJ_HhmH sH tH $þOòÿ$ SampleOJQJ0þOòÿ‘0 Typewriter CJOJQJ$þOòÿ¡$ Variable6,þOòÿ±, HTML Markup<B*"þOòÿÁ" Comment<TþâT Title1]$¤ð¤d1$a$!5CJ0OJQJhmH sH tH uZþâZ Subtitle1^$¤x¤d1$a$!5CJOJQJhmH sH tH uHþòH RFC-P1_„°¤ð^„°CJOJQJmH sH tH uRþR Param$` & F¦„e„›þ¤P¤(1$^„e`„›þhmH sH tH uLþL CODECompacta1$CJOJQJhmH sH tH u,þ1, Title Textb5.þ2. 00 BodyTextc¤Ü,þB,Bullet 1 d & FÛÿÿÿÿÿÿÿÿ ÿÿÛ<ÿÿÿÿee1–beËÛ † µ†pÛ Û &WbWˆ“e4ÿ•€4ÿ•€ð@ð  @ñÿÿÿ€€€÷ð ððxð( ð ð𜢠ð c ðR€Š¿ÿƒÃ.¿ ``T`T`T`Tðð ð"ñ¿€𜢠ð c ðR€Š¿ÿƒÃ.¿ ``T`T`T`Tðð ð"ñ¿€ð’ðð0ð( ð ððB ðS ð¿Ëÿ ?ð1e¸ÿÿÿòÿÿÿSýµ@¸ÿÿÿòÿÿÿSýµ@"19OY_`klopÒÓÜ÷ø‘opÒÓÙÜÿÿ Lothar Merk`E:\SyncMLDelv\syncml_tk_Maintenance1.2_PalmLinuxWin_20010423\syncml\doc\ReadmeMaintenance1.2.doc Lothar Merk`E:\SyncMLDelv\syncml_tk_Maintenance1.2_PalmLinuxWin_20010423\syncml\doc\ReadmeMaintenance1_2.docMerk]C:\Data\SyncMLDelv\syncml_tk_Maint2_PalmLinuxWin_20010611\syncml\doc\ReadmeMaintenance1_2.docMerk[C:\Data\SyncMLDelv\syncml_tk_Maint2_PalmLinuxWin_20010611\syncml\doc\ReadmeMaintenance2.docMerk[C:\Data\SyncMLDelv\syncml_tk_Maint2_PalmLinuxWin_20010611\syncml\doc\ReadmeMaintenance2.docMerk[C:\Data\SyncMLDelv\syncml_tk_Maint3_PalmLinuxWin_20010917\syncml\doc\ReadmeMaintenance3.docMerk[C:\Data\SyncMLDelv\syncml_tk_Maint3_PalmLinuxWin_20010917\syncml\doc\ReadmeMaintenance3.doc Thomas Klein@C:\Documents and Settings\thklein\Desktop\ReadmeMaintenance3.docIBM-User%D:\syncML\Doku\ReadmeMaintenance4.docIBM-User'D:\syncML\Doku\ReadmeMaintenance4_1.docüûÿÿÿÎÜÖ-ÿÿÿÿÿþÿÿÿÿÿÿÿÿÔhXíz@ÿºo:éÈuÿzS0à–ÀÿXlhdmÿÿÿÿÿÿÿÿÿ'5ÄáÚÞÿÿÿÿÿÿÿÿÿ¢M‹ ÿ1Í ÿB-6ïr-ÿµÚj?fÿ4 tj?fÿ$Ù ÿö[' ÿ†ld0à–Àÿ„m"0à–Àÿvj?fÿßhš6ïr-ÿÿÿÿÿÿÿÿÿZk¤V"ÙÿßQ±š…6$ÿt-j?fÿñI% ÿÿÿÿÿÿÿÿÿGB j?fÿ…'”  ÿ¹¨ ÞaÊ–ÿ›}þ šŠƒÿ»@I 0à–Àÿ$0< 0à–Àÿo j?fÿŒ@  ÿ ¾  ÿà:.j?fÿO{Qj?fÿÿÿÿÿÿÿÿÿ¯F‰0à–ÀÿÀdÚ ÿVVU ÿ@I P´ eÿ`ç ò\ÿºY ÿ:ksP´ eÿêN†ÿzh ~`V÷ÿÿÿÿÿÿÿÿÿ¿Al0à–ÀÿtQcÿRùV"ÙÿTrròz ­ÿ?ÎfØFÿÿÿÿÿÿÿÿÿ ˆ ÿü=êj?fÿ‘,WXÊÿOuðj?fÿ3v䆸ŸÿÿÿÿÿÿÿÿÿîXjj?fÿ­IXÊÿ™öÄáÚÞÿÊ• ÿÁi³ ÿOË0à–Àÿ’ý$h"—ÿÿÿÿÿÿÿÿÿ _Ej?fÿàN˜éÈuÿÿÿÿÿÿÿÿÿK» ÿ®T0à–Àÿ/9[0à–ÀÿC_‡ ÿ‰bÞj?fÿL{0à–Àÿ·PÔj?fÿKL8 6ïr-ÿÑÆ j?fÿxcÈ 0à–ÀÿÙï šŠƒÿ±T!0à–Àÿœ¦!šŠƒÿaU¶" ÿêv·"$h"—ÿÿÿÿÿÿÿÿÿ•mØ" ÿ+K#j?fÿ½m$¶k@rÿIÿÿÿÿÿÿÿ_P‰$0à–Àÿ FÜ$اÔÿÿÿÿÿÿÿÿÿ‚l%0à–Àÿ©>@% ÿJVX%x,µÿ n&j?fÿL«' ÿ¾E¤)4-¢ ÿï)0à–Àÿ{k* ÿ r*j?fÿÿÿÿÿÿÿÿÿPCs*j?fÿÓH +ÿ7 ..žŒ6•"o.ÄáÚÞÿPi‘0øˆ-`d<ç0 ÿb;¡1ÄáÚÞÿ^G¨1V"Ùÿþ1Ã10à–Àÿßê10à–ÀÿÙ$2j?fÿd*Ž20à–Àÿ@Ÿ2ÄáÚÞÿrA°2䆸Ÿÿ2.3 ÿ¤FP3P´ eÿ$F50à–ÀÿÙ*7ÄáÚÞÿ”2§7j?fÿÿÿÿÿÿÿÿÿéMA8éÈuÿp(þ8 ÿ@ Ö9täŽýÿ¥}: ÿïcš:ì=.ÿÈFÅ:0à–Àÿ­ ;V"Ùÿ‘q};FîNÿ§-­;j?fÿ‰‰j?fÿŽ3™>éÈuÿÿÿÿÿÿÿÿÿçA7@j?fÿ®?l@j?fÿÊÅ@ E^xÿÿÿÿÿÿÿÿÿZæA ÿãUóAj?fÿ÷ùB0à–ÀÿuqCj?fÿF_C$h"—ÿÏC ÿã)DP´ eÿdKEj?fÿ.E ÿGuXE0à–Àÿ5t€Ej?fÿ{‡E0à–Àÿâ—EÄáÚÞÿÿÿÿÿÿÿÿÿp«EÄáÚÞÿÿÿÿÿÿÿÿÿŽx¸E ÿäE0à–Àÿ:¤F ÿ· ¦FV"ÙÿqJ«F4-¢ ÿtMG0à–Àÿt?Gj?fÿÛqBGj?fÿf»G ÿ–)Hj?fÿTVHØ"Žgÿÿÿÿÿÿÿÿÿ 6pH4-¢ ÿB›HÀDâŒÿÿÿÿÿÿÿÿÿGÁHÿ.PbJ ÿÐ{­KÄáÚÞÿÿÿÿÿÿÿÿÿIN™LÄáÚÞÿÿÿÿÿÿÿÿÿb-³Lÿðk‘Mj?fÿs#ºM ÿ#tÑN0à–Àÿ„$‡OXÊÿ>PšŠƒÿƒt¡PV"Ùÿ§!FQj?fÿ¡0ËQéÈuÿÃLôQ ÿÓT ÿ´g^Tj?fÿ`•Tt(øxÿ^F»TP´ eÿh ØU ÿc{V ÿx-^V0à–ÀÿõeWTñ–ÿr»WšŠƒÿv\YŠ Iÿs˜Y ÿj:šYéÈuÿÿÿÿÿÿÿÿÿÛp¦Y ÿúSC[j?fÿŒ&H[ ÿÕ=j[šŠƒÿ¹Hˆ[ÄáÚÞÿÿÿÿÿÿÿÿÿ}¤[ÄáÚÞÿ+%?\Xíz@d9+]$h"—ÿÿÿÿÿÿÿÿÿT"í] ÿí57^ÄáÚÞÿ·U•^0à–Àÿ0K_0à–Àÿ~`j?fÿ`Gû`؉¨Àÿÿÿÿÿÿÿÿÿ"AaìzÐeÿ_[`bP´ eÿ~c¬é„mÿÿÿÿÿÿÿÿÿ+ ‘cˆnªÚÿÿÿÿÿÿÿÿÿ`&d0à–ÀÿÜh‡d0à–ÀÿVDŠdj?fÿÇm½dØybzÿ³5ÿe0à–ÀÿaJƒgÄáÚÞÿÿÿÿÿÿÿÿÿo 5h0à–ÀÿÎ#Öh ÿÓøiÿVRekÄáÚÞÿÿÿÿÿÿÿÿÿøt5lÄáÚÞÿÿÿÿÿÿÿÿÿv2ÐlÄáÚÞÿÿÿÿÿÿÿÿÿmÄáÚÞÿÿÿÿÿÿÿÿÿ [ynÄáÚÞÿ=xòn ÿ?4®oÿ³oÿ8>Rp ÿ$rÄáÚÞÿŽyLsj?fÿlt6ïr-ÿÿÿÿÿÿÿÿÿ×8¥tüÆ®|ÿÿÿÿÿÿÿÿÿHqªtÿ8+•uP´ eÿà[–uÿ“*©u$h"—ÿÿÿÿÿÿÿÿÿgYÂu ÿÇa)vP´ eÿÇ|$w¾ú ÿA3wj?fÿ,®w0à–Àÿ×:ExÄáÚÞÿÿÿÿÿÿÿÿÿ<=Ûx ÿºgßx6ïr-ÿÿÿÿÿÿÿÿÿö yÿÚd/yj?fÿpioyj?fÿCooyj?fÿÍ|zz´:B7ÿÿÿÿÿÿÿÿÿ†{ ÿ›t´{ÿÿÿÿÿÿÿÿÿÿÿÿÿ 4Ð{6<½ÿSï{j?fÿÝI'|$h"—ÿÿÿÿÿÿÿÿÿ^Š|j?fÿH)õ| ÿ’A}0à–Àÿ+2}ÄáÚÞÿÿÿÿÿÿÿÿÿ`}ÄáÚÞÿhMÆ~j?fÿ%8î~0à–Àÿl^0à–ÀÿÚP›}þ KL8 r»WÙï †ld»@I GuXE$F5ï)$0< ,®w³5ÿe¯F‰zSéMA8ºo:¿Al±T!x-^V%8î~d*Ž2’A}„m"#tÑN‘q};äE‚l%l^þ1Ã1Üh‡dtMGßê1xcÈ ®T_P‰$7 .0K_ÈFÅ:OËo 5h·U•^{‡E`&d÷ùBL{/9[TrrúSC[~`–)H _E§!FQdKE§-­;´g^TîXjÑÆ Cooy‰bÞ8 ÙvPCs*Úd/y5t€E®?l@pioyhMÆ~ŽyLs^Š|‰‰<Sï{ÚOuð n&4 tü=ê·PÔÇm½d¢M‹Óøi¹¨ à[–uHqªt?4®oÓH +ö y³o…'” ÃLôQþÿÿÿ˜ú¢þÿÿÿìú¢þÿÿÿPû¢Ž3™>aJƒgêv·"9+]VRek“*©u’ý'5ÝI'|+2}¹Hˆ[O{Qv2ÐlÐ{­K×:Exøt5l r*â—Ep«EmIN™L”2§7ºgßxßhšltj:šYàN˜Ûp¦Ys#ºM$Ùp(þ8+K#H)õ|Ç|$wþÿÿÿ´û¢ ˆ¥}:™öh ØU†{gYÂu ¾ Ù*7$rPi‘0í57^ºY`} [yn@Ÿ2þÿÿÿü¢•"o.b;¡1}¤[<=Ûx`Gû`B-`ç•mØ"Žx¸EçA7@GB {k*t?Gc{VÎ#ÖhÏCA3wÁi³8+•uVVUVDŠdo Ù$2K»µÚÊ•"AauqCðk‘MÛqBGT"í]L«'8>Rp.PbJF_Cþÿÿÿ|ü¢©>@%ZæAs˜YaU¶"7 .äü¢Œ@ ö['ÀdÚ_[`bðü¢.E‹6¢TuF=`•TJVX%JVX%üü¢v\Yïcš: 4Ð{@I ­I„$‡O‘,W@ Ö9RùqJ«F¾E¤) 6pHRùý¢­ ;Zk¤^G¨1ƒt¡PÚGè· ¦FÇa)v¤FP3^F»Tã)D:ks"Aaý¢t-ÓTõeWõeW ý¢ßQ±ßQ±,ý¢d<ç0b-³LtQcêN†GÁH2.3+ ‘c+%?\3vrA°2Ôhþÿÿÿþÿÿÿ8ý¢ÿþ×8¥tÿÿÿÿÿÿÿÿtù¢` ˆ@e „w„›þ^„w`„›þOJQJo(-ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿØù¢`m@h „Є˜þ^„Ð`„˜þOJQJo(·ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ<ú¢`l@„„åþ^„`„åþCJOJQJo(·ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¤ú¢ Ê@CJ$OJ QJ o(" ÿÿÿÿøú¢ @e „Š „›þ^„Š `„›þOJ QJ o(·ðÿÿÿÿ\û¢`c@e „Š „›þ^„Š `„›þOJ QJ o(-ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀû¢ @e „w„›þ^„w`„›þOJ QJ o(·ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ$ü¢ @e „w„›þ^„w`„›þOJQJo(-ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿˆü¢ s@„„åþ^„`„åþCJOJQJo(·ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ@ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿDý¢ @h„„^„`„OJQJ^Jo(·ðÿÿÿÿÿÿü    ÿ@€oot‚EoUÛ@@ G‡z€ÿTimes New Roman5€Symbol3& ‡z€ÿArial?Courier Neu?5 ‡z€ÿCourier New71Courier="HelvArial;" Helvetica5& ‡z€ÿTahoma3Times;€Wingdings]& Rotis Sans Serif for Nokia"CˆVüe ;H&9Dd&9üG&5ÒÌ ƒ.$Vü¥À´´€0dÄiœ5ÎUÿÿReference Toolkit Specification Hezel, UweIBM-Userþÿà…ŸòùOh«‘+'³Ù0xˆ¸ÄØäø  4 @ LX`hpä Reference Toolkit Specificationefe Hezel, Uweoeze Normal.doto IBM-Userto26-Microsoft Word 8.0p@†8”ÿú¿@nWÀ@†®¢ ßÁÒÌþÿÕÍÕœ.“—+,ù®DÕÍÕœ.“—+,ù®L hp|„Œ” œ¤¬´ ¼ èäIBM. Ä1  Reference Toolkit Specification TitelÀ(T\h_PID_LINKBASE _PID_GUIDäAAN{45F1021A-D569-4C19-9741-64A99523C1DB} þÿÿÿ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQþÿÿÿSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«þÿÿÿ­®¯°±²³þÿÿÿµ¶·¸¹º»þÿÿÿýÿÿÿýÿÿÿ¿þÿÿÿþÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿRoot Entryÿÿÿÿÿÿÿÿ ÀF »Ÿ ßÁàn$´ ßÁÁ€Data ÿÿÿÿÿÿÿÿÿÿÿÿàd1TableÿÿÿÿÿÿÿÿR"²WordDocumentÿÿÿÿ8<SummaryInformation(ÿÿÿÿÿÿÿÿÿÿÿÿ¬DocumentSummaryInformation8ÿÿÿÿÿÿÿÿ´CompObjÿÿÿÿjObjectPoolÿÿÿÿÿÿÿÿÿÿÿÿàn$´ ßÁàn$´ ßÁþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿ ÿÿÿÿ ÀFMicrosoft Word-Dokument MSWordDocWord.Document.8ô9²qlibsynthesis-3.4.0.47.1/src/syncml_tk/doc/ReadmeMaintenance4_2.doc000066400000000000000000003210001226375725500245330ustar00rootroot00000000000000ÐÏࡱá>þÿ ÌÎþÿÿÿÊËÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿì¥ÁE@ ø¿Ø!bjbjƒæƒæ 86áŒáŒ{UÿÿÿÿÿÿˆBBBB¶¶¶Ê===8J=f=4ÊÒÊì¦=¦=(Î=Î=Î=Š@Š@Š@QÊSÊSÊSÊSÊSÊSÊ$¾ÍRИwʶBAJ@J@@BABAwÊBBÎ=Î=|ŒÊBBBBAFBÎ=BRÎ=QÊBBAQÊBÀBÒB’®ÊB”"ÙÉ$Î=š= P„óƒ­‘Ã=ˆA(ÝÅþ%Ê,¢Ê0ÒÊÛÇþ¨Ð°A.¨ÐüýÉÊÊBBBB¨Ð¶ýÉ(Š@ž@B¬@ ¸@ŠŠ@Š@Š@wÊwÊÊÊd./ä ÞA4ÊÊ./SyncML Reference Toolkit Specification Release 4.2 October 13, 2003 READ ME Copyright Notice Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). All Rights Reserved. Implementation of all or part of any Specification may require licenses under third party intellectual property rights, including without limitation, patent rights (such a third party may or may not be a Supporter). The Sponsors of the Specification are not responsible and shall not be held responsible in any manner for identifying or failing to identify any or all such third party intellectual property rights. THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. The above notice and this paragraph must be included on all copies of this document that are made. File and Directory Structure The SyncML Reference Toolkit file tree is structured as shown in the following figure. Within syncml/src/sml the files of the toolkit itself are found. The transport handlers are stored in the directory syncml/src/xpt. Demos showing syncml at work will be organized within syncml/src/app. syncml ------ docs ----- internal ! !---- bin ------ win Binary files (like dlls) ! !---- src ------ sml ------ inc ------ win Public Headers ! ! ! ! ! !--- palm ! ! ! ! ! !--- mgr ------ inc SyncML Core (Manager) ! ! ! ! ! !--- all ! ! ! ! ! !--- win ! ! ! !--- wsm ------ inc SyncML Workspace ! ! ! ! !--- all ! ! !--- palm ! ! !--- win ! ! !--- linux ! ! !--- epoc ! ! ! !--- xlt ------ inc SyncML En-/Decoder ! ! ! ! ! !--- all ! ! ! ! ! !--- lib ------ inc SyncML Library Funct. ! ! ! !--- all ! !--- palm ! !--- win ! !--- linux ! !--- epoc ! !--- xpt -- !--- bindings Transport Handlers ! !--- manager Supported Platforms The SyncML Reference Toolkit has been implemented to be portable to as many hardware platforms and operating systems as possible. Nevertheless it is not possible to achieve an full platform independent code. The SyncML consortium therefore focusses on the following platforms: Windows 32 The deliverables target Windows 95 and NT 4.0 and comprise: Source Files. Several subdirectories named ../win hold files specific to the Windows target (e.g. syncml/src/sml/wsm/win). When compiling all these Windows-directories must be included. All other directories, which hold files specific to other targets must be excluded (e.g. ../palm; ../epoc)! The source code was developed using the following development environments : Microsoft Visual Studio C++ IBM Visual C++ GCC Palm-OS The deliverables target Palm OS 3.5 to OS 5.0 and comprise: Source Files. Several subdirectories named ../palm hold files specific to the Palm target (e.g. syncml/src/sml/wsm/palm). When compiling all these Palm-directories must be included. All other directories, which hold files specific to other targets must be excluded (e.g. ../win; ../epoc)! The source code was developed using the following development environments : Metrowerks GCC The Toolkit for Palm runs on Palm OS 3.1 too. Due to limitations of that version of the operating system, the size of the workspace is restricted to maximim 50kBytes. Not really recommended these days. LINUX To compile and run SyncML under a Linux Platform, the Win32 source code is used. Please follow the instructions in the README.linux file in the “src/bld” directory. Changes in the Maintenance 4.2 Release OBEX bugs fixed. Added MacOSX support. Added SSL support for PalmOS 5.0 (alpha) and PocketPC 2002. Updates for Linux. Memory change to allow you to not use the toolkit memory structure. Added support for SyncML 1.1.1. New API function smlStartMessageExt() with parameter to specify SyncML version.  SyncML Reference Toolkit Read Me  SAVEDATE \@ "yyyy-MM-dd" \* MERGEFORMAT 2001-09-18 Copyright © Ericsson, IBM, Lotus, Matsushita Communication Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). All Rights Reserved.  SyncML Reference Toolkit Read Me  SAVEDATE \@ "yyyy-MM-dd" \* MERGEFORMAT 2001-09-18 Copyright © Ericsson, IBM, Lotus, Matsushita Communication Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). All Rights Reserved.   'DEM]@AC`¾Ì+9q€‚•£Ìå&`(<=ScêüÔèøñâøÒÇ¿µÒ©©‘©©ƒµtµgµgµg\µgµgµghu#N6CJOJQJhu#N56CJOJQJhu#N<CJOJQJhu#Nhu#NB*CJOJQJphhu#NB*OJQJphhu#NB*OJQJphhu#NB*OJQJphhu#NCJOJQJhu#NOJQJhu#NCJOJQJhhu#N5B*CJOJQJphh“iè5CJ$mH nH sH u h“iè5CJ$ hu#N5CJ$!'EM^œÜ - m § è + i ¨ Ò Ó  Y ˜ Ù  [ ß % g òòòçåååååååååååååååååååååå $¤h1$7$8$H$ $¤€1$7$8$H$a${Ð!×!ýýýg ¤ å +m±ÜÝ!AC`‚¤®çñ{°Ñò>ýýýýýýýýýõÞÎõÃÃÃÃÃÃÃÃà d@ÿ1$7$8$H$ Æ&¤x¤x1$7$8$H$$ Æ@„°„Pþ¤ 1$7$8$H$^„°`„Pþ1$7$8$H$>jÉüdÃ÷*_“´ý)\}žêI}°å9ƒ¥ôôôôôôôôôôôôôôôôôôôôôôôôôôôô d@ÿ1$7$8$H$èéoÔêÿ  FRrx©¿Zj»éêñò.:Za¦>Mž¬Txy~#$%'CEOPöìßìÏ˽­Ë¨Ë Ë Ë Ë¨Ë½­ËœË¨Ë Ë Ë Ë¨Ë˜Ë½­Ë‘ÏËÏÏuhu#NB*OJQJphh“iè5B*CJOJQJph h“ièhu#Nh§%h‰MGhu#NOJQJ hu#N5hu#N5B*CJOJQJphhu#N5B*OJQJphhu#Nhu#N5B*CJOJQJphhu#N56CJOJQJhu#NCJOJQJhu#NCJOJQJ.¥ÒÓÔÕêÿ Fmn»×æêò.PQžôôôÝÝÕ¾Õ§ÕÕ§§§¾Õ§ÕÕ & F  Æh„h„˜þ1$7$8$H$^„h`„˜þ$ ÆÐ„°„Pþ¤ 1$7$8$H$^„°`„Pþ1$7$8$H$$ Æ@„°„Pþ¤ 1$7$8$H$^„°`„Pþ d@ÿ1$7$8$H$ž©­®y$&'OPaw³Æ èèààɾ²à£˜ŠŠŠŠŠ & F dð1$7$8$H$ dð1$7$8$H$$ Æ@¤ 1$7$8$H$ Æh1$7$8$H$ 1$7$8$H$gd“iè$ ÆÐ„°„Pþ¤ 1$7$8$H$^„°`„Pþ1$7$8$H$ & F  Æh„h„˜þ1$7$8$H$^„h`„˜þP`að  +y{|¡¢ËÌÖ×å £ ¤ ¥ ¦ Ë Ì õ ö !!!¹!Ð!Ñ!Ó!Ô!×!Ø!óçóÛóÛÌÛÄÀÄÀÄÀÄÀ±¬À¦ÀÄÀÄÀÄÀÄÀ±ÀœÀ’ÀÛjp2hu#NCJUjhu#NCJU hu#NCJ hu#Nhhu#NhmH nHsH tHuhu#Njhu#NUh‰MGh‰MGB*OJQJphh‰MGB*OJQJphhu#NB*OJQJphh“ièB*OJQJph$ {–ŸØÙ ¤ ¥ À É !!I!Î!Ï!Ð!Ò!Ó!Õ!Ö!×!Ø!îêêêèããèêêêèããèèèèèèèî$a$¤  & F dð1$7$8$H$gd‰MG6 00P P &P °‚. °ÆA!°8"°8#p$R%°°Þ°2p2Dd&& `+`+ffð<² ð C ðA¿ÿðÂbðà1„oœÅr<,;ÖFQ[‡¬bÿ¼1Dcnð´1„oœÅr<,;ÖFQ[‡¬bÿ‰PNG  IHDR&&è¬ÖgAMA±ˆ•˜ô¦ pHYs ø øf&<ý IDATxœíÝytU¢Çñºˆö"$ÄƃèÂ.Žì0 ‹¨Œ ›(F‘a—qæ Ûˆ ‚ìˆG}"¢(úØQGD-ÀŒ$  D ô}Ü¡^Ñtª·Û ù~þð`§êÖ­êêúÕ½u«Ê0Üà„¡®ܨÂöZ!Ô(¹±Âv«@Ø’R†!„Pÿ+á9Jxn/sá|²¾‘ãp8âããC] ¸ÁüòË/N§3Ôµ(Y˜FŽ”2>>>+++Ô€LBBBvvvx¶u¡® ¼ rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBäØ"¥tùG™S\9¶!\þ¡¸Œ9Ù.*„º7)¥âÂ… §N:~üøéÓ§333 OŸ>m†ÓéT“ !TÒÔ¬Y³R¥JIII5jÔ¸õÖ[ãããëׯo–€"rJ ¥,,,|áÂãZl¨h1ÿaåÒÐQÓDFF&$$$$$4lذQ£FÉÉÉ­ZµºõÖ[ !„ÊùóçKk‹ !ªU«vCì™RÊüüü¢¢¢ÿêp8ªU«Vâ\çÏŸwù0**ªråʯ"œÚÑëׯ/µ+**Ú²eËàÁƒ+Uª$„B8ŽÀþðÌ2G\\܈#þõ¯é_S”gN§SJ™ Jáp8<êjÚråʕڵk—¶"Íš5S+ëâܹsê—h=zt‰ßpTŸJxž1p-ç¿òòò^|ñŤ¤¤6mÚ¬\¹²°°Ð0 !„ÙiªÅ£†‘““³lÙ²Ž;¶k×nñâÅ—.] ಀҨƒ‘uo´Rýè£B]M[–.]zöìY÷µ0,«YâŒÒ2&Èe‘c†±bÅŠ;ï¼óå—_>qâ„qm_T{¡Ãá  T»µu)ßÿýèÑ£[¶l¹aÆ@- ð¬´[í“~ø¡æúøàÊ•+Ó§O/mET“¥´yÝÿÀ_:JSN#ÇÜ·V¯^Ý´iÓ!C†;vÌ¥M­& l+Ç0 §Ó©ÊtY”ò§Ÿ~êÞ½{‹-V¯^Ø…î<a322–-[f*å‰'fee•ø§2ë,¯u0¡^(U9Ã0Š‹‹Ç׿ÿ„º.ÿ¥ú4222ú÷ï?lØ05Z )åSO=uîÜ9#\»›233ßxãP×Þ)‘#¥¼råJ·nÝæÍ›g„ÓÏIõ­«3¯wß}·mÛ¶G u¥P~åçç¿òÊ+¡®E©V­Ze„q %*‘ãt:‡þå—_šÿë[9%Ž1?÷¡@ë5LÕÏÖºuëÍ›7ûV=À>—}ظ¶7¾þúëÿþ÷¿C[·]¾|yÉ’%êßî•GØ*‘3uêÔ÷ßß°âýdŒýU gÏžíÛ·ïÙ³gý¯$`“õwqùòå7ß|3´õ)ÑìÙ³­YHØÜ(Ê]äüðÃ/½ô’ˆö¸‡Q•þ:0ögÏž4hPÀG1Vê,Çá¸î€ ZÛ|ðAqqq¨*æÂüQL:Õ°üŠé^»Q”£§H)sss|ðAkç•EIMkܸqƒ êÖ­[«V-óÃâââ“'Oæåå?þàÁƒyyyòÚ£ „Çx¨³a›6mJKKãJ)‚Gí–ÉÉÉõë×߸q£aÙÛ³²²fÍš5qâÄVð:?þxAA¼þɃþæ›oÔ}€DО>0iÒ$ßêãp8Ôý4qqq¯¼òŠºõ¬Ä•Í‹ŠŠ80kÖ¬:”xÉÇ>µè-[¶|ƒ qß]+UªtìØ±P×÷¿Ö¯_ïò#BÔ©S''''!!Áå·“’’Rb!j$ž‹Q£Fi^— áéa¡¨¨héÒ¥¾Íët:£££§OŸ~øðáñãÇ׬YÓ(å5?ŒˆˆhÒ¤Éøñã¿ùæ›Ï>û¬^½z†O# ÌVѧŸ~*Ãû& Üè„]ºt‰u¹$YXX¨:²ÂÁßÿþw—‘”rüøñµk׿§þÊQä8pàÌ™3>Ì(¥Œß¾}ûĉcbb ïú={öܳgOÿþýÍOì¼Ö{ Nî$EÐH)£££'L˜`žÜ˜»Ü²eË233C]AcË–-[·nuùV«Ví±Ç3Âõ¼Vå(r¾ýö[¯¦7{bbbÖ¬Y“œœlýÜÛ¥W¯^ýÃ?|æ™g|h©¨‰322víÚåÕ¥ ¸ ÉÖóm¡¡ú¢Ÿx≻îºË¬ƒÂét^½zuøðá!G0oÞðã?ú6ã”)Sî¾ûî€Ôáå—_Þ¸qã?þèà Ã0–/_~×]w…éœÿ­à• -Ã4rss/_¾\§Nˆˆ5½¶­g­žËB =zäÈ‘¬¬¬Ó§OçääK)Ïž=UµjU§ÓÓ¸q㤤¤;î¸Cõå×f àºXK‹ŽŽ~ï½÷Ìs,s¹›7oÞ´iÓý÷ߨ…z+++kåÊ•âÚÓHk[cìØ±†÷ÃA§r9'Nœðê$HíÙÑÑÑ<òˆúÄÿyddäôéÓ{öìéÛ ç~øÁÛY‚ÔçC™Ö“SßJ0J?Ž«ÏwìØ±iÓ¦½{÷feeíß¿_½@ÏL÷F5mÚ´aÆÉÉÉ=zôPWׂǥz?ÿü³:doÛ¶mß¾}fÅÌꙉhÝKÍÿ­Q£Fûöí;wîܱcÇfÍšEDDõðzÇw´mÛöûï¿7+£ª·jÕªPEŽ”rÚ´iW¯^µF‹¢k×®76§ IÝ`_y‰)¥·rÔšZ½zõ¶Ù»uëvß}÷}ñÅ>Ì›žžžŸŸ¿~ýúE‹Ù¬¸6üoÙ²e>,±DRÊM›6͘1ðñ#7-Z´˜>}ºú÷ÁƒÇg“¦¥¥õêÕË()¨öïß¿fÍš7îÚµËý¥[†a8N5×áÇ>l~žœœÜ¼yóÞ½{÷îÝ;/ær:{öìÙ²eËæÍ›7oÞüŸÿüÇe3i¬Í/—mbþonnîš5kÖ¬YcFݺuÛ·oߦM›öíÛ£Õ«ê3vìØï¿ÿÞzùPJ¹bÅŠI“&ÝvÛm]¢_}õ•zÜ€uÕªUkñâÅæÿÒÊ/Ì£¤·C=kÑ¢…W{¤: ôìÙS–2Ú7N§såÊ•¾m‡Ã±sçÎììla·mgc:Ž;vj¤”C‡µÓah»xñbsöôôt¯¾‹… º×aíÚµMš4ñ¹;Å|Q^•*Už{î¹ .øö-«¹\æýç?ÿÙ²eKõùP·2™;@jjê¶mÛÜ+`‡u´*ÓR¬.Þ$%%™_Ÿ¹Ð=zø°•üdVÆ¥ÂóçÏ·NÆ i%œI‡£ð‰‡Ã‘ØjH)8àÛÞ „X·n”rÈ!êXfó ïp8†¨ú™ïa´³ •“'Oš%ø9ÇŽ{衇ì箇º™Û'55õ—_~ñmƒX÷{÷îMMMõ³nv*oÖÜápôîÝ[õ{<"Gµ`Áë&2ªBN§ 6¸ïo±±±—/_¶NFä(DŽwÂ'r”¹sç–x&ë3ŸË1«‘™™©^Mo¿™žžµ˜?¾°÷Šnó˜8iÒ$õ¢ U‚Ï‘sìØ±?ýéO·Ür‹º˜ásǸþ¨­þ[­Zµ—^z)//χMät:<8vìØÊ•+[ÎÁk师5kÖ¯¿þj¿Îž[9ª¡Ó®];÷eµhÑ¢°°ÐÛMä?üáîßõ¤I“\&#r"Ç;AŠuîé[}¾ùæ›ÀVÆÓ§Oˆˆðj-ºtéâÿr ëÕ«g3rTÞÔ©SçâÅ‹ÖB|‹œ#GŽ$&&ÚŸËBˆ;ï¼Óú(ä¿p!DRRRff¦Í:{nå(‡ªP¡‚58Õ¡õêÕ6—â¿ýû÷[—®v¼Š+fgg»LIä(á9åè¾s˜©üõ×_®.ðøã×®]Û«Y¾øâ ?ßG'¥üøã­¯ë.sz)åøñ㣣£ýY®aééé;w.í"„سgÏ´iÓÌÿõ0±¹6nÜøÇ?þ1¨+“J‚cÇŽõë×ïÒ¥K*¶qãÆ;w¶~¢Öú½÷Þ Ô"Ê4~üx— !}ôÑ`9D0”£Èq9§óÊ©S§ÔøÔwß}7??߃á˜UªT?~¼ýõC;w®? BÌŸ?ß«YªT©2jÔ(jÆéÓ§¨óågQž©­ôÆoØR¯6þçŸÞ§OŸüüüОTšµÝ»woïÞ½˜: °þ¯ZÍÿýßÿÕðN )ezzúúõë]>ŠŠšùäÛo¿‘‘árõBt¤µiòäÉöGK«ÉfÍšåóâ&NœèÕ~œ˜˜XTTä¾âÞFŽ~Bˆ‰'JßÚÊ•+ý/ç²ÿX‡ Š’xU¸a·ß~»ûNhe3r¤”+V¬p¯ÃáØ°aC0öjÅét®^½Z¸ ÁhÖ¬™zXƒ;"G!r¼¤È)..6ïRH%Åõ£l]~*THMM}衇^xá…/¾øâÌ™3ªý‰îܹӿ!ɬdçÎ}^ÜwÞéÕ~Ÿ[97~æ™g–/_¾sçÎóçÏËk»¨Yþ¹sçvïÞý?ÿó?ÇWâ}¨Æ UC§Äµ°ßÊ‘R~÷Ýw*Tp?Á Þе]»vEEE¹ìržCŽÈQˆï#rLcÇŽ ê=z>HIIyúé§?ýôSÏÝ ¥9sæL¥J•¼Zø° ó]se–¯&ëׯ_iEù9Âr—¥¢FÆ [´hѦM›vïÞ}üøñôôôo¿ývîܹýúõ«R¥ŠKöÛ_Šâïÿ{‰õߺu«ý¢\ZÀIIIï¾ûî•+Wìoù¼¼¼É“'W¨PÁlÙ_úsÏ=WZ±^EŽ”òÏþ³Ëft8¿ûÝï쯈WRSS]¾!Ä{ï½çáT‰ÈQˆï5r.\¸àÏSR‚Áü9ÅÅÅ;vóæÍ¥uU—f̘1^]¦r8Gõª•³{÷nóÐigu‡‡×˜ú9jî¹çž 6zX‘‚‚õF/ßR§´G6ôèÑër̘¼ÿþû½º[SQ+øÚk¯9¯nÆ2 #..®´qÞFNNNN¥J•\f‰ŠŠ ì CUU]F©©}/&&F½Ü½4DŽBäx'¨‘#¥û¬o—¬ï»ï>ë¶µ³¸F¹—3eÊo[K‡cúôé>ÔÙyg•ýµ¨_¿~‰[ÌÛVŽ”R½$к'¨ÿ.X° k§Œ3ÆeÕÔo¡Ì‰…ÈñN°#G0žËÉÉ‰ŽŽvœo¿ý¶Ìy‰%œ#§=}ÀE:u6lØ0aÂó“°ú†ÔÁQJ©|0{öliyÙ¥ûÄ-[¶LLL,ñ¯¥•¿aÃ;Sæåå}üñÇ6‹U%»Ü¯î?yíUf/¾ø¢Ï…tíÚ566Ö0 ‡ÃauÜíÛ·ÏۼƎëí5˜ !*T¨Ð·o_ÛÝU±k×.ÿ—®üõ¯UÇ5ë‡ÇŽ Ô ™V¯^}ùòe—3§æÍ›·k×. 宂ÚÊq&ô?þøüóÏÿæ7¿ «VŽõž å…^0ûôK\£µk×ÚΤ ŒŠŠ²Ók·hÑ"¯¶LíڵϞ=ë¹LZ9‡cäȑқœNçóÏ?ïUsÖ}'— ®ÃÛù1«Õ¬Y³yóæÂö56û¼*0°G)åèÑ£]Z9RÊŒŒŒ+Vø\æK/½tìØ1—Ï[¶lùä“Oú^W L!låØqúô鯾újΜ9ÇoÙ²¥ûýíÖ6Ëç.õv³(óæÍóP½O>ùĺt;Å–öÈáS§NEEEÙ,Ç0Œ&MšØÜ†>´r ¼þªJbË%í„¿ýíoíÌn~׿ÿýïRí`ð§•ãt:­÷ÚÄf3×]vv¶{óQ±ÿ~û…ÐÊQhåÜTbcc;uê”––¶dÉ’mÛ¶]¸páàÁƒüñ¤I“†ªNiÝû߬©ãymÄÚÆ=LÖ¥K—¸¸8aïȪ>îï#QæÍ›wåÊÃÞ µ¢W¯^eN曺uëÞrË-,ÐΕ(;;Û«&K||¼o sBˆ_|ѽ—òôéÓê”ÈN!ÖÉV­Z%¯o> !Ú´isÇw°Ú9"ÇwæÏ£qãÆ}ûö2eÊ;ï¼³k×®üüü={ö¼ýöÛiii=zôˆ‹‹3®?/¥§§{øIGGG?óÌ3†í£ªbݺuîŸ-]ºÔ«Šýáðjzûj×®ísHÖùóçmN©’ÉŸwц¹V­ZuíÚÕý{ùÇ?þ¡^cX&ë¯àwÞ1ÜvÚ€¶GÈ9¾³þ<Ì4)etttÓ¦M~øáW_}õ³Ï>;yòdVVÖ§Ÿ~:uêÔ:×zù}^îÉ“'wîÜéa‚'žxâÎ;ï´¿ëÖ­;~ü¸Ë‡6lP/œ¶©M›6Öç0Vdddxöx&„P=“7%)åk¯½V¹re—¯æÜ¹sê¥ öËY±b…z ‡õóZµj=òÈ#F¼DäøÎ¥áâáÃzõêõêÕëÙgŸýúë¯úé§.]º¸÷¼Ù!¯ =úúë¯=L=cÆ ûÅ^ºtéå—_6Ø*>?øàƒ2g´®Å’%Kû¼°åÕ·¦z&oJBˆÆ<ØýOóçÏ·¿‰òóóÏ{9IDATÓÒÒÌ}ÛìþÇ?þ¡Fë܈g(M¹8F>(éÜ*99yýúõ P/¾ýœŽ=êy‚®]»¶jÕªÌrÌu|çwÔ­†a!Š‹‹ÿùÏÚŸ½[·nå¤Ï=::ÚÎŽaNSâeꛆ”ràÀî$33³´ „.³†1þüÓ§O›ªßE³fÍÜÇaã&P^"Çð5uœNg`ë ª±páÂFùüä•'NxžQJ9þüÈÈHÏå˜?é‚‚‚©S§šÆ—-[vòäÉ2«¡fŽŽ~õÕWÕŒ7}H£FìLfnØÌÌÌ`V'Ä„;wnÓ¦ûŸÒÒÒìÄíž={¦M›f)eddä›o¾G!ÜTut8}úô}÷ÝçÛÑpàÀþ<×Ë…ùÓªQ£Æ /¼ðÈ#x5üÉTTTäùPѼyóîÝ»¯Y³F}RâRäµg— !fÏž–––˜˜xåÊ•—^zÉ(åynîÆg6qnúÓÒÄÄÄ={ö”9™¹a·mÛV\\Ú£§Ïi;"""–,Y’œœìp8œN§¹;effNž· löíôéÓç³Ï>3»ËJKãÚQiþüùÓ¦M[³fÍ/¿übs)ãÇ÷znXêÙ©†£&ÈÏÏÏÈÈhÑ¢EëpéÒ¥™3gÚœX}ï-[¶ìÞ½{ë`Õ¤I“!C†|ðÁf°©uë­·¦L™R⛜Ôþ–‘‘±uëVÕÖ7·gDDÄäÉ“ƒTU "з‚úp­^MÛm·ðõSVN§SÝÖàÃ&0`€ûó=Ýýúë¯êigÝ…UªT9qâ„:cµ9KiïÍôÌÛ[A[´háÓ6.ý…%í„j”„W•>|x x£ÊÙºu«¸ö@Ï‹V_bioëñçVPk}¤”ÙÙÙ±±±.ûŒ¢Ä·Ã™¢9r¤ûÎ9lØ0¶ŒÂ­  ·‚†XTTTƒ |›÷çŸÞ¶m[`룘/$öaÞøøx;‘3cÆ û}w?þøì×dذaö'¾ øðýåË—Ÿ={6 KWßøæÍ›ÕwZæ×jN’’ ”XÃ0êÕ«7gÎ÷¥/Z´Èýj¨ªüÙ³gß}÷]÷2Ÿzê©`Ta¢\DŽa>Œ§2O^ýõ@UÃzŒØ³g·§!æ)aÆ {_<ð@Ó¦Mí¤ŽZÙÕ«WKËÙ«çj$$$Ü{ï½^­Â®I“&U«VõvhûG}À:¬_¿Þóä^û÷iùlРA¬¬·ÞzË}b!Ä /¼péÒ%s-ÔÕºuëæÍ›»ª¡ò9)))>73W¬XqèС€TÃZu²_+k³æî»ï¶9oDDĤI“¼ZýúŒ;¶B…rq9Ðê·¿ý­·mÓ… jéÇŽó|W–»5jÔ«W/P(MDDD¿~ýÜw³)S¦¸ßœäEjF5n7±ò9}úôñ­ Ë0 !Ę1c.\¸ÀúìØ±Ã|:§ÍỶ+W®|Ï=÷ØŸkàÀ·ß~»-]JJÊ“O>éóV½qÝÿýÞβ{÷îG}TÔû³èììì^½zy5רQ£ô ™=z´õD¥È±cÇþú׿šJ)‹‹‹{ì1—’R<ØÛ—|ðáJݺu}>ÓB4mÚÔ«‡Úz““Ó¸qcáýƒ>UC§sçÎÞ.qöìÙf#Éÿ掺"½nÝ:Ÿ·À;|@J¹{÷nsKzÕHMMM5/àùàäÉ“III6‡u˜Ó!Ž;Vbþpát:ÇŒc\ÿ[UëoG]‹rhP¹reÿ_*Êð…áa¡]»vþ|û÷ïoÞ¼ùÔ©S/]º¤>‘Þßü(¥üòË/[µj•™™éÃìJÇŽ½š^JùÀ¨û|ó©‹ tëÖÍÿrnDÍš5KNN׆JÛÜ©¤”[·n:tèÕ«WÝÿTÚ,æ¿/]º4hР¬¬,ûõT‡õ^½z¹ˆƒD1iÒ$—ÇÊ©ƒ õæ¶>øÀ}•ûöí[«V-µ\©•³fÍß"G\/11ñ‰'žX¾|ù‘#GTÉæ Oëâ¬ÿ{éÒ¥íÛ·Ï;W½ÔÙŸjDFFzÛØRé'Mšä> Õ7Bˆ)S¦øó]ÜЭ)åÚµk£¢¢¼Ý˜jú[o½õé§ŸÞ»w¯‡JZ÷¨#GŽLš4)>>ÞúRZ; BDEEíÚµKá­ LŸ>ݽžBˆï¾ûNJ™­Æ_XGx«¿ú?”œVŽέœrtí·G))){÷îõ³œ¬¬¬yóæ©W®\¹yóæ5jРAll¬õ®·ÜÜÜììì'N9rdÇŽ/^4,1>=}ÇápŒ1ÂÛÑwjÏ›4iÒ’%KÔh]–îbøðá~–pCëÞ½ûèÑ£çÎkxÿmžß ¢veÃ0&Nœø›ßüFóI‘7ŠaÆ=ýôÓ~"ÝRPX&¸ÿÕ!DŸ>},Xª7%%%¥¥¥¹îò¶P!Dbbâ+¯¼¢«^½rt-Ç|Û¶m‹-2?ñí‡TÂò6!ÄСCGŽé±-[¶lÒ¤ÉÁƒ¥—W•TM*Uª4jÔ(ÿ«qsRΘ1#''G½DÙüЫ¨°~Ñæ¼Òò¬UŠjÞ¼ùûï¿ÂÇW !ÆÿÆoäçç[OMÜÏTž}öÙðyqê?üð·¿ý-$‹nܸñƒ>’E#ˆ×rL¿þúk›6mÄõÃfŠuxÒØ±cøhÑÉ“'›½dö[*jÊßÿþ÷©ÃÍѱ¦º‹ŠŠFmݤ¡Ú¯Ô¢“’’Ô¿2{>ƒ×±¦<û쳞»k×®}ùòå.ÑÏŽµêÙ³g·káEJY¥J•¯¾úê­·ÞªW¯^¦Žyº·téÒyóæ°’#FŒ°ùjK÷Zýñ T5nêkŠˆˆX°`Ák¯½mý<$UjÛ¶íÆkÖ¬’¥›ÔêOž<¹~ýú|#FŒ¨X±¢Æz!ôÂîh«:튊Š6lØŽ;zöìê¹’RFFF¦¥¥eff>úè£-¼AƒãÆóaÆÛn»­OŸ>­ÌÎ<žŽ7nß¾}êöØäMåÊ•/^üí·ßÞ~ûíf¬þj(jÑ111=ö˜,ý²ßO<¡·^½ò9VqqqkÖ¬Ùºuë]wÝ¥:FT{ÂÚ!¤Ÿ®{WŒùïîÝ»gff¾úê«111ÁXô„ \n)³’†aüå/ á·Ô¨Ü2¿SF‹%&&®]»væÌ™êÌÝå;õ¡ÀkeÖÍ\u~ݺuúÓŸ|(ÍŒ¤0`€KÉæf9rdP6jç+öÀ¡ÿµoÜ(nø#H@´jÕjÛ¶m_~ùå‹/¾Ø©S§J•*×?'*à„åÍ’æÛ´i3}úôíÛ·þù牉‰ÁX®ZPaa¡ýk¶ªzÍ›7ÔíŸN{ˬF@–n³(RÊ &dee-\¸P= /€ûË)¥¬X±âÀׯ_äÈ^äãR¸uŸ ”F©§®Y©‹ S§N à‚Jäù )¬Žò¡ê‰Õ¯Xó,22²cÇŽ:u2 ãÌ™3ŸþùÆ7lØ››Œ½AZF£uïÞýèÑ£‡z¯¢ÌýO-wêÔ©çγó“3¯*ÍŸ??222 ÇP!D­ZµFm5u€°?âNQ½zuõòVûåK)k×®=räÈ#Fdgg¯X±bÆ _}õ•ý¨+³VÑÑÑ}úôyàºuëf^@òÁƒ>xþüykÉñññþ×ÐJ1sæL—·´ !þD5µg:477×\Š”2>>¾Ä¶bÅŠjt:á=Íš5 u4 ý¶v§ö•úõë{õÃ`¸råÊÞ½{·mÛ¶cÇŽ½{÷îÛ·¯  @^?¤UM)¯96ç5/ÖiÔ¿o»í¶Ö­[·jÕªU«V)))Aê=+Mnnnݺu¯^½jç¨Úºuëï¿ÿ^CÝnV'NœøôÓO·lÙ²yóæ£Gª­{‘´Œ‡–aÓ†e·iß¾}Ë–-;tèpï½÷V©R%D«‚@BBBvvv‡±x@äØbòóóÏ;wêÔ©‹/æäääçç«cwnn®Ë,¥Œ‰‰QÝúÕ«W­^½z\\\\\\DD„õø¢yE^}õÕ &Øœ^±}ûvÞÕèk–äääüüóÏ999yyyN§3//Ïú5‡ÃQ½zu‡ÃQ­Zµ5jÔ©S§nݺµjÕRñ§äsDŽwÂ0r\xõË«ÃÄÅ‹7n|âÄ ›Ó;Žûî»oãÆA­U¹âmOà­pŽv}_x!á“7†aLœ8ñ—_~±?½”²_¿~Á«O9DÞ ftæÌ™Þ>ì rð_j|Aß¾}Ÿ~úéP×À͉k7÷§\+.Àvy¨¨ú°Aƒo¾ù¦ö*(/håÜ$\Þ-èòVë'Ö7Kš³·hÑbΜ9qqqú*  œ¡•sSqiܘOð0e—.]ÆŽÛ»wï`¿ˆœ›Ä°aÃÚ¶m[PP ^Áb>.://ïüùóæ«kÔ¨Q­Zµøøø:uꤦ¦vèÐÁú²/ò@P97‰¡C‡ú_¶T\ËhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9MˆÀ¶ÿÖµÁ÷”hèIEND®B`‚p2Dd&& `+`+ffð<² ð C ðA¿ÿðÂbðà1„oœÅr<,;ÖFQ[‡¬bÿ¼1´2cnð´1„oœÅr<,;ÖFQ[‡¬bÿ‰PNG  IHDR&&è¬ÖgAMA±ˆ•˜ô¦ pHYs ø øf&<ý IDATxœíÝytU¢Çñºˆö"$ÄƃèÂ.Žì0 ‹¨Œ ›(F‘a—qæ Ûˆ ‚ìˆG}"¢(úØQGD-ÀŒ$  D ô}Ü¡^Ñtª·Û ù~þð`§êÖ­êêúÕ½u«Ê0Üà„¡®ܨÂöZ!Ô(¹±Âv«@Ø’R†!„Pÿ+á9Jxn/sá|²¾‘ãp8âããC] ¸ÁüòË/N§3Ôµ(Y˜FŽ”2>>>+++Ô€LBBBvvvx¶u¡® ¼ rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBäØ"¥tùG™S\9¶!\þ¡¸Œ9Ù.*„º7)¥âÂ… §N:~üøéÓ§333 OŸ>m†ÓéT“ !TÒÔ¬Y³R¥JIII5jÔ¸õÖ[ãããëׯo–€"rJ ¥,,,|áÂãZl¨h1ÿaåÒÐQÓDFF&$$$$$4lذQ£FÉÉÉ­ZµºõÖ[ !„ÊùóçKk‹ !ªU«vCì™RÊüüü¢¢¢ÿêp8ªU«Vâ\çÏŸwù0**ªråʯ"œÚÑëׯ/µ+**Ú²eËàÁƒ+Uª$„B8ŽÀþðÌ2G\\܈#þõ¯é_S”gN§SJ™ Jáp8<êjÚråʕڵk—¶"Íš5S+ëâܹsê—h=zt‰ßpTŸJxž1p-ç¿òòò^|ñŤ¤¤6mÚ¬\¹²°°Ð0 !„ÙiªÅ£†‘““³lÙ²Ž;¶k×nñâÅ—.] ಀҨƒ‘uo´Rýè£B]M[–.]zöìY÷µ0,«YâŒÒ2&Èe‘c†±bÅŠ;ï¼óå—_>qâ„qm_T{¡Ãá  T»µu)ßÿýèÑ£[¶l¹aÆ@- ð¬´[í“~ø¡æúøàÊ•+Ó§O/mET“¥´yÝÿÀ_:JSN#ÇÜ·V¯^Ý´iÓ!C†;vÌ¥M­& l+Ç0 §Ó©ÊtY”ò§Ÿ~êÞ½{‹-V¯^Ø…î<a322–-[f*å‰'fee•ø§2ë,¯u0¡^(U9Ã0Š‹‹Ç׿ÿ„º.ÿ¥ú4222ú÷ï?lØ05Z )åSO=uîÜ9#\»›233ßxãP×Þ)‘#¥¼råJ·nÝæÍ›g„ÓÏIõ­«3¯wß}·mÛ¶G u¥P~åçç¿òÊ+¡®E©V­Ze„q %*‘ãt:‡þå—_šÿë[9%Ž1?÷¡@ë5LÕÏÖºuëÍ›7ûV=À>—}ظ¶7¾þúëÿþ÷¿C[·]¾|yÉ’%êßî•GØ*‘3uêÔ÷ßß°âýdŒýU gÏžíÛ·ïÙ³gý¯$`“õwqùòå7ß|3´õ)ÑìÙ³­YHØÜ(Ê]äüðÃ/½ô’ˆö¸‡Q•þ:0ögÏž4hPÀG1Vê,Çá¸î€ ZÛ|ðAqqq¨*æÂüQL:Õ°üŠé^»Q”£§H)sss|ðAkç•EIMkܸqƒ êÖ­[«V-óÃâââ“'Oæåå?þàÁƒyyyòÚ£ „Çx¨³a›6mJKKãJ)‚Gí–ÉÉÉõë×߸q£aÙÛ³²²fÍš5qâÄVð:?þxAA¼þɃþæ›oÔ}€DО>0iÒ$ßêãp8Ôý4qqq¯¼òŠºõ¬Ä•Í‹ŠŠ80kÖ¬:”xÉÇ>µè-[¶|ƒ qß]+UªtìØ±P×÷¿Ö¯_ïò#BÔ©S''''!!Áå·“’’Rb!j$ž‹Q£Fi^— áéa¡¨¨héÒ¥¾Íët:£££§OŸ~øðáñãÇ׬YÓ(å5?ŒˆˆhÒ¤Éøñã¿ùæ›Ï>û¬^½z†O# ÌVѧŸ~*Ãû& Üè„]ºt‰u¹$YXX¨:²ÂÁßÿþw—‘”rüøñµk׿§þÊQä8pàÌ™3>Ì(¥Œß¾}ûĉcbb ïú={öܳgOÿþýÍOì¼Ö{ Nî$EÐH)£££'L˜`žÜ˜»Ü²eË233C]AcË–-[·nuùV«Ví±Ç3Âõ¼Vå(r¾ýö[¯¦7{bbbÖ¬Y“œœlýÜÛ¥W¯^ýÃ?|æ™g|h©¨‰322víÚåÕ¥ ¸ ÉÖóm¡¡ú¢Ÿx≻îºË¬ƒÂét^½zuøðá!G0oÞðã?ú6ã”)Sî¾ûî€Ôáå—_Þ¸qã?þèà Ã0–/_~×]w…éœÿ­à• -Ã4rss/_¾\§Nˆˆ5½¶­g­žËB =zäÈ‘¬¬¬Ó§OçääK)Ïž=UµjU§ÓÓ¸q㤤¤;î¸Cõå×f àºXK‹ŽŽ~ï½÷Ìs,s¹›7oÞ´iÓý÷ߨ…z+++kåÊ•âÚÓHk[cìØ±†÷ÃA§r9'Nœðê$HíÙÑÑÑ<òˆúÄÿyddäôéÓ{öìéÛ ç~øÁÛY‚ÔçC™Ö“SßJ0J?Ž«ÏwìØ±iÓ¦½{÷feeíß¿_½@ÏL÷F5mÚ´aÆÉÉÉ=zôPWׂǥz?ÿü³:doÛ¶mß¾}fÅÌꙉhÝKÍÿ­Q£Fûöí;wîܱcÇfÍšEDDõðzÇw´mÛöûï¿7+£ª·jÕªPEŽ”rÚ´iW¯^µF‹¢k×®76§ IÝ`_y‰)¥·rÔšZ½zõ¶Ù»uëvß}÷}ñÅ>Ì›žžžŸŸ¿~ýúE‹Ù¬¸6üoÙ²e>,±DRÊM›6͘1ðñ#7-Z´˜>}ºú÷ÁƒÇg“¦¥¥õêÕË()¨öïß¿fÍš7îÚµËý¥[†a8N5×áÇ>l~žœœÜ¼yóÞ½{÷îÝ;/ær:{öìÙ²eËæÍ›7oÞüŸÿüÇe3i¬Í/—mbþonnîš5kÖ¬YcFݺuÛ·oߦM›öíÛ£Õ«ê3vìØï¿ÿÞzùPJ¹bÅŠI“&ÝvÛm]¢_}õ•zÜ€uÕªUkñâÅæÿÒÊ/Ì£¤·C=kÑ¢…W{¤: ôìÙS–2Ú7N§såÊ•¾m‡Ã±sçÎììla·mgc:Ž;vj¤”C‡µÓah»xñbsöôôt¯¾‹… º×aíÚµMš4ñ¹;Å|Q^•*Už{î¹ .øö-«¹\æýç?ÿÙ²eKõùP·2™;@jjê¶mÛÜ+`‡u´*ÓR¬.Þ$%%™_Ÿ¹Ð=zø°•üdVÆ¥ÂóçÏ·NÆ i%œI‡£ð‰‡Ã‘ØjH)8àÛÞ „X·n”rÈ!êXfó ïp8†¨ú™ïa´³ •“'Oš%ø9ÇŽ{衇ì箇º™Û'55õ—_~ñmƒX÷{÷îMMMõ³nv*oÖÜápôîÝ[õ{<"Gµ`Áë&2ªBN§ 6¸ïo±±±—/_¶NFä(DŽwÂ'r”¹sç–x&ë3ŸË1«‘™™©^Mo¿™žžµ˜?¾°÷Šnó˜8iÒ$õ¢ U‚Ï‘sìØ±?ýéO·Ür‹º˜ásǸþ¨­þ[­Zµ—^z)//χMät:<8vìØÊ•+[ÎÁk师5kÖ¯¿þj¿Îž[9ª¡Ó®];÷eµhÑ¢°°ÐÛMä?üáîßõ¤I“\&#r"Ç;AŠuîé[}¾ùæ›ÀVÆÓ§Oˆˆðj-ºtéâÿr ëÕ«g3rTÞÔ©SçâÅ‹ÖB|‹œ#GŽ$&&ÚŸËBˆ;ï¼Óú(ä¿p!DRRRff¦Í:{nå(‡ªP¡‚58Õ¡õêÕ6—â¿ýû÷[—®v¼Š+fgg»LIä(á9åè¾s˜©üõ×_®.ðøã×®]Û«Y¾øâ ?ßG'¥üøã­¯ë.sz)åøñ㣣£ýY®aééé;w.í"„سgÏ´iÓÌÿõ0±¹6nÜøÇ?þ1¨+“J‚cÇŽõë×ïÒ¥K*¶qãÆ;w¶~¢Öú½÷Þ Ô"Ê4~üx— !}ôÑ`9D0”£Èq9§óÊ©S§ÔøÔwß}7??߃á˜UªT?~¼ýõC;w®? BÌŸ?ß«YªT©2jÔ(jÆéÓ§¨óågQž©­ôÆoØR¯6þçŸÞ§OŸüüüОTšµÝ»woïÞ½˜: °þ¯ZÍÿýßÿÕðN )ezzúúõë]>ŠŠšùäÛo¿‘‘árõBt¤µiòäÉöGK«ÉfÍšåóâ&NœèÕ~œ˜˜XTTä¾âÞFŽ~Bˆ‰'JßÚÊ•+ý/ç²ÿX‡ Š’xU¸a·ß~»ûNhe3r¤”+V¬p¯ÃáØ°aC0öjÅét®^½Z¸ ÁhÖ¬™zXƒ;"G!r¼¤È)..6ïRH%Åõ£l]~*THMM}衇^xá…/¾øâÌ™3ªý‰îܹӿ!ɬdçÎ}^ÜwÞéÕ~Ÿ[97~æ™g–/_¾sçÎóçÏËk»¨Yþ¹sçvïÞý?ÿó?ÇWâ}¨Æ UC§Äµ°ßÊ‘R~÷Ýw*Tp?Á Þе]»vEEE¹ìržCŽÈQˆï#rLcÇŽ ê=z>HIIyúé§?ýôSÏÝ ¥9sæL¥J•¼Zø° ó]se–¯&ëׯ_iEù9Âr—¥¢FÆ [´hѦM›vïÞ}üøñôôôo¿ývîܹýúõ«R¥ŠKöÛ_Šâïÿ{‰õߺu«ý¢\ZÀIIIï¾ûî•+Wìoù¼¼¼É“'W¨PÁlÙ_úsÏ=WZ±^EŽ”òÏþ³Ëft8¿ûÝï쯈WRSS]¾!Ä{ï½çáT‰ÈQˆï5r.\¸àÏSR‚Áü9ÅÅÅ;vóæÍ¥uU—f̘1^]¦r8Gõª•³{÷nóÐigu‡‡×˜ú9jî¹çž 6zX‘‚‚õF/ßR§´G6ôèÑër̘¼ÿþû½º[SQ+øÚk¯9¯nÆ2 #..®´qÞFNNNN¥J•\f‰ŠŠ ì CUU]F©©}/&&F½Ü½4DŽBäx'¨‘#¥û¬o—¬ï»ï>ë¶µ³¸F¹—3eÊo[K‡cúôé>ÔÙyg•ýµ¨_¿~‰[ÌÛVŽ”R½$к'¨ÿ.X° k§Œ3ÆeÕÔo¡Ì‰…ÈñN°#G0žËÉÉ‰ŽŽvœo¿ý¶Ìy‰%œ#§=}ÀE:u6lØ0aÂó“°ú†ÔÁQJ©|0{öliyÙ¥ûÄ-[¶LLL,ñ¯¥•¿aÃ;Sæåå}üñÇ6‹U%»Ü¯î?yíUf/¾ø¢Ï…tíÚ566Ö0 ‡ÃauÜíÛ·ÏۼƎëí5˜ !*T¨Ð·o_ÛÝU±k×.ÿ—®üõ¯UÇ5ë‡ÇŽ Ô ™V¯^}ùòe—3§æÍ›·k×. 宂ÚÊq&ô?þøüóÏÿæ7¿ «VŽõž å…^0ûôK\£µk×ÚΤ ŒŠŠ²Ók·hÑ"¯¶LíڵϞ=ë¹LZ9‡cäȑқœNçóÏ?ïUsÖ}'— ®ÃÛù1«Õ¬Y³yóæÂö56û¼*0°G)åèÑ£]Z9RÊŒŒŒ+Vø\æK/½tìØ1—Ï[¶lùä“Oú^W L!låØqúô鯾újΜ9ÇoÙ²¥ûýíÖ6Ëç.õv³(óæÍóP½O>ùĺt;Å–öÈáS§NEEEÙ,Ç0Œ&MšØÜ†>´r ¼þªJbË%í„¿ýíoíÌn~׿ÿýïRí`ð§•ãt:­÷ÚÄf3×]vv¶{óQ±ÿ~û…ÐÊQhåÜTbcc;uê”––¶dÉ’mÛ¶]¸páàÁƒüñ¤I“†ªNiÝû߬©ãymÄÚÆ=LÖ¥K—¸¸8aïȪ>îï#QæÍ›wåÊÃÞ µ¢W¯^eN曺uëÞrË-,ÐΕ(;;Û«&K||¼o sBˆ_|ѽ—òôéÓê”ÈN!ÖÉV­Z%¯o> !Ú´isÇw°Ú9"ÇwæÏ£qãÆ}ûö2eÊ;ï¼³k×®üüü={ö¼ýöÛiii=zôˆ‹‹3®?/¥§§{øIGGG?óÌ3†í£ªbݺuîŸ-]ºÔ«Šýáðjzûj×®ísHÖùóçmN©’ÉŸwц¹V­ZuíÚÕý{ùÇ?þ¡^cX&ë¯àwÞ1ÜvÚ€¶GÈ9¾³þ<Ì4)etttÓ¦M~øáW_}õ³Ï>;yòdVVÖ§Ÿ~:uêÔ:×zù}^îÉ“'wîÜéa‚'žxâÎ;ï´¿ëÖ­;~ü¸Ë‡6lP/œ¶©M›6Öç0Vdddxöx&„P=“7%)åk¯½V¹re—¯æÜ¹sê¥ öËY±b…z ‡õóZµj=òÈ#F¼DäøÎ¥áâáÃzõêõêÕëÙgŸýúë¯úé§.]º¸÷¼Ù!¯ =úúë¯=L=cÆ ûÅ^ºtéå—_6Ø*>?øàƒ2g´®Å’%Kû¼°åÕ·¦z&oJBˆÆ<ØýOóçÏ·¿‰òóóÏ{9IDATÓÒÒÌ}ÛìþÇ?þ¡Fë܈g(M¹8F>(éÜ*99yýúõ P/¾ýœŽ=êy‚®]»¶jÕªÌrÌu|çwÔ­†a!Š‹‹ÿùÏÚŸ½[·nå¤Ï=::ÚÎŽaNSâeꛆ”ràÀî$33³´ „.³†1þüÓ§O›ªßE³fÍÜÇaã&P^"Çð5uœNg`ë ª±páÂFùüä•'NxžQJ9þüÈÈHÏå˜?é‚‚‚©S§šÆ—-[vòäÉ2«¡fŽŽ~õÕWÕŒ7}H£FìLfnØÌÌÌ`V'Ä„;wnÓ¦ûŸÒÒÒìÄíž={¦M›f)eddä›o¾G!ÜTut8}úô}÷ÝçÛÑpàÀþ<×Ë…ùÓªQ£Æ /¼ðÈ#x5üÉTTTäùPѼyóîÝ»¯Y³F}RâRäµg— !fÏž–––˜˜xåÊ•—^zÉ(åynîÆg6qnúÓÒÄÄÄ={ö”9™¹a·mÛV\\Ú£§Ïi;"""–,Y’œœìp8œN§¹;effNž· löíôéÓç³Ï>3»ËJKãÚQiþüùÓ¦M[³fÍ/¿übs)ãÇ÷znXêÙ©†£&ÈÏÏÏÈÈhÑ¢EëpéÒ¥™3gÚœX}ï-[¶ìÞ½{ë`Õ¤I“!C†|ðÁf°©uë­·¦L™R⛜Ôþ–‘‘±uëVÕÖ7·gDDÄäÉ“ƒTU "з‚úp­^MÛm·ðõSVN§SÝÖàÃ&0`€ûó=Ýýúë¯êigÝ…UªT9qâ„:cµ9KiïÍôÌÛ[A[´háÓ6.ý…%í„j”„W•>|x x£ÊÙºu«¸ö@Ï‹V_bioëñçVPk}¤”ÙÙÙ±±±.ûŒ¢Ä·Ã™¢9r¤ûÎ9lØ0¶ŒÂ­  ·‚†XTTTƒ |›÷çŸÞ¶m[`룘/$öaÞøøx;‘3cÆ û}w?þøì×dذaö'¾ øðýåË—Ÿ={6 KWßøæÍ›ÕwZæ×jN’’ ”XÃ0êÕ«7gÎ÷¥/Z´Èýj¨ªüÙ³gß}÷]÷2Ÿzê©`Ta¢\DŽa>Œ§2O^ýõ@UÃzŒØ³g·§!æ)aÆ {_<ð@Ó¦Mí¤ŽZÙÕ«WKËÙ«çj$$$Ü{ï½^­Â®I“&U«VõvhûG}À:¬_¿Þóä^û÷iùlРA¬¬·ÞzË}b!Ä /¼péÒ%s-ÔÕºuëæÍ›»ª¡ò9)))>73W¬XqèС€TÃZu²_+k³æî»ï¶9oDDĤI“¼ZýúŒ;¶B…rq9Ðê·¿ý­·mÓ… jéÇŽó|W–»5jÔ«W/P(MDDD¿~ýÜw³)S¦¸ßœäEjF5n7±ò9}úôñ­ Ë0 !Ę1c.\¸ÀúìØ±Ã|:§ÍỶ+W®|Ï=÷ØŸkàÀ·ß~»-]JJÊ“O>éóV½qÝÿýÞβ{÷îG}TÔû³èììì^½zy5רQ£ô ™=z´õD¥È±cÇþú׿šJ)‹‹‹{ì1—’R<ØÛ—|ðáJݺu}>ÓB4mÚÔ«‡Úz““Ó¸qcáýƒ>UC§sçÎÞ.qöìÙf#Éÿ掺"½nÝ:Ÿ·À;|@J¹{÷nsKzÕHMMM5/àùàäÉ“III6‡u˜Ó!Ž;Vbþpát:ÇŒc\ÿ[UëoG]‹rhP¹reÿ_*Êð…áa¡]»vþ|û÷ïoÞ¼ùÔ©S/]º¤>‘Þßü(¥üòË/[µj•™™éÃìJÇŽ½š^JùÀ¨û|ó©‹ tëÖÍÿrnDÍš5KNN׆JÛÜ©¤”[·n:tèÕ«WÝÿTÚ,æ¿/]º4hР¬¬,ûõT‡õ^½z¹ˆƒD1iÒ$—ÇÊ©ƒ õæ¶>øÀ}•ûöí[«V-µ\©•³fÍß"G\/11ñ‰'žX¾|ù‘#GTÉæ Oëâ¬ÿ{éÒ¥íÛ·Ï;W½ÔÙŸjDFFzÛØRé'Mšä> Õ7Bˆ)S¦øó]ÜЭ)åÚµk£¢¢¼Ý˜jú[o½õé§ŸÞ»w¯‡JZ÷¨#GŽLš4)>>ÞúRZ; BDEEíÚµKá­ LŸ>ݽžBˆï¾ûNJ™­Æ_XGx«¿ú?”œVŽέœrtí·G))){÷îõ³œ¬¬¬yóæ©W®\¹yóæ5jРAll¬õ®·ÜÜÜììì'N9rdÇŽ/^4,1>=}ÇápŒ1ÂÛÑwjÏ›4iÒ’%KÔh]–îbøðá~–pCëÞ½ûèÑ£çÎkxÿmžß ¢veÃ0&Nœø›ßüFóI‘7ŠaÆ=ýôÓ~"ÝRPX&¸ÿÕ!DŸ>},Xª7%%%¥¥¥¹îò¶P!Dbbâ+¯¼¢«^½rt-Ç|Û¶m‹-2?ñí‡TÂò6!ÄСCGŽé±-[¶lÒ¤ÉÁƒ¥—W•TM*Uª4jÔ(ÿ«qsRΘ1#''G½DÙüЫ¨°~Ñæ¼Òò¬UŠjÞ¼ùûï¿ÂÇW !ÆÿÆoäçç[OMÜÏTž}öÙðyqê?üð·¿ý-$‹nܸñƒ>’E#ˆ×rL¿þúk›6mÄõÃfŠuxÒØ±cøhÑÉ“'›½dö[*jÊßÿþ÷©ÃÍѱ¦º‹ŠŠFmݤ¡Ú¯Ô¢“’’Ô¿2{>ƒ×±¦<û쳞»k×®}ùòå.ÑÏŽµêÙ³g·káEJY¥J•¯¾úê­·ÞªW¯^¦Žyº·téÒyóæ°’#FŒ°ùjK÷Zýñ T5nêkŠˆˆX°`Ák¯½mý<$UjÛ¶íÆkÖ¬’¥›ÔêOž<¹~ýú|#FŒ¨X±¢Æz!ôÂîh«:튊Š6lØŽ;zöìê¹’RFFF¦¥¥eff>úè£-¼AƒãÆóaÆÛn»­OŸ>­ÌÎ<žŽ7nß¾}êöØäMåÊ•/^üí·ßÞ~ûíf¬þj(jÑ111=ö˜,ý²ßO<¡·^½ò9VqqqkÖ¬Ùºuë]wÝ¥:FT{ÂÚ!¤Ÿ®{WŒùïîÝ»gff¾úê«111ÁXô„ \n)³’†aüå/ á·Ô¨Ü2¿SF‹%&&®]»væÌ™êÌÝå;õ¡ÀkeÖÍ\u~ݺuúÓŸ|(ÍŒ¤0`€KÉæf9rdP6jç+öÀ¡ÿµoÜ(nø#H@´jÕjÛ¶m_~ùå‹/¾Ø©S§J•*×?'*à„åÍ’æÛ´i3}úôíÛ·þù牉‰ÁX®ZPaa¡ýk¶ªzÍ›7ÔíŸN{ˬF@–n³(RÊ &dee-\¸P= /€ûË)¥¬X±âÀׯ_äÈ^äãR¸uŸ ”F©§®Y©‹ S§N à‚Jäù )¬Žò¡ê‰Õ¯Xó,22²cÇŽ:u2 ãÌ™3ŸþùÆ7lØ››Œ½AZF£uïÞýèÑ£‡z¯¢ÌýO-wêÔ©çγó“3¯*ÍŸ??222 ÇP!D­ZµFm5u€°?âNQ½zuõòVûåK)k×®=räÈ#Fdgg¯X±bÆ _}õ•ý¨+³VÑÑÑ}úôyàºuëf^@òÁƒ>xþüykÉñññþ×ÐJ1sæL—·´ !þD5µg:477×\Š”2>>¾Ä¶bÅŠjt:á=Íš5 u4 ý¶v§ö•úõë{õÃ`¸råÊÞ½{·mÛ¶cÇŽ½{÷îÛ·¯  @^?¤UM)¯96ç5/ÖiÔ¿o»í¶Ö­[·jÕªU«V)))Aê=+Mnnnݺu¯^½jç¨Úºuëï¿ÿ^CÝnV'NœøôÓO·lÙ²yóæ£Gª­{‘´Œ‡–aÓ†e·iß¾}Ë–-;tèpï½÷V©R%D«‚@BBBvvv‡±x@äØbòóóÏ;wêÔ©‹/æäääçç«cwnn®Ë,¥Œ‰‰QÝúÕ«W­^½z\\\\\\DD„õø¢yE^}õÕ &Øœ^±}ûvÞÕèk–äääüüóÏ999yyyN§3//Ïú5‡ÃQ½zu‡ÃQ­Zµ5jÔ©S§nݺµjÕRñ§äsDŽwÂ0r\xõË«ÃÄÅ‹7n|âÄ ›Ó;Žûî»oãÆA­U¹âmOà­pŽv}_x!á“7†aLœ8ñ—_~±?½”²_¿~Á«O9DÞ ftæÌ™Þ>ì rð_j|Aß¾}Ÿ~úéP×À͉k7÷§\+.Àvy¨¨ú°Aƒo¾ù¦ö*(/håÜ$\Þ-èòVë'Ö7Kš³·hÑbΜ9qqqú*  œ¡•sSqiܘOð0e—.]ÆŽÛ»wï`¿ˆœ›Ä°aÃÚ¶m[PP ^Áb>.://ïüùóæ«kÔ¨Q­Zµøøø:uꤦ¦vèÐÁú²/ò@P97‰¡C‡ú_¶T\ËhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9MˆÀ¶ÿÖµÁ÷”hèIEND®B`‚eœH@ñÿHNormalOJQJ_HmHnHsH tH uj@òj Heading 1$ & F¤ð¤ @& Æ75B*CJ OJQJmH sH uR@òR Heading 2!$ & F¤ ¤@& Æ7@CJF@!òF Heading 3 & F@& Æ@ÐCJZ@1òZ Heading 4. & F ÆÐ`„Є0ý¤ð¤P@&^„Ð`„0ýF@F Heading 5¤<¤@& Æð5:@: Heading 6 @& Æ€:@: Heading 7 @& Æ:@: Heading 8 @& Æ : @: Heading 9 @& Æ0DA@òÿ¡D Default Paragraph FontVi@óÿ³V  Table Normal :V ö4Ö4Ö laö (k@ôÿÁ(No List NþOòN Body¤x¤x Æ&B*CJOJQJmH sH uBþOB 11 BodyText„¤Ü^„CJB @BFooter$d Æ9r OJQJ>@">Header Æ  ø%OJQJ>þO2> 22 BodyText„% ¤Ü^„% .@Q.TOC 1OJQJ^þOR^ Heading 1TOC! Æâ‘ „â„ý¤x^„â`„ý 5B*CJªþObª Bulleted - 1t & Fÿ„w„›þ¤Ü>ÆTÿe-ð^„w`„›þCJ¬þOr¬Numbered List 1t & Fÿ„w„›þ¤Ü>ÆT€e.^„w`„›þFþOq‚FNumbered List 2 „Š ^„Š CJ6@’6 Footnote Text¦þO¢¦ Bulleted - 2t & Fÿ„Š „›þ¤Ü>ÆTÿe-ð^„Š `„›þ>Á>TOC 2„‰„Xý^„‰`„XýOJQJ\þOÂ\ Heading 2TOC! Æ‹‘ „‹„Wý¤(^„‹`„WýB*CJ6á6TOC 3„Ý„­ü^„Ý`„­ü\þOâ\ Heading 3TOC! ÆÜ‘ „Ü„¯ü¤P^„Ü`„¯üB*CJDþOòDDocument Title¤€5CJ$DDTOC 4 Æ ‘ ‰‡ „  „<ü^„  `„<üXþOX Heading 4TOC! Æ¢ ‘ „¢ „:ü^„¢ `„:üB*CJ::TOC 5 "„ ^„  CJOJQJ::TOC 6 #„è^„è CJOJQJ::TOC 7 $„°^„° CJOJQJ::TOC 8 %„x^„x CJOJQJ::TOC 9 &„@^„@ CJOJQJ@Yr@ Document Map'-D OJQJJþO‚J CellBody (¤P¤PB*OJQJmH sH uTþO’T CellHeading )¤x¤x5B*OJQJmH sH uVþOòV Heading 02 *$¤h5B*CJOJQJmH sH uTþO²T Nonum Heading +1$¤x¤d5CJ$htH u0U@¢Á0 Hyperlink>*B*@V@¢Ñ@ FollowedHyperlink>*B* PþOâP Abstract .d,¤ðB*CJOJQJmH sH u¼þOò¼ Bulleted/ & Fÿ Æh„„åþ¤x>ÆTÿ·ð·······^„`„åþB*CJmH sH uRþOR BulletedCont0„¤P^„B*CJmH sH uRþOREquation1d¤È¤x Æ‘  B*OJ QJ BþO"B Figure 2¤x¤6B*mH sH uVþO2V Footnote3 Æä„ä„ÿ¤<^„ä`„ÿB*mH sH ubþOòb Heading 014$$¤ð¤@&d5B*CJ OJQJmH sH uL#LTable of Figures5„„pþ^„`„pþRþObR Numbered6 & F>¤x ÆB*CJmH sH u°þOr° Reference|7 & Fÿ Æ7„„åþ¤x>ÆT€[]^„`„åþB*CJRþO‚R SubTitle8$$d@a$5B*CJmH sH uNþOòN TableTitle9¤x ÆT6B*mH sH u,X@òÿ¡, Emphasis6>þOòÿ±> EquationVariables6>þOòÿÁ> ProgramCodeCJOJQJkH'.þOòÿÑ. SubscriptH*2þOòÿá2 SuperscriptH*4þOòÿñ4 SymbolCJOJQJkH*>þOòÿ> Underline>*CJOJQJkH'6"6Caption A¤x¤x6.)@¢!. Page NumberBþOñ2B DocumentOwnersC$a$CJDZ@BD Plain TextDOJQJmH sH udþObd Definition List E„h1$^„hCJOJQJhmH sH tH u`þOR` Definition Term F1$¤d¤dOJQJhmH sH tH uHþOñrH Editors NotesG6B*CJOJQJBþOñ‚B Code SnipetH¤x CJOJQJ^þO^ H1I$ & F1$¤ð¤d@&%5CJ(KH$OJQJhmH sH tH uZþOZ H2J$ & F1$¤d¤d@&!5CJ$OJQJhmH sH tH u0þOòÿ±0 Definition6TþOT H3L$1$¤d¤d@&!5CJOJQJhmH sH tH uTþOT H4M$1$¤d¤d@&!5CJOJQJhmH sH tH uPþOP H5N$1$¤d¤d@&5OJQJhmH sH tH uTþOT H6O$1$¤d¤d@&!5CJOJQJhmH sH tH uPþOP AddressP1$!6CJOJQJhmH sH tH ujþOj BlockquoteQ„h„h¤d¤d1$]„h^„hCJOJQJhmH sH tH u$þOòÿ!$ CITE6,þOòÿ1, CODE CJOJQJ8þOòÿA8 Keyboard5CJOJQJxþORx Preformatted+U1$ Æ# ¿~= ü»z9ø·!v%OJQJhmH sH tH un]@ñÿnz-Bottom of FormV$$d1$a$"<CJOJQJ_HhmH sH tH h\@ñÿh z-Top of FormW$&d1$a$"<CJOJQJ_HhmH sH tH ,þOòÿ, SampleOJQJ8þOòÿ‘8 Typewriter CJOJQJ,þOòÿ¡, Variable64þOòÿ±4 HTML Markup<B**þOòÿÁ* Comment<\þOâ\ Title1]$¤ð¤d1$a$!5CJ0OJQJhmH sH tH ubþOâb Subtitle1^$¤x¤d1$a$!5CJOJQJhmH sH tH uPþOòP RFC-P1_„°¤ð^„°CJOJQJmH sH tH uZþOZ Param$` & F¦„e„›þ¤P¤(1$^„e`„›þhmH sH tH uTþOT CODECompacta1$CJOJQJhmH sH tH u4þO14 Title Textb56þO26 00 BodyTextc¤Ü4þOB4Bullet 1 d & FØÿÿÿÿÿÿÿÿ ÿÿØ6ÿÿÿÿ'EM^œÜ-m§è+i¨ÒÓY˜Ù[ß%g¤å+m±ÜÝ!AC`‚¤®çñ{ ° Ñ ò > j É ü  d à ÷ * _ “ ´ ý ) \ } ž ê I}°å9ƒ¥ÒÓÔÕêÿ Fmn»×æêò.PQž©­®y$&'OPaw³Æ {–ŸØÙ¤¥ÀÉIÎÏÐÒÓÕÖÙ˜0€€˜0€€p˜0€€p˜0€€p˜0€€p˜0€€p˜0€€p˜0€€˜˜0€€˜˜0€€˜˜0€€˜˜0€€˜˜0€€p˜0€€p˜0€€p˜0€€˜0€€p˜0€€p˜0€€˜0€€p˜0€€p˜0€€˜0€€p˜0€€p˜0€€˜0€€p˜0€€p˜0€€˜0€€p˜0€€p˜0€€˜0€€p˜0€€p˜0€€˜0€€p˜0€€p˜0€€p˜0€€p˜0€€p˜0€€p˜0€€p˜0€€p˜0€€p˜0€€˜0€€p˜0€€p˜0€€˜0€€p˜0€€p˜0€€˜˜0€€˜˜0€€p˜0€€p˜0€€p˜0€€˜0€€p˜0€€p˜0€€p˜0€€p˜0€€˜˜0€€p˜0€€p˜0€€˜˜0€€˜˜0€€˜˜0€€p˜0€€p˜0€€˜˜0€€˜˜0€€ €˜0€€€˜0€€˜˜0€€˜˜0€€˜˜0€€˜˜0€€˜˜0€€˜˜0€€˜˜0€€˜˜0€€˜˜0€€ €˜0€€p˜0€€p˜0€€p˜ !0€€p˜0€€p˜0€€p˜ !0€€˜ !0€€p˜ !0€€p˜0€€p˜0€€˜ !0€€˜˜0€€p˜0€€p˜ !0€€p˜ !0€€˜˜0€€p˜0€€˜0€€p˜0€€˜0€€˜0€€˜0€€˜0€€˜ !0€€˜ !0€€˜ !0€€˜ !0€€˜ !0€€˜ !0€€˜˜@0€€ø€˜@0€€p˜@0€€p˜@0€€˜@0€€ø€˜@0€€p˜@0€€€˜@0€€ø€˜@0€€p˜@0€€p˜@0€€€˜@0€€ø€˜@0€€p˜@0€€€0`Ø0€€˜0€€˜0€€˜0€€€˜0€€€'EM^œÜ-m§è+i¨ÒÓY˜Ù[ß%g¤å+m±ÜÝ!AC`‚¤®çñ{ ° Ñ ò > j É ü  d à ÷ * _ “ ´ ý ) \ } ž ê I}°å9ƒ¥ÒÓÔÕêÿ Fmn»×æêò.PQž©­®y$&'OPaw³Æ Ùš0€€š0€€š0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€È˜0€€È˜0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€È˜0€€˜0€€˜0€€€˜0€€€˜0€€€˜ !0€€€š0€€š0€€š !0€€š !0€€€š !0€€€š0€€€š0€€€š !0€€€š0€€€š0€€€š !0€€€š !0€€€š0€€€š0€€€š0€€€˜0€€€˜0€€€˜0€€€˜0€€€˜0€€€¬:0i€¬:0i€¬:0i€¬:0i€¬:0i€š !0 €€€^^*ˆTWèPØ!g >¥ž Ø!×!&P[Pz…W4ÿ•€4ÿ•€ð@ð  @ñÿÿÿ€€€÷ð ððxð( ð ð𜢠ð c ðR€Š¿ÿƒÃ.¿ ``T`T`T`T"ñ¿€ðð ð𜢠ð c ðR€Š¿ÿƒÃ.¿ ``T`T`T`T"ñ¿€ðð ðð’ðð0ð( ð ððB ðS ð¿Ëÿ ?ð*W¸ÿÿÿòÿÿÿSýµ@¸ÿÿÿòÿÿÿSýµ@ÿÿãÁf¤Ý&4ÙDÙ8*€urn:schemas-microsoft-com:office:smarttags€date€ €10€13€2003€Day€Month€YearTx+z{ÏÐÖÙVy{ÏÐÙTxzzÙswxx{ÏÐÙÿÿ Lothar MerkMerkMerkMerkMerkMerk Thomas KleinIBM-UserIBM-UserPeter ThompsonüûÿÿÿÎÜÖ-ÿÿÿÿÿþÿÿÿÿÿÿÿÿÔhXíz@ÿºo:éÈuÿzS0à–ÀÿXlhdmÿÿÿÿÿÿÿÿÿ'5ÄáÚÞÿÿÿÿÿÿÿÿÿ¢M‹ ÿ1Í ÿB-6ïr-ÿµÚj?fÿ4 tj?fÿ$Ù ÿö[' ÿ†ld0à–Àÿ„m"0à–Àÿvj?fÿßhš6ïr-ÿÿÿÿÿÿÿÿÿZk¤V"ÙÿßQ±š…6$ÿt-j?fÿñI% ÿÿÿÿÿÿÿÿÿGB j?fÿ…'”  ÿ¹¨ ÞaÊ–ÿ›}þ šŠƒÿ»@I 0à–Àÿ$0< 0à–Àÿo j?fÿŒ@  ÿ ¾  ÿà:.j?fÿO{Qj?fÿÿÿÿÿÿÿÿÿ¯F‰0à–ÀÿÀdÚ ÿVVU ÿ@I P´ eÿ`ç ò\ÿºY ÿ:ksP´ eÿêN†ÿzh ~`V÷ÿÿÿÿÿÿÿÿÿ¿Al0à–ÀÿtQcÿRùV"ÙÿTrròz ­ÿ?ÎfØFÿÿÿÿÿÿÿÿÿ ˆ ÿü=êj?fÿ‘,WXÊÿOuðj?fÿ3v䆸ŸÿÿÿÿÿÿÿÿÿîXjj?fÿ­IXÊÿ™öÄáÚÞÿÊ• ÿÁi³ ÿOË0à–Àÿ’ý$h"—ÿÿÿÿÿÿÿÿÿ _Ej?fÿàN˜éÈuÿÿÿÿÿÿÿÿÿK» ÿ®T0à–Àÿ/9[0à–ÀÿC_‡ ÿ‰bÞj?fÿL{0à–Àÿ·PÔj?fÿKL8 6ïr-ÿÑÆ j?fÿxcÈ 0à–ÀÿÙï šŠƒÿ±T!0à–Àÿœ¦!šŠƒÿaU¶" ÿêv·"$h"—ÿÿÿÿÿÿÿÿÿ•mØ" ÿ+K#j?fÿ½m$¶k@rÿIÿÿÿÿÿÿÿ_P‰$0à–Àÿ FÜ$اÔÿÿÿÿÿÿÿÿÿ‚l%0à–Àÿ©>@% ÿJVX%x,µÿ n&j?fÿL«' ÿ¾E¤)4-¢ ÿï)0à–Àÿ{k* ÿ r*j?fÿÿÿÿÿÿÿÿÿPCs*j?fÿÓH +ÿ7 ..žŒ6•"o.ÄáÚÞÿPi‘0øˆ-`d<ç0 ÿb;¡1ÄáÚÞÿ^G¨1V"Ùÿþ1Ã10à–Àÿßê10à–ÀÿÙ$2j?fÿd*Ž20à–Àÿ@Ÿ2ÄáÚÞÿrA°2䆸Ÿÿ2.3 ÿ¤FP3P´ eÿ$F50à–ÀÿÙ*7ÄáÚÞÿ”2§7j?fÿÿÿÿÿÿÿÿÿéMA8éÈuÿp(þ8 ÿ@ Ö9täŽýÿ¥}: ÿïcš:ì=.ÿÈFÅ:0à–Àÿ­ ;V"Ùÿ‘q};FîNÿ§-­;j?fÿ‰‰j?fÿŽ3™>éÈuÿÿÿÿÿÿÿÿÿçA7@j?fÿ®?l@j?fÿÊÅ@ E^xÿÿÿÿÿÿÿÿÿZæA ÿãUóAj?fÿ÷ùB0à–ÀÿuqCj?fÿF_C$h"—ÿÏC ÿã)DP´ eÿdKEj?fÿ.E ÿGuXE0à–Àÿ5t€Ej?fÿ{‡E0à–Àÿâ—EÄáÚÞÿÿÿÿÿÿÿÿÿp«EÄáÚÞÿÿÿÿÿÿÿÿÿŽx¸E ÿäE0à–Àÿ:¤F ÿ· ¦FV"ÙÿqJ«F4-¢ ÿtMG0à–Àÿt?Gj?fÿÛqBGj?fÿf»G ÿ–)Hj?fÿTVHØ"Žgÿÿÿÿÿÿÿÿÿ 6pH4-¢ ÿB›HÀDâŒÿÿÿÿÿÿÿÿÿGÁHÿ.PbJ ÿÐ{­KÄáÚÞÿÿÿÿÿÿÿÿÿIN™LÄáÚÞÿÿÿÿÿÿÿÿÿb-³Lÿðk‘Mj?fÿs#ºM ÿ#tÑN0à–Àÿ„$‡OXÊÿ>PšŠƒÿƒt¡PV"Ùÿ§!FQj?fÿ¡0ËQéÈuÿÃLôQ ÿÓT ÿ´g^Tj?fÿ`•Tt(øxÿ^F»TP´ eÿh ØU ÿc{V ÿx-^V0à–ÀÿõeWTñ–ÿr»WšŠƒÿv\YŠ Iÿs˜Y ÿj:šYéÈuÿÿÿÿÿÿÿÿÿÛp¦Y ÿúSC[j?fÿŒ&H[ ÿÕ=j[šŠƒÿ¹Hˆ[ÄáÚÞÿÿÿÿÿÿÿÿÿ}¤[ÄáÚÞÿ+%?\Xíz@d9+]$h"—ÿÿÿÿÿÿÿÿÿT"í] ÿí57^ÄáÚÞÿ·U•^0à–Àÿ0K_0à–Àÿ~`j?fÿ`Gû`؉¨Àÿÿÿÿÿÿÿÿÿ"AaìzÐeÿ_[`bP´ eÿ~c¬é„mÿÿÿÿÿÿÿÿÿ+ ‘cˆnªÚÿÿÿÿÿÿÿÿÿ`&d0à–ÀÿÜh‡d0à–ÀÿVDŠdj?fÿÇm½dØybzÿ³5ÿe0à–ÀÿaJƒgÄáÚÞÿÿÿÿÿÿÿÿÿo 5h0à–ÀÿÎ#Öh ÿÓøiÿVRekÄáÚÞÿÿÿÿÿÿÿÿÿøt5lÄáÚÞÿÿÿÿÿÿÿÿÿv2ÐlÄáÚÞÿÿÿÿÿÿÿÿÿmÄáÚÞÿÿÿÿÿÿÿÿÿ [ynÄáÚÞÿ=xòn ÿ?4®oÿ³oÿ8>Rp ÿ$rÄáÚÞÿŽyLsj?fÿlt6ïr-ÿÿÿÿÿÿÿÿÿ×8¥tüÆ®|ÿÿÿÿÿÿÿÿÿHqªtÿ8+•uP´ eÿà[–uÿ“*©u$h"—ÿÿÿÿÿÿÿÿÿgYÂu ÿÇa)vP´ eÿÇ|$w¾ú ÿA3wj?fÿ,®w0à–Àÿ×:ExÄáÚÞÿÿÿÿÿÿÿÿÿ<=Ûx ÿºgßx6ïr-ÿÿÿÿÿÿÿÿÿö yÿÚd/yj?fÿpioyj?fÿCooyj?fÿÍ|zz´:B7ÿÿÿÿÿÿÿÿÿ†{ ÿ›t´{ÿÿÿÿÿÿÿÿÿÿÿÿÿ 4Ð{6<½ÿSï{j?fÿÝI'|$h"—ÿÿÿÿÿÿÿÿÿ^Š|j?fÿH)õ| ÿ’A}0à–Àÿ+2}ÄáÚÞÿÿÿÿÿÿÿÿÿ`}ÄáÚÞÿhMÆ~j?fÿ%8î~0à–Àÿl^0à–ÀÿÚP›}þ KL8 r»WÙï †ld»@I GuXE$F5ï)$0< ,®w³5ÿe¯F‰zSéMA8ºo:¿Al±T!x-^V%8î~d*Ž2’A}„m"#tÑN‘q};äE‚l%l^þ1Ã1Üh‡dtMGßê1xcÈ ®T_P‰$7 .0K_ÈFÅ:OËo 5h·U•^{‡E`&d÷ùBL{/9[TrrúSC[~`–)H _E§!FQdKE§-­;´g^TîXjÑÆ Cooy‰bÞ8 ÙvPCs*Úd/y5t€E®?l@pioyhMÆ~ŽyLs^Š|‰‰<Sï{ÚOuð n&4 tü=ê·PÔÇm½d¢M‹Óøi¹¨ à[–uHqªt?4®oÓH +ö y³o…'” ÃLôQþÿÿÿ”šþÿÿÿèšþÿÿÿL›Ž3™>aJƒgêv·"9+]VRek“*©u’ý'5ÝI'|+2}¹Hˆ[O{Qv2ÐlÐ{­K×:Exøt5l r*â—Ep«EmIN™L”2§7ºgßxßhšltj:šYàN˜Ûp¦Ys#ºM$Ùp(þ8+K#H)õ|Ç|$wþÿÿÿ°› ˆ¥}:™öh ØU†{gYÂu ¾ Ù*7$rPi‘0í57^ºY`} [yn@Ÿ2þÿÿÿœ•"o.b;¡1}¤[<=Ûx`Gû`B-`ç•mØ"Žx¸EçA7@GB {k*t?Gc{VÎ#ÖhÏCA3wÁi³8+•uVVUVDŠdo Ù$2K»µÚÊ•"AauqCðk‘MÛqBGT"í]L«'8>Rp.PbJF_Cþÿÿÿxœ©>@%ZæAs˜YaU¶"7 .àœŒ@ ö['ÀdÚ_[`bìœ.E‹6¢TuF=`•TJVX%JVX%øœv\Yïcš: 4Ð{@I ­I„$‡O‘,W@ Ö9RùqJ«F¾E¤) 6pHRù­ ;Zk¤^G¨1ƒt¡PÚGè· ¦FÇa)v¤FP3^F»Tã)D:ks"Aat-ÓTõeWõeWßQ±ßQ±(d<ç0b-³LtQcêN†GÁH2.3+ ‘c+%?\3vrA°2Ôhþÿÿÿþÿÿÿ4ÿþ×8¥tÿÿÿÿÿÿÿÿp™` ˆ@e „w„›þ^„w`„›þOJQJo(-ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÔ™`m@h „Є˜þ^„Ð`„˜þOJQJo(·ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ8š`l@„„åþ^„`„åþCJOJQJo(·ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ š Ê@CJ$OJ QJ o(" ÿÿÿÿôš @e „Š „›þ^„Š `„›þOJ QJ o(·ðÿÿÿÿX›`c@e „Š „›þ^„Š `„›þOJ QJ o(-ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¼› @e „w„›þ^„w`„›þOJ QJ o(·ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ œ @e „w„›þ^„w`„›þOJQJo(-ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„œ s@„„åþ^„`„åþCJOJQJo(·ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ@ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ@ @h„„^„`„OJQJ^Jo(·ðÿÿÿÿÿÿüÿÿü    å‰MGu#N§%“ièÄ{ÏÐÙÿ@€xx¤oxxØ`@ÿÿUnknownÿÿÿÿÿÿÿÿÿÿÿÿ G‡z €ÿTimes New Roman5€Symbol3& ‡z €ÿArial?Courier Neu?5 ‡z €ÿCourier New71 Courier=" HelvArial;" Helvetica5& ‡za€ÿTahoma3Times;€Wingdings]& Rotis Sans Serif for Nokia"ˆVüe ;H&Žjz&9üG&Dú ƒ*ú *$Vü¥À´´€4dppiœ5Î2ƒQVüßßHðÿ?äÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ièÿÿReference Toolkit Specification Hezel, UwePeter Thompsonüü                           ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~  € ‚ ƒ „ … † ‡ ˆ ‰ Š ‹ Œ Ž ‘ ’ “ ” • – — ˜ ™ š › œ ž Ÿ   ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ ­ ® ¯ ° ± ² ³ ´ µ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿ À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ ß à á â ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö ÷ ø ù ú û þÿà…ŸòùOh«‘+'³Ù0˜ÀÌàì $ @ L X dpx€ˆä Reference Toolkit Specificationefe Hezel, Uweoeze Normal.dotoPeter Thompsoni28eMicrosoft Word 10.0@˜Þ @. Kû¿@®Uñ¢À@¼žd­‘ÃúþÿÕÍÕœ.“—+,ù®DÕÍÕœ.“—+,ù®L hp|„Œ” œ¤¬´ ¼ èäIBM* p­  Reference Toolkit Specification TitleP :B_PID_LINKBASEäA þÿÿÿ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNþÿÿÿPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹þÿÿÿ»¼½¾¿ÀÁþÿÿÿÃÄÅÆÇÈÉþÿÿÿýÿÿÿýÿÿÿÍþÿÿÿþÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿRoot Entryÿÿÿÿÿÿÿÿ ÀFû„­‘ÃÏ€Data ÿÿÿÿÿÿÿÿÿÿÿÿàd1TableÿÿÿÿO¤ÔWordDocumentÿÿÿÿ86SummaryInformation(ÿÿÿÿÿÿÿÿÿÿÿÿºDocumentSummaryInformation8ÿÿÿÿÿÿÿÿÂCompObjÿÿÿÿÿÿÿÿÿÿÿÿjÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿ ÿÿÿÿ ÀFMicrosoft Word Document MSWordDocWord.Document.8ô9²qlibsynthesis-3.4.0.47.1/src/syncml_tk/doc/ReadmeMaintenance4_3.doc000066400000000000000000003360001226375725500245420ustar00rootroot00000000000000ÐÏࡱá>þÿ ÙÛþÿÿÿרÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿì¥ÁE@ ø¿Ð,bjbjƒæƒæ 8HáŒáŒs"UÿÿÿÿÿÿˆBBBB¶¶¶Ê’E’E’E8ÊE$îEDʸÓì>F>F(fFfFfF"I"I"I7Ó9Ó9Ó9Ó9Ó9Ó9Ó$¤ÖRöؘ]Ó¶ÚIâHâH@ÚIÚI]ÓBBfFfF|rÓ¼J¼J¼JÚI^BfFBRfF7Ó¼JÚI7Ó¼JÀ¼J|K’½¶ÊB”"ƒÒ$fF2F PNC¨œÃ’E8J‡ÎþÛÒ\ˆÓ0¸Ó…ÐþŽÙTJLŽÙü§ÒÊÊBBBBŽÙ¶§Ò4"I6I¼JDI PIŠ"I"I"I]Ó]ÓÊÊä®3ä JÊÊ®3SyncML Reference Toolkit Specification Release 4.3 October 27, 2003 READ ME Copyright Notice Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). All Rights Reserved. Implementation of all or part of any Specification may require licenses under third party intellectual property rights, including without limitation, patent rights (such a third party may or may not be a Supporter). The Sponsors of the Specification are not responsible and shall not be held responsible in any manner for identifying or failing to identify any or all such third party intellectual property rights. THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. The above notice and this paragraph must be included on all copies of this document that are made. File and Directory Structure The SyncML Reference Toolkit file tree is structured as shown in the following figure. Within syncml/src/sml the files of the toolkit itself are found. The transport handlers are stored in the directory syncml/src/xpt. Demos showing syncml at work will be organized within syncml/src/app. syncml ------ docs ----- internal ! !---- bin ------ win Binary files (like dlls) ! !---- src ------ sml ------ inc ------ win Public Headers ! ! ! ! ! !--- palm ! ! ! !--- mgr ------ inc SyncML Core (Manager) ! ! ! ! ! !--- all ! ! !--- win ! ! ! !--- wsm ------ inc SyncML Workspace ! ! ! ! ! !--- all ! ! !--- palm ! ! !--- win ! ! !--- linux ! ! !--- epoc ! ! ! !--- xlt ------ inc SyncML En-/Decoder ! ! ! ! ! !--- all ! ! ! !--- lib ------ inc SyncML Library Funct. ! ! ! !--- all ! !--- win ! !--- xpt -- !--- bindings Transport Handlers ! !--- common ! !--- all ! !--- linux ! !--- macosx ! !--- palm ! !--- tcp ! ! !--- all ! ! !--- linux ! ! !--- macosx ! ! !--- palm ! ! !--- win ! !--- win !--- http ! !--- all ! !--- linux ! !--- macosx ! !--- palm ! !--- win !--- obex ! !--- palm ! !--- smlobex ! !--- win !--- wsp !--- all !--- awsp !--- inc !--- palm !--- win Supported Platforms The SyncML Reference Toolkit has been implemented to be portable to as many hardware platforms and operating systems as possible. Nevertheless it is not possible to achieve an full platform independent code. The SyncML consortium therefore focusses on the following platforms: Windows 32 The deliverables target Windows 95 and NT 4.0 and comprise: Source Files. Several subdirectories named ../win hold files specific to the Windows target (e.g. syncml/src/sml/wsm/win). When compiling all these Windows-directories must be included. All other directories, which hold files specific to other targets must be excluded (e.g. ../palm; ../epoc)! The source code was developed using the following development environments : Microsoft Visual Studio C++ IBM Visual C++ GCC Palm-OS The deliverables target Palm OS 3.5 to OS 5.0 and comprise: Source Files. Several subdirectories named ../palm hold files specific to the Palm target (e.g. syncml/src/sml/wsm/palm). When compiling all these Palm-directories must be included. All other directories, which hold files specific to other targets must be excluded (e.g. ../win; ../epoc)! The source code was developed using the following development environments : Metrowerks GCC The Toolkit for Palm runs on Palm OS 3.1 too. Due to limitations of that version of the operating system, the size of the workspace is restricted to maximim 50kBytes. Not really recommended these days. LINUX To compile and run SyncML under a Linux Platform, the Win32 source code is used. Please follow the instructions in the README.linux file in the “src/bld” directory. Changes in the Maintenance 4.3 Release Fixed win .def files to work with NOWSM flag. Added extra #ifdefs to work with the NOWSM flag. Removed extra copy of the syncml_tk_prefix.h file. Fixed the problem – should apply to other similar flags. Changes in the Maintenance 4.2 Release OBEX bugs fixed. Added MacOSX support. Added SSL support for PalmOS 5.0 (alpha) and PocketPC 2002. Updates for Linux. Memory change to allow you to not use the toolkit memory structure. Added support for SyncML 1.1.1. New API function smlStartMessageExt() with parameter to specify SyncML version. Changes in the Maintenance 4 Release Obex transport binding was fixed to work properly with the XPT communication API. Sofar it’s only tested on Win32 systems running Windows 2000 (OBEX / IR and OBEX / TCP/IP) Implementing several DTD changes to support device management Implementing new extension for “Progress Information” usind a new tag “NumberOfChanges” Implementing new extension for “Large Object Handling” using a new flag MoreData for Item-Tags Implementing new extension for “Large Object Handling”, new API to calculate remaining space for data after setting up the tag-structure skeleton Implementing new extension to transport toolkit to support cryptographic security against manipulation during transport, new header field “x-syncml-hmac” (HTTP and OBEX only, not WSP) Bug fix for an Microsoft IIS-Hack in HTTP transport binding Bug fix for a minor bug causing the HTTP transport binding toolkit part to crash if message type string is longer than allowed 4.1: Declarating function ltoa() in linux-special file src/xpt/bindings/http/linux/xptihttp.h 4.1: Adding support for ‘SupportLargeObjs' and 'SupportNumberOfChanges' tags in device information dtd  SyncML Reference Toolkit Read Me  SAVEDATE \@ "yyyy-MM-dd" \* MERGEFORMAT 2001-09-18 Copyright © Ericsson, IBM, Lotus, Matsushita Communication Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). All Rights Reserved.  SyncML Reference Toolkit Read Me  SAVEDATE \@ "yyyy-MM-dd" \* MERGEFORMAT 2001-09-18 Copyright © Ericsson, IBM, Lotus, Matsushita Communication Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). All Rights Reserved.   '>DEM]@AB_½Ë*8p~€”¢Ëä%_aøñêÛøËÀ¸®Ë¢–¢Š¢–¢|x®m®`®`®`U®`®hu#N6CJOJQJhu#N56CJOJQJhu#N<CJOJQJhu#Nhu#NB*CJOJQJphhu#NB*OJQJphhu#NB*OJQJphhu#NB*OJQJphhu#NCJOJQJhu#NOJQJhu#NCJOJQJhhu#N5B*CJOJQJphh“iè5CJ$mH nH sH u h“iè5CJ$ hóU°5CJ$ hu#N5CJ$'EM^œÜ - m § è + i ¨ Ò Ó  Y ˜ Ù  [ ß % g òòòçåååååååååååååååååååååå $¤h1$7$8$H$ $¤€1$7$8$H$a$s*È,Ï,ýýýg ¤ å +m±ÜÝ!A_€£­æðz¯ÐH{®ÏýýýýýýýýýòâÚÏÏÏÏÏÏÏÏÏÏÏÏ d@ÿ1$7$8$H$1$7$8$H$ Æ&¤x¤x1$7$8$H$ 1$7$8$H$gd CeÏBu©ÜEf¯Û/{§Ú -w£ÙQËHôôôôôôôôôôôôôôôôôôææææææææ d@ÿ1$7$8$H$gdN7 d@ÿ1$7$8$H$abœ®eyzcuw9:tu°±ëì'(8Mblm©µÕÛ "½Í L M T U x ‚ ‘ ½ Ä ò !¡!°!""·"Û"Ü"öìßìßÕìßìöËöËöËöËöËö»·©™·”·Œ·Œ·Œ·”·©™·ˆ·”·Œ·Œ·Œ·”·„·h§%h‰MGhu#NOJQJ hu#N5hu#N5B*CJOJQJphhu#N5B*OJQJphhu#Nhu#N5B*CJOJQJphh CeCJOJQJhu#NCJOJQJhu#N56CJOJQJhu#NCJOJQJhN7CJOJQJ4HŒÑV‘Å={·ò&b¡ÜJ†Áý8MbñññññññññññññññññññññÚÒ1$7$8$H$$ Æ@„°„Pþ¤ 1$7$8$H$^„°`„Pþ d@ÿ1$7$8$H$gdN7bm©ÐÑ : I M U ‘ ³!´!" """Ü"â"‡#‰#èàÉààÉÉÉèàÉààÉÉààè¾² Æh1$7$8$H$ 1$7$8$H$gd“iè & F  Æh„h„˜þ1$7$8$H$^„h`„˜þ1$7$8$H$$ ÆÐ„°„Pþ¤ 1$7$8$H$^„°`„PþÜ"á"â"†#‡#ˆ#Š#²#Š$¦$¨$²$³$Ã$Ä$S%l%m%Ž%Ü%Þ%&$*q*s*t*™*š*Ã*òâÞ×ÇÞ·«Ç›Çƒƒwƒwhw·«Q«IÞIÞjhu#NU-hóU°B*OJQJhmHnHphsHtHuh‰MGh‰MGB*OJQJphh‰MGB*OJQJphh“ièB*OJQJphhu#NB*OJQJphh“iè5B*CJOJQJphhóU°B*OJQJphhóU°5B*CJOJQJphhu#N5B*CJOJQJph h“ièhu#Nhu#Nhu#N5B*CJOJQJphhu#N5B*OJQJph‰#Š#²#³#á#$E$Š$²$³$Ä$Ú$%)%m%Þ%&÷å×ÆÆÆÆ·¬žžžžžå & F dð1$7$8$H$gd‰MG & F dð1$7$8$H$ dð1$7$8$H$$ Æ@¤ 1$7$8$H$ & F dð1$7$8$H$gdóU° dð1$7$8$H$gdóU°$ Æ@¤ 1$7$8$H$gdóU°1$7$8$H$&&²&ð&H'§'9(ñ(-)¬) *r*s*Ž*—*Ð*Ñ*+œ++¸+Á+ú+û+A,ñààààààààààñÜÜÜÚÕÕÚÜÜÜÚÕ$a$¤  & F dð1$7$8$H$gdóU° dð1$7$8$H$gdóU°Ã*Ä*Î*Ï*Ý*+‡+›+œ++ž+Ã+Ä+í+î+ø+ù+,±,Ç,È,É,Ë,Ì,Ï,Ð,÷ó÷óäßóÙó÷ó÷ó÷ó÷óäóÕËóÁóµhóU°B*OJQJphjp2hu#NCJUjhu#NCJUh Ce hu#NCJ hu#Nhhu#NhmH nHsH tHuhu#Njhu#NUA,Æ,Ç,È,Ê,Ë,Í,Î,Ï,Ð,úøøøøøøøê dð1$7$8$H$gdóU°$a$ 6 00P P &P °‚. °ÆA!°8"°8#p$R%°°Þ°2p2Dd&& `+`+ffð<² ð C ðA¿ÿðÂbðà1„oœÅr<,;ÖFQ[‡¬bÿ¼1Dcnð´1„oœÅr<,;ÖFQ[‡¬bÿ‰PNG  IHDR&&è¬ÖgAMA±ˆ•˜ô¦ pHYs ø øf&<ý IDATxœíÝytU¢Çñºˆö"$ÄƃèÂ.Žì0 ‹¨Œ ›(F‘a—qæ Ûˆ ‚ìˆG}"¢(úØQGD-ÀŒ$  D ô}Ü¡^Ñtª·Û ù~þð`§êÖ­êêúÕ½u«Ê0Üà„¡®ܨÂöZ!Ô(¹±Âv«@Ø’R†!„Pÿ+á9Jxn/sá|²¾‘ãp8âããC] ¸ÁüòË/N§3Ôµ(Y˜FŽ”2>>>+++Ô€LBBBvvvx¶u¡® ¼ rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBäØ"¥tùG™S\9¶!\þ¡¸Œ9Ù.*„º7)¥âÂ… §N:~üøéÓ§333 OŸ>m†ÓéT“ !TÒÔ¬Y³R¥JIII5jÔ¸õÖ[ãããëׯo–€"rJ ¥,,,|áÂãZl¨h1ÿaåÒÐQÓDFF&$$$$$4lذQ£FÉÉÉ­ZµºõÖ[ !„ÊùóçKk‹ !ªU«vCì™RÊüüü¢¢¢ÿêp8ªU«Vâ\çÏŸwù0**ªråʯ"œÚÑëׯ/µ+**Ú²eËàÁƒ+Uª$„B8ŽÀþðÌ2G\\܈#þõ¯é_S”gN§SJ™ Jáp8<êjÚråʕڵk—¶"Íš5S+ëâܹsê—h=zt‰ßpTŸJxž1p-ç¿òòò^|ñŤ¤¤6mÚ¬\¹²°°Ð0 !„ÙiªÅ£†‘““³lÙ²Ž;¶k×nñâÅ—.] ಀҨƒ‘uo´Rýè£B]M[–.]zöìY÷µ0,«YâŒÒ2&Èe‘c†±bÅŠ;ï¼óå—_>qâ„qm_T{¡Ãá  T»µu)ßÿýèÑ£[¶l¹aÆ@- ð¬´[í“~ø¡æúøàÊ•+Ó§O/mET“¥´yÝÿÀ_:JSN#ÇÜ·V¯^Ý´iÓ!C†;vÌ¥M­& l+Ç0 §Ó©ÊtY”ò§Ÿ~êÞ½{‹-V¯^Ø…î<a322–-[f*å‰'fee•ø§2ë,¯u0¡^(U9Ã0Š‹‹Ç׿ÿ„º.ÿ¥ú4222ú÷ï?lØ05Z )åSO=uîÜ9#\»›233ßxãP×Þ)‘#¥¼råJ·nÝæÍ›g„ÓÏIõ­«3¯wß}·mÛ¶G u¥P~åçç¿òÊ+¡®E©V­Ze„q %*‘ãt:‡þå—_šÿë[9%Ž1?÷¡@ë5LÕÏÖºuëÍ›7ûV=À>—}ظ¶7¾þúëÿþ÷¿C[·]¾|yÉ’%êßî•GØ*‘3uêÔ÷ßß°âýdŒýU gÏžíÛ·ïÙ³gý¯$`“õwqùòå7ß|3´õ)ÑìÙ³­YHØÜ(Ê]äüðÃ/½ô’ˆö¸‡Q•þ:0ögÏž4hPÀG1Vê,Çá¸î€ ZÛ|ðAqqq¨*æÂüQL:Õ°üŠé^»Q”£§H)sss|ðAkç•EIMkܸqƒ êÖ­[«V-óÃâââ“'Oæåå?þàÁƒyyyòÚ£ „Çx¨³a›6mJKKãJ)‚Gí–ÉÉÉõë×߸q£aÙÛ³²²fÍš5qâÄVð:?þxAA¼þɃþæ›oÔ}€DО>0iÒ$ßêãp8Ôý4qqq¯¼òŠºõ¬Ä•Í‹ŠŠ80kÖ¬:”xÉÇ>µè-[¶|ƒ qß]+UªtìØ±P×÷¿Ö¯_ïò#BÔ©S''''!!Áå·“’’Rb!j$ž‹Q£Fi^— áéa¡¨¨héÒ¥¾Íët:£££§OŸ~øðáñãÇ׬YÓ(å5?ŒˆˆhÒ¤Éøñã¿ùæ›Ï>û¬^½z†O# ÌVѧŸ~*Ãû& Üè„]ºt‰u¹$YXX¨:²ÂÁßÿþw—‘”rüøñµk׿§þÊQä8pàÌ™3>Ì(¥Œß¾}ûĉcbb ïú={öܳgOÿþýÍOì¼Ö{ Nî$EÐH)£££'L˜`žÜ˜»Ü²eË233C]AcË–-[·nuùV«Ví±Ç3Âõ¼Vå(r¾ýö[¯¦7{bbbÖ¬Y“œœlýÜÛ¥W¯^ýÃ?|æ™g|h©¨‰322víÚåÕ¥ ¸ ÉÖóm¡¡ú¢Ÿx≻îºË¬ƒÂét^½zuøðá!G0oÞðã?ú6ã”)Sî¾ûî€Ôáå—_Þ¸qã?þèà Ã0–/_~×]w…éœÿ­à• -Ã4rss/_¾\§Nˆˆ5½¶­g­žËB =zäÈ‘¬¬¬Ó§OçääK)Ïž=UµjU§ÓÓ¸q㤤¤;î¸Cõå×f àºXK‹ŽŽ~ï½÷Ìs,s¹›7oÞ´iÓý÷ߨ…z+++kåÊ•âÚÓHk[cìØ±†÷ÃA§r9'Nœðê$HíÙÑÑÑ<òˆúÄÿyddäôéÓ{öìéÛ ç~øÁÛY‚ÔçC™Ö“SßJ0J?Ž«ÏwìØ±iÓ¦½{÷feeíß¿_½@ÏL÷F5mÚ´aÆÉÉÉ=zôPWׂǥz?ÿü³:doÛ¶mß¾}fÅÌꙉhÝKÍÿ­Q£Fûöí;wîܱcÇfÍšEDDõðzÇw´mÛöûï¿7+£ª·jÕªPEŽ”rÚ´iW¯^µF‹¢k×®76§ IÝ`_y‰)¥·rÔšZ½zõ¶Ù»uëvß}÷}ñÅ>Ì›žžžŸŸ¿~ýúE‹Ù¬¸6üoÙ²e>,±DRÊM›6͘1ðñ#7-Z´˜>}ºú÷ÁƒÇg“¦¥¥õêÕË()¨öïß¿fÍš7îÚµËý¥[†a8N5×áÇ>l~žœœÜ¼yóÞ½{÷îÝ;/ær:{öìÙ²eËæÍ›7oÞüŸÿüÇe3i¬Í/—mbþonnîš5kÖ¬YcFݺuÛ·oߦM›öíÛ£Õ«ê3vìØï¿ÿÞzùPJ¹bÅŠI“&ÝvÛm]¢_}õ•zÜ€uÕªUkñâÅæÿÒÊ/Ì£¤·C=kÑ¢…W{¤: ôìÙS–2Ú7N§såÊ•¾m‡Ã±sçÎììla·mgc:Ž;vj¤”C‡µÓah»xñbsöôôt¯¾‹… º×aíÚµMš4ñ¹;Å|Q^•*Už{î¹ .øö-«¹\æýç?ÿÙ²eKõùP·2™;@jjê¶mÛÜ+`‡u´*ÓR¬.Þ$%%™_Ÿ¹Ð=zø°•üdVÆ¥ÂóçÏ·NÆ i%œI‡£ð‰‡Ã‘ØjH)8àÛÞ „X·n”rÈ!êXfó ïp8†¨ú™ïa´³ •“'Oš%ø9ÇŽ{衇ì箇º™Û'55õ—_~ñmƒX÷{÷îMMMõ³nv*oÖÜápôîÝ[õ{<"Gµ`Áë&2ªBN§ 6¸ïo±±±—/_¶NFä(DŽwÂ'r”¹sç–x&ë3ŸË1«‘™™©^Mo¿™žžµ˜?¾°÷Šnó˜8iÒ$õ¢ U‚Ï‘sìØ±?ýéO·Ür‹º˜ásǸþ¨­þ[­Zµ—^z)//χMät:<8vìØÊ•+[ÎÁk师5kÖ¯¿þj¿Îž[9ª¡Ó®];÷eµhÑ¢°°ÐÛMä?üáîßõ¤I“\&#r"Ç;AŠuîé[}¾ùæ›ÀVÆÓ§Oˆˆðj-ºtéâÿr ëÕ«g3rTÞÔ©SçâÅ‹ÖB|‹œ#GŽ$&&ÚŸËBˆ;ï¼Óú(ä¿p!DRRRff¦Í:{nå(‡ªP¡‚58Õ¡õêÕ6—â¿ýû÷[—®v¼Š+fgg»LIä(á9åè¾s˜©üõ×_®.ðøã×®]Û«Y¾øâ ?ßG'¥üøã­¯ë.sz)åøñ㣣£ýY®aééé;w.í"„سgÏ´iÓÌÿõ0±¹6nÜøÇ?þ1¨+“J‚cÇŽõë×ïÒ¥K*¶qãÆ;w¶~¢Öú½÷Þ Ô"Ê4~üx— !}ôÑ`9D0”£Èq9§óÊ©S§ÔøÔwß}7??߃á˜UªT?~¼ýõC;w®? BÌŸ?ß«YªT©2jÔ(jÆéÓ§¨óågQž©­ôÆoØR¯6þçŸÞ§OŸüüüОTšµÝ»woïÞ½˜: °þ¯ZÍÿýßÿÕðN )ezzúúõë]>ŠŠšùäÛo¿‘‘árõBt¤µiòäÉöGK«ÉfÍšåóâ&NœèÕ~œ˜˜XTTä¾âÞFŽ~Bˆ‰'JßÚÊ•+ý/ç²ÿX‡ Š’xU¸a·ß~»ûNhe3r¤”+V¬p¯ÃáØ°aC0öjÅét®^½Z¸ ÁhÖ¬™zXƒ;"G!r¼¤È)..6ïRH%Åõ£l]~*THMM}衇^xá…/¾øâÌ™3ªý‰îܹӿ!ɬdçÎ}^ÜwÞéÕ~Ÿ[97~æ™g–/_¾sçÎóçÏËk»¨Yþ¹sçvïÞý?ÿó?ÇWâ}¨Æ UC§Äµ°ßÊ‘R~÷Ýw*Tp?Á Þе]»vEEE¹ìržCŽÈQˆï#rLcÇŽ ê=z>HIIyúé§?ýôSÏÝ ¥9sæL¥J•¼Zø° ó]se–¯&ëׯ_iEù9Âr—¥¢FÆ [´hѦM›vïÞ}üøñôôôo¿ývîܹýúõ«R¥ŠKöÛ_Šâïÿ{‰õߺu«ý¢\ZÀIIIï¾ûî•+Wìoù¼¼¼É“'W¨PÁlÙ_úsÏ=WZ±^EŽ”òÏþ³Ëft8¿ûÝï쯈WRSS]¾!Ä{ï½çáT‰ÈQˆï5r.\¸àÏSR‚Áü9ÅÅÅ;vóæÍ¥uU—f̘1^]¦r8Gõª•³{÷nóÐigu‡‡×˜ú9jî¹çž 6zX‘‚‚õF/ßR§´G6ôèÑër̘¼ÿþû½º[SQ+øÚk¯9¯nÆ2 #..®´qÞFNNNN¥J•\f‰ŠŠ ì CUU]F©©}/&&F½Ü½4DŽBäx'¨‘#¥û¬o—¬ï»ï>ë¶µ³¸F¹—3eÊo[K‡cúôé>ÔÙyg•ýµ¨_¿~‰[ÌÛVŽ”R½$к'¨ÿ.X° k§Œ3ÆeÕÔo¡Ì‰…ÈñN°#G0žËÉÉ‰ŽŽvœo¿ý¶Ìy‰%œ#§=}ÀE:u6lØ0aÂó“°ú†ÔÁQJ©|0{öliyÙ¥ûÄ-[¶LLL,ñ¯¥•¿aÃ;Sæåå}üñÇ6‹U%»Ü¯î?yíUf/¾ø¢Ï…tíÚ566Ö0 ‡ÃauÜíÛ·ÏۼƎëí5˜ !*T¨Ð·o_ÛÝU±k×.ÿ—®üõ¯UÇ5ë‡ÇŽ Ô ™V¯^}ùòe—3§æÍ›·k×. 宂ÚÊq&ô?þøüóÏÿæ7¿ «VŽõž å…^0ûôK\£µk×ÚΤ ŒŠŠ²Ók·hÑ"¯¶LíڵϞ=ë¹LZ9‡cäȑқœNçóÏ?ïUsÖ}'— ®ÃÛù1«Õ¬Y³yóæÂö56û¼*0°G)åèÑ£]Z9RÊŒŒŒ+Vø\æK/½tìØ1—Ï[¶lùä“Oú^W L!låØqúô鯾újΜ9ÇoÙ²¥ûýíÖ6Ëç.õv³(óæÍóP½O>ùĺt;Å–öÈáS§NEEEÙ,Ç0Œ&MšØÜ†>´r ¼þªJbË%í„¿ýíoíÌn~׿ÿýïRí`ð§•ãt:­÷ÚÄf3×]vv¶{óQ±ÿ~û…ÐÊQhåÜTbcc;uê”––¶dÉ’mÛ¶]¸páàÁƒüñ¤I“†ªNiÝû߬©ãymÄÚÆ=LÖ¥K—¸¸8aïȪ>îï#QæÍ›wåÊÃÞ µ¢W¯^eN曺uëÞrË-,ÐΕ(;;Û«&K||¼o sBˆ_|ѽ—òôéÓê”ÈN!ÖÉV­Z%¯o> !Ú´isÇw°Ú9"ÇwæÏ£qãÆ}ûö2eÊ;ï¼³k×®üüü={ö¼ýöÛiii=zôˆ‹‹3®?/¥§§{øIGGG?óÌ3†í£ªbݺuîŸ-]ºÔ«Šýáðjzûj×®ísHÖùóçmN©’ÉŸwц¹V­ZuíÚÕý{ùÇ?þ¡^cX&ë¯àwÞ1ÜvÚ€¶GÈ9¾³þ<Ì4)etttÓ¦M~øáW_}õ³Ï>;yòdVVÖ§Ÿ~:uêÔ:×zù}^îÉ“'wîÜéa‚'žxâÎ;ï´¿ëÖ­;~ü¸Ë‡6lP/œ¶©M›6Öç0Vdddxöx&„P=“7%)åk¯½V¹re—¯æÜ¹sê¥ öËY±b…z ‡õóZµj=òÈ#F¼DäøÎ¥áâáÃzõêõêÕëÙgŸýúë¯úé§.]º¸÷¼Ù!¯ =úúë¯=L=cÆ ûÅ^ºtéå—_6Ø*>?øàƒ2g´®Å’%Kû¼°åÕ·¦z&oJBˆÆ<ØýOóçÏ·¿‰òóóÏ{9IDATÓÒÒÌ}ÛìþÇ?þ¡Fë܈g(M¹8F>(éÜ*99yýúõ P/¾ýœŽ=êy‚®]»¶jÕªÌrÌu|çwÔ­†a!Š‹‹ÿùÏÚŸ½[·nå¤Ï=::ÚÎŽaNSâeꛆ”ràÀî$33³´ „.³†1þüÓ§O›ªßE³fÍÜÇaã&P^"Çð5uœNg`ë ª±páÂFùüä•'NxžQJ9þüÈÈHÏå˜?é‚‚‚©S§šÆ—-[vòäÉ2«¡fŽŽ~õÕWÕŒ7}H£FìLfnØÌÌÌ`V'Ä„;wnÓ¦ûŸÒÒÒìÄíž={¦M›f)eddä›o¾G!ÜTut8}úô}÷ÝçÛÑpàÀþ<×Ë…ùÓªQ£Æ /¼ðÈ#x5üÉTTTäùPѼyóîÝ»¯Y³F}RâRäµg— !fÏž–––˜˜xåÊ•—^zÉ(åynîÆg6qnúÓÒÄÄÄ={ö”9™¹a·mÛV\\Ú£§Ïi;"""–,Y’œœìp8œN§¹;effNž· löíôéÓç³Ï>3»ËJKãÚQiþüùÓ¦M[³fÍ/¿übs)ãÇ÷znXêÙ©†£&ÈÏÏÏÈÈhÑ¢EëpéÒ¥™3gÚœX}ï-[¶ìÞ½{ë`Õ¤I“!C†|ðÁf°©uë­·¦L™R⛜Ôþ–‘‘±uëVÕÖ7·gDDÄäÉ“ƒTU "з‚úp­^MÛm·ðõSVN§SÝÖàÃ&0`€ûó=Ýýúë¯êigÝ…UªT9qâ„:cµ9KiïÍôÌÛ[A[´háÓ6.ý…%í„j”„W•>|x x£ÊÙºu«¸ö@Ï‹V_bioëñçVPk}¤”ÙÙÙ±±±.ûŒ¢Ä·Ã™¢9r¤ûÎ9lØ0¶ŒÂ­  ·‚†XTTTƒ |›÷çŸÞ¶m[`룘/$öaÞøøx;‘3cÆ û}w?þøì×dذaö'¾ øðýåË—Ÿ={6 KWßøæÍ›ÕwZæ×jN’’ ”XÃ0êÕ«7gÎ÷¥/Z´Èýj¨ªüÙ³gß}÷]÷2Ÿzê©`Ta¢\DŽa>Œ§2O^ýõ@UÃzŒØ³g·§!æ)aÆ {_<ð@Ó¦Mí¤ŽZÙÕ«WKËÙ«çj$$$Ü{ï½^­Â®I“&U«VõvhûG}À:¬_¿Þóä^û÷iùlРA¬¬·ÞzË}b!Ä /¼péÒ%s-ÔÕºuëæÍ›»ª¡ò9)))>73W¬XqèС€TÃZu²_+k³æî»ï¶9oDDĤI“¼ZýúŒ;¶B…rq9Ðê·¿ý­·mÓ… jéÇŽó|W–»5jÔ«W/P(MDDD¿~ýÜw³)S¦¸ßœäEjF5n7±ò9}úôñ­ Ë0 !Ę1c.\¸ÀúìØ±Ã|:§ÍỶ+W®|Ï=÷ØŸkàÀ·ß~»-]JJÊ“O>éóV½qÝÿýÞβ{÷îG}TÔû³èììì^½zy5רQ£ô ™=z´õD¥È±cÇþú׿šJ)‹‹‹{ì1—’R<ØÛ—|ðáJݺu}>ÓB4mÚÔ«‡Úz““Ó¸qcáýƒ>UC§sçÎÞ.qöìÙf#Éÿ掺"½nÝ:Ÿ·À;|@J¹{÷nsKzÕHMMM5/àùàäÉ“III6‡u˜Ó!Ž;Vbþpát:ÇŒc\ÿ[UëoG]‹rhP¹reÿ_*Êð…áa¡]»vþ|û÷ïoÞ¼ùÔ©S/]º¤>‘Þßü(¥üòË/[µj•™™éÃìJÇŽ½š^JùÀ¨û|ó©‹ tëÖÍÿrnDÍš5KNN׆JÛÜ©¤”[·n:tèÕ«WÝÿTÚ,æ¿/]º4hР¬¬,ûõT‡õ^½z¹ˆƒD1iÒ$—ÇÊ©ƒ õæ¶>øÀ}•ûöí[«V-µ\©•³fÍß"G\/11ñ‰'žX¾|ù‘#GTÉæ Oëâ¬ÿ{éÒ¥íÛ·Ï;W½ÔÙŸjDFFzÛØRé'Mšä> Õ7Bˆ)S¦øó]ÜЭ)åÚµk£¢¢¼Ý˜jú[o½õé§ŸÞ»w¯‡JZ÷¨#GŽLš4)>>ÞúRZ; BDEEíÚµKá­ LŸ>ݽžBˆï¾ûNJ™­Æ_XGx«¿ú?”œVŽέœrtí·G))){÷îõ³œ¬¬¬yóæ©W®\¹yóæ5jРAll¬õ®·ÜÜÜììì'N9rdÇŽ/^4,1>=}ÇápŒ1ÂÛÑwjÏ›4iÒ’%KÔh]–îbøðá~–pCëÞ½ûèÑ£çÎkxÿmžß ¢veÃ0&Nœø›ßüFóI‘7ŠaÆ=ýôÓ~"ÝRPX&¸ÿÕ!DŸ>},Xª7%%%¥¥¥¹îò¶P!Dbbâ+¯¼¢«^½rt-Ç|Û¶m‹-2?ñí‡TÂò6!ÄСCGŽé±-[¶lÒ¤ÉÁƒ¥—W•TM*Uª4jÔ(ÿ«qsRΘ1#''G½DÙüЫ¨°~Ñæ¼Òò¬UŠjÞ¼ùûï¿ÂÇW !ÆÿÆoäçç[OMÜÏTž}öÙðyqê?üð·¿ý-$‹nܸñƒ>’E#ˆ×rL¿þúk›6mÄõÃfŠuxÒØ±cøhÑÉ“'›½dö[*jÊßÿþ÷©ÃÍѱ¦º‹ŠŠFmݤ¡Ú¯Ô¢“’’Ô¿2{>ƒ×±¦<û쳞»k×®}ùòå.ÑÏŽµêÙ³g·káEJY¥J•¯¾úê­·ÞªW¯^¦Žyº·téÒyóæ°’#FŒ°ùjK÷Zýñ T5nêkŠˆˆX°`Ák¯½mý<$UjÛ¶íÆkÖ¬’¥›ÔêOž<¹~ýú|#FŒ¨X±¢Æz!ôÂîh«:튊Š6lØŽ;zöìê¹’RFFF¦¥¥eff>úè£-¼AƒãÆóaÆÛn»­OŸ>­ÌÎ<žŽ7nß¾}êöØäMåÊ•/^üí·ßÞ~ûíf¬þj(jÑ111=ö˜,ý²ßO<¡·^½ò9VqqqkÖ¬Ùºuë]wÝ¥:FT{ÂÚ!¤Ÿ®{WŒùïîÝ»gff¾úê«111ÁXô„ \n)³’†aüå/ á·Ô¨Ü2¿SF‹%&&®]»væÌ™êÌÝå;õ¡ÀkeÖÍ\u~ݺuúÓŸ|(ÍŒ¤0`€KÉæf9rdP6jç+öÀ¡ÿµoÜ(nø#H@´jÕjÛ¶m_~ùå‹/¾Ø©S§J•*×?'*à„åÍ’æÛ´i3}úôíÛ·þù牉‰ÁX®ZPaa¡ýk¶ªzÍ›7ÔíŸN{ˬF@–n³(RÊ &dee-\¸P= /€ûË)¥¬X±âÀׯ_äÈ^äãR¸uŸ ”F©§®Y©‹ S§N à‚Jäù )¬Žò¡ê‰Õ¯Xó,22²cÇŽ:u2 ãÌ™3ŸþùÆ7lØ››Œ½AZF£uïÞýèÑ£‡z¯¢ÌýO-wêÔ©çγó“3¯*ÍŸ??222 ÇP!D­ZµFm5u€°?âNQ½zuõòVûåK)k×®=räÈ#Fdgg¯X±bÆ _}õ•ý¨+³VÑÑÑ}úôyàºuëf^@òÁƒ>xþüykÉñññþ×ÐJ1sæL—·´ !þD5µg:477×\Š”2>>¾Ä¶bÅŠjt:á=Íš5 u4 ý¶v§ö•úõë{õÃ`¸råÊÞ½{·mÛ¶cÇŽ½{÷îÛ·¯  @^?¤UM)¯96ç5/ÖiÔ¿o»í¶Ö­[·jÕªU«V)))Aê=+Mnnnݺu¯^½jç¨Úºuëï¿ÿ^CÝnV'NœøôÓO·lÙ²yóæ£Gª­{‘´Œ‡–aÓ†e·iß¾}Ë–-;tèpï½÷V©R%D«‚@BBBvvv‡±x@äØbòóóÏ;wêÔ©‹/æäääçç«cwnn®Ë,¥Œ‰‰QÝúÕ«W­^½z\\\\\\DD„õø¢yE^}õÕ &Øœ^±}ûvÞÕèk–äääüüóÏ999yyyN§3//Ïú5‡ÃQ½zu‡ÃQ­Zµ5jÔ©S§nݺµjÕRñ§äsDŽwÂ0r\xõË«ÃÄÅ‹7n|âÄ ›Ó;Žûî»oãÆA­U¹âmOà­pŽv}_x!á“7†aLœ8ñ—_~±?½”²_¿~Á«O9DÞ ftæÌ™Þ>ì rð_j|Aß¾}Ÿ~úéP×À͉k7÷§\+.Àvy¨¨ú°Aƒo¾ù¦ö*(/håÜ$\Þ-èòVë'Ö7Kš³·hÑbΜ9qqqú*  œ¡•sSqiܘOð0e—.]ÆŽÛ»wï`¿ˆœ›Ä°aÃÚ¶m[PP ^Áb>.://ïüùóæ«kÔ¨Q­Zµøøø:uꤦ¦vèÐÁú²/ò@P97‰¡C‡ú_¶T\ËhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9MˆÀ¶ÿÖµÁ÷”hèIEND®B`‚p2Dd&& `+`+ffð<² ð C ðA¿ÿðÂbðà1„oœÅr<,;ÖFQ[‡¬bÿ¼1´2cnð´1„oœÅr<,;ÖFQ[‡¬bÿ‰PNG  IHDR&&è¬ÖgAMA±ˆ•˜ô¦ pHYs ø øf&<ý IDATxœíÝytU¢Çñºˆö"$ÄƃèÂ.Žì0 ‹¨Œ ›(F‘a—qæ Ûˆ ‚ìˆG}"¢(úØQGD-ÀŒ$  D ô}Ü¡^Ñtª·Û ù~þð`§êÖ­êêúÕ½u«Ê0Üà„¡®ܨÂöZ!Ô(¹±Âv«@Ø’R†!„Pÿ+á9Jxn/sá|²¾‘ãp8âããC] ¸ÁüòË/N§3Ôµ(Y˜FŽ”2>>>+++Ô€LBBBvvvx¶u¡® ¼ rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBäØ"¥tùG™S\9¶!\þ¡¸Œ9Ù.*„º7)¥âÂ… §N:~üøéÓ§333 OŸ>m†ÓéT“ !TÒÔ¬Y³R¥JIII5jÔ¸õÖ[ãããëׯo–€"rJ ¥,,,|áÂãZl¨h1ÿaåÒÐQÓDFF&$$$$$4lذQ£FÉÉÉ­ZµºõÖ[ !„ÊùóçKk‹ !ªU«vCì™RÊüüü¢¢¢ÿêp8ªU«Vâ\çÏŸwù0**ªråʯ"œÚÑëׯ/µ+**Ú²eËàÁƒ+Uª$„B8ŽÀþðÌ2G\\܈#þõ¯é_S”gN§SJ™ Jáp8<êjÚråʕڵk—¶"Íš5S+ëâܹsê—h=zt‰ßpTŸJxž1p-ç¿òòò^|ñŤ¤¤6mÚ¬\¹²°°Ð0 !„ÙiªÅ£†‘““³lÙ²Ž;¶k×nñâÅ—.] ಀҨƒ‘uo´Rýè£B]M[–.]zöìY÷µ0,«YâŒÒ2&Èe‘c†±bÅŠ;ï¼óå—_>qâ„qm_T{¡Ãá  T»µu)ßÿýèÑ£[¶l¹aÆ@- ð¬´[í“~ø¡æúøàÊ•+Ó§O/mET“¥´yÝÿÀ_:JSN#ÇÜ·V¯^Ý´iÓ!C†;vÌ¥M­& l+Ç0 §Ó©ÊtY”ò§Ÿ~êÞ½{‹-V¯^Ø…î<a322–-[f*å‰'fee•ø§2ë,¯u0¡^(U9Ã0Š‹‹Ç׿ÿ„º.ÿ¥ú4222ú÷ï?lØ05Z )åSO=uîÜ9#\»›233ßxãP×Þ)‘#¥¼råJ·nÝæÍ›g„ÓÏIõ­«3¯wß}·mÛ¶G u¥P~åçç¿òÊ+¡®E©V­Ze„q %*‘ãt:‡þå—_šÿë[9%Ž1?÷¡@ë5LÕÏÖºuëÍ›7ûV=À>—}ظ¶7¾þúëÿþ÷¿C[·]¾|yÉ’%êßî•GØ*‘3uêÔ÷ßß°âýdŒýU gÏžíÛ·ïÙ³gý¯$`“õwqùòå7ß|3´õ)ÑìÙ³­YHØÜ(Ê]äüðÃ/½ô’ˆö¸‡Q•þ:0ögÏž4hPÀG1Vê,Çá¸î€ ZÛ|ðAqqq¨*æÂüQL:Õ°üŠé^»Q”£§H)sss|ðAkç•EIMkܸqƒ êÖ­[«V-óÃâââ“'Oæåå?þàÁƒyyyòÚ£ „Çx¨³a›6mJKKãJ)‚Gí–ÉÉÉõë×߸q£aÙÛ³²²fÍš5qâÄVð:?þxAA¼þɃþæ›oÔ}€DО>0iÒ$ßêãp8Ôý4qqq¯¼òŠºõ¬Ä•Í‹ŠŠ80kÖ¬:”xÉÇ>µè-[¶|ƒ qß]+UªtìØ±P×÷¿Ö¯_ïò#BÔ©S''''!!Áå·“’’Rb!j$ž‹Q£Fi^— áéa¡¨¨héÒ¥¾Íët:£££§OŸ~øðáñãÇ׬YÓ(å5?ŒˆˆhÒ¤Éøñã¿ùæ›Ï>û¬^½z†O# ÌVѧŸ~*Ãû& Üè„]ºt‰u¹$YXX¨:²ÂÁßÿþw—‘”rüøñµk׿§þÊQä8pàÌ™3>Ì(¥Œß¾}ûĉcbb ïú={öܳgOÿþýÍOì¼Ö{ Nî$EÐH)£££'L˜`žÜ˜»Ü²eË233C]AcË–-[·nuùV«Ví±Ç3Âõ¼Vå(r¾ýö[¯¦7{bbbÖ¬Y“œœlýÜÛ¥W¯^ýÃ?|æ™g|h©¨‰322víÚåÕ¥ ¸ ÉÖóm¡¡ú¢Ÿx≻îºË¬ƒÂét^½zuøðá!G0oÞðã?ú6ã”)Sî¾ûî€Ôáå—_Þ¸qã?þèà Ã0–/_~×]w…éœÿ­à• -Ã4rss/_¾\§Nˆˆ5½¶­g­žËB =zäÈ‘¬¬¬Ó§OçääK)Ïž=UµjU§ÓÓ¸q㤤¤;î¸Cõå×f àºXK‹ŽŽ~ï½÷Ìs,s¹›7oÞ´iÓý÷ߨ…z+++kåÊ•âÚÓHk[cìØ±†÷ÃA§r9'Nœðê$HíÙÑÑÑ<òˆúÄÿyddäôéÓ{öìéÛ ç~øÁÛY‚ÔçC™Ö“SßJ0J?Ž«ÏwìØ±iÓ¦½{÷feeíß¿_½@ÏL÷F5mÚ´aÆÉÉÉ=zôPWׂǥz?ÿü³:doÛ¶mß¾}fÅÌꙉhÝKÍÿ­Q£Fûöí;wîܱcÇfÍšEDDõðzÇw´mÛöûï¿7+£ª·jÕªPEŽ”rÚ´iW¯^µF‹¢k×®76§ IÝ`_y‰)¥·rÔšZ½zõ¶Ù»uëvß}÷}ñÅ>Ì›žžžŸŸ¿~ýúE‹Ù¬¸6üoÙ²e>,±DRÊM›6͘1ðñ#7-Z´˜>}ºú÷ÁƒÇg“¦¥¥õêÕË()¨öïß¿fÍš7îÚµËý¥[†a8N5×áÇ>l~žœœÜ¼yóÞ½{÷îÝ;/ær:{öìÙ²eËæÍ›7oÞüŸÿüÇe3i¬Í/—mbþonnîš5kÖ¬YcFݺuÛ·oߦM›öíÛ£Õ«ê3vìØï¿ÿÞzùPJ¹bÅŠI“&ÝvÛm]¢_}õ•zÜ€uÕªUkñâÅæÿÒÊ/Ì£¤·C=kÑ¢…W{¤: ôìÙS–2Ú7N§såÊ•¾m‡Ã±sçÎììla·mgc:Ž;vj¤”C‡µÓah»xñbsöôôt¯¾‹… º×aíÚµMš4ñ¹;Å|Q^•*Už{î¹ .øö-«¹\æýç?ÿÙ²eKõùP·2™;@jjê¶mÛÜ+`‡u´*ÓR¬.Þ$%%™_Ÿ¹Ð=zø°•üdVÆ¥ÂóçÏ·NÆ i%œI‡£ð‰‡Ã‘ØjH)8àÛÞ „X·n”rÈ!êXfó ïp8†¨ú™ïa´³ •“'Oš%ø9ÇŽ{衇ì箇º™Û'55õ—_~ñmƒX÷{÷îMMMõ³nv*oÖÜápôîÝ[õ{<"Gµ`Áë&2ªBN§ 6¸ïo±±±—/_¶NFä(DŽwÂ'r”¹sç–x&ë3ŸË1«‘™™©^Mo¿™žžµ˜?¾°÷Šnó˜8iÒ$õ¢ U‚Ï‘sìØ±?ýéO·Ür‹º˜ásǸþ¨­þ[­Zµ—^z)//χMät:<8vìØÊ•+[ÎÁk师5kÖ¯¿þj¿Îž[9ª¡Ó®];÷eµhÑ¢°°ÐÛMä?üáîßõ¤I“\&#r"Ç;AŠuîé[}¾ùæ›ÀVÆÓ§Oˆˆðj-ºtéâÿr ëÕ«g3rTÞÔ©SçâÅ‹ÖB|‹œ#GŽ$&&ÚŸËBˆ;ï¼Óú(ä¿p!DRRRff¦Í:{nå(‡ªP¡‚58Õ¡õêÕ6—â¿ýû÷[—®v¼Š+fgg»LIä(á9åè¾s˜©üõ×_®.ðøã×®]Û«Y¾øâ ?ßG'¥üøã­¯ë.sz)åøñ㣣£ýY®aééé;w.í"„سgÏ´iÓÌÿõ0±¹6nÜøÇ?þ1¨+“J‚cÇŽõë×ïÒ¥K*¶qãÆ;w¶~¢Öú½÷Þ Ô"Ê4~üx— !}ôÑ`9D0”£Èq9§óÊ©S§ÔøÔwß}7??߃á˜UªT?~¼ýõC;w®? BÌŸ?ß«YªT©2jÔ(jÆéÓ§¨óågQž©­ôÆoØR¯6þçŸÞ§OŸüüüОTšµÝ»woïÞ½˜: °þ¯ZÍÿýßÿÕðN )ezzúúõë]>ŠŠšùäÛo¿‘‘árõBt¤µiòäÉöGK«ÉfÍšåóâ&NœèÕ~œ˜˜XTTä¾âÞFŽ~Bˆ‰'JßÚÊ•+ý/ç²ÿX‡ Š’xU¸a·ß~»ûNhe3r¤”+V¬p¯ÃáØ°aC0öjÅét®^½Z¸ ÁhÖ¬™zXƒ;"G!r¼¤È)..6ïRH%Åõ£l]~*THMM}衇^xá…/¾øâÌ™3ªý‰îܹӿ!ɬdçÎ}^ÜwÞéÕ~Ÿ[97~æ™g–/_¾sçÎóçÏËk»¨Yþ¹sçvïÞý?ÿó?ÇWâ}¨Æ UC§Äµ°ßÊ‘R~÷Ýw*Tp?Á Þе]»vEEE¹ìržCŽÈQˆï#rLcÇŽ ê=z>HIIyúé§?ýôSÏÝ ¥9sæL¥J•¼Zø° ó]se–¯&ëׯ_iEù9Âr—¥¢FÆ [´hѦM›vïÞ}üøñôôôo¿ývîܹýúõ«R¥ŠKöÛ_Šâïÿ{‰õߺu«ý¢\ZÀIIIï¾ûî•+Wìoù¼¼¼É“'W¨PÁlÙ_úsÏ=WZ±^EŽ”òÏþ³Ëft8¿ûÝï쯈WRSS]¾!Ä{ï½çáT‰ÈQˆï5r.\¸àÏSR‚Áü9ÅÅÅ;vóæÍ¥uU—f̘1^]¦r8Gõª•³{÷nóÐigu‡‡×˜ú9jî¹çž 6zX‘‚‚õF/ßR§´G6ôèÑër̘¼ÿþû½º[SQ+øÚk¯9¯nÆ2 #..®´qÞFNNNN¥J•\f‰ŠŠ ì CUU]F©©}/&&F½Ü½4DŽBäx'¨‘#¥û¬o—¬ï»ï>ë¶µ³¸F¹—3eÊo[K‡cúôé>ÔÙyg•ýµ¨_¿~‰[ÌÛVŽ”R½$к'¨ÿ.X° k§Œ3ÆeÕÔo¡Ì‰…ÈñN°#G0žËÉÉ‰ŽŽvœo¿ý¶Ìy‰%œ#§=}ÀE:u6lØ0aÂó“°ú†ÔÁQJ©|0{öliyÙ¥ûÄ-[¶LLL,ñ¯¥•¿aÃ;Sæåå}üñÇ6‹U%»Ü¯î?yíUf/¾ø¢Ï…tíÚ566Ö0 ‡ÃauÜíÛ·ÏۼƎëí5˜ !*T¨Ð·o_ÛÝU±k×.ÿ—®üõ¯UÇ5ë‡ÇŽ Ô ™V¯^}ùòe—3§æÍ›·k×. 宂ÚÊq&ô?þøüóÏÿæ7¿ «VŽõž å…^0ûôK\£µk×ÚΤ ŒŠŠ²Ók·hÑ"¯¶LíڵϞ=ë¹LZ9‡cäȑқœNçóÏ?ïUsÖ}'— ®ÃÛù1«Õ¬Y³yóæÂö56û¼*0°G)åèÑ£]Z9RÊŒŒŒ+Vø\æK/½tìØ1—Ï[¶lùä“Oú^W L!låØqúô鯾újΜ9ÇoÙ²¥ûýíÖ6Ëç.õv³(óæÍóP½O>ùĺt;Å–öÈáS§NEEEÙ,Ç0Œ&MšØÜ†>´r ¼þªJbË%í„¿ýíoíÌn~׿ÿýïRí`ð§•ãt:­÷ÚÄf3×]vv¶{óQ±ÿ~û…ÐÊQhåÜTbcc;uê”––¶dÉ’mÛ¶]¸páàÁƒüñ¤I“†ªNiÝû߬©ãymÄÚÆ=LÖ¥K—¸¸8aïȪ>îï#QæÍ›wåÊÃÞ µ¢W¯^eN曺uëÞrË-,ÐΕ(;;Û«&K||¼o sBˆ_|ѽ—òôéÓê”ÈN!ÖÉV­Z%¯o> !Ú´isÇw°Ú9"ÇwæÏ£qãÆ}ûö2eÊ;ï¼³k×®üüü={ö¼ýöÛiii=zôˆ‹‹3®?/¥§§{øIGGG?óÌ3†í£ªbݺuîŸ-]ºÔ«Šýáðjzûj×®ísHÖùóçmN©’ÉŸwц¹V­ZuíÚÕý{ùÇ?þ¡^cX&ë¯àwÞ1ÜvÚ€¶GÈ9¾³þ<Ì4)etttÓ¦M~øáW_}õ³Ï>;yòdVVÖ§Ÿ~:uêÔ:×zù}^îÉ“'wîÜéa‚'žxâÎ;ï´¿ëÖ­;~ü¸Ë‡6lP/œ¶©M›6Öç0Vdddxöx&„P=“7%)åk¯½V¹re—¯æÜ¹sê¥ öËY±b…z ‡õóZµj=òÈ#F¼DäøÎ¥áâáÃzõêõêÕëÙgŸýúë¯úé§.]º¸÷¼Ù!¯ =úúë¯=L=cÆ ûÅ^ºtéå—_6Ø*>?øàƒ2g´®Å’%Kû¼°åÕ·¦z&oJBˆÆ<ØýOóçÏ·¿‰òóóÏ{9IDATÓÒÒÌ}ÛìþÇ?þ¡Fë܈g(M¹8F>(éÜ*99yýúõ P/¾ýœŽ=êy‚®]»¶jÕªÌrÌu|çwÔ­†a!Š‹‹ÿùÏÚŸ½[·nå¤Ï=::ÚÎŽaNSâeꛆ”ràÀî$33³´ „.³†1þüÓ§O›ªßE³fÍÜÇaã&P^"Çð5uœNg`ë ª±páÂFùüä•'NxžQJ9þüÈÈHÏå˜?é‚‚‚©S§šÆ—-[vòäÉ2«¡fŽŽ~õÕWÕŒ7}H£FìLfnØÌÌÌ`V'Ä„;wnÓ¦ûŸÒÒÒìÄíž={¦M›f)eddä›o¾G!ÜTut8}úô}÷ÝçÛÑpàÀþ<×Ë…ùÓªQ£Æ /¼ðÈ#x5üÉTTTäùPѼyóîÝ»¯Y³F}RâRäµg— !fÏž–––˜˜xåÊ•—^zÉ(åynîÆg6qnúÓÒÄÄÄ={ö”9™¹a·mÛV\\Ú£§Ïi;"""–,Y’œœìp8œN§¹;effNž· löíôéÓç³Ï>3»ËJKãÚQiþüùÓ¦M[³fÍ/¿übs)ãÇ÷znXêÙ©†£&ÈÏÏÏÈÈhÑ¢EëpéÒ¥™3gÚœX}ï-[¶ìÞ½{ë`Õ¤I“!C†|ðÁf°©uë­·¦L™R⛜Ôþ–‘‘±uëVÕÖ7·gDDÄäÉ“ƒTU "з‚úp­^MÛm·ðõSVN§SÝÖàÃ&0`€ûó=Ýýúë¯êigÝ…UªT9qâ„:cµ9KiïÍôÌÛ[A[´háÓ6.ý…%í„j”„W•>|x x£ÊÙºu«¸ö@Ï‹V_bioëñçVPk}¤”ÙÙÙ±±±.ûŒ¢Ä·Ã™¢9r¤ûÎ9lØ0¶ŒÂ­  ·‚†XTTTƒ |›÷çŸÞ¶m[`룘/$öaÞøøx;‘3cÆ û}w?þøì×dذaö'¾ øðýåË—Ÿ={6 KWßøæÍ›ÕwZæ×jN’’ ”XÃ0êÕ«7gÎ÷¥/Z´Èýj¨ªüÙ³gß}÷]÷2Ÿzê©`Ta¢\DŽa>Œ§2O^ýõ@UÃzŒØ³g·§!æ)aÆ {_<ð@Ó¦Mí¤ŽZÙÕ«WKËÙ«çj$$$Ü{ï½^­Â®I“&U«VõvhûG}À:¬_¿Þóä^û÷iùlРA¬¬·ÞzË}b!Ä /¼péÒ%s-ÔÕºuëæÍ›»ª¡ò9)))>73W¬XqèС€TÃZu²_+k³æî»ï¶9oDDĤI“¼ZýúŒ;¶B…rq9Ðê·¿ý­·mÓ… jéÇŽó|W–»5jÔ«W/P(MDDD¿~ýÜw³)S¦¸ßœäEjF5n7±ò9}úôñ­ Ë0 !Ę1c.\¸ÀúìØ±Ã|:§ÍỶ+W®|Ï=÷ØŸkàÀ·ß~»-]JJÊ“O>éóV½qÝÿýÞβ{÷îG}TÔû³èììì^½zy5רQ£ô ™=z´õD¥È±cÇþú׿šJ)‹‹‹{ì1—’R<ØÛ—|ðáJݺu}>ÓB4mÚÔ«‡Úz““Ó¸qcáýƒ>UC§sçÎÞ.qöìÙf#Éÿ掺"½nÝ:Ÿ·À;|@J¹{÷nsKzÕHMMM5/àùàäÉ“III6‡u˜Ó!Ž;Vbþpát:ÇŒc\ÿ[UëoG]‹rhP¹reÿ_*Êð…áa¡]»vþ|û÷ïoÞ¼ùÔ©S/]º¤>‘Þßü(¥üòË/[µj•™™éÃìJÇŽ½š^JùÀ¨û|ó©‹ tëÖÍÿrnDÍš5KNN׆JÛÜ©¤”[·n:tèÕ«WÝÿTÚ,æ¿/]º4hР¬¬,ûõT‡õ^½z¹ˆƒD1iÒ$—ÇÊ©ƒ õæ¶>øÀ}•ûöí[«V-µ\©•³fÍß"G\/11ñ‰'žX¾|ù‘#GTÉæ Oëâ¬ÿ{éÒ¥íÛ·Ï;W½ÔÙŸjDFFzÛØRé'Mšä> Õ7Bˆ)S¦øó]ÜЭ)åÚµk£¢¢¼Ý˜jú[o½õé§ŸÞ»w¯‡JZ÷¨#GŽLš4)>>ÞúRZ; BDEEíÚµKá­ LŸ>ݽžBˆï¾ûNJ™­Æ_XGx«¿ú?”œVŽέœrtí·G))){÷îõ³œ¬¬¬yóæ©W®\¹yóæ5jРAll¬õ®·ÜÜÜììì'N9rdÇŽ/^4,1>=}ÇápŒ1ÂÛÑwjÏ›4iÒ’%KÔh]–îbøðá~–pCëÞ½ûèÑ£çÎkxÿmžß ¢veÃ0&Nœø›ßüFóI‘7ŠaÆ=ýôÓ~"ÝRPX&¸ÿÕ!DŸ>},Xª7%%%¥¥¥¹îò¶P!Dbbâ+¯¼¢«^½rt-Ç|Û¶m‹-2?ñí‡TÂò6!ÄСCGŽé±-[¶lÒ¤ÉÁƒ¥—W•TM*Uª4jÔ(ÿ«qsRΘ1#''G½DÙüЫ¨°~Ñæ¼Òò¬UŠjÞ¼ùûï¿ÂÇW !ÆÿÆoäçç[OMÜÏTž}öÙðyqê?üð·¿ý-$‹nܸñƒ>’E#ˆ×rL¿þúk›6mÄõÃfŠuxÒØ±cøhÑÉ“'›½dö[*jÊßÿþ÷©ÃÍѱ¦º‹ŠŠFmݤ¡Ú¯Ô¢“’’Ô¿2{>ƒ×±¦<û쳞»k×®}ùòå.ÑÏŽµêÙ³g·káEJY¥J•¯¾úê­·ÞªW¯^¦Žyº·téÒyóæ°’#FŒ°ùjK÷Zýñ T5nêkŠˆˆX°`Ák¯½mý<$UjÛ¶íÆkÖ¬’¥›ÔêOž<¹~ýú|#FŒ¨X±¢Æz!ôÂîh«:튊Š6lØŽ;zöìê¹’RFFF¦¥¥eff>úè£-¼AƒãÆóaÆÛn»­OŸ>­ÌÎ<žŽ7nß¾}êöØäMåÊ•/^üí·ßÞ~ûíf¬þj(jÑ111=ö˜,ý²ßO<¡·^½ò9VqqqkÖ¬Ùºuë]wÝ¥:FT{ÂÚ!¤Ÿ®{WŒùïîÝ»gff¾úê«111ÁXô„ \n)³’†aüå/ á·Ô¨Ü2¿SF‹%&&®]»væÌ™êÌÝå;õ¡ÀkeÖÍ\u~ݺuúÓŸ|(ÍŒ¤0`€KÉæf9rdP6jç+öÀ¡ÿµoÜ(nø#H@´jÕjÛ¶m_~ùå‹/¾Ø©S§J•*×?'*à„åÍ’æÛ´i3}úôíÛ·þù牉‰ÁX®ZPaa¡ýk¶ªzÍ›7ÔíŸN{ˬF@–n³(RÊ &dee-\¸P= /€ûË)¥¬X±âÀׯ_äÈ^äãR¸uŸ ”F©§®Y©‹ S§N à‚Jäù )¬Žò¡ê‰Õ¯Xó,22²cÇŽ:u2 ãÌ™3ŸþùÆ7lØ››Œ½AZF£uïÞýèÑ£‡z¯¢ÌýO-wêÔ©çγó“3¯*ÍŸ??222 ÇP!D­ZµFm5u€°?âNQ½zuõòVûåK)k×®=räÈ#Fdgg¯X±bÆ _}õ•ý¨+³VÑÑÑ}úôyàºuëf^@òÁƒ>xþüykÉñññþ×ÐJ1sæL—·´ !þD5µg:477×\Š”2>>¾Ä¶bÅŠjt:á=Íš5 u4 ý¶v§ö•úõë{õÃ`¸råÊÞ½{·mÛ¶cÇŽ½{÷îÛ·¯  @^?¤UM)¯96ç5/ÖiÔ¿o»í¶Ö­[·jÕªU«V)))Aê=+Mnnnݺu¯^½jç¨Úºuëï¿ÿ^CÝnV'NœøôÓO·lÙ²yóæ£Gª­{‘´Œ‡–aÓ†e·iß¾}Ë–-;tèpï½÷V©R%D«‚@BBBvvv‡±x@äØbòóóÏ;wêÔ©‹/æäääçç«cwnn®Ë,¥Œ‰‰QÝúÕ«W­^½z\\\\\\DD„õø¢yE^}õÕ &Øœ^±}ûvÞÕèk–äääüüóÏ999yyyN§3//Ïú5‡ÃQ½zu‡ÃQ­Zµ5jÔ©S§nݺµjÕRñ§äsDŽwÂ0r\xõË«ÃÄÅ‹7n|âÄ ›Ó;Žûî»oãÆA­U¹âmOà­pŽv}_x!á“7†aLœ8ñ—_~±?½”²_¿~Á«O9DÞ ftæÌ™Þ>ì rð_j|Aß¾}Ÿ~úéP×À͉k7÷§\+.Àvy¨¨ú°Aƒo¾ù¦ö*(/håÜ$\Þ-èòVë'Ö7Kš³·hÑbΜ9qqqú*  œ¡•sSqiܘOð0e—.]ÆŽÛ»wï`¿ˆœ›Ä°aÃÚ¶m[PP ^Áb>.://ïüùóæ«kÔ¨Q­Zµøøø:uꤦ¦vèÐÁú²/ò@P97‰¡C‡ú_¶T\ËhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9MˆÀ¶ÿÖµÁ÷”hèIEND®B`‚eœH@ñÿHNormalOJQJ_HmHnHsH tH uj@òj Heading 1$ & F¤ð¤ @& Æ75B*CJ OJQJmH sH uR@òR Heading 2!$ & F¤ ¤@& Æ7@CJF@!òF Heading 3 & F@& Æ@ÐCJZ@1òZ Heading 4. & F ÆÐ`„Є0ý¤ð¤P@&^„Ð`„0ýF@F Heading 5¤<¤@& Æð5:@: Heading 6 @& Æ€:@: Heading 7 @& Æ:@: Heading 8 @& Æ : @: Heading 9 @& Æ0DA@òÿ¡D Default Paragraph FontVi@óÿ³V  Table Normal :V ö4Ö4Ö laö (k@ôÿÁ(No List NþOòN Body¤x¤x Æ&B*CJOJQJmH sH uBþOB 11 BodyText„¤Ü^„CJB @BFooter$d Æ9r OJQJ>@">Header Æ  ø%OJQJ>þO2> 22 BodyText„% ¤Ü^„% .@Q.TOC 1OJQJ^þOR^ Heading 1TOC! Æâ‘ „â„ý¤x^„â`„ý 5B*CJªþObª Bulleted - 1t & Fÿ„w„›þ¤Ü>ÆTÿe-ð^„w`„›þCJ¬þOr¬Numbered List 1t & Fÿ„w„›þ¤Ü>ÆT€e.^„w`„›þFþOq‚FNumbered List 2 „Š ^„Š CJ6@’6 Footnote Text¦þO¢¦ Bulleted - 2t & Fÿ„Š „›þ¤Ü>ÆTÿe-ð^„Š `„›þ>Á>TOC 2„‰„Xý^„‰`„XýOJQJ\þOÂ\ Heading 2TOC! Æ‹‘ „‹„Wý¤(^„‹`„WýB*CJ6á6TOC 3„Ý„­ü^„Ý`„­ü\þOâ\ Heading 3TOC! ÆÜ‘ „Ü„¯ü¤P^„Ü`„¯üB*CJDþOòDDocument Title¤€5CJ$DDTOC 4 Æ ‘ ‰‡ „  „<ü^„  `„<üXþOX Heading 4TOC! Æ¢ ‘ „¢ „:ü^„¢ `„:üB*CJ::TOC 5 "„ ^„  CJOJQJ::TOC 6 #„è^„è CJOJQJ::TOC 7 $„°^„° CJOJQJ::TOC 8 %„x^„x CJOJQJ::TOC 9 &„@^„@ CJOJQJ@Yr@ Document Map'-D OJQJJþO‚J CellBody (¤P¤PB*OJQJmH sH uTþO’T CellHeading )¤x¤x5B*OJQJmH sH uVþOòV Heading 02 *$¤h5B*CJOJQJmH sH uTþO²T Nonum Heading +1$¤x¤d5CJ$htH u0U@¢Á0 Hyperlink>*B*@V@¢Ñ@ FollowedHyperlink>*B* PþOâP Abstract .d,¤ðB*CJOJQJmH sH u¼þOò¼ Bulleted/ & Fÿ Æh„„åþ¤x>ÆTÿ·ð·······^„`„åþB*CJmH sH uRþOR BulletedCont0„¤P^„B*CJmH sH uRþOREquation1d¤È¤x Æ‘  B*OJ QJ BþO"B Figure 2¤x¤6B*mH sH uVþO2V Footnote3 Æä„ä„ÿ¤<^„ä`„ÿB*mH sH ubþOòb Heading 014$$¤ð¤@&d5B*CJ OJQJmH sH uL#LTable of Figures5„„pþ^„`„pþRþObR Numbered6 & F>¤x ÆB*CJmH sH u°þOr° Reference|7 & Fÿ Æ7„„åþ¤x>ÆT€[]^„`„åþB*CJRþO‚R SubTitle8$$d@a$5B*CJmH sH uNþOòN TableTitle9¤x ÆT6B*mH sH u,X@òÿ¡, Emphasis6>þOòÿ±> EquationVariables6>þOòÿÁ> ProgramCodeCJOJQJkH'.þOòÿÑ. SubscriptH*2þOòÿá2 SuperscriptH*4þOòÿñ4 SymbolCJOJQJkH*>þOòÿ> Underline>*CJOJQJkH'6"6Caption A¤x¤x6.)@¢!. Page NumberBþOñ2B DocumentOwnersC$a$CJDZ@BD Plain TextDOJQJmH sH udþObd Definition List E„h1$^„hCJOJQJhmH sH tH u`þOR` Definition Term F1$¤d¤dOJQJhmH sH tH uHþOñrH Editors NotesG6B*CJOJQJBþOñ‚B Code SnipetH¤x CJOJQJ^þO^ H1I$ & F1$¤ð¤d@&%5CJ(KH$OJQJhmH sH tH uZþOZ H2J$ & F1$¤d¤d@&!5CJ$OJQJhmH sH tH u0þOòÿ±0 Definition6TþOT H3L$1$¤d¤d@&!5CJOJQJhmH sH tH uTþOT H4M$1$¤d¤d@&!5CJOJQJhmH sH tH uPþOP H5N$1$¤d¤d@&5OJQJhmH sH tH uTþOT H6O$1$¤d¤d@&!5CJOJQJhmH sH tH uPþOP AddressP1$!6CJOJQJhmH sH tH ujþOj BlockquoteQ„h„h¤d¤d1$]„h^„hCJOJQJhmH sH tH u$þOòÿ!$ CITE6,þOòÿ1, CODE CJOJQJ8þOòÿA8 Keyboard5CJOJQJxþORx Preformatted+U1$ Æ# ¿~= ü»z9ø·!v%OJQJhmH sH tH un]@ñÿnz-Bottom of FormV$$d1$a$"<CJOJQJ_HhmH sH tH h\@ñÿh z-Top of FormW$&d1$a$"<CJOJQJ_HhmH sH tH ,þOòÿ, SampleOJQJ8þOòÿ‘8 Typewriter CJOJQJ,þOòÿ¡, Variable64þOòÿ±4 HTML Markup<B**þOòÿÁ* Comment<\þOâ\ Title1]$¤ð¤d1$a$!5CJ0OJQJhmH sH tH ubþOâb Subtitle1^$¤x¤d1$a$!5CJOJQJhmH sH tH uPþOòP RFC-P1_„°¤ð^„°CJOJQJmH sH tH uZþOZ Param$` & F¦„e„›þ¤P¤(1$^„e`„›þhmH sH tH uTþOT CODECompacta1$CJOJQJhmH sH tH u4þO14 Title Textb56þO26 00 BodyTextc¤Ü4þOB4Bullet 1 d & FÐ$ÿÿÿÿÿÿÿÿ ÿÿÐ$Hÿÿÿÿ'EM^œÜ-m§è+i¨ÒÓY˜Ù[ß%g¤å+m±ÜÝ!A_€£­æðz ¯ Ð  H { ® Ï  B u © Ü  E f ¯ Û  / { § Ú -w£ÙQËHŒÑV‘Å={·ò&b¡ÜJ†Áý8Mbm©ÐÑ:IMU‘³´ Üâ‡‰Š²³áEв³ÄÚ)mÞ²ðH§9 ñ -!¬! "r"s"Ž"—"Ð"Ñ"#œ##¸#Á#ú#û#A$Æ$Ç$È$Ê$Ë$Í$Î$Ñ$˜0€€˜0€€p˜0€€p˜0€€p˜0€€p˜0€€p˜0€€p˜0€€˜0€€˜˜0€€˜0€€p˜0€€˜˜0€€˜˜0€€˜˜0€€˜˜0€€˜˜0€€˜˜0€€˜˜0€€ €˜0€€ €˜0€€ €˜0€€€˜0€€ €˜0€€€˜0€€ €˜0€€ €˜0€€˜0€€€˜0€€ €˜0€€˜˜0€€ €˜0€€€˜0€€(€˜0€€ €˜0€€ €˜0€€˜˜0€€p˜0€€p˜0€€p˜0€€p˜0€€p˜0€€p˜0€€˜0€€p˜0€€˜0€€p˜0€€˜0€€p˜0€€˜0€€˜˜0€€˜0€€˜˜0€€˜0€€˜˜0€€˜0€€˜˜0€€˜0€€˜˜0€€˜0€€˜˜0€€˜0€€˜0€€ €˜0€€˜0€€ €˜0€€˜˜0€€˜0€€ €˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜˜0€€˜0€€˜˜0€€˜˜0€€˜˜0€€˜˜0€€˜˜0€€˜˜0€€ €˜0€€˜˜@0€€˜@0€€˜@0€€˜˜0€€˜˜0€€p˜0€€ €˜0€€Ð˜0€€p˜0€€p˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€p˜0€€p˜0€€p˜0€€p˜ !0€€p˜0€€p˜0€€p˜ !0€€˜ !0€€p˜ !0€€p˜0€€p˜0€€p˜ !0€€p˜0€€˜0€€p˜ !0€€˜ !0€€p˜0€€p˜0€€˜0€€˜0€€˜0€€˜˜0€€p˜0€€p˜0€€p˜ !0€€˜ !0€€˜ !0€€˜ !0€€˜0€€p˜0€€p˜ !0€€˜ !0€€p˜ !0€€p˜ !0€€˜ !0€€p˜ !0€€p˜0€€˜0€€˜ !0€€˜ !0€€˜ !0€€˜ !0€€˜˜ !0€€p˜ !0€€˜˜ !0€€p˜ !0€€˜ !0€€˜˜ !0€€p˜0€€p˜@0€€ø€˜@0€€˜@0€€˜@0€€˜@0€€ø€˜@0€€˜@0€€€˜@0€€ø€˜@0€€˜@0€€˜@0€€€˜@0€€ø€˜@0€€˜@0€€€0PÛú˜0€€˜0€€˜0€€˜0€€€˜0€€$'EM^œÜ-m§è+i¨ÒÓY˜Ù[ß%g¤å+m±ÜÝ!A_€£­æðz ¯ Ð  H { ® Ï  B u © Ü  E f ¯ Û  / { § Ú -w£ÙQËHŒÑV‘Å={·ò&b¡ÜJ†Áý8Mbm©ÐÑ:IMU‘³´ Üâ‡‰Š²³Š²³ÄÚ)m²ðH§9 ñ -!¬! "r"Ñ$š0€€š0€€š0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš0€€Èš@0€€Èš@0€€Èš@0€€Èš@0€€Èš@0€€Èš@0€€Èš@0€€Èš@0€€Èš@0€€Èš@0€€Èš@0€€Èš@0€€Èš@0€€Èš@0€€Èš@0€€Èš@0€€Èš@0€€Èš@0€€Èš@0€€Èš@0€€Èš@0€€Èš@0€€Èš@0€€Èš@0€€Èš@0€€Èš@0€€Èš@0€€Èš@0€€Èš@0€€Èš0€€š0€€€š0€€€š0€€€š !0€€€š0€€š0€€š !0€€š !0€€€š !0€€€š0€€€š0€€€š !0€€€š0€€€š0€€€š !0€€€š !0€€€š0€€€š0€€€š0€€€š0€€€š0€€€š0€€€š@0€€€š@0€€€®z0i0€š0€€€š0€€€®:0i0€®:0i0€®:0i0€®:0i0€®:0i0€®z00€®z00€®z00€®z00€®z00€®z00€®z00€®z00€®z00€®z00€®z00€®z00€š !0 €€€^^*ˆTWaÜ"Ã*Ð,"g ÏHb‰#&A,Ð, !#Ï,&P[Pz…W4ÿ•€4ÿ•€ð@ð  @ñÿÿÿ€€€÷ð ððxð( ð ð𜢠ð c ðR€Š¿ÿƒÃ.¿ ``T`T`T`T"ñ¿€ðð ð𜢠ð c ðR€Š¿ÿƒÃ.¿ ``T`T`T`T"ñ¿€ðð ðð’ðð0ð( ð ððB ðS ð¿Ëÿ ?ð*W¸ÿÿÿòÿÿÿSýµ@¸ÿÿÿòÿÿÿSýµ@ÿÿ+di|d(4Ñ$DÑ$8*€urn:schemas-microsoft-com:office:smarttags€date€ €10€2003€27€Day€Month€YearBB¯ ¯   ™ 8s"Ç$È$Î$Ñ$s"Ç$È$Ñ$BB¯ ¯   ™ 8r"Ñ$s"Ç$È$Ñ$ÿÿ Lothar MerkMerkMerkMerkMerkMerk Thomas KleinIBM-UserIBM-UserPeter ThompsonüûÿÿÿÎÜÖ-ÿÿÿÿÿþÿÿÿÿÿÿÿÿÔhXíz@ÿºo:éÈuÿzS0à–ÀÿXlhdmÿÿÿÿÿÿÿÿÿ'5ÄáÚÞÿÿÿÿÿÿÿÿÿ¢M‹ ÿ1Í ÿB-6ïr-ÿµÚj?fÿ4 tj?fÿ$Ù ÿö[' ÿ†ld0à–Àÿ„m"0à–Àÿvj?fÿßhš6ïr-ÿÿÿÿÿÿÿÿÿZk¤V"ÙÿßQ±š…6$ÿt-j?fÿñI% ÿÿÿÿÿÿÿÿÿGB j?fÿ…'”  ÿ¹¨ ÞaÊ–ÿ›}þ šŠƒÿ»@I 0à–Àÿ$0< 0à–Àÿo j?fÿŒ@  ÿ ¾  ÿà:.j?fÿO{Qj?fÿÿÿÿÿÿÿÿÿ¯F‰0à–ÀÿÀdÚ ÿVVU ÿ@I P´ eÿ`ç ò\ÿºY ÿ:ksP´ eÿêN†ÿzh ~`V÷ÿÿÿÿÿÿÿÿÿ¿Al0à–ÀÿtQcÿRùV"ÙÿTrròz ­ÿ?ÎfØFÿÿÿÿÿÿÿÿÿ ˆ ÿü=êj?fÿ‘,WXÊÿOuðj?fÿ3v䆸ŸÿÿÿÿÿÿÿÿÿîXjj?fÿ­IXÊÿ™öÄáÚÞÿÊ• ÿÁi³ ÿOË0à–Àÿ’ý$h"—ÿÿÿÿÿÿÿÿÿ _Ej?fÿàN˜éÈuÿÿÿÿÿÿÿÿÿK» ÿ®T0à–Àÿ/9[0à–ÀÿC_‡ ÿ‰bÞj?fÿL{0à–Àÿ·PÔj?fÿKL8 6ïr-ÿÑÆ j?fÿxcÈ 0à–ÀÿÙï šŠƒÿ±T!0à–Àÿœ¦!šŠƒÿaU¶" ÿêv·"$h"—ÿÿÿÿÿÿÿÿÿ•mØ" ÿ+K#j?fÿ½m$¶k@rÿIÿÿÿÿÿÿÿ_P‰$0à–Àÿ FÜ$اÔÿÿÿÿÿÿÿÿÿ‚l%0à–Àÿ©>@% ÿJVX%x,µÿ n&j?fÿL«' ÿ¾E¤)4-¢ ÿï)0à–Àÿ{k* ÿ r*j?fÿÿÿÿÿÿÿÿÿPCs*j?fÿÓH +ÿ7 ..žŒ6•"o.ÄáÚÞÿPi‘0øˆ-`d<ç0 ÿb;¡1ÄáÚÞÿ^G¨1V"Ùÿþ1Ã10à–Àÿßê10à–ÀÿÙ$2j?fÿd*Ž20à–Àÿ@Ÿ2ÄáÚÞÿrA°2䆸Ÿÿ2.3 ÿ¤FP3P´ eÿ$F50à–ÀÿÙ*7ÄáÚÞÿ”2§7j?fÿÿÿÿÿÿÿÿÿéMA8éÈuÿp(þ8 ÿ@ Ö9täŽýÿ¥}: ÿïcš:ì=.ÿÈFÅ:0à–Àÿ­ ;V"Ùÿ‘q};FîNÿ§-­;j?fÿ‰‰j?fÿŽ3™>éÈuÿÿÿÿÿÿÿÿÿçA7@j?fÿ®?l@j?fÿÊÅ@ E^xÿÿÿÿÿÿÿÿÿZæA ÿãUóAj?fÿ÷ùB0à–ÀÿuqCj?fÿF_C$h"—ÿÏC ÿã)DP´ eÿdKEj?fÿ.E ÿGuXE0à–Àÿ5t€Ej?fÿ{‡E0à–Àÿâ—EÄáÚÞÿÿÿÿÿÿÿÿÿp«EÄáÚÞÿÿÿÿÿÿÿÿÿŽx¸E ÿäE0à–Àÿ:¤F ÿ· ¦FV"ÙÿqJ«F4-¢ ÿtMG0à–Àÿt?Gj?fÿÛqBGj?fÿf»G ÿ–)Hj?fÿTVHØ"Žgÿÿÿÿÿÿÿÿÿ 6pH4-¢ ÿB›HÀDâŒÿÿÿÿÿÿÿÿÿGÁHÿ.PbJ ÿÐ{­KÄáÚÞÿÿÿÿÿÿÿÿÿIN™LÄáÚÞÿÿÿÿÿÿÿÿÿb-³Lÿðk‘Mj?fÿs#ºM ÿ#tÑN0à–Àÿ„$‡OXÊÿ>PšŠƒÿƒt¡PV"Ùÿ§!FQj?fÿ¡0ËQéÈuÿÃLôQ ÿÓT ÿ´g^Tj?fÿ`•Tt(øxÿ^F»TP´ eÿh ØU ÿc{V ÿx-^V0à–ÀÿõeWTñ–ÿr»WšŠƒÿv\YŠ Iÿs˜Y ÿj:šYéÈuÿÿÿÿÿÿÿÿÿÛp¦Y ÿúSC[j?fÿŒ&H[ ÿÕ=j[šŠƒÿ¹Hˆ[ÄáÚÞÿÿÿÿÿÿÿÿÿ}¤[ÄáÚÞÿ+%?\Xíz@d9+]$h"—ÿÿÿÿÿÿÿÿÿT"í] ÿí57^ÄáÚÞÿ·U•^0à–Àÿ0K_0à–Àÿ~`j?fÿ`Gû`؉¨Àÿÿÿÿÿÿÿÿÿ"AaìzÐeÿ_[`bP´ eÿ~c¬é„mÿÿÿÿÿÿÿÿÿ+ ‘cˆnªÚÿÿÿÿÿÿÿÿÿ`&d0à–ÀÿÜh‡d0à–ÀÿVDŠdj?fÿÇm½dØybzÿ³5ÿe0à–ÀÿaJƒgÄáÚÞÿÿÿÿÿÿÿÿÿo 5h0à–ÀÿÎ#Öh ÿÓøiÿVRekÄáÚÞÿÿÿÿÿÿÿÿÿøt5lÄáÚÞÿÿÿÿÿÿÿÿÿv2ÐlÄáÚÞÿÿÿÿÿÿÿÿÿmÄáÚÞÿÿÿÿÿÿÿÿÿ [ynÄáÚÞÿ=xòn ÿ?4®oÿ³oÿ8>Rp ÿ$rÄáÚÞÿŽyLsj?fÿlt6ïr-ÿÿÿÿÿÿÿÿÿ×8¥tüÆ®|ÿÿÿÿÿÿÿÿÿHqªtÿ8+•uP´ eÿà[–uÿ“*©u$h"—ÿÿÿÿÿÿÿÿÿgYÂu ÿÇa)vP´ eÿÇ|$w¾ú ÿA3wj?fÿ,®w0à–Àÿ×:ExÄáÚÞÿÿÿÿÿÿÿÿÿ<=Ûx ÿºgßx6ïr-ÿÿÿÿÿÿÿÿÿö yÿÚd/yj?fÿpioyj?fÿCooyj?fÿÍ|zz´:B7ÿÿÿÿÿÿÿÿÿ†{ ÿ›t´{ÿÿÿÿÿÿÿÿÿÿÿÿÿ 4Ð{6<½ÿSï{j?fÿÝI'|$h"—ÿÿÿÿÿÿÿÿÿ^Š|j?fÿH)õ| ÿ’A}0à–Àÿ+2}ÄáÚÞÿÿÿÿÿÿÿÿÿ`}ÄáÚÞÿhMÆ~j?fÿ%8î~0à–Àÿl^0à–ÀÿÚP›}þ KL8 r»WÙï †ld»@I GuXE$F5ï)$0< ,®w³5ÿe¯F‰zSéMA8ºo:¿Al±T!x-^V%8î~d*Ž2’A}„m"#tÑN‘q};äE‚l%l^þ1Ã1Üh‡dtMGßê1xcÈ ®T_P‰$7 .0K_ÈFÅ:OËo 5h·U•^{‡E`&d÷ùBL{/9[TrrúSC[~`–)H _E§!FQdKE§-­;´g^TîXjÑÆ Cooy‰bÞ8 ÙvPCs*Úd/y5t€E®?l@pioyhMÆ~ŽyLs^Š|‰‰<Sï{ÚOuð n&4 tü=ê·PÔÇm½d¢M‹Óøi¹¨ à[–uHqªt?4®oÓH +ö y³o…'” ÃLôQþÿÿÿ¼LõþÿÿÿMõþÿÿÿtMõŽ3™>aJƒgêv·"9+]VRek“*©u’ý'5ÝI'|+2}¹Hˆ[O{Qv2ÐlÐ{­K×:Exøt5l r*â—Ep«EmIN™L”2§7ºgßxßhšltj:šYàN˜Ûp¦Ys#ºM$Ùp(þ8+K#H)õ|Ç|$wþÿÿÿØMõ ˆ¥}:™öh ØU†{gYÂu ¾ Ù*7$rPi‘0í57^ºY`} [yn@Ÿ2þÿÿÿRp.PbJF_Cþÿÿÿ Nõ©>@%ZæAs˜YaU¶"7 .OõŒ@ ö['ÀdÚ_[`bOõ.E‹6¢TuF=`•TJVX%JVX% Oõv\Yïcš: 4Ð{@I ­I„$‡O‘,W@ Ö9RùqJ«F¾E¤) 6pHRù,Oõ­ ;Zk¤^G¨1ƒt¡PÚGè· ¦FÇa)v¤FP3^F»Tã)D:ks"Aa8Oõt-ÓTõeWõeWDOõßQ±ßQ±POõd<ç0b-³LtQcêN†GÁH2.3+ ‘c+%?\3vrA°2Ôhþÿÿÿþÿÿÿ\Oõÿþ×8¥tÿÿÿÿÿÿÿÿ˜Kõ` ˆ@e „w„›þ^„w`„›þOJQJo(-ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüKõ`m@h „Є˜þ^„Ð`„˜þOJQJo(·ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ`Lõ`l@„„åþ^„`„åþCJOJQJo(·ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÈLõ Ê@CJ$OJ QJ o(" ÿÿÿÿMõ @e „Š „›þ^„Š `„›þOJ QJ o(·ðÿÿÿÿ€Mõ`c@e „Š „›þ^„Š `„›þOJ QJ o(-ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿäMõ @e „w„›þ^„w`„›þOJ QJ o(·ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿHNõ @e „w„›þ^„w`„›þOJQJo(-ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¬Nõ s@„„åþ^„`„åþCJOJQJo(·ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ@ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿhOõ @h„„^„`„OJQJ^Jo(·ðÿÿÿÿÿÿüÿÿü    åN7‰MGu#N Ce§%óU°“iè¯ Û  Ú -£ "s"Ç$Ñ$ÿ@€´´ o´´Ð$P@ÿÿUnknownÿÿÿÿÿÿÿÿÿÿÿÿ G‡z €ÿTimes New Roman5€Symbol3& ‡z €ÿArial?Courier Neu?5 ‡z €ÿCourier New71 Courier=" HelvArial;" Helvetica5& ‡za€ÿTahoma3Times;€Wingdings]& Rotis Sans Serif for Nokia"ˆVüe ;H&"Úz&9üG&R$Oƒ>$O>$Vü¥À´´€r4db"b"iœ5Î3ƒQVüßßH(ðÿ?äÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ièÿÿReference Toolkit Specification Hezel, UwePeter Thompsonüü                           ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~  € ‚ ƒ „ … † ‡ ˆ ‰ Š ‹ Œ Ž ‘ ’ “ ” • – — ˜ ™ š › œ ž Ÿ   ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ ­ ® ¯ ° ± ² ³ ´ µ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿ À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ ß à á â ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö ÷ ø ù ú û þÿà…ŸòùOh«‘+'³Ù0˜ÀÌàì $ @ L X dpx€ˆä Reference Toolkit Specificationefe Hezel, Uweoeze Normal.dotoPeter Thompsoni30eMicrosoft Word 10.0@lŒt @–äeSû¿@S«À@L䨜Ã$OþÿÕÍÕœ.“—+,ù®DÕÍÕœ.“—+,ù®L hp|„Œ” œ¤¬´ ¼ èäIBM>b"­  Reference Toolkit Specification TitleP :B_PID_LINKBASEäA  !"#$þÿÿÿ&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWþÿÿÿYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆþÿÿÿÈÉÊËÌÍÎþÿÿÿÐÑÒÓÔÕÖþÿÿÿýÿÿÿýÿÿÿÚþÿÿÿþÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿRoot Entryÿÿÿÿÿÿÿÿ ÀFÇ{C¨œÃÜ€Data ÿÿÿÿÿÿÿÿÿÿÿÿ%àd1TableÿÿÿÿXŠÝWordDocumentÿÿÿÿ8HSummaryInformation(ÿÿÿÿÿÿÿÿÿÿÿÿÇDocumentSummaryInformation8ÿÿÿÿÿÿÿÿÏCompObjÿÿÿÿÿÿÿÿÿÿÿÿjÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿ ÿÿÿÿ ÀFMicrosoft Word Document MSWordDocWord.Document.8ô9²qlibsynthesis-3.4.0.47.1/src/syncml_tk/doc/ReadmeMaintenance4_4.doc000066400000000000000000003430001226375725500245410ustar00rootroot00000000000000ÐÏࡱá>þÿ ÞàþÿÿÿÜÝÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿì¥ÁE@ ø¿X/bjbjƒæƒæ 8NáŒáŒû$UÿÿÿÿÿÿˆÐÐÐÐDDDX I I I8XI,„ILX´ÖÜIÜI(JJJÀLÀLÀL3Ö5Ö5Ö5Ö5Ö5Ö5Ö$¸ÙR ܘYÖDÀL€L€L@ÀLÀLYÖÐÐJJ|nÖrMrMrMÀLFÐJÐRJ3ÖrMÀL3ÖrMÀrM2N’s¹ÊÐ""9Õ$JÐI p_ ûï5Ä IM=ÑþÖ,„Ö0´Ö;Óþ¢Ü"M4¢Üü]ÕXXÐÐÐÐ]Õn¢ÜDËÕ<ÀLÀLrMÀLÀLÀLÀLÀLYÖYÖXX$|5¤VMXX|5SyncML Reference Toolkit Specification Release 4.4 May 9, 2004 READ ME Copyright Notice Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). All Rights Reserved. Implementation of all or part of any Specification may require licenses under third party intellectual property rights, including without limitation, patent rights (such a third party may or may not be a Supporter). The Sponsors of the Specification are not responsible and shall not be held responsible in any manner for identifying or failing to identify any or all such third party intellectual property rights. THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. The above notice and this paragraph must be included on all copies of this document that are made. File and Directory Structure The SyncML Reference Toolkit file tree is structured as shown in the following figure. Within syncml/src/sml the files of the toolkit itself are found. The transport handlers are stored in the directory syncml/src/xpt. Demos showing syncml at work will be organized within syncml/src/examples. syncml ------ docs ----- internal ! !---- bin ------ win Binary files (like dlls) ! !---- src ------ sml ------ inc ------ win Public Headers ! ! ! ! ! !--- palm ! ! ! !--- mgr ------ inc SyncML Core (Manager) ! ! ! ! ! !--- all ! ! !--- win ! ! ! !--- wsm ------ inc SyncML Workspace ! ! ! ! ! !--- all ! ! !--- palm ! ! !--- win ! ! !--- linux ! ! !--- epoc ! ! ! !--- xlt ------ inc SyncML En-/Decoder ! ! ! ! ! !--- all ! ! ! !--- lib ------ inc SyncML Library Funct. ! ! ! !--- all ! !--- win ! !--- examples Example code ! !--- xpt -- !--- bindings Transport Handlers ! !--- common ! !--- all ! !--- linux ! !--- macosx ! !--- palm ! !--- tcp ! ! !--- all ! ! !--- linux ! ! !--- macosx ! ! !--- palm ! ! !--- win ! !--- win !--- http ! !--- all ! !--- linux ! !--- macosx ! !--- palm ! !--- win !--- obex ! !--- palm ! !--- smlobex ! !--- win !--- wsp !--- all !--- awsp !--- inc !--- palm !--- win Supported Platforms The SyncML Reference Toolkit has been implemented to be portable to as many hardware platforms and operating systems as possible. Nevertheless it is not possible to achieve an full platform independent code. The SyncML consortium therefore focusses on the following platforms: Windows 32 The deliverables target Windows 95 and NT 4.0 and comprise: Source Files. Several subdirectories named ../win hold files specific to the Windows target (e.g. syncml/src/sml/wsm/win). When compiling all these Windows-directories must be included. All other directories, which hold files specific to other targets must be excluded (e.g. ../palm; ../epoc)! The source code was developed using the following development environments : Microsoft Visual Studio C++ IBM Visual C++ GCC Palm-OS The deliverables target Palm OS 3.5 to OS 5.0 and comprise: Source Files. Several subdirectories named ../palm hold files specific to the Palm target (e.g. syncml/src/sml/wsm/palm). When compiling all these Palm-directories must be included. All other directories, which hold files specific to other targets must be excluded (e.g. ../win; ../epoc)! The source code was developed using the following development environments : Metrowerks GCC The Toolkit for Palm runs on Palm OS 3.1 too. Due to limitations of that version of the operating system, the size of the workspace is restricted to maximim 50kBytes. Not really recommended these days. LINUX To compile and run SyncML under a Linux Platform, the Win32 source code is used. Please follow the instructions in the README.linux file in the “src/bld” directory. Changes in the Maintenance 4.4 Release Removed binaries from the distribution. Added example directory in src. Mgr.h – Fixed bug declaring a variable with inappropriate type in struct instance_info_s Mgr.c - Fix compilation error if NOWSM macro is defined Smldef.h - Fixed compilation error if NOWSM macro is defined Added -Wall to CFLAGS, Removed unused variables and functions to obexbinding.*, obex.c, settings.c transact.c wsphttp.c, xptihttp.h, xpt-auth.c, xltdevinf.c, xpt-tcp.c, httptrans.c, xpt-http.c, define.h (in sml/inc/win). (General cleanup). Changes in the Maintenance 4.3 Release Fixed win .def files to work with NOWSM flag. Added extra #ifdefs to work with the NOWSM flag. Removed extra copy of the syncml_tk_prefix.h file. Fixed the problem – should apply to other similar flags. Changes in the Maintenance 4.2 Release OBEX bugs fixed. Added MacOSX support. Added SSL support for PalmOS 5.0 (alpha) and PocketPC 2002. Updates for Linux. Memory change to allow you to not use the toolkit memory structure. Added support for SyncML 1.1.1. New API function smlStartMessageExt() with parameter to specify SyncML version. Changes in the Maintenance 4 Release Obex transport binding was fixed to work properly with the XPT communication API. Sofar it’s only tested on Win32 systems running Windows 2000 (OBEX / IR and OBEX / TCP/IP) Implementing several DTD changes to support device management Implementing new extension for “Progress Information” usind a new tag “NumberOfChanges” Implementing new extension for “Large Object Handling” using a new flag MoreData for Item-Tags Implementing new extension for “Large Object Handling”, new API to calculate remaining space for data after setting up the tag-structure skeleton Implementing new extension to transport toolkit to support cryptographic security against manipulation during transport, new header field “x-syncml-hmac” (HTTP and OBEX only, not WSP) Bug fix for an Microsoft IIS-Hack in HTTP transport binding Bug fix for a minor bug causing the HTTP transport binding toolkit part to crash if message type string is longer than allowed 4.1: Declarating function ltoa() in linux-special file src/xpt/bindings/http/linux/xptihttp.h 4.1: Adding support for ‘SupportLargeObjs' and 'SupportNumberOfChanges' tags in device information dtd  SyncML Reference Toolkit Read Me  SAVEDATE \@ "yyyy-MM-dd" \* MERGEFORMAT 2001-09-18 Copyright © Ericsson, IBM, Lotus, Matsushita Communication Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). All Rights Reserved.  SyncML Reference Toolkit Read Me  SAVEDATE \@ "yyyy-MM-dd" \* MERGEFORMAT 2001-09-18 Copyright © Ericsson, IBM, Lotus, Matsushita Communication Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). All Rights Reserved.   '124789>?@HX;<=Z¸Æ%3kv~€”¢ËäøñêñêñêãêÔøÄ¹±§Ä››ƒ›w›ie§Z§Mhu#N56CJOJQJhu#N<CJOJQJhu#Nhu#NB*CJOJQJphh ZìB*OJQJphhu#NB*OJQJphhu#NB*OJQJphhu#NB*OJQJphhu#NCJOJQJhu#NOJQJhu#NCJOJQJhhu#N5B*CJOJQJphh“iè5CJ$mH nH sH u h“iè5CJ$ h]`%5CJ$ hóU°5CJ$ hu#N5CJ$'@HY—× ( h ¢ ã & d £ Í Î  T “ Ô  V ˜ Ú b òòòçåååååååååååååååååååååå $¤h1$7$8$H$ $¤€1$7$8$H$a$û,P/W/ýýýb Ÿ à &h¬×Ø<Z€£­æðz¯ÐH{®ÏýýýýýýýýýòâÚÏÏÏÏÏÏÏÏÏÏÏÏ d@ÿ1$7$8$H$1$7$8$H$ Æ&¤x¤x1$7$8$H$ 1$7$8$H$gd Ceä%_abœ®eyz Yef¼ÎÐ’“ÍÎ  DE€‘¦»ÅÆ.4öéöéÞöéöÔöéöéÊöÀ°ÀöéöÔ¦Ô¦Ô¦Ô¦Ô¦Ô–’„t’o’ghu#NOJQJ hu#N5hu#N5B*CJOJQJphhu#N5B*OJQJphhu#Nhu#N5B*CJOJQJphh CeCJOJQJh Zìh Zì56CJOJQJh ZìCJOJQJhu#NCJOJQJhN7CJOJQJhu#N6CJOJQJhu#N56CJOJQJhu#NCJOJQJ(ÏBu©ÜEf¯Û/{§Ú #f†Ðü2mªèôôôôôôôôôôôôôôôôææôôØØØØØ d@ÿ1$7$8$H$gdN7 d@ÿ1$7$8$H$gd Zì d@ÿ1$7$8$H$è$_¡å*m¯êY–ÔK»ú5h£ßV‘¦ññññññññññññññññññññññññÚ$ Æ@„°„Pþ¤ 1$7$8$H$^„°`„Pþ d@ÿ1$7$8$H$gdN7¦»Æ) * w “ ¢ ¦ ® ê " "Z"e"i"j"5#;#à#÷à÷É÷÷ÉÉÉà÷É÷÷ÉÉ÷÷ྠ1$7$8$H$gd“iè & F  Æh„h„˜þ1$7$8$H$^„h`„˜þ$ ÆÐ„°„Pþ¤ 1$7$8$H$^„°`„Pþ1$7$8$H$4e{ & w ¥ ¦ ­ ® Ñ Û ê ö !!K!b!ú! "Z"h"#4#5#:#;#ß#à#á#â# $S$«$¬$ã$ä$ï$ %!%ø%&&&üôüôüïüáÑüÍüïüôüôüôüïüÉüáÑü²ü¢–’ƒ’ƒ–’ƒ’ƒüh Zìh]`%h]`%B*OJQJphh]`%h]`%B*OJQJphh]`%5B*CJOJQJphhu#N5B*CJOJQJph h“ièhu#Nh§%h‰MGhu#N5B*CJOJQJphhu#N5B*OJQJph hu#N5hu#NOJQJhu#N+à#â# $ $3$S$¬$ä$!%&&:&;&i&óáÓ±©—‰x & F dð1$7$8$H$gdóU° dð1$7$8$H$gdóU°$ Æ@¤ 1$7$8$H$gdóU°1$7$8$H$ & F dð1$7$8$H$gd Zì & F dð1$7$8$H$gd]`% dð1$7$8$H$gd]`%$ Æ@¤ 1$7$8$H$gd]`% Æh1$7$8$H$ &:&'.'0':';'K'L'Û'ô'õ'(d(f(Œ(¬,ù,û,ü,!-"-K-L-V-W-e-Ÿ-.#.$.%.&.ðäÔÄÔ¸¬¸¬ ¬ ‘ ðäzärnrnrnrn_ZnTnr hu#NCJ hu#Nhhu#NhmH nHsH tHuhu#Njhu#NU-hóU°B*OJQJhmHnHphsHtHuh‰MGh‰MGB*OJQJphh‰MGB*OJQJphh“ièB*OJQJphhu#NB*OJQJphh“iè5B*CJOJQJphhu#N5B*CJOJQJphhóU°B*OJQJphhóU°5B*CJOJQJph i&š&Í&':';'L'b'ž'±'õ'f(Œ((:)x)Ð)/*îîîßÔÆÆÆÆÆµ£•îîîî dð1$7$8$H$gdóU°$ Æ@¤ 1$7$8$H$gdóU° & F dð1$7$8$H$gd‰MG & F dð1$7$8$H$ dð1$7$8$H$$ Æ@¤ 1$7$8$H$ & F dð1$7$8$H$gdóU°/*Á*y+µ+4,’,ú,û,--X-Y-Ÿ-$.%.@.I.‚.ƒ.É.N/O/P/R/S/îîîîîîàÜÜÜÚÕÕÚÜÜÜÚÕÕÚÚÚÚ$a$¤  dð1$7$8$H$gdóU° & F dð1$7$8$H$gdóU°&.K.L.u.v.€...9/O/P/Q/S/T/W/X/üôüôüôüåüá×üÍüÁhóU°B*OJQJphjp2hu#NCJUjhu#NCJUh Zìhu#NhmH nHsH tHujhu#NUhu#NS/U/V/W/X/ýýýï dð1$7$8$H$gdóU°6 00P P &P °‚. °ÆA!°8"°8#p$R%°°Þ°2p2Dd&& `+`+ffð<² ð C ðA¿ÿðÂbðà1„oœÅr<,;ÖFQ[‡¬bÿ¼1Dcnð´1„oœÅr<,;ÖFQ[‡¬bÿ‰PNG  IHDR&&è¬ÖgAMA±ˆ•˜ô¦ pHYs ø øf&<ý IDATxœíÝytU¢Çñºˆö"$ÄƃèÂ.Žì0 ‹¨Œ ›(F‘a—qæ Ûˆ ‚ìˆG}"¢(úØQGD-ÀŒ$  D ô}Ü¡^Ñtª·Û ù~þð`§êÖ­êêúÕ½u«Ê0Üà„¡®ܨÂöZ!Ô(¹±Âv«@Ø’R†!„Pÿ+á9Jxn/sá|²¾‘ãp8âããC] ¸ÁüòË/N§3Ôµ(Y˜FŽ”2>>>+++Ô€LBBBvvvx¶u¡® ¼ rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBäØ"¥tùG™S\9¶!\þ¡¸Œ9Ù.*„º7)¥âÂ… §N:~üøéÓ§333 OŸ>m†ÓéT“ !TÒÔ¬Y³R¥JIII5jÔ¸õÖ[ãããëׯo–€"rJ ¥,,,|áÂãZl¨h1ÿaåÒÐQÓDFF&$$$$$4lذQ£FÉÉÉ­ZµºõÖ[ !„ÊùóçKk‹ !ªU«vCì™RÊüüü¢¢¢ÿêp8ªU«Vâ\çÏŸwù0**ªråʯ"œÚÑëׯ/µ+**Ú²eËàÁƒ+Uª$„B8ŽÀþðÌ2G\\܈#þõ¯é_S”gN§SJ™ Jáp8<êjÚråʕڵk—¶"Íš5S+ëâܹsê—h=zt‰ßpTŸJxž1p-ç¿òòò^|ñŤ¤¤6mÚ¬\¹²°°Ð0 !„ÙiªÅ£†‘““³lÙ²Ž;¶k×nñâÅ—.] ಀҨƒ‘uo´Rýè£B]M[–.]zöìY÷µ0,«YâŒÒ2&Èe‘c†±bÅŠ;ï¼óå—_>qâ„qm_T{¡Ãá  T»µu)ßÿýèÑ£[¶l¹aÆ@- ð¬´[í“~ø¡æúøàÊ•+Ó§O/mET“¥´yÝÿÀ_:JSN#ÇÜ·V¯^Ý´iÓ!C†;vÌ¥M­& l+Ç0 §Ó©ÊtY”ò§Ÿ~êÞ½{‹-V¯^Ø…î<a322–-[f*å‰'fee•ø§2ë,¯u0¡^(U9Ã0Š‹‹Ç׿ÿ„º.ÿ¥ú4222ú÷ï?lØ05Z )åSO=uîÜ9#\»›233ßxãP×Þ)‘#¥¼råJ·nÝæÍ›g„ÓÏIõ­«3¯wß}·mÛ¶G u¥P~åçç¿òÊ+¡®E©V­Ze„q %*‘ãt:‡þå—_šÿë[9%Ž1?÷¡@ë5LÕÏÖºuëÍ›7ûV=À>—}ظ¶7¾þúëÿþ÷¿C[·]¾|yÉ’%êßî•GØ*‘3uêÔ÷ßß°âýdŒýU gÏžíÛ·ïÙ³gý¯$`“õwqùòå7ß|3´õ)ÑìÙ³­YHØÜ(Ê]äüðÃ/½ô’ˆö¸‡Q•þ:0ögÏž4hPÀG1Vê,Çá¸î€ ZÛ|ðAqqq¨*æÂüQL:Õ°üŠé^»Q”£§H)sss|ðAkç•EIMkܸqƒ êÖ­[«V-óÃâââ“'Oæåå?þàÁƒyyyòÚ£ „Çx¨³a›6mJKKãJ)‚Gí–ÉÉÉõë×߸q£aÙÛ³²²fÍš5qâÄVð:?þxAA¼þɃþæ›oÔ}€DО>0iÒ$ßêãp8Ôý4qqq¯¼òŠºõ¬Ä•Í‹ŠŠ80kÖ¬:”xÉÇ>µè-[¶|ƒ qß]+UªtìØ±P×÷¿Ö¯_ïò#BÔ©S''''!!Áå·“’’Rb!j$ž‹Q£Fi^— áéa¡¨¨héÒ¥¾Íët:£££§OŸ~øðáñãÇ׬YÓ(å5?ŒˆˆhÒ¤Éøñã¿ùæ›Ï>û¬^½z†O# ÌVѧŸ~*Ãû& Üè„]ºt‰u¹$YXX¨:²ÂÁßÿþw—‘”rüøñµk׿§þÊQä8pàÌ™3>Ì(¥Œß¾}ûĉcbb ïú={öܳgOÿþýÍOì¼Ö{ Nî$EÐH)£££'L˜`žÜ˜»Ü²eË233C]AcË–-[·nuùV«Ví±Ç3Âõ¼Vå(r¾ýö[¯¦7{bbbÖ¬Y“œœlýÜÛ¥W¯^ýÃ?|æ™g|h©¨‰322víÚåÕ¥ ¸ ÉÖóm¡¡ú¢Ÿx≻îºË¬ƒÂét^½zuøðá!G0oÞðã?ú6ã”)Sî¾ûî€Ôáå—_Þ¸qã?þèà Ã0–/_~×]w…éœÿ­à• -Ã4rss/_¾\§Nˆˆ5½¶­g­žËB =zäÈ‘¬¬¬Ó§OçääK)Ïž=UµjU§ÓÓ¸q㤤¤;î¸Cõå×f àºXK‹ŽŽ~ï½÷Ìs,s¹›7oÞ´iÓý÷ߨ…z+++kåÊ•âÚÓHk[cìØ±†÷ÃA§r9'Nœðê$HíÙÑÑÑ<òˆúÄÿyddäôéÓ{öìéÛ ç~øÁÛY‚ÔçC™Ö“SßJ0J?Ž«ÏwìØ±iÓ¦½{÷feeíß¿_½@ÏL÷F5mÚ´aÆÉÉÉ=zôPWׂǥz?ÿü³:doÛ¶mß¾}fÅÌꙉhÝKÍÿ­Q£Fûöí;wîܱcÇfÍšEDDõðzÇw´mÛöûï¿7+£ª·jÕªPEŽ”rÚ´iW¯^µF‹¢k×®76§ IÝ`_y‰)¥·rÔšZ½zõ¶Ù»uëvß}÷}ñÅ>Ì›žžžŸŸ¿~ýúE‹Ù¬¸6üoÙ²e>,±DRÊM›6͘1ðñ#7-Z´˜>}ºú÷ÁƒÇg“¦¥¥õêÕË()¨öïß¿fÍš7îÚµËý¥[†a8N5×áÇ>l~žœœÜ¼yóÞ½{÷îÝ;/ær:{öìÙ²eËæÍ›7oÞüŸÿüÇe3i¬Í/—mbþonnîš5kÖ¬YcFݺuÛ·oߦM›öíÛ£Õ«ê3vìØï¿ÿÞzùPJ¹bÅŠI“&ÝvÛm]¢_}õ•zÜ€uÕªUkñâÅæÿÒÊ/Ì£¤·C=kÑ¢…W{¤: ôìÙS–2Ú7N§såÊ•¾m‡Ã±sçÎììla·mgc:Ž;vj¤”C‡µÓah»xñbsöôôt¯¾‹… º×aíÚµMš4ñ¹;Å|Q^•*Už{î¹ .øö-«¹\æýç?ÿÙ²eKõùP·2™;@jjê¶mÛÜ+`‡u´*ÓR¬.Þ$%%™_Ÿ¹Ð=zø°•üdVÆ¥ÂóçÏ·NÆ i%œI‡£ð‰‡Ã‘ØjH)8àÛÞ „X·n”rÈ!êXfó ïp8†¨ú™ïa´³ •“'Oš%ø9ÇŽ{衇ì箇º™Û'55õ—_~ñmƒX÷{÷îMMMõ³nv*oÖÜápôîÝ[õ{<"Gµ`Áë&2ªBN§ 6¸ïo±±±—/_¶NFä(DŽwÂ'r”¹sç–x&ë3ŸË1«‘™™©^Mo¿™žžµ˜?¾°÷Šnó˜8iÒ$õ¢ U‚Ï‘sìØ±?ýéO·Ür‹º˜ásǸþ¨­þ[­Zµ—^z)//χMät:<8vìØÊ•+[ÎÁk师5kÖ¯¿þj¿Îž[9ª¡Ó®];÷eµhÑ¢°°ÐÛMä?üáîßõ¤I“\&#r"Ç;AŠuîé[}¾ùæ›ÀVÆÓ§Oˆˆðj-ºtéâÿr ëÕ«g3rTÞÔ©SçâÅ‹ÖB|‹œ#GŽ$&&ÚŸËBˆ;ï¼Óú(ä¿p!DRRRff¦Í:{nå(‡ªP¡‚58Õ¡õêÕ6—â¿ýû÷[—®v¼Š+fgg»LIä(á9åè¾s˜©üõ×_®.ðøã×®]Û«Y¾øâ ?ßG'¥üøã­¯ë.sz)åøñ㣣£ýY®aééé;w.í"„سgÏ´iÓÌÿõ0±¹6nÜøÇ?þ1¨+“J‚cÇŽõë×ïÒ¥K*¶qãÆ;w¶~¢Öú½÷Þ Ô"Ê4~üx— !}ôÑ`9D0”£Èq9§óÊ©S§ÔøÔwß}7??߃á˜UªT?~¼ýõC;w®? BÌŸ?ß«YªT©2jÔ(jÆéÓ§¨óågQž©­ôÆoØR¯6þçŸÞ§OŸüüüОTšµÝ»woïÞ½˜: °þ¯ZÍÿýßÿÕðN )ezzúúõë]>ŠŠšùäÛo¿‘‘árõBt¤µiòäÉöGK«ÉfÍšåóâ&NœèÕ~œ˜˜XTTä¾âÞFŽ~Bˆ‰'JßÚÊ•+ý/ç²ÿX‡ Š’xU¸a·ß~»ûNhe3r¤”+V¬p¯ÃáØ°aC0öjÅét®^½Z¸ ÁhÖ¬™zXƒ;"G!r¼¤È)..6ïRH%Åõ£l]~*THMM}衇^xá…/¾øâÌ™3ªý‰îܹӿ!ɬdçÎ}^ÜwÞéÕ~Ÿ[97~æ™g–/_¾sçÎóçÏËk»¨Yþ¹sçvïÞý?ÿó?ÇWâ}¨Æ UC§Äµ°ßÊ‘R~÷Ýw*Tp?Á Þе]»vEEE¹ìržCŽÈQˆï#rLcÇŽ ê=z>HIIyúé§?ýôSÏÝ ¥9sæL¥J•¼Zø° ó]se–¯&ëׯ_iEù9Âr—¥¢FÆ [´hѦM›vïÞ}üøñôôôo¿ývîܹýúõ«R¥ŠKöÛ_Šâïÿ{‰õߺu«ý¢\ZÀIIIï¾ûî•+Wìoù¼¼¼É“'W¨PÁlÙ_úsÏ=WZ±^EŽ”òÏþ³Ëft8¿ûÝï쯈WRSS]¾!Ä{ï½çáT‰ÈQˆï5r.\¸àÏSR‚Áü9ÅÅÅ;vóæÍ¥uU—f̘1^]¦r8Gõª•³{÷nóÐigu‡‡×˜ú9jî¹çž 6zX‘‚‚õF/ßR§´G6ôèÑër̘¼ÿþû½º[SQ+øÚk¯9¯nÆ2 #..®´qÞFNNNN¥J•\f‰ŠŠ ì CUU]F©©}/&&F½Ü½4DŽBäx'¨‘#¥û¬o—¬ï»ï>ë¶µ³¸F¹—3eÊo[K‡cúôé>ÔÙyg•ýµ¨_¿~‰[ÌÛVŽ”R½$к'¨ÿ.X° k§Œ3ÆeÕÔo¡Ì‰…ÈñN°#G0žËÉÉ‰ŽŽvœo¿ý¶Ìy‰%œ#§=}ÀE:u6lØ0aÂó“°ú†ÔÁQJ©|0{öliyÙ¥ûÄ-[¶LLL,ñ¯¥•¿aÃ;Sæåå}üñÇ6‹U%»Ü¯î?yíUf/¾ø¢Ï…tíÚ566Ö0 ‡ÃauÜíÛ·ÏۼƎëí5˜ !*T¨Ð·o_ÛÝU±k×.ÿ—®üõ¯UÇ5ë‡ÇŽ Ô ™V¯^}ùòe—3§æÍ›·k×. 宂ÚÊq&ô?þøüóÏÿæ7¿ «VŽõž å…^0ûôK\£µk×ÚΤ ŒŠŠ²Ók·hÑ"¯¶LíڵϞ=ë¹LZ9‡cäȑқœNçóÏ?ïUsÖ}'— ®ÃÛù1«Õ¬Y³yóæÂö56û¼*0°G)åèÑ£]Z9RÊŒŒŒ+Vø\æK/½tìØ1—Ï[¶lùä“Oú^W L!låØqúô鯾újΜ9ÇoÙ²¥ûýíÖ6Ëç.õv³(óæÍóP½O>ùĺt;Å–öÈáS§NEEEÙ,Ç0Œ&MšØÜ†>´r ¼þªJbË%í„¿ýíoíÌn~׿ÿýïRí`ð§•ãt:­÷ÚÄf3×]vv¶{óQ±ÿ~û…ÐÊQhåÜTbcc;uê”––¶dÉ’mÛ¶]¸páàÁƒüñ¤I“†ªNiÝû߬©ãymÄÚÆ=LÖ¥K—¸¸8aïȪ>îï#QæÍ›wåÊÃÞ µ¢W¯^eN曺uëÞrË-,ÐΕ(;;Û«&K||¼o sBˆ_|ѽ—òôéÓê”ÈN!ÖÉV­Z%¯o> !Ú´isÇw°Ú9"ÇwæÏ£qãÆ}ûö2eÊ;ï¼³k×®üüü={ö¼ýöÛiii=zôˆ‹‹3®?/¥§§{øIGGG?óÌ3†í£ªbݺuîŸ-]ºÔ«Šýáðjzûj×®ísHÖùóçmN©’ÉŸwц¹V­ZuíÚÕý{ùÇ?þ¡^cX&ë¯àwÞ1ÜvÚ€¶GÈ9¾³þ<Ì4)etttÓ¦M~øáW_}õ³Ï>;yòdVVÖ§Ÿ~:uêÔ:×zù}^îÉ“'wîÜéa‚'žxâÎ;ï´¿ëÖ­;~ü¸Ë‡6lP/œ¶©M›6Öç0Vdddxöx&„P=“7%)åk¯½V¹re—¯æÜ¹sê¥ öËY±b…z ‡õóZµj=òÈ#F¼DäøÎ¥áâáÃzõêõêÕëÙgŸýúë¯úé§.]º¸÷¼Ù!¯ =úúë¯=L=cÆ ûÅ^ºtéå—_6Ø*>?øàƒ2g´®Å’%Kû¼°åÕ·¦z&oJBˆÆ<ØýOóçÏ·¿‰òóóÏ{9IDATÓÒÒÌ}ÛìþÇ?þ¡Fë܈g(M¹8F>(éÜ*99yýúõ P/¾ýœŽ=êy‚®]»¶jÕªÌrÌu|çwÔ­†a!Š‹‹ÿùÏÚŸ½[·nå¤Ï=::ÚÎŽaNSâeꛆ”ràÀî$33³´ „.³†1þüÓ§O›ªßE³fÍÜÇaã&P^"Çð5uœNg`ë ª±páÂFùüä•'NxžQJ9þüÈÈHÏå˜?é‚‚‚©S§šÆ—-[vòäÉ2«¡fŽŽ~õÕWÕŒ7}H£FìLfnØÌÌÌ`V'Ä„;wnÓ¦ûŸÒÒÒìÄíž={¦M›f)eddä›o¾G!ÜTut8}úô}÷ÝçÛÑpàÀþ<×Ë…ùÓªQ£Æ /¼ðÈ#x5üÉTTTäùPѼyóîÝ»¯Y³F}RâRäµg— !fÏž–––˜˜xåÊ•—^zÉ(åynîÆg6qnúÓÒÄÄÄ={ö”9™¹a·mÛV\\Ú£§Ïi;"""–,Y’œœìp8œN§¹;effNž· löíôéÓç³Ï>3»ËJKãÚQiþüùÓ¦M[³fÍ/¿übs)ãÇ÷znXêÙ©†£&ÈÏÏÏÈÈhÑ¢EëpéÒ¥™3gÚœX}ï-[¶ìÞ½{ë`Õ¤I“!C†|ðÁf°©uë­·¦L™R⛜Ôþ–‘‘±uëVÕÖ7·gDDÄäÉ“ƒTU "з‚úp­^MÛm·ðõSVN§SÝÖàÃ&0`€ûó=Ýýúë¯êigÝ…UªT9qâ„:cµ9KiïÍôÌÛ[A[´háÓ6.ý…%í„j”„W•>|x x£ÊÙºu«¸ö@Ï‹V_bioëñçVPk}¤”ÙÙÙ±±±.ûŒ¢Ä·Ã™¢9r¤ûÎ9lØ0¶ŒÂ­  ·‚†XTTTƒ |›÷çŸÞ¶m[`룘/$öaÞøøx;‘3cÆ û}w?þøì×dذaö'¾ øðýåË—Ÿ={6 KWßøæÍ›ÕwZæ×jN’’ ”XÃ0êÕ«7gÎ÷¥/Z´Èýj¨ªüÙ³gß}÷]÷2Ÿzê©`Ta¢\DŽa>Œ§2O^ýõ@UÃzŒØ³g·§!æ)aÆ {_<ð@Ó¦Mí¤ŽZÙÕ«WKËÙ«çj$$$Ü{ï½^­Â®I“&U«VõvhûG}À:¬_¿Þóä^û÷iùlРA¬¬·ÞzË}b!Ä /¼péÒ%s-ÔÕºuëæÍ›»ª¡ò9)))>73W¬XqèС€TÃZu²_+k³æî»ï¶9oDDĤI“¼ZýúŒ;¶B…rq9Ðê·¿ý­·mÓ… jéÇŽó|W–»5jÔ«W/P(MDDD¿~ýÜw³)S¦¸ßœäEjF5n7±ò9}úôñ­ Ë0 !Ę1c.\¸ÀúìØ±Ã|:§ÍỶ+W®|Ï=÷ØŸkàÀ·ß~»-]JJÊ“O>éóV½qÝÿýÞβ{÷îG}TÔû³èììì^½zy5רQ£ô ™=z´õD¥È±cÇþú׿šJ)‹‹‹{ì1—’R<ØÛ—|ðáJݺu}>ÓB4mÚÔ«‡Úz““Ó¸qcáýƒ>UC§sçÎÞ.qöìÙf#Éÿ掺"½nÝ:Ÿ·À;|@J¹{÷nsKzÕHMMM5/àùàäÉ“III6‡u˜Ó!Ž;Vbþpát:ÇŒc\ÿ[UëoG]‹rhP¹reÿ_*Êð…áa¡]»vþ|û÷ïoÞ¼ùÔ©S/]º¤>‘Þßü(¥üòË/[µj•™™éÃìJÇŽ½š^JùÀ¨û|ó©‹ tëÖÍÿrnDÍš5KNN׆JÛÜ©¤”[·n:tèÕ«WÝÿTÚ,æ¿/]º4hР¬¬,ûõT‡õ^½z¹ˆƒD1iÒ$—ÇÊ©ƒ õæ¶>øÀ}•ûöí[«V-µ\©•³fÍß"G\/11ñ‰'žX¾|ù‘#GTÉæ Oëâ¬ÿ{éÒ¥íÛ·Ï;W½ÔÙŸjDFFzÛØRé'Mšä> Õ7Bˆ)S¦øó]ÜЭ)åÚµk£¢¢¼Ý˜jú[o½õé§ŸÞ»w¯‡JZ÷¨#GŽLš4)>>ÞúRZ; BDEEíÚµKá­ LŸ>ݽžBˆï¾ûNJ™­Æ_XGx«¿ú?”œVŽέœrtí·G))){÷îõ³œ¬¬¬yóæ©W®\¹yóæ5jРAll¬õ®·ÜÜÜììì'N9rdÇŽ/^4,1>=}ÇápŒ1ÂÛÑwjÏ›4iÒ’%KÔh]–îbøðá~–pCëÞ½ûèÑ£çÎkxÿmžß ¢veÃ0&Nœø›ßüFóI‘7ŠaÆ=ýôÓ~"ÝRPX&¸ÿÕ!DŸ>},Xª7%%%¥¥¥¹îò¶P!Dbbâ+¯¼¢«^½rt-Ç|Û¶m‹-2?ñí‡TÂò6!ÄСCGŽé±-[¶lÒ¤ÉÁƒ¥—W•TM*Uª4jÔ(ÿ«qsRΘ1#''G½DÙüЫ¨°~Ñæ¼Òò¬UŠjÞ¼ùûï¿ÂÇW !ÆÿÆoäçç[OMÜÏTž}öÙðyqê?üð·¿ý-$‹nܸñƒ>’E#ˆ×rL¿þúk›6mÄõÃfŠuxÒØ±cøhÑÉ“'›½dö[*jÊßÿþ÷©ÃÍѱ¦º‹ŠŠFmݤ¡Ú¯Ô¢“’’Ô¿2{>ƒ×±¦<û쳞»k×®}ùòå.ÑÏŽµêÙ³g·káEJY¥J•¯¾úê­·ÞªW¯^¦Žyº·téÒyóæ°’#FŒ°ùjK÷Zýñ T5nêkŠˆˆX°`Ák¯½mý<$UjÛ¶íÆkÖ¬’¥›ÔêOž<¹~ýú|#FŒ¨X±¢Æz!ôÂîh«:튊Š6lØŽ;zöìê¹’RFFF¦¥¥eff>úè£-¼AƒãÆóaÆÛn»­OŸ>­ÌÎ<žŽ7nß¾}êöØäMåÊ•/^üí·ßÞ~ûíf¬þj(jÑ111=ö˜,ý²ßO<¡·^½ò9VqqqkÖ¬Ùºuë]wÝ¥:FT{ÂÚ!¤Ÿ®{WŒùïîÝ»gff¾úê«111ÁXô„ \n)³’†aüå/ á·Ô¨Ü2¿SF‹%&&®]»væÌ™êÌÝå;õ¡ÀkeÖÍ\u~ݺuúÓŸ|(ÍŒ¤0`€KÉæf9rdP6jç+öÀ¡ÿµoÜ(nø#H@´jÕjÛ¶m_~ùå‹/¾Ø©S§J•*×?'*à„åÍ’æÛ´i3}úôíÛ·þù牉‰ÁX®ZPaa¡ýk¶ªzÍ›7ÔíŸN{ˬF@–n³(RÊ &dee-\¸P= /€ûË)¥¬X±âÀׯ_äÈ^äãR¸uŸ ”F©§®Y©‹ S§N à‚Jäù )¬Žò¡ê‰Õ¯Xó,22²cÇŽ:u2 ãÌ™3ŸþùÆ7lØ››Œ½AZF£uïÞýèÑ£‡z¯¢ÌýO-wêÔ©çγó“3¯*ÍŸ??222 ÇP!D­ZµFm5u€°?âNQ½zuõòVûåK)k×®=räÈ#Fdgg¯X±bÆ _}õ•ý¨+³VÑÑÑ}úôyàºuëf^@òÁƒ>xþüykÉñññþ×ÐJ1sæL—·´ !þD5µg:477×\Š”2>>¾Ä¶bÅŠjt:á=Íš5 u4 ý¶v§ö•úõë{õÃ`¸råÊÞ½{·mÛ¶cÇŽ½{÷îÛ·¯  @^?¤UM)¯96ç5/ÖiÔ¿o»í¶Ö­[·jÕªU«V)))Aê=+Mnnnݺu¯^½jç¨Úºuëï¿ÿ^CÝnV'NœøôÓO·lÙ²yóæ£Gª­{‘´Œ‡–aÓ†e·iß¾}Ë–-;tèpï½÷V©R%D«‚@BBBvvv‡±x@äØbòóóÏ;wêÔ©‹/æäääçç«cwnn®Ë,¥Œ‰‰QÝúÕ«W­^½z\\\\\\DD„õø¢yE^}õÕ &Øœ^±}ûvÞÕèk–äääüüóÏ999yyyN§3//Ïú5‡ÃQ½zu‡ÃQ­Zµ5jÔ©S§nݺµjÕRñ§äsDŽwÂ0r\xõË«ÃÄÅ‹7n|âÄ ›Ó;Žûî»oãÆA­U¹âmOà­pŽv}_x!á“7†aLœ8ñ—_~±?½”²_¿~Á«O9DÞ ftæÌ™Þ>ì rð_j|Aß¾}Ÿ~úéP×À͉k7÷§\+.Àvy¨¨ú°Aƒo¾ù¦ö*(/håÜ$\Þ-èòVë'Ö7Kš³·hÑbΜ9qqqú*  œ¡•sSqiܘOð0e—.]ÆŽÛ»wï`¿ˆœ›Ä°aÃÚ¶m[PP ^Áb>.://ïüùóæ«kÔ¨Q­Zµøøø:uꤦ¦vèÐÁú²/ò@P97‰¡C‡ú_¶T\ËhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9MˆÀ¶ÿÖµÁ÷”hèIEND®B`‚p2Dd&& `+`+ffð<² ð C ðA¿ÿðÂbðà1„oœÅr<,;ÖFQ[‡¬bÿ¼1´2cnð´1„oœÅr<,;ÖFQ[‡¬bÿ‰PNG  IHDR&&è¬ÖgAMA±ˆ•˜ô¦ pHYs ø øf&<ý IDATxœíÝytU¢Çñºˆö"$ÄƃèÂ.Žì0 ‹¨Œ ›(F‘a—qæ Ûˆ ‚ìˆG}"¢(úØQGD-ÀŒ$  D ô}Ü¡^Ñtª·Û ù~þð`§êÖ­êêúÕ½u«Ê0Üà„¡®ܨÂöZ!Ô(¹±Âv«@Ø’R†!„Pÿ+á9Jxn/sá|²¾‘ãp8âããC] ¸ÁüòË/N§3Ôµ(Y˜FŽ”2>>>+++Ô€LBBBvvvx¶u¡® ¼ rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9Mˆ€&D@"  ‘ЄÈhBäØ"¥tùG™S\9¶!\þ¡¸Œ9Ù.*„º7)¥âÂ… §N:~üøéÓ§333 OŸ>m†ÓéT“ !TÒÔ¬Y³R¥JIII5jÔ¸õÖ[ãããëׯo–€"rJ ¥,,,|áÂãZl¨h1ÿaåÒÐQÓDFF&$$$$$4lذQ£FÉÉÉ­ZµºõÖ[ !„ÊùóçKk‹ !ªU«vCì™RÊüüü¢¢¢ÿêp8ªU«Vâ\çÏŸwù0**ªråʯ"œÚÑëׯ/µ+**Ú²eËàÁƒ+Uª$„B8ŽÀþðÌ2G\\܈#þõ¯é_S”gN§SJ™ Jáp8<êjÚråʕڵk—¶"Íš5S+ëâܹsê—h=zt‰ßpTŸJxž1p-ç¿òòò^|ñŤ¤¤6mÚ¬\¹²°°Ð0 !„ÙiªÅ£†‘““³lÙ²Ž;¶k×nñâÅ—.] ಀҨƒ‘uo´Rýè£B]M[–.]zöìY÷µ0,«YâŒÒ2&Èe‘c†±bÅŠ;ï¼óå—_>qâ„qm_T{¡Ãá  T»µu)ßÿýèÑ£[¶l¹aÆ@- ð¬´[í“~ø¡æúøàÊ•+Ó§O/mET“¥´yÝÿÀ_:JSN#ÇÜ·V¯^Ý´iÓ!C†;vÌ¥M­& l+Ç0 §Ó©ÊtY”ò§Ÿ~êÞ½{‹-V¯^Ø…î<a322–-[f*å‰'fee•ø§2ë,¯u0¡^(U9Ã0Š‹‹Ç׿ÿ„º.ÿ¥ú4222ú÷ï?lØ05Z )åSO=uîÜ9#\»›233ßxãP×Þ)‘#¥¼råJ·nÝæÍ›g„ÓÏIõ­«3¯wß}·mÛ¶G u¥P~åçç¿òÊ+¡®E©V­Ze„q %*‘ãt:‡þå—_šÿë[9%Ž1?÷¡@ë5LÕÏÖºuëÍ›7ûV=À>—}ظ¶7¾þúëÿþ÷¿C[·]¾|yÉ’%êßî•GØ*‘3uêÔ÷ßß°âýdŒýU gÏžíÛ·ïÙ³gý¯$`“õwqùòå7ß|3´õ)ÑìÙ³­YHØÜ(Ê]äüðÃ/½ô’ˆö¸‡Q•þ:0ögÏž4hPÀG1Vê,Çá¸î€ ZÛ|ðAqqq¨*æÂüQL:Õ°üŠé^»Q”£§H)sss|ðAkç•EIMkܸqƒ êÖ­[«V-óÃâââ“'Oæåå?þàÁƒyyyòÚ£ „Çx¨³a›6mJKKãJ)‚Gí–ÉÉÉõë×߸q£aÙÛ³²²fÍš5qâÄVð:?þxAA¼þɃþæ›oÔ}€DО>0iÒ$ßêãp8Ôý4qqq¯¼òŠºõ¬Ä•Í‹ŠŠ80kÖ¬:”xÉÇ>µè-[¶|ƒ qß]+UªtìØ±P×÷¿Ö¯_ïò#BÔ©S''''!!Áå·“’’Rb!j$ž‹Q£Fi^— áéa¡¨¨héÒ¥¾Íët:£££§OŸ~øðáñãÇ׬YÓ(å5?ŒˆˆhÒ¤Éøñã¿ùæ›Ï>û¬^½z†O# ÌVѧŸ~*Ãû& Üè„]ºt‰u¹$YXX¨:²ÂÁßÿþw—‘”rüøñµk׿§þÊQä8pàÌ™3>Ì(¥Œß¾}ûĉcbb ïú={öܳgOÿþýÍOì¼Ö{ Nî$EÐH)£££'L˜`žÜ˜»Ü²eË233C]AcË–-[·nuùV«Ví±Ç3Âõ¼Vå(r¾ýö[¯¦7{bbbÖ¬Y“œœlýÜÛ¥W¯^ýÃ?|æ™g|h©¨‰322víÚåÕ¥ ¸ ÉÖóm¡¡ú¢Ÿx≻îºË¬ƒÂét^½zuøðá!G0oÞðã?ú6ã”)Sî¾ûî€Ôáå—_Þ¸qã?þèà Ã0–/_~×]w…éœÿ­à• -Ã4rss/_¾\§Nˆˆ5½¶­g­žËB =zäÈ‘¬¬¬Ó§OçääK)Ïž=UµjU§ÓÓ¸q㤤¤;î¸Cõå×f àºXK‹ŽŽ~ï½÷Ìs,s¹›7oÞ´iÓý÷ߨ…z+++kåÊ•âÚÓHk[cìØ±†÷ÃA§r9'Nœðê$HíÙÑÑÑ<òˆúÄÿyddäôéÓ{öìéÛ ç~øÁÛY‚ÔçC™Ö“SßJ0J?Ž«ÏwìØ±iÓ¦½{÷feeíß¿_½@ÏL÷F5mÚ´aÆÉÉÉ=zôPWׂǥz?ÿü³:doÛ¶mß¾}fÅÌꙉhÝKÍÿ­Q£Fûöí;wîܱcÇfÍšEDDõðzÇw´mÛöûï¿7+£ª·jÕªPEŽ”rÚ´iW¯^µF‹¢k×®76§ IÝ`_y‰)¥·rÔšZ½zõ¶Ù»uëvß}÷}ñÅ>Ì›žžžŸŸ¿~ýúE‹Ù¬¸6üoÙ²e>,±DRÊM›6͘1ðñ#7-Z´˜>}ºú÷ÁƒÇg“¦¥¥õêÕË()¨öïß¿fÍš7îÚµËý¥[†a8N5×áÇ>l~žœœÜ¼yóÞ½{÷îÝ;/ær:{öìÙ²eËæÍ›7oÞüŸÿüÇe3i¬Í/—mbþonnîš5kÖ¬YcFݺuÛ·oߦM›öíÛ£Õ«ê3vìØï¿ÿÞzùPJ¹bÅŠI“&ÝvÛm]¢_}õ•zÜ€uÕªUkñâÅæÿÒÊ/Ì£¤·C=kÑ¢…W{¤: ôìÙS–2Ú7N§såÊ•¾m‡Ã±sçÎììla·mgc:Ž;vj¤”C‡µÓah»xñbsöôôt¯¾‹… º×aíÚµMš4ñ¹;Å|Q^•*Už{î¹ .øö-«¹\æýç?ÿÙ²eKõùP·2™;@jjê¶mÛÜ+`‡u´*ÓR¬.Þ$%%™_Ÿ¹Ð=zø°•üdVÆ¥ÂóçÏ·NÆ i%œI‡£ð‰‡Ã‘ØjH)8àÛÞ „X·n”rÈ!êXfó ïp8†¨ú™ïa´³ •“'Oš%ø9ÇŽ{衇ì箇º™Û'55õ—_~ñmƒX÷{÷îMMMõ³nv*oÖÜápôîÝ[õ{<"Gµ`Áë&2ªBN§ 6¸ïo±±±—/_¶NFä(DŽwÂ'r”¹sç–x&ë3ŸË1«‘™™©^Mo¿™žžµ˜?¾°÷Šnó˜8iÒ$õ¢ U‚Ï‘sìØ±?ýéO·Ür‹º˜ásǸþ¨­þ[­Zµ—^z)//χMät:<8vìØÊ•+[ÎÁk师5kÖ¯¿þj¿Îž[9ª¡Ó®];÷eµhÑ¢°°ÐÛMä?üáîßõ¤I“\&#r"Ç;AŠuîé[}¾ùæ›ÀVÆÓ§Oˆˆðj-ºtéâÿr ëÕ«g3rTÞÔ©SçâÅ‹ÖB|‹œ#GŽ$&&ÚŸËBˆ;ï¼Óú(ä¿p!DRRRff¦Í:{nå(‡ªP¡‚58Õ¡õêÕ6—â¿ýû÷[—®v¼Š+fgg»LIä(á9åè¾s˜©üõ×_®.ðøã×®]Û«Y¾øâ ?ßG'¥üøã­¯ë.sz)åøñ㣣£ýY®aééé;w.í"„سgÏ´iÓÌÿõ0±¹6nÜøÇ?þ1¨+“J‚cÇŽõë×ïÒ¥K*¶qãÆ;w¶~¢Öú½÷Þ Ô"Ê4~üx— !}ôÑ`9D0”£Èq9§óÊ©S§ÔøÔwß}7??߃á˜UªT?~¼ýõC;w®? BÌŸ?ß«YªT©2jÔ(jÆéÓ§¨óågQž©­ôÆoØR¯6þçŸÞ§OŸüüüОTšµÝ»woïÞ½˜: °þ¯ZÍÿýßÿÕðN )ezzúúõë]>ŠŠšùäÛo¿‘‘árõBt¤µiòäÉöGK«ÉfÍšåóâ&NœèÕ~œ˜˜XTTä¾âÞFŽ~Bˆ‰'JßÚÊ•+ý/ç²ÿX‡ Š’xU¸a·ß~»ûNhe3r¤”+V¬p¯ÃáØ°aC0öjÅét®^½Z¸ ÁhÖ¬™zXƒ;"G!r¼¤È)..6ïRH%Åõ£l]~*THMM}衇^xá…/¾øâÌ™3ªý‰îܹӿ!ɬdçÎ}^ÜwÞéÕ~Ÿ[97~æ™g–/_¾sçÎóçÏËk»¨Yþ¹sçvïÞý?ÿó?ÇWâ}¨Æ UC§Äµ°ßÊ‘R~÷Ýw*Tp?Á Þе]»vEEE¹ìržCŽÈQˆï#rLcÇŽ ê=z>HIIyúé§?ýôSÏÝ ¥9sæL¥J•¼Zø° ó]se–¯&ëׯ_iEù9Âr—¥¢FÆ [´hѦM›vïÞ}üøñôôôo¿ývîܹýúõ«R¥ŠKöÛ_Šâïÿ{‰õߺu«ý¢\ZÀIIIï¾ûî•+Wìoù¼¼¼É“'W¨PÁlÙ_úsÏ=WZ±^EŽ”òÏþ³Ëft8¿ûÝï쯈WRSS]¾!Ä{ï½çáT‰ÈQˆï5r.\¸àÏSR‚Áü9ÅÅÅ;vóæÍ¥uU—f̘1^]¦r8Gõª•³{÷nóÐigu‡‡×˜ú9jî¹çž 6zX‘‚‚õF/ßR§´G6ôèÑër̘¼ÿþû½º[SQ+øÚk¯9¯nÆ2 #..®´qÞFNNNN¥J•\f‰ŠŠ ì CUU]F©©}/&&F½Ü½4DŽBäx'¨‘#¥û¬o—¬ï»ï>ë¶µ³¸F¹—3eÊo[K‡cúôé>ÔÙyg•ýµ¨_¿~‰[ÌÛVŽ”R½$к'¨ÿ.X° k§Œ3ÆeÕÔo¡Ì‰…ÈñN°#G0žËÉÉ‰ŽŽvœo¿ý¶Ìy‰%œ#§=}ÀE:u6lØ0aÂó“°ú†ÔÁQJ©|0{öliyÙ¥ûÄ-[¶LLL,ñ¯¥•¿aÃ;Sæåå}üñÇ6‹U%»Ü¯î?yíUf/¾ø¢Ï…tíÚ566Ö0 ‡ÃauÜíÛ·ÏۼƎëí5˜ !*T¨Ð·o_ÛÝU±k×.ÿ—®üõ¯UÇ5ë‡ÇŽ Ô ™V¯^}ùòe—3§æÍ›·k×. 宂ÚÊq&ô?þøüóÏÿæ7¿ «VŽõž å…^0ûôK\£µk×ÚΤ ŒŠŠ²Ók·hÑ"¯¶LíڵϞ=ë¹LZ9‡cäȑқœNçóÏ?ïUsÖ}'— ®ÃÛù1«Õ¬Y³yóæÂö56û¼*0°G)åèÑ£]Z9RÊŒŒŒ+Vø\æK/½tìØ1—Ï[¶lùä“Oú^W L!låØqúô鯾újΜ9ÇoÙ²¥ûýíÖ6Ëç.õv³(óæÍóP½O>ùĺt;Å–öÈáS§NEEEÙ,Ç0Œ&MšØÜ†>´r ¼þªJbË%í„¿ýíoíÌn~׿ÿýïRí`ð§•ãt:­÷ÚÄf3×]vv¶{óQ±ÿ~û…ÐÊQhåÜTbcc;uê”––¶dÉ’mÛ¶]¸páàÁƒüñ¤I“†ªNiÝû߬©ãymÄÚÆ=LÖ¥K—¸¸8aïȪ>îï#QæÍ›wåÊÃÞ µ¢W¯^eN曺uëÞrË-,ÐΕ(;;Û«&K||¼o sBˆ_|ѽ—òôéÓê”ÈN!ÖÉV­Z%¯o> !Ú´isÇw°Ú9"ÇwæÏ£qãÆ}ûö2eÊ;ï¼³k×®üüü={ö¼ýöÛiii=zôˆ‹‹3®?/¥§§{øIGGG?óÌ3†í£ªbݺuîŸ-]ºÔ«Šýáðjzûj×®ísHÖùóçmN©’ÉŸwц¹V­ZuíÚÕý{ùÇ?þ¡^cX&ë¯àwÞ1ÜvÚ€¶GÈ9¾³þ<Ì4)etttÓ¦M~øáW_}õ³Ï>;yòdVVÖ§Ÿ~:uêÔ:×zù}^îÉ“'wîÜéa‚'žxâÎ;ï´¿ëÖ­;~ü¸Ë‡6lP/œ¶©M›6Öç0Vdddxöx&„P=“7%)åk¯½V¹re—¯æÜ¹sê¥ öËY±b…z ‡õóZµj=òÈ#F¼DäøÎ¥áâáÃzõêõêÕëÙgŸýúë¯úé§.]º¸÷¼Ù!¯ =úúë¯=L=cÆ ûÅ^ºtéå—_6Ø*>?øàƒ2g´®Å’%Kû¼°åÕ·¦z&oJBˆÆ<ØýOóçÏ·¿‰òóóÏ{9IDATÓÒÒÌ}ÛìþÇ?þ¡Fë܈g(M¹8F>(éÜ*99yýúõ P/¾ýœŽ=êy‚®]»¶jÕªÌrÌu|çwÔ­†a!Š‹‹ÿùÏÚŸ½[·nå¤Ï=::ÚÎŽaNSâeꛆ”ràÀî$33³´ „.³†1þüÓ§O›ªßE³fÍÜÇaã&P^"Çð5uœNg`ë ª±páÂFùüä•'NxžQJ9þüÈÈHÏå˜?é‚‚‚©S§šÆ—-[vòäÉ2«¡fŽŽ~õÕWÕŒ7}H£FìLfnØÌÌÌ`V'Ä„;wnÓ¦ûŸÒÒÒìÄíž={¦M›f)eddä›o¾G!ÜTut8}úô}÷ÝçÛÑpàÀþ<×Ë…ùÓªQ£Æ /¼ðÈ#x5üÉTTTäùPѼyóîÝ»¯Y³F}RâRäµg— !fÏž–––˜˜xåÊ•—^zÉ(åynîÆg6qnúÓÒÄÄÄ={ö”9™¹a·mÛV\\Ú£§Ïi;"""–,Y’œœìp8œN§¹;effNž· löíôéÓç³Ï>3»ËJKãÚQiþüùÓ¦M[³fÍ/¿übs)ãÇ÷znXêÙ©†£&ÈÏÏÏÈÈhÑ¢EëpéÒ¥™3gÚœX}ï-[¶ìÞ½{ë`Õ¤I“!C†|ðÁf°©uë­·¦L™R⛜Ôþ–‘‘±uëVÕÖ7·gDDÄäÉ“ƒTU "з‚úp­^MÛm·ðõSVN§SÝÖàÃ&0`€ûó=Ýýúë¯êigÝ…UªT9qâ„:cµ9KiïÍôÌÛ[A[´háÓ6.ý…%í„j”„W•>|x x£ÊÙºu«¸ö@Ï‹V_bioëñçVPk}¤”ÙÙÙ±±±.ûŒ¢Ä·Ã™¢9r¤ûÎ9lØ0¶ŒÂ­  ·‚†XTTTƒ |›÷çŸÞ¶m[`룘/$öaÞøøx;‘3cÆ û}w?þøì×dذaö'¾ øðýåË—Ÿ={6 KWßøæÍ›ÕwZæ×jN’’ ”XÃ0êÕ«7gÎ÷¥/Z´Èýj¨ªüÙ³gß}÷]÷2Ÿzê©`Ta¢\DŽa>Œ§2O^ýõ@UÃzŒØ³g·§!æ)aÆ {_<ð@Ó¦Mí¤ŽZÙÕ«WKËÙ«çj$$$Ü{ï½^­Â®I“&U«VõvhûG}À:¬_¿Þóä^û÷iùlРA¬¬·ÞzË}b!Ä /¼péÒ%s-ÔÕºuëæÍ›»ª¡ò9)))>73W¬XqèС€TÃZu²_+k³æî»ï¶9oDDĤI“¼ZýúŒ;¶B…rq9Ðê·¿ý­·mÓ… jéÇŽó|W–»5jÔ«W/P(MDDD¿~ýÜw³)S¦¸ßœäEjF5n7±ò9}úôñ­ Ë0 !Ę1c.\¸ÀúìØ±Ã|:§ÍỶ+W®|Ï=÷ØŸkàÀ·ß~»-]JJÊ“O>éóV½qÝÿýÞβ{÷îG}TÔû³èììì^½zy5רQ£ô ™=z´õD¥È±cÇþú׿šJ)‹‹‹{ì1—’R<ØÛ—|ðáJݺu}>ÓB4mÚÔ«‡Úz““Ó¸qcáýƒ>UC§sçÎÞ.qöìÙf#Éÿ掺"½nÝ:Ÿ·À;|@J¹{÷nsKzÕHMMM5/àùàäÉ“III6‡u˜Ó!Ž;Vbþpát:ÇŒc\ÿ[UëoG]‹rhP¹reÿ_*Êð…áa¡]»vþ|û÷ïoÞ¼ùÔ©S/]º¤>‘Þßü(¥üòË/[µj•™™éÃìJÇŽ½š^JùÀ¨û|ó©‹ tëÖÍÿrnDÍš5KNN׆JÛÜ©¤”[·n:tèÕ«WÝÿTÚ,æ¿/]º4hР¬¬,ûõT‡õ^½z¹ˆƒD1iÒ$—ÇÊ©ƒ õæ¶>øÀ}•ûöí[«V-µ\©•³fÍß"G\/11ñ‰'žX¾|ù‘#GTÉæ Oëâ¬ÿ{éÒ¥íÛ·Ï;W½ÔÙŸjDFFzÛØRé'Mšä> Õ7Bˆ)S¦øó]ÜЭ)åÚµk£¢¢¼Ý˜jú[o½õé§ŸÞ»w¯‡JZ÷¨#GŽLš4)>>ÞúRZ; BDEEíÚµKá­ LŸ>ݽžBˆï¾ûNJ™­Æ_XGx«¿ú?”œVŽέœrtí·G))){÷îõ³œ¬¬¬yóæ©W®\¹yóæ5jРAll¬õ®·ÜÜÜììì'N9rdÇŽ/^4,1>=}ÇápŒ1ÂÛÑwjÏ›4iÒ’%KÔh]–îbøðá~–pCëÞ½ûèÑ£çÎkxÿmžß ¢veÃ0&Nœø›ßüFóI‘7ŠaÆ=ýôÓ~"ÝRPX&¸ÿÕ!DŸ>},Xª7%%%¥¥¥¹îò¶P!Dbbâ+¯¼¢«^½rt-Ç|Û¶m‹-2?ñí‡TÂò6!ÄСCGŽé±-[¶lÒ¤ÉÁƒ¥—W•TM*Uª4jÔ(ÿ«qsRΘ1#''G½DÙüЫ¨°~Ñæ¼Òò¬UŠjÞ¼ùûï¿ÂÇW !ÆÿÆoäçç[OMÜÏTž}öÙðyqê?üð·¿ý-$‹nܸñƒ>’E#ˆ×rL¿þúk›6mÄõÃfŠuxÒØ±cøhÑÉ“'›½dö[*jÊßÿþ÷©ÃÍѱ¦º‹ŠŠFmݤ¡Ú¯Ô¢“’’Ô¿2{>ƒ×±¦<û쳞»k×®}ùòå.ÑÏŽµêÙ³g·káEJY¥J•¯¾úê­·ÞªW¯^¦Žyº·téÒyóæ°’#FŒ°ùjK÷Zýñ T5nêkŠˆˆX°`Ák¯½mý<$UjÛ¶íÆkÖ¬’¥›ÔêOž<¹~ýú|#FŒ¨X±¢Æz!ôÂîh«:튊Š6lØŽ;zöìê¹’RFFF¦¥¥eff>úè£-¼AƒãÆóaÆÛn»­OŸ>­ÌÎ<žŽ7nß¾}êöØäMåÊ•/^üí·ßÞ~ûíf¬þj(jÑ111=ö˜,ý²ßO<¡·^½ò9VqqqkÖ¬Ùºuë]wÝ¥:FT{ÂÚ!¤Ÿ®{WŒùïîÝ»gff¾úê«111ÁXô„ \n)³’†aüå/ á·Ô¨Ü2¿SF‹%&&®]»væÌ™êÌÝå;õ¡ÀkeÖÍ\u~ݺuúÓŸ|(ÍŒ¤0`€KÉæf9rdP6jç+öÀ¡ÿµoÜ(nø#H@´jÕjÛ¶m_~ùå‹/¾Ø©S§J•*×?'*à„åÍ’æÛ´i3}úôíÛ·þù牉‰ÁX®ZPaa¡ýk¶ªzÍ›7ÔíŸN{ˬF@–n³(RÊ &dee-\¸P= /€ûË)¥¬X±âÀׯ_äÈ^äãR¸uŸ ”F©§®Y©‹ S§N à‚Jäù )¬Žò¡ê‰Õ¯Xó,22²cÇŽ:u2 ãÌ™3ŸþùÆ7lØ››Œ½AZF£uïÞýèÑ£‡z¯¢ÌýO-wêÔ©çγó“3¯*ÍŸ??222 ÇP!D­ZµFm5u€°?âNQ½zuõòVûåK)k×®=räÈ#Fdgg¯X±bÆ _}õ•ý¨+³VÑÑÑ}úôyàºuëf^@òÁƒ>xþüykÉñññþ×ÐJ1sæL—·´ !þD5µg:477×\Š”2>>¾Ä¶bÅŠjt:á=Íš5 u4 ý¶v§ö•úõë{õÃ`¸råÊÞ½{·mÛ¶cÇŽ½{÷îÛ·¯  @^?¤UM)¯96ç5/ÖiÔ¿o»í¶Ö­[·jÕªU«V)))Aê=+Mnnnݺu¯^½jç¨Úºuëï¿ÿ^CÝnV'NœøôÓO·lÙ²yóæ£Gª­{‘´Œ‡–aÓ†e·iß¾}Ë–-;tèpï½÷V©R%D«‚@BBBvvv‡±x@äØbòóóÏ;wêÔ©‹/æäääçç«cwnn®Ë,¥Œ‰‰QÝúÕ«W­^½z\\\\\\DD„õø¢yE^}õÕ &Øœ^±}ûvÞÕèk–äääüüóÏ999yyyN§3//Ïú5‡ÃQ½zu‡ÃQ­Zµ5jÔ©S§nݺµjÕRñ§äsDŽwÂ0r\xõË«ÃÄÅ‹7n|âÄ ›Ó;Žûî»oãÆA­U¹âmOà­pŽv}_x!á“7†aLœ8ñ—_~±?½”²_¿~Á«O9DÞ ftæÌ™Þ>ì rð_j|Aß¾}Ÿ~úéP×À͉k7÷§\+.Àvy¨¨ú°Aƒo¾ù¦ö*(/håÜ$\Þ-èòVë'Ö7Kš³·hÑbΜ9qqqú*  œ¡•sSqiܘOð0e—.]ÆŽÛ»wï`¿ˆœ›Ä°aÃÚ¶m[PP ^Áb>.://ïüùóæ«kÔ¨Q­Zµøøø:uꤦ¦vèÐÁú²/ò@P97‰¡C‡ú_¶T\ËhBä4!rš9Mˆ€&D@"  ‘ЄÈhBä4!rš9MˆÀ¶ÿÖµÁ÷”hèIEND®B`‚fœH@ñÿHNormalOJQJ_HmHnHsH tH uj@òj Heading 1$ & F¤ð¤ @& Æ75B*CJ OJQJmH sH uR@òR Heading 2!$ & F¤ ¤@& Æ7@CJF@!òF Heading 3 & F@& Æ@ÐCJZ@1òZ Heading 4. & F ÆÐ`„Є0ý¤ð¤P@&^„Ð`„0ýF@F Heading 5¤<¤@& Æð5:@: Heading 6 @& Æ€:@: Heading 7 @& Æ:@: Heading 8 @& Æ : @: Heading 9 @& Æ0DA@òÿ¡D Default Paragraph FontVi@óÿ³V  Table Normal :V ö4Ö4Ö laö (k@ôÿÁ(No List NþOòN Body¤x¤x Æ&B*CJOJQJmH sH uBþOB 11 BodyText„¤Ü^„CJB @BFooter$d Æ9r OJQJ>@">Header Æ  ø%OJQJ>þO2> 22 BodyText„% ¤Ü^„% .@Q.TOC 1OJQJ^þOR^ Heading 1TOC! Æâ‘ „â„ý¤x^„â`„ý 5B*CJªþObª Bulleted - 1t & Fÿ„w„›þ¤Ü>ÆTÿe-ð^„w`„›þCJ¬þOr¬Numbered List 1t & Fÿ„w„›þ¤Ü>ÆT€e.^„w`„›þFþOq‚FNumbered List 2 „Š ^„Š CJ6’6 Footnote Text¦þO¢¦ Bulleted - 2t & Fÿ„Š „›þ¤Ü>ÆTÿe-ð^„Š `„›þ>Á>TOC 2„‰„Xý^„‰`„XýOJQJ\þOÂ\ Heading 2TOC! Æ‹‘ „‹„Wý¤(^„‹`„WýB*CJ6á6TOC 3„Ý„­ü^„Ý`„­ü\þOâ\ Heading 3TOC! ÆÜ‘ „Ü„¯ü¤P^„Ü`„¯üB*CJDþOòDDocument Title¤€5CJ$DDTOC 4 Æ ‘ ‰‡ „  „<ü^„  `„<üXþOX Heading 4TOC! Æ¢ ‘ „¢ „:ü^„¢ `„:üB*CJ::TOC 5 "„ ^„  CJOJQJ::TOC 6 #„è^„è CJOJQJ::TOC 7 $„°^„° CJOJQJ::TOC 8 %„x^„x CJOJQJ::TOC 9 &„@^„@ CJOJQJ@Yr@ Document Map'-D OJQJJþO‚J CellBody (¤P¤PB*OJQJmH sH uTþO’T CellHeading )¤x¤x5B*OJQJmH sH uVþOòV Heading 02 *$¤h5B*CJOJQJmH sH uTþO²T Nonum Heading +1$¤x¤d5CJ$htH u0U@¢Á0 Hyperlink>*B*@V@¢Ñ@ FollowedHyperlink>*B* PþOâP Abstract .d,¤ðB*CJOJQJmH sH u¼þOò¼ Bulleted/ & Fÿ Æh„„åþ¤x>ÆTÿ·ð·······^„`„åþB*CJmH sH uRþOR BulletedCont0„¤P^„B*CJmH sH uRþOREquation1d¤È¤x Æ‘  B*OJ QJ BþO"B Figure 2¤x¤6B*mH sH uVþO2V Footnote3 Æä„ä„ÿ¤<^„ä`„ÿB*mH sH ubþOòb Heading 014$$¤ð¤@&d5B*CJ OJQJmH sH uL#LTable of Figures5„„pþ^„`„pþRþObR Numbered6 & F>¤x ÆB*CJmH sH u°þOr° Reference|7 & Fÿ Æ7„„åþ¤x>ÆT€[]^„`„åþB*CJRþO‚R SubTitle8$$d@a$5B*CJmH sH uNþOòN TableTitle9¤x ÆT6B*mH sH u,X@òÿ¡, Emphasis6>þOòÿ±> EquationVariables6>þOòÿÁ> ProgramCodeCJOJQJkH'.þOòÿÑ. SubscriptH*2þOòÿá2 SuperscriptH*4þOòÿñ4 SymbolCJOJQJkH*>þOòÿ> Underline>*CJOJQJkH'6"6Caption A¤x¤x6.)@¢!. Page NumberBþOñ2B DocumentOwnersC$a$CJDZ@BD Plain TextDOJQJmH sH udþObd Definition List E„h1$^„hCJOJQJhmH sH tH u`þOR` Definition Term F1$¤d¤dOJQJhmH sH tH uHþOñrH Editors NotesG6B*CJOJQJBþOñ‚B Code SnipetH¤x CJOJQJ^þO^ H1I$ & F1$¤ð¤d@&%5CJ(KH$OJQJhmH sH tH uZþOZ H2J$ & F1$¤d¤d@&!5CJ$OJQJhmH sH tH u0þOòÿ±0 Definition6TþOT H3L$1$¤d¤d@&!5CJOJQJhmH sH tH uTþOT H4M$1$¤d¤d@&!5CJOJQJhmH sH tH uPþOP H5N$1$¤d¤d@&5OJQJhmH sH tH uTþOT H6O$1$¤d¤d@&!5CJOJQJhmH sH tH uPþOP AddressP1$!6CJOJQJhmH sH tH ujþOj BlockquoteQ„h„h¤d¤d1$]„h^„hCJOJQJhmH sH tH u$þOòÿ!$ CITE6,þOòÿ1, CODE CJOJQJ8þOòÿA8 Keyboard5CJOJQJxþORx Preformatted+U1$ Æ# ¿~= ü»z9ø·!v%OJQJhmH sH tH un]@ñÿnz-Bottom of FormV$$d1$a$"<CJOJQJ_HhmH sH tH h\@ñÿh z-Top of FormW$&d1$a$"<CJOJQJ_HhmH sH tH ,þOòÿ, SampleOJQJ8þOòÿ‘8 Typewriter CJOJQJ,þOòÿ¡, Variable64þOòÿ±4 HTML Markup<B**þOòÿÁ* Comment<\þOâ\ Title1]$¤ð¤d1$a$!5CJ0OJQJhmH sH tH ubþOâb Subtitle1^$¤x¤d1$a$!5CJOJQJhmH sH tH uPþOòP RFC-P1_„°¤ð^„°CJOJQJmH sH tH uZþOZ Param$` & F¦„e„›þ¤P¤(1$^„e`„›þhmH sH tH uTþOT CODECompacta1$CJOJQJhmH sH tH u4þO14 Title Textb56þO26 00 BodyTextc¤Ü4þOB4Bullet 1 d & FŒe@RŒ ]`%HTML Preformatted7e Æ2”(¼ Päx  4 È#\'ð*„.2¬5@9OJQJ^JmH sH uX'ÿÿÿÿÿÿÿÿ ÿÿX'Nÿÿÿÿ'@HY—×(h¢ã&d£ÍÎT“ÔV˜Ú bŸà&h¬×Ø<Z€£­æðz ¯ Ð  H { ® Ï  B u © Ü  E f ¯ Û  / { § Ú #f†Ðü2mªè$_¡å*m¯êY–ÔK»ú5h£ßV‘¦»Æ)*w“¢¦®ê  Zeij5;àâ  3S¬ä!:;išÍ:;Lbž±õf Œ :!x!Ð!/"Á"y#µ#4$’$ú$û$%%X%Y%Ÿ%$&%&@&I&‚&ƒ&É&N'O'P'R'S'U'V'Y'˜0€€˜0€€p˜0€€p˜0€€p˜0€€p˜0€€p˜0€€p˜0€€˜0€€p˜0€€˜0€€˜0€€p˜0€€˜0€€˜0€€˜0€€p˜0€€˜˜0€€˜˜0€€˜˜0€€˜˜0€€˜˜0€€˜0€€p˜0€€p˜0€€˜0€€p˜0€€p˜0€€˜0€€p˜0€€p˜0€€˜0€€p˜0€€p˜0€€˜0€€p˜0€€p˜0€€p˜0€€p˜0€€p˜0€€p˜0€€p˜0€€p˜0€€p˜0€€˜0€€p˜0€€p˜0€€p˜0€€p˜0€€p˜0€€˜0€€p˜0€€p˜0€€p˜0€€p˜0€€p˜0€€˜0€€p˜0€€p˜0€€p˜0€€p˜0€€p˜0€€˜0€€p˜0€€p˜0€€p˜0€€˜˜0€€˜˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜ !0€€˜0€€˜0€€˜ !0€€˜ !0€€˜ !0€€˜0€€˜0€€˜ !0€€˜0€€˜0€€˜ !0€€˜ !0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜ !0€€˜ !0€€˜ !0€€˜ !0€€˜ !0€€˜ !0€€˜0€€˜0€€˜0€€˜ !0€€˜ !0€€˜ !0€€˜ !0€€˜0€€˜0€€˜ !0€€˜ !0€€˜ !0€€˜ !0€€˜ !0€€˜ !0€€˜0€€˜0€€˜ !0€€˜ !0€€˜ !0€€˜ !0€€˜ !0€€˜ !0€€˜ !0€€˜ !0€€˜ !0€€˜ !0€€˜0€€˜@0€€ø€˜@0€€p˜@0€€p˜@0€€˜@0€€ø€˜@0€€p˜@0€€˜@0€€ø€˜@0€€p˜@0€€p˜@0€€˜@0€€ø€˜@0€€p˜@0€€0õîܘ0€€˜0€€˜0€€˜0€€˜0€€'@HY—×(h¢ã&d£ÍÎT“ÔV˜Ú bŸà&h¬×Ø<Z€£­æðz ¯ Ð  H { ® Ï  B u © Ü  E f ¯ Û  / { § Ú #f†Ðü2mªè$_¡å*m¯êY–ÔK»ú5h£ßV‘¦»Æ)*w“¢¦®ê  Zeij5;àâ  3S¬ä!:;išÍ:;Lbž±õf Œ :!x!Ð!/"Á"y#µ#4$’$ú$Y'š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€˜0€€˜0€€š0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€š@0€€Èš0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š0€€š !0€€š0€€š0€€š !0€€š !0€€€š !0€€€š0€€€š0€€€š !0€€€š0€€€š0€€€š !0€€€š !0€€€š0€€€š0€€€š0€€€š0€€€š0€€€š0€€€š0€€€š !0€€€š !0€€š !0€€€š !0€€€š !0€€€š !0€€€š0€€€š0€€€š0€€€š !0€€€š !0€€€š !0€€€š !0 €€€š0€€€š0€€€š !0 €€€š !0 €€€š !0 €€€š !0 €€€š !0€€€š !0€€€š0€€€š0€€€š !0€€€š !0€€€š !0€€€š !0€€€š !0€€€š !0€€€š !0€€€š !0€€€š !0€€€š !0€€€š0€€€^^*ˆTWä4&&.X/ "%b Ïè¦à#i&/*S/X/!#$&W/&P[Pz…W4ÿ•€4ÿ•€ð@ð  @ñÿÿÿ€€€÷ð ððxð( ð ð𜢠ð c ðR€Š¿ÿƒÃ.¿ ``T`T`T`T"ñ¿€ðð ð𜢠ð c ðR€Š¿ÿƒÃ.¿ ``T`T`T`T"ñ¿€ðð ðð’ðð0ð( ð ððB ðS ð¿Ëÿ ?ð*W¸ÿÿÿòÿÿÿSýµ@¸ÿÿÿòÿÿÿSýµ@v~ fÆû$O'P'V'Y'û$O'P'Y'v~ fÆú$Y'û$O'P'Y'ÿÿ Lothar MerkMerkMerkMerkMerkMerk Thomas KleinIBM-UserIBM-UserPeter ThompsonüûÿÿÿÎÜÖ-ÿÿÿÿÿþÿÿÿÿÿÿÿÿÔhXíz@ÿºo:éÈuÿzS0à–ÀÿXlhdmÿÿÿÿÿÿÿÿÿ'5ÄáÚÞÿÿÿÿÿÿÿÿÿ¢M‹ ÿ1Í ÿB-6ïr-ÿµÚj?fÿ4 tj?fÿ$Ù ÿö[' ÿ†ld0à–Àÿ„m"0à–Àÿvj?fÿßhš6ïr-ÿÿÿÿÿÿÿÿÿZk¤V"ÙÿßQ±š…6$ÿt-j?fÿñI% ÿÿÿÿÿÿÿÿÿGB j?fÿ…'”  ÿ¹¨ ÞaÊ–ÿ›}þ šŠƒÿ»@I 0à–Àÿ$0< 0à–Àÿo j?fÿŒ@  ÿ ¾  ÿà:.j?fÿO{Qj?fÿÿÿÿÿÿÿÿÿ¯F‰0à–ÀÿÀdÚ ÿVVU ÿ@I P´ eÿ`ç ò\ÿºY ÿ:ksP´ eÿêN†ÿzh ~`V÷ÿÿÿÿÿÿÿÿÿ¿Al0à–ÀÿtQcÿRùV"ÙÿTrròz ­ÿ?ÎfØFÿÿÿÿÿÿÿÿÿ ˆ ÿü=êj?fÿ‘,WXÊÿOuðj?fÿ3v䆸ŸÿÿÿÿÿÿÿÿÿîXjj?fÿ­IXÊÿ™öÄáÚÞÿÊ• ÿÁi³ ÿOË0à–Àÿ’ý$h"—ÿÿÿÿÿÿÿÿÿ _Ej?fÿàN˜éÈuÿÿÿÿÿÿÿÿÿK» ÿ®T0à–Àÿ/9[0à–ÀÿC_‡ ÿ‰bÞj?fÿL{0à–Àÿ·PÔj?fÿKL8 6ïr-ÿÑÆ j?fÿxcÈ 0à–ÀÿÙï šŠƒÿ±T!0à–Àÿœ¦!šŠƒÿaU¶" ÿêv·"$h"—ÿÿÿÿÿÿÿÿÿ•mØ" ÿ+K#j?fÿ½m$¶k@rÿIÿÿÿÿÿÿÿ_P‰$0à–Àÿ FÜ$اÔÿÿÿÿÿÿÿÿÿ‚l%0à–Àÿ©>@% ÿJVX%x,µÿ n&j?fÿL«' ÿ¾E¤)4-¢ ÿï)0à–Àÿ{k* ÿ r*j?fÿÿÿÿÿÿÿÿÿPCs*j?fÿÓH +ÿ7 ..žŒ6•"o.ÄáÚÞÿPi‘0øˆ-`d<ç0 ÿb;¡1ÄáÚÞÿ^G¨1V"Ùÿþ1Ã10à–Àÿßê10à–ÀÿÙ$2j?fÿd*Ž20à–Àÿ@Ÿ2ÄáÚÞÿrA°2䆸Ÿÿ2.3 ÿ¤FP3P´ eÿ$F50à–ÀÿÙ*7ÄáÚÞÿ”2§7j?fÿÿÿÿÿÿÿÿÿéMA8éÈuÿp(þ8 ÿ@ Ö9täŽýÿ¥}: ÿïcš:ì=.ÿÈFÅ:0à–Àÿ­ ;V"Ùÿ‘q};FîNÿ§-­;j?fÿ‰‰j?fÿŽ3™>éÈuÿÿÿÿÿÿÿÿÿçA7@j?fÿ®?l@j?fÿÊÅ@ E^xÿÿÿÿÿÿÿÿÿZæA ÿãUóAj?fÿ÷ùB0à–ÀÿuqCj?fÿF_C$h"—ÿÏC ÿã)DP´ eÿdKEj?fÿ.E ÿGuXE0à–Àÿ5t€Ej?fÿ{‡E0à–Àÿâ—EÄáÚÞÿÿÿÿÿÿÿÿÿp«EÄáÚÞÿÿÿÿÿÿÿÿÿŽx¸E ÿäE0à–Àÿ:¤F ÿ· ¦FV"ÙÿqJ«F4-¢ ÿtMG0à–Àÿt?Gj?fÿÛqBGj?fÿf»G ÿ–)Hj?fÿTVHØ"Žgÿÿÿÿÿÿÿÿÿ 6pH4-¢ ÿB›HÀDâŒÿÿÿÿÿÿÿÿÿGÁHÿ.PbJ ÿÐ{­KÄáÚÞÿÿÿÿÿÿÿÿÿIN™LÄáÚÞÿÿÿÿÿÿÿÿÿb-³Lÿðk‘Mj?fÿs#ºM ÿ#tÑN0à–Àÿ„$‡OXÊÿ>PšŠƒÿƒt¡PV"Ùÿ§!FQj?fÿ¡0ËQéÈuÿÃLôQ ÿÓT ÿ´g^Tj?fÿ`•Tt(øxÿ^F»TP´ eÿh ØU ÿc{V ÿx-^V0à–ÀÿõeWTñ–ÿr»WšŠƒÿv\YŠ Iÿs˜Y ÿj:šYéÈuÿÿÿÿÿÿÿÿÿÛp¦Y ÿúSC[j?fÿŒ&H[ ÿÕ=j[šŠƒÿ¹Hˆ[ÄáÚÞÿÿÿÿÿÿÿÿÿ}¤[ÄáÚÞÿ+%?\Xíz@d9+]$h"—ÿÿÿÿÿÿÿÿÿT"í] ÿí57^ÄáÚÞÿ·U•^0à–Àÿ0K_0à–Àÿ~`j?fÿ`Gû`؉¨Àÿÿÿÿÿÿÿÿÿ"AaìzÐeÿ_[`bP´ eÿ~c¬é„mÿÿÿÿÿÿÿÿÿ+ ‘cˆnªÚÿÿÿÿÿÿÿÿÿ`&d0à–ÀÿÜh‡d0à–ÀÿVDŠdj?fÿÇm½dØybzÿ³5ÿe0à–ÀÿaJƒgÄáÚÞÿÿÿÿÿÿÿÿÿo 5h0à–ÀÿÎ#Öh ÿÓøiÿVRekÄáÚÞÿÿÿÿÿÿÿÿÿøt5lÄáÚÞÿÿÿÿÿÿÿÿÿv2ÐlÄáÚÞÿÿÿÿÿÿÿÿÿmÄáÚÞÿÿÿÿÿÿÿÿÿ [ynÄáÚÞÿ=xòn ÿ?4®oÿ³oÿ8>Rp ÿ$rÄáÚÞÿŽyLsj?fÿlt6ïr-ÿÿÿÿÿÿÿÿÿ×8¥tüÆ®|ÿÿÿÿÿÿÿÿÿHqªtÿ8+•uP´ eÿà[–uÿ“*©u$h"—ÿÿÿÿÿÿÿÿÿgYÂu ÿÇa)vP´ eÿÇ|$w¾ú ÿA3wj?fÿ,®w0à–Àÿ×:ExÄáÚÞÿÿÿÿÿÿÿÿÿ<=Ûx ÿºgßx6ïr-ÿÿÿÿÿÿÿÿÿö yÿÚd/yj?fÿpioyj?fÿCooyj?fÿÍ|zz´:B7ÿÿÿÿÿÿÿÿÿ†{ ÿ›t´{ÿÿÿÿÿÿÿÿÿÿÿÿÿ 4Ð{6<½ÿSï{j?fÿÝI'|$h"—ÿÿÿÿÿÿÿÿÿ^Š|j?fÿH)õ| ÿ’A}0à–Àÿ+2}ÄáÚÞÿÿÿÿÿÿÿÿÿ`}ÄáÚÞÿhMÆ~j?fÿ%8î~0à–Àÿl^0à–ÀÿÚP›}þ KL8 r»WÙï †ld»@I GuXE$F5ï)$0< ,®w³5ÿe¯F‰zSéMA8ºo:¿Al±T!x-^V%8î~d*Ž2’A}„m"#tÑN‘q};äE‚l%l^þ1Ã1Üh‡dtMGßê1xcÈ ®T_P‰$7 .0K_ÈFÅ:OËo 5h·U•^{‡E`&d÷ùBL{/9[TrrúSC[~`–)H _E§!FQdKE§-­;´g^TîXjÑÆ Cooy‰bÞ8 ÙvPCs*Úd/y5t€E®?l@pioyhMÆ~ŽyLs^Š|‰‰<Sï{ÚOuð n&4 tü=ê·PÔÇm½d¢M‹Óøi¹¨ à[–uHqªt?4®oÓH +ö y³o…'” ÃLôQþÿÿÿ$|Þþÿÿÿx|ÞþÿÿÿÜ|ÞŽ3™>aJƒgêv·"9+]VRek“*©u’ý'5ÝI'|+2}¹Hˆ[O{Qv2ÐlÐ{­K×:Exøt5l r*â—Ep«EmIN™L”2§7ºgßxßhšltj:šYàN˜Ûp¦Ys#ºM$Ùp(þ8+K#H)õ|Ç|$wþÿÿÿ@}Þ ˆ¥}:™öh ØU†{gYÂu ¾ Ù*7$rPi‘0í57^ºY`} [yn@Ÿ2þÿÿÿ¤}Þ•"o.b;¡1}¤[<=Ûx`Gû`B-`ç•mØ"Žx¸EçA7@GB {k*t?Gc{VÎ#ÖhÏCA3wÁi³8+•uVVUVDŠdo Ù$2K»µÚÊ•"AauqCðk‘MÛqBGT"í]L«'8>Rp.PbJF_Cþÿÿÿ~Þ©>@%ZæAs˜YaU¶"7 .p~ÞŒ@ ö['ÀdÚ_[`b|~Þ.E‹6¢TuF=`•TJVX%JVX%ˆ~Þv\Yïcš: 4Ð{@I ­I„$‡O‘,W@ Ö9RùqJ«F¾E¤) 6pHRù”~Þ­ ;Zk¤^G¨1ƒt¡PÚGè· ¦FÇa)v¤FP3^F»Tã)D:ks"Aa ~Þt-ÓTõeWõeW¬~ÞßQ±ßQ±¸~Þd<ç0b-³LtQcêN†GÁH2.3+ ‘c+%?\3vrA°2ÔhþÿÿÿþÿÿÿÄ~Þÿþ×8¥tÿÿÿÿÿÿÿÿ{Þ` ˆ@e „w„›þ^„w`„›þOJQJo(-ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿd{Þ`m@h „Є˜þ^„Ð`„˜þOJQJo(·ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÈ{Þ`l@„„åþ^„`„åþCJOJQJo(·ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ0|Þ Ê@CJ$OJ QJ o(" ÿÿÿÿ„|Þ @e „Š „›þ^„Š `„›þOJ QJ o(·ðÿÿÿÿè|Þ`c@e „Š „›þ^„Š `„›þOJ QJ o(-ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿL}Þ @e „w„›þ^„w`„›þOJ QJ o(·ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ°}Þ @e „w„›þ^„w`„›þOJQJo(-ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ~Þ s@„„åþ^„`„åþCJOJQJo(·ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ@ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÐ~Þ @h„„^„`„OJQJ^Jo(·ðÿÿÿÿÿÿüÿÿü    ‚¸ :õ++Z\P#Pk ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~  € ‚ ƒ „ … † ‡ ˆ ‰ Š ‹ Œ Ž ‘ ’ “ ” • – — ˜ ™ š › œ ž Ÿ   ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ ­ ® ¯ ° ± ² ³ ´ µ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿ À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ ß à á â ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö ÷ ø ù ú û þÿà…ŸòùOh«‘+'³Ù0˜ÀÌàì $ @ L X dpx€ˆä Reference Toolkit Specificationefe Hezel, Uweoeze Normal.dotoPeter Thompsoni31eMicrosoft Word 10.0@´³! @. Kû¿@®Uñ¢À@âTÝï5Ä„wþÿÕÍÕœ.“—+,ù®DÕÍÕœ.“—+,ù®L hp|„Œ” œ¤¬´ ¼ èäIBMCé$­  Reference Toolkit Specification TitleP :B_PID_LINKBASEäA  !"#$%&'þÿÿÿ)*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZþÿÿÿ\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËþÿÿÿÍÎÏÐÑÒÓþÿÿÿÕÖרÙÚÛþÿÿÿýÿÿÿýÿÿÿßþÿÿÿþÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿRoot Entryÿÿÿÿÿÿÿÿ ÀF`„*ûï5Äá€Data ÿÿÿÿÿÿÿÿÿÿÿÿ(àd1Tableÿÿÿÿ[žàWordDocumentÿÿÿÿ8NSummaryInformation(ÿÿÿÿÿÿÿÿÿÿÿÿÌDocumentSummaryInformation8ÿÿÿÿÿÿÿÿÔCompObjÿÿÿÿÿÿÿÿÿÿÿÿjÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿ ÿÿÿÿ ÀFMicrosoft Word Document MSWordDocWord.Document.8ô9²qlibsynthesis-3.4.0.47.1/src/syncml_tk/opensource_license.txt000066400000000000000000000042631226375725500240700ustar00rootroot00000000000000LICENSE The Copyright Holders of this software, including all accompanying documentation ("Software"), hereby grant, royalty free and for any purpose, permission to use, copy, modify and prepare derivative works therefrom, distribute, publish, sublicense and sell copies of the Software and to permit persons to whom the Software is furnished to do the same, all subject to the following conditions: 1. The complete text of the following noticeshall be reproduced on each copy or substantial copy of the Software in a location readily viewable to users of the Software: NOTICE Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001-2002). All Rights Reserved. Implementation of all or part of any Software may require licenses under third party intellectual property rights, including without limitation, patent rights. The Copyright Holders are not responsible and shall not be held responsible in any manner for identifying or failing to identify any or all such third party intellectual property rights. THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, NOKIA, OPENWAVE, PALM INC., PSION, STARFISH SOFTWARE, SYMBIAN AND ALL OTHER SYNCML SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., LTD, MOTOROLA, NOKIA, OPENWAVE, PALM INC., PSION, STARFISH SOFTWARE. SYMBIAN OR ANY OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE.libsynthesis-3.4.0.47.1/src/syncml_tk/src/000077500000000000000000000000001226375725500202255ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/000077500000000000000000000000001226375725500210205ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/SyncML.def000077500000000000000000000047101226375725500226520ustar00rootroot00000000000000EXPORTS smlAddCmd smlAlertCmd smlAllocAdd smlAllocAlert smlAllocAtomic smlAllocChal smlAllocCopy smlAllocCred smlAllocDelete smlAllocDevInfCTCap smlAllocDevInfCTData smlAllocDevInfCTDataList smlAllocDevInfCTDataProp smlAllocDevInfCTDataPropList smlAllocDevInfCtcapList smlAllocDevInfDSMem smlAllocDevInfDatastore smlAllocDevInfDatastoreList smlAllocDevInfDevInf smlAllocDevInfExt smlAllocDevInfExtList smlAllocDevInfSyncCap smlAllocDevInfXmit smlAllocDevInfXmitList smlAllocExec smlAllocGeneric smlAllocGet smlAllocItem smlAllocItemList smlAllocMap smlAllocMapItem smlAllocMapItemList smlAllocMetInfAnchor smlAllocMetInfMem smlAllocMetInfMetInf smlAllocPcdata smlAllocPcdataList smlAllocPut smlAllocReplace smlAllocResults smlAllocSearch smlAllocSequence smlAllocSource smlAllocSourceList smlAllocSourceRefList smlAllocStatus smlAllocSync smlAllocSyncHdr smlAllocTarget smlAllocTargetRefList smlAllocUnknownProtoElement smlCopyCmd smlDeleteCmd smlEndAtomic smlEndMessage smlEndSequence smlEndSync smlExecCmd smlFreeAlert smlFreeAtomic smlFreeChalPtr smlFreeCredPtr smlFreeDevInfCTCap smlFreeDevInfCTData smlFreeDevInfCTDataList smlFreeDevInfCTDataProp smlFreeDevInfCTDataPropList smlFreeDevInfCtcapList smlFreeDevInfDSMem smlFreeDevInfDatastore smlFreeDevInfDatastoreList smlFreeDevInfDevInf smlFreeDevInfExt smlFreeDevInfExtList smlFreeDevInfSynccap smlFreeDevInfXmit smlFreeDevInfXmitList smlFreeExec smlFreeGeneric smlFreeGetPut smlFreeItemList smlFreeItemPtr smlFreeMap smlFreeMapItemList smlFreeMapItemPtr smlFreeMetinfAnchor smlFreeMetinfMem smlFreeMetinfMetinf smlFreePcdata smlFreePcdataList smlFreeProtoElement smlFreeResults smlFreeSearch smlFreeSourceList smlFreeSourceRefList smlFreeSourceTargetPtr smlFreeStatus smlFreeSync smlFreeSyncHdr smlFreeTargetRefList smlGetCmd smlGetFreeBuffer smlInit smlInitInstance smlLibFree smlLibMalloc smlLibMemcmp smlLibMemcpy smlLibMemmove smlLibMemset smlLibPrint smlLibRealloc smlLibStrcat smlLibStrchr smlLibStrcmp smlLibStrcpy smlLibStrdup smlLibStrlen smlLibStrncat smlLibStrncmp smlLibStrncpy smlLibStrstr smlLibVprintf smlLockReadBuffer smlLockWriteBuffer smlMapCmd smlPcdata2String smlPcdataDup smlProcessData smlPutCmd smlReplaceCmd smlResultsCmd smlSearchCmd smlSetCallbacks smlSetEncoding smlSetSyncMLOptions smlSetUserData smlStartAtomic smlStartMessage smlStartMessageExt smlStartSequence smlStartSync smlStatusCmd smlString2Pcdata smlTerminate smlTerminateInstance smlUnlockReadBuffer smlUnlockWriteBuffer smlStartEvaluation smlEndEvaluation libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/inc/000077500000000000000000000000001226375725500215715ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/inc/palm/000077500000000000000000000000001226375725500225225ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/inc/palm/define.h000077500000000000000000000063561226375725500241420ustar00rootroot00000000000000/** * @file * Compiler Flag Definition File * * @target_system palm * @target_os palm */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ /** * File for Palm OS Specific Compiler Flags */ #ifndef _DEFINE_H #define _DEFINE_H #define __PALM_OS__ #define PILOT_PRECOMPILED_HEADERS_OFF #define SML_API #define SML_API_DEF #define XPT_API #define XPT_API_DEF /* Multi segment macro for Palm OS */ #define LIB_FUNC __attribute__ ((section ("lib"))) #define MGR_FUNC __attribute__ ((section ("mgr"))) #define WSM_FUNC __attribute__ ((section ("wsm"))) #define XLT_FUNC __attribute__ ((section ("xlt"))) // SyncML commands which are not required in a client can be switched off #define ATOMIC_SEND #define ATOMIC_RECEIVE #define COPY_SEND #define COPY_RECEIVE #define EXEC_SEND #define EXEC_RECEIVE #define MAP_RECEIVE #define MAPITEM_RECEIVE #define SEARCH_SEND #define SEARCH_RECEIVE #define SEQUENCE_SEND #define SEQUENCE_RECEIVE #define ADD_SEND #define GET_SEND #define RESULT_RECEIVE /* --- Toolkit a la Carte --- */ /* Compilerflags to include only subsets of the Toolkit functionality */ /* enable Alloc helpers */ #define __USE_ALLOCFUNCS__ /* Compiler Flag to include the XML Parsing Module */ #define __SML_XML__ /* Compiler Flag to include the WBXML Parsing Module */ #define __SML_WBXML__ /* Compiler Flag to include only the Minimum Toolkit functionality */ //#define __SML_LITE__ #define __USE_EXTENSIONS__ #define __USE_METINF__ #define __USE_DEVINF__ #endif libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/inc/sml.h000077500000000000000000000321261226375725500225440ustar00rootroot00000000000000/** * @file * External SyncML API * * @target_system all * @target_os all * @description Platform independent definition of the SyncML API functions * This is the external API exposed to applications using SyncML */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ #ifndef _SML_H #define _SML_H /************************************************************************* * Definitions *************************************************************************/ #include #include /************************************************************************* * External Functions *************************************************************************/ #if !defined(NOWSM) || !__LINK_TOOLKIT_STATIC__ /* * ============================ * General SyncML Functions * ============================ */ SML_API_DEF Ret_t smlInit(SmlOptionsPtr_t pOptions); SML_API_DEF Ret_t smlSetSyncMLOptions (SmlOptionsPtr_t pOptions); SML_API_DEF Ret_t smlTerminate(void); #endif /* * ============================ * Workspace Handling Functions * ============================ */ SML_API_DEF Ret_t smlLockReadBuffer(InstanceID_t id, MemPtr_t *pReadPosition, MemSize_t *usedSize); SML_API_DEF Ret_t smlUnlockReadBuffer(InstanceID_t id, MemSize_t processedBytes); #ifdef NOWSM SML_API Ret_t smlSetMaxOutgoingSize(InstanceID_t id, MemSize_t maxOutgoingSize); SML_API Ret_t smlSetOutgoingBegin(InstanceID_t id); SML_API Ret_t smlReadOutgoingAgain(InstanceID_t id); SML_API Ret_t smlPeekMessageBuffer(InstanceID_t id, Boolean_t outgoing, MemPtr_t *message, MemSize_t *msgsize); #endif SML_API_DEF Ret_t smlLockWriteBuffer(InstanceID_t id, MemPtr_t *pWritePosition, MemSize_t *freeSize); SML_API_DEF Ret_t smlUnlockWriteBuffer(InstanceID_t id, MemSize_t writtenBytes); /* * =========================================== * Protocol Element Building Functions (for Originator) * =========================================== */ /* Protocol Management */ SML_API_DEF Ret_t smlStartMessage(InstanceID_t id, SmlSyncHdrPtr_t pContent); SML_API_DEF Ret_t smlStartMessageExt(InstanceID_t id, SmlSyncHdrPtr_t pContent, SmlVersion_t vers); /* %%% added by luz 2003-08-06) */ SML_API_DEF Ret_t smlEndMessage(InstanceID_t id, Boolean_t final); SML_API_DEF Ret_t smlStartSync(InstanceID_t id, SmlSyncPtr_t pContent); SML_API_DEF Ret_t smlEndSync(InstanceID_t id); #ifdef ATOMIC_SEND /* these API calls are NOT included in the Toolkit lite version */ SML_API_DEF Ret_t smlStartAtomic(InstanceID_t id, SmlAtomicPtr_t pContent); SML_API_DEF Ret_t smlEndAtomic(InstanceID_t id); #endif #ifdef SEQUENCE_SEND SML_API_DEF Ret_t smlStartSequence(InstanceID_t id, SmlSequencePtr_t pContent); SML_API_DEF Ret_t smlEndSequence(InstanceID_t id); #endif /* Sync Commands */ #ifdef ADD_SEND SML_API_DEF Ret_t smlAddCmd(InstanceID_t id, SmlAddPtr_t pContent); #endif SML_API_DEF Ret_t smlAlertCmd(InstanceID_t id, SmlAlertPtr_t pContent); SML_API_DEF Ret_t smlDeleteCmd(InstanceID_t id, SmlDeletePtr_t pContent); #ifdef GET_SEND SML_API_DEF Ret_t smlGetCmd(InstanceID_t id, SmlGetPtr_t pContent); #endif SML_API_DEF Ret_t smlPutCmd(InstanceID_t id, SmlPutPtr_t pContent); SML_API_DEF Ret_t smlMapCmd(InstanceID_t id, SmlMapPtr_t pContent); SML_API_DEF Ret_t smlResultsCmd(InstanceID_t id, SmlResultsPtr_t pContent); SML_API_DEF Ret_t smlStatusCmd(InstanceID_t id, SmlStatusPtr_t pContent); SML_API_DEF Ret_t smlReplaceCmd(InstanceID_t id, SmlReplacePtr_t pContent); #ifdef COPY_SEND /* these API calls are NOT included in the Toolkit lite version */ SML_API_DEF Ret_t smlCopyCmd(InstanceID_t id, SmlCopyPtr_t pContent); #endif SML_API_DEF Ret_t smlMoveCmd(InstanceID_t id, SmlMovePtr_t pContent); #ifdef EXEC_SEND SML_API_DEF Ret_t smlExecCmd(InstanceID_t id, SmlExecPtr_t pContent); #endif #ifdef SEARCH_SEND SML_API_DEF Ret_t smlSearchCmd(InstanceID_t id, SmlSearchPtr_t pContent); #endif SML_API_DEF Ret_t smlStartEvaluation(InstanceID_t id); SML_API_DEF Ret_t smlEndEvaluation(InstanceID_t id, MemSize_t *freemem); /* * ============================================ * Command Dispatching Functions (for Receiver) * ============================================ */ SML_API_DEF Ret_t smlProcessData(InstanceID_t id, SmlProcessMode_t mode); /* * ==================================================== * Callback Functions to be implemented by the Receiver * ==================================================== */ /* Protocol Management */ typedef Ret_t (*smlStartMessageFunc) (InstanceID_t id, VoidPtr_t userData, SmlSyncHdrPtr_t pContent); typedef Ret_t (*smlEndMessageFunc) (InstanceID_t id, VoidPtr_t userData, Boolean_t final); typedef Ret_t (*smlStartSyncFunc) (InstanceID_t id, VoidPtr_t userData, SmlSyncPtr_t pContent); typedef Ret_t (*smlEndSyncFunc) (InstanceID_t id, VoidPtr_t userData); #ifdef ATOMIC_RECEIVE /* these callbacks are NOT included in the Toolkit lite version */ typedef Ret_t (*smlStartAtomicFunc) (InstanceID_t id, VoidPtr_t userData, SmlAtomicPtr_t pContent); typedef Ret_t (*smlEndAtomicFunc) (InstanceID_t id, VoidPtr_t userData); #endif #ifdef SEQUENCE_RECEIVE typedef Ret_t (*smlStartSequenceFunc) (InstanceID_t id, VoidPtr_t userData, SmlSequencePtr_t pContent); typedef Ret_t (*smlEndSequenceFunc) (InstanceID_t id, VoidPtr_t userData); #endif /* Sync Commands */ typedef Ret_t (*smlAddCmdFunc) (InstanceID_t id, VoidPtr_t userData, SmlAddPtr_t pContent); typedef Ret_t (*smlAlertCmdFunc) (InstanceID_t id, VoidPtr_t userData, SmlAlertPtr_t pContent); typedef Ret_t (*smlDeleteCmdFunc) (InstanceID_t id, VoidPtr_t userData, SmlDeletePtr_t pContent); typedef Ret_t (*smlGetCmdFunc) (InstanceID_t id, VoidPtr_t userData, SmlGetPtr_t pContent); typedef Ret_t (*smlPutCmdFunc) (InstanceID_t id, VoidPtr_t userData, SmlPutPtr_t pContent); #ifdef MAP_RECEIVE typedef Ret_t (*smlMapCmdFunc) (InstanceID_t id, VoidPtr_t userData, SmlMapPtr_t pContent); #endif #ifdef RESULT_RECEIVE typedef Ret_t (*smlResultsCmdFunc) (InstanceID_t id, VoidPtr_t userData, SmlResultsPtr_t pContent); #endif typedef Ret_t (*smlStatusCmdFunc) (InstanceID_t id, VoidPtr_t userData, SmlStatusPtr_t pContent); typedef Ret_t (*smlReplaceCmdFunc) (InstanceID_t id, VoidPtr_t userData, SmlReplacePtr_t pContent); #ifdef COPY_RECEIVE /* these callbacks are NOT included in the Toolkit lite version */ typedef Ret_t (*smlCopyCmdFunc) (InstanceID_t id, VoidPtr_t userData, SmlCopyPtr_t param); #endif #ifdef EXEC_RECEIVE typedef Ret_t (*smlExecCmdFunc) (InstanceID_t id, VoidPtr_t userData, SmlExecPtr_t pContent); #endif #ifdef SEARCH_RECEIVE typedef Ret_t (*smlSearchCmdFunc) (InstanceID_t id, VoidPtr_t userData, SmlSearchPtr_t pContent); #endif typedef Ret_t (*smlMoveCmdFunc) (InstanceID_t id, VoidPtr_t userData, SmlMovePtr_t param); /* Other Callbacks */ typedef Ret_t (*smlHandleErrorFunc) (InstanceID_t id, VoidPtr_t userData); typedef Ret_t (*smlTransmitChunkFunc) (InstanceID_t id, VoidPtr_t userData); /** * Structure defining references to the applications callback implementations **/ typedef struct sml_callbacks_s { /* Protocol Management Callbacks */ smlStartMessageFunc startMessageFunc; smlEndMessageFunc endMessageFunc; smlStartSyncFunc startSyncFunc; smlEndSyncFunc endSyncFunc; #ifdef ATOMIC_RECEIVE /* these callbacks are NOT included in the Toolkit lite version */ smlStartAtomicFunc startAtomicFunc; smlEndAtomicFunc endAtomicFunc; #endif #ifdef SEQUENCE_RECEIVE smlStartSequenceFunc startSequenceFunc; smlEndSequenceFunc endSequenceFunc; #endif /* Sync Command callbacks */ smlAddCmdFunc addCmdFunc; smlAlertCmdFunc alertCmdFunc; smlDeleteCmdFunc deleteCmdFunc; smlGetCmdFunc getCmdFunc; smlPutCmdFunc putCmdFunc; #ifdef MAP_RECEIVE smlMapCmdFunc mapCmdFunc; #endif #ifdef RESULT_RECEIVE smlResultsCmdFunc resultsCmdFunc; #endif smlStatusCmdFunc statusCmdFunc; smlReplaceCmdFunc replaceCmdFunc; #ifdef COPY_RECEIVE /* these callbacks are NOT included in the Toolkit lite version */ smlCopyCmdFunc copyCmdFunc; #endif #ifdef EXEC_RECEIVE smlExecCmdFunc execCmdFunc; #endif #ifdef SEARCH_RECEIVE smlSearchCmdFunc searchCmdFunc; #endif smlMoveCmdFunc moveCmdFunc; /* Other Callbacks */ smlHandleErrorFunc handleErrorFunc; smlTransmitChunkFunc transmitChunkFunc; //smlPrintFunc printFunc; } *SmlCallbacksPtr_t, SmlCallbacks_t; typedef const SmlCallbacks_t *SmlCallbacksCPtr_t; /* * ============================ * Instance Management Functions * ============================ */ SML_API_DEF Ret_t smlInitInstance(SmlCallbacksCPtr_t pCallbacks, SmlInstanceOptionsPtr_t pOptions, VoidPtr_t pUserData, InstanceID_t *pId); SML_API_DEF Ret_t smlTerminateInstance (InstanceID_t id); SML_API_DEF Ret_t smlSetCallbacks (InstanceID_t id, SmlCallbacksCPtr_t pCallbacks); SML_API_DEF Ret_t smlSetUserData (InstanceID_t id, VoidPtr_t pUserData); // added by luz %%%: SML_API Ret_t smlGetUserData(InstanceID_t id, VoidPtr_t *ppUserData); SML_API Ret_t smlGetEncoding(InstanceID_t id, SmlEncoding_t *pEncoding); #ifndef __SML_LITE__ /* these API calls are NOT included in the Toolkit lite version */ SML_API_DEF Ret_t smlSetEncoding (InstanceID_t id, SmlEncoding_t encoding); #endif /* * =================================== * Some Helper Functions and Utilities * =================================== */ SML_API_DEF Ret_t smlFreeProtoElement(VoidPtr_t pProtoElement); SML_API_DEF void smlFreePcdata(SmlPcdataPtr_t pPcdata); #ifndef __SML_LITE__ /* these API calls are NOT included in the Toolkit lite version */ SML_API_DEF String_t smlPcdata2String( SmlPcdataPtr_t pcdata ); SML_API_DEF SmlPcdataPtr_t smlString2Pcdata( String_t str ); SML_API_DEF SmlPcdataPtr_t smlPcdataDup(SmlPcdataPtr_t pcdata); SML_API_DEF MemSize_t smlGetFreeBuffer(InstanceID_t id); #endif #ifndef __PALM_OS__ /* these API calls are NOT exported in the Palm OS version */ SML_API_DEF void *smlLibMemset(void *pObject, int value, MemSize_t count); SML_API_DEF void *smlLibMemcpy(void *pTarget, const void *pSource, MemSize_t count); SML_API_DEF int smlLibMemcmp(const void *pTarget, const void *pSource, MemSize_t count); //SML_API_DEF void *smlLibMalloc(MemSize_t size); SML_API_DEF void smlLibFree(void *pObject); SML_API_DEF MemSize_t smlLibMemsize(const void *pObject); SML_API_DEF String_t smlLibStrdup (const char *constStringP); SML_API_DEF String_t smlLibStrcpy(const char *pTarget, const char *pSource); SML_API_DEF int smlLibStrcmp(const char *pTarget, const char *pSource); SML_API_DEF int smlLibStrlen(const char *pString); SML_API_DEF String_t smlLibStrncpy(const char *pTarget, const char *pSource, int count); SML_API_DEF int smlLibStrncmp(const char *pTarget, const char *pSource, int count); SML_API_DEF String_t smlLibStrcat(const char *pTarget, const char *pSource); SML_API_DEF String_t smlLibStrchr(const char *pString, char character); #ifndef __SML_LITE__ /* these API calls are NOT included in the Toolkit lite version */ SML_API_DEF void smlLibPrint(const char *text, ...); SML_API_DEF void *smlLibMemmove(void *pTarget, const void *pSource, MemSize_t count); SML_API_DEF void *smlLibRealloc(void *pObject, MemSize_t size); SML_API_DEF String_t smlLibStrncat(const char *pTarget, const char *pSource, int count); SML_API_DEF String_t smlLibStrstr(const char *pString, const char *pSubString); #endif #endif #endif libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/inc/smldef.h000077500000000000000000000147471226375725500232340ustar00rootroot00000000000000/** * @file * Type definitions for SyncML * * @target_system all * @target_os all * * @description Platform independent header with syncML types and definitions */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ #ifndef _SML_DEF_H #define _SML_DEF_H /************************************************************************* * Definitions *************************************************************************/ /** * include target/compiler specific defines/options/settings */ #include "define.h" /* * =================================== * Common all-purpose type definitions * =================================== */ /* * ================================== * Basic data types * ================================== */ typedef short Short_t; /**< short integer, 16 Bytes */ typedef long Long_t; /**< long integer, 32 Bytes */ typedef char* String_t; /**< String pointer, */ typedef unsigned char Byte_t; /**< a single byte */ typedef Byte_t Boolean_t; /**< a boolean */ #ifndef NULL /**< a NULL pointer */ #define NULL (void*) 0 #endif #ifndef FALSE #define FALSE 0 #endif #ifndef TRUE #define TRUE 1 #endif typedef Short_t Ret_t; /**< Return Type of API Commands */ typedef Long_t Length_t; /**< System dependent string length */ typedef Short_t MemHandle_t; /**< Memory object Handle */ typedef unsigned char *MemPtr_t; /**< Memory object Pointer */ typedef void *VoidPtr_t; /**< Void Pointer */ typedef Long_t MemSize_t; /**< System dependent memory object size */ typedef unsigned char MemByte_t; /**< Memory element */ typedef unsigned int Flag_t; /**< A generic flag type. This type is * used to declare variables in structures * wherever flags are used. */ /* * ================================== * Definitions used in the SyncML API * ================================== */ /** * Application callback function displaying output strings to the user */ typedef void (*smlPrintFunc) (String_t outputString); #ifdef NOWSM /** * structure describing the options and setting of this syncml process */ typedef struct sml_options_s { smlPrintFunc defaultPrintFunc; /**< default application callback for displaying strings, */ MemSize_t maxWorkspaceAvailMem; /**< size which all workspaces in total MUST not exceed */ } *SmlOptionsPtr_t, SmlOptions_t; #endif /** * Reference of an instance */ #ifdef NOWSM typedef void *InstanceID_t; /**< without wsm, instance ID is direct pointer to instance info */ #else typedef MemHandle_t InstanceID_t; /**< Handle, used as a unique ID of * an synchronization instance */ #endif /** * Type of used encoding */ typedef enum { SML_UNDEF = 0, SML_WBXML, SML_XML } SmlEncoding_t; /** * SyncML version */ // %%% added luz 2003-07-31: // %%% added DS 1.2 luz 2005-08-17: typedef enum { SML_VERS_UNDEF = 0, SML_VERS_1_0, SML_VERS_1_1, SML_VERS_1_2, SML_NUM_VERS } SmlVersion_t; /** * structure describing the options of an instance, */ typedef struct sml_instance_options_s { SmlEncoding_t encoding; /**< Used encoding type, */ MemSize_t workspaceSize; /**< size of the workspace to allocate (instance buffer size if NOWSM defined) */ #ifndef NOWSM String_t workspaceName; /**< name of the workspace */ #else MemSize_t maxOutgoingSize; /**< max size of outgoing message, 0 if no restriction */ #endif } *SmlInstanceOptionsPtr_t, SmlInstanceOptions_t; /** * Processing modes */ typedef enum { SML_DO_NOTHING = 0, SML_FIRST_COMMAND, SML_NEXT_COMMAND, SML_NEXT_MESSAGE, SML_ALL_COMMANDS } SmlProcessMode_t; /** * Requested buffer pointer position */ typedef enum { SML_FIRST_DATA_ITEM = 0, SML_FIRST_FREE_ITEM } SmlBufPtrPos_t; /** * SyncML Protocol Management and Command Elements (PE) */ typedef enum { SML_PE_UNDEF = 0, SML_PE_ERROR, SML_PE_ADD, SML_PE_ALERT, SML_PE_ATOMIC_START, SML_PE_ATOMIC_END, SML_PE_COPY, SML_PE_DELETE, SML_PE_EXEC, SML_PE_GET, SML_PE_MAP, SML_PE_PUT, SML_PE_RESULTS, SML_PE_SEARCH, SML_PE_SEQUENCE_START, SML_PE_SEQUENCE_END, SML_PE_STATUS, SML_PE_SYNC_START, SML_PE_SYNC_END, SML_PE_REPLACE, SML_PE_HEADER, SML_PE_PUT_GET, SML_PE_CMD_GROUP, SML_PE_GENERIC, SML_PE_FINAL, /* %%% Added 2005-08-17 by synthesis/luz for DS 1.2 */ SML_PE_MOVE } SmlProtoElement_t; #endif libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/inc/smldevinfdtd.h000077500000000000000000000161711226375725500244360ustar00rootroot00000000000000/** * @file * SyncML Device Information DTD specific type definitions * * @target_system all * @target_os all * @description Definition of structures representing DevInf DTD elements * This file reflects DevInf as specified in the document * http://www.openmobilealliance.org/tech/affiliates/syncml/syncml_devinf_v101_20010615.pdf */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ #ifndef _SML_DEVINFDTD_H #define _SML_DEVINFDTD_H /* process only if we really use DevInf DTD */ #ifdef __USE_DEVINF__ /*************************************************************************/ /* Definitions */ /*************************************************************************/ #include #include typedef struct sml_devinf_ext_s { SmlPcdataPtr_t xnam; SmlPcdataListPtr_t xval; /* optional */ } *SmlDevInfExtPtr_t, SmlDevInfExt_t; typedef struct sml_devinf_extlist_s { SmlDevInfExtPtr_t data; struct sml_devinf_extlist_s *next; } *SmlDevInfExtListPtr_t, SmlDevInfExtList_t; typedef struct sml_devinf_synccap_s { SmlPcdataListPtr_t synctype; } *SmlDevInfSyncCapPtr_t, SmlDevInfSyncCap_t; typedef struct sml_devinf_ctdata_s { SmlPcdataPtr_t name; SmlPcdataPtr_t dname; /* optional, display name */ SmlPcdataListPtr_t valenum; SmlPcdataPtr_t datatype; SmlPcdataPtr_t maxsize; // called size before DS 1.2 (still represents devInf for DS 1.1/1.0) /* SyncML DS 1.2, Synthesis/luz 2005-08-24 */ SmlPcdataPtr_t maxoccur; Flag_t flags; // } *SmlDevInfCTDataPtr_t, SmlDevInfCTData_t; typedef struct sml_devinf_ctdatalist_s { SmlDevInfCTDataPtr_t data; struct sml_devinf_ctdatalist_s *next; } *SmlDevInfCTDataListPtr_t, SmlDevInfCTDataList_t; typedef struct sml_devinf_ctdataprop_s { SmlDevInfCTDataPtr_t prop; SmlDevInfCTDataListPtr_t param; } *SmlDevInfCTDataPropPtr_t, SmlDevInfCTDataProp_t; typedef struct sml_devinf_ctdataproplist_s { SmlDevInfCTDataPropPtr_t data; struct sml_devinf_ctdataproplist_s *next; } *SmlDevInfCTDataPropListPtr_t, SmlDevInfCTDataPropList_t; /* SyncML DS 1.2, Synthesis/luz 2005-08-24 */ typedef struct sml_devinf_filtercap_s { SmlPcdataPtr_t cttype; SmlPcdataPtr_t verct; SmlPcdataListPtr_t filterkeyword; SmlPcdataListPtr_t propname; } *SmlDevInfFilterCapPtr_t, SmlDevInfFilterCap_t; /* SyncML DS 1.2, Synthesis/luz 2005-08-24 */ typedef struct sml_devinf_filtercaplist_s { SmlDevInfFilterCapPtr_t data; struct sml_devinf_filtercaplist_s *next; } *SmlDevInfFilterCapListPtr_t, SmlDevInfFilterCapList_t; typedef struct sml_devinf_ctcap_s { SmlPcdataPtr_t cttype; SmlPcdataPtr_t verct; // new for DS 1.2 SmlDevInfCTDataPropListPtr_t prop; Flag_t flags; // SmlDevInfFieldLevel_f, opt. } *SmlDevInfCTCapPtr_t, SmlDevInfCTCap_t; typedef struct sml_devinf_ctcaplist_s { SmlDevInfCTCapPtr_t data; struct sml_devinf_ctcaplist_s *next; } *SmlDevInfCtcapListPtr_t, SmlDevInfCtcapList_t; typedef struct sml_devinf_dsmem_s { SmlPcdataPtr_t maxmem; /* optional */ SmlPcdataPtr_t maxid; /* optional */ Flag_t flags; /* %%% luz:2003-04-28, made sharedMem a flag, was PCData (completely wrong) */ } *SmlDevInfDSMemPtr_t, SmlDevInfDSMem_t; typedef struct sml_devinf_xmit_s { SmlPcdataPtr_t cttype; SmlPcdataPtr_t verct; } *SmlDevInfXmitPtr_t, SmlDevInfXmit_t; typedef struct sml_devinf_xmitlist_s { SmlDevInfXmitPtr_t data; struct sml_devinf_xmitlist_s *next; } *SmlDevInfXmitListPtr_t, SmlDevInfXmitList_t; typedef struct sml_devinf_datastore_s { SmlPcdataPtr_t sourceref; SmlPcdataPtr_t displayname; /* optional */ SmlPcdataPtr_t maxguidsize; /* optional */ SmlDevInfXmitPtr_t rxpref; SmlDevInfXmitListPtr_t rx; /* optional */ SmlDevInfXmitPtr_t txpref; SmlDevInfXmitListPtr_t tx; /* optional */ SmlDevInfDSMemPtr_t dsmem; /* optional */ SmlDevInfSyncCapPtr_t synccap; /* SyncML DS 1.2, Synthesis/luz 2005-08-24 */ SmlDevInfXmitListPtr_t filterrx; /* optional */ SmlDevInfCtcapListPtr_t ctcap; // opt., Datastore-local >=DS1.2 type list SmlDevInfFilterCapListPtr_t filtercap; // opt., filter capabilities list Flag_t flags; // SmlDevInfHierarchical_f, opt. } *SmlDevInfDatastorePtr_t, SmlDevInfDatastore_t; typedef struct sml_devinf_datastorelist_s { SmlDevInfDatastorePtr_t data; struct sml_devinf_datastorelist_s *next; } *SmlDevInfDatastoreListPtr_t, SmlDevInfDatastoreList_t; typedef struct sml_devinf_devinf_s { SmlPcdataPtr_t verdtd; SmlPcdataPtr_t man; /* optional */ SmlPcdataPtr_t mod; /* optional */ SmlPcdataPtr_t oem; /* optional */ SmlPcdataPtr_t fwv; /* optional */ SmlPcdataPtr_t swv; /* optional */ SmlPcdataPtr_t hwv; /* optional */ SmlPcdataPtr_t devid; SmlPcdataPtr_t devtyp; SmlDevInfDatastoreListPtr_t datastore; SmlDevInfCtcapListPtr_t ctcap; // opt., global pre-DS 1.2 type list SmlDevInfExtListPtr_t ext; /* SCTSTK - 18/03/2002, S.H. 2002-04-05 : SyncML 1.1 */ Flag_t flags; } *SmlDevInfDevInfPtr_t, SmlDevInfDevInf_t; #endif // __USE_DEVINF__ #endif //_SML_DEVINFDTD_H_ libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/inc/smldtd.h000077500000000000000000000343361226375725500232450ustar00rootroot00000000000000/** * @file * SyncML DTD specific type definitions * * @target_system all * @target_os all * @description Definition of structures representing DTD elements */ /********************************************************************/ /* @note */ /* These definitions are based on the DTD dated from July, 7th, 00 */ /********************************************************************/ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ #ifndef _SML_DTD_H #define _SML_DTD_H /*************************************************************************/ /* Definitions */ /*************************************************************************/ #include /** * =========================== * Common used SyncML Elements * =========================== */ /** * PCDATA - types of synchronization data which SyncML supports */ typedef enum { SML_PCDATA_UNDEFINED = 0, SML_PCDATA_STRING, /**< String type */ SML_PCDATA_OPAQUE, /**< Opaque type */ SML_PCDATA_EXTENSION, /**< Extention type - specified by PcdataExtension_t */ SML_PCDATA_CDATA /**< XML CDATA type */ } SmlPcdataType_t; /** * PCDATA - types of extensions for PCData elements */ typedef enum { SML_EXT_UNDEFINED = 0, SML_EXT_METINF, /**< Meta Information */ SML_EXT_DEVINF, /**< Device Information */ SML_EXT_LAST /**< last codepage, needed for loops! */ } SmlPcdataExtension_t; /** * PCDATA - into this structure SyncML wraps the synchronization data itself */ typedef struct sml_pcdata_s { SmlPcdataType_t contentType; /**< The type of data which a PCDATA structure contains */ SmlPcdataExtension_t extension; /**< PCData Extension type */ MemSize_t length; /**< length of the data in this PCDATA structure */ VoidPtr_t content; /**< Pointer to the data itself */ } *SmlPcdataPtr_t, SmlPcdata_t; /** generic list of PCData elements */ typedef struct sml_pcdata_list_s { SmlPcdataPtr_t data; struct sml_pcdata_list_s *next; } *SmlPcdataListPtr_t, SmlPcdataList_t; /* * Various flags which are actually declared and (EMPTY) elements in * SyncML. This assumes at least a 16-bit architecture for the * underlying OS. We need to review this if that is deemed a problem. */ #define SmlArchive_f 0x8000 /**< Delete flags */ #define SmlSftDel_f 0x4000 /**< Delete flags */ #define SmlMoreData_f 0x0400 /**< MoreData flag */ #define SmlNoResults_f 0x0200 /**< No Results flag */ #define SmlNoResp_f 0x0100 /**< No Response flag */ #define SmlFinal_f 0x0001 /**< Header flag */ #ifdef __USE_METINF__ #define SmlMetInfSharedMem_f 0x0002 /**< MetInf Shared Memory Flag */ /* SyncML DS 1.2, Synthesis/luz 2005-08-24 */ #define SmlMetInfFieldLevel_f 0x0004 /**< MetInf FieldLevel Flag */ #endif #ifdef __USE_DEVINF__ #define SmlDevInfSharedMem_f 0x0004 /**< DevInf Shared Memory Flag */ /* SCTSTK - 18/03/2002, S.H. 2002-04-05 : SyncML 1.1 */ #define SmlDevInfUTC_f 0x0001 /**< DevInf utc Flag */ #define SmlDevInfNOfM_f 0x0002 /**< DevInf support n of m Flag */ #define SmlDevInfLargeObject_f 0x0008 /**< DevInf support large object Flag */ /* SyncML DS 1.2, Synthesis/luz 2005-08-24 */ #define SmlDevInfFieldLevel_f 0x0010 /**< DevInf support field level replaces */ #define SmlDevInfNoTruncate_f 0x0020 /**< DevInf support noTruncate Flag */ #define SmlDevInfHierarchical_f 0x0040 /**< DevInf support SupportHierarchicalSync Flag */ #endif /** * Chal */ typedef struct sml_chal_s { SmlPcdataPtr_t meta; } *SmlChalPtr_t, SmlChal_t; /** * Credentials */ typedef struct sml_cred_s { SmlPcdataPtr_t meta; // opt. SmlPcdataPtr_t data; } *SmlCredPtr_t, SmlCred_t; /* forward declaration as item is used in filter which is used in target which is used in item itself */ //typedef struct sml_item_s; /** * Record or Field level filter * %%% Added 2005-08-17 by synthesis/luz for DS 1.2 */ typedef struct sml_record_or_field_filter_s { struct sml_item_s *item; } *SmlRecordOrFieldFilterPtr_t, SmlRecordOrFieldFilter_t; /** * Filter * %%% Added 2005-08-17 by synthesis/luz for DS 1.2 */ typedef struct sml_filter_s { SmlPcdataPtr_t meta; SmlRecordOrFieldFilterPtr_t field; // opt. SmlRecordOrFieldFilterPtr_t record; // opt. SmlPcdataPtr_t filtertype; // opt. } *SmlFilterPtr_t, SmlFilter_t; /** * Source or target parent location * %%% Added 2005-08-17 by synthesis/luz for DS 1.2 */ typedef struct sml_source_or_target_parent_s { SmlPcdataPtr_t locURI; } *SmlSourceParentPtr_t, SmlSourceParent_t, *SmlTargetParentPtr_t, SmlTargetParent_t; /** * Source or target location */ typedef struct sml_source_or_target_s { SmlPcdataPtr_t locURI; SmlPcdataPtr_t locName; // opt. SmlFilterPtr_t filter; // opt., for target only } *SmlSourcePtr_t, SmlSource_t, *SmlTargetPtr_t, SmlTarget_t; typedef struct sml_source_list_s { SmlSourcePtr_t source; struct sml_source_list_s *next; } *SmlSourceListPtr_t, SmlSourceList_t; /* * ============================== * SyncML Message Header Elements * ============================== */ /** * SyncML header * As the header is needed for each SyncML message, it's also the parameter * of the startMessage call. */ typedef struct sml_sync_hdr_s { SmlProtoElement_t elementType; // Internal Toolkit Field SmlPcdataPtr_t version; SmlPcdataPtr_t proto; SmlPcdataPtr_t sessionID; SmlPcdataPtr_t msgID; Flag_t flags; // NoResp SmlTargetPtr_t target; SmlSourcePtr_t source; SmlPcdataPtr_t respURI; // opt. SmlCredPtr_t cred; // opt. SmlPcdataPtr_t meta; // opt. } *SmlSyncHdrPtr_t, SmlSyncHdr_t; // SyncML Body and SyncML container is not needed, as there are function calls // (smlStartMessage(), smlEndMessage()) that let the framework know when to start and end // the SyncML document /* * ========================= * Data description elements * ========================= */ /** * Auxiliary data added by layer above SMLTK. * Actual data will be in derived types that * are not visible to SMLTK. */ typedef struct sml_item_aux_s { void (*freeAux)(struct sml_item_aux_s *ptr); // Frees the aux instance. } *SmlItemAuxPtr_t, SmlItemAux_t; /** * Data in SyncML is encapsulated in an "item" element. */ typedef struct sml_item_s { SmlTargetPtr_t target; // opt. SmlSourcePtr_t source; // opt. SmlTargetParentPtr_t targetParent; // opt. (Added by luz 2005-08-17 for DS 1.2) SmlSourceParentPtr_t sourceParent; // opt. (Added by luz 2005-08-17 for DS 1.2) SmlPcdataPtr_t meta; // opt. SmlPcdataPtr_t data; // opt. Flag_t flags; // opt. for MoreData SmlItemAuxPtr_t aux; // for use by level above SMLTK } *SmlItemPtr_t, SmlItem_t; typedef struct sml_item_list_s { SmlItemPtr_t item; struct sml_item_list_s *next; } *SmlItemListPtr_t, SmlItemList_t; /* * ============================================== * SyncML Commands (Protocol Management Elements) * ============================================== */ /** * Generic commands: * Add, Copy, Replace, Delete, Move (added for DS 1.2, 2005-08-17 by luz) */ typedef struct sml_generic_s { SmlProtoElement_t elementType; // Internal Toolkit Field SmlPcdataPtr_t cmdID; Flag_t flags; // NoResp, Archive (Delete), SftDel (Delete) SmlCredPtr_t cred; // opt. SmlPcdataPtr_t meta; // opt. SmlItemListPtr_t itemList; } *SmlAddPtr_t, SmlAdd_t, *SmlCopyPtr_t, SmlCopy_t, *SmlMovePtr_t, SmlMove_t, *SmlReplacePtr_t, SmlReplace_t, *SmlDeletePtr_t, SmlDelete_t, *SmlGenericCmdPtr_t, SmlGenericCmd_t; /** * Alert command: */ typedef struct sml_alert_s { SmlProtoElement_t elementType; // Internal Toolkit Field SmlPcdataPtr_t cmdID; Flag_t flags; // NoResp SmlCredPtr_t cred; // opt. SmlPcdataPtr_t data; // opt. SmlItemListPtr_t itemList; } *SmlAlertPtr_t, SmlAlert_t; /** * Atomic/Sequence command: */ typedef struct sml_atomic_s { SmlProtoElement_t elementType; // Internal Toolkit Field SmlPcdataPtr_t cmdID; Flag_t flags; // NoResp SmlPcdataPtr_t meta; // opt. } *SmlAtomicPtr_t, SmlAtomic_t, *SmlSequencePtr_t, SmlSequence_t; /** * Sync command: */ typedef struct sml_sync_s { SmlProtoElement_t elementType; // Internal Toolkit Field SmlPcdataPtr_t cmdID; Flag_t flags; // NoResp SmlCredPtr_t cred; // opt. SmlTargetPtr_t target; // opt. SmlSourcePtr_t source; // opt. SmlPcdataPtr_t meta; // opt. SmlPcdataPtr_t noc; // opt. (SyncML 1.1) } *SmlSyncPtr_t, SmlSync_t; /** * Exec command: */ typedef struct sml_exec_s { SmlProtoElement_t elementType; SmlPcdataPtr_t cmdID; Flag_t flags; // NoResp SmlCredPtr_t cred; // opt. SmlPcdataPtr_t meta; // opt. SmlItemPtr_t item; } *SmlExecPtr_t, SmlExec_t; /** * Get and Put command: */ typedef struct sml_get_put_s { SmlProtoElement_t elementType; // Internal Toolkit Field SmlPcdataPtr_t cmdID; Flag_t flags; // NoResp SmlPcdataPtr_t lang; // opt. SmlCredPtr_t cred; // opt. SmlPcdataPtr_t meta; // opt. SmlItemListPtr_t itemList; } *SmlPutPtr_t, SmlPut_t, *SmlGetPtr_t, SmlGet_t; /** * Map command: */ typedef struct sml_map_item_s { SmlTargetPtr_t target; SmlSourcePtr_t source; } *SmlMapItemPtr_t, SmlMapItem_t; typedef struct sml_map_item_list_s { SmlMapItemPtr_t mapItem; struct sml_map_item_list_s *next; } *SmlMapItemListPtr_t, SmlMapItemList_t; typedef struct sml_map_s { SmlProtoElement_t elementType; // InternalToolkit Field SmlPcdataPtr_t cmdID; SmlTargetPtr_t target; SmlSourcePtr_t source; SmlCredPtr_t cred; // opt. SmlPcdataPtr_t meta; // opt. SmlMapItemListPtr_t mapItemList; } *SmlMapPtr_t, SmlMap_t; /** * Results command: */ typedef struct sml_results_s { SmlProtoElement_t elementType; // Internal Toolkit Field SmlPcdataPtr_t cmdID; SmlPcdataPtr_t msgRef; // opt. SmlPcdataPtr_t cmdRef; SmlPcdataPtr_t meta; // opt. SmlPcdataPtr_t targetRef; // opt. SmlPcdataPtr_t sourceRef; // opt. SmlItemListPtr_t itemList; } *SmlResultsPtr_t, SmlResults_t; /** * Search command: */ typedef struct sml_search_s { SmlProtoElement_t elementType; // Internal Toolkit Field SmlPcdataPtr_t cmdID; Flag_t flags; // NoResp, NoResults SmlCredPtr_t cred; // opt. SmlTargetPtr_t target; // opt. SmlSourceListPtr_t sourceList; SmlPcdataPtr_t lang; // opt. SmlPcdataPtr_t meta; SmlPcdataPtr_t data; } *SmlSearchPtr_t, SmlSearch_t; /** * Status command: */ typedef struct sml_target_ref_list_s { SmlPcdataPtr_t targetRef; struct sml_target_ref_list_s *next; } *SmlTargetRefListPtr_t, SmlTargetRefList_t; typedef struct sml_source_ref_list_s { SmlPcdataPtr_t sourceRef; struct sml_source_ref_list_s *next; } *SmlSourceRefListPtr_t, SmlSourceRefList_t; typedef struct sml_status_s { SmlProtoElement_t elementType; // Internal Toolkit Field SmlPcdataPtr_t cmdID; SmlPcdataPtr_t msgRef; // Opt. SmlPcdataPtr_t cmdRef; SmlPcdataPtr_t cmd; SmlTargetRefListPtr_t targetRefList; // opt. SmlSourceRefListPtr_t sourceRefList; // opt. SmlCredPtr_t cred; // opt. SmlChalPtr_t chal; // opt. SmlPcdataPtr_t data; SmlItemListPtr_t itemList; // opt. } *SmlStatusPtr_t, SmlStatus_t; /** * a little helper for typecasting */ typedef struct sml_unknown_proto_element_s { SmlProtoElement_t elementType; // Internal Toolkit Field } *SmlUnknownProtoElementPtr_t, SmlUnknownProtoElement_t; #endif libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/inc/smlerr.h000077500000000000000000000135461226375725500232620ustar00rootroot00000000000000/** * @file * ErrorLibrary * * @target_system all * @target_os all * @description Definition of the used Error Codes */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ #ifndef _SML_ERR_H #define _SML_ERR_H /************************************************************************* * Definitions *************************************************************************/ /* * No error, success code */ #define SML_ERR_OK 0x00 /**< OK */ #define SML_ERR_CONTINUE 0x01 /**< OK, but processing of message not finished yet (smlProcessData(NEXT_COMMAND) case) */ /* * SyncML Common Error Codes */ // general errors #define SML_ERR_UNSPECIFIC 0x10 /**< unspecific error */ #define SML_ERR_NOT_ENOUGH_SPACE 0x11 /**< not enough memory to perform this operation */ #define SML_ERR_WRONG_USAGE 0x13 /**< function was called in wrong context */ // wrong parameters #define SML_ERR_WRONG_PARAM 0x20 /**< wrong parameter */ #define SML_ERR_INVALID_SIZE 0x21 /**< param has an invalid size */ #define SML_ERR_INVALID_HANDLE 0x22 /**< if handle is invalid/unknown */ #define SML_ERR_INVALID_OPTIONS 0x23 /**< unkown or unallowed options */ /* * SyncML Mgr Error Codes */ #define SML_ERR_A_MGR_ERROR 0x1001 /**< a template */ #define SML_ERR_MGR_INVALID_INSTANCE_INFO 0x1002 /**< a invalid Instance Info structure is used */ #define SML_ERR_COMMAND_NOT_HANDLED 0x1003 /**< no callback function is available to handle this command */ #define SML_ERR_ALREADY_INITIALIZED 0x1004 /**< Mgr allready initialized */ /* * SyncML Xlt Error Codes */ #define SML_ERR_XLT_MISSING_CONT 0x2001 /**< required field content missing */ #define SML_ERR_XLT_BUF_ERR 0x2002 /**< Buffer too small */ #define SML_ERR_XLT_INVAL_PCDATA_TYPE 0x2003 /**< Invalid (WBXML) Element Type (STR_I etc.) */ #define SML_ERR_XLT_INVAL_LIST_TYPE 0x2004 /**< Invalid List Type (COL_LIST etc.) */ #define SML_ERR_XLT_INVAL_TAG_TYPE 0x2005 /**< Invalid Tag Type (TT_BEG etc.) */ #define SML_ERR_XLT_ENC_UNK 0x2007 /**< Unknown Encoding (WBXML, XML) */ #define SML_ERR_XLT_INVAL_PROTO_ELEM 0x2008 /**< Invalid Protocol Element (ADD, Delete, ...) */ #define SML_ERR_MISSING_LIST_ELEM 0x2009 /**< Missing Content of List Elements */ #define SML_ERR_XLT_INCOMP_WBXML_VERS 0x200A /**< Incompatible WBXML Content Format Version */ #define SML_ERR_XLT_INVAL_SYNCML_DOC 0x200B /**< Document does not conform to SyncML DTD */ #define SML_ERR_XLT_INVAL_PCDATA 0x200C /**< Invalid PCData elem (e.g. not encoded as OPAQUE data) */ #define SML_ERR_XLT_TOKENIZER_ERROR 0x200D /**< Unspecified tokenizer error */ #define SML_ERR_XLT_INVAL_WBXML_DOC 0x200E /**< Document does not conform to WBXML specification */ #define SML_ERR_XLT_WBXML_UKN_TOK 0x200F /**< Document contains unknown WBXML token */ #define SML_ERR_XLT_MISSING_END_TAG 0x2010 /**< Non-empty start tag without matching end tag */ #define SML_ERR_XLT_INVALID_CODEPAGE 0x2011 /**< WBXML document uses unspecified code page */ #define SML_ERR_XLT_END_OF_BUFFER 0x2012 /**< End of buffer reached */ #define SML_ERR_XLT_INVAL_XML_DOC 0x2013 /**< Document does not conform to XML 1.0 specification */ #define SML_ERR_XLT_XML_UKN_TAG 0x2014 /**< Document contains unknown XML tag */ #define SML_ERR_XLT_INVAL_PUB_IDENT 0x2015 /**< Invalid Public Identifier */ #define SML_ERR_XLT_INVAL_EXT 0x2016 /**< Invalid Codepage Extension */ #define SML_ERR_XLT_NO_MATCHING_CODEPAGE 0x2017 /**< No matching Codepage could be found */ #define SML_ERR_XLT_INVAL_INPUT_DATA 0x2018 /**< Data missing in input structure */ /* * SyncML Wsm Error Codes */ #define SML_ERR_WSM_BUF_TABLE_FULL 0x3001 /**< no more empty entries in buffer table available */ /* * SyncML Util Error Codes */ #define SML_ERR_A_UTI_UNKNOWN_PROTO_ELEMENT 0x7001 #endif libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/inc/smlmetinfdtd.h000077500000000000000000000100051226375725500244330ustar00rootroot00000000000000/** * @file * SyncML Meta Information DTD specific type definitions * * @target_system all * @target_os all * @description Definition of structures representing MetInf DTD elements */ /**************************************************************************/ /* @note */ /* These definitions are based on the MetInf DTD dated from Aug, 29th, 00 */ /**************************************************************************/ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ #ifndef _SML_METINFDTD_H #define _SML_METINFDTD_H /* process only if we really use MetInf DTD */ #ifdef __USE_METINF__ /*************************************************************************/ /* Definitions */ /*************************************************************************/ #include #include typedef struct sml_metinf_anchor_s { SmlPcdataPtr_t last; /* optional */ SmlPcdataPtr_t next; } *SmlMetInfAnchorPtr_t, SmlMetInfAnchor_t; typedef struct sml_metinf_mem_s { /* %%% luz 2005-08-24 :this definition was plain wrong - shared is a flag, not Pcdata! SmlPcdataPtr_t shared; */ SmlPcdataPtr_t free; SmlPcdataPtr_t freeid; /* Added by Synthesis/luz 2005-08-24, was wrong in toolkit up to now! */ Flag_t flags; // SharedMem flag (SmlMetInfSharedMem_f) } *SmlMetInfMemPtr_t, SmlMetInfMem_t; typedef struct sml_metinf_metinf_s { SmlPcdataPtr_t format; /* opt. */ SmlPcdataPtr_t type; /* opt. */ SmlPcdataPtr_t mark; /* opt. */ SmlPcdataPtr_t size; /* opt. */ SmlPcdataPtr_t nextnonce; /* opt. */ SmlPcdataPtr_t version; SmlPcdataPtr_t maxmsgsize; /* optional */ /* SCTSTK - 18/03/2002, S.H. 2002-04-05 : SyncML 1.1 */ SmlPcdataPtr_t maxobjsize; /* optional */ SmlMetInfMemPtr_t mem; /* optional */ SmlPcdataListPtr_t emi; /* optional */ SmlMetInfAnchorPtr_t anchor; /* opt. */ /* SyncML DS 1.2, Synthesis/luz 2005-08-24 */ Flag_t flags; // FieldLevel flag (SmlMetInfFieldLevel_f) } *SmlMetInfMetInfPtr_t, SmlMetInfMetInf_t; #endif /* __USE_METINF__ */ #endif /* _SML_METINFDTD_H */ libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/inc/win/000077500000000000000000000000001226375725500223665ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/inc/win/define.h000077500000000000000000000124771226375725500240070ustar00rootroot00000000000000/** * @file * Compiler Flag Definition File * * @target_system win * @target_os win */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ /** * File for Windows Specific Compiler Flags */ #ifndef _DEFINE_H #define _DEFINE_H #define __ANSI_C__ /* thread safety (added by luz@synthesis.ch, 2001-10-29) */ /* Note: moved define of this to target_options.h of every target #undef __MAKE_THREADSAFE /* enable Alloc helpers */ #define __USE_ALLOCFUNCS__ /* do we need WBXML (binary XML) processing ? */ #define __SML_WBXML__ /* do we need the capability to decode plain text tokens in WBXML? */ #define __SML_WBXML_TEXTTOKENS__ /* do we need XML processing ? */ #define __SML_XML__ /* are we using a 'light' toolkit ? */ //#define __SML_LITE__ /* do we use Sub DTD extensions ? */ #define __USE_EXTENSIONS__ /* do we need Metainformation DTD parsing ? */ #define __USE_METINF__ /* do we use Device Info DTD ? */ #define __USE_DEVINF__ /* which of the following optional commands should be included ? */ #define ADD_SEND #define ATOMIC_SEND #define ATOMIC_RECEIVE #define COPY_SEND #define COPY_RECEIVE #define EXEC_SEND #define EXEC_RECEIVE #define GET_SEND #define MAP_RECEIVE #define MAPITEM_RECEIVE #define RESULT_RECEIVE #define SEARCH_SEND #define SEARCH_RECEIVE #define SEQUENCE_SEND #define SEQUENCE_RECEIVE /* TK: to improve interoperability and handling we * switched to using .def files instead of compiler * specific per function definitions. As long as we only * use C this is the easiest and cleanes way */ #define SML_API #define SML_API_DEF #define XPT_API #define XPT_API_DEF /* Multi segment macro for Palm OS */ #define LIB_FUNC #define MGR_FUNC #define WSM_FUNC #define XLT_FUNC /* TK: Old, now obsolete code follows here */ #ifdef USE_OLD_DEFINES /* When building the DLL code with GNU, you should define BUILDING_DLL so that the variables/functions are exported correctly. When using the DLL, do NOT define BUILDING_DLL, and then the variables/functions will be imported correctly. You need to be using egcs-1.1.1 or newer. Building the DLL: - define BUILDING_DLL, which defines SML_API __attribute__((dllexport)) Building the client code: - DO NOT define BUILDING_DLL, which defines SML_API to be one __attribute__((dllimport)) */ #if __GNUC__ || __MSVC__ || __MSVCPP__ || _WIN32_WCE /* define this, if you want to link the toolkit static */ #if __LINK_TOOLKIT_STATIC__ || __linux__ #define SML_API #define SML_API_DEF #define XPT_API #define XPT_API_DEF #else #if BUILDING_DLL #define SML_API __declspec (dllexport) #define SML_API_DEF __declspec (dllexport) #define XPT_API __declspec (dllexport) #define XPT_API_DEF __declspec (dllexport) #else /* Not BUILDING_DLL */ #define SML_API __declspec (dllimport) #define SML_API_DEF __declspec (dllimport) #define XPT_API __declspec (dllimport) #define XPT_API_DEF __declspec (dllimport) #endif /* Not BUILDING_DLL */ #endif #else #if __IBMC__ || __IBMCPP__ #define SML_API_DEF __stdcall #define SML_API __stdcall _Export #define XPT_API_DEF __stdcall #define XPT_API __stdcall _Export #else #if WIN32 #define SML_API __declspec (dllexport) #define SML_API_DEF __declspec (dllexport) #define XPT_API #error #define XPT_API_DEF #error #else #define SML_API_DEF __stdcall #define SML_API __stdcall #define XPT_API_DEF __stdcall #define XPT_API __stdcall #endif #endif #endif #endif // USE_OLD_DEFINES #endif libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/lib/000077500000000000000000000000001226375725500215665ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/lib/all/000077500000000000000000000000001226375725500223365ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/lib/all/liblock.c000077500000000000000000000031261226375725500241260ustar00rootroot00000000000000/** * @file * Library for Thread Locking Functions * * @target_system ALL * @target_os ALL * @description thread-locking library, RTK addition by luz@synthesis.ch */ #include "syncml_tk_prefix_file.h" // %%% luz: needed for precompiled headers in eVC++ #define _IMPLEMENTS_LOCK_GLOBALS #include "liblock.h" #undef _IMPLEMENTS_LOCK_GLOBALS #ifdef __DEBUG_LOCKS static short gLockNest; void _ToolKitLockInit(const char *msg) { gLockNest=0; InitializeCriticalSection(&gSmlLock); DEBUGPRINTF(("Toolkitlock initialized from '%s'",msg)) } // _ToolKitLockInit void _ToolKitLockFree(const char *msg) { DeleteCriticalSection(&gSmlLock); DEBUGPRINTF(("Toolkitlock freed from '%s'",msg)); } // _ToolKitLockFree void _LockToolKit(const char *msg) { short sec=0; int k; if (!TryEnterCriticalSection(&gSmlLock)) { // could not enter for (k=0; k<10; k++) { Sleep(100); // wait 0.1 sec if (TryEnterCriticalSection(&gSmlLock)) goto entered; } // could not enter after 1 sec DEBUGPRINTF(("Toolkitlock not free after 1 sec trying...")) do { Sleep(30000); // wait 30 secs sec+=30; if (TryEnterCriticalSection(&gSmlLock)) goto entered; DEBUGPRINTF(("Toolkitlock not free after %d sec trying...",sec)) } while (1); } entered: #if __DEBUG_LOCKS>1 DEBUGPRINTF(("Toolkitlock entered from '%s'",msg)) #endif ; } // _LockToolKit void _ReleaseToolKit(const char *msg) { LeaveCriticalSection(&gSmlLock); #if __DEBUG_LOCKS>1 DEBUGPRINTF(("Toolkitlock released from '%s'",msg)) #endif } // _ReleaseToolKit #endif /* eof */ libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/lib/all/libmem.c000077500000000000000000000140301226375725500237500ustar00rootroot00000000000000/** * @file * Library for Memory Functions * * @target_system ALL * @target_os ALL * @description Header for the implementation of common memory handling * functions */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ /************************************************************************* * Definitions *************************************************************************/ #include "syncml_tk_prefix_file.h" // %%% luz: needed for precompiled headers in eVC++ #include #include "libmem.h" #ifdef __PALM_OS__ #include "MemoryMgr.h" #endif #ifdef MEMORY_PROFILING // %%% luz 2002-10-02 #include "profiling.h" #endif /************************************************************************* * External Functions for all TOOLKIT Versions *************************************************************************/ /** * Deallocates the memory of object "pObject", which has been allocated * previously. * If "pObject" is a NULL pointer nothing happens. * If "pObject" is a pointer to memory which has not been allocated * previouly, the behaviour is undefined. * The contents of the deallocated memory object is destroyed. */ SML_API void smlLibFree(void *pObject) { if (! pObject) return; #ifdef __PALM_OS__ MemPtrFree(pObject); #else // %%% luz 2002-10-02 #ifdef MEMORY_PROFILING sysync_free(pObject); #else free(pObject); #endif #endif } /** * Changes size of preallocated space for memory object "pObject" * to the new size specified by "constSize". * * If the new size is larger than the old size, the old contents * is not changed. Additionally space is added at the the end of * "pObject". The new allocated space is not initialized * to any special value. * If the new size is smaller than the old size, the unused space * is discarded. * * If "pObject" is a NULL pointer, this function behaves just like * smlLibMalloc(). * If "pObject" does not point to a previously allocated memory area, * the behavior is undefined. * If "constSize" is 0, a NULL pointer is returned and the space * which "pObject" points to is freed up. * * Returns a pointer to the first byte of the resized object. * If no new memory could be allocated, a NULL Pointer is returned * without changing the memory object "pObject" (Nothing happens to the content). * * @param pObject (IN/OUT) * memory object, which size should be changed * @param constSize (IN) * new size the memory object shall use * @return void pointer to memory object, which size has been be changed\n * NULL, if not successfull or if constSize==0 */ SML_API void *smlLibRealloc(void *pObject, MemSize_t constSize) { #ifdef __PALM_OS__ VoidPtr_t _new_object; MemSize_t _old_size; // It's a malloc! if (pObject == NULL) return smlLibMalloc(constSize); _old_size = MemPtrSize(pObject); if (constSize <= _old_size) { // make it smaller MemPtrResize(pObject, constSize); _new_object = pObject; } else { // maker it larger (we need to allocate new memory somewhere else) _new_object = smlLibMalloc(constSize); if (_new_object != NULL) { smlLibMemmove(_new_object, pObject, _old_size); smlLibFree(pObject); } } return _new_object; #else // %%% luz 2002-10-02 #ifdef MEMORY_PROFILING return sysync_realloc(pObject, constSize); #else return realloc(pObject, constSize); #endif #endif } #ifndef __PALM_OS__ /* If not Palm OS we use the Standard ANSI C functions */ SML_API void *smlLibMemset(void *pObject, int value, MemSize_t count){ return memset(pObject, value, count); } SML_API void *smlLibMemcpy(void *pTarget, const void *pSource, MemSize_t count){ return memcpy(pTarget, pSource, count); } SML_API void *smlLibMemmove(void *pTarget, const void *pSource, MemSize_t count){ return memmove(pTarget, pSource, count); } SML_API int smlLibMemcmp(const void *pTarget, const void *pSource, MemSize_t count){ return memcmp(pTarget, pSource, count); } #ifndef smlLibMalloc // define only if not already defined as a macro SML_API void *smlLibMalloc(MemSize_t size) { // %%% luz 2002-10-02 #ifdef MEMORY_PROFILING return (void *)sysync_malloc(size); #else return (void *)malloc(size); #endif } #endif #endif libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/lib/all/libstr.c000077500000000000000000000115561226375725500240140ustar00rootroot00000000000000/** * @file * Library for String Functions * * @target_system ALL * @target_os ALL * @description implementation of common string-handling functions */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ /************************************************************************* * Definitions *************************************************************************/ #include "syncml_tk_prefix_file.h" // %%% luz: needed for precompiled headers in eVC++ #include #include "libstr.h" #include "libmem.h" #ifdef __ANSI_C__ #include #endif #ifdef __PALM_OS__ #include #endif /************************************************************************* * External Functions for all TOOLKIT Versions *************************************************************************/ /** * Duplicates the String "constStringP". * Returns a pointer to the new copy of "constStringP". * * @param constStringP (IN) * string which is duplicated * @return pointer to the new copy,\n * NULL if no copy could be allocated */ SML_API String_t smlLibStrdup (const char *constStringP) { String_t _new_str; // allocate memory for new copy _new_str = (String_t)smlLibMalloc(smlLibStrlen(constStringP) + 1); // Copy the string into the new memory if (_new_str != NULL) smlLibStrcpy(_new_str, constStringP); return _new_str; } #ifndef __PALM_OS__ /* If not Palm OS we use the Standard ANSI C functions */ SML_API String_t smlLibStrcpy(const char *pTarget, const char *pSource) { return strcpy((char *)pTarget, (char *)pSource); } SML_API String_t smlLibStrncpy(const char *pTarget, const char *pSource, int count){ return strncpy((char *)pTarget, (char *)pSource, count); } SML_API String_t smlLibStrcat(const char *pTarget, const char *pSource){ return strcat((char *)pTarget, (char *)pSource); } SML_API int smlLibStrcmp(const char *pTarget, const char *pSource){ return strcmp((char *)pTarget, (char *)pSource); } SML_API int smlLibStrncmp(const char *pTarget, const char *pSource, int count){ return strncmp((char *)pTarget, (char *)pSource, count); } SML_API int smlLibStrnCasecmp(const char *pTarget, const char *pSource, int count){ return strncasecmp((char *)pTarget, (char *)pSource, count); } SML_API String_t smlLibStrchr(const char *pString, char character){ return strchr((char *)pString, character); } SML_API int smlLibStrlen(const char *pString){ return strlen((char *)pString); } #endif /************************************************************************* * Additional External Functions for Full Size TOOLKIT ONLY *************************************************************************/ #ifndef __SML_LITE__ /* these API calls are NOT included in the Toolkit lite version */ #ifndef __PALM_OS__ /* we use #define to reduce heap usage */ SML_API String_t smlLibStrncat(const char *pTarget, const char *pSource, int count){ return strncat((char *)pTarget, (char *)pSource, count); } SML_API String_t smlLibStrstr(const char *pString, const char *pSubString){ return strstr((char *)pString, (char *)pSubString); } #endif #endif libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/lib/all/libutil.c000077500000000000000000000116771226375725500241650ustar00rootroot00000000000000/** * @file * Library for IO Functions * * @target_system ALL * @target_os ALL * @description Utility I/O functions */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ /************************************************************************* * Definitions *************************************************************************/ #include "syncml_tk_prefix_file.h" // %%% luz: needed for precompiled headers in eVC++ #ifndef NOWSM // Note: in NOWSM case, these routines must be implemented in the // calling main code. #include #include #ifdef __ANSI_C__ #include #include #endif #ifdef __PALM_OS__ #include #include #endif #ifdef __EPOC_OS__ #include #include #endif #include "define.h" #include "libmem.h" #include "mgr.h" #include "libutil.h" // size of output buffer #define BUFFERSIZE 128 /* Used external functions */ extern SyncMLInfoPtr_t mgrGetSyncMLAnchor(); /************************************************************************* * External Functions *************************************************************************/ /** * Assembles a formatted textstring out of a list of argument. This string is * passed to a callback function, which is implementated by the application * for output to the user * * @param text (IN) * printf like format text string with multiple * arguments to be formatted as specified\n * Supported are: * \%d, \%i, \%u, \%x, \%s, \%c\n * +, -, \, *, \, h, l, L */ SML_API void smlLibPrint(const char *text, ...) { char pBuffer[BUFFERSIZE]; va_list args; SyncMLInfoPtr_t pSyncMLInfo; if ((pSyncMLInfo = mgrGetSyncMLAnchor()) != NULL) { pBuffer[0] = '\0'; va_start(args, text); // assemble the text string out of the single arguments #ifdef __ANSI_C__ vsprintf(pBuffer, text, args); #endif #ifdef __PALM_OS__ StrVPrintF(pBuffer, text, args); #endif #ifdef __EPOC_OS__ vsprintf(pBuffer, text, args); #endif va_end(args); // use the application callback function, // which implements the output. if (pSyncMLInfo && pSyncMLInfo->syncmlOptions && pSyncMLInfo->syncmlOptions->defaultPrintFunc) ((smlPrintFunc)(pSyncMLInfo->syncmlOptions->defaultPrintFunc))(pBuffer); } } SML_API void smlLibVprintf(const char *format, va_list args) { char pBuffer[BUFFERSIZE]; SyncMLInfoPtr_t pSyncMLInfo; if ((pSyncMLInfo = mgrGetSyncMLAnchor()) != NULL) { pBuffer[0] = '\0'; // assemble the text string out of the single arguments #ifdef __ANSI_C__ vsprintf(pBuffer, format, args); #endif #ifdef __PALM_OS__ StrVPrintF(pBuffer, format, args); #endif #ifdef __EPOC_OS__ vsprintf(pBuffer, format, args); #endif // use the application callback function, // which implements the output. if (pSyncMLInfo && pSyncMLInfo->syncmlOptions && pSyncMLInfo->syncmlOptions->defaultPrintFunc) ((smlPrintFunc)(pSyncMLInfo->syncmlOptions->defaultPrintFunc))(pBuffer); } } #endif // !defined(NOWSM) libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/lib/inc/000077500000000000000000000000001226375725500223375ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/lib/inc/liblock.h000077500000000000000000000043311226375725500241330ustar00rootroot00000000000000/** * @file * Library for Thread Locking Functions * * @target_system ALL * @target_os ALL * @description thread-locking library, RTK addition by luz@synthesis.ch */ #ifndef LIBLOCK_H #define LIBLOCK_H #include "define.h" #ifdef __DEBUG_LOCKS // needs debug global and DebugPrintf() extern void ThreadDebugPrintf(const char *text,...); #define DEBUGPRINTF(m) { ThreadDebugPrintf m; } #endif #if defined(__MAKE_THREADSAFE) && !defined(NOWSM) // thread safety measures are required only when working with WSM #ifdef _WIN32 #ifdef __DEBUG_LOCKS // we need TryEnterCriticalSection for debug #define _WIN32_WINNT 0x0400 #endif #define WIN32_LEAN_AND_MEAN #include #undef WIN32_LEAN_AND_MEAN // remove problematic windows defines (OPAQUE in wingdi.h, OPTIONAL in ????) #undef OPAQUE #undef OPTIONAL #include #ifdef __DEBUG_LOCKS /* - functions that also document lock usage */ void _ToolKitLockInit(const char *msg); void _ToolKitLockFree(const char *msg); void _LockToolKit(const char *msg); void _ReleaseToolKit(const char *msg); #define TOOLKITLOCK_INIT(m) _ToolKitLockInit(m); #define TOOLKITLOCK_FREE(m) _ToolKitLockFree(m); #define LOCKTOOLKIT(m) _LockToolKit(m); #define RELEASETOOLKIT(m) _ReleaseToolKit(m); #else /* - simple macros to use the lock */ #define TOOLKITLOCK_INIT(m) InitializeCriticalSection(&gSmlLock); #define TOOLKITLOCK_FREE(m) DeleteCriticalSection(&gSmlLock); #define LOCKTOOLKIT(m) EnterCriticalSection(&gSmlLock); #define RELEASETOOLKIT(m) LeaveCriticalSection(&gSmlLock); #endif #else #error "liblock.h: unsupported platform" #endif #else /* just NOP */ #define TOOLKITLOCK_INIT(m) #define TOOLKITLOCK_FREE(m) #define LOCKTOOLKIT(m) #define RELEASETOOLKIT(m) #endif #endif // LIBLOCK_H // globals declarations may not be omitted on second include! #ifdef __MAKE_THREADSAFE #ifdef _WIN32 /* define the required things */ #ifndef _IMPLEMENTS_LOCK_GLOBALS /* - the lock itself, as global variable */ extern CRITICAL_SECTION gSmlLock; #else CRITICAL_SECTION gSmlLock; #endif #endif #endif /* eof */ libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/lib/inc/libmem.h000077500000000000000000000077241226375725500237720ustar00rootroot00000000000000/** * @file * Library for Memory Functions * * @target_system ALL * @target_os ALL * @description Header for the implementation of common memory handling functions */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ #ifndef _LIB_MEM_H #define _LIB_MEM_H /************************************************************************* * Definitions *************************************************************************/ #include "define.h" #include #include #ifdef __ANSI_C__ #include #endif #ifdef __PALM_OS__ #include #endif /************************************************************************* * External Functions for all Toolkit versions *************************************************************************/ #ifdef __PALM_OS__ /* we use #define to reduce heap usage */ void *smlLibRealloc (VoidPtr_t objectP, MemSize_t constSize) LIB_FUNC; void smlLibFree (void* objectP) LIB_FUNC; #define smlLibMemset(pObject,value,count) ((void)MemSet((VoidPtr_t)pObject,(MemSize_t)count,(int)value)) #define smlLibMemcpy(pTarget,pSource,count) (MemMove(pTarget,(VoidPtr_t)pSource,count) ? pTarget : pTarget) #define smlLibMemmove(pTarget,pSource,count) (MemMove(pTarget,(VoidPtr_t)pSource,(MemSize_t)count) ? pTarget : pTarget) #define smlLibMemcmp(pTarget,pSource,count) (MemCmp((VoidPtr_t)pTarget,(VoidPtr_t)pSource,(MemSize_t)count)) #define smlLibMalloc(size) ((VoidPtr_t)MemPtrNew((MemSize_t)size)) #define smlLibMemsize(pObject) ((MemSize_t)MemPtrSize((VoidPtr_t)pObject)) #else SML_API_DEF void *smlLibRealloc(void *pObject, MemSize_t size) LIB_FUNC; SML_API_DEF void smlLibFree(void *pObject) LIB_FUNC; SML_API_DEF void *smlLibMemset(void *pObject, int value, MemSize_t count) LIB_FUNC; SML_API_DEF void *smlLibMemcpy(void *pTarget, const void *pSource, MemSize_t count) LIB_FUNC; SML_API_DEF void *smlLibMemmove(void *pTarget, const void *pSource, MemSize_t count) LIB_FUNC; SML_API_DEF int smlLibMemcmp(const void *pTarget, const void *pSource, MemSize_t count) LIB_FUNC; // original: SML_API_DEF void *smlLibMalloc(MemSize_t size) LIB_FUNC; #define smlLibMalloc(m) malloc(m) #endif #endif libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/lib/inc/libstr.h000077500000000000000000000117321226375725500240160ustar00rootroot00000000000000/** * @file * Library for String Functions * * @target_system ALL * @target_os ALL * @description Header for the implementation of common string-handling functions */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ #ifndef __LIB_STR_H #define __LIB_STR_H /************************************************************************* * Definitions *************************************************************************/ #include "define.h" #include "smldef.h" #include "libmem.h" #ifdef __ANSI_C__ #include #endif #ifdef __PALM_OS__ #include #endif /************************************************************************* * External Functions for all Toolkit versions *************************************************************************/ #ifdef __PALM_OS__ /* we use #define to reduce heap usage */ String_t smlLibStrdup (const char* constStringP) LIB_FUNC; #define smlLibStrcpy(pTarget,pSource) (char*)StrCopy((char*)pTarget,(char*)pSource) #define smlLibStrncpy(pTarget,pSource,count) (char*)StrNCopy((char*)pTarget,(char*)pSource,count) #define smlLibStrcat(pTarget,pSource) (char*)StrCat((char*)pTarget,(char*)pSource) #define smlLibStrcmp(pTarget,pSource) StrCompare((char*)pTarget,(char*)pSource) #define smlLibStrncmp(pTarget,pSource,count) StrNCompare((char*)pTarget,(char*)pSource,count) #define smlLibStrchr(pString,character) (char*)StrChr((String_t)pString,character) #define smlLibStrlen(pString) StrLen((char*)pString) #else /* we use functions, to make the library exportable */ SML_API_DEF String_t smlLibStrdup (const char *constStringP) LIB_FUNC; SML_API_DEF String_t smlLibStrcpy(const char *pTarget, const char *pSource) LIB_FUNC; SML_API_DEF String_t smlLibStrncpy(const char *pTarget, const char *pSource, int count) LIB_FUNC; SML_API_DEF String_t smlLibStrcat(const char *pTarget, const char *pSource) LIB_FUNC; SML_API_DEF int smlLibStrcmp(const char *pTarget, const char *pSource) LIB_FUNC; SML_API_DEF int smlLibStrncmp(const char *pTarget, const char *pSource, int count) LIB_FUNC; SML_API_DEF int smlLibStrnCasecmp(const char *pTarget, const char *pSource, int count) LIB_FUNC; SML_API_DEF String_t smlLibStrchr(const char *pString, char character) LIB_FUNC; SML_API_DEF int smlLibStrlen(const char *pString) LIB_FUNC; #endif /************************************************************************* * Additional External Functions for Full Sized Toolkit Only *************************************************************************/ #ifndef __SML_LITE__ /* these API calls are NOT included in the Toolkit lite version */ #ifdef __PALM_OS__ /* we use define to reduce heap usage */ #define smlLibStrncat(pTarget,pSource,count) (char*)StrNCat((char*)pTarget,(char*)pSource,count) #define smlLibStrstr(pString,pSubstring) (char*)StrStr((char*)pString,(char*)pSubstring) #else /* we use functions, to make the library exportable */ SML_API_DEF String_t smlLibStrncat(const char *pTarget, const char *pSource, int count) LIB_FUNC; SML_API_DEF String_t smlLibStrstr(const char *pString, const char *pSubString) LIB_FUNC; #endif #endif #endif libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/lib/inc/libutil.h000077500000000000000000000053671226375725500241720ustar00rootroot00000000000000/** * @file * Library for utility Functions * * @target_system ALL * @target_os ALL * @description Some I/O Utilities */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ #ifndef _LIB_UTIL_H #define _LIB_UTIL_H /************************************************************************* * Definitions *************************************************************************/ #include "define.h" #include "smldef.h" #ifdef __ANSI_C__ #include #endif #ifdef __PALM_OS__ #ifndef _MSL_CSTDARG #include // only if we don't use MSL #endif #endif #ifdef __EPOC_OS__ #include #endif /************************************************************************* * External Functions *************************************************************************/ /* IO functions */ SML_API_DEF void smlLibPrint(const char *text, ...) LIB_FUNC; SML_API_DEF void smlLibVprintf(const char *format, va_list va) LIB_FUNC; #endif libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/mgr/000077500000000000000000000000001226375725500216055ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/mgr/all/000077500000000000000000000000001226375725500223555ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/mgr/all/mgr.c000077500000000000000000000213461226375725500233170ustar00rootroot00000000000000/** * @file * Managing SyncML * * @target_system all * @target_os all * @description Core Module managing the life-cycle of a syncML Process itself */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ /************************************************************************* * Definitions *************************************************************************/ #include "syncml_tk_prefix_file.h" // %%% luz: needed for precompiled headers in eVC++ /* Include Headers */ #include #include #include #if defined(NOWSM) && !__LINK_TOOLKIT_STATIC__ // we need dummies of these as they are listed in the SyncML.def file SML_API_DEF Ret_t smlInit(SmlOptionsPtr_t pOptions) { return SML_ERR_OK; } SML_API_DEF Ret_t smlSetSyncMLOptions (SmlOptionsPtr_t pOptions) { return SML_ERR_OK; } SML_API_DEF Ret_t smlTerminate(void) { return SML_ERR_OK; } #endif #ifndef NOWSM #include "libmem.h" #include "liblock.h" #include "wsm.h" #include "mgr.h" #ifdef __EPOC_OS__ #include "core_globals_epoc.h" #endif /* Prototypes of exported SyncML API functions */ SML_API Ret_t smlInit(SmlOptionsPtr_t pOptions); SML_API Ret_t smlSetSyncMLOptions (SmlOptionsPtr_t pOptions); SML_API Ret_t smlTerminate(void); /* SyncML internal function prototypes */ InstanceInfoPtr_t mgrGetInstanceListAnchor(void); void mgrSetInstanceListAnchor(InstanceInfoPtr_t newListAnchor); SyncMLInfoPtr_t mgrGetSyncMLAnchor(void); /** * Anchor of the global syncML info structure */ #ifndef __EPOC_OS__ static SyncMLInfoPtr_t pGlobalAnchor=NULL; // this global pointer is used to access ALL globals within syncml #endif // This is the ONLY global varible of SyncML! #ifdef __EPOC_OS__ #define pGlobalAnchor TheCoreGlobalsEpoc()->pGlobalAnchor #endif /************************************************************************* * Exported SyncML API functions *************************************************************************/ /** * Initializes the SyncML Reference Tookit. This is required, before any * other function can be used. * * @param pCoreOptions (IN) * options to be applied for the toolkit * @return Return Code */ SML_API Ret_t smlInit(SmlOptionsPtr_t pCoreOptions) { /* ---- Definitions --- */ WsmOptions_t* pWorkspaceOptions; Ret_t rc; /* --- check, if SyncML has already been initialized --- */ if (pGlobalAnchor!=NULL) return SML_ERR_ALREADY_INITIALIZED; /* --- Check pOptions, which have been passed by the application --- */ if (!pCoreOptions) return SML_ERR_WRONG_USAGE; /* --- Create a SyncML info memory object to store all globals --- */ TOOLKITLOCK_INIT("smlInit"); pGlobalAnchor = (SyncMLInfoPtr_t)smlLibMalloc((MemSize_t)sizeof(SyncMLInfo_t)); if (pGlobalAnchor==NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pGlobalAnchor,0,(MemSize_t)sizeof(SyncMLInfo_t)); /* --- Set SyncML settings and options --- */ pGlobalAnchor->instanceListAnchor = NULL; // no instance exists at the beginning rc = smlSetSyncMLOptions (pCoreOptions); // store the options in the global structure if (rc!=SML_ERR_OK){ smlLibFree(pGlobalAnchor); pGlobalAnchor = NULL; return rc; } pGlobalAnchor->tokTbl = (TokenInfoPtr_t)smlLibMalloc(sizeof(TokenInfo_t)); if (pGlobalAnchor->tokTbl == NULL) { smlLibFree(pGlobalAnchor); return SML_ERR_NOT_ENOUGH_SPACE; } smlLibMemset(pGlobalAnchor->tokTbl, 0, sizeof(TokenInfo_t)); /* --- Init all modules ---*/ /* Init Workspace Module */ pWorkspaceOptions=(WsmOptions_t*)smlLibMalloc((MemSize_t)sizeof(WsmOptions_t)); // create workspace options if (pWorkspaceOptions == NULL) { smlLibFree(pGlobalAnchor->syncmlOptions); smlLibFree(pGlobalAnchor->tokTbl); smlLibFree(pGlobalAnchor); pGlobalAnchor = NULL; return SML_ERR_NOT_ENOUGH_SPACE; } smlLibMemset(pWorkspaceOptions,0,(MemSize_t)sizeof(WsmOptions_t)); pWorkspaceOptions->maxAvailMem=(MemSize_t)pGlobalAnchor->syncmlOptions->maxWorkspaceAvailMem; rc = wsmInit (pWorkspaceOptions); if (rc!=SML_ERR_OK){ smlLibFree(pGlobalAnchor->syncmlOptions); smlLibFree(pGlobalAnchor->tokTbl); smlLibFree(pGlobalAnchor); pGlobalAnchor = NULL; smlLibFree(pWorkspaceOptions); return rc; } smlLibFree(pWorkspaceOptions); return SML_ERR_OK; } /** * Terminate SyncML. Frees all memory and other ressources used by * SyncML. This function must be called when terminating SyncML * * @pre All instances must have been terminated * @return Return Code */ SML_API Ret_t smlTerminate(void) { // Have all Instances been terminated? if (pGlobalAnchor->instanceListAnchor!=NULL) return SML_ERR_WRONG_USAGE; /* --- Make sure, the workspace is destroyed --*/ LOCKTOOLKIT("smlTerminate"); wsmTerminate(); /* --- Free the global structure --*/ smlLibFree(pGlobalAnchor->tokTbl->SyncML); smlLibFree(pGlobalAnchor->tokTbl->MetInf); smlLibFree(pGlobalAnchor->tokTbl->DevInf); smlLibFree(pGlobalAnchor->tokTbl); smlLibFree(pGlobalAnchor->syncmlOptions); smlLibFree(pGlobalAnchor); pGlobalAnchor=NULL; TOOLKITLOCK_FREE("smlTerminate"); return SML_ERR_OK; } /** * Change the option settings for syncML * * @param pCoreOptions (IN) * options to be applied for the toolkit * @return Return Code */ SML_API Ret_t smlSetSyncMLOptions(SmlOptionsPtr_t pCoreOptions) { /* ---- Definitions --- */ SmlOptionsPtr_t pCoreOptionsCopy; /* --- Check pOptions, which have been passed by the application --- */ if (!pCoreOptions) return SML_ERR_WRONG_USAGE; /* --- free SyncML options --- */ smlLibFree(pGlobalAnchor->syncmlOptions); pGlobalAnchor->syncmlOptions = NULL; /* --- Use a copy of pCoreOptions --- */ pCoreOptionsCopy = (SmlOptionsPtr_t)smlLibMalloc((MemSize_t)sizeof(SmlOptions_t)); if (pCoreOptionsCopy==NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemcpy(pCoreOptionsCopy,pCoreOptions,(MemSize_t)sizeof(SmlOptions_t)); /* --- set new SyncML options --- */ pGlobalAnchor->syncmlOptions = pCoreOptionsCopy; // set the options,passed from the application return SML_ERR_OK; } /************************************************************************* * SyncML internal functions *************************************************************************/ /** * Retrieves a pointer to the structure holding all global informations * within SyncML * * @return Pointer to the pGlobalAnchor */ SyncMLInfoPtr_t mgrGetSyncMLAnchor(void) { return pGlobalAnchor; } /** * Retrieves a pointer to the list holding all instance informations * * @return Pointer to the pInstanceListAnchor */ InstanceInfoPtr_t mgrGetInstanceListAnchor(void) { return pGlobalAnchor->instanceListAnchor; } /** * Set the pointer to the list holding all instance informations * * @param newListAnchor (IN) * pointer to the pInstanceListAnchor */ void mgrSetInstanceListAnchor(InstanceInfoPtr_t newListAnchor) { pGlobalAnchor->instanceListAnchor=newListAnchor; } #endif // !defined(NOWSM) libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/mgr/all/mgrcmdbuilder.c000077500000000000000000000566051226375725500253600ustar00rootroot00000000000000/** * @file * SyncML Command Builder * * @target_system all * @target_os all * @description Core Module for assembling SyncML compliant documents */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ /************************************************************************* * Definitions *************************************************************************/ #include "syncml_tk_prefix_file.h" // %%% luz: needed for precompiled headers in eVC++ /* Include Headers */ #include #include "xltenc.h" #include "xltdec.h" #include "libmem.h" #include "mgr.h" /* Used external functions */ extern Ret_t smlLockWriteBuffer(InstanceID_t id, MemPtr_t *pWritePosition, MemSize_t *freeSize); extern Ret_t smlUnlockWriteBuffer(InstanceID_t id, MemSize_t writtenBytes); #ifndef __SML_LITE__ /* these API calls are NOT included in the Toolkit lite version */ extern Ret_t addInfo(InstanceInfoPtr_t pInfo); extern InstanceInfoPtr_t findInfo(InstanceID_t id); extern Ret_t removeInfo(InstanceID_t id); #endif /* Prototypes of exported SyncML API functions */ SML_API Ret_t smlStartMessage(InstanceID_t id, SmlSyncHdrPtr_t pContent); SML_API Ret_t smlStartMessageExt(InstanceID_t id, SmlSyncHdrPtr_t pContent, SmlVersion_t vers); SML_API Ret_t smlEndMessage(InstanceID_t id, Boolean_t final); SML_API Ret_t smlStartSync(InstanceID_t id, SmlSyncPtr_t pContent); SML_API Ret_t smlEndSync(InstanceID_t id); #ifdef ATOMIC_SEND /* these API calls are NOT included in the Toolkit lite version */ SML_API Ret_t smlStartAtomic(InstanceID_t id, SmlAtomicPtr_t pContent); SML_API Ret_t smlEndAtomic(InstanceID_t id); #endif #ifdef SEQUENCE_SEND SML_API Ret_t smlStartSequence(InstanceID_t id, SmlSequencePtr_t pContent); SML_API Ret_t smlEndSequence(InstanceID_t id); #endif #ifdef ADD_SEND SML_API Ret_t smlAddCmd(InstanceID_t id, SmlAddPtr_t pContent); #endif SML_API Ret_t smlAlertCmd(InstanceID_t id, SmlAlertPtr_t pContent); SML_API Ret_t smlDeleteCmd(InstanceID_t id, SmlDeletePtr_t pContent); #ifdef GET_SEND SML_API Ret_t smlGetCmd(InstanceID_t id, SmlGetPtr_t pContent); #endif SML_API Ret_t smlPutCmd(InstanceID_t id, SmlPutPtr_t pContent); SML_API Ret_t smlMapCmd(InstanceID_t id, SmlMapPtr_t pContent); SML_API Ret_t smlResultsCmd(InstanceID_t id, SmlResultsPtr_t pContent); SML_API Ret_t smlStatusCmd(InstanceID_t id, SmlStatusPtr_t pContent); SML_API Ret_t smlReplaceCmd(InstanceID_t id, SmlReplacePtr_t pContent); #ifdef COPY_SEND /* these API calls are NOT included in the Toolkit lite version */ SML_API Ret_t smlCopyCmd(InstanceID_t id, SmlCopyPtr_t pContent); #endif #ifdef EXEC_SEND SML_API Ret_t smlExecCmd(InstanceID_t id, SmlExecPtr_t pContent); #endif #ifdef SEARCH_SEND SML_API Ret_t smlSearchCmd(InstanceID_t id, SmlSearchPtr_t pContent); #endif SML_API Ret_t smlMoveCmd(InstanceID_t id, SmlMovePtr_t pContent); /* Private function prototypes */ static Ret_t mgrCreateNextCommand(InstanceID_t id, SmlProtoElement_t cmdType, VoidPtr_t pContent); Ret_t mgrResetWorkspace (InstanceID_t id); /************************************************************************* * Exported SyncML API functions *************************************************************************/ /** * Start a SyncML Message * * @param id (IN) * ID of the used instance * @param pContent (IN) * Data to pass along with that SyncML command * @return Return Code * @note (%%% luz 2003-08-06) this entry point is for compatibilty * reasons only and works for SyncML 1.0 only\n * please use smlStartMessageExt() instead in new projects. */ SML_API Ret_t smlStartMessage(InstanceID_t id, SmlSyncHdrPtr_t pContent) { /* just call smlStartMessageExt with vers set to SyncML 1.0 */ return smlStartMessageExt(id,pContent,SML_VERS_1_0); } /** * Start a SyncML Message * * @param id (IN) * ID of the used instance * @param pContent (IN) * Data to pass along with that SyncML command * @param vers (IN) * SyncML version * @note (%%% added by luz 2003-08-06 to support SyncML versions other than * 1.0 with new vers parameter) * @return Return Code */ SML_API Ret_t smlStartMessageExt(InstanceID_t id, SmlSyncHdrPtr_t pContent, SmlVersion_t vers) { /* --- Definitions --- */ InstanceInfoPtr_t pInstanceInfo; // pointer the the instance info structure for this id Ret_t rc; MemPtr_t pCurrentWritePosition; // current Position from to which to write MemPtr_t pBeginPosition; // saves the first position which has been written MemSize_t freeSize; // size of free memory for writing #ifdef NOWSM pInstanceInfo = (InstanceInfoPtr_t)id; // ID is the instance info pointer #else /* --- Retrieve the corresponding instanceInfo structure --- */ #ifdef __SML_LITE__ /* Only ONE instance is supported in the Toolkit lite version */ pInstanceInfo = mgrGetInstanceListAnchor(); #else pInstanceInfo = (InstanceInfoPtr_t) findInfo(id); #endif #endif if (pInstanceInfo==NULL) return SML_ERR_MGR_INVALID_INSTANCE_INFO; /* --- Get Write Access to the workspace --- */ #ifdef NOWSM // first remember where outgoing message starts in buffer smlSetOutgoingBegin(id); #endif // possibly, this will cause a buffer reset (if nothing is // unread in the buffer), and will auto-readjust the OutgoingBegin. rc = smlLockWriteBuffer(id, &pCurrentWritePosition, &freeSize); if (rc!=SML_ERR_OK) { // abort, unlock the buffer again without changing it's current position smlUnlockWriteBuffer(id, (MemSize_t)0); return rc; } /* Remember the position we have started writing */ pBeginPosition=pCurrentWritePosition; /* --- Call the encoder module --- */ /* (Saves the returned encoder state to the corresponding instanceInfo structure */ rc = xltEncInit (pInstanceInfo->instanceOptions->encoding, pContent, pCurrentWritePosition+freeSize, &pCurrentWritePosition, (XltEncoderPtr_t *)&(pInstanceInfo->encoderState), vers ); if (rc!=SML_ERR_OK) { // abort, unlock the buffer again without changing it's current position smlUnlockWriteBuffer(id, (MemSize_t)0); // Reset the encoder module (free the encoding object) xltEncReset(pInstanceInfo->encoderState); // this encoding job is over! reset instanceInfo pointer pInstanceInfo->encoderState=NULL; return rc; } /* --- End Write Access to the workspace --- */ rc = smlUnlockWriteBuffer(id, (MemSize_t)pCurrentWritePosition-(MemSize_t)pBeginPosition); return rc; } /** * End a SyncML Message * * @param id (IN) * ID of the used instance * @param final (IN) * Final Flag indicates last message within a package * @return Return Code */ SML_API Ret_t smlEndMessage(InstanceID_t id, Boolean_t final) { /* --- Definitions --- */ InstanceInfoPtr_t pInstanceInfo; // pointer the the instance info structure for this id Ret_t rc; MemPtr_t pCurrentWritePosition; // current Position from to which to write MemPtr_t pBeginPosition; // saves the first position which has been written MemSize_t freeSize; // size of free memory for writing #ifdef NOWSM pInstanceInfo = (InstanceInfoPtr_t)id; // ID is the instance info pointer #else /* --- Retrieve the corresponding instanceInfo structure --- */ #ifdef __SML_LITE__ /* Only ONE instance is supported in the Toolkit lite version */ pInstanceInfo = mgrGetInstanceListAnchor(); #else pInstanceInfo = (InstanceInfoPtr_t) findInfo(id); #endif #endif if (pInstanceInfo==NULL) return SML_ERR_MGR_INVALID_INSTANCE_INFO; // %%% luz 2003-08-19: added NULL check as previously failed encoding will delete encoder if (pInstanceInfo->encoderState==NULL) return SML_ERR_MGR_INVALID_INSTANCE_INFO; /* --- Get Write Access to the workspace --- */ rc = smlLockWriteBuffer(id, &pCurrentWritePosition, &freeSize); if (rc!=SML_ERR_OK) { // abort, unlock the buffer again without changing it's current position smlUnlockWriteBuffer(id, (MemSize_t)0); return rc; } /* Remember the position we have started writing */ pBeginPosition=pCurrentWritePosition; /* -- set Final Flag --*/ ((XltEncoderPtr_t)(pInstanceInfo->encoderState))->final = final; /* --- Call the encoder module --- */ rc = xltEncTerminate(pInstanceInfo->encoderState, pCurrentWritePosition+freeSize,&pCurrentWritePosition); if (rc!=SML_ERR_OK) { // abort, unlock the buffer again without changing it's current position smlUnlockWriteBuffer(id, (MemSize_t)0); // this encoding job is over! reset instanceInfo pointer pInstanceInfo->encoderState=NULL; return rc; } // this encoding job is over! reset instanceInfo pointer // (the decoding object itself has been freed by the decoder) pInstanceInfo->encoderState=NULL; /* --- End Write Access to the workspace --- */ rc = smlUnlockWriteBuffer(id, (MemSize_t)pCurrentWritePosition-(MemSize_t)pBeginPosition); return rc; } /** * Start synchronizing * * @param id (IN) * ID of the used instance * @param pContent (IN) Data to pass along with that SyncML command * @return Return Code */ SML_API Ret_t smlStartSync(InstanceID_t id, SmlSyncPtr_t pContent) { return mgrCreateNextCommand(id, SML_PE_SYNC_START, pContent); } /** * End synchronizing * * @param id (IN) * ID of the used instance * @return Return Code */ SML_API Ret_t smlEndSync(InstanceID_t id) { return mgrCreateNextCommand(id, SML_PE_SYNC_END, NULL); } #ifdef ATOMIC_SEND /* these API calls are NOT included in the Toolkit lite version */ /** * Start an atomic sequence * * @param id (IN) * ID of the used instance * @param pContent (IN) * Data to pass along with that SyncML command * @return Return Code */ SML_API Ret_t smlStartAtomic(InstanceID_t id, SmlAtomicPtr_t pContent) { return mgrCreateNextCommand(id, SML_PE_ATOMIC_START, pContent); } /** * End an atomic sequence * * @param id (IN) * ID of the used instance * @return Return Code */ SML_API Ret_t smlEndAtomic(InstanceID_t id) { return mgrCreateNextCommand(id, SML_PE_ATOMIC_END, NULL); } #endif #ifdef SEQUENCE_SEND /** * Start a sequence * * @param id (IN) * ID of the used instance * @param pContent (IN) * Data to pass along with that SyncML command * @return Return Code */ SML_API Ret_t smlStartSequence(InstanceID_t id, SmlSequencePtr_t pContent) { return mgrCreateNextCommand(id, SML_PE_SEQUENCE_START, pContent); } /** * End a sequence * * @param id (IN) * ID of the used instance * @return Return Code */ SML_API Ret_t smlEndSequence(InstanceID_t id) { return mgrCreateNextCommand(id, SML_PE_SEQUENCE_END, NULL); } #endif #ifdef ADD_SEND /** * Create a Add Command * * @param id (IN) * ID of the used instance * @param pContent (IN) * Data to pass along with that SyncML command * @return Return Code */ SML_API Ret_t smlAddCmd(InstanceID_t id, SmlAddPtr_t pContent) { return mgrCreateNextCommand(id, SML_PE_ADD, pContent); } #endif /** * Create a Alert Command * * @param id (IN) * ID of the used instance * @param pContent (IN) * Data to pass along with that SyncML command * @return Return Code */ SML_API Ret_t smlAlertCmd(InstanceID_t id, SmlAlertPtr_t pContent) { return mgrCreateNextCommand(id, SML_PE_ALERT, pContent); } /** * Create a Start Message Command * * @param id (IN) * ID of the used instance * @param pContent (IN) * Data to pass along with that SyncML command * @return Return Code */ SML_API Ret_t smlDeleteCmd(InstanceID_t id, SmlDeletePtr_t pContent) { return mgrCreateNextCommand(id, SML_PE_DELETE, pContent); } #ifdef GET_SEND /** * Create a Get Command * * @param id (IN) * ID of the used instance * @param pContent (IN) * Data to pass along with that SyncML command * @return Return Code */ SML_API Ret_t smlGetCmd(InstanceID_t id, SmlGetPtr_t pContent) { return mgrCreateNextCommand(id, SML_PE_GET, pContent); } #endif /** * Create a Put Command * * @param id (IN) * ID of the used instance * @param pContent (IN) * Data to pass along with that SyncML command * @return Return Code */ SML_API Ret_t smlPutCmd(InstanceID_t id, SmlPutPtr_t pContent) { return mgrCreateNextCommand(id, SML_PE_PUT, pContent); } /** * Create a Map Command * * @param id (IN) * ID of the used instance * @param pContent (IN) * Data to pass along with that SyncML command * @return Return Code */ SML_API Ret_t smlMapCmd(InstanceID_t id, SmlMapPtr_t pContent) { return mgrCreateNextCommand(id, SML_PE_MAP, pContent); } /** * Create a Results Command * * @param id (IN) * ID of the used instance * @param pContent (IN) * Data to pass along with that SyncML command * @return Return Code */ SML_API Ret_t smlResultsCmd(InstanceID_t id, SmlResultsPtr_t pContent) { return mgrCreateNextCommand(id, SML_PE_RESULTS, pContent); } /** * Create a Status Command * * @param id (IN) * ID of the used instance * @param pContent (IN) * Data to pass along with that SyncML command * @return Return Code */ SML_API Ret_t smlStatusCmd(InstanceID_t id, SmlStatusPtr_t pContent) { return mgrCreateNextCommand(id, SML_PE_STATUS, pContent); } /** * Create a Replace Command * * @param id (IN) * ID of the used instance * @param pContent (IN) * Data to pass along with that SyncML command * @return Return Code */ SML_API Ret_t smlReplaceCmd(InstanceID_t id, SmlReplacePtr_t pContent) { return mgrCreateNextCommand(id, SML_PE_REPLACE, pContent); } #ifdef COPY_SEND /* these API calls are NOT included in the Toolkit lite version */ /** * Create a Copy Command * * @param id (IN) * ID of the used instance * @param pContent (IN) * Data to pass along with that SyncML command * @return Return Code */ SML_API Ret_t smlCopyCmd(InstanceID_t id, SmlCopyPtr_t pContent) { return mgrCreateNextCommand(id, SML_PE_COPY, pContent); } #endif /** * Create a Move Command * * @param id (IN) * ID of the used instance * @param pContent (IN) * Data to pass along with that SyncML command * @return Return Code */ SML_API Ret_t smlMoveCmd(InstanceID_t id, SmlMovePtr_t pContent) { return mgrCreateNextCommand(id, SML_PE_MOVE, pContent); } #ifdef EXEC_SEND /** * Create a Exec Command * * @param id (IN) * ID of the used instance * @param pContent (IN) * Data to pass along with that SyncML command * @return Return Code */ SML_API Ret_t smlExecCmd(InstanceID_t id, SmlExecPtr_t pContent) { return mgrCreateNextCommand(id, SML_PE_EXEC, pContent); } #endif #ifdef SEARCH_SEND /** * Create a Search Command * * @param id (IN) * ID of the used instance * @param pContent (IN) * Data to pass along with that SyncML command * @return Return Code */ SML_API Ret_t smlSearchCmd(InstanceID_t id, SmlSearchPtr_t pContent) { return mgrCreateNextCommand(id, SML_PE_SEARCH, pContent); } #endif /************************************************************************* * Exported SyncML API functions (FULL-SIZE TOOLKIT ONLY) *************************************************************************/ #ifndef __SML_LITE__ /* these API calls are NOT included in the Toolkit lite version */ /** * Starts an evaluation run which prevents further API-Calls to write tags - * just the tag-sizes are calculated. Must be sopped via smlEndEvaluation * * @param id (IN) * ID of the used instance * @return Return Code */ SML_API Ret_t smlStartEvaluation(InstanceID_t id) { InstanceInfoPtr_t pInstanceInfo; // pointer the the instance info structure for this id Ret_t rc; #ifdef NOWSM pInstanceInfo = (InstanceInfoPtr_t)id; // ID is the instance info pointer #else /* --- Retrieve the corresponding instanceInfo structure --- */ #ifdef __SML_LITE__ /* Only ONE instance is supported in the Toolkit lite version */ pInstanceInfo = mgrGetInstanceListAnchor(); #else pInstanceInfo = (InstanceInfoPtr_t) findInfo(id); #endif #endif if (pInstanceInfo==NULL) return SML_ERR_MGR_INVALID_INSTANCE_INFO; /* --- Initialize Encoder for evaluation mode --- */ rc = xltStartEvaluation((XltEncoderPtr_t)(pInstanceInfo->encoderState)); return rc; } /** * Stops an evaluation run which prevents further API-Calls to write tags - * the remaining free buffer size after all Tags are written is returned * * @param id (IN) * ID of the used instance * @param freemem (IN/OUT) * Size of free buffer for data after all tags are written * @return Return Code */ SML_API Ret_t smlEndEvaluation(InstanceID_t id, MemSize_t *freemem) { InstanceInfoPtr_t pInstanceInfo; // pointer the the instance info structure for this id Ret_t rc; #ifdef NOWSM pInstanceInfo = (InstanceInfoPtr_t)id; // ID is the instance info pointer #else /* --- Retrieve the corresponding instanceInfo structure --- */ #ifdef __SML_LITE__ /* Only ONE instance is supported in the Toolkit lite version */ pInstanceInfo = mgrGetInstanceListAnchor(); #else pInstanceInfo = (InstanceInfoPtr_t) findInfo(id); #endif #endif if (pInstanceInfo==NULL) return SML_ERR_MGR_INVALID_INSTANCE_INFO; // %%% luz 2002-09-03: encoder can be null here if fatal error occurred before if (pInstanceInfo->encoderState==NULL) return SML_ERR_WRONG_USAGE; rc = xltEndEvaluation(id, (XltEncoderPtr_t)(pInstanceInfo->encoderState), freemem); return rc; } #endif /************************************************************************* * Private Functions *************************************************************************/ /** * Calls the encoding routines of the Encoder Module for a given Command Type * and Command Content * * @param id (IN) * ID of the Instance * @param cmdType (IN) * Type of the command (defined by the Proto Element Enumeration) * @param pContent (IN) * Content of the command to encode * @return Return value,\n * SML_ERR_OK if command has been encoded successfully */ static Ret_t mgrCreateNextCommand(InstanceID_t id, SmlProtoElement_t cmdType, VoidPtr_t pContent) { /* --- Definitions --- */ InstanceInfoPtr_t pInstanceInfo; // pointer the the instance info structure for this id Ret_t rc; MemPtr_t pCurrentWritePosition; // current Position from to which to write MemPtr_t pBeginPosition; // saves the first position which has been written MemSize_t freeSize; // size of free memory for writing #ifdef NOWSM pInstanceInfo = (InstanceInfoPtr_t)id; // ID is the instance info pointer #else /* --- Retrieve the corresponding instanceInfo structure --- */ #ifdef __SML_LITE__ /* Only ONE instance is supported in the Toolkit lite version */ pInstanceInfo = mgrGetInstanceListAnchor(); #else pInstanceInfo = (InstanceInfoPtr_t) findInfo(id); #endif #endif if (pInstanceInfo==NULL) return SML_ERR_MGR_INVALID_INSTANCE_INFO; // %%% luz 2002-11-27: added NULL check as previously failed encoding will delete encoder if (pInstanceInfo->encoderState==NULL) return SML_ERR_MGR_INVALID_INSTANCE_INFO; /* --- Get Write Access to the workspace --- */ rc = smlLockWriteBuffer(id, &pCurrentWritePosition, &freeSize); if (rc!=SML_ERR_OK) { // abort, unlock the buffer again without changing it's current position smlUnlockWriteBuffer(id, (MemSize_t)0); return rc; } // Remember the position we have started writing pBeginPosition=pCurrentWritePosition; /* --- Call the encoder module --- */ rc = xltEncAppend(pInstanceInfo->encoderState, cmdType, pCurrentWritePosition+freeSize, pContent, &pCurrentWritePosition); if (rc!=SML_ERR_OK) { /* check for full buffer and call TransmitChunk */ if (rc == SML_ERR_XLT_BUF_ERR) { // first check wether callback is defined if (pInstanceInfo->callbacks->transmitChunkFunc!= NULL) { // abort, unlock the buffer again without changing it's current position smlUnlockWriteBuffer(id, (MemSize_t)0); // call the callback pInstanceInfo->callbacks->transmitChunkFunc(id,NULL); // lock -> returns the amount of free buffer space smlLockWriteBuffer(id, &pCurrentWritePosition, &freeSize); pBeginPosition = pCurrentWritePosition; // now try again to encode and see wether we now have enough mem available rc = xltEncAppend(pInstanceInfo->encoderState, cmdType, pCurrentWritePosition+freeSize, pContent, &pCurrentWritePosition); // if rc == SML_ERR_OK continue else // return the errorcode if( rc != SML_ERR_OK) { smlUnlockWriteBuffer(id, (MemSize_t)0); // Reset the encoder module (free the encoding object) xltEncReset(pInstanceInfo->encoderState); // this encoding job is over! reset instanceInfo pointer pInstanceInfo->encoderState=NULL; return rc; } } } else { // abort, unlock the buffer again without changing it's current position smlUnlockWriteBuffer(id, (MemSize_t)0); // Reset the encoder module (free the encoding object) xltEncReset(pInstanceInfo->encoderState); // this encoding job is over! reset instanceInfo pointer pInstanceInfo->encoderState=NULL; return rc; } } /* --- End Write Access to the workspace --- */ rc = smlUnlockWriteBuffer(id, (MemSize_t)pCurrentWritePosition-(MemSize_t)pBeginPosition); return rc; } /* eof */ libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/mgr/all/mgrcmddispatcher.c000077500000000000000000000456471226375725500260640ustar00rootroot00000000000000/** * @file * SyncML Command Dispatcher * * @target_system all * @target_os all * @description Core module for dispatching parsed commands and invoking * callback functions of the application */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ /************************************************************************* * Definitions *************************************************************************/ #include "syncml_tk_prefix_file.h" // %%% luz: needed for precompiled headers in eVC++ #include "define.h" /* Include Headers */ #include "smldef.h" #include "smldtd.h" #include "smlerr.h" #include "libmem.h" #include "xltdec.h" #include "mgr.h" /* Used external functions */ #ifndef __SML_LITE__ /* these API calls are NOT included in the Toolkit lite version */ extern Ret_t addInfo(InstanceInfoPtr_t pInfo); extern InstanceInfoPtr_t findInfo(InstanceID_t id); extern Ret_t removeInfo(InstanceID_t id); #endif Ret_t smlLockReadBuffer(InstanceID_t id, MemPtr_t *pReadPosition, MemSize_t *usedSize); Ret_t smlUnlockReadBuffer(InstanceID_t id, MemSize_t processedBytes); /* Prototypes of exported SyncML API functions */ extern Ret_t smlProcessData(InstanceID_t id, SmlProcessMode_t mode); /* Private function prototypes */ static Ret_t mgrProcessNextCommand(InstanceID_t id, InstanceInfoPtr_t pInstanceInfo); static Ret_t mgrProcessStartMessage(InstanceID_t id, InstanceInfoPtr_t pInstanceInfo); Ret_t mgrResetWorkspace (InstanceID_t id); /************************************************************************* * Exported SyncML API functions *************************************************************************/ /** * Start the parsing of the XML code in the workspace buffer, * dispatches the interpreted command and calls the corresponding callback * functions provided by the application. * * @param id (IN) * The SyncML instance id is used for referencing the * workspace buffer from the XML content is parsed * @param mode (IN) * Mode of processing, Defines, if only the first or next * XML command is parsed or if all commands are processed * subsequently until the end of the entire workspace buffer * is reached. The NEXT_COMMAND flag defines the blocking mode, * the ALL_COMMANDS tag defines the non-blocking mode. * @return Return Code */ SML_API Ret_t smlProcessData(InstanceID_t id, SmlProcessMode_t mode) { /* --- Definitions --- */ InstanceInfoPtr_t pInstanceInfo; // state info for the given instanceID Ret_t rc; // Temporary return code saver #ifdef NOWSM pInstanceInfo = (InstanceInfoPtr_t)id; // ID is the instance info pointer #else /* --- Find that instance --- */ #ifdef __SML_LITE__ /* Only ONE instance is supported in the Toolkit lite version */ pInstanceInfo = mgrGetInstanceListAnchor(); #else pInstanceInfo = (InstanceInfoPtr_t) findInfo(id); #endif #endif if (pInstanceInfo==NULL) return SML_ERR_MGR_INVALID_INSTANCE_INFO; /* --- Are callback functions defined? --- */ if (pInstanceInfo->callbacks==NULL) return SML_ERR_COMMAND_NOT_HANDLED; /* --- Is parsing already in progress? --- */ if (pInstanceInfo->decoderState==NULL) { /* No! Parse the Message header section first */ rc = mgrProcessStartMessage(id, pInstanceInfo); if (rc!=SML_ERR_OK) return rc; } /* --- Parse now the Message body section! --- */ do { rc=mgrProcessNextCommand(id, pInstanceInfo); } while ( // keep processing while no error occurs, // AND the document end was not reached (decoderState has been invalidated), // AND the ALL_COMMAND mode is used (rc==SML_ERR_OK) &&((pInstanceInfo->decoderState)!=NULL) &&(mode==SML_ALL_COMMANDS) ); if (rc != SML_ERR_OK) { // abort, unlock the buffer again without changing it's current position smlUnlockReadBuffer(id, (MemSize_t)0); // Reset the decoder module (free the decoding object) xltDecReset(pInstanceInfo->decoderState); // this decoding job is over! reset Instance Info pointer pInstanceInfo->decoderState=NULL; // Reset the Workspace (the remaining unparsed document fragment will be lost) mgrResetWorkspace(id); } else { // %%%luz 2007-09-11: added SML_ERR_CONTINUE to signal processing of message not // yet complete in NEXT_COMMAND mode (is otherwise not very useful) if ((mode==SML_NEXT_COMMAND) && ((pInstanceInfo->decoderState)!=NULL)) { rc = SML_ERR_CONTINUE; // processing not yet complete } } return rc; } /************************************************************************* * Private Functions *************************************************************************/ /** * Parses the header information at the beginning of an SyncML document. * * @param id (IN) * current InstanceID to pass to callback functions * @param pInstanceInfo (IN/OUT) * state information of the given InstanceID * (decoder state will be changed) * @return Return value of the Parser,\n * SML_ERR_OK if next command was handled successfully */ static Ret_t mgrProcessStartMessage(InstanceID_t id, InstanceInfoPtr_t pInstanceInfo) { /* --- Definitions --- */ Ret_t rc; // Temporary return code saver SmlSyncHdrPtr_t pContent=NULL; // data of the command to process MemPtr_t pCurrentReadPosition ; // current Position from which is read MemPtr_t pBeginPosition; // saves the first position which has been reading MemSize_t usedSize ; // size of used memory to be read /* --- Get Read Access to the workspace --- */ rc = smlLockReadBuffer(id, &pCurrentReadPosition, &usedSize); if (rc!=SML_ERR_OK) { // abort, unlock the buffer again without changing it's current position smlUnlockReadBuffer(id, (MemSize_t)0); return rc; } // Remember the position we have started reading pBeginPosition=pCurrentReadPosition; #ifdef NOWSM // luz 2008-02-08: also remember the position of the first byte of the message to allow dumping it AFTER parsing the header pInstanceInfo->incomingMsgStart = pBeginPosition; #endif /* --- Start new decoding sequence and pass returned decoder status structure to instanceInfo --- */ rc = xltDecInit(pInstanceInfo->instanceOptions->encoding, pCurrentReadPosition+usedSize-1, &pCurrentReadPosition, (XltDecoderPtr_t *)&(pInstanceInfo->decoderState), &pContent); if (rc!=SML_ERR_OK) { // abort, unlock the buffer again without changing it's current position smlUnlockReadBuffer(id, (MemSize_t)0); // Reset the decoder module (free the decoding object) xltDecReset(pInstanceInfo->decoderState); // this decoding job is over! reset Instance Info pointer pInstanceInfo->decoderState=NULL; // Reset the Workspace (the remaining unparsed document fragment will be lost) mgrResetWorkspace(id); return rc; } /* --- End Read Access to the workspace --- */ rc = smlUnlockReadBuffer(id, (MemSize_t)pCurrentReadPosition-(MemSize_t)pBeginPosition); if (rc!=SML_ERR_OK) return rc; /* --- Perform callback to handle the beginning of a new message --- */ if (pInstanceInfo->callbacks->startMessageFunc==NULL) return SML_ERR_COMMAND_NOT_HANDLED; rc=pInstanceInfo->callbacks->startMessageFunc(id, pInstanceInfo->userData, pContent); if (rc != SML_ERR_OK) { // abort, unlock the buffer again without changing it's current position smlUnlockReadBuffer(id, (MemSize_t)0); // Reset the decoder module (free the decoding object) xltDecReset(pInstanceInfo->decoderState); // this decoding job is over! reset Instance Info pointer pInstanceInfo->decoderState=NULL; // Reset the Workspace (the remaining unparsed document fragment will be lost) mgrResetWorkspace(id); } return rc; } /** * Parses the next Sync Command in the sync document. * * @param id (IN) * current InstanceID to pass to callback functions * @param pInstanceInfo (IN) * state information of the given InstanceID * @return Return value of the Parser of the called application callback,\n * SML_ERR_OK if next command was handled successfully */ static Ret_t mgrProcessNextCommand(InstanceID_t id, InstanceInfoPtr_t pInstanceInfo) { /* --- Definitions --- */ Ret_t rc; // Temporary return code saver SmlProtoElement_t cmdType; // ID of the command to process VoidPtr_t pContent=NULL; // data of the command to process MemPtr_t pCurrentReadPosition; // current Position from which is read MemPtr_t pBeginPosition; // saves the first position which has been reading MemSize_t usedSize; // size of used memory to be read Boolean_t final; // flag indicates last message within a package /* --- Get Read Access to the workspace --- */ rc = smlLockReadBuffer(id, &pCurrentReadPosition, &usedSize); if (rc!=SML_ERR_OK) { // abort, unlock the buffer again without changing it's current position smlUnlockReadBuffer(id, (MemSize_t)0); return rc; } // Remember the position we have started reading pBeginPosition=pCurrentReadPosition; /* --- Parse next Command --- */ rc = xltDecNext(pInstanceInfo->decoderState, pCurrentReadPosition+usedSize, &pCurrentReadPosition, &cmdType, &pContent); if (rc!=SML_ERR_OK) { // abort, unlock the buffer again without changing it's current position smlUnlockReadBuffer(id, (MemSize_t)0); // Reset the decoder module (free the decoding object) xltDecReset(pInstanceInfo->decoderState); // this decoding job is over! reset Instance Info pointer pInstanceInfo->decoderState=NULL; // Reset the Workspace (the remaining unparsed document fragment will be lost) mgrResetWorkspace(id); return rc; } /* --- End Read Access to the workspace --- */ rc = smlUnlockReadBuffer(id, (MemSize_t)pCurrentReadPosition-(MemSize_t)pBeginPosition); if (rc!=SML_ERR_OK) { // abort, unlock the buffer again without changing it's current position smlUnlockReadBuffer(id, (MemSize_t)0); return rc; } /* --- Did we reach end of synchronization document? --- */ if (((XltDecoderPtr_t)(pInstanceInfo->decoderState))->finished!=0) { final = ((XltDecoderPtr_t)(pInstanceInfo->decoderState))->final; // flag is returned to appl. with callback rc=xltDecTerminate(pInstanceInfo->decoderState); if (rc!=SML_ERR_OK) { // abort, unlock the buffer again without changing it's current position smlUnlockReadBuffer(id, (MemSize_t)0); // Reset the decoder module (free the decoding object) xltDecReset(pInstanceInfo->decoderState); // this decoding job is over! reset Instance Info pointer pInstanceInfo->decoderState=NULL; // Reset the Workspace (the remaining unparsed document fragment will be lost) mgrResetWorkspace(id); return rc; } // this decoding job is over! reset Instance Info pointer // (the decoding object itself has been freed by the decoder) pInstanceInfo->decoderState=NULL; // Call the callback for handling an message ending if (pInstanceInfo->callbacks->endMessageFunc==NULL) return SML_ERR_COMMAND_NOT_HANDLED; rc=pInstanceInfo->callbacks->endMessageFunc(id, pInstanceInfo->userData, final); return rc; } /* --- Dispatch parsed command (and call the applications command handler function)--- */ switch (cmdType) { /* Handle ADD Command */ case SML_PE_ADD: if (pInstanceInfo->callbacks->addCmdFunc==NULL) return SML_ERR_COMMAND_NOT_HANDLED; return pInstanceInfo->callbacks->addCmdFunc (id, pInstanceInfo->userData, pContent); break; /* Handle ALERT Command */ case SML_PE_ALERT: if (pInstanceInfo->callbacks->alertCmdFunc==NULL) return SML_ERR_COMMAND_NOT_HANDLED; return pInstanceInfo->callbacks->alertCmdFunc (id, pInstanceInfo->userData, pContent); break; /* Handle DELETE Command */ case SML_PE_DELETE: if (pInstanceInfo->callbacks->deleteCmdFunc==NULL) return SML_ERR_COMMAND_NOT_HANDLED; return pInstanceInfo->callbacks->deleteCmdFunc (id, pInstanceInfo->userData, pContent); break; /* Handle PUT Command */ case SML_PE_PUT: if (pInstanceInfo->callbacks->putCmdFunc==NULL) return SML_ERR_COMMAND_NOT_HANDLED; return pInstanceInfo->callbacks->putCmdFunc (id, pInstanceInfo->userData, pContent); break; /* Handle GET Command */ case SML_PE_GET: if (pInstanceInfo->callbacks->getCmdFunc==NULL) return SML_ERR_COMMAND_NOT_HANDLED; return pInstanceInfo->callbacks->getCmdFunc (id, pInstanceInfo->userData, pContent); break; #ifdef MAP_RECEIVE /* Handle MAP Command */ case SML_PE_MAP: if (pInstanceInfo->callbacks->mapCmdFunc==NULL) return SML_ERR_COMMAND_NOT_HANDLED; return pInstanceInfo->callbacks->mapCmdFunc (id, pInstanceInfo->userData, pContent); break; #endif #ifdef RESULT_RECEIVE /* Handle RESULTS Command */ case SML_PE_RESULTS: if (pInstanceInfo->callbacks->resultsCmdFunc==NULL) return SML_ERR_COMMAND_NOT_HANDLED; return pInstanceInfo->callbacks->resultsCmdFunc (id, pInstanceInfo->userData, pContent); break; #endif /* Handle STATUS Command */ case SML_PE_STATUS: if (pInstanceInfo->callbacks->statusCmdFunc==NULL) return SML_ERR_COMMAND_NOT_HANDLED; return pInstanceInfo->callbacks->statusCmdFunc (id, pInstanceInfo->userData, pContent); break; /* Handle START SYNC Command */ case SML_PE_SYNC_START: if (pInstanceInfo->callbacks->startSyncFunc==NULL) return SML_ERR_COMMAND_NOT_HANDLED; return pInstanceInfo->callbacks->startSyncFunc (id, pInstanceInfo->userData, pContent); break; /* Handle END SYNC Command */ case SML_PE_SYNC_END: if (pInstanceInfo->callbacks->endSyncFunc==NULL) return SML_ERR_COMMAND_NOT_HANDLED; return pInstanceInfo->callbacks->endSyncFunc (id, pInstanceInfo->userData); break; /* Handle REPLACE Command */ case SML_PE_REPLACE: if (pInstanceInfo->callbacks->replaceCmdFunc==NULL) return SML_ERR_COMMAND_NOT_HANDLED; return pInstanceInfo->callbacks->replaceCmdFunc (id, pInstanceInfo->userData, pContent); break; /* Handle Final Flag */ case SML_PE_FINAL: // if a FINAL Flag appears do nothing return SML_ERR_OK; break; #ifdef SEARCH_RECEIVE /* these API calls are NOT included in the Toolkit lite version */ /* Handle SEARCH Command */ case SML_PE_SEARCH: if (pInstanceInfo->callbacks->searchCmdFunc==NULL) return SML_ERR_COMMAND_NOT_HANDLED; return pInstanceInfo->callbacks->searchCmdFunc (id, pInstanceInfo->userData, pContent); break; #endif #ifdef SEQUENCE_RECEIVE /* Handle START SEQUENCE Command */ case SML_PE_SEQUENCE_START: if (pInstanceInfo->callbacks->startSequenceFunc==NULL) return SML_ERR_COMMAND_NOT_HANDLED; return pInstanceInfo->callbacks->startSequenceFunc (id, pInstanceInfo->userData, pContent); break; /* Handle END SEQUENCE Command */ case SML_PE_SEQUENCE_END: if (pInstanceInfo->callbacks->endSequenceFunc==NULL) return SML_ERR_COMMAND_NOT_HANDLED; return pInstanceInfo->callbacks->endSequenceFunc (id, pInstanceInfo->userData); break; #endif #ifdef ATOMIC_RECEIVE /* Handle START ATOMIC Command */ case SML_PE_ATOMIC_START: if (pInstanceInfo->callbacks->startAtomicFunc==NULL) return SML_ERR_COMMAND_NOT_HANDLED; return pInstanceInfo->callbacks->startAtomicFunc (id, pInstanceInfo->userData, pContent); break; /* Handle END ATOMIC Command */ case SML_PE_ATOMIC_END: if (pInstanceInfo->callbacks->endAtomicFunc==NULL) return SML_ERR_COMMAND_NOT_HANDLED; return pInstanceInfo->callbacks->endAtomicFunc (id, pInstanceInfo->userData); break; #endif #ifdef COPY_RECEIVE /* Handle COPY Command */ case SML_PE_COPY: if (pInstanceInfo->callbacks->copyCmdFunc==NULL) return SML_ERR_COMMAND_NOT_HANDLED; return pInstanceInfo->callbacks->copyCmdFunc (id, pInstanceInfo->userData, pContent); break; #endif /* Handle MOVE Command */ case SML_PE_MOVE: if (pInstanceInfo->callbacks->moveCmdFunc==NULL) return SML_ERR_COMMAND_NOT_HANDLED; return pInstanceInfo->callbacks->moveCmdFunc (id, pInstanceInfo->userData, pContent); break; #ifdef EXEC_RECEIVE /* Handle EXEC Command */ case SML_PE_EXEC: if (pInstanceInfo->callbacks->execCmdFunc==NULL) return SML_ERR_COMMAND_NOT_HANDLED; return pInstanceInfo->callbacks->execCmdFunc (id, pInstanceInfo->userData, pContent); break; #endif /* Handle ERROR DETECTED */ //case SML_PE_ERROR: // if (pInstanceInfo->callbacks->handleErrorFunc==NULL) return SML_ERR_COMMAND_NOT_HANDLED; // return pInstanceInfo->callbacks->handleErrorFunc (id, pInstanceInfo->userData); // break; /* --- Invalid Command Element --- */ default: return SML_ERR_XLT_INVAL_PROTO_ELEM; break; } // switch } /* eof */ libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/mgr/all/mgrinstancelist.c000077500000000000000000000150311226375725500257320ustar00rootroot00000000000000/** * @file * List of SyncML Instances * * @target_system all * @target_os all * @description This module handles an element list of type InstanceInfo. Each * element is identified by the InstanceID. There are functions provided * to add, find and remove InstanceInfo elements. * This file is private to the core module. The InstanceInfo list is * used by the Modules MGR, MGRCmdDispatcher, MGRCmdBuilder * and MGRInstanceMgr. */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ /************************************************************************* * Definitions *************************************************************************/ #include "syncml_tk_prefix_file.h" // %%% luz: needed for precompiled headers in eVC++ /* Include Headers */ #include #include "libmem.h" #include "liblock.h" #include "mgr.h" #ifndef __SML_LITE__ /* Only ONE instance is supported in the Toolkit lite version */ #ifndef NOWSM /* only need if we are using workspace manager */ /* Used external functions */ SyncMLInfoPtr_t mgrGetSyncMLAnchor(void); InstanceInfoPtr_t mgrGetInstanceListAnchor(void); void mgrSetInstanceListAnchor(InstanceInfoPtr_t newListAnchor); /* SyncML internal function prototypes */ Ret_t addInfo(InstanceInfoPtr_t pInfo); InstanceInfoPtr_t findInfo(InstanceID_t id); Ret_t removeInfo(InstanceID_t id); /* Private function prototypes */ /************************************************************************* * SyncML internal functions *************************************************************************/ /** * Adds a new element to the list * * @param pInfo (IN) * pointer to the structure to be be added to list * @return Return value,\n * SML_ERR_OK if element was added successfully */ Ret_t addInfo(InstanceInfoPtr_t pInfo) { if (pInfo!=NULL) { InstanceInfoPtr_t _pTmp; LOCKTOOLKIT("addInfo"); /* Remember old beginning of the list */ _pTmp=mgrGetInstanceListAnchor(); /* insert element immediately after anchor */ mgrSetInstanceListAnchor(pInfo); // anchor of list points now to new info element pInfo->nextInfo=_pTmp; // Next info element is the prior first one. RELEASETOOLKIT("addInfo"); return SML_ERR_OK; } else { // Invalid InstanceInfo pointer was used (NULL) return SML_ERR_MGR_INVALID_INSTANCE_INFO; } } /** * Searches an element with the given InstanceID in the list * * @param id (IN) * ID of the InstanceInfo structure to be retrieved * @return Pointer to the InstanceInfo structure with the given ID\n * NULL, if no InstanceInfo with the given ID has been found */ InstanceInfoPtr_t findInfo(InstanceID_t id) { InstanceInfoPtr_t _pTmp; // A helper pointer /* go through the list until end */ LOCKTOOLKIT("findInfo"); for (_pTmp=mgrGetInstanceListAnchor(); _pTmp!=NULL; _pTmp=_pTmp->nextInfo) { if (_pTmp->id == id) { RELEASETOOLKIT("findInfo"); return _pTmp; // STOP, we've found the info, return! } } RELEASETOOLKIT("findInfo"); return NULL; // Info was not found, return NULL } /** * Removes an element with the given InstanceID from the list * * @param id (IN) * ID of the InstanceInfo structure to be removed * @return Return value,\n * SML_ERR_OK if element was removed successfully */ Ret_t removeInfo(InstanceID_t id) { InstanceInfoPtr_t _pTmp; // A helper pointer InstanceInfoPtr_t _pRemember; // A helper pointer LOCKTOOLKIT("removeInfo"); /* Remember current anchor */ _pRemember=mgrGetInstanceListAnchor(); /* special check, if list is empty */ if (_pRemember==NULL ) { RELEASETOOLKIT("removeInfo"); return SML_ERR_MGR_INVALID_INSTANCE_INFO; } /* special check, if first element should be removed */ if (_pRemember->id == id) { // It's the first element, update anchor! mgrSetInstanceListAnchor(_pRemember->nextInfo); //freeInfo(_pRemember); // Delete structure, free memory RELEASETOOLKIT("removeInfo"); return SML_ERR_OK; // return } /* go through the list until end */ for (_pTmp=_pRemember->nextInfo; _pTmp!=NULL; _pTmp=_pTmp->nextInfo) { if (_pTmp->id == id) // STOP, we've found the info { _pRemember->nextInfo=_pTmp->nextInfo; //freeInfo(_pTmp); // Delete structure, free memory RELEASETOOLKIT("removeInfo"); return SML_ERR_OK; // return } else { _pRemember=_pTmp; // update helper pointer } } RELEASETOOLKIT("removeInfo"); return SML_ERR_MGR_INVALID_INSTANCE_INFO; // Info wasn't found } #endif // !defined(NOWSM) #endif libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/mgr/all/mgrinstancemgr.c000077500000000000000000001102521226375725500255450ustar00rootroot00000000000000/** * @file * Managing SyncML Instances * * @target_system all * @target_os all * @description Core module for managing creation and usage of instances */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ /************************************************************************* * Definitions *************************************************************************/ #include "syncml_tk_prefix_file.h" // %%% luz: needed for precompiled headers in eVC++ /* Include Headers */ #include #include #include #include "libmem.h" #include "libstr.h" #include "liblock.h" #include "wsm.h" #include "mgr.h" #include /* Used external functions */ #ifndef NOWSM #ifndef __SML_LITE__ /* Only ONE instance is supported in the Toolkit lite version */ extern Ret_t addInfo(InstanceInfoPtr_t pInfo); extern InstanceInfoPtr_t findInfo(InstanceID_t id); extern Ret_t removeInfo(InstanceID_t id); #endif SyncMLInfoPtr_t mgrGetSyncMLAnchor(void); #endif /* Prototypes of exported SyncML API functions */ SML_API Ret_t smlInitInstance(SmlCallbacksCPtr_t callbacks, SmlInstanceOptionsPtr_t pOptions, VoidPtr_t pUserData, InstanceID_t *pInstanceID); SML_API Ret_t smlTerminateInstance (InstanceID_t id); SML_API Ret_t smlLockReadBuffer(InstanceID_t id, MemPtr_t *pReadPosition, MemSize_t *usedSize); SML_API Ret_t smlUnlockReadBuffer(InstanceID_t id, MemSize_t processedBytes); #ifdef NOWSM SML_API Ret_t smlSetMaxOutgoingSize(InstanceID_t id, MemSize_t maxOutgoingSize); SML_API Ret_t smlSetOutgoingBegin(InstanceID_t id); #endif SML_API Ret_t smlLockWriteBuffer(InstanceID_t id, MemPtr_t *pWritePosition, MemSize_t *freeSize); SML_API Ret_t smlUnlockWriteBuffer(InstanceID_t id, MemSize_t writtenBytes); SML_API Ret_t smlSetCallbacks (InstanceID_t id, SmlCallbacksCPtr_t pCallbacks); SML_API Ret_t smlSetUserData (InstanceID_t id, VoidPtr_t pUserData); // added by luz %%%: SML_API Ret_t smlGetUserData(InstanceID_t id, VoidPtr_t *ppUserData); SML_API Ret_t smlGetEncoding(InstanceID_t id, SmlEncoding_t *pEncoding); #ifndef __SML_LITE__ /* these API calls are NOT included in the Toolkit lite version */ SML_API Ret_t smlSetEncoding (InstanceID_t id, SmlEncoding_t encoding); #endif /* Private function prototypes */ Ret_t freeInstanceOptions (InstanceInfoPtr_t pInstanceInfo); static Ret_t freeInstanceInfo (InstanceInfoPtr_t pInfo); Ret_t mgrResetWorkspace (InstanceID_t id); Ret_t setInstanceOptions (InstanceID_t id, SmlInstanceOptionsPtr_t pOptions); /************************************************************************* * Public SyncML API Functions *************************************************************************/ /** * Creates a SyncML instance and assigns a corresponding workspace buffer in * which XML documents are assembled or parsed. * All callback functions implemented by a particular application are defined. * Instance specific options can be passed. This function has to be called * before the first synchronization tasks can be performed. A reference valid * for a SyncML instance is returned. * An instance is active when processing a synchronization request * otherwise it is idle. An instance is terminated when smlTerminateInstance * is called. * * @param pCallbacks (IN) * A structure holding references to the callback functions * implemented by the application * @param pOptions (IN) * Option settings of a particular SyncML instance * @param pUserData (IN) * UserData is a pointer to a void structure the application * can pass into the SyncML Toolkit instance info. It will * be returned to the application with every called callback * function call!\n * NOTE: This is only a pointer, the memory object itself * remains within the responsibility of the calling application. * The memory object will not be copied, moved or freed by the Toolkit. * @param pInstanceID (OUT) * Instance ID assigned to the initialized instance * @return Error Code */ SML_API Ret_t smlInitInstance(SmlCallbacksCPtr_t pCallbacks, SmlInstanceOptionsPtr_t pOptions, VoidPtr_t pUserData, InstanceID_t *pInstanceID) { /* --- Definitions --- */ InstanceInfoPtr_t pInstanceInfo; Ret_t rc; #ifndef NOWSM /* --- Check pOptions, which have been passed by the application --- */ if (!pOptions || !pOptions->workspaceName) return SML_ERR_WRONG_USAGE; #ifdef __SML_LITE__ /* Only ONE instance is supported in the Toolkit lite version */ /* if ONE instance is already initialized */ if (mgrGetInstanceListAnchor()!=NULL) return SML_ERR_WRONG_USAGE; #endif /* --- check wether we already know about this instance --- */ #ifdef __SML_LITE__ /* Only ONE instance is supported in the Toolkit lite version */ pInstanceInfo = mgrGetInstanceListAnchor(); #else pInstanceInfo = (InstanceInfoPtr_t) findInfo(*pInstanceID); #endif /* --- bail outh when we already have a instance with that id --- */ if (pInstanceInfo != NULL) return SML_ERR_WRONG_USAGE; /* --- Create a workspace for this instance --- */ LOCKTOOLKIT("smlInitInstance"); if ((rc = wsmCreate(pOptions->workspaceName, pOptions->workspaceSize, pInstanceID)) != SML_ERR_OK) { RELEASETOOLKIT("smlInitInstance after wsmCreate failure"); return rc; } RELEASETOOLKIT("smlInitInstance"); #else // NOWSM /* --- Check pOptions, which have been passed by the application --- */ if (!pOptions || !pOptions->workspaceSize) return SML_ERR_WRONG_USAGE; // ok so far rc=SML_ERR_OK; #endif /* --- Create an instance info memory object --- */ pInstanceInfo = (InstanceInfoPtr_t)smlLibMalloc((MemSize_t)sizeof(InstanceInfo_t)); if (pInstanceInfo==NULL) { #ifndef NOWSM wsmDestroy(pOptions->workspaceName); return SML_ERR_NOT_ENOUGH_SPACE; #endif } #ifdef NOWSM else { // instance info created, return pointer as instanceID *pInstanceID = (InstanceID_t)pInstanceInfo; } #endif smlLibMemset(pInstanceInfo,0,(MemSize_t)sizeof(InstanceInfo_t)); /* --- Set mandatory instance infos for this instance to defaults --- */ pInstanceInfo->status=MGR_IDLE; pInstanceInfo->encoderState=NULL; // no encoding in progress, currently not used pInstanceInfo->decoderState=NULL; // no decoding in progress, currently not used #ifndef NOWSM pInstanceInfo->id=*pInstanceID; pInstanceInfo->workspaceState=NULL; // to do: some workspace status info pInstanceInfo->nextInfo=NULL; #else // create a instance buffer pInstanceInfo->instanceBufSiz=pOptions->workspaceSize; // get requested size for the buffer pInstanceInfo->maxOutgoingSize=pOptions->maxOutgoingSize; // set max outgoing message size pInstanceInfo->instanceBuffer=smlLibMalloc(pInstanceInfo->instanceBufSiz); if (pInstanceInfo->instanceBuffer==NULL) return SML_ERR_NOT_ENOUGH_SPACE; // init buffer pointers pInstanceInfo->readPointer=pInstanceInfo->instanceBuffer; pInstanceInfo->writePointer=pInstanceInfo->instanceBuffer; pInstanceInfo->readLocked=0; pInstanceInfo->writeLocked=0; pInstanceInfo->outgoingMsgStart=NULL; pInstanceInfo->incomingMsgStart=NULL; #endif #ifndef NOWSM /* --- Add instance infos memory object to the instance info list --- */ #ifdef __SML_LITE__ /* Only ONE instance is supported in the Toolkit lite version */ mgrSetInstanceListAnchor(pInstanceInfo); #else rc = addInfo( pInstanceInfo ); if (rc!=SML_ERR_OK) return rc; #endif #endif /* --- Set the values of instance Infos as defined by the calling application ---*/ /* Set user data pointer */ pInstanceInfo->userData=pUserData; /* Set callback functions implemented by applications */ if (smlSetCallbacks(*pInstanceID, pCallbacks) != SML_ERR_OK) { #ifndef NOWSM wsmDestroy(pOptions->workspaceName); #endif return rc; } // luz: %%% this was called twice, probably this is a bug, so I disabled the second call //smlSetCallbacks(*pInstanceID, pCallbacks); /* Set other application defined options for that instance */ if (setInstanceOptions (*pInstanceID, pOptions) != SML_ERR_OK) { #ifndef NOWSM wsmDestroy(pOptions->workspaceName); #endif return rc; } return SML_ERR_OK; } /** * Terminates a SyncML instance. The instance info is removed from the instances * list. Allmemory allocated for the workspace and the options variables is * freed. * * @param id (IN) * ID of the instance to be terminated * @return Error Code */ SML_API Ret_t smlTerminateInstance (InstanceID_t id) { /* --- Definitions --- */ InstanceInfoPtr_t pInstanceInfo; #ifdef NOWSM pInstanceInfo = (InstanceInfoPtr_t)id; // ID is the instance info pointer #else Ret_t rc; /* --- Find that instance --- */ #ifdef __SML_LITE__ /* Only ONE instance is supported in the Toolkit lite version */ pInstanceInfo = mgrGetInstanceListAnchor(); #else pInstanceInfo = (InstanceInfoPtr_t) findInfo(id); #endif #endif if (pInstanceInfo==NULL) return SML_ERR_MGR_INVALID_INSTANCE_INFO; #ifndef NOWSM /* --- Close the workspace --- */ if (pInstanceInfo->instanceOptions != NULL) { LOCKTOOLKIT("smlTerminateInstance"); rc = wsmDestroy(pInstanceInfo->instanceOptions->workspaceName); RELEASETOOLKIT("smlTerminateInstance"); if (rc!=SML_ERR_OK) { // freeInstanceInfo(pInstanceInfo); return rc; } } /* --- Delete instance info and options --- */ #ifdef __SML_LITE__ /* Only ONE instance is supported in the Toolkit lite version */ mgrSetInstanceListAnchor(NULL); #else removeInfo(id); #endif #endif freeInstanceInfo (pInstanceInfo); return SML_ERR_OK; } /** * Sets new callback functions to an instance * * @param id (IN) * ID of the Instance * @param pCallbacks (IN) * A structure holding references to the callback functions * implemented by the application * @return Return value,\n * SML_ERR_OK if successful */ SML_API Ret_t smlSetCallbacks(InstanceID_t id, SmlCallbacksCPtr_t pCallbacks) { /* --- Definitions --- */ InstanceInfoPtr_t pInstanceInfo; SmlCallbacksPtr_t pCallbacksCopy; /* --- Check pCallbacks, which have been passed by the application --- */ if (!pCallbacks) return SML_ERR_WRONG_USAGE; #ifdef NOWSM pInstanceInfo = (InstanceInfoPtr_t)id; // ID is the instance info pointer #else /* --- Find that instance --- */ #ifdef __SML_LITE__ /* Only ONE instance is supported in the Toolkit lite version */ pInstanceInfo = mgrGetInstanceListAnchor(); #else pInstanceInfo = (InstanceInfoPtr_t) findInfo(id); #endif if (pInstanceInfo==NULL) return SML_ERR_MGR_INVALID_INSTANCE_INFO; #endif /* --- free old callback structure ---*/ smlLibFree(pInstanceInfo->callbacks); /* --- Use a copy of pCallbacksCopy --- */ pCallbacksCopy = (SmlCallbacksPtr_t)smlLibMalloc((MemSize_t)sizeof(SmlCallbacks_t)); if (pCallbacksCopy==NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemcpy(pCallbacksCopy,pCallbacks,(MemSize_t)sizeof(SmlCallbacks_t)); /* --- set new Callbacks --- */ pInstanceInfo->callbacks = pCallbacksCopy; return SML_ERR_OK; } /** * Sets a new Pointer to application specific user data, * which is passed to all invoked callback functions * * @param id (IN) * ID of the Instance * @param pUserData (IN) * UserData is a pointer to a void structure the application * can pass into the SyncML Toolkit instance info. It will * be returned to the application with every called callback * function call!\n * NOTE: This is only a pointer, the memory object itself * remains within the responsibility of the calling application. * The memory object will not be copied, moved or freed by the Toolkit. * @return Return value,\n * SML_ERR_OK if successful */ SML_API Ret_t smlSetUserData(InstanceID_t id, VoidPtr_t pUserData) { /* --- Definitions --- */ InstanceInfoPtr_t pInstanceInfo; #ifdef NOWSM pInstanceInfo = (InstanceInfoPtr_t)id; // ID is the instance info pointer #else /* --- Find that instance --- */ #ifdef __SML_LITE__ /* Only ONE instance is supported in the Toolkit lite version */ pInstanceInfo = mgrGetInstanceListAnchor(); #else pInstanceInfo = (InstanceInfoPtr_t) findInfo(id); #endif #endif if (pInstanceInfo==NULL) return SML_ERR_MGR_INVALID_INSTANCE_INFO; /* --- set new user data pointer ---*/ pInstanceInfo->userData=pUserData; return SML_ERR_OK; } /** * Returns Pointer to application specific user data, * which is passed to all invoked callback functions * * @param id (IN) * ID of the Instance * @param ppUserData (OUT) * Receives current Userdata pointer * @return Return value,\n * SML_ERR_OK if successful * @note (added by luz %%%) */ SML_API Ret_t smlGetUserData(InstanceID_t id, VoidPtr_t *ppUserData) { /* --- Definitions --- */ InstanceInfoPtr_t pInstanceInfo; #ifdef NOWSM pInstanceInfo = (InstanceInfoPtr_t)id; // ID is the instance info pointer #else /* --- Find that instance --- */ #ifdef __SML_LITE__ /* Only ONE instance is supported in the Toolkit lite version */ pInstanceInfo = mgrGetInstanceListAnchor(); #else pInstanceInfo = (InstanceInfoPtr_t) findInfo(id); #endif #endif if (pInstanceInfo==NULL) return SML_ERR_MGR_INVALID_INSTANCE_INFO; /* --- get userdata pointer ---*/ *ppUserData = pInstanceInfo->userData; return SML_ERR_OK; } // smlGetUserData /** * Returns Currently set encoding type * * @param id (IN) * ID of the Instance * @param pEncoding (OUT) * Receives current encoding * @return Return value,\n * SML_ERR_OK if successful * @note (added by luz %%%) */ SML_API Ret_t smlGetEncoding(InstanceID_t id, SmlEncoding_t *pEncoding) { /* --- Definitions --- */ InstanceInfoPtr_t pInstanceInfo; #ifdef NOWSM pInstanceInfo = (InstanceInfoPtr_t)id; // ID is the instance info pointer #else /* --- Find that instance --- */ #ifdef __SML_LITE__ /* Only ONE instance is supported in the Toolkit lite version */ pInstanceInfo = mgrGetInstanceListAnchor(); #else pInstanceInfo = (InstanceInfoPtr_t) findInfo(id); #endif #endif if (pInstanceInfo==NULL) return SML_ERR_MGR_INVALID_INSTANCE_INFO; /* --- get encoding ---*/ *pEncoding = pInstanceInfo->instanceOptions->encoding; return SML_ERR_OK; } // smlGetEncoding /** * Sets new encoding type for this Instance * * @param id (IN) * ID of the Instance * @param encoding (IN) * Type of Encoding to be used within this Instance * @return Return value,\n * SML_ERR_OK if successful */ #ifndef __SML_LITE__ /* these API calls are NOT included in the Toolkit lite version */ SML_API Ret_t smlSetEncoding(InstanceID_t id, SmlEncoding_t encoding) { /* --- Definitions --- */ InstanceInfoPtr_t pInstanceInfo; /* --- Check pCallbacks, which have been passed by the application --- */ if (encoding==SML_UNDEF) return SML_ERR_WRONG_USAGE; #ifdef NOWSM pInstanceInfo = (InstanceInfoPtr_t)id; // ID is the instance info pointer #else /* --- Find that instance --- */ #ifdef __SML_LITE__ /* Only ONE instance is supported in the Toolkit lite version */ pInstanceInfo = mgrGetInstanceListAnchor(); #else pInstanceInfo = (InstanceInfoPtr_t) findInfo(id); #endif #endif if (pInstanceInfo==NULL) return SML_ERR_MGR_INVALID_INSTANCE_INFO; /* --- free old callback structure ---*/ pInstanceInfo->instanceOptions->encoding = encoding; return SML_ERR_OK; } #endif /** * Locks the workspace buffer, which is assigned to the given instance * for reading. After this function is called, the application has * access to the workspace buffer, beginning at the address pReadPosition which * is returned by this function. SyncML will not change the workspace * buffer until smlUnlockReadBuffer is called. * pReadPosition returns a pointer to a valid position in the SyncML workspace * buffer. The pointer can be used by the application for copying outgoing * synchronization data from the buffer into some transport layer. usedSize * retrieves the size of synchronization data currently stored in the * workspace buffer beginning from the address to which pReadPosition points to. * This information is needed by the application when copying XML code out * of the buffer (while sending synchronization data) * * @param id (IN) * ID of the Instance * @param pReadPosition (OUT) * Workspace Pointer from which data can be read * @param usedSize (OUT) * Size of used data in workspace which may be read * @return Return value,\n * SML_ERR_OK if successful */ SML_API Ret_t smlLockReadBuffer(InstanceID_t id, MemPtr_t *pReadPosition, MemSize_t *usedSize) { #ifdef NOWSM InstanceInfoPtr_t pInstanceInfo; pInstanceInfo = (InstanceInfoPtr_t)id; // ID is the instance info pointer if (pInstanceInfo==NULL) return SML_ERR_MGR_INVALID_INSTANCE_INFO; // must not be already locked here if (pInstanceInfo->readLocked) return SML_ERR_WRONG_USAGE; // everything that is already written can also be read *pReadPosition = pInstanceInfo->readPointer; // used portion is what is between read and write pointers *usedSize = pInstanceInfo->writePointer-pInstanceInfo->readPointer; // lock pInstanceInfo->readLocked=1; #else Ret_t rc; LOCKTOOLKIT("smlLockReadBuffer"); /* --- Lock Workspace exclusively for reading and get a "Read" pointer --- */ rc = wsmLockH(id, SML_FIRST_DATA_ITEM, pReadPosition); RELEASETOOLKIT("smlLockReadBuffer"); if (rc!=SML_ERR_OK) return rc; /* --- Check, how much data has to be read ---*/ LOCKTOOLKIT("smlLockReadBuffer"); rc = wsmGetUsedSize(id,usedSize); RELEASETOOLKIT("smlLockReadBuffer"); if (rc!=SML_ERR_OK) return rc; #endif return SML_ERR_OK; } /** * End the read access of the application to the workspace buffer. * SyncML is now owner of the buffer again and is able to manipulate its contents. * processedBytes passes the number of bytes, which the application has * successfully read and processed (e.g. when the application has copied * outgoing synchronization data from the workspace into a communication module). * SyncML removes the given number of bytes from the workspace! * * @param id (IN) * ID of the Instance * @param processedBytes (IN) * Actually read and processed bytes * @return Return value,\n * SML_ERR_OK if successful */ SML_API Ret_t smlUnlockReadBuffer(InstanceID_t id, MemSize_t processedBytes) { #ifdef NOWSM InstanceInfoPtr_t pInstanceInfo; pInstanceInfo = (InstanceInfoPtr_t)id; // ID is the instance info pointer if (pInstanceInfo==NULL) return SML_ERR_MGR_INVALID_INSTANCE_INFO; // must be already locked here if (!pInstanceInfo->readLocked) return SML_ERR_WRONG_USAGE; // advance read pointer by number of bytes processed if (pInstanceInfo->readPointer+processedBytes>pInstanceInfo->writePointer) return SML_ERR_WRONG_USAGE; // too many bytes processed // update read pointer pInstanceInfo->readPointer+=processedBytes; /* %%% moved from here to smlLockWriteBuffer to leave buffer intact until we actually need to write more data (important for re-sending retries) // auto-reset pointers if we have now read everything if (pInstanceInfo->readPointer == pInstanceInfo->writePointer) { // clear the buffer mgrResetWorkspace(pInstanceInfo); } */ // unlock pInstanceInfo->readLocked=0; #else Ret_t rc; /* --- Pass the number of bytes which have been read --- */ LOCKTOOLKIT("smlUnlockReadBuffer"); rc = wsmProcessedBytes (id,processedBytes); RELEASETOOLKIT("smlUnlockReadBuffer"); if (rc!=SML_ERR_OK) return rc; /* --- Unlock Workspace --- */ LOCKTOOLKIT("smlUnlockReadBuffer"); rc = wsmUnlockH(id); RELEASETOOLKIT("smlUnlockReadBuffer"); if (rc!=SML_ERR_OK) return rc; #endif return SML_ERR_OK; } #ifdef NOWSM /** * Set max outgoing message size * * @param id (IN) * ID of the Instance * @param maxOutgoingSize (IN) * maximum size of outgoing message * (0=no limit except buffer size) * @return Return value,\n * SML_ERR_OK if successful */ SML_API Ret_t smlSetMaxOutgoingSize(InstanceID_t id, MemSize_t maxOutgoingSize) { InstanceInfoPtr_t pInstanceInfo; pInstanceInfo = (InstanceInfoPtr_t)id; // ID is the instance info pointer if (pInstanceInfo==NULL) return SML_ERR_MGR_INVALID_INSTANCE_INFO; // set max outgoing message size pInstanceInfo->maxOutgoingSize = maxOutgoingSize; return SML_ERR_OK; } /** * Marks the current write pointer position as beginning of a new outgoing * message. This is used to track outgoing message size while writing it * * @param id (IN) * ID of the Instance * @return Return value,\n * SML_ERR_OK if successful */ SML_API Ret_t smlSetOutgoingBegin(InstanceID_t id) { InstanceInfoPtr_t pInstanceInfo; pInstanceInfo = (InstanceInfoPtr_t)id; // ID is the instance info pointer if (pInstanceInfo==NULL) return SML_ERR_MGR_INVALID_INSTANCE_INFO; // remember current write pointer pInstanceInfo->outgoingMsgStart=pInstanceInfo->writePointer; return SML_ERR_OK; } /** * resets the read pointer to the beginning of the outgoing message * (must be set previously using smlSetOutgoingBegin()) * Note: this can also be used to make sure next smlLockReadBuffer() * does not return unprocessed garbage from a message * written previously to the buffer (as it can be the case * when using the same sml instance for both request and * response processing, as in libsynthesis). In this case * calling smlReadOutgoingAgain() ADVANCES the read * pointer past unprocessed garbage to the point in the * buffer where the next outgoing message starts. * * @param id (IN) * ID of the Instance * @return Return value,\n * SML_ERR_OK if successful */ SML_API Ret_t smlReadOutgoingAgain(InstanceID_t id) { InstanceInfoPtr_t pInstanceInfo; pInstanceInfo = (InstanceInfoPtr_t)id; // ID is the instance info pointer if (pInstanceInfo==NULL) return SML_ERR_MGR_INVALID_INSTANCE_INFO; // reset read pointer back to beginning of outgoing message (can be used for message retries) if (pInstanceInfo->outgoingMsgStart==NULL) return SML_ERR_WRONG_USAGE; // no outgoing start set pInstanceInfo->readPointer=pInstanceInfo->outgoingMsgStart; return SML_ERR_OK; } /** * gets pointer to message in buffer for dumping purposes * @note This is only valid for incoming messages BEFORE outgoing message writing has started * into the same instance buffer! * * @param id (IN) * ID of the Instance * @param outgoing (IN) * if set, outgoing message is returned, incoming otherwise * @param message (OUT) * pointer to message * @param msgsize (OUT) * message size * @return Return value,\n * SML_ERR_OK if successful */ SML_API Ret_t smlPeekMessageBuffer(InstanceID_t id, Boolean_t outgoing, MemPtr_t *message, MemSize_t *msgsize) { InstanceInfoPtr_t pInstanceInfo; pInstanceInfo = (InstanceInfoPtr_t)id; // ID is the instance info pointer if (pInstanceInfo==NULL) return SML_ERR_MGR_INVALID_INSTANCE_INFO; if (outgoing) { if (pInstanceInfo->outgoingMsgStart==NULL) return SML_ERR_WRONG_USAGE; // no outgoing message yet *message = pInstanceInfo->outgoingMsgStart; } else { if (pInstanceInfo->incomingMsgStart) { // incoming message start already detected, return it *message = pInstanceInfo->incomingMsgStart; } else { // apparently not started analyzing, assume read pointer as beginning of message if (pInstanceInfo->readPointer==0) return SML_ERR_WRONG_USAGE; // no outgoing message yet *message = pInstanceInfo->readPointer; } } if (*message>=pInstanceInfo->writePointer) return SML_ERR_WRONG_USAGE; // invalid pointer positions // size is space between start and write pointer *msgsize = pInstanceInfo->writePointer-*message; return SML_ERR_OK; } #endif /** * Locks the workspace buffer, which is assigned to the given * instance for writing. After this function is called, the * application has access to the workspace buffer, beginning * at the address pWritePosition which is returned by this * function. SyncML will not change the workspace buffer until * smlUnlockWriteBuffer is called. * pWritePosition returns a pointer to a valid position in the * SyncML workspace buffer. The pointer can be used by the application * for copying incoming synchronization data from some transport * layer into the buffer. freeSize retrieves the maximum usable * size of the workspace buffer beginning from the address to * which pWritePosition points to. This information is needed by * the application when copying XML code into the buffer (while * receiving synchronization data) * * @param id (IN) * ID of the Instance * @param pWritePosition (OUT) * Workspace Pointer to which data can be written * @param freeSize (OUT) * Max free Size of available space for data * @return Return value,\n * SML_ERR_OK if successful */ SML_API Ret_t smlLockWriteBuffer(InstanceID_t id, MemPtr_t *pWritePosition, MemSize_t *freeSize) { #ifdef NOWSM InstanceInfoPtr_t pInstanceInfo; Boolean_t ogs; pInstanceInfo = (InstanceInfoPtr_t)id; // ID is the instance info pointer if (pInstanceInfo==NULL) return SML_ERR_MGR_INVALID_INSTANCE_INFO; // must not be already locked here if (pInstanceInfo->writeLocked) return SML_ERR_WRONG_USAGE; // auto-reset pointers if buffer is empty by now if (pInstanceInfo->readPointer == pInstanceInfo->writePointer) { // remember if we were at outgoing message start point ogs = pInstanceInfo->outgoingMsgStart == pInstanceInfo->writePointer; // clear the buffer mgrResetWorkspace(pInstanceInfo); // restore outgoingMsgStart (to beginning of buffer now!) if it was set before if (ogs) pInstanceInfo->outgoingMsgStart=pInstanceInfo->writePointer; } // return current write pointer *pWritePosition = pInstanceInfo->writePointer; // free portion is either determined by actual room in buffer, or maximum outgoing size if set if ( pInstanceInfo->maxOutgoingSize && pInstanceInfo->outgoingMsgStart && pInstanceInfo->outgoingMsgStartwritePointer ) { // calculate what is allowed according to maxOutgoingSize *freeSize = (pInstanceInfo->maxOutgoingSize) - // maximum outgoing size (pInstanceInfo->writePointer-pInstanceInfo->outgoingMsgStart); // size of outgoing message so far if (pInstanceInfo->writePointer+*freeSize > pInstanceInfo->instanceBuffer+pInstanceInfo->instanceBufSiz) { // actual space in buffer is smaller *freeSize = (pInstanceInfo->instanceBuffer+pInstanceInfo->instanceBufSiz) - // end of buffer pInstanceInfo->writePointer; // current write position } } else { // simply return available size in buffer *freeSize = (pInstanceInfo->instanceBuffer+pInstanceInfo->instanceBufSiz) - // end of buffer pInstanceInfo->writePointer; // current write position } // lock pInstanceInfo->writeLocked=1; #else Ret_t rc; /* --- Lock Workspace exclusively for writing and get a "Write" pointer --- */ LOCKTOOLKIT("smlLockWriteBuffer"); rc = wsmLockH(id, SML_FIRST_FREE_ITEM, pWritePosition); RELEASETOOLKIT("smlLockWriteBuffer"); if (rc!=SML_ERR_OK) return rc; /* --- Check, how much free space is available for writing --- */ LOCKTOOLKIT("smlLockWriteBuffer"); rc = wsmGetFreeSize(id, freeSize); RELEASETOOLKIT("smlLockWriteBuffer"); if (rc!=SML_ERR_OK) return rc; #endif return SML_ERR_OK; } /** * * End the write access of the application to the workspace buffer. * SyncML is now owner of the buffer again and is able to manipulate its * contents. writtenBytes passes the number of bytes which have been * written into the workspace buffer (e.g. when the application has copied * incoming synchronization data from a communication module into the * workspace). This information is needed by SyncML when processing received * synchronization data. * * @param id (IN) * ID of the Instance * @param writtenBytes (IN) * Actually written bytes * @return Return value,\n * SML_ERR_OK if successful */ SML_API Ret_t smlUnlockWriteBuffer(InstanceID_t id, MemSize_t writtenBytes) { #ifdef NOWSM InstanceInfoPtr_t pInstanceInfo; pInstanceInfo = (InstanceInfoPtr_t)id; // ID is the instance info pointer if (pInstanceInfo==NULL) return SML_ERR_MGR_INVALID_INSTANCE_INFO; // must be already locked here if (!pInstanceInfo->writeLocked) return SML_ERR_WRONG_USAGE; if (writtenBytes > 0) { // advance write pointer by number of bytes written if (pInstanceInfo->writePointer+writtenBytes>pInstanceInfo->instanceBuffer+pInstanceInfo->instanceBufSiz) return SML_ERR_WRONG_USAGE; // too many bytes written // update write pointer pInstanceInfo->writePointer+=writtenBytes; } // unlock pInstanceInfo->writeLocked=0; #else Ret_t rc; if (writtenBytes > 0) { /* --- Pass the number of bytes which have been written --- */ LOCKTOOLKIT("smlUnlockWriteBuffer"); rc = wsmSetUsedSize(id,writtenBytes); RELEASETOOLKIT("smlUnlockWriteBuffer"); if (rc!=SML_ERR_OK) return rc; } /* --- Unlock Workspace --- */ LOCKTOOLKIT("smlUnlockWriteBuffer"); rc = wsmUnlockH(id); RELEASETOOLKIT("smlUnlockWriteBuffer"); if (rc!=SML_ERR_OK) return rc; #endif return SML_ERR_OK; } /************************************************************************* * SyncML internal functions *************************************************************************/ /** * Reset the Workspace Buffer position to the beginning of the workspace * (clears all data in the buffer) * * @param id (IN) * ID of the Instance * @return Return value,\n * SML_ERR_OK if successful */ Ret_t mgrResetWorkspace (InstanceID_t id) { #ifdef NOWSM InstanceInfoPtr_t pInstanceInfo; pInstanceInfo = (InstanceInfoPtr_t)id; // ID is the instance info pointer if (pInstanceInfo==NULL) return SML_ERR_MGR_INVALID_INSTANCE_INFO; pInstanceInfo->readPointer=pInstanceInfo->instanceBuffer; pInstanceInfo->writePointer=pInstanceInfo->instanceBuffer; pInstanceInfo->outgoingMsgStart=NULL; // no outgoing message in the buffer pInstanceInfo->incomingMsgStart=NULL; // no incoming message in the buffer return SML_ERR_OK; // ok #else Ret_t rc; LOCKTOOLKIT("mgrResetWorkspace"); rc=wsmReset (id); RELEASETOOLKIT("mgrResetWorkspace"); return rc; #endif } /** * The options settings of an instance are set to a new value * * @param id (IN) * Instance ID assigned to the instance * @param pOptions (IN) * New option settings of that particular SyncML instance\n * NOTE: only the encoding can be changed during life-time of an * instance. The other parameters of the instance options * (workspace size and name cannot be changed) * @return Error Code */ Ret_t setInstanceOptions (InstanceID_t id, SmlInstanceOptionsPtr_t pOptions) { /* --- Definitions --- */ InstanceInfoPtr_t pInstanceInfo; SmlInstanceOptionsPtr_t pOptionsCopy; #ifdef NOWSM /* --- Ckeck pOptions, which have been passed by the application --- */ if (!pOptions || (pOptions->encoding==SML_UNDEF)) return SML_ERR_WRONG_USAGE; pInstanceInfo = (InstanceInfoPtr_t)id; // ID is the instance info pointer #else /* --- Ckeck pOptions, which have been passed by the application --- */ if (!pOptions || !pOptions->workspaceName|| (pOptions->encoding==SML_UNDEF)) return SML_ERR_WRONG_USAGE; /* --- Find that instance --- */ #ifdef __SML_LITE__ /* Only ONE instance is supported in the Toolkit lite version */ pInstanceInfo = mgrGetInstanceListAnchor(); #else pInstanceInfo = (InstanceInfoPtr_t) findInfo(id); #endif #endif if (pInstanceInfo==NULL) return SML_ERR_MGR_INVALID_INSTANCE_INFO; /* --- free old instance options ---*/ freeInstanceOptions(pInstanceInfo); /* --- Use a copy of pOptionsCopy --- */ pOptionsCopy = (SmlInstanceOptionsPtr_t)smlLibMalloc((MemSize_t)sizeof(SmlInstanceOptions_t)); if (pOptionsCopy==NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemcpy(pOptionsCopy,pOptions,(MemSize_t)sizeof(SmlInstanceOptions_t)); #ifndef NOWSM pOptionsCopy->workspaceName=smlLibStrdup(pOptions->workspaceName); if (pOptionsCopy->workspaceName == NULL) { pInstanceInfo->instanceOptions=NULL; smlLibFree(pOptionsCopy); return SML_ERR_NOT_ENOUGH_SPACE; } #endif /* --- Assign the new options --- */ pInstanceInfo->instanceOptions=pOptionsCopy; /* --- Let the new settingds take effect --- */ /* --- Adjust workspace size ---*/ /* --- Change workspace name ---*/ // NOT SUPPORTED FOR YELLOW return SML_ERR_OK; } /** * Free Instances Options * * @param pInfo (IN) * Pointer to the pInstance Info, which options should be freed * @return SML_ERR_OK */ Ret_t freeInstanceOptions (InstanceInfoPtr_t pInfo) { /* --- Delete instance options (if there are any) --- */ if (pInfo->instanceOptions!=NULL) { #ifndef NOWSM if (pInfo->instanceOptions->workspaceName!=NULL) smlLibFree(pInfo->instanceOptions->workspaceName); // don't forget the substructures #endif smlLibFree(pInfo->instanceOptions); } return SML_ERR_OK; } /** * Free the memory of an removed Instance Info * (including referenced sub structures) * * @param id (IN) * ID of the InstanceInfo structure to be freed */ static Ret_t freeInstanceInfo(InstanceInfoPtr_t pInfo) { if (pInfo) { #ifdef NOWSM // return the instance buffer if (pInfo->instanceBuffer) smlLibFree(pInfo->instanceBuffer); #else if (pInfo->workspaceState) smlLibFree(pInfo->workspaceState); #endif if (pInfo->encoderState) xltEncReset((XltEncoderPtr_t)pInfo->encoderState); if (pInfo->decoderState) xltDecReset((XltDecoderPtr_t)pInfo->decoderState); if (pInfo->callbacks) smlLibFree(pInfo->callbacks); freeInstanceOptions(pInfo); smlLibFree(pInfo); } return SML_ERR_OK; } libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/mgr/all/mgrutil.c000077500000000000000000001224431226375725500242150ustar00rootroot00000000000000/** * @file * some helper functions * * @target_system all * @target_os all * @description */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ /************************************************************************* * Definitions *************************************************************************/ #include "syncml_tk_prefix_file.h" // %%% luz: needed for precompiled headers in eVC++ /* Include Headers */ #include #include #include #include #include #include #include "libmem.h" #include "libstr.h" #include "liblock.h" #include "mgr.h" #include "mgrutil.h" /************************************************************************* * Exported SyncML API functions *************************************************************************/ /** * Frees all allocated memory of a smlProtoElement * * @param pProtoElement (IN) * Element to free * @return Return Code */ SML_API Ret_t smlFreeProtoElement(VoidPtr_t pProtoElement) { if (! pProtoElement) return(SML_ERR_OK); switch (((SmlUnknownProtoElementPtr_t)pProtoElement)->elementType) { case SML_PE_HEADER: smlFreeSyncHdr((SmlSyncHdrPtr_t)pProtoElement); break; case SML_PE_SYNC_START: smlFreeSync((SmlSyncPtr_t)pProtoElement); break; case SML_PE_ADD: case SML_PE_COPY: case SML_PE_MOVE: case SML_PE_REPLACE: case SML_PE_DELETE: case SML_PE_GENERIC: smlFreeGeneric((SmlGenericCmdPtr_t)pProtoElement); break; case SML_PE_ALERT: smlFreeAlert((SmlAlertPtr_t)pProtoElement); break; case SML_PE_ATOMIC_START: case SML_PE_SEQUENCE_START: case SML_PE_CMD_GROUP: smlFreeAtomic((SmlAtomicPtr_t)pProtoElement); break; #if (defined EXEC_SEND || defined EXEC_RECEIVE) case SML_PE_EXEC: smlFreeExec((SmlExecPtr_t)pProtoElement); break; #endif case SML_PE_PUT: case SML_PE_GET: case SML_PE_PUT_GET: smlFreeGetPut((SmlPutPtr_t)pProtoElement); break; case SML_PE_MAP: smlFreeMap((SmlMapPtr_t)pProtoElement); break; case SML_PE_RESULTS: smlFreeResults((SmlResultsPtr_t)pProtoElement); break; #if (defined SEARCH_SEND || defined SEARCH_RECEIVE) case SML_PE_SEARCH: smlFreeSearch((SmlSearchPtr_t)pProtoElement); break; #endif case SML_PE_STATUS: smlFreeStatus((SmlStatusPtr_t)pProtoElement); break; default: return(SML_ERR_A_UTI_UNKNOWN_PROTO_ELEMENT); } return(SML_ERR_OK); } /** * Frees the Memory of an allocated Pcdata memory object * * @param pPcdata (IN) * A Pointer to a PcData structure, which should be freed */ SML_API void smlFreePcdata(SmlPcdataPtr_t pPcdata) { if (! pPcdata) return; if (pPcdata->contentType == SML_PCDATA_EXTENSION) { switch ((int)pPcdata->extension) { #ifdef __USE_METINF__ case SML_EXT_METINF: smlFreeMetinfMetinf(pPcdata->content); smlLibFree(pPcdata); break; #endif #ifdef __USE_DEVINF__ case SML_EXT_DEVINF: smlFreeDevInfDevInf(pPcdata->content); smlLibFree(pPcdata); break; #endif } return; } if (pPcdata->content) smlLibFree(pPcdata->content); smlLibFree(pPcdata); } SML_API void smlFreePcdataList(SmlPcdataListPtr_t list) { if (!list) return; smlFreePcdataList(list->next); smlFreePcdata(list->data); smlLibFree(list); return; } #ifdef __USE_METINF__ /** Subfunctions to smlFreePcdata, to freeup MetaInf DTD structures */ SML_API void smlFreeMetinfMetinf(SmlMetInfMetInfPtr_t data) { if (!data) return; smlFreePcdata(data->format); smlFreePcdata(data->type); smlFreePcdata(data->mark); smlFreePcdata(data->size); smlFreePcdata(data->version); smlFreePcdata(data->nextnonce); smlFreePcdata(data->maxmsgsize); /* SCTSTK - 18/03/2002, S.H. 2002-04-05 : SyncML 1.1 */ smlFreePcdata(data->maxobjsize); smlFreeMetinfAnchor(data->anchor); smlFreeMetinfMem(data->mem); smlFreePcdataList(data->emi); smlLibFree(data); return; } SML_API void smlFreeMetinfAnchor(SmlMetInfAnchorPtr_t data) { if (!data) return; smlFreePcdata(data->last); smlFreePcdata(data->next); smlLibFree(data); return; } SML_API void smlFreeMetinfMem(SmlMetInfMemPtr_t data) { if (!data) return; /* smlFreePcdata(data->shared); %%% luz 2005-08-24: shared is a flag, not a Pcdata - */ smlFreePcdata(data->free); smlFreePcdata(data->freeid); smlLibFree(data); return; } #endif #ifdef __USE_DEVINF__ /** Subfunctions to smlFreePcdata, to freeup DevInf DTD structures */ SML_API void smlFreeDevInfDevInf(SmlDevInfDevInfPtr_t data) { if (!data) return; smlFreePcdata(data->verdtd); smlFreePcdata(data->man); smlFreePcdata(data->mod); smlFreePcdata(data->oem); smlFreePcdata(data->fwv); smlFreePcdata(data->hwv); smlFreePcdata(data->swv); smlFreePcdata(data->devid); smlFreePcdata(data->devtyp); smlFreeDevInfDatastoreList(data->datastore); smlFreeDevInfExtList(data->ext); smlFreeDevInfCtcapList(data->ctcap); smlLibFree(data); } SML_API void smlFreeDevInfDatastore(SmlDevInfDatastorePtr_t data) { if (!data) return; smlFreePcdata(data->sourceref); smlFreePcdata(data->displayname); smlFreePcdata(data->maxguidsize); smlFreeDevInfXmit(data->rxpref); smlFreeDevInfXmit(data->txpref); smlFreeDevInfXmitList(data->rx); smlFreeDevInfXmitList(data->tx); smlFreeDevInfDSMem(data->dsmem); smlFreeDevInfSynccap(data->synccap); smlFreeDevInfXmitList(data->filterrx); smlFreeDevInfCtcapList(data->ctcap); smlFreeDevInfFilterCapList(data->filtercap); smlLibFree(data); return; } SML_API void smlFreeDevInfDatastoreList(SmlDevInfDatastoreListPtr_t data) { if (!data) return; smlFreeDevInfDatastore(data->data); smlFreeDevInfDatastoreList(data->next); smlLibFree(data); return; } SML_API void smlFreeDevInfXmitList(SmlDevInfXmitListPtr_t data) { if (!data) return; smlFreeDevInfXmit(data->data); smlFreeDevInfXmitList(data->next); smlLibFree(data); } SML_API void smlFreeDevInfXmit(SmlDevInfXmitPtr_t data) { if (!data) return; smlFreePcdata(data->cttype); smlFreePcdata(data->verct); smlLibFree(data); } SML_API void smlFreeDevInfDSMem(SmlDevInfDSMemPtr_t data) { if (!data) return; // %%%luz:2003-04-28: this is now a flag! smlFreePcdata(data->shared); smlFreePcdata(data->maxmem); smlFreePcdata(data->maxid); smlLibFree(data); } SML_API void smlFreeDevInfSynccap(SmlDevInfSyncCapPtr_t data) { if (!data) return; smlFreePcdataList(data->synctype); smlLibFree(data); } SML_API void smlFreeDevInfExt(SmlDevInfExtPtr_t data) { if (!data) return; smlFreePcdata(data->xnam); smlFreePcdataList(data->xval); smlLibFree(data); } SML_API void smlFreeDevInfExtList(SmlDevInfExtListPtr_t data) { if (!data) return; smlFreeDevInfExt(data->data); smlFreeDevInfExtList(data->next); smlLibFree(data); } SML_API void smlFreeDevInfCTData(SmlDevInfCTDataPtr_t data) { if (!data) return; smlFreePcdata(data->name); smlFreePcdata(data->dname); smlFreePcdataList(data->valenum); smlFreePcdata(data->datatype); smlFreePcdata(data->maxsize); smlFreePcdata(data->maxoccur); smlLibFree(data); } SML_API void smlFreeDevInfCTDataProp(SmlDevInfCTDataPropPtr_t data) { if (!data) return; smlFreeDevInfCTData(data->prop); smlFreeDevInfCTDataList(data->param); smlLibFree(data); } SML_API void smlFreeDevInfCTDataList(SmlDevInfCTDataListPtr_t data) { if (!data) return; smlFreeDevInfCTData(data->data); smlFreeDevInfCTDataList(data->next); smlLibFree(data); } SML_API void smlFreeDevInfCTDataPropList(SmlDevInfCTDataPropListPtr_t data) { if (!data) return; smlFreeDevInfCTDataProp(data->data); smlFreeDevInfCTDataPropList(data->next); smlLibFree(data); } SML_API void smlFreeDevInfCTCap(SmlDevInfCTCapPtr_t data) { if (!data) return; smlFreePcdata(data->cttype); smlFreePcdata(data->verct); smlFreeDevInfCTDataPropList(data->prop); smlLibFree(data); } SML_API void smlFreeDevInfCtcapList(SmlDevInfCtcapListPtr_t data) { if (!data) return; smlFreeDevInfCTCap(data->data); smlFreeDevInfCtcapList(data->next); smlLibFree(data); } SML_API void smlFreeDevInfFilterCap(SmlDevInfFilterCapPtr_t data) { if (!data) return; smlFreePcdata(data->cttype); smlFreePcdata(data->verct); smlFreePcdataList(data->filterkeyword); smlFreePcdataList(data->propname); smlLibFree(data); } SML_API void smlFreeDevInfFilterCapList(SmlDevInfFilterCapListPtr_t data) { if (!data) return; smlFreeDevInfFilterCap(data->data); smlFreeDevInfFilterCapList(data->next); smlLibFree(data); } #endif /************************************************************************* * Exported SyncML API functions (FULL-SIZE TOOLKIT ONLY) *************************************************************************/ #ifndef __SML_LITE__ /* these API calls are NOT included in the Toolkit lite version */ /** * Return amount of unused Workspace memory * * @param id instance ID * @return Amount of unused Workspace memory */ SML_API MemSize_t smlGetFreeBuffer(InstanceID_t id) { /* Definitions */ MemSize_t freeMem=0; #ifdef NOWSM InstanceInfoPtr_t pInstanceInfo = (InstanceInfoPtr_t)id; // ID is the instance info pointer if (pInstanceInfo==NULL) return 0; // no buffer if no instance there freeMem = (pInstanceInfo->instanceBuffer+pInstanceInfo->instanceBufSiz) - // end of buffer pInstanceInfo->writePointer; // current write pointer #else /* ask the Workspace Buffer */ LOCKTOOLKIT("smlGetFreeBuffer"); wsmGetFreeSize(id, &freeMem); RELEASETOOLKIT("smlGetFreeBuffer"); #endif return (MemSize_t)freeMem; } /** * Copy a string into a Pcdata structure * * @param str (IN) * Input String * @return A Pointer to a PcData structure */ SML_API SmlPcdataPtr_t smlString2Pcdata(String_t str) { /* Definitions */ SmlPcdataPtr_t pcdata; /* Invalid Input */ if (! str) return NULL; /* Allocate the PcData Structure */ pcdata = (SmlPcdataPtr_t)smlLibMalloc((MemSize_t)sizeof(SmlPcdata_t)); if (! pcdata) return NULL; smlLibMemset (pcdata, 0, (MemSize_t)sizeof(SmlPcdata_t)); /* Set the PcData Structure */ pcdata->contentType = SML_PCDATA_STRING; pcdata->length = smlLibStrlen( str ); pcdata->content = (VoidPtr_t)smlLibStrdup(str); return pcdata; } /** * Copy a Pcdata structure into a string * * @param pcdata (IN) * A Pointer to a PcData structure * @return Input String */ SML_API String_t smlPcdata2String(SmlPcdataPtr_t pcdata) { /* Definitions */ String_t str; /* Invalid Input */ if (! pcdata) return NULL; /* Allocate the String */ str = (String_t)smlLibMalloc((MemSize_t)(pcdata->length+1)); if (str == NULL) return NULL; /* Copy the string into the allocated data structure */ smlLibMemcpy((MemPtr_t)str, (MemPtr_t)pcdata->content, pcdata->length); *(str + pcdata->length) = '\0'; return str; } /** * Duplicates a Pcdata memory object * * @param pcdata (IN) * A Pointer to the original PcData structure * @return A Pointer to the copy of the PcData structure */ SML_API SmlPcdataPtr_t smlPcdataDup(SmlPcdataPtr_t pcdata) { /* Definitions */ SmlPcdataPtr_t newPcdata; /* Invalid Input */ if (! pcdata) return NULL; /* Allocate the new pcdata memory object */ newPcdata = (SmlPcdataPtr_t)smlLibMalloc((MemSize_t)sizeof(SmlPcdata_t)); if (! newPcdata) return NULL; smlLibMemset (newPcdata, 0, (MemSize_t)sizeof(SmlPcdata_t)); /* Set the PcData Structure */ newPcdata->contentType = pcdata->contentType; newPcdata->length = pcdata->length; newPcdata->content =(VoidPtr_t)smlLibMalloc((MemSize_t)pcdata->length+1); if (newPcdata->content ==NULL) { smlLibFree(newPcdata->content); smlLibFree(newPcdata); return NULL; } smlLibMemset(newPcdata->content, 0, (MemSize_t)((pcdata->length)+1)); smlLibMemcpy(newPcdata->content, pcdata->content, (MemSize_t)pcdata->length); return newPcdata; } #endif SML_API void smlFreeSyncHdr(SmlSyncHdrPtr_t pSyncHdr) { if (! pSyncHdr) return; smlFreePcdata(pSyncHdr->version); smlFreePcdata(pSyncHdr->proto); smlFreePcdata(pSyncHdr->sessionID); smlFreePcdata(pSyncHdr->msgID); smlFreePcdata(pSyncHdr->respURI); smlFreePcdata(pSyncHdr->meta); smlFreeSourceTargetPtr(pSyncHdr->source); smlFreeSourceTargetPtr(pSyncHdr->target); smlFreeCredPtr(pSyncHdr->cred); smlLibFree(pSyncHdr); } SML_API void smlFreeSync(SmlSyncPtr_t pSync) { if (! pSync) return; smlFreePcdata(pSync->cmdID); smlFreePcdata(pSync->meta); smlFreePcdata(pSync->noc); // %%% luz 2004-09-29 added to fix mem leak smlFreeSourceTargetPtr(pSync->source); smlFreeSourceTargetPtr(pSync->target); smlFreeCredPtr(pSync->cred); smlLibFree(pSync); } SML_API void smlFreeGeneric(SmlGenericCmdPtr_t pGenericCmd) { if (! pGenericCmd) return; smlFreePcdata(pGenericCmd->cmdID); smlFreePcdata(pGenericCmd->meta); smlFreeCredPtr(pGenericCmd->cred); smlFreeItemList(pGenericCmd->itemList); smlLibFree(pGenericCmd); } SML_API void smlFreeAlert(SmlAlertPtr_t pAlert) { if (! pAlert) return; smlFreePcdata(pAlert->cmdID); smlFreePcdata(pAlert->data); smlFreeCredPtr(pAlert->cred); smlFreeItemList(pAlert->itemList); smlLibFree(pAlert); } SML_API void smlFreeAtomic(SmlAtomicPtr_t pAtomic) { if (! pAtomic) return; smlFreePcdata(pAtomic->cmdID); smlFreePcdata(pAtomic->meta); smlLibFree(pAtomic); } #if (defined EXEC_SEND || defined EXEC_RECEIVE) SML_API void smlFreeExec(SmlExecPtr_t pExec) { if (! pExec) return; smlFreePcdata(pExec->cmdID); smlFreeCredPtr(pExec->cred); smlFreeItemPtr(pExec->item); smlLibFree(pExec); } #endif SML_API void smlFreeGetPut(SmlPutPtr_t pGetPut) { if (! pGetPut) return; smlFreePcdata(pGetPut->cmdID); smlFreePcdata(pGetPut->meta); smlFreePcdata(pGetPut->lang); smlFreeCredPtr(pGetPut->cred); smlFreeItemList(pGetPut->itemList); smlLibFree(pGetPut); } SML_API void smlFreeMap(SmlMapPtr_t pMap) { if (! pMap) return; smlFreePcdata(pMap->cmdID); smlFreePcdata(pMap->meta); smlFreeCredPtr(pMap->cred); smlFreeSourceTargetPtr(pMap->source); smlFreeSourceTargetPtr(pMap->target); smlFreeMapItemList(pMap->mapItemList); smlLibFree(pMap); } SML_API void smlFreeResults(SmlResultsPtr_t pResults) { if (! pResults) return; smlFreePcdata(pResults->cmdID); smlFreePcdata(pResults->msgRef); smlFreePcdata(pResults->cmdRef); smlFreePcdata(pResults->meta); smlFreePcdata(pResults->targetRef); smlFreePcdata(pResults->sourceRef); smlFreeItemList(pResults->itemList); smlLibFree(pResults); } #if (defined SEARCH_SEND || defined SEARCH_RECEIVE) SML_API void smlFreeSearch(SmlSearchPtr_t pSearch) { if (! pSearch) return; smlFreePcdata(pSearch->cmdID); smlFreePcdata(pSearch->lang); smlFreePcdata(pSearch->meta); smlFreePcdata(pSearch->data); smlFreeCredPtr(pSearch->cred); smlFreeSourceTargetPtr(pSearch->target); smlFreeSourceList(pSearch->sourceList); smlLibFree(pSearch); } #endif SML_API void smlFreeStatus(SmlStatusPtr_t pStatus) { if (! pStatus) return; smlFreePcdata(pStatus->cmdID); smlFreePcdata(pStatus->msgRef); smlFreePcdata(pStatus->cmdRef); smlFreePcdata(pStatus->cmd); smlFreePcdata(pStatus->data); smlFreeCredPtr(pStatus->cred); smlFreeChalPtr(pStatus->chal); smlFreeTargetRefList(pStatus->targetRefList); smlFreeSourceRefList(pStatus->sourceRefList); smlFreeItemList(pStatus->itemList); smlLibFree(pStatus); } SML_API void smlFreeCredPtr(SmlCredPtr_t pCred) { if (! pCred) return; smlFreePcdata(pCred->meta); smlFreePcdata(pCred->data); smlLibFree(pCred); } SML_API void smlFreeChalPtr(SmlChalPtr_t pChal) { if (! pChal) return; smlFreePcdata(pChal->meta); smlLibFree(pChal); } SML_API void smlFreeRecordFieldFilterPtr(SmlRecordOrFieldFilterPtr_t pRecordFieldFilter) { if (! pRecordFieldFilter) return; smlFreeItemPtr(pRecordFieldFilter->item); smlLibFree(pRecordFieldFilter); } SML_API void smlFreeFilterPtr(SmlFilterPtr_t pFilter) { if (! pFilter) return; smlFreePcdata(pFilter->meta); smlFreeRecordFieldFilterPtr(pFilter->field); smlFreeRecordFieldFilterPtr(pFilter->record); smlFreePcdata(pFilter->filtertype); smlLibFree(pFilter); } SML_API void smlFreeSourceTargetParentPtr(SmlSourceParentPtr_t pSourceTargetParent) { if (! pSourceTargetParent) return; smlFreePcdata(pSourceTargetParent->locURI); smlLibFree(pSourceTargetParent); } SML_API void smlFreeSourceTargetPtr(SmlSourcePtr_t pSourceTarget) { if (! pSourceTarget) return; smlFreePcdata(pSourceTarget->locURI); smlFreePcdata(pSourceTarget->locName); smlFreeFilterPtr(pSourceTarget->filter); smlLibFree(pSourceTarget); } SML_API void smlFreeSourceList(SmlSourceListPtr_t pSourceList) { SmlSourceListPtr_t pTmp; while (pSourceList) { pTmp = pSourceList->next; smlFreeSourceTargetPtr(pSourceList->source); smlLibFree(pSourceList); pSourceList = pTmp; } } SML_API void smlFreeSourceRefList(SmlSourceRefListPtr_t pSourceRefList) { SmlSourceRefListPtr_t pTmp; while (pSourceRefList) { pTmp = pSourceRefList->next; smlFreePcdata(pSourceRefList->sourceRef); smlLibFree(pSourceRefList); pSourceRefList = pTmp; } } SML_API void smlFreeTargetRefList(SmlTargetRefListPtr_t pTargetRefList) { SmlTargetRefListPtr_t pTmp; while (pTargetRefList) { pTmp = pTargetRefList->next; smlFreePcdata(pTargetRefList->targetRef); smlLibFree(pTargetRefList); pTargetRefList = pTmp; } } SML_API void smlFreeItemPtr(SmlItemPtr_t pItem) { if (! pItem) return; if (pItem->aux) pItem->aux->freeAux(pItem->aux); smlFreePcdata(pItem->meta); smlFreePcdata(pItem->data); smlFreeSourceTargetPtr(pItem->source); smlFreeSourceTargetPtr(pItem->target); smlLibFree(pItem); } SML_API void smlFreeItemList(SmlItemListPtr_t pItemList) { SmlItemListPtr_t pTmp; while (pItemList) { pTmp = pItemList->next; smlFreeItemPtr(pItemList->item); smlLibFree(pItemList); pItemList = pTmp; } } SML_API void smlFreeMapItemPtr(SmlMapItemPtr_t pMapItem) { if (! pMapItem) return; smlFreeSourceTargetPtr(pMapItem->source); smlFreeSourceTargetPtr(pMapItem->target); smlLibFree(pMapItem); } SML_API void smlFreeMapItemList(SmlMapItemListPtr_t pMapItemList) { SmlMapItemListPtr_t pTmp; while (pMapItemList) { pTmp = pMapItemList->next; smlFreeMapItemPtr(pMapItemList->mapItem); smlLibFree(pMapItemList); pMapItemList = pTmp; } } #ifdef __USE_ALLOCFUNCS__ /* Helperfunctions, that allocate and preset SyncML C structs */ SML_API SmlPcdataPtr_t smlAllocPcdata() { SmlPcdataPtr_t p = (SmlPcdataPtr_t)smlLibMalloc(sizeof(SmlPcdata_t)); if (p == NULL) return NULL; smlLibMemset(p, 0, sizeof(SmlPcdata_t)); return p; } SML_API SmlPcdataListPtr_t smlAllocPcdataList() { SmlPcdataListPtr_t p = (SmlPcdataListPtr_t)smlLibMalloc(sizeof(SmlPcdataList_t)); if (p == NULL) return NULL; smlLibMemset(p, 0, sizeof(SmlPcdataList_t)); p->data = smlAllocPcdata(); if (p->data == NULL) { smlFreePcdataList(p); return NULL; } return p; } SML_API SmlChalPtr_t smlAllocChal() { SmlChalPtr_t p = (SmlChalPtr_t)smlLibMalloc(sizeof(SmlChal_t)); if (p == NULL) return NULL; smlLibMemset(p, 0, sizeof(SmlChal_t)); p->meta = smlAllocPcdata(); if (p->meta == NULL) { smlFreeChalPtr(p); return NULL; } return p; } SML_API SmlCredPtr_t smlAllocCred() { SmlCredPtr_t p = (SmlCredPtr_t)smlLibMalloc(sizeof(SmlCred_t)); if (p == NULL) return NULL; smlLibMemset(p, 0, sizeof(SmlCred_t)); p->data = smlAllocPcdata(); if (p->data == NULL) { smlFreeCredPtr(p); return NULL; } return p; } SML_API SmlRecordOrFieldFilterPtr_t smlAllocRecordFieldFilter() { SmlRecordOrFieldFilterPtr_t p = (SmlRecordOrFieldFilterPtr_t)smlLibMalloc(sizeof(SmlRecordOrFieldFilterPtr_t)); if (p == NULL) return NULL; smlLibMemset(p, 0, sizeof(SmlRecordOrFieldFilterPtr_t)); p->item = smlAllocItem(); if (p->item == NULL) { smlFreeRecordFieldFilterPtr(p); return NULL; } return p; } SML_API SmlFilterPtr_t smlAllocFilter() { SmlFilterPtr_t p = (SmlFilterPtr_t)smlLibMalloc(sizeof(SmlFilterPtr_t)); if (p == NULL) return NULL; smlLibMemset(p, 0, sizeof(SmlFilterPtr_t)); p->meta = smlAllocPcdata(); if (p->meta == NULL) { smlFreeFilterPtr(p); return NULL; } return p; } SML_API SmlSourceParentPtr_t smlAllocSourceParent() { SmlSourceParentPtr_t p = (SmlSourceParentPtr_t)smlLibMalloc(sizeof(SmlSourceParentPtr_t)); if (p == NULL) return NULL; smlLibMemset(p, 0, sizeof(SmlSourceParentPtr_t)); p->locURI = smlAllocPcdata(); if (p->locURI == NULL) { smlFreeSourceTargetParentPtr(p); return NULL; } return p; } SML_API SmlTargetParentPtr_t smlAllocTargetParent() { return smlAllocSourceParent(); } SML_API SmlSourcePtr_t smlAllocSource() { SmlSourcePtr_t p = (SmlSourcePtr_t)smlLibMalloc(sizeof(SmlSource_t)); if (p == NULL) return NULL; smlLibMemset(p, 0, sizeof(SmlSource_t)); p->locURI = smlAllocPcdata(); if (p->locURI == NULL) { smlFreeSourceTargetPtr(p); return NULL; } return p; } SML_API SmlTargetPtr_t smlAllocTarget() { return smlAllocSource(); } SML_API SmlSourceListPtr_t smlAllocSourceList() { SmlSourceListPtr_t p = (SmlSourceListPtr_t)smlLibMalloc(sizeof(SmlSourceList_t)); if (p == NULL) return NULL; smlLibMemset(p, 0, sizeof(SmlSourceList_t)); p->source = smlAllocSource(); if (p->source == NULL) { smlFreeSourceList(p); return NULL; } return p; } SML_API SmlSyncHdrPtr_t smlAllocSyncHdr() { SmlSyncHdrPtr_t p = (SmlSyncHdrPtr_t)smlLibMalloc(sizeof(SmlSyncHdr_t)); if (p == NULL) return NULL; smlLibMemset(p, 0, sizeof(SmlSyncHdr_t)); p->elementType = SML_PE_HEADER; p->version = smlAllocPcdata(); if (p->version == NULL) { smlFreeSyncHdr(p); return NULL; } p->proto = smlAllocPcdata(); if (p->proto == NULL) { smlFreeSyncHdr(p); return NULL; } p->sessionID = smlAllocPcdata(); if (p->sessionID == NULL) { smlFreeSyncHdr(p); return NULL; } p->msgID = smlAllocPcdata(); if (p->msgID == NULL) { smlFreeSyncHdr(p); return NULL; } p->target = smlAllocTarget(); if (p->target == NULL) { smlFreeSyncHdr(p); return NULL; } p->source = smlAllocSource(); if (p->source == NULL) { smlFreeSyncHdr(p); return NULL; } return p; } SML_API SmlItemPtr_t smlAllocItem() { SmlItemPtr_t p = (SmlItemPtr_t)smlLibMalloc(sizeof(SmlItem_t)); if (p == NULL) return NULL; smlLibMemset(p, 0, sizeof(SmlItem_t)); return p; } SML_API SmlItemListPtr_t smlAllocItemList() { SmlItemListPtr_t p = (SmlItemListPtr_t)smlLibMalloc(sizeof(SmlItemList_t)); if (p == NULL) return NULL; smlLibMemset(p, 0, sizeof(SmlItemList_t)); p->item = smlAllocItem(); if (p->item == NULL) { smlFreeItemList(p); return NULL; } return p; } SML_API SmlGenericCmdPtr_t smlAllocGeneric() { SmlGenericCmdPtr_t p = (SmlGenericCmdPtr_t)smlLibMalloc(sizeof(SmlGenericCmd_t)); if (p == NULL) return NULL; smlLibMemset(p, 0, sizeof(SmlGenericCmd_t)); p->elementType = SML_PE_GENERIC; p->cmdID = smlAllocPcdata(); if (p->cmdID == NULL) { smlFreeGeneric(p); return NULL; } p->itemList = smlAllocItemList(); if (p->itemList == NULL) { smlFreeGeneric(p); return NULL; } return p; } SML_API SmlAddPtr_t smlAllocAdd() { SmlAddPtr_t p = smlAllocGeneric(); if (p == NULL) return p; p->elementType = SML_PE_ADD; return p; } SML_API SmlCopyPtr_t smlAllocCopy() { SmlCopyPtr_t p = smlAllocGeneric(); if (p == NULL) return p; p->elementType = SML_PE_COPY; return p; } SML_API SmlMovePtr_t smlAllocMove() { SmlCopyPtr_t p = smlAllocGeneric(); if (p == NULL) return p; p->elementType = SML_PE_MOVE; return p; } SML_API SmlReplacePtr_t smlAllocReplace() { SmlReplacePtr_t p = smlAllocGeneric(); if (p == NULL) return p; p->elementType = SML_PE_REPLACE; return p; } SML_API SmlDeletePtr_t smlAllocDelete() { SmlDeletePtr_t p = smlAllocGeneric(); if (p == NULL) return p; p->elementType = SML_PE_DELETE; return p; } SML_API SmlAlertPtr_t smlAllocAlert() { SmlAlertPtr_t p = (SmlAlertPtr_t)smlLibMalloc(sizeof(SmlAlert_t)); if (p == NULL) return NULL; smlLibMemset(p, 0, sizeof(SmlAlert_t)); p->elementType = SML_PE_ALERT; p->cmdID = smlAllocPcdata(); if (p->cmdID == NULL) { smlFreeAlert(p); return NULL; } p->itemList = smlAllocItemList(); if (p->itemList == NULL) { smlFreeAlert(p); return NULL; } return p; } SML_API SmlAtomicPtr_t smlAllocAtomic() { SmlAtomicPtr_t p = (SmlAtomicPtr_t)smlLibMalloc(sizeof(SmlAtomic_t)); if (p == NULL) return NULL; smlLibMemset(p, 0, sizeof(SmlAtomic_t)); p->elementType = SML_PE_ATOMIC_START; p->cmdID = smlAllocPcdata(); if (p->cmdID == NULL) { smlFreeAtomic(p); return NULL; } return p; } SML_API SmlSequencePtr_t smlAllocSequence() { SmlSequencePtr_t p = smlAllocAtomic(); if (p == NULL) return NULL; p->elementType = SML_PE_SEQUENCE_START; return p; } SML_API SmlSyncPtr_t smlAllocSync() { SmlSyncPtr_t p = (SmlSyncPtr_t)smlLibMalloc(sizeof(SmlSync_t)); if (p == NULL) return NULL; smlLibMemset(p, 0, sizeof(SmlSync_t)); p->elementType = SML_PE_SYNC_START; p->cmdID = smlAllocPcdata(); if (p->cmdID == NULL) { smlFreeSync(p); return NULL; } return p; } #if defined(EXEC_SEND) || defined(EXEC_RECEIVE) SML_API SmlExecPtr_t smlAllocExec() { SmlExecPtr_t p = (SmlExecPtr_t)smlLibMalloc(sizeof(SmlExec_t)); if (p == NULL) return NULL; smlLibMemset(p, 0, sizeof(SmlExec_t)); p->elementType = SML_PE_EXEC; p->cmdID = smlAllocPcdata(); if (p->cmdID == NULL) { smlFreeExec(p); return NULL; } p->item = smlAllocItem(); if (p->item == NULL) { smlFreeExec(p); return NULL; } return p; } #endif SML_API SmlGetPtr_t smlAllocGet() { SmlGetPtr_t p = (SmlGetPtr_t)smlLibMalloc(sizeof(SmlGet_t)); if (p == NULL) return NULL; smlLibMemset(p, 0, sizeof(SmlGet_t)); p->elementType = SML_PE_GET; p->cmdID = smlAllocPcdata(); if (p->cmdID == NULL) { smlFreeGetPut(p); return NULL; } p->itemList = smlAllocItemList(); if (p->itemList == NULL) { smlFreeGetPut(p); return NULL; } return p; } SML_API SmlPutPtr_t smlAllocPut() { SmlPutPtr_t p = smlAllocGet(); if (p == NULL) return NULL; p->elementType = SML_PE_PUT; return p; } SML_API SmlMapItemPtr_t smlAllocMapItem() { SmlMapItemPtr_t p = (SmlMapItemPtr_t)smlLibMalloc(sizeof(SmlMapItem_t)); if (p == 0) return NULL; smlLibMemset(p, 0, sizeof(SmlMapItem_t)); p->target = smlAllocTarget(); if (p->target == NULL) { smlFreeMapItemPtr(p); return NULL; } p->source = smlAllocSource(); if (p->source == NULL) { smlFreeMapItemPtr(p); return NULL; } return p; } SML_API SmlMapItemListPtr_t smlAllocMapItemList() { SmlMapItemListPtr_t p = (SmlMapItemListPtr_t)smlLibMalloc(sizeof(SmlMapItemList_t)); if (p == 0) return NULL; smlLibMemset(p, 0, sizeof(SmlMapItemList_t)); p->mapItem = smlAllocMapItem(); if (p->mapItem == NULL) { smlFreeMapItemList(p); return NULL; } return p; } SML_API SmlMapPtr_t smlAllocMap() { SmlMapPtr_t p = (SmlMapPtr_t)smlLibMalloc(sizeof(SmlMap_t)); if (p == 0) return NULL; smlLibMemset(p, 0, sizeof(SmlMap_t)); p->elementType = SML_PE_MAP; p->cmdID = smlAllocPcdata(); if (p->cmdID == NULL) { smlFreeMap(p); return NULL; } p->target = smlAllocTarget(); if (p->target == NULL) { smlFreeMap(p); return NULL; } p->source = smlAllocSource(); if (p->source == NULL) { smlFreeMap(p); return NULL; } p->mapItemList = smlAllocMapItemList(); if (p->mapItemList == NULL) { smlFreeMap(p); return NULL; } return p; } SML_API SmlResultsPtr_t smlAllocResults() { SmlResultsPtr_t p = (SmlResultsPtr_t)smlLibMalloc(sizeof(SmlResults_t)); if (p == 0) return NULL; smlLibMemset(p, 0, sizeof(SmlResults_t)); p->elementType = SML_PE_RESULTS; p->cmdID = smlAllocPcdata(); if (p->cmdID == NULL) { smlFreeResults(p); return NULL; } p->cmdRef = smlAllocPcdata(); if (p->cmdRef == NULL) { smlFreeResults(p); return NULL; } p->itemList = smlAllocItemList(); if (p->itemList == NULL) { smlFreeResults(p); return NULL; } return p; } #if (defined SEARCH_SEND || defined SEARCH_RECEIVE) SML_API SmlSearchPtr_t smlAllocSearch() { SmlSearchPtr_t p = (SmlSearchPtr_t)smlLibMalloc(sizeof(SmlSearch_t)); if (p == 0) return NULL; smlLibMemset(p, 0, sizeof(SmlSearch_t)); p->elementType = SML_PE_SEARCH; p->cmdID = smlAllocPcdata(); if (p->cmdID == NULL) { smlFreeSearch(p); return NULL; } p->meta = smlAllocPcdata(); if (p->meta == NULL) { smlFreeSearch(p); return NULL; } p->data = smlAllocPcdata(); if (p->data == NULL) { smlFreeSearch(p); return NULL; } p->sourceList = smlAllocSourceList(); if (p->sourceList == NULL) { smlFreeSearch(p); return NULL; } return p; } #endif SML_API SmlTargetRefListPtr_t smlAllocTargetRefList() { SmlTargetRefListPtr_t p = (SmlTargetRefListPtr_t)smlLibMalloc(sizeof(SmlTargetRefList_t)); if (p == 0) return NULL; smlLibMemset(p, 0, sizeof(SmlTargetRefList_t)); p->targetRef = smlAllocPcdata(); if (p->targetRef == NULL) { smlFreeTargetRefList(p); return NULL; } return p; } SML_API SmlSourceRefListPtr_t smlAllocSourceRefList() { SmlSourceRefListPtr_t p = (SmlSourceRefListPtr_t)smlLibMalloc(sizeof(SmlSourceRefList_t)); if (p == 0) return NULL; smlLibMemset(p, 0, sizeof(SmlSourceRefList_t)); p->sourceRef = smlAllocPcdata(); if (p->sourceRef == NULL) { smlFreeSourceRefList(p); return NULL; } return p; } SML_API SmlStatusPtr_t smlAllocStatus() { SmlStatusPtr_t p = (SmlStatusPtr_t)smlLibMalloc(sizeof(SmlStatus_t)); if (p == 0) return NULL; smlLibMemset(p, 0, sizeof(SmlStatus_t)); p->elementType = SML_PE_STATUS; p->cmdID = smlAllocPcdata(); if (p->cmdID == NULL) { smlFreeStatus(p); return NULL; } p->msgRef = smlAllocPcdata(); if (p->msgRef == NULL) { smlFreeStatus(p); return NULL; } p->cmdRef = smlAllocPcdata(); if (p->cmdRef == NULL) { smlFreeStatus(p); return NULL; } p->cmd = smlAllocPcdata(); if (p->cmd == NULL) { smlFreeStatus(p); return NULL; } p->data = smlAllocPcdata(); if (p->data == NULL) { smlFreeStatus(p); return NULL; } return p; } SML_API SmlUnknownProtoElementPtr_t smlAllocUnknownProtoElement() { SmlUnknownProtoElementPtr_t p = (SmlUnknownProtoElementPtr_t)smlLibMalloc(sizeof(SmlUnknownProtoElement_t)); if (p == 0) return NULL; smlLibMemset(p, 0, sizeof(SmlUnknownProtoElement_t)); p->elementType = SML_PE_UNDEF; return p; } #ifdef __USE_METINF__ SML_API SmlMetInfMetInfPtr_t smlAllocMetInfMetInf() { SmlMetInfMetInfPtr_t p = (SmlMetInfMetInfPtr_t)smlLibMalloc(sizeof(SmlMetInfMetInf_t)); if (p == NULL) return NULL; smlLibMemset(p, 0, sizeof(SmlMetInfMetInf_t)); return p; } SML_API SmlMetInfAnchorPtr_t smlAllocMetInfAnchor() { SmlMetInfAnchorPtr_t p = (SmlMetInfAnchorPtr_t)smlLibMalloc(sizeof(SmlMetInfAnchor_t)); if (p == NULL) return NULL; smlLibMemset(p, 0, sizeof(SmlMetInfAnchor_t)); p->next = smlAllocPcdata(); if (p->next == NULL) { smlFreeMetinfAnchor(p); return NULL; } return p; } SML_API SmlMetInfMemPtr_t smlAllocMetInfMem() { SmlMetInfMemPtr_t p = (SmlMetInfMemPtr_t)smlLibMalloc(sizeof(SmlMetInfMem_t)); if (p == NULL) return NULL; smlLibMemset(p, 0, sizeof(SmlMetInfMem_t)); p->free = smlAllocPcdata(); if (p->free == NULL) { smlFreeMetinfMem(p); return NULL; } p->freeid = smlAllocPcdata(); if (p->freeid == NULL) { smlFreeMetinfMem(p); return NULL; } return p; } #endif #ifdef __USE_DEVINF__ SML_API SmlDevInfExtPtr_t smlAllocDevInfExt() { SmlDevInfExtPtr_t p = (SmlDevInfExtPtr_t)smlLibMalloc(sizeof(SmlDevInfExt_t)); if (p == NULL) return NULL; smlLibMemset(p, 0, sizeof(SmlDevInfExt_t)); p->xnam = smlAllocPcdata(); if (p->xnam == NULL) { smlFreeDevInfExt(p); return NULL; } return p; } SML_API SmlDevInfExtListPtr_t smlAllocDevInfExtList() { SmlDevInfExtListPtr_t p = (SmlDevInfExtListPtr_t)smlLibMalloc(sizeof(SmlDevInfExtList_t)); if (p == NULL) return NULL; smlLibMemset(p, 0, sizeof(SmlDevInfExtList_t)); p->data = smlAllocDevInfExt(); if (p->data == NULL) { smlFreeDevInfExtList(p); return NULL; } return p; } SML_API SmlDevInfSyncCapPtr_t smlAllocDevInfSyncCap() { SmlDevInfSyncCapPtr_t p = (SmlDevInfSyncCapPtr_t)smlLibMalloc(sizeof(SmlDevInfSyncCap_t)); if (p == NULL) return NULL; smlLibMemset(p, 0, sizeof(SmlDevInfSyncCap_t)); p->synctype = smlAllocPcdataList(); if (p->synctype == NULL) { smlFreeDevInfSynccap(p); return NULL; } return p; } SML_API SmlDevInfCTDataPtr_t smlAllocDevInfCTData() { SmlDevInfCTDataPtr_t p = (SmlDevInfCTDataPtr_t)smlLibMalloc(sizeof(SmlDevInfCTData_t)); if (p == NULL) return NULL; smlLibMemset(p, 0, sizeof(SmlDevInfCTData_t)); p->name = smlAllocPcdata(); if (p->name == NULL) { smlFreeDevInfCTData(p); return NULL; } return p; } SML_API SmlDevInfCTDataListPtr_t smlAllocDevInfCTDataList() { SmlDevInfCTDataListPtr_t p = (SmlDevInfCTDataListPtr_t)smlLibMalloc(sizeof(SmlDevInfCTDataList_t)); if (p == NULL) return NULL; smlLibMemset(p, 0, sizeof(SmlDevInfCTDataList_t)); p->data = smlAllocDevInfCTData(); if (p->data == NULL) { smlFreeDevInfCTDataList(p); return NULL; } return p; } SML_API SmlDevInfCTDataPropPtr_t smlAllocDevInfCTDataProp() { SmlDevInfCTDataPropPtr_t p = (SmlDevInfCTDataPropPtr_t)smlLibMalloc(sizeof(SmlDevInfCTDataProp_t)); if (p == NULL) return NULL; smlLibMemset(p, 0, sizeof(SmlDevInfCTDataProp_t)); p->prop = smlAllocDevInfCTData(); if (p->prop == NULL) { smlFreeDevInfCTDataProp(p); return NULL; } return p; } SML_API SmlDevInfCTDataPropListPtr_t smlAllocDevInfCTDataPropList() { SmlDevInfCTDataPropListPtr_t p = (SmlDevInfCTDataPropListPtr_t)smlLibMalloc(sizeof(SmlDevInfCTDataPropList_t)); if (p == NULL) return NULL; smlLibMemset(p, 0, sizeof(SmlDevInfCTDataPropList_t)); p->data = smlAllocDevInfCTDataProp(); if (p->data == NULL) { smlFreeDevInfCTDataPropList(p); return NULL; } return p; } SML_API SmlDevInfCTCapPtr_t smlAllocDevInfCTCap() { SmlDevInfCTCapPtr_t p = (SmlDevInfCTCapPtr_t)smlLibMalloc(sizeof(SmlDevInfCTCap_t)); if (p == NULL) return NULL; smlLibMemset(p, 0, sizeof(SmlDevInfCTCap_t)); p->cttype = smlAllocPcdata(); if (p->cttype == NULL) { smlFreeDevInfCTCap(p); return NULL; } p->prop = smlAllocDevInfCTDataPropList(); if (p->prop == NULL) { smlFreeDevInfCTCap(p); return NULL; } return p; } SML_API SmlDevInfCtcapListPtr_t smlAllocDevInfCtcapList() { SmlDevInfCtcapListPtr_t p = (SmlDevInfCtcapListPtr_t)smlLibMalloc(sizeof(SmlDevInfCtcapList_t)); if (p == NULL) return NULL; smlLibMemset(p, 0, sizeof(SmlDevInfCtcapList_t)); p->data = smlAllocDevInfCTCap(); if (p->data == NULL) { smlFreeDevInfCtcapList(p); return NULL; } return p; } SML_API SmlDevInfDSMemPtr_t smlAllocDevInfDSMem() { SmlDevInfDSMemPtr_t p = (SmlDevInfDSMemPtr_t)smlLibMalloc(sizeof(SmlDevInfDSMem_t)); if (p == NULL) return NULL; smlLibMemset(p, 0, sizeof(SmlDevInfDSMem_t)); return p; } SML_API SmlDevInfXmitPtr_t smlAllocDevInfXmit() { SmlDevInfXmitPtr_t p = (SmlDevInfXmitPtr_t)smlLibMalloc(sizeof(SmlDevInfXmit_t)); if (p == NULL) return NULL; smlLibMemset(p, 0, sizeof(SmlDevInfXmit_t)); p->cttype = smlAllocPcdata(); if (p->cttype == NULL) { smlFreeDevInfXmit(p); return NULL; } p->verct = smlAllocPcdata(); if (p->verct == NULL) { smlFreeDevInfXmit(p); return NULL; } return p; } SML_API SmlDevInfXmitListPtr_t smlAllocDevInfXmitList() { SmlDevInfXmitListPtr_t p = (SmlDevInfXmitListPtr_t)smlLibMalloc(sizeof(SmlDevInfXmitList_t)); if (p == NULL) return NULL; smlLibMemset(p, 0, sizeof(SmlDevInfXmitList_t)); p->data = smlAllocDevInfXmit(); if (p->data == NULL) { smlFreeDevInfXmitList(p); return NULL; } return p; } SML_API SmlDevInfDatastorePtr_t smlAllocDevInfDatastore() { SmlDevInfDatastorePtr_t p = (SmlDevInfDatastorePtr_t)smlLibMalloc(sizeof(SmlDevInfDatastore_t)); if (p == NULL) return NULL; smlLibMemset(p, 0, sizeof(SmlDevInfDatastore_t)); p->sourceref = smlAllocPcdata(); if (p->sourceref == NULL) { smlFreeDevInfDatastore(p); return NULL; } p->rxpref = smlAllocDevInfXmit(); if (p->rxpref == NULL) { smlFreeDevInfDatastore(p); return NULL; } p->txpref = smlAllocDevInfXmit(); if (p->txpref == NULL) { smlFreeDevInfDatastore(p); return NULL; } p->synccap = smlAllocDevInfSyncCap(); if (p->synccap == NULL) { smlFreeDevInfDatastore(p); return NULL; } return p; } SML_API SmlDevInfDatastoreListPtr_t smlAllocDevInfDatastoreList() { SmlDevInfDatastoreListPtr_t p = (SmlDevInfDatastoreListPtr_t)smlLibMalloc(sizeof(SmlDevInfDatastoreList_t)); if (p == NULL) return NULL; smlLibMemset(p, 0, sizeof(SmlDevInfDatastoreList_t)); p->data = smlAllocDevInfDatastore(); if (p->data == NULL) { smlFreeDevInfDatastoreList(p); return NULL; } return p; } SML_API SmlDevInfDevInfPtr_t smlAllocDevInfDevInf() { SmlDevInfDevInfPtr_t p = (SmlDevInfDevInfPtr_t)smlLibMalloc(sizeof(SmlDevInfDevInf_t)); if (p == NULL) return NULL; smlLibMemset(p, 0, sizeof(SmlDevInfDevInf_t)); p->verdtd = smlAllocPcdata(); if (p->verdtd == NULL) { smlFreeDevInfDevInf(p); return NULL; } p->devid = smlAllocPcdata(); if (p->devid == NULL) { smlFreeDevInfDevInf(p); return NULL; } p->devtyp = smlAllocPcdata(); if (p->devtyp == NULL) { smlFreeDevInfDevInf(p); return NULL; } p->datastore = smlAllocDevInfDatastoreList(); if (p->verdtd == NULL) { smlFreeDevInfDevInf(p); return NULL; } p->ctcap = smlAllocDevInfCtcapList(); if (p->ctcap == NULL) { smlFreeDevInfDevInf(p); return NULL; } p->ext = smlAllocDevInfExtList(); if (p->ext == NULL) { smlFreeDevInfDevInf(p); return NULL; } return p; } #endif // DevInf #endif // AllocFuncs libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/mgr/inc/000077500000000000000000000000001226375725500223565ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/mgr/inc/mgr.h000077500000000000000000000152651226375725500233300ustar00rootroot00000000000000/** * @file * SyncML internal API of the MGR module * * @target_system all * @target_os all * @description Definitions for internal use within the SyncML implementation */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ #ifndef _MGR_H #define _MGR_H /************************************************************************* * Definitions *************************************************************************/ #include #include #include "wsm.h" #include /** * ======================================== * Definitions used for Instance Management * ======================================== **/ /** * Current instance status */ typedef enum { MGR_IDLE, /**< instance is idle (available for usage by applications) */ MGR_USED, /**< instance is in use, but currently inactive */ MGR_RECEIVE, /**< actively used for receiving (locked by application) */ MGR_SEND, /**< actively used for sending (locked by application) */ MGR_ENCODING, /**< actively used for encoding (locked by SyncML) */ MGR_DECODING /**< actively used for decoding (locked by SyncML) */ } InstanceStatus_t; /** * structure describing the current status of an instance, */ typedef struct instance_info_s { #ifndef NOWSM InstanceID_t id; /**< unique ID of the instance */ MemPtr_t workspaceHandle; /**< handle to the first position of the assigned workspace memory */ #else // buffer pointers for NOWSM simplified case MemPtr_t instanceBuffer; /**< pointer to instance work buffer */ MemSize_t instanceBufSiz; /**< size of currently allocated buffer */ Byte_t readLocked; /**< set when buffer is locked for read */ Byte_t writeLocked; /**< set when buffer is locked for read */ MemPtr_t readPointer; /**< read pointer */ MemPtr_t writePointer; /**< write pointer */ MemPtr_t outgoingMsgStart; /**< set whenever a smlStartMessage is issued, NULL when invalid */ MemPtr_t incomingMsgStart; /**< set whenever mgrProcessStartMessage starts reading a message, NULL when invalid */ MemSize_t maxOutgoingSize; /**< if<>0, smlXXXCmd will not modify the buffer when there's not enough room */ #endif InstanceStatus_t status; /**< current internal state of instance */ SmlCallbacksPtr_t callbacks; /**< Defined callback refererences for this Instance */ SmlInstanceOptionsPtr_t instanceOptions; /**< Defined options for this Instance (e.g. encoding type) */ VoidPtr_t userData; /**< Pointer to a structure, which is passed to the invoked callback functions */ #ifndef NOWSM VoidPtr_t workspaceState; /**< Pointer to a structure defining the current workspace status */ #endif VoidPtr_t encoderState; /**< Pointer to a structure defining the current encoder status */ VoidPtr_t decoderState; /**< Pointer to a structure defining the current decoder status */ #ifndef NOWSM struct instance_info_s* nextInfo; /**< Pointer to next Instance Info in a list */ #else smlPrintFunc defaultPrintFunc; /**< default application callback for displaying strings (is a global in original version) */ #endif } *InstanceInfoPtr_t, InstanceInfo_t; /** Pointers to store the global Tag tables */ typedef struct tokeninfo_s { TagPtr_t SyncML; TagPtr_t MetInf; TagPtr_t DevInf; } *TokenInfoPtr_t, TokenInfo_t; #ifndef NOWSM // Note, version without WSM has NO globals at all /** * structure describing the current status of the global syncml module * (holds all global variables within SyncML) */ typedef struct syncml_info_s { InstanceInfoPtr_t instanceListAnchor;/**< Anchor of the global list of known SyncML instances */ SmlOptionsPtr_t syncmlOptions; /**< Options valid for this SyncML Process */ WsmGlobalsPtr_t wsmGlobals; /**< Workspace global variables */ TokenInfoPtr_t tokTbl; } *SyncMLInfoPtr_t, SyncMLInfo_t; /************************************************************************* * External Function Declarations *************************************************************************/ SyncMLInfoPtr_t mgrGetSyncMLAnchor(void) MGR_FUNC; InstanceInfoPtr_t mgrGetInstanceListAnchor(void) MGR_FUNC; void mgrSetInstanceListAnchor(InstanceInfoPtr_t newListAnchor) MGR_FUNC; #ifndef __SML_LITE__ /* these API calls are NOT included in the Toolkit lite version */ /* SyncML internal function prototypes */ Ret_t addInfo(InstanceInfoPtr_t pInfo) MGR_FUNC; InstanceInfoPtr_t findInfo(InstanceID_t id) MGR_FUNC; Ret_t removeInfo(InstanceID_t id) MGR_FUNC; #endif #endif // !defined(NOWSM) Ret_t mgrResetWorkspace (InstanceID_t id) MGR_FUNC; #endif // ifndef _MGR_H libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/mgr/inc/mgrutil.h000077500000000000000000000217231226375725500242220ustar00rootroot00000000000000/** * @file * SyncML API for freeing SyncML C structures * * @target_system all * @target_os all * @description Definitions for internal use within the SyncML implementation */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ #ifndef _MGR_UTIL_H #define _MGR_UTIL_H /* Prototypes of exported SyncML API functions */ SML_API Ret_t smlFreeProtoElement(VoidPtr_t pProtoElement) MGR_FUNC; SML_API void smlFreePcdata(SmlPcdataPtr_t pPcdata) MGR_FUNC; SML_API void smlFreePcdataList(SmlPcdataListPtr_t list) MGR_FUNC; SML_API void smlFreeSyncHdr(SmlSyncHdrPtr_t pSyncHdr) MGR_FUNC; SML_API void smlFreeSync(SmlSyncPtr_t pSync) MGR_FUNC; SML_API void smlFreeGeneric(SmlGenericCmdPtr_t pGenericCmd) MGR_FUNC; SML_API void smlFreeAlert(SmlAlertPtr_t pAlert) MGR_FUNC; SML_API void smlFreeAtomic(SmlAtomicPtr_t pAtomic) MGR_FUNC; #if (defined EXEC_SEND || defined EXEC_RECEIVE) SML_API void smlFreeExec(SmlExecPtr_t pExec) MGR_FUNC; #endif SML_API void smlFreeGetPut(SmlPutPtr_t pGetPut) MGR_FUNC; SML_API void smlFreeMap(SmlMapPtr_t pMap) MGR_FUNC; SML_API void smlFreeResults(SmlResultsPtr_t pResults) MGR_FUNC; #if (defined SEARCH_SEND || defined SEARCH_RECEIVE) SML_API void smlFreeSearch(SmlSearchPtr_t pSearch) MGR_FUNC; #endif SML_API void smlFreeStatus(SmlStatusPtr_t pStatus) MGR_FUNC; SML_API void smlFreeCredPtr(SmlCredPtr_t pCred) MGR_FUNC; SML_API void smlFreeChalPtr(SmlChalPtr_t pChal) MGR_FUNC; SML_API void smlFreeRecordFieldFilterPtr(SmlRecordOrFieldFilterPtr_t pRecordFieldFilter) MGR_FUNC; SML_API void smlFreeFilterPtr(SmlFilterPtr_t pFilter) MGR_FUNC; SML_API void smlFreeSourceTargetParentPtr(SmlSourceParentPtr_t pSourceTargetParent) MGR_FUNC; SML_API void smlFreeSourceTargetPtr(SmlSourcePtr_t pSourceTarget) MGR_FUNC; SML_API void smlFreeSourceList(SmlSourceListPtr_t pSourceList) MGR_FUNC; SML_API void smlFreeSourceRefList(SmlSourceRefListPtr_t pSourceRefList) MGR_FUNC; SML_API void smlFreeTargetRefList(SmlTargetRefListPtr_t pTargetRefList) MGR_FUNC; SML_API void smlFreeItemPtr(SmlItemPtr_t pItem) MGR_FUNC; SML_API void smlFreeItemList(SmlItemListPtr_t pItemList) MGR_FUNC; SML_API void smlFreeMapItemPtr(SmlMapItemPtr_t pMapItem) MGR_FUNC; SML_API void smlFreeMapItemList(SmlMapItemListPtr_t pMapItemList) MGR_FUNC; #ifdef __USE_METINF__ SML_API void smlFreeMetinfAnchor(SmlMetInfAnchorPtr_t data) MGR_FUNC; SML_API void smlFreeMetinfMem(SmlMetInfMemPtr_t data) MGR_FUNC; SML_API void smlFreeMetinfMetinf(SmlMetInfMetInfPtr_t data) MGR_FUNC; #endif #ifdef __USE_DEVINF__ SML_API void smlFreeDevInfDatastore(SmlDevInfDatastorePtr_t data) MGR_FUNC; SML_API void smlFreeDevInfDatastoreList(SmlDevInfDatastoreListPtr_t data) MGR_FUNC; SML_API void smlFreeDevInfXmitList(SmlDevInfXmitListPtr_t data) MGR_FUNC; SML_API void smlFreeDevInfXmit(SmlDevInfXmitPtr_t data) MGR_FUNC; SML_API void smlFreeDevInfDSMem(SmlDevInfDSMemPtr_t data) MGR_FUNC; SML_API void smlFreeDevInfSynccap(SmlDevInfSyncCapPtr_t data) MGR_FUNC; SML_API void smlFreeDevInfExt(SmlDevInfExtPtr_t data) MGR_FUNC; SML_API void smlFreeDevInfExtList(SmlDevInfExtListPtr_t data) MGR_FUNC; SML_API void smlFreeDevInfCTData(SmlDevInfCTDataPtr_t data) MGR_FUNC; SML_API void smlFreeDevInfCTDataList(SmlDevInfCTDataListPtr_t data) MGR_FUNC; SML_API void smlFreeDevInfCTDataProp(SmlDevInfCTDataPropPtr_t data) MGR_FUNC; SML_API void smlFreeDevInfCTDataPropList(SmlDevInfCTDataPropListPtr_t data) MGR_FUNC; SML_API void smlFreeDevInfCTCap(SmlDevInfCTCapPtr_t data) MGR_FUNC; SML_API void smlFreeDevInfCtcapList(SmlDevInfCtcapListPtr_t data) MGR_FUNC; SML_API void smlFreeDevInfFilterCap(SmlDevInfFilterCapPtr_t data) MGR_FUNC; SML_API void smlFreeDevInfFilterCapList(SmlDevInfFilterCapListPtr_t data) MGR_FUNC; SML_API void smlFreeDevInfDevInf(SmlDevInfDevInfPtr_t data) MGR_FUNC; #endif #ifndef __SML_LITE__ /* these API calls are NOT included in the Toolkit lite version */ SML_API String_t smlPcdata2String( SmlPcdataPtr_t pcdata ) MGR_FUNC; SML_API SmlPcdataPtr_t smlString2Pcdata( String_t str ) MGR_FUNC; SML_API SmlPcdataPtr_t smlPcdataDup(SmlPcdataPtr_t pcdata) MGR_FUNC; SML_API MemSize_t smlGetFreeBuffer(InstanceID_t id) MGR_FUNC; #endif #ifdef __USE_ALLOCFUNCS__ SML_API SmlPcdataPtr_t smlAllocPcdata() MGR_FUNC; SML_API SmlPcdataListPtr_t smlAllocPcdataList() MGR_FUNC; SML_API SmlChalPtr_t smlAllocChal() MGR_FUNC; SML_API SmlCredPtr_t smlAllocCred() MGR_FUNC; SML_API SmlRecordOrFieldFilterPtr_t smlAllocRecordFieldFilter() MGR_FUNC; SML_API SmlFilterPtr_t smlAllocFilter() MGR_FUNC; SML_API SmlSourceParentPtr_t smlAllocSourceParent() MGR_FUNC; SML_API SmlTargetParentPtr_t smlAllocTargetParent() MGR_FUNC; SML_API SmlSourcePtr_t smlAllocSource() MGR_FUNC; SML_API SmlTargetPtr_t smlAllocTarget() MGR_FUNC; SML_API SmlSourceListPtr_t smlAllocSourceList() MGR_FUNC; SML_API SmlSyncHdrPtr_t smlAllocSyncHdr() MGR_FUNC; SML_API SmlItemPtr_t smlAllocItem() MGR_FUNC; SML_API SmlItemListPtr_t smlAllocItemList() MGR_FUNC; SML_API SmlGenericCmdPtr_t smlAllocGeneric() MGR_FUNC; SML_API SmlAddPtr_t smlAllocAdd() MGR_FUNC; SML_API SmlCopyPtr_t smlAllocCopy() MGR_FUNC; SML_API SmlMovePtr_t smlAllocMove() MGR_FUNC; SML_API SmlReplacePtr_t smlAllocReplace() MGR_FUNC; SML_API SmlDeletePtr_t smlAllocDelete() MGR_FUNC; SML_API SmlAlertPtr_t smlAllocAlert() MGR_FUNC; SML_API SmlAtomicPtr_t smlAllocAtomic() MGR_FUNC; SML_API SmlSequencePtr_t smlAllocSequence() MGR_FUNC; SML_API SmlSyncPtr_t smlAllocSync() MGR_FUNC; SML_API SmlExecPtr_t smlAllocExec() MGR_FUNC; SML_API SmlGetPtr_t smlAllocGet() MGR_FUNC; SML_API SmlPutPtr_t smlAllocPut() MGR_FUNC; SML_API SmlMapItemPtr_t smlAllocMapItem() MGR_FUNC; SML_API SmlMapItemListPtr_t smlAllocMapItemList() MGR_FUNC; SML_API SmlMapPtr_t smlAllocMap() MGR_FUNC; SML_API SmlResultsPtr_t smlAllocResults() MGR_FUNC; SML_API SmlSearchPtr_t smlAllocSearch() MGR_FUNC; SML_API SmlTargetRefListPtr_t smlAllocTargetRefList() MGR_FUNC; SML_API SmlSourceRefListPtr_t smlAllocSourceRefList() MGR_FUNC; SML_API SmlStatusPtr_t smlAllocStatus() MGR_FUNC; SML_API SmlUnknownProtoElementPtr_t smlAllocUnknownProtoElement() MGR_FUNC; #ifdef __USE_METINF__ SML_API SmlMetInfMetInfPtr_t smlAllocMetInfMetInf() MGR_FUNC; SML_API SmlMetInfAnchorPtr_t smlAllocMetInfAnchor() MGR_FUNC; SML_API SmlMetInfMemPtr_t smlAllocMetInfMem() MGR_FUNC; #endif // MetInf #ifdef __USE_DEVINF__ SML_API SmlDevInfExtPtr_t smlAllocDevInfExt() MGR_FUNC; SML_API SmlDevInfExtListPtr_t smlAllocDevInfExtList() MGR_FUNC; SML_API SmlDevInfSyncCapPtr_t smlAllocDevInfSyncCap() MGR_FUNC; SML_API SmlDevInfCTDataPtr_t smlAllocDevInfCTData() MGR_FUNC; SML_API SmlDevInfCTDataListPtr_t smlAllocDevInfCTDataList() MGR_FUNC; SML_API SmlDevInfCTDataPropPtr_t smlAllocDevInfCTDataProp() MGR_FUNC; SML_API SmlDevInfCTDataPropListPtr_t smlAllocDevInfCTDataPropList() MGR_FUNC; SML_API SmlDevInfCTCapPtr_t smlAllocDevInfCTCap() MGR_FUNC; SML_API SmlDevInfCtcapListPtr_t smlAllocDevInfCtcapList() MGR_FUNC; SML_API SmlDevInfDSMemPtr_t smlAllocDevInfDSMem() MGR_FUNC; SML_API SmlDevInfXmitPtr_t smlAllocDevInfXmit() MGR_FUNC; SML_API SmlDevInfXmitListPtr_t smlAllocDevInfXmitList() MGR_FUNC; SML_API SmlDevInfDatastorePtr_t smlAllocDevInfDatastore() MGR_FUNC; SML_API SmlDevInfDatastoreListPtr_t smlAllocDevInfDatastoreList() MGR_FUNC; SML_API SmlDevInfDevInfPtr_t smlAllocDevInfDevInf() MGR_FUNC; #endif // DevInf #endif // AllocFuncs #endif // MgrUtil.h libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/mgr/win/000077500000000000000000000000001226375725500224025ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/mgr/win/libinit.c000077500000000000000000000062301226375725500242040ustar00rootroot00000000000000/** * @file * Managing DLL * * @target_system Windows * @target_os Windows 9x/NT * @description Platform dependant DLL-entry-function */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ /************************************************************************* * Definitions *************************************************************************/ #include "syncml_tk_prefix_file.h" // %%% luz: needed for precompiled headers in eVC++ #define WIN32_LEAN_AND_MEAN #include #undef WIN32_LEAN_AND_MEAN #include /* SyncML internal function prototypes */ BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved); /** * This routine is called by the Mingw32, Cygwin32 or VC++ C run * time library init code, or the Borland DllEntryPoint routine. It * is responsible for initializing various dynamically loaded * libraries. * * @param hInst (IN) * Library instance handle. * @param reason (IN) * Reason this function is being called. * @param reserved (IN) * Not used. * @return TRUE on sucess,\n * FALSE on failure. */ BOOL APIENTRY DllMain(HINSTANCE hInst, DWORD reason, LPVOID reserved) { switch (reason) { case DLL_PROCESS_ATTACH: break; case DLL_PROCESS_DETACH: break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; } return TRUE; } libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/wsm/000077500000000000000000000000001226375725500216265ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/wsm/all/000077500000000000000000000000001226375725500223765ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/wsm/all/wsm.c000077500000000000000000000772511226375725500233670ustar00rootroot00000000000000/** * @file * SyncML WorkSpace Manager * * @target_system All * @target_os All * @description Workspace Manager API * Manages the SyncML document in memory. */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ #include "syncml_tk_prefix_file.h" #ifndef NOWSM // if no WSM, we can leave this one out completely /*************************************************************************/ /* Definitions */ /*************************************************************************/ #include "wsm.h" #include "wsm_sm.h" #include "smldef.h" #include "libmem.h" #include "libstr.h" #include "liblock.h" // for THREADDEBUGPRINTF %%% luz #include "mgr.h" // for global anchor /** WSM buffer flags */ #define WSM_VALID_F (Byte_t) 0x01 #define WSM_LOCKED_F (Byte_t) 0x02 #define WSM_MEMH_UNUSED -1 #ifndef __SML_LITE__ /* Global Vars */ /* =========== */ /* defines for convient use of global anchor */ #define wsmRet (mgrGetSyncMLAnchor())->wsmGlobals->wsmRet #define initWasCalled (mgrGetSyncMLAnchor())->wsmGlobals->initWasCalled #define maxWsmAvailMem (mgrGetSyncMLAnchor())->syncmlOptions->maxWorkspaceAvailMem #define wsmBuf (mgrGetSyncMLAnchor())->wsmGlobals->wsmBuf #define wsmIndex (mgrGetSyncMLAnchor())->wsmGlobals->wsmIndex void createDataStructs(void); void createDataStructs() { if ( (mgrGetSyncMLAnchor())->wsmGlobals == NULL ) { if ( ((mgrGetSyncMLAnchor())->wsmGlobals=smlLibMalloc(sizeof(WsmGlobals_t))) == 0 ) { return; } smlLibMemset((mgrGetSyncMLAnchor())->wsmGlobals, 0, sizeof(WsmGlobals_t)); wsmRet = 0; initWasCalled = 0; wsmIndex = 0; #ifdef __ANSI_C__ (mgrGetSyncMLAnchor())->wsmGlobals->wsmSm = NULL; #endif #ifdef __PALM_OS__ (mgrGetSyncMLAnchor())->wsmGlobals->wsmSm.smMemH = 0; (mgrGetSyncMLAnchor())->wsmGlobals->wsmSm.smLocked = 0; #endif #ifdef __EPOC_OS__ (mgrGetSyncMLAnchor())->wsmGlobals->wsmSm = NULL; #endif } } #define freeDataStructs() smlLibFree((mgrGetSyncMLAnchor())->wsmGlobals) /* private functions prototypes */ static Short_t getNextFreeEntry(); static Short_t lookup(MemHandle_t memH); static MemHandle_t nameToHandle(String_t name); static Short_t deleteBufferHandle(MemHandle_t memH); static Short_t resetBufferGlobals(MemHandle_t memH); static Byte_t isValidMemH(MemHandle_t memH); static Byte_t isLockedMemH(MemHandle_t memH); static Byte_t isMemAvailable(MemSize_t memToAlloc); /*************************************************************************/ /* Internal Functions */ /*************************************************************************/ /** * Get next free buffer entry. * Returns index of next free entry, or -1 if buffer table is full. */ static Short_t getNextFreeEntry() { Short_t i; for ( i=0; i < MAX_WSM_BUFFERS; ++i ) if ( wsmBuf[i].memH == WSM_MEMH_UNUSED ) return i; return -1; } /** * Get buffer table index for memH. * Returns -1 if memH not found. */ static Short_t lookup(MemHandle_t memH) { Short_t i; // first check cache if ( wsmBuf[wsmIndex].memH == memH ) return wsmIndex; // search through buffer for ( i=0; (i < MAX_WSM_BUFFERS) && (wsmBuf[i].memH != memH); ++i ) ; if ( i < MAX_WSM_BUFFERS ) { wsmIndex = i; return i; } else { return -1; // memH not found } } /** * Find memory handle corresponding to name. * Return WSM_MEMH_UNUSED, if name not found in wsmBuf. */ static MemHandle_t nameToHandle(String_t name) { int i; // first check cache if ( (wsmBuf[wsmIndex].bufName != NULL) && (smlLibStrcmp(wsmBuf[wsmIndex].bufName, name) == 0) ) return wsmBuf[wsmIndex].memH; // search through buffer for ( i=0; ((i < MAX_WSM_BUFFERS) && (wsmBuf[i].bufName == NULL ? 1 : smlLibStrcmp(wsmBuf[i].bufName, name) != 0)); ++i ) ; if ( i < MAX_WSM_BUFFERS ) return wsmBuf[i].memH; else { return WSM_MEMH_UNUSED; // name not found } } /** * Delete memory handle from buffer. * Return -1, if handle not found. */ static Short_t deleteBufferHandle(MemHandle_t memH) { if ( (wsmIndex = lookup(memH)) < 0 ) return -1; // handle not found // reset the values wsmBuf[wsmIndex].memH = WSM_MEMH_UNUSED; wsmBuf[wsmIndex].pFirstFree = NULL; wsmBuf[wsmIndex].pFirstData = NULL; wsmBuf[wsmIndex].size = 0; wsmBuf[wsmIndex].usedBytes = 0; //wsmBuf[wsmIndex].flags = ~WSM_VALID_F; wsmBuf[wsmIndex].flags = ((Byte_t) ~WSM_VALID_F); smlLibFree(wsmBuf[wsmIndex].bufName); // free mem wsmBuf[wsmIndex].bufName = NULL; return 0; } /** * Reset values in buffer table for entry memH. * If memH doesn't exist create an entry. * Return index to memH in buffer table, * or -1 if table is full */ static Short_t resetBufferGlobals(MemHandle_t memH) { if ( (wsmIndex = lookup(memH)) < 0 ) { // create new one if ( (wsmIndex = getNextFreeEntry()) < 0 ) return -1; // buffer table full wsmBuf[wsmIndex].memH = memH; } else // use existing one, which has to be reset prior usage smlLibFree(wsmBuf[wsmIndex].bufName); // free mem // reset the values wsmBuf[wsmIndex].pFirstFree = NULL; wsmBuf[wsmIndex].pFirstData = NULL; wsmBuf[wsmIndex].size = 0; wsmBuf[wsmIndex].usedBytes = 0; wsmBuf[wsmIndex].flags = WSM_VALID_F; wsmBuf[wsmIndex].bufName = NULL; return wsmIndex; } static Byte_t isValidMemH(MemHandle_t memH) { return (Byte_t) (wsmBuf[lookup(memH)].flags & WSM_VALID_F); } static Byte_t isLockedMemH(MemHandle_t memH) { return (Byte_t) (wsmBuf[lookup(memH)].flags & WSM_LOCKED_F); } static Byte_t isMemAvailable(MemSize_t memToAlloc) { int i; MemSize_t actMem = memToAlloc; if ( maxWsmAvailMem == 0 ) return 1; // no memsize restrictions for (i=0; i < MAX_WSM_BUFFERS; ++i) { if ( wsmBuf[i].memH != WSM_MEMH_UNUSED ) actMem += wsmBuf[i].size; } return ((Byte_t)(actMem <= maxWsmAvailMem)); } /*************************************************************************/ /* External Functions */ /*************************************************************************/ /** * Initializes all Workspace Manager related resources. * Should only be called once! * * @pre This is the first function call to WSM * @post All WSM resources are initialized * @param wsmOpts (IN) * WSM options, valid options are: * - maxAvailMem\n * Maximal amount of memory which wsm can use for the buffers.\n * 0 == no limitation * @return * - SML_ERR_OK, if O.K. * - SML_ERR_INVALID_OPTIONS, if wsmOpts is not valid * - SML_ERR_NOT_ENOUGH_SPACE, if not enough available memory * - SML_ERR_WRONG_USAGE, if wsmInit was already called */ Ret_t wsmInit (const WsmOptions_t *wsmOpts) { int i; // create global datastructs createDataStructs(); if (NULL == mgrGetSyncMLAnchor()->wsmGlobals) { return SML_ERR_NOT_ENOUGH_SPACE; } // check if init was already called if ( initWasCalled ) return SML_ERR_WRONG_USAGE; // check options if ( wsmOpts != NULL ) { if ( wsmOpts->maxAvailMem > 0 ) { maxWsmAvailMem = wsmOpts->maxAvailMem; } } // init resources for ( i=0; i < MAX_WSM_BUFFERS; ++i ) wsmBuf[i].memH = WSM_MEMH_UNUSED; wsmIndex = 0; initWasCalled = (Byte_t) 1; return wsmRet=SML_ERR_OK; } /** * Creates and opens a new buffer with name bufName and size bufSize. * If a buffer with name bufName already exists, the existing buffer * is resized to bufSize. * * @pre bufSize > 0 * @post * - handle refers to buffer bufName * - BufferSize = size * @param bufName (IN) * Name of buffer to be created * @param bufSize (IN) * Size of buffer to be created * @param wsmH (OUT) * Handle to new buffer * @return * - SML_ERR_OK, if O.K. * - SML_ERR_INVALID_SIZE, if bufSize <= 0 * - SML_ERR_NOT_ENOUGH_SPACE, if available memory < bufSize * - SML_ERR_WSM_BUF_TABLE_FULL, if buffer table is full * - SML_ERR_WRONG_USAGE, if wsmInit wasn't called before * @see wsmDestroy */ Ret_t wsmCreate (String_t bufName, MemSize_t bufSize, MemHandle_t *wsmH) { *wsmH = 0; // 0 in case of error if ( ! initWasCalled ) return SML_ERR_WRONG_USAGE; // check buffer space if ( getNextFreeEntry() == -1 ) { return wsmRet=SML_ERR_WSM_BUF_TABLE_FULL; } // check for maxMemAvailable if ( ! isMemAvailable(bufSize) ) { return SML_ERR_NOT_ENOUGH_SPACE; } // create buffer if ( (wsmRet = smCreate(bufName, bufSize, wsmH)) != SML_ERR_OK ) { if ( wsmRet == SML_ERR_WRONG_USAGE ) { // buffer already exists // resize existing buffer // open buffer if ( (wsmRet = smOpen(bufName, wsmH)) != SML_ERR_OK ) { return wsmRet=SML_ERR_NOT_ENOUGH_SPACE; } // resize buffer if ( (wsmRet = smSetSize(*wsmH, bufSize)) != SML_ERR_OK ) { return wsmRet=SML_ERR_NOT_ENOUGH_SPACE; } } else { return wsmRet; } } // reset buffer vars wsmIndex = resetBufferGlobals(*wsmH); // set buffer vars wsmBuf[wsmIndex].size = bufSize; wsmBuf[wsmIndex].bufName = smlLibStrdup(bufName); if (wsmBuf[wsmIndex].bufName == NULL) { smClose(*wsmH); smDestroy(bufName); return wsmRet=SML_ERR_NOT_ENOUGH_SPACE; } return wsmRet=SML_ERR_OK; } /** * Open existing buffer with name bufName. * * @pre WSM knows bufName * @post wsmH refers to buffer bufName * @param bufName (IN) * Name of buffer to be opened * @param wsmH (OUT) * Handle to new buffer (OUT) * @return * - SML_ERR_OK, if O.K. * - SML_WRONG_PARAM, if bufName is unknown * @see wsmClose */ Ret_t wsmOpen (String_t bufName, MemHandle_t *wsmH){ // open buffer if ( (wsmRet = smOpen(bufName, wsmH)) != SML_ERR_OK ) { return wsmRet; } // reset buffer vars wsmIndex = resetBufferGlobals(*wsmH); // set buf vars wsmRet = smGetSize(*wsmH, &wsmBuf[wsmIndex].size); wsmBuf[wsmIndex].bufName = smlLibStrdup(bufName); return wsmRet=SML_ERR_OK; } /** * Close an open buffer. * * @pre * - handle is valid * - handle is unlocked * @post handle is not known to WSM any more * @param wsmH (IN) * Handle to the open buffer * @return * - SML_ERR_OK, if O.K. * - SML_ERR_INVALID_HANDLE, if handle was invalid * - SML_ERR_WRONG_USAGE, if handle was still locked * @see wsmOpen */ Ret_t wsmClose (MemHandle_t wsmH) { // check if handle is invalid if ( ! isValidMemH(wsmH) ) { return wsmRet=SML_ERR_INVALID_HANDLE; } // close handle if ( (wsmRet = smClose(wsmH)) != SML_ERR_OK ) { return wsmRet; } wsmRet = deleteBufferHandle(wsmH); return wsmRet=SML_ERR_OK; } /** * Destroy existing buffer with name bufName. * * @pre * - WSM knows bufName * - handle is unlocked * @post * - buffer is not known to WSM any more * - all resources connected to this buffer are freed * @param bufName (IN) * Name of buffer to be opened * @return * - SML_ERR_OK, if O.K. * - SML_ERR_WRONG_PARAM, if bufName is unknown to WSM * - SML_ERR_WRONG_USAGE, if handle was still locked * @see wsmCreate */ Ret_t wsmDestroy (String_t bufName) { // free resources if ( (wsmRet = wsmClose(nameToHandle(bufName))) != SML_ERR_OK ) { return wsmRet; } // free buffer if ( (wsmRet = smDestroy(bufName)) != SML_ERR_OK ) { return wsmRet; } return wsmRet=SML_ERR_OK; } /** * Terminate WSM; free all buffers and resources. * * @pre all handles must be unlocked * @post all resources are freed * @return * - SML_ERR_OK, if O.K. * - SML_ERR_WRONG_USAGE, if a handle was still locked */ Ret_t wsmTerminate (void) { int i; // free all WSM resources for (i=0; i < MAX_WSM_BUFFERS; ++i) { if ( wsmBuf[i].memH != WSM_MEMH_UNUSED ) if ( wsmDestroy(wsmBuf[i].bufName) == SML_ERR_WRONG_USAGE ) { return SML_ERR_WRONG_USAGE; } } // free global DataStructs freeDataStructs(); return SML_ERR_OK; } /** * Tell Workspace Manager the number of bytes already processed. * * @pre * - handle is locked * - handle is valid * - noBytes <= wsmGetUsedSize * @post * - noBytes starting at wsmGetPtr() position are deleted; * - remaining bytes are copied to wsmGetPtr(SML_FIRST_FREE_ITEM) position * - wsmGetUsedSize -= noBytes * - wsmGetFreeSize += noBytes * @param wsmH (IN) * Handle to the open buffer * @param noBytes (IN) * Number of bytes already processed from buffer. * @return * - SML_ERR_OK, if O.K. * - SML_ERR_INVALID_HANDLE, if handle was invalid * - SML_ERR_WRONG_USAGE, if handle was not locked * - SML_ERR_INVALID_SIZE, if noBytes > wsmGetUsedSize * @see wsmGetFreeSize */ Ret_t wsmProcessedBytes (MemHandle_t wsmH, MemSize_t noBytes) { // check if handle is invalid if ( ! isValidMemH(wsmH) ) { return wsmRet=SML_ERR_INVALID_HANDLE; } // check if handle is unlocked if ( ! isLockedMemH(wsmH) ) { return wsmRet=SML_ERR_WRONG_USAGE; } wsmIndex = lookup(wsmH); if ( noBytes > wsmBuf[wsmIndex].usedBytes ) { return wsmRet=SML_ERR_INVALID_SIZE; } // adapt usedSize wsmBuf[wsmIndex].usedBytes -= noBytes; // move memory // check return ????? smlLibMemmove(wsmBuf[wsmIndex].pFirstData, (wsmBuf[wsmIndex].pFirstData + noBytes), wsmBuf[wsmIndex].usedBytes); // move pFirstFree wsmBuf[wsmIndex].pFirstFree -= noBytes; return wsmRet=SML_ERR_OK; } /** * Locks handle wsmH and get a pointer to the contents of wsmH. * RequestedPos describes the position in the buffer to which the returned * pointer should point. Valid values are: * - SML_FIRST_DATA_ITEM * - SML_FIRST_FREE_ITEM * * @pre * - handle is unlocked * - handle is valid * @post * - handle is locked * - points to first data item, or first free item. * @param wsmH (IN) * Handle to the open buffer * @param requestedPos (IN) * Requested position of the returned pointer * - SML_FIRST_DATA_ITEM : points to first data entry * - SML_FIRST_FREE_ITEM : points to first free entry * @param pMem (OUT) * Pointer to requested memory * @return * - SML_ERR_OK, if O.K. * - SML_ERR_INVALID_HANDLE, if handle was invalid * - SML_ERR_WRONG_USAGE, if handle was still locked * - SML_ERR_UNSPECIFIC, if requested position is unknown, or lock failed * @see wsmUnlockH */ Ret_t wsmLockH (MemHandle_t wsmH, SmlBufPtrPos_t requestedPos, MemPtr_t *pMem) { // check if handle is invalid if ( ! isValidMemH(wsmH) ) { return wsmRet=SML_ERR_INVALID_HANDLE; } // check if handle is locked if ( isLockedMemH(wsmH) ) { return wsmRet=SML_ERR_WRONG_USAGE; } // lock if ( (wsmRet = smLock(wsmH, pMem)) != SML_ERR_OK ) { return wsmRet=SML_ERR_UNSPECIFIC; } // set local pointers wsmIndex = lookup(wsmH); wsmBuf[wsmIndex].pFirstData = *pMem; wsmBuf[wsmIndex].pFirstFree = *pMem + wsmBuf[wsmIndex].usedBytes; wsmBuf[wsmIndex].flags |= WSM_LOCKED_F; switch (requestedPos) { case SML_FIRST_DATA_ITEM: *pMem = wsmBuf[wsmIndex].pFirstData; break; case SML_FIRST_FREE_ITEM: *pMem = wsmBuf[wsmIndex].pFirstFree; break; default: return wsmRet=SML_ERR_UNSPECIFIC; } return wsmRet=SML_ERR_OK; } /** * Returns the remaining unused bytes in the buffer. * * @pre handle is valid * @post wsmGetFreeSize = BufferSize - wsmGetUsedSize * @param wsmH (IN) * Handle to the open buffer * @param freeSize (OUT) * Number of bytes which are unused in this buffer * @return * - SML_ERR_OK, if O.K. * - SML_ERR_INVALID_HANDLE, if handle was invalid * @see wsmGetUsedSize, wsmProcessedBytes */ Ret_t wsmGetFreeSize(MemHandle_t wsmH, MemSize_t *freeSize) { // check if handle is invalid if ( ! isValidMemH(wsmH) ) { return wsmRet=SML_ERR_INVALID_HANDLE; } wsmIndex = lookup(wsmH); *freeSize = wsmBuf[wsmIndex].size - wsmBuf[wsmIndex].usedBytes; return wsmRet=SML_ERR_OK; } /** * Returns the number of bytes used in the buffer. * * @pre handle is valid * @post usedSize = BufferSize - wsmGetFreeSize * @param wsmH (IN) * Handle to the open buffer * @param usedSize (OUT) * Number of bytes which are already used in this buffer * @return * - SML_ERR_OK, if O.K. * - SML_ERR_INVALID_HANDLE, if handle was invalid * @see wsmGetFreeSize, wsmSetUsedSize */ Ret_t wsmGetUsedSize(MemHandle_t wsmH, MemSize_t *usedSize) { // check if handle is invalid if ( ! isValidMemH(wsmH) ) { return wsmRet=SML_ERR_INVALID_HANDLE; } wsmIndex = lookup(wsmH); *usedSize = wsmBuf[wsmIndex].usedBytes; return wsmRet=SML_ERR_OK; } /** * Unlock handle wsmH. * After this call all pointers to this memory handle are invalid * and should no longer be used. * * @pre * - handle is locked * - handle is valid * @post handle is unlocked * @param wsmH Handle to unlock (OUT) * @return * - SML_ERR_OK, if O.K. * - SML_ERR_INVALID_HANDLE, if handle was invalid * - SML_ERR_WRONG_USAGE, if handle was not locked * - SML_ERR_UNSPECIFIC, unlock failed * @see wsmLockH */ Ret_t wsmUnlockH (MemHandle_t wsmH) { // check if handle is invalid if ( ! isValidMemH(wsmH) ) { return wsmRet=SML_ERR_INVALID_HANDLE; } // check if handle is already unlocked if ( ! isLockedMemH(wsmH) ) { return wsmRet=SML_ERR_WRONG_USAGE; } // unlock if ( (wsmRet = smUnlock(wsmH)) != SML_ERR_OK ) { return wsmRet=SML_ERR_UNSPECIFIC; } // set local pointers wsmIndex = lookup(wsmH); wsmBuf[wsmIndex].pFirstData = NULL; wsmBuf[wsmIndex].pFirstFree = NULL; wsmBuf[wsmIndex].flags &= ~WSM_LOCKED_F; return wsmRet=SML_ERR_OK; } /** * Tell Workspace how many data were written into buffer. * * @pre * - handle is valid * - usedSize <= wsmGetFreeSize * - handle is locked * @post * - wsmGetUsedSize += usedSize * - wsmGetFreeSize -= usedSize * - instancePtr += usedSize * @param wsmH (IN) * Handle to the open buffer * @param usedSize (IN) * Number of bytes which were written into buffer * @return * - SML_ERR_OK, if O.K. * - SML_ERR_INVALID_HANDLE, if handle was invalid * - SML_ERR_INVALID_SIZE, if usedSize <= wsmGetFreeSize * @see wsmGetUsedSize */ Ret_t wsmSetUsedSize (MemHandle_t wsmH, MemSize_t usedSize) { // check if handle is invalid if ( ! isValidMemH(wsmH) ) { return wsmRet=SML_ERR_INVALID_HANDLE; } // check if handle is unlocked if ( ! isLockedMemH(wsmH) ) { return wsmRet=SML_ERR_WRONG_USAGE; } wsmIndex = lookup(wsmH); // usedSize > freeSize? if ( usedSize > (wsmBuf[wsmIndex].size - wsmBuf[wsmIndex].usedBytes) ) { return wsmRet=SML_ERR_INVALID_SIZE; } // adapt usedSize wsmBuf[wsmIndex].usedBytes += usedSize; // move pFirstFree wsmBuf[wsmIndex].pFirstFree += usedSize; return wsmRet=SML_ERR_OK; } /** * Reset the Workspace * * @post all data is lost. The FirstFree Position equals * the First Data position * @param wsmH (IN) * Handle to the open buffer * @return * - SML_ERR_OK, if O.K. */ Ret_t wsmReset (MemHandle_t wsmH) { wsmIndex = lookup(wsmH); wsmBuf[wsmIndex].pFirstFree = wsmBuf[wsmIndex].pFirstFree - wsmBuf[wsmIndex].usedBytes ; wsmBuf[wsmIndex].pFirstData = wsmBuf[wsmIndex].pFirstFree; wsmBuf[wsmIndex].usedBytes = 0; return SML_ERR_OK; } /*======================================================================================*/ #else /* WSM_LITE Version - uses only one buffer*/ /*======================================================================================*/ /* Global Vars */ /* =========== */ /* defines for convient use of global anchor */ #define wsmRet (mgrGetSyncMLAnchor())->wsmGlobals->wsmRet #define initWasCalled (mgrGetSyncMLAnchor())->wsmGlobals->initWasCalled #define maxWsmAvailMem (mgrGetSyncMLAnchor())->syncmlOptions->maxWorkspaceAvailMem #define wsmBuf (mgrGetSyncMLAnchor())->wsmGlobals->wsmBuf #define wsmIndex (mgrGetSyncMLAnchor())->wsmGlobals->wsmIndex void createDataStructs(void); void createDataStructs() { if ( (mgrGetSyncMLAnchor())->wsmGlobals == NULL ) { if ( ((mgrGetSyncMLAnchor())->wsmGlobals=smlLibMalloc(sizeof(WsmGlobals_t))) == 0 ) { return; } wsmRet = 0; initWasCalled = 0; wsmIndex = 0; #ifdef __ANSI_C__ (mgrGetSyncMLAnchor())->wsmGlobals->wsmSm = NULL; #endif #ifdef __PALM_OS__ (mgrGetSyncMLAnchor())->wsmGlobals->wsmSm.smMemH = 0; (mgrGetSyncMLAnchor())->wsmGlobals->wsmSm.smLocked = 0; #endif #ifdef __EPOC_OS__ (mgrGetSyncMLAnchor())->wsmGlobals->wsmSm = NULL; #endif } } #define freeDataStructs() smlLibFree((mgrGetSyncMLAnchor())->wsmGlobals) /* private functions prototypes */ static Short_t getNextFreeEntry(); static Short_t deleteBufferHandle(MemHandle_t memH); static Short_t resetBufferGlobals(MemHandle_t memH); static Byte_t isMemAvailable(MemSize_t memToAlloc); /*************************************************************************/ /* Internal Functions */ /*************************************************************************/ /** * Delete memory handle from buffer. * Return -1, if handle not found. */ static Short_t deleteBufferHandle(MemHandle_t memH) { // reset the values wsmBuf[0].memH = WSM_MEMH_UNUSED; wsmBuf[0].pFirstFree = NULL; wsmBuf[0].pFirstData = NULL; wsmBuf[0].size = 0; wsmBuf[0].usedBytes = 0; wsmBuf[0].flags = ~WSM_VALID_F; smlLibFree(wsmBuf[0].bufName); // free mem wsmBuf[0].bufName = NULL; return 0; } /** * Reset values in buffer table for entry memH. * If memH doesn't exist create an entry. * Return index to memH in buffer table, * or -1 if table is full */ static Short_t resetBufferGlobals(MemHandle_t memH) { if ( (wsmBuf[0].memH != memH) && (wsmBuf[0].memH == WSM_MEMH_UNUSED)) { // create new one wsmBuf[0].memH = memH; } else { // use existing one, which has to be reset prior usage smlLibFree(wsmBuf[0].bufName); // free mem } // reset the values wsmBuf[0].pFirstFree = NULL; wsmBuf[0].pFirstData = NULL; wsmBuf[0].size = 0; wsmBuf[0].usedBytes = 0; wsmBuf[0].flags = WSM_VALID_F; wsmBuf[0].bufName = NULL; return 0; } static Byte_t isMemAvailable(MemSize_t memToAlloc) { MemSize_t actMem = memToAlloc; if ( maxWsmAvailMem == 0 ) return 1; // no memsize restrictions if ( wsmBuf[0].memH != WSM_MEMH_UNUSED ) actMem += wsmBuf[0].size; return (actMem <= maxWsmAvailMem); } /*************************************************************************/ /* External Functions */ /*************************************************************************/ Ret_t wsmInit (const WsmOptions_t *wsmOpts) { // create global datastructs createDataStructs(); if (NULL == mgrGetSyncMLAnchor()->wsmGlobals) { return SML_ERR_NOT_ENOUGH_SPACE; } // check if init was already called if ( initWasCalled ) return SML_ERR_WRONG_USAGE; // check options if ( wsmOpts != NULL ) { if ( wsmOpts->maxAvailMem > 0 ) { maxWsmAvailMem = wsmOpts->maxAvailMem; } } // init resources wsmBuf[0].memH = WSM_MEMH_UNUSED; wsmIndex = 0; initWasCalled = (Byte_t) 1; return wsmRet=SML_ERR_OK; } Ret_t wsmCreate (String_t bufName, MemSize_t bufSize, MemHandle_t *wsmH) { *wsmH = 0; // 0 in case of error if ( ! initWasCalled ) return SML_ERR_WRONG_USAGE; // check buffer space if ( wsmBuf[0].memH != WSM_MEMH_UNUSED ) { return wsmRet=SML_ERR_WSM_BUF_TABLE_FULL; } // check for maxMemAvailable if ( ! isMemAvailable(bufSize) ) { return SML_ERR_NOT_ENOUGH_SPACE; } // create buffer if ( (wsmRet = smCreate(bufName, bufSize, wsmH)) != SML_ERR_OK ) { if ( wsmRet == SML_ERR_WRONG_USAGE ) { // buffer already exists // resize existing buffer // open buffer if ( (wsmRet = smOpen(bufName, wsmH)) != SML_ERR_OK ) { return wsmRet=SML_ERR_NOT_ENOUGH_SPACE; } // resize buffer if ( (wsmRet = smSetSize(*wsmH, bufSize)) != SML_ERR_OK ) { return wsmRet=SML_ERR_NOT_ENOUGH_SPACE; } } else { return wsmRet; } } // reset buffer vars resetBufferGlobals(*wsmH); // set buffer vars wsmBuf[0].size = bufSize; wsmBuf[0].bufName = smlLibStrdup(bufName); return wsmRet=SML_ERR_OK; } Ret_t wsmOpen (String_t bufName, MemHandle_t *wsmH){ // open buffer if ( (wsmRet = smOpen(bufName, wsmH)) != SML_ERR_OK ) { return wsmRet; } // reset buffer vars resetBufferGlobals(*wsmH); // set buf vars wsmRet = smGetSize(*wsmH, &wsmBuf[0].size); wsmBuf[0].bufName = smlLibStrdup(bufName); return wsmRet=SML_ERR_OK; } Ret_t wsmClose (MemHandle_t wsmH) { // check if handle is invalid // must be buffer 0, as only this one exists if ( ! ((wsmBuf[0].memH == wsmH) || (wsmBuf[0].flags & WSM_VALID_F)) ) { return wsmRet=SML_ERR_INVALID_HANDLE; } // close handle if ( (wsmRet = smClose(wsmH)) != SML_ERR_OK ) { return wsmRet; } wsmRet = deleteBufferHandle(wsmH); return wsmRet=SML_ERR_OK; } Ret_t wsmDestroy (String_t bufName) { // free resources if ( (wsmRet = wsmClose(wsmBuf[0].memH)) != SML_ERR_OK ) { return wsmRet; } // free buffer if ( (wsmRet = smDestroy(bufName)) != SML_ERR_OK ) { return wsmRet; } return wsmRet=SML_ERR_OK; } Ret_t wsmTerminate () { int i; // free all WSM resources for (i=0; i < MAX_WSM_BUFFERS; ++i) { if ( wsmBuf[i].memH != WSM_MEMH_UNUSED ) if ( wsmDestroy(wsmBuf[i].bufName) == SML_ERR_WRONG_USAGE ) { return SML_ERR_WRONG_USAGE; } } // free global DataStructs freeDataStructs(); return SML_ERR_OK; } Ret_t wsmProcessedBytes (MemHandle_t wsmH, MemSize_t noBytes) { // check if handle is invalid // must be buffer 0, as only this one exists if ( ! ((wsmBuf[0].memH == wsmH) || (wsmBuf[0].flags & WSM_VALID_F)) ) { return wsmRet=SML_ERR_INVALID_HANDLE; } // check if handle is unlocked // must be buffer 0, as only this one exists if ( ! ((wsmBuf[0].memH == wsmH) || (wsmBuf[0].flags & WSM_LOCKED_F)) ) { return wsmRet=SML_ERR_WRONG_USAGE; } if ( noBytes > wsmBuf[0].usedBytes ) { return wsmRet=SML_ERR_INVALID_SIZE; } // adapt usedSize wsmBuf[0].usedBytes -= noBytes; // move memory // check return ????? smlLibMemmove(wsmBuf[0].pFirstData, (wsmBuf[0].pFirstData + noBytes), wsmBuf[0].usedBytes); // move pFirstFree wsmBuf[0].pFirstFree -= noBytes; return wsmRet=SML_ERR_OK; } Ret_t wsmLockH (MemHandle_t wsmH, SmlBufPtrPos_t requestedPos, MemPtr_t *pMem) { // check if handle is invalid // must be buffer 0, as only this one exists if ( ! ((wsmBuf[0].memH == wsmH) || (wsmBuf[0].flags & WSM_VALID_F)) ) { return wsmRet=SML_ERR_INVALID_HANDLE; } // check if handle is locked // must be buffer 0, as only this one exists if ( ! ((wsmBuf[0].memH == wsmH) || (wsmBuf[0].flags & WSM_LOCKED_F)) ) { return wsmRet=SML_ERR_WRONG_USAGE; } // lock if ( (wsmRet = smLock(wsmH, pMem)) != SML_ERR_OK ) { return wsmRet=SML_ERR_UNSPECIFIC; } // set local pointers wsmBuf[0].pFirstData = *pMem; wsmBuf[0].pFirstFree = *pMem + wsmBuf[0].usedBytes; wsmBuf[0].flags |= WSM_LOCKED_F; switch (requestedPos) { case SML_FIRST_DATA_ITEM: *pMem = wsmBuf[0].pFirstData; break; case SML_FIRST_FREE_ITEM: *pMem = wsmBuf[0].pFirstFree; break; default: return wsmRet=SML_ERR_UNSPECIFIC; } return wsmRet=SML_ERR_OK; } Ret_t wsmGetFreeSize(MemHandle_t wsmH, MemSize_t *freeSize) { // check if handle is invalid // must be buffer 0, as only this one exists if ( ! ((wsmBuf[0].memH == wsmH) || (wsmBuf[0].flags & WSM_VALID_F)) ) { return wsmRet=SML_ERR_INVALID_HANDLE; } *freeSize = wsmBuf[0].size - wsmBuf[0].usedBytes; return wsmRet=SML_ERR_OK; } Ret_t wsmGetUsedSize(MemHandle_t wsmH, MemSize_t *usedSize) { // check if handle is invalid // must be buffer 0, as only this one exists if ( ! ((wsmBuf[0].memH == wsmH) || (wsmBuf[0].flags & WSM_VALID_F)) ) { return wsmRet=SML_ERR_INVALID_HANDLE; } *usedSize = wsmBuf[0].usedBytes; return wsmRet=SML_ERR_OK; } Ret_t wsmUnlockH (MemHandle_t wsmH) { // check if handle is invalid // must be buffer 0, as only this one exists if ( ! ((wsmBuf[0].memH == wsmH) || (wsmBuf[0].flags & WSM_VALID_F)) ) { return wsmRet=SML_ERR_INVALID_HANDLE; } // check if handle is already unlocked // must be buffer 0, as only this one exists if ( ! ((wsmBuf[0].memH == wsmH) || (wsmBuf[0].flags & WSM_LOCKED_F)) ) { return wsmRet=SML_ERR_WRONG_USAGE; } // unlock if ( (wsmRet = smUnlock(wsmH)) != SML_ERR_OK ) { return wsmRet=SML_ERR_UNSPECIFIC; } // set local pointers wsmBuf[0].pFirstData = NULL; wsmBuf[0].pFirstFree = NULL; wsmBuf[0].flags &= ~WSM_LOCKED_F; return wsmRet=SML_ERR_OK; } Ret_t wsmSetUsedSize (MemHandle_t wsmH, MemSize_t usedSize) { // check if handle is invalid // must be buffer 0, as only this one exists if ( ! ((wsmBuf[0].memH == wsmH) || (wsmBuf[0].flags & WSM_VALID_F)) ) { return wsmRet=SML_ERR_INVALID_HANDLE; } // check if handle is unlocked // must be buffer 0, as only this one exists if ( ! ((wsmBuf[0].memH == wsmH) || (wsmBuf[0].flags & WSM_LOCKED_F)) ) { return wsmRet=SML_ERR_WRONG_USAGE; } // usedSize > freeSize? if ( usedSize > (wsmBuf[0].size - wsmBuf[0].usedBytes) ) { return wsmRet=SML_ERR_INVALID_SIZE; } // adapt usedSize wsmBuf[0].usedBytes += usedSize; // move pFirstFree wsmBuf[0].pFirstFree += usedSize; return wsmRet=SML_ERR_OK; } Ret_t wsmReset (MemHandle_t wsmH) { wsmBuf[0].pFirstFree = wsmBuf[0].pFirstFree - wsmBuf[0].usedBytes ; wsmBuf[0].pFirstData = wsmBuf[0].pFirstFree; wsmBuf[0].usedBytes = 0; return SML_ERR_OK; } #endif // #ifndef __SML_LITE__ #endif // #ifndef NOWSM libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/wsm/inc/000077500000000000000000000000001226375725500223775ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/wsm/inc/wsm.h000077500000000000000000000104341226375725500233630ustar00rootroot00000000000000/** * @file * SyncML WorkSpace Manager * * @target_system All * @target_os All * @description Workspace Manager API * Manages the SyncML document in memory. */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ #ifndef _WSM_H #define _WSM_H #include "smlerr.h" #include "smldef.h" #include "syncml_tk_prefix_file.h" // %%% luz: needed for precompiled headers in eVC++ #ifndef NOWSM #include "wsm_sm.h" typedef struct WsmOptions_s { MemSize_t maxAvailMem; /**< maximum amount of memory available for all wsm buffers */ } WsmOptions_t; #ifdef __SML_LITE__ #ifdef MAX_WSM_BUFFERS #error "for __SML_LITE__, MAX_WSM_BUFFERS must not be predefined!" #endif #define MAX_WSM_BUFFERS 1 #else #ifndef MAX_WSM_BUFFERS // use default value of 4 (not much for a multi-connection server) #define MAX_WSM_BUFFERS 4 #endif #endif /** WSM internal buffer structure */ typedef struct WsmBuf_s { String_t bufName; /**< external name of buffer */ MemHandle_t memH; /**< memory handle */ MemPtr_t pFirstFree; /**< pointer to first free element in buffer */ MemPtr_t pFirstData; /**< pointer to first data element in buffer */ MemSize_t size; /**< size of buffer */ MemSize_t usedBytes; /**< used bytes in buffer */ Byte_t flags; } WsmBuf_t; /** WSM globals for use with global Anchor */ typedef struct WsmGlobals_s { Ret_t wsmRet; /**< last WSM return code */ Byte_t initWasCalled; /**< was wsmInit() called? */ WsmBuf_t wsmBuf[MAX_WSM_BUFFERS]; Short_t wsmIndex; /**< Index of actual buffer */ WsmSmGlobals_t wsmSm; /**< WSM_SM global; device dependent! */ } *WsmGlobalsPtr_t, WsmGlobals_t; Ret_t wsmInit (const WsmOptions_t *wsmOpts) WSM_FUNC; Ret_t wsmCreate (String_t bufName, MemSize_t bufSize, MemHandle_t *wsmH) WSM_FUNC; Ret_t wsmOpen (String_t bufName, MemHandle_t *wsmH) WSM_FUNC; Ret_t wsmClose (MemHandle_t wsmH) WSM_FUNC; Ret_t wsmDestroy (String_t bufName) WSM_FUNC; Ret_t wsmTerminate (void) WSM_FUNC; Ret_t wsmProcessedBytes (MemHandle_t wsmH, MemSize_t noBytes) WSM_FUNC; Ret_t wsmLockH (MemHandle_t wsmH, SmlBufPtrPos_t requestedPos, MemPtr_t *pMem) WSM_FUNC; Ret_t wsmGetFreeSize(MemHandle_t wsmH, MemSize_t *freeSize) WSM_FUNC; Ret_t wsmGetUsedSize(MemHandle_t wsmH, MemSize_t *usedSize) WSM_FUNC; Ret_t wsmUnlockH (MemHandle_t wsmH) WSM_FUNC; Ret_t wsmSetUsedSize (MemHandle_t wsmH, MemSize_t usedSize) WSM_FUNC; Ret_t wsmReset (MemHandle_t wsmH) ; #endif // !defined(NOWSM) #endif libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/wsm/inc/wsm_sm.h000077500000000000000000000075571226375725500240760ustar00rootroot00000000000000/** * @file * SyncML WorkSpace Manager * * @target_system All * @target_os All * @description Storage Management for Workspace Manager API * Encapsulates OS dependent parts of WSM. */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ #ifndef _WSM_SM_H #define _WSM_SM_H #include #ifdef __ANSI_C__ /** sbuffer list */ typedef struct smWinList_s { char *memName; /**< name of buffer */ char *winH; /**< reference to memory block */ MemHandle_t memH; /**< handle of memory block */ Byte_t locked; /**< is handle locked? */ MemSize_t memSize; /**< size of memory block */ struct smWinList_s *next; /**< next list item */ } smWinList_t; typedef smWinList_t *WsmSmGlobals_t; #endif #ifdef __PALM_OS__ #include /** dynamic buffer array */ typedef struct smPalm_s { MemHandle smPalmH; /**< reference to only memory block */ MemHandle_t smMemH; /**< handle of only memory block */ Byte_t smLocked; /**< is handle locked? */ } WsmSmGlobals_t; #endif #ifdef __EPOC_OS__ /** sbuffer list */ typedef struct smWinList_s { char *memName; /**< name of buffer */ char *winH; /**< reference to memory block */ MemHandle_t memH; /**< handle of memory block */ Byte_t locked; /**< is handle locked? */ MemSize_t memSize; /**< size of memory block */ struct smWinList_s *next; /**< next list item */ } smWinList_t; typedef smWinList_t *WsmSmGlobals_t; #endif Ret_t smCreate (String_t memName, MemSize_t memSize, MemHandle_t *memH) WSM_FUNC; Ret_t smOpen (String_t memName, MemHandle_t *memH) WSM_FUNC; Ret_t smClose (MemHandle_t memH) WSM_FUNC; Ret_t smDestroy (String_t memName) WSM_FUNC; Ret_t smLock (MemHandle_t memH, MemPtr_t *pMem) WSM_FUNC; Ret_t smUnlock (MemHandle_t memH) WSM_FUNC; Ret_t smSetSize (MemHandle_t memH, MemSize_t newSize) WSM_FUNC; Ret_t smGetSize (MemHandle_t memH, MemSize_t *actSize) WSM_FUNC; #endif libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/wsm/palm/000077500000000000000000000000001226375725500225575ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/wsm/palm/wsm_sm.c000077500000000000000000000117371226375725500242440ustar00rootroot00000000000000/** * @file * SyncML WorkSpace Manager * * @target_system Palm * @target_os PalmOS 3.5 * @description Storage Management for Workspace Manager API. * Palm OS version. */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ /************************************************************************* * Definitions * *************************************************************************/ #include #include #include #include "wsm_sm.h" /* Global Vars */ /* =========== */ #include "mgr.h" #define smPalmH (mgrGetSyncMLAnchor())->wsmGlobals->wsmSm.smPalmH #define smMemH (mgrGetSyncMLAnchor())->wsmGlobals->wsmSm.smMemH #define smLocked (mgrGetSyncMLAnchor())->wsmGlobals->wsmSm.smLocked /************************************************************************* * Internal Functions * *************************************************************************/ /************************************************************************* * External Functions * *************************************************************************/ Ret_t smCreate (String_t memName, MemSize_t memSize, MemHandle_t *memH) { if ( memSize <= 0 ) { return SML_ERR_INVALID_SIZE; } // only one create call does make sense under Palm OS if ( smMemH != 0 ) { return SML_ERR_WRONG_USAGE; } // set new values smLocked = 0; smMemH = 1; *memH = smMemH; // create memory if ( (smPalmH=MemHandleNew(memSize)) == 0 ) { return SML_ERR_NOT_ENOUGH_SPACE; } return SML_ERR_OK; } Ret_t smOpen (String_t memName, MemHandle_t *memH) { if ( smMemH == 0 ) { return SML_ERR_WRONG_PARAM; } *memH = smMemH; return SML_ERR_OK; } Ret_t smClose (MemHandle_t memH) { Err ret; // reset handle if ( (ret=MemHandleFree(smPalmH)) != 0 ) { return SML_ERR_WRONG_USAGE; } smMemH = 0; smLocked = 0; return SML_ERR_OK; } Ret_t smDestroy (String_t memName) { return SML_ERR_OK; } Ret_t smLock (MemHandle_t memH, MemPtr_t *pMem) { if ( memH != smMemH ) { return SML_ERR_WRONG_PARAM; } if ( smLocked ) { return SML_ERR_WRONG_USAGE; } if ( (*pMem = MemHandleLock(smPalmH)) == NULL ) { return SML_ERR_UNSPECIFIC; } smLocked = 1; return SML_ERR_OK; } Ret_t smUnlock (MemHandle_t memH) { if ( memH != smMemH ) { return SML_ERR_WRONG_PARAM; } if ( ! smLocked ) { return SML_ERR_WRONG_USAGE; } if ( MemHandleUnlock(smPalmH) != 0 ) { return SML_ERR_UNSPECIFIC; } smLocked = 0; return SML_ERR_OK; } Ret_t smSetSize (MemHandle_t memH, MemSize_t newSize) { Err ret; if ( memH != smMemH ) { return SML_ERR_WRONG_PARAM; } if ( smLocked ) { return SML_ERR_WRONG_USAGE; } if ( newSize <= 0 ) { return SML_ERR_INVALID_SIZE; } if ( (ret=MemHandleResize(smPalmH, newSize)) != 0 ) { return SML_ERR_NOT_ENOUGH_SPACE; } return SML_ERR_OK; } Ret_t smGetSize (MemHandle_t memH, MemSize_t *actSize) { if ( memH != smMemH ) { return SML_ERR_WRONG_PARAM; } *actSize = MemHandleSize(smPalmH); return SML_ERR_OK; } libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/wsm/win/000077500000000000000000000000001226375725500224235ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/wsm/win/wsm_sm.c000077500000000000000000000312211226375725500240760ustar00rootroot00000000000000/** * @file * SyncML WorkSpace Manager * * @target_system MS Windows * @target_os Windows 98 / NT * @description Storage Management for Workspace Manager API. * MS Windows version. */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ #include "syncml_tk_prefix_file.h" #ifndef NOWSM // if no WSM, we can leave this one out completely /*************************************************************************/ /* Definitions */ /*************************************************************************/ #include "wsm_sm.h" #include #include #include "libmem.h" #include "liblock.h" // for THREADDEBUGPRINTF %%% luz #include "smldef.h" #include "smlerr.h" /* Global Vars */ /* =========== */ /** root of buffer list */ #include "mgr.h" #define root (mgrGetSyncMLAnchor())->wsmGlobals->wsmSm /* private functions prototypes */ static Byte_t newListEle(const char *name, smWinList_t **newEle, MemHandle_t *newHandle); static Byte_t locateEle(const char *eleName, smWinList_t **p); static Byte_t locateH(MemHandle_t memH, smWinList_t **p); static void removeEle(const char *eleName); /*************************************************************************/ /* Internal Functions */ /*************************************************************************/ /** create new buffer element and assign name to it * return pointer to new element and handle of new element */ /* SCTSTK - 16/03/2002 S.H. 2002-04-05 : fixed so that it works even if the sequence of buffer termination is not in the reverse order of buffer creation */ // luz %%% NOTE: called only from routines which lock the toolkit already, // no separate lock required here static Byte_t newListEle(const char *name, smWinList_t **newEle, MemHandle_t *newHandle ) { smWinList_t *p; int i; for ( i=0; *newHandle < MAX_WSM_BUFFERS && (mgrGetSyncMLAnchor())->wsmGlobals->wsmBuf[i].memH != -1; ++i ) {}; if (i == MAX_WSM_BUFFERS) return 0; *newHandle=i+1; if ( ((*newEle) = smlLibMalloc(sizeof(smWinList_t))) == 0 ) return 0; // no more memory if ( ((*newEle)->memName = smlLibMalloc(strlen(name)+1)) == 0 ){ smlLibFree(*newEle); return 0; // no more memory } memcpy((*newEle)->memName, name, strlen(name)); (*newEle)->memName[strlen(name)] = '\0'; if ( root == 0 ) root = *newEle; else { p=root; while ( p->next != NULL) p = p->next; p->next = *newEle; } return 1; } /** * search for buffer with name eleName and return pointer to it in p. * * @return * - 0 if not found; * - 1 if found */ // luz %%% NOTE: called only from routines which lock the toolkit already, // no separate lock required here static Byte_t locateEle(const char *eleName, smWinList_t **p) { *p = root; while ( (*p != NULL) && (strcmp((*p)->memName, eleName) != 0) ) { *p = (*p)->next; } if ( *p == NULL ) return 0; else return 1; } /** * search for buffer with memHandle memH and return pointer to it in p. * * @return * - 0 if not found; * - 1 if found */ // luz %%% NOTE: called only from routines which lock the toolkit already, // no separate lock required here static Byte_t locateH(MemHandle_t memH, smWinList_t **p) { *p = root; while ( (*p != NULL) && ((*p)->memH != memH) ) { *p = (*p)->next; } if ( *p == NULL ) return 0; else return 1; } /** * remove buffer with name eleName from smWinList. */ // luz %%% NOTE: called only from routines which lock the toolkit already, // no separate lock required here static void removeEle(const char *eleName) { smWinList_t *act, *old; old = act = root; while ( (act != NULL) && (strcmp(act->memName, eleName) != 0) ) { old = act; act = act->next; } if ( act != NULL ) { if ( old == act ) // delete first list ele root = act->next; else old->next = act->next; smlLibFree(act->memName); smlLibFree(act); } } /*************************************************************************/ /* External Functions */ /*************************************************************************/ /** * Creates a new memory block with name memName and size memSize. * * @pre * - OS does not know memName * - memSize > 0 * @post * - memName exists with size memSize * - memH refers to new memory block. * @param memName (IN) * Name of new memory block * @param memSize (IN) * Size of new memory block * @param memH (OUT) * Handle to new memory block * @return * - SML_ERR_OK, if O.K. * - SML_ERR_WRONG_USAGE, if memName is already known to the OS * - SML_ERR_INVALID_SIZE, if memSize <= 0 * - SML_ERR_NOT_ENOUGH_SPACE, if available memory < memSize * @see smDestroy */ Ret_t smCreate (String_t memName, MemSize_t memSize, MemHandle_t *memH) { smWinList_t *pEle; // pointer to new buffer if ( memSize <= 0 ) { return SML_ERR_INVALID_SIZE; } if ( locateEle(memName, &pEle) ) { return SML_ERR_WRONG_USAGE; } // create new element in buffer list if ( ! newListEle(memName, &pEle, memH) ) { return SML_ERR_NOT_ENOUGH_SPACE; } // create memory if ( (pEle->winH=smlLibMalloc(memSize)) == 0 ) { smlLibFree(pEle->memName); smlLibFree(pEle); return SML_ERR_NOT_ENOUGH_SPACE; } // set new values pEle->locked = 0; pEle->memH = *memH; pEle->memSize = memSize; pEle->next = NULL; return SML_ERR_OK; } /** * Open connection to memory block with name memName. * * @pre OS does know memName * @post memH refers to memory block memName * @param memName (IN) * Name of memory block to open\n * Windows version: Name is ignored * @param memH (OUT) * Handle to opened memory block * @return * - SML_ERR_OK, if O.K. * - SML_ERR_WRONG_PARAM, if memName is unknown * @see smClose */ Ret_t smOpen (String_t memName, MemHandle_t *memH) { smWinList_t *pEle; // pointer to buffer element if ( ! locateEle(memName, &pEle) ) { return SML_ERR_WRONG_PARAM; } *memH = pEle->memH; return SML_ERR_OK; } /** * Close link to memory block. * * @pre * - memH is a valid memory block handle * - memH is unlocked * - no pointers to records are in use * @post memH is not valid anymore * @param memH (IN) * Handle to close * @return * - SML_ERR_OK, if O.K. * - SML_ERR_WRONG_USAGE, if memH is locked or unknown * @see smOpen */ Ret_t smClose (MemHandle_t memH) { smWinList_t *pEle; // pointer to buffer element if ( ! locateH(memH, &pEle) ) { return SML_ERR_WRONG_USAGE; } // reset handle smlLibFree(pEle->winH); pEle->memH = 0; pEle->locked = 0; pEle->memSize = 0; return SML_ERR_OK; } /** * Remove memory block memName within OS. * * @pre * - memName is a valid memory block name * - memory block is not in use (i.e. no handles and * pointers to this memory block are in use) * @post memName is not a valid memory block name anymore * @param memName (IN) * Name of memory block to remove * @return * - SML_ERR_OK, if O.K. * - SML_ERR_WRONG_PARAM, if memName is unknown * - SML_ERR_WRONG_USAGE, if memory block is still locked * @see smCreate */ Ret_t smDestroy (String_t memName) { smWinList_t *pEle; // pointer to buffer element if ( ! locateEle(memName, &pEle) ) { return SML_ERR_WRONG_PARAM; } if ( pEle->locked ) { return SML_ERR_WRONG_USAGE; } // remove memory buffer removeEle(memName); return SML_ERR_OK; } /** * Map memory block memH to local address space. * * @pre * - memH is a valid handle * - memory block is not locked * @post * - pMem points to memory block memH * - memory block is locked * @param memH (IN) * Handle to memory block * @param pMem (OUT) * Pointer to memory block memH mapped in local address space * @return * - SML_ERR_OK, if O.K. * - SML_ERR_WRONG_PARAM, if memH is unknown * - SML_ERR_WRONG_USAGE, if memH was already locked * - SML_ERR_UNSPECIFIC, if lock failed * @see smUnlock */ Ret_t smLock (MemHandle_t memH, MemPtr_t *pMem) { smWinList_t *pEle; // pointer to buffer element if ( ! locateH(memH, &pEle) ) { return SML_ERR_WRONG_PARAM; } if ( pEle->locked ) { return SML_ERR_WRONG_USAGE; } *pMem = (MemPtr_t)pEle->winH; pEle->locked = 1; return SML_ERR_OK; } /** * Free pointer mapped to memH memory block. * * @pre * - memH is a valid handle * - memory block is locked * @post memory block is unlocked * @param memH (IN) * Handle to memory block * @return * - SML_ERR_OK, if O.K. * - SML_ERR_WRONG_PARAM, if memH is unknown * - SML_ERR_WRONG_USAGE, if memH was already unlocked * - SML_ERR_UNSPECIFIC, if unlock failed * @see smLock */ Ret_t smUnlock (MemHandle_t memH) { smWinList_t *pEle; // pointer to buffer element if ( ! locateH(memH, &pEle) ) { return SML_ERR_WRONG_PARAM; } if ( ! pEle->locked ) { return SML_ERR_WRONG_USAGE; } pEle->locked = 0; return SML_ERR_OK; } /** * Set size of memory block memH to newSize. * * @pre * - memH is a valid handle * - newSize > 0 * - memory block is unlocked * @post memory block size = newSize * @param memH (IN) * Handle to memory block * @param newSize (IN) * New size of memory block * @return * - SML_ERR_OK, if O.K. * - SML_ERR_WRONG_PARAM, if memH is unknown * - SML_ERR_WRONG_USAGE, if memH is locked * - SML_ERR_INVALID_SIZE, if newSize <= 0 * - SML_ERR_NOT_ENOUGH_SPACE, if available memory < newSize * @see smGetSize */ Ret_t smSetSize (MemHandle_t memH, MemSize_t newSize) { smWinList_t *pEle; // pointer to buffer element if ( ! locateH(memH, &pEle) ) { return SML_ERR_WRONG_PARAM; } if ( pEle->locked ) { return SML_ERR_WRONG_USAGE; } if ( newSize <= 0 ) { return SML_ERR_INVALID_SIZE; } smlLibFree(pEle->winH); if ( (pEle->winH=smlLibMalloc(newSize)) == 0 ) { return SML_ERR_NOT_ENOUGH_SPACE; } pEle->memSize = newSize; return SML_ERR_OK; } /** * Get size of memory block memH. * * @pre memH is a valid handle * @post actSize = memory block size * @param memH (IN) * Handle to memory block * @param actSize (OUT) * Actual size of memory block * @return * - SML_ERR_OK, if O.K. * - SML_ERR_WRONG_PARAM, if memH is unknown * @see smSetSize */ Ret_t smGetSize (MemHandle_t memH, MemSize_t *actSize) { smWinList_t *pEle; // pointer to buffer element if ( ! locateH(memH, &pEle) ) { return SML_ERR_WRONG_PARAM; } *actSize = pEle->memSize; return SML_ERR_OK; } #endif // #ifndef NOWSM libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/xlt/000077500000000000000000000000001226375725500216275ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/xlt/all/000077500000000000000000000000001226375725500223775ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/xlt/all/xltdec.c000077500000000000000000002343721226375725500240440ustar00rootroot00000000000000/** * @file * SyncmML Decoder * * @target_system all * @target_os all * @description The SyncML parser. */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ /*************************************************************************/ /* Definitions */ /*************************************************************************/ #include "syncml_tk_prefix_file.h" // %%% luz: needed for precompiled headers in eVC++ #include "xltdec.h" #include "xltdeccom.h" #include "xlttags.h" #include "xltutilstack.h" #include "xlttagtbl.h" #include "xltmetinf.h" #include "xltdevinf.h" #include #include #include #include #include #include #include #include #ifdef SYDEBUG #if !defined(DIRECT_APPBASE_GLOBALACCESS) && defined(CONSOLEINFO) void ConsolePrintf(const char *text, ...); #define SMLERRPRINTFX(lvl,m) CONSOLEPRINTF(m) #else #define SMLERRPRINTFX(lvl,m) PNCDEBUGPRINTFX(lvl,m) #endif /** * Better parsing error reporting when used within Synthesis SyncML engine * added 2006-11-02 by luz@synthesis.ch */ // Error texts #define numSmlErrTexts (SML_ERR_XLT_INVAL_INPUT_DATA-SML_ERR_XLT_MISSING_CONT + 1) static const char * const smlErrTexts[numSmlErrTexts] = { "required field content missing", // 0x2001 "Buffer too small", // 0x2002 "Invalid (WBXML) Element Type", // 0x2003 "Invalid List Type", // 0x2004 "Invalid Tag Type", // 0x2005 "???", // 0x2006 "Unknown Encoding", // 0x2007 "Invalid Protocol Element", // 0x2008 "Missing Content of List Elements", // 0x2009 "Incompatible WBXML Content Format Version", // 0x200A "Document does not conform to SyncML DTD", // 0x200B "Invalid PCData elem", // 0x200C "Unspecified tokenizer error", // 0x200D "Document does not conform to WBXML specification", // 0x200E "Document contains unknown WBXML token", // 0x200F "Non-empty start tag without matching end tag", // 0x2010 "WBXML document uses unspecified code page", // 0x2011 "End of buffer reached", // 0x2012 "Document does not conform to XML 1.0 specification", // 0x2012 "Document contains unknown XML tag", // 0x2014 "Invalid Public Identifier", // 0x2015 "Invalid Codepage Extension", // 0x2016 "No matching Codepage could be found", // 0x2017 "Data missing in input structure", // 0x2018 }; // get error text const char *smlErrorText(Ret_t aRc) { if (aRc>=SML_ERR_XLT_MISSING_CONT && aRc<=SML_ERR_XLT_INVAL_INPUT_DATA) { return smlErrTexts[aRc-SML_ERR_XLT_MISSING_CONT]; } // no text found return ""; } // makes hex char out of nibble static char NibbleToHexDigit(uInt8 aNibble) { aNibble &= 0x0F; if (aNibble>9) return 'A'-0x0A+aNibble; else return '0'+aNibble; } // NibbleToHexDigit #define numBytesShow 32 // show token info void show_token(XltDecTokenPtr_t aToken, uInt32 aDebugMask) { int i; SmlPcdataExtension_t ext; TagPtr_t pTags; short tagwbxml; char *tagxml; char *extname; char *toktype; if (aToken==NULL) return; // get token type switch (aToken->type) { case TOK_TAG_START: toktype="start"; break; case TOK_TAG_END: toktype="end"; break; case TOK_TAG_EMPTY: toktype="empty"; break; case TOK_CONT: toktype="content"; break; default: toktype="UNKNOWN"; break; } // get extension name switch (aToken->ext) { case SML_EXT_METINF: extname="metInf"; break; case SML_EXT_DEVINF: extname="devInf"; break; default: extname="undef/SyncML"; break; } // check if this is a tag if (IS_TAG(aToken)) { // get tag information tagwbxml=-1; // undefined tagxml="UNDEFINED"; for (ext=SML_EXT_UNDEFINED; extid) != TN_UNDEF) { if (((pTags+i)->id) == aToken->tagid) { tagwbxml = (pTags+i)->wbxml; #if defined(__SML_XML__) || defined(__SML_WBXML_TEXTTOKENS__) tagxml = (pTags+i)->xml; #endif goto foundtag; } i++; } } } foundtag: #if defined(__SML_XML__) || defined(__SML_WBXML_TEXTTOKENS__) // we have tag names SMLERRPRINTFX(aDebugMask,( "- parsing %s token, ext=%s: <%s> (WBXML 0x%hX, tagid=%hd)", toktype, extname, tagxml, (short)tagwbxml, (short)aToken->tagid )); #else // we only have WBXML tag codes SMLERRPRINTFX(aDebugMask,( "- parsing %s token, ext=%s: tag (WBXML 0x%hX, tagid=%hd)", toktype, extname, (short)tagwbxml, (short)aToken->tagid )); #endif } // if tag else if (IS_CONTENT(aToken)) { // content SMLERRPRINTFX(aDebugMask,("- parsing content (%s token, ext=%s)",toktype,extname)); } else { // unknown SMLERRPRINTFX(aDebugMask,("- parsing %s token, ext=%s",toktype,extname)); } } // show_token Ret_t show_decode_error(Ret_t aRc, XltDecScannerPtr_t aScanner, char *aRoutineName) { char hexshow[numBytesShow*3+1]; char *p; unsigned char *b; int i; if (aRc!=SML_ERR_OK) { // get routine name if (aRoutineName==NULL) aRoutineName="SML"; // generic sml // Show error SMLERRPRINTFX(DBG_ERROR,("%s: smlErr 0x%hX (%s) while parsing",aRoutineName,aRc,smlErrorText(aRc))); // Show details if (aScanner && aScanner->curtok) { Long_t currentBytesShow = numBytesShow; Long_t remaining; // show what token we are parsing show_token(aScanner->curtok,DBG_ERROR); // show hex of at most 32 bytes after scan position b = aScanner->getPos(aScanner, &remaining); if (remaining < currentBytesShow) currentBytesShow = remaining; SMLERRPRINTFX(DBG_ERROR,( "- Tag start at 0x%lX, scanner pos at 0x%lX%s, data:", (unsigned long)aScanner->curtok->start, (unsigned long)b, aScanner->finished ? " (finished)" : "" )); if (b!=NULL) { p=hexshow; for (i=0; i>4); *p++ = NibbleToHexDigit(*b++); *p++ = ' '; } *p=0; b-=currentBytesShow; // rewind SMLERRPRINTFX(DBG_ERROR,("%s", hexshow)); p=hexshow; for (i=0; i=0x20) && (*b<0x7F) ? *b : '_'; b++; } *p=0; SMLERRPRINTFX(DBG_ERROR,("%s", hexshow)); } } else { // no scanner or no current token SMLERRPRINTFX(DBG_ERROR,( "%s: smlErr 0x%hX while parsing no current tag", aRoutineName, aRc )); } } // return error code return aRc; } // show_decode_error #endif // SYDEBUG #ifdef __USE_EXTENSIONS__ /* prototype for function in xltdecwbxml.c */ void subdtdDecodeWbxml(XltDecoderPtr_t pDecoder,SmlPcdataPtr_t *ppPcdata); #endif /** * Tries to concatenate two Pcdata elements. Only works when the two * elements are of the same type (e.g. SML_PCDATA_STRING). Returns a * pointer to the new Pcdata element or NULL if concatenation failed. */ static SmlPcdataPtr_t concatPCData(SmlPcdataPtr_t pDat1, const SmlPcdataPtr_t pDat2); /** * appendXXXList * * These are auxiliary functions for building SyncML elements that contain * lists of certain other data structures (e.g. Items). They take an * existing list (e.g. of type ItemListPtr_t) and append an appropriate * element at the end. If the ListPtr points to NULL a new list is created. * * @pre The scanner's current token is the start tag (may be * empty) of the SyncML element to be appended to the list. * @post The scanner's current token is the end tag (or empty * start tag) of the SyncML element that was added to the list. * @param pDecoder (IN/OUT) * the decoder * @param ppXXXList (IN/OUT) * NULL or an initialized list, to which element will be appended * @return SML_ERR_OK, if an element was successfully appended\n * else error code */ static Ret_t appendItemList(XltDecoderPtr_t pDecoder, SmlItemListPtr_t *ppItemList); #ifdef SEARCH_RECEIVE static Ret_t appendSourceList(XltDecoderPtr_t pDecoder, SmlSourceListPtr_t *ppSourceList); #endif #ifdef MAPITEM_RECEIVE static Ret_t appendMapItemList(XltDecoderPtr_t pDecoder, SmlMapItemListPtr_t *ppMapItemList); #endif static Ret_t appendTargetRefList(XltDecoderPtr_t pDecoder, SmlTargetRefListPtr_t *ppTargetRefList); static Ret_t appendSourceRefList(XltDecoderPtr_t pDecoder, SmlSourceRefListPtr_t *ppSourceRefList); /* if the commands are not defined we let the functions point to NULL */ #ifndef RESULT_RECEIVE #define buildResults NULL #endif #ifndef MAP_RECEIVE #define buildMap NULL #endif #ifndef EXEC_RECEIVE #define buildExec NULL #endif #if !defined(ATOMIC_RECEIVE) && !defined(SEQUENCE_RECEIVE) #define buildAtomOrSeq NULL #endif #ifndef SEARCH_RECEIVE #define buildSearch NULL #endif typedef struct PEBuilder_s { XltTagID_t tagid; SmlProtoElement_t type; Ret_t (*build)(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem); } PEBuilder_t, *PEBuilderPtr_t; /* luz 2005-08-17: simplified, removed unnecessary copying of the const static table */ static const PEBuilder_t cPE_Dec[] = { { TN_ADD, SML_PE_ADD, buildGenericCmd }, { TN_ALERT, SML_PE_ALERT, buildAlert }, { TN_ATOMIC, SML_PE_ATOMIC_START, buildAtomOrSeq }, { TN_COPY, SML_PE_COPY, buildGenericCmd }, { TN_DELETE, SML_PE_DELETE, buildGenericCmd }, { TN_EXEC, SML_PE_EXEC, buildExec }, { TN_GET, SML_PE_GET, buildPutOrGet }, { TN_MAP, SML_PE_MAP, buildMap }, { TN_PUT, SML_PE_PUT, buildPutOrGet }, { TN_RESULTS, SML_PE_RESULTS, buildResults }, { TN_SEARCH, SML_PE_SEARCH, buildSearch }, { TN_SEQUENCE, SML_PE_SEQUENCE_START, buildAtomOrSeq }, { TN_STATUS, SML_PE_STATUS, buildStatus }, { TN_SYNC, SML_PE_SYNC_START, buildSync }, { TN_REPLACE, SML_PE_REPLACE, buildGenericCmd }, { TN_MOVE, SML_PE_MOVE, buildGenericCmd }, { TN_UNDEF, SML_PE_UNDEF, 0 } }; /*************************************************************************/ /* External Functions */ /*************************************************************************/ /** * Description see XLTDec.h header file. */ Ret_t xltDecInit(const SmlEncoding_t enc, const MemPtr_t pBufEnd, MemPtr_t *ppBufPos, XltDecoderPtr_t *ppDecoder, SmlSyncHdrPtr_t *ppSyncHdr) { XltDecoderPtr_t pDecoder; Ret_t rc; /* create new decoder object */ if ((pDecoder = (XltDecoderPtr_t)smlLibMalloc(sizeof(XltDecoder_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; pDecoder->finished = 0; pDecoder->final = 0; pDecoder->scanner = NULL; if ((rc = xltUtilCreateStack(&pDecoder->tagstack, 10)) != SML_ERR_OK) { xltDecTerminate(pDecoder); return rc; } #ifdef __SML_WBXML__ if (enc == SML_WBXML) { rc = xltDecWbxmlInit(pBufEnd, ppBufPos, &pDecoder->scanner); if (rc == SML_ERR_OK) { pDecoder->charset = pDecoder->scanner->charset; pDecoder->charsetStr = NULL; } } else #endif #ifdef __SML_XML__ if (enc == SML_XML) { rc = xltDecXmlInit(pBufEnd, ppBufPos, &pDecoder->scanner); if (rc == SML_ERR_OK) { pDecoder->charset = 0; pDecoder->charsetStr = pDecoder->scanner->charsetStr; } } else #endif { rc = SML_ERR_XLT_ENC_UNK; } if (rc != SML_ERR_OK) { xltDecTerminate((XltDecoderPtr_t)pDecoder); return rc; } /* try to find SyncHdr element, first comes the SyncML tag... */ if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { xltDecTerminate((XltDecoderPtr_t)pDecoder); return rc; } if (!IS_START(pDecoder->scanner->curtok) || (pDecoder->scanner->curtok->tagid != TN_SYNCML)) { smlFreePcdata(pDecoder->scanner->curtok->pcdata); rc = SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pDecoder->scanner,"xltDecInit"); xltDecTerminate((XltDecoderPtr_t)pDecoder); return rc; } /* ... then the SyncHdr */ if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { xltDecTerminate((XltDecoderPtr_t)pDecoder); return rc; } if ((rc = buildSyncHdr(pDecoder, (VoidPtr_t)ppSyncHdr)) != SML_ERR_OK) { xltDecTerminate((XltDecoderPtr_t)pDecoder); return rc; } *ppBufPos = pDecoder->scanner->getPos(pDecoder->scanner, NULL); *ppDecoder = (XltDecoderPtr_t)pDecoder; return SML_ERR_OK; } /** * Description see XLTDec.h header file. */ Ret_t xltDecNext(XltDecoderPtr_t pDecoder, const MemPtr_t pBufEnd, MemPtr_t *ppBufPos, SmlProtoElement_t *pe, VoidPtr_t *ppContent) { XltDecoderPtr_t pDecPriv = (XltDecoderPtr_t)pDecoder; XltDecScannerPtr_t pScanner = pDecPriv->scanner; XltTagID_t tagid; Ret_t rc; int i; pScanner->setBuf(pScanner, *ppBufPos, pBufEnd); /* if we are still outside the SyncBody, look for SyncBody start tag */ if ((rc = pDecPriv->tagstack->top(pDecPriv->tagstack, &tagid)) != SML_ERR_OK) return rc; if (tagid == TN_SYNCML) { if (((rc = nextToken(pDecPriv)) != SML_ERR_OK)) { return rc; } if (!((IS_START(pScanner->curtok)) && (pScanner->curtok->tagid == TN_SYNCBODY))) { return SML_DECODEERROR(SML_ERR_XLT_INVAL_PROTO_ELEM,pScanner,"xltDecNext"); } } if ((rc = nextToken(pDecPriv)) != SML_ERR_OK) return rc; /* if we find a SyncML protocol element build the corresponding data structure */ if ((IS_START_OR_EMPTY(pScanner->curtok)) && (pScanner->curtok->tagid != TN_FINAL)) { i = 0; while ((cPE_Dec[i].tagid) != TN_UNDEF) { if ((cPE_Dec[i].tagid) == pScanner->curtok->tagid) { *pe = (cPE_Dec[i].type); if ((rc = cPE_Dec[i].build(pDecPriv, ppContent)) != SML_ERR_OK) return rc; /* T.K. adjust the SML_PE_ for 'generic' structures if (*pe == SML_PE_GENERIC) { SmlGenericCmdPtr_t g = *ppContent; switch ((int) (cPE_Dec[i].tagid)) { case TN_ADD : g->elementType = SML_PE_ADD; break; case TN_COPY : g->elementType = SML_PE_COPY; break; case TN_DELETE : g->elementType = SML_PE_DELETE; break; case TN_REPLACE: g->elementType = SML_PE_REPLACE; break; } } */ /* %%% luz 2005-08-17: we can do this a lot easier... */ /* if the procduced element has no distinct element type now, but is still SML_PE_GENERIC, we need to set it to the correct distinct value */ if (((SmlGenericCmdPtr_t)(*ppContent))->elementType == SML_PE_GENERIC) { ((SmlGenericCmdPtr_t)(*ppContent))->elementType = cPE_Dec[i].type; } break; } i++; } if ((cPE_Dec[i].tagid) == TN_UNDEF) { *pe = SML_PE_UNDEF; *ppContent = NULL; return SML_DECODEERROR(SML_ERR_XLT_INVAL_PROTO_ELEM,pScanner,"xltDecNext"); } } else { /* found end tag */ switch (pScanner->curtok->tagid) { case TN_ATOMIC: *pe = SML_PE_ATOMIC_END; *ppContent = NULL; break; case TN_SEQUENCE: *pe = SML_PE_SEQUENCE_END; *ppContent = NULL; break; case TN_SYNC: *pe = SML_PE_SYNC_END; *ppContent = NULL; break; case TN_FINAL: *pe = SML_PE_FINAL; *ppContent = NULL; pDecPriv->final = 1; break; case TN_SYNCBODY: /* next comes the SyncML end tag, then we're done */ if ((rc = nextToken(pDecPriv)) != SML_ERR_OK) return rc; if ((pScanner->curtok->type == TOK_TAG_END) && (pScanner->curtok->tagid == TN_SYNCML)) { *pe = SML_PE_UNDEF; *ppContent = NULL; pDecPriv->finished = 1; } else { return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"xltDecNext"); } break; default: return SML_DECODEERROR(SML_ERR_XLT_INVAL_PROTO_ELEM,pScanner,"xltDecNext"); } } *ppBufPos = pScanner->getPos(pScanner, NULL); return SML_ERR_OK; } /** * Description see XLTDec.h header file. */ Ret_t xltDecTerminate(XltDecoderPtr_t pDecoder) { XltDecoderPtr_t pDecPriv; if (pDecoder == NULL) return SML_ERR_OK; pDecPriv = (XltDecoderPtr_t)pDecoder; if (pDecPriv->scanner != NULL) pDecPriv->scanner->destroy(pDecPriv->scanner); if (pDecPriv->tagstack != NULL) pDecPriv->tagstack->destroy(pDecPriv->tagstack); smlLibFree(pDecPriv); return SML_ERR_OK; } Ret_t xltDecReset(XltDecoderPtr_t pDecoder) { return xltDecTerminate(pDecoder); } /** * Gets the next token from the scanner. * Checks if the current tag is an end tag and if so, whether the last * open start tag has the same tag id as the current end tag. An open start * tag is one which matching end tag has not been seen yet. * If the current tag is a start tag its tag ID will be pushed onto the * tag stack. * If the current tag is an empty tag or not a tag at all nothing will be * done. */ Ret_t nextToken(XltDecoderPtr_t pDecoder) { XltUtilStackPtr_t pTagStack; XltDecTokenPtr_t pToken; Ret_t rc; if ((rc = pDecoder->scanner->nextTok(pDecoder->scanner)) != SML_ERR_OK) return rc; pToken = pDecoder->scanner->curtok; pTagStack = pDecoder->tagstack; #if SYDEBUG>2 show_token(pToken,DBG_DETAILS); #endif if (IS_START(pToken)) { if (pTagStack->push(pTagStack, pToken->tagid)) return SML_ERR_UNSPECIFIC; } else if (IS_END(pToken)) { XltTagID_t lastopen; if (pTagStack->pop(pTagStack, &lastopen)) return SML_ERR_UNSPECIFIC; if (pToken->tagid != lastopen) return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pDecoder->scanner,"nextToken"); } return SML_ERR_OK; } Ret_t discardToken(XltDecoderPtr_t pDecoder) { Ret_t rc; XltTagID_t tmp; if ((rc = pDecoder->scanner->pushTok(pDecoder->scanner)) != SML_ERR_OK) return rc; if ((rc = pDecoder->tagstack->pop(pDecoder->tagstack, &tmp)) != SML_ERR_OK) return rc; return SML_ERR_OK; } /*************************************************************************/ /* Internal Functions */ /*************************************************************************/ static SmlPcdataPtr_t concatPCData(SmlPcdataPtr_t pDat1, const SmlPcdataPtr_t pDat2) { // luz: 2006-09-07: plain wrong again. We can very well concatenate // STRING, OPAQUE and CDATA, only extensions are not concatenatable // For this, no extra check is needed, as implementation below already does //%%% if (pDat1->contentType != pDat2->contentType) //%%% return NULL; switch (pDat1->contentType) { case SML_PCDATA_STRING: /* luz: 2005-03-07: original RTK code: plain wrong - causes crash as pDat1->content is NOT big enough to have data appended without re-alloc!! - No need to make difference between STRING and OPAQUE anyway! pDat1->content = (VoidPtr_t)smlLibStrcat(pDat1->content, pDat2->content); pDat1->length += pDat2->length; break; */ case SML_PCDATA_CDATA: case SML_PCDATA_OPAQUE: if (pDat2->contentType==SML_PCDATA_EXTENSION) return NULL; // can't concat // luz: 2005-03-07: made sure we ALWAYS have a null byte at the end of an opaque string if ((pDat1->content = smlLibRealloc(pDat1->content, pDat1->length + pDat2->length + 1)) == NULL) return NULL; smlLibMemmove(((Byte_t*)pDat1->content) + pDat1->length, pDat2->content, pDat2->length); pDat1->length += pDat2->length; ((char *)pDat1->content)[pDat1->length]=0; // null byte at the end break; default: return NULL; // can't concat } return pDat1; } Ret_t buildSyncHdr(XltDecoderPtr_t pDecoder, VoidPtr_t *ppSyncHdr) { XltDecScannerPtr_t pScanner; SmlSyncHdrPtr_t pSyncHdr; Ret_t rc; Long_t sessionid = 0, msgid = 0, source = 0, target = 0, version = 0, proto = 0; /* shortcut to the scanner object */ pScanner = pDecoder->scanner; /* if ppSyncHdr is not NULL we've already found a SyncHdr before! */ if (*ppSyncHdr != NULL) return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildSyncHdr"); /* initialize new SmlSyncHdr */ if ((pSyncHdr = (SmlSyncHdrPtr_t)smlLibMalloc(sizeof(SmlSyncHdr_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pSyncHdr, 0, sizeof(SmlSyncHdr_t)); /* initialize the element type field */ pSyncHdr->elementType = SML_PE_HEADER; /* empty SmlSyncHdr is possible */ if (IS_EMPTY(pScanner->curtok)) { *ppSyncHdr = pSyncHdr; return SML_ERR_OK; } /* get next Token */ if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlLibFree(pSyncHdr); return rc; } /* parse child elements until we find a matching end tag */ while (pScanner->curtok->type != TOK_TAG_END) { switch (pScanner->curtok->tagid) { /* PCDATA elements */ case TN_VERSION: rc = buildPCData(pDecoder, (VoidPtr_t)&pSyncHdr->version); version++; break; case TN_PROTO: rc = buildPCData(pDecoder, (VoidPtr_t)&pSyncHdr->proto); proto++; break; case TN_SESSIONID: rc = buildPCData(pDecoder, (VoidPtr_t)&pSyncHdr->sessionID); sessionid++; break; case TN_MSGID: rc = buildPCData(pDecoder, (VoidPtr_t)&pSyncHdr->msgID); msgid++; break; case TN_RESPURI: rc = buildPCData(pDecoder, (VoidPtr_t)&pSyncHdr->respURI); break; /* child tags */ case TN_TARGET: rc = buildTargetOrSource(pDecoder, (VoidPtr_t)&pSyncHdr->target); target++; break; case TN_SOURCE: rc = buildTargetOrSource(pDecoder, (VoidPtr_t)&pSyncHdr->source); source++; break; case TN_CRED: rc = buildCred(pDecoder, (VoidPtr_t)&pSyncHdr->cred); break; case TN_META: rc = buildPCData(pDecoder, (VoidPtr_t)&pSyncHdr->meta); break; /* flags (empty tags) */ case TN_NORESP: pSyncHdr->flags |= SmlNoResp_f; rc = buildEmptyTag(pDecoder); // allow for instead of break; default: rc = SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildSyncHdr"); } /* decoding of child element went ok? */ if (rc != SML_ERR_OK) { smlFreeSyncHdr(pSyncHdr); return rc; } /* get next token */ if ((rc = nextToken(pDecoder)) != SML_ERR_OK) { smlFreeSyncHdr(pSyncHdr); return rc; } } if ((sessionid == 0) || (msgid == 0) || (target == 0) || (source == 0) || (version == 0) || (proto == 0)) { smlFreeSyncHdr(pSyncHdr); return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildSyncHdr"); } *ppSyncHdr = pSyncHdr; return SML_ERR_OK; } Ret_t buildSync(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem) { XltDecScannerPtr_t pScanner; SmlSyncPtr_t pSync; Ret_t rc; Long_t cmdid = 0; /* stop decoding the Sync when we find a SyncML command */ Byte_t break_sync = 0; pScanner = pDecoder->scanner; if (*ppElem != NULL) return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildSync"); /* initialize a new Sync */ if ((pSync = (SmlSyncPtr_t)smlLibMalloc(sizeof(SmlSync_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pSync, 0, sizeof(SmlSync_t)); /* initialize the element type field */ pSync->elementType = SML_PE_SYNC_START; if (IS_EMPTY(pScanner->curtok)) { smlLibFree(pSync); return SML_ERR_OK; } /* get next token */ if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlLibFree(pSync); return rc; } /* parse child elements until we find a matching end tag or until we find a TN_ADD, TN_ATOMIC, etc. start tag */ while ((pScanner->curtok->type != TOK_TAG_END) && !break_sync) { switch (pScanner->curtok->tagid) { /* PCDATA elements */ case TN_CMDID: rc = buildPCData(pDecoder, (VoidPtr_t)&pSync->cmdID); cmdid++; break; case TN_META: rc = buildPCData(pDecoder, (VoidPtr_t)&pSync->meta); break; case TN_NUMBEROFCHANGES: rc = buildPCData(pDecoder, (VoidPtr_t)&pSync->noc); break; /* child tags */ case TN_CRED: rc = buildCred(pDecoder, (VoidPtr_t)&pSync->cred); break; case TN_TARGET: rc = buildTargetOrSource(pDecoder, (VoidPtr_t)&pSync->target); break; case TN_SOURCE: rc = buildTargetOrSource(pDecoder, (VoidPtr_t)&pSync->source); break; /* flags */ case TN_NORESP: pSync->flags |= SmlNoResp_f; rc = buildEmptyTag(pDecoder); // allow for instead of break; /* quit if we find an Add, Atomic, etc. element */ case TN_ADD: case TN_ATOMIC: case TN_COPY: case TN_DELETE: case TN_SEQUENCE: case TN_REPLACE: break_sync = 1; break; default: rc = SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildSync"); } if (rc != SML_ERR_OK) { smlFreeSync(pSync); return rc; } if (!break_sync) { /* get next token and continue as usual */ if ((rc = nextToken(pDecoder)) != SML_ERR_OK) { smlFreeSync(pSync); return rc; } } else { /* we've found a SyncML command - we need to go back one token and correct the tagstack */ if ((rc = discardToken(pDecoder)) != SML_ERR_OK) { smlFreeSync(pSync); return rc; } } } if (!break_sync) { if ((pScanner->curtok->tagid) != TN_SYNC) { smlFreeSync(pSync); return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildSync"); } else { if (pDecoder->tagstack->push(pDecoder->tagstack, pScanner->curtok->tagid)) { smlFreeSync(pSync); return SML_ERR_UNSPECIFIC; } if ((rc = pDecoder->scanner->pushTok(pDecoder->scanner)) != SML_ERR_OK) { smlFreeSync(pSync); return rc; } } } *ppElem = pSync; return SML_ERR_OK; } #if (defined ATOMIC_RECEIVE || defined SEQUENCE_RECEIVE) Ret_t buildAtomOrSeq(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem) { XltDecScannerPtr_t pScanner; SmlAtomicPtr_t pAoS; /* SmlAtomicPtr_t and SequencePtr_t are pointer to the same structure! */ Ret_t rc; Byte_t break_aos = 0; /* stop decoding the Atomic when we find a SyncML command */ Long_t cmdid = 0; pScanner = pDecoder->scanner; if (*ppElem != NULL) return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildAtomOrSeq"); if ((pAoS = (SmlAtomicPtr_t)smlLibMalloc(sizeof(SmlAtomic_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pAoS, 0, sizeof(SmlAtomic_t)); /* initialize the element type field */ pAoS->elementType = SML_PE_CMD_GROUP; if (IS_EMPTY(pScanner->curtok)) { smlLibFree(pAoS); return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildAtomOrSeq"); } /* get next token */ if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlLibFree (pAoS); return rc; } /* parse child elements until we find a matching end tag or until we find a TN_ADD, TN_ATOMIC, etc. start tag */ while ((pScanner->curtok->type != TOK_TAG_END) && !break_aos) { switch (pScanner->curtok->tagid) { /* PCDATA elements */ case TN_CMDID: rc = buildPCData(pDecoder, (VoidPtr_t)&pAoS->cmdID); cmdid++; break; case TN_META: rc = buildPCData(pDecoder, (VoidPtr_t)&pAoS->meta); break; /* flags */ case TN_NORESP: pAoS->flags |= SmlNoResp_f; rc = buildEmptyTag(pDecoder); // allow for instead of break; /* quit if we find an Add, Atomic, etc. element */ case TN_ADD: case TN_REPLACE: case TN_DELETE: case TN_COPY: case TN_ATOMIC: case TN_MAP: case TN_SYNC: case TN_GET: case TN_ALERT: case TN_EXEC: break_aos = 1; break; default: rc = SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildAtomOrSeq"); } if (rc != SML_ERR_OK) { smlFreeAtomic(pAoS); return rc; } if (!break_aos) { if ((rc = nextToken(pDecoder)) != SML_ERR_OK) { smlFreeAtomic(pAoS); return rc; } } else { /* we've found a SyncML command - we need to go back one token and correct the tagstack */ if ((rc = discardToken(pDecoder)) != SML_ERR_OK) { smlFreeAtomic(pAoS); return rc; } } } if (!break_aos) { /* Atomic/Sequence must contain at least one SyncML command */ smlFreeAtomic(pAoS); return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildAtomOrSeq"); } if (cmdid == 0) { smlFreeAtomic(pAoS); return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildAtomOrSeq"); } *ppElem = pAoS; return SML_ERR_OK; } #endif #ifdef EXEC_RECEIVE Ret_t buildExec(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem) { XltDecScannerPtr_t pScanner; SmlExecPtr_t pExec; Ret_t rc; Long_t items = 0, cmdid = 0; pScanner = pDecoder->scanner; if (*ppElem != NULL) return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildExec"); if ((pExec = (SmlExecPtr_t)smlLibMalloc(sizeof(SmlExec_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pExec, 0, sizeof(SmlExec_t)); /* initialize the element type field */ pExec->elementType = SML_PE_EXEC; if (IS_EMPTY(pScanner->curtok)) { smlLibFree(pExec); return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildExec"); } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlLibFree(pExec); return rc; } while (pScanner->curtok->type != TOK_TAG_END) { switch (pScanner->curtok->tagid) { /* PCData */ case TN_CMDID: rc = buildPCData(pDecoder, (VoidPtr_t)&pExec->cmdID); cmdid++; break; case TN_META: rc = buildPCData(pDecoder, (VoidPtr_t)&pExec->meta); break; /* child tags */ case TN_CRED: rc = buildCred(pDecoder, (VoidPtr_t)&pExec->cred); break; case TN_ITEM: rc = buildItem(pDecoder, (VoidPtr_t)&pExec->item); items++; break; /* flags */ case TN_NORESP: pExec->flags |= SmlNoResp_f; rc = buildEmptyTag(pDecoder); // allow for instead of break; default: rc = SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildExec"); } if (rc != SML_ERR_OK) { smlFreeExec(pExec); return rc; } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlFreeExec(pExec); return rc; } } if ((items == 0) || (cmdid == 0)) { smlFreeExec(pExec); return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildExec"); } *ppElem = pExec; return SML_ERR_OK; } #endif Ret_t buildGenericCmd(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem) { XltDecScannerPtr_t pScanner; SmlGenericCmdPtr_t pGenCmd; Ret_t rc; Long_t items = 0, cmdid = 0; pScanner = pDecoder->scanner; if (*ppElem != NULL) return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildGenericCmd"); /* initialize a new GenericCmd */ if ((pGenCmd = (SmlGenericCmdPtr_t)smlLibMalloc(sizeof(SmlGenericCmd_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pGenCmd, 0, sizeof(SmlGenericCmd_t)); /* initialize the element type field */ pGenCmd->elementType = SML_PE_GENERIC; if (IS_EMPTY(pScanner->curtok)) { smlLibFree(pGenCmd); return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildGenericCmd"); } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlLibFree(pGenCmd); return rc; } while (pScanner->curtok->type != TOK_TAG_END) { switch (pScanner->curtok->tagid) { /* PCDATA elements */ case TN_CMDID: rc = buildPCData(pDecoder, (VoidPtr_t)&pGenCmd->cmdID); cmdid++; break; case TN_META: rc = buildPCData(pDecoder, (VoidPtr_t)&pGenCmd->meta); break; /* child tags */ case TN_CRED: rc = buildCred(pDecoder, (VoidPtr_t)&pGenCmd->cred); break; /* flags (empty tags) */ case TN_NORESP: pGenCmd->flags |= SmlNoResp_f; rc = buildEmptyTag(pDecoder); // allow for instead of break; case TN_ARCHIVE: pGenCmd->flags |= SmlArchive_f; rc = buildEmptyTag(pDecoder); // allow for instead of break; case TN_SFTDEL: pGenCmd->flags |= SmlSftDel_f; rc = buildEmptyTag(pDecoder); // allow for instead of break; /* Lists */ case TN_ITEM: rc = appendItemList(pDecoder, &pGenCmd->itemList); items++; break; default: rc = SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildGenericCmd"); } if (rc != SML_ERR_OK) { smlFreeGeneric(pGenCmd); return rc; } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlFreeGeneric(pGenCmd); return rc; } } if ((items == 0) || (cmdid == 0)) { smlFreeGeneric(pGenCmd); return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildGenericCmd"); } *ppElem = pGenCmd; return SML_ERR_OK; } Ret_t buildAlert(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem) { XltDecScannerPtr_t pScanner; SmlAlertPtr_t pAlert; Ret_t rc; Long_t cmdid = 0; pScanner = pDecoder->scanner; if (*ppElem != NULL) return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildAlert"); if ((pAlert = (SmlAlertPtr_t)smlLibMalloc(sizeof(SmlAlert_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pAlert, 0, sizeof(SmlAlert_t)); /* initialize the element type field */ pAlert->elementType = SML_PE_ALERT; if (IS_EMPTY(pScanner->curtok)) { smlLibFree(pAlert); return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildAlert"); } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlLibFree(pAlert); return rc; } while (pScanner->curtok->type != TOK_TAG_END) { switch (pScanner->curtok->tagid) { /* PCDATA elements */ case TN_CMDID: rc = buildPCData(pDecoder, (VoidPtr_t)&pAlert->cmdID); cmdid++; break; case TN_DATA: rc = buildPCData(pDecoder, (VoidPtr_t)&pAlert->data); break; /* child tags */ case TN_CRED: rc = buildCred(pDecoder, (VoidPtr_t)&pAlert->cred); break; /* flags (empty tags) */ case TN_NORESP: pAlert->flags |= SmlNoResp_f; rc = buildEmptyTag(pDecoder); // allow for instead of break; /* Lists */ case TN_ITEM: rc = appendItemList(pDecoder, &pAlert->itemList); break; default: rc = SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildAlert"); } if (rc != SML_ERR_OK) { smlFreeAlert(pAlert); return rc; } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlFreeAlert(pAlert); return rc; } } if (cmdid == 0) { smlFreeAlert(pAlert); return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildAlert"); } *ppElem = pAlert; return SML_ERR_OK; } #ifdef MAP_RECEIVE Ret_t buildMap(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem) { XltDecScannerPtr_t pScanner; SmlMapPtr_t pMap; Ret_t rc; Long_t target = 0, source = 0, mapitems = 0, cmdid = 0; pScanner = pDecoder->scanner; if (*ppElem != NULL) return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildMap"); if ((pMap = (SmlMapPtr_t)smlLibMalloc(sizeof(SmlMap_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pMap, 0, sizeof(SmlMap_t)); /* initialize the element type field */ pMap->elementType = SML_PE_MAP; /* Source is required */ if (IS_EMPTY(pScanner->curtok)) { smlLibFree(pMap); return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildMap"); } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlLibFree(pMap); return rc; } while (pScanner->curtok->type != TOK_TAG_END) { switch (pScanner->curtok->tagid) { /* PCDATA elements */ case TN_CMDID: rc = buildPCData(pDecoder, (VoidPtr_t)&pMap->cmdID); cmdid++; break; case TN_META: rc = buildPCData(pDecoder, (VoidPtr_t)&pMap->meta); break; /* child tags */ case TN_CRED: rc = buildCred(pDecoder, (VoidPtr_t)&pMap->cred); break; case TN_SOURCE: rc = buildTargetOrSource(pDecoder, (VoidPtr_t)&pMap->source); source++; break; case TN_TARGET: rc = buildTargetOrSource(pDecoder, (VoidPtr_t)&pMap->target); target++; break; #ifdef MAPITEM_RECEIVE /* Lists */ case TN_MAPITEM: rc = appendMapItemList(pDecoder, &pMap->mapItemList); mapitems++; break; #endif default: rc = SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildMap"); } if (rc != SML_ERR_OK) { smlFreeMap(pMap); return rc; } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlFreeMap(pMap); return rc; } } if ((source == 0) || (mapitems == 0) || (target == 0) || (cmdid == 0)) { smlFreeMap(pMap); return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildMap"); } *ppElem = pMap; return SML_ERR_OK; } #endif #ifdef SEARCH_RECEIVE Ret_t buildSearch(XltDecoderPtr_t pDecoder, VoidPtr_t *ppSearch) { XltDecScannerPtr_t pScanner; SmlSearchPtr_t pSearch; Ret_t rc; Long_t source = 0, meta = 0, data = 0, cmdid = 0; pScanner = pDecoder->scanner; if (*ppSearch != NULL) return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildSearch"); if ((pSearch = (SmlSearchPtr_t)smlLibMalloc(sizeof(SmlSearch_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pSearch, 0, sizeof(SmlSearch_t)); /* initialize the element type field */ pSearch->elementType = SML_PE_SEARCH; /* Meta is required */ if (IS_EMPTY(pScanner->curtok)) { smlLibFree(pSearch); return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildSearch"); } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlLibFree(pSearch); return rc; } while (pScanner->curtok->type != TOK_TAG_END) { switch (pScanner->curtok->tagid) { /* PCDATA elements */ case TN_CMDID: rc = buildPCData(pDecoder, (VoidPtr_t)&pSearch->cmdID); cmdid++; break; case TN_LANG: rc = buildPCData(pDecoder, (VoidPtr_t)&pSearch->lang); break; case TN_META: rc = buildPCData(pDecoder, (VoidPtr_t)&pSearch->meta); meta++; break; case TN_DATA: rc = buildPCData(pDecoder, (VoidPtr_t)&pSearch->data); data++; break; /* child tags */ case TN_CRED: rc = buildCred(pDecoder, (VoidPtr_t)&pSearch->cred); break; case TN_TARGET: rc = buildTargetOrSource(pDecoder, (VoidPtr_t)&pSearch->target); break; /* flags */ case TN_NORESP: pSearch->flags |= SmlNoResp_f; rc = buildEmptyTag(pDecoder); // allow for instead of break; case TN_NORESULTS: pSearch->flags |= SmlNoResults_f; rc = buildEmptyTag(pDecoder); // allow for instead of break; /* Lists */ case TN_SOURCE: rc = appendSourceList(pDecoder, &pSearch->sourceList); source++; break; default: rc = SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildSearch"); } if (rc != SML_ERR_OK) { smlFreeSearch(pSearch); return rc; } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlFreeSearch(pSearch); return rc; } } if ((source == 0) || (meta == 0) || (data == 0) || (cmdid == 0)) { smlFreeSearch(pSearch); return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildSearch"); } *ppSearch = pSearch; return SML_ERR_OK; } #endif Ret_t buildPutOrGet(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem) { XltDecScannerPtr_t pScanner; SmlGetPtr_t pGet; Ret_t rc; Long_t items = 0, cmdid = 0; pScanner = pDecoder->scanner; if (*ppElem != NULL) return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildPutOrGet"); if ((pGet = (SmlGetPtr_t)smlLibMalloc(sizeof(SmlGet_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pGet, 0, sizeof(SmlGet_t)); /* initialize the element type field */ pGet->elementType = SML_PE_PUT_GET; if (IS_EMPTY(pScanner->curtok)) { smlLibFree(pGet); return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildPutOrGet"); } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlLibFree(pGet); return rc; } while (pScanner->curtok->type != TOK_TAG_END) { switch (pScanner->curtok->tagid) { /* PCDATA elements */ case TN_CMDID: rc = buildPCData(pDecoder, (VoidPtr_t)&pGet->cmdID); cmdid++; break; case TN_LANG: rc = buildPCData(pDecoder, (VoidPtr_t)&pGet->lang); break; case TN_META: rc = buildPCData(pDecoder, (VoidPtr_t)&pGet->meta); break; /* child tags */ case TN_CRED: rc = buildCred(pDecoder, (VoidPtr_t)&pGet->cred); break; /* flags */ case TN_NORESP: pGet->flags |= SmlNoResp_f; rc = buildEmptyTag(pDecoder); // allow for instead of break; /* Lists */ case TN_ITEM: rc = appendItemList(pDecoder, &pGet->itemList); items++; break; default: rc = SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildPutOrGet"); } if (rc != SML_ERR_OK) { smlFreeGetPut(pGet); return rc; } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlFreeGetPut(pGet); return rc; } } if ((items == 0) || (cmdid == 0)) { smlFreeGetPut(pGet); return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildPutOrGet"); } *ppElem = pGet; return SML_ERR_OK; } Ret_t buildRecordFieldFilter(XltDecoderPtr_t pDecoder, VoidPtr_t *ppRecordFieldFilter) { XltDecScannerPtr_t pScanner; SmlRecordOrFieldFilterPtr_t pRecordFieldFilter; Long_t item = 0; Ret_t rc; pScanner = pDecoder->scanner; if (*ppRecordFieldFilter != NULL) return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildRecordFieldFilter"); if ((pRecordFieldFilter = (SmlRecordOrFieldFilterPtr_t)smlLibMalloc(sizeof(SmlRecordOrFieldFilter_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pRecordFieldFilter, 0, sizeof(SmlRecordOrFieldFilter_t)); if (IS_EMPTY(pScanner->curtok)) { smlLibFree(pRecordFieldFilter); return SML_ERR_OK; } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlLibFree(pRecordFieldFilter); return rc; } while (pScanner->curtok->type != TOK_TAG_END) { switch (pScanner->curtok->tagid) { /* Item */ case TN_ITEM: rc = buildItem(pDecoder, (VoidPtr_t)&pRecordFieldFilter->item); item++; break; default: rc = SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildRecordFieldFilter"); } if (rc != SML_ERR_OK) { smlFreeRecordFieldFilterPtr(pRecordFieldFilter); return rc; } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlFreeRecordFieldFilterPtr(pRecordFieldFilter); return rc; } } if (item == 0) { smlFreeRecordFieldFilterPtr(pRecordFieldFilter); return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildRecordFieldFilter"); } *ppRecordFieldFilter = pRecordFieldFilter; return SML_ERR_OK; } Ret_t buildFilter(XltDecoderPtr_t pDecoder, VoidPtr_t *ppFilter) { XltDecScannerPtr_t pScanner; SmlFilterPtr_t pFilter; Long_t meta = 0; Ret_t rc; pScanner = pDecoder->scanner; if (*ppFilter != NULL) return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildFilter"); if ((pFilter = (SmlFilterPtr_t)smlLibMalloc(sizeof(SmlFilter_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pFilter, 0, sizeof(SmlFilter_t)); if (IS_EMPTY(pScanner->curtok)) { smlLibFree(pFilter); return SML_ERR_OK; } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlLibFree(pFilter); return rc; } while (pScanner->curtok->type != TOK_TAG_END) { switch (pScanner->curtok->tagid) { /* PCDATA elements */ case TN_META: rc = buildPCData(pDecoder, (VoidPtr_t)&pFilter->meta); meta++; break; /* Record or Field elements */ case TN_FIELD: rc = buildRecordFieldFilter(pDecoder, (VoidPtr_t)&pFilter->field); break; case TN_RECORD: rc = buildRecordFieldFilter(pDecoder, (VoidPtr_t)&pFilter->record); break; /* Flags */ case TN_FILTERTYPE: rc = buildPCData(pDecoder, (VoidPtr_t)&pFilter->filtertype); break; default: rc = SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildFilter"); } if (rc != SML_ERR_OK) { smlFreeFilterPtr(pFilter); return rc; } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlFreeFilterPtr(pFilter); return rc; } } if (meta == 0) { smlFreeFilterPtr(pFilter); return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildFilter"); } *ppFilter = pFilter; return SML_ERR_OK; } Ret_t buildTargetOrSourceParent(XltDecoderPtr_t pDecoder, VoidPtr_t *ppTargetParent) { XltDecScannerPtr_t pScanner; SmlTargetParentPtr_t pTargetParent; Long_t locuri = 0; Ret_t rc; pScanner = pDecoder->scanner; if (*ppTargetParent != NULL) return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildTargetOrSourceParent"); if ((pTargetParent = (SmlTargetParentPtr_t)smlLibMalloc(sizeof(SmlTargetParent_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pTargetParent, 0, sizeof(SmlTargetParent_t)); if (IS_EMPTY(pScanner->curtok)) { smlLibFree(pTargetParent); return SML_ERR_OK; } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlLibFree(pTargetParent); return rc; } while (pScanner->curtok->type != TOK_TAG_END) { switch (pScanner->curtok->tagid) { /* PCDATA elements */ case TN_LOCURI: rc = buildPCData(pDecoder, (VoidPtr_t)&pTargetParent->locURI); locuri++; break; default: rc = SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildTargetOrSourceParent"); } if (rc != SML_ERR_OK) { smlFreeSourceTargetParentPtr(pTargetParent); return rc; } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlFreeSourceTargetParentPtr(pTargetParent); return rc; } } if (locuri == 0) { smlFreeSourceTargetParentPtr(pTargetParent); return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildTargetOrSourceParent"); } *ppTargetParent = pTargetParent; return SML_ERR_OK; } Ret_t buildTargetOrSource(XltDecoderPtr_t pDecoder, VoidPtr_t *ppTarget) { XltDecScannerPtr_t pScanner; SmlTargetPtr_t pTarget; Long_t locuri = 0; Ret_t rc; pScanner = pDecoder->scanner; if (*ppTarget != NULL) return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildTargetOrSourceParent"); if ((pTarget = (SmlTargetPtr_t)smlLibMalloc(sizeof(SmlTarget_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pTarget, 0, sizeof(SmlTarget_t)); if (IS_EMPTY(pScanner->curtok)) { smlLibFree(pTarget); return SML_ERR_OK; } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlLibFree(pTarget); return rc; } while (pScanner->curtok->type != TOK_TAG_END) { switch (pScanner->curtok->tagid) { /* PCDATA elements */ case TN_LOCURI: rc = buildPCData(pDecoder, (VoidPtr_t)&pTarget->locURI); locuri++; break; case TN_LOCNAME: rc = buildPCData(pDecoder, (VoidPtr_t)&pTarget->locName); break; /* SyncML 1.2 Filter element, %%% added 2005-08-17 by synthesis/luz */ case TN_FILTER: rc = buildFilter(pDecoder, (VoidPtr_t)&pTarget->filter); break; default: rc = SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildTargetOrSourceParent"); } if (rc != SML_ERR_OK) { smlFreeSourceTargetPtr(pTarget); return rc; } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlFreeSourceTargetPtr(pTarget); return rc; } } if (locuri == 0) { smlFreeSourceTargetPtr(pTarget); return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildTargetOrSourceParent"); } *ppTarget = pTarget; return SML_ERR_OK; } Ret_t buildChal(XltDecoderPtr_t pDecoder, VoidPtr_t *ppChal) { XltDecScannerPtr_t pScanner; SmlChalPtr_t pChal; Long_t meta = 0; Ret_t rc; pScanner = pDecoder->scanner; if (*ppChal != NULL) return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildChal"); if ((pChal = (SmlChalPtr_t)smlLibMalloc(sizeof(SmlChal_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pChal, 0, sizeof(SmlChal_t)); if (IS_EMPTY(pScanner->curtok)) { *ppChal = pChal; return SML_ERR_OK; } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlLibFree(pChal); return rc; } while (pScanner->curtok->type != TOK_TAG_END) { switch (pScanner->curtok->tagid) { /* PCDATA elements */ case TN_META: rc = buildPCData(pDecoder, (VoidPtr_t)&pChal->meta); meta++; break; default: rc = SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildChal"); } if (rc != SML_ERR_OK) { smlFreeChalPtr(pChal); return rc; } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlFreeChalPtr(pChal); return rc; } } if (meta == 0) { smlFreeChalPtr(pChal); return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildChal"); } *ppChal = pChal; return SML_ERR_OK; } Ret_t buildCred(XltDecoderPtr_t pDecoder, VoidPtr_t *ppCred) { XltDecScannerPtr_t pScanner; SmlCredPtr_t pCred; Ret_t rc; Long_t data = 0; pScanner = pDecoder->scanner; if (*ppCred != NULL) return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildCred"); if ((pCred = (SmlCredPtr_t)smlLibMalloc(sizeof(SmlCred_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pCred, 0, sizeof(SmlCred_t)); if (IS_EMPTY(pScanner->curtok)) { *ppCred = pCred; return SML_ERR_OK; } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlLibFree(pCred); return rc; } while (pScanner->curtok->type != TOK_TAG_END) { switch (pScanner->curtok->tagid) { /* PCDATA elements */ case TN_DATA: rc = buildPCData(pDecoder, (VoidPtr_t)&pCred->data); data++; break; case TN_META: rc = buildPCData(pDecoder, (VoidPtr_t)&pCred->meta); break; default: rc = SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildCred"); } if (rc != SML_ERR_OK) { smlFreeCredPtr(pCred); return rc; } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlFreeCredPtr(pCred); return rc; } } if (data == 0) { smlFreeCredPtr(pCred); return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildCred"); } *ppCred = pCred; return SML_ERR_OK; } Ret_t buildItem(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem) { XltDecScannerPtr_t pScanner; SmlItemPtr_t pItem; Ret_t rc; pScanner = pDecoder->scanner; if (*ppElem != NULL) return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildItem"); if ((pItem = (SmlItemPtr_t)smlLibMalloc(sizeof(SmlItem_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pItem, 0, sizeof(SmlItem_t)); /* Item might be empty */ if (IS_EMPTY(pScanner->curtok)) { *ppElem = pItem; return SML_ERR_OK; } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlLibFree(pItem); return rc; } while (pScanner->curtok->type != TOK_TAG_END) { switch (pScanner->curtok->tagid) { /* PCDATA elements */ case TN_META: rc = buildPCData(pDecoder, (VoidPtr_t)&pItem->meta); break; case TN_DATA: rc = buildPCData(pDecoder, (VoidPtr_t)&pItem->data); #ifdef __USE_EXTENSIONS__ #ifdef __SML_WBXML__ if (pItem->data && pItem->data->contentType == SML_PCDATA_OPAQUE) subdtdDecodeWbxml(pDecoder, (SmlPcdataPtr_t*)&pItem->data); #endif #endif break; /* child tags */ case TN_TARGET: rc = buildTargetOrSource(pDecoder, (VoidPtr_t)&pItem->target); break; case TN_SOURCE: rc = buildTargetOrSource(pDecoder, (VoidPtr_t)&pItem->source); break; case TN_TARGETPARENT: rc = buildTargetOrSourceParent(pDecoder, (VoidPtr_t)&pItem->targetParent); break; case TN_SOURCEPARENT: rc = buildTargetOrSourceParent(pDecoder, (VoidPtr_t)&pItem->sourceParent); break; /* flags */ case TN_MOREDATA: pItem->flags |= SmlMoreData_f; rc = buildEmptyTag(pDecoder); // allow for instead of break; default: rc = SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildItem"); } if (rc != SML_ERR_OK) { smlFreeItemPtr(pItem); return rc; } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlFreeItemPtr(pItem); return rc; } } *ppElem = pItem; return SML_ERR_OK; } #ifdef MAPITEM_RECEIVE Ret_t buildMapItem(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem) { XltDecScannerPtr_t pScanner; SmlMapItemPtr_t pMapItem; Long_t target = 0, source = 0; Ret_t rc; pScanner = pDecoder->scanner; if (*ppElem != NULL) return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildMapItem"); if ((pMapItem = (SmlMapItemPtr_t)smlLibMalloc(sizeof(SmlMapItem_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pMapItem, 0, sizeof(SmlMapItem_t)); if (IS_EMPTY(pScanner->curtok)) { smlLibFree(pMapItem); return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildMapItem"); } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlLibFree(pMapItem); return rc; } while (pScanner->curtok->type != TOK_TAG_END) { switch (pScanner->curtok->tagid) { /* child tags */ case TN_TARGET: rc = buildTargetOrSource(pDecoder, (VoidPtr_t)&pMapItem->target); target++; break; case TN_SOURCE: rc = buildTargetOrSource(pDecoder, (VoidPtr_t)&pMapItem->source); source++; break; default: rc = SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildMapItem"); } if (rc != SML_ERR_OK) { smlFreeMapItemPtr(pMapItem); return rc; } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlFreeMapItemPtr(pMapItem); return rc; } } if ((target == 0) || (source == 0)) { smlFreeMapItemPtr(pMapItem); return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildMapItem"); } *ppElem = pMapItem; return SML_ERR_OK; } #endif Ret_t buildStatus(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem) { XltDecScannerPtr_t pScanner; SmlStatusPtr_t pStatus; Ret_t rc; Long_t cmd = 0, data = 0, cmdid = 0; pScanner = pDecoder->scanner; if (*ppElem != NULL) return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildStatus"); if ((pStatus = (SmlStatusPtr_t)smlLibMalloc(sizeof(SmlStatus_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pStatus, 0, sizeof(SmlStatus_t)); /* initialize the element type field */ pStatus->elementType = SML_PE_STATUS; if (IS_EMPTY(pScanner->curtok)) { smlLibFree(pStatus); return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildStatus"); } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlLibFree(pStatus); return rc; } while (pScanner->curtok->type != TOK_TAG_END) { switch (pScanner->curtok->tagid) { /* PCData elements */ case TN_CMDID: rc = buildPCData(pDecoder, (VoidPtr_t)&pStatus->cmdID); cmdid++; break; case TN_MSGREF: rc = buildPCData(pDecoder, (VoidPtr_t)&pStatus->msgRef); break; case TN_CMDREF: rc = buildPCData(pDecoder, (VoidPtr_t)&pStatus->cmdRef); break; case TN_CMD: rc = buildPCData(pDecoder, (VoidPtr_t)&pStatus->cmd); cmd++; break; case TN_DATA: rc = buildPCData(pDecoder, (VoidPtr_t)&pStatus->data); data++; break; case TN_CHAL: rc = buildChal(pDecoder, (VoidPtr_t)&pStatus->chal); break; case TN_CRED: rc = buildCred(pDecoder, (VoidPtr_t)&pStatus->cred); break; /* Lists */ case TN_ITEM: rc = appendItemList(pDecoder, (VoidPtr_t)&pStatus->itemList); break; case TN_TARGETREF: rc = appendTargetRefList(pDecoder, (VoidPtr_t)&pStatus->targetRefList); break; case TN_SOURCEREF: rc = appendSourceRefList(pDecoder, (VoidPtr_t)&pStatus->sourceRefList); break; default: rc = SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildStatus"); } if (rc != SML_ERR_OK) { smlFreeStatus(pStatus); return rc; } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlFreeStatus(pStatus); return rc; } } if ((cmd == 0) || (data == 0) || (cmdid == 0)) { smlFreeStatus(pStatus); return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildStatus"); } *ppElem = pStatus; return SML_ERR_OK; } #ifdef RESULT_RECEIVE Ret_t buildResults(XltDecoderPtr_t pDecoder, VoidPtr_t *ppResults) { XltDecScannerPtr_t pScanner; SmlResultsPtr_t pResults; Ret_t rc; Long_t cmdref = 0, items = 0, cmdid = 0; pScanner = pDecoder->scanner; if (*ppResults != NULL) return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildResults"); if ((pResults = (SmlResultsPtr_t)smlLibMalloc(sizeof(SmlResults_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pResults, 0, sizeof(SmlResults_t)); /* initialize the element type field */ pResults->elementType = SML_PE_RESULTS; if (IS_EMPTY(pScanner->curtok)) { smlLibFree(pResults); return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildResults"); } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlLibFree(pResults); return rc; } while (pScanner->curtok->type != TOK_TAG_END) { switch (pScanner->curtok->tagid) { /* PCDATA elements */ case TN_CMDID: rc = buildPCData(pDecoder, (VoidPtr_t)&pResults->cmdID); cmdid++; break; case TN_MSGREF: rc = buildPCData(pDecoder, (VoidPtr_t)&pResults->msgRef); break; case TN_CMDREF: rc = buildPCData(pDecoder, (VoidPtr_t)&pResults->cmdRef); cmdref++; break; case TN_META: rc = buildPCData(pDecoder, (VoidPtr_t)&pResults->meta); break; case TN_TARGETREF: rc = buildPCData(pDecoder, (VoidPtr_t)&pResults->targetRef); break; case TN_SOURCEREF: rc = buildPCData(pDecoder, (VoidPtr_t)&pResults->sourceRef); break; /* Lists */ case TN_ITEM: rc = appendItemList(pDecoder, &pResults->itemList); items++; break; default: rc = SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildResults"); } if (rc != SML_ERR_OK) { smlFreeResults(pResults); return rc; } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlFreeResults(pResults); return rc; } } if ((cmdref == 0) || (items == 0) || (cmdid == 0)) { smlFreeResults(pResults); return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildResults"); } *ppResults = pResults; return SML_ERR_OK; } #endif /// @brief can be called to process both forms of an empty tag ( and Ret_t buildEmptyTag(XltDecoderPtr_t pDecoder) { Ret_t rc; // if current tag is empty (that is, ist a start-and-end like ), that's simply ok if (IS_EMPTY(pDecoder->scanner->curtok)) return SML_ERR_OK; // otherwise, we need a next tag... if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) return rc; // no next tag found // ...and it must be a closing tag if (!IS_END(pDecoder->scanner->curtok)) return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pDecoder->scanner,"buildEmptyTag"); // yep, ok return SML_ERR_OK; } Ret_t buildPCData(XltDecoderPtr_t pDecoder, VoidPtr_t *ppPCData) { XltDecScannerPtr_t pScanner; SmlPcdataPtr_t pPCData = 0; SmlPcdataExtension_t ext; Ret_t rc; pScanner = pDecoder->scanner; if (*ppPCData != NULL) return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildPCData_1"); if (IS_EMPTY(pScanner->curtok)) { if ((pPCData = (SmlPcdataPtr_t)smlLibMalloc(sizeof(SmlPcdata_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pPCData, 0, sizeof(SmlPcdata_t)); *ppPCData = pPCData; return SML_ERR_OK; } pPCData = NULL; if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { if (rc == SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildPCData_2")) { /* leaks if dtd failed */ pPCData = pScanner->curtok->pcdata; *ppPCData = pPCData; } return rc; } if (IS_CONTENT(pScanner->curtok)) { /* PCData element has a regular string or opaque content */ while (pScanner->curtok->type == TOK_CONT) { if (pPCData == NULL) pPCData = pScanner->curtok->pcdata; else { pPCData = concatPCData(pPCData, pScanner->curtok->pcdata); smlLibFree(pScanner->curtok->pcdata->content); smlLibFree(pScanner->curtok->pcdata); if (pPCData == NULL) return SML_DECODEERROR(SML_ERR_XLT_INVAL_PCDATA,pScanner,"buildPCData_3"); } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { *ppPCData = pPCData; return rc; } } } else if (IS_START_OR_EMPTY(pScanner->curtok)) { /* PCData element contains an XML dokument that is handled by an extension mechanism */ ext = pScanner->curtok->ext; if ((rc = discardToken(pDecoder)) != SML_ERR_OK) return rc; if ((pPCData = (SmlPcdataPtr_t)smlLibMalloc(sizeof(SmlPcdata_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pPCData, 0, sizeof(SmlPcdata_t)); pPCData->contentType = SML_PCDATA_EXTENSION; pPCData->extension = ext; switch (ext) { #ifdef __USE_METINF__ case SML_EXT_METINF: if ((rc = buildMetInfMetInfCmd(pDecoder, (VoidPtr_t)&pPCData->content)) != SML_ERR_OK) { smlLibFree(pPCData); return rc; } break; #endif #ifdef __USE_DEVINF__ case SML_EXT_DEVINF: if ((rc = buildDevInfDevInfCmd(pDecoder, (VoidPtr_t)&pPCData->content)) != SML_ERR_OK) { smlLibFree(pPCData); return rc; } /* the scanner must point to the closing PCDATA tag */ if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlLibFree(pPCData); return rc; } break; #endif default: // %%% luz 2005-11-11 : added fallback to MetInf (workaround for ill-formed xml like in sync4j pda clients) // if undefined, try with metinf for ill-formatted xml like from sync4j palm client // - act like we had detected a switch in namespace to METINF pPCData->contentType = SML_PCDATA_EXTENSION; pPCData->extension = SML_EXT_METINF; pScanner->curtok->ext = SML_EXT_METINF; if ((rc = buildMetInfMetInfCmd(pDecoder, (VoidPtr_t)&pPCData->content)) != SML_ERR_OK) { smlLibFree(pPCData); return SML_DECODEERROR(SML_ERR_XLT_INVAL_EXT,pScanner,"buildPCData_4"); // if we fail parsing meta here, this is an invalid extension } break; } // switch } else if (IS_END(pScanner->curtok)) { /* PCData element is empty */ } else { return SML_DECODEERROR(SML_ERR_XLT_INVAL_PCDATA,pScanner,"buildPCData_5"); } if (pScanner->curtok->type != TOK_TAG_END) return SML_DECODEERROR(SML_ERR_XLT_INVAL_PCDATA,pScanner,"buildPCData_6"); if (pPCData == NULL) { if ((pPCData = (SmlPcdataPtr_t)smlLibMalloc(sizeof(SmlPcdata_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pPCData, 0, sizeof(SmlPcdata_t)); } *ppPCData = pPCData; return SML_ERR_OK; } Ret_t buildPCDataList(XltDecoderPtr_t pDecoder, VoidPtr_t *ppPCData) { SmlPcdataListPtr_t pPCDataList = NULL, pPrev = NULL; pPCDataList = (SmlPcdataListPtr_t) *ppPCData; /* advance to the end of the list, and create ther an empty list element */ while (pPCDataList != NULL) { pPrev = pPCDataList; pPCDataList = pPrev->next; } if ((pPCDataList = (SmlPcdataListPtr_t)smlLibMalloc(sizeof(SmlPcdataList_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pPCDataList, 0, sizeof(SmlPcdataList_t)); if (pPrev != NULL) /* we already had some entries in the list */ pPrev->next = pPCDataList; else /* nope we created a new list */ *ppPCData = pPCDataList; pPCDataList->data = NULL; /* at this point pPCDataList should point to an valid list element */ return buildPCData(pDecoder, (VoidPtr_t)&pPCDataList->data); } static Ret_t appendItemList(XltDecoderPtr_t pDecoder, SmlItemListPtr_t *ppItemList) { SmlItemListPtr_t pNewItemList; SmlItemListPtr_t pItemList; Ret_t rc; pItemList = *ppItemList; if (pItemList != NULL) while (pItemList->next != NULL) pItemList = pItemList->next; if ((pNewItemList = (SmlItemListPtr_t)smlLibMalloc(sizeof(SmlItemList_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pNewItemList, 0, sizeof(SmlItemList_t)); if ((rc = buildItem(pDecoder, (VoidPtr_t)&pNewItemList->item)) != SML_ERR_OK) { smlLibFree(pNewItemList); return rc; } if (pItemList == NULL) *ppItemList = pNewItemList; else pItemList->next = pNewItemList; return SML_ERR_OK; } #ifdef SEARCH_RECEIVE static Ret_t appendSourceList(XltDecoderPtr_t pDecoder, SmlSourceListPtr_t *ppSourceList) { SmlSourceListPtr_t pNewSourceList; SmlSourceListPtr_t pSourceList; Ret_t rc; pSourceList = *ppSourceList; if (pSourceList != NULL) while (pSourceList->next != NULL) pSourceList = pSourceList->next; if ((pNewSourceList = (SmlSourceListPtr_t)smlLibMalloc(sizeof(SmlSourceList_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pNewSourceList, 0, sizeof(SmlSourceList_t)); if ((rc = buildTargetOrSource(pDecoder, (VoidPtr_t)&pNewSourceList->source)) != SML_ERR_OK) { smlLibFree(pNewSourceList); return rc; } if (pSourceList == NULL) *ppSourceList = pNewSourceList; else pSourceList->next = pNewSourceList; return SML_ERR_OK; } #endif /* SEARCH_RECEIVE */ #ifdef MAPITEM_RECEIVE static Ret_t appendMapItemList(XltDecoderPtr_t pDecoder, SmlMapItemListPtr_t *ppMapItemList) { SmlMapItemListPtr_t pNewMapItemList; SmlMapItemListPtr_t pMapItemList; Ret_t rc; pMapItemList = *ppMapItemList; if (pMapItemList != NULL) while (pMapItemList->next != NULL) pMapItemList = pMapItemList->next; if ((pNewMapItemList = (SmlMapItemListPtr_t)smlLibMalloc(sizeof(SmlMapItemList_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pNewMapItemList, 0, sizeof(SmlMapItemList_t)); if ((rc = buildMapItem(pDecoder, (VoidPtr_t)&pNewMapItemList->mapItem)) != SML_ERR_OK) { smlLibFree(pNewMapItemList); return rc; } if (pMapItemList == NULL) *ppMapItemList = pNewMapItemList; else pMapItemList->next = pNewMapItemList; return SML_ERR_OK; } #endif static Ret_t appendTargetRefList(XltDecoderPtr_t pDecoder, SmlTargetRefListPtr_t *ppTargetRefList) { SmlTargetRefListPtr_t pNewTargetRefList; SmlTargetRefListPtr_t pTargetRefList; Ret_t rc; pTargetRefList = *ppTargetRefList; if (pTargetRefList != NULL) while (pTargetRefList->next != NULL) pTargetRefList = pTargetRefList->next; if ((pNewTargetRefList = (SmlTargetRefListPtr_t)smlLibMalloc(sizeof(SmlTargetRefList_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pNewTargetRefList, 0, sizeof(SmlTargetRefList_t)); if ((rc = buildPCData(pDecoder, (VoidPtr_t)&pNewTargetRefList->targetRef)) != SML_ERR_OK) { smlFreePcdata(pNewTargetRefList->targetRef); smlLibFree(pNewTargetRefList); return rc; } if (pTargetRefList == NULL) *ppTargetRefList = pNewTargetRefList; else pTargetRefList->next = pNewTargetRefList; return SML_ERR_OK; } static Ret_t appendSourceRefList(XltDecoderPtr_t pDecoder, SmlSourceRefListPtr_t *ppSourceRefList) { SmlSourceRefListPtr_t pNewSourceRefList; SmlSourceRefListPtr_t pSourceRefList; Ret_t rc; pSourceRefList = *ppSourceRefList; if (pSourceRefList != NULL) while (pSourceRefList->next != NULL) pSourceRefList = pSourceRefList->next; if ((pNewSourceRefList = (SmlSourceRefListPtr_t)smlLibMalloc(sizeof(SmlSourceRefList_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pNewSourceRefList, 0, sizeof(SmlSourceRefList_t)); if ((rc = buildPCData(pDecoder, (VoidPtr_t)&pNewSourceRefList->sourceRef)) != SML_ERR_OK) { smlFreePcdata(pNewSourceRefList->sourceRef); smlLibFree(pNewSourceRefList); return rc; } if (pSourceRefList == NULL) *ppSourceRefList = pNewSourceRefList; else pSourceRefList->next = pNewSourceRefList; return SML_ERR_OK; } libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/xlt/all/xltdeccom.h000077500000000000000000000167321226375725500245460ustar00rootroot00000000000000/** * @file * XML/WBXML scanner * * @target_system all * @target_os all * @description Common header file for the WBXML and the XML scanner. */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ /*************************************************************************/ /* Definitions */ /*************************************************************************/ #ifndef _XLT_DEC_COM_H #define _XLT_DEC_COM_H #include #include #include "xlttags.h" #define DEC_ID XLT_DEC_ID + 0 #define WBXML_ID XLT_DEC_ID + 200 #define XML_ID XLT_DEC_ID + 400 #define STACK_ID XLT_DEC_ID + 600 #ifdef __cplusplus extern "C" { #endif /* Token types returned by the scanner */ typedef enum { TOK_UNDEF = 0, TOK_TAG_START, TOK_TAG_END, TOK_TAG_EMPTY, TOK_CONT } XltTokType_t; /** * Struct containing a token returned by the scanner */ typedef struct { XltTokType_t type; /**< TOK_TAG_START, etc. */ XltTagID_t tagid; /**< TN_SYNCHDR, etc. - valid for token of type * TOK_TAG_xxx */ SmlPcdataExtension_t ext; /**< type of extension this tag belongs to - * valid for token of type TOK_TAG_xxx */ SmlPcdataPtr_t pcdata; /**< valid for token of type TOK_CONT */ MemPtr_t start; /**< pointer to the start of this token within * the document - needed for pushback */ } XltDecToken_t, *XltDecTokenPtr_t; /** @copydoc XltDecScanner_s */ typedef struct XltDecScanner_s XltDecScanner_t, *XltDecScannerPtr_t; /** * Public interface for the XML/WBXML scanner components. * * The struct used for holding the XML and WBXML scanner state information * are the same - function pointers are used to map the "objects" public * methods to the right functions for scanning XML and WBXML documents. * This object-oriented interface enables the parser component to use the * two scanners interchangeably. * The interface contains serveral public methods and attributes: */ struct XltDecScanner_s { /* public methods */ /** * Decodes the next valid token at the current position within the * document. Information about this token is placed into the curtok * attribute of the scanner object. * * @post curtok contains the last valid token. * @param pScanner (IN/OUT) * the scanner * @return SML_ERR_OK or an appropriate error code */ Ret_t (*nextTok)(XltDecScannerPtr_t pScanner); /** * Free the memory allocated by the scanner. * * @param pScanner (IN/OUT) * the scanner * @return SML_ERR_OK or an appropriate error code */ Ret_t (*destroy)(XltDecScannerPtr_t pScanner); /** * Resets the scanner to the beginning position within the document of the * last valid token stored in curtok. Only the last found token can be * pushed back. It is not possible to go back more than one token. * * @pre curtok contains a valid token. * @post the next call of nextTok will find the token that was pushed back. * @param pScanner (IN/OUT) * the scanner * @return SML_ERR_OK or an appropriate error code */ Ret_t (*pushTok)(XltDecScannerPtr_t pScanner); /** * Set the buffer the scanner works on. */ void (*setBuf)(XltDecScannerPtr_t pScanner, const MemPtr_t pBufStart, const MemPtr_t pBufEnd); /** * Get the current position of the scanner within the working buffer. * * @param pScanner (IN/OUT) * the scanner * @param remaining (OUT) * number of valid bytes after current position, optional (NULL acceptable) */ MemPtr_t (*getPos)(XltDecScannerPtr_t pScanner, Long_t *remaining); /* public attributes */ /** Contains the last valid token found by a call to nextTok. */ XltDecTokenPtr_t curtok; /** * The charset information as specified in the XML/WBXML document. * This is the IANA assigned MIBEnum value. */ Long_t charset; /** * String representation of the charset. This attribute is valid only when * charset equals zero. Otherwise charsetStr will be NULL. */ String_t charsetStr; /** * The document public identifier as specified in the XML/WBXML document. * This is the numeric identifier assigned by the WAP Forum. If this value * is zero, the public ID is instead specified as a string contained in the * pubIDStr public attribute. */ Long_t pubID; /** * The string representation of the document public identifier as specified * in the XML/WBXML document (e.g. "-//WAPFORUM//DTD WML 1.0//EN"). This * attribute is valid only when pubID equals zero. Otherwise pubIDStr will * be NULL. */ String_t pubIDStr; /** * This flag is set by the nextTok method when the scanner reaches the end * of the buffer. */ Flag_t finished; }; /** * Initialize a new WBXML scanner. * * @pre ppScanner is NULL * @post ppScanner points to an initialized scanner status object * @param pBufEnd (IN) * buffer containing the WBXML/XML document * @param ppBufPos (IN/OUT) * pointer to the current position within the buffer * @param ppScanner (OUT) * a new WBXML/XML scanner status object * @return SML_ERR_OK or an appropriate error code */ Ret_t xltDecWbxmlInit(const MemPtr_t pBufEnd, MemPtr_t *ppBufPos, XltDecScannerPtr_t *ppScanner); /** * Initialize a new XML scanner. * * @copydoc xltDecWbxmlInit */ Ret_t xltDecXmlInit(const MemPtr_t pBufEnd, MemPtr_t *ppBufPos, XltDecScannerPtr_t *ppScanner); #ifdef __cplusplus } #endif #endif libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/xlt/all/xltdecwbxml.c000077500000000000000000001053111226375725500251040ustar00rootroot00000000000000/** * @file * WBXML decoder * * @target_system all * @target_os all * @description The WBXML scanner/tokenizer. Used by the SyncML parser. */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ #include "syncml_tk_prefix_file.h" // %%% luz: needed for precompiled headers in eVC++ #include "define.h" #ifdef __SML_WBXML__ /*************************************************************************/ /* Definitions */ /*************************************************************************/ #include "xltdevinf.h" #include "xltdeccom.h" #include "xlttags.h" #include "xltutilstack.h" #include "xltdec.h" #include "smldtd.h" #include "smldevinfdtd.h" #include "smlmetinfdtd.h" #include "mgrutil.h" #include #include #include #ifdef IS_END /* to avoid redefinition of this macro */ #undef IS_END #endif void subdtdDecodeWbxml(XltDecoderPtr_t pDecoder,SmlPcdataPtr_t *ppPcdata); /* WBXML version that this parser knows */ #define _MAJOR_VERSION 1 #define _MINOR_VERSION 2 #define _MAX_PARSER_MINOR_VERSION 3 // luz: WBXML 1.3 seems to work identically in the SyncML context #define TAG_STATE 0 #define ATTRIBUTE_STATE 1 /* various checks about wbxml token */ #define HAS_ATTRIBUTES(tag) (*tag & 0x80) #define HAS_CONTENT(tag) (*tag & 0x40) #define IDENTITY(tag) (*tag & 0x3F) #define IS_SWITCH(tok) (*(tok) == 0x00) #define IS_END(tok) (*(tok) == 0x01) #define IS_ENTITY(tok) (*(tok) == 0x02) #define IS_STR_I(tok) (*(tok) == 0x03) #define IS_LITERAL(tok) (IDENTITY(tok) == 0x04) // Note: gcc cannot parse multi-line macros when file has DOS line ends #define IS_EXT_I(tok) ((*(tok) == 0x40) || (*(tok) == 0x41) || (*(tok) == 0x42)) #define IS_PI(tok) (*(tok) == 0x43) #define IS_EXT_T(tok) ((*(tok) == 0x80) || (*(tok) == 0x81) || (*(tok) == 0x82)) #define IS_STR_T(tok) (*(tok) == 0x83) #define IS_EXT(tok) ((*(tok) == 0xC0) || (*(tok) == 0xC1) || (*(tok) == 0xC2)) #define IS_OPAQUE(tok) (*(tok) == 0xC3) #define IS_STRING(tok) (IS_STR_I(tok) || IS_STR_T(tok)) #define IS_EXTENSION(tok) (IS_EXT_I(tok) || IS_EXT_T(tok) || IS_EXT(tok)) #define IS_ATTRIBUTE_VALUE(tok) (*(tok) & 0x80) #define IS_ATTRIBUTE_START(tok) (~IS_ATTRIBUTE_VALUE(tok)) /** @copydoc wbxmlScannerPriv_s */ typedef struct wbxmlScannerPriv_s wbxmlScannerPriv_t, *wbxmlScannerPrivPtr_t; /** * Private Interface for the WBXML scanner. * * The private scanner interface contains some additional member attributes * that are not listed in the public interface, e.g. a copy of the string * table and some other items that do not need to be known outside the * scanner module. */ struct wbxmlScannerPriv_s { /* public methods */ Ret_t (*nextTok)(XltDecScannerPtr_t); Ret_t (*destroy)(XltDecScannerPtr_t); Ret_t (*pushTok)(XltDecScannerPtr_t); void (*setBuf)(XltDecScannerPtr_t pScanner, const MemPtr_t pBufStart, const MemPtr_t pBufEnd); MemPtr_t (*getPos)(XltDecScannerPtr_t pScanner, Long_t *remaining); /* public attributes */ XltDecTokenPtr_t curtok; /**< current token */ Long_t charset; /**< character set as specified in the WBXML header */ String_t charsetStr; /**< NULL */ Long_t pubID; /**< document public identifier as specified in the WBXML header */ String_t pubIDStr; /**< pubID as a string - valid only when pubID == 0 */ Flag_t finished; /**< set when end of buffer is reached */ /* private attributes */ MemPtr_t pos; /**< current buffer position */ MemPtr_t bufend; /**< end of buffer */ Long_t pubIDIdx; /**< strtbl index of the string version of the pubID - valid only when pubID == 0 */ XltUtilStackPtr_t tagstack; /**< stack of open start tags */ MemPtr_t strtbl; /**< copy of the string table */ Long_t strtbllen; /**< length of the string table */ Byte_t state; /**< tag state or attribute state */ SmlPcdataExtension_t cptag; /**< current codepage for tags */ Byte_t cpattr; /**< current codepage for attributes */ SmlPcdataExtension_t activeExt; /**< the active Sub DTD */ }; /* typedef for multi-byte unsigned integers as specified in the WAP Binary XML Content Format specification */ typedef Long_t MBINT; /* * Public methods of the scanner interface. * * Description see XLTDecCom.h. */ static Ret_t _destroy(XltDecScannerPtr_t); static Ret_t _nextTok(XltDecScannerPtr_t); static Ret_t _pushTok(XltDecScannerPtr_t); static void _setBuf(XltDecScannerPtr_t, const MemPtr_t, const MemPtr_t); static MemPtr_t _getPos(XltDecScannerPtr_t, Long_t *remaining); /** * Advance the current position pointer after checking whether the end of * the buffer has been reached. If the end of the buffer has been reached * the scanner's finished flag is set. * * @return 0, if end of buffer has been reached * 1 otherwise */ static Boolean_t readBytes(wbxmlScannerPrivPtr_t pScanner, Long_t bytes); /** * Decodes multi-byte integers. * * @pre pScanner->pos points to the first byte of the mb_int. * @post pScanner->pos points to the last byte of the mb_int. */ static Ret_t parseInt(wbxmlScannerPrivPtr_t pScanner, MBINT *mbi); /** * wbxmlHeader, wbxmlVersion, wbxmlPublicID, wbxmlCharset * * These functions are used for decoding the WBXML document header. * wbxmlHeader is a short wrapper that calls the other four functions in * the right order to scan the header. wbxmlStrtbl makes a copy of the * string table. */ static Ret_t wbxmlHeader(wbxmlScannerPrivPtr_t pScanner); static Ret_t wbxmlVersion(wbxmlScannerPrivPtr_t pScanner); static Ret_t wbxmlPublicID(wbxmlScannerPrivPtr_t pScanner); static Ret_t wbxmlCharset(wbxmlScannerPrivPtr_t pScanner); static Ret_t wbxmlStrtbl(wbxmlScannerPrivPtr_t pScanner); /** * Switch WBXML code page */ static Ret_t wbxmlSwitchPage(wbxmlScannerPrivPtr_t pScanner); /** * wbxmlXXXToken * * Scan the document for the next valid XML/WBXML token as defined in the * XLTDecCom header file (e.g. TOK_TAG_START). * * @pre pScanner->pos points to the first byte of a valid WBXML * element (String, Tag, etc.) * @post pScanner->pos points to the last byte of the WBXML element; * pScanner->curtok contains type and tagid or pcdata of the token */ static Ret_t wbxmlStringToken(wbxmlScannerPrivPtr_t pScanner); static Ret_t wbxmlOpaqueToken(wbxmlScannerPrivPtr_t pScanner); static Ret_t wbxmlTagToken(wbxmlScannerPrivPtr_t pScanner); /** * wbxmlSkipXXX * * WBXML extensions, entities, processing instructions and attributes are * not supported by this scanner. If one is found it is skipped and * processing continues afterwards. */ static Ret_t wbxmlSkipExtension(wbxmlScannerPrivPtr_t pScanner); static Ret_t wbxmlSkipEntity(wbxmlScannerPrivPtr_t pScanner); static Ret_t wbxmlSkipPI(wbxmlScannerPrivPtr_t); static Ret_t wbxmlSkipAttribute(wbxmlScannerPrivPtr_t); /*************************************************************************/ /* External Functions */ /*************************************************************************/ /* * Create and initialize a new WBXML scanner. Description see XLTDec.h. */ Ret_t xltDecWbxmlInit(const MemPtr_t pBufEnd, MemPtr_t *ppBufPos, XltDecScannerPtr_t *ppScanner) { wbxmlScannerPrivPtr_t pScanner; Ret_t rc; /* initialize new WBXML scanner */ if ((pScanner = (wbxmlScannerPrivPtr_t)smlLibMalloc(sizeof(wbxmlScannerPriv_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pScanner, 0, sizeof(wbxmlScannerPriv_t)); pScanner->bufend = pBufEnd; pScanner->pos = *ppBufPos; if ((pScanner->curtok = (XltDecTokenPtr_t)smlLibMalloc(sizeof(XltDecToken_t))) == NULL) { smlLibFree(pScanner); *ppScanner = NULL; return SML_ERR_NOT_ENOUGH_SPACE; } smlLibMemset(pScanner->curtok, 0, sizeof(XltDecToken_t)); if ((rc = xltUtilCreateStack(&pScanner->tagstack, 10)) != SML_ERR_OK) { smlLibFree(pScanner->curtok); smlLibFree(pScanner); *ppScanner = NULL; return rc; } pScanner->state = TAG_STATE; /* point public/private methods to the right implementation */ pScanner->nextTok = _nextTok; pScanner->destroy = _destroy; pScanner->pushTok = _pushTok; pScanner->setBuf = _setBuf; pScanner->getPos = _getPos; /* decode WBXML header */ if ((rc = wbxmlHeader(pScanner)) != SML_ERR_OK) { pScanner->destroy((XltDecScannerPtr_t)pScanner); *ppScanner = NULL; return rc; } *ppScanner = (XltDecScannerPtr_t)pScanner; return SML_ERR_OK; } /** * Free memory. Description see XltDecAll.h. */ static Ret_t _destroy(XltDecScannerPtr_t pScanner) { wbxmlScannerPrivPtr_t pScannerPriv; if (pScanner == NULL) return SML_ERR_OK; pScannerPriv = (wbxmlScannerPrivPtr_t)pScanner; if (pScannerPriv->tagstack != NULL) pScannerPriv->tagstack->destroy(pScannerPriv->tagstack); smlLibFree(pScannerPriv->curtok); smlLibFree(pScannerPriv->strtbl); smlLibFree(pScannerPriv); return SML_ERR_OK; } /** * Get next token. */ static Ret_t _nextTok(XltDecScannerPtr_t pScanner) { wbxmlScannerPrivPtr_t pScannerPriv; Ret_t rc; pScannerPriv = (wbxmlScannerPrivPtr_t)pScanner; // T.K.: chanched Ptr_t to _t smlLibMemset(pScanner->curtok, 0, sizeof(XltDecToken_t)); pScannerPriv->curtok->start = pScannerPriv->pos; /* keep going until we find a "supported" element */ rc = SML_ERR_OK; while (rc == SML_ERR_OK) { /* skip PIs, extensions and entities... */ if (IS_PI(pScannerPriv->pos)) { rc = wbxmlSkipPI(pScannerPriv); } else if (IS_EXTENSION(pScannerPriv->pos)) { rc = wbxmlSkipExtension(pScannerPriv); } else if (IS_ENTITY(pScannerPriv->pos)) { rc = wbxmlSkipEntity(pScannerPriv); /* ... decode strings, opaque data and tags */ } else if (IS_STRING(pScannerPriv->pos)) { rc = wbxmlStringToken(pScannerPriv); break; } else if (IS_OPAQUE(pScannerPriv->pos)) { rc = wbxmlOpaqueToken(pScannerPriv); break; } else { rc = wbxmlTagToken(pScannerPriv); break; } } return rc; } /** * Reset the scanner to the starting position of the current token within * the buffer. */ static Ret_t _pushTok(XltDecScannerPtr_t pScanner) { wbxmlScannerPrivPtr_t pScannerPriv; XltUtilStackPtr_t pTagStack; XltTagID_t tagid; Ret_t rc = 0; pScannerPriv = (wbxmlScannerPrivPtr_t)pScanner; pTagStack = pScannerPriv->tagstack; if (pScannerPriv->curtok->start == NULL) return SML_ERR_WRONG_USAGE; /* reset scanner to position where tok begins */ pScannerPriv->pos = pScannerPriv->curtok->start; /* correct the tag stack */ if (pScannerPriv->curtok->type == TOK_TAG_START) { rc = pTagStack->pop(pTagStack, &tagid); } else if (pScannerPriv->curtok->type == TOK_TAG_END) { tagid = pScannerPriv->curtok->tagid; rc = pTagStack->push(pTagStack, tagid); } if (rc) return rc; /* invalidate curtok */ /* T.K. Possible Error. pScannerPriv->curtok is of type XltDecToken_t NOT ...Ptr_t */ // OrigLine: // smlLibMemset(pScannerPriv->curtok, 0, sizeof(XltDecTokenPtr_t)); pScannerPriv->curtok->type = (XltTokType_t)0; return SML_ERR_OK; } static void _setBuf(XltDecScannerPtr_t pScanner, const MemPtr_t pBufStart, const MemPtr_t pBufEnd) { wbxmlScannerPrivPtr_t pScannerPriv = (wbxmlScannerPrivPtr_t)pScanner; pScannerPriv->pos = pBufStart; pScannerPriv->bufend = pBufEnd; } static MemPtr_t _getPos(XltDecScannerPtr_t pScanner, Long_t *remaining) { if (remaining) *remaining = ((wbxmlScannerPrivPtr_t)pScanner)->bufend - ((wbxmlScannerPrivPtr_t)pScanner)->pos; return ((wbxmlScannerPrivPtr_t)pScanner)->pos; } /*************************************************************************/ /* Internal Functions */ /*************************************************************************/ /* * Advance the position pointer. Description see above. */ static Boolean_t readBytes(wbxmlScannerPrivPtr_t pScanner, Long_t bytes) { if (pScanner->pos + bytes > pScanner->bufend) { pScanner->finished = 1; return 0; } pScanner->pos += bytes; return 1; } /* * NOTICE: Entities, Extensions, Processing Instructions and Attributes * are not supported by the WBXML scanner. * * Extensions and Attributes are document-specific and are as such not used * by the SyncML specification. * The scanner will just ignore and skip over them. Neither * this scanner nor the parser use processing instructions so they are * skipped as well. */ /* * Decode the WBXML header containing version number, document public * identifier, character set and a string table. */ static Ret_t wbxmlHeader(wbxmlScannerPrivPtr_t pScanner) { Ret_t rc; /* decode the WBXML header */ if ((rc = wbxmlVersion(pScanner)) != SML_ERR_OK) return rc; if ((rc = wbxmlPublicID(pScanner)) != SML_ERR_OK) return rc; if ((rc = wbxmlCharset(pScanner)) != SML_ERR_OK) return rc; if ((rc = wbxmlStrtbl(pScanner)) != SML_ERR_OK) return rc; return SML_ERR_OK; } /** * Decode WBXML version. The scanner returns an error if the major version * of the document differs from the major version this scanner supports or * if the minor version of the document is larger than the minor version * the scanner supports. */ static Ret_t wbxmlVersion(wbxmlScannerPrivPtr_t pScanner) { Byte_t major, minor; minor = ((Byte_t)(*pScanner->pos & 0x0F)); major = ((Byte_t)((*pScanner->pos >> 4) + 1)); if (major != _MAJOR_VERSION || minor > _MAX_PARSER_MINOR_VERSION) return SML_DECODEERROR(SML_ERR_XLT_INCOMP_WBXML_VERS,pScanner,"wbxmlVersion"); if (!readBytes(pScanner, 1)) return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlVersion"); return SML_ERR_OK; } /** * Decodes WBXML Document Public Identifier. */ static Ret_t wbxmlPublicID(wbxmlScannerPrivPtr_t pScanner) { MBINT tmp; Ret_t rc; if (*pScanner->pos != 0) { /* pre-defined numeric identifier */ if ((rc = parseInt(pScanner, &tmp)) != SML_ERR_OK) return rc; pScanner->pubID = tmp; pScanner->pubIDIdx = 0; } else { /* public id is given as string table entry (which we haven't read at this point so we'll save the reference for later) */ if (!readBytes(pScanner, 1)) return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlPublicID"); if ((rc = parseInt(pScanner, &tmp)) != SML_ERR_OK) return rc; pScanner->pubID = 0; pScanner->pubIDIdx = tmp; } if (!readBytes(pScanner, 1)) return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlPublicID"); return SML_ERR_OK; } /** * Decode WBXML Charset. */ static Ret_t wbxmlCharset(wbxmlScannerPrivPtr_t pScanner) { /* TODO: if charset iformation has to be processed it can be done here. For the moment only UTF-8 is used by SyncML */ MBINT mibenum; Ret_t rc; /* charset is given as a single IANA assigned MIBEnum value */ if ((rc = parseInt(pScanner, &mibenum)) != SML_ERR_OK) return rc; pScanner->charset = mibenum; if (!readBytes(pScanner, 1)) return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlCharset"); return SML_ERR_OK; } /** * Keep a copy of the string table. */ static Ret_t wbxmlStrtbl(wbxmlScannerPrivPtr_t pScanner) { MBINT len; Ret_t rc; if ((rc = parseInt(pScanner, &len)) != SML_ERR_OK) return rc; if (!readBytes(pScanner, 1)) return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlStrtbl"); pScanner->strtbllen = len; if (len > 0) { if (pScanner->pos + len > pScanner->bufend) return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlStrtbl"); if ((pScanner->strtbl = smlLibMalloc(len)) == NULL) { return SML_ERR_NOT_ENOUGH_SPACE; } smlLibMemcpy(pScanner->strtbl, pScanner->pos, len); readBytes(pScanner, len); } else { pScanner->strtbl = NULL; } /* if the public ID was given as a string table reference save a reference to the corresponding string for later */ if (pScanner->pubID == 0) { if (pScanner->pubIDIdx > pScanner->strtbllen) return SML_DECODEERROR(SML_ERR_XLT_INVAL_WBXML_DOC,pScanner,"wbxmlStrtbl"); pScanner->pubIDStr = (String_t)(pScanner->strtbl + pScanner->pubIDIdx); } return SML_ERR_OK; } static Ret_t parseInt(wbxmlScannerPrivPtr_t pScanner, MBINT *mbi) { *mbi = 0; /* accumulate byte value until continuation flag (MSB) is zero */ for (;;) { *mbi = *mbi << 7; *mbi += *(pScanner->pos) & 0x7F; if (!(*pScanner->pos & 0x80)) break; if (!readBytes(pScanner, 1)) return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"parseInt"); } return SML_ERR_OK; } static Ret_t wbxmlStringToken(wbxmlScannerPrivPtr_t pScanner) { SmlPcdataPtr_t pPcdata; Ret_t rc; if ((pPcdata = (SmlPcdataPtr_t)smlLibMalloc(sizeof(SmlPcdata_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; /* copy the string into the new PCdata struct */ if (IS_STR_I(pScanner->pos)) { /* inline string */ if (!readBytes(pScanner, 1)) return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlStringToken"); pPcdata->extension = SML_EXT_UNDEFINED; pPcdata->contentType = SML_PCDATA_STRING; pPcdata->length = smlLibStrlen((String_t)pScanner->pos); if (pScanner->pos + pPcdata->length + 1 > pScanner->bufend) { smlLibFree(pPcdata); return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlStringToken"); } if ((pPcdata->content = smlLibMalloc(pPcdata->length + 1)) == NULL) { smlLibFree(pPcdata); return SML_ERR_NOT_ENOUGH_SPACE; } smlLibStrncpy(pPcdata->content, (String_t)pScanner->pos, pPcdata->length + 1); readBytes(pScanner, pPcdata->length + 1); } else { /* string table reference */ MBINT offset; /* offset into string table */ if (!readBytes(pScanner, 1)) return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlStringToken"); if ((rc = parseInt(pScanner, &offset)) != SML_ERR_OK) { smlLibFree(pPcdata); return rc; } if (offset >= pScanner->strtbllen) { smlLibFree(pPcdata); return SML_DECODEERROR(SML_ERR_XLT_INVAL_WBXML_DOC,pScanner,"wbxmlStringToken"); } pPcdata->contentType = SML_PCDATA_STRING; pPcdata->length = smlLibStrlen((String_t)(pScanner->strtbl + offset)); if ((pPcdata->content = smlLibMalloc(pPcdata->length + 1)) == NULL) { smlLibFree(pPcdata); return SML_ERR_NOT_ENOUGH_SPACE; } smlLibStrncpy(pPcdata->content, (String_t)(pScanner->strtbl + offset), pPcdata->length + 1); readBytes(pScanner, 1); } pScanner->curtok->pcdata = pPcdata; pScanner->curtok->type = TOK_CONT; return SML_ERR_OK; } static Ret_t wbxmlOpaqueToken(wbxmlScannerPrivPtr_t pScanner) { SmlPcdataPtr_t pPcdata = NULL; MBINT len; Ret_t rc; if (!readBytes(pScanner, 1)) return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlOpaqueToken"); /* a mbi indicates the length of the opaque data block that we'll copy into new PCdata struct */ if ((rc = parseInt(pScanner, &len)) != SML_ERR_OK) return rc; if (!readBytes(pScanner, 1)) return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlOpaqueToken"); if (pScanner->pos + len > pScanner->bufend) return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlOpaqueToken"); if ((pPcdata = (SmlPcdataPtr_t)smlLibMalloc(sizeof(SmlPcdata_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; pPcdata->extension = SML_EXT_UNDEFINED; pPcdata->contentType = SML_PCDATA_OPAQUE; pPcdata->length = len; /* Modification 2001-07-03 by Luz %%%%%: * made sure that content is one null byte longer * than indicated opaque content, such that strings that are coded as * opaque (happens to be the case with Nokia 9210) can still be read * as C-string without need for an intermediate buffer */ /* original: if ((pPcdata->content = smlLibMalloc(len)) == NULL) { smlLibFree(pPcdata); return SML_ERR_NOT_ENOUGH_SPACE; } */ /* modified: */ if ((pPcdata->content = smlLibMalloc(len+1)) == NULL) { smlLibFree(pPcdata); return SML_ERR_NOT_ENOUGH_SPACE; } ((char *)pPcdata->content)[len]=0; /* make sure there is a c-string terminator */ /* end modification */ smlLibMemcpy(pPcdata->content, pScanner->pos, len); pScanner->curtok->pcdata = pPcdata; readBytes(pScanner, len); pScanner->curtok->type = TOK_CONT; return SML_ERR_OK; } static Ret_t wbxmlTagToken(wbxmlScannerPrivPtr_t pScanner) { XltTagID_t tagid; Boolean_t has_cont, has_attr; Ret_t rc; if (IS_SWITCH(pScanner->pos)) { if ((rc = wbxmlSwitchPage(pScanner)) != SML_ERR_OK) return rc; } /* we have to look at the top of the tagstack to see which start tag an end tag belongs to */ if (IS_END(pScanner->pos)) { if (!readBytes(pScanner, 1)) return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlTagToken"); pScanner->curtok->type = TOK_TAG_END; rc = pScanner->tagstack->pop(pScanner->tagstack, &tagid); if (rc == SML_ERR_WRONG_USAGE) return SML_DECODEERROR(SML_ERR_XLT_INVAL_WBXML_DOC,pScanner,"wbxmlTagToken"); else if (rc) return rc; pScanner->curtok->tagid = tagid; return SML_ERR_OK; } /* look at the two MSB: does this tag have content or attributes? */ has_cont = ((Boolean_t)(HAS_CONTENT(pScanner->pos))); has_attr = ((Boolean_t)(HAS_ATTRIBUTES(pScanner->pos))); /* look up tag ID either by string or by number */ if (IS_LITERAL(pScanner->pos)) { MBINT offset; /* offset into the string table */ if (!readBytes(pScanner, 1)) return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlTagToken"); if ((rc = parseInt(pScanner, &offset)) != SML_ERR_OK) return rc; if (offset > pScanner->strtbllen) return SML_DECODEERROR(SML_ERR_XLT_INVAL_WBXML_DOC,pScanner,"wbxmlTagToken"); rc = (Ret_t)getTagIDByStringAndExt((String_t)(pScanner->strtbl + offset), pScanner->activeExt, &tagid); if ((tagid == TN_UNDEF) || (rc != SML_ERR_OK)) return rc; } else { rc = (Ret_t)getTagIDByByteAndExt((Byte_t)IDENTITY(pScanner->pos), pScanner->activeExt, &tagid); if ((tagid == TN_UNDEF) || (rc != SML_ERR_OK)) return rc; } /* we know everything we need to know */ pScanner->curtok->tagid = tagid; pScanner->curtok->type = has_cont ? TOK_TAG_START : TOK_TAG_EMPTY; #ifdef __USE_METINF__ pScanner->curtok->ext = pScanner->cptag == 0 ? SML_EXT_UNDEFINED : SML_EXT_METINF; #else pScanner->curtok->ext = SML_EXT_UNDEFINED; #endif if (!readBytes(pScanner, 1)) return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlTagToken"); /* push tag onto tagstack unless this tag is empty */ if (has_cont) { if ((rc = pScanner->tagstack->push(pScanner->tagstack, tagid)) != SML_ERR_OK) return rc; } /* skip attributes */ if (has_attr) { pScanner->state = ATTRIBUTE_STATE; if ((rc = wbxmlSkipAttribute(pScanner)) != SML_ERR_OK) return rc; pScanner->state = TAG_STATE; } return SML_ERR_OK; } /* * Switch WBXML code page. */ /* T.K. 06.02.01 * We need to enhance this as soon as we introduce * Sub DTD's with more than one WBXML codepage. But till then * there is only one case where WBXML codepages can occure, and * this is the MetInf Sub DTD. So in case we find a codepage switch * to something other than codepage zero, we set the active extension * to metinf. * In future versions the pScanner needs to be enhanced, to translate * codepageswitches context sensitive to the active extension. */ static Ret_t wbxmlSwitchPage(wbxmlScannerPrivPtr_t pScanner) { if (!readBytes(pScanner, 1)) return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlSwitchPage"); if (pScanner->state == TAG_STATE) pScanner->cptag = (SmlPcdataExtension_t)*pScanner->pos; else pScanner->cpattr = *pScanner->pos; readBytes(pScanner, 1); /* T.K. this needs to be adjusted as described above */ if (pScanner->cpattr != 0 || pScanner->cptag != 0) pScanner->activeExt = SML_EXT_METINF; else pScanner->activeExt = SML_EXT_UNDEFINED; return SML_ERR_OK; } /******************************/ /* Unsupported WBXML elements */ /******************************/ /** * Skips entities but doesn't do anything useful yet. */ static Ret_t wbxmlSkipEntity(wbxmlScannerPrivPtr_t pScanner) { MBINT tmp; Ret_t rc; if (!readBytes(pScanner, 1)) return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlSkipEntity"); if ((rc = parseInt(pScanner, &tmp)) != SML_ERR_OK) return rc; if (!readBytes(pScanner, 1)) return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlSkipEntity"); return SML_ERR_OK; } /* * Decode WBXML extensions. Skips the extension but doesn't do anything * useful with it. */ static Ret_t wbxmlSkipExtension(wbxmlScannerPrivPtr_t pScanner) { MBINT tmp; Ret_t rc; if (IS_EXT(pScanner->pos)) { /* single byte extension token */ if (!readBytes(pScanner, 1)) return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlSkipExtension"); } else if (IS_EXT_I(pScanner->pos)) { /* inline string extension token */ if (!readBytes(pScanner, 1)) return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlSkipExtension"); if (!readBytes(pScanner, smlLibStrlen((String_t)pScanner->pos) + 1)) return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlSkipExtension"); } else { /* inline integer extension token */ if (!readBytes(pScanner, 1)) return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlSkipExtension"); if ((rc = parseInt(pScanner, &tmp)) != SML_ERR_OK) return rc; if (!readBytes(pScanner, tmp + 1)) return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlSkipExtension"); } return SML_ERR_OK; } /* * Handle XML processing instructions. PIs are not supported but the * scanner recognizes and skips over them. */ static Ret_t wbxmlSkipPI(wbxmlScannerPrivPtr_t pScanner) { /* PIs are just like tag attributes with a special PI token instead * of the attribute start token */ return wbxmlSkipAttribute(pScanner); } /* * Handle attributes. Attributes are not supported but the * scanner recognizes and skips over them. */ static Ret_t wbxmlSkipAttribute(wbxmlScannerPrivPtr_t pScanner) { XltDecTokenPtr_t oldtok; MBINT tmp; Ret_t rc = 0; /* skipping attributes shouldn't change the current token so we make a copy... */ if ((oldtok = (XltDecTokenPtr_t)smlLibMalloc(sizeof(XltDecToken_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemcpy(oldtok, pScanner->curtok, sizeof(XltDecToken_t)); /* ... skip until attribute end tag... */ while (!IS_END(pScanner->pos)) { if (IS_STRING(pScanner->pos)) { rc = wbxmlStringToken(pScanner); /* avoid memory leak due to this ugly workaround of skipping attributes */ smlLibFree(pScanner->curtok->pcdata); } else if (IS_EXTENSION(pScanner->pos)) { rc = wbxmlSkipExtension(pScanner); } else if (IS_ENTITY(pScanner->pos)) { rc = wbxmlSkipEntity(pScanner); } else if (IS_OPAQUE(pScanner->pos)) { rc = wbxmlOpaqueToken(pScanner); /* avoid memory leak due to this ugly workaround of skipping attributes */ smlLibFree(pScanner->curtok->pcdata); } else if (IS_LITERAL(pScanner->pos)) { if (!readBytes(pScanner, 1)) return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlSkipAttribute"); rc = parseInt(pScanner, &tmp); if (!readBytes(pScanner, 1)) return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlSkipAttribute"); } else if (IS_SWITCH(pScanner->pos)) { rc = wbxmlSwitchPage(pScanner); } else { if (!readBytes(pScanner, 1)) return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlSkipAttribute"); } if (rc != SML_ERR_OK) { smlLibFree(oldtok); return rc; } } /* ... then skip the end tag itself... */ readBytes(pScanner, 1); /* ... and finaly restore our copy of curtok */ smlLibMemcpy(pScanner->curtok, oldtok, sizeof(XltDecToken_t)); smlLibFree(oldtok); return SML_ERR_OK; } #ifdef __USE_EXTENSIONS__ /* * This function tries to decode an inlined WBXML document inside * an PCDATA element. * In case of failing to decode it the PCDATA element isn't changed * at all. */ void subdtdDecodeWbxml(XltDecoderPtr_t pDecoder,SmlPcdataPtr_t *ppPcdata) { Ret_t _err = SML_ERR_OK; MemPtr_t pSubBuf = NULL; SmlPcdataPtr_t pSubPcdata = NULL; XltDecoderPtr_t pSubDecoder = NULL; #ifdef __USE_DEVINF__ wbxmlScannerPrivPtr_t pScannerPriv = NULL; #endif /* some sanity checks at first */ if (*ppPcdata == NULL) { if (pDecoder) /* use this rare case to remove warning */ { } return; } if ((*ppPcdata)->contentType != SML_PCDATA_OPAQUE) return; // now create a sub buffer pSubBuf = (MemPtr_t)smlLibMalloc((*ppPcdata)->length); if (pSubBuf == NULL) return; smlLibMemset(pSubBuf, 0x00, (*ppPcdata)->length); smlLibMemmove(pSubBuf, (*ppPcdata)->content, (*ppPcdata)->length); /* ok looks fine sofar - now lets decode the rest */ /* now lets create a decoder, but without parsing the SyncML * start tags (because it's not there) and skip the XML * part as we don't need it. */ pSubDecoder = (XltDecoderPtr_t)smlLibMalloc(sizeof(XltDecoder_t)); if (pSubDecoder == NULL) { smlLibFree(pSubBuf); return; } pSubDecoder->finished = 0; pSubDecoder->final = 0; pSubDecoder->scanner = NULL; if (xltUtilCreateStack(&pSubDecoder->tagstack, 10) != SML_ERR_OK) { smlLibFree(pSubDecoder); smlLibFree(pSubBuf); return; } if (xltDecWbxmlInit(pSubBuf+(*ppPcdata)->length,&pSubBuf, &pSubDecoder->scanner) != SML_ERR_OK) { xltDecTerminate(pSubDecoder); smlLibFree(pSubBuf); return; } pSubDecoder->charset = pSubDecoder->scanner->charset; pSubDecoder->charsetStr = NULL; pSubPcdata = (SmlPcdataPtr_t)smlLibMalloc(sizeof(SmlPcdata_t)); if (pSubPcdata == NULL) { xltDecTerminate(pSubDecoder); smlLibFree(pSubPcdata); smlLibFree(pSubBuf); return; } /* T.K. * In the future we need to check the WBXML stringtable and * switch into the right Sub DTD. But sofar only DevInf is * supported so we can save time and space */ /* T.K. * To prevent buffer corruption when __USE_DEVINF__ is not used * we initialize _err with any errorcode != OK, and this way * force the function to exit without modifying the ppPcdata */ _err = SML_ERR_UNSPECIFIC; #ifdef __USE_DEVINF__ pSubPcdata->contentType = SML_PCDATA_EXTENSION; pSubPcdata->extension = SML_EXT_DEVINF; pSubPcdata->length = 0; pSubPcdata->content = NULL; pScannerPriv = (wbxmlScannerPrivPtr_t)pSubDecoder->scanner; pScannerPriv->activeExt = SML_EXT_DEVINF; pScannerPriv->cpattr = 0; pScannerPriv->cptag = (SmlPcdataExtension_t)0; smlLibMemset(pScannerPriv->curtok, 0,sizeof(XltDecToken_t)); _err = buildDevInfDevInfCmd(pSubDecoder, (VoidPtr_t)&pSubPcdata->content); #endif if (_err != SML_ERR_OK) { xltDecTerminate(pSubDecoder); smlLibFree(pSubPcdata); smlLibFree(pSubBuf); return; } /* parsing is done, now lets anchor it within the original PCDATA element */ smlFreePcdata(*ppPcdata); *ppPcdata = pSubPcdata; /* we are done */ xltDecTerminate(pSubDecoder); smlLibFree(pSubBuf); return; } #endif #endif libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/xlt/all/xltdecwbxml.h000077500000000000000000000045431226375725500251160ustar00rootroot00000000000000/** * @file * internal WBXML decoder header file * * @target_system - * @target_os - */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ /*************************************************************************/ /* Definitions */ /*************************************************************************/ #ifndef _XLT_DEC_WBXML_H #define _XLT_DEC_WBXML_H #include "XLTDecAll.h" xltDecScanner_t* xltDecWbxmlScannerCreate(unsigned char *buf, long buflen); void xltDecWbxmlScannerDestroy(xltDecScanner_t *p); #endif libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/xlt/all/xltdecxml.c000077500000000000000000001162631226375725500245630ustar00rootroot00000000000000/** * @file * XML scanner * * @target_system all * @target_os all * @description The XML scanner/tokenizer. Used by the SyncML parser. */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ #include "syncml_tk_prefix_file.h" // %%% luz: needed for precompiled headers in eVC++ #include "define.h" #ifdef __SML_XML__ /*************************************************************************/ /* Definitions */ /*************************************************************************/ #include "xltdeccom.h" #include "xlttags.h" #include "xltdec.h" #include #include #include /** @copydoc wbxmlScannerPriv_s */ typedef struct xmlScannerPriv_s xmlScannerPriv_t, *xmlScannerPrivPtr_t; /** * Private Interface for the XML scanner. */ struct xmlScannerPriv_s { /* public */ Ret_t (*nextTok)(XltDecScannerPtr_t); Ret_t (*destroy)(XltDecScannerPtr_t); Ret_t (*pushTok)(XltDecScannerPtr_t); void (*setBuf)(XltDecScannerPtr_t pScanner, const MemPtr_t pBufStart, const MemPtr_t pBufEnd); MemPtr_t (*getPos)(XltDecScannerPtr_t pScanner, Long_t *remaining); XltDecTokenPtr_t curtok; /**< current token */ Long_t charset; /**< 0 */ String_t charsetStr; /**< character set */ Long_t pubID; /**< 0 */ String_t pubIDStr; /**< document public identifier */ SmlPcdataExtension_t ext; /**< which is the actual open namespace ? */ SmlPcdataExtension_t prev_ext; /**< which is the previous open namespace ? */ XltTagID_t ext_tag; /**< which tag started the actual namespace ? */ XltTagID_t prev_ext_tag; /**< which tag started the previous open namespace ? */ String_t nsprefix; /**< prefix used for active namespace (if any) */ Byte_t nsprelen; /**< how long is the prefix ? (to save smlLibStrlen calls) */ Flag_t finished; /* private */ MemPtr_t pos; /**< current position */ MemPtr_t bufend; /**< end of buffer */ }; /* * Public methods of the scanner interface. * * Description see XLTDecCom.h. */ static Ret_t _destroy(XltDecScannerPtr_t); static Ret_t _nextTok(XltDecScannerPtr_t); static Ret_t _pushTok(XltDecScannerPtr_t); static void _setBuf(XltDecScannerPtr_t, const MemPtr_t, const MemPtr_t); static MemPtr_t _getPos(XltDecScannerPtr_t, Long_t *remaining); /** * Advance the current position pointer after checking whether the end of * the buffer has been reached. If the end of the buffer has been reached * the scanner's finished flag is set. * * @param bytes (IN) * read this many bytes * @param pScanner (IN/OUT) * the scanner * @return 1, if end of buffer has not been reached\n * 0 otherwise */ static Boolean_t readBytes(xmlScannerPrivPtr_t pScanner, Long_t bytes); /* * Skip whitespaces. */ static void skipS(xmlScannerPrivPtr_t pScanner); /** * BOM processing. Currently only check BOMs for UTF-8, UTF-16le, UTF-16be, * UTF-32le and UTF-32be. Note that SML_ERR_XLT_ENC_UNK is also returned * when BOMs of UTF-16le, UTF-16be, UTF-32le and UTF-32be are processed for * these encodings are not supported in the current code base. * @param pScanner (IN/OUT) * the scanner * @return SML_ERR_OK if UTF-8 BOM or UTF-8 characters without a BOM * or 8-bit encodings like US-ACII * SML_ERR_XLT_ENC_UNK if other Encodings or Encoding BOMs */ static Ret_t bomDecl(xmlScannerPrivPtr_t pScanner); static Ret_t xmlTag(xmlScannerPrivPtr_t pScanner, Byte_t endtag); static Ret_t xmlName(xmlScannerPrivPtr_t pScanner, String_t *name); static Ret_t xmlCharData(xmlScannerPrivPtr_t pScanner); static Ret_t xmlProlog(xmlScannerPrivPtr_t pScanner); static Ret_t xmlDocTypeDecl(xmlScannerPrivPtr_t pScanner); static Ret_t xmlXMLDecl(xmlScannerPrivPtr_t pScanner); static Ret_t xmlAttribute(xmlScannerPrivPtr_t pScanner, String_t *name, String_t *value); static Ret_t xmlStringConst(xmlScannerPrivPtr_t pScanner, String_t *value); static Ret_t xmlSkipPCDATA(xmlScannerPrivPtr_t pScanner); static Ret_t xmlSkipComment(xmlScannerPrivPtr_t pScanner); static Ret_t xmlSkipAttributes(xmlScannerPrivPtr_t pScanner); static Ret_t xmlSkipPI(xmlScannerPrivPtr_t pScanner); static Ret_t xmlCDATA(xmlScannerPrivPtr_t pScanner); Boolean_t isPcdata(XltTagID_t tagid); /*************************************************************************/ /* External Functions */ /*************************************************************************/ Ret_t xltDecXmlInit(const MemPtr_t pBufEnd, MemPtr_t *ppBufPos, XltDecScannerPtr_t *ppScanner) { xmlScannerPrivPtr_t pScanner; Ret_t rc; pScanner = (xmlScannerPrivPtr_t)smlLibMalloc(sizeof(xmlScannerPriv_t)); if (pScanner == NULL) { *ppScanner = NULL; return SML_ERR_NOT_ENOUGH_SPACE; } memset(pScanner, 0, sizeof(*pScanner)); pScanner->pos = *ppBufPos; pScanner->bufend = pBufEnd; pScanner->curtok = (XltDecTokenPtr_t)smlLibMalloc(sizeof(XltDecToken_t)); if (pScanner->curtok == NULL) { smlLibFree(pScanner); *ppScanner = NULL; return SML_ERR_NOT_ENOUGH_SPACE; } memset(pScanner->curtok, 0, sizeof(*pScanner->curtok)); pScanner->curtok->tagid = TN_UNDEF; pScanner->ext = SML_EXT_UNDEFINED; pScanner->prev_ext = (SmlPcdataExtension_t)255; pScanner->ext_tag = TN_UNDEF; pScanner->prev_ext_tag = TN_UNDEF; /* point public/private methods to the right implementation */ pScanner->nextTok = _nextTok; pScanner->destroy = _destroy; pScanner->pushTok = _pushTok; pScanner->setBuf = _setBuf; pScanner->getPos = _getPos; if((rc = bomDecl(pScanner)) != SML_ERR_OK) return rc; if ((rc = xmlProlog(pScanner)) != SML_ERR_OK) { smlLibFree(pScanner->curtok); smlLibFree(pScanner); *ppScanner = NULL; return rc; } *ppScanner = (XltDecScannerPtr_t)pScanner; return SML_ERR_OK; } /** * Free memory. Description see XltDecAll.h. */ static Ret_t _destroy(XltDecScannerPtr_t pScanner) { xmlScannerPrivPtr_t pScannerPriv; if (pScanner == NULL) return SML_ERR_OK; pScannerPriv = (xmlScannerPrivPtr_t)pScanner; smlLibFree(pScannerPriv->curtok); smlLibFree(pScannerPriv->charsetStr); smlLibFree(pScannerPriv->pubIDStr); smlLibFree(pScannerPriv); return SML_ERR_OK; } /** * Get next token. Description see XltDecAll.h. */ static Ret_t _nextTok(XltDecScannerPtr_t pScanner) { xmlScannerPrivPtr_t pScannerPriv; Ret_t rc; pScannerPriv = (xmlScannerPrivPtr_t)pScanner; pScannerPriv->curtok->start = pScannerPriv->pos; if (pScannerPriv->curtok->type!=TOK_CONT) skipS(pScannerPriv); /* skip unsupported elements until we find a supported one */ rc = 0; while (!rc) { if (smlLibStrncmp((String_t)pScannerPriv->pos, "", 3) != 0)) if (!readBytes(pScanner, 1)) return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"xmlSkipComment"); if (pScanner->pos + 3 > pScanner->bufend) return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"xmlSkipComment"); if (!readBytes(pScanner, 3)) return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"xmlSkipComment"); skipS(pScanner); return SML_ERR_OK; } /** * Skip attributes -> they are not supported in SyncML */ static Ret_t xmlSkipAttributes(xmlScannerPrivPtr_t pScanner) { while ((pScanner->pos + 1 <= pScanner->bufend) && (smlLibStrncmp((String_t)pScanner->pos, ">", 1)) && (smlLibStrncmp((String_t)pScanner->pos, "/>", 2))) if (!readBytes(pScanner, 1)) return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"xmlSkipAttributes"); if (pScanner->pos + 1 > pScanner->bufend) return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"xmlSkipAttributes"); return SML_ERR_OK; } /** * Handle a CDATA content */ static Ret_t xmlCDATA(xmlScannerPrivPtr_t pScanner) { SmlPcdataPtr_t pPCData; MemPtr_t begin; int len; readBytes(pScanner, 9); pPCData = (SmlPcdataPtr_t)smlLibMalloc(sizeof(SmlPcdata_t)); if (pPCData == NULL) return SML_ERR_NOT_ENOUGH_SPACE; pPCData->contentType = SML_PCDATA_UNDEFINED; pPCData->length = 0; pPCData->content = NULL; begin = pScanner->pos; while (!((pScanner->pos[0] == ']') && (pScanner->pos[1] == ']') && (pScanner->pos[2] == '>'))) if (!readBytes(pScanner, 1)) return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"xmlCDATA"); len = pScanner->pos - begin; pPCData->content = smlLibMalloc(len + 1); if (pPCData->content == NULL) { smlLibFree(pPCData); return SML_ERR_NOT_ENOUGH_SPACE; } //%%%waste of CPU: smlLibMemset(pPCData->content, 0, len + 1); ((MemPtr_t)pPCData->content)[len]=0; // set terminator smlLibMemcpy(pPCData->content, begin, len); // copy data pPCData->contentType = SML_PCDATA_CDATA; pPCData->length = len; pScanner->curtok->type = TOK_CONT; pScanner->curtok->pcdata = pPCData; readBytes(pScanner, 3); return SML_ERR_OK; } /** * Read over a Pcdata content */ static Ret_t xmlSkipPCDATA(xmlScannerPrivPtr_t pScanner) { SmlPcdataPtr_t pPCData; MemPtr_t begin; int len; Ret_t rc; String_t _tagString = NULL; String_t _tagString2 = NULL; char entity; /* Check wether this PCData might contain a subdtd. ** We assume a Sub DTD starts with '<' as first char. ** If this char is present start further processing else ** take it as pure String data. If the scanning returns an ** error we reject the file, as '<' is not a valid char inside ** PCData elements. */ if (smlLibStrncmp((String_t)pScanner->pos, "<", 1) == 0) { rc = xmlTag(pScanner, 0); return rc; } _tagString = smlLibMalloc(XML_MAX_TAGLEN); if (_tagString == NULL) return SML_ERR_NOT_ENOUGH_SPACE; if ((rc = getTagString(pScanner->curtok->tagid, _tagString, pScanner->curtok->ext)) != SML_ERR_OK) { smlLibFree(_tagString); return rc; } _tagString2 = smlLibMalloc(smlLibStrlen(_tagString) + 4 + (pScanner->nsprelen +1)); // build a end tag String to compate (e.g. ) // beware of possible namespace prefixes if (_tagString2 == NULL) { smlLibFree(_tagString); return SML_ERR_NOT_ENOUGH_SPACE; } _tagString2 = smlLibStrcpy(_tagString2,"nsprelen > 0) { _tagString2 = smlLibStrcat(_tagString2,pScanner->nsprefix); _tagString2 = smlLibStrcat(_tagString2,":"); } _tagString2 = smlLibStrcat(_tagString2,_tagString); _tagString2 = smlLibStrcat(_tagString2,">"); smlLibFree(_tagString); pPCData = (SmlPcdataPtr_t)smlLibMalloc(sizeof(SmlPcdata_t)); if (pPCData == NULL) { smlLibFree(_tagString2); return SML_ERR_NOT_ENOUGH_SPACE; } pPCData->contentType = SML_PCDATA_UNDEFINED; pPCData->extension = SML_EXT_UNDEFINED; pPCData->length = 0; pPCData->content = NULL; begin = pScanner->pos; if (*pScanner->pos == '&') { Ret_t ret = xmlHTMLEntity(pScanner, &entity); if (ret) { smlLibFree(_tagString2); return ret; } begin = (MemPtr_t)&entity; len = 1; } else { // Read Pcdata content until end tag appears or we run into something which // requires special decoding: CDATA or HTML entity while (smlLibStrncmp((String_t)pScanner->pos, _tagString2, smlLibStrlen(_tagString2)) != 0) { // check if end of buffer if (pScanner->pos >= pScanner->bufend) { smlLibFree(_tagString2); return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"xmlSkipPCDATA"); } // %%% luz 2006-09-07 // check if another pos,"pos == '&') { // stop PCDATA scanning here break; } if (!readBytes(pScanner, 1)) return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"xmlSkipPCDATA"); } len = pScanner->pos - begin; } smlLibFree(_tagString2); pPCData->content = smlLibMalloc(len + 1); if (pPCData->content == NULL) { smlLibFree(pPCData); return SML_ERR_NOT_ENOUGH_SPACE; } //%%%waste of CPU: smlLibMemset(pPCData->content, 0, len + 1); ((MemPtr_t)pPCData->content)[len]=0; // set terminator smlLibMemcpy(pPCData->content, begin, len); pPCData->contentType = SML_PCDATA_STRING; pPCData->length = len; pScanner->curtok->type = TOK_CONT; pScanner->curtok->pcdata = pPCData; return SML_ERR_OK; } /** * Check if the current tag id represents a Pcdata element */ Boolean_t isPcdata(XltTagID_t tagid) { switch (tagid) { case TN_CMD: case TN_CMDID: case TN_CMDREF: case TN_LANG: case TN_LOCNAME: case TN_LOCURI: case TN_MSGID: case TN_MSGREF: case TN_RESPURI: case TN_SESSIONID: case TN_SOURCEREF: case TN_TARGETREF: case TN_VERSION: case TN_PROTO: case TN_DATA: case TN_META: case TN_NUMBEROFCHANGES: /* SyncML DS 1.2, Synthesis/luz 2005-08-24 */ case TN_FILTERTYPE: #ifdef __USE_METINF__ case TN_METINF_EMI: case TN_METINF_FORMAT: case TN_METINF_FREEID: case TN_METINF_FREEMEM: case TN_METINF_LAST: case TN_METINF_MARK: case TN_METINF_MAXMSGSIZE: /* SCTSTK - 18/03/2002 S.H. 2002-04-05 : SyncML 1.1 */ case TN_METINF_MAXOBJSIZE: case TN_METINF_NEXT: case TN_METINF_NEXTNONCE: case TN_METINF_SIZE: case TN_METINF_TYPE: case TN_METINF_VERSION: #endif #ifdef __USE_DEVINF__ case TN_DEVINF_MAN: case TN_DEVINF_MOD: case TN_DEVINF_OEM: case TN_DEVINF_FWV: case TN_DEVINF_SWV: case TN_DEVINF_HWV: case TN_DEVINF_DEVID: case TN_DEVINF_DEVTYP: case TN_DEVINF_MAXGUIDSIZE: case TN_DEVINF_SOURCEREF: case TN_DEVINF_DISPLAYNAME: case TN_DEVINF_CTTYPE: case TN_DEVINF_DATATYPE: case TN_DEVINF_SIZE: case TN_DEVINF_PROPNAME: case TN_DEVINF_VALENUM: case TN_DEVINF_PARAMNAME: case TN_DEVINF_SYNCTYPE: case TN_DEVINF_XNAM: case TN_DEVINF_XVAL: case TN_DEVINF_MAXMEM: case TN_DEVINF_MAXID: case TN_DEVINF_VERCT: case TN_DEVINF_VERDTD: /* SyncML DS 1.2, Synthesis/luz 2005-08-24 */ case TN_DEVINF_MAXOCCUR: case TN_DEVINF_FILTERKEYWORD: case TN_DEVINF_MAXSIZE: #endif return 1; default: return 0; } } #endif libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/xlt/all/xltdevinf.c000077500000000000000000001647771226375725500245770ustar00rootroot00000000000000/** * @file * DeviceInf DTD related functions for the en-/decoder * * @target_system all * @target_os all */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ #include "syncml_tk_prefix_file.h" // %%% luz: needed for precompiled headers in eVC++ #include "define.h" #ifdef __USE_DEVINF__ #include "smldevinfdtd.h" #include "smlmetinfdtd.h" #include "xlttags.h" #include "xltdevinf.h" #include "xlttagtbl.h" #include "xltenc.h" #include "xltencwbxml.h" #include #include #include #include #include #include /* decoder callbacks */ Ret_t buildDevInfDevInfContent(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem); Ret_t buildDevInfCtcap(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem, Boolean_t datastoreLocal); Ret_t buildDevInfDevInfCmd(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem) { XltDecScannerPtr_t pScanner; SmlDevInfDevInfPtr_t pElem = NULL; Ret_t rc; pScanner = pDecoder->scanner; if (*ppElem != NULL) return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildDevInfDevInfCmd"); if (IS_EMPTY(pScanner->curtok)) { *ppElem = pElem; return SML_ERR_OK; } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlLibFree(pElem); return rc; } switch (pScanner->curtok->tagid) { case TN_DEVINF_DEVINF: rc = buildDevInfDevInfContent(pDecoder, (VoidPtr_t)&pElem); break; default: rc = SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildDevInfDevInfCmd"); } if (rc != SML_ERR_OK) { smlLibFree(pElem); return rc; } *ppElem = pElem; return SML_ERR_OK; } Ret_t buildDevInfDevInfContent(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem) { XltDecScannerPtr_t pScanner; SmlDevInfDevInfPtr_t pElem; Ret_t rc; pScanner = pDecoder->scanner; if (*ppElem != NULL) return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildDevInfDevInfContent"); if ((pElem = (SmlDevInfDevInfPtr_t)smlLibMalloc(sizeof(SmlDevInfDevInf_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pElem, 0, sizeof(SmlDevInfDevInf_t)); if (IS_EMPTY(pScanner->curtok)) { *ppElem = pElem; return SML_ERR_OK; } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlLibFree(pElem); return rc; } while (pScanner->curtok->type != TOK_TAG_END) { switch (pScanner->curtok->tagid) { case TN_DEVINF_VERDTD: rc = buildPCData(pDecoder, (VoidPtr_t)&pElem->verdtd); break; case TN_DEVINF_MAN: rc = buildPCData(pDecoder, (VoidPtr_t)&pElem->man); break; case TN_DEVINF_MOD: rc = buildPCData(pDecoder, (VoidPtr_t)&pElem->mod); break; case TN_DEVINF_OEM: rc = buildPCData(pDecoder, (VoidPtr_t)&pElem->oem); break; case TN_DEVINF_FWV: rc = buildPCData(pDecoder, (VoidPtr_t)&pElem->fwv); break; case TN_DEVINF_SWV: rc = buildPCData(pDecoder, (VoidPtr_t)&pElem->swv); break; case TN_DEVINF_HWV: rc = buildPCData(pDecoder, (VoidPtr_t)&pElem->hwv); break; case TN_DEVINF_DEVID: rc = buildPCData(pDecoder, (VoidPtr_t)&pElem->devid); break; case TN_DEVINF_DEVTYP: rc = buildPCData(pDecoder, (VoidPtr_t)&pElem->devtyp); break; case TN_DEVINF_DATASTORE: rc = buildDevInfDataStoreList(pDecoder, (VoidPtr_t)&pElem->datastore); break; case TN_DEVINF_CTCAP: rc = buildDevInfCtcap(pDecoder, (VoidPtr_t)&pElem->ctcap,FALSE); // CTCap which is global in devInf itself (pre-DS 1.2) break; case TN_DEVINF_EXT: rc = buildDevInfExtList(pDecoder, (VoidPtr_t)&pElem->ext); break; /* SCTSTK - 18/03/2002 S.H. 2002-04-05 : SyncML 1.1 */ case TN_DEVINF_UTC: pElem->flags |= SmlDevInfUTC_f; rc = buildEmptyTag(pDecoder); // allow for instead of break; case TN_DEVINF_NOFM: pElem->flags |= SmlDevInfNOfM_f; rc = buildEmptyTag(pDecoder); // allow for instead of break; case TN_DEVINF_LARGEOBJECT: pElem->flags |= SmlDevInfLargeObject_f; rc = buildEmptyTag(pDecoder); // allow for instead of break; default: rc = SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildDevInfDevInfContent"); } if (rc != SML_ERR_OK) { smlLibFree(pElem); return rc; } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlLibFree(pElem); return rc; } } *ppElem = pElem; return SML_ERR_OK; } static Ret_t buildDevInfFilterCapList(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem) { SmlDevInfFilterCapListPtr_t *ppListElem = NULL; SmlDevInfFilterCapListPtr_t pFiltercap = NULL; SmlPcdataListPtr_t *ppList = NULL; SmlPcdataListPtr_t pList = NULL; XltDecScannerPtr_t pScanner = pDecoder->scanner; Ret_t rc; // if empty, that's ok and treated as NOP: if (IS_EMPTY(pScanner->curtok)) { return SML_ERR_OK; } // get next token if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { return rc; } // get pointer to where we'd insert the next list element ppListElem = (SmlDevInfFilterCapListPtr_t *) ppElem; while (*ppListElem!=NULL) { ppListElem = &((*ppListElem)->next); } // create new list element now pFiltercap = (SmlDevInfFilterCapListPtr_t)smlLibMalloc(sizeof(SmlDevInfFilterCapList_t)); if (pFiltercap == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pFiltercap, 0, sizeof(SmlDevInfFilterCapList_t)); pFiltercap->data = (SmlDevInfFilterCapPtr_t)smlLibMalloc(sizeof(SmlDevInfFilterCap_t)); if (pFiltercap->data == NULL) { smlFreeDevInfFilterCapList(pFiltercap); return SML_ERR_NOT_ENOUGH_SPACE; } smlLibMemset(pFiltercap->data, 0, sizeof(SmlDevInfFilterCap_t)); // scan until we hit end of enclosure () while (pScanner->curtok->type != TOK_TAG_END) { // process tags switch (pScanner->curtok->tagid) { /* PCDATA elements */ case TN_DEVINF_CTTYPE: rc = buildPCData(pDecoder, (VoidPtr_t)&pFiltercap->data->cttype); break; case TN_DEVINF_VERCT: rc = buildPCData(pDecoder, (VoidPtr_t)&pFiltercap->data->verct); break; case TN_DEVINF_FILTERKEYWORD: ppList = &pFiltercap->data->filterkeyword; goto keywordOrPropname; case TN_DEVINF_PROPNAME: ppList = &pFiltercap->data->propname; goto keywordOrPropname; keywordOrPropname: // find last existing valenum while (*ppList!=NULL) ppList=&((*ppList)->next); // create new list element pList = (SmlPcdataListPtr_t)smlLibMalloc(sizeof(SmlPcdataList_t)); if (pList == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pList, 0, sizeof(SmlPcdataList_t)); // insert contents rc = buildPCData(pDecoder, (VoidPtr_t)&pList->data); if (rc==SML_ERR_OK) { // ok, add element to list *ppList = pList; ppList = &(pList->next); } else smlFreePcdataList(pList); // invalid, get rid of it break; default: rc = SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildDevInfFilterCapList"); } if (rc != SML_ERR_OK) { smlFreeDevInfFilterCapList(pFiltercap); return rc; } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlFreeDevInfFilterCapList(pFiltercap); return rc; } } /* while we do not see an end tag */ // link into list *ppListElem = pFiltercap; // set elem link to where we must link in next element ppListElem = &(pFiltercap->next); // done ok return SML_ERR_OK; } Ret_t buildDevInfDataStoreCmd(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem) { XltDecScannerPtr_t pScanner; SmlDevInfDatastorePtr_t pElem; Ret_t rc; pScanner = pDecoder->scanner; if (*ppElem != NULL) return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildDevInfDataStoreCmd"); if ((pElem = (SmlDevInfDatastorePtr_t)smlLibMalloc(sizeof(SmlDevInfDatastore_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pElem, 0, sizeof(SmlDevInfDatastore_t)); if (IS_EMPTY(pScanner->curtok)) { *ppElem = pElem; return SML_ERR_OK; } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlLibFree(pElem); return rc; } while (pScanner->curtok->type != TOK_TAG_END) { switch (pScanner->curtok->tagid) { /* PCDATA elements */ case TN_DEVINF_SOURCEREF: rc = buildPCData(pDecoder, (VoidPtr_t)&pElem->sourceref); break; case TN_DEVINF_DISPLAYNAME: rc = buildPCData(pDecoder, (VoidPtr_t)&pElem->displayname); break; case TN_DEVINF_MAXGUIDSIZE: rc = buildPCData(pDecoder, (VoidPtr_t)&pElem->maxguidsize); break; /* other elements */ case TN_DEVINF_RXPREF: if (pElem->rxpref!=NULL) { // we already have a RxPref - simply ignore further ones // (in DS 1.2, some implementations send an other rx-pref for the folder object apart from the main type) SmlDevInfXmitPtr_t dummyP = NULL; rc = buildDevInfXmitCmd(pDecoder, (VoidPtr_t)&dummyP); smlFreeDevInfXmit(dummyP); // simply discard after parsing } else rc = buildDevInfXmitCmd(pDecoder, (VoidPtr_t)&pElem->rxpref); break; case TN_DEVINF_TXPREF: if (pElem->txpref!=NULL) { // we already have a txpref - simply ignore further ones // (in DS 1.2, some implementations send an other tx-pref for the folder object apart from the main type) SmlDevInfXmitPtr_t dummyP = NULL; rc = buildDevInfXmitCmd(pDecoder, (VoidPtr_t)&dummyP); smlFreeDevInfXmit(dummyP); // simply discard after parsing } else rc = buildDevInfXmitCmd(pDecoder, (VoidPtr_t)&pElem->txpref); break; case TN_DEVINF_RX: rc = buildDevInfXmitList(pDecoder, (VoidPtr_t)&pElem->rx); break; case TN_DEVINF_TX: rc = buildDevInfXmitList(pDecoder, (VoidPtr_t)&pElem->tx); break; case TN_DEVINF_CTCAP: rc = buildDevInfCtcap(pDecoder, (VoidPtr_t)&pElem->ctcap,TRUE); // CTCap which is local to datastore (DS 1.2 style) break; case TN_DEVINF_DSMEM: rc = buildDevInfDSMemCmd(pDecoder, (VoidPtr_t)&pElem->dsmem); break; case TN_DEVINF_SYNCCAP: rc = buildDevInfSyncCapCmd(pDecoder, (VoidPtr_t)&pElem->synccap); break; /* SyncML DS 1.2, Synthesis/luz 2005-08-25 */ case TN_DEVINF_FILTERCAP: rc = buildDevInfFilterCapList(pDecoder, (VoidPtr_t)&pElem->filtercap); break; case TN_DEVINF_FILTERRX: rc = buildDevInfXmitList(pDecoder, (VoidPtr_t)&pElem->filterrx); break; case TN_DEVINF_HIERARCHICAL: pElem->flags |= SmlDevInfHierarchical_f; rc = buildEmptyTag(pDecoder); // allow for instead of break; case TN_DEVINF_FIELDLEVEL: pElem->flags |= SmlDevInfFieldLevel_f; rc = buildEmptyTag(pDecoder); // allow for instead of break; default: rc = SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildDevInfDataStoreCmd"); } if (rc != SML_ERR_OK) { smlLibFree(pElem); return rc; } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlLibFree(pElem); return rc; } } *ppElem = pElem; return SML_ERR_OK; } Ret_t buildDevInfXmitCmd(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem) { XltDecScannerPtr_t pScanner; SmlDevInfXmitPtr_t pXmit; Ret_t rc; pScanner = pDecoder->scanner; if (*ppElem != NULL) return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildDevInfXmitCmd"); if ((pXmit = (SmlDevInfXmitPtr_t)smlLibMalloc(sizeof(SmlDevInfXmit_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pXmit, 0, sizeof(SmlDevInfXmit_t)); if (IS_EMPTY(pScanner->curtok)) { *ppElem = pXmit; return SML_ERR_OK; } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlLibFree(pXmit); return rc; } while (pScanner->curtok->type != TOK_TAG_END) { switch (pScanner->curtok->tagid) { /* PCDATA elements */ case TN_DEVINF_CTTYPE: rc = buildPCData(pDecoder, (VoidPtr_t)&pXmit->cttype); break; case TN_DEVINF_VERCT: rc = buildPCData(pDecoder, (VoidPtr_t)&pXmit->verct); break; default: rc = SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildDevInfXmitCmd"); } if (rc != SML_ERR_OK) { smlLibFree(pXmit); return rc; } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlLibFree(pXmit); return rc; } } *ppElem = pXmit; return SML_ERR_OK; } Ret_t buildDevInfXmitList(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem) { SmlDevInfXmitListPtr_t pElem = NULL, pPrev = NULL; pElem = (SmlDevInfXmitListPtr_t) *ppElem; /* advance to the end of the list, and create ther an empty list element */ while (pElem != NULL) { pPrev = pElem; pElem = pPrev->next; } if ((pElem = (SmlDevInfXmitListPtr_t)smlLibMalloc(sizeof(SmlDevInfXmitList_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pElem, 0, sizeof(SmlDevInfXmitList_t)); if (pPrev != NULL) /* we already had some entries in the list */ pPrev->next = pElem; else /* nope we created a new list */ *ppElem = pElem; pElem->data = NULL; /* at this point pElem should point to an valid list element */ return buildDevInfXmitCmd(pDecoder, (VoidPtr_t)&pElem->data); } Ret_t buildDevInfDataStoreList(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem) { SmlDevInfDatastoreListPtr_t pElem = NULL, pPrev = NULL; pElem = (SmlDevInfDatastoreListPtr_t) *ppElem; /* advance to the end of the list, and create ther an empty list element */ while (pElem != NULL) { pPrev = pElem; pElem = pPrev->next; } if ((pElem = (SmlDevInfDatastoreListPtr_t)smlLibMalloc(sizeof(SmlDevInfDatastoreList_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pElem, 0, sizeof(SmlDevInfDatastoreList_t)); if (pPrev != NULL) /* we already had some entries in the list */ pPrev->next = pElem; else /* nope we created a new list */ *ppElem = pElem; pElem->data = NULL; /* at this point pElem should point to an valid list element */ return buildDevInfDataStoreCmd(pDecoder, (VoidPtr_t)&pElem->data); } Ret_t buildDevInfExtList(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem) { SmlDevInfExtListPtr_t pElem = NULL, pPrev = NULL; pElem = (SmlDevInfExtListPtr_t) *ppElem; /* advance to the end of the list, and create ther an empty list element */ while (pElem != NULL) { pPrev = pElem; pElem = pPrev->next; } if ((pElem = (SmlDevInfExtListPtr_t)smlLibMalloc(sizeof(SmlDevInfExtList_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pElem, 0, sizeof(SmlDevInfExtList_t)); if (pPrev != NULL) /* we already had some entries in the list */ pPrev->next = pElem; else /* nope we created a new list */ *ppElem = pElem; pElem->data = NULL; /* at this point pElem should point to an valid list element */ return buildDevInfExtCmd(pDecoder, (VoidPtr_t)&pElem->data); } /// @brief scans common elements of Properties and PropParams /// @return SML_ERR_XLT_INVAL_PROTO_ELEM if unknown tag is encountered static Ret_t scanPropOrParamElement(XltDecoderPtr_t pDecoder, SmlDevInfCTDataPtr_t pPropOrParam) { SmlPcdataListPtr_t *ppValenums = &(pPropOrParam->valenum); SmlPcdataListPtr_t pValenum; XltDecScannerPtr_t pScanner = pDecoder->scanner; Ret_t rc; // process tags switch (pScanner->curtok->tagid) { case TN_DEVINF_DISPLAYNAME: rc = buildPCData(pDecoder, (VoidPtr_t)&pPropOrParam->dname); break; case TN_DEVINF_DATATYPE: rc = buildPCData(pDecoder, (VoidPtr_t)&pPropOrParam->datatype); break; case TN_DEVINF_MAXSIZE: case TN_DEVINF_SIZE: rc = buildPCData(pDecoder, (VoidPtr_t)&pPropOrParam->maxsize); break; case TN_DEVINF_MAXOCCUR: rc = buildPCData(pDecoder, (VoidPtr_t)&pPropOrParam->maxoccur); break; /* Flags */ case TN_DEVINF_NOTRUNCATE: pPropOrParam->flags |= SmlDevInfNoTruncate_f; rc = buildEmptyTag(pDecoder); // allow for instead of break; /* Valenum* */ case TN_DEVINF_VALENUM: // find last existing valenum while (*ppValenums!=NULL) ppValenums=&((*ppValenums)->next); // create new list element pValenum = (SmlPcdataListPtr_t)smlLibMalloc(sizeof(SmlPcdataList_t)); if (pValenum == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pValenum, 0, sizeof(SmlPcdataList_t)); // insert contents rc = buildPCData(pDecoder, (VoidPtr_t)&pValenum->data); if (rc==SML_ERR_OK) { // ok, add element to list *ppValenums = pValenum; ppValenums = &(pValenum->next); } else smlFreePcdataList(pValenum); // invalid, get rid of it break; default: rc = SML_DECODEERROR(SML_ERR_XLT_INVAL_PROTO_ELEM,pScanner,"scanPropOrParamElement"); } return rc; } // @brief scan a single bracket, or a <1.2 type list where a new implies end of current PropParam and start of a new one static Ret_t buildDevInfPropParam(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem, int datastoreLocal) { SmlDevInfCTDataListPtr_t *ppListElem = NULL; SmlDevInfCTDataListPtr_t pParam = NULL; Boolean_t newElement = FALSE; XltDecScannerPtr_t pScanner = pDecoder->scanner; Ret_t rc; if (IS_EMPTY(pScanner->curtok)) { return SML_ERR_OK; } if (datastoreLocal) { // DS 1.2: we have no initial tag to process right away, get next tag now if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { return rc; } newElement=TRUE; // new has already started here } // get pointer to where we'd insert the next list element ppListElem = (SmlDevInfCTDataListPtr_t *)ppElem; while (*ppListElem!=NULL) { ppListElem = &((*ppListElem)->next); } pParam=NULL; // now ppListElem points to a SmlDevInfCTDataListPtr_t which is NULL and // can be overwritten with the link to a new element // scan until we hit end of enclosure () or an unknown other tag while (pScanner->curtok->type != TOK_TAG_END) { if (!datastoreLocal && pScanner->curtok->tagid==TN_DEVINF_PARAMNAME) { // DS 1.1-style CTCap, seeing implies new element newElement=TRUE; } // create new element if needed if (newElement) { newElement=FALSE; pParam = (SmlDevInfCTDataListPtr_t)smlLibMalloc(sizeof(SmlDevInfCTDataList_t)); if (pParam == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pParam, 0, sizeof(SmlDevInfCTDataList_t)); pParam->data = (SmlDevInfCTDataPtr_t)smlLibMalloc(sizeof(SmlDevInfCTData_t)); if (pParam->data == NULL) { smlFreeDevInfCTDataList(pParam); return SML_ERR_NOT_ENOUGH_SPACE; } smlLibMemset(pParam->data, 0, sizeof(SmlDevInfCTData_t)); // link into list *ppListElem = pParam; // set elem link to where we must link in next element ppListElem = &(pParam->next); } // now, if we don't have a pParam, this is an invalid curtok->tagid) { /* PCDATA */ case TN_DEVINF_PARAMNAME: rc = buildPCData(pDecoder, (VoidPtr_t)&pParam->data->name); break; default: rc = scanPropOrParamElement(pDecoder, pParam->data); if (rc==SML_ERR_XLT_INVAL_PROTO_ELEM && !datastoreLocal) return SML_ERR_OK; // parser signals unknown tag, this is ok for pre-1.2 break; } if (rc != SML_ERR_OK) return rc; if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) return rc; } /* while we do not see an end tag */ return SML_ERR_OK; } // @brief scan a single bracket, or a <1.2 type list where a new implies end of current property and start of a new one static Ret_t buildDevInfProperty(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem, int datastoreLocal) { SmlDevInfCTDataPropListPtr_t *ppListElem = NULL; SmlDevInfCTDataPropListPtr_t pProp = NULL; Boolean_t newElement = FALSE; XltDecScannerPtr_t pScanner = pDecoder->scanner; Ret_t rc; /* Do not return immediately for <1.2 style, the outer loop ends only meeting an end tag * which will lead to an infinite loop*/ if (datastoreLocal && IS_EMPTY(pScanner->curtok)) { return SML_ERR_OK; } if (datastoreLocal) { // DS 1.2: we have no initial tag to process right away, get next tag now if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { return rc; } newElement=TRUE; // new has already started here } // get pointer to where we'd insert the next list element ppListElem = (SmlDevInfCTDataPropListPtr_t *) ppElem; while (*ppListElem!=NULL) { ppListElem = &((*ppListElem)->next); } pProp=NULL; // now ppListElem points to a SmlDevInfCTDataPropListPtr_t which is NULL and // can be overwritten with the link to a new element // scan until we hit end of enclosure () or an unknown other tag while (pScanner->curtok->type != TOK_TAG_END) { if (!datastoreLocal && pScanner->curtok->tagid==TN_DEVINF_PROPNAME) { // DS 1.1-style CTCap, seeing implies new element newElement=TRUE; } // create new element if needed if (newElement) { newElement=FALSE; pProp = (SmlDevInfCTDataPropListPtr_t)smlLibMalloc(sizeof(SmlDevInfCTDataPropList_t)); if (pProp == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pProp, 0, sizeof(SmlDevInfCTDataPropList_t)); pProp->data = (SmlDevInfCTDataPropPtr_t)smlLibMalloc(sizeof(SmlDevInfCTDataProp_t)); if (pProp->data == NULL) { smlFreeDevInfCTDataPropList(pProp); return SML_ERR_NOT_ENOUGH_SPACE; } smlLibMemset(pProp->data, 0, sizeof(SmlDevInfCTDataProp_t)); pProp->data->prop = (SmlDevInfCTDataPtr_t)smlLibMalloc(sizeof(SmlDevInfCTData_t)); if (pProp->data->prop == NULL) { smlFreeDevInfCTDataPropList(pProp); return SML_ERR_NOT_ENOUGH_SPACE; } smlLibMemset(pProp->data->prop, 0, sizeof(SmlDevInfCTData_t)); // link into list *ppListElem = pProp; // set elem link to where we must link in next element ppListElem = &(pProp->next); } // now, if we don't have a pProp, this is an invalid curtok->tagid) { case TN_DEVINF_PROPPARAM: // DS 1.2 case: only ends the param building process rc = buildDevInfPropParam(pDecoder, (VoidPtr_t)&pProp->data->param,datastoreLocal); break; case TN_DEVINF_PARAMNAME: // directly within (instead of enclosed in a ) - Nokia 2630 style // -> do not reject it but try to process in DS 1.1 style even if this is a DS 1.2 devInf rc = buildDevInfPropParam(pDecoder, (VoidPtr_t)&pProp->data->param,FALSE); // force DS 1.1 style if (rc==SML_ERR_OK) continue; // re-evaluate current tag (tag that caused buildDevInfPropParam() to end, either next , unknown or closing } else { rc = buildDevInfPropParam(pDecoder, (VoidPtr_t)&pProp->data->param,datastoreLocal); if (rc==SML_ERR_OK) continue; // re-evaluate current tag (tag that caused buildDevInfPropParam() to end, either next , unknown or closing } break; /* PCDATA */ case TN_DEVINF_PROPNAME: rc = buildPCData(pDecoder, (VoidPtr_t)&pProp->data->prop->name); break; default: rc = scanPropOrParamElement(pDecoder, pProp->data->prop); if (rc==SML_ERR_XLT_INVAL_PROTO_ELEM && !datastoreLocal) return SML_ERR_OK; // parser signals unknown tag, this is ok for pre-1.2 } if (rc != SML_ERR_OK) return rc; if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) return rc; } /* while we do not see an end tag */ return SML_ERR_OK; } // @brief scan a single bracket, which may contain serveral ctcaps for =DS 1.2 Ret_t buildDevInfCtcap(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem, Boolean_t datastoreLocal) { SmlDevInfCtcapListPtr_t *ppListElem = NULL; SmlDevInfCtcapListPtr_t pCtcap = NULL; Boolean_t newElement = FALSE; XltDecScannerPtr_t pScanner = pDecoder->scanner; Ret_t rc; if (IS_EMPTY(pScanner->curtok)) { return SML_ERR_OK; } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { return rc; } // get pointer to where we'd insert the next list element ppListElem = (SmlDevInfCtcapListPtr_t *)ppElem; while (*ppListElem!=NULL) { ppListElem = &((*ppListElem)->next); } pCtcap=NULL; // now ppListElem points to a SmlDevInfCtcapListPtr_t which is NULL and // can be overwritten with the link to a new element // datastore local CTCap is DS 1.2 or later, and implies that every type description has its own // So starting a CTCap implies creating a new element newElement=datastoreLocal; while (pScanner->curtok->type != TOK_TAG_END) { if (!datastoreLocal && pScanner->curtok->tagid==TN_DEVINF_CTTYPE) { // DS 1.1-style CTCap, seeing CTTYPE implies new element newElement=TRUE; } // create new element if needed if (newElement) { newElement=FALSE; pCtcap = (SmlDevInfCtcapListPtr_t)smlLibMalloc(sizeof(SmlDevInfCtcapList_t)); if (pCtcap == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pCtcap, 0, sizeof(SmlDevInfCtcapList_t)); pCtcap->data = (SmlDevInfCTCapPtr_t)smlLibMalloc(sizeof(SmlDevInfCTCap_t)); if (pCtcap->data == NULL) { smlFreeDevInfCtcapList(pCtcap); return SML_ERR_NOT_ENOUGH_SPACE; } smlLibMemset(pCtcap->data, 0, sizeof(SmlDevInfCTCap_t)); // link into list *ppListElem = pCtcap; // set elem link to where we must link in next element ppListElem = &(pCtcap->next); } // now, if we don't have a pCtcap, this is an invalid follows if (pCtcap==NULL) return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildDevInfCtcap"); // process tags switch (pScanner->curtok->tagid) { case TN_DEVINF_CTTYPE: rc = buildPCData(pDecoder, (VoidPtr_t)&pCtcap->data->cttype); break; case TN_DEVINF_VERCT: rc = buildPCData(pDecoder, (VoidPtr_t)&pCtcap->data->verct); break; case TN_DEVINF_PROPERTY: // DS 1.2 case: only ends the property building process, next token must be read first // If there is a Property tag, let's take it as DS 1.2 Property Decoding even if the CTCAP is globally // This is found from some Nokia phones (eg. N900, which will send a DevInf v1.2 but the CTCAP // was not inside the datastore as DevInf v1.1) rc = buildDevInfProperty(pDecoder, (VoidPtr_t)&pCtcap->data->prop,TRUE); break; case TN_DEVINF_PROPNAME: // must be inside else { rc = buildDevInfProperty(pDecoder, (VoidPtr_t)&pCtcap->data->prop,datastoreLocal); if (rc==SML_ERR_OK) continue; // re-evaluate current tag (tag that caused buildDevInfProperty() to end, either unknown or closing // this means do not return SML_ERR_OK unless this is an unknow tag or closing , otherwise it will trigger an infinite loop } break; default: rc = SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildDevInfCtcap"); } if (rc != SML_ERR_OK) { return rc; } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { return rc; } } /* eof while */ return SML_ERR_OK; } Ret_t buildDevInfDSMemCmd(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem) { XltDecScannerPtr_t pScanner; SmlDevInfDSMemPtr_t pElem; Ret_t rc; pScanner = pDecoder->scanner; if (*ppElem != NULL) return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildDevInfDSMemCmd"); if ((pElem = (SmlDevInfDSMemPtr_t)smlLibMalloc(sizeof(SmlDevInfDSMem_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pElem, 0, sizeof(SmlDevInfDSMem_t)); if (IS_EMPTY(pScanner->curtok)) { *ppElem = pElem; return SML_ERR_OK; } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlLibFree(pElem); return rc; } while (pScanner->curtok->type != TOK_TAG_END) { switch (pScanner->curtok->tagid) { /* PCDATA elements */ case TN_DEVINF_SHAREDMEM: // %%% luz:2003-04-28: made work as a flag pElem->flags |= SmlDevInfSharedMem_f; rc = buildEmptyTag(pDecoder); // allow for instead of break; case TN_DEVINF_MAXMEM: rc = buildPCData(pDecoder, (VoidPtr_t)&pElem->maxmem); break; case TN_DEVINF_MAXID: rc = buildPCData(pDecoder, (VoidPtr_t)&pElem->maxid); break; default: rc = SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildDevInfDSMemCmd"); } if (rc != SML_ERR_OK) { smlLibFree(pElem); return rc; } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlLibFree(pElem); return rc; } } *ppElem = pElem; return SML_ERR_OK; } Ret_t buildDevInfCTCapCmd(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem) { XltDecScannerPtr_t pScanner; SmlDevInfCTCapPtr_t pElem; Ret_t rc; pScanner = pDecoder->scanner; if (*ppElem != NULL) return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildDevInfCTCapCmd"); if ((pElem = (SmlDevInfCTCapPtr_t)smlLibMalloc(sizeof(SmlDevInfCTCap_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pElem, 0, sizeof(SmlDevInfCTCap_t)); if (IS_EMPTY(pScanner->curtok)) { *ppElem = pElem; return SML_ERR_OK; } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlLibFree(pElem); return rc; } while (pScanner->curtok->type != TOK_TAG_END) { switch (pScanner->curtok->tagid) { case TN_DEVINF_CTTYPE: rc = buildPCData(pDecoder, (VoidPtr_t)&pElem->cttype); break; default: rc = SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildDevInfCTCapCmd"); } if (rc != SML_ERR_OK) { smlLibFree(pElem); return rc; } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlLibFree(pElem); return rc; } } *ppElem = pElem; return SML_ERR_OK; } Ret_t buildDevInfSyncCapCmd(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem) { XltDecScannerPtr_t pScanner; SmlDevInfSyncCapPtr_t pElem; Ret_t rc; pScanner = pDecoder->scanner; if (*ppElem != NULL) return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildDevInfSyncCapCmd"); if ((pElem = (SmlDevInfSyncCapPtr_t)smlLibMalloc(sizeof(SmlDevInfSyncCap_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pElem, 0, sizeof(SmlDevInfSyncCap_t)); if (IS_EMPTY(pScanner->curtok)) { *ppElem = pElem; return SML_ERR_OK; } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlLibFree(pElem); return rc; } while (pScanner->curtok->type != TOK_TAG_END) { switch (pScanner->curtok->tagid) { case TN_DEVINF_SYNCTYPE: rc = buildPCDataList(pDecoder, (VoidPtr_t)&pElem->synctype); break; default: rc = SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildDevInfSyncCapCmd"); } if (rc != SML_ERR_OK) { smlLibFree(pElem); return rc; } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlLibFree(pElem); return rc; } } *ppElem = pElem; return SML_ERR_OK; } Ret_t buildDevInfExtCmd(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem) { XltDecScannerPtr_t pScanner; SmlDevInfExtPtr_t pElem; Ret_t rc; pScanner = pDecoder->scanner; if (*ppElem != NULL) return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildDevInfExtCmd"); if ((pElem = (SmlDevInfExtPtr_t)smlLibMalloc(sizeof(SmlDevInfExt_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pElem, 0, sizeof(SmlDevInfExt_t)); if (IS_EMPTY(pScanner->curtok)) { *ppElem = pElem; return SML_ERR_OK; } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlLibFree(pElem); return rc; } while (pScanner->curtok->type != TOK_TAG_END) { switch (pScanner->curtok->tagid) { case TN_DEVINF_XNAM: rc = buildPCData(pDecoder, (VoidPtr_t)&pElem->xnam); break; case TN_DEVINF_XVAL: rc = buildPCDataList(pDecoder, (VoidPtr_t)&pElem->xval); break; default: rc = SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildDevInfExtCmd"); } if (rc != SML_ERR_OK) { smlLibFree(pElem); return rc; } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlLibFree(pElem); return rc; } } *ppElem = pElem; return SML_ERR_OK; } /* see xltenc.c:XltEncBlock for description of parameters */ Ret_t devinfEncBlock(XltTagID_t tagId, XltRO_t reqOptFlag, const VoidPtr_t pContent, SmlEncoding_t enc, BufferMgmtPtr_t pBufMgr, SmlPcdataExtension_t attFlag) { //Return variable Ret_t _err; SmlPcdataListPtr_t pList = NULL; SmlDevInfDatastoreListPtr_t dsList = NULL; SmlDevInfCtcapListPtr_t ctList = NULL; SmlDevInfExtListPtr_t exList = NULL; SmlDevInfXmitListPtr_t xmList = NULL; SmlDevInfFilterCapListPtr_t fcapList = NULL; SmlDevInfCTDataPropListPtr_t propList = NULL; SmlDevInfCTDataListPtr_t paramList = NULL; XltTagID_t nameTagID = TN_UNDEF; SmlDevInfCTDataPtr_t pPropOrParam = NULL; //Check if pContent of a required field is missing if ((reqOptFlag == REQUIRED) && (pContent == NULL)) return SML_ERR_XLT_MISSING_CONT; //Check if pContent of a optional field is missing -> if yes we are done else if (pContent == NULL) return SML_ERR_OK; //Generate the commands -> see DTD switch (tagId) { case TN_DEVINF_EXT: if ((_err = xltGenerateTag(TN_DEVINF_EXT, TT_BEG, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; if ((_err = devinfEncBlock(TN_DEVINF_XNAM, REQUIRED, ((SmlDevInfExtPtr_t) pContent)->xnam, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; pList = ((SmlDevInfExtPtr_t)pContent)->xval; while (pList != NULL) { if ((_err = devinfEncBlock(TN_DEVINF_XVAL, OPTIONAL, pList->data, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; pList = pList->next; }; if ((_err = xltGenerateTag(TN_DEVINF_EXT, TT_END, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; break; case TN_DEVINF_SYNCCAP: if ((_err = xltGenerateTag(TN_DEVINF_SYNCCAP, TT_BEG, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; pList = ((SmlDevInfSyncCapPtr_t)pContent)->synctype; while (pList != NULL) { if ((_err = devinfEncBlock(TN_DEVINF_SYNCTYPE, OPTIONAL, pList->data, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; pList = pList->next; }; if ((_err = xltGenerateTag(TN_DEVINF_SYNCCAP, TT_END, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; break; case TN_DEVINF_SHAREDMEM: //set the flag in the (WB)XML document if the flag is in the pContent if ((*((Flag_t *) pContent)) & (SmlDevInfSharedMem_f)) if ((_err = xltGenerateTag(tagId, TT_ALL, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; break; // %%% luz:2003-04-28 added missing 1.1 devinf tags here case TN_DEVINF_UTC: //set the flag in the (WB)XML document if the flag is in the pContent if ((*((Flag_t *) pContent)) & (SmlDevInfUTC_f)) { if ((_err = xltGenerateTag(tagId, TT_ALL, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; } break; case TN_DEVINF_NOFM: //set the flag in the (WB)XML document if the flag is in the pContent if ((*((Flag_t *) pContent)) & (SmlDevInfNOfM_f)) { if ((_err = xltGenerateTag(tagId, TT_ALL, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; } break; case TN_DEVINF_LARGEOBJECT: //set the flag in the (WB)XML document if the flag is in the pContent if ((*((Flag_t *) pContent)) & (SmlDevInfLargeObject_f)) { if ((_err = xltGenerateTag(tagId, TT_ALL, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; } break; /* SyncML DS 1.2, Synthesis/luz 2005-08-24 */ case TN_DEVINF_FIELDLEVEL: //set the flag in the (WB)XML document if the flag is in the pContent if ((*((Flag_t *) pContent)) & (SmlDevInfFieldLevel_f)) { if ((_err = xltGenerateTag(tagId, TT_ALL, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; } break; case TN_DEVINF_HIERARCHICAL: //set the flag in the (WB)XML document if the flag is in the pContent if ((*((Flag_t *) pContent)) & (SmlDevInfHierarchical_f)) { if ((_err = xltGenerateTag(tagId, TT_ALL, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; } break; case TN_DEVINF_NOTRUNCATE: //set the flag in the (WB)XML document if the flag is in the pContent if ((*((Flag_t *) pContent)) & (SmlDevInfNoTruncate_f)) { if ((_err = xltGenerateTag(tagId, TT_ALL, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; } break; case TN_DEVINF_PROPERTY: // pContent is SmlDevInfCTDataPropPtr_t paramList = ((SmlDevInfCTDataPropPtr_t)pContent)->param; // get param list // modify pContent pPropOrParam = ((SmlDevInfCTDataPropPtr_t)pContent)->prop; // common property/propparam description record // set the tag to be used for name nameTagID=TN_DEVINF_PROPNAME; // is a property, use goto param_or_property; case TN_DEVINF_PROPPARAM: // pContent is SmlDevInfCTDataPtr_t (common data structure for and ) paramList=NULL; // set the tag to be used for name nameTagID=TN_DEVINF_PARAMNAME; // is a propparam, use // set content pPropOrParam = (SmlDevInfCTDataPtr_t)pContent; goto param_or_property; param_or_property: // - pPropOrParam is SmlDevInfCTDataPtr_t (common data structure for and ) // - paramList is either NULL (for params, which do not have params themselves) or SmlDevInfCTDataListPtr_t (for properties) // DS 1.2 or higher : open / to properly group all property related elements if (pBufMgr->vers>=SML_VERS_1_2) { if ((_err = xltGenerateTag(tagId, TT_BEG, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; } /* -- Propname or ParamName */ if ((_err = devinfEncBlock(nameTagID, REQUIRED, pPropOrParam->name, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; /* -- (ValEnum+ | (Datatype, Size?))? */ //%%% luz 2007-08-14 empty datatype is allowed as well (as this is what e.g. Nokia E90 sends, and when using SML to translate back to XML, we'd failed here before) if (pPropOrParam->valenum != NULL && pPropOrParam->datatype != NULL && pPropOrParam->datatype->length!=0) return SML_ERR_XLT_INVAL_INPUT_DATA; if (pPropOrParam->valenum != NULL) { // ValEnum+ pList = pPropOrParam->valenum; while (pList != NULL) { if ((_err = devinfEncBlock(TN_DEVINF_VALENUM, REQUIRED, pList->data, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; pList = pList->next; }; } else if (pPropOrParam->datatype != NULL) { // Datatype? if ((_err = devinfEncBlock(TN_DEVINF_DATATYPE, REQUIRED, pPropOrParam->datatype, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; } /* (Max)Size? (note, in <1.2, the tag was called "Size", in >=1.2, the tag is called "MaxSize" - but both have the same WBXML token) */ if ((_err = devinfEncBlock(pBufMgr->vers>=SML_VERS_1_2 ? TN_DEVINF_MAXSIZE : TN_DEVINF_SIZE, OPTIONAL, pPropOrParam->maxsize, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; /* -- DS 1.2: MaxOccur?, is valid for Properties only, not for PropParams */ if ((_err = devinfEncBlock(TN_DEVINF_MAXOCCUR, OPTIONAL, pPropOrParam->maxoccur, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; /* -- DS 1.2: (NoTruncate?), is valid for Properties only, not for PropParams */ if ((_err = devinfEncBlock(TN_DEVINF_NOTRUNCATE, OPTIONAL, &(pPropOrParam->flags), enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; /* -- DisplayName ? */ if ((_err = devinfEncBlock(TN_DEVINF_DISPLAYNAME, OPTIONAL, pPropOrParam->dname, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; /* -- now the paramList */ while (paramList != NULL) { /* Synthesis/luz 2005-08-24 : separated generation of element into own case */ if ((_err = devinfEncBlock(TN_DEVINF_PROPPARAM, REQUIRED, paramList->data, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; paramList = paramList->next; } // DS 1.2 or higher : close / encapsulation if (pBufMgr->vers>=SML_VERS_1_2) { if ((_err = xltGenerateTag(tagId, TT_END, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; } break; case TN_DEVINF_CTCAP: ctList = ((SmlDevInfCtcapListPtr_t)pContent); if (ctList == NULL) break; // empty CTCap - is ok, do not output anything // before DS 1.2 : all types are encapsulated in a single CTCap if (pBufMgr->versdata == NULL) return SML_ERR_XLT_INVAL_INPUT_DATA; // DS 1.2 or higher : every content type is separately enclosed in a CTCap if (pBufMgr->vers>=SML_VERS_1_2) { if ((_err = xltGenerateTag(TN_DEVINF_CTCAP, TT_BEG, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; } if ((_err = devinfEncBlock(TN_DEVINF_CTTYPE, REQUIRED, ctList->data->cttype, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; /* SyncML DS 1.2, Synthesis/luz 2005-09-28, required for DS 1.2 only, therefore OPTIONAL here */ if ((_err = devinfEncBlock(TN_DEVINF_VERCT, OPTIONAL, ctList->data->verct, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; /* SyncML DS 1.2, Synthesis/luz 2005-08-24 */ if ((_err = devinfEncBlock(TN_DEVINF_FIELDLEVEL, OPTIONAL, &(ctList->data->flags), enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; /* now the propList */ // %%% luz 2002-11-27: made property list optional (e.g. text/message of P800 has none) propList = ctList->data->prop; // %%% original: if (propList == NULL) return SML_ERR_XLT_INVAL_INPUT_DATA; while (propList != NULL) { if (propList->data == NULL) return SML_ERR_XLT_INVAL_INPUT_DATA; if (propList->data->prop == NULL) return SML_ERR_XLT_INVAL_INPUT_DATA; /* Synthesis/luz 2005-08-24 : separated generation of element into own case */ if ((_err = devinfEncBlock(TN_DEVINF_PROPERTY, REQUIRED, propList->data, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; propList = propList->next; } // DS 1.2 or higher : every content type is separately enclosed in a CTCap if (pBufMgr->vers>=SML_VERS_1_2) { if ((_err = xltGenerateTag(TN_DEVINF_CTCAP, TT_END, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; } /* eof propList */ ctList = ctList->next; }; // before DS 1.2 : all types are encapsulated in a single CTCap if (pBufMgr->versflags), enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; if ((_err = devinfEncBlock(TN_DEVINF_MAXMEM, OPTIONAL, ((SmlDevInfDSMemPtr_t) pContent)->maxmem, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; if ((_err = devinfEncBlock(TN_DEVINF_MAXID, OPTIONAL, ((SmlDevInfDSMemPtr_t) pContent)->maxid, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; if ((_err = xltGenerateTag(TN_DEVINF_DSMEM, TT_END, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; break; // special case, the following 5 have the same structure, only the tag name differs case TN_DEVINF_RX: case TN_DEVINF_TX: case TN_DEVINF_RXPREF: case TN_DEVINF_TXPREF: case TN_DEVINF_FILTERRX: /* SyncML DS 1.2, Synthesis/luz 2005-08-24 */ if ((_err = xltGenerateTag(tagId, TT_BEG, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; if ((_err = devinfEncBlock(TN_DEVINF_CTTYPE, REQUIRED, ((SmlDevInfXmitPtr_t) pContent)->cttype, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; if ((_err = devinfEncBlock(TN_DEVINF_VERCT, REQUIRED, ((SmlDevInfXmitPtr_t) pContent)->verct, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; if ((_err = xltGenerateTag(tagId, TT_END, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; break; /* SyncML DS 1.2, Synthesis/luz 2005-08-24 */ case TN_DEVINF_FILTERCAP: if ((_err = xltGenerateTag(tagId, TT_BEG, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; if ((_err = devinfEncBlock(TN_DEVINF_CTTYPE, REQUIRED, ((SmlDevInfFilterCapPtr_t) pContent)->cttype, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; if ((_err = devinfEncBlock(TN_DEVINF_VERCT, REQUIRED, ((SmlDevInfFilterCapPtr_t) pContent)->verct, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; pList = ((SmlDevInfFilterCapPtr_t) pContent)->filterkeyword; while (pList != NULL) { if ((_err = devinfEncBlock(TN_DEVINF_FILTERKEYWORD, REQUIRED, pList->data, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; pList=pList->next; } pList = ((SmlDevInfFilterCapPtr_t) pContent)->propname; while (pList != NULL) { if ((_err = devinfEncBlock(TN_DEVINF_PROPNAME, REQUIRED, pList->data, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; pList=pList->next; } if ((_err = xltGenerateTag(tagId, TT_END, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; break; case TN_DEVINF_DATASTORE: if ((_err = xltGenerateTag(TN_DEVINF_DATASTORE, TT_BEG, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; if ((_err = devinfEncBlock(TN_DEVINF_SOURCEREF, REQUIRED, ((SmlDevInfDatastorePtr_t) pContent)->sourceref, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; if ((_err = devinfEncBlock(TN_DEVINF_DISPLAYNAME, OPTIONAL, ((SmlDevInfDatastorePtr_t) pContent)->displayname, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; if ((_err = devinfEncBlock(TN_DEVINF_MAXGUIDSIZE, OPTIONAL, ((SmlDevInfDatastorePtr_t) pContent)->maxguidsize, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; if ((_err = devinfEncBlock(TN_DEVINF_RXPREF, REQUIRED, ((SmlDevInfDatastorePtr_t) pContent)->rxpref, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; xmList = ((SmlDevInfDatastorePtr_t)pContent)->rx; while (xmList != NULL) { if ((_err = devinfEncBlock(TN_DEVINF_RX, OPTIONAL, xmList->data, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; xmList = xmList->next; }; if ((_err = devinfEncBlock(TN_DEVINF_TXPREF, REQUIRED, ((SmlDevInfDatastorePtr_t) pContent)->txpref, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; xmList = ((SmlDevInfDatastorePtr_t)pContent)->tx; while (xmList != NULL) { if ((_err = devinfEncBlock(TN_DEVINF_TX, OPTIONAL, xmList->data, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; xmList = xmList->next; }; /* For SyncML DS 1.2, CTCaps are local to datastore, no longer global in DevInf */ if ((_err = devinfEncBlock(TN_DEVINF_CTCAP, OPTIONAL, ((SmlDevInfDatastorePtr_t) pContent)->ctcap, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; if ((_err = devinfEncBlock(TN_DEVINF_DSMEM, OPTIONAL, ((SmlDevInfDatastorePtr_t) pContent)->dsmem, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; /* SyncML DS 1.2, Synthesis/luz 2005-08-24 */ if ((_err = devinfEncBlock(TN_DEVINF_HIERARCHICAL, OPTIONAL, &(((SmlDevInfDatastorePtr_t) pContent)->flags), enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; if ((_err = devinfEncBlock(TN_DEVINF_SYNCCAP, REQUIRED, ((SmlDevInfDatastorePtr_t) pContent)->synccap, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; /* SyncML DS 1.2, Synthesis/luz 2005-08-24 */ xmList = ((SmlDevInfDatastorePtr_t)pContent)->filterrx; while (xmList != NULL) { if ((_err = devinfEncBlock(TN_DEVINF_FILTERRX, OPTIONAL, xmList->data, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; xmList = xmList->next; }; /* SyncML DS 1.2, Synthesis/luz 2005-08-25 */ fcapList = ((SmlDevInfDatastorePtr_t)pContent)->filtercap; while (fcapList != NULL) { if ((_err = devinfEncBlock(TN_DEVINF_FILTERCAP, OPTIONAL, fcapList->data, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; fcapList = fcapList->next; }; if ((_err = xltGenerateTag(TN_DEVINF_DATASTORE, TT_END, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; break; case TN_DEVINF_DEVINF: if ((_err = xltGenerateTag(TN_DEVINF_DEVINF, TT_BEG, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; if ((_err = devinfEncBlock(TN_DEVINF_VERDTD, REQUIRED, ((SmlDevInfDevInfPtr_t) pContent)->verdtd, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; if ((_err = devinfEncBlock(TN_DEVINF_MAN, OPTIONAL, ((SmlDevInfDevInfPtr_t) pContent)->man, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; if ((_err = devinfEncBlock(TN_DEVINF_MOD, OPTIONAL, ((SmlDevInfDevInfPtr_t) pContent)->mod, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; if ((_err = devinfEncBlock(TN_DEVINF_OEM, OPTIONAL, ((SmlDevInfDevInfPtr_t) pContent)->oem, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; if ((_err = devinfEncBlock(TN_DEVINF_FWV, OPTIONAL, ((SmlDevInfDevInfPtr_t) pContent)->fwv, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; if ((_err = devinfEncBlock(TN_DEVINF_SWV, OPTIONAL, ((SmlDevInfDevInfPtr_t) pContent)->swv, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; if ((_err = devinfEncBlock(TN_DEVINF_HWV, OPTIONAL, ((SmlDevInfDevInfPtr_t) pContent)->hwv, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; if ((_err = devinfEncBlock(TN_DEVINF_DEVID, REQUIRED, ((SmlDevInfDevInfPtr_t) pContent)->devid, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; if ((_err = devinfEncBlock(TN_DEVINF_DEVTYP, REQUIRED, ((SmlDevInfDevInfPtr_t) pContent)->devtyp, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; if ((_err = devinfEncBlock(TN_DEVINF_UTC, OPTIONAL, &(((SmlDevInfDevInfPtr_t) pContent)->flags), enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; if ((_err = devinfEncBlock(TN_DEVINF_NOFM, OPTIONAL, &(((SmlDevInfDevInfPtr_t) pContent)->flags), enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; if ((_err = devinfEncBlock(TN_DEVINF_LARGEOBJECT, OPTIONAL, &(((SmlDevInfDevInfPtr_t) pContent)->flags), enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; // According to SyncML standard, the dsList must not be empty. However as some implementations send such devInf, // and the RTK is also used to convert WBXML to XML for human readable message dumps, we now allow // generating such devInf (for the XML log output). dsList = ((SmlDevInfDevInfPtr_t)pContent)->datastore; //if (dsList == NULL) return SML_ERR_XLT_MISSING_CONT; if(dsList != NULL) { if ((_err = devinfEncBlock(TN_DEVINF_DATASTORE, REQUIRED, dsList->data, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; dsList = dsList->next; while (dsList != NULL) { if ((_err = devinfEncBlock(TN_DEVINF_DATASTORE, OPTIONAL, dsList->data, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; dsList = dsList->next; }; } // for pre DS 1.2, CTCaps are global (i.e at the devInf level): if ((_err = devinfEncBlock(TN_DEVINF_CTCAP, OPTIONAL, ((SmlDevInfDevInfPtr_t)pContent)->ctcap, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; // extensions exList = ((SmlDevInfDevInfPtr_t)pContent)->ext; while (exList != NULL) { if ((_err = devinfEncBlock(TN_DEVINF_EXT, OPTIONAL, exList->data, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; exList = exList->next; }; if ((_err = xltGenerateTag(TN_DEVINF_DEVINF, TT_END, enc, pBufMgr, SML_EXT_DEVINF)) != SML_ERR_OK) return _err; break; default: { // all leaf nodes (PCDATA#) return xltEncPcdata(tagId, reqOptFlag, pContent, enc, pBufMgr, attFlag); } //* eof default statement from switch tagid } // eof switch tagid return SML_ERR_OK; } #endif /* __USE_DEVINF__ */ libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/xlt/all/xltdevinf.h000077500000000000000000000065231226375725500245640ustar00rootroot00000000000000/** * @file * Definition of DevInf DTD prototypefunctions for the en-/decoder * * @target_system all * @target_os all */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ #ifndef _XLT_DEVINF_H #define _XLT_DEVINF_H /* process only if we really use DevInf DTD */ #ifdef __USE_DEVINF__ /*************************************************************************/ /* Definitions */ /*************************************************************************/ #include "xlttagtbl.h" #include "xltenc.h" Ret_t buildDevInfDevInfCmd(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem); Ret_t buildDevInfDataStoreCmd(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem); Ret_t buildDevInfXmitCmd(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem); Ret_t buildDevInfXmitList(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem); Ret_t buildDevInfDSMemCmd(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem); Ret_t buildDevInfCTCapCmd(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem); Ret_t buildDevInfSyncCapCmd(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem); Ret_t buildDevInfExtCmd(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem); Ret_t buildDevInfDataStoreList(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem); Ret_t buildDevInfExtList(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem); Ret_t buildDevInfCTCapList(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem); Ret_t devinfEncBlock(XltTagID_t tagId, XltRO_t reqOptFlag, const VoidPtr_t pContent, SmlEncoding_t enc, BufferMgmtPtr_t pBufMgr, SmlPcdataExtension_t attFlag); #endif /* __USE_DEVINF__ */ #endif /* _XLT_DEVINF_H */ libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/xlt/all/xltenc.c000077500000000000000000002007211226375725500240450ustar00rootroot00000000000000/** * @file * Encoder source file * * @target_system All * @target_os All */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ /*************************************************************************/ /* Definitions */ /*************************************************************************/ #include "syncml_tk_prefix_file.h" // %%% luz: needed for precompiled headers in eVC++ #include #ifdef __SML_WBXML__ #include "xltencwbxml.h" #endif #ifdef __SML_XML__ #include "xltencxml.h" #endif #include "xlttags.h" #include "xltmetinf.h" #include "xltdevinf.h" #include "smlmetinfdtd.h" #include "smldevinfdtd.h" #include #include #include Ret_t getTNbyPE(SmlProtoElement_t, XltTagID_t*); Ret_t xltEncBlock(XltTagID_t, XltRO_t, const VoidPtr_t, SmlEncoding_t, BufferMgmtPtr_t, SmlPcdataExtension_t); Ret_t xltEncList(XltListType_t, XltRO_t, VoidPtr_t, SmlEncoding_t, BufferMgmtPtr_t, SmlPcdataExtension_t); #ifndef __SML_LITE__ Ret_t xltBuildExtention(SmlPcdataExtension_t, XltRO_t, VoidPtr_t, SmlEncoding_t, BufferMgmtPtr_t); #endif typedef struct PEEnc_s { XltTagID_t tagid; SmlProtoElement_t type; } PEEnc_t, *PEEncPtr_t; /* luz 2005-08-17: simplified, removed unnecessary copying of the const static table */ static const PEEnc_t cPE_Enc[] = { { TN_ADD, SML_PE_ADD }, { TN_ALERT, SML_PE_ALERT }, { TN_ATOMIC, SML_PE_ATOMIC_START }, { TN_ATOMIC_END, SML_PE_ATOMIC_END }, { TN_COPY, SML_PE_COPY }, { TN_DELETE, SML_PE_DELETE }, { TN_EXEC, SML_PE_EXEC }, { TN_GET, SML_PE_GET }, { TN_MAP, SML_PE_MAP }, { TN_PUT, SML_PE_PUT }, { TN_RESULTS, SML_PE_RESULTS }, { TN_SEARCH, SML_PE_SEARCH }, { TN_SEQUENCE, SML_PE_SEQUENCE_START }, { TN_SEQUENCE_END, SML_PE_SEQUENCE_END }, { TN_STATUS, SML_PE_STATUS }, { TN_SYNC, SML_PE_SYNC_START }, { TN_SYNC_END, SML_PE_SYNC_END }, { TN_REPLACE, SML_PE_REPLACE }, { TN_UNDEF, SML_PE_UNDEF } }; Ret_t getTNbyPE(SmlProtoElement_t pE, XltTagID_t *tagID) { int i = 0; while ((cPE_Enc[i].type) != SML_PE_UNDEF) { if ((cPE_Enc[i].type) == pE) { *tagID = cPE_Enc[i].tagid; return SML_ERR_OK; } i++; } *tagID = TN_UNDEF; return SML_ERR_XLT_INVAL_PROTO_ELEM; } // %%% luz:2003-07-31: added SyncML FPI (formal public identifier) tables const char * const SyncMLFPI[SML_NUM_VERS] = { "???", "-//SYNCML//DTD SyncML 1.0//EN", "-//SYNCML//DTD SyncML 1.1//EN", "-//SYNCML//DTD SyncML 1.2//EN" }; const char * const SyncMLDevInfFPI[SML_NUM_VERS] = { "???", "-//SYNCML//DTD DevInf 1.0//EN", "-//SYNCML//DTD DevInf 1.1//EN", "-//SYNCML//DTD DevInf 1.2//EN" }; const int SyncMLWBXMLPublicID[SML_NUM_VERS] = { 0, 0, // we use the string ID, not the binary value (altough it seems to be defined as 0x0FD1 0x0FD3, 0x1201 }; const int SyncMLDevInfWBXMLPublicID[SML_NUM_VERS] = { 0, 0, 0x0FD4, // according to Nokia E70 0x1203 // according to Nokia E70 }; /** * Initializes an XML buffer; Creates XML code for the SyncHdr * and appends it to the buffer. * Returns 0 if operation was successful. * * @pre no memory should be allocated for ppEncoder (should be NULL) * pHeader has to contain a valid SyncHdr structure * pBufEnd must point to the end of the (WB)XML buffer * ppBufPos has to be initialized to the start point of the * (WB)XML buffer. * @post After the function call ppBufPos points to the * first free byte in the buffer behind the (WB)XML document * @param enc (IN) * the encoding constant (SML_WBXML or SML_XML) * @param pHeader (IN) * the SyncML header structure * @param pBufEnd (IN) * pointer to the end of the buffer to write on * @param ppBufPos (IN/OUT) * current position of the bufferpointer * @param ppEncoder (IN/OUT) * the encoder object * @param vers (IN) * SyncML version * @return shows error codes of function,\n * 0, if OK\n * Possible Error Codes: * - SML_ERR_XLT_MISSING_CONT * - SML_ERR_XLT_BUF_ERR * - SML_ERR_XLT_INVAL_ELEM_TYPE * - SML_ERR_XLT_INVAL_LIST_TYPE * - SML_ERR_XLT_INVAL_TAG_TYPE * - SML_ERR_XLT_ENC_UNK * - SML_ERR_XLT_INVAL_PROTO_ELEM */ Ret_t xltEncInit(SmlEncoding_t enc, const SmlSyncHdrPtr_t pHeader, const MemPtr_t pBufEnd, MemPtr_t *ppBufPos, XltEncoderPtr_t *ppEncoder, SmlVersion_t vers) { // Return variable Ret_t _err; XltEncoderPtr_t _pEncoder; //Structure containing buffer pointers, length and written bytes BufferMgmtPtr_t _pBufMgr; #ifdef __SML_XML__ MemPtr_t _tmpStr; MemPtr_t _xmlver = (MemPtr_t)XML_VERSION; MemPtr_t _xmlenc = (MemPtr_t)XML_ENCODING; MemByte_t _begpar = XML_BEGPAR; MemByte_t _endpar = XML_ENDPAR; #endif #ifdef __SML_WBXML__ MemByte_t _wbxmlver = XLT_WBXMLVER; MemByte_t _charset = XLT_CHARSET; // check if we want to send numeric or textual FPI MemByte_t _pubident1 = 0; // default to textual MemByte_t _pubident2 = 0; const char *_syncmldtd = SyncMLFPI[vers]; unsigned short fpi = SyncMLWBXMLPublicID[vers]; MemByte_t _stablen = smlLibStrlen(_syncmldtd); // %% not 0x1D constant! if (fpi) { // numeric FPI available _pubident1 = ((fpi>>7) & 0x7F)+0x80; // upper 7 bit _pubident2 = (fpi & 0x7F); // lower 7 bits _stablen = 0; // no string table } #endif //MemByte_t _tmp = 0x00;CURRENTLY NOT USED if ((_pEncoder = (XltEncoderPtr_t)smlLibMalloc(sizeof(XltEncoder_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; if ((_pBufMgr = (BufferMgmtPtr_t)smlLibMalloc(sizeof(BufferMgmt_t))) == NULL) { smlLibFree(_pEncoder); return SML_ERR_NOT_ENOUGH_SPACE; } //set the encoding _pEncoder->enc = enc; // %%% luz:2003-07-31: added version _pEncoder->vers = vers; _pEncoder->cur_ext = (SmlPcdataExtension_t)SML_EXT_UNDEFINED; _pEncoder->last_ext = (SmlPcdataExtension_t)SML_EXT_UNDEFINED; _pEncoder->end_tag_size = 0; _pEncoder->space_evaluation = NULL; _pBufMgr->smlXltBufferP = *ppBufPos; _pBufMgr->smlXltBufferLen = pBufEnd - *ppBufPos; _pBufMgr->smlXltStoreBufP = _pBufMgr->smlXltBufferP; _pBufMgr->smlXltWrittenBytes = 0; _pBufMgr->smlCurExt = _pEncoder->cur_ext; _pBufMgr->smlLastExt = _pEncoder->last_ext; _pBufMgr->smlActiveExt = SML_EXT_UNDEFINED; _pBufMgr->switchExtTag = TN_UNDEF; _pBufMgr->spaceEvaluation = 0; _pBufMgr->vers = vers; _pBufMgr->endTagSize = 0; switch (enc) { #ifdef __SML_WBXML__ case SML_WBXML: { // Set the WBXML Header Values // WBXML Version if ((_err = wbxmlWriteTypeToBuffer((MemPtr_t)(&_wbxmlver), TAG, 1, _pBufMgr)) != SML_ERR_OK) break; // Public Idetifier - default unknown if ((_err = wbxmlWriteTypeToBuffer((MemPtr_t)(&_pubident1), TAG, 1, _pBufMgr)) != SML_ERR_OK) break; if ((_err = wbxmlWriteTypeToBuffer((MemPtr_t)(&_pubident2), TAG, 1, _pBufMgr)) != SML_ERR_OK) break; // Character set - not yet implemented if ((_err = wbxmlWriteTypeToBuffer((MemPtr_t)(&_charset), TAG, 1, _pBufMgr)) != SML_ERR_OK) break; // - String table length - only used for textual FPI if ((_err = wbxmlWriteTypeToBuffer((MemPtr_t)(&_stablen), TAG, 1, _pBufMgr)) != SML_ERR_OK) break; // FPI - %%% luz:2003-07-31: not constant any more, varies according to SyncML version if (fpi==0) { // textual FPI // - string table consisting of FPI only if ((_err = xltAddToBuffer((MemPtr_t) (_syncmldtd) , smlLibStrlen((String_t)_syncmldtd), _pBufMgr)) != SML_ERR_OK) break; } else { // numeric FPI // NOP - no string table } break; } #endif #ifdef __SML_XML__ case SML_XML: { if ((_err = xltAddToBuffer((MemPtr_t)(&_begpar), 1, _pBufMgr)) != SML_ERR_OK) break; _tmpStr = (MemPtr_t)"?xml version=\""; if ((_err = xltAddToBuffer(_tmpStr, smlLibStrlen((String_t)_tmpStr), _pBufMgr)) != SML_ERR_OK) break; _tmpStr = _xmlver; if ((_err = xltAddToBuffer(_tmpStr, smlLibStrlen((String_t)_tmpStr), _pBufMgr)) != SML_ERR_OK) break; _tmpStr = (MemPtr_t)"\" encoding=\""; if ((_err = xltAddToBuffer(_tmpStr, smlLibStrlen((String_t)_tmpStr), _pBufMgr)) != SML_ERR_OK) break; _tmpStr = _xmlenc; if ((_err = xltAddToBuffer(_tmpStr, smlLibStrlen((String_t)_tmpStr), _pBufMgr)) != SML_ERR_OK) break; _tmpStr = (MemPtr_t)"\"?"; if ((_err = xltAddToBuffer(_tmpStr, smlLibStrlen((String_t)_tmpStr), _pBufMgr)) != SML_ERR_OK) break; if ((_err = xltAddToBuffer((MemPtr_t)(&_endpar), 1, _pBufMgr)) != SML_ERR_OK) break; break; } #endif default: { _err = SML_ERR_XLT_ENC_UNK; } } if (_err != SML_ERR_OK) { smlLibFree(_pBufMgr); smlLibFree(_pEncoder); return _err; } // SyncML Tag if ((_err = xltGenerateTag(TN_SYNCML, TT_BEG, enc, _pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) { smlLibFree(_pBufMgr); smlLibFree(_pEncoder); return _err; } // Generate SmlSyncHdr if ((_err = xltEncBlock(TN_SYNCHDR, REQUIRED, pHeader, enc, _pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) { smlLibFree(_pBufMgr); smlLibFree(_pEncoder); return _err; } // SyncBody Tag if ((_err = xltGenerateTag(TN_SYNCBODY, TT_BEG, enc, _pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) { smlLibFree(_pBufMgr); smlLibFree(_pEncoder); return _err; } _pEncoder->cur_ext = _pBufMgr->smlCurExt; _pEncoder->last_ext = _pBufMgr->smlLastExt; _pEncoder->end_tag_size = _pBufMgr->endTagSize; *ppBufPos = _pBufMgr->smlXltBufferP; smlLibFree(_pBufMgr); _pEncoder->final = 0; *ppEncoder = (XltEncoderPtr_t)_pEncoder; return SML_ERR_OK; } /** * Generates (WB)XML code and appends it to the XML buffer. * * @pre pEncoder holds the initialized encoder structure. * the initialization takes place in the xltEncAppend function * pContent has to contain a valid content structure structure * pBufEnd must point to the end of the (WB)XML buffer * ppBufPos has to be initialized to the start point of the * (WB)XML buffer. * @post After the function call ppBufPos points to the * first free byte in the buffer behind the (WB)XML document * @param pEncoder (IN) * the encoder object * @param pe (IN) * the protocol element (PE_ADD, ...) * @param pBufEnd (IN) * pointer to the end of the buffer to write on * @param pContent (IN) * the content to append to the SyncML document * @param ppBufPos (IN/OUT) * current position of the bufferpointer * @return shows error codes of function,\n * 0, if OK\n * Possible Error Codes: * - SML_ERR_XLT_MISSING_CONT * - SML_ERR_XLT_BUF_ERR * - SML_ERR_XLT_INVAL_ELEM_TYPE * - SML_ERR_XLT_INVAL_LIST_TYPE * - SML_ERR_XLT_INVAL_TAG_TYPE * - SML_ERR_XLT_ENC_UNK * - SML_ERR_XLT_INVAL_PROTO_ELEM */ Ret_t xltEncAppend(const XltEncoderPtr_t pEncoder, SmlProtoElement_t pe, const MemPtr_t pBufEnd, const VoidPtr_t pContent, MemPtr_t *ppBufPos) { // Return variable Ret_t _err; XltTagID_t tagID = TN_UNDEF; // encoding type SmlEncoding_t _enc; //Structure containing buffer pointers, length and written bytes BufferMgmtPtr_t _pBufMgr; if ((_pBufMgr = (BufferMgmtPtr_t)smlLibMalloc(sizeof(BufferMgmt_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(_pBufMgr, 0, sizeof(BufferMgmt_t)); //get the encoding type _enc = pEncoder->enc; _pBufMgr->vers = pEncoder->vers; // %%% luz:2003-07-31: pass SyncML version to bufmgr _pBufMgr->smlXltBufferP = *ppBufPos; _pBufMgr->smlXltBufferLen = pBufEnd - *ppBufPos; _pBufMgr->smlXltStoreBufP = _pBufMgr->smlXltBufferP; _pBufMgr->smlXltWrittenBytes = 0; _pBufMgr->smlActiveExt = SML_EXT_UNDEFINED; _pBufMgr->switchExtTag = TN_UNDEF; _pBufMgr->spaceEvaluation = ((pEncoder->space_evaluation == NULL) ? 0 : 1); // %%% luz 2002-09-03: evaluation may not mess with encoder state if ( _pBufMgr->spaceEvaluation) { // spaceEval state _pBufMgr->smlCurExt = pEncoder->space_evaluation->cur_ext; _pBufMgr->smlLastExt = pEncoder->space_evaluation->last_ext; } else { // normal encoder state _pBufMgr->smlCurExt = pEncoder->cur_ext; _pBufMgr->smlLastExt = pEncoder->last_ext; } _pBufMgr->endTagSize =0; _err = getTNbyPE(pe, &tagID); _err = xltEncBlock(tagID, REQUIRED, pContent, _enc, _pBufMgr, SML_EXT_UNDEFINED); if (_err != SML_ERR_OK) { smlLibFree(_pBufMgr); return _err; } if (pEncoder->space_evaluation != NULL) { // Only calculating size pEncoder->space_evaluation->written_bytes += _pBufMgr->smlXltWrittenBytes; pEncoder->space_evaluation->end_tag_size += _pBufMgr->endTagSize; // save it only into evaluation state pEncoder->space_evaluation->cur_ext = _pBufMgr->smlCurExt; pEncoder->space_evaluation->last_ext = _pBufMgr->smlLastExt; } else { // really generating data pEncoder->end_tag_size += _pBufMgr->endTagSize; // save it into encoder state pEncoder->cur_ext = _pBufMgr->smlCurExt; pEncoder->last_ext = _pBufMgr->smlLastExt; } *ppBufPos = _pBufMgr->smlXltBufferP; smlLibFree(_pBufMgr); return SML_ERR_OK; } /** * Filnalizes the (WB)XML document and returns the size of written bytes to * the workspace module * * @pre pEncoder holds the initialized encoder structure. * the initialization takes place in the xltEncAppend function * pBufEnd must point to the end of the (WB)XML buffer * ppBufPos has to be initialized to the start point of the * (WB)XML buffer. * @post After the function call ppBufPos points to the * first free byte in the buffer behind the (WB)XML document * @param pEncoder (IN) * the encoder object * @param pBufEnd (IN) * pointer to the end of the buffer to write on * @param ppBufPos (IN/OUT) * current position of the bufferpointer * @return shows error codes of function,\n * 0, if OK\n * Possible Error Codes: * - SML_ERR_XLT_BUF_ERR * - SML_ERR_XLT_MISSING_CONT * - SML_ERR_XLT_INVAL_ELEM_TYPE * - SML_ERR_XLT_INVAL_LIST_TYPE * - SML_ERR_XLT_INVAL_TAG_TYPE * - SML_ERR_XLT_ENC_UNK * - SML_ERR_XLT_INVAL_PROTO_ELEM */ Ret_t xltEncTerminate(const XltEncoderPtr_t pEncoder, const MemPtr_t pBufEnd, MemPtr_t *ppBufPos) { // Return variable Ret_t _err; // encoding type SmlEncoding_t _enc; //Structure containing buffer pointers, length and written bytes BufferMgmtPtr_t _pBufMgr; //get the encoding type _enc = pEncoder->enc; //Initialize buffer variables if ((_pBufMgr = smlLibMalloc(sizeof(BufferMgmt_t))) == NULL) { smlLibFree(pEncoder); return SML_ERR_NOT_ENOUGH_SPACE; } _pBufMgr->vers = pEncoder->vers; // %%% luz:2003-07-31: pass SyncML version to bufmgr _pBufMgr->smlXltWrittenBytes = 0; _pBufMgr->smlXltBufferP = *ppBufPos; _pBufMgr->smlXltStoreBufP = _pBufMgr->smlXltBufferP; _pBufMgr->smlXltBufferLen = pBufEnd - *ppBufPos; _pBufMgr->smlCurExt = pEncoder->cur_ext; _pBufMgr->smlLastExt = pEncoder->last_ext; _pBufMgr->smlActiveExt = pEncoder->cur_ext; _pBufMgr->switchExtTag = TN_UNDEF; _pBufMgr->spaceEvaluation = ((pEncoder->space_evaluation == NULL) ? 0 : 1); _pBufMgr->endTagSize =0; if (pEncoder->final == 1) { // Final Flag if ((_err = xltGenerateTag(TN_FINAL, TT_ALL, _enc, _pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) { smlLibFree(_pBufMgr); xltEncReset(pEncoder); return _err; } } // SyncBody End Tag if ((_err = xltGenerateTag(TN_SYNCBODY, TT_END, _enc, _pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) { smlLibFree(_pBufMgr); xltEncReset(pEncoder); return _err; } // SyncML End Tag if ((_err = xltGenerateTag(TN_SYNCML, TT_END, _enc, _pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) { smlLibFree(_pBufMgr); xltEncReset(pEncoder); return _err; } pEncoder->cur_ext = _pBufMgr->smlCurExt; pEncoder->last_ext = _pBufMgr->smlLastExt; *ppBufPos = _pBufMgr->smlXltBufferP; smlLibFree(_pBufMgr); xltEncReset(pEncoder); return SML_ERR_OK; } Ret_t xltEncReset(XltEncoderPtr_t pEncoder) { if ((pEncoder) && (pEncoder->space_evaluation)) { smlLibFree(pEncoder->space_evaluation); pEncoder->space_evaluation = NULL; } smlLibFree(pEncoder); return SML_ERR_OK; } /** * Starts an evaluation run which prevents further API-Calls to write tags - * just the tag-sizes are calculated. Must be sopped via smlEndEvaluation * * @param pEncoder (IN) * the encoder object * @return Return Code */ SML_API Ret_t xltStartEvaluation(XltEncoderPtr_t pEncoder) { XltSpaceEvaluationPtr_t _pSpaceEvaluation; if (pEncoder->space_evaluation != NULL) return SML_ERR_WRONG_USAGE; if ((_pSpaceEvaluation = (XltSpaceEvaluationPtr_t)smlLibMalloc(sizeof(XltSpaceEvaluation_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(_pSpaceEvaluation, 0, sizeof(XltSpaceEvaluation_t)); // %%% luz 2002-09-03: init encoder state shadow copies for evaluation from real encoder _pSpaceEvaluation->cur_ext = pEncoder->cur_ext; _pSpaceEvaluation->last_ext = pEncoder->last_ext; pEncoder->space_evaluation = _pSpaceEvaluation; return SML_ERR_OK; } /** * Stops an evaluation run which prevents further API-Calls to write tags - * the remaining free buffer size after all Tags are written is returned * * @param id (IN) * instance ID * @param pEncoder (IN) * the encoder object * @param freemem (IN/OUT) * Size of free buffer for data after all tags are written * @return Return Code */ SML_API Ret_t xltEndEvaluation(InstanceID_t id, XltEncoderPtr_t pEncoder, MemSize_t *freemem) { MemSize_t _free; XltSpaceEvaluationPtr_t _evaluation; _evaluation = pEncoder->space_evaluation; if (_evaluation == NULL) return SML_ERR_WRONG_USAGE; _free = smlGetFreeBuffer(id); _free -= _evaluation->written_bytes; _free -= _evaluation->end_tag_size; _free -= pEncoder->end_tag_size; *freemem = _free; smlLibFree(_evaluation); pEncoder->space_evaluation = NULL; return SML_ERR_OK; } /** * Generates a (WB)XML Block for a given tag ID and a given content * * @pre pContent holds a valid content structure * tagId contains a valid SyncML tag ID * @post the (WB)XML buffer in the pBufMgr structure contains the * encoded (WB)XML block * @param tagId (IN) * the ID for the tag to generate (TN_ADD, ...) * @param reqOptFlag (IN) * flag if the block is required or optional * @param pContent (IN) * the content structure of the block * @param enc (IN) * the encoding constant (SML_WBXML or SML_XML) * @param attFlag (IN) * indicates if the encoded tag contain Attributes * in namespace extensions * @param pBufMgr (IN/OUT) * pointer to a structure containing buffer management elements * @return shows error codes of function,\n * 0, if OK */ Ret_t xltEncBlock(XltTagID_t tagId, XltRO_t reqOptFlag, const VoidPtr_t pContent, SmlEncoding_t enc, BufferMgmtPtr_t pBufMgr, SmlPcdataExtension_t attFlag) { //Return variable Ret_t _err; //Check if pContent of a required field is missing if ((reqOptFlag == REQUIRED) && (pContent == NULL)) { switch ((int)tagId) { case TN_ATOMIC_END: case TN_SYNC_END: case TN_SEQUENCE_END: break; default: return SML_ERR_XLT_MISSING_CONT; } } //Check if pContent of a optional field is missing else if ((pContent == NULL) && (tagId != TN_SYNC_END) && (tagId != TN_ATOMIC_END) && (tagId != TN_SEQUENCE_END)) return SML_ERR_OK; //Generate the commands -> see DTD switch ((int)tagId){ case TN_SYNCHDR: // SyncHdr Begin Tag if ((_err = xltGenerateTag(TN_SYNCHDR, TT_BEG, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Version if ((_err = xltEncBlock(TN_VERSION, REQUIRED, ((SmlSyncHdrPtr_t) pContent)->version, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Proto if ((_err = xltEncBlock(TN_PROTO, REQUIRED, ((SmlSyncHdrPtr_t) pContent)->proto, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // SessionID if ((_err = xltEncBlock(TN_SESSIONID, REQUIRED, ((SmlSyncHdrPtr_t) pContent)->sessionID, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // MsgID if ((_err = xltEncBlock(TN_MSGID, REQUIRED, ((SmlSyncHdrPtr_t) pContent)->msgID, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Target if ((_err = xltEncBlock(TN_TARGET, REQUIRED, ((SmlSyncHdrPtr_t) pContent)->target, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Source if ((_err = xltEncBlock(TN_SOURCE, REQUIRED, ((SmlSyncHdrPtr_t) pContent)->source, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // RespURI? if ((_err = xltEncBlock(TN_RESPURI, OPTIONAL, ((SmlSyncHdrPtr_t) pContent)->respURI, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // NoResp? if ((_err = xltEncBlock(TN_NORESP, OPTIONAL, &((SmlSyncHdrPtr_t) pContent)->flags, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Cred? if ((_err = xltEncBlock(TN_CRED, OPTIONAL, ((SmlSyncHdrPtr_t) pContent)->cred, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Meta? if ((_err = xltEncBlock(TN_META, OPTIONAL, ((SmlSyncHdrPtr_t) pContent)->meta, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // SyncHdr End Tag if ((_err = xltGenerateTag(TN_SYNCHDR, TT_END, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; break; case TN_CRED: // Begin tag if ((_err = xltGenerateTag(TN_CRED, TT_BEG, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Meta? if ((_err = xltEncBlock(TN_META, OPTIONAL, ((SmlCredPtr_t) pContent)->meta, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Data if ((_err = xltEncBlock(TN_DATA, REQUIRED, ((SmlCredPtr_t) pContent)->data, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // End tag if ((_err = xltGenerateTag(TN_CRED, TT_END, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; break; case TN_SOURCEPARENT: case TN_TARGETPARENT: // Begin tag if ((_err = xltGenerateTag(tagId, TT_BEG, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // LocURI if ((_err = xltEncBlock(TN_LOCURI, REQUIRED, ((SmlSourceParentPtr_t) pContent)->locURI, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // End tag if ((_err = xltGenerateTag(tagId, TT_END, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; break; case TN_SOURCE: case TN_TARGET: // Begin tag if ((_err = xltGenerateTag(tagId, TT_BEG, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // LocURI if ((_err = xltEncBlock(TN_LOCURI, REQUIRED, ((SmlSourcePtr_t) pContent)->locURI, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // LocName? if ((_err = xltEncBlock(TN_LOCNAME, OPTIONAL, ((SmlSourcePtr_t) pContent)->locName, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Filter? if ((_err = xltEncBlock(TN_FILTER, OPTIONAL, ((SmlSourcePtr_t) pContent)->filter, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // End tag if ((_err = xltGenerateTag(tagId, TT_END, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; break; case TN_ITEM: // Begin tag if ((_err = xltGenerateTag(TN_ITEM, TT_BEG, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Target? if ((_err = xltEncBlock(TN_TARGET, OPTIONAL, ((SmlItemPtr_t) pContent)->target, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Source? if ((_err = xltEncBlock(TN_SOURCE, OPTIONAL, ((SmlItemPtr_t) pContent)->source, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // TargetParent? if ((_err = xltEncBlock(TN_TARGETPARENT, OPTIONAL, ((SmlItemPtr_t) pContent)->targetParent, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // SourceParent? if ((_err = xltEncBlock(TN_SOURCEPARENT, OPTIONAL, ((SmlItemPtr_t) pContent)->sourceParent, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Meta? if ((_err = xltEncBlock(TN_META, OPTIONAL, ((SmlItemPtr_t) pContent)->meta, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Data? if ((_err = xltEncBlock(TN_DATA, OPTIONAL, ((SmlItemPtr_t) pContent)->data, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // MoreData? if ((_err = xltEncBlock(TN_MOREDATA, OPTIONAL, &(((SmlItemPtr_t) pContent)->flags), enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // End tag if ((_err = xltGenerateTag(TN_ITEM, TT_END, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; break; /* %%% Added Filter tags 2005-08-17 by synthesis/luz for DS 1.2 */ case TN_FIELD: case TN_RECORD: // Begin tag if ((_err = xltGenerateTag(tagId, TT_BEG, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Item if ((_err = xltEncBlock(TN_ITEM, REQUIRED, ((SmlRecordOrFieldFilterPtr_t) pContent)->item, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // End tag if ((_err = xltGenerateTag(tagId, TT_END, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; break; case TN_FILTER: // Begin tag if ((_err = xltGenerateTag(tagId, TT_BEG, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Meta if ((_err = xltEncBlock(TN_META, REQUIRED, ((SmlFilterPtr_t) pContent)->meta, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Field? if ((_err = xltEncBlock(TN_FIELD, OPTIONAL, ((SmlFilterPtr_t) pContent)->field, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Record? if ((_err = xltEncBlock(TN_RECORD, OPTIONAL, ((SmlFilterPtr_t) pContent)->record, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // FilterType? if ((_err = xltEncBlock(TN_FILTERTYPE, OPTIONAL, ((SmlFilterPtr_t) pContent)->filtertype, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // End tag if ((_err = xltGenerateTag(tagId, TT_END, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; break; case TN_REPLACE: case TN_ADD: case TN_COPY: case TN_MOVE: // Begin tag if ((_err = xltGenerateTag(tagId, TT_BEG, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // CmdID if ((_err = xltEncBlock(TN_CMDID, REQUIRED, ((SmlGenericCmdPtr_t) pContent)->cmdID, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // NoResp? if ((_err = xltEncBlock(TN_NORESP, OPTIONAL, &((SmlGenericCmdPtr_t) pContent)->flags, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Cred? if ((_err = xltEncBlock(TN_CRED, OPTIONAL, ((SmlGenericCmdPtr_t) pContent)->cred, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Meta? if ((_err = xltEncBlock(TN_META, OPTIONAL, ((SmlGenericCmdPtr_t) pContent)->meta, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Item+ if ((_err = xltEncList(ITEM_LIST, REQUIRED, ((SmlGenericCmdPtr_t) pContent)->itemList, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // End tag if ((_err = xltGenerateTag(tagId, TT_END, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; break; case TN_ALERT: // Begin tag if ((_err = xltGenerateTag(TN_ALERT, TT_BEG, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // CmdID if ((_err = xltEncBlock(TN_CMDID, REQUIRED, ((SmlAlertPtr_t) pContent)->cmdID, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // NoResp? if ((_err = xltEncBlock(TN_NORESP, OPTIONAL, &((SmlAlertPtr_t) pContent)->flags, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Cred? if ((_err = xltEncBlock(TN_CRED, OPTIONAL, ((SmlAlertPtr_t) pContent)->cred, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Data? if ((_err = xltEncBlock(TN_DATA, OPTIONAL, ((SmlAlertPtr_t) pContent)->data, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Item* if ((_err = xltEncList(ITEM_LIST, OPTIONAL, ((SmlAlertPtr_t) pContent)->itemList, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // End tag if ((_err = xltGenerateTag(TN_ALERT, TT_END, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; break; #if (defined ATOMIC_SEND || defined SEQUENCE_SEND) case TN_ATOMIC: case TN_SEQUENCE: // Begin tag if ((_err = xltGenerateTag(tagId, TT_BEG, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // CmdID if ((_err = xltEncBlock(TN_CMDID, REQUIRED, ((SmlAtomicPtr_t) pContent)->cmdID, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // NoResp? if ((_err = xltEncBlock(TN_NORESP, OPTIONAL, &((SmlAtomicPtr_t) pContent)->flags, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Meta? if ((_err = xltEncBlock(TN_META, OPTIONAL, ((SmlAtomicPtr_t) pContent)->meta, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; //End tag in TN_ATOMIC_END break; case TN_ATOMIC_END: // End tag if ((_err = xltGenerateTag(TN_ATOMIC, TT_END, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; break; case TN_SEQUENCE_END: // End tag if ((_err = xltGenerateTag(TN_SEQUENCE, TT_END, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; break; #endif case TN_DELETE: // Begin tag if ((_err = xltGenerateTag(TN_DELETE, TT_BEG, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // CmdID if ((_err = xltEncBlock(TN_CMDID, REQUIRED, ((SmlDeletePtr_t) pContent)->cmdID, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // NoResp? if ((_err = xltEncBlock(TN_NORESP, OPTIONAL, &((SmlDeletePtr_t) pContent)->flags, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Archive? if ((_err = xltEncBlock(TN_ARCHIVE, OPTIONAL, &(((SmlDeletePtr_t) pContent)->flags), enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // SftDel? if ((_err = xltEncBlock(TN_SFTDEL, OPTIONAL, &(((SmlDeletePtr_t) pContent)->flags), enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Cred? if ((_err = xltEncBlock(TN_CRED, OPTIONAL, ((SmlDeletePtr_t) pContent)->cred, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Meta? if ((_err = xltEncBlock(TN_META, OPTIONAL, ((SmlDeletePtr_t) pContent)->meta, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Item+ if ((_err = xltEncList(ITEM_LIST, REQUIRED, ((SmlDeletePtr_t) pContent)->itemList, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // End tag if ((_err = xltGenerateTag(TN_DELETE, TT_END, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; break; #ifdef EXEC_SEND case TN_EXEC: // Begin tag if ((_err = xltGenerateTag(TN_EXEC, TT_BEG, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // CmdID if ((_err = xltEncBlock(TN_CMDID, REQUIRED, ((SmlExecPtr_t) pContent)->cmdID, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // NoResp? if ((_err = xltEncBlock(TN_NORESP, OPTIONAL, &((SmlExecPtr_t) pContent)->flags, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Cred? if ((_err = xltEncBlock(TN_CRED, OPTIONAL, ((SmlExecPtr_t) pContent)->cred, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Meta? if ((_err = xltEncBlock(TN_META, OPTIONAL, ((SmlExecPtr_t) pContent)->meta, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Item if ((_err = xltEncBlock(TN_ITEM, REQUIRED, ((SmlExecPtr_t) pContent)->item, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // End tag if ((_err = xltGenerateTag(TN_EXEC, TT_END, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; break; #endif case TN_GET: case TN_PUT: // Begin tag if ((_err = xltGenerateTag(tagId, TT_BEG, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // CmdID if ((_err = xltEncBlock(TN_CMDID, REQUIRED, ((SmlGetPtr_t) pContent)->cmdID, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // NoResp? if ((_err = xltEncBlock(TN_NORESP, OPTIONAL, &((SmlGetPtr_t) pContent)->flags, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Lang? if ((_err = xltEncBlock(TN_LANG, OPTIONAL, ((SmlGetPtr_t) pContent)->lang, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Cred? if ((_err = xltEncBlock(TN_CRED, OPTIONAL, ((SmlGetPtr_t) pContent)->cred, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Meta? if ((_err = xltEncBlock(TN_META, OPTIONAL, ((SmlGetPtr_t) pContent)->meta, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Item+ if ((_err = xltEncList(ITEM_LIST, REQUIRED, ((SmlGetPtr_t) pContent)->itemList, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // End tag if ((_err = xltGenerateTag(tagId, TT_END, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; break; case TN_MAP: // Begin tag if ((_err = xltGenerateTag(TN_MAP, TT_BEG, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // CmdID if ((_err = xltEncBlock(TN_CMDID, REQUIRED, ((SmlMapPtr_t) pContent)->cmdID, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Target if ((_err = xltEncBlock(TN_TARGET, REQUIRED, ((SmlMapPtr_t) pContent)->target, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Source if ((_err = xltEncBlock(TN_SOURCE, REQUIRED, ((SmlMapPtr_t) pContent)->source, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Cred? if ((_err = xltEncBlock(TN_CRED, OPTIONAL, ((SmlMapPtr_t) pContent)->cred, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Meta? if ((_err = xltEncBlock(TN_META, OPTIONAL, ((SmlMapPtr_t) pContent)->meta, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Mapitemlist if ((_err = xltEncList(MAPITEM_LIST, REQUIRED, ((SmlMapPtr_t) pContent)->mapItemList, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // End tag if ((_err = xltGenerateTag(TN_MAP, TT_END, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; break; case TN_MAPITEM: // Begin tag if ((_err = xltGenerateTag(TN_MAPITEM, TT_BEG, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Target if ((_err = xltEncBlock(TN_TARGET, REQUIRED, ((SmlMapItemPtr_t) pContent)->target, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Source if ((_err = xltEncBlock(TN_SOURCE, REQUIRED, ((SmlMapItemPtr_t) pContent)->source, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // End tag if ((_err = xltGenerateTag(TN_MAPITEM, TT_END, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; break; case TN_RESULTS: // Begin tag if ((_err = xltGenerateTag(TN_RESULTS, TT_BEG, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // CmdID if ((_err = xltEncBlock(TN_CMDID, REQUIRED, ((SmlResultsPtr_t) pContent)->cmdID, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // MsgRef? if ((_err = xltEncBlock(TN_MSGREF, OPTIONAL, ((SmlResultsPtr_t) pContent)->msgRef, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // CmdRef if ((_err = xltEncBlock(TN_CMDREF, REQUIRED, ((SmlResultsPtr_t) pContent)->cmdRef, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Meta? if ((_err = xltEncBlock(TN_META, OPTIONAL, ((SmlResultsPtr_t) pContent)->meta, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // TargetRef? if ((_err = xltEncBlock(TN_TARGETREF, OPTIONAL, ((SmlResultsPtr_t) pContent)->targetRef, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // SourceRef? if ((_err = xltEncBlock(TN_SOURCEREF, OPTIONAL, ((SmlResultsPtr_t) pContent)->sourceRef, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Item+ if ((_err = xltEncList(ITEM_LIST, REQUIRED, ((SmlResultsPtr_t) pContent)->itemList, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // End tag if ((_err = xltGenerateTag(TN_RESULTS, TT_END, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; break; case TN_CHAL: // Begin tag if ((_err = xltGenerateTag(TN_CHAL, TT_BEG, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Meta if ((_err = xltEncBlock(TN_META, REQUIRED, ((SmlChalPtr_t) pContent)->meta, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // End tag if ((_err = xltGenerateTag(TN_CHAL, TT_END, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; break; #ifdef SEARCH_SEND case TN_SEARCH: // Begin tag if ((_err = xltGenerateTag(TN_SEARCH, TT_BEG, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // CmdID if ((_err = xltEncBlock(TN_CMDID, REQUIRED, ((SmlSearchPtr_t) pContent)->cmdID, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // NoResp? if ((_err = xltEncBlock(TN_NORESP, OPTIONAL, &((SmlSearchPtr_t) pContent)->flags, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // NoResults? if ((_err = xltEncBlock(TN_NORESULTS, OPTIONAL, &((SmlSearchPtr_t) pContent)->flags, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Cred? if ((_err = xltEncBlock(TN_CRED, OPTIONAL, ((SmlSearchPtr_t) pContent)->cred, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Target? if ((_err = xltEncBlock(TN_TARGET, OPTIONAL, ((SmlSearchPtr_t) pContent)->target, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Source List if ((_err = xltEncList(SOURCE_LIST, REQUIRED, ((SmlSearchPtr_t) pContent)->sourceList, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Lang? if ((_err = xltEncBlock(TN_LANG, OPTIONAL, ((SmlSearchPtr_t) pContent)->lang, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Meta if ((_err = xltEncBlock(TN_META, REQUIRED, ((SmlSearchPtr_t) pContent)->meta, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Dsta if ((_err = xltEncBlock(TN_DATA, REQUIRED, ((SmlSearchPtr_t) pContent)->data, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // End tag if ((_err = xltGenerateTag(TN_SEARCH, TT_END, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; break; #endif case TN_STATUS: // Begin tag if ((_err = xltGenerateTag(TN_STATUS, TT_BEG, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // CmdID if ((_err = xltEncBlock(TN_CMDID, REQUIRED, ((SmlStatusPtr_t) pContent)->cmdID, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // MsgRef? if ((_err = xltEncBlock(TN_MSGREF, REQUIRED, ((SmlStatusPtr_t) pContent)->msgRef, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // CmdRef if ((_err = xltEncBlock(TN_CMDREF, REQUIRED, ((SmlStatusPtr_t) pContent)->cmdRef, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Cmd if ((_err = xltEncBlock(TN_CMD, REQUIRED, ((SmlStatusPtr_t) pContent)->cmd, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // TargetRefList? if ((_err = xltEncList(TARGETREF_LIST, OPTIONAL, ((SmlStatusPtr_t) pContent)->targetRefList, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // SourceRefList? if ((_err = xltEncList(SOURCEREF_LIST, OPTIONAL, ((SmlStatusPtr_t) pContent)->sourceRefList, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Cred? if ((_err = xltEncBlock(TN_CRED, OPTIONAL, ((SmlStatusPtr_t) pContent)->cred, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Chal? if ((_err = xltEncBlock(TN_CHAL, OPTIONAL, ((SmlStatusPtr_t) pContent)->chal, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Data if ((_err = xltEncBlock(TN_DATA, REQUIRED, ((SmlStatusPtr_t) pContent)->data, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Item* if ((_err = xltEncList(ITEM_LIST, OPTIONAL, ((SmlStatusPtr_t) pContent)->itemList, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // End tag if ((_err = xltGenerateTag(TN_STATUS, TT_END, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; break; case TN_SYNC: // Begin tag if ((_err = xltGenerateTag(TN_SYNC, TT_BEG, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // CmdID if ((_err = xltEncBlock(TN_CMDID, REQUIRED, ((SmlSyncPtr_t) pContent)->cmdID, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // NoResp? if ((_err = xltEncBlock(TN_NORESP, OPTIONAL, &((SmlSyncPtr_t) pContent)->flags, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Cred? if ((_err = xltEncBlock(TN_CRED, OPTIONAL, ((SmlSyncPtr_t) pContent)->cred, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Target? if ((_err = xltEncBlock(TN_TARGET, OPTIONAL, ((SmlSyncPtr_t) pContent)->target, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Source? if ((_err = xltEncBlock(TN_SOURCE, OPTIONAL, ((SmlSyncPtr_t) pContent)->source, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // Meta? if ((_err = xltEncBlock(TN_META, OPTIONAL, ((SmlSyncPtr_t) pContent)->meta, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // NumberOfChanges? if ((_err = xltEncBlock(TN_NUMBEROFCHANGES, OPTIONAL, ((SmlSyncPtr_t) pContent)->noc, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; // End tag in TN_SYNC_END break; case TN_SYNC_END: //End tag if ((_err = xltGenerateTag(TN_SYNC, TT_END, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; break; case TN_ARCHIVE: //set the flag in the (WB)XML document if the flag is in the pContent if ((*((Flag_t*)pContent)) & (SmlArchive_f)) { if ((_err = xltGenerateTag(tagId, TT_ALL, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; } break; case TN_SFTDEL: //set the flag in the (WB)XML document if the flag is in the pContent if ((*((Flag_t *) pContent)) & (SmlSftDel_f)) { if ((_err = xltGenerateTag(tagId, TT_ALL, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; } break; case TN_MOREDATA: //set the flag in the (WB)XML document if the flag is in the pContent if ((*((Flag_t *) pContent)) & (SmlMoreData_f)) { if ((_err = xltGenerateTag(tagId, TT_ALL, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; } break; case TN_NORESULTS: //set the flag in the (WB)XML document if the flag is in the pContent if ((*((Flag_t *) pContent)) & (SmlNoResults_f)) { if ((_err = xltGenerateTag(tagId, TT_ALL, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; } break; case TN_NORESP: //set the flag in the (WB)XML document if the flag is in the pContent if ((*((Flag_t *) pContent)) & (SmlNoResp_f)){ if ((_err = xltGenerateTag(tagId, TT_ALL, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; } break; case TN_FINAL: //set the flag in the (WB)XML document if the flag is in the pContent if ((*((Flag_t *) pContent)) & (SmlFinal_f)) { if ((_err = xltGenerateTag(tagId, TT_ALL, enc, pBufMgr, SML_EXT_UNDEFINED)) != SML_ERR_OK) return _err; } break; default: // all leaf nodes (PCDATA#) return xltEncPcdata(tagId, reqOptFlag, pContent, enc, pBufMgr, attFlag); } return SML_ERR_OK; } Ret_t xltEncPcdata(XltTagID_t tagId, XltRO_t reqOptFlag, const VoidPtr_t pContent, SmlEncoding_t enc, BufferMgmtPtr_t pBufMgr, SmlPcdataExtension_t attFlag) { //Return variable Ret_t _err; //generate PCDATA begin tag if ((_err = xltGenerateTag(tagId, TT_BEG, enc, pBufMgr, attFlag)) != SML_ERR_OK) return _err; //write the pContent to the buffer according the encoding type switch ((int)enc) { #ifdef __SML_WBXML__ case SML_WBXML: { switch (((SmlPcdataPtr_t)pContent)->contentType) { case SML_PCDATA_STRING: if ((_err = wbxmlWriteTypeToBuffer(((SmlPcdataPtr_t)pContent)->content, STR_I, ((SmlPcdataPtr_t)pContent)->length, pBufMgr)) != SML_ERR_OK) return _err; break; // Note: SML_PCDATA_CDATA case added by luz to allow direct translation from XML to WBXML case SML_PCDATA_CDATA: case SML_PCDATA_OPAQUE: if ((_err = wbxmlWriteTypeToBuffer(((SmlPcdataPtr_t)pContent)->content, OPAQUE, ((SmlPcdataPtr_t)pContent)->length, pBufMgr)) != SML_ERR_OK) return _err; break; #ifdef __USE_EXTENSIONS__ case SML_PCDATA_EXTENSION: if ((_err = xltBuildExtention(((SmlPcdataPtr_t)pContent)->extension, reqOptFlag, ((SmlPcdataPtr_t)pContent)->content, enc, pBufMgr)) != SML_ERR_OK) return _err; break; #endif default: // 2003-11-24: Tomy to deal with pcdata empty extensions (for example which is valid) // refer to xltdec.c to see that empty extensions result in SmlPcdataPtr_t with all fields (data) set to 0 if (((SmlPcdataPtr_t)pContent)->contentType != SML_PCDATA_UNDEFINED || ((SmlPcdataPtr_t)pContent)->extension != SML_EXT_UNDEFINED || ((SmlPcdataPtr_t)pContent)->length != 0 || ((SmlPcdataPtr_t)pContent)->content != NULL) return SML_ERR_XLT_INVAL_PCDATA_TYPE; // return SML_ERR_XLT_INVAL_PCDATA_TYPE; // end modified by Tomy }; // eof switch(contenttype) break; } // case WBXML #endif // eof WBXML #ifdef __SML_XML__ case SML_XML: { MemPtr_t _tmpStr; MemPtr_t p; MemSize_t len,n; char c; switch (((SmlPcdataPtr_t)pContent)->contentType) { // Note: SML_PCDATA_OPAQUE case added by luz to allow direct translation from WBXML to XML #ifdef PCDATA_OPAQUE_AS_CDATA case SML_PCDATA_OPAQUE: #endif case SML_PCDATA_CDATA: stringAsCData: { // %%% luz 2006-09-07 : made completely CDATA nesting safe // add CDATA _tmpStr = (MemPtr_t) " sequences p=((SmlPcdataPtr_t)pContent)->content; len=((SmlPcdataPtr_t)pContent)->length; n=0; while (n') { // we must substitute "]]>" with "]]>]" // - copy what we have so far (includes ]]>) n+=3; if ((_err = xltAddToBuffer(p, n, pBufMgr)) != SML_ERR_OK) return _err; // - add extra code needed _tmpStr = (MemPtr_t) "]"; if ((_err = xltAddToBuffer(_tmpStr, smlLibStrlen((String_t)_tmpStr), pBufMgr)) != SML_ERR_OK) return _err; // - restart where we are now p+=n; // first char after ]]> len-=n; // remaining length n=0; // processed chars } else { n++; // just go to next char } } // add remaining data if ((_err = xltAddToBuffer(p, len, pBufMgr)) != SML_ERR_OK) return _err; // add end of CDATA marker _tmpStr = (MemPtr_t) "]]>"; if ((_err = xltAddToBuffer(_tmpStr, smlLibStrlen((String_t)_tmpStr), pBufMgr)) != SML_ERR_OK) return _err; break; } // Note: SyncFest #5 shows that content; len=((SmlPcdataPtr_t)pContent)->length; while (len-->0) { c=*p++; if (c=='&' || c=='<' || c=='>') goto stringAsCData; // encode as CDATA } // ok, string is clean and does not need CDATA if ((_err = xltAddToBuffer(((SmlPcdataPtr_t)pContent)->content, ((SmlPcdataPtr_t)pContent)->length, pBufMgr)) != SML_ERR_OK) return _err; break; } #ifdef __USE_EXTENSIONS__ case SML_PCDATA_EXTENSION: { if ((_err = xltBuildExtention(((SmlPcdataPtr_t)pContent)->extension, reqOptFlag, ((SmlPcdataPtr_t)pContent)->content, enc, pBufMgr)) != SML_ERR_OK) return _err; break; } #endif default: { // 2003-11-24: Tomy to deal with pcdata empty extensions (for example which is valid) // refer to xltdec.c to see that empty extensions result in SmlPcdataPtr_t with all fields (data) set to 0 if (((SmlPcdataPtr_t)pContent)->contentType != SML_PCDATA_UNDEFINED || ((SmlPcdataPtr_t)pContent)->extension != SML_EXT_UNDEFINED || ((SmlPcdataPtr_t)pContent)->length != 0 || ((SmlPcdataPtr_t)pContent)->content != NULL) return SML_ERR_XLT_INVAL_PCDATA_TYPE; // return SML_ERR_XLT_INVAL_PCDATA_TYPE; // end modified by Tomy } } // switch tags break; } // case XML #endif // eof XML default: return SML_ERR_XLT_ENC_UNK; } // eof switch(enc) //generate PCDATA END tag if ((_err = xltGenerateTag(tagId, TT_END, enc, pBufMgr, attFlag)) != SML_ERR_OK) return _err; return SML_ERR_OK; } /** * Generates a list element which is not directly related to a tag * * @pre pList holds a valid list structure * listId contains a valid SyncML list ID * @post the (WB)XML buffer in the pBufMgr structure contains the * encoded (WB)XML list * @param listId (IN) * the ID of the list to generate (e.g. TARGET_LIST, ...) * @param reqOptFlag (IN) * flag if the block is required or optional * @param pList (IN) * reference to the list to process * @param enc (IN) * the encoding constant (SML_WBXML or SML_XML) * @param pBufMgr (IN/OUT) * pointer to a structure containing buffer management elements * @param attFlag (IN) * indicates if the encoded tag contain Attributes * in namespace extensions * @return shows error codes of function,\n * 0, if OK */ Ret_t xltEncList(XltListType_t listId, XltRO_t reqOptFlag, VoidPtr_t pList, SmlEncoding_t enc, BufferMgmtPtr_t pBufMgr, SmlPcdataExtension_t attFlag) { //Return variable Ret_t _err; //check if list is required or not if ((reqOptFlag == REQUIRED) && (pList == NULL)) return SML_ERR_XLT_MISSING_CONT; else if (pList == NULL) return SML_ERR_OK; //encode the different list types switch ((int)listId) { case ITEM_LIST: { do { if ((_err = xltEncBlock(TN_ITEM, OPTIONAL, ((SmlItemListPtr_t)pList)->item, enc, pBufMgr, attFlag)) != SML_ERR_OK) return _err; pList = ((SmlItemListPtr_t)pList)->next; } while ((SmlItemListPtr_t)pList != NULL); break; } case SOURCE_LIST: { do { if ((_err = xltEncBlock(TN_SOURCE, OPTIONAL, ((SmlSourceListPtr_t)pList)->source, enc, pBufMgr, attFlag)) != SML_ERR_OK) return _err; pList = ((SmlSourceListPtr_t)pList)->next; } while ((SmlSourceListPtr_t)pList != NULL); break; } case TARGETREF_LIST: { do { if ((_err = xltEncBlock(TN_TARGETREF, OPTIONAL, ((SmlTargetRefListPtr_t)pList)->targetRef, enc, pBufMgr, attFlag)) != SML_ERR_OK) return _err; pList = ((SmlTargetRefListPtr_t)pList)->next; } while ((SmlTargetRefListPtr_t)pList != NULL); break; } case SOURCEREF_LIST: { do { if ((_err = xltEncBlock(TN_SOURCEREF, OPTIONAL, ((SmlSourceRefListPtr_t)pList)->sourceRef, enc, pBufMgr, attFlag)) != SML_ERR_OK) return _err; pList = ((SmlSourceRefListPtr_t)pList)->next; } while ((SmlSourceRefListPtr_t)pList != NULL); break; } case MAPITEM_LIST: { do { if ((_err = xltEncBlock(TN_MAPITEM, OPTIONAL, ((SmlMapItemListPtr_t)pList)->mapItem, enc, pBufMgr, attFlag)) != SML_ERR_OK) return _err; pList = ((SmlMapItemListPtr_t)pList)->next; } while ((SmlMapItemListPtr_t)pList != NULL); break; } default: return SML_ERR_XLT_INVAL_LIST_TYPE; } return SML_ERR_OK; } /** * Generates a (WB)XML tag * * @pre valid parameters * @post the buffer contains a new tag * @param tagId (IN) * the tag ID * @param TagType (IN) * the tag type (begin tag, end tag, ...) * @param enc (IN) * the encoding constant (SML_WBXML or SML_XML) * @param attFlag (IN) * indicates if the encoded tag contain Attributes * in namespace extensions * @param pBufMgr (IN/OUT) * pointer to a structure containing buffer management elements * @return shows error codes of function,\n * 0, if OK */ Ret_t xltGenerateTag(XltTagID_t tagId, XltTagType_t TagType, SmlEncoding_t enc, BufferMgmtPtr_t pBufMgr, SmlPcdataExtension_t attFlag) { Ret_t _err; #ifdef __SML_WBXML__ MemByte_t _switchpage = XLT_SWITCHPAGE; #endif switch ((int)enc) { #ifdef __SML_WBXML__ case SML_WBXML: /* in WBXML codepage switches are done for starting tags only */ if (TagType != TT_END) { //codepage switching with wbxml instead of namespace if (getCodePage(attFlag) != getCodePage(pBufMgr->smlCurExt)) { MemByte_t _newcp = getCodePage(attFlag); if ((_err = wbxmlWriteTypeToBuffer((MemPtr_t)(&_switchpage), TAG, 1, pBufMgr)) != SML_ERR_OK) return _err; if ((_err = wbxmlWriteTypeToBuffer((MemPtr_t)(&_newcp), TAG, 1, pBufMgr)) != SML_ERR_OK) return _err; } if (attFlag != pBufMgr->smlCurExt) { pBufMgr->switchExtTag = tagId; pBufMgr->smlLastExt = pBufMgr->smlCurExt; pBufMgr->smlCurExt = attFlag; } } // for TagType return wbxmlGenerateTag(tagId, TagType, pBufMgr); #endif #ifdef __SML_XML__ case SML_XML: if (attFlag != pBufMgr->smlCurExt) { pBufMgr->switchExtTag = tagId; pBufMgr->smlLastExt = pBufMgr->smlCurExt; pBufMgr->smlCurExt = attFlag; } return xmlGenerateTag(tagId, TagType, pBufMgr, attFlag); #endif default: return SML_ERR_XLT_ENC_UNK; } //return SML_ERR_XLT_ENC_UNK;NOT NEEDED } #ifdef __USE_EXTENSIONS__ /* Entrypoint for SubDTD's. If we reached this point we already know * a) we have data fora sub-DTD to encode and * b) we know which sub-DTD should be encoded. * So just call the appropriate sub-DTD encoder and thats it. */ Ret_t xltBuildExtention(SmlPcdataExtension_t extId, XltRO_t reqOptFlag, VoidPtr_t pContent, SmlEncoding_t enc, BufferMgmtPtr_t pBufMgr) { switch (extId) { #ifdef __USE_METINF__ case SML_EXT_METINF: /* a metaInf DTD always starts with this token */ return metinfEncBlock(TN_METINF_METINF,reqOptFlag,pContent,enc,pBufMgr,SML_EXT_METINF); break; #endif #ifdef __USE_DEVINF__ case SML_EXT_DEVINF: /* a deviceInf DTD always starts with this token */ /* we have to choose, wether we have to encode the DevInf as XML or WBXML */ /* in the latter case, we need a special treatment of this sub-dtd, as we have */ /* to put it into a SML_PCDATA_OPAQUE field ... */ if (enc == SML_XML) return devinfEncBlock(TN_DEVINF_DEVINF,reqOptFlag,pContent,enc,pBufMgr,SML_EXT_DEVINF); else return subdtdEncWBXML(TN_DEVINF_DEVINF,reqOptFlag,pContent,SML_WBXML,pBufMgr,SML_EXT_DEVINF); break; #endif /* oops - we don not know about that extension -> bail out */ default: return SML_ERR_XLT_INVAL_EXT; } //return SML_ERR_OK;CAN NOT BE REACHED } /* Sub DTD's need a special treatment when used together with WBXML. * We need to eoncode them as a complete WBXML message including headers and stuff * and store the result within an SML_PCDATA_OPAQUE datafield. * To archieve this we create a new encoder, encode the message and finally * copy the result into the allready existing encoder. */ #ifdef __SML_WBXML__ Ret_t subdtdEncWBXML(XltTagID_t tagId, XltRO_t reqOptFlag, const VoidPtr_t pContent, SmlEncoding_t enc, BufferMgmtPtr_t pBufMgr, SmlPcdataExtension_t attFlag) { #ifdef __USE_DEVINF__ Ret_t _err = SML_ERR_OK; #endif /* Double the size of SubBufSize for the memory is small for some complex * content. */ MemSize_t SubBufSize = 12000 * 2; // for starters we use 12kB for each sub DTD to encode in WBXML BufferMgmtPtr_t pSubBufMgr = NULL; /* Even the doubled size was still too small. Instead of hard-coding the size, make it as large as the buffer we are copying into. The size of that one can be configured by the user of the toolkit. -- Patrick Ohly */ MemSize_t VarSubBufSize = pBufMgr->smlXltBufferLen - pBufMgr->smlXltWrittenBytes; if (VarSubBufSize > SubBufSize) { SubBufSize = VarSubBufSize; } // first create a sub buffer pSubBufMgr = (BufferMgmtPtr_t)smlLibMalloc(sizeof(BufferMgmt_t)); if (pSubBufMgr == NULL) { if (enc && pContent && reqOptFlag && tagId) { } return SML_ERR_NOT_ENOUGH_SPACE; } smlLibMemset(pSubBufMgr, 0,sizeof(BufferMgmt_t)); pSubBufMgr->smlXltBufferLen = SubBufSize; pSubBufMgr->smlXltBufferP = (MemPtr_t)smlLibMalloc(SubBufSize); if (pSubBufMgr->smlXltBufferP == NULL) { smlLibFree(pSubBufMgr); return SML_ERR_NOT_ENOUGH_SPACE; } smlLibMemset(pSubBufMgr->smlXltBufferP, 0, SubBufSize); pSubBufMgr->smlXltStoreBufP = pSubBufMgr->smlXltBufferP; pSubBufMgr->smlXltWrittenBytes = 0; pSubBufMgr->smlActiveExt = pBufMgr->smlActiveExt; pSubBufMgr->smlCurExt = pBufMgr->smlCurExt; pSubBufMgr->smlLastExt = pBufMgr->smlLastExt; pSubBufMgr->spaceEvaluation = pBufMgr->spaceEvaluation; pSubBufMgr->vers = pBufMgr->vers; // check if we want to use numeric or textual FPI if (SyncMLDevInfWBXMLPublicID[pBufMgr->vers]==0) { // textual FPI // - get the FPI string const char *FPIstring = SyncMLDevInfFPI[pBufMgr->vers]; Short_t FPIsize = smlLibStrlen(FPIstring); if (pSubBufMgr->spaceEvaluation == 0) { // - create the WBXML header pSubBufMgr->smlXltBufferP[0] = 0x02; // WBXML Version 1.2 pSubBufMgr->smlXltBufferP[1] = 0x00; // use Stringtable for ID pSubBufMgr->smlXltBufferP[2] = 0x00; // empty/unknown public ID pSubBufMgr->smlXltBufferP[3] = 0x6A; // charset encoding UTF-8 pSubBufMgr->smlXltBufferP[4] = FPIsize; // %%% not fixed=0x1D!! lenght of stringtable = length of FPIsize pSubBufMgr->smlXltBufferP += 5; // - Generate textual FPI smlLibMemmove(pSubBufMgr->smlXltBufferP, FPIstring, FPIsize); pSubBufMgr->smlXltBufferP += FPIsize; } // in case of space evaluation, just count the number of written bytes pSubBufMgr->smlXltWrittenBytes = 5 + FPIsize; } else { // numeric FPI, no string table if (pSubBufMgr->spaceEvaluation == 0) { // - create the WBXML header unsigned short fpi=SyncMLDevInfWBXMLPublicID[pBufMgr->vers]; pSubBufMgr->smlXltBufferP[0] = 0x02; // WBXML Version 1.2 pSubBufMgr->smlXltBufferP[1] = ((fpi>>7) & 0x7F)+0x80; // upper 7 bit pSubBufMgr->smlXltBufferP[2] = (fpi & 0x7F); // lower 7 bits pSubBufMgr->smlXltBufferP[3] = 0x6A; // charset encoding UTF-8 pSubBufMgr->smlXltBufferP[4] = 0; // no string table pSubBufMgr->smlXltBufferP += 5; } // in case of space evaluation, just count the number of written bytes pSubBufMgr->smlXltWrittenBytes = 5; } // do the encoding switch (attFlag) { #ifdef __USE_DEVINF__ case SML_EXT_DEVINF: if ((_err = devinfEncBlock(TN_DEVINF_DEVINF,reqOptFlag,pContent,enc,pSubBufMgr,SML_EXT_DEVINF)) != SML_ERR_OK) { smlLibFree(pSubBufMgr->smlXltStoreBufP); smlLibFree(pSubBufMgr); return _err; } break; #endif /* oops - we don not know about that extension -> bail out */ default: smlLibFree(pSubBufMgr->smlXltStoreBufP); smlLibFree(pSubBufMgr); return SML_ERR_XLT_INVAL_EXT; } #ifdef __USE_DEVINF__ // move it to the 'real' encoder buffer // now set up the OPAQUE field if (pBufMgr->spaceEvaluation == 0) { pBufMgr->smlXltBufferP[0] = 0xC3; // OPAQUE data identifier pBufMgr->smlXltBufferP += 1; wbxmlOpaqueSize2Buf(pSubBufMgr->smlXltWrittenBytes, pBufMgr); smlLibMemmove(pBufMgr->smlXltBufferP, pSubBufMgr->smlXltStoreBufP, pSubBufMgr->smlXltWrittenBytes); pBufMgr->smlXltBufferP += pSubBufMgr->smlXltWrittenBytes; pBufMgr->smlXltWrittenBytes += pSubBufMgr->smlXltWrittenBytes; } else { pBufMgr->smlXltWrittenBytes++; wbxmlOpaqueSize2Buf(pSubBufMgr->smlXltWrittenBytes, pBufMgr); pBufMgr->smlXltWrittenBytes += pSubBufMgr->smlXltWrittenBytes; } // clean up the temporary stuff smlLibFree(pSubBufMgr->smlXltStoreBufP); smlLibFree(pSubBufMgr); return _err; #endif } #endif #endif libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/xlt/all/xltenccom.c000077500000000000000000000100021226375725500245330ustar00rootroot00000000000000/** * @file * Encoder utils file * * @target_system All * @target_os All */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ /*************************************************************************/ /* Definitions */ /*************************************************************************/ #include "syncml_tk_prefix_file.h" // %%% luz: needed for precompiled headers in eVC++ #include "xltenccom.h" #include #include /** * Add a string to the global buffer * * @pre pContent contains some content bytes to write to the (WB) XML buffer * @post content is written to the buffer * @param pContent (IN) * the character pointer referencing the content to write to the buffer * @param size (IN) * the content length * @param pBufMgr (IN/OUT) * pointer to a structure containing buffer management elements * @return shows error codes of function,\n * 0, if OK */ Ret_t xltAddToBuffer(const MemPtr_t pContent, MemSize_t size, BufferMgmtPtr_t pBufMgr) { // if we are doing a space evaluation, do not write the data physically - just remember its length if (!pBufMgr->spaceEvaluation) { //check if buffersize is to small to write the content if ((size + pBufMgr->smlXltWrittenBytes) > pBufMgr->smlXltBufferLen) { #ifdef NCDEBUGPRINTFX #warning "%%%%% delete that message later" NCDEBUGPRINTFX(DBG_RTK_SML,( "xltAddToBuffer: buffer too small, pContent='%0.30s', size=%ld, pBufMgr->smlXltWrittenBytes=%ld, pBufMgr->smlXltBufferLen=%ld", pContent, size, pBufMgr->smlXltWrittenBytes, pBufMgr->smlXltBufferLen )); #endif return SML_ERR_XLT_BUF_ERR; } if (!(smlLibMemcpy((void*) pBufMgr->smlXltBufferP, (void*) pContent, (MemSize_t) size))) { #ifdef NCDEBUGPRINTFX #warning "%%%%% delete that message later" NCDEBUGPRINTFX(DBG_RTK_SML,( "xltAddToBuffer: memCpy failed, pBufMgr->smlXltBufferP=%lX, size=%ld", (long)pBufMgr->smlXltBufferP, size )); #endif return SML_ERR_XLT_BUF_ERR; } pBufMgr->smlXltBufferP += size; } pBufMgr->smlXltWrittenBytes += size; return SML_ERR_OK; } libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/xlt/all/xltenccom.h000077500000000000000000000072461226375725500245600ustar00rootroot00000000000000/** * @file * Encoder utils header file * * @target_system All * @target_os All */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ /*************************************************************************/ /* Definitions */ /*************************************************************************/ #ifndef _XLT_ENC_COM_H #define _XLT_ENC_COM_H #include #include #include #include "xlttags.h" #ifdef __cplusplus extern "C" { #endif /** flags if a (WB)XML block is required or optional */ typedef enum { OPTIONAL = 0, REQUIRED } XltRO_t; /** Tag Types (TT) - begin tags, end tags, ... */ typedef enum { TT_END = 0, TT_BEG, TT_ALL } XltTagType_t; /** Structure elements which are not directly relied to a tag */ typedef enum { ITEM_LIST, TARGET_LIST, SOURCE_LIST, META_LIST, MAPITEM_LIST, TARGETREF_LIST, SOURCEREF_LIST } XltListType_t; /** Type for storing free mem size evaluation information */ typedef struct XltSpaceEvaluation_s { MemSize_t written_bytes; MemSize_t end_tag_size; // %%% luz 2002-09-03: evaluation needs private shadow copies of these: SmlPcdataExtension_t cur_ext; SmlPcdataExtension_t last_ext; } XltSpaceEvaluation_t, *XltSpaceEvaluationPtr_t; typedef struct bufferMgmt_s { MemPtr_t smlXltBufferP; MemPtr_t smlXltStoreBufP; MemSize_t smlXltWrittenBytes; MemSize_t smlXltBufferLen; XltTagID_t switchExtTag; SmlPcdataExtension_t smlCurExt; SmlPcdataExtension_t smlLastExt; SmlPcdataExtension_t smlActiveExt; MemSize_t endTagSize; Boolean_t spaceEvaluation; // %%% luz:2003-04-24: added syncmlvers // %%% luz:2003-07-31: made it an enum, now called vers SmlVersion_t vers; } BufferMgmt_t, *BufferMgmtPtr_t; Ret_t xltAddToBuffer(const MemPtr_t pContent, MemSize_t size, BufferMgmtPtr_t pBufMgr); #ifdef __cplusplus } #endif #endif libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/xlt/all/xltencwbxml.c000077500000000000000000000221311226375725500251140ustar00rootroot00000000000000/** * @file * The WBXML Encoder source file * * @target_system All * @target_os All */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ #include "syncml_tk_prefix_file.h" // %%% luz: needed for precompiled headers in eVC++ #include "define.h" #ifdef __SML_WBXML__ /*************************************************************************/ /* Definitions */ /*************************************************************************/ #include "xltencwbxml.h" #include #include #include "xlttags.h" /** * Converts a element type into its wbxml token * * @pre valid element type * @post return of wbxml token * @param elType (IN) * element type * @return wbxml token\n * 0, if no matching wbxml token */ MemByte_t wbxmlGetGlobToken(XltElementType_t elType) { typedef struct GlobTok_s { XltElementType_t id; MemByte_t wbxml; } GlobTok_t; // encoding of global tokens; related to the type XML_ElementType_t GlobTok_t globtoken[] = { { END, 0x01 }, //Tag End { STR_I, 0x03 }, //Inline string { OPAQUE, 0xC3 }, //Opaque Data { UNDEF, 0x00 } }; int i = -1; while (globtoken[++i].id != UNDEF) if (globtoken[i].id == elType) return globtoken[i].wbxml; return 0; } /** * Converts a Long_t opaque size to a wbxml mb_u_int32 and adds it to the buffer * * @pre size of the content to be written as opaque datatype * @post the size is converted to the mb_u_int32 representation and added * to the buffer * @param size (IN) * length of the opaque data * @param pBufMgr (IN/OUT) * pointer to a structure containing buffer management elements * @return shows error codes of function,\n * 0, if OK */ Ret_t wbxmlOpaqueSize2Buf(Long_t size, BufferMgmtPtr_t pBufMgr) { Long_t _thresholdcount = 1; Long_t _bytesNeeded = 0; MemPtr_t _byteArray; MemPtr_t _tmpByteArray; int i, j; Ret_t _err; //j max = number of bytes of size for (j=1; j<=sizeof(size); j++) { //if the size of the content is smaller than the power of 128,j -> //one more byte is needed in the mb_u_int32 representation of WBXML _thresholdcount = _thresholdcount * 128; if(size < _thresholdcount) { _bytesNeeded = j; break; } } if (pBufMgr->spaceEvaluation == 0) { //allocate number of bytes needed by the mb_u_int32 data type if ((_byteArray = smlLibMalloc(_bytesNeeded)) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; _tmpByteArray = _byteArray; //process al bytes in the mb_u_int32 data type for (i=1; i<=_bytesNeeded; i++) { // the lowest byte needs a 0 in its highest bit -> no | 0x80 if ((_bytesNeeded - i) == 0) { *_tmpByteArray = ((unsigned char)(size & 0x7F)); } // all the other byte needs a 1 in its highest bit -> | 0x80 else { // only the seven lower bits contain the size value -> >> 7 *_tmpByteArray = ((unsigned char)(((size >> (7 * (_bytesNeeded - i))) & 0x7F) | 0x80)); _tmpByteArray++; } } _err = xltAddToBuffer(_byteArray, _bytesNeeded, pBufMgr); smlLibFree(_byteArray); } else { pBufMgr->smlXltWrittenBytes += _bytesNeeded; // %%% luz 2002-09-03: return value was missing here. _err=SML_ERR_OK; } return _err; } /** * Generates a tag for a given tag ID and a given tag type * * @pre valid parameters * @post a new wbxml tag is written to the buffer * @param tagId (IN) * the ID for the tag to generate (TN_ADD, ...) * @param tagType (IN) * the tag type (e.g. Begin Tag -> TT_BEG, ...) * @param pBufMgr (IN/OUT) * pointer to a structure containing buffer management elements * @return shows error codes of function,\n * 0, if OK */ Ret_t wbxmlGenerateTag(XltTagID_t tagId, XltTagType_t tagType, BufferMgmtPtr_t pBufMgr ) { Ret_t _err = SML_ERR_OK; MemByte_t _tmp = 0x00; //check if content byte has to be added to the tag switch (tagType) { //set the end tag case TT_END: { _tmp = (MemByte_t)wbxmlGetGlobToken(END); if (!_tmp) return SML_ERR_XLT_INVAL_TAG_TYPE; _err = xltAddToBuffer((&_tmp), 1, pBufMgr); // remember the number of byte that must follow for the according end-tag if (_err == SML_ERR_OK) pBufMgr->endTagSize -= 1; return _err; } //Begin and End Tag in one case TT_ALL: { _err = (MemByte_t)getTagByte(tagId, pBufMgr->smlCurExt, &_tmp); if ((!_tmp) || (_err != SML_ERR_OK)) return _err; return xltAddToBuffer((MemPtr_t)(&_tmp), 1, pBufMgr); } //Only Begin Tag -> content follows -> content byte has to be added case TT_BEG: { _err = (MemByte_t)getTagByte(tagId, pBufMgr->smlCurExt, &_tmp); if ((!_tmp) || (_err != SML_ERR_OK)) return _err; _tmp = ((MemByte_t)(_tmp | XLT_CONTBYTE)); _err = xltAddToBuffer(&_tmp, 1, pBufMgr); // remember the number of byte that must follow for the according end-tag if (_err == SML_ERR_OK) pBufMgr->endTagSize += 1; return _err; } default: return SML_ERR_XLT_INVAL_TAG_TYPE; } // return SML_ERR_OK;Unreachable } /** * Write a content of a certain WBXML element type (e.g.\ STR_I) * to the global buffer * * @pre valid parameters * @post the content is written to the wbxml buffer with the leading * bytes for the opaque data type or the STR_I data type * @param pContent (IN) * the character pointer referencing the content to * write to the buffer * @param elType (IN) * the element type to write to the buffer (e.g. STR_I) * @param size (IN) * the content length * @param pBufMgr (IN/OUT) * pointer to a structure containing buffer management elements * @return shows error codes of function,\n * 0, if OK */ Ret_t wbxmlWriteTypeToBuffer(const MemPtr_t pContent, XltElementType_t elType, Long_t size, BufferMgmtPtr_t pBufMgr) { Ret_t _err; MemByte_t _termstr = XLT_TERMSTR; MemByte_t _tmp; switch((int)elType) { case TAG: { return (xltAddToBuffer(pContent, size, pBufMgr)); } case STR_I: { _tmp = (MemByte_t)wbxmlGetGlobToken(STR_I); if (!_tmp) return SML_ERR_XLT_WBXML_UKN_TOK; //add the STR_I identifier if ((_err = xltAddToBuffer(&_tmp, 1, pBufMgr)) != SML_ERR_OK) return _err; //add the string to the buffer if ((_err = xltAddToBuffer(pContent, (!pContent) ? 0 : smlLibStrlen((String_t)pContent), pBufMgr)) != SML_ERR_OK) return _err; //add the string terminator '\0' if ((_err = xltAddToBuffer(&_termstr, 1, pBufMgr)) != SML_ERR_OK) return _err; return SML_ERR_OK; } case OPAQUE: { _tmp = (MemByte_t)wbxmlGetGlobToken(OPAQUE); if (!_tmp) return SML_ERR_XLT_WBXML_UKN_TOK; //add the OPAQUE identifier if ((_err = xltAddToBuffer(&_tmp, 1, pBufMgr)) != SML_ERR_OK) return _err; //add the pContent length if ((_err = wbxmlOpaqueSize2Buf(size, pBufMgr)) != SML_ERR_OK) return _err; //add the string buffer if ((_err = xltAddToBuffer(pContent, size, pBufMgr)) != SML_ERR_OK) return _err; return SML_ERR_OK; } default: return SML_ERR_XLT_INVAL_PCDATA_TYPE; } // return SML_ERR_OK;unreachable } #endif libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/xlt/all/xltencwbxml.h000077500000000000000000000072321226375725500251260ustar00rootroot00000000000000/** * @file * The WBXML Encoder header file * * @target_system All * @target_os All */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ /*************************************************************************/ /* Definitions */ /*************************************************************************/ #ifndef _XLT_ENC_WBXML_H #define _XLT_ENC_WBXML_H #include #include #include #include "xlttags.h" #include "xltenccom.h" #define test 1 /** byte for WBXML String Table Length - not yet implemented yet -> 0x00 */ #define XLT_STABLEN 0x00 /** byte for WBXML charset - not yet implemented - default UTF-8 */ #define XLT_CHARSET 0x6A /** byte for WBXML Version Number */ #define XLT_WBXMLVER 0x02 /** byte to add to a tag if a content follows */ #define XLT_CONTBYTE 0x40 /** byte to add to a tag if an attribute follows */ #define XLT_ATTRBYTE 0x80 /** termination character for certain WBXML element types (e.g.\ STR_I) */ #define XLT_TERMSTR 0x00 /** public identifier 0x00,0x00 -> unknown, use stringtable */ #define XLT_PUBIDENT1 0x00 #define XLT_PUBIDENT2 0x00 // %%% luz: 2003-07-31: now in xltenc.c's SyncMLFPI table //#define XLT_DTD_ID "-//SYNCML//DTD SyncML 1.0//EN" /** switch page tag 0x00 */ #define XLT_SWITCHPAGE 0x00 /** default codepage */ #define XLT_DEFAULTCODEPAGE 0x00 #ifdef __cplusplus extern "C" { #endif /** global tokens in WBXML */ typedef enum { UNDEF = 0, END, STR_I, OPAQUE, TAG } XltElementType_t; Ret_t wbxmlGenerateTag(XltTagID_t tagId, XltTagType_t tagType, BufferMgmtPtr_t pBufMgr); Ret_t wbxmlWriteTypeToBuffer(const MemPtr_t pContent, XltElementType_t elType, Long_t size, BufferMgmtPtr_t pBufMgr); Ret_t wbxmlOpaqueSize2Buf(Long_t size, BufferMgmtPtr_t pBufMgr); MemByte_t wbxmlGetGlobToken(XltElementType_t elType); #ifdef __cplusplus } #endif #endif libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/xlt/all/xltencxml.c000077500000000000000000000151561226375725500245740ustar00rootroot00000000000000/** * @file * The XML Encoder source file * * @target_system All * @target_os All */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ #include "syncml_tk_prefix_file.h" // %%% luz: needed for precompiled headers in eVC++ #include "define.h" #ifdef __SML_XML__ /*************************************************************************/ /* Definitions */ /*************************************************************************/ #include "xltencxml.h" #include #include "xlttags.h" #include /** * Generates a XML tag * * @pre valid parameters * @post the XML tag is written to the XML buffer * @param tagId (IN) * the ID for the tag to generate (TN_ADD, ...) * @param tagType (IN) * the tag type (e.g. Begin Tag -> TT_BEG, ...) * @param attFlag (IN) * indicates if the encoded tag contain Attributes in namespace * extensions * @param pBufMgr (IN/OUT) * pointer to a structure containing buffer management elements * @return shows error codes of function,\n * 0, if OK */ Ret_t xmlGenerateTag(XltTagID_t tagId, XltTagType_t tagType, BufferMgmtPtr_t pBufMgr, SmlPcdataExtension_t attFlag) { Ret_t _err; MemByte_t _begpar = XML_BEGPAR; MemByte_t _tagdel = XML_TAGDEL; MemByte_t _endpar = XML_ENDPAR; MemByte_t _nstagstart[] = XML_NSSTART; MemByte_t _nstagend[] = XML_NSEND; String_t _tagstr; String_t _tagnsattr = NULL; if ((_tagstr = (String_t)smlLibMalloc(XML_MAX_TAGLEN)) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; if ((_err = getTagString(tagId, _tagstr, attFlag)) != SML_ERR_OK) { smlLibFree(_tagstr); return _err; } if (!_tagstr) { // check again as _tagstr might be alterd in getTagString smlLibFree(_tagstr); return SML_ERR_XLT_INVAL_TAG_TYPE; } /* the tag _must_ have an xmlns attribute */ if (attFlag != pBufMgr->smlActiveExt || tagId == TN_SYNCML) { // %%% luz:2003-07-31: now uses namespace from table according to version if (getExtName(attFlag, &_tagnsattr, pBufMgr->vers) != SML_ERR_OK) { smlLibFree(_tagstr); return SML_ERR_XLT_INVAL_TAG_TYPE; } } pBufMgr->smlActiveExt = attFlag; //check if content byte has to be added to the tag switch (tagType) { // set the end tag case TT_END: { if ((_err = xltAddToBuffer((MemPtr_t)(&_begpar), 1, pBufMgr)) != SML_ERR_OK) break; if ((_err = xltAddToBuffer((MemPtr_t)(&_tagdel), 1, pBufMgr)) != SML_ERR_OK) break; if ((_err = xltAddToBuffer((MemPtr_t)_tagstr, smlLibStrlen(_tagstr), pBufMgr)) != SML_ERR_OK) break; if ((_err = xltAddToBuffer((MemPtr_t)(&_endpar), 1, pBufMgr)) != SML_ERR_OK) break; if (tagId == pBufMgr->switchExtTag) { pBufMgr->smlActiveExt = pBufMgr->smlLastExt; pBufMgr->smlCurExt = pBufMgr->smlLastExt; pBufMgr->smlLastExt = attFlag; } // just forget the stored number ob bytes for this end-tag since written now pBufMgr->endTagSize -= (3 + smlLibStrlen(_tagstr)); break; } //Empty tag case TT_ALL: { if ((_err = xltAddToBuffer((MemPtr_t)(&_begpar), 1, pBufMgr)) != SML_ERR_OK) break; if ((_err = xltAddToBuffer((MemPtr_t)_tagstr, smlLibStrlen(_tagstr), pBufMgr)) != SML_ERR_OK) break; if (_tagnsattr) { if ((_err = xltAddToBuffer((MemPtr_t)(&_nstagstart), 8, pBufMgr)) != SML_ERR_OK) break; if ((_err = xltAddToBuffer((MemPtr_t)_tagnsattr, smlLibStrlen(_tagnsattr), pBufMgr)) != SML_ERR_OK) break; if ((_err = xltAddToBuffer((MemPtr_t)&_nstagend, 1, pBufMgr)) != SML_ERR_OK) break; } if ((_err = xltAddToBuffer((MemPtr_t)(&_tagdel), 1, pBufMgr)) != SML_ERR_OK) break; if ((_err = xltAddToBuffer((MemPtr_t)(&_endpar), 1, pBufMgr)) != SML_ERR_OK) break; break; } //Only Begin Tag -> content follows -> content byte has to be added case TT_BEG: { if ((_err = xltAddToBuffer((MemPtr_t)(&_begpar), 1, pBufMgr)) != SML_ERR_OK) break; if ((_err = xltAddToBuffer((MemPtr_t)_tagstr, smlLibStrlen(_tagstr), pBufMgr)) != SML_ERR_OK) break; if (_tagnsattr) { if ((_err = xltAddToBuffer((MemPtr_t)&_nstagstart, 8, pBufMgr)) != SML_ERR_OK) break; if ((_err = xltAddToBuffer((MemPtr_t)_tagnsattr, smlLibStrlen(_tagnsattr), pBufMgr)) != SML_ERR_OK) break; if ((_err = xltAddToBuffer((MemPtr_t)&_nstagend, 1, pBufMgr)) != SML_ERR_OK) break; } if ((_err = xltAddToBuffer((MemPtr_t)(&_endpar), 1, pBufMgr)) != SML_ERR_OK) break; // remember the number of byte that must follow for the according end-tag pBufMgr->endTagSize += (3 + smlLibStrlen(_tagstr)); break; } default: { smlLibFree(_tagstr); smlLibFree(_tagnsattr); return SML_ERR_XLT_INVAL_TAG_TYPE; } } smlLibFree(_tagstr); smlLibFree(_tagnsattr); return _err; } #endif libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/xlt/all/xltencxml.h000077500000000000000000000055051226375725500245760ustar00rootroot00000000000000/** * @file * The XML Encoder header file * * @target_system All * @target_os All */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ /*************************************************************************/ /* Definitions */ /*************************************************************************/ #ifdef __SML_XML__ #ifndef _XLT_ENC_XML_H #define _XLT_ENC_XML_H #include #include "xlttags.h" #include "xltenccom.h" /** byte for XML tag begin parentheses */ #define XML_BEGPAR '<' /** byte for XML tag end parentheses */ #define XML_ENDPAR '>' /** byte for XML tag del */ #define XML_TAGDEL '/' /** XML version */ #define XML_VERSION "1.0" /** XML encoding */ #define XML_ENCODING "UTF-8" /** XML namespaceattribute */ #define XML_NSSTART " xmlns='" #define XML_NSEND "'" #ifdef __cplusplus extern "C" { #endif Ret_t xmlGenerateTag(XltTagID_t tagId, XltTagType_t tagType, BufferMgmtPtr_t pBufMgr, SmlPcdataExtension_t attFlag); #ifdef __cplusplus } #endif #endif #endif libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/xlt/all/xltmetinf.c000077500000000000000000000376211226375725500245710ustar00rootroot00000000000000/** * @file * MetaInf DTD related functions for the en-/decoder * * @target_system all * @target_os all */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ #include "syncml_tk_prefix_file.h" // %%% luz: needed for precompiled headers in eVC++ #include "define.h" #ifdef __USE_METINF__ #include "smlmetinfdtd.h" #include "xlttags.h" #include "xltmetinf.h" #include "xlttagtbl.h" #include "xltenc.h" #include "xltencwbxml.h" #include "define.h" #include "libstr.h" #include "smlerr.h" #include "smldtd.h" #include "libmem.h" #include "libutil.h" /* extern */ extern SML_API void smlFreeMetinfAnchor(SmlMetInfAnchorPtr_t data) XLT_FUNC; extern SML_API void smlFreeMetinfMem(SmlMetInfMemPtr_t data) XLT_FUNC; extern SML_API void smlFreeMetinfMetinf(SmlMetInfMetInfPtr_t data) XLT_FUNC; /* decoder callbacks */ Ret_t buildMetInfAnchorCmd(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem) { XltDecScannerPtr_t pScanner; SmlMetInfAnchorPtr_t pAnchor; Ret_t rc; pScanner = pDecoder->scanner; if (*ppElem != NULL) return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildMetInfAnchorCmd"); if ((pAnchor = (SmlMetInfAnchorPtr_t)smlLibMalloc(sizeof(SmlMetInfAnchor_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pAnchor, 0, sizeof(SmlMetInfAnchor_t)); if (IS_EMPTY(pScanner->curtok)) { *ppElem = pAnchor; return SML_ERR_OK; } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlFreeMetinfAnchor(pAnchor); //smlLibFree(pAnchor); return rc; } while (pScanner->curtok->type != TOK_TAG_END) { switch (pScanner->curtok->tagid) { /* PCDATA elements */ case TN_METINF_LAST: rc = buildPCData(pDecoder, (VoidPtr_t)&pAnchor->last); break; case TN_METINF_NEXT: rc = buildPCData(pDecoder, (VoidPtr_t)&pAnchor->next); break; default: rc = SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC,pScanner,"buildMetInfAnchorCmd_2"); } if (rc != SML_ERR_OK) { smlFreeMetinfAnchor(pAnchor); //smlLibFree(pAnchor); return rc; } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlFreeMetinfAnchor(pAnchor); //smlLibFree(pAnchor); return rc; } } *ppElem = pAnchor; return SML_ERR_OK; } Ret_t buildMetinfNextCmd(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem) { XltDecScannerPtr_t pScanner; SmlMetInfAnchorPtr_t pAnchor; Ret_t rc; pScanner = pDecoder->scanner; if (*ppElem == NULL) { if ((pAnchor = (SmlMetInfAnchorPtr_t)smlLibMalloc(sizeof(SmlMetInfAnchor_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pAnchor, 0, sizeof(SmlMetInfAnchor_t)); } else { pAnchor = (SmlMetInfAnchorPtr_t)*ppElem; if (pAnchor->next != NULL) return SML_ERR_XLT_INVAL_SYNCML_DOC; } rc = buildPCData(pDecoder, (VoidPtr_t)&pAnchor->next); if (rc != SML_ERR_OK && ppElem == NULL) { smlFreeMetinfAnchor(pAnchor); return rc; } if (ppElem == NULL) { *ppElem = pAnchor; } return SML_ERR_OK; } Ret_t buildMetInfMemCmd(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem) { XltDecScannerPtr_t pScanner; SmlMetInfMemPtr_t pMem; Ret_t rc; pScanner = pDecoder->scanner; if (*ppElem != NULL) return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC, pScanner, "buildMetInfMemCmd"); if ((pMem = (SmlMetInfMemPtr_t)smlLibMalloc(sizeof(SmlMetInfMem_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pMem, 0, sizeof(SmlMetInfMem_t)); if (IS_EMPTY(pScanner->curtok)) { *ppElem = pMem; return SML_ERR_OK; } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlFreeMetinfMem(pMem); //smlLibFree(pMem); return rc; } while (pScanner->curtok->type != TOK_TAG_END) { switch (pScanner->curtok->tagid) { /* %%% luz 2005-08-24 :this definition was plain wrong - shared is a flag, not Pcdata! case TN_METINF_SHAREDMEM: rc = buildPCData(pDecoder, (VoidPtr_t)&pMem->shared); break; */ /* PCDATA elements */ case TN_METINF_FREEMEM: rc = buildPCData(pDecoder, (VoidPtr_t)&pMem->free); break; case TN_METINF_FREEID: rc = buildPCData(pDecoder, (VoidPtr_t)&pMem->freeid); break; /* flags */ case TN_METINF_SHAREDMEM: pMem->flags |= SmlMetInfSharedMem_f; rc = buildEmptyTag(pDecoder); // allow for instead of break; default: rc = SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC, pScanner, "buildMetInfMemCmd_2"); } if (rc != SML_ERR_OK) { smlFreeMetinfMem(pMem); //smlLibFree(pMem); return rc; } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlFreeMetinfMem(pMem); //smlLibFree(pMem); return rc; } } *ppElem = pMem; return SML_ERR_OK; } Ret_t buildMetInfMetInfCmd(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem) { XltDecScannerPtr_t pScanner; SmlMetInfMetInfPtr_t pMeta; Ret_t rc; int foundWrapper = 0; pScanner = pDecoder->scanner; if (*ppElem != NULL) return SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC, pScanner, "buildMetInfMetInfCmd"); if ((pMeta = (SmlMetInfMetInfPtr_t)smlLibMalloc(sizeof(SmlMetInfMetInf_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; smlLibMemset(pMeta, 0, sizeof(SmlMetInfMetInf_t)); if (IS_EMPTY(pScanner->curtok)) { *ppElem = pMeta; return SML_ERR_OK; } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlFreeMetinfMetinf(pMeta); //smlLibFree(pMeta); return rc; } while (pScanner->curtok->type != TOK_TAG_END) { switch (pScanner->curtok->tagid) { case TN_METINF_METINF: /* ignore - it's just the wrapper tag */ foundWrapper = 1; break; case TN_METINF_FORMAT: rc = buildPCData(pDecoder, (VoidPtr_t)&pMeta->format); break; case TN_METINF_TYPE: rc = buildPCData(pDecoder, (VoidPtr_t)&pMeta->type); break; case TN_METINF_MARK: rc = buildPCData(pDecoder, (VoidPtr_t)&pMeta->mark); break; case TN_METINF_SIZE: rc = buildPCData(pDecoder, (VoidPtr_t)&pMeta->size); break; case TN_METINF_VERSION: rc = buildPCData(pDecoder, (VoidPtr_t)&pMeta->version); break; case TN_METINF_NEXTNONCE: rc = buildPCData(pDecoder, (VoidPtr_t)&pMeta->nextnonce); break; case TN_METINF_ANCHOR: rc = buildMetInfAnchorCmd(pDecoder, (VoidPtr_t)&pMeta->anchor); break; case TN_METINF_MAXMSGSIZE: rc = buildPCData(pDecoder, (VoidPtr_t)&pMeta->maxmsgsize); break; /* SCTSTK - 18/03/2002 S.H. 2002-04-05: SyncML 1.1 */ case TN_METINF_MAXOBJSIZE: rc = buildPCData(pDecoder, (VoidPtr_t)&pMeta->maxobjsize); break; case TN_METINF_MEM: rc = buildMetInfMemCmd(pDecoder, (VoidPtr_t)&pMeta->mem); break; case TN_METINF_EMI: rc = buildPCDataList(pDecoder, (VoidPtr_t)&pMeta->emi); break; /* SyncML DS 1.2, Synthesis/luz 2005-08-24 */ case TN_METINF_FIELDLEVEL: pMeta->flags |= SmlMetInfFieldLevel_f; rc = buildEmptyTag(pDecoder); // allow for instead of break; /* Next without Anchor, Andris Pavenis 2012-05-29 */ case TN_METINF_NEXT: rc = buildMetinfNextCmd(pDecoder, (VoidPtr_t)&pMeta->anchor); break; default: rc = SML_DECODEERROR(SML_ERR_XLT_INVAL_SYNCML_DOC, pScanner, "buildMetInfMetInfCmd_2"); } if (rc != SML_ERR_OK) { smlFreeMetinfMetinf(pMeta); //smlLibFree(pMeta); return rc; } if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlFreeMetinfMetinf(pMeta); //smlLibFree(pMeta); return rc; } } if (foundWrapper) { /* Optional Metinf root tag was used in this message. * The actual token is the closing root tag. * It is required that the scanner points to the first tag _after_ * ..., so we just skip to the next token and continue. */ if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { smlFreeMetinfMetinf(pMeta); //smlLibFree(pMeta); return rc; } } *ppElem = pMeta; return SML_ERR_OK; } /* see xltenc.c:XltEncBlock for description of parameters */ Ret_t metinfEncBlock(XltTagID_t tagId, XltRO_t reqOptFlag, const VoidPtr_t pContent, SmlEncoding_t enc, BufferMgmtPtr_t pBufMgr, SmlPcdataExtension_t attFlag) { //Return variable Ret_t _err; SmlPcdataListPtr_t pList = NULL; //Check if pContent of a required field is missing if ((reqOptFlag == REQUIRED) && (pContent == NULL)) return SML_ERR_XLT_MISSING_CONT; //Check if pContent of a optional field is missing -> if yes we are done else if (pContent == NULL) return SML_ERR_OK; //Generate the commands -> see DTD switch (tagId) { case TN_METINF_ANCHOR: if ((_err = xltGenerateTag(TN_METINF_ANCHOR, TT_BEG, enc, pBufMgr, SML_EXT_METINF)) != SML_ERR_OK) return _err; if ((_err = metinfEncBlock(TN_METINF_LAST, OPTIONAL, ((SmlMetInfAnchorPtr_t) pContent)->last, enc, pBufMgr, SML_EXT_METINF)) != SML_ERR_OK) return _err; if ((_err = metinfEncBlock(TN_METINF_NEXT, REQUIRED, ((SmlMetInfAnchorPtr_t) pContent)->next, enc, pBufMgr, SML_EXT_METINF)) != SML_ERR_OK) return _err; if ((_err = xltGenerateTag(TN_METINF_ANCHOR, TT_END, enc, pBufMgr, SML_EXT_METINF)) != SML_ERR_OK) return _err; break; case TN_METINF_MEM: if ((_err = xltGenerateTag(TN_METINF_MEM, TT_BEG, enc, pBufMgr, SML_EXT_METINF)) != SML_ERR_OK) return _err; if ((_err = metinfEncBlock(TN_METINF_SHAREDMEM, OPTIONAL, &(((SmlMetInfMemPtr_t) pContent)->flags), enc, pBufMgr, SML_EXT_METINF)) != SML_ERR_OK) return _err; if ((_err = metinfEncBlock(TN_METINF_FREEMEM, REQUIRED, ((SmlMetInfMemPtr_t) pContent)->free, enc, pBufMgr, SML_EXT_METINF)) != SML_ERR_OK) return _err; if ((_err = metinfEncBlock(TN_METINF_FREEID, REQUIRED, ((SmlMetInfMemPtr_t) pContent)->freeid, enc, pBufMgr, SML_EXT_METINF)) != SML_ERR_OK) return _err; if ((_err = xltGenerateTag(TN_METINF_MEM, TT_END, enc, pBufMgr, SML_EXT_METINF)) != SML_ERR_OK) return _err; break; case TN_METINF_SHAREDMEM: //set the flag in the (WB)XML document if the flag is in the pContent if ((*((Flag_t *) pContent)) & (SmlMetInfSharedMem_f)) if ((_err = xltGenerateTag(tagId, TT_ALL, enc, pBufMgr, SML_EXT_METINF)) != SML_ERR_OK) return _err; break; case TN_METINF_FIELDLEVEL: //set the flag in the (WB)XML document if the flag is in the pContent if ((*((Flag_t *) pContent)) & (SmlMetInfFieldLevel_f)) if ((_err = xltGenerateTag(tagId, TT_ALL, enc, pBufMgr, SML_EXT_METINF)) != SML_ERR_OK) return _err; break; case TN_METINF_METINF: //if ((_err = xltGenerateTag(TN_METINF_METINF, TT_BEG, enc, pBufMgr, SML_EXT_METINF)) != SML_ERR_OK) return _err; if ((_err = metinfEncBlock(TN_METINF_FORMAT, OPTIONAL, ((SmlMetInfMetInfPtr_t) pContent)->format, enc, pBufMgr, SML_EXT_METINF)) != SML_ERR_OK) return _err; if ((_err = metinfEncBlock(TN_METINF_TYPE, OPTIONAL, ((SmlMetInfMetInfPtr_t) pContent)->type, enc, pBufMgr, SML_EXT_METINF)) != SML_ERR_OK) return _err; if ((_err = metinfEncBlock(TN_METINF_MARK, OPTIONAL, ((SmlMetInfMetInfPtr_t) pContent)->mark, enc, pBufMgr, SML_EXT_METINF)) != SML_ERR_OK) return _err; if ((_err = metinfEncBlock(TN_METINF_SIZE, OPTIONAL, ((SmlMetInfMetInfPtr_t) pContent)->size, enc, pBufMgr, SML_EXT_METINF)) != SML_ERR_OK) return _err; if ((_err = metinfEncBlock(TN_METINF_ANCHOR, OPTIONAL, ((SmlMetInfMetInfPtr_t) pContent)->anchor, enc, pBufMgr, SML_EXT_METINF)) != SML_ERR_OK) return _err; if ((_err = metinfEncBlock(TN_METINF_VERSION, OPTIONAL, ((SmlMetInfMetInfPtr_t) pContent)->version, enc, pBufMgr, SML_EXT_METINF)) != SML_ERR_OK) return _err; if ((_err = metinfEncBlock(TN_METINF_NEXTNONCE, OPTIONAL, ((SmlMetInfMetInfPtr_t) pContent)->nextnonce, enc, pBufMgr, SML_EXT_METINF)) != SML_ERR_OK) return _err; if ((_err = metinfEncBlock(TN_METINF_MAXMSGSIZE,OPTIONAL, ((SmlMetInfMetInfPtr_t) pContent)->maxmsgsize, enc, pBufMgr, SML_EXT_METINF)) != SML_ERR_OK) return _err; // %%% luz 2003-04-24: added maxobjsize generation (was missing = bug in original RTK 4.1) if ((_err = metinfEncBlock(TN_METINF_MAXOBJSIZE,OPTIONAL, ((SmlMetInfMetInfPtr_t) pContent)->maxobjsize, enc, pBufMgr, SML_EXT_METINF)) != SML_ERR_OK) return _err; pList = ((SmlMetInfMetInfPtr_t)pContent)->emi; while (pList != NULL) { if ((_err = xltEncBlock(TN_METINF_EMI, OPTIONAL, pList->data, enc, pBufMgr, SML_EXT_METINF)) != SML_ERR_OK) return _err; pList = pList->next; }; if ((_err = metinfEncBlock(TN_METINF_MEM, OPTIONAL, ((SmlMetInfMetInfPtr_t) pContent)->mem, enc, pBufMgr, SML_EXT_METINF)) != SML_ERR_OK) return _err; /* SyncML DS 1.2, Synthesis/luz 2005-08-24 */ if ((_err = metinfEncBlock(TN_METINF_FIELDLEVEL,OPTIONAL, &(((SmlMetInfMetInfPtr_t) pContent)->flags), enc, pBufMgr, SML_EXT_METINF)) != SML_ERR_OK) return _err; //if ((_err = xltGenerateTag(TN_METINF_METINF, TT_END, enc, pBufMgr, SML_EXT_METINF)) != SML_ERR_OK) return _err; break; default: { // all leaf nodes (PCDATA#) return xltEncPcdata(tagId, reqOptFlag, pContent, enc, pBufMgr, attFlag); } /* eof default statement from switch tagid */ } /* eof switch tagid */ return SML_ERR_OK; } #endif /* __USE_METINF__ */ libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/xlt/all/xltmetinf.h000077500000000000000000000054101226375725500245650ustar00rootroot00000000000000/** * @file * Definition of MetaInf DTD prototypefunctions for the en-/decoder * * @target_system all * @target_os all */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ #ifndef _XLT_METINF_H #define _XLT_METINF_H /* process only if we really use MetInf DTD */ #ifdef __USE_METINF__ /*************************************************************************/ /* Definitions */ /*************************************************************************/ #include "xlttagtbl.h" #include "xltenc.h" Ret_t buildMetInfAnchorCmd(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem); Ret_t buildMetInfMetInfCmd(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem); Ret_t buildMetInfMemCmd(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem); Ret_t metinfEncBlock(XltTagID_t tagId, XltRO_t reqOptFlag, const VoidPtr_t pContent, SmlEncoding_t enc, BufferMgmtPtr_t pBufMgr, SmlPcdataExtension_t attFlag); #endif /* __USE_METINF__ */ #endif /* _XLT_METINF_H */ libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/xlt/all/xlttags.c000077500000000000000000000555421226375725500242470ustar00rootroot00000000000000/** * @file * Definition of WBXML/XML tags for the en-/decoder * * @target_system all * @target_os all */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ #include "syncml_tk_prefix_file.h" // %%% luz: needed for precompiled headers in eVC++ #include "xlttags.h" #include #include #include #include #include #include "xltmetinf.h" #include "xltdevinf.h" #include "xlttagtbl.h" // %%% luz:2003-07-31: added SyncML namespace tables const char * const SyncMLNamespaces[SML_NUM_VERS] = { "???", "SYNCML:SYNCML1.0", "SYNCML:SYNCML1.1", "SYNCML:SYNCML1.2" }; /* local prototypes */ #ifdef NOWSM //%%% removed const to prevent gcc "type qualifiers ignored on function return type" warning //const // without WSM, the tag table is a global read-only constant #endif TagPtr_t getTagTable(SmlPcdataExtension_t ext); //SmlPcdataExtension_t getByName(String_t ns); void freeDtdTable(DtdPtr_t tbl); #ifdef NOWSM //%%% removed const to prevent gcc "type qualifiers ignored on function return type" warning //const // without WSM, the DTD table is a global read-only constant #endif DtdPtr_t getDtdTable(); // free table obtained with getDtdTable() void freeDtdTable(DtdPtr_t tbl) { #ifndef NOWSM // only with WSM this is an allocated table smlLibFree(tbl); #endif } /** * Returns a copy of the table containing all known (sub) dtd's * On error a NULL pointer is returned */ #ifdef NOWSM //%%% removed const to prevent gcc "type qualifiers ignored on function return type" warning //const // without WSM, the DTD table is a global read-only constant #endif DtdPtr_t getDtdTable() { #ifdef NOWSM // NOWSM method, table is const, just return a pointer static const Dtd_t XltDtdTbl[] = { { "SYNCML:SYNCML1.0", SML_EXT_UNDEFINED}, // %%% note that this is the default, will be override by syncml version specific string from { "syncml:metinf", SML_EXT_METINF}, { "syncml:devinf", SML_EXT_DEVINF}, { NULL, SML_EXT_LAST} }; return (DtdPtr_t)XltDtdTbl; #else // WSM method wasting a lot of memory DtdPtr_t _tmpPtr; Dtd_t XltDtdTbl[] = { { "SYNCML:SYNCML1.0", SML_EXT_UNDEFINED}, { "syncml:metinf", SML_EXT_METINF}, { "syncml:devinf", SML_EXT_DEVINF}, { NULL, SML_EXT_LAST} }; _tmpPtr = NULL; _tmpPtr = (DtdPtr_t)smlLibMalloc(sizeof(XltDtdTbl)); if (_tmpPtr == NULL) return NULL; smlLibMemcpy(_tmpPtr, &XltDtdTbl, sizeof(XltDtdTbl)); return _tmpPtr; #endif } /** * Returns the official name for a given extention/sub-DTD * and stored it in 'name'. If not found name isn't modified */ // %%% luz:2003-04-24: added syncmlvers parameter // %%% luz:2003-07-31: changed to vers enum Ret_t getExtName(SmlPcdataExtension_t ext, String_t *name, SmlVersion_t vers) { DtdPtr_t dtdhead = getDtdTable(); DtdPtr_t dtd = dtdhead; const char *dtdname; if (!dtdhead) return -1; for (;dtd->ext != SML_EXT_LAST; dtd++) { if (!dtd->name) continue; /* skip empty names (should not appear but better be on the safe side) */ if (dtd->ext == ext) { String_t _tmp; // this is the default dtdname=dtd->name; // %%% luz:2003-04-24: added dynamic generation of namespace according to SyncML version if (ext==SML_EXT_UNDEFINED && vers!=SML_VERS_UNDEF) { // this requests SyncML namespace dtdname=SyncMLNamespaces[vers]; } _tmp = smlLibMalloc(smlLibStrlen(dtdname)+1); if (!_tmp) { freeDtdTable(dtdhead); return SML_ERR_NOT_ENOUGH_SPACE; } smlLibStrcpy(_tmp, dtdname); freeDtdTable(dtdhead); *name = _tmp; return SML_ERR_OK; } } freeDtdTable(dtdhead); return -1; } /** * Returns the codepage constant assoziated with the name stored in 'ns' * * @return a SmlPcdataExtension_t representing the corresponding codepage id. * If no corresponding codepage is found -1 is returned. */ SmlPcdataExtension_t getExtByName(String_t ns) { DtdPtr_t dtdhead = getDtdTable(); DtdPtr_t dtd = dtdhead; SmlPcdataExtension_t ext = (SmlPcdataExtension_t) 255; if (!dtdhead) return SML_EXT_UNDEFINED; for (;dtd->ext != SML_EXT_LAST; dtd++) { const char *dtdname=dtd->name; if (!dtdname) continue; /* skip empty names (should not appear but better be on the safe side) */ if (dtd->ext==SML_EXT_UNDEFINED && smlLibStrnCasecmp("SYNCML:SYNCML",ns,13)==0) { // SyncML namespace is ok without checking version! ext = SML_EXT_UNDEFINED; break; } else if (smlLibStrcmp(dtdname,ns) == 0) { ext = dtd->ext; break; } } freeDtdTable(dtdhead); return ext; } /* if the commands are not defined we let the functions point to NULL */ #ifndef RESULT_RECEIVE #define buildResults NULL #endif #ifndef MAP_RECEIVE #define buildMap NULL #endif #ifndef EXEC_RECEIVE #define buildExec NULL #endif #if !defined(ATOMIC_RECEIVE) && !defined(SEQUENCE_RECEIVE) #define buildAtomOrSeq NULL #endif #ifndef SEARCH_RECEIVE #define buildSearch NULL #endif /** * Returns the tag table - this function is used to avoid a global * tag table variable * * @return a pointer to the tag table containing tag ids, * codepages, wbxml tags and xml tags */ /* T.K. initialized the structure via _TOKEN Macro, to take * out the XML name tags when not compiled with XML support. * In addtion removed the (unused) pointer for the build functions */ #if defined(__SML_XML__) || defined(__SML_WBXML_TEXTTOKENS__) #define _TOKEN(id, wbxml, xml) (id), (wbxml), (xml) #else #define _TOKEN(id, wbxml, xml) (id), (wbxml), "" #endif #ifdef NOWSM //%%% removed const to prevent gcc "type qualifiers ignored on function return type" warning //const // without WSM, the tag table is a global read-only constant #endif TagPtr_t getTagTable(SmlPcdataExtension_t ext) { #ifndef NOWSM int mySize = 0; TagPtr_t _tmpTagPtr; SyncMLInfoPtr_t pGA = NULL; #else TagPtr_t _tmpTagPtr=NULL; #endif /* standard SyncML codepage */ static const Tag_t syncml[] = { { _TOKEN(TN_ADD, 0x05, "Add")}, { _TOKEN(TN_ALERT, 0x06, "Alert")}, { _TOKEN(TN_ARCHIVE, 0x07, "Archive")}, { _TOKEN(TN_ATOMIC, 0x08, "Atomic")}, { _TOKEN(TN_CHAL, 0x09, "Chal")}, { _TOKEN(TN_CMD, 0x0A, "Cmd")}, { _TOKEN(TN_CMDID, 0x0B, "CmdID")}, { _TOKEN(TN_CMDREF, 0x0C, "CmdRef")}, { _TOKEN(TN_COPY, 0x0D, "Copy")}, { _TOKEN(TN_CRED, 0x0E, "Cred")}, { _TOKEN(TN_DATA, 0x0F, "Data")}, { _TOKEN(TN_DELETE, 0x10, "Delete")}, { _TOKEN(TN_EXEC, 0x11, "Exec")}, { _TOKEN(TN_FINAL, 0x12, "Final")}, { _TOKEN(TN_GET, 0x13, "Get")}, { _TOKEN(TN_ITEM, 0x14, "Item")}, { _TOKEN(TN_LANG, 0x15, "Lang")}, { _TOKEN(TN_LOCNAME, 0x16, "LocName")}, { _TOKEN(TN_LOCURI, 0x17, "LocURI")}, { _TOKEN(TN_MAP, 0x18, "Map")}, { _TOKEN(TN_MAPITEM, 0x19, "MapItem")}, { _TOKEN(TN_META, 0x1A, "Meta")}, { _TOKEN(TN_MSGID, 0x1B, "MsgID")}, { _TOKEN(TN_MSGREF, 0x1C, "MsgRef")}, { _TOKEN(TN_NORESP, 0x1D, "NoResp")}, { _TOKEN(TN_NORESULTS, 0x1E, "NoResults")}, { _TOKEN(TN_PUT, 0x1F, "Put")}, { _TOKEN(TN_REPLACE, 0x20, "Replace")}, { _TOKEN(TN_RESPURI, 0x21, "RespURI")}, { _TOKEN(TN_RESULTS, 0x22, "Results")}, { _TOKEN(TN_SEARCH, 0x23, "Search")}, { _TOKEN(TN_SEQUENCE, 0x24, "Sequence")}, { _TOKEN(TN_SESSIONID, 0x25, "SessionID")}, { _TOKEN(TN_SFTDEL, 0x26, "SftDel")}, { _TOKEN(TN_SOURCE, 0x27, "Source")}, { _TOKEN(TN_SOURCEREF, 0x28, "SourceRef")}, { _TOKEN(TN_STATUS, 0x29, "Status")}, { _TOKEN(TN_SYNC, 0x2A, "Sync")}, { _TOKEN(TN_SYNCBODY, 0x2B, "SyncBody")}, { _TOKEN(TN_SYNCHDR, 0x2C, "SyncHdr")}, { _TOKEN(TN_SYNCML, 0x2D, "SyncML")}, { _TOKEN(TN_TARGET, 0x2E, "Target")}, { _TOKEN(TN_TARGETREF, 0x2F, "TargetRef")}, { _TOKEN(TN_VERSION, 0x31, "VerDTD")}, { _TOKEN(TN_PROTO, 0x32, "VerProto")}, /* SyncML DS 1.1 */ { _TOKEN(TN_NUMBEROFCHANGES, 0x33, "NumberOfChanges")}, { _TOKEN(TN_MOREDATA, 0x34, "MoreData")}, /* SyncML DS 1.2, Synthesis/luz 2005-08-17 */ { _TOKEN(TN_FIELD, 0x35, "Field")}, { _TOKEN(TN_FILTER, 0x36, "Filter")}, { _TOKEN(TN_RECORD, 0x37, "Record")}, { _TOKEN(TN_FILTERTYPE, 0x38, "FilterType")}, { _TOKEN(TN_SOURCEPARENT, 0x39, "SourceParent")}, { _TOKEN(TN_TARGETPARENT, 0x3A, "TargetParent")}, { _TOKEN(TN_MOVE, 0x3B, "Move")}, { _TOKEN(TN_CORRELATOR, 0x3C, "Correlator")}, /* End of table */ { _TOKEN(TN_UNDEF, 0x00, NULL)} }; #ifdef __USE_METINF__ static const Tag_t metinf[] = { { _TOKEN(TN_METINF_ANCHOR, 0x05, "Anchor")}, { _TOKEN(TN_METINF_EMI, 0x06, "EMI")}, { _TOKEN(TN_METINF_FORMAT, 0x07, "Format")}, { _TOKEN(TN_METINF_FREEID, 0x08, "FreeID")}, { _TOKEN(TN_METINF_FREEMEM, 0x09, "FreeMem")}, { _TOKEN(TN_METINF_LAST, 0x0A, "Last")}, { _TOKEN(TN_METINF_MARK, 0x0B, "Mark")}, { _TOKEN(TN_METINF_MAXMSGSIZE, 0x0C, "MaxMsgSize")}, { _TOKEN(TN_METINF_MEM, 0x0D, "Mem")}, { _TOKEN(TN_METINF_METINF, 0x0E, "MetInf")}, { _TOKEN(TN_METINF_NEXT, 0x0F, "Next")}, { _TOKEN(TN_METINF_NEXTNONCE, 0x10, "NextNonce")}, { _TOKEN(TN_METINF_SHAREDMEM, 0x11, "SharedMem")}, { _TOKEN(TN_METINF_SIZE, 0x12, "Size")}, { _TOKEN(TN_METINF_TYPE, 0x13, "Type")}, { _TOKEN(TN_METINF_VERSION, 0x14, "Version")}, /* SCTSTK - 18/03/2002, S.H. 2002-04-05 : SyncML 1.1 */ { _TOKEN(TN_METINF_MAXOBJSIZE, 0x15, "MaxObjSize")}, /* SyncML DS 1.2, Synthesis/luz 2005-08-17 */ { _TOKEN(TN_METINF_FIELDLEVEL, 0x16, "FieldLevel")}, /* End of table */ { _TOKEN(TN_UNDEF, 0x00, NULL)} }; #endif #ifdef __USE_DEVINF__ static const Tag_t devinf[] = { {_TOKEN(TN_DEVINF_CTCAP, 0x05, "CTCap")}, {_TOKEN(TN_DEVINF_CTTYPE, 0x06, "CTType")}, {_TOKEN(TN_DEVINF_DATASTORE, 0x07, "DataStore")}, {_TOKEN(TN_DEVINF_DATATYPE, 0x08, "DataType")}, {_TOKEN(TN_DEVINF_DEVID, 0x09, "DevID")}, {_TOKEN(TN_DEVINF_DEVINF, 0x0A, "DevInf")}, {_TOKEN(TN_DEVINF_DEVTYP, 0x0B, "DevTyp")}, {_TOKEN(TN_DEVINF_DISPLAYNAME, 0x0C, "DisplayName")}, {_TOKEN(TN_DEVINF_DSMEM, 0x0D, "DSMem")}, {_TOKEN(TN_DEVINF_EXT, 0x0E, "Ext")}, {_TOKEN(TN_DEVINF_FWV, 0x0F, "FwV")}, {_TOKEN(TN_DEVINF_HWV, 0x10, "HwV")}, {_TOKEN(TN_DEVINF_MAN, 0x11, "Man")}, {_TOKEN(TN_DEVINF_MAXGUIDSIZE, 0x12, "MaxGUIDSize")}, {_TOKEN(TN_DEVINF_MAXID, 0x13, "MaxID")}, {_TOKEN(TN_DEVINF_MAXMEM, 0x14, "MaxMem")}, {_TOKEN(TN_DEVINF_MOD, 0x15, "Mod")}, {_TOKEN(TN_DEVINF_OEM, 0x16, "OEM")}, {_TOKEN(TN_DEVINF_PARAMNAME, 0x17, "ParamName")}, {_TOKEN(TN_DEVINF_PROPNAME, 0x18, "PropName")}, {_TOKEN(TN_DEVINF_RX, 0x19, "Rx")}, {_TOKEN(TN_DEVINF_RXPREF, 0x1A, "Rx-Pref")}, {_TOKEN(TN_DEVINF_SHAREDMEM, 0x1B, "SharedMem")}, {_TOKEN(TN_DEVINF_SIZE, 0x1C, "Size")}, {_TOKEN(TN_DEVINF_SOURCEREF, 0x1D, "SourceRef")}, {_TOKEN(TN_DEVINF_SWV, 0x1E, "SwV")}, {_TOKEN(TN_DEVINF_SYNCCAP, 0x1F, "SyncCap")}, {_TOKEN(TN_DEVINF_SYNCTYPE, 0x20, "SyncType")}, {_TOKEN(TN_DEVINF_TX, 0x21, "Tx")}, {_TOKEN(TN_DEVINF_TXPREF, 0x22, "Tx-Pref")}, {_TOKEN(TN_DEVINF_VALENUM, 0x23, "ValEnum")}, {_TOKEN(TN_DEVINF_VERCT, 0x24, "VerCT")}, {_TOKEN(TN_DEVINF_VERDTD, 0x25, "VerDTD")}, {_TOKEN(TN_DEVINF_XNAM, 0x26, "XNam")}, {_TOKEN(TN_DEVINF_XVAL, 0x27, "XVal")}, /* %%% luz:2003-04-28 : added these SyncML 1.2 tags, they were missing */ {_TOKEN(TN_DEVINF_UTC, 0x28, "UTC")}, {_TOKEN(TN_DEVINF_NOFM, 0x29, "SupportNumberOfChanges")}, {_TOKEN(TN_DEVINF_LARGEOBJECT, 0x2A, "SupportLargeObjs")}, /* SyncML DS 1.2, Synthesis/luz 2005-08-17 */ {_TOKEN(TN_DEVINF_PROPERTY, 0x2B, "Property")}, {_TOKEN(TN_DEVINF_PROPPARAM, 0x2C, "PropParam")}, {_TOKEN(TN_DEVINF_MAXOCCUR, 0x2D, "MaxOccur")}, {_TOKEN(TN_DEVINF_NOTRUNCATE, 0x2E, "NoTruncate")}, {_TOKEN(TN_DEVINF_FILTERRX, 0x30, "Filter-Rx")}, {_TOKEN(TN_DEVINF_FILTERCAP, 0x31, "FilterCap")}, {_TOKEN(TN_DEVINF_FILTERKEYWORD,0x32, "FilterKeyword")}, {_TOKEN(TN_DEVINF_FIELDLEVEL, 0x33, "FieldLevel")}, {_TOKEN(TN_DEVINF_HIERARCHICAL, 0x34, "SupportHierarchicalSync")}, {_TOKEN(TN_DEVINF_MAXSIZE, 0x1C, "MaxSize")}, // alias for TN_DEVINF_SIZE (same WBXML, different XML) /* End of table */ {_TOKEN(TN_UNDEF, 0x00, NULL)} }; #endif #ifndef NOWSM _tmpTagPtr = NULL; pGA = mgrGetSyncMLAnchor(); if (pGA == NULL) return NULL; #endif /* get the correct codepage */ if (ext == SML_EXT_UNDEFINED) { #ifndef NOWSM _tmpTagPtr = pGA->tokTbl->SyncML; if (_tmpTagPtr == NULL) { mySize = sizeof(syncml); pGA->tokTbl->SyncML = (TagPtr_t)smlLibMalloc(mySize); if (pGA->tokTbl->SyncML == NULL) return NULL; smlLibMemcpy(pGA->tokTbl->SyncML, &syncml, mySize); _tmpTagPtr = pGA->tokTbl->SyncML; } #else _tmpTagPtr=(TagPtr_t)syncml; #endif } #ifdef __USE_METINF__ else if (ext == SML_EXT_METINF) { #ifndef NOWSM _tmpTagPtr = pGA->tokTbl->MetInf; if (_tmpTagPtr == NULL) { mySize = sizeof(metinf); pGA->tokTbl->MetInf = (TagPtr_t)smlLibMalloc(mySize); if (pGA->tokTbl->MetInf == NULL) return NULL; smlLibMemcpy(pGA->tokTbl->MetInf, &metinf, mySize); _tmpTagPtr = pGA->tokTbl->MetInf; } #else _tmpTagPtr=(TagPtr_t)metinf; #endif } #endif #ifdef __USE_DEVINF__ else if (ext == SML_EXT_DEVINF) { #ifndef NOWSM _tmpTagPtr = pGA->tokTbl->DevInf; if (_tmpTagPtr == NULL) { mySize = sizeof(devinf); pGA->tokTbl->DevInf = (TagPtr_t)smlLibMalloc(mySize); if (pGA->tokTbl->DevInf == NULL) return NULL; smlLibMemcpy(pGA->tokTbl->DevInf, &devinf, mySize); _tmpTagPtr = pGA->tokTbl->DevInf; } #else _tmpTagPtr=(TagPtr_t)devinf; #endif } #endif return _tmpTagPtr; } #undef _TOKEN // we don't need that macro any longer /** * Returns a tag string which belongs to a tag ID. * This function is needed for the XML encoding * * @pre valid tag ID, the tagSring has to be allocated * @post tag string is returned * @param tagID (IN) * the ID for the tag * @param tagString (IN/OUT) * allocated string into which the XML tag string will be written * @param ext (IN) * the PCDATA extension type * @return 0, if OK */ #ifdef __SML_XML__ Ret_t getTagString(XltTagID_t tagID, String_t tagString, SmlPcdataExtension_t ext) { // %%% luz 2005-11-11 : added retry loop to try MetInf as a fallback (workaround for ill-formed xml like in sync4j pda clients) do { int i = 0; TagPtr_t pTags = getTagTable(ext); if (pTags == NULL) { tagString[0] = '\0'; return SML_ERR_NOT_ENOUGH_SPACE; } while (((pTags+i)->id) != TN_UNDEF) { if (((pTags+i)->id) == tagID) { String_t _tmp = (pTags+i)->xml; smlLibStrcpy(tagString, _tmp); return SML_ERR_OK; } i++; } // tag not found if (ext==SML_EXT_METINF) break; // already tried with implicit or explicit metinf // try metinf implicitly for ill-formed xml like sync4j clients ext=SML_EXT_METINF; } while(TRUE); tagString[0] = '\0'; return SML_ERR_XLT_INVAL_PROTO_ELEM; } #endif /** * Returns a WBXML byte which belongs to a tag ID in a defined codepage. * This function is needed for the WBXML encoding * * @pre valid tag ID, valid code page * @post tag byte is returned * @param tagID (IN) * the ID for the tag * @param ext (IN) * code page group for the tag * @param pTagByte (IN) * the byte representation of the tag * @return 0, if OK */ Ret_t getTagByte(XltTagID_t tagID, SmlPcdataExtension_t ext, Byte_t *pTagByte) { int i = 0; TagPtr_t pTags = getTagTable(ext); if (pTags == NULL) { return SML_ERR_NOT_ENOUGH_SPACE; } while (((pTags+i)->id) != TN_UNDEF) { if (((pTags+i)->id) == tagID) { *pTagByte = (pTags+i)->wbxml; return SML_ERR_OK; } i++; } *pTagByte = 0; return SML_ERR_XLT_INVAL_PROTO_ELEM; } /** * Returns the code page which belongs to a certain PCDATA extension type. * * @pre valid PCDATA extension type * @post the code page is returned * @param ext (IN) * the PCDATA extension type * @return the code page */ Byte_t getCodePage(SmlPcdataExtension_t ext) { #ifdef __USE_METINF__ if (ext == SML_EXT_METINF) return 1; #endif #ifdef __USE_DEVINF__ if (ext == SML_EXT_DEVINF) return 0; #endif return 0; } /** * Returns the codepage which belongs to a certain tag ID * * @pre valid tag ID * @post the code page is returned * @param tagID (IN) * the ID of the tag * @param pExt (IN) * the codepage/extention of the tag * @return 0, if OK */ Ret_t getExtById(XltTagID_t tagID, SmlPcdataExtension_t *pExt) { int i = 0; SmlPcdataExtension_t ext; /* Iterate over all defined extensions to find the corresponding TAG. * Empty extensions, e.g. not defined numbers will be skipped. */ for (ext = SML_EXT_UNDEFINED; ext < SML_EXT_LAST; ext++) { TagPtr_t pTags = getTagTable(ext); if (pTags == NULL) { continue; /* skip empty codepage */ } i = 0; while (((pTags+i)->id) != TN_UNDEF) { if (((pTags+i)->id) == tagID){ *pExt = ext; return SML_ERR_OK; } i++; } } /* tag not found in any extension */ *pExt = (SmlPcdataExtension_t)255; return SML_ERR_XLT_INVAL_PROTO_ELEM; } /** * Returns the tag ID which belongs to a tag string in a certain codepage * * @pre valid tag string, valid code page * @post tag id is returned * @param tag (IN) * the string representation of the tag * @param ext (IN) * code page group for the tag * @param pTagID (IN) * the tag id of the tag * @return 0, if OK */ Ret_t getTagIDByStringAndExt(String_t tag, SmlPcdataExtension_t ext, XltTagID_t *pTagID) { int i = 0; TagPtr_t pTags = getTagTable(ext); if (pTags == NULL) { return SML_ERR_NOT_ENOUGH_SPACE; } for (i=0;((pTags+i)->id) != TN_UNDEF; i++) { if (*(pTags+i)->xml != *tag) continue; // if the first char doesn't match we skip the strcmp to speed things up if (smlLibStrcmp(((pTags+i)->xml), tag) == 0) { *pTagID = (pTags+i)->id; return SML_ERR_OK; } } *pTagID = TN_UNDEF; return SML_ERR_XLT_INVAL_PROTO_ELEM; } /** * Returns the tag ID which belongs to a tag byte in a certain codepage * * @pre valid tag byte, valid code page * @post tag id is returned * @param tag (IN) * the byte representation of the tag * @param ext (IN) * code page group for the tag * @param pTagID (IN) * the tag id of the tag * @return 0, if OK */ Ret_t getTagIDByByteAndExt(Byte_t tag, SmlPcdataExtension_t ext, XltTagID_t *pTagID) { int i = 0; TagPtr_t pTags = getTagTable(ext); if (pTags == NULL) { return SML_ERR_NOT_ENOUGH_SPACE; } while (((pTags+i)->id) != TN_UNDEF) { if (((pTags+i)->wbxml) == tag) { *pTagID = (pTags+i)->id; return SML_ERR_OK; } i++; } *pTagID = TN_UNDEF; return SML_ERR_XLT_INVAL_PROTO_ELEM; } #ifdef __SML_XML__ /** * Returns the tag ID which belongs to a tag string in a certain namespace * * @pre valid tag string, valid namespace * @post tag id is returned * @param tag (IN) * the string representation of the tag * @param ns (IN) * namespace group for the tag * @param pTagID (IN) * the tag id of the tag * @return 0, if OK */ Ret_t getTagIDByStringAndNamespace(String_t tag, String_t ns, XltTagID_t *pTagID) { int i = 0; TagPtr_t pTags = getTagTable(getExtByName(ns)); if (pTags == NULL) { return SML_ERR_NOT_ENOUGH_SPACE; } while (((pTags+i)->id) != TN_UNDEF) { if ((smlLibStrcmp(((pTags+i)->xml), tag) == 0)) { *pTagID = (pTags+i)->id; return SML_ERR_OK; } i++; } *pTagID = TN_UNDEF; return SML_ERR_XLT_INVAL_PROTO_ELEM; } #endif libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/xlt/all/xlttags.h000077500000000000000000000135361226375725500242510ustar00rootroot00000000000000/** * @file * Definition of WBXML/XML tags for the en-/decoder * * @target_system all * @target_os all */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ /*************************************************************************/ /* Definitions */ /*************************************************************************/ #ifndef _XLT_TAGS_H #define _XLT_TAGS_H #include #include #define XML_MAX_TAGLEN 35 #ifdef __cplusplus extern "C" { #endif // Tag IDs typedef enum { TN_UNDEF = 0, TN_ADD, TN_ALERT, TN_ARCHIVE, TN_ATOMIC, TN_ATOMIC_END, /* 5 */ TN_CHAL, TN_CMD, TN_CMDID, TN_CMDREF, TN_COPY, /* 10 */ TN_CRED, TN_DATA, TN_DELETE, TN_EXEC, TN_FINAL, /* 15 */ TN_GET, TN_ITEM, TN_LANG, TN_LOCNAME, TN_LOCURI, /* 20 */ TN_MAP, TN_MAPITEM, TN_META, TN_MSGID, TN_MSGREF, /* 25 */ TN_NORESP, TN_NORESULTS, TN_PUT, TN_REPLACE, TN_RESPURI, /* 30 */ TN_RESULTS, TN_SEARCH, TN_SEQUENCE, TN_SEQUENCE_END, TN_SESSIONID, /* 35 */ TN_SFTDEL, TN_SOURCE, TN_SOURCEREF, TN_STATUS, TN_SYNC, /* 40 */ TN_SYNCBODY, TN_SYNCHDR, TN_SYNCML, TN_SYNC_END, TN_TARGET, /* 45 */ TN_TARGETREF, TN_VERSION, TN_PROTO, TN_METINF_ANCHOR, TN_METINF_EMI, /* 50 */ TN_METINF_FORMAT, TN_METINF_FREEID, TN_METINF_FREEMEM, TN_METINF_LAST, TN_METINF_MARK, /* 55 */ TN_METINF_MAXMSGSIZE, TN_METINF_MEM, TN_METINF_METINF, TN_METINF_NEXT, TN_METINF_NEXTNONCE, /* 60 */ TN_METINF_SHAREDMEM, TN_METINF_SIZE, TN_METINF_TYPE, TN_METINF_VERSION, TN_DEVINF_CTCAP, /* 65 */ TN_DEVINF_CTTYPE, TN_DEVINF_DATASTORE, TN_DEVINF_DATATYPE, TN_DEVINF_DEVID, TN_DEVINF_DEVINF, /* 70 */ TN_DEVINF_DEVTYP, TN_DEVINF_DISPLAYNAME, TN_DEVINF_DSMEM, TN_DEVINF_EXT, TN_DEVINF_FWV, /* 75 */ TN_DEVINF_HWV, TN_DEVINF_MAN, TN_DEVINF_MAXGUIDSIZE, TN_DEVINF_MAXID, TN_DEVINF_MAXMEM, /* 80 */ TN_DEVINF_MOD, TN_DEVINF_OEM, TN_DEVINF_PARAMNAME, TN_DEVINF_PROPNAME, TN_DEVINF_RX, /* 85 */ TN_DEVINF_RXPREF, TN_DEVINF_SHAREDMEM, TN_DEVINF_SIZE, TN_DEVINF_SOURCEREF, TN_DEVINF_SWV, /* 90 */ TN_DEVINF_SYNCCAP, TN_DEVINF_SYNCTYPE, TN_DEVINF_TX, TN_DEVINF_TXPREF, TN_DEVINF_VALENUM, /* 95 */ TN_DEVINF_VERCT, TN_DEVINF_VERDTD, TN_DEVINF_XNAM, TN_DEVINF_XVAL, /* SCTSTK - 18/03/2002, S.H. 2002-04-05 : SyncML 1.1 */ TN_NUMBEROFCHANGES, /* 100 */ TN_MOREDATA, TN_METINF_MAXOBJSIZE, TN_DEVINF_UTC, TN_DEVINF_NOFM, TN_DEVINF_LARGEOBJECT, /* SyncML DS 1.2, Synthesis/luz 2005-08-17 */ TN_FIELD, TN_FILTER, TN_RECORD, TN_FILTERTYPE, TN_SOURCEPARENT, TN_TARGETPARENT, TN_MOVE, TN_CORRELATOR, TN_METINF_FIELDLEVEL, TN_DEVINF_PROPERTY, TN_DEVINF_PROPPARAM, TN_DEVINF_MAXOCCUR, TN_DEVINF_NOTRUNCATE, TN_DEVINF_FILTERRX, TN_DEVINF_FILTERCAP, TN_DEVINF_FILTERKEYWORD, TN_DEVINF_FIELDLEVEL, TN_DEVINF_HIERARCHICAL, TN_DEVINF_MAXSIZE // alias for TN_DEVINF_SIZE (same WBXML, different XML) } XltTagID_t; extern const char * const SyncMLNamespaces[SML_NUM_VERS]; typedef struct Dtd_s { String_t name; SmlPcdataExtension_t ext; } Dtd_t, *DtdPtr_t; Ret_t getTagString(XltTagID_t tagID, String_t tagString, SmlPcdataExtension_t ext); #ifdef __SML_WBXML__ Ret_t getTagByte(XltTagID_t tagID, SmlPcdataExtension_t ext, Byte_t *tagByte); #endif Byte_t getCodePage(SmlPcdataExtension_t ext); Ret_t getTagIDByStringAndExt(String_t tag, SmlPcdataExtension_t ext, XltTagID_t *pTagID); #ifdef __SML_WBXML__ Ret_t getTagIDByByteAndExt(Byte_t tag, SmlPcdataExtension_t ext, XltTagID_t *pTagID); #endif #ifdef __SML_XML__ Ret_t getTagIDByStringAndNamespace(String_t tag, String_t ns, XltTagID_t *pTagID); #endif Ret_t getExtById(XltTagID_t tagID, SmlPcdataExtension_t *pExt); // %%% luz:2003-07-31: added vers parameter Ret_t getExtName(SmlPcdataExtension_t ext, String_t *name, SmlVersion_t vers); Ret_t getTagIDByStringAndExt(String_t tag, SmlPcdataExtension_t ext, XltTagID_t *pTagID); SmlPcdataExtension_t getExtByName(String_t ns); #ifdef __cplusplus } #endif #endif libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/xlt/all/xlttagtbl.h000077500000000000000000000120531226375725500245610ustar00rootroot00000000000000/** * @file * Definition of en-/decoder tagtable data * * @target_system all * @target_os all */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ #ifndef _XLT_TAGTBL_H #define _XLT_TAGTBL_H /*************************************************************************/ /* Definitions */ /*************************************************************************/ #include "xlttags.h" #include "xltdec.h" #include "xltdeccom.h" typedef struct Tag_s { XltTagID_t id; Byte_t wbxml; String_t xml; } Tag_t, *TagPtr_t; /** * buildXXX * * These functions each decode one single SyncML element starting at the * current position within the SyncML document. Child elements are build * recursively. * The functions check that the pointer to the memory structures are * NULL when called and return an error otherwise. This will only happen * when a SyncML element contains several child elements of the same type * for which this is not allowed according to the SyncML DTD; e.g. a * SyncHdr with two or more MsgID tags. Items and other list types * are handled separately by the appendXXXList functions (see below). * * @pre ppElem is NULL * The scanner's current token is the start tag (may be * empty) of the SyncML element to be decoded. * @post The scanner's current token is the end tag (or empty * start tag) of the SyncML element to be decoded. */ /* implemented in xltdec.c! */ Ret_t buildAlert(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem); #if (defined ATOMIC_RECEIVE || defined SEQUENCE_RECEIVE) Ret_t buildAtomOrSeq(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem); #endif Ret_t buildChal(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem); Ret_t buildCred(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem); Ret_t buildDelete(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem); Ret_t buildExec(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem); Ret_t buildRecordFieldFilter(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem); Ret_t buildFilter(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem); Ret_t buildGenericCmd(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem); Ret_t buildItem(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem); Ret_t buildMap(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem); Ret_t buildMapItem(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem); Ret_t buildEmptyTag(XltDecoderPtr_t pDecoder); Ret_t buildPCData(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem); Ret_t buildPCDataList(XltDecoderPtr_t pDecoder, VoidPtr_t *ppPCData); Ret_t buildPutOrGet(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem); Ret_t buildResults(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem); #ifdef SEARCH_RECEIVE Ret_t buildSearch(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem); #endif Ret_t buildStatus(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem); Ret_t buildSync(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem); Ret_t buildSyncHdr(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem); Ret_t buildTargetOrSource(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem); Ret_t buildTargetOrSourceParent(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem); #ifdef NOWSM //%%% removed const to prevent gcc "type qualifiers ignored on function return type" warning //const // without WSM, the tag table is a global read-only constant #endif TagPtr_t getTagTable(SmlPcdataExtension_t cp); #endif /* _XLT_TAGTBL_H */ libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/xlt/all/xltutilstack.c000077500000000000000000000151211226375725500253010ustar00rootroot00000000000000/** * @file * XLT Decoder Stack * * @target_system all * @target_os all * @description A simple array-based stack implementation. */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ /*************************************************************************/ /* Definitions */ /*************************************************************************/ #include "syncml_tk_prefix_file.h" // %%% luz: needed for precompiled headers in eVC++ #include "xltdeccom.h" #include "xltutilstack.h" #include #include struct ArrayStack_s; typedef struct ArrayStack_s *ArrayStackPtr_t, ArrayStack_t; struct ArrayStack_s { /* public */ Ret_t (*top)(const XltUtilStackPtr_t, XltUtilStackItem_t *); Ret_t (*pop)(XltUtilStackPtr_t, XltUtilStackItem_t *); Ret_t (*push)(XltUtilStackPtr_t, const XltUtilStackItem_t); Ret_t (*destroy)(XltUtilStackPtr_t); /* private */ Long_t topidx; // index of the top of the stack Long_t size; // size of the stack (multiple of chunksize) Long_t chunksize; // size of memory chunks allocated at a time XltUtilStackItem_t *array; // the stack itself }; static Ret_t _top(const XltUtilStackPtr_t, XltUtilStackItem_t *); static Ret_t _pop(XltUtilStackPtr_t, XltUtilStackItem_t *); static Ret_t _push(XltUtilStackPtr_t, const XltUtilStackItem_t); static Ret_t _destroy(XltUtilStackPtr_t); /*************************************************************************/ /* External Functions */ /*************************************************************************/ Ret_t xltUtilCreateStack(XltUtilStackPtr_t *ppStack, const Long_t size) { ArrayStackPtr_t pStack; if (size <= 0) return SML_ERR_WRONG_PARAM; if ((pStack = (ArrayStackPtr_t)smlLibMalloc(sizeof(ArrayStack_t))) == NULL) { *ppStack = NULL; return SML_ERR_NOT_ENOUGH_SPACE; } pStack->top = _top; pStack->pop = _pop; pStack->push = _push; pStack->destroy = _destroy; pStack->topidx = -1; pStack->size = size; pStack->chunksize = size; pStack->array = NULL; if ((pStack->array = (XltUtilStackItem_t*)smlLibMalloc(size * sizeof(XltUtilStackItem_t))) == NULL) { *ppStack = NULL; smlLibFree(pStack); return SML_ERR_NOT_ENOUGH_SPACE; } *ppStack = (XltUtilStackPtr_t)pStack; return SML_ERR_OK; } /*************************************************************************/ /* Internal Functions */ /*************************************************************************/ static Ret_t _top(const XltUtilStackPtr_t pStack, XltUtilStackItem_t *itemPtr) { ArrayStackPtr_t pStackPriv = (ArrayStackPtr_t)pStack; if (pStackPriv->topidx == -1) return SML_ERR_WRONG_USAGE; *itemPtr = pStackPriv->array[pStackPriv->topidx]; return SML_ERR_OK; } static Ret_t _pop(XltUtilStackPtr_t pStack, XltUtilStackItem_t *itemPtr) { ArrayStackPtr_t pStackPriv = (ArrayStackPtr_t)pStack; XltUtilStackItem_t item; if (pStackPriv->topidx == -1) return SML_ERR_WRONG_USAGE; item = pStackPriv->array[pStackPriv->topidx]; pStackPriv->topidx--; if ((pStackPriv->topidx >= 0) && (pStackPriv->topidx < pStackPriv->size - pStackPriv->chunksize)) { Long_t newsize; XltUtilStackItem_t *newarray; newsize = pStackPriv->size - pStackPriv->chunksize; if ((newarray = (XltUtilStackItem_t*)smlLibRealloc(pStackPriv->array, newsize * sizeof(XltUtilStackItem_t))) != NULL) { pStackPriv->size = newsize; pStackPriv->array = newarray; } else { return SML_ERR_NOT_ENOUGH_SPACE; } } *itemPtr = item; return SML_ERR_OK; } static Ret_t _push(XltUtilStackPtr_t pStack, const XltUtilStackItem_t item) { ArrayStackPtr_t pStackPriv = (ArrayStackPtr_t)pStack; if (pStackPriv->topidx == pStackPriv->size - 1) { Long_t newsize; XltUtilStackItem_t *newarray; newsize = pStackPriv->size + pStackPriv->chunksize; if ((newarray = (XltUtilStackItem_t*)smlLibRealloc(pStackPriv->array, newsize * sizeof(XltUtilStackItem_t))) != NULL) { pStackPriv->size = newsize; pStackPriv->array = newarray; } else { return SML_ERR_NOT_ENOUGH_SPACE; } } pStackPriv->topidx++; pStackPriv->array[pStackPriv->topidx] = item; return SML_ERR_OK; } static Ret_t _destroy(XltUtilStackPtr_t pStack) { ArrayStackPtr_t pStackPriv; if (pStack == NULL) return SML_ERR_OK; pStackPriv = (ArrayStackPtr_t)pStack; smlLibFree(pStackPriv->array); smlLibFree(pStackPriv); return SML_ERR_OK; } libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/xlt/all/xltutilstack.h000077500000000000000000000121241226375725500253060ustar00rootroot00000000000000/** * @file * XLT Decoder Util * * @target_system all * @target_os all * @description Header file for a simple stack implementation used * by the WBXML scanner and the SyncML parser. */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ /*************************************************************************/ /* Definitions */ /*************************************************************************/ #ifndef _XLT_UTIL_STACK_H #define _XLT_UTIL_STACK_H #include "xlttags.h" #include /** type for stack elements */ typedef XltTagID_t XltUtilStackItem_t; /** @copydoc XltUtilStack_s */ typedef struct XltUtilStack_s *XltUtilStackPtr_t, XltUtilStack_t; /** * XLTUtilStack interface * * Like the WBXML/XML scanner, this stack implementation tries to emulate * an object-oriented interface. It consist of one stack structure that * contains the public methods and attributes and another private stack * structure that is not visible to the users of the stack. A stack object * has the following public methods: */ struct XltUtilStack_s { /** * Returns the top element of the stack. * * @pre the stack contains at least one element * @param XltUtilStackPtr_t (IN) * the stack * @param XltUtilStackItem_t (OUT) * the top element of the stack * @return - SML_ERR_WRONG_USAGE, if the stack is empty * - SML_ERR_OK, else */ Ret_t (*top)(const XltUtilStackPtr_t, XltUtilStackItem_t *); /** * Returns the top element and takes it off the stack. * * @pre the stack contains at least one element * @post the top element of the stack is removed * @param XltUtilStackPtr_t (IN/OUT) * the stack * @param XltUtilStackItem_t (OUT) * the top element of the stack * @return - SML_ERR_WRONG_USAGE, if the stack is empty * - SML_ERR_NOT_ENOUGH_SPACE, if memory reallocation failed * - SML_ERR_OK, else */ Ret_t (*pop)(XltUtilStackPtr_t, XltUtilStackItem_t *); /** * Put a new element on top of the stack. * * @post popping the stack yields the same stack as before the push * @param XltUtilStackPtr_t (IN/OUT) * the stack * @param XltUtilStackItem_t (IN) * the new stack element * @return - SML_ERR_NOT_ENOUGH_SPACE, if memory reallocation failed * - SML_ERR_OK, else */ Ret_t (*push)(XltUtilStackPtr_t, const XltUtilStackItem_t); /** * Free the memory used by the stack. * * @param XltUtilStackPtr_t (IN/OUT) * the stack * @return - SML_ERR_OK */ Ret_t (*destroy)(XltUtilStackPtr_t); }; /** * Creates a new stack. The size parameter indicates for how many elements * memory should be allocated initially. This does _not_ mean that you can * not push more than that many element onto the stack - in that case * memory for another size elements is allocated. * * @post the stack pointer points to a new, empty stack * @param ppStack (OUT) * a new stack * @param size (IN) * the initial size of the stack * @return - SML_ERR_NOT_ENOUGH_SPACE, if memory allocation failed * - SML_ERR_OK, else */ Ret_t xltUtilCreateStack(XltUtilStackPtr_t *ppStack, const Long_t size); #endif libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/xlt/inc/000077500000000000000000000000001226375725500224005ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/xlt/inc/xltdec.h000077500000000000000000000174261226375725500240510ustar00rootroot00000000000000/** * @file * Interface for the XLT Decoder component. * * @target_system all * @target_os all * @description Interface for the WBXML and XML decoder component. */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ /*************************************************************************/ /* Definitions */ /*************************************************************************/ #ifndef _XLT_DEC_H #define _XLT_DEC_H #include #include #include #include "xltdeccom.h" #include "xltutilstack.h" #ifdef __cplusplus extern "C" { #endif /** * Better parsing error reporting when used within Synthesis SyncML engine * added 2006-11-02 by luz@synthesis.ch */ #ifdef SYDEBUG #include "sysync_debug.h" Ret_t show_decode_error(Ret_t aRc, XltDecScannerPtr_t aScanner, char *aRoutineName); #define SML_DECODEERROR(e,sc,n) show_decode_error(e,(XltDecScannerPtr_t)sc,n) #else #define SML_DECODEERROR(e,sc,n) (e) #endif /** * The XLT Decoder Interface consists of a single XltDecoder "object" * (struct) and an creation/initialization function. The XltDecoder * object contains all "public" methods and data structures. The first * parameter for any public method is the object of which the method is * called. */ typedef struct XltDecoder_s { /** * Character set used in the document - this is the MIBEnum value assigned * by the IANA for the character encoding, e.g. "3" for US-ASCII. */ Long_t charset; /** * Name of the character set, e.g. "US-ASCII" - valid * only when charset == 0. */ String_t charsetStr; /** * Indicates whether the decoder has reached the end of the buffer during * the last call to xltDecNext. */ Flag_t finished; Boolean_t final; /** * Pointer to the scanner status object used by this decoder. The scanner * will be created during the initialization of the decoder as either a XML * or WBXML scanner. */ XltDecScannerPtr_t scanner; /** * The decoder uses an internal stack to check that for every start tag * there is a corresponding end tag. */ XltUtilStackPtr_t tagstack; } XltDecoder_t, *XltDecoderPtr_t; /** * Initializes a new decoder object. This function allocates memory for the * decoder structure which has to be freed by a call to the decoder's * terminate method when the decoder is not needed anymore. As part of the * initialization the decoder begins decoding the SyncML document to find * the SyncHdr element. * * @pre ppDecoder is NULL * ppBufPos * @post ppDecoder points to an initialized decoder status object * @param enc (IN) * the document encoding (WBXML or XML) * @param pBufEnd (IN) * pointer to the end of the buffer which contains the document * @param ppBufPos (IN/OUT) * pointer to the current position within the buffer * @param ppDecoder (OUT) * the decoder status object * @param ppSyncHdr (OUT) * the SyncHdr element * @return * - SML_ERR_OK, if the decoder could be created and the * SmlSyncHdr was found * - else error code */ Ret_t xltDecInit(const SmlEncoding_t enc, const MemPtr_t pBufEnd, MemPtr_t *ppBufPos, XltDecoderPtr_t *ppDecoder, SmlSyncHdrPtr_t *ppSyncHdr) XLT_FUNC; /** * Decodes the next protocol element of the given SyncML document. This * function creates the data structures detailed in the SMLDtd header file. * It is the responsibility of the SyncML client application to free the * allocated memory after it is done processing the data. * This function sets the decoder's finished flag if no protocol element was * found. In that case pPE is set to SML_PE_UNDEF and pContent is NULL. * * @pre pDecoder points to a decoder status object initialized by xltDecInit * @post pPE and pContent describe the next valid protocol * element within the SyncML document OR * the finished flag of the decoder status object is set * @param pBufEnd (IN) * pointer to the end of the buffer * @param pDecoder (IN/OUT) * the decoder status object * @param ppBufPos (IN/OUT) * pointer to the current position within the * buffer before and after the call to xltDecNext * @param pPE (OUT) * the type of the protocol element (e.g. SML_PE_ADD) * @param pContent (OUT) * the data structure for the p.e. cast * (e.g. AddPtr_t) to a void pointer * @return * - SML_ERR_OK, if a valid protocol element was found * or if decoder reached the end of the buffer * - else error code showing where the parsing failed */ Ret_t xltDecNext(XltDecoderPtr_t pDecoder, const MemPtr_t pBufEnd, MemPtr_t *ppBufPos, SmlProtoElement_t *pPE, VoidPtr_t *pContent) XLT_FUNC; /** * Frees the memory allocated by the decoder. * * @pre pDecoder points to a decoder status object initialized by xltDecInit * @post all memory allocated by the decoder status object is freed * @param pDecoder (IN) * the decoder * @return * - SML_ERR_OK, if the memory could be freed * - else error code */ Ret_t xltDecTerminate(XltDecoderPtr_t pDecoder) XLT_FUNC; Ret_t xltDecReset(XltDecoderPtr_t pDecoder) XLT_FUNC; /* T.K. moved here from xltdec.c for use in sub-DTD parsing */ #define IS_START(tok) ((tok)->type == TOK_TAG_START) #define IS_END(tok) ((tok)->type == TOK_TAG_END) #define IS_EMPTY(tok) ((tok)->type == TOK_TAG_EMPTY) #define IS_TAG(tok) (IS_START(tok) || IS_EMPTY(tok) || IS_END(tok)) #define IS_START_OR_EMPTY(tok) (IS_START(tok) || IS_EMPTY(tok)) #define IS_CONTENT(tok) ((tok)->type == TOK_CONT) /** * just wrapper around the scanner's * nextTok methods that do some error checking. */ Ret_t nextToken(XltDecoderPtr_t pDecoder) XLT_FUNC; /** * just wrapper around the scanner's * pushTok methods that do some error checking. */ Ret_t discardToken(XltDecoderPtr_t pDecoder) XLT_FUNC; /* eof xltdec.c stuff */ #ifdef __cplusplus } #endif #endif libsynthesis-3.4.0.47.1/src/syncml_tk/src/sml/xlt/inc/xltenc.h000077500000000000000000000100761226375725500240550ustar00rootroot00000000000000/** * @file * Encoder header file * * @target_system All * @target_os All */ /* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * */ /*************************************************************************/ /* Definitions */ /*************************************************************************/ #ifndef _XLT_ENC_H #define _XLT_ENC_H #include #include #include #include #include #ifdef __cplusplus extern "C" { #endif /** Type for storing encoder information */ typedef struct XltEncoder_s { SmlEncoding_t enc; SmlVersion_t vers; // %%% luz 2003-07-31: added SyncML version here SmlPcdataExtension_t cur_ext; SmlPcdataExtension_t last_ext; Boolean_t final; XltSpaceEvaluationPtr_t space_evaluation; MemSize_t end_tag_size; } XltEncoder_t, *XltEncoderPtr_t; Ret_t xltEncInit(SmlEncoding_t enc, const SmlSyncHdrPtr_t pHeader, const MemPtr_t pBufEnd, MemPtr_t *ppBufPos, XltEncoderPtr_t *ppEncoder, SmlVersion_t vers) XLT_FUNC; Ret_t xltEncAppend(const XltEncoderPtr_t pEncoder, SmlProtoElement_t pe, const MemPtr_t pBufEnd, const VoidPtr_t pContent, MemPtr_t *ppBufPos) XLT_FUNC; Ret_t xltEncTerminate(const XltEncoderPtr_t pEncoder, const MemPtr_t pBufEnd, MemPtr_t *ppBufPos) XLT_FUNC; Ret_t xltEncReset(XltEncoderPtr_t pEncoder) XLT_FUNC; Ret_t xltGenerateTag(XltTagID_t, XltTagType_t, SmlEncoding_t, BufferMgmtPtr_t, SmlPcdataExtension_t) XLT_FUNC; Ret_t xltStartEvaluation(XltEncoderPtr_t pEncoder) XLT_FUNC; Ret_t xltEndEvaluation(InstanceID_t id, XltEncoderPtr_t pEncoder, MemSize_t *freemem) XLT_FUNC; Ret_t xltEncBlock(XltTagID_t tagId, XltRO_t reqOptFlag, const VoidPtr_t pContent, SmlEncoding_t enc, BufferMgmtPtr_t pBufMgr, SmlPcdataExtension_t attFlag) XLT_FUNC; Ret_t xltBuildExtention(SmlPcdataExtension_t extId, XltRO_t reqOptFlag, VoidPtr_t pContent, SmlEncoding_t enc, BufferMgmtPtr_t pBufMgr) XLT_FUNC; Ret_t xltEncPcdata(XltTagID_t tagId, XltRO_t reqOptFlag, const VoidPtr_t pContent, SmlEncoding_t enc, BufferMgmtPtr_t pBufMgr, SmlPcdataExtension_t attFlag) XLT_FUNC; Ret_t subdtdEncWBXML(XltTagID_t tagId, XltRO_t reqOptFlag, const VoidPtr_t pContent, SmlEncoding_t enc, BufferMgmtPtr_t pBufMgr, SmlPcdataExtension_t attFlag) XLT_FUNC; #ifdef __cplusplus } #endif #endif libsynthesis-3.4.0.47.1/src/syncml_tk_prefix_file.h000077500000000000000000000006361226375725500221730ustar00rootroot00000000000000// dummy prefix file, used for CW based projects which do // not need the prefix file here, but in the target settings #ifdef _MSC_VER #error "this is not the right syncml_tk_prefix_file.h -> reorder include paths such that project-specific prefix is used!" #endif #ifdef __PALM_OS__ #error "this is not the right syncml_tk_prefix_file.h -> reorder access paths such that project-specific prefix is used!" #endif libsynthesis-3.4.0.47.1/src/synthesis-linker.map000066400000000000000000000005311226375725500214440ustar00rootroot00000000000000VER_1.0 { global: SySync_*ConnectEngine; SySync_*ConnectEngineS; SySync_*DisconnectEngine; SySync_*ConsolePrintf; SySync_CondTimedWait; SySync_CondWait; extern "C++" { sysync::DataConversion*; sysync::SySyncDebugPuts*; }; local: *; }; libsynthesis-3.4.0.47.1/src/sysync/000077500000000000000000000000001226375725500167635ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/sysync/binfilebase.cpp000077500000000000000000000316641226375725500217470ustar00rootroot00000000000000/** * @File binfile.cpp * * @Author Lukas Zeller (luz@plan44.ch) * * @brief TBinFileBase * Simple record based binary file storage class * * Copyright (c) 2003-2011 by Synthesis AG + plan44.ch * * @Date 2006-03-28 : luz : extracted into separate file from TBinfileImplDS */ #include "prefix_file.h" #include "binfilebase.h" namespace sysync { // TBinFileBase // ============ // constructor TBinFileBase::TBinFileBase() : fDestructed(false) { fBinFileHeader.idword=0; fBinFileHeader.version=0; fBinFileHeader.headersize=sizeof(TBinFileHeader); fBinFileHeader.recordsize=0; fBinFileHeader.numrecords=0; fBinFileHeader.allocatedrecords=0; fBinFileHeader.uniquerecordid=0; fHeaderDirty=false; fExtraHeaderDirty=false; fExtraHeaderP=NULL; fExtraHeaderSize=0; fFoundVersion=0; } // TBinFileBase::TBinFileBase // destructor TBinFileBase::~TBinFileBase() { destruct(); } // TBinFileBase::~TBinFileBase void TBinFileBase::destruct(void) { if (!fDestructed) doDestruct(); fDestructed=true; } // TBinFileBase::destruct void TBinFileBase::doDestruct(void) { // make sure files are closed close(); } // TBinFileBase::doDestruct // - set path to binary file containing the database void TBinFileBase::setFileInfo(const char *aFilename, uInt32 aVersion, uInt32 aIdWord, uInt32 aExpectedRecordSize) { close(); fFilename=aFilename; fIdWord=aIdWord; fVersion=aVersion; fExpectedRecordSize=aExpectedRecordSize; } // TBinFileBase::setFileInfo // - copy entire binfile 1:1 without looking at header bferr TBinFileBase::createAsCopyFrom(TBinFileBase &aSourceBinFile, bool aOverwrite) { // make sure it is closed first close(); aSourceBinFile.close(); // open original if (!aSourceBinFile.platformOpenFile(aSourceBinFile.fFilename.c_str(), fopm_update)) return BFE_NOTFOUND; // get original header into my own fBinFileHeader aSourceBinFile.platformSeekFile(0); if (!aSourceBinFile.platformReadFile(&fBinFileHeader,sizeof(fBinFileHeader))) { aSourceBinFile.platformCloseFile(); return BFE_BADSTRUCT; } // calculate file size uInt32 filesize = fBinFileHeader.headersize + fBinFileHeader.recordsize * fBinFileHeader.allocatedrecords; // create output file if (!aOverwrite) { // first test for existing file if (platformOpenFile(fFilename.c_str(), fopm_update)) { // already exists, don't copy platformCloseFile(); // close existing file aSourceBinFile.platformCloseFile(); // close input return BFE_EXISTS; // already exists, don't overwrite } } if (!platformOpenFile(fFilename.c_str(), fopm_create)) { aSourceBinFile.platformCloseFile(); // close input return BFE_IOERR; } // allocate buffer to read entire file void *copybuffer = malloc(filesize); if (!copybuffer) { aSourceBinFile.platformCloseFile(); // close input platformCloseFile(); // close output return BFE_MEMORY; // fatal } // read everything from old file aSourceBinFile.platformSeekFile(0); if (!aSourceBinFile.platformReadFile(copybuffer,filesize)) { aSourceBinFile.platformCloseFile(); // close input platformCloseFile(); // close output return BFE_IOERR; } aSourceBinFile.platformCloseFile(); // done with input file // write everything out to new file if (!platformWriteFile(copybuffer,filesize)) { platformCloseFile(); // close output return BFE_IOERR; } // return memory free(copybuffer); // close output platformCloseFile(); // done ok return BFE_OK; } // - try to open existing DB file according to params set with setFileInfo bferr TBinFileBase::open(uInt32 aExtraHeadersize, void *aExtraHeaderP, TUpdateFunc aUpdateFunc) { // make sure it is closed first close(); // save extra header info fExtraHeaderSize=aExtraHeadersize; fExtraHeaderP=aExtraHeaderP; // try to open file for (binary) update if (!platformOpenFile(fFilename.c_str(),fopm_update)) return BFE_NOTFOUND; // read header fHeaderDirty=false; platformSeekFile(0); if (!platformReadFile(&fBinFileHeader,sizeof(fBinFileHeader))) { close(); return BFE_BADSTRUCT; } // check type and Version if (fBinFileHeader.idword!=fIdWord) { close(); return BFE_BADTYPE; } // remember the version we found when trying to open fFoundVersion = fBinFileHeader.version; // check need for upgrade if (fBinFileHeader.version!=fVersion) { // try to update file if update-func is provided if (aUpdateFunc) { // check if we can update (no data provided for update) uInt32 newrecordsize=aUpdateFunc(fFoundVersion,fVersion,NULL,NULL,0); if (newrecordsize) { // we can update from current to requested version // - allocate buffer for all records uInt32 numrecords = fBinFileHeader.numrecords; uInt32 oldrecordsize = fBinFileHeader.recordsize; void *oldrecords = malloc(numrecords * oldrecordsize); if (!oldrecords) return BFE_MEMORY; // - read all current records into memory (relative to old headersize) readRecord(0,oldrecords,numrecords); // Update header because extra header might have changed in size if (fExtraHeaderP && (fBinFileHeader.headersize!=sizeof(TBinFileHeader)+fExtraHeaderSize)) { // (extra) header has changed in size // - read old extra header (or part of it that will be retained in case it shrinks between versions) uInt32 oldEHdrSz = fBinFileHeader.headersize-sizeof(TBinFileHeader); platformSeekFile(sizeof(TBinFileHeader)); platformReadFile(fExtraHeaderP,oldEHdrSz<=fExtraHeaderSize ? oldEHdrSz : fExtraHeaderSize); // - adjust the overall header size fBinFileHeader.headersize = sizeof(TBinFileHeader)+fExtraHeaderSize; // - let the update function handle init of the extra header aUpdateFunc(fFoundVersion,fVersion,NULL,fExtraHeaderP,0); // - make sure new extra header gets written fExtraHeaderDirty = true; } // - modify header fields fBinFileHeader.version=fVersion; // update version fBinFileHeader.recordsize=newrecordsize; // update record size fHeaderDirty=true; // header must be updated // - write new header (to make sure file is at least as long as header+extraheader) flushHeader(); // - truncate the file (taking new extra header size into account already, in case it has changed) truncate(); // - now convert buffered records void *newrecord = malloc(newrecordsize); for (uInt32 i=0; i0) { platformSeekFile(sizeof(TBinFileHeader)); platformReadFile(fExtraHeaderP,fExtraHeaderSize); fExtraHeaderDirty=false; } return BFE_OK; } // TBinFileBase::open // - create new DB file according to params set with setFileInfo bferr TBinFileBase::create(uInt32 aRecordsize, uInt32 aExtraHeadersize, void *aExtraHeaderP, bool aOverwrite) { bferr e; close(); // try to open e=open(aExtraHeadersize,NULL); // do not pass our new header data in case there is an old file already if (e==BFE_NOTFOUND || aOverwrite) { close(); // create new file if (!platformOpenFile(fFilename.c_str(),fopm_create)) return BFE_IOERR; // could not create for some reason // prepare header fBinFileHeader.idword=fIdWord; fBinFileHeader.version=fVersion; fBinFileHeader.headersize=sizeof(TBinFileHeader)+aExtraHeadersize; fBinFileHeader.recordsize=aRecordsize; fBinFileHeader.numrecords=0; fBinFileHeader.allocatedrecords=0; fBinFileHeader.uniquerecordid=0; fHeaderDirty = true; // - link in the new extra header buffer fExtraHeaderP = aExtraHeaderP; fExtraHeaderDirty = true; // make sure it gets written // write entire header e=flushHeader(); // opened with new version fFoundVersion = fVersion; } else if (e==BFE_OK) { // already exists close(); e=BFE_EXISTS; } return e; } // TBinFileBase::create // - close the file bferr TBinFileBase::close(void) { if (platformFileIsOpen()) { // remove empty space from end of file truncate(fBinFileHeader.numrecords); // write new header flushHeader(); // close file platformCloseFile(); } return BFE_OK; } // TBinFileBase::close // - close and delete file (full cleanup) bferr TBinFileBase::closeAndDelete(void) { close(); // now delete return platformDeleteFile(fFilename.c_str()) ? BFE_OK : BFE_IOERR; } // TBinFileBase::closeAndDelete // - flush the header to the file bferr TBinFileBase::flushHeader(void) { // save header if dirty if (fHeaderDirty) { platformSeekFile(0); platformWriteFile(&fBinFileHeader,sizeof(fBinFileHeader)); fHeaderDirty=false; } // save extra header if existing and requested if (fExtraHeaderP && fExtraHeaderDirty) { platformSeekFile(sizeof(fBinFileHeader)); platformWriteFile(fExtraHeaderP,fExtraHeaderSize); fExtraHeaderDirty=false; } // make sure data is really flushed in case we get improperly // destructed platformFlushFile(); return BFE_OK; } // TBinFileBase::flushHeader // - truncate to specified number of records bferr TBinFileBase::truncate(uInt32 aNumRecords) { if (!platformFileIsOpen()) return BFE_NOTOPEN; platformTruncateFile(fBinFileHeader.headersize+aNumRecords*fBinFileHeader.recordsize); fBinFileHeader.numrecords=aNumRecords; fBinFileHeader.allocatedrecords=aNumRecords; fHeaderDirty=true; return BFE_OK; } // TBinFileBase::truncate // - read by index bferr TBinFileBase::readRecord(uInt32 aIndex, void *aRecordData, uInt32 aNumRecords) { if (!platformFileIsOpen()) return BFE_NOTOPEN; if (aNumRecords==0) return BFE_OK; // find record position in file if (aIndex+aNumRecords>fBinFileHeader.numrecords) return BFE_BADINDEX; // not enough records to read if (!platformSeekFile(fBinFileHeader.headersize+aIndex*fBinFileHeader.recordsize)) return BFE_BADINDEX; // read data now if (!platformReadFile(aRecordData,fBinFileHeader.recordsize*aNumRecords)) return BFE_IOERR; // could not read as expected return BFE_OK; } // TBinFileBase::readRecord // - update by index bferr TBinFileBase::updateRecord(uInt32 aIndex, const void *aRecordData, uInt32 aNumRecords) { if (!platformFileIsOpen()) return BFE_NOTOPEN; if (aNumRecords==0) return BFE_OK; // nothing to do // find record position in file if (aIndex+aNumRecords>fBinFileHeader.numrecords) return BFE_BADINDEX; // trying to update more records than actually here if (!platformSeekFile(fBinFileHeader.headersize+aIndex*fBinFileHeader.recordsize)) return BFE_BADINDEX; // write data now if (!platformWriteFile(aRecordData,fBinFileHeader.recordsize*aNumRecords)) return BFE_IOERR; // could not read as expected return BFE_OK; } // TBinFileBase::updateRecord // - new record, returns new index bferr TBinFileBase::newRecord(uInt32 &aIndex, const void *aRecordData) { if (!platformFileIsOpen()) return BFE_NOTOPEN; // go to end of file if (!platformSeekFile(fBinFileHeader.headersize+fBinFileHeader.numrecords*fBinFileHeader.recordsize)) return BFE_IOERR; // write a new record if (!platformWriteFile(aRecordData,fBinFileHeader.recordsize)) return BFE_IOERR; // could not read as expected // update header aIndex=fBinFileHeader.numrecords++; // return index of new record fBinFileHeader.allocatedrecords++; fHeaderDirty=true; return BFE_OK; } // TBinFileBase::newRecord // - delete record bferr TBinFileBase::deleteRecord(uInt32 aIndex) { if (!platformFileIsOpen()) return BFE_NOTOPEN; if (aIndex>=fBinFileHeader.numrecords) return BFE_BADINDEX; if (aIndex using namespace std; namespace sysync { #ifndef ANDROID #pragma pack(push,4) // 32bit #endif // general defines for bindatastore // File header typedef struct { uInt32 idword; // identifies the database file type uInt32 version; // identifies the version of the database file uInt32 headersize; // size of header in bytes (specific files might have additional header info) uInt32 recordsize; // size in bytes of a single record uInt32 numrecords; // number of actual records uInt32 allocatedrecords; // number of allocated records in the file (including empty space) uInt32 uniquerecordid; // ever increasing counter to generate unique IDs for records } TBinFileHeader; #ifndef ANDROID #pragma pack(pop) #endif typedef uInt16 bferr; #define BFE_OK 0 // ok #define BFE_BADVERSION 1 // version mismatch #define BFE_BADTYPE 2 // type mismatch #define BFE_BADSTRUCT 3 // bad file structure (e.g. extra header size too big) #define BFE_NOTFOUND 4 // file not found #define BFE_EXISTS 5 // file already exists #define BFE_BADINDEX 6 // no such record #define BFE_NOTOPEN 7 // file not open #define BFE_IOERR 8 // I/O error #define BFE_MEMORY 9 // memory error typedef enum { fopm_update, // open for read and write fopm_create // create for read and write (truncate possibly existing) } TFileOpenModes; // DB version update function: // - when called with aOldRecordData==aNewRecordData==NULL, just checks if update is possible and returns new record size if yes // - when called with aOldRecordData==NULL, but aNewRecordData!=0, aNewRecordData points to the extra header and should be // updated for new version (only called when extra header size is actually different) // - when called with aOldRecordData!=0 and aNewRecordData!=0, it must update the record data to the new version. // This is repeated for all records in the binfile. typedef uInt32 (*TUpdateFunc)(uInt32 aOldVersion, uInt32 aNewVersion, void *aOldRecordData, void *aNewRecordData, uInt32 aOldSize); class TBinFileBase { // construction/destruction private: bool fDestructed; // flag which will be set once destruct() has been called - by the outermost derivate's destructor public: TBinFileBase(); virtual void doDestruct(void); // will be called by destruct, derived must call inherited if they implement it void destruct(void); // to be called by ALL destructors of derivates. virtual ~TBinFileBase(); // DB file access // - set path to binary file containing the database (aExpectedRecordSize can be zero if record size is not predetermined by a sizeof()) void setFileInfo(const char *aFilename, uInt32 aVersion, uInt32 aIdWord, uInt32 aExpectedRecordSize); // - get version file had when opening uInt32 getFoundVersion(void) { return fFoundVersion; }; // - check if open bool isOpen(void) { return platformFileIsOpen(); }; // - create a copy bferr createAsCopyFrom(TBinFileBase &aSourceBinFile, bool aOverwrite=false); // - try to open existing DB file according to params set with setFileInfo bferr open(uInt32 aExtraHeadersize=0, void *aExtraHeaderP=NULL, TUpdateFunc aUpdateFunc=NULL); // - create existing DB file according to params set with setFileInfo bferr create(uInt32 aRecordsize, uInt32 aExtraHeadersize=0, void *aExtraHeaderP=NULL, bool aOverwrite=false); // - truncate to specified number of records bferr truncate(uInt32 aNumRecords=0); // - make the extra header dirty void setExtraHeaderDirty(void) { fExtraHeaderDirty=true; }; // - flush the header to the file bferr flushHeader(void); // - close the file bferr close(void); // - close and delete file (full cleanup) bferr closeAndDelete(void); // Info // - number of records uInt32 getNumRecords(void) { return fBinFileHeader.numrecords; }; // - net size of record uInt32 getRecordSize(void) { return fBinFileHeader.recordsize; }; // - get next unique ID (starts at 1, is never 0!) uInt32 getNextUniqueID(void) { return ++fBinFileHeader.uniquerecordid; fHeaderDirty=true; }; // record access // - read by index bferr readRecord(uInt32 aIndex, void *aRecordData, uInt32 aNumRecords=1); // - update by index bferr updateRecord(uInt32 aIndex, const void *aRecorddata, uInt32 aNumRecords=1); // - new record bferr newRecord(const void *aRecorddata) { uInt32 i; return newRecord(i,aRecorddata); }; bferr newRecord(uInt32 &aIndex, const void *aRecorddata); // - delete record bferr deleteRecord(uInt32 aIndex); protected: // Platform file implementation abstraction // - test if platform file open virtual bool platformFileIsOpen(void) = 0; // - open file virtual bool platformOpenFile(cAppCharP aFilePath, TFileOpenModes aMode) = 0; // - close file virtual bool platformCloseFile(void) = 0; // - seek in file virtual bool platformSeekFile(uInt32 aPos, bool aFromEnd=false) = 0; // - read from file virtual bool platformReadFile(void *aBuffer, uInt32 aMaxRead) = 0; // - write to file virtual bool platformWriteFile(const void *aBuffer, uInt32 aBytes) = 0; // - flush all buffers virtual bool platformFlushFile(void) = 0; // - truncate file to a specific length virtual bool platformTruncateFile(uInt32 aNewSize) = 0; // - delete file entirely virtual bool platformDeleteFile(cAppCharP aFilePath) = 0; private: // file identification string fFilename; uInt32 fIdWord; uInt32 fVersion; uInt32 fFoundVersion; // version of file found when opening (to check after opening for happened upgrade) uInt32 fExpectedRecordSize; // cached header bool fHeaderDirty; // set if header must be written back to DB file bool fExtraHeaderDirty; // set if extra header must be written back to DB file TBinFileHeader fBinFileHeader; // standard header void *fExtraHeaderP; // pointer to extra header that will be read at open() and written at close() uInt32 fExtraHeaderSize; // size of extra header bytes at fExtraHeaderP }; // TBinFileBase } // namespace sysync #endif // BINFILEBASE_H libsynthesis-3.4.0.47.1/src/sysync/binfileimplclient.cpp000077500000000000000000003232331226375725500231710ustar00rootroot00000000000000/** * @File binfileimplclient.cpp * * @Author Lukas Zeller (luz@plan44.ch) * * @brief TBinfileImplClient * Represents a client session (agent) that saves profile, target, resume info * and optionally changelog in TBinFile binary files * * Copyright (c) 2003-2011 by Synthesis AG + plan44.ch * * @Date 2005-09-30 : luz : created from TBinfileImplClient */ /* */ // includes #include "prefix_file.h" #include "binfileimplclient.h" #include "binfileimplds.h" #include "syserial.h" #include namespace sysync { // Support for EngineModule common interface // ========================================= #ifdef ENGINEINTERFACE_SUPPORT #ifndef ENGINE_LIBRARY #ifdef RELEASE_VERSION #error "this is here for Q&D testing with outlook client only" #endif // factory function implementation - declared in TEngineInterface ENGINE_IF_CLASS *newClientEngine(void) { return new TBinfileEngineInterface; } // newEngine #ifdef RELEASE_VERSION #error "this is only here for Q&D testing with outlook client - remove it later, global factory function may no longer be used by engineInterface targets!!" #else /// @brief returns a new application base. TSyncAppBase *TBinfileEngineInterface::newSyncAppBase(void) { return sysync::newSyncAppBase(); // use global factory function } // TBinfileEngineInterface::newSyncAppBase #endif #endif // not ENGINE_LIBRARY // create appropriate root key TSettingsKeyImpl *TBinfileEngineInterface::newSettingsRootKey(void) { return new TBinfileAgentRootKey(this); // return base class which can return some engine infos } // TBinfileEngineInterface::newSettingsRootKey // Target key // ---------- // constructor TBinfileTargetKey::TBinfileTargetKey( TEngineInterface *aEngineInterfaceP, sInt32 aTargetIndex, TBinfileDBSyncTarget *aTargetP, TBinfileClientConfig *aBinfileClientConfigP, TBinfileDSConfig *aBinfileDSConfigP ) : inherited(aEngineInterfaceP), fTargetIndex(aTargetIndex), fTargetP(aTargetP), fBinfileClientConfigP(aBinfileClientConfigP), fBinfileDSConfigP(aBinfileDSConfigP) { // nop } // TBinfileTargetKey::TBinfileTargetKey // destructor - close key TBinfileTargetKey::~TBinfileTargetKey() { // closing key if (fTargetP) { if (fDirty && fTargetIndex>=0) { // write back changed record fBinfileClientConfigP->writeTarget(fTargetIndex,*fTargetP); } // now delete the target record delete fTargetP; } } // TBinfileTargetKey::~TBinfileTargetKey // return ID of current key TSyError TBinfileTargetKey::GetKeyID(sInt32 &aID) { aID = fTargetP ? fTargetP->localDBTypeID : KEYVAL_ID_UNKNOWN; return LOCERR_OK; } // TBinfileTargetKey::GetKeyID // - read display name static TSyError readDispName( TStructFieldsKey *aStructFieldsKeyP, const TStructFieldInfo *aFldInfoP, appPointer aBuffer, memSize aBufSize, memSize &aValSize ) { // get from config TBinfileTargetKey *targetKeyP = static_cast(aStructFieldsKeyP); cAppCharP dispName = ""; #ifndef MINIMAL_CODE dispName = targetKeyP->getBinfileDSConfig()->fDisplayName.c_str(); #endif if (*dispName==0) { // no display name, get technical name instead dispName = targetKeyP->getBinfileDSConfig()->getName(); } return TStructFieldsKey::returnString(dispName, aBuffer, aBufSize, aValSize); } // readDispName // - read path where binfiles are, for plugin config files passed around engine static TSyError readBinFileDirTarget( TStructFieldsKey *aStructFieldsKeyP, const TStructFieldInfo *aFldInfoP, appPointer aBuffer, memSize aBufSize, memSize &aValSize ) { TBinfileTargetKey *targetKeyP = static_cast(aStructFieldsKeyP); // get info string binFilesDir; targetKeyP->getBinfileClientConfig()->getBinFilesPath(binFilesDir); return TStructFieldsKey::returnString(binFilesDir.c_str(), aBuffer, aBufSize, aValSize); } // readBinFileDirTarget // - read availability flag for this datastore static TSyError readIsAvailable( TStructFieldsKey *aStructFieldsKeyP, const TStructFieldInfo *aFldInfoP, appPointer aBuffer, memSize aBufSize, memSize &aValSize ) { TBinfileTargetKey *targetKeyP = static_cast(aStructFieldsKeyP); // - get profile by ID bool avail = false; if (targetKeyP && targetKeyP->getTarget()) { TBinfileDBSyncProfile profile; targetKeyP->getBinfileClientConfig()->getProfileByID(targetKeyP->getProfileID(),profile); avail = targetKeyP->getBinfileClientConfig()->isTargetAvailable(&profile,targetKeyP->getTarget()->localDBTypeID); } return TStructFieldsKey::returnInt(avail, sizeof(avail), aBuffer, aBufSize, aValSize); } // readIsAvailable // - read danger flags for this datastore (will return them even if not enabled) static TSyError readTargetDangerFlags( TStructFieldsKey *aStructFieldsKeyP, const TStructFieldInfo *aFldInfoP, appPointer aBuffer, memSize aBufSize, memSize &aValSize ) { TBinfileTargetKey *targetKeyP = static_cast(aStructFieldsKeyP); bool zapsServer, zapsClient; lineartime_t lastSync; uInt32 dbid; // get info uInt8 danger=0; TBinfileDBSyncTarget *targetP; if (targetKeyP && (targetP=targetKeyP->getTarget())) { targetKeyP->getBinfileClientConfig()->getTargetLastSyncTime(*targetP, lastSync, zapsServer, zapsClient, dbid); danger = (zapsServer ? DANGERFLAG_WILLZAPSERVER : 0) + (zapsClient ? DANGERFLAG_WILLZAPCLIENT : 0); } return TStructFieldsKey::returnInt(danger, sizeof(danger), aBuffer, aBufSize, aValSize); } // readTargetDangerFlags // - write a readonly bitmask (rdonly_xxx), if this returns LOCERR_OK, readonly is enabled static TSyError writeTargetReadOnlyCheck( TStructFieldsKey *aStructFieldsKeyP, const TStructFieldInfo *aFldInfoP, cAppPointer aBuffer, memSize aValSize ) { TBinfileTargetKey *targetKeyP = static_cast(aStructFieldsKeyP); // get readonly mask to check for uInt16 readOnlyMask = *((uInt16 *)aBuffer); // check in profile bool rdOnly=false; if (targetKeyP && targetKeyP->getTarget()) { TBinfileDBSyncProfile profile; targetKeyP->getBinfileClientConfig()->getProfileByID(targetKeyP->getProfileID(),profile); rdOnly = targetKeyP->getBinfileClientConfig()->isReadOnly( &profile, readOnlyMask ); } // if feature is enabled for this profile, return LOCERR_OK, DB_NoContent otherwise return rdOnly ? LOCERR_OK : DB_NoContent; } // writeTargetReadOnlyCheck // - write a feature number (APPFTR_xxx), if this returns LOCERR_OK, feature is available, otherwise not static TSyError writeTargetFeatureCheck( TStructFieldsKey *aStructFieldsKeyP, const TStructFieldInfo *aFldInfoP, cAppPointer aBuffer, memSize aValSize ) { TBinfileTargetKey *targetKeyP = static_cast(aStructFieldsKeyP); // get feature to check for uInt16 featureNo = *((uInt16 *)aBuffer); // extra check for those that only make sense together with certain fDSAvailFlag bool avail=true; uInt16 dsAvailFlags = targetKeyP->getBinfileDSConfig()->fDSAvailFlag; if (featureNo==APP_FTR_EVENTRANGE && (dsAvailFlags & dsavail_events)==0) avail=false; // event range makes sense for events only if (featureNo==APP_FTR_EMAILRANGE && (dsAvailFlags & dsavail_emails)==0) avail=false; // email range makes sense for emails only // check on profile (and global) level if (avail && targetKeyP && targetKeyP->getTarget()) { TBinfileDBSyncProfile profile; targetKeyP->getBinfileClientConfig()->getProfileByID(targetKeyP->getProfileID(),profile); avail = targetKeyP->getBinfileClientConfig()->isFeatureEnabled( &profile, featureNo ); } // if feature is enabled for this profile, return LOCERR_OK, DB_NoContent otherwise return avail ? LOCERR_OK : DB_NoContent; } // writeTargetFeatureCheck // macro simplifying typing in the table below #define OFFS_SZ_TG(n) (offsetof(TBinfileDBSyncTarget,n)), sizeof(dP_tg->n) // dummy pointer needed for sizeof static const TBinfileDBSyncTarget *dP_tg=NULL; // accessor table for target key and for TARGETSETTING() script function const TStructFieldInfo TargetFieldInfos[] = { // valName, valType, writable, fieldOffs, valSiz { "profileID", VALTYPE_INT32, false, OFFS_SZ_TG(remotepartyID) }, // read-only profile ID { "enabled", VALTYPE_ENUM, true, OFFS_SZ_TG(enabled) }, { "forceslow", VALTYPE_ENUM, true, OFFS_SZ_TG(forceSlowSync) }, { "syncmode", VALTYPE_ENUM, true, OFFS_SZ_TG(syncmode) }, { "limit1", VALTYPE_INT32, true, OFFS_SZ_TG(limit1) }, { "limit2", VALTYPE_INT32, true, OFFS_SZ_TG(limit2) }, { "extras", VALTYPE_INT32, true, OFFS_SZ_TG(extras) }, { "localpath", VALTYPE_TEXT, true, OFFS_SZ_TG(localDBPath) }, { "remotepath", VALTYPE_TEXT, true, OFFS_SZ_TG(remoteDBpath) }, #if defined(DESKTOP_CLIENT) || TARGETS_DB_VERSION>4 { "localcontainer", VALTYPE_TEXT, true, OFFS_SZ_TG(localContainerName) }, #endif // read-only status info { "dbname", VALTYPE_TEXT, false, OFFS_SZ_TG(dbname) }, { "lastSync", VALTYPE_TIME64, false, OFFS_SZ_TG(lastSync) }, { "lastChangeCheck", VALTYPE_TIME64, false, OFFS_SZ_TG(lastChangeCheck) }, { "resumeAlertCode", VALTYPE_INT16, true, OFFS_SZ_TG(resumeAlertCode) }, // programmatic danger flags (will sync zap client or server data?) { "dangerFlags", VALTYPE_INT8, false, 0,0, &readTargetDangerFlags, NULL }, // special programmatic availability and feature checks { "isAvailable", VALTYPE_ENUM, false, 0,0, &readIsAvailable, NULL }, // datastore availability { "checkForReadOnly", VALTYPE_INT16, true, 0,0, NULL, &writeTargetReadOnlyCheck }, // target level readonly check { "checkForFeature", VALTYPE_INT16, true, 0,0, NULL, &writeTargetFeatureCheck }, // target level feature check // display name from config { "dispName", VALTYPE_TEXT, false, 0,0, &readDispName, NULL }, // path where binfiles are, for plugin config files passed around engine { "binfilesDir", VALTYPE_TEXT, false, 0,0, &readBinFileDirTarget, NULL }, // new fields of TARGETS_DB_VERSION 6 and beyond #if TARGETS_DB_VERSION>5 { "remoteDispName", VALTYPE_TEXT, false, OFFS_SZ_TG(remoteDBdispName) }, // filtering { "filterCapDesc", VALTYPE_TEXT, false, OFFS_SZ_TG(filterCapDesc) }, { "remoteFilters", VALTYPE_TEXT, true, OFFS_SZ_TG(remoteFilters) }, { "localFilters", VALTYPE_TEXT, true, OFFS_SZ_TG(localFilters) }, #endif }; const sInt32 numTargetFieldInfos = sizeof(TargetFieldInfos)/sizeof(TStructFieldInfo); // get table describing the fields in the struct const TStructFieldInfo *TBinfileTargetKey::getFieldsTable(void) { return TargetFieldInfos; } // TBinfileTargetKey::getFieldsTable sInt32 TBinfileTargetKey::numFields(void) { return numTargetFieldInfos; } // TBinfileTargetKey::numFields // get actual struct base address uInt8P TBinfileTargetKey::getStructAddr(void) { return (uInt8P)fTargetP; } // TBinfileTargetKey::getStructAddr // Profiles container key // ---------------------- // constructor TBinfileTargetsKey::TBinfileTargetsKey(TEngineInterface *aEngineInterfaceP, sInt32 aProfileID) : inherited(aEngineInterfaceP), fProfileID(aProfileID), fTargetIterator(-1) { // get pointer to BinFileClientConfig fBinfileClientConfigP = static_cast( aEngineInterfaceP->getSyncAppBase()->getRootConfig()->fAgentConfigP ); } // TBinfileTargetsKey::TBinfileTargetsKey // target can be opened only by (dbtype-)ID TSyError TBinfileTargetsKey::OpenSubkey( TSettingsKeyImpl *&aSettingsKeyP, sInt32 aID, uInt16 aMode ) { // safety check to see if targets are open at all if (!fBinfileClientConfigP->fTargetsBinFile.isOpen()) return LOCERR_WRONGUSAGE; TBinfileDBSyncTarget *targetP = new TBinfileDBSyncTarget; TSyError sta = LOCERR_OK; sInt32 targetIndex = -1; while(true) { switch (aID) { case KEYVAL_ID_FIRST: fTargetIterator = 0; // go to first goto getnthtarget; // then fetch next case KEYVAL_ID_NEXT: // increment fTargetIterator++; getnthtarget: // get n-th target as indicated by iterator if (fTargetIterator>=0) targetIndex = fBinfileClientConfigP->findTargetIndex(fProfileID,fTargetIterator); if (targetIndex>=0) goto gettarget; // next target found in iteration, get it // no more targets found sta=DB_NoContent; // no more targets break; default: // get target by ID if (aID<0) { sta=LOCERR_WRONGUSAGE; break; } // find target by dbtypeid targetIndex = fBinfileClientConfigP->findTargetIndexByDBInfo(fProfileID,aID,NULL); gettarget: // get target by index targetIndex = fBinfileClientConfigP->getTarget(targetIndex,*targetP); // check error if (targetIndex<0) sta=DB_NotFound; // target not found break; } if (sta==LOCERR_OK && targetIndex>=0) { // we have loaded a target, create subkey handler and pass data /* %%% old: search by name // - find related datastore config (by dbname) TBinfileDSConfig *dsCfgP = static_cast( fBinfileClientConfigP->getLocalDS(targetP->dbname) ); */ // - find related datastore config (by dbtypeid) TBinfileDSConfig *dsCfgP = static_cast( fBinfileClientConfigP->getLocalDS(NULL,targetP->localDBTypeID) ); if (dsCfgP==NULL) { // this target entry is not configured in the config -> skip it while iterating, // or return "DB error" if explicitly addressed // - re-enter iteration if iterating if (aID==KEYVAL_ID_FIRST) aID=KEYVAL_ID_NEXT; if (aID==KEYVAL_ID_NEXT) continue; // re-iterate // otherwise return DB error to signal inconsistency between target and config sta=DB_Error; } else { aSettingsKeyP = new TBinfileTargetKey(fEngineInterfaceP,targetIndex,targetP,fBinfileClientConfigP,dsCfgP); if (aSettingsKeyP) targetP=NULL; // ownership passed else sta=LOCERR_OUTOFMEM; // cannot create object } } // done, no re-iteration needed break; } // while true // get rid of it if we couldn't pass it to the subkey handler if (targetP) delete targetP; // done return sta; } // TBinfileTargetsKey::OpenSubkey #ifdef AUTOSYNC_SUPPORT // Autosync level key // ------------------ // constructor TBinfileASLevelKey::TBinfileASLevelKey( TEngineInterface *aEngineInterfaceP, sInt32 aLevelIndex, TBinfileDBSyncProfile *aProfileP, TBinfileClientConfig *aBinfileClientConfigP ) : inherited(aEngineInterfaceP), fLevelIndex(aLevelIndex), fProfileP(aProfileP), fBinfileClientConfigP(aBinfileClientConfigP) { } // TBinfileASLevelKey::TBinfileASLevelKey // destructor - close key TBinfileASLevelKey::~TBinfileASLevelKey() { // closing key // NOP here } // TBinfileASLevelKey::~TBinfileASLevelKey // return ID of current key TSyError TBinfileASLevelKey::GetKeyID(sInt32 &aID) { aID = fLevelIndex; // ID is level index return LOCERR_OK; } // TBinfileASLevelKey::GetKeyID // macro simplifying typing in the table below #define OFFS_SZ_AS(n) (offsetof(TAutoSyncLevel,n)), sizeof(dP_as->n) // dummy pointer needed for sizeof static const TAutoSyncLevel *dP_as=NULL; // accessor table for profiles static const TStructFieldInfo ASLevelFieldInfos[] = { // valName, valType, writable, fieldOffs, valSiz { "mode", VALTYPE_ENUM, true, OFFS_SZ_AS(Mode) }, { "startDayTime", VALTYPE_INT16, true, OFFS_SZ_AS(StartDayTime) }, { "endDayTime", VALTYPE_INT16, true, OFFS_SZ_AS(EndDayTime) }, { "weekdayMask", VALTYPE_INT8, true, OFFS_SZ_AS(WeekdayMask) }, { "chargeLevel", VALTYPE_INT8, true, OFFS_SZ_AS(ChargeLevel) }, { "memLevel", VALTYPE_INT8, true, OFFS_SZ_AS(MemLevel) }, { "flags", VALTYPE_INT8, true, OFFS_SZ_AS(Flags) }, }; // get table describing the fields in the struct const TStructFieldInfo *TBinfileASLevelKey::getFieldsTable(void) { return ASLevelFieldInfos; } // TBinfileASLevelKey::getFieldsTable sInt32 TBinfileASLevelKey::numFields(void) { return sizeof(ASLevelFieldInfos)/sizeof(TStructFieldInfo); } // TBinfileASLevelKey::numFields // get actual struct base address uInt8P TBinfileASLevelKey::getStructAddr(void) { return (uInt8P)&(fProfileP->AutoSyncLevel[fLevelIndex]); } // TBinfileASLevelKey::getStructAddr // Autosync levels container key // ----------------------------- // constructor TBinfileASLevelsKey::TBinfileASLevelsKey(TEngineInterface *aEngineInterfaceP, TBinfileDBSyncProfile *aProfileP) : inherited(aEngineInterfaceP), fASLevelIterator(-1), fProfileP(aProfileP) { // get pointer to BinFileClientConfig fBinfileClientConfigP = static_cast( aEngineInterfaceP->getSyncAppBase()->getRootConfig()->fAgentConfigP ); } // TBinfileASLevelsKey::TBinfileASLevelsKey // autosync levels can be opened only by ID TSyError TBinfileASLevelsKey::OpenSubkey( TSettingsKeyImpl *&aSettingsKeyP, sInt32 aID, uInt16 aMode ) { TSyError sta = LOCERR_OK; switch (aID) { case KEYVAL_ID_FIRST: fASLevelIterator = 0; // go to first goto getlevel; // then fetch next case KEYVAL_ID_NEXT: // increment fASLevelIterator++; getlevel: // use iterator as ID (ID=level index) aID = fASLevelIterator; default: // open specified ID if (aID<0) { sta=LOCERR_WRONGUSAGE; } else if (aID>=NUM_AUTOSYNC_LEVELS) sta=DB_NoContent; // no more autosync levels else { fASLevelIterator = aID; aSettingsKeyP = new TBinfileASLevelKey(fEngineInterfaceP,aID,fProfileP,fBinfileClientConfigP); } break; } // done return sta; } // TBinfileASLevelsKey::OpenSubkey #endif // AUTOSYNC_SUPPORT // Profile key // ----------- // constructor TBinfileProfileKey::TBinfileProfileKey( TEngineInterface *aEngineInterfaceP, sInt32 aProfileIndex, // if <0, aProfileP is the running session's profile record TBinfileDBSyncProfile *aProfileP, TBinfileClientConfig *aBinfileClientConfigP ) : inherited(aEngineInterfaceP), fProfileIndex(aProfileIndex), fProfileP(aProfileP), fBinfileClientConfigP(aBinfileClientConfigP) { } // TBinfileProfileKey::TBinfileProfileKey // destructor - close key TBinfileProfileKey::~TBinfileProfileKey() { // closing key if (fProfileP) { if (fDirty && fProfileIndex>=0) { // write back changed record fBinfileClientConfigP->writeProfile(fProfileIndex,*fProfileP); } // now delete the profile record if it is not a running session's (because then it is just passed) if (fProfileIndex>=0) delete fProfileP; } } // TBinfileProfileKey::~TBinfileProfileKey // return ID of current key TSyError TBinfileProfileKey::GetKeyID(sInt32 &aID) { aID = getProfileID(); return LOCERR_OK; } // TBinfileProfileKey::GetKeyID // open subkey by name (not by path!) // - this is the actual implementation TSyError TBinfileProfileKey::OpenSubKeyByName( TSettingsKeyImpl *&aSettingsKeyP, cAppCharP aName, stringSize aNameSize, uInt16 aMode ) { if (fProfileP && strucmp(aName,"targets",aNameSize)==0) aSettingsKeyP = new TBinfileTargetsKey(fEngineInterfaceP,fProfileP->profileID); #ifdef AUTOSYNC_SUPPORT else if (fProfileP && strucmp(aName,"autosynclevels",aNameSize)==0) aSettingsKeyP = new TBinfileASLevelsKey(fEngineInterfaceP,fProfileP); #endif else return inherited::OpenSubKeyByName(aSettingsKeyP,aName,aNameSize,aMode); // opened a key return LOCERR_OK; } // TBinfileProfileKey::OpenSubKeyByName // - read path where binfiles are, for plugin config files passed around engine static TSyError readBinFileDirProfile( TStructFieldsKey *aStructFieldsKeyP, const TStructFieldInfo *aFldInfoP, appPointer aBuffer, memSize aBufSize, memSize &aValSize ) { TBinfileProfileKey *profileKeyP = static_cast(aStructFieldsKeyP); // get info string binFilesDir; profileKeyP->getBinfileClientConfig()->getBinFilesPath(binFilesDir); return TStructFieldsKey::returnString(binFilesDir.c_str(), aBuffer, aBufSize, aValSize); } // readBinFileDirProfile // - read danger flags for the profile (combined danger of all enabled datastores) static TSyError readDangerFlags( TStructFieldsKey *aStructFieldsKeyP, const TStructFieldInfo *aFldInfoP, appPointer aBuffer, memSize aBufSize, memSize &aValSize ) { TBinfileProfileKey *profileKeyP = static_cast(aStructFieldsKeyP); bool zapsServer, zapsClient; lineartime_t lastSync; // get info uInt8 danger=0; profileKeyP->getBinfileClientConfig()->getProfileLastSyncTime( profileKeyP->getProfileID(), lastSync, zapsServer, zapsClient ); danger = (zapsServer ? DANGERFLAG_WILLZAPSERVER : 0) + (zapsClient ? DANGERFLAG_WILLZAPCLIENT : 0); return TStructFieldsKey::returnInt(danger, sizeof(danger), aBuffer, aBufSize, aValSize); } // readDangerFlags // - write a feature number (APPFTR_xxx), if this returns LOCERR_OK, feature is available, otherwise not static TSyError writeFeatureCheck( TStructFieldsKey *aStructFieldsKeyP, const TStructFieldInfo *aFldInfoP, cAppPointer aBuffer, memSize aValSize ) { TBinfileProfileKey *profileKeyP = static_cast(aStructFieldsKeyP); // get feature to check for uInt16 featureNo = *((uInt16 *)aBuffer); // if feature is enabled for this profile, return LOCERR_OK, DB_NoContent otherwise return profileKeyP->getBinfileClientConfig()->isFeatureEnabled( profileKeyP->getProfile(), featureNo ) ? LOCERR_OK : DB_NoContent; } // writeFeatureCheck // - write a readonly bitmask (rdonly_xxx), if this returns LOCERR_OK, readonly is enabled static TSyError writeReadOnlyCheck( TStructFieldsKey *aStructFieldsKeyP, const TStructFieldInfo *aFldInfoP, cAppPointer aBuffer, memSize aValSize ) { TBinfileProfileKey *profileKeyP = static_cast(aStructFieldsKeyP); // get readonly mask to check for uInt16 readOnlyMask = *((uInt16 *)aBuffer); // check in profile bool rdOnly= profileKeyP->getBinfileClientConfig()->isReadOnly( profileKeyP->getProfile(), readOnlyMask ); // if feature is enabled for this profile, return LOCERR_OK, DB_NoContent otherwise return rdOnly ? LOCERR_OK : DB_NoContent; } // writeReadOnlyCheck // macro simplifying typing in the table below #define OFFS_SZ_PF(n) (offsetof(TBinfileDBSyncProfile,n)), sizeof(dP_pf->n) // dummy pointer needed for sizeof static const TBinfileDBSyncProfile *dP_pf=NULL; // accessor table for profiles and for PROFILESETTING script function const TStructFieldInfo ProfileFieldInfos[] = { // valName, valType, writable, fieldOffs, valSiz { "profileName", VALTYPE_TEXT, true, OFFS_SZ_PF(profileName) }, { "protocol", VALTYPE_ENUM, true, OFFS_SZ_PF(protocol) }, { "serverURI", VALTYPE_TEXT, true, OFFS_SZ_PF(serverURI) }, { "URIpath", VALTYPE_TEXT, true, OFFS_SZ_PF(URIpath) }, { "serverUser", VALTYPE_TEXT, true, OFFS_SZ_PF(serverUser) }, { "serverPassword", VALTYPE_TEXT_OBFUS, true, OFFS_SZ_PF(serverPassword) }, { "transportUser", VALTYPE_TEXT, true, OFFS_SZ_PF(transportUser) }, { "transportPassword", VALTYPE_TEXT_OBFUS, true, OFFS_SZ_PF(transportPassword) }, { "socksHost", VALTYPE_TEXT, true, OFFS_SZ_PF(socksHost) }, { "proxyHost", VALTYPE_TEXT, true, OFFS_SZ_PF(proxyHost) }, { "proxyUser", VALTYPE_TEXT, true, OFFS_SZ_PF(proxyUser) }, { "proxyPassword", VALTYPE_TEXT_OBFUS, true, OFFS_SZ_PF(proxyPassword) }, { "encoding", VALTYPE_ENUM, true, OFFS_SZ_PF(encoding) }, { "lastAuthMethod", VALTYPE_ENUM, true, OFFS_SZ_PF(lastAuthMethod) }, { "lastNonce", VALTYPE_TEXT, true, OFFS_SZ_PF(lastNonce) }, { "syncmlvers", VALTYPE_ENUM, true, OFFS_SZ_PF(lastSyncMLVersion) }, { "useProxy", VALTYPE_ENUM, true, OFFS_SZ_PF(useProxy) }, { "useConnectionProxy", VALTYPE_ENUM, true, OFFS_SZ_PF(useConnectionProxy) }, { "transpFlags", VALTYPE_INT32, true, OFFS_SZ_PF(transpFlags) }, { "profileFlags", VALTYPE_INT32, true, OFFS_SZ_PF(profileFlags) }, // generic fields for app specific usage { "profileExtra1", VALTYPE_INT32, true, OFFS_SZ_PF(profileExtra1) }, { "profileExtra2", VALTYPE_INT32, true, OFFS_SZ_PF(profileExtra2) }, { "profileData", VALTYPE_BUF, true, OFFS_SZ_PF(profileData) }, // feature/availability/extras flags { "dsAvailFlags", VALTYPE_INT16, true, OFFS_SZ_PF(dsAvailFlags) }, { "readOnlyFlags", VALTYPE_INT8, true, OFFS_SZ_PF(readOnlyFlags) }, { "remoteFlags", VALTYPE_INT8, false, OFFS_SZ_PF(remoteFlags) }, { "featureFlags", VALTYPE_INT8, true, OFFS_SZ_PF(featureFlags) }, // programmatic danger flags (will sync zap client or server data?) { "dangerFlags", VALTYPE_INT8, false, 0,0, &readDangerFlags, NULL }, // special programmatic feature check { "checkForFeature", VALTYPE_INT16, true, 0,0, NULL, &writeFeatureCheck }, { "checkForReadOnly", VALTYPE_INT16, true, 0,0, NULL, &writeReadOnlyCheck }, // path where binfiles are, for plugin config files passed around engine { "binfilesDir", VALTYPE_TEXT, false, 0,0, &readBinFileDirProfile, NULL }, #ifdef AUTOSYNC_SUPPORT // autosync { "timedSyncMobile", VALTYPE_INT16, true, OFFS_SZ_PF(TimedSyncMobilePeriod) }, { "timedSyncCradled", VALTYPE_INT16, true, OFFS_SZ_PF(TimedSyncCradledPeriod) }, #endif }; const sInt32 numProfileFieldInfos = sizeof(ProfileFieldInfos)/sizeof(TStructFieldInfo); // get table describing the fields in the struct const TStructFieldInfo *TBinfileProfileKey::getFieldsTable(void) { return ProfileFieldInfos; } // TBinfileProfileKey::getFieldsTable sInt32 TBinfileProfileKey::numFields(void) { return numProfileFieldInfos; } // TBinfileProfileKey::numFields // get actual struct base address uInt8P TBinfileProfileKey::getStructAddr(void) { return (uInt8P)fProfileP; } // TBinfileProfileKey::getStructAddr // Profiles container key // ---------------------- // constructor TBinfileProfilesKey::TBinfileProfilesKey(TEngineInterface *aEngineInterfaceP) : inherited(aEngineInterfaceP), fProfileIterator(-1) { // get pointer to BinFileClientConfig (can be NULL in case engine was never initialized with a config) fBinfileClientConfigP = static_cast( aEngineInterfaceP->getSyncAppBase()->getRootConfig()->fAgentConfigP ); // default to not loosing or upgrading config fMayLooseOldCfg=false; } // TBinfileProfilesKey::TBinfileProfilesKey // destructor TBinfileProfilesKey::~TBinfileProfilesKey() { // make sure all settings are saved if ( fBinfileClientConfigP && // it's possible that we get there before engine was ever initialized! (fBinfileClientConfigP->fProfileBinFile.isOpen() || fBinfileClientConfigP->fTargetsBinFile.isOpen()) ) { fBinfileClientConfigP->closeSettingsDatabases(); fBinfileClientConfigP->openSettingsDatabases(false); } } // TBinfileProfilesKey::~TBinfileProfilesKey // profiles can be opened only by ID TSyError TBinfileProfilesKey::OpenSubkey( TSettingsKeyImpl *&aSettingsKeyP, sInt32 aID, uInt16 aMode ) { TBinfileDBSyncProfile *profileP = NULL; TSyError sta = LOCERR_OK; // safety check to see if config is here and profiles are open if (!fBinfileClientConfigP || !(fBinfileClientConfigP->fProfileBinFile.isOpen())) return LOCERR_WRONGUSAGE; // now create a profile record (which will be passed to subkey on success) profileP = new TBinfileDBSyncProfile; // check what to do switch (aID) { case KEYVAL_ID_NEW: // create a new empty profile fProfileIterator = fBinfileClientConfigP->newProfile("empty profile", false); // now get it goto getprofile; case KEYVAL_ID_NEW_DEFAULT: // create new profile with default values fProfileIterator = fBinfileClientConfigP->newProfile("default profile", true); // now get it goto getprofile; case KEYVAL_ID_NEW_DUP: // create duplicate of last opened profile (if any) fProfileIterator = fBinfileClientConfigP->newProfile("duplicated profile", false, fProfileIterator); // now get it goto getprofile; case KEYVAL_ID_FIRST: fProfileIterator = 0; // go to first goto getprofile; // then fetch next case KEYVAL_ID_NEXT: // increment fProfileIterator++; getprofile: // get profile by index if (fProfileIterator>=0) fProfileIterator=fBinfileClientConfigP->getProfile(fProfileIterator,*profileP); goto checkerror; default: if (aID<0) { sta=LOCERR_WRONGUSAGE; break; } // open by ID fProfileIterator=fBinfileClientConfigP->getProfileByID(aID,*profileP); checkerror: // check error if (fProfileIterator<0) sta=DB_NoContent; // no more profiles break; } if (sta==LOCERR_OK && fProfileIterator>=0) { // we have loaded a profile, create subkey handler and pass data aSettingsKeyP = new TBinfileProfileKey(fEngineInterfaceP,fProfileIterator,profileP,fBinfileClientConfigP); if (aSettingsKeyP) profileP=NULL; // ownership passed else sta=LOCERR_OUTOFMEM; // cannot create object } // get rid of it if we couldn't pass it to the subkey handler if (profileP) delete profileP; // done return sta; } // TBinfileProfilesKey::OpenSubkey // delete profile by ID TSyError TBinfileProfilesKey::DeleteSubkey(sInt32 aID) { sInt32 profileIndex = fBinfileClientConfigP->getProfileIndex(aID); if (profileIndex<0) return DB_NotFound; fBinfileClientConfigP->deleteProfile(profileIndex); fProfileIterator = -1; // invalidate iterator return LOCERR_OK; } // TBinfileProfilesKey::DeleteSubkey // - write a feature number (APPFTR_xxx), if this returns LOCERR_OK, feature is available, otherwise not static TSyError writeGlobalFeatureCheck( TStructFieldsKey *aStructFieldsKeyP, const TStructFieldInfo *aFldInfoP, cAppPointer aBuffer, memSize aValSize ) { // get feature to check for uInt16 featureNo = *((uInt16 *)aBuffer); // if feature is enabled for this profile, return LOCERR_OK, DB_NoContent otherwise return aStructFieldsKeyP->getEngineInterface()->getSyncAppBase()->isFeatureEnabled(featureNo) ? LOCERR_OK : DB_NoContent; } // writeGlobalFeatureCheck // - write provisioning string static TSyError writeProvisioningString( TStructFieldsKey *aStructFieldsKeyP, const TStructFieldInfo *aFldInfoP, cAppPointer aBuffer, memSize aValSize ) { TBinfileProfilesKey *profilesKeyP = static_cast(aStructFieldsKeyP); // execute the provisioning string // Note: if a new profile is created, the iterator is set such that KEYVAL_ID_NEXT // will return the profile just added/updated by provisioning sInt32 touchedProfile; cAppCharP p=cAppCharP(aBuffer); TSyError sta = LOCERR_CFGPARSE; while (p && *p) { // push this line if (profilesKeyP->getBinfileClientConfig()->executeProvisioningString(p, touchedProfile)) { // parsed ok sta = LOCERR_OK; // at least one line is ok profilesKeyP->setNextProfileindex(touchedProfile); // such that KEYVAL_ID_NEXT will get the new/modified profile } // search for next line // - skip to end while (*p && *p!=0x0A && *p!=0x0D) ++p; // - skip line end while (*p==0x0A || *p==0x0D) ++p; } return sta; } // writeProvisioningString // - read registration status code static TSyError readVarCfgStatus( TStructFieldsKey *aStructFieldsKeyP, const TStructFieldInfo *aFldInfoP, appPointer aBuffer, memSize aBufSize, memSize &aValSize ) { aValSize=2; if (aBufSize>=aValSize) { // get ptr TBinfileProfilesKey *profilesKeyP = static_cast(aStructFieldsKeyP); // sanity check if (!(profilesKeyP->fBinfileClientConfigP)) return LOCERR_WRONGUSAGE; // it's possible that we get there before engine was ever initialized! // try to access variable part of config (profiles/targets) localstatus sta = profilesKeyP->fBinfileClientConfigP->loadVarConfig(profilesKeyP->fMayLooseOldCfg); if (sta==LOCERR_OK) { // make sure profiles have all targets currently found in config profilesKeyP->fBinfileClientConfigP->checkProfiles(); } // copy from config *((uInt16*)aBuffer)=sta; } return LOCERR_OK; } // readVarCfgStatus // - read "overwrite" flag static TSyError readMayLooseOldConfig( TStructFieldsKey *aStructFieldsKeyP, const TStructFieldInfo *aFldInfoP, appPointer aBuffer, memSize aBufSize, memSize &aValSize ) { return TStructFieldsKey::returnInt(static_cast(aStructFieldsKeyP)->fMayLooseOldCfg, 1, aBuffer, aBufSize, aValSize); } // readMayLooseOldConfig // - write "overwrite" flag static TSyError writeMayLooseOldConfig( TStructFieldsKey *aStructFieldsKeyP, const TStructFieldInfo *aFldInfoP, cAppPointer aBuffer, memSize aValSize ) { // set flag static_cast(aStructFieldsKeyP)->fMayLooseOldCfg = *((uInt8 *)aBuffer); return LOCERR_OK; } // writeMayLooseOldConfig // does not work at this time, but intention would be to get rid of the warning below // #pragma GCC diagnostic ignored "-Wno-invalid-offsetof" // accessor table for profiles static const TStructFieldInfo ProfilesFieldInfos[] = { // valName, valType, writable, fieldOffs, valSiz { "settingsstatus", VALTYPE_INT16, false, 0, 0, &readVarCfgStatus, NULL }, //{ "overwrite", VALTYPE_INT8, true, offsetof(TBinfileProfilesKey,fMayLooseOldCfg), 1 }, //%%% this use of offsetof is not clean, so we use a getter/setter instead { "overwrite", VALTYPE_INT8, true, 0, 0, &readMayLooseOldConfig, &writeMayLooseOldConfig }, { "provisioningstring", VALTYPE_TEXT, true, 0, 0, NULL, &writeProvisioningString }, { "checkForFeature", VALTYPE_INT16, true, 0, 0, NULL, &writeGlobalFeatureCheck }, // global level feature check }; // get table describing the fields in the struct const TStructFieldInfo *TBinfileProfilesKey::getFieldsTable(void) { return ProfilesFieldInfos; } // TBinfileProfilesKey::getFieldsTable sInt32 TBinfileProfilesKey::numFields(void) { return sizeof(ProfilesFieldInfos)/sizeof(TStructFieldInfo); } // TBinfileProfilesKey::numFields // get actual struct base address uInt8P TBinfileProfilesKey::getStructAddr(void) { return (uInt8P)this; } // TBinfileProfilesKey::getStructAddr // Log entry key // ------------- // constructor TBinfileLogKey::TBinfileLogKey( TEngineInterface *aEngineInterfaceP, TLogFileEntry *aLogEntryP, TBinfileClientConfig *aBinfileClientConfigP ) : inherited(aEngineInterfaceP), fLogEntryP(aLogEntryP), fBinfileClientConfigP(aBinfileClientConfigP) { } // TBinfileLogKey::TBinfileLogKey // destructor - close key TBinfileLogKey::~TBinfileLogKey() { // closing key // - dispose log entry memory if (fLogEntryP) delete fLogEntryP; } // TBinfileLogKey::~TBinfileLogKey // - read DB display name related to this log entry static TSyError readLogDispName( TStructFieldsKey *aStructFieldsKeyP, const TStructFieldInfo *aFldInfoP, appPointer aBuffer, memSize aBufSize, memSize &aValSize ) { TBinfileLogKey *logentryKeyP = static_cast(aStructFieldsKeyP); // get config of datastore via DBID TLocalDSConfig *dscfgP = logentryKeyP->getBinfileClientConfig()->getLocalDS(NULL,logentryKeyP->getLogEntry()->dbID); cAppCharP dispName = ""; #ifndef MINIMAL_CODE dispName = dscfgP->fDisplayName.c_str(); #endif if (*dispName==0) { // no display name, get technical name instead dispName = dscfgP->getName(); } return TStructFieldsKey::returnString(dispName, aBuffer, aBufSize, aValSize); } // readLogDispName // - read DB display name related to this log entry static TSyError readLogProfileName( TStructFieldsKey *aStructFieldsKeyP, const TStructFieldInfo *aFldInfoP, appPointer aBuffer, memSize aBufSize, memSize &aValSize ) { TBinfileLogKey *logentryKeyP = static_cast(aStructFieldsKeyP); // get profile data via profile ID TBinfileDBSyncProfile profile; logentryKeyP->getBinfileClientConfig()->getProfileByID(logentryKeyP->getLogEntry()->profileID,profile); return TStructFieldsKey::returnString(profile.profileName, aBuffer, aBufSize, aValSize); } // readLogProfileName // macro simplifying typing in the table below #define OFFS_SZ_LOG(n) (offsetof(TLogFileEntry,n)), sizeof(dP_log->n) // dummy pointer needed for sizeof static const TLogFileEntry *dP_log=NULL; // accessor table for log entries static const TStructFieldInfo LogEntryFieldInfos[] = { // valName, valType, writable, fieldOffs, valSiz // - direct access { "time", VALTYPE_TIME64, false, OFFS_SZ_LOG(time) }, { "dbtypeid", VALTYPE_INT32, false, OFFS_SZ_LOG(dbID) }, { "profileid", VALTYPE_INT32, false, OFFS_SZ_LOG(profileID) }, { "status", VALTYPE_INT16, false, OFFS_SZ_LOG(status) }, { "mode", VALTYPE_INT16, false, OFFS_SZ_LOG(mode) }, { "dirmode", VALTYPE_INT16, false, OFFS_SZ_LOG(dirmode) }, { "locAdded", VALTYPE_INT32, false, OFFS_SZ_LOG(locAdded) }, { "locUpdated", VALTYPE_INT32, false, OFFS_SZ_LOG(locUpdated) }, { "locDeleted", VALTYPE_INT32, false, OFFS_SZ_LOG(locDeleted) }, { "remAdded", VALTYPE_INT32, false, OFFS_SZ_LOG(remAdded) }, { "remUpdated", VALTYPE_INT32, false, OFFS_SZ_LOG(remUpdated) }, { "remDeleted", VALTYPE_INT32, false, OFFS_SZ_LOG(remDeleted) }, { "inBytes", VALTYPE_INT32, false, OFFS_SZ_LOG(inBytes) }, { "outBytes", VALTYPE_INT32, false, OFFS_SZ_LOG(outBytes) }, { "locRejected", VALTYPE_INT32, false, OFFS_SZ_LOG(locRejected) }, { "remRejected", VALTYPE_INT32, false, OFFS_SZ_LOG(remRejected) }, // - procedural convenience { "dispName", VALTYPE_TEXT, false, 0, 0, &readLogDispName, NULL }, { "profileName", VALTYPE_TEXT, false, 0, 0, &readLogProfileName, NULL }, }; // get table describing the fields in the struct const TStructFieldInfo *TBinfileLogKey::getFieldsTable(void) { return LogEntryFieldInfos; } // TBinfileLogKey::getFieldsTable sInt32 TBinfileLogKey::numFields(void) { return sizeof(LogEntryFieldInfos)/sizeof(TStructFieldInfo); } // TBinfileLogKey::numFields // get actual struct base address uInt8P TBinfileLogKey::getStructAddr(void) { return (uInt8P)(fLogEntryP); } // TBinfileLogKey::getStructAddr // Log entries container key // ------------------------- // constructor TBinfileLogsKey::TBinfileLogsKey(TEngineInterface *aEngineInterfaceP) : inherited(aEngineInterfaceP), fLogEntryIterator(-1) { fBinfileClientConfigP = static_cast( aEngineInterfaceP->getSyncAppBase()->getRootConfig()->fAgentConfigP ); // open the log file // - get base path string filepath; fBinfileClientConfigP->getBinFilesPath(filepath); filepath += LOGFILE_DB_NAME; // - try to open fLogFile.setFileInfo(filepath.c_str(),LOGFILE_DB_VERSION,LOGFILE_DB_ID,sizeof(TLogFileEntry)); fLogFile.open(0,NULL,NULL); // Note: errors are not checked here, as no logfile is ok. We'll check before trying to read with isOpen() } // TBinfileLogsKey::TBinfileLogsKey // log entries can be opened only by reverse index (0=newest...n=oldest) TSyError TBinfileLogsKey::OpenSubkey( TSettingsKeyImpl *&aSettingsKeyP, sInt32 aID, uInt16 aMode ) { // if there is no logfile, we have no entries if (!fLogFile.isOpen()) return DB_NotFound; switch (aID) { case KEYVAL_ID_FIRST: fLogEntryIterator = 0; // go to latest (last in file!) goto getnthentry; // then fetch next case KEYVAL_ID_NEXT: // increment fLogEntryIterator++; goto getnthentry; default: fLogEntryIterator=aID; getnthentry: // get n-th-last log entry as indicated by iterator // - check index range sInt32 numrecs = fLogFile.getNumRecords(); if (fLogEntryIterator<0) return LOCERR_WRONGUSAGE; if (fLogEntryIterator>=numrecs) return DB_NoContent; // - retrieve TLogFileEntry *entryP = new TLogFileEntry; if (fLogFile.readRecord(numrecs-1-fLogEntryIterator,entryP) != BFE_OK) { delete entryP; return DB_Fatal; } // - create key and return it (loaded entry gets owned by key) aSettingsKeyP = new TBinfileLogKey(fEngineInterfaceP,entryP,fBinfileClientConfigP); } return LOCERR_OK; } // TBinfileLogsKey::OpenSubkey // delete profile by ID TSyError TBinfileLogsKey::DeleteSubkey(sInt32 aID) { // log can only be cleared entirely if (aID!=KEYVAL_ID_ALL) return LOCERR_WRONGUSAGE; // erase log fLogFile.truncate(0); return LOCERR_OK; } // TBinfileLogsKey::DeleteSubkey // Binfile Agent root key // ---------------------- // Constructor TBinfileAgentRootKey::TBinfileAgentRootKey(TEngineInterface *aEngineInterfaceP) : inherited(aEngineInterfaceP) { } // TBinfileAgentRootKey::TBinfileAgentRootKey // open subkey by name (not by path!) // - this is the actual implementation TSyError TBinfileAgentRootKey::OpenSubKeyByName( TSettingsKeyImpl *&aSettingsKeyP, cAppCharP aName, stringSize aNameSize, uInt16 aMode ) { if (strucmp(aName,"profiles",aNameSize)==0) { // allow accessing profiles only for active binfiles if ( static_cast( fEngineInterfaceP->getSyncAppBase()->getRootConfig()->fAgentConfigP )->fBinfilesActive ) { aSettingsKeyP = new TBinfileProfilesKey(fEngineInterfaceP); } else { // cannot access profiles of inactive binfile layer return LOCERR_WRONGUSAGE; } } else if (strucmp(aName,"synclogs",aNameSize)==0) aSettingsKeyP = new TBinfileLogsKey(fEngineInterfaceP); else return inherited::OpenSubKeyByName(aSettingsKeyP,aName,aNameSize,aMode); // opened a key return LOCERR_OK; } // TBinfileAgentRootKey::OpenSubKeyByName // Client runtime settings key // --------------------------- // Constructor TBinFileAgentParamsKey::TBinFileAgentParamsKey(TEngineInterface *aEngineInterfaceP, TSyncAgent *aClientSessionP) : inherited(aEngineInterfaceP,aClientSessionP) { } // TBinFileAgentParamsKey::TBinFileAgentParamsKey // open subkey by name (not by path!) TSyError TBinFileAgentParamsKey::OpenSubKeyByName( TSettingsKeyImpl *&aSettingsKeyP, cAppCharP aName, stringSize aNameSize, uInt16 aMode ) { if (strucmp(aName,"profile",aNameSize)==0) { // get binfileclient session pointer TBinfileImplClient *bfclientP = static_cast(fAgentP); // opens current session's active profile aSettingsKeyP = new TBinfileProfileKey( fEngineInterfaceP, -1, // signals passing active session's profile &bfclientP->fProfile, // pointer to the current session's profile bfclientP->fConfigP // the config ); } else return inherited::OpenSubKeyByName(aSettingsKeyP,aName,aNameSize,aMode); // opened a key return LOCERR_OK; } // TBinFileAgentParamsKey::OpenSubKeyByName #endif // ENGINEINTERFACE_SUPPORT // Config // ====== TBinfileClientConfig::TBinfileClientConfig(TConfigElement *aParentElement) : TAgentConfig("BinFileDBClient",aParentElement) { } // TBinfileClientConfig::TBinfileClientConfig TBinfileClientConfig::~TBinfileClientConfig() { clear(); } // TBinfileClientConfig::~TBinfileClientConfig // init defaults void TBinfileClientConfig::clear(void) { // Only active in clients by default fBinfilesActive = IS_CLIENT; #ifndef HARDCODED_CONFIG // init defaults fSeparateChangelogs = true; // for engine libraries with full config, use separated changelogs by default (auto-migration w/o side effects is built-in) fBinFilesPath.erase(); #else fSeparateChangelogs = false; // for traditional hard-coded clients like WinMobile and PalmOS, use pre 3.4.0.10 behaviour (uses less memory) #endif fBinFileLog=false; // - clear inherited inherited::clear(); } // TBinfileClientConfig::clear #ifndef HARDCODED_CONFIG // config element parsing bool TBinfileClientConfig::localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine) { // checking the elements // - binfiles path if (strucmp(aElementName,"binfilespath")==0) expectMacroString(fBinFilesPath); else if (strucmp(aElementName,"binfilelog")==0) expectBool(fBinFileLog); else if (strucmp(aElementName,"binfilesactive")==0) expectBool(fBinfilesActive); else if (strucmp(aElementName,"separatechangelogs")==0) expectBool(fSeparateChangelogs); // - none known here else return inherited::localStartElement(aElementName,aAttributes,aLine); // ok return true; } // TBinfileClientConfig::localStartElement #endif // update profile record contents static uInt32 profileUpdateFunc(uInt32 aOldVersion, uInt32 aNewVersion, void *aOldRecordData, void *aNewRecordData, uInt32 aOldSize) { if (aOldVersionPROFILE_DB_VERSION) return 0; // unknown old or newer than current version, cannot update if (aNewVersion!=PROFILE_DB_VERSION) return 0; // cannot update to other version than current // create default values for profile if (aOldRecordData && aNewRecordData) { TBinfileDBSyncProfile *profileP = (TBinfileDBSyncProfile *)aNewRecordData; // make an empty default profile TBinfileClientConfig::initProfile(*profileP, "dummy", true); #if (PROFILE_DB_VERSION>=6) && (LOWEST_PROFILE_DB_VERSION<6) // copy in old version's data if (aOldVersion<=5) { // between 5 and 6, sizes of user and pw fields have all changed in size, so we need // to copy field-by-field o_TBinfileDBSyncProfile *oP=(o_TBinfileDBSyncProfile *)aOldRecordData; // now copy profileP->profileID = oP->profileID; AssignCString(profileP->profileName,oP->profileName,maxnamesiz); profileP->encoding = oP->encoding; AssignCString(profileP->serverURI,oP->serverURI,maxurisiz); AssignCString(profileP->serverUser,oP->serverUser,maxupwsiz); memcpy(profileP->serverPassword,oP->serverPassword,o_maxupwsiz); AssignCString(profileP->transportUser,oP->transportUser,maxupwsiz); memcpy(profileP->transportPassword,oP->transportPassword,o_maxupwsiz); AssignCString(profileP->socksHost,oP->socksHost,maxurisiz); AssignCString(profileP->proxyHost,oP->proxyHost,maxurisiz); profileP->sessionID = oP->sessionID; profileP->lastSyncMLVersion = oP->lastSyncMLVersion; profileP->lastAuthMethod = oP->lastAuthMethod; profileP->lastAuthFormat = oP->lastAuthFormat; AssignCString(profileP->lastNonce,oP->lastNonce,maxnoncesiz); profileP->firstuse = oP->firstuse; if (aOldVersion>=5) { // can only be OldVersion==5 // copy additional PROFILE_DB_VERSION 5 settings AssignCString(profileP->URIpath,oP->URIpath,maxpathsiz); profileP->protocol = oP->protocol; profileP->readOnlyFlags = oP->readOnlyFlags; AssignCString(profileP->localDBProfileName,oP->localDBProfileName,localDBpathMaxLen); profileP->useProxy = oP->useProxy; profileP->useConnectionProxy = oP->useConnectionProxy; // - Auto-Sync levels (3 levels, first match overrides lower level settings) profileP->AutoSyncLevel[0]=oP->AutoSyncLevel[0]; profileP->AutoSyncLevel[1]=oP->AutoSyncLevel[1]; profileP->AutoSyncLevel[2]=oP->AutoSyncLevel[2]; profileP->TimedSyncMobilePeriod = oP->TimedSyncMobilePeriod; profileP->TimedSyncCradledPeriod = oP->TimedSyncCradledPeriod; // - IPP settings are not copied, they have changed a bit between 6 and 7 } } #endif if (aOldVersion<7) { // as ippsettings have changed between 6 and 7, do not copy them, but erase them #if PROFILE_DB_VERSION>=5 profileP->ippSettings.id[0]=0; profileP->ippSettings.cred[0]=0; profileP->ippSettings.srv[0]=0; profileP->ippSettings.method=0; #endif } // From Version 7 onwards, only some fields were added at the end, so simple copy is ok if (aOldVersion==7) { memcpy(aNewRecordData,aOldRecordData,PROFILE_DB_VERSION_7_SZ); } if (aOldVersion==8) { memcpy(aNewRecordData,aOldRecordData,PROFILE_DB_VERSION_8_SZ); } /* when we have PROFILE_DB_VERSION > 9 if (aOldVersion==9) { memcpy(aNewRecordData,aOldRecordData,PROFILE_DB_VERSION_9_SZ); } */ } // updated ok (or updateable ok if no data pointers provided) return sizeof(TBinfileDBSyncProfile); } // profileUpdateFunc // update target record contents static uInt32 targetUpdateFunc(uInt32 aOldVersion, uInt32 aNewVersion, void *aOldRecordData, void *aNewRecordData, uInt32 aOldSize) { if (aOldVersionTARGETS_DB_VERSION) return 0; // unknown old version, cannot update if (aNewVersion!=TARGETS_DB_VERSION) return 0; // cannot update to other version than current // create default values for profile if (aOldRecordData && aNewRecordData) { TBinfileDBSyncTarget *targetP = (TBinfileDBSyncTarget *)aNewRecordData; // copy old data - beginning of record is identical memcpy(aNewRecordData,aOldRecordData,aOldSize); // now initialize fields that old version didn't have if (aOldVersion<4) { // init new version 4 fields targetP->resumeAlertCode = 0; // also wipe out version 3 "lastModCount", which now becomes "lastSuspendModCount" targetP->lastSuspendModCount = 0; } #if TARGETS_DB_VERSION >= 5 if (aOldVersion<5) { // init new version 5 fields AssignCString(targetP->localContainerName,NULL,localDBpathMaxLen); } #endif #if TARGETS_DB_VERSION >= 6 if (aOldVersion<6) { // init new version 6 fields AssignCString(targetP->dummyIdentifier1,NULL,remoteAnchorMaxLen); AssignCString(targetP->dummyIdentifier2,NULL,remoteAnchorMaxLen); AssignCString(targetP->remoteDBdispName,NULL,dispNameMaxLen); AssignCString(targetP->filterCapDesc,NULL,filterCapDescMaxLen); AssignCString(targetP->remoteFilters,NULL,filterExprMaxLen); AssignCString(targetP->localFilters,NULL,filterExprMaxLen); } #endif } // updated ok (or updateable ok if no data pointers provided) // - return size of new record return sizeof(TBinfileDBSyncTarget); } // targetUpdateFunc // get path where to store binfiles void TBinfileClientConfig::getBinFilesPath(string &aPath) { #ifndef HARDCODED_CONFIG if (!fBinFilesPath.empty()) aPath = fBinFilesPath; else #endif { // use appdata directory as defined by the current platform/OS if (!getPlatformString(pfs_appdata_path,aPath)) { // we have no path aPath.erase(); } } // make OS path of it (if not empty) and create directory if not existing yet if (!aPath.empty()) { // make sure it exists makeOSDirPath(aPath,true); } }; // TBinfileClientConfig::getBinFilesPath // open settings databases localstatus TBinfileClientConfig::openSettingsDatabases(bool aDoLoose) { if (!fBinfilesActive) { // databases can be opened only with active binfiles layer return LOCERR_WRONGUSAGE; } else { // safe for calling more than once if (fProfileBinFile.isOpen() && fTargetsBinFile.isOpen()) return LOCERR_OK; // already open - ok // open profile and targets databases // - get base path string basepath; getBinFilesPath(basepath); string usedpath; bool newprofiles=false; bferr err; // - profiles usedpath=basepath + PROFILE_DB_NAME; fProfileBinFile.setFileInfo(usedpath.c_str(),PROFILE_DB_VERSION,PROFILE_DB_ID,sizeof(TBinfileDBSyncProfile)); err = fProfileBinFile.open(0,NULL,profileUpdateFunc); if (err!=BFE_OK) { // create new one or overwrite incompatible one if allowed if (aDoLoose || err!=BFE_BADVERSION) { err=fProfileBinFile.create(sizeof(TBinfileDBSyncProfile),0,NULL,true); newprofiles=true; } else { // would create new file due to bad (newer or non-upgradeable older) version return LOCERR_CFGPARSE; // this is kind of a config parsing error } } // - targets usedpath=basepath + TARGETS_DB_NAME; fTargetsBinFile.setFileInfo(usedpath.c_str(),TARGETS_DB_VERSION,TARGETS_DB_ID,sizeof(TBinfileDBSyncTarget)); err = fTargetsBinFile.open(0,NULL,targetUpdateFunc); if (err!=BFE_OK || newprofiles) { // create new one or overwrite incompatible one // also ALWAYS create new targets if we HAVE created new profiles if (aDoLoose || newprofiles || err!=BFE_BADVERSION) { err=fTargetsBinFile.create(sizeof(TBinfileDBSyncTarget),0,NULL,true); } else { // would create new file due to bad (newer or non-upgradeable older) version return LOCERR_CFGPARSE; // this is kind of a config parsing error } } return err; } } // TBinfileClientConfig::openSettingsDatabases // close settings databases void TBinfileClientConfig::closeSettingsDatabases(void) { // open profile and targets databases fProfileBinFile.close(); fTargetsBinFile.close(); } // TBinfileClientConfig::closeSettingsDatabases // resolve void TBinfileClientConfig::localResolve(bool aLastPass) { // resolve inherited inherited::localResolve(aLastPass); } // TBinfileClientConfig::localResolve // MUST be called after creating config to load (or pre-load) variable parts of config // such as binfile profiles. If aDoLoose==false, situations, where existing config // is detected but cannot be re-used will return an error. With aDoLoose==true, config // files etc. are created even if it means a loss of data. localstatus TBinfileClientConfig::loadVarConfig(bool aDoLoose) { // let inherited to it's stuff localstatus err=inherited::loadVarConfig(aDoLoose); if (fBinfilesActive) { // now do my own stuff if (err==LOCERR_OK) { err=openSettingsDatabases(aDoLoose); } } // return status return err; } // TBinfileClientConfig::loadVarConfig // save app state (such as settings in datastore configs etc.) void TBinfileClientConfig::saveAppState(void) { if (fBinfilesActive) { // close and re-open the settings binfiles to make sure their // contents is permanently saved closeSettingsDatabases(); openSettingsDatabases(false); } } // TBinfileClientConfig::saveAppState // API for settings management // initialize a new-created profile database void TBinfileClientConfig::initProfileDb(void) { // create default profile newProfile("Default",true); } // TBinfileClientConfig::initProfileDb // Defaults for profile #ifndef DEFAULT_ENCODING #define DEFAULT_ENCODING SML_WBXML #endif #ifndef DEFAULT_SERVER_URI #define DEFAULT_SERVER_URI NULL #endif #ifndef DEFAULT_URI_PATH #define DEFAULT_URI_PATH NULL #endif #ifndef DEFAULT_SERVER_USER #define DEFAULT_SERVER_USER NULL #endif #ifndef DEFAULT_SERVER_PASSWD #define DEFAULT_SERVER_PASSWD NULL #endif #ifndef DEFAULT_TRANSPORT_USER #define DEFAULT_TRANSPORT_USER NULL #endif #ifndef DEFAULT_TRANSPORT_PASSWD #define DEFAULT_TRANSPORT_PASSWD NULL #endif #ifndef DEFAULT_SOCKS_HOST #define DEFAULT_SOCKS_HOST NULL #endif #ifndef DEFAULT_PROXY_HOST #define DEFAULT_PROXY_HOST NULL #endif #ifndef DEFAULT_PROXY_USER #define DEFAULT_PROXY_USER NULL #endif #ifndef DEFAULT_PROXY_PASSWD #define DEFAULT_PROXY_PASSWD NULL #endif #ifndef DEFAULT_DATASTORES_ENABLED #define DEFAULT_DATASTORES_ENABLED false #endif #ifndef DEFAULT_LOCALDB_PROFILE #define DEFAULT_LOCALDB_PROFILE NULL #endif #ifndef DEFAULT_USESYSTEMPROXY #define DEFAULT_USESYSTEMPROXY true #endif // create new profile with targets for all configured datastores // - returns index of new profile sInt32 TBinfileClientConfig::newProfile(const char *aProfileName, bool aSetDefaults, sInt32 aTemplateProfile) { TBinfileDBSyncProfile profile; TBinfileDBSyncTarget target; sInt32 profileIndex; TBinfileDBSyncProfile templateprofile; TBinfileDBSyncTarget templatetarget; // create profile record initProfile(profile,aProfileName,aSetDefaults); #ifdef EXPIRES_AFTER_DAYS // copy date of first use (to see if someone tried to tamper with...) uInt32 vers; getSyncAppBase()->getFirstUseInfo(SYSER_VARIANT_CODE,profile.firstuse,vers); #endif // copy from template profile, if any if (aTemplateProfile>=0) { aTemplateProfile=getProfile(aTemplateProfile,templateprofile); } if (aTemplateProfile>=0) { // copy user config profile.encoding=templateprofile.encoding; #ifndef HARD_CODED_SERVER_URI strncpy(profile.serverURI,templateprofile.serverURI,maxurisiz); // if hardcoded, don't copy from template #endif strncpy(profile.serverUser,templateprofile.serverUser,maxupwsiz); strncpy(profile.transportUser,templateprofile.transportUser,maxupwsiz); strncpy(profile.socksHost,templateprofile.socksHost,maxurisiz); strncpy(profile.proxyHost,templateprofile.proxyHost,maxurisiz); strncpy(profile.proxyUser,templateprofile.proxyUser,maxupwsiz); // additional proxy flags profile.useProxy=templateprofile.useProxy; profile.useConnectionProxy=templateprofile.useConnectionProxy; // improved URI settings strncpy(profile.URIpath,templateprofile.URIpath,maxpathsiz); profile.protocol=templateprofile.protocol; // feature flags profile.readOnlyFlags = 0; // no read-only flags by default profile.featureFlags=templateprofile.featureFlags; // inherit features profile.dsAvailFlags=templateprofile.dsAvailFlags; // inherit datastore availability // extras profile.transpFlags=templateprofile.transpFlags; // inherit transport related flags profile.profileFlags=templateprofile.profileFlags; // inherit general profile flags // Note: do not copy profileExtra1/2 and profileData - as these are too app specific // local DB profile (not used in PPC, only for Outlook client) strncpy(profile.localDBProfileName,templateprofile.localDBProfileName,localDBpathMaxLen); // autosync settings profile.AutoSyncLevel[0]=templateprofile.AutoSyncLevel[0]; profile.AutoSyncLevel[1]=templateprofile.AutoSyncLevel[1]; profile.AutoSyncLevel[2]=templateprofile.AutoSyncLevel[2]; // timed sync settings profile.TimedSyncMobilePeriod=templateprofile.TimedSyncMobilePeriod; profile.TimedSyncCradledPeriod=templateprofile.TimedSyncCradledPeriod; /* %%% do not copy IPP settings, these should be provisioned by the SyncML server // IPP settings (not available in all clients, but present in all profile records profile.ippSettings=templateprofile.ippSettings; */ } #ifndef HARD_CODED_SERVER_URI // override with config-defined fixed server URL, if any if (!fServerURI.empty()) { strncpy(profile.serverURI,fServerURI.c_str(),maxurisiz); profile.readOnlyFlags = rdonly_URI; // make URI readonly } #endif // save profile record profileIndex=writeProfile(-1,profile); // create a target for each configured datastore // Note: create target also for not available datastores TLocalDSList::iterator pos; for (pos=fDatastores.begin();pos!=fDatastores.end();pos++) { if ((*pos)->isAbstractDatastore()) continue; // don't try to create targets for abstract datastores (like superdatastores) // non-abstract datastores at this point are always binfile-based by definition (this is a binfileimplclient, and this is one of its datastores) TBinfileDSConfig *cfgP = static_cast(*pos); cfgP->initTarget(target,profile.profileID,aSetDefaults ? NULL : "",aSetDefaults && DEFAULT_DATASTORES_ENABLED); // remote datastore names default to local ones, empty if not default // copy from template if (aTemplateProfile>=0) { // find matching template target sInt32 tti=findTargetIndexByDBInfo( templateprofile.profileID, // profile to search targets for cfgP->fLocalDBTypeID, NULL // can be NULL if name does not matter ); if (tti>=0) { getTarget(tti,templatetarget); // copy user config strncpy(target.remoteDBpath,templatetarget.remoteDBpath,remoteDBpathMaxLen); target.syncmode=templatetarget.syncmode; target.limit1=templatetarget.limit1; target.limit2=templatetarget.limit2; target.extras=templatetarget.extras; } } // save target record writeTarget(-1,target); } return profileIndex; } // TBinfileClientConfig::newProfile // helper static void AssignDefault(char *aCStr, bool aWithDefaults, const char *aDefault, size_t aLen) { if (aWithDefaults) AssignCString(aCStr,aDefault,aLen); else AssignCString(aCStr,NULL,aLen); } // AssignDefault // init empty profile record void TBinfileClientConfig::initProfile(TBinfileDBSyncProfile &aProfile, const char *aName, bool aWithDefaults) { // - wipe it to all zeroes to make sure we don't save any garbage under no circumstances memset((void *)&aProfile,0,sizeof(TBinfileDBSyncProfile)); // - Name if (aName==0) aName=""; strncpy(aProfile.profileName,aName,maxnamesiz); // - encoding defaults to WBXML aProfile.encoding=DEFAULT_ENCODING; AssignDefault(aProfile.serverURI,aWithDefaults, DEFAULT_SERVER_URI, maxurisiz); // - suffix (for hardcoded base URI versions) AssignDefault(aProfile.URIpath,aWithDefaults, DEFAULT_URI_PATH, maxpathsiz); #ifdef PROTOCOL_SELECTOR aProfile.protocol=PROTOCOL_SELECTOR; #else aProfile.protocol=transp_proto_uri; #endif aProfile.readOnlyFlags=0; // all read&write so far aProfile.remoteFlags=0; // no remote specifics known so far #ifdef FTRFLAGS_ALWAYS_AVAILABLE aProfile.featureFlags=FTRFLAGS_ALWAYS_AVAILABLE; // set default availability #else aProfile.featureFlags=0; // no special feature flags #endif #ifdef DSFLAGS_ALWAYS_AVAILABLE aProfile.dsAvailFlags=DSFLAGS_ALWAYS_AVAILABLE; // set default availability #else aProfile.dsAvailFlags=0; // no extra DS enabled #endif // - User name AssignDefault(aProfile.serverUser,aWithDefaults, DEFAULT_SERVER_USER, maxupwsiz); // - password, mangled assignMangledToCString(aProfile.serverPassword, (const char *)(aWithDefaults ? DEFAULT_SERVER_PASSWD : NULL), maxupwsiz,true); // - Transport user AssignDefault(aProfile.transportUser,aWithDefaults, DEFAULT_TRANSPORT_USER, maxupwsiz); // - Transport password, mangled assignMangledToCString(aProfile.transportPassword, (const char *)(aWithDefaults ? DEFAULT_TRANSPORT_PASSWD : NULL), maxupwsiz,true); // - Socks Host AssignDefault(aProfile.socksHost,aWithDefaults, DEFAULT_SOCKS_HOST, maxurisiz); // - Proxy Host AssignDefault(aProfile.proxyHost,aWithDefaults, DEFAULT_PROXY_HOST, maxurisiz); // - local DB profile name AssignDefault(aProfile.localDBProfileName,true,DEFAULT_LOCALDB_PROFILE,localDBpathMaxLen); // - additional proxy flags aProfile.useProxy=aProfile.proxyHost[0]!=0; // use if a default proxy is defined aProfile.useConnectionProxy=DEFAULT_USESYSTEMPROXY; // use proxy from connection if available // - proxy user AssignDefault(aProfile.proxyUser,aWithDefaults, DEFAULT_PROXY_USER, maxupwsiz); // - proxy password, mangled assignMangledToCString(aProfile.proxyPassword, (const char *)(aWithDefaults ? DEFAULT_PROXY_PASSWD : NULL), maxupwsiz,true); // - extra flags aProfile.transpFlags = 0; aProfile.profileFlags = 0; // - general purpose reserved fields aProfile.profileExtra1 = 0; aProfile.profileExtra2 = 0; memset(&aProfile.profileData, 0, profiledatasiz); // - automatic sync scheduling aProfile.AutoSyncLevel[0].Mode=autosync_none; // not enabled aProfile.AutoSyncLevel[0].StartDayTime=8*60; // 8:00 AM aProfile.AutoSyncLevel[0].EndDayTime=17*60; // 5:00 PM (17:00) aProfile.AutoSyncLevel[0].WeekdayMask=0x3E; // Mo-Fr aProfile.AutoSyncLevel[0].ChargeLevel=60; // 60% battery level needed aProfile.AutoSyncLevel[0].MemLevel=10; // 10% memory must be free aProfile.AutoSyncLevel[0].Flags=0; // no flags so far aProfile.AutoSyncLevel[1].Mode=autosync_none; // not enabled aProfile.AutoSyncLevel[1].StartDayTime=0; aProfile.AutoSyncLevel[1].EndDayTime=0; aProfile.AutoSyncLevel[1].WeekdayMask=0; aProfile.AutoSyncLevel[1].ChargeLevel=0; aProfile.AutoSyncLevel[1].MemLevel=0; aProfile.AutoSyncLevel[1].Flags=0; aProfile.AutoSyncLevel[2].Mode=autosync_none; // not enabled aProfile.AutoSyncLevel[2].StartDayTime=0; aProfile.AutoSyncLevel[2].EndDayTime=0; aProfile.AutoSyncLevel[2].WeekdayMask=0; aProfile.AutoSyncLevel[2].ChargeLevel=0; aProfile.AutoSyncLevel[2].MemLevel=0; aProfile.AutoSyncLevel[2].Flags=0; // Timed sync settings aProfile.TimedSyncMobilePeriod=2*60; // every 2 hours aProfile.TimedSyncCradledPeriod=15; // every 15 minutes // IPP settings aProfile.ippSettings.srv[0]=0; aProfile.ippSettings.port=0; aProfile.ippSettings.period=5*60; // 5 mins aProfile.ippSettings.path[0]=0; aProfile.ippSettings.id[0]=0; aProfile.ippSettings.method=0; // none defined aProfile.ippSettings.cred[0]=0; aProfile.ippSettings.maxinterval=0; aProfile.ippSettings.timedds[0]=0; // Internals // - session ID aProfile.sessionID=0; // - last connection's parameters (used as default for next session) aProfile.lastSyncMLVersion=syncml_vers_unknown; aProfile.lastAuthMethod=auth_none; aProfile.lastAuthFormat=fmt_chr; AssignCString(aProfile.lastNonce,NULL,maxnoncesiz); } // initProfile // checks that all profiles are complete with targets for all configured datastores // (in case of STD->PRO upgrade for example) void TBinfileClientConfig::checkProfiles(void) { for (sInt32 pidx=0; pidxPRO upgrade for example) void TBinfileClientConfig::checkProfile(sInt32 aProfileIndex) { TBinfileDBSyncProfile profile; // get profile record if (getProfile(aProfileIndex,profile)>=0) { // make sure a target exists for each configured datastore // Note: also creates targets for currently unavailable datastores (profile.dsAvailFlags, license...) TLocalDSList::iterator pos; for (pos=fDatastores.begin();pos!=fDatastores.end();pos++) { TBinfileDSConfig *cfgP = static_cast(*pos); // find matching template target findOrCreateTargetIndexByDBInfo( profile.profileID, // profile to search targets for cfgP->fLocalDBTypeID, NULL // can be NULL if name does not matter ); } } } // TBinfileClientConfig::newProfile // - write profile, returns index of profile sInt32 TBinfileClientConfig::writeProfile( sInt32 aProfileIndex, // -1 if adding new profile TBinfileDBSyncProfile &aProfile // profile ID is set to new ID in aProfile ) { uInt32 newindex=aProfileIndex; if (aProfileIndex<0) { // set new unqiue ID aProfile.profileID=fProfileBinFile.getNextUniqueID(); // create new record fProfileBinFile.newRecord(newindex,&aProfile); // make sure header is up to date (in case we terminate improperly) fProfileBinFile.flushHeader(); } else { // find record fProfileBinFile.updateRecord(aProfileIndex,&aProfile); } // return index of data return newindex; } // TBinfileClientConfig::writeProfile // - delete profile (and all of its targets) bool TBinfileClientConfig::deleteProfile(sInt32 aProfileIndex) { // remove all targets sInt32 idx; uInt32 profileID = getIDOfProfile(aProfileIndex); if (profileID==0) return false; do { // find first (still existing) target for this profile idx = findTargetIndex(profileID,0); if (idx<0) break; // no more targets // if we have separate changelogs or this is the last profile, also delete targets' changelogs if (fSeparateChangelogs || fProfileBinFile.getNumRecords()<=1) { // clean related changelogs cleanChangeLogForTarget(idx,profileID); } // delete target deleteTarget(idx); } while (true); // remove profile itself if (fProfileBinFile.deleteRecord(aProfileIndex)!=BFE_OK) return false; if (fProfileBinFile.getNumRecords()==0) { // last profile deleted, remove file itself to clean up as much as possible fProfileBinFile.closeAndDelete(); // re-create fProfileBinFile.create(sizeof(TBinfileDBSyncProfile),0,NULL,true); } else { // make sure header is up to date (in case we terminate improperly) fProfileBinFile.flushHeader(); } // return return true; } // TBinfileClientConfig::deleteProfile // - get number of existing profiles sInt32 TBinfileClientConfig::numProfiles(void) { return fProfileBinFile.getNumRecords(); } // TBinfileClientConfig::numProfiles // - get profile, returns index or -1 if no more profiles sInt32 TBinfileClientConfig::getProfile( sInt32 aProfileIndex, TBinfileDBSyncProfile &aProfile ) { if (fProfileBinFile.readRecord(aProfileIndex,&aProfile)!=BFE_OK) return -1; return aProfileIndex; } // TBinfileClientConfig::getProfile // - get index of profile by ID sInt32 TBinfileClientConfig::getProfileIndex(uInt32 aProfileID) { TBinfileDBSyncProfile profile; return getProfileByID(aProfileID,profile); } // TBinfileClientConfig::getProfileIndex // - get profile by ID, returns index or -1 if no profile found // Note: aProfile might be writte even if profile is not found sInt32 TBinfileClientConfig::getProfileByID( uInt32 aProfileID, TBinfileDBSyncProfile &aProfile ) { sInt32 aIndex=0; while (true) { aIndex = getProfile(aIndex,aProfile); if (aIndex<0) break; // not found // check ID if (aProfile.profileID == aProfileID) break; // next profile aIndex++; } return aIndex; } // TBinfileClientConfig::getProfile // - get profile index from name, returns index or -1 if no matching profile found sInt32 TBinfileClientConfig::getProfileIndexByName(cAppCharP aProfileName) { sInt32 np = numProfiles(); sInt32 pi = np; TBinfileDBSyncProfile profile; while (pi>0) { pi--; getProfile(pi,profile); if (strucmp(profile.profileName,aProfileName)==0) { return pi; // found, return index } } return -1; // not found } // TBinfileClientConfig::getProfileByName // - get ID of profile from index, 0 if none found uInt32 TBinfileClientConfig::getIDOfProfile(sInt32 aProfileIndex) { // get profile ID TBinfileDBSyncProfile profile; if (fProfileBinFile.readRecord(aProfileIndex,&profile)!=BFE_OK) return 0; return profile.profileID; } // TBinfileClientConfig::getIDOfProfile // - get last sync (earliest of lastSync of all sync-enabled targets), 0=never bool TBinfileClientConfig::getProfileLastSyncTime(uInt32 aProfileID, lineartime_t &aLastSync, bool &aZapsServer, bool &aZapsClient) { sInt32 i,targetIndex; uInt32 dbid; lineartime_t targlast; aLastSync=maxLinearTime; aZapsServer=false; aZapsClient=false; bool zs,zc; i=0; do { targetIndex=findTargetIndex(aProfileID,i++); if (targetIndex<0) break; // get last sync of this target if (getTargetLastSyncTime(targetIndex,targlast,zs,zc,dbid)) { // enabled target if (targlastisFeatureEnabled(aFeatureNo)) return false; // this feature is not enabled at all #ifdef FTRFLAGS_ALWAYS_AVAILABLE // check for profile-level enabling // - get flag for feature No uInt8 ftrflag=0; switch (aFeatureNo) { case APP_FTR_AUTOSYNC: ftrflag=ftrflg_autosync; break; case APP_FTR_IPP: ftrflag=ftrflg_dmu; break; case APP_FTR_EVENTRANGE: case APP_FTR_EMAILRANGE: ftrflag=ftrflg_range; break; default : return true; // not a profile-level feature, but it is globally on -> is enabled } // - check if generally enabled even if not in profile flags if ((ftrflag & FTRFLAGS_ALWAYS_AVAILABLE)!=0) return true; // always available (hardcoded) // - now it depends on the profile flags return (aProfileP && (aProfileP->featureFlags & ftrflag)!=0); #else // no profile level feature enabling - everything that is globally enabled is also enabled in this profile return true; #endif } // TBinfileClientConfig::isFeatureEnabled // - check for feature enabled (profile or license dependent) bool TBinfileClientConfig::isReadOnly(sInt32 aProfileIndex, uInt8 aReadOnlyMask) { TBinfileDBSyncProfile profile; if (getProfile(aProfileIndex,profile)<0) return true; // make all read-only if we have no profile else return isReadOnly(&profile, aReadOnlyMask); // check if available in this profile } // TBinfileClientConfig::isFeatureEnabled // - check for readonly (profile or license dependent) bool TBinfileClientConfig::isReadOnly(TBinfileDBSyncProfile *aProfileP, uInt8 aReadOnlyMask) { // check special hardcoded cases #ifdef HARD_CODED_DBNAMES if (aReadOnlyMask & rdonly_dbpath) return true; // with hardcoded DB names, these are ALWAYS readonly #endif #ifdef HARD_CODED_SERVER_URI if (aReadOnlyMask & rdonly_URI) return true; // with hardcoded URI, this is ALWAYS readonly #endif // just check profile flags if (!aProfileP) return true; // make all read-only if we have no profile return aProfileP->readOnlyFlags & aReadOnlyMask; // readonly if flag is set in profile } // TBinfileClientConfig::isReadOnly // - check if datastore of specified target is available // in the given profile bool TBinfileClientConfig::isTargetAvailable( TBinfileDBSyncProfile *aProfileP, uInt32 aLocalDBTypeID ) { TLocalDSList::iterator pos; for (pos=fDatastores.begin();pos!=fDatastores.end();pos++) { TBinfileDSConfig *cfgP = static_cast(*pos); if ( cfgP->fLocalDBTypeID==aLocalDBTypeID ) { // right datastore config found // - return it's availability status return cfgP->isAvailable(aProfileP); } } // datastore not found -> not available return false; } // TBinfileClientConfig::isTargetAvailable // - find available target for profile by DB ID/name. Returns target index or -1 if // DBTypeID not available in this profile/license or not implemented at all sInt32 TBinfileClientConfig::findAvailableTargetIndexByDBInfo( TBinfileDBSyncProfile *aProfileP, // profile to search targets for uInt32 aLocalDBTypeID, const char *aLocalDBName // can be NULL if name does not matter ) { if (!isTargetAvailable(aProfileP,aLocalDBTypeID)) return -1; if (!aProfileP) return -1; // no profile, no target return findOrCreateTargetIndexByDBInfo(aProfileP->profileID,aLocalDBTypeID,aLocalDBName); } // TBinfileClientConfig::findAvailableTargetIndexByDBInfo // - find target for profile by DB ID/name. Returns target index or -1 if none found sInt32 TBinfileClientConfig::findOrCreateTargetIndexByDBInfo( uInt32 aProfileID, // profile to search targets for uInt32 aLocalDBTypeID, const char *aLocalDBName // can be NULL if name does not matter ) { sInt32 targidx; TBinfileDBSyncTarget target; targidx=findTargetIndexByDBInfo(aProfileID,aLocalDBTypeID,aLocalDBName); if (targidx<0) { // does not exist yet, create it now TLocalDSList::iterator pos; for (pos=fDatastores.begin();pos!=fDatastores.end();pos++) { if ((*pos)->isAbstractDatastore()) continue; // only non-abstract datastores are guaranteed binfileds and have a target TBinfileDSConfig *cfgP = static_cast(*pos); if ( cfgP->fLocalDBTypeID==aLocalDBTypeID && (aLocalDBName==NULL || cfgP->fLocalDBPath==aLocalDBName) ) { // right datastore found cfgP->initTarget(target,aProfileID,NULL,DEFAULT_DATASTORES_ENABLED); // init default // write new target and get a index back targidx=writeTarget(-1,target); // done break; } } } return targidx; } // findOrCreateTargetIndexByDBInfo // - find target for profile by DB ID/name. Returns target index or -1 if none found sInt32 TBinfileClientConfig::findTargetIndexByDBInfo( uInt32 aProfileID, // profile to search targets for uInt32 aLocalDBTypeID, const char *aLocalDBName // can be NULL if name does not matter ) { // now search targets TBinfileDBSyncTarget target; sInt32 maxidx = fTargetsBinFile.getNumRecords(); sInt32 targidx; for (targidx=0; targidx=0) { StringObjAppendPrintf(basefilename, "_%d",aProfileID); } return basefilename; } // completely clear changelog and pending maps for specified target void TBinfileClientConfig::cleanChangeLogForTarget(sInt32 aTargetIndex, sInt32 aProfileID) { TBinfileDBSyncTarget target; getTarget(aTargetIndex,target); cleanChangeLogForDBname(target.dbname, aProfileID); } // TBinfileClientConfig::cleanChangeLogForTarget // completely clear changelog and pending maps for specified database name and profile void TBinfileClientConfig::cleanChangeLogForDBname(cAppCharP aDBName, sInt32 aProfileID) { // open changelog. Name is datastore name with _XXX_clg.bfi suffix (XXX=profileID, if negative, combined changelog/maps/pendingitem will be deleted) string basefilename = relatedDBNameBase(aDBName, aProfileID); string filename; TBinFile binfile; // delete changelog filename = basefilename + CHANGELOG_DB_SUFFIX; binfile.setFileInfo(filename.c_str(),CHANGELOG_DB_VERSION,CHANGELOG_DB_ID,0); binfile.closeAndDelete(); // delete pending maps filename = basefilename + PENDINGMAP_DB_SUFFIX; binfile.setFileInfo(filename.c_str(),PENDINGMAP_DB_VERSION,PENDINGMAP_DB_ID,0); binfile.closeAndDelete(); // delete pending item filename = basefilename + PENDINGITEM_DB_SUFFIX; binfile.setFileInfo(filename.c_str(),PENDINGITEM_DB_VERSION,PENDINGITEM_DB_ID,0); binfile.closeAndDelete(); } // TBinfileClientConfig::cleanChangeLogForDBname void TBinfileClientConfig::separateDBFile(cAppCharP aDBName, cAppCharP aDBSuffix, sInt32 aProfileID) { TBinFile sourceFile; TBinFile targetFile; string sourceName = relatedDBNameBase(aDBName, -1) + aDBSuffix; // without profile ID in name string targetName = relatedDBNameBase(aDBName, aProfileID) + aDBSuffix; // with profile ID in name sourceFile.setFileInfo(sourceName.c_str(), 0, 0, 0); targetFile.setFileInfo(targetName.c_str(), 0, 0, 0); targetFile.createAsCopyFrom(sourceFile); } // separate changelogs and other related files into separate files for each profile void TBinfileClientConfig::separateChangeLogsAndRelated(cAppCharP aDBName) { // iterate over all profiles TBinfileDBSyncProfile profile; sInt32 idx = 0; // set up original basename while (true) { idx = getProfile(idx,profile); if (idx<0) break; // no more profiles // copy all dependent files of that profile and the given database // - copy changelog separateDBFile(aDBName,CHANGELOG_DB_SUFFIX,profile.profileID); // - copy pendingmaps separateDBFile(aDBName,PENDINGMAP_DB_SUFFIX,profile.profileID); // - copy pendingitem separateDBFile(aDBName,PENDINGITEM_DB_SUFFIX,profile.profileID); // next profile idx++; } // - delete original files that were shared between profiles cleanChangeLogForDBname(aDBName,-1); } // remote provisioning (using generic code in include file) #include "clientprovisioning_inc.cpp" // Autosync mechanisms (using generic code in include file) #include "clientautosync_inc.cpp" /* * Implementation of TBinfileImplClient */ /* public TBinfileImplClient members */ TBinfileImplClient::TBinfileImplClient(TSyncAppBase *aSyncAppBaseP, TSyncSessionHandle *aSyncSessionHandleP, cAppCharP aSessionID) : TStdLogicAgent(aSyncAppBaseP, aSyncSessionHandleP, aSessionID), fConfigP(NULL) { // get config for agent TRootConfig *rootcfgP = aSyncAppBaseP->getRootConfig(); // - save direct link to agent config for easy reference fConfigP = static_cast(rootcfgP->fAgentConfigP); // - make profile invalid fProfileIndex=-1; fProfileDirty=false; // Note: Datastores are already created from config } // TBinfileImplClient::TBinfileImplClient TBinfileImplClient::~TBinfileImplClient() { // make sure everything is terminated BEFORE destruction of hierarchy begins TerminateSession(); } // TBinfileImplClient::~TBinfileImplClient // Terminate session void TBinfileImplClient::TerminateSession() { if (!fTerminated && fConfigP->fBinfilesActive) { // save profile changes if (fProfileIndex>=0 && fProfileDirty) { fConfigP->fProfileBinFile.updateRecord(fProfileIndex,&fProfile); fProfileDirty=false; fProfileIndex=-1; } // now reset session InternalResetSession(); // make sure all data is flushed fConfigP->fProfileBinFile.flushHeader(); fConfigP->fTargetsBinFile.flushHeader(); } inherited::TerminateSession(); } // TBinfileImplClient::TerminateSession #ifdef ENGINEINTERFACE_SUPPORT // set profileID to client session before doing first SessionStep void TBinfileImplClient::SetProfileSelector(uInt32 aProfileSelector) { if (aProfileSelector==0) fProfileSelectorInternal = DEFAULT_PROFILE_ID; else fProfileSelectorInternal = fConfigP->getProfileIndex(aProfileSelector); } // TBinfileImplClient::SetProfileSelector /// @brief Get new session key to access details of this session appPointer TBinfileImplClient::newSessionKey(TEngineInterface *aEngineInterfaceP) { return new TBinFileAgentParamsKey(aEngineInterfaceP,this); } // TBinfileImplClient::newSessionKey #endif // ENGINEINTERFACE_SUPPORT // Reset session void TBinfileImplClient::InternalResetSession(void) { // reset all datastores now to make sure all DB activity is done // before we possibly close session-global databases // (Note: TerminateDatastores() will be called again by TSyncSession) TerminateDatastores(); fRemoteFlags=0; // no remote-specifics enabled so far } // TBinfileImplClient::InternalResetSession // Virtual version void TBinfileImplClient::ResetSession(void) { if (fConfigP->fBinfilesActive) { // do my own stuff InternalResetSession(); } // let ancestor do its stuff TStdLogicAgent::ResetSession(); } // TBinfileImplClient::ResetSession // - load remote connect params (syncml version, type, format and last nonce) // Note: agents that can cache this information between sessions will load // last info here. void TBinfileImplClient::loadRemoteParams(void) { if (!fConfigP->fBinfilesActive || fProfileIndex<0) { // not active or no profile loaded, let ancestor handle case TStdLogicAgent::loadRemoteParams(); } else { // copy profile cached values fSyncMLVersion= fProfile.lastSyncMLVersion >= numSyncMLVersions ? syncml_vers_unknown : // if profile has higher version than we support, reset to unknown fProfile.lastSyncMLVersion; fRemoteRequestedAuth= fProfile.lastAuthMethod >= numAuthTypes ? auth_md5 : // if auth is unknown, reset to MD5 fProfile.lastAuthMethod; fRemoteRequestedAuthEnc= fProfile.lastAuthFormat >= numFmtTypes ? fmt_b64 : // if format is unknown, reset to B64 fProfile.lastAuthFormat; fRemoteNonce=fProfile.lastNonce; fRemoteFlags=fProfile.remoteFlags; // init remote specific behaviour flags from profile } // modify some behaviour based on remote flags if (fRemoteFlags & remotespecs_noDS12Filters) fServerHasSINCEBEFORE = false; // prevent auto-generated SINCE/BEFORE } // TBinfileImplClient::loadRemoteParams // - save remote connect params for use in next session (if descendant implements it) void TBinfileImplClient::saveRemoteParams(void) { if (fConfigP->fBinfilesActive && fProfileIndex>=0) { // save values to profile // - SyncML version (save it only if it is "better" than what we knew so far) if (fSyncMLVersion > fProfile.lastSyncMLVersion) { fProfile.lastSyncMLVersion=fSyncMLVersion; } fProfile.lastAuthMethod=fRemoteRequestedAuth; fProfile.lastAuthFormat=fRemoteRequestedAuthEnc; fProfile.remoteFlags=fRemoteFlags; // save remote-specific behaviour flags fProfileDirty=true; AssignCString(fProfile.lastNonce,fRemoteNonce.c_str(),maxnoncesiz); } } // TBinfileImplClient::saveRemoteParams // check remote devinf to detect special behaviour needed for some servers. localstatus TBinfileImplClient::checkRemoteSpecifics(SmlDevInfDevInfPtr_t aDevInfP, SmlDevInfDevInfPtr_t *aOverrideDevInfP) { if (fConfigP->fBinfilesActive && aDevInfP) { // check for some specific servers we KNOW they need special treatment uInt8 setFlags = 0; uInt8 clearFlags = 0; if (strnncmp(smlPCDataToCharP(aDevInfP->devid),"OracleSyncServer")==0) { // Oracle OCS // - unqiue ID even if device might have non-unique ones // - no X-nnn type params // - no DS 1.2 PDEBUGPRINTFX(DBG_HOT+DBG_REMOTEINFO,("Detected Oracle OCS Server - suppress dynamic X-nnnn TYPE params, and ")); setFlags |= remotespecs_noXTypeParams+remotespecs_noDS12Filters; #ifndef GUARANTEED_UNIQUE_DEVICID // - Oracle OCS needs unique deviceID/locURI under ALL circumstances as they do // session tracking by locURI, so we always use a hash of deviceID + username // as visible deviceID PDEBUGPRINTFX(DBG_HOT+DBG_REMOTEINFO,("OCS with device that has not guaranteed unique ID - use user+devid hash for Source LocURI")); setFlags |= remotespecs_devidWithUserHash; #else clearFlags |= remotespecs_devidWithUserHash; #endif } else if (strnncmp(smlPCDataToCharP(aDevInfP->mod), "Beehive", 7)==0) { // Oracle Beehive, starts with "Beehive", i.e. "Beehive R1" // - no DS 1.2 PDEBUGPRINTFX(DBG_HOT+DBG_REMOTEINFO,("Detected Oracle Beehive - suppress ")); setFlags |= remotespecs_noDS12Filters; clearFlags |= remotespecs_noXTypeParams+remotespecs_devidWithUserHash; } else { // make sure oracle-specific flags are cleared for all other server types clearFlags |= remotespecs_noXTypeParams+remotespecs_noDS12Filters+remotespecs_devidWithUserHash; } // now apply sInt8 newFlags = (fRemoteFlags & ~clearFlags) | setFlags; if (newFlags != fRemoteFlags) { // change of remotespecs_devidWithUserHash needs session restart bool needrestart = (newFlags & remotespecs_devidWithUserHash) != (fRemoteFlags & remotespecs_devidWithUserHash); // remote flags need to be changed fRemoteFlags = newFlags; // save them into profile saveRemoteParams(); // restart session when needed if (needrestart) { // - abort session, but have main loop retry starting it PDEBUGPRINTFX(DBG_ERROR,("Warning: must restart session with changed remotespecs_devidWithUserHash")); AbortSession(LOCERR_RESTART,true); } } } // let session handle other details return inherited::checkRemoteSpecifics(aDevInfP, aOverrideDevInfP); } // TBinfileImplClient::checkRemoteSpecifics #ifdef IPP_SUPPORT // generates custom PUT in case IPP/DMU is enabled to request settings void TBinfileImplClient::issueCustomGetPut(bool aGotDevInf, bool aSentDevInf) { if (fConfigP->fBinfilesActive) { // get autosync PUT req string string req; fConfigP->autosync_get_putrequest(req); // now create a PUT if (!req.empty()) { TPutCommand *putcommandP = new TPutCommand(this); putcommandP->setMeta(newMetaType(IPP_PARAMS_ITEM_METATYPE)); SmlItemPtr_t putItemP = putcommandP->addSourceLocItem(IPP_PARAMS_LOCURI_REQ); // - add data to item putItemP->data = newPCDataString(req.c_str()); putcommandP->allowFailure(); // do not abort session in case server does not understand the command ISSUE_COMMAND_ROOT(this,putcommandP); } } // let ancestors issue their custom gets and puts, if any inherited::issueCustomGetPut(aGotDevInf, aSentDevInf); } // TBinfileImplClient::issueCustomGetPut #endif // IPP_SUPPORT // handler of custom IPP/DMU put and result commands void TBinfileImplClient::processPutResultItem(bool aIsPut, const char *aLocUri, TSmlCommand *aPutResultsCommandP, SmlItemPtr_t aPutResultsItemP, TStatusCommand &aStatusCommand) { if (fConfigP->fBinfilesActive) { #ifdef IPP_SUPPORT // check for DMU specials if (strucmp(relativeURI(aLocUri),relativeURI(IPP_PARAMS_LOCURI_CFG))==0) { // get DMU string const char *ippstring = smlItemDataToCharP(aPutResultsItemP); PDEBUGPRINTFX(DBG_HOT,("received IPP config string: %s",ippstring)); // process it string tag,value; while (ippstring && *ippstring) { ippstring=nextTag(ippstring,tag,value); // set ipp params in current profile fConfigP->ipp_setparam(tag.c_str(),value.c_str(),fProfile.ippSettings); // make sure autosync profile copy gets updated as well if (fConfigP->fAutosyncProfileLastidx==fProfileIndex) { fConfigP->fAutosyncProfile = fProfile; // copy profile into autosync fConfigP->autosync_condchanged(); // do immediately check settings at next autosync step } // make sure profile gets saved fProfileDirty=true; } // is ok aStatusCommand.setStatusCode(200); // is ok aStatusCommand.dontSend(); // ..but do not send it (%%% as session would then end with error 9999) } else #endif #ifdef SETTINGS_PROVISIONING_VIA_PUT // check for provisioning strings arriving via PUT command if (strucmp(relativeURI(aLocUri),relativeURI(SETTINGS_LOCURI_CFG))==0) { // get provisioning string const char *provstring = smlItemDataToCharP(aPutResultsItemP); PDEBUGPRINTFX(DBG_HOT,("received settings provisioning string: %s",provstring)); // process it // - but first save current profile fConfigP->writeProfile(fProfileIndex,fProfile); // - now modify profile (may include the current profile) sInt32 activeprofile; bool provok = fConfigP->executeProvisioningString(provstring, activeprofile); // - reload current profile (possibly modified) fConfigP->getProfile(fProfileIndex,fProfile); // is ok aStatusCommand.setStatusCode(provok ? 200 : 400); // ok or bad request aStatusCommand.dontSend(); // ..but do not send it (%%% as session would then end with error 9999) } else #endif { // let ancestors process it inherited::processPutResultItem(aIsPut,aLocUri,aPutResultsCommandP,aPutResultsItemP,aStatusCommand); } } else { // let ancestors process it inherited::processPutResultItem(aIsPut,aLocUri,aPutResultsCommandP,aPutResultsItemP,aStatusCommand); } } // TBinfileImplClient::processPutResultItem #ifdef PROTOCOL_SELECTOR // Names of protocols according to TTransportProtocols const char * const Protocol_Names[num_transp_protos] = { "", // none, protocol contained in URI "http://", "https://", "wsp://", // WSP protocol "OBEX:IRDA", // OBEX/IRDA protocol "OBEX:BT", // OBEX/BT protocol "OBEX://", // OBEX/TCP protocol }; #endif // - selects a profile (returns LOCERR_NOCFG if profile not found) // Note: This call must create and initialize all datastores that // are to be synced with that profile. localstatus TBinfileImplClient::SelectProfile(uInt32 aProfileSelector, bool aAutoSyncSession) { uInt32 recidx,maxidx; // detect special tunnel session's selection bool tunnel = aProfileSelector==TUNNEL_PROFILE_ID; // select profile if active if (fConfigP->fBinfilesActive) { if (tunnel) { aProfileSelector=DEFAULT_PROFILE_ID; } // Note: profile database has already been opened in config resolve() if (aProfileSelector==DEFAULT_PROFILE_ID) { // default is first one aProfileSelector=0; } // try to load profile if (fConfigP->fProfileBinFile.readRecord(aProfileSelector,&fProfile)!=BFE_OK) goto defaultprofile; // use default // Now we have the profile fProfileIndex=aProfileSelector; fRemotepartyID=fProfile.profileID; // Set session parameters #ifdef SYNCML_ENCODING_OVERRIDE fEncoding = SYNCML_ENCODING_OVERRIDE; // we use a globally defined encoding #else fEncoding = fProfile.encoding; // we use the profile's encoding #endif #ifdef HARD_CODED_SERVER_URI // - Hard coded base URL of server fRemoteURI=DEFAULT_SERVER_URI; // always use fixed URI #else // - configured URL // check config-level fixed URI first if (!fConfigP->fServerURI.empty()) { // override server URL from fixed value in config fRemoteURI = fConfigP->fServerURI; // config if (strucmp(fProfile.serverURI,fRemoteURI.c_str())!=0) { PDEBUGPRINTFX(DBG_ERROR,("Warning - config overrides/overwrites server URL in profile")); // re-adjust profile AssignCString(fProfile.serverURI, fConfigP->fServerURI.c_str(), maxurisiz); // copy predefined URI back into profile fProfile.readOnlyFlags |= rdonly_URI; // make it read-only } } else { // use URL from profile fRemoteURI=fProfile.serverURI; } #endif // not HARD_CODED_SERVER_URI // check for URI that is a template and need inserts: size_t n; // - %%% check future other inserts here, \u should be last because if there's no \u, standard // CUSTOM_URI_SUFFIX mechanism may apply in else branch // - \u for URIpath n = fRemoteURI.find("\\u"); if (n!=string::npos) { // URIPath may only not contain any special chars that might help to inject different server URLs string up = fProfile.URIpath; if (up.find_first_of(":/?.&=%,;")!=string::npos) fRemoteURI.erase(n, 2); // no insert, invalid chars in URIpath else fRemoteURI.replace(n, 2, up); // insert URIPath instead of \u } #ifdef CUSTOM_URI_SUFFIX else { // Only if original URI is not a template // - append custom URI suffix stored in serverURI field of profile (if one is set) if (*(fProfile.URIpath)) { // - append delimiter first if one defined (CUSTOM_URI_SUFFIX not NULL) const char *p=CUSTOM_URI_SUFFIX; if (p) fRemoteURI.append(p); // - now append custom URI suffix fRemoteURI.append(fProfile.URIpath); } } #endif // CUSTOM_URI_SUFFIX #ifdef PROTOCOL_SELECTOR fRemoteURI.insert(0,Protocol_Names[fProfile.protocol]); fNoCRCPrefixLen=strlen(Protocol_Names[fProfile.protocol]); #endif // PROTOCOL_SELECTOR fServerUser=fProfile.serverUser; getUnmangled(fServerPassword,fProfile.serverPassword,maxupwsiz); // - HTTP auth fTransportUser=fProfile.transportUser; getUnmangled(fTransportPassword,fProfile.transportPassword,maxupwsiz); // - proxy fSocksHost.erase(); // default to none fProxyHost.erase(); fProxyUser.erase(); fProxyPassword.erase(); #ifdef PROXY_SUPPORT if (fProfile.useProxy) { fSocksHost=fProfile.socksHost; fProxyHost=fProfile.proxyHost; fProxyUser=fProfile.proxyUser; getUnmangled(fProxyPassword,fProfile.proxyPassword,maxupwsiz);; PDEBUGPRINTFX(DBG_TRANSP,("Sync Profile contains active proxy settings: http=%s, socks=%s, proxyuser=%s",fProxyHost.c_str(), fSocksHost.c_str(), fProxyUser.c_str())); } #endif // PROXY_SUPPORT // check for forced legacy mode fLegacyMode = fProfile.profileFlags & PROFILEFLAG_LEGACYMODE; // check for lenient mode fLenientMode = fProfile.profileFlags & PROFILEFLAG_LENIENTMODE; // - get and increment session ID and save for next session // Note: as auth retries will increment the ID as well, we inc by 5 // to avoid repeating the ID too soon fProfile.sessionID+=5; fProfileDirty=true; fClientSessionNo=fProfile.sessionID; // Note: loadRemoteParams will fetch the cached params from fProfile // Reset session after profile change (especially fRemoteURI) // and also remove any datastores we might have ResetAndRemoveDatastores(); // in case of tunnel, don't touch datastores if (tunnel) return LOCERR_OK; // Now iterate trough associated target records and create datastores maxidx=fConfigP->fTargetsBinFile.getNumRecords(); TBinfileDBSyncTarget target; for (recidx=0; recidxfTargetsBinFile.readRecord(recidx,&target)==BFE_OK) { // check if this one of my targets if (target.remotepartyID == fRemotepartyID) { // get datastore config #ifdef HARDCODED_CONFIG // - traditional method by name for old monolythic builds (to make sure we don't break anything) TBinfileDSConfig *binfiledscfgP = static_cast( getSessionConfig()->getLocalDS(target.dbname) ); #else // - newer, engine based targets should use the DBtypeID instead, to allow change of DB name without loosing config TBinfileDSConfig *binfiledscfgP = static_cast( getSessionConfig()->getLocalDS(NULL,target.localDBTypeID) ); #endif // check if we have config and if this DS is available now (profile.dsAvailFlags, DSFLAGS_ALWAYS_AVAILABLE, evtl. license...) if (binfiledscfgP && binfiledscfgP->isAvailable(&fProfile)) { // check if this DB must be synced bool syncit=false; #ifdef AUTOSYNC_SUPPORT if (aAutoSyncSession) { // target enable status is not relevant, but autosync alert is syncit = binfiledscfgP->fAutosyncForced || (binfiledscfgP->fAutosyncAlerted && target.enabled); } else { // normal session syncit = target.enabled && target.remoteDBpath[0]!=0; // and remote DB path specified binfiledscfgP->fAutosyncAlerted=false; // this is NOT an autosync session binfiledscfgP->fAutosyncForced=false; } #else syncit = target.enabled && target.remoteDBpath[0]!=0; // and remote DB path specified #endif if (syncit) { TBinfileImplDS *binfiledsP=NULL; if (binfiledscfgP) { // create datastore binfiledsP = static_cast(binfiledscfgP->newLocalDataStore(this)); } if (binfiledsP) { // copy target info to datastore for later access during sync binfiledsP->fTargetIndex=recidx; binfiledsP->fTarget=target; // determine sync mode / flags to use TSyncModes myMode; bool mySlow; #ifdef AUTOSYNC_SUPPORT if (aAutoSyncSession && binfiledscfgP->fAutosyncAlertCode!=0) { // syncmode provided from auto sync alert (e.g. SAN) bool myIsSA; TLocalEngineDS::getSyncModeFromAlertCode( binfiledscfgP->fAutosyncAlertCode, myMode, mySlow, myIsSA ); } else #endif { // take it from config myMode = target.syncmode; mySlow = target.forceSlowSync; } // clean change logs if... // ...we have separate changelog or this is the only profile // ...this is NOT a resumable session (resumable not necessarily means that it WILL be resumed) // ...we're about to slow sync if (mySlow && target.resumeAlertCode==0 && (fConfigP->fSeparateChangelogs || fConfigP->fProfileBinFile.getNumRecords()==1)) { fConfigP->cleanChangeLogForDBname(target.dbname,fProfile.profileID); } // set non-BinFile specific parameters (note that this call might // be to a derivate which uses additional info from fTarget to set sync params) binfiledsP->dsSetClientSyncParams( myMode, mySlow, target.remoteDBpath, NULL, // DB user NULL, // DB password NULL, // local path extension // %%% add filters here later!!! NULL, // filter query false // filter inclusive ); // prepare local datastore (basic init can be done here) and check availability if (binfiledsP->localDatastorePrep()) { // add to datastores for this sync fLocalDataStores.push_back(binfiledsP); } else { // silently discard (do not sync it) PDEBUGPRINTFX(DBG_ERROR,("Local Database for datastore '%s' prepares not ok -> not synced",binfiledsP->getName())); // show event (alerted for no database) SESSION_PROGRESS_EVENT( this, pev_error, binfiledscfgP, LOCERR_LOCDBNOTRDY,0,0 ); delete binfiledsP; } } } // if target DB enabled for sync } // if we have a datastore config for this target } // if target belongs to this profile } // if we can read the target record } // for all target records // ok if at least one datastore enabled; #ifdef ENGINE_LIBRARY // For engine library, check for a non-empty URL makes no // sense any more, because the app on top of libsynthesis may know how // to contact the server without an URL (for example, via some transport // which doesn't need a parameter) return fLocalDataStores.size()>0 ? LOCERR_OK : LOCERR_NOCFG; #else // for classic synthesis builds (winmobile, palmos) the app relies on // the check for a non-empty URL, so we keep it for these legacy build cases return fLocalDataStores.size()>0 && fRemoteURI.size()>0 ? LOCERR_OK : LOCERR_NOCFG; #endif } // active defaultprofile: return inherited::SelectProfile(aProfileSelector, aAutoSyncSession); } // TBinfileImplClient::SelectProfile /* end of TBinfileImplClient implementation */ } // namespace sysync // eof libsynthesis-3.4.0.47.1/src/sysync/binfileimplclient.h000077500000000000000000000465431226375725500226440ustar00rootroot00000000000000/** * @File binfileimplclient.h * * @Author Lukas Zeller (luz@plan44.ch) * * @brief TBinfileImplClient * Represents a client session (agent) that saves profile, target, resume info * and optionally changelog in TBinFile binary files * * Copyright (c) 2003-2011 by Synthesis AG + plan44.ch * * @Date 2005-09-30 : luz : created from TBinfileImplClient */ /* */ #ifndef BINFILEIMPLCLIENT_H #define BINFILEIMPLCLIENT_H // includes #include "sysync.h" #include "stdlogicagent.h" #include "binfileimplds.h" #include "engineinterface.h" #include "syncclientbase.h" #ifndef SYSYNC_CLIENT #error "binfileimplclient only makes sense with client datastores" #endif namespace sysync { // Support for EngineModule common interface // ========================================= #ifdef ENGINEINTERFACE_SUPPORT // forward class TBinfileAgentRootKey; class TBinfileClientConfig; // Engine module class class TBinfileEngineInterface : public TClientEngineInterface { typedef TClientEngineInterface inherited; public: //%%% protected: /// @brief Must be derived in engineBase derivates for generating root for the appropriate settings tree /// @return root settings object, or NULL if failure virtual TSettingsKeyImpl *newSettingsRootKey(void); #ifndef ENGINE_LIBRARY #ifdef RELEASE_VERSION #error "this is here for Q&D testing with outlook client only" #endif /// @brief returns a new application base. /// @note in engineInterface based targets, this is the replacement for the formerly /// global newSyncAppBase() factory function. virtual TSyncAppBase *newSyncAppBase(void); #endif }; // TBinfileEngineInterface // extern for accessing these in TARGETSETTING script function extern const TStructFieldInfo TargetFieldInfos[]; extern const sInt32 numTargetFieldInfos; // Binfile based target key class TBinfileTargetKey : public TStructFieldsKey { typedef TStructFieldsKey inherited; public: TBinfileTargetKey( TEngineInterface *aEngineInterfaceP, sInt32 aTargetIndex, TBinfileDBSyncTarget *aTargetP, TBinfileClientConfig *aBinfileClientConfigP, TBinfileDSConfig *aBinfileDSConfigP ); virtual ~TBinfileTargetKey(); TBinfileDSConfig *getBinfileDSConfig(void) { return fBinfileDSConfigP; }; TBinfileDBSyncTarget *getTarget(void) { return fTargetP; }; TBinfileClientConfig *getBinfileClientConfig(void) { return fBinfileClientConfigP; }; sInt32 getProfileID() { return fTargetP ? fTargetP->remotepartyID : KEYVAL_ID_UNKNOWN; }; protected: // return ID of this key virtual TSyError GetKeyID(sInt32 &aID); // get table describing the fields in the struct virtual const TStructFieldInfo *getFieldsTable(void); virtual sInt32 numFields(void); // get actual struct base address virtual uInt8P getStructAddr(void); private: // profile sInt32 fTargetIndex; // index for writing back profile TBinfileDBSyncTarget *fTargetP; TBinfileClientConfig *fBinfileClientConfigP; TBinfileDSConfig *fBinfileDSConfigP; }; // TBinfileTargetKey // Binfile based targets collection key class TBinfileTargetsKey : public TSettingsKeyImpl { typedef TSettingsKeyImpl inherited; public: TBinfileTargetsKey(TEngineInterface *aEngineInterfaceP, sInt32 aProfileID); protected: // targets can be opened only by dbtype-ID virtual TSyError OpenSubkey( TSettingsKeyImpl *&aSettingsKeyP, sInt32 aID, uInt16 aMode ); private: sInt32 fProfileID; // profile ID sInt32 fTargetIterator; TBinfileClientConfig *fBinfileClientConfigP; }; // TBinfileTargetsKey #ifdef AUTOSYNC_SUPPORT // Binfile based autosync level key class TBinfileASLevelKey : public TStructFieldsKey { typedef TStructFieldsKey inherited; public: TBinfileASLevelKey( TEngineInterface *aEngineInterfaceP, sInt32 aLevelIndex, TBinfileDBSyncProfile *aProfileP, TBinfileClientConfig *aBinfileClientConfigP ); virtual ~TBinfileASLevelKey(); protected: // return ID of this key virtual TSyError GetKeyID(sInt32 &aID); // get table describing the fields in the struct virtual const TStructFieldInfo *getFieldsTable(void); virtual sInt32 numFields(void); // get actual struct base address virtual uInt8P getStructAddr(void); private: // profile sInt32 fLevelIndex; // level index TBinfileDBSyncProfile *fProfileP; TBinfileClientConfig *fBinfileClientConfigP; }; // TBinfileASLevelKey // Binfile based autosync levels collection key class TBinfileASLevelsKey : public TSettingsKeyImpl { typedef TSettingsKeyImpl inherited; public: TBinfileASLevelsKey(TEngineInterface *aEngineInterfaceP, TBinfileDBSyncProfile *aProfileP); protected: // levels can be opened only by ID virtual TSyError OpenSubkey( TSettingsKeyImpl *&aSettingsKeyP, sInt32 aID, uInt16 aMode ); private: sInt32 fASLevelIterator; TBinfileDBSyncProfile *fProfileP; TBinfileClientConfig *fBinfileClientConfigP; }; // TBinfileASLevelsKey #endif // AUTOSYNC_SUPPORT // extern for accessing these in PROFILESETTING script function extern const TStructFieldInfo ProfileFieldInfos[]; extern const sInt32 numProfileFieldInfos; // Binfile based profile key class TBinfileProfileKey : public TStructFieldsKey { typedef TStructFieldsKey inherited; public: TBinfileProfileKey( TEngineInterface *aEngineInterfaceP, sInt32 aProfileIndex, TBinfileDBSyncProfile *aProfileP, TBinfileClientConfig *aBinfileClientConfigP ); virtual ~TBinfileProfileKey(); TBinfileClientConfig *getBinfileClientConfig(void) { return fBinfileClientConfigP; }; TBinfileDBSyncProfile *getProfile(void) { return fProfileP; }; sInt32 getProfileID() { return fProfileP ? fProfileP->profileID : KEYVAL_ID_UNKNOWN; }; protected: // return ID of this key virtual TSyError GetKeyID(sInt32 &aID); // open subkey by name (not by path!) // - this is the actual implementation virtual TSyError OpenSubKeyByName( TSettingsKeyImpl *&aSettingsKeyP, cAppCharP aName, stringSize aNameSize, uInt16 aMode ); // get table describing the fields in the struct virtual const TStructFieldInfo *getFieldsTable(void); virtual sInt32 numFields(void); // get actual struct base address virtual uInt8P getStructAddr(void); private: // profile sInt32 fProfileIndex; // index for writing back profile TBinfileDBSyncProfile *fProfileP; TBinfileClientConfig *fBinfileClientConfigP; }; // TBinfileProfileKey // Binfile based profiles collection key class TBinfileProfilesKey : public TStructFieldsKey { typedef TStructFieldsKey inherited; public: TBinfileProfilesKey(TEngineInterface *aEngineInterfaceP); virtual ~TBinfileProfilesKey(); TBinfileClientConfig *getBinfileClientConfig(void) { return fBinfileClientConfigP; }; // set iterator void setNextProfileindex(sInt32 aProfileIndex) { fProfileIterator=aProfileIndex-1; }; protected: // profiles can be opened only by ID virtual TSyError OpenSubkey( TSettingsKeyImpl *&aSettingsKeyP, sInt32 aID, uInt16 aMode ); virtual TSyError DeleteSubkey(sInt32 aID); // get table describing the fields in the struct virtual const TStructFieldInfo *getFieldsTable(void); virtual sInt32 numFields(void); // get actual struct base address virtual uInt8P getStructAddr(void); private: // internal sInt32 fProfileIterator; public: // binfileconfig TBinfileClientConfig *fBinfileClientConfigP; // flag how to call loadVarConfig bool fMayLooseOldCfg; }; // TBinfileProfilesKey // Binfile based log entry key class TBinfileLogKey : public TStructFieldsKey { typedef TStructFieldsKey inherited; public: TBinfileLogKey( TEngineInterface *aEngineInterfaceP, TLogFileEntry *aLogEntryP, TBinfileClientConfig *aBinfileClientConfigP ); virtual ~TBinfileLogKey(); TBinfileClientConfig *getBinfileClientConfig(void) { return fBinfileClientConfigP; }; TLogFileEntry *getLogEntry(void) { return fLogEntryP; }; protected: // get table describing the fields in the struct virtual const TStructFieldInfo *getFieldsTable(void); virtual sInt32 numFields(void); // get actual struct base address virtual uInt8P getStructAddr(void); private: TLogFileEntry *fLogEntryP; TBinfileClientConfig *fBinfileClientConfigP; }; // TBinfileLogKey // Binfile based log entry collection key class TBinfileLogsKey : public TSettingsKeyImpl { typedef TSettingsKeyImpl inherited; public: TBinfileLogsKey(TEngineInterface *aEngineInterfaceP); protected: // targets can be opened only by dbtype-ID virtual TSyError OpenSubkey( TSettingsKeyImpl *&aSettingsKeyP, sInt32 aID, uInt16 aMode ); virtual TSyError DeleteSubkey(sInt32 aID); private: // binfileconfig TBinfileClientConfig *fBinfileClientConfigP; // iterator sInt32 fLogEntryIterator; // the log file TBinFile fLogFile; }; // TBinfileLogsKey // Binfile based client settings rootkey class TBinfileAgentRootKey : public TSettingsRootKey { typedef TSettingsRootKey inherited; public: TBinfileAgentRootKey(TEngineInterface *aEngineInterfaceP); protected: // open subkey by name (not by path!) virtual TSyError OpenSubKeyByName( TSettingsKeyImpl *&aSettingsKeyP, cAppCharP aName, stringSize aNameSize, uInt16 aMode ); }; // TBinfileAgentRootKey #endif // ENGINEINTERFACE_SUPPORT // Config // ====== class TBinfileClientConfig: public TAgentConfig { typedef TAgentConfig inherited; public: TBinfileClientConfig(TConfigElement *aParentElement); virtual ~TBinfileClientConfig(); // API for settings management // - initialize a new-created profile database void initProfileDb(void); // - create a new profile including appropriate targets sInt32 newProfile(const char *aProfileName, bool aSetDefaults, sInt32 aTemplateProfile=-1); // - init profile record with defaults static void initProfile(TBinfileDBSyncProfile &aProfile, const char *aName, bool aWithDefaults); // - write profile, returns index of profile sInt32 writeProfile( sInt32 aProfileIndex, // -1 if adding new profile TBinfileDBSyncProfile &aProfile // profile ID is set to new ID in aProfile ); // - delete profile (and all of its targets) bool deleteProfile( sInt32 aProfileIndex ); // - get number of existing profiles sInt32 numProfiles(void); // - get profile, returns index or -1 if no more profiles sInt32 getProfile( sInt32 aProfileIndex, TBinfileDBSyncProfile &aProfile ); // - get profile index from name, returns index or -1 if no matching profile found sInt32 getProfileIndexByName(cAppCharP aProfileName); // - get profile by ID sInt32 getProfileByID( uInt32 aProfileID, TBinfileDBSyncProfile &aProfile ); sInt32 getProfileIndex(uInt32 aProfileID); // - checks that all profiles are complete with targets for all configured datastores // (in case of STD->PRO upgrade for example) void checkProfiles(void); // - checks that profile is complete with targets for all configured datastores // (in case of STD->PRO upgrade for example) void checkProfile(sInt32 aProfileIndex); // - get profile ID by index, 0 if none found uInt32 getIDOfProfile(sInt32 aProfileIndex); // - check for feature enabled (profile or license dependent) bool isFeatureEnabled(TBinfileDBSyncProfile *aProfileP, uInt16 aFeatureNo); // with profile already loaded bool isFeatureEnabled(sInt32 aProfileIndex, uInt16 aFeatureNo); // by profile index // - check for readonly parts of profile settings bool isReadOnly(TBinfileDBSyncProfile *aProfileP, uInt8 aReadOnlyMask); bool isReadOnly(sInt32 aProfileIndex, uInt8 aReadOnlyMask); // - get last sync (earliest of lastSync of all sync-enabled targets), 0=never. Returns false if no enabled targets bool getProfileLastSyncTime(uInt32 aProfileID, lineartime_t &aLastSync, bool &aZapsServer, bool &aZapsClient); // - get last sync of target, 0=never. Returns false if target not enabled bool getTargetLastSyncTime(sInt32 aTargetIndex, lineartime_t &aLastSync, bool &aZapsServer, bool &aZapsClient, uInt32 &aDBID); bool getTargetLastSyncTime(TBinfileDBSyncTarget &aTarget, lineartime_t &aLastSync, bool &aZapsServer, bool &aZapsClient, uInt32 &aDBID); // - check if datastore of specified target is available in the given profile bool isTargetAvailable(TBinfileDBSyncProfile *aProfileP, uInt32 aLocalDBTypeID); // - find available target for profile by DB ID/name. Returns target index or -1 if // DBTypeID not available in this profile/license or not implemented at all sInt32 findAvailableTargetIndexByDBInfo( TBinfileDBSyncProfile *aProfileP, // profile to search targets for uInt32 aLocalDBTypeID, const char *aLocalDBName // can be NULL if name does not matter ); // - find or create target for profile by DB ID/name. creates target if not found existing already. sInt32 findOrCreateTargetIndexByDBInfo( uInt32 aProfileID, // profile to search targets for uInt32 aLocalDBTypeID, const char *aLocalDBName // can be NULL if name does not matter ); // - find target for profile by DB ID/name. Returns target index or -1 if none found sInt32 findTargetIndexByDBInfo( uInt32 aProfileID, // profile to search targets for uInt32 aLocalDBTypeID, const char *aLocalDBName ); // - find target for profile. Returns target index or -1 if none found sInt32 findTargetIndex( uInt32 aProfileID, // profile to search targets for sInt32 aTargetSeqNum // sequence number (0..n) ); // - write target, returns index of target sInt32 writeTarget( sInt32 aTargetIndex, // -1 if adding new target const TBinfileDBSyncTarget &aTarget ); // - delete target bool deleteTarget( sInt32 aTargetIndex ); // - get target info sInt32 getTarget( sInt32 aTargetIndex, TBinfileDBSyncTarget &aTarget ); // - get path where to store binfiles void getBinFilesPath(string &aPath); // activtion switch (for making it inactive e.g. in server case) bool fBinfilesActive; // separate changelogs per profile bool fSeparateChangelogs; #ifndef HARDCODED_CONFIG // - configurable path where to store binfiles string fBinFilesPath; #endif // - if set, sync log statistics are saved to binfile bool fBinFileLog; // Binary Files TBinFile fProfileBinFile; TBinFile fTargetsBinFile; // - cleanup changelog, pendingmap, pendingitem string relatedDBNameBase(cAppCharP aDBName, sInt32 aProfileID); void cleanChangeLogForTarget(sInt32 aTargetIndex, sInt32 aProfileID); void cleanChangeLogForDBname(cAppCharP aDBName, sInt32 aProfileID); void separateChangeLogsAndRelated(cAppCharP aDBName); // - called when app should save its persistent state virtual void saveAppState(void); // - MUST be called after creating config to load (or pre-load) variable parts of config // such as binfile profiles. If aDoLoose==false, situations, where existing config // is detected but cannot be re-used will return an error. With aDoLoose==true, config // files etc. are created even if it means a loss of data. virtual localstatus loadVarConfig(bool aDoLoose=false); // open and close the settings databases localstatus openSettingsDatabases(bool aDoLoose); void closeSettingsDatabases(void); private: // helper for migrating to separated changelogs/pendingmaps/pendingitem void separateDBFile(cAppCharP aDBName, cAppCharP aDBSuffix, sInt32 aProfileID); protected: // check config elements #ifndef HARDCODED_CONFIG virtual bool localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine); #endif virtual void clear(); virtual void localResolve(bool aLastPass); // Client provisioning declarations CLIENTPROVISIONING_CLASSDECL // Autosync declarations CLIENTAUTOSYNC_CLASSDECL }; // TBinfileClientConfig // Binary file based session class TBinfileImplClient: public TStdLogicAgent { typedef TStdLogicAgent inherited; #ifdef ENGINEINTERFACE_SUPPORT friend class TBinFileAgentParamsKey; #endif public: TBinfileImplClient(TSyncAppBase *aSyncAppBaseP, TSyncSessionHandle *aSyncSessionHandleP, cAppCharP aSessionID); /// check if active derived classes (in particular: customImplDS that CAN derive binfiles, but does not necessarily so) bool binfilesActive(void) { return fConfigP && fConfigP->fBinfilesActive; }; // - selects a profile (returns false if profile not found) // Note: This call must create and initialize all datastores that // are to be synced with that profile. virtual localstatus SelectProfile(uInt32 aProfileSelector, bool aAutoSyncSession=false); virtual ~TBinfileImplClient(); virtual void TerminateSession(void); // Terminate session, like destructor, but without actually destructing object itself virtual void ResetSession(void); // Resets session (but unlike TerminateSession, session might be re-used) void InternalResetSession(void); // static implementation for calling through virtual destructor and virtual ResetSession(); #ifdef ENGINEINTERFACE_SUPPORT // set profileID to client session before doing first SessionStep virtual void SetProfileSelector(uInt32 aProfileSelector); /// @brief Get new session key to access details of this session virtual appPointer newSessionKey(TEngineInterface *aEngineInterfaceP); #endif // ENGINEINTERFACE_SUPPORT // - load remote connect params (syncml version, type, format and last nonce) // Note: agents that can cache this information between sessions will load // last info here. virtual void loadRemoteParams(void); // - save remote connect params for use in next session (if descendant implements it) virtual void saveRemoteParams(void); // special behaviour #ifndef GUARANTEED_UNIQUE_DEVICID virtual bool devidWithUserHash(void) { return (fRemoteFlags & remotespecs_devidWithUserHash)!=0; }; // include user name to make a hash-based pseudo-device ID when flag is set #endif // - handle custom put and result commands (for remote provisioning and IPP) virtual void processPutResultItem(bool aIsPut, const char *aLocUri, TSmlCommand *aPutResultsCommandP, SmlItemPtr_t aPutResultsItemP, TStatusCommand &aStatusCommand); #ifdef IPP_SUPPORT // - called to issue custom get and put commands virtual void issueCustomGetPut(bool aGotDevInf, bool aSentDevInf); #endif // binfile agent config TBinfileClientConfig *fConfigP; // unique ID to identify info record of remote party (profile for client, deviceentry for server) uInt32 fRemotepartyID; // - check remote devinf to detect special behaviour needed for some servers. Base class // does not do anything on server level (configured rules are handled at session level) virtual localstatus checkRemoteSpecifics(SmlDevInfDevInfPtr_t aDevInfP, SmlDevInfDevInfPtr_t *aOverrideDevInfP); TBinfileDBSyncProfile fProfile; // - remote specific client behaviour flags uInt8 fRemoteFlags; // flags for remote specific behaviour (remotespecs_XXX) private: // selected profile sInt32 fProfileIndex; bool fProfileDirty; }; // TBinfileImplClient #ifdef ENGINEINTERFACE_SUPPORT // Support for EngineModule common interface // ========================================= // client runtime parameters class TBinFileAgentParamsKey : public TAgentParamsKey { typedef TAgentParamsKey inherited; public: TBinFileAgentParamsKey(TEngineInterface *aEngineInterfaceP, TSyncAgent *aClientSessionP); virtual ~TBinFileAgentParamsKey() {}; protected: // open subkey by name (not by path!) virtual TSyError OpenSubKeyByName( TSettingsKeyImpl *&aSettingsKeyP, cAppCharP aName, stringSize aNameSize, uInt16 aMode ); }; // TBinFileAgentParamsKey #endif // ENGINEINTERFACE_SUPPORT } // namespace sysync #endif // BINFILEIMPLCLIENT_H // eof libsynthesis-3.4.0.47.1/src/sysync/binfileimplds.cpp000077500000000000000000003324711226375725500223250ustar00rootroot00000000000000/** * @File binfileimplds.cpp * * @Author Lukas Zeller (luz@plan44.ch) * * @brief TBinfileImplDS * Represents a client datastore implementation which has target management * (and optionally change log) based on binary files * * Copyright (c) 2003-2011 by Synthesis AG + plan44.ch * * @Date 2005-09-30 : luz : created from TBinfileImplDS */ /* */ // includes #include "prefix_file.h" #include "sysync.h" #include "binfileimplclient.h" #include "binfileimplds.h" #include #if defined(BINFILE_ALWAYS_ACTIVE) && defined(SYSYNC_SERVER) #error "BINFILE_ALWAYS_ACTIVE is not compatible with server-enabled builds" #endif namespace sysync { #ifdef SCRIPT_SUPPORT // Script Functions // ================ class TBFDSfuncs { public: static TItemField *fieldFromStructField(cAppCharP aFieldName, const TStructFieldInfo *aStructFieldInfos, sInt32 aNumFields, uInt8P aStructAddr, TScriptContext *aFuncContextP) { TItemField *fldP = NULL; // search for name for (sInt32 i=0; ivalName, aFieldName)==0 && info->valSiz>0) { // found field if (info->valType==VALTYPE_TEXT) { // text fldP = newItemField(fty_string, aFuncContextP->getSessionZones()); fldP->setAsString((cAppCharP)(aStructAddr+info->fieldOffs)); return fldP; } else if (info->valType==VALTYPE_TIME64) { // timestamp fldP = newItemField(fty_timestamp, aFuncContextP->getSessionZones()); static_cast(fldP)->setTimestampAndContext( *((lineartime_t *)(aStructAddr+info->fieldOffs)), TCTX_UTC // internal timestamps are UTC ); return fldP; } else { // all other types are treated as integers fieldinteger_t fint = 0; switch(info->valSiz) { case 1 : fint = *((uInt8 *)(aStructAddr+info->fieldOffs)); break; case 2 : fint = *((uInt16 *)(aStructAddr+info->fieldOffs)); break; case 4 : fint = *((uInt32 *)(aStructAddr+info->fieldOffs)); break; case 8 : fint = *((uInt64 *)(aStructAddr+info->fieldOffs)); break; } fldP = newItemField(fty_integer, aFuncContextP->getSessionZones()); fldP->setAsInteger(fint); return fldP; } } } // no such field, return an unassigned field fldP=newItemField(fty_none, aFuncContextP->getSessionZones()); fldP->unAssign(); // make it (already is...) unassigned return fldP; } // fieldFromStructField // variant PROFILESETTING(string settingsfieldname) // returns data from profile settings (like /profiles/n does) static void func_ProfileSetting(TItemField *&aTermP, TScriptContext *aFuncContextP) { string varname; TBinfileImplDS *dsP = static_cast(aFuncContextP->getCallerContext()); // get name aFuncContextP->getLocalVar(0)->getAsString(varname); // get value aTermP = fieldFromStructField( varname.c_str(), ProfileFieldInfos, numProfileFieldInfos, (uInt8P)&(static_cast(dsP->getSession())->fProfile), aFuncContextP ); }; // func_ProfileSetting // variant TARGETSETTING(string settingsfieldname) // returns data from target settings (like /profiles/n/targets/dbid/settingsfieldname does) static void func_TargetSetting(TItemField *&aTermP, TScriptContext *aFuncContextP) { string varname; TBinfileImplDS *dsP = static_cast(aFuncContextP->getCallerContext()); // get name aFuncContextP->getLocalVar(0)->getAsString(varname); // get value aTermP = fieldFromStructField( varname.c_str(), TargetFieldInfos, numTargetFieldInfos, (uInt8P)&(dsP->fTarget), aFuncContextP ); }; // func_TargetSetting }; // TBFDSfuncs const uInt8 param_OneStr[] = { VAL(fty_string) }; const TBuiltInFuncDef BinfileDBFuncDefs[] = { { "TARGETSETTING", TBFDSfuncs::func_TargetSetting, fty_none, 1, param_OneStr }, { "PROFILESETTING", TBFDSfuncs::func_ProfileSetting, fty_none, 1, param_OneStr }, }; // chain to general ClientDB functions static void *BinfileClientDBChainFunc(void *&aCtx) { // caller context remains unchanged // -> no change needed // next table is general ClientDB func table return (void *)&ClientDBFuncTable; } // BinfileClientDBChainFunc // function table for client-only script functions const TFuncTable BinfileClientDBFuncTable = { sizeof(BinfileDBFuncDefs) / sizeof(TBuiltInFuncDef), // size of table BinfileDBFuncDefs, // table pointer BinfileClientDBChainFunc // chain to general agent funcs. }; #endif // SCRIPT_SUPPORT // Config // ====== TBinfileDSConfig::TBinfileDSConfig(const char* aName, TConfigElement *aParentElement) : TLocalDSConfig(aName,aParentElement) { // nop so far clear(); } // TBinfileDSConfig::TBinfileDSConfig TBinfileDSConfig::~TBinfileDSConfig() { // nop so far } // TBinfileDSConfig::~TBinfileDSConfig // init defaults void TBinfileDSConfig::clear(void) { // Only active in clients by default fBinfileDSActive = IS_CLIENT; // change detection by CRC is enabled by default only for builds that CAN'T have DB-side detection #ifdef CHANGEDETECTION_AVAILABLE fCRCChangeDetection = false; // normally, DB can report changes. CRC checking can be enabled as an option fCRCPseudoChangeDetection = false; // normally, DB reports changes correctly. Verifying changes can be enabled as an option #endif // init defaults fLocalDBPath.erase(); fDSAvailFlag=0; // set default according to former build-time target setting #ifdef SYNCTIME_IS_ENDOFSESSION fCmpRefTimeStampAtEnd = true; #else fCmpRefTimeStampAtEnd = false; #endif // clear inherited inherited::clear(); } // TBinfileDSConfig::clear #ifndef HARDCODED_CONFIG // config element parsing bool TBinfileDSConfig::localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine) { // checking the elements if (strucmp(aElementName,"dbpath")==0) expectString(fLocalDBPath); else if (strucmp(aElementName,"dsavailflag")==0) expectUInt16(fDSAvailFlag); else if (strucmp(aElementName,"cmptimestampatend")==0) expectBool(fCmpRefTimeStampAtEnd); else if (strucmp(aElementName,"binfiledsactive")==0) expectBool(fBinfileDSActive); #ifdef CHANGEDETECTION_AVAILABLE else if (strucmp(aElementName,"crcchangedetection")==0) expectBool(fCRCChangeDetection); else if (strucmp(aElementName,"pseudochangedetection")==0) expectBool(fCRCPseudoChangeDetection); #endif // - none known here else return TLocalDSConfig::localStartElement(aElementName,aAttributes,aLine); // ok return true; } // TBinfileDSConfig::localStartElement #endif // resolve void TBinfileDSConfig::localResolve(bool aLastPass) { if (aLastPass) { // check for required settings #ifdef CHANGEDETECTION_AVAILABLE // - pseudochange detection would interfere with regular CRC based change detection and is also completely useless then if (fCRCChangeDetection) fCRCPseudoChangeDetection = false; // just switch it off, makes no sense #endif } // resolve inherited inherited::localResolve(aLastPass); } // TBinfileDSConfig::localResolve // checks if datastore is available for given profile. If aProfileP is NULL, // general availability is checked (profile might allow more or less) bool TBinfileDSConfig::isAvailable(TBinfileDBSyncProfile *aProfileP) { #ifndef DSFLAGS_ALWAYS_AVAILABLE // all datastores are always available return true; #else // check if available // - %%%later: check if license allows using this datastore // %%% // - if it's one of the always available datastores, always return true if (fDSAvailFlag & DSFLAGS_ALWAYS_AVAILABLE) return true; // - check if it's enabled in the profile if (aProfileP==NULL) return false; // no profile return (aProfileP->dsAvailFlags & fDSAvailFlag)!=0; #endif } // TBinfileDSConfig::isAvailable #ifndef DEFAULT_SYNCMODE #define DEFAULT_SYNCMODE smo_twoway #endif // init default target for datastore void TBinfileDSConfig::initTarget( TBinfileDBSyncTarget &aTarget, uInt32 aRemotepartyID, const char *aRemoteName, // defaults to name of datastore bool aEnabled // enabled? ) { //set to zeros to avoid memory warnings memset(&aTarget, 0, sizeof(aTarget)); // link to the profile aTarget.remotepartyID=aRemotepartyID; // enabled or not? aTarget.enabled=aEnabled; // force slow sync (slow sync is used anyway, but shows this to user) aTarget.forceSlowSync=true; // sync mode aTarget.syncmode=DEFAULT_SYNCMODE; // reset all options aTarget.limit1=0; aTarget.limit2=0; aTarget.extras=0; // database identification aTarget.localDBTypeID=fLocalDBTypeID; // what target database AssignCString(aTarget.localDBPath,fLocalDBPath.c_str(),localDBpathMaxLen); #if defined(DESKTOP_CLIENT) || TARGETS_DB_VERSION>4 AssignCString(aTarget.localContainerName,NULL,localDBpathMaxLen); #endif // link to configuration is by datastore name AssignCString(aTarget.dbname,getName(),dbnamelen); // default name for remote datastore is same as local one if (!aRemoteName) aRemoteName=getName(); AssignCString(aTarget.remoteDBpath,aRemoteName,remoteDBpathMaxLen); // - init new target record's variables (will be updated after sync) aTarget.lastSync=0; // no last sync date yet aTarget.lastChangeCheck=0; aTarget.lastSuspendModCount=0; /// @note: before DS 1.2 enginem this was used as "lastModCount" aTarget.resumeAlertCode=0; // no resume yet aTarget.lastTwoWayModCount=0; aTarget.remoteAnchor[0]=0; // no anchor yet // Version 6 and later #if TARGETS_DB_VERSION>5 aTarget.dummyIdentifier1[0]=0; aTarget.dummyIdentifier2[0]=0; AssignCString(aTarget.remoteDBdispName, getName(), dispNameMaxLen); // default to local name aTarget.filterCapDesc[0]=0; aTarget.remoteFilters[0]=0; aTarget.localFilters[0]=0; #endif } // initTarget /* * Implementation of TBinfileImplDS */ TBinfileImplDS::TBinfileImplDS( TBinfileDSConfig *aConfigP, sysync::TSyncSession *aSessionP, const char *aName, uInt32 aCommonSyncCapMask ) : TStdLogicDS(aConfigP, aSessionP, aName, aCommonSyncCapMask) { // no changelog loaded yet (needed here because InternalResetDataStore will test it) fLoadedChangeLog=NULL; fLoadedChangeLogEntries=0; // just to make sure fHasPendingChanges=false; fPreviousToRemoteModCount=0; fPreviousSuspendModCount=0; fCurrentModCount=0; // now do internal reset InternalResetDataStore(); // save config pointer fConfigP=aConfigP; // no target loaded yet fTargetIndex=-1; } // TBinfileImplDS::TBinfileImplDS void TBinfileImplDS::dsResetDataStore(void) { // Do my normal internal reset InternalResetDataStore(); // Let ancestor initialize inherited::dsResetDataStore(); if (binfileDSActive()) { // And now force MaxGUIDSize to what this datastore can handle fMaxGUIDSize=BINFILE_MAXGUIDSIZE; } } // TBinfileImplDS::dsResetDataStore void TBinfileImplDS::InternalResetDataStore(void) { // forget preflight fPreflighted=false; // forget loaded changelog forgetChangeLog(); // no pending changes known yet fHasPendingChanges=0; // unknown number of changes fNumberOfLocalChanges=-1; } // TBinfileImplDS::InternalResetDataStore TBinfileImplDS::~TBinfileImplDS() { InternalResetDataStore(); } // TBinfileImplDS::~TBinfileImplDS // called when message processing (and probably thread) ends // (can be used to finalize things that cannot continue until next request // such as code that cannot be called from different threads) void TBinfileImplDS::dsEndOfMessage(void) { // %%% save between messages in debug #ifdef SYDEBUG //endWrite(); #endif // let ancestor do things inherited::dsEndOfMessage(); } // TBinfileImplDS::dsEndOfMessage /// inform logic of coming state change localstatus TBinfileImplDS::dsBeforeStateChange(TLocalEngineDSState aOldState,TLocalEngineDSState aNewState) { return inherited::dsBeforeStateChange(aOldState, aNewState); } // TBinfileImplDS::dsBeforeStateChange /// inform logic of happened state change localstatus TBinfileImplDS::dsAfterStateChange(TLocalEngineDSState aOldState,TLocalEngineDSState aNewState) { if (aNewState == dssta_completed) { // free resources which are not valid when restarting, // in particular the change log InternalResetDataStore(); } return inherited::dsAfterStateChange(aOldState, aNewState); } // TBinfileImplDS::dsAfterStateChange // - init Sync Parameters for datastore // Derivates might override this to pre-process and modify parameters // (such as adding client settings as CGI to remoteDBPath) bool TBinfileImplDS::dsSetClientSyncParams( TSyncModes aSyncMode, bool aSlowSync, const char *aRemoteDBPath, const char *aDBUser, const char *aDBPassword, const char *aLocalPathExtension, const char *aRecordFilterQuery, bool aFilterInclusive ) { if (binfileDSActive()) { #ifdef AUTOSYNC_SUPPORT string s; bool cgi=false; // add autosync options if this is an autosync if (fConfigP->fAutosyncAlerted || fConfigP->fAutosyncForced) { if (!fConfigP->fAutosyncPathCGI.empty()) { s=aRemoteDBPath; cgi = s.find('?')!=string::npos; if (!cgi) { s+='?'; cgi=true; } s += fConfigP->fAutosyncPathCGI; aRemoteDBPath=s.c_str(); } } #endif } return inherited::dsSetClientSyncParams(aSyncMode,aSlowSync,aRemoteDBPath,aDBUser,aDBPassword,aLocalPathExtension,aRecordFilterQuery,aFilterInclusive); } // TBinfileImplDS::dsSetClientSyncParams // BinFile DB implementation specific routines // =========================================== // clean up change log // - removes chgl_deleted entries that are older or // same age as indicated by aOldestSyncModCount) // - finalizes localids localstatus TBinfileImplDS::changeLogPostflight(uInt32 aOldestSyncModCount) { // review all logentries TChangeLogEntry logentry; uInt32 logindex=0; while (true) { if (fChangeLog.readRecord(logindex,&logentry)!=BFE_OK) break; // seen all if ( (logentry.flags & chgl_deleted) && (logentry.modcount<=aOldestSyncModCount) ) { // all peers (in all profiles related to this changelog, which is only one with the separated changelogs!) // have seen this delete already, so this one should be deleted // - delete the record, another one will appear at this index fChangeLog.deleteRecord(logindex); } else { // no delete, finalize localid (possible only with string localIDs) #ifndef NUMERIC_LOCALIDS localid_out_t locID = logentry.dbrecordid; if (dsFinalizeLocalID(locID)) { // update log entry ASSIGN_LOCALID_TO_FLD(logentry.dbrecordid,LOCALID_OUT_TO_IN(locID)); fChangeLog.updateRecord(logindex, &logentry); } #endif // no delete, advance index logindex++; } } return LOCERR_OK; } // TBinfileImplDS::changeLogPostflight // zap changelog. Should be called if datastore as a entiety was replaced // by another datatstore (or created new) void TBinfileImplDS::zapChangeLog(void) { // forget cached changelog if any forgetChangeLog(); // make sure changelog file is open if (openChangeLog()) { // kill all entries fChangeLog.truncate(0); // reset modcount fChgLogHeader.modcount = 0; fChgLogHeader.lastChangeCheckIdentifier[0] = 0; fChgLogHeader.lastChangeCheck = noLinearTime; // make sure header is written fChangeLog.setExtraHeaderDirty(); fChangeLog.flushHeader(); } PDEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI,("zapChangeLog: erased changelog")); } // TBinfileImplDS::zapChangeLog // update change log record contents static uInt32 changelogUpdateFunc(uInt32 aOldVersion, uInt32 aNewVersion, void *aOldRecordData, void *aNewRecordData, uInt32 aOldSize) { if (aOldVersionCHANGELOG_DB_VERSION) return 0; // unknown old version or too new version, cannot update if (aNewVersion!=CHANGELOG_DB_VERSION) return 0; // cannot update to other version than current // create default values for profile if (aOldRecordData && aNewRecordData) { // update records TChangeLogEntry *chglogEntryP = (TChangeLogEntry *)aNewRecordData; // check for special case that old record is V2 or V3 and was compiled without CHANGEDETECTION_AVAILABLE uInt16 crc = 0; if ((aOldVersion==2 || aOldVersion==3) && aOldSize!=offsetof(TChangeLogEntry,modcount_created)) { // this means that the records were compiled without CHANGEDETECTION_AVAILABLE and had a // dataCRC field between modcount and flags //#if defined(WINCE) || #if defined(__PALM_OS__) #error "This code must be verified to check if upgrade works as intended with targets that did not have CHANGEDETECTION_AVAILABLE" #endif // - offset of the CRC field we already have int o = offsetof(TChangeLogEntry,flags); // - copy up to the CRC which is already there memcpy(aNewRecordData,aOldRecordData,o); // - get the CRC which is already there to init the new V5 DB field below crc = *((uInt16 *)((uInt8 *)aOldRecordData+o)); // - also copy the flags chglogEntryP->flags = *((uInt8 *)((uInt8 *)aOldRecordData+o+sizeof(uInt16))); // next after dataCRC chglogEntryP->dummy = *((uInt8 *)((uInt8 *)aOldRecordData+o+sizeof(uInt16)+sizeof(uInt8))); // next after flags } else { // copy old data - beginning of record is identical memcpy(aNewRecordData,aOldRecordData,aOldSize); } // now initialize fields that old version didn't have if (aOldVersion<4) { // init new version 4 fields chglogEntryP->modcount_created = 0; // assume created before changelogging history started } if (aOldVersion<5) { // init new V5 dataCRC; if we are updating from V2 or V3 (which is handled above) we'll assign the previous CRC here, 0 otherwise chglogEntryP->dataCRC = crc; } } else if (aNewRecordData) { // update extra header TChangeLogHeader *extraHeaderP = (TChangeLogHeader *)aNewRecordData; if (aOldVersion<3) { // header has got new fields between v2 and v3 // Note: these will be updated with data from target fields after actually opening the changelog // Just init them now extraHeaderP->lastChangeCheckIdentifier[0] = 0; extraHeaderP->lastChangeCheck = noLinearTime; } // updated header ok return sizeof(TChangeLogHeader); } // updated ok (or updateable ok if no data pointers provided) // - return size of new record return sizeof(TChangeLogEntry); } // changelogUpdateFunc // returns true if we had a valid changelog bool TBinfileImplDS::openChangeLog(void) { if (fChangeLog.isOpen()) return true; // was already open // open and possibly migrate the changelog TBinfileImplClient *bfcP = static_cast(fSessionP); TBinfileClientConfig *bfcfgP = static_cast(fSessionP->getSessionConfig()); // open changelog. Name is datastore name with _clg.bfi suffix string changelogname = bfcfgP->relatedDBNameBase(getName(), bfcP->fRemotepartyID); changelogname += CHANGELOG_DB_SUFFIX; fChangeLog.setFileInfo(changelogname.c_str(),CHANGELOG_DB_VERSION,CHANGELOG_DB_ID,sizeof(TChangeLogEntry)); if (fChangeLog.open(sizeof(TChangeLogHeader),&fChgLogHeader,changelogUpdateFunc)!=BFE_OK) { // can't open changelog - check if we might need need migration from united changelogs to separated if (bfcfgP->fSeparateChangelogs) { // check if we have the old united changelog and migrate everything if so string unitedchangelogname = bfcfgP->relatedDBNameBase(getName(), -1); // united name unitedchangelogname += CHANGELOG_DB_SUFFIX; fChangeLog.setFileInfo(unitedchangelogname.c_str(),CHANGELOG_DB_VERSION,CHANGELOG_DB_ID,sizeof(TChangeLogEntry)); if (fChangeLog.open(sizeof(TChangeLogHeader),&fChgLogHeader,changelogUpdateFunc)==BFE_OK) { // the old unified changelog is there - we need to do a full migration now // - close it fChangeLog.close(); // - perform migration for this DB PDEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI,("openChangeLog: auto-migrating from common to profile-separated changelog for this datastore")); bfcfgP->separateChangeLogsAndRelated(getName()); // - recursively call myself, now the profile specific log should be there return openChangeLog(); } // we're not migrating (we could not open the changelog because this is a new profile!) // - restore the per-profile name for creation of new log below fChangeLog.setFileInfo(changelogname.c_str(),CHANGELOG_DB_VERSION,CHANGELOG_DB_ID,sizeof(TChangeLogEntry)); } // create new change log or overwrite incompatible one // - init changelog header fields fChgLogHeader.modcount=0; //set all bytes to zero to avoid memory warnings memset(fChgLogHeader.lastChangeCheckIdentifier, 0, changeIndentifierMaxLen); fChgLogHeader.lastChangeCheck = noLinearTime; // - create new changelog fChangeLog.create(sizeof(TChangeLogEntry),sizeof(TChangeLogHeader),&fChgLogHeader,true); PDEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI,("openChangeLog: changelog did not exist (or bad version) -> created new")); return false; // changelog is new, so we need a slow sync } else { // check if opening was an upgrade from version 2 if (fChangeLog.getFoundVersion()<3) { // version 3 has introduced saving the last-check date/identifiers in the changelog header, // before that the identifiers used where (wrongly) those of the target. So copy // the target info to the new header now. This gives perfect results only for single // profile use, but existing products before update to v3 were single profile so we can // safely assume this will give a smooth transition (without re-send-everything effects). #if TARGETS_DB_VERSION>5 // - dummyIdentifier1 is the former lastSyncIdentifier and contains the token from the // last change check towards the DB (in case sync identifiers are available at all) AssignCString(fChgLogHeader.lastChangeCheckIdentifier,fTarget.dummyIdentifier1,changeIndentifierMaxLen); #endif // - lastChangeCheck is the former lastTwoWaySync and contains the timestamp of the last change check towards the DB fChgLogHeader.lastChangeCheck = fTarget.lastChangeCheck; // - make sure it gets written back fChangeLog.setExtraHeaderDirty(); fChangeLog.flushHeader(); PDEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI,("openChangeLog: upgraded changelog from V2 to V4 (new header, new modcount_created)")); } } return true; // changelog already existed, so we assume it's up-to-date } // TBinfileImplDS::openChangeLog // returns true if we had a valid pending map file bool TBinfileImplDS::openPendingMaps(void) { if (fPendingMaps.isOpen()) return true; // was already open openChangeLog(); // must be open, because it checks for migration of pendingmaps as well string pendingmapsname = static_cast(fSessionP->getSessionConfig())->relatedDBNameBase(getName(), fTarget.remotepartyID); pendingmapsname += PENDINGMAP_DB_SUFFIX; fPendingMaps.setFileInfo(pendingmapsname.c_str(),PENDINGMAP_DB_VERSION,PENDINGMAP_DB_ID, sizeof(TPendingMapEntry)); PDEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI+DBG_EXOTIC,("openPendingMaps: file name='%s'",pendingmapsname.c_str())); if (fPendingMaps.open(sizeof(TPendingMapHeader),&fPendingMapHeader)!=BFE_OK) { // create new pending maps or overwrite incompatible one // - bind to remote party (in case of combined changelog, we only have a single pendingmap file, and it is valid only for ONE remote party) fPendingMapHeader.remotepartyID = static_cast(fSessionP)->fRemotepartyID; // - create new changelog fPendingMaps.create(sizeof(TPendingMapEntry),sizeof(TPendingMapHeader),&fPendingMapHeader,true); PDEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI,("openPendingMaps: pending maps did not exist (or bad version) -> created new")); return false; // pending map file is new, so we have no already pending maps } return true; // pending map file already existed, so we assume it's up-to-date } // TBinfileImplDS::openPendingMaps // get reference time to be used as reference date for this sync's modifications // Note: this time marks the beginning of the sync session. If possible // datastore should mark all modifications with this time, even if // they occur later during the sync session. Only if setting the // modified date explicitly is not possible, setting fCmpRefTimeStampAtEnd // (default = defined(SYNCTIME_IS_ENDOFSESSION)) can be used to make sure // that modifications made during the session are not detected as changed // for the next session. lineartime_t TBinfileImplDS::getThisSyncModRefTime(void) { return #ifdef SYNCTIME_IS_LOCALTIME makeLocalTimestamp(fCurrentSyncTime); // make local time for comparison #else fCurrentSyncTime; #endif } // TBinfileImplDS::getThisSyncModRefTime // get reference time to be used in case datastore implementation wants to compare // with the time of last sync (last two-way sync, that is!) lineartime_t TBinfileImplDS::getLastSyncModRefTime(void) { return #ifdef SYNCTIME_IS_LOCALTIME makeLocalTimestamp(fPreviousSyncTime); // make local time for comparison #else fPreviousSyncTime; #endif } // TBinfileImplDS::getLastSyncModRefTime // update change log using CRC checksum comparison before syncing // Note: Don't call before types are ok (we need TSyncItems) localstatus TBinfileImplDS::changeLogPreflight(bool &aValidChangelog) { localstatus sta = LOCERR_OK; aValidChangelog = false; bferr err = BFE_OK; TChangeLogEntry *existingentries = NULL; // none yet uInt32 numexistinglogentries; bool foundone; uInt32 seen = 0; uInt32 logindex; TChangeLogEntry newentry; //set zeros to avoid memory warnings memset(&newentry, 0, sizeof(newentry)); TSyncItem *itemP = NULL; localid_out_t itemLocalID; uInt16 dataCRC = 0; bool itemIsModified = false; // just in case: make sure we don't have a changelog loaded here forgetChangeLog(); // no changes detected yet fNumberOfLocalChanges=0; // make sure we have the change log DB open openChangeLog(); // - get saved modcount for this database and increment for this preflight fChgLogHeader.modcount += 1; fCurrentModCount = fChgLogHeader.modcount; // - update date of last check to start of sync - everything happening during or after this sync is for next session // Note: this is used only if not CRC_CHANGE_DETECTION fChgLogHeader.lastChangeCheck = fCurrentSyncTime; // change log header is dirty fChangeLog.setExtraHeaderDirty(); PDEBUGBLOCKCOLL("changeLogPreflight"); #ifdef SYDEBUG string lsd; StringObjTimestamp(lsd,fPreviousSyncTime); PDEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI,( "changeLogPreflight: %sfCurrentModCount=%ld, fPreviousToRemoteModCount=%ld, fPreviousSyncTime(UTC)=%s", isResuming() ? "RESUMING, " : "", (long)fCurrentModCount, (long)fPreviousToRemoteModCount, lsd.c_str() )); #endif // - save header err = fChangeLog.flushHeader(); if (err!=BFE_OK) goto done; // - we don't need the changelog to be updated when all we do is refresh from server if (isRefreshOnly()) goto done; // done ok // - load entire existing changelog into memory numexistinglogentries = fChangeLog.getNumRecords(); // logentries that are already there PDEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI,("changeLogPreflight: at start, changelog has %ld entries",(long)numexistinglogentries)); if (numexistinglogentries>0) { // - allocate array for all existing entries (use sysync_malloc because e.g. on PalmOS this uses special funcs to allow > 64k) existingentries = (TChangeLogEntry *)sysync_malloc(sizeof(TChangeLogEntry)*numexistinglogentries); if (!existingentries) { err=BFE_MEMORY; goto done; } // not enough memory // - read all entries fChangeLog.readRecord(0,existingentries,numexistinglogentries); // Mark all not-yet-deleted in the log as delete candidate // (those that still exist will be get the candidate mark removed below) for (logindex=0;logindexgetLocalID(),localid); } else { // without CRC, we have got the ID into itemLocalID already localid=LOCALID_OUT_TO_IN(itemLocalID); } #endif // not RECORDHASH_FROM_DBAPI // show item info found in DB #ifdef SYDEBUG string sl; LOCALID_TO_STRING(localid,sl); if (CRC_CHANGE_DETECTION) { #ifdef RECORDHASH_FROM_DBAPI PDEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI,("changeLogPreflight: item #%ld : localid=%s, dataCRC=0x%04hX, NOC=%ld ",(long)seen,sl.c_str(),(long)fNumberOfLocalChanges,dataCRC)); #else PDEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI,("changeLogPreflight: item #%ld : localid=%s, NOC=%ld ",(long)seen,sl.c_str(),(long)fNumberOfLocalChanges)); #endif } else { PDEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI,( "changeLogPreflight: item #%ld : localid=%s, database says item %s modified", (long)seen,sl.c_str(), itemIsModified ? "IS" : "is NOT" )); } #endif // SYDEBUG // - search for already existing changelog entry for this uniqueID // (prevent searching those that we have created in this preflight) bool chgentryexists=false; // none found yet TChangeLogEntry *currentEntryP = NULL; // no entry yet for (logindex=0; logindexflags & chgl_delete_candidate) { currentEntryP->flags &= ~chgl_delete_candidate; // remove candidate flag } // found if (CRC_CHANGE_DETECTION) { PDEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI+DBG_EXOTIC,( "- found in changelog at index=%ld, flags=0x%02hX, modcount=%ld, modcount_created=%ld, saved CRC=0x%04hX", (long)logindex, (uInt16)currentEntryP->flags, (long)currentEntryP->modcount, (long)currentEntryP->modcount_created, currentEntryP->dataCRC )); } else { PDEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI+DBG_EXOTIC,( "- found in changelog at index=%ld, flags=0x%02hX, modcount=%ld, modcount_created=%ld", (long)logindex, (uInt16)currentEntryP->flags, (long)currentEntryP->modcount, (long)currentEntryP->modcount_created )); } break; } } // - create new record if (!chgentryexists) { // set unique ID, init other fields ASSIGN_LOCALID_TO_FLD(newentry.dbrecordid,localid); // - just init these, will be updated with real values below newentry.flags = 0; newentry.dataCRC = 0; newentry.modcount = 0; newentry.modcount_created = 0; PDEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI+DBG_EXOTIC,("- does not yet exist in changelog, created new")); // new entry is now current entry currentEntryP = &newentry; } // now check what to do if (CRC_CHANGE_DETECTION) { #ifndef RECORDHASH_FROM_DBAPI // we need a CRC but don't have it precalculated from the DB layer dataCRC=itemP->getDataCRC(0,true); // start new CRC, do not include eqm_none fields #endif // not RECORDHASH_FROM_DBAPI } // - check if new or changed if (chgentryexists && !(currentEntryP->flags & chgl_deleted)) { // entry exists (and is not a deleted one), could be changed if (CRC_CHANGE_DETECTION) { // - check CRC to calculate itemIsModified itemIsModified = existingentries[logindex].dataCRC!=dataCRC; if (itemIsModified) { PDEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI+DBG_EXOTIC,( "- item has changed (current CRC=0x%04hX, old CRC=0x%04hX)", dataCRC, currentEntryP->dataCRC )); // has changed since last time checked by preflight (but only those! There might be more items // changed since last sync or resume, but these ALREADY have a modcount in the changelog that // flags them such). // So this is the place to reset chgl_modbysync (which marks items changed by a sync and not from outside) currentEntryP->flags &= ~chgl_modbysync; // detecting a real change here cancels the mod-by-sync flag set for sync-added/changed entries // update CRC and modification count currentEntryP->dataCRC=dataCRC; currentEntryP->modcount=fCurrentModCount; // update modification count // this is a local change for this session fNumberOfLocalChanges++; // for suspend: those that detect a change here were modified AFTER last suspend, so always count them } } else { // - DB has reported change status into itemIsModified already if (itemIsModified) { PDEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI+DBG_EXOTIC,("- item has changed (according to what database says)")); // has changed since last time checked by preflight (but only those! There might be more items // changed since last sync or resume, but these ALREADY have a modcount in the changelog that // flags them such). // So this is the place to reset chgl_modbysync (which marks items changed by a sync and not from outside) currentEntryP->flags &= ~chgl_modbysync; // detecting a real change here cancels the mod-by-sync flag set for sync-added/changed entries // update modification count currentEntryP->modcount=fCurrentModCount; // this is a local change for this session fNumberOfLocalChanges++; // for suspend: those that detect a change here were modified AFTER last suspend, so always count them } } if (!itemIsModified) { // no change detected since last preflight (but still, this could be a change to report to the server) if (isResuming()) { // if resuming - only those count that are marked for resume if (currentEntryP->flags & chgl_markedforresume) fNumberOfLocalChanges++; // in resumes: only count those that are actually marked for resume } else { // not resuming - all existing ones count if this is a slow sync, // otherwise, those modified since last to-remote-sync count as well (although not modified since last preflight!) if (fSlowSync || currentEntryP->modcount>fPreviousToRemoteModCount) fNumberOfLocalChanges++; } } } else { // entry does not exist (or existed as deleted entry) -> means that this record was (maybe: re-)added new // (since last preflight, which always means also AFTER last suspend!) // - is modified now currentEntryP->modcount = fCurrentModCount; // - is (re)created now: set the creation modcount, this is used to detect a client-side newly added item currentEntryP->modcount_created = fCurrentModCount; // - no flags set currentEntryP->flags = 0; // - update CRC to current value if CRC is in use if (CRC_CHANGE_DETECTION) { currentEntryP->dataCRC = dataCRC; } else { currentEntryP->dataCRC = 0; // clean it for cosmetic reasons only } // create if entry is new if (!chgentryexists) { // this is a new, additional entry (and not a resurrected deleted one) fChangeLog.newRecord(currentEntryP); PDEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI,("- item was newly added (no entry existed in changelog before)")); } else { // the entry itself existed, but was a deleted entry. We're now re-using that one PDEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI,("- item has re-appeared (i.e. item with same local uniqueID that was once before deleted is now here again)")); } // this is a local change for this session (even for resume - we need to add newly added ones in resume!) fNumberOfLocalChanges++; } // Next item if (CRC_CHANGE_DETECTION) { #ifdef RECORDHASH_FROM_DBAPI foundone = getNextItemCRC(itemLocalID,dataCRC); #else // forget this one delete itemP; // check next foundone = getNextItem(itemP); #endif } else { #ifdef CHANGEDETECTION_AVAILABLE foundone = getNextItemInfo(itemLocalID,itemIsModified); #endif } } // while all records in DB // check that we've terminated the list because we've really seen all items and not // because of an error reading an item (which would cause false deletes) if (isDBError(lastDBError())) { sta=510; // database error goto error; } // now find and update delete candidates // (That is, all entries in the log that have no DB record associated any more) // Note: we only search logentries that were here already before the preflight, // because new ones never are delete candidates for (logindex=0;logindex mark deleted",(long)logindex)); // this is a local change for this session if (!isResuming() || (existingentries[logindex].flags & chgl_markedforresume)) fNumberOfLocalChanges++; // in resumes: only count those that are actually marked for resume } } // successfully updated in memory, now write changed entries back to binfile // Note: entries created during this preflight are already saved. Only in-memory modifications to pre-existing ones need to be saved. #ifdef SYDEBUG DEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI+DBG_EXOTIC,("changeLogPreflight: saving %ld existing entries",(long)numexistinglogentries)); if (DEBUGTEST(DBG_ADMIN+DBG_DBAPI+DBG_EXOTIC)) { for (uInt32 si=0; si(fSessionP)->fRemotepartyID; TBinFile *targetsBinFileP = &(static_cast(fSessionP)->fConfigP->fTargetsBinFile); // for server or version with syncrequests in config, we must try to load // the target record or create one if it is missing if (fTargetIndex<0) { // try to find target by fRemotepartyID and targetDB code/name uInt32 maxidx=targetsBinFileP->getNumRecords(); uInt32 recidx; for (recidx=0; recidxreadRecord(recidx,&fTarget)==BFE_OK) { // check if this is my target if ( fTarget.remotepartyID == remotepartyID && fTarget.localDBTypeID == fConfigP->fLocalDBTypeID && strucmp(fTarget.localDBPath,fConfigP->fLocalDBPath.c_str(),localDBpathMaxLen)==0 ) { // this is the target record for our DB, now get it (mark it busy) fTargetIndex=recidx; return LOCERR_OK; // target found } } } // target not found if (aCreateIfMissing) { // create new target record // - init with defaults fConfigP->initTarget(fTarget,remotepartyID,aRemoteDBID,true); // enabled if created here! // - save new record uInt32 ti; targetsBinFileP->newRecord(ti,&fTarget); fTargetIndex = ti; return LOCERR_OK; // created and loaded now } return 404; // not found } return LOCERR_OK; // already loaded } // TBinfileImplDS::loadTarget // - called for SyncML 1.1 if remote wants number of changes. // Must return -1 if no NOC value can be returned // NOTE: we implement it here only for server, as it is not really needed // for clients normally - if it is needed, client's agent must provide // it in derived class as StdLogicDS has no own list it can use to count // in client case. sInt32 TBinfileImplDS::getNumberOfChanges(void) { if (binfileDSActive() && IS_CLIENT) { // for client case with active binfile, we return the locally computed count // (for server, the entire list of changes is loaded by the baseclass // before NOC is needed, so the baseclass has the more accurate count // which takes filtering etc. into account). return fNumberOfLocalChanges; } // otherwise, let base class handle it (server and client w/o binfile) return inherited::getNumberOfChanges(); } bool TBinfileImplDS::hasPendingChangesForNextSync() { if (binfileDSActive() && IS_CLIENT) { // shortcut? if (fHasPendingChanges) { PDEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI+DBG_EXOTIC,("sync session known to be incomplete")); return true; } // also check change log, just to be sure; // note that new entries in the change log that were // added during the current sync session are not yet loaded, // and that entries in memory may still need to be flushed // to disk if (fLoadedChangeLog) { for (uInt32 si=0; si fCurrentModCount) { #ifdef NUMERIC_LOCALIDS PDEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI+DBG_EXOTIC,( "%ld : localID=%ld, flags=0x%X, modcount=%ld, modcount_created=%ld => pending change", (long)si, fLoadedChangeLog[si].dbrecordid, (int)fLoadedChangeLog[si].flags, (long)fLoadedChangeLog[si].modcount, (long)fLoadedChangeLog[si].modcount_created )); #else PDEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI+DBG_EXOTIC,( "%ld : localID='%s', flags=0x%X, modcount=%ld, modcount_created=%ld => pending change", (long)si, fLoadedChangeLog[si].dbrecordid, (int)fLoadedChangeLog[si].flags, (long)fLoadedChangeLog[si].modcount, (long)fLoadedChangeLog[si].modcount_created )); #endif return true; } } } return false; } return inherited::getNumberOfChanges(); } /// sync login (into this database) /// @note might be called several times (auth retries at beginning of session) /// @note must update the following saved AND current state variables /// - in TLocalEngineDS: fLastRemoteAnchor, (fLastLocalAnchor), fResumeAlertCode, fFirstTimeSync /// - for client: fPendingAddMaps /// - in TStdLogicDS: fPreviousSyncTime, fCurrentSyncTime /// - in TBinfileImplDS: ??? /// @todo document these /// - in derived classes: whatever else belongs to dsSavedAdmin and dsCurrentAdmin state localstatus TBinfileImplDS::implMakeAdminReady( cAppCharP aDeviceID, // remote device URI (device ID) cAppCharP aDatabaseID, // database ID cAppCharP aRemoteDBID // database ID of remote device ) { if (!binfileDSActive()) return LOCERR_WRONGUSAGE; // must be active when called at all localstatus sta=LOCERR_OK; // assume ok PDEBUGBLOCKDESCCOLL("implMakeAdminReady","Loading target info and pending maps"); // - init defaults fLastRemoteAnchor.erase(); fPreviousSyncTime=0; fFirstTimeSync=false; // assume not first time #if !defined(PRECONFIGURED_SYNCREQUESTS) // when sync params are in binfiles, target must be present by now - make sure it is loaded sta=loadTarget(false); // target info must already be present by now (loaded at session's SelectProfile) if (sta!=LOCERR_OK || fTargetIndex<0) { // problem loading target record sta = sta ? sta : 404; PDEBUGPRINTFX(DBG_ERROR,("Error %d loading target record",sta)); PDEBUGENDBLOCK("implMakeAdminReady"); return sta; } // we have the target in the fTarget member #else // e.g. for clients without syncrequests in config, target record might not exist here, so we allow creating it sta=loadTarget(true, aRemoteDBID); #endif // Now fTarget has valid target info // - if we don't have any remote anchor stored, this must be a first time sync if (*(fTarget.remoteAnchor)==0) fFirstTimeSync=true; // - get last anchor if (fTarget.forceSlowSync) { // - forget last anchor fLastRemoteAnchor.erase(); // make sure we get a slow sync } else { // - get last anchor fLastRemoteAnchor.assign(fTarget.remoteAnchor); } // - get last resume info fPreviousSuspendModCount = fTarget.lastSuspendModCount; /// @note: before DS 1.2 engine this was used as "lastModCount" fResumeAlertCode = fTarget.resumeAlertCode; // - get last sync time and changelog cursor fPreviousToRemoteModCount = fTarget.lastTwoWayModCount; // reference is when we've last full-synced! fPreviousSyncTime = fTarget.lastSync; PDEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI,( "implMakeAdminReady(binfile): ResumeAlertCode=%hd, PreviousSuspendModCount=%ld, PreviousToRemoteModCount=%ld, LastRemoteAnchor='%s'", fResumeAlertCode, (long)fPreviousSuspendModCount, (long)fPreviousToRemoteModCount, fLastRemoteAnchor.c_str() )); // determine time of this sync (will be overridden in case of BASED_ON_BINFILE_CLIENT) fCurrentSyncTime=getSession()->getSystemNowAs(TCTX_UTC); // NOW ! // do some more things if we are starting sync now if (!fPreflighted) { if (!openChangeLog()) { // changelog did not exist yet // - force slow sync fTarget.forceSlowSync=true; // set target flag to force slowsync even if we repeat this fLastRemoteAnchor.erase(); fPreviousSyncTime = noLinearTime; fPreviousToRemoteModCount = 0; fPreviousSuspendModCount = 0; // - no compare references yet fPreviousToRemoteSyncCmpRef = noLinearTime; fPreviousSuspendIdentifier.erase(); } else { // Get token and date representing last update of this changelog (last preflight) // Note: towards the database, we only check for changes since the last preflight (the fPreviousToRemoteSyncCmpRef is semantically // incorrect when TCustomImplDS is used with BASED_ON_BINFILE_CLIENT on top of binfile). // The separation between changes since last-to-remote sync and last resume is done based on the changelog modcounts. // - get date of last check fPreviousToRemoteSyncCmpRef=fChgLogHeader.lastChangeCheck; fPreviousSuspendCmpRef=fPreviousToRemoteSyncCmpRef; // DB on top of binfile only needs one reference time, which is the last changelog check time. #ifdef SYDEBUG string lsd; StringObjTimestamp(lsd,fPreviousToRemoteSyncCmpRef); PDEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI,("- last preflight update (fPreviousToRemoteSyncCmpRef) at %s",lsd.c_str())); #endif // SYDEBUG #if TARGETS_DB_VERSION>=6 // - DB api level change detection identifiers fPreviousToRemoteSyncIdentifier.assign(fChgLogHeader.lastChangeCheckIdentifier); fPreviousSuspendIdentifier = fPreviousToRemoteSyncIdentifier; // DB on top of binfile only needs one reference time, which is the last changelog check time. PDEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI,("- last preflight update (fPreviousToRemoteSyncIdentifier) is '%s'",fPreviousToRemoteSyncIdentifier.c_str())); #endif // TARGETS_DB_VERSION>=6 } } // get pending maps anyway (even if not resuming there might be pending maps) if(openPendingMaps()) { // there is a pending map file, check if these are really our maps // Note: with separated changelogs, this should be always the case! PDEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI+DBG_EXOTIC,( "implMakeAdminReady: remotePartyID of pendingmaps=%ld, current profile's remotepartyID=%ld", (long)fPendingMapHeader.remotepartyID, (long)static_cast(fSessionP)->fRemotepartyID )); if (fPendingMapHeader.remotepartyID == static_cast(fSessionP)->fRemotepartyID) { // these are our maps, load them TPendingMapEntry pme; string localid; for (uInt32 i=0; i(fSessionP->getSessionConfig())->relatedDBNameBase(getName(), fTarget.remotepartyID); fname += PENDINGITEM_DB_SUFFIX; pendingItemFile.setFileInfo(fname.c_str(),PENDINGITEM_DB_VERSION,PENDINGITEM_DB_ID,0); // no expected record size PDEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI+DBG_EXOTIC,( "opening pending item file: file name='%s'", fname.c_str() )); if (pendingItemFile.open(sizeof(TPendingItemHeader),&pendingItemHeader)==BFE_OK) { // we have a pending item file if (pendingItemHeader.remotepartyID == static_cast(fSessionP)->fRemotepartyID) { // this is our pending item, load it // - transfer header data fPartialItemState = pendingItemHeader.piState; // note: we always have the pi_state_loaded... state here fLastItemStatus = pendingItemHeader.lastItemStatus; fLastSourceURI = pendingItemHeader.lastSourceURI; fLastTargetURI = pendingItemHeader.lastTargetURI; fPITotalSize = pendingItemHeader.totalSize; fPIUnconfirmedSize = pendingItemHeader.unconfirmedSize; fPIStoredSize = pendingItemHeader.storedSize; // - load the data if any if (fPIStoredDataP && fPIStoredDataAllocated) smlLibFree(fPIStoredDataP); fPIStoredDataP=NULL; fPIStoredDataAllocated=false; if (fPIStoredSize) { fPIStoredDataP=smlLibMalloc(fPIStoredSize+1); // one for safety null terminator if (fPIStoredDataP) { fPIStoredDataAllocated=true; // get the data pendingItemFile.readRecord(0,fPIStoredDataP,1); *((uInt8 *)fPIStoredDataP+fPIStoredSize)=0; // safety null terminator } else { PDEBUGPRINTFX(DBG_ERROR,("Cannot allocate buffer (%ld bytes) for pendingitem",(long)fPIStoredSize)); fPIStoredSize=0; } } } PDEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI,("implMakeAdminReady: loaded pending item with %ld data bytes",(long)fPIStoredSize)); // done pendingItemFile.close(); } } // done PDEBUGENDBLOCK("implMakeAdminReady"); return sta; } // TBinfileImplDS::implMakeAdminReady localstatus TBinfileImplDS::implStartDataRead() { if (!binfileDSActive()) return LOCERR_WRONGUSAGE; // must be active when called at all // init reading of all records // - start at beginning of log fLogEntryIndex=0; return LOCERR_OK; } // TBinfileImplDS::implStartDataRead /* %%% seems obsolete - never called from anywhere #ifdef OBJECT_FILTERING // Test Filters bool TBinfileImplDS::testFilters(TMultiFieldItem *aItemP) { return // generally suitable item for this datastore aItemP->testFilter(fLocalDBFilter.c_str()) && // and passing current sync set filter aItemP->testFilter(fSyncSetFilter.c_str()) && // and not invisible ( getDSConfig()->fInvisibleFilter.empty() || // no invisible filter means visible !aItemP->testFilter(getDSConfig()->fInvisibleFilter.c_str()) // failing invisible filter means visible too ); } // TBinfileImplDS::testFilters #endif */ /// @brief called to have all non-yet-generated sync commands as "to-be-resumed" void TBinfileImplDS::implMarkOnlyUngeneratedForResume(void) { if (!binfileDSActive()) return; // must be active when called at all TChangeLogEntry *chglogP; // simply return aEof when just refreshing if (fRefreshOnly) return; // make sure we have the changelog in memory loadChangeLog(); // check if more records uInt32 logEntryIndex=fLogEntryIndex; DEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI+DBG_EXOTIC,("implMarkOnlyUngeneratedForResume: total=%ld, already generated=%ld",(long)fLoadedChangeLogEntries,(long)logEntryIndex)); // Note: already generated entries had their flag cleared when they were generated. // Some of them might already be marked now again by early markItemForResume() due to unsuccessful status // for all remaining records, check if they must be marked or not // (depends on current marked state as well if this is a resumed session already) while (logEntryIndexflags & chgl_markedforresume)) { // not marked for resume, but check if it has changed after the last suspend if (chglogP->modcount<=fPreviousSuspendModCount) { // is not marked for resume AND has not changed since last suspend markforresume=false; // not to be included in resume } } } if (markforresume) { // this item would have been reported in THIS session // now check if this should be marked for resume for NEXT session if (fSlowSync) { // slow sync mode if (chglogP->flags & chgl_deleted) { // skip deleted in slow sync markforresume=false; // not to be included in resume } } else if (!fSlowSync) { // prevent ANY reporting of items marked as receiveOnly in normal sync (but send them in slow sync!) if (chglogP->flags & chgl_receive_only) { // skip receive-only items in normal sync. So deleting or changing them locally will not send them // to the server. However after a slow sync, existing local items will be send (and possibly added, // if not already there) to the server markforresume=false; // not to be included in resume } else { // mark for resume if change to be reported markforresume=chglogP->modcount>fPreviousToRemoteModCount; } } } // now apply change of chgl_markedforresume to actual changelog entry #ifdef NUMERIC_LOCALIDS DEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI+DBG_EXOTIC,( "implMarkOnlyUngeneratedForResume: localID=%ld new markforresume=%d, old markforresume=%d", (long)chglogP->dbrecordid, (int)markforresume, (int)((chglogP->flags & chgl_markedforresume)!=0) )); #else DEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI+DBG_EXOTIC,( "implMarkOnlyUngeneratedForResume: localID='%s' new markforresume=%d, old markforresume=%d", chglogP->dbrecordid, (int)markforresume, (int)((chglogP->flags & chgl_markedforresume)!=0) )); #endif // update flag if (markforresume) chglogP->flags |= chgl_markedforresume; else chglogP->flags &= ~chgl_markedforresume; // Note: changelog will be saved at SaveAdminData } } // TBinfileImplDS::implMarkOnlyUngeneratedForResume // called to mark an already generated (but unsent or sent but not yet statused) item // as "to-be-resumed", by localID or remoteID (latter only in server case). void TBinfileImplDS::implMarkItemForResume(cAppCharP aLocalID, cAppCharP aRemoteID, bool aUnSent) { if (!binfileDSActive()) return; // must be active when called at all // make sure we have the changelog in memory loadChangeLog(); localid_out_t locID; STR_TO_LOCALID(aLocalID,locID); // search for item by localID uInt32 i; for (i=0; i=fLoadedChangeLogEntries) { DEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI+DBG_EXOTIC,( "implMarkItemForResume: localID='%s': changelog entry not found", aLocalID )) } #endif } // TBinfileImplDS::implMarkItemForResume // called to mark an already sent item as "to-be-resent", e.g. due to temporary // error status conditions, by localID or remoteID (latter only in server case). void TBinfileImplDS::implMarkItemForResend(cAppCharP aLocalID, cAppCharP aRemoteID) { if (!binfileDSActive()) return; // must be active when called at all // make sure we have the changelog in memory loadChangeLog(); localid_out_t locID; STR_TO_LOCALID(aLocalID,locID); // search for item by localID uInt32 i; for (i=0; i=fLoadedChangeLogEntries) { DEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI+DBG_EXOTIC,( "implMarkItemForResend: localID='%s': changelog entry not found", aLocalID )) } #endif } // TBinfileImplDS::implMarkItemForResend // Get next item from database localstatus TBinfileImplDS::implGetItem( bool &aEof, bool &aChanged, // if set on entry, only changed ones will be reported, otherwise all will be returned and aChanged contains flag if entry has changed or not TSyncItem* &aSyncItemP ) { if (!binfileDSActive()) return LOCERR_WRONGUSAGE; // must be active when called at all localstatus sta=LOCERR_OK; TSyncItem *myitemP=NULL; TChangeLogEntry *chglogP; bool onlyChanged = aChanged; aEof=true; // Update change log // Note: we cannot do it earlier as we need item types setup correctly // which is not the case before here! if (!fPreflighted) { fPreflighted=true; // find and update (if not refreshing) changelog for this database bool normal=false; sta=changeLogPreflight(normal); if (sta!=LOCERR_OK) return sta; // database error } // simply return aEof when just refreshing if (fRefreshOnly) return LOCERR_OK; // make sure we have the changelog in memory loadChangeLog(); do { if (fLogEntryIndexflags & chgl_markedforresume)) { // not marked for resume, but check if it has changed after the last suspend // NOTE: this catches those added after last suspend as well, which is IMPORTANT // (otherwise, they would not get detected later, as we do not differentiate // adds and replaces (unlike in server, where new adds will be shown in the // next session after the resumed one) if (chglogP->modcount<=fPreviousSuspendModCount) { // is not marked for resume AND has not changed (or was added) since last suspend continue; // not for resume - check next } else { // New behaviour here from 3.1.5.2 onwards: // SyncML DS 1.2.1 explicitly FORBIDS that changes happening after suspending // are included in a resume. So we have to post-pone these. For that we must artificially // mark them changed such that they will be detected in next non-resume (but not before). // Note that this also affects other profiles as there is only one single changelog - // however, this is not a problem because the records detected new or changed now // will inevitably be new or changed in all other profiles as well. So we can // safely touch these record's modcount w/o any noticeable side effects in other profiles. PDEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,("Detected item changed/added after suspend -> postpone reporting it for next non-resumed session")); // - update the mod count such that this record will be detected again in the next non-resumed session // (fCurrentModCount marks entries changed in this session, +1 makes sure these will be detected in the NEXT session) chglogP->modcount=fCurrentModCount+1; // also update the creation stamp for new added item if(chglogP->modcount_created > fPreviousToRemoteModCount) { chglogP->modcount_created=fCurrentModCount+1; } // - mark it "modified by sync" to prevent it being sent during resume chglogP->flags |= chgl_modbysync; } } /* NOTE: 2007-12-17, luz: I initially added chgl_modbysync just to prevent that adds from server occurred in a suspended part of the session would be sent back to the server in the resume (as these DO get marked for resume). However, this is not a good strategy because the server cannot know which of its adds were actually successful, so the client MUST send them back to the server so the server can tell which items must be sent (possibly again) and which are definitely already stored in the client. See correspondence with Faisal from Oracle around 2007-12-17. So the chgl_modbysync flag is maintained for now, but not used for anything. */ /* NOTE: 2008-01-11, luz: THE ABOVE IS WRONG! The server CAN know which adds were successful: those for which it has received a map in the suspended session or a begin-of-session-map in the current session (or both). So we SHOULD suppress those items that have chgl_modbysync set. */ // we are resuming, prevent reporting those back that were added or changed // by one of the suspended earlier parts of this session if (chglogP->flags & chgl_modbysync) { PDEBUGPRINTFX(DBG_ADMIN+DBG_HOT,("Item not sent because it was added/changed by remote in suspended previous session or by user on device after suspend")); continue; // these must NOT be reported back during a resumed sync } } else { // make sure we clear the resume mark on ALL entries, even those not reported // (as the marks are all invalid) chglogP->flags &= ~chgl_markedforresume; // for a non-resumed slow sync, also clear all resend flags if (fSlowSync) chglogP->flags &= ~chgl_resend; } // At this point, the current entry is a candidate for being reported // (not excplicitly excluded) // - now check if and how to report it if (fSlowSync) { // slow sync mode // - skip deleted in slow sync, but report all others if (chglogP->flags & chgl_deleted) { continue; // check next } } else { // prevent ANY reporting of items marked as receiveOnly in normal sync (but send them in slow sync!) if (chglogP->flags & chgl_receive_only) { // skip receive-only items in normal sync. So deleting or changing them locally will not send them // to the server. However after a slow sync, existing local items will be send (and possibly added, // if not already there) to the server continue; } // mark those as "changed" which have really changed or have the resend flag set bool hasChanged= (chglogP->modcount>fPreviousToRemoteModCount) || // change detected (chglogP->flags & chgl_resend); // or marked for resend e.g. due to error in last session #ifdef SYDEBUG if (chglogP->flags & chgl_resend) { PDEBUGPRINTFX(DBG_ADMIN+DBG_HOT,( "Item treated as changed because resend-flag was set" )); } #endif // clear resend flag now - it is processed chglogP->flags &= ~chgl_resend; // skip unchanged ones if only changed ones are to be reported if (!hasChanged && onlyChanged) continue; // unchanged, do not report // always report changed status in aChanged aChanged=hasChanged; } // this entry is to be reported // - now check how to report if (chglogP->flags & chgl_deleted) { // deleted: only report if it is also changed (i.e. delete detected since last sync) // Note: this can only happen when caller requests to see all records, not only changed, // which usually only occurs in slowsync where deletes are NOT reported anyway. // However: when caller must dynamically filter the syncset, it will request all records // even in normal syncs and then this can happen. if (!aChanged) continue; // delete was reported earlier, don't report it again // deleted, we cannot get it from the DB, create a empty item myitemP = new TSyncItem(); // add ID ASSIGN_LOCALID_TO_ITEM(*myitemP,chglogP->dbrecordid); // deleted, syncop is delete myitemP->setSyncOp(sop_delete); } else { // get contents from the DB myitemP=NULL; // in case getItemByID should abort before pointer assigned sta = getItemByID(chglogP->dbrecordid,myitemP); if ((sta!=LOCERR_OK) || !myitemP) { // error getting record if (sta==404) { // record seems to have vanished between preflight and now PDEBUGPRINTFX(DBG_ERROR,("Record does not exist any more in database%s -> ignore",lastDBErrorText().c_str())); // simply don't include in sync set - next preflight will detect it deleted if (myitemP) delete myitemP; // delete in case we have some half-filled record here continue; // try next } else { // record does not exist PDEBUGPRINTFX(DBG_ERROR,("Error getting Record from DB%s -> Status %hd",lastDBErrorText().c_str(),sta)); goto error; } } // detect wheter the item is new added or changed if(chglogP->modcount_created > fPreviousToRemoteModCount) { // Added myitemP->setSyncOp(sop_add); } else { // Not added (changed or just reported because we want all records reported) // - if enabled, also verify change by checking CRC before reporting it (unless this is a slow sync) if (CRC_DETECT_PSEUDOCHANGES && aChanged) { // check if really changed using CRC, but only... // ...if not slow sync (all items must be reported) // ...if change was detected in this session's preflight. If the change was detected earlier and is still // pending (i.e. newer than the last sync), this means that this change might have failed to be applied // in a previous sync and thus must be reported again (but as CRC was updated in the last run, // it would be suppressed). This is a compromise that minimizes pseudochanges normally, but cannot // entirely prevent them. In other words: the first attempt to report a pseudo-change is // suppressed, but in case this sync fails, subsequent syncs will report it. uInt16 newDataCRC = myitemP->getDataCRC(0,true); PDEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI+DBG_EXOTIC,( "CRC comparison for pseudo-change detection: old CRC=0x%hX, new CRC=0x%hX, recordModCount=%u, currentModCount=%u", chglogP->dataCRC, newDataCRC, chglogP->modcount, fCurrentModCount )); if (chglogP->dataCRC==newDataCRC && !fSlowSync && chglogP->modcount==fCurrentModCount) { // none of the relevant fields have changed -> don't report the item PDEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI,("Not reporting localID='%s' as changed because CRC detected this as a pseudo-change.",myitemP->getLocalID())); aChanged = false; // even if it gets reported, it does not count as changed any more if (onlyChanged) { // we don't need to report this at all, as we only report changed ones delete myitemP; // delete the item continue; // don't report, try next } // report as unchanged } else { // change will now be reported, so update CRC to what we report now // Note: the problem with this is that in case the sync does not succeed now, the CRC is already updated and would // trigger pseudo-change detection in the next session. Therefore, pseudo-change detection is only active for // changes newly detected during this sync. chglogP->dataCRC = newDataCRC; } } // CRC_DETECT_PSEUDOCHANGES // - report as replace (changed or not) myitemP->setSyncOp(sop_replace); } // make sure item has the localid which was used to retrieve it ASSIGN_LOCALID_TO_ITEM(*myitemP,chglogP->dbrecordid); } // - make sure IDs are ok myitemP->clearRemoteID(); // client never has a remote ID // record found // - items that do go out into the engine must not any longer be marked for resume (from this session) // Note: they may get marked by receiving unsuccessful status for them before session ends! chglogP->flags &= ~chgl_markedforresume; DEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI+DBG_EXOTIC,("Reporting localID='%s', flags=0x%x as sop=%s",myitemP->getLocalID(),(int)chglogP->flags,SyncOpNames[myitemP->getSyncOp()])); aEof=false; break; } else { // no more records break; } } while(true); // loop until record found or EOF // set item to return aSyncItemP = myitemP; // ok return LOCERR_OK; error: // general database error PDEBUGPRINTFX(DBG_ERROR,("implGetItem error %hd%s",sta,lastDBErrorText().c_str())); aSyncItemP=NULL; return sta; } // TBinfileImplDS::implGetItem // end of read localstatus TBinfileImplDS::implEndDataRead(void) { if (!binfileDSActive()) return LOCERR_WRONGUSAGE; // must be active when called at all // pass it on to the DB api (usually dummy for traditional binfile derivates, but // needed for customimplds) return apiEndDataRead(); } // TBinfileImplDS::implEndDataRead /// forget changelog in memory void TBinfileImplDS::forgetChangeLog(void) { if (fLoadedChangeLog==NULL) return; // ok, already gone PDEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI+DBG_EXOTIC,("forgetChangeLog: DISCARDING already loaded changelog with %ld entries",(long)fLoadedChangeLogEntries)); sysync_free(fLoadedChangeLog); fLoadedChangeLog=NULL; fLoadedChangeLogEntries=0; } // TBinfileImplDS::forgetChangeLog /// load changelog into memory for quick access void TBinfileImplDS::loadChangeLog(void) { // if already loaded, simply return if (fLoadedChangeLog) return; // ok, already there // allocate memory for it fLoadedChangeLogEntries=fChangeLog.getNumRecords(); if (fLoadedChangeLogEntries>0) { // (use sysync_malloc because e.g. on PalmOS this uses special funcs to allow > 64k) fLoadedChangeLog = (TChangeLogEntry *)sysync_malloc(sizeof(TChangeLogEntry)*fLoadedChangeLogEntries); if (fLoadedChangeLog) { // now load it if (fChangeLog.readRecord(0,fLoadedChangeLog,fLoadedChangeLogEntries)==BFE_OK) { PDEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI+DBG_EXOTIC,("loadChangeLog: loaded changelog with %ld entries",(long)fLoadedChangeLogEntries)); } else { // cannot load from file, discard allocated buffer forgetChangeLog(); } } else { // not enough memory, cannot load fLoadedChangeLogEntries=0; } } } // TBinfileImplDS::loadChangeLog #define ZAP_FORCES_SLOWSYNC 1 // start of write localstatus TBinfileImplDS::implStartDataWrite(void) { if (!binfileDSActive()) return LOCERR_WRONGUSAGE; // must be active when called at all localstatus sta = LOCERR_OK; // latest chance to do preflight in case GetItem was never called if (!fPreflighted) { fPreflighted=true; // find and update (if not refreshing) changelog for this database bool normal=false; changeLogPreflight(normal); if (!normal) return LOCERR_UNDEFINED; // failure } // let api layer do it's stuff sta = apiStartDataWrite(); if (sta!=LOCERR_OK) return sta; // failed // check if we need to zap the datastore first // Note: only do it if not resuming! if (fSlowSync && fRefreshOnly && !isResuming()) { // yes, zap data sta = zapDatastore(); if (sta!=LOCERR_OK) { preventResuming(); // only half-zapped, prevent resuming (we must retry zapping ALL and then do a full slow sync anyway) return sta; // failed } // now, either zap the changelog and set this datastore to slowsync in all // other profiles or flag all entries as deleted during this sync. #ifdef ZAP_FORCES_SLOWSYNC // we force a slowsync, zap the changelog fChangeLog.truncate(0); // forget the anchor to force a slow sync anyway fTarget.remoteAnchor[0]=0; // (only to make sure. If sync completes successfully, this will be updated anyway in SaveAnchor) // for combined changelog, we need to take care of other profiles if (!static_cast(fSessionP->getSessionConfig())->fSeparateChangelogs) { // zap the anchors in all other profiles for this datastore // because we have deleted the (common) changelog. Note that this also resets our own // target's anchor (again) // get target DB TBinFile *targetsBinFileP = &(static_cast(fSessionP)->fConfigP->fTargetsBinFile); TBinfileDBSyncTarget target; // - loop trough all targets for (uInt32 ti=0; tigetNumRecords(); ti++) { targetsBinFileP->readRecord(ti,&target); if ( (target.localDBTypeID == fTarget.localDBTypeID) && // same datastoreID (strucmp(target.localDBPath,fTarget.localDBPath)==0) // ..and name ) { // this is a target of this datastore, remove saved anchor // to irreversibely force a slowsync next time target.remoteAnchor[0]=0; targetsBinFileP->updateRecord(ti,&target); } } } // if combined changelog #endif } // Load changelog as we need quick access loadChangeLog(); #ifndef ZAP_FORCES_SLOWSYNC if (fLoadedChangeLogEntries>0) { if (fSlowSync && fRefreshOnly) { // database was zapped, all existing changelog entries must be set to deleted // by this sync session. // (This is important for combined changelog, for separate changelog these entries // get obsolete anyway after this sync, but updating them for consistency is still good) for (uInt32 k=0; ksetSyncOp(aItem.getSyncOp()); // now copy retrieved contents to original item aItem = *itemP; delete itemP; } // ok return true; } // TBinfileImplDS::implRetrieveItemByID // process single item (but does not consume it) bool TBinfileImplDS::implProcessItem( TSyncItem *aItemP, // the item TStatusCommand &aStatusCommand ) { if (!binfileDSActive()) return LOCERR_WRONGUSAGE; // must be active when called at all localid_out_t newid; TSyError statuscode; localstatus sta; bool ok; bool receiveOnly=false; // default to normal two-way bool reportAsChangedInNextSync=false; bool reportAsDeletedInNextSync=false; TMultiFieldItem *augmentedItemP = NULL; SYSYNC_TRY { // - get op TSyncOperation sop = aItemP->getSyncOp(); // - get localid localid_t localid; STR_TO_LOCALID(aItemP->getLocalID(),localid); // - now perform op switch (sop) { // %%% note: sop_copy is now implemented by read/add sequence // in localdatatstore, but will be moved here later possibly case sop_add : // add record if ((sta=createItem(aItemP,newid,receiveOnly))!=LOCERR_OK) { PDEBUGPRINTFX(DBG_ERROR,("cannot create record in database (sta=%hd)",sta)); // check special "needs merge" case if (sta==DB_Conflict) { // DB has detected item conflicts with data already stored in the database and // request merging current data from the backend with new data before storing. // - get the ID of the record to merge with localid = LOCALID_OUT_TO_IN(newid); ASSIGN_LOCALID_TO_ITEM(*aItemP,localid); // - merge with database contents bool changedDBVersion, changedNewVersion; augmentedItemP = mergeWithDatabaseVersion(aItemP, changedDBVersion, changedNewVersion); if (augmentedItemP==NULL) sta = DB_Error; // no item found, DB error else { // store augmented version back to DB only if modified if (changedDBVersion) { STR_TO_LOCALID(augmentedItemP->getLocalID(),localid); sta = updateItemByID(localid,augmentedItemP); // we'll need to sync it back in the next session, // because the server's copy is now older than the // client's copy if (sta == LOCERR_OK) reportAsChangedInNextSync = true; } else { sta = LOCERR_OK; } } // The server now has two items where the client only has // one. If we were to tell the server the same local ID // for both of the server's items, it would get confused. // For example, the Synthesis engine then sent a Delete // request with empty client and server ID. // // Instead, let the rest of the code below proceed (to get // the state of the existing local item right), and then // create a unique, fake local ID that we assign to the // item and copy into the change log as "deleted item". if (sta == LOCERR_OK) reportAsDeletedInNextSync = true; } else { statuscode=sta; goto error; // check errors } } // set status statuscode=201; // added // set new localID into item localid = LOCALID_OUT_TO_IN(newid); ASSIGN_LOCALID_TO_ITEM(*aItemP,localid); break; case sop_replace : // change record if ((sta=updateItemByID(localid,aItemP))!=LOCERR_OK) { PDEBUGPRINTFX(DBG_ERROR,("cannot update record in database (sta=%hd)",sta)); statuscode=sta; goto error; // check errors } // set status statuscode=200; // replaced break; case sop_delete : // delete record if ((sta=deleteItemByID(localid))!=LOCERR_OK) { PDEBUGPRINTFX(DBG_ERROR,("cannot delete record in database (sta=%hd)",sta)); statuscode=sta; // not found goto error; // check errors } // set status statuscode=200; break; default : PDEBUGPRINTFX(DBG_ERROR,("Unknown sync-op in TBinfileImplDS::ProcessItem")); statuscode=501; // not implemented goto error; } // switch(sop) // update changelog uInt16 crc=0; // none unless we need it if (CRC_CHANGE_DETECTION || CRC_DETECT_PSEUDOCHANGES) { // - calc new data CRC if not deleted record if (sop!=sop_delete) { // - get new CRC. Note: to avoid differences in written and readback // data to cause "changed" records, we read the item from the DB again // altough this needs a little extra CPU performance #ifdef RECORDHASH_FROM_DBAPI if (getItemCRCByID(localid,crc)!=LOCERR_OK) { // we don't find the item with that localID. // Probably it has got another localID due to DB-internal reasons // (such as POOM changing a recurring appointment) // - handle this as if it was ok. Next session's preflight will find // that the item is gone and will send a delete to server, and // will also find a new item (this one under new localid) and add // this to the server. crc=0; DEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI,("Item has probably changed its localid during replace, CRC gets invalid")); } #else TSyncItem *readbackItemP=NULL; if (getItemByID(localid,readbackItemP)!=LOCERR_OK) { // we don't find the item with that localID. // Probably it has got another localID due to DB-internal reasons // (such as POOM changing a recurring appointment) // - handle this as if it was ok. Next session's preflight will find // that the item is gone and will send a delete to server, and // will also find a new item (this one under new localid) and add // this to the server. crc=0; DEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI,("Item has probably changed its localid during replace, CRC gets invalid")); } else { // Note: we don't need to set localID in item as it is not used in the CRC crc = readbackItemP->getDataCRC(0,true); // start new CRC, do not include eqm_none fields } if (readbackItemP) delete readbackItemP; #endif // not RECORDHASH_FROM_DBAPI } } // - search changelog entry sInt32 logindex=-1; TChangeLogEntry newentry; TChangeLogEntry *affectedentryP = &newentry; memset(&newentry, 0, sizeof(newentry)); for (uInt32 i=0; idataCRC=crc; if (reportAsChangedInNextSync) { // make sure NEXT sync will catch this again, as stored version is different // from what we received (merged with pre-existing duplicate) affectedentryP->modcount=fCurrentModCount+1; fHasPendingChanges=true; } else { // just current mod count affectedentryP->modcount=fCurrentModCount; } if (sop==sop_delete) affectedentryP->flags |= chgl_deleted; // set receiveOnly flag if needed. Note that this flag, once set, is never deleted (so item stays write only) if (receiveOnly) affectedentryP->flags |= chgl_receive_only; // set special flag which prevents that this change gets sent back in a resume as a // "modified or added after last suspend" type record (which it technically is, but we // use the flag to prevent that it is sent back if this session is suspended and resumed later. // Note that real adds and changes happening during suspend will also get this flag set // (but also receive a modcount>fCurrentModCount that makes sure these will be reported in // the next non-resumed session). affectedentryP->flags |= chgl_modbysync; // add to changelog DB if needed if (logindex<0) { // new added item ASSIGN_LOCALID_TO_FLD(affectedentryP->dbrecordid,localid); // also record the time this entry was created affectedentryP->modcount_created=fCurrentModCount; // save it #ifdef NUMERIC_LOCALIDS DEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI+DBG_EXOTIC,( "new entry %ld : localID=%ld, flags=0x%X, modcount=modcount_created=%ld, new dataCRC=0x%hX", (long)fChangeLog.getNumRecords(), affectedentryP->dbrecordid, (int)affectedentryP->flags, (long)affectedentryP->modcount, affectedentryP->dataCRC )); #else DEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI+DBG_EXOTIC,( "new entry %ld : localID='%s', flags=0x%X, modcount=modcount_created=%ld, new dataCRC=0x%hX", (long)fChangeLog.getNumRecords(), affectedentryP->dbrecordid, (int)affectedentryP->flags, (long)affectedentryP->modcount, affectedentryP->dataCRC )); #endif // Note: changeLogPostflight() will check these for temporary localids and finalize them when needed fChangeLog.newRecord(affectedentryP); } if (reportAsDeletedInNextSync) { fHasPendingChanges=true; #ifdef NUMERIC_LOCALIDS // assumes that valid local IDs are positive // and can hold values in the range of -1 to -RAND_MAX-1 localid_t fakelocalid = -(rand() & 0x7FFFFFFF) - 1; #else char fakelocalid[STRING_LOCALID_MAXLEN]; static unsigned int fakeidcounter; sprintf(fakelocalid, "fake-%u-%d", ++fakeidcounter, rand()); #endif // Checking for collisions with other fake IDs would be nice, // but isn't easy because new entries in fChangeLog are not // in memory. We have to trust the random number generator // and the sequence counter (for string IDs). memset(&newentry, 0, sizeof(newentry)); ASSIGN_LOCALID_TO_FLD(newentry.dbrecordid,fakelocalid); ASSIGN_LOCALID_TO_ITEM(*aItemP,fakelocalid); newentry.flags = chgl_deleted; // send during next sync newentry.modcount_created = newentry.modcount = fCurrentModCount+1; #ifdef NUMERIC_LOCALIDS DEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI+DBG_EXOTIC,( "fake new entry %ld : localID=%ld, flags=0x%X, modcount=modcount_created=%ld, new dataCRC=0x%hX", (long)fChangeLog.getNumRecords(), newentry.dbrecordid, (int)newentry.flags, (long)newentry.modcount, newentry.dataCRC )); #else DEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI+DBG_EXOTIC,( "fake new entry %ld : localID='%s', flags=0x%X, modcount=modcount_created=%ld, new dataCRC=0x%hX", (long)fChangeLog.getNumRecords(), newentry.dbrecordid, (int)newentry.flags, (long)newentry.modcount, newentry.dataCRC )); #endif fChangeLog.newRecord(&newentry); } // done ok=true; goto done; } SYSYNC_CATCH (exception &e) statuscode=500; DEBUGPRINTFX(DBG_ERROR,("******** Exception in TBinfileImplDS::ProcessItem: %s (status=%ld)",e.what(), (long)statuscode)); ok=false; goto done; SYSYNC_ENDCATCH SYSYNC_CATCH (...) DEBUGPRINTFX(DBG_ERROR,("******** Exception in TBinfileImplDS::ProcessItem")); statuscode=500; ok=false; goto done; SYSYNC_ENDCATCH error: // report OS specific error codes as item text back to the originator ok=false; PDEBUGPRINTFX(DBG_ERROR,("Database Error --> SyncML status %ld%s",(long)statuscode,lastDBErrorText().c_str())); //aStatusCommand.addItemString(lastDBErrorDbgText().c_str()); done: delete augmentedItemP; aStatusCommand.setStatusCode(statuscode); return ok; } // TBinfileImplDS::implProcessItem // called to confirm a sync operation's completion (status from remote received) // @note aSyncOp passed not necessarily reflects what was sent to remote, but what actually happened void TBinfileImplDS::dsConfirmItemOp(TSyncOperation aSyncOp, cAppCharP aLocalID, cAppCharP aRemoteID, bool aSuccess, localstatus aErrorStatus) { if (binfileDSActive()) { // Nothing to do here, even successful deletes must not delete changelog entry (this will be done // by changeLogPostFlight() for those enties that have been reported as deleted in all profiles!) } // - let inherited know as well inherited::dsConfirmItemOp(aSyncOp, aLocalID, aRemoteID, aSuccess, aErrorStatus); } // TBinfileImplDS::confirmItemOp // - save status information required to possibly perform a resume (as passed to datastore with // implMarkOnlyUngeneratedForResume() and implMarkItemForResume()) // (or, in case the session is really complete, make sure that no resume state is left) localstatus TBinfileImplDS::implSaveResumeMarks(void) { if (!binfileDSActive()) return LOCERR_WRONGUSAGE; // must be active when called at all // update modcount reference of last suspend fPreviousSuspendModCount = fCurrentModCount; // save admin data now return SaveAdminData(true,false); // end of session, but not successful } // TBinfileImplDS::implSaveResumeMarks // log datastore sync result // - Called at end of sync with this datastore void TBinfileImplDS::dsLogSyncResult(void) { // Note: binfile logs can be active even if binfiles layer otherwise is not active TBinfileClientConfig *clientCfgP = static_cast(fSessionP->getSessionConfig()); if (clientCfgP->fBinFileLog) { // writing binfile logs enabled TBinFile logFile; // Open logfile // - get base path string filepath; clientCfgP->getBinFilesPath(filepath); filepath += LOGFILE_DB_NAME; // - open or create logFile.setFileInfo(filepath.c_str(),LOGFILE_DB_VERSION,LOGFILE_DB_ID,sizeof(TLogFileEntry)); if (logFile.open(0,NULL,NULL)!=BFE_OK) { // create new one or overwrite incompatible one logFile.create(sizeof(TLogFileEntry),0,NULL,true); } // append new record // - create record TLogFileEntry logInfo; logInfo.time = fCurrentSyncTime; // current sync's time logInfo.status = getAbortStatusCode(); // reason for abort (0 if ok) logInfo.mode = (fSlowSync ? (fFirstTimeSync ? 2 : 1) : 0) + (fResuming ? 10 : 0); logInfo.dirmode = fSyncMode; // sync direction mode logInfo.infoID = 0; // none logInfo.dbID = fConfigP->fLocalDBTypeID; // ID of DB (to allow fetching name) logInfo.profileID = static_cast(fSessionP)->fRemotepartyID; // ID of profile (to allow fetching name) logInfo.locAdded = fLocalItemsAdded; logInfo.locUpdated = fLocalItemsUpdated; logInfo.locDeleted = fLocalItemsDeleted; logInfo.remAdded = fRemoteItemsAdded; logInfo.remUpdated = fRemoteItemsUpdated; logInfo.remDeleted = fRemoteItemsDeleted; logInfo.inBytes = fIncomingDataBytes; logInfo.outBytes = fOutgoingDataBytes; logInfo.locRejected = fLocalItemsError; logInfo.remRejected = fRemoteItemsError; // - save it logFile.newRecord(&logInfo); // close the logfile again logFile.close(); } } // TBinfileImplDS::dsLogSyncResult // save end of session state // Note that in BASED_ON_BINFILE_CLIENT case, this is derived in customimplds and will // be called by the derivate after doing customimpl specific stuff. localstatus TBinfileImplDS::implSaveEndOfSession(bool aUpdateAnchors) { if (!binfileDSActive()) return LOCERR_WRONGUSAGE; // must be active when called at all // update TCustomImplDS dsSavedAdmin variables (other levels have already updated their variables if (aUpdateAnchors) { if (!fRefreshOnly || fSlowSync) { // This was really a two-way sync or we implicitly know that // we are now in sync with remote (like after one-way-from-remote refresh = reload local) fPreviousToRemoteModCount = fCurrentModCount; } // updating anchor means invalidating last Suspend fPreviousSuspendCmpRef = fPreviousToRemoteSyncCmpRef; // setting to current reference can do less harm than setting it to zero fPreviousSuspendModCount=0; } // save admin data now localstatus sta=SaveAdminData(true,aUpdateAnchors); // end of session if (sta==LOCERR_OK) { // finalize admin data stuff now uInt32 oldestmodcount=0xFFFFFFFF; // do a postFlight to remove unused entries from the changelog if (static_cast(fSessionP->getSessionConfig())->fSeparateChangelogs) { // Each profile has it's own changelog, so just delete entries that are older than this profile's last sync or resume if (fTarget.lastSuspendModCount!=0) oldestmodcount = fTarget.lastSuspendModCount; if (fTarget.lastTwoWayModCount!=0 && fTarget.lastTwoWayModCount(fSessionP)->fConfigP->fTargetsBinFile); uInt32 maxidx = targetsBinFileP->getNumRecords(); uInt32 idx; TBinfileDBSyncTarget target; for (idx=0; idxreadRecord(idx,&target); if ( // Note: %%% this is same mechanism as for changelog filenames // Not ok if multiple databases go with the same datastore.getName() strucmp(target.dbname,getName())==0 ) { // target for this database found, check if modcount is older if (target.lastSuspendModCount!=0 && target.lastSuspendModCountfCmpRefTimeStampAtEnd) { fChgLogHeader.lastChangeCheck = getSession()->getSystemNowAs(TCTX_UTC); // NOW ! (again); } fChangeLog.setExtraHeaderDirty(); fChangeLog.flushHeader(); // save other admin data TBinFile *targetsBinFileP = &(static_cast(fSessionP)->fConfigP->fTargetsBinFile); // update target fields // - update anchor AssignCString(fTarget.remoteAnchor,fLastRemoteAnchor.c_str(),remoteAnchorMaxLen); PDEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI,("SaveAdminData: saving remote anchor = '%s'",fLastRemoteAnchor.c_str())); // - update this sync time (last sync field in DB) and modcount fTarget.lastSync=fPreviousSyncTime; fTarget.lastTwoWayModCount=fPreviousToRemoteModCount; // Note: compare times and identifiers are not needed any more (these are now in the changelog), // But we assigne some for dbg purposes. // - update the last changelog check time. fTarget.lastChangeCheck=fPreviousToRemoteSyncCmpRef; #if TARGETS_DB_VERSION>=6 // - identifiers (tokens for StartDataRead) PDEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI+DBG_EXOTIC,("SaveAdminData: saving target sync token %s", fPreviousToRemoteSyncIdentifier.c_str())); AssignCString(fTarget.dummyIdentifier1,fPreviousToRemoteSyncIdentifier.c_str(),remoteAnchorMaxLen); // former lastSyncIdentifier AssignCString(fTarget.dummyIdentifier2,NULL,remoteAnchorMaxLen); // former lastSuspendIdentifier, not needed, make empty // store remote datastore's display name (is empty if we haven't got one from the remote via devInf) if (getRemoteDatastore()) { AssignCString(fTarget.remoteDBdispName,getRemoteDatastore()->getDisplayName(),dispNameMaxLen); } #endif // check for other target record updates needed at end of session if (aSessionFinished && aSuccessful) { // - reset mode back to normal, that is after a forced reload of client OR server // we assume that two-way sync will be what we want next. if (fTarget.forceSlowSync) { fTarget.syncmode = smo_twoway; } fTarget.forceSlowSync=false; } // special operations needed depending on suspend state fTarget.resumeAlertCode=fResumeAlertCode; if (fResumeAlertCode==0) { fTarget.lastSuspendModCount = 0; } else { /// @note: lastSuspendModCount is the same target field that previously was called "lastModCount" fTarget.lastSuspendModCount = fPreviousSuspendModCount; if (!static_cast(fSessionP->getSessionConfig())->fSeparateChangelogs) { // Combined changelogs: make sure that resume alert codes of all other profile's targets for this datastore are erased // (because in a single changelog there is only one set of markforresume flags and single pendingmap+pendingitem files) TBinfileDBSyncTarget otherTarget; memset(&otherTarget, 0, sizeof(otherTarget)); for (sInt32 ti=0; tigetNumRecords()); ti++) { if (ti!=fTargetIndex) { // get that target targetsBinFileP->readRecord(ti,&otherTarget); if ( (otherTarget.localDBTypeID == fTarget.localDBTypeID) && // same datastoreID (strucmp(otherTarget.localDBPath,fTarget.localDBPath)==0) && // ..and name (otherTarget.resumeAlertCode!=0) // ..and has a saved suspend state ) { // same datastore, but different profile is also suspended -> new suspend cancels old one DEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI+DBG_EXOTIC,("SaveAdminData: cancelled resumeAlertCode in profile=%ld",(long)otherTarget.remotepartyID)); otherTarget.resumeAlertCode=0; otherTarget.lastSuspendModCount=0; targetsBinFileP->updateRecord(ti,&otherTarget); } } } } } PDEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI,("SaveAdminData: lastTwoWayModCount = %ld, lastSuspendModCount = %ld", (long)fPreviousToRemoteModCount, (long)fPreviousSuspendModCount)); // save pending maps (anyway, even if not suspended) openPendingMaps(); // make sure we have the pendingmap file open now fPendingMaps.truncate(0); // delete current contents TStringToStringMap::iterator spos; TPendingMapEntry pme; localid_t localid; // - pending maps now belong to us! // Note: they always do with separated changelogs fPendingMapHeader.remotepartyID = static_cast(fSessionP)->fRemotepartyID; fPendingMaps.setExtraHeaderDirty(); // - now pending maps (unsent ones) DEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI+DBG_DETAILS,("SaveAdminData: saving %ld entries from fPendingAddMaps to fPendingMaps binfile",(long)fPendingAddMaps.size())); for (spos=fPendingAddMaps.begin();spos!=fPendingAddMaps.end();spos++) { string locID = (*spos).first; dsFinalizeLocalID(locID); // pending maps might have non-final ID, so give datastore implementation to return finalized version STR_TO_LOCALID(locID.c_str(),localid); ASSIGN_LOCALID_TO_FLD(pme.dbrecordid,localid); AssignCString(pme.remoteID,(*spos).second.c_str(),BINFILE_MAXGUIDSIZE+1); fPendingMaps.newRecord(&pme); } // - now pending maps (sent, but not seen status yet) DEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI+DBG_DETAILS,("SaveAdminData: saving %ld entries from fUnconfirmedMaps to fPendingMaps binfile",(long)fUnconfirmedMaps.size())); for (spos=fUnconfirmedMaps.begin();spos!=fUnconfirmedMaps.end();spos++) { STR_TO_LOCALID((*spos).first.c_str(),localid); ASSIGN_LOCALID_TO_FLD(pme.dbrecordid,localid); AssignCString(pme.remoteID,(*spos).second.c_str(),BINFILE_MAXGUIDSIZE+1); fPendingMaps.newRecord(&pme); } // - save them fPendingMaps.close(); // Save last item info and possibly partial item data TPendingItemHeader pendingItemHeader; memset((void*)&pendingItemHeader,0,sizeof(pendingItemHeader)); // make nicely empty by default bool saveit=false; // - profile ID where this pending item belongs to pendingItemHeader.remotepartyID = static_cast(fSessionP)->fRemotepartyID; // determine if and what to save if (fPartialItemState==pi_state_none) { pendingItemHeader.piState = pi_state_none; pendingItemHeader.storedSize=0; // no data to store saveit=true; } else if (fPartialItemState==pi_state_save_incoming || fPartialItemState==pi_state_save_outgoing) { // - last item info pendingItemHeader.lastItemStatus = fLastItemStatus; AssignCString(pendingItemHeader.lastSourceURI,fLastSourceURI.c_str(),BINFILE_MAXGUIDSIZE+1); AssignCString(pendingItemHeader.lastTargetURI,fLastTargetURI.c_str(),BINFILE_MAXGUIDSIZE+1); // - partial item info pendingItemHeader.totalSize = fPITotalSize; pendingItemHeader.unconfirmedSize = fPIUnconfirmedSize; if (fPartialItemState==pi_state_save_incoming) { // store incoming pendingItemHeader.piState = pi_state_loaded_incoming; pendingItemHeader.storedSize=fPIStoredSize; } else if (fPartialItemState==pi_state_save_outgoing) { // store outgoing pendingItemHeader.piState = pi_state_loaded_outgoing; pendingItemHeader.storedSize=fPIStoredSize; } else pendingItemHeader.storedSize=0; // nothing to store saveit=true; } if (saveit) { TBinFile pendingItemFile; string fname = static_cast(fSessionP->getSessionConfig())->relatedDBNameBase(getName(), fTarget.remotepartyID); fname += PENDINGITEM_DB_SUFFIX; pendingItemFile.setFileInfo(fname.c_str(),PENDINGITEM_DB_VERSION,PENDINGITEM_DB_ID,0); PDEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI+DBG_EXOTIC,( "SaveAdminData: creating pending item file: file name='%s', storing %ld bytes", fname.c_str(), (long)pendingItemHeader.storedSize )); PDEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI+DBG_DETAILS,( "SaveAdminData: saved pending item: src='%s', targ='%s', laststatus=%hd, pistate=%d, total=%ld, unconfirmed=%ld, stored=%ld", pendingItemHeader.lastSourceURI, pendingItemHeader.lastTargetURI, pendingItemHeader.lastItemStatus, pendingItemHeader.piState, (long)pendingItemHeader.totalSize, (long)pendingItemHeader.unconfirmedSize, (long)pendingItemHeader.storedSize )); bferr bfe=pendingItemFile.create( pendingItemHeader.storedSize, // record size = size of data chunk to be buffered sizeof(TPendingItemHeader), // extra header size &pendingItemHeader, // extra header data true // overwrite existing ); if (bfe==BFE_OK) { // created successfully, store data if any if (pendingItemHeader.storedSize && fPIStoredDataP) { // we have data to store uInt32 newIndex; bfe=pendingItemFile.newRecord(newIndex,fPIStoredDataP); } // close file pendingItemFile.close(); } if (bfe!=BFE_OK) { PDEBUGPRINTFX(DBG_ERROR,("Error writing pending item file, bferr=%hd",bfe)); } } PDEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI+DBG_DETAILS,("SaveAdminData: fTargetIndex %d resumeAlertCode = %hd, lastSuspendModCount = %ld",fTargetIndex,fResumeAlertCode,(long)fTarget.lastSuspendModCount)); // update the target record if (fTargetIndex>=0) { targetsBinFileP->updateRecord(fTargetIndex,&fTarget); fTargetIndex=-1; // invalid now } PDEBUGENDBLOCK("SaveAdminData"); // ok return LOCERR_OK; } // TBinfileImplDS::SaveAdminData /* end of TBinfileImplDS implementation */ } // namespace sysync // eof libsynthesis-3.4.0.47.1/src/sysync/binfileimplds.h000077500000000000000000001127311226375725500217650ustar00rootroot00000000000000/** * @File binfileimplds.h * * @Author Lukas Zeller (luz@plan44.ch) * * @brief TBinfileImplDS * Represents a client datastore implementation which has target management * (and optionally change log) based on binary files * * Copyright (c) 2003-2011 by Synthesis AG + plan44.ch * * @Date 2005-09-30 : luz : created from TBinfileImplDS */ /* */ #ifndef BINFILEIMPLDS_H #define BINFILEIMPLDS_H // includes #include "binfile.h" // platform specific header (using binfilebase) #include "stdlogicds.h" #include "multifielditem.h" // defines that allow using the generic method implementations // for provisioning and autosync #define CLIENTAGENTCONFIG TBinfileClientConfig #define CLIENTDSCONFIG TBinfileDSConfig #define PROFILERECORD TBinfileDBSyncProfile #define TARGETRECORD TBinfileDBSyncTarget #include "clientprovisioning_inc.h" #include "clientautosync_inc.h" namespace sysync { // Defines // ======= #ifndef ANDROID #pragma pack(push,4) // 32bit #endif // specific sync const uInt16 dbnamelen=32; // Local IDs // ========= // local ID typedefs and Macros #ifdef NUMERIC_LOCALIDS // numeric local IDs typedef NUMERIC_LOCALIDS localid_t; typedef localid_t localid_out_t; #define LOCALID_EQUAL(a,b) (a==b) #if NUMERIC_LOCALID_SZ==2 #define STR_TO_LOCALID(s,i) StrToUShort(s,i) #elif NUMERIC_LOCALID_SZ==4 #define STR_TO_LOCALID(s,i) StrToULong(s,i) #elif NUMERIC_LOCALID_SZ==8 #define STR_TO_LOCALID(s,i) StrToULongLong(s,i) #else #error "unknown size of numeric local ID" #endif #define ASSIGN_LOCALID_TO_FLD(a,b) (a=b) #define LOCALID_OUT_TO_IN(out) out #if NUMERIC_LOCALID_SZ<=4 #define LOCALID_TO_STRING(i,s) { StringObjPrintf(s,"%lu",(uInt32)i); } #else #define LOCALID_TO_STRING(i,s) { StringObjPrintf(s,"%llu",(uInt64)i); } #endif #define ASSIGN_LOCALID_TO_ITEM(it,i) { string s; LOCALID_TO_STRING(i,s); (it).setLocalID(s.c_str()); } #else // string local IDs const uInt16 maxidlen = STRING_LOCALID_MAXLEN; typedef char *localid_t; typedef string localid_out_t; #define LOCALID_EQUAL(a,b) (strnncmp(a,b,maxidlen)==0) #define STR_TO_LOCALID(s,i) (i=(char *)s) #define LOCALID_TO_STRING(i,s) s=i #define ASSIGN_LOCALID_TO_FLD(a,b) AssignCString(a,b,maxidlen) #define LOCALID_OUT_TO_IN(out) ((char *)out.c_str()) #define ASSIGN_LOCALID_TO_ITEM(it,i) (it).setLocalID(i) #endif // User log // ======== // Note: Engine 3.1.5.1 and later have the fBinFileLog which can be turned on to have binfileds // write the log records automatically. With ENGINEINTERFACE_SUPPORT, the /synclogs // settingskey can be used to access the log records. // In 3.0 clients, implementation of filling and displaying the log binfile is platform dependent // simply using this typedef to have a common format. #ifdef SETTINGS_BFI_PREFIX // custom settings name prefix #define LOGFILE_DB_NAME SETTINGS_BFI_PREFIX "log.bfi" #else #define LOGFILE_DB_NAME "sysylog.bfi" #endif #define LOGFILE_DB_ID 8 #define LOGFILE_DB_VERSION 3 typedef struct { lineartime_t time; ///< timestamp for this log entry uInt32 dbID; ///< the datastore involved uInt32 profileID; ///< id of the profile localstatus status; uInt16 mode; ///< sync mode: 0=normal, 1=slow, 2=first time, +10 = resumed sInt32 infoID; ///< ressource id of text describing error (only valid with platform-specific log file filling, not available via /synclogs) uInt32 locAdded; uInt32 locUpdated; uInt32 locDeleted; uInt32 remAdded; uInt32 remUpdated; uInt32 remDeleted; uInt32 inBytes; uInt32 outBytes; // V2 fields start here uInt32 locRejected; uInt32 remRejected; // V3 fields start here uInt16 dirmode; /// 4 // unite desktop and mobile client // - container name / entryID char localContainerName[localDBpathMaxLen]; #endif #if !defined(DESKTOP_CLIENT) && TARGETS_DB_VERSION>4 #error "Make sure to unite desktop and mobile versions - desktop already is version 5. Note that localDBpathMaxLen is shorter in mobile; check if 128 is really needed for desktop!" #endif // Version 6 fields start here // =========================== #if TARGETS_DB_VERSION>5 // storage for non-time sync identifiers in case DB on top is customImplDS char dummyIdentifier1[remoteAnchorMaxLen]; // (formerly lastSyncIdentifier) not used any more - single identifier in changelog is sufficient char dummyIdentifier2[remoteAnchorMaxLen]; // (formerly lastSuspendIdentifier) not used any more - single identifier in changelog is sufficient // remote datastore info (retrieved from devInf, if possible) char remoteDBdispName[dispNameMaxLen]; // display name of remote datastore char filterCapDesc[filterCapDescMaxLen]; // description string of remote filter capabilities // remote filter expression (in internal format) char remoteFilters[filterExprMaxLen]; // local (client side) filter expression (in internal format) char localFilters[filterExprMaxLen]; #endif // TARGETS_DB_VERSION > 5 // Version 7 fields %%%will%%% start here // =========================== #if TARGETS_DB_VERSION>6 #error "target versions > 6 not yet supported! - please check TARGETS_DB_VERSION" #endif // TARGETS_DB_VERSION > 6 } TBinfileDBSyncTarget; #define TARGETS_DB_VERSION_4_SZ sizeof(TBinfileDBSyncTarget) #define TARGETS_DB_VERSION_3_SZ offsetof(TBinfileDBSyncTarget,resumeAlertCode) // Sync Profile database // ===================== #ifdef SETTINGS_BFI_PREFIX // custom settings name prefix #define PROFILE_DB_NAME SETTINGS_BFI_PREFIX "prof.bfi" #else #define PROFILE_DB_NAME "sysyprof.bfi" #endif #ifndef ENHANCED_PROFILES_2004 #error "non-enhanced profiles and profile version <6 no longer supported!" #endif #define PROFILE_DB_ID 2 #define PROFILE_DB_VERSION 9 // lowest profile DB version still supported for automatic upgrading #define LOWEST_PROFILE_DB_VERSION 4 // read-only flags const uInt8 rdonly_URI = 0x01; // server URI const uInt8 rdonly_URIpath = 0x02; // URI path suffix const uInt8 rdonly_protocol = 0x04; // protocol (transport http/https flag as well as SyncML version) const uInt8 rdonly_dbpath = 0x08; // DB path names const uInt8 rdonly_profile = 0x10; // profile may not be deleted or renamed (but non-readonly options can be set) const uInt8 rdonly_proxy = 0x20; // proxy settings (except proxy auth settings). // - Bit 6+7 reserved // feature flags const uInt8 ftrflg_autosync = 0x01; // autosync enabled const uInt8 ftrflg_dmu = 0x02; // DMU enabled const uInt8 ftrflg_range = 0x04; // Range filtering enabled (APP_FTR_EVENTRANGE etc...) // datastore availability flags const uInt16 dsavail_all = 0xFFFF; // all implemented datastores const uInt16 dsavail_contacts = 0x0001; // contacts const uInt16 dsavail_events = 0x0002; // events const uInt16 dsavail_tasks = 0x0004; // tasks const uInt16 dsavail_memos = 0x0008; // notes/memos const uInt16 dsavail_emails = 0x0010; // emails // remote-specifics flags const uInt8 remotespecs_devidWithUserHash = 0x01; // device ID must always include the user name const uInt8 remotespecs_noXTypeParams = 0x02; // vCard should not contain any X-Synthesis-RefX and other X-hhh type tags const uInt8 remotespecs_noDS12Filters = 0x04; // we should not use DS 1.2 SINCE/BEFORE filters // - Bit 3..7 reserved // field sizes const uInt16 maxurisiz=128; const uInt16 maxupwsiz=64; const uInt16 maxnamesiz=42; const uInt16 maxnoncesiz=64; const uInt16 maxpathsiz=64; const uInt16 profiledatasiz=256; typedef enum { transp_proto_uri, // protocol included in URI transp_proto_http, // HTTP protocol transp_proto_https, // HTTPS protocol transp_proto_wsp, // WSP protocol transp_proto_obex_irda, // OBEX/IRDA protocol transp_proto_obex_bt, // OBEX/BT protocol transp_proto_obex_tcp, // OBEX/TCP protocol num_transp_protos // number of protocols } TTransportProtocols; // NOTE!!!: changing number of levels implies a change of PROFILE_DB_VERSION!! #define NUM_AUTOSYNC_LEVELS 3 // we provide 3 levels of autosync typedef struct { // Unique ID uInt32 profileID; // internal unique ID of the profile (selects targets by their remotepartyID) // PROFILE_DB_VERSION <=4 settings char profileName[maxnamesiz]; // - encoding (note that release client might not allow XML) SmlEncoding_t encoding; // - Old-style Server URI, misused for several other things // Note: for hard-coded server URI, this is also misused as companyID or secure flag: // - ONE_e2g: serverURI = companyID // - SCM: serverURI[0] = secure flag (HTTPS) char serverURI[maxurisiz]; // - User name char serverUser[maxupwsiz]; // - password char serverPassword[maxupwsiz]; // - Transport user char transportUser[maxupwsiz]; // - Transport password char transportPassword[maxupwsiz]; // - Socks Host char socksHost[maxurisiz]; // - Proxy Host char proxyHost[maxurisiz]; // Internals // - session ID uInt8 sessionID; // - last connection's parameters (used as default for next session) TSyncMLVersions lastSyncMLVersion; TAuthTypes lastAuthMethod; TFmtTypes lastAuthFormat; char lastNonce[maxnoncesiz]; // - for registration checking lineardate_t firstuse; // copy of a global setting, so we can compare and see if someone has tampered with // Additional PROFILE_DB_VERSION 5 settings // - Enhanced server addressing // - possibly some path extension char URIpath[maxpathsiz]; // - protocol selector (0=free-form from URI, 1..n = reserved for fixed protocols) TTransportProtocols protocol; // - read-only flags (rdonly_xxx) uInt8 readOnlyFlags; // - flags for special remote-specific behaviour (remotespecs_XXX) - was reserved until 2.5.0.68 / 2.9.8.10. uInt8 remoteFlags; // - profile feature flags (ftrflg_xxx) uInt8 featureFlags; // - Local Database profile name char localDBProfileName[localDBpathMaxLen]; // - Proxy usage options bool useProxy; // use configured proxies bool useConnectionProxy; // using proxy from current connection, if available // - Auto-Sync levels (3 levels, first match overrides lower level settings) TAutoSyncLevel AutoSyncLevel[NUM_AUTOSYNC_LEVELS]; // - Datastore available flags (for clients with variable datastores) uInt16 dsAvailFlags; // dsavail_xxx flags // - Timed sync settings uInt16 TimedSyncMobilePeriod; // [min] how often to sync when mobile (battery, wireless) uInt16 TimedSyncCradledPeriod; // [min] how often to sync when cradled (ac powered, wired) // - IPP settings (not available in all clients, but present in all profile records TIPPSettings ippSettings; // Additional PROFILE_DB_VERSION 8 settings // - Proxy user char proxyUser[maxupwsiz]; // - Proxy password char proxyPassword[maxupwsiz]; // Additional PROFILE_DB_VERSION 9 settings // - transport related profile flags uInt32 transpFlags; // - general profile flags uInt32 profileFlags; // - general profile ints uInt32 profileExtra1; uInt32 profileExtra2; // - general purpose profile data (intended for SDK based app's usage) uInt8 profileData[profiledatasiz]; } TBinfileDBSyncProfile; #define PROFILE_DB_VERSION_7_SZ offsetof(TBinfileDBSyncProfile,proxyUser) #define PROFILE_DB_VERSION_8_SZ offsetof(TBinfileDBSyncProfile,transpFlags) #if LOWEST_PROFILE_DB_VERSION<6 // old structs and consts used to access fields of profiles older than PROFILE_DB_VERSION 6 const uInt16 o_maxurisiz=128; const uInt16 o_maxupwsiz=32; const uInt16 o_maxnamesiz=42; const uInt16 o_maxnoncesiz=64; const uInt16 o_maxpathsiz=64; typedef struct { char srv[maxipppathsiz]; uInt16 port; uInt16 period; char path[maxipppathsiz]; char id[maxippidsiz]; uInt8 method; } o_TIPPSettings; typedef struct { // Unique ID uInt32 profileID; // internal unique ID of the profile (selects targets by their remotepartyID) // PROFILE_DB_VERSION <=4 settings char profileName[o_maxnamesiz]; // - encoding (note that release client might not allow XML) SmlEncoding_t encoding; // - Old-style Server URI, misused for several other things // Note: for hard-coded server URI, this is also misused as companyID or secure flag: // - ONE_e2g: serverURI = companyID // - SCM: serverURI[0] = secure flag (HTTPS) char serverURI[o_maxurisiz]; // - User name char serverUser[o_maxupwsiz]; // - password char serverPassword[o_maxupwsiz]; // - Transport user char transportUser[o_maxupwsiz]; // - Transport password char transportPassword[o_maxupwsiz]; // - Socks Host char socksHost[o_maxurisiz]; // - Proxy Host char proxyHost[o_maxurisiz]; // Internals // - session ID uInt8 sessionID; // - last connection's parameters (used as default for next session) TSyncMLVersions lastSyncMLVersion; TAuthTypes lastAuthMethod; TFmtTypes lastAuthFormat; char lastNonce[o_maxnoncesiz]; // - for registration checking lineardate_t firstuse; // copy of a global setting, so we can compare and see if someone has tampered with // Additional PROFILE_DB_VERSION 5 settings // - Enhanced server addressing // - possibly some path extension char URIpath[o_maxpathsiz]; // - protocol selector (0=free-form from URI, 1..n = reserved for fixed protocols) TTransportProtocols protocol; // - read-only flags (Bit 0=URI, 1=URIpath, 2=protocol, 3..7 reserved) uInt8 readOnlyFlags; // - 2 bytes reserved for future use uInt16 reserved1; // - Local Database profile name char localDBProfileName[localDBpathMaxLen]; // - Proxy usage options bool useProxy; // use configured proxies bool useConnectionProxy; // using proxy from current connection, if available // - Auto-Sync levels (3 levels, first match overrides lower level settings) TAutoSyncLevel AutoSyncLevel[NUM_AUTOSYNC_LEVELS]; // - reserved uInt8 reserved2; // reserved uInt8 reserved3; // reserved // - Timed sync settings uInt16 TimedSyncMobilePeriod; // [min] how often to sync when mobile (battery, wireless) uInt16 TimedSyncCradledPeriod; // [min] how often to sync when cradled (ac powered, wired) // - IPP settings (not available in all clients, but present in all profile records o_TIPPSettings ippSettings; } o_TBinfileDBSyncProfile; #endif // versioned record sizes #define PROFILE_DB_VERSION_5_SZ sizeof(o_TBinfileDBSyncProfile) #define PROFILE_DB_VERSION_4_SZ offsetof(o_TBinfileDBSyncProfile,URIpath) #ifndef ANDROID #pragma pack(pop) #endif #ifndef CHANGEDETECTION_AVAILABLE #define CRC_CHANGE_DETECTION true #define CRC_DETECT_PSEUDOCHANGES false #else #define CRC_CHANGE_DETECTION (fConfigP->fCRCChangeDetection) #define CRC_DETECT_PSEUDOCHANGES (fConfigP->fCRCPseudoChangeDetection) #endif // datastore config // ================ #ifdef SCRIPT_SUPPORT // publish func table for chaining extern const TFuncTable BinfileClientDBFuncTable; #endif // SCRIPT_SUPPORT class TBinfileDSConfig: public TLocalDSConfig { typedef TLocalDSConfig inherited; public: TBinfileDSConfig(const char* aName, TConfigElement *aParentElement); virtual ~TBinfileDSConfig(); // properties // - activtion switch (for making it inactive e.g. in server case) bool fBinfileDSActive; #ifdef CHANGEDETECTION_AVAILABLE // - we have change detection, but we can be set to enable change detection by CRC, // or verifying DB reported changes by CRC to avoid pseudo-changes (only touched, but not modified records). bool fCRCChangeDetection; bool fCRCPseudoChangeDetection; #endif // - identifies local Database related to this datastore string fLocalDBPath; // - flag that corresponds with profile.dsAvailFlags / dsavail_xxx uInt16 fDSAvailFlag; // - if set, the compare reference time for changelog updates is set to end-of-session time // Note: before 3.2.0.32, this was hardcoded via SYNCTIME_IS_ENDOFSESSION. Now SYNCTIME_IS_ENDOFSESSION // only defines the default value for this setting bool fCmpRefTimeStampAtEnd; // public methods // - init a default target for this datastore virtual void initTarget( TBinfileDBSyncTarget &aTarget, // target record to initialize uInt32 aRemotepartyID, const char *aRemoteName=NULL, // defaults to name of datastore bool aEnabled=false // enabled? ); // - checks if datastore is available for given profile. If aProfileP is NULL, // general availability is checked (profile might allow more or less) bool isAvailable(TBinfileDBSyncProfile *aProfileP); // - one-way support is always given for binfile based DS virtual bool isOneWayFromRemoteSupported() { return true; } #ifdef SCRIPT_SUPPORT // function table virtual const TFuncTable *getClientDBFuncTable(void) { return &BinfileClientDBFuncTable; }; #endif // SCRIPT_SUPPORT protected: // check config elements #ifndef HARDCODED_CONFIG virtual bool localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine); #endif virtual void clear(); virtual void localResolve(bool aLastPass); // Autosync declarations CLIENTAUTOSYNC_CLASSDECL_DB }; // TBinfileDSConfig class TBinfileImplDS: public TStdLogicDS { typedef TStdLogicDS inherited; private: void InternalResetDataStore(void); // reset for re-use without re-creation protected: /// @name dsSavedAdmin administrative data (anchors, timestamps, maps) as saved or to-be-saved /// @Note These will be loaded and saved be derived classes /// @Note Some of these will be updated from resp. @ref dsCurrentAdmin members at distinct events (suspend, session end, etc.) /// @Note Some of these will be updated during the session, but in a way that does NOT affect the anchoring of current/last session // /// @{ /// Reference time of previous changelog update (preflight) /// @note the name of the variable indicates "previous to remote sync" time because in BASED_ON_BINFILE_CLIENT case where // TCustomImplDS sits on top of binfile, it expects that instance var name (because in non binfile-based cases, // that is in fact the "previous to remote sync" date. With the intermediate binfile changelog however, only // changes since last preflight (changelog update) need to be reported. lineartime_t fPreviousToRemoteSyncCmpRef; /// Reference string used by database API level (in BASED_ON_BINFILE_CLIENT case) to detect changes string fPreviousToRemoteSyncIdentifier; /// modification count of last sync target's modifications uInt32 fPreviousToRemoteModCount; /// Reference time of last suspend, needed to detect modifications that took place between last suspend and current resume lineartime_t fPreviousSuspendCmpRef; /// Reference string used by database API level (in BASED_ON_BINFILE_CLIENT case) to detect changes after last suspend string fPreviousSuspendIdentifier; /// modification count used to determine modifications since last to-remote-sync uInt32 fPreviousSuspendModCount; /// @} /// @name dsCurrentAdmin current session's admin data (anchors, timestamps, maps) /// @Note These will be copied to @ref dsSavedAdmin members ONLY when a session completes successfully/suspends. /// @Note Admin data is NEVER directly saved or loaded from these /// @Note Derivates will update some of these at dssta_adminready with current time/anchor values // /// @{ /// Reference time of current sync to compare modification dates against /// @note initially==fCurrentSyncTime, but might be set to end-of-session time for databases which cannot explicitly set modification timestamps lineartime_t fCurrentSyncCmpRef; /// modification count identifying this session's time (for detecting changes taking place after this session) uInt32 fCurrentModCount; /// Reference string returned by database API level identifying this session's time (for detecting changes taking place after this session) string fCurrentSyncIdentifier; /// @} public: TBinfileImplDS( TBinfileDSConfig *aConfigP, sysync::TSyncSession *aSessionP, const char *aName, uInt32 aCommonSyncCapMask=0); virtual ~TBinfileImplDS(); virtual void announceAgentDestruction(void) { /** @todo nop for now */ }; virtual void dsResetDataStore(void); // - called from TBinFileDBAgent::SelectProfile(), should return false if local datastore is not accessible virtual bool localDatastorePrep(void) { return true; } // - set Sync Parameters. Derivate adds CGI to aRemoteDBPath virtual bool dsSetClientSyncParams( TSyncModes aSyncMode, bool aSlowSync, const char *aRemoteDBPath, const char *aDBUser = NULL, const char *aDBPassword = NULL, const char *aLocalPathExtension = NULL, const char *aRecordFilterQuery = NULL, bool aFilterInclusive = false ); // Target vars sInt32 fTargetIndex; TBinfileDBSyncTarget fTarget; protected: /// called for SyncML 1.1 if remote wants number of changes. /// Must return -1 no NOC value can be returned virtual sInt32 getNumberOfChanges(void); /// checks change log for already known changes virtual bool hasPendingChangesForNextSync(); // Simple custom DB access interface methods /// sync login (into this database) /// @note might be called several times (auth retries at beginning of session) /// @note must update the following state variables /// - in TLocalEngineDS: fLastRemoteAnchor, fLastLocalAnchor, fResumeAlertCode, fFirstTimeSync /// - for client: fPendingAddMaps /// - in TStdLogicDS: fPreviousSyncTime, fCurrentSyncTime /// - in derived classes: whatever else belongs to dsSavedAdmin and dsCurrentAdmin state virtual localstatus implMakeAdminReady( const char *aDeviceID, ///< remote device URI (device ID) const char *aDatabaseID, ///< database ID const char *aRemoteDBID ///< database ID of remote device ); /// start data read /// @note: fSlowSync and fRefreshOnly must be valid before calling this method virtual localstatus implStartDataRead(); /// get item from DB virtual localstatus implGetItem( bool &aEof, bool &aChanged, TSyncItem* &aSyncItemP ); /// end of read virtual localstatus implEndDataRead(void); /// start of write virtual localstatus implStartDataWrite(void); /// review reported entry (allows post-processing such as map deleting) /// MUST be called after implStartDataWrite, before any actual writing, /// for each item obtained in implGetItem virtual localstatus implReviewReadItem( TSyncItem &aItem // the item ) { return true; }; // nop here /// retrieve specified item from database virtual bool implRetrieveItemByID( TSyncItem &aItem, // the item TStatusCommand &aStatusCommand ); /// process item (according to operation: add/delete/replace - and for future: copy/move) virtual bool implProcessItem( TSyncItem *aItemP, // the item TStatusCommand &aStatusCommand ); /// called to mark an already generated (but probably not sent or not yet statused) item /// as "to-be-resumed", by localID or remoteID (latter only in server case). /// @note This must be repeatable without side effects, as server must mark/save suspend state /// after every request (and not just at end of session) virtual void implMarkItemForResume(cAppCharP aLocalID, cAppCharP aRemoteID, bool aUnSent); /// called to mark an already sent item as "to-be-resent", e.g. due to temporary /// error status conditions, by localID or remoteID (latter only in server case). virtual void implMarkItemForResend(cAppCharP aLocalID, cAppCharP aRemoteID); /// called to have all non-yet-generated sync commands as "to-be-resumed" virtual void implMarkOnlyUngeneratedForResume(void); /// save status information required to possibly perform a resume (as passed to datastore with /// markOnlyUngeneratedForResume() and markItemForResume()) /// (or, in case the session is really complete, make sure that no resume state is left) virtual localstatus implSaveResumeMarks(void); /// save end of session state virtual localstatus implSaveEndOfSession(bool aUpdateAnchors); /// end write sequence virtual bool implEndDataWrite(void); public: /// @name dsXXXX virtuals defined by TLocalEngineDS /// These are usually designed such that they should always call inherited::dsXXX to let the entire chain /// of ancestors see the calls /// @{ // /// end of message handling virtual void dsEndOfMessage(void); /// inform logic of coming state change virtual localstatus dsBeforeStateChange(TLocalEngineDSState aOldState,TLocalEngineDSState aNewState); /// inform logic of happened state change virtual localstatus dsAfterStateChange(TLocalEngineDSState aOldState,TLocalEngineDSState aNewState); /// called to confirm a sync operation's completion (ok status from remote received) /// @note aSyncOp passed not necessarily reflects what was sent to remote, but what actually happened virtual void dsConfirmItemOp(TSyncOperation aSyncOp, cAppCharP aLocalID, cAppCharP aRemoteID, bool aSuccess, localstatus aErrorStatus=0); /// returns true if DB implementation supports resume (saving of resume marks, alert code, pending maps) virtual bool dsResumeSupportedInDB(void) { return true; }; // resume supported /// returns true if DB implementation supports resuming in midst of a chunked item (can save fPIxxx.. and related admin data) virtual bool dsResumeChunkedSupportedInDB(void) { return true; }; /// saves user log information about the sync session virtual void dsLogSyncResult(void); /// @} protected: // Routines to be implemented by derived classes to actually access // local databases #ifdef RECORDHASH_FROM_DBAPI /// get first item's ID and CRC from the sync set. /// @return false if no item found virtual bool getFirstItemCRC(localid_out_t &aLocalID, uInt16 &aItemCRC) = 0; /// get next item's ID and CRC from the sync set. /// @return false if no item found virtual bool getNextItemCRC(localid_out_t &aLocalID, uInt16 &aItemCRC) = 0; #else /// get first item from the sync set. Caller obtains ownership if aItemP is not NULL after return /// @return false if no item found virtual bool getFirstItem(TSyncItem *&aItemP) = 0; /// get next item from the sync set. Caller obtains ownership if aItemP is not NULL after return /// @return false if no item found virtual bool getNextItem(TSyncItem *&aItemP) = 0; #endif // RECORDHASH_FROM_DBAPI #ifdef CHANGEDETECTION_AVAILABLE /// get first item's ID and modification status from the sync set /// @return false if no item found virtual bool getFirstItemInfo(localid_out_t &aLocalID, bool &aItemHasChanged) = 0; /// get next item's ID and modification status from the sync set. /// @return false if no item found virtual bool getNextItemInfo(localid_out_t &aLocalID, bool &aItemHasChanged) = 0; #endif // CHANGEDETECTION_AVAILABLE /// get item by local ID from the sync set. Caller obtains ownership if aItemP is not NULL after return /// @return != LOCERR_OK if item with specified ID is not found. virtual localstatus getItemByID(localid_t aLocalID, TSyncItem *&aItemP) = 0; #ifdef RECORDHASH_FROM_DBAPI /// get specified item's CRC as calculated by DB /// @return != LOCERR_OK if item with specified ID is not found. virtual localstatus getItemCRCByID(localid_t aLocalID, uInt16 &aItemCRC) = 0; #endif // RECORDHASH_FROM_DBAPI /// end of syncset reading phase (especially for customimplds on top of binfileds) virtual localstatus apiEndDataRead(void) { return LOCERR_OK; }; /// signal start of data write phase virtual localstatus apiStartDataWrite(void) { return LOCERR_OK; }; /// signal end of data write phase virtual localstatus apiEndDataWrite(void) { return LOCERR_OK; }; /// update item by local ID in the sync set. Caller retains ownership of aItemP /// @return != LOCERR_OK if item with specified ID is not found. virtual localstatus updateItemByID(localid_t aLocalID, TSyncItem *aItemP) = 0; /// delete item by local ID in the sync set. /// @return != LOCERR_OK if item with specified ID is not found. virtual localstatus deleteItemByID(localid_t aLocalID) = 0; /// create new item in the sync set. Caller retains ownership of aItemP. /// @return LOCERR_OK or error code. /// @param[out] aNewLocalID local ID assigned to new item /// @param[out] aReceiveOnly is set to true if local changes/deletion of this item should not be /// reported to the server in normal syncs. virtual localstatus createItem(TSyncItem *aItemP,localid_out_t &aNewLocalID, bool &aReceiveOnly) = 0; /// zaps the entire datastore, returns LOCERR_OK if ok /// @return LOCERR_OK or error code. virtual localstatus zapDatastore(void) = 0; /// returns timestamp of this sync session (must be used to set mod-timestamp on added and changed records) lineartime_t getThisSyncTime(void) { return fCurrentSyncTime; } /// get reference time or count to be used as reference date for this sync's modifications lineartime_t getThisSyncModRefTime(void); uInt32 getThisSyncModCount(void) { return fCurrentModCount; } /// get reference time or count to be used in case datastore implementation wants to compare /// with the time or count of last sync (last two-way sync, that is!) lineartime_t getLastSyncModRefTime(void); uInt32 getLastSyncModCount(void) { return fPreviousToRemoteModCount; } /// zaps changelog. Should be called if datastore as a entiety was replaced /// by another datatstore (or created new) void zapChangeLog(void); /// check if active derived classes (in particular: customImplDS that CAN derive binfiles, but does not necessarily so) bool binfileDSActive(void) { return fConfigP && fConfigP->fBinfileDSActive; }; private: /// load changelog into memory for quick access void loadChangeLog(void); /// forget changelog in memory void forgetChangeLog(void); /// private helper to prepare for apiSaveAdminData() localstatus SaveAdminData(bool aSessionFinished, bool aSuccessful); /// load target record for this datastore localstatus loadTarget(bool aCreateIfMissing, cAppCharP aRemoteDBID=NULL); /* %%% seems obsolete - never called from anywhere // private utils #ifdef OBJECT_FILTERING // - Test Filters bool testFilters(TMultiFieldItem *aItemP); #endif */ // sync anchor, time and changelog cursor (modcount) #ifdef CHECKSUM_CHANGELOG /// change log TBinFile fChangeLog; ///< change log binfile TChangeLogHeader fChgLogHeader; ///< change log header // - returns true if we had a valid changelog bool openChangeLog(void); // - returns true if we had a valid pending map file bool openPendingMaps(void); // - update change log before syncing. Don't call before types are ok (we need TSyncItems) localstatus changeLogPreflight(bool &aValidChangelog); // - clean up change log after syncing localstatus changeLogPostflight(uInt32 aOldestSyncModCount); // - vars bool fPreflighted; // set if preflight (changelog update) was done // - entire change log, loaded into memory for quick reference during write phase TChangeLogEntry *fLoadedChangeLog; uInt32 fLoadedChangeLogEntries; // - true if there are known pending changes for the next sync // (necessary for hasPendingChangesForNextSync() // because not all of the change log is always in memory) bool fHasPendingChanges; #endif // CHECKSUM_CHANGELOG /// pending maps for Resume TBinFile fPendingMaps; ///< pending map binfile TPendingMapHeader fPendingMapHeader; ///< pending map header // number of local changes sInt32 fNumberOfLocalChanges; // GetItem vars uInt32 fLogEntryIndex; // config (typed pointer for convenience) TBinfileDSConfig *fConfigP; }; // TBinfileImplDS } // namespace sysync #endif // BINFILEIMPLDS_H // eof libsynthesis-3.4.0.47.1/src/sysync/clientautosync_inc.cpp000077500000000000000000002312561226375725500234000ustar00rootroot00000000000000/* * File: clientautosync_inc.cpp * * Include file for binfileagent.cpp and palmdbagent.cpp to provide * autosync mechanisms. * * Author: Lukas Zeller (luz@plan44.ch) * * Copyright (c) 2004-2011 by Synthesis AG + plan44.ch * * 2004-05-10 : luz : created from clientprovisioning_inc.cpp * * */ #ifdef AUTOSYNC_SUPPORT #ifdef SYDEBUG static const char * const IPPStateNames[num_ipp_states] = { "unknown", "idle", "activated", "subscribed" }; static const char * const AutoSyncModeNames[num_autosync_modes] = { "push", "timed", "none", "serveralert" }; static const char * const AutoSyncStateNames[num_autosync_states] = { "idle", "start", // start selected autosync mechanism "timedsync", // pure scheduled sync "timedsync_wait", // waiting for scheduled sync to occur "ipp_connectwait", // start waiting until connecting again "ipp_connectwaiting", // waiting for connecting again "ipp_resubscribe", // re-subscribe to DMU method 1 "alert_implicit", // alert implicit datastores "ipp_connect", // connect to server "ipp_sendrequest", // send request to server "ipp_answerwait", // connected, waiting for answer from IPP server "ipp_disconnect", // disconnect from the server "ipp_endanswer", // disconnect after a IPP answer "ipp_processanswer" // process collected IPP answer }; #endif // utility functions // applies the value to the IPP parameter identified by aTag // This can be called from client provisioning code or from a sync session's GET // command RESULT (if the server supports IPP autoconfig) void CLIENTAGENTCONFIG::ipp_setparam(const char *aTag, const char *aValue, TIPPSettings &aIPPSettings) { #ifdef IPP_SUPPORT uInt16 res=0; if (strucmp(aTag,"srv")==0) { AssignCString(aIPPSettings.srv,aValue,maxipppathsiz); fIPPState=ippstate_unknown; } else if (strucmp(aTag,"path")==0) { AssignCString(aIPPSettings.path,aValue,maxipppathsiz); } else if (strucmp(aTag,"id")==0) { AssignCString(aIPPSettings.id,aValue,maxippidsiz); fIPPState=ippstate_unknown; } else if (strucmp(aTag,"port")==0) { StrToUShort(aValue,aIPPSettings.port); } else if (strucmp(aTag,"period")==0) { StrToUShort(aValue,aIPPSettings.period); } else if (strucmp(aTag,"method")==0) { StrToUShort(aValue,res); aIPPSettings.method=(uInt8)res; fIPPState=ippstate_unknown; } else if (strucmp(aTag,"cred")==0) { AssignCString(aIPPSettings.cred,aValue,maxipppathsiz); fIPPState=ippstate_unknown; } else if (strucmp(aTag,"maxinterval")==0) { StrToUShort(aValue,res); aIPPSettings.maxinterval=res; } else if (strucmp(aTag,"timedds")==0) { AssignCString(aIPPSettings.timedds,aValue,maxipppathsiz); } #ifdef GAL_CLIENT_SUPPORT else if (strucmp(aTag,"gal_url")==0) { AssignCString(gGALInfo.url,aValue,GAL_STRING_MAX); gGALInfo.galUpdated=true; } else if (strucmp(aTag,"gal_domain")==0) { AssignCString(gGALInfo.domain,aValue,GAL_STRING_MAX); gGALInfo.galUpdated=true; } #endif #endif } // CLIENTAGENTCONFIG::ipp_setparam // generic code that can work as palmdbagent or binfiledbagent method // must be called when application starts to initialize autosync // BEFORE autosync_setprofile() void CLIENTAGENTCONFIG::autosync_init(lineartime_t aLastAlert) { // make sure all autosync is disabled fAutosyncProfile.AutoSyncLevel[0].Mode=autosync_none; fAutosyncProfile.AutoSyncLevel[1].Mode=autosync_none; fAutosyncProfile.AutoSyncLevel[2].Mode=autosync_none; // init state fAutosyncState=autosync_idle; fAutosyncProfileLastidx=-1; // no profile selected yet fAutosyncLastAlert=aLastAlert; // as saved by the main app fNewMode=autosync_none; // no new mode // init per-profile state fCurrentLevelIndex=-1; // none yet fAutoSyncMode=autosync_none; // disabled until we have checked fNextSyncAt=0; // we do not know when next sync will be fWhyNotFlags=0; // no reason why not // cancel all current alerts autosync_ackAlert(false); #ifdef TCP_LEAK_DEBUG fTcpLeakCounter=0; #endif } // CLIENTAGENTCONFIG::autosync_init // to be called to forget or actually execute prepared autosync alerts in DS config // (e.g. after asking user for confirmation after receiving a SAN) void CLIENTAGENTCONFIG::autosync_ackAlert(bool aAck) { if (!aAck) { // cancel alert fAutosyncAlerted=false; fUnsuccessfulAlerts=0; // make sure all prepared alerts in the DS config are cleared TLocalDSList::iterator pos; for (pos=fDatastores.begin(); pos!=fDatastores.end(); pos++) { CLIENTDSCONFIG *dscfgP = static_cast(*pos); dscfgP->fAutosyncAlerted=false; dscfgP->fAutosyncForced=false; dscfgP->fAutosyncAlertCode=0; dscfgP->fAutosyncPathCGI.erase(); } } else { // activate alerts prepared in DS config fAutosyncAlerted=true; } } // autosync_ackAlert // must be called when active profile changes (or at start of application) void CLIENTAGENTCONFIG::autosync_setprofile(sInt32 aProfileIndex, bool aHasChanged) { if (aProfileIndex != fAutosyncProfileLastidx || aHasChanged) { // a new profile gets active fAutosyncProfileLastidx=aProfileIndex; // - first stop autosync autosync_stop(); // - cancel eventually pending alerts autosync_ackAlert(false); // - read profile that determines autosync behaviour if (getProfile(aProfileIndex,fAutosyncProfile)<0) { // make sure all autosync is disabled fAutosyncProfile.AutoSyncLevel[0].Mode=autosync_none; fAutosyncProfile.AutoSyncLevel[1].Mode=autosync_none; fAutosyncProfile.AutoSyncLevel[2].Mode=autosync_none; } // - re-init per-profile state fAutoSyncMode=autosync_none; // disabled until we have checked fAutosyncAlerted=false; fNextSyncAt=0; // we do not know when next sync will be fWhyNotFlags=0; // no reason why not #ifdef IPP_SUPPORT fIPPState=ippstate_unknown; // we do not know yet #endif // - make sure we do a full settings check fNextCheckAt=0; // do immediately check settings at next step fNextWakeupCheckAt=0; } } // CLIENTAGENTCONFIG::autosync_setprofile // must be called to obtain DMU PUT command data to send to SyncML server void CLIENTAGENTCONFIG::autosync_get_putrequest(string &aReq) { // use custom Put for requesting activation in s2g methods 0 and 1 (but not for method 2 and above) aReq.erase(); // no DMU request when DMU is not active or status unknown #ifdef IPP_SUPPORT if (fAutoSyncMode==autosync_ipp && fIPPState!=ippstate_unknown && fAutosyncProfile.ippSettings.method3 // Note: do no show this in normal debug clients any more as it now happens for EVERY autosync check if (PDEBUGTEST(DBG_TRANSP)) { string ts; StringObjTimestamp(ts,aRestartAt); PDEBUGPRINTFX(DBG_TRANSP,( "AUTOSYNC: app %s quit now, and must be running (again) by %s", canquit ? "MAY" : "MUST NOT", ts.c_str() )); } #endif return canquit; } // CLIENTAGENTCONFIG::autosync_canquit // returns true if we need to perform a sync session now bool CLIENTAGENTCONFIG::autosync_check(bool aActive) { // process one state machine step in active mode autosync_step(aActive); // check if we have a pending re-alert due to failed session execution, // but only if autosync mode is still active (could be temporarily off because of phone flight mode) if (!fAutosyncAlerted && aActive && fAutoSyncMode!=autosync_none) { // no real alert pending, check if we need to generate one for retry reasons if (fUnsuccessfulAlerts>0 && fUnsuccessfulAlertsfAutosyncLastAlert+(AUTOSYNC_MIN_ALERTRETRY << (fUnsuccessfulAlerts-1))*secondToLinearTimeFactor) { // re-alert PDEBUGPRINTFX(DBG_TRANSP,("AUTOSYNC: re-alerting after %hd unsuccessful attempts to run AutoSync Session",fUnsuccessfulAlerts)); fAutosyncLastAlert=getSystemNowAs(TCTX_SYSTEM); fAutosyncAlerted=true; if (fUnsuccessfulAlerts>=AUTOSYNC_FORCEDOWN_RETRIES) { #ifndef ENGINE_LIBRARY // explicitly bring down connection (if we are in a XPT client) getXPTClientBase()->releaseConnection(true); #endif // bring down autosync autosync_stop(); } } } } return fAutosyncAlerted && aActive; } // CLIENTAGENTCONFIG::autosync_check // called to announce that a autosync session was performed void CLIENTAGENTCONFIG::autosync_confirm(bool aUnsuccessful) { if (aUnsuccessful) { // re-alert again later fUnsuccessfulAlerts++; // but clear main alert flag fAutosyncAlerted=false; } else { // clear alert autosync_ackAlert(false); } PDEBUGPRINTFX(DBG_HOT,("AUTOSYNC: confirmed %ssuccessful execution of autosync session",aUnsuccessful ? "un" : "")); } // CLIENTAGENTCONFIG::autosync_confirm // returns true if we need to perform a sync session now void CLIENTAGENTCONFIG::autosync_stop(void) { // perform steps until autosync is idle while(fAutosyncState!=autosync_idle) { // process one state machine step in inactive mode autosync_step(false); } } // CLIENTAGENTCONFIG::autosync_stop // parse parameter from aText static const char *getParam(const char *aText, string &aParam, bool aNeedsSemicolon) { aParam.erase(); // skip leading spaces while (*aText && (*aText==' ')) aText++; // must start with semicolon if (!aNeedsSemicolon || (*aText && (*aText==';'))) { if (aNeedsSemicolon) aText++; // skip it // skip more spaces if any while (*aText && (*aText==' ')) aText++; char quotechar=0; if (*aText==0x22) { quotechar=*aText++; // remember quote char } // read parameter while (*aText && (quotechar ? *aText!=quotechar : !isspace(*aText) && (*aText!=';'))) { // read char if (*aText=='\\') { aText++; if (*aText==0) break; } // add to result aParam += *aText++; } // skip quote char if this was one if (quotechar && *aText==quotechar) aText++; } return aText; } // getParam // get status information about autosync void CLIENTAGENTCONFIG::autosync_status( TAutosyncModes &aAutosyncMode, // currently active mode lineartime_t &aNextSync, // 0 if no scheduled nextsync lineartime_t &aLastAlert, // 0 if no alert seen so far uInt8 &aWhyNotFlags // autosync status flags ) { // return current mode aAutosyncMode = fAutosyncState==autosync_idle ? autosync_none : // show "disabled" state while idle fAutoSyncMode; // special check for IPP (but only if we are really in autosync at this time) #ifdef IPP_SUPPORT if (aAutosyncMode==autosync_ipp) { // check if we have the right activation level if (fIPPState!=ippstate_subscribed) { // reason for not being active is that we are not (yet) correctly activated and/or subscribed aWhyNotFlags=autosync_status_notsubscribed; aAutosyncMode=autosync_none; // show "disabled" while not activated or subscribed } } else #endif { // return reason for not being active right now // (but omit wrongday/wrongtime as these are user settings and should not show up as errors aWhyNotFlags= (fAutosyncState==autosync_idle || fAutosyncState==autosync_timedsync_wait) ? fWhyNotFlags & ~(autosync_status_wrongday+autosync_status_wrongtime) : 0; } // return time of next known sync aNextSync = fNextSyncAt; // timed sync disabled by zero interval? if (aAutosyncMode==autosync_timed) { if (aNextSync==0) { // reason for not being active is that for current mode (cradled/mobile), the interval is set to 0 aWhyNotFlags=autosync_status_disabled; aAutosyncMode=autosync_none; // show "disabled" while timed autosync is not active } else if (aWhyNotFlags) { // other reason for timed sync to be not active aAutosyncMode=autosync_none; // show "disabled" while timed autosync is not active } } // also report last alert aLastAlert=fAutosyncLastAlert; } // CLIENTAGENTCONFIG::autosync_status /// @brief helper: check if environment factors (other than time), such as Mem or Bat, allow this level /// @return true if active, false if not (and updated aWhyNotFlags) static bool checkLevelEnvFactors(const TAutoSyncLevel &aLevel, uInt8 &aWhyNotFlags) { bool levelActive; #ifndef ENGINE_LIBRARY uInt8 battlevel; bool acpowered; #ifdef ENGINEINTERFACE_SUPPORT #error "fMasterPointer in AppBase links to owning TEngineInterface!!" #endif if (getPowerStatus(battlevel,acpowered,getXPTClientBase()->fMasterPointer)) { // valid power info, check if this allows enabling level levelActive = acpowered || battlevel>=aLevel.ChargeLevel; } else { // no valid power info, enabled only if there's no min charge level defined levelActive = aLevel.ChargeLevel==0; } #else #ifdef RELEASE_VERSION #error "reorganize batt and memory level checks in a XPT independent way" #endif levelActive=true; #endif // set flag if battery is reason for inactive level if (!levelActive) aWhyNotFlags |= autosync_status_lowbat; // - check mem as well if (levelActive) { #ifndef ENGINE_LIBRARY // - battery power uInt8 memlevel; #ifdef ENGINEINTERFACE_SUPPORT #error "fMasterPointer in AppBase links to owning TEngineInterface!!" #endif if (getMemFreeStatus(memlevel,getXPTClientBase()->fMasterPointer)) { // valid memory info, check if this allows enabling level levelActive = memlevel>=aLevel.MemLevel; } else { // no valid memory info, enabled only if there's no min free mem level defined levelActive = aLevel.MemLevel==0; } #else levelActive=true; #endif // set flag if memory is reason for inactive level if (!levelActive) aWhyNotFlags |= autosync_status_lowmem; } return levelActive; } // checkLevelEnvFactors /// @brief helper: check if this level is active. /// @return /// - true if yes: returns true and sets aMode. /// - false if no: returns false /// - aNextCheckNeeded is always updated, if 0, we do not need to check because this level cannot get active any time /// OR no timed activity is needed to activate it (as in case of SAN - as long as app starts when SMS arrives, /// that's sufficient. static bool checkAutoSyncLevel(const TAutoSyncLevel &aLevel, lineartime_t aNow, lineartime_t &aNextCheckNeeded, uInt8 &aWhyNotFlags) { bool levelActive=false; // check if we are in one of the selected weekdays (localtime) uInt8 weekday=lineartime2weekday(aNow); if ((aLevel.WeekdayMask & (1<=aLevel.StartDayTime; bool beforend = minuteofdayserverURI; #endif const char *uripos = strstr(serverURI,sanObj.fServerID.c_str()); if (!uripos) { if (aLocalPush && strstr(serverURI,"/*")) { // catchall for local push PDEBUGPRINTFX(DBG_ERROR,("AUTOSYNC: ServerID in SAN (%s) does not match, but profile has catchall-URI for local push",sanObj.fServerID.c_str())); } else { PDEBUGPRINTFX(DBG_ERROR,("AUTOSYNC: ServerID in SAN (%s) is not substring of current profile's Server URL (%s)",sanObj.fServerID.c_str(),serverURI)); return DB_NotFound; // no matching profile found } } // server identifier is ok, check if there are any syncs at all if (sanObj.fNSync<1) { PDEBUGPRINTFX(DBG_ERROR,("AUTOSYNC: SAN does not contain any Sync requests")); return LOCERR_PROCESSMSG; // bad SAN } // check Digest for SANs Version 1.2 and higher if (sanObj.fProtocolVersion>=12) { // get real size of SAN size_t sanSize=aPushMsgSz; // not longer than this err = sanObj.GetSanSize(aPushMsg,sanSize); if (err!=LOCERR_OK) { PDEBUGPRINTFX(DBG_ERROR,("AUTOSYNC: invalid SAN size (raw buffer = %ld), err=%d",aPushMsgSz,err)); return LOCERR_PROCESSMSG; // bad SAN } // now we have user/pw - check the digest string pw; getUnmangled(pw,alertedProfile->serverPassword,maxupwsiz); err=sanObj.CreateDigest( alertedProfile->serverUser, pw.c_str(), alertedProfile->lastNonce, aPushMsg, sanSize ); if (err==LOCERR_OK) { // have it checked if (!sanObj.DigestOK(aPushMsg)) { /// @todo %%% as long as it is unclear where nonce should come from, allow a "Synthesis" constant noce err=sanObj.CreateDigest( alertedProfile->serverUser, pw.c_str(), "Synthesis", aPushMsg, sanSize ); if (err==LOCERR_OK) err = sanObj.DigestOK(aPushMsg) ? LOCERR_OK : DB_Forbidden; } else err=LOCERR_OK; } // - @todo %%% missing for the moment, needs some work on san.cpp first if (err!=LOCERR_OK) { PDEBUGPRINTFX(DBG_ERROR,("AUTOSYNC: invalid SAN digest, err=%hd",err)); return err; // digest not ok } } // SAN with Digest // store some info from SAN aAlertedProfile = fAutosyncProfileLastidx; // %%% for now, we only check the current profile aUIMode=sanObj.fUI_Mode; // pass UI mode out to allow GUI to react // - adjust UI mode if not specified if (aUIMode==UI_not_specified) { // not specified: in background for local sync, visible for remote sync (which will not run unless AutoSync is generally on!) aUIMode = aLocalPush ? UI_background : UI_informative; } fAutosyncSANSessionID = sanObj.fSessionID; // process the sync requests, first one is already here do { // alert by name, force sync (= sync wether target is enabled or not) // if we have UI interaction or localPush, we also alert those datastores that have never synced so far PDEBUGPRINTFX(DBG_HOT,("AUTOSYNC: SAN requests alert %d for '%s', content type code = 0x%lX",syncType,datastoreURI.c_str(),contentType)); if (alertDbByName(datastoreURI.c_str(), "",true,syncType,aUIMode==UI_user_interaction || aLocalPush)) { wantsSync=true; } // check if there are more nth++; err=sanObj.GetNthSync( nth, syncType, contentType, datastoreURI ); } while(err==LOCERR_OK); if (err!=404) { PDEBUGPRINTFX(DBG_ERROR,("AUTOSYNC: error processing %d-th sync request",nth,err)); // but do not exit - it might still be that we have started alerted a sync already } if (wantsSync) { // update server version according to SAN SyncML version TSyncMLVersions alertVers; switch (sanObj.fProtocolVersion) { case 12 : alertVers = syncml_vers_1_2; break; case 11 : alertVers = syncml_vers_1_1; break; case 10 : alertVers = syncml_vers_1_0; break; default : alertVers = syncml_vers_unknown; break; } PDEBUGPRINTFX(DBG_TRANSP,("AUTOSYNC: SAN requests SyncML version %d.%d",sanObj.fProtocolVersion/10,sanObj.fProtocolVersion%10)); if (alertedProfile->lastSyncMLVersion!=alertVers) { // adjust it alertedProfile->lastSyncMLVersion=alertVers; writeProfile(aAlertedProfile,*alertedProfile); } // check if the profile is enabled for autosync at all /// @todo implement checking through all matching profiles - for now, only current is active if ( (fAutoSyncMode!=autosync_serveralerted && fAutoSyncMode!=autosync_ipp) || // no push mode selected for now fAutosyncState==autosync_idle // or active but disabled ) { // SAN is fine, however we are not in Autosync mode // Note: datastores are already alerted in DS config - GUI may choose to start a sync even if Autosync is off return DB_NotAllowed; } else { // we are in autosync mode, but check environment first fEnvCheckedAt = getSystemNowAs(TCTX_SYSTEM); if (fCurrentLevelIndex>=0 && !checkLevelEnvFactors(fAutosyncProfile.AutoSyncLevel[fCurrentLevelIndex], fWhyNotFlags)) { // environment factors disallow syncing now PDEBUGPRINTFX(DBG_ERROR,("AUTOSYNC: SAN wants sync, but Bat/Mem of current level does not allow -> re-checking levels")); fNextCheckAt=0; // force re-checking for active levels return DB_NotAllowed; } } } // everything fine return wantsSync ? LOCERR_OK : DB_NotFound; // no matching target DS found } // autosync_processSAN #endif // performs next step in the state machine void CLIENTAGENTCONFIG::autosync_step(bool aActive) { #ifdef IPP_SUPPORT TcpRc_t tcperr; localstatus err; uInt16 connwaitseconds; const char *q,*p; const int bufsiz=2000; unsigned char buffer[bufsiz]; unsigned long received; #endif string s; TARGETRECORD target; sInt32 idx,seq; CLIENTDSCONFIG *dscfgP; uInt16 interval; string dbname; string filtercgi; bool done; bool newmode; lineartime_t now,nowminute; TAutoSyncStates newstate; bool isCradled; // get clientbase object #ifndef ENGINE_LIBRARY TXPTClientBase *clientBaseP = getXPTClientBase(); #endif do { // assume no state change newstate=fAutosyncState; fCurrentLevelIndex = -1; // none chosen yet // get current time now=getSystemNowAs(TCTX_SYSTEM); nowminute = (now / 60 / secondToLinearTimeFactor) * 60 * secondToLinearTimeFactor; // precision by minute only newmode=false; // assume no mode change done=true; // assume done after processing current state // sanity check for last alert: if (fAutosyncLastAlert>now) fAutosyncLastAlert=0; // reset when "last" alert seems to be in the future - which is not possible // check for new mode if (fNextCheckAt==0 || fNextCheckAt<=now) { // we need to find relevant autosync params fNextCheckAt=maxLinearTime; // infinity fNextWakeupCheckAt=maxLinearTime; // infinity lineartime_t nextcheck; uInt8 lvl; fWhyNotFlags=0; bool found=false; for (lvl=0; lvl0) t=now+AUTOSYNC_MEMCHECK_INTERVAL*secondToLinearTimeFactor; if (t0) t=now+AUTOSYNC_BATTCHECK_INTERVAL*secondToLinearTimeFactor; if (tisConnectable(true)) { found=false; fWhyNotFlags=autosync_status_notconnectable; // check availability of connection soon again fNextCheckAt=now+AUTOSYNC_CONNCHECK_INTERVAL*secondToLinearTimeFactor; } else #endif if (fAutosyncState==autosync_ipp_answerwait) { // is connectable and we are waiting for an answer // now check for changes in cradled/mobile status #ifndef ENGINE_LIBRARY isCradled = clientBaseP->isDeviceCradled(); #else isCradled = true; #endif if (fCurrentlyCradled!=isCradled) { fCurrentlyCradled=isCradled; #ifdef IPP_SUPPORT // seems this has changed, make sure we do a disconnect/reconnect // %%% is a bit ugly to influence the state machine here, but // on the other hand it's here we check so we act here as well... PDEBUGPRINTFX(DBG_HOT,("Detected change to %s state -> reconnect IPP",fCurrentlyCradled ? "cradled" : "mobile")); newstate=autosync_ipp_disconnect; fAutosyncRetries=2; // retry almost immediately done=false; #endif } } } // switch autosync off if none of the levels is active if (!found) { fNewMode=autosync_none; // disable } } // if we have a mode switch pending if (fNewMode!=fAutoSyncMode) { // delay mode switch until we have reached autosync_idle in between if (fAutosyncState==autosync_idle) { // show mode change PDEBUGPRINTFX(DBG_HOT,( "AUTOSYNC: ** MODE CHANGED from %s to %s", AutoSyncModeNames[fAutoSyncMode], AutoSyncModeNames[fNewMode] )); // now we can switch modes fAutoSyncMode=fNewMode; // this is a real mode switch (not only temporary deactivation), // - last alert is cleared when we are now actively going idle. For switching // between DMU and timed, we'll keep the last alert. if (fNewMode==autosync_none) { // - forget last alert, such that timed syncs will immediately start after re-start fAutosyncLastAlert=0; // never so far } } else { // stop current activity first before starting new aActive=false; // show pending mode change PDEBUGPRINTFX(DBG_TRANSP,( "AUTOSYNC: pending mode change from %s to %s - waiting for state to get idle", AutoSyncModeNames[fAutoSyncMode], AutoSyncModeNames[fNewMode] )); } } // now determine IPP state #ifdef IPP_SUPPORT if (isFeatureEnabled(&fAutosyncProfile,APP_FTR_IPP)) { if (fIPPState==ippstate_unknown) { // we have restarted, determine mode from what we have in the settings // (NOTE: this is independent of current autosync mode!) fIPPState=ippstate_idle; // Assume not activated at all fConversationStage=ippconvstage_login; // we need to log in first fDSCfgIterator = fDatastores.end(); if (fAutosyncProfile.ippSettings.id[0]!=0) { // we have a DMUCI/deviceID // - check further params that must be present for either state if (fAutosyncProfile.ippSettings.method==IPP_METHOD_DMUS2G) { fIPPState=ippstate_activated; // with a DMUCI, we are at least activated // method IPP_METHOD_DMUS2G: if we have creds and server, we think we are subscribed if ( fAutosyncProfile.ippSettings.srv[0]!=0 && fAutosyncProfile.ippSettings.cred[0]!=0 ) fIPPState=ippstate_subscribed; } else { // method IPP_METHOD_DMU0 and OMP: when we have a server, we are subscribed // Note: for OMP, the actual SUBSCRIBE command will be issued after connecting later. // The "subscribed" term here relates to DMU terminology. if (fAutosyncProfile.ippSettings.srv[0]!=0) fIPPState=ippstate_subscribed; } } if (fAutosyncProfile.ippSettings.method!=IPP_METHOD_DMU0) { PDEBUGPRINTFX(DBG_TRANSP,( "AUTOSYNC: re-evaluated IPP state from available settings = %s", IPPStateNames[fIPPState] )); } } } #endif // now let state machine run switch (fAutosyncState) { case autosync_idle: // if idle and we want autosync active, we must start it now if (aActive && fAutoSyncMode!=autosync_none) { newstate=autosync_start; done=false; } break; case autosync_start: if (!aActive) { newstate=autosync_idle; break; } // select which loop to start in the state machine if (fAutoSyncMode==autosync_timed) { // go to timed sync checks newstate=autosync_timedsync; done=false; } #ifdef IPP_SUPPORT else if (fAutoSyncMode==autosync_ipp) { // for push methods, we do NOT want a timed sync immediately, // but only after a certain time after the last alert. if (fAutosyncLastAlert==0) fAutosyncLastAlert=now; // assume we have just synced (to avoid a sync shortly after start) // try to connect newstate=autosync_ipp_connect; fAutosyncRetries=0; done=false; } #endif // otherwise, just stay in autosync_start (e.g. for SAN push) break; case autosync_timedsync: if (!aActive) { newstate=autosync_idle; break; } // check for timed sync #ifndef ENGINE_LIBRARY isCradled=clientBaseP->isDeviceCradled(); #else isCradled=true; #endif interval = isCradled ? fAutosyncProfile.TimedSyncCradledPeriod : fAutosyncProfile.TimedSyncMobilePeriod; // calculate time of next sync, minute precision if (fAutosyncLastAlert==0) { if (interval!=0) fNextSyncAt=now; // if we don't know when we've last synced, sync NOW! } else { if (interval==0) break; // do not enter timed sync wait if interval is zero fNextSyncAt = fAutosyncLastAlert + (interval * 60 * secondToLinearTimeFactor); } if (PDEBUGTEST(DBG_TRANSP)) { string ts1,ts2; StringObjTimestamp(ts1,now); StringObjTimestamp(ts2,fNextSyncAt); PDEBUGPRINTFX(DBG_TRANSP,( "AUTOSYNC: Entered timed sync at %s, interval(%s)=%hd min -> next sync at %s", ts1.c_str(), isCradled ? "cradled" : "mobile", interval, ts2.c_str() )); } // update whyNot flags so we'll show the whynot cause as status if (fCurrentLevelIndex>=0) { checkLevelEnvFactors(fAutosyncProfile.AutoSyncLevel[fCurrentLevelIndex], fWhyNotFlags); fEnvCheckedAt = now; } // go waiting newstate=autosync_timedsync_wait; done=false; break; case autosync_timedsync_wait: if (!aActive) { newstate=autosync_idle; fNextSyncAt=0; // when we are not in timed sync, we don't know when next sync will be break; } // remove whynots after a while if (fWhyNotFlags && (now > fEnvCheckedAt+AUTOSYNC_ENVERRSDISPLAY_SECS*secondToLinearTimeFactor)) fWhyNotFlags = 0; // forget them until we re-evaluate them // check for timed sync if (fNextSyncAt!=0 && now>=fNextSyncAt) { // we should start a timed sync - but check environment first (might have changed since we checked last when entering timed sync) if (fCurrentLevelIndex<0) { fNextCheckAt=0; // force immediate check for active levels break; // don't check before we know which level we are in } fEnvCheckedAt = now; if(!checkLevelEnvFactors(fAutosyncProfile.AutoSyncLevel[fCurrentLevelIndex], fWhyNotFlags)) { // environment factors disallow syncing now PDEBUGPRINTFX(DBG_ERROR,("AUTOSYNC: timed sync scheduled for now, but Bat/Mem does not allow -> re-checking levels")); fNextCheckAt=0; // force immediate check for active levels fNextSyncAt=0; // cancel this sync fAutosyncLastAlert = now; // prevent immediate retries, treat as if a sync was alerted newstate=autosync_timedsync; // calc next timed sync break; } // we should start a autosync PDEBUGPRINTFX(DBG_TRANSP,("AUTOSYNC: starting timed sync session")); // we need to re-evaluate the time of next sync, and eventually // enter another mode (could be that we've got here to perform // a safeguard timed sync while in push mode) newstate=autosync_start; // if any datastores are enabled, this will now cause // a sync, so count this as alert fAutosyncLastAlert=now; // autosync-alert all enabled local datastores seq=0; do { idx=findTargetIndex(fAutosyncProfile.profileID,seq++); if (idx<0) break; // no more targets getTarget(idx,target); // get related datastore in config dscfgP = static_cast(getLocalDS(target.dbname)); // check if we would cause a zap on either side if (target.enabled) { if (!( target.forceSlowSync && (target.syncmode==smo_fromclient || target.syncmode==smo_fromserver) )) { dscfgP->fAutosyncForced=false; dscfgP->fAutosyncAlerted=true; dscfgP->fAutosyncPathCGI.erase(); // alerted at least one, autosync is in alerted state now fAutosyncAlerted=true; PDEBUGPRINTFX(DBG_HOT,("AUTOSYNC: *** ALERTED timed autosync for all enabled datastores")); } else { // prevent autosync because of possible zap PDEBUGPRINTFX(DBG_ERROR,("AUTOSYNC: datastore '%s' would cause client or server to be totally overwritten -> do not do timed autosync",dscfgP->getName())); } } } while (true); #ifdef SYDEBUG if (!fAutosyncAlerted) { PDEBUGPRINTFX(DBG_ERROR,("AUTOSYNC: No timed sync possible because no datastore available for sync")); } #endif } break; #ifdef IPP_SUPPORT case autosync_ipp_connectwait: if (!aActive) { newstate=autosync_idle; break; } // start wait phase fAutosyncLastStateChange=now; newstate=autosync_ipp_connectwaiting; // check if we need to resubscribe instead of connecting // (IPP_METHOD_DMUS2G only) if ( fAutosyncProfile.ippSettings.method==IPP_METHOD_DMUS2G && fAutosyncRetries>=IPP_RESUBSCRIBE_RETRIES ) { // check if we need to reactivate if (fAutosyncRetries>=IPP_REACTIVATE_RETRIES) { // force re-activation fIPPState=ippstate_idle; #ifdef SYDEBUG if (fAutosyncRetries==IPP_REACTIVATE_RETRIES) PDEBUGPRINTFX(DBG_ERROR,("AUTOSYNC: too many unsuccessful retries (#%hd) -> cleared activation",fAutosyncRetries)); #endif if (fAutosyncRetries>=IPP_BLOCK_RETRIES) { // prevent hectic syncs in case nothing works at all #ifdef SYDEBUG if (fAutosyncRetries==IPP_BLOCK_RETRIES) PDEBUGPRINTFX(DBG_ERROR,("AUTOSYNC: too many unsuccessful retries (#%hd) -> IPP deactivated",fAutosyncRetries)); #endif newstate=autosync_idle; break; } } if (fUnsuccessfulAlerts==0) { // resubscribe PDEBUGPRINTFX(DBG_ERROR,("AUTOSYNC: too many unsuccessful retries (#%hd) -> requesting resubscription",fAutosyncRetries)); newstate=autosync_ipp_resubscribe; break; } // in case of unsuccesful alerts pending, we'll just enter the waiting state } PDEBUGPRINTFX(DBG_TRANSP,("AUTOSYNC: waiting to connect before next retry (#%hd)",fAutosyncRetries)); done=false; break; case autosync_ipp_connectwaiting: // check for deactivation if (!aActive) { newstate=autosync_idle; break; } // wait until we can reconnect connwaitseconds = IPP_MIN_RECONNECTWAIT<<(fAutosyncRetries-1); if (connwaitseconds>IPP_MAX_RECONNECTWAIT) connwaitseconds=IPP_MAX_RECONNECTWAIT; if (fAutosyncRetries==0 || now>fAutosyncLastStateChange+connwaitseconds*secondToLinearTimeFactor) { // waited long enough newstate=autosync_ipp_connect; PDEBUGPRINTFX(DBG_TRANSP,("AUTOSYNC: waited for %hd seconds in autosync_ipp_connectwaiting",connwaitseconds)); done=false; } break; case autosync_ipp_resubscribe: // IPP_METHOD_DMUS2G only: // force a sync session for resubscription PDEBUGPRINTFX(DBG_HOT,("AUTOSYNC: Performing a sync session to (re-)subscribe now, datastores=%s",fAutosyncProfile.ippSettings.timedds)); if (fIPPState>ippstate_activated) fIPPState=ippstate_activated; // forget subscription if we had one // - wipe server address to make sure we don't use old, expired one any more fAutosyncProfile.ippSettings.srv[0]=0; // - wipe credential fAutosyncProfile.ippSettings.cred[0]=0; // - do an implicit sync newstate=autosync_alert_implicit; done=false; break; case autosync_alert_implicit: // state is idle after an implicit alert newstate=autosync_idle; // only alert if no unsuccessful alerts are pending if (fUnsuccessfulAlerts==0) { // alert all datastores in fImplicitDatastores p = fAutosyncProfile.ippSettings.timedds; while (*p) { // find next comma or EOS for (q=p; *q!=',' && *q!=0; q++); dbname.assign(p,q-p); // alert for sync, no extra filter if (alertDbByName(dbname.c_str(),"",true)) { fAutosyncAlerted=true; fAutosyncLastAlert=now; } // next name if (*q) q++; // skip delimiter p=q; // start after next delimiter, if any } } // - now alert a timed sync session done=true; break; case autosync_ipp_connect: // check if we are connectable at this time if (!clientBaseP->isConnectable(true)) { // we cannot connect now, disable autosync for now newstate=autosync_idle; // effective immediately done=false; // force re-checking of autosync mode (which will keep autosync off until connectable) fNextCheckAt=0; } if (fAutosyncProfile.ippSettings.method==IPP_METHOD_DMU0) { // use the "maxinterval" sync interval in addition to push if ( (fAutosyncLastAlert!=0) && (fAutosyncProfile.ippSettings.maxinterval!=0) && (now>fAutosyncLastAlert+fAutosyncProfile.ippSettings.maxinterval*60*secondToLinearTimeFactor) && !(fAutosyncProfile.ippSettings.timedds[0]==0) && (fUnsuccessfulAlerts==0) ) { // no push alert within maxinterval, perform an implicit timed sync with the datastores from timedds newstate=autosync_alert_implicit; PDEBUGPRINTFX(DBG_HOT,("AUTOSYNC: no alert within maxinterval=%hd mins, performing an implicit autosync session now",fAutosyncProfile.ippSettings.maxinterval)); done=false; break; } } else if (fAutosyncProfile.ippSettings.method==IPP_METHOD_DMUS2G) { // enhanced protocol with router/server architecture // - check if we need to trigger a sync session to (re-)activate/subscribe and get creds // - we start a sync session if we are not subscribed (and we haven't tried for at least IPP_MIN_RESUBSCRIBEWAIT) // - we start a sync session if current credential has timed out if ( ( (fIPPState!=ippstate_subscribed && (fAutosyncRetries==0 || now>fAutosyncLastAlert+IPP_MIN_RESUBSCRIBEWAIT*secondToLinearTimeFactor)) || ( (fAutosyncLastAlert!=0) && (fAutosyncProfile.ippSettings.maxinterval!=0) && (now>fAutosyncLastAlert+fAutosyncProfile.ippSettings.maxinterval*60*secondToLinearTimeFactor) ) ) && !(fAutosyncProfile.ippSettings.timedds[0]==0) && (fUnsuccessfulAlerts==0) ) { PDEBUGPRINTFX(DBG_HOT,("AUTOSYNC: no credential or no alert within current credential lifetime=%d mins, performing an implicit sync to (re-)subscribe now",fAutosyncProfile.ippSettings.maxinterval)); // we need to resubscribe newstate=autosync_ipp_resubscribe; // this is a failed attempt to connect, make sure fAutosyncRetries is not zero any more fAutosyncRetries++; done=false; break; } } // if we have no server here, state must be re-evaluated if (fAutosyncProfile.ippSettings.srv[0]==0) fIPPState=ippstate_unknown; // check for unsubscribed again if (fIPPState!=ippstate_subscribed) { // not subscribed (no server address) -> keep waiting PDEBUGPRINTFX(DBG_TRANSP,("AUTOSYNC: IPP connection cannot be made because IPP state is not subscribed -> wait again")); if (fAutosyncRetriesestablishConnectionFor(s.c_str(),true); // background priority connection if (err!=LOCERR_OK) { // failed, wait until trying again PDEBUGPRINTFX(DBG_ERROR,("AUTOSYNC: autosync_ipp_connect: failed establishing connection, err=%hd",err)); newstate=autosync_ipp_connectwait; // just not being able to establish a connection MUST NOT trigger a resubscription! if (fAutosyncRetriesreleaseConnection(fAutosyncRetries>=IPP_FORCEDOWN_RETRIES); PDEBUGPRINTFX(DBG_TRANSP,("AUTOSYNC: disconnected, entering wait for next connection...")); newstate=autosync_ipp_connectwait; break; case autosync_ipp_sendrequest: // check for deactivation if (!aActive) { newstate=autosync_ipp_disconnect; done=false; break; } // send IPP request // - clear answer string fAutosyncIPPAnswer.erase(); // - nothing known about headers or conten length yet fHeaderLength = 0; fContentLength = 0; if (fAutosyncProfile.ippSettings.method==IPP_METHOD_DMU0) { // DMU method 0 (aka IPP, aka DMU demo) // - create GET request string StringObjPrintf(s, "GET %s%s\r\n", fAutosyncProfile.ippSettings.path, fAutosyncProfile.ippSettings.id ); } else if (fAutosyncProfile.ippSettings.method==IPP_METHOD_DMUS2G) { // DMU method 1 (s2g router/server architecture) // - create LOGIN request string StringObjPrintf(s, "LOGIN %s%s\r\n" "cred=%s\r\n" "\r\n", fAutosyncProfile.ippSettings.path, fAutosyncProfile.ippSettings.id, fAutosyncProfile.ippSettings.cred ); } else if (fAutosyncProfile.ippSettings.method==IPP_METHOD_OMP) { // Oracle Mobile Push string data; data.erase(); // - prepare POST request StringObjPrintf(s, "POST %s HTTP/1.1\r\n" "Host: %s\r\n" "Content-Type: application/vnd.mobilepush\r\n", fAutosyncProfile.ippSettings.path, fAutosyncProfile.ippSettings.srv ); // - now add specific command if (fConversationStage==ippconvstage_login) { // need login first string pw; getUnmangled(pw, fAutosyncProfile.serverPassword); // we need to login first StringObjPrintf(data, "LOGIN %s#P%s %s\r\n", fAutosyncProfile.serverUser, fAutosyncProfile.ippSettings.id, pw.c_str() ); } else { // not login, add the cookie StringObjAppendPrintf(s, "Cookie: %s\r\n", fOMPCookie.c_str() ); // now the command if (fConversationStage==ippconvstage_subscribe) { // logged in, now subscribe to all available datastores while (fDSCfgIterator != fDatastores.end()) { // check the datastore CLIENTDSCONFIG *dscfgP = static_cast(*fDSCfgIterator); fDSCfgIterator++; cAppCharP subsName = NULL; if (dscfgP->fDSAvailFlag & dsavail_contacts) subsName = "CONTACTS"; else if (dscfgP->fDSAvailFlag & dsavail_events) subsName = "CALENDAR"; else if (dscfgP->fDSAvailFlag & dsavail_tasks) subsName = "TODO"; else if (dscfgP->fDSAvailFlag & dsavail_emails) subsName = "EMAIL"; else continue; // try next // create subscription for this datastore StringObjPrintf(data, "SUBSCRIBE %s\r\n", subsName ); break; } } else if (fConversationStage==ippconvstage_polling) { // subscribed, now poll // - add push time header StringObjAppendPrintf(s, "TruePush-time: %d\r\n", fAutosyncProfile.ippSettings.period ); // - and the command data = "P\r\n"; } } // add content with length header StringObjAppendPrintf(s, "Content-Length: %ld\r\n" "\r\n" "%s", data.size(), data.c_str() ); } else { // unknown method, disconnect again PDEBUGPRINTFX(DBG_ERROR,("AUTOSYNC: Warning: unknown method=%d, disconnecting",(int)fAutosyncProfile.ippSettings.method)); newstate=autosync_ipp_disconnect; done=false; break; } PDEBUGPRINTFX(DBG_TRANSP,("AUTOSYNC: sending request: %s",s.c_str())); // - sent it tcperr = tcpSendDataEx( &fAutosyncIPPSocket, // socket (unsigned char *)s.c_str(), // request string s.size(), 5 // maximally 5 seconds (usually, this should work w/o ANY timeout) ); if (tcperr==TCP_RC_ETIMEDOUT) break; // just try again later if (tcperr!=TCP_RC_OK) { // failed: disconnect & reconnect PDEBUGPRINTFX(DBG_ERROR,("AUTOSYNC: failed sending request, tcperr=%d",tcperr)); newstate=autosync_ipp_disconnect; fAutosyncRetries++; // count retry done=false; break; } // request sent ok newstate=autosync_ipp_answerwait; // and wait for answer fAutosyncLastStateChange=now; break; case autosync_ipp_answerwait: // check for deactivation if (!aActive) { newstate=autosync_ipp_disconnect; done=false; break; } // when we've got so far, now enable timed-sync-while-ipp-active // if not already enabled (enabled = fAutosyncLastAlert is set) if (fAutosyncLastAlert==0) fAutosyncLastAlert=now; // wait for IPP answer received=bufsiz; tcperr = tcpReadDataEx( &fAutosyncIPPSocket, // Socket buffer, &received, 0 ); if (tcperr==TCP_RC_ETIMEDOUT) { // check if connection is still ok if (!clientBaseP->isConnectionOK()) { PDEBUGPRINTFX(DBG_ERROR,("AUTOSYNC: Connection not ok any more while waiting for answer -> disconnect")); newstate=autosync_ipp_disconnect; fAutosyncRetries=2; // retry almost immediately done=false; } // check if IPP period is over uInt32 timeout = fAutosyncProfile.ippSettings.method==IPP_METHOD_OMP && fConversationStage!=ippconvstage_polling ? IPP_OMP_COMMAND_TIMEOUT : // non-poll OMP command fAutosyncProfile.ippSettings.period; // poll command if (now>fAutosyncLastStateChange+timeout*secondToLinearTimeFactor) { // IPP period timeout PDEBUGPRINTFX(DBG_TRANSP,("AUTOSYNC: IPP period timeout (%d secs), go to disconnect",timeout)); newstate=autosync_ipp_disconnect; fAutosyncRetries=0; // ok so far done=false; } break; // stay in answerwait or disconnect after period timeout } if (tcperr==TCP_RC_EOF) { // connection properly closed newstate=autosync_ipp_endanswer; break; } if (tcperr!=TCP_RC_OK) { // failed: disconnect & reconnect PDEBUGPRINTFX(DBG_ERROR,("AUTOSYNC: failed receiving answer, tcperr=%d",tcperr)); newstate=autosync_ipp_disconnect; fAutosyncRetries++; // count retry done=false; break; } // received answer bytes fAutosyncIPPAnswer.append((const char *)buffer,received); if (fAutosyncProfile.ippSettings.method==IPP_METHOD_OMP) { size_t n; // check for content length if (fContentLength==0) { n = fAutosyncIPPAnswer.find("Content-Length: "); if (n!=string::npos) { n += 16; n += StrToULong(fAutosyncIPPAnswer.c_str()+n, fContentLength, 9); } } // check for end of headers if (fHeaderLength==0) { n = fAutosyncIPPAnswer.find("\r\n\r\n"); if (n!=string::npos) { fHeaderLength = n+4; } } // check for all data seen if (fHeaderLength && fContentLength && fAutosyncIPPAnswer.size()>=fHeaderLength+fContentLength) { // End of request, but not necessarily connection. // (processing answer will decide if connection must be closed) newstate=autosync_ipp_processanswer; break; } } // stay in answerwait until connection closes break; case autosync_ipp_endanswer: PDEBUGPRINTFX(DBG_TRANSP,("AUTOSYNC: end of data from server, closing connection")); // close connection tcpCloseConnection(&fAutosyncIPPSocket); fAutosyncIPPSocket=0; #ifdef TCP_LEAK_DEBUG fTcpLeakCounter--; #endif // release connection clientBaseP->releaseConnection(); // state is idle after processing a message newstate=autosync_ipp_processanswer; // leave app some time to close and release the connection done=true; break; case autosync_ipp_processanswer: PDEBUGPRINTFX(DBG_HOT,("AUTOSYNC: processing answer from server: %" FMT_LENGTH("0.100") "s",FMT_LENGTH_LIMITED(100,fAutosyncIPPAnswer.c_str()))); // state is idle after processing a message newstate=autosync_idle; // process collected answer bytes p=fAutosyncIPPAnswer.c_str(); uInt16 retriedsofar=fAutosyncRetries; fAutosyncRetries=0; bool disconnect=true; // default to disconnect for every message if (fAutosyncProfile.ippSettings.method==IPP_METHOD_OMP) { // parse line by line bool inheaders=true; disconnect=false; // for OMP, only disconnect if explicitly requested by "Connection:" header while (*p) { // check for those headers we need to know if (strucmp(p,"\r\n",2)==0) { p+=2; inheaders=false; break; } if (strucmp(p,"Set-Cookie: ",12)==0) { // extract login cookie p+=12; q=p; while (*q && *q!=';' && *q>=' ') q++; fOMPCookie.assign(p,q-p); } else if (strucmp(p,"Connection: close",22)==0) { disconnect=true; } // go past next CRLF while (*p && *p!='\r') p++; p++; if (*p=='\n') p++; } // now decode status returned (still in headers means failure as well) bool success = !inheaders && (strucmp(p,"OK ",3)==0) || isdigit(*p); // a non-ok on any stage means we must retry or fall back to login after some retries if (!success) { fAutosyncRetries=retriedsofar+1; // this is an error, keep counting retries PDEBUGPRINTFX(DBG_ERROR,("AUTOSYNC: OMP server error: %" FMT_LENGTH("0.100") "s",FMT_LENGTH_LIMITED(100,p))); newstate=autosync_ipp_disconnect; if (fAutosyncRetries>IPP_OMP_RELOGIN_RETRIES) { PDEBUGPRINTFX(DBG_ERROR,("AUTOSYNC: OMP repeated server error -> force relogin")); fConversationStage = ippconvstage_login; } break; } // basically ok, now depends on communication stage if (fConversationStage==ippconvstage_login) { // last command sent was login // - next is subscribe fConversationStage=ippconvstage_subscribe; // - start with first datastore fDSCfgIterator = fDatastores.begin(); } else if (fConversationStage==ippconvstage_subscribe) { // check if more DS must be subscribed if (fDSCfgIterator == fDatastores.end()) fConversationStage=ippconvstage_polling; // all subscribed, proceed to polling now } else if (fConversationStage==ippconvstage_polling) { // check polling response while (isdigit(*p)) { // event line // Syntax: notify_seqno SP dest_app SP username SP deviceID SP event // 12 EMAIL john.doe@oracle.com 123123:132123:132123 SYNC // - skip seqno while (*p && isdigit(*p)) p++; if (*p==' ') { p++; // - extract app uInt16 availFlag; q=p; while (*q && *q!=' ') q++; if (strucmp(p,"CONTACTS",q-p)==0) availFlag = dsavail_contacts; else if (strucmp(p,"CALENDAR",q-p)==0) availFlag = dsavail_events; else if (strucmp(p,"TODO",q-p)==0) availFlag = dsavail_tasks; else if (strucmp(p,"EMAIL",q-p)==0) availFlag = dsavail_emails; if (availFlag) { // check for SYNC event p=q; if (*p==' ') p++; // - skip user while (*p && *p!=' ') p++; if (*p==' ') p++; // - skip device ID while (*p && *p!=' ') p++; if (*p==' ') p++; // check for SYNC command if (strucmp(p,"SYNC",4)==0) { PDEBUGPRINTFX(DBG_HOT,("AUTOSYNC: received OMP sync request for availFlags=0x%hX",availFlag)); // alert for sync if (alertDbByAppType(availFlag,true)) { fAutosyncAlerted=true; fAutosyncLastAlert=now; disconnect=true; // break TCP connection } } } else break; } // forward to end of line or string while (*p && (*p>=0x20)) p++; while (*p && ((*p=='\n') || (*p=='\r'))) p++; } // while } } else { // DMU0 or DMUS2G while (*p) { // check for basic command if ( (fAutosyncProfile.ippSettings.method==IPP_METHOD_DMU0 && strucmp(p,"Sync:",5)==0) || (fAutosyncProfile.ippSettings.method==IPP_METHOD_DMUS2G && strucmp(p,"sync=",5)==0) ) { p+=5; // get datastore name (remote datastore path, that is!) p=getParam(p,dbname,false); // get eventual additional params // - first is filter CGI p=getParam(p,filtercgi,true); // search DB to flag autosync for it PDEBUGPRINTFX(DBG_HOT,("AUTOSYNC: received sync request for db='%s', filter='%s'",dbname.c_str(),filtercgi.c_str())); // alert for sync if (alertDbByName(dbname.c_str(),filtercgi.c_str(),true)) { fAutosyncAlerted=true; fAutosyncLastAlert=now; } } // if "Sync:" or "sync=" line else if ( (fAutosyncProfile.ippSettings.method==IPP_METHOD_DMUS2G && strucmp(p,"error=",6)==0) ) { p+=6; fAutosyncRetries=retriedsofar+1; // this is an error, keep counting retries // get error code uInt32 dmuerr=99999; // unknown error code StrToULong(p,dmuerr,6); if (dmuerr==10010 || dmuerr==10020) { // credential unknown, bad or expired // - make sure that we'll resubscribe if (fAutosyncRetries( getLocalDS(target.dbname) ); bool mayStart= aAlwaysStart || (target.lastSync!=0); // start allowed ONLY if we have synced before with this target // if we have an explicit sync mode, this overrides the preset mode if (mayStart) { if (aSyncAlert!=0) { // caller provides a sync mode dscfgP->fAutosyncAlertCode=aSyncAlert; // use passed sync alert code } else { // do not automatically start in "dangerous" modes dscfgP->fAutosyncAlertCode=0; // get mode from config mayStart = !( target.forceSlowSync && (target.syncmode==smo_fromclient || target.syncmode==smo_fromserver) ); } } // start if not "dangerous" or when sync mode is explicitly requested by trusted party (SAN) if (mayStart) { // alert dscfgP->fAutosyncForced=aForced; // forced if selected dscfgP->fAutosyncAlerted=true; // alerted anyway AssignString(dscfgP->fAutosyncPathCGI, aFilterCGI); // alerted at least one, IPP is in alerted state now alertedAny=true; PDEBUGPRINTFX(DBG_HOT,("AUTOSYNC: *** ALERTED autosync for datastore '%s' (requested alert=%hd)",dscfgP->getName(),dscfgP->fAutosyncAlertCode)); } else { // prevent autosync because of possible zap PDEBUGPRINTFX(DBG_ERROR,("AUTOSYNC: datastore '%s' never synceed so far or would IMPLICITLY cause client or server to be totally overwritten -> do not autosync",dscfgP->getName())); } } } while (true); return alertedAny; } // CLIENTAGENTCONFIG::alertDbByName /// @brief alert a datastore by generic application type (DSAvailFlag) /// @note if syncType is given (e.g. from a SAN) complete overwrites are possible if explicitly requested bool CLIENTAGENTCONFIG::alertDbByAppType(uInt16 aDSAvailFlag, bool aForced, bool aAlwaysStart) { bool alertedAny=false; TARGETRECORD target; TLocalDSList::iterator pos; for(pos=fDatastores.begin();pos!=fDatastores.end();pos++) { CLIENTDSCONFIG *dscfgP = static_cast(*pos); if ((dscfgP->fDSAvailFlag & aDSAvailFlag) == aDSAvailFlag) { // found datastore // - get target record to check settings sInt32 idx = findTargetIndexByDBInfo(fAutosyncProfile.profileID, dscfgP->fLocalDBTypeID, NULL); if (idx>=0) { getTarget(idx,target); bool mayStart= aAlwaysStart || (target.lastSync!=0); // start allowed ONLY if we have synced before with this target // if we have an explicit sync mode, this overrides the preset mode if (mayStart) { // do not automatically start in "dangerous" modes dscfgP->fAutosyncAlertCode=0; // get mode from config mayStart = !( target.forceSlowSync && (target.syncmode==smo_fromclient || target.syncmode==smo_fromserver) ); } // start if not "dangerous" or when sync mode is explicitly requested by trusted party (SAN) if (mayStart) { // alert dscfgP->fAutosyncForced=aForced; // forced if selected dscfgP->fAutosyncAlerted=true; // alerted anyway // alerted at least one, IPP is in alerted state now alertedAny=true; PDEBUGPRINTFX(DBG_HOT,("AUTOSYNC: *** ALERTED OMP autosync for datastore '%s' (requested alert=%hd)",dscfgP->getName(),dscfgP->fAutosyncAlertCode)); } else { // prevent autosync because of possible zap PDEBUGPRINTFX(DBG_ERROR,("AUTOSYNC: datastore '%s' never synced so far or would IMPLICITLY cause client or server to be totally overwritten -> do not autosync",dscfgP->getName())); } } } } return alertedAny; } // CLIENTAGENTCONFIG::alertDbByAppType #endif /* eof */ libsynthesis-3.4.0.47.1/src/sysync/clientautosync_inc.h000077500000000000000000000264531226375725500230460ustar00rootroot00000000000000/* * File: clientautosync_inc.h * */ #ifdef IPP_SUPPORT // we need the platform-specific TCP-IP implementation extern "C" { #include "xptitcp.h" } #endif // we need the xpt client base if we directly do TCP/IP #if defined(IPP_SUPPORT) || !defined(ENGINE_LIBRARY) #include "xptclientbase.h" #endif #ifdef SERVERALERT_SUPPORT #include "san.h" #endif // define to debug TCP open/close balance //#define TCP_LEAK_DEBUG 1 #ifdef GAL_CLIENT_SUPPORT #define GAL_STRING_MAX 80 // globals typedef struct { // GAL settings bool galUpdated; char url[GAL_STRING_MAX]; char domain[GAL_STRING_MAX]; } TGALInfo; extern TGALInfo gGALInfo; #endif // we need some system status routins // these routines must be implemented in the application // - get power status (percentage) of the system, returns false if none available bool getPowerStatus(uInt8 &aBattLevel, bool &aACPowered, void *aMasterPointer); // - get free memory status (percentage free) of the system, returns false if none available bool getMemFreeStatus(uInt8 &aMemLevel, void *aMasterPointer); // - check if device is cradled bool isDeviceCradled(void *aMasterPointer); namespace sysync { // Autosync modes // note: %%% eventually, SMP GUI still depends on this order - PPC is fixed as per 2006-03-09 typedef enum { autosync_ipp, // Intelligent Push&Poll (DMU) autosync_timed, // timed sync (scheduled sync) autosync_none, // no autosync autosync_serveralerted, // SAN - SyncML server alerted sync num_autosync_modes } TAutosyncModes; // Autosync status #define autosync_status_wrongday 0x01 #define autosync_status_wrongtime 0x02 #define autosync_status_lowmem 0x04 #define autosync_status_lowbat 0x08 #define autosync_status_disabled 0x10 // disabled by interval=0 (for example) #define autosync_status_notconnectable 0x20 #define autosync_status_notsubscribed 0x40 #define autosync_status_notlicensed 0x80 // IPP/DMU without license // Autosync condition level settings record // NOTE!!!!!: If this struct is changed, this implies a PROFILE_DB_VERSION change!!! typedef struct { TAutosyncModes Mode; uInt16 StartDayTime; // [min from midnight] when to start autosync uInt16 EndDayTime; // [min from midnight] when to stop autosync uInt8 WeekdayMask; // [Bits: 0=sun, 1=mon .. 6=sat] days when autosync is active uInt8 ChargeLevel; // percent of battery charge required to activate uInt8 MemLevel; // percent of memory that must be free for doing autosync uInt8 Flags; // additional condition flags - reserved for future use } TAutoSyncLevel; // IPP methods #define IPP_METHOD_DMU0 0 // simple poll, open specification, used by Toffa SyncWiseEnterprise #define IPP_METHOD_DMUS2G 1 // proprietary s2g method 1 protocol, confidential spec #define IPP_METHOD_OMP 2 // Oracle Mobile Push // Autosync IPP settings record // NOTE!!!!!: If this struct is changed, this implies a PROFILE_DB_VERSION change!!! const uInt16 maxippidsiz=64; const uInt16 maxipppathsiz=64; typedef struct { char srv[maxipppathsiz]; uInt16 port; uInt16 period; char path[maxipppathsiz]; char id[maxippidsiz]; uInt8 method; // new PROFILE_DB_VERSION>=6 fields char cred[maxipppathsiz]; uInt16 maxinterval; char timedds[maxipppathsiz]; } TIPPSettings; typedef enum { ippstate_unknown, ippstate_idle, ippstate_activated, ippstate_subscribed, num_ipp_states } TIPPActivationState; typedef enum { ippconvstage_login, ippconvstage_subscribe, ippconvstage_polling } TIPPConvStage; // AutoSync states typedef enum { autosync_idle, // no activity autosync_start, // start selected autosync mechanism autosync_timedsync, // start pure scheduled sync (calc when we need next sync) autosync_timedsync_wait, // waiting for scheduled sync to occur autosync_ipp_connectwait, // start waiting until connecting again autosync_ipp_connectwaiting, // waiting for connecting again autosync_ipp_resubscribe, // cause a timed sync to re-subscribe to IPP autosync_alert_implicit, // implicit alert autosync_ipp_connect, // connect to server autosync_ipp_sendrequest, // send request to server autosync_ipp_answerwait, // connected, waiting for answer from IPP server autosync_ipp_disconnect, // disconnect from the server autosync_ipp_endanswer, // disconnect after a IPP answer autosync_ipp_processanswer, // process collected IPP answer num_autosync_states } TAutoSyncStates; // IPP parameters #define IPP_MIN_RECONNECTWAIT 3 // [seconds] #define IPP_MAX_RECONNECTWAIT 1800 // [seconds] = half an hour #define IPP_FORCEDOWN_RETRIES 3 // force down connection after 3 failed reconnects #define IPP_RESUBSCRIBE_RETRIES 5 // re-subscribe after 5 failed reconnects #define IPP_REACTIVATE_RETRIES 7 // after 7 failed reconnects with resubscription, force a reactivation #define IPP_BLOCK_RETRIES 9 // after 9 failed reconnects, do not do anything any more #define IPP_MIN_RESUBSCRIBEWAIT 180 // [seconds] wait minimally 3 minutes until re-trying subcription in case previous sync session did not deliver subscription params #define IPP_OMP_COMMAND_TIMEOUT 10 // [seconds] wait x seconds for non-poll OMP command to get answer #define IPP_OMP_RELOGIN_RETRIES 2 // fall back to re-login after 2 failed attempts // Autosync parameters #define AUTOSYNC_MAX_ALERTRETRIES 5 // retry max 5 times to start a sync session again after a failed alert #define AUTOSYNC_FORCEDOWN_RETRIES 2 // after 2 retries, bring down connection first before re-trying #define AUTOSYNC_MIN_ALERTRETRY 10 // retry after 10,20,40,80 and 160 secs #define AUTOSYNC_BATTCHECK_INTERVAL 60 // check battery level every minute #define AUTOSYNC_MEMCHECK_INTERVAL 60 // check memory every minute #define AUTOSYNC_CONNCHECK_INTERVAL 10 // check connection status every 10 seconds #define AUTOSYNC_ENVERRSDISPLAY_SECS 15 // show battery/mem errors 15 seconds after failed timed autosync #ifdef IPP_SUPPORT // applies the value to the IPP parameter identified by aTag // This can be called from client provisioning code or from a sync session's GET // command RESULT (if the server supports IPP autoconfig) void ipp_setparam(const char *aTag, const char *aValue, TIPPSettings &aIPPSettings); #endif #ifdef TCP_LEAK_DEBUG #define TCP_LEAKCOUNTER uInt32 fTcpLeakCounter; #else #define TCP_LEAKCOUNTER #endif #ifdef IPP_SUPPORT #define IPP_VARS \ uInt16 fAutosyncRetries; /* retry count for IPP connection attempts */ \ Socket_t fAutosyncIPPSocket; /* the socket used for IPP */ \ string fAutosyncIPPAnswer; /* the IPP answer is collected here */ \ TIPPActivationState fIPPState; /* the IPP activation state */ \ TIPPConvStage fConversationStage; /* conversation stage within IPP poll connection (OMG only at this time) */ \ TLocalDSList::iterator fDSCfgIterator; /* iterator for datastores (used for SUBSCRIBE in OMP) */ \ string fOMPCookie; /* cookie for OMP */ \ uInt32 fHeaderLength; /* header length */ \ uInt32 fContentLength; /* content length */ #define IPP_METHODS #else #define IPP_METHODS #define IPP_VARS #endif #ifdef SERVERALERT_SUPPORT #define SAN_VARS \ uInt32 fAutosyncSANSessionID; /* Session ID as requested by SAN */ #define SAN_METHODS \ /* - analyzes server alert (SAN) message */ \ localstatus autosync_processSAN(bool aLocalPush, void *aPushMsg, uInt32 aPushMsgSz, cAppCharP aHeaders, sInt32 &aAlertedProfile, UI_Mode &aUIMode); #else #define SAN_METHODS #define SAN_VARS #endif // macro to declare autosync methods and fields in agent config #ifndef AUTOSYNC_SUPPORT #define CLIENTAUTOSYNC_CLASSDECL #else #define CLIENTAUTOSYNC_CLASSDECL \ public: \ /* Autosync methods */ \ /* - init autosync mechanism */ \ void autosync_init(lineartime_t aLastAlert); \ /* - set profile */ \ void autosync_setprofile(sInt32 aProfileIndex, bool aHasChanged); \ /* must be called to obtain DMU PUT command data to send to SyncML server */ \ void autosync_get_putrequest(string &aReq); \ /* - should be called when environmental params have changed */ \ void autosync_condchanged(void); \ /* - check if app may quit */ \ bool autosync_canquit(lineartime_t &aRestartAt, bool aEnabled); \ /* - check if we need a sync now */ \ bool autosync_check(bool aActive); \ /* - get status information about autosync */ \ void autosync_status( \ TAutosyncModes &aAutosyncMode, /* currently active mode */ \ lineartime_t &aNextSync, /* 0 if no scheduled nextsync */ \ lineartime_t &aLastAlert, /* 0 if no alert seen so far */ \ uInt8 &aWhyNotFlags /* why-no-autosync status flags */ \ ); \ /* - returns true if we need to perform a sync session now */ \ void autosync_stop(void); \ /* - performs next step in the state machine */ \ void autosync_step(bool aActive); \ /* - forget or activate syncs alerted for autosync in DS config */ \ void autosync_ackAlert(bool aAck); \ /* - confirm that autosync has taken place (clears alerted flag) */ \ void autosync_confirm(bool aUnsuccessful=false); \ /* - parse ipp params */ \ void ipp_setparam(const char *aTag, const char *aValue, TIPPSettings &aIPPSettings); \ IPP_METHODS \ SAN_METHODS \ /* - profile record */ \ PROFILERECORD fAutosyncProfile; \ sInt32 fAutosyncProfileLastidx; /* -1 if no profile selected before */ \ private: \ /* alert a datastore by remote database name */ \ bool alertDbByName(const char *aRemoteDBName, const char *aFilterCGI, bool aForced, uInt16 syncAlert=0, bool aAlwaysStart=false); \ /* alert a datastore by generic type flag */ \ bool alertDbByAppType(uInt16 aDSAvailFlag, bool aForced, bool aAlwaysStart=false); \ /* private vars needed for autosync */ \ /* - state vars */ \ sInt16 fCurrentLevelIndex; /* index of currently active autosync level, -1 if none */ \ TAutosyncModes fAutoSyncMode; /* currently active autosync mode */ \ TAutosyncModes fNewMode; /* new target mode */ \ lineartime_t fNextCheckAt; /* when we need to check for mode change or timed sync next, 0 if immediately */ \ lineartime_t fNextWakeupCheckAt; /* when we need to wakeup app to check levels, 0 if immediately */ \ uInt8 fWhyNotFlags; /* reason why we cannot run autosync now */ \ lineartime_t fEnvCheckedAt; /* when we last checked the mem/batt environmental factors */ \ lineartime_t fNextSyncAt; /* when next sync will take place */ \ TAutoSyncStates fAutosyncState; /* current state machine state */ \ bool fAutosyncAlerted; /* set when some datastores get alerted, cleared when autosync_confirm() */ \ lineartime_t fAutosyncLastStateChange; /* time when state changed last time */ \ uInt16 fUnsuccessfulAlerts; /* if > 0, we had unsuccessful alerts - delay re-alerting */ \ IPP_VARS \ SAN_VARS \ bool fCurrentlyCradled; /* the current IPP connection is assuming cradled operation */ \ /* timed sync */ \ lineartime_t fAutosyncLastAlert; /* time when last autosync was alerted */ \ TCP_LEAKCOUNTER #endif // macro to declare autosync fields in DB (target) config #ifndef AUTOSYNC_SUPPORT #define CLIENTAUTOSYNC_CLASSDECL_DB #else #define CLIENTAUTOSYNC_CLASSDECL_DB \ public: \ bool fAutosyncAlerted; /* set if server requested sync of this datastore */ \ bool fAutosyncForced; /* set if server requests sync of this datastore even if target is disabled */ \ uInt16 fAutosyncAlertCode; /* if not 0, this is the alert code requested e.g. by a SAN initiated autosync */ \ string fAutosyncPathCGI; /* the CGI to be appended to the database path */ #endif } // namespace sysync /* eof */ libsynthesis-3.4.0.47.1/src/sysync/clientprovisioning_inc.cpp000077500000000000000000000306111226375725500242510ustar00rootroot00000000000000/* * File: clientprovisioning_inc.cpp * * Include file for binfileagent.cpp and palmdbagent.cpp to provide * string-command based client provisioning. * * Author: Lukas Zeller (luz@plan44.ch) * * Copyright (c) 2003-2011 by Synthesis AG + plan44.ch * * 2003-09-30 : luz : created * * */ #ifndef ENHANCED_PROFILES_2004 #error "no support any more for non-ENHANCED_PROFILES_2004" #endif // Configure profile // - params must always start with pf="profilename" or defpf="profilename" // - aActiveProfile is updated only if profile was actually added, changed or deleted static bool configProfile(CLIENTAGENTCONFIG *aCfgP, const char *aParm, bool aMayAdd, bool aMayUpdate, sInt32 &aActiveProfile) { #ifdef MULTI_PROFILE_SUPPORT const sInt32 maxprofiles = 30; // prevent overflowing popup too much #else const sInt32 maxprofiles = 1; // only one profile #endif string tag,pfnam,value; // get profile name aParm=nextTag(aParm,tag,pfnam); if (!aParm) return false; bool def=false; if (tag=="defpf") def=true; else if (!(tag=="pf")) return false; // find profile by name sInt32 np = aCfgP->numProfiles(); sInt32 pi = np; PROFILERECORD profile; bool found=false; while (pi>0) { pi--; aCfgP->getProfile(pi,profile); if (strucmp(profile.profileName,pfnam.c_str())==0) { found=true; break; } } // now profile is current profile record if found==true // - check delete first if (!aMayAdd && !aMayUpdate) { // delete requested if (!found) return false; // does not exist if (np<2) return false; // only one profile left, do not delete // perform delete aCfgP->deleteProfile(pi); aActiveProfile=0; // re-activate profile 0 return true; } // - For update (modify or add): If profile not found AND... // ...if a default profile is specified -> overwrite first profile // ...if single-profile client -> overwrite the profile if (!found && aMayUpdate && aMayAdd && (def || maxprofiles==1) && np>0) { pi=0; // first is default aCfgP->getProfile(pi,profile); AssignCString(profile.profileName,pfnam.c_str(),maxnamesiz); found=true; } // - if not found and add not allowed or already too many profiles -> exit if (!found && (!aMayAdd || np>=maxprofiles)) return false; // nothing added // - if found, but update not allowed -> exit if (found && !aMayUpdate) return false; // nothing updated // Now, create new profile if we don't modify if (!found) { // - create new profile without default settings pi = aCfgP->newProfile(pfnam.c_str(),false); // - get the record aCfgP->getProfile(pi,profile); } // now set the params sInt32 ti=-1; // no target selected yet TARGETRECORD target; uInt32 profileID=aCfgP->getIDOfProfile(pi); // loop through params while (aParm!=NULL) { // get next tag aParm=nextTag(aParm,tag,value); // process tag if (tag=="db") { // save current target first, if any if (ti>=0) aCfgP->writeTarget(ti,target); // select new target by DB name sInt32 si=0; do { ti=aCfgP->findTargetIndex(profileID,si++); if (ti<0) break; // all checked, none found // check db name ti=aCfgP->getTarget(ti,target); } while(!(value==target.dbname)); } else if (tag=="uri") { // URI (or URI suffix) #ifdef HARD_CODED_SERVER_URI // - URI is fixed, so specified URI must be URI suffix (from old pre-2004 profiles) AssignCString(profile.URIpath,value.c_str(),maxpathsiz); #else // - URI can be set, except if config specifies a fixed URI if (aCfgP->fServerURI.empty()) AssignCString(profile.serverURI,value.c_str(),maxurisiz); #endif // setting URI resets the device to unknown SyncML version profile.lastSyncMLVersion=syncml_vers_unknown; } #ifdef PROTOCOL_SELECTOR else if (tag=="proto") { // Protocol selector profile.protocol = (TTransportProtocols)uint16Val(value.c_str()); if (profile.protocol>=num_transp_protos) profile.protocol=transp_proto_uri; } #endif else if (tag=="syncmlvers") { // initial SyncML version profile.lastSyncMLVersion = (TSyncMLVersions)uint16Val(value.c_str()); if (profile.lastSyncMLVersion>=numSyncMLVersions) profile.lastSyncMLVersion=syncml_vers_unknown; } else if (tag=="uripath") { // URI path AssignCString(profile.URIpath,value.c_str(),maxpathsiz); } else if (tag=="roflags") { // Read only flags profile.readOnlyFlags=uint16Val(value.c_str()); } else if (tag=="ftrflags") { // Feature flags profile.featureFlags=uint16Val(value.c_str()); } else if (tag=="dsflags") { // Datastore available flags profile.dsAvailFlags=uint16Val(value.c_str()); } else if (tag=="user") { // User AssignCString(profile.serverUser,value.c_str(),maxupwsiz); } else if (tag=="pwd") { // password assignMangledToCString(profile.serverPassword, value.c_str(), maxupwsiz,true); } else if (tag=="httpuser") { // User AssignCString(profile.transportUser,value.c_str(),maxupwsiz); } else if (tag=="httppwd") { // password assignMangledToCString(profile.transportPassword, value.c_str(), maxupwsiz,true); } else if (tag=="transpflags") { // transport related flags profile.transpFlags=uint32Val(value.c_str()); } else if (tag=="profileflags") { // general profile flags profile.transpFlags=uint32Val(value.c_str()); } #ifdef PROXY_SUPPORT else if (tag=="proxy") { // User AssignCString(profile.proxyHost,value.c_str(),maxurisiz); } else if (tag=="socks") { // User AssignCString(profile.socksHost,value.c_str(),maxurisiz); } else if (tag=="connproxy") { // use connection's proxy settings profile.useConnectionProxy=boolVal(value.c_str()); } else if (tag=="useproxy") { // use connection's proxy settings profile.useProxy=boolVal(value.c_str()); } else if (tag=="proxyuser") { // User AssignCString(profile.proxyUser,value.c_str(),maxupwsiz); } else if (tag=="proxypwd") { // password assignMangledToCString(profile.proxyPassword, value.c_str(), maxupwsiz,true); } #endif #ifdef AUTOSYNC_SUPPORT // Autosync activity schedule if (strucmp(tag.c_str(),"asl",3)==0) { // autosync level do { // - get level number if (tag.size()<5) break; // too short uInt8 lvl=tag[3]-0x30-1; // get level number 1..n and convert to 0-based index if (lvl>=NUM_AUTOSYNC_LEVELS) break; // invalid level number if (tag[4]!='_') break; // - level number found, check for subtag const char *subtag = tag.c_str()+5; if (strucmp(subtag,"mode")==0) { // autosync mode profile.AutoSyncLevel[lvl].Mode=(TAutosyncModes)uint16Val(value.c_str()); } else if (strucmp(subtag,"start")==0) { // start day time for autosync profile.AutoSyncLevel[lvl].StartDayTime=uint16Val(value.c_str()); } else if (strucmp(subtag,"end")==0) { // end day time for autosync profile.AutoSyncLevel[lvl].EndDayTime=uint16Val(value.c_str()); } else if (strucmp(subtag,"wdays")==0) { // weekdays for autosync (bit 0=Su, 1=Mo .. 6=Sa) profile.AutoSyncLevel[lvl].WeekdayMask=uint16Val(value.c_str()); } else if (strucmp(subtag,"charge")==0) { // charge level (% of full battery) profile.AutoSyncLevel[lvl].ChargeLevel=uint16Val(value.c_str()); } else if (strucmp(subtag,"mem")==0) { // min free mem level (% of total memory) profile.AutoSyncLevel[lvl].MemLevel=uint16Val(value.c_str()); } else if (strucmp(subtag,"flags")==0) { // extra flags profile.AutoSyncLevel[lvl].Flags=uint16Val(value.c_str()); } } while(false); } // aslvlN_xxxx #ifdef IPP_SUPPORT else if (strucmp(tag.c_str(),"ipp_",4)==0) { // IPP parameters, parse rest after ipp_ prefix aCfgP->ipp_setparam(tag.c_str()+4,value.c_str(),profile.ippSettings); } #endif // Timed sync schedule else if (tag=="ts_mobile") { // interval (minutes) for mobile timed sync profile.TimedSyncMobilePeriod=uint16Val(value.c_str()); } else if (tag=="ts_cradled") { // interval (minutes) for cradled timed sync profile.TimedSyncCradledPeriod=uint16Val(value.c_str()); } #endif else if (ti>=0) { // target-level settings if (tag=="enabled") { // enabled target.enabled = value=="1"; } else if (tag=="slow") { // force slowsync target.forceSlowSync = value=="1"; } else if (tag=="mode" && value.size()>=1) { // mode: 0=twoway, 1=fromserver, 2=fromclient uInt8 m=value[0]-0x30; if (m<=2) target.syncmode = (TSyncModes)m; } else if (tag=="path") { // remote DB path AssignCString(target.remoteDBpath,value.c_str(),remoteDBpathMaxLen); } #if TARGETS_DB_VERSION>5 else if (tag=="remoteFilters") { // remote DB path AssignCString(target.remoteFilters,value.c_str(),filterExprMaxLen); } else if (tag=="localFilters") { // remote DB path AssignCString(target.remoteFilters,value.c_str(),filterExprMaxLen); } #endif else if (tag=="ext") { // extras StrToULong(value.c_str(), target.extras); } else if (tag=="lim1") { // limit1 StrToLong(value.c_str(), target.limit1); } else if (tag=="lim2") { // limit2 StrToLong(value.c_str(), target.limit2); } } // if target selected } // while more tags // save open target if any if (ti>=0) aCfgP->writeTarget(ti,target); // save profile aCfgP->writeProfile(pi,profile); aActiveProfile=pi; // return changed or added profile number return true; } // configProfile // Configure registration // cmd="reg";text="name ::m=manufacturer";key="ABCD-EFGH-KIJL-1234"; static bool configRegistration(const char *aRegParams, TSyncAppBase *aAppBaseP) { #ifdef SYSER_REGISTRATION string tag,text,key; // get text aRegParams = nextTag(aRegParams,tag,text); if (!(tag=="text")) return false; // get key if (!aRegParams) return false; aRegParams = nextTag(aRegParams,tag,key); if (!(tag=="key")) return false; // apply registration return aAppBaseP->checkAndSaveRegInfo(text.c_str(), key.c_str())==LOCERR_OK; #else return false; // no registration possible #endif } // configRegistration // generic code that can work as palmdbagent or binfiledbagent method // - Provisioning string format: tag="value"[;tag="value"].... // - commands: // - add : only adds a profile, does nothing if already existing or // with single-profile-client. // - update : adds new or updates existing profile, if defpf is used // or with single-profile client, the first profile will be // updated (overwritten) // - modify : only modifies profile with specified name, never overwrites // another profile. // - delete : deletes profile with specified name (except if it is only // profile left) // - reg : apply license information bool CLIENTAGENTCONFIG::executeProvisioningString(const char *aProvisioningCmd, sInt32 &aActiveProfile) { string tag,value; const char *p=aProvisioningCmd; // get command tag p=nextTag(p,tag,value); if (!p) return false; // first tag must be "cmd" if (!(tag=="cmd")) return false; // dispatch commands if (value=="reg") { // registration return configRegistration(p,getSyncAppBase()); } else if (value=="add") { // add new profile if not already there return configProfile(this,p,true,false,aActiveProfile); // may add but may not update } else if (value=="update") { // update or add profile return configProfile(this,p,true,true,aActiveProfile); // may add and update } else if (value=="modify") { // only modify existing return configProfile(this,p,false,true,aActiveProfile); // may not add but may update } else if (value=="delete") { // delete existing return configProfile(this,p,false,false,aActiveProfile); // neither add nor update = delete } else return false; // unknown command } // CLIENTAGENTCONFIG::executeProvisioningString /* eof */ libsynthesis-3.4.0.47.1/src/sysync/clientprovisioning_inc.h000077500000000000000000000004661226375725500237230ustar00rootroot00000000000000/* * File: clientprovisioning_inc.h * */ // macro to declare clientprovisioning methods and fields #define CLIENTPROVISIONING_CLASSDECL \ public: \ /* - execute remote provisioning command */ \ bool executeProvisioningString(const char *aProvisioningCmd, sInt32 &aActiveProfile); /* eof */ libsynthesis-3.4.0.47.1/src/sysync/configelement.cpp000077500000000000000000001002731226375725500223140ustar00rootroot00000000000000/* * File: ConfigElement.cpp * * Author: Lukas Zeller (luz@plan44.ch) * * TConfigElement * Element of hierarchical configuration * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * 2001-11-14 : luz : created */ // includes #include "prefix_file.h" #include "sysync.h" #include "configelement.h" #include "syncappbase.h" #include "scriptcontext.h" #include "multifielditem.h" #include "sysync_crc16.h" #include "vtimezone.h" using namespace sysync; #ifndef RELEASE_VERSION // if defined, parsing debug info goes to console //#define CONSDEBUG #endif #ifdef CONSDEBUG #define CONSDBGPRINTF(m) CONSOLEPRINTF(m) const char * const ParseModeNames[numParseModes] = { "element", // normal, expecting sub-elements "nested", // like pamo_element, but scanning nested elements in same TConfigElement "delegated", // I have delegated parsing of a single sub-element of mine to another element (without XML nesting) "end", // expecting end of element "endnested", // expecting end of nested element (i.e. will call nestedElementEnd()) "all", // read over all content "string", // string, but with all WSP converted to space and removed at beginning an end "rawstring", // string without any changes "cstring", // string with \\, \t,\n,\r and \xXX escape conversion "macrostring", // string which can contain macros to substitute config vars in $xxx or $() format #ifdef SCRIPT_SUPPORT "script", // tokenized script "functiondef", // script function definition #endif "field", "path", // string is updated such that a filename can be appended directly "boolean", "tristate", "timestamp", "timezone", "vtimezone", "idcode", "char", "int64", "int32", "int16", "enum1by", "enum2by", "enum4by" }; #else #define CONSDBGPRINTF(m) #endif /* * Implementation of TConfigElement */ /* public TConfigElement members */ TConfigElement::TConfigElement(const char *aElementName, TConfigElement *aParentElementP) { // set element name fElementName=aElementName; fResolveImmediately=false; // by default, elements do not resolve immediately, but when entire config is read // set parent and root element pointers fParentElementP=aParentElementP; if (fParentElementP) { // has parent, get root from parent fRootElementP=fParentElementP->getRootElement(); } else { // base element cannot be root fRootElementP=NULL; } #ifndef HARDCODED_CONFIG // init parsing ResetParsing(); #endif fCfgVarExp=0; } // TConfigElement::TConfigElement TConfigElement::~TConfigElement() { clear(); } // TConfigElement::~TConfigElement TSyncAppBase *TConfigElement::getSyncAppBase(void) { return fRootElementP ? fRootElementP->fSyncAppBaseP : NULL; } // TConfigElement::getSyncAppBase // - convenience version for getting time lineartime_t TConfigElement::getSystemNowAs(timecontext_t aContext) { return sysync::getSystemNowAs(aContext,getSyncAppBase()->getAppZones()); } // TConfigElement::getSystemNowAs #ifndef HARDCODED_CONFIG // static helper, returns attribute value or NULL if none const char *TConfigElement::getAttr(const char **aAttributes, const char *aAttrName) { if (!aAttributes) return NULL; const char *attname; while ((attname=*aAttributes)!=0) { if (strucmp(attname,aAttrName)==0) { return *(++aAttributes); // found, return value } aAttributes+=2; // skip value, go to next name } return NULL; // not found } // TConfigElement::getAttr // get attribute value, check for macro expansion // @param aDefaultExpand : if set, non-recursive expansion is done anyway, otherwise, a "expand" attribute is required bool TConfigElement::getAttrExpanded(const char **aAttributes, const char *aAttrName, string &aValue, bool aDefaultExpand) { cAppCharP val = getAttr(aAttributes, aAttrName); if (!val) return false; // no value aValue = val; getSyncAppBase()->expandConfigVars(aValue, aDefaultExpand ? 1 : fCfgVarExp, this, getName()); return true; } // TConfigElement::getAttrExpanded // static helper, returns true if attribute has valid (or none, if aOpt) bool value bool TConfigElement::getAttrBool(const char **aAttributes, const char *aAttrName, bool &aBool, bool aOpt) { const char *v = getAttr(aAttributes,aAttrName); if (!v) return aOpt; // not existing, is ok if optional return StrToBool(v,aBool); } // TConfigElement::getAttrBool // static helper, returns true if attribute has valid (or none, if aOpt) short value bool TConfigElement::getAttrShort(const char **aAttributes, const char *aAttrName, sInt16 &aShort, bool aOpt) { const char *v = getAttr(aAttributes,aAttrName); if (!v) return aOpt; // not existing, is ok if optional return StrToShort(v,aShort); } // TConfigElement::getAttrShort // static helper, returns true if attribute has valid (or none, if aOpt) short value bool TConfigElement::getAttrLong(const char **aAttributes, const char *aAttrName, sInt32 &aLong, bool aOpt) { const char *v = getAttr(aAttributes,aAttrName); if (!v) return aOpt; // not existing, is ok if optional return StrToLong(v,aLong); } // TConfigElement::getAttrLong #ifdef SCRIPT_SUPPORT sInt16 TConfigElement::getFieldIndex(cAppCharP aFieldName, TFieldListConfig *aFieldListP, TScriptContext *aScriptContextP) { // fields or local script variables (if any) can be mapped if (aScriptContextP) return aScriptContextP->getIdentifierIndex(OBJ_AUTO, aFieldListP,aFieldName); else return aFieldListP ? aFieldListP->fieldIndex(aFieldName) : VARIDX_UNDEFINED; } #else sInt16 TConfigElement::getFieldIndex(cAppCharP aFieldName, TFieldListConfig *aFieldListP) { // only direct mapping of MultiFieldItem fields return aFieldListP ? aFieldListP->fieldIndex(aFieldName) : VARIDX_UNDEFINED; } #endif #endif // HARDCODED_CONFIG void TConfigElement::clear(void) { // nop } // TConfigElement::clear // resolve (finish after all data is parsed) void TConfigElement::Resolve(bool aLastPass) { #ifndef HARDCODED_CONFIG // Only resolve if element was not already resolved when it finished parsing // or if it was not parsed at all (that is, it did not appear in the config // at all and only contains default values) if (!fResolveImmediately || !fCompleted) { // try to finally resolve private stuff now that all children are resolved localResolve(aLastPass); } #else // hardcoded config is never resolved early localResolve(aLastPass); #endif }; // TConfigElement::Resolve #ifdef SYDEBUG TDebugLogger *TConfigElement::getDbgLogger(void) { // commands log to session's logger TSyncAppBase *appBase = getSyncAppBase(); return appBase ? appBase->getDbgLogger() : NULL; } // TConfigElement::getDbgLogger uInt32 TConfigElement::getDbgMask(void) { TSyncAppBase *appBase = getSyncAppBase(); if (!appBase) return 0; // no session, no debug return appBase->getDbgMask(); } // TConfigElement::getDbgMask #endif #ifndef HARDCODED_CONFIG void TConfigElement::ResetParsing(void) { fChildParser=NULL; fParseMode=pamo_element; // expecting elements fNest=0; // normal elements start with Nest=0 fExpectAllNestStart=-1; // no expectAll called yet fCompleted=false; // not yet completed parsing fTempString.erase(); // nothing accumulated yet #ifdef SYSER_REGISTRATION fLockedElement=false; fHadLockedSubs=false; #endif } // TConfigElement::ResetParsing(void) // report error void TConfigElement::ReportError(bool aFatal, const char *aMessage, ...) { const sInt32 maxmsglen=1024; char msg[maxmsglen]; va_list args; msg[0]='\0'; va_start(args, aMessage); char *p = msg; int n=0; // show fatal flag if (aFatal) { strcat(p,"Fatal: "); n=strlen(p); p+=n; } // assemble the message string vsnprintf(p, maxmsglen-n, aMessage, args); va_end(args); // set the message TRootConfigElement *rootP = getRootElement(); if (!rootP) SYSYNC_THROW(TConfigParseException("Element without root")); rootP->setError(aFatal,msg); } // TConfigElement::ReportError // fail in parsing (short form of ReportError) bool TConfigElement::fail(const char *aMessage, ...) { const sInt32 maxmsglen=1024; char msg[maxmsglen]; va_list args; msg[0]='\0'; va_start(args, aMessage); // assemble the message string vsnprintf(msg, maxmsglen, aMessage, args); va_end(args); // report the error ReportError(true,msg); // skip the rest expectAll(); // return value return true; } // TConfigElement::fail // start of element, this config element decides who processes this element bool TConfigElement::startElement(const char *aElementName, const char **aAttributes, sInt32 aLine) { if (fChildParser) { // parsing in a sub-level, delegate return fChildParser->startElement(aElementName,aAttributes,aLine); } else { CONSDBGPRINTF(( "'%s' starts in configElement='%s' with parsemode='%s' nest=%hd at source line=%ld", aElementName, getName(), ParseModeNames[fParseMode], fNest, aLine )); if (fParseMode==pamo_all) { // read over contents, no matter what is inside fNest++; return true; } #ifdef SYSER_REGISTRATION // check for locked elements or subtrees // - copy parent's lock status if (getParentElement()) fLockedElement=getParentElement()->fLockedElement; // - if not already locked, see if locked section starts with this element if (!fLockedElement) { getAttrBool(aAttributes,"locked",fLockedElement,true); } // Perform CRC sum if locked element if (fLockedElement) { CONSDBGPRINTF(( "'%s' is locked and is included in LockCRC = 0x%04hX", aElementName, getRootElement()->getConfigLockCRC() )); // CRC over opening element name getRootElement()->addToLockCRC(aElementName); // CRC over all attributes if (aAttributes) { const char **attrs=aAttributes; const char *attelem; while ((attelem=*attrs++)!=0) { // alternating names and values getRootElement()->addToLockCRC(attelem); } } } #endif // check conditional parsing bool condmet=true; // assume parsing cAppCharP cond; string vv,val; // check platform filter if (condmet) { cAppCharP pf=getAttr(aAttributes,"platform"); if (pf && strucmp(pf,SYSYNC_PLATFORM_NAME)!=0) { // tag is not for this platform, ignore condmet=false; } } // check for config var conditionals if (condmet) { cond=getAttr(aAttributes,"if"); if (cond) { // check for value comparison string nam; // - determine comparison cAppCharP p2,p = cond; int cmpres = 2; // 2: invalid, 1: var > cond, -1: var < cond, 0: var=cond bool neg=false; appChar c; while ((c=*p)) { p2=p++; if (c=='=') { if (*p=='=') p++; // = and == are equivalent cmpres=0; // must be equal break; } else if (c=='!' && *p=='=') { p++; cmpres=0; neg=true; // must not be equal break; } else if (c=='>') { if (*p=='=') { p++; cmpres=-1; // var >= cond is equal to NOT val < cond neg=true; } else { cmpres=1; // var > cond } break; } else if (c=='<') { if (*p=='=') { p++; cmpres=1; // var <= cond is equal to NOT val > cond neg=true; } else { cmpres=-1; // var < cond } break; } } // now value is at *p or we have not found a comparison op if (cmpres<2) { nam.assign(cond,p2-cond); val=p; } else { nam=cond; val.erase(); } // get var - if it does not exist, comparison always renders false if (nam=="version") { // special comparison mode for version // - parse reference into version components uInt16 maj=0,min=0,rev=0,bld=0; p = val.c_str(); do { p+=StrToUShort(p,maj); if (*p++!='.') break; p+=StrToUShort(p,min); if (*p++!='.') break; p+=StrToUShort(p,rev); if (*p++!='.') break; p+=StrToUShort(p,bld); } while(false); // - compare with hexversion StringObjPrintf(val,"%02X%02X%02X%02X",maj,min,rev,bld); nam="hexversion"; } // get config var to perform condition check condmet=getSyncAppBase()->getConfigVar(nam.c_str(),vv); if (condmet) { // var exists, perform comparison if (cmpres>=2) { // no comparison, but just boolean check. Non-bool but empty=false, non-bool-non-empty=true condmet = !vv.empty(); if (condmet) StrToBool(vv.c_str(), condmet); } else { int res = strcmp(vv.c_str(),val.c_str()); res = res>0 ? 1 : (res<0 ? -1 : 0); condmet = neg != (cmpres==res); } } } } // check for ifdef if (condmet) { cond=getAttr(aAttributes,"ifdef"); if (cond) condmet = getSyncAppBase()->getConfigVar(cond,vv); } // check for ifndef if (condmet) { cond=getAttr(aAttributes,"ifndef"); if (cond) condmet = !getSyncAppBase()->getConfigVar(cond,vv); } // skip this tag if conditions not met if (!condmet) { // skip everything inside CONSDBGPRINTF(("Condition for parsing not met - skipping tag")); expectAll(); return true; // ok, go on } // Now we know that we must actually parse this tag // check configvar expansion mode fCfgVarExp=0; // default to automatic (i.e. certain content such as paths or macrostrings will be expanded without "expand" attr) cAppCharP cm=getAttr(aAttributes,"expand"); if (cm) { // explicit expand directive for this tag (includes expandable attributes of this tag, // but only attributes queried with getAttrExpanded() can expand at all) bool b; if (strucmp(cm,"single")==0) fCfgVarExp=1; else if (StrToBool(cm,b)) fCfgVarExp = b ? 2 : -1; } // check for use-everywhere special tags if (strucmp(aElementName,"configmsg")==0) { bool iserr=true; cAppCharP msg=getAttr(aAttributes,"error"); if (!msg) { msg=getAttr(aAttributes,"warning"); iserr=false; } if (!msg) msg="Error: found "; ReportError(iserr,msg); expectAll(); return false; // generate error message } // check if we are re-entering the same object again (trying to overwrite) if (fCompleted) { ReportError(true,"Duplicate definition of <%s>",aElementName); expectAll(); return false; // not allowed, generate error message } if (fParseMode==pamo_element || fParseMode==pamo_nested) { // expecting element fTempString.erase(); if (localStartElement(aElementName,aAttributes,aLine)) { // element known and parsing initialized ok #ifdef SYSER_REGISTRATION if (fLockedElement && fChildParser==NULL && fParseMode!=pamo_element && fParseMode!=pamo_nested) fHadLockedSubs=true; // flag that this element has processed non-child subelements in locked mode #endif return true; } else { // unknown element: read over all its contents ReportError(false,"invalid tag <%s>",aElementName); expectAll(); return false; // element not known, generate error message } } /* %%% moved up to beginning else if (fParseMode==pamo_all) { // read over contents fNest++; } */ else { ReportError(false,"no XML tag expected here"); } return true; } } // TConfigElement::startElement // character data of current element void TConfigElement::charData(const char *aCharData, sInt32 aNumChars) { if (fChildParser) { // parsing in a sub-level, delegate return fChildParser->charData(aCharData,aNumChars); } else { if (fParseMode==pamo_all /* %%% not needed, I think || fNest>0 */) { // just ignore } else if (fParseMode==pamo_element || fParseMode==pamo_nested || fParseMode==pamo_end || fParseMode==pamo_endnested) { // only whitespace allowed here while (aNumChars--) { if (!isspace(*aCharData++)) { ReportError(false,"no character data expected"); break; } } } else { // accumulate char data in string fTempString.append(aCharData,aNumChars); } } } // TConfigElement::charData // read over all contents of current TConfigElement void TConfigElement::expectAll(void) { // we are already in an element but have no non-decrementing // parse mode set like expectEmpty() or expectString() etc. // so nest count must be incremented to balance decrement occurring // at next element end. fExpectAllNestStart = fParseMode==pamo_nested ? fNest : -1; // remember where we left nested mode and entered ignoring mode fNest++; fParseMode=pamo_all; } // TConfigElement::expectAll // expect Enum element void TConfigElement::expectEnum(sInt16 aDestSize,void *aPtr, const char * const aEnumNames[], sInt16 aNumEnums) { // save params fParseEnumArray = aEnumNames; fParseEnumNum = aNumEnums; // determine mode and destination switch (aDestSize) { case 1 : fParseMode=pamo_enum1by; fResultPtr.fCharP=(char *)aPtr; break; case 2 : fParseMode=pamo_enum2by; fResultPtr.fShortP=(sInt16 *)aPtr; break; case 4 : fParseMode=pamo_enum4by; fResultPtr.fLongP=(sInt32 *)aPtr; break; default: SYSYNC_THROW(TConfigParseException("expectEnum: invalid enum size")); } } // TConfigElement::expectEnum // delegate parsing of a single element to another config element // after processing aElementName and all subtags, processing will return to this object // (rather than waiting for an end tag in aConfigElemP) bool TConfigElement::delegateParsingTo(TConfigElement *aConfigElemP, const char *aElementName, const char **aAttributes, sInt32 aLine) { if (aConfigElemP) { expectChildParsing(*aConfigElemP); fParseMode=pamo_delegated; // let child parse the current tag right away return aConfigElemP->localStartElement(aElementName,aAttributes,aLine); } else return false; // if we have no delegate, we can't understand this tag } // TConfigElement::delegateParsingTo // end of element, returns true when this config element is done parsing bool TConfigElement::endElement(const char *aElementName, bool aIsDelegated) { if (fChildParser) { // parsing in a real or simulated (delegateParsingTo) sub-level if (fChildParser->endElement(aElementName,fParseMode==pamo_delegated)) { // child has finished parsing fChildParser=NULL; // handle next element myself if (aIsDelegated) { // - we were delegated to process a single element from another element. // So, we nust not continue parsing here, but pass back to parent // for next element return true; } // otherwise, wait here for next element to start (or encosing element to end) fParseMode=pamo_element; // expect another element or end of myself } else { // child is still parsing, so am I return false; } } else { CONSDBGPRINTF(( "'%s' ends in configElement='%s' with parsemode='%s' nest=%hd, aIsDelegated=%d", aElementName, getName(), ParseModeNames[fParseMode], fNest, aIsDelegated )); #ifdef SYSER_REGISTRATION // Perform CRC sum if locked element if (fLockedElement) { // CRC over CharData getRootElement()->addToLockCRC(fTempString.c_str()); } #endif const char *p; // BCPPB: declaring vars in case does not work. size_t n,lnwsp; bool hlp; timecontext_t tctx; // expand macros in string first if (fCfgVarExp==0) { // auto mode fCfgVarExp = fParseMode==pamo_path || fParseMode==pamo_macrostring ? 2 : -1; } // do config variable expansion now (or not, according to fCfgVarExp) getSyncAppBase()->expandConfigVars(fTempString,fCfgVarExp,this,aElementName); // now parse switch (fParseMode) { case pamo_end: case pamo_endnested: if (fNest>0) { // Note: normal empty elements are NOT considered nested elements by default, only if // they request endnested mode explicitly if (fParseMode==pamo_endnested) nestedElementEnd(); // inform possible parser of nested element that a nested element ends here // back to nested fParseMode=pamo_nested; } else fParseMode=pamo_element; // back to normal element parsing return false; // do not exit case pamo_all: case pamo_nested: if (fNest>0) { // not yet finished with startlevel, continue with pamo_all/pamo_nested fNest--; if (fExpectAllNestStart>0) { // we are in expectAll mode within pamo_nested if(fNest==fExpectAllNestStart) { // reached level where we started ignoring contents before fExpectAllNestStart = -1; // processed now fParseMode = pamo_nested; // back to nested (but active) parsing, like in Mime-Dir profile } else { // NOP here - do NOT call nestedElementEnd() } } else { // end of active nested element nestedElementEnd(); // inform possible parser of nested element if (fNest==0) { // if back on nest level 0, switch to pamo_element fParseMode = pamo_element; } } return false; // stay in this element } // nested or all at level 0 cause handling like pamo_element case pamo_element: // end of element while looking for elements: // this is end of this config element itself // - flag completion of this element fCompleted=true; // prevents re-entry // Resolve if this is element says it is self-contained (no references to other elements // that might follow later in the config file) if (fResolveImmediately) { // resolve element NOW, last pass localResolve(true); } // - return parsing authority to caller return true; case pamo_cstring: // interpret C-type escapes (only \t,\r,\n and \xXX, no octal) #ifdef SYSER_REGISTRATION if (fHadLockedSubs && !fResultPtr.fStringP->empty()) ReportError(true,"Duplicate definition of <%s>",aElementName); #endif fResultPtr.fStringP->erase(); CStrToStrAppend(fTempString.c_str(), *(fResultPtr.fStringP)); break; case pamo_string: case pamo_macrostring: case pamo_path: #ifdef SYSER_REGISTRATION if (fHadLockedSubs && !fResultPtr.fStringP->empty()) ReportError(true,"Duplicate definition of <%s>",aElementName); #endif // remove spaces at beginning and end fResultPtr.fStringP->erase(); p = fTempString.c_str(); // - skip leading spaces while (*p && isspace(*p)) ++p; // - copy chars and convert all wsp to spaces n=0; lnwsp=0; while (*p) { ++n; // count char if (isspace(*p)) fResultPtr.fStringP->append(" "); else { fResultPtr.fStringP->append(p,1); lnwsp=n; // remember last non-whitespace } ++p; } // - remove trailing spaces fResultPtr.fStringP->resize(lnwsp); // - if path requested, shape it up if needed if (fParseMode==pamo_path) { makeOSDirPath(*(fResultPtr.fStringP)); } break; case pamo_rawstring: #ifdef SYSER_REGISTRATION if (fHadLockedSubs && !fResultPtr.fStringP->empty()) ReportError(true,"Duplicate definition of <%s>",aElementName); #endif (*(fResultPtr.fStringP))=fTempString; break; case pamo_field: #ifdef SCRIPT_SUPPORT *(fResultPtr.fShortP) = getFieldIndex(fTempString.c_str(),fFieldListP,fScriptContextP); #else *(fResultPtr.fShortP) = getFieldIndex(fTempString.c_str(),fFieldListP); #endif break; #ifdef SCRIPT_SUPPORT case pamo_script: case pamo_functiondef: SYSYNC_TRY { if (fParseMode==pamo_functiondef) TScriptContext::TokenizeAndResolveFunction(getSyncAppBase(),fExpectLine,fTempString.c_str(),(*(fResultPtr.fFuncDefP))); else { #ifdef SYSER_REGISTRATION if (fHadLockedSubs && !fResultPtr.fStringP->empty()) ReportError(true,"Duplicate definition of <%s>",aElementName); #endif TScriptContext::Tokenize(getSyncAppBase(),aElementName,fExpectLine,fTempString.c_str(),(*(fResultPtr.fStringP)),fExpectContextFuncs,false,fExpectNoDeclarations); } } SYSYNC_CATCH (exception &e) ReportError(true,"Script Error: %s",e.what()); SYSYNC_ENDCATCH break; #endif case pamo_timestamp: // expect timestamp, store as UTC if (ISO8601StrToTimestamp(fTempString.c_str(), *(fResultPtr.fTimestampP), tctx)==0) ReportError(false,"bad ISO8601 timestamp value"); if (TCTX_IS_UNKNOWN(tctx)) tctx=TCTX_SYSTEM; TzConvertTimestamp(*(fResultPtr.fTimestampP),tctx,TCTX_UTC,getSyncAppBase()->getAppZones()); break; case pamo_timezone: // time zone by name (internal or olson) if (!TimeZoneNameToContext(fTempString.c_str(), *(fResultPtr.fTimeContextP), getSyncAppBase()->getAppZones(), true)) ReportError(false,"invalid/unknown timezone name"); break; case pamo_vtimezone: // definition of custom time zone in vTimezone format if (!VTIMEZONEtoInternal(fTempString.c_str(), tctx, fResultPtr.fGZonesP, getDbgLogger())) ReportError(false,"invalid vTimezone defintion"); break; case pamo_boolean: if (!StrToBool(fTempString.c_str(),*(fResultPtr.fBoolP))) ReportError(false,"bad boolean value"); break; case pamo_tristate: if (fTempString.empty() || fTempString=="unspecified" || fTempString=="default") *(fResultPtr.fByteP)=-1; // unspecified else { if (!StrToBool(fTempString.c_str(),hlp)) ReportError(false,"bad boolean value"); else *(fResultPtr.fByteP)= hlp ? 1 : 0; } break; case pamo_int64: if (!StrToLongLong(fTempString.c_str(),*(fResultPtr.fLongLongP))) ReportError(false,"bad integer (64bit) value"); break; case pamo_int32: if (!StrToLong(fTempString.c_str(),*(fResultPtr.fLongP))) ReportError(false,"bad integer (32bit) value"); break; case pamo_char: if (fTempString.size()>1) ReportError(false,"single char or nothing (=NUL char) expected"); if (fTempString.size()==0) *(fResultPtr.fCharP) = 0; else *(fResultPtr.fCharP) = fTempString[0]; break; case pamo_idCode: // Palm/MacOS-type 4-char code if (fTempString.size()!=4) ReportError(false,"id code must be exactly 4 characters"); *(fResultPtr.fLongP) = ((uInt32)fTempString[0] << 24) + ((uInt32)fTempString[1] << 16) + ((uInt16)fTempString[2] << 8) + ((uInt8)fTempString[3]); break; case pamo_int16: if (!StrToShort(fTempString.c_str(),*(fResultPtr.fShortP))) ReportError(false,"bad integer (16bit) value"); break; case pamo_enum1by: case pamo_enum2by: case pamo_enum4by: sInt16 tempenum; if (!StrToEnum(fParseEnumArray,fParseEnumNum,tempenum,fTempString.c_str())) ReportError(false,"bad enumeration value '%s'",fTempString.c_str()); else { // now assign enum if (fParseMode==pamo_enum1by) *fResultPtr.fCharP = tempenum; else if (fParseMode==pamo_enum2by) *fResultPtr.fShortP = tempenum; else if (fParseMode==pamo_enum4by) *fResultPtr.fLongP = tempenum; } break; default: SYSYNC_THROW(TConfigParseException(DEBUGTEXT("Unknown parse mode","ce1"))); } // normal case: end of simple element parsed at same level as parent if (aIsDelegated) { // - we were delegated to process a single element from another element. // So, we nust not continue parsing here, but pass back to parent // for next element return true; } else { // - expect next element fParseMode=pamo_element; } } // end of embedded element, but not of myself #ifdef SYSER_REGISTRATION #ifdef CONSDEBUG if (fLockedElement) { CONSDBGPRINTF(( "'%s' was locked and was included in LockCRC = 0x%04hX", aElementName, getRootElement()->getConfigLockCRC() )); } #endif // - back to parent's lock status (or false if no parent) fLockedElement=getParentElement() ? getParentElement()->fLockedElement : false; #endif // do not return to parent config element return false; } // TConfigElement::endElement // reset error void TRootConfigElement::resetError(void) { fError=false; fErrorMessage.erase(); } // TRootConfigElement::ResetError // set error void TRootConfigElement::setError(bool aFatal, const char *aMsg) { if (!fErrorMessage.empty()) fErrorMessage += '\n'; // multiple messages on multiple lines fErrorMessage.append(aMsg); if (aFatal && fFatalError==LOCERR_OK) fFatalError=LOCERR_CFGPARSE; // this is a config parse error fError=true; } // TRootConfigElement::setError // check for error message const char *TRootConfigElement::getErrorMsg(void) { if (!fError) return NULL; return fErrorMessage.c_str(); } // TRootConfigElement::GetErrorMsg // reset parsing (=reset error and fatal errors) void TRootConfigElement::ResetParsing(void) { resetError(); fDocStarted=false; fFatalError=LOCERR_OK; #ifdef SYSER_REGISTRATION fLockCRC=0; // no CRC lock sum yet #endif TConfigElement::ResetParsing(); } // TRootConfigElement::ResetParsing #endif // resolve config tree and catch errors bool TRootConfigElement::ResolveAll(void) { SYSYNC_TRY { Resolve(true); return true; } SYSYNC_CATCH (TConfigParseException &e) #ifndef HARDCODED_CONFIG ReportError(true,e.what()); #endif return false; SYSYNC_ENDCATCH } // TRootConfigElement::ResolveAll #ifndef HARDCODED_CONFIG // start of element, this config element decides who processes this element bool TRootConfigElement::startElement(const char *aElementName, const char **aAttributes, sInt32 aLine) { if (!fDocStarted) { // document not yet started if (strucmp(aElementName,XMLCONFIG_DOCNAME)==0) { // check version const char* vers = getAttr(aAttributes,"version"); if (!vers) { ReportError(true,"Missing version attribute for document"); expectAll(); // ignore everything } else if (strucmp(vers,XMLCONFIG_DOCVERSION)!=0) { ReportError(true, "Bad config document version (expected %s, found %s)", XMLCONFIG_DOCVERSION, vers ); expectAll(); // ignore everything inside that element } fDocStarted=true; // started normally return true; } else { // invalid element return false; } } else { return TConfigElement::startElement(aElementName,aAttributes,aLine); } } // TRootConfigElement::startElement #ifdef SYSER_REGISTRATION // add config text to locking CRC void TRootConfigElement::addToLockCRC(const char *aCharData, size_t aNumChars) { size_t n = aNumChars ? aNumChars : strlen(aCharData); char c; bool lastwasctrl=false; while (n--) { c=*aCharData++; // compact multiple whitespace to single char if ((uInt8)c<=' ') { if (lastwasctrl) continue; lastwasctrl=true; // treat them all as spaces c=' '; } else { lastwasctrl=false; // this is a non-space } // add to CRC fLockCRC=sysync::sysync_crc16(fLockCRC,(uInt8)c); } } // TRootConfigElement::addToLockCRC #endif #endif // no hardcode config /* end of TConfigElement implementation */ // eof libsynthesis-3.4.0.47.1/src/sysync/configelement.h000077500000000000000000000270301226375725500217600ustar00rootroot00000000000000/* * File: ConfigElement.h * * Author: Lukas Zeller (luz@plan44.ch) * * TConfigElement * Element of hierarchical configuration * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * 2001-11-14 : luz : created */ #ifndef ConfigElement_H #define ConfigElement_H #include "prefix_file.h" #include "sysync.h" #include "syncexception.h" #include "sysync_globs.h" namespace sysync { // forward class TConfigElement; class TDebugLogger; // parse modes typedef enum { pamo_element, // normal, expecting sub-elements pamo_nested, // like pamo_element, but scanning nested elements in same TConfigElement pamo_delegated, // I have delegated parsing of a single sub-element of mine to another element (without XML nesting) pamo_end, // expecting end of element (empty element) pamo_endnested, // expecting end of nested element (i.e. will call nestedElementEnd()) pamo_all, // read over all content pamo_string, pamo_cstring, pamo_rawstring, pamo_macrostring, // string which can contain macros to substitute config vars in $xxx or $() format #ifdef SCRIPT_SUPPORT pamo_script, pamo_functiondef, #endif pamo_field, // field ID pamo_path, // string is updated such that a filename can be appended directly, otherwise like pamo_macrostring pamo_boolean, pamo_tristate, pamo_timestamp, pamo_timezone, // time zone name pamo_vtimezone, // time zone definition in vTimezone format pamo_idCode, pamo_char, pamo_int64, pamo_int32, pamo_int16, pamo_enum1by, pamo_enum2by, pamo_enum4by, numParseModes } TCfgParseMode; class TConfigParseException : public TSyncException { typedef TSyncException inherited; public: TConfigParseException(const char *aMsg1) : TSyncException(aMsg1) {}; }; // TConfigParseException class TRootConfigElement; // forward class TFieldListConfig; #ifdef SCRIPT_SUPPORT class TUserScriptFunction; class TScriptContext; #endif class TSyncAppBase; // forward class TConfigElement { public: // constructor TConfigElement(const char *aElementName, TConfigElement *aParentElementP); virtual ~TConfigElement(); virtual void clear(void); // remove all dynamic elements, reset to default values // - called when all parsing is done, intended for cross-element links void Resolve(bool aLastPass); // - called when app should save its persistent state virtual void saveAppState(void) { /* nop by default */}; #ifndef HARDCODED_CONFIG // Sax parsing // - report parsing error (may only be called from within parsing methods) void ReportError(bool aFatal, const char *aMessage, ...); bool fail(const char *aMessage, ...); // - start of element, this config element decides who processes this element virtual bool startElement(const char *aElementName, const char **aAttributes, sInt32 aLine); // - character data of current element void charData(const char *aCharData, sInt32 aNumChars); // - end of element, returns true when this config element is done parsing bool endElement(const char *aElementName, bool aIsDelegated=false); #endif // access to nodes // - root node TRootConfigElement *getRootElement(void) { return fRootElementP; }; // - parent node, NULL if none TConfigElement *getParentElement(void) { return fParentElementP; }; // - get sync app base (application root) TSyncAppBase *getSyncAppBase(void); // - convenience version for getting time lineartime_t getSystemNowAs(timecontext_t aContext); // - name const char *getName(void) { return fElementName.c_str(); }; // Public properties // - name of element string fElementName; #ifndef HARDCODED_CONFIG // helpers for attributes static const char *getAttr(const char **aAttributes, const char *aAttrName); bool getAttrExpanded(const char **aAttributes, const char *aAttrName, string &aValue, bool aDefaultExpand); static bool getAttrBool(const char **aAttributes, const char *aAttrName, bool &aBool, bool aOpt=false); static bool getAttrShort(const char **aAttributes, const char *aAttrName, sInt16 &aShort, bool aOpt=false); static bool getAttrLong(const char **aAttributes, const char *aAttrName, sInt32 &aLong, bool aOpt=false); #ifdef SCRIPT_SUPPORT static sInt16 getFieldIndex(cAppCharP aFieldName, TFieldListConfig *aFieldListP, TScriptContext *aScriptContextP=NULL); #else static sInt16 getFieldIndex(cAppCharP aFieldName, TFieldListConfig *aFieldListP); #endif // public helpers bool delegateParsingTo(TConfigElement *aConfigElemP, const char *aElementName, const char **aAttributes, sInt32 aLine); void expectChildParsing(TConfigElement &aConfigElem) { aConfigElem.ResetParsing(); fChildParser=&aConfigElem; }; // let child element parse contents void expectAll(void); void expectEmpty(bool nested=false) { fParseMode = nested ? pamo_endnested : pamo_end; }; #endif // locked config sections support #ifdef SYSER_REGISTRATION bool fLockedElement; // set while parsing locked element bool fHadLockedSubs; // set if this element contained locked non-child subelements (will prevent string overwrites) #endif protected: #ifdef SYDEBUG TDebugLogger *getDbgLogger(void); uInt32 getDbgMask(void); #endif // - called after parsing is finished, should resolve links and throws on error virtual void localResolve(bool /* aLastPass */) { }; // nop #ifndef HARDCODED_CONFIG // parsing virtual void ResetParsing(void); // - checks if element known and decides what to do virtual bool localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine) { return false; } // unknown element // - called after nested level ends virtual void nestedElementEnd(void) {}; // - helpers void expectNested(void) { fParseMode=pamo_nested; }; void startNestedParsing() { fNest++; expectNested(); } // let same element parse nested levels void expectString(string &aString) { fParseMode=pamo_string; fResultPtr.fStringP=&aString; }; void expectMacroString(string &aString) { fParseMode=pamo_macrostring; fResultPtr.fStringP=&aString; }; void expectCString(string &aString) { fParseMode=pamo_cstring; fResultPtr.fStringP=&aString; }; void expectRawString(string &aString) { fParseMode=pamo_rawstring; fResultPtr.fStringP=&aString; }; #ifdef SCRIPT_SUPPORT void expectScript(string &aTScript,sInt32 aLine, const TFuncTable *aContextFuncs, bool aNoDeclarations=false) { fParseMode=pamo_script; fResultPtr.fStringP=&aTScript; fExpectLine=aLine; fExpectContextFuncs=aContextFuncs; fExpectNoDeclarations=aNoDeclarations; }; void expectFunction(TUserScriptFunction &aFuncDef,sInt32 aLine=0) { fParseMode=pamo_functiondef; fResultPtr.fFuncDefP=&aFuncDef; fExpectLine=aLine; }; #endif void expectPath(string &aString) { fParseMode=pamo_path; fResultPtr.fStringP=&aString; }; void expectBool(bool &aBool) { fParseMode=pamo_boolean; fResultPtr.fBoolP=&aBool; }; void expectTristate(sInt8 &aTristate) { fParseMode=pamo_tristate; fResultPtr.fByteP=&aTristate; }; void expectTimestamp(lineartime_t &aTimestamp) { fParseMode=pamo_timestamp; fResultPtr.fTimestampP=&aTimestamp; }; void expectTimezone(timecontext_t &aTimeContext) { fParseMode=pamo_timezone; fResultPtr.fTimeContextP=&aTimeContext; }; void expectVTimezone(GZones *aZonesToAddTo) { fParseMode=pamo_vtimezone; fResultPtr.fGZonesP=aZonesToAddTo; }; void expectIdCode(uInt32 &aLong) { fParseMode=pamo_idCode; fResultPtr.fLongP=(sInt32 *)(&aLong); }; void expectChar(char &aChar) { fParseMode=pamo_char; fResultPtr.fCharP=(char *)(&aChar); }; void expectInt64(sInt64 &aLongLong) { fParseMode=pamo_int64; fResultPtr.fLongLongP=&aLongLong; }; void expectInt32(sInt32 &aLong) { fParseMode=pamo_int32; fResultPtr.fLongP=&aLong; }; void expectUInt32(uInt32 &aLong) { fParseMode=pamo_int32; fResultPtr.fLongP=(sInt32 *)(&aLong); }; void expectInt16(sInt16 &aShort) { fParseMode=pamo_int16; fResultPtr.fShortP=&aShort; }; void expectUInt16(uInt16 &aShort) { fParseMode=pamo_int16; fResultPtr.fShortP=(sInt16 *)(&aShort); }; void expectEnum(sInt16 aDestSize,void *aPtr, const char * const aEnumNames[], sInt16 aNumEnums); #ifdef SCRIPT_SUPPORT void expectFieldID(sInt16 &aShort, TFieldListConfig *aFieldListP, TScriptContext *aScriptContextP=NULL) { fParseMode=pamo_field; fResultPtr.fShortP=&aShort; fFieldListP=aFieldListP; fScriptContextP=aScriptContextP; }; #else void expectFieldID(sInt16 &aShort, TFieldListConfig *aFieldListP) { fParseMode=pamo_field; fResultPtr.fShortP=&aShort; fFieldListP=aFieldListP; }; #endif #endif // config tree branches (childs) TRootConfigElement *fRootElementP; // root element sInt16 fNest; // nesting count for unprocessed or nested (in same TConfigElement) XML tags sInt16 fExpectAllNestStart; // nesting count where expectAll() was called while in pamo_nested mode bool fResolveImmediately; private: TConfigElement *fParentElementP; // parent of this element #ifndef HARDCODED_CONFIG // parsing TConfigElement *fChildParser; // child parser, NULL if none (this is parsing) string fTempString; // string to accumulate chars TCfgParseMode fParseMode; sInt32 fExpectLine; // line number of where expected data started TFieldListConfig *fFieldListP; // field list for expectField #ifdef SCRIPT_SUPPORT const TFuncTable *fExpectContextFuncs; // context-specific function table TScriptContext *fScriptContextP; // script context for expectField bool fExpectNoDeclarations; // flag for tokenizer #endif // - parse params const char * const * fParseEnumArray; sInt16 fParseEnumNum; bool fCompleted; // set when entire element has been scanned ok (not in progress any more) sInt8 fCfgVarExp; // config var expansion mode: -1 = no, 0=auto (depending on expectXXX), 1=yes, 2=yes with recursion // - where to store result (must be in accordance with fParseMode union { string *fStringP; sInt64 *fLongLongP; sInt32 *fLongP; char *fCharP; sInt16 *fShortP; bool *fBoolP; sInt8 *fByteP; lineartime_t *fTimestampP; GZones *fGZonesP; timecontext_t *fTimeContextP; #ifdef SCRIPT_SUPPORT TUserScriptFunction *fFuncDefP; #endif } fResultPtr; #endif // free config }; // TConfigElement class TRootConfigElement : public TConfigElement { typedef TConfigElement inherited; friend class TConfigElement; public: TRootConfigElement(TSyncAppBase *aSyncAppBaseP) : TConfigElement("root",NULL) { fSyncAppBaseP=aSyncAppBaseP; fRootElementP=this; }; bool ResolveAll(void); #ifndef HARDCODED_CONFIG void resetError(void); const char *getErrorMsg(void); localstatus getFatalError(void) { return fFatalError; }; void setError(bool aFatal, const char *aMsg); void setFatalError(localstatus aLocalFatalError) { fFatalError=aLocalFatalError; }; virtual void ResetParsing(void); // - start of element, this config element decides who processes this element virtual bool startElement(const char *aElementName, const char **aAttributes, sInt32 aLine); #endif protected: // Sync app base TSyncAppBase *fSyncAppBaseP; #ifndef HARDCODED_CONFIG // global parsing error handling bool fError; // error occurred localstatus fFatalError; // set<>0 if parsing should be aborted string fErrorMessage; // error message public: // section locking support #ifndef SYSER_REGISTRATION // - dummy uInt16 getConfigLockCRC(void) { return 0; }; #else // - get current config lock CRC uInt16 getConfigLockCRC(void) { return fLockCRC; }; // - add config text to locking CRC void addToLockCRC(const char *aCharData, size_t aNumChars=0); private: uInt16 fLockCRC; // accumulated CRC of all locked elements #endif private: bool fDocStarted; #endif }; } // namespace sysync #endif // ConfigElement_H // eof libsynthesis-3.4.0.47.1/src/sysync/customimplagent.cpp000077500000000000000000000674771226375725500227320ustar00rootroot00000000000000/** * @File customimplagent.cpp * * @Author Lukas Zeller (luz@plan44.ch) * * @brief TCustomAgent * Base class for agenst (servers or clients) with customizable datastores * based on TCustomImplDS * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * @Date 2005-12-05 : luz : separated from odbcdbagent */ // includes #include "sysync.h" #include "multifielditem.h" #include "mimediritemtype.h" #include "customimplagent.h" #include "customimplds.h" namespace sysync { // Charset names for DB charset specification // Note: numCharSets and the TCharSets type enum is defined in sysync_utils const char * const DBCharSetNames[numCharSets] = { "unknown", "ASCII", "ANSI", "ISO-8859-1", "UTF-8", "UTF-16", #ifdef CHINESE_SUPPORT "GB2312", "CP936", #endif }; // database field type names const char * const DBFieldTypeNames[numDBfieldTypes] = { "string", "blob", "date", "time", "timefordate", "timestamp", "dateonly", "zoneoffset_hours", "zoneoffset_mins", "zoneoffset_secs", "zonename", "numeric", "lineartime", "lineardate", "unixtime_s", "unixtime_ms", "unixtime_us", "unixdate_s", "unixdate_ms", "unixdate_us", "nsdate" }; // Generic Utils // ============= // integer in DB to lineartime conversion lineartime_t dbIntToLineartime(sInt64 aDBInt, TDBFieldType aDbfty) { switch (aDbfty) { case dbft_unixtime_s: case dbft_unixdate_s: // integer value representing UNIX epoch date in seconds return secondToLinearTimeFactor*aDBInt+UnixToLineartimeOffset; case dbft_nsdate_s: // integer value representing NSDate in seconds return secondToLinearTimeFactor*aDBInt+NSDateToLineartimeOffset; case dbft_unixtime_ms: case dbft_unixdate_ms: // integer value representing UNIX epoch date in milliseconds return aDBInt*secondToLinearTimeFactor/1000+UnixToLineartimeOffset; case dbft_unixdate_us: case dbft_unixtime_us: // integer value representing UNIX epoch time stamp in microseconds return aDBInt*secondToLinearTimeFactor/1000000+UnixToLineartimeOffset; case dbft_lineardate: // linear date as-is return aDBInt*linearDateToTimeFactor; case dbft_lineartime: default: // linear time as-is return aDBInt; } } // dbIntToLineartime // lineartime to integer in DB conversion sInt64 lineartimeToDbInt(lineartime_t aLinearTime, TDBFieldType aDbfty) { switch (aDbfty) { case dbft_unixtime_s: case dbft_unixdate_s: // integer value representing UNIX epoch date in seconds return (aLinearTime-UnixToLineartimeOffset)/secondToLinearTimeFactor; case dbft_nsdate_s: // integer value representing NSDate in seconds return (aLinearTime-NSDateToLineartimeOffset)/secondToLinearTimeFactor; case dbft_unixtime_ms: case dbft_unixdate_ms: // integer value representing UNIX epoch date in milliseconds return (aLinearTime-UnixToLineartimeOffset)*1000/secondToLinearTimeFactor; case dbft_unixdate_us: case dbft_unixtime_us: // integer value representing UNIX epoch time stamp in microseconds return (aLinearTime-UnixToLineartimeOffset)*1000000/secondToLinearTimeFactor; case dbft_lineardate: // linear date as-is return aLinearTime/linearDateToTimeFactor; case dbft_lineartime: default: // linear time as-is return aLinearTime; } } // lineartimeToDbInt // Config // ====== TCustomAgentConfig::TCustomAgentConfig(TConfigElement *aParentElement) : #ifdef BASED_ON_BINFILE_CLIENT TBinfileClientConfig(aParentElement) #else TAgentConfig("CustomAgent",aParentElement) #endif #ifdef SCRIPT_SUPPORT , fResolverContext(NULL) #endif { // nop so far } // TCustomAgentConfig::TCustomAgentConfig TCustomAgentConfig::~TCustomAgentConfig() { clear(); } // TCustomAgentConfig::~TCustomAgentConfig // init defaults void TCustomAgentConfig::clear(void) { // init defaults fCurrentDateIsUTC=false; // compatibility flag only, will set fCurrentDateTimeZone to TCTX_UTC at Resolve if set fCurrentDateTimeZone=TCTX_SYSTEM; // assume system local time fDataCharSet=chs_ansi; // assume ANSI, is probable for ODBC connection fDataLineEndMode=lem_dos; // default to CRLF, as this seems to be safest assumption // resolver context #ifndef BINFILE_ALWAYS_ACTIVE #ifdef SCRIPT_SUPPORT fLoginInitScript.erase(); fLoginCheckScript.erase(); fLoginFinishScript.erase(); if (fResolverContext) { delete fResolverContext; fResolverContext=NULL; } #endif #endif // BINFILE_ALWAYS_ACTIVE // clear inherited inherited::clear(); } // TCustomAgentConfig::clear #ifdef SCRIPT_SUPPORT // Custom agent specific script functions // ====================================== class TCustomAgentFuncs { public: #ifndef BINFILE_ALWAYS_ACTIVE // Login context functions // integer CHECKAUTH(string user, string secret, integer secretismd5) // returns auth status of checking given user name and given secret against user/secret from remote static void func_CheckAuth(TItemField *&aTermP, TScriptContext *aFuncContextP) { // get local side info string dbuser,dbsecret,nonce; bool secretismd5,authok; aFuncContextP->getLocalVar(0)->getAsString(dbuser); aFuncContextP->getLocalVar(1)->getAsString(dbsecret); secretismd5=aFuncContextP->getLocalVar(2)->getAsBoolean(); // check against remote side info. TCustomImplAgent *agentP = static_cast(aFuncContextP->getCallerContext()); if (agentP->fAuthType==sectyp_md5_V10 || agentP->fAuthType==sectyp_md5_V11) agentP->getAuthNonce(agentP->fAuthDevice,nonce); if (!secretismd5) { // local secret is clear text password, check against what was transmitted from remote authok=agentP->checkAuthPlain( dbuser.c_str(), // user name as specified by caller dbsecret.c_str(), // secret as specfied by caller (usually retrieved from DB) nonce.c_str(), // the nonce agentP->fAuthSecret, // the auth secret as transmitted from remote agentP->fAuthType // the type of the auth secret ); } else { // local secret is b64(md5(user:password)) authok= agentP->fAuthType==sectyp_md5_V11 && // auth secret from remote MUST be V1.1 type MD5 agentP->checkMD5WithNonce( dbsecret.c_str(), // b64(md5(user:password)) as provided by caller to check against nonce.c_str(), // the nonce agentP->fAuthSecret // auth secret according to SyncML 1.1 (b64(md5(b64(md5(user:pw)):nonce)) ); } // return auth checking result aTermP->setAsInteger(authok ? 1 : 0); }; // func_CheckAuth // integer AUTHOK() // returns current auth ok status (standard checking enabled) static void func_AuthOK(TItemField *&aTermP, TScriptContext *aFuncContextP) { aTermP->setAsInteger( static_cast(aFuncContextP->getCallerContext())->fStandardAuthOK ? 1 : 0 ); }; // func_AuthOK // string AUTHUSER() // returns name of user that tries to authenticate static void func_AuthUser(TItemField *&aTermP, TScriptContext *aFuncContextP) { aTermP->setAsString( static_cast(aFuncContextP->getCallerContext())->fAuthUser ); }; // func_AuthUser // SETUSERNAME(string username) // set user name that will be used to find user in DB // (but note that original username will be used to check auth with MD5 auth) static void func_SetUserName(TItemField *&aTermP, TScriptContext *aFuncContextP) { aFuncContextP->getLocalVar(0)->getAsString( static_cast(aFuncContextP->getCallerContext())->fUserName ); }; // func_SetUserName // SETDOMAIN(string domainname) // set "domain" name that can be used to differentiate user domains // (mainly an xml2go requirement) static void func_SetDomain(TItemField *&aTermP, TScriptContext *aFuncContextP) { aFuncContextP->getLocalVar(0)->getAsString( static_cast(aFuncContextP->getCallerContext())->fDomainName ); }; // func_SetDomain // string AUTHSTRING() // returns auth string (MD5 digest or plain text, according to AUTHTYPE()) // sent by user trying to authenticate static void func_AuthString(TItemField *&aTermP, TScriptContext *aFuncContextP) { aTermP->setAsString( static_cast(aFuncContextP->getCallerContext())->fAuthSecret ); }; // func_AuthString // string AUTHDEVICEID() // returns remote device ID static void func_AuthDeviceID(TItemField *&aTermP, TScriptContext *aFuncContextP) { aTermP->setAsString( static_cast(aFuncContextP->getCallerContext())->fAuthDevice ); }; // func_AuthDeviceID // integer AUTHTYPE() // returns static void func_AuthType(TItemField *&aTermP, TScriptContext *aFuncContextP) { aTermP->setAsInteger( (fieldinteger_t) static_cast(aFuncContextP->getCallerContext())->fAuthType ); }; // func_AuthType // integer UNKNOWNDEVICE() // returns if device was not yet in device table (valid in fLoginCheckScript only) static void func_Unknowndevice(TItemField *&aTermP, TScriptContext *aFuncContextP) { aTermP->setAsInteger( static_cast(aFuncContextP->getCallerContext())->fUnknowndevice ? 1 : 0 ); }; // func_Unknowndevice // string USERKEY() // returns user key static void func_UserKey(TItemField *&aTermP, TScriptContext *aFuncContextP) { aTermP->setAsString( static_cast(aFuncContextP->getCallerContext())->fUserKey ); }; // func_UserKey // SETUSERKEY(variant userkey) // set user key for this sync session static void func_SetUserKey(TItemField *&aTermP, TScriptContext *aFuncContextP) { aFuncContextP->getLocalVar(0)->getAsString( static_cast(aFuncContextP->getCallerContext())->fUserKey ); }; // func_SetUserKey // string DEVICEKEY() // returns device key static void func_DeviceKey(TItemField *&aTermP, TScriptContext *aFuncContextP) { aTermP->setAsString( static_cast(aFuncContextP->getCallerContext())->fDeviceKey ); }; // func_DeviceKey // SETDEVICEKEY(variant devicekey) // set device key for this sync session static void func_SetDeviceKey(TItemField *&aTermP, TScriptContext *aFuncContextP) { aFuncContextP->getLocalVar(0)->getAsString( static_cast(aFuncContextP->getCallerContext())->fDeviceKey ); }; // func_SetDeviceKey #endif // not BINFILE_ALWAYS_ACTIVE // timestamp DBINTTOTIMESTAMP(integer dbint,string dbfieldtype) // convert database integer to timestamp static void func_DBIntToTimestamp(TItemField *&aTermP, TScriptContext *aFuncContextP) { string tname,literal; aFuncContextP->getLocalVar(1)->getAsString(tname); // DB type string // search DB type, default to lineartime sInt16 ty; TDBFieldType dbfty=dbft_lineartime; if (StrToEnum(DBFieldTypeNames,numDBfieldTypes,ty,tname.c_str())) dbfty=(TDBFieldType)ty; // now set timestamp static_cast(aTermP)->setTimestampAndContext( dbIntToLineartime(aFuncContextP->getLocalVar(0)->getAsInteger(), dbfty), // timestamp TCTX_UNKNOWN // unknown zone ); }; // func_DBIntToTimestamp // integer TIMESTAMPTODBINT(timestamp ts,string dbfieldtype) // convert database integer to timestamp static void func_TimestampToDBInt(TItemField *&aTermP, TScriptContext *aFuncContextP) { string tname,literal; aFuncContextP->getLocalVar(1)->getAsString(tname); // DB type string // search DB type, default to lineartime sInt16 ty; TDBFieldType dbfty=dbft_lineartime; if (StrToEnum(DBFieldTypeNames,numDBfieldTypes,ty,tname.c_str())) dbfty=(TDBFieldType)ty; // now set timestamp aTermP->setAsInteger( lineartimeToDbInt( static_cast(aFuncContextP->getLocalVar(0))->getTimestampAs(TCTX_UNKNOWN), dbfty ) ); }; // func_TimestampToDBInt // timestamp CONVERTTODATAZONE(timestamp atime [,boolean doUnfloat]) // returns timestamp converted to database time zone. // - If doUnfloat, floating timestamps will be fixed in the new zone w/o conversion of the timestamp itself. static void func_ConvertToDataZone(TItemField *&aTermP, TScriptContext *aFuncContextP) { // get DB zone TCustomImplAgent *agentP = static_cast(aFuncContextP->getCallerContext()); TCustomImplDS *datastoreP = static_cast(agentP->fScriptContextDatastore); timecontext_t actual,tctx; if (datastoreP) tctx = static_cast(datastoreP->getDSConfig())->fDataTimeZone; else tctx = agentP->fConfigP->fCurrentDateTimeZone; // get timestamp TTimestampField *tsP = static_cast(aFuncContextP->getLocalVar(0)); // convert and get actually resulting context back lineartime_t ts = tsP->getTimestampAs(tctx,&actual); // unfloat floats if selected if (aFuncContextP->getLocalVar(1)->getAsBoolean() && TCTX_IS_UNKNOWN(actual)) actual=tctx; // unfloat // assign it to result static_cast(aTermP)->setTimestampAndContext(ts,actual); }; // func_ConvertToDataZone }; // TCustomAgentFuncs const uInt8 param_CheckAuth[] = { VAL(fty_string), VAL(fty_string), VAL(fty_integer) }; const uInt8 param_DBIntToTimestamp[] = { VAL(fty_integer), VAL(fty_string) }; const uInt8 param_TimestampToDBInt[] = { VAL(fty_timestamp), VAL(fty_string) }; const uInt8 param_ConvertToDataZone[] = { VAL(fty_timestamp), OPTVAL(fty_integer) }; const uInt8 param_variant[] = { VAL(fty_none) }; #ifndef BINFILE_ALWAYS_ACTIVE // builtin function table for login context const TBuiltInFuncDef CustomAgentFuncDefs[numCustomAgentFuncs] = { { "AUTHOK", TCustomAgentFuncs::func_AuthOK, fty_integer, 0, NULL }, { "CHECKAUTH", TCustomAgentFuncs::func_CheckAuth, fty_integer, 3, param_CheckAuth }, { "AUTHUSER", TCustomAgentFuncs::func_AuthUser, fty_string, 0, NULL }, { "SETUSERNAME", TCustomAgentFuncs::func_SetUserName, fty_none, 1, param_oneString }, { "SETDOMAIN", TCustomAgentFuncs::func_SetDomain, fty_none, 1, param_oneString }, { "AUTHSTRING", TCustomAgentFuncs::func_AuthString, fty_string, 0, NULL }, { "AUTHDEVICEID", TCustomAgentFuncs::func_AuthDeviceID, fty_string, 0, NULL }, { "AUTHTYPE", TCustomAgentFuncs::func_AuthType, fty_integer, 0, NULL }, { "UNKNOWNDEVICE", TCustomAgentFuncs::func_Unknowndevice, fty_integer, 0, NULL }, { "SETUSERKEY", TCustomAgentFuncs::func_SetUserKey, fty_none, 1, param_variant }, { "SETDEVICEKEY", TCustomAgentFuncs::func_SetDeviceKey, fty_none, 1, param_variant }, }; #endif // not BINFILE_ALWAYS_ACTIVE // builtin function defs for customImpl database and login contexts const TBuiltInFuncDef CustomAgentAndDSFuncDefs[numCustomAgentAndDSFuncs] = { #ifndef BINFILE_ALWAYS_ACTIVE { "DEVICEKEY", TCustomAgentFuncs::func_DeviceKey, fty_string, 0, NULL }, { "USERKEY", TCustomAgentFuncs::func_UserKey, fty_string, 0, NULL }, #endif { "DBINTTOTIMESTAMP", TCustomAgentFuncs::func_DBIntToTimestamp, fty_timestamp, 2, param_DBIntToTimestamp }, { "TIMESTAMPTODBINT", TCustomAgentFuncs::func_TimestampToDBInt, fty_integer, 2, param_TimestampToDBInt }, { "CONVERTTODATAZONE", TCustomAgentFuncs::func_ConvertToDataZone, fty_timestamp, 2, param_ConvertToDataZone }, }; #ifndef BINFILE_ALWAYS_ACTIVE // function table which is chained from login-context function table const TFuncTable CustomAgentFuncTable2 = { sizeof(CustomAgentAndDSFuncDefs) / sizeof(TBuiltInFuncDef), // size of table CustomAgentAndDSFuncDefs, // table pointer NULL // no chain func }; // chain from login context agent funcs to general agent funcs extern const TFuncTable CustomDSFuncTable2; static void *CustomAgentChainFunc(void *&aCtx) { // caller context remains unchanged // -> no change needed // next table is Agent's general function table return (void *)&CustomAgentFuncTable2; } // CustomAgentChainFunc // function table for login context scripts const TFuncTable CustomAgentFuncTable = { sizeof(CustomAgentFuncDefs) / sizeof(TBuiltInFuncDef), // size of table CustomAgentFuncDefs, // table pointer CustomAgentChainFunc // chain to general agent funcs. }; #endif // not BINFILE_ALWAYS_ACTIVE // chain from agent funcs to custom datastore funcs (when chained via CustomDSFuncTable1 extern const TFuncTable CustomDSFuncTable2; static void *CustomDSChainFunc1(void *&aCtx) { // caller context for datastore-level functions is the datastore pointer if (aCtx) aCtx = static_cast(aCtx)->fScriptContextDatastore; // next table is custom datastore's return (void *)&CustomDSFuncTable2; } // CustomDSChainFunc1 // function table which is used by CustomImplDS scripts to access agent-level funcs and then chain // back to datastore level funcs const TFuncTable CustomDSFuncTable1 = { sizeof(CustomAgentAndDSFuncDefs) / sizeof(TBuiltInFuncDef), // size of agent's table CustomAgentAndDSFuncDefs, // table pointer to agent's general purpose (non login-context specific) funcs CustomDSChainFunc1 // chain to ODBC datastore level DB functions }; #endif // SCRIPT_SUPPORT // config element parsing bool TCustomAgentConfig::localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine) { // checking the elements #ifndef BINFILE_ALWAYS_ACTIVE #ifdef SCRIPT_SUPPORT if (strucmp(aElementName,"logininitscript")==0) expectScript(fLoginInitScript,aLine,getAgentFuncTableP()); else if (strucmp(aElementName,"logincheckscript")==0) expectScript(fLoginCheckScript,aLine,getAgentFuncTableP()); else if (strucmp(aElementName,"loginfinishscript")==0) expectScript(fLoginFinishScript,aLine,getAgentFuncTableP()); else #endif // SCRIPT_SUPPORT #endif // BINFILE_ALWAYS_ACTIVE // - session level Date/Time info if ( strucmp(aElementName,"timestamputc")==0 || // old 2.1 compatible strucmp(aElementName,"timeutc")==0 // new 3.0 variant, unified with datastore level setting ) { // - warn for usage of old timeutc ReportError(false,"Warning: / is deprecated - please use instead",aElementName); expectBool(fCurrentDateIsUTC); } else if (strucmp(aElementName,"datatimezone")==0) expectTimezone(fCurrentDateTimeZone); // - session level charset and line ends else if (strucmp(aElementName,"datacharset")==0) expectEnum(sizeof(fDataCharSet),&fDataCharSet,DBCharSetNames,numCharSets); else if (strucmp(aElementName,"datalineends")==0) expectEnum(sizeof(fDataLineEndMode),&fDataLineEndMode,lineEndModeNames,numLineEndModes); // - none known here else return inherited::localStartElement(aElementName,aAttributes,aLine); // ok return true; } // TCustomAgentConfig::localStartElement // resolve void TCustomAgentConfig::localResolve(bool aLastPass) { // convert legacy UTC flag to timezone setting if (fCurrentDateIsUTC) fCurrentDateTimeZone = TCTX_UTC; // Scripts etc. if (aLastPass) { #ifndef BINFILE_ALWAYS_ACTIVE #ifdef SCRIPT_SUPPORT // login scripting TScriptContext::resolveScript(getSyncAppBase(),fLoginInitScript,fResolverContext,NULL); TScriptContext::resolveScript(getSyncAppBase(),fLoginCheckScript,fResolverContext,NULL); TScriptContext::resolveScript(getSyncAppBase(),fLoginFinishScript,fResolverContext,NULL); ResolveAPIScripts(); // - derivates' scripts are resolved by now, we can dispose of the resolver context // NOTE: this is true if (fResolverContext) delete fResolverContext; fResolverContext=NULL; #endif #endif // not BINFILE_ALWAYS_ACTIVE } // resolve inherited inherited::localResolve(aLastPass); } // TCustomAgentConfig::localResolve /* public TCustomImplAgent members */ TCustomImplAgent::TCustomImplAgent(TSyncAppBase *aAppBaseP, TSyncSessionHandle *aSessionHandleP, cAppCharP aSessionID) : inherited(aAppBaseP, aSessionHandleP, aSessionID), fConfigP(NULL) #ifdef SCRIPT_SUPPORT ,fScriptContextDatastore(NULL) #endif #ifdef SCRIPT_SUPPORT ,fAgentContext(NULL) #endif #ifdef DBAPI_TUNNEL_SUPPORT ,fTunnelDatastoreP(NULL) #endif { // get config for agent and save direct link to agent config for easy reference fConfigP = static_cast(getRootConfig()->fAgentConfigP); #ifndef BINFILE_ALWAYS_ACTIVE #ifdef SCRIPT_SUPPORT // create login script context if there are scripts // Note: derivates might already have initialized fAgentContext here, that's why we // now NULL it via ctor. TScriptContext::rebuildContext(getSyncAppBase(),fConfigP->fLoginInitScript,fAgentContext,this); TScriptContext::rebuildContext(getSyncAppBase(),fConfigP->fLoginCheckScript,fAgentContext,this); TScriptContext::rebuildContext(getSyncAppBase(),fConfigP->fLoginFinishScript,fAgentContext,this,true); // now build vars // Note: derivates will rebuild NOW, AFTER our rebuilds, in the derived constructor #endif #endif // BINFILE_ALWAYS_ACTIVE // Note: Datastores are already created from config } // TCustomImplAgent::TCustomImplAgent // destructor TCustomImplAgent::~TCustomImplAgent() { // make sure everything is terminated BEFORE destruction of hierarchy begins TerminateSession(); } // TCustomImplAgent::~TCustomImplAgent // Terminate session void TCustomImplAgent::TerminateSession() { if (!fTerminated) { // Note that the following will happen BEFORE destruction of // individual datastores, so make sure datastores are already // independent of the agnet's ressources InternalResetSession(); #ifdef SCRIPT_SUPPORT // get rid of login context if (fAgentContext) delete fAgentContext; #endif // Make sure datastores know that the agent will go down soon announceDestruction(); } inherited::TerminateSession(); } // TCustomImplAgent::TerminateSession // Reset session void TCustomImplAgent::InternalResetSession(void) { // reset all datastores now to make everything is done which might need the // Agent before it is destroyed // (Note: TerminateDatastores() will be called again by ancestors) TerminateDatastores(); } // TCustomImplAgent::InternalResetSession // Virtual version void TCustomImplAgent::ResetSession(void) { // do my own stuff InternalResetSession(); // let ancestor do its stuff inherited::ResetSession(); } // TCustomImplAgent::ResetSession #ifdef DBAPI_TUNNEL_SUPPORT // initialize session for DBAPI tunnel usage localstatus TCustomImplAgent::InitializeTunnelSession(cAppCharP aDatastoreName) { localstatus sta = LOCERR_OK; // do the minimum of profile selection needed to make DBs work sta = SelectProfile(TUNNEL_PROFILE_ID, false); if (sta==LOCERR_OK) { // find datastore to work with TLocalDSConfig *dsCfgP = getSessionConfig()->getLocalDS(aDatastoreName); if (!dsCfgP) { // no such datastore found sta = DB_NotFound; } else { // found config for given name, instantiate the datastore object fTunnelDatastoreP = static_cast(dsCfgP->newLocalDataStore(this)); if (!fTunnelDatastoreP) sta = DB_Error; } } // done return sta; } // TCustomImplAgent::InitializeTunnelSession // return the datastore initialized for tunnel access TLocalEngineDS *TCustomImplAgent::getTunnelDS() { return fTunnelDatastoreP; } // TCustomImplAgent::getTunnelDS #endif // DBAPI_TUNNEL_SUPPORT #ifndef BINFILE_ALWAYS_ACTIVE // check credential string // Note: if authentication is successful, odbcDBServer session // saves the user key and device key for later reference in subsequent // DB accesses. bool TCustomImplAgent::SessionLogin(const char *aUserName, const char *aAuthString, TAuthSecretTypes aAuthStringType, const char *aDeviceID) { #ifdef BASED_ON_BINFILE_CLIENT // let binfile handle it if it is active if (binfilesActive()) { return inherited::SessionLogin(aUserName, aAuthString, aAuthStringType, aDeviceID); } #endif // BASED_ON_BINFILE_CLIENT bool authok = false; string nonce; if (!fConfigP) return false; // no config -> fail early (no need for cleanup) #ifdef SYSYNC_CLIENT if (IS_CLIENT) { #ifndef NO_LOCAL_DBLOGIN // check for possible client without need for local DB login if (fNoLocalDBLogin) { // just use local DB login name as user key (userkey is probably not needed anyway) fUserKey=fLocalDBUser; // accept as auth ok return true; // return early, no need for cleanup } #else // client without need for local login return true; //#warning "we could probably eliminate much more code here" #endif } #endif // SYSYNC_CLIENT // first step: set defaults fUserKey=aUserName; // user key is equal to user name fDeviceKey=aDeviceID; // device key is equal to device name #ifndef SCRIPT_SUPPORT #define DB_USERNAME aUserName #else #define DB_USERNAME fUserName.c_str() fDomainName.erase(); // no domain name // second step: run script to possibly grant auth before any other method is // needed at all // - set status vars that can be referenced by context funcs in script fStandardAuthOK=false; // not yet authorized, for AUTHOK() func fAuthUser=aUserName; // for AUTHUSER() func fUserName=aUserName; // copy into string var that can be modified by SETUSERNAME() fAuthSecret=aAuthString; // for AUTHSECRET() func fAuthDevice=aDeviceID; // for AUTHDEVICEID() func fAuthType=aAuthStringType; // for AUTHTYPE() func fUnknowndevice=true; // we do not know the device here already // now call and evaluate boolean result TItemField *resP=NULL; fScriptContextDatastore=NULL; if (!TScriptContext::executeWithResult( resP, // can be default result or NULL, will contain result or NULL if no result fAgentContext, fConfigP->fLoginInitScript, fConfigP->getAgentFuncTableP(), // context function table this, // context data (myself) NULL, false, NULL, false )) { authok=false; // script failed, auth failed goto cleanup; } else { if (resP) { // explicit auth or reject at this stage SYSYNC_TRY { // - first let device register itself (and find devicekey possibly) CheckDevice(aDeviceID); // - now get auth result authok = resP->getAsBoolean(); } SYSYNC_CATCH(exception &e) // log error PDEBUGPRINTFX(DBG_ERROR,("Exception during CheckDevice after initscript has accepted/rejected auth: %s",e.what())); // fail auth authok=false; SYSYNC_ENDCATCH delete resP; goto cleanup; } // otherwise, we haven't authorized yet authok=false; } #endif SYSYNC_TRY { // fourth step: get device info, if any CheckDevice(aDeviceID); // fifth step: check simpleauth (in base class) // NOTE: overrides any API level checks if simpleauth is set! if (TSyncSession::SessionLogin(aUserName,aAuthString,aAuthStringType,aDeviceID)) { authok=true; goto cleanup; } // sixth step: let DB API level check authorisation authok=CheckLogin(aUserName, DB_USERNAME, aAuthString, aAuthStringType, aDeviceID); #ifdef SCRIPT_SUPPORT // finalize login // - refresh auth status fStandardAuthOK=authok; // for AUTHOK() func // - call script (if any) fScriptContextDatastore=NULL; authok=TScriptContext::executeTest( authok, // default for no script, no result or script error is current auth fAgentContext, fConfigP->fLoginFinishScript, fConfigP->getAgentFuncTableP(), // context function table (void *)this // context data (myself) ); #endif } SYSYNC_CATCH(exception &e) // log error PDEBUGPRINTFX(DBG_ERROR,("Exception while trying to access DB for SessionLogin: %s",e.what())); authok=false; SYSYNC_ENDCATCH cleanup: // clean up login stuff LoginCleanUp(); // let derived class clean up (like closing transactions etc.) // return status return authok; } // TCustomImplAgent::SessionLogin #endif // BINFILE_ALWAYS_ACTIVE } // namespace sysync /* end of TCustomImplAgent implementation */ // eof libsynthesis-3.4.0.47.1/src/sysync/customimplagent.h000077500000000000000000000201741226375725500223560ustar00rootroot00000000000000/** * @File customimplagent.h * * @Author Lukas Zeller (luz@plan44.ch) * * @brief TCustomImplAgent * Base class for agenst (servers or clients) with customizable datastores * based on TCustomImplDS * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * @Date 2005-12-05 : luz : separated from odbcdbagent */ #ifndef CUSTOMIMPLAGENT_H #define CUSTOMIMPLAGENT_H // includes #include "stdlogicagent.h" #include "stdlogicds.h" #include "multifielditem.h" #include "scriptcontext.h" #ifdef BASED_ON_BINFILE_CLIENT #include "binfileimplclient.h" #endif using namespace sysync; namespace sysync { #ifdef SCRIPT_SUPPORT // publish as derivates might need it extern const TFuncTable CustomAgentFuncTable; extern const TFuncTable CustomAgentFuncTable2; extern const TFuncTable CustomDSFuncTable1; // - define count here as derivates will access the funcdefs table directly const int numCustomAgentFuncs=14; extern const TBuiltInFuncDef CustomAgentFuncDefs[numCustomAgentFuncs]; #ifndef BINFILE_ALWAYS_ACTIVE const int numCustomAgentAndDSFuncs=5; #else const int numCustomAgentAndDSFuncs=3; #endif extern const TBuiltInFuncDef CustomAgentAndDSFuncDefs[numCustomAgentAndDSFuncs]; #endif // config names for character sets extern const char * const DBCharSetNames[numCharSets]; // database field types typedef enum { dbft_string, dbft_blob, // binary contents of string will be used, no translations dbft_date, dbft_time, dbft_timefordate, // to add time to a date dbft_timestamp, dbft_dateonly, // timestamp, but carrying only a date, so no zone correction is applied dbft_uctoffsfortime_hours, // to add UTC offset to a time or timestamp dbft_uctoffsfortime_mins, // to add UTC offset to a time or timestamp dbft_uctoffsfortime_secs, // to add UTC offset to a time or timestamp dbft_zonename, // to get zone name of a timestamp dbft_numeric, // string value is used w/o any quotes in SQL dbft_lineartime, // linear time as-is dbft_lineardate, // linear date as-is dbft_unixtime_s, // integer value representing UNIX epoch time stamp in seconds dbft_unixtime_ms, // integer value representing UNIX epoch time stamp in milliseconds dbft_unixtime_us, // integer value representing UNIX epoch time stamp in microseconds dbft_unixdate_s, // integer value representing UNIX epoch date in seconds dbft_unixdate_ms, // integer value representing UNIX epoch date in milliseconds dbft_unixdate_us, // integer value representing UNIX epoch date in microseconds dbft_nsdate_s, // integer value representing NSDate (seconds since 2001-01-01 00:00) numDBfieldTypes } TDBFieldType; extern const char * const DBFieldTypeNames[numDBfieldTypes]; // integer in DB <-> lineartime conversions lineartime_t dbIntToLineartime(sInt64 aDBInt, TDBFieldType aDbfty); sInt64 lineartimeToDbInt(lineartime_t aLinearTime, TDBFieldType aDbfty); // forward class TCustomDSConfig; #ifdef SCRIPT_SUPPORT class TScriptContext; #endif class TCustomAgentConfig: #ifdef BASED_ON_BINFILE_CLIENT public TBinfileClientConfig #else public TAgentConfig #endif { #ifdef BASED_ON_BINFILE_CLIENT typedef TBinfileClientConfig inherited; #else typedef TAgentConfig inherited; #endif public: TCustomAgentConfig(TConfigElement *aParentElement); virtual ~TCustomAgentConfig(); // properties #ifdef SCRIPT_SUPPORT // - login scripts string fLoginInitScript; // called to initialize variables and early check for auth string fLoginCheckScript; // called to check permission for all users in question string fLoginFinishScript; // called when login is finished (failed or successful) #endif // SCRIPT_SUPPORT // - Date/Time info bool fCurrentDateIsUTC; //%%% legacy flag for compatibility, superseded by fCurrentDateTimeZone timecontext_t fCurrentDateTimeZone; // time zone for storing/retrieving timestamps in DB // - charset to be used in the data table TCharSets fDataCharSet; // - line end mode to be used in the data table for multiline data TLineEndModes fDataLineEndMode; #ifdef SCRIPT_SUPPORT // provided to allow derivates to add API specific script functions to scripts called from customagent virtual const TFuncTable *getAgentFuncTableP(void) { #ifndef BASED_ON_BINFILE_CLIENT return &CustomAgentFuncTable; #else return NULL; #endif }; TScriptContext *fResolverContext; #endif protected: // check config elements virtual bool localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine); virtual void clear(); virtual void localResolve(bool aLastPass); #ifdef SCRIPT_SUPPORT virtual void ResolveAPIScripts(void) { /* NOP */ }; #endif }; // TCustomAgentConfig class TCustomImplDS; class TCustomImplAgent: #ifdef BASED_ON_BINFILE_CLIENT public TBinfileImplClient #else public TStdLogicAgent #endif { friend class TCustomCommonFuncs; friend class TCustomAgentFuncs; #ifdef BASED_ON_BINFILE_CLIENT typedef TBinfileImplClient inherited; #else typedef TStdLogicAgent inherited; #endif public: TCustomImplAgent(TSyncAppBase *aAppBaseP, TSyncSessionHandle *aSessionHandleP, cAppCharP aSessionID); virtual ~TCustomImplAgent(); virtual void TerminateSession(void); // Terminate session, like destructor, but without actually destructing object itself virtual void ResetSession(void); // Resets session (but unlike TerminateSession, session might be re-used) void InternalResetSession(void); // static implementation for calling through virtual destructor and virtual ResetSession(); // Custom agent config TCustomAgentConfig *fConfigP; // Needed for general script support #ifdef SCRIPT_SUPPORT TCustomImplDS *fScriptContextDatastore; // needed because datastore chains agent's script funcs #endif // SCRIPT_SUPPORT #ifdef DBAPI_TUNNEL_SUPPORT // Initialize a datastore tunnel session virtual localstatus InitializeTunnelSession(cAppCharP aDatastoreName); virtual TLocalEngineDS *getTunnelDS(); #endif #ifndef BASED_ON_BINFILE_CLIENT // if binfiles are not compiled in, they are always inactive (otherwise binfileclient parent defines this method) bool binfilesActive(void) { return false; }; #endif // Login and device management only if not exclusively based on binfile client #ifndef BINFILE_ALWAYS_ACTIVE // - login for this session virtual bool SessionLogin(const char *aUserName, const char *aAuthString, TAuthSecretTypes aAuthStringType, const char *aDeviceID); // - clean up after all login activity is over (including finishscript) virtual void LoginCleanUp(void) { /* NOP at this level */ }; // - get user key const char *getUserKey(void) { return fUserKey.c_str(); }; // status vars, valid during login context script execution only! #ifdef SCRIPT_SUPPORT bool fStandardAuthOK; // result of standard auth checking string fUserName; // possibly modified user name used to find user in DB string fDomainName; // domain name possibly derived from LOCALURI or similar const char *fAuthUser; // original username as sent by remote const char *fAuthSecret; // secret from remote (normally, MD5 of user:password) const char *fAuthDevice; // device ID TAuthSecretTypes fAuthType; // set if V11-type secret bool fUnknowndevice; // set if device is unknown so far #endif // SCRIPT_SUPPORT // session vars string fUserKey; // user key obtained at SessionLogin string fDeviceKey; // device key obtained at SessionLogin protected: // - check device ID related stuff virtual void CheckDevice(const char *aDeviceID) { /* NOP here */ }; // - check user/pw (part of SessionLogin process) virtual bool CheckLogin(const char *aOriginalUserName, const char *aModifiedUserName, const char *aAuthString, TAuthSecretTypes aAuthStringType, const char *aDeviceID) { return false; /* cannot login */ }; // - remote device is analyzed, possibly save status virtual void remoteAnalyzed(void) { /* NOP at this level */ }; // script contexts #endif // BINFILE_ALWAYS_ACTIVE #ifdef SCRIPT_SUPPORT TScriptContext *fAgentContext; #endif // SCRIPT_SUPPORT #ifdef DBAPI_TUNNEL_SUPPORT TCustomImplDS *fTunnelDatastoreP; #endif // DBAPI_TUNNEL_SUPPORT }; // TCustomImplAgent } // namespace sysync #endif // CUSTOMIMPLAGENT_H // eof libsynthesis-3.4.0.47.1/src/sysync/customimplds.cpp000077500000000000000000005206431226375725500222270ustar00rootroot00000000000000/** * @File customimpl.cpp * * @Author Lukas Zeller (luz@plan44.ch) * * @brief TCustomImplDS * Base class for customizable datastores (mainly extended DB mapping features * common to all derived classes like ODBC, DBAPI etc.). * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * @Date 2005-12-05 : luz : separated from odbcapids */ // includes #include "sysync.h" #include "multifielditem.h" #include "mimediritemtype.h" #include "customimplds.h" #include "customimplagent.h" #ifdef DBAPI_TUNNEL_SUPPORT #include "SDK_util.h" #endif namespace sysync { #ifndef BINFILE_ALWAYS_ACTIVE #ifdef SYDEBUG const char * const MapEntryTypeNames[numMapEntryTypes] = { "invalid", "normal", "tempidmap", "pendingmap" }; #endif #endif // not BINFILE_ALWAYS_ACTIVE #ifdef SCRIPT_SUPPORT class TCustomDSfuncs { public: // Custom Impl datastore specific script functions // =============================================== // string FOLDERKEY() // returns folder key static void func_FolderKey(TItemField *&aTermP, TScriptContext *aFuncContextP) { aTermP->setAsString( static_cast(aFuncContextP->getCallerContext())->fFolderKey.c_str() ); }; // func_FolderKey // string TARGETKEY() // returns target key static void func_TargetKey(TItemField *&aTermP, TScriptContext *aFuncContextP) { aTermP->setAsString( static_cast(aFuncContextP->getCallerContext())->fTargetKey.c_str() ); }; // func_TargetKey // integer ARRAYINDEX() // returns current array index when reading or writing an array // in the finish function it denotes the number of array items totally static void func_ArrayIndex(TItemField *&aTermP, TScriptContext *aFuncContextP) { aTermP->setAsInteger( static_cast(aFuncContextP->getCallerContext())->fArrIdx ); }; // func_ArrayIndex // string PARENTKEY() // returns key of (array) parent object (like %k) static void func_ParentKey(TItemField *&aTermP, TScriptContext *aFuncContextP) { aTermP->setAsString( static_cast(aFuncContextP->getCallerContext())->fParentKey.c_str() ); }; // func_ParentKey // integer WRITING() // returns true if script is called while writing to DB static void func_Writing(TItemField *&aTermP, TScriptContext *aFuncContextP) { aTermP->setAsBoolean( static_cast(aFuncContextP->getCallerContext())->fWriting ); }; // func_Writing // integer DELETING() // returns true if script is called while deleting in DB static void func_Deleting(TItemField *&aTermP, TScriptContext *aFuncContextP) { aTermP->setAsBoolean( static_cast(aFuncContextP->getCallerContext())->fDeleting ); }; // func_Deleting // integer INSERTING() // returns true if script is called while inserting new data to DB static void func_Inserting(TItemField *&aTermP, TScriptContext *aFuncContextP) { aTermP->setAsBoolean( static_cast(aFuncContextP->getCallerContext())->fInserting ); }; // func_Inserting // string LOGSUBST(string logtext) // returns log placeholders substituted in logtext static void func_LogSubst(TItemField *&aTermP, TScriptContext *aFuncContextP) { string logtext; aFuncContextP->getLocalVar(0)->getAsString(logtext); // log text // perform substitutions static_cast(aFuncContextP->getCallerContext())->DoLogSubstitutions(logtext,false); // return it aTermP->setAsString(logtext); }; // func_LogSubst }; // TCustomDSfuncs const uInt8 param_LogSubst[] = { VAL(fty_string) }; // builtin function table for datastore level const TBuiltInFuncDef CustomDSFuncDefs[] = { { "FOLDERKEY", TCustomDSfuncs::func_FolderKey, fty_string, 0, NULL }, { "TARGETKEY", TCustomDSfuncs::func_TargetKey, fty_string, 0, NULL }, { "ARRAYINDEX", TCustomDSfuncs::func_ArrayIndex, fty_integer, 0, NULL }, { "PARENTKEY", TCustomDSfuncs::func_ParentKey, fty_string, 0, NULL }, { "WRITING", TCustomDSfuncs::func_Writing, fty_integer, 0, NULL }, { "INSERTING", TCustomDSfuncs::func_Inserting, fty_integer, 0, NULL }, { "DELETING", TCustomDSfuncs::func_Deleting, fty_integer, 0, NULL }, { "LOGSUBST", TCustomDSfuncs::func_LogSubst, fty_string, 1, param_LogSubst } }; // chain to generic local engine datastore funcs static void *CustomDSChainFunc2(void *&aCtx) { // context pointer for datastore-level funcs is the datastore // -> no change needed // next table is localEngineDS's return (void *)&DBFuncTable; } // CustomDSChainFunc2 const TFuncTable CustomDSFuncTable2 = { sizeof(CustomDSFuncDefs) / sizeof(TBuiltInFuncDef), // size of table CustomDSFuncDefs, // table pointer CustomDSChainFunc2 // chain generic DB functions }; #endif // Config // ====== TCustomDSConfig::TCustomDSConfig(const char* aName, TConfigElement *aParentElement) : inherited(aName,aParentElement), fFieldMappings("mappings",this) #ifdef SCRIPT_SUPPORT ,fResolveContextP(NULL) ,fDSScriptsResolved(false) #endif { // nop so far clear(); } // TCustomDSConfig::TCustomDSConfig TCustomDSConfig::~TCustomDSConfig() { // clear clear(); } // TCustomDSConfig::~TCustomDSConfig // init defaults void TCustomDSConfig::clear(void) { // init defaults // - multi-folder support fMultiFolderDB=false; // Data table options // - charset to be used in the data table fDataCharSet=chs_ansi; // suitable default for ODBC // - line end mode to be used in the data table for multiline data fDataLineEndMode=lem_dos; // default to CRLF, as this seems to be safest assumption // - if set, causes that data is read from DB first and then merged // with updated fields. Not needed in normal SQL DBs, as they can // update a subset of all columns. However, might still be needed // for special cases like Achil that needs record size calculation // or sortfeldXXX generation. fUpdateAllFields=false; // - Date/Time info fDataIsUTC=false; // compatibility flag only, will set fDataTimeZone to TCTX_UTC at Resolve if set fDataTimeZone=TCTX_SYSTEM; // default to local system time fUserZoneOutput=true; // by default, non-floating timestamps are moved to user zone after reading from DB. Only if zone context for timestamp fields is really retrieved from the DB on a per record level, this can be switched off #ifndef BINFILE_ALWAYS_ACTIVE // - flag indicating that admin tables have DS 1.2 support (map entrytype, map flags, fResumeAlertCode, fLastSuspend, fLastSuspendIdentifier fResumeSupport=false; fResumeItemSupport=false; // no item resume as well // - admin capability info fSyncTimeStampAtEnd=false; // if set, time point of sync is taken AFTER last write to DB (for single-user DBs like FMPro). Note that target table layout is different in this case! fOneWayFromRemoteSupported=false; // compatible with old layout of target tables, no support #endif // not BINFILE_ALWAYS_ACTIVE fStoreSyncIdentifiers=false; // compatible with old layout of target tables, no support // clear embedded fFieldMappings.clear(); #ifdef SCRIPT_SUPPORT // - script called after admin data is loaded (before any data access takes place) fAdminReadyScript.erase(); // - script called at end of sync session fSyncEndScript.erase(); // - clear script resolve context if (fResolveContextP) { delete fResolveContextP; fResolveContextP=NULL; } fDSScriptsResolved=false; #endif // clear inherited inherited::clear(); } // TCustomDSConfig::clear // config element parsing bool TCustomDSConfig::localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine) { // multi-folder-support if (strucmp(aElementName,"multifolder")==0) expectBool(fMultiFolderDB); // user data related properties else if (strucmp(aElementName,"datacharset")==0) expectEnum(sizeof(fDataCharSet),&fDataCharSet,DBCharSetNames,numCharSets); else if (strucmp(aElementName,"datalineends")==0) expectEnum(sizeof(fDataLineEndMode),&fDataLineEndMode,lineEndModeNames,numLineEndModes); else if (strucmp(aElementName,"updateallfields")==0) expectBool(fUpdateAllFields); // - Date/Time info else if (strucmp(aElementName,"timeutc")==0) { // - warn for usage of old timeutc ReportError(false,"Warning: is deprecated - please use instead",aElementName); expectBool(fDataIsUTC); } else if (strucmp(aElementName,"datatimezone")==0) expectTimezone(fDataTimeZone); else if (strucmp(aElementName,"userzoneoutput")==0) expectBool(fUserZoneOutput); #ifndef BINFILE_ALWAYS_ACTIVE // - admin capability info else if (strucmp(aElementName,"synctimestampatend")==0) expectBool(fSyncTimeStampAtEnd); else if (strucmp(aElementName,"fromremoteonlysupport")==0) expectBool(fOneWayFromRemoteSupported); else if (strucmp(aElementName,"resumesupport")==0) expectBool(fResumeSupport); else if (strucmp(aElementName,"resumeitemsupport")==0) expectBool(fResumeItemSupport); #endif // BINFILE_ALWAYS_ACTIVE else if ( strucmp(aElementName,"storelastsyncidentifier")==0 || strucmp(aElementName,"storesyncidentifiers")==0 ) expectBool(fStoreSyncIdentifiers); #ifdef SCRIPT_SUPPORT else if (strucmp(aElementName,"adminreadyscript")==0) expectScript(fAdminReadyScript, aLine, getDSFuncTableP()); else if (strucmp(aElementName,"syncendscript")==0) expectScript(fSyncEndScript, aLine, getDSFuncTableP()); #endif // - field mappings else if (strucmp(aElementName,"fieldmap")==0) { // check reference argument const char* ref = getAttr(aAttributes,"fieldlist"); if (!ref) { ReportError(true,"fieldmap missing 'fieldlist' attribute"); } else { // look for field list TMultiFieldDatatypesConfig *mfcfgP = DYN_CAST(getSyncAppBase()->getRootConfig()->fDatatypesConfigP); if (!mfcfgP) SYSYNC_THROW(TConfigParseException("no multifield config")); TFieldListConfig *cfgP = mfcfgP->getFieldList(ref); if (!cfgP) return fail("fieldlist '%s' not defined for fieldmap",ref); // - store field list reference in map fFieldMappings.fFieldListP=cfgP; // - let element handle parsing expectChildParsing(fFieldMappings); } } // - none known here else return inherited::localStartElement(aElementName,aAttributes,aLine); // ok return true; } // TCustomDSConfig::localStartElement // resolve void TCustomDSConfig::localResolve(bool aLastPass) { // convert legacy UTC flag to timezone setting if (fDataIsUTC) fDataTimeZone = TCTX_UTC; // scripts #ifdef SCRIPT_SUPPORT if (aLastPass) { // resolve map scripts now in case they haven't been resolved already ResolveDSScripts(); } #endif // resolve children fFieldMappings.Resolve(aLastPass); #ifdef SCRIPT_SUPPORT // Now everything is resolved, we can forget the resolve context if (aLastPass && fResolveContextP) { delete fResolveContextP; fResolveContextP = NULL; } #endif // resolve inherited inherited::localResolve(aLastPass); } // TCustomDSConfig::localResolve #ifdef SCRIPT_SUPPORT // resolve DS related scripts, but make sure we do that only once // Note: MAKE SURE that order of resolving is same as rebuilding order! void TCustomDSConfig::ResolveDSScripts(void) { // resolve if (!fDSScriptsResolved) { // resolve possible API level scripts first apiResolveScripts(); // resolve start and end scripts first TScriptContext::resolveScript(getSyncAppBase(),fAdminReadyScript,fResolveContextP,NULL); TScriptContext::resolveScript(getSyncAppBase(),fSyncEndScript,fResolveContextP,NULL); // - option filter generator script TScriptContext::resolveScript(getSyncAppBase(),fFieldMappings.fOptionFilterScript,fResolveContextP,fFieldMappings.fFieldListP); // - map scripts TScriptContext::resolveScript(getSyncAppBase(),fFieldMappings.fInitScript,fResolveContextP,fFieldMappings.fFieldListP); TScriptContext::resolveScript(getSyncAppBase(),fFieldMappings.fAfterReadScript,fResolveContextP,fFieldMappings.fFieldListP); TScriptContext::resolveScript(getSyncAppBase(),fFieldMappings.fBeforeWriteScript,fResolveContextP,fFieldMappings.fFieldListP); TScriptContext::resolveScript(getSyncAppBase(),fFieldMappings.fAfterWriteScript,fResolveContextP,fFieldMappings.fFieldListP); TScriptContext::resolveScript(getSyncAppBase(),fFieldMappings.fFinishScript,fResolveContextP,fFieldMappings.fFieldListP); TScriptContext::resolveScript(getSyncAppBase(),fFieldMappings.fFinalisationScript,fResolveContextP,fFieldMappings.fFieldListP); fDSScriptsResolved=true; } } // TCustomDSConfig::ResolveDSScripts #endif // transfer size limits from map to type static void transferMapOptionsToType(TFieldMapList &aFml, TMultiFieldItemType *aItemTypeP, sInt16 aMaxRepeat, sInt16 aRepInc) { TFieldMapList::iterator pos; TFieldMapItem *fmiP; for (pos=aFml.begin(); pos!=aFml.end(); pos++) { fmiP = *pos; #ifdef ARRAYDBTABLES_SUPPORT if (fmiP->isArray()) { // is array, recurse into fields of array TFieldMapArrayItem *fmaiP = static_cast(fmiP); transferMapOptionsToType( fmaiP->fArrayFieldMapList, aItemTypeP, fmaiP->fMaxRepeat, fmaiP->fRepeatInc ); } else #endif if (fmiP->fid>=0) { // normal map, apply to all related fields if (aMaxRepeat==0) aMaxRepeat=1; // unlimited repeat is only applied to first field #ifdef ARRAYFIELD_SUPPORT TFieldDefinition *fdP=aItemTypeP->getFieldDefinition(fmiP->fid); if (fdP && fdP->array) { // this is an array field, disable fid offsetting aMaxRepeat=1; } #endif for (sInt16 k=0; kgetFieldOptions(fmiP->fid+k*aRepInc); if (!optP) break; if ( optP->maxsize==FIELD_OPT_MAXSIZE_NONE || // no size defined yet optP->maxsize==FIELD_OPT_MAXSIZE_UNKNOWN || // or defined as unknown (optP->maxsize>sInt32(fmiP->maxsize) && // or defined size is larger than that one set in the mapping... fmiP->maxsize!=0) // ..but map size is not unlimited ) { // set new max size optP->maxsize = fmiP->maxsize; } if (fmiP->notruncate) optP->notruncate=true; } } } } // transferMapOptionsToType // Add (probably datastore-specific) limits such as MaxSize and NoTruncate to types void TCustomDSConfig::addTypeLimits(TLocalEngineDS *aLocalDatastoreP, TSyncSession *aSessionP) { // add field size limitations from map to all types TSyncItemTypePContainer::iterator pos; TSyncItemTypePContainer *typesP = &(aLocalDatastoreP->fRxItemTypes); for (uInt8 i=0; i<2; i++) { for (pos=typesP->begin(); pos!=typesP->end(); pos++) { // apply maps to type transferMapOptionsToType( fFieldMappings.fFieldMapList, static_cast(*pos), 1,1 // single instance only ); } typesP = &(aLocalDatastoreP->fTxItemTypes); } } // TCustomDSConfig::addTypeLimits // proptotype to make compiler happy bool parseMap(TCustomDSConfig *aCustomDSConfig, TConfigElement *cfgP, bool aIsArray, TFieldListConfig *aFieldListP, TFieldMapList &aFieldMapList, const char **aAttributes, bool aUpdateParams); // parse map items bool parseMap(TCustomDSConfig *aCustomDSConfig, TConfigElement *cfgP, bool aIsArray, TFieldListConfig *aFieldListP, TFieldMapList &aFieldMapList, const char **aAttributes, bool aUpdateParams) { TFieldMapItem *mapitemP = NULL; sInt16 fid = VARIDX_UNDEFINED; // get name const char* nam = cfgP->getAttr(aAttributes,"name"); // get base field reference is possible for arrays too, to specify the relevant array size const char* ref = cfgP->getAttr(aAttributes,aIsArray ? "sizefrom" : "references"); if (ref) { // get fid for referenced field if (!aCustomDSConfig->fFieldMappings.fFieldListP) SYSYNC_THROW(TConfigParseException("map with no field list defined")); #ifdef SCRIPT_SUPPORT fid = TConfigElement::getFieldIndex(ref,aCustomDSConfig->fFieldMappings.fFieldListP,aCustomDSConfig->fResolveContextP); #else fid = TConfigElement::getFieldIndex(ref,aCustomDSConfig->fFieldMappings.fFieldListP); #endif } // now decide what to do if (aUpdateParams) { // only updating params of existing map (non-arrays only!) // - search for existing map item by name TFieldMapList::iterator pos; for (pos=aFieldMapList.begin(); pos!=aFieldMapList.end(); pos++) { // check for name TFieldMapItem *fmiP = static_cast(*pos); if (strucmp(nam,fmiP->getName())==0) { // found it mapitemP = fmiP; } } if (!mapitemP) { return cfgP->fail("mapredefine must refer to an existing map"); } } else { // creating a new map #ifdef ARRAYDBTABLES_SUPPORT if (aIsArray) { // array container mapitemP = aCustomDSConfig->newFieldMapArrayItem(aCustomDSConfig,cfgP); // save size field reference if any mapitemP->fid=fid; // extra attributes for derived classes mapitemP->checkAttrs(aAttributes); // let array container parse details cfgP->expectChildParsing(*mapitemP); } #endif } if (!aIsArray) { // simple map cfgP->expectEmpty(); // plain maps may not have content // process creation of map item const char* type = cfgP->getAttr(aAttributes,"type"); const char* mode = cfgP->getAttr(aAttributes,"mode"); bool truncate = true; cfgP->getAttrBool(aAttributes,"truncate",truncate,true); if (!nam || !ref || !type) return cfgP->fail("map must have 'name', 'references', 'type' and 'mode' attributes at least"); if (fid==VARIDX_UNDEFINED) return cfgP->fail("map references unknown field '%s'",ref); // convert type sInt16 ty; if (!StrToEnum(DBFieldTypeNames,numDBfieldTypes,ty,type)) return cfgP->fail("unknown type '%s'",type); // convert mode // - needed flags bool rd,wr,fins,fupd; // - optional flags bool asparam=false,floatingts=false,needsfinalisation=false; if (mode) { rd=false,wr=false; fins=false; fupd=false; while (*mode) { if (tolower(*mode)=='r') rd=true; else if (tolower(*mode)=='w') { wr=true; fins=true; fupd=true; } // for both insert and update else if (tolower(*mode)=='i') { wr=true; fins=true; } // insert only else if (tolower(*mode)=='u') { wr=true; fupd=true; } // update only else if (tolower(*mode)=='p') { asparam=true; } // map as parameter (e.g. ODBC parameter mechanism for INSERT/UPDATE statements) else if (tolower(*mode)=='f') { floatingts=true; } // map as floating time field (will be written as-is, no conversion from/to DB time zone takes place) else if (tolower(*mode)=='x') { needsfinalisation=true; } // needs to be kept for finalisation at end of session (for relational link updates etc.) else return cfgP->fail("invalid mode '%c'",*mode); // next char mode++; } } else { // default mode for needed flags rd=true; wr=true; fins=true; fupd=true; } // Optionals // - size sInt32 sz=0; // default to unlimited if (!cfgP->getAttrLong(aAttributes,"size",sz,true)) cfgP->fail("invalid size specification"); // - statement index sInt16 setno=0; // default to 0 if (!cfgP->getAttrShort(aAttributes,"set_no",setno,true)) cfgP->fail("invalid set_no specification"); // create mapitem, name is DB field name if (!aUpdateParams) { mapitemP = aCustomDSConfig->newFieldMapItem(nam,cfgP); } mapitemP->fid=fid; mapitemP->dbfieldtype=(TDBFieldType)ty; mapitemP->readable=rd; mapitemP->writable=wr; mapitemP->for_insert=fins; mapitemP->for_update=fupd; mapitemP->as_param=asparam; mapitemP->floating_ts=floatingts; mapitemP->needs_finalisation=needsfinalisation; mapitemP->maxsize=(uInt32)sz; mapitemP->notruncate=!truncate; mapitemP->setNo=(uInt16)setno; // extra attributes for derived classes mapitemP->checkAttrs(aAttributes); } // if normal map if (!aUpdateParams) { // - and add it to the list aFieldMapList.push_back(mapitemP); } return true; } // parseMap // Field Map item // ============== TFieldMapItem::TFieldMapItem(const char *aElementName, TConfigElement *aParentElement) : TConfigElement(aElementName,aParentElement) { // default suitable for array container readable=false; writable=false; for_insert=false; for_update=false; as_param=false; floating_ts=false; needs_finalisation=false; setNo=0; // default set is 0 maxsize=0; // no max size notruncate=false; // allow truncation by default fid=VARIDX_UNDEFINED; // no field dbfieldtype=dbft_string; // default to string } // TFieldMapItem::TFieldMapItem #ifdef ARRAYDBTABLES_SUPPORT // array container // =============== TFieldMapArrayItem::TFieldMapArrayItem(TCustomDSConfig *aCustomDSConfigP, TConfigElement *aParentElement) : TFieldMapItem("array",aParentElement), fCustomDSConfigP(aCustomDSConfigP) { clear(); } // TFieldMapArrayItem::TFieldMapArrayItem TFieldMapArrayItem::~TFieldMapArrayItem() { // nop so far clear(); } // TFieldMapArrayItem::~TFieldMapArrayItem // init defaults void TFieldMapArrayItem::clear(void) { // init defaults // - clear values #ifdef OBJECT_FILTERING fNoItemsFilter.erase(); #endif fMaxRepeat=1; fRepeatInc=1; fStoreEmpty=false; #ifdef SCRIPT_SUPPORT // - clear scripts fInitScript.erase(); fAfterReadScript.erase(); fBeforeWriteScript.erase(); fAfterWriteScript.erase(); fFinishScript.erase(); fScriptsResolved=false; #endif // - clear map items TFieldMapList::iterator pos; for (pos=fArrayFieldMapList.begin(); pos!=fArrayFieldMapList.end(); pos++) delete (*pos); fArrayFieldMapList.clear(); // clear inherited inherited::clear(); } // TFieldMapArrayItem::clear #ifdef SCRIPT_SUPPORT void TFieldMapArrayItem::expectScriptUnresolved(string &aTScript,sInt32 aLine, const TFuncTable *aContextFuncs) { if (fScriptsResolved) { fail("array scripts must be defined before first within array"); } else { expectScript(aTScript,aLine,aContextFuncs); } } // TFieldMapArrayItem::expectScriptUnresolved #endif // config element parsing bool TFieldMapArrayItem::localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine) { // checking the elements if (strucmp(aElementName,"map")==0) { #ifdef SCRIPT_SUPPORT // early resolve basic map scripts so map entries can refer to local vars if (!fScriptsResolved) ResolveArrayScripts(); #endif // now parse new map item return parseMap(fCustomDSConfigP,this,false,fCustomDSConfigP->fFieldMappings.fFieldListP,fArrayFieldMapList,aAttributes, false); } /* nested arrays not yet supported // %%%% Note: if we do support them, we need to update // the script resolution stuff above and make ProcessArrayScripts recursive else if (strucmp(aElementName,"array")==0) #ifdef SCRIPT_SUPPORT // early resolve basic map scripts so map entries can refer to local vars if (!fScriptsResolved) ResolveArrayScripts(); #endif // now parse nested array map return parseMap(fBaseFieldMappings,this,true,fFieldListP,fArrayFieldMapList,aAttributes, false); */ else if (strucmp(aElementName,"maxrepeat")==0) expectInt16(fMaxRepeat); else if (strucmp(aElementName,"repeatinc")==0) expectInt16(fRepeatInc); else if (strucmp(aElementName,"storeempty")==0) expectBool(fStoreEmpty); #ifdef OBJECT_FILTERING else if (strucmp(aElementName,"noitemsfilter")==0) expectString(fNoItemsFilter); #endif #ifdef SCRIPT_SUPPORT else if (strucmp(aElementName,"initscript")==0) expectScriptUnresolved(fInitScript, aLine, fCustomDSConfigP->fFieldMappings.getDSFuncTableP()); else if (strucmp(aElementName,"afterreadscript")==0) expectScriptUnresolved(fAfterReadScript, aLine, fCustomDSConfigP->fFieldMappings.getDSFuncTableP()); else if (strucmp(aElementName,"beforewritescript")==0) expectScriptUnresolved(fBeforeWriteScript, aLine, fCustomDSConfigP->fFieldMappings.getDSFuncTableP()); else if (strucmp(aElementName,"afterwritescript")==0) expectScriptUnresolved(fAfterWriteScript, aLine, fCustomDSConfigP->fFieldMappings.getDSFuncTableP()); else if (strucmp(aElementName,"finishscript")==0) expectScriptUnresolved(fFinishScript, aLine, fCustomDSConfigP->fFieldMappings.getDSFuncTableP()); #endif // - none known here else return inherited::localStartElement(aElementName,aAttributes,aLine); // ok return true; } // TFieldMapArrayItem::localStartElement #ifdef SCRIPT_SUPPORT // process single array's scripts (resolve or rebuild them) void TFieldMapArrayItem::ResolveArrayScripts(void) { // resolve TScriptContext::resolveScript(getSyncAppBase(),fInitScript,fCustomDSConfigP->fResolveContextP,fCustomDSConfigP->fFieldMappings.fFieldListP); TScriptContext::resolveScript(getSyncAppBase(),fAfterReadScript,fCustomDSConfigP->fResolveContextP,fCustomDSConfigP->fFieldMappings.fFieldListP); TScriptContext::resolveScript(getSyncAppBase(),fBeforeWriteScript,fCustomDSConfigP->fResolveContextP,fCustomDSConfigP->fFieldMappings.fFieldListP); TScriptContext::resolveScript(getSyncAppBase(),fAfterWriteScript,fCustomDSConfigP->fResolveContextP,fCustomDSConfigP->fFieldMappings.fFieldListP); TScriptContext::resolveScript(getSyncAppBase(),fFinishScript,fCustomDSConfigP->fResolveContextP,fCustomDSConfigP->fFieldMappings.fFieldListP); fScriptsResolved=true; } // TFieldMapArrayItem::ResolveArrayScripts #endif // resolve void TFieldMapArrayItem::localResolve(bool aLastPass) { if (aLastPass) { #ifdef SCRIPT_SUPPORT // resolve map scripts now in case they haven't been resolved already if (!fScriptsResolved) ResolveArrayScripts(); #endif } // resolve inherited inherited::localResolve(aLastPass); } // TFieldMapArrayItem::localResolve #endif // field mappings // ============== TFieldMappings::TFieldMappings(const char* aName, TConfigElement *aParentElement) : TConfigElement(aName,aParentElement), fFieldListP(NULL) { clear(); } // TFieldMappings::TFieldMappings TFieldMappings::~TFieldMappings() { // nop so far clear(); } // TFieldMappings::~TFieldMappings // init defaults void TFieldMappings::clear(void) { // init defaults // - clear map items TFieldMapList::iterator pos; for (pos=fFieldMapList.begin(); pos!=fFieldMapList.end(); pos++) delete (*pos); fFieldMapList.clear(); #ifdef SCRIPT_SUPPORT // - clear scripts fOptionFilterScript.erase(); fInitScript.erase(); fAfterReadScript.erase(); fBeforeWriteScript.erase(); fAfterWriteScript.erase(); fFinishScript.erase(); // fFinishScript is now in use for exit call of datastore handling fFinalisationScript.erase(); // called for each item with fields having the needs_finalisation set (BEFORE fFinishScript) #endif // - clear reference fFieldListP=NULL; // clear inherited inherited::clear(); } // TFieldMappings::clear #ifdef SCRIPT_SUPPORT void TFieldMappings::expectScriptUnresolved(string &aTScript,sInt32 aLine, const TFuncTable *aContextFuncs) { TCustomDSConfig *dscfgP = static_cast(getParentElement()); if (dscfgP->fDSScriptsResolved) { fail("database scripts must be defined before first "); } else { expectScript(aTScript,aLine,aContextFuncs); } } // TFieldMappings::expectScriptUnresolved #endif // config element parsing bool TFieldMappings::localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine) { TCustomDSConfig *dscfgP = static_cast(getParentElement()); // checking the elements if (strucmp(aElementName,"map")==0) { #ifdef SCRIPT_SUPPORT // early resolve basic datastore scripts so map entries can refer to local vars already dscfgP->ResolveDSScripts(); #endif // now parse map return parseMap(dscfgP,this,false,fFieldListP,fFieldMapList,aAttributes, false); } else if (strucmp(aElementName,"mapredefine")==0) { // allow specifying parameters for some maps in a automap generated mappings list return parseMap(dscfgP,this,false,fFieldListP,fFieldMapList,aAttributes, true); } else if (strucmp(aElementName,"automap")==0) { // auto-create map entries for all fields in the field list // (this is a convenience function to allow nearly identical usage of textdb and dbapi with text module) if (!fFieldListP) SYSYNC_THROW(TConfigParseException("automap with no field list defined")); // check mode option bool indexAsName=false; if (!getAttrBool(aAttributes,"indexasname",indexAsName,true)) fail("invalid indexasname value"); // iterate through field definitions and create a string mapping TFieldDefinitionList::iterator pos; sInt16 fid=0; string fieldname; for (pos=fFieldListP->fFields.begin(); pos!=fFieldListP->fFields.end(); ++pos, ++fid) { // create DB field name if (indexAsName) StringObjPrintf(fieldname,"%hd",fid); // use fid as field name else fieldname=TCFG_CSTR(pos->fieldname); // use internal field's name // create mapitem using field index/itemfield name as DB field name TFieldMapItem *mapitemP = static_cast(getParentElement())->newFieldMapItem(fieldname.c_str(),this); mapitemP->fid=fid; // fid corresponds with position in field definitions list mapitemP->dbfieldtype = pos->type==fty_timestamp ? dbft_timestamp : dbft_string; // map timestamps as such, otherwise all are strings mapitemP->readable=true; mapitemP->writable=true; mapitemP->for_insert=true; mapitemP->for_update=true; // - and add it to the list fFieldMapList.push_back(mapitemP); } // that's it expectEmpty(); } #ifdef ARRAYDBTABLES_SUPPORT else if (strucmp(aElementName,"array")==0) { #ifdef SCRIPT_SUPPORT // early resolve basic datastore scripts so array map entries can refer to local vars already! dscfgP->ResolveDSScripts(); #endif // now parse array map return parseMap(dscfgP,this,true,fFieldListP,fFieldMapList,aAttributes,false); } #endif #ifdef SCRIPT_SUPPORT else if (strucmp(aElementName,"optionfilterscript")==0) expectScriptUnresolved(fOptionFilterScript, aLine, getDSFuncTableP()); else if (strucmp(aElementName,"initscript")==0) expectScriptUnresolved(fInitScript, aLine, getDSFuncTableP()); else if (strucmp(aElementName,"afterreadscript")==0) expectScriptUnresolved(fAfterReadScript, aLine, getDSFuncTableP()); else if (strucmp(aElementName,"beforewritescript")==0) expectScriptUnresolved(fBeforeWriteScript, aLine, getDSFuncTableP()); else if (strucmp(aElementName,"afterwritescript")==0) expectScriptUnresolved(fAfterWriteScript, aLine, getDSFuncTableP()); else if (strucmp(aElementName,"finishscript")==0) expectScriptUnresolved(fFinishScript, aLine, getDSFuncTableP()); else if (strucmp(aElementName,"finalisationscript")==0) expectScriptUnresolved(fFinalisationScript, aLine, getDSFuncTableP()); #endif // - none known here else return inherited::localStartElement(aElementName,aAttributes,aLine); // ok return true; } // TFieldMappings::localStartElement // resolve void TFieldMappings::localResolve(bool aLastPass) { // resolve each map TFieldMapList::iterator pos; for (pos=fFieldMapList.begin(); pos!=fFieldMapList.end(); pos++) { (*pos)->Resolve(aLastPass); } // resolve inherited inherited::localResolve(aLastPass); } // TFieldMappings::localResolve #ifdef SCRIPT_SUPPORT // access to DS func table pointer const TFuncTable *TFieldMappings::getDSFuncTableP(void) { return static_cast(getParentElement())->getDSFuncTableP(); } // TFieldMappings::getDSFuncTableP #endif /* * Implementation of TCustomImplDS */ // constructor TCustomImplDS::TCustomImplDS( TCustomDSConfig *aConfigP, sysync::TSyncSession *aSessionP, const char *aName, uInt32 aCommonSyncCapMask ) : inherited(aConfigP,aSessionP, aName, aCommonSyncCapMask) { fNeedFinalisation=false; // save pointer to config record fConfigP=aConfigP; fMultiFolderDB = fConfigP->fMultiFolderDB; // make a local copy of the typed agent pointer fAgentP=static_cast(fSessionP); // make a local copy of the typed agent config pointer fAgentConfigP = DYN_CAST( aSessionP->getRootConfig()->fAgentConfigP ); if (!fAgentConfigP) SYSYNC_THROW(TSyncException(DEBUGTEXT("TCustomImplDS finds no AgentConfig","odds7"))); #ifdef SCRIPT_SUPPORT fScriptContextP=NULL; // no context yet #endif // init these keys - these might or might not be used by descendants fFolderKey.erase(); // the folder key is undefined fTargetKey.erase(); // the target key is undefined // clear rest InternalResetDataStore(); } // TCustomImplDS::TCustomImplDS TCustomImplDS::~TCustomImplDS() { InternalResetDataStore(); } // TCustomImplDS::~TCustomImplDS /// @brief called while agent is still fully ok, so we must clean up such that later call of destructor does NOT access agent any more void TCustomImplDS::announceAgentDestruction(void) { // reset myself InternalResetDataStore(); // make sure we don't access the agent any more // Note: as CustomImplDS always needs to be derived, we don't call // engTerminateDatastore() here, but rely on descendants having done that already fAgentP = NULL; // call inherited inherited::announceAgentDestruction(); } // TCustomImplDS::announceAgentDestruction /// @brief called to reset datastore /// @note must be safe to be called multiple times and even after announceAgentDestruction() void TCustomImplDS::InternalResetDataStore(void) { #ifdef SCRIPT_SUPPORT fOptionFilterTested=false; // not tested yet fOptionFilterWorksOnDBLevel=true; // assume true #endif // delete sync set DeleteSyncSet(); // delete finalisation queue TMultiFieldItemList::iterator pos; for (pos=fFinalisationQueue.begin();pos!=fFinalisationQueue.end();pos++) delete (*pos); // delete the item fFinalisationQueue.clear(); #ifndef BINFILE_ALWAYS_ACTIVE fGetPhase=gph_done; // must be initialized first by startDataRead fGetPhasePrepared=false; // Clear map table and sync set lists fMapTable.clear(); #endif // BINFILE_ALWAYS_ACTIVE #ifdef BASED_ON_BINFILE_CLIENT fSyncSetLoaded=false; #endif // BASED_ON_BINFILE_CLIENT fNoSingleItemRead=false; // assume we can read single items if (fAgentP) { // forget script context #ifdef SCRIPT_SUPPORT if (fScriptContextP) { delete fScriptContextP; // forget context fScriptContextP=NULL; } #endif } #ifdef DBAPI_TUNNEL_SUPPORT // Tunnel DB access support fTunnelReadStarted = false; #endif } // TCustomImplDS::InternalResetDataStore // helper for getting a field pointer (local script var or item's field) TItemField *TCustomImplDS::getMappedBaseFieldOrVar(TMultiFieldItem &aItem, sInt16 aFid) { // get base field (array itself for array fields, not an element) #ifdef SCRIPT_SUPPORT if (fScriptContextP) return fScriptContextP->getFieldOrVar(&aItem,aFid); else return aItem.getField(aFid); #else return aItem.getField(aFid); #endif } // TCustomImplDS::getMappedBaseFieldOrVar // helper for getting a field pointer (local script var or item's field) TItemField *TCustomImplDS::getMappedFieldOrVar(TMultiFieldItem &aItem, sInt16 aFid, sInt16 aRepOffset, bool aExistingOnly) { TItemField *fieldP=NULL; // get field (or base field) #ifdef ARRAYFIELD_SUPPORT fieldP = getMappedBaseFieldOrVar(aItem,aFid); if (!fieldP) return NULL; // no field if (fieldP->isArray()) { // use aRepOffset as array index fieldP = fieldP->getArrayField(aRepOffset,aExistingOnly); } else #endif { // use aRepOffset as fid offset #ifdef SCRIPT_SUPPORT if (aFid<0) aRepOffset=0; // locals are never offset #endif fieldP = getMappedBaseFieldOrVar(aItem,aFid+aRepOffset); } return fieldP; } // TCustomImplDS::getMappedFieldOrVar // inform logic of coming state change localstatus TCustomImplDS::dsBeforeStateChange(TLocalEngineDSState aOldState,TLocalEngineDSState aNewState) { if (aNewState>=dssta_dataaccessdone && aOldStatefScriptContextDatastore=this; while (fFinalisationQueue.size()>0) { // process finalisation script TMultiFieldItem *itemP = *(fFinalisationQueue.begin()); PDEBUGBLOCKFMTCOLL(("Finalizing","Finalizing item","LocalID=%s",itemP->getLocalID())); TScriptContext::execute( fScriptContextP,fConfigP->fFieldMappings.fFinalisationScript,fConfigP->getDSFuncTableP(),fAgentP, itemP,true // pass the item from the queue, is writable (mainly to allow fields to be passed as by-ref params) ); PDEBUGENDBLOCK("Finalizing"); // no longer needed delete itemP; // remove from queue fFinalisationQueue.erase(fFinalisationQueue.begin()); } PDEBUGENDBLOCK("Finalisation"); } // Finally, call the finish script of the field mappings fWriting=false; fInserting=false; fDeleting=false; fAgentP->fScriptContextDatastore=this; if (!TScriptContext::execute(fScriptContextP,fConfigP->fFieldMappings.fFinishScript,fConfigP->getDSFuncTableP(),fAgentP)) return 510; // script error -> DB error #endif } // let inherited do its stuff as well return inherited::dsBeforeStateChange(aOldState,aNewState); } // TCustomImplDS::dsBeforeStateChange // inform logic of happened state change localstatus TCustomImplDS::dsAfterStateChange(TLocalEngineDSState aOldState,TLocalEngineDSState aNewState) { if (aNewState==dssta_completed) { // completed now, call finish script #ifdef SCRIPT_SUPPORT // process sync end script fAgentP->fScriptContextDatastore=this; TScriptContext::execute(fScriptContextP,fConfigP->fSyncEndScript,fConfigP->getDSFuncTableP(),fAgentP); #endif // reset in case that we restart DeleteSyncSet(); #ifdef BASED_ON_BINFILE_CLIENT fSyncSetLoaded=false; #endif } // let inherited do its stuff as well return inherited::dsAfterStateChange(aOldState,aNewState); } // TCustomImplDS::dsAfterStateChange #ifndef BINFILE_ALWAYS_ACTIVE // mark all map entries as deleted bool TCustomImplDS::deleteAllMaps(void) { string sql,s; bool allok=true; TMapContainer::iterator pos; for (pos=fMapTable.begin();pos!=fMapTable.end();pos++) { (*pos).deleted=true; // deleted } PDEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,("deleteAllMaps: all existing map entries (%ld) now marked deleted=1",(long)fMapTable.size())); return allok; } // TCustomImplDS::deleteAllMaps // find non-deleted map entry by local ID/maptype TMapContainer::iterator TCustomImplDS::findMapByLocalID(const char *aLocalID,TMapEntryType aEntryType, bool aDeletedAsWell) { TMapContainer::iterator pos; if (aLocalID) { for (pos=fMapTable.begin();pos!=fMapTable.end();pos++) { if ( (*pos).localid==aLocalID && (*pos).entrytype==aEntryType // && !(*pos).remoteid.empty() // Note: was ok in old versions, but now we can have map entries from resume with empty localID && (aDeletedAsWell || !(*pos).deleted) // if selected, don't show deleted entries ) { // found return pos; } } } return fMapTable.end(); } // TCustomImplDS::findMapByLocalID // find map entry by remote ID TMapContainer::iterator TCustomImplDS::findMapByRemoteID(const char *aRemoteID) { TMapContainer::iterator pos; if (aRemoteID) { for (pos=fMapTable.begin();pos!=fMapTable.end();pos++) { if ( (*pos).remoteid==aRemoteID && (*pos).entrytype == mapentry_normal && !(*pos).deleted // only plain normal non-deleted maps (no tempid or mapforresume) ) { // found return pos; } } } return fMapTable.end(); } // TCustomImplDS::findMapByRemoteID #ifdef SYSYNC_SERVER // - called when a item in the sync set changes its localID (due to local DB internals) // Datastore must make sure that possibly cached items get updated void TCustomImplDS::dsLocalIdHasChanged(const char *aOldID, const char *aNewID) { // find item in map TMapContainer::iterator pos=findMapByLocalID(aOldID,mapentry_normal); // only plain maps, no deleted ones if (pos!=fMapTable.end()) { // found, modify now // NOTE: we may not modify a localid, but must delete the entry and add a new one // - get remote ID string remoteid = (*pos).remoteid; uInt32 mapflags = (*pos).mapflags; // - mark old map entry as deleted (*pos).deleted=true; // - create new one modifyMap(mapentry_normal,aNewID,remoteid.c_str(),mapflags,false); } // let base class do what is needed to update the item itself inherited::dsLocalIdHasChanged(aOldID, aNewID); } // TCustomImplDS::dsLocalIdHasChanged #endif /// @brief modify internal map table /// @note /// - if aDelete is set, map entry will be deleted /// - aClearFlags (default=all) will be cleared when updating only /// - aMapFlags will be set when updating /// - if aRemoteID is NULL when updating an existing (not marked deleted) item, existing remoteID will NOT be modified /// - otherwise, map item will be added or updated. /// - routine makes sure that there is no more than one map for each localID/entrytype and /// each remoteID. /// - remoteID can also be a temporary localID used by server to send to clients with too small MaxGUIDSize (mapflag_tempidmap set) /// - routine will re-activate deleted entries to avoid unnecessary delete/insert void TCustomImplDS::modifyMap(TMapEntryType aEntryType, const char *aLocalID, const char *aRemoteID, uInt32 aMapFlags, bool aDelete, uInt32 aClearFlags) { TMapContainer::iterator pos=fMapTable.end(); DEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,( "ModifyMap called: aEntryType=%s, aLocalID='%s, aRemoteid='%s', aMapflags=0x%lX, aDelete=%d", MapEntryTypeNames[aEntryType], aLocalID && *aLocalID ? aLocalID : "", aRemoteID ? (*aRemoteID ? aRemoteID : "") : "", (long)aMapFlags, (int)aDelete )); // - if there is a localID, search map entry (even if it is deleted) if (aLocalID && *aLocalID!=0) { for (pos=fMapTable.begin();pos!=fMapTable.end();pos++) { if ( // localID and entrytype matches (*pos).localid==aLocalID && (*pos).entrytype==aEntryType ) { PDEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,( "- found entry by entrytype/localID='%s' - remoteid='%s', mapflags=0x%lX, changed=%d, deleted=%d, added=%d, markforresume=%d, savedmark=%d", aLocalID, (*pos).remoteid.c_str(), (long)(*pos).mapflags, (int)(*pos).changed, (int)(*pos).deleted, (int)(*pos).added, (int)(*pos).markforresume, (int)(*pos).savedmark )); break; } } } else aLocalID=NULL; // decide what to do if (aDelete) { // delete if (!aLocalID) { if (!aRemoteID) return; // nop // we need to search by remoteID first pos=findMapByRemoteID(aRemoteID); #ifdef SYDEBUG if (pos!=fMapTable.end()) { DEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,( "- found entry by remoteID='%s' - localid='%s', mapflags=0x%lX, changed=%d, deleted=%d, added=%d, markforresume=%d, savedmark=%d", aRemoteID, (*pos).localid.c_str(), (long)(*pos).mapflags, (int)(*pos).changed, (int)(*pos).deleted, (int)(*pos).added, (int)(*pos).markforresume, (int)(*pos).savedmark )); } #endif } if (pos==fMapTable.end()) return; // not found, nop // mark deleted if ((*pos).added) { // has been added in this session and not yet saved // so it does not yet exist in the DB at all // - simply forget entry fMapTable.erase(pos); // - done, ok return; } // entry has already been saved to DB before - only mark deleted (*pos).deleted=true; } // delete else { // update or add if (pos==fMapTable.end()) { PDEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,( "- found no matching entry for localID '%s' - creating new one, added=true", aLocalID )); // add, because there is not yet an item with that localid/entrytype TMapEntry entry; entry.entrytype=aEntryType; entry.added=true; entry.changed=true; entry.localid=aLocalID; AssignString(entry.remoteid,aRemoteID); // if NULL, remoteID will be empty entry.savedmark=false; entry.markforresume=false; entry.mapflags=0; // none set by default fMapTable.push_front(entry); pos=fMapTable.begin(); // first entry is new entry } else { PDEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,( "- matching entry found - re-activating deleted and/or updating contents if needed" )); /* %%% NO!!!! plain wrong - because this causes added and later changed entries never be added to the DB! // %%% No room for paranoia here - makes things worse! // just to make sure - added should not be set here // (if we delete an added one before, it will be completely deleted from the list again) (*pos).added=false; */ // check if contents change, update if so if ( (((*pos).mapflags & ~mapflag_useforresume) != aMapFlags) || // flags different (useForResume not tested!) (aRemoteID && !((*pos).remoteid==aRemoteID)) // remoteID different ) { // new RemoteID (but not NULL = keep existing) or different mapflags were passed -> this is a real change if (aRemoteID) (*pos).remoteid=aRemoteID; (*pos).changed=true; // really changed compared to what is already in DB } } // now item exists, set details (*pos).deleted=false; // in case we had it deleted before, but not yet saved // clear those flags shown in aClearFlags (by default: all) and set those in aMapFlags (*pos).mapflags = ((*pos).mapflags & ~aClearFlags) | aMapFlags; // now remove all other items with same remoteID (except if we have no or empty remoteID) if (aEntryType==mapentry_normal && aRemoteID && *aRemoteID) { // %%% note: this is strictly necessary only for add, but cleans up for update TMapContainer::iterator pos2; for (pos2=fMapTable.begin();pos2!=fMapTable.end();pos2++) { if (pos2!=pos && (*pos2).remoteid==aRemoteID && (*pos2).entrytype==aEntryType) { // found another one with same remoteID/entrytype PDEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,( "- cleanup: removing same remoteID from other entry with localid='%s', mapflags=0x%lX, changed=%d, deleted=%d, added=%d, markforresume=%d, savedmark=%d", (*pos2).localid.c_str(), (long)(*pos2).mapflags, (int)(*pos2).changed, (int)(*pos2).deleted, (int)(*pos2).added, (int)(*pos2).markforresume, (int)(*pos2).savedmark )); // this remoteID is invalid for sure as we just have assigned it to another item - remove it (*pos2).remoteid.erase(); (*pos2).changed=true; // make sure it gets saved } } } } // modify or add } // TCustomImplDS::modifyMap #endif // not BINFILE_ALWAYS_ACTIVE // delete syncset // - if aContentsOnly, only item data will be deleted, but localID/containerid will // be retained void TCustomImplDS::DeleteSyncSet(bool aContentsOnly) { TSyncSetList::iterator pos; for (pos=fSyncSetList.begin();pos!=fSyncSetList.end();pos++) { // delete contained item, if any if ((*pos)->itemP) { delete ((*pos)->itemP); (*pos)->itemP=NULL; } if (!aContentsOnly) delete (*pos); // delete syncsetitem itself } if (!aContentsOnly) fSyncSetList.clear(); } // TCustomImplDS::DeleteSyncSet // - get container ID for specified localid bool TCustomImplDS::getContainerID(const char *aLocalID, string &aContainerID) { TSyncSetList::iterator pos = findInSyncSet(aLocalID); if (pos!=fSyncSetList.end()) { aContainerID = (*pos)->containerid; return true; // found } return false; // not found } // TCustomImplDS::getContainerID // find entry in sync set by localid TSyncSetList::iterator TCustomImplDS::findInSyncSet(const char *aLocalID) { TSyncSetList::iterator pos; for (pos=fSyncSetList.begin();pos!=fSyncSetList.end();pos++) { if ((*pos)->localid==aLocalID) { // found return pos; } } return fSyncSetList.end(); } // TCustomImplDS::findInSyncSet // called when message processing void TCustomImplDS::dsEndOfMessage(void) { // let ancestor do things inherited::dsEndOfMessage(); } // TCustomImplDS::dsEndOfMessage // Simple DB access interface methods // - returns true if database implementation can only update all fields of a record at once bool TCustomImplDS::dsReplaceWritesAllDBFields(void) { // return true if we should read record from DB before replacing. return fConfigP->fUpdateAllFields; } // TCustomImplDS::dsReplaceWritesAllDBFields #ifndef BINFILE_ALWAYS_ACTIVE // returns true if DB implementation supports resume (saving of resume marks, alert code, pending maps, tempGUIDs) bool TCustomImplDS::dsResumeSupportedInDB(void) { #ifdef BASED_ON_BINFILE_CLIENT if (binfileDSActive()) return inherited::dsResumeSupportedInDB(); else #endif return fConfigP && fConfigP->fResumeSupport; } // TCustomImplDS::dsResumeSupportedInDB // returns true if DB implementation supports resuming in midst of a chunked item (can save fPIxxx.. and related admin data) bool TCustomImplDS::dsResumeChunkedSupportedInDB(void) { #ifdef BASED_ON_BINFILE_CLIENT if (binfileDSActive()) return inherited::dsResumeChunkedSupportedInDB(); else #endif return fConfigP && fConfigP->fResumeItemSupport; } // TCustomImplDS::dsResumeChunkedSupportedInDB #endif // BINFILE_ALWAYS_ACTIVE #ifdef OBJECT_FILTERING // - returns true if DB implementation can also apply special filters like CGI-options // /dr(x,y) etc. during fetching bool TCustomImplDS::dsOptionFilterFetchesFromDB(void) { #ifndef SYSYNC_TARGET_OPTIONS // there are no ranges to filter at all return true; // we can "filter" this (nothing) #else // no filter range set: yes, we can filter if (fDateRangeStart==0 && fDateRangeEnd==0) return true; // we can "filter" this // see if a script provides a solution #ifdef SCRIPT_SUPPORT if (!fOptionFilterTested) { fOptionFilterTested=true; // call script to take measures such that database implementation can // filter, returns true if filtering is entirely possible // (e.g. for ODBC, script should generate appropriate WHERE clause and set it with SETSQLFILTER()) fAgentP->fScriptContextDatastore=this; fOptionFilterWorksOnDBLevel = TScriptContext::executeTest( false, // assume we cannot filter if no script or script returns nothing fScriptContextP, // context fConfigP->fFieldMappings.fOptionFilterScript, // the script fConfigP->getDSFuncTableP(),fAgentP // funcdefs/context ); } if (fOptionFilterWorksOnDBLevel) return true; #endif // we can't filter, let anchestor try return inherited::dsOptionFilterFetchesFromDB(); #endif } // TCustomImplDS::dsOptionFilterFetchesFromDB #endif // OBJECT_FILTERING /// sync login (into this database) /// @note might be called several times (auth retries at beginning of session) /// @note must update the following saved AND current state variables /// - in TLocalEngineDS: fLastRemoteAnchor, fLastLocalAnchor, fResumeAlertCode, fFirstTimeSync /// - for client: fPendingAddMaps /// - for server: fTempGUIDMap /// - in TStdLogicDS: fPreviousSyncTime, fCurrentSyncTime /// - in TCustomImplDS: fCurrentSyncCmpRef, fCurrentSyncIdentifier, fPreviousToRemoteSyncCmpRef, /// fPreviousToRemoteSyncIdentifier, fPreviousSuspendCmpRef, fPreviousSuspendIdentifier /// - in derived classes: whatever else belongs to dsSavedAdmin and dsCurrentAdmin state localstatus TCustomImplDS::implMakeAdminReady( const char *aDeviceID, // remote device URI (device ID) const char *aDatabaseID, // database ID const char *aRemoteDBID // database ID of remote device ) { localstatus sta=LOCERR_OK; // assume ok string sql; // init state variables // dsSavedAdmin // - of TLocalEngineDS: fFirstTimeSync=true; // assume first time sync fLastRemoteAnchor.erase(); // remote anchor not known yet fResumeAlertCode=0; // no session to resume // - of TStdLogicDS: fPreviousSyncTime=0; // - of TCustomImplDS: fPreviousToRemoteSyncCmpRef=0; // no previous session fPreviousToRemoteSyncIdentifier.erase(); fPreviousSuspendCmpRef=0; // no previous suspend fPreviousSuspendIdentifier.erase(); // dsCurrentAdmin // - of TLocalEngineDS: // - of TStdLogicDS: fCurrentSyncTime=0; // - of TCustomImplDS: fCurrentSyncCmpRef=0; fCurrentSyncIdentifier.erase(); #ifndef BINFILE_ALWAYS_ACTIVE fMapTable.clear(); // map is empty to begin with #endif // now get admin data SYSYNC_TRY { #ifdef SCRIPT_SUPPORT // rebuild context for all scripts (if not already resolved) // Note: unlike while reading config, here all maps and scripts are already available // so this will build the entire context at once. if (!fScriptContextP) { // Rebuild order MUST be same as resolving order (see ResolveDSScripts()) // - scripts in possible derivates apiRebuildScriptContexts(); // - adminready and end scripts outside the fieldmappings TScriptContext::rebuildContext(fSessionP->getSyncAppBase(),fConfigP->fAdminReadyScript,fScriptContextP,fSessionP); TScriptContext::rebuildContext(fSessionP->getSyncAppBase(),fConfigP->fSyncEndScript,fScriptContextP,fSessionP); // - scripts within fieldmappings TScriptContext::rebuildContext(fSessionP->getSyncAppBase(),fConfigP->fFieldMappings.fOptionFilterScript,fScriptContextP,fSessionP); TScriptContext::rebuildContext(fSessionP->getSyncAppBase(),fConfigP->fFieldMappings.fInitScript,fScriptContextP,fSessionP); TScriptContext::rebuildContext(fSessionP->getSyncAppBase(),fConfigP->fFieldMappings.fAfterReadScript,fScriptContextP,fSessionP); TScriptContext::rebuildContext(fSessionP->getSyncAppBase(),fConfigP->fFieldMappings.fBeforeWriteScript,fScriptContextP,fSessionP); TScriptContext::rebuildContext(fSessionP->getSyncAppBase(),fConfigP->fFieldMappings.fAfterWriteScript,fScriptContextP,fSessionP); TScriptContext::rebuildContext(fSessionP->getSyncAppBase(),fConfigP->fFieldMappings.fFinishScript,fScriptContextP,fSessionP); TScriptContext::rebuildContext(fSessionP->getSyncAppBase(),fConfigP->fFieldMappings.fFinalisationScript,fScriptContextP,fSessionP); #ifdef ARRAYDBTABLES_SUPPORT // - rebuild array script vars TFieldMapList::iterator pos; for (pos=fConfigP->fFieldMappings.fFieldMapList.begin(); pos!=fConfigP->fFieldMappings.fFieldMapList.end(); pos++) { if ((*pos)->isArray()) { TFieldMapArrayItem *fmaiP = DYN_CAST(*pos); if (fmaiP) { // rebuild // %%% note, this is not capable of nested arrays yet TScriptContext::rebuildContext(fSessionP->getSyncAppBase(),fmaiP->fInitScript,fScriptContextP,fSessionP); TScriptContext::rebuildContext(fSessionP->getSyncAppBase(),fmaiP->fAfterReadScript,fScriptContextP,fSessionP); TScriptContext::rebuildContext(fSessionP->getSyncAppBase(),fmaiP->fBeforeWriteScript,fScriptContextP,fSessionP); TScriptContext::rebuildContext(fSessionP->getSyncAppBase(),fmaiP->fAfterWriteScript,fScriptContextP,fSessionP); TScriptContext::rebuildContext(fSessionP->getSyncAppBase(),fmaiP->fFinishScript,fScriptContextP,fSessionP); } } } #endif // now instantiate variables TScriptContext::buildVars(fScriptContextP); } #endif #ifdef BASED_ON_BINFILE_CLIENT if (binfileDSActive()) { // binfile's implMakeAdminReady will do the job sta = inherited::implMakeAdminReady(aDeviceID, aDatabaseID, aRemoteDBID); } else #endif // BASED_ON_BINFILE_CLIENT { #ifndef BINFILE_ALWAYS_ACTIVE // Load admin data from TXXXApiDS (ODBC, text or derived class' special implementation) sta = apiLoadAdminData( aDeviceID, // remote device URI (device ID) aDatabaseID, // database ID aRemoteDBID // database ID of remote device ); #endif } // set error if one occurred during load if (sta==LOCERR_OK) { // extra check: if we get empty remote anchor, this is a first-time sync even if DB claims the opposite if (fLastRemoteAnchor.empty()) fFirstTimeSync=true; // create identifier if we don't have it stored in the DB if (!fConfigP->fStoreSyncIdentifiers) { // we generate the identifiers as ISO8601 UTC string from the timestamp TimestampToISO8601Str(fPreviousToRemoteSyncIdentifier,fPreviousToRemoteSyncCmpRef,TCTX_UTC,false,false); TimestampToISO8601Str(fPreviousSuspendIdentifier,fPreviousSuspendCmpRef,TCTX_UTC,false,false); } // determine time of this sync fCurrentSyncTime= fAgentP->getDatabaseNowAs(TCTX_UTC); // by default, these two are equal // (but if DB cannot write items with timestamp exactly==fCurrentSyncTime, fCurrentSyncCmpRef might be a later time, like end-of-session) fCurrentSyncCmpRef = fCurrentSyncTime; // admin ready now, call script that may access DB to fetch some extra options #ifdef SCRIPT_SUPPORT fAgentP->fScriptContextDatastore=this; if (!TScriptContext::executeTest(true,fScriptContextP,fConfigP->fAdminReadyScript,fConfigP->getDSFuncTableP(),fAgentP)) sta=510; // script returns false or fails -> DB error #endif if (sta==LOCERR_OK) { // successful so far, now allow for early startDataRead to occur if configured on api level sta = apiEarlyDataAccessStart(); if (sta==508) { // special case: the database requests a slow sync for internal reasons (like change tracking disabled) // - force slow sync by removing last anchor fLastRemoteAnchor.erase(); sta = LOCERR_OK; } } } // if apiLoadAdminData successful } SYSYNC_CATCH(exception &e) PDEBUGPRINTFX(DBG_ERROR,("implMakeAdminReady exception: %s",e.what())); sta=510; SYSYNC_ENDCATCH // done return sta; } // TCustomImplDS::implMakeAdminReady // start data read localstatus TCustomImplDS::implStartDataRead() { localstatus sta = LOCERR_OK; // get field map list TFieldMapList &fml = fConfigP->fFieldMappings.fFieldMapList; // check if we have fileds that must be finalized or array fields at all (to avoid unneeded operations if not) TFieldMapList::iterator pos; #ifdef ARRAYDBTABLES_SUPPORT fHasArrayFields=false; // until we KNOW otherwise #endif fNeedFinalisation=false; // until we KNOW otherwise for (pos=fml.begin(); pos!=fml.end(); pos++) { // - check finalisation if ((*pos)->needs_finalisation) fNeedFinalisation=true; // - check array mappings #ifdef ARRAYDBTABLES_SUPPORT if ((*pos)->isArray()) fHasArrayFields=true; #endif } #ifdef BASED_ON_BINFILE_CLIENT if (binfileDSActive()) { // further preparation is in binfileds sta = inherited::implStartDataRead(); if (sta==LOCERR_OK) { // now make sure the syncset is loaded sta = makeSyncSetLoaded( fSlowSync // all items with data needed for slow sync #ifdef OBJECT_FILTERING || fFilteringNeededForAll // all item data needed for dynamic filtering #endif || CRC_CHANGE_DETECTION // all item data needed when binfile must detect changes using CRC ); } } else #endif // BASED_ON_BINFILE_CLIENT { #ifndef BINFILE_ALWAYS_ACTIVE // kill all map entries if slow sync (but not if resuming!!) if (fSlowSync && !isResuming()) { // mark all map entries as deleted deleteAllMaps(); } // - count entire read as database read TP_DEFIDX(li); TP_SWITCH(li,fSessionP->fTPInfo,TP_database); PDEBUGBLOCKFMTCOLL(("ReadSyncSet","Reading Sync Set from Database","datastore=%s",getName())); SYSYNC_TRY { // read sync set (maybe from derived non-odbc data source) // - in slow sync, we need all items (so allow ReadSyncSet to read them all here) // - if all items must be filtered, we also need all data // Note: ReadSyncSet will decide if it actually needs to load the syncset or not (depends on refresh, slowsync and needs of apiZapSyncSet()) sta = apiReadSyncSet( fSlowSync #ifdef OBJECT_FILTERING || fFilteringNeededForAll #endif ); // determine how GetItem will start fGetPhase = fSlowSync ? gph_added_changed : gph_deleted; // just report added (not-in-map, map is cleared already) for slowsync // phase not yet prepared fGetPhasePrepared = false; // end of DB read PDEBUGENDBLOCK("ReadSyncSet"); TP_START(fSessionP->fTPInfo,li); } SYSYNC_CATCH(exception &e) PDEBUGPRINTFX(DBG_ERROR,("StartDataRead exception: %s",e.what())); sta=510; // end of DB read PDEBUGENDBLOCK("ReadSyncSet"); TP_START(fSessionP->fTPInfo,li); SYSYNC_ENDCATCH #endif // BINFILE_ALWAYS_ACTIVE } return sta; } // TCustomImplDS::implStartDataRead // Queue the data needed for finalisation (usually - relational link updates) // as a item copy with only finalisation-required fields void TCustomImplDS::queueForFinalisation(TMultiFieldItem *aItemP) { sInt16 fid; // create a same-typed copy of the original item (initially empty) TMultiFieldItem *itemP = new TMultiFieldItem(aItemP->getItemType(),aItemP->getTargetItemType()); // copy localID and syncop itemP->setLocalID(aItemP->getLocalID()); itemP->setSyncOp(aItemP->getSyncOp()); // copy fields that are marked for finalisation TFieldMapList &fml = fConfigP->fFieldMappings.fFieldMapList; TFieldMapList::iterator pos; for (pos=fml.begin(); pos!=fml.end(); pos++) { TFieldMapItem *fmiP = *pos; #ifdef ARRAYDBTABLES_SUPPORT if (fmiP->isArray()) { TFieldMapList::iterator pos2; TFieldMapList &afml = static_cast(fmiP)->fArrayFieldMapList; for (pos2=afml.begin(); pos2!=afml.end(); pos2++) { TFieldMapItem *fmi2P = *pos2; fid = fmi2P->fid; if (fmi2P->needs_finalisation && fid>=0) { // this mapping indicates need for finalisation and references a fieldlist field, copy referenced field *(itemP->getField(fid))=*(aItemP->getField(fid)); } } } else #endif // ARRAYDBTABLES_SUPPORT { fid = fmiP->fid; if (fmiP->needs_finalisation && fid>=0) { // this mapping indicates need for finalisation and references a fieldlist field, copy referenced field *(itemP->getField(fid))=*(aItemP->getField(fid)); } } } // put the finalisation item into the queue fFinalisationQueue.push_back(itemP); } // TCustomImplDS::queueForFinalisation #ifndef BINFILE_ALWAYS_ACTIVE /// @brief called to have all non-yet-generated sync commands as "to-be-resumed" void TCustomImplDS::implMarkOnlyUngeneratedForResume(void) { #ifdef BASED_ON_BINFILE_CLIENT // let binfile handle it if it is active if (binfileDSActive()) { inherited::implMarkOnlyUngeneratedForResume(); return; } #endif // BASED_ON_BINFILE_CLIENT // Note: all "markforresume" flags (but NOT the actual mapflag_useforresume!) are cleared // after loading or saving admin, so we can start adding resume marks BEFORE // implMarkOnlyUngeneratedForResume is called (needed to re-add items that got // an unsuccessful status from remote that suggests re-trying in next resume, such as 514) // add all not-yet-got items TMapContainer::iterator pos; TGetPhases getPhase = fGetPhase; // start at current get phase bool getPrepared = fGetPhasePrepared; // now flag all deletes that need resuming if (getPhase==gph_deleted) { // now mark pending deletes; if we are still in "deleted" phase, add these first for (pos = !getPrepared ? fMapTable.begin() : fDeleteMapPos; pos!=fMapTable.end(); ++pos) { // check only undeleted map entries // Note: non-normal maps are always in deleted state in fMapTable, so these will be skipped as well if ((*pos).deleted) continue; // check if deleted if (findInSyncSet((*pos).localid.c_str())==fSyncSetList.end()) { // mark this as pending for resume (*pos).markforresume=true; } } getPhase=gph_added_changed; getPrepared=false; } // now flag all changes and adds that need resuming // if we are already gph_done, no items need to be flagged here if (getPhase==gph_added_changed) { // if we are in the add/change phase, add not-yet handled adds/changes TSyncSetList::iterator syncsetpos; if (!getPrepared) syncsetpos=fSyncSetList.begin(); else syncsetpos=fSyncSetPos; // now mark pending changes and adds while (syncsetpos!=fSyncSetList.end()) { // check if we need to mark it bool needMark=false; pos=findMapByLocalID((*syncsetpos)->localid.c_str(),mapentry_normal,true); // find deleted ones as well if (fSlowSync) { if (IS_CLIENT) { // for client, there are no reference-only: mark all leftovers in a slow sync needMark=true; } else { // for server, make sure not to mark reference-only. if (!isResuming() || pos==fMapTable.end()) { // if not resuming, or we have no map for this one at all - we'll need it again for resume needMark=true; } else { // for slowsync resume which have already a map: // - items that are not marked for resume, but already have a remoteID mapped // are reference-only and must NOT be marked if (((*pos).mapflags & mapflag_useforresume) || (*pos).remoteid.empty()) needMark=true; } } } else if (!isRefreshOnly() || (isRefreshOnly() && isCacheData())) { // not slow sync, and not refresh from remote only - mark those that are actually are involved if (pos!=fMapTable.end()) { // known item, needs a mark only if record is modified (and updates reported at all) needMark=((*syncsetpos)->isModified) && fReportUpdates; } else { // adds need marking, anyway needMark=true; } } // now apply mark if needed if (needMark) { if (pos==fMapTable.end()) { // no map entry for this item yet (this means that this is a new detected add // - add pendingAddConfirm item now, and mark it for resume TMapEntry entry; entry.entrytype=mapentry_normal; entry.localid=(*syncsetpos)->localid.c_str(); entry.remoteid.erase(); entry.mapflags=mapflag_pendingAddConfirm; entry.added=true; entry.changed=true; entry.deleted=false; entry.markforresume=true; entry.savedmark=false; fMapTable.push_back(entry); } else { // add flag to existing map item if ((*pos).deleted) { // undelete (re-use existing, but currently invalid entry) (*pos).remoteid.erase(); (*pos).changed=true; (*pos).deleted=false; (*pos).mapflags=0; } (*pos).markforresume=true; } } // next ++syncsetpos; } } } // TCustomImplDS::implMarkOnlyUngeneratedForResume // called to confirm a sync operation's completion (status from remote received) // @note aSyncOp passed not necessarily reflects what was sent to remote, but what actually happened void TCustomImplDS::dsConfirmItemOp(TSyncOperation aSyncOp, cAppCharP aLocalID, cAppCharP aRemoteID, bool aSuccess, localstatus aErrorStatus) { #ifdef BASED_ON_BINFILE_CLIENT // let binfile handle it if it is active if (binfileDSActive()) { inherited::dsConfirmItemOp(aSyncOp, aLocalID, aRemoteID, aSuccess, aErrorStatus); return; } #endif // BASED_ON_BINFILE_CLIENT if (aSyncOp==sop_delete || aSyncOp==sop_archive_delete) { // a confirmed delete causes the entire map entry to be removed (item no longer exists (or is visible) locally or remotely) if (aSuccess) { PDEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,("successful status for delete received -> delete map entry now")); modifyMap(mapentry_normal,aLocalID,aRemoteID,0,true); } } else { TMapContainer::iterator pos; if (IS_CLIENT) { // for client, always find by localid pos=findMapByLocalID(aLocalID,mapentry_normal); } else { // for server, only add can be found by localid if (aSyncOp==sop_add) pos=findMapByLocalID(aLocalID,mapentry_normal); else pos=findMapByRemoteID(aRemoteID); } if (pos!=fMapTable.end()) { // Anyway, clear the status pending flag // Note: we do not set the "changed" bit here because we don't really need to make this persistent between sessions (*pos).mapflags &= ~mapflag_pendingStatus; if (IS_CLIENT) { if (aSuccess) { // Note: we do not check for sop here - any successfully statused sop will clear the pending add status // (e.g. in slow sync, items reported as add to engine are actually sent as replaces, but still // seeing a ok status means that they are not any longer pending as adds) // Note: the same functionality formerly was in TStdLogicDS::startDataWrite() - making sure that a // add sent to the server is not repeated. As every item reported by implGetItem now already // has a map entry (adds get one with mapflag_pendingAddConfirm set), we just need to clear // the flag here now that we know the add has reached the server. // Note: For the server, we can clear the mapflag_pendingAddConfirm not before we have received a item for it! PDEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,("successful status for non-delete received -> clear mapflag_pendingAddConfirm")); (*pos).mapflags &= ~mapflag_pendingAddConfirm; (*pos).changed = true; // this MUST be made persistent! } } // if client } else { PDEBUGPRINTFX(DBG_ERROR+DBG_EXOTIC,("dsConfirmItemOp - INTERNAL ERROR: no map entry exists for item")); } } // let inherited know as well inherited::dsConfirmItemOp(aSyncOp, aLocalID, aRemoteID, aSuccess, aErrorStatus); } // TCustomImplDS::confirmItemOp // called to mark an already sent item as "to-be-resent", e.g. due to temporary // error status conditions, by localID or remoteID (latter only in server case). void TCustomImplDS::implMarkItemForResend(cAppCharP aLocalID, cAppCharP aRemoteID) { #ifdef BASED_ON_BINFILE_CLIENT // let binfile handle it if it is active if (binfileDSActive()) { inherited::implMarkItemForResend(aLocalID, aRemoteID); return; } #endif // BASED_ON_BINFILE_CLIENT // Note: this is only relevant for replaces and some adds: // - some adds will not have a map entry yet // - deletes will not have their map entry deleted until they are confirmed // But replaces would not get re-sent as they would not get detected // modified any more once a session has completed. TMapContainer::iterator pos; if (aLocalID && *aLocalID) pos=findMapByLocalID(aLocalID,mapentry_normal,false); // only undeleted ones else if (aRemoteID && *aRemoteID) pos=findMapByRemoteID(aRemoteID); else return; // neither local nor remote ID specified -> nop if (pos==fMapTable.end()) { PDEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,("implMarkItemForResend: no map entry found -> item does not exist or is an add which will be sent anyway")); return; // no item can be searched or created } // set resend flag now (if not already set) if (!((*pos).mapflags & mapflag_resend)) { (*pos).mapflags |= mapflag_resend; (*pos).changed=true; } // and make sure it gets resent in case of a suspend as well (mark for resume) // This is needed for suspends where unprocessed items gets statused with 514 BEFORE // the server knows that this is going to be a suspend. (*pos).markforresume=true; PDEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC+DBG_HOT,( "localID='%s' marked for resending by setting mapflag_resend (AND mark for eventual resume!), flags now=0x%lX", (*pos).localid.c_str(), (long)(*pos).mapflags )); } // TCustomImplDS::implMarkItemForResend // called to mark an already generated (but unsent or sent but not yet statused) item // as "to-be-resumed", by localID or remoteID (latter only in server case). void TCustomImplDS::implMarkItemForResume(cAppCharP aLocalID, cAppCharP aRemoteID, bool aUnSent) { #ifdef BASED_ON_BINFILE_CLIENT // let binfile handle it if it is active if (binfileDSActive()) { inherited::implMarkItemForResume(aLocalID, aRemoteID, aUnSent); return; } #endif // BASED_ON_BINFILE_CLIENT TMapContainer::iterator pos; if (aLocalID && *aLocalID) pos=findMapByLocalID(aLocalID,mapentry_normal,true); // also find deleted ones else if (aRemoteID && *aRemoteID) pos=findMapByRemoteID(aRemoteID); else return; // no item can be searched or created if (pos!=fMapTable.end()) { // we have an entry for this item, mark it for resume if ((*pos).deleted) { // undelete (re-use existing, but currently invalid entry) (*pos).remoteid.erase(); (*pos).changed=true; (*pos).deleted=false; (*pos).mapflags=0; } // for unsent ones, the status is not pending any more else if (aUnSent && ((*pos).mapflags & (mapflag_pendingStatus+mapflag_pendingDeleteStatus))) { // reset the status pending flags (*pos).changed=true; (*pos).mapflags &= ~(mapflag_pendingStatus+mapflag_pendingDeleteStatus); } // For Server: those that have mapflag_pendingAddConfirm (adds) may be marked for // resume ONLY if we can rely on early maps or if they are completely unsent. // Sent adds will just keep their mapflag_pendingAddConfirm until they receive their map // For Client: all items will be marked for resume if ( IS_SERVER && ((*pos).mapflags & mapflag_pendingAddConfirm) && // is an add... !aUnSent && // ...and already sent out !fSessionP->getSessionConfig()->fRelyOnEarlyMaps // and we can't rely on the client sending the maps before ) { // for server: already sent adds may not be repeated unless we can rely on early maps PDEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,( "implMarkItemForResume: localID='%s', has mapFlags=0x%lX and was probably executed at remote -> NOT marked for resume", (*pos).localid.c_str(), (long)(*pos).mapflags )); (*pos).markforresume=false; } else { // for client: everything may be repeated and therefore marked for resume // for server: unsent adds will also be marked, or all if we can rely on early maps (which is the default) PDEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,( "implMarkItemForResume: localID='%s', has mapFlags=0x%lX and was %s executed at remote%s -> mark for resume", (*pos).localid.c_str(), (long)(*pos).mapflags, aUnSent ? "NOT" : "probably", fSessionP->getSessionConfig()->fRelyOnEarlyMaps ? " (relying on early maps)" : "" )); (*pos).markforresume=true; } } else if (aLocalID && *aLocalID) { PDEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,( "implMarkItemForResume: localID='%s', was not yet in map and was %sexecuted at remote -> created map and marked for resume", aLocalID, aUnSent ? "NOT " : "probably" )); // we have no entry for this item, make one (only if this is not a remoteID-only item, // but this should not occur here anyway - items without localID can only be replaces // from server to client, in which case we have a map entry anyway) TMapEntry entry; entry.entrytype=mapentry_normal; entry.localid=aLocalID; entry.remoteid.erase(); entry.mapflags=0; entry.added=true; entry.changed=true; entry.deleted=false; entry.markforresume=true; entry.savedmark=false; fMapTable.push_back(entry); } } // TCustomImplDS::implMarkItemForResume // Get next item from database localstatus TCustomImplDS::implGetItem( bool &aEof, bool &aChanged, // if set on entry, only changed ones will be reported, otherwise all will be returned and aChanged contains flag if entry has changed or not TSyncItem* &aSyncItemP ) { #ifdef BASED_ON_BINFILE_CLIENT // let binfile handle it if it is active if (binfileDSActive()) { return inherited::implGetItem(aEof, aChanged, aSyncItemP); } #endif // BASED_ON_BINFILE_CLIENT localstatus sta = LOCERR_OK; bool reportChangedOnly = aChanged; // save initial state, as we might repeat... bool rep=true; // to start-up lower part TSyncOperation sop=sop_none; aEof=true; // assume we have nothing to report string remid; TMultiFieldItem *myitemP=NULL; // short-cut if refreshing only and not slowsync resuming (then we need the items for comparison) if (isRefreshOnly() && !isCacheData() && !(isResuming() && isSlowSync())) return sta; // aEof is set, return nothing TP_DEFIDX(li); TP_SWITCH(li,fSessionP->fTPInfo,TP_database); SYSYNC_TRY { // check mode if (fGetPhase==gph_deleted) { // report deleted items, that is those in the map that are not // any more in the sync set of local IDs // Note: we need no extra database access any more for this if (!fGetPhasePrepared) { // start at beginning of map table fDeleteMapPos=fMapTable.begin(); fGetPhasePrepared=true; } do { rep=false; // report all those map entries that have no data entry (any more) // as deleted records // - check if there is more data in map table to process if (fDeleteMapPos==fMapTable.end()) { fGetPhase=gph_added_changed; // end of this phase, now report additions and modifications rep=true; // continue in second part (get updated records) fGetPhasePrepared=false; // next phase must be prepared break; } else { // search if there is a local ID still existing for that ID TMapEntry entry = (*fDeleteMapPos); // check only undeleted map entries if (entry.deleted || entry.entrytype!=mapentry_normal) { // deleted or non-normal map entry - simply skip rep=true; } else if (isResuming() && !(entry.mapflags & mapflag_useforresume)) { // this delete has already been reported deleted in previous suspended session // (or it was deleted from the datastore WHILE or after start of a suspended session, // in this case the item will be reported deleted in the NEXT complete sync session) PDEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,("Resuming and found item not marked for resume -> ignore for delete checking")); rep=true; } else if (findInSyncSet(entry.localid.c_str())==fSyncSetList.end()) { // this item has been deleted (and not yet been reported if this is a resume) -> report it PDEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,("Normal sync and found item in map which is not in syncset -> delete and mark with mapflag_pendingDeleteStatus")); // - create new empty TMultiFieldItem myitemP = (TMultiFieldItem *) newItemForRemote(ity_multifield); // - add IDs myitemP->setRemoteID(entry.remoteid.c_str()); myitemP->setLocalID(entry.localid.c_str()); // - set operation myitemP->setSyncOp(sop_delete); // - set item aSyncItemP = myitemP; aEof=false; // report something // mark entry as waiting for delete status // NOTES: - we cannot delete the map entry until we get a confirmItemOp() for it // - the pendingStatus flag does not need to be persistent between sessions, so we don't set the changed flag here! // - the flag is important in case a server-delete vs client-replace conflict occurs which the client wins. In that // case implProcessItem needs to be able to tell that still having a map entry does NOT mean we do have // the record still in the DB. entry.mapflags |= mapflag_pendingDeleteStatus; (*fDeleteMapPos)=entry; // save updated entry in list // found one to report } else { rep=true; // must repeat again } } // go to next fDeleteMapPos++; } while(rep); } // report deleted phase if (rep && fGetPhase==gph_added_changed) { // report changed and added items. Those that are in the sync set but // not yet in the map are added items, those that are already in the // map are changed items if the mod date is newer than last sync // and deleted if they don't pass extra filters if (!fGetPhasePrepared) { // start at beginning of map table fSyncSetPos=fSyncSetList.begin(); fGetPhasePrepared=true; } do { rep=false; remid.erase(); // - check if there is more data in the syncset to process if (fSyncSetPos==fSyncSetList.end()) { fGetPhase=gph_done; // end of this phase, now report additions and modifications rep=true; // continue in next phase (if any) fGetPhasePrepared=false; // next phase must be prepared break; } else { // get syncset entry TSyncSetItem *syncsetitemP = (*fSyncSetPos); sop=sop_none; TMapContainer::iterator pos; // search if there is a map entry for this item already pos=findMapByLocalID(syncsetitemP->localid.c_str(),mapentry_normal); // do not find deleted ones, only valid entries! #ifdef SYDEBUG if (pos!=fMapTable.end()) { // Debug PDEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,( "Item localID='%s' already has map entry: remoteid='%s', mapflags=0x%lX, changed=%d, deleted=%d, added=%d, markforresume=%d, savedmark=%d", syncsetitemP->localid.c_str(), (*pos).remoteid.c_str(), (long)(*pos).mapflags, (int)(*pos).changed, (int)(*pos).deleted, (int)(*pos).added, (int)(*pos).markforresume, (int)(*pos).savedmark )); } #endif // now find what syncop results if (fSlowSync && !isResuming()) { // all items in local sync set are to be reported PDEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,("Slow sync and not resuming -> all items are first reported sop_wants_replace (will become add later)")); sop=sop_wants_replace; aChanged=true; // clear the resend flags if any if (pos!=fMapTable.end()) { if ((*pos).mapflags & mapflag_resend) { (*pos).mapflags &= ~mapflag_resend; (*pos).changed = true; } } } else { if (pos!=fMapTable.end()) { // for slowsync resume - items that are not marked for resume, but already have a remoteID mapped // must be presented for re-match with sop_reference_only if (IS_SERVER && fSlowSync && isResuming() && !((*pos).mapflags & mapflag_useforresume) && !(*pos).remoteid.empty()) { // this item apparently was already slow-sync-matched before the suspend - still show it for reference to avoid re-adding it sop=sop_reference_only; } else if (!isRefreshOnly() || (isRefreshOnly() && isCacheData())) { // item is already in map: check if this is an already detected, but unfinished add if (!((*pos).mapflags & mapflag_pendingAddConfirm)) { // is a replace (not an add): changed if mod date newer or resend flagged (AND updates enabled) // Note: For reporting modifications, the date of last sending-data-to-remote date is relevant bool hasChanged= (((*fSyncSetPos)->isModified) || ((*pos).mapflags & mapflag_resend)) && fReportUpdates; // reset resend flag here if it acutually causes a resend here (otherwise, keep it for later) if (hasChanged && (*pos).mapflags & mapflag_resend) { PDEBUGPRINTFX(DBG_ADMIN+DBG_HOT,("Item '%s' treated as changed because resend-flag was set",syncsetitemP->localid.c_str())); (*pos).mapflags &= ~mapflag_resend; (*pos).changed = true; } if (isResuming()) { // Basically, on resume just report those that have the mapflag_useforresume flag set. // However, there is one difficult problem here: // - Those that were successfully modified in the suspended part of a session, but get modified // AGAIN between suspend and this resume will NOT be detected as changes any more. Therefore, for // items we see here that don't have the mapflag_useforresume, we need to check additionally if // they possibly have changed AFTER THE LAST SUSPEND SAVE if ((*pos).mapflags & mapflag_useforresume) { PDEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,("Resuming and found marked-for-resume -> send replace")); sop=sop_wants_replace; hasChanged=true; // mark this as change (again, because marked for resume) } else if (!reportChangedOnly || hasChanged) { // this one does not have the flag set, but it would be reported as a change if this was not a resume // so this could be a change happened between suspend and resume if (syncsetitemP->isModifiedAfterSuspend) { // yes, this one was modified AFTER the suspended session, so we'll send it, too PDEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,("Resuming and found NOT marked-for-resume, but changed after last suspend -> send replace again")); sop=sop_wants_replace; hasChanged=true; // mark this as change (since last suspend, that is) } } } else if (!reportChangedOnly || hasChanged) { // report only if aChanged was false on entry (=reportChangedOnly is false) or if modified anyway PDEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,("Normal sync, item changed -> send replace")); sop=sop_wants_replace; } remid=(*pos).remoteid; aChanged=hasChanged; // return changed status anyway } // if not add else { // already detected, but unfinished add // For server: Might be resent ONLY if resuming and marked for resume (otherwise, we MUST wait for map or we'll get duplicates) // For client: resend always except if resuming and not marked for it if (isResuming()) { if ((*pos).mapflags & mapflag_useforresume) { PDEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,("Resuming and found marked-for-resume with mapflag_pendingAddConfirm -> unsent add, send it again")); sop=sop_wants_add; } else { PDEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,("Resuming and NOT marked-for-resume with mapflag_pendingAddConfirm -> ignore")); } } else { if (IS_CLIENT) { // for client - repeating an add does not harm (but helps if it did not reach the server in the previous attempt PDEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,("Non-resume sync found item with mapflag_pendingAddConfirm -> send it again")); sop=sop_wants_add; } // client else { // for server - repeating an add potentially DOES harm (duplicate if client already got the add, but didn't send a map yet) // but it's ok if it's flagged as an explicit resend (this happens only if we have got error status from remote) if ((*pos).mapflags & mapflag_resend) { PDEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,("Item with mapflag_pendingAddConfirm (add) also has mapflag_resend -> we can safely resend")); sop=sop_wants_add; // - reset resend flag here (*pos).mapflags &= ~mapflag_resend; (*pos).changed = true; } else { PDEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,("Non-resume sync found item with mapflag_pendingAddConfirm (add) -> ignore until map is found")); } } // server } } } // if not refreshonly } // a map entry already exists else { // item is not yet in map: this is a new one. Report it if we are not resuming a previous session // (in this case, items added after start of the original session will be detected at NEXT full // session, so just leave it out for now) // Note: this is first-time add detection. If we get this reported as sop_wants_add below, a map with // mapflag_pendingAddConfirm will be created for it. if (isRefreshOnly() && isCacheData()) { PDEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,("New item (no map yet) detected during Refresh only -> ignore for now, will be deleted later unless matched against peer item")); sop=sop_none; } else if (isRefreshOnly()) { PDEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,("New item (no map yet) detected during Refresh only -> ignore for now, will be added in next two-way sync")); sop=sop_none; } else if (isResuming()) { PDEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,("Resuming and found new item which was not present in original session -> ignore for now, will be added in next regular sync")); sop=sop_none; } else { PDEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,("Normal sync, item not yet in map -> add to remote")); sop=sop_wants_add; } } } if (sop!=sop_none) { // we need the item from the database SYSYNC_TRY { bool fetched=false; // - check if we've already read it (at apiReadSyncSet()) if (syncsetitemP->itemP) { // yes, take it out of the syncset if (fNoSingleItemRead) { // we may need it later, so we can only pass a copy to caller myitemP = (TMultiFieldItem *) newItemForRemote(ity_multifield); if (!myitemP) SYSYNC_THROW(TSyncException("newItemForRemote could not create new Item")); // copy item (id, op, contents) (*myitemP) = (*(syncsetitemP->itemP)); } else { // we don't need it later, pass original to caller and remove link in syncsetitem myitemP = syncsetitemP->itemP; syncsetitemP->itemP = NULL; // syncsetitem does not own it any longer } fetched=true; // we have the item // Make sure item is fully equipped // - assign local id, as it is required by DoDataSubstitutions myitemP->setLocalID(syncsetitemP->localid.c_str()); // - assign remote id if we know one myitemP->setRemoteID(remid.c_str()); // - set operation myitemP->setSyncOp(sop); } else { // We need to read the item here // - create new empty TMultiFieldItem myitemP = (TMultiFieldItem *) newItemForRemote(ity_multifield); if (!myitemP) SYSYNC_THROW(TSyncException("newItemForRemote could not create new Item")); // - assign local id, as it is required by DoDataSubstitutions myitemP->setLocalID(syncsetitemP->localid.c_str()); // - assign remote id if we know one myitemP->setRemoteID(remid.c_str()); // - set operation myitemP->setSyncOp(sop); // Now fetch item (read phase) sta=apiFetchItem(*myitemP,true,syncsetitemP); if (sta==LOCERR_OK) { // successfully fetched fetched=true; } else if (sta==404) { // this record has been deleted since we have read the // localid list. If this is was an add, we can simply // ignore it // - decide what this means now if (sop==sop_reference_only || sop==sop_wants_add) { // was deleted before we could fetch it for adding (or reference), just ignore PDEBUGPRINTFX(DBG_DATA+DBG_DETAILS,("to-be-added record localID=%s was deleted during this sync session -> ignore",myitemP->getLocalID())); rep=true; delete myitemP; // could still be that we have a mapflag_useforresume map entry, make sure we get rid of it if (pos!=fMapTable.end()) { // mark deleted (*pos).deleted=true; } goto nextchanged; } else { // was changed, but now doesn't exist any more -> treat as delete // - adjust operation PDEBUGPRINTFX(DBG_DATA+DBG_DETAILS,("to-be-changed record localID=%s was deleted during this sync session -> delete",myitemP->getLocalID())); myitemP->setSyncOp(sop_delete); myitemP->cleardata(); // make sure it is empty // - set item to return to caller aSyncItemP = myitemP; aEof=false; // report something if (!fSlowSync) { // Note: we can safely assume that the map entry exists - otherwise sop would be sop_wants_add // map entry must be marked to show that this now is a pending delete (*pos).changed=true; (*pos).mapflags &= ~(mapflag_pendingStatus); (*pos).mapflags |= mapflag_pendingDeleteStatus; } fetched=false; // prevent map manipulations below } } else { // other error SYSYNC_THROW(TSyncException("Error fetching data from DB",sta)); } } // else: fetch from DB needed if (fetched) { // set item to return to caller aSyncItemP = myitemP; aEof=false; // report something // info PDEBUGPRINTFX(DBG_DATA+DBG_DETAILS,("Fetched record data from DB with localID=%s",myitemP->getLocalID())); } } SYSYNC_CATCH(...) if (myitemP) delete myitemP; SYSYNC_RETHROW; SYSYNC_ENDCATCH } // item to report else { // item read must not be reported, try to get next rep=true; } } // not end of syncset nextchanged: // go to next fSyncSetPos++; } while(rep); } // report added and changed phase if (rep) { // end of items aEof=true; // syncset can be deleted only if we can retrieve individual items later from DB // if not, we must keep the syncset in memory if (!fNoSingleItemRead) { // we don't need the SyncSet list any more // (and especially the items that did NOT get reported to the caller of GetItem // can be deleted now to free memory. Reported items are now owned by the caller) DeleteSyncSet(fMultiFolderDB); } } // done TP_START(fSessionP->fTPInfo,li); // show item fetched #ifdef SYDEBUG if (PDEBUGTEST(DBG_DATA+DBG_SCRIPTS) && aSyncItemP) aSyncItemP->debugShowItem(DBG_DATA); // show item fetched #endif } SYSYNC_CATCH(exception &e) PDEBUGPRINTFX(DBG_ERROR,("GetItem exception: %s",e.what())); TP_START(fSessionP->fTPInfo,li); sta=510; SYSYNC_ENDCATCH // done return sta; } // TCustomImplDS::implGetItem #endif // not BINFILE_ALWAYS_ACTIVE // end of read localstatus TCustomImplDS::implEndDataRead(void) { #ifdef BASED_ON_BINFILE_CLIENT // let binfile handle it if it is active if (binfileDSActive()) { return inherited::implEndDataRead(); } #endif // BASED_ON_BINFILE_CLIENT // let API handle it directly return apiEndDataRead(); } // TCustomImplDS::implEndDataRead // start of write localstatus TCustomImplDS::implStartDataWrite() { localstatus sta = LOCERR_OK; #ifdef BASED_ON_BINFILE_CLIENT // let binfile handle it if it is active if (binfileDSActive()) { sta = inherited::implStartDataWrite(); } else #endif // BASED_ON_BINFILE_CLIENT { #ifndef BINFILE_ALWAYS_ACTIVE SYSYNC_TRY { // let actual data implementation prepare sta = apiStartDataWrite(); if (sta==LOCERR_OK) { // Notes: // - transaction starts implicitly when first INSERT / UPDATE / DELETE occurs // - resumed slow refreshes must NOT zap the sync set again! // - prevent zapping when datastore is in readonly mode! if (fRefreshOnly && !fCacheData && fSlowSync && !isResuming() && !fReadOnly) { // - make sure we have at least one pev_deleting event, in case app tracks it to see if session caused changes to DB DB_PROGRESS_EVENT(this,pev_deleting,0,0,0); // now, we need to zap the DB first PDEBUGBLOCKFMTCOLL(("ZapSyncSet","Zapping sync set in database","datastore=%s",getName())); SYSYNC_TRY { sta=apiZapSyncSet(); PDEBUGENDBLOCK("ZapSyncSet"); } SYSYNC_CATCH(exception &e) PDEBUGPRINTFX(DBG_ERROR,("ZapSyncSet exception: %s",e.what())); sta=510; // end of DB read PDEBUGENDBLOCK("ZapSyncSet"); SYSYNC_ENDCATCH if (sta!=LOCERR_OK) { PDEBUGPRINTFX(DBG_ERROR,("implStartDataWrite: cannot zap data for refresh, status=%hd",sta)); } // ok, now that the old data is zapped, we MUST forget the former sync set, it is now for sure invalid DeleteSyncSet(false); } } } SYSYNC_CATCH(exception &e) PDEBUGPRINTFX(DBG_ERROR,("implStartDataWrite exception: %s",e.what())); sta=510; SYSYNC_ENDCATCH #endif } // done return sta; } // TCustomImplDS::implStartDataWrite #ifndef BINFILE_ALWAYS_ACTIVE // review reported entry (allows post-processing such as map deleting) // MUST be called after StartDataWrite, before any actual writing, // for each item obtained in GetItem localstatus TCustomImplDS::implReviewReadItem( TSyncItem &aItem // the item ) { #ifdef BASED_ON_BINFILE_CLIENT // let binfile handle it if it is active if (binfileDSActive()) { return inherited::implReviewReadItem(aItem); } #endif // BASED_ON_BINFILE_CLIENT // get the operation TSyncOperation sop = aItem.getSyncOp(); // NOTE: Don't touch map if this is a for-reference-only (meaning that the map is // already ok, and it is included here ONLY to find possible slowsync matches)! if (sop!=sop_reference_only) { // Adjust map flags or create map if needed if (fSlowSync || sop==sop_add || sop==sop_wants_add) { // for slowsync, all items are kind of "adds", that is, not yet mapped (server case) // or not yet statused (client case) // for normal sync, make sure adds get mapflag_pendingAddConfirm set and remoteID gets cleared (is not valid in any case) modifyMap(mapentry_normal,aItem.getLocalID(),"",mapflag_pendingAddConfirm+mapflag_pendingStatus,false,mapflag_pendingDeleteStatus); } else if (sop==sop_delete) { // In case when postFetch filtering changed an item from replace to delete, // we must make sure that the map entry gets the deleted status set // - simply make sure deleted item's map entry will get deleted once the delete is confirmed modifyMap(mapentry_normal,aItem.getLocalID(),NULL,mapflag_pendingDeleteStatus,false,0); } else { // not add (and never a delete here) -> is replace. Set status pending flag (which doesn't need to be saved to DB) modifyMap(mapentry_normal,aItem.getLocalID(),NULL,mapflag_pendingStatus,false,mapflag_pendingAddConfirm+mapflag_pendingDeleteStatus); } } return LOCERR_OK; } // TCustomImplDS::implReviewReadItem // - retrieve specified item from database bool TCustomImplDS::implRetrieveItemByID( TSyncItem &aItem, // the item TStatusCommand &aStatusCommand ) { #ifdef BASED_ON_BINFILE_CLIENT // let binfile handle it if it is active if (binfileDSActive()) { return inherited::implRetrieveItemByID(aItem, aStatusCommand); } #endif // BASED_ON_BINFILE_CLIENT bool ok=true; // determine item's local ID if (!aItem.hasLocalID()) { if (IS_CLIENT) { // client case: MUST have local ID aStatusCommand.setStatusCode(400); // bad request (no address) return false; } else { // no local ID specified directly, address by remote ID if (!aItem.hasRemoteID()) { aStatusCommand.setStatusCode(400); // bad request (no address) return false; } // lookup remote ID in map TMapContainer::iterator mappos = findMapByRemoteID(aItem.getRemoteID()); if (mappos==fMapTable.end()) { aStatusCommand.setStatusCode(404); // not found return false; } // set local ID aItem.setLocalID(mappos->localid.c_str()); // check if we have a local ID now if (!aItem.hasLocalID()) { aStatusCommand.setStatusCode(400); // bad request (no address) return false; } } } TP_DEFIDX(li); TP_SWITCH(li,fSessionP->fTPInfo,TP_database); // if we can't fetch single items from DB, we should have all // in the syncset and can get them from there if (fNoSingleItemRead) { // search sync set by localID TSyncSetList::iterator pos=findInSyncSet(aItem.getLocalID()); if (pos!=fSyncSetList.end() && (*pos)->itemP) { // found, copy data to item passed aItem.replaceDataFrom(*((*pos)->itemP)); } else { // not found aStatusCommand.setStatusCode(404); // not found ok=false; } } else { // fetch from DB SYSYNC_TRY { // fetch data from DB localstatus sta=apiFetchItem(*((TMultiFieldItem *)&aItem),false,NULL); // no syncsetitem known if (sta!=LOCERR_OK) { aStatusCommand.setStatusCode(sta); ok=false; } } SYSYNC_CATCH(exception &e) PDEBUGPRINTFX(DBG_ERROR,("implRetrieveItemByID exception: %s",e.what())); aStatusCommand.setStatusCode(510); ok=false; SYSYNC_ENDCATCH } // return status TP_START(fSessionP->fTPInfo,li); return ok; } // TCustomImplDS::implRetrieveItemByID /// called to set maps. /// @note aRemoteID or aLocalID can be NULL - which signifies deletion of a map entry /// @note that this might be needed for clients accessing a server-style database as well localstatus TCustomImplDS::implProcessMap(cAppCharP aRemoteID, cAppCharP aLocalID) { localstatus sta = 510; // error // Note: Map must be ready to have either empty local or remote ID to delete an entry if (!aLocalID) { // delete by remote ID modifyMap(mapentry_normal,NULL,aRemoteID,0,true); PDEBUGPRINTFX(DBG_ADMIN,("Map entry (or entries) for RemoteID='%s' removed",aRemoteID)); sta=LOCERR_OK; } else { // - if RemoteID is empty, this means that Map should be deleted if (!aRemoteID) { // Map delete request modifyMap(mapentry_normal,aLocalID,NULL,0,true); PDEBUGPRINTFX(DBG_ADMIN,("Map entry (or entries) for LocalID='%s' removed",aLocalID)); sta=LOCERR_OK; } else { // Map modify or add request, automatically clears mapflag_pendingAddConfirm (and all other) // flag(s), INLCUDING resume mark. So even if all sent adds (and not only the unsent ones) // get marked for resume in a suspend (fRelyOnEarlyMaps set), those that actually got added // in the previous session will not be re-sent for sure. modifyMap(mapentry_normal,aLocalID,aRemoteID,0,false); PDEBUGPRINTFX(DBG_ADMIN,("Map entry updated: LocalID='%s', RemoteID='%s'",aLocalID,aRemoteID)); sta=LOCERR_OK; } // if not map delete } // return status return sta; } // TCustomImplDS::implProcessMap enum CustomItemOp { CUSTOM_ITEM_ADD, CUSTOM_ITEM_ADD_AUGMENTED, CUSTOM_ITEM_UPDATE, CUSTOM_ITEM_UPDATE_AUGMENTED, CUSTOM_ITEM_DELETE }; struct TCustomItemAux : public TSyncItemAux { string fLocalID; string fRemoteID; // A copy of the original C string, to be on the safe side. bool fRemoteIDSet; TSyncOperation fSop; bool fRemoteHasLatestData; CustomItemOp fOp; }; /// process item (according to operation: add/delete/replace - and for future: copy/move) /// @note data items will be sent only after StartWrite() bool TCustomImplDS::implProcessItem( TSyncItem *aItemP, // the item TStatusCommand &aStatusCommand ) { #ifdef BASED_ON_BINFILE_CLIENT // let binfile handle it if it is active if (binfileDSActive()) { return inherited::implProcessItem(aItemP, aStatusCommand); } #endif // BASED_ON_BINFILE_CLIENT // Same approach as in TLocalEngineDS::engProcessRemoteItem: // backup local state and restore when called again. bool ok=true; localstatus sta=LOCERR_OK; string localID; const char *remoteID; // %%% bool RemoteIDKnown=false; TMapContainer::iterator mappos; TSyncOperation sop=sop_none; TMultiFieldItem *augmentedItemP = NULL; bool remoteHasLatestData; CustomItemOp op; TP_DEFIDX(li); TP_SWITCH(li,fSessionP->fTPInfo,TP_database); SYSYNC_TRY { // get casted item pointer TMultiFieldItem *myitemP = (TMultiFieldItem *)aItemP; TCustomItemAux *aux = static_cast(myitemP->getAux(TSyncItem::CUSTOM_DS)); DEBUGPRINTFX(DBG_DATA,( "TCustomImplDS::implProcessItem %p %s, SyncOp=%s, RemoteID='%s', LocalID='%s'", myitemP, aux ? "resuming" : "starting", SyncOpNames[myitemP->getSyncOp()], myitemP->getRemoteID(), myitemP->getLocalID() )); if (aux) { // Resuming the function call: restore variables, jump to store // method call. localID = aux->fLocalID; remoteID = aux->fRemoteIDSet ? aux->fRemoteID.c_str() : NULL; sop = aux->fSop; remoteHasLatestData = aux->fRemoteHasLatestData; op = aux->fOp; // Stripped down logic from normal code path below. // We can't save/restore mapppos because it points into // a data structure which may change between calls, thus // invalidating the old iterator. if (IS_CLIENT) { if (!localID.empty() && sop!=sop_add && sop!=sop_wants_add) mappos=findMapByLocalID(localID.c_str(),mapentry_normal); else mappos=fMapTable.end(); } else { mappos=findMapByRemoteID(remoteID); if (mappos!=fMapTable.end()) { localID = (*mappos).localid; } } aStatusCommand.setStatusCode(510); switch (op) { case CUSTOM_ITEM_ADD: goto do_add; case CUSTOM_ITEM_ADD_AUGMENTED: goto do_add_augmented; case CUSTOM_ITEM_UPDATE: goto do_update; case CUSTOM_ITEM_UPDATE_AUGMENTED: goto do_update_augmented; case CUSTOM_ITEM_DELETE: goto do_delete; }; } if (false) { // Prepare for resuming the function call. Will only be reached // via goto with "op" set to something identifying the source of // the jump. again: #define CHECK_FOR_AGAIN(_status, _op) \ if (_status == LOCERR_AGAIN) { \ op = _op; \ goto again; \ } if (!aux) { aux = new TCustomItemAux; myitemP->setAux(TSyncItem::CUSTOM_DS, aux); } aux->fLocalID = localID; aux->fRemoteID = remoteID ? remoteID : ""; aux->fRemoteIDSet = remoteID != NULL; aux->fSop = sop; aux->fRemoteHasLatestData = remoteHasLatestData; aux->fOp = op; aStatusCommand.setStatusCode(LOCERR_AGAIN); goto error; } // - get op sop = myitemP->getSyncOp(); // - check IDs if (IS_CLIENT) { // Client case: we always get the local ID, except for add localID=myitemP->getLocalID(); remoteID=myitemP->getRemoteID(); if (!localID.empty() && sop!=sop_add && sop!=sop_wants_add) mappos=findMapByLocalID(localID.c_str(),mapentry_normal); // for all but sop == sop_add else mappos=fMapTable.end(); // if there is no localid or it is an add, we have no map entry yet } else { // Server case: we only know the remote ID // - get remoteID remoteID=myitemP->getRemoteID(); // first see if we have a map entry for this remote ID localID.erase(); // none yet // Note: // - even items detected for deletion still have a map item until deletion is confirmed by the remote party, // so we'll be able to update already "deleted" items (in case they are not really gone, but only invisible in the sync set) // - we can use mapflag_pendingDeleteStatus (which does not need persistence in the DB, so works even for not resume-enabled backends) // to keep still existing and deleted items apart. mappos=findMapByRemoteID(remoteID); // search for it if (mappos!=fMapTable.end()) { localID = (*mappos).localid; // assign it if we have it } } // - now perform op aStatusCommand.setStatusCode(510); // default DB error remoteHasLatestData = false; switch (sop) { /// @todo sop_copy is now implemented by read/add sequence /// in localEngineDS, but will be moved here later possibly case sop_add : // check for duplicated add // Notes: // - server must check it here, because map lookup is needed. Contrarily, client // can check it on localengineds level against the pending maps list with isAddFromLastSession(). // - if mapflag_pendingDeleteStatus is set, the item still has a map entry, but does not exist in the DB any more // so do not report 418 here! if (IS_SERVER && mappos!=fMapTable.end() && ((*mappos).mapflags & mapflag_pendingDeleteStatus)==0) { // we already know this item (and it was not already detected as deleted from the DB, so should exist there) // - status "already exists" aStatusCommand.setStatusCode(418); ok = false; break; } // add item and retrieve new localID for it do_add: sta = apiAddItem(*myitemP,localID); CHECK_FOR_AGAIN(sta, CUSTOM_ITEM_ADD); myitemP->setLocalID(localID.c_str()); // possibly following operations need to be based on new localID returned by add // check for backend asking engine to do a merge if (sta==DB_Conflict) { // DB has detected item conflicts with data already stored in the database and // request merging current data from the backend with new data before storing. bool changedDBVersion, changedNewVersion; augmentedItemP = mergeWithDatabaseVersion(myitemP, changedDBVersion, changedNewVersion); if (augmentedItemP==NULL) sta = DB_Error; // no item found, DB error else { // store augmented version back to DB only if modified do_add_augmented: if (changedDBVersion) sta = apiUpdateItem(*augmentedItemP); else sta = LOCERR_OK; CHECK_FOR_AGAIN(sta, CUSTOM_ITEM_ADD_AUGMENTED); // in server case, further process like backend merge (but no need to fetch again, we just keep augmentedItemP) if (IS_SERVER && sta==LOCERR_OK) { // TLocalEngineDS::engProcessRemoteItemAsServer() in // localengineds.cpp already counted the item as added // because it didn't know that special handling would be // needed. Instead of a complicated mechanism to report // back the actual outcome, let's fix the statistics // here. fLocalItemsAdded--; if (changedDBVersion) fLocalItemsUpdated++; sta = DB_DataMerged; } // in the processing below avoid sending an unnecessare Replace // if the data sent by the peer already was up-to-date if (!changedNewVersion) remoteHasLatestData = true; } } if (IS_SERVER) { #ifdef SYSYNC_SERVER if (sta==DB_DataMerged || sta==DB_DataReplaced) { // while adding, data was merged with pre-existing data from... // ..either data external from the sync set, such as augmenting a contact with info from a third-party lookup // ..or another item pre-existing in the sync set. PDEBUGPRINTFX(DBG_DATA,("Database adapter indicates that added item was merged with pre-existing data (status 207/209/409)")); // check if the item resulting from merge is known by the client already (in it's pre-merge form, that is) TMapContainer::iterator conflictingMapPos = findMapByLocalID(localID.c_str(), mapentry_normal); bool remoteAlreadyKnowsItem = conflictingMapPos!=fMapTable.end(); // also check if we have a (pre-merge) operation pending for that item already TSyncItem *conflictingItemP = getConflictingItemByLocalID(myitemP); if (conflictingItemP) { // cancel any pending operation for the original item. dontSendItemAsServer(conflictingItemP); } // If client already knows that item, we must propagate the merge to the client // by deleting the original item (in addition to sending the update of the merge) if (remoteAlreadyKnowsItem) { PDEBUGPRINTFX(DBG_DATA,( "Merge occured with an item already known remotely (localID=%s, remoteID=%s) -> delete duplicate from client", (*conflictingMapPos).localid.c_str(), (*conflictingMapPos).remoteid.c_str() )); // client already knows an item with that server-side localID // - check if it is the same item as the added one from a server's perspective // (this should not normally not be the case, as otherwise we should not have // tried to add it in the first place - check above should have generated 418 error) bool sameRemoteItem = (*conflictingMapPos).remoteid==myitemP->getRemoteID(); if (sameRemoteItem) { PDEBUGPRINTFX(DBG_ERROR,("Consistency error: despite being added new, this remoteID is already known!?")); } else { // create delete for now duplicate item on client TSyncItem *duplDelP = newItemForRemote(myitemP->getTypeID()); if (duplDelP) { // - setup delete item duplDelP->setRemoteID((*conflictingMapPos).remoteid.c_str()); duplDelP->clearLocalID(); duplDelP->setSyncOp(sop_delete); // - add it to the list of changes to be sent to the client later SendItemAsServer(duplDelP); } } } // if backend has not replaced, but merely merged data, we're done. Otherwise, client needs to be updated with // merged/augmented version of the data if (!remoteHasLatestData && sta!=DB_DataReplaced) { // now create a replace command to update the item added from the client with the merge result // - this is like forcing a conflict, i.e. this loads the item by local/remoteid and adds it to // the to-be-sent list of the server. if (augmentedItemP) { // augmented version was created in engine, just add that version to the list of items to be sent SendItemAsServer(augmentedItemP); // takes ownership of augmentedItemP augmentedItemP = NULL; } else { // augmented version was created in backend, fetch it now and add to list of items to be sent SendDBVersionOfItemAsServer(myitemP); } } sta = LOCERR_OK; // otherwise, treat as ok } #endif // SYSYNC_SERVER } // server // - we don't need the augmented item any more if it still exists at this point if (augmentedItemP) { delete augmentedItemP; augmentedItemP = NULL; } if (sta!=LOCERR_OK) { aStatusCommand.setStatusCode(sta); ok=false; } else { // added ok // - save what is needed for finalisation if (fNeedFinalisation) { myitemP->setLocalID(localID.c_str()); // finalisation needs to know the local ID queueForFinalisation(myitemP); } // - status ok aStatusCommand.setStatusCode(201); // item added // - add or update map entry (in client case, remoteID is irrelevant and possibly is not saved) modifyMap(mapentry_normal,localID.c_str(),remoteID,0,false); ok=true; } break; case sop_replace : if (mappos==fMapTable.end()) { // not found in map table aStatusCommand.setStatusCode(404); ok=false; } else { // - make sure item has local ID set myitemP->setLocalID(localID.c_str()); // update item do_update: sta = apiUpdateItem(*myitemP); CHECK_FOR_AGAIN(sta, CUSTOM_ITEM_UPDATE); if (sta==DB_Conflict) { // DB has detected item conflicts with data already stored in the database and // request merging current data from the backend with new data before storing. bool changedDBVersion, changedNewVersion; augmentedItemP = mergeWithDatabaseVersion(myitemP, changedDBVersion, changedNewVersion); if (augmentedItemP==NULL) sta = DB_Error; // no item found, DB error else { // store augmented version back to DB only if modified do_update_augmented: if (changedDBVersion) sta = apiUpdateItem(*augmentedItemP); else sta = LOCERR_OK; CHECK_FOR_AGAIN(sta, CUSTOM_ITEM_UPDATE_AUGMENTED); delete augmentedItemP; // forget now } } // now check final status if (sta!=LOCERR_OK) { aStatusCommand.setStatusCode(sta); ok=false; } else { // updated ok // - save what is needed for finalisation if (fNeedFinalisation) queueForFinalisation(myitemP); // - status ok aStatusCommand.setStatusCode(200); // item replaced ok ok=true; } } break; case sop_delete : case sop_archive_delete : case sop_soft_delete : if (mappos==fMapTable.end()) { // not found in map table means that remote is trying to // delete an item that wasn't mapped before. This is different from // the case below when the actual item is not there any more, but // the map still existed (-> 211) aStatusCommand.setStatusCode(404); ok=false; } else { // - make sure item has local ID set myitemP->setLocalID(localID.c_str()); // delete item do_delete: sta = apiDeleteItem(*myitemP); CHECK_FOR_AGAIN(sta, CUSTOM_ITEM_DELETE); if (sta!=LOCERR_OK) { // not found is reported as successful 211 status, because result is ok (item deleted, whatever reason) if (sta==404) sta=211; // ok, but item was not there any more else ok=false; // others are real errors aStatusCommand.setStatusCode(sta); } else { // - ok aStatusCommand.setStatusCode(200); // item deleted ok ok=true; } if (ok) { // delete map entry anyway // - mark the map entry for deletion modifyMap(mapentry_normal,localID.c_str(),NULL,0,true); } } break; default : SYSYNC_THROW(TSyncException("Unknown sync op in TCustomImplDS::implProcessItem")); } // switch if (ok) { // successful, save new localID in item myitemP->setLocalID(localID.c_str()); TP_START(fSessionP->fTPInfo,li); return true; } else { TP_START(fSessionP->fTPInfo,li); return false; } } SYSYNC_CATCH (exception &e) PDEBUGPRINTFX(DBG_ERROR,("******** TCustomImplDS::implProcessItem exception: %s",e.what())); aStatusCommand.setStatusCode(510); goto error; SYSYNC_ENDCATCH SYSYNC_CATCH (...) PDEBUGPRINTFX(DBG_ERROR,("******** TCustomImplDS::implProcessItem unknown exception")); goto error; SYSYNC_ENDCATCH error: // Switch back to previous timer TP_START(fSessionP->fTPInfo,li); return false; } // TCustomImplDS::implProcessItem // private helper to prepare for apiSaveAdminData() localstatus TCustomImplDS::SaveAdminData(bool aSessionFinished, bool aSuccessful) { TMapContainer::iterator pos; localstatus sta=LOCERR_OK; // calculate difference between current and previous state of tempGUID maps or pending maps // - mark all non-main map entries as deleted (those that still exist will be re-added later) // - also do some clean-up in case of successful end-of-session pos=fMapTable.begin(); while (pos!=fMapTable.end()) { if ((*pos).entrytype!=mapentry_normal) { // Note: this is not strictly needed any more, as non-normal maps are // now already entered into fMapTable with deleted flag set // (to make sure they don't get used by accident) (*pos).deleted=true; } else if (!(*pos).deleted) { // in case of map table without flags, we must get rid of all non-real maps if (!dsResumeSupportedInDB() && aSessionFinished) { // For client, remoteid is irrelevant and can well be empty // Map entries exist for those items that are not newly added on the client // For server, maps w/o remoteid are not really mapped and must not be saved when // we have no flags to mark this special conditon (mapflag_pendingAddConfirm) if (IS_SERVER && (*pos).remoteid.empty()) { // no remoteid -> this is not a real map, we cannot represent it w/o resume support (=flags) in map table DEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,("LocalID='%s' has no remoteID - cannot be stored in non-DS-1.2 Map DB -> removed map",(*pos).localid.c_str())); if ((*pos).added) { // was never added to DB, so no need to delete it in DB either - just forget it TMapContainer::iterator delpos=pos++; fMapTable.erase(delpos); continue; } else { // is already in DB - mark deleted (*pos).deleted=true; } } else { // clear all specials (*pos).mapflags=0; (*pos).savedmark=false; (*pos).markforresume=false; } } // normal, undeleted map entry, check for cleanup else if ( aSessionFinished && aSuccessful && ((*pos).mapflags & mapflag_pendingAddConfirm) ) { // successful end of session - we can forget pending add confirmations (as the add commands apparently never reached the remote at all) // Note: for clients, maps can well have an empty remoteid (because it does not need to be saved) if (IS_SERVER && (*pos).remoteid.empty()) { PDEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,("Successful end of session but localID='%s' has no remoteID and pendingAddConfirm still set -> removed map",(*pos).localid.c_str())); // if not mapped, this will be a re-add in the next session, so forget it for now if ((*pos).added) { // was never added to DB, so no need to delete it in DB either - just forget it TMapContainer::iterator delpos=pos++; fMapTable.erase(delpos); continue; } else { // is already in DB - mark deleted (*pos).deleted=true; } } else { // For server: is mapped, which means that it now exists in the client - just clean mapflag_pendingAddConfirm // For client: just clean the pendingAddConfirm // Note: maps like this should not exist at this time - as at end of a successful session all items should // have got confirmation. PDEBUGPRINTFX(DBG_ERROR,("Apparently successful end of session - but localID='%s' has pendingAddConfirm still set: sync may not be fully complete",(*pos).localid.c_str())); (*pos).mapflags &= ~mapflag_pendingAddConfirm; // keep mapflag_pendingStatus for documentary/debug purposes (*pos).changed = true; // make sure it gets written to DB } } } // increment here only so we can do "continue" w/o pos increment after delete pos++; } // for all map entries if (dsResumeSupportedInDB()) { // If we have different map entry types - re-add the special entries from the separate lists // Note: these entries are already in the global map table, but with the deleted flag set. // Here those that still exist now will be re-activated (without saving them again if not needed) TStringToStringMap::iterator spos; if (IS_CLIENT) { #ifdef SYSYNC_CLIENT // - now pending maps (unsent ones) PDEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,("SaveAdminData: adding %ld entries from fPendingAddMaps as mapentry_pendingmap",(long)fPendingAddMaps.size())); for (spos=fPendingAddMaps.begin();spos!=fPendingAddMaps.end();spos++) { string locID = (*spos).first; dsFinalizeLocalID(locID); // make sure we have the permanent version in case datastore implementation did deliver temp IDs modifyMap(mapentry_pendingmap, locID.c_str(), (*spos).second.c_str(), 0, false); } // - now pending maps (sent, but not seen status yet) PDEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,("SaveAdminData: adding %ld entries from fUnconfirmedMaps as mapentry_pendingmap/mapflag_pendingMapStatus",(long)fUnconfirmedMaps.size())); for (spos=fUnconfirmedMaps.begin();spos!=fUnconfirmedMaps.end();spos++) { modifyMap(mapentry_pendingmap, (*spos).first.c_str(), (*spos).second.c_str(), mapflag_pendingMapStatus, false); } #endif } else { #ifdef SYSYNC_SERVER // - the tempguid maps PDEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,("SaveAdminData: adding %ld entries from fTempGUIDMap as mapentry_tempidmap",(long)fTempGUIDMap.size())); for (spos=fTempGUIDMap.begin();spos!=fTempGUIDMap.end();spos++) { modifyMap(mapentry_tempidmap, (*spos).second.c_str(), (*spos).first.c_str(), 0, false); } #endif } } sta=apiSaveAdminData(aSessionFinished,aSuccessful); if (sta!=LOCERR_OK) { PDEBUGPRINTFX(DBG_ERROR,("SaveAdminData failed, err=%hd",sta)); } return sta; } // TCustomImplDS::SaveAdminData #endif // not BINFILE_ALWAYS_ACTIVE // save end of session state localstatus TCustomImplDS::implSaveEndOfSession(bool aUpdateAnchors) { localstatus sta=LOCERR_OK; PDEBUGBLOCKCOLL("SaveEndOfSession"); // update TCustomImplDS dsSavedAdmin variables (other levels have already updated their variables if (aUpdateAnchors) { if (!fRefreshOnly || (fRefreshOnly && fCacheData) || fSlowSync) { // This was really a two-way sync or we implicitly know that // we are now in sync with remote (like after one-way-from-remote refresh = reload local) #ifdef BASED_ON_BINFILE_CLIENT if (!binfileDSActive()) #endif // BASED_ON_BINFILE_CLIENT { #ifndef BINFILE_ALWAYS_ACTIVE // Note: in case of BASED_ON_BINFILE_CLIENT, these updates will be done by binfileds // (also note that fPreviousToRemoteSyncCmpRef has different semantics in BASED_ON_BINFILE_CLIENT, // as it serves as a last-changelog-update reference then) // But here, fPreviousToRemoteSyncCmpRef is what it seems - the timestamp corresponding to last sync to remote if (fConfigP->fSyncTimeStampAtEnd) { // if datastore cannot explicitly set modification timestamps, best time to save is current time fPreviousToRemoteSyncCmpRef = fAgentP->getDatabaseNowAs(TCTX_UTC); } else { // if datastore can set modification timestamps, best time to save is start of sync fPreviousToRemoteSyncCmpRef = fCurrentSyncTime; } #endif } // also update opaque reference string possibly needed in DS API implementations fPreviousToRemoteSyncIdentifier = fCurrentSyncIdentifier; PDEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI+DBG_EXOTIC,("updating sync token (fPreviousToRemoteSyncIdentifier) from %s to current sync token %s",fPreviousToRemoteSyncIdentifier.c_str(),fCurrentSyncIdentifier.c_str())); } else { PDEBUGPRINTFX(DBG_ADMIN+DBG_DBAPI+DBG_EXOTIC,("keeping old sync token (fPreviousToRemoteSyncIdentifier) %s instead of updating to current sync token %s",fPreviousToRemoteSyncIdentifier.c_str(),fCurrentSyncIdentifier.c_str())); } // updating anchor means invalidating last Suspend fPreviousSuspendCmpRef = fPreviousToRemoteSyncCmpRef; // setting to current reference can do less harm than setting it to zero fPreviousSuspendIdentifier.erase(); } #ifdef BASED_ON_BINFILE_CLIENT if (binfileDSActive()) { // if we sit on top of activated binfile, let binfile do the actual end-if-session work // (updates of cmprefs etc. are done at binfile level again). sta = inherited::implSaveEndOfSession(aUpdateAnchors); } else #endif // BASED_ON_BINFILE_CLIENT { // save admin data myself now sta=SaveAdminData(true,aUpdateAnchors); // end of session // we can foget the maps now fMapTable.clear(); } PDEBUGENDBLOCK("SaveEndOfSession"); return sta; } // TCustomImplDS::implSaveEndOfSession // - end write with commit bool TCustomImplDS::implEndDataWrite(void) { localstatus sta=LOCERR_OK; TP_DEFIDX(li); TP_SWITCH(li,fSessionP->fTPInfo,TP_database); SYSYNC_TRY { // first make sure data writing ends (and obtain current sync identifier) sta = apiEndDataWrite(fCurrentSyncIdentifier); } SYSYNC_CATCH (exception &e) PDEBUGPRINTFX(DBG_ERROR,("******** implEndDataWrite exception: %s",e.what())); TP_START(fSessionP->fTPInfo,li); return false; SYSYNC_ENDCATCH TP_START(fSessionP->fTPInfo,li); #ifdef BASED_ON_BINFILE_CLIENT if (binfileDSActive()) { // binfile level must be called as well sta = inherited::implEndDataWrite(); } #endif return sta; } // TCustomImplDS::implEndDataWrite // delete sync set one by one localstatus TCustomImplDS::zapSyncSetOneByOne(void) { TSyncSetList::iterator pos; localstatus sta; TStatusCommand dummy(getSession()); // check if we need to apply filters bool filteredDelete = fFilteringNeededForAll || fFilteringNeeded; TSyncItem *delitemP = NULL; if (!filteredDelete) { PDEBUGPRINTFX(DBG_DATA,("Zapping datastore unfiltered: deleting %ld items from database",(long)fSyncSetList.size())); } else { PDEBUGPRINTFX(DBG_DATA,("Zapping datastore with filter: deleting only filter passing items of max %ld items",(long)fSyncSetList.size())); } long tot = fSyncSetList.size(); long n = 0; for (pos=fSyncSetList.begin(); pos!=fSyncSetList.end(); ++pos) { if (filteredDelete) { // we need to inspect further, as we may NOT delete the entire sync set // - get the item with data (we become owner of it!) getItemFromSyncSetItem(*pos,delitemP); // - check filters bool passes=postFetchFiltering(delitemP); if (!passes) { tot--; // one less than initially assumed continue; // don't delete this one, it does not pass the filter } // - delete now PDEBUGPRINTFX(DBG_DATA,("- item '%s' passes filter -> deleting",delitemP->getLocalID())); } else { // all items loaded need to be deleted // - create dummy item delitemP = newItemForRemote(ity_multifield); delitemP->setLocalID((*pos)->localid.c_str()); } // delete sta = apiDeleteItem(*(static_cast(delitemP))); n++; DB_PROGRESS_EVENT(this,pev_deleting,n,tot,0); // forget the item delete delitemP; // success or "211 - not deleted" is ok. if (sta!=LOCERR_OK && sta!=211) return sta; } return LOCERR_OK; // zapped ok } // TCustomImplDS::zapSyncSetOneByOne // private helper: get item with data from sync set list. Retrieves item if not already // there from loading the sync set // Note: can be called with aSyncSetItemP==NULL, which causes directly loading from DB // in all cases. localstatus TCustomImplDS::getItemFromSyncSetItem(TSyncSetItem *aSyncSetItemP, TSyncItem *&aItemP) { if (aSyncSetItemP && aSyncSetItemP->itemP) { // already fetched - pass it to caller and remove link in syncsetitem aItemP = aSyncSetItemP->itemP; aSyncSetItemP->itemP = NULL; // syncsetitem does not own it any longer } else { // item not yet fetched (or already retrieved once), fetch it now // - create new empty TMultiFieldItem aItemP = (TMultiFieldItem *) newItemForRemote(ity_multifield); if (!aItemP) return 510; // - assign local id, as it is required e.g. by DoDataSubstitutions aItemP->setLocalID(aSyncSetItemP->localid.c_str()); // - set default operation aItemP->setSyncOp(sop_replace); // Now fetch item (read phase) localstatus sta = apiFetchItem(*((TMultiFieldItem *)aItemP),true,aSyncSetItemP); if (sta!=LOCERR_OK) { delete aItemP; aItemP = NULL; } return sta; } // ok return LOCERR_OK; } // TCustomImplDS::getItemFromSyncSetItem #ifndef BINFILE_ALWAYS_ACTIVE // - save status information required to possibly perform a resume (as passed to datastore with // implMarkOnlyUngeneratedForResume() and implMarkItemForResume()) // (or, in case the session is really complete, make sure that no resume state is left) localstatus TCustomImplDS::implSaveResumeMarks(void) { #ifdef BASED_ON_BINFILE_CLIENT // let binfile handle it if it is active if (binfileDSActive()) { return inherited::implSaveResumeMarks(); } #endif // BASED_ON_BINFILE_CLIENT // update anchoring info for resume if (fConfigP->fSyncTimeStampAtEnd) { // if datastore cannot explicitly set modification timestamps, best time to save is current time fPreviousSuspendCmpRef = fAgentP->getDatabaseNowAs(TCTX_UTC); } else { // if datastore can set modification timestamps, best time to save is start of sync fPreviousSuspendCmpRef = fCurrentSyncTime; } // also update opaque reference string possibly needed in DS API implementations fPreviousSuspendIdentifier = fCurrentSyncIdentifier; // save admin data now return SaveAdminData(false,false); // not end of session, not successful end either } // TCustomImplDS::implSaveResumeMarks #endif // not BINFILE_ALWAYS_ACTIVE #ifdef BASED_ON_BINFILE_CLIENT // Connecting methods when CustomImplDS is used on top of BinFileImplDS // Note: these are defined by BinFileImplDS and are ONLY CALLED IF BinFileImplDS is // active. In setups where we can switch off the intermediate binfile layer, // these routines are never called and can't harm // private helper localstatus TCustomImplDS::makeSyncSetLoaded(bool aNeedAll) { localstatus sta = LOCERR_OK; // assume loaded ok if (!fSyncSetLoaded) { // not yet loaded, try to load PDEBUGBLOCKFMTCOLL(("ReadSyncSet","Reading Sync Set from Database","datastore=%s",getName())); SYSYNC_TRY { sta = apiReadSyncSet(aNeedAll); PDEBUGENDBLOCK("ReadSyncSet"); } SYSYNC_CATCH(exception &e) PDEBUGPRINTFX(DBG_ERROR,("makeSyncSetLoaded exception: %s",e.what())); sta=510; // end of DB read PDEBUGENDBLOCK("ReadSyncSet"); SYSYNC_ENDCATCH if (sta==LOCERR_OK) fSyncSetLoaded=true; // is now loaded } return sta; // ok only if now loaded } // TCustomImplDS::makeSyncSetLoaded /// get first item from the sync set. Caller obtains ownership if aItemP is not NULL after return /// @return false if no item found bool TCustomImplDS::getFirstItem(TSyncItem *&aItemP) { // reset the iterator fSyncSetPos = fSyncSetList.begin(); // now get first item's info return getNextItem(aItemP); } // TCustomImplDS::getFirstItem /// get next item from the sync set. Caller obtains ownership if aItemP is not NULL after return /// @return false if no item found bool TCustomImplDS::getNextItem(TSyncItem *&aItemP) { if (!fSyncSetLoaded) return false; // no syncset, nothing to report if (fSyncSetPos!=fSyncSetList.end()) { // get the info TSyError sta = getItemFromSyncSetItem(*fSyncSetPos,aItemP); if (sta==LOCERR_OK) { // advance to next item in sync set fSyncSetPos++; // successful return true; } } // no more items (or problem getting item) return false; } // TCustomImplDS::getNextItem #ifdef CHANGEDETECTION_AVAILABLE /// get item's ID and modification status from the sync set, not including data /// @return false if no item found bool TCustomImplDS::getFirstItemInfo(localid_out_t &aLocalID, bool &aItemHasChanged) { // reset the iterator fSyncSetPos = fSyncSetList.begin(); // now get first item's info return getNextItemInfo(aLocalID, aItemHasChanged); } // TCustomImplDS::getFirstItemInfo /// get next item's ID and modification status from the sync set, not including data /// @return false if no item found bool TCustomImplDS::getNextItemInfo(localid_out_t &aLocalID, bool &aItemHasChanged) { if (!fSyncSetLoaded) return false; // no syncset, nothing to report if (fSyncSetPos!=fSyncSetList.end()) { // get the info TSyncSetItem *syncsetitemP = (*fSyncSetPos); // - ID STR_TO_LOCALID(syncsetitemP->localid.c_str(),aLocalID); // - changeflag aItemHasChanged = syncsetitemP->isModified; // advance to next item in sync set fSyncSetPos++; // ok return true; } // no more items return false; } // TCustomImplDS::getNextItemInfo #endif // CHANGEDETECTION_AVAILABLE /// get item by local ID from the sync set. Caller obtains ownership if aItemP is not NULL after return /// @return != LOCERR_OK if item with specified ID is not found. localstatus TCustomImplDS::getItemByID(localid_t aLocalID, TSyncItem *&aItemP) { if (!fSyncSetLoaded) return 510; // syncset should be loaded here! // search in syncset string localid; LOCALID_TO_STRING(aLocalID,localid); TSyncSetList::iterator syncsetpos = findInSyncSet(localid.c_str()); if (syncsetpos==fSyncSetList.end()) { // not found in current sync set, but could be a newly inserted item - try direct load // - create new empty TMultiFieldItem aItemP = (TMultiFieldItem *) newItemForRemote(ity_multifield); if (!aItemP) return 510; // - assign local id, as it is required e.g. by DoDataSubstitutions aItemP->setLocalID(localid.c_str()); // - set default operation aItemP->setSyncOp(sop_replace); // - now fetch directly from DB localstatus sta = apiFetchItem(*((TMultiFieldItem *)aItemP),true,NULL); if (sta!=LOCERR_OK) { delete aItemP; aItemP = NULL; } return sta; } else { // return sync item from syncset item (fetches data now if not fetched before) return getItemFromSyncSetItem(*syncsetpos,aItemP); } } // TCustomImplDS::getItemByID /// update item by local ID in the sync set. Caller retains ownership of aItemP /// @return != LOCERR_OK if item with specified ID is not found. localstatus TCustomImplDS::updateItemByID(localid_t aLocalID, TSyncItem *aItemP) { if (!aItemP) return 510; // error if (!aItemP->isBasedOn(ity_multifield)) return 415; // must be multifield item TMultiFieldItem *myItemP = static_cast(aItemP); // - assign localid string localid; LOCALID_TO_STRING(aLocalID,localid); myItemP->setLocalID(localid.c_str()); // have API handle it localstatus sta = apiUpdateItem(*myItemP); if (sta==LOCERR_OK) { // updated ok // - save what is needed for finalisation if (fNeedFinalisation) { queueForFinalisation(myItemP); } } return sta; } // TCustomImplDS::updateItemByID /// delete item by local ID in the sync set. /// @return != LOCERR_OK if item with specified ID is not found. localstatus TCustomImplDS::deleteItemByID(localid_t aLocalID) { // create new dummy TMultiFieldItem TMultiFieldItem *myItemP = (TMultiFieldItem *) newItemForRemote(ity_multifield); // assign localid string localid; LOCALID_TO_STRING(aLocalID,localid); myItemP->setLocalID(localid.c_str()); // have API delete it localstatus sta = apiDeleteItem(*myItemP); delete myItemP; // delete dummy item // return status return sta; } // TCustomImplDS::deleteItemByID /// create new item in the sync set. Caller retains ownership of aItemP. /// @return LOCERR_OK or error code. /// @param[out] aNewLocalID local ID assigned to new item /// @param[out] aReceiveOnly is set to true if local changes/deletion of this item should not be /// reported to the server in normal syncs. localstatus TCustomImplDS::createItem(TSyncItem *aItemP,localid_out_t &aNewLocalID, bool &aReceiveOnly) { if (!aItemP) return 510; // error if (!aItemP->isBasedOn(ity_multifield)) return 415; // must be multifield item TMultiFieldItem *myItemP = static_cast(aItemP); // add it to the database string newLocalID; localstatus sta = apiAddItem(*myItemP,newLocalID); // return assigned ID STR_TO_LOCALID(newLocalID.c_str(),aNewLocalID); if (sta==LOCERR_OK) { // added ok // - save what is needed for finalisation if (fNeedFinalisation) { myItemP->setLocalID(newLocalID.c_str()); // finalisation needs to know the local ID queueForFinalisation(myItemP); } } // so far, we don't have receive-only items aReceiveOnly = false; // return status return sta; } // TCustomImplDS::createItem /// zaps the entire datastore, returns LOCERR_OK if ok /// @return LOCERR_OK or error code. localstatus TCustomImplDS::zapDatastore(void) { // make sure we have the sync set if we need it to zap it if (apiNeedSyncSetToZap()) { // make sure we have the sync set localstatus sta = makeSyncSetLoaded(false); if (sta!=LOCERR_OK) return sta; // error } // Zap the sync set in this datastore (will possibly call zapSyncSetOneByOne if there's no more efficient way to do it than one by one) // - make sure we have at least one pev_deleting event, in case app tracks it to see if session caused changes to DB DB_PROGRESS_EVENT(this,pev_deleting,0,0,0); // - now zap return apiZapSyncSet(); } // TCustomImplDS::zapDatastore #endif // BASED_ON_BINFILE_CLIENT connecting methods #ifdef DBAPI_TEXTITEMS // helper to process params // - if aParamName!=NULL, it searches for the value of the requested parameter and returns != NULL, NULL if none found // - if aParamName==NULL, it scans until all params are skipped and returns end of params cAppCharP paramScan(cAppCharP aParams,cAppCharP aParamName, string &aValue) { cAppCharP p = aParams; cAppCharP q,r; int nl,vl; bool quotedvalue=false; if (!p) return NULL; while (*p && *p==';') { // skip param intro p++; // find end of param name for (q=p; *q!=0 && *q!=';' && *q!=':' && *q!='=';) q++; nl=q-p; // - now: p=start of name, nl=length of name // find end of param value if (nl && *q=='=') { // value starts after equal sign q++; if (*q=='"') { // " ) { work around bug in colorizer // quoted value quotedvalue=true; r=++q; while (*r && *r!='"') { // " ) { work around bug in colorizer if (*r=='\\') { r++; if (*r) r++; } else r++; } vl=r-q; if (*r) r++; // skip closing quote if not delimited by end of string } else { // unquoted value, ends at next colon, semicolon or line end (no value case) for (r=q; *r && *r!=':' && *r!=';' && *r!='\r' && *r!='\n';) r++; vl = r-q; } // - now: q=start of value, vl=length of value, *r=char after value } else { // no value r=q; vl=0; } // check if it's our value if (aParamName) { // we are searching a single parameter if (strucmp(p,aParamName,nl)==0) { // found, return it's value if (quotedvalue) CStrToStrAppend(q, aValue, true); // stop at quote or end of line else aValue.assign(q,vl); return p; // position of parameter name } } // next param p=r; } // end of all params if (aParamName) return NULL; // we were searching for a special param and haven't found it // we were scanning for the end of all params // - save all params aValue.assign(aParams,p-aParams); // - return pointer to what comes after params return p; } // paramScan // store API key/value pair field in named field bool TCustomImplDS::storeField( cAppCharP aName, cAppCharP aParams, cAppCharP aValue, TMultiFieldItem &aItem, uInt16 aSetNo, // unused here in base class sInt16 aArrayIndex ) { string s; // find field by name TItemField *fieldP = aItem.getArrayField(aName, aArrayIndex, false); // create element if not existing if (!fieldP) return false; // nothing stored // convert to app string s.erase(); appendStringAsUTF8(aValue, s, chs_utf8, lem_cstr); // treat timestamp specially if (fieldP->isBasedOn(fty_timestamp)) { TTimestampField *tsfP = static_cast(fieldP); // default time zone is none timecontext_t tctx = TCTX_UNKNOWN; // modify time zone if params contain a TZNAME if (paramScan(aParams,"TZNAME",s)) { // convert to time zone context (olson allowed) TimeZoneNameToContext(s.c_str(), tctx, tsfP->getGZones(), true); } // now parse text string into field tsfP->setAsISO8601(aValue, tctx, false); } else { // all others: just set as string fieldP->setAsString(aValue); } return true; } // TCustomImplDS::storeField // - parse text data into item // Note: generic implementation, using virtual storeField() method // to differentiate between use with mapped fields in DBApi and // direct (unmapped) TMultiFieldItem access in Tunnel API. bool TCustomImplDS::parseItemData( TMultiFieldItem &aItem, cAppCharP aItemData, uInt16 aSetNo ) { // read data from input string into mapped fields (or local vars) cAppCharP p = aItemData; cAppCharP q; string fieldname,params,value; bool readsomething=false; uInt16 arrayindex; // show item data as is PDEBUGPRINTFX(DBG_USERDATA+DBG_DBAPI+DBG_EXOTIC+DBG_HOT,("parseItemData received string from DBApi:")); PDEBUGPUTSXX(DBG_USERDATA+DBG_DBAPI+DBG_EXOTIC,aItemData,0,true); // read all fields while(*p) { arrayindex=0; // find name for (q=p; *q && *q!='[' && *q!=':' && *q!=';';) q++; fieldname.assign(p,q-p); // check for array index if (*q=='[') { q++; q+=StrToUShort(q,arrayindex); if (*q==']') q++; } p=q; // find and skip params p = paramScan(p,NULL,params); // p should now point to ':' if (*p==':' || !params.empty()) { // blobs needn't to contain a ':' value.erase(); if (*p==':') { // only get a value, if there is one !! p++; // consume colon // get value p += CStrToStrAppend( p,value,true ); // stop at quote or ctrl char } // if // store field now if (storeField( fieldname.c_str(), params.c_str(), value.c_str(), aItem, aSetNo, // ordering of params is correct now ( before !! ) arrayindex )) readsomething=true; } // skip everything up to next end of line (in case value was terminated by a quote or other ctrl char) while (*p && *p!='\r' && *p!='\n') p++; // skip all line end chars up to beginning of next line or end of record while (*p && (*p=='\r' || *p=='\n')) p++; // p now points to next line's beginning }; return readsomething; } // TCustomImplDS::parseItemData // generate text representation of a single item field bool TCustomImplDS::generateItemFieldData( bool aAssignedOnly, TCharSets aDataCharSet, TLineEndModes aDataLineEndMode, timecontext_t aTimeContext, TItemField *aBasefieldP, cAppCharP aBaseFieldName, string &aDataFields ) { TItemField *leaffieldP; string val; if (!aBasefieldP) return false; // ignore field if it is not assigned and assignedonly flag is set if (aAssignedOnly && aBasefieldP->isUnassigned()) return false; // yes, we want to write this field #ifdef ARRAYFIELD_SUPPORT uInt16 arrayIndex=0; #endif do { // first check if there is an element at all #ifdef ARRAYFIELD_SUPPORT if (aBasefieldP->isArray()) leaffieldP = aBasefieldP->getArrayField(arrayIndex,true); // get existing leaf fields only else leaffieldP = aBasefieldP; // leaf is base field #else leaffieldP = aBasefieldP; // leaf is base field #endif // if no leaf field, we'll need to exit here (we're done with the array) if (leaffieldP==NULL) break; // we have some data, first append name aDataFields += aBaseFieldName; #ifdef ARRAYFIELD_SUPPORT // append array index if this is an array field if (aBasefieldP->isArray()) StringObjAppendPrintf(aDataFields,"[%d]",arrayIndex); #endif // append value if (aBasefieldP->elementsBasedOn(fty_blob)) { // - for blobs we use a BlobID and send the data later aDataFields += ";BLOBID="; aDataFields += aBaseFieldName; #ifdef ARRAYFIELD_SUPPORT // append array index if this is an array field if (aBasefieldP->isArray()) StringObjAppendPrintf(aDataFields,"[%d]",arrayIndex); #endif } else { // - literal value (converted to DB charset as C-escaped string) if (leaffieldP->isBasedOn(fty_timestamp)) { TTimestampField *tsfP = static_cast(leaffieldP); // get original zone timecontext_t tctx = tsfP->getTimeContext(); if (TCTX_IS_DURATION(tctx) || TCTX_IS_DATEONLY(tctx) ||!TCTX_IS_UNKNOWN(tctx)) { // not fully floating, get name TimeZoneContextToName(tctx, val, tsfP->getGZones()); // append it aDataFields+= ";TZNAME="; aDataFields+= val; } // now convert to database time zone tctx = aTimeContext; // desired output zone // report as-is if we have a floating map or if it IS floating if (tsfP->isFloating()) tctx = TCTX_UNKNOWN; // report as-is // now create ISO8601 representation in the requested output time zone // Note: unless output time zone is "FLOATING", this timestamp is *not* in the time zone // of TZNAME, but normalized to the requested output time zone! tsfP->getAsISO8601(val,tctx,true,false,false); } else { leaffieldP->getAsString(val); // get value } aDataFields+=':'; // delimiter string valDB; appendUTF8ToString( val.c_str(), valDB, aDataCharSet, aDataLineEndMode ); StrToCStrAppend(valDB.c_str(),aDataFields,true); // allow 8-bit chars to be represented as-is (no \xXX escape needed) } // if aDataFields+="\r\n"; // CRLF at end // next item in array #ifdef ARRAYFIELD_SUPPORT arrayIndex++; #endif } while(aBasefieldP->isArray()); // only arrays do loop // generated something return true; } // TCustomImplDS::generateItemFieldData #ifdef DBAPI_TUNNEL_SUPPORT // - parse itemdata into item using DB mappings bool TCustomImplDS::parseTunnelItemData( TMultiFieldItem &aItem, cAppCharP aItemData ) { return parseItemData(aItem, aItemData, 0); // internal fields don't have set numbers } // TCustomImplDS::parseTunnelItemData // generate text representations of item's fields (BLOBs and parametrized fields not included) // - returns true if at least one field appended bool TCustomImplDS::generateTunnelItemData( bool aAssignedOnly, TMultiFieldItem *aItemP, string &aDataFields ) { bool createdone=false; // create text representation for all fields in the field list TFieldListConfig *flcP = aItemP->getFieldDefinitions(); sInt16 fid = 0; while (fidnumFields()) { // get base field TItemField *basefieldP = aItemP->getField(fid); // The plugin api docs say that text items should be UTF8 with CRLF line ends. // Plugins might choose how they render their timestamps, we choose UTC (so rendered timestamps will have trailing Z, // unless they are really floating). Note that the TZNAME param still indicates the originating timezone (so is NOT // always UTC!). if (generateItemFieldData(aAssignedOnly, chs_utf8, lem_dos, TCTX_UTC, basefieldP, TCFG_CSTR(flcP->fFields[fid].fieldname), aDataFields)) createdone=true; // we now have at least one field fid++; } // for all field mappings PDEBUGPRINTFX(DBG_USERDATA+DBG_EXOTIC+DBG_HOT,("generateItemData generated string for TunnelAPI:")); PDEBUGPUTSXX(DBG_USERDATA+DBG_EXOTIC,aDataFields.c_str(),0,true); return createdone; } // TCustomImplDS::generateTunnelItemData #endif // DBAPI_TUNNEL_SUPPORT #endif // DBAPI_TEXTITEMS #if defined(DBAPI_ASKEYITEMS) && defined(ENGINEINTERFACE_SUPPORT) // - get a settings key instance that can access the item // NULL is allowed for aItemP for cases where we don't have or want an item (!ReadNextItem:allfields) TDBItemKey *TCustomImplDS::newDBItemKey(TMultiFieldItem *aItemP, bool aOwnsItem) { return new TDBItemKey(getSession()->getSyncAppBase()->fEngineInterfaceP,aItemP,this,aOwnsItem); } // TCustomImplDS::newDBItemKey // TDBItemKey // ========== // set new content item void TDBItemKey::setItem(TMultiFieldItem *aItemP, bool aPassOwner) { forgetItem(); fItemP = aItemP; fOwnsItem = aPassOwner; fWritten = fItemP; // if we have set an item, this counts as written } // TDBItemKey::setItem // get FID for specified name sInt16 TDBItemKey::getFidFor(cAppCharP aName, stringSize aNameSz) { if (!fItemP) return VARIDX_UNDEFINED; // no item, no field is accessible TFieldMapList *fmlP = &(fCustomImplDS->fConfigP->fFieldMappings.fFieldMapList); // check for iterator commands first if (strucmp(aName,VALNAME_FIRST)==0) { fIterator=fmlP->begin(); if (fIterator!=fmlP->end()) return static_cast(*fIterator)->fid; } else if (strucmp(aName,VALNAME_NEXT)==0) { if (fIterator!=fmlP->end()) fIterator++; if (fIterator!=fmlP->end()) return static_cast(*fIterator)->fid; } else { TFieldMapList::iterator pos; for (pos=fmlP->begin(); pos!=fmlP->end(); pos++) { // check for name TFieldMapItem *fmiP = static_cast(*pos); if (strucmp(aName,fmiP->getName(),aNameSz)==0) { // return field ID (negative = local script var, positive = item field) return fmiP->fid; } } } // none found return VARIDX_UNDEFINED; } // TDBItemKey::getFidFor TItemField *TDBItemKey::getBaseFieldFromFid(sInt16 aFid) { if (!fItemP) return NULL; // no item, no field is accessible return fCustomImplDS->getMappedBaseFieldOrVar(*fItemP, aFid); } // TDBItemKey::getBaseFieldFromFid bool TDBItemKey::getFieldNameFromFid(sInt16 aFid, string &aFieldName) { if (!fItemP) return false; // no item, no field is accessible // name is map name (NOT field name!) TFieldMapList *fmlP = &(fCustomImplDS->fConfigP->fFieldMappings.fFieldMapList); TFieldMapList::iterator pos; TFieldMapItem *fmiP; // search field map item by fid, return name for (pos=fmlP->begin(); pos!=fmlP->end(); pos++) { fmiP = static_cast(*pos); // check for fid if (fmiP->fid == aFid) { // return name aFieldName = fmiP->getName(); return true; } } // none found return false; } // TDBItemKey::getFieldNameFromFid #endif // DBAPI_ASKEYITEMS and ENGINEINTERFACE_SUPPORT // Tunnel DB API (accessing a datastore from UIAPI) within a tunnel session // ------------------------------------------------------------------------ #ifdef DBAPI_TUNNEL_SUPPORT // private helper preparing type infrastucture so we can use it void TCustomImplDS::setupTunnelTypes(TSyncItemType *aItemTypeP) { // make sure we have types, or set type if we explicitly specify one if (!canCreateItemForRemote() || aItemTypeP) { // default to preferred TX type if none specified if (!aItemTypeP) aItemTypeP = getPreferredTxItemType(); // install single type for everything setSendTypeInfo(aItemTypeP,aItemTypeP); setReceiveTypeInfo(aItemTypeP,aItemTypeP); } } // must be called to start accesses (read or write) TSyError TCustomImplDS::TunnelStartDataRead(cAppCharP lastToken, cAppCharP resumeToken) { TSyError sta = LOCERR_OK; // forget previously started stuff InternalResetDataStore(); // force reading all data (we are simulating a plugin, which always reports entire sync set!) fSlowSync = true; // make admin ready string deviceID = "tunnelSession_"; deviceID += getName(); // append datastore name to build pseudo device name sta = implMakeAdminReady(deviceID.c_str(), getName(), "tunnelDBAPI"); if (sta==LOCERR_OK) { // setup types - default to preferred tx if not explicitly set (via /tunnel/itemtype) setupTunnelTypes(); // make sure types are ready for use initDataTypeUse(); // start anew sta = implStartDataRead(); } return sta; } TSyError TCustomImplDS::TunnelReadNextItemInternal(ItemID aID, TSyncItem *&aItemP, sInt32 *aStatus, bool aFirst) { TSyError sta = LOCERR_OK; // rewind if first item requested if (aFirst) { sta = implStartDataRead(); } // get next item from DB if (sta==LOCERR_OK) { bool isEOF; bool changed = false; // report all items, not only changed ones aItemP = NULL; sta = implGetItem(isEOF, changed, aItemP); if (sta==LOCERR_OK) { if (isEOF) { // no item *aStatus = ReadNextItem_EOF; } else { // item found // Note: changed status is not really reliable, does not differentiate resumed/normal // and does not relate to tokens passed in TunnelStartDataRead(). // It reflects what the next normal sync would report as changed *aStatus = changed ? ReadNextItem_Changed : ReadNextItem_Unchanged; // implGetItem should deliver some data in all cases if (!aItemP) return DB_Error; // something's wrong // get ID aID->item = StrAlloc(aItemP->getLocalID()); aID->parent = NULL; // none } } } return sta; } // TCustomImplDS::TunnelReadNextItemInternal TSyError TCustomImplDS::TunnelReadNextItem(ItemID aID, appCharP *aItemData, sInt32 *aStatus, bool aFirst) { TSyncItem *itemP = NULL; *aItemData = NULL; TSyError sta = TunnelReadNextItemInternal(aID,itemP,aStatus,aFirst); if (itemP) { if (aItemData) { // create text version and return it string textData; textData.erase(); generateTunnelItemData(false,static_cast(itemP),textData); *aItemData = StrAlloc(textData.c_str()); } // not used any more, we have the text representation delete itemP; } return sta; } TSyError TCustomImplDS::TunnelReadNextItemAsKey(ItemID aID, KeyH aItemKey, sInt32 *aStatus, bool aFirst) { TSyncItem *itemP = NULL; TSyError sta = TunnelReadNextItemInternal(aID,itemP,aStatus,aFirst); if (itemP) { // assign data if (aItemKey) { // pass the item to the key and let key own it, so item will be deleted with key reinterpret_cast(aItemKey)->setItem(static_cast(itemP), true); } else { // nobody wants the item, delete it delete itemP; } } return sta; } // TCustomImplDS::TunnelReadNextItemAsKey TSyError TCustomImplDS::TunnelReadItem(cItemID aID, appCharP *aItemData) { *aItemData = NULL; // create empty item TMultiFieldItem *itemP = static_cast(newItemForRemote(ity_multifield)); // set localID to retrieve itemP->setLocalID(aID->item); // retrieve TStatusCommand dummy(getSession()); TSyError sta = implRetrieveItemByID(*itemP, dummy) ? LOCERR_OK : dummy.getStatusCode(); if (sta==LOCERR_OK) { if (aItemData) { // create text version and return it string textData; textData.erase(); generateTunnelItemData(false,static_cast(itemP),textData); *aItemData = StrAlloc(textData.c_str()); } // not used any more, we have the text representation delete itemP; } return sta; } TSyError TCustomImplDS::TunnelReadItemAsKey(cItemID aID, KeyH aItemKey) { // get item TMultiFieldItem *itemP = reinterpret_cast(aItemKey)->getItem(); // set localID to retrieve itemP->setLocalID(aID->item); // retrieve TStatusCommand dummy(getSession()); return implRetrieveItemByID(*itemP, dummy) ? LOCERR_OK : dummy.getStatusCode(); } // TCustomImplDS::TunnelReadItemAsKey // end of accessing sync set (single item retrieval still possible) TSyError TCustomImplDS::TunnelEndDataRead() { // just pass on return implEndDataRead(); } // TCustomImplDS::TunnelEndDataRead TSyError TCustomImplDS::TunnelStartDataWrite() { // just pass on return apiStartDataWrite(); } // TCustomImplDS::TunnelStartDataWrite // helper routine for insert TSyError TCustomImplDS::TunnelInsertItemInternal(TMultiFieldItem *aItemP, ItemID aNewID) { string newid; TSyError sta = apiAddItem(*aItemP, newid); if (sta==LOCERR_OK) { if (aNewID) { aNewID->item = StrAlloc(newid.c_str()); aNewID->parent = NULL; // none } } return sta; } // TCustomImplDS::TunnelInsertItemInternal TSyError TCustomImplDS::TunnelInsertItem(cAppCharP aItemData, ItemID aID) { TMultiFieldItem *itemP = static_cast(newItemForRemote(ity_multifield)); TSyError sta = LOCERR_WRONGUSAGE; // no parseable data if (parseItemData(*itemP, aItemData, 0)) { // parsed some data, insert it sta = TunnelInsertItemInternal(itemP,aID); } // delete the item delete itemP; return sta; } // TCustomImplDS::TunnelInsertItem TSyError TCustomImplDS::TunnelInsertItemAsKey(KeyH aItemKey, ItemID aID) { return TunnelInsertItemInternal(reinterpret_cast(aItemKey)->getItem(),aID); } // TCustomImplDS::TunnelInsertItemAsKey // helper routine for update TSyError TCustomImplDS::TunnelUpdateItemInternal(TMultiFieldItem *aItemP, cItemID aID, ItemID aUpdID) { string updid; aItemP->setLocalID(aID->item); TSyError sta = apiUpdateItem(*aItemP); if (sta==LOCERR_OK) { if (aUpdID) { cAppCharP newID = aItemP->getLocalID(); if (strcmp(newID,aID->item)!=0) aUpdID->item = StrAlloc(newID); else aUpdID->item = NULL; aUpdID->parent = NULL; // none } } return sta; } // TCustomImplDS::TunnelUpdateItemInternal TSyError TCustomImplDS::TunnelUpdateItem(cAppCharP aItemData, cItemID aID, ItemID aUpdID) { TMultiFieldItem *itemP = static_cast(newItemForRemote(ity_multifield)); TSyError sta = LOCERR_WRONGUSAGE; // no parseable data if (parseItemData(*itemP, aItemData, 0)) { // parsed some data, insert it sta = TunnelUpdateItemInternal(itemP,aID,aUpdID); } // delete the item delete itemP; return sta; } // TCustomImplDS::TunnelUpdateItem TSyError TCustomImplDS::TunnelUpdateItemAsKey(KeyH aItemKey, cItemID aID, ItemID aUpdID) { return TunnelUpdateItemInternal(reinterpret_cast(aItemKey)->getItem(),aID,aUpdID); } // TCustomImplDS::TunnelUpdateItemAsKey TSyError TCustomImplDS::TunnelMoveItem(cItemID aID, cAppCharP newParID) { return LOCERR_NOTIMP; } // TCustomImplDS::TunnelMoveItem TSyError TCustomImplDS::TunnelDeleteItem(cItemID aID) { TMultiFieldItem *itemP = static_cast(newItemForRemote(ity_multifield)); itemP->setLocalID(aID->item); TSyError sta = apiDeleteItem(*itemP); delete itemP; return sta; } // TCustomImplDS::TunnelDeleteItem TSyError TCustomImplDS::TunnelEndDataWrite(bool aSuccess, appCharP *aNewToken) { string newToken; TSyError sta = apiEndDataWrite(newToken); if (aNewToken) { *aNewToken = StrAlloc(newToken.c_str()); } return sta; } // TCustomImplDS::TunnelEndDataWrite void TCustomImplDS::TunnelDisposeObj(void* aMemory) { // return string we have created as a plugin (is NULL safe) StrDispose(aMemory); } // TCustomImplDS::TunnelDisposeObj // Tunnel key factory method TSettingsKeyImpl *TCustomImplDS::newTunnelKey(TEngineInterface *aEngineInterfaceP) { return new TCustomDSTunnelKey(aEngineInterfaceP,this); } // TCustomImplDS::newTunnelKey // TTunnelKey // ---------- // constructor TCustomDSTunnelKey::TCustomDSTunnelKey( TEngineInterface *aEngineInterfaceP, TCustomImplDS *aCustomImplDsP ) : inherited(aEngineInterfaceP), fCustomImplDsP(aCustomImplDsP) { } // TCustomDSTunnelKey::TCustomDSTunnelKey // destructor - close key TCustomDSTunnelKey::~TCustomDSTunnelKey() { // closing key } // TCustomDSTunnelKey::~TCustomDSTunnelKey // open subkey by name (not by path!) // - this is the actual implementation TSyError TCustomDSTunnelKey::OpenSubKeyByName( TSettingsKeyImpl *&aSettingsKeyP, cAppCharP aName, stringSize aNameSize, uInt16 aMode ) { if (strucmp(aName,"item",aNameSize)==0) { // make sure defaults are initialized fCustomImplDsP->setupTunnelTypes(); // create a sendable item TMultiFieldItem *itemP = static_cast(fCustomImplDsP->newItemForRemote(ity_multifield)); // wrap it into a item key aSettingsKeyP = new TMultiFieldItemKey(fEngineInterfaceP, itemP, true); // item is owned by key, which means that it will be deleted with key // done return LOCERR_OK; } else return inherited::OpenSubKeyByName(aSettingsKeyP,aName,aNameSize,aMode); // opened a key return LOCERR_OK; } // TCustomDSTunnelKey::OpenSubKeyByName // - get item type name (if not written before, this will be the preferred type of the datastore) static TSyError readItemType( TStructFieldsKey *aStructFieldsKeyP, const TStructFieldInfo *aFldInfoP, appPointer aBuffer, memSize aBufSize, memSize &aValSize ) { TCustomImplDS *ds = static_cast(aStructFieldsKeyP)->getCustomImplDs(); // make sure defaults are initialized ds->setupTunnelTypes(); // get name of fLocalSendToRemoteTypeP return TStructFieldsKey::returnString(ds->getLocalSendType()->getTypeName(), aBuffer, aBufSize, aValSize); } // readItemType // - set item type static TSyError writeItemType( TStructFieldsKey *aStructFieldsKeyP, const TStructFieldInfo *aFldInfoP, cAppPointer aBuffer, memSize aValSize ) { TCustomImplDS *ds = static_cast(aStructFieldsKeyP)->getCustomImplDs(); cAppCharP p=cAppCharP(aBuffer); TSyncItemType *ty = ds->getSendType(p,NULL); if (!ty) return 404; // type not found ds->setupTunnelTypes(ty); // done return LOCERR_OK; } // writeItemType // accessor table for tunnel key values const TStructFieldInfo TunnelFieldInfos[] = { // valName, valType, writable, fieldOffs, valSiz { "itemtype", VALTYPE_TEXT, true, 0, 0, &readItemType, &writeItemType }, }; const sInt32 numTunnelFieldInfos = sizeof(TunnelFieldInfos)/sizeof(TStructFieldInfo); // get table describing the fields in the struct const TStructFieldInfo *TCustomDSTunnelKey::getFieldsTable(void) { return TunnelFieldInfos; } // TCustomDSTunnelKey::getFieldsTable sInt32 TCustomDSTunnelKey::numFields(void) { return numTunnelFieldInfos; } // TCustomDSTunnelKey::numFields #endif // DBAPI_TUNNEL_SUPPORT /* end of TCustomImplDS implementation */ } // namespace // eof libsynthesis-3.4.0.47.1/src/sysync/customimplds.h000077500000000000000000001261561226375725500216750ustar00rootroot00000000000000/** * @File customimpl.h * * @Author Lukas Zeller (luz@plan44.ch) * * @brief TCustomImplDS * Base class for customizable datastores (mainly extended DB mapping features * common to all derived classes like ODBC, DBAPI etc.). * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * @Date 2005-12-05 : luz : separated from odbcapids */ #ifndef CUSTOMIMPLDS_H #define CUSTOMIMPLDS_H // includes #include "stdlogicds.h" #include "multifielditemtype.h" #include "customimplagent.h" #ifdef BASED_ON_BINFILE_CLIENT #include "binfileimplds.h" #else #ifdef BINFILE_ALWAYS_ACTIVE #error "BINFILE_ALWAYS_ACTIVE is only possible when BASED_ON_BINFILE_CLIENT" #endif #endif using namespace sysync; namespace sysync { #ifdef SCRIPT_SUPPORT // publish as derivates might need it extern const TFuncTable CustomDSFuncTable2; #endif // the datastore config // field mapping base class class TFieldMapItem : public TConfigElement { typedef TConfigElement inherited; public: TFieldMapItem(const char *aElementName, TConfigElement *aParentElement); virtual bool isArray(void) { return false; }; // - parser for extra attributes (for derived classes) virtual void checkAttrs(const char **aAttributes) { /* nop in base class */ }; // - field mode, here in base class to simplify things bool readable; // used to read (for SELECT) bool writable; // used to write (for UPDATE,INSERT) // - more detailed control bool for_insert; bool for_update; // - map as parameter (rather than literally inserting field values in INSERT and UPDATE statements) bool as_param; // - map as floating time field (will be written as-is, no conversion from/to DB time zone takes place) bool floating_ts; // - if set, this field's value needs to be saved for finalisation run at the very end of the sync session bool needs_finalisation; // - set number (for having different sets in different statement parts) uInt16 setNo; // - name of the field in SQL statements is the name of the item // - field ID in MultiFieldItem sInt16 fid; // - type // Note: Fields that are separate date/time in the DB but one // field in MultiFieldItem can be specified as dbft_date FIRST and // then as dbft_timefordate in this list, causing time to be combined // with date. TDBFieldType dbfieldtype; // database field type // - field size uInt32 maxsize; // number of chars field can hold (if string or BLOB), 0=unlimited bool notruncate; // set if this field should never be sent truncated by the remote }; // TFieldMapItem typedef std::list TFieldMapList; #ifdef ARRAYDBTABLES_SUPPORT class TFieldMappings; class TCustomDSConfig; // special field map item: Array map class TFieldMapArrayItem : public TFieldMapItem { typedef TFieldMapItem inherited; public: TFieldMapArrayItem(TCustomDSConfig *aCustomDSConfigP, TConfigElement *aParentElement); virtual ~TFieldMapArrayItem(); // properties // - the map for the fields in the array. fid of maps are used as base fid // if they do not reference array fields TFieldMapList fArrayFieldMapList; // - config of related datastore TCustomDSConfig *fCustomDSConfigP; // - base TFieldMappings %%% not used any more, we take it from fCustomDSConfigP //TFieldMappings *fBaseFieldMappings; // - referenced fieldlist %%% not used any more, we take it from fBaseFieldMappings // TFieldListConfig *fFieldListP; #ifdef OBJECT_FILTERING // - filter expression: // if filter evaluates as true, array is not written (or deleted at update) // if array has no items on read, filter is applied to item with makepass() string fNoItemsFilter; #endif #ifdef SCRIPT_SUPPORT // array record's scripts string fInitScript; string fAfterReadScript; string fBeforeWriteScript; string fAfterWriteScript; string fFinishScript; #endif // - repeating params sInt16 fMaxRepeat; // if==0, unlimited repeats (for array fields only) sInt16 fRepeatInc; // increment per repetition bool fStoreEmpty; // if set, empty leaf fields will also be stored in the array // Methods virtual bool isArray(void) { return true; }; virtual void clear(); protected: // check config elements virtual bool localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine); virtual void localResolve(bool aLastPass); #ifdef SCRIPT_SUPPORT // process map scripts (resolve or rebuild them) bool fScriptsResolved; void ResolveArrayScripts(void); void expectScriptUnresolved(string &aTScript,sInt32 aLine, const TFuncTable *aContextFuncs); #endif }; // TFieldMapArrayItem #endif class TCustomDSConfig; class TFieldMappings: public TConfigElement { typedef TConfigElement inherited; public: TFieldMappings(const char* aName, TConfigElement *aParentElement); virtual ~TFieldMappings(); // properties // - the map itself TFieldMapList fFieldMapList; #ifdef SCRIPT_SUPPORT // - script that evaluates the syncset options such as STARTDATE() and ENDDATE() // and configures the DB such that the filtering takes place during fetch. // Must return TRUE if DB level filter can perform requested options string fOptionFilterScript; // - main record's scripts string fInitScript; string fAfterReadScript; string fBeforeWriteScript; string fAfterWriteScript; string fFinishScript; string fFinalisationScript; #endif // - a reference to a field list TFieldListConfig *fFieldListP; virtual void clear(); #ifdef SCRIPT_SUPPORT // processing of map scripts (resolve or rebuild them) virtual const TFuncTable *getDSFuncTableP(void); //%%% moved to fDSScriptsResolved: bool fScriptsResolved; //%%% moved to ResolveDSScripts: void ResolveMapScripts(void); #endif protected: #ifdef SCRIPT_SUPPORT void expectScriptUnresolved(string &aTScript,sInt32 aLine, const TFuncTable *aContextFuncs); #endif // check config elements virtual bool localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine); virtual void localResolve(bool aLastPass); }; // TFieldMappings class TCustomDSConfig: #ifdef BASED_ON_BINFILE_CLIENT public TBinfileDSConfig #else public TLocalDSConfig #endif { #ifdef BASED_ON_BINFILE_CLIENT typedef TBinfileDSConfig inherited; #else typedef TLocalDSConfig inherited; #endif public: TCustomDSConfig(const char* aName, TConfigElement *aParentElement); virtual ~TCustomDSConfig(); // properties // - if set, multi-folder (datastore consisting of multiple folders, such as email) // features are enabled for this datastore bool fMultiFolderDB; // - charset to be used in the data table TCharSets fDataCharSet; // - line end mode to be used in the data table for multiline data TLineEndModes fDataLineEndMode; // - if set, causes that data is read from DB first and then merged // with updated fields. Not needed in normal DBs that can // update a subset of all columns. bool fUpdateAllFields; // - Date/Time info bool fDataIsUTC; //%%% legacy flag for compatibility, superseded by fDataTimeZone timecontext_t fDataTimeZone; // time zone for storing/retrieving timestamps in DB bool fUserZoneOutput; // if set, all non-floating timestamps are moved to user time zone (probably from datatimezone) // - admin capability info bool fStoreSyncIdentifiers; // if set, database separately stores "last sync with data sent to remote" and "last suspend" identifiers (stored as string, not necessarily a date) #ifndef BINFILE_ALWAYS_ACTIVE bool fSyncTimeStampAtEnd; // if set, time point of sync is taken AFTER last write to DB (for single-user DBs like FMPro) bool fOneWayFromRemoteSupported; // if set, database has a separate "last sync with data sent to remote" timestamp bool fResumeSupport; // if set, admin tables have DS 1.2 support needed for resume (map entrytype, map flags, fResumeAlertCode, fLastSuspend, fLastSuspendIdentifier bool fResumeItemSupport; // if set, admin tables have support for storing data to resume a partially transferred item // - one-way support is always given for binfile based DS virtual bool isOneWayFromRemoteSupported() { return fOneWayFromRemoteSupported; } #endif // not BINFILE_ALWAYS_ACTIVE // - Database field to item field mappings TFieldMappings fFieldMappings; #ifdef SCRIPT_SUPPORT // provided to allow derivates to add API specific script functions to scripts called from CustomImplDS virtual const TFuncTable *getDSFuncTableP(void) { return &CustomDSFuncTable1; }; // - script called after admin data is loaded (before any data access takes place) string fAdminReadyScript; // - script called after sync with this datastore is ended (before writing the log) string fSyncEndScript; // - context for resolving scripts in datastore context TScriptContext *fResolveContextP; // - resolve DS scripts, this may be called before entire DS config is resolved to allow map's accessing local vars bool fDSScriptsResolved; void ResolveDSScripts(void); virtual void apiResolveScripts(void) { /* nop here */ }; #endif // factory functions for field map items virtual TFieldMapItem *newFieldMapItem(const char *aElementName, TConfigElement *aParentElement) { return new TFieldMapItem(aElementName,aParentElement); }; #ifdef ARRAYDBTABLES_SUPPORT virtual TFieldMapArrayItem *newFieldMapArrayItem(TCustomDSConfig *aCustomDSConfig, TConfigElement *aParentElement) { return new TFieldMapArrayItem(aCustomDSConfig,aParentElement); }; #endif // returns false for datastores that are not abstract, i.e. have a backend implementation (=all stdlogicds derivates) virtual bool isAbstractDatastore(void) { return false; }; // customimplds is the foundation for a implemented backend - so it is no longer abstract protected: // Add (probably datastore-specific) limits such as MaxSize and NoTruncate to types virtual void addTypeLimits(TLocalEngineDS *aLocalDatastoreP, TSyncSession *aSessionP); // check config elements virtual bool localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine); virtual void clear(); virtual void localResolve(bool aLastPass); }; // TCustomDSConfig #ifndef BINFILE_ALWAYS_ACTIVE // getitem phase typedef enum { gph_deleted, gph_added_changed, gph_done } TGetPhases; /// Map flags #define mapflag_useforresume 0x00000001 ///< set on map items that were marked for resume in the previous session #define mapflag_pendingMapStatus 0x00000002 ///< set on pending maps that have been sent, but not seen status yet #define mapflag_pendingStatus 0x00000004 ///< set on map items that have generated a add/update/move, but not seen status yet #define mapflag_pendingDeleteStatus 0x00000008 ///< set on map items that have generated a delete, but not seen status yet #define mapflag_pendingAddConfirm 0x00000010 ///< set on items that have generated a add op, and have not yet received full confirmation (=status for client, =map for server) #define mapflag_resend 0x00000020 ///< set on items that should be re-sent to remote in next session /// Map entry types typedef enum { mapentry_invalid, ///< should not ever be present mapentry_normal, ///< normal localID to remoteID map item mapentry_tempidmap, ///< pseudo-map items that is not a local/remote maps, but saved local/adjustedLocal map (server only) mapentry_pendingmap, ///< pseudo-map item that represents pending maps to be sent after resume (client only) numMapEntryTypes } TMapEntryType; #ifdef SYDEBUG extern const char * const MapEntryTypeNames[]; #endif /// local in-memory map entry /// @Note This mapentry can hold main maps, as well as tempGUID and pendingMap pseudo maps typedef struct { TMapEntryType entrytype; ///< type of mapentry string localid; ///< localID string remoteid; ///< remoteID uInt32 mapflags; ///< mapflag_xxxx bool changed; ///< set for map items changed in this session bool deleted; ///< set for map items deleted in this session bool added; ///< set for map items added in this session bool markforresume; ///< set for map items that must be saved with mapflag_useforresume bool savedmark; ///< set for map items that are already saved with mapflag_useforresume (optimisation) } TMapEntry; // container for map entries typedef list TMapContainer; #endif // BINFILE_ALWAYS_ACTIVE // local SyncSet entry typedef struct { string localid; string containerid; // for multi-folder DBs bool isModified; // set if modified since last sync bool isModifiedAfterSuspend; // set if modified since last suspend // optional item contents (depends on implementation of ReadSyncSet()) TMultiFieldItem *itemP; } TSyncSetItem; // container for sync set information typedef list TSyncSetList; // container for finalisation typedef list TMultiFieldItemList; class TDBItemKey; class TCustomImplDS: #ifdef BASED_ON_BINFILE_CLIENT public TBinfileImplDS #else public TStdLogicDS #endif { #ifdef BASED_ON_BINFILE_CLIENT typedef TBinfileImplDS inherited; #else typedef TStdLogicDS inherited; #endif friend class TCustomDSfuncs; friend class TCustomCommonFuncs; friend class TDBItemKey; friend class TCustomDSTunnelKey; private: void InternalResetDataStore(void); // reset for re-use without re-creation protected: /// @name dsSavedAdmin administrative data (anchors, timestamps, maps) as saved or to-be-saved /// @Note These will be loaded and saved be derived classes /// @Note Some of these will be updated from resp. @ref dsCurrentAdmin members at distinct events (suspend, session end, etc.) /// @Note Some of these will be updated during the session, but in a way that does NOT affect the anchoring of current/last session // /// @{ /// Reference time of previous sync which sent data to remote to compare modification dates against /// @note normally==fPreviousSyncTime, but can be end of sync for datastore that can't write modified timestamps at will #ifndef BASED_ON_BINFILE_CLIENT /// @note for BASED_ON_BINFILE_CLIENT case, these already exist at the binfile level, so we MUST NOT have them here again!! /// @note if binfile is there, but disabled, we still dont need these member vars. lineartime_t fPreviousToRemoteSyncCmpRef; /// Reference string used by database API level to determine modifications since last to-remote-sync string fPreviousToRemoteSyncIdentifier; /// Reference time of last suspend, needed to detect modifications that took place between last suspend and current resume lineartime_t fPreviousSuspendCmpRef; /// Reference string used by database API level to detect modifications that took place between last suspend and current resume string fPreviousSuspendIdentifier; /// @} /// @name dsCurrentAdmin current session's admin data (anchors, timestamps, maps) /// @Note These will be copied to @ref dsSavedAdmin members ONLY when a session completes successfully/suspends. /// @Note Admin data is NEVER directly saved or loaded from these /// @Note Derivates will update some of these at dssta_adminready with current time/anchor values // /// @{ /// Reference time of current sync to compare modification dates against /// @note initially==fCurrentSyncTime, but might be set to end-of-session time for databases which cannot explicitly set modification timestamps lineartime_t fCurrentSyncCmpRef; /// Reference string returned by database API level identifying this session's time (for detecting changes taking place after this session) string fCurrentSyncIdentifier; /// @} #endif public: TCustomImplDS( TCustomDSConfig *aConfigP, sysync::TSyncSession *aSessionP, const char *aName, uInt32 aCommonSyncCapMask=0); virtual void announceAgentDestruction(void); virtual void dsResetDataStore(void) { InternalResetDataStore(); inherited::dsResetDataStore(); }; virtual ~TCustomImplDS(); /// @name apiXXXX methods defining the interface from TCustomImplDS to TXXXApi actual API implementations /// @{ // #ifndef BINFILE_ALWAYS_ACTIVE /// @brief Load admin data from database /// @param aDeviceID[in] remote device URI (device ID) /// @param aDatabaseID[in] local database ID /// @param aRemoteDBID[in] database ID of remote device /// Must search for existing target record matching the triple (aDeviceID,aDatabaseID,aRemoteDBID) /// - if there is a matching record: load it /// - if there is no matching record, set fFirstTimeSync=true. The implementation may already create a /// new record with the key (aDeviceID,aDatabaseID,aRemoteDBID) and initialize it with the data from /// the items as shown below. At least, fTargetKey must be set to a value that will allow apiSaveAdminData to /// update the record. In case implementation chooses not create the record only in apiSaveAdminData, it must /// buffer the triple (aDeviceID,aDatabaseID,aRemoteDBID) such that it is available at apiSaveAdminData. /// If a record exists implementation must load the following items: /// - fTargetKey = some key value that can be used to re-identify the target record later at SaveAdminData. /// If the database implementation has other means to re-identify the target, this can be /// left unassigned. /// - fLastRemoteAnchor = anchor string used by remote party for last session (and saved to DB then) /// - fPreviousSyncTime = anchor (beginning of session) timestamp of last session. /// - fPreviousToRemoteSyncCmpRef = Reference time to determine items modified since last time sending data to remote /// (or last changelog update in case of BASED_ON_BINFILE_CLIENT) /// - fPreviousToRemoteSyncIdentifier = string identifying last session that sent data to remote /// (or last changelog update in case of BASED_ON_BINFILE_CLIENT). Needs only be saved /// if derived datastore cannot work with timestamps and has its own identifier. /// - fMapTable = list containing map entries. The implementation must load all map entries /// related to the current sync target identified by the triple of (aDeviceID,aDatabaseID,aRemoteDBID) /// or by fTargetKey. The entries added to fMapTable must have "changed", "added" and "deleted" flags /// set to false. /// For resumable datastores: /// - fMapTable = In addition to the above, the markforresume flag must be saved in the mapflags // when it is not equal to the savedmark flag - independently of added/deleted/changed. /// - fResumeAlertCode = alert code of current suspend state, 0 if none /// - fPreviousSuspendCmpRef = reference time of last suspend (used to detect items modified during a suspend / resume) /// - fPreviousSuspendIdentifier = identifier of last suspend (used to detect items modified during a suspend / resume) /// (needs only be saved if derived datastore cannot work with timestamps and has /// its own identifier) /// - fPendingAddMaps = map. The implementation must load all all pending maps (client only) into /// fPendingAddMaps (and fUnconfirmedMaps must be left empty). /// - fTempGUIDMap = map. The implementation must save all entries as temporary LUID to GUID mappings /// (server only) virtual localstatus apiLoadAdminData( const char *aDeviceID, // remote device URI (device ID) const char *aDatabaseID, // database ID const char *aRemoteDBID // database ID of remote device ) = 0; /// @brief Save admin data to database /// @param[in] aSessionFinished if true, this is a end-of-session save (and not only a suspend save) - but not necessarily a successful one /// @param[in] aSuccessful if true, this is a successful end-of-session /// Must save to the target record addressed at LoadAdminData() by the triple (aDeviceID,aDatabaseID,aRemoteDBID) /// Implementation must save the following items: /// - fLastRemoteAnchor = anchor string used by remote party for this session (and saved to DB then) /// - fPreviousSyncTime = anchor (beginning of session) timestamp of this session. /// - fPreviousToRemoteSyncCmpRef = Reference time to determine items modified since last time sending data to remote /// (or last changelog update in case of BASED_ON_BINFILE_CLIENT) /// - fPreviousToRemoteSyncIdentifier = string identifying last session that sent data to remote /// (or last changelog update in case of BASED_ON_BINFILE_CLIENT). Needs only be saved /// if derived datastore cannot work with timestamps and has its own identifier. /// - fMapTable = list containing map entries. The implementation must save all map entries /// that have changed, are new or are deleted. See below for additional resume requirements. /// For resumable datastores: /// - fMapTable = In addition to the above, the markforresume flag must be saved in the mapflags // when it is not equal to the savedmark flag - independently of added/deleted/changed. /// - fResumeAlertCode = alert code of current suspend state, 0 if none /// - fPreviousSuspendCmpRef = reference time of last suspend (used to detect items modified during a suspend / resume) /// - fPreviousSuspendIdentifier = identifier of last suspend (used to detect items modified during a suspend / resume) /// (needs only be saved if derived datastore cannot work with timestamps and has /// its own identifier) /// - fPendingAddMaps and fUnconfirmedMaps = map. The implementation must save all entries as /// pending maps (client only). localIDs might be temporary, so call dsFinalizeLocalID() to /// ensure these are final. /// - fTempGUIDMap = map. The implementation must save all entries as temporary LUID to GUID mappings /// (server only) virtual localstatus apiSaveAdminData(bool aSessionFinished, bool aSuccessful) = 0; #endif // BINFILE_ALWAYS_ACTIVE /// allow early data access start (if datastore is configured for it) virtual localstatus apiEarlyDataAccessStart(void) { return LOCERR_OK; /* nop if not overridden */ }; /// read sync set IDs and mod dates. /// @param[in] if set, all data fields are needed, so ReadSyncSet MAY /// read items here already. Note that ReadSyncSet MAY read items here /// even if aNeedAll is not set (if it is more efficient than reading /// them separately afterwards). virtual localstatus apiReadSyncSet(bool aNeedAll) = 0; /// Zap all data in syncset (note that everything outside the sync set will remain intact) virtual localstatus apiZapSyncSet(void) = 0; virtual bool apiNeedSyncSetToZap(void) = 0; // derivate must define this so we can prepare the sync set before zapping if needed /// fetch record contents from DB by localID. virtual localstatus apiFetchItem(TMultiFieldItem &aItem, bool aReadPhase, TSyncSetItem *aSyncSetItemP) = 0; /// add new item to datastore, returns created localID virtual localstatus apiAddItem(TMultiFieldItem &aItem, string &aLocalID) = 0; /// update existing item in datastore, returns 404 if item not found virtual localstatus apiUpdateItem(TMultiFieldItem &aItem) = 0; /// delete existing item in datastore, returns 211 if not existing any more virtual localstatus apiDeleteItem(TMultiFieldItem &aItem) = 0; /// end of syncset reading phase virtual localstatus apiEndDataRead(void) = 0; /// start of write virtual localstatus apiStartDataWrite(void) = 0; #ifdef __clang__ /// Same name as in TBinfileImplDS. Tell clang compiler to ignore that name clash, /// it is okay here. #pragma clang diagnostic push #pragma clang diagnostic ignored "-Woverloaded-virtual" #endif /// end DB data write sequence (but not yet admin data) virtual localstatus apiEndDataWrite(string &aThisSyncIdentifier) = 0; #ifdef __clang__ #pragma clang diagnostic pop #endif /// @} #ifdef DBAPI_TUNNEL_SUPPORT /// @name TunnelXXX methods allowing abstracted access to datastores from UIApi from within a tunnel session /// @{ // virtual TSyError TunnelStartDataRead(cAppCharP aLastToken, cAppCharP aResumeToken); virtual TSyError TunnelReadNextItem(ItemID aID, appCharP *aItemData, sInt32 *aStatus, bool aFirst); virtual TSyError TunnelReadItem(cItemID aID, appCharP *aItemData); virtual TSyError TunnelEndDataRead(); virtual TSyError TunnelStartDataWrite(); virtual TSyError TunnelInsertItem(cAppCharP aItemData, ItemID aID); virtual TSyError TunnelUpdateItem(cAppCharP aItemData, cItemID aID, ItemID aUpdID); virtual TSyError TunnelMoveItem(cItemID aID, cAppCharP aNewParID); virtual TSyError TunnelDeleteItem(cItemID aID); virtual TSyError TunnelEndDataWrite(bool aSuccess, appCharP *aNewToken); virtual void TunnelDisposeObj(void* aMemory); virtual TSyError TunnelReadNextItemAsKey(ItemID aID, KeyH aItemKey, sInt32 *aStatus, bool aFirst); virtual TSyError TunnelReadItemAsKey(cItemID aID, KeyH aItemKey); virtual TSyError TunnelInsertItemAsKey(KeyH aItemKey, ItemID aID); virtual TSyError TunnelUpdateItemAsKey(KeyH aItemKey, cItemID aID, ItemID aUpdID); virtual TSettingsKeyImpl *newTunnelKey(TEngineInterface *aEngineInterfaceP); // helpers void setupTunnelTypes(TSyncItemType *aItemTypeP=NULL); /// @} #endif public: /// @name dsXXXX virtuals defined by TLocalEngineDS /// These are usually designed such that they should always call inherited::dsXXX to let the entire chain /// of ancestors see the calls /// @{ // /// end of message handling virtual void dsEndOfMessage(void); /// inform logic of coming state change virtual localstatus dsBeforeStateChange(TLocalEngineDSState aOldState,TLocalEngineDSState aNewState); /// inform logic of happened state change virtual localstatus dsAfterStateChange(TLocalEngineDSState aOldState,TLocalEngineDSState aNewState); #ifndef BINFILE_ALWAYS_ACTIVE /// called to confirm a sync operation's completion (ok status from remote received) /// @note aSyncOp passed not necessarily reflects what was sent to remote, but what actually happened virtual void dsConfirmItemOp(TSyncOperation aSyncOp, cAppCharP aLocalID, cAppCharP aRemoteID, bool aSuccess, localstatus aErrorStatus=0); #endif // BINFILE_ALWAYS_ACTIVE /// @} /// @name dsHelpers private/protected helper routines /// @{ // private: /// private helper to prepare for apiSaveAdminData() localstatus SaveAdminData(bool aSessionFinished, bool aSuccessful); /// @} // agent TCustomImplAgent *fAgentP; // access to agent (casted fSessionP for convenience) // config (typed pointers for convenience) TCustomDSConfig *fConfigP; TCustomAgentConfig *fAgentConfigP; protected: // some vars sInt16 fArrIdx; #ifdef SCRIPT_SUPPORT // - temp vars while running scripts string fParentKey; bool fWriting; bool fInserting; bool fDeleting; #endif #ifdef ARRAYDBTABLES_SUPPORT bool fHasArrayFields; // set if array table access needed #endif bool fNeedFinalisation; // set if fields which need finalisation exist in field mappings // script context #ifdef SCRIPT_SUPPORT TScriptContext *fScriptContextP; virtual void apiRebuildScriptContexts(void) { /* nop here */ }; #endif // Simple custom DB access interface methods // - returns true if database implementation can only update all fields of a record at once virtual bool dsReplaceWritesAllDBFields(void); #ifndef BINFILE_ALWAYS_ACTIVE // - returns true if DB implementation supports resume (saving of resume marks, alert code, pending maps, tempGUIDs) virtual bool dsResumeSupportedInDB(void); // - returns true if DB implementation supports resuming in midst of a chunked item (can save fPIxxx.. and related admin data) virtual bool dsResumeChunkedSupportedInDB(void); #endif // not BINFILE_ALWAYS_ACTIVE #ifdef OBJECT_FILTERING // - returns true if DB implementation can also apply special filters like CGI-options // /dr(x,y) etc. during fetching virtual bool dsOptionFilterFetchesFromDB(void); #endif /// @name implXXX methods used when based on StdLogicDS /// @{ /// @brief sync login (into this database) /// @note also exists in BASED_ON_BINFILE_CLIENT, will do the job together with /// inhertited binfile version (instead of using DB api) /// @note might be called several times (auth retries at beginning of session) /// @note must update the following state variables /// - in TLocalEngineDS: fLastRemoteAnchor, fLastLocalAnchor, fResumeAlertCode, fFirstTimeSync /// - for client: fPendingAddMaps /// - for server: fTempGUIDMap /// - in TStdLogicDS: fPreviousSyncTime, fCurrentSyncTime /// - in derived classes: whatever else belongs to dsSavedAdmin and dsCurrentAdmin state /// (for example fTargetKey, fFolderKey) virtual localstatus implMakeAdminReady( const char *aDeviceID, ///< remote device URI (device ID) const char *aDatabaseID, ///< database ID const char *aRemoteDBID ///< database ID of remote device ); /// save end of session state /// @note also exists in BASED_ON_BINFILE_CLIENT, will do the job together with /// inhertited binfile version (instead of using DB api) virtual localstatus implSaveEndOfSession(bool aUpdateAnchors); /// start data read /// @note: fSlowSync and fRefreshOnly must be valid before calling this method virtual localstatus implStartDataRead(); /// end of read /// @note also exists in BASED_ON_BINFILE_CLIENT, will do the job together with /// inhertited binfile version. virtual localstatus implEndDataRead(void); /// start of write /// @note also exists in BASED_ON_BINFILE_CLIENT, will do the job together with /// inhertited binfile version. virtual localstatus implStartDataWrite(void); /// end write sequence /// @note also exists in BASED_ON_BINFILE_CLIENT, will do the job together with /// inhertited binfile version. virtual bool implEndDataWrite(void); #ifdef BASED_ON_BINFILE_CLIENT /// when based on binfile client, we need the syncset loaded when binfile is active bool implNeedSyncSetToRetrieve(void) { return binfileDSActive(); }; /// when based on binfile client, we can't track syncop changes (like having the DB report /// items as added again when stdlogic filters have decided they fell out of the syncset) virtual bool implTracksSyncopChanges(void) { return !binfileDSActive(); }; #else bool implNeedSyncSetToRetrieve(void) { return false; }; // non-binfiles don't need the syncset to retrieve virtual bool implTracksSyncopChanges(void) { return true; }; // non-binfile custimpls are capable of this #endif #ifndef BINFILE_ALWAYS_ACTIVE /// get item from DB virtual localstatus implGetItem( bool &aEof, bool &aChanged, TSyncItem* &aSyncItemP ); /// review reported entry (allows post-processing such as map deleting) /// MUST be called after implStartDataWrite, before any actual writing, /// for each item obtained in implGetItem virtual localstatus implReviewReadItem( TSyncItem &aItem // the item ); /// called to set maps. /// @note aLocalID or aRemoteID can be NULL - which signifies deletion of a map entry /// @note that this might be needed for clients accessing a server-style database as well virtual localstatus implProcessMap(cAppCharP aRemoteID, cAppCharP aLocalID); /// retrieve specified item from database virtual bool implRetrieveItemByID( TSyncItem &aItem, // the item TStatusCommand &aStatusCommand ); virtual localstatus logicDeleteItemByID(TSyncItem &aSyncItem) { return apiDeleteItem((TMultiFieldItem &)aSyncItem); } /// process item (according to operation: add/delete/replace - and for future: copy/move) virtual bool implProcessItem( TSyncItem *aItemP, // the item TStatusCommand &aStatusCommand ); /// called to mark an already generated (but probably not sent or not yet statused) item /// as "to-be-resumed", by localID or remoteID (latter only in server case). /// @note This must be repeatable without side effects, as server must mark/save suspend state /// after every request (and not just at end of session) virtual void implMarkItemForResume(cAppCharP aLocalID, cAppCharP aRemoteID, bool aUnSent); /// called to mark an already sent item as "to-be-resent", e.g. due to temporary /// error status conditions, by localID or remoteID (latter only in server case). virtual void implMarkItemForResend(cAppCharP aLocalID, cAppCharP aRemoteID); /// called to have all non-yet-generated sync commands as "to-be-resumed" virtual void implMarkOnlyUngeneratedForResume(void); /// save status information required to possibly perform a resume (as passed to datastore with /// markOnlyUngeneratedForResume() and markItemForResume()) /// (or, in case the session is really complete, make sure that no resume state is left) virtual localstatus implSaveResumeMarks(void); /// @} #endif // not BINFILE_ALWAYS_ACTIVE #ifdef BASED_ON_BINFILE_CLIENT /// @name methods used when based on BinfileImplDS /// @{ #ifndef CHANGEDETECTION_AVAILABLE #error "CustomImplDS can be built only on BinFileImplDS with CHANGEDETECTION_AVAILABLE" #endif /// get first item's ID and modification status from the sync set /// @return false if no item found virtual bool getFirstItemInfo(localid_out_t &aLocalID, bool &aItemHasChanged); /// get next item's ID and modification status from the sync set. /// @return false if no item found virtual bool getNextItemInfo(localid_out_t &aLocalID, bool &aItemHasChanged); /// get first item from the sync set. Caller obtains ownership if aItemP is not NULL after return /// @return false if no item found virtual bool getFirstItem(TSyncItem *&aItemP); /// get next item from the sync set. Caller obtains ownership if aItemP is not NULL after return /// @return false if no item found virtual bool getNextItem(TSyncItem *&aItemP); /// get item by local ID from the sync set. Caller obtains ownership if aItemP is not NULL after return /// @return != LOCERR_OK if item with specified ID is not found. virtual localstatus getItemByID(localid_t aLocalID, TSyncItem *&aItemP); /* no need to implement these here, calling API level directly from binfile is enough /// signal start of data write phase virtual localstatus apiStartDataWrite(void); /// signal end of data write phase virtual localstatus apiEndDataWrite(void); */ /// update item by local ID in the sync set. Caller retains ownership of aItemP /// @return != LOCERR_OK if item with specified ID is not found. virtual localstatus updateItemByID(localid_t aLocalID, TSyncItem *aItemP); /// delete item by local ID in the sync set. /// @return != LOCERR_OK if item with specified ID is not found. virtual localstatus deleteItemByID(localid_t aLocalID); /// create new item in the sync set. Caller retains ownership of aItemP. /// @return LOCERR_OK or error code. /// @param[out] aNewLocalID local ID assigned to new item /// @param[out] aReceiveOnly is set to true if local changes/deletion of this item should not be /// reported to the server in normal syncs. virtual localstatus createItem(TSyncItem *aItemP,localid_out_t &aNewLocalID, bool &aReceiveOnly); /// zaps the entire datastore, returns LOCERR_OK if ok /// @return LOCERR_OK or error code. virtual localstatus zapDatastore(void); /// @} #endif // BASED_ON_BINFILE_CLIENT protected: // - helper for getting a base field pointer (not resolved down to array element) TItemField *getMappedBaseFieldOrVar(TMultiFieldItem &aItem, sInt16 aFid); // - helper for getting a field pointer (local script var or item's field) TItemField *getMappedFieldOrVar(TMultiFieldItem &aItem, sInt16 aFid, sInt16 aRepOffset, bool aExistingOnly=false); // In-memory map and syncset access // - mark all map entries as deleted bool deleteAllMaps(void); // - delete syncset void DeleteSyncSet(bool aContentsOnly=false); // - get container ID for specified localid bool getContainerID(const char *aLocalID, string &aContainerID); // - delete sync set one by one localstatus zapSyncSetOneByOne(void); // - Queue the data needed for finalisation (usually - relational link updates) // as a item copy with only finalisation-required fields void queueForFinalisation(TMultiFieldItem *aItemP); public: // - get last to-remote sync time lineartime_t getPreviousToRemoteSyncCmpRef(void) { return fPreviousToRemoteSyncCmpRef; }; lineartime_t getPreviousSuspendCmpRef(void) { return fPreviousSuspendCmpRef; }; // - get syncset list TSyncSetList *getSyncSetList(void) { return &fSyncSetList; }; // - find entry in sync set by localid TSyncSetList::iterator findInSyncSet(const char *aLocalID); protected: #ifndef BINFILE_ALWAYS_ACTIVE // - find non-deleted map entry by local ID / entry type TMapContainer::iterator findMapByLocalID(const char *aLocalID,TMapEntryType aEntryType, bool aDeletedAsWell=false); // - find map entry by remote ID TMapContainer::iterator findMapByRemoteID(const char *aRemoteID); // - modify map, if remoteID or localID is NULL or empty, map item will be deleted (if it exists at all) void modifyMap(TMapEntryType aEntryType, const char *aLocalID, const char *aRemoteID, uInt32 aMapFlags, bool aDelete, uInt32 aClearFlags=0xFFFFFFFF); #endif // not BINFILE_ALWAYS_ACTIVE #ifdef SYSYNC_SERVER // - called when a item in the sync set changes its localID (due to local DB internals) // Datastore must make sure that possibly cached items get updated virtual void dsLocalIdHasChanged(const char *aOldID, const char *aNewID); #endif // SYSYNC_SERVER // - target key (if needed by descendant) string fTargetKey; // - folder key (key value for subselecting in datastore, determined at implMakeAdminReady()) string fFolderKey; // local list of local IDs/mod timestamps of current sync set for speedup and avoiding LEFT OUTER JOIN TSyncSetList fSyncSetList; // - iterator for reporting new and added items in GetItem TSyncSetList::iterator fSyncSetPos; // - list of items that must be processed in finalisation at end of sync TMultiFieldItemList fFinalisationQueue; #ifndef BINFILE_ALWAYS_ACTIVE // local map list TMapContainer fMapTable; // - iterator for reporting deleted items in GetItem TMapContainer::iterator fDeleteMapPos; bool fReportDeleted; TGetPhases fGetPhase; // phase of get bool fGetPhasePrepared; // set if phase is prepared (select or list iterator init) #endif // BINFILE_ALWAYS_ACTIVE #ifdef BASED_ON_BINFILE_CLIENT bool fSyncSetLoaded; // set if sync set is currently loaded localstatus makeSyncSetLoaded(bool aNeedAll); #endif // BASED_ON_BINFILE_CLIENT localstatus getItemFromSyncSetItem(TSyncSetItem *aSyncSetItemP, TSyncItem *&aItemP); bool fNoSingleItemRead; // if set, syncset list will also contain items bool fMultiFolderDB; // if set, we need the syncset list for finding container IDs later #ifdef SCRIPT_SUPPORT bool fOptionFilterTested; bool fOptionFilterWorksOnDBLevel; // set if option filters can be executed by DB #endif // SCRIPT_SUPPORT #ifdef DBAPI_TUNNEL_SUPPORT // Tunnel DB access support bool fTunnelReadStarted; bool generateTunnelItemData(bool aAssignedOnly, TMultiFieldItem *aItemP, string &aDataFields); bool parseTunnelItemData(TMultiFieldItem &aItem, const char *aItemData); TSyError TunnelReadNextItemInternal(ItemID aID, TSyncItem *&aItemP, sInt32 *aStatus, bool aFirst); TSyError TunnelInsertItemInternal(TMultiFieldItem *aItemP, ItemID aNewID); TSyError TunnelUpdateItemInternal(TMultiFieldItem *aItemP, cItemID aID, ItemID aUpdID); #endif // DBAPI_TUNNEL_SUPPORT #ifdef DBAPI_TEXTITEMS // Text item handling // - store itemdata field into named TItemField (derived DBApi store will override this with DB-mapped version) virtual bool storeField( const char *aName, const char *aParams, const char *aValue, TMultiFieldItem &aItem, uInt16 aSetNo, sInt16 aArrayIndex ); // - parse itemdata into item (generic, using virtual storeField() for actually finding field by name) bool parseItemData( TMultiFieldItem &aItem, const char *aItemData, uInt16 aSetNo ); // - generate text data for one field (common for Tunnel and DB API) bool generateItemFieldData( bool aAssignedOnly, TCharSets aDataCharSet, TLineEndModes aDataLineEndMode, timecontext_t aTimeContext, TItemField *aBasefieldP, cAppCharP aBaseFieldName, string &aDataFields ); #endif // DBAPI_TEXTITEMS #if (defined(DBAPI_ASKEYITEMS) || defined(DBAPI_TUNNEL_SUPPORT)) && defined(ENGINEINTERFACE_SUPPORT) TDBItemKey *newDBItemKey(TMultiFieldItem *aItemP, bool aOwnsItem=false); #endif // (DBAPI_ASKEYITEMS or DBAPI_TUNNEL_SUPPORT) and ENGINEINTERFACE_SUPPORT }; // TCustomImplDS #ifdef DBAPI_TEXTITEMS // helper to process params // - if aParamName!=NULL, it searches for the value of the requested parameter and returns != NULL, NULL if none found // - if aParamName==NULL, it scans until all params are skipped and returns end of params cAppCharP paramScan(cAppCharP aParams,cAppCharP aParamName, string &aValue); #endif // DBAPI_TEXTITEMS #if (defined(DBAPI_ASKEYITEMS) || defined(DBAPI_TUNNEL_SUPPORT)) && defined(ENGINEINTERFACE_SUPPORT) // key for access to a item using the settings key API class TDBItemKey : public TItemFieldKey { typedef TItemFieldKey inherited; public: TDBItemKey(TEngineInterface *aEngineInterfaceP, TMultiFieldItem *aItemP, TCustomImplDS *aCustomImplDS, bool aOwnsItem=false) : inherited(aEngineInterfaceP), fCustomImplDS(aCustomImplDS), fItemP(aItemP), fOwnsItem(aOwnsItem) {}; virtual ~TDBItemKey() { forgetItem(); }; TMultiFieldItem *getItem(void) { return fItemP; }; void setItem(TMultiFieldItem *aItemP, bool aPassOwner=false); protected: // methods to actually access a TItemField virtual sInt16 getFidFor(cAppCharP aName, stringSize aNameSz); virtual bool getFieldNameFromFid(sInt16 aFid, string &aFieldName); virtual TItemField *getBaseFieldFromFid(sInt16 aFid); // the datastore TCustomImplDS *fCustomImplDS; // the item being accessed TMultiFieldItem *fItemP; bool fOwnsItem; // iterator TFieldMapList::iterator fIterator; private: void forgetItem() { if (fOwnsItem && fItemP) { delete fItemP; } fItemP=NULL; }; }; // TDBItemKey #endif // (DBAPI_ASKEYITEMS or DBAPI_TUNNEL_SUPPORT) and ENGINEINTERFACE_SUPPORT #ifdef DBAPI_TUNNEL_SUPPORT // tunnel DB API parameters class TCustomDSTunnelKey : public TStructFieldsKey { typedef TStructFieldsKey inherited; public: TCustomDSTunnelKey(TEngineInterface *aEngineInterfaceP, TCustomImplDS *aCustomImplDsP); virtual ~TCustomDSTunnelKey(); TCustomImplDS *getCustomImplDs(void) { return fCustomImplDsP; } protected: // open subkey by name (not by path!) // - this is the actual implementation virtual TSyError OpenSubKeyByName( TSettingsKeyImpl *&aSettingsKeyP, cAppCharP aName, stringSize aNameSize, uInt16 aMode ); // field access const TStructFieldInfo *getFieldsTable(void); sInt32 numFields(void); // fields TCustomImplDS *fCustomImplDsP; }; // TCustomDSTunnelKey #endif // DBAPI_TUNNEL_SUPPORT } // namespace sysync #endif // CUSTOMIMPLDS_H // eof libsynthesis-3.4.0.47.1/src/sysync/dataconversion.cpp000066400000000000000000000136631226375725500225170ustar00rootroot00000000000000#include #include #include using namespace sysync; namespace sysync { class TDummyLocalDSConfig : public TLocalDSConfig { public: TDummyLocalDSConfig(TConfigElement *element) : TLocalDSConfig("dummy", element) {} virtual TLocalEngineDS* newLocalDataStore(sysync::TSyncSession*) { return NULL; } }; class TDummyTLocalEngineDS : public TLocalEngineDS { public: TDummyTLocalEngineDS(TLocalDSConfig *config, TSyncSession *session) : TLocalEngineDS(config, session, "dummy") {} virtual bool logicProcessRemoteItem(TSyncItem*, TStatusCommand&, bool&, std::string*) { return false; } virtual bool logicRetrieveItemByID(TSyncItem&, TStatusCommand&) { return false; } #ifdef SYSYNC_CLIENT virtual bool logicGenerateSyncCommandsAsClient(TSmlCommandPContainer&, TSmlCommand*&, const char*) { return false; } #endif #ifdef SYSYNC_SERVER virtual bool logicGenerateSyncCommandsAsServer(TSmlCommandPContainer &, TSmlCommand * &, const char *) { return false; } #endif virtual void logicMarkOnlyUngeneratedForResume() {} virtual void logicMarkItemForResume(const char*, const char*, bool) {} virtual void logicMarkItemForResend(const char*, const char*) {} #ifdef SYSYNC_SERVER virtual TSyncItem *getConflictingItemByRemoteID(TSyncItem *syncitemP) { return NULL; } virtual TSyncItem *getConflictingItemByLocalID(TSyncItem *syncitemP) { return NULL; } virtual TSyncItem *getMatchingItem(TSyncItem *syncitemP, TEqualityMode aEqMode) { return NULL; } virtual void dontSendItemAsServer(TSyncItem *syncitemP) {} virtual void SendItemAsServer(TSyncItem *aSyncitemP) {} virtual localstatus logicProcessMap(cAppCharP aRemoteID, cAppCharP aLocalID) { return 0; } #endif }; bool DataConversion(SessionH aSession, const char *aFromTypeName, const char *aToTypeName, std::string &aItemData) { bool res = false; TProfileHandler *fromProfile = NULL; TProfileHandler *toProfile = NULL; TSyncItemType *fromItemType = NULL; TSyncItemType *toItemType = NULL; TSyncItem *fromItem = NULL; TSyncItem *toItem = NULL; SmlItemPtr_t smlitem = NULL; TSyncSession *session = reinterpret_cast(aSession); TConfigElement dummyElement("dummy", NULL); class TDummyLocalDSConfig dummyConfig(&dummyElement); class TDummyTLocalEngineDS dummy(&dummyConfig, session); // Temporarily disable per-session workarounds for our peer's // time handling. Eventually we want to make this configurable // per function call, not per session, but for that more // code restructuring is necessary. bool oldRemoteCanHandleUTC = session->fRemoteCanHandleUTC; session->fRemoteCanHandleUTC = true; timecontext_t oldUserTimeContext = session->fUserTimeContext; session->fUserTimeContext = TCTX_UNKNOWN; SYSYNC_TRY { TRootConfig *config = session->getRootConfig(); TDatatypesConfig *types = config->fDatatypesConfigP; TDataTypeConfig *fromTypeConfig = types->getDataType(aFromTypeName); TDataTypeConfig *toTypeConfig = types->getDataType(aToTypeName); TStatusCommand statusCmd(session); if (!fromTypeConfig) { LOGDEBUGPRINTFX(session->getDbgLogger(), DBG_PARSE, ("%s: unknown type", aFromTypeName)); goto done; } if (!toTypeConfig) { LOGDEBUGPRINTFX(session->getDbgLogger(), DBG_PARSE, ("%s: unknown type", aToTypeName)); goto done; } fromItemType = fromTypeConfig->newSyncItemType(session, NULL); toItemType = toTypeConfig->newSyncItemType(session, NULL); if (!fromItemType || !toItemType) { LOGDEBUGPRINTFX(session->getDbgLogger(), DBG_PARSE, ("could not create item types")); goto done; } // parse data and create item from it smlitem = newItem(); if (!smlitem) { LOGDEBUGPRINTFX(session->getDbgLogger(), DBG_PARSE, ("SML item allocation failed")); goto done; } smlitem->data = newPCDataStringX(reinterpret_cast(aItemData.c_str()), true, aItemData.size()); if (!smlitem->data) { LOGDEBUGPRINTFX(session->getDbgLogger(), DBG_PARSE, ("SML data allocation failed")); goto done; } fromItem = fromItemType->newSyncItem(smlitem, sop_replace, fmt_chr, fromItemType, &dummy, statusCmd); smlFreeItemPtr(smlitem); smlitem = NULL; if (!fromItem) { LOGDEBUGPRINTFX(session->getDbgLogger(), DBG_PARSE, ("could not parse data as %s", aFromTypeName)); goto done; } // create item of target format, fill it with the parsed data, then encode toItem = toItemType->newSyncItem(toItemType, &dummy); if (!toItem) { LOGDEBUGPRINTFX(session->getDbgLogger(), DBG_PARSE, ("could not allocate item")); goto done; } if (!toItem->replaceDataFrom(*fromItem)) { LOGDEBUGPRINTFX(session->getDbgLogger(), DBG_PARSE, ("%s and %s are not compatible", aFromTypeName, aToTypeName)); goto done; } smlitem = toItemType->newSmlItem(toItem, &dummy); if (!smlitem) { LOGDEBUGPRINTFX(session->getDbgLogger(), DBG_PARSE, ("could not encode data as %s", aToTypeName)); goto done; } stringSize size; const char *data = smlPCDataToCharP(smlitem->data, &size); if (!data && size) { LOGDEBUGPRINTFX(session->getDbgLogger(), DBG_PARSE, ("string allocation failed")); goto done; } aItemData.assign(data, size); res = true; } SYSYNC_CATCH (...) // TODO: error logging res = false; SYSYNC_ENDCATCH done: if (smlitem) smlFreeItemPtr(smlitem); delete fromItem; delete toItem; delete fromProfile; delete toProfile; delete fromItemType; delete toItemType; session->fRemoteCanHandleUTC = oldRemoteCanHandleUTC; session->fUserTimeContext = oldUserTimeContext; return res; } } // namespace sysync libsynthesis-3.4.0.47.1/src/sysync/dataobjtype.cpp000077500000000000000000000773141226375725500220140ustar00rootroot00000000000000/* * File: DataObjType.cpp * * Author: Beat Forster (bfo@synthesis.ch) * * TDataObjType * base class for data object based items (EMAILOBJ, FILEOBJ, FOLDEROBJ) * implemented for OMA DS V1.2 * * Copyright (c) 2005-2011 by Synthesis AG + plan44.ch * * 2005-07-20 : bfo : created from TextItemType * */ // includes #include "prefix_file.h" #include "sysync.h" #include "dataobjtype.h" using namespace sysync; namespace sysync { const char* BeginCDATA= ""; const char* LowerCDATA= "]]]]>> const char* nam = getAttr(aAttributes,"field"); if (!fFieldListP) return fail("'use' must be specfied before first "); // search field // %%% add context here if we have any sInt16 fid = TConfigElement::getFieldIndex(nam,fFieldListP); if (fid==VARIDX_UNDEFINED) return fail("'field' references unknown field '%s'",nam); // create new tagmap TTagMapDefinition *tagmapP= new TTagMapDefinition(this,fid); // - save in list fTagMaps.push_back(tagmapP); // - let element handle parsing expectChildParsing(*tagmapP); return true; } // if // - none known here if (inherited::localStartElement(aElementName,aAttributes,aLine)) return true; // let the profile parse as if it was inside a or if (fProfileConfigP) return delegateParsingTo(fProfileConfigP,aElementName,aAttributes,aLine); // cannot parse return false; } // TDataObjConfig::localStartElement // resolve void TDataObjConfig::localResolve(bool aLastPass) { // nop // resolve inherited inherited::localResolve(aLastPass); } // TDataObjConfig::localResolve #endif // CONFIGURABLE_TYPE_SUPPORT #ifdef HARDCODED_TYPE_SUPPORT TTagMapDefinition *TDataObjConfig::addTagMap( sInt16 aFid, const char* aXmlTag, bool aBoolType, bool aEmbedded, const char* aParent ) { // create new tagmap TTagMapDefinition *tagmapP = new TTagMapDefinition(this,aFid); // save the options TCFG_ASSIGN(tagmapP->fXmlTag,aXmlTag); tagmapP->fBoolType= aBoolType; tagmapP->fEmbedded= aEmbedded; tagmapP->fParent = aParent; // save in list fTagMaps.push_back(tagmapP); // return pointer return tagmapP; } // TDataObjConfig::addTagMap #endif // HARDCODED_TYPE_SUPPORT /* * Implementation of TDataObjType */ TDataObjType::TDataObjType( TSyncSession *aSessionP, TDataTypeConfig *aTypeCfgP, // type config const char *aCTType, const char *aVerCT, TSyncDataStore *aRelatedDatastoreP, TFieldListConfig *aFieldDefinitions // field definitions ) : TMultiFieldItemType(aSessionP,aTypeCfgP,aCTType,aVerCT,aRelatedDatastoreP,aFieldDefinitions), fProfileHandlerP(NULL) { // save typed config pointer again fTypeCfgP = static_cast(aTypeCfgP); // create the profile handler if there is one at all (a profile is optional) if (fTypeCfgP->fProfileConfigP) { // create the handler fProfileHandlerP = fTypeCfgP->fProfileConfigP->newProfileHandler(this); // set profile mode fProfileHandlerP->setProfileMode(fTypeCfgP->fProfileMode); } } // TDataObjType::TDataObjType TDataObjType::~TDataObjType() { // handler not needed any more if (fProfileHandlerP) delete fProfileHandlerP; } // TDataObjType::~TDataObjType #ifdef OBJECT_FILTERING // get field index of given filter expression identifier. sInt16 TDataObjType::getFilterIdentifierFieldIndex(const char *aIdentifier, uInt16 aIndex) { // check if explicit field level identifier if (strucmp(aIdentifier,"F.",2)==0) { // explicit field identifier, skip property lookup aIdentifier+=2; } else { // search tagmaps for tagged fields TTagMapList::iterator pos; for (pos= fTypeCfgP->fTagMaps.begin(); pos!=fTypeCfgP->fTagMaps.end(); pos++) { // first priority: compare with explicit filterkeyword, if any if (!TCFG_ISEMPTY((*pos)->fFilterKeyword)) { // compare with filterkeyword if (strucmp(TCFG_CSTR((*pos)->fFilterKeyword),aIdentifier)==0) return (*pos)->fFid; } else if (!TCFG_ISEMPTY((*pos)->fXmlTag)) { // compare with xml tag name itself if (strucmp(TCFG_CSTR((*pos)->fXmlTag),aIdentifier)==0) return (*pos)->fFid; } // if } // for // no matching tag found, let TTextProfileHandler search for its own filter identifiers if (fProfileHandlerP) { sInt16 fid = fProfileHandlerP->getFilterIdentifierFieldIndex(aIdentifier,aIndex); if (fid!=FID_NOT_SUPPORTED) return fid; } // no tagged field found, search underlying field list } // if no field ID found so far, look up in field list return TMultiFieldItemType::getFilterIdentifierFieldIndex(aIdentifier, aIndex); } // TDataObjType::getFilterIdentifierFieldIndex #endif // OBJECT_FILTERING // helper to create same-typed instance via base class TSyncItemType *TDataObjType::newCopyForSameType( TSyncSession *aSessionP, // the session TSyncDataStore *aDatastoreP // the datastore ) { // create new itemtype of appropriate derived class type that can handle // this type MP_RETURN_NEW(TDataObjType,DBG_OBJINST,"TDataObjType",TDataObjType( aSessionP, fTypeConfigP, getTypeName(), getTypeVers(), aDatastoreP, fFieldDefinitionsP )); } // TDataObjType::newCopyForSameType // create new sync item of proper type and optimization for specified target TSyncItem *TDataObjType::internalNewSyncItem(TSyncItemType *aTargetItemTypeP, TLocalEngineDS *aLocalDatastoreP) { // All DataObjs are stored in MultiFieldItems if (!aTargetItemTypeP->isBasedOn(ity_multifield)) SYSYNC_THROW(TSyncException(DEBUGTEXT("TDataObjType::internalNewSyncItem with bad-typed target","txit3"))); TMultiFieldItemType *targetitemtypeP = static_cast (aTargetItemTypeP); return new TMultiFieldItem(this,targetitemtypeP); } // TDataObjType::internalNewSyncItem // fill in SyncML data (but leaves IDs empty) bool TDataObjType::internalFillInData( TSyncItem *aSyncItemP, // SyncItem to be filled with data SmlItemPtr_t aItemP, // SyncML toolkit item Data to be converted into SyncItem (may be NULL if no data, in case of Delete or Map) TLocalEngineDS *aLocalDatastoreP, // local datastore TStatusCommand &aStatusCmd // status command that might be modified in case of error ) { // check type if (!aSyncItemP->isBasedOn(ity_multifield)) SYSYNC_THROW(TSyncException(DEBUGTEXT("TDataObjType::internalFillInData: incompatible item class","txit4"))); TMultiFieldItem *itemP = static_cast (aSyncItemP); // process data if any if (aItemP->data) { // parse data stringSize sz; cAppCharP t = smlPCDataToCharP(aItemP->data,&sz); if (!parseData(t,sz,*itemP,aLocalDatastoreP)) { // format error aStatusCmd.setStatusCode(415); // Unsupported media type or format ADDDEBUGITEM(aStatusCmd,"Error parsing Text content"); return false; } } else { // no data aStatusCmd.setStatusCode(412); // incomplete command ADDDEBUGITEM(aStatusCmd,"No data found in item"); return false; } // ok, let ancestor process data as well return TMultiFieldItemType::internalFillInData(aSyncItemP,aItemP,aLocalDatastoreP,aStatusCmd); } // TDataObjType::internalFillInData // sets data and meta from SyncItem data, but leaves source & target untouched bool TDataObjType::internalSetItemData( TSyncItem *aSyncItemP, // the syncitem to be represented as SyncML SmlItemPtr_t aItem, // item with NULL meta and NULL data TLocalEngineDS *aLocalDatastoreP // local datastore ) { // check type if (!aSyncItemP->isBasedOn(ity_multifield)) SYSYNC_THROW(TSyncException(DEBUGTEXT("TDataObjType::internalSetItemData: incompatible item class","txit4"))); TMultiFieldItem *itemP = static_cast (aSyncItemP); // let ancestor prepare first if (!TMultiFieldItemType::internalSetItemData(aSyncItemP,aItem,aLocalDatastoreP)) return false; // generate data item string dataitem; generateData(aLocalDatastoreP,*itemP,dataitem); // put data item into opaque/cdata PCData (note that dataitem could be BINARY string, so we need to pass size!) aItem->data=newPCDataStringX((const uInt8 *)dataitem.c_str(),true,dataitem.size()); // can't go wrong return true; } // TDataObjType::internalSetItemData static void AddXmlTag( string &aString, string aTag, bool newline= false ) { aString+= "<" + aTag + ">"; if (newline) aString+= "\n"; } // AddXmlTag static void AddXmlTagEnd( string &aString, string aTag, bool newline= true ) { aString+= ""; if (newline) aString+= "\n"; } // AddXmlTagEnd static void AppendXml( string &aString, string aTag, const char* value, bool tagDone= false ) { if (*value!='\0') { if (!tagDone) AddXmlTag( aString, aTag ); aString+= value; AddXmlTagEnd( aString, aTag ); } // if } // AppendXml static void AppendCDATA( string &aString, const char* aTag, const char* aValue ) { AddXmlTag( aString, aTag ); // must be shown according to OMA DS 1.2, // even if the body is empty if (*aValue!='\0') { aString+= BeginCDATA; // only for the xml representation aString+= aValue; // the body //%%% luz: not needed here as there is no enclosing CData any more (or this will be done when needed by the SML encoder!) //aString+= LowerCDATA; // only for the xml representation aString+= '\n'; } // if AddXmlTagEnd( aString, aTag ); } // AppendCDATA string TDataObjType::getAttr( TMultiFieldItem &aItem, const char* aXmlTag, const char* aXmlAttr ) { TItemField* fieldP; TTagMapList::iterator pos; string v; // search for an element, which matches for both and for (pos= fTypeCfgP->fTagMaps.begin(); pos!=fTypeCfgP->fTagMaps.end(); pos++) { fieldP= aItem.getField( (*pos)->fFid ); // this is the element we're looking for if (strcmp( aXmlTag, TCFG_CSTR((*pos)->fXmlTag ))==0 && strcmp( aXmlAttr,TCFG_CSTR((*pos)->fXmlAttr))==0) { fieldP->getAsString( v ); // this is the attribute we're looking for break; } // if } // for return v; // is "", if no attribute found } // TDataObjType::getAttr // generate Data item (includes header and footer) void TDataObjType::generateData(TLocalEngineDS *aDatastoreP, TMultiFieldItem &aItem, string &aString) { #ifdef SYDEBUG PDEBUGPRINTFX(DBG_GEN+DBG_HOT,("Generating:") ); aItem.debugShowItem(DBG_GEN); #endif TItemField* fieldP; TItemField* fieldDocType; // the reference to the "DOCTYPE" (File/Folder/Email) field TTagMapList::iterator pos; string docT, v; string inParent; bool tagOpened= false; //%%% luz: do not add extra CData here, this will be done when needed by the SML encoder! //aString= BeginCDATA; // start a CDATA sequence fieldDocType= aItem.getField( "DOCTYPE" ); if (fieldDocType) { fieldDocType->getAsString( docT ); // main tag, straight forward implementation AddXmlTag ( aString, docT, true ); } // if // go thru the tag element list and get the matching element for (pos= fTypeCfgP->fTagMaps.begin(); pos!=fTypeCfgP->fTagMaps.end(); pos++) { fieldP= aItem.getField( (*pos)->fFid ); // this is the element we're looking for if (!fieldP || // not a valid field fieldP==fieldDocType) continue; // has been done outside already, ignore it bool isArr= fieldP->isArray(); sInt16 maxI= 1; // do it once w/o array if (isArr) maxI= fieldP->arraySize(); if (maxI==0) continue; // it is an array w/o any items, skip it if ((*pos)->fEmbedded && fProfileHandlerP) { // set related datastore so handler can access session specific datastore state fProfileHandlerP->setRelatedDatastore(aDatastoreP); fProfileHandlerP->generateText(aItem, v); AppendCDATA( aString, TCFG_CSTR((*pos)->fXmlTag), v.c_str()); continue; // it's done now for this element } // if // the standard case (not embedded): cover both cases: array AND no array sInt16 i; for (i= 0; igetArrayField( i ); if (fieldAP->isAssigned() && TCFG_ISEMPTY((*pos)->fParent) && !inParent.empty()) { AddXmlTagEnd( aString,inParent.c_str() ); inParent= ""; } // there is no native bool representation for the field lists // So do it with the help of an additional flag v= ""; if (fieldAP->isAssigned()) { if (fieldAP->isBasedOn( fty_blob ) && fieldAP->hasProxy()) { #ifdef STREAMFIELD_SUPPORT string enc= getAttr( aItem, TCFG_CSTR((*pos)->fXmlTag), "enc" ); // according OMA DS 1.2, the endcoding attribute "enc" must be // either not present (no encoding), "quoted-printable" or "base64". // The implementation SHOULD NOT use other enc attribute values. const char* ptr = fieldAP->getCStr(); size_t size= fieldAP->getStreamSize(); if (enc.empty()) { // no encoding v.assign( ptr,size ); // => assign directly } else if (strucmp( enc.c_str(),"base64" )==0) { char* bb= b64::encode( (uInt8*)ptr,size ); v= bb; // maybe one copy operation can be avoided in future b64::free( bb ); // does never contain '\0' => can be treated as normal string } else if (strucmp( enc.c_str(),"quoted-printable")==0) { sysync::appendEncoded( (uInt8*)ptr,size, v, enc_quoted_printable, MIME_MAXLINESIZE,0,true,true ); } else { v = "unknown_encoding: \""; v+= enc; v+= "\""; } #endif } else if ((*pos)->fBoolType) { // best fitting for integer and string int ii= fieldAP->getAsInteger(); switch ( ii ) { // this is the integer - boolean mapping case -1: v= "false"; break; // a strange value for "false" case 0: v= ""; break; // 0 is the empty value (not assigned at parsing) case 1: v= "true"; break; // the 'normal' value for "true" } // switch } // if else fieldAP->getAsString( v ); if (!v.empty()) { // avoid multiple identical elements (even if it's allowed in OMA DS 1.2) if (!TCFG_ISEMPTY((*pos)->fParent)) { bool ok= inParent.empty(); // either iParent==0 or strings are different if (!ok && strucmp( inParent.c_str(),TCFG_CSTR((*pos)->fParent) )!=0) { AddXmlTagEnd( aString,inParent.c_str() ); // switch off old tag first, if different ok= true; } // if if (ok) { inParent= (*pos)->fParent; AddXmlTag( aString,inParent.c_str(), true ); } // if } // if } // if } // if if (TCFG_ISEMPTY((*pos)->fXmlAttr)) { // w/o attributes if (tagOpened) aString+= ">"; AppendXml ( aString, (*pos)->fXmlTag, v.c_str(), tagOpened ); tagOpened= false; } else if (!v.empty()) { // with XML attribute handling if (!tagOpened) { aString+= "<"; aString+= TCFG_CSTR((*pos)->fXmlTag); } // if aString+= " "; aString+= TCFG_CSTR((*pos)->fXmlAttr); aString+= "=\"" + v + "\""; tagOpened= true; } // if } // for } // for // Leave the block finally if (!inParent.empty()) AddXmlTagEnd( aString,inParent.c_str()); if (fieldDocType) { fieldDocType->getAsString( docT ); // end of main tag, straight forward implementation AddXmlTagEnd ( aString, docT ); } // if //%%% luz: do not add extra CData here, this will be done when needed by the SML encoder! //aString+= EndCDATA; // terminate the sequence #ifdef SYDEBUG if (PDEBUGTEST(DBG_GEN)) { // note, do not use debugprintf because string is too long PDEBUGPRINTFX(DBG_GEN,("%s", "") ); PDEBUGPRINTFX(DBG_GEN,("Successfully generated:") ); PDEBUGPUTSX (DBG_GEN+DBG_USERDATA, aString.c_str() ); PDEBUGPRINTFX(DBG_GEN+DBG_USERDATA,("%s", "") ); } // if #endif } // TDataObjType::generateData /*! Skip white spaces */ static void SkipWhiteSP( const char* &p ) { while (*p==0x0D || // CR *p==0x0A || // LF *p==0x09 || // HT *p==' ') p++; // skip leading CR/LF/Tabs and spaces } // SkipWhiteSP // simple straight forward letter recognition static bool IsLetter( char ch ) { ch= toupper(ch); return ch>='A' && ch<='Z'; } // IsLetter /*! Get the next tag and value of

* * @param may contain attributes, e.g. * @param +1 go down in the hierarchy * 0 stay on the same level * -1 go up in the hierarchy */ static bool NextTag( const char* &p, string &aTag, string &aAttr, const char* &aPos, int &aSize, int &level, int &direction ) { const char* BeginCom= ""; const char* q; // default values bool vDone= false; aAttr = ""; aPos = ""; aSize = 0; direction = 0; SkipWhiteSP( p ); q= strstr( p,BeginCom ); // comment ? if (q && q==p) { } else { if (*p!='<') return false; // must start with a tag p++; if (*p=='/') { p++; direction= -1; } q= strstr( p,">" ); if (!q) return false; aTag.assign( p, (unsigned int)( q-p ) ); // this is the tag int pos= aTag.find(" "); if (pos>=0) { // the tag contains some attributes aAttr= aTag.substr( pos+1 ); // ==> get them aTag = aTag.substr( 0,pos ); // the real tag } // if p= q+1; } // if do { SkipWhiteSP( p ); if (direction==-1) return true; // end tag reached if (*p!='<') break; // a value is coming now, not nested // is it a comment ? q= strstr( p,BeginCom ); if (q && q==p) { q= strstr( q, EndCom ); if (!q) return false; p= q + strlen ( EndCom ); continue; // comment is skipped } // if q= strstr( p," do handling outside return true; } while (true); SkipWhiteSP( p ); q= strstr( p, "" ); if (!q) return false; p= q+1; return true; } // NextTag // the structure for attributes with values struct TAField { string name; string value; }; // AField /* struct VVV { VVV() { printf( "hinein\n" ); } ~VVV() { printf( "hinaus '%s'\n", a.c_str() ); } string a; }; */ // parse Data item (includes header and footer) bool TDataObjType::parseData(const char *aText, stringSize aSize, TMultiFieldItem &aItem, TLocalEngineDS *aDatastoreP) { TItemField* fieldP; TTagMapList::iterator pos; string tag, attr, value, docType; const char* vPos; int vSize; // Hierarchical tags typedef std::list TStrList; TStrList tagHierarchy; TStrList::iterator px; TAField a; typedef std::list TAList; TAList aList; TAList::iterator ax; #ifdef SYDEBUG if (PDEBUGTEST(DBG_PARSE)) { // very detailed, show item being parsed PDEBUGPRINTFX(DBG_PARSE+DBG_HOT, ("Parsing: ") ); PDEBUGPUTSX (DBG_PARSE+DBG_USERDATA, aText); } #endif // Go thru all the tags and build temporary stack at int level= 0; int direction; const char* p= aText; if (strstr( p, BeginCDATA )==p) p+= strlen( BeginCDATA ); while (NextTag( p, tag,attr, vPos,vSize, level,direction )) { // parse all attributes and put them into aList.clear(); while (!attr.empty()) { int apos= attr.find( "=\"" ); if (apos<0) { attr= ""; break; } a.name = attr.substr( 0,apos ); attr = attr.substr( apos+2 ); apos= attr.find( "\"" ); if (apos<0) { attr= ""; break; } a.value= attr.substr( 0,apos ); attr = attr.substr( apos+1 ); while (attr.find(" ")==0) attr= attr.substr( 1 ); aList.push_back( a ); } // while switch (direction) { case -1 : px= tagHierarchy.end(); // are we going up in the hierarchy ? if (px!=tagHierarchy.begin()) // if the list is not empty ... tagHierarchy.erase( --px ); // erase last element break; case 1 : tagHierarchy.push_back( tag ); // are we going down in the hierarchy ? if (level>1) break; docType= tag; vPos = docType.c_str(); vSize= docType.length(); tag = "DOCTYPE"; // assign the document type // go on for this special case default: // go thru the tag element list and get the matching element for (pos= fTypeCfgP->fTagMaps.begin(); pos!=fTypeCfgP->fTagMaps.end(); pos++) { if (strucmp( tag.c_str(),TCFG_CSTR((*pos)->fXmlTag) )==0) { fieldP= aItem.getField( (*pos)->fFid ); // this is the element we're looking for if (fieldP) { if (fieldP->isAssigned() && // -> allow multiple fields with the same name !fieldP->isArray()) continue; // it is assigned already ! // for embedded structures, the content shouldn't be copied // in all other cases, it can still be used as string if (!(*pos)->fEmbedded) value.assign( vPos,vSize ); // this is the value of this tag bool xAtt= !TCFG_ISEMPTY((*pos)->fXmlAttr); if (aList.size()==0) { if (xAtt) continue; // does not fit, both must be either empty } else { if (xAtt) { value= ""; for (ax= aList.begin(); ax!=aList.end(); ax++) { if (strucmp( (*ax).name.c_str(),TCFG_CSTR((*pos)->fXmlAttr) )==0) { value= (*ax).value.c_str(); break; // for attribute handling take as . } // if } // for if (value.empty()) continue; } // if } // if do { // there must be either no parent, or the parent must match if ( !TCFG_ISEMPTY((*pos)->fParent) && strucmp( TCFG_CSTR ((*pos)->fParent),tagHierarchy.back().c_str() )!=0) break; if (fieldP->isBasedOn( fty_blob )) { #ifdef STREAMFIELD_SUPPORT string enc= getAttr( aItem, TCFG_CSTR((*pos)->fXmlTag), "enc" ); if (enc.empty()) { // no encoding } else if (strucmp( enc.c_str(),"base64" )==0) { uInt32 oLen; uInt8* bb= b64::decode( value.c_str(), 0, &oLen ); fieldP->setAsString( (const char*)bb, oLen ); // assign the value b64::free ( bb ); break; // already done now (blob assigned correctly } else if (strucmp( enc.c_str(),"quoted-printable")==0) { string v; sysync::appendDecoded( value.c_str(),value.length(), v, enc_quoted_printable ); fieldP->setAsString( v.c_str(), v.size() ); // assign the value break; // already done now (blob assigned correctly } else { value = "unknown_encoding: \""; value+= enc; value+= "\""; } #endif } // if // we don't have a boolean type directly, so make a special conversion for it if ((*pos)->fBoolType) { // assuming the field list item is integer for boolean if (strucmp( value.c_str(),"0" )==0) break; // as defined in OMA DS 1.2 else if (strucmp( value.c_str(),"false" )==0) value= "-1"; // special boolean treatement else if (strucmp( value.c_str(),"true" )==0) value= "1"; } // if // delegate parsing of embedded object if ((*pos)->fEmbedded && fProfileHandlerP) { // set related datastore so handler can access session specific datastore state fProfileHandlerP->setRelatedDatastore(aDatastoreP); // vPos,vSize is not a copy, but a direct reference into bool ok= fProfileHandlerP->parseText(vPos,vSize, aItem); if (!ok) { // format error // aStatusCmd.setStatusCode(415); // Unsupported media type or format // ADDDEBUGITEM(aStatusCmd,"Error parsing Text content"); return false; } // if break; // already done (at profile handler) } // if // it's ok now to fill in if (fieldP->isArray()) fieldP->appendString( value.c_str() ); else fieldP->setAsString ( value.c_str() ); // assign the value } while (false); } // if if (aList.size()==0) break; } // if } // for } // switch } // while #ifdef SYDEBUG PDEBUGPRINTFX(DBG_PARSE,("Successfully parsed: ")); aItem.debugShowItem(DBG_DATA+DBG_PARSE); #endif return true; } // TDataObjType::parseData // generates SyncML-Devinf property list for type SmlDevInfCTDataPropListPtr_t TDataObjType::newCTDataPropList(TTypeVariantDescriptor aVariantDescriptor) { // no properties here return NULL; } // TDataObjType::newCTDataPropList // Filtering: add keywords and property names to filterCap void TDataObjType::addFilterCapPropsAndKeywords(SmlPcdataListPtr_t &aFilterKeywords, SmlPcdataListPtr_t &aFilterProps, TTypeVariantDescriptor aVariantDescriptor) { // add keywords from tagmaps #ifdef OBJECT_FILTERING TTagMapList::iterator pos; for(pos=fTypeCfgP->fTagMaps.begin();pos!=fTypeCfgP->fTagMaps.end();pos++) { // first priority: compare with explicit filterkeyword, if any if (!TCFG_ISEMPTY((*pos)->fFilterKeyword)) { // has a filterkeyword, show it addPCDataStringToList(TCFG_CSTR((*pos)->fFilterKeyword), &aFilterKeywords); } } // let embedded profile add the keywords if (fProfileHandlerP) { fProfileHandlerP->addFilterCapPropsAndKeywords(aFilterKeywords, aFilterProps, aVariantDescriptor, this); } // let base class add own keywords/props inherited::addFilterCapPropsAndKeywords(aFilterKeywords, aFilterProps, aVariantDescriptor); #endif } // TDataObjType::addFilterCapPropsAndKeywords // intended for creating SyncItemTypes for remote databases from // transmitted DevInf. // SyncItemType MUST NOT take ownership of devinf structure passed // (because multiple types might be created from a single CTCap entry) bool TDataObjType::analyzeCTCap(SmlDevInfCTCapPtr_t aCTCapP) { // just let parent handle return inherited::analyzeCTCap(aCTCapP); } // TDataObjType::analyzeCTCap /// @brief copy CTCap derived info from another SyncItemType /// @return false if item not compatible /// @note required to create remote type variants from ruleMatch type alternatives bool TDataObjType::copyCTCapInfoFrom(TSyncItemType &aSourceItem) { // just let parent handle return inherited::copyCTCapInfoFrom(aSourceItem); } // TDataObjType::copyCTCapInfoFrom } // namespace sysync /* end of TDataObjType implementation */ // eof libsynthesis-3.4.0.47.1/src/sysync/dataobjtype.h000077500000000000000000000141311226375725500214450ustar00rootroot00000000000000/* * File: DataObjType.h * * Author: Beat Forster (bfo@synthesis.ch) * * TDataObjType * base class for data object based items (EMAILOBJ, FILEOBJ, FOLDEROBJ) * implemented for OMA DS V1.2 * * Copyright (c) 2005-2011 by Synthesis AG + plan44.ch * * 2005-07-20 : bfo : created from TextItemType * */ #ifndef DataObjType_H #define DataObjType_H // includes #include "syncitemtype.h" #include "multifielditemtype.h" #include "textprofile.h" // for test //#define HARDCODED_TYPE_SUPPORT namespace sysync { // property definition class TTagMapDefinition : public TConfigElement { typedef TConfigElement inherited; public: // constructor/destructor TTagMapDefinition(TConfigElement *aParentElementP, sInt16 aFid); virtual ~TTagMapDefinition(); // properties // - tagged field TCFG_STRING fXmlTag; // - attribute field of tag TCFG_STRING fXmlAttr; // - specifies the field as boolean bool fBoolType; // - specifies an embedded profile (for RFC2822) bool fEmbedded; // - the expected parent tag (if not empty) TCFG_STRING fParent; // - field id sInt16 fFid; #ifdef OBJECT_FILTERING // - no filterkeyword TCFG_STRING fFilterKeyword; #endif #ifdef CONFIGURABLE_TYPE_SUPPORT // check config elements virtual bool localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine); #endif virtual void clear(); }; // TTagMapDefinition // tag mapping definitions typedef std::list TTagMapList; // Text based datatype class TDataObjConfig : public TMultiFieldTypeConfig { typedef TMultiFieldTypeConfig inherited; public: TDataObjConfig(const char *aElementName, TConfigElement *aParentElementP); virtual ~TDataObjConfig(); // properties // - Note, field list is parsed here, but is a property of TMultiFieldTypeConfig // - text-line based field definitions TTagMapList fTagMaps; // public functions // - create Sync Item Type of appropriate type from config virtual TSyncItemType *newSyncItemType(TSyncSession *aSessionP, TSyncDataStore *aDatastoreP); #ifdef HARDCODED_TYPE_SUPPORT TTagMapDefinition *addTagMap( sInt16 aFid, const char* aXmlTag, bool aBoolType, bool aEmbedded, const char* aParent ); #endif protected: #ifdef CONFIGURABLE_TYPE_SUPPORT // check config elements virtual bool localStartElement( const char *aElementName, const char **aAttributes, sInt32 aLine ); virtual void localResolve( bool aLastPass ); #endif virtual void clear(); }; // TDataObjConfig const uInt16 ity_dataobj= 200; // must be unique class TDataObjType: public TMultiFieldItemType { typedef TMultiFieldItemType inherited; public: // constructor TDataObjType( TSyncSession *aSessionP, TDataTypeConfig *aTypeCfgP, // type config const char *aCTType, const char *aVerCT, TSyncDataStore *aRelatedDatastoreP, TFieldListConfig *aFieldDefinitions // field definitions ); // destructor virtual ~TDataObjType(); // access to type virtual uInt16 getTypeID(void) const { return ity_dataobj; }; virtual bool isBasedOn(uInt16 aItemTypeID) const { return aItemTypeID==ity_dataobj ? true : TMultiFieldItemType::isBasedOn(aItemTypeID); }; // differentiation between implemented and just descriptive TSyncTypeItems virtual bool isImplemented(void) { return true; }; // MIME-DIR is an implementation // helper to create same-typed instance via base class // MUST BE IMPLEMENTED IN ALL DERIVED CLASSES! virtual TSyncItemType *newCopyForSameType( TSyncSession *aSessionP, // the session TSyncDataStore *aDatastoreP // the datastore ); /// @brief copy CTCap derived info from another SyncItemType virtual bool copyCTCapInfoFrom(TSyncItemType &aSourceItem); #ifdef OBJECT_FILTERING // filtering // - get field index of given filter expression identifier. virtual sInt16 getFilterIdentifierFieldIndex(const char *aIdentifier, uInt16 aIndex); #endif protected: // - analyze CTCap for specific type virtual bool analyzeCTCap(SmlDevInfCTCapPtr_t aCTCapP); // - obtain property list for type, returns NULL if none available virtual SmlDevInfCTDataPropListPtr_t newCTDataPropList(TTypeVariantDescriptor aVariantDescriptor); // - Filtering: add keywords and property names to filterCap virtual void addFilterCapPropsAndKeywords(SmlPcdataListPtr_t &aFilterKeywords, SmlPcdataListPtr_t &aFilterProps, TTypeVariantDescriptor aVariantDesc); // Item data management // - create new sync item of proper type and optimization for specified target virtual TSyncItem *internalNewSyncItem(TSyncItemType *aTargetItemTypeP, TLocalEngineDS *aLocalDatastoreP); // - fill in SyncML data (but leaves IDs empty) virtual bool internalFillInData( TSyncItem *aSyncItemP, // SyncItem to be filled with data SmlItemPtr_t aItemP, // SyncML toolkit item Data to be converted into SyncItem (may be NULL if no data, in case of Delete or Map) TLocalEngineDS *aLocalDatastoreP, // local datastore TStatusCommand &aStatusCmd // status command that might be modified in case of error ); // - sets data and meta from SyncItem data, but leaves source & target untouched virtual bool internalSetItemData( TSyncItem *aSyncItemP, // the syncitem to be represented as SyncML SmlItemPtr_t aItem, // item with NULL meta and NULL data TLocalEngineDS *aLocalDatastoreP // local datastore ); // get attribute of . If not available, return "" virtual string getAttr( TMultiFieldItem &aItem, const char* aXmlTag, const char* aXmlAttr ); // generate Data item (includes header and footer) virtual void generateData(TLocalEngineDS *aDatastoreP, TMultiFieldItem &aItem, string &aString); // parse Data item (includes header and footer) virtual bool parseData(const char *aText, stringSize aSize, TMultiFieldItem &aItem, TLocalEngineDS *aDatastoreP); private: // member fields TProfileHandler *fProfileHandlerP; TDataObjConfig *fTypeCfgP; // the text type config element }; // TDataObjType } // namespace sysync #endif // DataObjType_H // eof libsynthesis-3.4.0.47.1/src/sysync/debuglogger.cpp000077500000000000000000001721561226375725500217740ustar00rootroot00000000000000/* * File: debuglogger.cpp * * Author: Lukas Zeller (luz@plan44.ch) * * Global debug mechanisms * * Copyright (c) 2005-2011 by Synthesis AG + plan44.ch * * 2005-08-04 : luz : created * */ #include "prefix_file.h" #ifdef SYDEBUG #include "debuglogger.h" #ifdef MULTI_THREAD_SUPPORT #include "platform_thread.h" #endif #ifdef USE_DLT #include #endif namespace sysync { #ifdef USE_DLT static bool DbgDLTInitialized; static DltContext DbgProtoContext; static DltContext DbgSessionContext; static DltContext DbgAdminContext; static DltContext DbgDataContext; static DltContext DbgRemoteInfoContext; static DltContext DbgParseContext; static DltContext DbgGenerateContext; static DltContext DbgTranspContext; static DltContext DbgSyncMLTKContext; static DltContext DbgDefaultContext; #endif #ifndef HARDCODED_CONFIG // debug format modes cAppCharP const DbgOutFormatNames[numDbgOutFormats] = { "text", // plain text format (but can be indented) "xml", // XML format "html" // HTML format #ifdef USE_DLT // If DLT support is not enabled, then trying to uses it in a config // will lead to a generic parse error. Might be good enough, although // a dedicated error message about "DLT being disabled in this build" // would be nicer. , "dlt" // GENIVI Diagnostic Log and Trace #endif }; // HTML dynamic folding modes cAppCharP const DbgFoldingModeNames[numDbgFoldingModes] = { "none", // do not include dynamic folding into HTML logs "collapsed", // include folding - all collapsed by default "expanded", // include folding - all expanded by default "auto" // include folding - collapse/expand state predefined on a block-by-block basis }; cAppCharP const DbgSourceModeNames[numDbgSourceModes] = { "none", // do not include links into source code in HTML logs "hint", // no links, but info about what file/line number the message comes from "doxygen", // include link into doxygen prepared HTML version of source code "txmt", // include txmt:// link (understood by TextMate and BBEdit) into source code }; // debug flush modes cAppCharP const DbgFlushModeNames[numDbgFlushModes] = { "buffered", // no flush, keep open as long as possible, output buffered (fast, needed for network drives) "flush", // flush every debug message "openclose" // open and close debug channel separately for every message (as in 2.x engine) }; // debug subthread isolation modes cAppCharP const DbgSubthreadModeNames[numDbgSubthreadModes] = { "none", // do not handle output from subthread specially "suppress", // suppress output from subthreads "separate", // create separate output stream (=file) for each subthread "mix", // mix on a line by line basis "mixblocks" // buffer thread's output and mix block-wise it into main stream when appropriate }; #endif // file extentsions for debug format modes cAppCharP const DbgOutFormatExtensions[numDbgOutFormats] = { ".log", // plain text format (but can be indented) ".xml", // XML format ".html" // HTML format }; cAppCharP const DbgOutDefaultPrefixes[numDbgOutFormats] = { "*** Start of log", "\n" "", "\n" "SySync SyncML Engine " SYSYNC_FULL_VERSION_STRING " Log\n" "\n" "\n" "

Start of log - SySync SyncML Engine " SYSYNC_FULL_VERSION_STRING "

\n
    \n" }; cAppCharP const DbgOutDefaultSuffixes[numDbgOutFormats] = { "*** End of log", "", "

End of log

" }; cAppCharP FoldingPrefix = "\n" "
  • [-- collapse all --][++ expand all ++]
  • \n"; // externals #ifdef CONSOLEINFO // privately redefined here to avoid circular headers (would need syncappbase.h) extern "C" void ConsolePuts(const char *text); #endif // TDbgOptions implementation // -------------------------- TDbgOptions::TDbgOptions() { // set defaults clear(); } // TDbgOptions::TDbgOptions void TDbgOptions::clear(void) { fOutputFormat = dbgfmt_html; // most universally readable and convenient fIndentString = " "; // two spaces fCustomPrefix.erase(); // no custom prefix fCustomSuffix.erase(); // no custom suffix fSeparateMsgs = true; // separate text message lines ( in xml) fTimestampStructure = true; // timestamps in structure... fTimestampForAll = false; // ..but not for every line fThreadIDForAll = false; // not by default fFlushMode = dbgflush_none; // no special flush or openclose (fast, but might loose info on process abort) fFoldingMode = dbgfold_auto; // dynamic folding enabled, expanded/collapsed defaults automatically set on block-by-block basis #ifdef SYDEBUG_LOCATION fSourceLinkMode = dbgsource_none; // no links into source code fSourceRootPath = SYDEBUG_LOCATION; // use default path from build #endif fAppend = false; // default to overwrite existing logfiles fSubThreadMode = dbgsubthread_suppress; // simply suppress subthread info fSubThreadBufferMax = 1024*1024; // don't buffer more than one meg. } // TDbgOptions::clear // TDbgOut implementation // ---------------------- TDbgOut::TDbgOut() : fDestructed(false) { // init fIsOpen=false; } // TDbgOut::TDbgOut TDbgOut::~TDbgOut() { destruct(); } // TDbgOut::~TDbgOut void TDbgOut::destruct(void) { if (!fDestructed) doDestruct(); fDestructed=true; } // TDbgOut::destruct void TDbgOut::doDestruct(void) { // make sure files are closed closeDbg(); } // TDbgOut::doDestruct // TStdFileDbgOut implementation // ----------------------------- #ifndef NO_C_FILES TStdFileDbgOut::TStdFileDbgOut() { // init fFileName.erase(); fFile=NULL; mutex=newMutex(); } // TStdFileDbgOut::TStdFileDbgOut TStdFileDbgOut::~TStdFileDbgOut() { destruct(); freeMutex(mutex); } // TStdFileDbgOut::~TStdFileDbgOut // open standard C file based debug output channel bool TStdFileDbgOut::openDbg(cAppCharP aDbgOutputName, cAppCharP aSuggestedExtension, TDbgFlushModes aFlushMode, bool aOverWrite, bool aRawMode) { if (fIsOpen) { // first close closeDbg(); } // now apply new flush mode fFlushMode=aFlushMode; // save new file name fFileName=aDbgOutputName; // for C files, use the extension provided fFileName+=aSuggestedExtension; // open fFile=fopen(fFileName.c_str(),aRawMode ? (aOverWrite ? "wb" : "ab") : (aOverWrite ? "w" : "a")); // in case this fails, we'll have a NULL fFile. We can't do anything more here fIsOpen=fFile!=NULL; // For openclose mode, we have opened here only to check for logfile writability - close again if (fIsOpen && fFlushMode==dbgflush_openclose) { fclose(fFile); fFile=NULL; } // return false if we haven't been successful opening the channel return fIsOpen; } // TStdFileDbgOut::openDbg // return current size of debug file uInt32 TStdFileDbgOut::dbgFileSize(void) { if (!fIsOpen) return 0; // no file, no size uInt32 sz; if (fFlushMode==dbgflush_openclose) { // we need to open the file for append first fFile=fopen(fFileName.c_str(),"a"); fseek(fFile,0,SEEK_END); // move to end (needed, otherwise ftell may return 0 despite "a" fopen mode) sz=ftell(fFile); fclose(fFile); fFile=NULL; } else { fseek(fFile,0,SEEK_END); // move to end (needed, otherwise ftell may return 0 despite "a" fopen mode) sz=ftell(fFile); // return size } return sz; } // TStdFileDbgOut::dbgFileSize // close standard C file based debug channel void TStdFileDbgOut::closeDbg(void) { if (fIsOpen) { if (fFile) { fclose(fFile); fFile=NULL; } fIsOpen=false; } } // TStdFileDbgOut::closeDbg // write single line to standard file based output channel void TStdFileDbgOut::putLine(cAppCharP aLine, bool aForceFlush) { // if not open, just NOP if (fIsOpen) { if (fFlushMode==dbgflush_openclose) { // we need to open the file for append first lockMutex(mutex); fFile=fopen(fFileName.c_str(),"a"); if (!fFile) unlockMutex(mutex); } if (fFile) { // now output fputs(aLine,fFile); fputs("\n",fFile); // do required flushing if (fFlushMode==dbgflush_openclose) { // we need to close the file after every line of output fclose(fFile); fFile=NULL; unlockMutex(mutex); } else if (aForceFlush || fFlushMode==dbgflush_flush) { // simply flush fflush(fFile); } } } } // TStdFileDbgOut::putLine // write raw data to output file void TStdFileDbgOut::putRawData(cAppPointer aData, memSize aSize) { if (fIsOpen) { if (fFlushMode==dbgflush_openclose) { // we need to open the file for append first lockMutex(mutex); fFile=fopen(fFileName.c_str(),"a"); } if (fFile) { if (fwrite(aData, 1, aSize, fFile) != 1) { // error ignored } } // do required flushing if (fFlushMode==dbgflush_openclose) { // we need to close the file after every line of output fclose(fFile); fFile=NULL; unlockMutex(mutex); } else if (fFlushMode==dbgflush_flush) { // simply flush fflush(fFile); } } } // TStdFileDbgOut::putRawData #endif // TConsoleDbgOut implementation // ----------------------------- TConsoleDbgOut::TConsoleDbgOut() { // init } // TStdFileDbgOut::TStdFileDbgOut // open standard C file based debug output channel bool TConsoleDbgOut::openDbg(cAppCharP aDbgOutputName, cAppCharP aSuggestedExtension, TDbgFlushModes aFlushMode, bool aOverWrite, bool aRawMode) { if (fIsOpen) { // first close closeDbg(); } // raw mode is not supported if (!aRawMode) fIsOpen=true; // return false if we haven't been successful opening the channel return fIsOpen; } // TConsoleDbgOut::openDbg // close standard C file based debug channel void TConsoleDbgOut::closeDbg(void) { fIsOpen=false; } // TConsoleDbgOut::closeDbg // write single line to standard file based output channel void TConsoleDbgOut::putLine(cAppCharP aLine, bool aForceFlush) { // if not open, just NOP if (fIsOpen) { CONSOLEPUTS(aLine); } } // TConsoleDbgOut::putLine // TDebugLoggerBase implementation // ------------------------------- // constructor TDebugLoggerBase::TDebugLoggerBase(GZones *aGZonesP) : fGZonesP(aGZonesP) { fDebugMask=0; fDebugEnabled=true; // enabled by default fNextDebugMask=0; fDbgOutP=NULL; fDbgOptionsP=NULL; fIndent=0; fBlockHistory=NULL; // no Block open yet fOutStarted=false; // not yet started fBlockNo=0; fGZonesP=NULL; fOutputLoggerP=NULL; // no redirected output yet } // TDebugLoggerBase::TDebugLoggerBase // destructor TDebugLoggerBase::~TDebugLoggerBase() { // make sure debug is finalized DebugFinalizeOutput(); // make sure possibly left-over history elements are erased while (fBlockHistory) { TBlockLevel *bl=fBlockHistory; fBlockHistory=bl->fNext; delete bl; } // get rid of output object if (fDbgOutP) delete fDbgOutP; fDbgOutP=NULL; } // TDebugLoggerBase::TDebugLoggerBase // @brief convenience version for getting time lineartime_t TDebugLoggerBase::getSystemNowAs(timecontext_t aContext) { return sysync::getSystemNowAs(aContext,fGZonesP); } // TDebugLoggerBase::getSystemNowAs // install outputter void TDebugLoggerBase::installOutput(TDbgOut *aDbgOutP) { // get rid of possibly installed previous outputter if (fDbgOutP) delete fDbgOutP; fDbgOutP=aDbgOutP; } // TDebugLoggerBase::installOutput /// @brief link this logger to another logger and redirect output to that logger /// @param aDebugLoggerP[in] another logger, that must be alive as long as this logger is alive void TDebugLoggerBase::outputVia(TDebugLoggerBase *aDebugLoggerP) { // save logger and prefix fOutputLoggerP = aDebugLoggerP; } // TDebugLoggerBase::outputVia #if defined(CONSOLEINFO) && defined(CONSOLEINFO_LIBC) extern "C" { int (*SySync_ConsolePrintf)(FILE *stream, const char *format, ...) = fprintf; } #endif // output formatted text void TDebugLoggerBase::DebugVPrintf(TDBG_LOCATION_PROTO uInt32 aDbgMask, cAppCharP aFormat, va_list aArgs) { // we need a format and debug not completely off if ((getMask() & aDbgMask)==aDbgMask && aFormat) { const sInt16 maxmsglen=1024; char msg[maxmsglen]; msg[0]='\0'; // assemble the message string vsnprintf(msg, maxmsglen, aFormat, aArgs); // write the string DebugPuts(TDBG_LOCATION_ARG aDbgMask,msg); } } // TDebugLoggerBase::DebugVPrintf // helper needed for maintaining old DEBUGPRINTFX() macro syntax TDebugLoggerBase &TDebugLoggerBase::setNextMask(uInt32 aDbgMask) { fNextDebugMask=aDbgMask; return *this; } // TDebugLoggerBase::setNextMask // like DebugPrintf(), but using mask previously set by setNextMask() void TDebugLoggerBase::DebugPrintfLastMask(TDBG_LOCATION_PROTO cAppCharP aFormat, ...) { va_list args; // we need a format and debug not completely off if ((getMask() & fNextDebugMask)==fNextDebugMask && aFormat) { va_start(args, aFormat); DebugVPrintf(TDBG_LOCATION_ARG fNextDebugMask,aFormat,args); va_end(args); } fNextDebugMask=0; } // TDebugLoggerBase::DebugPrintfLastMask // output formatted text void TDebugLoggerBase::DebugPrintf(TDBG_LOCATION_PROTO uInt32 aDbgMask, cAppCharP aFormat, ...) { va_list args; // we need a format and debug not completely off if ((getMask() & aDbgMask)==aDbgMask && aFormat) { va_start(args, aFormat); DebugVPrintf(TDBG_LOCATION_ARG aDbgMask,aFormat,args); va_end(args); } } // TDebugLoggerBase::DebugVPrintf // open new Block without attribute list void TDebugLoggerBase::DebugOpenBlock(TDBG_LOCATION_PROTO cAppCharP aBlockName, cAppCharP aBlockTitle, bool aCollapsed) { // we need a format and debug not completely off if (getMask() && aBlockName) { #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wformat-security" #endif DebugOpenBlock(TDBG_LOCATION_ARG aBlockName,aBlockTitle,aCollapsed,NULL); #ifdef __clang__ #pragma clang diagnostic pop #endif } } // TDebugLoggerBase::DebugOpenBlock // open new Block with attribute list, printf style void TDebugLoggerBase::DebugOpenBlock(TDBG_LOCATION_PROTO cAppCharP aBlockName, cAppCharP aBlockTitle, bool aCollapsed, cAppCharP aBlockFmt, ...) { va_list args; // we need a format and debug not completely off if (getMask() && aBlockName) { va_start(args, aBlockFmt); DebugVOpenBlock(TDBG_LOCATION_ARG aBlockName,aBlockTitle,aCollapsed,aBlockFmt,args); va_end(args); } } // TDebugLoggerBase::DebugOpenBlock // open new Block with attribute list, printf style, expanded by default void TDebugLoggerBase::DebugOpenBlockExpanded(TDBG_LOCATION_PROTO cAppCharP aBlockName, cAppCharP aBlockTitle, cAppCharP aBlockFmt, ...) { va_list args; // we need a format and debug not completely off if (getMask() && aBlockName) { va_start(args, aBlockFmt); DebugVOpenBlock(TDBG_LOCATION_ARG aBlockName,aBlockTitle,false,aBlockFmt,args); va_end(args); } } // TDebugLoggerBase::DebugOpenBlockExpanded // open new Block with attribute list, printf style, collapsed by default void TDebugLoggerBase::DebugOpenBlockCollapsed(TDBG_LOCATION_PROTO cAppCharP aBlockName, cAppCharP aBlockTitle, cAppCharP aBlockFmt, ...) { va_list args; // we need a format and debug not completely off if (getMask() && aBlockName) { va_start(args, aBlockFmt); DebugVOpenBlock(TDBG_LOCATION_ARG aBlockName,aBlockTitle,true,aBlockFmt,args); va_end(args); } } // TDebugLoggerBase::DebugOpenBlockCollapsed #ifdef SYDEBUG_LOCATION #define MAKEDBGLINK(txt) dbg2Link(TDBG_LOCATION_ARG txt) /// turn text into link to source code string TDebugLoggerBase::dbg2Link(const TDbgLocation &aTDbgLoc, const string &aTxt) { if (!aTDbgLoc.fFile || !fDbgOptionsP || fDbgOptionsP->fSourceLinkMode==dbgsource_none || fDbgOptionsP->fOutputFormat!=dbgfmt_html) return aTxt; // disabled, non-html or no information to create source link // create link or hint to source code string line; switch(fDbgOptionsP->fSourceLinkMode) { case dbgsource_hint: { // only add name/line number/function as title hint (in a otherwise inactive link) line = "fSourceRootPath; line += "/"; string file = aTDbgLoc.fFile; size_t off = file.rfind('/'); if (off != file.npos) file = file.substr(off + 1); for (off = 0; off < file.size(); off++) { switch(file[off]) { case '_': line+="__"; break; case '.': line+="_8"; break; default: line+=file[off]; break; } } StringObjAppendPrintf(line,"-source.html#l%05d",aTDbgLoc.fLine); line+="\""; if (aTDbgLoc.fFunction) { line+=" title=\""; line+=aTDbgLoc.fFunction; line+="\""; } goto closelink; } case dbgsource_txmt: { // create txmt:// URL scheme link, which opens TextMate or BBEdit at the correct line in MacOS X line = "fSourceRootPath; path += aTDbgLoc.fFile; // - add path CGI encoded line += encodeForCGI(path.c_str()); // - add line number if (aTDbgLoc.fLine>0) StringObjAppendPrintf(line,"&line=%d",aTDbgLoc.fLine); line+="\""; if (aTDbgLoc.fFunction) { line+=" title=\""; line+=aTDbgLoc.fFunction; line+='"'; } } closelink: { line+=">"; line+=aTxt; line+=""; break; } default: line = aTxt; } // switch // return return line; } // TDebugLoggerBase::dbg2Link #else #define MAKEDBGLINK(txt) (txt) #endif // SYDEBUG_LOCATION #ifdef USE_DLT static void DbgText2PlainText(const char *in, size_t len, std::string &out) { const char *q=in; const char *s=q; const char *end=in + len; while (q=6 && strucmp(q,"&html;",6)==0) { if (q>s) out.append(s,q-s); // everything until next &html; must be filtered out // - search next &html; s=q=q+6; while(q+6<=end && strucmp(q,"&html;",6)!=0) q++; s=q=q+6; } else if (end-q>=4 && strucmp(q,"&sp;",4)==0) { if (q>s) out.append(s,q-s); s=q=q+4; out += ' '; // convert to plain space } else q++; } else { q++; } } if (q>s) out.append(s,q-s); } #endif // USE_DLT // output text to debug channel void TDebugLoggerBase::DebugPuts(TDBG_LOCATION_PROTO uInt32 aDbgMask, cAppCharP aText, stringSize aTextSize, bool aPreFormatted) { // we need a text and debug not completely off if (!((getMask() & aDbgMask)==aDbgMask && aText && fDbgOptionsP)) { // cannot output //#ifdef __MWERKS__ //#warning "ugly hack" DebugPutLine(TDBG_LOCATION_NONE "
  • Warning: Dbg output system already half shut down (limited formatting)!
  • "); if (aText) DebugPutLine(TDBG_LOCATION_NONE aText); DebugPutLine(TDBG_LOCATION_NONE "
  • "); //#endif } else { // make sure output is started if (!fOutStarted) { // try starting output DebugStartOutput(); // disable debugging in this logger if starting output failed // (prevents endless re-trying to open debug logs e.g. when log directory does not exist) if (!fOutStarted) { fDebugEnabled = false; return; // stop all efforts here } } #ifdef USE_DLT // DLT logging logs everything in one chunk if (fDbgOptionsP->fOutputFormat == dbgfmt_dlt) { DltContext *context = &DbgDefaultContext; if (aDbgMask & DBG_PROTO) { context = &DbgProtoContext; } else if (aDbgMask & DBG_SESSION) { context = &DbgSessionContext; } else if (aDbgMask & DBG_ADMIN) { context = &DbgAdminContext; } else if (aDbgMask & DBG_DATA) { context = &DbgDataContext; } else if (aDbgMask & DBG_REMOTEINFO) { context = &DbgRemoteInfoContext; } else if (aDbgMask & DBG_PARSE) { context = &DbgParseContext; } else if (aDbgMask & DBG_GEN) { context = &DbgGenerateContext; } else if (aDbgMask & DBG_TRANSP) { context = &DbgTranspContext; } else if (aDbgMask & (DBG_RTK_SML|DBG_RTK_XPT)) { context = &DbgSyncMLTKContext; } DltLogLevelType level = DLT_LOG_VERBOSE; if (level > DLT_LOG_INFO && (aDbgMask & DBG_HOT)) { level = DLT_LOG_INFO; } if (level > DLT_LOG_ERROR && (aDbgMask & DBG_ERROR)) { level = DLT_LOG_ERROR; } if (level > DLT_LOG_DEBUG && (aDbgMask & (DBG_USERDATA|DBG_PLUGIN|DBG_FILTER|DBG_CONFLICT))) { level = DLT_LOG_DEBUG; } if (level < DLT_LOG_VERBOSE && (aDbgMask & DBG_DETAILS)) { level = (DltLogLevelType)((int)level + 1); } if ((aTextSize > 0 && strlen(aText) > aTextSize) || strstr(aText, "&html;") || strstr(aText, "&sp;")) { // Must make a copy and potentially filter out html markup. string buffer; buffer.reserve(aTextSize); DbgText2PlainText(aText, aTextSize ? aTextSize : strlen(aText), buffer); DLT_LOG(*context, level, DLT_STRING(buffer.c_str())); } else { // Fast path: log directly. DLT_LOG(*context, level, DLT_STRING(aText)); } return; } #endif // USE_DLT // dissect into lines cAppCharP end=aTextSize ? aText+aTextSize : NULL; bool firstLine=true; // check for preformatted message bool pre=strnncmp(aText,"⪯",5)==0; if (pre) aText+=5; pre = pre || aPreFormatted; // now process text while ((!end || aTextfOutputFormat) { // HTML case dbgfmt_html: // prefix first line with
  • , second and further with
    if (firstLine) { line="
  • "; // add timestamp if needed for every line if ( fDbgOptionsP->fTimestampForAll || fDbgOptionsP->fThreadIDForAll #ifdef SYDEBUG_LOCATION || fDbgOptionsP->fSourceLinkMode!=dbgsource_none #endif ) { string prefix; prefix = "["; #ifdef MULTI_THREAD_SUPPORT if (fDbgOptionsP->fThreadIDForAll) { StringObjAppendPrintf(prefix,"%09lu",myThreadID()); if (fDbgOptionsP->fTimestampForAll) prefix += ", "; } #endif if (fDbgOptionsP->fTimestampForAll) { StringObjTimestamp(ts,getSystemNowAs(TCTX_SYSTEM)); prefix += ts; } #ifdef SYDEBUG_LOCATION else if (!fDbgOptionsP->fThreadIDForAll) { // neither threadID nor timestamp, but source requested -> put small text here prefix += "src"; } #endif prefix+="] "; // if we have links into source code, add it here line += MAKEDBGLINK(prefix); } // colorize some messages string cl=""; // colors, not mixable, most relevant first if (aDbgMask & DBG_ERROR) { cl="error"; } else if (aDbgMask & DBG_EXOTIC) { cl="exotic"; } else if (aDbgMask & DBG_SCRIPTS) { cl="script"; } else if (aDbgMask & DBG_PLUGIN) { cl="plugin"; } else if (aDbgMask & DBG_DBAPI) { cl="dbapi"; } else if (aDbgMask & DBG_CONFLICT) { cl="conflict"; } else if (aDbgMask & DBG_MATCH) { cl="match"; } else if (aDbgMask & DBG_REMOTEINFO) { cl="remote"; } else if (aDbgMask & DBG_PROTO) { cl="proto"; } else if (aDbgMask & DBG_FILTER) { cl="filter"; } else if (aDbgMask & DBG_PARSE) { cl="incoming"; } else if (aDbgMask & DBG_GEN) { cl="outgoing"; } else if (aDbgMask & DBG_REST) { cl="rest"; } // apply basic color style if (!cl.empty()) { line+=""; } // aditional style modifiers that can be combined with colors if (aDbgMask & DBG_HOT) { if (cl.empty()) line+=""; else line+=""; } // start preformatted if selected if (pre) line+="
    ";
              }
              else {
                if (!pre) line="
    "; } goto xmlize; // XML, just output and replace special chars as needed case dbgfmt_xml: if (firstLine) { #ifdef MULTI_THREAD_SUPPORT if (fDbgOptionsP->fThreadIDForAll) { line+=""; StringObjAppendPrintf(line,"%09lu",myThreadID()); line+=""; } #endif if (fDbgOptionsP->fTimestampForAll) { StringObjTimestamp(ts,getSystemNowAs(TCTX_SYSTEM)); line+=""; } DebugPutLine(TDBG_LOCATION_NONE line.c_str(),line.size()); line.erase(); } if (fDbgOptionsP->fSeparateMsgs) { line+=""; } xmlize: q=aText; s=q; while (qs) line.append(s,q-s); // flush stuff scanned so far // everything until next &html; does not need or want escaping, copy it as is // - search next &html; s=q=q+6; while(*q && strucmp(q,"&html;",6)!=0) q++; // - append everything between if we are in HTML mode if (fDbgOptionsP->fOutputFormat==dbgfmt_html && q>s) line.append(s,q-s); s=q=q+6; } else if (strucmp(q,"&sp;",4)==0) { if (q>s) line.append(s,q-s); // flush stuff scanned so far // non-breaking space in HTML, normal space otherwise if (fDbgOptionsP->fOutputFormat==dbgfmt_html) line += " "; else line += ' '; s=q=q+4; // skip &sp; } else { if (q>s) line.append(s,q-s); line+="&"; s=++q; } } else if (*q=='<') { if (q>s) line.append(s,q-s); line+="<"; s=++q; } else if (*q=='>') { if (q>s) line.append(s,q-s); line+=">"; s=++q; } else { q++; } } if (q>s) line.append(s,q-s); if (fDbgOptionsP->fSeparateMsgs && fDbgOptionsP->fOutputFormat==dbgfmt_xml) { line+=""; } break; // plain text default: case dbgfmt_text: q=aText; s=q; while (qs) line.append(s,q-s); // everything until next &html; must be filtered out // - search next &html; s=q=q+6; while(*q && strucmp(q,"&html;",6)!=0) q++; s=q=q+6; } else if (strucmp(q,"&sp;",4)==0) { if (q>s) line.append(s,q-s); s=q=q+4; line += ' '; // convert to plain space } else q++; } else { q++; } } if (q>s) line.append(s,q-s); break; } // switch text output firstLine=false; // skip the lineend, if any while (((!end || pfOutputFormat==dbgfmt_html && ((end && p>=end) || *p==0)) { // end preformatted if (pre) line+="
    "; // colors if (aDbgMask & ( DBG_ERROR | DBG_SCRIPTS | DBG_REST | DBG_EXOTIC | DBG_DBAPI | DBG_PLUGIN | DBG_PARSE | DBG_GEN | DBG_CONFLICT | DBG_MATCH | DBG_REMOTEINFO | DBG_PROTO | DBG_FILTER )) { line+="
    "; // end special style } // HOT modifier if (aDbgMask & ( DBG_HOT )) { line+="
    "; // end special style } line+="
  • "; // we need to close the list entry } DebugPutLine(TDBG_LOCATION_NONE line.c_str(),line.size(),pre); // next line, if any aText=p; } // loop until all text done } } // TDebugLoggerBase::DebugPuts // open new Block with attribute list, varargs passed void TDebugLoggerBase::DebugVOpenBlock(TDBG_LOCATION_PROTO cAppCharP aBlockName, cAppCharP aBlockTitle, bool aCollapsed, cAppCharP aBlockFmt, va_list aArgs) { if (!fDbgOptionsP) return; if (fDbgOptionsP->fFoldingMode==dbgfold_collapsed) aCollapsed=true; else if (fDbgOptionsP->fFoldingMode==dbgfold_expanded) aCollapsed=false; if (getMask() && aBlockName && fDbgOptionsP) { // make sure output is started if (!fOutStarted) DebugStartOutput(); // create Block line on current indent level string bl; string ts; // - preamble, possibly with timestamp bool withTime = fDbgOptionsP->fTimestampStructure; if (withTime) StringObjTimestamp(ts,getSystemNowAs(TCTX_SYSTEM)); switch (fDbgOptionsP->fOutputFormat) { // XML case dbgfmt_xml: bl="<"; bl+=aBlockName; if (withTime) { bl+=" time=\"" + ts + "\""; } if (aBlockTitle) { bl+=" title=\""; bl+=aBlockTitle; bl+="\""; } break; // HTML case dbgfmt_html: bl="
  • "; if (fDbgOptionsP->fFoldingMode!=dbgfold_none) { StringObjAppendPrintf(bl, "
    +
    ", long(getBlockNo()), aCollapsed ? "inline" : "none", long(getBlockNo()), long(getBlockNo()), aCollapsed ? "none" : "inline", long(getBlockNo()) ); } StringObjAppendPrintf(bl,"", long(getBlockNo())); if (withTime) { bl += MAKEDBGLINK(string("[") + ts + "] "); } #ifdef SYDEBUG_LOCATION else if (fDbgOptionsP->fSourceLinkMode!=dbgsource_none) { bl += MAKEDBGLINK(string("[src] ")); } #endif bl+="'"; bl+=aBlockName; bl+="'"; if (aBlockTitle) { bl+=" - "; bl+=aBlockTitle; } bl+="
    "; break; // plain text default: case dbgfmt_text: bl.erase(); if (!fDbgOptionsP->fTimestampForAll && withTime) { // avoid timestamp here if all lines get timestamped anyway bl+="[" + ts + "] "; } bl+=aBlockName; if (aBlockTitle) { bl+=" - "; bl+=aBlockTitle; } break; } // switch preamble // - attributes if (aBlockFmt) { // first expand all printf parameters string attrs; vStringObjPrintf(attrs,aBlockFmt,true,aArgs); // isolate |-separated attribute format strings cAppCharP q,r,s,p=attrs.c_str(); while (*p) { // search for beginning of value q=p; while(*q && *q!='=' && *q!='|') q++; // search for end of value r=q; s=q; // in case we don't have a = if (*q=='=') { s=q+1; r=s; while (*r && *r!='|') r++; } // now: p=start of attrname, q=end of attrname // s=start of value, r=end of value // output an attribute now if (q>p && r>s) { switch (fDbgOptionsP->fOutputFormat) { // XML case dbgfmt_xml: bl+=" "; bl.append(p,q-p); bl+="=\""; bl.append(s,r-s); bl+="\""; break; case dbgfmt_html: bl+=", "; bl.append(p,q-p); bl+="="; bl.append(s,r-s); bl+=""; break; case dbgfmt_text: default: bl+=", "; bl.append(p,q-p); bl+="="; bl.append(s,r-s); break; } // switch attribute } // non-empty attribute // more attributes to come? if (*r=='|') r++; // skip separator p=r; } // while } // attributes present // - finalize Block switch (fDbgOptionsP->fOutputFormat) { // XML case dbgfmt_xml: bl+=">"; break; // HTML case dbgfmt_html: bl+=""; // end span for attributes if (fDbgOptionsP->fFoldingMode!=dbgfold_none) { StringObjAppendPrintf(bl, " [--][++]", long(getBlockNo()), long(getBlockNo()) ); } // link to end of block StringObjAppendPrintf(bl," [->end]", long(getBlockNo())); // link to start of enclosing block (if any) if (fBlockHistory) { StringObjAppendPrintf(bl," [->enclosing]", long(fBlockHistory->fBlockNo)); } // start div for content folding if (fDbgOptionsP->fFoldingMode!=dbgfold_none) { StringObjAppendPrintf(bl, "
    ", long(getBlockNo()), aCollapsed ? "none" : "inline" ); } bl+="
      "; // now start list for block's contents break; // plain text default: case dbgfmt_text: break; } // switch preamble // now output Block line (on current indent level) DebugPutLine(TDBG_LOCATION_NONE bl.c_str(), bl.size()); // increase indent level (applies to all Block contents) fIndent++; // save Block on stack TBlockLevel *newLevel = new TBlockLevel; newLevel->fBlockName=aBlockName; newLevel->fNext=fBlockHistory; newLevel->fBlockNo=getBlockNo(); // save block number to reference block in collapse box at end of block nextBlock(); // increment block number fBlockHistory=newLevel; // insert new level at start of list } } // TDebugLoggerBase::DebugVOpenBlock // close named Block. If no name given, topmost Block will be closed void TDebugLoggerBase::DebugCloseBlock(TDBG_LOCATION_PROTO cAppCharP aBlockName) { if (fOutStarted && getMask() && fDbgOptionsP && fBlockHistory) { if (aBlockName==NULL) { #if SYDEBUG>1 internalCloseBlocks(TDBG_LOCATION_ARG fBlockHistory->fBlockName.c_str(),"Block Nest Warning: Missing Block name at close"); #else internalCloseBlocks(TDBG_LOCATION_ARG fBlockHistory->fBlockName.c_str(),NULL); #endif } else { internalCloseBlocks(TDBG_LOCATION_ARG aBlockName,NULL); } } } // TDebugLoggerBase::DebugCloseBlock // internal helper used to close all or some Blocks void TDebugLoggerBase::internalCloseBlocks(TDBG_LOCATION_PROTO cAppCharP aBlockName, cAppCharP aCloseComment) { if (!fDbgOptionsP) return; // security bool withTime = fDbgOptionsP->fTimestampStructure; string comment; #if SYDEBUG>1 if (!fBlockHistory && aBlockName) { // no blocks open any more and not close-all-remaining call (log close...) DebugPrintf(TDBG_LOCATION_ARG DBG_EXOTIC+DBG_ERROR,"Block Nest Warning: Trying to close block '%s', but no block is open",aBlockName); } #endif while (fBlockHistory) { // prepare comment comment.erase(); if (aCloseComment) { comment += " - "; comment += aCloseComment; } // check if closing top-of-stack Block now bool found= (aBlockName && strucmp(aBlockName,fBlockHistory->fBlockName.c_str())==0); if (!found && fBlockHistory->fNext==NULL) { // last Block always counts as "found"... found = true; #if SYDEBUG>1 // ...but issue warning as name is not what we would have expected StringObjAppendPrintf(comment, " - Block Nest Warning: closing '%s', but expected '%s'",aBlockName ? aBlockName : "", fBlockHistory->fBlockName.c_str()); #endif } // now close topmost Block string ts,bl; // - get time if needed and possibly put it within indented block if (withTime) { StringObjTimestamp(ts,getSystemNowAs(TCTX_SYSTEM)); // for XML, the time must be shown before the close tag on a separate line if (fDbgOptionsP->fOutputFormat == dbgfmt_xml) { StringObjPrintf(bl,"",ts.c_str()); DebugPutLine(TDBG_LOCATION_NONE bl.c_str(), bl.size()); // still within block, indented } } // - now unindent if (fIndent>0) fIndent--; // - then create closing Block #if SYDEBUG>1 if (!found) StringObjAppendPrintf(comment," - Block Nest Warning: implicitly closed (by explicitly closing '%s')",aBlockName ? aBlockName : ""); #endif switch (fDbgOptionsP->fOutputFormat) { // XML case dbgfmt_xml: bl="fBlockName; bl+=">"; if (!comment.empty()) { bl+=" "; } break; // HTML case dbgfmt_html: bl="
    "; // end of content list if (fDbgOptionsP->fFoldingMode!=dbgfold_none) { StringObjAppendPrintf(bl, "", long(fBlockHistory->fBlockNo) ); } StringObjAppendPrintf(bl,"",long(fBlockHistory->fBlockNo)); if (withTime) { bl += MAKEDBGLINK(string("[") + ts + "] "); } bl += "End of '"; bl+=fBlockHistory->fBlockName; bl+="'"; bl+=comment; bl+=""; // link to top of block StringObjAppendPrintf(bl," [->top]",long(fBlockHistory->fBlockNo)); // link to end of enclosing block (if any) if (fBlockHistory->fNext) { StringObjAppendPrintf(bl," [->enclosing]",long(fBlockHistory->fNext->fBlockNo)); } if (fDbgOptionsP->fFoldingMode!=dbgfold_none) { bl+="
    "; // end of folding division } bl+="
  • "; // end of list entry containing entire block break; // plain text default: case dbgfmt_text: bl.erase(); if (!fDbgOptionsP->fTimestampForAll && withTime) { // avoid timestamp here if all lines get timestamped anyway bl+="[" + ts + "] "; } bl+="End of '"; bl+=fBlockHistory->fBlockName; bl+="'"; bl+=comment; break; } // switch Block close // - output closing Block line DebugPutLine(TDBG_LOCATION_NONE bl.c_str(), bl.size()); // - remove Block level TBlockLevel *closedLevel = fBlockHistory; fBlockHistory = closedLevel->fNext; delete closedLevel; // if we have found the Block, exit here if (found) break; } } // TDebugLoggerBase::internalCloseBlocks #ifdef USE_DLT static void RegisterContext(DltContext *aHandle, const char *aContextID, const char *aDescription) { std::string envName = "LIBSYNTHESIS_"; envName += aContextID; const char *value = getenv(envName.c_str()); if (value) { // Explicit level. DltLogLevelType level = (DltLogLevelType)atoi(value); dlt_register_context_ll_ts(aHandle, aContextID, aDescription, level, DLT_TRACE_STATUS_OFF); } else { // Default level. dlt_register_context(aHandle, aContextID, aDescription); } } #endif // USE_DLT // start debugging output if needed and sets fOutStarted bool TDebugLoggerBase::DebugStartOutput(void) { if (!fOutStarted) { #ifdef USE_DLT if (fDbgOptionsP && fDbgOptionsP->fOutputFormat==dbgfmt_dlt) { // Register our logging contexts. if (!DbgDLTInitialized) { RegisterContext(&DbgProtoContext, "PROT", "SyncML protocol related information"); RegisterContext(&DbgSessionContext, "SESS", "session management related information"); RegisterContext(&DbgAdminContext, "ADMN", "verything that has to do with administrative data (anchors, targets, map table)"); RegisterContext(&DbgDataContext, "DATA", "Everything that has to do with handling user data (data objects). Actual user data will however be shown only if loglevel >= debug."); RegisterContext(&DbgRemoteInfoContext, "REMI", "This shows information delivered in the remote party's device information, such as manufacturer name, datatypes supported, fields supported etc."); RegisterContext(&DbgParseContext, "PARS", "This shows information related to parsing and processing incoming data from the remote party. Actual user data will however be shown only if loglevel >= debug."); RegisterContext(&DbgGenerateContext, "GEN", "This shows information related to generating outgoing data for the remote party. Actual user data will however be shown only if loglevel >= debug."); RegisterContext(&DbgTranspContext, "TRNS", "shows transport (http and TCP communication) related information"); RegisterContext(&DbgSyncMLTKContext, "SMLT", "messages generated by the SyncML Toolkit code"); RegisterContext(&DbgDefaultContext, "SYS", "any other libsynthesis debug log message that does not fit in any of the other contexts"); DbgDLTInitialized = true; } fOutStarted = true; } else #endif // USE_DLT if (fOutputLoggerP) { // using another logger, call it to start output fOutStarted = fOutputLoggerP->DebugStartOutput(); if (fOutStarted) { // start with indent level of parent logger fIndent = fOutputLoggerP->fIndent; // note: we'll use the parent logger's block number... fBlockNo = 0; // ...but init to something just in case } } else if (fDbgOptionsP && fDbgOutP && !fDbgPath.empty()) { // try to open the debug channel (force to openclose if we have multiple threads mixed in one file) if (fDbgOutP->openDbg( fDbgPath.c_str(), DbgOutFormatExtensions[fDbgOptionsP->fOutputFormat], fDbgOptionsP->fSubThreadMode==dbgsubthread_linemix ? dbgflush_openclose : fDbgOptionsP->fFlushMode, !fDbgOptionsP->fAppend )) { // make sure we don't recurse when we produce some output fOutStarted = true; fIndent = 0; // reset to make sure // create a block number that is unique in the file, even if we append multiple times. // We assume that a block consumes at least 256 bytes, so size_of_file/256 always gets // an unused block ID within that file // 256 is a safe assumption because the "fold" button alone are around 250 bytes fBlockNo = 1 + (fDbgOutP->dbgFileSize()/256); // now create required prefix DebugPutLine(TDBG_LOCATION_NONE fDbgOptionsP->fCustomPrefix.empty() ? DbgOutDefaultPrefixes[fDbgOptionsP->fOutputFormat] : fDbgOptionsP->fCustomPrefix.c_str()); // add folding javascript if needed if (fDbgOptionsP->fOutputFormat==dbgfmt_html && fDbgOptionsP->fFoldingMode!=dbgfold_none) { DebugPutLine(TDBG_LOCATION_NONE FoldingPrefix); } } // debug channel opened successfully } // use own debug channel } // environment ready to start output return fOutStarted; } // TDebugLoggerBase::DebugStartOutput // @brief finalize debugging output (close Blocks, close output channel) void TDebugLoggerBase::DebugFinalizeOutput(void) { if (fOutputLoggerP) { // just close my own blocks internalCloseBlocks(TDBG_LOCATION_NONE NULL,"closed because sub-log ends here"); } if (fOutStarted && fDbgOptionsP && fDbgOutP) { // close all left-open open Blocks internalCloseBlocks(TDBG_LOCATION_NONE NULL,"closed because log ends here"); // now finalize output // - special stuff before if (fDbgOptionsP->fOutputFormat == dbgfmt_xml) fIndent=0; // unindent to zero (document is not a real Block) // - then suffix DebugPutLine(TDBG_LOCATION_NONE fDbgOptionsP->fCustomSuffix.empty() ? DbgOutDefaultSuffixes[fDbgOptionsP->fOutputFormat] : fDbgOptionsP->fCustomSuffix.c_str()); // now close the debug channel fDbgOutP->closeDbg(); } // whatever happened, we are not started any more fOutStarted=false; } // TDebugLoggerBase::DebugFinalizeOutput // Output single line to debug channel (includes indenting and other prefixing, but no further formatting) void TDebugLoggerBase::DebugPutLine(TDBG_LOCATION_PROTO cAppCharP aText, stringSize aTextSize, bool aPre) { #ifdef USE_DLT if (fDbgOptionsP && fDbgOptionsP->fOutputFormat==dbgfmt_dlt) { // One example where this gets called is DebugVOpen/CloseBlock() // with lines prepared as if we are printing plain text. Use // a fairly neutral log level here. if (aText) { if (aTextSize > 0 && aTextSize < strlen(aText)) { string buffer(aText, aTextSize); DLT_LOG(DbgDefaultContext, DLT_LOG_INFO, DLT_STRING(buffer.c_str())); } else { DLT_LOG(DbgDefaultContext, DLT_LOG_INFO, DLT_STRING(aText)); } } return; } #endif // USE_DLT if (!aText || (!fDbgOutP && !fOutputLoggerP)) return; if (*aText) { // not an empty line string msg; msg.erase(); // prefix with timestamp if selected in text format if (fDbgOptionsP && fDbgOptionsP->fOutputFormat==dbgfmt_text && fDbgOptionsP->fTimestampForAll) { // prefix each line (before the indent!) with a timestamp string ts; StringObjTimestamp(ts,getSystemNowAs(TCTX_SYSTEM)); msg='['; msg+=ts; msg+="] "; } // Indent if selected if (fDbgOptionsP && !fDbgOptionsP->fIndentString.empty() && !(fDbgOptionsP->fOutputFormat==dbgfmt_html && aPre)) { // with indent for (uInt16 n=0; nfIndentString; } } // add message itself if (aTextSize) msg.append(aText,aTextSize); else msg.append(aText); // now output if (fOutputLoggerP) { // use parent's output fOutputLoggerP->fDbgOutP->putLine(msg.c_str(),false); // %%% no forceflush for now } else { // use my own output channel fDbgOutP->putLine(msg.c_str(),false); // %%% no forceflush for now } } } // TDebugLoggerBase::DebugPutLine // TDebugLogger implementation // --------------------------- // constructor TDebugLogger::TDebugLogger(GZones *aGZonesP) : inherited(aGZonesP) { #ifdef MULTI_THREAD_SUPPORT fMainThreadID=0; fSubThreadLogs=NULL; fSilentLoggerP=NULL; #endif } // TDebugLogger::TDebugLogger // destructor TDebugLogger::~TDebugLogger() { #ifdef MULTI_THREAD_SUPPORT // remove subthread loggers TSubThreadLog* subThreadP = fSubThreadLogs; fSubThreadLogs = NULL; while (subThreadP) { // delete logger if any if (subThreadP->fSubThreadLogger) { SYSYNC_TRY { delete subThreadP->fSubThreadLogger; } SYSYNC_CATCH(...) // nop SYSYNC_ENDCATCH } TSubThreadLog* delP = subThreadP; subThreadP = subThreadP->fNext; delete delP; } // if (fSilentLoggerP) { delete fSilentLoggerP; fSilentLoggerP = NULL; } #endif } // TDebugLogger::~TDebugLogger #ifdef MULTI_THREAD_SUPPORT void TDebugLogger::setOptions(const TDbgOptions *aDbgOptionsP) { TDebugLoggerBase::setOptions(aDbgOptionsP); TSubThreadLog* subThreadP = fSubThreadLogs; while (subThreadP) { if (subThreadP->fSubThreadLogger) { subThreadP->fSubThreadLogger->setOptions(aDbgOptionsP); } subThreadP = subThreadP->fNext; } } /// @brief find (and possibly delete) subthread record /// @param aAndRemove[in] if set, the subthread record will be removed in a thread safe way /// IF AND ONLY IF aThreadID is the calling thread (i.e. only own thread may be removed from the list)! /// Note that the caller must take care of deleting the subthread record TSubThreadLog *TDebugLogger::findSubThread(uInt32 aThreadID, bool aAndRemove) { TSubThreadLog* subThreadP = fSubThreadLogs; TSubThreadLog** subThreadLinkPP = &fSubThreadLogs; while (subThreadP) { if (subThreadP->fThreadID == aThreadID) { if (aAndRemove) { // bridge previous with next in one single assignment (i.e. thread safe) *subThreadLinkPP = subThreadP->fNext; } // return found record (note that it MUST BE DELETED by caller if no longer used) return subThreadP; } subThreadLinkPP = &subThreadP->fNext; subThreadP = *subThreadLinkPP; } return NULL; // none found } // TDebugLogger::findSubThread /// @brief find or create logger for subthread TDebugLoggerBase *TDebugLogger::getThreadLogger(bool aCreateNew) { if (!fDbgOptionsP || fDbgOptionsP->fSubThreadMode==dbgsubthread_none) return this; // no options, do not handle subthreads specially uIntArch threadID = myThreadID(); if (fDbgOptionsP->fSubThreadMode==dbgsubthread_linemix || threadID==fMainThreadID) { // In line mix and for mainthread - I am the logger for this thread! return this; } TSubThreadLog* subThreadP = findSubThread(threadID); if (subThreadP) { // we know this subthread, return its logger return subThreadP->fSubThreadLogger; // can be NULL if subthread logging is disabled } // unknown subthread if (fMainThreadID==0) { // no current mainthread, let subthread write to main log // Note: this makes sure log info possibly trailing the DebugThreadOutputDone() // also lands in the main log. This is not critical - the only thing that must be // ensured is that starting new threads is made only with DebugDefineMainThread set. return this; } // new subthread, create entry in list if (aCreateNew) { string s; // create new entry subThreadP = new TSubThreadLog; subThreadP->fThreadID=threadID; subThreadP->fNext=fSubThreadLogs; // link current list behind this new entry // create logger for the thread (or none) switch (fDbgOptionsP->fSubThreadMode) { case dbgsubthread_separate: // separate file for subthread output // - create new base logger subThreadP->fSubThreadLogger = new TDebugLoggerBase(fGZonesP); // - install output (copy) subThreadP->fSubThreadLogger->installOutput(fDbgOutP ? fDbgOutP->clone() : NULL); // - same options subThreadP->fSubThreadLogger->setOptions(getOptions()); // - inherit current mask/enable subThreadP->fSubThreadLogger->setMask(getMask()); subThreadP->fSubThreadLogger->setEnabled(fDebugEnabled); // - debug path is same as myself plus Thread ID subThreadP->fSubThreadLogger->setDebugPath(fDbgPath.c_str()); StringObjPrintf(s,"_%lu",(long unsigned)threadID); subThreadP->fSubThreadLogger->appendToDebugPath(s.c_str()); break; case dbgsubthread_suppress: default: // no output from subthreads subThreadP->fSubThreadLogger=NULL; // no logger break; } // now activate by linking it at top of list (this is thread safe) fSubThreadLogs = subThreadP; // return the logger return subThreadP->fSubThreadLogger; } return NULL; // no logger for this thread } // TDebugLogger::getThreadLogger // helper needed for maintaining old DEBUGPRINTFX() macro syntax TDebugLoggerBase &TDebugLogger::setNextMask(uInt32 aDbgMask) { TDebugLoggerBase *loggerP = getThreadLogger(); if (loggerP) { // return pointer to loggerbase whose DebugPrintfLastMask() must be called return loggerP->inherited::setNextMask(aDbgMask); } else { // we have no logger but still need to return something if (!fSilentLoggerP) { fSilentLoggerP = new TDebugLoggerBase(fGZonesP); fSilentLoggerP->setEnabled(false); } fSilentLoggerP->setNextMask(DBG_ERROR); // must set non-zero to make sure it is NOT output! return *fSilentLoggerP; } } // TDebugLoggerBase::setNextMask // output text to debug channel, with checking for subthreads void TDebugLogger::DebugPuts(TDBG_LOCATION_PROTO uInt32 aDbgMask, cAppCharP aText, stringSize aTextSize, bool aPreFormatted) { TDebugLoggerBase *loggerP = getThreadLogger(); if (loggerP) loggerP->inherited::DebugPuts(TDBG_LOCATION_ARG aDbgMask,aText,aTextSize,aPreFormatted); } // TDebugLogger::DebugPuts void TDebugLogger::DebugVPrintf(TDBG_LOCATION_PROTO uInt32 aDbgMask, cAppCharP aFormat, va_list aArgs) { TDebugLoggerBase *loggerP = getThreadLogger(); if (loggerP) loggerP->inherited::DebugVPrintf(TDBG_LOCATION_ARG aDbgMask,aFormat,aArgs); } // TDebugLogger::DebugVPrintf void TDebugLogger::DebugVOpenBlock(TDBG_LOCATION_PROTO cAppCharP aBlockName, cAppCharP aBlockTitle, bool aCollapsed, cAppCharP aBlockFmt, va_list aArgs) { TDebugLoggerBase *loggerP = getThreadLogger(); if (loggerP) loggerP->inherited::DebugVOpenBlock(TDBG_LOCATION_ARG aBlockName, aBlockTitle, aCollapsed, aBlockFmt, aArgs); } // TDebugLogger::DebugVOpenBlock void TDebugLogger:: DebugCloseBlock(TDBG_LOCATION_PROTO cAppCharP aBlockName) { TDebugLoggerBase *loggerP = getThreadLogger(); if (loggerP) loggerP->inherited::DebugCloseBlock(TDBG_LOCATION_ARG aBlockName); } // TDebugLogger::DebugCloseBlock #endif // output all buffered subthread's output in a special subthread Block in the main output void TDebugLogger::DebugShowSubThreadOutput(void) { #ifdef MULTI_THREAD_SUPPORT // nop as long mixed-block mode is not implemented #endif } // TDebugLogger::DebugShowSubThreadOutput // the calling thread signals that it is done with doing output for now. If the main // thread is doing this and we have bufferandmix mode, the next subthread will be allowed // to write into the output channel until a new main thread gains control via // DebugDefineMainThread(); void TDebugLogger::DebugThreadOutputDone(bool aRemoveIt) { #ifdef MULTI_THREAD_SUPPORT uIntArch threadID = myThreadID(); if (threadID==fMainThreadID) { // current main thread done fMainThreadID = 0; } // for session logs, subthreads are usually left in the list at this time (aRemoveIt==false) // (as they will get deleted with the session logger later anyway) if (aRemoveIt) { TSubThreadLog* tP = findSubThread(threadID,true); if (tP) { if (tP->fSubThreadLogger) { SYSYNC_TRY { delete tP->fSubThreadLogger; } SYSYNC_CATCH(...) // nop SYSYNC_ENDCATCH } delete tP; } } #endif } // TDebugLogger::DebugThreadOutputDone // Used to regain control as main thread (e.g. for the next request of a session which // possibly occurs from another thread). void TDebugLogger::DebugDefineMainThread(void) { #ifdef MULTI_THREAD_SUPPORT uIntArch threadID = myThreadID(); // if this is already the main thread, no op if (threadID == fMainThreadID) return; // nop, done // thread is not the current main thread // - search if it is a registered subthread TSubThreadLog *subThreadP = findSubThread(threadID); if (fMainThreadID==0) { // no main thread currently registered if (subThreadP!=NULL) { // this is not a new thread, but a known subthread, can't get main thread now return; // no further op } else { // this is not a known subthread, so it can become the main thread fMainThreadID = threadID; return; // done } } else { // cannot become main thread, will be treated as subthread if it generates output // - no op required } #endif } // TDebugLogger::DebugDefineMainThread } // namespace sysync #endif // SYDEBUG // eof libsynthesis-3.4.0.47.1/src/sysync/debuglogger.h000077500000000000000000000474221226375725500214360ustar00rootroot00000000000000/* * File: debuglogger.h * * Author: Lukas Zeller (luz@plan44.ch) * * Global debug mechanisms * * Copyright (c) 2005-2011 by Synthesis AG + plan44.ch * * 2005-08-04 : luz : created * */ #ifndef DEBUGLOGGER_H #define DEBUGLOGGER_H #ifdef SYDEBUG #include "generic_types.h" #include "platform_mutex.h" #include "platform_thread.h" #include "sysync.h" #include "sysync_noncopyable.h" namespace sysync { /// @brief Debug output formats typedef enum { dbgfmt_text, ///< plain text format (but can be indented) dbgfmt_xml, ///< XML format dbgfmt_html, ///< HTML format #ifdef USE_DLT dbgfmt_dlt, ///< GENIVI Diagnostic Log and Trace #endif numDbgOutFormats } TDbgOutFormats; /// @brief HTML dynamic folding typedef enum { dbgfold_none, ///< do not include dynamic folding into HTML logs dbgfold_collapsed, ///< include folding - all collapsed by default dbgfold_expanded, ///< include folding - all expanded by default dbgfold_auto, ///< include folding - collapse/expand state predefined on a block-by-block basis numDbgFoldingModes } TDbgFoldingModes; /// @brief Debug flush modes typedef enum { dbgflush_none, ///< no flush, keep open as long as possible dbgflush_flush, ///< flush every debug message dbgflush_openclose, ///< open and close debug channel separately for every message (as in 2.x engine) numDbgFlushModes } TDbgFlushModes; /// @brief Debug subthread logging modes typedef enum { dbgsubthread_none, ///< do not handle output from subthread specially dbgsubthread_suppress, ///< suppress output from subthreads dbgsubthread_separate, ///< create separate output stream (=file) for each subthread dbgsubthread_linemix, ///< mix output on a line by line basis (forcing output to slow openclose mode) dbgsubthread_bufferandmix, ///< buffer thread's output and mix it into main stream when appropriate numDbgSubthreadModes } TDbgSubthreadModes; /// @brief HTML linking into source code typedef enum { dbgsource_none, ///< do not include links into source code in HTML logs dbgsource_hint, ///< no links, but info about what file/line number the message comes from dbgsource_doxygen, ///< include link into doxygen prepared HTML version of source code dbgsource_txmt, ///< include txmt:// link (understood by TextMate and BBEdit) into source code numDbgSourceModes } TDbgSourceModes; #ifndef HARDCODED_CONFIG extern cAppCharP const DbgOutFormatNames[numDbgOutFormats]; extern cAppCharP const DbgFoldingModeNames[numDbgFoldingModes]; extern cAppCharP const DbgFlushModeNames[numDbgFlushModes]; extern cAppCharP const DbgSubthreadModeNames[numDbgSubthreadModes]; extern cAppCharP const DbgSourceModeNames[numDbgSourceModes]; #endif extern cAppCharP const DbgOutFormatExtensions[numDbgOutFormats]; /// @brief Debug options container class TDbgOptions { public: // constructor TDbgOptions(); // methods void clear(void); // properties TDbgOutFormats fOutputFormat; ///< format string fIndentString; ///< indent string string fCustomPrefix; ///< custom prefix (different xml header or html with different styles for example) string fCustomSuffix; ///< custom suffix (should match prefix) string fBasename; ///< the initial part of the log file name, can override the hard-coded TARGETID (empty if unset) bool fSeparateMsgs; ///< separate message lines (needed especially in XML to avoid unformatted PCDATA block) bool fTimestampStructure; ///< include timestamp for structure elements (blocks) bool fTimestampForAll; ///< include timestamp information for every message bool fThreadIDForAll; ///< include thread ID information for every message TDbgFlushModes fFlushMode; ///< how and when to flush TDbgFoldingModes fFoldingMode; ///< if and how to fold HTML output TDbgSourceModes fSourceLinkMode; ///< if and how to link with source code string fSourceRootPath; ///< defines root path for source links bool fAppend; ///< if set, existing debug files will not be overwritten, but appended to TDbgSubthreadModes fSubThreadMode; ///< how to handle debug messages from subthreads uInt32 fSubThreadBufferMax; ///< how much to buffer for subthread maximally }; // TDbgOptions /// @brief Debug output channel class TDbgOut : noncopyable { // construction/destruction private: bool fDestructed; // flag which will be set once destruct() has been called - by the outermost derivate's destructor public: TDbgOut(); virtual ~TDbgOut(); virtual void doDestruct(void); // will be called by destruct, derived must call inherited if they implement it void destruct(void); // to be called by ALL destructors of derivates. // methods /// @brief duplicate output channel virtual TDbgOut *clone(void) { return new TDbgOut; }; /// @brief open debug output channel /// Notes: /// - Autocloses current channel if already open /// - May not actually open the channel, but should test if channel is writable /// @return false if debug channel cannot be opened and written to /// @param aDbgOutputName[in] name (usually file name) of debug output channel /// @param aSuggestedExtension[in] file extension suggested (may not be used depending on channel type) /// @param aFlushMode[in] flush mode to be used on the channel /// @param aOverWrite[in] if true, debug output channel (=file) will be overwritten (otherwise: appended to) /// @param aRawMode[in] if true, debug output channel (=file) is opened in binary raw mode (for message dumps etc.) virtual bool openDbg(cAppCharP aDbgOutputName, cAppCharP aSuggestedExtension, TDbgFlushModes aFlushMode, bool aOverWrite, bool aRawMode=false) { return true; }; /// @brief get current size of output file /// @return number of bytes, 0 if file is empty or for non-files (like console) virtual uInt32 dbgFileSize(void) { return 0; }; /// @brief close and flush all log output virtual void closeDbg(void) { /* nop */ }; /// @brief write single line to debug output channel /// @param aLine[in] text for line to be written out (must not contain line ends) /// @param aForceFlush[in] if true, debug output will be flushed to permanent storage regardless of current flush mode virtual void putLine(cAppCharP aLine, bool aForceFlush) { /* nop */}; /// @brief write raw data to debug output channel (usually makes sense only when channel is opened in raw mode) /// @param aData[in] pointer to data to be written /// @param aSize[in] size in bytes of data block at aData to be written virtual void putRawData(cAppPointer aData, memSize aSize) { /* nop */}; protected: bool fIsOpen; }; // TDbgOut #ifndef NO_C_FILES /// @brief Standard file debug output channel class TStdFileDbgOut : public TDbgOut { typedef TDbgOut inherited; public: // constructor/destructor TStdFileDbgOut(); virtual ~TStdFileDbgOut(); // methods virtual TDbgOut *clone(void) { return new TStdFileDbgOut; }; virtual bool openDbg(cAppCharP aDbgOutputName, cAppCharP aSuggestedExtension, TDbgFlushModes aFlushMode, bool aOverWrite, bool aRawMode=false); virtual uInt32 dbgFileSize(void); virtual void closeDbg(void); virtual void putLine(cAppCharP aLine, bool aForceFlush); virtual void putRawData(cAppPointer aData, memSize aSize); private: TDbgFlushModes fFlushMode; string fFileName; FILE * fFile; MutexPtr_t mutex; }; // TStdFileDbgOut #endif /// @brief Output to console class TConsoleDbgOut : public TDbgOut { typedef TDbgOut inherited; public: // constructor/destructor TConsoleDbgOut(); // methods virtual TDbgOut *clone(void) { return new TConsoleDbgOut; }; virtual bool openDbg(cAppCharP aDbgOutputName, cAppCharP aSuggestedExtension, TDbgFlushModes aFlushMode, bool aOverWrite, bool aRawMode=false); virtual void closeDbg(void); virtual void putLine(cAppCharP aLine, bool aForceFlush); virtual void putRawData(cAppPointer aData, memSize aSize) { /* not supported on console, just NOP */ }; }; // TConsoleDbgOut // Debug logger class // ------------------ /// @brief hierachical block history typedef struct BlockLevel { string fBlockName; uInt32 fBlockNo; struct BlockLevel *fNext; } TBlockLevel; class TDebugLogger; class GZones; /// @brief Debug logger base class (without subthread handling) class TDebugLoggerBase : noncopyable { public: // constructor/destructor TDebugLoggerBase(GZones *aGZonesP); virtual ~TDebugLoggerBase(); // methods /// @brief install output channel handler object (and pass it's ownership!) /// @param aDbgOutP[in] output channel to be used for this logger (will be owned and finally destroyed by the logger) void installOutput(TDbgOut *aDbgOutP); /// @brief link this logger to another logger and redirect output to that logger /// @param aDebugLoggerP[in] another logger, that must be alive as long as this logger is alive void outputVia(TDebugLoggerBase *aDebugLoggerP); /// @brief check if an output channel is already established other than with default values bool outputEstablished(void) { return fOutStarted; }; /// @brief set debug options virtual void setOptions(const TDbgOptions *aDbgOptionsP) { fDbgOptionsP = aDbgOptionsP; }; /// @brief get debug options pointer const TDbgOptions *getOptions(void) { return fDbgOptionsP; }; // @brief convenience version for getting time lineartime_t getSystemNowAs(timecontext_t aContext); /// @brief get current debug mask for this logger. /// Note that setEnabled(false) will cause this to return 0 even if the mask itself is non-zero uInt32 getMask(void) { return fDebugEnabled ? fDebugMask : 0; }; uInt32 getRealMask(void) { return fDebugMask; }; /// @brief set new debug mask for this logger void setMask(uInt32 aDbgMask) { fDebugMask=aDbgMask; }; /// @brief enable or disable this logger (but leave dbgMask intact) void setEnabled(bool aEnabled) { fDebugEnabled=aEnabled; }; /// @brief set debug output path + filename (no extension, please) void setDebugPath(cAppCharP aPath) { fDbgPath = aPath; }; /// @brief append to debug output path + filename (no extension, please) void appendToDebugPath(cAppCharP aPathElement) { fDbgPath += aPathElement; }; /// @brief get debug output file path (w/o extension) cAppCharP getDebugPath(void) { return fOutputLoggerP ? fOutputLoggerP->getDebugPath() : fDbgPath.c_str(); }; /// @brief get debug output file name (w/o path or extension) cAppCharP getDebugFilename(void) { if (fOutputLoggerP) return fOutputLoggerP->getDebugFilename(); size_t n=fDbgPath.find_last_of("\\/:"); return fDbgPath.c_str()+(n!=string::npos ? n+1 : 0); }; /// @brief get debug output file extension cAppCharP getDebugExt(void) { return fOutputLoggerP ? fOutputLoggerP->getDebugExt() : fDbgOptionsP ? DbgOutFormatExtensions[fDbgOptionsP->fOutputFormat] : ""; }; // - normal output /// @brief Write text to debug output channel. /// Notes: /// - Line will be terminated by linefeed automatically (no need to include a linefeed for single line message) /// - \n chars can be used to separate multi-line output. Formatter will take care that /// all lines are equally indented/formatted/prefixed /// @param aDbgMask debug mask, bits set here must be set in the debuglogger's own mask in order to display the debug text /// @param aText[in] text to be written out /// @param aTextSize[in] if>0, this is the maximum number of chars to output from aText virtual void DebugPuts(TDBG_LOCATION_PROTO uInt32 aDbgMask, cAppCharP aText, stringSize aTextSize=0, bool aPreFormatted=false); /// @brief Write formatted text to debug output channel. /// @param aDbgMask debug mask, bits set here must be set in the debuglogger's own mask in order to display the debug text /// @param aFormat[in] format text in vprintf style to be written out /// @param aArgs[in] varargs in vprintf style virtual void DebugVPrintf(TDBG_LOCATION_PROTO uInt32 aDbgMask, cAppCharP aFormat, va_list aArgs); /// @brief Write formatted text to debug output channel. /// @param aDbgMask debug mask, bits set here must be set in the debuglogger's own mask in order to display the debug text /// @param aFormat[in] format text in printf style to be written out void DebugPrintf(TDBG_LOCATION_PROTO uInt32 aDbgMask, cAppCharP aFormat, ...) #ifdef __GNUC__ __attribute__((format(printf, TDBG_LOCATION_ARG_NUM + 3, TDBG_LOCATION_ARG_NUM + 4))) #endif ; /// @brief set debug mask to be used for next DebugPrintfLastMask() call /// @param aDbgMask debug mask, bits set here must be set in the debuglogger's own mask in order to display the debug text virtual TDebugLoggerBase &setNextMask(uInt32 aDbgMask); /// @brief like DebugPrintf(), but using mask previously set by setNextMask() /// @param aFormat[in] format text in printf style to be written out void DebugPrintfLastMask(TDBG_LOCATION_PROTO cAppCharP aFormat, ...) #ifdef __GNUC__ __attribute__((format(printf, TDBG_LOCATION_ARG_NUM + 2, TDBG_LOCATION_ARG_NUM + 3))) #endif ; // - Blocks /// @brief Open structure Block. Depending on the output format, this will generate indent, XML tags, HTML headers etc. /// @param aBlockName[in] Name of Block. Will be used e.g. for tag name in XML. Intention is to group similar entities with the same BlockName /// @param aBlockTitle[in] Title (descriptive text) of Block. /// @param aCollapsed[in] If set, and folding mode is auto, block will be initially collapsed when log is opened in browser. /// @param aBlockFmt[in] Format string for additional Block info. Should contain one or multiple tag=value pairs, separated by the pipe char |. /// This will be used to generate XML attributes or other identifiers. /// @param aArgs[in] varargs in vprintf style for aBlockFmt virtual void DebugVOpenBlock(TDBG_LOCATION_PROTO cAppCharP aBlockName, cAppCharP aBlockTitle, bool aCollapsed, cAppCharP aBlockFmt, va_list aArgs); /// @brief Open structure Block, printf style variant void DebugOpenBlock(TDBG_LOCATION_PROTO cAppCharP aBlockName, cAppCharP aBlockTitle, bool aCollapsed, cAppCharP aBlockFmt, ...) #ifdef __GNUC__ __attribute__((format(printf, TDBG_LOCATION_ARG_NUM + 5, TDBG_LOCATION_ARG_NUM + 6))) #endif ; void DebugOpenBlockExpanded(TDBG_LOCATION_PROTO cAppCharP aBlockName, cAppCharP aBlockTitle, cAppCharP aBlockFmt, ...) #ifdef __GNUC__ __attribute__((format(printf, TDBG_LOCATION_ARG_NUM + 4, TDBG_LOCATION_ARG_NUM + 5))) #endif ; void DebugOpenBlockCollapsed(TDBG_LOCATION_PROTO cAppCharP aBlockName, cAppCharP aBlockTitle, cAppCharP aBlockFmt, ...) #ifdef __GNUC__ __attribute__((format(printf, TDBG_LOCATION_ARG_NUM + 4, TDBG_LOCATION_ARG_NUM + 5))) #endif ; /// @brief Open structure Block, without any attributes virtual void DebugOpenBlock(TDBG_LOCATION_PROTO cAppCharP aBlockName, cAppCharP aBlockTitle=NULL, bool aCollapsed=false); /// @brief Close structure Block. Name is used to close possibly unclosed contained Blocks automatically. virtual void DebugCloseBlock(TDBG_LOCATION_PROTO cAppCharP aBlockName); protected: // helper methods /// @brief start debugging output if needed and sets fOutStarted bool DebugStartOutput(void); /// @brief Output single line to debug channel (includes indenting, but no other formatting) void DebugPutLine(TDBG_LOCATION_PROTO cAppCharP aText, stringSize aTextSize=0, bool aPre=false); /// @brief finalize debugging output void DebugFinalizeOutput(void); /// @brief get block number uInt32 getBlockNo(void) { return fOutputLoggerP ? fOutputLoggerP->getBlockNo() : fBlockNo; }; /// @brief increment block number void nextBlock(void) { if (fOutputLoggerP) fOutputLoggerP->nextBlock(); else fBlockNo++; }; /// @brief internal helper for closing debug Blocks /// @param aBlockName[in] Name of Block to close. All Blocks including the first with given name will be closed. If NULL, all Blocks will be closed. /// @param aCloseComment[in] Comment about closing Block. If NULL, no comment will be shown (unless implicit closes occur, which auto-creates a comment) void internalCloseBlocks(TDBG_LOCATION_PROTO cAppCharP aBlockName, cAppCharP aCloseComment); #ifdef SYDEBUG_LOCATION /// @brief turn text into link to source code string dbg2Link(const TDbgLocation &aTDbgLoc, const string &aTxt); #endif // SYDEBUG_LOCATION // Variables TDbgOut *fDbgOutP; // the debug output string fDbgPath; // the output path+filename (w/o extension) const TDbgOptions *fDbgOptionsP; // the debug options uInt32 fDebugMask; // the debug mask bool fDebugEnabled; // on-off-switch for debugging output uInt32 fNextDebugMask; // debug mask to be used for next DebugPrintfLastMask() uInt16 fIndent; // the current indent TBlockLevel *fBlockHistory; // the linked list of Block history entries bool fOutStarted; // set if output has started uInt32 fBlockNo; // block count for folding GZones *fGZonesP; // zones list for time conversions TDebugLoggerBase *fOutputLoggerP; // another logger to be used for output }; // TDebugLoggerBase #ifdef MULTI_THREAD_SUPPORT /// @brief Subthread log handling typedef struct SubThreadLog { uInt32 fThreadID; struct SubThreadLog *fNext; TDebugLoggerBase *fSubThreadLogger; } TSubThreadLog; #endif /// @brief Debug logger class class TDebugLogger : public TDebugLoggerBase { typedef TDebugLoggerBase inherited; public: // constructor/destructor TDebugLogger(GZones *aGZonesP); virtual ~TDebugLogger(); // methods #ifdef MULTI_THREAD_SUPPORT /// @brief set debug options in this logger and all sub thread loggers virtual void setOptions(const TDbgOptions *aDbgOptionsP); virtual void DebugPuts(TDBG_LOCATION_PROTO uInt32 aDbgMask, cAppCharP aText, stringSize aTextSize=0, bool aPreFormatted=false); virtual void DebugVPrintf(TDBG_LOCATION_PROTO uInt32 aDbgMask, cAppCharP aFormat, va_list aArgs); virtual void DebugVOpenBlock(TDBG_LOCATION_PROTO cAppCharP aBlockName, cAppCharP aBlockTitle, bool aCollapsed, cAppCharP aBlockFmt, va_list aArgs); virtual void DebugCloseBlock(TDBG_LOCATION_PROTO cAppCharP aBlockName); virtual TDebugLoggerBase &setNextMask(uInt32 aDbgMask); #endif // - thread debug output serializing /// @brief output all buffered subthread's output in a special subthread Block in the main output void DebugShowSubThreadOutput(void); /// @brief signals the calling thread that it is done with doing output for now. /// @param aRemoveIt[in] if set, do remove thread from the subthread logger list /// Notes: /// - If the main thread is doing this and we have bufferandmix mode, the next subthread will be allowed /// to write into the output channel until a new main thread gains control via DebugDefineMainThread(); void DebugThreadOutputDone(bool aRemoveIt=false); /// @brief Define the current calling thread as the main debug thread /// Note: This is used for example when starting to process the next request of a session which possibly // occurs from another thread). void DebugDefineMainThread(void); private: #ifdef MULTI_THREAD_SUPPORT // helpers /// @brief find (and possibly delete) subthread record /// @param aAndRemove[in] if set, the subthread record will be removed in a thread safe way /// IF AND ONLY IF aThreadID is the calling thread (i.e. only own thread may be removed from the list)! /// Note that the caller must take care of deleting the subthread record TSubThreadLog *findSubThread(uInt32 aThreadID, bool aAndRemove=false); /// @brief find or create logger for subthread TDebugLoggerBase *getThreadLogger(bool aCreateNew=true); // Variables uIntArch fMainThreadID; TSubThreadLog *fSubThreadLogs; // the linked list of active subthreads TDebugLoggerBase *fSilentLoggerP; // a silent (inactive) logger required for suppressed subthreads #endif }; // TDebugLogger } // namespace sysync #endif // SYDEBUG #endif // DEBUGLOGGER_H // eof libsynthesis-3.4.0.47.1/src/sysync/engineentry.cpp000077500000000000000000000353411226375725500220270ustar00rootroot00000000000000/** * @File enginementry.cpp * * @Author Beat Forster (bfo@synthesis.ch) * * @brief TEngineModuleBase * engine bus bar class * * Copyright (c) 2007-2011 by Synthesis AG + plan44.ch * */ /* */ #include "prefix_file.h" #include "SDK_util.h" #include "engineentry.h" #include "enginemodulebase.h" namespace sysync { // Get object reference static DB_Callback DBC ( void* aCB ) { return (DB_Callback) aCB; } static TEngineModuleBase* URef( void* aCB ) { return (TEngineModuleBase*)DBC( aCB )->thisBase; } static TunnelWrapper* TW ( CContext aContext ) { return (TunnelWrapper*)aContext; } static TEngineModuleBase* TRef( CContext aContext ) { return URef( TW( aContext )->tCB ); } static SessionH TCon( CContext aContext ) { return TW( aContext )->tContext; } // --- Callback entries -------------------------- void DebugDB ( void* aCB, cAppCharP aParams ) { DBC( aCB )->DB_DebugPuts ( aCB, aParams ); } // DebugDB void DebugExotic ( void* aCB, cAppCharP aParams ) { DBC( aCB )->DB_DebugExotic ( aCB, aParams ); } // DebugExotic void DebugBlock ( void* aCB, cAppCharP aTag, cAppCharP aDesc, cAppCharP aAttrText ) { DBC( aCB )->DB_DebugBlock ( aCB, aTag, aDesc, aAttrText ); } // DebugBlock void DebugEndBlock ( void* aCB, cAppCharP aTag ) { DBC( aCB )->DB_DebugEndBlock ( aCB, aTag ); } // DebugEndBlock void DebugEndThread ( void* aCB ) { DBC( aCB )->DB_DebugEndThread( aCB ); } // DebugEndThread // ---------------------------------------------------------------------------------------- TSyError SetStringMode ( void* aCB, uInt16 aCharSet, uInt16 aLineEndMode, bool aBigEndian ) { return URef( aCB )->SetStringMode ( aCharSet, aLineEndMode, aBigEndian ); } // SetStringMode TSyError InitEngineXML ( void* aCB, cAppCharP aConfigXML ) { return URef( aCB )->InitEngineXML ( aConfigXML ); } // InitEngineXML TSyError InitEngineFile( void* aCB, cAppCharP aConfigFilePath ) { return URef( aCB )->InitEngineFile ( aConfigFilePath ); } // InitEngineFile TSyError InitEngineCB ( void* aCB, TXMLConfigReadFunc aReaderFunc, void* aContext ) { return URef( aCB )->InitEngineCB ( aReaderFunc, aContext ); } // InitEngineCB // ---------------------------------------------------------------------------------------- TSyError OpenSession( void* aCB, SessionH *aSessionH, uInt32 aSelector, cAppCharP aSessionName ) { return URef( aCB )->OpenSession( *aSessionH, aSelector, aSessionName ); } // OpenSession TSyError OpenSessionKey( void* aCB, SessionH aSessionH, KeyH *aKeyH, uInt16 aMode ) { return URef( aCB )->OpenSessionKey ( aSessionH, *aKeyH, aMode ); } // OpenSessionKey TSyError SessionStep( void* aCB, SessionH aSessionH, uInt16 *aStepCmd, TEngineProgressInfo *aInfoP ) { return URef( aCB )->SessionStep ( aSessionH, *aStepCmd, aInfoP ); } // SessionStep TSyError GetSyncMLBuffer( void* aCB, SessionH aSessionH, bool aForSend, appPointer *aBuffer, memSize *aBufSize ) { return URef( aCB )->GetSyncMLBuffer ( aSessionH, aForSend, *aBuffer, *aBufSize ); } // GetSyncMLBuffer TSyError RetSyncMLBuffer( void* aCB, SessionH aSessionH, bool aForSend, memSize aRetSize ) { return URef( aCB )->RetSyncMLBuffer ( aSessionH, aForSend, aRetSize ); } // RetSyncMLBuffer TSyError ReadSyncMLBuffer ( void* aCB, SessionH aSessionH, appPointer aBuffer, memSize aBufSize, memSize *aValSize ) { return URef( aCB )->ReadSyncMLBuffer ( aSessionH, aBuffer, aBufSize, *aValSize ); } // ReadSyncMLBuffer TSyError WriteSyncMLBuffer( void* aCB, SessionH aSessionH, appPointer aBuffer, memSize aValSize ) { return URef( aCB )->WriteSyncMLBuffer ( aSessionH, aBuffer, aValSize ); } // WriteSyncMLBuffer TSyError CloseSession( void* aCB, SessionH aSessionH ) { return URef( aCB )->CloseSession ( aSessionH ); } // CloseSession // ---------------------------------------------------------------------------------------- TSyError OpenKeyByPath( void* aCB, KeyH *aKeyH, KeyH aParentKeyH, cAppCharP aPath, uInt16 aMode ) { return URef( aCB )->OpenKeyByPath ( *aKeyH, aParentKeyH, aPath, aMode ); } // OpenKeyByPath TSyError OpenSubkey ( void* aCB, KeyH *aKeyH, KeyH aParentKeyH, sInt32 aID, uInt16 aMode ) { return URef( aCB )->OpenSubkey ( *aKeyH, aParentKeyH, aID, aMode ); } // OpenSubkey TSyError DeleteSubkey( void* aCB, KeyH aParentKeyH, sInt32 aID ) { return URef( aCB )->DeleteSubkey ( aParentKeyH, aID ); } // DeleteSubkey TSyError GetKeyID( void* aCB, KeyH aKeyH, sInt32 *aID ) { return URef( aCB )->GetKeyID ( aKeyH, *aID ); } // GetKeyID TSyError SetTextMode( void* aCB, KeyH aKeyH, uInt16 aCharSet, uInt16 aLineEndMode, bool aBigEndian ) { return URef( aCB )->SetTextMode ( aKeyH, aCharSet, aLineEndMode, aBigEndian ); } // SetTextMode TSyError SetTimeMode( void* aCB, KeyH aKeyH, uInt16 aTimeMode ) { return URef( aCB )->SetTimeMode ( aKeyH, aTimeMode ); } // SetTimeMode TSyError CloseKey( void* aCB, KeyH aKeyH ) { return URef( aCB )->CloseKey ( aKeyH ); } // CloseKey // ---------------------------------------------------------------------------------------- TSyError GetValue ( void* aCB, KeyH aKeyH, cAppCharP aValName, uInt16 aValType, appPointer aBuffer, memSize aBufSize, memSize *aValSize ) { return URef( aCB )->GetValue( aKeyH, aValName, aValType, aBuffer, aBufSize,*aValSize ); } // GetValue TSyError GetValueByID( void* aCB, KeyH aKeyH, sInt32 aID, sInt32 arrIndex, uInt16 aValType, appPointer aBuffer, memSize aBufSize, memSize *aValSize ) { return URef( aCB )->GetValueByID( aKeyH, aID, arrIndex, aValType, aBuffer, aBufSize, *aValSize ); } // GetValueByID sInt32 GetValueID ( void* aCB, KeyH aKeyH, cAppCharP aName ) { return URef( aCB )->GetValueID ( aKeyH, aName ); } // GetValueID TSyError SetValue ( void* aCB, KeyH aKeyH, cAppCharP aValName, uInt16 aValType, cAppPointer aBuffer, memSize aValSize ) { return URef( aCB )->SetValue ( aKeyH, aValName, aValType, aBuffer, aValSize ); } // SetValue TSyError SetValueByID( void* aCB, KeyH aKeyH, sInt32 aID, sInt32 arrIndex, uInt16 aValType, cAppPointer aBuffer, memSize aValSize ) { return URef( aCB )->SetValueByID( aKeyH, aID, arrIndex, aValType, aBuffer, aValSize ); } // SetValueByID // ---------------------------------------------------------------------------------------- TSyError StartDataRead ( CContext ac, cAppCharP lastToken, cAppCharP resumeToken ) { return TRef( ac )->StartDataRead ( TCon( ac ), lastToken, resumeToken ); } // StartDataRead TSyError ReadNextItem ( CContext ac, ItemID aID, appCharP *aItemData, sInt32 *aStatus, bool aFirst ) { return TRef( ac )->ReadNextItem ( TCon( ac ), aID, aItemData, aStatus, aFirst ); } // ReadNextItem TSyError ReadItem ( CContext ac, cItemID aID, appCharP *aItemData ) { return TRef( ac )->ReadItem ( TCon( ac ), aID, aItemData ); } // ReadItem TSyError EndDataRead ( CContext ac ) { return TRef( ac )->EndDataRead ( TCon( ac ) ); } // EndDataRead TSyError StartDataWrite ( CContext ac ) { return TRef( ac )->StartDataWrite ( TCon( ac ) ); } // StartDataWrite TSyError InsertItem ( CContext ac, cAppCharP aItemData, ItemID aID ) { return TRef( ac )->InsertItem ( TCon( ac ), aItemData, aID ); } // InsertItem TSyError UpdateItem ( CContext ac, cAppCharP aItemData, cItemID aID, ItemID updID ) { return TRef( ac )->UpdateItem ( TCon( ac ), aItemData, aID, updID ); } // UpdateItem TSyError MoveItem ( CContext ac, cItemID aID, cAppCharP newParID ) { return TRef( ac )->MoveItem ( TCon( ac ), aID, newParID ); } // MoveItem TSyError DeleteItem ( CContext ac, cItemID aID ) { return TRef( ac )->DeleteItem ( TCon( ac ), aID ); } // DeleteItem TSyError EndDataWrite ( CContext ac, bool success, appCharP *newToken ) { return TRef( ac )->EndDataWrite ( TCon( ac ), success, newToken ); } // EndDataWrite void DisposeObj ( CContext ac, void* memory ) { TRef( ac )->DisposeObj ( TCon( ac ), memory ); } // DisposeObj // ---- asKey functions ---- TSyError ReadNextItemAsKey( CContext ac, ItemID aID, KeyH aItemKey, sInt32 *aStatus, bool aFirst ) { return TRef( ac )->ReadNextItemAsKey( TCon( ac ), aID, aItemKey, aStatus, aFirst ); } // ReadNextItemAsKey TSyError ReadItemAsKey ( CContext ac, cItemID aID, KeyH aItemKey ) { return TRef( ac )->ReadItemAsKey ( TCon( ac ), aID, aItemKey ); } // ReadItemAsKey TSyError InsertItemAsKey ( CContext ac, KeyH aItemKey, ItemID aID ) { return TRef( ac )->InsertItemAsKey ( TCon( ac ), aItemKey, aID ); } // InsertItemAsKey TSyError UpdateItemAsKey ( CContext ac, KeyH aItemKey, cItemID aID, ItemID updID ) { return TRef( ac )->UpdateItemAsKey ( TCon( ac ), aItemKey, aID, updID ); } // UpdateItemAsKey // ---------------------------------------------------------------------------------------- // connect generic key access routines void CB_Connect_KeyAccess( void* aCB ) { DB_Callback cb= (DB_Callback)aCB; if (!CB_OK( cb,8 )) return; // minimum callback version required // calls used by both DBApi and UIApi cb->ui.OpenKeyByPath = OpenKeyByPath; cb->ui.OpenSubkey = OpenSubkey; cb->ui.DeleteSubkey = DeleteSubkey; cb->ui.GetKeyID = GetKeyID; cb->ui.SetTextMode = SetTextMode; cb->ui.SetTimeMode = SetTimeMode; cb->ui.CloseKey = CloseKey; cb->ui.GetValue = GetValue; cb->ui.GetValueByID = GetValueByID; cb->ui.GetValueID = GetValueID; cb->ui.SetValue = SetValue; cb->ui.SetValueByID = SetValueByID; } // CB_Connect_KeyAccess static void CB_Connect_Tunnel( void* aCB ) { DB_Callback cb= (DB_Callback)aCB; if (!CB_OK( cb, 9 )) return; // minimum callback version required cb->dt.StartDataRead = StartDataRead; cb->dt.ReadNextItem = ReadNextItem; cb->dt.ReadItem = ReadItem; cb->dt.EndDataRead = EndDataRead; cb->dt.StartDataWrite = StartDataWrite; cb->dt.InsertItem = InsertItem; cb->dt.UpdateItem = UpdateItem; cb->dt.MoveItem = MoveItem; cb->dt.DeleteItem = DeleteItem; cb->dt.EndDataWrite = EndDataWrite; if (!CB_OK( cb,11 )) return; // minimum callback version required cb->dt.DisposeObj = DisposeObj; cb->dt.ReadNextItemAsKey= ReadNextItemAsKey; cb->dt.ReadItemAsKey = ReadItemAsKey; cb->dt.InsertItemAsKey = InsertItemAsKey; cb->dt.UpdateItemAsKey = UpdateItemAsKey; } // CB_Connect_Tunnel void CB_Connect( void* aCB ) { DB_Callback cb= (DB_Callback)aCB; if (!CB_OK( cb,8 )) return; // minimum callback version required // calls needed for accessing engine from the outside (UIApi) cb->ui.SetStringMode = SetStringMode; cb->ui.InitEngineXML = InitEngineXML; cb->ui.InitEngineFile = InitEngineFile; cb->ui.InitEngineCB = InitEngineCB; cb->ui.OpenSession = OpenSession; cb->ui.OpenSessionKey = OpenSessionKey; cb->ui.SessionStep = SessionStep; cb->ui.GetSyncMLBuffer = GetSyncMLBuffer; cb->ui.RetSyncMLBuffer = RetSyncMLBuffer; cb->ui.ReadSyncMLBuffer = ReadSyncMLBuffer; cb->ui.WriteSyncMLBuffer= WriteSyncMLBuffer; cb->ui.CloseSession = CloseSession; // generic key access calls used by both DBApi and UIApi CB_Connect_KeyAccess( cb ); CB_Connect_Tunnel ( cb ); } // CB_Connect void SySyncDebugPuts(void* aCB, cAppCharP aFile, int aLine, cAppCharP aFunction, int aDbgLevel, cAppCharP aLinePrefix, cAppCharP aText) { URef( aCB )->debugPuts(aFile, aLine, aFunction, aDbgLevel, aLinePrefix, aText); } } // namespace sysync // eof libsynthesis-3.4.0.47.1/src/sysync/engineentry.h000077500000000000000000000170311226375725500214700ustar00rootroot00000000000000/** * @File engineentry.h * * @Author Beat Forster (bfo@synthesis.ch) * * Copyright (c) 2007-2011 by Synthesis AG + plan44.ch * */ /* */ #ifndef ENGINEENTRY_H #define ENGINEENTRY_H #include "generic_types.h" #include "sync_dbapidef.h" // we need STL strings #include using namespace std; namespace sysync { ENGINE_ENTRY_CXX void DebugDB ( void* aCB, cAppCharP aParams ) ENTRY_ATTR; ENGINE_ENTRY_CXX void DebugExotic ( void* aCB, cAppCharP aParams ) ENTRY_ATTR; ENGINE_ENTRY_CXX void DebugBlock ( void* aCB, cAppCharP aTag, cAppCharP aDesc, cAppCharP aAttrText ) ENTRY_ATTR; ENGINE_ENTRY_CXX void DebugEndBlock ( void* aCB, cAppCharP aTag ) ENTRY_ATTR; ENGINE_ENTRY_CXX void DebugEndThread ( void* aCB ) ENTRY_ATTR; // ---------------------------------------------------------------------------------------- ENGINE_ENTRY_CXX TSyError SetStringMode ( void* aCB, uInt16 aCharSet, uInt16 aLineEndMode, bool aBigEndian ) ENTRY_ATTR; ENGINE_ENTRY_CXX TSyError InitEngineXML ( void* aCB, cAppCharP aConfigXML ) ENTRY_ATTR; ENGINE_ENTRY_CXX TSyError InitEngineFile ( void* aCB, cAppCharP aConfigFilePath ) ENTRY_ATTR; ENGINE_ENTRY_CXX TSyError InitEngineCB ( void* aCB, TXMLConfigReadFunc aReaderFunc, void* aContext ) ENTRY_ATTR; ENGINE_ENTRY_CXX TSyError OpenSession ( void* aCB, SessionH *aSessionH, uInt32 aSelector, cAppCharP aSessionName ) ENTRY_ATTR; ENGINE_ENTRY_CXX TSyError OpenSessionKey ( void* aCB, SessionH aSessionH, KeyH *aKeyH, uInt16 aMode ) ENTRY_ATTR; ENGINE_ENTRY_CXX TSyError SessionStep ( void* aCB, SessionH aSessionH, uInt16 *aStepCmd, TEngineProgressInfo *aInfoP ) ENTRY_ATTR; ENGINE_ENTRY_CXX TSyError GetSyncMLBuffer ( void* aCB, SessionH aSessionH, bool aForSend, appPointer *aBuffer, memSize *aBufSize ) ENTRY_ATTR; ENGINE_ENTRY_CXX TSyError RetSyncMLBuffer ( void* aCB, SessionH aSessionH, bool aForSend, memSize aRetSize ) ENTRY_ATTR; ENGINE_ENTRY_CXX TSyError ReadSyncMLBuffer ( void* aCB, SessionH aSessionH, appPointer aBuffer, memSize aBufSize, memSize *aValSize ) ENTRY_ATTR; ENGINE_ENTRY_CXX TSyError WriteSyncMLBuffer( void* aCB, SessionH aSessionH, appPointer aBuffer, memSize aValSize ) ENTRY_ATTR; ENGINE_ENTRY_CXX TSyError CloseSession ( void* aCB, SessionH aSessionH ) ENTRY_ATTR; ENGINE_ENTRY_CXX TSyError OpenKeyByPath ( void* aCB, KeyH *aKeyH, KeyH aParentKeyH, cAppCharP aPath, uInt16 aMode ) ENTRY_ATTR; ENGINE_ENTRY_CXX TSyError OpenSubkey ( void* aCB, KeyH *aKeyH, KeyH aParentKeyH, sInt32 aID, uInt16 aMode ) ENTRY_ATTR; ENGINE_ENTRY_CXX TSyError DeleteSubkey ( void* aCB, KeyH aParentKeyH, sInt32 aID ) ENTRY_ATTR; ENGINE_ENTRY_CXX TSyError GetKeyID ( void* aCB, KeyH aKeyH, sInt32 *aID ) ENTRY_ATTR; ENGINE_ENTRY_CXX TSyError SetTextMode ( void* aCB, KeyH aKeyH, uInt16 aCharSet, uInt16 aLineEndMode, bool aBigEndian ) ENTRY_ATTR; ENGINE_ENTRY_CXX TSyError SetTimeMode ( void* aCB, KeyH aKeyH, uInt16 aTimeMode ) ENTRY_ATTR; ENGINE_ENTRY_CXX TSyError CloseKey ( void* aCB, KeyH aKeyH ) ENTRY_ATTR; ENGINE_ENTRY_CXX TSyError GetValue ( void* aCB, KeyH aKeyH, cAppCharP aValName, uInt16 aValType, appPointer aBuffer, memSize aBufSize, memSize *aValSize ) ENTRY_ATTR; ENGINE_ENTRY_CXX TSyError GetValueByID ( void* aCB, KeyH aKeyH, sInt32 aID, sInt32 arrIndex, uInt16 aValType, appPointer aBuffer, memSize aBufSize, memSize *aValSize ) ENTRY_ATTR; ENGINE_ENTRY_CXX sInt32 GetValueID ( void* aCB, KeyH aKeyH, cAppCharP aName ) ENTRY_ATTR; ENGINE_ENTRY_CXX TSyError SetValue ( void* aCB, KeyH aKeyH, cAppCharP aValName, uInt16 aValType, cAppPointer aBuffer, memSize aValSize ) ENTRY_ATTR; ENGINE_ENTRY_CXX TSyError SetValueByID ( void* aCB, KeyH aKeyH, sInt32 aID, sInt32 arrIndex, uInt16 aValType, cAppPointer aBuffer, memSize aValSize ) ENTRY_ATTR; // ---- tunnel -------------------------------------------------------------------------------------------------------- ENGINE_ENTRY_CXX TSyError StartDataRead ( CContext ac, cAppCharP lastToken, cAppCharP resumeToken ) ENTRY_ATTR; ENGINE_ENTRY_CXX TSyError ReadNextItem ( CContext ac, ItemID aID, appCharP *aItemData, sInt32 *aStatus, bool aFirst ) ENTRY_ATTR; ENGINE_ENTRY_CXX TSyError ReadItem ( CContext ac, cItemID aID, appCharP *aItemData ) ENTRY_ATTR; ENGINE_ENTRY_CXX TSyError EndDataRead ( CContext ac ) ENTRY_ATTR; ENGINE_ENTRY_CXX TSyError StartDataWrite ( CContext ac ) ENTRY_ATTR; ENGINE_ENTRY_CXX TSyError InsertItem ( CContext ac, cAppCharP aItemData, ItemID aID ) ENTRY_ATTR; ENGINE_ENTRY_CXX TSyError UpdateItem ( CContext ac, cAppCharP aItemData, cItemID aID, ItemID updID ) ENTRY_ATTR; ENGINE_ENTRY_CXX TSyError MoveItem ( CContext ac, cItemID aID, cAppCharP newParID ) ENTRY_ATTR; ENGINE_ENTRY_CXX TSyError DeleteItem ( CContext ac, cItemID aID ) ENTRY_ATTR; ENGINE_ENTRY_CXX TSyError EndDataWrite ( CContext ac, bool success, appCharP *newToken ) ENTRY_ATTR; ENGINE_ENTRY_CXX void DisposeObj ( CContext ac, void* memory ) ENTRY_ATTR; // ---- asKey ---- ENGINE_ENTRY_CXX TSyError ReadNextItemAsKey( CContext ac, ItemID aID, KeyH aItemKey, sInt32 *aStatus, bool aFirst ) ENTRY_ATTR; ENGINE_ENTRY_CXX TSyError ReadItemAsKey ( CContext ac, cItemID aID, KeyH aItemKey ) ENTRY_ATTR; ENGINE_ENTRY_CXX TSyError InsertItemAsKey ( CContext ac, KeyH aItemKey, ItemID aID ) ENTRY_ATTR; ENGINE_ENTRY_CXX TSyError UpdateItemAsKey ( CContext ac, KeyH aItemKey, cItemID aID, ItemID updID ) ENTRY_ATTR; // ---------------------------------------------------------------------------------------- ENGINE_ENTRY_CXX void CB_Connect( void* aCB ) ENTRY_ATTR; // engine local helper, used e.g. from PluginDS/Agent void CB_Connect_KeyAccess ( void* aCB ); } // namespace sysync #endif // ENGINEENTRY_H // eof libsynthesis-3.4.0.47.1/src/sysync/engineinterface.cpp000066400000000000000000002106161226375725500226230ustar00rootroot00000000000000/** * @File engineinterface.cpp * * @Author Lukas Zeller (luz@plan44.ch) * * @brief TEngineInterface - common interface to SySync engine for SDK * * Copyright (c) 2007-2011 by Synthesis AG + plan44.ch * */ #include "prefix_file.h" #ifdef ENGINEINTERFACE_SUPPORT #include "engineinterface.h" #include "syserial.h" #include "syncappbase.h" #include "SDK_util.h" namespace sysync { // TSettingsKeyImpl // ================ TSettingsKeyImpl::TSettingsKeyImpl( TEngineInterface *aEngineInterfaceP ) : fEngineInterfaceP(aEngineInterfaceP), fImplicitParentKeyP(NULL) { // init defaults from engine interface fCharSet = fEngineInterfaceP->fCharSet; fBigEndian = fEngineInterfaceP->fBigEndian; fLineEndMode = fEngineInterfaceP->fLineEndMode; // init hardcoded defaults fTimeMode = TMODE_LINEARTIME+TMODE_FLAG_FLOATING; // linear time (as floating, which means UTC for engine timestamps) } // TSettingsKeyImpl::TSettingsKeyImpl TSettingsKeyImpl::~TSettingsKeyImpl() { // deleting object means closing key // - At this point (in baseclass), actual key implementation is closed // already, so we can delete implicitly opened ancestors now recursively if (fImplicitParentKeyP) { delete fImplicitParentKeyP; fImplicitParentKeyP=NULL; } } // TSettingsKeyImpl::TSettingsKeyImpl // open subkey(chain) by path // - walks down through needed subkeys TSyError TSettingsKeyImpl::OpenKeyByPath( TSettingsKeyImpl *&aSettingsKeyP, // might be set even if overall open fails - caller must delete object passed back in case of failure cAppCharP aPath, uInt16 aMode, bool aImplicit // if set, this means that THIS key was implicitly opened, and should be implicitly closed as well ) { TSyError sta; TSettingsKeyImpl *subKeyP=NULL; // as long as we haven't openend anything, make sure pointer returned is NULL aSettingsKeyP=NULL; // open by relative path, starting at myself if (aPath==NULL) return LOCERR_WRONGUSAGE; // strip leading separators while (*aPath==SETTINGSKEY_PATH_SEPARATOR) aPath++; // search end of string or next separator cAppCharP e = aPath; while (*e && *e!=SETTINGSKEY_PATH_SEPARATOR) e++; // open the element we have found sta = OpenSubKeyByName(aSettingsKeyP,aPath,e-aPath,aMode); if (sta == LOCERR_OK) { // immediate subkey opened successfully // - if this is an implicit open, link back to myself as I must be deleted when subkey is deleted if (aImplicit) { aSettingsKeyP->fImplicitParentKeyP = this; } // new opened key inherits base key's value formatting settings aSettingsKeyP->SetTextMode(fCharSet, fLineEndMode,fBigEndian); aSettingsKeyP->SetTimeMode(fTimeMode); // - check if chain continues while (*e==SETTINGSKEY_PATH_SEPARATOR) e++; // strip leading separators if (*e) { // another path element follows, open it recursively // - this is implicit in any case! sta = aSettingsKeyP->OpenKeyByPath(subKeyP,e,aMode,true); if (subKeyP != NULL) { // more subkeys were opened, possibly not entire chain as requested. But in // any case, we need to pass back the rightmost opened key in the path as this // must be deleted by the caller (causing all implicitly related objects to delete as well) aSettingsKeyP = subKeyP; } } } // return status return sta; } // TSettingsKeyImpl::OpenKeyByPath const uInt16 engineCharSets[numCharSets] = { CHS_UNKNOWN, CHS_ASCII, CHS_ANSI, CHS_ISO_8859_1, CHS_UTF8, CHS_UTF16, #ifdef CHINESE_SUPPORT CHS_GB2312, CHS_CP936 #endif }; const uInt16 engineLineEndModes[numLineEndModes] = { LEM_NONE, LEM_UNIX, LEM_MAC, LEM_DOS, LEM_CSTR, LEM_FILEMAKER }; // Set text format parameters TSyError TSettingsKeyImpl::SetTextMode(uInt16 aCharSet, uInt16 aLineEndMode, bool aBigEndian) { // translate charset uInt16 chs; for (chs=0; chs we can return native value directly if (aValType == VALTYPE_TEXT) { if (!aBuffer || aBufSize==0) { // only measure size return GetValueInternal(aID,aArrayIndex,NULL,0,aValSize); } else { // low level text routines do not set terminators for simplicity, so make sure we have one here // - request only max one char less than buf can hold, so we always have room for a terminator sta = GetValueInternal(aID,aArrayIndex,aBuffer,aBufSize-1,aValSize); // - make sure we have a NUL terminator at the very end of the buffer in all cases ((appCharP)aBuffer)[aBufSize-1] = 0; // ultimate terminator // - also make sure we have a terminator at the end of the actual string if (sta==LOCERR_OK && aValSizeaBufSize-1) { sta = LOCERR_TRUNCATED; aValSize = aBufSize-1; // return actual size, not untruncated one } return sta; } } else { // non-text, simply return value sta = GetValueInternal(aID,aArrayIndex,aBuffer,aBufSize,aValSize); if (sta==LOCERR_OK && aBufSize && aBuffer && aValSize>aBufSize) { // not only measuring size, check for truncation if (aValType==VALTYPE_BUF) { // in case of buffer, we call this "truncated" (we don't know if the result is usable or not, depends on data itself) sta = LOCERR_TRUNCATED; aValSize = aBufSize; // return actual size, not untruncated one } else { // in other cases, too small buffer makes result unusable, so we don't call it "truncated" // AND: we return the needed buffer size sta = LOCERR_BUFTOOSMALL; } } return sta; } } // some kind of conversion needed // - get native size of value first memSize valSiz; sta = GetValueInternal(aID,aArrayIndex,NULL,0,valSiz); if (sta!=LOCERR_OK) return sta; // - allocate matching buffer memSize bufSiz = valSiz+1; // extra room for terminator uInt8P bufP = (uInt8P) malloc(bufSiz); bufP[valSiz]=0; // make sure we have a terminator if (bufP==NULL) return LOCERR_OUTOFMEM; // - get value in native type sta = GetValueInternal(aID,aArrayIndex,bufP,bufSiz,valSiz); if (sta==LOCERR_OK) { // value conversion matrix // - switch by native value type switch (valType) { // Timestamp native type (always VALTYPE_TIME64) case VALTYPE_TIME64: tempTime = *((lineartime_t *)bufP); tctx = (fTimeMode & TMODE_FLAG_UTC)==0 ? TCTX_SYSTEM : TCTX_UTC; // convert it from internal format (UTC), unless we request floating if ((fTimeMode & TMODE_FLAG_FLOATING)==0) TzConvertTimestamp(tempTime,TCTX_UTC,tctx,getEngineInterface()->getSyncAppBase()->getAppZones()); else tctx = TCTX_UNKNOWN; // make sure that ISO8601 representation has no TZ info in floating mode // now return if (aValType==VALTYPE_TEXT) { // return time as text TimestampToISO8601Str(valStr, tempTime, tctx, false, false); txt = valStr.c_str(); goto textConv; } // no time will return an error code if (tempTime==noLinearTime) { // no time sta=DB_NoContent; // indicates NO value break; } // return time as integer number switch (fTimeMode & TMODE_MODEMASK) { case TMODE_LINEARDATE: tempInt = tempTime / linearDateToTimeFactor; goto intConv; case TMODE_UNIXTIME_MS: tempInt = tempTime-UnixToLineartimeOffset; // lineartime_t (that is, milliseconds), but with unix epoch origin goto intConv; case TMODE_UNIXTIME: tempInt = (tempTime-UnixToLineartimeOffset)/secondToLinearTimeFactor; goto intConv; default : tempInt = tempTime; goto intConv; } break; // Integer native types case VALTYPE_INT8: tempInt = *((sInt8 *)bufP); goto intConv; case VALTYPE_INT16: tempInt = *((sInt16 *)bufP); goto intConv; case VALTYPE_INT32: tempInt = *((sInt32 *)bufP); goto intConv; case VALTYPE_INT64: tempInt = *((sInt64 *)bufP); intConv: // convert integer into desired target type switch (aValType) { case VALTYPE_INT8: case VALTYPE_ENUM: aValSize=1; if (aBufSize0 ? aBufSize-2 : 0 // max output size (but no limit if measuring actual size) )) sta = LOCERR_TRUNCATED; // return (possibly truncated) size aValSize=convStr.size(); // this will be added as part of the content, and gives a 16bit NUL terminator convStr+=(char)0; } else { // 8-bit character encoding if (!appendUTF8ToString( txt, convStr, fCharSet, fLineEndMode, qm_none, aBufSize>0 ? aBufSize-1 : 0 // max output size (but no limit if measuring actual size) )) sta = LOCERR_TRUNCATED; // return (possibly truncated) size aValSize=convStr.size(); } // if requested, return value into buffer if (aBufSize>0) { // copy including implicit NUL terminator BYTE (in case of UTF16, there is an extra explicit NUL char in the convStr itself to make a 16-bit NUL!) memcpy(aBuffer,(appPointer)convStr.c_str(),convStr.size()+1>aBufSize ? aBufSize : convStr.size()+1); } else { // measuring size always returns OK sta = LOCERR_OK; } } break; } // switch by native type } // if value returned // - return temp buffer free(bufP); // - return status return sta; } // TSettingsKeyImpl::GetValueByID // Writes a named value in specified format passed in memory buffer TSyError TSettingsKeyImpl::SetValueByID( sInt32 aID, sInt32 aArrayIndex, uInt16 aValType, cAppPointer aBuffer, memSize aValSize ) { TSyError sta = LOCERR_OK; sInt64 tempInt; lineartime_t tempTime; timecontext_t tctx; appPointer bP; memSize siz; string convStr; // get native type of value (and check validity of ID - invalid IDs must return VALTYPE_UNKNOWN) uInt16 valType = GetValueType(aID); if (valType==VALTYPE_UNKNOWN) return DB_NotFound; // measure value for strings if (aValType == VALTYPE_TEXT && aValSize == memSize(-1)) { if (fCharSet==chs_utf16) return LOCERR_NOTIMP; // measuring UTF-16 not supported yet //aValSize = wcslen((short *)aBuffer)/2; else aValSize = strlen((char *)aBuffer); } // we can set directly if input type matches native type if ( (aValType == VALTYPE_BUF) || ((valType == aValType) && (valType != VALTYPE_TEXT || (fCharSet==chs_utf8 && fLineEndMode==lem_cstr)) && (valType != VALTYPE_TIME64 || ((fTimeMode & TMODE_MODEMASK)==TMODE_LINEARTIME)) ) ) { // presented type&format matches native or we are setting bytes 1:1 anyway -> we can set native value directly return SetValueInternal(aID,aArrayIndex,aBuffer,aValSize); } // some kind of conversion needed // - switch by presented value type switch (aValType) { // Set "no value" case VALTYPE_NULL: sta = SetValueInternal(aID,aArrayIndex,NULL,0); break; // Text presented case VALTYPE_TEXT: // first convert into internal text format if (fCharSet==chs_utf16) { appendUTF16AsUTF8((uInt16 *)aBuffer,aValSize/2,fBigEndian,convStr, true, true); } else { string s; s.assign((cAppCharP)aBuffer,aValSize); appendStringAsUTF8(s.c_str(), convStr, fCharSet, lem_cstr, true); } // possibly convert text to native switch (valType) { case VALTYPE_TIME64: // convert text to internal time format ISO8601StrToTimestamp(convStr.c_str(), tempTime, tctx); // if not floating, assume target timestamp is UTC, so ISO string w/o time zone is treated as system time for convenience if ((fTimeMode & TMODE_FLAG_FLOATING)==0) TzConvertTimestamp(tempTime, tctx, TCTX_UTC, getEngineInterface()->getSyncAppBase()->getAppZones(), TCTX_SYSTEM); siz=8; bP = &tempTime; break; case VALTYPE_INT8: case VALTYPE_INT16: case VALTYPE_INT32: case VALTYPE_INT64: // convert text to integer StrToLongLong(convStr.c_str(),tempInt); goto intConv; case VALTYPE_TEXT: siz=convStr.size(); bP=(appPointer)convStr.c_str(); break; default: // cannot return as text return LOCERR_WRONGUSAGE; } // set it sta = SetValueInternal(aID,aArrayIndex,bP,siz); break; // Timestamp presented case VALTYPE_TIME32: if (aValSize<4) return LOCERR_BUFTOOSMALL; tempTime = *((sInt32 *)aBuffer); goto timeConv; case VALTYPE_TIME64: if (aValSize<8) return LOCERR_BUFTOOSMALL; tempTime = *((sInt64 *)aBuffer); timeConv: switch (fTimeMode & TMODE_MODEMASK) { case TMODE_LINEARDATE: tempInt = tempTime * linearDateToTimeFactor; break; case TMODE_UNIXTIME_MS: tempInt = tempTime+UnixToLineartimeOffset; break; case TMODE_UNIXTIME: tempInt = secondToLinearTimeFactor*tempTime+UnixToLineartimeOffset; break; case TMODE_LINEARTIME: default : tempInt = tempTime; break; } tctx = (fTimeMode & TMODE_FLAG_UTC)==0 ? TCTX_SYSTEM : TCTX_UTC; // convert to UTC if needed if ((fTimeMode & TMODE_FLAG_FLOATING)==0) TzConvertTimestamp(tempInt,tctx,TCTX_UTC,getEngineInterface()->getSyncAppBase()->getAppZones()); goto intConv; // Integer presented types case VALTYPE_INT8: case VALTYPE_ENUM: if (aValSize<1) return LOCERR_BUFTOOSMALL; tempInt = *((sInt8 *)aBuffer); goto intConv; case VALTYPE_INT16: if (aValSize<2) return LOCERR_BUFTOOSMALL; tempInt = *((sInt16 *)aBuffer); goto intConv; case VALTYPE_INT32: if (aValSize<4) return LOCERR_BUFTOOSMALL; tempInt = *((sInt32 *)aBuffer); goto intConv; case VALTYPE_INT64: if (aValSize<8) return LOCERR_BUFTOOSMALL; tempInt = *((sInt64 *)aBuffer); intConv: // convert integer into native type union { sInt64 buffer64; sInt32 buffer32; sInt16 buffer16; sInt8 buffer8; } buffer; bP = &buffer; switch (valType) { case VALTYPE_INT8: siz=1; buffer.buffer8 = tempInt; break; case VALTYPE_INT16: siz=2; buffer.buffer16 = tempInt; break; case VALTYPE_INT32: siz=4; buffer.buffer32 = tempInt; break; case VALTYPE_INT64: case VALTYPE_TIME64: // native timestamp siz=8; buffer.buffer64 = tempInt; break; default: // other types (like text) cannot set as integer return LOCERR_WRONGUSAGE; // conversion not allowed break; } // now write int/time value sta = SetValueInternal(aID,aArrayIndex,bP,siz); break; } // switch by presented type return sta; } // TSettingsKeyImpl::SetValueByID #define VALID_IDXOFFS_VALTYPE 0x100000 #define VALID_MASK_IDX 0x00FFFF // helper for detecting generic field attribute access bool TSettingsKeyImpl::checkFieldAttrs(cAppCharP aName, size_t &aBaseNameSize, sInt32 &aFldID) { aBaseNameSize = strlen(aName); aFldID = 0; // basic if (aBaseNameSize >= strlen(VALSUFF_TYPE) && strucmp(aName+aBaseNameSize-strlen(VALSUFF_TYPE),VALSUFF_TYPE)==0) { // value type aBaseNameSize-=strlen(VALSUFF_TYPE); aFldID += VALID_IDXOFFS_VALTYPE; } if (strucmp(aName,VALNAME_FLAG,aBaseNameSize)==0) return true; // asking for flag mask only return false; // aFldID is only the flag mask, caller must add base index } // TSettingsKeyImpl::checkFieldAttrs // helper for returning generic field attribute type bool TSettingsKeyImpl::checkAttrValueType(sInt32 aID, uInt16 &aValType) { if (aID>0 && (aID & VALID_IDXOFFS_VALTYPE)) { aValType = VALTYPE_INT16; // valtype is always uInt16 return true; } return false; } // TSettingsKeyImpl::checkAttrValueType // helper for returning generic field attribute values bool TSettingsKeyImpl::checkAttrValue( sInt32 aID, sInt32 aArrayIndex, appPointer aBuffer, memSize aBufSize, memSize &aValSize ) { if (aID>0 && (aID & VALID_IDXOFFS_VALTYPE)) { // return type, not value aValSize = 2; uInt16 valtype = GetValueType(aID & VALID_MASK_IDX); if (aBufSize>=aValSize) { memcpy(aBuffer,&valtype,aValSize); } return true; } return false; } // TSettingsKeyImpl::checkAttrValue // TReadOnlyInfoKey // ================ // get value's ID (e.g. internal index) sInt32 TReadOnlyInfoKey::GetValueID(cAppCharP aName) { const TReadOnlyInfo *tblP = getInfoTable(); sInt32 idx=0; size_t namsz; sInt32 fldID; if (checkFieldAttrs(aName,namsz,fldID)) return fldID; while(tblP && idx=numInfos()) return VALTYPE_UNKNOWN; return getInfoTable()[aID].valType; } // TReadOnlyInfoKey::GetValueType // get value TSyError TReadOnlyInfoKey::GetValueInternal( sInt32 aID, sInt32 aArrayIndex, appPointer aBuffer, memSize aBufSize, memSize &aValSize ) { if (checkAttrValue(aID,aArrayIndex,aBuffer,aBufSize,aValSize)) return LOCERR_OK; const TReadOnlyInfo *infoP = &(getInfoTable()[aID]); memSize siz = infoP->valSiz; if (siz==0 && infoP->valType==VALTYPE_TEXT) siz = strlen((cAppCharP)(infoP->valPtr)); // return actual size aValSize = siz; // return requested amount of data or all we have, whatever is smaller if (siz>aBufSize) siz=aBufSize; // limit to buffer size (aBufSiz is compensated for NUL terminator already, so we can use memcpy for strings as well) memcpy(aBuffer,infoP->valPtr,siz); return LOCERR_OK; } // TReadOnlyInfoKey::GetValueInternal // TConfigVarKey // ============= // get value's ID (config vars do NOT have a real ID!) sInt32 TConfigVarKey::GetValueID(cAppCharP aName) { size_t namsz; sInt32 fldID; checkFieldAttrs(aName,namsz,fldID); if (fldID!=0) return fldID; // is an attribute // value itself cannot be accessed by ID - so cache name for next call to getValueInternal fVarName = aName; // cache name return KEYVAL_NO_ID; }; // get value's native type (all config vars are text) uInt16 TConfigVarKey::GetValueType(sInt32 aID) { uInt16 valType; if (checkAttrValueType(aID,valType)) return valType; // value itself is always text return VALTYPE_TEXT; } // TConfigVarKey::GetValueType // get value TSyError TConfigVarKey::GetValueInternal( sInt32 aID, sInt32 aArrayIndex, appPointer aBuffer, memSize aBufSize, memSize &aValSize ) { if (checkAttrValue(aID,aArrayIndex,aBuffer,aBufSize,aValSize)) return LOCERR_OK; string s; if (!fEngineInterfaceP->getSyncAppBase()->getConfigVar(fVarName.c_str(),s)) return DB_NotFound; // copy string into buffer aValSize=s.size(); strncpy((appCharP)aBuffer,s.c_str(),aBufSize); return LOCERR_OK; } // TConfigVarKey::GetValueInternal // set value TSyError TConfigVarKey::SetValueInternal( sInt32 aID, sInt32 aArrayIndex, cAppPointer aBuffer, memSize aValSize ) { if (!aBuffer) { // writing NULL means undefining variable fEngineInterfaceP->getSyncAppBase()->unsetConfigVar(fVarName.c_str()); return LOCERR_OK; } string v; v.assign((cAppCharP)aBuffer,(size_t)aValSize); // copy because input could be unterminated string if (!fEngineInterfaceP->getSyncAppBase()->setConfigVar(fVarName.c_str(),v.c_str())) return DB_NotFound; return LOCERR_OK; } // TConfigVarKey::SetValueInternal // TStructFieldsKey // ================ // static helper for procedural string readers TSyError TStructFieldsKey::returnString(cAppCharP aReturnString, appPointer aBuffer, memSize aBufSize, memSize &aValSize) { aValSize=strlen(aReturnString); if (aBufSize>=aValSize) { // copy string strncpy((appCharP)aBuffer,aReturnString,aValSize); } return LOCERR_OK; } // returnString // static helper for procedural int readers TSyError TStructFieldsKey::returnInt(sInt32 aInt, memSize aIntSize, appPointer aBuffer, memSize aBufSize, memSize &aValSize) { aValSize=aIntSize; if (aBufSize==0) return LOCERR_OK; // measuring size if (aBufSize=4) *((sInt32 *)aBuffer) = (sInt32)aInt; else if (aValSize>=2) *((sInt16 *)aBuffer) = (sInt16)aInt; else *((sInt8 *)aBuffer) = (sInt8)aInt; return LOCERR_OK; } // returnInt TSyError TStructFieldsKey::returnLineartime(lineartime_t aTime, appPointer aBuffer, memSize aBufSize, memSize &aValSize) { aValSize=sizeof(lineartime_t); if (aBufSize==0) return LOCERR_OK; // measuring size if (aBufSize=numFields()) return VALTYPE_UNKNOWN; const TStructFieldInfo *fldinfoP = &(getFieldsTable()[aID]); valType = fldinfoP->valType; if (valType == VALTYPE_ENUM) { // VALTYPE_ENUM: determine integer type from actual size of variable switch (fldinfoP->valSiz) { default : return VALTYPE_INT8; // smallest causes least harm: use as default case 2 : return VALTYPE_INT16; case 4 : return VALTYPE_INT32; case 8 : return VALTYPE_INT64; } } else if (valType == VALTYPE_TEXT_OBFUS) return VALTYPE_TEXT; // obfuscated fields are text for SDK user else return valType; // just return specified type } // TStructFieldsKey::GetValueType // get value TSyError TStructFieldsKey::GetValueInternal( sInt32 aID, sInt32 aArrayIndex, appPointer aBuffer, memSize aBufSize, memSize &aValSize ) { if (checkAttrValue(aID,aArrayIndex,aBuffer,aBufSize,aValSize)) return LOCERR_OK; const TStructFieldInfo *fldinfoP = &(getFieldsTable()[aID]); // check for programmatic access to value if (fldinfoP->getValueProc) { // get value programmatically return fldinfoP->getValueProc(this,fldinfoP,aBuffer,aBufSize,aValSize); } // fetch value from structure memSize siz = fldinfoP->valSiz; // get (max) size if (siz==0) return DB_Forbidden; // read access not allowed uInt8P valPtr = getStructAddr()+fldinfoP->fieldOffs; // for text fields, measure actual size if (fldinfoP->valType==VALTYPE_TEXT) siz = strlen((cAppCharP)valPtr); // return actual size aValSize = siz; // return requested amount of data or all we have, whatever is smaller if (siz>aBufSize) siz=aBufSize; // limit to buffer size (aBufSiz is compensated for NUL terminator already, so we can use memcpy for strings as well) // for obfuscated fields, use special routine if (fldinfoP->valType==VALTYPE_TEXT_OBFUS && siz>0) { getUnmangledAsBuf((appCharP)aBuffer, siz, (cAppCharP)valPtr); // measure decoded aValSize = strlen((cAppCharP)aBuffer); } else memcpy(aBuffer,valPtr,siz); return LOCERR_OK; } // TStructFieldsKey::GetValueInternal // set value TSyError TStructFieldsKey::SetValueInternal( sInt32 aID, sInt32 aArrayIndex, cAppPointer aBuffer, memSize aValSize ) { if (!aBuffer) return LOCERR_WRONGUSAGE; // cannot handle NULL values if (aID & VALID_IDXOFFS_VALTYPE) return DB_Forbidden; // can't write type TSyError sta = LOCERR_OK; const TStructFieldInfo *fldinfoP = &(getFieldsTable()[aID]); // refuse writing to read-only fields if (!fldinfoP->writable) return DB_Forbidden; // check for programmatic access to value if (fldinfoP->setValueProc) { // set value programmatically return fldinfoP->setValueProc(this,fldinfoP,aBuffer,aValSize); } // write value to structure memSize siz = fldinfoP->valSiz; // get (max) size (for strings: buffer including NUL) if (siz==0) return DB_Forbidden; // write access not allowed uInt8P valPtr = getStructAddr()+fldinfoP->fieldOffs; // adjust usable size for strings if (fldinfoP->valType == VALTYPE_TEXT) siz--; // reserve one for terminator // check and signal truncation if (aValSize>siz) sta=LOCERR_TRUNCATED; else siz=aValSize; // copy data into struct if (fldinfoP->valType==VALTYPE_TEXT_OBFUS) { string v; v.assign((cAppCharP)aBuffer,aValSize); assignMangledToCString((appCharP)valPtr, v.c_str(), fldinfoP->valSiz, true); // always use entire buffer and fill it with garbage beyond end of actual data } else memcpy(valPtr,aBuffer,siz); // - struct modified, signal that (for derivates that might want to save the record on close) fDirty=true; // append terminator in case of text if (fldinfoP->valType == VALTYPE_TEXT) *(valPtr+siz)=0; // done return sta; } // TStructFieldsKey::SetValueInternal #ifdef SYSER_REGISTRATION // Licensing key // ------------- // Accessors for license text and code // - read license text static TSyError readLicenseText( TStructFieldsKey *aStructFieldsKeyP, const TStructFieldInfo *aFldInfoP, appPointer aBuffer, memSize aBufSize, memSize &aValSize ) { // copy from config aValSize=aStructFieldsKeyP->getEngineInterface()->getSyncAppBase()->getRootConfig()->fLicenseName.size(); if (aBufSize>0) strncpy((char *)aBuffer,aStructFieldsKeyP->getEngineInterface()->getSyncAppBase()->getRootConfig()->fLicenseName.c_str(),aBufSize); return LOCERR_OK; } // readLicenseText // - write license text static TSyError writeLicenseText( TStructFieldsKey *aStructFieldsKeyP, const TStructFieldInfo *aFldInfoP, cAppPointer aBuffer, memSize aValSize ) { // assign to config aStructFieldsKeyP->getEngineInterface()->getSyncAppBase()->getRootConfig()->fLicenseName.assign((cAppCharP)aBuffer,aValSize); /* DO NOT recalculate, only when setting code // recalculate app enabled status fEngineInterfaceP->getSyncAppBase()->isRegistered(); */ return LOCERR_OK; } // writeLicenseText // - write license code static TSyError writeLicenseCode( TStructFieldsKey *aStructFieldsKeyP, const TStructFieldInfo *aFldInfoP, cAppPointer aBuffer, memSize aValSize ) { // assign to config aStructFieldsKeyP->getEngineInterface()->getSyncAppBase()->getRootConfig()->fLicenseCode.assign((cAppCharP)aBuffer,aValSize); // recalculate all license dependent variables aStructFieldsKeyP->getEngineInterface()->getSyncAppBase()->isRegistered(); // always ok return LOCERR_OK; } // writeLicenseCode // - read (and recalculate) registration status code // (i.e. status of currently installed license. Note that even if this returns non-ok, the app // might still be able to sync, e.g. due to a free demo period) static TSyError readRegStatus( TStructFieldsKey *aStructFieldsKeyP, const TStructFieldInfo *aFldInfoP, appPointer aBuffer, memSize aBufSize, memSize &aValSize ) { aValSize=2; if (aBufSize>=aValSize) { // recalculate all license dependent variables localstatus sta = aStructFieldsKeyP->getEngineInterface()->getSyncAppBase()->isRegistered(); // copy from config *((uInt16*)aBuffer)=sta; } return LOCERR_OK; } // readRegStatus // - read (and recalculate) application enable status code // (i.e. if app can sync now. Note that this does not necessarily mean that a valid license is installed, // read "regStatus" for that). static TSyError readEnabledStatus( TStructFieldsKey *aStructFieldsKeyP, const TStructFieldInfo *aFldInfoP, appPointer aBuffer, memSize aBufSize, memSize &aValSize ) { aValSize=2; if (aBufSize>=aValSize) { // recalculate all license dependent variables and current enabled status // Note: includes checking for daysleft localstatus sta = aStructFieldsKeyP->getEngineInterface()->getSyncAppBase()->appEnableStatus(); // copy from config *((uInt16*)aBuffer)=sta; } return LOCERR_OK; } // readEnabledStatus #if defined(EXPIRES_AFTER_DAYS) && defined(ENGINEINTERFACE_SUPPORT) // - write first use version number static TSyError writeFuv( TStructFieldsKey *aStructFieldsKeyP, const TStructFieldInfo *aFldInfoP, cAppPointer aBuffer, memSize aValSize ) { uInt32 fuv = *((uInt32 *)aBuffer); if (fuv==0x53595359) { // start eval aStructFieldsKeyP->getEngineInterface()->getSyncAppBase()->updateFirstUseInfo( aStructFieldsKeyP->getEngineInterface()->getSyncAppBase()->fFirstUseDate, aStructFieldsKeyP->getEngineInterface()->getSyncAppBase()->fFirstUseVers ); } else { // simply assign (usually values read from here in an earlier session and stored persistently outside) aStructFieldsKeyP->getEngineInterface()->getSyncAppBase()->fFirstUseVers = fuv; } // always ok return LOCERR_OK; } // writeFuv #endif // EXPIRES_AFTER_DAYS+ENGINEINTERFACE_SUPPORT // macro simplifying typing in the table below #define OFFS_SZ_AB(n) (offsetof(TSyncAppBase,n)), sizeof(dP_ab->n) // dummy pointer needed for sizeof static const TSyncAppBase *dP_ab=NULL; // accessor table for licensing info static const TStructFieldInfo LicensingFieldInfos[] = { // valName, valType, writable, fieldOffs, valSiz // - license text and code (writable) { "licensetext", VALTYPE_TEXT, true, 0, 0, &readLicenseText, &writeLicenseText }, { "licensecode", VALTYPE_TEXT, true, 0, 0, NULL, &writeLicenseCode }, #if defined(EXPIRES_AFTER_DAYS) && defined(ENGINEINTERFACE_SUPPORT) // - read/write for eval { "fud", VALTYPE_INT32, true, OFFS_SZ_AB(fFirstUseDate) }, // first use date { "fuv", VALTYPE_INT32, true, OFFS_SZ_AB(fFirstUseVers), NULL, &writeFuv }, // first use version #endif // - read-only info about licensing status from syncappbase { "regStatus", VALTYPE_INT16, false, 0, 0, &readRegStatus, NULL }, { "enabledStatus", VALTYPE_INT16, false, 0, 0, &readEnabledStatus, NULL }, { "regOK", VALTYPE_ENUM, false, OFFS_SZ_AB(fRegOK) }, { "productCode", VALTYPE_ENUM, false, OFFS_SZ_AB(fRegProductCode) }, { "productFlags", VALTYPE_ENUM, false, OFFS_SZ_AB(fRegProductFlags) }, { "quantity", VALTYPE_ENUM, false, OFFS_SZ_AB(fRegQuantity) }, { "licenseType", VALTYPE_ENUM, false, OFFS_SZ_AB(fRegLicenseType) }, { "daysleft", VALTYPE_ENUM, false, OFFS_SZ_AB(fDaysLeft) }, }; // get table describing the fields in the struct const TStructFieldInfo *TLicensingKey::getFieldsTable(void) { return LicensingFieldInfos; } // TLicensingKey::getFieldsTable sInt32 TLicensingKey::numFields(void) { return sizeof(LicensingFieldInfos)/sizeof(TStructFieldInfo); } // TLicensingKey::numFields // get actual struct base address uInt8P TLicensingKey::getStructAddr(void) { return (uInt8P)fEngineInterfaceP->getSyncAppBase(); // we are accessing SyncAppBase fields } // TLicensingKey::getStructAddr #endif // SYSER_REGISTRATION // TEngineInterface // ================ // constructor TEngineInterface::TEngineInterface() : fAppBaseP(NULL) { // init string modes to default fCharSet = chs_utf8; fLineEndMode = lem_cstr; fBigEndian = false; // default to Intel order } // TEngineInterface // constructor TSyError TEngineInterface::Init() { #ifdef DIRECT_APPBASE_GLOBALACCESS // global anchor only exists in old-style targets; pure engines do not have it any more sysync_glob_setanchor(this); #endif // create the appropriate SyncAppBase object fAppBaseP = newSyncAppBase(); if (fAppBaseP==NULL) return LOCERR_UNDEFINED; // set myself as the Master fAppBaseP->fEngineInterfaceP = this; // connect the debug routines to the appbase logger #ifdef SYDEBUG if (fCI) { fCI->callbackRef = fAppBaseP; fCI->DB_DebugPuts = AppBaseLogDebugPuts; fCI->DB_DebugBlock = AppBaseLogDebugBlock; fCI->DB_DebugEndBlock = AppBaseLogDebugEndBlock; fCI->DB_DebugEndThread = AppBaseLogDebugEndThread; fCI->DB_DebugExotic = AppBaseLogDebugExotic; } #endif // we have an appbase now return LOCERR_OK; } // TEngineInterface::Init TSyError TEngineInterface::Term() { // empty for the moment return LOCERR_OK; } // TEnigneInterface::Term // destructor TEngineInterface::~TEngineInterface() { // delete the SyncAppBase if (fAppBaseP) { delete fAppBaseP; fAppBaseP=NULL; } #ifdef DIRECT_APPBASE_GLOBALACCESS // global anchor only exists in old-style targets; pure engines do not have it any more sysync_glob_setanchor(NULL); #endif } // ~TEngineInterface // Set text format parameters TSyError TEngineInterface::SetStringMode(uInt16 aCharSet, uInt16 aLineEndMode, bool aBigEndian) { // translate charset uInt16 chs; for (chs=0; chsfApiInterModuleContext = fCI->gContext; // make sure we have string as UTF-8 string tempStr; aConfigXML = makeAppString(aConfigXML, tempStr); // feed config string directly into engine return getSyncAppBase()->readXMLConfigConstant(aConfigXML); #endif } // TEngineInterface::InitEngineXML /// @brief init object, optionally passing a open FILE for reading config /// @param aCfgFile[in] open file containing XML config /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure TSyError TEngineInterface::InitEngineFile(cAppCharP aConfigFilePath) { // make sure we have string as UTF-8 string tempStr; aConfigFilePath = makeAppString(aConfigFilePath, tempStr); // get the global context for pooling ressources like Java VM fAppBaseP->fApiInterModuleContext = fCI->gContext; // read config from a file string pathStr = aConfigFilePath; getSyncAppBase()->expandConfigVars(pathStr,2); // now parse config return getSyncAppBase()->readXMLConfigFile(pathStr.c_str()); } // TEngineInterface::InitEngineFile /// @brief init object, optionally passing a callback for reading config /// @param aReaderFunc[in] callback function which can deliver next chunk of XML config data /// @param aContext[in] free context pointer passed back with callback /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure TSyError TEngineInterface::InitEngineCB(TXMLConfigReadFunc aReaderFunc, void *aContext) { // get the global context for pooling ressources like Java VM fAppBaseP->fApiInterModuleContext = fCI->gContext; // now parse config return getSyncAppBase()->readXMLConfigStream(aReaderFunc, aContext); } // TEngineInterface::InitEngineCB /// @brief Open a session /// @param aNewSessionH[out] receives session handle for all session execution calls /// @param aSelector[in] selector, depending on session type. For multi-profile clients: profile ID to use /// @param aSessionName[in] a text name/id to identify a session, useage depending on session type. /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure TSyError TEngineInterface::OpenSession(SessionH &aNewSessionH, uInt32 aSelector, cAppCharP aSessionName) { // safety check - app must be enabled (initialized with config and ok license before we can open a session) localstatus sta=getSyncAppBase()->appEnableStatus(); if (sta!=LOCERR_OK) return sta; // app not enabled (and maybe not initialized properly) - prevent any session opening // make sure we have string as UTF-8 string tempStr; aSessionName = makeAppString(aSessionName, tempStr); return OpenSessionInternal(aNewSessionH, aSelector, aSessionName); } // TEngineInterface::OpenSession /// @brief internal implementation, derived in actual clients or servers TSyError TEngineInterface::OpenSessionInternal(SessionH &aNewSessionH, uInt32 aSelector, cAppCharP aSessionName) { // must be implemented in derived class return LOCERR_NOTIMP; } // TEngineInterface::OpenSessionInternal /// @brief open session specific runtime parameter/settings key /// @note key handle obtained with this call must be closed BEFORE SESSION IS CLOSED! /// @param aNewKeyH[out] receives the opened key's handle on success /// @param aSessionH[in] session handle obtained with OpenSession /// @param aMode[in] the open mode /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure TSyError TEngineInterface::OpenSessionKey(SessionH aSessionH, KeyH &aNewKeyH, uInt16 aMode) { // no session key available in base class return DB_NotFound; } // TEngineInterface::OpenSessionKey /// @brief Close a session /// @note It depends on session type if this also destroys the session or if it may persist and can be re-opened. /// @param aSessionH[in] session handle obtained with OpenSession /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure TSyError TEngineInterface::CloseSession(SessionH aSessionH) { // must be implemented in derived class return LOCERR_NOTIMP; } // TEngineInterface::CloseSession /// @brief Executes next step of the session /// @param aSessionH[in] session handle obtained with OpenSession /// @param aStepCmd[in/out] step command (STEPCMD_xxx): /// - tells caller to send or receive data or end the session etc. /// - instructs engine to suspend or abort the session etc. /// @param aInfoP[in] pointer to a TEngineProgressInfo structure, NULL if no progress info needed /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure TSyError TEngineInterface::SessionStep (SessionH aSessionH, uInt16 &aStepCmd, TEngineProgressInfo *aInfoP) { // must be implemented in derived class return LOCERR_NOTIMP; } // TEngineInterface::SessionStep /// @brief Get access to SyncML message buffer /// @param aSessionH[in] session handle obtained with OpenSession /// @param aForSend[in] send mode (true) / receive mode (false) /// @param aBuffer[out] receives pointer to buffer (empty for receive, full for send) /// @param aBufSize[out] receives size of empty or full buffer /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure TSyError TEngineInterface::GetSyncMLBuffer(SessionH aSessionH, bool aForSend, appPointer &aBuffer, memSize &aBufSize) { Ret_t rc; MemSize_t bufSz; // Note: this is SML_TK definition of memsize! // get SML instance for this session (note that "session" could be a SAN checker as well) InstanceID_t myInstance = getSmlInstanceOfSession(aSessionH); if (myInstance==0) return LOCERR_WRONGUSAGE; // no instance, usage must be wrong // provide access to the buffer if (aForSend) { // we want to read the SyncML buffer rc=smlLockReadBuffer( myInstance, (unsigned char **)&aBuffer, // receives address of buffer containing SyncML to send &bufSz // receives size of SyncML to send ); aBufSize = bufSz; } else { // we want to write the SyncML buffer rc=smlLockWriteBuffer( myInstance, (unsigned char **)&aBuffer, // receives address of buffer where received SyncML can be put &bufSz // capacity of the buffer ); aBufSize = bufSz; } // check error if (rc!=SML_ERR_OK) return LOCERR_SMLFATAL; // problem with SML toolkit // done return LOCERR_OK; } // TEngineInterface::GetSyncMLBuffer /// @brief Return SyncML message buffer to engine /// @param aSessionH[in] session handle obtained with OpenSession /// @param aForSend[in] send mode (true) / receive mode (false) /// @param aProcessed[in] number of bytes put into or read from the buffer /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure TSyError TEngineInterface::RetSyncMLBuffer(SessionH aSessionH, bool aForSend, memSize aProcessed) { Ret_t rc; // get SML instance for this session (note that "session" could be a SAN checker as well) InstanceID_t myInstance = getSmlInstanceOfSession(aSessionH); if (myInstance==0) return LOCERR_WRONGUSAGE; // no instance, usage must be wrong // return buffer if (aForSend) { // we have read the SyncML from the buffer (and usually sent to the remote) rc=smlUnlockReadBuffer( myInstance, aProcessed // number of bytes read from the buffer (and sent to the remote, hopefully...) ); } else { // we have written some data (usually received from the remote) into the SyncML buffer rc=smlUnlockWriteBuffer( myInstance, aProcessed // number of SyncML bytes put into the buffer (coming from the remote, usually...) ); } // check error if (rc!=SML_ERR_OK) return LOCERR_SMLFATAL; // problem with SML toolkit // done return LOCERR_OK; } // TEngineInterface::RetSyncMLBuffer /// @brief Read data from SyncML message buffer /// @param aSessionH[in] session handle obtained with OpenSession /// @param aBuffer[in] pointer to buffer /// @param aBufSize[in] size of buffer, maximum to be read /// @param aMsgSize[out] size of data available in the buffer for read INCLUDING just returned data. /// @note If the aBufSize is too small to return all available data LOCERR_TRUNCATED will be returned, and the /// caller can repeat calls to ReadSyncMLBuffer to get the next chunk. /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure TSyError TEngineInterface::ReadSyncMLBuffer(SessionH aSessionH, appPointer aBuffer, memSize aBufSize, memSize &aMsgSize) { TSyError sta; appPointer bufP; memSize msgsiz; // get buffer for read sta = GetSyncMLBuffer(aSessionH,true,bufP,msgsiz); if (sta!=LOCERR_OK) return sta; // anyway: pass size of data in the buffer aMsgSize = msgsiz; // check if buffer passed is large enough if (aBufSize0) { // copy data memcpy(aBuffer,bufP,msgsiz); } // return SyncML buffer to engine RetSyncMLBuffer(aSessionH,true,msgsiz); // return status return sta; } // TEngineInterface::ReadSyncMLBuffer /// @brief Write data to SyncML message buffer /// @param aSessionH[in] session handle obtained with OpenSession /// @param aBuffer[in] pointer to buffer /// @param aMsgSize[in] size of message to write to the buffer /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure TSyError TEngineInterface::WriteSyncMLBuffer(SessionH aSessionH, appPointer aBuffer, memSize aMsgSize) { TSyError sta; appPointer bufP; memSize bufsiz; // get buffer for write sta = GetSyncMLBuffer(aSessionH,false,bufP,bufsiz); if (sta!=LOCERR_OK) return sta; // check if buffer large enough to write data if (aMsgSize>bufsiz) { // can't write data - message too large sta = LOCERR_BUFTOOSMALL; aMsgSize=0; // don't write anything } else { if (aMsgSize>0) { // copy data memcpy(bufP,aBuffer,aMsgSize); } } // return SyncML buffer to engine RetSyncMLBuffer(aSessionH,false,aMsgSize); // return status return sta; } // TEngineInterface::WriteSyncMLBuffer /// @brief open Settings key by path specification /// @param aNewKeyH[out] receives the opened key's handle on success /// @param aParentKeyH[in] NULL if path is absolute from root, handle to an open key for relative access /// @param aPath[in] the path specification as null terminated string /// @param aMode[in] the open mode /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure TSyError TEngineInterface::OpenKeyByPath ( KeyH &aNewKeyH, KeyH aParentKeyH, cAppCharP aPath, uInt16 aMode ) { TSettingsKeyImpl *aBaseKeyP = NULL; TSettingsKeyImpl *aKeyP = NULL; bool implicit = false; TSyError sta; // make sure we have string as UTF-8 string tempStr; aPath = makeAppString(aPath, tempStr); // determine base key if (aParentKeyH) { // already opened base key passed aBaseKeyP = reinterpret_cast(aParentKeyH); implicit = false; // we have the parent already, do not delete it implicitly } else { // we need to implicitly create the root key aBaseKeyP = newSettingsRootKey(); implicit = true; // the root key is implicitly created and must be deleted implicitly as well } // open key if (implicit && (aPath==NULL || *aPath==0 || (*aPath==SETTINGSKEY_PATH_SEPARATOR && *(aPath+1)==0))) { // opening root requested aKeyP = aBaseKeyP; sta = LOCERR_OK; } else { // open subkey of current key sta = aBaseKeyP->OpenKeyByPath(aKeyP,aPath,aMode,implicit); } if (sta!=LOCERR_OK) { if (aKeyP) { // make sure all implicitly opened elements of the chain are deleted // (includes the TSettingsRootKey, if one was created above) delete aKeyP; } } else { // pass back pointer to opened key aNewKeyH = (KeyH)aKeyP; } return sta; } // TEngineInterface::OpenKeyByPath /// @brief open Settings subkey key by ID or iterating over all subkeys /// @param aNewKeyH[out] receives the opened key's handle on success /// @param aParentKeyH[in] handle to the parent key /// @param aID[in] the ID of the subkey to open, /// or KEYVAL_ID_FIRST/KEYVAL_ID_NEXT to iterate over existing subkeys /// or KEYVAL_ID_NEW to create a new subkey /// @param aMode[in] the open mode /// @return LOCERR_OK on success, DB_NoContent when no more subkeys are found with /// KEYVAL_ID_FIRST/KEYVAL_ID_NEXT /// or any other SyncML or LOCERR_xxx error code on failure TSyError TEngineInterface::OpenSubkey( KeyH &aNewKeyH, KeyH aParentKeyH, sInt32 aID, uInt16 aMode ) { TSettingsKeyImpl *baseKeyP = NULL; TSettingsKeyImpl *keyP = NULL; TSyError sta; // We need a parent key if (!aParentKeyH) return LOCERR_WRONGUSAGE; // Get key baseKeyP = reinterpret_cast(aParentKeyH); // now open subkey sta = baseKeyP->OpenSubkey(keyP,aID,aMode); if (sta == LOCERR_OK) { // return key handle aNewKeyH = (KeyH)keyP; } return sta; } // TEngineInterface::OpenSubkey /// @brief delete Settings subkey key by ID /// @param aID[in] the ID of the subkey to delete /// @param aParentKeyH[in] handle to the parent key /// @return LOCERR_OK on success /// or any other SyncML or LOCERR_xxx error code on failure TSyError TEngineInterface::DeleteSubkey(KeyH aParentKeyH, sInt32 aID) { // We need a parent key if (!aParentKeyH) return LOCERR_WRONGUSAGE; // Get key return reinterpret_cast(aParentKeyH)->DeleteSubkey(aID); } // TEngineInterface::DeleteSubkey /// @brief Get key ID of currently open key. Note that the Key ID is only locally unique within /// the parent key. /// @param aKeyH[in] an open key handle /// @param aID[out] receives the ID of the open key, which can be used to re-access the /// key within its parent using OpenSubkey() /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure TSyError TEngineInterface::GetKeyID(KeyH aKeyH, sInt32 &aID) { if (!aKeyH) return LOCERR_WRONGUSAGE; return reinterpret_cast(aKeyH)->GetKeyID(aID); } // TEngineInterface::GetKeyID /// @brief Set text format parameters /// @param aKeyH[in] an open key handle /// @param aCharSet[in] charset (default is UTF-8 when SetTextMode() is not used) /// @param aLineEndMode[in] line end mode (default is C-lineends of the platform (almost always LF) when SetTextMode() is not used) /// @param aBigEndian[in] determines endianness of UTF16 text (defaults to little endian = intel order) /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure TSyError TEngineInterface::SetTextMode(KeyH aKeyH, uInt16 aCharSet, uInt16 aLineEndMode, bool aBigEndian) { if (!aKeyH) return LOCERR_WRONGUSAGE; return reinterpret_cast(aKeyH)->SetTextMode(aCharSet,aLineEndMode,aBigEndian); } // TEngineInterface::SetTextMode /// @brief Set time format parameters /// @param aKeyH[in] an open key handle /// @param aTimeMode[in] time mode, see TMODE_xxx (default is platform's lineratime_t when SetTimeMode() is not used) /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure TSyError TEngineInterface::SetTimeMode(KeyH aKeyH, uInt16 aTimeMode) { if (!aKeyH) return LOCERR_WRONGUSAGE; return reinterpret_cast(aKeyH)->SetTimeMode(aTimeMode); } // TEngineInterface::SetTimeMode /// @brief Closes a key opened by OpenKeyByPath() or OpenSubKey() /// @param aKeyH[in] an open key handle. Will be invalid when call returns with LOCERR_OK. Do not re-use! /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure TSyError TEngineInterface::CloseKey(KeyH aKeyH) { if (aKeyH) { // deleting key will close it (including all implicitly opened parents) delete reinterpret_cast(aKeyH); } return LOCERR_OK; } // TEngineInterface::CloseKey /// @brief get value's ID for use with Get/SetValueByID() /// @return KEYVAL_ID_UNKNOWN when name is unknown, /// KEYVAL_NO_ID when name is known, but no ID exists for it (ID access not possible) /// ID of value otherwise sInt32 TEngineInterface::GetValueID(KeyH aKeyH, cAppCharP aName) { if (!aKeyH) return KEYVAL_ID_UNKNOWN; // make sure we have string as UTF-8 string tempStr; aName = makeAppString(aName, tempStr); return reinterpret_cast(aKeyH)->GetValueID(aName); } // TEngineInterface::GetValueID /// @brief Reads a named value in specified format into passed memory buffer /// @param aKeyH[in] an open key handle /// @param aValueName[in] name of the value to read /// @param aValType[in] desired return type, see VALTYPE_xxxx /// @param aBuffer[in/out] buffer where to store the data /// @param aBufSize[in] size of buffer in bytes (ALWAYS in bytes, even if value is Unicode string) /// @param aValSize[out] actual size of value. /// For VALTYPE_TEXT, size is string length (IN BYTES) excluding NULL terminator /// Note that this will be set also when return value is LOCERR_BUFTOOSMALL, to indicate the required buffer size /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure TSyError TEngineInterface::GetValue( KeyH aKeyH, cAppCharP aValueName, uInt16 aValType, appPointer aBuffer, memSize aBufSize, memSize &aValSize ) { if (!aKeyH) return LOCERR_WRONGUSAGE; // GetValueID will convert aValueName to app format if needed sInt32 valId = GetValueID(aKeyH,aValueName); if (valId==KEYVAL_ID_UNKNOWN) return DB_NotFound; // directly call settingsKeyImpl, for cases where value has no ID return reinterpret_cast(aKeyH)->GetValueByID( valId,0,aValType,aBuffer,aBufSize,aValSize ); } // GetValue /// @brief Reads value by ID in specified format into passed memory buffer /// @param aKeyH[in] an open key handle /// @param aID[in] ID of the value to read /// @param aArrayIndex[in] 0-based array element index for array values. /// @param aValType[in] desired return type, see VALTYPE_xxxx /// @param aBuffer[in/out] buffer where to store the data /// @param aBufSize[in] size of buffer in bytes (ALWAYS in bytes, even if value is Unicode string) /// @param aValSize[out] actual size of value. /// For VALTYPE_TEXT, size is string length (IN BYTES) excluding NULL terminator /// Note that this will be set also when return value is LOCERR_BUFTOOSMALL, to indicate the required buffer size /// @return LOCERR_OK on success, LOCERR_OUTOFRANGE when array index is out of range /// SyncML or LOCERR_xxx error code on other failure TSyError TEngineInterface::GetValueByID( KeyH aKeyH, sInt32 aID, sInt32 aArrayIndex, uInt16 aValType, appPointer aBuffer, memSize aBufSize, memSize &aValSize ) { if (!aKeyH) return LOCERR_WRONGUSAGE; if (aID==KEYVAL_NO_ID) return LOCERR_BADPARAM; return reinterpret_cast(aKeyH)->GetValueByID( aID,aArrayIndex,aValType,aBuffer,aBufSize,aValSize ); } // TEngineInterface::GetValueByID /// @brief Writes a named value in specified format passed in memory buffer /// @param aKeyH[in] an open key handle /// @param aValueName[in] name of the value to write /// @param aValType[in] type of value passed in, see VALTYPE_xxxx /// @param aBuffer[in] buffer containing the data /// @param aValSize[in] size of value. For VALTYPE_TEXT, size can be passed as -1 if string is null terminated /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure TSyError TEngineInterface::SetValue( KeyH aKeyH, cAppCharP aValueName, uInt16 aValType, cAppPointer aBuffer, memSize aValSize ) { if (!aKeyH) return LOCERR_WRONGUSAGE; // GetValueID will convert aValueName to app format if needed sInt32 valId = GetValueID(aKeyH,aValueName); if (valId==KEYVAL_ID_UNKNOWN) return DB_NotFound; return reinterpret_cast(aKeyH)->SetValueByID( valId,0,aValType,aBuffer,aValSize ); } // TEngineInterface::SetValue /// @brief Writes a named value in specified format passed in memory buffer /// @param aKeyH[in] an open key handle /// @param aID[in] ID of the value to read /// @param aArrayIndex[in] 0-based array element index for array values. /// @param aValType[in] type of value passed in, see VALTYPE_xxxx /// @param aBuffer[in] buffer containing the data /// @param aValSize[in] size of value. For VALTYPE_TEXT, size can be passed as -1 if string is null terminated /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure TSyError TEngineInterface::SetValueByID( KeyH aKeyH, sInt32 aID, sInt32 aArrayIndex, uInt16 aValType, cAppPointer aBuffer, memSize aValSize ) { if (!aKeyH) return LOCERR_WRONGUSAGE; if (aID==KEYVAL_NO_ID) return LOCERR_BADPARAM; return reinterpret_cast(aKeyH)->SetValueByID( aID,aArrayIndex,aValType,aBuffer,aValSize ); } // TEngineInterface::SetValueByID #ifdef DBAPI_TUNNEL_SUPPORT // DBApi-like access to datastores // =============================== TSyError TEngineInterface::StartDataRead(SessionH aSessionH, cAppCharP lastToken, cAppCharP resumeToken) { TLocalEngineDS *ds = reinterpret_cast(aSessionH)->getTunnelDS(); if (!ds) return LOCERR_WRONGUSAGE; // need properly opened tunnel session/datastore return ds->TunnelStartDataRead(lastToken,resumeToken); } // StartDataRead TSyError TEngineInterface::ReadNextItem(SessionH aSessionH, ItemID aID, appCharP *aItemData, sInt32 *aStatus, bool aFirst) { TLocalEngineDS *ds = reinterpret_cast(aSessionH)->getTunnelDS(); if (!ds) return LOCERR_WRONGUSAGE; // need properly opened tunnel session/datastore return ds->TunnelReadNextItem(aID,aItemData,aStatus,aFirst); } // ReadNextItem TSyError TEngineInterface::ReadItem(SessionH aSessionH, cItemID aID, appCharP *aItemData) { TLocalEngineDS *ds = reinterpret_cast(aSessionH)->getTunnelDS(); if (!ds) return LOCERR_WRONGUSAGE; // need properly opened tunnel session/datastore return ds->TunnelReadItem(aID,aItemData); } // ReadItem TSyError TEngineInterface::EndDataRead(SessionH aSessionH) { TLocalEngineDS *ds = reinterpret_cast(aSessionH)->getTunnelDS(); if (!ds) return LOCERR_WRONGUSAGE; // need properly opened tunnel session/datastore return ds->TunnelEndDataRead(); } // EndDataRead TSyError TEngineInterface::StartDataWrite(SessionH aSessionH) { TLocalEngineDS *ds = reinterpret_cast(aSessionH)->getTunnelDS(); if (!ds) return LOCERR_WRONGUSAGE; // need properly opened tunnel session/datastore return ds->TunnelStartDataWrite(); } // StartDataWrite TSyError TEngineInterface::InsertItem(SessionH aSessionH, cAppCharP aItemData, ItemID aID) { TLocalEngineDS *ds = reinterpret_cast(aSessionH)->getTunnelDS(); if (!ds) return LOCERR_WRONGUSAGE; // need properly opened tunnel session/datastore return ds->TunnelInsertItem(aItemData,aID); } // InsertItem TSyError TEngineInterface::UpdateItem(SessionH aSessionH, cAppCharP aItemData, cItemID aID, ItemID updID ) { TLocalEngineDS *ds = reinterpret_cast(aSessionH)->getTunnelDS(); if (!ds) return LOCERR_WRONGUSAGE; // need properly opened tunnel session/datastore return ds->TunnelUpdateItem(aItemData,aID,updID); } // UpdateItem TSyError TEngineInterface::MoveItem(SessionH aSessionH, cItemID aID, cAppCharP newParID) { TLocalEngineDS *ds = reinterpret_cast(aSessionH)->getTunnelDS(); if (!ds) return LOCERR_WRONGUSAGE; // need properly opened tunnel session/datastore return ds->TunnelMoveItem(aID,newParID); } // MoveItem TSyError TEngineInterface::DeleteItem(SessionH aSessionH, cItemID aID) { TLocalEngineDS *ds = reinterpret_cast(aSessionH)->getTunnelDS(); if (!ds) return LOCERR_WRONGUSAGE; // need properly opened tunnel session/datastore return ds->TunnelDeleteItem(aID); } // DeleteItem TSyError TEngineInterface::EndDataWrite(SessionH aSessionH, bool success, appCharP *newToken) { TLocalEngineDS *ds = reinterpret_cast(aSessionH)->getTunnelDS(); if (!ds) return LOCERR_WRONGUSAGE; // need properly opened tunnel session/datastore return ds->TunnelEndDataWrite(success,newToken); } // EndDataWrite void TEngineInterface::DisposeObj(SessionH aSessionH, void* memory) { TLocalEngineDS *ds = reinterpret_cast(aSessionH)->getTunnelDS(); if (!ds) return; // need properly opened tunnel session/datastore return ds->TunnelDisposeObj(memory); } // DisposeObj // ---- asKey ---- TSyError TEngineInterface::ReadNextItemAsKey(SessionH aSessionH, ItemID aID, KeyH aItemKey, sInt32 *aStatus, bool aFirst) { TLocalEngineDS *ds = reinterpret_cast(aSessionH)->getTunnelDS(); if (!ds) return LOCERR_WRONGUSAGE; // need properly opened tunnel session/datastore return ds->TunnelReadNextItemAsKey(aID,aItemKey,aStatus,aFirst); } // ReadNextItemAsKey TSyError TEngineInterface::ReadItemAsKey(SessionH aSessionH, cItemID aID, KeyH aItemKey) { TLocalEngineDS *ds = reinterpret_cast(aSessionH)->getTunnelDS(); if (!ds) return LOCERR_WRONGUSAGE; // need properly opened tunnel session/datastore return ds->TunnelReadItemAsKey(aID,aItemKey); } // ReadItemAsKey TSyError TEngineInterface::InsertItemAsKey(SessionH aSessionH, KeyH aItemKey, ItemID aID) { TLocalEngineDS *ds = reinterpret_cast(aSessionH)->getTunnelDS(); if (!ds) return LOCERR_WRONGUSAGE; // need properly opened tunnel session/datastore return ds->TunnelInsertItemAsKey(aItemKey,aID); } // InsertItemAsKey TSyError TEngineInterface::UpdateItemAsKey(SessionH aSessionH, KeyH aItemKey, cItemID aID, ItemID updID) { TLocalEngineDS *ds = reinterpret_cast(aSessionH)->getTunnelDS(); if (!ds) return LOCERR_WRONGUSAGE; // need properly opened tunnel session/datastore return ds->TunnelUpdateItemAsKey(aItemKey,aID,updID); } // UpdateItemAsKey #endif // DBAPI_TUNNEL_SUPPORT TSyError TEngineInterface::debugPuts(cAppCharP aFile, int aLine, cAppCharP aFunction, int aDbgLevel, cAppCharP aPrefix, cAppCharP aText) { #if defined(SYDEBUG) // Including the prefix as meta-data would be better, because it would // allow formatting it, for example in HTML. Instead of // dropping it entirely, at least mix into the normal text. if (aPrefix) { std::string body = aPrefix; if (aText) { body += ": "; body += aText; } getSyncAppBase()->getDbgLogger()->DebugPuts(TDBG_LOCATION_ARGS(aFunction, aFile, aLine /*, aPrefix */) aDbgLevel, body.c_str()); } else { getSyncAppBase()->getDbgLogger()->DebugPuts(TDBG_LOCATION_ARGS(aFunction, aFile, aLine) aDbgLevel, aText); } return 0; #else return LOCERR_NOTIMP; #endif } // debugPuts #ifdef ENGINE_LIBRARY #ifndef SIMPLE_LINKING // Callback "factory" function implementation static TSyError internal_ConnectEngine( bool aIsServer, UI_Call_In *aCIP, uInt16 aCallbackVersion, // if==0, engine creates new aCI CVersion *aEngVersionP, CVersion aPrgVersion, uInt16 aDebugFlags ) { // create new engine TEngineModuleBase *engine = NULL; TSyError err = LOCERR_OK; if (aIsServer) { #ifdef SYSYNC_SERVER engine = newServerEngine(); #else err = LOCERR_WRONGUSAGE; #endif } else { #ifdef SYSYNC_CLIENT engine = newClientEngine(); #else err = LOCERR_WRONGUSAGE; #endif } if (err==LOCERR_OK) { // connect the engine if (aCallbackVersion!=0) { // valid aCIP passed in // - flag static engine->fCIisStatic= true; // - prepare callback and pass to engine (*aCIP)->callbackVersion = aCallbackVersion; // fill in the outside callback version engine->fCI = *aCIP; // engine uses the structure provided by the uiapp // - connect the engine err = engine->Connect("", aPrgVersion, aDebugFlags); } else { // no aCIP passed, let engine create one // - connect engine err = engine->Connect("", aPrgVersion, aDebugFlags); // - get CI from engine *aCIP = engine->fCI; } // - get the version if (aEngVersionP) *aEngVersionP = Plugin_Version(0); } return err; } // internal_ConnectEngine // Client engine main entry point TSyError SYSYNC_EXTERNAL(ConnectEngine)( UI_Call_In *aCI, CVersion *aEngVersion, CVersion aPrgVersion, uInt16 aDebugFlags ) { return internal_ConnectEngine(false, aCI, 0, aEngVersion, aPrgVersion, aDebugFlags); } // ConnectEngine // The same, but coming in with a valid */ TSyError SYSYNC_EXTERNAL(ConnectEngineS)( UI_Call_In aCI, uInt16 aCallbackVersion, CVersion *aEngVersion, CVersion aPrgVersion, uInt16 aDebugFlags ) { return internal_ConnectEngine(false, &aCI, aCallbackVersion, aEngVersion, aPrgVersion, aDebugFlags); } // ConnectEngineS // Server engine main entry point TSyError SYSYNC_EXTERNAL_SRV(ConnectEngine)( UI_Call_In *aCI, CVersion *aEngVersion, CVersion aPrgVersion, uInt16 aDebugFlags ) { return internal_ConnectEngine(true, aCI, 0, aEngVersion, aPrgVersion, aDebugFlags); } // ConnectEngine // The same, but coming in with a valid */ TSyError SYSYNC_EXTERNAL_SRV(ConnectEngineS)( UI_Call_In aCI, uInt16 aCallbackVersion, CVersion *aEngVersion, CVersion aPrgVersion, uInt16 aDebugFlags ) { return internal_ConnectEngine(true, &aCI, aCallbackVersion, aEngVersion, aPrgVersion, aDebugFlags); } // ConnectEngineS static TSyError internal_DisconnectEngine(UI_Call_In aCI) { TSyError err= LOCERR_OK; if (aCI && aCI->thisBase) { // structure must still exist // first get pointer to engine TEngineModuleBase *engine = static_cast(aCI->thisBase); err= engine->Disconnect(); aCI->thisBase= NULL; // no longer valid // delete the engine (this also deletes the callback!) SYSYNC_TRY { delete engine; } SYSYNC_CATCH (...) err = LOCERR_EXCEPTION; SYSYNC_ENDCATCH // done } // if return err; } // internal_DisconnectEngine /* Entry point to disconnect client engine */ TSyError SYSYNC_EXTERNAL(DisconnectEngine)(UI_Call_In aCI) { return internal_DisconnectEngine(aCI); } /* Entry point to disconnect server engine */ TSyError SYSYNC_EXTERNAL_SRV(DisconnectEngine)(UI_Call_In aCI) { return internal_DisconnectEngine(aCI); } #endif // not SIMPLE_LINKING #endif // ENGINE_LIBRARY } // namespace sysync /* end of TEngineInterface implementation */ #endif // ENGINEINTERFACE_SUPPORT // eof libsynthesis-3.4.0.47.1/src/sysync/engineinterface.h000077500000000000000000001006011226375725500222630ustar00rootroot00000000000000/** * @File engineinterface.h * * @Author Lukas Zeller (luz@plan44.ch) * * @brief TEngineInterface - common interface to SySync engine for SDK * * Copyright (c) 2007-2011 by Synthesis AG + plan44.ch * */ /* */ #ifndef ENGINEINTERFACE_H #define ENGINEINTERFACE_H #ifdef ENGINEINTERFACE_SUPPORT // published engine definitions #include "engine_defs.h" // internal sysync engine definitions #include "sysync.h" #include "syserial.h" // decide if using with EngineModuleBase class #ifdef SIMPLE_LINKING #define EMBVIRTUAL #else #include "enginemodulebase.h" #define EMBVIRTUAL virtual #endif // DBAPI tunnel support #ifdef DBAPI_TUNNEL_SUPPORT #define TUNNEL_IMPL #define TUNNEL_IMPL_VOID #else #define TUNNEL_IMPL { return LOCERR_NOTIMP; } #define TUNNEL_IMPL_VOID {} #endif using namespace std; namespace sysync { // forward class TEngineInterface; class TSyncAppBase; #ifdef SIMPLE_LINKING // for using the engineInterface without EngineModuleBase, engine base class // for the newXXXXEngine() functions is TEngineInterface #define ENGINE_IF_CLASS TEngineInterface // factory function declarations are here, as we have no EngineModuleBase #ifdef SYSYNC_CLIENT ENGINE_IF_CLASS *newClientEngine(void); #endif #ifdef SYSYNC_SERVER ENGINE_IF_CLASS *newServerEngine(void); #endif #else // with EngineModuleBase, use it as base class. newXXXXXEngine are declared in // enginemodulebase.h #define ENGINE_IF_CLASS TEngineModuleBase #endif // settings key implementation base class class TSettingsKeyImpl : noncopyable { public: TSettingsKeyImpl(TEngineInterface *aEngineInterfaceP); virtual ~TSettingsKeyImpl(); // open subkey(chain) by relative(!) path // - walks down through needed subkeys, always starting at myself TSyError OpenKeyByPath( TSettingsKeyImpl *&aSettingsKeyP, cAppCharP aPath, uInt16 aMode, bool aImplicit ); // open Settings subkey key by ID or iterating over all subkeys virtual TSyError OpenSubkey( TSettingsKeyImpl *&aSettingsKeyP, sInt32 aID, uInt16 aMode ) { // by default, opening by key is not allowed (only if derived class implements it) return DB_NotAllowed; }; // delete Settings subkey key by ID virtual TSyError DeleteSubkey(sInt32 aID) { // by default, keys cannot be deleted return DB_NotAllowed; }; // return ID of current key virtual TSyError GetKeyID(sInt32 &aID) { // by default, key has no ID access to subkeys return DB_NotAllowed; }; // get value's ID (e.g. internal index) virtual sInt32 GetValueID(cAppCharP aName) { return KEYVAL_ID_UNKNOWN; // unknown }; // Set text format parameters TSyError SetTextMode(uInt16 aCharSet, uInt16 aLineEndMode, bool aBigEndian); // Set text format parameters TSyError SetTimeMode(uInt16 aTimeMode) { fTimeMode = aTimeMode; return LOCERR_OK; }; // Reads a named value in specified format into passed memory buffer TSyError GetValueByID( sInt32 aID, sInt32 aArrayIndex, uInt16 aValType, appPointer aBuffer, memSize aBufSize, memSize &aValSize ); // Writes a named value in specified format passed in memory buffer TSyError SetValueByID( sInt32 aID, sInt32 aArrayIndex, uInt16 aValType, cAppPointer aBuffer, memSize aValSize ); // get engine interface TEngineInterface *getEngineInterface(void) { return fEngineInterfaceP; }; protected: // open subkey by name (not by path!) // - this is the actual implementation virtual TSyError OpenSubKeyByName( TSettingsKeyImpl *&aSettingsKeyP, cAppCharP aName, stringSize aNameSize, uInt16 aMode ) { // by default, no key can be found (derived class must implement it) return DB_NotFound; }; // get value's native type // Note: this must be safe if aID is out of range and must return VALTYPE_UNKNOWN if so. virtual uInt16 GetValueType(sInt32 aID) { return VALTYPE_UNKNOWN; // unknown }; // Internal Get Value in internal format. // Notes: // - all values, even strings can be returned as bare data (no NUL terminator needed, but allowed for VALTYPE_TEXT) // - in all cases, no more than aBufSize bytes may be copied (and in case of strings, if aBufSize equals the string // size, the routine must return the entire string data, even if this means omitting the terminator) // - in all cases, aValSize must return the actual size of the entire value, regardless of how many bytes could // actually be copied. Note that this is UNLIKE aValSize for the exposed API GetValue(), which always returns // the number of bytes returned, even if these are truncated. virtual TSyError GetValueInternal( sInt32 aID, sInt32 aArrayIndex, appPointer aBuffer, memSize aBufSize, memSize &aValSize ) { // By default, there are no values return DB_NotAllowed; }; // set value virtual TSyError SetValueInternal( sInt32 aID, sInt32 aArrayIndex, cAppPointer aBuffer, memSize aValSize ) { // By default, there are no values return DB_NotAllowed; }; // helper for detecting generic field attribute access bool checkFieldAttrs(cAppCharP aName, size_t &aBaseNameSize, sInt32 &aFldID); // helper for returning generic field attribute type bool checkAttrValueType(sInt32 aID, uInt16 &aValType); // helper for returning generic field attribute values bool checkAttrValue( sInt32 aID, sInt32 aArrayIndex, appPointer aBuffer, memSize aBufSize, memSize &aValSize ); // the engine interface TEngineInterface *fEngineInterfaceP; // Value format modes TCharSets fCharSet; bool fBigEndian; TLineEndModes fLineEndMode; uInt16 fTimeMode; private: // link to implicitly opened parent (when opening via OpenKeyByPath) TSettingsKeyImpl *fImplicitParentKeyP; }; // TSettingsKeyImpl // Table for TReadOnlyInfoKey typedef struct { cAppCharP valName; // null for terminator uInt16 valType; appPointer valPtr; memSize valSiz; // size of var or 0 for autosize for null terminated strings } TReadOnlyInfo; // key delivering constant infos class TReadOnlyInfoKey : public TSettingsKeyImpl { typedef TSettingsKeyImpl inherited; public: TReadOnlyInfoKey(TEngineInterface *aEngineInterfaceP) : inherited(aEngineInterfaceP) {}; // get value's ID (e.g. internal index) virtual sInt32 GetValueID(cAppCharP aName); protected: // get value's native type virtual uInt16 GetValueType(sInt32 aID); // get value virtual TSyError GetValueInternal( sInt32 aID, sInt32 aArrayIndex, appPointer aBuffer, memSize aBufSize, memSize &aValSize ); virtual const TReadOnlyInfo *getInfoTable(void) = 0; virtual sInt32 numInfos(void) = 0; private: // iterator uInt16 fIterator; }; // TReadOnlyInfoKey // key for accessing global config vars class TConfigVarKey : public TSettingsKeyImpl { typedef TSettingsKeyImpl inherited; public: TConfigVarKey(TEngineInterface *aEngineInterfaceP) : inherited(aEngineInterfaceP) {}; // get value's ID (config vars do NOT have an ID!) virtual sInt32 GetValueID(cAppCharP aName); protected: // get value's native type (all config vars are text) virtual uInt16 GetValueType(sInt32 aID); // get value virtual TSyError GetValueInternal( sInt32 aID, sInt32 aArrayIndex, appPointer aBuffer, memSize aBufSize, memSize &aValSize ); // set value virtual TSyError SetValueInternal( sInt32 aID, sInt32 aArrayIndex, cAppPointer aBuffer, memSize aValSize ); private: // cached name of last variable name used (to get around IDs) string fVarName; }; // TConfigVarKey // forward class TStructFieldsKey; typedef struct TStructFieldInfo TStructFieldInfo; // function prototype to get values typedef TSyError (*TGetValueProc)( TStructFieldsKey *aStructFieldsKeyP, const TStructFieldInfo *aFldInfoP, appPointer aBuffer, memSize aBufSize, memSize &aValSize ); // function prototype to set values typedef TSyError (*TSetValueProc)( TStructFieldsKey *aStructFieldsKeyP, const TStructFieldInfo *aFldInfoP, cAppPointer aBuffer, memSize aValSize ); // Table for TStructFieldsKey typedef struct TStructFieldInfo { cAppCharP valName; // null for terminator uInt16 valType; bool writable; // set if field can be written size_t fieldOffs; // offset of field from beginning of structure size_t valSiz; // size of field in bytes, if 0, only get/setValueProc access is possible (and if these are not defined, access is not allowed) TGetValueProc getValueProc; // if not NULL, this routine is called instead of reading data directly TSetValueProc setValueProc; // if not NULL, this routine is called instead of writing data directly } TStructFieldInfo; // key for access to a struct containing settings fields class TStructFieldsKey : public TSettingsKeyImpl { typedef TSettingsKeyImpl inherited; public: TStructFieldsKey(TEngineInterface *aEngineInterfaceP) : inherited(aEngineInterfaceP), fDirty(false), fIterator(0) {}; // get value's ID (e.g. internal index) virtual sInt32 GetValueID(cAppCharP aName); // Static helpers // - static helper for procedural string readers static TSyError returnString(cAppCharP aReturnString, appPointer aBuffer, memSize aBufSize, memSize &aValSize); static TSyError returnInt(sInt32 aInt, memSize aIntSize, appPointer aBuffer, memSize aBufSize, memSize &aValSize); static TSyError returnLineartime(lineartime_t aTime, appPointer aBuffer, memSize aBufSize, memSize &aValSize); protected: // get value's native type virtual uInt16 GetValueType(sInt32 aID); // get value virtual TSyError GetValueInternal( sInt32 aID, sInt32 aArrayIndex, appPointer aBuffer, memSize aBufSize, memSize &aValSize ); // set value virtual TSyError SetValueInternal( sInt32 aID, sInt32 aArrayIndex, cAppPointer aBuffer, memSize aValSize ); // get table describing the fields in the struct virtual const TStructFieldInfo *getFieldsTable(void) { return NULL; }; virtual sInt32 numFields(void) { return 0; }; // get actual struct base address virtual uInt8P getStructAddr(void) { return NULL; }; // flag that will be set on first write access bool fDirty; private: // iterator uInt16 fIterator; }; // TStructFieldsKey // Engine info static const uInt16 variantCode = SYSER_VARIANT_CODE; static const TReadOnlyInfo EngineInfoTable[] = { // name, type, ptr, siz { "version", VALTYPE_TEXT, (appPointer)SYSYNC_FULL_VERSION_STRING, 0 }, { "platform", VALTYPE_TEXT, (appPointer)SYSYNC_PLATFORM_NAME, 0 }, { "name", VALTYPE_TEXT, (appPointer)CUST_SYNC_MODEL, 0 }, { "manufacturer", VALTYPE_TEXT, (appPointer)CUST_SYNC_MAN, 0 }, { "comment", VALTYPE_TEXT, (appPointer)VERSION_COMMENTS, 0 }, // other build infos { "variantcode", VALTYPE_INT16, (appPointer)&variantCode, 2 }, // Note: productcode and extraid are already available as configvars }; class TEngineInfoKey : public TReadOnlyInfoKey { typedef TReadOnlyInfoKey inherited; public: TEngineInfoKey(TEngineInterface *aEngineInterfaceP) : inherited(aEngineInterfaceP) {}; protected: virtual const TReadOnlyInfo *getInfoTable(void) { return EngineInfoTable; }; virtual sInt32 numInfos(void) { return sizeof(EngineInfoTable)/sizeof(TReadOnlyInfo); }; }; // TEngineInfoKey // Licensing #ifdef SYSER_REGISTRATION class TLicensingKey : public TStructFieldsKey { typedef TStructFieldsKey inherited; public: TLicensingKey(TEngineInterface *aEngineInterfaceP) : inherited(aEngineInterfaceP) {}; protected: // get table describing the fields in the struct virtual const TStructFieldInfo *getFieldsTable(void); virtual sInt32 numFields(void); // get actual struct base address virtual uInt8P getStructAddr(void); }; // TLicensingKey #endif // Generic root key, providing settings keys common to all // SySync applications class TSettingsRootKey : public TSettingsKeyImpl { typedef TSettingsKeyImpl inherited; public: TSettingsRootKey(TEngineInterface *aEngineInterfaceP) : inherited(aEngineInterfaceP) {}; protected: // open subkey by name (not by path!) // - this is the actual implementation virtual TSyError OpenSubKeyByName( TSettingsKeyImpl *&aSettingsKeyP, cAppCharP aName, stringSize aNameSize, uInt16 aMode ) { if (strucmp(aName,"engineinfo",aNameSize)==0) aSettingsKeyP = new TEngineInfoKey(fEngineInterfaceP); else if (strucmp(aName,"configvars",aNameSize)==0) aSettingsKeyP = new TConfigVarKey(fEngineInterfaceP); #ifdef SYSER_REGISTRATION else if (strucmp(aName,"licensing",aNameSize)==0) aSettingsKeyP = new TLicensingKey(fEngineInterfaceP); #endif else return inherited::OpenSubKeyByName(aSettingsKeyP,aName,aNameSize,aMode); // opened a key return LOCERR_OK; }; }; // TSettingsRootKey // Common Engine Interface class TEngineInterface : #ifdef SIMPLE_LINKING noncopyable #else public TEngineModuleBase #endif { #ifndef SIMPLE_LINKING typedef TEngineModuleBase inherited; #endif friend class TSettingsKeyImpl; public: TEngineInterface(); // constructor virtual ~TEngineInterface(); // destructor /// @brief Object init, usually called at connect time /// @note needed to allow virtual call to newSyncAppBase() factory function EMBVIRTUAL TSyError Init(void); EMBVIRTUAL TSyError Term(void); // Engine init // ----------- /// @brief Set the global mode for string paramaters (when never called, default params are UTF-8 with C-style line ends) /// @param aCharSet[in] charset /// @param aLineEndMode[in] line end mode (default is C-lineends of the platform (almost always LF)) /// @param aBigEndian[in] determines endianness of UTF16 text (defaults to little endian = intel order) /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure EMBVIRTUAL TSyError SetStringMode(uInt16 aCharSet, uInt16 aLineEndMode=LEM_CSTR, bool aBigEndian=false); /// @brief init object, optionally passing XML config text in memory /// @param aConfigXML[in] NULL or empty string if no external config needed, config text otherwise /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure EMBVIRTUAL TSyError InitEngineXML(cAppCharP aConfigXML); /// @brief init object, optionally passing a open FILE for reading config /// @param aConfigFilePath[in] path to config file /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure EMBVIRTUAL TSyError InitEngineFile(cAppCharP aConfigFilePath); /// @brief init object, optionally passing a callback for reading config /// @param aReaderFunc[in] callback function which can deliver next chunk of XML config data /// @param aContext[in] free context pointer passed back with callback /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure EMBVIRTUAL TSyError InitEngineCB(TXMLConfigReadFunc aReaderFunc, void *aContext); // Running a Sync Session // ---------------------- /// @brief Open a session /// @param aNewSessionH[out] receives session handle for all session execution calls /// @param aSelector[in] selector, depending on session type. For multi-profile clients: profile ID to use /// @param aSessionName[in] a text name/id to identify a session, useage depending on session type. /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure EMBVIRTUAL TSyError OpenSession(SessionH &aNewSessionH, uInt32 aSelector=0, cAppCharP aSessionName=NULL); protected: // internal implementation, sessionname already in application format virtual TSyError OpenSessionInternal(SessionH &aNewSessionH, uInt32 aSelector, cAppCharP aSessionName); public: /// @brief open session specific runtime parameter/settings key /// @note key handle obtained with this call must be closed BEFORE SESSION IS CLOSED! /// @param aNewKeyH[out] receives the opened key's handle on success /// @param aSessionH[in] session handle obtained with OpenSession. /// When used as callback from DBApi, this parameter is irrelevant and /// must be set to NULL as a callback from DBApi has an implicit session context /// automatically. /// @param aMode[in] the open mode /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure virtual TSyError OpenSessionKey(SessionH aSessionH, KeyH &aNewKeyH, uInt16 aMode); /// @brief Close a session /// @note It depends on session type if this also destroys the session or if it may persist and can be re-opened. /// @param aSessionH[in] session handle obtained with OpenSession /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure virtual TSyError CloseSession(SessionH aSessionH); /// @brief Executes sync session or other sync related activity step by step /// @param aSessionH[in] session handle obtained with OpenSession /// @param aStepCmd[in/out] step command (STEPCMD_xxx): /// - tells caller to send or receive data or end the session etc. /// - instructs engine to suspend or abort the session etc. /// @param aInfoP[in] pointer to a TEngineProgressInfo structure, NULL if no progress info needed /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure virtual TSyError SessionStep(SessionH aSessionH, uInt16 &aStepCmd, TEngineProgressInfo *aInfoP = NULL); /// @brief Get access to SyncML message buffer /// @param aSessionH[in] session handle obtained with OpenSession /// @param aBuffer[out] receives pointer to buffer (empty for receive, full for send) /// @param aBufSize[out] receives size of empty or full buffer /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure EMBVIRTUAL TSyError GetSyncMLBuffer(SessionH aSessionH, bool aForSend, appPointer &aBuffer, memSize &aBufSize); /// @brief Return SyncML message buffer to engine /// @param aSessionH[in] session handle obtained with OpenSession /// @param aProcessed[in] number of bytes put into or read from the buffer /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure EMBVIRTUAL TSyError RetSyncMLBuffer(SessionH aSessionH, bool aForSend, memSize aProcessed); /// @brief Read data from SyncML message buffer /// @param aSessionH[in] session handle obtained with OpenSession /// @param aBuffer[in] pointer to buffer /// @param aBufSize[in] size of buffer, maximum to be read /// @param aMsgSize[out] size of data available in the buffer for read INCLUDING just returned data. /// @note If the aBufSize is too small to return all available data LOCERR_TRUNCATED will be returned, and the /// caller can repeat calls to ReadSyncMLBuffer to get the next chunk. /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure EMBVIRTUAL TSyError ReadSyncMLBuffer (SessionH aSessionH, appPointer aBuffer, memSize aBufSize, memSize &aMsgSize); /// @brief Write data to SyncML message buffer /// @param aSessionH[in] session handle obtained with OpenSession /// @param aBuffer[in] pointer to buffer /// @param aMsgSize[in] size of message to write to the buffer /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure EMBVIRTUAL TSyError WriteSyncMLBuffer(SessionH aSessionH, appPointer aBuffer, memSize aMsgSize); // Settings access // --------------- /// @brief open Settings key by path specification /// @param aNewKeyH[out] receives the opened key's handle on success /// @param aParentKeyH[in] NULL if path is absolute from root, handle to an open key for relative access /// @param aPath[in] the path specification as null terminated string /// @param aMode[in] the open mode /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure EMBVIRTUAL TSyError OpenKeyByPath ( KeyH &aNewKeyH, KeyH aParentKeyH, cAppCharP aPath, uInt16 aMode ); /// @brief open Settings subkey key by ID or iterating over all subkeys /// @param aNewKeyH[out] receives the opened key's handle on success /// @param aParentKeyH[in] handle to the parent key (NULL = root key) /// @param aID[in] the ID of the subkey to open, /// or KEYVAL_ID_FIRST/KEYVAL_ID_NEXT to iterate over existing subkeys, returns DB_NoContent when no more found /// or KEYVAL_ID_NEW(_xxx) to create a new subkey /// @param aMode[in] the open mode /// @return LOCERR_OK on success, DB_NoContent when no more subkeys are found with /// KEYVAL_ID_FIRST/KEYVAL_ID_NEXT /// or any other SyncML or LOCERR_xxx error code on failure EMBVIRTUAL TSyError OpenSubkey( KeyH &aNewKeyH, KeyH aParentKeyH, sInt32 aID, uInt16 aMode ); /// @brief delete Settings subkey key by ID /// @param aParentKeyH[in] handle to the parent key /// @param aID[in] the ID of the subkey to delete /// @return LOCERR_OK on success /// or any other SyncML or LOCERR_xxx error code on failure EMBVIRTUAL TSyError DeleteSubkey(KeyH aParentKeyH, sInt32 aID); /// @brief Get key ID of currently open key. Note that the Key ID is only locally unique within /// the parent key. /// @param aKeyH[in] an open key handle /// @param aID[out] receives the ID of the open key, which can be used to re-access the /// key within its parent using OpenSubkey() /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure EMBVIRTUAL TSyError GetKeyID(KeyH aKeyH, sInt32 &aID); /// @brief Set text format parameters (when never called, default params are those set with global SetStringMode()) /// @param aKeyH[in] an open key handle /// @param aCharSet[in] charset /// @param aLineEndMode[in] line end mode (defaults to C-lineends of the platform (almost always LF)) /// @param aBigEndian[in] determines endianness of UTF16 text (defaults to little endian = intel order) /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure EMBVIRTUAL TSyError SetTextMode(KeyH aKeyH, uInt16 aCharSet, uInt16 aLineEndMode=LEM_CSTR, bool aBigEndian=false); /// @brief Set time format parameters /// @param aKeyH[in] an open key handle /// @param aTimeMode[in] time mode, see TMODE_xxx (default is platform's lineratime_t when SetTimeMode() is not used) /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure EMBVIRTUAL TSyError SetTimeMode(KeyH aKeyH, uInt16 aTimeMode); /// @brief Closes a key opened by OpenKeyByPath() or OpenSubKey() /// @param aKeyH[in] an open key handle. Will be invalid when call returns with LOCERR_OK. Do not re-use! /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure EMBVIRTUAL TSyError CloseKey(KeyH aKeyH); /// @brief Reads a named value in specified format into passed memory buffer /// @param aKeyH[in] an open key handle /// @param aValueName[in] name of the value to read. Some keys offer special ".XXX" /// suffixes (VALSUFF_XXX) to value names, which return alternate values (like a timestamp field's /// time zone name with ".TZNAME"). /// @param aValType[in] desired return type, see VALTYPE_xxxx /// @param aBuffer[in/out] buffer where to store the data /// @param aBufSize[in] size of buffer in bytes (ALWAYS in bytes, even if value is Unicode string) /// Note: to get only size of a value (useful especially for strings), pass 0 as buffer size. /// @param aValSize[out] actual size of value. /// For VALTYPE_TEXT, size is string length (IN BYTES) excluding NULL terminator /// Note that this will be set also when return value is LOCERR_BUFTOOSMALL, /// to indicate the required buffer size (buffer contents is undefined in case of LOCERR_BUFTOOSMALL). /// For values that can be truncated (strings), LOCERR_TRUNCATED will be returned /// when returned value is not entire value - aValSize is truncated size then. Use /// a call with aBufSize==0 to determine actual value size in bytes. Add one character size /// to the buffer size in case of VALTYPE_TEXT for the NUL terminator. /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure EMBVIRTUAL TSyError GetValue( KeyH aKeyH, cAppCharP aValueName, uInt16 aValType, appPointer aBuffer, memSize aBufSize, memSize &aValSize ); /// @brief Writes a named value in specified format passed in memory buffer /// @param aKeyH[in] an open key handle /// @param aValueName[in] name of the value to write. Some keys offer special ".XXX" /// suffixes (VALSUFF_XXX) to value names, which are used to set alternate values (like a /// timestamp field's time zone name with ".TZNAME"). /// @param aValType[in] type of value passed in, see VALTYPE_xxxx /// @param aBuffer[in] buffer containing the data /// @param aValSize[in] size of value. For VALTYPE_TEXT, size can be passed as -1 if string is null terminated /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure. If value /// buffer passed in is too small for aValType (such as only 2 bytes for a VALTYPE_INT32, /// LOCERR_BUFTOOSMALL will be returned and nothing stored. If buffer passed in is too /// long (e.g. for strings) to be entirely stored, only the beginning is stored and /// LOCERR_TRUNCATED is returned. EMBVIRTUAL TSyError SetValue( KeyH aKeyH, cAppCharP aValueName, uInt16 aValType, cAppPointer aBuffer, memSize aValSize ); /// @brief get value's ID for use with Get/SetValueByID() /// @param aKeyH[in] an open key handle /// @param aName[in] name of the value to write. Some keys offer special ".FLAG.XXX" /// values, which return flag bits which can be added to the regular ID to obtain /// alternate values (like the value name with ".FLAG.VALNAME", useful when iterating /// over values). /// @return KEYVAL_ID_UNKNOWN when no ID available for name, ID of value otherwise EMBVIRTUAL sInt32 GetValueID(KeyH aKeyH, cAppCharP aName); /// @brief Reads a named value in specified format into passed memory buffer /// @param aKeyH[in] an open key handle /// @param aID[in] ID of the value to read (evenually plus flag mask obtained by GetValueID(".FLAG.XXX") call) /// @param aArrayIndex[in] 0-based array element index for array values. /// @param aValType[in] desired return type, see VALTYPE_xxxx /// @param aBuffer[in/out] buffer where to store the data /// @param aBufSize[in] size of buffer in bytes (ALWAYS in bytes, even if value is Unicode string) /// Note: to get only size of a value (useful especially for strings), pass 0 as buffer size. /// @param aValSize[out] actual size of value. /// For VALTYPE_TEXT, size is string length (IN BYTES) excluding NULL terminator /// Note that this will be set also when return value is LOCERR_BUFTOOSMALL, /// to indicate the required buffer size (buffer contents is undefined in case of LOCERR_BUFTOOSMALL). /// For values that can be truncated (strings), LOCERR_TRUNCATED will be returned /// when returned value is not entire value - aValSize is truncated size then. Use /// a call with aBufSize==0 to determine actual value size in bytes. Add one character size /// to the buffer size in case of VALTYPE_TEXT for the NUL terminator. /// @return LOCERR_OK on success, LOCERR_OUTOFRANGE when array index is out of range /// SyncML or LOCERR_xxx error code on other failure. EMBVIRTUAL TSyError GetValueByID( KeyH aKeyH, sInt32 aID, sInt32 aArrayIndex, uInt16 aValType, appPointer aBuffer, memSize aBufSize, memSize &aValSize ); /// @brief Writes a named value in specified format passed in memory buffer /// @param aKeyH[in] an open key handle /// @param aID[in] ID of the value to write (evenually plus flag mask obtained by GetValueID(".FLAG.XXX") call) /// @param aArrayIndex[in] 0-based array element index for array values. /// @param aValType[in] type of value passed in, see VALTYPE_xxxx /// @param aBuffer[in] buffer containing the data /// @param aValSize[in] size of value. For VALTYPE_TEXT, size can be passed as -1 if string is null terminated /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure. If value /// buffer passed in is too small for aValType (such as only 2 bytes for a VALTYPE_INT32, /// LOCERR_BUFTOOSMALL will be returned and nothing stored. If buffer passed in is too /// long (e.g. for strings) to be entirely stored, only the beginning is stored and /// LOCERR_TRUNCATED is returned. EMBVIRTUAL TSyError SetValueByID( KeyH aKeyH, sInt32 aID, sInt32 aArrayIndex, uInt16 aValType, cAppPointer aBuffer, memSize aValSize ); /// @name DB-Api-like access to datastore adaptor (eg. when using tunnel plugin) /// @note These all return LOCERR_NOTIMP when DBAPI_TUNNEL_SUPPORT is not defined /// /// @{ EMBVIRTUAL TSyError StartDataRead ( SessionH aSessionH, cAppCharP lastToken, cAppCharP resumeToken ) TUNNEL_IMPL; EMBVIRTUAL TSyError ReadNextItem ( SessionH aSessionH, ItemID aID, appCharP *aItemData, sInt32 *aStatus, bool aFirst ) TUNNEL_IMPL; EMBVIRTUAL TSyError ReadItem ( SessionH aSessionH, cItemID aID, appCharP *aItemData ) TUNNEL_IMPL; EMBVIRTUAL TSyError EndDataRead ( SessionH aSessionH ) TUNNEL_IMPL; EMBVIRTUAL TSyError StartDataWrite ( SessionH aSessionH ) TUNNEL_IMPL; EMBVIRTUAL TSyError InsertItem ( SessionH aSessionH, cAppCharP aItemData, ItemID aID ) TUNNEL_IMPL; EMBVIRTUAL TSyError UpdateItem ( SessionH aSessionH, cAppCharP aItemData, cItemID aID, ItemID updID ) TUNNEL_IMPL; EMBVIRTUAL TSyError MoveItem ( SessionH aSessionH, cItemID aID, cAppCharP newParID ) TUNNEL_IMPL; EMBVIRTUAL TSyError DeleteItem ( SessionH aSessionH, cItemID aID ) TUNNEL_IMPL; EMBVIRTUAL TSyError EndDataWrite ( SessionH aSessionH, bool success, appCharP *newToken ) TUNNEL_IMPL; EMBVIRTUAL void DisposeObj ( SessionH aSessionH, void* memory ) TUNNEL_IMPL_VOID; // ---- asKey ---- EMBVIRTUAL TSyError ReadNextItemAsKey( SessionH aSessionH, ItemID aID, KeyH aItemKey, sInt32 *aStatus, bool aFirst ) TUNNEL_IMPL; EMBVIRTUAL TSyError ReadItemAsKey ( SessionH aSessionH, cItemID aID, KeyH aItemKey ) TUNNEL_IMPL; EMBVIRTUAL TSyError InsertItemAsKey ( SessionH aSessionH, KeyH aItemKey, ItemID aID ) TUNNEL_IMPL; EMBVIRTUAL TSyError UpdateItemAsKey ( SessionH aSessionH, KeyH aItemKey, cItemID aID, ItemID updID ) TUNNEL_IMPL; EMBVIRTUAL TSyError debugPuts(cAppCharP aFile, int aLine, cAppCharP aFunction, int aDbgLevel, cAppCharP aLinePrefix, cAppCharP aText); /// @} /// @brief returns the current application base object TSyncAppBase *getSyncAppBase(void) { return fAppBaseP; }; #ifdef DIRECT_APPBASE_GLOBALACCESS // only as a hack until we are completely free of global anchors void setSyncAppBase(TSyncAppBase *aAppBaseP) { fAppBaseP=aAppBaseP; }; #endif protected: /// @brief Must be derived in engineBase derivates for generating root for the appropriate settings tree /// @return root settings object, or NULL if failure virtual TSettingsKeyImpl *newSettingsRootKey(void) { return new TSettingsRootKey(this); // return base class which can return some engine infos }; /// @brief returns a new application base. /// @note in engineInterface based targets, this is the replacement for the formerly /// global newSyncAppBase() factory function. virtual TSyncAppBase *newSyncAppBase(void) = 0; /// @brief returns the SML instance for a given session handle virtual InstanceID_t getSmlInstanceOfSession(SessionH aSessionH) { return 0; /* no instance in base class */ }; private: // conversion helper // - converts byte stream (which can be an 8-bit char set or unicode in intel or motorola order) // to internal UTF-8, according to text mode set with SetStringMode() cAppCharP makeAppString(cAppCharP aTextP, string &aString); // the application base TSyncAppBase *fAppBaseP; // String format modes TCharSets fCharSet; bool fBigEndian; TLineEndModes fLineEndMode; }; // TEngineInterface } // namespace sysync #endif // ENGINEINTERFACE_SUPPORT #endif // ENGINEINTERFACE_H // eof libsynthesis-3.4.0.47.1/src/sysync/global_progress.h000077500000000000000000000061101226375725500223210ustar00rootroot00000000000000/* * Include file to allow SyncML RTK to use progress callback * * Copyright (c) 2003-2011 by Synthesis AG + plan44.ch */ #ifndef GLOBAL_PROGRESS_H #define GLOBAL_PROGRESS_H #include "generic_types.h" #ifdef __cplusplus namespace sysync { #endif // - progress event types typedef enum { // global pev_error, // some fatal aborting error pev_message, // extra messages pev_errcode, // extra error code pev_nop, // no extra message, just called to allow aborting pev_wait, // called to signal main program that caller would want to wait for extra1 milliseconds pev_debug, // called to allow debug interactions, extra1=code // transport-related pev_sendstart, pev_sendend, pev_recvstart, pev_recvend, pev_ssl_expired, // expired pev_ssl_notrust, // not completely trusted pev_conncheck, // sent periodically when waiting for network, allows application to check connection pev_suspendcheck, // sent when client could initiate a explicit suspend // General pev_display100, // alert 100 received from remote, extra1=char * to message text in UTF8 // Session-related pev_sessionstart, pev_sessionend, // session ended, probably with error in extra // Datastore-related pev_preparing, // preparing (e.g. preflight in some clients), extra1=progress, extra2=total pev_deleting, // deleting (zapping datastore), extra1=progress, extra2=total pev_alerted, // datastore alerted (extra1=0 for normal, 1 for slow, 2 for first time slow, extra2=1 for resumed session, extra3=syncmode) pev_syncstart, // sync started pev_itemreceived, // item received, extra1=current item count, extra2=number of expected changes (if >= 0) pev_itemsent, // item sent, extra1=current item count, extra2=number of expected items to be sent (if >=0) pev_itemprocessed, // item locally processed, extra1=# added, extra2=# updated, extra3=# deleted pev_syncend, // sync finished, probably with error in extra1 (0=ok), syncmode in extra2 (0=normal, 1=slow, 2=first time), extra3=1 for resumed session) pev_dsstats_l, // datastore statistics for local (extra1=# added, extra2=# updated, extra3=# deleted) pev_dsstats_r, // datastore statistics for remote (extra1=# added, extra2=# updated, extra3=# deleted) pev_dsstats_e, // datastore statistics for local/remote rejects (extra1=# locally rejected, extra2=# remotely rejected) pev_dsstats_s, // datastore statistics for server slowsync (extra1=# slowsync matches) pev_dsstats_c, // datastore statistics for server conflicts (extra1=# server won, extra2=# client won, extra3=# duplicated) pev_dsstats_d, // datastore statistics for data volume (extra1=outgoing bytes, extra2=incoming bytes) // number of enums numProgressEventTypes } TProgressEventType; #ifndef ENGINE_LIBRARY // globally accessible progress event posting #ifdef __cplusplus extern "C" int GlobalNotifyProgressEvent #else extern int GlobalNotifyProgressEvent #endif ( TProgressEventType aEventType, sInt32 aExtra1, sInt32 aExtra2, sInt32 aExtra3 ); #endif // not ENGINE_LIBRARY #ifdef __cplusplus } // namespace sysync #endif #endif // GLOBAL_PROGRESS_H /* eof */ libsynthesis-3.4.0.47.1/src/sysync/iso8601.cpp000066400000000000000000000321131226375725500206000ustar00rootroot00000000000000/* * File: iso8601.cpp * * Author: Lukas Zeller (luz@plan44.ch) * * conversion from/to linear time scale. * * Copyright (c) 2002-2011 by Synthesis AG + plan44.ch * * 2002-05-02 : luz : extracted from sysync_utils * */ #include "prefix_file.h" #include "iso8601.h" #include "stringutils.h" #include "timezones.h" #if defined(EXPIRES_AFTER_DATE) && !defined(FULLY_STANDALONE) // only if used in sysync context #include "sysync.h" #endif namespace sysync { /// @brief convert ISO8601 to timestamp and timezone /// @return number of successfully converted characters or 0 if no valid ISO8601 specification could be decoded /// @param[in] aISOString input string in ISO8601 /// @param[out] aTimestamp representation of ISO time spec as is (no time zone conversions) /// @param[out] aWithTime if set, time specification was found in input string /// @param[out] aTimeContext: /// TCTX_DURATION if ISO8601 is a duration format (PnDTnHnMnS.MS) /// TCTX_UNKNOWN if ISO8601 does not include a time zone specification /// TCTX_UTC if ISO8601 ends with the "Z" specifier /// TCTX_DATEONLY if ISO8601 only contains a date, but no time /// TCTX_OFFSCONTEXT(xx) if ISO8601 explicitly specifies a UTC offset sInt16 ISO8601StrToTimestamp(cAppCharP aISOString, lineartime_t &aTimestamp, timecontext_t &aTimeContext) { uInt16 y,m,d,hr,mi,s,ms; // unsigned because these can't be signed when parsing bool isExtended=false; sInt16 n,h,sg; n=0; // check if it might be duration sg=0; // duration sign // - sign if (*aISOString=='-') { sg=-1; // negative duration aISOString++; n++; } else if(*aISOString=='+') { sg=1; // positive duration aISOString++; n++; } if (*aISOString=='P') { if (sg==0) sg=1; aISOString++; n++; } else if (sg!=0) return 0; // we had a sign, but no 'P' -> invalid ISO8601 date // if y!=0 here, this is a duration if (sg!=0) { // duration aTimestamp = 0; aTimeContext = TCTX_UNKNOWN + TCTX_DURATION; bool timepart = false; // parse duration parts while (true) { if (*aISOString=='T' && !timepart) { timepart = true; aISOString++; n++; } #ifdef NO_FLOATS sInt32 part; h = StrToLong(aISOString,part); #else double part; h = StrToDouble(aISOString,part); #endif if (h>0) { aISOString+=h; n+=h; // this is a part, must be followed by a designator switch (*aISOString) { case 'Y': part*=365; goto days; // approximate year case 'M': // month or minute if (timepart) { aTimestamp += (lineartime_t)(part*sg*secondToLinearTimeFactor*SecsPerMin); // minute break; } else { part*=30; // approximate month goto days; } case 'W': part *= 7; goto days; // one week case 'D': days: aTimestamp += (lineartime_t)(part*sg*linearDateToTimeFactor); break; case 'H': aTimestamp += (lineartime_t)(part*sg*secondToLinearTimeFactor*SecsPerHour); break; case 'S': aTimestamp += (lineartime_t)(part*sg*secondToLinearTimeFactor); break; default: return 0; // bad designator, error } aISOString++; n++; } // if number else { // no more digits -> end of duration string return n; // number of chars processed } } // while } // if duration // try to parse date // - first should be 4 digit year h = StrToUShort(aISOString,y,4); if (h!=4) return 0; // no ISO8601 date aISOString+=h; n+=h; // - test for format if (*aISOString=='-') { isExtended=true; aISOString++; n++; } // - next must be 2 digit month h = StrToUShort(aISOString,m,2); if (h!=2) return 0; // no ISO8601 date aISOString+=h; n+=h; // - check separator in case of extended format if (isExtended) { if (*aISOString != '-') return 0; // missing separator, no ISO8601 date aISOString++; n++; } // - next must be 2 digit day h = StrToUShort(aISOString,d,2); if (h!=2) return 0; // no ISO8601 date aISOString+=h; n+=h; // convert date to timestamp aTimestamp = date2lineartime(y,m,d); // Now next must be "T" if time spec is included if (*aISOString!='T') { // date-only, floating aTimeContext = TCTX_DATEONLY|TCTX_UNKNOWN; } else { // parse time as well aISOString++; n++; // skip "T" mi=0; s=0; ms=0; // reset optional time components // - next must be 2 digit hour h = StrToUShort(aISOString,hr,2); if (h!=2) return 0; // no ISO8601 time, we need the hour, minimally aISOString+=h; n+=h; // - check separator in case of extended format if (isExtended) { if (*aISOString != ':') return 0; // missing separator, no ISO8601 time (Note: hour-only reduced precision does not exist for extended format) aISOString++; n++; } // - next must be 2 digit minute (or nothing for hour-only reduced precision basic format) h = StrToUShort(aISOString,mi,2); if (!isExtended && h==0) goto timeok; if (h!=2) return 0; // no ISO8601 time, must be 2 digits here aISOString+=h; n+=h; // - check separator in case of extended format if (isExtended) { if (*aISOString != ':') goto timeok; // no separator means hour:minute reduced precision for extended format aISOString++; n++; } // - next must be 2 digit second (or nothing for reduced precision without seconds) h = StrToUShort(aISOString,s,2); if (!isExtended && h==0) goto timeok; // no seconds is ok for basic format only (in extended format, the separator must be omitted as well, which is checked above) if (h!=2) return 0; // no ISO8601 time, must be 2 digits here aISOString+=h; n+=h; // optional fractions of seconds if (*aISOString=='.') { aISOString++; n++; h = StrToUShort(aISOString,ms,3); if (h==0) return 0; // invalid fraction specified aISOString+=h; n+=h; while (h<3) { ms *= 10; h++; } // make milliseconds } timeok: // add to timestamp aTimestamp += time2lineartime(hr,mi,s,ms); // check for zone specification h = ISO8601StrToContext(aISOString,aTimeContext); aISOString+=h; n+=h; } // return number of characters converted return n; } // ISO8601StrToTimestamp /// @brief convert ISO8601 zone offset to internal time zone /// @return number of successfully converted characters or 0 if no valid ISO8601 time zone spec could be decoded /// @param[in] aISOString input string in ISO8601 time zone offset format (or just "Z" for UTC) /// @param[out] aTimeContext: /// TCTX_UNKNOWN if no time zone specification is found /// TCTX_UTC if "Z" specifier found /// TCTX_OFFSCONTEXT(xx) if explicit UTC offset is found sInt16 ISO8601StrToContext(cAppCharP aISOString, timecontext_t &aTimeContext) { sInt16 n=0,h; sInt16 minoffs; uInt16 offs; aTimeContext = TCTX_UNKNOWN; bool western=false; // check for UTC special case if (*aISOString=='Z') { n++; aTimeContext = TCTX_UTC; } else { // check for time zone offset if (*aISOString!='+' && *aISOString!='-') return 0; // error, nothing converted western = *aISOString=='-'; // time is behind of UTC in the west aISOString++; n++; h=StrToUShort(aISOString,offs,2); if (h!=2) return 0; // not +HH format with 2 digits, nothing converted aISOString+=h; n+=h; // make minutes minoffs = offs*60; // hour offset ok, now check minutes if (*aISOString==':') { aISOString++; n++; }; // extended format // get minutes, if any h = StrToUShort(aISOString,offs,2); if (h==2) { // minute specified minoffs += offs; // add minutes } // adjust sign if (western) minoffs=-minoffs; // western offset is negative // return non-symbolic minute offset aTimeContext = TCTX_OFFSCONTEXT(minoffs); } // return number of characters converted return n; } // ISO8601StrToContext /// @brief convert timestamp to ISO8601 representation /// @param[out] aISOString will receive ISO8601 formatted date/time /// @param[in] aTimestamp representation of ISO time spec as is (no time zone conversions) /// @param[in] aExtFormat if set, extended format is generated /// @param[in] aWithFracSecs if set, fractional seconds are displayed (3 digits, milliseconds) /// @param[in] aTimeContext: /// TCTX_DURATION: timestamp is a duration and is shown in ISO8601 duration format (PnDTnHnMnS.MS) /// TCTX_UNKNOWN : time is shown as relative format (no "Z", no explicit offset) /// TCTX_TIMEONLY /// TCTX_UTC : time is shown with "Z" specifier /// TCTX_DATEONLY: only date part is shown (of date or duration) /// TCTX_OFFSCONTEXT(xx) : time is shown with explicit UTC offset (but not with "Z", even if offset is 0:00) void TimestampToISO8601Str(string &aISOString, lineartime_t aTimestamp, timecontext_t aTimeContext, bool aExtFormat, bool aWithFracSecs) { // check for duration (should be rendered even if value is 0) if (TCTX_IS_DURATION(aTimeContext)) { // render as duration // - sign if (aTimestamp<0) { aTimestamp=-aTimestamp; aISOString = "-"; } else { aISOString.erase(); } // - "P" duration designator aISOString += "P"; // - days lineardate_t days = aTimestamp / linearDateToTimeFactor; if (days!=0) StringObjAppendPrintf(aISOString,"%ldD",(long)days); // - time part if needed if (!TCTX_IS_DATEONLY(aTimeContext) && lineartime2timeonly(aTimestamp)>(aWithFracSecs ? 0 : secondToLinearTimeFactor-1)) { aISOString += "T"; // we have a time part sInt16 h,m,s,ms; lineartime2time(aTimestamp,&h,&m,&s,&ms); if (h!=0) StringObjAppendPrintf(aISOString,"%hdH",h); if (m!=0) StringObjAppendPrintf(aISOString,"%hdM",m); if (aWithFracSecs && ms!=0) { // with milliseconds, implies seconds as well, even if they are zero StringObjAppendPrintf(aISOString,"%hd.%03hdS",s,ms); } else { // no milliseconds, show seconds if not zero if (s!=0) StringObjAppendPrintf(aISOString,"%hdS",s); } } else if(days==0) { aISOString="PT0S"; // no time part and no days, just display 0 seconds (and not negative, even if fraction might be) } // done return; } // no timestamp, no string if (aTimestamp==0) { aISOString.erase(); return; } // Date if we want date bool hasDate=false; if (!TCTX_IS_TIMEONLY(aTimeContext)) { // we want the date part sInt16 y,m,d; lineartime2date(aTimestamp,&y,&m,&d); if (!TCTX_IS_DURATION(aTimeContext) || !(y==0 && m==0 && d==0)) { if (aExtFormat) StringObjPrintf(aISOString,"%04d-%02d-%02d",y,m,d); // Extended format else StringObjPrintf(aISOString,"%04d%02d%02d",y,m,d); // Basic format hasDate=true; } } else { aISOString.erase(); } // Add time if we want time if (!TCTX_IS_DATEONLY(aTimeContext)) { // we want the time part // - add separator if (hasDate) aISOString+='T'; // - now add the time sInt16 h,m,s,ms; lineartime2time(aTimestamp,&h,&m,&s,&ms); if (aExtFormat) StringObjAppendPrintf(aISOString,"%02hd:%02hd:%02hd",h,m,s); // Extended format else StringObjAppendPrintf(aISOString,"%02hd%02hd%02hd",h,m,s); // Basic format // - add fractions of the second if selected and not 0 if (aWithFracSecs && (ms!=0)) { StringObjAppendPrintf(aISOString,".%03hd",ms); // 3 decimal fraction digits for milliseconds } if (!TCTX_IS_DURATION(aTimeContext)) { // add explicit time zone specification (or UTC "Z") if aTimecontext is a non-symbolic offset ContextToISO8601StrAppend(aISOString, aTimeContext, aExtFormat); } } } // TimestampToISO8601Str /// @brief append internal time zone as ISO8601 zone offset to string /// @param[out] aISOString ISO8601 time zone spec will be appended to this string /// @param[in] aTimeContext /// @param[in] aExtFormat if set, extended format is generated bool ContextToISO8601StrAppend(string &aISOString, timecontext_t aTimeContext, bool aExtFormat) { // check for UTC special case if (TCTX_IS_UTC(aTimeContext)) { aISOString += 'Z'; return true; // has time zone } // check if this is a resolved or a symbolic time zone if (TCTX_IS_TZ(aTimeContext)) return false; // symbolic (includes unknown) - cannot append minute offset // offset specified, show it long moffs = TCTX_MINOFFSET(aTimeContext); bool minus = moffs<0; moffs = abs(moffs); long hoffs = moffs / MinsPerHour; moffs = moffs % MinsPerHour; StringObjAppendPrintf(aISOString, "%c%02ld", minus ? '-' : '+', hoffs); if (moffs!=0 || aExtFormat) { // minute specification required (always so for extended format) if (aExtFormat) aISOString+=':'; // add separator for extended format StringObjAppendPrintf(aISOString, "%02ld", moffs); } return true; // has time zone } // ContextToISO8601StrAppend } // namespace sysync /* eof */ libsynthesis-3.4.0.47.1/src/sysync/iso8601.h000077500000000000000000000051531226375725500202540ustar00rootroot00000000000000/* * File: iso8601.h * * Author: Lukas Zeller (luz@plan44.ch) * * conversion from/to linear time scale. * * Copyright (c) 2002-2011 by Synthesis AG + plan44.ch * * 2002-05-02 : luz : extracted from sysync_utils * */ #ifndef ISO8601_H #define ISO8601_H #include #include "lineartime.h" #include "timezones.h" using namespace std; namespace sysync { /// @brief convert ISO8601 to timestamp /// @return number of successfully converted characters /// @param[in] aISOString input string in ISO8601 /// @param[out] aTimestamp representation of ISO time spec as is (no time zone conversions) /// @param[out] aTimeContext: /// TCTX_UNKNOWN if ISO8601 does not include a time zone specification /// TCTX_UTC if ISO8601 ends with the "Z" specifier /// TCTX_DATEONLY if ISO8601 only contains a date, but no time /// TCTX_OFFSCONTEXT(xx) if ISO8601 explicitly specifies a UTC offset sInt16 ISO8601StrToTimestamp(cAppCharP aISOString, lineartime_t &aTimestamp, timecontext_t &aTimeContext); /// @brief convert ISO8601 zone offset to internal time context /// @param[in] aISOString input string in ISO8601 /// @param[out] aTimeContext context, TCTX_UNKNOWN if none found sInt16 ISO8601StrToContext(cAppCharP aISOString, timecontext_t &aTimeContext); /// @brief convert timestamp to ISO8601 representation /// @param[out] aISOString will receive ISO8601 formatted date/time /// @param[in] aTimestamp representation of ISO time spec as is (no time zone conversions) /// @param[in] aExtFormat if set, extended format is generated /// @param[in] aTimeContext: /// TCTX_UNKNOWN : time is shown as relative format (no "Z", no explicit offset) /// TCTX_UTC : time is shown with "Z" specifier /// TCTX_DATEONLY: only date part is shown /// TCTX_OFFSCONTEXT(xx) : time is shown with explicit UTC offset (but not with "Z", even if offset is 0:00) /// @param[in] aWithFracSecs if set, factional parts of the second are shown in the output void TimestampToISO8601Str(string &aISOString, lineartime_t aTimestamp, timecontext_t aTimeContext, bool aExtFormat=false, bool aWithFracSecs=false); /// @brief append internal time context as ISO8601 zone offset to string /// @param[out] aISOString ISO8601 time zone spec will be appended to this string /// @param[in] aTimeContext /// @param[in] aExtFormat if set, extended format is generated /// @return true if time zone spec appended, false if not bool ContextToISO8601StrAppend(string &aISOString, timecontext_t aTimeContext, bool aExtFormat); } // namespace sysync #endif // ISO8601_H /* eof */ libsynthesis-3.4.0.47.1/src/sysync/itemfield.cpp000066400000000000000000002026041226375725500214350ustar00rootroot00000000000000/* * File: itemfield.cpp * * Author: Lukas Zeller (luz@plan44.ch) * * TItemField * Abstract class, holds a single field value * TStringField, TIntegerField, TTimeStampField etc. * Implementations of field types * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * 2001-08-08 : luz : created * */ // includes #include "prefix_file.h" #include "sysync.h" #include "itemfield.h" #include "multifielditemtype.h" #if defined(CHECKSUM_CHANGELOG) && !defined(RECORDHASH_FROM_DBAPI) #include "sysync_crc16.h" #endif using namespace sysync; namespace sysync { // type names cAppCharP const ItemFieldTypeNames[numFieldTypes] = { "string", "telephone", "integer", "timestamp", "date", "url", "multiline", "blob", "none" }; // corresponding SyncML devInf const TPropDataTypes devInfPropTypes[numFieldTypes] = { proptype_chr, // string -> Character proptype_phonenum, // telephone -> Phone number proptype_int, // integer -> Integer proptype_datetime, // Timestamp -> Date and time of day proptype_datetime, // Date -> Date and time of day proptype_chr, // URL -> Character proptype_text, // multiline -> plain text proptype_bin, // BLOB -> Binary proptype_unknown, // none -> unknown }; /* * Implementation of TItemField */ TItemField::TItemField() : fAssigned(false) // unassigned at creation { } // TItemField::TItemField TItemField::~TItemField() { } // TItemField::~TItemField #ifdef SYDEBUG // show field contents as string for debug output size_t TItemField::StringObjFieldAppend(string &s, uInt16 aMaxStrLen) { if (isUnassigned()) s+=""; else if (isEmpty()) s+=""; else appendToString(s, aMaxStrLen); return 0; // non-strings do not have a real size } // TItemField::StringObjFieldAppend #endif // append (default to appending string value of other field) void TItemField::append(TItemField &aItemField) { string s; aItemField.getAsString(s); appendString(s); } // TItemField::append // generic cross-type assignment via string format TItemField& TItemField::operator=(TItemField &aItemField) { string s; if (aItemField.isUnassigned()) unAssign(); // copy unassigned status else if (aItemField.isEmpty()) assignEmpty(); // copy empty status else { aItemField.getAsString(s); setAsString(s); } return *this; } // TItemField::operator= // get any field as integer fieldinteger_t TItemField::getAsInteger(void) { // convert to integer number string s; fieldinteger_t i; getAsString(s); if (! #ifndef NO64BITINT StrToLongLong(s.c_str(),i) #else StrToLong(s.c_str(),i) #endif ) i=0; // defined value return i; } // TItemField::getAsInteger // get integer as numeric string void TItemField::setAsInteger(fieldinteger_t aInteger) { string s; #ifndef NO64BITINT LONGLONGTOSTR(s,PRINTF_LLD_ARG(aInteger)); #else StringObjPrintf(s,"%ld",(sInt32)aInteger); #endif // set as string setAsString(s); } // TItemField::setAsInteger // set as string, max number of chars = aLen void TItemField::setAsString(cAppCharP aString, size_t aLen) { if (!aString) assignEmpty(); else { string t(aString,aLen); // now call basic setter setAsString(t.c_str()); } } // TItemField::setAsString size_t TItemField::getStringSize(void) { if (getType()==fty_none) return 0; // empty/unassigned field has no size (avoid unneeded getAsString) string s; getAsString(s); return s.size(); } // TItemField::getStringSize bool TItemField::contains(TItemField &aItemField, bool aCaseInsensitive) { string s; aItemField.getAsString(s); return findInString(s.c_str(), aCaseInsensitive)>=0; } #ifdef STREAMFIELD_SUPPORT // reset stream (start reading and/or writing at specified position) void TItemField::resetStream(size_t aPos) { if (aPos==0) fStreamPos=0; // optimized short-cut else { size_t sz=getStreamSize(); if (aPos>sz) fStreamPos=sz; else fStreamPos=aPos; } } // TItemField::resetStream // read from stream size_t TItemField::readStream(void *aBuffer, size_t aMaxBytes) { string s; getAsString(s); size_t sz=s.size(); if (fStreamPos>sz) fStreamPos=sz; if (fStreamPos+aMaxBytes > sz) aMaxBytes=sz-fStreamPos; if (aMaxBytes>0) { // copy memory memcpy(aBuffer,s.c_str()+fStreamPos,aMaxBytes); } // return number of chars actually read fStreamPos+=aMaxBytes; return aMaxBytes; } // TItemField::readStream // write to stream size_t TItemField::writeStream(void *aBuffer, size_t aNumBytes) { if (aNumBytes==0) return 0; if (fStreamPos!=0) { // not replacing entire contents, need read-modify-write of string string s; getAsString(s); if (fStreamPos>s.size()) fStreamPos=s.size(); s.resize(fStreamPos); s.append((cAppCharP)aBuffer,aNumBytes); setAsString(s); } else { setAsString((cAppCharP)aBuffer,aNumBytes); } fStreamPos+=aNumBytes; return aNumBytes; } // TItemField::writeStream #endif /* end of TItemField implementation */ #ifdef ARRAYFIELD_SUPPORT /* * Implementation of TArrayField */ // constructor TArrayField::TArrayField(TItemFieldTypes aLeafFieldType, GZones *aGZonesP) { fLeafFieldType=aLeafFieldType; fGZonesP = aGZonesP; // field for index==0 always exists fFirstField = newItemField(fLeafFieldType,fGZonesP,false); } // TArrayField::TArrayField // destructor TArrayField::~TArrayField() { // make sure leaf fields (except idx==0) are gone unAssign(); // and kill firstfield delete fFirstField; } // TArrayField::~TArrayField bool TArrayField::elementsBasedOn(TItemFieldTypes aFieldType) const { return fFirstField->isBasedOn(aFieldType); } // TArrayField::elementsBasedOn #ifdef SYDEBUG // show field contents as string for debug output size_t TArrayField::StringObjFieldAppend(string &s, uInt16) { if (!isAssigned()) return inherited::StringObjFieldAppend(s,0); // let ancestor show StringObjAppendPrintf(s,"",(long int)(arraySize())); return 0; } // TArrayField::StringObjFieldAppend #endif // get field from array (creates new if index is larger than current array size) TItemField *TArrayField::getArrayField(sInt16 aArrIdx, bool aExistingOnly) { TItemField *fldP = NULL; // check index, negative index means array field itself if (aArrIdx<0) return this; // check if we have that field already if (aArrIdxgetDataCRC(crc); } return crc; } // TArrayField::getDataCRC #endif // clear all leaf fields void TArrayField::unAssign(void) { for (sInt16 idx=0; idxunAssign(); // first is always kept, it is the fFirstField, so only unassign to remove content else delete fArray[idx]; fArray[idx]=NULL; } } // clear list now fArray.clear(); // clear flag as well that could be set in case of an explicitly assigned empty array fAssigned = false; } // TArrayField::unAssign // assign TItemField& TArrayField::operator=(TItemField &aItemField) { // assignment of empty (could be EMPTY or UNASSIGNED) must be handled by base class if (aItemField.isEmpty()) return TItemField::operator=(aItemField); // handle array-to-array assignments if (aItemField.isArray()) { // delete my current contents unAssign(); // copy leaf fields from other field for (sInt16 idx=0; idxgetArrayField(idx)); } } else { // non-array (non-empty) assigned to array: just assign value to first element unAssign(); *(getArrayField(0)) = aItemField; } return *this; } // TArrayField::operator= // append values (only assigned ones) // - if other field is an array, too, all elements of other array // will be appended at end of this array. // - if other field is a scalar, it's value will be appended to // the array. void TArrayField::append(TItemField &aItemField) { if (aItemField.isArray()) { // append elements of another array to this array for (sInt16 idx=0; idxsetAsString(aString,aMaxChars); } // TArrayField::appendString // contains for arrays means "contains in any of the elements" // (if aItemField is an array as well, this means that every element must be // contained somewhere in my own array) bool TArrayField::contains(TItemField &aItemField, bool aCaseInsensitive) { bool contained = false; if (aItemField.isArray()) { contained=true; // array: all array elements must be contained in at least one of my elements for (sInt16 idx=0; idx not contained contained = false; break; } } } else { // leaf element: must be contained in at least one of my elements contained = false; for (sInt16 idx=0; idxcontains(aItemField,aCaseInsensitive)) { // the value of aItemField is contained in one of my elements -> contained contained = true; break; } } } return contained; } // TItemField::contains // compare: returns 0 if equal, 1 if this > aItem, -1 if this < aItem, // SYSYNC_NOT_COMPARABLE if not comparable at all or not equal and no ordering known // Note: array fields are only comparable with other array fields sInt16 TArrayField::compareWith(TItemField &aItemField, bool aCaseInsensitive) { if (!aItemField.isArray()) return SYSYNC_NOT_COMPARABLE; // get sizes of arrays sInt16 mysz = arraySize(); sInt16 othersz = aItemField.arraySize(); sInt16 commonsz = mysz>othersz ? othersz : mysz; // compare common array elements for (sInt16 idx=0; idxcompareWith(*(aItemField.getArrayField(idx)), aCaseInsensitive); if (res!=0) return res; // all non-equal return } // all compared fields are equal if (mysz==othersz) return 0; // same size : equal // Sizes differ, but that only matters if the extra entries are // actually assigned. Without that special case, we end up // with the situation where parsing, encoding and parsing // again leads to different fields: // - EMAIL;TYPE=OTHER:foo -> EMAIL_FLAGS 1 entry "unassigned" // - unassigned -> EMAIL:foo // - EMAIL:foo -> EMAIL_FLAGS 0 entry // - EMAIL_FLAGS 1 entry "unassigned" > EMAIL_FLAGS 0 entry TItemField &largerField = mysz < othersz ? aItemField : *this; sInt16 minsz, maxsz; sInt16 res; // larger array is greater if (mysz < othersz) { minsz = mysz; maxsz = othersz; res = -1; } else { minsz = othersz; maxsz = mysz; res = 1; } for (sInt16 idx=minsz; idxisAssigned()) // found real difference return res; } // larger array contains only extra unassigned entries, ignore them return 0; } // TArrayField::compareWith /* end of TArrayField implementation */ #endif /* * Implementation of TStringField */ TStringField::TStringField() { #ifdef STREAMFIELD_SUPPORT fBlobProxyP=NULL; #endif } // TStringField::TStringField TStringField::~TStringField() { #ifdef STREAMFIELD_SUPPORT // remove proxy if any TBlobProxy::unlink(fBlobProxyP); #endif } // TStringField::~TStringField #if defined(CHECKSUM_CHANGELOG) && !defined(RECORDHASH_FROM_DBAPI) // changelog support: calculate CRC over contents uInt16 TStringField::getDataCRC(uInt16 crc) { // CRC over characters in the string return sysync_crc16_block(getCStr(),getStringSize(),crc); } // TStringField::getDataCRC #endif // assignment TItemField& TStringField::operator=(TItemField &aItemField) { DELETEPROXY; // forget old value and old proxy as well // handle myself only if other is string field as well if (aItemField.isBasedOn(fty_string)) { // copy fields 1:1 const TStringField *sfP = static_cast(&aItemField); fString=sfP->fString; fAssigned=sfP->fAssigned; #ifdef STREAMFIELD_SUPPORT fBlobProxyP=sfP->fBlobProxyP; // copy proxy as well if (fBlobProxyP) fBlobProxyP->link(); // link again, now both fields use the proxy #endif } else TItemField::operator=(aItemField); // generic cross-type assignment (via string) return *this; } // TStringField::operator= // get size of string size_t TStringField::getStringSize(void) { #ifdef STREAMFIELD_SUPPORT return getStreamSize(); #else return fString.size(); #endif } // TStringField::getStringSize // normalized string is contents without leading or trailing control chars or spaces void TStringField::getAsNormalizedString(string &aString) { size_t nsiz = getStringSize(); // we need the actual string to do this PULLFROMPROXY; // find first non-control or non-WSP char size_t start = 0; while (start0 && ((uInt8)fString[nsiz-1])<=' ') nsiz--; // take string without any leading or trailing white space or other control chars aString.assign(fString,start,nsiz-start); } // TStringField::getAsNormalizedString #ifdef SYDEBUG // show field contents as string for debug output size_t TStringField::StringObjFieldAppend(string &s, uInt16 aMaxStrLen) { size_t n = 0; // empty or unassigned is handled by base class if (isEmpty()) { return inherited::StringObjFieldAppend(s,aMaxStrLen); } // with proxy installed, do not pull the string if (PROXYINSTALLED) { s+=""; n=0; // unknown size at this time } else { // no proxy installed s+='"'; // - check if display length is sufficient size_t i; n = getStringSize(); if (aMaxStrLen==0 || n<=10 || n<=size_t(aMaxStrLen-2)) { // strings below 11 chars are always shown in full s.append(fString); } else { i = (aMaxStrLen-5)/2; // half of the size that can be displayed s.append(fString,0,i); s.append("..."); s.append(fString,n-i,i); } s+='"'; } // return actual string size (not shortened one!) return n; } // TStringField::StringObjFieldAppend #endif #ifdef STREAMFIELD_SUPPORT // set blob loader proxy (ownership is passed to field) void TStringField::setBlobProxy(TBlobProxy *aBlobProxyP) { if (fBlobProxyP==aBlobProxyP) return; // same proxy, just ignore // unlink previous proxy, if any TBlobProxy::unlink(fBlobProxyP); // assign new proxy fBlobProxyP=aBlobProxyP; // assigning a proxy means that the field is now assigned fAssigned=true; } // TStringField::setBlobProxy // pull entire string from proxy and forget proxy void TStringField::pullFromProxy(void) { if (fBlobProxyP) { const size_t bufsiz=4096; cAppCharP bufP = new char[bufsiz]; resetStream(); size_t by; SYSYNC_TRY { do { by=fBlobProxyP->readBlobStream(this, fStreamPos, (void *)bufP, bufsiz); fString.append(bufP,by); } while (by==bufsiz); } SYSYNC_CATCH(exception &e) // avoid crashing session if proxy pull fails fString="Server error while getting data from proxy object: "; fString+=e.what(); SYSYNC_ENDCATCH delete bufP; // proxy is no longer needed TBlobProxy::unlink(fBlobProxyP); } } // TStringField::pullFromProxy // return size of stream size_t TStringField::getStreamSize(void) { if (fBlobProxyP) SYSYNC_TRY { return fBlobProxyP->getBlobSize(this); // return size of entire blob } SYSYNC_CATCH(exception &e) return 0; // cannot return actual size SYSYNC_ENDCATCH else return fString.size(); // just return size of already stored string } // TStringField::getStreamSize // read as stream size_t TStringField::readStream(void *aBuffer, size_t aMaxBytes) { if (fBlobProxyP) { SYSYNC_TRY { // let proxy handle this return fBlobProxyP->readBlobStream(this, fStreamPos, aBuffer, aMaxBytes); } SYSYNC_CATCH(...) // do not return anything return 0; // do not return anything SYSYNC_ENDCATCH } else { // read from string itself size_t sz=fString.size(); if (fStreamPos>sz) fStreamPos=sz; if (fStreamPos+aMaxBytes > sz) aMaxBytes=sz-fStreamPos; if (aMaxBytes>0) { // copy memory memcpy(aBuffer,fString.c_str()+fStreamPos,aMaxBytes); } // return number of chars actually read fStreamPos+=aMaxBytes; return aMaxBytes; } } // TStringField::readStream // write as stream size_t TStringField::writeStream(void *aBuffer, size_t aNumBytes) { if (aNumBytes==0) return 0; if (fStreamPos>fString.size()) fStreamPos=fString.size(); fString.resize(fStreamPos); fString.append((cAppCharP)aBuffer,aNumBytes); fStreamPos+=aNumBytes; return aNumBytes; } // TStringField::writeStream #endif // set as string, max number of chars to assign = aLen void TStringField::setAsString(cAppCharP aString, size_t aLen) { DELETEPROXY; // forget old value and old proxy as well if (!aString) fString.erase(); else fString.assign(aString,aLen); stringWasAssigned(); } // TStringField::setAsString // append to string void TStringField::appendString(cAppCharP aString, size_t aMaxChars) { PULLFROMPROXY; // make sure we have all chars if (aString) { fString.append(aString,aMaxChars); } stringWasAssigned(); } // TStringField::appendString // merge field contents into this field bool TStringField::merge(TItemField &aItemField, const char aSep) { bool mergedsomething=false; if (aItemField.isBasedOn(fty_string)) { TStringField *sfP = static_cast(&aItemField); #ifdef STREAMFIELD_SUPPORT pullFromProxy(); // make sure we have all chars sfP->pullFromProxy(); // make sure we have all chars #endif if (aSep) { // take each aSep separated part of source (aItemField), and if it is not // yet part of target (this), then add it string::size_type j,i=0; string part; do { // extract part from source j=sfP->fString.find(aSep,i); if (j==string::npos) part.assign(sfP->fString,i,sfP->fString.size()-i); else part.assign(sfP->fString,i,j-i); // see if it is contained in target already if (!part.empty() && fString.find(part)==string::npos) { // not contained, add if (!fString.empty()) fString+=aSep; inherited::appendString(part); mergedsomething=true; } // check next part i=j+1; // char after last separator } while (j!=string::npos); } else { // no intelligent separator based merge, just append if not equal if (sfP->fString != fString) { inherited::appendString(sfP->fString); mergedsomething=true; } } } return mergedsomething; } // TStringField::merge // compare: returns 0 if equal, 1 if this > aItem, -1 if this < aItem, // SYSYNC_NOT_COMPARABLE if not equal and no ordering known or if field // types do not match. // Note: ordering may NOT be age relevant; it just means that an ordering // for this field type exists. // Note: Both fields must be assigned. NO TEST IS DONE HERE! sInt16 TStringField::compareWith(TItemField &aItemField, bool aCaseInsensitive) { sInt16 result; PULLFROMPROXY; if (aItemField.isBasedOn(fty_string)) { TStringField *sfP = static_cast(&aItemField); #ifdef STREAMFIELD_SUPPORT sfP->pullFromProxy(); // make sure we have all chars #endif // direct compare possible, return strcmp if (aCaseInsensitive) result=strucmp(fString.c_str(),sfP->fString.c_str()); else result=strcmp(fString.c_str(),sfP->fString.c_str()); } else { // convert other field to string string s; aItemField.getAsString(s); if (aCaseInsensitive) result=strucmp(fString.c_str(),s.c_str()); else result=strcmp(fString.c_str(),s.c_str()); } return result >0 ? 1 : (result<0 ? -1 : 0); } // TStringField::compareWith // check if specified field is shortened version of this one bool TStringField::isShortVers(TItemField &aItemField, sInt32 aOthersMax) { if (!aItemField.isBasedOn(fty_string)) return false; // different types TStringField *sfP = static_cast(&aItemField); #ifdef STREAMFIELD_SUPPORT pullFromProxy(); // make sure we have all chars sfP->pullFromProxy(); // make sure we have all chars #endif // same type // - if other field is empty, it does not count as a shortened version in any case if (sfP->isEmpty()) return false; // - show if other field is shortened version of this one return ( aOthersMax!=FIELD_OPT_MAXSIZE_NONE && // other field is limited (if not, cannot be short version) (aOthersMax==FIELD_OPT_MAXSIZE_UNKNOWN || uInt32(aOthersMax)==sfP->getStringSize()) && // size is unknown or other value is max size findInString(sfP->fString.c_str())==0 // other value is contained at beginning of this value ); } // TStringField::isShortVers // - check if String is contained in value and returns position sInt16 TStringField::findInString(cAppCharP aString, bool aCaseInsensitive) { PULLFROMPROXY; if (aString==NULL || *aString==0) return fString.empty() ? 0 : -1; // if I am empty myself,treat empty string as contained at beginning // no empty reference string if (!aCaseInsensitive) { return fString.find(aString); } else { return strupos(fString.c_str(),aString,fString.size()); } }; /* end of TStringField implementation */ /* * Implementation of TBlobField */ TBlobField::TBlobField() { // nothing known about contents yet fHasEncoding = enc_none; fWantsEncoding = enc_none; fCharset = chs_utf8; } // TBlobField::TBlobField TBlobField::~TBlobField() { } // TBlobField::~TBlobField // assignment TItemField& TBlobField::operator=(TItemField &aItemField) { DELETEPROXY; // forget old value and old proxy as well // assignment of empty (could be EMPTY or UNASSIGNED) must be handled by base class if (aItemField.isEmpty()) return TItemField::operator=(aItemField); // handle non-empty myself if other is based on string (blob is just a enhanced string) if (aItemField.isBasedOn(fty_string)) { // assign string portions TStringField::operator=(aItemField); if(aItemField.isBasedOn(fty_blob)) { // other is a blob, copy blob specific options const TBlobField *bfP = static_cast(&aItemField); fHasEncoding=bfP->fHasEncoding; fWantsEncoding=bfP->fWantsEncoding; fCharset=bfP->fCharset; } else { // reset blob options to default for string content fHasEncoding = enc_none; fWantsEncoding = enc_none; fCharset = chs_utf8; } } else TItemField::operator=(aItemField); // generic cross-type assignment (via string) return *this; } // TBlobField::operator= #ifdef SYDEBUG // debug support size_t TBlobField::StringObjFieldAppend(string &s, uInt16 aMaxStrLen) { // empty or unassigned is handled by base class if (isEmpty()) { return inherited::StringObjFieldAppend(s, aMaxStrLen); } // avoid pulling a proxy for debug if (!PROXYINSTALLED) { appendToString(s); // show standard string which is pseudo-content return getStringSize(); // return actual size of BLOB } else return inherited::StringObjFieldAppend(s, aMaxStrLen); // with proxy installed, base class will show that } // TBlobField::StringObjFieldAppend #endif // SYDEBUG /* end of TBlobField implementation */ /* * Implementation of TTelephoneField */ TTelephoneField::TTelephoneField() { } // TTelephoneField::TTelephoneField TTelephoneField::~TTelephoneField() { } // TTelephoneField::~TTelephoneField void TTelephoneField::getAsNormalizedString(string &aString) { cAppCharP p = getCStr(); char c; aString.erase(); // only returns alphanum and +,*,#, rest is filtered out while ((c=*p++)!=0) { if (isalnum(c) || c=='+' || c=='#' || c=='*') aString+=c; } } // TTelephoneField::getAsNormalizedString // compare: returns 0 if equal, 1 if this > aItem, -1 if this < aItem, // SYSYNC_NOT_COMPARABLE if not equal and no ordering known or if field // types do not match. // Note: ordering may NOT be age relevant; it just means that an ordering // for this field type exists. // Note: Both fields must be assigned. NO TEST IS DONE HERE! sInt16 TTelephoneField::compareWith(TItemField &aItemField, bool aCaseInsensitive) { if (!aItemField.isBasedOn(fty_telephone)) { // if other field is not telephone, try normal string comparison return TStringField::compareWith(aItemField, aCaseInsensitive); } // compare possible, return strcmp of normalized numbers TTelephoneField *tfP = static_cast(&aItemField); string s1,s2; getAsNormalizedString(s1); tfP->getAsNormalizedString(s2); if (s1==s2) return 0; // equal else return SYSYNC_NOT_COMPARABLE; // not equal, ordering makes no sense for tel numbers } // TTelephoneField::compareWith /* end of TTelephoneField implementation */ /* * Implementation of TTelephoneField */ TMultilineField::TMultilineField() { } // TMultilineField::TMultilineField TMultilineField::~TMultilineField() { } // TMultilineField::~TMultilineField // compare: returns 0 if equal, 1 if this > aItem, -1 if this < aItem, // SYSYNC_NOT_COMPARABLE if not equal and no ordering known or if field // types do not match. // Note: ordering may NOT be age relevant; it just means that an ordering // for this field type exists. // Note: Both fields must be assigned. NO TEST IS DONE HERE! sInt16 TMultilineField::compareWith(TItemField &aItemField, bool aCaseInsensitive) { if (!aItemField.isBasedOn(fty_multiline)) { // if other field is not multiline, try normal string comparison return TStringField::compareWith(aItemField); } // compare possible, return strcmp of normalized texts TMultilineField *mfP = static_cast(&aItemField); string s1,s2; getAsNormalizedString(s1); mfP->getAsNormalizedString(s2); // compare sInt8 result; if (aCaseInsensitive) result=strucmp(s1.c_str(),s2.c_str()); else result=strcmp(s1.c_str(),s2.c_str()); return result >0 ? 1 : (result<0 ? -1 : 0); } // TMultilineField::compareWith /* end of TMultilineField implementation */ /* * Implementation of TURLField */ TURLField::TURLField() { } // TURLField::TURLField TURLField::~TURLField() { } // TURLField::~TURLField void TURLField::stringWasAssigned(void) { // post-process string that was just assigned string proto; if (!fString.empty()) { // make sure we have a URL with protocol splitURL(fString.c_str() ,&proto, NULL, NULL, NULL, NULL, NULL, NULL); if (proto.empty()) { // no protocol set, but string not empty --> assume http fString.insert(0, "http://"); } } inherited::stringWasAssigned(); } // TURLField::stringWasAssigned /* end of TURLField implementation */ /* * Implementation of TTimestampField */ TTimestampField::TTimestampField(GZones *aGZonesP) { fGZonesP = aGZonesP; fTimestamp=0; fTimecontext=TCTX_UNKNOWN; } // TTimestampField::TTimestampField TTimestampField::~TTimestampField() { } // TTimestampField::~TTimestampField #if defined(CHECKSUM_CHANGELOG) && !defined(RECORDHASH_FROM_DBAPI) // changelog support: calculate CRC over contents uInt16 TTimestampField::getDataCRC(uInt16 crc) { // calculate CRC such that only a effective change in the time zone will cause a // CRC change: TCTX_SYSTEM must be converted to UTC as changing the system time zone // should not re-sync the entire calendar lineartime_t crcts = fTimestamp; timecontext_t crcctx = fTimecontext; if (TCTX_IS_SYSTEM(crcctx)) { if (TzConvertTimestamp(crcts,crcctx,TCTX_UTC,fGZonesP)) crcctx=TCTX_UTC; // use UTC representation for CRC (= same as in 3.0) } // try to avoid re-sync when upgrading from 3.0 to 3.1 if (TCTX_IS_UTC(crcctx)) crcctx=0; // this is what we had in 3.0 for non-floating timestamps // CRC over timestamp itself and zone offset crc=sysync_crc16_block(&crcts,sizeof(crcts),crc); return sysync_crc16_block(&crcctx,sizeof(crcctx),crc); } // TTimestampField::getDataCRC #endif // assignment TItemField& TTimestampField::operator=(TItemField &aItemField) { // assignment of empty (could be EMPTY or UNASSIGNED) must be handled by base class if (aItemField.isEmpty()) return TItemField::operator=(aItemField); // handle non-empty myself if (aItemField.isBasedOn(fty_timestamp)) { const TTimestampField *sfP = static_cast(&aItemField); fTimestamp=sfP->fTimestamp; fTimecontext=sfP->fTimecontext; fAssigned=sfP->fAssigned; } else if (aItemField.getCalcType()==fty_integer) { setAsInteger(aItemField.getAsInteger()); } else TItemField::operator=(aItemField); // generic cross-type assignment (via string) return *this; } // TTimestampField::operator= // compare: returns 0 if equal, 1 if this > aItem, -1 if this < aItem, // SYSYNC_NOT_COMPARABLE if not equal and no ordering known or if field // types do not match. // Note: ordering may NOT be age relevant; it just means that an ordering // for this field type exists. // Note: Both fields must be assigned. NO TEST IS DONE HERE! sInt16 TTimestampField::compareWith(TItemField &aItemField, bool aCaseInsensitive) { sInt16 res; lineartime_t cmpval; timecontext_t cmpcontext; // determine value to compare with if (aItemField.isBasedOn(fty_timestamp)) { cmpval=static_cast(&aItemField)->fTimestamp; cmpcontext=static_cast(&aItemField)->fTimecontext; } else { // not same type if (aItemField.getCalcType()==fty_integer) { // use second argument as lineartime units number cmpval=aItemField.getAsInteger(); cmpcontext=fTimecontext; // treat number as timestamp value in my own context } else { // use second argument as ISO8601 string string s; aItemField.getAsString(s); ISO8601StrToTimestamp(s.c_str(), cmpval, cmpcontext); if (TCTX_IS_UNKNOWN(cmpcontext)) cmpcontext=fTimecontext; // treat unqualified ISO timestamp in my own context } } // convert compare value into my own context (if not already so) if (!TzConvertTimestamp(cmpval,cmpcontext,fTimecontext,fGZonesP)) return SYSYNC_NOT_COMPARABLE; // contexts are not compatible to compare // compare possible, return strcmp-type result res=fTimestamp==cmpval ? 0 : (fTimestamp>cmpval ? 1 : -1); if (res!=0) { // greater/less-type result is valid only if both sides are not empty if (fTimestamp==0) return SYSYNC_NOT_COMPARABLE; // empty value, cannot compare if (cmpval==0) return SYSYNC_NOT_COMPARABLE; // empty value, cannot compare } return res; } // TTimestampField::compareWith #ifdef SYDEBUG // debug support size_t TTimestampField::StringObjFieldAppend(string &s, uInt16 aMaxStrLen) { // empty or unassigned is handled by base class if (isEmpty()) { return inherited::StringObjFieldAppend(s, aMaxStrLen); } string str; timecontext_t tctx; TimestampToISO8601Str(str,fTimestamp,fTimecontext,true,true); s.append(str); tctx=fTimecontext; if (TCTX_IS_TZ(tctx)) { // symbolic time zone not represented in ISO8601, show extra s.append(" ("); if (TCTX_IS_UNKNOWN(tctx)) { s.append("floating"); } else { if (TCTX_IS_SYSTEM(tctx)) { // is the system zone s.append("System "); // resolve from meta to symbolic zone TzResolveMetaContext(tctx,fGZonesP); } if (!TCTX_IS_BUILTIN(tctx)) { s.append("imported "); } s.append("TZ: "); // show time zone name TimeZoneContextToName(tctx,str,fGZonesP); s.append(str); } s.append(")"); } // size not known return 0; } // TTimestampField::StringObjFieldAppend #endif // SYDEBUG // set timestamp from ISO8601 string void TTimestampField::setAsString(cAppCharP aString) { // - set context if contained in ISO string, otherwise leave it as TCTX_UNKNOWN setAsISO8601(aString, TCTX_UNKNOWN, false); } // TTimestampField::setAsString // get timestamp as ISO8601 string (default representation) void TTimestampField::getAsString(string &aString) { // use default rendering // - show with current context, show UTC with Z but other zones without zone specifier getAsISO8601(aString,TCTX_UNKNOWN,true,false,false,false); } // getAsString /// @brief add a delta time to the timestamp /// @param aDeltaTime[in] : delta time value in lineartime_t units void TTimestampField::addTime(lineartime_t aDeltaTime) { fTimestamp=fTimestamp+aDeltaTime; fAssigned=true; } // TTimestampField::addTime /// @brief get time context /// @return minute offset east of UTC, returns 0 for floating timestamps (and UTC, of course) sInt16 TTimestampField::getMinuteOffset(void) { sInt16 moffs; if (TzResolveToOffset(fTimecontext, moffs, fTimestamp, false, fGZonesP)) return moffs; // found offset else return 0; // no offset (e.g. floating timestamp) } // TTimestampField::getMinuteOffset /// @brief test for floating time (=time not in a specified zone context) /// @return true if context is TCTX_UNKNOWN bool TTimestampField::isFloating(void) { return TCTX_IS_UNKNOWN(fTimecontext); } // TTimestampField::isFloating /// @brief make timestamp floating (i.e. remove time zone info from context) void TTimestampField::makeFloating(void) { // rendering flags from original context, new zone is UNKNOWN (=floating) fTimecontext = TCTX_JOIN_RFLAGS_TZ(fTimecontext, TCTX_UNKNOWN); } // TTimestampField::makeFloating /// @brief test for duration /// @return true if context has TCTX_DURATION rendering flag set bool TTimestampField::isDuration(void) { return TCTX_IS_DURATION(fTimecontext); } // TTimestampField::isDuration /// @brief make timestamp a duration (also implies making it floating) void TTimestampField::makeDuration(void) { // rendering flags from original context, new zone is UNKNOWN (=floating) fTimecontext |= TCTX_DURATION; makeFloating(); } // TTimestampField::makeDuration /// @brief get timestamp converted to a specified time context /// @param aTargetContext[in] : requests output context for timestamp. /// Use TCTX_UNKNOWN to get timestamp as-is. /// If timestamp is floating, it will always be returned as-is /// @param aActualContext[out] : if not NULL, the actual context of the returned value /// will be returned here. This might be another // context than specified with aTargetContext depending on floating/notime status. /// @return timestamp in lineartime lineartime_t TTimestampField::getTimestampAs(timecontext_t aTargetContext, timecontext_t *aActualContext) { // default context is that of the field (will be overwritten if result is moved to another context) if (aActualContext) *aActualContext = fTimecontext; // current field's context // if no time set or TCTX_UNKNOWN specified, just return the timestamp as-is if (fTimestamp==noLinearTime || TCTX_IS_UNKNOWN(aTargetContext)) { return TCTX_IS_DATEONLY(aTargetContext) ? lineartime2dateonlyTime(fTimestamp) : // truncated to date-only fTimestamp; // as-is } // convert to the requested context lineartime_t ts = fTimestamp; if (TCTX_IS_DATEONLY(fTimecontext)) { // is date only, connot convert to another zone, just return date part (and original context) return lineartime2dateonlyTime(ts); } else { // datetime or time if (!TzConvertTimestamp(ts,fTimecontext,aTargetContext,fGZonesP)) { // cannot convert, but we return unconverted timestamp if we can also return the actual context if (aActualContext) return fTimestamp; // return as-is else return noLinearTime; // invalid conversion, can't return a value } } // return target context as actual context if (aActualContext) *aActualContext = aTargetContext; // return timestamp, possibly truncated to date-only or time-only if requested if (TCTX_IS_DATEONLY(aTargetContext)) return lineartime2dateonlyTime(ts); else if (TCTX_IS_TIMEONLY(aTargetContext)) return lineartime2timeonly(ts); else return ts; // date and time } // TTimestampField::getTimestampAs /// @brief get timestamp as ISO8601 string. /// @param aISOString[out] : timestamp in ISO8601 format /// @param aTargetContext[in] : requests output context for timestamp. Use TCTX_UNKNOWN to show timestamp (or dateonly or timeonly) as-is. /// @param aShowWithZ[in] : if set and timezone is UTC, value will be shown with "Z" appended /// @param aShowWithZone[in] : if set and timestamp is not floating, zone offset will be appended in +-xx:xx form /// @param aExtFormat[in] : if set, ISO8601 extended format is used /// @param aWithFracSecs[in] : if set, fractions of seconds will be shown (millisecond resolution) void TTimestampField::getAsISO8601(string &aISOString, timecontext_t aTargetContext, bool aShowWithZ, bool aShowWithZone, bool aExtFormat, bool aWithFracSecs) { // get time in requested context lineartime_t ts = getTimestampAs(aTargetContext); // if target context was set to TCTX_UNKNOWN, this means that we want to use the stored context if (aTargetContext==TCTX_UNKNOWN) // really explicitly TCTX_UNKNOWN without any rendering flags! aTargetContext = fTimecontext; // return empty string if no timestamp or conversion impossible (but show empty duration as such!) if (ts==noLinearTime && !TCTX_IS_DURATION(fTimecontext)) { aISOString.erase(); return; } // check if time zone should be included or not if (!TCTX_IS_UNKNOWN(aTargetContext)) { if ( TCTX_IS_UTC(aTargetContext) ? !aShowWithZ : !aShowWithZone ) { // prevent showing with time zone aTargetContext = TCTX_JOIN_RFLAGS_TZ(aTargetContext,TCTX_UNKNOWN); } } // now convert TimestampToISO8601Str(aISOString, ts, aTargetContext, aExtFormat, aWithFracSecs); } // TTimestampField::getAsISO8601 /// @brief move timestamp to specified context (i.e. convert the timestamp value from current to /// specified context). Floating timestamps cannot and will not be moved. /// @param aNewcontext[in] : context to move timestamp to. /// timestamp will be converted to represent the same point in time in the new context /// @param aSetUnmovables : if set, non-movable timestamps will be just assigned the new context, // that is floating timestamps will be bound to specified context or // non-floating timestamps will be made floating if new context is TCTX_UNKNOWN bool TTimestampField::moveToContext(timecontext_t aNewcontext, bool aSetUnmovables) { bool ok=true; if (isFloating() || fTimestamp==noLinearTime) { // floating and empty timestamp cannot be moved if (aSetUnmovables) { // bind floating timestamp to specified zone fTimecontext = aNewcontext; } else ok=false; // floating/empty timestamps can only be fixed, not moved } else { // timestamp is not floating or empty if (TCTX_IS_UNKNOWN(aNewcontext)) { if (aSetUnmovables) fTimecontext = aNewcontext; // make floating else ok = false; } else { // new context is not floating and old context isn't, either -> convert ok = TzConvertTimestamp(fTimestamp, fTimecontext, aNewcontext, fGZonesP); } } if (ok) fTimecontext = aNewcontext; // we are now in the new context return ok; } // TTimestampField::moveToContext /// @brief set timestamp from ISO8601 string. /// @return true if successful /// @param aISOString[in] : timestamp in ISO8601 basic or extended format, optionally including Z or +xx:xx zone specifier /// @param aDefaultContext[in] : timezone context to use when ISO8601 does not specify a zone context or when aIgnoreZone is true /// @param aIgnoreZone[in] : if set, timezone specification contained in ISO8601 is ignored. Resulting time context will be aDefaultContext (or TCTX_UNKNOWN for date-only) bool TTimestampField::setAsISO8601(cAppCharP aISOString, timecontext_t aDefaultContext, bool aIgnoreZone) { bool ok = ISO8601StrToTimestamp(aISOString, fTimestamp, fTimecontext); if (ok) { fAssigned=true; // if timestamp has unknown zone because it is a date-only or a duration, do NOT assign the default zone! if (aIgnoreZone || (TCTX_IS_UNKNOWN(fTimecontext) && !TCTX_IS_DATEONLY(fTimecontext) && !TCTX_IS_DURATION(fTimecontext))) { // set default context fTimecontext = aDefaultContext; } } else assignEmpty(); // in all cases, this is now assigned (but probably empty if string was not ok) return ok; } // TTimestampField::setAsISO8601 #ifdef EMAIL_FORMAT_SUPPORT static cAppCharP const rfc822_weekdays[7] = { "Sun","Mon","Tue","Wed","Thu","Fri","Sat" }; const size_t rfc822maxMonthLen = 3; static cAppCharP const rfc822_months[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; /// @brief get timestamp as RFC(2)822 style date /// @param aRFC822String[out] : timestamp in RFC(2)822 format /// @param aTargetContext[in] : requests output context for timestamp. Use TCTX_UNKNOWN to show timestamp as-is. /// @param aShowWithZone[in] : if set and timestamp is not floating, zone offset will be shown void TTimestampField::getAsRFC822date(string &aRFC822String, timecontext_t aTargetContext, bool aShowWithZone) { // get time in requested context lineartime_t ts = getTimestampAs(aTargetContext); // if target context was set to TCTX_UNKNOWN, this means that we want to use the stored context if (TCTX_IS_UNKNOWN(aTargetContext)) aTargetContext = fTimecontext; // get elements sInt16 y,mo,d,h,mi,s,ms,w, moffs; lineartime2date(ts,&y,&mo,&d); lineartime2time(ts,&h,&mi,&s,&ms); w = lineartime2weekday(ts); // now print StringObjPrintf( aRFC822String, "%s, %02hd %s %04hd %02hd:%02hd:%02hd", rfc822_weekdays[w], d,rfc822_months[mo-1],y, h,mi,s ); if (aShowWithZone && !TCTX_IS_UNKNOWN(aTargetContext)) { // get offset TzResolveToOffset(aTargetContext, moffs, ts, false, fGZonesP); StringObjAppendPrintf( aRFC822String, " %c%02hd%02hd", moffs>=0 ? '+' : '-', (uInt16)(abs(moffs) / MinsPerHour), (uInt16)(abs(moffs) % MinsPerHour) ); } } // TTimestampField::getAsRFC822date /// @brief set timestamp as RFC(2)822 style date /// @return true if successful /// @param aRFC822String[in] : timestamp in RFC(2)822 format /// @param aDefaultContext[in] : timezone context to use when RFC822 date does not specify a time zone /// @param aIgnoreZone[in] : if set, timezone specification contained in input string is ignored. Resulting time context will be aDefaultContext bool TTimestampField::setAsRFC822date(cAppCharP aRFC822String, timecontext_t aDefaultContext, bool aIgnoreZone) { cAppCharP p; size_t inpSiz = strlen(aRFC822String); cAppCharP eot=aRFC822String+inpSiz; sInt16 minoffs=0; // check for weekday p = (cAppCharP) memchr(aRFC822String,',',inpSiz); if (p) p++; // skip comma else p=aRFC822String; // start at beginning // scan elements char month[rfc822maxMonthLen+1]; sInt16 y,mo,d,h,m,s; s=0; // optional second // scan day while (peot) return false; // string too short p+=StrToShort(p,d,2); // scan month while (peot) return false; // string too short p+=StrToShort(p,y,4); // scan time while (peot) return false; // string too short p+=StrToShort(p,h,2); if (p+3>eot || *p++ !=':') return false; // one for colon, two for minutes p+=StrToShort(p,m,2); if (p+3<=eot && *p==':') { // one for colon, two for minutes // optional second p++; p+=StrToShort(p,s,2); } // convert month for (mo=0; mo<12; mo++) if (strucmp(month,rfc822_months[mo])==0) break; if (mo==12) return false; // bad format mo++; // make month number // make timestamp fTimestamp = date2lineartime(y,mo,d) + time2lineartime(h,m,s,0); // check time zone bool neg=false; while (p=eot) return false; // string too short p++; sInt16 tzh,tzm; // scan timezone if ( p+4<=eot && StrToShort(p,tzh,2)==2 && StrToShort(p+2,tzm,2)==2 ) { p+=4; // set time zone minoffs=((tzh*MinsPerHour)+tzm); if (neg) minoffs = -minoffs; // make zone fTimecontext = TCTX_OFFSCONTEXT(minoffs); aIgnoreZone=false; // zone spec valid } } else if (isalpha(*p)) { // could be time zone name, internal or olson name (if not, ignore zone spec) aIgnoreZone = !TimeZoneNameToContext(p,fTimecontext,fGZonesP,true); } } // if no valid zone, use default if (aIgnoreZone) { // assume default time fTimecontext = aDefaultContext; } return true; } // RFC822dateToTimeStamp #endif // EMAIL_FORMAT_SUPPORT /* end of TTimestampField implementation */ /* * Implementation of TDateField */ TDateField::TDateField(GZones *aGZonesP) : TTimestampField(aGZonesP) { fTimecontext |= TCTX_DATEONLY; } // TDateField::TDateField TDateField::~TDateField() { } // TDateField::~TDateField // compare: returns 0 if equal, 1 if this > aItem, -1 if this < aItem, // SYSYNC_NOT_COMPARABLE if not equal and no ordering known or if field // types do not match. // Note: ordering may NOT be age relevant; it just means that an ordering // for this field type exists. // Note: Both fields must be assigned. NO TEST IS DONE HERE! sInt16 TDateField::compareWith(TItemField &aItemField, bool aCaseInsensitive) { sInt16 res; // check comparison with non-date if (!aItemField.isBasedOn(fty_timestamp)) return TTimestampField::compareWith(aItemField); // handles all comparisons with other types // date comparison is context independent TTimestampField *sfP = static_cast(&aItemField); // compare possible, return strcmp-type result // - convert to date only lineardate_t a = getTimestampAs(TCTX_UNKNOWN+TCTX_DATEONLY) / linearDateToTimeFactor; lineardate_t b = sfP->getTimestampAs(TCTX_UNKNOWN+TCTX_DATEONLY) / linearDateToTimeFactor; // - compare dates res=a==b ? 0 : (a>b ? 1 : -1); if (res!=0) { // greater/less-type result is valid only if both sides are not empty if ( isEmpty()) return SYSYNC_NOT_COMPARABLE; // empty value, cannot compare if (sfP->isEmpty()) return SYSYNC_NOT_COMPARABLE; // empty value, cannot compare } return res; } // TDateField::compareWith // get date as ISO8601 string (default representation) void TDateField::getAsString(string &aString) { // use default rendering // - show with current context, but always date-only, no Z or zone info inherited::getAsISO8601(aString,TCTX_UNKNOWN+TCTX_DATEONLY,false,false,false,false); } // TDateField::getAsString // set date from ISO8601 string (default interpretation) void TDateField::setAsString(cAppCharP aString) { // default interpretation is floating date // - parse timestamp, ignore timezone if (setAsISO8601(aString, TCTX_UNKNOWN+TCTX_DATEONLY, true)) { // truncate to date-only fTimestamp = lineartime2dateonlyTime(fTimestamp); } // in all cases, this is now assigned (but probably empty) fAssigned=true; } // TDateField::setAsString /* end of TDateField implementation */ /* * Implementation of TIntegerField */ TIntegerField::TIntegerField() { fInteger=0; fEmpty=true; } // TIntegerField::TIntegerField TIntegerField::~TIntegerField() { } // TIntegerField::~TIntegerField #if defined(CHECKSUM_CHANGELOG) && !defined(RECORDHASH_FROM_DBAPI) // changelog support: calculate CRC over contents uInt16 TIntegerField::getDataCRC(uInt16 crc) { // CRC over integer number return sysync_crc16_block(&fInteger,sizeof(fInteger),crc); } // TIntegerField::getDataCRC #endif // assignment TItemField& TIntegerField::operator=(TItemField &aItemField) { // assignment of empty (could be EMPTY or UNASSIGNED) must be handled by base class if (aItemField.isEmpty()) return TItemField::operator=(aItemField); // handle non-empty myself if (aItemField.isBasedOn(fty_integer)) { const TIntegerField *sfP = static_cast(&aItemField); fInteger=sfP->fInteger; fEmpty=sfP->fEmpty; fAssigned=sfP->fAssigned; } else if (aItemField.getCalcType()==fty_integer) { fInteger=aItemField.getAsInteger(); fEmpty=false; fAssigned=aItemField.isAssigned(); } else TItemField::operator=(aItemField); // generic cross-type assignment (via string) return *this; } // TIntegerField::operator= // compare: returns 0 if equal, 1 if this > aItem, -1 if this < aItem, // SYSYNC_NOT_COMPARABLE if not equal and no ordering known or if field // types do not match. // Note: ordering may NOT be age relevant; it just means that an ordering // for this field type exists. // Notes: - Both fields must be assigned. NO TEST IS DONE HERE! // - emptyness is not taken into account (empty counts as 0 here) sInt16 TIntegerField::compareWith(TItemField &aItemField, bool aCaseInsensitive) { if (aItemField.getCalcType()!=fty_integer) return TItemField::compareWith(aItemField); // handles generic comparisons fieldinteger_t otherInt = aItemField.getAsInteger(); // compare possible, return strcmp-type result return fInteger==otherInt ? 0 : (fInteger>otherInt ? 1 : -1); } // TIntegerField::compareWith // get integer as integer fieldinteger_t TIntegerField::getAsInteger(void) { return fInteger; } // TIntegerField::getAsInteger // set integer void TIntegerField::setAsInteger(fieldinteger_t aInteger) { fInteger=aInteger; fAssigned=true; fEmpty=false; } // TIntegerField::setAsInteger // set integer from numeric string void TIntegerField::setAsString(cAppCharP aString) { // check for hex bool ok; if (strucmp(aString,"0x",2)==0) { // hex number #ifndef NO64BITINT ok = HexStrToULongLong(aString+2,*((uInt64 *)&fInteger)); #else ok = HexStrToULong(aString+2,*((uInt32 *)&fInteger)); #endif } else { // decimal integer number #ifndef NO64BITINT ok = StrToLongLong(aString,fInteger); #else ok = StrToLong(aString,fInteger); #endif } if (!ok) fInteger=0; // defined value // setting with a non-integer value makes the integer empty (but having integer value 0) fEmpty = !ok; // in all cases, this is now assigned (but probably with the default=0) fAssigned=true; } // TIntegerField::setAsString // get integer as numeric string void TIntegerField::getAsString(string &aString) { if (fEmpty) aString.erase(); else { #ifndef NO64BITINT LONGLONGTOSTR(aString,PRINTF_LLD_ARG(fInteger)); #else StringObjPrintf(aString,"%ld",(sInt32)fInteger); #endif } } // TIntegerField::getAsString /* end of TIntegerField implementation */ // factory function TItemField *newItemField(const TItemFieldTypes aType, GZones *aGZonesP, bool aAsArray) { #ifdef ARRAYFIELD_SUPPORT if (aAsArray) { return new TArrayField(aType,aGZonesP); } else #endif { switch (aType) { case fty_string: return new TStringField; case fty_telephone: return new TTelephoneField; case fty_integer: return new TIntegerField; case fty_timestamp: return new TTimestampField(aGZonesP); case fty_date: return new TDateField(aGZonesP); case fty_url: return new TURLField; case fty_multiline: return new TMultilineField; case fty_blob: return new TBlobField; case fty_none: return new TItemField; // base class, can represent EMPTY and UNASSIGNED default: return NULL; } } } // newItemField #ifdef ENGINEINTERFACE_SUPPORT // TItemFieldKey // ============= // get value's ID (e.g. internal index) sInt32 TItemFieldKey::GetValueID(cAppCharP aName) { // check special suffixes size_t namsz = strlen(aName); sInt32 fldID = 0; // basic if (namsz >= strlen(VALSUFF_TZNAME) && strucmp(aName+namsz-strlen(VALSUFF_TZNAME),VALSUFF_TZNAME)==0) { // time zone name as string requested namsz-=7; fldID += VALID_FLAG_TZNAME; } else if (namsz >= strlen(VALSUFF_TZOFFS) && strucmp(aName+namsz-strlen(VALSUFF_TZOFFS),VALSUFF_TZOFFS)==0) { // time zone offset in minutes namsz-=7; fldID += VALID_FLAG_TZOFFS; } else if (namsz >= strlen(VALSUFF_NORM) && strucmp(aName+namsz-strlen(VALSUFF_NORM),VALSUFF_NORM)==0) { // normalized value namsz-=5; fldID += VALID_FLAG_NORM; } else if (namsz >= strlen(VALSUFF_ARRSZ) && strucmp(aName+namsz-strlen(VALSUFF_ARRSZ),VALSUFF_ARRSZ)==0) { // array size namsz-=10; fldID += VALID_FLAG_ARRSIZ; } else if (namsz >= strlen(VALSUFF_NAME) && strucmp(aName+namsz-strlen(VALSUFF_NAME),VALSUFF_NAME)==0) { // value name namsz-=8; fldID += VALID_FLAG_VALNAME; } else if (namsz >= strlen(VALSUFF_TYPE) && strucmp(aName+namsz-strlen(VALSUFF_TYPE),VALSUFF_TYPE)==0) { // value type namsz-=8; fldID += VALID_FLAG_VALTYPE; } // check if this is only a query for the flags alone if (strucmp(aName,VALNAME_FLAG,namsz)==0) return fldID; // return flags alone // get fid for given name sInt16 fid = getFidFor(aName,namsz); if (fid==VARIDX_UNDEFINED) return KEYVAL_ID_UNKNOWN; // unknown field else return fldID + (sInt32)((uInt16)fid); // return FID in lo word, flags in highword } // TItemFieldKey::GetValueID // get value's native type uInt16 TItemFieldKey::GetValueType(sInt32 aID) { // fid is lower 16 bits of aID (and gets negative if bit15 of aID is set) sInt16 fid; *((uInt16 *)(&fid)) = aID & VALID_MASK_FID; // assign without sign extension // now get base field TItemField *baseFieldP = getBaseFieldFromFid(fid); if (baseFieldP) { // field exists // - check special queries if (aID & VALID_FLAG_ARRSIZ) return VALTYPE_INT16; // size is a 16-bit integer, regardless of field type else if (aID & VALID_FLAG_VALNAME) return VALTYPE_TEXT; // name of the value is text else if (aID & VALID_FLAG_VALTYPE) return VALTYPE_INT16; // VALTYPE_XXX are 16-bit integers else if (aID & VALID_FLAG_NORM) return VALTYPE_TEXT; // normalized value is text // - otherwise, valtype depends on field type TItemFieldTypes fty = baseFieldP->getElementType(); // return native type switch (fty) { case fty_none: return VALTYPE_UNKNOWN; case fty_blob: return VALTYPE_BUF; case fty_string: case fty_multiline: case fty_telephone: case fty_url: return VALTYPE_TEXT; case fty_integer: return VALTYPE_INT64; case fty_timestamp: case fty_date: if (aID & VALID_FLAG_TZNAME) return VALTYPE_TEXT; // time zone name is a text else if (aID & VALID_FLAG_TZOFFS) return VALTYPE_INT16; // minute offset is 16-bit integer else return VALTYPE_TIME64; // time values case numFieldTypes: // invalid break; } // switch } // no field, no type return VALTYPE_UNKNOWN; } // TItemFieldKey::GetValueType // helper for getting a leaf field pointer (interpretation of aRepOffset depends on array field or not) TItemField *TItemFieldKey::getFieldFromFid(sInt16 aFid, sInt16 aRepOffset, bool aExistingOnly) { TItemField *fieldP=NULL; // get field (or base field) #ifdef ARRAYFIELD_SUPPORT fieldP = getBaseFieldFromFid(aFid); if (!fieldP) return NULL; // no field if (fieldP->isArray()) { // use aRepOffset as array index fieldP = fieldP->getArrayField(aRepOffset,aExistingOnly); } else #endif { // use aRepOffset as fid offset #ifdef SCRIPT_SUPPORT if (aFid<0) aRepOffset=0; // locals are never offset #endif fieldP = getBaseFieldFromFid(aFid+aRepOffset); } return fieldP; } // TItemFieldKey::getFieldFromFid // get value TSyError TItemFieldKey::GetValueInternal( sInt32 aID, sInt32 aArrayIndex, appPointer aBuffer, memSize aBufSize, memSize &aValSize ) { string sval; TItemField *fieldP; // fid is lower 16 bits of aID (and gets negative if bit15 of aID is set) sInt16 fid; *((uInt16 *)(&fid)) = aID & VALID_MASK_FID; // assign without sign extension // check for special queries not actually accessing a leaf field if (aID & VALID_FLAG_ARRSIZ) { // return array size (returns DB_NotFound for non-arrays) fieldP = getBaseFieldFromFid(fid); // if not an array, return DB_NotFound if (!fieldP || !fieldP->isArray()) return DB_NotFound; // there is no array size for non-arrays // return size aValSize=sizeof(sInt16); // value if enough room if (aBufSize>=aValSize) *((sInt16 *)aBuffer)=fieldP->arraySize(); // ok return LOCERR_OK; } else if (aID & VALID_FLAG_VALNAME) { // only return name of field if (!getFieldNameFromFid(fid,sval)) return DB_NotFound; if (aBufSize>=sval.size()) memcpy(aBuffer,sval.c_str(),sval.size()); // copy name data aValSize=sval.size(); return LOCERR_OK; } else if (aID & VALID_FLAG_VALTYPE) { // only return VALTYPE of field uInt16 valtype = GetValueType(aID & ~VALID_FLAG_VALTYPE); aValSize = sizeof(valtype); if (aBufSize>=aValSize) memcpy(aBuffer,&valtype,aValSize); // copy valtype uInt16 return LOCERR_OK; } // Get actual data - we need the leaf field (unless we pass <0 for aArrayIndex, which accesses the array base field) fieldP = getFieldFromFid(fid, aArrayIndex, true); // existing array elements only if (!fieldP) { // array instance does not exist return LOCERR_OUTOFRANGE; } else { // leaf field (or explicitly requested array base field) exists if (!fieldP->isAssigned()) return DB_NotFound; // no content found because none assigned if (fieldP->isEmpty()) return DB_NoContent; // empty if (fieldP->isArray()) return LOCERR_OUTOFRANGE; // no real access for array base field possible - if we get here it means non-empty // assigned and not empty, return actual value TItemFieldTypes fty = fieldP->getType(); appPointer valPtr = NULL; size_t sz; fieldinteger_t intVal; lineartime_t ts; timecontext_t tctx; sInt16 minOffs; TTimestampField *tsFldP; if (aID & VALID_FLAG_NORM) { // for all field types: get normalized string value fieldP->getAsNormalizedString(sval); aValSize = sval.size(); valPtr = (appPointer)sval.c_str(); } else { switch (fty) { case fty_timestamp: case fty_date: tsFldP = static_cast(fieldP); if (aID & VALID_FLAG_TZNAME) { // time zone name is a text sval.erase(); // no zone tctx = tsFldP->getTimeContext(); if (!TCTX_IS_UNKNOWN(tctx) || TCTX_IS_DURATION(tctx) || TCTX_IS_DATEONLY(tctx)) { // has a zone (or is duration/dateonly), get name TimeZoneContextToName(tctx, sval, tsFldP->getGZones()); } aValSize = sval.size(); valPtr = (appPointer)sval.c_str(); } else if (aID & VALID_FLAG_TZOFFS) { // minute offset as 16-bit integer aValSize = sizeof(sInt16); if ( tsFldP->isFloating() || !TzResolveToOffset(tsFldP->getTimeContext(), minOffs, tsFldP->getTimestampAs(TCTX_UNKNOWN), false, tsFldP->getGZones()) ) return DB_NotFound; // cannot get minute offset or floating timestamp -> no result // return minute offset valPtr = &minOffs; } else { // return timestamp itself (either as-is or in UTC, if TMODE_FLAG_FLOATING not set) aValSize = sizeof(lineartime_t); if (fTimeMode & TMODE_FLAG_FLOATING) ts = tsFldP->getTimestampAs(TCTX_UNKNOWN); // as-is else ts = tsFldP->getTimestampAs(TCTX_UTC,&tctx); // always as UTC, will be converted to SYSTEM possibly by caller // return timestamp valPtr = &ts; } break; case fty_integer: aValSize = sizeof(fieldinteger_t); intVal = fieldP->getAsInteger(); valPtr = &intVal; break; case fty_none: aValSize = 0; break; case fty_blob: static_cast(fieldP)->getBlobDataPtrSz(valPtr,sz); aValSize = sz; break; case fty_string: case fty_multiline: case fty_telephone: case fty_url: aValSize = fieldP->getStringSize(); valPtr = (appPointer)static_cast(fieldP)->getCStr(); break; case numFieldTypes: // invalid break; } // switch } // now we have valid aValSize and valPtr if (aBuffer && aBufSize>=aValSize) { // copy value data memcpy(aBuffer,valPtr,aValSize); } } // ok return LOCERR_OK; } // TItemFieldKey::GetValueInternal // set value TSyError TItemFieldKey::SetValueInternal( sInt32 aID, sInt32 aArrayIndex, cAppPointer aBuffer, memSize aValSize ) { TItemField *fieldP; // fid is lower 16 bits of aID (and gets negative if bit15 of aID is set) sInt16 fid; *((uInt16 *)(&fid)) = aID & VALID_MASK_FID; // assign without sign extension // check for special array size query if (aID & VALID_FLAG_ARRSIZ) { // array size is not writable return DB_NotAllowed; } // now get leaf field fieldP = getFieldFromFid(fid, aArrayIndex, false); // create element if needed if (!fieldP) { // should not happen return DB_Error; } else { // leaf field exists, set value fWritten = true; TItemFieldTypes fty = fieldP->getType(); fieldinteger_t intVal; lineartime_t ts; timecontext_t tctx; sInt16 minOffs; string sval; TTimestampField *tsFldP; // treat setting normalized value like setting as string if (aID & VALID_FLAG_NORM) fty = fty_string; // treat like string // handle NULL (empty) case if (aBuffer==0) { // buffer==NULL means NULL value fieldP->assignEmpty(); return LOCERR_OK; } // now handle according to type switch (fty) { case fty_timestamp: case fty_date: tsFldP = static_cast(fieldP); if (aID & VALID_FLAG_TZNAME) { // set time zone by name sval.assign((cAppCharP)aBuffer,aValSize); tctx = TCTX_UNKNOWN; if (!sval.empty()) { // convert (internal or olson names allowed) if (!TimeZoneNameToContext(sval.c_str(), tctx, tsFldP->getGZones(), true)) return LOCERR_BADPARAM; // bad timezone name } // set context tsFldP->setTimeContext(tctx); } else if (aID & VALID_FLAG_TZOFFS) { // minute offset as 16-bit integer minOffs = *((sInt16 *)aBuffer); // set context tsFldP->setTimeContext(TCTX_MINOFFSET(minOffs)); } else { // set timestamp itself (either as-is or in UTC, if TMODE_FLAG_FLOATING not set) ts = *((lineartime_t *)aBuffer); if ((fTimeMode & TMODE_FLAG_FLOATING)==0) tsFldP->setTimestampAndContext(ts,TCTX_UTC); // incoming timestamp is UTC, set it as such else tsFldP->setTimestamp(ts); // just set timestamp as-is and don't touch rest } break; case fty_integer: intVal = *((fieldinteger_t *)aBuffer); fieldP->setAsInteger(intVal); break; case fty_blob: static_cast(fieldP)->setBlobDataPtrSz((void *)aBuffer,aValSize); break; case fty_string: case fty_multiline: case fty_telephone: case fty_url: fieldP->setAsString((cAppCharP)aBuffer,aValSize); break; case fty_none: case numFieldTypes: // invalid break; } // switch } // ok return LOCERR_OK; } // TItemFieldKey::SetValueInternal #endif // ENGINEINTERFACE_SUPPORT } // namespace sysync // eof libsynthesis-3.4.0.47.1/src/sysync/itemfield.h000077500000000000000000000764771226375725500211260ustar00rootroot00000000000000/* * File: itemfield.h * * Author: Lukas Zeller (luz@plan44.ch) * * TItemField * Abstract class, holds a single field value * TStringField, TIntegerField, TTelephoneField, TTimeStampField etc. * Implementations of field types * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * 2001-08-08 : luz : created * */ #ifndef ItemField_H #define ItemField_H // includes #include "sysync_globs.h" #include "sysync_utils.h" #include "engineinterface.h" #include #ifdef ARRAYFIELD_SUPPORT #include #endif namespace sysync { extern cAppCharP const ItemFieldTypeNames[numFieldTypes]; extern const TPropDataTypes devInfPropTypes[numFieldTypes]; #ifndef NO64BITINT typedef sInt64 fieldinteger_t; #define StrToFieldinteger(s,i) StrToLongLong(s,i) #else typedef sInt32 fieldinteger_t; #define StrToFieldinteger(s,i) StrToLong(s,i) #endif // our own implementation for dynamic casts for Items without needing RTTI #define ITEMFIELD_DYNAMIC_CAST_PTR(ty,tyid,src) (src->isBasedOn(tyid) ? static_cast(src) : NULL) // basically abstract class, but can be used to represent EMPTY and ASSIGNED values class TItemField { public: TItemField(); virtual ~TItemField(); #ifdef ARRAYFIELD_SUPPORT // check array virtual bool isArray(void) const { return false; } virtual TItemField *getArrayField(sInt16 aArrIdx, bool /* aExistingOnly */=false) { return aArrIdx==0 ? this : NULL; }; virtual sInt16 arraySize(void) const { return 1; } // non-array has one element virtual TItemFieldTypes getElementType(void) const { return getType(); } // non array element is same as base type #else // non-virtual versions if we have no array fields at all bool isArray(void) const { return false; } TItemField *getArrayField(sInt16 aArrIdx, bool aExistingOnly=false) { return aArrIdx==0 ? this : NULL; }; sInt16 arraySize(void) const { return 1; } // non-array has one element TItemFieldTypes getElementType(void) const { return getType(); } #endif // changelog support #if defined(CHECKSUM_CHANGELOG) && !defined(RECORDHASH_FROM_DBAPI) virtual uInt16 getDataCRC(uInt16 crc=0) { return crc; }; // base class is always empty #endif // access to type virtual TItemFieldTypes getType(void) const { return fty_none; } // no real type virtual TItemFieldTypes getCalcType(void) const { return getType(); }; virtual bool isBasedOn(TItemFieldTypes aFieldType) const { return aFieldType==fty_none; }; virtual bool elementsBasedOn(TItemFieldTypes aFieldType) const { return isBasedOn(aFieldType); }; // dependency on a local ID virtual void setParentLocalID(cAppCharP /* aParentLocalID */) { /* nop */ }; // access to field contents #ifdef STREAMFIELD_SUPPORT // - stream interface (default implementation accesses string representation of field) virtual void resetStream(size_t aPos=0); virtual size_t getStreamSize(void) { return getStringSize(); }; virtual size_t getStreamPos(void) const { return fStreamPos; }; virtual size_t readStream(void *aBuffer, size_t aMaxBytes); virtual size_t writeStream(void *aBuffer, size_t aNumBytes); void appendStream(void) { resetStream(getStreamSize()); }; #endif virtual bool hasProxy(void) { return false; }; // normal fields don't have a proxy // - as string virtual void setAsString(cAppCharP /* aString */) { fAssigned=true; }; // basic setter, this one must be derived for all non-string descendants virtual void setAsString(cAppCharP aString, size_t aLen); virtual void setAsString(const string &aString) { setAsString(aString.c_str(),aString.size()); }; virtual void getAsString(string &aString) { aString.erase(); }; // empty string by default virtual void appendToString(string &aString, size_t aMaxLen=0) { string s; getAsString(s); if (aMaxLen) aString.append(s,0,aMaxLen); else aString.append(s); }; // generic append virtual cAppCharP getCStr(void) { return NULL; } // only real strings can return CStr (used for PalmOS optimization) virtual void getAsNormalizedString(string &aString) { getAsString(aString); }; virtual size_t getStringSize(void); // - as boolean (default: non-empty is true) virtual bool getAsBoolean(void) { return !isEmpty(); }; virtual void setAsBoolean(bool aBool) { if (aBool) setAsString("1"); else assignEmpty(); }; // - as integer virtual fieldinteger_t getAsInteger(void); virtual void setAsInteger(fieldinteger_t aInteger); // some string operations // - append string/char virtual void appendString(cAppCharP /* aString */, size_t /* aMaxChars */) { /* nop */ }; void appendString(cAppCharP aString) { appendString(aString,strlen(aString)); }; void appendString(const string &aString) { appendString(aString.c_str(),aString.size()); }; void appendChar(const char aChar) { appendString(&aChar,1); }; // - check if specified value is contained in myself virtual bool contains(TItemField &aItemField, bool aCaseInsensitive); // - find string in contents virtual sInt16 findInString(cAppCharP /* aString */, bool /* aCaseInsensitive */) { return -1; }; // - check if specified field is shortened version of this one virtual bool isShortVers(TItemField & /* aItemField */, sInt32 /* aOthersMax */) { return false; }; // - assignment virtual bool isAssigned(void) { return fAssigned; }; bool isUnassigned(void) { return !isAssigned(); }; virtual void unAssign(void) { fAssigned=false; }; // empty is NOT always same as unassigned; e.g. for strings empty can be empty string assigned virtual bool isEmpty(void) { return getType()==fty_none ? true : isUnassigned(); } // - make assigned, but empty (explicit "" string assigned) virtual void assignEmpty(void) { fAssigned=true; }; // assignment virtual TItemField& operator=(TItemField &aItemField); // field comparison bool operator==(TItemField &aItem) { return compareWith(aItem)==0; } bool operator!=(TItemField &aItem) { return compareWith(aItem)!=0; } bool operator>(TItemField &aItem) { return compareWith(aItem)>0; } bool operator>=(TItemField &aItem) { return compareWith(aItem)>=0; } bool operator<(TItemField &aItem) { return compareWith(aItem)<0; } bool operator<=(TItemField &aItem) { return compareWith(aItem)<=0; } // append (default to appending string value of other field) virtual void append(TItemField &aItemField); // merge fields virtual bool merge(TItemField & /* aItemField */, const char /* aSep */=0) { return false; /* nop */ }; // compare: returns 0 if equal, 1 if this > aItem, -1 if this < aItem, // SYSYNC_NOT_COMPARABLE if not comparable at all or not equal and no ordering known virtual sInt16 compareWith(TItemField & /* aItemField */, bool =false /* aCaseInsensitive */) { return SYSYNC_NOT_COMPARABLE; }; // debug support #ifdef SYDEBUG virtual size_t StringObjFieldAppend(string &s, uInt16 aMaxStrLen); // show field contents as string for debug output #endif protected: // assigned flag bool fAssigned; #ifdef STREAMFIELD_SUPPORT // stream position size_t fStreamPos; #endif }; // TItemField typedef TItemField *TItemFieldP; #ifdef ARRAYFIELD_SUPPORT typedef std::vector TFieldArray; // array field, contains a list of fields of TItemFields class TArrayField : public TItemField, noncopyable { typedef TItemField inherited; public: TArrayField(TItemFieldTypes aLeafFieldType, GZones *aGZonesP); virtual ~TArrayField(); // check array virtual bool isArray(void) const { return true; } virtual TItemField *getArrayField(sInt16 aArrIdx, bool aExistingOnly=false); virtual sInt16 arraySize(void) const { return fArray.size(); } // return size of array // changelog support #if defined(CHECKSUM_CHANGELOG) && !defined(RECORDHASH_FROM_DBAPI) virtual uInt16 getDataCRC(uInt16 crc=0); #endif // access to type virtual TItemFieldTypes getType(void) const { return fty_none; } // array has no type virtual TItemFieldTypes getElementType(void) const { return fLeafFieldType; } // type of leaf fields (accessible even if array is empty) virtual bool elementsBasedOn(TItemFieldTypes aFieldType) const; // some string operations // - assignment virtual bool isAssigned(void) { return !isEmpty() || fAssigned; }; // empty, but explicitly assigned so is assigned as well virtual void unAssign(void); // clear all elements and clear fAssigned // - append string to array = append string as last element of array virtual void appendString(cAppCharP aString, size_t aMaxChars); // empty is array with no elements virtual bool isEmpty(void) { return arraySize()==0; }; // - make assigned virtual void assignEmpty(void) { unAssign(); fAssigned = true; }; // assigning emptyness must make isAssigned true! // assignment virtual TItemField& operator=(TItemField &aItemField); // check if specified value is contained in myself virtual bool contains(TItemField &aItemField, bool aCaseInsensitive); // append (default to appending value of other field as a new array element) virtual void append(TItemField &aItemField); // merge fields virtual bool merge(TItemField & /* aItemField */, const char /* aSep */=0) { return false; /* nop */ }; // compare: returns 0 if equal, 1 if this > aItem, -1 if this < aItem, // SYSYNC_NOT_COMPARABLE if not comparable at all or not equal and no ordering known virtual sInt16 compareWith(TItemField &aItemField, bool aCaseInsensitive=false); // debug support #ifdef SYDEBUG virtual size_t StringObjFieldAppend(string &s, uInt16); // show field contents as string for debug output #endif protected: // type of contained leaf fields TItemFieldTypes fLeafFieldType; // first field, is instantiated with array to allow type comparisons TItemField *fFirstField; // Zones for fields GZones *fGZonesP; // actual field vector TFieldArray fArray; }; // TArrayField #endif #ifndef STREAMFIELD_SUPPORT #define PULLFROMPROXY #define DELETEPROXY #define PROXYINSTALLED false #else #define PULLFROMPROXY pullFromProxy() #define DELETEPROXY setBlobProxy(NULL) #define PROXYINSTALLED (fBlobProxyP!=NULL) // forward class TStringField; // abstract Proxy object for Blob contents, allows loading a BLOB from DB at the moment it is // actually required. // Intended to be derived by database implementations class TBlobProxy { public: TBlobProxy() { fUsage=1; } // initial creator also gets owner virtual ~TBlobProxy() {}; // - returns size of entire blob virtual size_t getBlobSize(TStringField *aFieldP) = 0; // - read from Blob from specified stream position and update stream pos virtual size_t readBlobStream(TStringField *aFieldP, size_t &aPos, void *aBuffer, size_t aMaxBytes) = 0; // - dependency on a local ID virtual void setParentLocalID(cAppCharP aParentLocalID) { /* nop */ }; // - usage control void link(void) { fUsage++; }; static void unlink(TBlobProxy *&aProxyP) { if (aProxyP) { if (--(aProxyP->fUsage) == 0) delete aProxyP; aProxyP=NULL; } }; private: uInt16 fUsage; }; // TBlobProxy #endif // string field. // Note that a string can also be a string of binary data, // not only a NUL-terminated string (as used in derived blob class) class TStringField: public TItemField { typedef TItemField inherited; friend class TBlobProxy; public: TStringField(); virtual ~TStringField(); // access to type virtual TItemFieldTypes getType(void) const { return fty_string; }; virtual bool isBasedOn(TItemFieldTypes aFieldType) const { return aFieldType==fty_string ? true : TItemField::isBasedOn(aFieldType); }; // changelog support #if defined(CHECKSUM_CHANGELOG) && !defined(RECORDHASH_FROM_DBAPI) virtual uInt16 getDataCRC(uInt16 crc=0); #endif // assignment virtual TItemField& operator=(TItemField &aItemField); // access to normalized version of content virtual void getAsNormalizedString(string &aString); // access to field contents #ifdef STREAMFIELD_SUPPORT // - set blob loader proxy (ownership is passed to field) void setBlobProxy(TBlobProxy *aBlobProxyP); // - stream interface virtual size_t getStreamSize(void); virtual size_t readStream(void *aBuffer, size_t aMaxBytes); virtual size_t writeStream(void *aBuffer, size_t aNumBytes); virtual bool hasProxy(void) { return fBlobProxyP!=NULL; }; // - stream field proxies actually can have dependencies on a local ID virtual void setParentLocalID(cAppCharP aParentLocalID) { if (fBlobProxyP) fBlobProxyP->setParentLocalID(aParentLocalID); }; #endif // - as string virtual void setAsString(cAppCharP aString) { DELETEPROXY; if (aString) fString=aString; else fString.erase(); stringWasAssigned(); }; virtual void setAsString(const string &aString) { DELETEPROXY; fString=aString; stringWasAssigned(); }; // works even if string contains NULs virtual void setAsString(cAppCharP aString, size_t aLen); virtual void getAsString(string &aString) { PULLFROMPROXY; aString=fString; }; virtual void appendToString(string &aString, size_t aMaxLen=0) { PULLFROMPROXY; if (aMaxLen) aString.append(fString,0,aMaxLen); else aString.append(fString); }; virtual cAppCharP getCStr(void) { PULLFROMPROXY; return fString.c_str(); } // string can return CStr (used for PalmOS optimization) virtual size_t getStringSize(void); // can cause proxied values to be retrieved, so use with care with BLOBS virtual void unAssign(void) { DELETEPROXY; fString.erase(); TItemField::unAssign(); }; // empty test virtual bool isEmpty(void) { return isUnassigned() || getStringSize()==0; } virtual void assignEmpty(void) { DELETEPROXY; fString.erase(); TItemField::assignEmpty(); }; // some string operations // - append string virtual void appendString(cAppCharP aString, size_t aMaxChars); // - check if specified field is shortened version of this one virtual bool isShortVers(TItemField &aItemField, sInt32 aOthersMax); // - check if String is contained in value and returns position virtual sInt16 findInString(cAppCharP aString, bool aCaseInsensitive=false); // merge fields virtual bool merge(TItemField &aItemField, const char aSep=0); // compare: returns 0 if equal, 1 if this > aItem, -1 if this < aItem // SYSYNC_NOT_COMPARABLE if not equal and no ordering known virtual sInt16 compareWith(TItemField &aItemField, bool aCaseInsensitive=false); #ifdef STREAMFIELD_SUPPORT void pullFromProxy(void); #endif // debug support #ifdef SYDEBUG virtual size_t StringObjFieldAppend(string &s, uInt16 aMaxStrLen); #endif protected: virtual void stringWasAssigned(void) { fAssigned=true; }; // post-process string that was just assigned #ifdef STREAMFIELD_SUPPORT TBlobProxy *fBlobProxyP; #endif string fString; }; // TStringField // BLOB field. This is a string field but has many direct access functions // disabled, contents should only be read using stream interface, // comparing is not possible class TBlobField: public TStringField { typedef TStringField inherited; public: TBlobField(); virtual ~TBlobField(); // access to type virtual TItemFieldTypes getType(void) const { return fty_blob; }; virtual bool isBasedOn(TItemFieldTypes aFieldType) const { return aFieldType==fty_blob ? true : TStringField::isBasedOn(aFieldType); }; // changelog support // Note: uses inherited implementation of TStringField // assignment virtual TItemField& operator=(TItemField &aItemField); // - as string virtual void getAsString(string &aString) { StringObjPrintf(aString,"", long(getStringSize())); }; // must be read with stream interface void getBlobAsString(string &aString) { TStringField::getAsString(aString); }; // must use this one to get as string // - as Pointer/Data void getBlobDataPtrSz(void *&aPtr, size_t &aSize) { aPtr=(void *)TStringField::getCStr(); aSize=TStringField::getStringSize(); }; void setBlobDataPtrSz(void *aPtr, size_t aSize) { setAsString((cAppCharP)aPtr, aSize); }; // - test virtual bool isEmpty(void) { return isUnassigned(); } // do not test for empty string as this would cause BLOB to be read // some string operations // - check if specified field is shortened version of this one virtual bool isShortVers(TItemField & /* aItemField */, sInt32 /* aOthersMax */) { return false; }; // cannot compare // - check if String is contained in value and returns position virtual sInt16 findInString(cAppCharP /* aString */, bool /* aCaseInsensitive */) { return -1; }; // cannot search // merge fields virtual bool merge(TItemField & /* aItemField */, const char /* aSep */=0) { return false; }; // cannot merge // compare: returns 0 if equal, 1 if this > aItem, -1 if this < aItem // SYSYNC_NOT_COMPARABLE if not equal and no ordering known virtual sInt16 compareWith(TItemField & /* aItemField */, bool /* aCaseInsensitive */) { return SYSYNC_NOT_COMPARABLE; }; // cannot compare // make contents and encoding/charset valid void makeContentsValid(void) { PULLFROMPROXY; }; // debug support #ifdef SYDEBUG virtual size_t StringObjFieldAppend(string &s, uInt16 aMaxStrLen); // show field contents as string for debug output #endif // extra info about BLOB contents TEncodingTypes fHasEncoding; TEncodingTypes fWantsEncoding; TCharSets fCharset; }; // TBlobField // telephone number string field // compares normalized version of number text (only +*# and digits) class TTelephoneField: public TStringField { typedef TStringField inherited; public: TTelephoneField(); virtual ~TTelephoneField(); // access to type virtual TItemFieldTypes getType(void) const { return fty_telephone; }; virtual TItemFieldTypes getCalcType(void) const { return fty_string; }; virtual bool isBasedOn(TItemFieldTypes aFieldType) const { return aFieldType==fty_telephone ? true : TStringField::isBasedOn(aFieldType); }; // assignment virtual TItemField& operator=(TItemField &aItemField) { return TStringField::operator=(aItemField); }; // access to normalized version of content virtual void getAsNormalizedString(string &aString); // compare: returns 0 if equal, 1 if this > aItem, -1 if this < aItem // SYSYNC_NOT_COMPARABLE if not equal and no ordering known virtual sInt16 compareWith(TItemField &aItemField, bool aCaseInsensitive=false); }; // TTelephoneField // multiline string field // compares without any leading or trailing whitespace, linefeeds, controlchars class TMultilineField: public TStringField { typedef TStringField inherited; public: TMultilineField(); virtual ~TMultilineField(); // access to type virtual TItemFieldTypes getType(void) const { return fty_multiline; }; virtual TItemFieldTypes getCalcType(void) const { return fty_string; }; virtual bool isBasedOn(TItemFieldTypes aFieldType) const { return aFieldType==fty_multiline ? true : TStringField::isBasedOn(aFieldType); }; // assignment virtual TItemField& operator=(TItemField &aItemField) { return TStringField::operator=(aItemField); }; // compare: returns 0 if equal, 1 if this > aItem, -1 if this < aItem // SYSYNC_NOT_COMPARABLE if not equal and no ordering known virtual sInt16 compareWith(TItemField &aItemField, bool aCaseInsensitive=false); }; // TMultilineField // URL field // normalizes URL (appends http:// if no protocol part specified) class TURLField: public TStringField { typedef TStringField inherited; public: TURLField(); virtual ~TURLField(); // access to type virtual TItemFieldTypes getType(void) const { return fty_url; }; virtual TItemFieldTypes getCalcType(void) const { return fty_string; }; virtual bool isBasedOn(TItemFieldTypes aFieldType) const { return aFieldType==fty_url ? true : TStringField::isBasedOn(aFieldType); }; // assignment virtual TItemField& operator=(TItemField &aItemField) { return TStringField::operator=(aItemField); }; //%%%virtual void setAsString(cAppCharP aString); virtual void stringWasAssigned(void); // post-process string that was just assigned }; // TURLField class TTimestampField: public TItemField { typedef TItemField inherited; public: TTimestampField(GZones *aGZonesP); virtual ~TTimestampField(); // access to type virtual TItemFieldTypes getType(void) const { return fty_timestamp; }; virtual TItemFieldTypes getCalcType(void) const { return fty_integer; }; virtual bool isBasedOn(TItemFieldTypes aFieldType) const { return aFieldType==fty_timestamp ? true : TItemField::isBasedOn(aFieldType); }; // assignment virtual TItemField& operator=(TItemField &aItemField); // changelog support #if defined(CHECKSUM_CHANGELOG) && !defined(RECORDHASH_FROM_DBAPI) virtual uInt16 getDataCRC(uInt16 crc=0); #endif // access to field contents virtual void setAsString(cAppCharP aString); virtual void getAsString(string &aString); virtual fieldinteger_t getAsInteger(void) { return (fieldinteger_t)fTimestamp; }; virtual void setAsInteger(fieldinteger_t aInteger) { fTimestamp = (lineartime_t)aInteger; }; // does not touch the timecontext! virtual void unAssign(void) { fTimestamp=noLinearTime; fTimecontext=TCTX_UNKNOWN; TItemField::unAssign(); }; // empty test (zero timestamp means empty, unless it is a duration) virtual bool isEmpty(void) { return isUnassigned() || (fTimestamp==noLinearTime && !TCTX_IS_DURATION(fTimecontext)); } virtual void assignEmpty(void) { fTimestamp=noLinearTime; fTimecontext=TCTX_UNKNOWN; TItemField::assignEmpty(); }; // compare: returns 0 if equal, 1 if this > aItem, -1 if this < aItem // SYSYNC_NOT_COMPARABLE if not equal and no ordering known virtual sInt16 compareWith(TItemField &aItemField, bool aCaseInsensitive=false); // type specific access and utilities /// @brief add a delta time to the timestamp /// @param aDeltaTime[in] : delta time value in lineartime_t units void addTime(lineartime_t aDeltaTime); /// @brief get time context /// @return time context timecontext_t getTimeContext(void) { return fTimecontext; } /// @brief get time context /// @return minute offset east of UTC, returns 0 for floating timestamps (and UTC, of course) sInt16 getMinuteOffset(void); /// @brief test for floating time (=time not in a specified zone context) /// @return true if context is TCTX_UNKNOWN bool isFloating(void); /// @brief make timestamp floating (i.e. remove time zone info from context) void makeFloating(void); /// @brief test for duration /// @return true if context has TCTX_DURATION rendering flag set bool isDuration(void); /// @brief make timestamp a duration (also implies making it floating) void makeDuration(void); /// @brief get timestamp converted to a specified time context /// @param aTargetContext[in] : requests output context for timestamp. /// Use TCTX_UNKNOWN to get timestamp as-is. /// If timestamp is floating, it will always be returned as-is /// @param aActualContext[out] : if not NULL, the actual context of the returned value /// will be returned here. This might be another // context than specified with aTargetContext depending on floating/notime status. /// @return timestamp in lineartime lineartime_t getTimestampAs(timecontext_t aTargetContext, timecontext_t *aActualContext=NULL); /// @brief get timestamp as ISO8601 string. /// @param aISOString[out] : timestamp in ISO8601 format /// @param aTargetContext[in] : requests output context for timestamp. Use TCTX_UNKNOWN to show timestamp as-is. /// @param aShowWithZ[in] : if set and timezone is UTC, value will be shown with "Z" appended /// @param aShowWithZone[in] : if set and timestamp is not floating, zone offset will be appended in +-xx:xx form /// @param aExtFormat[in] : if set, ISO8601 extended format is used /// @param aWithFracSecs[in] : if set, fractions of seconds will be shown (millisecond resolution) void getAsISO8601(string &aISOString, timecontext_t aTargetContext, bool aShowWithZ=true, bool aShowWithZone=false, bool aExtFormat=false, bool aWithFracSecs=false); /// @brief set timestamp value and context /// @param aTimestamp[in] : timestamp to set /// @param aTimecontext[in] : context to set void setTimestampAndContext(lineartime_t aTimestamp, timecontext_t aTimecontext) { setTimestamp(aTimestamp); setTimeContext(aTimecontext); }; /// @brief set timestamp value without context /// @param aTimestamp[in] : timestamp to set void setTimestamp(lineartime_t aTimestamp) { fTimestamp=aTimestamp; fAssigned=true; }; /// @brief set timestamp value and context /// @param aTimecontext[in] : context to set (timestamp will not be touched or converted) virtual void setTimeContext(timecontext_t aTimecontext) { fTimecontext=aTimecontext; fAssigned=true; }; /// @brief move timestamp to specified context (i.e. convert the timestamp value from current to /// specified context). Floating timestamps cannot and will not be moved. /// @param aNewcontext[in] : context to move timestamp to. /// timestamp will be converted to represent the same point in time in the new context /// @param aSetUnmovables : if set, non-movable timestamps will be just assigned the new context, // that is floating timestamps will be bound to specified context or // non-floating timestamps will be made floating if new context is TCTX_UNKNOWN bool moveToContext(timecontext_t aNewcontext, bool aSetUnmovables=false); /// @brief set timestamp from ISO8601 string. /// @return true if successful /// @param aISOString[in] : timestamp in ISO8601 basic or extended format, optionally including Z or +xx:xx zone specifier /// @param aDefaultContext[in] : timezone context to use when ISO8601 does not specify a zone context or when aIgnoreZone is true /// @param aIgnoreZone[in] : if set, timezone specification contained in ISO8601 is ignored. Resulting time context will be aDefaultContext bool setAsISO8601(cAppCharP aISOString, timecontext_t aDefaultContext=TCTX_UNKNOWN, bool aIgnoreZone=false); #ifdef EMAIL_FORMAT_SUPPORT /// @brief get timestamp as RFC(2)822 style date /// @param aRFC822String[out] : timestamp in RFC(2)822 format /// @param aTargetContext[in] : requests output context for timestamp. Use TCTX_UNKNOWN to show timestamp as-is. /// @param aShowWithZone[in] : if set and timestamp is not floating, zone offset will be shown void getAsRFC822date(string &aRFC822String, timecontext_t aTargetContext, bool aShowWithZone=false); /// @brief set timestamp as RFC(2)822 style date /// @return true if successful /// @param aRFC822String[in] : timestamp in RFC(2)822 format /// @param aDefaultContext[in] : timezone context to use when RFC822 date does not specify a time zone /// @param aIgnoreZone[in] : if set, timezone specification contained in input string is ignored. Resulting time context will be aDefaultContext bool setAsRFC822date(cAppCharP aRFC822String, timecontext_t aDefaultContext=TCTX_UNKNOWN, bool aIgnoreZone=false); #endif // EMAIL_FORMAT_SUPPORT // debug support #ifdef SYDEBUG virtual size_t StringObjFieldAppend(string &s, uInt16 aMaxStrLen); #endif GZones *getGZones(void) { return fGZonesP; }; protected: lineartime_t fTimestamp; // timestamp in context indicated by fTimecontext timecontext_t fTimecontext; // context/options of timestamp GZones *fGZonesP; // zones }; // TTimestampField class TDateField: public TTimestampField { typedef TTimestampField inherited; public: TDateField(GZones *aGZonesP); virtual ~TDateField(); // assignment virtual TItemField& operator=(TItemField &aItemField) { return TTimestampField::operator=(aItemField); }; // access to type virtual TItemFieldTypes getType(void) const { return fty_date; }; virtual TItemFieldTypes getCalcType(void) const { return fty_integer; }; virtual bool isBasedOn(TItemFieldTypes aFieldType) const { return aFieldType==fty_date ? true : TTimestampField::isBasedOn(aFieldType); }; // access to field contents virtual void setAsString(cAppCharP aString); virtual void getAsString(string &aString); // compare: returns 0 if equal, 1 if this > aItem, -1 if this < aItem // SYSYNC_NOT_COMPARABLE if not equal and no ordering known virtual sInt16 compareWith(TItemField &aItemField, bool aCaseInsensitive=false); /// @brief set timestamp value and context /// @param aTimecontext[in] : context to set (timestamp will not be touched or converted) virtual void setTimeContext(timecontext_t aTimecontext) { fTimecontext=aTimecontext | TCTX_DATEONLY; fAssigned=true; }; }; // TDateField class TIntegerField: public TItemField { typedef TItemField inherited; public: TIntegerField(); virtual ~TIntegerField(); // access to type virtual TItemFieldTypes getType(void) const { return fty_integer; }; virtual bool isBasedOn(TItemFieldTypes aFieldType) const { return aFieldType==fty_integer ? true : TItemField::isBasedOn(aFieldType); }; // assignment virtual TItemField& operator=(TItemField &aItemField); // changelog support #if defined(CHECKSUM_CHANGELOG) && !defined(RECORDHASH_FROM_DBAPI) virtual uInt16 getDataCRC(uInt16 crc=0); #endif // access to field contents // - as string virtual void setAsString(cAppCharP aString); virtual void getAsString(string &aString); virtual void unAssign(void) { fInteger=0; TItemField::unAssign(); }; // - as boolean (empty is false, zero value is false, other values are true) virtual bool getAsBoolean(void) { return !(isEmpty() || fInteger==0); }; virtual void setAsBoolean(bool aBool) { fAssigned=true; fEmpty=false; if (aBool) fInteger=1; else fInteger=0; }; virtual fieldinteger_t getAsInteger(void); virtual void setAsInteger(fieldinteger_t aInteger); // empty test and assignment virtual bool isEmpty(void) { return isUnassigned() || fEmpty; }; virtual void assignEmpty(void) { fInteger=0; fEmpty=true; TItemField::assignEmpty(); }; // compare: returns 0 if equal, 1 if this > aItem, -1 if this < aItem // SYSYNC_NOT_COMPARABLE if not equal and no ordering known virtual sInt16 compareWith(TItemField &aItemField, bool aCaseInsensitive=false); protected: fieldinteger_t fInteger; // integer value bool fEmpty; // extra empty flag }; // TIntegerField // factory function TItemField *newItemField(const TItemFieldTypes aType, GZones *aGZonesP, bool aAsArray=false); #ifdef ENGINEINTERFACE_SUPPORT // special flags coded into value ID #define VALID_FLAG_TZNAME 0x010000 #define VALID_FLAG_TZOFFS 0x020000 #define VALID_FLAG_ARRSIZ 0x040000 #define VALID_FLAG_VALNAME 0x080000 #define VALID_FLAG_VALTYPE 0x100000 #define VALID_FLAG_NORM 0x200000 #define VALID_MASK_FID 0x00FFFF // key for access to a item using the settings key API class TItemFieldKey : public TSettingsKeyImpl { typedef TSettingsKeyImpl inherited; public: TItemFieldKey(TEngineInterface *aEngineInterfaceP) : inherited(aEngineInterfaceP), fWritten(false) {}; // get value's ID (e.g. internal index) virtual sInt32 GetValueID(cAppCharP aName); bool isWritten(void) { return fWritten; }; protected: // get value's native type virtual uInt16 GetValueType(sInt32 aID); // get value virtual TSyError GetValueInternal( sInt32 aID, sInt32 aArrayIndex, appPointer aBuffer, memSize aBufSize, memSize &aValSize ); // set value virtual TSyError SetValueInternal( sInt32 aID, sInt32 aArrayIndex, cAppPointer aBuffer, memSize aValSize ); // flag that will be set on first write access bool fWritten; // abstract methods to actually access a TItemField virtual sInt16 getFidFor(cAppCharP aName, stringSize aNameSz) = 0; virtual TItemField *getBaseFieldFromFid(sInt16 aFid) = 0; virtual bool getFieldNameFromFid(sInt16 aFid, string &aFieldName) { return false; /* no name */ }; private: // utility TItemField *getFieldFromFid(sInt16 aFid, sInt16 aRepOffset, bool aExistingOnly=false); }; // TItemFieldKey #endif // ENGINEINTERFACE_SUPPORT } // namespace sysync #endif // ItemField_H // eof libsynthesis-3.4.0.47.1/src/sysync/localengineds.cpp000066400000000000000000010646501226375725500223120ustar00rootroot00000000000000/** * @File localengineds.cpp * * @Author Lukas Zeller (luz@plan44.ch) * * @brief TLocalEngineDS * Abstraction of the local datastore - interface class to the * sync engine. * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * @Date 2005-09-15 : luz : created from localdatastore */ // includes #include "prefix_file.h" #include "sysync.h" #include "localengineds.h" #include "syncappbase.h" #include "scriptcontext.h" #include "superdatastore.h" #include "syncagent.h" using namespace sysync; namespace sysync { #ifdef SYDEBUG cAppCharP const LocalDSStateNames[numDSStates] = { "idle", "client_initialized", "admin_ready", "client_sent_alert", "server_alerted", "server_answered_alert", "client_alert_statused", "client_alerted", "sync_mode_stable", "data_access_started", "sync_set_ready", "client_sync_gen_started", "server_seen_client_mods", "server_sync_gen_started", "sync_gen_done", "data_access_done", "client_maps_sent", "admin_done", "completed" }; #endif #ifdef OBJECT_FILTERING // add a new expression to an existing filter static void addToFilter(const char *aNewFilter, string &aFilter, bool aORChain=false) { if (aNewFilter && *aNewFilter) { // just assign if current filter expression is empty if (aFilter.empty()) aFilter = aNewFilter; else { // construct new filter string newFilter; StringObjPrintf(newFilter,"(%s)%c(%s)",aFilter.c_str(),aORChain ? '|' : '&',aNewFilter); aFilter = newFilter; } } } // addToFilter #endif #ifdef SCRIPT_SUPPORT // Script functions // ================ class TLDSfuncs { public: #ifdef OBJECT_FILTERING #ifdef SYNCML_TAF_SUPPORT // string GETCGITARGETFILTER() // returns current CGI-specified target address filter expression static void func_GetCGITargetFilter(TItemField *&aTermP, TScriptContext *aFuncContextP) { TLocalEngineDS *dsP = static_cast(aFuncContextP->getCallerContext()); aTermP->setAsString(dsP->fTargetAddressFilter.c_str()); }; // func_GetCGITargetFilter // string GETTARGETFILTER() // returns current internal target address filter expression static void func_GetTargetFilter(TItemField *&aTermP, TScriptContext *aFuncContextP) { TLocalEngineDS *dsP = static_cast(aFuncContextP->getCallerContext()); aTermP->setAsString(dsP->fIntTargetAddressFilter.c_str()); }; // func_GetTargetFilter // SETTARGETFILTER(string filter) // sets (overwrites) the internal target address filter static void func_SetTargetFilter(TItemField *&aTermP, TScriptContext *aFuncContextP) { TLocalEngineDS *dsP = static_cast(aFuncContextP->getCallerContext()); aFuncContextP->getLocalVar(0)->getAsString(dsP->fIntTargetAddressFilter); }; // func_SetTargetFilter // ADDTARGETFILTER(string filter) // adds a filter expression to the existing internal targetfilter (automatically paranthesizing and adding AND) static void func_AddTargetFilter(TItemField *&aTermP, TScriptContext *aFuncContextP) { string f; TLocalEngineDS *dsP = static_cast(aFuncContextP->getCallerContext()); aFuncContextP->getLocalVar(0)->getAsString(f); addToFilter(f.c_str(),dsP->fIntTargetAddressFilter,false); // AND-chaining }; // func_AddTargetFilter #endif // SYNCML_TAF_SUPPORT // string GETFILTER() // returns current sync set filter expression static void func_GetFilter(TItemField *&aTermP, TScriptContext *aFuncContextP) { TLocalEngineDS *dsP = static_cast(aFuncContextP->getCallerContext()); aTermP->setAsString(dsP->fSyncSetFilter.c_str()); }; // func_GetFilter // SETFILTER(string filter) // sets (overwrites) the current sync set filter static void func_SetFilter(TItemField *&aTermP, TScriptContext *aFuncContextP) { TLocalEngineDS *dsP = static_cast(aFuncContextP->getCallerContext()); aFuncContextP->getLocalVar(0)->getAsString(dsP->fSyncSetFilter); dsP->engFilteredFetchesFromDB(true); // update filter dependencies }; // func_SetFilter // ADDFILTER(string filter) // adds a filter expression to the existing (dynamic) targetfilter (automatically paranthesizing and adding AND) static void func_AddFilter(TItemField *&aTermP, TScriptContext *aFuncContextP) { string f; TLocalEngineDS *dsP = static_cast(aFuncContextP->getCallerContext()); aFuncContextP->getLocalVar(0)->getAsString(f); addToFilter(f.c_str(),dsP->fSyncSetFilter,false); // AND-chaining dsP->engFilteredFetchesFromDB(true); // update filter dependencies }; // func_AddFilter // ADDSTATICFILTER(string filter) // adds a filter expression to the existing (static) localdbfilter (automatically paranthesizing and adding AND) static void func_AddStaticFilter(TItemField *&aTermP, TScriptContext *aFuncContextP) { string f; TLocalEngineDS *dsP = static_cast(aFuncContextP->getCallerContext()); aFuncContextP->getLocalVar(0)->getAsString(f); addToFilter(f.c_str(),dsP->fLocalDBFilter,false); // AND-chaining dsP->engFilteredFetchesFromDB(true); // update filter dependencies }; // func_AddStaticFilter #endif // OBJECT_FILTERING #ifdef SYSYNC_TARGET_OPTIONS // string DBOPTIONS() // returns current DB options static void func_DBOptions(TItemField *&aTermP, TScriptContext *aFuncContextP) { TLocalEngineDS *dsP = static_cast(aFuncContextP->getCallerContext()); aTermP->setAsString(dsP->fDBOptions.c_str()); }; // func_DBOptions // integer DBHANDLESOPTS() // returns true if database can completely handle options like /dr() and /li during fetching static void func_DBHandlesOpts(TItemField *&aTermP, TScriptContext *aFuncContextP) { aTermP->setAsBoolean( static_cast(aFuncContextP->getCallerContext())->dsOptionFilterFetchesFromDB() ); }; // func_DBHandlesOpts // timestamp STARTDATE() // returns startdate if one is set in datastore static void func_StartDate(TItemField *&aTermP, TScriptContext *aFuncContextP) { lineartime_t d = static_cast(aFuncContextP->getCallerContext())->fDateRangeStart; TTimestampField *resP = static_cast(aTermP); if (d==noLinearTime) resP->assignEmpty(); else resP->setTimestampAndContext(d,TCTX_UTC); }; // func_StartDate // SETSTARTDATE(timestamp startdate) // sets startdate for datastore static void func_SetStartDate(TItemField *&aTermP, TScriptContext *aFuncContextP) { TTimestampField *tsP = static_cast(aFuncContextP->getLocalVar(0)); timecontext_t tctx; static_cast(aFuncContextP->getCallerContext())->fDateRangeStart = tsP->getTimestampAs(TCTX_UTC,&tctx); // floating will also be treated as UTC }; // func_SetStartDate // timestamp ENDDATE() // returns enddate if one is set in datastore static void func_EndDate(TItemField *&aTermP, TScriptContext *aFuncContextP) { lineartime_t d = static_cast(aFuncContextP->getCallerContext())->fDateRangeEnd; TTimestampField *resP = static_cast(aTermP); if (d==noLinearTime) resP->assignEmpty(); else resP->setTimestampAndContext(d,TCTX_UTC); }; // func_EndDate // SETENDDATE(timestamp startdate) // sets enddate for datastore static void func_SetEndDate(TItemField *&aTermP, TScriptContext *aFuncContextP) { TTimestampField *tsP = static_cast(aFuncContextP->getLocalVar(0)); timecontext_t tctx; static_cast(aFuncContextP->getCallerContext())->fDateRangeEnd = tsP->getTimestampAs(TCTX_UTC,&tctx); // floating will also be treated as UTC }; // func_SetEndDate // integer DEFAULTSIZELIMIT() // returns limit set for all items in this datastore (the /li(xxx) CGI option value) static void func_DefaultLimit(TItemField *&aTermP, TScriptContext *aFuncContextP) { fieldinteger_t i = static_cast(aFuncContextP->getCallerContext())->fSizeLimit; if (i<0) aTermP->unAssign(); // no limit else aTermP->setAsInteger(i); }; // func_DefaultLimit // SETDEFAULTSIZELIMIT(integer limit) // sets limit for all items in this datastore (the /li(xxx) CGI option value) static void func_SetDefaultLimit(TItemField *&aTermP, TScriptContext *aFuncContextP) { static_cast(aFuncContextP->getCallerContext())->fSizeLimit = aFuncContextP->getLocalVar(0)->getAsInteger(); }; // func_SetDefaultLimit // integer NOATTACHMENTS() // returns true if attachments should be suppressed (/na CGI option) static void func_NoAttachments(TItemField *&aTermP, TScriptContext *aFuncContextP) { aTermP->setAsBoolean( static_cast(aFuncContextP->getCallerContext())->fNoAttachments ); }; // func_NoAttachments // SETNOATTACHMENTS(integer flag) // if true, attachments will be suppressed (/na CGI option) static void func_SetNoAttachments(TItemField *&aTermP, TScriptContext *aFuncContextP) { static_cast(aFuncContextP->getCallerContext())->fNoAttachments = aFuncContextP->getLocalVar(0)->getAsBoolean(); }; // func_SetNoAttachments // integer MAXITEMCOUNT() // returns item count limit (0=none) as set by /max(n) CGI option static void func_MaxItemCount(TItemField *&aTermP, TScriptContext *aFuncContextP) { aTermP->setAsInteger( static_cast(aFuncContextP->getCallerContext())->fMaxItemCount ); }; // func_MaxItemCount // SETMAXITEMCOUNT(integer maxcount) // set item count limit (0=none) as set by /max(n) CGI option static void func_SetMaxItemCount(TItemField *&aTermP, TScriptContext *aFuncContextP) { static_cast(aFuncContextP->getCallerContext())->fMaxItemCount = aFuncContextP->getLocalVar(0)->getAsInteger(); }; // func_SetMaxItemCount #endif // SYSYNC_TARGET_OPTIONS // integer SLOWSYNC() // returns true if we are in slow sync static void func_SlowSync(TItemField *&aTermP, TScriptContext *aFuncContextP) { aTermP->setAsBoolean( static_cast(aFuncContextP->getCallerContext())->isSlowSync() ); }; // func_SlowSync // FORCESLOWSYNC() // force a slow sync (like with /na CGI option) static void func_ForceSlowSync(TItemField *&aTermP, TScriptContext *aFuncContextP) { static_cast(aFuncContextP->getCallerContext())->engForceSlowSync(); }; // func_ForceSlowSync // integer ALERTCODE() // returns the alert code as currently know by datastore (might change from normal to slow while processing) static void func_AlertCode(TItemField *&aTermP, TScriptContext *aFuncContextP) { aTermP->setAsInteger( static_cast(aFuncContextP->getCallerContext())->fAlertCode ); }; // func_AlertCode // SETALERTCODE(integer maxcount) // set the alert code (makes sense in alertscript to modify the incoming code to something different) static void func_SetAlertCode(TItemField *&aTermP, TScriptContext *aFuncContextP) { static_cast(aFuncContextP->getCallerContext())->fAlertCode = aFuncContextP->getLocalVar(0)->getAsInteger(); }; // func_SetAlertCode // integer REFRESHONLY() // returns true if sync is only refreshing local (note that alert code might be different, as local // refresh can take place without telling the remote so, for compatibility with clients that do not support the mode) static void func_RefreshOnly(TItemField *&aTermP, TScriptContext *aFuncContextP) { aTermP->setAsBoolean( static_cast(aFuncContextP->getCallerContext())->isRefreshOnly() ); }; // func_RefreshOnly // SETREFRESHONLY(integer flag) // modifies the refresh only flag (one way sync from remote to local only) // Note that clearing this flag when a client has alerted one-way will probably lead to an error static void func_SetRefreshOnly(TItemField *&aTermP, TScriptContext *aFuncContextP) { static_cast(aFuncContextP->getCallerContext())->engSetRefreshOnly( aFuncContextP->getLocalVar(0)->getAsBoolean() ); }; // func_SetRefreshOnly // integer CACHEDATA() // returns true if sync is refreshing local data in caching mode (without deleting everything beforehand) static void func_CacheData(TItemField *&aTermP, TScriptContext *aFuncContextP) { aTermP->setAsBoolean( static_cast(aFuncContextP->getCallerContext())->isCacheData() ); }; // func_CacheData static void func_SetCacheData(TItemField *&aTermP, TScriptContext *aFuncContextP) { static_cast(aFuncContextP->getCallerContext())->engSetCacheData( aFuncContextP->getLocalVar(0)->getAsBoolean() ); }; // func_SetCacheData // integer READONLY() // returns true if sync is read-only (only reading from local datastore) static void func_ReadOnly(TItemField *&aTermP, TScriptContext *aFuncContextP) { aTermP->setAsBoolean( static_cast(aFuncContextP->getCallerContext())->isReadOnly() ); }; // func_ReadOnly // SETREADONLY(integer flag) // modifies the read only flag (only reading from local datastore) static void func_SetReadOnly(TItemField *&aTermP, TScriptContext *aFuncContextP) { static_cast(aFuncContextP->getCallerContext())->engSetReadOnly( aFuncContextP->getLocalVar(0)->getAsBoolean() ); }; // func_SetReadOnly // integer FIRSTTIMESYNC() // returns true if we are in first time slow sync static void func_FirstTimeSync(TItemField *&aTermP, TScriptContext *aFuncContextP) { aTermP->setAsBoolean( static_cast(aFuncContextP->getCallerContext())->isFirstTimeSync() ); }; // func_FirstTimeSync // void SETCONFLICTSTRATEGY(string strategy) // sets conflict strategy for this session static void func_SetConflictStrategy(TItemField *&aTermP, TScriptContext *aFuncContextP) { // convert to syncop string s; aFuncContextP->getLocalVar(0)->getAsString(s); sInt16 strategy; StrToEnum(conflictStrategyNames,numConflictStrategies, strategy, s.c_str()); static_cast(aFuncContextP->getCallerContext())->fSessionConflictStrategy = (TConflictResolution) strategy; }; // func_SetConflictStrategy // string DBNAME() // returns name of DB static void func_DBName(TItemField *&aTermP, TScriptContext *aFuncContextP) { aTermP->setAsString( static_cast(aFuncContextP->getCallerContext())->getName() ); }; // func_DBName // void ABORTDATASTORE(integer statuscode) static void func_AbortDatastore(TItemField *&aTermP, TScriptContext *aFuncContextP) { static_cast(aFuncContextP->getCallerContext())->engAbortDataStoreSync(aFuncContextP->getLocalVar(0)->getAsInteger(),true); // we cause the abort locally } // func_AbortDatastore // string LOCALDBNAME() // returns name of local DB with which it was identified for the sync static void func_LocalDBName(TItemField *&aTermP, TScriptContext *aFuncContextP) { aTermP->setAsString( static_cast(aFuncContextP->getCallerContext())->getIdentifyingName() ); }; // func_LocalDBName // string REMOTEDBNAME() // returns remote datastore's full name (as used by the remote in command, may contain subpath and CGI) static void func_RemoteDBName(TItemField *&aTermP, TScriptContext *aFuncContextP) { TLocalEngineDS *dsP = static_cast(aFuncContextP->getCallerContext()); aTermP->setAsString(dsP->getRemoteDatastore()->getFullName()); }; // func_RemoteDBName #ifdef SYSYNC_CLIENT // ADDTARGETCGI(string cgi) // adds CGI to the target URI. If target URI already contains a ?, string will be just // appended, otherwise a ? is added, then the new CGI. // Note: if string to be added is already contained, it will not be added again static void func_AddTargetCGI(TItemField *&aTermP, TScriptContext *aFuncContextP) { TLocalEngineDS *dsP = static_cast(aFuncContextP->getCallerContext()); // Add extra CGI specified string cgi; aFuncContextP->getLocalVar(0)->getAsString(cgi); addCGItoString(dsP->fRemoteDBPath,cgi.c_str(),true); }; // func_AddTargetCGI // SETRECORDFILTER(string filter, boolean inclusive) // Sets record level filter expression for remote static void func_SetRecordFilter(TItemField *&aTermP, TScriptContext *aFuncContextP) { TLocalEngineDS *dsP = static_cast(aFuncContextP->getCallerContext()); // put into record level filter if (dsP->getSession()->getSyncMLVersion()>=syncml_vers_1_2) { // DS 1.2: use aFuncContextP->getLocalVar(0)->getAsString(dsP->fRemoteRecordFilterQuery); dsP->fRemoteFilterInclusive = aFuncContextP->getLocalVar(1)->getAsBoolean(); } else if (!aFuncContextP->getLocalVar(0)->isEmpty()) { // DS 1.1 and below and not empty filter: add as cgi string filtercgi; if (aFuncContextP->getLocalVar(1)->getAsBoolean()) filtercgi = "/tf("; // exclusive, use TAF else filtercgi = "/fi("; // inclusive, use sync set filter aFuncContextP->getLocalVar(0)->appendToString(filtercgi); filtercgi += ')'; addCGItoString(dsP->fRemoteDBPath,filtercgi.c_str(),true); } }; // func_SetRecordFilter // SETDAYSRANGE(integer daysbefore, integer daysafter) // Sets type of record filter static void func_SetDaysRange(TItemField *&aTermP, TScriptContext *aFuncContextP) { TLocalEngineDS *dsP = static_cast(aFuncContextP->getCallerContext()); // get params int daysbefore = aFuncContextP->getLocalVar(0)->getAsInteger(); int daysafter = aFuncContextP->getLocalVar(1)->getAsInteger(); // depending on SyncML version, create a SINCE/BEFORE filter or use the /dr(x,y) syntax if (dsP->getSession()->getSyncMLVersion()>=syncml_vers_1_2 && static_cast(dsP->getSession())->fServerHasSINCEBEFORE) { // use the SINCE/BEFORE syntax // BEFORE&EQ;20070808T000000Z&AND;SINCE&EQ;20070807T000000Z lineartime_t now = getSystemNowAs(TCTX_UTC,aFuncContextP->getSessionZones()); string ts; // AND-chain with possibly existing filter cAppCharP sep = ""; if (!dsP->fRemoteRecordFilterQuery.empty()) sep = "&AND;"; if (daysbefore>=0) { dsP->fRemoteRecordFilterQuery += sep; dsP->fRemoteRecordFilterQuery += "SINCE&EQ;"; TimestampToISO8601Str(ts,now-daysbefore*linearDateToTimeFactor,TCTX_UTC,false,false); dsP->fRemoteRecordFilterQuery += ts; sep = "&AND;"; } if (daysafter>=0) { dsP->fRemoteRecordFilterQuery += sep; dsP->fRemoteRecordFilterQuery += "BEFORE&EQ;"; TimestampToISO8601Str(ts,now+daysafter*linearDateToTimeFactor,TCTX_UTC,false,false); dsP->fRemoteRecordFilterQuery += ts; } } else { // use the /dr(-x,y) syntax string rangecgi; StringObjPrintf(rangecgi,"/dr(%ld,%ld)",(long int)(-daysbefore),(long int)(daysafter)); addCGItoString(dsP->fRemoteDBPath,rangecgi.c_str(),true); } }; // func_SetDaysRange #endif // SYSYNC_CLIENT }; // TLDSfuncs const uInt8 param_FilterArg[] = { VAL(fty_string) }; const uInt8 param_DateArg[] = { VAL(fty_timestamp) }; const uInt8 param_IntArg[] = { VAL(fty_integer) }; const uInt8 param_StrArg[] = { VAL(fty_string) }; const uInt8 param_OneInteger[] = { VAL(fty_integer) }; const TBuiltInFuncDef DBFuncDefs[] = { #ifdef OBJECT_FILTERING #ifdef SYNCML_TAF_SUPPORT { "GETCGITARGETFILTER", TLDSfuncs::func_GetCGITargetFilter, fty_string, 0, NULL }, { "GETTARGETFILTER", TLDSfuncs::func_GetTargetFilter, fty_string, 0, NULL }, { "SETTARGETFILTER", TLDSfuncs::func_SetTargetFilter, fty_none, 1, param_FilterArg }, { "ADDTARGETFILTER", TLDSfuncs::func_AddTargetFilter, fty_none, 1, param_FilterArg }, #endif { "GETFILTER", TLDSfuncs::func_GetFilter, fty_string, 0, NULL }, { "SETFILTER", TLDSfuncs::func_SetFilter, fty_none, 1, param_FilterArg }, { "ADDFILTER", TLDSfuncs::func_AddFilter, fty_none, 1, param_FilterArg }, { "ADDSTATICFILTER", TLDSfuncs::func_AddStaticFilter, fty_none, 1, param_FilterArg }, #endif #ifdef SYSYNC_TARGET_OPTIONS { "DBOPTIONS", TLDSfuncs::func_DBOptions, fty_string, 0, NULL }, { "STARTDATE", TLDSfuncs::func_StartDate, fty_timestamp, 0, NULL }, { "ENDDATE", TLDSfuncs::func_EndDate, fty_timestamp, 0, NULL }, { "SETSTARTDATE", TLDSfuncs::func_SetStartDate, fty_none, 1, param_DateArg }, { "SETENDDATE", TLDSfuncs::func_SetEndDate, fty_none, 1, param_DateArg }, { "MAXITEMCOUNT", TLDSfuncs::func_MaxItemCount, fty_integer, 0, NULL }, { "SETMAXITEMCOUNT", TLDSfuncs::func_SetMaxItemCount, fty_none, 1, param_IntArg }, { "NOATTACHMENTS", TLDSfuncs::func_NoAttachments, fty_integer, 0, NULL }, { "SETNOATTACHMENTS", TLDSfuncs::func_SetNoAttachments, fty_none, 1, param_IntArg }, { "DEFAULTSIZELIMIT", TLDSfuncs::func_DefaultLimit, fty_integer, 0, NULL }, { "SETDEFAULTSIZELIMIT", TLDSfuncs::func_SetDefaultLimit, fty_none, 1, param_IntArg }, { "DBHANDLESOPTS", TLDSfuncs::func_DBHandlesOpts, fty_integer, 0, NULL }, #endif { "ALERTCODE", TLDSfuncs::func_AlertCode, fty_integer, 0, NULL }, { "SETALERTCODE", TLDSfuncs::func_SetAlertCode, fty_none, 1, param_IntArg }, { "SLOWSYNC", TLDSfuncs::func_SlowSync, fty_integer, 0, NULL }, { "FORCESLOWSYNC", TLDSfuncs::func_ForceSlowSync, fty_none, 0, NULL }, { "REFRESHONLY", TLDSfuncs::func_RefreshOnly, fty_integer, 0, NULL }, { "SETREFRESHONLY", TLDSfuncs::func_SetRefreshOnly, fty_none, 1, param_IntArg }, { "CACHEDATA", TLDSfuncs::func_CacheData, fty_integer, 0, NULL }, { "SETCACHEDATA", TLDSfuncs::func_SetCacheData, fty_none, 1, param_IntArg }, { "READONLY", TLDSfuncs::func_ReadOnly, fty_integer, 0, NULL }, { "SETREADONLY", TLDSfuncs::func_SetReadOnly, fty_none, 1, param_IntArg }, { "FIRSTTIMESYNC", TLDSfuncs::func_FirstTimeSync, fty_integer, 0, NULL }, { "SETCONFLICTSTRATEGY", TLDSfuncs::func_SetConflictStrategy, fty_none, 1, param_StrArg }, { "DBNAME", TLDSfuncs::func_DBName, fty_string, 0, NULL }, { "LOCALDBNAME", TLDSfuncs::func_LocalDBName, fty_string, 0, NULL }, { "REMOTEDBNAME", TLDSfuncs::func_RemoteDBName, fty_string, 0, NULL }, { "ABORTDATASTORE", TLDSfuncs::func_AbortDatastore, fty_none, 1, param_OneInteger }, }; // functions for all datastores const TFuncTable DBFuncTable = { sizeof(DBFuncDefs) / sizeof(TBuiltInFuncDef), // size of table DBFuncDefs, // table pointer NULL // no chain func }; #ifdef SYSYNC_CLIENT const uInt8 param_OneStr[] = { VAL(fty_string) }; const uInt8 param_OneInt[] = { VAL(fty_integer) }; const uInt8 param_TwoInt[] = { VAL(fty_integer), VAL(fty_integer) }; const uInt8 param_SetRecordFilter[] = { VAL(fty_string), VAL(fty_integer) }; const TBuiltInFuncDef ClientDBFuncDefs[] = { { "ADDTARGETCGI", TLDSfuncs::func_AddTargetCGI, fty_none, 1, param_OneStr }, { "SETRECORDFILTER", TLDSfuncs::func_SetRecordFilter, fty_none, 2, param_SetRecordFilter }, { "SETDAYSRANGE", TLDSfuncs::func_SetDaysRange, fty_none, 2, param_TwoInt }, }; // chain to general DB functions static void *ClientDBChainFunc(void *&aCtx) { // caller context remains unchanged // -> no change needed // next table is general DS func table return (void *)&DBFuncTable; } // ClientDBChainFunc // function table for client-only script functions const TFuncTable ClientDBFuncTable = { sizeof(ClientDBFuncDefs) / sizeof(TBuiltInFuncDef), // size of table ClientDBFuncDefs, // table pointer ClientDBChainFunc // chain to general agent funcs. }; #endif // SYSYNC_CLIENT #endif // SCRIPT_SUPPORT // config // ====== // conflict strategy names // bfo: Problems with XCode (expicit qualification), already within namespace ? //const char * const sysync::conflictStrategyNames[numConflictStrategies] = { const char * const conflictStrategyNames[numConflictStrategies] = { "duplicate", // add conflicting counterpart to both databases "newer-wins", // newer version wins (if date/version comparison is possible, like sst_duplicate otherwise) "server-wins", // server version wins (and is written to client) "client-wins" // client version wins (and is written to server) }; // type support config TTypeSupportConfig::TTypeSupportConfig(const char* aName, TConfigElement *aParentElement) : TConfigElement(aName,aParentElement) { clear(); } // TTypeSupportConfig::TTypeSupportConfig TTypeSupportConfig::~TTypeSupportConfig() { clear(); } // TTypeSupportConfig::~TTypeSupportConfig // init defaults void TTypeSupportConfig::clear(void) { // init defaults fPreferredTx = NULL; fPreferredRx = NULL; fPreferredLegacy = NULL; fAdditionalTypes.clear(); #ifndef NO_REMOTE_RULES fRuleMatchTypes.clear(); #endif // clear inherited inherited::clear(); } // TTypeSupportConfig::clear #ifdef HARDCODED_CONFIG // add type support bool TTypeSupportConfig::addTypeSupport( cAppCharP aTypeName, bool aForRead, bool aForWrite, bool aPreferred, cAppCharP aVariant, cAppCharP aRuleMatch ) { // search datatype TDataTypeConfig *typecfgP = static_cast(getRootElement())->fDatatypesConfigP->getDataType(aTypeName); if (!typecfgP) return false; // search variant TTypeVariantDescriptor variantDescP = NULL; if (aVariant && *aVariant) variantDescP = typecfgP->getVariantDescriptor(aVariant); // now add datatype if (aPreferred) { // - preferred if (aForRead) { if (!fPreferredRx) { fPreferredRx=typecfgP; // set it fPrefRxVariantDescP=variantDescP; } } if (aForWrite) { if (!fPreferredTx) { fPreferredTx=typecfgP; // set it fPrefTxVariantDescP=variantDescP; } } } // if preferred else { // - additional TAdditionalDataType adt; adt.datatypeconfig=typecfgP; adt.forRead=aForRead; adt.forWrite=aForWrite; adt.variantDescP=variantDescP; // variant of that type #ifndef NO_REMOTE_RULES if (aRuleMatch) { // this is a rulematch type (which overrides normal type selection mechanism) AssignString(atd.remoteRuleMatch,aRuleMatch); // remote rule match string fRuleMatchTypes.push_back(adt); // save it in the list } else #endif { // standard type fAdditionalTypes.push_back(adt); // save it in the list } } return true; } // TTypeSupportConfig::addTypeSupport #else // config element parsing bool TTypeSupportConfig::localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine) { // checking the elements if (strucmp(aElementName,"use")==0) { expectEmpty(); // datatype usage specs may not have // process arguments const char* nam = getAttr(aAttributes,"datatype"); if (!nam) return fail("use must have 'datatype' attribute"); // search datatype TDataTypeConfig *typecfgP = static_cast(getRootElement())->fDatatypesConfigP->getDataType(nam); if (!typecfgP) return fail("unknown datatype '%s' specified",nam); #ifndef NO_REMOTE_RULES // get rulematch string, if any cAppCharP ruleMatch = getAttr(aAttributes,"rulematch"); #endif // convert variant TTypeVariantDescriptor variantDescP=NULL; // no variant descriptor by default cAppCharP variant = getAttr(aAttributes,"variant"); if (variant) { // get a type-specific descriptor which describes the variant of a type to be used with this datastore variantDescP = typecfgP->getVariantDescriptor(variant); if (!variantDescP) return fail("unknown variant '%s' specified",variant); } // convert mode bool rd=true,wr=true; const char* mode = getAttr(aAttributes,"mode"); if (mode) { rd=false; wr=false; while (*mode) { if (tolower(*mode)=='r') rd=true; else if (tolower(*mode)=='w') wr=true; else { ReportError(true,"invalid mode '%c'",*mode); return true; } // next char mode++; } if (!rd && !wr) return fail("mode must specify 'r', 'w' or 'rw' at least"); } // get preferred bool preferred=false; const char* pref = getAttr(aAttributes,"preferred"); if (pref) { if (!StrToBool(pref, preferred)) { if (strucmp(pref,"legacy")==0) { // this is the preferred type for blind and legacy mode sync attempts fPreferredLegacy=typecfgP; // remember (note that there is only ONE preferred type, mode is ignored) preferred=false; // not officially preferred } else return fail("bad value for 'preferred'"); } } // now add datatype if (preferred) { // - preferred if (rd) { if (fPreferredRx) return fail("preferred read type already defined"); else { fPreferredRx=typecfgP; // set it fPrefRxVariantDescP=variantDescP; } } if (wr) { if (fPreferredTx) return fail("preferred write type already defined"); else { fPreferredTx=typecfgP; // set it fPrefTxVariantDescP=variantDescP; } } } // if preferred else { // - additional TAdditionalDataType adt; adt.datatypeconfig=typecfgP; adt.forRead=rd; adt.forWrite=wr; adt.variantDescP=variantDescP; #ifndef NO_REMOTE_RULES if (ruleMatch) { // this is a rulematch type (which overrides normal type selection mechanism) AssignString(adt.remoteRuleMatch,ruleMatch); // remote rule match string fRuleMatchTypes.push_back(adt); // save it in the list } else #endif { // standard type fAdditionalTypes.push_back(adt); // save it in the list } } } // - none known here else return inherited::localStartElement(aElementName,aAttributes,aLine); // ok return true; } // TTypeSupportConfig::localStartElement #endif // resolve void TTypeSupportConfig::localResolve(bool aLastPass) { #ifndef HARDCODED_CONFIG if (aLastPass) { // check for required settings if (!fPreferredTx || !fPreferredRx) SYSYNC_THROW(TConfigParseException("'typesupport' must contain at least one preferred type for read and write")); } #endif // resolve inherited inherited::localResolve(aLastPass); } // TTypeSupportConfig::localResolve // datastore config TLocalDSConfig::TLocalDSConfig(const char* aName, TConfigElement *aParentElement) : TConfigElement(aName,aParentElement), fTypeSupport("typesupport",this) { clear(); } // TLocalDSConfig::TLocalDSConfig TLocalDSConfig::~TLocalDSConfig() { // nop so far } // TLocalDSConfig::~TLocalDSConfig // init defaults void TLocalDSConfig::clear(void) { // init defaults // - conflict resolution strategy fConflictStrategy=cr_newer_wins; fSlowSyncStrategy=cr_newer_wins; fFirstTimeStrategy=cr_newer_wins; // options fLocalDBTypeID=0; fReadOnly=false; fCanRestart=false; fReportUpdates=true; fDeleteWins=false; // replace wins over delete by default fResendFailing=true; // resend failing items in next session by default #ifdef SYSYNC_SERVER fTryUpdateDeleted=false; // no attempt to update already deleted items (assuming they are invisible only) fAlwaysSendLocalID=false; // off as it used to be not SCTS conformant (but would give clients chances to remap IDs) #endif fMaxItemsPerMessage=0; // no limit #ifdef OBJECT_FILTERING // - filters fRemoteAcceptFilter.erase(); fSilentlyDiscardUnaccepted=false; fLocalDBFilterConf.erase(); fMakePassFilter.erase(); fInvisibleFilter.erase(); fMakeVisibleFilter.erase(); // - DS 1.2 Filter support ( allowed in Alert, / shown in devInf) fDS12FilterSupport=false; // off by default, as clients usually don't have it // - Set if date range support is available in this datastore fDateRangeSupported=false; #endif #ifdef SCRIPT_SUPPORT fDBInitScript.erase(); fSentItemStatusScript.erase(); fReceivedItemStatusScript.erase(); fAlertScript.erase(); #ifdef SYSYNC_CLIENT fAlertPrepScript.erase(); #endif fDBFinishScript.erase(); #endif // clear embedded fTypeSupport.clear(); // clear inherited inherited::clear(); } // TLocalDSConfig::clear #ifndef HARDCODED_CONFIG // config element parsing bool TLocalDSConfig::localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine) { // checking the elements if (strucmp(aElementName,"dbtypeid")==0) expectUInt32(fLocalDBTypeID); else if (strucmp(aElementName,"typesupport")==0) expectChildParsing(fTypeSupport); else if (strucmp(aElementName,"conflictstrategy")==0) expectEnum(sizeof(fConflictStrategy),&fConflictStrategy,conflictStrategyNames,numConflictStrategies); else if (strucmp(aElementName,"slowsyncstrategy")==0) expectEnum(sizeof(fSlowSyncStrategy),&fSlowSyncStrategy,conflictStrategyNames,numConflictStrategies); else if (strucmp(aElementName,"firsttimestrategy")==0) expectEnum(sizeof(fFirstTimeStrategy),&fFirstTimeStrategy,conflictStrategyNames,numConflictStrategies); else if (strucmp(aElementName,"readonly")==0) expectBool(fReadOnly); else if (strucmp(aElementName,"canrestart")==0) expectBool(fCanRestart); else if (strucmp(aElementName,"syncmode")==0) { if (!fSyncModeBuffer.empty()) { fSyncModes.insert(fSyncModeBuffer); fSyncModeBuffer.clear(); } expectString(fSyncModeBuffer); } else if (strucmp(aElementName,"reportupdates")==0) expectBool(fReportUpdates); else if (strucmp(aElementName,"deletewins")==0) expectBool(fDeleteWins); else if (strucmp(aElementName,"resendfailing")==0) expectBool(fResendFailing); #ifdef SYSYNC_SERVER else if (strucmp(aElementName,"tryupdatedeleted")==0) expectBool(fTryUpdateDeleted); else if (strucmp(aElementName,"alwayssendlocalid")==0) expectBool(fAlwaysSendLocalID); else if (strucmp(aElementName,"alias")==0) { // get a name string name; if (!getAttrExpanded(aAttributes, "name", name, true)) return fail("Missing 'name' attribute in 'alias'"); fAliasNames.push_back(name); expectEmpty(); } #endif else if (strucmp(aElementName,"maxitemspermessage")==0) expectUInt32(fMaxItemsPerMessage); #ifdef OBJECT_FILTERING // filtering else if (strucmp(aElementName,"acceptfilter")==0) expectString(fRemoteAcceptFilter); else if (strucmp(aElementName,"silentdiscard")==0) expectBool(fSilentlyDiscardUnaccepted); else if (strucmp(aElementName,"localdbfilter")==0) expectString(fLocalDBFilterConf); else if (strucmp(aElementName,"makepassfilter")==0) expectString(fMakePassFilter); else if (strucmp(aElementName,"invisiblefilter")==0) expectString(fInvisibleFilter); else if (strucmp(aElementName,"makevisiblefilter")==0) expectString(fMakeVisibleFilter); else if (strucmp(aElementName,"ds12filters")==0) expectBool(fDS12FilterSupport); else if (strucmp(aElementName,"daterangesupport")==0) expectBool(fDateRangeSupported); #endif #ifdef SCRIPT_SUPPORT else if (strucmp(aElementName,"datastoreinitscript")==0) expectScript(fDBInitScript,aLine,&DBFuncTable); else if (strucmp(aElementName,"sentitemstatusscript")==0) expectScript(fSentItemStatusScript,aLine,&ErrorFuncTable); else if (strucmp(aElementName,"receiveditemstatusscript")==0) expectScript(fReceivedItemStatusScript,aLine,&ErrorFuncTable); else if (strucmp(aElementName,"alertscript")==0) expectScript(fAlertScript,aLine,&DBFuncTable); #ifdef SYSYNC_CLIENT else if (strucmp(aElementName,"alertprepscript")==0) expectScript(fAlertPrepScript,aLine,getClientDBFuncTable()); #endif else if (strucmp(aElementName,"datastorefinishscript")==0) expectScript(fDBFinishScript,aLine,&DBFuncTable); #endif #ifndef MINIMAL_CODE else if (strucmp(aElementName,"displayname")==0) expectString(fDisplayName); #endif // - none known here else return inherited::localStartElement(aElementName,aAttributes,aLine); // ok return true; } // TLocalDSConfig::localStartElement #endif // resolve void TLocalDSConfig::localResolve(bool aLastPass) { if (!fSyncModeBuffer.empty()) { fSyncModes.insert(fSyncModeBuffer); fSyncModeBuffer.clear(); } if (aLastPass) { #ifdef SCRIPT_SUPPORT TScriptContext *sccP = NULL; SYSYNC_TRY { // resolve all scripts in same context // - first script needed (when alert is created) #ifdef SYSYNC_CLIENT TScriptContext::resolveScript(getSyncAppBase(),fAlertPrepScript,sccP,NULL); #endif // - scripts needed when database is made ready TScriptContext::resolveScript(getSyncAppBase(),fDBInitScript,sccP,NULL); TScriptContext::resolveScript(getSyncAppBase(),fSentItemStatusScript,sccP,NULL); TScriptContext::resolveScript(getSyncAppBase(),fReceivedItemStatusScript,sccP,NULL); TScriptContext::resolveScript(getSyncAppBase(),fAlertScript,sccP,NULL); TScriptContext::resolveScript(getSyncAppBase(),fDBFinishScript,sccP,NULL); // - forget this context if (sccP) delete sccP; } SYSYNC_CATCH (...) if (sccP) delete sccP; SYSYNC_RETHROW; SYSYNC_ENDCATCH #endif } // resolve embedded fTypeSupport.Resolve(aLastPass); // resolve inherited inherited::localResolve(aLastPass); } // TLocalDSConfig::localResolve // - add type support to datatstore from config void TLocalDSConfig::addTypes(TLocalEngineDS *aDatastore, TSyncSession *aSessionP) { TSyncItemType *typeP; TSyncItemType *writetypeP; // preferred types, create instances only if not already existing // - preferred receive typeP = aSessionP->findLocalType(fTypeSupport.fPreferredRx); if (!typeP) { typeP = fTypeSupport.fPreferredRx->newSyncItemType(aSessionP,NULL); // local types are never exclusively related to a datastore aSessionP->addLocalItemType(typeP); // add to session } // - preferred send writetypeP = aSessionP->findLocalType(fTypeSupport.fPreferredTx); if (!writetypeP) { writetypeP = fTypeSupport.fPreferredTx->newSyncItemType(aSessionP,NULL); // local types are never exclusively related to a datastore aSessionP->addLocalItemType(writetypeP); } // - set preferred types aDatastore->setPreferredTypes(typeP,writetypeP); // additional types TAdditionalTypesList::iterator pos; for (pos=fTypeSupport.fAdditionalTypes.begin(); pos!=fTypeSupport.fAdditionalTypes.end(); pos++) { // - search for type already created from same config item typeP = aSessionP->findLocalType((*pos).datatypeconfig); if (!typeP) { // - does not exist yet, create the type typeP = (*pos).datatypeconfig->newSyncItemType(aSessionP,NULL); // local types are never exclusively related to a datastore // - add type to session types aSessionP->addLocalItemType(typeP); } // - add type to datastore's supported types aDatastore->addTypeSupport(typeP,(*pos).forRead,(*pos).forWrite); } #ifndef NO_REMOTE_RULES // rulematch types for (pos=fTypeSupport.fRuleMatchTypes.begin(); pos!=fTypeSupport.fRuleMatchTypes.end(); pos++) { // - search for type already created from same config item typeP = aSessionP->findLocalType((*pos).datatypeconfig); if (!typeP) { // - does not exist yet, create the type typeP = (*pos).datatypeconfig->newSyncItemType(aSessionP,NULL); // local types are never exclusively related to a datastore // - add type to session types aSessionP->addLocalItemType(typeP); } // - add type to datastore's rulematch types aDatastore->addRuleMatchTypeSupport(typeP,(*pos).remoteRuleMatch.c_str()); } #endif // now apply type limits // Note: this is usually derived, as limits are often defined within the datastore, // not the type itself (however, for hardcoded template-based fieldlists, // the limits are taken from the template, see TLocalDSConfig::addTypeLimits() addTypeLimits(aDatastore, aSessionP); } // TLocalDSConfig::addTypes // Add (probably datastore-specific) limits such as MaxSize and NoTruncate to types void TLocalDSConfig::addTypeLimits(TLocalEngineDS *aLocalDatastoreP, TSyncSession *aSessionP) { // add field size limitations from map to all types TSyncItemTypePContainer::iterator pos; TSyncItemTypePContainer *typesP = &(aLocalDatastoreP->fRxItemTypes); for (uInt8 i=0; i<2; i++) { for (pos=typesP->begin(); pos!=typesP->end(); pos++) { // apply default limits to type (e.g. from hard-coded template in config) (*pos)->addDefaultTypeLimits(); } typesP = &(aLocalDatastoreP->fTxItemTypes); } } // TLocalDSConfig::addTypeLimits // Check for alias names uInt16 TLocalDSConfig::isDatastoreAlias(cAppCharP aDatastoreURI) { // only servers have (and may need) aliases #ifdef SYSYNC_SERVER for (TStringList::iterator pos = fAliasNames.begin(); pos!=fAliasNames.end(); pos++) { if (*pos == aDatastoreURI) return (*pos).size(); // return size of match } #endif return 0; } // TLocalDSConfig::isDatastoreAlias /* * Implementation of TLocalEngineDS */ /// @Note InternalResetDataStore() must also be callable from destructor /// (care not to call other objects which will refer to the already /// half-destructed datastore!) void TLocalEngineDS::InternalResetDataStore(void) { // possibly complete, if not already done (should be, by engFinishDataStoreSync() !) if (fLocalDSState>dssta_idle) changeState(dssta_completed); // complete NOW, opportunity to show stats, etc. // switch down to idle changeState(dssta_idle); /// @todo obsolete: fState=dss_idle; fAbortStatusCode=LOCERR_OK; // not aborted yet fLocalAbortCause=true; // assume local cause fRemoteAddingStopped=false; fAlertCode=0; // not yet alerted /// Init Sync mode @ref dsSyncMode fSyncMode=smo_twoway; // default to twoway fForceSlowSync=false; fSlowSync=false; fRefreshOnly=false; fCacheData=false; fReadOnly=false; fReportUpdates=fDSConfigP->fReportUpdates; // update reporting according to what is configured fCanRestart=fDSConfigP->fCanRestart; fSyncModes=fDSConfigP->fSyncModes; fServerAlerted=false; fResuming=false; #ifdef SUPERDATASTORES fAsSubDatastoreOf=NULL; // is not a subdatastore #endif /// Init administrative data to defaults @ref dsAdminData // - last fLastRemoteAnchor.erase(); fLastLocalAnchor.erase(); // - current fNextRemoteAnchor.erase(); fNextLocalAnchor.erase(); // suspend state fResumeAlertCode=0; // none fPreventResuming=false; // suspend of chunked items fPartialItemState=pi_state_none; fLastSourceURI.erase(); fLastTargetURI.erase(); fLastItemStatus=0; fPITotalSize=0; fPIStoredSize=0; fPIUnconfirmedSize=0; if (fPIStoredDataAllocated) { smlLibFree(fPIStoredDataP); fPIStoredDataAllocated=false; } fPIStoredDataP=NULL; // other state info fFirstTimeSync=false; // not first sync by default #ifdef SYSYNC_CLIENT // - maps for add commands fPendingAddMaps.clear(); fUnconfirmedMaps.clear(); fLastSessionMaps.clear(); #endif #ifdef SYSYNC_SERVER PDEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,( "fTempGUIDMap: removing %ld items", (long)fTempGUIDMap.size() )); fTempGUIDMap.clear(); #endif /// Init type negotiation /// - for sending data fLocalSendToRemoteTypeP = NULL; fRemoteReceiveFromLocalTypeP = NULL; /// - for receiving data fLocalReceiveFromRemoteTypeP = NULL; fRemoteSendToLocalTypeP = NULL; /// Init Filtering @ref dsFiltering resetFiltering(); /// Init item processing @ref dsItemProcessing fSessionConflictStrategy=cr_duplicate; // will be updated later when sync mode is known fItemSizeLimit=-1; // no limit yet fCurrentSyncOp = sop_none; // will be set at engProcessItem() fEchoItemOp = sop_none; // will be set at engProcessItem() fItemConflictStrategy=fSessionConflictStrategy; // will be set at engProcessItem() fForceConflict = false; // will be set at engProcessItem() fDeleteWins = false; // will be set at engProcessItem() fRejectStatus = -1; // will be set at engProcessItem() #ifdef SCRIPT_SUPPORT // - delete the script context if any if (fSendingTypeScriptContextP) { delete fSendingTypeScriptContextP; fSendingTypeScriptContextP=NULL; } if (fReceivingTypeScriptContextP) { delete fReceivingTypeScriptContextP; fReceivingTypeScriptContextP=NULL; } if (fDataStoreScriptContextP) { delete fDataStoreScriptContextP; fDataStoreScriptContextP=NULL; } #endif /// Init other vars @ref dsOther /// Init Counters and statistics @ref dsCountStats // - NOC from remote fRemoteNumberOfChanges=-1; // none known yet // - data transferred fIncomingDataBytes=0; fOutgoingDataBytes=0; // - locally performed ops fLocalItemsAdded=0; fLocalItemsUpdated=0; fLocalItemsDeleted=0; fLocalItemsError=0; // - remotely performed ops fRemoteItemsAdded=0; fRemoteItemsUpdated=0; fRemoteItemsDeleted=0; fRemoteItemsError=0; #ifdef SYSYNC_SERVER // - conflicts fConflictsServerWins=0; fConflictsClientWins=0; fConflictsDuplicated=0; // - slow sync matches fSlowSyncMatches=0; #endif // Override defaults from ancestor // - generally, limit GUID size to reasonable size (even if we can // theoretically handle unlimited GUIDs in client, except for // some DEBUGPRINTF statements that will crash for example with // the brain-damaged GUIDs that Exchange server uses. fMaxGUIDSize = 64; } // TLocalEngineDS::InternalResetDataStore /// constructor TLocalEngineDS::TLocalEngineDS(TLocalDSConfig *aDSConfigP, TSyncSession *aSessionP, const char *aName, uInt32 aCommonSyncCapMask) : TSyncDataStore(aSessionP, aName, aCommonSyncCapMask) ,fPIStoredDataP(NULL) ,fPIStoredDataAllocated(false) #ifdef SCRIPT_SUPPORT ,fSendingTypeScriptContextP(NULL) // no associated script context ,fReceivingTypeScriptContextP(NULL) // no associated script context ,fDataStoreScriptContextP(NULL) // no datastore level context #endif ,fRemoteDatastoreP(NULL) // no associated remote { // set config ptr fDSConfigP = aDSConfigP; if (!fDSConfigP) SYSYNC_THROW(TSyncException(DEBUGTEXT("TLocalEngineDS::TLocalEngineDS called with NULL config","lds1"))); /// Init Sync state @ref dsSyncState fLocalDSState=dssta_idle; // idle to begin with // now reset InternalResetDataStore(); } // TLocalEngineDS::TLocalEngineDS TLocalEngineDS::~TLocalEngineDS() { // reset everything InternalResetDataStore(); } // TLocalEngineDS::~TLocalEngineDS #ifdef SYDEBUG // return datastore state name cAppCharP TLocalEngineDS::getDSStateName(void) { return LocalDSStateNames[fLocalDSState]; } // TLocalEngineDS::getDSStateName // return datastore state name cAppCharP TLocalEngineDS::getDSStateName(TLocalEngineDSState aState) { return LocalDSStateNames[aState]; } // TLocalEngineDS::getDSStateName #endif // reset datastore (after use) void TLocalEngineDS::engResetDataStore(void) { // now reset // - logic layer and above dsResetDataStore(); // - myself InternalResetDataStore(); // - anchestors inherited::engResetDataStore(); } // TLocalEngineDS::engResetDataStore // check if this datastore is accessible with given URI // NOTE: By default, local datastore type is addressed with // first path element of URI, rest of path might be used // by derivates to subselect data folders etc. uInt16 TLocalEngineDS::isDatastore(const char *aDatastoreURI) { // extract base name string basename; analyzeName(aDatastoreURI,&basename); // compare only base name // - compare with main name int res = inherited::isDatastore(basename.c_str()); if (res==0) { // Not main name: compare with aliases res = fDSConfigP->isDatastoreAlias(basename.c_str()); } return res; } // TLocalEngineDS::isDatastore /// get DB specific error message text for dbg log, or empty string if none /// @return platform specific DB error text string TLocalEngineDS::lastDBErrorText(void) { string s; s.erase(); uInt32 err = lastDBError(); if (isDBError(err)) { StringObjPrintf(s," (DB specific error code = %ld)",(long)lastDBError()); } return s; } // TLocalEngineDS::lastDBErrorText #ifdef SYSYNC_CLIENT // - init Sync Parameters (client case) // Derivates might override this to pre-process and modify parameters // (such as adding client settings as CGI to remoteDBPath) bool TLocalEngineDS::dsSetClientSyncParams( TSyncModes aSyncMode, bool aSlowSync, const char *aRemoteDBPath, const char *aDBUser, const char *aDBPassword, const char *aLocalPathExtension, const char *aRecordFilterQuery, bool aFilterInclusive ) { // - set remote params fRemoteDBPath=aRemoteDBPath; AssignString(fDBUser,aDBUser); AssignString(fDBPassword,aDBPassword); // check for running under control of a superdatastore // - aRemoteDBPath might contain a special prefix: "remote", with "super" specifying the // name of a local superdatastore to run the sync with string opts; if (!fRemoteDBPath.empty() && fRemoteDBPath.at(0)=='<') { // we have an option prefix size_t pfxe = fRemoteDBPath.find('>', 1); if (pfxe!=string::npos) { // extract options opts.assign(fRemoteDBPath, 1, pfxe-1); // store remote path cleaned from options fRemoteDBPath.erase(0,pfxe+1); } } if (!opts.empty()) { #ifdef SUPERDATASTORES // For now, the only option withing angle brackets is the name of the superdatastore, so opts==superdatastorename // - look for superdatastore having the specified name TSuperDSConfig *superdscfgP = static_cast(getSession()->getSessionConfig()->getLocalDS(opts.c_str())); if (superdscfgP && superdscfgP->isAbstractDatastore()) { // see if we have an instance of this already fAsSubDatastoreOf = static_cast(getSession()->findLocalDataStore(superdscfgP)); if (fAsSubDatastoreOf) { // that superdatastore already exists, just override client sync params with those already set aSyncMode = fAsSubDatastoreOf->fSyncMode; aSlowSync = fAsSubDatastoreOf->fSlowSync; aRecordFilterQuery = fAsSubDatastoreOf->fRemoteRecordFilterQuery.c_str(); } else { // instantiate new superdatastore fAsSubDatastoreOf = static_cast(superdscfgP->newLocalDataStore(getSession())); if (fAsSubDatastoreOf) { fSessionP->fLocalDataStores.push_back(fAsSubDatastoreOf); // configure it with the same parameters as the subdatastore if (!fAsSubDatastoreOf->dsSetClientSyncParams( aSyncMode, aSlowSync, fRemoteDBPath.c_str(), // already cleaned from prefix aDBUser, aDBPassword, aLocalPathExtension, aRecordFilterQuery, aFilterInclusive )) return false; // failed } } if (fAsSubDatastoreOf) { // find link config for this superdatastore TSubDSLinkConfig *lcfgP = NULL; TSubDSConfigList::iterator pos; for(pos=superdscfgP->fSubDatastores.begin();pos!=superdscfgP->fSubDatastores.end();pos++) { if ((*pos)->fLinkedDSConfigP==fDSConfigP) { // this is the link lcfgP = *pos; break; } } if (lcfgP) { // now link into superdatastore fAsSubDatastoreOf->addSubDatastoreLink(lcfgP,this); } else { PDEBUGPRINTFX(DBG_ERROR,("Warning: '%s' is not a subdatastore of '%s'", getName(), opts.c_str())); return false; // failed } } } else { PDEBUGPRINTFX(DBG_ERROR,("Warning: No superdatastore name '%s' exists -> can't run '%s' under superdatastore control", opts.c_str(), getName())); return false; // failed } #endif // SUPERDATASTORES } // sync mode fSyncMode=aSyncMode; fSlowSync=aSlowSync; fRefreshOnly=fSyncMode==smo_fromserver; // here to make sure, should be set by setSyncMode(FromAlertCode) later anyway // DS 1.2 filters AssignString(fRemoteRecordFilterQuery,aRecordFilterQuery); fRemoteFilterInclusive=aFilterInclusive; // params // - build local path fLocalDBPath=URI_RELPREFIX; fLocalDBPath+=getName(); if (aLocalPathExtension && *aLocalPathExtension) { fLocalDBPath+='/'; fLocalDBPath+=aLocalPathExtension; } // - we have the params for syncing now return changeState(dssta_clientparamset)==LOCERR_OK; } // TLocalEngineDS::dsSetClientSyncParams #endif // SYSYNC_CLIENT // add support for more data types // (for programatically creating local datastores from specialized TSyncSession derivates) void TLocalEngineDS::addTypeSupport(TSyncItemType *aItemTypeP,bool aForRx, bool aForTx) { if (aForRx) fRxItemTypes.push_back(aItemTypeP); if (aForTx) fTxItemTypes.push_back(aItemTypeP); } // TLocalEngineDS::addTypeSupport #ifndef NO_REMOTE_RULES // add data type that overrides normal type selection if string matches active remote rule void TLocalEngineDS::addRuleMatchTypeSupport(TSyncItemType *aItemTypeP,cAppCharP aRuleMatchString) { TRuleMatchTypeEntry rme; rme.itemTypeP = aItemTypeP; rme.ruleMatchString = aRuleMatchString; fRuleMatchItemTypes.push_back(rme); } // TLocalEngineDS::addRuleMatchTypeSupport #endif TTypeVariantDescriptor TLocalEngineDS::getVariantDescForType(TSyncItemType *aItemTypeP) { // search in config for specific variant descriptor // - first check preferred rx if (fDSConfigP->fTypeSupport.fPreferredRx == aItemTypeP->getTypeConfig()) return fDSConfigP->fTypeSupport.fPrefRxVariantDescP; // - then check preferred tx if (fDSConfigP->fTypeSupport.fPreferredTx == aItemTypeP->getTypeConfig()) return fDSConfigP->fTypeSupport.fPrefTxVariantDescP; // - then check additional types TAdditionalTypesList::iterator pos; for (pos=fDSConfigP->fTypeSupport.fAdditionalTypes.begin(); pos!=fDSConfigP->fTypeSupport.fAdditionalTypes.end(); pos++) { if ((*pos).datatypeconfig == aItemTypeP->getTypeConfig()) return (*pos).variantDescP; } // none found return NULL; } // TLocalEngineDS::getVariantDescForType // - called when a item in the sync set changes its localID (due to local DB internals) void TLocalEngineDS::dsLocalIdHasChanged(const char *aOldID, const char *aNewID) { #ifdef SYSYNC_SERVER if (IS_SERVER) { // make sure remapped localIDs get updated as well TStringToStringMap::iterator pos; for (pos=fTempGUIDMap.begin(); pos!=fTempGUIDMap.end(); pos++) { if (pos->second == aOldID) { // update ID PDEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,( "fTempGUIDMap: updating mapping of %s from %s to %s", pos->first.c_str(), aOldID, aNewID )); pos->second = aNewID; break; } } } #endif // SYSYNC_SERVER } // TLocalEngineDS::dsLocalIdHasChanged #ifdef SYSYNC_SERVER // for received GUIDs (Map command), obtain real GUID (might be temp GUID due to maxguidsize restrictions) void TLocalEngineDS::obtainRealLocalID(string &aLocalID) { if (aLocalID.size()>0 && aLocalID[0]=='#') { // seems to be a temp GUID TStringToStringMap::iterator pos = fTempGUIDMap.find(aLocalID); if (pos!=fTempGUIDMap.end()) { // found temp GUID mapping, replace it PDEBUGPRINTFX(DBG_DATA,( "translated tempLocalID='%s' back to real localID='%s'", aLocalID.c_str(), (*pos).second.c_str() )); aLocalID = (*pos).second; } else { PDEBUGPRINTFX(DBG_ERROR,("No realLocalID found for tempLocalID='%s'",aLocalID.c_str())); } } } // TLocalEngineDS::obtainRealLocalID // for sending GUIDs (Add command), generate temp GUID which conforms to maxguidsize of remote datastore if needed void TLocalEngineDS::adjustLocalIDforSize(string &aLocalID, sInt32 maxguidsize, sInt32 prefixsize) { if (maxguidsize>0) { if (aLocalID.length()+prefixsize>(uInt32)maxguidsize) { //BCPPB needed unsigned cast // real GUID is too long, we need to create a temp #if SYDEBUG>1 // first check if there is already a mapping for it, // because on-disk storage can only hold one; also // saves space // TODO: implement this more efficiently than this O(N) search for (TStringToStringMap::const_iterator it = fTempGUIDMap.begin(); it != fTempGUIDMap.end(); ++it) { if (it->second == aLocalID) { // found an existing mapping! PDEBUGPRINTFX(DBG_ERROR,( "fTempGUIDMap: translated realLocalID='%s' to tempLocalID='%s' (reused?!)", aLocalID.c_str(), it->first.c_str() )); aLocalID = it->first; return; } } string tempguid; long counter = fTempGUIDMap.size(); // as list only grows, we have unique tempuids for sure while (true) { counter++; StringObjPrintf(tempguid,"#%ld",counter); if (fTempGUIDMap.find(tempguid) != fTempGUIDMap.end()) { PDEBUGPRINTFX(DBG_ERROR,( "fTempGUIDMap: '%s' not new?!", tempguid.c_str() )); } else { break; } } #else // rely on tempguid list only growing (which still holds true) string tempguid; StringObjPrintf(tempguid,"#%ld",(long)fTempGUIDMap.size()+1); // as list only grows, we have unique tempuids for sure #endif fTempGUIDMap[tempguid]=aLocalID; PDEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,( "fTempGUIDMap: translated realLocalID='%s' to tempLocalID='%s'", aLocalID.c_str(), tempguid.c_str() )); aLocalID=tempguid; } } } // TLocalEngineDS::adjustLocalIDforSize #endif // SYSYNC_SERVER // set Sync types needed for sending local data to remote DB void TLocalEngineDS::setSendTypeInfo( TSyncItemType *aLocalSendToRemoteTypeP, TSyncItemType *aRemoteReceiveFromLocalTypeP ) { fLocalSendToRemoteTypeP=aLocalSendToRemoteTypeP; fRemoteReceiveFromLocalTypeP=aRemoteReceiveFromLocalTypeP; } // TLocalEngineDS::setSendTypeInfo // set Sync types needed for receiving remote data in local DB void TLocalEngineDS::setReceiveTypeInfo( TSyncItemType *aLocalReceiveFromRemoteTypeP, TSyncItemType *aRemoteSendToLocalTypeP ) { fLocalReceiveFromRemoteTypeP=aLocalReceiveFromRemoteTypeP; fRemoteSendToLocalTypeP=aRemoteSendToLocalTypeP; } // TLocalEngineDS::setReceiveTypeInfo // - init usage of datatypes set with setSendTypeInfo/setReceiveTypeInfo localstatus TLocalEngineDS::initDataTypeUse(void) { localstatus sta = LOCERR_OK; // check compatibility if ( !fLocalSendToRemoteTypeP || !fLocalReceiveFromRemoteTypeP || !fLocalSendToRemoteTypeP->isCompatibleWith(fLocalReceiveFromRemoteTypeP) ) { // send and receive types not compatible sta = 415; PDEBUGPRINTFX(DBG_ERROR,("Incompatible send and receive types -> cannot sync (415)")); engAbortDataStoreSync(sta,true,false); // do not proceed with sync of this datastore, local problem, not resumable return sta; } #ifdef SCRIPT_SUPPORT // let types initialize themselves for being used by this datastore // - optimization: if both types are same, initialize only once if (fLocalSendToRemoteTypeP == fLocalReceiveFromRemoteTypeP) fLocalReceiveFromRemoteTypeP->initDataTypeUse(this,true,true); // send and receive else { fLocalSendToRemoteTypeP->initDataTypeUse(this,true,false); // for sending, not receiving fLocalReceiveFromRemoteTypeP->initDataTypeUse(this,false,true); // not sending, for receiving } #endif // ok return sta; } // TLocalEngineDS::initDataTypeUse // conflict resolution strategy. Conservative here TConflictResolution TLocalEngineDS::getConflictStrategy(bool aForSlowSync, bool aForFirstTime) { return aForSlowSync ? (aForFirstTime ? fDSConfigP->fFirstTimeStrategy : fDSConfigP->fSlowSyncStrategy) : fDSConfigP->fConflictStrategy; } // TLocalEngineDS::getConflictStrategy // add filter keywords and property names to filterCap void TLocalEngineDS::addFilterCapPropsAndKeywords(SmlPcdataListPtr_t &aFilterKeywords, SmlPcdataListPtr_t &aFilterProps) { #ifdef OBJECT_FILTERING // add my own properties if (fDSConfigP->fDateRangeSupported) { addPCDataStringToList("BEFORE", &aFilterKeywords); addPCDataStringToList("SINCE", &aFilterKeywords); } // get default send type TSyncItemType *itemTypeP = fSessionP->findLocalType(fDSConfigP->fTypeSupport.fPreferredTx); TTypeVariantDescriptor variantDesc = NULL; doesUseType(itemTypeP, &variantDesc); // have it add it's keywords and properties itemTypeP->addFilterCapPropsAndKeywords(aFilterKeywords,aFilterProps,variantDesc); #endif } // TLocalEngineDS::addFilterCapPropsAndKeywords // reset all filter settings void TLocalEngineDS::resetFiltering(void) { #ifdef OBJECT_FILTERING // - dynamic sync set filter fSyncSetFilter.erase(); // - static filter fLocalDBFilter=fDSConfigP->fLocalDBFilterConf; // use configured localDB filter // - TAF filters #ifdef SYNCML_TAF_SUPPORT fTargetAddressFilter.erase(); // none from yet fIntTargetAddressFilter.erase(); // none from internal source (script) #endif #ifdef SYSYNC_TARGET_OPTIONS // - Other filtering options fDateRangeStart=0; // no date range fDateRangeEnd=0; fSizeLimit=-1; // no size limit fMaxItemCount=0; // no item count limit fNoAttachments=false; // attachments not suppressed fDBOptions.erase(); // no options #endif // - Filtering requirements fTypeFilteringNeeded=false; fFilteringNeededForAll=false; fFilteringNeeded=false; #endif // OBJECT_FILTERING } // TLocalEngineDS::resetFiltering #ifdef OBJECT_FILTERING /// @brief check single filter term for DS 1.2 filterkeywords. /// @return true if term still needs to be added to normal filter expression, false if term will be handled otherwise bool TLocalEngineDS::checkFilterkeywordTerm( cAppCharP aIdent, bool aAssignToMakeTrue, cAppCharP aOp, bool aCaseInsensitive, cAppCharP aVal, bool aSpecialValue, TSyncItemType *aItemTypeP ) { // show it to the datatype (if any) if (aItemTypeP) { if (!aItemTypeP->checkFilterkeywordTerm(aIdent, aAssignToMakeTrue, aOp, aCaseInsensitive, aVal, aSpecialValue)) return false; // type fully handles it, no need to check it further or add it to the filter expression } // we generally implement BEFORE and SINCE on the datastore level // This might not make sense depending on the actual datatype, but does not harm either #ifdef SYSYNC_TARGET_OPTIONS timecontext_t tctx; if (strucmp(aIdent,"BEFORE")==0) { if (ISO8601StrToTimestamp(aVal,fDateRangeEnd,tctx)) { TzConvertTimestamp(fDateRangeEnd,tctx,TCTX_UTC,getSessionZones(),fSessionP->fUserTimeContext); } else { PDEBUGPRINTFX(DBG_ERROR,("invalid ISO datetime for BEFORE: '%s'",aVal)); return true; // add it to filter, possibly this is not meant to be a filterkeyword } } else if (strucmp(aIdent,"SINCE")==0) { if (ISO8601StrToTimestamp(aVal,fDateRangeStart,tctx)) { TzConvertTimestamp(fDateRangeStart,tctx,TCTX_UTC,getSessionZones(),fSessionP->fUserTimeContext); } else { PDEBUGPRINTFX(DBG_ERROR,("invalid ISO datetime for SINCE: '%s'",aVal)); return true; // add it to filter, possibly this is not meant to be a filterkeyword } } else if (strucmp(aIdent,"MAXSIZE")==0) { if (StrToFieldinteger(aVal,fSizeLimit)==0) { PDEBUGPRINTFX(DBG_ERROR,("invalid integer for MAXSIZE: '%s'",aVal)); return true; // add it to filter, possibly this is not meant to be a filterkeyword } } else if (strucmp(aIdent,"MAXCOUNT")==0) { if (StrToULong(aVal,fMaxItemCount)==0) { PDEBUGPRINTFX(DBG_ERROR,("invalid integer for MAXSIZE: '%s'",aVal)); return true; // add it to filter, possibly this is not meant to be a filterkeyword } } else if (strucmp(aIdent,"NOATT")==0) { if (!StrToBool(aVal,fNoAttachments)==0) { PDEBUGPRINTFX(DBG_ERROR,("invalid boolean for NOATT: '%s'",aVal)); return true; // add it to filter, possibly this is not meant to be a filterkeyword } } else if (strucmp(aIdent,"DBOPTIONS")==0) { fDBOptions = aVal; // just get DB options } #endif else { // unknown identifier, add to filter expression return true; } // this term will be processed by special mechanism like fDateRangeStart/fDateRangeEnd // or fSizeLimit, so there is no need for normal filtering return false; // do not include into filter } // TLocalEngineDS::checkFilterkeywordTerm /// @brief parse "syncml:filtertype-cgi" filter, convert into internal filter syntax /// and possibly sets some special filter options (fDateRangeStart, fDateRangeEnd) /// based on "filterkeywords" available for the type passed (DS 1.2). /// For parsing DS 1.1/1.0 TAF-style filters, aItemType can be NULL, no type-specific /// filterkeywords can be parsed then. /// @return pointer to next character after processing (usually points to terminator) /// @param[in] aCGI the NUL-terminated filter string /// @param[in] aItemTypeP if not NULL, this is the item type the filter applies to const char *TLocalEngineDS::parseFilterCGI(cAppCharP aCGI, TSyncItemType *aItemTypeP, string &aFilter) { const char *p=aCGI, *q; sInt16 paraNest=0; // nested paranthesis string ident; char op[3]; char logop; string val; bool termtofilter; bool assigntomaketrue; bool specialvalue; bool caseinsensitive; PDEBUGPRINTFX(DBG_FILTER+DBG_EXOTIC,("Parsing syncml:filtertype-cgi filter: %s",aCGI)); aFilter.erase(); logop=0; while (p && *p) { if (aFilter.empty()) logop=0; // ignore logical operation that would be at beginning of an expression // skip spaces while (isspace(*p)) p++; // now we need an ident or paranthesis if (*p=='(') { if (logop) aFilter+=logop; // expression continues, we need the logop now logop=0; // now consumed paraNest++; aFilter+='('; p++; } else { // must be term: ident op val // - check special case pseudo-identifiers if (strucmp(p,"&LUID;",6)==0) { ident="LUID"; p+=6; } else { // normal identifier // - search end q=p; while (isalnum(*q) || *q=='[' || *q==']' || *q=='.' || *q=='_') q++; // - assign if (q==p) { PDEBUGPRINTFX(DBG_ERROR,("Expected identifier but found '%s'",p)); break; } ident.assign(p,q-p); p=q; } // skip spaces while (isspace(*p)) p++; // next must be comparison operator, possibly preceeded by modifiers op[0]=0; op[1]=0; op[2]=0; assigntomaketrue=false; specialvalue=false; caseinsensitive=false; // - check modifiers first if (*p==':') { assigntomaketrue=true; p++; } if (*p=='*') { specialvalue=true; p++; } if (*p=='^') { caseinsensitive=true; p++; } // - now OP either in internal form or as pseudo-entity if (*p=='>' || *p=='<') { // possible two-char ops (>=, <=, <>) op[0]=*p++; if (*p=='>' || *p=='=') { op[1]=*p++; } } else if (*p=='=' || *p=='%' || *p=='$') { // single char ops, just use them as is op[0]=*p++; } else if (*p=='&') { p++; if (tolower(*p)=='i') { caseinsensitive=true; p++; } if (strucmp(p,"eq;",3)==0) { op[0]='='; p+=3; } else if (strucmp(p,"gt;",3)==0) { op[0]='>'; p+=3; } else if (strucmp(p,"ge;",3)==0) { op[0]='>'; op[1]='='; p+=3; } else if (strucmp(p,"lt;",3)==0) { op[0]='<'; p+=3; } else if (strucmp(p,"le;",3)==0) { op[0]='<'; op[1]='='; p+=3; } else if (strucmp(p,"ne;",3)==0) { op[0]='<'; op[1]='>'; p+=3; } else if (strucmp(p,"con;",4)==0) { op[0]='%'; p+=4; } else if (strucmp(p,"ncon;",5)==0) { op[0]='$'; p+=5; } else { PDEBUGPRINTFX(DBG_ERROR,("Expected comparison operator pseudo-entity but found '%s'",p-1)); break; } } else { PDEBUGPRINTFX(DBG_ERROR,("Expected comparison operator but found '%s'",p)); break; } // next must be value // - check for special value cases if (strucmp(p,"&NULL;",6)==0) { // SyncML DS 1.2 p+=6; val='E'; specialvalue=true; } else if (strucmp(p,"&UNASSIGNED;",12)==0) { // Synthesis extension p+=12; val='U'; specialvalue=true; } else { val.erase(); } // - get value chars while (*p && *p!='&' && *p!='|' && *p!=')') { // value char, possibly hex escaped uInt16 c; if (*p=='%') { // convert from hex if (HexStrToUShort(p+1,c,2)==2) { p+=3; } else c=*p++; } else c=*p++; // add to value val += (char)c; } // value // now we have identifier, op and value // - check and possibly sort out filterkeyword terms termtofilter = checkFilterkeywordTerm(ident.c_str(),assigntomaketrue,op,caseinsensitive,val.c_str(),specialvalue,aItemTypeP); // - add to filter if not handled already by other mechanism if (termtofilter) { if (logop) aFilter+=logop; // if this is a continuation, add logical operator now aFilter += ident; if (assigntomaketrue) aFilter+=':'; if (specialvalue) aFilter+='*'; if (caseinsensitive) aFilter+='^'; aFilter += op; aFilter += val; } else { PDEBUGPRINTFX(DBG_FILTER+DBG_EXOTIC,( "checkFilterkeywordTerm(%s,%hd,%s,%hd,%s,%hd) prevents adding to filter", ident.c_str(),(uInt16)assigntomaketrue,op,(uInt16)caseinsensitive,val.c_str(),(uInt16)specialvalue )); if (logop) { PDEBUGPRINTFX(DBG_FILTER,("Ignored logical operation '%c' due to always-ANDed filterkeyword",logop)); } } // now check for continuation: optional closing paranthesis plus logical op // - closing paranthesis do { // skip spaces while (isspace(*p)) p++; if (*p!=')') break; if (paraNest==0) { // as we might parse filters as part of /fi() or /tf() options, // this is not an error but only means end of filter expression goto endFilter; } aFilter+=')'; paraNest--; p++; } while (true); // - logical op if (*p==0) break; // done else if (*p=='&') { logop=*p++; // if no entity matches, & by itself is treated as AND if (strucmp(p,"amp;",4)==0) { logop='&'; p+=4; } else if (strucmp(p,"and;",4)==0) { logop='&'; p+=4; } else if (strucmp(p,"or;",3)==0) { logop='|'; p+=3; } } else if (*p=='|') { logop='|'; } else { PDEBUGPRINTFX(DBG_ERROR,("Expected logical operator or end of filter but found '%s'",p)); break; } } // not opening paranthesis } // while not end of filter endFilter: PDEBUGPRINTFX(DBG_FILTER+DBG_EXOTIC,("Resulting internal filter: %s",aFilter.c_str())); // return pointer to terminating character return p; } // TLocalEngineDS::parseFilterCGI #endif // analyze database name void TLocalEngineDS::analyzeName( const char *aDatastoreURI, string *aBaseNameP, string *aTableNameP, string *aCGIP ) { const char *p,*q=NULL, *r; r=strchr(aDatastoreURI,'?'); p=strchr(aDatastoreURI,'/'); if (r && p>r) p=NULL; // if slash is in CGI, ignore it else q=p+1; // slash exclusive if (p!=NULL) { // we have more than just the first element if (aBaseNameP) aBaseNameP->assign(aDatastoreURI,p-aDatastoreURI); // rest is table name and probably CGI if (aTableNameP) { if (r) aTableNameP->assign(q,r-q); // we have CGI else *aTableNameP=q; // entire rest is tablename } } else { // no second path element, but possibly CGI // - assign base name if (aBaseNameP) { if (r) (*aBaseNameP).assign(aDatastoreURI,r-aDatastoreURI); // only up to CGI else (*aBaseNameP)=aDatastoreURI; // complete name } // - there is no table name if (aTableNameP) aTableNameP->erase(); } // return CGI (w/o question mark) if any if (aCGIP) { if (r) *aCGIP=r+1; else aCGIP->erase(); } } // TLocalEngineDS::analyzeName #ifdef SYSYNC_TARGET_OPTIONS // parses single option, returns pointer to terminating char of argument string // or NULL on error // Note: if aArguments is passed NULL, this is an option without arguments, // and an arbitrary non-NULL will be returned if parsing is ok const char *TLocalEngineDS::parseOption( const char *aOptName, const char *aArguments, bool aFromSyncCommand ) { #ifdef OBJECT_FILTERING if (strucmp(aOptName,"fi")==0) { if (!aArguments) return NULL; // make sync set filter expression string f; aArguments=parseFilterCGI(aArguments,fLocalSendToRemoteTypeP,f); // if type being used for sending to remote is known here, use it if (!aFromSyncCommand) { addToFilter(f.c_str(),fSyncSetFilter,false); // AND chaining // call this once to give derivate a chance to see if it can filter the now set fSyncSetFilter engFilteredFetchesFromDB(true); } return aArguments; // end of filter pattern } #ifdef SYNCML_TAF_SUPPORT else if (strucmp(aOptName,"tf")==0) { if (!aArguments) return NULL; // make temporary filter (or TAF) expression aArguments=parseFilterCGI(aArguments,fLocalSendToRemoteTypeP,fTargetAddressFilter); // if type being used for sending to remote is known here, use it // Note: TAF filters are always evaluated internally as we need all SyncSet records // regardless of possible TAF suppression (for slowsync matching etc.) return aArguments; // end of filter pattern } #endif else if (aArguments && strucmp(aOptName,"dr")==0) { // date range limit sInt16 dstart,dend; if (sscanf(aArguments,"%hd,%hd",&dstart,&dend)==2) { // - find end of arguments aArguments=strchr(aArguments,')'); // - calculate start and end fDateRangeStart=getSystemNowAs(TCTX_UTC,getSessionZones()); fDateRangeEnd=fDateRangeStart; // - now use offsets fDateRangeStart+=dstart*linearDateToTimeFactor; fDateRangeEnd+=dend*linearDateToTimeFactor; return aArguments; } else return NULL; } else if (aArguments && strucmp(aOptName,"li")==0) { // size limit sInt16 n=StrToFieldinteger(aArguments,fSizeLimit); if (n>0) { // - find end of arguments aArguments+=n; return aArguments; } else return NULL; } else if (!aArguments && strucmp(aOptName,"na")==0) { // no attachments fNoAttachments=true; return (const char *)1; // non-zero } else if (aArguments && strucmp(aOptName,"max")==0) { // maximum number of items (for email for example) sInt16 n=StrToULong(aArguments,fMaxItemCount); if (n>0) { // - find end of arguments aArguments+=n; return aArguments; } else return NULL; } else #endif #ifdef SYSYNC_SERVER if (IS_SERVER && !aArguments && strucmp(aOptName,"slow")==0) { // force a slow sync PDEBUGPRINTFX(DBG_HOT,("Slowsync forced by CGI-option in db path")); fForceSlowSync=true; return (const char *)1; // non-zero } else #endif // SYSYNC_SERVER if (aArguments && strucmp(aOptName,"o")==0) { // datastore options // - find end of arguments const char *p=strchr(aArguments,')'); if (p) fDBOptions.assign(aArguments,p-aArguments); return p; } else return NULL; // not parsed } // TLocalEngineDS::parseOption #endif // parse options localstatus TLocalEngineDS::engParseOptions( const char *aTargetURIOptions, // option string contained in target URI bool aFromSyncCommand // must be set when parsing options from target URI ) { localstatus sta=LOCERR_OK; if (aTargetURIOptions) { const char *p = aTargetURIOptions; #ifdef SYSYNC_TARGET_OPTIONS const char *q; #endif char c; string taf; // official TAF while ((c=*p)) { #ifdef SYSYNC_TARGET_OPTIONS if (c=='/') { // proprietary option lead-in // - get option name string optname; optname.erase(); while(isalnum(c=*(++p))) optname+=c; // - get arguments if (c=='(') { q=p; // save p++; // skip "(" p=parseOption(optname.c_str(),p,aFromSyncCommand); if (!p) { // unrecognized or badly formatted option, just add it to TAF taf+='/'; taf+=optname; p=q; // restart after option name continue; } if (*p!=')') { sta=406; PDEBUGPRINTFX(DBG_ERROR,("Syntax error in target options")); break; } } else { // option without arguments if (!parseOption(optname.c_str(),NULL,aFromSyncCommand)) { sta=406; PDEBUGPRINTFX(DBG_ERROR,("Unknown target option")); break; } // error, not parsed p--; // will be incremented once again below } } else #endif { // char not part of an option taf+=c; } // next p++; } // check if we have TAF if (taf.size()>0) { #if defined(TAF_AS_SYNCSETFILTER) && defined(SYSYNC_TARGET_OPTIONS) // treat as "fi()" option like before 1.0.8.10 if (!parseOption("fi",taf.c_str(),aFromSyncCommand)) { sta=406; } // error, not parsed #else #ifdef SYNCML_TAF_SUPPORT // treat as "tf()" = real TAF if (!parseOption("tf",taf.c_str(),aFromSyncCommand)) { sta=406; } // error, not parsed #else sta=406; PDEBUGPRINTFX(DBG_ERROR,("TAF not supported")); #endif #endif } } // return status return sta; } // TLocalEngineDS::engParseOptions // process SyncML 1.2 style filter localstatus TLocalEngineDS::engProcessDS12Filter(SmlFilterPtr_t aTargetFilter) { localstatus sta=LOCERR_OK; if (aTargetFilter) { // check general availability #ifdef OBJECT_FILTERING if (!fDSConfigP->fDS12FilterSupport) #endif { PDEBUGPRINTFX(DBG_ERROR,("DS 1.2 style filtering is not available or disabled in config ()")); sta=406; goto error; } // check filter TSyncItemType *itemTypeP=NULL; // no associated type so far bool inclusiveFilter=false; // default is EXCLUSIVE // - meta if (aTargetFilter->meta) { SmlMetInfMetInfPtr_t metaP = smlPCDataToMetInfP(aTargetFilter->meta); const char *typestr = smlMetaTypeToCharP(metaP); // get sync item type for it // - filter mostly applies to items SENT, so we search these first itemTypeP = getSendType(typestr,NULL); if (!itemTypeP) itemTypeP = getReceiveType(typestr,NULL); PDEBUGPRINTFX(DBG_FILTER,("DS12 is '%s' -> %sfound",typestr,itemTypeP ? "" : "NOT ")); if (!itemTypeP) { sta=415; goto error; } } // - filtertype if (aTargetFilter->filtertype) { const char *ftystr = smlPCDataToCharP(aTargetFilter->filtertype); if (strucmp(ftystr,SYNCML_FILTERTYPE_INCLUSIVE)==0) { inclusiveFilter=true; } else if (strucmp(ftystr,SYNCML_FILTERTYPE_EXCLUSIVE)==0) { inclusiveFilter=false; } else { PDEBUGPRINTFX(DBG_ERROR,("Invalid '%s'",ftystr)); sta=422; goto error; } } // - field level filter if (aTargetFilter->field) { /// @todo %%% to be implemented PDEBUGPRINTFX(DBG_ERROR,("Field-level filtering not supported")); sta=406; goto error; } // - record level filter if (aTargetFilter->record) { #ifdef OBJECT_FILTERING SmlItemPtr_t recordItemP = aTargetFilter->record->item; if (recordItemP) { // - check grammar const char *grammarstr = smlMetaTypeToCharP(smlPCDataToMetInfP(recordItemP->meta)); if (strucmp(grammarstr,SYNCML_FILTERTYPE_CGI)!=0) { PDEBUGPRINTFX(DBG_ERROR,("Invalid filter grammar '%s'",grammarstr)); sta=422; goto error; } // now get the actual filter string const char *filterstring = smlPCDataToCharP(recordItemP->data); PDEBUGPRINTFX(DBG_HOT,( "Remote specified %sCLUSIVE filter query: '%s'", inclusiveFilter ? "IN" : "EX", filterstring )); if (*filterstring) { string f; // parse it filterstring = parseFilterCGI(filterstring,itemTypeP,f); if (*filterstring) { // not read to end PDEBUGPRINTFX(DBG_ERROR,("filter query syntax error at: '%s'",filterstring)); sta=422; goto error; } /// @todo: %%% check if this is correct interpretation // - exclusive is what we used to call "sync set" filtering // - inclusive seems to be former TAF if (inclusiveFilter) { // INCLUSIVE #ifdef SYNCML_TAF_SUPPORT fTargetAddressFilter=f; #else PDEBUGPRINTFX(DBG_ERROR,("This SyncML engine version has no INCLUSIVE filter support")); #endif } else { // EXCLUSIVE addToFilter(f.c_str(),fSyncSetFilter,false); // AND chaining PDEBUGPRINTFX(DBG_FILTER,("complete sync set filter is now: '%s'",fSyncSetFilter.c_str())); // call this once to give derivate a chance to see if it can filter the now set fSyncSetFilter engFilteredFetchesFromDB(true); } } } // if item #else // no object filtering PDEBUGPRINTFX(DBG_ERROR,("This SyncML engine version has no filter support (only PRO has)")); sta=406; goto error; #endif } // record } // filter at all error: return sta; } // TLocalEngineDS::engProcessDS12Filter // process Sync alert from remote party: check if alert code is supported, // check if slow sync is needed due to anchor mismatch // - server case: also generate appropriate Alert acknowledge command TAlertCommand *TLocalEngineDS::engProcessSyncAlert( TSuperDataStore *aAsSubDatastoreOf, // if acting as subdatastore uInt16 aAlertCode, // the alert code const char *aLastRemoteAnchor, // last anchor of remote const char *aNextRemoteAnchor, // next anchor of remote const char *aTargetURI, // target URI as sent by remote, no processing at all const char *aIdentifyingTargetURI, // target URI that was used to identify datastore const char *aTargetURIOptions, // option string contained in target URI SmlFilterPtr_t aTargetFilter, // DS 1.2 filter, NULL if none const char *aSourceURI, // source URI TStatusCommand &aStatusCommand // status that might be modified ) { TAlertCommand *alertcmdP=NULL; localstatus sta=LOCERR_OK; SYSYNC_TRY { if (IS_SERVER) { // save the identifying URI fIdentifyingDBName = aIdentifyingTargetURI; } // determine status of read-only option fReadOnly= fSessionP->getReadOnly() || // session level read-only flag (probably set by login) fDSConfigP->fReadOnly; // or datastore config #ifdef SUPERDATASTORES // if running as subdatastore of a superdatastore already, this call mus be from a superdatastore as well (aAsSubDatastoreOf!=NULL) // Note: On a client, fAsSubDatastoreOf is set earlier in dsSetClientSyncParams() // On a server, fAsSubDatastoreOf will be set now to avoid alerting as sub- and normal datastore at the same time. if (fAsSubDatastoreOf && !aAsSubDatastoreOf) { // bad, cannot be alerted directly AND as subdatastore aStatusCommand.setStatusCode(400); ADDDEBUGITEM(aStatusCommand,"trying to alert already alerted subdatastore"); PDEBUGPRINTFX(DBG_ERROR,("Already alerted as subdatastore of '%s'",fAsSubDatastoreOf->getName())); return NULL; } // set subdatastore mode fAsSubDatastoreOf = aAsSubDatastoreOf; #endif // reset type info fLocalSendToRemoteTypeP = NULL; fLocalReceiveFromRemoteTypeP = NULL; fRemoteReceiveFromLocalTypeP=NULL; fRemoteSendToLocalTypeP=NULL; // prepare database-level scripts // NOTE: in client case, alertprepscript is already rebuilt here! #ifdef SCRIPT_SUPPORT TScriptContext::rebuildContext(fSessionP->getSyncAppBase(),fDSConfigP->fDBInitScript,fDataStoreScriptContextP,fSessionP); TScriptContext::rebuildContext(fSessionP->getSyncAppBase(),fDSConfigP->fSentItemStatusScript,fDataStoreScriptContextP,fSessionP); TScriptContext::rebuildContext(fSessionP->getSyncAppBase(),fDSConfigP->fReceivedItemStatusScript,fDataStoreScriptContextP,fSessionP); TScriptContext::rebuildContext(fSessionP->getSyncAppBase(),fDSConfigP->fAlertScript,fDataStoreScriptContextP,fSessionP); TScriptContext::rebuildContext(fSessionP->getSyncAppBase(),fDSConfigP->fDBFinishScript,fDataStoreScriptContextP,fSessionP,true); // now instantiate vars #endif // NOTE for client case: // ALL instantiated datastores have already sent an Alert to the server by now here // check DS 1.2 sta = engProcessDS12Filter(aTargetFilter); if (sta != LOCERR_OK) { aStatusCommand.setStatusCode(sta); ADDDEBUGITEM(aStatusCommand,"Invalid in target options"); return NULL; // error in options } // Filter CGI is now a combination of TAF and Synthesis-Style // extras (options). if (aTargetURIOptions && *aTargetURIOptions) { // there are target address options (such as filter CGI and TAF) sta = engParseOptions(aTargetURIOptions,false); if (sta != LOCERR_OK) { aStatusCommand.setStatusCode(sta); ADDDEBUGITEM(aStatusCommand,"Invalid CGI target URI options"); return NULL; // error in options } } if (IS_SERVER) { // server case: initially we are not in refresh only mode. Alert code or alert script could change this fRefreshOnly=false; fCacheData=false; } // save it for suspend and reference in scripts fAlertCode=aAlertCode; #ifdef SCRIPT_SUPPORT // call the alert script, which might want to force a slow sync and/or a server sync set zap TScriptContext::execute( fDataStoreScriptContextP, fDSConfigP->fAlertScript, &DBFuncTable, this // caller context ); aAlertCode=fAlertCode; // get possibly modified version back (SETALERTCODE) #endif // if we process a sync alert now, we haven't started sync or map generation #ifdef SYSYNC_SERVER if (IS_SERVER) { // server case: forget Temp GUID mapping // make sure we are not carrying forward any left-overs. Last sessions's tempGUID mappings that are // needed for "early map" resolution might be loaded by the call to engInitSyncAnchors below. // IMPORTANT NOTE: the tempGUIDs that might get loaded will become invalid as soon as // starts - so fTempGUIDMap needs to be cleared again as soon as the first command arrives from the client. fTempGUIDMap.clear(); } #endif // save remote's next anchor for saving at end of session fNextRemoteAnchor = aNextRemoteAnchor; // get target info in case we are server #ifdef SYSYNC_SERVER if (IS_SERVER) { // now get anchor info out of database // - make sure other anchor variables are set sta = engInitSyncAnchors( aIdentifyingTargetURI, // use processed form, not as sent by remote aSourceURI ); if (sta!=LOCERR_OK) { // error getting anchors aStatusCommand.setStatusCode(syncmlError(sta)); PDEBUGPRINTFX(DBG_ERROR,("Could not get Sync Anchor info, status=%hd",sta)); return NULL; // no alert to send back } // Server ok until here PDEBUGPRINTFX(DBG_PROTO,( "Saved Last Remote Client Anchor='%s', received Remote Client Anchor='%s' (must match for normal sync)", fLastRemoteAnchor.c_str(), aLastRemoteAnchor )); PDEBUGPRINTFX(DBG_PROTO,( "Received Remote Client Anchor='%s' (to be compared with in NEXT session)", fNextRemoteAnchor.c_str() )); PDEBUGPRINTFX(DBG_PROTO,( "(Saved) Last Local Server Anchor='%s', (generated) Next Local Server Anchor='%s' (sent to client as / in )", fLastLocalAnchor.c_str(), fNextLocalAnchor.c_str() )); } #endif #ifdef SYSYNC_CLIENT if (IS_CLIENT) { // Client ok until here PDEBUGPRINTFX(DBG_PROTO,( "Saved Last Remote Server Anchor='%s', received Remote Server Anchor='%s' (must match for normal sync)", fLastRemoteAnchor.c_str(), aLastRemoteAnchor )); PDEBUGPRINTFX(DBG_PROTO,( "Received Remote Server Anchor='%s' (to be compared with in NEXT session)", fNextRemoteAnchor.c_str() )); } #endif PDEBUGPRINTFX(DBG_PROTO,( "(Saved) fResumeAlertCode = %hd (valid for >DS 1.2 only)", fResumeAlertCode )); // Now check for resume // - default to what was actually alerted uInt16 effectiveAlertCode=aAlertCode; #ifdef SYSYNC_SERVER if (IS_SERVER) { // - check if resuming server session fResuming=false; if (aAlertCode==225) { if (fSessionP->getSyncMLVersion()fLenientMode && IS_CLIENT) #endif ) ) || // either anchors must match (or lenient mode for client)... (fResuming && *aLastRemoteAnchor==0) // ...or in case of resume, remote not sending anchor is ok as well ) && !fForceSlowSync // ...but no force for slowsync may be set internally ) || fSlowSync // if slow sync is requested by the remote anyway, we don't need to be in sync anyway, so just go on ) { if (!(fLastRemoteAnchor==aLastRemoteAnchor) && fSessionP->fLenientMode) { PDEBUGPRINTFX(DBG_ERROR,("Warning - remote anchor mismatch but tolerated in lenient mode")); } // sync state ok or Slow sync requested anyway: #ifdef SYSYNC_SERVER if (IS_SERVER) { // we can generate Alert with same code as sent // %%% Note: this is not entirely clear, as SCTS sends // corresponding SERVER ALERTED code back. // Specs suggest that we send the code back unmodified uInt16 alertCode = getSyncStateAlertCode(fServerAlerted); alertcmdP = new TAlertCommand(fSessionP,this,alertCode); fAlertCode=alertCode; // save it for reference in scripts and for suspend/resume } #endif } else { // switch to slow sync fSlowSync=true; PDEBUGPRINTFX(DBG_HOT,("Switched to SlowSync because of Anchor mismatch or server-side user option")); CONSOLEPRINTF(("- switched to SlowSync because of Sync Anchor mismatch")); // sync state not ok, we need slow sync aStatusCommand.setStatusCode(508); // Refresh required // update effective alert code uInt16 alertCode = getSyncStateAlertCode(false); fAlertCode=alertCode; // save it for reference in scripts and for suspend // NOTE: if client detected slow-sync not before here, status 508 alone // (without another Alert 201 sent to the server) is sufficient for // server to switch to slow sync. if (IS_SERVER) { // generate Alert for Slow sync alertcmdP = new TAlertCommand(fSessionP,this,alertCode); } } // Now we are alerted for a sync // - reset item counters fItemsSent = 0; fItemsReceived = 0; #ifdef SYSYNC_SERVER if (IS_SERVER) { // Server case // - show info PDEBUGPRINTFX(DBG_HOT,( "ALERTED from client for %s%s%s Sync", fResuming ? "resumed " : "", fSlowSync ? "slow" : "normal", fFirstTimeSync ? " first time" : "" )); // server: add Item with Anchors and URIs SmlItemPtr_t itemP = newItem(); // - anchors itemP->meta=newMetaAnchor(fNextLocalAnchor.c_str(),fLastLocalAnchor.c_str()); // - MaxObjSize here again to make SCTS happy if ( (fSessionP->getRootConfig()->fLocalMaxObjSize>0) && (fSessionP->getSyncMLVersion()>=syncml_vers_1_1) ) { // SyncML 1.1 has object size and we need to put it here for SCTS smlPCDataToMetInfP(itemP->meta)->maxobjsize=newPCDataLong( fSessionP->getRootConfig()->fLocalMaxObjSize ); } // - URIs (reversed from what was received in Alert) itemP->source=newLocation(aTargetURI); // use unprocessed form as sent by remote itemP->target=newLocation(aSourceURI); // - add to alert command alertcmdP->addItem(itemP); // - set new state, alert now answered changeState(dssta_serveransweredalert,true); // force it } // server case #endif // SYSYNC_SERVER #ifdef SYSYNC_CLIENT if (IS_CLIENT) { // Client case // - now sync mode is stable (late switch to slowsync has now occurred if any) changeState(dssta_syncmodestable,true); // - show info PDEBUGPRINTFX(DBG_HOT,( "ALERTED from server for %s%s%s Sync", fResuming ? "resumed " : "", fSlowSync ? "slow" : "normal", fFirstTimeSync ? " first time" : "" )); } // client Case #endif // SYSYNC_CLIENT } // clear partial item if we definitely know we are not resuming if (!fResuming) { // not resuming - prevent that partial item is used in TSyncOpCommand fPartialItemState=pi_state_none; // free this space early (would be freed at session end anyway, but we don't need it any more now) if (fPIStoredDataAllocated) { smlLibFree(fPIStoredDataP); fPIStoredDataAllocated=false; } fPIStoredDataP=NULL; } // save name how remote adresses local database // (for sending same URI back in own Sync) fRemoteViewOfLocalURI = aTargetURI; // save it if (IS_SERVER) { fRemoteDBPath = aSourceURI; } if (sta!=LOCERR_OK) { // no alert command if (alertcmdP) delete alertcmdP; alertcmdP=NULL; aStatusCommand.setStatusCode(syncmlError(sta)); PDEBUGPRINTFX(DBG_HOT,("engProcessSyncAlert failed with status=%hd",sta)); } } SYSYNC_CATCH (...) // clean up locally owned objects if (alertcmdP) delete alertcmdP; SYSYNC_RETHROW; SYSYNC_ENDCATCH // return alert command, if any return alertcmdP; } // TLocalEngineDS::engProcessSyncAlert // process status received for sync alert bool TLocalEngineDS::engHandleAlertStatus(TSyError aStatusCode) { bool handled=false; if (IS_CLIENT) { // for client, make sure we have just sent the alert if (!testState(dssta_clientsentalert,true)) return false; // cannot switch if server not alerted // anyway, we have seen the status changeState(dssta_clientalertstatused,true); // force it } else { // for server, check if client did combined init&sync if (fLocalDSState>=dssta_syncmodestable) { // must be combined init&sync if (aStatusCode!=200) { // everything except ok is not allowed here PDEBUGPRINTFX(DBG_ERROR,("In combined init&sync, Alert status must be ok (but is %hd)",aStatusCode)); dsAbortDatastoreSync(400,false); // remote problem } // aborted or not, status is handled return true; } // normal case with separate init: we need to have answered the alert here if (!testState(dssta_serveransweredalert,true)) return false; // cannot switch if server not alerted } // server case // now check status code if (aStatusCode==508) { // remote party needs slow sync PDEBUGPRINTFX(DBG_HOT,("engHandleAlertStatus: Remote party needs SlowSync, switching to slowsync (AFTER alert, cancelling possible Resume)")); // Note: in server and client cases, this mode change may happen AFTER alert command exchange // - switch to slow sync fSlowSync=true; // - if we are late-forced to slow sync, this means that this cannot be a resume fResuming=false; // - update effective alert code that will be saved when this session gets suspended fAlertCode=getSyncStateAlertCode(fServerAlerted); handled=true; } else if (aStatusCode==200) { handled=true; } if (IS_CLIENT) { // check for resume override by server if (!handled && fResuming) { // we have requested resume if (aStatusCode==509) { // resume not accepted by server, but overridden by another sync type fResuming=false; PDEBUGPRINTFX(DBG_ERROR,("engHandleAlertStatus: Server rejected Resume")); handled=true; } } } else { // if we have handled it here, sync mode is now stable if (handled) { // if we get that far, sync mode for server is now stable AND we can receive cached maps changeState(dssta_syncmodestable,true); // force it, sync mode is now stable, no further changes are possible } } // no other status codes are supported at the datastore level if (!handled && aStatusCode>=400) { engAbortDataStoreSync(aStatusCode, false); // remote problem handled=true; } return handled; // status handled } // TLocalEngineDS::engHandleAlertStatus // initialize reception of syncop commands for datastore // Note: previously, this was implemented as initLocalDatastoreSync in syncsession localstatus TLocalEngineDS::engInitForSyncOps( const char *aRemoteDatastoreURI // URI of remote datastore ) { localstatus sta = LOCERR_OK; // no default types TSyncItemType *LocalSendToRemoteTypeP=NULL; // used by local to send to remote TSyncItemType *RemoteReceiveFromLocalTypeP=NULL; // used by remote to receive from local TSyncItemType *LocalReceiveFromRemoteTypeP=NULL; // used by local to receive from remote TSyncItemType *RemoteSendToLocalTypeP=NULL; // used by remote to send to local // Now determine remote datastore // Note: It might be that this was called already earlier in the session, so // the link between local and remote datastore might already exist if (fRemoteDatastoreP==NULL) { // try to locate it by name and set it - in case of superdatastore, it will be set in all subdatastores engSetRemoteDatastore(fSessionP->findRemoteDataStore(aRemoteDatastoreURI)); } else { // There is a remote datastore already associated #ifdef SYDEBUG // - make a sanity check to see if sepcified remote URI matches if(fRemoteDatastoreP!=fSessionP->findRemoteDataStore(aRemoteDatastoreURI)) { PDEBUGPRINTFX(DBG_ERROR,( "Warning: Received remote DS LocURI '%s' does not match already associated DS '%s'. We use the associated DS.", aRemoteDatastoreURI, fRemoteDatastoreP->getName() )); } #endif } // Now create a dummy remote data store for a blind sync attempt if (!fRemoteDatastoreP) { // no such remote datastore for this local datastore known, create one (or fail) #ifdef REMOTE_DS_MUST_BE_IN_DEVINF if (fSessionP->fRemoteDataStoresKnown) { // we have received devinf, but still can't find remote data store: error // Note: we had to disable this because of bugs in smartner server PDEBUGPRINTFX(DBG_ERROR,("Remote datastore name '%s' not found in received DevInf",aRemoteDatastoreURI)); return 404; } else #else if (fSessionP->fRemoteDataStoresKnown) { // we have received devinf, but still can't find remote data store: // just show in log, but continue as if there was no devInf received at all PDEBUGPRINTFX(DBG_ERROR,("Warning: Remote datastore name '%s' not found in received DevInf.",aRemoteDatastoreURI)); } #endif { // We couldn't retrieve DevInf (or !REMOTE_DS_MUST_BE_IN_DEVINF), so we have to try blind // - check remote specifics here if we had no devinf (there might be default remote // rules to apply or checking license restrictions // - this is executed only once per session, after that, we'll be fRemoteDevInfLock-ed if (!fSessionP->fRemoteDevInfKnown && !fSessionP->fRemoteDevInfLock) { // detect client specific server behaviour if needed sta = fSessionP->checkRemoteSpecifics(NULL, NULL); fSessionP->remoteAnalyzed(); // analyzed now (accepted or not does not matter) if (sta!=LOCERR_OK) return sta; // not ok, device rejected } // default data types are those preferred by local datastore (or explicitly marked for blind sync attempts) if (getDSConfig()->fTypeSupport.fPreferredLegacy) { // we have a preferred type for blind sync attempts LocalSendToRemoteTypeP = getSession()->findLocalType(getDSConfig()->fTypeSupport.fPreferredLegacy); LocalReceiveFromRemoteTypeP = LocalSendToRemoteTypeP; } else { // no specific "blind" preference, use my own normally preferred types LocalSendToRemoteTypeP = getPreferredTxItemType(); // send in preferred tx type of local datastore LocalReceiveFromRemoteTypeP = getPreferredRxItemType(); // receive in preferred rx type of local datastore } // same type on both end (as only local type exists) RemoteReceiveFromLocalTypeP = LocalSendToRemoteTypeP; // same on both end RemoteSendToLocalTypeP = LocalReceiveFromRemoteTypeP; // same on both end (as only local type exists) // create "remote" datastore with matching properties to local one PDEBUGPRINTFX(DBG_ERROR,("Warning: No DevInf for remote datastore, running blind sync attempt")); TRemoteDataStore *remDsP; MP_NEW(remDsP,DBG_OBJINST,"TRemoteDataStore",TRemoteDataStore( fSessionP, aRemoteDatastoreURI, // remote name of datastore 0 // standard Sync caps )); // - set it (in case of superdatastore in all subdatastores as well) engSetRemoteDatastore(remDsP); // add type support fRemoteDatastoreP->setPreferredTypes( RemoteReceiveFromLocalTypeP, // remote receives in preferred tx type of local datastore RemoteSendToLocalTypeP // remote sends in preferred rx type of local datastore ); // add it to the remote datastore list fSessionP->fRemoteDataStores.push_back(fRemoteDatastoreP); // make sure late devInf arriving won't supersede our artificially created remote datastore any more fSessionP->fRemoteDevInfLock=true; } } else { // found remote DB, determine default data exchange types // - common types for sending data to remote LocalSendToRemoteTypeP=getTypesForTxTo(fRemoteDatastoreP,&RemoteReceiveFromLocalTypeP); // - common types for receiving data from remote LocalReceiveFromRemoteTypeP=getTypesForRxFrom(fRemoteDatastoreP,&RemoteSendToLocalTypeP); } #ifndef NO_REMOTE_RULES // check if rule match type will override what we found so far if (!fSessionP->fActiveRemoteRules.empty()) { // have a look at our rulematch types TRuleMatchTypesContainer::iterator pos; TSyncItemType *ruleMatchTypeP = NULL; for (pos=fRuleMatchItemTypes.begin();pos!=fRuleMatchItemTypes.end();++pos) { // there is a rule applied // - parse match string in format "rule[,rule]..." with * and ? wildcards allowed in "rule" cAppCharP p=(*pos).ruleMatchString; while (*p!=0) { // split at commas cAppCharP e=strchr(p,','); size_t n; if (e) { n=e-p; e++; } else { n=strlen(p); e=p+n; } // see if that matches with any of the active rules TRemoteRulesList::iterator apos; for(apos=fSessionP->fActiveRemoteRules.begin();apos!=fSessionP->fActiveRemoteRules.end();apos++) { if (strwildcmp((*apos)->getName(), p, 0, n)==0) { ruleMatchTypeP=(*pos).itemTypeP; // get the matching type break; } } if (ruleMatchTypeP) break; // found a rule match type // test next match target p=e; } // apply if found one already if (ruleMatchTypeP) { // use this instead of normal types // - local types LocalSendToRemoteTypeP=ruleMatchTypeP; // used by local to send to remote LocalReceiveFromRemoteTypeP=ruleMatchTypeP; // used by local to receive from remote // Find matching remote types // - first look for existing remote type with same config as local one TSyncItemType *remCorrTypeP = fSessionP->findRemoteType(ruleMatchTypeP->getTypeConfig(),fRemoteDatastoreP); // - if none found, create one and have it inherit the CTCap options of the generic version that is already there if (!remCorrTypeP) { // none found: need to create one remCorrTypeP = ruleMatchTypeP->newCopyForSameType(fSessionP,fRemoteDatastoreP); if (remCorrTypeP) { // - get generic remote type (the one that might have received CTCap already) TSyncItemType *remGenericTypeP = fRemoteDatastoreP->getSendType(ruleMatchTypeP); // - copy options if (remGenericTypeP) remCorrTypeP->copyCTCapInfoFrom(*remGenericTypeP); } } // now assign RemoteReceiveFromLocalTypeP=remCorrTypeP; RemoteSendToLocalTypeP=remCorrTypeP; // Show that we are using ruleMatch type PDEBUGPRINTFX(DBG_DATA+DBG_HOT,( "An active remote rule overrides default type usage - forcing type '%s' for send and receive", ruleMatchTypeP->getTypeConfig()->getName() )); // done break; } } } #endif // check if we are sync compatible (common type for both directions) if (LocalSendToRemoteTypeP && LocalReceiveFromRemoteTypeP && RemoteReceiveFromLocalTypeP && RemoteSendToLocalTypeP) { // avoid further changes in remote devInf (e.g. by late result of GET, sent *after* first ) fSessionP->fRemoteDevInfLock=true; // there is a common data type for each of both directions // - show local types PDEBUGPRINTFX(DBG_DATA,( "Local Datastore '%s' - Types: tx to remote: '%s': %s (%s), rx from remote: '%s': %s (%s)", getName(), LocalSendToRemoteTypeP->getTypeConfig()->getName(),LocalSendToRemoteTypeP->getTypeName(), LocalSendToRemoteTypeP->getTypeVers(), LocalReceiveFromRemoteTypeP->getTypeConfig()->getName(),LocalReceiveFromRemoteTypeP->getTypeName(), LocalReceiveFromRemoteTypeP->getTypeVers() )); // - show remote types PDEBUGPRINTFX(DBG_DATA+DBG_DETAILS,( "Remote Datastore '%s' - Types: tx to local: '%s': %s (%s), rx from local: '%s': %s (%s)", fRemoteDatastoreP->getName(), RemoteSendToLocalTypeP->getTypeConfig()->getName(),RemoteSendToLocalTypeP->getTypeName(), RemoteSendToLocalTypeP->getTypeVers(), RemoteReceiveFromLocalTypeP->getTypeConfig()->getName(),RemoteReceiveFromLocalTypeP->getTypeName(), RemoteReceiveFromLocalTypeP->getTypeVers() )); } else { // datastores are not sync compatible sta=415; PDEBUGPRINTFX(DBG_ERROR,("No common datastore formats -> cannot sync (415)")); PDEBUGPRINTFX(DBG_EXOTIC,("- LocalSendToRemoteTypeP = '%s'", LocalSendToRemoteTypeP ? LocalSendToRemoteTypeP->getTypeName() : "")); PDEBUGPRINTFX(DBG_EXOTIC,("- LocalReceiveFromRemoteTypeP = '%s'", LocalReceiveFromRemoteTypeP ? LocalReceiveFromRemoteTypeP->getTypeName() : "")); PDEBUGPRINTFX(DBG_EXOTIC,("- RemoteSendToLocalTypeP = '%s'", RemoteSendToLocalTypeP ? RemoteSendToLocalTypeP->getTypeName() : "")); PDEBUGPRINTFX(DBG_EXOTIC,("- RemoteReceiveFromLocalTypeP = '%s'", RemoteReceiveFromLocalTypeP ? RemoteReceiveFromLocalTypeP->getTypeName() : "")); engAbortDataStoreSync(sta,true,false); // do not proceed with sync of this datastore, local problem, not resumable return sta; } // set type info in local datastore setSendTypeInfo(LocalSendToRemoteTypeP,RemoteReceiveFromLocalTypeP); setReceiveTypeInfo(LocalReceiveFromRemoteTypeP,RemoteSendToLocalTypeP); // - initialize usage of types (checks compatibility as well) return initDataTypeUse(); } // TLocalEngineDS::engInitForSyncOps // called from command to generate sync sub-commands to be sent to remote // Returns true if now finished for this datastore // also changes state to dssta_syncgendone when all sync commands have been generated bool TLocalEngineDS::engGenerateSyncCommands( TSmlCommandPContainer &aNextMessageCommands, TSmlCommand * &aInterruptedCommandP, const char *aLocalIDPrefix ) { PDEBUGBLOCKFMT(("SyncGen","Now generating sync commands","datastore=%s",getName())); bool finished=false; #ifdef SYSYNC_CLIENT if (IS_CLIENT) finished = logicGenerateSyncCommandsAsClient(aNextMessageCommands, aInterruptedCommandP, aLocalIDPrefix); #endif #ifdef SYSYNC_SERVER if (IS_SERVER) finished = logicGenerateSyncCommandsAsServer(aNextMessageCommands, aInterruptedCommandP, aLocalIDPrefix); #endif // change state when finished if (finished) { changeState(dssta_syncgendone,true); if (IS_CLIENT) { // from client only skips to clientmapssent without any server communication // (except if we are in old synthesis-compatible mode which runs from-client-only // with empty sync-from-server and map phases. if (getSyncMode()==smo_fromclient && !fSessionP->fCompleteFromClientOnly) { // data access ends with all sync commands generated in from-client-only PDEBUGPRINTFX(DBG_PROTO,("From-Client-Only sync: skipping directly to end of map phase now")); changeState(dssta_dataaccessdone,true); changeState(dssta_clientmapssent,true); } } } PDEBUGPRINTFX(DBG_DATA,( "engGenerateSyncCommands ended, state='%s', sync generation %sdone", getDSStateName(), fLocalDSState>=dssta_syncgendone ? "" : "NOT " )); PDEBUGENDBLOCK("SyncGen"); return finished; } // TLocalEngineDS::engGenerateSyncCommands // called to confirm a sync operation's completion (status from remote received) // @note aSyncOp passed not necessarily reflects what was sent to remote, but what actually happened void TLocalEngineDS::dsConfirmItemOp(TSyncOperation aSyncOp, cAppCharP aLocalID, cAppCharP aRemoteID, bool aSuccess, localstatus aErrorStatus) { // commands failed with "cancelled" should be re-sent for resume if (!aSuccess && aErrorStatus==514 && dsResumeSupportedInDB() && fSessionP->isSuspending()) { // cancelled syncop as result of explicit suspend: mark for resume as it was never really processed at the other end PDEBUGPRINTFX(DBG_DATA+DBG_EXOTIC,("Cancelled SyncOp during suspend -> mark for resume")); engMarkItemForResume(aLocalID,aRemoteID,true); } PDEBUGPRINTFX(DBG_DATA+DBG_EXOTIC,( "dsConfirmItemOp completed, syncop=%s, localID='%s', remoteID='%s', %s, errorstatus=%hd", SyncOpNames[aSyncOp], aLocalID ? aLocalID : "", aRemoteID ? aRemoteID : "", aSuccess ? "SUCCESS" : "FAILURE", aErrorStatus )); } // TLocalEngineDS::dsConfirmItemOp // handle status of sync operation // Note: in case of superdatastore, status is always directed to the originating subdatastore, as // the fDataStoreP of the SyncOpCommand is set to subdatastore when generating the SyncOps. bool TLocalEngineDS::engHandleSyncOpStatus(TStatusCommand *aStatusCmdP,TSyncOpCommand *aSyncOpCmdP) { TSyError statuscode = aStatusCmdP->getStatusCode(); // we can make it simple here because we KNOW that we do not send multiple items per SyncOp, so we // just need to look at the first item's target and source const char *localID = aSyncOpCmdP->getSourceLocalID(); const char *remoteID = aSyncOpCmdP->getTargetRemoteID(); #ifdef SYSYNC_SERVER string realLocID; #endif if (localID) { #ifdef SUPERDATASTORES // remove possible prefix if this item was sent in the command context of a superdatastore if (fAsSubDatastoreOf) { // let superdatastore remove the prefix for me localID = fAsSubDatastoreOf->removeSubDSPrefix(localID,this); } #endif #ifdef SYSYNC_SERVER if (IS_SERVER) { // for server only: convert to internal representation realLocID=localID; obtainRealLocalID(realLocID); localID=realLocID.c_str(); } #endif } // handle special cases for Add/Replace/Delete TSyncOperation sop = aSyncOpCmdP->getSyncOp(); switch (sop) { case sop_wants_add: case sop_add: if (statuscode<300 || statuscode==419) { // All ok status 2xx as well as special "merged" 419 is ok for an add: // Whatever remote said, I know this is an add and so I counts this as such // (even if the remote somehow merged it with existing data, // it is obviously a new item in my sync set with this remote) fRemoteItemsAdded++; dsConfirmItemOp(sop_add,localID,remoteID,true); // ok added } else if ( statuscode==418 && (isResuming() || (isSlowSync() && IS_CLIENT) ) ) { // "Already exists"/418 is acceptable... // ... in slow sync as client, as some servers use it instead of 200/419 for slow sync match // ... during resumed sync as server with clients like Symbian which // can detect duplicate adds themselves. Should not generally // occur, as we shouldn't re-send them as long as we haven't seen // a map. But symbian cannot send early maps - it instead does // it's own duplicate checking. // ... during resumed sync as client (as servers might issue 418 for // items sent a second time after an implicit suspend) PDEBUGPRINTFX(DBG_ERROR,("Warning: received 418 status for add in resumed/slowsync session -> treat it as ok (200)")); dsConfirmItemOp(sop_replace,localID,remoteID,true); // kind of ok statuscode=200; // convert to ok (but no count incremented, as nothing changed) } else { dsConfirmItemOp(sop_add,localID,remoteID,false,statuscode); // failed add } // adding with 420 error: device full if (statuscode==420) { // special case: device indicates that it is full, so stop adding in this session PDEBUGPRINTFX(DBG_ERROR,("Warning: Status %hd: Remote device full -> preventing further adds in this session",statuscode)); engStopAddingToRemote(); fRemoteItemsError++; // this is considered a remote item error } break; // case sop_copy: break; case sop_wants_replace: case sop_replace: #ifdef SYSYNC_SERVER if (IS_SERVER && (statuscode==404 || statuscode==410)) { // obviously, remote item that we wanted to change does not exist any more. // Instead of aborting the session we'll just remove the map item for that // server item, such that it will be re-added in the next sync session PDEBUGPRINTFX(DBG_DATA,("Status %hd: Replace target not found on client -> silently ignore but remove map in server (item will be added in next session), ",statuscode)); // remove map for remote item(s), targetRef contain remoteIDs SmlTargetRefListPtr_t targetrefP = aStatusCmdP->getStatusElement()->targetRefList; while (targetrefP) { // target ref available engProcessMap(smlPCDataToCharP(targetrefP->targetRef),NULL); // next targetrefP=targetrefP->next; } statuscode=410; // always use "gone" status (even if we might have received a 404) dsConfirmItemOp(sop_replace,localID,remoteID,false,statuscode); break; } else #endif if (statuscode==201) { fRemoteItemsAdded++; dsConfirmItemOp(sop_add,localID,remoteID,true); // ok as add } else if (statuscode<300 || statuscode==419) { // conflict resolved counts as ok as well fRemoteItemsUpdated++; dsConfirmItemOp(sop_replace,localID,remoteID,true); // ok as replace } #ifdef SYSYNC_CLIENT else if (IS_CLIENT && (isSlowSync() && statuscode==418)) { // "Already exists"/418 is acceptable as client in slow sync because some // servers use it instead of 200/419 for slow sync match PDEBUGPRINTFX(DBG_ERROR,("Warning: received 418 for for replace during slow sync - treat it as ok (200), but don't count as update")); dsConfirmItemOp(sop_replace,localID,remoteID,true); // 418 is acceptable in slow sync (not really conformant, but e.g. happening with Scheduleworld) statuscode=200; // always use "gone" status (even if we might have received a 404) } #endif // SYSYNC_CLIENT else { dsConfirmItemOp(sop_replace,localID,remoteID,false,statuscode); // failed replace } break; case sop_archive_delete: case sop_soft_delete: case sop_delete: if (statuscode<211) fRemoteItemsDeleted++; // allow 211 and 404 for delete - after all, the record is not there // any more on the remote if (statuscode==404 || statuscode==211) { PDEBUGPRINTFX(DBG_DATA,("Status: %hd: To-be-deleted item not found, but accepted this (changed status to 200)",statuscode)); statuscode=200; } // if ok (explicit or implicit), we can confirm the delete dsConfirmItemOp(sop_delete,localID,remoteID,statuscode<300,statuscode); // counts as ok delete break; default: break; } // switch // check if we want to mark failed items for resend in the next session or abort bool resend = fDSConfigP->fResendFailing; // get default from config #ifdef SCRIPT_SUPPORT // let script check status code TErrorFuncContext errctx; errctx.statuscode = statuscode; errctx.resend = resend; errctx.newstatuscode = statuscode; errctx.syncop = sop; errctx.datastoreP = this; // - first check datastore level if ( TScriptContext::executeTest( false, // assume script does NOT handle status entirely fDataStoreScriptContextP, fDSConfigP->fSentItemStatusScript, &ErrorFuncTable, &errctx // caller context ) ) { // completely handled PDEBUGPRINTFX(DBG_ERROR,("Status: %hd: Handled by datastore script (original op was %s)",statuscode,SyncOpNames[sop])); return true; } errctx.statuscode = errctx.newstatuscode; // - then check session level if ( TScriptContext::executeTest( false, // assume script does NOT handle status entirely fSessionP->fSessionScriptContextP, fSessionP->getSessionConfig()->fSentItemStatusScript, &ErrorFuncTable, &errctx // caller context ) ) { // completely handled PDEBUGPRINTFX(DBG_ERROR,("Status: %hd: Handled by session script (original op was %s)",statuscode,SyncOpNames[sop])); return true; } // not completely handled, use possibly modified status code #ifdef SYDEBUG if (statuscode != errctx.newstatuscode) { PDEBUGPRINTFX(DBG_ERROR,("Status: Script changed original status=%hd to %hd (original op was %s)",statuscode,errctx.newstatuscode,SyncOpNames[errctx.syncop])); } #endif statuscode = errctx.newstatuscode; resend = errctx.resend; #endif // now perform default action according to status code switch (statuscode) { case 200: break; case 201: PDEBUGPRINTFX(DBG_PROTO,("Status: %hd: Item added (original op was %s)",statuscode,SyncOpNames[sop])); break; case 204: PDEBUGPRINTFX(DBG_PROTO,("Status: %hd: No content (original op was %s)",statuscode,SyncOpNames[sop])); break; case 207: case 208: case 209: case 419: PDEBUGPRINTFX(DBG_HOT,("Status: %hd: Conflict resolved (original op was %s)",statuscode,SyncOpNames[sop])); break; case 210: PDEBUGPRINTFX(DBG_HOT,("Status: %hd: Delete without archive (original op was %s)",statuscode,SyncOpNames[sop])); break; case 211: PDEBUGPRINTFX(DBG_ERROR,("Status: %hd: nothing deleted, item not found (original op was %s)",statuscode,SyncOpNames[sop])); break; case 410: // gone case 420: // device full // these have been handled above and are considered ok now break; case 514: // cancelled // ignore cancelling while suspending, as these are CAUSED by the suspend if (fSessionP->isSuspending() && dsResumeSupportedInDB()) { // don't do anything here - we'll be suspended later (but process commands until then) // dsConfirmItemOp() has already caused the item to be marked for resume break; } // for non-DS-1.2 sessions, we treat 514 like the other errors below (that is - retry might help) case 424: // size mismatch (e.g. due to faild partial item resume attempt -> retry will help) case 417: // retry later (remote says that retry will probably work) case 506: // processing error, retry later (remote says that retry will probably work) case 404: // not found (retry is not likely to help, but does not harm too much, either) case 408: // timeout (if that happens on a single item, retry probably helps) case 415: // bad type (retry is not likely to help, but does not harm too much, either) case 510: // datastore failure (too unspecific to know if retry might help, but why not?) case 500: // general failure (too unspecific to know if retry might help, but why not?) // these errors cause either a resend in a later session // or only abort the datastore, but not the session if (resend && dsResumeSupportedInDB()) { PDEBUGPRINTFX(DBG_ERROR,("Status: General error %hd (original op was %s) -> marking item for resend in next session",statuscode,SyncOpNames[sop])); engMarkItemForResend(localID,remoteID); // Note: includes incrementing fRemoteItemsError } else { PDEBUGPRINTFX(DBG_ERROR,("Status: General error %hd (original op was %s) -> aborting sync with this datastore",statuscode,SyncOpNames[sop])); engAbortDataStoreSync(statuscode,false); // remote problem } break; default: // let command handle it return false; //break; } // status handled return true; // handled status } // TLocalEngineDS::engHandleSyncOpStatus /// Internal events during sync for derived classes /// @Note local DB authorisation must be established already before calling these /// - cause loading of all session anchoring info and other admin data (logicMakeAdminReady()) /// fLastRemoteAnchor,fLastLocalAnchor,fNextLocalAnchor; isFirstTimeSync() will be valid after the call /// - in case of superdatastore, consolidates the anchor information from the subdatastores localstatus TLocalEngineDS::engInitSyncAnchors( cAppCharP aDatastoreURI, ///< local datastore URI cAppCharP aRemoteDBID ///< ID of remote datastore (to find session information in local DB) ) { // nothing more to do than making admin data ready // - this will fill all dsSavedAdminData members here and in all derived classes localstatus sta=logicMakeAdminReady(aDatastoreURI, aRemoteDBID); if (sta==LOCERR_OK) { changeState(dssta_adminready); // admin data is now ready } // return on error return sta; } // TLocalEngineDS::engInitSyncAnchors #ifdef SYSYNC_CLIENT // initialize Sync alert for datastore according to Parameters set with dsSetClientSyncParams() localstatus TLocalEngineDS::engPrepareClientSyncAlert(void) { #ifdef SUPERDATASTORES // no operation here if running under control of a superdatastore. // superdatastore's engPrepareClientSyncAlert() will call engPrepareClientRealDSSyncAlert of all subdatastores at the right time if (fAsSubDatastoreOf) return LOCERR_OK; #endif // this is a real datastore return engPrepareClientDSForAlert(); } // TLocalEngineDS::engPrepareClientSyncAlert // initialize Sync alert for datastore according to Parameters set with dsSetClientSyncParams() localstatus TLocalEngineDS::engPrepareClientDSForAlert(void) { localstatus sta; // reset the filters that might be added to in alertprepscript // (as they might have been half set-up in a previous failed alert, they must be cleared and re-constructed here) resetFiltering(); #ifdef SCRIPT_SUPPORT // AlertPrepareScript to add filters and CGI // - rebuild early (before all of the other DS scripts in makeAdminReady caused by engInitSyncAnchors below!) TScriptContext::rebuildContext(fSessionP->getSyncAppBase(),fDSConfigP->fAlertPrepScript,fDataStoreScriptContextP,fSessionP); // - add custom DS 1.2 filters and/or custom CGI to fRemoteDBPath TScriptContext::execute( fDataStoreScriptContextP, fDSConfigP->fAlertPrepScript, fDSConfigP->getClientDBFuncTable(), // function table with extra this // datastore pointer needed for context ); #endif // - save the identifying name of the DB fIdentifyingDBName = fLocalDBPath; // - get information about last session out of database sta = engInitSyncAnchors( relativeURI(fLocalDBPath.c_str()), fRemoteDBPath.c_str() ); if (sta!=LOCERR_OK) { // error getting anchors PDEBUGPRINTFX(DBG_ERROR,("Could not get Sync Anchor info")); return localError(sta); } // check if we are forced to slowsync (otherwise, fSlowSync is pre-set from dsSetClientSyncParams() fSlowSync = fSlowSync || fLastLocalAnchor.empty() || fFirstTimeSync; // check for resume if (fResumeAlertCode!=0 && fSessionP->getSyncMLVersion()>=syncml_vers_1_2) { // we have a suspended session, try to resume PDEBUGPRINTFX(DBG_PROTO,("Found suspended session with Alert Code = %hd",fResumeAlertCode)); fResuming = true; } return LOCERR_OK; // ok } // TLocalEngineDS::engPrepareClientDSForAlert // generate Sync alert for datastore after initialisation with engPrepareClientSyncAlert() // Note: this could be repeatedly called due to auth failures at beginning of session // Note: this is a NOP for subDatastores (should not be called in this case, anyway) localstatus TLocalEngineDS::engGenerateClientSyncAlert( TAlertCommand *&aAlertCommandP ) { aAlertCommandP=NULL; #ifdef SUPERDATASTORES if (fAsSubDatastoreOf) return LOCERR_OK; // NOP, ok, only superdatastore creates an alert! #endif PDEBUGPRINTFX(DBG_PROTO,( "(Saved) Last Local Client Anchor='%s', (generated) Next Local Client Anchor='%s' (sent to server as / in )", fLastLocalAnchor.c_str(), fNextLocalAnchor.c_str() )); // create appropriate initial alert command TAgentConfig *configP = static_cast(static_cast(getSession())->getRootConfig()->fAgentConfigP); uInt16 alertCode = getSyncStateAlertCode(fServerAlerted, configP->fPreferSlowSync); // check for resume if (fResuming) { // check if what we resume is same as what we wanted to do if (alertCode != fResumeAlertCode) { // this is ok for client, just show in log PDEBUGPRINTFX(DBG_PROTO,( "Sync mode seems to have changed (alert code = %hd) since last Suspend (alert code = %hd)", alertCode, fResumeAlertCode )); } // resume alertCode=225; // resume PDEBUGPRINTFX(DBG_PROTO,( "Alerting resume of last sync session (original alert code = %hd)", fResumeAlertCode )); } aAlertCommandP = new TAlertCommand(fSessionP,this,alertCode); PDEBUGPRINTFX(DBG_HOT,( "%s: ALERTING server for %s%s%s Sync", getName(), fResuming ? "RESUMED " : "", fSlowSync ? "slow" : "normal", fFirstTimeSync ? " first time" : "" )); // add Item with Anchors and URIs SmlItemPtr_t itemP = newItem(); // - anchors itemP->meta=newMetaAnchor(fNextLocalAnchor.c_str(),fLastLocalAnchor.c_str()); // - MaxObjSize here again to make SCTS happy if ( (fSessionP->getSyncMLVersion()>=syncml_vers_1_1) && (fSessionP->getRootConfig()->fLocalMaxObjSize>0) ) { // SyncML 1.1 has object size and we need to put it here for SCTS smlPCDataToMetInfP(itemP->meta)->maxobjsize=newPCDataLong( fSessionP->getRootConfig()->fLocalMaxObjSize ); } // - URIs itemP->source=newLocation(fLocalDBPath.c_str()); // local DB ID itemP->target=newLocation(fRemoteDBPath.c_str()); // use remote path as configured in client settings // - add DS 1.2 filters if (!fRemoteRecordFilterQuery.empty() || false /* %%% field level filter */) { if (fSessionP->getSyncMLVersion()findLocalType(fDSConfigP->fTypeSupport.fPreferredRx); if (itemTypeP) { // add meta type filterP->meta = newMetaType(itemTypeP->getTypeName()); } // add filtertype if needed (=not EXCLUSIVE) if (fRemoteFilterInclusive) { filterP->filtertype=newPCDataString(SYNCML_FILTERTYPE_INCLUSIVE); } // record level if (!fRemoteRecordFilterQuery.empty()) { // add filterP->record = SML_NEW(SmlRecordOrFieldFilter_t); // - add item with data=filterquery filterP->record->item = newStringDataItem(fRemoteRecordFilterQuery.c_str()); // - add meta type with grammar filterP->record->item->meta = newMetaType(SYNCML_FILTERTYPE_CGI); PDEBUGPRINTFX(DBG_HOT,( "Alerting with %sCLUSIVE Record Level Filter Query = '%s'", fRemoteFilterInclusive ? "IN" : "EX", fRemoteRecordFilterQuery.c_str() )); } // field level /// @todo %%% to be implemented if (false) { // !!! remember to add real check (now: false) in outer if-statement as well!!!!! // %%% tbd } } // add it to item itemP->target->filter = filterP; } // - add to alert command aAlertCommandP->addItem(itemP); // we have now produced the client alert command, change state return changeState(dssta_clientsentalert); } // TLocalEngineDS::engGenerateClientSyncAlert // Init engine for client sync // - determine types to exchange // - make sync set ready localstatus TLocalEngineDS::engInitForClientSync(void) { #ifdef SUPERDATASTORES // no init in case we are under control of a superdatastore -> the superdatastore will do that if (fAsSubDatastoreOf) return LOCERR_OK; #endif return engInitDSForClientSync(); } // TLocalEngineDS::engInitForClientSync // Init engine for client sync // - determine types to exchange // - make sync set ready localstatus TLocalEngineDS::engInitDSForClientSync(void) { // make ready for syncops localstatus sta = engInitForSyncOps(getRemoteDBPath()); if (sta==LOCERR_OK) { // - let local datastore (derived DB-specific class) prepare for sync sta = changeState(dssta_dataaccessstarted); if (sta==LOCERR_OK && isStarted(false)) { // already started now, change state sta = changeState(dssta_syncsetready); } } return sta; } // TLocalEngineDS::engInitDSForClientSync #endif // Client // get Alert code for current Sync State uInt16 TLocalEngineDS::getSyncStateAlertCode(bool aServerAlerted, bool aClientMinimal) { uInt16 alertcode=0; switch (fSyncMode) { case smo_twoway : alertcode = aServerAlerted ? 206 : 200; break; case smo_fromclient : alertcode = aServerAlerted ? 207 : 202; // fully specified break; case smo_fromserver : if (aClientMinimal) { // refresh from server is just client not sending any data, so we can alert like two-way alertcode = aServerAlerted ? 206 : 200; } else { // correctly alert it alertcode = aServerAlerted ? 209 : 204; } break; case numSyncModes: // invalid break; } // slowsync/refresh variants are always plus one, except 206 --> 201 (same as client initiated slow sync) if (fSlowSync) alertcode = (alertcode!=206 ? alertcode+1 : 201); return alertcode; } // TLocalEngineDS::getSyncStateAlertCode /// initializes Sync state variables and returns false if alert is not supported localstatus TLocalEngineDS::setSyncModeFromAlertCode(uInt16 aAlertCode, bool aAsClient) { localstatus sta; TSyncModes syncMode; bool slowSync, serverAlerted; // - translate into mode and flags sta=getSyncModeFromAlertCode(aAlertCode,syncMode,slowSync,serverAlerted); if (sta==LOCERR_OK) { // - set them sta=setSyncMode(aAsClient,syncMode,slowSync,serverAlerted); } return sta; } // TLocalEngineDS::setSyncModeFromAlertCode /// initializes Sync mode variables localstatus TLocalEngineDS::setSyncMode(bool aAsClient, TSyncModes aSyncMode, bool aIsSlowSync, bool aIsServerAlerted) { // get sync caps of this datastore uInt32 synccapmask=getSyncCapMask(); // check if mode supported if (aIsServerAlerted) { // check if we support server alerted modes, SyncCap/Bit=7 if (~synccapmask & (1<<7)) return 406; // not supported } switch(aSyncMode) { case smo_twoway: // Two-way Sync, SyncCap/Bit=1 // or Two-way slow Sync, SyncCap/Bit=2 if (~synccapmask & (1<< (aIsSlowSync ? 2 : 1))) return 406; // not supported if (fSyncMode==smo_fromserver && aAsClient) aSyncMode=smo_fromserver; // for client, if already fromserver mode set, keep it break; case smo_fromclient: // One-way from client, SyncCap/Bit=3 // or Refresh (=slow one-way) from client, SyncCap/Bit=4 if (~synccapmask & (1<< (aIsSlowSync ? 4 : 3))) return 406; // not supported if (!aAsClient) fRefreshOnly=true; // as server, we are in refresh-only-mode if we get one-way from client break; case smo_fromserver: // One-way from server, SyncCap/Bit=5 // or Refresh (=slow one-way) from server, SyncCap/Bit=6 if (~synccapmask & (1<< (aIsSlowSync ? 6 : 5))) return 406; // not supported if (aAsClient) fRefreshOnly=true; // as client, we are in refresh-only-mode if we get one-way fromm server break; default: return 400; // bad request } // now set mode and flags (possibly adjusted above) fSyncMode=aSyncMode; fSlowSync=aIsSlowSync; fServerAlerted=aIsServerAlerted; // ok return LOCERR_OK; } // TLocalEngineDS::setSyncMode /// get Sync mode variables from given alert code localstatus TLocalEngineDS::getSyncModeFromAlertCode(uInt16 aAlertCode, TSyncModes &aSyncMode, bool &aIsSlowSync, bool &aIsServerAlerted) { // these might be pre-defined) /// @deprecated state change does not belong here aIsSlowSync=false; aIsServerAlerted=false; aSyncMode=smo_twoway; // to make sure it is valid // first test if server-alerted if (aAlertCode>=206 && aAlertCode<210) { // Server alerted modes aIsServerAlerted=true; } // test for compatibility with alert code switch(aAlertCode) { case 200: case 206: // Two-way Sync aSyncMode=smo_twoway; aIsSlowSync=false; break; case 201: // Two-way slow Sync aSyncMode=smo_twoway; aIsSlowSync=true; break; case 202: case 207: // One-way from client aSyncMode=smo_fromclient; aIsSlowSync=false; break; case 203: case 208: // refresh (=slow one-way) from client aSyncMode=smo_fromclient; aIsSlowSync=true; break; case 204: case 209: // One-way from server aSyncMode=smo_fromserver; aIsSlowSync=false; break; case 205: case 210: // refresh (=slow one-way) from server aSyncMode=smo_fromserver; aIsSlowSync=true; break; default: // bad alert return 400; } return LOCERR_OK; } // TLocalEngineDS::getSyncModeFromAlertCode // create new Sync capabilities info from capabilities mask // Bit0=reserved, Bit1..Bitn = SyncType 1..n available // Note: derived classes might add special sync codes and/or mask standard ones SmlDevInfSyncCapPtr_t TLocalEngineDS::newDevInfSyncCap(uInt32 aSyncCapMask) { SmlDevInfSyncCapPtr_t synccapP; SmlPcdataPtr_t synctypeP; // new synccap structure synccapP = SML_NEW(SmlDevInfSyncCap_t); // synccap list is empty synccapP->synctype=NULL; // now add standard synccaps for (sInt16 k=0; k<32; k++) { if (aSyncCapMask & (1<synctype)); } } // Now add non-standard synccaps. // From the spec: "Other values can also be specified." // Values are PCDATA, so we can use plain strings. // // But the Funambol server expects integer numbers and // throws a parser error when sent a string. So better // stick to a semi-random number (hopefully no-one else // is using it). // // Worse, Nokia phones cancel direct sync sessions with an // OBEX error ("Forbidden") when non-standard sync modes // are included in the SyncCap. // Event worse, some servers refuse to sync at // all with strange/misleading error codes when extensions are found. // Therefore, this is nothing to be enabled in general, // so it needs to be explicitly enabled in config from // 3.4.0.45 onwards (using yes // If it is enabled in config, the following logic is used: // - libsynthesis in a SyncML client will always send // all the extended sync modes; with the Funambol // workaround in place that works // - libsynthesis in a SyncML server will only send the // extended sync modes if the client has sent any // extended sync modes itself; the 390002 mode is // sent unconditionally for that purpose // // Corresponding code in TRemoteDataStore::setDatastoreDevInf(). // if ( fSessionP->getSessionConfig()->fSyncModeExtensions && // must be enabled in config (!IS_SERVER || fSessionP->receivedSyncModeExtensions()) // and if, server only uses it with clients which have it in their devInf as well ) { bool extended=false; if (canRestart()) { synctypeP=newPCDataString("390001"); addPCDataToList(synctypeP,&(synccapP->synctype)); extended=true; } // Finally add non-standard synccaps that are outside of the // engine's control. set modes; getSyncModes(modes); for (set::const_iterator it = modes.begin(); it != modes.end(); ++it) { synctypeP=newPCDataString(*it); addPCDataToList(synctypeP,&(synccapP->synctype)); extended=true; } // Add fake mode to signal peer that we support extensions. // Otherwise a server won't send them, to avoid breaking // client's (like Nokia phones) which don't. // // Don't send the fake mode unnecessarily (= when some other // non-standard modes where already added), because Funambol seems // to have a hard-coded limit of 9 entries in the and // complains with a 513 internal server error (when using WBXML) // or a 'Expected "CTCap" end tag, found "CTType" end tag' (when // using XML). if (!extended) { synctypeP=newPCDataString("390002"); addPCDataToList(synctypeP,&(synccapP->synctype)); } } // return it return synccapP; } // TLocalEngineDS::newDevInfSyncCap // obtain new datastore info, returns NULL if none available SmlDevInfDatastorePtr_t TLocalEngineDS::newDevInfDatastore(bool aAsServer, bool aWithoutCTCapProps) { SmlDevInfDatastorePtr_t datastoreP; // set only basic info, details must be added in derived class // - sourceref is the name of the datastore, // or for server, if already alerted, the name used in the alert // (this is to allow /dsname/foldername with clients that expect the // devInf to contain exactly the same full path as name, like newer Nokias) string dotname; #ifdef SYSYNC_SERVER if (IS_SERVER && testState(dssta_serveralerted,false) && fSessionP->fDSPathInDevInf) { // server and already alerted // - don't include sub-datastores if (fAsSubDatastoreOf) { return NULL; } // - use datastore spec as sent from remote, minus CGI, as relative spec dotname = URI_RELPREFIX; dotname += fSessionP->SessionRelativeURI(fRemoteViewOfLocalURI.c_str()); if (!fSessionP->fDSCgiInDevInf) { // remove CGI string::size_type n=dotname.find("?"); if (n!=string::npos) dotname.resize(n); // remove CGI } } else #endif { // client or not yet alerted - just use datastore base name StringObjPrintf(dotname,URI_RELPREFIX "%s",fName.c_str()); } // create new datastoreP=SML_NEW(SmlDevInfDatastore_t); datastoreP->sourceref=newPCDataString(dotname); #ifndef MINIMAL_CODE // - Optional display name datastoreP->displayname=newPCDataOptString(getDisplayName()); #else datastoreP->displayname=NULL; #endif // - MaxGUIDsize (for client only) if (aAsServer) datastoreP->maxguidsize=NULL; else datastoreP->maxguidsize=newPCDataLong(fMaxGUIDSize); // - check for legacy mode type (that is to be used as "preferred" instead of normal preferred) TSyncItemType *legacyTypeP = NULL; if (getSession()->fLegacyMode && getDSConfig()->fTypeSupport.fPreferredLegacy) { // get the type marked as blind legacyTypeP = getSession()->findLocalType(getDSConfig()->fTypeSupport.fPreferredLegacy); } // - RxPref if (!fRxPrefItemTypeP) SYSYNC_THROW(TStructException("Datastore has no RxPref ItemType")); datastoreP->rxpref = (legacyTypeP ? legacyTypeP : fRxPrefItemTypeP)->newXMitDevInf(); // - Rx (excluding the type we report as preferred) datastoreP->rx=TSyncItemType::newXMitListDevInf(fRxItemTypes,legacyTypeP ? legacyTypeP : fRxPrefItemTypeP); // - TxPref if (!fTxPrefItemTypeP) SYSYNC_THROW(TStructException("Datastore has no TxPref ItemType")); datastoreP->txpref = (legacyTypeP ? legacyTypeP : fTxPrefItemTypeP)->newXMitDevInf(); // - Tx (excluding the type we report as preferred) datastoreP->tx=TSyncItemType::newXMitListDevInf(fTxItemTypes,legacyTypeP ? legacyTypeP : fTxPrefItemTypeP); // - DSMem /// @todo %%% tbd: add dsmem datastoreP->dsmem=NULL; // - SyncML DS 1.2 datastore-local CTCap if (fSessionP->getSyncMLVersion()>=syncml_vers_1_2) { // CTCap is local to datastore, get only CTCaps relevant for this datastore, but independently from alerted state datastoreP->ctcap = fSessionP->newLocalCTCapList(false, this, aWithoutCTCapProps); } else datastoreP->ctcap=NULL; // before SyncML 1.2, there was no datastore-local CTCap // - SyncML DS 1.2 flags (SmlDevInfHierarchical_f) /// @todo %%% tbd: add SmlDevInfHierarchical_f datastoreP->flags=0; // - SyncML DS 1.2 filters datastoreP->filterrx=NULL; datastoreP->filtercap=NULL; #ifdef OBJECT_FILTERING if (IS_SERVER && fDSConfigP->fDS12FilterSupport && fSessionP->getSyncMLVersion()>=syncml_vers_1_2) { // Show Filter info in 1.2 devInf if this is not a client // - FilterRx constant datastoreP->filterrx = SML_NEW(SmlDevInfXmitList_t); datastoreP->filterrx->next = NULL; datastoreP->filterrx->data = SML_NEW(SmlDevInfXmit_t); datastoreP->filterrx->data->cttype=newPCDataString(SYNCML_FILTERTYPE_CGI); datastoreP->filterrx->data->verct=newPCDataString(SYNCML_FILTERTYPE_CGI_VERS); // build filtercap SmlPcdataListPtr_t filterkeywords = NULL; SmlPcdataListPtr_t filterprops = NULL; // - fill the lists from types addFilterCapPropsAndKeywords(filterkeywords,filterprops); // - if we have something, actually build a filtercap if (filterkeywords || filterprops) { // we have filtercaps, add them // - FilterCap list datastoreP->filtercap = SML_NEW(SmlDevInfFilterCapList_t); datastoreP->filtercap->next = NULL; datastoreP->filtercap->data = SML_NEW(SmlDevInfFilterCap_t); datastoreP->filtercap->data->cttype=newPCDataString(SYNCML_FILTERTYPE_CGI); datastoreP->filtercap->data->verct=newPCDataString(SYNCML_FILTERTYPE_CGI_VERS); // - add list we've got datastoreP->filtercap->data->filterkeyword=filterkeywords; datastoreP->filtercap->data->propname=filterprops; } } #endif // OBJECT_FILTERING // - Sync capabilities of this datastore datastoreP->synccap=newDevInfSyncCap(getSyncCapMask()); // return it return datastoreP; } // TLocalEngineDS::newDevInfDatastore // Set remote datastore for local void TLocalEngineDS::engSetRemoteDatastore( TRemoteDataStore *aRemoteDatastoreP // the remote datastore involved ) { // save link to remote datastore if (fRemoteDatastoreP) { if (fRemoteDatastoreP!=aRemoteDatastoreP) SYSYNC_THROW(TSyncException("Sync continues with different datastore")); } fRemoteDatastoreP=aRemoteDatastoreP; } // TLocalEngineDS::engSetRemoteDatastore // SYNC command bracket start (check credentials if needed) bool TLocalEngineDS::engProcessSyncCmd( SmlSyncPtr_t aSyncP, // the Sync element TStatusCommand &aStatusCommand, // status that might be modified bool &aQueueForLater // will be set if command must be queued for later (re-)execution ) { // get number of changes info if available if (aSyncP->noc) { StrToLong(smlPCDataToCharP(aSyncP->noc),fRemoteNumberOfChanges); } // check if datastore is aborted if (CheckAborted(aStatusCommand)) return false; // check if (!fRemoteDatastoreP) SYSYNC_THROW(TSyncException("No remote datastore linked")); // let remote datastore process it first if (!fRemoteDatastoreP->remoteProcessSyncCmd(aSyncP,aStatusCommand,aQueueForLater)) { PDEBUGPRINTFX(DBG_ERROR,("TLocalEngineDS::engProcessSyncCmd: remote datastore failed processing ")); changeState(dssta_idle,true); // force it return false; } // check for combined init&sync if (!testState(dssta_syncmodestable,false)) { // encountered before sync mode stable: could be combined init&sync session if (fLocalDSState>=dssta_serveransweredalert) { // ok for switching to combined init&sync PDEBUGPRINTFX(DBG_HOT,("TLocalEngineDS::engProcessSyncCmd: detected combined init&sync, freeze sync mode already now")); // - freeze sync mode as it is now changeState(dssta_syncmodestable,true); // force it, sync mode is now stable, no further changes are possible } } // now init if this is the first command bool startingNow = false; // assume start already initiated if (testState(dssta_syncmodestable,true)) { // all alert and alert status must be done by now, sync mode must be stable CONSOLEPRINTF(("- Starting Sync with Datastore '%s', %s sync",fRemoteViewOfLocalURI.c_str(),fSlowSync ? "slow" : "normal")); startingNow = true; // initiating start now #ifdef SYSYNC_SERVER if (IS_SERVER) { // at this point, all temporary GUIDs become invalid (no "early map" possible any more which might refer to last session's tempGUIDs) fTempGUIDMap.clear(); // forget all previous session's temp GUID mappings // let local datastore (derived DB-specific class) prepare for sync localstatus sta = changeState(dssta_dataaccessstarted); if (sta!=LOCERR_OK) { // abort session (old comment: %%% aborting datastore only does not work, will loop, why? %%%) aStatusCommand.setStatusCode(syncmlError(sta)); PDEBUGPRINTFX(DBG_ERROR,("TLocalEngineDS::engProcessSyncCmd: could not change state to dsssta_dataaccessstarted -> abort")); engAbortDataStoreSync(sta,true); // local problem return false; } } #endif } // if data access started (finished or not), check start status // for every execution and re-execution of the sync command if (testState(dssta_dataaccessstarted)) { // queue command if datastore is not yet started already if (engIsStarted(!startingNow)) { // wait only if start was already initiated // - is now initialized if (IS_SERVER) { // - for server, make the sync set ready now (as engine is now started) changeState(dssta_syncsetready,true); // force it } else { // - for client, we need at least dssta_syncgendone (sync set has been ready long ago, we've already sent changes to server!) if (!testState(dssta_syncgendone)) { // bad sequence of commands ( from server too early!) aStatusCommand.setStatusCode(400); PDEBUGPRINTFX(DBG_ERROR,("TLocalEngineDS::engProcessSyncCmd: client received SYNC before sending SYNC complete")); engAbortDataStoreSync(400,false,false); // remote problem, not resumable return false; } } PDEBUGPRINTFX(DBG_HOT,( "- Started %s Sync (first command)", fSlowSync ? "slow" : "normal" )); if (fRemoteNumberOfChanges>=0) PDEBUGPRINTFX(DBG_HOT,("- NumberOfChanges announced by remote = %ld",(long)fRemoteNumberOfChanges)); DB_PROGRESS_EVENT(this,pev_syncstart,0,0,0); } else { // - not yet started PDEBUGPRINTFX(DBG_HOT,( "- Starting sync not yet complete - re-execute command again in next message" )); aQueueForLater=true; return true; // ok so far } } // must be syncready here (otherwise we return before we reach this) if (!testState(dssta_syncsetready)) { aStatusCommand.setStatusCode(403); // forbidden ADDDEBUGITEM(aStatusCommand,"SYNC received too early"); PDEBUGPRINTFX(DBG_ERROR,("TLocalEngineDS::engProcessSyncCmd: SYNC received too early")); engAbortDataStoreSync(403,false,false); // remote problem, not resumable return false; } // state is now syncing /// @deprecated - dssta_syncsetready is enough //fState=dss_syncing; return true; } // TLocalEngineDS::engProcessSyncCmd // SYNC command bracket end (but another might follow in next message) bool TLocalEngineDS::engProcessSyncCmdEnd(bool &aQueueForLater) { bool ok=true; // queue it for later as long as datastore is not ready now if (!engIsStarted(false)) { // not waiting if not started // no state change, just postpone execution aQueueForLater=true; } // also inform remote if (fRemoteDatastoreP) ok=fRemoteDatastoreP->remoteProcessSyncCmdEnd(); return ok; } // TLocalEngineDS::engProcessSyncCmdEnd #ifdef SYSYNC_SERVER // server case: called whenever outgoing Message of Sync Package starts void TLocalEngineDS::engServerStartOfSyncMessage(void) { // this is where we might start our own command (all // received commands are now processed) // - Note that this might be a subdatastore -> if so, do NOT // start a sync (superdatastore will handle this) // - Note that this will be called even if current message is // already full, so it could well be that this sync command // is queued. if (!fSessionP->fCompleteFromClientOnly && testState(dssta_serverseenclientmods) && getSyncMode()==smo_fromclient) { // from-client only does not send back a command, simply end data access here PDEBUGPRINTFX(DBG_PROTO,("from-client-only:do not send command back to client, data access ends here")); changeState(dssta_syncgendone,true); changeState(dssta_dataaccessdone,true); } // ### SyncFest #5, found with Tactel Jazz Client: // - do not send anything when remote datastore is not known else if (fRemoteDatastoreP) { if (!testState(dssta_serversyncgenstarted) && testState(dssta_serverseenclientmods)) { changeState(dssta_serversyncgenstarted,true); if (!isSubDatastore()) { // - Note: if sync command was already started, the // finished(), continueIssue() mechanism will make sure that // more commands are generated // - Note2: if all sync commands can be sent at once, // fState will be modified by issuing , so // it must be ok for issuing syncops here already! TSyncCommand *synccmdP = new TSyncCommand( fSessionP, this, // local datastore fRemoteDatastoreP // remote datastore ); // issue ISSUE_COMMAND_ROOT(fSessionP,synccmdP); } } } else { changeState(dssta_idle,true); // force it } } // TLocalEngineDS::engServerStartOfSyncMessage #endif // server only // called whenever Message of Sync Package ends or after last queued Sync command is executed // - aEndOfAllSyncCommands is true when at end of Sync-data-from-remote packet // AND all possibly queued sync/syncop commands have been processed. void TLocalEngineDS::engEndOfSyncFromRemote(bool aEndOfAllSyncCommands) { // is called for all local datastores, including superdatastore, even inactive ones, so check state first if (testState(dssta_syncsetready)) { if (aEndOfAllSyncCommands) { // we are at end of sync-data-from-remote for THIS datastore if (IS_CLIENT) { // - we are done with from server, that is, data access is done now changeState(dssta_dataaccessdone,true); // force it } else { // - server has seen all client modifications now // Note: in case of the simulated-empty-sync-hack in action, we // allow that we are already in server_sync_gen_started and // won't try to force down to dssta_serverseenclientmods if (!fSessionP->fFakeFinalFlag || getDSState() active - allowing state>server_seen_client_mods")); } } } #ifdef SYSYNC_SERVER if (IS_SERVER) { engServerStartOfSyncMessage(); } #endif // now do final things if (testState(dssta_dataaccessdone,true)) { // @todo: I think, as long as we need to send maps, we're not done yet!!! // sync packets in both directions done, forget remote datastore fRemoteDatastoreP=NULL; } } // dssta_syncsetready } // TLocalEngineDS::engEndOfSyncFromRemote // - must return true if this datastore is finished with // (if all datastores return true, // session is allowed to finish sync packet with outgoing message bool TLocalEngineDS::isSyncDone(void) { // is called for all local datastores, even inactive ones, which must signal sync done, too // - only datastores currently receiving or sending commands are not done with sync // - aborted datastores are also done with sync, no matter what status they have return ( fAbortStatusCode!=0 || //(fState!=dss_syncsend && fState!=dss_syncing && fState!=dss_syncready && fState!=dss_syncfinish) !testState(dssta_clientsentalert) || // nothing really happened yet... testState(dssta_syncgendone) // ...or already completed generating ); } // TLocalEngineDS::isSyncDone // test datastore state for minimal or exact state bool TLocalEngineDS::testState(TLocalEngineDSState aMinState, bool aNeedExactMatch) { bool result = (!aNeedExactMatch || (fLocalDSState==aMinState)) && (fLocalDSState>=aMinState); DEBUGPRINTFX(DBG_EXOTIC,( "%s: testState=%s - expected state%c='%s', found state=='%s'", getName(), result ? "TRUE" : "FALSE", aNeedExactMatch ? '=' : '>', getDSStateName(aMinState), getDSStateName() )); return result; } // TLocalEngineDS::testState // change datastore state, calls logic layer before and after change localstatus TLocalEngineDS::changeState(TLocalEngineDSState aNewState, bool aForceOnError) { localstatus err1,err2; TLocalEngineDSState oldState = fLocalDSState; // nop if no change in state if (aNewState==oldState) return LOCERR_OK; // state cannot be decremented except down to adminready and below if ((aNewStatedssta_adminready)) { PDEBUGPRINTFX(DBG_ERROR,( "%s: Internal error: attempt to reduce state from '%s' to '%s' - aborting", getName(), getDSStateName(oldState), getDSStateName(aNewState) )); err1 = 500; dsAbortDatastoreSync(err1,true); return err1; } // give logic opportunity to react before state changes PDEBUGBLOCKFMT(( "DSStateChange", "Datastore changes state", "datastore=%s|oldstate=%s|newstate=%s", getName(), getDSStateName(oldState), getDSStateName(aNewState) )); err2 = LOCERR_OK; err1 = dsBeforeStateChange(oldState,aNewState); if (!aForceOnError && err1) goto endchange; // switch state fLocalDSState = aNewState; if (aNewState == dssta_syncmodestable) { // There are multiple places where the sync mode is frozen. Ensure // that this change is reported in all of them by putting the code // here. PDEBUGPRINTFX(DBG_HOT,( "executing %s%s%s Sync%s", fResuming ? "resumed " : "", fSlowSync ? "slow" : "normal", fFirstTimeSync ? " first time" : "", fSyncMode == smo_twoway ? ", two-way" : fSyncMode == smo_fromclient ? " from client" : fSyncMode == smo_fromserver ? " from server" : " in unknown direction?!" )); #ifdef PROGRESS_EVENTS // progress event DB_PROGRESS_EVENT(this, pev_alerted, fSlowSync ? (fFirstTimeSync ? 2 : 1) : 0, fResuming ? 1 : 0, fSyncMode ); #endif // PROGRESS_EVENTS } // now give logic opportunity to react again err2 = dsAfterStateChange(oldState,aNewState); endchange: PDEBUGENDBLOCK("DSStateChange"); // return most recent error return err2 ? err2 : err1; } // TLocalEngineDS::changeState // test datastore abort status // datastore is aborted when // - it was explicitly aborted (engAbortDataStoreSync() called, fAbortStatusCode set) // - session is suspending and the datastore has not yet completed sync up to sending // maps (client) or admin already saved (server+client). // If client has sent maps, all that MIGHT be missing would be map status, and // if that hasn't arrived, the pendingMaps mechanism will make sure these get // sent in the next session. bool TLocalEngineDS::isAborted(void) { return fAbortStatusCode!=0 || (fSessionP->isSuspending() && !testState(dssta_clientmapssent)); } // TLocalEngineDS::isAborted // abort sync with this datastore void TLocalEngineDS::engAbortDataStoreSync(TSyError aStatusCode, bool aLocalProblem, bool aResumable) { if (fLocalDSState!=dssta_idle && !fAbortStatusCode) { // prepare status fAbortStatusCode = aStatusCode ? aStatusCode : 514; // make sure we have a non-zero fAbortStatusCode fLocalAbortCause = aLocalProblem; if (!aResumable) preventResuming(); // prevent resuming PDEBUGBLOCKFMT(( "DSAbort","Aborting datastore sync","abortStatusCode=%hd|localProblem=%s|resumable=%s", aStatusCode, aLocalProblem ? "yes" : "no", aResumable ? "yes" : "no" )); // tell that to the session fSessionP->DatastoreFailed(aStatusCode,aLocalProblem); // as soon as sync set is ready, we have potentially started the sync and resume makes sense // NOTE: before we have made the sync set ready, WE MUST NOT resume, because making the sync // set ready includes zapping it on slow refreshes, and this is only done when not resuming // (so saving a suspend state before dssta_syncsetready would cause that the zapping is // possibly skipped) if (!testState(dssta_syncsetready)) preventResuming(); // prevent resuming before sync set is ready // save resume (or non-resumable!) status only if this is NOT A TIMEOUT, because if it is a // (server) timeout, suspend state was saved at end of last request, and writing again here would destroy // the state. if (aStatusCode!=408) { engSaveSuspendState(true); // save even if already aborted } // let derivates know dsAbortDatastoreSync(aStatusCode, aLocalProblem); // show abort PDEBUGPRINTFX(DBG_ERROR,( "*************** Warning: Datastore flagged aborted (after %ld sec. request processing, %ld sec. total) with %s Status %hd", (long)((getSession()->getSystemNowAs(TCTX_UTC)-fSessionP->getLastRequestStarted()) / secondToLinearTimeFactor), (long)((getSession()->getSystemNowAs(TCTX_UTC)-fSessionP->getSessionStarted()) / secondToLinearTimeFactor), aLocalProblem ? "LOCAL" : "REMOTE", aStatusCode )); DB_PROGRESS_EVENT( this, pev_syncend, getAbortStatusCode(), fSlowSync ? (fFirstTimeSync ? 2 : 1) : 0, fResuming ? 1 : 0 ); PDEBUGENDBLOCK("DSAbort"); } } // TLocalEngineDS::engAbortDataStoreSync // check if aborted, set status to abort reason code if yes bool TLocalEngineDS::CheckAborted(TStatusCommand &aStatusCommand) { if (fAbortStatusCode!=0) { aStatusCommand.setStatusCode( fSessionP->getSyncMLVersion()>=syncml_vers_1_1 ? 514 : // cancelled (fAbortStatusCodegetSessionStarted()); StringSubst(aLog,"%ssT",s,4); } // %sdT sync duration (in seconds) for this datastore (start of session until datastore finished) StringSubst(aLog,"%sdT",((sInt32)(fEndOfSyncTime-fSessionP->getSessionStarted())/secondToLinearTimeFactor),4); // %nD Datastore name StringSubst(aLog,"%nD",getName(),3); // %rD Datastore remote path StringSubst(aLog,"%rD",fRemoteDBPath,3); // %lD Datastore local path (complete with all CGI) StringSubst(aLog,"%lD",fRemoteViewOfLocalURI,3); // %iR Remote Device ID (URI) StringSubst(aLog,"%iR",fSessionP->getRemoteURI(),3); // %nR Remote name: [Manufacturer ]Model") StringSubst(aLog,"%nR",fSessionP->getRemoteDescName(),3); // %vR Remote Device Version Info ("Type (HWV, FWV, SWV) Oem") StringSubst(aLog,"%vR",fSessionP->getRemoteInfoString(),3); // %U User Name StringSubst(aLog,"%U",fSessionP->getSyncUserName(),2); // %iS local Session ID StringSubst(aLog,"%iS",fSessionP->getLocalSessionID(),3); // %sS Status code (0 if successful) StringSubst(aLog,"%sS",fAbortStatusCode,3); // %ssS Session Status code (0 if successful) StringSubst(aLog,"%ssS",fSessionP->getAbortReasonStatus(),4); // %syV SyncML version (as text) of session StringSubst(aLog,"%syV",SyncMLVerDTDNames[fSessionP->getSyncMLVersion()],4); // %syV SyncML version numeric (0=unknown, 1=1.0, 2=1.1, 3=1.2) of session StringSubst(aLog,"%syVn",(long)fSessionP->getSyncMLVersion(),5); // %mS Syncmode (0=twoway, 1=fromclient 2=fromserver) StringSubst(aLog,"%mS",(sInt32)fSyncMode,3); // %tS Synctype (0=normal,1=slow,2=firsttime slow, +10 if resumed session) StringSubst(aLog,"%tS",(fSlowSync ? (fFirstTimeSync ? 2 : 1) : 0) + (isResuming() ? 10 : 0),3); // %laI locally added Items StringSubst(aLog,"%laI",fLocalItemsAdded,4); // %raI remotely added Items StringSubst(aLog,"%raI",fRemoteItemsAdded,4); // %ldI locally deleted Items StringSubst(aLog,"%ldI",fLocalItemsDeleted,4); // %rdI remotely deleted Items StringSubst(aLog,"%rdI",fRemoteItemsDeleted,4); // %luI locally updated Items StringSubst(aLog,"%luI",fLocalItemsUpdated,4); // %ruI remotely updated Items StringSubst(aLog,"%ruI",fRemoteItemsUpdated,4); // %reI locally not accepted Items (sent error to remote, remote MAY resend them or abort the session) StringSubst(aLog,"%leI",fLocalItemsError,4); // %leI remotely not accepted Items (got error from remote, local will resend them later) StringSubst(aLog,"%reI",fRemoteItemsError,4); #ifdef SYSYNC_SERVER if (IS_SERVER) { // %smI Slowsync matched Items StringSubst(aLog,"%smI",fSlowSyncMatches,4); // %scI Server won Conflicts StringSubst(aLog,"%scI",fConflictsServerWins,4); // %ccI Client won Conflicts StringSubst(aLog,"%ccI",fConflictsClientWins,4); // %dcI Conflicts with duplications StringSubst(aLog,"%dcI",fConflictsDuplicated,4); // %tiB total incoming bytes StringSubst(aLog,"%tiB",fSessionP->getIncomingBytes(),4); // %toB total outgoing bytes StringSubst(aLog,"%toB",fSessionP->getOutgoingBytes(),4); } #endif // %niB net incoming data bytes for this datastore StringSubst(aLog,"%diB",fIncomingDataBytes,4); // %noB net incoming data bytes for this datastore StringSubst(aLog,"%doB",fOutgoingDataBytes,4); #endif } // TLocalEngineDS::DoLogSubstitutions // log datastore sync result // - Called at end of sync with this datastore void TLocalEngineDS::dsLogSyncResult(void) { #ifndef MINIMAL_CODE if (fSessionP->logEnabled()) { string logtext; logtext=fSessionP->getSessionConfig()->fLogFileFormat; if (!logtext.empty()) { // substitute DoLogSubstitutions(logtext,true); // plaintext // show fSessionP->WriteLogLine(logtext.c_str()); } } #endif } // TLocalEngineDS::dsLogSyncResult // Terminate all activity with this datastore // Note: may be called repeatedly, must only execute relevant shutdown code once void TLocalEngineDS::engTerminateDatastore(localstatus aAbortStatusCode) { // now abort (if not already aborted), then finish activities engFinishDataStoreSync(aAbortStatusCode); // and finally reset completely engResetDataStore(); } // TLocalEngineDS::TerminateDatastore // called at very end of sync session, when everything is done // Note: is also called before deleting a datastore (so aborted sessions // can do cleanup and/or statistics display as well) void TLocalEngineDS::engFinishDataStoreSync(localstatus aErrorStatus) { // set end of sync time fEndOfSyncTime = getSession()->getSystemNowAs(TCTX_UTC); // check if we have something to do at all if (fLocalDSState!=dssta_idle && fLocalDSState!=dssta_completed) { if (aErrorStatus==LOCERR_OK) { // Check if we need to abort now due to failed items only if (fRemoteItemsError>0) { // remote reported errors if (fSlowSync && fRemoteItemsAdded==0 && fRemoteItemsDeleted==0 && fRemoteItemsUpdated==0 && fSessionP->getSessionConfig()->fAbortOnAllItemsFailed) { PDEBUGPRINTFX(DBG_ERROR+DBG_DETAILS,("All remote item operations failed -> abort sync")); engAbortDataStoreSync(512,false,false); // remote problems (only failed items in a slow sync) caused sync to fail, not resumable } else fSessionP->DatastoreHadErrors(); // at least SOME items were successful, so it's not a completely unsuccessful sync } } // abort, if requested from caller or only-failed-items if (aErrorStatus!=LOCERR_OK) engAbortDataStoreSync(aErrorStatus,true); // if we have an error here, this is considered a local problem else { DB_PROGRESS_EVENT( this, pev_syncend, fAbortStatusCode, fSlowSync ? (fFirstTimeSync ? 2 : 1) : 0, fResuming ? 1 : 0 ); } #ifdef SUPERDATASTORES // if this is part of a superdatastore, include its statistics into mine, as // superdatastore can not save any statistics. // This ensures that the result sum over all subdatastores is correct, // however the assignment of error and byte counts is not (all non-related // counts go to first subdatastores with the following code) if (fAsSubDatastoreOf) { fOutgoingDataBytes += fAsSubDatastoreOf->fOutgoingDataBytes; fIncomingDataBytes += fAsSubDatastoreOf->fIncomingDataBytes; fRemoteItemsError += fAsSubDatastoreOf->fRemoteItemsError; fLocalItemsError += fAsSubDatastoreOf->fLocalItemsError; // consumed now, clear in superdatastore fAsSubDatastoreOf->fOutgoingDataBytes=0; fAsSubDatastoreOf->fIncomingDataBytes=0; fAsSubDatastoreOf->fRemoteItemsError=0; fAsSubDatastoreOf->fLocalItemsError=0; } #endif // make log entry dsLogSyncResult(); // update my session state vars for successful sessions if (aErrorStatus==LOCERR_OK) { // update anchor fLastRemoteAnchor=fNextRemoteAnchor; fLastLocalAnchor=fNextLocalAnchor; // note: when using TStdLogicDS, this is not saved, but re-generated at next sync from timestamp // no resume fResumeAlertCode=0; // no resume item (just to make sure we don't get strange effects later) fLastItemStatus = 0; fLastSourceURI.erase(); fLastTargetURI.erase(); fPartialItemState = pi_state_none; fPIStoredSize = 0; } // now shift state to complete, let logic and implementation save the state changeState(dssta_completed,true); #ifdef SCRIPT_SUPPORT // - call DB finish script TScriptContext::execute( fDataStoreScriptContextP, fDSConfigP->fDBFinishScript, &DBFuncTable, // context's function table this // datastore pointer needed for context ); #endif } // in any case: idle now again (note: could be shift from dssta_completed to dssta_idle) changeState(dssta_idle,true); } // TLocalEngineDS::engFinishDataStoreSync /// inform everyone of coming state change localstatus TLocalEngineDS::dsBeforeStateChange(TLocalEngineDSState aOldState,TLocalEngineDSState aNewState) { localstatus sta = LOCERR_OK; return sta; } // TLocalEngineDS::dsBeforeStateChange /// inform everyone of happened state change localstatus TLocalEngineDS::dsAfterStateChange(TLocalEngineDSState aOldState,TLocalEngineDSState aNewState) { localstatus sta = LOCERR_OK; if (aOldState>dssta_idle && aNewState==dssta_completed) { // we are going from a non-idle state to completed // - show statistics showStatistics(); } return sta; } // TLocalEngineDS::dsAfterStateChange // show statistics or error of current sync void TLocalEngineDS::showStatistics(void) { // Console CONSOLEPRINTF(("")); CONSOLEPRINTF(("- Sync Statistics for '%s' (%s), %s sync", getName(), fRemoteViewOfLocalURI.c_str(), fSlowSync ? "slow" : "normal" )); // now show results if (isAborted()) { // failed CONSOLEPRINTF((" ************ Failed with status code=%hd",fAbortStatusCode)); } else { // successful: show statistics on console CONSOLEPRINTF((" ==================================================")); if (IS_SERVER) { CONSOLEPRINTF((" on Server on Client")); } else { CONSOLEPRINTF((" on Client on Server")); } CONSOLEPRINTF((" Added: %9ld %9ld",(long)fLocalItemsAdded,(long)fRemoteItemsAdded)); CONSOLEPRINTF((" Deleted: %9ld %9ld",(long)fLocalItemsDeleted,(long)fRemoteItemsDeleted)); CONSOLEPRINTF((" Updated: %9ld %9ld",(long)fLocalItemsUpdated,(long)fRemoteItemsUpdated)); CONSOLEPRINTF((" Rejected with error: %9ld %9ld",(long)fLocalItemsError,(long)fRemoteItemsError)); #ifdef SYSYNC_SERVER if (IS_SERVER) { CONSOLEPRINTF((" SlowSync Matches: %9ld",(long)fSlowSyncMatches)); CONSOLEPRINTF((" Server won Conflicts: %9ld",(long)fConflictsServerWins)); CONSOLEPRINTF((" Client won Conflicts: %9ld",(long)fConflictsClientWins)); CONSOLEPRINTF((" Conflicts with Duplication: %9ld",(long)fConflictsDuplicated)); } #endif } CONSOLEPRINTF(("")); // Always provide statistics as events DB_PROGRESS_EVENT(this,pev_dsstats_l,fLocalItemsAdded,fLocalItemsUpdated,fLocalItemsDeleted); DB_PROGRESS_EVENT(this,pev_dsstats_r,fRemoteItemsAdded,fRemoteItemsUpdated,fRemoteItemsDeleted); DB_PROGRESS_EVENT(this,pev_dsstats_e,fLocalItemsError,fRemoteItemsError,0); #ifdef SYSYNC_SERVER if (IS_SERVER) { DB_PROGRESS_EVENT(this,pev_dsstats_s,fSlowSyncMatches,0,0); DB_PROGRESS_EVENT(this,pev_dsstats_c,fConflictsServerWins,fConflictsClientWins,fConflictsDuplicated); } #endif // NOTE: pev_dsstats_d should remain the last log data event sent (as it terminates collecting data in some GUIs) DB_PROGRESS_EVENT(this,pev_dsstats_d,fOutgoingDataBytes,fIncomingDataBytes,fRemoteItemsError); // Always show statistics in debug log #ifdef SYDEBUG PDEBUGPRINTFX(DBG_HOT,("Sync Statistics for '%s' (%s), %s sync", getName(), fRemoteViewOfLocalURI.c_str(), fSlowSync ? "slow" : "normal" )); if (PDEBUGTEST(DBG_HOT)) { string stats = "==================================================\n"; if (IS_SERVER) { stats += " on Server on Client\n"; } else { stats += " on Client on Server\n"; } StringObjAppendPrintf(stats,"Added: %9ld %9ld\n",(long)fLocalItemsAdded,(long)fRemoteItemsAdded); StringObjAppendPrintf(stats,"Deleted: %9ld %9ld\n",(long)fLocalItemsDeleted,(long)fRemoteItemsDeleted); StringObjAppendPrintf(stats,"Updated: %9ld %9ld\n",(long)fLocalItemsUpdated,(long)fRemoteItemsUpdated); StringObjAppendPrintf(stats,"Rejected with error: %9ld %9ld\n\n",(long)fLocalItemsError,(long)fRemoteItemsError); #ifdef SYSYNC_SERVER if (IS_SERVER) { StringObjAppendPrintf(stats,"SlowSync Matches: %9ld\n",(long)fSlowSyncMatches); StringObjAppendPrintf(stats,"Server won Conflicts: %9ld\n",(long)fConflictsServerWins); StringObjAppendPrintf(stats,"Client won Conflicts: %9ld\n",(long)fConflictsClientWins); StringObjAppendPrintf(stats,"Conflicts with Duplication: %9ld\n\n",(long)fConflictsDuplicated); } #endif StringObjAppendPrintf(stats,"Content Data Bytes sent: %9ld\n",(long)fOutgoingDataBytes); StringObjAppendPrintf(stats,"Content Data Bytes received: %9ld\n\n",(long)fIncomingDataBytes); StringObjAppendPrintf(stats,"Duration of sync [seconds]: %9ld\n",(long)((fEndOfSyncTime-fSessionP->getSessionStarted())/secondToLinearTimeFactor)); PDEBUGPUTSXX(DBG_HOT,stats.c_str(),0,true); } if (isAborted()) { // failed PDEBUGPRINTFX(DBG_ERROR,("Warning: Failed with status code=%hd, statistics are incomplete!!",fAbortStatusCode)); } #endif } // TLocalEngineDS::showStatistics // create a new syncop command for sending to remote TSyncOpCommand *TLocalEngineDS::newSyncOpCommand( TSyncItem *aSyncItemP, // the sync item TSyncItemType *aSyncItemTypeP, // the sync item type cAppCharP aLocalIDPrefix ) { // get operation TSyncOperation syncop=aSyncItemP->getSyncOp(); // obtain meta SmlPcdataPtr_t metaP = newMetaType(aSyncItemTypeP->getTypeName()); // create command TSyncOpCommand *syncopcmdP = new TSyncOpCommand(fSessionP,this,syncop,metaP); // make sure item does not have stuff it is not allowed to have // %%% SCTS does not like SourceURI in Replace and Delete commands sent to Client // there are the only ones allowed to carry a GUID if (IS_SERVER) { #ifdef SYSYNC_SERVER // Server: commands only have remote IDs, except add which only has target ID if (syncop==sop_add || syncop==sop_wants_add) aSyncItemP->clearRemoteID(); // no remote ID else { if (!fDSConfigP->fAlwaysSendLocalID && aSyncItemP->hasRemoteID()) { // only if localID may not be included in all syncops, // and not if the item has no remote ID yet // // The second case had to be added to solve an issue // during suspended syncs: // - server tries to add a new item and uses the Replace op for it // - pending Replace is added to map // - next sync resends the Replace, but with empty IDs and thus // cannot be processed by client // // Log from such a failed sync: // Item localID='328' already has map entry: remoteid='', mapflags=0x1, changed=0, deleted=0, added=0, markforresume=0, savedmark=1 // Resuming and found marked-for-resume -> send replace // ... // Command 'Replace': is 1-th counted cmd, cmdsize(+tags needed to end msg)=371, available=130664 (maxfree=299132, freeaftersend=298761, notUsableBufferBytes()=168468) // Item remoteID='', localID='', datasize=334 // Replace: issued as (outgoing MsgID=2, CmdID=4), now queueing for status // ... // Status 404: Replace target not found on client -> silently ignore but remove map in server (item will be added in next session), aSyncItemP->clearLocalID(); // no local ID } } #endif } else { // Client: all commands only have local IDs aSyncItemP->clearRemoteID(); // no remote ID } // add the localID prefix if we do have a localID to send if (aSyncItemP->hasLocalID()) { if (IS_SERVER) { #ifdef SYSYNC_SERVER // make sure GUID (plus prefixes) is not exceeding allowed size adjustLocalIDforSize(aSyncItemP->fLocalID,getRemoteDatastore()->getMaxGUIDSize(),aLocalIDPrefix ? strlen(aLocalIDPrefix) : 0); #endif } // add local ID prefix, if any if (aLocalIDPrefix && *aLocalIDPrefix) aSyncItemP->fLocalID.insert(0,aLocalIDPrefix); } #ifdef SYSYNC_TARGET_OPTIONS // init item generation variables fItemSizeLimit=fSizeLimit; #else fItemSizeLimit=-1; // no limit #endif // now add item SmlItemPtr_t itemP = aSyncItemTypeP->newSmlItem(aSyncItemP,this); // check if data size is ok if (itemP && fSessionP->fMaxOutgoingObjSize) { if (itemP->data && itemP->data->content && itemP->data->length) { // there is data, check if size is ok if (itemP->data->length > fSessionP->fMaxOutgoingObjSize) { // too large, suppress it PDEBUGPRINTFX(DBG_ERROR,( "WARNING: outgoing item is larger (%ld) than MaxObjSize (%ld) of remote -> suppress now/mark for resend", (long)itemP->data->length, (long)fSessionP->fMaxOutgoingObjSize )); smlFreeItemPtr(itemP); itemP=NULL; // mark item for resend // For datastores without resume support, this will just have no effect at all engMarkItemForResend(aSyncItemP->getLocalID(),aSyncItemP->getRemoteID()); } } } if (itemP) { // add it to the command syncopcmdP->addItem(itemP); } else { // no item - command is invalid, delete it delete syncopcmdP; syncopcmdP=NULL; } // return command return syncopcmdP; } // TLocalEngineDS::newSyncOpCommand // create SyncItem suitable for being sent from local to remote TSyncItem *TLocalEngineDS::newItemForRemote( uInt16 aExpectedTypeID // typeid of expected type ) { // safety if (!canCreateItemForRemote()) SYSYNC_THROW(TSyncException("newItemForRemote called without sufficient type information ready")); // create TSyncItem *itemP = fLocalSendToRemoteTypeP->newSyncItem(fRemoteReceiveFromLocalTypeP,this); if (!itemP) SYSYNC_THROW(TSyncException("newItemForRemote could not create item")); // check type if (!itemP->isBasedOn(aExpectedTypeID)) { PDEBUGPRINTFX(DBG_ERROR,( "newItemForRemote created item of typeID %hd, caller expects %hd", itemP->getTypeID(), aExpectedTypeID )); SYSYNC_THROW(TSyncException("newItemForRemote created wrong item type")); } return itemP; } // TLocalEngineDS::newItemForRemote // return pure relative (item) URI (removes absolute part or ./ prefix) const char *TLocalEngineDS::DatastoreRelativeURI(const char *aURI) { return relativeURI(relativeURI(aURI,fSessionP->getLocalURI()),getName()); } // TLocalEngineDS::DatastoreRelativeURI // - init filtering and check if needed (sets fTypeFilteringNeeded, fFilteringNeeded and fFilteringNeededForAll) void TLocalEngineDS::initPostFetchFiltering(void) { #ifdef OBJECT_FILTERING if (!fLocalSendToRemoteTypeP) { fTypeFilteringNeeded=false; fFilteringNeeded=false; fFilteringNeededForAll=false; } else { // get basic settings from type fLocalSendToRemoteTypeP->initPostFetchFiltering(fTypeFilteringNeeded,fFilteringNeededForAll,this); fFilteringNeeded=fTypeFilteringNeeded; // NOTE: if type filtering is needed, it's the responsibility of initPostFetchFiltering() of // the type to check (using the DBHANDLESOPTS() script func) if DB does already handle // the range filters and such and possibly avoid type filtering then. // then check for standard filter requirements #ifdef SYDEBUG #ifdef SYNCML_TAF_SUPPORT if (!fTargetAddressFilter.empty()) PDEBUGPRINTFX(DBG_DATA,("using (dynamic, temporary) TAF expression from CGI : %s",fTargetAddressFilter.c_str())); if (!fIntTargetAddressFilter.empty()) PDEBUGPRINTFX(DBG_DATA,("using (dynamic, temporary) internally set TAF expression : %s",fIntTargetAddressFilter.c_str())); #endif // SYNCML_TAF_SUPPORT if (!fSyncSetFilter.empty()) PDEBUGPRINTFX(DBG_DATA,("using (dynamic) sync set filter expression : %s",fSyncSetFilter.c_str())); if (!fLocalDBFilter.empty()) PDEBUGPRINTFX(DBG_DATA,("using (static) local db filter expression : %s",fLocalDBFilter.c_str())); #endif // SYDEBUG // - if DB does the standard filters, we don't need to check them here again if (!engFilteredFetchesFromDB(true)) { // If DB does NOT do the standard filters, we have to do them here // - this is the case if we have an (old-style) sync set filter, but not filtered by DB // we need to filter all because sync set filter can be dynamic if (!fSyncSetFilter.empty()) fFilteringNeededForAll=true; // always return true if there is something to filter at all if ( !fLocalDBFilter.empty() || !fDSConfigP->fInvisibleFilter.empty() || !fSyncSetFilter.empty() || !fDSConfigP->fRemoteAcceptFilter.empty() ) fFilteringNeeded=true; } } PDEBUGPRINTFX(DBG_FILTER+DBG_HOT,( "Datastore-level postfetch filtering %sneeded%s", fFilteringNeeded ? "" : "NOT ", fFilteringNeeded ? (fFilteringNeededForAll ? " and to be applied to all records" : " only for changed records") : "" )); #endif } // TLocalEngineDS::initPostFetchFiltering // filter fetched record bool TLocalEngineDS::postFetchFiltering(TSyncItem *aSyncItemP) { #ifndef OBJECT_FILTERING return true; // no filters, always pass #else if (!aSyncItemP) return false; // null item does not pass // first do standard filters // - if DB has filtered the bool passes=true; if (fFilteringNeeded) { // - first make sure outgoing object has all properties set // such that it would pass the acceptance filter (for example KIND for calendar...) if (!aSyncItemP->makePassFilter(fDSConfigP->fRemoteAcceptFilter.c_str())) { // we could not make item pass acceptance filters PDEBUGPRINTFX(DBG_ERROR,("- item localid='%s' cannot be made passing -> ignored",aSyncItemP->getLocalID())); passes=false; } // now check for field-level filters if (passes && !engFilteredFetchesFromDB()) { // DB has not already filtered these, so we need to do it here // - "moving target" first passes=fSyncSetFilter.empty() || aSyncItemP->testFilter(fSyncSetFilter.c_str()); if (passes) { // - static filters passes = aSyncItemP->testFilter(fLocalDBFilter.c_str()) && // local filter ( fDSConfigP->fInvisibleFilter.empty() || // and either no invisibility defined... !aSyncItemP->testFilter(fDSConfigP->fInvisibleFilter.c_str()) // ...or NOT passed ); } } if (passes && fTypeFilteringNeeded) { // finally, apply type's filter passes=aSyncItemP->postFetchFiltering(this); } } else { // no filtering needed, DB has already filtered out those that would not pass // BUT: make sure outgoing items WILL pass the acceptance filter. If this // cannot be done, item will be filtered out. if (!aSyncItemP->makePassFilter(fDSConfigP->fRemoteAcceptFilter.c_str())) { // we could not make item pass acceptance filters PDEBUGPRINTFX(DBG_ERROR,("- item localid='%s' cannot be made passing -> ignored",aSyncItemP->getLocalID())); passes=false; } } #ifdef SYDEBUG if (!passes) { PDEBUGPRINTFX(DBG_DATA,("- item localid='%s' does not pass filters -> ignored",aSyncItemP->getLocalID())); } #endif // return result return passes; #endif } // TLocalEngineDS::postFetchFiltering #ifdef OBJECT_FILTERING // - called to check if incoming item passes acception filters bool TLocalEngineDS::isAcceptable(TSyncItem *aSyncItemP, TStatusCommand &aStatusCommand) { // test acceptance if (aSyncItemP->testFilter(fDSConfigP->fRemoteAcceptFilter.c_str())) return true; // ok // not accepted, set 415 error if (!fDSConfigP->fSilentlyDiscardUnaccepted) aStatusCommand.setStatusCode(415); ADDDEBUGITEM(aStatusCommand,"Received item does not pass acceptance filter"); PDEBUGPRINTFX(DBG_ERROR,( "Received item does not pass acceptance filter: %s", fDSConfigP->fRemoteAcceptFilter.c_str() )); return false; } // TLocalEngineDS::isAcceptable /// @brief called to make incoming item visible /// @return true if now visible bool TLocalEngineDS::makeVisible(TSyncItem *aSyncItemP) { bool invisible=false; if (!fDSConfigP->fInvisibleFilter.empty()) { invisible=aSyncItemP->testFilter(fDSConfigP->fInvisibleFilter.c_str()); } if (invisible) { return aSyncItemP->makePassFilter(fDSConfigP->fMakeVisibleFilter.c_str()); } return true; // is already visible } // TLocalEngineDS::makeVisible /// @brief called to make incoming item INvisible /// @return true if now INvisible bool TLocalEngineDS::makeInvisible(TSyncItem *aSyncItemP) { // return true if could make invisible or already was invisible if (fDSConfigP->fInvisibleFilter.empty()) return false; // no invisible filter, cannot make invisible // make pass invisible filter - if successful, we're now invisible return aSyncItemP->makePassFilter(fDSConfigP->fInvisibleFilter.c_str()); // try to make invisible (and return result) } // TLocalEngineDS::makeInvisible // - called to make incoming item pass sync set filtering bool TLocalEngineDS::makePassSyncSetFilter(TSyncItem *aSyncItemP) { bool pass=true; // make sure we pass sync set filtering and stay visible if (!fSyncSetFilter.empty()) { // try to make pass sync set filter (modifies item only if it would not pass otherwise) pass=aSyncItemP->makePassFilter(fSyncSetFilter.c_str()); } if (!pass || fSyncSetFilter.empty()) { // specified sync set filter cannot make item pass, or no sync set filter at all: // - apply makePassFilter default expression if (!fDSConfigP->fMakePassFilter.empty()) { pass=aSyncItemP->makePassFilter(fDSConfigP->fMakePassFilter.c_str()); if (pass) { // check again to check if item would pass the syncset filter now pass=aSyncItemP->testFilter(fSyncSetFilter.c_str()); } } } return pass; } // TLocalEngineDS::makePassSyncSetFilter #endif // process remote item bool TLocalEngineDS::engProcessRemoteItem( TSyncItem *syncitemP, TStatusCommand &aStatusCommand ) { #ifdef SYSYNC_CLIENT if (IS_CLIENT) return engProcessRemoteItemAsClient(syncitemP,aStatusCommand); // status, must be set to correct status code (ok / error) #endif #ifdef SYSYNC_SERVER if (IS_SERVER) return engProcessRemoteItemAsServer(syncitemP,aStatusCommand); // status, must be set to correct status code (ok / error) #endif // neither return false; } // TLocalEngineDS::engProcessRemoteItem class SyncOpItemAux : public SmlItemAux_t { static void freeAuxImpl(SmlItemAuxPtr_t ptr); public: SyncOpItemAux(); TSyncItemType *remoteTypeP; TSyncItemType *localTypeP; TFmtTypes fmt; TSyncItem *syncitemP; }; SyncOpItemAux::SyncOpItemAux() { freeAux = freeAuxImpl; } void SyncOpItemAux::freeAuxImpl(SmlItemAuxPtr_t ptr) { delete static_cast(ptr); } // process SyncML SyncOp command for this datastore bool TLocalEngineDS::engProcessSyncOpItem( TSyncOperation aSyncOp, // the operation SmlItemPtr_t aItemP, // the item to be processed SmlMetInfMetInfPtr_t aMetaP, // command-wide meta, if any TStatusCommand &aStatusCommand // pre-set 200 status, can be modified in case of errors ) { bool regular = false; // determine SyncItemType that can handle this item data if (fRemoteDatastoreP==NULL) { PDEBUGPRINTFX(DBG_ERROR,("engProcessSyncOpItem: Remote Datastore not known")); aStatusCommand.setStatusCode(500); } // We need the local and remote type plus format to // process the item. TSyncItemType *remoteTypeP; TSyncItemType *localTypeP; TFmtTypes fmt; TSyncItem *syncitemP=NULL; string versstr; SyncOpItemAux *aux = aItemP->aux ? static_cast(aItemP->aux) : NULL; if (aux) { // Reuse the previously calculated // values when being called again. remoteTypeP = aux->remoteTypeP; localTypeP = aux->remoteTypeP; fmt = aux->fmt; syncitemP = aux->syncitemP; goto process; } if (false) { again: if (!aux) { aux = new SyncOpItemAux; } aItemP->aux = aux; aux->remoteTypeP = remoteTypeP; aux->localTypeP = localTypeP; aux->fmt = fmt; aux->syncitemP = syncitemP; return false; } // - start with default remoteTypeP=getRemoteSendType(); localTypeP=getLocalReceiveType(); // - see if command-wide meta plus item contents specify another type // (item meta, if present, overrides command wide meta) // see if item itself or command meta specify a type name or format SmlMetInfMetInfPtr_t itemmetaP; itemmetaP = smlPCDataToMetInfP(aItemP->meta); // - format fmt=fmt_chr; if (itemmetaP && itemmetaP->format) smlPCDataToFormat(itemmetaP->format,fmt); // use type name from item's meta else if (aMetaP && aMetaP->format) smlPCDataToFormat(aMetaP->format,fmt); // use type name from command-wide meta // - type const char *typestr; typestr = NULL; if (itemmetaP && itemmetaP->type) typestr = smlPCDataToCharP(itemmetaP->type); // use type name from item's meta else if (aMetaP && aMetaP->type) typestr = smlPCDataToCharP(aMetaP->type); // use type name from command-wide meta // check if there is a type specified if (typestr) { PDEBUGPRINTFX(DBG_DATA,("Explicit type '%s' specified in command or item meta",typestr)); if (strcmp(remoteTypeP->getTypeName(),typestr)!=0) { // specified type is NOT default type: search appropriate remote type remoteTypeP=fRemoteDatastoreP->getSendType(typestr,NULL); // no version known so far if (!remoteTypeP) { // specified type is not a remote type listed in remote's devInf. // But as remote is actually using it, we can assume it does support it, so use local type of same name instead PDEBUGPRINTFX(DBG_ERROR,("According to remote devInf, '%s' is not supported, but obviously it is used here so we try to handle it",typestr)); // look it up in local datastore's list remoteTypeP=getReceiveType(typestr,NULL); } } if (remoteTypeP) { #ifdef APP_CAN_EXPIRE // get modified date of item lineardate_t moddat=0; // IMPORTANT, must be initialized in case expiryFromData returns nothing! bool ok = remoteTypeP->expiryFromData(aItemP,moddat)<=MAX_EXPIRY_DIFF+5; // ok==true: we are within hard expiry // ok==false: we are out of hard expiry #ifdef SYSER_REGISTRATION if (getSession()->getSyncAppBase()->fRegOK) { // we have a license (permanent or timed) --> hard expiry is irrelevant // (so override ok according to validity of current license) ok=true; // assume ok // check if license is timed, and if so, check if mod date is within timed range // (if not, set ok to false) uInt8 rd = getSession()->getSyncAppBase()->fRegDuration; if (rd) { lineardate_t ending = date2lineardate(rd/12+2000,rd%12+1,1); ok = ending>=moddat; // ok if not modified after end of license period } } #endif // when we have no license (neither permanent nor timed), hard expiry decides as is // (so just use ok as is) if (!ok) { aStatusCommand.setStatusCode(403); // forbidden to hack this expiry stuff! fSessionP->AbortSession(403,true); // local problem return false; } #endif // APP_CAN_EXPIRE // we have a type, which should be able to determine version from data if (remoteTypeP->versionFromData(aItemP,versstr)) { // version found, Make sure version matches as well PDEBUGPRINTFX(DBG_DATA,("Version '%s' obtained from item data",versstr.c_str())); // check if current remotetype already has correct version (and type, but we know this already) if (!remoteTypeP->supportsType(remoteTypeP->getTypeName(),versstr.c_str(),true)) { // no, type/vers do not match, search again remoteTypeP=fRemoteDatastoreP->getSendType(typestr,versstr.c_str()); if (!remoteTypeP) { // specified type is not a remote type listed in remote's devInf. // But as remote is actually using it, we can assume it does support it, so use local type of same name instead PDEBUGPRINTFX(DBG_ERROR,("According to remote devInf, '%s' version '%s' is not supported, but obviously it is used here so we try to handle it",typestr,versstr.c_str())); // look it up in local datastore's list remoteTypeP=getReceiveType(typestr,versstr.c_str()); } } } else { PDEBUGPRINTFX(DBG_HOT,("Version could not be obtained from item data")); } } if (!remoteTypeP) { // no matching remote type: fail aStatusCommand.setStatusCode(415); ADDDEBUGITEM(aStatusCommand,"Incompatible content type specified in command or item meta"); PDEBUGPRINTFX(DBG_ERROR,( "Incompatible content type '%s' version '%s' specified in command or item meta", typestr, versstr.empty() ? "[none]" : versstr.c_str() )); return false; // irregular } else { // we have the remote type, now determine matching local type // - first check if this is compatible with the existing localTypeP (which // was possibly selected by remote rule match if (!localTypeP->supportsType(remoteTypeP->getTypeName(),remoteTypeP->getTypeVers(),false)) { // current default local type does not support specified remote type // - find a matching local type localTypeP=getReceiveType(remoteTypeP); #ifdef SYDEBUG if (localTypeP) { PDEBUGPRINTFX(DBG_DATA+DBG_HOT,( "Explicit type '%s' does not match default type -> switching to local type '%s' for processing item", typestr, localTypeP->getTypeConfig()->getName() )); } #endif } } } // Now process or resume. We cannot jump right into // the block because of the try/catch, so some checks // for resuming are necessary. process: if (localTypeP && remoteTypeP) { // create the item (might have empty data in case of delete) if (!syncitemP) syncitemP=remoteTypeP->newSyncItem(aItemP,aSyncOp,fmt,localTypeP,this,aStatusCommand); if (!syncitemP) { // failed to create item return false; // irregular } // Now start the real processing PDEBUGBLOCKFMT(("Process_Item","processing remote item", "SyncOp=%s|LocalID=%s|RemoteID=%s", SyncOpNames[syncitemP->getSyncOp()], syncitemP->getLocalID(), syncitemP->getRemoteID() )); #ifdef SCRIPT_SUPPORT TErrorFuncContext errctx; errctx.syncop = syncitemP->getSyncOp(); #endif SYSYNC_TRY { // this call frees the item, unless it wants to be called again regular = engProcessRemoteItem(syncitemP,aStatusCommand); if (aStatusCommand.getStatusCode() == LOCERR_AGAIN) { goto again; } syncitemP = NULL; PDEBUGENDBLOCK("Process_Item"); } SYSYNC_CATCH (...) // Hmm, was the item freed? Not sure, so assume that it was freed. PDEBUGENDBLOCK("Process_Item"); SYSYNC_RETHROW; SYSYNC_ENDCATCH // Check for datastore level scripts that might change the status code and/or regular status #ifdef SCRIPT_SUPPORT errctx.statuscode = aStatusCommand.getStatusCode(); errctx.newstatuscode = errctx.statuscode; errctx.datastoreP = this; // call script regular = TScriptContext::executeTest( regular, // pass through regular status fDataStoreScriptContextP, fDSConfigP->fReceivedItemStatusScript, &ErrorFuncTable, &errctx // caller context ); // use possibly modified status code #ifdef SYDEBUG if (aStatusCommand.getStatusCode() != errctx.newstatuscode) { PDEBUGPRINTFX(DBG_ERROR,("Status: Datastore script changed original status=%hd to %hd (original op was %s)",aStatusCommand.getStatusCode(),errctx.newstatuscode,SyncOpNames[errctx.syncop])); } #endif aStatusCommand.setStatusCode(errctx.newstatuscode); #endif if (regular) { // item 100% successfully processed // - set new defaults to same type as current item setReceiveTypeInfo(localTypeP,remoteTypeP); } } else { // missing remote or local type: fail aStatusCommand.setStatusCode(415); ADDDEBUGITEM(aStatusCommand,"Unknown content type"); PDEBUGPRINTFX(DBG_ERROR,( "Missing remote or local SyncItemType" )); regular=false; // irregular } return regular; } // TLocalEngineDS::engProcessSyncOpItem #ifdef SYSYNC_SERVER // Server Case // =========== // helper to cause database version of an item (as identified by aSyncItemP's ID) to be sent to client // (aka "force a conflict") TSyncItem *TLocalEngineDS::SendDBVersionOfItemAsServer(TSyncItem *aSyncItemP) { TStatusCommand dummy(fSessionP); // - create new item TSyncItem *conflictingItemP = newItemForRemote(aSyncItemP->getTypeID()); if (!conflictingItemP) return NULL; // - set IDs conflictingItemP->setLocalID(aSyncItemP->getLocalID()); conflictingItemP->setRemoteID(aSyncItemP->getRemoteID()); // - this is always a replace conflict (item exists in DB) conflictingItemP->setSyncOp(sop_wants_replace); // - try to get from DB bool ok=logicRetrieveItemByID(*conflictingItemP,dummy); if (ok && dummy.getStatusCode()!=404) { // item found in DB, add it to the sync set so it can be sent to remote // if not cancelled by dontSendItemAsServer() SendItemAsServer(conflictingItemP); PDEBUGPRINTFX(DBG_DATA,("Forced conflict with corresponding item from server DB")); } else { // no item found, we cannot force a conflict delete conflictingItemP; conflictingItemP=NULL; } return conflictingItemP; } // TLocalEngineDS::SendDBVersionOfItemAsServer // process map localstatus TLocalEngineDS::engProcessMap(cAppCharP aRemoteID, cAppCharP aLocalID) { if (!testState(dssta_syncmodestable)) { // Map received when not appropriate PDEBUGPRINTFX(DBG_ERROR,("Map not allowed in this stage of sync")); return 403; } // pre-process localID string realLocalID; if (aLocalID && *aLocalID) { // Note: Map must be ready to have either empty local or remote ID to delete an entry // perform reverse lookup of received GUID to real GUID realLocalID = aLocalID; obtainRealLocalID(realLocalID); aLocalID=realLocalID.c_str(); } else { aLocalID=NULL; } // pre-process remoteID if (!aRemoteID || *aRemoteID==0) aRemoteID=NULL; // let implementation process the map command return logicProcessMap(aRemoteID, aLocalID); } // TLocalEngineDS::engProcessMap enum LocalItemOp { LOCAL_ITEM_DELETE, LOCAL_ITEM_ADD_NORMAL, LOCAL_ITEM_ADD_DELETED, LOCAL_ITEM_ADD_DUPLICATE, LOCAL_ITEM_REPLACE_MERGED, LOCAL_ITEM_REPLACE_FROM_CLIENT, LOCAL_ITEM_REPLACE, LOCAL_ITEM_ADD_MERGED, LOCAL_ITEM_REPLACE_MERGED2, LOCAL_ITEM_ADD_SLOW }; struct TLocalSyncItemAux : public TSyncItemAux { TSyncItem *fConflictingItemP; TSyncItem *fEchoItemP; TSyncItem *fDelItemP; TSyncItem *fMatchingItemP; bool fChangedIncoming; bool fChangedExisting; bool fRemainsVisible; TSyncOperation fSyncOp; uInt16 fItemTypeID; string fRemoteID; LocalItemOp fOp; TSyncOperation fCurrentSyncOp; TSyncOperation fEchoItemOp; TConflictResolution fItemConflictStrategy; bool fForceConflict; bool fDeleteWins; bool fPreventAdd; bool fIgnoreUpdate; sInt16 fRejectStatus; }; // process sync operation from client with specified sync item // (according to current sync mode of local datastore) // - returns true (and unmodified or non-200-successful status) if // operation could be processed regularily // - returns false (but probably still successful status) if // operation was processed with internal irregularities, such as // trying to delete non-existant item in datastore with // incomplete Rollbacks (which returns status 200 in this case!). bool TLocalEngineDS::engProcessRemoteItemAsServer( TSyncItem *aSyncItemP, TStatusCommand &aStatusCommand // status, must be set to correct status code (ok / error) ) { // The logic of this function is pretty complex. Instead of trying // to retrace our steps when called again after a LOCERR_AGAIN, let's // jump to labels directly. For that to work, all local variables // must be defined before the goto. TSyncItem *conflictingItemP; TSyncItem *echoItemP; TSyncItem *delitemP; TSyncItem *matchingItemP = NULL; bool changedincoming; bool changedexisting; bool remainsvisible; TSyncOperation syncop; uInt16 itemtypeid; string remoteid; LocalItemOp op; bool ok=false; TLocalSyncItemAux *aux = static_cast(aSyncItemP->getAux(TSyncItem::LOCAL_ENGINE)); if (aux) { // Resuming the function call: restore variables, jump to store // method call. // // The compiler will tell us if we jump across a variable // instantiation which initializes the variable ("jump bypasses // variable initialization"). Variables which are not needed when // resuming must be initialized with normal assignments to avoid // this error. Variables which are needed, need to be moved to the // section above and added to the store/restore. conflictingItemP = aux->fConflictingItemP; echoItemP = aux->fEchoItemP; delitemP = aux->fDelItemP; matchingItemP = aux->fMatchingItemP; changedincoming = aux->fChangedIncoming; changedexisting = aux->fChangedExisting; remainsvisible = aux->fRemainsVisible; syncop = aux->fSyncOp; itemtypeid = aux->fItemTypeID; remoteid = aux->fRemoteID; op = aux->fOp; // Besides the local variables, we also need to set members // to the value they had before leaving. See checkItem() below. // Some of these will never be different from the default because // if they got set in the first call, we don't queue and thus // don't get here. But restore them anyway, just to be sure. fCurrentSyncOp = aux->fCurrentSyncOp; fEchoItemOp = aux->fEchoItemOp; fItemConflictStrategy = aux->fItemConflictStrategy; fForceConflict = aux->fForceConflict; fDeleteWins = aux->fDeleteWins; fPreventAdd = aux->fPreventAdd; fIgnoreUpdate = aux->fIgnoreUpdate; fRejectStatus = aux->fRejectStatus; PDEBUGPRINTFX(DBG_DATA,("%s item operation resumed",SyncOpNames[syncop])); switch (op) { case LOCAL_ITEM_DELETE: goto do_delete; case LOCAL_ITEM_ADD_NORMAL: goto do_add_normal; case LOCAL_ITEM_ADD_DELETED: goto do_add_deleted; case LOCAL_ITEM_ADD_DUPLICATE: goto do_add_duplicate; case LOCAL_ITEM_REPLACE_MERGED: goto do_replace_merged; case LOCAL_ITEM_REPLACE_FROM_CLIENT: goto do_replace_from_client; case LOCAL_ITEM_REPLACE: goto do_replace; case LOCAL_ITEM_ADD_MERGED: goto do_add_merged; case LOCAL_ITEM_REPLACE_MERGED2: goto do_replace_merged2; case LOCAL_ITEM_ADD_SLOW: goto do_add_slow; }; } if (false) { // Prepare for resuming the function call. Will only be reached // via goto with "op" set to something identifying the source of // the jump. again: #define CHECK_FOR_AGAIN(_op) \ if (aStatusCommand.getStatusCode() == LOCERR_AGAIN) { \ op = _op; \ goto again; \ } if (!aux) { aux = new TLocalSyncItemAux; aSyncItemP->setAux(TSyncItem::LOCAL_ENGINE, aux); } aux->fConflictingItemP = conflictingItemP; aux->fEchoItemP = echoItemP; aux->fDelItemP = delitemP; aux->fMatchingItemP = matchingItemP; aux->fChangedIncoming = changedincoming; aux->fChangedExisting = changedexisting; aux->fRemainsVisible = remainsvisible; aux->fSyncOp = syncop; aux->fItemTypeID = itemtypeid; aux->fRemoteID = remoteid; aux->fOp = op; aux->fCurrentSyncOp = fCurrentSyncOp; aux->fEchoItemOp = fEchoItemOp; aux->fItemConflictStrategy = fItemConflictStrategy; aux->fForceConflict = fForceConflict; aux->fDeleteWins = fDeleteWins; aux->fPreventAdd = fPreventAdd; aux->fIgnoreUpdate = fIgnoreUpdate; aux->fRejectStatus = fRejectStatus; aStatusCommand.setStatusCode(LOCERR_AGAIN); return false; } // Normal control flow: initialize variables, then execute. conflictingItemP=NULL; echoItemP=NULL; delitemP=NULL; changedincoming=false; changedexisting=false; remainsvisible=true; // usually, we want the item to remain visible in the sync set // get some info out of item (we might need it after item is already consumed) syncop=aSyncItemP->getSyncOp(); itemtypeid=aSyncItemP->getTypeID(); remoteid=aSyncItemP->getRemoteID(); // check if datastore is aborted if(CheckAborted(aStatusCommand)) return false; // send event (but no abort checking) DB_PROGRESS_EVENT(this,pev_itemreceived,++fItemsReceived,fRemoteNumberOfChanges,0); fPreventAdd = false; fIgnoreUpdate = false; // show PDEBUGPRINTFX(DBG_DATA,("%s item operation received",SyncOpNames[syncop])); // check if receiving commands is allowed at all if (fSyncMode==smo_fromserver) { // Modifications from client not allowed during update from server only aStatusCommand.setStatusCode(403); ADDDEBUGITEM(aStatusCommand,"Client command not allowed in one-way/refresh from server"); PDEBUGPRINTFX(DBG_ERROR,("Client command not allowed in one-way/refresh from server")); delete aSyncItemP; return false; } // let item check itself to catch special cases // - init variables which are used/modified by item checking #ifdef SYSYNC_TARGET_OPTIONS // init item generation variables fItemSizeLimit=fSizeLimit; #else fItemSizeLimit=-1; // no limit #endif fCurrentSyncOp = syncop; fEchoItemOp = sop_none; fItemConflictStrategy=fSessionConflictStrategy; // get default strategy for this item fForceConflict = false; fDeleteWins = fDSConfigP->fDeleteWins; // default to configured value fRejectStatus = -1; // no rejection // - now check // check reads and possibly modifies: // - fEchoItemOp : if not sop_none, the incoming item is echoed back to the remote with the specified syncop // - fItemConflictStrategy : might be changed from the pre-set datastore default // - fForceConflict : if set, a conflict is forced by adding the corresponding local item (if any) to the list of items to be sent // - fDeleteWins : if set, in a replace/delete conflict delete will win (regardless of strategy) // - fPreventAdd : if set, attempt to add item from remote (even implicitly trough replace) will cause no add but delete of remote item // - fIgnoreUpdate : if set, attempt to update item from remote will be ignored, only adds (also implicit ones) are executed // - fRejectStatus : if set>=0, incoming item is irgnored silently(==0) or with error(!=0) aSyncItemP->checkItem(this); // - create echo item if we need one if (fEchoItemOp!=sop_none) { // Note: sop_add makes no sense at all. // Note: If echo is enabled, conflicts are not checked, as echo makes only sense in // cases where we know that a conflict cannot occur or is irrelevant // - artifically create a "conflicting" item, that is, one to be sent back to remote echoItemP=newItemForRemote(aSyncItemP->getTypeID()); // - assign data from incoming item if echo is not a delete if (fEchoItemOp!=sop_delete && fEchoItemOp!=sop_archive_delete && fEchoItemOp!=sop_soft_delete) echoItemP->replaceDataFrom(*aSyncItemP); // - set remote ID (note again: sop_add makes no sense here) echoItemP->setRemoteID(aSyncItemP->getRemoteID()); // - set sop echoItemP->setSyncOp(fEchoItemOp); // - now check for possible conflict if (!fSlowSync) { conflictingItemP = getConflictingItemByRemoteID(aSyncItemP); // remove item if there is one that would conflict with the echo if (conflictingItemP) dontSendItemAsServer(conflictingItemP); conflictingItemP = NULL; } // - add echo to the list of items to be sent (DB takes ownership) SendItemAsServer(echoItemP); PDEBUGPRINTFX(DBG_DATA,("Echoed item back to remote with sop=%s",SyncOpNames[fEchoItemOp])); // process item normally (except that we don't check for LUID conflicts) } // - check if incoming item should be processed at all if (fRejectStatus>=0) { // Note: a forced conflict can still occur even if item is rejected // (this has the effect of unconditionally letting the server item win) if (fForceConflict && syncop!=sop_add) { conflictingItemP = SendDBVersionOfItemAsServer(aSyncItemP); // Note: conflictingitem is always a replace if (conflictingItemP) { if (syncop==sop_delete) { // original was delete, forced conflict means re-adding to remote conflictingItemP->setSyncOp(sop_wants_add); } else { // merge here because we'll not process the item further conflictingItemP->mergeWith(*aSyncItemP,changedexisting,changedincoming,this); } } } // now discard the incoming item delete aSyncItemP; PDEBUGPRINTFX(fRejectStatus>=400 ? DBG_ERROR : DBG_DATA,("Item rejected with Status=%hd",fRejectStatus)); if (fRejectStatus>0) { // rejected with status code (not necessarily error) aStatusCommand.setStatusCode(fRejectStatus); if (fRejectStatus>=300) { // non 200-codes are errors ADDDEBUGITEM(aStatusCommand,"Item rejected"); return false; } } // silently rejected return true; } // now perform requested operation localstatus sta; switch (syncop) { readonly_delete: // read-only handling of delete is like soft delete: remove map entry, but nothing else PDEBUGPRINTFX(DBG_DATA,("Read-Only Datastore: Prevented actual deletion, just removing map entry")); case sop_soft_delete: // Readonly: allowed, as only map is touched // soft delete from client is treated as an indication that the item was // removed from the client's datastore, but is still in the set // of sync data for that client. // This means that the map item must be removed. // - when the item is hard-deleted on the server, nothing will happen at next sync // - when the item is modified on the server, it will be re-added to the client at next sync // - when slow sync is performed, the item will be re-added, too. // %%%%% Note that this does NOT work as it is now, as adds also occur for non-modified // items that have no map AND are visible under current targetFilter. // probably we should use a map entry with no remoteID for soft-deleted items later.... // Delete Map entry by remote ID aSyncItemP->clearLocalID(); // none sta=engProcessMap(aSyncItemP->getRemoteID(),NULL); ok=sta==LOCERR_OK; aStatusCommand.setStatusCode(ok ? 200 : sta); break; case sop_archive_delete: if (fReadOnly) goto readonly_delete; // register removal of item in map, but do nothing to data itself #ifdef OBJECT_FILTERING if (!fDSConfigP->fInvisibleFilter.empty()) { // turn into replace with all fields unavailable but made to pass invisible filter // - make sure that no data field is assigned aSyncItemP->cleardata(); // - make item pass "invisible" filter if (aSyncItemP->makePassFilter(fDSConfigP->fInvisibleFilter.c_str())) { // item now passes invisible rule, that is, it is invisible -> replace in DB goto archive_delete; } } // fall trough, no archive delete supported #endif // No archive delete support if there is no filter to detect/generate invisibles // before SyncML 1.1 : we could return 210 here and still process the delete op. // SyncML 1.1 : we must return 501 (not implemented) here aStatusCommand.setStatusCode(501); PDEBUGPRINTFX(DBG_ERROR,("Datastore does not support Archive-Delete, error status = 501")); delete aSyncItemP; ok=false; break; case sop_delete: // delete item by LUID if (fSlowSync) { aStatusCommand.setStatusCode(403); ADDDEBUGITEM(aStatusCommand,"Delete during slow sync not allowed"); PDEBUGPRINTFX(DBG_ERROR,("Delete during slow sync not allowed")); delete aSyncItemP; ok=false; break; } // check for conflict with replace from server // Note: conflict cases do not change local DB, so they are allowed before checking fReadOnly if (!echoItemP) conflictingItemP = getConflictingItemByRemoteID(aSyncItemP); // do not check conflicts if we have already created an echo // - check if we must force the conflict if (!conflictingItemP && fForceConflict) { conflictingItemP=SendDBVersionOfItemAsServer(aSyncItemP); } if (conflictingItemP) { // conflict only if other party has replace if (conflictingItemP->getSyncOp()==sop_replace || conflictingItemP->getSyncOp()==sop_wants_replace) { if (!fDeleteWins) { // act as if successfully deleted and cause re-adding of still existing server item // - discard deletion delete aSyncItemP; // - remove map entry for this item (it no longer exists on the client) sta = engProcessMap(NULL,conflictingItemP->getLocalID()); aStatusCommand.setStatusCode(sta==LOCERR_OK ? 200 : sta); // - change replace to add (as to-be-replaced item is already deleted on remote) conflictingItemP->setSyncOp(sop_add); // - remove remote ID (will be assigned a new ID because the item is now re-added) conflictingItemP->setRemoteID(""); // - no server operation needed PDEBUGPRINTFX(DBG_DATA,("Conflict of Client Delete with Server replace -> discarded delete, re-added server item to client")); ok=true; break; } else { // delete preceedes replace // - avoid sending item from server dontSendItemAsServer(conflictingItemP); // - let delete happen } } // if both have deleted the item, we should remove the map // and avoid sending a delete to the client else if (conflictingItemP->getSyncOp()==sop_delete) { // - discard deletion delete aSyncItemP; // - remove map entry for this item (it no longer exists) sta = engProcessMap(NULL,conflictingItemP->getLocalID()); aStatusCommand.setStatusCode(sta==LOCERR_OK ? 200 : sta); // - make sure delete from server is not sent dontSendItemAsServer(conflictingItemP); PDEBUGPRINTFX(DBG_DATA,("Client and Server have deleted same item -> just removed map entry")); ok=true; break; } } // real delete is discarded silently when fReadOnly is set if (fReadOnly) goto readonly_delete; // register removal of item in map, but do nothing to data itself // really delete fLocalItemsDeleted++; remainsvisible=false; // deleted not visible any more do_delete: ok=logicProcessRemoteItem(aSyncItemP,aStatusCommand,remainsvisible); // delete in local database NOW CHECK_FOR_AGAIN(LOCAL_ITEM_DELETE); break; case sop_copy: if (fReadOnly) { delete aSyncItemP; // we don't need it aStatusCommand.setStatusCode(200); PDEBUGPRINTFX(DBG_DATA,("Read-Only: copy command silently discarded")); ok=true; break; } // %%% note: this would belong into specific datastore implementation, but is here // now for simplicity as copy isn't used heavily het // retrieve data from local datastore if (!logicRetrieveItemByID(*aSyncItemP,aStatusCommand)) { ok=false; break; } // process like add /// @todo %%%%%%%%%%%%%%%% NOTE: MISSING SENDING BACK MAP COMMAND for new GUID created goto normal_add; case sop_add: // test for slow sync if (fSlowSync) goto sop_slow_add; // add in slow sync is like replace normal_add: // add as new item to server DB aStatusCommand.setStatusCode(201); // item added (if no error occurs) if (fReadOnly) { delete aSyncItemP; // we don't need it PDEBUGPRINTFX(DBG_DATA,("Read-Only: add command silently discarded")); ok=true; break; } // check if adds are prevented if (!fPreventAdd) { // add allowed fLocalItemsAdded++; #ifdef OBJECT_FILTERING // test if acceptable if (!isAcceptable(aSyncItemP,aStatusCommand)) { ok=false; break; } // cannot be accepted // Note: making item to pass sync set filter is implemented in derived DB implementation // as criteria for passing might be in data that must first be read from the DB #endif do_add_normal: remainsvisible=true; // should remain visible ok=logicProcessRemoteItem(aSyncItemP,aStatusCommand,remainsvisible); // add to local database NOW CHECK_FOR_AGAIN(LOCAL_ITEM_ADD_NORMAL); if (!remainsvisible && fSessionP->getSyncMLVersion()>=syncml_vers_1_2) { PDEBUGPRINTFX(DBG_DATA+DBG_HOT,("Added item is not visible under current filters -> remove it on client")); goto removefromremoteandsyncset; } break; } goto preventadd; archive_delete: sop_slow_add: aSyncItemP->setSyncOp(sop_replace); // set correct op // ...and process like replace case sop_reference_only: case sop_replace: #ifdef OBJECT_FILTERING // test if acceptable if (!isAcceptable(aSyncItemP,aStatusCommand)) { ok=false; break; } // cannot be accepted // Note: making item to pass sync set filter is implemented in derived DB implementation // as criteria for passing might be in data that must first be read from the DB #endif // check for conflict with server side modifications if (!fSlowSync) { if (!echoItemP) conflictingItemP = getConflictingItemByRemoteID(aSyncItemP); // - check if we must force the conflict if (!conflictingItemP && fForceConflict) { conflictingItemP=SendDBVersionOfItemAsServer(aSyncItemP); } bool deleteconflict; deleteconflict=false; if (conflictingItemP) { // Note: if there is a conflict, this replace cannot be an // implicit add, so we don't need to check for fPreventAdd // here. // Note: if we are in ignoreUpdate mode, the only conflict resolution // possible is unconditional server win sInt16 cmpRes; cmpRes = SYSYNC_NOT_COMPARABLE; // assume we can resolve the conflict aStatusCommand.setStatusCode(419); // default to server win ADDDEBUGITEM(aStatusCommand,"Conflict resolved by server"); PDEBUGPRINTFX(DBG_HOT,( "Conflict: Remote <%s> with remoteID=%s <--> Local <%s> with localID=%s, remoteID=%s", SyncOpNames[aSyncItemP->getSyncOp()], aSyncItemP->getRemoteID(), SyncOpNames[conflictingItemP->getSyncOp()], conflictingItemP->getLocalID(), conflictingItemP->getRemoteID() )); // we have a conflict, decide what to do TConflictResolution crstrategy; if (fReadOnly || fIgnoreUpdate) { // server always wins and overwrites modified client version PDEBUGPRINTFX(DBG_DATA,("Read-Only or IgnoreUpdate: server always wins")); crstrategy=cr_server_wins; } else if (fCacheData) { PDEBUGPRINTFX(DBG_DATA,("Caching data: client always wins")); crstrategy=cr_client_wins; } else { // two-way crstrategy = fItemConflictStrategy; // get conflict strategy pre-set for this item if (conflictingItemP->getSyncOp()==sop_delete) { // server wants to delete item, client wants to replace if (fDSConfigP->fTryUpdateDeleted) { // if items are not really deleted, but only made invisible, // we can assume we can update the "deleted" item // BUT ONLY if the conflict strategy is not "server always wins" if (crstrategy==cr_server_wins) { PDEBUGPRINTFX(DBG_PROTO+DBG_HOT,("Conflict of Client Replace with Server delete and strategy is server-wins -> delete from client")); aStatusCommand.setStatusCode(419); // server wins, client command ignored break; // done } else { PDEBUGPRINTFX(DBG_PROTO+DBG_HOT,("Conflict of Client Replace with Server delete -> try to update already deleted item (as it might still exist in syncset)")); // apply replace (and in case of !fDeleteWins, possible implicit add) fPreventAdd=fDeleteWins; // we want implicit add only if delete cannot win do_add_deleted: remainsvisible=!fDeleteWins; // we want to see the item in the sync set if delete does not win! ok=logicProcessRemoteItem(aSyncItemP,aStatusCommand,remainsvisible); CHECK_FOR_AGAIN(LOCAL_ITEM_ADD_DELETED); } if (fDeleteWins) { if (!ok) { // could not update already deleted item PDEBUGPRINTFX(DBG_PROTO,("Could not update already deleted server item (seems to be really deleted, not just invisible)")); aStatusCommand.setStatusCode(419); // server wins, client command ignored } else { // update of invisible item successful, but it will still be deleted from client // Note: possibly, the update was apparently successful, but only because an UPDATE with no // target does not report an error. So effectively, no update might have happened. PDEBUGPRINTFX(DBG_PROTO,("Updated already deleted server item, but delete still wins -> client item will be deleted")); fLocalItemsUpdated++; aStatusCommand.setStatusCode(200); // client command successful (but same item will still be deleted) } // nothing more to do, let delete happen on the client (conflictingItemP delete will be sent) ok=true; } else { // not fDeleteWins - item failed, updated or implicitly added if (ok) { // update (or implicit add) successful if (aStatusCommand.getStatusCode()==201) { PDEBUGPRINTFX(DBG_PROTO,("Client Update wins and has re-added already deleted server item -> prevent delete on client")); fLocalItemsAdded++; } else { PDEBUGPRINTFX(DBG_PROTO,("Client Update wins and has updated still existing server item -> prevent delete on client")); fLocalItemsUpdated++; } // and client item wins - prevent sending delete to client // - don't send delete to client conflictingItemP->setSyncOp(sop_none); // just in case... dontSendItemAsServer(conflictingItemP); } } // done break; } else { // Normal delete conflict processing (assuming deleted items REALLY deleted) if (!fDeleteWins) { // - client always wins (replace over delete) crstrategy=cr_client_wins; deleteconflict=true; // flag condition for processing below // - change from replace to add, because item is already deleted in server and must be re-added fLocalItemsAdded++; aSyncItemP->setSyncOp(sop_add); PDEBUGPRINTFX(DBG_PROTO,("Conflict of Client Replace with Server delete -> client wins, client item is re-added to server")); } else { // delete wins, just discard incoming item delete aSyncItemP; PDEBUGPRINTFX(DBG_PROTO,("Conflict of Client Replace with Server delete -> DELETEWINS() set -> ignore client replace")); ok=true; break; } } } else { // replace from client conflicts with replace from server // - compare items for further conflict resolution // NOTE: it is serveritem.compareWith(clientitem) cmpRes = conflictingItemP->compareWith( *aSyncItemP,eqm_conflict,this #ifdef SYDEBUG ,PDEBUGTEST(DBG_CONFLICT) // show conflict comparisons in normal sync if conflict details are enabled #endif ); PDEBUGPRINTFX(DBG_DATA,( "Compared conflicting items with eqm_conflict: remoteItem %s localItem", cmpRes==0 ? "==" : (cmpRes>0 ? "<" : ">") )); // see if we can determine newer item if (crstrategy==cr_newer_wins) { if (cmpRes!=0 && conflictingItemP->sortable(*aSyncItemP)) { // newer item wins // (comparison was: serveritem.compareWith(clientitem), so // cmpRes<0 means that client is newer PDEBUGPRINTFX(DBG_PROTO,("Conflict resolved by identifying newer item")); if (cmpRes > 0) crstrategy=cr_server_wins; // server has newer item else crstrategy=cr_client_wins; // client has newer item } else { // newer item cannot be determined, duplicate items crstrategy=cr_duplicate; } PDEBUGPRINTFX(DBG_DATA,( "Newer item %sdetermined: %s", crstrategy==cr_duplicate ? "NOT " : "", crstrategy==cr_client_wins ? "Client item is newer and wins" : (crstrategy==cr_server_wins ? "Server item is newer ans wins" : "item is duplicated if different") )); } } // modify strategy based on compare if (cmpRes==0 && crstrategy==cr_duplicate) { // items are equal by definition of item comparison, // but obviously both changed, this means that changes should be // mergeable // So, by deciding arbitrarily that server has won, we will not loose any data crstrategy=cr_server_wins; // does not matter, because merge will be attempted PDEBUGPRINTFX(DBG_DATA,("Duplication avoided because items are equal by their own definition, just merge")); } // if adds prevented, we cannot duplicate, let server win if (fPreventAdd && crstrategy==cr_duplicate) crstrategy=cr_server_wins; } // not fReadOnly // now apply strategy if (crstrategy==cr_duplicate) { // add items vice versa PDEBUGPRINTFX(DBG_PROTO,("Conflict resolved by duplicating items in both databases")); aStatusCommand.setStatusCode(209); fConflictsDuplicated++; // - set server item such that it will be added as new item to client DB conflictingItemP->setSyncOp(sop_add); // - break up mapping between client and server item BEFORE adding to server // because else adding of item with already existing remoteID can fail. // In addition, item now being sent to client may not have a map before // it receives a map command from the client! sta = engProcessMap(NULL,conflictingItemP->getLocalID()); if(sta!=LOCERR_OK) { PDEBUGPRINTFX(DBG_ERROR,( "Problem (status=%hd) removing map entry for LocalID='%s'", sta, conflictingItemP->getLocalID() )); } // - add client item as new item to server DB fLocalItemsAdded++; aSyncItemP->setSyncOp(sop_add); // set correct op do_add_duplicate: remainsvisible=true; // should remain visible ok=logicProcessRemoteItem(aSyncItemP,aStatusCommand,remainsvisible); // add to local database NOW CHECK_FOR_AGAIN(LOCAL_ITEM_ADD_DUPLICATE); break; } else if (crstrategy==cr_server_wins) { // Note: for fReadOnly, this is always the case! // server item wins and is sent to client PDEBUGPRINTFX(DBG_PROTO,("Conflict resolved: server item replaces client item")); aStatusCommand.setStatusCode(419); // server wins, client command ignored fConflictsServerWins++; // - make sure item is set to replace data in client conflictingItemP->setSyncOp(sop_replace); // - attempt to merge data from loosing item (accumulating fields) if (!fReadOnly) { conflictingItemP->mergeWith(*aSyncItemP,changedexisting,changedincoming,this); } if (fIgnoreUpdate) changedexisting=false; // never try to update existing item if (changedexisting) { // we have merged something, so server must be updated, too // Note: after merge, both items are equal. We check if conflictingitem // has changed, but if yes, we write the incoming item. Conflicting item // will get sent to client later PDEBUGPRINTFX(DBG_DATA,("*** Merged some data from loosing client item into winning server item")); // set correct status for conflict resultion by merge aStatusCommand.setStatusCode(207); // merged // process update in local database fLocalItemsUpdated++; aSyncItemP->setSyncOp(sop_replace); // update do_replace_merged: remainsvisible=true; // should remain visible ok=logicProcessRemoteItem(aSyncItemP,aStatusCommand,remainsvisible); // update in local database NOW CHECK_FOR_AGAIN(LOCAL_ITEM_REPLACE_MERGED); break; } else { // - item sent by client has lost and can be deleted now // %%% possibly add option here to archive item in some way // BUT ONLY IF NOT fReadOnly delete aSyncItemP; } } else if (crstrategy==cr_client_wins) { // client item wins and is sent to server PDEBUGPRINTFX(DBG_PROTO,("Conflict resolved: client item replaces server item")); aStatusCommand.setStatusCode(208); // client wins fConflictsClientWins++; // - attempt to merge data from loosing item (accumulating fields) if (!fCacheData && !deleteconflict) { aSyncItemP->mergeWith(*conflictingItemP,changedincoming,changedexisting,this); } if (changedincoming) { // we have merged something, so client must be updated even if it has won // Note: after merge, both items are equal. We check if aSyncItemP // has changed, but if yes, we make sure the conflicting item gets // sent to the client PDEBUGPRINTFX(DBG_DATA,("*** Merged some data from loosing server item into winning client item")); conflictingItemP->setSyncOp(sop_replace); // update // set correct status for conflict resultion by merge aStatusCommand.setStatusCode(207); // merged // will be sent because it is in the list } else { // - make sure conflicting item from server is NOT sent to client conflictingItemP->setSyncOp(sop_none); // just in case... dontSendItemAsServer(conflictingItemP); aStatusCommand.setStatusCode(200); // ok } // - replace item in server (or leave it as is, if conflict was with delete) if (!deleteconflict) { fLocalItemsUpdated++; aSyncItemP->setSyncOp(sop_replace); } do_replace_from_client: remainsvisible=true; // should remain visible ok=logicProcessRemoteItem(aSyncItemP,aStatusCommand,remainsvisible); // replace in local database NOW CHECK_FOR_AGAIN(LOCAL_ITEM_REPLACE_FROM_CLIENT); break; } } // replace conflict else { // normal replace without any conflict if (fReadOnly) { delete aSyncItemP; // we don't need it aStatusCommand.setStatusCode(200); PDEBUGPRINTFX(DBG_DATA,("Read-Only: replace command silently discarded")); ok=true; break; } // no conflict, just let client replace server's item PDEBUGPRINTFX(DBG_DATA+DBG_CONFLICT,("No Conflict: client item replaces server item")); // - replace item in server (or add if item does not exist and not fPreventAdd) aSyncItemP->setSyncOp(sop_replace); do_replace: remainsvisible=true; // should remain visible ok=logicProcessRemoteItem(aSyncItemP,aStatusCommand,remainsvisible); CHECK_FOR_AGAIN(LOCAL_ITEM_REPLACE); if (!ok) { // check if this is a 404 or 410 and fPreventAdd if (fPreventAdd && (aStatusCommand.getStatusCode()==404 || aStatusCommand.getStatusCode()==410)) goto preventadd2; // to-be-replaced item not found and implicit add prevented -> delete from remote // simply failed break; } // still visible in sync set? if (!remainsvisible && fSessionP->getSyncMLVersion()>=syncml_vers_1_2) { // -> cause item to be deleted on remote PDEBUGPRINTFX(DBG_DATA+DBG_HOT,("Item replaced no longer visible in syncset -> returning delete to remote")); goto removefromremoteandsyncset; } // processed ok if (aStatusCommand.getStatusCode()==201) fLocalItemsAdded++; else fLocalItemsUpdated++; ok=true; break; } } // normal sync else { // slow sync (replaces AND adds are treated the same) // - first do a strict search for identical item. This is required to // prevent that in case of multiple (loosely compared) matches we // catch the wrong item and cause a mess at slowsync // NOTE: we do compare only relevant fields (eqm_conflict) matchingItemP = getMatchingItem(aSyncItemP,eqm_conflict); // separate assignment, only done as part of normal control flow if (!matchingItemP) { // try again with less strict comparison (eqm_slowsync or eqm_always for firsttimesync) DEBUGPRINTFX(DBG_DATA+DBG_MATCH,("Strict search for matching item failed, try with configured EqMode now")); matchingItemP = getMatchingItem(aSyncItemP,fFirstTimeSync ? eqm_always : eqm_slowsync); } if (matchingItemP) { // both sides already have this item PDEBUGPRINTFX(DBG_DATA+DBG_HOT,( "Slow Sync Match detected - localID='%s' matches incoming item", matchingItemP->getLocalID() )); fSlowSyncMatches++; aStatusCommand.setStatusCode(syncop==sop_add ? 201 : 200); // default is: simply ok. But if original op was Add, MUST return 201 status (SCTS requires it) bool matchingok; matchingok = false; // - do not update map yet, as we still don't know if client item will // possibly be added instead of mapped // Note: ONLY in case this is a reference-only item, the map is already updated! bool mapupdated; mapupdated = syncop==sop_reference_only; // - determine which one is winning bool needserverupdate; bool needclientupdate; needserverupdate = false; needclientupdate = false; // if updates are ignored, we can short-cut here // Note: if this is a reference-only item, it was already updated (if needed) before last suspend // so skip updating now! if (syncop!=sop_reference_only && !fIgnoreUpdate) { // Not a reference-only and also updates not suppressed // - for a read-only datastore, this defaults to server always winning TConflictResolution crstrategy; crstrategy = fReadOnly ? cr_server_wins : // server always wins for read-only fItemConflictStrategy; // pre-set strategy for this item // Determine what data to use if (crstrategy==cr_newer_wins) { // use newer // Note: comparison is clientitem.compareWith(serveritem) // so if result>0, client is newer than server sInt16 cmpRes = aSyncItemP->compareWith( *matchingItemP,eqm_nocompare,this #ifdef SYDEBUG ,PDEBUGTEST(DBG_CONFLICT+DBG_DETAILS) // show age comparisons only if we want to see details #endif ); if (cmpRes==1) crstrategy=cr_client_wins; else if (cmpRes==-1 || fPreventAdd) crstrategy=cr_server_wins; // server wins if adds prevented else crstrategy=cr_duplicate; // fall back to duplication if we can't determine newer item PDEBUGPRINTFX(DBG_DATA,( "Newer item %sdetermined: %s", crstrategy==cr_duplicate ? "NOT " : "", crstrategy==cr_client_wins ? "Client item is newer and wins" : (crstrategy==cr_server_wins ? "Server item is newer and wins" : "item is duplicated if different") )); } // if adds prevented, we cannot duplicate, let server win if (fPreventAdd && crstrategy==cr_duplicate) crstrategy=cr_server_wins; else if (fCacheData) crstrategy=cr_client_wins; // now execute chosen strategy if (crstrategy==cr_client_wins) { if (fCacheData) { // - merge server's data into client item PDEBUGPRINTFX(DBG_DATA,("Caching: copying winning client item into loosing server item")); aSyncItemP->mergeWith(*matchingItemP,changedincoming,changedexisting,this, TSyncItem::MERGE_OPTION_CHANGE_OTHER); } else { // - merge server's data into client item PDEBUGPRINTFX(DBG_DATA,("Trying to merge some data from loosing server item into winning client item")); aSyncItemP->mergeWith(*matchingItemP,changedincoming,changedexisting,this); // only count if server gets updated if (changedexisting) fConflictsClientWins++; } // Note: changedexisting will cause needserverupdate to be set below } else if (crstrategy==cr_server_wins) { // - merge client data into server item PDEBUGPRINTFX(DBG_DATA,("Trying to merge some data from loosing client item into winning server item")); matchingItemP->mergeWith(*aSyncItemP,changedexisting,changedincoming,this); // only count if client gets updated if (changedincoming) fConflictsServerWins++; // Note: changedincoming will cause needclientupdate to be set below } else if (crstrategy==cr_duplicate) { // test if items are equal enough // (Note: for first-sync, compare mode for item matching can be looser // (eqm_always), so re-comparison here makes sense) if ( matchingItemP->compareWith( *aSyncItemP,eqm_slowsync,this #ifdef SYDEBUG ,PDEBUGTEST(DBG_CONFLICT+DBG_DETAILS) // show equality re-test only for details enabled #endif )!=0 ) { // items are not really equal in content, so duplicate them on both sides PDEBUGPRINTFX(DBG_PROTO,("Matching items are not fully equal, duplicate them on both sides")); fConflictsDuplicated++; // - duplicates contain merged data matchingItemP->mergeWith(*aSyncItemP,changedexisting,changedincoming,this); // - add client item (with server data merged) as new item to server fLocalItemsAdded++; aSyncItemP->setSyncOp(sop_add); aStatusCommand.setStatusCode(201); // item added (if no error occurs) do_add_merged: string guid; remainsvisible=true; // should remain visible matchingok=logicProcessRemoteItem(aSyncItemP,aStatusCommand,remainsvisible,&guid); // add item in local database NOW CHECK_FOR_AGAIN(LOCAL_ITEM_ADD_MERGED); aSyncItemP=NULL; // is already deleted! if (matchingok) { // do it only if server add successful, because otherwise we don't have a GUID // - make sure same item is ADDED as new item to client matchingItemP->setSyncOp(sop_add); // add it, prevent it from re-match (is sop_wants_add now) matchingItemP->setLocalID(guid.c_str()); // this is now a pair with the newly added item (not the original one) matchingItemP->setRemoteID(""); // we don't know the remote ID yet } // adding duplicate to server (add) is already done changedexisting=false; changedincoming=false; mapupdated=true; // no need to update map needserverupdate=false; // already done // client must received the (updated) server item as an add (set above) needclientupdate=true; } } } // if not ignoreUpdate // Update server map now if required // - NOTE THAT THIS IS VERY IMPORTANT TO DO BEFORE any possible // replaces, because replacing the matchingItem can only be // done via its remoteID, which is, at this moment, probably not // valid. After Mapping, it is ensured that the mapped remoteID // uniquely identifies the matchingItem. if (!mapupdated) { // - update map in server sta = engProcessMap( aSyncItemP->getRemoteID(), // remote ID (LUID) of item received from client matchingItemP->getLocalID() // local ID (GUID) of item already stored in server ); matchingok = sta==LOCERR_OK; if (!matchingok) { // failed ok=false; aStatusCommand.setStatusCode(sta); break; } } // Now prepare updates of (already mapped) server and client items if needed if (changedexisting) { // matched item in server's sync set was changed and must be update in server DB // update server only if updates during non-first-time slowsync are enabled if (fFirstTimeSync || fSessionP->fUpdateServerDuringSlowsync) { needserverupdate=true; // note: ineffective if fReadOnly PDEBUGPRINTFX(DBG_DATA+DBG_HOT,("Server data was updated by record sent by client, REPLACE it in server DB")); } else { PDEBUGPRINTFX(DBG_DATA+DBG_HOT,("Server data was updated by record sent by client, but server updates during non-firsttime slowsyncs are disabled")); } } if (changedincoming) { // incoming item from remote was changed after receiving and must be reflected // back to client // NOTE: this can also happen with sop_reference_only items // - client will be updated because matchingItemP is still in list matchingItemP->setSyncOp(sop_replace); // cancel wants_add state, prevent re-match // - matchingItem was retrieved BEFORE map was done, and has no valid remote ID // so remote ID must be added now. matchingItemP->setRemoteID(aSyncItemP->getRemoteID()); // update client only if updates during non-first-time slowsync are enabled if (fFirstTimeSync || fSessionP->fUpdateClientDuringSlowsync) { PDEBUGPRINTFX(DBG_DATA+DBG_HOT,("Record sent by client was updated with server data, client will receive a REPLACE")); needclientupdate=true; } else { PDEBUGPRINTFX(DBG_DATA+DBG_HOT,("Record sent by client was updated, but client updates during non-firsttime slowsyncs are disabled")); } } // update // - check if client must be updated if (!needclientupdate) { // prevent updating client // - make sure matching item from server is NOT sent to client matchingItemP->setSyncOp(sop_none); // just in case... dontSendItemAsServer(matchingItemP); } else { // check if replaces may be sent to client during slowsync if (matchingItemP->getSyncOp()==sop_replace && fSessionP->fNoReplaceInSlowsync) { PDEBUGPRINTFX(DBG_DATA+DBG_HOT,("Update of client item suppressed because of ")); matchingItemP->setSyncOp(sop_none); // just in case... dontSendItemAsServer(matchingItemP); } else { PDEBUGPRINTFX(DBG_DATA+DBG_HOT,("Update of client item enabled (will be sent later)")); } } // - check if server must be updated (NEVER for fReadOnly) if (!fReadOnly && needserverupdate && aSyncItemP) { // update server // - update server side (NOTE: processItemAsServer takes ownership, pointer gets invalid!) fLocalItemsUpdated++; aSyncItemP->setSyncOp(sop_replace); do_replace_merged2: remainsvisible=true; // should remain visible matchingok=logicProcessRemoteItem(aSyncItemP,aStatusCommand,remainsvisible); // replace item in local database NOW CHECK_FOR_AGAIN(LOCAL_ITEM_REPLACE_MERGED2); PDEBUGPRINTFX(DBG_DATA+DBG_HOT,("Updated server item")); } else { // - delete incoming item unprocessed (if not already deleted) if (aSyncItemP) delete aSyncItemP; } // check if we need to actively delete item from the client as it falls out of the filter if (!remainsvisible && fSessionP->getSyncMLVersion()>=syncml_vers_1_2) { // -> cause item to be deleted on remote PDEBUGPRINTFX(DBG_DATA+DBG_HOT,("Slow sync matched item no longer visible in syncset -> returning delete to remote")); goto removefromremoteandsyncset; } ok=matchingok; break; } else { PDEBUGPRINTFX(DBG_DATA+DBG_HOT,("No matching item found - add it to local database")); // this item is not yet on the server, add it normally aStatusCommand.setStatusCode(201); // item added (if no error occurs) if (fReadOnly) { delete aSyncItemP; // we don't need it PDEBUGPRINTFX(DBG_DATA,("Read-Only: slow-sync add/replace command silently discarded")); ok=true; break; } if (fPreventAdd) goto preventadd; fLocalItemsAdded++; aSyncItemP->setSyncOp(sop_add); // set correct op do_add_slow: remainsvisible=true; // should remain visible ok=logicProcessRemoteItem(aSyncItemP,aStatusCommand,remainsvisible); // add to local database NOW CHECK_FOR_AGAIN(LOCAL_ITEM_ADD_SLOW); break; } } // slow sync break; // just in case.... preventadd: // add not allowed, delete remote item instead // - consume original delete aSyncItemP; preventadd2: aStatusCommand.setStatusCode(201); // pretend adding item was successful PDEBUGPRINTFX(DBG_DATA,("Prevented explicit add, returning delete to remote")); ok=true; goto removefromremote; // as we have PREVENTED adding the item, it is not in the map removefromremoteandsyncset: // remove item from local map first engProcessMap(remoteid.c_str(),NULL); removefromremote: // have item removed from remote delitemP = newItemForRemote(itemtypeid); delitemP->setRemoteID(remoteid.c_str()); delitemP->setSyncOp(sop_delete); SendItemAsServer(delitemP); // pass ownership break; default : SYSYNC_THROW(TSyncException("Unknown sync op in TLocalEngineDS::processRemoteItemAsServer")); } // switch if (ok) { DB_PROGRESS_EVENT(this,pev_itemprocessed,fLocalItemsAdded,fLocalItemsUpdated,fLocalItemsDeleted); } else { // if the DB has a error string to show, add it here aStatusCommand.addItemString(lastDBErrorText().c_str()); } // done return ok; } // TLocalEngineDS::engProcessRemoteItemAsServer /// @brief called at end of request processing, should be used to save suspend state /// @note superdatastore does it itself to have correct order of things happening void TLocalEngineDS::engRequestEnded(void) { #ifdef SUPERDATASTORES if (fAsSubDatastoreOf) return; #endif // If DS 1.2: Make sure everything is ready for a resume in case there's an abort (implicit Suspend) // before the next request. Note that the we cannot wait for session timeout, as the resume attempt // from the client probably arrives much earlier. // Note: It is ESSENTIAL not to save the state until sync set is ready, because saving state will // cause DB access, and DB access is not permitted while sync set is possibly still loading // (possibly in a separate thread!). So dssta_syncmodestable (as in <=3.0.0.2) is NOT enough here! if (testState(dssta_syncsetready)) { // make sure all unsent items are marked for resume engSaveSuspendState(false); // only if not already aborted } // let datastore prepare for end of request dsRequestEnded(); // and let it prepare for end of this thread as well dsThreadMayChangeNow(); } // TLocalEngineDS::engRequestEnded #endif // SYSYNC_SERVER #ifdef SYSYNC_CLIENT // Client Case // =========== // process sync operation from server with specified sync item // (according to current sync mode of local datastore) // - returns true (and unmodified or non-200-successful status) if // operation could be processed regularily // - returns false (but probably still successful status) if // operation was processed with internal irregularities, such as // trying to delete non-existant item in datastore with // incomplete Rollbacks (which returns status 200 in this case!). bool TLocalEngineDS::engProcessRemoteItemAsClient( TSyncItem *aSyncItemP, TStatusCommand &aStatusCommand // status, must be set to correct status code (ok / error) ) { string remoteid,localid; bool ok; bool remainsvisible; // send event and check for user abort #ifdef PROGRESS_EVENTS if (!DB_PROGRESS_EVENT(this,pev_itemreceived,++fItemsReceived,fRemoteNumberOfChanges,0)) { fSessionP->AbortSession(500,true,LOCERR_USERABORT); // this also causes datastore to be aborted } if (!SESSION_PROGRESS_EVENT(fSessionP,pev_suspendcheck,NULL,0,0,0)) { fSessionP->SuspendSession(LOCERR_USERSUSPEND); } #endif // check if datastore is aborted if (CheckAborted(aStatusCommand)) return false; // init behaviour vars (these are normally used by server only, // but must be initialized correctly for client as well as descendants might test them fPreventAdd = false; fIgnoreUpdate = false; TSyncOperation syncop; LocalItemOp op; TLocalSyncItemAux *aux = static_cast(aSyncItemP->getAux(TSyncItem::LOCAL_ENGINE)); if (aux) { // Resuming the function call: restore variables, jump to store // method call. remainsvisible = aux->fRemainsVisible; syncop = aux->fSyncOp; remoteid = aux->fRemoteID; op = aux->fOp; fCurrentSyncOp = aux->fCurrentSyncOp; fEchoItemOp = aux->fEchoItemOp; fItemConflictStrategy = aux->fItemConflictStrategy; fForceConflict = aux->fForceConflict; fDeleteWins = aux->fDeleteWins; fRejectStatus = aux->fRejectStatus; PDEBUGPRINTFX(DBG_DATA,("%s item operation resumed",SyncOpNames[syncop])); switch (op) { case LOCAL_ITEM_DELETE: goto do_delete; case LOCAL_ITEM_ADD_NORMAL: goto do_add; case LOCAL_ITEM_REPLACE: goto do_replace; // Not used in client: case LOCAL_ITEM_ADD_DELETED: case LOCAL_ITEM_ADD_DUPLICATE: case LOCAL_ITEM_REPLACE_MERGED: case LOCAL_ITEM_REPLACE_FROM_CLIENT: case LOCAL_ITEM_ADD_MERGED: case LOCAL_ITEM_REPLACE_MERGED2: case LOCAL_ITEM_ADD_SLOW: break; }; } if (false) { // Prepare for resuming the function call. Will only be reached // via goto with "op" set to something identifying the source of // the jump. again: if (!aux) { aux = new TLocalSyncItemAux; aSyncItemP->setAux(TSyncItem::LOCAL_ENGINE, aux); } aux->fRemainsVisible = remainsvisible; aux->fSyncOp = syncop; aux->fRemoteID = remoteid; aux->fOp = op; aux->fCurrentSyncOp = fCurrentSyncOp; aux->fEchoItemOp = fEchoItemOp; aux->fItemConflictStrategy = fItemConflictStrategy; aux->fForceConflict = fForceConflict; aux->fDeleteWins = fDeleteWins; aux->fRejectStatus = fRejectStatus; aStatusCommand.setStatusCode(LOCERR_AGAIN); return false; } // get operation out of item syncop=aSyncItemP->getSyncOp(); // show DEBUGPRINTFX(DBG_DATA,("%s item operation received",SyncOpNames[syncop])); // check if receiving commands is allowed at all // - must be in correct sync state if (!testState(dssta_syncgendone)) { // Modifications from server not allowed before client has done sync gen // %%% we could possibly relax this one, depending on the DB aStatusCommand.setStatusCode(403); PDEBUGPRINTFX(DBG_ERROR,("Server command not allowed before client has sent entire ")); delete aSyncItemP; return false; } // - must not be one-way if (fSyncMode==smo_fromclient) { // Modifications from server not allowed during update from client only aStatusCommand.setStatusCode(403); ADDDEBUGITEM(aStatusCommand,"Server command not allowed in one-way/refresh from client"); PDEBUGPRINTFX(DBG_ERROR,("Server command not allowed in one-way/refresh from client")); delete aSyncItemP; return false; } else { // silently discard all modifications if readonly if (fReadOnly) { PDEBUGPRINTFX(DBG_ERROR,("Read-Only: silently discarding all modifications")); aStatusCommand.setStatusCode(200); // always ok (but never "added"), so server cannot expect Map delete aSyncItemP; return true; } // let item check itself to catch special cases // - init variables which are used/modified by item checking fItemSizeLimit=-1; // no limit fCurrentSyncOp = syncop; fEchoItemOp = sop_none; fItemConflictStrategy=fSessionConflictStrategy; // get default strategy for this item fForceConflict = false; fDeleteWins = fDSConfigP->fDeleteWins; // default to configured value fRejectStatus = -1; // no rejection // - now check // check reads and possibly modifies: // - fEchoItemOp : if not sop_none, the incoming item is echoed back to the remote with the specified syncop // - fItemConflictStrategy : might be changed from the pre-set datastore default // - fForceConflict : if set, a conflict is forced by adding the corresponding local item (if any) to the list of items to be sent // - fDeleteWins : if set, in a replace/delete conflict delete will win (regardless of strategy) // - fPreventAdd : if set, attempt to add item from remote (even implicitly trough replace) will cause no add but delete of remote item // - fIgnoreUpdate : if set, attempt to update item from remote will be ignored, only adds (also implicit ones) are executed // - fRejectStatus : if set>=0, incoming item is irgnored silently(==0) or with error(!=0) aSyncItemP->checkItem(this); // - check if incoming item should be processed at all if (fRejectStatus>=0) { // now discard the incoming item delete aSyncItemP; PDEBUGPRINTFX(fRejectStatus>=400 ? DBG_ERROR : DBG_DATA,("Item rejected with Status=%hd",fRejectStatus)); if (fRejectStatus>0) { // rejected with status code (not necessarily error) aStatusCommand.setStatusCode(fRejectStatus); if (fRejectStatus>=300) { // non 200-codes are errors ADDDEBUGITEM(aStatusCommand,"Item rejected"); return false; } } // silently rejected return true; } // now perform requested operation switch (syncop) { case sop_soft_delete: case sop_archive_delete: case sop_delete: // delete item fLocalItemsDeleted++; do_delete: remainsvisible=false; // deleted not visible any more ok=logicProcessRemoteItem(aSyncItemP,aStatusCommand,remainsvisible); // delete in local database NOW CHECK_FOR_AGAIN(LOCAL_ITEM_DELETE); break; case sop_copy: // %%% note: this would belong into specific datastore implementation, but is here // now for simplicity as copy isn't used heavily het // retrieve data from local datastore if (!logicRetrieveItemByID(*aSyncItemP,aStatusCommand)) { ok=false; break; } // process like add case sop_add: // add as new item to client DB aStatusCommand.setStatusCode(201); // item added (if no error occurs) fLocalItemsAdded++; // add to local datastore // - get remoteid BEFORE processing item (as logicProcessRemoteItem consumes the item!!) remoteid=aSyncItemP->getRemoteID(); // get remote ID // check if this remoteid is already known from last session - if so, this means that // this add was re-sent and must NOT be executed if (isAddFromLastSession(remoteid.c_str())) { aStatusCommand.setStatusCode(418); // already exists PDEBUGPRINTFX(DBG_ERROR,("Warning: Item with same server-side ID (GUID) was already added in previous session - ignore add now")); delete aSyncItemP; // forget item ok=false; break; } #ifdef OBJECT_FILTERING if (!isAcceptable(aSyncItemP,aStatusCommand)) { delete aSyncItemP; // forget item ok=false; // cannot be accepted break; } #endif do_add: remainsvisible=true; // should remain visible ok=logicProcessRemoteItem(aSyncItemP,aStatusCommand,remainsvisible,&localid); // add to local database NOW, get back local GUID CHECK_FOR_AGAIN(LOCAL_ITEM_ADD_NORMAL); if (!ok) break; // if added (not replaced), we need to send map if (aStatusCommand.getStatusCode()==201) { // really added: remember map entry DEBUGPRINTFX(DBG_ADMIN+DBG_DETAILS,( "engProcessRemoteItemAsClient: add command: adding new entry to fPendingAddMaps - localid='%s', remoteID='%s'", localid.c_str(), remoteid.c_str() )); fPendingAddMaps[localid]=remoteid; } ok=true; // fine break; case sop_replace: // - replace item in client fLocalItemsUpdated++; aSyncItemP->setSyncOp(sop_replace); #ifdef OBJECT_FILTERING if (!isAcceptable(aSyncItemP,aStatusCommand)) { ok=false; // cannot be accepted break; } #endif // - get remoteid BEFORE processing item (as logicProcessRemoteItem consumes the item!!), // in case replace is converted to add and we need to register a map entry. remoteid=aSyncItemP->getRemoteID(); // get remote ID do_replace: remainsvisible=true; // should remain visible ok=logicProcessRemoteItem(aSyncItemP,aStatusCommand,remainsvisible,&localid); // replace in local database NOW CHECK_FOR_AGAIN(LOCAL_ITEM_REPLACE); // if added (not replaced), we need to send map if (aStatusCommand.getStatusCode()==201) { // Note: logicProcessRemoteItem should NOT do an add if we have no remoteid, but return 404. // The following check is just additional security. // really added: remember map entry if server sent remoteID (normally, it won't for Replace) if (!remoteid.empty()) { // we can handle that, as remote sent us the remoteID we need to map it correctly DEBUGPRINTFX(DBG_ADMIN+DBG_DETAILS,( "engProcessRemoteItemAsClient: replace command for unknown localID but with remoteID -> adding new entry to fPendingAddMaps - localid='%s', remoteID='%s'", localid.c_str(), remoteid.c_str() )); fPendingAddMaps[localid]=remoteid; } else { // we cannot handle this (we shouldn't have, in logicProcessRemoteItem!!) aStatusCommand.setStatusCode(510); ok=false; } } break; // fine, ok = irregularity status default: SYSYNC_THROW(TSyncException("Unknown sync op in TLocalEngineDS::processRemoteItemAsClient")); } // switch // processed if (ok) { DB_PROGRESS_EVENT(this,pev_itemprocessed,fLocalItemsAdded,fLocalItemsUpdated,fLocalItemsDeleted); } else { // if the DB has a error string to show, add it here aStatusCommand.addItemString(lastDBErrorText().c_str()); } return ok; } } // TLocalEngineDS::processRemoteItemAsClient // client case: called whenever outgoing Message of Sync Package starts void TLocalEngineDS::engClientStartOfSyncMessage(void) { // is called for all local datastores, even inactive ones, so check state first if (testState(dssta_dataaccessstarted) && !isAborted()) { // only alerted non-sub datastores will start a command here, ONCE // if there are pending maps, they will be sent FIRST if (fRemoteDatastoreP) { if (!testState(dssta_clientsyncgenstarted)) { // shift state to syncgen started // NOTE: if all sync commands can be sent at once, // state will change again by issuing , so // it MUST be changed here (not after issuing!) changeState(dssta_clientsyncgenstarted,true); // - make sure remotedatastore has correct full name fRemoteDatastoreP->setFullName(getRemoteDBPath()); // an interrupted command at this point is a map command - continueIssue() will take care if (!fSessionP->isInterrupedCmdPending() && numUnsentMaps()>0) { // Check for pending maps from previous session (even in DS 1.0..1.1 case this is possible) fUnconfirmedMaps.clear(); // no unconfirmed maps left... fLastSessionMaps.clear(); // ...and no lastSessionMaps yet: all are in pendingMaps // if this is a not-resumed slow sync, pending maps must not be sent, but discarded if (isSlowSync() && !isResuming()) { // forget the pending maps PDEBUGPRINTFX(DBG_HOT,("There are %ld cached map entries from last Session, but this is a non-resumed slow sync: discard them",(long)numUnsentMaps())); fPendingAddMaps.clear(); } else { // - now sending pending (cached) map commands from previous session // Note: if map command was already started, the // finished(), continueIssue() mechanism will make sure that // more commands are generated. This mechanism will also make // sure that outgoing package cannot get until // map is completely sent. // Note2: subdatastores do not generate their own map commands, // but are called by superdatastore for contributing to united map if (!isSubDatastore()) { PDEBUGBLOCKFMT(("LastSessionMaps","Now sending cached map entries from last Session","datastore=%s",getName())); TMapCommand *mapcmdP = new TMapCommand( fSessionP, this, // local datastore fRemoteDatastoreP // remote datastore ); // issue ISSUE_COMMAND_ROOT(fSessionP,mapcmdP); PDEBUGENDBLOCK("LastSessionMaps"); } } } // Now, send sync command (unless we are a subdatastore, in this case the superdatastore will take care) if (!isSubDatastore()) { // Note: if sync command was already started, the // finished(), continueIssue() mechanism will make sure that // more commands are generated // Note2: subdatastores do not generate their own sync commands, // but switch to dssta_client/serversyncgenstarted for contributing to united sync command TSyncCommand *synccmdP = new TSyncCommand( fSessionP, this, // local datastore fRemoteDatastoreP // remote datastore ); // issue ISSUE_COMMAND_ROOT(fSessionP,synccmdP); } } } else { PDEBUGPRINTFX(DBG_ERROR,("engClientStartOfSyncMessage can't start sync phase - missing remotedatastore")); changeState(dssta_idle,true); // force to idle, nothing happened yet } } // if dsssta_dataaccessstarted and not aborted } // TLocalEngineDS::engClientStartOfSyncMessage // Client only: returns number of unsent map items sInt32 TLocalEngineDS::numUnsentMaps(void) { return fPendingAddMaps.size(); } // TLocalEngineDS::numUnsentMaps // Client only: called whenever outgoing Message starts that may contain commands // @param[in] aNotYetInMapPackage set if we are still in sync-from-server package // @note usually, client starts sending maps while still receiving syncops from server void TLocalEngineDS::engClientStartOfMapMessage(bool aNotYetInMapPackage) { // is called for all local datastores, even inactive ones, so check state first if (testState(dssta_syncgendone) && !isAborted()) { // datastores that have finished generating their // now can start a command here, once (if not isInterrupedCmdPending(), that is, not a map already started) if (fRemoteDatastoreP) { // start a new map command if we don't have any yet and we are not done (dssta_clientmapssent) yet if (!fSessionP->isInterrupedCmdPending() && !testState(dssta_clientmapssent)) { // check if we should start one (that is, if the list is not empty) if (numUnsentMaps()>0) { // - now sending map command // NOTE: if all map commands can be sent at once, // fState will be modified again by issuing , so // it MUST be set here (not after issuing!) // - data access done only if we are in Map package now if (!aNotYetInMapPackage) changeState(dssta_dataaccessdone); // usually already set in engEndOfSyncFromRemote(), but does not harm here // Note: if map command was already started, the // finished(), continueIssue() mechanism will make sure that // more commands are generated. This mechanism will also make // sure that outgoing package cannot get until // map is completely sent. // Note2: subdatastores do not generate their own map commands, // but superdatastore calls their generateMapItem for contributing to united map if (!isSubDatastore()) { TMapCommand *mapcmdP = new TMapCommand( fSessionP, this, // local datastore fRemoteDatastoreP // remote datastore ); // issue ISSUE_COMMAND_ROOT(fSessionP,mapcmdP); } } else { // we need no map items now, but if this is still sync-from-server-package, // we are not done yet if (aNotYetInMapPackage) { DEBUGPRINTFX(DBG_PROTO,("No map command need to be generated now, but still in from server package")); } else { // we are done now DEBUGPRINTFX(DBG_PROTO,("All map commands sending complete")); changeState(dssta_clientmapssent); } } } } // if fRemoteDataStoreP } // if >=dssta_syncgendone } // TLocalEngineDS::engClientStartOfMapMessage // called to mark maps confirmed, that is, we have received ok status for them void TLocalEngineDS::engMarkMapConfirmed(cAppCharP aLocalID, cAppCharP aRemoteID) { // As this is client-only, we don't need to check for tempGUIDs here. // Note: superdatastore has an implementation which dispatches by prefix TStringToStringMap::iterator pos=fUnconfirmedMaps.find(aLocalID); if (pos!=fUnconfirmedMaps.end()) { DEBUGPRINTFX(DBG_ADMIN+DBG_EXOTIC,( "engMarkMapConfirmed: deleting confirmed entry localID='%s', remoteID='%s' from fUnconfirmedMaps", aLocalID, aRemoteID )); // move it to lastsessionmap fLastSessionMaps[(*pos).first]=(*pos).second; // remove it from unconfirmed map fUnconfirmedMaps.erase(pos); } } // TLocalEngineDS::engMarkMapConfirmed // Check if the remoteid was used by an add command not // fully mapped&confirmed in the previous session bool TLocalEngineDS::isAddFromLastSession(cAppCharP aRemoteID) { TStringToStringMap::iterator pos; TStringToStringMap *mapListP; for (int i=0; i<3; i++) { // determine next list to search mapListP = i==0 ? &fPendingAddMaps : (i==1 ? &fUnconfirmedMaps : &fLastSessionMaps); // search it for (pos=mapListP->begin(); pos!=mapListP->end(); ++pos) { if (strcmp((*pos).second.c_str(),aRemoteID)==0) return true; // remoteID known -> is add from last session } } // not found in any of the lists return false; } // TLocalEngineDS::isAddFromLastSession // - called to generate Map items // Returns true if now finished for this datastore // also sets fState to dss_done when finished bool TLocalEngineDS::engGenerateMapItems(TMapCommand *aMapCommandP, cAppCharP aLocalIDPrefix) { #ifdef USE_SML_EVALUATION sInt32 leavefree = fSessionP->getNotUsableBufferBytes(); #else sInt32 freeroom = fSessionP->getFreeCommandSize(); #endif TStringToStringMap::iterator pos=fPendingAddMaps.begin(); PDEBUGBLOCKFMT(("MapGenerate","Generating Map items...","datastore=%s",getName())); do { // check if already done if (pos==fPendingAddMaps.end()) break; // done // get ID string locID = (*pos).first; dsFinalizeLocalID(locID); // make sure we have the permanent version in case datastore implementation did deliver temp IDs // create prefixed version of ID string prefixedLocID; AssignString(prefixedLocID, aLocalIDPrefix); // init with prefix (if any) prefixedLocID += locID; // append local ID // add it to map command aMapCommandP->addMapItem(prefixedLocID.c_str(),(*pos).second.c_str()); // check if we could send this command #ifdef USE_SML_EVALUATION if ( (aMapCommandP->evalIssue( fSessionP->peekNextOutgoingCmdID(), fSessionP->getOutgoingMsgID() ) // what is left in buffer after sending Map so far >=leavefree) // all this must still be more than what we MUST leave free ) #else if (freeroom>aMapCommandP->messageSize()) #endif { // yes, it should work PDEBUGPRINTFX(DBG_PROTO,( "Mapitem generated: localID='%s', remoteID='%s'", prefixedLocID.c_str(), (*pos).second.c_str() )); // move sent ones to unconfirmed list (Note: use real locID, without prefix!) fUnconfirmedMaps[locID]=(*pos).second; // remove item from to-be-sent list TStringToStringMap::iterator temp_pos = pos++; // make copy and set iterator to next fPendingAddMaps.erase(temp_pos); // now entry can be deleted (N.M. Josuttis, pg204) } else { // no room for this item in this message, interrupt now // - delete already added item again aMapCommandP->deleteLastMapItem(); // - interrupt here PDEBUGPRINTFX(DBG_PROTO,("Interrupted generating Map items because max message size reached")) PDEBUGENDBLOCK("MapGenerate"); return false; } } while(true); // done // if we are dataaccessdone or more -> end of map phase for this datastore if (testState(dssta_dataaccessdone)) { changeState(dssta_clientmapssent,true); PDEBUGPRINTFX(DBG_PROTO,("Finished generating Map items, server has finished , we are done now")) } #ifdef SYDEBUG // else if we are not yet dssta_syncgendone -> this is the end of a early pending map send else if (!dbgTestState(dssta_syncgendone)) { PDEBUGPRINTFX(DBG_PROTO,("Finished sending cached Map items from last session")) } // otherwise, we are not really finished with the maps yet (but with the current map command) else { PDEBUGPRINTFX(DBG_PROTO,("Finished generating Map items for now, but server still sending ")) } #endif PDEBUGENDBLOCK("MapGenerate"); return true; } // TLocalEngineDS::engGenerateMapItems #endif // SYSYNC_SERVER // - called to mark an already generated (but probably not sent or not yet statused) item // as "to-be-resumed", by localID or remoteID (latter only in server case). // NOTE: This must be repeatable without side effects, as server must mark/save suspend state // after every request (and not just at end of session) void TLocalEngineDS::engMarkItemForResume(cAppCharP aLocalID, cAppCharP aRemoteID, bool aUnSent) { #ifdef SUPERDATASTORES // if we are acting as a subdatastore, aLocalID might be prefixed if (fAsSubDatastoreOf && aLocalID) { // remove prefix aLocalID = fAsSubDatastoreOf->removeSubDSPrefix(aLocalID, this); } #endif #ifdef SYSYNC_SERVER // Now mark for resume if (IS_SERVER && aLocalID && *aLocalID) { // localID can be a translated localid at this point (for adds), so check for it string localid=aLocalID; obtainRealLocalID(localid); logicMarkItemForResume(localid.c_str(), aRemoteID, aUnSent); } else #endif { // localID not used or client (which never has tempGUIDs) logicMarkItemForResume(aLocalID, aRemoteID, aUnSent); } } // TLocalEngineDS::engMarkItemForResume // - called to mark an already generated (but probably not sent or not yet statused) item // as "to-be-resent", by localID or remoteID (latter only in server case). void TLocalEngineDS::engMarkItemForResend(cAppCharP aLocalID, cAppCharP aRemoteID) { #ifdef SUPERDATASTORES // if we are acting as a subdatastore, aLocalID might be prefixed if (fAsSubDatastoreOf && aLocalID) { // remove prefix aLocalID = fAsSubDatastoreOf->removeSubDSPrefix(aLocalID, this); } #endif // a need to resend is always a problem with the remote (either explicit non-ok status // received or implicit like data size too big to be sent at all due to maxmsgsize or // maxobjsize restrictions. fRemoteItemsError++; // now mark for resend #ifdef SYSYNC_SERVER if (IS_SERVER && aLocalID && *aLocalID) { // localID can be a translated localid at this point (for adds), so check for it string localid=aLocalID; obtainRealLocalID(localid); logicMarkItemForResend(localid.c_str(), aRemoteID); } else #endif { // localID not used or client (which never has tempGUIDs) logicMarkItemForResend(aLocalID, aRemoteID); } } // TLocalEngineDS::engMarkItemForResend // @brief save everything needed to resume later, in case we get suspended /// - Might be called multiple times during a session, must make sure every time /// that the status is correct, that is, previous suspend state is erased localstatus TLocalEngineDS::engSaveSuspendState(bool aAnyway) { // only save here if not aborted already (aborting saves the state immediately) // or explicitly requested if (aAnyway || !isAborted()) { // only save if DS 1.2 and supported by DB if ((fSessionP->getSyncMLVersion()>=syncml_vers_1_2) && dsResumeSupportedInDB()) { PDEBUGBLOCKFMT(("SaveSuspendState","Saving state for suspend/resume","datastore=%s",getName())); // save alert state (if not explicitly prevented) fResumeAlertCode=fPreventResuming ? 0 : fAlertCode; if (fResumeAlertCode) { if (fPartialItemState!=pi_state_save_outgoing) { // ONLY if we have no request for saving an outgoing item state already, // we possibly need to save a pending incoming item // if there is an incompletely received item, let it update Partial Item (fPIxxx) state // (if it is an item of this datastore, that is). if (fSessionP->fIncompleteDataCommandP) fSessionP->fIncompleteDataCommandP->updatePartialItemState(this); } // this makes sure that only ungenerated (but to-be generated) items will be // marked for resume. Items that have been generated in this session (but might // have been marked for resume in a previous session must no longer be marked // after this call. // This also includes saving state for a partially sent item so we could resume it (fPIxxx) logicMarkOnlyUngeneratedForResume(); // then, we need to additionally mark those items for resume which have been // generated, but not yet sent or sent but not received status so far. fSessionP->markPendingForResume(this); } // let datastore make all this persistent // NOTE: this must happen even if we have no suspend state here, // as marked-for-resends need to be saved here as well. localstatus sta=logicSaveResumeMarks(); if (sta!=LOCERR_OK) { PDEBUGPRINTFX(DBG_ERROR,("Error saving suspend state with logicSaveResumeMarks(), status=%hd",sta)); } PDEBUGENDBLOCK("SaveSuspendState"); return sta; } // resume not supported due to datastore or SyncML version<1.2 -> ok anyway PDEBUGPRINTFX(DBG_PROTO,("SaveSuspendState not possible (SyncML<1.2 or not supported by DB)")); } return LOCERR_OK; } // TLocalEngineDS::engSaveSuspendState } // namespace sysync /* end of TLocalEngineDS implementation */ // eof libsynthesis-3.4.0.47.1/src/sysync/localengineds.h000077500000000000000000001713531226375725500217600ustar00rootroot00000000000000/** * @File localengineds.h * * @Author Lukas Zeller (luz@plan44.ch) * * @brief TLocalEngineDS * Abstraction of the local datastore - interface class to the * sync engine. * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * @Date 2005-09-15 : luz : created from localdatastore */ #ifndef LocalEngineDS_H #define LocalEngineDS_H // includes #include "configelement.h" #include "syncitem.h" #include "syncdatastore.h" #include "itemfield.h" // more includes after config classes definitions using namespace sysync; namespace sysync { extern const char * const conflictStrategyNames[]; #ifdef SCRIPT_SUPPORT // publish as derivates might need it extern const TFuncTable DBFuncTable; #endif class TLocalEngineDS; // forward // datatype list entry class TAdditionalDataType { public: TDataTypeConfig *datatypeconfig; bool forRead; bool forWrite; TTypeVariantDescriptor variantDescP; #ifndef NO_REMOTE_RULES string remoteRuleMatch; // remote rule match string #endif }; // datatypes list typedef std::list TAdditionalTypesList; #ifndef NO_REMOTE_RULES // rule match type list entry typedef struct { TSyncItemType *itemTypeP; cAppCharP ruleMatchString; } TRuleMatchTypeEntry; // container types typedef std::list TRuleMatchTypesContainer; // contains rule match item types #endif // type support configuration of that database class TTypeSupportConfig : public TConfigElement { typedef TConfigElement inherited; public: TTypeSupportConfig(const char* aName, TConfigElement *aParentElement); virtual ~TTypeSupportConfig(); // properties // - preferred data types TDataTypeConfig *fPreferredTx; TTypeVariantDescriptor fPrefTxVariantDescP; TDataTypeConfig *fPreferredRx; TTypeVariantDescriptor fPrefRxVariantDescP; // - preferred data type for blind and legacy mode sync attempts TDataTypeConfig *fPreferredLegacy; // - other data types TAdditionalTypesList fAdditionalTypes; #ifndef NO_REMOTE_RULES // - types that are selected when matching with a remote rule TAdditionalTypesList fRuleMatchTypes; #endif // public methods virtual void clear(); #ifdef HARDCODED_CONFIG // add type support bool addTypeSupport( cAppCharP aTypeName, bool aForRead, bool aForWrite, bool aPreferred, cAppCharP aVariant, cAppCharP aRuleMatch=NULL ); #endif protected: // check config elements #ifndef HARDCODED_CONFIG virtual bool localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine); #endif virtual void localResolve(bool aLastPass); }; // TTypeSupportConfig #if defined(SCRIPT_SUPPORT) && defined(SYSYNC_CLIENT) // publish func table for chaining extern const TFuncTable ClientDBFuncTable; #endif typedef list TStringList; // local datastore config class TLocalDSConfig: public TConfigElement { typedef TConfigElement inherited; public: TLocalDSConfig(const char* aName, TConfigElement *aParentElement); virtual ~TLocalDSConfig(); // properties // - ID to identify datastore instance in callbacks and derived // classes implementing multiple interface variants (such as PalmDbDatastore) // and to relate client (profile) target settings with datastores uInt32 fLocalDBTypeID; // - supported datatypes TTypeSupportConfig fTypeSupport; // - conflict strategy TConflictResolution fConflictStrategy; TConflictResolution fSlowSyncStrategy; TConflictResolution fFirstTimeStrategy; // - options bool fReadOnly; // if set, datastore will not write any data (only maps) to local DB (but fake successful status to remote) bool fCanRestart; // if set, then the datastore is able to participate in multiple sync sessions; in other words after a successful read/write cycle it is possible to restart at the reading phase set fSyncModes; // all additional, non-standard sync modes #ifndef HARDCODED_CONFIG string fSyncModeBuffer; // only used during XML config parsing #endif bool fReportUpdates; // if set(normal case), updates of server items will be sent to client (can be set to false for example for emails) bool fResendFailing; // if set, items that receive a failure status from the remote will be resent in the next session (if DS 1.2 suspend marks supported by the DB) bool fDeleteWins; // if set, in a replace/delete conflict the delete wins (also see DELETEWINS()) #ifdef SYSYNC_SERVER bool fTryUpdateDeleted; // if set, in a client update with server delete conflict, server tries to update the already deleted item (in case it is just invisible) bool fAlwaysSendLocalID; // always send localID to clients (which gives them opportunity to remap IDs on Replace) TStringList fAliasNames; // list of aliases for this datastore #endif // SYSYNC_SERVER uInt32 fMaxItemsPerMessage; // if >0, limits the number of items sent per SyncML message (useful in case of slow datastores where collecting data might exceed client timeout) #ifdef OBJECT_FILTERING // filtering // - filter applied to items coming from remote party, non-matching // items will be rejected with 415 (unknown format) status // unless fSilentlyDiscardUnaccepted is set to true (then we accept and discard silently) // (outgoing items will be made pass this filter with makePassFilter) string fRemoteAcceptFilter; bool fSilentlyDiscardUnaccepted; // - filter will be applied to items read from the local database, // IN ADDITION to possibly specified target address filtering string fLocalDBFilterConf; // - filter applied to incoming items with makePassFilter // when there is no fSyncSetFilter or when applying fSyncSetFilter // with makePassFilter still does not make item pass. string fMakePassFilter; // - filter to check if item is to be treated as "invisible", // also applied to incoming items to make them invisible // (archive-delete) // %%%%% these notes are from earlier syncVisibility stuff that never // %%%%% worked: // - for delete items going to remote, fSyncVisibiliy=false means that Soft Delete should be // - for delete items coming from remote, fSyncVisibility=false means that Archive delete is requested string fInvisibleFilter; // - filter applied to incoming items if they do pass fInvisibleFilter (i.e. would be invisible) string fMakeVisibleFilter; // - DS 1.2 Filter support ( allowed in Alert, / shown in devInf) bool fDS12FilterSupport; // - Set if date range support is available in this datastore bool fDateRangeSupported; #endif #ifdef SCRIPT_SUPPORT // General DB scripts string fDBInitScript; string fSentItemStatusScript; string fReceivedItemStatusScript; string fAlertScript; string fDBFinishScript; #ifdef SYSYNC_CLIENT string fAlertPrepScript; // function table virtual const TFuncTable *getClientDBFuncTable(void) { return &ClientDBFuncTable; }; #endif // SYSYNC_CLIENT #endif // SCRIPT_SUPPORT #ifndef MINIMAL_CODE // display name string fDisplayName; #endif // public methods // - create appropriate datastore from config, calls addTypeSupport as well virtual TLocalEngineDS *newLocalDataStore(TSyncSession *aSessionP) = 0; // - add type support to datatstore from config virtual void addTypes(TLocalEngineDS *aDatastore, TSyncSession *aSessionP); // - add (probably datastore-specific) limits such as MaxSize and NoTruncate to types // (called by addTypes), usually derived as type limits come from DS implementation virtual void addTypeLimits(TLocalEngineDS *aLocalDatastoreP, TSyncSession *aSessionP); // - reset config to defaults virtual void clear(); // - check for alias names uInt16 isDatastoreAlias(cAppCharP aDatastoreURI); // - returns true for datastores that are abstract, i.e. don't have a backend implementation (like superdatastores, or non-derived localengineds) virtual bool isAbstractDatastore(void) { return true; }; // pure localengineds is abstract. First derivate towards backend (stdlogicds) will override this with "false". protected: // check config elements #ifndef HARDCODED_CONFIG virtual bool localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine); #endif virtual void localResolve(bool aLastPass); }; // TLocalDSConfig // datastore config list typedef std::list TLocalDSList; // forward class TAlertCommand; class TRemoteDataStore; class TSyncOpCommand; /// @brief Local Engine Datastore States /// @Note these states are strictly in sequence as they happen during a sync session, so /// we can use < and > comparisons to check stage of sync process typedef enum { dssta_idle, ///< client&server, inactive, idle (after reset or creation) dssta_clientparamset, ///< client only, client has received params for syncing (dsSetClientSyncParams()) dssta_adminready, ///< client&server, administration data ready (all last & next timestamps/anchors/ids/maps available) dssta_clientsentalert, ///< client only, client has sent alert for sync to server dssta_serveralerted, ///< server only, server has received alert for sync from client dssta_serveransweredalert, ///< server only, server has sent status and response alert for client dssta_clientalertstatused, ///< client only, client has received status for sync alert dssta_clientalerted, ///< client only, client has received response alert from server dssta_syncmodestable, ///< client&server, sync mode is now stable (all alerts and alert statuses are exchanged and processed), server is ready for early maps dssta_dataaccessstarted, ///< client&server, user data access has started (e.g. loading of sync set in progress) dssta_syncsetready, ///< client&server, sync set is ready and can be accessed with logicXXXX sync op calls dssta_clientsyncgenstarted, ///< client only, generation of sync command(s) in client for server has started (possibly, we send some pending maps first) dssta_serverseenclientmods, ///< server only, server has seen all client modifications now dssta_serversyncgenstarted, ///< server only, generation of sync command(s) in server for client has started dssta_syncgendone, ///< client&server, generation of sync command(s) is complete dssta_dataaccessdone, ///< client&server, user data access has ended (no more user data reads or writes, but still maps) dssta_clientmapssent, ///< client only, all maps have been sent to server dssta_admindone, ///< client&server, administration data access done (all anchors, timestamps, maps and stuff saved) dssta_completed, ///< client&server, sync session complete (not necessarily successfully, check isAborted()!), including showing logs etc. numDSStates } TLocalEngineDSState; typedef enum { pi_state_none, ///< no partial item pi_state_loaded_incoming, ///< we have an incoming item loaded from admin data (but not changed) pi_state_loaded_outgoing, ///< we have an outgoing item loaded from admin data (but not changed) pi_state_save_incoming, ///< we must save the incoming item at next suspend pi_state_save_outgoing ///< we must save the outgoing item at next suspend } TPartialItemState; } // end namespace sysync // additional includes here as they need config classes already defined #include "synccommand.h" #include "syncsession.h" namespace sysync { #ifdef SCRIPT_SUPPORT class TScriptContext; class TLDSfuncs; #endif // for engXXXX methods that need only be virtual in case we have superdatastores #ifdef SUPERDATASTORES #define SUPERDS_VIRTUAL virtual class TSuperDataStore; // forward declaration #else #define SUPERDS_VIRTUAL #define TSuperDataStore TLocalEngineDS // to allow parameter for engProcessSyncAlert() #endif /// @brief Local datastore engine and abstraction of actual implementation /// - session and commands only call non-virtual engXXXX members of this class to /// perform any operations on the datastore /// - to perform actual access logic (which might be implemented in different flavors), /// this class calls virtual (usually abstract) logicXXXX members, which are /// implemented in derived classes. class TLocalEngineDS: public TSyncDataStore { typedef TSyncDataStore inherited; friend class TLDSfuncs; friend class TMFTypeFuncs; friend class TSyncSession; friend class TSyncCommand; friend class TSyncOpCommand; friend class TMultiFieldItemType; friend class TTextProfileHandler; friend class TSyncAgent; #ifdef SUPERDATASTORES friend class TSuperDataStore; #endif protected: /// @name dsSyncState member fields defining the sync state of the datastore // /// @{ TLocalEngineDSState fLocalDSState; ///< internal state of the datastore sync process localstatus fAbortStatusCode; ///< status code when engAbortDatastoreSync() was called bool fLocalAbortCause; ///< flag signalling if abort cause was local or remote bool fRemoteAddingStopped; ///< set when no more add commands should be sent to remote (e.g. device full) localstatus fAlertCode; ///< alert code in use by this datastore (for scripts and for suspend) /// @} /// @name dsSyncMode member fields defining the sync mode of the datastore /// @Note These get valid for the first time in dssta_clientinit (for client) or /// dssta_serveralerted (for server), but might change again due to /// detection of slowsync or resume until dssta_syncmodestable is reached // /// @{ TSyncModes fSyncMode; ///< basic Sync mode (twoway, fromclient, fromserver) bool fForceSlowSync; ///< set if external reason wants to force a slow sync even if it is not needed bool fSlowSync; ///< set if slow sync or refresh bool fRefreshOnly; ///< set if local data is refreshed from remote only, that is, no local changes will be sent to remote (can be set independently of apparent fSyncMode) bool fCacheData; ///< only relevant if fRefreshOnly is also set: instead of throwing away /// all data at the start of the sync, apply remote changes and remove /// all local data that the peer doesn't have bool fReadOnly; ///< if set, datastore will not write any user data (but fake successful status to remote) bool fReportUpdates; ///< if NOT set, datastore will not report updates to client (e.g. for email) bool fServerAlerted; ///< set if sync was server alerted bool fResuming; ///< set if this is a resume of a previous session #ifdef SUPERDATASTORES TSuperDataStore *fAsSubDatastoreOf; ///< if set, this points to the superdatastore, and MUST NOT receive any commands from the session directly #endif /// @} /// @name dsSavedAdmin administrative data (anchors, timestamps, maps) as saved or to-be-saved /// @Note These will be loaded and saved be derived classes /// @Note Some of these will be updated from resp. @ref dsCurrentAdmin members at distinct events (suspend, session end, etc.) /// @Note Some of these will be updated during the session, but in a way that does NOT affect the anchoring of current/last session // /// @{ // - anchors, valid at dssta_adminready string fLastRemoteAnchor; ///< last remote anchor (saved remote's next anchor in DB at end of last session) string fLastLocalAnchor; ///< last local anchor (saved local next anchor in DB at end of last session) @note this will be generated as // - suspend state uInt16 fResumeAlertCode; ///< alert code saved at suspend of previous session, 0 if none bool fPreventResuming; ///< can be set by running session to prevent that session can be resumed (e.g. in case of incomplete zapping at "reload device") // - other state info bool fFirstTimeSync; ///< set to true if this is the first sync // - item ID lists (maps) #ifdef SYSYNC_SERVER TStringToStringMap fTempGUIDMap; ///< container for temp GUID to real GUID mapping #endif #ifdef SYSYNC_CLIENT TStringToStringMap fPendingAddMaps; ///< container for map items to be sent to server: fPendingAddMaps[localid]=remoteid; Note: might contain temporary localIDs that must be converted to final ones before using in or saving with dsFinalizeLocalID() TStringToStringMap fUnconfirmedMaps; ///< container for map items already sent to server, but not yet confirmed: fUnconfirmedMaps[localid]=remoteid; TStringToStringMap fLastSessionMaps; ///< container for map items already confirmed, but still needed for duplicate checking:: fLastSessionMaps[localid]=remoteid; #endif // - information about last item sent or received in previously suspended session TSyError fLastItemStatus; ///< final status sent for last item in previously suspended session. string fLastSourceURI; ///< Source LocURI of last item sent in previously suspended session. string fLastTargetURI; ///< Target LocURI of partial item // - resuming chunked item data (send or receive) TPartialItemState fPartialItemState; ///< state of partial item vars uInt32 fPITotalSize; ///< total size of the partially transmitted item, 0 if none uInt32 fPIUnconfirmedSize; ///< size of already received, but probably repeated data - or size of data pending to be (re-)sent uInt32 fPIStoredSize; ///< total size of stored data (some of it might not be confirmed) appPointer fPIStoredDataP; ///< stored data, allocated with smlLibMalloc(). bool fPIStoredDataAllocated; ///< set if stored data was allocated by the session. Otherwise, it is owned by the currently incomplete command /// @} /// @name dsCurrentAdmin current session's admin data (anchors, timestamps, maps) /// @Note These will be copied to @ref dsSavedAdmin members ONLY when a session completes successfully/suspends. /// @Note Admin data is NEVER directly saved or loaded from these /// @Note Derivates will update some of these at dssta_adminready with current time/anchor values // /// @{ // - anchors, valid at dssta_adminready string fNextRemoteAnchor; ///< next remote anchor (sent at Alert by remote) string fNextLocalAnchor; ///< local anchor of this session /// @} /// @name dsFiltering item and syncset filtering /// @Note syncset restriction filtering expressions and limits /// must be evaluated by derived datastore implementations // /// @{ #ifdef OBJECT_FILTERING /// dynamic filter, if set and the datastore cannot handle it directly, all records need to be read /// this filter is good for filter expressions that might change between sync sessions string fSyncSetFilter; /// static filter, only applied to already read items, no need to filter all items string fLocalDBFilter; #ifdef SYNCML_TAF_SUPPORT /// real SyncML-like Target Address Filtering (TAF), set from commands string fTargetAddressFilter; /// internal SyncML-like Target Address Filtering (TAF), set internally by scripts string fIntTargetAddressFilter; #endif // SYNCML_TAF_SUPPORT #ifdef SYSYNC_TARGET_OPTIONS // Date range lineartime_t fDateRangeStart; ///< date range start, 0=none, must be evaluated by derived datastore implementations lineartime_t fDateRangeEnd; ///< date range end, 0=none, must be evaluated by derived datastore implementations /// size limit, -1=none, must be evaluated by derived datastore implementations fieldinteger_t fSizeLimit; /// max item count, 0=none (for example for emails) uInt32 fMaxItemCount; /// no attachments (for example emails) bool fNoAttachments; /// datastore options, can be evaluated in scripts, obtained from /o() CGI in database path string fDBOptions; // free database options #endif // SYSYNC_TARGET_OPTIONS // - filtering needs, initialized by initPostFetchFiltering() bool fTypeFilteringNeeded; bool fFilteringNeeded; bool fFilteringNeededForAll; #endif // OBJECT_FILTERING /// @} /// @name dsItemProcessing item processing parameters and options /// @note these can be influenced by various script functions during the session // /// @{ /// conflict strategy for this datastore in this session /// @note can be modified by datastoreinitscript TConflictResolution fSessionConflictStrategy; fieldinteger_t fItemSizeLimit; ///< size limit for item being processed or generated (initally=fSizeLimit) but can be changed by scripts TSyncOperation fEchoItemOp; ///< if not sop_none, processed item will be echoed back to remote TSyncOperation fCurrentSyncOp; ///< current sync-operation TConflictResolution fItemConflictStrategy; ///< conflict strategy for currently processed item bool fForceConflict; ///< if set, a conflict will be forced bool fDeleteWins; ///< if set, in a replace/delete conflict delete will win (regardless of strategy) bool fPreventAdd; ///< if set, attempt to add item from remote will cause no add but delete of remote item bool fIgnoreUpdate; ///< if set, attempt to update item from remote will be ignored (only adds, also implicit ones) are executed) sInt16 fRejectStatus; ///< if >=0, incoming item will be discarded with this status code (0=silently) #ifdef SCRIPT_SUPPORT /// @{ Type Script support (actual scripts are in the datatypes, but contexts are here as /// same datatype can be used in parallel in different datastores) TScriptContext *fSendingTypeScriptContextP; TScriptContext *fReceivingTypeScriptContextP; ///< @note can be NULL if sending and receiving uses the same context /// @} /// @{ generic datastore-level scripts TScriptContext *fDataStoreScriptContextP; // for executing status check scripts /// @} #endif /// @} /// @name dsCountStats item counting and statistics /// @{ // /// number of changes remote will send (valid if >=0), SyncML 1.1 sInt32 fRemoteNumberOfChanges; /// @{ net data transferred (item data, without any SyncML protocol overhead, meta etc.) sInt32 fIncomingDataBytes; sInt32 fOutgoingDataBytes; /// }@ /// @{ locally performed ops sInt32 fLocalItemsAdded; sInt32 fLocalItemsUpdated; sInt32 fLocalItemsDeleted; sInt32 fLocalItemsError; // items that caused an error to be sent to the remote (and SHOULD be sent again by the remote, or abort the session) /// }@ // @{ remotely performed ops sInt32 fRemoteItemsAdded; sInt32 fRemoteItemsUpdated; sInt32 fRemoteItemsDeleted; sInt32 fRemoteItemsError; // items that had a remote error (and will be resent later) /// }@ #ifdef SYSYNC_SERVER // @{ conflicts sInt32 fConflictsServerWins; sInt32 fConflictsClientWins; sInt32 fConflictsDuplicated; /// slow sync matches sInt32 fSlowSyncMatches; #endif /// @{ item transmission counts sInt32 fItemsSent; sInt32 fItemsReceived; /// }@ /// @} private: /// @name dsOther other members needed for handling the sync /// @{ /// datastore config pointer TLocalDSConfig *fDSConfigP; #ifdef SYSYNC_CLIENT // parameters for syncing with remote DB as client // - local string fLocalDBPath; ///< client, entire path to the local database, which might include subpaths/CGI to subselect records in the local DB // - remote string fDBUser; ///< client, DB layer user name string fDBPassword; ///< client, DB layer password string fRemoteRecordFilterQuery; ///< client, record level filter query bool fRemoteFilterInclusive; ///< client, inclusive filter flag #endif // SYSYNC_CLIENT string fRemoteDBPath; ///< server and client, path of remote DB, for documentary purposes string fIdentifyingDBName; ///< server and client, name with which the to-be-synced DB is identified (important in case of aliases in server) /// remote datastore involved, valid after processSyncCmdAsServer() TRemoteDataStore *fRemoteDatastoreP; /// Remote view if local URI /// - Server case: URI how remote has accessed local, for sending Sync commands back and to /// create devInf datastore name when devInf is queried AFTER being alerted from client /// - Client case: URI of local DB (only used to match commands coming back) string fRemoteViewOfLocalURI; /// time when datastore terminated sync, for statistics only lineartime_t fEndOfSyncTime; // default types of remote datastore for sending/receiving during Sync TSyncItemType *fRemoteReceiveFromLocalTypeP; ///< type used by remote to receive from local TSyncItemType *fRemoteSendToLocalTypeP; ///< type used by remote to send to local TSyncItemType *fLocalSendToRemoteTypeP; ///< type used by local to send to remote TSyncItemType *fLocalReceiveFromRemoteTypeP; ///< type used by local to receive from remote /// @} private: /// reset for re-use without re-creation, used by constructor as well void InternalResetDataStore(void); public: /// constructor TLocalEngineDS(TLocalDSConfig *aDSConfigP, TSyncSession *aSessionP, cAppCharP aName, uInt32 aCommonSyncCapMask=0); /// destructor virtual ~TLocalEngineDS(); /// @name dsProperty property and state querying methods /// @{ #ifndef MINIMAL_CODE // - return display name (descriptive) virtual const char *getDisplayName(void) { return fDSConfigP->fDisplayName.empty() ? getName() : fDSConfigP->fDisplayName.c_str(); }; #endif TLocalEngineDSState getDSState(void) { return fLocalDSState; } #ifdef SYDEBUG cAppCharP getDSStateName(void); static cAppCharP getDSStateName(TLocalEngineDSState aState); bool dbgTestState(TLocalEngineDSState aMinState, bool aNeedExactMatch=false) { return aNeedExactMatch ? fLocalDSState==aMinState : fLocalDSState>=aMinState; }; #endif // get name with which this datastore was identified by the remote cAppCharP getIdentifyingName(void) { return fIdentifyingDBName.c_str(); } /// calculate Sync mode and flags from given alert code /// @note does not affect DS state in any way, nor checks if DS can handle this code. /// (this will be done only when calling setSyncMode()) static localstatus getSyncModeFromAlertCode(TSyError aAlertCode, TSyncModes &aSyncMode, bool &aIsSlowSync, bool &aIsServerAlerted); /// determine if this is a first time sync situation bool isFirstTimeSync(void) { return fFirstTimeSync; }; /// check if sync is started (e.g. background loading of syncset) virtual bool isStarted(bool aWait) { return fLocalDSState>=dssta_dataaccessstarted; }; // single thread version is started when data access is started (and never waits) // called for >=SyncML 1.1 if remote wants number of changes. // Must return -1 if no NOC value can be returned virtual sInt32 getNumberOfChanges(void) { return -1; /* no NOC supported */ }; /// Called at end of sync to determine whether the store already knows /// that it has more changes for the server in the next sync session. /// For example, the TBinFileImplDS looks at its change log to determine that. virtual bool hasPendingChangesForNextSync() { return false; } /// test abort status, datastore is aborted also when session is just suspended bool isAborted(void); /// abort status code with local error code prefix if cause was local TSyError getAbortStatusCode(void) { return fLocalAbortCause ? localError(fAbortStatusCode) : syncmlError(fAbortStatusCode); }; /// test if active bool isActive(void) { return fLocalDSState!=dssta_idle && !isAborted(); }; // test active-in-sync status /// Returns true if this datastore is done with commands (but not necessarily done with maps) virtual bool isSyncDone(void); lineartime_t getEndOfSyncTime() { return fEndOfSyncTime; }; // documentary only! // - sync mode TSyncModes getSyncMode(void) { return fSyncMode; }; ///< get sync mode bool isSlowSync(void) { return fSlowSync; }; ///< true if slow sync bool isResuming(void) { return fResuming; }; ///< true if resuming a previous session bool isRefreshOnly(void) { return fRefreshOnly; }; ///< true if only refreshing with data from remote (no send to remote) bool isCacheData(void) { return fCacheData; }; bool isReadOnly(void) { return fReadOnly; }; ///< true if only reading from local datastore (and ignoring any updates from remote) /// get remote datastore related to this datastore TRemoteDataStore *getRemoteDatastore(void) { return fRemoteDatastoreP; }; /// return remote view of local URI (might be different from what we might think it is locally) cAppCharP getRemoteViewOfLocalURI(void) { return fRemoteViewOfLocalURI.c_str(); }; /// check if this datastore is accessible with given URI /// @note By default, local datastore type is addressed with /// first path element of URI, rest of path might be used /// by derivates to subselect data folders etc. /// @note returns number of characters matched to allow searching to /// detect "better" matches (Oracle server case with /Calendar AND /Calendar/Events) virtual uInt16 isDatastore(const char *aDatastoreURI); /// returns true if this datastore is currently in use as subdatastore of a superdatastore #ifdef SUPERDATASTORES bool isSubDatastore(void) { return fAsSubDatastoreOf!=NULL; }; #else bool isSubDatastore(void) { return false; }; #endif // - data type information TSyncItemType *getLocalSendType(void) { return fLocalSendToRemoteTypeP; }; ///< type used by local to send to remote TSyncItemType *getLocalReceiveType(void) { return fLocalReceiveFromRemoteTypeP; }; ///< type used by local to receive from remote TSyncItemType *getRemoteSendType(void) { return fRemoteSendToLocalTypeP; }; ///< type used by remote to send to local TSyncItemType *getRemoteReceiveType(void) { return fRemoteReceiveFromLocalTypeP; }; ///< type used by remote to receive from local /// get remote DB path cAppCharP getRemoteDBPath(void) { return fRemoteDBPath.c_str(); }; #ifdef SYSYNC_CLIENT /// get local DB path cAppCharP getLocalDBPath(void) { return fLocalDBPath.c_str(); }; #endif /// get datastore config pointer TLocalDSConfig *getDSConfig(void) { return fDSConfigP; }; /// datastore options fieldinteger_t getItemSizeLimit(void) { return fItemSizeLimit; }; bool getNoAttachments(void) { #ifdef SYSYNC_TARGET_OPTIONS return fNoAttachments; #else return false; #endif }; /// @} /// @name engXXXX methods defining the interface to other engine components (session, commands) /// Only these will be called by the engine - the engine will no longer call directly into logicXXXX /// @Note some of these are virtuals ONLY for being derived by superdatastore, NEVER by locic or other derivates /// We use the SUPERDS_VIRTUAL macro for these, which is empty in case we don't have superdatastores, then /// these can be non-virtual. /// @{ // /// reset datastore, but does not end sync nicely /// @note is virtual because derived from TSyncDataStore virtual void engResetDataStore(void); /// flag that sync with this datastore is aborted. Datastore is not yet terminated by this. /// @note calling engAbortDatastoreSync should not cause large activities - all terminating /// activity should be in engTerminateSync(), which will be called later virtual void engAbortDataStoreSync(TSyError aReason, bool aLocalProblem, bool aResumable=true); /// Finish all activity with this datastore /// @note functionality is that of former TLocalDataStore::endOfSync() /// @note if not yet aborted with other reason, datastore now gets aborted with given aErrorStatus /// @note the datastore should perform all activity needed to end the sync SUPERDS_VIRTUAL void engFinishDataStoreSync(localstatus aErrorStatus=LOCERR_OK); /// Terminate all activity with this datastore /// @note may be called repeatedly, relevant shutdown code is executed only once void engTerminateDatastore(localstatus aAbortStatusCode=408); // default to timeout /// called at end of incoming message for all localEngineDS (super or not) /// @note is not virtual, as superdatastore MUST NOT implement it void engEndOfMessage(void) { dsEndOfMessage(); }; // simply call protected virtual chain /// force slow sync void engForceSlowSync(void) { fForceSlowSync=true; }; /// set refresh only mode (do not send to remote) void engSetRefreshOnly(bool b) { fRefreshOnly=b; }; void engSetCacheData(bool b) { fCacheData=b; }; /// set read only mode (do not receive from remote) void engSetReadOnly(bool b) { fReadOnly=b; }; /// can be called to avoid further ADD commands to be sent to remote (device full case, e.g.) void engStopAddingToRemote(void) { fRemoteAddingStopped=true; }; /// can be called to prevent that current session can be resumed later (e.g. when user aborts zapping datastore in client) void preventResuming(void) { fPreventResuming=true; } #ifdef OBJECT_FILTERING /// returns true if DB implementation can filter the standard filters /// (LocalDBFilter, TargetFilter and InvisibleFilter) during database fetch - /// otherwise, fetched items will be filtered after being read from DB. /// Defined as abstract here to make sure derived datastores do implement filtering SUPERDS_VIRTUAL bool engFilteredFetchesFromDB(bool aFilterChanged=false) { return dsFilteredFetchesFromDB(aFilterChanged); }; #endif // called for >=SyncML 1.1 if remote wants number of changes. // Must return -1 if no NOC value can be returned SUPERDS_VIRTUAL sInt32 engGetNumberOfChanges(void) { return getNumberOfChanges(); }; /// Set remote datastore for local datastore /// (must be called before engProcessSyncCmd and engGenerateSyncCmd) SUPERDS_VIRTUAL void engSetRemoteDatastore(TRemoteDataStore *aRemoteDatastoreP); #ifdef SYSYNC_CLIENT /// initialize Sync alert for datastore according to Parameters set with dsSetClientSyncParams() /// @note initializes anchors and makes calls to isFirstTimeSync() valid SUPERDS_VIRTUAL localstatus engPrepareClientSyncAlert(void); /// internal helper to be called by engPrepareClientSyncAlert() from this class and from superdatastore localstatus engPrepareClientDSForAlert(void); /// generate Sync alert for datastore /// @note this could be repeatedly called due to auth failures at beginning of session /// @note this is a NOP for subDatastores (should not be called in this case, anyway) localstatus engGenerateClientSyncAlert(TAlertCommand *&aAlertCommandP); // Init engine for client sync (superdatastore aware) // - determine types to exchange // - make sync set ready SUPERDS_VIRTUAL localstatus engInitForClientSync(void); // - non-superdatastore aware base functionality localstatus engInitDSForClientSync(void); #endif /// Internal events during sync for derived classes /// @note local DB authorisation must be established already before calling these /// - cause loading of all session anchoring info and other admin data (logicMakeAdminReady()) /// fLastRemoteAnchor,fLastLocalAnchor,fNextLocalAnchor; isFirstTimeSync() will be valid after the call /// - in case of superdatastore, consolidates the anchor information from the subdatastores SUPERDS_VIRTUAL localstatus engInitSyncAnchors( cAppCharP aDatastoreURI, ///< local datastore URI cAppCharP aRemoteDBID ///< ID of remote datastore (to find session information in local DB) ); /// process Sync alert for a datastore SUPERDS_VIRTUAL TAlertCommand *engProcessSyncAlert( TSuperDataStore *aAsSubDatastoreOf, ///< if acting as subdatastore, this is the pointer to the superdatastore uInt16 aAlertCode, ///< the alert code const char *aLastRemoteAnchor, ///< last anchor of client const char *aNextRemoteAnchor, ///< next anchor of client const char *aTargetURI, ///< target URI as sent by remote, no processing at all const char *aIdentifyingTargetURI, ///< target URI that was used to identify datastore const char *aTargetURIOptions, ///< option string contained in target URI SmlFilterPtr_t aTargetFilter, ///< DS 1.2 filter, NULL if none const char *aSourceURI, ///< source URI TStatusCommand &aStatusCommand ///< status that might be modified ); /// process status received for sync alert SUPERDS_VIRTUAL bool engHandleAlertStatus(TSyError aStatusCode); /// parse target address options /// @note this will be called BEFORE engInitForSyncOps() localstatus engParseOptions( const char *aTargetURIOptions, ///< option string contained in target URI bool aFromSyncCommand=false ///< must be set when parsing options from target URI ); /// reset all filter settings void resetFiltering(void); /// process SyncML 1.2 style filter localstatus engProcessDS12Filter(SmlFilterPtr_t aTargetFilter); /// initialize reception of syncop commands for datastore /// @note previously, this was implemented as initLocalDatastoreSync in syncsession localstatus engInitForSyncOps( const char *aRemoteDatastoreURI ///< URI of remote datastore ); /// called from command to generate sync sub-commands to be sent to remote /// Returns true if now finished for this datastore /// also changes state to dssta_syncgendone when all sync commands have been generated SUPERDS_VIRTUAL bool engGenerateSyncCommands( TSmlCommandPContainer &aNextMessageCommands, TSmlCommand * &aInterruptedCommandP, const char *aLocalIDPrefix=NULL ); #ifdef SYSYNC_CLIENT /// client only: called whenever outgoing Message of Sync Package starts /// @note should start a sync command for all alerted datastores SUPERDS_VIRTUAL void engClientStartOfSyncMessage(void); /// Client only: called whenever outgoing Message starts that may contain commands /// @param[in] aNotYetInMapPackage set if we are still in sync-from-server package /// @note usually, client starts sending maps while still receiving syncops from server void engClientStartOfMapMessage(bool aNotYetInMapPackage); /// Client only: returns number of unsent map items SUPERDS_VIRTUAL sInt32 numUnsentMaps(void); #endif // SYSYNC_CLIENT #ifdef SYSYNC_SERVER /// server only: called whenever we should start a sync command for all alerted datastores /// if not already started void engServerStartOfSyncMessage(void); /// called to process map commands from client to server /// @note aLocalID or aRemoteID can be NULL - which signifies deletion of a map entry SUPERDS_VIRTUAL localstatus engProcessMap(cAppCharP aRemoteID, cAppCharP aLocalID); #endif // SYSYNC_SERVER /// check is datastore is completely started. /// @param[in] aWait if set, call will not return until either started state is reached /// or cannot be reached within the maximally allowed request processing time left. SUPERDS_VIRTUAL bool engIsStarted(bool aWait) { return isStarted(aWait); }; /// SYNC command bracket start (check credentials if needed) SUPERDS_VIRTUAL bool engProcessSyncCmd( SmlSyncPtr_t aSyncP, // the Sync element TStatusCommand &aStatusCommand, // status that might be modified bool &aQueueForLater // will be set if command must be queued for later (re-)execution ); /// SYNC command bracket end (but another might follow in next message) SUPERDS_VIRTUAL bool engProcessSyncCmdEnd(bool &aQueueForLater); /// called whenever Message of Sync Package ends or after last queued Sync command is executed void engEndOfSyncFromRemote(bool aEndOfAllSyncCommands); /// process SyncML SyncOp command for this datastore /// @return true if regular processing (status can still be non-200!) /// @note this routine does the common pre-processing like conversion to internal item format /// and type checking. The actual work is then done by @ref engProcessRemoteItemAsClient /// or @ref engProcessRemoteItemAsServer bool engProcessSyncOpItem( TSyncOperation aSyncOp, // the operation SmlItemPtr_t aItemP, // the item to be processed SmlMetInfMetInfPtr_t aMetaP, // command-wide meta, if any TStatusCommand &aStatusCommand // pre-set 200 status, can be modified in case of errors ); /// @{ /// process sync operation from remote with specified sync item /// (according to current sync mode of local datastore) /// @note /// - returns true (and unmodified or non-200-successful status) if /// operation could be processed regularily /// - returns false (but probably still successful status) if /// operation was processed with internal irregularities, such as /// trying to delete non-existant item in datastore with /// incomplete Rollbacks (which returns status 200 in this case!). #ifdef SYSYNC_CLIENT bool engProcessRemoteItemAsClient( TSyncItem *aSyncItemP, ///< the item to be processed TStatusCommand &aStatusCommand ///< status, must be set to correct status code (ok / error) ); #endif #ifdef SYSYNC_SERVER bool engProcessRemoteItemAsServer( TSyncItem *aSyncItemP, ///< the item to be processed TStatusCommand &aStatusCommand ///< status, must be set to correct status code (ok / error) ); #endif SUPERDS_VIRTUAL bool engProcessRemoteItem( TSyncItem *syncitemP, TStatusCommand &aStatusCommand ); /// handle status of sync operation bool engHandleSyncOpStatus(TStatusCommand *aStatusCmdP,TSyncOpCommand *aSyncOpCmdP); /// called to mark maps confirmed, that is, we have received ok status for them #ifdef SYSYNC_CLIENT SUPERDS_VIRTUAL void engMarkMapConfirmed(cAppCharP aLocalID, cAppCharP aRemoteID); /// called to generate Map items /// @note Returns true if now finished for this datastore /// @note also sets fState to done when finished SUPERDS_VIRTUAL bool engGenerateMapItems(TMapCommand *aMapCommandP, cAppCharP aLocalIDPrefix); /// Client only: Check if the remoteid was used by an add command not /// fully mapped&confirmed in the previous session bool isAddFromLastSession(cAppCharP aRemoteID); #endif /// called to mark an already generated (but probably not sent or not yet statused) item /// as "to-be-resumed", by localID or remoteID (latter only in server case). /// @note This must be repeatable without side effects, as server must mark/save suspend state /// after every request (and not just at end of session) void engMarkItemForResume(cAppCharP aLocalID, cAppCharP aRemoteID, bool aUnSent); // - called to mark an already generated (but probably not sent or not yet statused) item // as "to-be-resent", by localID or remoteID (latter only in server case). void engMarkItemForResend(cAppCharP aLocalID, cAppCharP aRemoteID); // - Set types to be used for sending and receiving items SUPERDS_VIRTUAL void setSendTypeInfo( TSyncItemType *aLocalSendToRemoteTypeP, TSyncItemType *aRemoteReceiveFromLocalTypeP ); SUPERDS_VIRTUAL void setReceiveTypeInfo( TSyncItemType *aLocalReceiveFromRemoteTypeP, TSyncItemType *aRemoteSendToLocalTypeP ); // - init usage of datatypes set with setSendTypeInfo/setReceiveTypeInfo SUPERDS_VIRTUAL localstatus initDataTypeUse(void); // "modern" filtering (in contrast to the "old" fSyncSetFilter et.al. stuff) // - init filtering and check if needed (sets fFilteringNeeded and fFilteringNeededForAll) void initPostFetchFiltering(void); // - check if item passes filter and probably apply some modifications to it bool postFetchFiltering(TSyncItem *aSyncItemP); // add filter keywords and property names to filterCap void addFilterCapPropsAndKeywords(SmlPcdataListPtr_t &aFilterKeywords, SmlPcdataListPtr_t &aFilterProps); #ifdef OBJECT_FILTERING /* %%% outdated // - converts CGI-style filter string to internal filter string syntax // and expands special functions const char *filterCGIToString(cAppCharP aCGI, string &aFilter); */ /// @brief parse "syncml:filtertype-cgi" filter, convert into internal filter syntax /// and possibly sets some special filter options (fDateRangeStart, fDateRangeEnd) /// based on "filterkeywords" available for the type passed (DS 1.2). /// For parsing DS 1.1/1.0 TAF-style filters, aItemType can be NULL, no type-specific /// filterkeywords can be parsed then. /// @return pointer to next character after processing (usually points to terminator) /// @param[in] aCGI the NUL-terminated filter string /// @param[in] aItemTypeP if not NULL, this is the item type the filter applies to const char *parseFilterCGI(cAppCharP aCGI, TSyncItemType *aItemTypeP, string &aFilter); /// @brief check single filter term for DS 1.2 filterkeywords. /// @return true if term still needs to be added to normal filter expression, false if term will be handled otherwise virtual bool checkFilterkeywordTerm( cAppCharP aIdent, bool aAssignToMakeTrue, cAppCharP aOp, bool aCaseInsensitive, cAppCharP aVal, bool aSpecialValue, TSyncItemType *aItemTypeP ); // - called to check if incoming item passes acception filters bool isAcceptable(TSyncItem *aSyncItemP, TStatusCommand &aStatusCommand); // - called to make incoming item pass sync set filtering bool makePassSyncSetFilter(TSyncItem *aSyncItemP); /// @brief called to make incoming item visible /// @return true if now visible bool makeVisible(TSyncItem *aSyncItemP); /// @brief called to make incoming item INvisible /// @return true if now INvisible bool makeInvisible(TSyncItem *aSyncItemP); #endif // log datastore sync result // - Called at end of sync with this datastore virtual void dsLogSyncResult(void); // add support for more data types // (for programatically creating local datastores from specialized TSyncSession derivates) void addTypeSupport(TSyncItemType *aItemTypeP,bool aForRx=true, bool aForTx=true); #ifndef NO_REMOTE_RULES // add data type that overrides normal type selection if string matches active remote rule void addRuleMatchTypeSupport(TSyncItemType *aItemTypeP,cAppCharP aRuleMatchString); #endif // get usage variant for a specified type usage virtual TTypeVariantDescriptor getVariantDescForType(TSyncItemType *aItemTypeP); #ifdef SYSYNC_SERVER /// called at end of request processing in server (derived only by superdatastore) SUPERDS_VIRTUAL void engRequestEnded(void); /// end map operation (derived class might want to rollback) bool MapFinishAsServer( bool aDoCommit, // if not set, entire map operation must be undone TStatusCommand &aStatusCommand // status, must be set on error or non-200-status ) { return true; } #endif /// @} #ifdef DBAPI_TUNNEL_SUPPORT /// @name TunnelXXX methods allowing abstracted access to datastores from UIApi from within a tunnel session /// @{ // virtual TSyError TunnelStartDataRead(cAppCharP aLastToken, cAppCharP aResumeToken) { return LOCERR_NOTIMP; }; virtual TSyError TunnelReadNextItem(ItemID aID, appCharP *aItemData, sInt32 *aStatus, bool aFirst) { return LOCERR_NOTIMP; }; virtual TSyError TunnelReadItem(cItemID aID, appCharP *aItemData) { return LOCERR_NOTIMP; }; virtual TSyError TunnelEndDataRead() { return LOCERR_NOTIMP; }; virtual TSyError TunnelStartDataWrite() { return LOCERR_NOTIMP; }; virtual TSyError TunnelInsertItem(cAppCharP aItemData, ItemID aID) { return LOCERR_NOTIMP; }; virtual TSyError TunnelUpdateItem(cAppCharP aItemData, cItemID aID, ItemID aUpdID) { return LOCERR_NOTIMP; }; virtual TSyError TunnelMoveItem(cItemID aID, cAppCharP aNewParID) { return LOCERR_NOTIMP; }; virtual TSyError TunnelDeleteItem(cItemID aID) { return LOCERR_NOTIMP; }; virtual TSyError TunnelEndDataWrite(bool aSuccess, appCharP *aNewToken) { return LOCERR_NOTIMP; }; virtual void TunnelDisposeObj(void* aMemory) { return; }; virtual TSyError TunnelReadNextItemAsKey(ItemID aID, KeyH aItemKey, sInt32 *aStatus, bool aFirst) { return LOCERR_NOTIMP; }; virtual TSyError TunnelReadItemAsKey(cItemID aID, KeyH aItemKey) { return LOCERR_NOTIMP; }; virtual TSyError TunnelInsertItemAsKey(KeyH aItemKey, ItemID aID) { return LOCERR_NOTIMP; }; virtual TSyError TunnelUpdateItemAsKey(KeyH aItemKey, cItemID aID, ItemID aUpdID) { return LOCERR_NOTIMP; }; virtual TSettingsKeyImpl *newTunnelKey(TEngineInterface *) { return NULL; }; /// @} #endif /// @name dsXXXX (usually abstract) virtuals defining the interface to derived datastore classes (logic, implementation, api) /// These are usually designed such that they should always call inherited::dsXXX to let the entire chain /// of ancestors see the calls /// @{ // public: /// alert possible thread change virtual void dsThreadMayChangeNow(void) {}; // nop at this level #ifdef SYSYNC_CLIENT /// set Sync Parameters. Derivates might override this to pre-process and modify parameters /// (such as adding client settings as CGI to remoteDBPath) virtual bool dsSetClientSyncParams( TSyncModes aSyncMode, bool aSlowSync, const char *aRemoteDBPath, const char *aDBUser = NULL, const char *aDBPassword = NULL, const char *aLocalPathExtension = NULL, const char *aRecordFilterQuery = NULL, bool aFilterInclusive = false ); #endif // SYSYNC_CLIENT protected: /// reset datastore to a re-usable, like new-created state. virtual void dsResetDataStore(void) {}; /// make sure datastore does not need agent any more. /// @note Called while agent is still fully ok, so we must clean up such /// that later call of destructor does NOT access agent any more virtual void announceAgentDestruction(void) { engTerminateDatastore(); }; /// abort datastore (no reset yet, everything is just frozen as it is) virtual void dsAbortDatastoreSync(TSyError aStatusCode, bool aLocalProblem) {}; // nop here /// inform everyone of coming state change virtual localstatus dsBeforeStateChange(TLocalEngineDSState aOldState,TLocalEngineDSState aNewState); /// inform everyone of happened state change virtual localstatus dsAfterStateChange(TLocalEngineDSState aOldState,TLocalEngineDSState aNewState); #ifdef SYSYNC_CLIENT /// finalize local ID (for datastores that can't efficiently produce these at insert) virtual bool dsFinalizeLocalID(string &aLocalID) { return false; /* no change, ID is ok */}; #endif #ifdef OBJECT_FILTERING /// tests if DB implementation can filter the standard filters /// (LocalDBFilter, TargetFilter and InvisibleFilter) during database fetch - /// otherwise, fetched items will be filtered after being read from DB. /// Defined as abstract here to make sure derived datastores do implement filtering /// @param[in] aFilterChanged if true, this signals to the datastore that filter expression might have changed in between virtual bool dsFilteredFetchesFromDB(bool aFilterChanged=false) { return false; }; // datastores can't do this by default /// returns true if DB implementation can also apply special filters like CGI-options /// /dr(x,y) etc. during fetching virtual bool dsOptionFilterFetchesFromDB(void) { return false; }; // datastores can't do this by default #endif /// returns true if DB implementation supports resume (saving of resume marks, alert code, pending maps, tempGUIDs) virtual bool dsResumeSupportedInDB(void) { return false; }; /// returns true if DB implementation supports resuming in midst of a chunked item (can save fPIxxx.. and related admin data) virtual bool dsResumeChunkedSupportedInDB(void) { return false; }; /// called when a item in the sync set changes its localID (due to local DB internals) /// Datastore must make sure that possibly cached items get updated virtual void dsLocalIdHasChanged(const char *aOldID, const char *aNewID); /// called when request processing ends virtual void dsEndOfMessage(void) {}; // nop at this level /// called at end of request processing in server /// @note handling of suspend state saving and calling dsThreadMayChangeNow MUST NOT /// be implemented here - engEndOfMessage() takes care of this virtual void dsRequestEnded(void) {}; // nop at this level /// called to confirm a sync operation's completion (ok status from remote received) /// @note aSyncOp passed not necessarily reflects what was sent to remote, but what actually happened virtual void dsConfirmItemOp(TSyncOperation aSyncOp, cAppCharP aLocalID, cAppCharP aRemoteID, bool aSuccess, localstatus aErrorStatus=0); /// @} protected: /// @name logicXXXX (usually abstract) virtuals defining the interface to the datastore logic implementation layer /// These will never be called directly by the engine, but only from engXXX members of this class /// @{ // /// - might be called several times (auth retries at beginning of session) virtual localstatus logicMakeAdminReady(cAppCharP aDataStoreURI, cAppCharP aRemoteDBID) { return LOCERR_NOTIMP; }; /// returns true if logic layer has running threads in the background virtual bool logicHasBackgroundThreads(void) { return false; }; // single thread never has background /// returns true if DB implementation cannot guarantee complete /// rollback of all writes (e.g. if DB must commit at end of message) /// @todo rollbacks are obsolete, kick this one out virtual bool incompleteRollbacksPossible(void) { return false; } /// get conflict resolution strategy. virtual TConflictResolution getConflictStrategy(bool aForSlowSync, bool aForFirstTime=false); #ifdef SYSYNC_SERVER /// check if conflicting item already exist in list of items-to-be-sent-to-client virtual TSyncItem *getConflictingItemByRemoteID(TSyncItem *syncitemP) = 0; virtual TSyncItem *getConflictingItemByLocalID(TSyncItem *syncitemP) = 0; /// called to check if content-matching item from server exists virtual TSyncItem *getMatchingItem(TSyncItem *syncitemP, TEqualityMode aEqMode) = 0; /// called to prevent item to be sent to client in subsequent engGenerateSyncCommands() // item in question should be an item that was returned by getConflictingItemByRemoteID() or getMatchingItem() virtual void dontSendItemAsServer(TSyncItem *syncitemP) = 0; /// called to have additional item sent to remote (DB takes ownership of item) virtual void SendItemAsServer(TSyncItem *aSyncitemP) = 0; /// called for servers when receiving map from client virtual localstatus logicProcessMap(cAppCharP aRemoteID, cAppCharP aLocalID) = 0; #endif /// called to process incoming item operation. /// Method must take ownership of syncitemP in all cases virtual bool logicProcessRemoteItem( TSyncItem *syncitemP, TStatusCommand &aStatusCommand, bool &aVisibleInSyncset, // on entry: tells if resulting item SHOULD be visible; on exit: set if processed item remains visible in the sync set. string *aGUID=NULL // GUID is stored here if not NULL ) = 0; /// called to read a specified item from the server DB (not restricted to set of conflicting items) virtual bool logicRetrieveItemByID( TSyncItem &aSyncItem, ///< item to be filled with data from server. Local or Remote ID must already be set TStatusCommand &aStatusCommand ///< status, must be set on error or non-200-status ) = 0; #ifdef SYSYNC_CLIENT /// client: called to generate sync sub-commands to be sent to server /// Returns true if now finished for this datastore /// also sets fState to dss_syncdone(server)/dss_syncready(client) when finished virtual bool logicGenerateSyncCommandsAsClient( TSmlCommandPContainer &aNextMessageCommands, TSmlCommand * &aInterruptedCommandP, const char *aLocalIDPrefix=NULL ) = 0; #endif #ifdef SYSYNC_SERVER /// server: called to generate sync sub-commands to be sent to client /// Returns true if now finished for this datastore /// also sets fState to dss_syncdone(server)/dss_syncready(client) when finished virtual bool logicGenerateSyncCommandsAsServer( TSmlCommandPContainer &aNextMessageCommands, TSmlCommand * &aInterruptedCommandP, const char *aLocalIDPrefix=NULL ) = 0; #endif /// called to have all non-yet-generated sync commands as "to-be-resumed" virtual void logicMarkOnlyUngeneratedForResume(void) = 0; /// called to mark an already generated (but probably not sent or not yet statused) item /// as "to-be-resumed", by localID or remoteID (latter only in server case). /// @note This must be repeatable without side effects, as server must mark/save suspend state /// after every request (and not just at end of session) virtual void logicMarkItemForResume(cAppCharP aLocalID, cAppCharP aRemoteID, bool aUnSent) = 0; /// called to mark an already sent item as "to-be-resent", e.g. due to temporary /// error status conditions, by localID or remoteID (latter only in server case). virtual void logicMarkItemForResend(cAppCharP aLocalID, cAppCharP aRemoteID) = 0; /// save status information required to possibly perform a resume (as passed to datastore with /// markOnlyUngeneratedForResume() and markItemForResume()) /// (or, in case the session is really complete, make sure that no resume state is left) /// @note Must also save tempGUIDs (for server) and pending/unconfirmed maps (for client) virtual localstatus logicSaveResumeMarks(void) { return LOCERR_NOTIMP; }; // must be derived (or avoided, as in superdatastore) /// do log substitutions virtual void DoLogSubstitutions(string &aLog,bool aPlaintext); /// @} /// @name dsHelpers private/protected helper routines /// These will never be called directly by the engine, but only from engXXX members of this class /// @{ // #ifdef SUPERDATASTORES protected: #else private: #endif /// change datastore state, calls logic layer before and after change localstatus changeState(TLocalEngineDSState aNewState, bool aForceOnError=false); /// test datastore state for minimal or exact state bool testState(TLocalEngineDSState aMinState, bool aNeedExactMatch=false); private: /// get Alert code for current Sync State uInt16 getSyncStateAlertCode(bool aServerAlerted=false, bool aClientMinimal=false); /// initializes Sync state variables localstatus setSyncMode(bool aAsClient, TSyncModes aSyncMode, bool aIsSlowSync, bool aIsServerAlerted); /// initializes Sync state variables and returns error if alert is not supported localstatus setSyncModeFromAlertCode(uInt16 aAlertCode, bool aAsClient); /// check if aborted and if yes, set status with appropriate error code bool CheckAborted(TStatusCommand &aStatusCommand); /// called to show sync statistics in debug log and on console SUPERDS_VIRTUAL void showStatistics(void); /// Parse CGI option #ifdef SYSYNC_TARGET_OPTIONS cAppCharP parseOption( const char *aOptName, const char *aArguments, bool aFromSyncCommand ); #endif #ifndef NO_REMOTE_RULES /// rule match types container TRuleMatchTypesContainer fRuleMatchItemTypes; // contains rule match item types #endif protected: #ifdef SYSYNC_SERVER /// for sending GUIDs (Add command), generate temp GUID which conforms to maxguidsize of remote datastore if needed void adjustLocalIDforSize(string &aLocalID, sInt32 maxguidsize, sInt32 prefixsize); /// for received GUIDs (Map command), obtain real GUID (might be temp GUID due to maxguidsize restrictions) void obtainRealLocalID(string &aLocalID); /// helper to cause database version of an item (as identified by aSyncItemP's ID) to be sent to client /// (aka "force a conflict") TSyncItem *SendDBVersionOfItemAsServer(TSyncItem *aSyncItemP); #endif // SYSYNC_SERVER /// helper to save resume state either at end of request or explicitly at reception of a "suspend" SUPERDS_VIRTUAL localstatus engSaveSuspendState(bool aAnyway); /// Returns true if type information is sufficient to create items to be sent to remote party bool canCreateItemForRemote(void) { return (fLocalSendToRemoteTypeP && fRemoteReceiveFromLocalTypeP); }; /// create SyncItem suitable for being sent from local to remote TSyncItem *newItemForRemote( uInt16 aExpectedTypeID ///< typeid of expected type ); /// helper for derived classes to generate sync op commands TSyncOpCommand *newSyncOpCommand( TSyncItem *aSyncItemP, // the sync item TSyncItemType *aSyncItemTypeP, // the sync item type cAppCharP aLocalIDPrefix // prefix for localID (can be NULL for none) ); /// return pure relative (item) URI (removes absolute part or ./ prefix) /// @note this one is virtual because it is defined in TSyncDataStore virtual cAppCharP DatastoreRelativeURI(cAppCharP aURI); /// obtain new datastore info, returns NULL if none available /// @note this one is virtual because it is defined in TSyncDataStore virtual SmlDevInfDatastorePtr_t newDevInfDatastore(bool aAsServer, bool aWithoutCTCapProps); /// obtain sync capabilities list for datastore /// @note this one is virtual because it is defined in TSyncDataStore virtual SmlDevInfSyncCapPtr_t newDevInfSyncCap(uInt32 aSyncCapMask); /// analyze database name void analyzeName( const char *aDatastoreURI, string *aBaseNameP, string *aTableNameP=NULL, string *aCGIP=NULL ); /// get DB specific error code for last routine call that returned !=LOCERR_OK /// @return platform specific DB error code virtual uInt32 lastDBError(void) { return 0; }; virtual bool isDBError(uInt32 aErrCode) { return aErrCode!=0; } // standard implementation assumes 0=ok /// get error message text showing lastDBError for dbg log, or empty string if none /// @return platform specific DB error text virtual string lastDBErrorText(void); /// @} }; // TLocalEngineDS } // namespace sysync #endif // LocalEngineDS_H // eof libsynthesis-3.4.0.47.1/src/sysync/mimediritemtype.cpp000077500000000000000000000313321226375725500227030ustar00rootroot00000000000000/* * File: mimediritemtype.cpp * * Author: Lukas Zeller (luz@plan44.ch) * * TMimeDirItemType * base class for MIME DIR based content types (vCard, vCalendar...) * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * 2001-06-12 : luz : created * */ // includes #include "prefix_file.h" #include "sysync.h" #include "mimediritemtype.h" #include "vtimezone.h" using namespace sysync; namespace sysync { // mime-DIR mode names const char * const mimeModeNames[numMimeModes] = { "old", "standard" }; // enumeration modes const char * const EnumModeNames[numEnumModes] = { "translate", // translation from value to name and vice versa "prefix", // translation of prefix while copying rest of string "defaultname", // default name when translating from value to name "defaultvalue", // default value when translating from name to value "ignore" // ignore value or name }; // profile modes const char * const ProfileModeNames[numProfileModes] = { "custom", // custom profile "vtimezones", // VTIMEZONE profile(s), expands to a VTIMEZONE for every time zone referenced by convmode TZID fields }; // Config // ====== // MIMEDir-based datatype config TMIMEDirTypeConfig::TMIMEDirTypeConfig(const char* aName, TConfigElement *aParentElement) : TMultiFieldTypeConfig(aName,aParentElement) { clear(); } // TMIMEDirTypeConfig::TMIMEDirTypeConfig TMIMEDirTypeConfig::~TMIMEDirTypeConfig() { clear(); } // TMIMEDirTypeConfig::~TMIMEDirTypeConfig // init defaults void TMIMEDirTypeConfig::clear(void) { // clear inherited inherited::clear(); } // TMIMEDirTypeConfig::clear // init defaults void TMIMEDirTypeConfig::localResolve(bool aLastPass) { if (aLastPass) { // make a casted copy of the profile pointer GET_CASTED_PTR(fMIMEProfileP,TMIMEProfileConfig,fProfileConfigP,DEBUGTEXT("TMIMEDirTypeConfig with non-TMIMEProfileConfig profile","mdit2")); #ifdef CONFIGURABLE_TYPE_SUPPORT if (!fMIMEProfileP) SYSYNC_THROW(TConfigParseException("no 'mimeprofile' found")); #endif } // resolve inherited inherited::localResolve(aLastPass); } // TMIMEDirTypeConfig::localResolve // create Sync Item Type of appropriate type from config TSyncItemType *TMIMEDirTypeConfig::newSyncItemType(TSyncSession *aSessionP, TSyncDataStore *aDatastoreP) { if (!fMIMEProfileP) SYSYNC_THROW(TSyncException(DEBUGTEXT("TMIMEDirTypeConfig: no or wrong-typed profile","mdit1"))); return new TMimeDirItemType( aSessionP, this, fTypeName.c_str(), fTypeVersion.c_str(), aDatastoreP, fMIMEProfileP->fFieldListP ); } // TMIMEDirTypeConfig::newSyncItemType // get a descriptor for selecting a variant of a datatype (if any), NULL=no variant with this name TTypeVariantDescriptor TMIMEDirTypeConfig::getVariantDescriptor(const char *aVariantName) { // variants in MIME-Dir are currently level 1 subprofiles // - we need it here already (we calculate it once again in Resolve) GET_CASTED_PTR(fMIMEProfileP,TMIMEProfileConfig,fProfileConfigP,DEBUGTEXT("TMIMEDirTypeConfig with non-TMIMEProfileConfig profile","mdit2")); const TProfileDefinition *subprofileP = fMIMEProfileP->fRootProfileP->subLevels; while (subprofileP) { if (strucmp(aVariantName,TCFG_CSTR(subprofileP->levelName))==0) { return (TTypeVariantDescriptor) subprofileP; // pointer to subProfile is our descriptor } // next subprofileP=subprofileP->next; } // not found return NULL; } // TMIMEDirTypeConfig::getVariantDescriptor #ifdef CONFIGURABLE_TYPE_SUPPORT // config element parsing bool TMIMEDirTypeConfig::localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine) { // checking the elements /* use profilemode instead if (strucmp(aElementName,"mimedirmode")==0) expectEnum(sizeof(fMimeDirMode),&fMimeDirMode,mimeModeNames,numMimeModes); else */ // - none known here return TMultiFieldTypeConfig::localStartElement(aElementName,aAttributes,aLine); // ok return true; } // TMIMEDirTypeConfig::localStartElement #endif #pragma exceptions reset #undef EXCEPTIONS_HERE #define EXCEPTIONS_HERE TARGET_HAS_EXCEPTIONS /* * Implementation of TMimeDirItemType */ TMimeDirItemType::TMimeDirItemType( TSyncSession *aSessionP, TDataTypeConfig *aTypeConfigP, const char *aCTType, const char *aVerCT, TSyncDataStore *aRelatedDatastoreP, TFieldListConfig *aFieldDefinitions // field definitions ) : TMultiFieldItemType(aSessionP,aTypeConfigP,aCTType,aVerCT,aRelatedDatastoreP,aFieldDefinitions) { // create the profile handler fProfileHandlerP = static_cast(static_cast(aTypeConfigP)->fProfileConfigP->newProfileHandler(this)); // set profile mode fProfileHandlerP->setProfileMode(static_cast(aTypeConfigP)->fProfileMode); fReceivedFieldDefs=false; } // TMimeDirItemType::TMimeDirItemType TMimeDirItemType::~TMimeDirItemType() { // release the profile handler delete fProfileHandlerP; } // TMimeDirItemType::~TMimeDirItemType #ifdef OBJECT_FILTERING // get field index of given filter expression identifier. sInt16 TMimeDirItemType::getFilterIdentifierFieldIndex(const char *aIdentifier, uInt16 aIndex) { // check if explicit field level identifier if (strucmp(aIdentifier,"F.",2)==0) { // explicit field identifier, skip property lookup aIdentifier+=2; } else if (fProfileHandlerP) { // let profile search for fields by profile-defined alternative names sInt16 fid = fProfileHandlerP->getFilterIdentifierFieldIndex(aIdentifier, aIndex); if (fid!=FID_NOT_SUPPORTED) return fid; } // if no field ID found so far, look up in field list return TMultiFieldItemType::getFilterIdentifierFieldIndex(aIdentifier, aIndex); } // TMimeDirItemType::getFilterIdentifierFieldIndex #endif // create new sync item of proper type and optimization for specified target TSyncItem *TMimeDirItemType::internalNewSyncItem(TSyncItemType *aTargetItemTypeP, TLocalEngineDS *aLocalDatastoreP) { // All MimeDirs are stored in MultiFieldItems TMultiFieldItemType *targetitemtypeP; GET_CASTED_PTR(targetitemtypeP,TMultiFieldItemType,aTargetItemTypeP,DEBUGTEXT("TMimeDirItemType::internalNewSyncItem with bad-typed target","mdit6")); MP_RETURN_NEW(TMultiFieldItem,DBG_OBJINST,"TMultiFieldItem",TMultiFieldItem(this,targetitemtypeP)); } // TMimeDirItemType::internalNewSyncItem // fill in SyncML data (but leaves IDs empty) bool TMimeDirItemType::internalFillInData( TSyncItem *aSyncItemP, // SyncItem to be filled with data SmlItemPtr_t aItemP, // SyncML toolkit item Data to be converted into SyncItem (may be NULL if no data, in case of Delete or Map) TLocalEngineDS *aLocalDatastoreP, // local datastore TStatusCommand &aStatusCmd // status command that might be modified in case of error ) { // check type TMultiFieldItem *itemP; GET_CASTED_PTR(itemP,TMultiFieldItem,aSyncItemP,DEBUGTEXT("TMimeDirItemType::internalFillInData: incompatible item class","mdit7")); // process data if any if (aItemP->data) { // set related datastore so handler can access datastore/session specific datastore state fProfileHandlerP->setRelatedDatastore(aLocalDatastoreP); // parse data stringSize sz; cAppCharP t = smlPCDataToCharP(aItemP->data,&sz); if (!fProfileHandlerP->parseText(t,sz,*itemP)) { // format error aStatusCmd.setStatusCode(415); // Unsupported media type or format ADDDEBUGITEM(aStatusCmd,"Error parsing MIME-DIR content"); return false; } } else { // no data aStatusCmd.setStatusCode(412); // incomplete command ADDDEBUGITEM(aStatusCmd,"No data found in item"); return false; } // let ancestor process data as well return TMultiFieldItemType::internalFillInData(aSyncItemP,aItemP,aLocalDatastoreP,aStatusCmd); } // TMimeDirItemType::internalFillInData // sets data and meta from SyncItem data, but leaves source & target untouched bool TMimeDirItemType::internalSetItemData( TSyncItem *aSyncItemP, // the syncitem to be represented as SyncML SmlItemPtr_t aItem, // item with NULL meta and NULL data TLocalEngineDS *aLocalDatastoreP // local datastore ) { // check type TMultiFieldItem *itemP; GET_CASTED_PTR(itemP,TMultiFieldItem,aSyncItemP,DEBUGTEXT("TMimeDirItemType::internalSetItemData: incompatible item class","mdit8")); // let ancestor prepare first if (!TMultiFieldItemType::internalSetItemData(aSyncItemP,aItem,aLocalDatastoreP)) return false; // set related datastore so handler can access datastore/session specific datastore state fProfileHandlerP->setRelatedDatastore(aLocalDatastoreP); // generate data item string dataitem; fProfileHandlerP->generateText(*itemP,dataitem); // put data item into opaque/cdata PCData aItem->data=newPCDataStringX((const uInt8 *)dataitem.c_str(),true); // can't go wrong return true; } // TMimeDirItemType::internalSetItemData bool TMimeDirItemType::parseForProperty(SmlItemPtr_t aItemP, const char *aPropName, string &aString) { if (aItemP && aItemP->data) return parseForProperty(smlPCDataToCharP(aItemP->data),aPropName,aString); else return false; } // TMimeDirItemType::parseForProperty // scan Data item for specific property (used for quick type tests) bool TMimeDirItemType::parseForProperty(const char *aText, const char *aPropName, string &aString) { return static_cast(fProfileHandlerP)->parseForProperty(aText, aPropName, aString); } // TMimeDirItemType::parseForProperty // generates SyncML-Devinf property list for type SmlDevInfCTDataPropListPtr_t TMimeDirItemType::newCTDataPropList(TTypeVariantDescriptor aVariantDescriptor) { // let profile handle that return fProfileHandlerP->newCTDataPropList(aVariantDescriptor, this); } #ifdef OBJECT_FILTERING // Filtering: add keywords and property names to filterCap void TMimeDirItemType::addFilterCapPropsAndKeywords(SmlPcdataListPtr_t &aFilterKeywords, SmlPcdataListPtr_t &aFilterProps, TTypeVariantDescriptor aVariantDescriptor) { fProfileHandlerP->addFilterCapPropsAndKeywords(aFilterKeywords, aFilterProps, aVariantDescriptor, this); // add basics inherited::addFilterCapPropsAndKeywords(aFilterKeywords,aFilterProps,aVariantDescriptor); } // TMimeDirItemType::addFilterCapPropsAndKeywords #endif // OBJECT_FILTERING // Analyze CTCap part of devInf bool TMimeDirItemType::analyzeCTCap(SmlDevInfCTCapPtr_t aCTCapP) { if (TMultiFieldItemType::analyzeCTCap(aCTCapP)) { // let profile check fProfileHandlerP->analyzeCTCap(aCTCapP, this); } #ifdef SYDEBUG if (PDEBUGTEST(DBG_REMOTEINFO+DBG_DETAILS)) { // Show which fields are enabled PDEBUGPRINTFX(DBG_REMOTEINFO,("Field options after CTCap analyzing:")); string finfo; for (sInt16 i=0; inumFields(); i++) { StringObjAppendPrintf(finfo, "- %-20s : %-12s maxoccur=%ld, maxsize=%ld %s%s\n", fFieldDefinitionsP->fFields[i].TCFG_CSTR(fieldname), getFieldOptions(i)->available ? "AVAILABLE" : "n/a", (long)getFieldOptions(i)->maxoccur, (long)getFieldOptions(i)->maxsize, getFieldOptions(i)->maxsize == FIELD_OPT_MAXSIZE_UNKNOWN ? "(limited, but unknown size)" : (getFieldOptions(i)->maxsize == FIELD_OPT_MAXSIZE_NONE ? "(unlimited)" : ""), getFieldOptions(i)->notruncate ? ", noTruncate" : "" ); } PDEBUGPUTSXX(DBG_REMOTEINFO+DBG_DETAILS,finfo.c_str(),0,true); } #endif return true; } /// @brief helper to create same-typed instance via base class TSyncItemType *TMimeDirItemType::newCopyForSameType( TSyncSession *aSessionP, // the session TSyncDataStore *aDatastoreP // the datastore ) { // create new itemtype of appropriate derived class type that can handle // this type MP_RETURN_NEW(TMimeDirItemType,DBG_OBJINST,"TMimeDirItemType",TMimeDirItemType( aSessionP, fTypeConfigP, getTypeName(), getTypeVers(), aDatastoreP, fFieldDefinitionsP )); } // TMimeDirItemType::newCopyForSameType /// @brief copy CTCap derived info from another SyncItemType /// @return false if item not compatible /// @note required to create remote type variants from ruleMatch type alternatives bool TMimeDirItemType::copyCTCapInfoFrom(TSyncItemType &aSourceItem) { // must be same type as myself or based on the type of myself if (!aSourceItem.isBasedOn(getTypeID())) return false; // not compatible TMimeDirItemType *itemTypeP = static_cast(&aSourceItem); // copy the fieldDefs flag fReceivedFieldDefs = itemTypeP->fReceivedFieldDefs; // other CTCap info is in the field options of MultiFieldItemType return inherited::copyCTCapInfoFrom(aSourceItem); } // TMimeDirItemType::copyCTCapInfoFrom /* end of TMimeDirItemType implementation */ } // namespace sysync // eof libsynthesis-3.4.0.47.1/src/sysync/mimediritemtype.h000077500000000000000000000117301226375725500223500ustar00rootroot00000000000000/* * File: mimediritemtype.h * * Author: Lukas Zeller (luz@plan44.ch) * * TMimeDirItemType * base class for MIME DIR based content types (vCard, vCalendar...) * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * 2001-06-12 : luz : created * */ #ifndef MimeDirItemType_H #define MimeDirItemType_H // includes #include "syncitemtype.h" #include "multifielditemtype.h" #include "mimedirprofile.h" #include namespace sysync { // MIME-dir based datatype class TMIMEDirTypeConfig : public TMultiFieldTypeConfig { typedef TMultiFieldTypeConfig inherited; public: TMIMEDirTypeConfig(const char *aElementName, TConfigElement *aParentElementP); virtual ~TMIMEDirTypeConfig(); // properties // - associated MIME profile (casted version of ancestor's fProfileConfigP) TMIMEProfileConfig *fMIMEProfileP; // public functions // - create Sync Item Type of appropriate type from config virtual TSyncItemType *newSyncItemType(TSyncSession *aSessionP, TSyncDataStore *aDatastoreP); // get a descriptor for selecting a variant of a datatype (if any), NULL=no variant with this name virtual TTypeVariantDescriptor getVariantDescriptor(const char *aVariantName); protected: #ifdef CONFIGURABLE_TYPE_SUPPORT // check config elements virtual bool localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine); #endif virtual void localResolve(bool aLastPass); virtual void clear(); }; // TMIMEDirTypeConfig const uInt16 ity_mimedir=101; // must be unique class TMimeDirItemType: public TMultiFieldItemType { typedef TMultiFieldItemType inherited; friend class TMimeDirProfileHandler; public: // constructor TMimeDirItemType( TSyncSession *aSessionP, TDataTypeConfig *aTypeConfigP, const char *aCTType, const char *aVerCT, TSyncDataStore *aRelatedDatastoreP, TFieldListConfig *aFieldDefinitions // field definitions ); // destructor virtual ~TMimeDirItemType(); // access to type virtual uInt16 getTypeID(void) const { return ity_mimedir; }; virtual bool isBasedOn(uInt16 aItemTypeID) const { return aItemTypeID==ity_mimedir ? true : TMultiFieldItemType::isBasedOn(aItemTypeID); }; // differentiation between implemented and just descriptive TSyncTypeItems virtual bool isImplemented(void) { return true; }; // MIME-DIR is an implementati on // returns true if field options are based on remote devinf (and not just defaults) virtual bool hasReceivedFieldOptions(void) { return fReceivedFieldDefs; }; // helper to create same-typed instance via base class // MUST BE IMPLEMENTED IN ALL DERIVED CLASSES! virtual TSyncItemType *newCopyForSameType( TSyncSession *aSessionP, // the session TSyncDataStore *aDatastoreP // the datastore ); #ifdef OBJECT_FILTERING // filtering // - get field index of given filter expression identifier. virtual sInt16 getFilterIdentifierFieldIndex(const char *aIdentifier, uInt16 aIndex); #endif protected: // member fields TMimeDirProfileHandler *fProfileHandlerP; // CTCap parsing/generation // - analyze CTCap for specific type virtual bool analyzeCTCap(SmlDevInfCTCapPtr_t aCTCapP); /// @brief copy CTCap derived info from another SyncItemType virtual bool copyCTCapInfoFrom(TSyncItemType &aSourceItemP); // - obtain property list for type, returns NULL if none available virtual SmlDevInfCTDataPropListPtr_t newCTDataPropList(TTypeVariantDescriptor aVariantDescriptor); #ifdef OBJECT_FILTERING // - Filtering: add keywords and property names to filterCap virtual void addFilterCapPropsAndKeywords(SmlPcdataListPtr_t &aFilterKeywords, SmlPcdataListPtr_t &aFilterProps, TTypeVariantDescriptor aVariantDesc); #endif // scan for specific property value string (for version check) bool parseForProperty(const char *aText, const char *aPropName, string &aString); bool parseForProperty(SmlItemPtr_t aItemP, const char *aPropName, string &aString); // Item data management // - create new sync item of proper type and optimization for specified target virtual TSyncItem *internalNewSyncItem(TSyncItemType *aTargetItemTypeP, TLocalEngineDS *aLocalDatastoreP); // - fill in SyncML data (but leaves IDs empty) virtual bool internalFillInData( TSyncItem *aSyncItemP, // SyncItem to be filled with data SmlItemPtr_t aItemP, // SyncML toolkit item Data to be converted into SyncItem (may be NULL if no data, in case of Delete or Map) TLocalEngineDS *aLocalDatastoreP, // local datastore TStatusCommand &aStatusCmd // status command that might be modified in case of error ); // - sets data and meta from SyncItem data, but leaves source & target untouched virtual bool internalSetItemData( TSyncItem *aSyncItemP, // the syncitem to be represented as SyncML SmlItemPtr_t aItem, // item with NULL meta and NULL data TLocalEngineDS *aLocalDatastoreP // local datastore ); private: bool fReceivedFieldDefs; }; // TMimeDirItemType } // namespace sysync #endif // MimeDirItemType_H // eof libsynthesis-3.4.0.47.1/src/sysync/mimedirprofile.cpp000066400000000000000000007164651226375725500225210ustar00rootroot00000000000000/* * File: mimedirprofile.cpp * * Author: Lukas Zeller (luz@plan44.ch) * * TMimeDirItemType * base class for MIME DIR based content types (vCard, vCalendar...) * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * 2009-01-09 : luz : created from mimediritemtype.cpp * */ // includes #include "prefix_file.h" #include "sysync.h" #include "vtimezone.h" #include "rrules.h" #include "mimedirprofile.h" #include "mimediritemtype.h" #include "syncagent.h" #include using namespace sysync; namespace sysync { // mime-DIR mode names const char * const mimeModeNames[numMimeModes] = { "old", "standard" }; // VTIMEZONE generation modes const char * const VTimeZoneGenModes[numVTimeZoneGenModes] = { "current", "start", "end", "range", "openend" }; // VTIMEZONE generation modes const char * const VTzIdGenModes[numTzIdGenModes] = { "default", "olson" }; // enumeration modes const char * const EnumModeNames[numEnumModes] = { "translate", // translation from value to name and vice versa "prefix", // translation of prefix while copying rest of string "defaultname", // default name when translating from value to name "defaultvalue", // default value when translating from name to value "ignore" // ignore value or name }; // profile modes const char * const ProfileModeNames[numProfileModes] = { "custom", // custom profile "vtimezones", // VTIMEZONE profile(s), expands to a VTIMEZONE for every time zone referenced by convmode TZID fields }; // Config // ====== #pragma exceptions off // Type registry TMIMEProfileConfig::TMIMEProfileConfig(const char* aName, TConfigElement *aParentElement) : TProfileConfig(aName,aParentElement) { fRootProfileP=NULL; // no profile yet clear(); } // TMIMEProfileConfig::TMIMEProfileConfig TMIMEProfileConfig::~TMIMEProfileConfig() { clear(); } // TMIMEProfileConfig::~TMIMEProfileConfig // init defaults void TMIMEProfileConfig::clear(void) { // init defaults if (fRootProfileP) { delete fRootProfileP; fRootProfileP=NULL; // no profile any more } // init options fUnfloatFloating = false; fVTimeZoneGenMode = vtzgen_current; // show VTIMEZONE valid for current year (i.e. not dependent on record's time stamps) fTzIdGenMode = tzidgen_default; // default TZIDs // reset group building mechanism #ifdef CONFIGURABLE_TYPE_SUPPORT fLastProperty = NULL; fPropertyGroupID = 1; // start at 1 (0=no group) #endif // clear inherited inherited::clear(); } // TMIMEProfileConfig::clear #pragma exceptions reset // handler factory TProfileHandler *TMIMEProfileConfig::newProfileHandler(TMultiFieldItemType *aItemTypeP) { // check if fieldlists match as they should if (aItemTypeP->getFieldDefinitions()!=fFieldListP) { // profile is for another field list, cannot be used for this item type return NULL; } // our handler is the text profile handler return (TProfileHandler *)(new TMimeDirProfileHandler(this,aItemTypeP)); } #ifdef CONFIGURABLE_TYPE_SUPPORT // get conversion mode, virtual, can be overridden by derivates bool TMIMEProfileConfig::getConvMode(cAppCharP aText, sInt16 &aConvMode) { // separate options size_t n=0; // no size cAppCharP op = strchr(aText, '+'); if (op) n = op-aText; // check basic modes if (op && n==0) { // only options, no basic mode aConvMode = CONVMODE_NONE; } else { // first item is basic mode if (strucmp(aText,"none",n)==0) aConvMode = CONVMODE_NONE; else if (strucmp(aText,"version",n)==0) aConvMode = CONVMODE_VERSION; else if (strucmp(aText,"prodid",n)==0) aConvMode = CONVMODE_PRODID; else if (strucmp(aText,"timestamp",n)==0) aConvMode = CONVMODE_TIMESTAMP; else if (strucmp(aText,"date",n)==0) aConvMode = CONVMODE_DATE; else if (strucmp(aText,"autodate",n)==0) aConvMode = CONVMODE_AUTODATE; else if (strucmp(aText,"autoenddate",n)==0) aConvMode = CONVMODE_AUTOENDDATE; else if (strucmp(aText,"tz",n)==0) aConvMode = CONVMODE_TZ; else if (strucmp(aText,"daylight",n)==0) aConvMode = CONVMODE_DAYLIGHT; else if (strucmp(aText,"tzid",n)==0) aConvMode = CONVMODE_TZID; else if (strucmp(aText,"emptyonly",n)==0) aConvMode = CONVMODE_EMPTYONLY; else if (strucmp(aText,"bitmap",n)==0) aConvMode = CONVMODE_BITMAP; else if (strucmp(aText,"multimix",n)==0) aConvMode = CONVMODE_MULTIMIX; else if (strucmp(aText,"blob_b64",n)==0) aConvMode = CONVMODE_BLOB_B64; else if (strucmp(aText,"blob_auto",n)==0) aConvMode = CONVMODE_BLOB_AUTO; else if (strucmp(aText,"mailto",n)==0) aConvMode = CONVMODE_MAILTO; else if (strucmp(aText,"valuetype",n)==0) aConvMode = CONVMODE_VALUETYPE; else if (strucmp(aText,"fullvaluetype",n)==0) aConvMode = CONVMODE_FULLVALUETYPE; else if (strucmp(aText,"rrule",n)==0) aConvMode = CONVMODE_RRULE; else { fail("'conversion' value '%s' is invalid",aText); return false; } } // now check for options flags and or them into conversion value while (op) { aText = op+1; // skip + n = 0; op = strchr(aText, '+'); if (op) n = op-aText; if (strucmp(aText,"extfmt",n)==0) aConvMode |= CONVMODE_FLAG_EXTFMT; else if (strucmp(aText,"millisec",n)==0) aConvMode |= CONVMODE_FLAG_MILLISEC; else { fail("'conversion' option '%s' is invalid",aText); return false; } } return true; } // TMIMEProfileConfig::getConvMode // private helper bool TMIMEProfileConfig::getConvAttrs(const char **aAttributes, sInt16 &aFid, sInt16 &aConvMode, char &aCombSep) { // - get options const char *fnam = getAttr(aAttributes,"field"); if (fnam && *fnam!=0) { // has field spec // - find field ID aFid = fFieldListP->fieldIndex(fnam); if (aFid==VARIDX_UNDEFINED) { fail("'field' '%s' does not exist in field list '%s'",fnam,fFieldListP->getName()); return false; } } // - get conversion mode const char *conv = getAttr(aAttributes,"conversion"); if (conv) { if (!getConvMode(conv,aConvMode)) return false; } // - get combination char const char *comb = getAttr(aAttributes,"combine"); if (comb) { if (strucmp(comb,"no")==0) aCombSep=0; else if (strucmp(comb,"lines")==0) aCombSep='\n'; else if (strlen(comb)==1) aCombSep=*comb; else { fail("'combine' value '%s' is invalid",comb); return false; } } return true; // ok } // TMIMEProfileConfig::getConvAttrs bool TMIMEProfileConfig::getMask(const char **aAttributes, const char *aName, TParameterDefinition *aParamP, TNameExtIDMap &aMask) { const char *m=getAttr(aAttributes,aName); if (m) { while (*m) { // skip comma separators and spaces if (*m==',' || *m<=0x20) { m++; continue; } // decode substring TParameterDefinition *paramP = aParamP; // default param size_t n=0; while(m[n]>0x20 && m[n]!=',') { if (m[n]=='.') { // qualified enum, search param paramP=fOpenProperty->findParameter(m,n); if (!paramP) { fail("Unknown param '%s' referenced in '%s'",m,aName); return false; } m+=n+1; // set start to enum name n=0; // start anew continue; // prevent increment } n++; } if (!paramP) { fail("Enum value must be qualified with parameter name: '%s'",m); return false; } TNameExtIDMap msk = paramP->getExtIDbit(m,n); if (msk==0) { fail("'%s' is not an enum of parameter '%s'",m,paramP->paramname.c_str()); return false; } aMask = aMask | msk; m+=n; // advance pointer } } return true; // ok; } // TMIMEProfileConfig::getMask bool TMIMEProfileConfig::processPosition(TParameterDefinition *aParamP, const char **aAttributes) { // // - get maps TNameExtIDMap hasmap=0; TNameExtIDMap hasnotmap=0; TNameExtIDMap showsmap=0; if (!getMask(aAttributes,"has",aParamP,hasmap)) return false; // failed if (!getMask(aAttributes,"hasnot",aParamP,hasnotmap)) return false; // failed if (!getMask(aAttributes,"shows",aParamP,showsmap)) return false; // failed // - get field sInt16 fid=FID_NOT_SUPPORTED; const char *fnam = getAttr(aAttributes,"field"); if (fnam) { fid = fFieldListP->fieldIndex(fnam); if (fid==VARIDX_UNDEFINED) return !fail("'field' '%s' does not exist in field list '%s'",fnam,fFieldListP->getName()); } // - calculate offset from first specified value field in property sInt16 fidoffs=FID_NOT_SUPPORTED; if (fid>=0) { for (sInt16 k=0; knumValues; k++) { fidoffs=fOpenProperty->convdefs[k].fieldid; if (fidoffs>=0) break; // found field offset } if (fidoffs<0) return !fail("property '%s' does not have any field assigned, cannot use 'position'",fOpenProperty->propname.c_str()); // calc now fidoffs=fid-fidoffs; } // - get repeat and increment sInt16 repeat=1; // no repeat, no rewrite, but check other s when property occurs again. sInt16 incr=1; // inc by 1 sInt16 minshow=-1; // auto mode, same as repeat bool overwriteempty=true; // do not store empty repetitions bool readonly=false; // not just a parsing alternative sInt16 sharecountoffs=0; // no repeat counter sharing // - check special maxrepeat values const char *repval = getAttr(aAttributes,"repeat"); if (repval) { if (strucmp(repval,"rewrite")==0) repeat=REP_REWRITE; #ifdef ARRAYFIELD_SUPPORT else if (strucmp(repval,"array")==0) repeat=REP_ARRAY; #endif else if (!StrToShort(repval,repeat)) return !fail("expected number, 'rewrite' or 'array' in 'repeat'"); } // - increment and minshow if ( !getAttrShort(aAttributes,"increment",incr,true) || !getAttrShort(aAttributes,"minshow",minshow,true) || !getAttrShort(aAttributes,"sharepreviouscount",sharecountoffs,true) ) return !fail("number expected in 'increment', 'minshow' and 'sharepreviouscount'"); // - overwrite empty if (!getAttrBool(aAttributes,"overwriteempty",overwriteempty,true)) return !fail("expected boolean value in 'overwriteempty'"); // - read only position if (!getAttrBool(aAttributes,"readonly",readonly,true)) return !fail("expected boolean value in 'readonly'"); // - create name extension (position) fOpenProperty->addNameExt( fRootProfileP,hasmap,hasnotmap,showsmap,fidoffs, repeat,incr,minshow,overwriteempty,readonly,sharecountoffs ); expectEmpty(); // no contents (and not a separte nest level) return true; // ok } // TMIMEProfileConfig::processPosition // called at end of nested parsing level void TMIMEProfileConfig::nestedElementEnd(void) { // - change mode if (fOpenConvDef) fOpenConvDef=NULL; // done with value spec else if (fOpenParameter) fOpenParameter=NULL; // done with paramater else if (fOpenProperty) fOpenProperty=NULL; // done with property else if (fOpenProfile) { fOpenProfile=fOpenProfile->parentProfile; // back to parent profile (or NULL if root) // groups do not span profiles fLastProperty=NULL; } } // TMIMEProfileConfig::nestedElementEnd // config element parsing bool TMIMEProfileConfig::localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine) { sInt16 nummand; const char *nam; const char *val; const char *fnam; sInt16 fid; sInt16 convmode; char combsep; // MIME profile. This is multi-level and therefore needs // complicated parser. if (fNest==0) { // reset to root level fOpenProfile=NULL; fOpenProperty=NULL; fOpenParameter=NULL; fOpenConvDef=NULL; } // - parse generics // - get MIME-DIR type dependency TMimeDirMode modeDep = numMimeModes; // no mode dependency by default sInt16 m; cAppCharP modeDepName = getAttr(aAttributes,"onlyformode"); if (modeDepName) { if (!StrToEnum(mimeModeNames,numMimeModes,m,modeDepName)) return fail("unknown 'onlyformode' attribute value '%s'",modeDepName); else modeDep=(TMimeDirMode)m; } // - now parse specifics if (fOpenConvDef) { if (strucmp(aElementName,"enum")==0) { // // - get name and value nam = getAttr(aAttributes,"name"); val = getAttr(aAttributes,"value"); // - get mode TEnumMode mode=enm_translate; // default to translate const char *mod=getAttr(aAttributes,"mode"); if (mod) { if (!StrToEnum(EnumModeNames,numEnumModes,m,mod)) return fail("unknown 'mode' '%s'",mod); else mode=(TEnumMode)m; } // - get options bool positional=fOpenParameter && fOpenParameter->extendsname; // default to parameter if (!getAttrBool(aAttributes,"positional",positional,true)) return fail("bad boolean value for 'positional'"); if (fOpenParameter && positional && !fOpenParameter->extendsname) return fail("'parameter' must have set 'positional' to use positional 'enum's"); // check logic if (mode!=enm_default_value && mode!=enm_ignore && (!nam || *nam==0)) return fail("non-default/non-positional 'enum' must have 'name' attribute"); // 1:1 translation shortcut: if no value specified, use name as value if (mode==enm_translate && !val) val=nam; // use name as value // default name and ignore can have no value (prefix can have empty value) if (!positional && mode!=enm_default_name && mode!=enm_ignore && (!val || (*val==0 && mode!=enm_prefix))) return fail("non-default 'enum' must have (possibly non-empty) 'value' attribute"); // - create enum if (positional) fOpenConvDef->addEnumNameExt(fOpenProperty, nam,val,mode); else fOpenConvDef->addEnum(nam,val,mode); expectEmpty(); // no contents (and not a separate nest level) } // none known here else return false; // parent is TConfigElement, no need to call inherited } else if (fOpenParameter) { if (strucmp(aElementName,"value")==0) { // // - set default options fid=FID_NOT_SUPPORTED; convmode = CONVMODE_NONE; combsep = 0; // - get other options of convdef if (!getConvAttrs(aAttributes,fid,convmode,combsep)) return true; // failed // - set convdef fOpenConvDef = fOpenParameter->setConvDef(fid,convmode,combsep); startNestedParsing(); } else if (strucmp(aElementName,"position")==0) { // Position within parameter, enums reference this parameter without // explicitly qualified enum names. To reference enums of other params, // qualified names are allowed. // if (!processPosition(fOpenParameter,aAttributes)) return true; // failed } // none known here else return inherited::localStartElement(aElementName, aAttributes, aLine); // call inherited } else if (fOpenProperty) { if (strucmp(aElementName,"value")==0) { // // - get index sInt16 idx=0; if (!getAttrShort(aAttributes,"index",idx,fOpenProperty->numValues==1)) // optional only for 1-value properties (or lists) return fail("'index' missing or with invalid value"); if (idx>=fOpenProperty->numValues) return fail("'index' out of range (0..%hd)",fOpenProperty->numValues); // - set default options fid=FID_NOT_SUPPORTED; convmode = CONVMODE_NONE; combsep = 0; // - get other options of convdef if (!getConvAttrs(aAttributes,fid,convmode,combsep)) return true; // failed // - set convdef fOpenConvDef = fOpenProperty->setConvDef(idx,fid,convmode,combsep); startNestedParsing(); } else if (strucmp(aElementName,"parameter")==0) { // // - get name nam = getAttr(aAttributes,"name"); if (!nam || *nam==0) return fail("'parameter' must have 'name' attribute"); // - get options bool positional=false; bool defparam=false; bool shownonempty=false; // don't show properties that have only param values, but no main value bool showinctcap=false; // don't show parameter in CTCap by default if ( !getAttrBool(aAttributes,"positional",positional,true) || !getAttrBool(aAttributes,"default",defparam,true) || !getAttrBool(aAttributes,"shownonempty",shownonempty,true) || !getAttrBool(aAttributes,"show",showinctcap,true) || !getAttrBool(aAttributes,"showindevinf",showinctcap,true) // synonymous with "show" for parameters (note that "show" on properties is no longer effective on purpose!) ) return fail("bad boolean value"); // - add parameter fOpenParameter = fOpenProperty->addParam(nam,defparam,positional,shownonempty,showinctcap,modeDep); #ifndef NO_REMOTE_RULES const char *depRuleName = getAttr(aAttributes,"rule"); TCFG_ASSIGN(fOpenParameter->dependencyRuleName,depRuleName); // save name for later resolving #endif startNestedParsing(); } else if (strucmp(aElementName,"position")==0) { // Position outside parameter, enums must reference parameters using // explicitly qualified enum names like "TYPE.HOME" // if (!processPosition(NULL,aAttributes)) return true; // failed } // none known here else return inherited::localStartElement(aElementName, aAttributes, aLine); // call inherited } else if (fOpenProfile) { if (strucmp(aElementName,"subprofile")==0) { // // // - starting a new subprofile starts a new property group anyway fLastProperty=NULL; // - get name nam = getAttr(aAttributes,"name"); if (!nam || *nam==0) return fail("'subprofile' must have 'name' attribute"); // - get profile mode TProfileModes mode = profm_custom; cAppCharP pfmode = getAttr(aAttributes,"mode"); if (pfmode) { if (!StrToEnum(ProfileModeNames,numProfileModes,m,pfmode)) return fail("unknown profile 'mode' '%s'",pfmode); else mode=(TProfileModes)m; } // - check mode dependent params TProfileDefinition *profileP = NULL; // no foreign properties by default if (mode==profm_custom) { // Custom profile // - get number of mandatory properties if (!getAttrShort(aAttributes,"nummandatory",nummand,false)) return fail ("missing or bad 'nummandatory' specification"); // - check if using properties of other profile const char *use = getAttr(aAttributes,"useproperties"); if (use) { profileP = fRootProfileP->findProfile(use); if (!profileP) return fail("unknown profile '%s' specified in 'useproperties'",use); expectEmpty(true); // subprofile is a nest level, so we need to flag that (otherwise, nestedElementEnd() would not get called) } else { // parsing nested elements in this TConfigElement startNestedParsing(); } } else { // non-custom profiles are expected to be empty expectEmpty(true); // subprofile is a nest level, so we need to flag that (otherwise, nestedElementEnd() would not get called) } // - get DevInf visibility options bool showifselectedonly = false; // default: show anyway if (!getAttrBool(aAttributes,"showifselectedonly",showifselectedonly,true)) return fail("bad boolean value for showifselectedonly"); // - create subprofile now fOpenProfile = fOpenProfile->addSubProfile(nam,nummand,showifselectedonly,mode,modeDep); // - add properties of other level if any if (profileP) fOpenProfile->usePropertiesOf(profileP); // - add level control field stuff, if any fnam = getAttr(aAttributes,"field"); if (fnam) { // - "value" is optional, without a value subprofile is activated if field is non-empty val = getAttr(aAttributes,"value"); // - find field fid = fFieldListP->fieldIndex(fnam); if (fid==VARIDX_UNDEFINED) return fail("'field' '%s' does not exist in field list '%s'",fnam,fFieldListP->getName()); // - set level control convdef TConversionDef *cdP = fOpenProfile->setConvDef(fid); // set field ID of level control field if (val) cdP->addEnum("",val,enm_translate); // set value to be set into level control field when level is entered } } else if (strucmp(aElementName,"property")==0) { // // - get name nam = getAttr(aAttributes,"name"); if (!nam || *nam==0) return fail("'property' must have 'name' attribute"); // - check grouping if (!fLastProperty || strucmp(TCFG_CSTR(fLastProperty->propname),nam)!=0) { // first property in group fPropertyGroupID++; // new group ID } #ifndef NO_REMOTE_RULES // - get rule dependency bool isRuleDep=false; const char *depRuleName = getAttr(aAttributes,"rule"); if (depRuleName) { isRuleDep=true; if (strucmp(depRuleName,"other")==0) { // "other" rule (property is active if no other property from the group gets active) depRuleName=NULL; } } #endif // - get number of values sInt16 numval=1; // default to 1 const char *nvs = getAttr(aAttributes,"values"); if (nvs) { if (strucmp(nvs,"list")==0) numval=NUMVAL_LIST; else if (strucmp(nvs,"expandedlist")==0) numval=NUMVAL_REP_LIST; else if (!StrToShort(nvs,numval)) return fail("invalid value in 'values' attribute"); } // - get options bool mandatory = false; bool showprop = true; // show property in devInf by default bool suppressempty = false; bool allowFoldAtSep = false; bool canfilter = false; // 3.2.0.9 onwards: do not show filter caps by default (devInf gets too large) if ( !getAttrBool(aAttributes,"mandatory",mandatory,true) || !getAttrBool(aAttributes,"showindevinf",showprop,true) || // formerly just called "show" (but renamed to make it ineffective in old configs as new engine prevents duplicates automatically) !getAttrBool(aAttributes,"suppressempty",suppressempty,true) || !getAttrBool(aAttributes,"filter",canfilter,true) || !getAttrBool(aAttributes,"foldbetween",allowFoldAtSep,true) ) return fail("bad boolean value"); const char *valsep= getAttr(aAttributes,"valueseparator"); if (!valsep) valsep=";"; // default to semicolon if not defined const char *altvalsep= getAttr(aAttributes,"altvalueseparator"); if (!altvalsep) altvalsep=""; // default to none if not defined // - group field ID sInt16 groupFieldID = FID_NOT_SUPPORTED; // no group field ID by default cAppCharP gfin = getAttr(aAttributes, "groupfield"); if (gfin) { groupFieldID = fFieldListP->fieldIndex(gfin); if (groupFieldID==VARIDX_UNDEFINED) { fail("'groupfield' '%s' does not exist in field list '%s'",gfin,fFieldListP->getName()); return false; } } // - delayed processing sInt16 delayedprocessing=0; // default to 0 if (!getAttrShort(aAttributes,"delayedparsing",delayedprocessing,true)) return fail ("bad 'delayedparsing' specification"); // - create property now and open new level of parsing fOpenProperty=fOpenProfile->addProperty(nam, numval, mandatory, showprop, suppressempty, delayedprocessing, *valsep, fPropertyGroupID, canfilter, modeDep, *altvalsep, groupFieldID, allowFoldAtSep); fLastProperty=fOpenProperty; // for group checking #ifndef NO_REMOTE_RULES // - add rule dependency (pointer will be resolved later) fOpenProperty->dependsOnRemoterule=isRuleDep; fOpenProperty->ruleDependency=NULL; // not known yet TCFG_ASSIGN(fOpenProperty->dependencyRuleName,depRuleName); // save name for later resolving #endif startNestedParsing(); } // none known here else return inherited::localStartElement(aElementName, aAttributes, aLine); // call inherited } else { if (strucmp(aElementName,"profile")==0) { // if (fRootProfileP) return fail("'profile' cannot be defined more than once"); // new profile starts new property group fLastProperty=NULL; // get name nam = getAttr(aAttributes,"name"); if (!nam || *nam==0) return fail("'profile' must have 'name' attribute"); // - get number of mandatory properties if (!getAttrShort(aAttributes,"nummandatory",nummand,false)) return fail ("missing or bad 'nummandatory' specification"); // create root profile fRootProfileP = new TProfileDefinition(NULL,nam,nummand,false,profm_custom,numMimeModes); // root needs no selection to be shown, is always a custom profile, and not mode dependent // parsing nested elements in this TConfigElement fOpenProfile=fRootProfileP; // current open profile startNestedParsing(); } else if (strucmp(aElementName,"unfloattimestamps")==0) expectBool(fUnfloatFloating); else if (strucmp(aElementName,"vtimezonegenmode")==0) expectEnum(sizeof(fVTimeZoneGenMode),&fVTimeZoneGenMode,VTimeZoneGenModes,numVTimeZoneGenModes); else if (strucmp(aElementName,"tzidgenmode")==0) expectEnum(sizeof(fTzIdGenMode),&fTzIdGenMode,VTzIdGenModes,numTzIdGenModes); // none known here else return inherited::localStartElement(aElementName, aAttributes, aLine); } // ok return true; } // TMIMEProfileConfig::localStartElement #ifndef NO_REMOTE_RULES // resolve remote rule dependencies in profile (recursive) static void resolveRemoteRuleDeps(TProfileDefinition *aProfileP, TAgentConfig *aSessionConfigP) { TProfileDefinition *profileP = aProfileP; while (profileP) { // resolve properties TPropertyDefinition *propP = profileP->propertyDefs; while (propP) { // check for rule-dependent props if (propP->dependsOnRemoterule) { propP->ruleDependency=NULL; // assume the "other" rule entry if (!TCFG_ISEMPTY(propP->dependencyRuleName)) { // find remote rule TRemoteRulesList::iterator pos; for(pos=aSessionConfigP->fRemoteRulesList.begin();pos!=aSessionConfigP->fRemoteRulesList.end();pos++) { if (strucmp(TCFG_CSTR(propP->dependencyRuleName),(*pos)->getName())==0) { // found rule by name propP->ruleDependency=(*pos); break; } } if (propP->ruleDependency==NULL) { string s; StringObjPrintf(s,"property '%s' depends on unknown rule '%s'",TCFG_CSTR(propP->propname),TCFG_CSTR(propP->dependencyRuleName)); SYSYNC_THROW(TConfigParseException(s.c_str())); } } // rule specified } // also fix rule-dependent parameters TParameterDefinition *paramP = propP->parameterDefs; while (paramP) { if (!TCFG_ISEMPTY(paramP->dependencyRuleName)) { TRemoteRulesList::iterator pos; for(pos=aSessionConfigP->fRemoteRulesList.begin();pos!=aSessionConfigP->fRemoteRulesList.end();pos++) { if (strucmp(TCFG_CSTR(paramP->dependencyRuleName),(*pos)->getName())==0) { paramP->ruleDependency=(*pos); break; } } if (paramP->ruleDependency==NULL) { string s; StringObjPrintf(s,"parameter '%s' in property '%s' depends on unknown rule '%s'", TCFG_CSTR(paramP->paramname), TCFG_CSTR(propP->propname), TCFG_CSTR(propP->dependencyRuleName)); SYSYNC_THROW(TConfigParseException(s.c_str())); } } paramP = paramP->next; } // next propP=propP->next; } // resolve subprofiles resolveRemoteRuleDeps(profileP->subLevels,aSessionConfigP); // next profileP=profileP->next; } } // resolveRemoteRuleDeps #endif // resolve void TMIMEProfileConfig::localResolve(bool aLastPass) { if (aLastPass) { // check for required settings if (!fRootProfileP) SYSYNC_THROW(TConfigParseException("empty 'mimeprofile' not allowed")); #ifndef NO_REMOTE_RULES // recursively resolve remote rule dependencies in all properties resolveRemoteRuleDeps( fRootProfileP, static_cast(static_cast(getRootElement())->fAgentConfigP) ); #endif } // resolve inherited inherited::localResolve(aLastPass); } // TMIMEProfileConfig::localResolve #endif // CONFIGURABLE_TYPE_SUPPORT // implementation of MIME-DIR info classes #pragma exceptions off #define EXCEPTIONS_HERE 0 TEnumerationDef::TEnumerationDef(const char *aEnumName, const char *aEnumVal, TEnumMode aMode, sInt16 aNameExtID) { next=NULL; TCFG_ASSIGN(enumtext,aEnumName); TCFG_ASSIGN(enumval,aEnumVal); enummode=aMode; nameextid=aNameExtID; } // TEnumerationDef::TEnumerationDef TEnumerationDef::~TEnumerationDef() { // make sure entire chain gets deleted if (next) delete next; } // TEnumerationDef::~TEnumerationDef TConversionDef::TConversionDef() { fieldid=FID_NOT_SUPPORTED; enumdefs=NULL; convmode=0; combineSep=0; } // TConversionDef::TConversionDef TConversionDef::~TConversionDef() { // make sure enum list gets deleted if (enumdefs) delete enumdefs; } // TEnumerationDef::~TEnumerationDef TConversionDef *TConversionDef::setConvDef( sInt16 aFieldId, sInt16 aConvMode, char aCombSep ) { fieldid=aFieldId; convmode=aConvMode; combineSep=aCombSep; return this; } // TConversionDef::setConvDef const TEnumerationDef *TConversionDef::findEnumByName(const char *aName, sInt16 n) const { TEnumerationDef *enumP = enumdefs; TEnumerationDef *defaultenumP = NULL; while(enumP) { // check plain match if ( (enumP->enummode==enm_translate || enumP->enummode==enm_ignore) && strucmp(aName,TCFG_CSTR(enumP->enumtext),n)==0 ) break; // found full match // check prefix match else if ( enumP->enummode==enm_prefix && (TCFG_SIZE(enumP->enumtext)==0 || strucmp(aName,TCFG_CSTR(enumP->enumtext),TCFG_SIZE(enumP->enumtext))==0) ) break; // found prefix match (or prefix entry with no text, which means match as well) // otherwise: remember if this is a default else if (enumP->enummode==enm_default_value) { // default value entry defaultenumP=enumP; // anyway: remember default value entry // allow searching default value by name (for "has","hasnot" parsing via getExtIDbit()) if (!(TCFG_ISEMPTY(enumP->enumtext)) && strucmp(aName,TCFG_CSTR(enumP->enumtext),n)==0) break; // found named default value } // check next enumP=enumP->next; } return enumP ? enumP : defaultenumP; } // TConversionDef::findEnumByName const TEnumerationDef *TConversionDef::findEnumByVal(const char *aVal, sInt16 n) const { TEnumerationDef *enumP = enumdefs; TEnumerationDef *defaultenumP = NULL; while(enumP) { // check full match if ( (enumP->enummode==enm_translate || enumP->enummode==enm_ignore) && strucmp(aVal,TCFG_CSTR(enumP->enumval),n)==0 ) break; // found // check prefix match else if ( enumP->enummode==enm_prefix && (TCFG_SIZE(enumP->enumval)==0 || strucmp(aVal,TCFG_CSTR(enumP->enumval),TCFG_SIZE(enumP->enumval))==0) ) break; // found prefix match (or prefix entry with no value, which means match as well) // remember if this is a default else if (enumP->enummode == enm_default_name) defaultenumP=enumP; // remember default // check next enumP=enumP->next; } return enumP ? enumP : defaultenumP; } // TConversionDef::findEnumByVal void TConversionDef::addEnum(const char *aEnumName, const char *aEnumVal, TEnumMode aMode) { TEnumerationDef **enumPP = &enumdefs; while(*enumPP!=NULL) enumPP=&((*enumPP)->next); // find last in chain *enumPP = new TEnumerationDef(aEnumName,aEnumVal,aMode); // w/o name extension } // TConversionDef::addEnum // add enum for name extension, auto-creates property-unique name extension ID void TConversionDef::addEnumNameExt(TPropertyDefinition *aProp, const char *aEnumName, const char *aEnumVal, TEnumMode aMode) { TEnumerationDef **enumPP = &enumdefs; while(*enumPP!=NULL) enumPP=&((*enumPP)->next); // find last in chain if (aProp->nextNameExt>31) #if EXCEPTIONS_HERE SYSYNC_THROW(TSyncException(DEBUGTEXT("more than 32 name extensions","mdit3"))); #else return; // silently ignore #endif *enumPP = new TEnumerationDef(aEnumName,aEnumVal, aMode, aProp->nextNameExt++); } // TConversionDef::addEnumNameExt TParameterDefinition::TParameterDefinition( const char *aName, bool aDefault, bool aExtendsName, bool aShowNonEmpty, bool aShowInCTCap, TMimeDirMode aModeDep ) { next=NULL; TCFG_ASSIGN(paramname,aName); defaultparam=aDefault; extendsname=aExtendsName; shownonempty=aShowNonEmpty; showInCTCap=aShowInCTCap; modeDependency=aModeDep; #ifndef NO_REMOTE_RULES ruleDependency=NULL; TCFG_CLEAR(dependencyRuleName); #endif } // TParameterDefinition::TParameterDefinition TParameterDefinition::~TParameterDefinition() { if (next) delete next; } // TParameterDefinition::~TParameterDefinition TNameExtIDMap TParameterDefinition::getExtIDbit(const char *aEnumName, sInt16 n) { const TEnumerationDef *enumP=convdef.findEnumByName(aEnumName,n); if (enumP) { return ((TNameExtIDMap)1<nameextid); } return 0; } // TParameterDefinition::getExtIDbit TPropNameExtension::TPropNameExtension( TNameExtIDMap aMusthave_ids, TNameExtIDMap aForbidden_ids, TNameExtIDMap aAddtlSend_ids, sInt16 aFieldidoffs, sInt16 aMaxRepeat, sInt16 aRepeatInc, sInt16 aMinShow, bool aOverwriteEmpty, bool aReadOnly, sInt16 aRepeatID ) { next=NULL; musthave_ids=aMusthave_ids; forbidden_ids=aForbidden_ids; addtlSend_ids=aAddtlSend_ids; fieldidoffs=aFieldidoffs; maxRepeat=aMaxRepeat; repeatInc=aRepeatInc; minShow=aMinShow; overwriteEmpty=aOverwriteEmpty; readOnly=aReadOnly; repeatID=aRepeatID; } // TPropNameExtension::TPropNameExtension TPropNameExtension::~TPropNameExtension() { if (next) delete next; } // TPropNameExtension::~TPropNameExtension TPropertyDefinition::TPropertyDefinition(const char* aName, sInt16 aNumVals, bool aMandatory, bool aShowInCTCap, bool aSuppressEmpty, uInt16 aDelayedProcessing, char aValuesep, char aAltValuesep, uInt16 aPropertyGroupID, bool aCanFilter, TMimeDirMode aModeDep, sInt16 aGroupFieldID, bool aAllowFoldAtSep) { next = NULL; TCFG_ASSIGN(propname,aName); nameExts = NULL; // none yet nextNameExt = 0; // no enums with name extensions defined yet for this property valuelist = false; // no value list by default expandlist = false; // not expanding value list into repeating property by default valuesep = aValuesep; // separator for structured-value and value-list properties altvaluesep = aAltValuesep; // alternate separator for structured-value and value-list properties (for parsing only) allowFoldAtSep = aAllowFoldAtSep; // allow folding at value separators even if it inserts a space at the end of the previous value groupFieldID = aGroupFieldID; // fid for field that contains the group tag (prefix to the property name, like "a" in "a.TEL:079122327") propGroup = aPropertyGroupID; // property group ID // check if this is an unprocessed wildcard property unprocessed = strchr(aName, '*')!=NULL; // check value list if (aNumVals==NUMVAL_LIST || aNumVals==NUMVAL_REP_LIST) { // value list valuelist = true; expandlist = aNumVals==NUMVAL_REP_LIST; numValues = 1; // we accept a single convdef only } else { // individual values numValues = aNumVals; } // create convdefs array convdefs = new TConversionDef[numValues]; parameterDefs = NULL; // none yet mandatory = aMandatory; showInCTCap = aShowInCTCap; canFilter = aCanFilter; suppressEmpty = aSuppressEmpty; delayedProcessing = aDelayedProcessing; modeDependency = aModeDep; #ifndef NO_REMOTE_RULES // not dependent on rule yet (as rules do not exists at TPropertyDefinition creation, // dependency will be added later, if any) dependsOnRemoterule = false; ruleDependency = NULL; #endif } // TPropertyDefinition::TPropertyDefinition TPropertyDefinition::~TPropertyDefinition() { // delete name extensions if (nameExts) delete nameExts; // delete convdefs array if (convdefs) delete [] convdefs; // delete parameter definitions if (parameterDefs) delete parameterDefs; // delete rest of chain if (next) delete next; } // TPropertyDefinition::~TPropertyDefinition TConversionDef *TPropertyDefinition::setConvDef(sInt16 aValNum, sInt16 aFieldId,sInt16 aConvMode,char aCombSep) { if (aValNum<0 || aValNum>=numValues) #if EXCEPTIONS_HERE SYSYNC_THROW(TSyncException(DEBUGTEXT("setConvDef for Property with bad value number","mdit4"))); #else return NULL; // silently ignore #endif return convdefs[aValNum].setConvDef(aFieldId,aConvMode,aCombSep); }; // TPropertyDefinition::TConversionDef void TPropertyDefinition::addNameExt(TProfileDefinition *aRootProfile, // for profile-global RepID generation TNameExtIDMap aMusthave_ids, TNameExtIDMap aForbidden_ids, TNameExtIDMap aAddtlSend_ids, sInt16 aFieldidoffs, sInt16 aMaxRepeat, sInt16 aRepeatInc, sInt16 aMinShow, bool aOverwriteEmpty, bool aReadOnly, sInt16 aShareCountOffs ) { TPropNameExtension **namextPP = &nameExts; while(*namextPP!=NULL) namextPP=&((*namextPP)->next); // find last in chain if (aMinShow<0) { if (aMaxRepeat==REP_ARRAY) aMinShow=0; // by default, show nothing if array is empty else aMinShow=aMaxRepeat; // auto mode, show all repetitions } *namextPP = new TPropNameExtension( aMusthave_ids,aForbidden_ids,aAddtlSend_ids,aFieldidoffs, aMaxRepeat,aRepeatInc,aMinShow,aOverwriteEmpty,aReadOnly, // readOnly alternative parsing might want to share the // repeat count with previous occurrences aShareCountOffs ? aRootProfile->nextRepID-aShareCountOffs : aRootProfile->nextRepID++ ); } // TPropertyDefinition::addNameExt TParameterDefinition *TPropertyDefinition::addParam( const char *aName, bool aDefault, bool aExtendsName, bool aShowNonEmpty, bool aShowInCTCap, TMimeDirMode aModeDep ) { TParameterDefinition **paramPP = ¶meterDefs; while(*paramPP!=NULL) paramPP=&((*paramPP)->next); // find last in chain *paramPP = new TParameterDefinition(aName,aDefault,aExtendsName,aShowNonEmpty,aShowInCTCap, aModeDep); return *paramPP; } // TPropertyDefinition::addParam // find parameter by name TParameterDefinition *TPropertyDefinition::findParameter(const char *aNam, sInt16 aLen) { TParameterDefinition *paramP = parameterDefs; while (paramP) { if (strucmp(aNam,TCFG_CSTR(paramP->paramname),aLen)==0) return paramP; // found paramP=paramP->next; // next } // not found return NULL; } // TPropertyDefinition::findParameter TProfileDefinition::TProfileDefinition( TProfileDefinition *aParentProfileP, // parent profile const char *aProfileName, // name sInt16 aNumMandatory, bool aShowInCTCapIfSelectedOnly, TProfileModes aProfileMode, TMimeDirMode aModeDep ) { parentProfile=aParentProfileP; // NULL if root next=NULL; // set fields TCFG_ASSIGN(levelName,aProfileName); shownIfSelectedOnly = aShowInCTCapIfSelectedOnly; profileMode = aProfileMode; modeDependency = aModeDep; // init numMandatoryProperties=aNumMandatory; propertyDefs=NULL; subLevels=NULL; ownsProps=true; nextRepID=0; } // TProfileDefinition::TProfileDefinition TProfileDefinition::~TProfileDefinition() { if (propertyDefs && ownsProps) delete propertyDefs; if (subLevels) delete subLevels; if (next) delete next; } // TProfileDefinition::~TProfileDefinition TProfileDefinition *TProfileDefinition::addSubProfile( const char *aProfileName, // name sInt16 aNumMandatory, bool aShowInCTCapIfSelectedOnly, TProfileModes aProfileMode, TMimeDirMode aModeDep ) { TProfileDefinition **profilePP=&subLevels; while (*profilePP!=NULL) profilePP=&((*profilePP)->next); *profilePP=new TProfileDefinition(this,aProfileName,aNumMandatory,aShowInCTCapIfSelectedOnly,aProfileMode,aModeDep); return *profilePP; } // TProfileDefinition::addSubProfile TPropertyDefinition *TProfileDefinition::addProperty( const char *aName, // name sInt16 aNumValues, // number of values bool aMandatory, // mandatory bool aShowInCTCap, // show in CTCap bool aSuppressEmpty, // suppress empty ones on send uInt16 aDelayedProcessing, // delayed processing when parsed, 0=immediate processing, 1..n=delayed char aValuesep, // value separator uInt16 aPropertyGroupID, // property group ID (alternatives for same-named properties should have same ID>0) bool aCanFilter, // can be filtered -> show in filter cap TMimeDirMode aModeDep, // property valid only for specific MIME mode char aAltValuesep, // alternate separator (for parsing) sInt16 aGroupFieldID, // group field ID bool aAllowFoldAtSep // allow folding at separators ) { TPropertyDefinition **propPP=&propertyDefs; while (*propPP!=NULL) propPP=&((*propPP)->next); *propPP=new TPropertyDefinition(aName,aNumValues,aMandatory,aShowInCTCap,aSuppressEmpty,aDelayedProcessing,aValuesep,aAltValuesep,aPropertyGroupID,aCanFilter,aModeDep,aGroupFieldID,aAllowFoldAtSep); // return new property return *propPP; } // TProfileDefinition::addProperty void TProfileDefinition::usePropertiesOf(TProfileDefinition *aProfile) { ownsProps=false; propertyDefs=aProfile->propertyDefs; } // TProfileDefinition::usePropertiesOf // find (sub)profile by name, recursively TProfileDefinition *TProfileDefinition::findProfile(const char *aNam) { // check myself if (levelName==aNam) return this; // check sublevels TProfileDefinition *lvlP = subLevels; TProfileDefinition *foundlvlP; while(lvlP) { foundlvlP=lvlP->findProfile(aNam); if (foundlvlP) return foundlvlP; lvlP=lvlP->next; } // does not match myself nor one of my sublevels return NULL; } // TProfileDefinition::findProfile #pragma exceptions reset #undef EXCEPTIONS_HERE #define EXCEPTIONS_HERE TARGET_HAS_EXCEPTIONS #ifdef OBJECT_FILTERING // get property definition of given filter expression identifier. TPropertyDefinition *TProfileDefinition::getPropertyDef(const char *aPropName) { TPropertyDefinition *propP = NULL; if (!aPropName) return propP; // no name, no fid // Depth first: search in subprofiles, if any TProfileDefinition *profileP = subLevels; while (profileP) { // search depth first if ((propP=profileP->getPropertyDef(aPropName))!=NULL) return propP; // found // test next profile profileP=profileP->next; } // now search my own properties propP = propertyDefs; while (propP) { // compare names if (strucmp(aPropName,TCFG_CSTR(propP->propname))==0) { return propP; } // test next property propP=propP->next; } // not found return NULL; } // TProfileDefinition::getPropertyDef // get field index of given filter expression identifier. sInt16 TProfileDefinition::getPropertyMainFid(const char *aPropName, uInt16 aIndex) { sInt16 fid = VARIDX_UNDEFINED; // search property definition with matching name TPropertyDefinition *propP = getPropertyDef(aPropName); // search for first value with a field assigned if (propP) { // found property with matching name if (propP->convdefs) { if (aIndex==0) { // no index specified -> search first with a valid FID for (uInt16 i=0; inumValues; i++) { if ((fid=propP->convdefs[i].fieldid)!=VARIDX_UNDEFINED) return fid; // found a field index } } else { // index specified for multivalued properties -> return specified value's ID if (aIndex<=propP->numValues) { return propP->convdefs[aIndex-1].fieldid; } } } } // not found return VARIDX_UNDEFINED; } // TProfileDefinition::getPropertyMainFid #endif // OBJECT_FILTERING /* * Implementation of TMimeDirProfileHandler */ TMimeDirProfileHandler::TMimeDirProfileHandler( TMIMEProfileConfig *aMIMEProfileCfgP, TMultiFieldItemType *aItemTypeP ) : TProfileHandler(aMIMEProfileCfgP, aItemTypeP) { // save profile config pointer fProfileCfgP = aMIMEProfileCfgP; fProfileDefinitionP = fProfileCfgP->fRootProfileP; // settable options defaults fMimeDirMode=mimo_standard; fReceiverCanHandleUTC = true; fVCal10EnddatesSameDay = false; // avoid 23:59:59 style end date by default fReceiverTimeContext = TCTX_UNKNOWN; // none in particular fDontSendEmptyProperties = false; // send all defined properties fDefaultOutCharset = chs_utf8; // standard fDefaultInCharset = chs_utf8; // standard fDoQuote8BitContent = false; // no quoting needed per se fDoNotFoldContent = false; // standard requires folding fTreatRemoteTimeAsLocal = false; // only for broken implementations fTreatRemoteTimeAsUTC = false; // only for broken implementations fActiveRemoteRules.clear(); // no dependency on certain remote rules } // TMimeDirProfileHandler::TMimeDirProfileHandler TMimeDirProfileHandler::~TMimeDirProfileHandler() { // nop for now } // TMimeDirProfileHandler::~TTextProfileHandler #ifdef OBJECT_FILTERING // get field index of given filter expression identifier. sInt16 TMimeDirProfileHandler::getFilterIdentifierFieldIndex(const char *aIdentifier, uInt16 aIndex) { // search properties for field index return fProfileDefinitionP->getPropertyMainFid(aIdentifier, aIndex); } // TMimeDirProfileHandler::getFilterIdentifierFieldIndex #endif // OBJECT_FILTERING // parses enum value for CONVMODE_MULTIMIX // [offs.](Bx|Lzzzzzzz) // aN returns the bit number or the offset of the zzzzz literal within aMixVal, depending on aIsBitMap static bool mixvalparse(cAppCharP aMixVal, uInt16 &aOffs, bool &aIsBitMap, uInt16 &aN) { aOffs = 0; cAppCharP p = aMixVal; // check offset (2 digit max) if (isdigit(*p)) { p+=StrToUShort(p,aOffs,2); if (*p++ != '.') return false; // wrong syntax } // check command if (*p == 'B') { // bit number aIsBitMap = true; if (StrToUShort(p+1,aN,2)<1) return false; // wrong syntax } else if (*p=='L') { // literal, return position within string aIsBitMap = false; aN = p+1-aMixVal; // literal starts at this position } else return false; // unknown command return true; } // mixvalparse // returns the size of the field block (how many fids in sequence) related // to a given convdef (for multi-field conversion modes such as CONVMODE_RRULE sInt16 TMimeDirProfileHandler::fieldBlockSize(const TConversionDef &aConvDef) { if ((aConvDef.convmode & CONVMODE_MASK)==CONVMODE_RRULE) return 6; // RRULE fieldblock: DTSTART,FREQ,INTERVAL,FIRSTMASK,LASTMASK,UNTIL = 6 fields else return 1; // single field } // TMimeDirProfileHandler::fieldBlockSize // special field translation (to be extended in derived classes) // Note: the string returned by this function will be scanned as a // value list if combinesep is set, and every single value will be // enum-translated if enums defined. bool TMimeDirProfileHandler::fieldToMIMEString( TMultiFieldItem &aItem, // the item where data comes from sInt16 aFid, // the field ID (can be NULL for special conversion modes) sInt16 aArrIndex, // the repeat offset to handle array fields const TConversionDef *aConvDefP, // the conversion definition record string &aString // output string ) { const int maxmix = 10; uInt16 mixOffs[maxmix]; bool mixIsFlags[maxmix]; TEnumerationDef *enumP; uInt16 offs; bool isFlags; int nummix, i; fieldinteger_t flags; uInt16 bitNo; TTimestampField *tsFldP; TIntegerField *ifP; TStringField *sfP; timecontext_t tctx; lineartime_t ts; string s; // RRULE field block values char freq; // frequency char freqmod; // frequency modifier sInt16 interval; // interval fieldinteger_t firstmask; // day mask counted from the first day of the period fieldinteger_t lastmask; // day mask counted from the last day of the period lineartime_t until; // last day timecontext_t untilcontext; // get pointer to leaf field TItemField *fldP = aItem.getArrayField(aFid,aArrIndex,true); // existing array elements only bool dateonly = false; // assume timestamp mode bool autodate = true; // show date-only values automatically as date-only, even if stored in a timestamp field bool extFmt = (aConvDefP->convmode & CONVMODE_FLAG_EXTFMT)!=0; bool milliSec = (aConvDefP->convmode & CONVMODE_FLAG_MILLISEC)!=0; sInt16 convmode = aConvDefP->convmode & CONVMODE_MASK; switch (convmode) { // no special mode case CONVMODE_NONE: case CONVMODE_EMPTYONLY: // just get field as string if (!fldP) return false; // no field, no value if (!fldP->isBasedOn(fty_timestamp)) goto normal; // Based on timestamp // - handle date-only specially if (fldP->getType()==fty_date) goto dateonly; // date-only else goto timestamp; // others are treated as timestamps // date & time modes case CONVMODE_DATE: // always show as date dateonly: dateonly = true; // render as date in all cases goto timestamp; case CONVMODE_AUTOENDDATE: case CONVMODE_AUTODATE: // show date-only as date in iCal 2.0 (mimo_standard), but always as timestamp for vCal 1.0 (mimo_old) if (fMimeDirMode==mimo_standard) goto timestamp; // use autodate if MIME-DIR format is not vCal 1.0 style // for vCal 1.0 style, always renders as timestamp (as date-only values are not allowed there) case CONVMODE_TIMESTAMP: // always show as timestamp // get explictly as timestamp (even if field or field contents is date) autodate = false; // do not show as date, even if it is a date-only timestamp: if (!fldP) return false; // no field, no value if (!fldP->isBasedOn(fty_timestamp)) goto normal; // show as timestamp tsFldP = static_cast(fldP); tctx = tsFldP->getTimeContext(); // check for auto-date if (autodate) { if (TCTX_IS_DATEONLY(tctx)) dateonly=true; } // check for special cases if (TCTX_IS_DURATION(tctx)) { // duration is shown as such tsFldP->getAsISO8601(aString, TCTX_UNKNOWN | TCTX_DURATION, false, false, extFmt, milliSec); } else if (dateonly) { // date-only are either floating or shown as date-only part of original timestamp tsFldP->getAsISO8601(aString, TCTX_UNKNOWN | TCTX_DATEONLY, false, false, extFmt, milliSec); } else if (fReceiverCanHandleUTC && !tsFldP->isFloating()) { // remote can handle UTC and the timestamp is not floating if (!TCTX_IS_UNKNOWN(fPropTZIDtctx)) { // if we have rendered a TZID for this property, this means that apparently the remote // supports TZID (otherwise the field would not be marked available in the devInf). // - show it as floating, explicitly with both date AND time (both flags set) tsFldP->getAsISO8601(aString, TCTX_UNKNOWN | TCTX_TIMEONLY | TCTX_DATEONLY, false, false, extFmt, milliSec); } else { // - show it as UTC tsFldP->getAsISO8601(aString, TCTX_UTC, true, false, extFmt, milliSec); } } else { // remote cannot handle UTC or time is floating (possibly dateonly or duration) if (tsFldP->isFloating()) { // floating, show as-is ts = tsFldP->getTimestampAs(TCTX_UNKNOWN); if (ts==noLinearTime) aString.erase(); else { if (TCTX_IS_DATEONLY(tctx)) { // value is a date-only, but we must render it a datetime ts=lineartime2dateonlyTime(ts); // make time part 0:00:00 } // first check for auto-end-date (which must be floating) // Note: we don't get here with a date only mimo_standard because it will be catched above, so test is not really needed if (convmode==CONVMODE_AUTOENDDATE && fVCal10EnddatesSameDay && TCTX_IS_DATEONLY(tctx) && fMimeDirMode==mimo_old) ts-=1; // subtract one unit to make end show last time unit of previous day // now show as floating ISO8601 TimestampToISO8601Str(aString, ts, TCTX_UNKNOWN, extFmt, milliSec); } } else { // not floating (=not a enddateonly), but we can't send UTC - render as localtime // in item time zone (which defaults to session time zone) tsFldP->getAsISO8601(aString, fItemTimeContext, false, false, extFmt, milliSec); } } return true; // found normal: // simply as string fldP->getAsString(aString); return true; // found case CONVMODE_TZ: case CONVMODE_TZID: case CONVMODE_DAYLIGHT: // use now as default point in time for possible offset calculations ts = getSession()->getSystemNowAs(TCTX_SYSTEM); // if no field is specified, the item context is used (which defaults to // the session's user context) // Note that testing fldP is not enough, because an empty array will also cause fldP==NULL if (!fldP) { if (aFid!=FID_NOT_SUPPORTED) return false; // field not available (but conversion definition DOES refer to a field --> no time zone) // conversion definition does not refer to a field: use item context tctx = fItemTimeContext; } else if (fldP->isBasedOn(fty_timestamp)) { // time zone of a timestamp tsFldP = static_cast(fldP); // - if floating time, we have no time zone if (tsFldP->isFloating() || tsFldP->isDuration()) return false; // floating or duration -> no time zone // - get context tctx = tsFldP->getTimeContext(); // get the context // - get the value ts = tsFldP->getTimestampAs(TCTX_UNKNOWN); // prevent generating TZID (and associated VTIMEZONES later) for empty timestamp if (ts==noLinearTime) return false; // no timestamp -> no time zone } else if (fldP->getCalcType()==fty_integer) { // integer field is simply a time zone offset in minutes tctx = TCTX_MINOFFSET(fldP->getAsInteger()); } else if (!fldP->isEmpty()) { // string field can be timezone name (internal or olson) or numeric minute offset fldP->getAsString(s); if (!TimeZoneNameToContext(s.c_str(),tctx,getSessionZones(), true)) { // if not recognized as time zone name, use integer value tctx = TCTX_MINOFFSET(fldP->getAsInteger()); } } else return false; // no TZ to show // if remote cannot handle UTC (i.e. only understands localtime), then make sure // the time zone shown is the general item zone (user zone). if (!fReceiverCanHandleUTC) { TzConvertTimestamp(ts,tctx,fItemTimeContext,getSessionZones()); tctx = fItemTimeContext; // use item zone } // now render context as selected if (convmode==CONVMODE_TZID) { // time zone ID for iCal 2.0 TZID parameter // - make sure meta context is resolved (we don't want "SYSTEM" as TZID!) if (!TzResolveMetaContext(tctx, getSessionZones())) return false; // cannot resolve, no time zone ID // - if time zone is not UTC (which is represented as "Z" and needs no TZID), show name if (!TCTX_IS_UTC(tctx) && !TCTX_IS_UNKNOWN(tctx) && !TCTX_IS_DATEONLY(tctx)) { // - show name of zone as TZID if (!TimeZoneContextToName(tctx, aString, getSessionZones(), fProfileCfgP->fTzIdGenMode==tzidgen_olson ? "o" : NULL)) return false; // cannot get name/ID // - flag property-level TZID generated now fPropTZIDtctx=tctx; // - add to set of TZID-referenced time zones (for vTimezone generation) fUsedTCtxSet.insert(fUsedTCtxSet.end(),tctx); // - update range of time covered for generating VTIMEZONE later if (ts) { if (fEarliestTZDate==noLinearTime || fEarliestTZDate>ts) fEarliestTZDate = ts; // new minimum if (fLatestTZDate==noLinearTime || fLatestTZDategetAsString(s); aString.erase(); if (strucmp(s.c_str(),"mailto:",7)!=0 && s.size()>0) aString="mailto:"; aString+=s; return true; case CONVMODE_VALUETYPE: case CONVMODE_FULLVALUETYPE: // specify value type of field if needed if (!fldP) return false; // no field -> no VALUE param if (fldP->isBasedOn(fty_timestamp)) { // show VALUE=DATE if we have date-only or time-only tctx = static_cast(fldP)->getTimeContext(); if (TCTX_IS_DURATION(tctx)) aString="DURATION"; else if (TCTX_IS_DATEONLY(tctx)) aString="DATE"; else if (TCTX_IS_TIMEONLY(tctx)) aString="TIME"; else { // only show type if full value type requested if (convmode==CONVMODE_FULLVALUETYPE) aString="DATE-TIME"; else return false; // we don't need a VALUE param for normal datetimes } } else return false; // no field type that needs VALUE param // valuetype generated return true; case CONVMODE_VERSION: // version string aString=aItem.getItemType()->getTypeVers(fProfileMode); return true; case CONVMODE_PRODID: // PRODID ISO9070 non-registered FPI // -//ABC Corporation//NONSGML My Product//EN aString = SYSYNC_FPI; return true; case CONVMODE_BITMAP: // bitmap is a special case of multimix, set up params nummix = 1; mixOffs[0]=0; mixIsFlags[0]=true; goto genmix; case CONVMODE_MULTIMIX: // list of special values that can be either literals or bit masks, and can optionally affect more than one field // Syntax: // Bx : Bit number x (like in CONVMODE_BITMAP, x = 0..63) // Lxxxx : Literal xxxxx (xxxxx will just be copied from the source field) // y.Bx or y.Lxxxx : use y as field offset to use (no y means 0 offset) // - collect parameters to generate mix from enums nummix = 0; enumP = aConvDefP->enumdefs; while(enumP) { if (mixvalparse(TCFG_CSTR(enumP->enumval),offs,isFlags,bitNo)) { // check if this field is in list already for (i=0; i=maxmix) break; // no more mixes allowed, stop scanning } next: // check next enum enumP=enumP->next; } genmix: // now generate strings from collected data aString.erase(); for (i=0; igetAsInteger(); bitNo=0; while (flags) { if (flags & 1) { // create bit representation if (!aString.empty() && aConvDefP->combineSep) aString+=aConvDefP->combineSep; // separator first if not first item if (convmode==CONVMODE_MULTIMIX) { // multimix mode, use full syntax if (mixOffs[i]>0) StringObjAppendPrintf(aString,"%d.",mixOffs[i]); aString += 'B'; } // add bit number StringObjAppendPrintf(aString,"%hd",bitNo); } flags >>= 1; // consume this one bitNo++; } } else { // literal if (!fldP->isEmpty()) { if (!aString.empty() && aConvDefP->combineSep) aString+=aConvDefP->combineSep; // append separator if there are more flags if (mixOffs[i]>0) StringObjAppendPrintf(aString,"%d.",mixOffs[i]); aString += 'L'; // literal fldP->appendToString(aString); } } } // field available } // for each mix return true; case CONVMODE_RRULE: { // get values from field block if (aFid<0) return false; // no field, no string // - freq/freqmod if (!(sfP = ITEMFIELD_DYNAMIC_CAST_PTR(TStringField,fty_string,aItem.getArrayField(aFid,aArrIndex,true)))) return false; aFid++; // do NOT INCREMENT in macro, as it would get incremented twice sfP->getAsString(s); freq='0'; // none freqmod=' '; // no modifier if (s.size()>0) freq=s[0]; if (s.size()>1) freqmod=s[1]; // - interval if (!(ifP = ITEMFIELD_DYNAMIC_CAST_PTR(TIntegerField,fty_integer,aItem.getArrayField(aFid,aArrIndex,true)))) return false; aFid++; // do NOT INCREMENT in macro, as it would get incremented twice interval=(sInt16)ifP->getAsInteger(); // - firstmask if (!(ifP = ITEMFIELD_DYNAMIC_CAST_PTR(TIntegerField,fty_integer,aItem.getArrayField(aFid,aArrIndex,true)))) return false; aFid++; // do NOT INCREMENT in macro, as it would get incremented twice firstmask=ifP->getAsInteger(); // - lastmask if (!(ifP = ITEMFIELD_DYNAMIC_CAST_PTR(TIntegerField,fty_integer,aItem.getArrayField(aFid,aArrIndex,true)))) return false; aFid++; // do NOT INCREMENT in macro, as it would get incremented twice lastmask=ifP->getAsInteger(); // - until if (!(tsFldP = ITEMFIELD_DYNAMIC_CAST_PTR(TTimestampField,fty_timestamp,aItem.getArrayField(aFid,aArrIndex,true)))) return false; aFid++; // do NOT INCREMENT in macro, as it would get incremented twice // Until // - UTC preferred as output format if basically possible and not actively disabled untilcontext= fReceiverCanHandleUTC && getSession()->canHandleUTC() ? TCTX_UTC : fItemTimeContext; // - get in preferred zone (or floating) until=tsFldP->getTimestampAs(untilcontext,&untilcontext); lineartime_t tzend = until; // A RRULE with no end extends at least into current time (for tz range update, see below) if (until==noLinearTime) { // no end, but we still need a range to generate time zones for tzend = getSession()->getSystemNowAs(TCTX_UTC); } else { // Treat RR_END similar to CONVMODE_AUTODATE, i.e. prevent rendering a date-only value in mimo_old (which is not correct according to the standard) if (TCTX_IS_DATEONLY(untilcontext) && fMimeDirMode==mimo_old) { // there are no date-only recurrence ends in vCalendar 1.0 until = lineartime2dateonlyTime(until)+secondToLinearTimeFactor*SecsPerHour*24-1 ; // make time part 23:59:59.999 of this day untilcontext &= ~TCTX_DATEONLY; // clear dateonly rendering flag } } // Now do the conversion bool ok; if (fMimeDirMode==mimo_old) { // vCalendar 1.0 type RRULE ok = internalToRRULE1( aString, freq, freqmod, interval, firstmask, lastmask, until, untilcontext, GETDBGLOGGER ); } else { // iCalendar 2.0 type RRULE ok = internalToRRULE2( aString, freq, freqmod, interval, firstmask, lastmask, until, untilcontext, GETDBGLOGGER ); } // if we actually generated a RRULE, the range of used time zones must be updated according // to the recurrence end (date or open end, see tzend calculation above) if (!aString.empty()) { if (fEarliestTZDate==noLinearTime || tzendfLatestTZDate) fLatestTZDate = tzend; } return ok; break; // just in case } default: // unknown mode, no value return false; } return false; } // TMimeDirProfileHandler::fieldToMIMEString /// @brief test if char is part of a line end /// @return true if aChar is a line end char /// @param [in] aChar charcter to check static bool isLineEndChar(appChar aChar) { return (aChar=='\x0D') || (aChar=='\x0A'); } // isLineEndChar /// @brief test if char is end of a line or end of the text (NUL) /// @return true if aChar is a line end char or NUL /// @param [in] aChar charcter to check static bool isEndOfLineOrText(appChar aChar) { return (aChar==0) || isLineEndChar(aChar); } // isEndOfLineOrText /// @brief test if a line end of any kind is at aText /// @note CR,LF,CRLF and CR...CRLF sequences are all considered one line end /// @return true if line end found /// @param [in/out] aText advance past line end sequence static bool testAndSkipLineEnd(cAppCharP &aText) { cAppCharP p = aText; bool crFound = false; // skip sequence of CRs while (*p=='\x0D') { p++; crFound = true; } // past all CRs in a row if (*p=='\x0A') { // independent of the number of CRs preceeding, this is a line end including the LF aText = p+1; // past LF return true; } else if (crFound) { // we previously found at least one CR at the beginning, but no LF is following // -> assume CR only line ends, consider first CR as a line end by itself aText++; // skip first CR return true; } // not a line end return false; } // testAndSkipLineEnd // return incremented pointer pointing to original char or next non-folded char static cAppCharP skipfolded(cAppCharP aText, TMimeDirMode aMimeMode, bool qpSoftBreakCancel=false) { cAppCharP p = aText; if (testAndSkipLineEnd(p)) { // check for folding sequence if (*p==' ' || *p=='\x09') { // line end followed by space: folding sequence if (aMimeMode==mimo_standard) { // ignore entire sequence (CR,LF,SPACE/TAB) return p+1; } else { // old folding type, LWSP must be preserved return p; } } } else if (qpSoftBreakCancel && *p=='=') { // could be soft break sequence, check for line end p++; if (testAndSkipLineEnd(p)) { return p; } } // not folding sequence, return ptr to char as is return aText; } // skipfolded // get next character, while skipping MIME-DIR folding sequences // if qpSoftBreakCancel, QUOTED-PRINTABLE encoding style soft-line-break sequences // will be eliminated static const char *nextunfolded(const char *p, TMimeDirMode aMimeMode, bool qpSoftBreakCancel=false) { if (*p==0) return p; // at end of string, do not advance p++; // point to next return skipfolded(p,aMimeMode,qpSoftBreakCancel); } // nextunfolded // helper for MIME DIR parsing: // - apply encoding and charset conversion to values part of property if needed static void decodeValue( TEncodingTypes aEncoding, // the encoding to be used TCharSets aCharset, // charset to be applied to 8-bit chars TMimeDirMode aMimeMode, // the MIME mode char aStructSep, // input is structured value, stop when aStructSep is encountered char aAltSep, // alternate separator, also stop when encountering this one (but only if aStructSep is !=0) const char *&aText, // where to start decoding, updated past last char added to aVal string &aVal // decoded data is stored here (possibly some binary data) ) { const int maxseqlen=6; int seqlen; char c,chrs[maxseqlen]; const char *p,*q; aVal.erase(); bool escaped = false; bool lastWasQPCR = false; if (aEncoding==enc_quoted_printable) { // decode quoted-printable content p = skipfolded(aText,aMimeMode,true); // get unfolded start point (in case value starts with folding sequence) do { // decode standard content c=*p; if (isEndOfLineOrText(c) || (!escaped && aStructSep!=0 && (c==aStructSep || c==aAltSep))) break; // EOLN and struct separators terminate value // test if escape char (but do not filter it out, as actual de-escaping is done in parseValue() later escaped=(!escaped) && (c=='\\'); // escape next only if we are not escaped already // char found if (c=='=') { uInt16 code; const char *s; char hex[2]; s=nextunfolded(p,aMimeMode,true); if (*s==0) break; // end of string hex[0]=*s; // first digit s=nextunfolded(s,aMimeMode,true); if (*s==0) break; // end of string hex[1]=*s; // second digit if (HexStrToUShort(hex,code,2)==2) { p=s; // continue with next char after second digit c=code; // decoded char if (c=='\x0D') { c='\n'; // convert to newline lastWasQPCR = true; // remember } else if (c=='\x0A') { if (lastWasQPCR) { // if last was CR, ignore LF (CR already has generated a newline) p = nextunfolded(p,aMimeMode,true); // but skip it for now. lastWasQPCR = false; continue; // ignore LF } // LF not preceeded by CR is a newline c='\n'; // convert to newline } else { // neither CR nor LF lastWasQPCR = false; } } } else { lastWasQPCR = false; } seqlen=1; // assume logical char consists of single byte chrs[0]=c; do { seqlen=appendCharsAsUTF8(chrs,aVal,aCharset,seqlen); // add char (possibly with UTF8 expansion) to aVal if (seqlen<=1) break; // done // need more bytes to encode entire char for (int i=1;i this appears to be the end of the property // Now for ill-encoded vCard 2.1 which chop B64 into lines, but do not prefix continuation // lines with some whitespace, make sure the next line contains a colon // - skip that line end while (isLineEndChar(*r)) r++; // - examine next line bool eob64 = false; for (cAppCharP r2=r; *r2 && !isLineEndChar(*r2); r2++) { if (*r2==':' || *r2==';') { eob64 = true; break; } } if (eob64) break; // q is end of B64 string -> go decode it // there's more to the b64 string at r, continue looking for end } // skip to continuation of B64 string q=r; } else q++; } // - decode base 64 uInt32 binsz=0; uInt8 *binP = b64::decode(p, q-p, &binsz); aVal.append((const char *)binP,binsz); b64::free(binP); // - continue at next char after b64 value p=q; } else { // no (known) encoding p = skipfolded(aText,aMimeMode,false); // get unfolded start point (in case value starts with folding sequence) do { c=*p; if (isEndOfLineOrText(c) || (!escaped && aStructSep!=0 && (c==aStructSep || c==aAltSep))) break; // EOLN and structure-sep (usually ;) terminate value // test if escape char (but do not filter it out, as actual de-escaping is done in parseValue() later escaped=(!escaped) && (c=='\\'); // escape next only if we are not escaped already // process char seqlen=1; // assume logical char consists of single byte chrs[0]=c; do { seqlen=appendCharsAsUTF8(chrs,aVal,aCharset,seqlen); // add char (possibly with UTF8 expansion) to aVal if (seqlen<=1) break; // done // need more bytes to encode entire char for (int i=1;i=MIME_MAXLINESIZE && *proptext) || explf) { // avoid unnecessary folding (there must be something more coming) // folding needed (line gets longer than MIME_MAXLINESIZE or '\n' found in input string) if (aMimeMode==mimo_old && !explf) { // vCard 2.1 type folding, must occur before an LWSP if (foldLoc<0) { // emergency force fold and accept data being shredded // - copy all we have by now aString.append(firstunwritten,n); firstunwritten += n; // now pointing to next n = 0; // none left - new line is empty now // - insert line break aString.append("\x0D\x0A "); // line break AND an extra shredding space } else { // - copy all up to (but not including) last LWSP (or '\b' break indicator) aString.append(firstunwritten,foldLoc); firstunwritten += foldLoc; // now pointing to LWSP (or non-LWSP in case of '\b') n -= foldLoc; // number of chars left (including LWSP) // - insert line break aString.append("\x0D\x0A"); // line break if (*firstunwritten!=' ' && *firstunwritten!=0x09) aString += ' '; // breaking at location indicated by '\b', LWSP must be added // - copy rest scanned so far (except in '\b' case, this begins with an LWSP) aString.append(firstunwritten,n); } } else { // MIME-DIR type folding, can occur anywhere and *adds* a LWSP (which is removed at unfolding later) // or mimo-old type folding containing explicit CR(LF)s -> break here if (explf) { // explicit \n or \r is not copied, but only causes line break to occur n--; } if (foldLoc<0 || explf) { // no or explf indicator, just fold here aString.append(firstunwritten,n); n = 0; // nothing left to carry over - new line is empty now } else { // we have a preferred folding location detected before: copy all up to (but not including) break indicator aString.append(firstunwritten,foldLoc); firstunwritten += foldLoc; // now pointing to next char after break) n -= foldLoc; // number of chars left (including LWSP) } // now fold aString.append("\x0D\x0A"); // line break if ( (c!='\r' && aMimeMode==mimo_standard) || // folding indicator and MIME-DIR -> folding always must insert extra space (c=='\r' && !aDoSoftBreak) // soft-break indicator, but not in softbreak mode (i.e. B64 input) -> always insert extra space ) aString += ' '; // not only soft line break, but MIMD-DIR type folding // - copy carry over from previous line if (n>0) aString.append(firstunwritten,n); } // we are on a new line now llen = n; // new line has this size of what was carried over from the previous line foldLoc = -1; n = 0; firstunwritten = proptext; } } // append rest aString.append(firstunwritten,n); // terminate property aString.append("\x0D\x0A"); // CRLF } // finalizeProperty // results for generateValue: #define GENVALUE_NOTSUPPORTED 0 // field not supported #define GENVALUE_EXHAUSTED 1 // array field exhausted #define GENVALUE_EMPTYELEMENT 2 // array field empty #define GENVALUE_EMPTY 3 // non-array field empty #define GENVALUE_ELEMENT 4 // non-empty array element #define GENVALUE_NONEMPTY 5 // non-empty non-array value // helper for generateMimeDir() // - generate parameter or property value(list), // returns: GENVALUE_xxx sInt16 TMimeDirProfileHandler::generateValue( TMultiFieldItem &aItem, // the item where data comes from const TConversionDef *aConvDefP, sInt16 aBaseOffset, // basic fid offset to use sInt16 aRepOffset, // repeat offset, adds to aBaseOffset for non-array fields, is array index for array fields string &aString, // where value is ADDED char aSeparator, // separator to be used between values if field contains multiple values in a list separated by confdef->combineSep TMimeDirMode aMimeMode, // MIME mode (older or newer vXXX format compatibility) bool aParamValue, // set if generating parameter value (different escaping rules, i.e. colon must be escaped, or entire value double-quoted) bool aStructured, // set if value consists of multiple values (needs semicolon content escaping) bool aCommaEscape, // set if "," content escaping is needed (for values in valuelists like TYPE=TEL,WORK etc.) TEncodingTypes &aEncoding, // modified if special value encoding is required bool &aNonASCII, // set if any non standard 7bit ASCII-char is contained char aFirstChar, // will be appended before value if there is any value (and in MIME-DIR '\b' optional break indicator is appended as well) sInt32 &aNumNonSpcs, // how many non-spaces are already in the value bool aFoldAtSeparators, // if true, even in mimo_old folding may appear at value separators (adding an extra space - which is ok for EXDATE and similar) bool aEscapeOnlyLF // if true, only linefeeds are escaped as \n, but nothing else (not even \ itself) ) { string vallist; // as received from fieldToMIMEString() string val; // single value string outval; // entire value (list) escaped char c; // determine field ID bool isarray = false; // no array by default sInt16 fid=aConvDefP->fieldid; if (fid>=0) { // field has storage // - fid is always offset by baseoffset fid += aBaseOffset; // - adjust now isarray = aItem.adjustFidAndIndex(fid,aRepOffset); // generate only if available in both source and target (or non-SyncML context) if (isFieldAvailable(aItem,fid)) { // find out if value exists if (aItem.isAssigned(fid)) { // - field has a value assigned (altough this might be empty string) // determine max size to truncate value if needed outval.erase(); sInt32 valsiz=0; // net size of value //%%%% getTargetItemType??? sInt32 maxSiz=aItem.getTargetItemType()->getFieldOptions(fid)->maxsize; if (maxSiz==FIELD_OPT_MAXSIZE_UNKNOWN || maxSiz==FIELD_OPT_MAXSIZE_NONE) maxSiz = 0; // no size restriction bool noTruncate=aItem.getTargetItemType()->getFieldOptions(fid)->notruncate; // check for BLOB values sInt16 convmode = aConvDefP->convmode & CONVMODE_MASK; if (convmode==CONVMODE_BLOB_B64 || convmode==CONVMODE_BLOB_AUTO) { // no value lists, escaping, enums. Simply set value and encoding TItemField *fldP = aItem.getArrayField(fid,aRepOffset,true); // existing array elements only if (!fldP) return GENVALUE_EXHAUSTED; // no leaf field - must be exhausted array (fldP==NULL is not possible here for non-arrays) if (fldP->isUnassigned()) return GENVALUE_EMPTYELEMENT; // must be empty element empty element, but field supported (fldP==NULL is not possible here for non-arrays) // check max size and truncate if needed if (maxSiz && sInt32(fldP->getStringSize())>maxSiz) { if (noTruncate || getSession()->getSyncMLVersion() omit", (long)maxSiz)); return GENVALUE_NOTSUPPORTED; // treat it as if field was not supported locally } } // append to existing string fldP->appendToString(outval,maxSiz); if (convmode==CONVMODE_BLOB_AUTO) { // auto mode: use B64 encoding only if non-printable or // non-ASCII characters are in the value size_t len = outval.size(); for (size_t i = 0; i < len; i++) { char c = outval[i]; if (!isascii(c) || !isprint(c)) { aEncoding=enc_base64; break; } } } else { // blob mode: always use B64 aEncoding=enc_base64; } // only ASCII in value: either because it contains only // those to start with or because they will be encoded aNonASCII=false; } else { // apply custom field(s)-to-string translation if needed if (!fieldToMIMEString(aItem,fid,aRepOffset,aConvDefP,vallist)) { // check if no value because array was exhausted if (aItem.getArrayField(fid,aRepOffset,true)) return isarray ? GENVALUE_EMPTYELEMENT : GENVALUE_EMPTY; // no value (but field supported) else return GENVALUE_EXHAUSTED; // no leaf field - must be exhausted array } // separate value list into multiple values if needed const char *lp = vallist.c_str(); // list item pointer const char *sp; // start of item pointer (helper) sInt32 n; while (*lp!=0) { // find (single) input value string's end for (sp=lp,n=0; (c=*lp)!=0; lp++, n++) { if (c==aConvDefP->combineSep) break; } // - n=size of input value, p=ptr to end of value (0 or sep) val.assign(sp,n); // perform enum translation if needed if (aConvDefP->enumdefs) { const TEnumerationDef *enumP = aConvDefP->findEnumByVal(val.c_str()); if (enumP) { PDEBUGPRINTFX(DBG_GEN+DBG_EXOTIC,("Val='%s' translated to enumName='%s' mode=%s", val.c_str(), TCFG_CSTR(enumP->enumtext), EnumModeNames[enumP->enummode])); if (enumP->enummode==enm_ignore) val.erase(); // ignore -> make value empty as empty values are never stored else if (enumP->enummode==enm_prefix) { // replace value prefix by text prefix n=TCFG_SIZE(enumP->enumval); val.replace(0,n,TCFG_CSTR(enumP->enumtext)); // replace val prefix by text prefix } else { // simply use translated value val=enumP->enumtext; } } else { PDEBUGPRINTFX(DBG_GEN+DBG_EXOTIC,("No translation found for Val='%s'", val.c_str())); } } // - val is now translated enum (or original value if value does not match any enum text) valsiz+=val.size(); // perform escaping and determine need for encoding bool spaceonly = true; bool firstchar = true; for (const char *p=val.c_str();(c=*p)!=0 && (c!=aConvDefP->combineSep);p++) { // process char // - check for whitespace if (!isspace(c)) { spaceonly = false; // does not consist of whitespace only aNumNonSpcs++; // count consecutive non-spaces if (aMimeMode==mimo_old && aEncoding==enc_none && aNumNonSpcs>MIME_MAXLINESIZE) { // If text contains words with critical (probably unfoldable) size in mimo-old, select quoted printable encoding aEncoding=enc_quoted_printable; } } else { aNumNonSpcs = 0; // new word starts } // only text must be fully escaped, turn escaping off for RRULE (RECUR type) // escape reserved chars switch (c) { case '"': if (firstchar && aParamValue && aMimeMode==mimo_standard) goto do_escape; // if param value starts with a double quote, we need to escape it because param value can be in double-quote-enclosed form goto add_char; // otherwise, just add case ',': // in MIME-DIR, always escape commas, in pre-MIME-DIR only if usage in value list requires it if (!aCommaEscape && aMimeMode==mimo_old) goto add_char; goto do_escape; case ':': // always escape colon in parameters if (!aParamValue) goto add_char; goto do_escape; case '\\': // Backslash must always be escaped // - for MIMO-old: at least Nokia 9210 does it this way // - for MIME-DIR: specified in the standard goto do_escape; case ';': // in MIME-DIR, always escape semicolons, in pre-MIME-DIR only in parameters and structured values if (!aParamValue && !aStructured && aMimeMode==mimo_old) goto add_char; do_escape: if (!aEscapeOnlyLF) { // escape chars with backslash outval+='\\'; } goto out_char; case '\r': // ignore returns break; case '\n': // quote linefeeds if (aMimeMode==mimo_old) { if (aEncoding==enc_none) { // For line ends in mimo_old: select quoted printable encoding aEncoding=enc_quoted_printable; } // just pass it, will be encoded later goto add_char; } else { // MIME-DIR: use quoted C-style notation outval.append("\\n"); } break; default: add_char: // prevent adding space-only for params if (spaceonly && aParamValue) break; // just check next out_char: // check for non ASCII and set flag if found if ((uInt8)c > 0x7F) aNonASCII=true; // just copy to output outval+=c; firstchar = false; // first char is out break; } } // for all chars in val item // go to next item in the val list (if any) if (*lp!=0) { // more items in the list // - add separator if previous one is not empty param value if (!(spaceonly && aParamValue)) { if (aMimeMode==mimo_standard || aFoldAtSeparators) { outval+='\b'; // preferred break location (or location where extra space is allowed for mimo_old) aNumNonSpcs=0; // we can fold here, so word is broken } outval+=aSeparator; aNumNonSpcs++; // count it (assuming separator is never a space!) valsiz++; // count it as part of the value } lp++; // skip input list separator } // check for truncation needs (do not truncate parameters, ever) if (maxSiz && valsiz>maxSiz && !aParamValue) { // size exceeded if (noTruncate) { // truncate not allowed PDEBUGPRINTFX(DBG_ERROR+DBG_GEN,( "Value '%" FMT_LENGTH(".40") "s' exceeds %ld chars net length but is noTruncate -> omit", FMT_LENGTH_LIMITED(40,outval.c_str()), (long)maxSiz )); // treat it as if field was not supported locally return GENVALUE_NOTSUPPORTED; } else { // truncate allowed, shorten output accordingly outval.erase(outval.size()-(valsiz-maxSiz)); PDEBUGPRINTFX(DBG_GEN,( "Truncated value '%" FMT_LENGTH(".40") "s' to %ld chars net length (maxSize)", FMT_LENGTH_LIMITED(40,outval.c_str()), (long)maxSiz )); // do not add more chars break; } } } // while value chars available } // not BLOB conversion // value generated in outval (altough it might be an empty string) } // if field assigned else { // not assigned. However a not assigned array means an array with no elements, which // is the same as an exhausted array return isarray ? GENVALUE_EXHAUSTED : GENVALUE_NOTSUPPORTED; // array is exhaused, non-array unassigned means not available } } // source and target both support the field (or field belongs to mandatory property) else return GENVALUE_NOTSUPPORTED; // field not supported by either source or target (and not mandatory) -> do not generate value } // if fieldid exists else { // could be special conversion using no data or data from // internal object variables (such as VERSION value) if (fieldToMIMEString(aItem,FID_NOT_SUPPORTED,0,aConvDefP,vallist)) { // got some output, use it as value outval=vallist; } else // no value, no output return GENVALUE_NOTSUPPORTED; // field not supported } // now we have a value in outval, check if encoding needs to be applied // - check if we should select QUOTED-PRINTABLE because of nonASCII if (aNonASCII && fDoQuote8BitContent && aEncoding==enc_none) aEncoding=enc_quoted_printable; // just append if (!outval.empty() && aFirstChar!=0) { if (aMimeMode==mimo_standard || aFoldAtSeparators) { aString+='\b'; // preferred break location (or location where extra space is allowed for mimo_old) aNumNonSpcs = 0; // we can break here, new word starts } aString+=aFirstChar; // we have a value, add sep char first aNumNonSpcs++; // count it (assuming separator is never a space!) } aString.append(outval); // done return outval.empty() ? (isarray ? GENVALUE_EMPTYELEMENT : GENVALUE_EMPTY) // empty : (isarray ? GENVALUE_ELEMENT : GENVALUE_NONEMPTY); // non empty } // TMimeDirProfileHandler::generateValue // generate parameters for one property instance // - returns true if parameters with shownonempty=true were generated bool TMimeDirProfileHandler::generateParams( TMultiFieldItem &aItem, // the item where data comes from string &aString, // the string to add parameters to const TPropertyDefinition *aPropP, // the property to generate (all instances) TMimeDirMode aMimeMode, // MIME mode (older or newer vXXX format compatibility) sInt16 aBaseOffset, sInt16 aRepOffset, TPropNameExtension *aPropNameExt, // propname extension for generating musthave param values sInt32 &aNumNonSpcs // number of consecutive non-spaces, accumulated so far ) { const TParameterDefinition *paramP; bool paramstarted; char sep=0; // separator for value lists bool nonasc=false; TEncodingTypes encoding; string paramstr; bool showalways=false; // Generate parameters // Note: altough positional values are always the same, non-positional values // can vary from repetition to repetition and can be mixed with the // positional values. So we must generate the mixture again for // every repetition. // - check all parameters for musthave values paramP = aPropP->parameterDefs; while (paramP) { // parameter not started yet paramstarted=false; // process param only if matching mode and active rules if (mimeModeMatch(paramP->modeDependency) #ifndef NO_REMOTE_RULES && (!paramP->ruleDependency || isActiveRule(paramP->ruleDependency)) #endif ) { // first append extendsname param values if (paramP->extendsname && aPropNameExt) { const TEnumerationDef *enumP = paramP->convdef.enumdefs; while (enumP) { if (enumP->nameextid>=0) { // value is relevant for name extension, check if required for this param if ((((TNameExtIDMap)1<nameextid) & (aPropNameExt->musthave_ids | aPropNameExt->addtlSend_ids))!=0) { // found param value which is required or flagged to be sent additionally as name extension if (!paramstarted) { paramstarted=true; aString+=';'; // param always starts with ; if (paramP->defaultparam && (aMimeMode==mimo_old)) { // default param, values are written like a list of params sep=';'; // separator, in case other values follow } else { // normal parameter, first add param separator and name // - lead-in aString.append(paramP->paramname); aString+='='; // - separator, in case other values follow sep=','; // value list separator is comma by default } } else { // add separator for one more value aString+=sep; } // add value aString.append(enumP->enumtext); } // if enum value is a "must have" value for name extension } // if enum value is relevant to name extension // next enum value enumP=enumP->next; } // while enum values } // if extendsname // append value(s) if there is an associated field paramstr.erase(); // none to start with if (paramP->convdef.fieldid!=FID_NOT_SUPPORTED) { if (!paramstarted) { // Note: paramstarted must not be set here, as empty value might prevent param from being written // parameter starts with ";" paramstr+=';'; if (paramP->defaultparam && (aMimeMode==mimo_old)) { // default param, values are written like a list of params sep=';'; } else { // normal parameter, first add name paramstr.append(paramP->paramname); paramstr+='='; sep=','; // value list separator is comma by default } } else { // already started values, just add more // - next value starts with a separator paramstr+=sep; } // add parameter value(list) encoding=enc_none; // parameters are not encoded // NOTE: only non-empty parameters are generated // NOTE: parameters themselves cannot have a value list that is stored in an array, // but parameters of repeating properties can be stored in array elements (using the // same index as for the property itself) // Note: Escape commas if separator is a comma sInt32 numNoSpcs = aNumNonSpcs; if (generateValue(aItem,&(paramP->convdef),aBaseOffset,aRepOffset,paramstr,sep,aMimeMode,true,false,sep==',',encoding,nonasc,0,numNoSpcs,false,false)>=GENVALUE_ELEMENT) { // value generated, add parameter name/value (or separator/value for already started params) aString.append(paramstr); aNumNonSpcs = numNoSpcs; // actually added, count now paramstarted=true; // started only if we really have appended something at all } } // if field defined for this param // update show status if (paramP->shownonempty && paramstarted) showalways=true; // param has a value and must make property show } // next param paramP=paramP->next; } // while params return showalways; } // TMimeDirProfileHandler::generateParams // generateProperty return codes: #define GENPROP_EXHAUSTED 0 // nothing generated because data source exhausted (or field not supported) #define GENPROP_EMPTY 1 // nothing generated because empty value (but field supported) #define GENPROP_NONEMPTY 2 // something generated // helper for generateMimeDir(), expansion of property according to nameExts void TMimeDirProfileHandler::expandProperty( TMultiFieldItem &aItem, // the item where data comes from string &aString, // the string to add properties to const char *aPrefix, // the prefix (property name) const TPropertyDefinition *aPropP, // the property to generate (all instances) TMimeDirMode aMimeMode // MIME mode (older or newer vXXX format compatibility) ) { // scan nameExts to generate name-extended variants and repetitions TPropNameExtension *propnameextP = aPropP->nameExts; if (!propnameextP) { // no name extensions -> this is a non-repeating property // just generate once, even if empty (except if it has suppressempty set) generateProperty( aItem, // the item where data comes from aString, // the string to add properties to aPrefix, // the prefix (property name) aPropP, // the property to generate 0, // field ID offset to be used 0, // additional repeat offset / array index aMimeMode, // MIME mode (older or newer vXXX format compatibility) false // if set, a property with only empty values will never be generated ); } else { // scan name extensions sInt16 generated=0; sInt16 maxOccur=0; // default to no limit while (propnameextP) { sInt16 baseoffs=propnameextP->fieldidoffs; sInt16 repoffs=0; // no repeat offset yet if (baseoffs!=OFFS_NOSTORE && !propnameextP->readOnly) { // we can address fields for this property and it's not readonly (parsing variant) // generate value part sInt16 n=propnameextP->maxRepeat; // check for value list if (aPropP->valuelist && !aPropP->expandlist) { // property contains a value list -> all repetitions are shown within ONE property instance // NOTE: generateProperty will exhaust possible repeats generateProperty( aItem, // the item where data comes from aString, // the string to add properties to aPrefix, // the prefix (property name) aPropP, // the property to generate baseoffs, // field ID offset to be used repoffs, // additional repeat offset / array index aMimeMode, // MIME mode (older or newer vXXX format compatibility) propnameextP->minShow<1, // suppress if fewer to show than 1 (that is, like suppressempty in this case) propnameextP // propname extension for generating musthave param values and maxrep/repinc for valuelists ); } else { // now generate separate properties for all repetitions // Note: strategy is to keep order as much as possible (completely if // minShow is >= maxRepeat sInt16 emptyRepOffs=-1; // get occurrence limit as provided by remote for (sInt16 i=0; inumValues; i++) { sInt16 fid=aPropP->convdefs[0].fieldid; if (fid>=0) { if (fRelatedDatastoreP) { // only if datastore is related we are in SyncML context, otherwise we should not check maxOccur maxOccur = aItem.getItemType()->getFieldOptions(fid)->maxoccur; } else maxOccur = 0; // no limit // Note: all value fields of the property will have the same maxOccur, so we can stop here break; } } do { // generate property for this repetition // - no repeating within generateProperty takes place! sInt16 genres = generateProperty( aItem, // the item where data comes from aString, // the string to add properties to aPrefix, // the prefix (property name) aPropP, // the property to generate baseoffs, // field ID offset to be used repoffs, // additional repeat offset / array index aMimeMode, // MIME mode (older or newer vXXX format compatibility) propnameextP->minShow-generatedmaxRepeat==REP_ARRAY && genres==GENPROP_EXHAUSTED) break; // exit loop if any only if array exhausted } // one more generated of the maximum possible (note: REP_ARRAY=32k, so this will not limit an array) n--; repoffs+=propnameextP->repeatInc; // end generation if remote's maxOccur limit is reached if (maxOccur && generated>=maxOccur) { PDEBUGPRINTFX(DBG_GEN,( "maxOccur (%hd) for Property '%s' reached - no more instances will be generated", maxOccur, TCFG_CSTR(aPropP->propname) )); break; } } while(n>0); // add empty ones if needed while (generatedminShow && emptyRepOffs>=0 && !(maxOccur && generated>=maxOccur)) { // generate empty ones (no suppression) generateProperty(aItem,aString,aPrefix,aPropP,baseoffs,emptyRepOffs,aMimeMode,false); generated++; // count as generated anyway (even in case generation of empty is globally turned off) } } // repeat properties when we have repeating enabled } // if name extension is stored propnameextP=propnameextP->next; // stop if maxOccur reached if (maxOccur && generated>=maxOccur) break; } // while nameexts } // if nameexts at all } // TMimeDirProfileHandler::expandProperty // helper for expandProperty: generates property // returns: GENPROP_xxx sInt16 TMimeDirProfileHandler::generateProperty( TMultiFieldItem &aItem, // the item where data comes from string &aString, // the string to add properties to const char *aPrefix, // the prefix (property name) const TPropertyDefinition *aPropP, // the property to generate (all instances) sInt16 aBaseOffset, // field ID offset to be used sInt16 aRepeatOffset, // additional repeat offset / array index TMimeDirMode aMimeMode, // MIME mode (older or newer vXXX format compatibility) bool aSuppressEmpty, // if set, a property with only empty values will not be generated TPropNameExtension *aPropNameExt // propname extension for generating musthave param values and maxrep/repinc for valuelists ) { string proptext; // unfolded property text proptext.reserve(300); // not too small string elemtext; // single element (value or param) text TEncodingTypes encoding; bool nonasc=false; // - reset TZID presence flag fPropTZIDtctx = TCTX_UNKNOWN; // - start with empty text proptext.erase(); // - init flags bool anyvaluessupported = false; // at least one of the main values must be supported by the remote in order to generate property at all bool arrayexhausted = false; // flag will be set if a main value was not generated because array exhausted bool anyvalues = false; // flag will be set when at least one value has been generated sInt32 numNonSpcs=0; encoding=enc_none; // default is no encoding sInt16 v=0; // value counter nonasc=false; // assume plain ASCII sInt16 genres; TEncodingTypes enc; bool na; const TConversionDef *convP; // - now generate if (aPropP->unprocessed) { convP = &(aPropP->convdefs[0]); // unfolded and not-linefeed-escaped raw property stored in string - generate it as one value enc=encoding; na=false; genres=generateValue( aItem, convP, aBaseOffset, // base offset, relative to aRepeatOffset, // repeat offset or array index elemtext, // value will be stored here (might be binary in case of BLOBs, but then encoding will be set) 0, // should for some exotic reason values consist of a list, separate it by "," (";" is reserved for structured values) aMimeMode, false, // no parameter false, // not structured value, don't escape ";" false, // don't escape commas, either enc, // will receive needed encoding (usually B64 for binary values) na, 0, // no first char numNonSpcs, // number of consecutive non-spaces, accumulated aPropP->allowFoldAtSep, true // linefeed only escaping ); // check if something was generated if (genres>=GENVALUE_ELEMENT) { // generated something, might have caused encoding/noasc change encoding=enc; nonasc=nonasc || na; anyvaluessupported=true; anyvalues=true; // separate name+params and values bool dq = false; bool fc = true; size_t pti = string::npos; appChar c; for (cAppCharP p=elemtext.c_str(); (c=*p)!=0; p++) { if (dq) { if (c=='"') dq = false; // end of double quoted part } else { // not in doublequote if (fc && c=='"') dq = true; // if first char is doublequote, start quoted string else if (c==':') { pti = p-elemtext.c_str(); break; } // found else if (c=='\\' && *(p+1)) p++; // make sure next char is not evaluated } fc = false; // no longer first char } if (pti!=string::npos) { proptext.assign(elemtext, 0, pti); // name+params without separator elemtext.erase(0, pti+1); // remove name and separator } } else { arrayexhausted = true; // no more values, assume array exhausted } } else { // Normally generated property // - first set group if there is one if (aPropP->groupFieldID!=FID_NOT_SUPPORTED) { // get group name TItemField *g_fldP = aItem.getArrayFieldAdjusted(aPropP->groupFieldID+aBaseOffset, aRepeatOffset, true); if (g_fldP && !g_fldP->isEmpty()) { g_fldP->appendToString(proptext); proptext += '.'; // group separator } } // - append name and (possibly) parameters that are constant over all repetitions proptext += aPrefix; // - up to here assume no spaces numNonSpcs = proptext.size()+14; // some extra room for possible ";CHARSET=UTF8" // - append parameter values // anyvalues gets set if a parameter with shownonempty attribute was generated anyvalues=generateParams( aItem, // the item where data comes from proptext, // where params will be appended aPropP, // the property definition aMimeMode, aBaseOffset, aRepeatOffset, aPropNameExt, numNonSpcs ); // - append value(s) sInt16 maxrep=1,repinc=1; if (aPropNameExt) { maxrep=aPropNameExt->maxRepeat; repinc=aPropNameExt->repeatInc; } // generate property contents if (aPropP->valuelist && !aPropP->expandlist) { // property with value list // NOTE: convdef[0] is used for all values, aRepeatOffset changes convP = &(aPropP->convdefs[0]); // - now iterate over available repeats or array contents while(aRepeatOffsetvaluesep, // use valuelist separator between multiple values possibly generated from a list in a single field (e.g. CATEGORIES) aMimeMode, false, // not a param true, // always escape ; in valuelist properties aPropP->valuesep==',' || aPropP->altvaluesep==',', // escape commas if one of the separators is a comma enc, na, v>0 ? aPropP->valuesep : 0, // separate with specified multi-value-delimiter if not first value numNonSpcs, // number of consecutive non-spaces, accumulated aPropP->allowFoldAtSep, (convP->convmode & CONVMODE_MASK)==CONVMODE_RRULE // RRULES are not to be escaped ); // check if something was generated if (genres>=GENVALUE_ELEMENT) { // generated something, might have caused encoding/noasc change encoding=enc; nonasc=nonasc || na; } // update if we have at least one value of this property supported (even if empty) by the remote party if (genres>GENVALUE_NOTSUPPORTED) anyvaluessupported=true; if (genres==GENVALUE_EXHAUSTED) arrayexhausted=true; // for at least one component of the property, the array is exhausted // update if we have any value now (even if only empty) // - generate empty property according to // - aSuppressEmpty // - session-global fDontSendEmptyProperties // - supressEmpty property flag in property definition // - if no repeat (i.e. no aPropNameExt), exhausted array is treated like empty value (i.e. rendered unless suppressempty set) anyvalues = anyvalues || (genres>= (aSuppressEmpty || fDontSendEmptyProperties || aPropP->suppressEmpty ? GENVALUE_ELEMENT // if empty values should be suppressed, we need a non-empty element (array or simple field) : GENVALUE_EXHAUSTED // for valuelists, if empty values are not explicitly suppressed (i.e. minshow==0, see caller) exhausted array must always produce an empty value ) ); // count effective value appended v++; // update repeat offset aRepeatOffset+=repinc; // check for array mode - stop if array is exhausted or field not supported if (maxrep==REP_ARRAY && genres<=GENVALUE_EXHAUSTED) break; } } else { // property with individual values (like N) // NOTE: field changes with different convdefs, offsets remain stable arrayexhausted = true; // assume all arrays exhausted unless we find at least one non-exhausted array bool somearrays = false; // no arrays yet do { convP = &(aPropP->convdefs[v]); // generate one value enc=encoding; na=false; genres=generateValue( aItem, convP, aBaseOffset, // base offset, relative to aRepeatOffset, // repeat offset or array index elemtext, // value will be stored here (might be binary in case of BLOBs, but then encoding will be set) ',', // should for some exotic reason values consist of a list, separate it by "," (";" is reserved for structured values) aMimeMode, false, aPropP->numValues>1, // structured value, escape ";" aPropP->altvaluesep==',', // escape commas if alternate separator is a comma enc, // will receive needed encoding (usually B64 for binary values) na, 0, // no first char numNonSpcs, // number of consecutive non-spaces, accumulated aPropP->allowFoldAtSep, (convP->convmode & CONVMODE_MASK)==CONVMODE_RRULE // RRULES are not to be escaped ); //* %%% */ PDEBUGPRINTFX(DBG_EXOTIC,("generateValue #%hd for property '%s' returns genres==%hd",v,TCFG_CSTR(aPropP->propname),genres)); // check if something was generated if (genres>=GENVALUE_ELEMENT) { // generated something, might have caused encoding/noasc change encoding=enc; nonasc=nonasc || na; } // update if we have at least one value of this property supported (even if empty) by the remote party if (genres>GENVALUE_NOTSUPPORTED) anyvaluessupported=true; if (genres==GENVALUE_ELEMENT || genres==GENVALUE_EMPTYELEMENT) { arrayexhausted = false; // there is at least one non-exhausted array we're reading from (even if only empty value) somearrays = true; // generating from array } else if (genres==GENVALUE_EXHAUSTED) somearrays = true; // generating from array // update if we have any value now (even if only empty) // - generate empty property according to // - aSuppressEmpty // - session-global fDontSendEmptyProperties // - supressEmpty property flag in property definition // - if no repeat (i.e. no aPropNameExt), exhausted array is treated like empty value (i.e. rendered unless suppressempty set) anyvalues = anyvalues || (genres>=(aSuppressEmpty || fDontSendEmptyProperties || aPropP->suppressEmpty ? GENVALUE_ELEMENT : (aPropNameExt ? GENVALUE_EMPTYELEMENT : GENVALUE_EXHAUSTED))); // insert delimiter if not last value v++; if (v>=aPropP->numValues) break; // done with all values // add delimiter for next value if (aMimeMode==mimo_standard || aPropP->allowFoldAtSep) { elemtext+='\b'; // preferred break location (or location where extra space is allowed for mimo_old) numNonSpcs = 0; // can break here, new word starts } elemtext+=aPropP->valuesep; numNonSpcs++; // count it (assuming separator is never a space!) // add break indicator } while(true); // if none of the data sources is an array, we can't be exhausted. if (!somearrays) arrayexhausted = false; } } // normal generated property from components // - finalize property if it contains supported fields at all (or is mandatory) if ((anyvaluessupported && anyvalues) || aPropP->mandatory) { // - generate charset parameter if needed // NOTE: MIME-DIR based formats do NOT have the CHARSET attribute any more! if (nonasc && aMimeMode==mimo_old && fDefaultOutCharset!=chs_ansi) { // non-ASCII chars contained, generate property telling what charset is used proptext.append(";CHARSET="); proptext.append(MIMECharSetNames[fDefaultOutCharset]); } // - generate encoding parameter if needed if (encoding!=enc_none) { // in MIME-DIR, only "B" is allowed for binary, for vCard 2.1 it is "BASE64" if (encoding==enc_base64 || encoding==enc_b) { encoding = aMimeMode==mimo_standard ? enc_b : enc_base64; } // add the parameter proptext.append(";ENCODING="); proptext.append(MIMEEncodingNames[encoding]); } // - separate value from property text proptext+=':'; // - append (probably encoded) values now, always in UTF-8 encodeValues(encoding,fDefaultOutCharset,elemtext,proptext,fDoNotFoldContent); // - fold, copy and terminate (CRLF) property into aString output finalizeProperty(proptext.c_str(),aString,aMimeMode,fDoNotFoldContent,encoding==enc_quoted_printable); // - special case: base64 (but not B) encoded value must have an extra CRLF even if folding is // disabled, so we need to insert it here (because non-folding mode eliminates it from being // generated automatically in encodeValues/finalizeProperty) if (fDoNotFoldContent && encoding==enc_base64) aString.append("\x0D\x0A"); // extra CRLF terminating a base64 encoded property (note, base64 only occurs in mimo_old) // - property generated return GENPROP_NONEMPTY; } else { // Note: it is essential to return GENPROP_EXHAUSTED if no values are supported for this property at // all (otherwise caller might loop endless trying to generate a non-empty property return anyvaluessupported ? (arrayexhausted ? GENPROP_EXHAUSTED : GENPROP_EMPTY) // no property generated : GENPROP_EXHAUSTED; // no values supported means "exhausted" as well } } // TMimeDirProfileHandler::generateProperty // generate MIME-DIR from item into string object void TMimeDirProfileHandler::generateMimeDir(TMultiFieldItem &aItem, string &aString) { // clear string aString.reserve(3000); // not too small aString.erase(); // reset item time zone before generating fHasExplicitTZ = false; // none set explicitly fItemTimeContext = fReceiverTimeContext; // default to receiver context fUsedTCtxSet.clear(); // no TZIDs used yet fEarliestTZDate = noLinearTime; // reset range of generated timestamps related to a TZID or TZ/DAYLIGHT fLatestTZDate = noLinearTime; fVTimeZonePendingProfileP = NULL; // no VTIMEZONE pending for generation fVTimeZoneInsertPos = 0; // no insert position yet // recursively generate levels generateLevels(aItem,aString,fProfileDefinitionP); // now generate VTIMEZONE, if needed if (fVTimeZonePendingProfileP) { string s, val, vtz; vtz.erase(); // generate needed vTimeZones (according to fUsedTCtxSet) for (TTCtxSet::iterator pos=fUsedTCtxSet.begin(); pos!=fUsedTCtxSet.end(); pos++) { // - calculate first and last year covered by timestamps in this record sInt16 startYear=0,endYear=0; if (fEarliestTZDate && fProfileCfgP->fVTimeZoneGenMode!=vtzgen_current) { // dependent on actually created dates lineartime2date(fEarliestTZDate, &startYear, NULL, NULL); lineartime2date(fLatestTZDate, &endYear, NULL, NULL); // there is at least one date in the record switch (fProfileCfgP->fVTimeZoneGenMode) { case vtzgen_start: endYear = startYear; // only show for start of range break; case vtzgen_end: startYear = endYear; // only show for end of range break; case vtzgen_range: // pass both start and end year break; case vtzgen_openend: // pass start year but request that all rules from start up to the current date are inlcuded endYear = 0; break; case vtzgen_current: case numVTimeZoneGenModes: // case statement to keep gcc happy, will not be reached because of if() above break; } } // - lead-in s="BEGIN:"; s.append(fVTimeZonePendingProfileP->levelName); finalizeProperty(s.c_str(),vtz,fMimeDirMode,false,false); // - generate raw string //%%% endYear is not yet implemented in internalToVTIMEZONE(), fTzIdGenMode has only the olson option for now internalToVTIMEZONE(*pos, val, getSessionZones(), NULL, startYear, endYear, fProfileCfgP->fTzIdGenMode==tzidgen_olson ? "o" : NULL); size_t i,n = 0; while (val.size()>n) { i = val.find('\n',n); // next line end if (i==string::npos) i=val.size(); if (i-n>1) { // more than one char = not only a trailing line end s.assign(val,n,i-n); // finalize and add property finalizeProperty(s.c_str(),vtz,fMimeDirMode,false,false); // advance cursor beyond terminating LF n=i+1; } } // - lead out s="END:"; s.append(fVTimeZonePendingProfileP->levelName); finalizeProperty(s.c_str(),vtz,fMimeDirMode,false,false); } // for // now insert the VTIMEZONE into the output string (so possibly making it appear BEFORE the // properties that use TZIDs) aString.insert(fVTimeZoneInsertPos, vtz); // done fVTimeZonePendingProfileP = NULL; } // if pending VTIMEZONE } // TMimeDirProfileHandler::generateMimeDir // generate nested levels of MIME-DIR content void TMimeDirProfileHandler::generateLevels( TMultiFieldItem &aItem, string &aString, const TProfileDefinition *aProfileP ) { // check if level must be generated bool dolevel=false; string s,val; sInt16 fid=aProfileP->levelConvdef.fieldid; if (fid<0) dolevel=true; // if no controlling field there, generate anyway else { // check field contents to determine if generation is needed if (aItem.isAssigned(fid)) { const TEnumerationDef *enumP = aProfileP->levelConvdef.enumdefs; aItem.getField(fid)->getAsString(val); if (enumP) { // if enumdefs, content must match first enumdef's enumval (NOT enumtext!!) dolevel = strucmp(val.c_str(),TCFG_CSTR(enumP->enumval))==0; } else { // just being not empty enables level dolevel = !aItem.getField(fid)->isEmpty(); } } } // check for MIME mode dependency dolevel = dolevel && mimeModeMatch(aProfileP->modeDependency); // generate level if enabled if (dolevel) { // generate level start if (aProfileP->profileMode==profm_vtimezones) { // don't generate now, just remember the string position where we should add the // VTIMEZONEs when we're done generating the record. fVTimeZonePendingProfileP = aProfileP; fVTimeZoneInsertPos = aString.size(); } else { // standard custom level s="BEGIN:"; s.append(aProfileP->levelName); finalizeProperty(s.c_str(),aString,fMimeDirMode,false,false); // loop through all properties of that level const TPropertyDefinition *propP = aProfileP->propertyDefs; #ifndef NO_REMOTE_RULES uInt16 propGroup=0; // group identifier (all props with same name have same group ID) const TPropertyDefinition *otherRulePropP = NULL; // default property which is used if none of the rule-dependent in the group was used bool ruleSpecificExpanded = false; #endif const TPropertyDefinition *expandPropP; while (propP) { // check for mode dependency if (!mimeModeMatch(propP->modeDependency)) { // no mode match -> just skip this one propP=propP->next; continue; } #ifndef NO_REMOTE_RULES // check for beginning of new group (no or different property group number) if (propP->propGroup==0 || propP->propGroup!=propGroup) { // end of last group - start of new group propGroup = propP->propGroup; // remember new group number // expand "other"-rule dependent variant from last group if (!ruleSpecificExpanded && otherRulePropP) { expandProperty( aItem, aString, TCFG_CSTR(otherRulePropP->propname), // the prefix consists of the property name otherRulePropP, // the property definition fMimeDirMode // MIME-DIR mode ); } // for next group, no rule-specific version has been expanded yet ruleSpecificExpanded = false; // for next group, we don't have a "other"-rule variant otherRulePropP=NULL; } // check if entry is rule-specific expandPropP=NULL; // do not expand by default if (propP->dependsOnRemoterule) { // check if depends on current rule if (propP->ruleDependency==NULL) { // this is the "other"-rule dependent variant // - just remember otherRulePropP=propP; } else if (isActiveRule(propP->ruleDependency)) { // specific for the applied rule expandPropP=propP; // default to expand current prop // now we have expanded a rule-specific property (blocks expanding of "other"-rule dependent prop) ruleSpecificExpanded=true; } } else { // does not depend on rule, expand anyway expandPropP=propP; } // check if this is last prop of list propP=propP->next; if (!propP && otherRulePropP && !ruleSpecificExpanded) { // End of prop list, no rule-specific expand yet, and there is a otherRuleProp // expand "other"-rule's property instead expandPropP=otherRulePropP; } #else // simply expand it expandPropP=propP; propP=propP->next; #endif // now expand if selected if (expandPropP) { // recursively generate all properties that expand from this entry // (includes extendsfieldid-parameters and repetitions expandProperty( aItem, aString, TCFG_CSTR(expandPropP->propname), // the prefix consists of the property name expandPropP, // the property definition fMimeDirMode // MIME-DIR mode ); } } // properties loop // generate sublevels, if any const TProfileDefinition *subprofileP = aProfileP->subLevels; while (subprofileP) { // generate sublevels (possibly, none is generated) generateLevels(aItem,aString,subprofileP); // next subprofileP=subprofileP->next; } // generate level end s="END:"; s.append(aProfileP->levelName); finalizeProperty(s.c_str(),aString,fMimeDirMode,false,false); } // normal level } // if level must be generated } // TMimeDirProfileHandler::generateLevels // Convert string from MIME-format into field value(s). // - the string passed to this function is already a translated value // list if combinesep is set, and every single value is already // enum-translated if enums are defined. // - returns false if field(s) could not be assigned because aText has // a bad syntax. // - returns true if field(s) assigned something useful or no field is // available to assign anything to. bool TMimeDirProfileHandler::MIMEStringToField( const char *aText, // the value text to assign or add to the field const TConversionDef *aConvDefP, // the conversion definition record TMultiFieldItem &aItem, // the item where data goes to sInt16 aFid, // the field ID (can be NULL for special conversion modes) sInt16 aArrIndex // the repeat offset to handle array fields ) { sInt16 moffs; uInt16 offs,n; bool isBitMap; fieldinteger_t flags = 0; TTimestampField *tsFldP; timecontext_t tctx; TParsedTzidSet::iterator tz; string s; // RRULE lineartime_t dtstart; timecontext_t startcontext = 0, untilcontext = 0; char freq; char freqmod; sInt16 interval; fieldinteger_t firstmask; fieldinteger_t lastmask; lineartime_t until; bool dostore; // get pointer to leaf field TItemField *fldP = aItem.getArrayField(aFid,aArrIndex); sInt16 convmode = aConvDefP->convmode & CONVMODE_MASK; switch (convmode) { case CONVMODE_MAILTO: // remove the mailto: prefix if there is one if (strucmp(aText,"mailto:",7)==0) aText+=7; // remove leading "mailto:" goto normal; case CONVMODE_EMPTYONLY: // same as CONVMODE_NONE, but assigns only first occurrence (that is, // when field is still empty) if (!fldP) return true; // no field, assignment "ok" (=nop) if (!fldP->isEmpty()) return true; // field not empty, discard new assignment case CONVMODE_TIMESTAMP: // nothing special for parsing case CONVMODE_AUTODATE: // nothing special for parsing case CONVMODE_AUTOENDDATE: // check for "last minute of the day" case CONVMODE_DATE: // dates will be made floating case CONVMODE_NONE: normal: if (!fldP) return true; // no field, assignment "ok" (=nop) // just set as string or add if combine mode if (aConvDefP->combineSep) { // combine mode if (!fldP->isEmpty()) { // not empty, append with separator char cs[2]; cs[0]=aConvDefP->combineSep; cs[1]=0; fldP->appendString(cs); } fldP->appendString(aText); } else { // for non-strings, skip leading spaces before trying to parse if (!fldP->isBasedOn(fty_string)) { while (*aText && *aText==' ') aText++; // skip leading spaces } // simple assign mode if (fldP->isBasedOn(fty_timestamp)) { // read as ISO8601 timestamp tsFldP = static_cast(fldP); // if field already has a non-unknown context (e.g. set via TZID, or TZ/DAYLIGHT), // use that as context for floating ISO date (i.e. no "Z" or "+/-hh:mm" suffix) if (!tsFldP->isFloating()) { // field already has a TZ specified (e.g. by a TZID param), use that instead of item level context tctx = tsFldP->getTimeContext(); } else { // no pre-known zone for this specific field, check if property has a specific zone if (!TCTX_IS_UNKNOWN(fPropTZIDtctx)) { // property has a specified time zone context from a TZID, use it tctx = fPropTZIDtctx; // default to property's TZID (if one was parsed, otherwise this will be left floating) } else if (fHasExplicitTZ) { // item has an explicitly specified time zone context (e.g. set via TZ: property), // treat all timestamps w/o own time zone ("Z" suffix) in that context tctx = fItemTimeContext; } else { // item has no explicitly specified time zone context, // parse and leave floating float for now tctx = TCTX_UNKNOWN; // default to floating } } // Now tctx is the default zone to bet set for ALL values that are in floating notation // - check for special handling of misbehaving remotes if (fTreatRemoteTimeAsLocal || fTreatRemoteTimeAsUTC) { // ignore time zone specs which might be present possibly tsFldP->setAsISO8601(aText, tctx, true); // now force time zone to item/user context or UTC depending on flag settings tctx = fTreatRemoteTimeAsLocal ? fItemTimeContext : TCTX_UTC; // set it tsFldP->setTimeContext(tctx); } else { // read with time zone, if present, and default to tctx set above tsFldP->setAsISO8601(aText, tctx, false); // check if still floating now if (tsFldP->isFloating()) { // unfloat only if remote cannot handle UTC and therefore ALWAYS uses localtime. // otherwise, assume that floating status is intentional and must be retained. // Note: TZID and TZ, if present, are already applied by now // Note: DURATION and DATE floating will always be retained, as they are always intentional if ((!fReceiverCanHandleUTC || fProfileCfgP->fUnfloatFloating) && !TCTX_IS_DATEONLY(tsFldP->getTimeContext()) && !tsFldP->isDuration()) { // not intentionally floating, but just not capable otherwise // - put it into context of item (which is in this case session's user context) tsFldP->setTimeContext(fItemTimeContext); } } else { // non-floating if (fHasExplicitTZ) { // item has explicit zone - move timestamp to it (e.g. if timestamps are sent // in ISO8601 Z notation, but a TZ/DAYLIGHT or TZID is present) tsFldP->moveToContext(tctx,false); } } } // special conversions if (convmode==CONVMODE_DATE) { tsFldP->makeFloating(); // date-only is forced floating } else if (convmode==CONVMODE_AUTOENDDATE && fMimeDirMode==mimo_old) { // check if this could be a 23:59 type end-of-day lineartime_t ts = tsFldP->getTimestampAs(fItemTimeContext,&tctx); // get in item context or floating lineartime_t ts0 = lineartime2dateonlyTime(ts); if (ts0!=ts && AlldayCount(ts0,ts)>0) { // only if not already a 0:00 // this is a 23:59 type end-of-day, convert it to midnight of next day (AND adjust time context, in case it is now different from original) tsFldP->setTimestampAndContext(lineartime2dateonlyTime(ts)+linearDateToTimeFactor,tctx); } } } else { // read as text fldP->setAsString(aText); } } return true; // found // Time zones case CONVMODE_TZ: // parse time zone if (ISO8601StrToContext(aText, tctx)!=0) { // Note: this is always global for the entire item, so set the item context // (which is then used when parsing dates (which should be delayed to make sure TZ is seen first) fItemTimeContext = tctx; if (!TCTX_IS_TZ(tctx)) { // only offset. Try to symbolize it by passing a DAYLIGHT:FALSE and the offset if (TzDaylightToContext("FALSE", fItemTimeContext, tctx, getSessionZones(), fReceiverTimeContext)) fItemTimeContext = tctx; // there is a symbolized context, keep that } fHasExplicitTZ = true; // zone explicitly set, not only copied from session's user zone goto timecontext; } return true; // not set, is ok case CONVMODE_DAYLIGHT: // parse DAYLIGHT zone description property, prefer user zone (among multiple zones matching the Tz/daylight info) // - resolve to offset (assuming that item context came from a TZ property, so it will // be one of the non-DST zones, so reftime does not matter) tctx = fItemTimeContext; TzResolveContext(tctx, getSystemNowAs(TCTX_UTC, getSessionZones()), true, getSessionZones()); // - now find matching zone for given offset and DAYLIGHT property string if (TzDaylightToContext(aText,tctx,tctx,getSessionZones(),fReceiverTimeContext)) { // this is always global for the entire item, so set the item context // (which is then used when parsing dates (which should be delayed to make sure TZ is seen first) fItemTimeContext = tctx; fHasExplicitTZ = true; // zone explicitly set, not only copied from session's user zone goto timecontext; } return true; // not set, is ok case CONVMODE_TZID: // try to get context for named zone // - look up in TZIDs we've parsed so far from VTIMEZONE tz = fParsedTzidSet.find(aText); if (tz!=fParsedTzidSet.end()) { tctx = tz->second; // get tctx resolved from VTIMEZONE // use tctx for all values from this property fPropTZIDtctx = tctx; goto timecontext; } else if (TimeZoneNameToContext(aText, tctx, getSessionZones(), true)) { // found valid TZID property, save it so we can use it for all values of this property that don't specify their own TZ PDEBUGPRINTFX(DBG_ERROR,("Warning: TZID %s could be resolved against internal name, but appropriate VTIMEZONE is missing",aText)); fPropTZIDtctx=tctx; goto timecontext; } else { PDEBUGPRINTFX(DBG_ERROR,("Invalid TZID value '%s' found (no related VTIMEZONES found and not referring to an internal time zone name)",aText)); } return true; // not set, is ok timecontext: // if no field, we still have the zone as fItemTimeContext if (!fldP) return true; // no field, is ok else if (fldP->isBasedOn(fty_timestamp)) { // based on timestamp, assign context to that timestamp tsFldP = static_cast(fldP); tsFldP->setTimeContext(tctx); } else if (fldP->getCalcType()==fty_integer || !TCTX_IS_TZ(tctx)) { // integer field or non-symbolic time zone: // assign minute offset as number (calculated for now) TzResolveToOffset(tctx, moffs, getSession()->getSystemNowAs(TCTX_UTC), true, getSessionZones()); fldP->setAsInteger(moffs); } else { // assign symbolic time zone name TimeZoneContextToName(tctx, s, getSessionZones()); fldP->setAsString(s); } return true; case CONVMODE_MULTIMIX: case CONVMODE_BITMAP: while (*aText && *aText==' ') aText++; // skip leading spaces if (convmode==CONVMODE_MULTIMIX) { // parse value to determine field if (!mixvalparse(aText, offs, isBitMap, n)) return true; // syntax not ok, nop fldP = aItem.getArrayField(aFid+offs,aArrIndex); } else { // just bit number isBitMap=true; if (StrToUShort(aText,n,2)<1) return true; // no integer convertible value, nop } if (!fldP) return true; // no field, assignment "ok" (=nop) if (isBitMap) { // store or add to bitmap // - get current bitmap value if we have a spearator (means that we can have multiple values) if (aConvDefP->combineSep) flags=fldP->getAsInteger(); flags = flags | ((fieldinteger_t)1<setAsInteger(flags); } else { // store as literal fldP->setAsString(aText+n); } return true; // ok case CONVMODE_VERSION: // version string // - return true if correct version string return strucmp(aText,aItem.getItemType()->getTypeVers(fProfileMode))==0; case CONVMODE_PRODID: case CONVMODE_VALUETYPE: case CONVMODE_FULLVALUETYPE: return true; // simply ignore, always ok case CONVMODE_RRULE: // helpers TTimestampField *tfP; TIntegerField *ifP; TStringField *sfP; if (aFid<0) return true; // no field block, assignment "ok" (=nop) // read DTSTART (last=6th field in block) as reference for converting count to end time point dtstart=0; // start date/time, as reference if (!(tfP = ITEMFIELD_DYNAMIC_CAST_PTR(TTimestampField,fty_timestamp,aItem.getArrayField(aFid+5,aArrIndex)))) return false; // TZ and TZID should be applied to dates by now, so dtstart should be in right zone dtstart = tfP->getTimestampAs(TCTX_UNKNOWN,&startcontext); if (TCTX_IS_UTC(startcontext)) { // UTC is probably not the correct zone to resolve weekdays -> convert to item zone dtstart = tfP->getTimestampAs(fItemTimeContext,&startcontext); } // init field block values freq='0'; // frequency freqmod=' '; // frequency modifier interval=0; // unspecified interval firstmask=0; // day mask counted from the first day of the period lastmask=0; // day mask counted from the last day of the period until=0; // last day // do the conversion here dostore=false; if (fMimeDirMode==mimo_old) { // vCalendar 1.0 type RRULE dostore=RRULE1toInternal( aText, // RRULE string to be parsed dtstart, // reference date for parsing RRULE startcontext, freq, freqmod, interval, firstmask, lastmask, until, untilcontext, GETDBGLOGGER ); } else { // iCalendar 2.0 type RRULE dostore=RRULE2toInternal( aText, // RRULE string to be parsed dtstart, // reference date for parsing RRULE startcontext, freq, freqmod, interval, firstmask, lastmask, until, untilcontext, GETDBGLOGGER ); } if (dostore) { // store values into field block // - freq/freqmod if (!(sfP = ITEMFIELD_DYNAMIC_CAST_PTR(TStringField,fty_string,aItem.getArrayField(aFid,aArrIndex)))) return false; aFid++; // do NOT INCREMENT in macro, as it would get incremented twice sfP->assignEmpty(); if (freq!='0') { sfP->appendChar(freq); sfP->appendChar(freqmod); } // - interval if (!(ifP = ITEMFIELD_DYNAMIC_CAST_PTR(TIntegerField,fty_integer,aItem.getArrayField(aFid,aArrIndex)))) return false; aFid++; // do NOT INCREMENT in macro, as it would get incremented twice ifP->setAsInteger(interval); // - firstmask if (!(ifP = ITEMFIELD_DYNAMIC_CAST_PTR(TIntegerField,fty_integer,aItem.getArrayField(aFid,aArrIndex)))) return false; aFid++; // do NOT INCREMENT in macro, as it would get incremented twice ifP->setAsInteger(firstmask); // - lastmask if (!(ifP = ITEMFIELD_DYNAMIC_CAST_PTR(TIntegerField,fty_integer,aItem.getArrayField(aFid,aArrIndex)))) return false; aFid++; // do NOT INCREMENT in macro, as it would get incremented twice ifP->setAsInteger(lastmask); // - until if (!(tfP = ITEMFIELD_DYNAMIC_CAST_PTR(TTimestampField,fty_timestamp,aItem.getArrayField(aFid,aArrIndex)))) return false; aFid++; // do NOT INCREMENT in macro, as it would get incremented twice tfP->setTimestampAndContext(until,untilcontext); // - dtstart is not stored, but only read above for reference // done return true; } else { return false; } break; // just in case default: // unknown mode, cannot convert return false; } return false; } // TMimeDirProfileHandler::MIMEStringToField // helper for parseMimeDir() // - parse parameter or property value(list), returns false if no value(list) bool TMimeDirProfileHandler::parseValue( const string &aText, // string to parse as value (could be binary content) const TConversionDef *aConvDefP, sInt16 aBaseOffset, // base offset sInt16 aRepOffset, // repeat offset, adds to aBaseOffset for non-array fields, is array index for array fileds TMultiFieldItem &aItem, // the item where data goes to bool &aNotEmpty, // is set true (but never set false) if property contained any (non-positional) values char aSeparator, // separator between values TMimeDirMode aMimeMode, // MIME mode (older or newer vXXX format compatibility) bool aParamValue, // set if parsing parameter value (different escaping rules) bool aStructured, // set if value consists of multiple values (has semicolon content escaping) bool aOnlyDeEscLF // set if de-escaping only for \n -> LF, but all visible char escapes should be left intact ) { string val,val2; char c; const char *p; // determine field ID sInt16 fid=aConvDefP->fieldid; if (fid>=0) { // value has field where it can be stored // - fid is ALWAYS offset by baseoffset fid += aBaseOffset; // - adjust fid and repoffset (add them and reset aRepOffset if no array field) aItem.adjustFidAndIndex(fid,aRepOffset); // find out if value exists (available in source and target) if (isFieldAvailable(aItem,fid)) { // parse only if field available in both source and target if ( (aConvDefP->convmode & CONVMODE_MASK)==CONVMODE_BLOB_B64 || (aConvDefP->convmode & CONVMODE_MASK)==CONVMODE_BLOB_AUTO ) { // move 1:1 into field // - get pointer to leaf field TItemField *fldP = aItem.getArrayField(fid,aRepOffset); // - directly set field with entire (possiby binary) string content if (fldP) fldP->setAsString(aText); // parsed successfully return true; } // normal text value, apply de-escaping, charset transformation, value list and enum conversion p = aText.c_str(); // start here while (*p) { // value list loop // - get next value val.erase(); while ((c=*p)!=0) { // check for field list separator (if field allows list at all) if (c==aSeparator && aConvDefP->combineSep) { p++; // skip separator break; } // check for escaped chars if (c=='\\') { p++; c=*p; if (!c) break; // half escape sequence, ignore else if (c=='n' || c=='N') c='\n'; else if (aOnlyDeEscLF) val+='\\'; // if deescaping only for \n, transfer this non-LF escape into output // other escaped chars are shown as themselves } // add char val+=c; // next p++; } // find first non-space and number of chars excluding leading and trailing spaces const char* valnospc = val.c_str(); size_t numnospc=val.size(); while (*valnospc && *valnospc==' ') { valnospc++; numnospc--; } while (*(valnospc+numnospc-1)==' ') { numnospc--; } // - counts as non-empty if there is a non-empty (and not space-only) value string (even if // it might be converted to empty-value in enum conversion) if (*valnospc) aNotEmpty=true; // - apply enum translation if any const TEnumerationDef *enumP = aConvDefP->findEnumByName(valnospc,numnospc); if (enumP) { // we have an explicit value (can be default if there is a enm_defaultvalue enum) if (enumP->enummode==enm_ignore) continue; // do not assign anything, get next value else { if (enumP->enummode==enm_prefix) { // append original value minus prefix to translation size_t n=TCFG_SIZE(enumP->enumtext); val2.assign(valnospc+n,numnospc-n); // copying from original val val=enumP->enumval; // assign the prefix val+=val2; // and append the original value sans prefix } else { val=enumP->enumval; // just use translated value } } } // assign (or add) value to field if (!MIMEStringToField( val.c_str(), // the value text to assign or add to the field aConvDefP, // the conversion definition aItem, fid, // field ID, can be -1 aRepOffset // 0 or array index )) { // field conversion error PDEBUGPRINTFX(DBG_ERROR,( "TMimeDirProfileHandler::parseValue: MIMEStringToField assignment (fid=%hd, arrindex=%hd) failed", fid, aRepOffset )); return false; } } // while(more chars in value text) } // if source and target fields available else { // show this in log, as most probably it's a remote devInf bug PDEBUGPRINTFX(DBG_PARSE,("No value stored for field index %hd because remote indicates not supported in devInf",fid)); } } // if fieldid exists else { // could be special conversion using no data or data from // internal object variables (such as VERSION value) if (!MIMEStringToField( aText.c_str(), // the value text to process aConvDefP, // the conversion definition aItem, FID_NOT_SUPPORTED, 0 )) { // field conversion error PDEBUGPRINTFX(DBG_ERROR,( "TMimeDirProfileHandler::parseValue: MIMEStringToField in check mode (no field) failed with val=%s", aText.c_str() )); return false; } } // parsed successfully return true; } // TMimeDirProfileHandler::parseValue // parse given property bool TMimeDirProfileHandler::parseProperty( cAppCharP &aText, // where to start interpreting property, will be updated past end of what was scanned TMultiFieldItem &aItem, // item to store data into const TPropertyDefinition *aPropP, // the property definition sInt16 *aRepArray, // array[repeatID], holding current repetition COUNT for a certain nameExts entry sInt16 aRepArraySize, // size of array (for security) TMimeDirMode aMimeMode, // MIME mode (older or newer vXXX format compatibility) cAppCharP aGroupName, // property group ("a" in "a.TEL:131723612") size_t aGroupNameLen, cAppCharP aFullPropName, // entire property name (excluding group) - might be needed in case of wildcard property match size_t aFullNameLen ) { TNameExtIDMap nameextmap; const TParameterDefinition *paramP; const char *p,*ep,*vp; char c; string pname; string val; string unprocessedVal; bool defaultparam; bool fieldoffsetfound; bool notempty = false; bool valuelist; sInt16 pidx; // parameter index TEncodingTypes encoding; TCharSets charset; // field storage info vars, defaults are used if property has no TPropNameExtension sInt16 baseoffset = 0; sInt16 repoffset = 0; sInt16 maxrep = 1; // no repeat by default sInt16 repinc = 1; // inc by 1 sInt16 repid = -1; // invalid by default bool overwriteempty = false; // do not overwrite empty values by default bool repoffsByGroup = false; // init encoding = enc_none; // no encoding by default charset = aMimeMode==mimo_standard ? chs_utf8 : fDefaultInCharset; // always UTF8 for real MIME-DIR (same as enclosing SyncML doc), for mimo_old depends on remote rule option (normally UTF-8) nameextmap = 0; // no name extensions detected so far fieldoffsetfound = (aPropP->nameExts==NULL); // no first pass needed at all w/o nameExts, just use offs=0 valuelist = aPropP->valuelist; // cache flag // prepare storage as unprocessed value if (aPropP->unprocessed) { if (aGroupName && *aGroupName) { unprocessedVal.assign(aGroupName, aGroupNameLen); unprocessedVal += '.'; } unprocessedVal.append(aFullPropName, aFullNameLen); } // scan parameter list (even if unprocessed, to catch ENCODING and CHARSET) do { p=aText; while (*p==';') { // param follows defaultparam=false; pname.erase(); p=nextunfolded(p,aMimeMode); // parameter expected here // - find end of parameter name vp=NULL; // no param name found for (ep=p; *ep; ep=nextunfolded(ep,aMimeMode)) { if (*ep=='=') { // param value follows at vp vp=nextunfolded(ep,aMimeMode); break; } else if (*ep==':' || *ep==';') { // end of parameter name w/o equal sign if (aMimeMode!=mimo_old) { // only mimo_old allows default params, but as e.g. Nokia Intellisync (Synchrologic) does this completely wrong, we now tolerate it POBJDEBUGPRINTFX(getSession(),DBG_ERROR,( "Parameter without value: %s - is wrong in MIME-DIR, but we tolerate it and parse as default param name", pname.c_str() )); } // treat this as a value of the default parameter (correct syntax in old vCard 2.1/vCal 1.0, wrong in MIME-DIR) defaultparam=true; // default param // value is equal to param name and starts at p vp=p; break; } // add char to param name (unfolded!) pname+=*ep; } if (!vp) { POBJDEBUGPRINTFX(getSession(),DBG_ERROR,("parseProperty: bad parameter %s (missing value)",pname.c_str())); return false; } // parameter name & value isolated, pname=name (if not defaultparam), vp points to value // - obtain unfolded value val.erase(); bool dquoted = false; bool wasdquoted = false; // - note: we allow quoted params even with mimo_old, as the chance is much higher that a param value // beginning with doublequote is actually a quoted string than a value containing a doublequote at the beginning if (*vp=='"') { dquoted = true; wasdquoted = true; vp=nextunfolded(vp,aMimeMode); } do { c=*vp; if (isEndOfLineOrText(c)) break; if (dquoted) { // within double quoted value, only closing dquote can end it if (c=='"') { // swallow closing double quote and proceed (next should be end of value anyway) vp = nextunfolded(vp,aMimeMode); dquoted = false; continue; } } else { // not within double quoted value if (c==':' || c==';') break; // end of value // check escaped characters if (c=='\\') { // escape char, do not check next char for end-of-value (but DO NOT expand \-escaped chars here!!) vp=nextunfolded(vp,aMimeMode); c=*vp; // get next if (c) { val+='\\'; // keep the escaped sequence for later when value is actually processed! } else { // half-finished escape at end of value, ignore break; } } } val+=c; // cancel QP softbreaks if encoding is already switched to QP at this point vp=nextunfolded(vp,aMimeMode,encoding==enc_quoted_printable); } while(true); // - processing of next param starts here p=vp; // check for global parameters bool storeUnprocessed = true; // in case this is a unprocessed property, flag will be cleared to prevent storing params that still ARE processed if ((aMimeMode==mimo_old && defaultparam) || strucmp(pname.c_str(),"ENCODING")==0) { // get encoding // Note: always process ENCODING, as QP is mimo-old specific and must be removed for normalized storage for (sInt16 k=0; k (k); } } if (aPropP->unprocessed) { if (encoding==enc_quoted_printable) storeUnprocessed = false; // QP will be decoded (for unprocessed properties), so param must not be stored else encoding = enc_none; // other encodings will not be processed for unprocessed properties } } else if (strucmp(pname.c_str(),"CHARSET")==0) { // charset specified (mimo_old value-only not supported) // Note: always process CHARSET, because non-UTF8 cannot be safely passed to DBs, so we need // to convert in case it's not UTF-8 even for "unprocessed" properties sInt16 k; for (k=1; k=numCharSets) { // unknown charset POBJDEBUGPRINTFX(getSession(),DBG_ERROR,("========== WARNING: Unknown Charset '%s'",val.c_str())); // %%% replace 8bit chars with underscore charset=chs_unknown; } storeUnprocessed = false; // CHARSET is never included in unprocessed property, as we always store UTF-8 } if (aPropP->unprocessed && storeUnprocessed && fieldoffsetfound) { // append in reconstructed form for storing "unprocessed" (= lightly normalized) unprocessedVal += ';'; unprocessedVal += pname; if (!defaultparam) { unprocessedVal += '='; if (wasdquoted) unprocessedVal += '"'; unprocessedVal += val; if (wasdquoted) unprocessedVal += '"'; } } // find param in list now paramP = aPropP->parameterDefs; pidx=0; // parameter index while (paramP) { // check for match if ( mimeModeMatch(paramP->modeDependency) && #ifndef NO_REMOTE_RULES (!paramP->ruleDependency || isActiveRule(paramP->ruleDependency)) && #endif ((defaultparam && paramP->defaultparam) || strucmp(pname.c_str(),TCFG_CSTR(paramP->paramname))==0) ) { // param name found // - process value (list) if (!fieldoffsetfound) { // first pass, check for extendsname parameters if (paramP->extendsname) { // - for each value in the value list, check if it has a nameextid if (!paramP->convdef.enumdefs) { DEBUGPRINTFX(DBG_PARSE,( "parseProperty: extendsname param w/o enum : %s;%s", TCFG_CSTR(aPropP->propname), TCFG_CSTR(paramP->paramname) )); return false; } // - loop through value list ep=val.c_str(); while (*ep) { sInt32 n; const char *pp; // find end of next value in list for (n=0,pp=ep; *pp; pp++) { if (*pp==',') { pp++; // skip the comma break; } n++; } // search in enums list const TEnumerationDef *enumP = paramP->convdef.findEnumByName(ep,n); if (enumP && enumP->nameextid>=0) { // set name extension map bit nameextmap |= ((TNameExtIDMap)1<nameextid); } // next value in list ep=pp; } } // if extendsname } // first pass else { // second pass: read param value(s) if (!parseValue( val, // input string, possibly binary (e.g. in case of B64 encoded PHOTO) &(paramP->convdef), baseoffset, // base offset (as determined by position) repoffset, // repetition offset or array index aItem, // the item where data goes to notempty, // set true if value(s) parsed are not all empty defaultparam ? ';' : ',', // value list separator aMimeMode, // MIME mode (older or newer vXXX format compatibility) true, // parsing a parameter false, // no structured value false // normal, full de-escaping )) { DEBUGPRINTFX(DBG_PARSE,( "TMimeDirProfileHandler::parseProperty: %s: value not parsed: %s", pname.c_str(), val.c_str() )); return false; } } // second pass } // if (param known) // test next param paramP=paramP->next; pidx++; } // while more params // p points to ';' of next param or ':' of value } // while more parameters (*p==';') // check if both passes done or if property storage is explicitly blocked already (baseoffset=-1) if (fieldoffsetfound) break; // start second pass fieldoffsetfound=true; // - assume empty to start with notempty=false; // - prepare for second pass: check if set of param values match // an entry in the nameexts list TPropNameExtension *propnameextP = aPropP->nameExts; if (propnameextP) { repoffsByGroup = false; bool dostore = false; while (propnameextP) { // check if entry matches parsed extendsname param values if ( ((propnameextP->musthave_ids & nameextmap) == propnameextP->musthave_ids) && // needed there ((propnameextP->forbidden_ids & nameextmap) == 0) // none of the forbidden ones there ) { // found match, get offset baseoffset=propnameextP->fieldidoffs; if (baseoffset==OFFS_NOSTORE) break; // abort with dostore=false // check if repeat needed/allowed maxrep=propnameextP->maxRepeat; if (maxrep==REP_REWRITE) { dostore=true; // we can store break; // unlimited repeat allowed but stored in same fields (overwrite), no need for index search by group } // find index where to store this repetition repid=propnameextP->repeatID; if (repid>=aRepArraySize) SYSYNC_THROW(TSyncException(DEBUGTEXT("TMimeDirProfileHandler::parseProperty: repID too high","mdit11"))); // check if a group ID determines the repoffset (not possible for valuelists) if (aPropP->groupFieldID!=FID_NOT_SUPPORTED && !valuelist) { // search in group field string s; bool someGroups = false; for (sInt16 n=0; nrepeatInc; // original repeatoffset (not adjusted yet) TItemField *g_fldP = aItem.getArrayFieldAdjusted(aPropP->groupFieldID+baseoffset,g_repoffset,true); // get leaf field, if it exists if (!g_fldP) break; // group field for that repetition does not (yet) exist, array exhausted // compare group name if (g_fldP->isAssigned()) { someGroups = someGroups || !g_fldP->isEmpty(); // when we find a non-empty group field, we have at least one group detected if (someGroups) { // don't use repetitions already used by SOME of the fields in the group // for auto-assigning new groups (or ungrouped occurrences) if (aRepArray[repid]getAsString(s); if (aGroupName && strucmp(aGroupName,s.c_str(),aGroupNameLen)==0) { repoffsByGroup = true; dostore = true; repoffset = g_repoffset; PDEBUGPRINTFX(DBG_PARSE+DBG_EXOTIC,("parseProperty: found group '%s' at repoffset=%d (repcount=%d)",s.c_str(),repoffset,n)); break; } } } // for all possible repetitions // minrep now contains minimal repetition count for !repoffsByGroup case } // if grouped property if (!repoffsByGroup) { if (aRepArray[repid]repeatInc; // note: repArray will be updated below (if property not empty or !overwriteempty) dostore=true; // we can store do { repoffset = aRepArray[repid]*repinc; // - set flag if repeat offset should be incremented after storing an empty property or not overwriteempty = propnameextP->overwriteEmpty; // - check if target property main value is empty (must be, or we will skip that repetition) dostore = false; // if no field exists, we do not store for (sInt16 e=0; enumValues; e++) { if (aPropP->convdefs[e].fieldid==FID_NOT_SUPPORTED) continue; // no field, no need to check it sInt16 e_fid = aPropP->convdefs[e].fieldid+baseoffset; sInt16 e_rep = repoffset; aItem.adjustFidAndIndex(e_fid,e_rep); // - get base field TItemField *e_basefldP = aItem.getField(e_fid); TItemField *e_fldP = NULL; if (e_basefldP) e_fldP=e_basefldP->getArrayField(e_rep,true); // get leaf field, if it exists if (!e_basefldP || (e_fldP && e_fldP->isAssigned())) { // base field of one of the main fields does not exist or leaf field is already assigned // -> skip that repetition dostore = false; break; } else dostore = true; // at least one field exists, we might store } // check if we can test more repetitions if (!dostore) { if (aRepArray[repid]+1next; } // while search for matching nameExts entry // abort if we can't store if (!dostore) { aText=p; // this is what we've read so far return false; } } // if name extension list not empty // Now baseoffset/repoffset are valid to be used for storage } while(true); // until parameter pass 1 & pass 2 done // parameters are all processed by now, decision made to store data (if !dostore, routine exits above) // - store the group tag value if we have one if (aPropP->groupFieldID!=FID_NOT_SUPPORTED) { TItemField *g_fldP = aItem.getArrayFieldAdjusted(aPropP->groupFieldID+baseoffset,repoffset,false); if (g_fldP) g_fldP->setAsString(aGroupName,aGroupNameLen); // store the group name (aGroupName might be NULL, that's ok) } if (aPropP->unprocessed) { if (*p==':') { // there is a value p++; // - get entire property value part, not checking for any separators, but converting to appchar (UTF-8) and unfolding decodeValue(encoding==enc_quoted_printable ? encoding : enc_none, charset, aMimeMode, 0, 0, p, val); // - add it to "unprocessed" value representation unprocessedVal += ':'; unprocessedVal += val; // - process this as a whole (de-escaping ONLY CRLFs) and assign to field if (!parseValue( unprocessedVal, &(aPropP->convdefs[0]), // the conversion definition baseoffset, // identifies base field repoffset, // repeat offset to base field / array index aItem, // the item where data goes to notempty, // set true if value(s) parsed are not all empty 0, // no value list separator aMimeMode, // MIME mode (older or newer vXXX format compatibility) false, // no parameter false, // not structured true // only de-escape linefeeds, but nothing else )) { return false; } } // if property has a value part } // if unprocessed property else { // - read and decode value(s) char sep=':'; // first value starts with colon // repeat until we have all values for (sInt16 i=0; inumValues || valuelist; i++) { if (*p!=sep && (aPropP->altvaluesep==0 || *p!=aPropP->altvaluesep)) { #ifdef SYDEBUG // Note: for valuelists, this is the normal loop exit case as we are not limited by numValues if (!valuelist) { // New behaviour: omitting values is ok (needed e.g. for T39m) DEBUGPRINTFX(DBG_PARSE,("TMimeDirProfileHandler::parseProperty: %s does not specify all values",TCFG_CSTR(aPropP->propname))); } #endif break; // all available values read } // skip separator p++; // get value(list) unfolded decodeValue(encoding,charset,aMimeMode,aPropP->numValues > 1 || valuelist ? aPropP->valuesep : 0,aPropP->altvaluesep,p,val); // check if we can store, otherwise just read over value // - get the conversion def for the value TConversionDef *convDef = &(aPropP->convdefs[valuelist ? 0 : i]); // always use convdef[0] for value lists // - store value if not a value list (but simple value or part of structured value), or store if // valuelist and repeat not yet exhausted, or if valuelist without repetition but combination separator // which allows to put multiple values into a single field if (!valuelist || repoffsetcombineSep)) { // convert and store value (or comma separated value-list, not to mix with valuelist-property!!) if (!parseValue( val, convDef, baseoffset, // identifies base field repoffset, // repeat offset to base field / array index aItem, // the item where data goes to notempty, // set true if value(s) parsed are not all empty ',', aMimeMode, // MIME mode (older or newer vXXX format compatibility) false, // no parameter aPropP->numValues > 1, // structured if multiple values false // normal, full de-escaping )) { PDEBUGPRINTFX(DBG_PARSE+DBG_EXOTIC,( "TMimeDirProfileHandler::parseProperty: %s: value not parsed: %s", TCFG_CSTR(aPropP->propname), val.c_str() )); return false; } // update repeat offset and repeat count if this is a value list if (valuelist && convDef->combineSep==0 && (notempty || !overwriteempty)) { // - update count for every non-empty value (for empty values only if overwriteempty is not set) if (repid>=0) aRepArray[repid]++; // next repetition repoffset+=repinc; // also update repeat offset } } else { // value cannot be stored PDEBUGPRINTFX(DBG_PARSE+DBG_EXOTIC,( "TMimeDirProfileHandler::parseProperty: %s: value not stored because repeat exhausted: %s", TCFG_CSTR(aPropP->propname), val.c_str() )); } // more values must be separated by the value sep char (default=';' but can be ',' e.g. for iCalendar 2.0 CATEGORIES) sep = aPropP->valuesep; } // for all values } // process values if (notempty && !valuelist) { // at least one of the components is not empty. Make sure all components are "touched" such that // in case of arrays, these are assigned even if empty for (sInt16 j=0; jnumValues; j++) { sInt16 fid=aPropP->convdefs[j].fieldid; if (fid>=0) { // requesting the pointer creates the field if it does not already exist aItem.getArrayFieldAdjusted(fid+baseoffset,repoffset,false); } } } if (!valuelist && repid>=0 && (notempty || !overwriteempty) && !repoffsByGroup) { // we have used this repetition and actually stored values, so count it now // (unless we have stored an empty value only and overwriteempty is true, in // this case we don't increment, so next value found for this repetition will // overwrite empty value // Also, if repeat offset was found by group name, don't increment (aRepArray // is already updated in this case) aRepArray[repid]++; } // update read pointer past end of what we've scanned (but not necessarily up // to next property beginning) aText=p; // done, ok return true; } // TMimeDirProfileHandler::parseProperty // parse MIME-DIR from specified string into item bool TMimeDirProfileHandler::parseMimeDir(const char *aText, TMultiFieldItem &aItem) { // start with empty item aItem.cleardata(); // reset item time zone before parsing fHasExplicitTZ = false; // none set explicitly fItemTimeContext = fReceiverTimeContext; // default to user context fDelayedProps.clear(); // start w/o delayed props fParsedTzidSet.clear(); // start w/o time zones // start parsing on root level if (parseLevels(aText,aItem,fProfileDefinitionP,true)) { // make sure all supported (=available) fields are at least empty (but not missing!) aItem.assignAvailables(); return true; } else return false; } // TMimeDirProfileHandler::parseMimeDir // parameter string for QP encoding. Needed when skipping otherwise unknown properties #define QP_ENCODING_PARAM "ENCODING=QUOTED-PRINTABLE" // parse MIME-DIR level from specified string into item bool TMimeDirProfileHandler::parseLevels( const char *&aText, TMultiFieldItem &aItem, const TProfileDefinition *aProfileP, bool aRootLevel ) { appChar c; cAppCharP p, propname, groupname; sInt32 n, gn; sInt16 foundmandatory=0; const sInt16 maxreps = 50; sInt16 repArray[maxreps]; bool atStart = aRootLevel; // reset repetition counts for (sInt16 k=0; klevelConvdef.fieldid; if (fid>=0) { // field defined for level entry // - make sure field exists and is assigned empty value at least aItem.getFieldRef(fid).assignEmpty(); const TEnumerationDef *enumP = aProfileP->levelConvdef.enumdefs; if (enumP) { // if enumdefs, content is set to first enumdef's enumval (NOT enumtext!!) aItem.getField(fid)->setAsString(TCFG_CSTR(enumP->enumval)); } } // skip possible leading extra LF and CR and whitespace here // NOTE: Magically server sends XML CDATA with 0x0D 0x0D 0x0A for example while (isspace(*aText)) aText++; // parse input text property by property do { // start of property parsing // - reset TZID flag fPropTZIDtctx = TCTX_UNKNOWN; // - prepare scanning p=aText; propname = p; // assume name starts at beginning of text n = 0; groupname = NULL; // assume no group gn = 0; // determine property name end (and maybe group name) do { c=*p; if (!c) { // end of text reached w/o property name POBJDEBUGPRINTFX(getSession(),DBG_ERROR,("parseMimeDir: no property name found, text=%s",aText)); return false; } if (c==':' || c==';') break; // handle grouping if (c=='.') { // this is a group name (or element of it) // - remember the group name if (!groupname) groupname = propname; gn = p-groupname; // size of groupname // - prop name starts after group name (and dot) propname = ++p; // skip group n = 0; continue; } // next char p++; n++; } while(true); // propname points to start, p points to end of property name, n=name size // - search through all properties bool propparsed=false; // - check for BEGIN and END if (strucmp(propname,"BEGIN",n)==0) { // BEGIN encountered p = propname+n; // - skip possible parameters for broken implementations like Intellisync/Synchrologic if (*p==';') while (*p && *p!=':') p++; // - isolate value size_t l=0; const char *lnam=p+1; while (*(lnam+l)>=0x20) l++; // calculate length of value p=lnam+l; // advance scanning pointer to terminator n=0; // prevent false advancing at end of prop loop if (atStart) { // value must be level name, else this is a bad profile if (strucmp(lnam,TCFG_CSTR(aProfileP->levelName),l)!=0) { POBJDEBUGPRINTFX(getSession(),DBG_ERROR,("parseMimeDir: root level BEGIN has bad value: %s",aText)); return false; } atStart=false; // no special lead-in check any more propparsed=true; } else { // value determines new level to enter if (disabledLevels==0) { // search for sublevel const TProfileDefinition *subprofileP = aProfileP->subLevels; while (subprofileP) { // check if ( mimeModeMatch(subprofileP->modeDependency) && strucmp(lnam,TCFG_CSTR(subprofileP->levelName),l)==0 ) { // sublevel found, process while ((uInt8)(*p)<0x20) p++; // advance scanning pointer to beginning of next property // check special case first if (subprofileP->profileMode==profm_vtimezones) { // vTimeZone is handled specially string s2; string s = "END:"; s.append(subprofileP->levelName); n = s.size(); // size of lead-out cAppCharP e = strstr(p,s.c_str()); if (e==NULL) return false; // unterminated vTimeZone sublevel s.assign(p,e-p); // everything between lead-in and lead-out p = e+n; // advance pointer beyond VTIMEZONES appendStringAsUTF8(s.c_str(), s2, chs_utf8, lem_cstr, false); timecontext_t tctx; // identify or add this in the session zones string tzid; if (VTIMEZONEtoInternal(s2.c_str(), tctx, getSessionZones(), getDbgLogger(), &tzid)) { // time zone identified #ifdef SYDEBUG string tzname; TimeZoneContextToName(tctx, tzname, getSessionZones()); PDEBUGPRINTFX(DBG_PARSE+DBG_EXOTIC,("parseMimeDir: VTIMEZONE with ID='%s' parsed to internal time zone '%s'",tzid.c_str(),tzname.c_str())); #endif // remember it by original name for TZID parsing fParsedTzidSet[tzid] = tctx; } else { POBJDEBUGPRINTFX(getSession(),DBG_ERROR,("parseMimeDir: could not parse VTIMEZONE: %s",s.c_str())); } } else { // ordinary non-root level if (!parseLevels(p,aItem,subprofileP,false)) return false; } // - now continue on this level propparsed=true; break; } // next subprofileP=subprofileP->next; } if (!propparsed) { // no matching sublevel found, disable this level disabledLevels=1; } } else { // already disabled, just nest disabledLevels++; } } // BEGIN not on rootlevel } // BEGIN found else if (strucmp(propname,"END",n)==0) { // END encountered p = propname+n; // - skip possible parameters for broken implementations like Intellisync/Synchrologic if (*p==';') while (*p && *p!=':') p++; // - isolate value size_t l=0; const char *lnam=p+1; while (*(lnam+l)>=0x20) l++; // calculate length of value p=lnam+l; // advance scanning pointer to terminator n=0; // prevent false advancing at end of prop loop // check if (disabledLevels>0) { // end of a disabled level, just un-nest disabledLevels--; } else { // should be end of active level, check name if (strucmp(lnam,TCFG_CSTR(aProfileP->levelName),l)!=0) { POBJDEBUGPRINTFX(getSession(),DBG_ERROR,("parseMimeDir: unexpected END value: %s",aText)); return false; } // correct end of level aText=p; // points to terminator, which is correct for end-of-level // break scanner loop break; } } // END found else if (disabledLevels==0) { if (atStart) { POBJDEBUGPRINTFX(getSession(),DBG_ERROR,("parseMimeDir: root level does not start with BEGIN: %s",aText)); return false; } // not disabled level const TPropertyDefinition *propP = aProfileP->propertyDefs; #ifndef NO_REMOTE_RULES const TPropertyDefinition *otherRulePropP = NULL; // default property which is used if none of the rule-dependent in the group was used bool ruleSpecificParsed = false; uInt16 propGroup=0; // group identifier (all props with same name have same group ID) #endif const TPropertyDefinition *parsePropP; while(propP) { // compare if ( mimeModeMatch(propP->modeDependency) && // none or matching mode dependency strwildcmp(propname,TCFG_CSTR(propP->propname),n)==0 // wildcards allowed (for unprocessed properties for example) ) { // found property def with matching name (and MIME mode) // check all in group (=all subsequent with same name) #ifndef NO_REMOTE_RULES propGroup=propP->propGroup; ruleSpecificParsed=false; otherRulePropP=NULL; while (propP && propP->propGroup==propGroup && propP->propGroup!=0) #else do #endif { // still in same group (= same name) #ifndef NO_REMOTE_RULES // check if this property should be used for parsing parsePropP=NULL; // do not parse by default if (propP->dependsOnRemoterule) { // check if depends on current rule if (propP->ruleDependency==NULL) { // this is the "other"-rule dependent variant // - just remember for now otherRulePropP=propP; } else if (isActiveRule(propP->ruleDependency)) { // specific for the applied rule parsePropP=propP; // default to expand current prop // now we have expanded a rule-specific property (blocks parsing of "other"-rule dependent prop) ruleSpecificParsed=true; } } else { // does not depend on rule, parse anyway parsePropP=propP; } // check if this is last prop of list propP=propP->next; if (!(propP && propP->propGroup==propGroup) && otherRulePropP && !ruleSpecificParsed) { // End of alternatives for parsing this property, no rule-specific parsed yet, and there is a otherRuleProp // parse "other"-rule's property instead parsePropP=otherRulePropP; } #else // simply parse it parsePropP=propP; propP=propP->next; #endif // now parse (or save for delayed parsing later) if (parsePropP) { if (parsePropP->delayedProcessing) { // buffer parameters needed to parse later PDEBUGPRINTFX(DBG_PARSE+DBG_EXOTIC,("parseMimeDir: property %s parsing delayed, rank=%hd",TCFG_CSTR(parsePropP->propname),parsePropP->delayedProcessing)); TDelayedPropParseParams dppp; dppp.delaylevel = parsePropP->delayedProcessing; dppp.start = p; dppp.groupname = groupname; dppp.groupnameLen = gn; dppp.propDefP = parsePropP; TDelayedParsingPropsList::iterator pos; for (pos=fDelayedProps.begin(); pos!=fDelayedProps.end(); pos++) { // insert at end or before first occurrence of higer delay if ((*pos).delaylevel>dppp.delaylevel) { fDelayedProps.insert(pos,dppp); break; } } if (pos==fDelayedProps.end()) fDelayedProps.push_back(dppp); // update mandatory count (even if we haven't parsed it yet) if (parsePropP->mandatory) foundmandatory++; // skip for now p=propname+n; propparsed=true; // but is "parsed" for loop break; // parse next } if (parseProperty( p, // where to start interpreting property, will be updated past end of poperty aItem, // item to store data into parsePropP, // the (matching) property definition repArray, maxreps, fMimeDirMode, // MIME-DIR mode groupname, gn, propname, n )) { // property parsed successfully propparsed=true; // count mandarory properties found if (parsePropP->mandatory) foundmandatory++; break; // parse next } // if not successfully parsed, continue with next property which // can have the same name, but possibly different parameter definitions } // if parseProp } // while same property group (poperties with same name) #ifdef NO_REMOTE_RULES while(false); // if no remote rules, we do not loop #endif if (propparsed) break; // do not continue outer loop if inner loop has parsed a prop successfully } // if name matches (=start of group found) else { // not start of group // - next property propP=propP->next; } } // while all properties } // else: neither BEGIN nor END if (!propparsed) { // unknown property PDEBUGPRINTFX(DBG_PARSE,("parseMimeDir: property not parsed (unknown or not storable): %" FMT_LENGTH(".30") "s",FMT_LENGTH_LIMITED(30,aText))); // skip parsed part (the name) p=propname+n; } // p is now end of parsed part // - skip rest up to EOLN (=any ctrl char) // Note: we need to check if this is quoted-printable, otherwise we might NOT cancel soft breaks bool isqp = false; while ((c=*p)!=0) { if (isEndOfLineOrText(c)) break; // end of line or string if (c==';' && *(p+1)) { if (strucmp(p+1, QP_ENCODING_PARAM, strlen(QP_ENCODING_PARAM))==0) { c = *(p+1+strlen(QP_ENCODING_PARAM)); isqp = c==':' || c==';'; // the property is QP encoded, we need to cancel QP softbreaks while looking for end of property } } p=nextunfolded(p,fMimeDirMode,isqp); // cancel soft breaks if we are in QP encoded property } // - skip entire EOLN (=all control chars in sequence %%%) while (*p && (uInt8)(*p)<'\x20') p=nextunfolded(p,fMimeDirMode); // set next property start point aText=p; } while (*aText); // exit if end of string // now parse delayed ones (list is in delay order already) if (aRootLevel) { // process delayed properties only after entire record is parsed (i.e. when we are at root level here) TDelayedParsingPropsList::iterator pos; for (pos=fDelayedProps.begin(); pos!=fDelayedProps.end(); pos++) { p = (*pos).start; // where to start parsing PDEBUGPRINTFX(DBG_PARSE+DBG_EXOTIC,( "parseMimeDir: now parsing delayed property rank=%hd: %" FMT_LENGTH(".30") "s", (*pos).delaylevel, FMT_LENGTH_LIMITED(30,(*pos).start) )); if (parseProperty( p, // where to start interpreting property, will be updated past end of property aItem, // item to store data into (*pos).propDefP, // the (matching) property definition repArray, maxreps, fMimeDirMode, // MIME-DIR mode (*pos).groupname, (*pos).groupnameLen, "X-delayed", 9 // dummy, unprocessed properties must not be parsed in delayed mode! )) { // count mandarory properties found //%%% moved this to when we queue the delayed props, as mandatory count is per-profile //if ((*pos).propDefP->mandatory) foundmandatory++; } else { // delayed parsing failed PDEBUGPRINTFX(DBG_PARSE,("parseMimeDir: failed delayed parsing of property %" FMT_LENGTH(".30") "s",FMT_LENGTH_LIMITED(30,(*pos).start))); } } // we don't need them any more - clear delayed props fDelayedProps.clear(); } // verify integrity if (foundmandatorynumMandatoryProperties) { // not all mandatory properties found POBJDEBUGPRINTFX(getSession(),DBG_ERROR,( "parseMimeDir: missing %d of %hd mandatory properies", aProfileP->numMandatoryProperties-foundmandatory, aProfileP->numMandatoryProperties )); // unsuccessful parsing return false; } // successful parsing done return true; // %%%%% NOTE: exactly those fields in aItem should be assigned // which are available in source and target. // possibly this should be done in prepareForSendTo (o.‰) of // MultiFieldItem... } // TMimeDirProfileHandler::parseLevels void TMimeDirProfileHandler::getOptionsFromDatastore(void) { // get options datastore if one is related; // ignore the session from getSession() here because we need // to distinguish between script context and normal sync context // (the former has no datastore, the latter has) TSyncSession *sessionP = fRelatedDatastoreP ? fRelatedDatastoreP->getSession() : NULL; if (sessionP) { fReceiverCanHandleUTC = sessionP->fRemoteCanHandleUTC; fVCal10EnddatesSameDay = sessionP->fVCal10EnddatesSameDay; fReceiverTimeContext = sessionP->fUserTimeContext; // default to user context fDontSendEmptyProperties = sessionP->fDontSendEmptyProperties; fDefaultOutCharset = sessionP->fDefaultOutCharset; fDefaultInCharset = sessionP->fDefaultInCharset; fDoQuote8BitContent = sessionP->fDoQuote8BitContent; fDoNotFoldContent = sessionP->fDoNotFoldContent; fTreatRemoteTimeAsLocal = sessionP->fTreatRemoteTimeAsLocal; fTreatRemoteTimeAsUTC = sessionP->fTreatRemoteTimeAsUTC; #ifndef NO_REMOTE_RULES fActiveRemoteRules = sessionP->fActiveRemoteRules; // copy the list #endif } } // generate Data item (includes header and footer) void TMimeDirProfileHandler::generateText(TMultiFieldItem &aItem, string &aString) { // get options datastore if one is related getOptionsFromDatastore(); #ifdef SYDEBUG PDEBUGPRINTFX(DBG_GEN+DBG_HOT,("Generating....")); aItem.debugShowItem(DBG_DATA+DBG_GEN); #endif // baseclass just generates MIME-DIR fBeginEndNesting=0; // no BEGIN out yet generateMimeDir(aItem,aString); #ifdef SYDEBUG if (PDEBUGTEST(DBG_GEN+DBG_USERDATA)) { // note, do not use debugprintf because string is too long PDEBUGPRINTFX(DBG_GEN,("Generated: ")); PDEBUGPUTSXX(DBG_GEN+DBG_USERDATA,aString.c_str(),0,true); } #endif } // TMimeDirProfileHandler::generateText // parse Data item (includes header and footer) bool TMimeDirProfileHandler::parseText(const char *aText, stringSize aTextSize, TMultiFieldItem &aItem) { //#warning "aTextSize must be checked!" // get options datastore if one is related getOptionsFromDatastore(); // baseclass just parses MIME-DIR fBeginEndNesting = 0; // no BEGIN found yet #ifdef SYDEBUG if (PDEBUGTEST(DBG_PARSE)) { // very detailed, show item being parsed PDEBUGPRINTFX(DBG_PARSE+DBG_HOT,("Parsing: ")); PDEBUGPUTSXX(DBG_PARSE+DBG_USERDATA,aText,0,true); } #endif if (parseMimeDir(aText,aItem)) { if (fBeginEndNesting) { PDEBUGPRINTFX(DBG_ERROR,("TMimeDirProfileHandler parsing ended with NestCount<>0: %hd",fBeginEndNesting)); return false; // unmatched BEGIN/END } #ifdef SYDEBUG PDEBUGPRINTFX(DBG_PARSE,("Successfully parsed: ")); aItem.debugShowItem(DBG_DATA+DBG_PARSE); #endif return true; } else { PDEBUGPRINTFX(DBG_ERROR,("Failed parsing item")); return false; } } // TMimeDirProfileHandler::parseText bool TMimeDirProfileHandler::parseForProperty(SmlItemPtr_t aItemP, const char *aPropName, string &aString) { if (aItemP && aItemP->data) return parseForProperty(smlPCDataToCharP(aItemP->data),aPropName,aString); else return false; } // TMimeDirProfileHandler::parseForProperty // scan Data item for specific property (used for quick type tests) bool TMimeDirProfileHandler::parseForProperty(const char *aText, const char *aPropName, string &aString) { uInt16 n=strlen(aPropName); while (*aText) { const char *p=aText; // find property end do { p=nextunfolded(p,fMimeDirMode,true); } while ((*p)>=0x20); // p now points to property end if (strucmp(aText,aPropName,n)==0 && aText[n]==':') { aText+=n+1; // start of value aString.assign(aText,p-aText); // save value return true; } // find next property beginning do { p=nextunfolded(p,fMimeDirMode,true); } while (*p && ((*p)<0x20)); // set to beginning of next aText=p; } // not found return false; } // TMimeDirProfileHandler::parseForProperty // helper for newCTDataPropList void TMimeDirProfileHandler::enumerateLevels(const TProfileDefinition *aProfileP, SmlPcdataListPtr_t *&aPcdataListPP, const TProfileDefinition *aSelectedProfileP, TMimeDirItemType *aItemTypeP) { // only if mode matches if (!mimeModeMatch(aProfileP->modeDependency)) return; // add name of this profile if... // ...generally enabled for CTCap (shownIfSelectedOnly=false), independent of what other profiles might be selected (e.g. VALARM) // ...this is the explicitly selected profile (like VTODO while creating DS 1.2 devinf for the tasks datastor) // ...no profile is specifically selected, which means we want to see ALL profiles (like a DS 1.1 vCalendar type outside ) // This means, the only case a name is NOT added are those with those having showlevel="no" when ANOTHER profile is explicitly selected. if (!aProfileP->shownIfSelectedOnly || aProfileP==aSelectedProfileP || aSelectedProfileP==NULL) { aPcdataListPP = addPCDataStringToList(TCFG_CSTR(aProfileP->levelName),aPcdataListPP); // check for special subprofiles if (aProfileP->profileMode==profm_vtimezones) { // has STANDARD and DAYLIGHT subprofiles aPcdataListPP = addPCDataStringToList("STANDARD",aPcdataListPP); aPcdataListPP = addPCDataStringToList("DAYLIGHT",aPcdataListPP); } // add names of subprofiles, if any const TProfileDefinition *subprofileP = aProfileP->subLevels; while (subprofileP) { // If this profile is the selected profile, ALL subprofiles must be shown in all cases (so we pass NULL) enumerateLevels(subprofileP,aPcdataListPP,aProfileP==aSelectedProfileP ? NULL : aSelectedProfileP, aItemTypeP); // next subprofileP=subprofileP->next; } } } // TMimeDirProfileHandler::enumerateLevels // add a CTDataProp item to a CTDataPropList static void addCTDataPropToListIfNotExists( SmlDevInfCTDataPropPtr_t aCTDataPropP, // existing CTDataProp item data structure, ownership is passed to list SmlDevInfCTDataPropListPtr_t *aCTDataPropListPP // adress of list root pointer (which points to existing item list or NULL) ) { // add it to the list (but only if we don't already have it) while (*aCTDataPropListPP) { // check name if (strcmp(smlPCDataToCharP(aCTDataPropP->prop->name),smlPCDataToCharP((*aCTDataPropListPP)->data->prop->name))==0) { //%%% we can add merging parameters here as well // same property already exists, forget this one smlFreeDevInfCTDataProp(aCTDataPropP); aCTDataPropP = NULL; break; } aCTDataPropListPP = &((*aCTDataPropListPP)->next); } // if not detected duplicate, add it now if (aCTDataPropP) { addCTDataPropToList(aCTDataPropP,aCTDataPropListPP); } } // addCTDataPropToListIfNotExists // add a CTData describing a property (as returned by newDevInfCTData()) // as a new property without parameters to a CTDataPropList static void addNewPropToListIfNotExists( SmlDevInfCTDataPtr_t aPropCTData, // CTData describing property SmlDevInfCTDataPropListPtr_t *aCTDataPropListPP // adress of list root pointer (which points to existing item list or NULL) ) { SmlDevInfCTDataPropPtr_t propdataP = SML_NEW(SmlDevInfCTDataProp_t); propdataP->param = NULL; // no params propdataP->prop = aPropCTData; addCTDataPropToListIfNotExists(propdataP, aCTDataPropListPP); } // addNewPropToListIfNotExists // helper for newCTDataPropList void TMimeDirProfileHandler::enumerateProperties(const TProfileDefinition *aProfileP, SmlDevInfCTDataPropListPtr_t *&aPropListPP, const TProfileDefinition *aSelectedProfileP, TMimeDirItemType *aItemTypeP) { // remember start of properties // add all properties of this level (if enabled) // Note: if this is the explicitly selected (sub)profile, it will be shown under any circumstances if ((!aProfileP->shownIfSelectedOnly || aProfileP==aSelectedProfileP || aSelectedProfileP==NULL) && mimeModeMatch(aProfileP->modeDependency)) { if (aProfileP->profileMode==profm_vtimezones) { // Add properties of VTIMEZONE here addNewPropToListIfNotExists(newDevInfCTData("TZID"),aPropListPP); addNewPropToListIfNotExists(newDevInfCTData("DTSTART"),aPropListPP); addNewPropToListIfNotExists(newDevInfCTData("RRULE"),aPropListPP); addNewPropToListIfNotExists(newDevInfCTData("TZOFFSETFROM"),aPropListPP); addNewPropToListIfNotExists(newDevInfCTData("TZOFFSETTO"),aPropListPP); addNewPropToListIfNotExists(newDevInfCTData("TZNAME"),aPropListPP); } else { // normal profile defined in config, add properties as defined in profile, avoid duplicates const TPropertyDefinition *propP = aProfileP->propertyDefs; while (propP) { if (propP->showInCTCap && mimeModeMatch(propP->modeDependency)) { // - new list entry in CTCap (if property to be shown) SmlDevInfCTDataPropPtr_t propdataP = SML_NEW(SmlDevInfCTDataProp_t); propdataP->param = NULL; // default to no params // - add params, if needed SmlDevInfCTDataListPtr_t *nextParamPP = &(propdataP->param); const TParameterDefinition *paramP = propP->parameterDefs; while(paramP) { // check if parameter is enabled for being shown in CTCap if (paramP->showInCTCap && mimeModeMatch(paramP->modeDependency)) { // For some older 1.1 devices (in particular Nokia 7610), enum values of default params // in pre-MIME-DIR must be shown as param NAMES (not enums). // But newer 1.2 Nokias like E90 need proper TYPE param with valEnums (when run in 1.2 mode. E90 is fine with 7610 style for 1.1) // So: normally (fEnumDefaultPropParams==undefined==-1), we show 7610 style for 1.1 and E90 style for 1.2. // and ENUMDEFAULTPROPPARAMS() can be used to control this behaviour when needed if ( paramP->defaultparam && fMimeDirMode==mimo_old && ( (getSession()->fEnumDefaultPropParams==-1 && getSession()->getSyncMLVersion()fEnumDefaultPropParams==1) // ..or explicitly enabled ) ) { // add the name extending enum values as param names TEnumerationDef *enumP = paramP->convdef.enumdefs; while(enumP) { if (!TCFG_ISEMPTY(enumP->enumtext) && enumP->enummode==enm_translate) { // create new param list entry nextParamPP = addCTDataToList(newDevInfCTData(TCFG_CSTR(enumP->enumtext)),nextParamPP); } enumP=enumP->next; } } else { // - proper parameter with valEnum list SmlDevInfCTDataPtr_t paramdataP = newDevInfCTData(TCFG_CSTR(paramP->paramname)); // - add valenums if any SmlPcdataListPtr_t *nextValenumPP = &(paramdataP->valenum); TEnumerationDef *enumP = paramP->convdef.enumdefs; while(enumP) { if (!TCFG_ISEMPTY(enumP->enumtext) && enumP->enummode==enm_translate) { // create new valenum list entry nextValenumPP = addPCDataStringToList(TCFG_CSTR(enumP->enumtext),nextValenumPP); } enumP=enumP->next; } // - add it to the params list nextParamPP = addCTDataToList(paramdataP,nextParamPP); } } // if param to be shown paramP=paramP->next; } // - get possible size limit and notruncate flag uInt32 sz=0; // no size limit by default bool noTruncate=false; // by default, truncation is ok TFieldDefinition *fieldDefP = NULL; for (sInt16 i=0; inumValues; i++) { sInt16 fid=propP->convdefs[0].fieldid; if (fid>=0) { // Field type (we need it later when we have a maxsize, which is only allowed together with a datatype in 1.1 DTD) if (!fieldDefP) fieldDefP = fItemTypeP->getFieldDefinition(fid); // Size uInt32 fsz = fItemTypeP->getFieldOptions(fid)->maxsize; // only if related datastore (i.e. SyncML context) // - smallest non-fieldblock (excludes RRULE-type special conversions), not-unknown and not-unlimited maxsize is used if (fieldBlockSize(propP->convdefs[0])==1 && (sz==0 || sz>fsz) && fsz!=FIELD_OPT_MAXSIZE_NONE && sInt32(fsz)!=FIELD_OPT_MAXSIZE_UNKNOWN) sz=fsz; // If any field requests no truncation, report noTruncate if (getSession()->getSyncMLVersion()>=syncml_vers_1_2 && fItemTypeP->getFieldOptions(fid)->notruncate) noTruncate=true; } } // - calculate our own maxoccur (value in our field options is not used for now %%%) uInt32 maxOccur=0; if (getSession()->getSyncMLVersion()>=syncml_vers_1_2) { if (propP->nameExts) { // name extensions determine repeat count TPropNameExtension *extP = propP->nameExts; while (extP) { if (!extP->readOnly) { if (extP->maxRepeat==REP_ARRAY) { // no limit maxOccur=0; // unlimited break; // prevent other name extensions to intervene } else { // limited number of occurrences, add to count maxOccur+=extP->maxRepeat; } } // next extP=extP->next; } } else { // not repeating: property may not occur more than once maxOccur=1; } } // - some SyncML 1.0 clients crash when they see type/size if (!(getSession()->fShowTypeSzInCTCap10) && getSession()->getSyncMLVersion()<=syncml_vers_1_0) { sz = 0; // prevent size/type in SyncML 1.0 (as old clients like S55 crash if it is included) } // - find out if we need to show the type (before SyncML 1.2, Size MUST be preceeded by DataType) // On the other hand, DataType MUST NOT be used in 1.2 for VersIt types!!! cAppCharP dataType=NULL; if (sz!=0 && fieldDefP && getSession()->getSyncMLVersion()type]; if (dt==proptype_text) dt=proptype_chr; // SyncML 1.1 does not have "text" type if (dt!=proptype_unknown) dataType = propDataTypeNames[dt]; } // - add property data descriptor propdataP->prop = newDevInfCTData(TCFG_CSTR(propP->propname),sz,noTruncate,maxOccur,dataType); if (propP->convdefs && (propP->convdefs->convmode & CONVMODE_MASK)==CONVMODE_VERSION) { // special case: add version valenum addPCDataStringToList(aItemTypeP->getTypeVers(),&(propdataP->prop->valenum)); } // add it if not already same-named property in the list, otherwise discard it addCTDataPropToListIfNotExists(propdataP,aPropListPP); } // if to be shown in CTCap propP=propP->next; } // while properties } // normal profile defined in config // add properties of other levels const TProfileDefinition *subprofileP = aProfileP->subLevels; while (subprofileP) { // only if the current profile is the selected profile, properties of ALL contained subprofiles will be shown // (otherwise, selection might be within the current profile, so we need to pass on the selection) enumerateProperties(subprofileP,aPropListPP,aProfileP==aSelectedProfileP ? NULL : aSelectedProfileP, aItemTypeP); // next subprofileP=subprofileP->next; } } } // TMimeDirProfileHandler::enumerateProperties // helper: enumerate filter properties void TMimeDirProfileHandler::enumeratePropFilters(const TProfileDefinition *aProfileP, SmlPcdataListPtr_t &aFilterProps, const TProfileDefinition *aSelectedProfileP, TMimeDirItemType *aItemTypeP) { // add all properties of this level (if enabled) // Note: if this is the explicitly selected (sub)profile, it will be shown under any circumstances if (!aProfileP->shownIfSelectedOnly || aProfileP==aSelectedProfileP) { const TPropertyDefinition *propP = aProfileP->propertyDefs; while (propP) { if ( propP->canFilter && (propP->showInCTCap || aProfileP==aSelectedProfileP) && propP->convdefs && (propP->convdefs[0].convmode & CONVMODE_MASK)!=CONVMODE_VERSION && (propP->convdefs[0].convmode & CONVMODE_MASK)!=CONVMODE_PRODID ) { // Note: properties of explicitly selected (sub)profiles will be shown anyway, // as only purpose of suppressing properties in devInf is to avoid // duplicate listing in case of multiple subprofiles in ONE CTCap. // - add property name to filter property list addPCDataStringToList(TCFG_CSTR(propP->propname), &aFilterProps); } // if to be shown in filterCap propP=propP->next; } } // add properties of other levels const TProfileDefinition *subprofileP = aProfileP->subLevels; while (subprofileP) { if (aSelectedProfileP==NULL || subprofileP==aSelectedProfileP) { // only if the current profile is the selected profile, filter properties of ALL contained subprofiles will be shown enumeratePropFilters(subprofileP,aFilterProps,aProfileP==aSelectedProfileP ? NULL : aSelectedProfileP, aItemTypeP); } // next subprofileP=subprofileP->next; } } // TMimeDirProfileHandler::enumeratePropFilters #ifdef OBJECT_FILTERING // Filtering: add keywords and property names to filterCap void TMimeDirProfileHandler::addFilterCapPropsAndKeywords(SmlPcdataListPtr_t &aFilterKeywords, SmlPcdataListPtr_t &aFilterProps, TTypeVariantDescriptor aVariantDescriptor, TSyncItemType *aItemTypeP) { // get pointer to selected variant (if none, all variants will be shown) const TProfileDefinition *selectedSubprofileP = (const TProfileDefinition *)aVariantDescriptor; // get pointer to mimedir item type TMimeDirItemType *mimeDirItemTypeP; GET_CASTED_PTR(mimeDirItemTypeP,TMimeDirItemType,aItemTypeP,"MIME-DIR profile used with non-MIME-DIR type"); // add name of all properties that have canFilter attribute set enumeratePropFilters(fProfileDefinitionP,aFilterProps,selectedSubprofileP, mimeDirItemTypeP); } // TMimeDirProfileHandler::addFilterCapPropsAndKeywords #endif // OBJECT_FILTERING // generates SyncML-Devinf property list for type SmlDevInfCTDataPropListPtr_t TMimeDirProfileHandler::newCTDataPropList(TTypeVariantDescriptor aVariantDescriptor, TSyncItemType *aItemTypeP) { TMimeDirItemType *itemTypeP = static_cast(aItemTypeP); // get pointer to selected variant (if none, all variants will be shown) const TProfileDefinition *selectedSubprofileP = (const TProfileDefinition *)aVariantDescriptor; // generate new list SmlDevInfCTDataPropListPtr_t proplistP = SML_NEW(SmlDevInfCTDataPropList_t); SmlDevInfCTDataPropListPtr_t nextpropP = proplistP; // generate BEGIN property // - add property contents nextpropP->data = SML_NEW(SmlDevInfCTDataProp_t); nextpropP->data->param=NULL; // no params // - property data descriptor SmlDevInfCTDataPtr_t pdataP = newDevInfCTData("BEGIN"); nextpropP->data->prop = pdataP; // - add valenums for all profiles and subprofiles SmlPcdataListPtr_t *liststartPP = &pdataP->valenum; enumerateLevels(fProfileDefinitionP,liststartPP,selectedSubprofileP,itemTypeP); // generate END property nextpropP->next = SML_NEW(SmlDevInfCTDataPropList_t); nextpropP=nextpropP->next; // - add property contents nextpropP->data = SML_NEW(SmlDevInfCTDataProp_t); nextpropP->data->param=NULL; // no params // - property data descriptor pdataP = newDevInfCTData("END"); nextpropP->data->prop = pdataP; // - add valenums for all profiles and subprofiles liststartPP = &pdataP->valenum; enumerateLevels(fProfileDefinitionP,liststartPP,selectedSubprofileP,itemTypeP); // generate all other properties of all levels nextpropP->next=NULL; // in case no properties are found SmlDevInfCTDataPropListPtr_t *propstartPP = &nextpropP->next; enumerateProperties(fProfileDefinitionP,propstartPP,selectedSubprofileP,itemTypeP); // done return proplistP; } // TMimeDirProfileHandler::newCTDataPropList // Analyze CTCap part of devInf bool TMimeDirProfileHandler::analyzeCTCap(SmlDevInfCTCapPtr_t aCTCapP, TSyncItemType *aItemTypeP) { TMimeDirItemType *itemTypeP = static_cast(aItemTypeP); // assume all sublevels enabled (as long as we don't get a // BEGIN CTCap listing all the available levels. //aItemTypeP->setLevelOptions(NULL,true); // check details SmlDevInfCTDataPropListPtr_t proplistP = aCTCapP->prop; if (proplistP) { if (!itemTypeP->fReceivedFieldDefs) { // there is a propList, and we haven't scanned one already for this type // (could be the case for DS 1.2 vCalendar where we get events & tasks separately) // so disable all non-mandatory fields first (available ones will be re-enabled) for (sInt16 i=0; ifFieldDefinitionsP->numFields(); i++) { itemTypeP->getFieldOptions(i)->available=false; } // force mandatory properties to be always "available" setfieldoptions(NULL,fProfileDefinitionP,itemTypeP); } // now we have received fields itemTypeP->fReceivedFieldDefs=true; } while (proplistP) { // get property descriptor SmlDevInfCTDataPtr_t propP = proplistP->data->prop; // see if we have this property in any of the levels setfieldoptions(propP,fProfileDefinitionP,itemTypeP); // next property in CTCap proplistP=proplistP->next; } // properties in CTCap return true; } // TMimeDirProfileHandler::analyzeCTCap // %%%%% dummy for now bool TMimeDirProfileHandler::setLevelOptions(const char *aLevelName, bool aEnable, TMimeDirItemType *aItemTypeP) { // do it recursively. // %%% we need to have a flag somewhere for these // don't we have one already??? // YES, its fSubLevelRestrictions (supposedly a bitmask for max 32 levels) // %%% checking the levels and ignoring incoming/outgoing items with // wrong levels must be added later return true; } // TMimeDirProfileHandler::setLevelOptions // enable fields related to aPropP property in profiles recursively // or (if aPropP is NULL), enable fields of all mandatory properties void TMimeDirProfileHandler::setfieldoptions( const SmlDevInfCTDataPtr_t aPropP, // property to enable fields for, NULL if all mandatory properties should be enabled const TProfileDefinition *aProfileP, TMimeDirItemType *aItemTypeP ) { // set defaults sInt32 propsize = FIELD_OPT_MAXSIZE_NONE; sInt32 maxOccur = 0; // none by default bool noTruncate=false; const char* propname = NULL; TFieldOptions *fo; // get params from CTCap property definition (if any) if (aPropP) { // get name of CTCap property propname = smlPCDataToCharP(aPropP->name); // get possible maxSize if (aPropP->maxsize) { if (getSession()->fIgnoreDevInfMaxSize) { // remote rule flags maxsize as invalid (like in E90), flag it as unknown (but possibly limited) propsize = FIELD_OPT_MAXSIZE_UNKNOWN; } else { // treat as valid StrToLong(smlPCDataToCharP(aPropP->maxsize),propsize); } } // get possible maxOccur if (aPropP->maxoccur) { StrToLong(smlPCDataToCharP(aPropP->maxoccur),maxOccur); } // get possible noTruncate if (aPropP->flags & SmlDevInfNoTruncate_f) noTruncate=true; // check for BEGIN to check for enabled sublevels if (strucmp(propname,"BEGIN")==0) { // check ValEnums that denote supported levels SmlPcdataListPtr_t valenumP = aPropP->valenum; if (valenumP) { // we HAVE supported BEGINs listed, so disable all levels first // and have them individually enabled below according to ValEnums setLevelOptions(NULL,false,aItemTypeP); } while (valenumP) { // get sublevel name const char *slname = smlPCDataToCharP(valenumP->data); setLevelOptions(slname,true,aItemTypeP); // enable this one // check next valenumP=valenumP->next; } } } // if enabling for specified property // enable all fields related to this property and set options const TPropertyDefinition *propdefP = aProfileP->propertyDefs; sInt16 j,q,i,o,r,bs; while (propdefP) { // compare if ( (propname==NULL && propdefP->mandatory) || (propname && (strucmp(propname,TCFG_CSTR(propdefP->propname))==0)) ) { // match (or enabling mandatory) -> enable all fields that are related to this property // - values for (i=0; inumValues; i++) { // base field ID j=propdefP->convdefs[i].fieldid; bs=fieldBlockSize(propdefP->convdefs[i]); if (j>=0) { // field supported TPropNameExtension *pneP = propdefP->nameExts; if (pneP) { while(pneP) { o = pneP->fieldidoffs; if (o>=0) { r=0; // for all repetitions (but only for first if mode is REP_ARRAY // or field is an array) do { // make entire field block addressed by this convdef available // and set maxoccur/notruncate for (q=0; qgetFieldOptions(j+o+q); if (fo) fo->available=true; } // set size if specified (only for first field in block) fo = aItemTypeP->getFieldOptions(j+o); if (fo) { if (propsize!=FIELD_OPT_MAXSIZE_NONE) fo->maxsize=propsize; // set maxoccur if specified if (maxOccur!=0) fo->maxoccur=maxOccur; // set noTruncate if (noTruncate) fo->notruncate=true; } // next o+=pneP->repeatInc; } while ( ++r < pneP->maxRepeat && pneP->maxRepeat!=REP_ARRAY #ifdef ARRAYFIELD_SUPPORT && !aItemTypeP->getFieldDefinition(j)->array #endif ); } pneP=pneP->next; } } else { // single variant, non-repeating property // make entire field block addressed by this convdef available for (q=0; qgetFieldOptions(j+q); if (fo) fo->available=true; } // set size if specified fo = aItemTypeP->getFieldOptions(j); if (fo) { if (propsize!=FIELD_OPT_MAXSIZE_NONE) fo->maxsize=propsize; // set maxoccur if specified if (maxOccur!=0) fo->maxoccur=maxOccur; // set noTruncate if (noTruncate) fo->notruncate=true; } } } } // enable values // - parameter values const TParameterDefinition *paramdefP = propdefP->parameterDefs; while(paramdefP) { // base field ID j=paramdefP->convdef.fieldid; bs=fieldBlockSize(paramdefP->convdef); if (j>=0) { // field supported TPropNameExtension *pneP = propdefP->nameExts; if (pneP) { while(pneP) { o = pneP->fieldidoffs; if (o>=0) { r=0; // for all repetitions do { // make entire field block addressed by this convdef available for (q=0; qgetFieldOptions(j+o+q); if (fo) fo->available=true; } // set size if specified fo = aItemTypeP->getFieldOptions(j+o); if (propsize!=FIELD_OPT_MAXSIZE_NONE && fo) fo->maxsize=propsize; // Note: MaxOccur and NoTruncate are not relevant for parameter values // next o+=pneP->repeatInc; } while ( ++r < pneP->maxRepeat && pneP->maxRepeat!=REP_ARRAY #ifdef ARRAYFIELD_SUPPORT && !aItemTypeP->getFieldDefinition(j)->array #endif ); } pneP=pneP->next; } } else { // single variant, non-repeating property // make entire field block addressed by this convdef available for (q=0; qgetFieldOptions(j+q); if (fo) fo->available=true; } // set size if specified fo = aItemTypeP->getFieldOptions(j); if (propsize!=FIELD_OPT_MAXSIZE_NONE && fo) fo->maxsize=propsize; } } paramdefP=paramdefP->next; } // while } // if known property propdefP=propdefP->next; } // now enable fields in all subprofiles const TProfileDefinition *subprofileP = aProfileP->subLevels; while (subprofileP) { setfieldoptions(aPropP,subprofileP,aItemTypeP); // next subprofileP=subprofileP->next; } } // TMimeDirProfileHandler::setfieldoptions // set mode (for those profiles that have more than one, like MIME-DIR's old/standard) void TMimeDirProfileHandler::setProfileMode(sInt32 aMode) { fProfileMode = aMode; // determine derived mime mode switch (aMode) { case PROFILEMODE_OLD : fMimeDirMode=mimo_old; break; // 1 = old = vCard 2.1 / vCalendar 1.0 default : fMimeDirMode=mimo_standard; break; // anything else = standard = vCard 3.0 / iCalendar 2.0 style } } // TMimeDirProfileHandler::setProfileMode #ifndef NO_REMOTE_RULES void TMimeDirProfileHandler::setRemoteRule(const string &aRemoteRuleName) { TSessionConfig *scP = getSession()->getSessionConfig(); TRemoteRulesList::iterator pos; for(pos=scP->fRemoteRulesList.begin();pos!=scP->fRemoteRulesList.end();pos++) { if((*pos)->fElementName == aRemoteRuleName) { // only this rule and all rules included by it rule must be active fActiveRemoteRules.clear(); activateRemoteRule(*pos); break; } } } // TMimeDirProfileHandler::setRemoteRule void TMimeDirProfileHandler::activateRemoteRule(TRemoteRuleConfig *aRuleP) { // activate this rule (similar code as in TSyncSession::checkRemoteSpecifics() fActiveRemoteRules.push_back(aRuleP); // - apply options that have a value //if (aRuleP->fLegacyMode>=0) fLegacyMode = aRuleP->fLegacyMode; //if (aRuleP->fLenientMode>=0) fLenientMode = aRuleP->fLenientMode; //if (aRuleP->fLimitedFieldLengths>=0) fLimitedRemoteFieldLengths = aRuleP->fLimitedFieldLengths; if (aRuleP->fDontSendEmptyProperties>=0) fDontSendEmptyProperties = aRuleP->fDontSendEmptyProperties; if (aRuleP->fDoQuote8BitContent>=0) fDoQuote8BitContent = aRuleP->fDoQuote8BitContent; if (aRuleP->fDoNotFoldContent>=0) fDoNotFoldContent = aRuleP->fDoNotFoldContent; //if (aRuleP->fNoReplaceInSlowsync>=0) fNoReplaceInSlowsync = aRuleP->fNoReplaceInSlowsync; if (aRuleP->fTreatRemoteTimeAsLocal>=0) fTreatRemoteTimeAsLocal = aRuleP->fTreatRemoteTimeAsLocal; if (aRuleP->fTreatRemoteTimeAsUTC>=0) fTreatRemoteTimeAsUTC = aRuleP->fTreatRemoteTimeAsUTC; if (aRuleP->fVCal10EnddatesSameDay>=0) fVCal10EnddatesSameDay = aRuleP->fVCal10EnddatesSameDay; //if (aRuleP->fIgnoreDevInfMaxSize>=0) fIgnoreDevInfMaxSize = aRuleP->fIgnoreDevInfMaxSize; //if (aRuleP->fIgnoreCTCap>=0) fIgnoreCTCap = aRuleP->fIgnoreCTCap; //if (aRuleP->fDSPathInDevInf>=0) fDSPathInDevInf = aRuleP->fDSPathInDevInf; //if (aRuleP->fDSCgiInDevInf>=0) fDSCgiInDevInf = aRuleP->fDSCgiInDevInf; //if (aRuleP->fUpdateClientDuringSlowsync>=0) fUpdateClientDuringSlowsync = aRuleP->fUpdateClientDuringSlowsync; //if (aRuleP->fUpdateServerDuringSlowsync>=0) fUpdateServerDuringSlowsync = aRuleP->fUpdateServerDuringSlowsync; //if (aRuleP->fAllowMessageRetries>=0) fAllowMessageRetries = aRuleP->fAllowMessageRetries; //if (aRuleP->fStrictExecOrdering>=0) fStrictExecOrdering = aRuleP->fStrictExecOrdering; //if (aRuleP->fTreatCopyAsAdd>=0) fTreatCopyAsAdd = aRuleP->fTreatCopyAsAdd; //if (aRuleP->fCompleteFromClientOnly>=0) fCompleteFromClientOnly = aRuleP->fCompleteFromClientOnly; //if (aRuleP->fRequestMaxTime>=0) fRequestMaxTime = aRuleP->fRequestMaxTime; if (aRuleP->fDefaultOutCharset!=chs_unknown) fDefaultOutCharset = aRuleP->fDefaultOutCharset; if (aRuleP->fDefaultInCharset!=chs_unknown) fDefaultInCharset = aRuleP->fDefaultInCharset; // - possibly override decisions that are otherwise made by session // Note: this is not a single option because we had this before rule options were tristates. //if (aRuleP->fForceUTC>0) fRemoteCanHandleUTC=true; //if (aRuleP->fForceLocaltime>0) fRemoteCanHandleUTC=false; // now recursively activate included rules TRemoteRulesList::iterator pos; for(pos=aRuleP->fSubRulesList.begin();pos!=aRuleP->fSubRulesList.end();pos++) { activateRemoteRule(*pos); } } // check if given rule (by name, or if aRuleName=NULL by rule pointer) is active bool TMimeDirProfileHandler::isActiveRule(TRemoteRuleConfig *aRuleP) { TRemoteRulesList::iterator pos; for(pos=fActiveRemoteRules.begin();pos!=fActiveRemoteRules.end();pos++) { if ((*pos)==aRuleP) return true; } // no match return false; } // TMimeDirProfileHandler::isActiveRule #endif // NO_REMOTE_RULES // - check mode bool TMimeDirProfileHandler::mimeModeMatch(TMimeDirMode aMimeMode) { return aMimeMode==numMimeModes || // not dependent on MIME mode aMimeMode==fMimeDirMode; } // TMimeDirProfileHandler::mimeModeMatch /* end of TMimeDirProfileHandler implementation */ // Utility functions // ----------------- /// @brief checks two timestamps if they represent an all-day event /// @param[in] aStart start time /// @param[in] aEnd end time /// @return 0 if not allday, x=1..n if allday (spanning x days) by one of the /// following criteria: /// - both start and end at midnight of the same day (= 1 day) /// - both start and end at midnight of different days (= 1..n days) /// - start at midnight and end between 23:59:00 and 23:59:59 of /// same or different days (= 1..n days) uInt16 AlldayCount(lineartime_t aStart, lineartime_t aEnd) { lineartime_t startTime = lineartime2timeonly(aStart); if (startTime!=0) return 0; // start not at midnight -> no allday lineartime_t endTime = lineartime2timeonly(aEnd); if (endTime==0) { if (aStart==aEnd) aEnd += linearDateToTimeFactor; // one day } else if (endTime>= (23*MinsPerHour+59)*SecsPerMin*secondToLinearTimeFactor) { // add one minute to make sure we reach into next day aEnd += SecsPerMin*secondToLinearTimeFactor; } else return 0; // allday criteria not met // now calculate number of days return (aEnd-aStart) / linearDateToTimeFactor; } // AlldayCount /// @brief checks two timestamps if they represent an all-day event /// @param[in] aStartFldP start time field /// @param[in] aEndFldP end time field /// @param[in] aTimecontext context to use to check allday criteria for all non-floating timestamps /// or UTC timestamps only (if aContextForUTC is set). /// @param[in] aContextForUTC if set, context is only applied for UTC timestamps, other non-floatings are checked as-is /// @return 0 if not allday, x=1..n if allday (spanning x days) uInt16 AlldayCount(TItemField *aStartFldP, TItemField *aEndFldP, timecontext_t aTimecontext, bool aContextForUTC) { if (!aStartFldP->isBasedOn(fty_timestamp)) return 0; if (!aEndFldP->isBasedOn(fty_timestamp)) return 0; TTimestampField *startFldP = static_cast(aStartFldP); TTimestampField *endFldP = static_cast(aEndFldP); // check in specified time zone if originally UTC (or aContextForUTC not set), otherwise check as-is timecontext_t tctx; lineartime_t start = startFldP->getTimestampAs(!aContextForUTC || TCTX_IS_UTC(startFldP->getTimeContext()) ? aTimecontext : TCTX_UNKNOWN, &tctx); lineartime_t end = endFldP->getTimestampAs(!aContextForUTC || TCTX_IS_UTC(endFldP->getTimeContext()) ? aTimecontext : TCTX_UNKNOWN, &tctx); return AlldayCount(start,end); } // AlldayCount /// @brief makes two timestamps represent an all-day event /// @param[in/out] aStart start time within the first day, will be set to midnight (00:00:00) /// @param[in/out] aEnd end time within the last day or at midnight of the next day, /// will be set to midnight of the next day /// @param[in] aDays if>0, this is used to calculate the aEnd timestamp (aEnd input is /// ignored then) void MakeAllday(lineartime_t &aStart, lineartime_t &aEnd, sInt16 aDays) { lineartime_t duration = 0; // first calculate duration (assuming that even if there's a timezone problem, both // timestamps will be affected so duration is still correct) if (aDays<=0) { // use implicit duration duration = aEnd-aStart; } else { // use explicit duration duration = aDays * linearDateToTimeFactor; } // truncate start to midnight aStart = lineartime2dateonlyTime(aStart); // calculate timestamp that for sure is in next day aEnd = aStart + duration + linearDateToTimeFactor-1; // one unit less than a full day, ensures that 00:00:00 input will remain same day // make day-only of next day aEnd = lineartime2dateonlyTime(aEnd); } // MakeAllday /// @brief makes two timestamp fields represent an all-day event /// @param[in/out] aStartFldP start time within the first day, will be set to dateonly /// @param[in/out] aEndFldP end time within the last day or at midnight of the next day, will be set to dateonly of the next day /// @param[in] aTimecontext context to calculate day boundaries in (if timestamp is not already floating), can be floating to treat in context of start date /// @param[in] aDays if>0, this is used to calculate the aEnd timestamp (aEnd input is /// ignored then) /// @note fields will be made floating and dateonly void MakeAllday(TItemField *aStartFldP, TItemField *aEndFldP, timecontext_t aTimecontext, sInt16 aDays) { if (!aStartFldP->isBasedOn(fty_timestamp)) return; if (!aEndFldP->isBasedOn(fty_timestamp)) return; TTimestampField *startFldP = static_cast(aStartFldP); TTimestampField *endFldP = static_cast(aEndFldP); // adjust in specified time zone (or floating) timecontext_t tctx; lineartime_t start = startFldP->getTimestampAs(aTimecontext,&tctx); // context must match, unless either requested-as-is or timestamp is already floating if (tctx!=aTimecontext && !TCTX_IS_UNKNOWN(aTimecontext) && !TCTX_IS_UNKNOWN(tctx)) return; // cannot do anything // get end in same context as start is lineartime_t end = endFldP->getTimestampAs(tctx); // make allday MakeAllday(start,end,aDays); // store back and floating + dateonly tctx = TCTX_UNKNOWN | TCTX_DATEONLY; // for output format capable of date-only startFldP->setTimestampAndContext(start,tctx); endFldP->setTimestampAndContext(end,tctx); } // MakeAllday } // namespace sysync // eof libsynthesis-3.4.0.47.1/src/sysync/mimedirprofile.h000077500000000000000000001056051226375725500221550ustar00rootroot00000000000000/* * File: mimedirprofile.h * * Author: Lukas Zeller (luz@plan44.ch) * * TMimeDirItemType * base class for MIME DIR based content types (vCard, vCalendar...) * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * 2009-01-09 : luz : created from mimediritemtype.h * */ #ifndef MimeDirProfile_H #define MimeDirProfile_H // includes #include "syncitemtype.h" #include "multifielditemtype.h" #include "engine_defs.h" #include namespace sysync { // conversion mode is a basic value plus some optional flags #define CONVMODE_MASK 0xFF // 8 bits for basic convmode // flags #define CONVMODE_FLAG_EXTFMT 0x0100 // use ISO8601 extended format for rendering date and time #define CONVMODE_FLAG_MILLISEC 0x0200 // render milliseconds // special field conversion modes #define CONVMODE_NONE 0 // no conversion (just string copy), but includes value list parsing and enum conversion #define CONVMODE_VERSION 1 // version #define CONVMODE_PRODID 2 // PRODID #define CONVMODE_TIMESTAMP 3 // forced full timestamp, even if this is a date field #define CONVMODE_DATE 4 // forced date-only, even if this is a timestamp field #define CONVMODE_AUTODATE 5 // in vCal 1.0 style formats, force to timestamp representation, in MIME-DIR, show depending on actual value #define CONVMODE_AUTOENDDATE 6 // in vCal 1.0 style formats, force to timestamp representation - if actual value is a date, subtract 1 unit (to show end of previous day rather than midnight of next) #define CONVMODE_TZ 7 // time zone offset in ISO8601 hh:mm representation for vCalendar 1.0 representation #define CONVMODE_DAYLIGHT 8 // DAYLIGHT property to describe time zone with DST in vCalendar 1.0 #define CONVMODE_TZID 9 // time zone ID for iCalendar 2.0 #define CONVMODE_EMPTYONLY 10 // same as CONVMODE_NONE, except that assignment occurs only if field is still empty #define CONVMODE_BITMAP 11 // values, converted to integer, are interpreted as bit numbers #define CONVMODE_BLOB_B64 12 // 1:1 storage of (decoded) value into field. When encoding, b64 is used #define CONVMODE_MAILTO 13 // 1:1 storage of (decoded) value into field. When encoding, b64 is used #define CONVMODE_VALUETYPE 14 // automatic VALUE parameter e.g. for timestamp fields that contain a date-only value (VALUE=DATE) or duration (VALUE=DURATION) #define CONVMODE_MULTIMIX 15 // special mode for mapping enums to bits (like CONVMODE_BITMAP), but mixed from multiple fields and with option to store as-is (special enum "value" syntax needed) #define CONVMODE_FULLVALUETYPE 16 // explicit VALUE parameter, does not assume a default #define CONVMODE_BLOB_AUTO 17 // like CONVMODE_BLOB_B64, but if data consists of printable ASCII-chars only, no B64 encoding is used // derived type modes start here #define CONVMODE_MIME_DERIVATES 20 // define those that we want to implement (also work as getConfMode conditionals) #define CONVMODE_RRULE CONVMODE_MIME_DERIVATES+0 // RRULE, needs RRULE field block // special numvals #define NUMVAL_LIST -1 // property contains a value list (like EXDATE) rather than individual values (like N) #define NUMVAL_REP_LIST -2 // same as NUMVAL_LIST, but property is output as repetition of the entire property rather than as list in single property // profile internal MIME-DIR mode (externally, profile mode is set by PROFILEMODE_xxx and setProfileMode() typedef enum { mimo_old, // vCard 2.1 type encoding, CRLF, default params mimo_standard, // MIME DIR conformant, vCard 3.0 mode numMimeModes } TMimeDirMode; // VTIMEZONE generation mode (what timezone definition rules to include) typedef enum { vtzgen_current, vtzgen_start, vtzgen_end, vtzgen_range, vtzgen_openend, numVTimeZoneGenModes } TVTimeZoneGenMode; typedef enum { tzidgen_default, tzidgen_olson, numTzIdGenModes } TTzIdGenMode; // name extension map typedef uInt32 TNameExtIDMap; // forward class TProfileDefinition; class TPropertyDefinition; class TMimeDirItemType; class TRemoteRuleConfig; // enumeration modes typedef enum { enm_translate, // translation from value to name and vice versa enm_prefix, // enumtext/enumval are prefixes of enm_default_name, // default name when translating from value to name enm_default_value, // default value when translating from name to value enm_ignore, // ignore value or name numEnumModes } TEnumMode; // enumeration element definition class TEnumerationDef : noncopyable { public: // constructor/destructor TEnumerationDef(const char *aEnumName, const char *aEnumVal, TEnumMode aMode, sInt16 aNameExtID=-1); ~TEnumerationDef(); // next item TEnumerationDef *next; // enum text TCFG_STRING enumtext; // enum translation (value to be stored in DB field), NULL if no translation TCFG_STRING enumval; // enum mode TEnumMode enummode; // ID (0..31) identifying ID of this value for property name extension purposes // -1 means value is irrelevant to name extension sInt16 nameextid; }; // TEnumerationDef // conversion & storage definition class TConversionDef : noncopyable { public: // constructor/destructor TConversionDef(); ~TConversionDef(); // tools void addEnum(const char *aEnumName, const char *aEnumVal, TEnumMode aMode=enm_translate); void addEnumNameExt(TPropertyDefinition *aProp, const char *aEnumName, const char *aEnumVal=NULL, TEnumMode aMode=enm_translate); TConversionDef *setConvDef(sInt16 aFieldId=FID_NOT_SUPPORTED,sInt16 aConvMode=0,char aCombSep=0); const TEnumerationDef *findEnumByName(const char *aName, sInt16 n=0) const; const TEnumerationDef *findEnumByVal(const char *aVal, sInt16 n=0) const; // base field id for parameter (will be offset for name-extended and repeated properties) sInt16 fieldid; // VARIDX_UNDEFINED (negative) means value is not supported // enumeration list, NULL if none TEnumerationDef *enumdefs; // conversion sInt16 convmode; // 0=direct, 1..n=special procedure needed char combineSep; // 0=no combination, char=char to be used to combine multiple values in field }; // TConversionDef // parameter definition class TParameterDefinition : noncopyable { public: // constructor/destructor TParameterDefinition(const char *aName, bool aDefault, bool aExtendsName, bool aShowNonEmpty, bool aShowInCTCap, TMimeDirMode aModeDep); ~TParameterDefinition(); // tools TConversionDef *setConvDef(sInt16 aFieldId=FID_NOT_SUPPORTED,sInt16 aConvMode=0,char aCombSep=0) { return convdef.setConvDef(aFieldId,aConvMode,aCombSep); }; TNameExtIDMap getExtIDbit(const char *aEnumName, sInt16 n=0); // next TParameterDefinition *next; // parameter name TCFG_STRING paramname; // NULL for terminator // used as default param, for example for type tags which have no explicit TYPE= in older vXX formats bool defaultparam; // parameter exists only in specific MIME-DIR mode (set to numMimeModes for non-dependent parameter) TMimeDirMode modeDependency; // parameter can extend property name by enumerated values with nameextid's bool extendsname; // if parameter has non-empty value, property will be treated as non-empty bool shownonempty; // flag if parameter should be (not necessarily IS, depending on SyncML version) shown in CTCap bool showInCTCap; // conversion information TConversionDef convdef; #ifndef NO_REMOTE_RULES // rule processing is simpler than with properties: // a parameter is expanded or parsed if no rule was set or the given // rule is active TRemoteRuleConfig *ruleDependency; // name of remote rule dependency (will be resolved to set ruleDependency) TCFG_STRING dependencyRuleName; #endif }; // TParameterDefinition // property name extension by values of parameters class TPropNameExtension : noncopyable { public: // constructor/destructor TPropNameExtension( TNameExtIDMap aMusthave_ids, TNameExtIDMap aForbidden_ids, TNameExtIDMap aAddtlSend_ids, sInt16 aFieldidoffs, sInt16 aMaxRepeat, sInt16 aRepeatInc, sInt16 aMinShow, bool aOverwriteEmpty, bool aReadOnly, sInt16 aRepeatID ); ~TPropNameExtension(); // link to next, NULL if end TPropNameExtension *next; // Bitmap, has bit set for each nameextid which must be present for property // in order to store it with given fid offset. // - This nameextids will also be used to generate properties with // corresponding parameter values. TNameExtIDMap musthave_ids; // Bitmap, has bit set for each nameextid which MAY NOT be present for // property in order to store it with given fid offset. TNameExtIDMap forbidden_ids; // Bitmap, has bit set for each nameextid which should additionally be present // when sending the property (such as VOICE for telephone), but is not a musthave. TNameExtIDMap addtlSend_ids; // field ID offset to be used for storage of property value(s) and // non-name extending parameter value(s) on musthave_ids/forbidden_ids matches // OFFS_NOSTORE : prevents storing/generating of this property value sInt16 fieldidoffs; // allowable repeat count (adding repeatInc to all related field ids when property is repeated) // - if set to REP_REWRITE (=0), value can occur multiple times, but later occurrences // override earlier ones (no offset incrementing) // - if set to REP_ARRAY, repeat is unlimited (should be used with array fields only) sInt16 maxRepeat; // if maxRepeat>1, the offset is incremented by the given value // (to allow multi-value properties to be repeated blockwise, not field-by-field) sInt16 repeatInc; // minimal number of times the property should be shown, even if repetitions do not contain // any values. If set to 0, property will not show at all if no values are there sInt16 minShow; // flag to allow overwriting empty instances with next non-empty instance of same property bool overwriteEmpty; // flag for name extension variants only used for parsing, not for generating bool readOnly; // unique (over all TPropNameExtension) ID used for keeping track of repetitions at parsing sInt16 repeatID; }; // TPropNameExtension // property definition class TPropertyDefinition : noncopyable { public: // constructor/destructor TPropertyDefinition(const char* aName, sInt16 aNumVals, bool aMandatory, bool aShowInCTCap, bool aSuppressEmpty, uInt16 aDelayedProcessing, char aValuesep, char aAltValuesep, uInt16 aPropertyGroupID, bool aCanFilter, TMimeDirMode aModeDep, sInt16 aGroupFieldID, bool aAllowFoldAtSep); ~TPropertyDefinition(); // tools TParameterDefinition *addParam(const char *aName, bool aDefault, bool aExtendsName, bool aShowNonEmpty=false, bool aShowInCTCap=false, TMimeDirMode aModeDep=numMimeModes); void addNameExt(TProfileDefinition *aRootProfile, // for profile-global RepID generation TNameExtIDMap aMusthave_ids, TNameExtIDMap aForbidden_ids, TNameExtIDMap aAddtlSend_ids, sInt16 aFieldidoffs, sInt16 aMaxRepeat=1, sInt16 aRepeatInc=1, sInt16 aMinShow=-1, bool aOverwriteEmpty=true, // show all, but overwrite empty repetitions bool aReadOnly=false, // not a parsing alternative sInt16 aShareCountOffs=0 // not sharing the repeat ID with a previous name extension ); TConversionDef *setConvDef(sInt16 aValNum, sInt16 aFieldId=FID_NOT_SUPPORTED,sInt16 aConvMode=0,char aCombSep=0); TParameterDefinition *findParameter(const char *aNam, sInt16 aLen=0); // next in list TPropertyDefinition *next; // property name TCFG_STRING propname; // property name extension list. // - If NULL, property is non-repeatable and has no name extensions at all TPropNameExtension *nameExts; // ID of group field sInt16 groupFieldID; // number of values sInt16 numValues; // conversion specification(s) for each value TConversionDef *convdefs; // if set, property is not processed but stored entirely (unfolded, but otherwise unprocessed) in the first defined // This gets automatically set when a property name contains an asterisk wildcard character bool unprocessed; // if set, property has a list of values that are stored in an array field or // by offseting fid. Note that a PropNameExtension is needed to allow storing more // than a single value. If valuelist=true, convdefs should only contain a single entry, // other entries are not used bool valuelist; // if set, valuelist properties should be rendered by repeating the property instead of creating a list of values in one property bool expandlist; // char to separate value list items (defaults to semicolon) char valuesep; char altvaluesep; // second value separator to respect when parsing (generating always uses valuesep) bool allowFoldAtSep; // allow folding at value separators (for mimo_old, even if it inserts an extra space) // parameter listm TParameterDefinition *parameterDefs; // mandatory bool mandatory; // flag if property should be shown in CTCap bool showInCTCap; // flag if property can be used in filters (and will be shown in FilterCap, when showInCTCap is true as well bool canFilter; // flag if property should be suppressed if it has only empty values bool suppressEmpty; // delayed processing order (for things like RRULE that must be processed at the end) uInt16 delayedProcessing; // property exists only in specific MIME-DIR mode (set to numMimeModes for non-dependent properties) TMimeDirMode modeDependency; // internal for creation of name extension IDs sInt16 nextNameExt; // property group ID uInt16 propGroup; // starting at 1, groups subsequent props that have the same name #ifndef NO_REMOTE_RULES // set if property enabled only if ruleDependency matches session's applied rule (even if NULL = no rule must be applied) bool dependsOnRemoterule; // the rule that must be selected to enable this property. If NULL, this property // is used only if NO rule is selected. TRemoteRuleConfig *ruleDependency; #ifdef CONFIGURABLE_TYPE_SUPPORT // name of remote rule dependency (will be resolved to set ruleDependency) TCFG_STRING dependencyRuleName; #endif #endif }; // TPropertyDefinition // enumeration modes typedef enum { profm_custom, // custom defined profile/subprofile profm_vtimezones, // VTIMEZONE profile(s), expands to a VTIMEZONE for every time zone referenced by convmode TZID fields numProfileModes } TProfileModes; // Profile level definition class TProfileDefinition : noncopyable { public: // constructor/destructor TProfileDefinition( TProfileDefinition *aParentProfileP, // parent profile const char *aProfileName, // name sInt16 aNumMandatory, bool aShowInCTCapIfSelectedOnly, TProfileModes aProfileMode, TMimeDirMode aModeDep ); ~TProfileDefinition(); // tools TConversionDef *setConvDef(sInt16 aFieldId=FID_NOT_SUPPORTED,sInt16 aConvMode=0,char aCombSep=0) { return levelConvdef.setConvDef(aFieldId,aConvMode,aCombSep); }; TProfileDefinition *addSubProfile( const char *aProfileName, // name sInt16 aNumMandatory, bool aShowInCTCapIfSelectedOnly, TProfileModes aProfileMode = profm_custom, TMimeDirMode aModeDep = numMimeModes ); TPropertyDefinition *addProperty( const char *aName, // name sInt16 aNumValues, // number of values, NUMVAL_LIST/NUMVAL_REP_LIST if it is a value list bool aMandatory, // mandatory bool aShowInCTCap, // show in CTCap bool aSuppressEmpty, // suppress empty ones on send uInt16 aDelayedProcessing=0, // delayed processing when parsed, 0=immediate processing, 1..n=delayed char aValuesep=';', // value separator uInt16 aPropertyGroupID=0, // property group ID (alternatives for same-named properties should have same ID>0) bool aCanFilter=false, // can be filtered -> show in filter cap TMimeDirMode aModeDep=numMimeModes, // property valid only for specific MIME mode char aAltValuesep=0, // no alternate separator sInt16 aGroupFieldID=FID_NOT_SUPPORTED, // no group field bool aAllowFoldAtSep=false // do not fold at separators when it would insert extra spaces ); void usePropertiesOf(TProfileDefinition *aProfile); TPropertyDefinition *getPropertyDef(const char *aPropName); sInt16 getPropertyMainFid(const char *aPropName, uInt16 aIndex); TProfileDefinition *findProfile(const char *aNam); // next in chain TProfileDefinition *next; // parent profile TProfileDefinition *parentProfile; // NULL if root // Profile Level name TCFG_STRING levelName; // Level existence control field (affected/tested when level entered) // NOTE: levelConvdef.enumdefs is used specially: it points to a SINGLE entry, // not an array (no terminator!!). This entry contains IN THE enumval // field (NOT enumtext!!!) the value to be stored in the field // indicated by fieldid when this level is entered with BEGIN TConversionDef levelConvdef; // this subprofile (and related properties and sub-sub-profiles) // is shown in devInf only if it is explictly selected or if all are selected bool shownIfSelectedOnly; // number of mandatory properties in this level sInt16 numMandatoryProperties; // property list, NULL if none TPropertyDefinition *propertyDefs; // sublevel list, NULL if none TProfileDefinition *subLevels; // next repeat ID for this (root) profile sInt16 nextRepID; // profile mode (custom profile or predefined profile like vTIMEZONE) TProfileModes profileMode; // dependency on MIME-dir mode TMimeDirMode modeDependency; private: bool ownsProps; }; // TProfileDefinition // MIME profile definition config class TMIMEProfileConfig : public TProfileConfig { typedef TProfileConfig inherited; public: TMIMEProfileConfig(const char* aName, TConfigElement *aParentElement); virtual ~TMIMEProfileConfig(); // handler factory virtual TProfileHandler *newProfileHandler(TMultiFieldItemType *aItemTypeP); // properties // - root profile TProfileDefinition *fRootProfileP; // - options bool fUnfloatFloating; // set if floating timestamps should always be unfloated into item time zone TVTimeZoneGenMode fVTimeZoneGenMode; // how outgoing VTIMEZONE records should be generated TTzIdGenMode fTzIdGenMode; // what type of TZIDs should be generated protected: // check config elements #ifdef CONFIGURABLE_TYPE_SUPPORT virtual bool localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine); public: virtual void localResolve(bool aLastPass); protected: virtual void nestedElementEnd(void); // parse conversion mode bool getConvMode(cAppCharP aText, sInt16 &aConvMode); #endif virtual void clear(); private: #ifdef CONFIGURABLE_TYPE_SUPPORT // parsing help bool getConvAttrs(const char **aAttributes, sInt16 &aFid, sInt16 &aConvMode, char &aCombSep); bool getMask(const char **aAttributes, const char *aName, TParameterDefinition *aParamP, TNameExtIDMap &aMask); bool processPosition(TParameterDefinition *aParamP, const char **aAttributes); // parsing vars TProfileDefinition *fOpenProfile; // profile being parsed TPropertyDefinition *fOpenProperty; // property being parsed TParameterDefinition *fOpenParameter; // parameter being parsed TConversionDef *fOpenConvDef; // conversion definition being parsed TPropertyDefinition *fLastProperty; // last property added in profile (to build groups) uInt16 fPropertyGroupID; // property grouping #endif }; // TMIMEProfileConfig // delayed property parsing info typedef struct { uInt16 delaylevel; const char *start; const char *groupname; size_t groupnameLen; const TPropertyDefinition *propDefP; } TDelayedPropParseParams; // delayed property parsing list typedef std::list TDelayedParsingPropsList; // used time context set typedef std::set TTCtxSet; // parsed TZID map typedef std::map TParsedTzidSet; class TMimeDirProfileHandler : public TProfileHandler { typedef TProfileHandler inherited; public: // constructor TMimeDirProfileHandler( TMIMEProfileConfig *aMIMEProfileCfgP, TMultiFieldItemType *aItemTypeP ); // destructor virtual ~TMimeDirProfileHandler(); #ifdef OBJECT_FILTERING // filtering // - get field index of given filter expression identifier. virtual sInt16 getFilterIdentifierFieldIndex(const char *aIdentifier, uInt16 aIndex); // - add keywords and property names to filterCap virtual void addFilterCapPropsAndKeywords(SmlPcdataListPtr_t &aFilterKeywords, SmlPcdataListPtr_t &aFilterProps, TTypeVariantDescriptor aVariantDescriptor, TSyncItemType *aItemTypeP); #endif // - obtain property list for type, returns NULL if none available virtual SmlDevInfCTDataPropListPtr_t newCTDataPropList(TTypeVariantDescriptor aVariantDescriptor, TSyncItemType *aItemTypeP); // - Analyze CTCap part of devInf virtual bool analyzeCTCap(SmlDevInfCTCapPtr_t aCTCapP, TSyncItemType *aItemTypeP); // set profile options // - mode (for those profiles that have more than one, like MIME-DIR's old/standard) virtual void setProfileMode(sInt32 aMode); #ifndef NO_REMOTE_RULES // set specific remote rule and activate the behavior defined by it; // to be used only in script context, inside a session the session // properties are used instead virtual void setRemoteRule(const string &aRemoteRuleName); #endif // generate Text Data (includes header and footer) virtual void generateText(TMultiFieldItem &aItem, string &aString); // parse Data item (includes header and footer) virtual bool parseText(const char *aText, stringSize aTextSize, TMultiFieldItem &aItem); // scan for specific property value string (for version check) bool parseForProperty(const char *aText, const char *aPropName, string &aString); bool parseForProperty(SmlItemPtr_t aItemP, const char *aPropName, string &aString); // get profile definition TProfileDefinition *getProfileDefinition(void) { return fProfileDefinitionP; }; private: // Settable options // - profile mode sInt32 fProfileMode; // - derived from profile mode: MIME dir mode TMimeDirMode fMimeDirMode; // - ability of receiver to handle UTC bool fReceiverCanHandleUTC; // - how end dates should be formatted bool fVCal10EnddatesSameDay; // - empty property policy bool fDontSendEmptyProperties; // - default output charset TCharSets fDefaultOutCharset; // - default input interpretation charset TCharSets fDefaultInCharset; // - user time context timecontext_t fReceiverTimeContext; // - set if any 8-bit content must be encoded QUOTED-PRINTABLE bool fDoQuote8BitContent; // - set if no line folding should be done bool fDoNotFoldContent; // - time handling bool fTreatRemoteTimeAsLocal; bool fTreatRemoteTimeAsUTC; #ifndef NO_REMOTE_RULES // - dependency on certain remote rule(s) TRemoteRulesList fActiveRemoteRules; // list of active remote rules that might influence behaviour bool isActiveRule(TRemoteRuleConfig *aRuleP); // check if given rule is among the active ones #endif // vars TMIMEProfileConfig *fProfileCfgP; // the MIME-DIR profile config element // property definitions TProfileDefinition *fProfileDefinitionP; // BEGIN/END nesting sInt16 fBeginEndNesting; // time zone management bool fHasExplicitTZ; // parsed or generated explicit time zone for entire item (CONVMODE_TZ) timecontext_t fItemTimeContext; // time zone context for entire item, is copy of session's user context as long as fHasExplicitTZ not set timecontext_t fPropTZIDtctx; // property level time zone context - is set whenever a CONVMODE_TZID is successfully parsed or generated, reset at property start TTCtxSet fUsedTCtxSet; // all time contexts used in this item (for generating) lineartime_t fEarliestTZDate; // earliest date/time generated using a time context from fUsedTCtxSet lineartime_t fLatestTZDate; // latest date/time generated using a time context from fUsedTCtxSet TParsedTzidSet fParsedTzidSet; // all time contexts parsed in from VTIMEZONE // delayed generation of VTIMEZONE subprofile (after all TZID are collected in fUserTctxSet) const TProfileDefinition *fVTimeZonePendingProfileP; // the profile definition, NULL if none size_t fVTimeZoneInsertPos; // where to insert VTIMEZONE // delayed processing TDelayedParsingPropsList fDelayedProps; // list of properties to parse out-of-order // helper void getOptionsFromDatastore(void); protected: // generate MIME-DIR from item into string object void generateMimeDir(TMultiFieldItem &aItem, string &aString); // parse MIME-DIR from specified string into item bool parseMimeDir(const char *aText, TMultiFieldItem &aItem); // special field translations (to be overridden in derived classes) // - returns the size of the field block (how many fids in sequence) related // to a given convdef (for multi-field conversion modes such as CONVMODE_RRULE virtual sInt16 fieldBlockSize(const TConversionDef &aConvDef); // - field value to string for further MIME-DIR generation processing virtual bool fieldToMIMEString( TMultiFieldItem &aItem, // the item where data goes to sInt16 aFid, // the field ID (can be NULL for special conversion modes) sInt16 aArrIndex, // the repeat offset to handle array fields const TConversionDef *aConvDefP, // the conversion definition record string &aString // output string ); // - single MIME-DIR value string to field (to be overridden in derived classes) virtual bool MIMEStringToField( const char *aText, // the value text to assign or add to the field const TConversionDef *aConvDefP, // the conversion definition record TMultiFieldItem &aItem, // the item where data goes to sInt16 aFid, // the field ID (can be NULL for special conversion modes) sInt16 aArrIndex // the repeat offset to handle array fields ); private: // helpers for CTCap/FilterCap // - set field options (enabled, maxsize, maxoccur, notruncate) of fields related to aPropP property in profiles recursively // or (if aPropP is NULL), enable fields of all mandatory properties void setfieldoptions( const SmlDevInfCTDataPtr_t aPropP, // property to enable fields for, NULL if all mandatory properties should be enabled const TProfileDefinition *aProfileP, TMimeDirItemType *aItemTypeP ); // - set level bool setLevelOptions(const char *aLevelName, bool aEnable, TMimeDirItemType *aItemTypeP); // - add level description to CTCap list void enumerateLevels(const TProfileDefinition *aProfileP, SmlPcdataListPtr_t *&aPcdataListPP, const TProfileDefinition *aSelectedProfileP, TMimeDirItemType *aItemTypeP); // - add property description to CTCap list void enumerateProperties(const TProfileDefinition *aProfileP, SmlDevInfCTDataPropListPtr_t *&aPropListPP, const TProfileDefinition *aSelectedProfileP, TMimeDirItemType *aItemTypeP); // - enumerate filter properties void enumeratePropFilters(const TProfileDefinition *aProfileP, SmlPcdataListPtr_t &aFilterProps, const TProfileDefinition *aSelectedProfileP, TMimeDirItemType *aItemTypeP); // - check mode bool mimeModeMatch(TMimeDirMode aMimeMode); // helpers for generateMimeDir() // - generate parameter or property value(list), // returns: 2 if value found, 1 if no value (but field supported), 0 if field not supported sInt16 generateValue( TMultiFieldItem &aItem, // the item where data comes from const TConversionDef *aConvDefP, sInt16 aBaseOffset, // basic fid offset to use sInt16 aArrayOffset, // additional offset to use, or array index in case of array field string &aString, // where value is ADDED char aSeparator, TMimeDirMode aMimeMode, // MIME mode (older or newer vXXX format compatibility) bool aParamValue, // set if generating parameter value (different escaping rules, i.e. ";" and ":" must be escaped) bool aStructured, // set if value consists of multiple values (needs ";" escaping) bool aCommaEscape, // set if "," content escaping is needed (for values in valuelists like TYPE=TEL,WORK etc.) TEncodingTypes &aEncoding, // modified if special value encoding is required bool &aNonASCII, // set if any non standard 7bit ASCII-char is contained char aFirstChar, // will be appended before value if there is any value sInt32 &aNumNonSpcs, // how many non-spaces are already in the value bool aFoldAtSeparator, // if true, even in mimo_old folding may appear at value separators (adding an extra space - which is ok for EXDATE and similar) bool aEscapeOnlyLF // if true, only linefeeds are escaped as \n, but nothing else (not even \ itself) ); // - recursive expansion of properties void expandProperty( TMultiFieldItem &aItem, // the item where data comes from string &aString, // the string to add properties to const char *aPrefix, // the prefix (property name) const TPropertyDefinition *aPropP, // the property to generate (all instances) TMimeDirMode aMimeMode // MIME mode (older or newer vXXX format compatibility) ); // - generate single property (except for valuelist-type properties) sInt16 generateProperty( TMultiFieldItem &aItem, // the item where data comes from string &aString, // the string to add properties to const char *aPrefix, // the prefix (property name) const TPropertyDefinition *aPropP, // the property to generate (single instance) sInt16 aBaseOffset, // field ID offset to be used sInt16 aRepeatOffset, // additional repeat offset / array index TMimeDirMode aMimeMode, // MIME mode (older or newer vXXX format compatibility) bool aSuppressEmpty, // if set, a property with only empty values will not be generated TPropNameExtension *aPropNameExt=NULL // propname extension for generating musthave param values and maxrep/repinc for valuelists ); // - generate parameters for one property instance // returns true if parameters with shownonempty=true were generated bool generateParams( TMultiFieldItem &aItem, // the item where data comes from string &aString, // the string to add parameters to const TPropertyDefinition *aPropP, // the property to generate (all instances) TMimeDirMode aMimeMode, // MIME mode (older or newer vXXX format compatibility) sInt16 aBaseOffset, sInt16 aRepOffset, TPropNameExtension *aPropNameExt, // propname extension for generating musthave param values sInt32 &aNumNonSpcs // how many non-spaces are already in the value ); // - recursively generate levels void generateLevels( TMultiFieldItem &aItem, string &aString, const TProfileDefinition *aProfileP ); // - parse parameter or property value(list), returns false if no value(list) bool parseValue( const string &aText, // string to parse as value (could be binary content) const TConversionDef *aConvDefP, sInt16 aBaseOffset, // base offset sInt16 aRepOffset, // repeat offset, adds to aBaseOffset for non-array fields, is array index for array fileds TMultiFieldItem &aItem, // the item where data goes to bool &aNotEmpty, // is set true (but never set false) if property contained any (non-positional) values char aSeparator, // separator between values that consist of a list of enums etc. (more common for params than for values) TMimeDirMode aMimeMode, // MIME mode (older or newer vXXX format compatibility) bool aParamValue, // set if parsing parameter value (different escaping rules) bool aStructured, // set if value consists of multiple values (has semicolon content escaping) bool aOnlyDeEscLF // set if de-escaping only for \n -> LF, but all visible char escapes should be left intact ); // - parse given property bool parseProperty( cAppCharP &aText, // where to start interpreting property, will be updated past end of poperty TMultiFieldItem &aItem, // item to store data into const TPropertyDefinition *aPropP, // the property definition sInt16 *aRepArray, // array[repeatID], holding current repetition COUNT for a certain nameExts entry sInt16 aRepArraySize, // size of array (for security) TMimeDirMode aMimeMode, // MIME mode (older or newer vXXX format compatibility) cAppCharP aGroupName, // property group ("a" in "a.TEL:131723612") size_t aGroupNameLen, cAppCharP aFullPropName, // entire property name (excluding group) - might be needed in case of wildcard property match size_t aFullNameLen ); // parse MIME-DIR level from specified string into item bool parseLevels( const char *&aText, TMultiFieldItem &aItem, const TProfileDefinition *aProfileP, bool aRootLevel ); #ifndef NO_REMOTE_RULES // helper for setRemoteRule(): add one specific remote rule and activate the behavior defined by it void activateRemoteRule(TRemoteRuleConfig *aRuleP); #endif }; // TMimeDirProfileHandler // Utility functions // ----------------- /// @brief checks two timestamps if they represent an all-day event /// @param[in] aStart start time /// @param[in] aEnd end time /// @return 0 if not allday, x=1..n if allday (spanning x days) by one of the /// following criteria: /// - both start and end at midnight of the same day (= 1 day) /// - both start and end at midnight of different days (= 1..n days) /// - start at midnight and end between 23:59:00 and 23:59:59 of /// same or different days (= 1..n days) uInt16 AlldayCount(lineartime_t aStart, lineartime_t aEnd); /// @brief checks two timestamps if they represent an all-day event /// @param[in] aStartFldP start time field /// @param[in] aEndFldP end time field /// @param[in] aTimecontext context to use to check allday criteria for all non-floating timestamps /// or UTC timestamps only (if aContextForUTC is set). /// @param[in] aContextForUTC if set, context is only applied for UTC timestamps, other non-floatings are checked as-is /// @return 0 if not allday, x=1..n if allday (spanning x days) uInt16 AlldayCount(TItemField *aStartFldP, TItemField *aEndFldP, timecontext_t aTimecontext, bool aContextForUTC); /// @brief makes two timestamps represent an all-day event /// @param[in/out] aStart start time within the first day, will be set to midnight (00:00:00) /// @param[in/out] aEnd end time within the last day or at midnight of the next day, /// will be set to midnight of the next day /// @param[in] aDays if>0, this is used to calculate the aEnd timestamp (aEnd input is /// ignored then) void MakeAllday(lineartime_t &aStart, lineartime_t &aEnd, sInt16 aDays=0); /// @brief makes two timestamp fields represent an all-day event /// @param[in/out] aStartFldP start time within the first day, will be set to dateonly /// @param[in/out] aEndFldP end time within the last day or at midnight of the next day, will be set to dateonly of the next day /// @param[in] aTimecontext context to calculate day boundaries in /// @param[in] aDays if>0, this is used to calculate the aEnd timestamp (aEnd input is /// ignored then) /// @note fields will be made floating and dateonly void MakeAllday(TItemField *aStartFldP, TItemField *aEndFldP, timecontext_t aTimecontext, sInt16 aDays=0); } // namespace sysync #endif // MimeDirProfile_H // eof libsynthesis-3.4.0.47.1/src/sysync/multifielditem.cpp000077500000000000000000001624101226375725500225130ustar00rootroot00000000000000/* * File: MultiFieldItem.cpp * * Author: Lukas Zeller (luz@plan44.ch) * * TMultiFieldItem * Item consisting of multiple data fields (TItemField objects) * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * 2001-08-08 : luz : created * */ // includes #include "prefix_file.h" #include "sysync.h" #include "multifielditem.h" #include "multifielditemtype.h" using namespace sysync; namespace sysync { // Config // ====== TFieldListConfig::TFieldListConfig(const char* aName, TConfigElement *aParentElement) : TConfigElement(aName,aParentElement) { clear(); } // TFieldListConfig::TFieldListConfig TFieldListConfig::~TFieldListConfig() { clear(); } // TFieldListConfig::~TFieldListConfig // init defaults void TFieldListConfig::clear(void) { // init defaults fAgeSortable=false; fFields.clear(); #ifdef HARDCODED_TYPE_SUPPORT fFieldListTemplateP=NULL; #endif // clear inherited inherited::clear(); } // TFieldListConfig::clear #ifdef CONFIGURABLE_TYPE_SUPPORT // config element parsing bool TFieldListConfig::localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine) { // - fieldlist entry // if (strucmp(aElementName,"field")==0) { // may not contain anything expectEmpty(); // check attributes const char *nam = getAttr(aAttributes,"name"); const char *type = getAttr(aAttributes,"type"); const char *rel = getAttr(aAttributes,"compare"); if (!(nam && *nam && type && rel)) return fail("'field' must have 'name', 'type' and 'compare' attributes"); // parse enums sInt16 ty; if (!StrToEnum(ItemFieldTypeNames,numFieldTypes,ty,type)) return fail("Unknown 'type' attribute: '%s'",type); sInt16 eqrel; if (!StrToEnum(compareRelevanceNames,numEQmodes,eqrel,rel)) return fail("Unknown 'compare' attribute: '%s'",rel); // set defaults bool agerelevant=false; // not age relevant by default sInt16 mergemode=mem_none; // no merge by default // get optional attributes if (!getAttrBool(aAttributes,"age",agerelevant,true)) return fail("Bad boolean value"); #ifdef ARRAYFIELD_SUPPORT bool array=false; // not an array if (!getAttrBool(aAttributes,"array",array,true)) return fail("Bad boolean value"); #endif const char *p = getAttr(aAttributes,"merge"); if (p) { // sort out special cases if (strucmp(p,"no")==0) mergemode=mem_none; else if (strucmp(p,"fillempty")==0) mergemode=mem_fillempty; else if (strucmp(p,"addunassigned")==0) mergemode=mem_addunassigned; else if (strucmp(p,"append")==0) mergemode=mem_concat; else if (strucmp(p,"lines")==0) mergemode='\n'; else if (strlen(p)==1) mergemode=*p; // single char is merge char else return fail("Invalid value '%s' for 'merge' attribute",p); } // now add new field specification TFieldDefinition fielddef; // prepare template element fielddef.type=(TItemFieldTypes)ty; #ifdef ARRAYFIELD_SUPPORT fielddef.array = array; #endif TCFG_ASSIGN(fielddef.fieldname,nam); fielddef.eqRelevant=(TEqualityMode)eqrel; fielddef.ageRelevant=agerelevant; fAgeSortable=fAgeSortable || fielddef.ageRelevant; // if at least one field is age-relevant, we can sort items fielddef.mergeMode=mergemode; // copy into array fFields.push_back(fielddef); } // - none known here else return inherited::localStartElement(aElementName,aAttributes,aLine); // ok return true; } // TFieldListConfig::localStartElement // resolve void TFieldListConfig::localResolve(bool aLastPass) { if (aLastPass) { // check for required settings if (fFields.size()==0) SYSYNC_THROW(TSyncException("fieldlist must contain at least one field")); } // resolve inherited inherited::localResolve(aLastPass); } // TFieldListConfig::localResolve #endif // get index of a field sInt16 TFieldListConfig::fieldIndex(const char *aName, size_t aLen) { TFieldDefinitionList::iterator pos; sInt16 n; for (n=0,pos=fFields.begin(); pos!=fFields.end(); ++n,pos++) { if (strucmp(aName,pos->TCFG_CSTR(fieldname),aLen)==0) { return n; // return field ID } } return VARIDX_UNDEFINED; // not found } // TFieldListConfig::fieldIndex // profile handler TProfileHandler::TProfileHandler(TProfileConfig *aProfileCfgP, TMultiFieldItemType *aItemTypeP) { // save profile config pointer fItemTypeP = aItemTypeP; // no related datastore yet fRelatedDatastoreP = NULL; } // TProfileHandler::TProfileHandler TProfileHandler::~TProfileHandler() { // nop for now } // TProfileHandler::~TProfileHandler // - get session pointer TSyncSession *TProfileHandler::getSession(void) { return fItemTypeP ? fItemTypeP->getSession() : NULL; } // TProfileHandler::getSession // - get session zones pointer GZones *TProfileHandler::getSessionZones(void) { return fItemTypeP ? fItemTypeP->getSessionZones() : NULL; } // TProfileHandler::getSessionZones #ifdef SYDEBUG TDebugLogger *TProfileHandler::getDbgLogger(void) { // commands log to session's logger return fItemTypeP ? fItemTypeP->getDbgLogger() : NULL; } // TProfileHandler::getDbgLogger uInt32 TProfileHandler::getDbgMask(void) { if (!fItemTypeP) return 0; // no item type, no debug return fItemTypeP->getDbgMask(); } // TProfileHandler::getDbgMask #endif // - check availability (depends on item "supported" flags only in SyncML datastore context) bool TProfileHandler::isFieldAvailable(TMultiFieldItem &aItem, sInt16 aFieldIndex) { if (fRelatedDatastoreP) { // in datastore/SyncML context, only fields supported on both sides are considered "available" return aItem.isAvailable(aFieldIndex); } else { // in non-datastore context, all fields are considered available, as long as // the field index is in range TMultiFieldItemType *mfitP = aItem.getItemType(); return mfitP && mfitP->isFieldIndexValid(aFieldIndex); } } // TProfileHandler::isFieldAvailable // Profile config root element TProfileConfig::TProfileConfig(const char* aName, TConfigElement *aParentElement) : TConfigElement(aName,aParentElement) { clear(); } // TProfileConfig::TProfileConfig TProfileConfig::~TProfileConfig() { clear(); } // TProfileConfig::~TProfileConfig // init defaults void TProfileConfig::clear(void) { // init defaults fFieldListP=NULL; // no field list linked // clear inherited inherited::clear(); } // TProfileConfig::clear #ifdef HARDCODED_TYPE_SUPPORT // read hardcoded fieldlist config void TFieldListConfig::readFieldListTemplate(const TFieldDefinitionsTemplate *aTemplateP) { if (!aTemplateP) return; // save the link to the template as well (we'll need it for maxsize etc. later) fFieldListTemplateP=aTemplateP; fFields.clear(); // copy values fAgeSortable=false; TFieldDefinition fielddef; for (sInt16 i=0; inumFields; i++) { const TFieldDefinitionTemplate *afieldP= &(aTemplateP->fieldDefs[i]); // prepare template element fielddef.type=afieldP->type; #ifdef ARRAYFIELD_SUPPORT fielddef.array = afieldP->array; #endif TCFG_ASSIGN(fielddef.fieldname,afieldP->fieldname); fielddef.eqRelevant=afieldP->eqRelevant; fielddef.ageRelevant=afieldP->ageRelevant; fAgeSortable=fAgeSortable || fielddef.ageRelevant; // if at least one field is age-relevant, we can sort fielddef.mergeMode=afieldP->mergeMode; // copy into array fFields.push_back(fielddef); } } // TFieldListConfig::readFieldListTemplate #endif TMultiFieldDatatypesConfig::TMultiFieldDatatypesConfig(TConfigElement *aParentElement) : TDatatypesConfig("datatypes",aParentElement) { clear(); } // TMultiFieldDatatypesConfig::TMultiFieldDatatypesConfig TMultiFieldDatatypesConfig::~TMultiFieldDatatypesConfig() { // make sure we don't re-build types (createHardcodedTypes() in clear()) // so we call internalClear() here! internalClear(); } // TMultiFieldDatatypesConfig::~TMultiFieldDatatypesConfig // init defaults void TMultiFieldDatatypesConfig::clear(void) { // remove internals internalClear(); // Now datatypes registry is really empty #ifdef HARDCODED_TYPE_SUPPORT // - add hard-coded default type information (if any) static_cast(getRootElement())->createHardcodedTypes(this); #endif } // TMultiFieldDatatypesConfig::clear // init defaults void TMultiFieldDatatypesConfig::internalClear(void) { // remove fieldlists TFieldListsList::iterator pos1; for(pos1=fFieldLists.begin();pos1!=fFieldLists.end();pos1++) delete *pos1; fFieldLists.clear(); // remove profiles TProfilesList::iterator pos2; for(pos2=fProfiles.begin();pos2!=fProfiles.end();pos2++) delete *pos2; fProfiles.clear(); // clear inherited inherited::clear(); } // TMultiFieldDatatypesConfig::internalClear // get a field list by name TFieldListConfig *TMultiFieldDatatypesConfig::getFieldList(const char *aName) { TFieldListsList::iterator pos; for(pos=fFieldLists.begin();pos!=fFieldLists.end();pos++) { if (strucmp((*pos)->getName(),aName)==0) { // found return *pos; } } return NULL; // not found } // TMultiFieldDatatypesConfig::getFieldList // get a profile by name TProfileConfig *TMultiFieldDatatypesConfig::getProfile(const char *aName) { TProfilesList::iterator pos; for(pos=fProfiles.begin();pos!=fProfiles.end();pos++) { if (strucmp((*pos)->getName(),aName)==0) { // found return *pos; } } return NULL; // not found } // TMultiFieldDatatypesConfig::getProfile #ifdef CONFIGURABLE_TYPE_SUPPORT // config element parsing bool TMultiFieldDatatypesConfig::localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine) { // checking the elements // - field lists or profiles can appear at this level bool newFieldList=false; TProfileConfig *newProfileP=NULL; TFieldListConfig *flP = NULL; // in case it is a field list or a profile - check for name const char* nam = getAttr(aAttributes,"name"); // now check if fieldlist or profile if (strucmp(aElementName,"fieldlist")==0) { newFieldList=true; } // the xml tag itself is used as the profile's typename (historical reasons/compatibility with existing config) else if ((newProfileP=getSyncAppBase()->getRootConfig()->newProfileConfig(nam,aElementName,this))!=NULL) { const char* flnam = getAttr(aAttributes,"fieldlist"); if (!flnam) return fail("%s is missing 'fieldlist' attribute",aElementName); else { flP = getFieldList(flnam); if (!flP) return fail("fieldlist '%s' unknown in %s",flnam,aElementName); } } // - tag not known here else return TDatatypesConfig::localStartElement(aElementName,aAttributes,aLine); // known tag, check if we need further processing if (newFieldList || newProfileP) { if (!nam) return fail("%s is missing 'name' attribute",aElementName); // create new named field list or use already created profile if (newFieldList) { // new field list TFieldListConfig *fieldlistcfgP = new TFieldListConfig(nam,this); fFieldLists.push_back(fieldlistcfgP); // save in list expectChildParsing(*fieldlistcfgP); // let element handle parsing } else { // new profile newProfileP->fFieldListP=flP; // set field list for profile fProfiles.push_back(newProfileP); // save in list expectChildParsing(*newProfileP); // let element handle parsing } } // ok return true; } // TMultiFieldDatatypesConfig::localStartElement // resolve void TMultiFieldDatatypesConfig::localResolve(bool aLastPass) { // resolve profiles TProfilesList::iterator pos1; for(pos1=fProfiles.begin();pos1!=fProfiles.end();pos1++) { (*pos1)->localResolve(aLastPass); } // resolve field lists TFieldListsList::iterator pos2; for(pos2=fFieldLists.begin();pos2!=fFieldLists.end();pos2++) { (*pos2)->localResolve(aLastPass); } // resolve inherited inherited::localResolve(aLastPass); } // TMultiFieldDatatypesConfig::localResolve #endif /* * Implementation of TMultiFieldItem */ /* public TMultiFieldItem members */ TMultiFieldItem::TMultiFieldItem( TMultiFieldItemType *aItemTypeP, // owner's (=source) type TMultiFieldItemType *aTargetItemTypeP // target type (for optimization) ) : TSyncItem(aItemTypeP) { // save types fItemTypeP = aItemTypeP; // owner (source) type fTargetItemTypeP = aTargetItemTypeP; // target (destination) type // copy field definitions pointer for fast access fFieldDefinitionsP = fItemTypeP->getFieldDefinitions(); if (!fFieldDefinitionsP) SYSYNC_THROW(TSyncException(DEBUGTEXT("MultiFieldItem without FieldDefinitions","mfi3"))); // test if target has same field defs if (fTargetItemTypeP->getFieldDefinitions()!=fFieldDefinitionsP) SYSYNC_THROW(TSyncException(DEBUGTEXT("MultiFieldItem with non-matching target field definitions","mfi1"))); // create fields array fFieldsP = new TItemFieldP[fFieldDefinitionsP->numFields()]; // - init it with null pointers for (sInt16 i=0; inumFields(); i++) fFieldsP[i]=NULL; } // TMultiFieldItem::TMultiFieldItem TMultiFieldItem::~TMultiFieldItem() { // remove fields cleardata(); // remove fields list delete[] fFieldsP; } // TMultiFieldItem::~TMultiFieldItem // remove all data from item void TMultiFieldItem::cleardata(void) { if (fFieldDefinitionsP) { for (sInt16 i=0; inumFields(); i++) { if (fFieldsP[i]) { delete fFieldsP[i]; // delete field object fFieldsP[i]=NULL; } } } } // TMultiFieldItem::cleardata #if defined(CHECKSUM_CHANGELOG) && !defined(RECORDHASH_FROM_DBAPI) // changelog support: calculate CRC over contents uInt16 TMultiFieldItem::getDataCRC(uInt16 crc, bool aEQRelevantOnly) { // iterate over all fields if (fFieldDefinitionsP) { for (sInt16 i=0; inumFields(); i++) { if (!aEQRelevantOnly || fFieldDefinitionsP->fFields[i].eqRelevant!=eqm_none) { if (fFieldsP[i]) { crc=fFieldsP[i]->getDataCRC(crc); } } } } return crc; } // TMultiFieldItem::getDataCRC #endif // adjust fid and repeat offset to access array element if // base fid is an array field or to offset fid accordingly // if based fid is NOT an array field // - returns adjusted aFid and aIndex ready to be used with getArrayField() // - returns true if aFid IS an array field bool TMultiFieldItem::adjustFidAndIndex(sInt16 &aFid, sInt16 &aIndex) { bool arrfield; #ifdef ARRAYFIELD_SUPPORT // fid is offset repoffset only if not an array field arrfield=true; // check for array field first TItemField *fldP = getField(aFid); if (fldP) { if (!(fldP->isArray())) { // no array field arrfield=false; aFid += aIndex; // use array offset as additional field ID offset aIndex=0; // no array index } } else { // Note: if field does not exist, do not apply offset, but don't report array field either! arrfield = false; } #else // without array support, fid is always offset by rep offset aFid += aIndex; aIndex=0; // no array index arrfield=false; #endif // return true if this is really an array field return arrfield; } // adjustFidAndIndex // return specified leaf field of array field or regular field // depending if aFid addresses an array or not. // (This is a shortcut method to access fields specified by a base fid and a repeat) TItemField *TMultiFieldItem::getArrayFieldAdjusted(sInt16 aFid, sInt16 aIndex, bool aExistingOnly) { adjustFidAndIndex(aFid,aIndex); return getArrayField(aFid, aIndex, aExistingOnly); } // TMultiFieldItem::getArrayFieldAdjusted // return specified leaf field of array field TItemField *TMultiFieldItem::getArrayField(sInt16 aFid, sInt16 aIndex, bool aExistingOnly) { #ifdef ARRAYFIELD_SUPPORT TItemField *fiP = getField(aFid); if (!fiP) return NULL; return fiP->getArrayField(aIndex,aExistingOnly); #else // without array support, we can only access index==0 if (aIndex>0) return NULL; // other indices don't exist return getField(aFid); #endif } // TMultiFieldItem::getArrayField // get field by name (returns NULL if not known, creates if known but not existing yet) TItemField *TMultiFieldItem::getArrayField(const char *aFieldName, sInt16 aIndex, bool aExistingOnly) { return getArrayField(fItemTypeP->getFieldIndex(aFieldName),aIndex,aExistingOnly); } // TMultiFieldItem::getArrayField // get field by index (returns NULL if not known, creates if known but not existing yet) TItemField *TMultiFieldItem::getField(sInt16 aFieldIndex) { if (!fItemTypeP->isFieldIndexValid(aFieldIndex)) return NULL; // invalid index TItemField *fiP = fFieldsP[aFieldIndex]; if (!fiP) { // we must create the field first fiP=newItemField( fFieldDefinitionsP->fFields[aFieldIndex].type, getSessionZones() #ifdef ARRAYFIELD_SUPPORT ,fFieldDefinitionsP->fFields[aFieldIndex].array #endif ); // save in array fFieldsP[aFieldIndex] = fiP; } return fiP; } // TMultiFieldItem::getField // find index of field (returns FID_NOT_SUPPORTED if field is not a field of this item) sInt16 TMultiFieldItem::getIndexOfField(const TItemField *aFieldP) { for (sInt16 i=0; inumFields(); i++) { if (fFieldsP[i]==aFieldP) { // found field, return it's index return i; } } return FID_NOT_SUPPORTED; // not found } // TMultiFieldItem::getIndexOfField // get field by name (returns NULL if not known, creates if known but not existing yet) TItemField *TMultiFieldItem::getField(const char *aFieldName) { return getField(fItemTypeP->getFieldIndex(aFieldName)); } // TMultiFieldItem::getField // get field reference (create if not yet created) // throws if bad index TItemField &TMultiFieldItem::getFieldRef(sInt16 aFieldIndex) { TItemField *fiP = getField(aFieldIndex); if (!fiP) SYSYNC_THROW(TSyncException(DEBUGTEXT("getFieldRef with bad index called","mfi2"))); // invalid index return *fiP; } // TMultiFieldItem::getFieldRef // check if field is assigned (exists and has a value) bool const TMultiFieldItem::isAssigned(const char *aFieldName) { return isAssigned(fItemTypeP->getFieldIndex(aFieldName)); } // TMultiFieldItem::isAssigned TMultiFieldItemType *TMultiFieldItem::getLocalItemType(void) { return fItemTypeP && fItemTypeP->isRemoteType() ? fTargetItemTypeP : fItemTypeP; } // TMultiFieldItem::getLocalItemType TMultiFieldItemType *TMultiFieldItem::getRemoteItemType(void) { return fItemTypeP && fItemTypeP->isRemoteType() ? fItemTypeP : fTargetItemTypeP; } // TMultiFieldItem::getRemoteItemType // check if field is assigned (exists and has a value) bool const TMultiFieldItem::isAssigned(sInt16 aFieldIndex) { // check if field object exists at all if (!fItemTypeP->isFieldIndexValid(aFieldIndex)) return false; // invalid index TItemField *fiP = fFieldsP[aFieldIndex]; if (!fiP) return false; // field object does not exist // return if field object is assigned return fiP->isAssigned(); } // TMultiFieldItem::isAssigned // field availability (combined source & target) bool TMultiFieldItem::isAvailable(const char *aFieldName) { return isAvailable(fItemTypeP->getFieldIndex(aFieldName)); } // TMultiFieldItem::isAvailable // field availability (combined source & target) bool TMultiFieldItem::isAvailable(sInt16 aFieldIndex) { if (fItemTypeP && fTargetItemTypeP) { if (!fItemTypeP->isFieldIndexValid(aFieldIndex)) return false; // invalid index return fItemTypeP->getFieldOptions(aFieldIndex)->available && fTargetItemTypeP->getFieldOptions(aFieldIndex)->available; } else return false; // source or target missing, not available } // TMultiFieldItem::isAvailable bool TMultiFieldItem::knowsRemoteFieldOptions(void) { // knows them if either myself or the other side has received devInf // (depends: received item has it in its own type, to be sent one in the target type) return (fItemTypeP && fItemTypeP->hasReceivedFieldOptions()) || (fTargetItemTypeP && fTargetItemTypeP->hasReceivedFieldOptions()); } // TMultiFieldItem::knowsRemoteFieldOptions // make sure that all fields that are available in source and target are // assigned at least an empty value void TMultiFieldItem::assignAvailables(void) { if (fFieldDefinitionsP) { for (sInt16 k=0; knumFields(); k++) { if (isAvailable(k)) { TItemField *fldP=getField(k); // force creation if (fldP) { // make sure it is assigned a "empty" value if (fldP->isUnassigned()) fldP->assignEmpty(); } } } } } // TMultiFieldItem::assignAvailables // cast pointer to same type, returns NULL if incompatible TMultiFieldItem *TMultiFieldItem::castToSameTypeP(TSyncItem *aItemP) { if (aItemP->isBasedOn(ity_multifield)) { TMultiFieldItem *multifielditemP=static_cast (aItemP); // class compatible, now test type compatibility // - field definition list must be the same instance(!) in both items if (fFieldDefinitionsP==multifielditemP->fFieldDefinitionsP) return multifielditemP; else return NULL; } // not even class compatible return NULL; } // TMultiFieldItem::castToSameTypeP // test if comparable (at least for equality) bool TMultiFieldItem::comparable(TSyncItem &aItem) { // test if comparable: other type must be same type of multifield return castToSameTypeP(&aItem)!=NULL; } // TMultiFieldItem::comparable // test if sortable (by age, newer are > than older) bool TMultiFieldItem::sortable(TSyncItem &aItem) { if (!fFieldDefinitionsP->fAgeSortable) return false; // not sortable at all if (comparable(aItem)) { // item is comparable (has same FieldDefinitions) // Now check if all ageRelevant fields are assigned on both sides // Note: we can static-cast here because comparable() has verified aItem's type TMultiFieldItem *multifielditemP=static_cast (&aItem); // search for ageRelevant fields for (sInt16 i=0; inumFields(); i++) { if (fFieldDefinitionsP->fFields[i].ageRelevant) { // check if available for both types if (!( isAssigned(i) && // my own multifielditemP->isAssigned(i) // aItem's )) return false; // missing needed field on one side } } return true; // all ageRelevant fields are assigned in both sides } else return false; // not comparable is not sortable either } // TMultiFieldItem::sortable #ifdef OBJECT_FILTERING // check post-fetch filter bool TMultiFieldItem::postFetchFiltering(TLocalEngineDS *aDatastoreP) { return fItemTypeP->postFetchFiltering(this,aDatastoreP); } // TMultiFieldItem::postFetchFiltering // test if item passes filter bool TMultiFieldItem::testFilter(const char *aFilterString) { // process filter without modifying #ifdef SYDEBUG PDEBUGPRINTFX(DBG_DATA+DBG_FILTER+DBG_HOT,( "Testing filter '%s' against item:", aFilterString )); if (*aFilterString && PDEBUGTEST(DBG_DATA+DBG_FILTER+DBG_USERDATA)) { debugShowItem(DBG_DATA+DBG_FILTER); } #endif bool result=processFilter(false,aFilterString); PDEBUGPRINTFX(DBG_DATA+DBG_FILTER+DBG_HOT,( "Filter test result is %s", result ? "TRUE" : "FALSE" )); // false on syntax error if (*aFilterString) { PDEBUGPRINTFX(DBG_ERROR,("unexpected chars in filter expression: %s",aFilterString)); return false; } return result; } // TMultiFieldItem::testFilter // make item pass filter bool TMultiFieldItem::makePassFilter(const char *aFilterString) { // process filter with making modifications such that item passes filter condition bool result = processFilter(true,aFilterString); // false on syntax error if (*aFilterString) { PDEBUGPRINTFX(DBG_ERROR+DBG_FILTER,("unexpected chars in filter expression: %s",aFilterString)); return false; } return result; } // TMultiFieldItem::makePassFilter // process filter expression bool TMultiFieldItem::processFilter(bool aMakePass, const char *&aPos, const char *aStop, sInt16 aLastOpPrec) { char c=0; const char *st; string str; bool result; sInt16 fid; sInt16 cmpres=0; bool neg; bool assignToMakeTrue; bool specialValue; bool caseinsensitive; TStringField idfield; TItemField *fldP; // determine max length if (aStop==NULL) aStop=aPos+strlen(aPos); // empty expression is true result=true; // process simple term () // Note: do not allow negation to make sure // that TRUE of a comparison always // adds to TRUE of the entire expression neg=false; // not negated // - get first non-space while (aPos<=aStop) { c=*aPos; if (c!=' ') break; aPos++; } // Term starts here, first char is c, aPos points to it // - check subexpression paranthesis if (c=='(') { // boolean term is grouped subexpression, don't stop at logical operation aPos++; result=processFilter(aMakePass,aPos,aStop,0); // dont stop at any logical operator // check if matching paranthesis if (*(aPos++)!=')') { PDEBUGPRINTFX(DBG_ERROR+DBG_FILTER,("Filter expression error (missing \")\") at: %s",--aPos)); //%%% no, don't skip rest, as otherwise caller will not know that filter processing failed!%%% aPos=aStop; // skip rest return false; // always fail } if (neg) result=!result; } else if (c==0) { // empty term, counts as true return result; } else { // must be simple boolean term // - remember start of ident st=aPos; // - search end of ident while (isFilterIdent(c)) c=*(++aPos); // - c/aPos=char after ident, get ident str.assign(st,aPos-st); // - check for subscript index uInt16 subsIndex=0; // no index (index is 1-based in DS 1.2 filter specs) if (c=='[') { // expect numeric index aPos++; // next aPos+=StrToUShort(aPos,subsIndex); if (*aPos!=']') { PDEBUGPRINTFX(DBG_ERROR+DBG_FILTER,("Filter expression error (missing \"]\") at: %s",--aPos)); return false; // syntax error, does not pass } c=*(++aPos); // process next after subscript } // - get field ID for that ident (can be -1 if none found) // - check special idents first if (str=="LUID") { // this is SyncML-TAF Standard // it is also produced by DS 1.2 &LUID; pseudo-identifier if (IS_CLIENT) idfield.setAsString(getLocalID()); else idfield.setAsString(getRemoteID()); fldP=&idfield; } else if (str=="LOCALID") { // this is a Synthesis extension idfield.setAsString(getLocalID()); fldP=&idfield; } #ifdef SYSYNC_SERVER else if (IS_SERVER && str=="GUID") { // this is a Synthesis extension, added for symmetry to LUID idfield.setAsString(getLocalID()); fldP=&idfield; } else if (IS_SERVER && str=="REMOTEID") { // this is a Synthesis extension idfield.setAsString(getRemoteID()); fldP=&idfield; } #endif // SYSYNC_SERVER else { // must be a field if (fItemTypeP) fid=fItemTypeP->getFilterIdentifierFieldIndex(str.c_str(),subsIndex); else fid=VARIDX_UNDEFINED; // none // now get field pointer (or NULL if field not found) fldP = getField(fid); } // - skip spaces while (isspace(c)) c=*(++aPos); // - check for makepass-assignment modifier ":" assignToMakeTrue=c==':'; if (assignToMakeTrue) c=*(++aPos); // - check for special-value modifier "*" specialValue=c=='*'; if (specialValue) c=*(++aPos); // - check for case-insensitive comparison mode caseinsensitive=c=='^'; if (caseinsensitive) c=*(++aPos); // - now find comparison mode // cmpres = expected strcmp-style result: // 0 if equal, 1 if ident > value, -1 if ident < value, aPos++; // consume first char of comparison anyway if (c=='%') { cmpres=2; } // special flag for CONTAINS else if (c=='$') { cmpres=2; neg=!neg; } else if (c=='=') { cmpres=0; } // equal else if (c=='>') { if (*aPos=='=') { aPos++; neg=!neg; cmpres=-1; } // >= is not < else { cmpres=1; } // > } else if (c=='<') { if (*aPos=='>') { aPos++; neg=!neg; cmpres=0; } // <> is not = else if (*aPos=='=') { aPos++; neg=!neg; cmpres=1; } // <= is not > else { cmpres=-1; } // < } // - now read value st=aPos; // should start here // - find end (end of string, closing paranthesis or logical op) while (aPos result of term, negated or not, is always FALSE result=false; } else { if (cmpres==2) { // "contains" // - create a reference field TItemField *valfldP = newItemField(fldP->getElementType(),getSessionZones()); // - assign value as string valfldP->setAsString(str.c_str()); result = fldP->contains(*valfldP,caseinsensitive); // assign to make pass if enabled if (!result && aMakePass && assignToMakeTrue) { if (fldP->isArray()) fldP->append(*valfldP); // just append another element to make it contained else *fldP = *valfldP; // just overwrite value with to-be-contained value result=true; // now passes } delete valfldP; // no longer needed } else { if (specialValue) { if (cmpres!=0) result=false; // can only compare for equal else { if (str=="E") { // empty result = fldP->isEmpty(); } else if (str=="N") { // NULL, unassigned result = fldP->isAssigned(); } if (neg) result=!result; // make empty or unassigned to pass filter (make non-empty is not possible) if (!result && aMakePass && assignToMakeTrue && !neg) { if (str=="E") { fldP->assignEmpty(); } else if (str=="N") { fldP->unAssign(); } result=true; // now passes } } } else { // create a reference field TItemField *valfldP = newItemField(fldP->getElementType(),getSessionZones()); // assign value as string valfldP->setAsString(str.c_str()); // compare fields, then compare result with what was expected result = (fldP->compareWith(*valfldP,caseinsensitive) == cmpres); // negate result if needed if (neg) result=!result; // if field not assigned, comparison is always false if (fldP->isUnassigned()) result=false; // assign to make pass if enabled if (!result && aMakePass && assignToMakeTrue) { (*fldP) = (*valfldP); result=true; // now passes } // now clear again delete valfldP; } } } } // term is now evaluated, show what follows // - check for boolean op chain, aPos points now to possible logical operator do { // - skip spaces c=*aPos; while (c==' ') c=*(++aPos); // - check char at aPos if (c=='&') { // AND if (2<=aLastOpPrec) return result; // evaluation continues in caller (always as long as we don't have higher prec than AND) // skip op aPos++; // next term must be true as well // - return when encountering AND, OR and end of expression // - next term must also be modified to make pass bool termres = processFilter(aMakePass, aPos, aStop, 2); result = result && termres; } else if (c=='|') { // OR if (1<=aLastOpPrec) return result; // evaluation continues in caller // skip op aPos++; // next term must be true only if this one is not true // - return only when encountering AND or // - if first term is already true, next must never be modifed to pass bool termres = processFilter(result ? false : aMakePass, aPos, aStop, 1); result = result || termres; } else { // End of Expression // would be: if (0<=aLastOpPrec) return result; } } while(true); } #endif #ifdef SYSYNC_SERVER // compare function, returns 0 if equal, 1 if this > aItem, -1 if this < aItem sInt16 TMultiFieldItem::compareWith( TSyncItem &aItem, TEqualityMode aEqMode, TLocalEngineDS *aDatastoreP #ifdef SYDEBUG ,bool aDebugShow #endif ) { #ifndef SYDEBUG const aDebugShow = false; #endif sInt16 cmpres; TMultiFieldItem *multifielditemP = castToSameTypeP(&aItem); if (!multifielditemP) { cmpres = SYSYNC_NOT_COMPARABLE; goto exit; } // do the compare if (fItemTypeP) cmpres=fItemTypeP->compareItems(*this,*multifielditemP,aEqMode,aDebugShow,aDatastoreP); else cmpres=standardCompareWith(*multifielditemP,aEqMode,aDebugShow); exit: #ifdef SYDEBUG if (aDebugShow) { OBJDEBUGPRINTFX(getItemType()->getSession(),DBG_DATA,( "Compared [LOC=%s,REM=%s] with [LOC=%s,REM=%s] (eqMode=%hd), cmpres=%hd", getLocalID(), getRemoteID(), aItem.getLocalID(), aItem.getRemoteID(), (sInt16) aEqMode, cmpres )); } #endif return cmpres; } // TMultiFieldItem::compareWith // compare function, returns 0 if equal, 1 if this > aItem, -1 if this < aItem sInt16 TMultiFieldItem::standardCompareWith( TMultiFieldItem &aItem, TEqualityMode aEqMode, bool aDebugShow ) { sInt16 commonfound=0; sInt16 result=0; // default to equal // we should test for comparable() before! if (!comparable(aItem)) { result=SYSYNC_NOT_COMPARABLE; goto exit; } // now compare field-by-field // - equal means equality of all eqRelevant fields (both non-existing is // equality, too) // (but possibly differences in ageRelevant fields) // - larger/smaller means not equal in eqRelevant fields but // older/newer by ageRelevant fields // - SYSYNC_NOT_COMPARABLE means not equal and not ageSortable either if (aEqMode!=eqm_nocompare) { for (sInt16 i=0; inumFields(); i++) { // both fields must be available in their respective ItemType if (!getItemType()->getFieldOptions(i)->available || !aItem.getItemType()->getFieldOptions(i)->available) continue; // not available in both items, do not compare // then test for equality (if relevant in given context) if (fFieldDefinitionsP->fFields[i].eqRelevant>=aEqMode) { // at least one is available and relevant in both items commonfound++; // this is an EQ-relevant field // - get fields TItemField &f1=getFieldRef(i); TItemField &f2=aItem.getFieldRef(i); // - For slowsync and firstsync matching, non-ASSIGNED fields will not // be compared (to allow matching a less-equipped clinet record with its // better equipped server record and vice versa. Example is the S55 // which discards private addresses, old method rendered lots of // duplicates on slow sync if (aEqMode>=eqm_slowsync) { if (f1.isUnassigned() || f2.isUnassigned()) continue; // omit comparing fields where one side is unassigned } // - get assigned status of both fields // BCPPB revealed bad error: isAssigned was not called (forgot ())!!! // %%% Note: I think that isAssigned() is the wrong function here, we will use // !isEmpty(), which returns true for unassigned fields as well as for empty ones //bool a1 = f1.isAssigned(); // assignment status of field in this item //bool a2 = f2.isAssigned(); // assignment status of same field in other item bool a1 = !f1.isEmpty(); // non-empty status of field in this item bool a2 = !f2.isEmpty(); // non-empty status of same field in other item // - if both are unassigned -> equal if (!a1 && !a2) continue; // we are staying equal, test next field // - if one of them is unassigned -> not equal // - if both are assigned, fields must be equal if (!a1 || !a2) { // one not assigned result=SYSYNC_NOT_COMPARABLE; #ifdef SYDEBUG if (aDebugShow) { // not assigned if (!a1) { PDEBUGPRINTFX(DBG_DATA+DBG_MATCH,("- not equal because fid=%hd not assigned/empty in this item",i)); } else if (!a2) { PDEBUGPRINTFX(DBG_DATA+DBG_MATCH,("- not equal because fid=%hd not assigned/empty in other item",i)); } } #endif break; } else if (f1 != f2) { // content not equal #ifdef SYDEBUG string ds; if (aDebugShow) { // assigned but not equal PDEBUGPRINTFX(DBG_DATA+DBG_MATCH,("- not equal because fid=%hd not same in both items:",i)); getField(i)->getAsString(ds); PDEBUGPRINTFX(DBG_DATA+DBG_MATCH+DBG_USERDATA,( "- this item : '%-.1000s'",ds.c_str() )); aItem.getField(i)->getAsString(ds); PDEBUGPRINTFX(DBG_DATA+DBG_MATCH+DBG_USERDATA,( "- other item : '%-.1000s'",ds.c_str() )); PDEBUGPRINTFX(DBG_DATA+DBG_MATCH,( "- thisItem.CompareWith(otherItem) = %hd", getFieldRef(i).compareWith(aItem.getFieldRef(i)) )); } #endif // now check for cut-off situation sInt32 s1=getItemType()->getFieldOptions(i)->maxsize; sInt32 s2=aItem.getItemType()->getFieldOptions(i)->maxsize; // Note: (2002-12-01) do not actually use size, as it will probably not be accurate enough, // but always pass FIELD_OPT_MAXSIZE_UNKNOWN. if (s1!=FIELD_OPT_MAXSIZE_NONE) s1=FIELD_OPT_MAXSIZE_UNKNOWN; if (s2!=FIELD_OPT_MAXSIZE_NONE) s2=FIELD_OPT_MAXSIZE_UNKNOWN; // Now check short versions if (f1.isShortVers(f2,s2) || f2.isShortVers(f1,s1)) { // cutoff detected, counts as equal #ifdef SYDEBUG if (aDebugShow) { PDEBUGPRINTFX(DBG_DATA+DBG_MATCH,( "- Cutoff detected, field considered equal, maxsize(thisitem)=%ld, maxsize(otheritem)=%ld", (long)s1,(long)s2 )); } #endif } else { // no cutoff, not equal result=SYSYNC_NOT_COMPARABLE; break; } } // else if not equal } // if eq-relevant } // for all fields } // if EQ-compare at all if (!commonfound) result=SYSYNC_NOT_COMPARABLE; // if not equal, try to compare age (if age-sortable item at all) if (result!=0 && fFieldDefinitionsP->fAgeSortable) { for (sInt16 i=0; inumFields(); i++) { // then test for age (if relevant) if (fFieldDefinitionsP->fFields[i].ageRelevant) { // this is an age relevant field // - get assigned status of both fields bool a1 = isAssigned(i); // assignment status of field in this item bool a2 = aItem.isAssigned(i); // assignment status of same field in other item // - if both are unassigned -> cannot decide, continue if (!a1 && !a2) continue; // test next field // - if one of them is unassigned -> not age-comparable if (!a1 || !a2) { result=SYSYNC_NOT_COMPARABLE; goto exit; } // - if both are assigned, return field comparison value result=getFieldRef(i).compareWith(aItem.getFieldRef(i)); if (result!=0) { // not equal, newer item determined goto exit; } // continue to resolve age with next fields } } // no age relevant fields or all age relevant fields equal (possibly all unassigned) result=SYSYNC_NOT_COMPARABLE; } // done exit: return result; } // TMultiFieldItem::standardCompareWith #endif // server only // update dependencies of fields (such as BLOB proxies) on localID void TMultiFieldItem::updateLocalIDDependencies(void) { const char *localid = getLocalID(); // go through all fields for (sInt16 k=0; knumFields(); k++) { TItemField *fldP = getField(k); for (sInt16 i=0; iarraySize(); i++) { TItemField *leaffldP = fldP->getArrayField(i); if (leaffldP) leaffldP->setParentLocalID(localid); } } } // TMultiFieldItem::updateLocalIDDependencies /// @brief replace data contents from specified item /// @param aAvailableOnly: only replace contents actually available in aItem, leave rest untouched /// NOTE: this was changed slightly between 1.x.8.5 and 1.x.8.6: /// If the source type has not received devinf saying which fields are available, /// only fields that are actually ASSIGNED are written. If aAssignedOnly is /// additionally set, only assigned fields will be written anyway. /// @param aDetectCutOffs: use field's maxsize specs to detect contents cut off by limited field /// lengths and do not replace data if target is equal with source up to field length /// @param aAssignedOnly: just copy assigned fields (no check for availability) /// @param aTransferUnassigned: transfer unassigned status from source item (i.e. unassign those /// in target that are unassigned in source, no check for availability) bool TMultiFieldItem::replaceDataFrom(TSyncItem &aItem, bool aAvailableOnly, bool aDetectCutoffs, bool aAssignedOnly, bool aTransferUnassigned) { TMultiFieldItem *multifielditemP = castToSameTypeP(&aItem); if (!multifielditemP) return false; // ok, same type, copy data for (sInt16 i=0; inumFields(); i++) { if ( !aAvailableOnly || ( !aAssignedOnly && // availability is relevant only if not aAssignedOnly multifielditemP->fItemTypeP->hasReceivedFieldOptions() && multifielditemP->fItemTypeP->getFieldOptions(i)->available ) || multifielditemP->isAssigned(i) ) { // copy field sInt32 siz=multifielditemP->fItemTypeP->getFieldOptions(i)->maxsize; if (aDetectCutoffs && siz!=FIELD_OPT_MAXSIZE_NONE) { // check if source fields's content is fully contained at beginning of // target string, if yes, don't do anything // Note: (2002-12-01) do not actually use size, as it will probably not be accurate enough, // but always pass FIELD_OPT_MAXSIZE_UNKNOWN. if (getFieldRef(i).isShortVers(multifielditemP->getFieldRef(i),FIELD_OPT_MAXSIZE_UNKNOWN)) { // yes, we think that this is a cut-off, // so leave target untouched as it has more complete version of this field continue; } } // copy source field into this target field getFieldRef(i)=multifielditemP->getFieldRef(i); } else if (aTransferUnassigned && !multifielditemP->isAssigned(i)) { // explicitly transfer unassigned status // Note: this is useful in read-modify-write done exclusively for cutoff prevention, // as it prevents re-writing fields that were not actually transmitted from the remote // (i.e. no get-from-DB-and-write-same-value-back). Might be essential in case of special // fields where the datastore MUST know if these were sent with the data, like FN in pocketpc) getFieldRef(i).unAssign(); } } return true; } // TMultiFieldItem::replaceDataFrom // check item before processing it bool TMultiFieldItem::checkItem(TLocalEngineDS *aDatastoreP) { return fItemTypeP->checkItem(*this,aDatastoreP); } // TMultiFieldItem::checkItem #ifdef SYSYNC_SERVER // merge this item with specified item. // Notes: // - specified item is treated as loosing item, this item is winning item // - also updates other item to make sure it is equal to the winning after the merge // sets (but does not reset) change status of this and other item. // Note that changes of non-relevant fields are not reported here. void TMultiFieldItem::mergeWith(TSyncItem &aItem, bool &aChangedThis, bool &aChangedOther, TLocalEngineDS *aDatastoreP, int mode) { TMultiFieldItem *multifielditemP = castToSameTypeP(&aItem); if (!multifielditemP) return; // do the merge if (fItemTypeP) fItemTypeP->mergeItems(*this,*multifielditemP,aChangedThis,aChangedOther,aDatastoreP, mode); else standardMergeWith(*multifielditemP,aChangedThis,aChangedOther, mode); // show result OBJDEBUGPRINTFX(getItemType()->getSession(),DBG_DATA+DBG_CONFLICT,( "mergeWith() final status: thisitem: %schanged, otheritem: %schanged (relevant; eqm_none field changes are not indicated)", aChangedThis ? "" : "not ", aChangedOther ? "" : "not " )); } // TMultiFieldItem::mergeWith // merge this item with specified item. // Notes: // - specified item is treated as loosing item, this item is winning item // - also updates other item to make sure it is equal to the winning after the merge // returns update status of this and other item. Note that changes of non-relevant fields are // not reported here. void TMultiFieldItem::standardMergeWith(TMultiFieldItem &aItem, bool &aChangedThis, bool &aChangedOther, int mode) { // same type of multifield, try to merge for (sInt16 i=0; inumFields(); i++) { // get merge mode sInt16 sep=fFieldDefinitionsP->fFields[i].mergeMode; // possible merging is only relevant (=to be reported) for fields that are not eqm_none bool mergerelevant = fFieldDefinitionsP->fFields[i].eqRelevant!=eqm_none; // check if available in both items at all if ( fItemTypeP->getFieldOptions(i)->available && // winning aItem.fItemTypeP->getFieldOptions(i)->available // loosing ) { // fields available in both items // - get both fields TItemField &winningField = getFieldRef(i); TItemField &loosingField = aItem.getFieldRef(i); // - get assigned status of both fields bool winning = winningField.isAssigned(); bool loosing = loosingField.isAssigned(); // - now decide what to do if (sep!=mem_none && mode == MERGE_OPTION_FROM_CONFIG) { // merge enabled PDEBUGPRINTFX(DBG_DATA+DBG_CONFLICT,( "Field '%s' available and enabled for merging, mode/sep=0x%04hX, %srelevant", fFieldDefinitionsP->fFields[i].TCFG_CSTR(fieldname), sep, mergerelevant ? "" : "NOT " )); PDEBUGPRINTFX(DBG_DATA+DBG_CONFLICT,( "- %sassigned in winning / %sassigned in loosing", winning ? "" : "not ", loosing ? "" : "not " )); // - if both are unassigned -> nop if (!winning && !loosing) continue; // test next field // - if this item has field unassigned and other has it assigned: copy contents else if (!winning && loosing && (sep==mem_fillempty || sep==mem_addunassigned)) { // assign loosing item's content to non-assigned winning item getFieldRef(i)=aItem.getFieldRef(i); #ifdef SYDEBUG string ds; getFieldRef(i).getAsString(ds); PDEBUGPRINTFX(DBG_DATA+DBG_CONFLICT+DBG_USERDATA,( "- assigned value '%" FMT_LENGTH(".40") "s' to winning (which had nothing assigned here)", FMT_LENGTH_LIMITED(40,ds.c_str()) )); #endif // count only if relevant and not assigned empty value // (so empty and unassigned are treated equally) if (mergerelevant && !aItem.getFieldRef(i).isEmpty()) aChangedThis=true; // merged something into this item } else if (winning && loosing) { // merge loosing field into winning field if (sep==mem_fillempty) { // only fill up empty winning fields if (winningField.isEmpty() && !loosingField.isEmpty()) { // only copy value from loosing if winning is empty winningField=loosingField; #ifdef SYDEBUG string ds; winningField.getAsString(ds); PDEBUGPRINTFX(DBG_DATA+DBG_CONFLICT+DBG_USERDATA,( "- copied value '%" FMT_LENGTH(".40") "s' from loosing to empty winning", FMT_LENGTH_LIMITED(40,ds.c_str()) )); #endif if (mergerelevant) aChangedThis=true; } } else { // try real merge (sep might be 0 (mem_concat) or a separator char) #ifdef SYDEBUG string ds1,ds2; winningField.getAsString(ds1); loosingField.getAsString(ds2); PDEBUGPRINTFX(DBG_DATA+DBG_CONFLICT+DBG_USERDATA,( "- try merging winning value '%" FMT_LENGTH(".40") "s' with loosing value '%" FMT_LENGTH(".40") "s'", FMT_LENGTH_LIMITED(40,ds1.c_str()), FMT_LENGTH_LIMITED(40,ds2.c_str()) )); #endif if (winningField.merge(loosingField,sep)) aChangedThis=true; #ifdef SYDEBUG winningField.getAsString(ds1); PDEBUGPRINTFX(DBG_DATA+DBG_CONFLICT+DBG_USERDATA,( " merged %sthing, winning value is '%" FMT_LENGTH(".40") "s'", aChangedThis ? "some" : "no", FMT_LENGTH_LIMITED(40,ds1.c_str()) )); #endif } } } // merge enabled // with or without merge, loosing fields must be equal to winning ones // - for non merge-relevant (that is, never-compared) fields, // just assign winning value to loosing and do not compare (this // is important to avoid pulling large blobs and strings here - // assignment just passes the proxy) if (!mergerelevant) { // everything is handled by the field assignment mechanisms if (mode == MERGE_OPTION_CHANGE_THIS) { winningField = loosingField; } else { loosingField = winningField; } } else if (winningField!=loosingField) { // merge relevant fields will get more sophisticated treatment, such // as checking if a change has occurred and cutoff detection #ifdef SYDEBUG string wfv,lfv; winningField.getAsString(wfv); loosingField.getAsString(lfv); PDEBUGPRINTFX(DBG_DATA+DBG_CONFLICT+DBG_USERDATA,( "Winning and loosing Field '%s' not equal: '%" FMT_LENGTH(".30") "s' <> '%" FMT_LENGTH(".30") "s'", fFieldDefinitionsP->fFields[i].TCFG_CSTR(fieldname), FMT_LENGTH_LIMITED(30,wfv.c_str()),FMT_LENGTH_LIMITED(30,lfv.c_str()) )); #endif // update loosing item, too, unless the winning field is shorter or explicitly requested if (mode == MERGE_OPTION_CHANGE_THIS || loosingField.isShortVers(winningField,fItemTypeP->getFieldOptions(i)->maxsize)) { // winning field is short version of loosing field -> loosing field is "better", use it winningField=loosingField; aChangedThis=true; } else { // standard case, loosing field is replaced by winning field loosingField=winningField; aChangedOther=true; } // this is some kind of item-level merge as well #ifdef SYDEBUG string ds; winningField.getAsString(ds); PDEBUGPRINTFX(DBG_DATA+DBG_CONFLICT+DBG_USERDATA,( "- updated fields such that both have same value '%" FMT_LENGTH(".40") "s'", FMT_LENGTH_LIMITED(40,ds.c_str()) )); #endif } } // field available in both items } // field loop } // TMultiFieldItem::standardMergeWith #endif // server only #ifdef SYDEBUG // show item contents for debug void TMultiFieldItem::debugShowItem(uInt32 aDbgMask) { TFieldListConfig *fielddefsP = getFieldDefinitions(); string val,fshow,oloc,orem; TFieldOptions *foptP; TItemField *fldP; if (PDEBUGTEST(aDbgMask|DBG_DETAILS)) { // very detailed bool hasdata = getSyncOp()!=sop_archive_delete && getSyncOp()!=sop_soft_delete && getSyncOp()!=sop_delete && getSyncOp()!=sop_copy && getSyncOp()!=sop_move; // - item header info PDEBUGPRINTFX(aDbgMask|DBG_DETAILS|DBG_HOT,( "Item LocalID='%s', RemoteID='%s', operation=%s%s", getLocalID(), getRemoteID(), SyncOpNames[getSyncOp()], hasdata && PDEBUGTEST(aDbgMask|DBG_USERDATA) ? ", size: [maxlocal,maxremote,actual]" : "" )); if (!hasdata) return; // do not show data for delete if (!PDEBUGTEST(aDbgMask|DBG_USERDATA)) { PDEBUGPRINTFX(aDbgMask|DBG_DETAILS,("*** field data not shown because userdata log is disabled ***")); return; // do not show any field data } // - fields fshow.erase(); for (sInt16 k=0; knumFields(); k++) { SYSYNC_TRY { const TFieldDefinition *fdP = &(fielddefsP->fFields[k]); // get options oloc="?"; if (fItemTypeP) { foptP=fItemTypeP->getFieldOptions(k); if (!foptP->available) oloc="n/a"; else StringObjPrintf(oloc,"%ld",(long)foptP->maxsize); } orem="?"; if (fTargetItemTypeP) { foptP=fTargetItemTypeP->getFieldOptions(k); if (!foptP->available) orem="n/a"; else StringObjPrintf(orem,"%ld",(long)foptP->maxsize); } // get value (but prevent pulling proxies) fldP=NULL; size_t n=0; // empty or unknown size if (isAssigned(k)) { fldP = getField(k); val.erase(); n = fldP->StringObjFieldAppend(val,99); // get string representation and size } else val=""; // now show main info StringObjAppendPrintf(fshow, "- %2d : %10s %-15s [%4s,%4s,%6ld] : %s\n", k, // fid ItemFieldTypeNames[fdP->type], // field type TCFG_CSTR(fdP->fieldname), // field name oloc.c_str(), orem.c_str(), long(n), val.c_str() ); // show array contents if any if (fldP && fldP->isArray()) { int arridx; for (arridx=0; arridxarraySize(); arridx++) { // show array elements TItemField *elemP = fldP->getArrayField(arridx,true); val.erase(); elemP->StringObjFieldAppend(val,99); StringObjAppendPrintf(fshow, " -- element %4d : %s\n", arridx, val.c_str() ); } } // isArray } SYSYNC_CATCH(exception &e) PDEBUGPRINTFX(DBG_ERROR,("Exception when trying to show field fid=%hd: %s[FLUSH]",k,e.what())); SYSYNC_ENDCATCH SYSYNC_CATCH(...) PDEBUGPRINTFX(DBG_ERROR,("Unknown Exception when trying to show field fid=%hd[FLUSH]",k)); SYSYNC_ENDCATCH } // for all fields PDEBUGPUTSXX(aDbgMask|DBG_DETAILS|DBG_USERDATA,fshow.c_str(),0,true); } else if (PDEBUGTEST(aDbgMask)) { // single line only StringObjPrintf(fshow, "Item locID='%s', RemID='%s', op=%s", getLocalID(), getRemoteID(), SyncOpNames[getSyncOp()] ); if (!PDEBUGTEST(aDbgMask|DBG_USERDATA)) { fshow+=", *** userdata log disabled ***"; } else if ( getSyncOp()==sop_archive_delete || getSyncOp()==sop_soft_delete || getSyncOp()==sop_delete ) { // do not show data for delete } else { fshow+=", Fields: "; for (sInt16 k=0; knumFields(); k++) { if (isAssigned(k)) { if (!getField(k)->isEmpty() && !getField(k)->hasProxy()) { getField(k)->StringObjFieldAppend(fshow,20); fshow+=", "; } } } } PDEBUGPUTSX(aDbgMask,fshow.c_str()); } } // TMultiFieldItem::debugShowItem #endif /* end of TMultiFieldItem implementation */ #ifdef DBAPI_TUNNEL_SUPPORT // TMultiFieldItemKey // ================== // set new content item void TMultiFieldItemKey::setItem(TMultiFieldItem *aItemP, bool aPassOwner) { forgetItem(); fItemP = aItemP; fOwnsItem = aPassOwner; fWritten = fItemP; // if we have set an item, this counts as written } // TMultiFieldItemKey::setItem // get FID for specified name sInt16 TMultiFieldItemKey::getFidFor(cAppCharP aName, stringSize aNameSz) { if (!fItemP) return VARIDX_UNDEFINED; // no item, no field is accessible TFieldListConfig *flcP = fItemP->getFieldDefinitions(); // check for iterator commands first if (strucmp(aName,VALNAME_FIRST)==0) { fIteratorFid = 0; if (fIteratorFidnumFields()) return fIteratorFid; } else if (strucmp(aName,VALNAME_NEXT)==0) { if (fIteratorFidnumFields()) fIteratorFid++; if (fIteratorFidnumFields()) return fIteratorFid; } else { return flcP->fieldIndex(aName,aNameSz); } // none found return VARIDX_UNDEFINED; } // TMultiFieldItemKey::getFidFor TItemField *TMultiFieldItemKey::getBaseFieldFromFid(sInt16 aFid) { if (!fItemP) return NULL; // no item, no field is accessible return fItemP->getField(aFid); } // TMultiFieldItemKey::getBaseFieldFromFid bool TMultiFieldItemKey::getFieldNameFromFid(sInt16 aFid, string &aFieldName) { if (!fItemP) return false; // no item, no field is accessible // name is field name TFieldListConfig *flcP = fItemP->getFieldDefinitions(); if (aFid>=0 && aFidnumFields()) { aFieldName = flcP->fFields[aFid].fieldname; return true; } // none found return false; } // TMultiFieldItemKey::getFieldNameFromFid #endif // DBAPI_TUNNEL_SUPPORT } // namespace sysync // eof libsynthesis-3.4.0.47.1/src/sysync/multifielditem.h000077500000000000000000000370431226375725500221630ustar00rootroot00000000000000/* * File: MultiFieldItem.h * * Author: Lukas Zeller (luz@plan44.ch) * * TMultiFieldItem * Item consisting of multiple data fields (TItemField objects) * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * 2001-08-08 : luz : created * */ #ifndef MultiFieldItem_H #define MultiFieldItem_H // includes #include "syncitem.h" #include "itemfield.h" #include "configelement.h" #include "syncappbase.h" using namespace sysync; namespace sysync { // undefined field/var index // Notes: // - positive indices address fields in the field list, negative indices address script variables // - this must be in 8-bit-negative range for current implementation of TScripTContext // - FID_NOT_SUPPORTED must be the same value as these are used interchangeably // (historically FID_NOT_SUPPORTED was -1). Definition of FID_NOT_SUPPORTED checks this now. #define VARIDX_UNDEFINED -128 // helper macros for getting a field by FID with casting // - get dynamically casted field, returns NULL if field has wrong type or does not exist #define GETFIELD_DYNAMIC_CAST(ty,tyid,fid,itemP) ( itemP->getField(fid) ? ITEMFIELD_DYNAMIC_CAST_PTR(ty,tyid,itemP->getField(fid)) : NULL ) // - get statically casted field, field must exist and have that type #define GETFIELD_STATIC_CAST(ty,fid,itemP) ( static_cast(itemP->getField(fid)) ) // single field definition class TFieldDefinition { public: // type TItemFieldTypes type; #ifdef ARRAYFIELD_SUPPORT bool array; // set if this is an array field #endif // name TCFG_STRING fieldname; // relevant for equality (used in slow sync and in conflicts) TEqualityMode eqRelevant; // relevant for age sorting (used in case of conflict) bool ageRelevant; // merge options (used whenever one record overwrites other) // - if mergeMode = mem_none, merge is disabled // - if mergeMode = mem_fillempty, empty fields will be filled, but no concatenation is used // - if mergeMode>=0, fields that are non-equal will be accumulated // - if >0 then mergeMode will be used as separation char char mergeMode; }; // TFieldDefinition #ifdef HARDCODED_TYPE_SUPPORT // single field definition typedef struct { // type TItemFieldTypes type; //#ifdef ARRAYFIELD_SUPPORT //%%% make all templates equal bool array; // set if this is an array field //#endif // name const char *fieldname; // relevant for equality (used in slow sync and in conflicts) TEqualityMode eqRelevant; // relevant for age sorting (used in case of conflict) bool ageRelevant; // merge options (used whenever one record overwrites other) // - if mergeMode = mem_none, merge is disabled // - if mergeMode = mem_fillempty, empty fields will be filled, but no concatenation is used // - if mergeMode>=0, fields that are non-equal will be accumulated // - if >0 then mergeMode will be used as separation char char mergeMode; // Type limit defaults uInt32 maxSize; bool noTruncate; } TFieldDefinitionTemplate; // field definitions template typedef struct { // number of fields sInt16 numFields; // sortable by age? bool ageSortable; // %%%% not needed any more, will be set automatically if at least one field is agerelevant // field definitions [0..numfields-1] // note: sort order is 0..n, i.e. fields with lower indexes are more relevant const TFieldDefinitionTemplate *fieldDefs; } TFieldDefinitionsTemplate; #endif // field array typedef std::vector TFieldDefinitionList; class TMultiFieldDatatypesConfig; // forward class TMultiFieldItem; class TMultiFieldItemType; // field definition config // This object MUST exist only ONCE per // MultiField-based type (as assignment compatibility is // given by POINTER IDENTITY of the MultiField's TFieldListConfig). class TFieldListConfig : public TConfigElement { typedef TConfigElement inherited; friend class TMultiFieldDatatypesConfig; public: TFieldListConfig(const char* aName, TConfigElement *aParentElement); virtual ~TFieldListConfig(); #ifdef HARDCODED_TYPE_SUPPORT const TFieldDefinitionsTemplate *fFieldListTemplateP; void readFieldListTemplate(const TFieldDefinitionsTemplate *aTemplateP); #endif // properties // - sortable by age? bool fAgeSortable; // - field definition array TFieldDefinitionList fFields; sInt16 numFields(void) { return fFields.size(); }; sInt16 fieldIndex(const char *aName, size_t aLen=0); protected: // check config elements #ifdef CONFIGURABLE_TYPE_SUPPORT virtual bool localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine); virtual void localResolve(bool aLastPass); #endif virtual void clear(); }; // TFieldListConfig // profile handler abstract base class class TProfileHandler { public: // constructor/destructor TProfileHandler(TProfileConfig *aProfileCfgP, TMultiFieldItemType *aItemTypeP); virtual ~TProfileHandler(); #ifdef OBJECT_FILTERING // filtering // - get field index of given filter expression identifier. virtual sInt16 getFilterIdentifierFieldIndex(const char *aIdentifier, uInt16 aIndex) = 0; // - add keywords and property names to filterCap virtual void addFilterCapPropsAndKeywords(SmlPcdataListPtr_t &aFilterKeywords, SmlPcdataListPtr_t &aFilterProps, TTypeVariantDescriptor aVariantDesc, TSyncItemType *aItemTypeP) = 0; #endif // DevInf // - obtain property list for type, returns NULL if none available virtual SmlDevInfCTDataPropListPtr_t newCTDataPropList(TTypeVariantDescriptor aVariantDescriptor, TSyncItemType *aItemTypeP) { return NULL; }; // - Analyze CTCap part of devInf virtual bool analyzeCTCap(SmlDevInfCTCapPtr_t aCTCapP, TSyncItemType *aItemTypeP) { return true; }; // set profile options // - mode (for those profiles that have more than one, like MIME-DIR's old/standard) virtual void setProfileMode(sInt32 aMode) { /* nop here */ }; #ifndef NO_REMOTE_RULES // - choose remote rule by name, true if found virtual void setRemoteRule(const string &aRemoteRuleName) { /* nop here */ } #endif // set related datastore (NULL for independent use e.g. from script functions) void setRelatedDatastore(TLocalEngineDS *aRelatedDatastoreP) { fRelatedDatastoreP = aRelatedDatastoreP; }; // generate Text Data virtual void generateText(TMultiFieldItem &aItem, string &aString) = 0; // parse Data item virtual bool parseText(const char *aText, stringSize aTextSize, TMultiFieldItem &aItem) = 0; // Debug #ifdef SYDEBUG TDebugLogger *getDbgLogger(void); uInt32 getDbgMask(void); #endif protected: TLocalEngineDS *fRelatedDatastoreP; // related datastore, can be NULL TMultiFieldItemType *fItemTypeP; // the item type using this handler // helpers // - get session pointer TSyncSession *getSession(void); // - get session zones pointer GZones *getSessionZones(void); // - check availability (depends on item "supported" flags only in SyncML datastore context) bool isFieldAvailable(TMultiFieldItem &aItem, sInt16 aFieldIndex); }; // TProfileHandler // profile config base class (e.g. for MIMEDIR and text profiles) // A profile is a config element related to a single fieldlist, but probably to more // than one datatype class TProfileConfig : public TConfigElement { typedef TConfigElement inherited; friend class TMultiFieldDatatypesConfig; friend class TTextTypeConfig; public: TProfileConfig(const char* aName, TConfigElement *aParentElement); virtual ~TProfileConfig(); // handler factory virtual TProfileHandler *newProfileHandler(TMultiFieldItemType *aItemTypeP) = 0; // properties // - field list config TFieldListConfig *fFieldListP; protected: // check config elements virtual void clear(); }; // TProfileConfig // fieldlists list typedef std::list TFieldListsList; // profiles list typedef std::list TProfilesList; // multi-field based type config registry class TMultiFieldDatatypesConfig : public TDatatypesConfig { typedef TDatatypesConfig inherited; public: TMultiFieldDatatypesConfig(TConfigElement *aParentElement); virtual ~TMultiFieldDatatypesConfig(); // properties // - field lists TFieldListsList fFieldLists; TFieldListConfig *getFieldList(const char *aName); // - profiles (fieldlist-related definitions, but probably used in multiple datatypes) TProfilesList fProfiles; TProfileConfig *getProfile(const char *aName); protected: // check config elements #ifdef CONFIGURABLE_TYPE_SUPPORT virtual bool localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine); virtual void localResolve(bool aLastPass); #endif virtual void clear(); private: void internalClear(void); }; // TMultiFieldDatatypesConfig const uInt16 ity_multifield = 100; // must be unique class TMultiFieldItem: public TSyncItem { typedef TSyncItem inherited; public: TMultiFieldItem( TMultiFieldItemType *aItemTypeP, // owner's (=source) type TMultiFieldItemType *aTargetItemTypeP // target type (for optimization) ); virtual ~TMultiFieldItem(); // access to type virtual uInt16 getTypeID(void) const { return ity_multifield; }; virtual bool isBasedOn(uInt16 aItemTypeID) const { return aItemTypeID==ity_multifield ? true : TSyncItem::isBasedOn(aItemTypeID); }; // assignment (IDs and contents) virtual TSyncItem& operator=(TSyncItem &aSyncItem) { return TSyncItem::operator=(aSyncItem); }; // changelog support #if defined(CHECKSUM_CHANGELOG) && !defined(RECORDHASH_FROM_DBAPI) virtual uInt16 getDataCRC(uInt16 crc=0, bool aEQRelevantOnly=false); #endif // update dependencies of fields (such as BLOB proxies) on localID virtual void updateLocalIDDependencies(void); // - access fields by field name or index TItemField *getField(sInt16 aFieldIndex); TItemField *getField(const char *aFieldName); TItemField &getFieldRef(sInt16 aFieldIndex); // get field reference (create if not yet created) // for array support, but is always there to simplify implementations TItemField *getArrayField(const char *aFieldName, sInt16 aIndex, bool aExistingOnly=false); TItemField *getArrayField(sInt16 aFid, sInt16 aIndex, bool aExistingOnly=false); TItemField *getArrayFieldAdjusted(sInt16 aFid, sInt16 aIndex, bool aExistingOnly=false); // find index of field (returns FID_NOT_SUPPORTED if field is not a field of this item) sInt16 getIndexOfField(const TItemField *aFieldP); // adjust fid and repeat offset to access array element if // base fid is an array field or to offset fid accordingly // if based fid is NOT an array field // - returns adjusted aFid and aIndex ready to be used with getArrayField() // - returns true if aFid IS an array field bool adjustFidAndIndex(sInt16 &aFid, sInt16 &aIndex); // - check if field is assigned (exists and has a value) bool const isAssigned(sInt16 aFieldIndex); bool const isAssigned(const char *aFieldName); // access field definitions TFieldListConfig *getFieldDefinitions(void) { return fFieldDefinitionsP; }; // get associated MultiFieldItemType TMultiFieldItemType *getItemType(void) { return fItemTypeP; }; TMultiFieldItemType *getTargetItemType(void) { return fTargetItemTypeP; }; TMultiFieldItemType *getLocalItemType(void); TMultiFieldItemType *getRemoteItemType(void); // field availability (combined source & target) bool isAvailable(sInt16 aFieldIndex); bool isAvailable(const char *aFieldName); bool knowsRemoteFieldOptions(void); // - instantiate all fields that are available in source and target void assignAvailables(void); // compare abilities virtual bool comparable(TSyncItem &aItem); virtual bool sortable(TSyncItem &aItem); // clear item data virtual void cleardata(void); // replace data contents from specified item // - aAvailable only: only replace contents actually available in aItem, leave rest untouched // - aDetectCutOffs: handle case where aItem could have somehow cut-off data and prevent replacing // complete data with cut-off version (e.g. mobiles like T39m with limited name string capacity) virtual bool replaceDataFrom(TSyncItem &aItem, bool aAvailableOnly=false, bool aDetectCutoffs=false, bool aAssignedOnly=false, bool aTransferUnassigned=false); // check item before processing it virtual bool checkItem(TLocalEngineDS *aDatastoreP); #ifdef SYSYNC_SERVER // merge this item with specified item. // Notes: // - specified item is treated as loosing item, this item is winning item // - also updates other item to make sure it is equal to the winning after the merge // sets (but does not reset) change status of this and other item. // Note that changes of non-relevant fields are not reported here. virtual void mergeWith(TSyncItem &aItem, bool &aChangedThis, bool &aChangedOther, TLocalEngineDS *aDatastoreP, int mode = MERGE_OPTION_FROM_CONFIG); // standard merge (subset of mergeWith, used if no merge script is defined) void standardMergeWith(TMultiFieldItem &aItem, bool &aChangedThis, bool &aChangedOther, int mode = MERGE_OPTION_FROM_CONFIG); // compare: returns 0 if equal, 1 if this > aItem, -1 if this < aItem // SYSYNC_NOT_COMPARABLE if not equal and no ordering known virtual sInt16 compareWith( TSyncItem &aItem, TEqualityMode aEqMode, TLocalEngineDS *aDatastoreP #ifdef SYDEBUG ,bool aDebugShow=false #endif ); // standard compare (subset of compareWith, used if no compare script is defined) sInt16 standardCompareWith( TMultiFieldItem &aItem, TEqualityMode aEqMode, bool aDebugShow ); #endif #ifdef SYDEBUG // show item contents for debug virtual void debugShowItem(uInt32 aDbgMask=DBG_DATA); #endif #ifdef OBJECT_FILTERING // New style generic filtering // - check if item passes filter and probably apply some modifications to it virtual bool postFetchFiltering(TLocalEngineDS *aDatastoreP); // Old style object filtering // - test if item passes filter virtual bool testFilter(const char *aFilterString); // - make item pass filter virtual bool makePassFilter(const char *aFilterString); // - actually process filter expression bool processFilter(bool aMakePass, const char *&aPos, const char *aStop=NULL, sInt16 aLastOpPrec=0); #endif protected: // associated multifield type items (owner and target) TMultiFieldItemType *fItemTypeP; TMultiFieldItemType *fTargetItemTypeP; // associated field definitions (copied from ItemType for performance) TFieldListConfig *fFieldDefinitionsP; // contents: array of actual fields TItemField **fFieldsP; private: // cast pointer to same type, returns NULL if incompatible TMultiFieldItem *castToSameTypeP(TSyncItem *aItemP); // all are compatible TSyncItem }; // TMultiFieldItem #ifdef DBAPI_TUNNEL_SUPPORT // key for access to a item using the settings key API class TMultiFieldItemKey : public TItemFieldKey { typedef TItemFieldKey inherited; public: TMultiFieldItemKey(TEngineInterface *aEngineInterfaceP, TMultiFieldItem *aItemP, bool aOwnsItem=false) : inherited(aEngineInterfaceP), fItemP(aItemP), fOwnsItem(aOwnsItem) {}; virtual ~TMultiFieldItemKey() { forgetItem(); }; TMultiFieldItem *getItem(void) { return fItemP; }; void setItem(TMultiFieldItem *aItemP, bool aPassOwner=false); protected: // methods to actually access a TItemField virtual sInt16 getFidFor(cAppCharP aName, stringSize aNameSz); virtual bool getFieldNameFromFid(sInt16 aFid, string &aFieldName); virtual TItemField *getBaseFieldFromFid(sInt16 aFid); // the item being accessed TMultiFieldItem *fItemP; bool fOwnsItem; // iterator sInt16 fIteratorFid; private: void forgetItem() { if (fOwnsItem && fItemP) { delete fItemP; } fItemP=NULL; }; }; // TMultiFieldItemKey #endif // DBAPI_TUNNEL_SUPPORT } // namespace sysync #endif // MultiFieldItem_H // eof libsynthesis-3.4.0.47.1/src/sysync/multifielditemtype.cpp000077500000000000000000001152061226375725500234160ustar00rootroot00000000000000/* * File: MultiFieldItemType.cpp * * Author: Lukas Zeller (luz@plan44.ch) * * TMultiFieldItemType * Type consisting of multiple data fields (TItemField objects) * To be used as base class for field formats like vCard, * vCalendar etc. * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * 2001-08-13 : luz : created * */ // includes #include "prefix_file.h" #include "sysync.h" #include "multifielditemtype.h" namespace sysync { // multifield-based datatype config TMultiFieldTypeConfig::TMultiFieldTypeConfig(const char* aName, TConfigElement *aParentElement) : TDataTypeConfig(aName,aParentElement) { clear(); } // TMultiFieldTypeConfig::TMultiFieldTypeConfig TMultiFieldTypeConfig::~TMultiFieldTypeConfig() { clear(); } // TMultiFieldTypeConfig::~TMultiFieldTypeConfig // init defaults void TMultiFieldTypeConfig::clear(void) { // clear properties // - remove link to field list fFieldListP=NULL; // - remove link to field list fProfileConfigP=NULL; #ifdef SCRIPT_SUPPORT fInitScript.erase(); fIncomingScript.erase(); fOutgoingScript.erase(); fFilterInitScript.erase(); fPostFetchFilterScript.erase(); #ifdef SYSYNC_SERVER fCompareScript.erase(); fMergeScript.erase(); #endif fProcessItemScript.erase(); #endif // clear properties fProfileMode=PROFILEMODE_DEFAULT; // default profile mode // clear inherited inherited::clear(); } // TMultiFieldTypeConfig::clear #ifdef SCRIPT_SUPPORT class TMFTypeFuncs { public: // integer SYNCMODESUPPORTED(string mode) // // True if the remote datastore is known to support the specific mode // (usually because it sent SyncCap including the mode), false if unknown // or not supported. // // Only works inside scripts which work on remote items. static void func_SyncModeSupported(TItemField *&aTermP, TScriptContext *aFuncContextP) { bool supported = false; TMultiFieldItemType *mfitP = static_cast(aFuncContextP->getCallerContext()); if (mfitP->fFirstItemP && mfitP->fFirstItemP->getRemoteItemType()) { TSyncDataStore *related = mfitP->fFirstItemP->getRemoteItemType()->getRelatedDatastore(); if (related) { std::string mode; aFuncContextP->getLocalVar(0)->getAsString(mode); supported = related->syncModeSupported(mode); } } aTermP->setAsInteger(supported); }; // func_SyncModeSupported // void SETFILTERALL(integer all) // sets if all records in the syncset need to checked against filter or only those that are new or changed static void func_SetFilterAll(TItemField *&aTermP, TScriptContext *aFuncContextP) { static_cast(aFuncContextP->getCallerContext())->fNeedToFilterAll = aFuncContextP->getLocalVar(0)->getAsBoolean(); }; // func_SetFilterAll #ifdef SYSYNC_TARGET_OPTIONS // integer SIZELIMIT() // gets the size limit set for this item static void func_Limit(TItemField *&aTermP, TScriptContext *aFuncContextP) { fieldinteger_t i = static_cast(aFuncContextP->getCallerContext())->fDsP->fItemSizeLimit; if (i<0) aTermP->unAssign(); else aTermP->setAsInteger(i); }; // func_Limit // SETSIZELIMIT(integer limit) // sets size limit used for generating this item for remote static void func_SetLimit(TItemField *&aTermP, TScriptContext *aFuncContextP) { static_cast(aFuncContextP->getCallerContext())->fDsP->fItemSizeLimit = aFuncContextP->getLocalVar(0)->isUnassigned() ? -1 : aFuncContextP->getLocalVar(0)->getAsInteger(); }; // func_SetLimit #endif #ifdef SYSYNC_SERVER // void ECHOITEM(string syncop) // creates a duplicate of the processed item to be sent back to sender with the specified syncop static void func_EchoItem(TItemField *&aTermP, TScriptContext *aFuncContextP) { // convert to syncop string s; aFuncContextP->getLocalVar(0)->getAsString(s); sInt16 sop; StrToEnum(SyncOpNames, numSyncOperations, sop, s.c_str()); static_cast(aFuncContextP->getCallerContext())->fDsP->fEchoItemOp = (TSyncOperation) sop; }; // func_EchoItem // void CONFLICTSTRATEGY(string strategy) // sets the conflict strategy for this item static void func_ConflictStrategy(TItemField *&aTermP, TScriptContext *aFuncContextP) { // convert to conflictstrategy string s; aFuncContextP->getLocalVar(0)->getAsString(s); sInt16 strategy; StrToEnum(conflictStrategyNames,numConflictStrategies, strategy, s.c_str()); static_cast(aFuncContextP->getCallerContext())->fDsP->fItemConflictStrategy = (TConflictResolution) strategy; }; // func_ConflictStrategy // void FORCECONFLICT() // forces conflict between this item and item from the DB static void func_ForceConflict(TItemField *&aTermP, TScriptContext *aFuncContextP) { static_cast(aFuncContextP->getCallerContext())->fDsP->fForceConflict=true; }; // func_ForceConflict // void DELETEWINS() // in a replace/delete conflict, delete wins (normally, replace wins) static void func_DeleteWins(TItemField *&aTermP, TScriptContext *aFuncContextP) { static_cast(aFuncContextP->getCallerContext())->fDsP->fDeleteWins=true; }; // func_DeleteWins // void PREVENTADD() // if set, attempt to add item from remote will cause no add but delete of remote item static void func_PreventAdd(TItemField *&aTermP, TScriptContext *aFuncContextP) { static_cast(aFuncContextP->getCallerContext())->fDsP->fPreventAdd=true; }; // func_PreventAdd // void IGNOREUPDATE() // if set, attempt to update existing items from remote will be ignored static void func_IgnoreUpdate(TItemField *&aTermP, TScriptContext *aFuncContextP) { static_cast(aFuncContextP->getCallerContext())->fDsP->fIgnoreUpdate=true; }; // func_IgnoreUpdate // void MERGEFIELDS(mode = 0) // Optional mode parameter determines the result of the merge. // 0 = according to config, 1 = loosing item is overwritten, 2 = winning item is overwritten static void func_MergeFields(TItemField *&aTermP, TScriptContext *aFuncContextP) { TMultiFieldItemType *mfitP = static_cast(aFuncContextP->getCallerContext()); if (mfitP->fFirstItemP) { TItemField *argP = aFuncContextP->getLocalVar(0); mfitP->fFirstItemP->standardMergeWith(*(mfitP->fSecondItemP),mfitP->fChangedFirst,mfitP->fChangedSecond, (argP && argP->isAssigned()) ? argP->getAsInteger() : 0); } }; // func_MergeFields // integer WINNINGCHANGED() // returns true if winning was changed static void func_WinningChanged(TItemField *&aTermP, TScriptContext *aFuncContextP) { TMultiFieldItemType *mfitP = static_cast(aFuncContextP->getCallerContext()); aTermP->setAsInteger(mfitP->fChangedFirst ? 1 : 0); }; // func_WinningChanged // integer LOOSINGCHANGED() // returns true if loosing was changed static void func_LoosingChanged(TItemField *&aTermP, TScriptContext *aFuncContextP) { TMultiFieldItemType *mfitP = static_cast(aFuncContextP->getCallerContext()); aTermP->setAsInteger(mfitP->fChangedSecond ? 1 : 0); }; // func_LoosingChanged static void func_SetWinningChanged(TItemField *&aTermP, TScriptContext *aFuncContextP) { TMultiFieldItemType *mfitP = static_cast(aFuncContextP->getCallerContext()); mfitP->fChangedFirst = aFuncContextP->getLocalVar(0)->getAsBoolean(); }; // func_SetWinningChanged static void func_SetLoosingChanged(TItemField *&aTermP, TScriptContext *aFuncContextP) { TMultiFieldItemType *mfitP = static_cast(aFuncContextP->getCallerContext()); mfitP->fChangedSecond = aFuncContextP->getLocalVar(0)->getAsBoolean(); }; // func_SetLoosingChanged // integer COMPAREFIELDS() // returns 0 if equal, 1 if first > second, -1 if first < second static void func_CompareFields(TItemField *&aTermP, TScriptContext *aFuncContextP) { TMultiFieldItemType *mfitP = static_cast(aFuncContextP->getCallerContext()); if (!mfitP->fFirstItemP) aTermP->setAsInteger(SYSYNC_NOT_COMPARABLE); else { aTermP->setAsInteger( mfitP->fFirstItemP->standardCompareWith(*(mfitP->fSecondItemP),mfitP->fEqMode,OBJDEBUGTEST(mfitP,DBG_SCRIPTS+DBG_DATA+DBG_MATCH)) ); } }; // func_CompareFields // string COMPARISONMODE() // returns mode of comparison static void func_ComparisonMode(TItemField *&aTermP, TScriptContext *aFuncContextP) { TMultiFieldItemType *mfitP = static_cast(aFuncContextP->getCallerContext()); if (!mfitP->fFirstItemP) aTermP->unAssign(); // no comparison else { aTermP->setAsString(comparisonModeNames[mfitP->fEqMode]); } }; // func_CompareFields // int MERGEMODE() // returns mode of merging, see MERGEFIELDS() static void func_MergeMode(TItemField *&aTermP, TScriptContext *aFuncContextP) { TMultiFieldItemType *mfitP = static_cast(aFuncContextP->getCallerContext()); if (!mfitP->fFirstItemP) aTermP->unAssign(); // no merging else { aTermP->setAsInteger(mfitP->fMergeMode); } }; // func_MergeMode #endif // string SYNCOP() // returns sync-operation as text static void func_SyncOp(TItemField *&aTermP, TScriptContext *aFuncContextP) { aTermP->setAsString( SyncOpNames[static_cast(aFuncContextP->getCallerContext())->fCurrentSyncOp] ); }; // func_SyncOp // void REJECTITEM(integer statuscode) // causes current item not to be processed, but rejected with status code (0=silently rejected) static void func_RejectItem(TItemField *&aTermP, TScriptContext *aFuncContextP) { static_cast(aFuncContextP->getCallerContext())->fDsP->fRejectStatus= aFuncContextP->getLocalVar(0)->getAsInteger(); }; // func_RejectItem // string REMOTEID() // returns target item's remoteID as text static void func_RemoteID(TItemField *&aTermP, TScriptContext *aFuncContextP) { TMultiFieldItemType *mfitP = static_cast(aFuncContextP->getCallerContext()); if (mfitP->fFirstItemP) { aTermP->setAsString(mfitP->fFirstItemP->getRemoteID()); } }; // func_RemoteID // void SETREMOTEID(string remoteid) // sets the target item's remote ID as text static void func_SetRemoteID(TItemField *&aTermP, TScriptContext *aFuncContextP) { TMultiFieldItemType *mfitP = static_cast(aFuncContextP->getCallerContext()); if (mfitP->fFirstItemP) { string s; aFuncContextP->getLocalVar(0)->getAsString(s); mfitP->fFirstItemP->setRemoteID(s.c_str()); } }; // func_SetRemoteID // string LOCALID() // returns target item's localID as text static void func_LocalID(TItemField *&aTermP, TScriptContext *aFuncContextP) { TMultiFieldItemType *mfitP = static_cast(aFuncContextP->getCallerContext()); if (mfitP->fFirstItemP) { aTermP->setAsString(mfitP->fFirstItemP->getLocalID()); } }; // func_LocalID // void SETLOCALID(string remoteid) // sets the target item's localID as text static void func_SetLocalID(TItemField *&aTermP, TScriptContext *aFuncContextP) { TMultiFieldItemType *mfitP = static_cast(aFuncContextP->getCallerContext()); if (mfitP->fFirstItemP) { string s; aFuncContextP->getLocalVar(0)->getAsString(s); mfitP->fFirstItemP->setLocalID(s.c_str()); } }; // func_SetLocalID }; // TMFTypeFuncs // chain function to link datastore-level functions static void* DataTypeChainFunc(void *&aNextCallerContext) { // caller context for datastore-level functions is the datastore pointer if (aNextCallerContext) aNextCallerContext = static_cast(aNextCallerContext)->fDsP; // next table is that of the localdatastore return (void *) &DBFuncTable; } // DataTypeChainFunc const uInt8 param_StrArg[] = { VAL(fty_string) }; const uInt8 param_IntArg[] = { VAL(fty_integer) }; // builtin functions for datastore-context table const TBuiltInFuncDef DataTypeFuncDefs[] = { { "SYNCMODESUPPORTED", TMFTypeFuncs::func_SyncModeSupported, fty_integer, 1, param_StrArg }, { "SETFILTERALL", TMFTypeFuncs::func_SetFilterAll, fty_none, 1, param_IntArg }, #ifdef SYSYNC_TARGET_OPTIONS { "SIZELIMIT", TMFTypeFuncs::func_Limit, fty_integer, 0, NULL }, { "SETSIZELIMIT", TMFTypeFuncs::func_SetLimit, fty_none, 1, param_IntArg }, #endif #ifdef SYSYNC_SERVER { "ECHOITEM", TMFTypeFuncs::func_EchoItem, fty_none, 1, param_StrArg }, { "CONFLICTSTRATEGY", TMFTypeFuncs::func_ConflictStrategy, fty_none, 1, param_StrArg }, { "FORCECONFLICT", TMFTypeFuncs::func_ForceConflict, fty_none, 0, NULL }, { "DELETEWINS", TMFTypeFuncs::func_DeleteWins, fty_none, 0, NULL }, { "PREVENTADD", TMFTypeFuncs::func_PreventAdd, fty_none, 0, NULL }, { "IGNOREUPDATE", TMFTypeFuncs::func_IgnoreUpdate, fty_none, 0, NULL }, { "MERGEFIELDS", TMFTypeFuncs::func_MergeFields, fty_none, 1, param_oneOptInteger }, { "WINNINGCHANGED", TMFTypeFuncs::func_WinningChanged, fty_integer, 0, NULL }, { "LOOSINGCHANGED", TMFTypeFuncs::func_LoosingChanged, fty_integer, 0, NULL }, { "SETWINNINGCHANGED", TMFTypeFuncs::func_SetWinningChanged, fty_none, 1, param_IntArg }, { "SETLOOSINGCHANGED", TMFTypeFuncs::func_SetLoosingChanged, fty_none, 1, param_IntArg }, { "COMPAREFIELDS", TMFTypeFuncs::func_CompareFields, fty_integer, 0, NULL }, { "COMPARISONMODE", TMFTypeFuncs::func_ComparisonMode, fty_string, 0, NULL }, { "MERGEMODE", TMFTypeFuncs::func_MergeMode, fty_integer, 0, NULL }, #endif { "SYNCOP", TMFTypeFuncs::func_SyncOp, fty_string, 0, NULL }, { "REJECTITEM", TMFTypeFuncs::func_RejectItem, fty_none, 1, param_IntArg }, { "LOCALID", TMFTypeFuncs::func_LocalID, fty_string, 0, NULL }, { "SETLOCALID", TMFTypeFuncs::func_SetLocalID, fty_none, 1, param_StrArg }, { "REMOTEID", TMFTypeFuncs::func_RemoteID, fty_string, 0, NULL }, { "SETREMOTEID", TMFTypeFuncs::func_SetRemoteID, fty_none, 1, param_StrArg }, }; const TFuncTable DataTypeFuncTable = { sizeof(DataTypeFuncDefs) / sizeof(TBuiltInFuncDef), // size of table DataTypeFuncDefs, // table pointer DataTypeChainFunc // chain to localdatastore funcs }; #endif #ifdef CONFIGURABLE_TYPE_SUPPORT // config element parsing bool TMultiFieldTypeConfig::localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine) { // checking the elements // Note: derived classes might override this "use" further // Here, we check for using only a file list, or a profile which implies a field list if (strucmp(aElementName,"use")==0) { if (fFieldListP || fProfileConfigP) return fail("'use' cannot be specified more than once"); // - get type registry TMultiFieldDatatypesConfig *mufcP; GET_CASTED_PTR(mufcP,TMultiFieldDatatypesConfig,getParentElement(),DEBUGTEXT("TMultiFieldTypeConfig with non-TMultiFieldDatatypesConfig parent","txit2")); // - check what to look for const char *pnam = getAttr(aAttributes,"fieldlist"); if (pnam) { // we are addressing a fieldlist fFieldListP=mufcP->getFieldList(pnam); if (!fFieldListP) return fail("unknown field list '%s' specified in 'use'",pnam); } else { // this must be a profile (we may also call it 'mimeprofile' for historical, <=2.1 engine reasons) pnam = getAttr(aAttributes,"profile"); if (!pnam) pnam = getAttr(aAttributes,"mimeprofile"); // %%% for compatibility with <=2.1 engine configs if (!pnam) return fail("'use' must have a 'fieldlist' or 'profile' attribute"); fProfileConfigP=mufcP->getProfile(pnam); if (!fProfileConfigP) return fail("unknown profile '%s' specified in 'use'",pnam); // - copy field list pointer into TMultiFieldTypeConfig as well fFieldListP = fProfileConfigP->fFieldListP; } expectEmpty(); } else if (strucmp(aElementName,"profilemode")==0) expectInt32(fProfileMode); // usually, this is set implicitly by derived types, such as vCard, vCalendar #ifdef SCRIPT_SUPPORT else if (strucmp(aElementName,"initscript")==0) expectScript(fInitScript,aLine,&DataTypeFuncTable); else if (strucmp(aElementName,"incomingscript")==0) expectScript(fIncomingScript,aLine,&DataTypeFuncTable); else if (strucmp(aElementName,"outgoingscript")==0) expectScript(fOutgoingScript,aLine,&DataTypeFuncTable); else if (strucmp(aElementName,"filterinitscript")==0) expectScript(fFilterInitScript,aLine,&DataTypeFuncTable); else if (strucmp(aElementName,"filterscript")==0) expectScript(fPostFetchFilterScript,aLine,&DataTypeFuncTable); #ifdef SYSYNC_SERVER else if (strucmp(aElementName,"comparescript")==0) expectScript(fCompareScript,aLine,&DataTypeFuncTable); else if (strucmp(aElementName,"mergescript")==0) expectScript(fMergeScript,aLine,&DataTypeFuncTable); #endif else if (strucmp(aElementName,"processitemscript")==0) expectScript(fProcessItemScript,aLine,&DataTypeFuncTable); #endif // - none known here else return TDataTypeConfig::localStartElement(aElementName,aAttributes,aLine); // ok return true; } // TMultiFieldTypeConfig::localStartElement // resolve void TMultiFieldTypeConfig::localResolve(bool aLastPass) { // check if (aLastPass) { if (!fFieldListP) SYSYNC_THROW(TConfigParseException("missing 'use' in datatype")); #ifdef SCRIPT_SUPPORT TScriptContext *sccP = NULL; SYSYNC_TRY { // resolve all scripts in same context // - init script TScriptContext::resolveScript(getSyncAppBase(),fInitScript,sccP,fFieldListP); // - incoming/outgoing scripts TScriptContext::resolveScript(getSyncAppBase(),fIncomingScript,sccP,fFieldListP); TScriptContext::resolveScript(getSyncAppBase(),fOutgoingScript,sccP,fFieldListP); // - filtering scripts TScriptContext::resolveScript(getSyncAppBase(),fFilterInitScript,sccP,fFieldListP); TScriptContext::resolveScript(getSyncAppBase(),fPostFetchFilterScript,sccP,fFieldListP); // - compare and merge scripts #ifdef SYSYNC_SERVER TScriptContext::resolveScript(getSyncAppBase(),fCompareScript,sccP,fFieldListP); TScriptContext::resolveScript(getSyncAppBase(),fMergeScript,sccP,fFieldListP); #endif // - special processing of incoming items before they are sent to the DB TScriptContext::resolveScript(getSyncAppBase(),fProcessItemScript,sccP,fFieldListP); // - forget this context (rebuild will take place in the datastore's fXXXXTypeScriptContextP) if (sccP) delete sccP; } SYSYNC_CATCH (...) if (sccP) delete sccP; SYSYNC_RETHROW; SYSYNC_ENDCATCH #endif } // resolve inherited inherited::localResolve(aLastPass); } // TMultiFieldTypeConfig::localResolve #endif // CONFIGURABLE_TYPE_SUPPORT #ifdef HARDCODED_TYPE_SUPPORT void TMultiFieldTypeConfig::setConfig(TFieldListConfig *aFieldList, const char *aTypeName, const char* aTypeVers) { // set field list fFieldListP=aFieldList; // set type name/version if (aTypeName) fTypeName=aTypeName; if (aTypeVers) fTypeVersion=aTypeVers; } // TMultiFieldTypeConfig::setConfig #endif // HARDCODED_TYPE_SUPPORT /* * Implementation of TMultiFieldItemType */ /* public TMultiFieldItemType members */ TMultiFieldItemType::TMultiFieldItemType( TSyncSession *aSessionP, TDataTypeConfig *aTypeConfigP, const char *aCTType, const char *aVerCT, TSyncDataStore *aRelatedDatastoreP, TFieldListConfig *aFieldDefinitions // field definition list ) : TSyncItemType(aSessionP,aTypeConfigP,aCTType,aVerCT,aRelatedDatastoreP) { // save field definition pointer fFieldDefinitionsP = aFieldDefinitions; if (!fFieldDefinitionsP) SYSYNC_THROW(TSyncException(DEBUGTEXT("MultiFieldItemType without fieldDefinitions","mfit1"))); // create options array fFieldOptionsP = new TFieldOptions[fFieldDefinitionsP->numFields()]; // - init default options for (sInt16 i=0; inumFields(); i++) { // by default, all fields in the list are available fFieldOptionsP[i].available=true; // available fFieldOptionsP[i].maxsize= aSessionP->fLimitedRemoteFieldLengths ? FIELD_OPT_MAXSIZE_UNKNOWN : // limited, but unknown length FIELD_OPT_MAXSIZE_NONE; // no known limit fFieldOptionsP[i].maxoccur=0; // maximum occurrence count not defined fFieldOptionsP[i].notruncate=false; // allow truncation by default } } // TMultiFieldItemType::TMultiFieldItemType TMultiFieldItemType::~TMultiFieldItemType() { // remove fields options array delete [] fFieldOptionsP; } // TMultiFieldItemType::~TMultiFieldItemType // compatibility (=assignment compatibility between items based on these types) bool TMultiFieldItemType::isCompatibleWith(TSyncItemType *aReferenceType) { // check compatibility // - reference must be based on TMultiFieldItemType if (!aReferenceType->isBasedOn(ity_multifield)) return false; // - both multifields must be based on same field list return fFieldDefinitionsP == static_cast(aReferenceType)->fFieldDefinitionsP; } // TMultiFieldItemType::isCompatibleWith // Initialize use of datatype with a datastore // Note: This might not affect any datatype-related members, as datatype can // be in use by different datastores at a time. Intitialisation is // performed on members of the datastore (such as fXXXXTypeScriptContextP) void TMultiFieldItemType::initDataTypeUse(TLocalEngineDS *aDatastoreP, bool aForSending, bool aForReceiving) { #ifdef SCRIPT_SUPPORT // Note: identifier situation is equal for all calls of initDataTypeUse, however, // as multiple datastores might use the datatype, several instances of the // context (with separate local var VALUEs) might exist. // Delete old context(s), if any if (aDatastoreP->fSendingTypeScriptContextP && aForSending) { // delete only if actually using this type for sending (otherwise, sending context must be left untouched) delete aDatastoreP->fSendingTypeScriptContextP; aDatastoreP->fSendingTypeScriptContextP=NULL; } if (aDatastoreP->fReceivingTypeScriptContextP && aForReceiving) { // delete only if actually using this type for receiving (otherwise, receiving context must be left untouched) delete aDatastoreP->fReceivingTypeScriptContextP; aDatastoreP->fReceivingTypeScriptContextP=NULL; } // Create contexts in datastore and instantiate variables for scripts TMultiFieldTypeConfig *cfgP = getMultifieldTypeConfig(); // Get context // NOTE: if initialized for both sending and receiving, only the sending // context will be used for both receiving and sending TScriptContext **ctxPP; if (aForSending) // sending or both ctxPP = &aDatastoreP->fSendingTypeScriptContextP; else // only receiving ctxPP = &aDatastoreP->fReceivingTypeScriptContextP; // NOTE: always rebuild all scripts, even though // some might remain unused in the sending or receiving context // This is needed because we don't know at ResolveScript() if a // type will be used for input or output only, and rebuild must // be in the same order as Resolve to guarantee same var/field indexes. // - init script (will be executed right after all scripts are resolved) TScriptContext::rebuildContext(cfgP->getSyncAppBase(),cfgP->fInitScript,*ctxPP,fSessionP); // - incoming and outgoing data brush-ups scripts TScriptContext::rebuildContext(cfgP->getSyncAppBase(),cfgP->fIncomingScript,*ctxPP,fSessionP); TScriptContext::rebuildContext(cfgP->getSyncAppBase(),cfgP->fOutgoingScript,*ctxPP,fSessionP); // - filtering scripts TScriptContext::rebuildContext(cfgP->getSyncAppBase(),cfgP->fFilterInitScript,*ctxPP,fSessionP); TScriptContext::rebuildContext(cfgP->getSyncAppBase(),cfgP->fPostFetchFilterScript,*ctxPP,fSessionP); // - compare and merge scripts #ifdef SYSYNC_SERVER TScriptContext::rebuildContext(cfgP->getSyncAppBase(),cfgP->fCompareScript,*ctxPP,fSessionP); TScriptContext::rebuildContext(cfgP->getSyncAppBase(),cfgP->fMergeScript,*ctxPP,fSessionP); #endif // - special processing of incoming items before they are sent to the DB TScriptContext::rebuildContext(cfgP->getSyncAppBase(),cfgP->fProcessItemScript,*ctxPP,fSessionP,true); // now build vars // Now execute init script // - init the needed member vars fDsP = aDatastoreP; fFirstItemP = NULL; fSecondItemP = NULL; fEqMode = eqm_none; fCurrentSyncOp = sop_none; TScriptContext::execute( *ctxPP, // the context cfgP->fInitScript, // the script &DataTypeFuncTable, // context function table this // context data (myself) ); #endif } // TMultiFieldItemType::initDataTypeUse #ifdef OBJECT_FILTERING // - check if new-style filtering needed void TMultiFieldItemType::initPostFetchFiltering(bool &aNeeded, bool &aNeededForAll, TLocalEngineDS *aDatastoreP) { // init filter and determine if we need any filtering #ifndef SCRIPT_SUPPORT aNeeded=false; aNeededForAll=false; #else fNeedToFilterAll=true; // init member that will be acessed by the script fDsP=aDatastoreP; // set for access from script funcs fFirstItemP = NULL; fSecondItemP = NULL; fEqMode = eqm_none; aNeeded=TScriptContext::executeTest( false, // default to no need for any filters aDatastoreP->fSendingTypeScriptContextP, static_cast(fTypeConfigP)->fFilterInitScript, &DataTypeFuncTable, // context function table this // context data (myself) ); // - copy back script output aNeededForAll=fNeedToFilterAll; if (!aNeeded) aNeededForAll=false; // keep this consistent POBJDEBUGPRINTFX(fSessionP,DBG_FILTER,( "Type-specific postfetch filtering %sneeded%s", aNeeded ? "" : "NOT ", aNeeded ? (aNeededForAll ? " and to be applied to all records" : " only for changed records") : "" )); #endif } // TMultiFieldItemType::initPostFetchFiltering // called by TMultiField::postFetchFiltering() // Checks if to-be-sent item fetched from DB passes all filters to be actually sent to remote bool TMultiFieldItemType::postFetchFiltering(TMultiFieldItem *aItemP, TLocalEngineDS *aDatastoreP) { #ifndef SCRIPT_SUPPORT return true; // no scripts, always pass #else // if no script, always pass string &script = static_cast(fTypeConfigP)->fPostFetchFilterScript; if (script.empty()) return true; // call script to test filter fDsP=aDatastoreP; // set for access from script funcs fFirstItemP = NULL; fSecondItemP = NULL; fEqMode = eqm_none; fCurrentSyncOp = aItemP->getSyncOp(); return TScriptContext::executeTest( false, // default to not passing if filter script fails or returns no value aDatastoreP->fSendingTypeScriptContextP, script, &DataTypeFuncTable, // context function table this, // context data (myself) aItemP, // target item true // can be written if needed ); #endif } // TMultiFieldItemType::postFetchFiltering #endif // check item before processing it bool TMultiFieldItemType::checkItem(TMultiFieldItem &aItem, TLocalEngineDS *aDatastoreP) { #ifndef SCRIPT_SUPPORT return true; // simply ok #else // execute a script if there is a context for it fDsP=aDatastoreP; // set for access from script funcs fFirstItemP = &aItem; fSecondItemP = NULL; fEqMode = eqm_none; fCurrentSyncOp = aItem.getSyncOp(); return TScriptContext::execute( aDatastoreP->fReceivingTypeScriptContextP ? aDatastoreP->fReceivingTypeScriptContextP : aDatastoreP->fSendingTypeScriptContextP, static_cast(fTypeConfigP)->fProcessItemScript, &DataTypeFuncTable, // context function table this, // context data (myself) &aItem, // the item true // checking might change data ); fFirstItemP = NULL; #endif } // TMultiFieldItemType::checkItem #ifdef SYSYNC_SERVER // compare two items sInt16 TMultiFieldItemType::compareItems( TMultiFieldItem &aFirstItem, TMultiFieldItem &aSecondItem, TEqualityMode aEqMode, bool aDebugShow, TLocalEngineDS *aDatastoreP ) { #ifndef SCRIPT_SUPPORT // just do standard compare return aFirstItem.standardCompareWith(aSecondItem,aEqMode,aDebugShow); #else // if no script use standard comparison sInt16 cmpres; string &script = static_cast(fTypeConfigP)->fCompareScript; if (script.empty()) return aFirstItem.standardCompareWith(aSecondItem,aEqMode,aDebugShow); // execute script to perform comparison // - set up helpers fDsP = aDatastoreP; fEqMode = aEqMode; fFirstItemP = &aFirstItem; fSecondItemP = &aSecondItem; fCurrentSyncOp = fDsP->fCurrentSyncOp; TItemField *resP=NULL; bool ok=TScriptContext::executeWithResult( resP, // result will be put here if there is one aDatastoreP->fReceivingTypeScriptContextP ? aDatastoreP->fReceivingTypeScriptContextP : aDatastoreP->fSendingTypeScriptContextP, script, &DataTypeFuncTable, // context function table this, // context data (myself) &aFirstItem, // winning item false, // compare is read-only &aSecondItem, // loosing item false, // compare is read-only !PDEBUGTEST(DBG_MATCH+DBG_EXOTIC) // suppress script debug output unless comparison detail display is on ); // items are no longer available fFirstItemP = NULL; fSecondItemP = NULL; // get result cmpres=SYSYNC_NOT_COMPARABLE; // default to not comparable (if error or no result) if (ok) { if (resP) cmpres=resP->getAsInteger(); } // dispose result field if (resP) delete resP; // return result return cmpres; #endif } // TMultiFieldItemType::compareItems // merge two items void TMultiFieldItemType::mergeItems( TMultiFieldItem &aWinningItem, TMultiFieldItem &aLoosingItem, bool &aChangedWinning, bool &aChangedLoosing, TLocalEngineDS *aDatastoreP, int mode ) { #ifndef SCRIPT_SUPPORT // just do standard merge aWinningItem.standardMergeWith(aLoosingItem,aChangedWinning,aChangedLoosing,mode); return; #else // if no script use standard merging string &script = static_cast(fTypeConfigP)->fMergeScript; if (script.empty()) { aWinningItem.standardMergeWith(aLoosingItem,aChangedWinning,aChangedLoosing,mode); return; } // execute script to perform merge // - set up helpers fDsP = aDatastoreP; fFirstItemP = &aWinningItem; fSecondItemP = &aLoosingItem; fChangedFirst = aChangedWinning; fChangedSecond = aChangedLoosing; fCurrentSyncOp = fDsP->fCurrentSyncOp; fMergeMode = mode; TScriptContext::execute( aDatastoreP->fReceivingTypeScriptContextP ? aDatastoreP->fReceivingTypeScriptContextP : aDatastoreP->fSendingTypeScriptContextP, script, &DataTypeFuncTable, // context function table this, // context data (myself) &aWinningItem, // winning item true, // can be written if needed &aLoosingItem, // loosing item true, // can be written if needed !PDEBUGTEST(DBG_CONFLICT) // script output only if conflict details enabled ); // items are no longer available fFirstItemP = NULL; fSecondItemP = NULL; // get change status back aChangedWinning = fChangedFirst; aChangedLoosing = fChangedSecond; #endif } // TMultiFieldItemType::mergeItems #endif // SYSYNC_SERVER // helper to create same-typed instance via base class TSyncItemType *TMultiFieldItemType::newCopyForSameType( TSyncSession *aSessionP, // the session TSyncDataStore *aDatastoreP // the datastore ) { // create new itemtype of appropriate derived class type that can handle // this type MP_RETURN_NEW(TMultiFieldItemType,DBG_OBJINST,"TMultiFieldItemType",TMultiFieldItemType(aSessionP,fTypeConfigP,getTypeName(),getTypeVers(),aDatastoreP,fFieldDefinitionsP)); } // TMultiFieldItemType::newCopyForSameType /// @brief copy CTCap derived info from another SyncItemType /// @return false if item not compatible /// @note required to create remote type variants from ruleMatch type alternatives bool TMultiFieldItemType::copyCTCapInfoFrom(TSyncItemType &aSourceItem) { // must be based on same type as myself and have the same fieldlist if (!aSourceItem.isBasedOn(getTypeID())) return false; // not compatible TMultiFieldItemType *itemTypeP = static_cast(&aSourceItem); if (fFieldDefinitionsP!=itemTypeP->fFieldDefinitionsP) return false; // not compatible // both have the same fFieldDefinitionsP, so both option arrays have the same size // - we can copy the options 1:1 for (sInt16 i=0; inumFields(); i++) { // by default, all fields in the list are available fFieldOptionsP[i] = itemTypeP->fFieldOptionsP[i]; } // other CTCap info is in the field options of MultiFieldItemType return inherited::copyCTCapInfoFrom(aSourceItem); } // TMultiFieldItemType::copyCTCapInfoFrom // apply default limits to type (e.g. from hard-coded template in config) void TMultiFieldItemType::addDefaultTypeLimits(void) { #ifdef HARDCODED_TYPE_SUPPORT // get default type settings from field list template if (fFieldDefinitionsP && fFieldDefinitionsP->fFieldListTemplateP) { // copy options from field list template for (sInt16 i=0; ifFieldListTemplateP->numFields; i++) { // get options TFieldOptions *optP = getFieldOptions(i); // transfer limits if not already defined // - max field size if (optP->maxsize==FIELD_OPT_MAXSIZE_NONE) optP->maxsize=fFieldDefinitionsP->fFieldListTemplateP->fieldDefs[i].maxSize; // - notruncate option if (!optP->notruncate) optP->notruncate=fFieldDefinitionsP->fFieldListTemplateP->fieldDefs[i].noTruncate; } } #endif } // TMultiFieldItemType::addDefaultTypeLimits // access to fields by name (returns FID_NOT_SUPPORTED if field not found) sInt16 TMultiFieldItemType::getFieldIndex(const char *aFieldName) { for (sInt16 i=0; inumFields(); i++) { if (strucmp(aFieldName,fFieldDefinitionsP->fFields[i].TCFG_CSTR(fieldname))==0) return i; // found } return FID_NOT_SUPPORTED; // not found } // TMultiFieldItemType::getFieldIndex bool TMultiFieldItemType::isFieldIndexValid(sInt16 aFieldIndex) { return (aFieldIndex>=0 && aFieldIndexnumFields()); } // TMultiFieldItemType::isFieldIndexValid // access to field options (returns NULL if field not found) TFieldOptions *TMultiFieldItemType::getFieldOptions(sInt16 aFieldIndex) { if (!isFieldIndexValid(aFieldIndex)) return NULL; return &(fFieldOptionsP[aFieldIndex]); } // TMultiFieldItemType::getFieldOptions // test if item could contain cut-off data (e.g. because of field size restrictions) // compared to specified reference item // NOTE: if no reference item is specified, any occurrence of a // size-limited field will signal possible cutoff bool TMultiFieldItemType::mayContainCutOffData(TSyncItemType *aReferenceType) { TMultiFieldItemType *refP=NULL; if (aReferenceType->isBasedOn(ity_multifield)) refP=static_cast(aReferenceType); for (sInt16 i=0; inumFields(); i++) { sInt32 refsize,mysize; mysize = getFieldOptions(i)->maxsize; if (refP) refsize = refP->getFieldOptions(i)->maxsize; else refsize = FIELD_OPT_MAXSIZE_NONE; // assume no limit // now sort out cases: cutOff data can happen if if ( // - this field is somehow limited && reference field is unlimited or limited, but unknown (mysize!=FIELD_OPT_MAXSIZE_NONE && (refsize<=0)) || // - this field has smaller size than reference field (mysize0 && refsize>0) ) { // field could contain cut-off data (when conataining data from reference type) return true; } } // no field limits detected, no cutoff return false; } // TMultiFieldItemType::mayContainCutOffData // fill in SyncML data (but leaves IDs empty) // Note: for MultiFieldItem, this is for post-processing data (FieldFillers) bool TMultiFieldItemType::internalFillInData( TSyncItem *aSyncItemP, // SyncItem to be filled with data SmlItemPtr_t aItemP, // SyncML toolkit item Data to be converted into SyncItem (may be NULL if no data, in case of Delete or Map) TLocalEngineDS *aLocalDatastoreP, // local datastore TStatusCommand &aStatusCmd // status command that might be modified in case of error ) { #if defined(SCRIPT_SUPPORT) // check type TMultiFieldItem *itemP; GET_CASTED_PTR(itemP,TMultiFieldItem,aSyncItemP,DEBUGTEXT("TMultiFieldItemType::internalFillInData: incompatible item class","mfit2")); #endif #ifdef SCRIPT_SUPPORT // post-process data: apply incoming script // - init the needed member vars fDsP = aLocalDatastoreP; fFirstItemP = itemP; fSecondItemP = NULL; fEqMode = eqm_none; fCurrentSyncOp = itemP->getSyncOp(); TScriptContext::execute( aLocalDatastoreP->fReceivingTypeScriptContextP ? aLocalDatastoreP->fReceivingTypeScriptContextP : // separate context for receiving, use it aLocalDatastoreP->fSendingTypeScriptContextP, // send and receive use same context (sending one) static_cast(fTypeConfigP)->fIncomingScript, &DataTypeFuncTable, this, itemP, true, NULL, false, !PDEBUGTEST(DBG_PARSE) ); fFirstItemP = NULL; #endif // - do NOT call ancestor (it's a dummy for types w/o implementation returning false) // can't go wrong return true; } // TMultiFieldItemType::internalFillInData // sets data and meta from SyncItem data, but leaves source & target untouched // Note: for MultiFieldItem, this is for pre-processing data (FieldFillers) bool TMultiFieldItemType::internalSetItemData( TSyncItem *aSyncItemP, // the syncitem to be represented as SyncML SmlItemPtr_t aItem, // item with NULL meta and NULL data TLocalEngineDS *aLocalDatastoreP // local datastore ) { #if defined(SCRIPT_SUPPORT) // check type TMultiFieldItem *itemP; GET_CASTED_PTR(itemP,TMultiFieldItem,aSyncItemP,DEBUGTEXT("TMultiFieldItemType::internalSetItemData: incompatible item class","mdit8")); // do NOT call ancestor (it's a dummy for types w/o implementation returning false) #endif #ifdef SCRIPT_SUPPORT // pre-process data: apply outgoing script // - init the needed member vars fDsP = aLocalDatastoreP; fFirstItemP = itemP; fSecondItemP = NULL; fEqMode = eqm_none; fCurrentSyncOp = itemP->getSyncOp(); return TScriptContext::execute( aLocalDatastoreP->fSendingTypeScriptContextP, static_cast(fTypeConfigP)->fOutgoingScript, &DataTypeFuncTable, this, itemP, true, NULL, false, !PDEBUGTEST(DBG_GEN) ); fFirstItemP = NULL; #else // can't go wrong return true; #endif } // TMultiFieldItemType::internalSetItemData } // namespace sysync /* end of TMultiFieldItemType implementation */ // eof libsynthesis-3.4.0.47.1/src/sysync/multifielditemtype.h000077500000000000000000000232441226375725500230630ustar00rootroot00000000000000/* * File: MultiFieldItemType.h * * Author: Lukas Zeller (luz@plan44.ch) * * TMultiFieldItemType * Type consisting of multiple data fields (TItemField objects) * To be used as base class for field formats like vCard, * vCalendar etc. * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * 2001-08-13 : luz : created * */ #ifndef MultiFieldItemType_H #define MultiFieldItemType_H // includes #include "syncitemtype.h" #include "multifielditem.h" #include "scriptcontext.h" using namespace sysync; namespace sysync { // special field IDs #define FID_NOT_SUPPORTED -128 // no field-ID #if defined(VARIDX_UNDEFINED) && FID_NOT_SUPPORTED!=VARIDX_UNDEFINED #error "FID_NOT_SUPPORTED must be the same as VARIDX_UNDEFINED" #endif // special field offsets #define OFFS_NOSTORE -9999 // offset meaning "do not store" // special repeat counts #define REP_REWRITE 0 // unlimited repeating, but later occurrences overwrite previous ones #define REP_ARRAY 32767 // virtually unlimited repeating, should be used with array fields only // default profile mode (devivates might define their own) #define PROFILEMODE_DEFAULT 0 // default mode of the profile, usually MIME-DIR // type-instance specific options (there can be multiple // TSyncItemType instances with the same TFieldListConfig, // but different sets of field options, e.g. different // versions of the same content type where one has fewer // fields implemented, or server and client types with // differing sets of available fields) #define FIELD_OPT_MAXSIZE_UNKNOWN -1 #define FIELD_OPT_MAXSIZE_NONE 0 typedef struct { bool available; // set if field is available in this type sInt32 maxsize; // maximum field length, FIELD_OPT_MAXSIZE_NONE=none, FIELD_OPT_MAXSIZE_UNKNOWN=limited, but unknown bool notruncate; // set if type doesn't want to get truncated values for this field from remote sInt32 maxoccur; // maximum number of repetitions of properties based on this field } TFieldOptions; // multi-field based datatype class TMultiFieldTypeConfig : public TDataTypeConfig { typedef TDataTypeConfig inherited; public: TMultiFieldTypeConfig(const char *aElementName, TConfigElement *aParentElementP); virtual ~TMultiFieldTypeConfig(); // properties // - associated field list config (normally set from derived type) TFieldListConfig *fFieldListP; // - associated profile TProfileConfig *fProfileConfigP; // - mode for profile sInt32 fProfileMode; #ifdef SCRIPT_SUPPORT // - scripts string fInitScript; // executed once per usage by a datastore string fIncomingScript; // script that is executed after receiving item string fOutgoingScript; // script that is executed just before sending item string fFilterInitScript; // script that is executed once per session when filter params are all available. Must return true if something to filter at all string fPostFetchFilterScript; // script that is executed after item is fetched from DB. Must return true if item passes string fCompareScript; // script that is executed to compare items string fMergeScript; // script that is executed to merge items string fProcessItemScript; // script that is executed to decide what to do with an incoming item #endif #ifdef HARDCODED_TYPE_SUPPORT void setConfig(TFieldListConfig *aFieldList, const char *aTypeName, const char* aTypeVers); #endif protected: #ifdef CONFIGURABLE_TYPE_SUPPORT // check config elements virtual bool localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine); virtual void localResolve(bool aLastPass); #endif virtual void clear(); }; // TMultiFieldTypeConfig class TMultiFieldItemType: public TSyncItemType { typedef TSyncItemType inherited; public: TMultiFieldItemType( TSyncSession *aSessionP, TDataTypeConfig *aTypeConfigP, const char *aCTType, const char *aVerCT, TSyncDataStore *aRelatedDatastoreP, TFieldListConfig *aFieldDefinitions // field definition list ); virtual ~TMultiFieldItemType(); // access to type virtual uInt16 getTypeID(void) const { return ity_multifield; }; virtual bool isBasedOn(uInt16 aItemTypeID) const { return aItemTypeID==ity_multifield ? true : TSyncItemType::isBasedOn(aItemTypeID); }; // differentiation between implemented and just descriptive TSyncTypeItems virtual bool isImplemented(void) { return true; }; // MultiFields are implemented // compatibility (=assignment compatibility between items based on these types) virtual bool isCompatibleWith(TSyncItemType *aReferenceType); // test if item could contain cut-off data (e.g. because of field size restrictions) // compared to specified reference item virtual bool mayContainCutOffData(TSyncItemType *aReferenceType); // helper to create same-typed instance via base class // MUST BE IMPLEMENTED IN ALL non-virtual DERIVED CLASSES! virtual TSyncItemType *newCopyForSameType( TSyncSession *aSessionP, // the session TSyncDataStore *aDatastoreP // the datastore ); /// @brief copy CTCap derived info from another SyncItemType virtual bool copyCTCapInfoFrom(TSyncItemType &aSourceItemP); // apply default limits to type (e.g. from hard-coded template in config) virtual void addDefaultTypeLimits(void); // get config pointer TMultiFieldTypeConfig *getMultifieldTypeConfig(void) { return static_cast(fTypeConfigP); }; // access field definitions TFieldListConfig *getFieldDefinitions(void) { return fFieldDefinitionsP; }; // access to fields by name (returns -1 if field not found) sInt16 getFieldIndex(const char *aFieldName); bool isFieldIndexValid(sInt16 aFieldIndex); // access to field options (returns NULL if field not found) TFieldOptions *getFieldOptions(sInt16 aFieldIndex); TFieldOptions *getFieldOptions(const char *aFieldName) { return getFieldOptions(getFieldIndex(aFieldName)); }; virtual bool hasReceivedFieldOptions(void) { return false; }; // returns true if field options are based on remote devinf (and not just defaults) // access to field definitions TFieldDefinition *getFieldDefinition(sInt16 aFieldIndex) { if (fFieldDefinitionsP) return &(fFieldDefinitionsP->fFields[aFieldIndex]); else return NULL; } // Prepare datatype for use with a datastore. This might be implemented // in derived classes to initialize the datastore's script context etc. virtual void initDataTypeUse(TLocalEngineDS *aDatastoreP, bool aForSending, bool aForReceiving); #ifdef OBJECT_FILTERING // new style generic filtering // - init new-style filtering, returns flag if needed at all virtual void initPostFetchFiltering(bool &aNeeded, bool &aNeededForAll, TLocalEngineDS *aDatastoreP); // - do the actual filtering bool postFetchFiltering(TMultiFieldItem *aItemP, TLocalEngineDS *aDatastoreP); // old style expression filtering // - get field index of given filter expression identifier. Note that // derived classes might first check for MIME property names etc. virtual sInt16 getFilterIdentifierFieldIndex(const char *aIdentifier, uInt16 aIndex) { return getFieldIndex(aIdentifier); }; // base class just handles field names #endif // comparing and merging sInt16 compareItems(TMultiFieldItem &aFirstItem, TMultiFieldItem &aSecondItem, TEqualityMode aEqMode, bool aDebugShow, TLocalEngineDS *aDatastoreP); void mergeItems( TMultiFieldItem &aWinningItem, TMultiFieldItem &aLoosingItem, bool &aChangedWinning, bool &aChangedLoosing, TLocalEngineDS *aDatastoreP, int mode //< MERGE_OPTION_* ); // check item before processing it bool checkItem(TMultiFieldItem &aItem, TLocalEngineDS *aDatastoreP); protected: // Item data management // - create new sync item of proper type and optimization for specified target /* MultiFields are only a base class and lack implementation of the following: virtual TSyncItem *internalNewSyncItem(TSyncItemType *aTargetItemTypeP, TLocalEngineDS *aLocalDatastoreP); */ // - fill in SyncML data (but leaves IDs empty) // Note: for MultiFieldItem, this is for post-processing data (FieldFillers) virtual bool internalFillInData( TSyncItem *aSyncItemP, // SyncItem to be filled with data SmlItemPtr_t aItemP, // SyncML toolkit item Data to be converted into SyncItem (may be NULL if no data, in case of Delete or Map) TLocalEngineDS *aLocalDatastoreP, // local datastore TStatusCommand &aStatusCmd // status command that might be modified in case of error ); // - sets data and meta from SyncItem data, but leaves source & target untouched // Note: for MultiFieldItem, this is for pre-processing data (FieldFillers) virtual bool internalSetItemData( TSyncItem *aSyncItemP, // the syncitem to be represented as SyncML SmlItemPtr_t aItem, // item with NULL meta and NULL data TLocalEngineDS *aLocalDatastoreP // local datastore ); // field definition list pointer TFieldListConfig *fFieldDefinitionsP; public: // temporary variables needed by filter script context funcs bool fNeedToFilterAll; // need to filter all records, even not-changed ones (dynamic syncset) #ifdef SCRIPT_SUPPORT TLocalEngineDS *fDsP; // helper for script context funcs TMultiFieldItem *fFirstItemP; // helper for script context funcs TMultiFieldItem *fSecondItemP; // helper for script context funcs bool fChangedFirst; // helper for script context funcs bool fChangedSecond; // helper for script context funcs TEqualityMode fEqMode; // helper for script context funcs TSyncOperation fCurrentSyncOp; // helper for script context funcs int fMergeMode; // helper for script context funcs #endif private: // array of field options TFieldOptions *fFieldOptionsP; }; // TMultiFieldItemType } // namespace sysync #endif // MultiFieldItemType_H // eof libsynthesis-3.4.0.47.1/src/sysync/rawdataitemtype.cpp000066400000000000000000000176161226375725500227060ustar00rootroot00000000000000/* * File: rawdataitemtype.cpp * * Author: Lukas Zeller (luz@plan44.ch) * * TRawDataItemType * Item type for 1:1 raw items (SyncML payload is exchanged 1:1 with database backend) * * Copyright (c) 2010 by Synthesis AG (www.synthesis.ch) * * 2010-05-14 : luz : created * */ // includes #include "prefix_file.h" #include "sysync.h" #include "rawdataitemtype.h" using namespace sysync; namespace sysync { // Config // ====== // MIMEDir-based datatype config TRawDataTypeConfig::TRawDataTypeConfig(const char* aName, TConfigElement *aParentElement) : TMultiFieldTypeConfig(aName,aParentElement) { clear(); } // TRawDataTypeConfig::TRawDataTypeConfig TRawDataTypeConfig::~TRawDataTypeConfig() { clear(); } // TRawDataTypeConfig::~TRawDataTypeConfig // init defaults void TRawDataTypeConfig::clear(void) { // clear FIDs fFidItemData = FID_NOT_SUPPORTED; // clear inherited inherited::clear(); } // TRawDataTypeConfig::clear // resolve dependencies void TRawDataTypeConfig::localResolve(bool aLastPass) { if (aLastPass) { // get FIDs of the fields we directly use // - the "ITEMDATA" field containing the raw item data fFidItemData = getFieldIndex("ITEMDATA",fFieldListP); if (fFidItemData==FID_NOT_SUPPORTED) goto missingfield; // %%% add more FID searches (and checks, if the field is mandatory) here } // resolve inherited inherited::localResolve(aLastPass); return; missingfield: SYSYNC_THROW(TConfigParseException("fieldlist for RawDataItem must contain certain predefined fields (like ITEMDATA)!")); } // TRawDataTypeConfig::localResolve // create Sync Item Type of appropriate type from config TSyncItemType *TRawDataTypeConfig::newSyncItemType(TSyncSession *aSessionP, TSyncDataStore *aDatastoreP) { return new TRawDataItemType( aSessionP, this, fTypeName.c_str(), fTypeVersion.c_str(), aDatastoreP, fFieldListP ); } // TRawDataTypeConfig::newSyncItemType #ifdef CONFIGURABLE_TYPE_SUPPORT // config element parsing bool TRawDataTypeConfig::localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine) { // checking the elements // - none known here return TMultiFieldTypeConfig::localStartElement(aElementName,aAttributes,aLine); // ok return true; } // TRawDataTypeConfig::localStartElement #endif /* * Implementation of TRawDataItemType */ TRawDataItemType::TRawDataItemType( TSyncSession *aSessionP, TDataTypeConfig *aTypeConfigP, const char *aCTType, const char *aVerCT, TSyncDataStore *aRelatedDatastoreP, TFieldListConfig *aFieldDefinitions // field definitions ) : TMultiFieldItemType(aSessionP,aTypeConfigP,aCTType,aVerCT,aRelatedDatastoreP,aFieldDefinitions) { fCfgP = static_cast(aTypeConfigP); } // TRawDataItemType::TRawDataItemType TRawDataItemType::~TRawDataItemType() { } // TRawDataItemType::~TRawDataItemType // create new sync item of proper type and optimization for specified target TSyncItem *TRawDataItemType::internalNewSyncItem(TSyncItemType *aTargetItemTypeP, TLocalEngineDS *aLocalDatastoreP) { // All RawDataItems are stored in MultiFieldItems (in specific, predefined fields) TMultiFieldItemType *targetitemtypeP; GET_CASTED_PTR(targetitemtypeP,TMultiFieldItemType,aTargetItemTypeP,DEBUGTEXT("TRawDataItemType::internalNewSyncItem with bad-typed target","mdit6")); MP_RETURN_NEW(TMultiFieldItem,DBG_OBJINST,"TMultiFieldItem",TMultiFieldItem(this,targetitemtypeP)); } // TRawDataItemType::internalNewSyncItem // fill in SyncML data (but leaves IDs empty) bool TRawDataItemType::internalFillInData( TSyncItem *aSyncItemP, // SyncItem to be filled with data SmlItemPtr_t aItemP, // SyncML toolkit item Data to be converted into SyncItem (may be NULL if no data, in case of Delete or Map) TLocalEngineDS *aLocalDatastoreP, // local datastore TStatusCommand &aStatusCmd // status command that might be modified in case of error ) { // check type TMultiFieldItem *itemP; GET_CASTED_PTR(itemP,TMultiFieldItem,aSyncItemP,DEBUGTEXT("TRawDataItemType::internalFillInData: incompatible item class","mdit7")); // store data, if any, in predefined ITEMDATA field if (aItemP->data) { // read data into predefined raw data field TItemField *fldP = itemP->getField(fCfgP->fFidItemData); if (fldP) { // get raw data stringSize sz; cAppCharP data = smlPCDataToCharP(aItemP->data,&sz); // put it into ITEMDATA field fldP->setAsString(data, sz); } } else { // no data aStatusCmd.setStatusCode(412); // incomplete command ADDDEBUGITEM(aStatusCmd,"No data found in item"); return false; } // let ancestor process data as well return TMultiFieldItemType::internalFillInData(aSyncItemP,aItemP,aLocalDatastoreP,aStatusCmd); } // TRawDataItemType::internalFillInData // sets data and meta from SyncItem data, but leaves source & target untouched bool TRawDataItemType::internalSetItemData( TSyncItem *aSyncItemP, // the syncitem to be represented as SyncML SmlItemPtr_t aItem, // item with NULL meta and NULL data TLocalEngineDS *aLocalDatastoreP // local datastore ) { // check type TMultiFieldItem *itemP; GET_CASTED_PTR(itemP,TMultiFieldItem,aSyncItemP,DEBUGTEXT("TRawDataItemType::internalSetItemData: incompatible item class","mdit8")); // let ancestor prepare first if (!TMultiFieldItemType::internalSetItemData(aSyncItemP,aItem,aLocalDatastoreP)) return false; // generate data item from predefined ITEMDATA field TItemField *fldP = itemP->getField(fCfgP->fFidItemData); if (fldP) { string dataitem; if (fldP->isBasedOn(fty_blob)) { // is a BLOB, don't use getAsString as BLOB only returns pseudo-data indicating length of BLOB ((TBlobField *)fldP)->getBlobAsString(dataitem); } else { // for all other types, just get it as string fldP->getAsString(dataitem); } // put data item into opaque/cdata PCData aItem->data=newPCDataStringX((const uInt8 *)dataitem.c_str(),true,dataitem.size()); } // can't go wrong return true; } // TRawDataItemType::internalSetItemData // generates SyncML-Devinf property list for type SmlDevInfCTDataPropListPtr_t TRawDataItemType::newCTDataPropList(TTypeVariantDescriptor aVariantDescriptor) { // return supported properties //#warning "TODO create this list from some configuration data" return NULL; // %%% for now: none } // Analyze CTCap part of devInf bool TRawDataItemType::analyzeCTCap(SmlDevInfCTCapPtr_t aCTCapP) { // no analysis so far // TODO: maybe add mechanism to capture CTCap here and pass it to the DB backend in a predefined field for analysis return inherited::analyzeCTCap(aCTCapP); } /// @brief helper to create same-typed instance via base class TSyncItemType *TRawDataItemType::newCopyForSameType( TSyncSession *aSessionP, // the session TSyncDataStore *aDatastoreP // the datastore ) { // create new itemtype of appropriate derived class type that can handle // this type MP_RETURN_NEW(TRawDataItemType,DBG_OBJINST,"TRawDataItemType",TRawDataItemType( aSessionP, fTypeConfigP, getTypeName(), getTypeVers(), aDatastoreP, fFieldDefinitionsP )); } // TRawDataItemType::newCopyForSameType /// @brief copy CTCap derived info from another SyncItemType /// @return false if item not compatible /// @note required to create remote type variants from ruleMatch type alternatives bool TRawDataItemType::copyCTCapInfoFrom(TSyncItemType &aSourceItem) { // must be same type as myself or based on the type of myself if (!aSourceItem.isBasedOn(getTypeID())) return false; // not compatible //TRawDataItemType *itemTypeP = static_cast(&aSourceItem); // all CTCap info we might have is in the field options of MultiFieldItemType return inherited::copyCTCapInfoFrom(aSourceItem); } // TRawDataItemType::copyCTCapInfoFrom /* end of TRawDataItemType implementation */ } // namespace sysync // eof libsynthesis-3.4.0.47.1/src/sysync/rawdataitemtype.h000066400000000000000000000077241226375725500223520ustar00rootroot00000000000000/* * File: rawdataitemtype.h * * Author: Lukas Zeller (luz@plan44.ch) * * TRawDataItemType * Item type for 1:1 raw items (SyncML payload is exchanged 1:1 with database backend) * * Copyright (c) 2010 by Synthesis AG (www.synthesis.ch) * * 2010-05-14 : luz : created * */ #ifndef RawDataItemType_H #define RawDataItemType_H // includes #include "syncitemtype.h" #include "multifielditemtype.h" namespace sysync { // MIME-dir based datatype class TRawDataTypeConfig : public TMultiFieldTypeConfig { typedef TMultiFieldTypeConfig inherited; public: TRawDataTypeConfig(const char *aElementName, TConfigElement *aParentElementP); virtual ~TRawDataTypeConfig(); // properties // public functions // - create Sync Item Type of appropriate type from config virtual TSyncItemType *newSyncItemType(TSyncSession *aSessionP, TSyncDataStore *aDatastoreP); protected: #ifdef CONFIGURABLE_TYPE_SUPPORT // check config elements virtual bool localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine); #endif virtual void localResolve(bool aLastPass); virtual void clear(); public: // FIDs of the predefined fields we need to access sInt16 fFidItemData; // BLOB or string field that will contain item // %%% add more FID vars here }; // TRawDataTypeConfig const uInt16 ity_rawdata=90; // must be unique class TRawDataItemType: public TMultiFieldItemType { typedef TMultiFieldItemType inherited; friend class TMimeDirProfileHandler; public: // constructor TRawDataItemType( TSyncSession *aSessionP, TDataTypeConfig *aTypeConfigP, const char *aCTType, const char *aVerCT, TSyncDataStore *aRelatedDatastoreP, TFieldListConfig *aFieldDefinitions // field definitions ); // destructor virtual ~TRawDataItemType(); // access to type virtual uInt16 getTypeID(void) const { return ity_rawdata; }; virtual bool isBasedOn(uInt16 aItemTypeID) const { return aItemTypeID==ity_rawdata ? true : inherited::isBasedOn(aItemTypeID); }; // differentiation between implemented and just descriptive TSyncTypeItems virtual bool isImplemented(void) { return true; }; // RawItem is an implementati on // helper to create same-typed instance via base class // MUST BE IMPLEMENTED IN ALL DERIVED CLASSES! virtual TSyncItemType *newCopyForSameType( TSyncSession *aSessionP, // the session TSyncDataStore *aDatastoreP // the datastore ); protected: // CTCap parsing/generation // - analyze CTCap for specific type virtual bool analyzeCTCap(SmlDevInfCTCapPtr_t aCTCapP); /// @brief copy CTCap derived info from another SyncItemType virtual bool copyCTCapInfoFrom(TSyncItemType &aSourceItemP); // - obtain property list for type, returns NULL if none available virtual SmlDevInfCTDataPropListPtr_t newCTDataPropList(TTypeVariantDescriptor aVariantDescriptor); // Item data management // - create new sync item of proper type and optimization for specified target virtual TSyncItem *internalNewSyncItem(TSyncItemType *aTargetItemTypeP, TLocalEngineDS *aLocalDatastoreP); // - fill in SyncML data (but leaves IDs empty) virtual bool internalFillInData( TSyncItem *aSyncItemP, // SyncItem to be filled with data SmlItemPtr_t aItemP, // SyncML toolkit item Data to be converted into SyncItem (may be NULL if no data, in case of Delete or Map) TLocalEngineDS *aLocalDatastoreP, // local datastore TStatusCommand &aStatusCmd // status command that might be modified in case of error ); // - sets data and meta from SyncItem data, but leaves source & target untouched virtual bool internalSetItemData( TSyncItem *aSyncItemP, // the syncitem to be represented as SyncML SmlItemPtr_t aItem, // item with NULL meta and NULL data TLocalEngineDS *aLocalDatastoreP // local datastore ); private: // convenience casted pointer to my config TRawDataTypeConfig *fCfgP; }; // TRawDataItemType } // namespace sysync #endif // RawDataItemType_H // eof libsynthesis-3.4.0.47.1/src/sysync/remotedatastore.cpp000077500000000000000000000233761226375725500227070ustar00rootroot00000000000000/* * File: RemoteDataStore.cpp * * Author: Lukas Zeller (luz@plan44.ch) * * TRemoteDataStore * Abstraction of remote data store for SyncML Server * Buffers and forwards incoming remote data store commands for * processing by sync engine. * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * 2001-06-12 : luz : created * */ // includes #include "prefix_file.h" #include "sysync.h" #include "syncagent.h" #include "remotedatastore.h" using namespace sysync; /* * Implementation of TRemoteDataStore */ void TRemoteDataStore::init(void) { // nop so far } // TSyncDataStore::init void TRemoteDataStore::InternalResetDataStore(void) { // for server, get default GUID size (in case remote devInf does not send one) #ifdef SYSYNC_SERVER if (IS_SERVER) { fMaxGUIDSize = static_cast(getSession()->getSessionConfig())->fMaxGUIDSizeSent; } #endif } // TRemoteDataStore::InternalResetDataStore TRemoteDataStore::TRemoteDataStore(TSyncSession *aSessionP) : TSyncDataStore(aSessionP) { // nop so far } // TSyncDataStore::TSyncDataStore TRemoteDataStore::TRemoteDataStore( TSyncSession *aSessionP, const char *aName, uInt32 aCommonSyncCapMask ) : TSyncDataStore(aSessionP, aName, aCommonSyncCapMask) { // assume full name same as real name, but could be updated at or fFullName=aName; } // TSyncDataStore::TSyncDataStore TRemoteDataStore::~TRemoteDataStore() { InternalResetDataStore(); // nop so far } // TRemoteDataStore::~TRemoteDataStore // - return pure relative (item) URI (removes absolute part or ./ prefix) const char *TRemoteDataStore::DatastoreRelativeURI(const char *aURI) { return relativeURI(aURI,fSessionP->getRemoteURI()); } // TRemoteDataStore::DatastoreRelativeURI // check if this remote datastore is accessible with given URI // NOTE: URI might include path elements or CGI params that are // access options to the database. // Remote datastores however only represent devinf, so // it counts as name match if start of specified URI matches // name and then continues with "/" or "?" (subpaths and CGI ignored) uInt16 TRemoteDataStore::isDatastore(const char *aDatastoreURI) { // - make pure relative paths const char *nam=DatastoreRelativeURI(fName.c_str()); size_t n=strlen(nam); const char *uri=DatastoreRelativeURI(aDatastoreURI); // - compare up to end of local name if (strucmp(nam,uri,n,n)==0) { // beginnig matches. char c=uri[n]; // terminating char // match if full match, or uri continues with '/' or '?' // Note: return number of chars matched, to allow search for best match return (c==0 || c=='/' || c=='?') ? n : 0; } else return 0; // no match } // TRemoteDataStore::isDatastore // SYNC command bracket start (check credentials if needed) bool TRemoteDataStore::remoteProcessSyncCmd( SmlSyncPtr_t aSyncP, // the Sync element TStatusCommand &aStatusCommand, // status that might be modified bool &aQueueForLater // will be set if command must be queued for later (re-)execution ) { // adjust name of datastore (may include subpath or CGI) fFullName = smlSrcTargLocURIToCharP(aSyncP->source); // read meta of Sync Command for remote datastore // NOTE: this will overwrite Max values possibly read from DevInf // as meta is more accurate (actual free bytes/ids, not total) SmlMetInfMetInfPtr_t metaP = smlPCDataToMetInfP(aSyncP->meta); if (metaP) { if (metaP->mem) { // - max free bytes if (metaP->mem->free) if (!StrToLongLong(smlPCDataToCharP(metaP->mem->free),fFreeMemory)) return false; // - maximum ID if (metaP->mem->freeid) if (!StrToLongLong(smlPCDataToCharP(metaP->mem->freeid),fFreeID)) return false; } PDEBUGPRINTFX(DBG_REMOTEINFO,("Sync Meta provides memory constraints: FreeMem=" PRINTF_LLD ", FreeID=" PRINTF_LLD,PRINTF_LLD_ARG(fFreeMemory),PRINTF_LLD_ARG(fFreeID))); } return true; } // TRemoteDataStore::remoteProcessSyncCmd // SYNC command bracket end (but another might follow in next message) bool TRemoteDataStore::remoteProcessSyncCmdEnd(void) { // %%% nop for now, %%% possibly obsolete return true; } // TRemoteDataStore::remoteProcessSyncCmdEnd // end of all sync commands from client bool TRemoteDataStore::endOfClientSyncCmds(void) { // %%% nop for now, %%% possibly obsolete return true; } // TRemoteDataStore::endOfClientSyncCmds // set description structure of datastore bool TRemoteDataStore::setDatastoreDevInf( SmlDevInfDatastorePtr_t aDataStoreDevInfP, // the datastore DevInf TSyncItemTypePContainer &aLocalItemTypes, // list to look up local types (for reference) TSyncItemTypePContainer &aNewItemTypes // list to add analyzed types if not already there ) { // get important info out of the structure SYSYNC_TRY { // - name (sourceRef) fName=smlPCDataToCharP(aDataStoreDevInfP->sourceref); #ifndef MINIMAL_CODE // - displayname fDisplayName=smlPCDataToCharP(aDataStoreDevInfP->displayname); #endif // - MaxGUIDsize if (aDataStoreDevInfP->maxguidsize) { if (!StrToLong(smlPCDataToCharP(aDataStoreDevInfP->maxguidsize),fMaxGUIDSize)) return false; } else { PDEBUGPRINTFX(DBG_REMOTEINFO,("Datastore DevInf does not specify MaxGUIDSize -> using default")); } PDEBUGPRINTFX(DBG_REMOTEINFO+DBG_HOT,( "Remote Datastore Name='%s', DisplayName='%s', MaxGUIDSize=%ld", getName(), getDisplayName(), (long)fMaxGUIDSize )); PDEBUGPRINTFX(DBG_REMOTEINFO,( "Preferred Rx='%s' version '%s', preferred Tx='%s' version '%s'", smlPCDataToCharP(aDataStoreDevInfP->rxpref->cttype), smlPCDataToCharP(aDataStoreDevInfP->rxpref->verct), smlPCDataToCharP(aDataStoreDevInfP->txpref->cttype), smlPCDataToCharP(aDataStoreDevInfP->txpref->verct) )); // - analyze DS 1.2 style datastore local CTCap if (getSession()->getSyncMLVersion()>=syncml_vers_1_2) { // analyze CTCaps (content type capabilities) SmlDevInfCtcapListPtr_t ctlP = aDataStoreDevInfP->ctcap; // loop through list PDEBUGBLOCKDESC("RemoteTypes", "Analyzing remote types listed in datastore level CTCap"); if (getSession()->fIgnoreCTCap) { // ignore CTCap if (ctlP) { PDEBUGPRINTFX(DBG_REMOTEINFO+DBG_HOT,("Remote rule prevents looking at CTCap")); } } else { while (ctlP) { if (ctlP->data) { // create appropriate remote data itemtypes if (TSyncItemType::analyzeCTCapAndCreateItemTypes( getSession(), this, // this is the DS1.2 style where CTCap is related to this datastore ctlP->data, // CTCap aLocalItemTypes, // look up in local types for specialized classes aNewItemTypes // add new item types here )) { // we have CTCap info of at least one remote type getSession()->fRemoteDataTypesKnown=true; } else return false; } // - go to next item ctlP=ctlP->next; } // while } PDEBUGENDBLOCK("RemoteTypes"); } // if >=DS1.2 // - analyze supported rx types TSyncDataStore *relDsP = getSession()->getSyncMLVersion()>=syncml_vers_1_2 ? this : NULL; fRxPrefItemTypeP=TSyncItemType::registerRemoteType(fSessionP,aDataStoreDevInfP->rxpref,aLocalItemTypes,aNewItemTypes,relDsP); fRxItemTypes.push_back(fRxPrefItemTypeP); registerTypes(fRxItemTypes,aDataStoreDevInfP->rx,aLocalItemTypes,aNewItemTypes,relDsP); // - analyze supported tx types fTxPrefItemTypeP=TSyncItemType::registerRemoteType(fSessionP,aDataStoreDevInfP->txpref,aLocalItemTypes,aNewItemTypes,relDsP); fTxItemTypes.push_back(fTxPrefItemTypeP); registerTypes(fTxItemTypes,aDataStoreDevInfP->tx,aLocalItemTypes,aNewItemTypes,relDsP); // - Datastore Memory if (aDataStoreDevInfP->dsmem) { // datastore provides memory information // Note: command meta could override these with actual free info // - max free bytes if (aDataStoreDevInfP->dsmem->maxmem) { if (!StrToLongLong(smlPCDataToCharP(aDataStoreDevInfP->dsmem->maxmem),fMaxMemory)) return false; else fFreeMemory=fMaxMemory; // default for free = max (sync meta might correct this) } // - maximum free ID if (aDataStoreDevInfP->dsmem->maxid) { if (!StrToLongLong(smlPCDataToCharP(aDataStoreDevInfP->dsmem->maxid),fMaxID)) return false; else fFreeID=fMaxID; // default for free = max (sync meta might correct this) } PDEBUGPRINTFX(DBG_REMOTEINFO,("DevInf provides DSMem: MaxMem=" PRINTF_LLD ", MaxID=" PRINTF_LLD,PRINTF_LLD_ARG(fFreeMemory),PRINTF_LLD_ARG(fMaxID))); } // - SyncCap - standard types currently ignored, only // our own extensions are relevant. // Corresponding code in TLocalEngineDS::newDevInfSyncCap() if (aDataStoreDevInfP->synccap) { SmlPcdataListPtr_t stlP = aDataStoreDevInfP->synccap->synctype; // loop through list PDEBUGBLOCKDESCCOLL("RemoteSyncTypes", "Analyzing remote sync types listed in datastore level SyncCap"); while (stlP) { if (stlP->data) { const char *type = smlPCDataToCharP(stlP->data); PDEBUGPRINTFX(DBG_REMOTEINFO,("SyncType='%s'", type)); fSyncModes.insert(type); if (!strcmp(type, "390001")) { fCanRestart = true; } } stlP = stlP->next; } PDEBUGENDBLOCK("RemoteSyncTypes"); } } SYSYNC_CATCH (...) DEBUGPRINTFX(DBG_ERROR,("******** setDatastoreDevInf caused exception")); return false; SYSYNC_ENDCATCH return true; } // TRemoteDataStore::setDatastoreDevInf /* end of TRemoteDataStore implementation */ // eof libsynthesis-3.4.0.47.1/src/sysync/remotedatastore.h000077500000000000000000000054531226375725500223500ustar00rootroot00000000000000/* * File: RemoteDataStore.h * * Author: Lukas Zeller (luz@plan44.ch) * * TRemoteDataStore * Abstraction of remote data store for SyncML Server * Buffers and forwards incoming remote data store commands for * processing by sync engine. * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * 2001-06-12 : luz : created * */ #ifndef RemoteDataStore_H #define RemoteDataStore_H // includes #include "sysync.h" #include "syncdatastore.h" namespace sysync { class TRemoteDataStore: public TSyncDataStore { typedef TSyncDataStore inherited; friend class TSyncAgent; private: void init(void); // internal init void InternalResetDataStore(void); // reset for re-use without re-creation public: TRemoteDataStore(TSyncSession *aSessionP); TRemoteDataStore(TSyncSession *aSessionP, const char *aName, uInt32 aCommonSyncCapMask=0); virtual void engResetDataStore(void) { InternalResetDataStore(); inherited::engResetDataStore(); }; virtual ~TRemoteDataStore(); // Naming // check if this remote datastore is accessible with given URI virtual uInt16 isDatastore(const char *aDatastoreURI); const char *getFullName(void) { return fFullName.c_str(); } void setFullName(const char *aFullName) { fFullName=aFullName; }; // - SYNC command bracket start (check credentials if needed) bool remoteProcessSyncCmd( SmlSyncPtr_t aSyncP, // the Sync element TStatusCommand &aStatusCommand, // status that might be modified bool &aQueueForLater // will be set if command must be queued for later (re-)execution ); // %%% probably obsolete %%%% process client commands in server case // - SYNC command bracket end (but another might follow in next message) bool remoteProcessSyncCmdEnd(void); // %%% probably obsolete %%%% process client commands in server case // - end of all sync commands from client bool endOfClientSyncCmds(void); // description structure of datastore (NULL if not available) // - set description structure, ownership is passed to TSyncDataStore virtual bool setDatastoreDevInf( SmlDevInfDatastorePtr_t aDataStoreDevInfP, // the datastore DevInf TSyncItemTypePContainer &aLocalItemTypes, // list to look up local types (for reference) TSyncItemTypePContainer &aNewItemTypes // list to add analyzed types if not already there ); // helpers // - return display name #ifndef MINIMAL_CODE virtual const char *getDisplayName(void) { return fDisplayName.c_str(); }; #endif // - return pure relative (item) URI (removes absolute part or ./ prefix) const char *DatastoreRelativeURI(const char *aURI); protected: #ifndef MINIMAL_CODE // Display name of Datastore string fDisplayName; #endif private: string fFullName; }; // TRemoteDataStore } // namespace sysync #endif // RemoteDataStore_H // eof libsynthesis-3.4.0.47.1/src/sysync/rrules.cpp000077500000000000000000002335671226375725500210260ustar00rootroot00000000000000/* * File: rrules.cpp * * Author: Lukas Zeller (luz@plan44.ch) * * Parser/Generator routines for vCalendar RRULES * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * 2004-11-23 : luz : created from exctracts from vcalendaritemtype.cpp * */ #include "prefix_file.h" #include #include "rrules.h" #if defined(SYSYNC_TOOL) #include "syncappbase.h" // for CONSOLEPRINTF #endif using namespace sysync; namespace sysync { // Names of weekdays in RRULEs const char* const RRULE_weekdays[ DaysOfWeek ] = { "SU", "MO", "TU", "WE", "TH", "FR", "SA" }; // Support for SySync Diagnostic Tool #ifdef SYSYNC_TOOL // convert between RRULE and internal format int rruleConv(int argc, const char *argv[]) { if (argc<0) { // help requested CONSOLEPRINTF((" rrule ...")); CONSOLEPRINTF((" Convert between RRULE representations:")); CONSOLEPRINTF((" mode \"i\" : internal format: startdate,freq,freqmod,interval,firstmask,lastmask,until")); CONSOLEPRINTF((" (firstmask/lastmask in decimal or hex, until in ISO8601 format)")); CONSOLEPRINTF((" mode \"t\" : output only, like \"i\" but also shows table of first 10 recurrence dates")); CONSOLEPRINTF((" mode \"1\" : startdate,RRULE according to vCalendar 1.0 specs")); CONSOLEPRINTF((" mode \"2\" : startdate,RRULE according to iCalendar (RFC2445) specs")); return EXIT_SUCCESS; } // check for argument if (argc!=3) { CONSOLEPRINTF(("3 arguments required")); return EXIT_FAILURE; } // mode char inmode,outmode; // internal representation lineartime_t start; char freq; char freqmod; sInt16 interval; fieldinteger_t firstmask; fieldinteger_t lastmask; lineartime_t until; // time zone stuff timecontext_t rulecontext=TCTX_UNKNOWN; timecontext_t untilcontext; GZones zones; // RRULE char isodate[50]; char rulebuf[200]; string rrule,iso; // get input mode inmode=tolower(*(argv[0])); if (inmode!='i' && inmode!='1' && inmode!='2') { CONSOLEPRINTF(("invalid input mode, must be i, 1 or 2")); return EXIT_FAILURE; } // get output mode outmode=tolower(*(argv[1])); if (outmode!='i' && outmode!='t' && outmode!='1' && outmode!='2') { CONSOLEPRINTF(("invalid output mode, must be i, t, 1 or 2")); return EXIT_FAILURE; } CONSOLEPRINTF(("")); // reset params freq='0'; // frequency = none freqmod=' '; // frequency modifier interval=0; // interval firstmask=0; // day mask counted from the first day of the period lastmask=0; // day mask counted from the last day of the period until= noLinearTime; // last day // get input and convert to internal format (if needed) if (inmode=='i') { if (sscanf(argv[2], "%[^,],%c,%c,%hd,%lld,%lld,%s", rulebuf, &freq, &freqmod, &interval, &firstmask, &lastmask, isodate )!=7) { CONSOLEPRINTF(("invalid internal format input")); return EXIT_FAILURE; } // - convert dates ISO8601StrToTimestamp(rulebuf,start,rulecontext); // Start determines rule context ISO8601StrToTimestamp(isodate,until,untilcontext); // until will be converted to same context TzConvertTimestamp(until,untilcontext,rulecontext,&zones); } else if (inmode=='1') { if (sscanf(argv[2],"%[^,],%[^\n]",isodate,rulebuf)!=2) { CONSOLEPRINTF(("error, expected: startdate,RRULE")); return EXIT_FAILURE; } ISO8601StrToTimestamp(isodate,start,rulecontext); if (!RRULE1toInternal( rulebuf, // RRULE string to be parsed start, // reference date for parsing RRULE rulecontext, // time context of RRULE freq, freqmod, interval, firstmask, lastmask, until, untilcontext, NULL )) { CONSOLEPRINTF(("invalid/unsupported RRULE type 1 specification")); return EXIT_FAILURE; } } else if (inmode=='2') { if (sscanf(argv[2],"%[^,],%[^\n]",isodate,rulebuf)!=2) { CONSOLEPRINTF(("error, expected: startdate,RRULE")); return EXIT_FAILURE; } ISO8601StrToTimestamp(isodate,start,rulecontext); if (!RRULE2toInternal( rulebuf, // RRULE string to be parsed start, // reference date for parsing RRULE rulecontext, // time context of RRULE freq, freqmod, interval, firstmask, lastmask, until, untilcontext, NULL )) { CONSOLEPRINTF(("invalid/unsupported RRULE type 2 specification")); return EXIT_FAILURE; } } // convert to rrule (if needed) and output TimestampToISO8601Str(iso,start,rulecontext,true); if (outmode=='i' || outmode=='t') { TimestampToISO8601Str(rrule,until,TCTX_UTC,true); CONSOLEPRINTF(( "Internal format (start,freq,freqmod,interval,firstmask,lastmask,until:\n%s,%c,%c,%hd,0x%llX,0x%llX,%s", iso.c_str(), freq, freqmod, interval, firstmask, lastmask, rrule.c_str() )); // extra info if we have 't' table mode lineartime_t occurrence; if (outmode=='t') { sInt16 cnt; for (cnt=1; cnt<=10; cnt++) { // calculate date of cnt-th recurrence if (!endDateFromCount( occurrence, start, freq, freqmod, interval, firstmask, lastmask, cnt, true, // counting occurrences NULL )) break; // see if limit already reached if (occurrence>until) { cnt=0; break; } // show this recurrence TimestampToISO8601Str(iso,occurrence,rulecontext,true); CONSOLEPRINTF(( "%3d. occurrence at %s (%s)", cnt, iso.c_str(), RRULE_weekdays[lineartime2weekday(occurrence)] )); } // show end date if not all recurrences shown already if (cnt>10) { // calculate occurrence count if (countFromEndDate( cnt, true, // counting occurrences start, freq, freqmod, interval, firstmask, lastmask, until, NULL )) { if (cnt==0) { CONSOLEPRINTF(( "last occurrence: (repeating infinitely)", cnt, iso.c_str() )); } else { // convert back to date if (endDateFromCount( occurrence, start, freq, freqmod, interval, firstmask, lastmask, cnt, true, // counting occurrences NULL )) { TimestampToISO8601Str(iso,occurrence,rulecontext,true); CONSOLEPRINTF(( "%3d./LAST occ. at %s (%s)", cnt, iso.c_str(), RRULE_weekdays[lineartime2weekday(occurrence)] )); } } } } } } else if (outmode=='1') { if (!internalToRRULE1( rrule, // receives RRULE string freq, freqmod, interval, firstmask, lastmask, until, rulecontext, NULL )) { CONSOLEPRINTF(("Cannot show as RRULE type 1")); return EXIT_FAILURE; } CONSOLEPRINTF(("RRULE type 1 format (start,rrule):\n%s,%s",iso.c_str(),rrule.c_str())); } else if (outmode=='2') { if (!internalToRRULE2( rrule, // receives RRULE string freq, freqmod, interval, firstmask, lastmask, until, rulecontext, NULL )) { CONSOLEPRINTF(("Cannot show as RRULE type 2")); return EXIT_FAILURE; } CONSOLEPRINTF(("RRULE type 2 format (start,rrule):\n%s,%s",iso.c_str(),rrule.c_str())); } return EXIT_SUCCESS; } // rruleConv #endif // SYSYNC_TOOL /* // sample of a field block: Offset=0: - frequency codes: 0 = none, s = secondly, m = minutely, h = hourly, D = daily, W = weekly, M = monthly, Y = yearly - frequency modifiers space = none s = by second list m = by minute list h = by hour list W = by weekday list D = by monthday list Y = by yearday list N = by weeknumber list M = by monthlist P = by setposlist Offset=1: - interval Offset=2: - bit-coded list of items according to frequency modifier, relative to the beginning of the interval - for seconds, minutes, hours: Bit0=first, Bit1=second.... - for weekly: Bit0=Sun, Bit6=Sat - for monthly by weekday: Bit0=first Sun, Bit7=2nd Sun... Bit35=5th Sun - for monthly by day: Bit0=1st, Bit1=2nd, Bit31=31st. - for yearly by month: Bit0=jan, Bit1=feb,... - for yearly by weeknumber: Bit0=weekno1,.... Offset=3: - bit coded list of items according to frequency modifier, relative to the end of the interval: - Bit0=last, Bit1=second last, Bit2=third last.... - for weekly: Bit0=last Sun, Bit1=last Mon,... Bit7=second last Sun,... Offset=4: - end date. This is calculated from DTSTART and count if incoming rule does not specify an end date Offset=5: - for reference only */ // Converts internal recurrence into vCalendar 1.0 RRULE string bool internalToRRULE1( string &aString, // receives RRULE string char freq, char freqmod, sInt16 interval, fieldinteger_t firstmask, fieldinteger_t lastmask, lineartime_t until, timecontext_t untilcontext, TDebugLogger *aLogP ) { // Now do the conversion string s; sInt16 i,j,k; fieldinteger_t m; bool repshown; aString.erase(); // frequency and modifier switch (freq) { case '0' : return true; // no repetition case 'D' : aString+='D'; break; case 'W' : aString+='W'; break; case 'M' : aString+='M'; if (freqmod=='W') aString+='P'; // by-(weekday)-position else if (freqmod=='D') aString+='D'; // by (month)day else goto incompat; break; case 'Y' : aString+='Y'; if (freqmod=='M') aString+='M'; // by month // else if (freqmod=='Y') aString+='D'; // by yearday, %%%% not supported else goto incompat; break; default : goto incompat; } // switch freq // add interval if (interval<1) goto incompat; StringObjAppendPrintf(aString,"%hd",interval); // add modifiers switch (freqmod) { case 'W' : if (freq=='M') { // Monthly by weekday m = firstmask; for (i=0; i<2; i++) { // - from start and from end for (j=0; j0) aString+='-'; else aString+='+'; } // show day aString+=' '; aString+=RRULE_weekdays[k]; } } } // - switch to those that are relative to the end of the month m = lastmask; } } else { // weekly by weekday for (k=0; k0) aString+='-'; } } // - switch to those that are relative to the end of the month / year m = lastmask; } break; case ' ' : // no modifiers, that's ok as well break; default : goto incompat; } // switch freqmod // add end date (or #0 if no end date = endless) if (until!=noLinearTime) { // there is an end date, use it aString+=' '; TimestampToISO8601Str(s, until, untilcontext); aString+=s; } else { // there is no end date, repeat forever aString+=" #0"; } // genereated a RRULE return true; incompat: // incompatible, cannot be shown as vCal 1.0 RRULE aString.erase(); return false; // no value generated } // internalToRRULE1 // Converts internal recurrence into vCalendar 2.0 RRULE string bool internalToRRULE2( string &aString, // receives RRULE string char freq, char freqmod, sInt16 interval, fieldinteger_t firstmask, fieldinteger_t lastmask, lineartime_t until, timecontext_t untilcontext, TDebugLogger *aLogP ) { LOGDEBUGPRINTFX(aLogP,DBG_EXOTIC+DBG_GEN,( "InternalToRRULE2(): expanding freq=%c, freqmod=%c, interval=%hd, firstmask=%llX, lastmask=%llX", freq, freqmod, interval, (long long)firstmask, (long long)lastmask )); // Now do the conversion string s; sInt16 i,j,k; fieldinteger_t m; bool repshown; cAppCharP sep; aString.erase(); // frequency and modifier switch (freq) { case '0' : return true; // no repetition case 'D' : aString+="FREQ=DAILY"; break; case 'W' : aString+="FREQ=WEEKLY"; break; case 'M' : aString+="FREQ=MONTHLY"; break; case 'Y' : aString+="FREQ=YEARLY"; break; default : goto incompat; } // switch freq // add interval if (interval<1) goto incompat; StringObjAppendPrintf(aString,";INTERVAL=%hd",interval); // add modifiers switch (freqmod) { case 'W' : sep=";BYDAY="; if (freq=='M') { // Monthly by weekday m = firstmask; for (i=0; i<2; i++) { // - from start and from end for (j=0; j0) aString+='-'; StringObjAppendPrintf(aString,"%d",j+1); // - show if relative to beginning or end of month } // show day aString+=RRULE_weekdays[k]; } } } // - switch to those that are relative to the end of the month m = lastmask; } } else { // weekly by weekday for (k=0; k parse error switch (c) { case 'D' : freq='D'; break; case 'W' : freq='W'; freqmod='W'; break; case 'M' : freq='M'; // get modifier c=*p++; if (c=='P') freqmod='W'; // by weekday else if (c=='D') freqmod='D'; // by monthday else goto norep; // unknown modifier: cancel repetition (but no error) break; case 'Y' : freq='Y'; // get modifier c=*p++; if (c=='M') freqmod='M'; // by monthlist else if (c=='D') freqmod='Y'; // by day-of-year list %%% not supported else goto norep; // unknown modifier: cancel repetition (but no error) break; default : goto incompat; } // get interval while (isdigit(*p)) { interval=interval*10+((*p++)-'0'); } if (interval==0) goto incompat; // no interval is incompatible -> parse error // get modifier(s) if any switch (freq) { case 'W' : // weekly may or may not have modifiers do { do c=*p++; while(c==' '); // next non-space if (isalpha(c)) { c2=*p++; if (!isalpha(c2)) goto incompat; // bad weekday syntax -> parse error for (k=0;k parse error firstmask = firstmask | ((uInt64)1<'5' || c<'1') goto incompat; // no more than 5 weeks in a month! -> parse error j=c-'1'; // first occurrence=0 // check for '+' or '-' if (*p=='+') p++; // simply skip else if (!(fromstart=!(*p=='-'))) p++; // skip } else if (isalpha(c)) { // get weekday spec c2=*p++; if (!isalpha(c2)) goto incompat; // bad weekday syntax -> parse error for (k=0;k parse error m=(uInt64)1<<(DaysOfWeek*j+k); if (fromstart) firstmask |= m; else lastmask |= m; // add weekday rep } else { // end of modifiers p--; break; } } while(true); // check if we need defaults if (!(firstmask | lastmask)) { if (!dtstart) goto norep; // cannot set, no start date (but no error) // determine the repetition in the month of this weekday j=(startday-1) / DaysOfWeek; firstmask = ((uInt64)1<<(DaysOfWeek*j+startwday)); // set nth repetition of current weekday } } else { // must be 'D' = monthly by day of month do { fromstart=true; do c=*p++; while(c==' '); // next non-space if (c=='L' && *p=='D') { // special case: "LD" means last day of month lastmask |= 1; } else if (isdigit(c) && (*p) && (!isdigit(*p) || !isdigit(*(p+1)))) { // more than two digits are end date // get day number k=c-'0'; if (isdigit(*p)) k=k*10+((*p++)-'0'); // check for '+' or '-' if (*p=='+') p++; // simply skip plus if (!(fromstart=!(*p=='-'))) p++; // skip minus and set fromstart to false if (k==0) goto incompat; // 0 is not allowed -> parse error // set mask k--; // bits are 0 based m = (uInt64)1< parse error // set mask k--; // bits are 0 based firstmask |= (uInt64)1<= 4 digits) or # or end of string --p; // we have fetched one to many // - make best try to convert to by-monthlist freqmod='M'; firstmask = ((uInt64)1<<(startmonth-1)); // set bit of current day-in-month } // yearly modifiers done break; } // switch for modifier reading // get count or end date do c=*p++; while (c==' '); // next non-space cnt=2; // default to repeat once (=applied two times) if (c==0) goto calcenddate; else if (c=='#') { // count specified if (!StrToShort(p,cnt)) goto incompat; // bad count -> parse error calcenddate: if (!endDateFromCount(until,dtstart,freq,freqmod,interval,firstmask,lastmask,cnt,false,aLogP)) goto norep; untilcontext = startcontext; // until is in same context as start } // count specified else { // must be end date, or spec is bad p--; if (ISO8601StrToTimestamp(p, until, untilcontext)==0) goto incompat; // bad end date -> parse error } // end date specified // parsed ok, now store it goto store; norep: // no repetition (but no parse error generated) freq='0'; // frequency = none freqmod=' '; // frequency modifier interval=0; // interval firstmask=0; // day mask counted from the first day of the period lastmask=0; // day mask counted from the last day of the period until= noLinearTime; // last day store: return true; // ok incompat: // incompatible, value cannot be parsed usefully return false; // no value generated } // RRULE1toInternal /// @brief calculate end date of RRULE when count is specified /// @return true if repeating, false if not repeating at all /// @note returns until=noLinearTime for endless repeat (count=0) bool endDateFromCount( lineartime_t &until, lineartime_t dtstart, char freq, char freqmod, sInt16 interval, fieldinteger_t firstmask,fieldinteger_t lastmask, sInt16 cnt, bool countsoccurrences, TDebugLogger *aLogP ) { // count<=0 means endless if (cnt<=0) { until= noLinearTime; // forever, we don't need a start date for this return true; // ok } // check no-rep cases if (cnt<0) return false; // negative count, no repeat if (dtstart==noLinearTime) return false; // no start date, cannot calc end date -> no rep (but no error) if (interval<=0) return false; // interval=0 means no recurrence (but no error) // default to dtstart until = dtstart; // calculate elements of start point sInt16 startwday; sInt16 startyear,startmonth,startday; lineartime_t starttime; starttime = lineartime2timeonly(dtstart); // start time of day startwday = lineartime2weekday(dtstart); // get starting weekday lineartime2date(dtstart,&startyear,&startmonth,&startday); // year, month, day-in-month // calculate interval repetitions (which is what is needed for daily and RRULE v1 calculation) sInt16 ivrep = (cnt-1)*interval; // check if daily if (freq == 'D') { // Daily recurrence is same for occurrence and interval counts LOGDEBUGPRINTFX(aLogP,DBG_PARSE+DBG_EXOTIC,("endDateFromCount: daily calc - same in all cases")); until = dtstart+(ivrep*linearDateToTimeFactor); return true; } else if (!countsoccurrences) { // RRULE v1 interpretation of count (=number of repetitions of interval, not number of occurrences) // - determine end of recurrence interval (which is usually NOT a occurrence precisely) switch (freq) { case 'W': LOGDEBUGPRINTFX(aLogP,DBG_PARSE+DBG_EXOTIC,("endDateFromCount: simple weekly calc")); // v1 end date calc, we need to take into account possible masks, so result must be end of interval, not just start date+interval // weekly: end date is last day of target week until=dtstart+((ivrep*DaysOfWeek-startwday+6)*linearDateToTimeFactor); return true; case 'M': LOGDEBUGPRINTFX(aLogP,DBG_PARSE+DBG_EXOTIC,("endDateFromCount: simple monthly calc")); startmonth--; // make 0 based startmonth += ivrep+1; // add number of months plus one (as we want next month, and then go one day back to last day of month) startyear += startmonth / 12; // update years startmonth = startmonth % 12 + 1; // update month and make 1 based again // - calculate last day in month of occurrence until = (date2lineardate(startyear,startmonth,1)-1)*linearDateToTimeFactor+starttime; return true; case 'Y': LOGDEBUGPRINTFX(aLogP,DBG_PARSE+DBG_EXOTIC,("endDateFromCount: simple yearly calc")); // yearly: end date is end of end year until = (date2lineardate(startyear+ivrep,12,31))*linearDateToTimeFactor+starttime; return true; } } else { // v2 type counting, means that count specifies number of occurrences, not interval repetitions // requires more elaborate expansion // NOTE: this does not work without masks set, so we need to calculate the default masks if none are explicitly set // - we need the number of days in the month in most cases sInt16 lastday = getMonthDays(lineartime2dateonly(dtstart)); // number of days in this month sInt16 newYearsPassed; switch (freq) { case 'W': LOGDEBUGPRINTFX(aLogP,DBG_PARSE+DBG_EXOTIC,("endDateFromCount: full expansion weekly calc")); // - make sure we have a mask if (firstmask==0 && lastmask==0) firstmask = 1<6) { // new week starts startwday=0; // skip part of interval which has no occurrence until+=(interval-1)*7*linearDateToTimeFactor; } } return true; case 'M': if (freqmod=='W') { // monthly by weekday LOGDEBUGPRINTFX(aLogP,DBG_PARSE+DBG_EXOTIC,("endDateFromCount: full expansion of monthly by weekday")); // - make sure we have a mask if (firstmask==0 && lastmask==0) firstmask = (uInt64)1<<(startwday+7*((startday-1)/7)); // set start day in mask // - now calculate while (firstmask || lastmask) { // calculate which weeks we are in sInt16 fwk=(startday-1) / 7; // start is nth week of the month sInt16 lwk=(lastday-startday) / 7; // start is nth-last week of the month if ( (firstmask & ((uInt64)1<<(startwday+7*fwk))) || // nth occurrence of weekday in month (lastmask & ((uInt64)1<<(startwday+7*lwk))) // nth-last occurrence of weekday in month ) { // found an occurrence cnt--; // count it if (cnt<=0) break; // found all } // increment day until+=linearDateToTimeFactor; startday++; // next day in month startwday++; if (startwday>6) startwday=0; // next day in the week // check for new month if (startday>lastday) { // new month starts sInt16 i=interval; while (true) { lastday = getMonthDays(lineartime2dateonly(until)); // number of days in next month startday = 1; // start at 1st of month again if (--i == 0) break; // done // skip entire next month until+=lastday*linearDateToTimeFactor; // advance by number of days in this month } // now recalculate weekday startwday=lineartime2weekday(until); // calculation continues here } } } else { // everything else, including no modifier, is treated as monthly by monthday LOGDEBUGPRINTFX(aLogP,DBG_PARSE+DBG_EXOTIC,("endDateFromCount: full expansion of monthly by monthday")); // - make sure we have a mask if (firstmask==0 && lastmask==0) firstmask = (uInt64)1<<(startday-1); // set start day in mask // - now calculate while (firstmask || lastmask) { if ( (firstmask & ((uInt64)1<<(startday-1))) || // nth day in month (lastmask & ((uInt64)1<<(lastday-startday))) // nth-last day in month ) { // found an occurrence cnt--; // count it if (cnt<=0) break; // found all } // increment day until+=linearDateToTimeFactor; startday++; // next day in month if (startday>lastday) { // new month starts sInt16 i=interval; while (true) { lastday = getMonthDays(lineartime2dateonly(until)); // number of days in next month startday = 1; // start at 1st of month again if (--i == 0) break; // done // skip entire next month until+=lastday*linearDateToTimeFactor; // advance by number of days in this month } } } } return true; case 'Y': if (freqmod=='M') { // Yearly by month LOGDEBUGPRINTFX(aLogP,DBG_PARSE+DBG_EXOTIC,("endDateFromCount: full expansion of yearly by month")); // - make sure we have a mask if (firstmask==0 && lastmask==0) firstmask = (uInt64)1<<(startmonth-1); // set start month in mask // - do entire calculation on 1st of month such that we can be sure that day exists (unlike a Feb 30th or April 31th) until -= (startday-1)*linearDateToTimeFactor; // - now calculate newYearsPassed=0; // occurrence interval can be at most 4 years in the future (safety abort) while (newYearsPassed<=4) { if (firstmask & ((uInt64)1<<(startmonth-1))) { // possibly found an occurrence // - is an occurrence only if that day exists in the month if (startday<=lastday) { cnt--; // count it newYearsPassed = 0; if (cnt<=0) break; // found all } } // go to same day in next month (and skip months that don't have that day, like an 31st April or 30Feb until+=lastday*linearDateToTimeFactor; startmonth++; if (startmonth>12) { // new year starts startmonth=1; newYearsPassed++; // skip additional years (in month steps) for (sInt16 i=(interval-1)*12; i>0; i--) { lastday = getMonthDays(lineartime2dateonly(until)); // number of days in next month // skip month until+=lastday*linearDateToTimeFactor; // advance by number of days in this month } } // get size of next month to check lastday = getMonthDays(lineartime2dateonly(until)); // number of days in next month } // move back to start day until += (startday-1)*linearDateToTimeFactor; } else { // everything else, including no modifier, is treated as yearly on the same date (multiple occurrences per year not supported) LOGDEBUGPRINTFX(aLogP,DBG_PARSE+DBG_EXOTIC,("endDateFromCount: full expansion of yearly by yearday - NOT SUPPORTED with more than one day")); until = (date2lineardate(startyear+ivrep,startmonth,startday))*linearDateToTimeFactor+starttime; } return true; } // switch } // no recurrence return false; } // endDateFromCount #ifdef DEBUG /* // %%%% hack debug #define SYNTHESIS_UNIT_TEST 1 #define UNIT_TEST_TITLE(a) #define UNIT_TEST_CALL(x,p,t,v) */ #endif #ifdef SYNTHESIS_UNIT_TEST // helper to create lineartime parameters static lineartime_t t(char *aTime) { if (!aTime || *aTime==0) return noLinearTime; timecontext_t tctx; lineartime_t res; ISO8601StrToTimestamp(aTime, res, tctx); return res; } // helper to show lineartime results static char buf[100]; char *s(lineartime_t aTime) { if (aTime==noLinearTime) return ""; string str; TimestampToISO8601Str(str, aTime, TCTX_UNKNOWN, true, false); strcpy(buf,str.c_str()); return buf; } // RRULE expansion tests bool test_expand_rrule(void) { bool ok=true; lineartime_t lt; TRRuleExpandStatus es; { UNIT_TEST_TITLE("Birthday 1"); UNIT_TEST_CALL(initRRuleExpansion(es,t("2008-03-31T00:00:00"),'Y','M',1,0x4,0x0,t("2009-03-31T00:00:00"),t("2009-04-01T00:00:00")),("-none-"),true,ok); UNIT_TEST_CALL(lt = getNextOccurrence(es),("lt = %s",s(lt)),lt==t("2009-03-31T00:00:00"),ok); UNIT_TEST_CALL(lt = getNextOccurrence(es),("lt = %s",s(lt)),lt==t(""),ok); // generated occurrences (checked 3) UNIT_TEST_TITLE("Birthday 2"); UNIT_TEST_CALL(initRRuleExpansion(es,t("1979-03-06T00:00:00"),'Y','M',1,0x4,0x0,t("2009-03-31T00:00:00"),t("2009-04-01T00:00:00")),("-none-"),true,ok); UNIT_TEST_CALL(lt = getNextOccurrence(es),("lt = %s",s(lt)),lt==t(""),ok); // no occurrences (checked 32) UNIT_TEST_TITLE("Birthday 3"); UNIT_TEST_CALL(initRRuleExpansion(es,t("2006-03-13T00:00:00"),'Y','M',1,0x4,0x0,t("2009-02-23T00:00:00"),t("2009-03-31T00:00:00")),("-none-"),true,ok); UNIT_TEST_CALL(lt = getNextOccurrence(es),("lt = %s",s(lt)),lt==t("2009-03-13T00:00:00"),ok); UNIT_TEST_CALL(lt = getNextOccurrence(es),("lt = %s",s(lt)),lt==t(""),ok); // generated occurrences (checked 5) UNIT_TEST_TITLE("Pay day"); UNIT_TEST_CALL(initRRuleExpansion(es,t("2006-06-20T00:00:00"),'M','D',1,0x80000,0x0,t("2009-02-23T00:00:00"),t("2009-03-31T00:00:00")),("-none-"),true,ok); UNIT_TEST_CALL(lt = getNextOccurrence(es),("lt = %s",s(lt)),lt==t("2009-03-20T00:00:00"),ok); UNIT_TEST_CALL(lt = getNextOccurrence(es),("lt = %s",s(lt)),lt==t(""),ok); // generated occurrences (checked 35) UNIT_TEST_TITLE("St. Patrick's Day"); UNIT_TEST_CALL(initRRuleExpansion(es,t("2006-03-17T00:00:00"),'Y','M',1,0x4,0x0,t("2009-02-23T00:00:00"),t("2009-03-31T00:00:00")),("-none-"),true,ok); UNIT_TEST_CALL(lt = getNextOccurrence(es),("lt = %s",s(lt)),lt==t("2009-03-17T00:00:00"),ok); UNIT_TEST_CALL(lt = getNextOccurrence(es),("lt = %s",s(lt)),lt==t(""),ok); // generated occurrences (checked 5) // Expanding 'Change fish tank filter': UNIT_TEST_TITLE("Change fish tank filter"); UNIT_TEST_CALL(initRRuleExpansion(es,t("2007-10-21T00:00:00"),'W','W',5,0x1,0x0,t("2009-02-23T00:00:00"),t("2009-03-31T00:00:00")),("-none-"),true,ok); UNIT_TEST_CALL(lt = getNextOccurrence(es),("lt = %s",s(lt)),lt==t("2009-03-29T00:00:00"),ok); UNIT_TEST_CALL(lt = getNextOccurrence(es),("lt = %s",s(lt)),lt==t(""),ok); // generated occurrences (checked 17) // Expanding 'Start of British Summer Time': UNIT_TEST_TITLE("Start of British Summer Time"); UNIT_TEST_CALL(initRRuleExpansion(es,t("2003-03-30T00:00:00"),'M','W',12,0x0,0x1,t("2009-02-23T00:00:00"),t("2009-03-31T00:00:00")),("-none-"),true,ok); UNIT_TEST_CALL(lt = getNextOccurrence(es),("lt = %s",s(lt)),lt==t("2009-03-29T00:00:00"),ok); UNIT_TEST_CALL(lt = getNextOccurrence(es),("lt = %s",s(lt)),lt==t(""),ok); // generated occurrences (checked 8) UNIT_TEST_TITLE("Birthday 4"); UNIT_TEST_CALL(initRRuleExpansion(es,t("1957-03-14T00:00:00"),'Y','M',1,0x4,0x0,t("2009-02-23T00:00:00"),t("2009-03-31T00:00:00")),("-none-"),true,ok); UNIT_TEST_CALL(lt = getNextOccurrence(es),("lt = %s",s(lt)),lt==t("2009-03-14T00:00:00"),ok); UNIT_TEST_CALL(lt = getNextOccurrence(es),("lt = %s",s(lt)),lt==t(""),ok); // generated occurrences (checked 54) UNIT_TEST_TITLE("Buy Lottery tickets"); UNIT_TEST_CALL(initRRuleExpansion(es,t("2007-08-11T00:00:00"),'W','W',3,0x40,0x0,t("2009-02-23T00:00:00"),t("2009-03-31T00:00:00")),("-none-"),true,ok); UNIT_TEST_CALL(lt = getNextOccurrence(es),("lt = %s",s(lt)),lt==t("2009-02-28T00:00:00"),ok); UNIT_TEST_CALL(lt = getNextOccurrence(es),("lt = %s",s(lt)),lt==t("2009-03-21T00:00:00"),ok); UNIT_TEST_CALL(lt = getNextOccurrence(es),("lt = %s",s(lt)),lt==t(""),ok); // generated occurrences (checked 30) UNIT_TEST_TITLE("Recycling bin collection"); UNIT_TEST_CALL(initRRuleExpansion(es,t("2007-08-17T00:00:00"),'W','W',2,0x20,0x0,t("2009-02-23T00:00:00"),t("2009-03-31T00:00:00")),("-none-"),true,ok); UNIT_TEST_CALL(lt = getNextOccurrence(es),("lt = %s",s(lt)),lt==t("2009-02-27T00:00:00"),ok); UNIT_TEST_CALL(lt = getNextOccurrence(es),("lt = %s",s(lt)),lt==t("2009-03-13T00:00:00"),ok); UNIT_TEST_CALL(lt = getNextOccurrence(es),("lt = %s",s(lt)),lt==t("2009-03-27T00:00:00"),ok); UNIT_TEST_CALL(lt = getNextOccurrence(es),("lt = %s",s(lt)),lt==t(""),ok); // generated occurrences (checked 44) UNIT_TEST_TITLE("test feb 29th"); UNIT_TEST_CALL(initRRuleExpansion(es,t("2008-02-29T14:00:00"),'Y','M',1,0x0,0x0,t("2009-04-01T00:00:00"),t("2019-04-04T00:00:00")),("-none-"),true,ok); UNIT_TEST_CALL(lt = getNextOccurrence(es),("lt = %s",s(lt)),lt==t("2012-02-29T14:00:00"),ok); UNIT_TEST_CALL(lt = getNextOccurrence(es),("lt = %s",s(lt)),lt==t("2016-02-29T14:00:00"),ok); UNIT_TEST_CALL(lt = getNextOccurrence(es),("lt = %s",s(lt)),lt==t(""),ok); UNIT_TEST_TITLE("February and March 29th every year"); UNIT_TEST_CALL(initRRuleExpansion(es,t("2008-02-29T14:00:00"),'Y','M',1,0x6,0x0,t("2009-04-01T00:00:00"),t("2016-04-04T00:00:00")),("-none-"),true,ok); UNIT_TEST_CALL(lt = getNextOccurrence(es),("lt = %s",s(lt)),lt==t("2010-03-29T14:00:00"),ok); UNIT_TEST_CALL(lt = getNextOccurrence(es),("lt = %s",s(lt)),lt==t("2011-03-29T14:00:00"),ok); UNIT_TEST_CALL(lt = getNextOccurrence(es),("lt = %s",s(lt)),lt==t("2012-02-29T14:00:00"),ok); // leap year UNIT_TEST_CALL(lt = getNextOccurrence(es),("lt = %s",s(lt)),lt==t("2012-03-29T14:00:00"),ok); UNIT_TEST_CALL(lt = getNextOccurrence(es),("lt = %s",s(lt)),lt==t("2013-03-29T14:00:00"),ok); UNIT_TEST_CALL(lt = getNextOccurrence(es),("lt = %s",s(lt)),lt==t("2014-03-29T14:00:00"),ok); UNIT_TEST_CALL(lt = getNextOccurrence(es),("lt = %s",s(lt)),lt==t("2015-03-29T14:00:00"),ok); UNIT_TEST_CALL(lt = getNextOccurrence(es),("lt = %s",s(lt)),lt==t("2016-02-29T14:00:00"),ok); // leap year UNIT_TEST_CALL(lt = getNextOccurrence(es),("lt = %s",s(lt)),lt==t("2016-03-29T14:00:00"),ok); UNIT_TEST_CALL(lt = getNextOccurrence(es),("lt = %s",s(lt)),lt==t(""),ok); UNIT_TEST_TITLE("suddenly expanding from start problem"); UNIT_TEST_CALL(initRRuleExpansion(es,t("2007-08-17"),'W','W',2,0x20,0x0,t("2009-07-04"),t("2009-08-08")),("-none-"),true,ok); UNIT_TEST_CALL(lt = getNextOccurrence(es),("lt = %s",s(lt)),lt==t("2009-07-17"),ok); UNIT_TEST_CALL(lt = getNextOccurrence(es),("lt = %s",s(lt)),lt==t("2009-07-31"),ok); UNIT_TEST_CALL(lt = getNextOccurrence(es),("lt = %s",s(lt)),lt==t(""),ok); } return ok; } #endif // SYNTHESIS_UNIT_TEST /// @brief initialize expansion of RRule void initRRuleExpansion( TRRuleExpandStatus &es, lineartime_t aDtstart, char aFreq, char aFreqmod, sInt16 aInterval, fieldinteger_t aFirstmask, fieldinteger_t aLastmask, lineartime_t aExpansionStart, lineartime_t aExpansionEnd ) { // %%% hardcoded for now es.weekstart = 0; // starts on sunday for now // save recurrence parameters es.freq = aFreq; es.freqmod = aFreqmod; es.interval = aInterval; es.firstmask = aFirstmask; es.lastmask = aLastmask; // analyze bits es.singleFMaskBit = -1; if (es.lastmask==0 && es.firstmask) { fieldinteger_t m = es.firstmask; es.singleFMaskBit = 0; while((m & 1)==0) { m>>=1; es.singleFMaskBit++; } // calculate bit number of next set bit if (m & ~1) es.singleFMaskBit = -1; // more bits to come - reset again } // init expansion parameters // - no valid occurrence yet es.started = false; // - elements of start point es.starttime = lineartime2timeonly(aDtstart); // start time of day lineartime2date(aDtstart,&es.startyear,&es.startmonth,&es.startday); // year, month, day-in-month // - cursor, initialized to start point es.cursor = aDtstart; es.cursorMLen = getMonthDays(lineartime2dateonly(es.cursor)); es.cursorWDay = lineartime2weekday(es.cursor); // get cursor weekday // save expansion range es.expansionEnd = aExpansionEnd; // can be noLinearTime if no end is set es.expansionStartDayOffset = 0; if (aExpansionStart!=noLinearTime) { // specified start of expansion period, apply if later than beginning of recurrence es.expansionStartDayOffset = (lineartime2dateonly(aExpansionStart)-lineartime2dateonly(es.cursor)); if (es.expansionStartDayOffset<0) es.expansionStartDayOffset = 0; } #ifdef SYNTHESIS_UNIT_TEST sInt16 y,m,d,h,mi,s,ms; lineartime2date(aExpansionStart, &y, &m, &d); lineartime2time(aExpansionStart, &h, &mi, &s, &ms); printf(" aExpansionStart = %04hd-%02hd-%02hd %02hd:%02hd:%02hd - es.expansionStartDayOffset=%ld\n",y,m,d,h,mi,s,es.expansionStartDayOffset); #endif } // advance cursor by given number of days static void adjustCursor(TRRuleExpandStatus &es, lineardate_t aDays) { // now days = number of days to advance es.cursor += aDays*linearDateToTimeFactor; // adjust weekday es.cursorWDay += aDays % DaysPerWk; if (es.cursorWDay<0) es.cursorWDay += DaysPerWk; else if (es.cursorWDay>=DaysPerWk) es.cursorWDay -= DaysPerWk; #ifdef SYNTHESIS_UNIT_TEST sInt16 y,m,d,h,mi,s,ms; lineartime2date(es.cursor, &y, &m, &d); lineartime2time(es.cursor, &h, &mi, &s, &ms); printf(" es.cursor = %04hd-%02hd-%02hd %02hd:%02hd:%02hd / Day=%hd, lt=%lld\n",y,m,d,h,mi,s,es.cursorWDay,es.cursor); #endif } static lineardate_t makeMultiple(lineardate_t d, sInt16 aMultiple, sInt16 aMaxRemainder=0) { if (aMultiple>1) { // we need to make sure remainder is 0 and advance extra lineardate_t r = d % aMultiple; // remainder if (r>aMaxRemainder) { // round up to next multiple d += aMultiple - r; } } return d; } // simple and fast cursor increment static void incCursor(TRRuleExpandStatus &es) { es.cursor += linearDateToTimeFactor; es.cursorWDay += 1; if (es.cursorWDay>=DaysPerWk) es.cursorWDay=0; } static bool expansionEnd(TRRuleExpandStatus &es) { if (es.expansionEnd && es.cursor>=es.expansionEnd) { // end of expansion, reset cursor es.cursor = noLinearTime; return true; } // not yet end of expansion return false; } static sInt16 monthDiff(sInt16 y1, sInt16 m1, sInt16 y2, sInt16 m2) { return (y1-y2)*12 + (m1-m2); } static void monthAdd(sInt16 &y, sInt16 &m, sInt16 a) { m += a; if (m>12) { sInt16 r = (m-1)/12; // years plus y += r; // add the years m -= (r*12); // remove from the months } } /// @brief get next occurrence /// @return noLinearTime if no next occurrence exists, lineartime of next occurrence otherwise lineartime_t getNextOccurrence(TRRuleExpandStatus &es) { if (es.cursor==noLinearTime) return noLinearTime; // already done (or never started properly) if (es.interval<=0) return noLinearTime; // interval=0 means no recurrence (but no error) // if we are already started, we need to advance the cursor first, then check for match bool advanceFirst = es.started; // now calculate if (es.freq=='D') { // Daily: can be calculated directly if (!es.started) { // calculate first occurrence adjustCursor(es, makeMultiple(es.expansionStartDayOffset, es.interval)); // move cursor to first day } else { // calculate next occurrence adjustCursor(es, es.interval); } } // D else if (es.freq=='W') { // Note: interval of weekly recurrences starts at sunday, // so recurrence starting at a Thu, scheduled for every two weeks on Mo and Thu will have: // 1st week: Thu, 2nd week: nothing, 3rd week: Mo,Thu, 4rd week: nothing, 5th week: Mo,Thu... if (!es.started) { // make sure we have a mask if (es.firstmask==0) es.firstmask = 1<0) { // need to go into subsequent month numMonths += es.interval-monthMod; // months to next interval start // entire month is after expansion start, so begin with 1st es.startday = 1; } monthAdd(es.startyear,es.startmonth,numMonths); // startYear/month/day now on first candidate // - calculate linear start es.cursor = date2lineartime(es.startyear, es.startmonth, es.startday); if (expansionEnd(es)) goto done; // could by beyond current expanding scope due to interval jump // - calculate last day in this month es.cursorMLen = getMonthDays(lineartime2dateonly(es.cursor)); // - make sure cursor weekday is correct es.cursorWDay = lineartime2weekday(es.cursor); } } // apply freqmod if (es.freqmod=='W') { // monthly by weekday // - calculate first/next occurrence (if not first occurrence, do not check initially but advance first) while(true) { // calculate which weeks we are in sInt16 fwk=(es.startday-1) / DaysPerWk; // start is nth week of the month sInt16 lwk=(es.cursorMLen-es.startday) / DaysPerWk; // start is nth-last week of the month // check if we found an occurrence if (!advanceFirst) { if ( (es.firstmask & ((uInt64)1<<(es.cursorWDay+DaysPerWk*fwk))) || // nth occurrence of weekday in month (es.lastmask & ((uInt64)1<<(es.cursorWDay+DaysPerWk*lwk))) // nth-last occurrence of weekday in month ) break; } advanceFirst = false; // next time we need to check // - next day-in-month is next candidate es.cursorWDay++; if (es.cursorWDay>=DaysPerWk) es.cursorWDay=0; // next day in the week es.startday++; if (es.startday>es.cursorMLen) { // end of month reached // - goto next relevant month monthAdd(es.startyear,es.startmonth,es.interval); // - first day es.startday=1; // - advance cursor into new month es.cursor = date2lineartime(es.startyear, es.startmonth, es.startday); // - get length of this month es.cursorMLen = getMonthDays(lineartime2dateonly(es.cursor)); // - make sure cursor weekday is correct es.cursorWDay = lineartime2weekday(es.cursor); } } // found occurrence, update cursor es.cursor = date2lineartime(es.startyear, es.startmonth, es.startday)+es.starttime; } // MW else { // monthly by monthday list // - calculate first/next occurrence (if not first occurrence, do not check initially but advance first) while(advanceFirst || !( (es.firstmask & ((uInt64)1<<(es.startday-1))) || // nth day in month (es.lastmask & ((uInt64)1<<(es.cursorMLen-es.startday))) // nth-last day in month )) { advanceFirst = false; // next time we need to check if (es.singleFMaskBit>=0) { // - next candidate is indicated by single mask bit if (es.startdayes.cursorMLen) { // end of month reached // - goto next relevant month monthAdd(es.startyear,es.startmonth,es.interval); // - first day es.startday=1; // - advance cursor into new month es.cursor = date2lineartime(es.startyear, es.startmonth, es.startday); // - get length of this month es.cursorMLen = getMonthDays(lineartime2dateonly(es.cursor)); } } // found occurrence, update cursor es.cursor = date2lineartime(es.startyear, es.startmonth, es.startday)+es.starttime; } // MD } // M else if (es.freq=='Y') { if (!es.started) { // Make sure we have a mask or cancel freqmod entirely if (es.firstmask==0 && es.lastmask==0) { // no mask at all, only startmonth counts anyway -> revert to simple direct calculation (cancel freqmod) es.freqmod = 0; } else if (es.singleFMaskBit>=0 && es.singleFMaskBit+1==es.startmonth) { // mask with single bit on start date month -> can revert to simple diect calculation (cancel freqmod) es.freqmod = 0; // no month list parsing needed } // For all yearly repeats: find first year to apply freqmod to if (es.expansionStartDayOffset) { // does not necessarily start in cursor year // - move cursor to where we want to begin earliest adjustCursor(es, es.expansionStartDayOffset); // - year of the expansion start sInt16 y,m,d; lineartime2date(es.cursor,&y,&m,&d); // year, month, day-in-month // - make sure cursor can be a candidate (i.e. is not before start) if (es.freqmod=='M') { if (d>es.startday) monthAdd(y, m, 1); // no occurrence possible in this month, next candidate is in next month } else { if (m>es.startmonth || (m==es.startmonth && d>es.startday)) y++; // no occurrence possible this year, next candidate is in next year } // - make sure we are in a year at the beginning of the interval sInt16 numYears = y-es.startyear; sInt16 yearMod = numYears % es.interval; if (yearMod>0) { // need to go into subsequent year numYears += es.interval-yearMod; // months to next interval start m = 1; // start with Jan again (only used below when checking monthlist i.e. freqmod==M) } es.startyear += numYears; if (es.freqmod=='M') { // month-by-month checking es.startmonth = m; } // startYear/month/day now on first candidate // - calculate linear start es.cursor = date2lineartime(es.startyear, es.startmonth, 1)+es.starttime; es.cursorMLen = getMonthDays(lineartime2dateonly(es.cursor)); adjustCursor(es, es.startday-1); if (expansionEnd(es)) goto done; // could by beyond current expanding scope due to interval jump // - calculate last day in this month } } // apply freqmod if (es.freqmod=='M') { // yearly by month list (and we really have a month list, not only a single month bit) // - calculate first/next occurrence (if not first occurrence, do not check initially but advance first) int yearsscanned = 0; do { while(advanceFirst || !( (es.firstmask & ((uInt64)1<<(es.startmonth-1))) || // nth month (es.lastmask & ((uInt64)1<<(12-es.startmonth))) // nth-last month )) { advanceFirst = false; // next time we need to check // - next month is next candidate es.startmonth++; if (es.startmonth>12) { // end of year reached // - goto next relevant year es.startyear += es.interval; yearsscanned ++; // - first month again es.startmonth = 1; } } // found possible occurrence (could be a day that does not exist in the month), update cursor es.cursor = date2lineartime(es.startyear, es.startmonth, 1)+es.starttime; es.cursorMLen = getMonthDays(lineartime2dateonly(es.cursor)); adjustCursor(es, es.startday-1); // repeat until day actually exists if (es.startday>es.cursorMLen) { // disable checking for match again advanceFirst = true; } } while(advanceFirst && yearsscanned<5); // found occurrence } // YM else { // yearly on same date while (advanceFirst || es.startday>es.cursorMLen ) { advanceFirst = false; // next time we need to check // just calculate next candiate es.startyear += es.interval; // update cursor and calculate es.cursor = date2lineartime(es.startyear, es.startmonth, 1)+es.starttime; es.cursorMLen = getMonthDays(lineartime2dateonly(es.cursor)); adjustCursor(es, es.startday-1); } // found occurrence } // Yx } // Y else { // unknown = nonexpandable recurrence // - return start date as first occurrence to make sure it does not get invisible if (es.started) { // subsequent occurrence requested: not available es.cursor = noLinearTime; } } // stop expansion if end of expansion period reached expansionEnd(es); done: // done es.started = true; return es.cursor; } // getNthNextOccurrence /// @brief calculate number of recurrences from specified end date of RRULE /// @return true if count could be calculated, false otherwise /// @param[in] dtstart, until : must be in the correct context to evaluate weekday rules /// @param[in] countsoccurrences : if true, counting occurrences (rather than intervals) /// @note returns until=noLinearTime for endless repeat (count=0) bool countFromEndDate( sInt16 &cnt, bool countsoccurrences, lineartime_t dtstart, char freq, char freqmod, sInt16 interval, fieldinteger_t firstmask,fieldinteger_t lastmask, lineartime_t until, TDebugLogger *aLogP ) { if (dtstart==noLinearTime || interval<1) return false; // no start date or interval, cannot calc count if (until==noLinearTime) { // endless repeat cnt=0; return true; } // iterate until end date is reached cnt=1; lineartime_t occurrence=noLinearTime; // break after 500 recurrences while (cnt<500) { if (!endDateFromCount( occurrence, dtstart, freq,freqmod, interval, firstmask,lastmask, cnt, countsoccurrences, aLogP )) return false; // error, cannot calc end date if (occurrence>until) { // no more occurrences cnt--; if (cnt==0) return false; // if not endless, but no occurrence found in range -> not repeating return true; // return count } // next occurrence cnt++; } // 500 and more recurrences count as endless cnt=0; return true; } // countFromEndDate // Converts vCalendar 2.0 RRULE string into internal recurrence representation bool RRULE2toInternal( const char *aText, // RRULE string to be parsed lineartime_t dtstart, // reference date for parsing RRULE timecontext_t startcontext, // context of reference date char &freq, char &freqmod, sInt16 &interval, fieldinteger_t &firstmask, fieldinteger_t &lastmask, lineartime_t &until, timecontext_t &untilcontext, TDebugLogger *aLogP, lineartime_t *aNewStartP ) { #ifdef SYDEBUG string abc; LOGDEBUGPRINTFX(aLogP,DBG_PARSE+DBG_EXOTIC,("RRULE2toInternal(): start analyzing '%s'", aText)); #endif string temp; const char *p; char s [50]; sInt16 startwday; sInt16 startyear,startmonth,startday; string::size_type endIndex = 0; string::size_type startIndex = 0; uInt16 cnt = 0; size_t pos; bool calculateEndDate = false; // indicator that end date calc is required as last step bool calculateFirstOccurrence = false; // indicator that aNewStartP should be adjusted to show the first occurrence string key,value,byday,bymonthday,bymonth; // get elements of start point startwday=lineartime2weekday(dtstart); // get starting weekday lineartime2date(dtstart,&startyear,&startmonth,&startday); // year, month, day-in-month until= noLinearTime; // initialize end point, if not available // do the conversion here p=aText; int start = 0; // get freq if (!getNextDirective(temp, p, start)) { // failed goto incompat; } // analyze freq if (temp == "FREQ=YEARLY") { freq='Y'; } else if (temp == "FREQ=MONTHLY") { freq='M'; } else if (temp == "FREQ=WEEKLY") { freq='W'; } else if (temp == "FREQ=DAILY") { freq='D'; } else { goto incompat; } LOGDEBUGPRINTFX(aLogP,DBG_PARSE+DBG_EXOTIC,("- found frequency %s which maps to freq %c", temp.c_str(), freq)); // init vars cnt = 0; // set interval to 1 interval = 1; freqmod = ' '; firstmask = 0; lastmask = 0; // get next directives while (getNextDirective(temp, p, start)) { LOGDEBUGPRINTFX(aLogP,DBG_PARSE+DBG_EXOTIC,("- found next directive %s", temp.c_str())); // split pos = temp.find("="); if (pos == string::npos || pos == 0 || pos == (temp.length() - 1)) { goto incompat; } key = temp.substr(0, pos); value = temp.substr(pos + 1, temp.length() - 1); LOGDEBUGPRINTFX(aLogP,DBG_PARSE+DBG_EXOTIC,("- extracted key/value %s/%s", key.c_str(), value.c_str())); // check for until if (key == "UNTIL") { if (ISO8601StrToTimestamp(value.c_str(), until, untilcontext)==0) goto incompat; // invalid end date calculateEndDate = false; } // check for count else if (key == "COUNT") { // convert count for (int i = 0, ii = value.length(); i < ii; ++i) { if (isdigit(value[i])) { cnt = cnt * 10 + ((value[i]) - '0'); } } // check if no count or one only if (cnt <= 1) goto norep; // no repetition // we need to recalculate the enddate from count calculateEndDate = true; } // check for interval else if (key == "INTERVAL") { // convert interval interval = 0; for (int i = 0, ii = value.length(); i < ii; ++i) { if (isdigit(value[i])) { interval = interval * 10 + ((value[i]) - '0'); } } if (interval == 0) goto incompat; // invalid interval } // just copy all supported BYxxx rules into vars else if (key == "BYDAY") byday = value; else if (key == "BYMONTHDAY") bymonthday = value; else if (key == "BYMONTH") bymonth = value; // ignore week start else if (key == "WKST") { // nop } else goto incompat; // unknown directive } // while #ifdef SYDEBUG LOGDEBUGPRINTFX(aLogP,DBG_PARSE+DBG_EXOTIC,("- dtstart weekday is %i", startwday)); LOGDEBUGPRINTFX(aLogP,DBG_PARSE+DBG_EXOTIC,("- extracted interval %u", interval)); LOGDEBUGPRINTFX(aLogP,DBG_PARSE+DBG_EXOTIC,("- extracted interval (2nd time) %u", interval)); LOGDEBUGPRINTFX(aLogP,DBG_PARSE+DBG_EXOTIC,("- extracted count %u", cnt)); LOGDEBUGPRINTFX(aLogP,DBG_PARSE+DBG_EXOTIC,("- end date calc required? %s", calculateEndDate ? "true" : "false")); LOGDEBUGPRINTFX(aLogP,DBG_PARSE+DBG_EXOTIC,("- extracted byday %s", byday.c_str())); LOGDEBUGPRINTFX(aLogP,DBG_PARSE+DBG_EXOTIC,("- extracted bymonthday %s", bymonthday.c_str())); LOGDEBUGPRINTFX(aLogP,DBG_PARSE+DBG_EXOTIC,("- extracted bymonth %s", bymonth.c_str())); TimestampToISO8601Str(abc,until,startcontext,false,false); LOGDEBUGPRINTFX(aLogP,DBG_PARSE+DBG_EXOTIC,("- extracted until %s", abc.c_str())); #endif // Generally, we only support one BYxxx, not combinations. However, FREQ=YEARLY + BYMONTH + BYDAY is common // to express start and end times of DST in VTIMEZONEs, so we convert these into equivalent FREQ=MONTHLY if (freq=='Y' && !byday.empty() && !bymonth.empty() && bymonth.find(",")==string::npos) { // yearly by (single!) month and by day // - get month as indicated by BYMONTH sInt16 newStartMonth = 0; if (StrToShort(bymonth.c_str(), newStartMonth)>0 && newStartMonth) { // - check if BYMONTH is just redundant and references same month as start date bool convertToMonthly = startmonth>0 && startmonth==newStartMonth; if (!convertToMonthly && aNewStartP) { // not redundant, but we can return a new start date convertToMonthly = true; // calculate the new start date startmonth = newStartMonth; dtstart = date2lineartime(startyear, startmonth, startday) + lineartime2timeonly(dtstart); LOGDEBUGPRINTFX(aLogP,DBG_PARSE+DBG_EXOTIC,("- moved recurrence origin to %04hd-%02hd-%02hd",startyear, startmonth, startday)); // pass it back to caller calculateFirstOccurrence = true; // need to fine tune at the end *aNewStartP = dtstart; } if (convertToMonthly) { LOGDEBUGPRINTFX(aLogP,DBG_PARSE+DBG_EXOTIC,("- converted FREQ=YEARLY BYMONTH into MONTHLY")); freq = 'M'; // convert from YEARLY to MONTHLY interval = 12*interval; // but with 12 months interval -> equivalent bymonth.erase(); // forget BYMONTH clause } } } // if FREQ=YEARLY + BYMONTH + BYDAY // check freq endIndex = 0; startIndex = 0; switch (freq) { case 'D' : // make weekly if byday and nothing else is set if (!(byday == "") && bymonth == "" && bymonthday == "") { freq='W'; freqmod='W'; // search separator ',' while ((endIndex = byday.find(",", startIndex)) != string::npos) { // set masks for the specific day if (!setWeekday(byday, firstmask, lastmask, startIndex, endIndex, false)) goto incompat; // set new start startIndex = endIndex + 1; if (startIndex >= byday.length()) break; } // check if anything is behind endindex if (endIndex == string::npos && startIndex < byday.length()) { endIndex = byday.length(); if (!setWeekday(byday, firstmask, lastmask, startIndex, endIndex, false)) goto incompat; } } else { // we don't support byday and anything else at the same time if (!byday.empty()) goto incompat; // ok, no mod freqmod = ' '; } break; case 'W' : // we don't support month or monthday within weekly if (!bymonth.empty() || !bymonthday.empty()) goto incompat; // set weekly and days freqmod='W'; if (!byday.empty()) { // search separator ',' while ((endIndex = byday.find(",", startIndex)) != string::npos) { // set masks for the specific day if (!setWeekday(byday, firstmask, lastmask, startIndex, endIndex, false)) goto incompat; // set new start startIndex = endIndex + 1; if (startIndex >= byday.length()) break; } // check if anything is behind endindex if (endIndex == string::npos && startIndex < byday.length()) { endIndex = byday.length(); if (!setWeekday(byday, firstmask, lastmask, startIndex, endIndex, false)) goto incompat; } } break; case 'M' : // we don't support by month in monthly if (!bymonth.empty()) goto incompat; // we don't support byday and bymonthday at the same time if (!byday.empty() && !bymonthday.empty()) goto incompat; // check if bymonthday if (!bymonthday.empty()) { freqmod = 'D'; // search separator ',' while ((endIndex = bymonthday.find(",", startIndex)) != string::npos) { // set masks for the specific day if (!setMonthDay(bymonthday, firstmask, lastmask, startIndex, endIndex)) goto incompat; // set new start startIndex = endIndex + 1; if (startIndex >= bymonthday.length()) break; } // check if anything is behind endindex if (endIndex == string::npos && startIndex < bymonthday.length()) { endIndex = bymonthday.length(); if (!setMonthDay(bymonthday, firstmask, lastmask, startIndex, endIndex)) goto incompat; } } // or if by weekday else if (!byday.empty()) { freqmod = 'W'; // search separator ',' while ((endIndex = byday.find(",", startIndex)) != string::npos) { // set masks for the specific day if (!setWeekday(byday, firstmask, lastmask, startIndex, endIndex, true)) goto incompat; // set new start startIndex = endIndex + 1; if (startIndex >= byday.length()) break; } // check if anything is behind endindex if (endIndex == string::npos && startIndex < byday.length()) { endIndex = byday.length(); if (!setWeekday(byday, firstmask, lastmask, startIndex, endIndex, true)) goto incompat; } } else { // fine, no mod freqmod = ' '; } break; case 'Y' : if ( byday == "" || (byday.length() == 2 && byday[0] == RRULE_weekdays[startwday][0] && byday[1] == RRULE_weekdays[startwday][1]) ) { temp.erase(); sprintf(s, "%hd", startday); temp.append(s); LOGDEBUGPRINTFX(aLogP,DBG_PARSE+DBG_EXOTIC,("- bymonthday checking %s against %s", temp.c_str(), bymonthday.c_str())); if (bymonthday == "" || bymonthday == temp) { temp.erase(); sprintf(s, "%hd", startmonth); temp.append(s); LOGDEBUGPRINTFX(aLogP,DBG_PARSE+DBG_EXOTIC,("- bymonth checking %s against %s", temp.c_str(), bymonth.c_str())); if (bymonth == "" || bymonth == temp) { // this should usually be ' ' but the vcard conversion has a bug and requires 'M' freqmod = 'M'; lastmask = 0; firstmask = 0; } else goto incompat; } else goto incompat; } else goto incompat; break; default : LOGDEBUGPRINTFX(aLogP,DBG_PARSE+DBG_EXOTIC,("- strange self-set freq %c, rule was %s", freq, aText)); break; } // switch // calc end date, assumption/make sure: cnt > 1 if (calculateEndDate) { LOGDEBUGPRINTFX(aLogP,DBG_PARSE+DBG_EXOTIC,("- calculating end date now")); if (!endDateFromCount(until,dtstart,freq,freqmod,interval,firstmask,lastmask,cnt,true,aLogP)) goto norep; untilcontext = startcontext; // until is in same context as start } // calculate exact date of first occurrence if (calculateFirstOccurrence && aNewStartP) { TRRuleExpandStatus es; initRRuleExpansion(es, dtstart, freq, freqmod, interval, firstmask, lastmask, dtstart, noLinearTime); dtstart = getNextOccurrence(es); if (LOGDEBUGTEST(aLogP,DBG_PARSE+DBG_EXOTIC)) { sInt16 ny,nm,nd; lineartime2date(dtstart,&ny,&nm,&nd); LOGDEBUGPRINTFX(aLogP,DBG_PARSE+DBG_EXOTIC,("- adjusted first occurrence date to %04hd-%02hd-%02hd",ny, nm, nd)); } *aNewStartP = dtstart; } // parsed ok, now store it goto store; norep: // no repetition (but no parse error generated) freq='0'; // frequency = none freqmod=' '; // frequency modifier interval=0; // interval firstmask=0; // day mask counted from the first day of the period lastmask=0; // day mask counted from the last day of the period until= noLinearTime; // last day store: #ifdef SYDEBUG LOGDEBUGPRINTFX(aLogP,DBG_PARSE+DBG_EXOTIC,("- leaving with freq %c, freqmod %c, interval %hd, firstmask %ld, lastmask %ld", freq, freqmod, interval, (long)firstmask, (long)lastmask)); TimestampToISO8601Str(abc,until,untilcontext,false,false); LOGDEBUGPRINTFX(aLogP,DBG_PARSE+DBG_EXOTIC,("RRULE2toInternal(): extracted until '%s'", abc.c_str())); #endif return true; // ok incompat: // incompatible, value cannot be parsed usefully return false; // no value generated } // RRULE2toInternal // appends the firstmask and lastmask as numbers to the string. // all values are increased by one prior to adding them to string. void appendMaskAsNumbers( cAppCharP aPrefix, // if list is not empty, this will be appended in front of the list string &aString, // receives list string fieldinteger_t firstmask, fieldinteger_t lastmask ) { fieldinteger_t m = firstmask; int i,k; for (i=0; i<2; i++) { // - show day numbers for (k=0; k<32; k++) { if (m & ((uInt64)1<0) aString+='-'; StringObjAppendPrintf(aString,"%d",k+1); } } // - switch to those that are relative to the end of the month / year m = lastmask; } } // appendMaskAsNumbers // returns the next directive for the ical format bool getNextDirective( string &aString, const char *aText, int &aStart ) { // check if (*aText == 0) { return false; } char c; // check start if (aStart > 0) { // skip to start for (int i = 0; (i < aStart) && ((c = *aText) != 0); ++i) aText++; } else { // skip all spaces while ((c = *aText) == ' ') { aText++; } } // erase string, set counter aString.erase(); uInt16 counter = 0; // append text c = *aText++; aStart++; while (c != 0 && c != ';') { aString.append(1, c); ++counter; c = *aText++; aStart++; } // empty? if (counter == 0) return false; // remove trailing whitespace sInt16 i = counter - 1; while (i >= 0 && aString[i] == ' ') { aString.erase(i, 1); --i; } // check length if (i == -1) return false; // fine return true; } // getNextDirective // maps the byday rule into the masks bool setWeekday( const string &byday, fieldinteger_t &firstmask, fieldinteger_t &lastmask, string::size_type &startIndex, const string::size_type &endIndex, bool allowSpecial ) { // remove leading spaces while (byday[startIndex] == ' ' && startIndex < endIndex) { ++startIndex; } // check if digit or sign if (isdigit(byday[startIndex]) || byday[startIndex] == '+' || byday[startIndex] == '-') { // check if numbers before week days are allowed if (!allowSpecial) { return false; } // special treatment return setSpecialWeekday(byday, firstmask, lastmask, startIndex, endIndex); } // get index of weekday array sInt16 weekdayIndex = getWeekdayIndex(byday, startIndex); if (weekdayIndex == -1) { return false; } // put into mask if (!allowSpecial) { firstmask |= ((uInt64)1<= endIndex - 1) { return false; } // get index for weekday sInt16 index = getWeekdayIndex(byday, startIndex); if (index == -1) { return false; } // put into mask if (isNegative) { lastmask |= (((uInt64)1< #include "lineartime.h" #endif using namespace sysync; namespace sysync { #ifdef FULLY_STANDALONE typedef sInt64 fieldinteger_t; class TDebugLogger; #endif #ifdef SYSYNC_TOOL // convert between RRULE and internal format int rruleConv(int argc, const char *argv[]); #endif #ifdef MOBOSX // make this usable by the Todo+Cal app #define PUBLIC_ENTRY extern "C" #define PUBLIC_ENTRY_ATTR __attribute__((visibility("default"))) #else #define PUBLIC_ENTRY #define PUBLIC_ENTRY_ATTR #endif const int DaysOfWeek = 7; const int WeeksOfMonth= 5; #ifdef SYNTHESIS_UNIT_TEST // RRULE expansion tests bool test_expand_rrule(void); #endif // Converts internal recurrence into vCalendar 1.0 RRULE string bool internalToRRULE1( string &aString, // receives RRULE string char freq, char freqmod, sInt16 interval, fieldinteger_t firstmask, fieldinteger_t lastmask, lineartime_t until, timecontext_t untilcontext, TDebugLogger *aLogP ); // Converts internal recurrence into vCalendar 2.0 RRULE string bool internalToRRULE2( string &aString, // receives RRULE string char freq, char freqmod, sInt16 interval, fieldinteger_t firstmask, fieldinteger_t lastmask, lineartime_t until, timecontext_t untilcontext, TDebugLogger *aLogP ); // Converts vCalendar 1.0 RRULE string into internal recurrence representation bool RRULE1toInternal( const char *aText, // RRULE string to be parsed lineartime_t dtstart, // reference date for parsing RRULE timecontext_t startcontext, // context of reference date, until will be in same context char &freq, char &freqmod, sInt16 &interval, fieldinteger_t &firstmask, fieldinteger_t &lastmask, lineartime_t &until, timecontext_t &untilcontext, TDebugLogger *aLogP ); // Converts vCalendar 2.0 RRULE string into internal recurrence representation bool RRULE2toInternal( const char *aText, // RRULE string to be parsed lineartime_t dtstart, // reference date for parsing RRULE timecontext_t startcontext, // context of reference date, until will be in same context char &freq, char &freqmod, sInt16 &interval, fieldinteger_t &firstmask, fieldinteger_t &lastmask, lineartime_t &until, timecontext_t &untilcontext, TDebugLogger *aLogP, lineartime_t *aNewStartP = NULL // optional, if not NULL, conversion may return modified start date ); /// @brief recurrence rule expansion status record typedef struct { // recurrence definition parameters char freq; char freqmod; sInt16 interval; fieldinteger_t firstmask; fieldinteger_t lastmask; sInt16 weekstart; // 0=Su, 1=Mo... // bit anaalysis for speedup sInt16 singleFMaskBit; // if >=0, only this bit number is set in firstmask and none in lastmask. // start and end point of recurrence lineardate_t expansionStartDayOffset; lineartime_t expansionEnd; // internal status // - start point sInt16 startyear,startmonth,startday; lineartime_t starttime; // time part for re-adding after expansion // - current point of expansion lineartime_t cursor; sInt16 cursorWDay; // weekday sInt16 cursorMLen; // length of month // - set if started (i.e. advanced cursor to first valid recurrence) bool started; } TRRuleExpandStatus; /// @brief initialize expansion of RRule PUBLIC_ENTRY void initRRuleExpansion( TRRuleExpandStatus &es, lineartime_t aDtstart, char aFreq, char aFreqmod, sInt16 aInterval, fieldinteger_t aFirstmask, fieldinteger_t aLastmask, lineartime_t aExpansionStart=noLinearTime, lineartime_t aExpansionEnd=noLinearTime ); /// @brief get next occurrence /// @return noLinearTime if no next occurrence exists, lineartime of next occurrence otherwise PUBLIC_ENTRY lineartime_t getNextOccurrence(TRRuleExpandStatus &es); /// @brief calculate end date of RRULE when count is specified /// @return true if repeating, false if not repeating at all /// @note returns until=noLinearTime for endless repeat (count=0) /// @note this is made public as TodoZ iPhone app uses it for calendar recurrence expansion PUBLIC_ENTRY bool endDateFromCount( lineartime_t &until, lineartime_t dtstart, char freq, char freqmod, sInt16 interval, fieldinteger_t firstmask,fieldinteger_t lastmask, sInt16 cnt, bool countsoccurrences, TDebugLogger *aLogP ) PUBLIC_ENTRY_ATTR; /// @brief calculate number of recurrences from specified end date of RRULE /// @return true if count could be calculated, false otherwise /// @note returns until=noLinearTime for endless repeat (count=0) bool countFromEndDate( sInt16 &cnt, bool countsoccurrences, lineartime_t dtstart, char freq, char freqmod, sInt16 interval, fieldinteger_t firstmask,fieldinteger_t lastmask, lineartime_t until, TDebugLogger *aLogP ); // appends the firstmask and lastmask as numbers to the string. // all values are increased by one prior to adding them to string. void appendMaskAsNumbers( cAppCharP aPrefix, // if list is not empty, this will be appended in front of the list string &aString, // receives list string fieldinteger_t firstmask, fieldinteger_t lastmask ); // returns the next directive for the ical format bool getNextDirective( string &aString, const char *aText, int &aStart ); // maps the byday rule into the masks bool setWeekday( const string &byday, fieldinteger_t &firstmask, fieldinteger_t &lastmask, string::size_type &startIndex, const string::size_type &endIndex, bool allowSpecial ); // maps a special weekday (+/- int WEEKDAY) into the masks bool setSpecialWeekday( const string &byday, fieldinteger_t &firstmask, fieldinteger_t &lastmask, string::size_type &startIndex, const string::size_type &endIndex ); // returns the index within the rrule weekday array for the next // two chars of the supplied string starting at startIndex sInt16 getWeekdayIndex( const string &byday, sInt16 startIndex ); // set a day in month bool setMonthDay( const string &bymonthday, fieldinteger_t &firstmask, fieldinteger_t &lastmask, string::size_type &startIndex, const string::size_type &endIndex ); } // namespace sysync #endif // RRULES_H /* eof */ libsynthesis-3.4.0.47.1/src/sysync/scriptcontext.cpp000077500000000000000000005511521226375725500224140ustar00rootroot00000000000000/* * File: scriptcontext.cpp * * Author: Lukas Zeller (luz@plan44.ch) * * TScriptContext * Environment to tokenize, prepare and run scripts * * Copyright (c) 2002-2011 by Synthesis AG + plan44.ch * * 2002-09-11 : luz : created * */ #include "prefix_file.h" #ifdef SCRIPT_SUPPORT // includes #include "scriptcontext.h" #include "platform_exec.h" // for SHELLEXECUTE #include "rrules.h" // for RECURRENCE_COUNT/DATE #include "vtimezone.h" // for SETTIMEZONE #include "mimediritemtype.h" // for AlldayCount/MakeAllday #ifdef REGEX_SUPPORT #include "pcre.h" // for RegEx functions #endif #include #include // script debug messages #ifdef SYDEBUG #define SCRIPTDBGMSGX(lvl,x) { if (debugon && fSessionP) { POBJDEBUGPRINTFX(fSessionP,lvl,x); } } #define SCRIPTDBGMSG(x) SCRIPTDBGMSGX(DBG_SCRIPTS,x) #define SCRIPTDBGSTART(nam) { if (debugon && fSessionP) { if (fSessionP->getDbgMask() & DBG_SCRIPTS) { fSessionP->PDEBUGBLOCKFMTCOLL(("ScriptExecute","Start executing Script","name=%s",nam)); } else { POBJDEBUGPRINTFX(fSessionP,DBG_DATA,("Executing Script '%s'",nam)); } } } #define SCRIPTDBGEND() { if (debugon && fSessionP && (fSessionP->getDbgMask() & DBG_SCRIPTS)) { fSessionP->PDEBUGENDBLOCK("ScriptExecute"); } } #define SCRIPTDBGTEST (debugon && fSessionP && (fSessionP->getDbgMask() & DBG_SCRIPTS)) #define EXPRDBGTEST (debugon && fSessionP && ((fSessionP->getDbgMask() & (DBG_SCRIPTS|DBG_SCRIPTEXPR)) == (DBG_SCRIPTS|DBG_SCRIPTEXPR))) #define DBGSTRINGDEF(s) string s #define DBGVALUESHOW(s,v) dbgValueShow(s,v) #if SYDEBUG>1 #define SHOWVARDEFS(t) showVarDefs(t) #else #define SHOWVARDEFS(t) #endif #else #define SCRIPTDBGMSGX(lvl,x) #define SCRIPTDBGMSG(x) #define SCRIPTDBGSTART(nam) #define SCRIPTDBGEND() #define SCRIPTDBGTEST false #define EXPRDBGTEST false #define DBGSTRINGDEF(s) #define DBGVALUESHOW(s,v) #define SHOWVARDEFS(t) #endif namespace sysync { #ifdef SYDEBUG // show value of a field static void dbgValueShow(string &aString, TItemField *aFieldP) { TItemFieldTypes ty; if (aFieldP) { // value aString = "&html;&html;"; aFieldP->StringObjFieldAppend(aString,200); aString += "&html;&html;"; // add type info ty=aFieldP->getType(); aString += " ("; aString += ItemFieldTypeNames[ty]; aString += ")"; } else { aString=""; } } // dbgValueShow #endif TTokenizeException::TTokenizeException(cAppCharP aScriptName, cAppCharP aMsg1,cAppCharP aScript, uInt16 aIndex, uInt16 aLine) : TConfigParseException("") { cAppCharP p2=aScript+aIndex; cAppCharP p1=p2-(aIndex>5 ? 5 : aIndex); StringObjPrintf(fMessage, "%s: %s at line %hd: '...%-.5s_%-.10s...'", aScriptName ? aScriptName : "", aMsg1, aLine, p1, p2 ); } // TTokenizeException::TTokenizeException TScriptErrorException::TScriptErrorException(cAppCharP aMsg1, uInt16 aLine, cAppCharP aIdent) : TConfigParseException("") { if (aIdent) { StringObjPrintf(fMessage,aMsg1,aIdent); } else { StringObjPrintf(fMessage,"%s",aMsg1); } StringObjAppendPrintf( fMessage, " in script at line %hd", aLine ); } // TScriptErrorException::TScriptErrorException /* * Implementation of TScriptConfig */ // config constructor TScriptConfig::TScriptConfig(TConfigElement *aParentElementP) : TConfigElement("scripting",aParentElementP) { clear(); } // TScriptConfig::TScriptConfig // config destructor TScriptConfig::~TScriptConfig() { clear(); } // TScriptConfig::~TScriptConfig // init defaults void TScriptConfig::clear(void) { // delete options fMaxLoopProcessingTime = #if SYDEBUG>1 60; // 1 min for debugging #else 5; // 5 seconds for real execution #endif // delete functions TUserScriptList::iterator pos; for (pos=fFunctionScripts.begin();pos!=fFunctionScripts.end();++pos) { delete (*pos); } fFunctionScripts.clear(); fScriptMacros.clear(); // clear inherited inherited::clear(); } // TScriptConfig::clear // server config element parsing bool TScriptConfig::localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine) { // checking the elements if (strucmp(aElementName,"looptimeout")==0) expectUInt32(fMaxLoopProcessingTime); else if (strucmp(aElementName,"function")==0) { // create new function definition TUserScriptFunction *funcdefP = new TUserScriptFunction; fFunctionScripts.push_back(funcdefP); expectFunction(*funcdefP,aLine); } else if (strucmp(aElementName,"macro")==0) { const char *macroname = getAttr(aAttributes,"name"); if (!macroname) fail(" must have a 'name' attribute"); // create new macro expectRawString(fScriptMacros[macroname]); } // - none known here else return inherited::localStartElement(aElementName,aAttributes,aLine); // ok return true; } // TScriptConfig::localStartElement // resolve void TScriptConfig::localResolve(bool aLastPass) { // resolve inherited inherited::localResolve(aLastPass); } // TScriptConfig::localResolve // get script text string *TScriptConfig::getFunctionScript(sInt16 aFuncIndex) { if (aFuncIndex<0 || aFuncIndex>(sInt16)fFunctionScripts.size()) return NULL; return &(fFunctionScripts[aFuncIndex]->fFuncDef); } // TScriptConfig::getFunctionScript // get index of specific function sInt16 TScriptConfig::getFunctionIndex(cAppCharP aName, size_t aLen) { TUserScriptList::iterator pos; sInt16 i=0; for (pos=fFunctionScripts.begin();pos!=fFunctionScripts.end();++pos) { if (strucmp((*pos)->fFuncName.c_str(),aName)==0) return i; i++; } // unknown return VARIDX_UNDEFINED; } // TScriptConfig::getFunctionIndex // Script variable definition // create new scrip variable definition TScriptVarDef::TScriptVarDef(cAppCharP aName,uInt16 aIdx, TItemFieldTypes aType, bool aIsArray, bool aIsRef, bool aIsOpt) { fVarName=aName; fIdx=aIdx; fVarType=aType; fIsArray=aIsArray; fIsRef=aIsRef; fIsOpt=aIsOpt; } // TScriptVarDef::TScriptVarDef TScriptVarDef::~TScriptVarDef() { } // TScriptVarDef::~TScriptVarDef /* * builtin function definitions */ class TBuiltinStdFuncs { public: // timestamp NOW() // returns current date/time stamp in UTC with timezone set static void func_Now(TItemField *&aTermP, TScriptContext *aFuncContextP) { TTimestampField *tsP = static_cast(aTermP); tsP->setTimestampAndContext( getSystemNowAs(TCTX_UTC, tsP->getGZones()), TCTX_UTC ); }; // func_Now // timestamp SYSTEMNOW() // returns current date/time stamp as system time with timezone set static void func_SystemNow(TItemField *&aTermP, TScriptContext *aFuncContextP) { TTimestampField *tsP = static_cast(aTermP); tsP->setTimestampAndContext( getSystemNowAs(TCTX_SYSTEM, tsP->getGZones()), TCTX_SYSTEM ); }; // func_SystemNow // timestamp DBNOW() // returns database's idea of "now" in UTC with local timezone set static void func_DbNow(TItemField *&aTermP, TScriptContext *aFuncContextP) { TTimestampField *tsP = static_cast(aTermP); tsP->setTimestampAndContext( aFuncContextP->getSession()->getDatabaseNowAs(TCTX_UTC), TCTX_UTC ); }; // func_DbNow // integer ZONEOFFSET(timestamp atime) // returns zone offset for given timestamp. // New in 3.1: Floating timestamps return unassigned static void func_ZoneOffset(TItemField *&aTermP, TScriptContext *aFuncContextP) { TTimestampField *tsP = static_cast(aFuncContextP->getLocalVar(0)); sInt16 moffs=0; if (tsP->isFloating()) { // floating timestamps do not have an offset aTermP->unAssign(); } else { moffs = tsP->getMinuteOffset(); aTermP->setAsInteger((sInt32)moffs*SecsPerMin); } }; // func_ZoneOffset // helper to get a time context from integer seconds offset or string zone name static timecontext_t contextFromSpec(TItemField *aVariantP, TScriptContext *aFuncContextP) { timecontext_t tctx = TCTX_UNKNOWN; if (aVariantP->isBasedOn(fty_timestamp)) { // just use context of another timestamp tctx = static_cast(aVariantP)->getTimeContext(); } else if (aVariantP->getCalcType()==fty_integer) { // integer specifies a seconds offset tctx = TCTX_MINOFFSET(aVariantP->getAsInteger() / SecsPerMin); } else if (aVariantP->isEmpty()) { // empty non-timestamp and non-integer mean unknown/floating timezone tctx = TCTX_UNKNOWN; } else { // treat as string specifying time zone by name or vTimezone string str; aVariantP->getAsString(str); if (strucmp(str.c_str(),"USERTIMEZONE")==0) { // special case - session's user time zone tctx = aFuncContextP->getSession()->fUserTimeContext; } else if (strucmp(str.c_str(),"SYSTEM")==0) { tctx = TCTX_SYSTEM; } else if (strucmp(str.c_str(),"BEGIN:VTIMEZONE",15)==0) { // is a vTimezone, get it if (!VTIMEZONEtoInternal(str.c_str(), tctx, aFuncContextP->getSession()->getSessionZones(),aFuncContextP->getSession()->getDbgLogger())) tctx = TCTX_UNKNOWN; } else { // search for timezone by name (internal or olson) if (!TimeZoneNameToContext(str.c_str(), tctx, aFuncContextP->getSession()->getSessionZones(), true)) { // last attempt is parsing it as a ISO8601 offset spec ISO8601StrToContext(str.c_str(), tctx); } } } return tctx; } // contextFromSpec // helper to represent a time context as string static void zoneStrFromContext(timecontext_t aContext, TItemField *aZoneStrFieldP, TScriptContext *aFuncContextP) { string str; if (TCTX_IS_UNKNOWN(aContext)) { // no time zone aZoneStrFieldP->unAssign(); } else if (TCTX_IS_TZ(aContext)) { // symbolic time zone, show name TimeZoneContextToName(aContext,str,aFuncContextP->getSession()->getSessionZones()); aZoneStrFieldP->setAsString(str); } else { // is non-symbolic minute offset, show it in ISO8601 extended form str.erase(); ContextToISO8601StrAppend(str, aContext, true); } } // zoneStrFromContext // string TIMEZONE(timestamp atime) // returns time zone name static void func_Timezone(TItemField *&aTermP, TScriptContext *aFuncContextP) { TTimestampField *tsP = static_cast(aFuncContextP->getLocalVar(0)); zoneStrFromContext(tsP->getTimeContext(), aTermP, aFuncContextP); }; // func_Timezone // string VTIMEZONE(timestamp atime) // returns time zone in VTIMEZONE format static void func_VTimezone(TItemField *&aTermP, TScriptContext *aFuncContextP) { TTimestampField *tsP = static_cast(aFuncContextP->getLocalVar(0)); string z; internalToVTIMEZONE(tsP->getTimeContext(),z,aFuncContextP->getSession()->getSessionZones()); aTermP->setAsString(z); }; // func_VTimezone // SETTIMEZONE(timestamp &atime,variant zonespec) // sets time zone for given timestamp field static void func_SetTimezone(TItemField *&aTermP, TScriptContext *aFuncContextP) { TTimestampField *tsP = static_cast(aFuncContextP->getLocalVar(0)); // get context from variant spec timecontext_t tctx = contextFromSpec(aFuncContextP->getLocalVar(1), aFuncContextP); // set it tsP->setTimeContext(tctx); }; // func_SetTimezone // SETFLOATING(timestamp &atime) // sets given timestamp to floating (no timezone) // this is an efficient shortform for SETTIMEZONE(atime,"FLOATING") or SETTIMEZONE(atime,"") static void func_SetFloating(TItemField *&aTermP, TScriptContext *aFuncContextP) { TTimestampField *tsP = static_cast(aFuncContextP->getLocalVar(0)); // set it tsP->setTimeContext(TCTX_UNKNOWN); }; // func_SetFloating // timestamp CONVERTTOZONE(timestamp atime, variant zonespec [,boolean doUnfloat]) // returns timestamp converted to specified zone. // - If doUnfloat, floating timestamps will be fixed in the new zone w/o conversion of the timestamp itself. // - timestamps that already have a zone will be converted static void func_ConvertToZone(TItemField *&aTermP, TScriptContext *aFuncContextP) { TTimestampField *tsP = static_cast(aFuncContextP->getLocalVar(0)); // get context from variant spec timecontext_t actual,tctx = contextFromSpec(aFuncContextP->getLocalVar(1), aFuncContextP); // convert and get actually resulting context back (can also be floating) lineartime_t ts = tsP->getTimestampAs(tctx,&actual); // unfloat floats if selected if (aFuncContextP->getLocalVar(2)->getAsBoolean() && TCTX_IS_UNKNOWN(actual)) actual=tctx; // unfloat // assign it to result static_cast(aTermP)->setTimestampAndContext(ts,actual); }; // func_ConvertToZone // timestamp CONVERTTOUSERZONE(timestamp atime [,boolean doUnfloat]) // returns timestamp converted to user time zone.(or floating timestamp as-is) // - this is an efficient shortform for CONVERTTOZONE(atime,"USERTIMEZONE") // - If doUnfloat, floating timestamps will be fixed in the new zone w/o conversion of the timestamp itself. // - timestamps that already have a zone will be converted static void func_ConvertToUserZone(TItemField *&aTermP, TScriptContext *aFuncContextP) { TTimestampField *tsP = static_cast(aFuncContextP->getLocalVar(0)); timecontext_t actual,tctx = aFuncContextP->getSession()->fUserTimeContext; // convert and get actually resulting context back (can also be floating) lineartime_t ts = tsP->getTimestampAs(tctx,&actual); // unfloat floats if selected if (aFuncContextP->getLocalVar(1)->getAsBoolean() && TCTX_IS_UNKNOWN(actual)) actual=tctx; // unfloat // assign it to result static_cast(aTermP)->setTimestampAndContext(ts,actual); }; // func_ConvertToUserZone // string USERTIMEZONE() // returns session user time zone name static void func_UserTimezone(TItemField *&aTermP, TScriptContext *aFuncContextP) { zoneStrFromContext(aFuncContextP->getSession()->fUserTimeContext,aTermP, aFuncContextP); }; // func_UserTimezone // SETUSERTIMEZONE(variant zonespec) // sets session user time zone static void func_SetUserTimezone(TItemField *&aTermP, TScriptContext *aFuncContextP) { // get context from variant spec timecontext_t tctx = contextFromSpec(aFuncContextP->getLocalVar(1), aFuncContextP); aFuncContextP->getSession()->fUserTimeContext = tctx; }; // func_SetUserTimezone // integer ISDATEONLY(timestamp atime) // returns true if given timestamp is a date-only static void func_IsDateOnly(TItemField *&aTermP, TScriptContext *aFuncContextP) { TTimestampField *tsP = static_cast(aFuncContextP->getLocalVar(0)); aTermP->setAsInteger(TCTX_IS_DATEONLY(tsP->getTimeContext()) ? 1 : 0); }; // func_IsDateOnly // timestamp DATEONLY(timestamp atime) // returns a floating(!) date-only of the given timestamp static void func_DateOnly(TItemField *&aTermP, TScriptContext *aFuncContextP) { TTimestampField *tsP = static_cast(aFuncContextP->getLocalVar(0)); // get timestamp as dateonly timecontext_t tctx; lineartime_t ts; ts = tsP->getTimestampAs(TCTX_UNKNOWN | TCTX_DATEONLY, &tctx); // assign it to result (but do NOT pass in tctx, as it might contain a zone // but we need it as floating to make dates comparable static_cast(aTermP)->setTimestampAndContext(ts,TCTX_DATEONLY|TCTX_UNKNOWN); }; // func_DateOnly // timestamp TIMEONLY(timestamp atime) // returns a floating(!) time-only of the given timestamp static void func_TimeOnly(TItemField *&aTermP, TScriptContext *aFuncContextP) { TTimestampField *tsP = static_cast(aFuncContextP->getLocalVar(0)); // get timestamp as dateonly timecontext_t tctx; lineartime_t ts; ts = tsP->getTimestampAs(TCTX_UNKNOWN | TCTX_TIMEONLY, &tctx); // assign it to result (but do NOT pass in tctx, as it might contain a zone // but we need it as floating to make dates comparable static_cast(aTermP)->setTimestampAndContext(ts,TCTX_TIMEONLY|TCTX_UNKNOWN); }; // func_TimeOnly // integer ISDURATION(timestamp atime) // returns true if given timestamp is a duration value static void func_IsDuration(TItemField *&aTermP, TScriptContext *aFuncContextP) { TTimestampField *tsP = static_cast(aFuncContextP->getLocalVar(0)); aTermP->setAsInteger(tsP->isDuration() ? 1 : 0); }; // func_IsDuration // timestamp DURATION(timestamp atime) // returns the timestamp as a duration (floating, duration flag set) static void func_Duration(TItemField *&aTermP, TScriptContext *aFuncContextP) { TTimestampField *tsP = static_cast(aFuncContextP->getLocalVar(0)); // get timestamp as-is timecontext_t tctx; lineartime_t ts; ts = tsP->getTimestampAs(TCTX_UNKNOWN, &tctx); // result is floating timestamp with duration flag set (and dateonly/timeonly flags retained) static_cast(aTermP)->setTimestampAndContext(ts,TCTX_UNKNOWN|(tctx&TCTX_RFLAGMASK)|TCTX_DURATION); }; // func_Duration // timestamp POINTINTIME(timestamp atime) // returns the timestamp as a point in time (i.e. not duration and not dateonly/timeonly) static void func_PointInTime(TItemField *&aTermP, TScriptContext *aFuncContextP) { TTimestampField *tsP = static_cast(aFuncContextP->getLocalVar(0)); // get timestamp as-is timecontext_t tctx; lineartime_t ts; ts = tsP->getTimestampAs(TCTX_UNKNOWN, &tctx); // assign it to result with duration and dateonly flag cleared static_cast(aTermP)->setTimestampAndContext(ts,tctx & (~(TCTX_DURATION+TCTX_DATEONLY+TCTX_TIMEONLY))); }; // func_PointInTime // integer ISFLOATING(timestamp atime) // returns true if given timestamp is floating (i.e. not bound to a time zone) static void func_IsFloating(TItemField *&aTermP, TScriptContext *aFuncContextP) { TTimestampField *tsP = static_cast(aFuncContextP->getLocalVar(0)); aTermP->setAsInteger(tsP->isFloating() ? 1 : 0); }; // func_IsFloating // integer ALLDAYCOUNT(timestamp start, timestamp end [, boolean checkinusercontext [, onlyutcinusercontext]]) // returns number of days for an all-day event // Note: Timestamps must be in the context in which they are to be checked for midnight, 23:59:xx etc. // except if checkinusercontext ist set (then non-floating timestamps are moved into user context before // checking. onlyutcinusercontext limits moving to user context to UTC timestamps only. static void func_AlldayCount(TItemField *&aTermP, TScriptContext *aFuncContextP) { sInt16 c = AlldayCount( aFuncContextP->getLocalVar(0), aFuncContextP->getLocalVar(1), aFuncContextP->getLocalVar(2)->getAsBoolean() ? aFuncContextP->getSession()->fUserTimeContext : TCTX_UNKNOWN, aFuncContextP->getLocalVar(3)->getAsBoolean() ); aTermP->setAsInteger(c); }; // func_AlldayCount // MAKEALLDAY(timestamp &start, timestamp &end [,integer days]) // adjusts timestamps for allday representation, makes them floating // Note: Timestamps must already represent local day times static void func_MakeAllday(TItemField *&aTermP, TScriptContext *aFuncContextP) { sInt16 days=aFuncContextP->getLocalVar(2)->getAsInteger(); // returns 0 if unassigned MakeAllday( aFuncContextP->getLocalVar(0), aFuncContextP->getLocalVar(1), TCTX_UNKNOWN, days ); }; // func_MakeAllday // integer WEEKDAY(timestamp timestamp) // returns weekday (0=sunday, 1=monday ... 6=saturday) from a timestamp static void func_Weekday(TItemField *&aTermP, TScriptContext *aFuncContextP) { lineartime_t lt = static_cast(aFuncContextP->getLocalVar(0))->getTimestampAs(TCTX_UNKNOWN); aTermP->setAsInteger(lineartime2weekday(lt)); }; // func_Weekday // integer SECONDS(integer timeunits) // returns number of seconds from a time unit spec static void func_Seconds(TItemField *&aTermP, TScriptContext *aFuncContextP) { fieldinteger_t v=aFuncContextP->getLocalVar(0)->getAsInteger(); aTermP->setAsInteger(v/secondToLinearTimeFactor); }; // func_Seconds // integer MILLISECONDS(integer timeunits) // returns number of milliseconds from a time unit spec static void func_Milliseconds(TItemField *&aTermP, TScriptContext *aFuncContextP) { fieldinteger_t v=aFuncContextP->getLocalVar(0)->getAsInteger(); if (secondToLinearTimeFactor==1) { v=v*1000; // internal unit is seconds } else if (secondToLinearTimeFactor!=1000) { v=v/secondToLinearTimeFactor; // seconds v=v*1000; // artifical milliseconds } aTermP->setAsInteger(v); }; // func_Milliseconds // void SLEEPMS(integer milliseconds) // sleeps process (or thread) for specified time static void func_SleepMS(TItemField *&aTermP, TScriptContext *aFuncContextP) { fieldinteger_t sl=aFuncContextP->getLocalVar(0)->getAsInteger(); // make nanoseconds, then timeunits sl *= 1000000LL; sl /= nanosecondsPerLinearTime; sleepLineartime(sl); }; // func_SleepMS // integer TIMEUNITS(integer seconds) // returns number of time units from a seconds spec static void func_Timeunits(TItemField *&aTermP, TScriptContext *aFuncContextP) { fieldinteger_t v=aFuncContextP->getLocalVar(0)->getAsInteger(); aTermP->setAsInteger(v*secondToLinearTimeFactor); }; // func_Timeunits // integer DAYUNITS(integer days) // returns number of time units from a seconds spec static void func_Dayunits(TItemField *&aTermP, TScriptContext *aFuncContextP) { fieldinteger_t v=aFuncContextP->getLocalVar(0)->getAsInteger(); aTermP->setAsInteger(v*linearDateToTimeFactor); }; // func_Dayunits // integer MONTHDAYS(timestamp date) // returns number of days of the month date is in static void func_MonthDays(TItemField *&aTermP, TScriptContext *aFuncContextP) { lineartime_t ts = static_cast(aFuncContextP->getLocalVar(0))->getTimestampAs(TCTX_UNKNOWN); aTermP->setAsInteger(getMonthDays(lineartime2dateonly(ts))); }; // func_MonthDays // DEBUGMESSAGE(string msg) // writes debug message to debug log file if debugging is not completely disabled static void func_Debugmessage(TItemField *&aTermP, TScriptContext *aFuncContextP) { #ifdef SYDEBUG if (aFuncContextP->getDbgMask()) { // get message string s; aFuncContextP->getLocalVar(0)->getAsString(s); // write it if (aFuncContextP->getSession()) { POBJDEBUGPRINTFX(aFuncContextP->getSession(),DBG_HOT,("Script DEBUGMESSAGE() at Line %hd: %s",aFuncContextP->getScriptLine(),s.c_str())); } else { POBJDEBUGPRINTFX(aFuncContextP->getSyncAppBase(),DBG_HOT,("Script DEBUGMESSAGE() at Line %hd: %s",aFuncContextP->getScriptLine(),s.c_str())); } } #endif }; // func_Debugmessage // DEBUGSHOWVARS() // shows values of all local script variables static void func_DebugShowVars(TItemField *&aTermP, TScriptContext *aFuncContextP) { #ifdef SYDEBUG if (aFuncContextP->getDbgMask() && aFuncContextP->fParentContextP) { POBJDEBUGPRINTFX(aFuncContextP->getSession(),DBG_HOT,("Script DEBUGSHOWVARS() at Line %hd:",aFuncContextP->getScriptLine())); // show all local vars (of PARENT!) TScriptContext *showContextP = aFuncContextP->fParentContextP; string fshow; uInt16 i; for (i=0; igetNumLocals(); i++) { StringObjAppendPrintf(fshow,"- %-20s : ",showContextP->getVarDef(i)->fVarName.c_str()); showContextP->getLocalVar(i)->StringObjFieldAppend(fshow,80); fshow += '\n'; } // output preformatted POBJDEBUGPUTSXX(aFuncContextP->getSession(),DBG_HOT,fshow.c_str(),0,true); } #endif }; // func_DebugShowVars // DEBUGSHOWITEM([bool aShowRefItem]) // shows all fields and values of current item static void func_DebugShowItem(TItemField *&aTermP, TScriptContext *aFuncContextP) { #ifdef SYDEBUG if (aFuncContextP->getDbgMask() && aFuncContextP->fParentContextP) { POBJDEBUGPRINTFX(aFuncContextP->getSession(),DBG_HOT,("Script DEBUGSHOWITEM() at Line %hd:",aFuncContextP->getScriptLine())); // select item TMultiFieldItem *showItemP = aFuncContextP->getLocalVar(0)->getAsBoolean() ? // optional param to select ref item instead of target aFuncContextP->fParentContextP->fReferenceItemP : aFuncContextP->fParentContextP->fTargetItemP; if (showItemP) { showItemP->debugShowItem(DBG_HOT); } else { POBJDEBUGPRINTFX(aFuncContextP->getSession(),DBG_HOT,("- no item to show")); } } #endif }; // func_DebugShowItem // SETXMLTRANSLATE(bool yesorno) // enables or disables XML translated SyncML message dumping on a per session basis static void func_SetXMLTranslate(TItemField *&aTermP, TScriptContext *aFuncContextP) { #ifdef SYDEBUG if (aFuncContextP->getSession()) aFuncContextP->getSession()->fXMLtranslate=aFuncContextP->getLocalVar(0)->getAsBoolean(); #endif }; // func_SetXMLTranslate // SETMSGDUMP(bool yesorno) // enables or disables raw SyncML message dumping on a per session basis static void func_SetMsgDump(TItemField *&aTermP, TScriptContext *aFuncContextP) { #ifdef SYDEBUG if (aFuncContextP->getSession()) aFuncContextP->getSession()->fMsgDump=aFuncContextP->getLocalVar(0)->getAsBoolean(); #endif }; // func_SetMsgDump // SETDEBUGOPTIONS(string optionname, boolean set) // sets or clears debug option flags (for the currently running session) static void func_SetDebugOptions(TItemField *&aTermP, TScriptContext *aFuncContextP) { #ifdef SYDEBUG TDebugLogger *loggerP=aFuncContextP->getDbgLogger(); if (loggerP) { // get option string string s; aFuncContextP->getLocalVar(0)->getAsString(s); // convert to bitmask sInt16 k; if (StrToEnum(debugOptionNames,numDebugOptions,k,s.c_str())) { // found mask, modify uInt32 currentmask=loggerP->getRealMask(); if (aFuncContextP->getLocalVar(1)->getAsBoolean()) currentmask |= debugOptionMasks[k]; else currentmask &= ~debugOptionMasks[k]; // .. and apply loggerP->setMask(currentmask); } } #endif }; // func_SetDebugOptions // SETDEBUGMASK(integer mask) // sets the debug mask static void func_SetDebugMask(TItemField *&aTermP, TScriptContext *aFuncContextP) { #ifdef SYDEBUG TDebugLogger *loggerP=aFuncContextP->getDbgLogger(); if (loggerP) { // get mask value loggerP->setMask(aFuncContextP->getLocalVar(0)->getAsInteger()); } #endif }; // func_SetDebugMask // integer GETDEBUGMASK() // gets the current debug mask static void func_GetDebugMask(TItemField *&aTermP, TScriptContext *aFuncContextP) { uInt32 m=0; // without debug, mask is always 0 #ifdef SYDEBUG TDebugLogger *loggerP=aFuncContextP->getDbgLogger(); if (loggerP) { // get mask value loggerP->getRealMask(); } #endif aTermP->setAsInteger(m); }; // func_GetDebugMask // void REQUESTMAXTIME(integer maxtime_seconds) static void func_RequestMaxTime(TItemField *&aTermP, TScriptContext *aFuncContextP) { TSyncSession *sessionP = aFuncContextP->getSession(); if (sessionP) { sessionP->fRequestMaxTime=aFuncContextP->getLocalVar(0)->getAsInteger(); } } // func_RequestMaxTime // void REQUESTMINTIME(integer maxtime_seconds) // artificial delay for testing static void func_RequestMinTime(TItemField *&aTermP, TScriptContext *aFuncContextP) { TSyncSession *sessionP = aFuncContextP->getSession(); if (sessionP) { sessionP->fRequestMinTime=aFuncContextP->getLocalVar(0)->getAsInteger(); } } // func_RequestMinTime // string SYNCMLVERS() // gets the SyncML version of the current session as string like "1.2" or "1.0" etc. static void func_SyncMLVers(TItemField *&aTermP, TScriptContext *aFuncContextP) { aTermP->setAsString(SyncMLVersionNames[aFuncContextP->getSession()->getSyncMLVersion()]); }; // func_SyncMLVers // integer SHELLEXECUTE(string command, string arguments [,boolean inbackground]) // executes the command line in a shell, returns the exit code of the command static void func_Shellexecute(TItemField *&aTermP, TScriptContext *aFuncContextP) { // get params string cmd,params; bool inbackground; sInt32 exitcode; aFuncContextP->getLocalVar(0)->getAsString(cmd); aFuncContextP->getLocalVar(1)->getAsString(params); // optional param inbackground=aFuncContextP->getLocalVar(2)->getAsBoolean(); // returns false if not assigned -> not in background // execute now exitcode=shellExecCommand(cmd.c_str(),params.c_str(),inbackground); // return result code aTermP->setAsInteger(exitcode); }; // func_Shellexecute // string READ(string file) // reads the file and returns its content or UNASSIGNED in case of failure; // errors are logged static void func_Read(TItemField *&aTermP, TScriptContext *aFuncContextP) { // get params string file; aFuncContextP->getLocalVar(0)->getAsString(file); // execute now string content; FILE *in; in = fopen(file.c_str(), "rb"); if (in) { long size = fseek(in, 0, SEEK_END); if (size >= 0) { // managed to obtain size, use it to pre-allocate result content.reserve(size); fseek(in, 0, SEEK_SET); } else { // ignore seek error, might not be a plain file clearerr(in); } if (!ferror(in)) { char buf[8192]; size_t read; while ((read = fread(buf, 1, sizeof(buf), in)) > 0) { content.append(buf, read); } } } if (in && !ferror(in)) { // return content as string aTermP->setAsString(content); } else { PLOGDEBUGPRINTFX(aFuncContextP->getDbgLogger(),DBG_ERROR,( "IO error in READ(\"%s\"): %s ", file.c_str(), strerror(errno) )); } if (in) { fclose(in); } } // func_Read // string URIToPath(string uri) // extracts the file path in a file:// uri; handles uri decoding // Returns UNASSIGNED if not a file:// uri static void func_URIToPath(TItemField *&aTermP, TScriptContext *aFuncContextP) { // get params string uri; aFuncContextP->getLocalVar(0)->getAsString(uri); string protocol, doc; splitURL(uri.c_str(), &protocol, NULL, &doc, NULL, NULL, NULL, NULL); if (protocol == "file") { string path; path.reserve(doc.size() + 1); path += "/"; // leading slash is never included by splitURL() path += doc; urlDecode(&path); aTermP->setAsString(path); } } // func_URIToPath // string REMOTERULENAME() // returns name of the LAST matched remote rule (or subrule), empty if none // Note: this is legacy from 3.4.0.4 onwards, as we now have a list of multiple active rules static void func_Remoterulename(TItemField *&aTermP, TScriptContext *aFuncContextP) { #ifndef NO_REMOTE_RULES if (aFuncContextP->getSession()) { // there is a session if (!aFuncContextP->getSession()->fActiveRemoteRules.empty()) { // there is at least one rule applied, get the last one in the list aTermP->setAsString(aFuncContextP->getSession()->fActiveRemoteRules.back()->getName()); return; } } #endif // no remote rule applied aTermP->assignEmpty(); }; // func_Remoterulename // boolean ISACTIVERULE(string rulename) // checks if given rule is currently activated static void func_isActiveRule(TItemField *&aTermP, TScriptContext *aFuncContextP) { #ifndef NO_REMOTE_RULES string r; aFuncContextP->getLocalVar(0)->getAsString(r); if (aFuncContextP->getSession()) { // there is a session, return status aTermP->setAsBoolean(aFuncContextP->getSession()->isActiveRule(r.c_str())); return; } #endif // remote rules not supported or no session active aTermP->assignEmpty(); }; // func_Remoterulename // TREATASLOCALTIME(integer flag) static void func_SetTreatAsLocaltime(TItemField *&aTermP, TScriptContext *aFuncContextP) { TSyncSession *sessionP = aFuncContextP->getSession(); if (sessionP) sessionP->fTreatRemoteTimeAsLocal = aFuncContextP->getLocalVar(0)->getAsBoolean(); }; // func_SetTreatAsLocaltime // TREATASUTC(integer flag) static void func_SetTreatAsUTC(TItemField *&aTermP, TScriptContext *aFuncContextP) { TSyncSession *sessionP = aFuncContextP->getSession(); if (sessionP) sessionP->fTreatRemoteTimeAsUTC = aFuncContextP->getLocalVar(0)->getAsBoolean(); }; // func_SetTreatAsUTC // UPDATECLIENTINSLOWSYNC(integer flag) static void func_SetUpdateClientInSlowSync(TItemField *&aTermP, TScriptContext *aFuncContextP) { TSyncSession *sessionP = aFuncContextP->getSession(); if (sessionP) sessionP->fUpdateClientDuringSlowsync = aFuncContextP->getLocalVar(0)->getAsBoolean(); }; // func_SetUpdateClientInSlowSync // UPDATESERVERINSLOWSYNC(integer flag) static void func_SetUpdateServerInSlowSync(TItemField *&aTermP, TScriptContext *aFuncContextP) { TSyncSession *sessionP = aFuncContextP->getSession(); if (sessionP) sessionP->fUpdateServerDuringSlowsync = aFuncContextP->getLocalVar(0)->getAsBoolean(); }; // func_SetUpdateServerInSlowSync // SHOWCTCAPPROPERTIES(bool yesorno) static void func_ShowCTCapProps(TItemField *&aTermP, TScriptContext *aFuncContextP) { TSyncSession *sessionP = aFuncContextP->getSession(); if (sessionP) sessionP->fShowCTCapProps = aFuncContextP->getLocalVar(0)->getAsBoolean(); } // func_ShowCTCapProps // SHOWTYPESIZEINCTCAP10(bool yesorno) static void func_ShowTypeSizeInCTCap10(TItemField *&aTermP, TScriptContext *aFuncContextP) { TSyncSession *sessionP = aFuncContextP->getSession(); if (sessionP) sessionP->fShowTypeSzInCTCap10 = aFuncContextP->getLocalVar(0)->getAsBoolean(); } // func_ShowTypeSizeInCTCap10 // ENUMDEFAULTPROPPARAMS(bool yesorno) static void func_EnumDefaultPropParams(TItemField *&aTermP, TScriptContext *aFuncContextP) { TSyncSession *sessionP = aFuncContextP->getSession(); // Note that this is a tristate! if (sessionP) sessionP->fEnumDefaultPropParams = aFuncContextP->getLocalVar(0)->getAsBoolean() ? 1 : 0; } // func_EnumDefaultPropParams // string LOCALURI() // returns local URI as used by client for starting session static void func_LocalURI(TItemField *&aTermP, TScriptContext *aFuncContextP) { string r; if (aFuncContextP->getSession()) { // there is a session aTermP->setAsString(aFuncContextP->getSession()->getInitialLocalURI()); return; } // no session?? aTermP->assignEmpty(); }; // func_LocalURI // string SUBSTR(string, from [, count]) static void func_Substr(TItemField *&aTermP, TScriptContext *aFuncContextP) { // get params string s; aFuncContextP->getLocalVar(0)->getAsString(s); string::size_type i=aFuncContextP->getLocalVar(1)->getAsInteger(); // optional param string::size_type l=s.size(); // default to entire string if (aFuncContextP->getLocalVar(2)->isAssigned()) l=aFuncContextP->getLocalVar(2)->getAsInteger(); // use specified count string r; // adjust params if (i>=s.size()) l=0; else if (i+l>s.size()) l=s.size()-i; // evaluate if (l>0) r.assign(s,i,l); // save result aTermP->setAsString(r); }; // func_Substr // string EXPLODE(string glue, variant &parts[]) static void func_Explode(TItemField *&aTermP, TScriptContext *aFuncContextP) { // get params string glue,s; aFuncContextP->getLocalVar(0)->getAsString(glue); TItemField *fldP = aFuncContextP->getLocalVar(1); // concatenate array elements with glue aTermP->assignEmpty(); for (uInt16 i=0; iarraySize(); i++) { // get array element as string fldP->getArrayField(i)->getAsString(s); // add to output aTermP->appendString(s); if (i+1arraySize()) { // we have more elements, add glue aTermP->appendString(glue); } } }; // func_Explode #ifdef _MSC_VER static long long V_llabs( long long j ) { return (j < 0 ? -j : j); } #endif // integer ABS(integer val) static void func_Abs(TItemField *&aTermP, TScriptContext *aFuncContextP) { #ifdef _MSC_VER aTermP->setAsInteger(V_llabs(aFuncContextP->getLocalVar(0)->getAsInteger())); #else aTermP->setAsInteger(::llabs(aFuncContextP->getLocalVar(0)->getAsInteger())); #endif }; // func_Abs // integer SIGN(integer val) // i == 0 : 0 // i > 0 : 1 // i < 0 : -1 static void func_Sign(TItemField *&aTermP, TScriptContext *aFuncContextP) { fieldinteger_t i = aFuncContextP->getLocalVar(0)->getAsInteger(); aTermP->setAsInteger(i==0 ? 0 : (i>0 ? 1 : -1)); }; // func_Sign // integer RANDOM(integer range [, integer seed]) // generates random number between 0 and range-1. Seed is optional to init random generator static void func_Random(TItemField *&aTermP, TScriptContext *aFuncContextP) { // seed if second param there if (aFuncContextP->getLocalVar(1)->isAssigned()) { // seed random gen first srand((unsigned int)aFuncContextP->getLocalVar(1)->getAsInteger()); } // now get random value fieldinteger_t r = rand(); fieldinteger_t max = RAND_MAX; // scale to specified range aTermP->setAsInteger(r * aFuncContextP->getLocalVar(0)->getAsInteger() / (max+1)); }; // func_Random // string NUMFORMAT(integer num, integer digits [,string filler=" " [,boolean opts=""]]) static void func_NumFormat(TItemField *&aTermP, TScriptContext *aFuncContextP) { // mandatory params fieldinteger_t i = aFuncContextP->getLocalVar(0)->getAsInteger(); sInt16 numdigits = aFuncContextP->getLocalVar(1)->getAsInteger(); // negative = left justified // optional params string filler = " "; // default to filling with spaces if (aFuncContextP->getLocalVar(2)->isAssigned()) aFuncContextP->getLocalVar(2)->getAsString(filler); // empty: no filling, only truncation string opts; aFuncContextP->getLocalVar(3)->getAsString(opts); // +: show plus sign. space: show space as plus sign // generate raw string string s; // - determine hex mode bool hex = opts.find("x")!=string::npos; // - create sign char sign = 0; if (!hex) { if (i<0) sign = '-'; else { if (opts.find("+")!=string::npos) sign='+'; else if (opts.find(" ")!=string::npos) sign=' '; } } // create raw numeric string if (hex) { StringObjPrintf(s,"%llX",(long long)i); } else { #ifdef _MSC_VER StringObjPrintf(s,"%lld",V_llabs(i)); #else StringObjPrintf(s,"%lld",::llabs(i)); #endif } // adjust char c = *(filler.c_str()); // NUL or filler char if (c!='0' && sign) { s.insert((size_t)0,(size_t)1,sign); // no zero-padding: insert sign before padding sign=0; // done now } sInt32 n,sz = s.size() + (sign ? 1 : 0); // leave room for sign after zero padding if (numdigits>0) { // right aligned field n = numdigits-sz; // empty space in field if (n<0) s.erase(0,-n); // delete at beginning else if (n>0 && c) s.insert((size_t)0,(size_t)n,c); // insert at beginning } else { // left aligned field n = -numdigits-sz; // empty space in field if (n<0) s.erase(sz-n,-n); // delete at end else if (n>0 && c) s.insert((size_t)sz,(size_t)n,c); // insert at end } // insert plus now if filled with zeroes if (sign) s.insert((size_t)0,(size_t)1,sign); // insert sign after zero padding // return string aTermP->setAsString(s); } // func_NumFormat // integer LENGTH(string) static void func_Length(TItemField *&aTermP, TScriptContext *aFuncContextP) { TItemField *fldP = aFuncContextP->getLocalVar(0); fieldinteger_t siz; if (fldP->isBasedOn(fty_string)) { // don't get value to avoid pulling large strings just for size siz=static_cast(fldP)->getStringSize(); } else { // brute force string s; fldP->getAsString(s); siz=s.size(); } // save result aTermP->setAsInteger(siz); }; // func_Length // integer SIZE(&var) static void func_Size(TItemField *&aTermP, TScriptContext *aFuncContextP) { TItemField *fldP = aFuncContextP->getLocalVar(0); fieldinteger_t siz; if (fldP->isArray()) { siz=fldP->arraySize(); } else if (fldP->isBasedOn(fty_string)) { // don't get value to avoid pulling large strings just for size siz=static_cast(fldP)->getStringSize(); } else { // brute force string s; fldP->getAsString(s); siz=s.size(); } // save result aTermP->setAsInteger(siz); }; // func_Size // integer FIND(string, pattern [, startat]) static void func_Find(TItemField *&aTermP, TScriptContext *aFuncContextP) { // get params string s,pat; string::size_type p; aFuncContextP->getLocalVar(0)->getAsString(s); aFuncContextP->getLocalVar(1)->getAsString(pat); // optional param uInt32 i=aFuncContextP->getLocalVar(2)->getAsInteger(); // returns 0 if unassigned // find in string if (iunAssign(); else aTermP->setAsInteger(p); }; // func_Find // integer RFIND(string, pattern [, startat]) static void func_RFind(TItemField *&aTermP, TScriptContext *aFuncContextP) { // get params string s,pat; string::size_type p; aFuncContextP->getLocalVar(0)->getAsString(s); aFuncContextP->getLocalVar(1)->getAsString(pat); // optional param uInt32 i=aFuncContextP->getLocalVar(2)->getAsInteger(); // returns 0 if unassigned if (i>s.size()) i=s.size(); // find in string p=s.rfind(pat,i); // return UNASSIGNED for "not found" and position otherwise if (p==string::npos) aTermP->unAssign(); else aTermP->setAsInteger(p); }; // func_RFind #ifdef REGEX_SUPPORT // run PCRE regexp // Returns: > 0 => success; value is the number of elements filled in // = 0 => success, but offsets is not big enough // -1 => failed to match // -2 => PCRE_ERROR_NULL => did not compile, error reported to aDbgLogger // < -2 => some kind of unexpected problem static int run_pcre(cAppCharP aRegEx, cAppCharP aSubject, stringSize aSubjLen, stringSize aSubjStart, int *aOutVec, int aOVSize, TDebugLogger *aDbgLogger) { string regexpat; // set default options int options=0; // scan input pattern. If it starts with /, we assume /xxx/opt form cAppCharP p = aRegEx; char c=*p; if (c=='/') { // delimiter found p++; // - now search end while (*p) { if (*p=='\\') { // escaped char p++; if (*p) p++; } else { if (*p==c) { // found end of regex size_t n=p-aRegEx-1; // size of plain regExp // - scan options cAppCharP o = p++; while (*o) { switch (*o) { case 'i' : options |= PCRE_CASELESS; break; case 'm' : options |= PCRE_MULTILINE; break; case 's' : options |= PCRE_DOTALL; break; case 'x' : options |= PCRE_EXTENDED; break; case 'U' : options |= PCRE_UNGREEDY; break; } o++; } // - extract regex itself regexpat.assign(aRegEx+1,n); aRegEx = regexpat.c_str(); break; // done } p++; } } // while chars in regex } // if regex with delimiter // - compile regex pcre *regex; cAppCharP errMsg=NULL; int errOffs=0; regex = pcre_compile(aRegEx, options | PCRE_UTF8, &errMsg, &errOffs, NULL); if (regex==NULL) { // error, display it in log if script logging is on PLOGDEBUGPRINTFX(aDbgLogger,DBG_SCRIPTS+DBG_ERROR,( "RegEx error at pattern pos %d: %s ", errOffs, errMsg ? errMsg : "" )); return PCRE_ERROR_NULL; // -2, regexp did not compile } else { // regExp is ok and can be executed against subject int r = pcre_exec(regex, NULL, aSubject, aSubjLen, aSubjStart, 0, aOutVec, aOVSize); pcre_free(regex); return r; } } // run_pcre // integer REGEX_FIND(string subject, string pattern [, integer startat]) static void func_Regex_Find(TItemField *&aTermP, TScriptContext *aFuncContextP) { // get params string s,pat; aFuncContextP->getLocalVar(0)->getAsString(s); aFuncContextP->getLocalVar(1)->getAsString(pat); // optional param sInt16 i=aFuncContextP->getLocalVar(2)->getAsInteger(); // returns 0 if unassigned // use PCRE to find const int ovsize=3; // we need no matches int ov[ovsize]; int rc = run_pcre(pat.c_str(),s.c_str(),s.size(),i,ov,ovsize,aFuncContextP->getDbgLogger()); if (rc>=0) { // return start position aTermP->setAsInteger(ov[0]); } else { // return UNASSIGNED for "not found" and error aTermP->unAssign(); } }; // func_Regex_Find // integer REGEX_MATCH(string subject, string regexp, integer startat, array &matches) static void func_Regex_Match(TItemField *&aTermP, TScriptContext *aFuncContextP) { // get params string s,pat; aFuncContextP->getLocalVar(0)->getAsString(s); aFuncContextP->getLocalVar(1)->getAsString(pat); sInt32 i=aFuncContextP->getLocalVar(2)->getAsInteger(); TItemField *matchesP = aFuncContextP->getLocalVar(3); string m; // use PCRE to find const int ovsize=54; // max matches (they say this must be a multiple of 3, no idea why; I'd say 2...) int ov[ovsize]; int rc = run_pcre(pat.c_str(),s.c_str(),s.size(),i,ov,ovsize,aFuncContextP->getDbgLogger()); if (rc>0) { // return start position aTermP->setAsInteger(ov[0]); // return matches int mIdx; TItemField *fldP; for (mIdx=0; mIdxisArray()) fldP = matchesP->getArrayField(mIdx); else { // non-array specified fldP = matchesP; // - if there are no subpatterns, assign the first match (entire pattern) // - if there are subpatterns, assign the first subpattern match if (rc>1) { // there is at least one subpattern mIdx++; // skip the entire pattern match such that 1st subpattern gets assigned } } // assign match (first is entire pattern) fldP->setAsString(s.c_str()+ov[mIdx*2],ov[mIdx*2+1]-ov[mIdx*2]); // assign substring // end if matches is not an array if (!matchesP->isArray()) break; } } else { // return UNASSIGNED for "not found" and all errors aTermP->unAssign(); } }; // func_Regex_Match // integer REGEX_SPLIT(string subject, string separatorregexp, array elements [, boolean emptyElements]) // returns number of elements created in elements array static void func_Regex_Split(TItemField *&aTermP, TScriptContext *aFuncContextP) { // get params string s,pat; aFuncContextP->getLocalVar(0)->getAsString(s); aFuncContextP->getLocalVar(1)->getAsString(pat); TItemField *elementsP = aFuncContextP->getLocalVar(2); // optional params bool emptyElements = aFuncContextP->getLocalVar(3)->getAsBoolean(); // skip empty elements by default // find all recurrences of separator uInt32 i = 0; // start at beginning sInt32 rIdx = 0; // no results so far while (igetDbgLogger()); if (rc<=0) { // no further match found // - simulate match at end of string ov[0]=s.size(); ov[1]=ov[0]; } // copy element if (uInt32(ov[0])>i || emptyElements) { TItemField *fldP = elementsP->getArrayField(rIdx); if (ov[0]-i>0) fldP->setAsString(s.c_str()+i,ov[0]-i); else fldP->assignEmpty(); // empty element // next element rIdx++; } // skip separator i = ov[1]; } // while not at end of string // return number of elements found aTermP->setAsInteger(rIdx); }; // func_Regex_Split // string REGEX_REPLACE(string,regexp,replacement [,startat [,repeat]]) static void func_Regex_Replace(TItemField *&aTermP, TScriptContext *aFuncContextP) { // get params string s,pat,reppat,res; aFuncContextP->getLocalVar(0)->getAsString(s); aFuncContextP->getLocalVar(1)->getAsString(pat); aFuncContextP->getLocalVar(2)->getAsString(reppat); // optional params sInt16 i=aFuncContextP->getLocalVar(3)->getAsInteger(); // returns 0 if unassigned -> start at beginning sInt32 c=aFuncContextP->getLocalVar(4)->getAsInteger(); // returns 0 if unassigned -> replace all // use PCRE to find const int ovsize=54; // max matches (they say this must be a multiple of 3, no idea why; I'd say 2...) int ov[ovsize]; res.assign(s.c_str(),i); // part of string not searched at all do { int rc = run_pcre(pat.c_str(),s.c_str(),s.size(),i,ov,ovsize,aFuncContextP->getDbgLogger()); if (rc<0) break; // error or no more matches found // found an occurrence // - subsititute matches in replacement string cAppCharP p=reppat.c_str(); cAppCharP q=p; string rep; rep.erase(); while (*p) { if (*p=='\\') { p++; if (*p==0) break; // check for escaped backslash if (*p=='\\') { p++; continue; } // get replacement number if (isdigit(*p)) { // is replacement escape sequence, get index uInt16 mIdx = *(p++)-'0'; // append chars before \x rep.append(q,p-q-2); // append match (if there is one) if (mIdx0); // if c==0, replace all, otherwise as many times as c says res.append(s.c_str()+i); // rest // return result aTermP->setAsString(res); }; // func_Regex_Replace #endif // REGEX_SUPPORT // integer COMPARE(value, value) // - returns 0 if equal, 1 if first > second, -1 if first < second, // SYSYNC_NOT_COMPARABLE if not equal and no ordering known or if field // types do not match. static void func_Compare(TItemField *&aTermP, TScriptContext *aFuncContextP) { // compare first field with second one aTermP->setAsInteger( aFuncContextP->getLocalVar(0)->compareWith(*(aFuncContextP->getLocalVar(1))) ); }; // func_Compare // integer CONTAINS(&ref, value [,bool caseinsensitive]) // - returns 1 if value contained in ref, 0 if not static void func_Contains(TItemField *&aTermP, TScriptContext *aFuncContextP) { // check if second is contained in first bool caseinsensitive = aFuncContextP->getLocalVar(2)->getAsBoolean(); // returns false if not specified aTermP->setAsBoolean( aFuncContextP->getLocalVar(0)->contains(*(aFuncContextP->getLocalVar(1)),caseinsensitive) ); }; // func_Contains // APPEND(&ref, value) // - appends value to ref (ref can be array) static void func_Append(TItemField *&aTermP, TScriptContext *aFuncContextP) { // append second to first aFuncContextP->getLocalVar(0)->append(*(aFuncContextP->getLocalVar(1))); }; // func_Append // string UPPERCASE(string) static void func_UpperCase(TItemField *&aTermP, TScriptContext *aFuncContextP) { string s; TItemField *fldP = aFuncContextP->getLocalVar(0); if (fldP->isAssigned()) { fldP->getAsString(s); StringUpper(s); // save result aTermP->setAsString(s); } else { aTermP->unAssign(); } }; // func_UpperCase // string LOWERCASE(string) static void func_LowerCase(TItemField *&aTermP, TScriptContext *aFuncContextP) { string s; TItemField *fldP = aFuncContextP->getLocalVar(0); if (fldP->isAssigned()) { fldP->getAsString(s); StringLower(s); // save result aTermP->setAsString(s); } else { aTermP->unAssign(); } }; // func_LowerCase // string NORMALIZED(variant value) // get as normalized string (trimmed CR/LF/space at both ends, no special chars for telephone numbers, http:// added for URLs w/o protocol spec) static void func_Normalized(TItemField *&aTermP, TScriptContext *aFuncContextP) { // get field reference TItemField *fldP = aFuncContextP->getLocalVar(0); if (fldP->isAssigned()) { // get normalized version string s; fldP->getAsNormalizedString(s); // save it aTermP->setAsString(s); } else { aTermP->unAssign(); } }; // func_Normalized // bool ISAVAILABLE(variant &fieldvar) // check if field is available (supported by both ends) // - returns EMPTY if availability is not known // - fieldvar must be a field contained in the primary item of the caller, else function returns UNASSIGNED static void func_IsAvailable(TItemField *&aTermP, TScriptContext *aFuncContextP) { if (aFuncContextP->fParentContextP) { // get item to find field in TMultiFieldItem *checkItemP = aFuncContextP->fParentContextP->fTargetItemP; // check if this item's type has actually received availability info if (!checkItemP->knowsRemoteFieldOptions()) { aTermP->assignEmpty(); // nothing known about field availability return; } else { // we have availability info // - get index of field by field pointer (passed by reference) sInt16 fid = checkItemP->getIndexOfField(aFuncContextP->getLocalVar(0)); if (fid!=FID_NOT_SUPPORTED) { // field exists, return availability aTermP->setAsBoolean(checkItemP->isAvailable(fid)); return; } } } // no parent context or field not found aTermP->unAssign(); }; // func_IsAvailable // SETFIELDOPTIONS(variant &fieldvar, bool available [[[, int maxsize=0 ], int maxoccur=0 ], int notruncate=FALSE]) // set field options (override what might have been set by reading devInf) // - fieldvar must be a field contained in the primary item of the caller, else function is NOP static void func_SetFieldOptions(TItemField *&aTermP, TScriptContext *aFuncContextP) { if (aFuncContextP->fParentContextP) { // get item to find field in TMultiFieldItem *checkItemP = aFuncContextP->fParentContextP->fTargetItemP; // modify options on the "remote" type TMultiFieldItemType *mfitP = checkItemP->getRemoteItemType(); // - get index of field by field pointer (passed by reference) sInt16 fid = checkItemP->getIndexOfField(aFuncContextP->getLocalVar(0)); if (mfitP && fid!=FID_NOT_SUPPORTED) { // field exists, we can set availability // - get params bool available = aFuncContextP->getLocalVar(1)->getAsBoolean(); sInt32 maxsize = FIELD_OPT_MAXSIZE_NONE; if (aFuncContextP->getLocalVar(2)->isAssigned()) maxsize = aFuncContextP->getLocalVar(2)->getAsInteger(); sInt32 maxoccur = aFuncContextP->getLocalVar(3)->getAsInteger(); // returns 0 if not specified bool notruncate = aFuncContextP->getLocalVar(4)->getAsBoolean(); // - now set options TFieldOptions *fo = mfitP->getFieldOptions(fid); if (fo) { fo->available=available; fo->maxsize=maxsize; fo->maxoccur=maxoccur; fo->notruncate=notruncate; } } } }; // func_SetFieldOptions // string ITEMDATATYPE() // returns the type's internal name (like "vcard21") static void func_ItemDataType(TItemField *&aTermP, TScriptContext *aFuncContextP) { if (aFuncContextP->fParentContextP) { // get item of which we want to know the type TMultiFieldItem *checkItemP = aFuncContextP->fParentContextP->fTargetItemP; if (checkItemP) { TMultiFieldItemType *mfitP = static_cast(checkItemP->getItemType()); if (mfitP) { aTermP->setAsString(mfitP->getTypeConfig()->getName()); return; } } } // no type associated or no item in current context aTermP->unAssign(); }; // func_ItemDataType // string ITEMTYPENAME() // returns the type's name (like "text/x-vcard") static void func_ItemTypeName(TItemField *&aTermP, TScriptContext *aFuncContextP) { if (aFuncContextP->fParentContextP) { // get item of which we want to know the type TMultiFieldItem *checkItemP = aFuncContextP->fParentContextP->fTargetItemP; if (checkItemP) { TMultiFieldItemType *mfitP = static_cast(checkItemP->getItemType()); if (mfitP) { aTermP->setAsString(mfitP->getTypeName()); return; } } } // no type associated or no item in current context aTermP->unAssign(); }; // func_ItemTypeName // string ITEMTYPEVERS() // returns the type's version string (like "2.1") static void func_ItemTypeVers(TItemField *&aTermP, TScriptContext *aFuncContextP) { if (aFuncContextP->fParentContextP) { // get item of which we want to know the type TMultiFieldItem *checkItemP = aFuncContextP->fParentContextP->fTargetItemP; if (checkItemP) { TMultiFieldItemType *mfitP = static_cast(checkItemP->getItemType()); if (mfitP) { aTermP->setAsString(mfitP->getTypeVers()); return; } } } // no type associated or no item in current context aTermP->unAssign(); }; // func_ItemTypeVers // void SWAP(untyped1,untyped2) static void func_Swap(TItemField *&aTermP, TScriptContext *aFuncContextP) { // get params TItemField *p1 = aFuncContextP->getLocalVar(0); TItemField *p2 = aFuncContextP->getLocalVar(1); TItemField *tempP = newItemField(p1->getType(), aFuncContextP->getSessionZones()); // swap (*tempP)=(*p1); (*p1)=(*p2); (*p2)=(*tempP); }; // func_Swap // string TYPENAME(untyped1) static void func_TypeName(TItemField *&aTermP, TScriptContext *aFuncContextP) { // get params TItemFieldTypes ty = aFuncContextP->getLocalVar(0)->getType(); // return type name aTermP->setAsString(ItemFieldTypeNames[ty]); }; // func_TypeName // variant SESSIONVAR(string varname) static void func_SessionVar(TItemField *&aTermP, TScriptContext *aFuncContextP) { TItemField *sessionVarP; TScriptVarDef *sessionVarDefP; string varname; TScriptContext *sessionContextP=NULL; // get name aFuncContextP->getLocalVar(0)->getAsString(varname); // get variable from session if (aFuncContextP->getSession()) sessionContextP=aFuncContextP->getSession()->getSessionScriptContext(); if (sessionContextP) { // get definition sessionVarDefP = sessionContextP->getVarDef( varname.c_str(),varname.size() ); if (sessionVarDefP) { // get variable sessionVarP = sessionContextP->getLocalVar(sessionVarDefP->fIdx); if (sessionVarP) { // create result field of appropriate type aTermP = newItemField(sessionVarP->getType(), aFuncContextP->getSessionZones()); // copy value (*aTermP) = (*sessionVarP); } } } if (!aTermP) { // if no such variable found, return unassigned (but not no-value, which would abort script) aTermP=newItemField(fty_none, aFuncContextP->getSessionZones()); aTermP->unAssign(); // make it (already is...) unassigned } }; // func_SessionVar // SETSESSIONVAR(string varname, value) static void func_SetSessionVar(TItemField *&aTermP, TScriptContext *aFuncContextP) { TItemField *sessionVarP; TScriptVarDef *sessionVarDefP; string varname; TScriptContext *sessionContextP=NULL; // get name aFuncContextP->getLocalVar(0)->getAsString(varname); // get variable from session if (aFuncContextP->getSession()) sessionContextP=aFuncContextP->getSession()->getSessionScriptContext(); if (sessionContextP) { // get definition sessionVarDefP = sessionContextP->getVarDef( varname.c_str(),varname.size() ); if (sessionVarDefP) { // get variable sessionVarP = sessionContextP->getLocalVar(sessionVarDefP->fIdx); if (sessionVarP) { // store new value (*sessionVarP) = (*(aFuncContextP->getLocalVar(1))); } } } }; // func_SetSessionVar // void ABORTSESSION(integer statuscode) static void func_AbortSession(TItemField *&aTermP, TScriptContext *aFuncContextP) { TSyncSession *sessionP = aFuncContextP->getSession(); if (sessionP) { sessionP->AbortSession(aFuncContextP->getLocalVar(0)->getAsInteger(),true); // locally caused } }; // func_AbortSession // SETDEBUGLOG(integer enabled) // set debug log output for this sync session static void func_SetDebugLog(TItemField *&aTermP, TScriptContext *aFuncContextP) { #ifdef SYDEBUG TSyncSession *sessionP = aFuncContextP->getSession(); if (sessionP) { sessionP->getDbgLogger()->setEnabled( aFuncContextP->getLocalVar(0)->getAsBoolean() ); /// @todo: remove this // %%% for now, we also need to set this separate flag sessionP->fSessionDebugLogs= aFuncContextP->getLocalVar(0)->getAsBoolean(); } #endif }; // func_SetDebugLog // SETLOG(integer enabled) // set debug log output for this sync session static void func_SetLog(TItemField *&aTermP, TScriptContext *aFuncContextP) { #ifndef MINIMAL_CODE TSyncSession *sessionP = aFuncContextP->getSession(); if (sessionP) { sessionP->fLogEnabled= aFuncContextP->getLocalVar(0)->getAsBoolean(); } #endif }; // func_SetLog // SETREADONLY(integer readonly) // set readonly option of this sync session static void func_SetReadOnly(TItemField *&aTermP, TScriptContext *aFuncContextP) { TSyncSession *sessionP = aFuncContextP->getSession(); if (sessionP) { sessionP->setReadOnly(aFuncContextP->getLocalVar(0)->getAsBoolean()); } }; // func_SetReadOnly // string CONFIGVAR(string varname) static void func_ConfigVar(TItemField *&aTermP, TScriptContext *aFuncContextP) { string varname,value; // get name aFuncContextP->getLocalVar(0)->getAsString(varname); // get value from syncappbase if (!aFuncContextP->getSyncAppBase()->getConfigVar(varname.c_str(),value)) aTermP->setAsString(value); else aTermP->unAssign(); // not found }; // func_ConfigVar // timestamp RECURRENCE_DATE( // timestamp start, // string rr_freq, integer interval, // integer fmask, integer lmask, // boolean occurrencecount, // integer count // ) static void func_Recurrence_Date(TItemField *&aTermP, TScriptContext *aFuncContextP) { // get params string rr_freq; TTimestampField *startFldP = static_cast(aFuncContextP->getLocalVar(0)); timecontext_t tctx; // - get start timestamp as is along with current context lineartime_t start = startFldP->getTimestampAs(TCTX_UNKNOWN,&tctx); aFuncContextP->getLocalVar(1)->getAsString(rr_freq); char freq = rr_freq.size()>0 ? rr_freq[0] : ' '; char freqmod = rr_freq.size()>1 ? rr_freq[1] : ' '; sInt16 interval = aFuncContextP->getLocalVar(2)->getAsInteger(); fieldinteger_t fmask = aFuncContextP->getLocalVar(3)->getAsInteger(); fieldinteger_t lmask = aFuncContextP->getLocalVar(4)->getAsInteger(); bool occurrencecount = aFuncContextP->getLocalVar(5)->getAsBoolean(); uInt16 count = aFuncContextP->getLocalVar(6)->getAsInteger(); // now calculate lineartime_t occurrence; if(endDateFromCount( occurrence, start, freq,freqmod, interval, fmask,lmask, count, occurrencecount, aFuncContextP->getDbgLogger() )) { // successful, set timestamp in same context as start timestamp had static_cast(aTermP)->setTimestampAndContext(occurrence,tctx); } else { // unsuccessful aTermP->unAssign(); } } // func_Recurrence_Date // integer RECURRENCE_COUNT( // timestamp start, // string rr_freq, integer interval, // integer fmask, integer lmask, // boolean occurrencecount, // timestamp occurrence // ) static void func_Recurrence_Count(TItemField *&aTermP, TScriptContext *aFuncContextP) { // get params string rr_freq; timecontext_t tctx; // - start time context is used for rule evaluation lineartime_t start = static_cast(aFuncContextP->getLocalVar(0))->getTimestampAs(TCTX_UNKNOWN,&tctx); aFuncContextP->getLocalVar(1)->getAsString(rr_freq); char freq = rr_freq.size()>0 ? rr_freq[0] : ' '; char freqmod = rr_freq.size()>1 ? rr_freq[1] : ' '; sInt16 interval = aFuncContextP->getLocalVar(2)->getAsInteger(); fieldinteger_t fmask = aFuncContextP->getLocalVar(3)->getAsInteger(); fieldinteger_t lmask = aFuncContextP->getLocalVar(4)->getAsInteger(); bool occurrencecount = aFuncContextP->getLocalVar(5)->getAsBoolean(); // - get end date / recurrence to get count for // Note: this is obtained in the same context as start, even if it might be in another context lineartime_t occurrence = static_cast(aFuncContextP->getLocalVar(6))->getTimestampAs(tctx); // now calculate sInt16 count; if(countFromEndDate( count, occurrencecount, start, freq,freqmod, interval, fmask,lmask, occurrence, aFuncContextP->getDbgLogger() )) { // successful aTermP->setAsInteger(count); } else { // unsuccessful aTermP->unAssign(); } } // func_Recurrence_Count // string MAKE_RRULE( // boolean rrule2, // string rr_freq, integer interval, // integer fmask, integer lmask, // timestamp until // ) static void func_Make_RRULE(TItemField *&aTermP, TScriptContext *aFuncContextP) { // get params string rr_freq; timecontext_t untilcontext; // - start time context is used for rule evaluation bool rruleV2 = aFuncContextP->getLocalVar(0)->getAsBoolean(); aFuncContextP->getLocalVar(1)->getAsString(rr_freq); char freq = rr_freq.size()>0 ? rr_freq[0] : ' '; char freqmod = rr_freq.size()>1 ? rr_freq[1] : ' '; sInt16 interval = aFuncContextP->getLocalVar(2)->getAsInteger(); fieldinteger_t fmask = aFuncContextP->getLocalVar(3)->getAsInteger(); fieldinteger_t lmask = aFuncContextP->getLocalVar(4)->getAsInteger(); lineartime_t until = static_cast(aFuncContextP->getLocalVar(5))->getTimestampAs(TCTX_UNKNOWN,&untilcontext); // convert to RRULE string string rrule; bool ok; if (rruleV2) ok = internalToRRULE2(rrule,freq,freqmod,interval,fmask,lmask,until,untilcontext,aFuncContextP->getDbgLogger()); else ok = internalToRRULE1(rrule,freq,freqmod,interval,fmask,lmask,until,untilcontext,aFuncContextP->getDbgLogger()); if (ok) { // successful aTermP->setAsString(rrule); } else { // unsuccessful aTermP->unAssign(); } } // func_Make_RRULE // boolean PARSE_RRULE( // boolean rruleV2, // string rrule, // timestamp start, // string &rr_freq, integer &interval, // integer &fmask, integer &lmask, // timestamp &until // ) static void func_Parse_RRULE(TItemField *&aTermP, TScriptContext *aFuncContextP) { timecontext_t startcontext; char freq[3] = {' ', ' ', 0}; sInt16 interval; fieldinteger_t fmask,lmask; lineartime_t until; timecontext_t untilcontext; // get params // - start time context is used for rule evaluation bool rruleV2 = aFuncContextP->getLocalVar(0)->getAsBoolean(); string rrule; aFuncContextP->getLocalVar(1)->getAsString(rrule); lineartime_t start = static_cast(aFuncContextP->getLocalVar(2))->getTimestampAs(TCTX_UNKNOWN,&startcontext); bool ok; if (rruleV2) ok = RRULE2toInternal(rrule.c_str(),start,startcontext,freq[0],freq[1],interval,fmask,lmask,until,untilcontext,aFuncContextP->getDbgLogger()); else ok = RRULE1toInternal(rrule.c_str(),start,startcontext,freq[0],freq[1],interval,fmask,lmask,until,untilcontext,aFuncContextP->getDbgLogger()); if (ok) { // successful // - save return values aFuncContextP->getLocalVar(3)->setAsString(freq); aFuncContextP->getLocalVar(4)->setAsInteger(interval); aFuncContextP->getLocalVar(5)->setAsInteger(fmask); aFuncContextP->getLocalVar(6)->setAsInteger(lmask); static_cast(aFuncContextP->getLocalVar(7))->setTimestampAndContext(until, untilcontext); } aTermP->setAsBoolean(ok); } // func_Parse_RRULE // integer PARSEEMAILSPEC(string emailspec, string &name, string &email) static void func_ParseEmailSpec(TItemField *&aTermP, TScriptContext *aFuncContextP) { string spec,name,addr; aFuncContextP->getLocalVar(0)->getAsString(spec); cAppCharP e = parseRFC2822AddrSpec(spec.c_str(),name,addr); aTermP->setAsInteger(e-spec.c_str()); // return number of chars parsed aFuncContextP->getLocalVar(1)->setAsString(name); aFuncContextP->getLocalVar(2)->setAsString(addr); } // func_ParseEmailSpec // string MAKEEMAILSPEC(string name, string email) static void func_MakeEmailSpec(TItemField *&aTermP, TScriptContext *aFuncContextP) { string spec,name,addr; aFuncContextP->getLocalVar(0)->getAsString(name); aFuncContextP->getLocalVar(1)->getAsString(addr); makeRFC2822AddrSpec(name.c_str(),addr.c_str(),spec); aTermP->setAsString(spec); // return RFC2822 email address specification } // func_MakeEmailSpec // helper to create profile handler by name // - returns NULL if no such profile name or profile's field list does not match the item's fieldlist static TProfileHandler *newProfileHandlerByName(cAppCharP aProfileName, TMultiFieldItem *aItemP) { // get type registry to find profile config in TMultiFieldDatatypesConfig *mufcP; GET_CASTED_PTR(mufcP,TMultiFieldDatatypesConfig,aItemP->getItemType()->getTypeConfig()->getParentElement(),"PARSETEXTWITHPROFILE/MAKETEXTWITHPROFILE used with non-multifield item"); // get profile config from type registry TProfileConfig *profileConfig = mufcP->getProfile(aProfileName); if (profileConfig) { // create a profile handler for the item type return profileConfig->newProfileHandler(aItemP->getItemType()); } return NULL; // no such profile } // integer PARSETEXTWITHPROFILE(string textformat, string profileName [, int mode = 0 = default [, string remoteRuleName = "" = other]]) static void func_ParseTextWithProfile(TItemField *&aTermP, TScriptContext *aFuncContextP) { bool ok = false; if (aFuncContextP->fParentContextP) { // get the item to work with TMultiFieldItem *itemP = aFuncContextP->fParentContextP->fTargetItemP; // get a handler by name string s; aFuncContextP->getLocalVar(1)->getAsString(s); TProfileHandler *profileHandlerP = newProfileHandlerByName(s.c_str(), itemP); if (profileHandlerP) { // now we can convert // - set the mode code (none = 0 = default) profileHandlerP->setProfileMode(aFuncContextP->getLocalVar(2)->getAsInteger()); profileHandlerP->setRelatedDatastore(NULL); // no datastore in particular is related #ifndef NO_REMOTE_RULES // - try to find remote rule TItemField *field = aFuncContextP->getLocalVar(3); if (field) { field->getAsString(s); if (!s.empty()) profileHandlerP->setRemoteRule(s); } #endif // - convert aFuncContextP->getLocalVar(0)->getAsString(s); ok = profileHandlerP->parseText(s.c_str(), s.size(), *itemP); // - forget delete profileHandlerP; } } aTermP->setAsBoolean(ok); } // func_ParseTextWithProfile // string MAKETEXTWITHPROFILE(string profileName [, int mode [, string remoteRuleName = "" = other] ]) static void func_MakeTextWithProfile(TItemField *&aTermP, TScriptContext *aFuncContextP) { if (aFuncContextP->fParentContextP) { // get the item to work with TMultiFieldItem *itemP = aFuncContextP->fParentContextP->fTargetItemP; // get a handler by name string s; aFuncContextP->getLocalVar(0)->getAsString(s); TProfileHandler *profileHandlerP = newProfileHandlerByName(s.c_str(), itemP); if (profileHandlerP) { // now we can convert // - set the mode code (none = 0 = default) profileHandlerP->setProfileMode(aFuncContextP->getLocalVar(1)->getAsInteger()); profileHandlerP->setRelatedDatastore(NULL); // no datastore in particular is related #ifndef NO_REMOTE_RULES // - try to find remote rule TItemField *field = aFuncContextP->getLocalVar(2); if (field) { field->getAsString(s); if (!s.empty()) profileHandlerP->setRemoteRule(s); } #endif // - convert, after clearing the string (some generateText() implementations // append instead of overwriting) s = ""; profileHandlerP->generateText(*itemP,s); aTermP->setAsString(s); // return text generated according to profile // - forget delete profileHandlerP; } } } // func_MakeTextWithProfile }; // TBuiltinStdFuncs const uInt8 param_oneTimestamp[] = { VAL(fty_timestamp) }; const uInt8 param_oneInteger[] = { VAL(fty_integer) }; const uInt8 param_oneString[] = { VAL(fty_string) }; const uInt8 param_oneVariant[] = { VAL(fty_none) }; const uInt8 param_oneOptInteger[] = { OPTVAL(fty_integer) }; const uInt8 param_Random[] = { VAL(fty_integer), OPTVAL(fty_integer) }; const uInt8 param_SetTimezone[] = { REF(fty_timestamp), VAL(fty_none) }; const uInt8 param_SetFloating[] = { REF(fty_timestamp) }; const uInt8 param_ConvertToZone[] = { VAL(fty_timestamp), VAL(fty_none), OPTVAL(fty_integer) }; const uInt8 param_ConvertToUserZone[] = { VAL(fty_timestamp), OPTVAL(fty_integer) }; const uInt8 param_Shellexecute[] = { VAL(fty_string), VAL(fty_string), OPTVAL(fty_integer) }; const uInt8 param_substr[] = { VAL(fty_string), VAL(fty_integer), OPTVAL(fty_integer) }; const uInt8 param_size[] = { REF(fty_none) }; const uInt8 param_Normalized[] = { REF(fty_none) }; const uInt8 param_find[] = { VAL(fty_string), VAL(fty_string), OPTVAL(fty_integer) }; const uInt8 param_compare[] = { VAL(fty_none), VAL(fty_none) }; const uInt8 param_contains[] = { REF(fty_none), VAL(fty_none), OPTVAL(fty_integer) }; const uInt8 param_append[] = { REF(fty_none), VAL(fty_none) }; const uInt8 param_swap[] = { REF(fty_none), REF(fty_none) }; const uInt8 param_isAvailable[] = { REF(fty_none) }; const uInt8 param_setFieldOptions[] = { REF(fty_none), VAL(fty_integer), OPTVAL(fty_integer), OPTVAL(fty_integer), OPTVAL(fty_integer) }; const uInt8 param_typename[] = { VAL(fty_none) }; const uInt8 param_SetSessionVar[] = { VAL(fty_string), VAL(fty_none) }; const uInt8 param_SetDebugOptions[] = { VAL(fty_string), VAL(fty_integer) }; const uInt8 param_Recurrence_Date[] = { VAL(fty_timestamp), VAL(fty_string), VAL(fty_integer), VAL(fty_integer), VAL(fty_integer), VAL(fty_integer), VAL(fty_integer) }; const uInt8 param_Recurrence_Count[] = { VAL(fty_timestamp), VAL(fty_string), VAL(fty_integer), VAL(fty_integer), VAL(fty_integer), VAL(fty_integer), VAL(fty_timestamp) }; const uInt8 param_Make_RRULE[] = { VAL(fty_integer), VAL(fty_string), VAL(fty_integer), VAL(fty_integer), VAL(fty_integer), VAL(fty_timestamp) }; const uInt8 param_Parse_RRULE[] = { VAL(fty_integer), VAL(fty_string), VAL(fty_timestamp), REF(fty_string), REF(fty_integer), REF(fty_integer), REF(fty_integer), REF(fty_timestamp) }; const uInt8 param_AlldayCount[] = { VAL(fty_timestamp), VAL(fty_timestamp), OPTVAL(fty_integer), OPTVAL(fty_integer) }; const uInt8 param_MakeAllday[] = { REF(fty_timestamp), REF(fty_timestamp), OPTVAL(fty_integer) }; const uInt8 param_NumFormat[] = { VAL(fty_integer), VAL(fty_integer), OPTVAL(fty_string), OPTVAL(fty_string) }; const uInt8 param_Explode[] = { VAL(fty_string), REFARR(fty_none) }; const uInt8 param_parseEmailSpec[] = { VAL(fty_string), REF(fty_string), REF(fty_string) }; const uInt8 param_makeEmailSpec[] = { VAL(fty_string), VAL(fty_string) }; const uInt8 param_parseTextWithProfile[] = { VAL(fty_string), VAL(fty_string), OPTVAL(fty_integer), OPTVAL(fty_string) }; const uInt8 param_makeTextWithProfile[] = { VAL(fty_string), OPTVAL(fty_integer), OPTVAL(fty_string) }; #ifdef REGEX_SUPPORT const uInt8 param_regexfind[] = { VAL(fty_string), VAL(fty_string), OPTVAL(fty_integer) }; const uInt8 param_regexmatch[] = { VAL(fty_string), VAL(fty_string), VAL(fty_integer), REF(fty_none) }; const uInt8 param_regexreplace[] = { VAL(fty_string), VAL(fty_string), VAL(fty_string), OPTVAL(fty_integer), OPTVAL(fty_integer) }; const uInt8 param_regexsplit[] = { VAL(fty_string), VAL(fty_string), REFARR(fty_none), OPTVAL(fty_integer) }; #endif // builtin function table const TBuiltInFuncDef BuiltInFuncDefs[] = { { "ABS", TBuiltinStdFuncs::func_Abs, fty_integer, 1, param_oneInteger }, { "SIGN", TBuiltinStdFuncs::func_Sign, fty_integer, 1, param_oneInteger }, { "RANDOM", TBuiltinStdFuncs::func_Random, fty_integer, 2, param_Random }, { "NUMFORMAT", TBuiltinStdFuncs::func_NumFormat, fty_string, 4, param_NumFormat }, { "NORMALIZED", TBuiltinStdFuncs::func_Normalized, fty_string, 1, param_Normalized }, { "ISAVAILABLE", TBuiltinStdFuncs::func_IsAvailable, fty_integer, 1, param_isAvailable }, { "SETFIELDOPTIONS", TBuiltinStdFuncs::func_SetFieldOptions, fty_none, 5, param_setFieldOptions }, { "ITEMDATATYPE", TBuiltinStdFuncs::func_ItemDataType, fty_string, 0, NULL }, { "ITEMTYPENAME", TBuiltinStdFuncs::func_ItemTypeName, fty_string, 0, NULL }, { "ITEMTYPEVERS", TBuiltinStdFuncs::func_ItemTypeVers, fty_string, 0, NULL }, { "EXPLODE", TBuiltinStdFuncs::func_Explode, fty_string, 2, param_Explode }, { "SUBSTR", TBuiltinStdFuncs::func_Substr, fty_string, 3, param_substr }, { "LENGTH", TBuiltinStdFuncs::func_Length, fty_integer, 1, param_oneString }, { "SIZE", TBuiltinStdFuncs::func_Size, fty_integer, 1, param_size }, { "FIND", TBuiltinStdFuncs::func_Find, fty_integer, 3, param_find }, { "RFIND", TBuiltinStdFuncs::func_RFind, fty_integer, 3, param_find }, #ifdef REGEX_SUPPORT { "REGEX_FIND", TBuiltinStdFuncs::func_Regex_Find, fty_integer, 3, param_regexfind }, { "REGEX_MATCH", TBuiltinStdFuncs::func_Regex_Match, fty_integer, 4, param_regexmatch }, { "REGEX_SPLIT", TBuiltinStdFuncs::func_Regex_Split, fty_integer, 4, param_regexsplit }, { "REGEX_REPLACE", TBuiltinStdFuncs::func_Regex_Replace, fty_string, 5, param_regexreplace }, #endif { "COMPARE", TBuiltinStdFuncs::func_Compare, fty_integer, 2, param_compare }, { "CONTAINS", TBuiltinStdFuncs::func_Contains, fty_integer, 3, param_contains }, { "APPEND", TBuiltinStdFuncs::func_Append, fty_none, 2, param_append }, { "UPPERCASE", TBuiltinStdFuncs::func_UpperCase, fty_string, 1, param_oneString }, { "LOWERCASE", TBuiltinStdFuncs::func_LowerCase, fty_string, 1, param_oneString }, { "SWAP", TBuiltinStdFuncs::func_Swap, fty_none, 2, param_swap }, { "TYPENAME", TBuiltinStdFuncs::func_TypeName, fty_string, 1, param_oneVariant }, { "REMOTERULENAME", TBuiltinStdFuncs::func_Remoterulename, fty_string, 0, NULL }, { "ISACTIVERULE", TBuiltinStdFuncs::func_isActiveRule, fty_integer, 1, param_oneString }, { "LOCALURI", TBuiltinStdFuncs::func_LocalURI, fty_string, 0, NULL }, { "NOW", TBuiltinStdFuncs::func_Now, fty_timestamp, 0, NULL }, { "SYSTEMNOW", TBuiltinStdFuncs::func_SystemNow, fty_timestamp, 0, NULL }, { "DBNOW", TBuiltinStdFuncs::func_DbNow, fty_timestamp, 0, NULL }, { "ZONEOFFSET", TBuiltinStdFuncs::func_ZoneOffset, fty_integer, 1, param_oneTimestamp }, { "TIMEZONE", TBuiltinStdFuncs::func_Timezone, fty_string, 1, param_oneTimestamp }, { "VTIMEZONE", TBuiltinStdFuncs::func_VTimezone, fty_string, 1, param_oneTimestamp }, { "SETTIMEZONE", TBuiltinStdFuncs::func_SetTimezone, fty_none, 2, param_SetTimezone }, { "SETFLOATING", TBuiltinStdFuncs::func_SetFloating, fty_none, 1, param_SetFloating }, { "CONVERTTOZONE", TBuiltinStdFuncs::func_ConvertToZone, fty_timestamp, 3, param_ConvertToZone }, { "CONVERTTOUSERZONE", TBuiltinStdFuncs::func_ConvertToUserZone, fty_timestamp, 2, param_ConvertToUserZone }, { "USERTIMEZONE", TBuiltinStdFuncs::func_UserTimezone, fty_string, 0, NULL }, { "SETUSERTIMEZONE", TBuiltinStdFuncs::func_SetUserTimezone, fty_none, 1, param_oneVariant }, { "ISDATEONLY", TBuiltinStdFuncs::func_IsDateOnly, fty_integer, 1, param_oneTimestamp }, { "DATEONLY", TBuiltinStdFuncs::func_DateOnly, fty_timestamp, 1, param_oneTimestamp }, { "TIMEONLY", TBuiltinStdFuncs::func_TimeOnly, fty_timestamp, 1, param_oneTimestamp }, { "ISDURATION", TBuiltinStdFuncs::func_IsDuration, fty_integer, 1, param_oneTimestamp }, { "DURATION", TBuiltinStdFuncs::func_Duration, fty_timestamp, 1, param_oneTimestamp }, { "POINTINTIME", TBuiltinStdFuncs::func_PointInTime, fty_timestamp, 1, param_oneTimestamp }, { "ISFLOATING", TBuiltinStdFuncs::func_IsFloating, fty_integer, 1, param_oneTimestamp }, { "WEEKDAY", TBuiltinStdFuncs::func_Weekday, fty_integer, 1, param_oneTimestamp }, { "SECONDS", TBuiltinStdFuncs::func_Seconds, fty_integer, 1, param_oneInteger }, { "MILLISECONDS", TBuiltinStdFuncs::func_Milliseconds, fty_integer, 1, param_oneInteger }, { "SLEEPMS", TBuiltinStdFuncs::func_SleepMS, fty_none, 1, param_oneInteger }, { "TIMEUNITS", TBuiltinStdFuncs::func_Timeunits, fty_integer, 1, param_oneInteger }, { "DAYUNITS", TBuiltinStdFuncs::func_Dayunits, fty_integer, 1, param_oneInteger }, { "MONTHDAYS", TBuiltinStdFuncs::func_MonthDays, fty_integer, 1, param_oneTimestamp }, { "DEBUGMESSAGE", TBuiltinStdFuncs::func_Debugmessage, fty_none, 1, param_oneString }, { "DEBUGSHOWVARS", TBuiltinStdFuncs::func_DebugShowVars, fty_none, 0, NULL }, { "DEBUGSHOWITEM", TBuiltinStdFuncs::func_DebugShowItem, fty_none, 1, param_oneOptInteger }, { "SETDEBUGOPTIONS", TBuiltinStdFuncs::func_SetDebugOptions, fty_none, 2, param_SetDebugOptions }, { "SETDEBUGMASK", TBuiltinStdFuncs::func_SetDebugMask, fty_none, 1, param_oneInteger }, { "SETXMLTRANSLATE", TBuiltinStdFuncs::func_SetXMLTranslate, fty_none, 1, param_oneInteger }, { "SETMSGDUMP", TBuiltinStdFuncs::func_SetMsgDump, fty_none, 1, param_oneInteger }, { "GETDEBUGMASK", TBuiltinStdFuncs::func_GetDebugMask, fty_integer, 0, NULL }, { "REQUESTMAXTIME", TBuiltinStdFuncs::func_RequestMaxTime, fty_none, 1, param_oneInteger }, { "REQUESTMINTIME", TBuiltinStdFuncs::func_RequestMinTime, fty_none, 1, param_oneInteger }, { "SHELLEXECUTE", TBuiltinStdFuncs::func_Shellexecute, fty_integer, 3, param_Shellexecute }, { "READ", TBuiltinStdFuncs::func_Read, fty_string, 1, param_oneString }, { "URITOPATH", TBuiltinStdFuncs::func_URIToPath, fty_string, 1, param_oneString }, { "SESSIONVAR", TBuiltinStdFuncs::func_SessionVar, fty_none, 1, param_oneString }, { "SETSESSIONVAR", TBuiltinStdFuncs::func_SetSessionVar, fty_none, 2, param_SetSessionVar }, { "ABORTSESSION", TBuiltinStdFuncs::func_AbortSession, fty_none, 1, param_oneInteger }, { "SETDEBUGLOG", TBuiltinStdFuncs::func_SetDebugLog, fty_none, 1, param_oneInteger }, { "SETLOG", TBuiltinStdFuncs::func_SetLog, fty_none, 1, param_oneInteger }, { "SETREADONLY", TBuiltinStdFuncs::func_SetReadOnly, fty_none, 1, param_oneInteger }, { "CONFIGVAR", TBuiltinStdFuncs::func_ConfigVar, fty_string, 1, param_oneString }, { "TREATASLOCALTIME", TBuiltinStdFuncs::func_SetTreatAsLocaltime, fty_none, 1, param_oneInteger }, { "TREATASUTC", TBuiltinStdFuncs::func_SetTreatAsUTC, fty_none, 1, param_oneInteger }, { "UPDATECLIENTINSLOWSYNC", TBuiltinStdFuncs::func_SetUpdateClientInSlowSync, fty_none, 1, param_oneInteger }, { "UPDATESERVERINSLOWSYNC", TBuiltinStdFuncs::func_SetUpdateServerInSlowSync, fty_none, 1, param_oneInteger }, { "SHOWCTCAPPROPERTIES", TBuiltinStdFuncs::func_ShowCTCapProps, fty_none, 1, param_oneInteger }, { "SHOWTYPESIZEINCTCAP10", TBuiltinStdFuncs::func_ShowTypeSizeInCTCap10, fty_none, 1, param_oneInteger }, { "ENUMDEFAULTPROPPARAMS", TBuiltinStdFuncs::func_EnumDefaultPropParams, fty_none, 1, param_oneInteger }, { "RECURRENCE_DATE", TBuiltinStdFuncs::func_Recurrence_Date, fty_timestamp, 7, param_Recurrence_Date }, { "RECURRENCE_COUNT", TBuiltinStdFuncs::func_Recurrence_Count, fty_integer, 7, param_Recurrence_Count }, { "MAKE_RRULE", TBuiltinStdFuncs::func_Make_RRULE, fty_string, 6, param_Make_RRULE }, { "PARSE_RRULE", TBuiltinStdFuncs::func_Parse_RRULE, fty_integer, 8, param_Parse_RRULE }, { "PARSEEMAILSPEC", TBuiltinStdFuncs::func_ParseEmailSpec, fty_integer, 3, param_parseEmailSpec }, { "MAKEEMAILSPEC", TBuiltinStdFuncs::func_MakeEmailSpec, fty_string, 2, param_makeEmailSpec }, { "PARSETEXTWITHPROFILE", TBuiltinStdFuncs::func_ParseTextWithProfile, fty_integer, 4, param_parseTextWithProfile }, { "MAKETEXTWITHPROFILE", TBuiltinStdFuncs::func_MakeTextWithProfile, fty_string, 3, param_makeTextWithProfile }, { "SYNCMLVERS", TBuiltinStdFuncs::func_SyncMLVers, fty_string, 0, NULL }, { "ALLDAYCOUNT", TBuiltinStdFuncs::func_AlldayCount, fty_integer, 4, param_AlldayCount }, { "MAKEALLDAY", TBuiltinStdFuncs::func_MakeAllday, fty_integer, 3, param_MakeAllday }, }; const TFuncTable BuiltInFuncTable = { sizeof(BuiltInFuncDefs) / sizeof(TBuiltInFuncDef), // size of table BuiltInFuncDefs, // table pointer NULL // no chain func }; /* * Implementation of TScriptContext */ /* public TScriptContext members */ TScriptContext::TScriptContext(TSyncAppBase *aAppBaseP, TSyncSession *aSessionP) : fAppBaseP(aAppBaseP), // save syncappbase link, must always exist fSessionP(aSessionP), // save session, can be NULL fNumVars(0), // number of instantiated vars fNumParams(0), fFieldsP(NULL), // no field contents yet scriptname(NULL), // no script name known yet linesource(NULL), executing(false), debugon(false), fTargetItemP(NULL), fReferenceItemP(NULL), fParentContextP(NULL) { fVarDefs.clear(); } // TScriptContext::TScriptContext TScriptContext::~TScriptContext() { clear(); } // TScriptContext::~TScriptContext // Reset context (clear all variables and definitions) void TScriptContext::clear(void) { // clear actual fields clearFields(); // clear definitions TVarDefs::iterator pos; for (pos=fVarDefs.begin(); pos!=fVarDefs.end(); pos++) { if (*pos) delete (*pos); } fVarDefs.clear(); } // TScriptContext::clear GZones *TScriptContext::getSessionZones(void) { return fSessionP ? fSessionP->getSessionZones() : NULL; } // TScriptContext::getSessionZones #ifdef SYDEBUG // get debug logger TDebugLogger *TScriptContext::getDbgLogger(void) { // use session logger if linked to a session if (fSessionP) return fSessionP->getDbgLogger(); // otherwise, use global logger return fAppBaseP ? fAppBaseP->getDbgLogger() : NULL; } // TScriptContext::getDbgLogger uInt32 TScriptContext::getDbgMask(void) { // use session logger if linked to a session if (fSessionP) return fSessionP->getDbgMask(); // otherwise, use global logger return fAppBaseP ? fAppBaseP->getDbgMask() : 0; } // TScriptContext::getDbgMask #endif // Reset context (clear all variables and definitions) void TScriptContext::clearFields(void) { if (fFieldsP) { // clear local vars (fields), but not references TVarDefs::iterator pos; for (pos=fVarDefs.begin(); pos!=fVarDefs.end(); pos++) { sInt16 i=(*pos)->fIdx; if (i>=fNumVars) break; // all instantiated vars done, stop even if more might be defined if (fFieldsP[i]) { if (!(*pos)->fIsRef) delete fFieldsP[i]; // delete field object (but only if not reference) fFieldsP[i]=NULL; } } // clear array of field pointers delete [] fFieldsP; fFieldsP=NULL; fNumVars=0; } } // TScriptContext::clearFields // check for identifier static bool isidentchar(appChar c) { return isalnum(c) || c=='_'; } // isidentchar // adds source line (including source text, if selected) to token stream static void addSourceLine(uInt16 aLine, const char *aText, string &aScript, bool aIncludeSource, uInt16 &aLastIncludedLine) { aScript+=TK_SOURCELINE; // token #ifdef SYDEBUG sInt16 linelen=0; // line #0 is script/function name and must be included anyway if (aIncludeSource && (aLine>aLastIncludedLine || aLine==0)) { const char *tt=aText; while (*tt && *tt!=0x0D && *tt!=0x0A) ++tt; linelen=tt-aText+1; // room for the terminator if (linelen>250) linelen=250; // limit size (2 chars needed for number, 3 reserved) // Note: even empty line will have at least one char (the terminator) aScript+=(appChar)(2+linelen); // length of additional data } else { // Note: not-included line will have no extra data (not even the terminator), so // it can be distinguished from empty line aIncludeSource=false; aScript+=(appChar)(2); // length of additional data } #else aScript+=(appChar)(2); // length of additional data #endif // add source line number aScript+=(appChar)(aLine>>8); // source line aScript+=(appChar)(aLine & 0xFF); // add source itself #ifdef SYDEBUG if (aIncludeSource) { aScript.append(aText,linelen-1); aScript+=(appChar)(0); // add terminator aLastIncludedLine = aLine; } #endif } // addSourceLine // Tokenize input string void TScriptContext::Tokenize(TSyncAppBase *aAppBaseP, cAppCharP aScriptName, sInt32 aLine, cAppCharP aScriptText, string &aTScript, const TFuncTable *aContextFuncs, bool aFuncHeader, bool aNoDeclarations, TMacroArgsArray *aMacroArgsP) { string itm; string macro; appChar c,c2; appChar token,lasttoken=0; cAppCharP text = aScriptText; cAppCharP p; uInt16 line=aLine; // script starts here sInt16 enu; // clear output aTScript.erase(); // debug info if script debugging is enabled in configuration bool includesource = #ifdef SYDEBUG aAppBaseP->getRootConfig()->fDebugConfig.fDebug & DBG_SCRIPTS; #else false; #endif uInt16 lastincludedline = 0; if (*text) { #ifdef SYDEBUG // insert script name as line #0 in all but completely empty scripts (or functions) if (aScriptName) addSourceLine(0,aScriptName,aTScript,true,lastincludedline); #endif // insert source line identification token for start of script for all but completely empty scripts addSourceLine(line,text,aTScript,includesource,lastincludedline); } // marco argument expansion // Note: $n (with n=1,2,3...9) is expanded before any other processing. To insert e.g. $2 literally, use $$2. // $n macros that can't be expanded will be left in the text AS IS string itext; if (aMacroArgsP) { itext = text; // we need a string to substitute macro args in size_t i = 0; while (i=0 && (size_t)argidxsize()) { // found macro argument, replace in input string itext.replace(i-1, 2, (*aMacroArgsP)[argidx]); // no nested macro argument eval, just advance pointer behind replacement text i += (*aMacroArgsP)[argidx].size()-1; // check next char continue; } } } } // now use expanded version of text for tokenizing text = itext.c_str(); } // actual tokenisation cAppCharP textstart = text; SYSYNC_TRY { // process text while (*text) { // get next token token=0; // none yet // - skip spaces (but not line ends) while (*text==' ' || *text=='\t') text++; // - dispatch different types of tokens c=*text++; if (c==0) break; // done with script // - check input now if (isdigit(c)) { // numeric literal p=text-1; // beginning of literal while (isalnum(*text)) text++; // - p=start, text=past end of numeric literal itm.assign(p,text-p); // code literal into token string aTScript+=TK_NUMERIC_LITERAL; // token aTScript+=(appChar)(itm.size()); // length of additional data aTScript.append(itm); } else if (c=='"') { // string literal, parse itm.erase(); while ((c=*text)) { text++; if (c=='"') { break; } // done if (c=='\\') { // escape char c2=*text++; if (!c2) break; // escape without anything following -> done else if (c2=='n') c='\n'; // internal line end else if (c2=='t') c='\t'; // internal tab else if (c2=='x') { // hex char spec uInt16 sh; text+=HexStrToUShort(text,sh,2); c=(appChar)sh; } else c=c2; // simply use char following the escape char } // now add if (c) itm+=c; } // code literal into token string aTScript+=TK_STRING_LITERAL; // token aTScript+=(appChar)(itm.size()); // length of additional data aTScript.append(itm); } else if (isalpha(c)) { // identifier // - get identifier p=text-1; while (isidentchar(*text)) text++; // - now p=start of identified, text=end uInt16 il=text-p; // - skip whitespace following identifier while (*text==' ' || *text=='\t') text++; // - check language keywords if (strucmp(p,"IF",il)==0) token=TK_IF; else if (strucmp(p,"ELSE",il)==0) token=TK_ELSE; else if (strucmp(p,"LOOP",il)==0) token=TK_LOOP; else if (strucmp(p,"WHILE",il)==0) token=TK_WHILE; else if (strucmp(p,"BREAK",il)==0) token=TK_BREAK; else if (strucmp(p,"CONTINUE",il)==0) token=TK_CONTINUE; else if (strucmp(p,"RETURN",il)==0) token=TK_RETURN; // - check special constants else if (strucmp(p,"EMPTY",il)==0) token=TK_EMPTY; else if (strucmp(p,"UNASSIGNED",il)==0) token=TK_UNASSIGNED; else if (strucmp(p,"TRUE",il)==0) token=TK_TRUE; else if (strucmp(p,"FALSE",il)==0) token=TK_FALSE; // - check types else if (StrToEnum(ItemFieldTypeNames,numFieldTypes,enu,p,il)) { // check if declaration and if allowed if (aNoDeclarations && lasttoken!=TK_OPEN_PARANTHESIS) SYSYNC_THROW(TTokenizeException(aScriptName, "no local variable declarations allowed in this script",textstart,text-textstart,line)); // code type into token aTScript+=TK_TYPEDEF; // token aTScript+=1; // length of additional data aTScript+=enu; // type } // - check function calls if in body else if (*text=='(' && !aFuncHeader) { // identifier followed by ( must be function call (if not in header of function itself) // - check for built-in function sInt16 k=0; while (k=0) { // no built-in base function, could be context-related function k=0; // function index (may span several chain links) // - start with passed functable TFuncTable *functableP = (TFuncTable *)aContextFuncs; while(functableP) { // get the function table properties sInt16 fidx,numfuncs = functableP->numFuncs; const TBuiltInFuncDef *funcs = functableP->funcDefs; // process this func table for (fidx=0; fidxchainFunc) { // obtain next function table (caller context pointer is irrelevant here) k+=numfuncs; // index for next chained table starts at end of indexes for current table void *ctx=NULL; functableP=(TFuncTable *)functableP->chainFunc(ctx); } else { functableP=NULL; // end chaining loop } } // while if (k>=0) { // no built-in nor context-built-in found, assume user-defined aTScript+=TK_USERFUNCTION; // token aTScript+=(appChar)(il+1); // length of additional data aTScript+=VARIDX_UNDEFINED; // no function index defined yet aTScript.append(p,il); // identifier name } } } // - check object qualifiers else if (*text=='.') { // must be qualifier uInt8 objidx=OBJ_AUTO; if (strucmp(p,"LOCAL",il)==0) objidx=OBJ_LOCAL; else if (strucmp(p,"OLD",il)==0) objidx=OBJ_REFERENCE; else if (strucmp(p,"LOOSING",il)==0) objidx=OBJ_REFERENCE; else if (strucmp(p,"REFERENCE",il)==0) objidx=OBJ_REFERENCE; else if (strucmp(p,"NEW",il)==0) objidx=OBJ_TARGET; else if (strucmp(p,"WINNING",il)==0) objidx=OBJ_TARGET; else if (strucmp(p,"TARGET",il)==0) objidx=OBJ_TARGET; else SYSYNC_THROW(TTokenizeException(aScriptName,"unknown object name",textstart,text-textstart,line)); text++; // skip object qualifier aTScript+=TK_OBJECT; // token aTScript+=1; // length of additional data aTScript+=objidx; // object index } else { // generic identifier, must be some kind of variable reference aTScript+=TK_IDENTIFIER; // token aTScript+=(appChar)(il+1); // length of additional data aTScript+=VARIDX_UNDEFINED; // no variable index defined yet aTScript.append(p,il); // identifier name } } // if identifier else { // get next char for double-char tokens c2=*text; // check special single chars switch (c) { // - macro case '$': { // get macro name p=text; while (isidentchar(*text)) text++; if (text==p) SYSYNC_THROW(TTokenizeException(aScriptName,"missing macro name after $",textstart,text-textstart,line)); itm.assign(p,text-p); // see if we have such a macro TScriptConfig *cfgP = aAppBaseP->getRootConfig()->fScriptConfigP; TStringToStringMap::iterator pos = cfgP->fScriptMacros.find(itm); if (pos==cfgP->fScriptMacros.end()) SYSYNC_THROW(TTokenizeException(aScriptName,"unknown macro",textstart,p-1-textstart,line)); TMacroArgsArray macroArgs; // check for macro arguments if (*text=='(') { // Macro has Arguments text++; string arg; // Note: closing brackets and commas must be escaped when used as part of a macro argument while (*text) { c=*text++; if (c==',' || c==')') { // end of argument macroArgs.push_back(arg); // save it in array arg.erase(); if (c==')') break; // end of macro continue; // skip comma, next arg } else if (c=='\\') { if (*text==0) break; // end of string // escaped - use next char w/o testing for , or ) c=*text++; } // add to argument string arg += c; } } // continue tokenizing with macro text TScriptContext::Tokenize( aAppBaseP, itm.c_str(), // pass macro name as "script" name 1, // line number relative to beginning of macro (*pos).second.c_str(), // use macro text as script text macro, // produce tokenized macro here aContextFuncs, // same context false, // not in function header aNoDeclarations, // same condition ¯oArgs // macro arguments ); // append tokenized macro to current script aTScript+=macro; // continue with normal text break; } // - grouping case '(': token=TK_OPEN_PARANTHESIS; break; // open subexpression/argument paranthesis case ')': token=TK_CLOSE_PARANTHESIS; break; // close subexpression/argument paranthesis case ',': token=TK_LIST_SEPARATOR; break; // comma for separating arguments case '{': token=TK_BEGIN_BLOCK; aFuncHeader=false; break; // begin block (and start of function body) case '}': token=TK_END_BLOCK; break; // end block case ';': token=TK_END_STATEMENT; break; // end statement case '[': token=TK_OPEN_ARRAY; break; // open array paranthesis case ']': token=TK_CLOSE_ARRAY; break; // close array paranthesis // line ends case 0x0D: if (c2==0x0A) text++; // skip LF of CRLF sequence as well to make sure it is not counted twice // otherwise treat like LF case 0x0A: // new line begins : insert source line identification token (and source of next line, if any) line++; addSourceLine(line,text,aTScript,includesource,lastincludedline); break; // possible multi-char tokens case '/': if (c2=='/') { text++; // end-of-line comment, skip it do { c=*text; if (c==0 || c==0x0D || c==0x0A) break; text++; } while(true); } else if (c2=='*') { // C-style comment, skip until next '*/' text++; do { c=*text; if (c==0) break; text++; // next if (c=='*' && *text=='/') { // end of comment text++; // skip / break; // end of comment } else if (c==0x0D || c==0x0A) { if (*text==0x0A) text++; // skip LF of CRLF sequence as well to make sure it is not counted twice // new line begins : insert source line identification token (and source of next line, if any) line++; addSourceLine(line,text,aTScript,includesource,lastincludedline); } } while(true); } else token=TK_DIVIDE; // simple division break; case '*': token=TK_MULTIPLY; break; // multiply case '%': token=TK_MODULUS; break; // modulus case '+': token=TK_PLUS; break; // add case '-': token=TK_MINUS; break; // subtract/unary minus case '^': token=TK_BITWISEXOR; break; // bitwise XOR case '~': token=TK_BITWISENOT; break; // bitwise not (one's complement) case '!': if (c2=='=') { token=TK_NOTEQUAL; text++; } // != else token=TK_LOGICALNOT; // ! break; case '=': if (c2=='=') { token=TK_EQUAL; text++; } // == else token=TK_ASSIGN; // = break; case '>': if (c2=='=') { token=TK_GREATEREQUAL; text++; } // >= else if (c2=='>') { token=TK_SHIFTRIGHT; text++; } // >> else token=TK_GREATERTHAN; // > break; case '<': if (c2=='=') { token=TK_LESSEQUAL; text++; } // <= else if (c2=='<') { token=TK_SHIFTLEFT; text++; } // << else if (c2=='>') { token=TK_NOTEQUAL; text++; } // <> else token=TK_LESSTHAN; // < break; case '&': if (c2=='&') { token=TK_LOGICALAND; text++; } // && else token=TK_BITWISEAND; // & break; case '|': if (c2=='|') { token=TK_LOGICALOR; text++; } // || else token=TK_BITWISEOR; // | break; default: SYSYNC_THROW(TTokenizeException(aScriptName,"Syntax Error",textstart,text-textstart,line)); } } // add token if simple token found if (token) aTScript+=token; lasttoken=token; // save for differentiating casts from declarations etc. } // while more script text } SYSYNC_CATCH (...) // make sure that script with errors is not stored aTScript.erase(); SYSYNC_RETHROW; SYSYNC_ENDCATCH } // TScriptContext::Tokenize // tokenize and resolve user-defined function void TScriptContext::TokenizeAndResolveFunction(TSyncAppBase *aAppBaseP, sInt32 aLine, cAppCharP aScriptText, TUserScriptFunction &aFuncDef) { TScriptContext *resolvecontextP=NULL; Tokenize(aAppBaseP, NULL, aLine,aScriptText,aFuncDef.fFuncDef,NULL,true); // parse as function SYSYNC_TRY { // resolve identifiers resolvecontextP=new TScriptContext(aAppBaseP,NULL); resolvecontextP->ResolveIdentifiers( aFuncDef.fFuncDef, NULL, // no fields false, // not rebuild &aFuncDef.fFuncName // store name here ); delete resolvecontextP; } SYSYNC_CATCH (exception &e) delete resolvecontextP; SYSYNC_RETHROW; SYSYNC_ENDCATCH } // TScriptContext::TokenizeAndResolveFunction // resolve identifiers in a script, if there is a context passed at all void TScriptContext::resolveScript(TSyncAppBase *aAppBaseP, string &aTScript,TScriptContext *&aCtxP, TFieldListConfig *aFieldListConfigP) { if (aTScript.empty()) return; // no resolving needed if (!aCtxP) { // we need a context, create one aCtxP = new TScriptContext(aAppBaseP, NULL); } aCtxP->ResolveIdentifiers( aTScript, aFieldListConfigP, false ); } // TScriptContext::ResolveScript // link a script into a context with already instantiated variables. // This is for "late bound" scripts (such as rulescript) that cannot be bound at config // but are determined only later, when their context is already instantiated. void TScriptContext::linkIntoContext(string &aTScript,TScriptContext *aCtxP, TSyncSession *aSessionP) { if (aTScript.empty() || !aCtxP) return; // no resolving needed (no script or no context) // resolve identfiers (no new declarations possible) aCtxP->ResolveIdentifiers( aTScript, NULL, // no field list false, // do not rebuild NULL, // no function name false // no declarations allowed ); } // TScriptContext::linkIntoContext // rebuild a script context for a script, if the script is not empty // - Script must already be resolved with ResolveIdentifiers // - If context already exists, adds new locals to existing ones // - If aBuildVars is set, buildVars() will be called after rebuilding variable definitions void TScriptContext::rebuildContext(TSyncAppBase *aAppBaseP, string &aTScript,TScriptContext *&aCtxP, TSyncSession *aSessionP, bool aBuildVars) { // Optimization: Nop if script is empty and NOT build var requested for already existing context (=vars from other scripts!) if (aTScript.empty() && !(aBuildVars && aCtxP)) return; // Create context if there isn't one yet if (!aCtxP) { // we need a context, create one aCtxP = new TScriptContext(aAppBaseP,aSessionP); } SYSYNC_TRY { aCtxP->ResolveIdentifiers( aTScript, NULL, true ); if (aBuildVars) { // call this one, too buildVars(aCtxP); } } SYSYNC_CATCH (TScriptErrorException &e) // show error in log, but otherwise ignore it POBJDEBUGPRINTFX(aSessionP,DBG_ERROR,("Failed rebuilding script context: %s",e.what())); SYSYNC_ENDCATCH SYSYNC_CATCH (...) SYSYNC_ENDCATCH } // TScriptContext::rebuildContext // Builds the local variables according to definitions (clears existing vars first) void TScriptContext::buildVars(TScriptContext *&aCtxP) { if (aCtxP) { // instantiate the variables aCtxP->PrepareLocals(); } } // TScriptContext::buildVars // init parsing vars void TScriptContext::initParse(const string &aTScript, bool aExecuting) { executing=aExecuting; bp=(cUInt8P)aTScript.c_str(); // start of script ep=bp+aTScript.size(); // end of script p=bp; // cursor, start at beginning np=NULL; // no next token yet line=0; // no line yet linesource=NULL; // no source yet scriptname=NULL; // no name yet inComment=false; // not in comment yet if (p == ep) // empty script return; // try to get start line if (ep>bp && *p!=TK_SOURCELINE) SYSYNC_THROW(TScriptErrorException(DEBUGTEXT("Script does not start with TK_SOURCELINE","scri2"),line)); do { // get script name or first source code line line = (((uInt8)*(p+2))<<8) + (uInt8)(*(p+3)); nextline=line; // assume same #ifdef SYDEBUG sInt16 n=(uInt8)*(p+1)-2; if (n>0) { linesource=(const char *)(p+4); // source for this line starts here if (line==0) { // this is the script name scriptname=linesource; // remember linesource=NULL; } } p+=2+2+n; #else p+=2+2; // script starts here #endif if (line==0) { // we have the name continue; // get first line now } break; } while(true); } // TScriptContext::initParse #ifdef SYDEBUG // colorize source line (comments only so far) static void colorizeSourceLine(cAppCharP aSource, string &aColorSource, bool &aComment, bool skipping) { appChar c; bool start=true; bool incomment=aComment; bool lineendcomment=false; aColorSource.erase(); while ((c=*aSource++)) { // check for comment start if (!aComment && !skipping) { // not in comment if (c=='/') { if (*aSource=='*') { aComment=true; } else if (*aSource=='/') { aComment=true; lineendcomment=true; } } } // switch to new color if changes at this point if (start || incomment!=aComment) { aColorSource += "&html;"; if (!start) aColorSource += ""; // not start aColorSource += "&html;"; incomment = aComment; } // output current char if (c==' ') aColorSource += "&sp;"; // will convert to   in HTML else aColorSource += c; // check for end of comment after this char if (aComment && !lineendcomment && !skipping) { // in C-style comment if (c=='/' && !start && *(aSource-2)=='*') { // this was end of C-comment aComment=false; } } // not start any more start=false; } // end of color aColorSource += "&html;&html;"; // end of line terminates //-style comment if (lineendcomment) aComment=false; } // colorizeSourceLine #endif // get token at p if not end of script, updates np to point to next token uInt8 TScriptContext::gettoken(void) { uInt8 tk; DBGSTRINGDEF(s); if (np) p=np; // advance to next token line=nextline; // advance to next line if (p>=ep) return 0; // end of script do { // get token and search next tk=*p; // get token if (tk>TK_MAX_MULTIBYTE) np=p+1; // single byte token, next is next char else np=p+2+*(p+1); // use length to find next token // show current line with source if we have it #ifdef SYDEBUG // delay display of line when processing a end block statement to make sure // end-skipping decision is made BEFORE showing the line if (SCRIPTDBGTEST && linesource && executing && tk!=TK_END_STATEMENT && tk!=TK_END_BLOCK) { bool sk = skipping>0; colorizeSourceLine(linesource,s,inComment,sk); SCRIPTDBGMSG(("Line %4hd: %s",line,s.c_str())); linesource=NULL; // prevent showing same line twice } #endif // check if it is line token, which would be processed invisibly if (tk==TK_SOURCELINE) { // get source code line number line = (((uInt8)*(p+2))<<8) + (uInt8)(*(p+3)); // get source code itself, if present #ifdef SYDEBUG sInt16 n=(uInt8)*(p+1)-2; if (n>0) linesource=(const char *)(p+4); // source for this line starts here #endif // go to next token p=np; continue; // fetch next } nextline=line; // by default, assume next token is on same line do { // check if next is line token, if yes, skip it as well if (*np==TK_SOURCELINE) { // get next token's source code line #ifdef SYDEBUG uInt16 showline = nextline; // current line is next that must be shown #endif nextline = (((uInt8)*(np+2))<<8) + (uInt8)(*(np+3)); #ifdef SYDEBUG // - show last line if we'll skip another line if (linesource && executing) { colorizeSourceLine(linesource,s,inComment,skipping>0); SCRIPTDBGMSG(("Line %4hd: %s",showline,s.c_str())); linesource=NULL; // prevent showing same line twice } // - get next line's number and text sInt16 n=(uInt8)*(np+1)-2; if (n>0) linesource=(const char *)(np+4); // source for this line starts here np=np+2+2+n; #else np=np+2+2; // skip token #endif continue; // test again } break; } while(true); break; } while(true); return tk; } // TScriptContext::gettoken // re-use last token fetched with gettoken() void TScriptContext::reusetoken(void) { // set pointer such that next gettoken will fetch the same token again np=p; nextline=line; } // TScriptContext::reusetoken // Resolve local variable declarations, references and field references // Note: does not clear the context, so multiple scripts can // share the same context // Note: modifies the aTScript passed (inserts identifier IDs) void TScriptContext::ResolveIdentifiers(string &aTScript,TFieldListConfig *aFieldListConfigP, bool aRebuild, string *aFuncNameP, bool aNoNewLocals) { uInt8 tk; // current token TItemFieldTypes ty=fty_none; bool deftype=false; bool refdecl=false; bool funcparams=false; string ident; sInt16 objidx; // init parsing initParse(aTScript); objidx=OBJ_AUTO; while ((tk=gettoken())) { // check declaration syntax if (deftype && tk!=TK_IDENTIFIER) SYSYNC_THROW(TScriptErrorException("Bad declaration",line)); if (!funcparams && tk==TK_OPEN_PARANTHESIS) { // could be typecast if (*np==TK_TYPEDEF) { // is a typecase gettoken(); // swallow type identifier // next must be closing paranthesis if (gettoken()!=TK_CLOSE_PARANTHESIS) SYSYNC_THROW(TScriptErrorException("Invalid typecast",line)); } } // process token else if (tk==TK_TYPEDEF) { // type definition (for variable declaration or function definition) ty = (TItemFieldTypes)(*(p+2)); deftype=true; // we are in type definition mode now // check if we are declaring a variable reference if (*np==TK_BITWISEAND) { gettoken(); refdecl=true; // defining a reference if (!funcparams) SYSYNC_THROW(TScriptErrorException("Field reference declaration allowed for function parameters",line)); } } else if (tk==TK_OBJECT) { objidx=*(p+2); continue; // avoid resetting to OBJ_AUTO at end of loop } else if (tk==TK_CLOSE_PARANTHESIS) { if (funcparams) { // end of function parameters fNumParams=fVarDefs.size(); // locals declared up to here are parameters funcparams=false; // done with parameters } } else if (tk==TK_IDENTIFIER) { // get identifier ident.assign((cAppCharP)(p+3),(size_t)(*(p+1)-1)); // check for function definition if (!funcparams && *np==TK_OPEN_PARANTHESIS) { // this is a function declaration if (!aRebuild) { // - check if allowed if (!aFuncNameP) SYSYNC_THROW(TScriptErrorException("cannot declare function here",line)); // - save name of function aFuncNameP->assign(ident); } // - determine return type if (deftype) fFuncType=ty; // save function return type else fFuncType=fty_none; // void function // - switch to function param parsing gettoken(); // get opening paranthesis funcparams=true; deftype=false; } else if (deftype) { // defining new local variable or parameter if (objidx!=OBJ_AUTO && objidx!=OBJ_LOCAL) SYSYNC_THROW(TScriptErrorException("cannot declare non-local variable '%s'",line,ident.c_str())); bool arr=false; // define new identifier(s) cUInt8P idp=p; // remember identifier token pointer // - check if this is an array definition if (*np==TK_OPEN_ARRAY) { arr=true; gettoken(); if (*np!=TK_CLOSE_ARRAY) SYSYNC_THROW(TScriptErrorException("Invalid array declaration for '%s'",line,ident.c_str())); #ifndef ARRAYFIELD_SUPPORT SYSYNC_THROW(TScriptErrorException("Arrays not available in this version",line)); #endif gettoken(); // swallow closing bracket } // - check if variable already defined TScriptVarDef *vardefP=NULL; #if SYDEBUG>1 // always get it by name and compare index vardefP = getVarDef(ident.c_str(),ident.size()); #else if (!aRebuild || (sInt8)(*(idp+2))==VARIDX_UNDEFINED) // first time build or index not yet set for another reason: get by name vardefP = getVarDef(ident.c_str(),ident.size()); else // on rebuild, get definition by already known index vardefP = getVarDef(-((sInt8)(*(idp+2))+1)); #endif #ifndef RELEASE_VERSION DEBUGPRINTFX(DBG_SCRIPTS+DBG_EXOTIC,( "ident=%s, vardefP=0x%lX, vardefP->fIdx=%d, stored idx=%d (=vardef idx %d)", ident.c_str(), (long)vardefP, vardefP ? (int)vardefP->fIdx : VARIDX_UNDEFINED, (int)((sInt8)(*(idp+2))), (int)(-((sInt8)(*(idp+2))+1)) )); #endif // check for match if (vardefP) { // check if type matching if (ty!=vardefP->fVarType || arr!=vardefP->fIsArray || refdecl!=vardefP->fIsRef) SYSYNC_THROW(TScriptErrorException("Redefined '%s' to different type",line,ident.c_str())); } else { // not existing yet if (aNoNewLocals) { // Note: aNoNewLocals is useful when resolving a script into a context // with already existing variables (such as RuleScript). We cannot // add new variables once the VarDefs have been instantiated! SYSYNC_THROW(TScriptErrorException("Cannot declare variables in this script",line)); } else { // create new variable definition vardefP = new TScriptVarDef(ident.c_str(),fVarDefs.size(),ty,arr,refdecl,false); fVarDefs.push_back(vardefP); #ifndef RELEASE_VERSION DEBUGPRINTFX(DBG_SCRIPTS+DBG_EXOTIC,( "created new vardef, ident=%s, type=%s, vardefP=0x%lX, vardefs.size()=%ld", ident.c_str(), ItemFieldTypeNames[ty], (long)vardefP, (long)fVarDefs.size() )); #endif } } if (!aRebuild) { // creating defs for the first time, set index aTScript[idp-bp+2]= -(sInt8)(vardefP->fIdx)-1; } #if SYDEBUG>1 else { // check existing index against new one if ((sInt8)(*(idp+2))!=-(sInt8)(vardefP->fIdx)-1) SYSYNC_THROW(TScriptErrorException(DEBUGTEXT("Rebuilding defs gives different index","scri1"),line)); } #endif // - check what follows deftype=false; // default to nothing refdecl=false; if (funcparams) { if (*np==TK_LIST_SEPARATOR) gettoken(); // ok, next param } else { if (*np==TK_LIST_SEPARATOR) { deftype=true; // continue with more definitions of same type gettoken(); // consume separator } else if (*np!=TK_END_STATEMENT) SYSYNC_THROW(TScriptErrorException("Missing ';' after declaration of '%s'",line,ident.c_str())); } } else if (!aRebuild) { // refer to identifier sInt16 i=getIdentifierIndex(objidx,aFieldListConfigP,ident.c_str(),ident.size()); if (i==VARIDX_UNDEFINED) SYSYNC_THROW(TScriptErrorException("Undefined identifier '%s'",line,ident.c_str())); // save field/var index in script aTScript[p-bp+2]= (sInt8)i; } } else { // Other non-declaration tokens // - if this is function param def, no other tokens are allowed if (funcparams) { SYSYNC_THROW(TScriptErrorException("Invalid function parameter declaration",line)); } else { // non-declaration stuff if (tk==TK_USERFUNCTION && !aRebuild) { // resolve function ident.assign((cAppCharP)(p+3),(size_t)(*(p+1)-1)); sInt16 i=getSyncAppBase()->getRootConfig()->fScriptConfigP->getFunctionIndex(ident.c_str(),ident.size()); if (i==VARIDX_UNDEFINED) SYSYNC_THROW(TScriptErrorException("Undefined function '%s'",line,ident.c_str())); // save function index in script aTScript[p-bp+2]= (sInt8)i; } } } objidx=OBJ_AUTO; // default to auto-select // process next } SHOWVARDEFS(aRebuild ? "Rebuilding" : "Resolving"); } // TScriptContext::ResolveIdentifiers // create local variable definitions for calling a built-in function // This is called for built-in functions before calling PrepareLocals, and // builds up local var definitions like ResolveIdentifiers does for // script code. void TScriptContext::defineBuiltInVars(const TBuiltInFuncDef *aFuncDefP) { // get information and save it in the function's context fNumParams=aFuncDefP->fNumParams; fFuncType=aFuncDefP->fReturntype; // get params sInt16 i=0; while (ifParamTypes[i]; TItemFieldTypes ty= (TItemFieldTypes)(paramdef & PARAM_TYPEMASK); bool isref = paramdef & PARAM_REF; bool isarr = paramdef & PARAM_ARR; bool isopt = paramdef & PARAM_OPT; TScriptVarDef *vardefP = new TScriptVarDef("", fVarDefs.size(), ty, isarr, isref, isopt); fVarDefs.push_back(vardefP); i++; } } // TScriptContext::defineBuiltInVars // execute built-in function void TScriptContext::executeBuiltIn(TItemField *&aTermP, const TBuiltInFuncDef *aFuncDefP) { TItemField *resultP=NULL; // pre-create result field if type is known // Note: multi-typed functions might create result themselves depending on result type if (fFuncType!=fty_none) resultP = newItemField(fFuncType, getSessionZones()); // call actual function routine (aFuncDefP->fFuncProc)(resultP,this); // return result if (aTermP) { // copy value to exiting result field if (resultP) { (*aTermP)=(*resultP); delete resultP; } else aTermP=NULL; // no result } else { // just pass back result field (or NULL) aTermP=resultP; } } // TScriptContext::executeBuiltIn #if SYDEBUG>1 void TScriptContext::showVarDefs(cAppCharP aTxt) { if (DEBUGTEST(DBG_SCRIPTS+DBG_EXOTIC)) { // Show var defs DEBUGPRINTFX(DBG_SCRIPTS+DBG_EXOTIC+DBG_HOT,("%s - %s, ctx=0x%lX, VarDefs:",aTxt,scriptname ? scriptname : "",(long)this)); TVarDefs::iterator pos; for (pos=fVarDefs.begin(); pos!=fVarDefs.end(); pos++) { DEBUGPRINTFX(DBG_SCRIPTS+DBG_EXOTIC,( "%d: %s %s%s%s", (*pos)->fIdx, ItemFieldTypeNames[(*pos)->fVarType], (*pos)->fIsRef ? "&" : "", (*pos)->fVarName.c_str(), (*pos)->fIsArray ? "[]" : "" )); } } } // TScriptContext::showVarDefs #endif // Prepare local variables (create local fields), according to definitions (re-)built with ResolveIdentifiers() // Note: This is called after ResolveIdentifiers() for each script of that context // have been called. Normally ResolveIdentifiers() was called already at config parse // with an anonymous context that is lost when PrepareLocals needs to be called. // Therefore, ResolveIdentifiers(aRebuild=true) can be called to rebuild the definitions from // the script(s) involved. Care must be taken to call ResolveIdentifiers() for each script // in the same order as at config parse to make sure already resolved indexes will match the variables (again). // Note: Field references will have a NULL pointer (which must be filled when the function is // called. bool TScriptContext::PrepareLocals(void) { // make sure old array is cleared SHOWVARDEFS("PrepareLocals"); clearFields(); // create array of appropriate size for locals fNumVars=fVarDefs.size(); SYSYNC_TRY { if (fNumVars) { fFieldsP=new TItemFieldP[fNumVars]; if (fFieldsP==NULL) return false; // - init it with null pointers to make sure we can survive when field instantiation fails for (sInt16 i=0; ifIsRef && ((*pos)->fVarType!=fty_none)) { // this is not a reference and not an untyped parameter: // instantiate a locally owned field fFieldsP[(*pos)->fIdx]=sysync::newItemField((*pos)->fVarType,getSessionZones(),(*pos)->fIsArray); } } } } SYSYNC_CATCH (...) // failed, remove fields again clearFields(); return false; SYSYNC_ENDCATCH return true; } // TScriptContext::PrepareLocals // execute a script returning a boolean bool TScriptContext::executeTest( bool aDefaultAnswer, // result if no script is there or script returns no value TScriptContext *aCtxP, const string &aTScript, const TFuncTable *aFuncTableP, // context's function table, NULL if none void *aCallerContext, // free pointer possibly having a meaning for context functions and chain function TMultiFieldItem *aTargetItemP, // target (or "loosing") item bool aTargetWritable, // if set, target item may be modified TMultiFieldItem *aReferenceItemP, // reference for source (or "old" or "winning") item bool aRefWritable // if set, reference item may also be written ) { // if no script (no context), return default answer if (!aCtxP) return aDefaultAnswer; // now call and evaluate boolean result TItemField *resP; bool res; res=aCtxP->ExecuteScript( aTScript, &resP, // we want a result false, // not a function aFuncTableP, // context function table aCallerContext, // context data aTargetItemP, // target (or "loosing") item aTargetWritable, // if set, target item may be modified aReferenceItemP, // reference for source (or "old" or "winning") item aRefWritable // if set, reference item may also be written ); if (!res) { // script execution failed, do as if there was no script res=aDefaultAnswer; } else { // evaluate result if (resP) { res=resP->getAsBoolean(); // get rid of result delete resP; } else { // no result, return default res=aDefaultAnswer; } } // return result return res; } // TScriptContext::executeTest // execute a script returning a result if there is a context for it bool TScriptContext::executeWithResult( TItemField *&aResultField, // can be default result or NULL, will contain result or NULL if no result TScriptContext *aCtxP, const string &aTScript, const TFuncTable *aFuncTableP, // context's function table, NULL if none void *aCallerContext, // free pointer possibly having a meaning for context functions TMultiFieldItem *aTargetItemP, // target (or "loosing") item bool aTargetWritable, // if set, target item may be modified TMultiFieldItem *aReferenceItemP, // reference for source (or "old" or "winning") item bool aRefWritable, // if set, reference item may also be written bool aNoDebug // if set, debug output is suppressed even if DBG_SCRIPTS is generally on ) { // if no script (no context), return default answer if (!aCtxP) return true; // ok, leave aResultFieldP unmodified // now call and evaluate result return aCtxP->ExecuteScript( aTScript, &aResultField, // we want a result, if we pass a default it will be modified if script has a result false, // not a function aFuncTableP, // context function table aCallerContext, // context data aTargetItemP, // target (or "loosing") item aTargetWritable, // if set, target item may be modified aReferenceItemP, // reference for source (or "old" or "winning") item aRefWritable, // if set, reference item may also be written aNoDebug // if set, debug output is suppressed even if DBG_SCRIPTS is generally on ); } // TScriptContext::executeTest // execute a script if there is a context for it bool TScriptContext::execute( TScriptContext *aCtxP, const string &aTScript, const TFuncTable *aFuncTableP, // context's function table, NULL if none void *aCallerContext, // free pointer possibly having a meaning for context functions TMultiFieldItem *aTargetItemP, // target (or "loosing") item bool aTargetWritable, // if set, target item may be modified TMultiFieldItem *aReferenceItemP, // reference for source (or "old" or "winning") item bool aRefWritable, // if set, reference item may also be written bool aNoDebug // if set, debug output is suppressed even if DBG_SCRIPTS is generally on ) { if (!aCtxP) return true; // no script, success // execute script in given context SYSYNC_TRY { bool r=aCtxP->ExecuteScript( aTScript, NULL, // we don't need a result false, // not a function aFuncTableP, // context specific function table aCallerContext, // caller's context private data pointer aTargetItemP, // target (or "loosing") item aTargetWritable, // if set, target item may be modified aReferenceItemP, // reference for source (or "old" or "winning") item aRefWritable, // if set, reference item may also be written aNoDebug // if set, debug output is suppressed even if DBG_SCRIPTS is generally on ); return r; } SYSYNC_CATCH (...) SYSYNC_RETHROW; SYSYNC_ENDCATCH } // TScriptContext::execute void TScriptContext::pushState(TScriptState aNewState, cUInt8P aBegin, uInt16 aLine) { if (fStackEntries>=maxstackentries) SYSYNC_THROW(TScriptErrorException("too many IF/ELSE/WHILE/LOOP nested",line)); // use defaults if (aBegin==NULL) { aBegin = np; // next token after current token aLine = nextline; } // push current state fScriptstack[fStackEntries].state=aNewState; // new state fScriptstack[fStackEntries].begin=aBegin; // start of block fScriptstack[fStackEntries].line=aLine; // line where block starts fStackEntries++; } // TScriptContext::pushState // pop state from flow control state stack void TScriptContext::popState(TScriptState aCurrentStateExpected) { if (fScriptstack[fStackEntries-1].state!=aCurrentStateExpected) SYSYNC_THROW(TScriptErrorException("bad block/IF/ELSE/WHILE/LOOP nesting",line)); // remove entry fStackEntries--; // remove stack entry if (fStackEntries<1) SYSYNC_THROW(TScriptErrorException(DEBUGTEXT("unbalanced control flow stack pop","scri3"),line)); } // TScriptContext::popState // get variable specification, returns true if writable bool TScriptContext::getVarField(TItemField *&aItemFieldP) { sInt16 objnum, varidx, arridx; TMultiFieldItem *itemP=NULL; bool writeable=false; bool fidoffs=false; uInt8 tk; aItemFieldP=NULL; // none by default tk=gettoken(); objnum=OBJ_AUTO; // default to automatic object selection // check for object specifier if (tk==TK_OBJECT) { // object qualifier objnum=*(p+2); tk=gettoken(); // must be followed by identifier if (tk!=TK_IDENTIFIER) SYSYNC_THROW(TScriptErrorException("bad variable/field reference",line)); } // check for object itself if (tk==TK_IDENTIFIER) { #ifdef SYDEBUG cAppCharP idnam=(cAppCharP)(p+3); int idlen=*(p+1)-1; #endif // get index varidx=(sInt8)(*(p+2)); if (varidx==VARIDX_UNDEFINED) SYSYNC_THROW(TScriptErrorException("Undefined identifier",line)); // check possible array index arridx=-1; // default to non-array if (*np==TK_OPEN_ARRAY) { tk=gettoken(); // consume open bracket // check special field-offset access mode if (*np==TK_PLUS) { fidoffs=true; gettoken(); // consume the plus } TItemField *fldP = new TIntegerField; SYSYNC_TRY { evalExpression(fldP,EXPRDBGTEST,NULL); // do not show array index expression evaluation arridx=fldP->getAsInteger(); delete fldP; } SYSYNC_CATCH (...) delete fldP; SYSYNC_RETHROW; SYSYNC_ENDCATCH // check closing array bracket tk=gettoken(); if (tk!=TK_CLOSE_ARRAY) SYSYNC_THROW(TScriptErrorException("missing ']' for array reference",line)); } // now access field #ifdef SYDEBUG sInt16 oai=arridx; #endif // - determine object if not explicitly specified if (objnum==OBJ_AUTO) { if (varidx<0) objnum=OBJ_LOCAL; else objnum=OBJ_TARGET; } // - now access (arridx==-1 if we don't want to access leaf element) if (objnum==OBJ_LOCAL) { if (fidoffs) { varidx-=arridx; arridx=-1; } // use array index as offset within local fields (negative indices!) aItemFieldP=getFieldOrVar(NULL,varidx,arridx); writeable=true; // locals are always writeable } else { // prepare index/arrayindex to access if (fidoffs) { varidx+=arridx; arridx=-1; } // use array index as offset within field list // get item to access if (objnum==OBJ_TARGET) { itemP=fTargetItemP; writeable=fTargetWritable; } else if (objnum==OBJ_REFERENCE) { itemP=fReferenceItemP; writeable=fRefWritable; } if (itemP) aItemFieldP=getFieldOrVar(itemP,varidx,arridx); else SYSYNC_THROW(TScriptErrorException("field not accessible in this context",line)); } // error if no field DBGSTRINGDEF(s); DBGSTRINGDEF(sa); DBGVALUESHOW(s,aItemFieldP); if (EXPRDBGTEST) { if (oai>=0) { if (arridx!=-1) StringObjPrintf(sa,"[%hd]",oai); else StringObjPrintf(sa,"[+%hd]",oai); } else { // no array access sa.erase(); } SCRIPTDBGMSG(( "- %s: %.*s%s = %s", objnum==OBJ_LOCAL ? "Local Variable" : (objnum==OBJ_REFERENCE ? "OLD/LOOSING Field " : "Field"), idlen,idnam, sa.c_str(), s.c_str() )); } if (!aItemFieldP) SYSYNC_THROW(TScriptErrorException("undefined identifier, bad array index or offset",line)); // return field pointer we've found, if any return writeable; } else SYSYNC_THROW(TScriptErrorException("expected identifier",line)); } // TScriptContext::getVarField // evaluate function parameters void TScriptContext::evalParams(TScriptContext *aFuncContextP) { uInt8 tk; sInt16 paramidx; TScriptVarDef *vardefP; TItemField *fldP; tk=gettoken(); if (tk!=TK_OPEN_PARANTHESIS) SYSYNC_THROW(TScriptErrorException("missing '(' of function parameter list",line)); paramidx=0; // special check for function with only optional params if (aFuncContextP->getNumParams()>0 && aFuncContextP->getVarDef((short)0)->fIsOpt) { if (*np==TK_CLOSE_PARANTHESIS) goto noparams; // first is optional already -> ok to see closing paranthesis here } // at least one param while(paramidxgetNumParams()) { vardefP=aFuncContextP->getVarDef(paramidx); // check what param is expected next if (vardefP->fIsRef) { // by reference, we must have a writable lvalue here fldP=NULL; if (*np==TK_IDENTIFIER || *np==TK_OBJECT) { // get writable field/var of caller if (!getVarField(fldP)) SYSYNC_THROW(TScriptErrorException("expected writable by-reference parameter",line)); // type must match (or destination must be untyped) if (vardefP->fVarType!=fldP->getType() && vardefP->fVarType!=fty_none) SYSYNC_THROW(TScriptErrorException("expected by-reference parameter of type '%s'",line,ItemFieldTypeNames[vardefP->fVarType])); // type must match (or destination must be untyped) if (vardefP->fIsArray && !(fldP->isArray())) SYSYNC_THROW(TScriptErrorException("expected array as by-reference parameter",line)); // assign field to function context's local var list aFuncContextP->setLocalVar(paramidx,fldP); } else SYSYNC_THROW(TScriptErrorException("expected by-reference parameter",line)); } else { // by value // - get field where to assign value if (vardefP->fVarType!=fty_none) { // already prepared typed parameter fldP=aFuncContextP->getLocalVar(paramidx); // - evaluate expression into local var evalExpression(fldP,EXPRDBGTEST); // do not show expression, as we will show param } else { // untyped param, let evaluation create correct type fldP=NULL; evalExpression(fldP,EXPRDBGTEST); // do not show expression, as we will show param // untyped params are not yet instantiated, assign expression result now aFuncContextP->setLocalVar(paramidx,fldP); } } DBGSTRINGDEF(s); DBGVALUESHOW(s,fldP); SCRIPTDBGMSG(( "- Parameter #%d (by %s) = %s", paramidx+1, vardefP->fIsRef ? "reference" : "value", s.c_str() )); // got param paramidx++; // check parameter delimiters if (paramidxgetNumParams()) { // function potentially has more params tk=gettoken(); if (tk!=TK_LIST_SEPARATOR) { // - check if next is an optional parameter if (aFuncContextP->getVarDef(paramidx)->fIsOpt) goto endofparams; // yes, optional -> check for end of parameter list else SYSYNC_THROW(TScriptErrorException("expected ',' (more parameters)",line)); // non-optional parameter missing } } } // check end of parameter list noparams: tk=gettoken(); endofparams: if (tk!=TK_CLOSE_PARANTHESIS) SYSYNC_THROW(TScriptErrorException("missing ')' of function parameter list",line)); } // TScriptContext::evalParams // evaluate term, return caller-owned field containing term data TItemField *TScriptContext::evalTerm(TItemFieldTypes aResultType) { TItemFieldTypes termtype=aResultType; // default to result type TItemField *termP=NULL; uInt8 tk; TScriptContext *funccontextP; string *funcscript; const char *funcname; uInt16 funcnamelen; // Evaluate term. A term is // - a subexpression in paranthesis // - a variable reference // - a builtin function call // - a user defined function call // - a literal, including the special EMPTY and UNASSIGNED ones // A term can be preceeded by a typecast do { tk=gettoken(); if (tk==TK_OPEN_PARANTHESIS) { // typecast or subexpression if (*np==TK_TYPEDEF) { // this is a typecast gettoken(); // actually get type termtype=(TItemFieldTypes)(*(p+2)); // set new term target type if (gettoken()!=TK_CLOSE_PARANTHESIS) SYSYNC_THROW(TScriptErrorException("missing ')' after typecast",line)); if (aResultType!=fty_none && aResultType!=termtype) SYSYNC_THROW(TScriptErrorException("invalid typecast",line)); continue; // now get term } else { // process subexpression into term if (termtype!=fty_none) { // prepare distinct result type field termP=newItemField(termtype, getSessionZones()); } // puts result in a caller-owned termP (creates new one ONLY if caller passes NULL) evalExpression(termP,EXPRDBGTEST); // do not show subexpression results if (gettoken()!=TK_CLOSE_PARANTHESIS) SYSYNC_THROW(TScriptErrorException("missing ')' after expression",line)); } } else if (tk==TK_FUNCTION || tk==TK_CONTEXTFUNCTION) { // get function definition table reference const TFuncTable *functableP = (tk==TK_FUNCTION) ? &BuiltInFuncTable : // globally available functions fFuncTableP; // context specific functions // get the function index sInt16 funcid=*(p+2); // now find the function definition record in the chain of function tables void *callerContext = fCallerContext; // start with caller context of current script while(functableP && funcid>=functableP->numFuncs) { // function is in a chained table // - adjust id to get offset based on next table funcid-=functableP->numFuncs; // - get next table and next caller context if (functableP->chainFunc) functableP = (TFuncTable *)functableP->chainFunc(callerContext); else functableP = NULL; } if (!functableP) SYSYNC_THROW(TScriptErrorException("undefined context function",line)); // found function table and caller context, now get funcdef const TBuiltInFuncDef *funcdefP = &(functableP->funcDefs[funcid]); // execute built-in function call funcname=funcdefP->fFuncName; funcnamelen=100; // enough SCRIPTDBGMSG(("- %s() built-in function call:",funcname)); // - get context for built-in function funccontextP=new TScriptContext(fAppBaseP,fSessionP); SYSYNC_TRY { // define built-in parameters of function context funccontextP->defineBuiltInVars(funcdefP); // prepare local variables of function context funccontextP->PrepareLocals(); // prepare parameters evalParams(funccontextP); // copy current line for reference (as builtins have no own line number funccontextP->line=line; // copy caller's context pointer (possibly modified by function table chaining) funccontextP->fCallerContext=callerContext; funccontextP->fParentContextP=this; // link to calling script context // copy target and reference item vars funccontextP->fTargetItemP = fTargetItemP; funccontextP->fTargetWritable = fTargetWritable; funccontextP->fReferenceItemP = fReferenceItemP; funccontextP->fRefWritable = fRefWritable; // execute function funccontextP->executeBuiltIn(termP,funcdefP); // show by-ref parameters after call if (SCRIPTDBGTEST) { // show by-ref variables for (uInt16 i=0; ifNumParams; i++) { if (funcdefP->fParamTypes[i] & PARAM_REF) { // is a parameter passed by reference, possibly changed by function call DBGSTRINGDEF(s); DBGVALUESHOW(s,funccontextP->getLocalVar(i)); SCRIPTDBGMSG(( "- return value of by-ref parameter #%d = %s", i+1, s.c_str() )); } } } // done delete funccontextP; } SYSYNC_CATCH (...) if (funccontextP) delete funccontextP; SYSYNC_RETHROW; SYSYNC_ENDCATCH goto funcresult; } else if (tk==TK_USERFUNCTION) { // user defined function call funcname=(const char *)p+3; funcnamelen=*(p+1)-1; SCRIPTDBGMSGX(DBG_SCRIPTS+DBG_EXOTIC+DBG_SCRIPTEXPR,("- User-defined function %.*s call:",funcnamelen,funcname)); // - get function text funcscript=getSyncAppBase()->getRootConfig()->fScriptConfigP->getFunctionScript(*(p+2)); if (!funcscript) SYSYNC_THROW(TSyncException(DEBUGTEXT("invalid user function index","scri7"))); // %%% possibly add caching of function contexts here. // Now we rebuild a context for every function call. Not extremely efficient... funccontextP=NULL; rebuildContext(fAppBaseP,*funcscript,funccontextP,fSessionP,true); if (!funccontextP) SYSYNC_THROW(TSyncException(DEBUGTEXT("no context for user-defined function call","scri5"))); SYSYNC_TRY { // prepare parameters evalParams(funccontextP); // pass parent context funccontextP->fParentContextP=this; // link to calling script context // process sub-script into term if (termtype!=fty_none) termP=newItemField(termtype, getSessionZones()); // we want a specific type, pre-define the field // execute function if (!funccontextP->ExecuteScript( *funcscript, &termP, // receives result, if any true, // is a function NULL, NULL, // no context functions/datapointer NULL, false, // no target fields NULL, false // no reference fields )) { SCRIPTDBGMSG(("- User-defined function failed to execute")); SYSYNC_THROW(TSyncException("User-defined function failed to execute properly")); } // done if (funccontextP) delete funccontextP; } SYSYNC_CATCH (...) if (funccontextP) delete funccontextP; SYSYNC_RETHROW; SYSYNC_ENDCATCH funcresult: DBGSTRINGDEF(s); DBGVALUESHOW(s,termP); SCRIPTDBGMSG(( "- %.*s() function result = %s", funcnamelen,funcname, s.c_str() )); } else if (tk==TK_EMPTY) { termP=newItemField(fty_none, getSessionZones()); termP->assignEmpty(); // make it EMPTY (that is, assigned) //SCRIPTDBGMSGX(DBG_SCRIPTS+DBG_EXOTIC+DBG_SCRIPTEXPR,("- Literal: EMPTY")); } else if (tk==TK_UNASSIGNED) { termP=newItemField(fty_none, getSessionZones()); termP->unAssign(); // make it (already is...) unassigned //SCRIPTDBGMSGX(DBG_SCRIPTS+DBG_EXOTIC+DBG_SCRIPTEXPR,("- Literal: UNASSIGNED")); } else if (tk==TK_TRUE || tk==TK_FALSE) { termP=newItemField(fty_integer, getSessionZones()); termP->setAsInteger(tk==TK_TRUE ? 1 : 0); // set 0 or 1 //SCRIPTDBGMSGX(DBG_SCRIPTS+DBG_EXOTIC+DBG_SCRIPTEXPR,("- Literal BOOLEAN: %d",tk==TK_TRUE ? 1 : 0)); } else if (tk==TK_NUMERIC_LITERAL) { // %%% possibly add fty_float later // set type to integer if not another type requested //SCRIPTDBGMSGX(DBG_SCRIPTS+DBG_EXOTIC+DBG_SCRIPTEXPR,("- Literal number: %0.*s",*(p+1),p+2)); if (termtype==fty_none) termtype=fty_integer; goto literalterm; } else if (tk==TK_STRING_LITERAL) { if (termtype==fty_none) termtype=fty_string; //SCRIPTDBGMSGX(DBG_SCRIPTS+DBG_EXOTIC+DBG_SCRIPTEXPR,("- Literal string: \"%0.*s\"",*(p+1),p+2)); literalterm: termP = newItemField(termtype, getSessionZones()); termP->setAsString((cAppCharP)(p+2),*(p+1)); } else { // must be identifier reusetoken(); TItemField *varP=NULL; getVarField(varP); // copy and convert if (termtype==fty_none) termtype=varP->getType(); termP=newItemField(termtype, getSessionZones()); (*termP)=(*varP); // simply assign (automatically converts if needed) } break; } while(true); // repeat only for typecast return termP; // return caller-owned field } // TScriptContext::evalTerm // evaluate expression, creates new or fills passed caller-owned field with result void TScriptContext::evalExpression( TItemField *&aResultFieldP, // result (created new if passed NULL, modified and casted if passed a field) bool aShowResult, // if set, this is the main expression (and we want to see the result in DBG) TItemField *aLeftTermP, // if not NULL, chain-evaluate rest of expression according to aBinaryOp and aPreviousOp. WILL BE CONSUMED uInt8 *aBinaryOpP, // operator to be applied between term passed in aLeftTermP and next term, will receive next operator that has same or lower precedence than aPreviousOp uInt8 aPreviousOp // if an operator of same or lower precedence than this is found, expression evaluation ends ) { TItemFieldTypes termtype; // type of term TItemField *termP; // next term TItemField *resultP; // intermediate result string s; // temp string bool retainType=false; uInt8 unaryop,binaryop,nextbinaryop; fieldinteger_t a,b; // defaults binaryop=0; // none by default if (aBinaryOpP) binaryop=*aBinaryOpP; // get one if one was passed termtype=fty_none; // first term can be anything // init first term/operation if there is one if (binaryop && !aLeftTermP) binaryop=0; // security // process expression #ifdef SYDEBUG // - determine if subexpression if (!binaryop) { // starting new evaluation SCRIPTDBGMSGX(DBG_SCRIPTS+DBG_EXOTIC+DBG_SCRIPTEXPR,("- Starting expression evaluation")); } #endif SYSYNC_TRY { // Note: if binaryop!=0, we have a valid aLeftTermP do { resultP=NULL; termP=NULL; // Get next term unaryop=0; // default to none // - check for unaries if (*np==TK_BITWISENOT || *np==TK_LOGICALNOT || *np==TK_MINUS) { unaryop=gettoken(); // evaluate to integer, as unary ops all only make sense with integers termtype=fty_integer; } // - get next term termP=evalTerm(termtype); // Apply unaries now if (unaryop) { // all unaries are integer ops if (termP->getCalcType()!=fty_integer) SYSYNC_THROW(TScriptErrorException("unary operator applied to non-integer",line)); fieldinteger_t ival = termP->getAsInteger(); // apply op switch (unaryop) { case TK_MINUS: ival=-ival; break; case TK_BITWISENOT: ival= ~ival; break; case TK_LOGICALNOT: ival= !termP->getAsBoolean(); break; } // store back into term field termP->setAsInteger(ival); } // now we have a new term in termP (or NULL if term had no result) // - check for a next operator nextbinaryop=0; if (*np>=TK_BINOP_MIN && *np <=TK_BINOP_MAX) { // this is a binary operator nextbinaryop=gettoken(); } // - check for non-existing term if (!termP && (binaryop || nextbinaryop)) SYSYNC_THROW(TScriptErrorException("non-value cannot be used in expression",line)); // - check if there is a previous operation pending if (binaryop) { fieldinteger_t intres; // There is an operation to perform between aLeftTermP and current term (or expression with // higher precedence) // - get precedences (make them minus to have lowerpreccurrentprec) { // next operator has higher precedence, evaluate everything up to next operator with same or // lower precedence as current one BEFORE applying binaryop evalExpression( resultP, // we'll receive the result here EXPRDBGTEST, // do not normally show subexpression results termP, // left term of new expression, WILL BE CONSUMED &nextbinaryop, // operator, will be updated to receive next operator to apply binaryop // evaluation stops when expression reaches operator with same or lower precedence ); // nextbinaryop now has next operation to perform AFTER doing binaryop termP=resultP; // original termP has been consumed, use result as new termP resultP=NULL; } // Now we can apply binaryop between lasttermP and termP // Note: this must CONSUME termP AND aLeftTermP and CREATE resultP // - check for operators that work with multiple types if (binaryop==TK_PLUS) { if (aLeftTermP->getCalcType()!=fty_integer) { // treat plus as general append (defaults to string append for non-arrays) aLeftTermP->append(*termP); resultP=aLeftTermP; // we can simply pass the pointer aLeftTermP=NULL; // consume goto opdone; // operation done, get rid of termP } } else if (binaryop>=TK_LESSTHAN && binaryop<=TK_NOTEQUAL) { // comparison operators sInt16 cmpres=-3; // will never happen bool neg=false; switch (binaryop) { // - comparison case TK_LESSTHAN : cmpres=-1; break; case TK_GREATERTHAN : cmpres=1; break; case TK_LESSEQUAL : cmpres=1; neg=true; break; case TK_GREATEREQUAL : cmpres=-1; neg=true; break; // - equality case TK_EQUAL : cmpres=0; break; case TK_NOTEQUAL : cmpres=0; neg=true; break; } // do comparison if (termP->getType()==fty_none) { // EMPTY or UNASSIGNED comparison if (termP->isUnassigned()) { intres = aLeftTermP->isUnassigned() ? 0 : 1; // if left is assigned, it is greater } else { intres = aLeftTermP->isEmpty() ? 0 : 1; // if left is not empty, it is greater } } else { // normal comparison intres=aLeftTermP->compareWith(*termP); } if (intres==SYSYNC_NOT_COMPARABLE) intres=0; // false else { intres=cmpres==intres; if (neg) intres=!intres; } retainType= aLeftTermP->getType()==fty_integer;; // comparisons must always have plain integer result goto intresult; } // - integer operators a=aLeftTermP->getAsInteger(); b=termP->getAsInteger(); // for integer math operators, retain type of left term if it can calculate as integer // (such that expressions like: "timestamp + integer" will have a result type of timestamp) retainType = aLeftTermP->getCalcType()==fty_integer; // now perform integer operation switch (binaryop) { // - multiply, divide case TK_MULTIPLY : intres=a*b; break; case TK_DIVIDE : intres=a/b; break; case TK_MODULUS : intres=a%b; break; // - add, subtract case TK_PLUS : intres=a+b; break; case TK_MINUS : intres=a-b; break; // - shift case TK_SHIFTLEFT : intres=a<>b; break; // - bitwise AND case TK_BITWISEAND : intres=a&b; break; // - bitwise XOR case TK_BITWISEXOR : intres=a^b; break; // - bitwise OR case TK_BITWISEOR : intres=a|b; break; // - logical AND case TK_LOGICALAND : intres=a&&b; break; // - logical OR case TK_LOGICALOR : intres=a||b; break; default: SYSYNC_THROW(TScriptErrorException("operator not implemented",line)); } intresult: // save integer result (optimized, generate new field only if aLeftTermP is not already integer-calc-type) if (retainType) resultP=aLeftTermP; // retain original left-side type (including extra information like time zone context and rendering type) else { // create new integer field resultP = newItemField(fty_integer, getSessionZones()); delete aLeftTermP; } aLeftTermP=NULL; resultP->setAsInteger(intres); opdone: // check for special conditions when operating on timestamps if (resultP->isBasedOn(fty_timestamp) && termP->isBasedOn(fty_timestamp)) { // both based on timestamp. if (binaryop==TK_MINUS && !static_cast(resultP)->isDuration() && !static_cast(termP)->isDuration()) { // subtracted two points in time -> result is duration static_cast(resultP)->makeDuration(); } } // get rid of termP delete termP; termP=NULL; } // if binary op was pending else { // no binary op pending, simply pass term as result resultP=termP; termP=NULL; } // Now termP and aLeftTermP are consumed, resultP is alive // - determine next operation if (nextbinaryop) { // check precedence, if we can pass back to previous sInt8 lastprec=-(aPreviousOp & TK_OP_PRECEDENCE_MASK); sInt8 thisprec=-(nextbinaryop & TK_OP_PRECEDENCE_MASK); if (aPreviousOp && thisprec<=lastprec) break; // force exit, resultP is assigned } // result is going to be left term for next operation aLeftTermP=resultP; binaryop=nextbinaryop; } while(nextbinaryop); // as long as expression continues // show result #ifdef SYDEBUG // show final result of main expression only if (!nextbinaryop && aShowResult) { DBGVALUESHOW(s,resultP); SCRIPTDBGMSG(( "- Expression result: %s", s.c_str() )); } #endif // convert result to desired type if (!aResultFieldP) { // no return field passed, just pass pointer (and ownership) of our resultP aResultFieldP=resultP; } else { // return field already exists, assign value (will convert type if needed) if (resultP) { (*aResultFieldP)=(*resultP); delete resultP; // not passed to caller, so we must get rid of it } else { // no result, unAssign aResultFieldP->unAssign(); } } // return nextbinaryop if requested if (aBinaryOpP) *aBinaryOpP=nextbinaryop; // this is how we ended } SYSYNC_CATCH (...) // delete terms if (resultP) delete resultP; if (aLeftTermP) delete aLeftTermP; if (termP) delete termP; SYSYNC_RETHROW; SYSYNC_ENDCATCH } // TScriptContext:evalExpression // execute script // returns false if script execution was not successful bool TScriptContext::ExecuteScript( const string &aTScript, TItemField **aResultPP, // if not NULL, a result field will be returned here (must be deleted by caller) bool aAsFunction, // if set, this is a function call const TFuncTable *aFuncTableP, // context's function table, NULL if none void *aCallerContext, // free pointer possibly having a meaning for context functions TMultiFieldItem *aTargetItemP, // target (or "loosing") item bool aTargetWritable, // if set, target item may be modified TMultiFieldItem *aReferenceItemP, // reference for source (or "old" or "winning") item bool aRefWritable, // if set, reference item may also be written bool aNoDebug // if set, debug output is suppressed even if DBG_SCRIPTS is generally on ) { if (aResultPP) *aResultPP=NULL; // no result yet TItemField *resultP = NULL; // none yet uInt8 tk; // current token TScriptState sta; // status skipping=0; // skipping level bool funchdr=aAsFunction; // flag if processing function header first if (funchdr) skipping=1; // skip stuff // endless loop protection lineartime_t loopmaxtime=0; // not in a loop // save context parameters fTargetItemP=aTargetItemP; // target (or "loosing") item fTargetWritable=aTargetWritable; // if set, target item may be modified fReferenceItemP=aReferenceItemP; // reference for source (or "old" or "winning") item fRefWritable=aRefWritable; // if set, reference item may also be written fFuncTableP=aFuncTableP; // context's function table, NULL if none fCallerContext=aCallerContext; #ifdef SYDEBUG debugon = !aNoDebug; #endif // init parsing (for execute) initParse(aTScript,true); // test if there's something to execute at all if (ep>bp) { #ifdef SYDEBUG if (aAsFunction) { SCRIPTDBGMSGX(DBG_SCRIPTS+DBG_HOT,("* Starting execution of user-defined function")); } else { SCRIPTDBGSTART(scriptname ? scriptname : ""); } #endif SYSYNC_TRY { // init state stack fStackEntries=0; // stack is empty pushState(ssta_statement); // start with statement // execute while ((tk=gettoken())) { resultP=NULL; // start of statement // - check for block if (tk==TK_BEGIN_BLOCK) { // push current state to stack and start new block pushState(ssta_block); if (funchdr) { // start of first block = start of function body, stop skipping funchdr=false; skipping=0; } continue; // process next } else if (tk==TK_END_BLOCK) { // pop block start, throw error if none there popState(ssta_block); // treat like end-of-statement, check for IF/ELSE/LOOP etc. goto endstatement; } else if (tk==TK_END_STATEMENT) { goto endstatement; } // - handle skipping of conditionally excluded blocks if (skipping!=0) { // only IF and ELSE are of any relevance if (tk==TK_IF) { pushState(ssta_if); // nested IF skipping++; // skip anyway } else if (tk==TK_ELSE) { // %%% this case probably never happens, as it is pre-fetched at end-of-statement // only push ELSE if this is not a chained ELSE IF if (*np!=TK_IF) pushState(ssta_else); // nested ELSE } // all others are irrelevant during skip continue; } else { // really executing // - check empty statement if (tk==TK_END_STATEMENT) goto endstatement; // - check IF statement else if (tk==TK_IF || tk==TK_WHILE) { // IF or WHILE conditional // - remember for WHILE case as condition must be re-evaluated for every loop cUInt8P condBeg = p; uInt16 condLine = line; // - process boolean expression tk=gettoken(); if (tk!=TK_OPEN_PARANTHESIS) SYSYNC_THROW(TScriptErrorException("missing '(' after IF or WHILE",line)); SCRIPTDBGMSGX(DBG_SCRIPTS+DBG_EXOTIC+DBG_SCRIPTEXPR,("- IF or WHILE, evaluating condition...")); evalExpression(resultP,EXPRDBGTEST); tk=gettoken(); if (tk!=TK_CLOSE_PARANTHESIS) SYSYNC_THROW(TScriptErrorException("missing ')' in IF or WHILE",line)); // - determine which branch to process if (!(resultP && resultP->getAsBoolean())) skipping=1; // enter skip level 1 SCRIPTDBGMSGX(DBG_SCRIPTS+DBG_EXOTIC,("- %s condition is %s", *condBeg==TK_WHILE ? "WHILE" : "IF", skipping ? "false" : "true")); delete resultP; resultP=NULL; if (*condBeg==TK_WHILE) { if (skipping) { SCRIPTDBGMSGX(DBG_SCRIPTS+DBG_HOT,("- WHILE condition is false -> skipping WHILE body")); } // for every subsequent loop, WHILE must be reprocessed pushState(ssta_while,condBeg,condLine); goto startloop; // limit loop execution time } else { // process statement (block) after IF pushState(ssta_if); } continue; } // Note: ELSE is checked at end of statement only // Check loop beginning else if (tk==TK_LOOP) { // initiate loop pushState(ssta_loop); SCRIPTDBGMSGX(DBG_SCRIPTS+DBG_EXOTIC,("- LOOP entered")); startloop: // - remember entry time of outermost loop if (loopmaxtime==0) { uInt32 loopSecs = getSyncAppBase()->getRootConfig()->fScriptConfigP->fMaxLoopProcessingTime; if (loopSecs>0) { loopmaxtime= getSystemNowAs(TCTX_UTC, getSessionZones())+ secondToLinearTimeFactor * loopSecs; } else { loopmaxtime=maxLinearTime; // virtually unlimited time } } continue; } else if (tk==TK_CONTINUE || tk==TK_BREAK) { // see if there is a LOOP or WHILE on the stack bool inloop=false; bool inwhile=false; sInt16 sp=fStackEntries; while (sp>0) { sta = fScriptstack[sp-1].state; if (sta==ssta_loop) { inloop=true; break; } // we are in a LOOP if (sta==ssta_while) { inwhile=true; break; } // we are in a WHILE sp--; } // no loop found, error if (!inloop && !inwhile) SYSYNC_THROW(TScriptErrorException("BREAK or CONTINUE without enclosing LOOP or WHILE",line)); if (tk==TK_BREAK) { // make sure we are skipping everything (including any number of nested if/else // and blocks up to reaching next end-of-loop). Note that if a LOOP or WHILE is in the // skipped part, it will not cause troubles because it is not recognized as // such while skipping. skipping=maxstackentries; } else { // continue, remove stack entries down to LOOP or WHILE and jump to beginning of loop // - same as if we had reached the bottom of the loop, but pop // open blocks, if's and else's first // - sta is ssta_loop or ssta_while to decide if we must pop the status or not goto loopcontinue; } } else if (tk==TK_TYPEDEF) { // declaration, skip it do { if (*np!=TK_IDENTIFIER) SYSYNC_THROW(TScriptErrorException("Invalid declaration",line)); tk=gettoken(); // swallow identifier if (*np==TK_OPEN_ARRAY) { // must be array declaration tk=gettoken(); // swallow [ if (*np==TK_CLOSE_ARRAY) gettoken(); // swallow ] } if (*np!=TK_LIST_SEPARATOR) break; gettoken(); // swallow separator } while(true); // end of statement should follow here, will be checked below. } else if (tk==TK_IDENTIFIER || tk==TK_OBJECT) { SCRIPTDBGMSGX(DBG_SCRIPTS+DBG_EXOTIC+DBG_SCRIPTEXPR,("- Starting assignment/unstored expression")); // could be assignment if identifier is followed by TK_ASSIGN // otherwise, it could be a simple expression evaluation cUInt8P ts=p; // remember start of statement uInt16 tl=line; // remember line as well TItemField *fldP; reusetoken(); bool writeable=getVarField(fldP); // now check if this is an assignment if (*np==TK_ASSIGN) { gettoken(); // swallow TK_ASSIGN // must be writeable if (!writeable) SYSYNC_THROW(TScriptErrorException("Not allowed to assign to this field/variable",line)); // evaluate expression into given field evalExpression(fldP,false); // we show the result ourselves DBGSTRINGDEF(s); DBGVALUESHOW(s,fldP); SCRIPTDBGMSG(("- Assigned expression result = %s",s.c_str())); } else { // must be plain expression np=ts; // back to start of statement; nextline=tl; evalExpression(resultP,true); // we always want to see the result SCRIPTDBGMSGX(DBG_SCRIPTS+DBG_EXOTIC+DBG_SCRIPTEXPR,("- Evaluated unstored expression")); // - if nothing follows, script ends here with result of expression if (*np==0) break; // - otherwise, forget result delete resultP; resultP=NULL; } } else if (tk==TK_RETURN) { // simply return if no expression follows resultP=NULL; if (*np==TK_END_STATEMENT) { SCRIPTDBGMSGX(DBG_SCRIPTS+DBG_HOT,("- RETURN: ending %s without result",aAsFunction ? "function" : "script")); break; } // evaluate expression first SCRIPTDBGMSGX(DBG_SCRIPTS+DBG_EXOTIC+DBG_SCRIPTEXPR,("- RETURN: evaluating result expression...")); evalExpression(resultP,false); // we always show the result ourselves DBGSTRINGDEF(s); DBGVALUESHOW(s,resultP); SCRIPTDBGMSGX(DBG_SCRIPTS+DBG_HOT,( "- RETURN: ending %s with result = %s", aAsFunction ? "function" : "script", s.c_str() )); // now end script break; } else { // everything else must be plain expression (e.g. function calls etc.) SCRIPTDBGMSGX(DBG_SCRIPTS+DBG_EXOTIC+DBG_SCRIPTEXPR,("- Starting evaluating unstored expression")); reusetoken(); evalExpression(resultP,false); // we always show the result ourselves SCRIPTDBGMSGX(DBG_SCRIPTS+DBG_EXOTIC+DBG_SCRIPTEXPR,("- Evaluated unstored expression")); /* %%% wrong, prevents script from returning NOTHING! to return a value, RETURN *must* be used! // - if nothing follows, script ends here with result of expression if (*np==0) { DBGSTRINGDEF(s); DBGVALUESHOW(s,resultP); SCRIPTDBGMSGX(DBG_SCRIPTS+DBG_HOT,( "- Script ends with result = %s", s.c_str() )); break; } */ // - otherwise, forget result delete resultP; resultP=NULL; } } // not skipping // Statement executed, next must be end-of-statement tk=gettoken(); if (tk!=TK_END_STATEMENT) SYSYNC_THROW(TScriptErrorException("missing ';' after statement",line)); // Statement executed and properly terminated endstatement: // check state sta=fScriptstack[fStackEntries-1].state; // check end of IF block if (sta==ssta_if) { SCRIPTDBGMSGX(DBG_SCRIPTS+DBG_EXOTIC,("- End of %s IF",skipping ? "skipped" : "executed")); popState(sta); // end this state if (skipping) { // IF branch was not executed, check for else if (*np==TK_ELSE) { // else follows // - swallow TK_ELSE gettoken(); // - check for ELSE IF chain // (in this case, we must NOT push a state, but let chained IF push TK_IF again // and also increment skipping again, after it is decremented by one below) if (*np!=TK_IF) { pushState(ssta_else); // end-of-chain ELSE: enter else state // keep skipping (compensate for decrement below) ONLY if end-of-chain ELSE // is not to be executed due to surrounding skip. if (skipping>1) skipping++; } } // no ELSE, just continue with next statement skipping--; // reduce skip level continue; } else { // IF branch was executed, check for else if (*np==TK_ELSE) { // else follows, skip it (including all chained IFs) skipping=1; gettoken(); // swallow ELSE // - check for ELSE IF chain if (*np==TK_IF) { // chained if while skipping gettoken(); // consume it (avoid regular parsing to see it and increment skipping) pushState(ssta_chainif); // chained IF, make sure nothing is executed up to and including end-of-chain else } else pushState(ssta_else); // process as skipped ELSE part } // no else, simply continue execution continue; } } else if (sta==ssta_chainif) { // only entered while skipping rest of chain SCRIPTDBGMSGX(DBG_SCRIPTS+DBG_EXOTIC,("- End of skipped ELSE IF")); if (*np==TK_ELSE) { gettoken(); // consume it if (*np==TK_IF) { // chained if while skipping gettoken(); // consume it (avoid regular parsing to see it and increment skipping) // stay in ssta_chainif } else { popState(ssta_chainif); // end of ELSE IF chain pushState(ssta_else); // rest is a normal skipped ELSE part } } else { // end of skipped chained ifs popState(ssta_chainif); skipping--; } } else if (sta==ssta_else) { SCRIPTDBGMSGX(DBG_SCRIPTS+DBG_EXOTIC,("- End of %s ELSE",skipping ? "skipped" : "executed")); popState(ssta_else); // end of else state if (skipping) skipping--; } // check end of LOOP block else if (sta==ssta_loop || sta==ssta_while) { // Note: we'll never see that for a completely skipped loop/while, as // no ssta_loop/ssta_while is pushed while skipping. if (!skipping) goto loopcontinue; // not end of while or breaking out of loop, repeat // - end of loop reached popState(sta); skipping=0; // end of loop found after BREAK, continue normal execution SCRIPTDBGMSGX(DBG_SCRIPTS+DBG_EXOTIC,("- End of WHILE or LOOP")); } // nothing special, just execute next statement continue; loopcontinue: // continue at beginning of loop which is at top of state stack if (getSystemNowAs(TCTX_UTC, getSessionZones())>loopmaxtime) SYSYNC_THROW(TScriptErrorException("loop execution aborted because reached (endless loop?)",line)); // go to beginning of loop: restore position of beginning of loop (including condition in case of WHILE) np=fScriptstack[fStackEntries-1].begin; // next token after current token nextline=fScriptstack[fStackEntries-1].line; // line of next token after current token linesource=NULL; // prevent showing source (which is that of NEXT line, not that of jump target's // for while, we must pop the stack entry as it will be recreated by re-excution of the WHILE statement if (sta==ssta_while) popState(sta); SCRIPTDBGMSGX(DBG_SCRIPTS+DBG_HOT,("- Starting next iteration of LOOP/WHILE -> jumping to line %hd",nextline)); continue; } // while more tokens } // try SYSYNC_CATCH (exception &e) // make sure field is deleted if (resultP) delete resultP; // show error message SCRIPTDBGMSGX(DBG_ERROR,("Warning: TERMINATING SCRIPT WITH ERROR: %s",e.what())); if (!aAsFunction) SCRIPTDBGEND(); return false; SYSYNC_ENDCATCH #ifdef SYDEBUG if (aAsFunction) { SCRIPTDBGMSGX(DBG_SCRIPTS+DBG_HOT,("* Successfully finished execution of user-defined function")); } else { SCRIPTDBGEND(); } #endif } // if something to execute at all // return most recent evaluated expression (normally RETURN expression) if (aResultPP) { // caller wants to see result, pass it back if (*aResultPP && resultP) { // script result field already exists, assign value (**aResultPP)=(*resultP); delete resultP; } else { // script result field does not yet exist, just pass result (even if it is NULL) *aResultPP=resultP; } } else if (resultP) delete resultP; // nobody needs the result, delete it // execution successful return true; } // TScriptContext::ExecuteScript // get variable definition by name, NULL if none defined yet TScriptVarDef *TScriptContext::getVarDef(cAppCharP aVarName,size_t len) { TVarDefs::iterator pos; for (pos=fVarDefs.begin(); pos!=fVarDefs.end(); pos++) { if (strucmp((*pos)->fVarName.c_str(),aVarName,0,len)==0) return (*pos); } return NULL; } // TScriptContext::getVarDef // get variable definition by index, NULL if none defined yet TScriptVarDef *TScriptContext::getVarDef(sInt16 aLocalVarIdx) { if (aLocalVarIdx<0 || uInt32(aLocalVarIdx)>=fVarDefs.size()) return NULL; return fVarDefs[aLocalVarIdx]; } // TScriptContext::getVarDef // - get identifier index (>=0: field index, <0: local var) // returns VARIDX_UNDEFINED for unknown identifier sInt16 TScriptContext::getIdentifierIndex(sInt16 aObjIndex, TFieldListConfig *aFieldListConfigP, cAppCharP aIdentifier,size_t aLen) { // first look for local variable if (aObjIndex==OBJ_AUTO || aObjIndex==OBJ_LOCAL) { TScriptVarDef *vardefP = getVarDef(aIdentifier,aLen); if (vardefP) { return - (sInt16)vardefP->fIdx-1; } } if (aObjIndex==OBJ_AUTO || aObjIndex==OBJ_TARGET || aObjIndex==OBJ_REFERENCE) { // look for field with that name if (!aFieldListConfigP) return VARIDX_UNDEFINED; // no field list available here return aFieldListConfigP->fieldIndex(aIdentifier,aLen); } else return VARIDX_UNDEFINED; // unknown object, unknown index } // TScriptContext::getIdentifierIndex // get field by fid, can also be field of aItem, also resolves arrays TItemField *TScriptContext::getFieldOrVar(TMultiFieldItem *aItemP, sInt16 aFid, sInt16 aArrIdx) { TItemField *fldP = getFieldOrVar(aItemP,aFid); if (!fldP) return NULL; #ifdef ARRAYFIELD_SUPPORT if (aArrIdx>=0) return fldP->getArrayField(aArrIdx); else return fldP; // return field without array resolution #else if (aArrIdx>0) return NULL; return fldP; #endif } // TScriptContext::getFieldOrVar // get field by fid, can be field of aItem (positive aFid) or local variable (negative fid) TItemField *TScriptContext::getFieldOrVar(TMultiFieldItem *aItemP, sInt16 aFid) { if (aFid<0) return getLocalVar(-aFid-1); if (!aItemP) return NULL; return aItemP->getField(aFid); } // TScriptContext::getFieldOrVar // get local var by local index TItemField *TScriptContext::getLocalVar(sInt16 aVarIdx) { if (aVarIdx<0 || aVarIdx>=fNumVars) return NULL; return fFieldsP[aVarIdx]; } // TScriptContext::getLocalVar // set local var by local index (used for passing references) void TScriptContext::setLocalVar(sInt16 aVarIdx, TItemField *aFieldP) { if (aVarIdx<0 || aVarIdx>=fNumVars) return; fFieldsP[aVarIdx]=aFieldP; // set new } // TScriptContext::setLocalVar /* end of TScriptContext implementation */ #ifdef ENGINEINTERFACE_SUPPORT // TScriptVarKey // ============= // get FID for specified name sInt16 TScriptVarKey::getFidFor(cAppCharP aName, stringSize aNameSz) { if (fScriptContext==NULL) return VARIDX_UNDEFINED; // check for iterator commands first if (strucmp(aName,VALNAME_FIRST)==0) { fIterator=0; if (fIterator>=sInt32(fScriptContext->fVarDefs.size())) return VARIDX_UNDEFINED; return -fIterator-1; } else if (strucmp(aName,VALNAME_NEXT)==0) { fIterator++; if (fIterator>=sInt32(fScriptContext->fVarDefs.size())) return VARIDX_UNDEFINED; return -fIterator-1; } else return fScriptContext->getIdentifierIndex(OBJ_LOCAL, NULL, aName, aNameSz); } // TScriptVarKey::getFidFor // get base field from FID TItemField *TScriptVarKey::getBaseFieldFromFid(sInt16 aFid) { if (fScriptContext==NULL) return NULL; return fScriptContext->getFieldOrVar(NULL, aFid); } // TScriptVarKey::getBaseFieldFromFid // get field name from FID bool TScriptVarKey::getFieldNameFromFid(sInt16 aFid, string &aFieldName) { if (fScriptContext==NULL) return false; TScriptVarDef *vardefP = fScriptContext->getVarDef(-aFid-1); if (vardefP) { aFieldName = vardefP->fVarName; return true; } // none found return false; } // TScriptVarKey::getFieldNameFromFid #endif // ENGINEINTERFACE_SUPPORT } // namespace sysync #endif // SCRIPT_SUPPORT // eof libsynthesis-3.4.0.47.1/src/sysync/scriptcontext.h000077500000000000000000000420601226375725500220520ustar00rootroot00000000000000/* * File: scriptcontext.cpp * * Author: Lukas Zeller (luz@plan44.ch) * * TScriptContext * Environment to tokenize, prepare and run scripts * * Copyright (c) 2002-2011 by Synthesis AG + plan44.ch * * 2002-09-11 : luz : created * * */ #ifdef SCRIPT_SUPPORT #ifndef SCRIPT_CONTEXT_H #define SCRIPT_CONTEXT_H // includes #include "sysync.h" #include "itemfield.h" #include "multifielditem.h" using namespace sysync; namespace sysync { /* * builtin function definitions */ #define PARAM_TYPEMASK 0x1F #define PARAM_OPT 0x20 #define PARAM_REF 0x40 #define PARAM_ARR 0x80 #define VAL(x) ( (uInt8)x) #define OPTVAL(x) (((uInt8)x)+PARAM_OPT) #define REF(x) (((uInt8)x)+PARAM_REF) #define REFARR(x) (((uInt8)x)+PARAM_REF+PARAM_ARR) extern const uInt8 param_oneTimestamp[]; extern const uInt8 param_oneInteger[]; extern const uInt8 param_oneString[]; extern const uInt8 param_oneVariant[]; extern const uInt8 param_oneOptInteger[]; // Token definitions // - Multi-Byte tokens: // tldddddddddddddd // - t=token ID alphanum. // - l=length of additional token data, 0x00..0xFF as one char // - dddddd=additional token data // highest Multibyte token #define TK_MAX_MULTIBYTE 0x1F // - literals, dddd=literal string #define TK_NUMERIC_LITERAL 0x10 #define TK_STRING_LITERAL 0x11 // - variable identifiers, dddd = idddddd // where i=room for field index, dddd=identifier #define TK_IDENTIFIER 0x12 // - script line token, dd = line number 16bit, followed by source text (NUL terminated) if script debug on #define TK_SOURCELINE 0x13 // - object specifier, d=single object index byte #define TK_OBJECT 0x14 // - builtin function identifier, d=function index #define TK_FUNCTION 0x15 // - user defined function identifier, idddddd i=room for function index, ddd=function name #define TK_USERFUNCTION 0x16 // - built-in context-dependent function #define TK_CONTEXTFUNCTION 0x17 // - type definition, d=TItemFieldTypes enum #define TK_TYPEDEF 0x18 // object indices #define OBJ_AUTO 0 // not specified, is local or target field #define OBJ_LOCAL 1 // local variable #define OBJ_TARGET 2 // target field #define OBJ_REFERENCE 3 // reference field // - language elements, 0x80..0x9F #define TK_IF 0x80 #define TK_ELSE 0x81 #define TK_LOOP 0x82 #define TK_BREAK 0x83 #define TK_CONTINUE 0x84 #define TK_RETURN 0x85 #define TK_WHILE 0x86 // - constants #define TK_EMPTY 0x90 #define TK_UNASSIGNED 0x91 #define TK_TRUE 0x92 #define TK_FALSE 0x93 // - grouping, in the 0x20..0x3F area #define TK_DOMAINSEP '.' #define TK_OPEN_PARANTHESIS '(' #define TK_CLOSE_PARANTHESIS ')' #define TK_LIST_SEPARATOR ',' #define TK_BEGIN_BLOCK 0x30 #define TK_END_BLOCK 0x31 #define TK_END_STATEMENT ';' #define TK_OPEN_ARRAY 0x32 #define TK_CLOSE_ARRAY 0x33 // - operators, in the 0x40..0x7F range // in order of precedence (upper 6 bits = precedence) #define TK_OP_PRECEDENCE_MASK 0xFC #define TK_BINOP_MIN 0x44 #define TK_BINOP_MAX 0x68 // excluding assignment %%% // Pure unaries // - negation #define TK_BITWISENOT 0x40 #define TK_LOGICALNOT 0x41 // Binaries (some of them also used as unaries, like MINUS) // - multiply, divide #define TK_MULTIPLY 0x44 #define TK_DIVIDE 0x45 #define TK_MODULUS 0x46 // - add, subtract #define TK_PLUS 0x48 #define TK_MINUS 0x49 // - shift #define TK_SHIFTLEFT 0x4C #define TK_SHIFTRIGHT 0x4D // - comparison #define TK_LESSTHAN 0x50 #define TK_GREATERTHAN 0x51 #define TK_LESSEQUAL 0x52 #define TK_GREATEREQUAL 0x53 // - equality #define TK_EQUAL 0x54 #define TK_NOTEQUAL 0x55 // - bitwise AND #define TK_BITWISEAND 0x58 // - bitwise XOR #define TK_BITWISEXOR 0x5C // - bitwise OR #define TK_BITWISEOR 0x60 // - logical AND #define TK_LOGICALAND 0x64 // - logical OR #define TK_LOGICALOR 0x68 // Special modifying operator // - assignment #define TK_ASSIGN 0x6C // local script variable definition class TScriptVarDef { public: TScriptVarDef(cAppCharP aName,uInt16 aIdx, TItemFieldTypes aType, bool aIsArray, bool aIsRef, bool aIsOpt); ~TScriptVarDef(); uInt16 fIdx; // index (position in container). string fVarName; // Variable name TItemFieldTypes fVarType; // type of variable bool fIsArray; bool fIsRef; // set if this is a local reference to an existing variable bool fIsOpt; // set if this is a optional parameter }; // TScriptVarDef // script variables typedef std::vector TVarDefs; // user defined script function class TUserScriptFunction { public: string fFuncName; string fFuncDef; }; // TUserScriptFunction typedef std::vector TUserScriptList; // global script config (such as user-defined functions) class TScriptConfig : public TConfigElement { typedef TConfigElement inherited; public: TScriptConfig(TConfigElement *aParentElementP); virtual ~TScriptConfig(); // properties uInt32 fMaxLoopProcessingTime; // seconds // special scripts // user-defined functions TUserScriptList fFunctionScripts; // macros (pure texts used while parsing) TStringToStringMap fScriptMacros; // accessing user defined functions string *getFunctionScript(sInt16 aFuncIndex); sInt16 getFunctionIndex(cAppCharP aName, size_t aLen); virtual void clear(); void clearmacros() { fScriptMacros.clear(); }; // called when config is read, as then templates are no longer needed protected: // check config elements virtual bool localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine); virtual void localResolve(bool aLastPass); }; // TScriptConfig // script tokenizing error class TTokenizeException : public TConfigParseException { typedef TConfigParseException inherited; public: TTokenizeException(cAppCharP aScriptName, cAppCharP aMsg1,cAppCharP aScript, uInt16 aIndex, uInt16 aLine); }; // TTokenizeException // script resolving or execution error class TScriptErrorException : public TConfigParseException { typedef TConfigParseException inherited; public: TScriptErrorException(cAppCharP aMsg1, uInt16 aLine, cAppCharP aIdent=NULL); }; // TScriptErrorException // folder mapping table typedef std::vector TMacroArgsArray; // script execution state stack typedef enum { ssta_statement, ssta_block, ssta_if, ssta_else, ssta_chainif, ssta_loop, ssta_while, } TScriptState; typedef struct { TScriptState state; // state cUInt8P begin; // begin of that state in source uInt16 line; // line number } TScriptStackEntry; // flow control stack depth const sInt16 maxstackentries=40; class TMultiFieldItem; // script context class TScriptContext { friend class TScriptVarKey; public: TScriptContext(TSyncAppBase *aAppBaseP, TSyncSession *aSessionP); virtual ~TScriptContext(); // Tokenizing is available without context static void Tokenize(TSyncAppBase *aAppBaseP, cAppCharP aScriptName, sInt32 aLine, cAppCharP aScriptText, string &aTScript, const TFuncTable *aContextFuncs, bool aFuncHeader=false, bool aNoDeclarations=false, TMacroArgsArray *aMacroArgsP=NULL); static void TokenizeAndResolveFunction(TSyncAppBase *aAppBaseP, sInt32 aLine, cAppCharP aScriptText, TUserScriptFunction &aFuncDef); // resolve identifiers in a script, if there is a context passed at all static void resolveScript(TSyncAppBase *aAppBaseP, string &aTScript,TScriptContext *&aCtxP, TFieldListConfig *aFieldListConfigP); // rebuild a script context for a script, if the script is not empty // - Script must already be resolved with ResolveIdentifiers // - If context already exists, adds new locals to existing ones // - If aBuildVars is set, buildVars() will be called after rebuilding variable definitions static void rebuildContext(TSyncAppBase *aAppBaseP, string &aTScript,TScriptContext *&aCtxP, TSyncSession *aSessionP=NULL, bool aBuildVars=false); // - link a script into a contect with already instantiated variables. This is e.g. for activating remoterule scripts static void linkIntoContext(string &aTScript,TScriptContext *aCtxP, TSyncSession *aSessionP); // Build the local variables according to definitions (clears existing vars first) static void buildVars(TScriptContext *&aCtxP); // execute a script if there is a context for it bool static execute( TScriptContext *aCtxP, const string &aTScript, const TFuncTable *aFuncTableP, // context's function table, NULL if none void *aCallerContext, // free pointer possibly having a meaning for context functions TMultiFieldItem *aTargetItemP=NULL, // target (or "loosing") item bool aTargetWritable=true, // if set, target item may be modified TMultiFieldItem *aReferenceItemP=NULL, // reference for source (or "old" or "winning") item bool aRefWritable=false, // if set, reference item may also be written bool aNoDebug=false // if set, debug output is suppressed even if DBG_SCRIPTS is generally on ); // execute a script returning a boolean if there is a context for it bool static executeTest( bool aDefaultAnswer, // result if no script is there or script returns no value TScriptContext *aCtxP, const string &aTScript, const TFuncTable *aFuncTableP, // context's function table, NULL if none void *aCallerContext, // free pointer possibly having a meaning for context functions TMultiFieldItem *aTargetItemP=NULL, // target (or "loosing") item bool aTargetWritable=true, // if set, target item may be modified TMultiFieldItem *aReferenceItemP=NULL, // reference for source (or "old" or "winning") item bool aRefWritable=false // if set, reference item may also be written ); // execute a script returning a result if there is a context for it bool static executeWithResult( TItemField *&aResultField, // can be default result or NULL, will contain result or NULL if no result TScriptContext *aCtxP, const string &aTScript, const TFuncTable *aFuncTableP, // context's function table, NULL if none void *aCallerContext, // free pointer possibly having a meaning for context functions TMultiFieldItem *aTargetItemP, // target (or "loosing") item bool aTargetWritable, // if set, target item may be modified TMultiFieldItem *aReferenceItemP, // reference for source (or "old" or "winning") item bool aRefWritable, // if set, reference item may also be written bool aNoDebug=false // if set, debug output is suppressed even if DBG_SCRIPTS is generally on ); // get info uInt16 getScriptLine(void) { return line; }; // get context pointers TSyncSession *getSession(void) { return fSessionP; }; TSyncAppBase *getSyncAppBase(void) { return fAppBaseP; }; GZones *getSessionZones(void); #ifdef SYDEBUG TDebugLogger *getDbgLogger(void); uInt32 getDbgMask(void); #endif // Reset context (clear all variables and definitions) void clear(void); // clear all fields (local variables), but not their definitions void clearFields(void); // Resolve local variable declarations, references and field references void ResolveIdentifiers( string &aTScript, TFieldListConfig *aFieldListConfigP, bool aRebuild=false, string *aFuncNameP=NULL, bool aNoNewLocals=false // if set, declaration of new locals will be suppressed ); // Prepare local variables (create local fields), according to definitions (re-)built with ResolveIdentifiers() bool PrepareLocals(void); // Execute script bool ExecuteScript( const string &aTScript, TItemField **aResultPP, // if not NULL, a result field will be returned here (must be deleted by caller) bool aAsFunction, // if set, this is a function call const TFuncTable *aFuncTableP, // context's function table, NULL if none void *aCallerContext, // free pointer possibly having a meaning for context functions TMultiFieldItem *aTargetItemP, // target (or "loosing") item bool aTargetWritable, // if set, target item may be modified TMultiFieldItem *aReferenceItemP, // reference for source (or "old" or "winning") item bool aRefWritable, // if set, reference item may also be written bool aNoDebug=false // if set, debug output is suppressed even if DBG_SCRIPTS is generally on ); // context variable access // - get variable definition, NULL if none defined yet TScriptVarDef *getVarDef(cAppCharP aVarName,size_t len=0); TScriptVarDef *getVarDef(sInt16 aLocalVarIdx); // - get identifier index (>=0: field index, <0: local var) // returns VARIDX_UNDEFINED for unknown identifier sInt16 getIdentifierIndex(sInt16 aObjIndex, TFieldListConfig *aFieldListConfigP, cAppCharP aIdentifier,size_t aLen=0); // - get field by fid, can also be field of aItem, also resolves arrays TItemField *getFieldOrVar(TMultiFieldItem *aItemP, sInt16 aFid, sInt16 aArrIdx); // - get field by fid, can also be field of aItem TItemField *getFieldOrVar(TMultiFieldItem *aItemP, sInt16 aFid); // - get local var by local index TItemField *getLocalVar(sInt16 aVarIdx); // - set local var by local index (used for passing references) void setLocalVar(sInt16 aVarIdx, TItemField *aFieldP); sInt16 getNumLocals(void) { return fNumVars; }; // - parameters sInt16 getNumParams(void) { return fNumParams; }; // - caller's context data pointer (opaque, for use by context functions) void *getCallerContext(void) { return fCallerContext; }; private: // syncappbase link, must always exist TSyncAppBase *fAppBaseP; // session link, can be NULL TSyncSession *fSessionP; // local variable definitions (used in resolve phase) TVarDefs fVarDefs; // actually instantiated local variable fields (size of fFieldsP array, used at execution) // Note: might differ from fVarDefs when new vars have been defined, but not instantiated yet) uInt16 fNumVars; // function properties (if context is a function context) uInt16 fNumParams; // this determines the number of parameter locals TItemFieldTypes fFuncType; // return type of function // The local variables and field references TItemField **fFieldsP; // script parsing // - variables sInt16 skipping; // skipping uInt16 line,nextline; // line numbers cUInt8P bp; // start of script cUInt8P ep; // end of script cUInt8P p; // cursor, start at beginning cUInt8P np; // next token #ifdef SYDEBUG const char *scriptname; // name of script const char *linesource; // start of embedded source for current line bool executing; // set if executing (not resolving) bool debugon; // set if debug enabled bool inComment; // for colorizer #endif // - helpers void initParse(const string &aTScript, bool aExecuting=false); // init parsing variables uInt8 gettoken(void); // get next token void reusetoken(void); // re-use last token fetched with gettoken() // script execution // - flow control state stack sInt16 fStackEntries; TScriptStackEntry fScriptstack[maxstackentries]; // - context information public: // Items TMultiFieldItem *fTargetItemP; bool fTargetWritable; TMultiFieldItem *fReferenceItemP; bool fRefWritable; // Link to calling script context (for function contexts) TScriptContext *fParentContextP; private: // Function table const TFuncTable *fFuncTableP; // caller context's function table void *fCallerContext; // free pointer possibly having a meaning for context functions // - helpers void pushState(TScriptState aNewState, cUInt8P aBegin=NULL, uInt16 aLine=0); void popState(TScriptState aCurrentStateExpected); bool getVarField(TItemField *&aItemFieldP); void evalParams(TScriptContext *aFuncContextP); TItemField *evalTerm(TItemFieldTypes aResultType); void evalExpression( TItemField *&aResultFieldP, // result (created new if passed NULL, modified and casted if passed a field) bool aShowResult=true, // if set, this is the main expression (and we want to see the result in DBG) TItemField *aLeftTermP=NULL, // if not NULL, chain-evaluate rest of expression according to aBinaryOp and aPreviousOp. WILL BE CONSUMED uInt8 *aBinaryOpP=NULL, // operator to be applied between term passed in aLeftTermP and next term, will receive next operator that has same or lower precedence than aPreviousOp uInt8 aPreviousOp=0 // if an operator of same or lower precedence than this is found, expression evaluation ends ); void defineBuiltInVars(const TBuiltInFuncDef *aFuncDefP); void executeBuiltIn(TItemField *&aTermP, const TBuiltInFuncDef *aFuncDefP); #ifdef SYDEBUG void showVarDefs(cAppCharP aTxt); #endif }; // TScriptContext #ifdef ENGINEINTERFACE_SUPPORT // key for access to script context variables class TScriptVarKey : public TItemFieldKey { typedef TItemFieldKey inherited; public: TScriptVarKey(TEngineInterface *aEngineInterfaceP, TScriptContext *aScriptContext) : inherited(aEngineInterfaceP), fScriptContext(aScriptContext), // may be NULL, no vars will be accessible then but no crash occurs fIterator(0) {}; protected: // methods to actually access a TItemField virtual sInt16 getFidFor(cAppCharP aName, stringSize aNameSz); virtual TItemField *getBaseFieldFromFid(sInt16 aFid); virtual bool getFieldNameFromFid(sInt16 aFid, string &aFieldName); // the script context TScriptContext *fScriptContext; // value iterator sInt16 fIterator; }; // TScriptVarKey #endif // ENGINEINTERFACE_SUPPORT } // namespace sysync #endif // SCRIPT_CONTEXT_H #endif // SCRIPT_SUPPORT /* eof */ libsynthesis-3.4.0.47.1/src/sysync/simpleitem.cpp000077500000000000000000000047551226375725500216550ustar00rootroot00000000000000/* * File: SimpleItem.cpp * * Author: Lukas Zeller (luz@plan44.ch) * * TSimpleItem * Simple item, no internal structure but just a string * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * 2001-06-18 : luz : created * */ // includes #include "prefix_file.h" #include "sysync.h" #include "simpleitem.h" #ifdef CHECKSUM_CHANGELOG #include "sysync_crc16.h" #endif using namespace sysync; /* * Implementation of TSimpleItem */ TSimpleItem::TSimpleItem(TSyncItemType *aItemTypeP) : TSyncItem(aItemTypeP) { // save link to type fItemTypeP = aItemTypeP; } // TSimpleItem::TSimpleItem TSimpleItem::~TSimpleItem() { } // TSimpleItem::~TSimpleItem #ifdef CHECKSUM_CHANGELOG // changelog support: calculate CRC over contents uInt16 TSimpleItem::getDataCRC(uInt16 crc, bool aEQRelevantOnly) { // CRC of contents string (no change if nothing in it) return sysync_crc16_block(fContents.c_str(),fContents.size(),crc); } // TSimpleItem::getDataCRC #endif // test if comparable (at least for equality) bool TSimpleItem::comparable(TSyncItem &aItem) { // test if comparable: only SimpleItems can be compared return aItem.getTypeID() == getTypeID(); } // TSimpleItem::comparable // replace data contents from specified item // - aAvailable only: only replace contents actually available in aItem, leave rest untouched // - aDetectCutOffs: handle case where aItem could have somhow cut-off data and prevent replacing // complete data with cut-off version (e.g. mobiles like T39m with limited name string capacity) bool TSimpleItem::replaceDataFrom(TSyncItem &aItem, bool aAvailableOnly, bool aDetectCutoffs, bool aAssignedOnly, bool aTransferUnassigned) { // check type if (!aItem.isBasedOn(ity_simple)) return false; // ok, same type, copy data fContents=static_cast(&aItem)->fContents; return true; } // TSimpleItem::replaceDataFrom // compare function, returns 0 if equal, 1 if this > aItem, -1 if this < aItem sInt16 TSimpleItem::compareWith( TSyncItem &aItem, TEqualityMode aEqMode, TLocalEngineDS *aDatastoreP #ifdef SYDEBUG ,bool aDebugShow #endif ) { // we should test for comparable() before! if (!comparable(aItem)) return SYSYNC_NOT_COMPARABLE; TSimpleItem *simpleitemP = ((TSimpleItem *)&aItem); // compare (equality only, mod date/version is unknown) if (fContents == simpleitemP->fContents) return 0; else return SYSYNC_NOT_COMPARABLE; } // TSimpleItem::compareWith /* end of TSimpleItem implementation */ // eof libsynthesis-3.4.0.47.1/src/sysync/simpleitem.h000077500000000000000000000045111226375725500213100ustar00rootroot00000000000000/* * File: SimpleItem.h * * Author: Lukas Zeller (luz@plan44.ch) * * TSimpleItem * Simple item, no internal structure but just a string * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * 2001-06-18 : luz : created * */ #ifndef SimpleItem_H #define SimpleItem_H // includes #include "syncitem.h" #include "sysync.h" namespace sysync { const uInt16 ity_simple = 1; // must be unique class TSimpleItem: public TSyncItem { typedef TSyncItem inherited; public: TSimpleItem(TSyncItemType *aItemTypeP); virtual ~TSimpleItem(); // access to type virtual uInt16 getTypeID(void) const { return ity_simple; }; virtual bool isBasedOn(uInt16 aItemTypeID) const { return aItemTypeID==ity_simple ? true : TSyncItem::isBasedOn(aItemTypeID); }; // assignment (IDs and contents) virtual TSyncItem& operator=(TSyncItem &aSyncItem) { return TSyncItem::operator=(aSyncItem); }; // access to simple item contents const char *getContents(void) { return fContents.c_str(); }; void setContents(const char *aContents) { fContents = aContents; }; // compare abilities virtual bool comparable(TSyncItem &aItem); virtual bool sortable(TSyncItem &aItem) { return false; } // clear item data virtual void cleardata(void) { fContents.erase(); }; // - changelog support #ifdef CHECKSUM_CHANGELOG virtual uInt16 getDataCRC(uInt16 crc=0, bool aEQRelevantOnly=false); #endif // replace data contents from specified item // - aAvailable only: only replace contents actually available in aItem, leave rest untouched // - aDetectCutOffs: handle case where aItem could have somhow cut-off data and prevent replacing // complete data with cut-off version (e.g. mobiles like T39m with limited name string capacity) virtual bool replaceDataFrom(TSyncItem &aItem, bool aAvailableOnly=false, bool aDetectCutoffs=false, bool aAssignedOnly=false, bool aTransferUnassigned=false); protected: // compare function, returns 0 if equal, 1 if this > aItem, -1 if this < aItem virtual sInt16 compareWith( TSyncItem &aItem, TEqualityMode aEqMode, TLocalEngineDS *aDatastoreP #ifdef SYDEBUG ,bool aDebugShow=false #endif ); // associated type item TSyncItemType *fItemTypeP; // contents: simple string string fContents; }; // TSimpleItem } // namespace sysync #endif // SimpleItem_H // eof libsynthesis-3.4.0.47.1/src/sysync/smltk_precomp.h000077500000000000000000000017011226375725500220150ustar00rootroot00000000000000/* C Headers that might be available in precompiled form * for SML toolkit compilation. * (standard libraries, SyncML toolkit itself...) */ #ifndef SMLTK_PRECOMP_H #define SMLTK_PRECOMP_H /* prerequisites for SML toolkit */ // - compiler/platform specific defines #include "define.h" // - special, platform dependent lock library // (may include extra platform support headers BEFORE // other SML files will include standard platform support) #include "liblock.h" /* standard C includes */ #include #include #ifdef __PALM_OS__ #include #include #include #else #include #include #endif #if !defined(__MC68K__) && !defined(LINUX) && !defined(WINCE) && !defined(MACOSX) && !defined(__EPOC_OS__) #include #endif /* SyncML Toolkit includes */ // - SyncML Toolkit external API #include "sml.h" #include "smlerr.h" #endif /* defined SMLTK_PRECOMP_H */ libsynthesis-3.4.0.47.1/src/sysync/smltk_precomp_xpt.h000077500000000000000000000005431226375725500227130ustar00rootroot00000000000000/* C Headers that might be available in precompiled form * for SML toolkit compilation. * (standard libraries, SyncML toolkit itself...) */ #ifndef SMLTK_PRECOMP_XPT_H #define SMLTK_PRECOMP_XPT_H /* SyncML Toolkit includes */ // standard stuff #include "smltk_precomp.h" // plus XPT stuff #include "xpt.h" #endif /* defined SMLTK_PRECOMP_XPT_H */ libsynthesis-3.4.0.47.1/src/sysync/stdlogicagent.cpp000077500000000000000000000030011226375725500223130ustar00rootroot00000000000000/** * @File stdlogicagent.cpp * * @Author Lukas Zeller (luz@plan44.ch) * * @brief TStdLogicAgent * Agent (=server or client session) for standard database logic implementations, see @ref TStdLogicDS * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * @Date 2005-09-23 : luz : created from custdbagent */ /* */ // includes #include "prefix_file.h" #include "stdlogicagent.h" /* * Implementation of TStdLogicAgent */ /* public TStdLogicAgent members */ TStdLogicAgent::TStdLogicAgent(TSyncAppBase *aAppBaseP, TSyncSessionHandle *aSessionHandleP, cAppCharP aSessionID) : inherited(aAppBaseP, aSessionHandleP, aSessionID) { if (IS_SERVER) { #ifdef SYSYNC_SERVER InternalResetSession(); #endif } } // TStdLogicAgent::TStdLogicAgent // destructor TStdLogicAgent::~TStdLogicAgent() { // make sure everything is terminated BEFORE destruction of hierarchy begins TerminateSession(); } // TStdLogicAgent::~TStdLogicAgent // Terminate session void TStdLogicAgent::TerminateSession() { if (!fTerminated) { InternalResetSession(); } inherited::TerminateSession(); } // TStdLogicAgent::TerminateSession // Reset session void TStdLogicAgent::InternalResetSession(void) { } // TStdLogicAgent::InternalResetSession // Virtual version void TStdLogicAgent::ResetSession(void) { // do my own stuff InternalResetSession(); // let ancestor do its stuff inherited::ResetSession(); } // TStdLogicAgent::ResetSession /* end of TStdLogicAgent implementation */ // eof libsynthesis-3.4.0.47.1/src/sysync/stdlogicagent.h000077500000000000000000000030151226375725500217650ustar00rootroot00000000000000/** * @File stdlogicagent.h * * @Author Lukas Zeller (luz@plan44.ch) * * @brief TStdLogicAgent * Agent (=server or client session) for standard database logic implementations, see @ref TStdLogicDS * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * @Date 2005-09-23 : luz : created from custdbagent */ /* */ #ifndef STDLOGICAGENT_H #define STDLOGICAGENT_H // includes #include "sysync.h" #include "syncagent.h" #include "localengineds.h" using namespace sysync; namespace sysync { class TStdLogicAgent: public TSyncAgent { typedef TSyncAgent inherited; public: TStdLogicAgent(TSyncAppBase *aAppBaseP, TSyncSessionHandle *aSessionHandleP, cAppCharP aSessionID); virtual ~TStdLogicAgent(); virtual void TerminateSession(void); // Terminate session, like destructor, but without actually destructing object itself virtual void ResetSession(void); // Resets session (but unlike TerminateSession, session might be re-used) void InternalResetSession(void); // static implementation for calling through virtual destructor and virtual ResetSession(); // user authentication #ifndef SYSYNC_CLIENT // - server-only build should implement it, so we make it abstract here again (altough there is // an implementation for simpleauth in session. virtual bool SessionLogin(const char *aUserName, const char *aAuthString, TAuthSecretTypes aAuthStringType, const char *aDeviceID) = 0; #endif // not SYSYNC_CLIENT }; // TStdLogicAgent } // namespace sysync #endif // STDLOGICAGENT_H // eof libsynthesis-3.4.0.47.1/src/sysync/stdlogicds.cpp000066400000000000000000002104551226375725500216350ustar00rootroot00000000000000/** * @File stdlogicds.cpp * * @Author Lukas Zeller (luz@plan44.ch) * * @brief TStdLogicDS * Standard database logic implementation, suitable for most (currently all) * actual DS implementations, but takes as few assumptions about datastore * so for vastly different sync patterns, this could be replaced by differnt locic * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * @Date 2005-09-15 : luz : created from custdbdatastore */ /* */ // includes #include "prefix_file.h" #include "sysync.h" #include "stdlogicds.h" #include "multifielditem.h" #include "multifielditemtype.h" using namespace sysync; namespace sysync { /* * Implementation of TStdLogicDS */ /* public TStdLogicDS members */ TStdLogicDS::TStdLogicDS( TLocalDSConfig *aDSConfigP, sysync::TSyncSession *aSessionP, const char *aName, long aCommonSyncCapMask ) : TLocalEngineDS(aDSConfigP, aSessionP, aName, aCommonSyncCapMask) #ifdef MULTI_THREAD_DATASTORE ,fMultiThread(NULL) ,fStartSyncStatus(aSessionP) // a thread-private status command to store status ocurring during threaded startDataAccessForServer() #endif { InternalResetDataStore(); fMultiThread= fSessionP->getSessionConfig()->fMultiThread; // get comfort pointer } // TStdLogicDS::TStdLogicDS TStdLogicDS::~TStdLogicDS() { InternalResetDataStore(); } // TStdLogicDS::~TStdLogicDS void TStdLogicDS::InternalResetDataStore(void) { // reset fFirstTimeSync=false; fWriteStarted=false; fPreviousSyncTime=0; fCurrentSyncTime=0; #ifdef MULTI_THREAD_DATASTORE // combined ifdef/flag if (fMultiThread) { // make sure background processing aborts if it is in progress fStartSyncThread.terminate(); // request soft termination of thread if (!fStartSyncThread.waitfor()) { // has not already terminated PDEBUGPRINTFX(DBG_HOT,("******** Waiting for background thread to terminate")); fStartSyncThread.waitfor(-1); // wait forever or until thread really terminates PDEBUGPRINTFX(DBG_HOT,("******** Background thread terminated")); } // if } // if #endif // we are not initializing fInitializing=false; // no start init request yet fStartInit=false; if(HAS_SERVER_DB) { #ifdef USES_SERVER_DB // remove all items TSyncItemPContainer::iterator pos; for (pos=fItems.begin(); pos!=fItems.end(); ++pos) { delete *pos; } fItems.clear(); // clear list #endif } if (IS_SERVER) { #ifdef SYSYNC_SERVER fNumRefOnlyItems=0; #endif } } // TStdLogicDS::InternalResetDataStore // Internal events during sync to access local database // ==================================================== // called to make admin data ready localstatus TStdLogicDS::logicMakeAdminReady(cAppCharP aDataStoreURI, cAppCharP aRemoteDBID) { PDEBUGBLOCKFMTCOLL(("MakeAdminReady","Making Admin Data ready to check sync anchors","localDB=%s|remoteDB=%s",aDataStoreURI,aRemoteDBID)); // init local anchor strings, because it will not be set on impl level // (impl level only uses timestamps for local anchor) // These will be derived from timestamps below when implMakeAdminReady() is successful fLastLocalAnchor.erase(); fNextLocalAnchor.erase(); // Updates the following state variables // - from TLocalEngineDS: fLastRemoteAnchor, fLastLocalAnchor, fResumeAlertCode, fFirstTimeSync // - for client: fPendingAddMaps // - for server: fTempGUIDMap // - from TStdLogicDS: fPreviousSyncTime, fCurrentSyncTime // - from derived classes: whatever else belongs to dsSavedAdmin and dsCurrentAdmin state localstatus sta = implMakeAdminReady( fSessionP->getRemoteURI(), // remote device/server URI (device ID) aDataStoreURI, // entire relative URI of local datastore aRemoteDBID // database ID of remote device/server (=path as sent by remote) ); if (sta==LOCERR_OK) { // TStdLogicDS requires implementation to store timestamps to make the local anchors // - regenerate last session's local anchor string from timestamp TimestampToISO8601Str(fLastLocalAnchor,fPreviousSyncTime,TCTX_UTC,false,false); // - create this session's local anchor string from timestamp TimestampToISO8601Str(fNextLocalAnchor,fCurrentSyncTime,TCTX_UTC,false,false); // - check if config has changed since last sync if (fFirstTimeSync || fPreviousSyncTime<=fSessionP->getRootConfig()->fConfigDate) { // remote should see our (probably changed) devInf PDEBUGPRINTFX(DBG_PROTO,("First time sync or config changed since last sync -> remote should see our devinf")); fSessionP->remoteMustSeeDevinf(); } else if (IS_CLIENT && canRestart()) { // When a client can restart, it must tell the server before // asking for the server's DevInf, because restart capability is // negotiated with a SyncMode extension which is only sent by // the server if it has seen the client indicate that it // supports these extensions by sending its own. If the server // somehow didn't store our DevInf, it'll ask for it, but then // it may be too late, so we pro-actively always send it when // restarting is possible. PDEBUGPRINTFX(DBG_PROTO,("Client needs to negotiate restart capability -> remote should see our devinf")); fSessionP->remoteMustSeeDevinf(); } // empty saved anchors if first time sync (should be empty anyway, but...) if (fFirstTimeSync) { fLastLocalAnchor.empty(); fLastRemoteAnchor.empty(); } } PDEBUGENDBLOCK("MakeAdminReady"); return sta; } // TStdLogicDS::logicMakeAdminReady // start writing if not already started localstatus TStdLogicDS::startDataWrite() { localstatus sta = LOCERR_OK; if (!fWriteStarted) { sta = implStartDataWrite(); fWriteStarted = sta==LOCERR_OK; // must be here to prevent recursion as startDataWrite might be called implicitly below if (HAS_SERVER_DB) { #ifdef USES_SERVER_DB // server-type DB needs post-processing to update map entries (client and server case) TSyncItemPContainer::iterator pos; if (sta==LOCERR_OK) { // Now allow post-processing of all reported items for (pos=fItems.begin(); pos!=fItems.end(); ++pos) { localstatus sta2 = implReviewReadItem(**pos); if (sta2!=LOCERR_OK) sta = sta2; } } #endif } if (IS_CLIENT && HAS_SERVER_DB) { #ifdef USES_SERVER_DB /// @todo we don't need the items to remain that long at all - not even for CLIENT_USES_SERVER_DB case fItems.clear(); // empty list #endif } } DEBUGPRINTFX(DBG_DATA,("startDataWrite called, status=%hd", sta)); return sta; } // TStdLogicDS::startDataWrite // end writing localstatus TStdLogicDS::endDataWrite(void) { localstatus sta=LOCERR_OK; DEBUGPRINTFX(DBG_DATA,( "endDataWrite called, write %s started", fWriteStarted ? "is" : "not" )); // if we commit a write, the session is ok, and we can clear the resume state if (fWriteStarted) { sta = implEndDataWrite(); // ended now fWriteStarted=false; } return sta; } // TStdLogicDS::endDataWrite // - read specific item from database // Data and missing ID information is filled in from local database bool TStdLogicDS::logicRetrieveItemByID( TSyncItem &aSyncItem, // item to be filled with data from server. Local or Remote ID must already be set TStatusCommand &aStatusCommand // status, must be set on error or non-200-status ) { // simply call implementation return implRetrieveItemByID(aSyncItem,aStatusCommand); } // TLocalEngineDS::logicRetrieveItemByID /// check is datastore is completely started. /// @param[in] aWait if set, call will not return until either started state is reached /// or cannot be reached within the maximally allowed request processing time left. bool TStdLogicDS::isStarted(bool aWait) { #ifdef SYSYNC_SERVER if (IS_SERVER) { // only server has threaded datastores so far if (aWait && fInitializing) { localstatus sta = startDataAccessForServer(); if (sta!=LOCERR_OK) { SYSYNC_THROW(TSyncException("startDataAccessForServer failed (when called from isStarted)", sta)); } } } #endif // if initialisation could not be completed in the first startDataAccessForServer() call // we are not started. return !fInitializing && inherited::isStarted(aWait); } // TStdLogicDS::isStarted /// called to mark an already generated (but probably not sent or not yet statused) item /// as "to-be-resumed", by localID or remoteID (latter only in server case). /// @note This must be repeatable without side effects, as server must mark/save suspend state /// after every request (and not just at end of session) void TStdLogicDS::logicMarkItemForResume(cAppCharP aLocalID, cAppCharP aRemoteID, bool aUnSent) { implMarkItemForResume(aLocalID, aRemoteID, aUnSent); } // TStdLogicDS::logicMarkItemForResume /// called to mark an already sent item as "to-be-resent", e.g. due to temporary /// error status conditions, by localID or remoteID (latter only in server case). void TStdLogicDS::logicMarkItemForResend(cAppCharP aLocalID, cAppCharP aRemoteID) { implMarkItemForResend(aLocalID, aRemoteID); } // TStdLogicDS::logicMarkItemForResend /// save status information required to possibly perform a resume (as passed to datastore with /// markOnlyUngeneratedForResume(), markItemForResume() and markItemForResend()) /// (or, in case the session is really complete, make sure that no resume state is left) /// @note Must also save tempGUIDs (for server) and pending/unconfirmed maps (for client) localstatus TStdLogicDS::logicSaveResumeMarks(void) { PDEBUGBLOCKFMTCOLL(("SaveResumeMarks","let implementation save resume info","datastore=%s",getName())); localstatus sta = implSaveResumeMarks(); PDEBUGENDBLOCK("SaveResumeMarks"); return sta; } // TStdLogicDS::logicSaveResumeMarks // - called for SyncML 1.1 if remote wants number of changes. // Must return -1 if no NOC value can be returned sInt32 TStdLogicDS::getNumberOfChanges(void) { if (IS_SERVER) { #ifdef SYSYNC_SERVER // for server, number of changes is the number of items in the item list // minus those that are for reference only (in a slow sync resume) return fItems.size()-fNumRefOnlyItems; #endif } else { // for client, derived class must provide it, or we'll return the default here (=no NOC) // Note: for client-only builds, this methods does not exist in StdLogicDS and thus // inherited is always used return inherited::getNumberOfChanges(); } } // TStdLogicDS::getNumberOfChanges #ifdef SYSYNC_SERVER // Server case // =========== // Actual start sync actions in DB. If server supports threaded init, this will // be called in a sub-thread's context localstatus TStdLogicDS::performStartSync(void) { localstatus sta = LOCERR_OK; TP_DEFIDX(li); TP_SWITCH(li,fSessionP->fTPInfo,TP_database); sta = implStartDataRead(); fNumRefOnlyItems=0; if (sta==LOCERR_OK) { // now get data from DB if (!isRefreshOnly() || (isRefreshOnly() && isCacheData()) || (isSlowSync() && isResuming())) { // not only updating from client, so read all items now // Note: for a resumed slow updating from client only, we need the // currently present syncset as well as we need it to detect // re-sent items bool eof; bool changed; PDEBUGBLOCKFMTCOLL(("GetItems","Read items from DB implementation","datastore=%s",getName())); do { // check if external request to terminate loop if (shouldExitStartSync()) { PDEBUGPRINTFX(DBG_ERROR,("performStartSync aborted by external request")); PDEBUGENDBLOCK("GetItems"); TP_START(fSessionP->fTPInfo,li); return 510; } // try to read item TSyncItem *myitemP=NULL; // report all items in syncset, not only changes if we need to filter changed=!fFilteringNeededForAll; // let GetItem // now fetch next item sta = implGetItem(eof,changed,myitemP); if (sta!=LOCERR_OK) { implEndDataRead(); // terminate reading PDEBUGENDBLOCK("GetItems"); TP_START(fSessionP->fTPInfo,li); return sta; } else { // read successful, test for eof if (eof) break; // reading done if (fSlowSync) changed=true; // all have changed (just in case GetItem does not return clean result here) // NOTE: sop can be sop_reference_only ONLY in case of server resuming a slowsync TSyncOperation sop=myitemP->getSyncOp(); // check if we need to do some filtering to determine final syncop // NOTE: call postFetchFiltering even in case we do not actually // need filtering (but we might need making item pass acceptance filter!) if (sop!=sop_delete && sop!=sop_soft_delete && sop!=sop_archive_delete) { // we need to post-fetch filter the item first bool passes=postFetchFiltering(myitemP); if (!passes) { // item was changed and does not pass now -> might be fallen out of the sync set now. // Only when the DB is capable of tracking items fallen out of the sync set (i.e. bring them up as adds // later should they match the filter criteria again), we can implement removing based // on filter criteria. Otherwise, these are simply ignored. if (implTracksSyncopChanges() && !fSlowSync && (sop==sop_wants_replace)) { // item already exists on remote but falls out of syncset now: delete // NOTE: This works only if reviewReadItem() is correctly implemented // and checks for items that are deleted after being reported // as replace to delete their local map entry (which makes // them add candidates again) sop=sop_delete; myitemP->cleardata(); // also get rid of unneeded data } else sop=sop_none; // ignore all others (especially adds or slowsync replaces) } else { // item passes = belongs to sync set if (sop==sop_wants_replace && !changed && !fSlowSync) { // exists but has not changed since last sync sop=sop_none; // ignore for now } } } // check if we should use that item if (sop==sop_none) { delete myitemP; continue; // try next from DB } // set final sop now myitemP->setSyncOp(sop); // %%% these are just-in-case tests for sloppy db interface // - adjust operation for slowsync if (fSlowSync) { if (sop==sop_delete || sop==sop_soft_delete || sop==sop_archive_delete) { // do not process deleted items during slow sync at all delete myitemP; // forget it continue; // Read next item } else { // must be add or replace, will be an add by default (if unmatched) // - set it to sop_wants_add to signal that this item was not matched yet! myitemP->setRemoteID(""); // forget remote ID, is unknown in slow sync anyway if (sop!=sop_reference_only) // if reference only (resumed slowsync), keep it as is myitemP->setSyncOp(sop_wants_add); // flag it unmatched } } // - now add it to my local list fItems.push_back(myitemP); if (sop==sop_reference_only) fNumRefOnlyItems++; // count these to avoid them being shown in NOC } } while (true); // exit by break PDEBUGENDBLOCK("GetItems"); } // not from client only // end reading sta=implEndDataRead(); // show items PDEBUGPRINTFX(DBG_HOT,("%s: number of local items involved in %ssync = %ld",getName(), fSlowSync ? "slow " : "",(long)fItems.size())); CONSOLEPRINTF((" %ld local items are new/changed/deleted for this sync",(long)fItems.size())); if (PDEBUGTEST(DBG_DATA+DBG_DETAILS)) { PDEBUGBLOCKFMTCOLL(("SyncSet","Items involved in Sync","datastore=%s",getName())); for (TSyncItemPContainer::iterator pos=fItems.begin();pos!=fItems.end();pos++) { TSyncItem *syncitemP = (*pos); PDEBUGPRINTFX(DBG_DATA,( "SyncOp=%-20s: LocalID=%15s RemoteID=%15s", SyncOpNames[syncitemP->getSyncOp()], syncitemP->getLocalID(), syncitemP->getRemoteID() )); } PDEBUGENDBLOCK("SyncSet"); } // initiate writing and cause reviewing of items now, // before any of them can be modified by sync process // Notes: // - startDataWrite() includes zapping the sync set // in slow refresh only sessions (not resumed, see next note) // - In case of resumed slow refresh from remote, the sync set // will not get zapped again, because some items are already there if (sta==LOCERR_OK) sta = startDataWrite(); // private helper // test if ok if (sta != LOCERR_OK) { // failed engAbortDataStoreSync(sta,true); return sta; } TP_START(fSessionP->fTPInfo,li); return sta; } // startDataRead successful else { TP_START(fSessionP->fTPInfo,li); return sta; } } // TStdLogicDS::performStartSync #ifdef MULTI_THREAD_DATASTORE // function executed by thread static uInt32 StartSyncThreadFunc(TThreadObject *aThreadObject, uIntArch aParam) { // parameter passed is pointer to datastore TStdLogicDS *datastoreP = static_cast((void *)aParam); // now call routine that actually performs datastore start uInt32 exitCode = (uInt32) (datastoreP->performStartSync()); // thread is about to end (has ended for the Impl and Api levels), inform datastore // and post necessary ThreadMayChangeNow() calls datastoreP->endingThread(); // return return exitCode; } // StartSyncThreadFunc bool TStdLogicDS::threadedStartSync(void) { // do this in a separate thread if requested // Note: ThreadMayChangeNow() has been posted already by startingThread() PDEBUGPRINTFX(DBG_HOT,("******* starting background thread for reading sync set...")); fStartSyncStatus.setStatusCode(200); // assume ok if (!fStartSyncThread.launch(StartSyncThreadFunc,(uIntArch)this)) { // pass datastoreP as param // starting thread failed PDEBUGPRINTFX(DBG_ERROR,("******* Failed starting background thread for reading sync set")); return false; } #ifdef SYDEBUG // show link to thread log PDEBUGPRINTFX(DBG_HOT,( "******* started &html;&html;background thread id=%lu&html;&html; for reading sync set", getDbgLogger()->getDebugFilename(), // href base (long unsigned)fStartSyncThread.getid(), // plus thread getDbgLogger()->getDebugExt(), // plus extension (long unsigned)fStartSyncThread.getid() )); #endif return true; // started ok } // TStdLogicDS::threadedStartSync // can be called to check if performStartSync() should be terminated bool TStdLogicDS::shouldExitStartSync(void) { // threaded version, check if termination flag was set return fMultiThread && fStartSyncThread.terminationRequested(); } // TStdLogicDS::shouldExitStartSync #else // MULTI_THREAD_DATASTORE // can be called to check if performStartSync() should be terminated bool TStdLogicDS::shouldExitStartSync(void) { // nonthread version, is never the case return false; } // TStdLogicDS::shouldExitStartSync #endif // MULTI_THREAD_DATASTORE // called by dsBeforeStateChange to dssta_dataaccessstarted to make sure datastore is // getting ready for being accessed. Also called by isStarted(true) when starting // up took longer than one request max time for threaded datastores localstatus TStdLogicDS::startDataAccessForServer(void) { localstatus sta = LOCERR_OK; DEBUGPRINTFX(DBG_HOT,("TStdLogicDS::startDataAccessForServer")); if (!fInitializing) { // The datastore has not started initializing yet // - start initialisation now fWriteStarted=false; // - read all records from DB right now if server data is used at all DEBUGPRINTFX(DBG_DATA,("- number of items in list before StartDataRead = %ld",(long)fItems.size())); // now we can initialize the conflict resolution mode for this session /// @todo move this to localengineds, at point where we get dssta_syncmodestable fSessionConflictStrategy=getConflictStrategy(fSlowSync,fFirstTimeSync); // prepare for read #ifdef SCRIPT_SUPPORT // - call DB init script, which might add extra filters depending on options and remoterule TScriptContext::execute( fDataStoreScriptContextP, getDSConfig()->fDBInitScript, &DBFuncTable, // context's function table this // datastore pointer needed for context ); // - datastoreinitscript might abort the sync with this datastore, check for that and exit if so if (isAborted()) { return getAbortStatusCode(); } #endif // - init post fetch filtering, sets fFilteringNeededForAll and fFilteringNeeded correctly initPostFetchFiltering(); // - now we can start reading (fFilteringNeededForAll can be checked by StartDataRead) fInitializing=true; // we enter the initialisation phase now fStartInit=true; // and we want to start the init } // try starting init now (possibly repeats until it can be done) if (fStartInit) { PDEBUGPRINTFX(DBG_DATA,( "MultiThread %sabled", fMultiThread ? "en":"dis" )); #ifdef MULTI_THREAD_DATASTORE // combined define and flag if (fMultiThread) { // start init thread if (startingThread()) { // we may start a thread here if (threadedStartSync()) fStartInit= false; // starting done now } // if } // if #endif if (!fMultiThread) { // Just perform initialisation sta = performStartSync(); fStartInit=false; // starting done now fInitializing=false; // initialisation is already complete here } // if } #ifdef MULTI_THREAD_DATASTORE // combined define and flag if (fMultiThread) { // wait for started initialisation to finish within time we have left for this request if (!fStartInit && fInitializing) { // initialisation started but not ended so far: wait for it until done or defined request time passed sInt32 t=fSessionP->RemainingRequestTime(); if (fStartSyncThread.waitfor(t<0 ? 0 : t * 1000)) { // background thread has terminated sta = fStartSyncThread.exitcode(); PDEBUGPRINTFX(DBG_HOT,("******* background thread for startSync() terminated with exit code=%ld, status sta=%hd", (long)fStartSyncThread.exitcode(),sta)); // initialisation is now complete fInitializing=false; } // if } // if } // if #endif // now complete initialisation if not still initializing in background if (!fStartInit && !fInitializing) { // finished background processing if (sta==LOCERR_OK) { // quick test: if number of items is > than allowed maxid of remote datatstore, // sync is unlikely to succeed if (getRemoteDatastore()->getMaxID()<(long)fItems.size()) { // this will not work, warn (but no longer abort session, as Siemens S55 guys don't like that) CONSOLEPRINTF(( "Warning: Synchronisation involves more items (%ld) than client can possibly manage (%ld", (long)fItems.size(), (long)getRemoteDatastore()->getMaxID() )); PDEBUGPRINTFX(DBG_ERROR,( "Warning: Synchronisation involves more items (%ld) than client can possibly manage (%ld)", (long)fItems.size(), (long)getRemoteDatastore()->getMaxID() )); } } // return status of initialisation return sta; } else { // background processing still in progress // - if we are still processing in background, init is ok so far return LOCERR_OK; } } // TStdLogicDS::startDataAccessForServer // called to check if conflicting replace or delete command from server exists TSyncItem *TStdLogicDS::getConflictingItemByRemoteID(TSyncItem *syncitemP) { // search for conflicting item by remoteID TSyncItemPContainer::iterator pos; for (pos=fItems.begin(); pos!=fItems.end(); ++pos) { if (strcmp((*pos)->getRemoteID(),syncitemP->getRemoteID())==0) { // same LUID exists in data from server PDEBUGPRINTFX(DBG_DATA+DBG_CONFLICT,( "TStdLogicDS::getConflictingItemByRemoteID, found RemoteID='%s', LocalID='%s', syncop=%s", syncitemP->getRemoteID(), syncitemP->getLocalID(), SyncOpNames[syncitemP->getSyncOp()] )); return (*pos); // return pointer to item in question } } PDEBUGPRINTFX(DBG_DATA+DBG_CONFLICT,("TStdLogicDS::getConflictingItemByRemoteID, no conflicting item")); return NULL; } // TStdLogicDS::getConflictingItemByRemoteID // called to check if conflicting item (with same localID) already exists in the list of items // to be sent to the server TSyncItem *TStdLogicDS::getConflictingItemByLocalID(TSyncItem *syncitemP) { // search for conflicting item by localID TSyncItemPContainer::iterator pos; for (pos=fItems.begin(); pos!=fItems.end(); ++pos) { if (strcmp((*pos)->getLocalID(),syncitemP->getLocalID())==0) { // same LUID exists in data from server PDEBUGPRINTFX(DBG_DATA+DBG_CONFLICT,( "TStdLogicDS::getConflictingItemByLocalID, found RemoteID='%s', LocalID='%s', syncop=%s", syncitemP->getRemoteID(), syncitemP->getLocalID(), SyncOpNames[syncitemP->getSyncOp()] )); return (*pos); // return pointer to item in question } } PDEBUGPRINTFX(DBG_DATA+DBG_CONFLICT,("TStdLogicDS::getConflictingItemByLocalID, no conflicting item")); return NULL; } // TStdLogicDS::getConflictingItemByLocalID // called to check if content-matching item from server exists for slow sync TSyncItem *TStdLogicDS::getMatchingItem(TSyncItem *syncitemP, TEqualityMode aEqMode) { // search for content matching item TSyncItemPContainer::iterator pos; for (pos=fItems.begin(); pos!=fItems.end(); ++pos) { DEBUGPRINTFX(DBG_DATA+DBG_MATCH+DBG_EXOTIC,( "comparing (this) local item localID='%s' with incoming (other) item remoteID='%s'", (*pos)->getLocalID(), syncitemP->getRemoteID() )); if ((*pos)->compareWith( *syncitemP,aEqMode,this #ifdef SYDEBUG ,PDEBUGTEST(DBG_DATA+DBG_MATCH+DBG_EXOTIC) // only show comparison if exotic AND match is enabled #endif )==0) { // items match in content // - check if item is not already matched if ((*pos)->getSyncOp()!=sop_wants_add && (*pos)->getSyncOp()!=sop_reference_only) { // item has already been matched before, so don't match it again DEBUGPRINTFX(DBG_DATA,( "TStdLogicDS::getMatchingItem, match but already used -> skip it: remoteID='%s' = localID='%s'", syncitemP->getRemoteID(), (*pos)->getLocalID() )); } else { // item has not been matched yet (wannabe add or reference-only), return it now PDEBUGPRINTFX(DBG_DATA+DBG_MATCH+DBG_HOT,( "TStdLogicDS::getMatchingItem, found remoteID='%s' is equal in content with localID='%s'", syncitemP->getRemoteID(), (*pos)->getLocalID() )); return (*pos); // return pointer to item in question } } } PDEBUGPRINTFX(DBG_DATA+DBG_MATCH,("TStdLogicDS::getMatchingItem, no matching item")); return NULL; } // TStdLogicDS::getMatchingItem // - called to prevent item to be sent to client in subsequent generateSyncCommands() // item in question should be an item that was returned by getConflictingItemByRemoteID() or getMatchingItem() void TStdLogicDS::dontSendItemAsServer(TSyncItem *syncitemP) { PDEBUGPRINTFX(DBG_DATA+DBG_EXOTIC,("Preventing localID='%s' to be sent to client",syncitemP->getLocalID())); syncitemP->setSyncOp(sop_none); // anyway, set to none // delete from list as we don't need it any more TSyncItemPContainer::iterator pos; for (pos=fItems.begin(); pos!=fItems.end(); ++pos) { if (*pos == syncitemP) { // it is in our list PDEBUGPRINTFX(DBG_DATA+DBG_HOT,("Item with localID='%s' will NOT be sent to client (slowsync match / duplicate prevention)",syncitemP->getLocalID())); delete *pos; // delete item itself fItems.erase(pos); // remove from list break; } } } // TStdLogicDS::dontSendItemAsServer // - called when a item in the sync set changes its localID (due to local DB internals) // Datastore must make sure that possibly cached items get updated // - NOTE: derivates must take care of updating map entries as well! void TStdLogicDS::dsLocalIdHasChanged(const char *aOldID, const char *aNewID) { PDEBUGPRINTFX(DBG_DATA,("TStdLogicDS::dsLocalIdHasChanged")); // update in loaded list of items TSyncItemPContainer::iterator pos; for (pos=fItems.begin(); pos!=fItems.end(); ++pos) { if (strcmp((*pos)->getLocalID(),aOldID)==0) { // found item, change it's local ID now (*pos)->setLocalID(aNewID); // make sure internal dependencies get updated (*pos)->updateLocalIDDependencies(); // done break; } } // let base class do what is needed to update the item itself inherited::dsLocalIdHasChanged(aOldID, aNewID); } // TStdLogicDS::dsLocalIdHasChanged // - called to have additional item sent to remote void TStdLogicDS::SendItemAsServer(TSyncItem *aSyncitemP) { // add to list of changes fItems.push_back(aSyncitemP); } // TStdLogicDS::SendItemAsServer // - end map operation (derived class might want to rollback) bool TStdLogicDS::MapFinishAsServer( bool aDoCommit, // if not set, entire map operation must be undone TStatusCommand &aStatusCommand // status, must be set on error or non-200-status ) { // unsuccessful Map will cause rollback of entire datastore transaction if (!aDoCommit) { // bad, abort session engAbortDataStoreSync(510,true); // data store failed, local problem } return true; } // TStdLogicDS::MapFinishAsServer // - called to let server generate sync commands for client // Returns true if now finished (or aborted) for this datastore // also sets fState to dss_syncdone when finished bool TStdLogicDS::logicGenerateSyncCommandsAsServer( TSmlCommandPContainer &aNextMessageCommands, TSmlCommand * &aInterruptedCommandP, cAppCharP aLocalIDPrefix ) { bool alldone=false; bool ignoreitem; uInt32 itemcount=0; // send as many as possible from list of local modifications // sop_want_replace can only be sent if state is already dss_syncfinish TSyncItemPContainer::iterator pos; pos = fItems.begin(); // first item TSyncItemType *itemtypeP = getRemoteReceiveType(); POINTERTEST(itemtypeP,("TStdLogicDS::logicGenerateSyncCommandsAsServer: fRemoteReceiveFromLocalTypeP undefined")); #ifdef SYDEBUG if (fMaxItemCount> 0) { PDEBUGPRINTFX(DBG_DATA+DBG_HOT,( "Info: Max number of items to be sent in this session is limited to %ld (already sent by now=%ld)", (long)fMaxItemCount, (long)fItemsSent )); } #endif while ( !isAborted() && // not aborted (getDSConfig()->fMaxItemsPerMessage==0 || itemcountfMaxItemsPerMessage) && // max item count per message not reached or not active !fSessionP->outgoingMessageFull() && // message not full aNextMessageCommands.size()==0 // no commands already queued for next message ) { // get item to process if (pos == fItems.end()) { alldone=true; break; } // TSyncItem *syncitemP = (*pos); // get sync op to perform TSyncOperation syncop=syncitemP->getSyncOp(); // check if we can send the item now (for replaces, we need ALWAYS to wait until client has finished sending) // Note: usually sync engine will not start generating before dssta_serverseenclientmods anyway, but... if (syncop==sop_wants_replace && !testState(dssta_serverseenclientmods)) { // cannot be sent now, take next pos++; continue; } // check if we should ignore this item ignoreitem = syncop==sop_reference_only; // ignore anyway if reference only // further check if not already ignored if (!ignoreitem) { // - check if adding is still allowed if (fRemoteAddingStopped && (syncop==sop_wants_add || syncop==sop_add)) { // adding to remote has been stopped, discard add items PDEBUGPRINTFX(DBG_DATA,( "Suppressed add for item localID='%s' (fRemoteAddingStopped)", syncitemP->getLocalID() )); ignoreitem=true; } #ifdef SYNCML_TAF_SUPPORT // check other reasons to prevent further adds if (syncop==sop_wants_add || syncop==sop_add) { // - check if max number of items has already been reached if (fMaxItemCount!=0 && fItemsSent>=fMaxItemCount) { PDEBUGPRINTFX(DBG_DATA,( "Suppressed add for item localID='%s' (max item count=%ld reached)", syncitemP->getLocalID(), fMaxItemCount )); ignoreitem=true; } // - check if item passes possible TAF /// %%% (do not filter replaces, as these would not get reported again in the next session) /// @todo: the above is no longer true as we can now have them re-sent in next session, /// so this must be changed later!!! if (!( syncitemP->testFilter(fTargetAddressFilter.c_str()) && syncitemP->testFilter(fIntTargetAddressFilter.c_str()) )) { PDEBUGPRINTFX(DBG_DATA+DBG_HOT,( "Item localID='%s' does not pass INCLUSIVE filter (TAF) -> Suppressed adding", syncitemP->getLocalID() )); ignoreitem=true; } } #endif } // Now discard if ignored if (ignoreitem) { // remove item from list TSyncItemPContainer::iterator temp_pos = pos++; // make copy and set iterator to next fItems.erase(temp_pos); // now entry can be deleted (N.M. Josuttis, pg204) // delete item itself delete syncitemP; // test next continue; } // create sync op command (may return NULL in case command cannot be created, e.g. for MaxObjSize limitations) TSyncOpCommand *syncopcmdP = newSyncOpCommand(syncitemP,itemtypeP,aLocalIDPrefix); // erase item from list delete syncitemP; pos = fItems.erase(pos); // issue command now // - Note that when command is split, issuePtr returns true, but we still may NOT generate new commands // as the message is already full now. That's why the while contains a check for message full and aNextMessageCommands size // (was not the case before 2.1.0.2, which could cause that the first chunk of a subsequent command // would be sent before the third..nth chunk of the previous command). TSmlCommand *cmdP = syncopcmdP; syncopcmdP=NULL; // possibly, we have a NULL command here (e.g. in case it could not be generated due to MaxObjSize restrictions) if (cmdP) { // We pass the command to the issue mechanism - last chance to count is here. // Note: the command might be queued and actually sent in a subsequent message. fItemsSent++; // overall counter for statistics itemcount++; // per message counter DB_PROGRESS_EVENT(this,pev_itemsent,fItemsSent,getNumberOfChanges(),0); // send event (but no check for abort) // now issue if (!fSessionP->issuePtr(cmdP,aNextMessageCommands,aInterruptedCommandP)) { alldone=false; // issue failed (no room in message), not finished so far break; // stop trying to issue more commands } } }; // while not aborted and not message full // we are not done until all aNextMessageCommands are also out // Note: this must be specially checked because we now have SyncML 1.1 chunked commands. // Those issue() fine, but leave a next chunk in the aNextMessageCommands queue. if (alldone && aNextMessageCommands.size()>0) { alldone=false; } // finished when we have done all return (alldone || isAborted()); } // TStdLogicDS::logicGenerateSyncCommandsAsServer // called for servers when receiving map from client localstatus TStdLogicDS::logicProcessMap(cAppCharP aRemoteID, cAppCharP aLocalID) { // simply call implementation return implProcessMap(aRemoteID, aLocalID); } // TStdLogicDS::logicProcessMap #endif // SYSYNC_SERVER #ifdef SYSYNC_CLIENT // Client Case // =========== // called by dsBeforeStateChange to dssta_dataaccessstarted to make sure datastore is ready for being accessed. localstatus TStdLogicDS::startDataAccessForClient(void) { DEBUGPRINTFX(DBG_HOT,("TStdLogicDS::startDataAccessForClient")); // init fWriteStarted=false; fEoC=false; // not all changes seen yet // prepare for read #ifdef SCRIPT_SUPPORT // - call DB init script, which might add extra filters depending on options and remoterule TScriptContext::execute( fDataStoreScriptContextP, getDSConfig()->fDBInitScript, &DBFuncTable, // context's function table this // datastore pointer needed for context ); // - datastoreinitscript might abort the sync with this datastore, check for that and exit if so if (isAborted()) { return getAbortStatusCode(); } #endif // - init post fetch filtering, sets fFilteringNeededForAll and fFilteringNeeded correctly initPostFetchFiltering(); // - prepare for read localstatus sta=implStartDataRead(); return sta; } // TStdLogicDS::startDataAccessForClient // called to generate sync sub-commands as client for remote server // @return true if now finished for this datastore bool TStdLogicDS::logicGenerateSyncCommandsAsClient( TSmlCommandPContainer &aNextMessageCommands, TSmlCommand * &aInterruptedCommandP, cAppCharP aLocalIDPrefix ) { localstatus sta = LOCERR_OK; bool alldone=true; // send as many changed items as possible TSyncItemType *itemtypeP = getRemoteReceiveType(); POINTERTEST(itemtypeP,("TStdLogicDS::logicGenerateSyncCommandsAsClient: fRemoteReceiveFromLocalTypeP undefined")); while (!fEoC && !isAborted() && !fSessionP->outgoingMessageFull() && aNextMessageCommands.size()==0) { // get next item from DB TSyncItem *syncitemP = NULL; #ifdef OBJECT_FILTERING bool changed=!fFilteringNeededForAll; // set if we need all records for later filtering #else bool changed=true; // without filters, always let DB check if modified #endif sta = implGetItem(fEoC,changed,syncitemP); if (sta!=LOCERR_OK) { // fatal error implEndDataRead(); // terminate reading (error does not matter) engAbortDataStoreSync(sta, true); // local problem return false; // not complete } // read successful, test for EoC (end of changes) if (fEoC) break; // reading done if (fSlowSync) changed=true; // all have changed (just in case GetItem does not return clean result here) // get sync op to perform TSyncOperation syncop=syncitemP->getSyncOp(); if (syncop!=sop_delete && syncop!=sop_soft_delete && syncop!=sop_archive_delete) { #ifdef OBJECT_FILTERING // Filtering // - call this anyway (makes sure item is made conformant to remoteAccept filter, even if // fFilteringNeeded is not set) bool passes=postFetchFiltering(syncitemP); if (fFilteringNeeded && !passes) { // item was changed and does not pass now -> might be fallen out of the sync set now. // Only when the DB is capable of tracking items fallen out of the sync set (i.e. bring them up as adds // later should they match the filter criteria again), we can implement removing based // on filter criteria. Otherwise, these are simply ignored. if (implTracksSyncopChanges() && !fSlowSync && changed && (syncop==sop_replace || syncop==sop_wants_replace)) { // item already exists on remote but falls out of syncset now: delete // NOTE: This works only if reviewReadItem() is correctly implemented // and checks for items that are deleted after being reported // as replace to delete their local map entry (which makes // them add candidates again) syncop = sop_delete; syncitemP->cleardata(); // also get rid of unneeded data } else syncop = sop_none; // ignore all others (especially adds or slowsync replaces) } else #endif { // item passes (or no filters anyway) -> belongs to sync set if ((syncop==sop_replace || syncop==sop_wants_replace) && !changed && !fSlowSync) { // exists but has not changed since last sync syncop=sop_none; // ignore for now } } } // check if we should use that item if (syncop==sop_none) { delete syncitemP; continue; // try next from DB } // set final syncop now syncitemP->setSyncOp(syncop); // create sync op command TSyncOpCommand *syncopcmdP = newSyncOpCommand(syncitemP,itemtypeP,aLocalIDPrefix); #ifdef CLIENT_USES_SERVER_DB // save item, we need it later for post-processing and Map simulation fItems.push_back(syncitemP); #else // delete item, not used any more delete syncitemP; #endif // issue command now // - Note that when command is split, issuePtr returns true, but we still may NOT generate new commands // as the message is already full now. That's why the while contains a check for message full and aNextMessageCommands size // (was not the case before 2.1.0.2, which could cause that the first chunk of a subsequent command // would be sent before the third..nth chunk of the previous command). TSmlCommand *cmdP = syncopcmdP; syncopcmdP=NULL; // possibly, we have a NULL command here (e.g. in case it could not be generated due to MaxObjSize restrictions) if (cmdP) { // We pass the command to the issue mechanism - last chance to count is here. // Note: the command might be queued and actually sent in a subsequent message. fItemsSent++; #ifdef PROGRESS_EVENTS // send progress event and check for abort if (!DB_PROGRESS_EVENT(this,pev_itemsent,fItemsSent,getNumberOfChanges(),0)) { implEndDataRead(); // terminate reading fSessionP->AbortSession(500,true,LOCERR_USERABORT); return false; // error } #endif // issue now if (!fSessionP->issuePtr(cmdP,aNextMessageCommands,aInterruptedCommandP)) { alldone=false; // issue failed (no room in message), not finished so far break; } #ifdef PROGRESS_EVENTS // check for "soft" suspension if (!SESSION_PROGRESS_EVENT(fSessionP,pev_suspendcheck,NULL,0,0,0)) { fSessionP->SuspendSession(LOCERR_USERSUSPEND); } #endif } }; // while not aborted // we are not done until all aNextMessageCommands are also out // Note: this must be specially checked because we now have SyncML 1.1 chunked commands. // Those issue() fine, but leave a next chunk in the aNextMessageCommands queue. if (alldone && aNextMessageCommands.size()>0) { alldone=false; } // done if we are now ready for sync or if aborted return ((alldone && fEoC) || isAborted()); } // TStdLogicDS::logicGenerateSyncCommandsAsClient #endif // SYSYNC_CLIENT /// @brief called to have all not-yet-generated sync commands as "to-be-resumed" void TStdLogicDS::logicMarkOnlyUngeneratedForResume(void) { if (IS_SERVER) { #ifdef SYSYNC_SERVER // we do not maintain the map/bookmark list at this level, so // derived class (ODBC, BinFile etc.) must make sure that their list is // clean (no marks from previous sessions) before calling this inherited version implMarkOnlyUngeneratedForResume(); // Now add those that we have already received from the implementation TSyncItemPContainer::iterator pos; for (pos = fItems.begin(); pos != fItems.end(); ++pos) { // let datastore mark these unprocessed TSyncItem *syncitemP = (*pos); // mark it for resume by ID logicMarkItemForResume(syncitemP->getLocalID(),syncitemP->getRemoteID(),true); // these are unsent } #endif // SYSYNC_SERVER } else { #ifdef SYSYNC_CLIENT // we do not maintain the map/bookmark list at this level, so // derived class (ODBC, BinFile etc.) must make sure that their list is // clean (no marks from previous sessions) before calling this inherited version implMarkOnlyUngeneratedForResume(); // in client case, fItems does not contain ungenerated/unprocessed items // so we don't have anything more do here for now #endif // SYSYNC_CLIENT } } // TStdLogicDS::logicMarkOnlyUngeneratedForResume /// helper to merge database version of an item with the passed version of the same item; /// does age comparison by default, with "local side wins" as fallback TMultiFieldItem *TStdLogicDS::mergeWithDatabaseVersion(TSyncItem *aSyncItemP, bool &aChangedDBVersion, bool &aChangedNewVersion) { aChangedDBVersion = false; aChangedNewVersion = false; TStatusCommand dummy(fSessionP); TMultiFieldItem *dbVersionItemP = (TMultiFieldItem *)newItemForRemote(aSyncItemP->getTypeID()); if (!dbVersionItemP) return NULL; // - set IDs dbVersionItemP->setLocalID(aSyncItemP->getLocalID()); dbVersionItemP->setRemoteID(aSyncItemP->getRemoteID()); // - result is always a replace (item exists in DB) dbVersionItemP->setSyncOp(sop_wants_replace); // - try to get from DB bool ok=logicRetrieveItemByID(*dbVersionItemP,dummy); if (ok && dummy.getStatusCode()!=404) { // item found in DB, merge with original item // TODO (?): make this configurable TConflictResolution crstrategy = cr_newer_wins; if (crstrategy==cr_newer_wins) { sInt16 cmpRes = aSyncItemP->compareWith( *dbVersionItemP, eqm_nocompare,this #ifdef SYDEBUG ,PDEBUGTEST(DBG_CONFLICT+DBG_DETAILS) // show age comparisons only if we want to see details #endif ); if (cmpRes==-1) crstrategy=cr_server_wins; else crstrategy=cr_client_wins; PDEBUGPRINTFX(DBG_DATA,( "Newer item determined: %s", crstrategy==cr_client_wins ? "Incoming item is newer and wins" : "DB item is newer and wins" )); if (crstrategy==cr_client_wins) { aSyncItemP->mergeWith(*dbVersionItemP, aChangedNewVersion, aChangedDBVersion, this); } else { dbVersionItemP->mergeWith(*aSyncItemP, aChangedDBVersion, aChangedNewVersion, this); } PDEBUGPRINTFX(DBG_DATA,( "Merged incoming item (%s,relevant,%smodified) with version from database (%s,%s,%smodified)", crstrategy==cr_client_wins ? "winning" : "loosing", aChangedNewVersion ? "" : "NOT ", crstrategy==cr_server_wins ? "winning" : "loosing", aChangedDBVersion ? "to-be-replaced" : "to-be-left-unchanged", aChangedDBVersion ? "" : "NOT " )); } } else { // no item found, we cannot force a conflict PDEBUGPRINTFX(DBG_ERROR,("Could not retrieve database version of item, DB status code = %hd",dummy.getStatusCode())); delete dbVersionItemP; dbVersionItemP=NULL; return NULL; } return dbVersionItemP; } // TStdLogicDS::mergeWithDatabaseVersion enum LogicItemOp { LOGIC_ITEM_WRITE, LOGIC_ITEM_REPLACE_FALLBACK, LOGIC_ITEM_ADD_FALLBACK }; struct TLogicSyncItemAux : public TSyncItemAux { bool fIrregular; bool fShouldBeVisible; bool fVisibleInSyncset; TSyncItem *fSyncItemP; LogicItemOp fOp; }; // called to process incoming item operation // Method takes ownership of syncitemP in all cases bool TStdLogicDS::logicProcessRemoteItem( TSyncItem *syncitemP, TStatusCommand &aStatusCommand, bool &aVisibleInSyncset, // on entry: tells if resulting item SHOULD be visible; on exit: set if processed item remains visible in the sync set. string *aGUID // GUID is stored here if not NULL ) { localstatus sta=LOCERR_OK; bool irregular=false; bool shouldbevisible=aVisibleInSyncset; string datatext; LogicItemOp op; // Must be kept alive for the duration of the entire call, // in case that we need to resume. TSyncItem *origSyncItemP=syncitemP; TP_DEFIDX(li); TP_SWITCH(li,fSessionP->fTPInfo,TP_database); SYSYNC_TRY { // assume item will stay visible in the syncset after processing aVisibleInSyncset=true; // start writing if not already started sta=startDataWrite(); if (sta!=LOCERR_OK) { aStatusCommand.setStatusCode(sta); } else { TLogicSyncItemAux *aux = static_cast(origSyncItemP->getAux(TSyncItem::STD_LOGIC_DS)); // show DEBUGPRINTFX(DBG_DATA,( "TStdLogicDS::logicProcessRemoteItem %p %s, SyncOp=%s, RemoteID='%s', LocalID='%s'", origSyncItemP, aux ? "resuming" : "starting", SyncOpNames[origSyncItemP->getSyncOp()], origSyncItemP->getRemoteID(), origSyncItemP->getLocalID() )); // Same approach as in TLocalEngineDS::engProcessRemoteItemAsServer(): // jump directly to the point where we left the last time we where // called for this item. if (aux) { irregular = aux->fIrregular; shouldbevisible = aux->fShouldBeVisible; aVisibleInSyncset = aux->fVisibleInSyncset; syncitemP = aux->fSyncItemP; op = aux->fOp; switch (op) { case LOGIC_ITEM_WRITE: goto do_write; case LOGIC_ITEM_REPLACE_FALLBACK: goto do_replace_fallback; case LOGIC_ITEM_ADD_FALLBACK: goto do_add_fallback; } } if (false) { again: #define CHECK_FOR_AGAIN(_op) \ if (aStatusCommand.getStatusCode() == LOCERR_AGAIN) { \ op = _op; \ goto again; \ } if (!aux) { aux = new TLogicSyncItemAux; origSyncItemP->setAux(TSyncItem::STD_LOGIC_DS, aux); } aux->fIrregular = irregular; aux->fShouldBeVisible = shouldbevisible; aux->fVisibleInSyncset = aVisibleInSyncset; aux->fSyncItemP = syncitemP; aux->fOp = op; aStatusCommand.setStatusCode(LOCERR_AGAIN); return false; } // now perform action if (syncitemP->getSyncOp()==sop_replace || syncitemP->getSyncOp()==sop_wants_replace) { // check if we should read before writing TMultiFieldItem *mfiP; GET_CASTED_PTR(mfiP,TMultiFieldItem,syncitemP,""); bool replacewritesallfields = dsReplaceWritesAllDBFields(); bool mightcontaincutoff=false; // - see if we would pass sync set filter as is #ifdef OBJECT_FILTERING aVisibleInSyncset = mfiP->testFilter(fSyncSetFilter.c_str()); bool invisible = !getDSConfig()->fInvisibleFilter.empty() && // has an invisible filter mfiP->testFilter(getDSConfig()->fInvisibleFilter.c_str()); // and passes it -> invisible bool visibilityok = (aVisibleInSyncset && !invisible) == shouldbevisible; // check if visibility is correct if (visibilityok && !replacewritesallfields && aVisibleInSyncset) // avoid expensive check if we have to read anyway #endif mightcontaincutoff = mfiP->getItemType()->mayContainCutOffData(mfiP->getTargetItemType()); // - if not, we must read item from the DB first and then // test again. if ( #ifdef OBJECT_FILTERING !visibilityok || #endif replacewritesallfields || mightcontaincutoff || fIgnoreUpdate // if we may not update items, only add them, then we must check first if item exists in DB ) { // the item we are replacing might contain cut-off data or // needs otherwise to be modified based on current contents // we should therefore read item from DB first // - create new empty TMultiFieldItem TMultiFieldItem *refitemP = (TMultiFieldItem *) newItemForRemote(ity_multifield); if (IS_CLIENT) { // Client: retrieve by local ID refitemP->clearRemoteID(); // not known refitemP->setLocalID(syncitemP->getLocalID()); // make sure we retrieve by local ID } else { // Server: retrieve by remote ID refitemP->clearLocalID(); // make sure we retrieve by remote ID refitemP->setRemoteID(syncitemP->getRemoteID()); // make sure we retrieve by remote ID } refitemP->setSyncOp(sop_replace); #ifdef OBJECT_FILTERING PDEBUGPRINTFX(DBG_DATA,( "TStdLogicDS: Need read-modify-write (cause: %s%s%s%s) -> retrieve original item from DB", !visibilityok ? "visibility_not_ok " : "", replacewritesallfields ? "replace_writes_all_fields " : "", mightcontaincutoff ? "might_contain_cutoff_data " : "", fIgnoreUpdate ? "ignoreUpdate " : "" )); #else PDEBUGPRINTFX(DBG_DATA,( "TStdLogicDS: Need read-modify-write (cause: %s%s%s) -> retrieve original item from DB", replacewritesallfields ? "replace_writes_all_fields " : "", mightcontaincutoff ? "might_contain_cutoff_data " : "", fIgnoreUpdate ? "ignoreUpdate " : "" )); #endif if (implRetrieveItemByID(*refitemP,aStatusCommand)) { #ifdef SYDEBUG if (PDEBUGTEST(DBG_DATA)) { PDEBUGPRINTFX(DBG_DATA,("TStdLogicDS: Retrieved item")); if (PDEBUGTEST(DBG_DATA+DBG_DETAILS)) refitemP->debugShowItem(); // show item retrieved } #endif if (fIgnoreUpdate) { // updates may not be executed at all, and be simply ignored aStatusCommand.setStatusCode(200); // fake ok. PDEBUGPRINTFX(DBG_DATA+DBG_HOT,("TStdLogicDS: fIgnoreUpdate set, update command not executed but answered with status 200")); irregular=true; sta=LOCERR_OK; goto processed; } // we got the item to be replaced // - now modify it: // - only modify available fields // - perform cutoff prevention // - do not just copy assigned fields (but all those that are available) // - IF replace can write individual fields, then transfer unassigned status // (also for non-availables!) to avoid that datastore needs to write back // values that are already there. refitemP->replaceDataFrom(*syncitemP,true,true,false,!replacewritesallfields); #ifdef SYDEBUG if (PDEBUGTEST(DBG_DATA)) { PDEBUGPRINTFX(DBG_DATA,("TStdLogicDS: Item updated with contents from remote")); if (PDEBUGTEST(DBG_DATA+DBG_EXOTIC)) refitemP->debugShowItem(); // show item retrieved } #endif #ifdef OBJECT_FILTERING // - make sure item will pass sync set filter NOW makePassSyncSetFilter(refitemP); // - make sure item will be visible NOW makeVisible(refitemP); #ifdef SYDEBUG if (PDEBUGTEST(DBG_DATA)) { PDEBUGPRINTFX(DBG_DATA,("TStdLogicDS: Made visible and pass sync set filter")); if (PDEBUGTEST(DBG_DATA+DBG_EXOTIC)) refitemP->debugShowItem(); // show item retrieved } #endif #endif // - use new item for further processing syncitemP=refitemP; } else { // failed retrieving item: switch to add sta = aStatusCommand.getStatusCode(); if (sta==404 || sta==410) { // this is an irregularity for a client (but it's perfectly // normal case for server, as client may use replace for adds+replaces) if (IS_CLIENT && !syncitemP->hasRemoteID()) { // - we cannot handle this properly, we have no remoteID, so report error to server PDEBUGPRINTFX(DBG_ERROR,("TStdLogicDS: Item not found, but cannot switch to add because no RemoteID is known, Status=%hd",aStatusCommand.getStatusCode())); } else { if (fPreventAdd) { // prevent implicit add -> return sta as is } else { // - switch to add if remote sent remoteID along so we can properly map syncitemP->setSyncOp(sop_add); PDEBUGPRINTFX(DBG_DATA,("TStdLogicDS: RetrieveItem: not found (Status=%hd) --> adding instead",sta)); if (IS_SERVER) { #ifdef SYSYNC_SERVER // server: make sure we delete the old item from the map table (as we *know* the item is gone - should it reappear under a different localID, it'll be re-added) implProcessMap(syncitemP->getRemoteID(),NULL); #endif } else { // client: we can handle it, as we know the remoteID irregular=true; // irregular only for client } sta=LOCERR_OK; // ok for further processing, anyway } } } else { // this is a fatal error, report it PDEBUGPRINTFX(DBG_ERROR,("TStdLogicDS: RetrieveItem failed, Status=%hd",sta)); } // get rid of reference item delete refitemP; } } } if (sta==LOCERR_OK) { // make sure that added items will pass sync set filters. If we can't make them pass // for DS 1.2 exclusive filters we must generate a delete so we must remember the itempassed status) #ifdef OBJECT_FILTERING if (syncitemP->getSyncOp()==sop_add || syncitemP->getSyncOp()==sop_wants_add) { // - make sure new item will pass sync set filter when re-read from DB aVisibleInSyncset=makePassSyncSetFilter(syncitemP); // - also make sure new item has correct visibility status if (shouldbevisible) makeVisible(syncitemP); // make visible else aVisibleInSyncset = !makeInvisible(syncitemP); // make invisible } #endif // Now let derived class process the item do_write: if (!implProcessItem(syncitemP,aStatusCommand)) sta = aStatusCommand.getStatusCode(); // not successful, get error status code CHECK_FOR_AGAIN(LOGIC_ITEM_WRITE); } // perform special case handling if (sta!=LOCERR_OK) { // irregular, special case handling switch (syncitemP->getSyncOp()) { case sop_wants_add : // to make sure case sop_add : if (sta==418) { // 418: item already exists, this is kind of a conflict if (isResuming() || fIgnoreUpdate || IS_CLIENT) { // - in a client, this should not happen (prevented via checking against pending maps before // this routine is called) - if it still does just report the status back // - in a resume, this can happen and the add should be ignored (se we return the status 418) // - if updates are to be ignored, don't try update instead (and report 418) // --> just return the status as-is } else { // in normal sync in the server case, this can happen when a previous session // was aborted (and already applied adds not rolled back) // --> reprocess it as a replace PDEBUGPRINTFX(DBG_DATA,("to-be-added item already exists -> trying replace (=conflict resolved by client winning)")); // - switch to replace syncitemP->setSyncOp(sop_replace); irregular=true; // - process again do_replace_fallback: if (implProcessItem(syncitemP,aStatusCommand)) { aStatusCommand.setStatusCode(208); // client has won } else { CHECK_FOR_AGAIN(LOGIC_ITEM_REPLACE_FALLBACK); // failed, return status sta = aStatusCommand.getStatusCode(); } } } break; case sop_replace : if (sta==404 || sta==410) { // this is an irregularity for a client (but it's perfectly // normal case for server, as client may use replace for adds+replaces) if (IS_CLIENT && !syncitemP->hasRemoteID()) { // - we cannot handle this properly, we have no remoteID, so report error to server PDEBUGPRINTFX(DBG_ERROR,("to-be-replaced item not found, but cannot switch to add because no RemoteID is known, Status=%hd",sta)); } else { if (fPreventAdd) { // prevent implicit add -> return status as is } else { // - switch to add if remote sent remoteID along so we can properly map syncitemP->setSyncOp(sop_add); if (IS_SERVER) { #ifdef SYSYNC_SERVER // - make sure we delete the old item from the map table (as we *know* the item is gone - should it reappear under a different localID, it'll be re-added) implProcessMap(syncitemP->getRemoteID(),NULL); #endif } else { // we can handle it, as we know the remoteID irregular=true; } PDEBUGPRINTFX(DBG_DATA,("to-be-replaced item not found (Status=%hd) --> adding instead",sta)); // - process again (note that we are re-using the status command that might // already have a text item with an OS errir if something failed before) sta=LOCERR_OK; // forget previous status do_add_fallback: if (!implProcessItem(syncitemP,aStatusCommand)) sta=aStatusCommand.getStatusCode(); // not successful, get error status code CHECK_FOR_AGAIN(LOGIC_ITEM_ADD_FALLBACK); } } } break; case sop_delete : case sop_archive_delete : case sop_soft_delete : if (sta==404 || sta==410) { if (fSessionP->getSessionConfig()->fDeletingGoneOK) { // 404/410: item not found, could be because previous aborted session has // already committed deletion of that item -> behave as if delete was ok PDEBUGPRINTFX(DBG_DATA,("to-be-deleted item was not found, but do NOT report %hd",sta)); aStatusCommand.setStatusCode(200); irregular=true; sta = LOCERR_OK; // this is ok, item is deleted already } } break; default : SYSYNC_THROW(TSyncException("Unknown sync op in TStdLogicDS::logicProcessRemoteItem")); } // switch } // if not ok processed: if (sta==LOCERR_OK) { PDEBUGPRINTFX(DBG_DATA,( "- Operation %s performed (%sregular), Remote ID=%s Local ID=%s, status=%hd", SyncOpNames[syncitemP->getSyncOp()], irregular ? "ir" : "", syncitemP->getRemoteID(), syncitemP->getLocalID(), aStatusCommand.getStatusCode() )); // return GUID if string ptr was passed if (aGUID) { (*aGUID)=syncitemP->getLocalID(); } } /* LOCERR_AGAIN */ else { PDEBUGPRINTFX(DBG_ERROR,( "- Operation %s failed with SyncML status=%hd", SyncOpNames[syncitemP->getSyncOp()], sta )); } } // if startDataWrite ok // anyway, we are done with this item, delete it now delete syncitemP; if (syncitemP != origSyncItemP) delete origSyncItemP; TP_START(fSessionP->fTPInfo,li); // done, return regular/irregular status return (sta==LOCERR_OK) && !irregular; } SYSYNC_CATCH (...) // delete the item if (syncitemP) delete syncitemP; if (syncitemP != origSyncItemP) delete origSyncItemP; TP_START(fSessionP->fTPInfo,li); // re-throw SYSYNC_RETHROW; SYSYNC_ENDCATCH #ifndef __BORLANDC__ return false; // BCPPB: unreachable code #endif } // TStdLogicDS::logicProcessRemoteItem // Abort datastore sync void TStdLogicDS::dsAbortDatastoreSync(TSyError aReason, bool aLocalProblem) { // call anchestor inherited::dsAbortDatastoreSync(aReason, aLocalProblem); } // TStdLogicDS::dsAbortDatastoreSync // inform logic of coming state change localstatus TStdLogicDS::dsBeforeStateChange(TLocalEngineDSState aOldState,TLocalEngineDSState aNewState) { localstatus sta=LOCERR_OK; if (aNewState==dssta_dataaccessstarted) { // start data access if (IS_CLIENT) { #ifdef SYSYNC_CLIENT sta = startDataAccessForClient(); #endif } else { #ifdef SYSYNC_SERVER sta = startDataAccessForServer(); #endif } } if (IS_CLIENT) { if (aNewState==dssta_syncgendone) { // when client has done sync gen, start writing sta = startDataWrite(); } } // client #ifdef SYSYNC_SERVER if (aNewState==dssta_serverseenclientmods) { // Can only happen in server. Implement removal of unmatched items // when in caching mode. if (fCacheData && fSlowSync) { TSyncItemPContainer::iterator pos=fItems.begin(); while (pos!=fItems.end()) { TSyncItem *syncitemP = (*pos); if (syncitemP->getSyncOp() == sop_wants_add) { PDEBUGPRINTFX(DBG_DATA,("caching mode: remove unmatched item %s", syncitemP->getLocalID())); syncitemP->setSyncOp(sop_delete); localstatus status = logicDeleteItemByID(*syncitemP); if (status != LOCERR_OK) { return status; } else { TSyncItemPContainer::iterator next = pos; ++next; delete syncitemP; fItems.erase(pos); pos = next; fLocalItemsDeleted++; } } else { ++pos; } } } } #endif // SYSYNC_SERVER if (aNewState==dssta_completed && !isAborted()) { // finish writing data now anyway endDataWrite(); // we must save anchors at the moment we shift from any state to dssta_completed PDEBUGPRINTFX(DBG_ADMIN,("TStdLogicDS: successfully completed, save anchors now")); // update our level's state fPreviousSyncTime = fCurrentSyncTime; // let implementation update their state and save it sta=implSaveEndOfSession(true); if (sta!=LOCERR_OK) { PDEBUGPRINTFX(DBG_ERROR,("TStdLogicDS: Could not save session completed status, err=%hd",sta)); } } if (aNewState==dssta_idle && aOldState>=dssta_syncsetready) { // again: make sure data is written anyway (if already done this is a NOP) endDataWrite(); } // abort on error if (sta!=LOCERR_OK) return sta; // let inherited do its stuff as well return inherited::dsBeforeStateChange(aOldState,aNewState); } // TStdLogicDS::dsBeforeStateChange // inform logic of happened state change localstatus TStdLogicDS::dsAfterStateChange(TLocalEngineDSState aOldState,TLocalEngineDSState aNewState) { localstatus sta=LOCERR_OK; if (aNewState==dssta_dataaccessdone) { // finish writing data now endDataWrite(); } // abort on error if (sta!=LOCERR_OK) return sta; // let inherited do its stuff as well return inherited::dsAfterStateChange(aOldState,aNewState); } // TStdLogicDS::dsAfterStateChange /** @deprecated obsolete, replaced by stuff in dsBeforeStateChange() // called at very end of sync session, when all map commands are done, too // Note: is also called before deleting a datastore (so aborted sessions // can do cleanup and/or statistics display as well) void TStdLogicDS::endOfSync(bool aRegular) { // save new sync anchor now // NOTE: gets called even if not active if (fState!=dss_idle) { PDEBUGPRINTFX(DBG_ADMIN,("TStdLogicDS::endOfSync, %sregular end of sync session",aRegular ? "" : "ir")); if (!aRegular) fRollback=true; // do not write irregular ends // datastore was active in sync, end it now if (!fRollback) { fRollback=!startWrite(); if (!fRollback) { fRollback=!SaveAnchor(fNextRemoteAnchor.c_str()); } } #ifdef SYDEBUG if (fRollback) DEBUGPRINTFX(DBG_ERROR,("************** Datastore error, rolling back transaction")); #endif // if session is complete, we can't resume it any more, so clear that status now if (!fRollback) { fResumeAlertCode=0; // no resume } // end writing now, sync is done endWrite(); } // let ancestor do its things TLocalEngineDS::endOfSync(aRegular); } // TStdLogicDS::endOfSync */ } // namespace sysync /* end of TStdLogicDS implementation */ // eof libsynthesis-3.4.0.47.1/src/sysync/stdlogicds.h000077500000000000000000000421601226375725500213010ustar00rootroot00000000000000/** * @File stdlogicds.h * * @Author Lukas Zeller (luz@plan44.ch) * * @brief TStdLogicDS * Standard database logic implementation, suitable for most (currently all) * actual DS implementations, but takes as few assumptions about datastore * so for vastly different sync patterns, this could be replaced by differnt locic * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * @Date 2005-09-15 : luz : created from custdbdatastore */ /* */ #ifndef TStdLogicDS_H #define TStdLogicDS_H // includes #include "sysync.h" #include "syncappbase.h" #include "localengineds.h" #ifdef MULTI_THREAD_DATASTORE #include "platform_thread.h" #endif #if defined(CLIENT_USES_SERVER_DB) #define USES_SERVER_DB 1 #define HAS_SERVER_DB 1 #else #ifdef SERVER_SUPPORT #define USES_SERVER_DB 1 #endif #define HAS_SERVER_DB IS_SERVER #endif using namespace sysync; namespace sysync { // container for TSyncItem pointers typedef std::list TSyncItemPContainer; // contains data items /// @brief standard logic datastore /// - only called directly by TLocalEngineDS via logicXXXX virtuals. /// - to perform actual access to implementation, this class calls its (mostly abstract) /// implXXXX virtuals. class TStdLogicDS: public TLocalEngineDS { typedef TLocalEngineDS inherited; private: bool fWriteStarted; ///< set if write has started #ifdef SYSYNC_CLIENT bool fEoC; ///< end of changes #if defined(CLIENT_USES_SERVER_DB) && !defined(SYSYNC_SERVER) TSyncItemPContainer fItems; ///< list of data items, used to simulate maps in server DB #endif #endif #ifdef SYSYNC_SERVER TSyncItemPContainer fItems; ///< list of data items uInt32 fNumRefOnlyItems; #endif // startSync/threading privates bool fInitializing; bool fStartInit; bool fMultiThread; // copied flag from sessionConfig protected: /// @name dsSavedAdmin administrative data (anchors, timestamps, maps) as saved or to-be-saved /// @Note These will be loaded and saved be derived classes /// @Note Some of these will be updated from resp. @ref dsCurrentAdmin members at distinct events (suspend, session end, etc.) /// @Note Some of these will be updated during the session, but in a way that does NOT affect the anchoring of current/last session // /// @{ // - TStdLogicDS is timestamp-based, so we save timestamps of the previous session lineartime_t fPreviousSyncTime; ///< time of previous sync (used to generate local anchor string representing previous sync) /// @} /// @name dsCurrentAdmin current session's admin data (anchors, timestamps, maps) /// @Note These will be copied to @ref dsSavedAdmin members ONLY when a session completes successfully/suspends. /// @Note Admin data is NEVER directly saved or loaded from these /// @Note Derivates will update some of these at dssta_adminready with current time/anchor values // /// @{ // - TStdLogicDS is timestamp-based, so we get timestamp to anchor this session lineartime_t fCurrentSyncTime; ///< anchoring timestamp of this, currently running sync. /// @} private: /// internally reset for re-use without re-creation void InternalResetDataStore(void); public: /// constructor TStdLogicDS( TLocalDSConfig *aDSConfigP, sysync::TSyncSession *aSessionP, const char *aName, long aCommonSyncCapMask=0); virtual ~TStdLogicDS(); public: /// @name dsProperty property and state querying methods /// @{ /// check is datastore is completely started. /// @param[in] aWait if set, call will not return until either started state is reached /// or cannot be reached within the maximally allowed request processing time left. virtual bool isStarted(bool aWait); /// @} protected: /// @name dsXXXX (usually abstract) virtuals defining the interface to derived datastore classes (implementation, api) /// These are usually designed such that they should always call inherited::dsXXX to let the entire chain /// of ancestors see the calls /// @{ // /// reset datastore to a re-usable, like new-created state. virtual void dsResetDataStore(void) { InternalResetDataStore(); inherited::dsResetDataStore(); }; /// abort datastore (no reset yet, everything is just frozen as it is) virtual void dsAbortDatastoreSync(TSyError aStatusCode, bool aLocalProblem); /// inform logic of coming state change virtual localstatus dsBeforeStateChange(TLocalEngineDSState aOldState,TLocalEngineDSState aNewState); /// inform logic of happened state change virtual localstatus dsAfterStateChange(TLocalEngineDSState aOldState,TLocalEngineDSState aNewState); #ifdef SYSYNC_SERVER // - called when a item in the sync set changes its localID (due to local DB internals) // Datastore must make sure that possibly cached items get updated virtual void dsLocalIdHasChanged(const char *aOldID, const char *aNewID); #endif /// @} /// @name logicXXXX methods defining the interface to TLocalEngineDS. /// Only these will be called by TLocalEnginDS /// @Note some of these are virtuals ONLY for being derived by superdatastore, NEVER by locic or other derivates /// We use the SUPERDS_VIRTUAL macro for these, which is empty in case we don't have superdatastores, then /// these can be non-virtual. /// @{ // /// called to make admin data ready /// - might be called several times (auth retries at beginning of session) virtual localstatus logicMakeAdminReady(cAppCharP aDataStoreURI, cAppCharP aRemoteDBID); /// called to have all non-yet-generated sync commands as "to-be-resumed" virtual void logicMarkOnlyUngeneratedForResume(void); /// called to mark an already generated (but probably not sent or not yet statused) item /// as "to-be-resumed", by localID or remoteID (latter only in server case). /// @note This must be repeatable without side effects, as server must mark/save suspend state /// after every request (and not just at end of session) virtual void logicMarkItemForResume(cAppCharP aLocalID, cAppCharP aRemoteID, bool aUnSent); /// called to mark an already sent item as "to-be-resent", e.g. due to temporary /// error status conditions, by localID or remoteID (latter only in server case). virtual void logicMarkItemForResend(cAppCharP aLocalID, cAppCharP aRemoteID); /// save status information required to possibly perform a resume (as passed to datastore with /// markOnlyUngeneratedForResume(), markItemForResume() and markItemForResend()) /// (or, in case the session is really complete, make sure that no resume state is left) /// @note Must also save tempGUIDs (for server) and pending/unconfirmed maps (for client) virtual localstatus logicSaveResumeMarks(void); /// called to process incoming item operation /// @note Method must take ownership of syncitemP in all cases virtual bool logicProcessRemoteItem( TSyncItem *syncitemP, TStatusCommand &aStatusCommand, bool &aVisibleInSyncset, ///< on entry: tells if resulting item SHOULD be visible; on exit: set if processed item remains visible in the sync set. string *aGUID=NULL ///< GUID is stored here if not NULL ); /// called to read a specified item from the server DB (not restricted to set of conflicting items) virtual bool logicRetrieveItemByID( TSyncItem &aSyncItem, ///< item to be filled with data from server. Local or Remote ID must already be set TStatusCommand &aStatusCommand ///< status, must be set on error or non-200-status ); /// delete existing item in datastore, returns 211 if not existing any more virtual localstatus logicDeleteItemByID(TSyncItem &aSyncItem) = 0; /// @} /// @name implXXXX methods defining the interface to TStdLogicDS. /// Only these will be called by TLocalEngineDS /// @Note some of these are virtuals ONLY for being derived by superdatastore, NEVER by locic or other derivates /// We use the SUPERDS_VIRTUAL macro for these, which is empty in case we don't have superdatastores, then /// these can be non-virtual. /// @{ // /// save status information required to possibly perform a resume (as passed to datastore with /// markOnlyUngeneratedForResume() and markItemForResume()) /// (or, in case the session is really complete, make sure that no resume state is left) /// @note Must also save tempGUIDs (for server) and pending/unconfirmed maps (for client) virtual localstatus implSaveResumeMarks(void) = 0; // - called to have all non-yet-generated sync commands as "to-be-resumed" virtual void implMarkOnlyUngeneratedForResume(void) = 0; /// called to mark an already generated (but probably not sent or not yet statused) item /// as "to-be-resumed", by localID or remoteID (latter only in server case). /// @note This must be repeatable without side effects, as server must mark/save suspend state /// after every request (and not just at end of session) virtual void implMarkItemForResume(cAppCharP aLocalID, cAppCharP aRemoteID, bool aUnSent) = 0; /// called to mark an already sent item as "to-be-resent", e.g. due to temporary /// error status conditions, by localID or remoteID (latter only in server case). virtual void implMarkItemForResend(cAppCharP aLocalID, cAppCharP aRemoteID) = 0; /// sync login (into this database) /// @note might be called several times (auth retries at beginning of session) /// @note must update the following state variables /// - in TLocalEngineDS: fLastRemoteAnchor, fLastLocalAnchor, fResumeAlertCode, fFirstTimeSync /// - for client: fPendingAddMaps /// - for server: fTempGUIDMap /// - in TStdLogicDS: fPreviousSyncTime, fCurrentSyncTime /// - in derived classes: whatever else belongs to dsSavedAdmin and dsCurrentAdmin state virtual localstatus implMakeAdminReady( const char *aDeviceID, ///< @param[in] remote device URI (device ID) const char *aDatabaseID, ///< @param[in] database ID const char *aRemoteDBID ///< @param[in] database ID of remote device ) = 0; /// start data read /// @note: fSlowSync and fRefreshOnly must be valid before calling this method virtual localstatus implStartDataRead() = 0; /// get item from DB virtual localstatus implGetItem( bool &aEof, ///< set if no more items bool &aChanged, ///< if set on entry, only changed items will be reported, otherwise all will be returned and aChanged denotes if items has changed or not TSyncItem* &aSyncItemP ///< will receive the item ) = 0; /// end of read virtual localstatus implEndDataRead(void) = 0; /// start of write virtual localstatus implStartDataWrite(void) = 0; /// Returns true when DB can track syncop changes (i.e. having the DB report /// items as added again when stdlogic filters have decided they fell out of the syncset, /// and has announced this to the DB using implReviewReadItem(). virtual bool implTracksSyncopChanges(void) { return false; }; // derived DB class needs to confirm true if /// review reported entry (allows post-processing such as map deleting) /// MUST be called after implStartDataWrite, before any actual writing, /// for each item obtained in implGetItem virtual localstatus implReviewReadItem( TSyncItem &aItem ///< the item ) = 0; #ifdef SYSYNC_SERVER /// called to set maps. /// @note aLocalID or aRemoteID can be NULL - which signifies deletion of a map entry /// @note that this might be needed for clients accessing a server-style database as well virtual localstatus implProcessMap(cAppCharP aRemoteID, cAppCharP aLocalID) = 0; #endif /// called to read a specified item from the server DB (not restricted to set of conflicting items) virtual bool implRetrieveItemByID( TSyncItem &aSyncItem, ///< item to be filled with data from server. Local or Remote ID must already be set TStatusCommand &aStatusCommand ///< status, must be set on error or non-200-status ) = 0; /// process item (according to operation: add/delete/replace/map) virtual bool implProcessItem( TSyncItem *aItemP, ///< the item TStatusCommand &aStatusCommand ) = 0; /// save end of session state virtual localstatus implSaveEndOfSession(bool aUpdateAnchors) = 0; /// end write sequence virtual bool implEndDataWrite(void) = 0; /// @} private: /// @name dsHelpers /// internal, private helper methods #ifdef SYSYNC_CLIENT /// called by dsBeforeStateChange to dssta_dataaccessstarted to make sure datastore is ready for being accessed. virtual localstatus startDataAccessForClient(void); #endif #ifdef SYSYNC_SERVER /// called by dsBeforeStateChange to dssta_dataaccessstarted to make sure datastore is ready for being accessed. virtual localstatus startDataAccessForServer(void); #endif /// @} protected: // - helper to merge database version of an item with the passed version of the same item TMultiFieldItem *mergeWithDatabaseVersion(TSyncItem *aSyncItemP, bool &aChangedDBVersion, bool &aChangedNewVersion); #ifdef SYSYNC_SERVER // - check if conflicting item already exist in list of items-to-be-sent-to-client virtual TSyncItem *getConflictingItemByRemoteID(TSyncItem *syncitemP); virtual TSyncItem *getConflictingItemByLocalID(TSyncItem *syncitemP); // - called to check if content-matching item from server exists virtual TSyncItem *getMatchingItem(TSyncItem *syncitemP, TEqualityMode aEqMode); // - called to prevent item to be sent to client in subsequent logicGenerateSyncCommandsAsServer() // item in question should be an item that was returned by getConflictingItemByRemoteID() or getMatchingItem() virtual void dontSendItemAsServer(TSyncItem *syncitemP); // - called to have additional item sent to remote (DB takes ownership of item) virtual void SendItemAsServer(TSyncItem *aSyncitemP); private: // - end map operation (rollback if not aDoCommit) virtual bool MapFinishAsServer( bool aDoCommit, // if not set, entire map operation must be undone TStatusCommand &aStatusCommand // status, must be set on error or non-200-status ); /// called to generate sync sub-commands as client for remote server /// @return true if now finished for this datastore virtual bool logicGenerateSyncCommandsAsServer( TSmlCommandPContainer &aNextMessageCommands, TSmlCommand * &aInterruptedCommandP, cAppCharP aLocalIDPrefix ); /// called for servers when receiving map from client /// @note aLocalID or aRemoteID can be NULL - which signifies deletion of a map entry virtual localstatus logicProcessMap(cAppCharP aLocalID, cAppCharP aRemoteID); #endif // SYSYNC_SERVER #ifdef SYSYNC_CLIENT /// called to generate sync sub-commands as server for remote client /// @return true if now finished for this datastore virtual bool logicGenerateSyncCommandsAsClient( TSmlCommandPContainer &aNextMessageCommands, TSmlCommand * &aInterruptedCommandP, cAppCharP aLocalIDPrefix ); #endif // SYSYNC_CLIENT // - determine if this is a first time sync situation virtual bool isFirstTimeSync(void) { return fFirstTimeSync; }; protected: // - called for SyncML 1.1 if remote wants number of changes. // Must return -1 no NOC value can be returned // NOTE: we implement it here only for server, as it is not really needed // for clients normally - if it is needed, client's agent must provide // it as CustDBDatastore has no own list it can use to count in client case. virtual sInt32 getNumberOfChanges(void); public: // Simple custom DB access interface methods // - returns true if database implementation can only update all fields of a record at once virtual bool dsReplaceWritesAllDBFields(void) { return false; } // we assume DB is smart enough #ifdef OBJECT_FILTERING // - returns true if DB implementation can filter during database fetch // (otherwise, fetched items must be filtered after being read from DB) virtual bool dsFilteredFetchesFromDB(bool aFilterChanged=false) { return false; } // assume unfiltered data from DB #endif private: /// internal stdlogic: start writing if not already started localstatus startDataWrite(void); /// internal stdlogic: end writing if not already ended localstatus endDataWrite(void); public: // - must be called before starting a thread. If returns false, starting a thread now // is not allowed and must be postponed. virtual bool startingThread(void) { return true; }; // - must be called when a thread's activity has ended // BUT THE CALL MUST BE FROM THE ENDING THREAD, not the main thread! virtual void endingThread(void) {}; // - should be called before doing DB accesses that might be locked (e.g. because another thread is using the DB resources) virtual bool dbAccessLocked(void) { return false; }; // - Actual start sync actions in DB. If server supports threaded init, this will // be called in a sub-thread's context localstatus performStartSync(void); #ifdef MULTI_THREAD_DATASTORE TStatusCommand fStartSyncStatus; // a thread-private status command to store status ocurring during threaded startSync() #endif private: // - can be called to check if performStartSync() should be terminated bool shouldExitStartSync(void); #ifdef MULTI_THREAD_DATASTORE bool threadedStartSync(void); TThreadObject fStartSyncThread; // the wrapper object for the startSync thread #endif }; // TStdLogicDS } // namespace sysync #endif // TStdLogicDS_H // eof libsynthesis-3.4.0.47.1/src/sysync/stringutils.cpp000077500000000000000000000563351226375725500220750ustar00rootroot00000000000000/* * File: stringutils.cpp * * Authors: Lukas Zeller (luz@plan44.ch) * Beat Forster (bfo@synthesis.ch) * * C++ string utils * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * 2002-05-01 : luz : extracted from sysync_utils */ #include "prefix_file.h" #include "stringutils.h" // Consistent support for Linux, MacOSX CW & XCode #if defined __GNUC__ || defined _MSC_VER #include #else #include #endif #include #include #include using namespace std; namespace sysync { #ifdef NO_VSNPRINTF // dummy (unsafe!!) map to vsprintf int vsnprintf(char *s, int sz, const char *formatStr, va_list arg) { return vsprintf(s,formatStr,arg); } // vsnprintf #endif #ifdef NO_SNPRINTF // own implementation (possibly unsafe, if vsnprintf is dummy) int snprintf(char *s, int sz, const char *formatStr, ...) { va_list args; va_start(args, formatStr); // now make the string int n=vsnprintf(s,sz,formatStr,args); va_end(args); return n; } // snprintf #endif /// @brief Return passed pointer as C string, if pointer is NULL, empty string is returned /// @param[in] aStr a C string or NULL /// @return if aStr is NULL, returns empty string, aStr otherwise const char *alwaysCStr(const char *aStr) { return aStr ? aStr : ""; } // alwaysCStr // Assign char ptr to string object // NOTE: NULL is allowed and means empty string void AssignString(string &aString, const char *aCharP) { if (aCharP) aString=aCharP; else aString.erase(); } // AssignString // Assign char ptr to char array of size aLen (note that we always leave room for terminator) // NOTE: NULL is allowed and means empty string void AssignCString(char *aCStr, const char *aCharP, size_t aLen) { if (aCharP) { strncpy(aCStr,aCharP,aLen-1); aCStr[aLen-1]=0; // make sure it is terminated } else aCStr[0]=0; } // AssignCString // trim leading spaces/ctrls and everything including and after the next space/ctrl void AssignTrimmedCString(char *aCStr, const char *aCharP, size_t aLen) { if (aCharP) { // not empty, find first non-control/space while (*aCharP && (uInt8)(*aCharP)<=0x20) aCharP++; // now find end const char *e = aCharP; while (*e && (uInt8)(*e)>0x20) e++; // copy valid part of URL size_t n=e-aCharP; if (n>aLen-1) n=aLen-1; // limit to max buffer size strncpy(aCStr,aCharP,n); aCStr[n]=0; // make sure it is terminated } else aCStr[0]=0; } // AssignTrimmedCString // save mangled into C-string buffer uInt16 assignMangledToCString(char *aCString, const char *aCode, uInt16 aMaxBytes, bool aIsName, uInt8 aMangleInc, const char *aSecondKey) { uInt8 mangler=aMangleInc; uInt16 b,bytes=0; uInt8 c; const char *kp = aSecondKey && *aSecondKey ? aSecondKey : NULL; // need at least once char of key while(aCode && *aCode && bytes=0x20)) || (!aIsName && isalnum(c))) { // save only visible chars and spaces from name and alphanums from code *(aCString++)= c ^ mangler ^ (kp ? *(kp++) : 0); // add mangled if (kp && *kp==0) kp=aSecondKey; // wrap around mangler+=aMangleInc; bytes++; } } // add terminator in all cases *aCString++=mangler ^ (kp ? *(kp++) : 0); if (kp && *kp==0) kp=aSecondKey; // wrap around bytes++; // now add some garbage to disguise length of actual data b=bytes; while (b 0 && aMangled && (c=((uInt8)(*aMangled) ^ mangler ^ (kp ? *(kp++) : 0)))) { aString += (char)c; if (kp && *kp==0) kp=aSecondKey; // wrap around aMangled++; mangler+=aMangleInc; } } // getUnmangled // get unmangled into buffer void getUnmangledAsBuf(appCharP aBuffer, uInt16 aBufSize, cAppCharP aMangled, uInt8 aMangleInc, cAppCharP aSecondKey) { uInt8 mangler=aMangleInc; uInt8 c; if (!aBuffer || aBufSize<1) return; // no buffer const char *kp = aSecondKey && *aSecondKey ? aSecondKey : NULL; // need at least once char of key aBuffer[--aBufSize]=0; // ultimate security terminator while (aBufSize-- > 0 && aMangled && (c=((uInt8)(*aMangled) ^ mangler ^ (kp ? *(kp++) : 0)))) { *(aBuffer++) = (char)c; if (kp && *kp==0) kp=aSecondKey; // wrap around aMangled++; mangler+=aMangleInc; } *(aBuffer) = 0; // terminate } // getUnmangled // case insensitive and whitespace trimming strcmp, NULL allowed as empty string input sInt16 strutrimcmp(const char *s1, const char *s2) { // skip whitespace on both strings first while (s1 && *s1 && isspace(*s1)) ++s1; while (s2 && *s2 && isspace(*s2)) ++s2; // count number of non-whitespaces sInt32 n1=0; while (s1 && s1[n1] && !isspace(s1[n1])) ++n1; sInt32 n2=0; while (s2 && s2[n2] && !isspace(s2[n2])) ++n2; // now compare return strucmp(s1,s2,n1,n2); } // strutrimcmp // case insensitive strcmp which allow wildcards ? and * in s2, NULL allowed as empty string input sInt16 strwildcmp(const char *s1, const char *s2, size_t len1, size_t len2) { // allow NULL as empty strings if (!s1) s1 = ""; if (!s2) s2 = ""; // s1>s2 : 1, s1==s2 : 0, s1len2 ? len2 : len1)); for (i=0; (!len || i full match return 0; } // next attempt s1++; j++; } // no match if we get this far return 1; } else if (*s2!='?' && toupper(*s1)!=toupper(*s2)) return toupper(*s1)>toupper(*s2) ? 1 : -1; // different and no wildcard in pattern at this place // next s1++; s2++; } // equal up to end of shorter string or reached len // - if both reached end or len if (len1 ? i==len1 : *s1==0) { // s1 has reached end, check special case that pattern ends with *, this would be ok if ((len==0 || i=slen)) return -1; // pattern too long to possibly match at all if (toupper(*(s+k))!=toupper(*pat)) break; // no match at this position pat++; } if (*pat==0 || (patlen && k>=patlen)) return i; // pattern end reached and all matches so far -> found string here // try next position s++; } return -1; // not found in any position } // strupos // case insensitive strcmp, NULL allowed as empty string input sInt16 strucmp(const char *s1, const char *s2, size_t len1, size_t len2) { // allow NULL as empty strings if (!s1) s1 = ""; if (!s2) s2 = ""; // s1>s2 : 1, s1==s2 : 0, s1len2 ? len2 : len1)); for (i=0; (!len || itoupper(*s2) ? 1 : -1; // different // next s1++; s2++; } // equal up to end of shorter string or reached len // - if both reached end or len -> equal if ( ((len1 ? i==len1 : false) || *s1==0) && ((len2 ? i==len2 : false) || *s2==0) ) return 0; // - not equal, longer string is larger // (if not reached end of s1 or stopped before len1, s1 is longer // but note than len1 can be longer than actual length of s1, so we // must check for *s1 to make sure we have really not reached end of s1) return (len1 ? is2 : 1, s1==s2 : 0, s1len2 ? len2 : len1)); for (i=0; (!len || i*s2 ? 1 : -1; // different // next s1++; s2++; } // equal up to end of shorter string or reached len // - if both reached end or len if ( ((len1 ? i==len1 : false) || *s1==0) && ((len2 ? i==len2 : false) || *s2==0) ) return 0; // - not equal, longer string is larger // (if not reached end of s1 or stopped before len1, s1 is longer // but note than len1 can be longer than actual length of s1, so we // must check for *s1 to make sure we have really not reached end of s1) return (len1 ? i0) return "Yes"; else return "No"; } const char *boolString(bool aBool) { if (aBool) return "Yes"; else return "No"; } // returns true on successful conversion of string to enum bool StrToEnum(const char * const aEnumNames[], sInt16 aNumEnums, sInt16 &aShort, const char *aStr, sInt16 aLen) { const char *e; for (sInt16 k=0; k9) return 'A'-0x0A+aNibble; else return '0'+aNibble; } // NibbleToHexDigit // returns number of successfully converted chars sInt16 HexStrToUShort(const char *aStr, uInt16 &aShort, sInt16 aMaxDigits) { // our own implementation char c; sInt16 n=0; aShort=0; //firstly check aMaxDigits to avoid accessing invalid value of 'aStr' //This will cause a memory warning checked by valgrind while ((n'9' ? toupper(*p)-'A'+0x0A : *p-'0'); p++; n++; } break; } // c is the char to add } else if (aStopAtQuoteOrCtrl && (c=='"' || c<0x20)) { // terminating char is NOT consumed p--; break; // stop here } // otherwise, ignore any control characters else if (c<0x20 && c!=ignore) continue; // add it to the result if (c) aString+=c; } // return number of converted chars return p-aStr; } // CStrToStrAppend // add a hex byte to a string // Note: this is required because PalmOS sprintf does not correctly // work with %02X (always writes 4 digits!) void AppendHexByte(string &aString, uInt8 aByte) { aString += NibbleToHexDigit(aByte>>4); aString += NibbleToHexDigit(aByte); } // AppendHexByte // returns number of C-string-escaped chars successfully converted to string sInt16 StrToCStrAppend(const char *aStr, string &aString, bool aAllow8Bit, char ignore) { unsigned char c; const char *p=aStr; while ((c=*p++)) { // check for specials if (c==ignore) aString+= c; else if (c==0x09) aString+="\\t"; else if (c==0x0A) aString+="\\n"; else if (c==0x0D) aString+="\\r"; else if (c==0x22) aString+="\\\""; else if (c=='\\') aString+="\\\\"; // escape the backslash as well else if (c<0x20 || c==0x7F || (!aAllow8Bit && c>=0x80)) { aString += "\\x"; AppendHexByte(aString,c); } else { // as is aString+=c; } } // return number of converted chars return p-aStr; } // CStrToStrAppend // old-style C-formatted output into string object void vStringObjPrintf(string &aStringObj, const char *aFormat, bool aAppend, va_list aArgs) { #ifndef NO_VSNPRINTF const size_t bufsiz=128; #else const size_t bufsiz=2048; #endif ssize_t actualsize; char buf[bufsiz]; buf[0]='\0'; char *bufP = NULL; if (!aAppend) aStringObj.erase(); #ifndef NO_VSNPRINTF // using aArgs in vsnprintf() is destructive, need a copy in // case we call the function a second time va_list args; va_copy(args, aArgs); #endif actualsize = vsnprintf(buf, bufsiz, aFormat, aArgs); #ifndef NO_VSNPRINTF if (actualsize>=(ssize_t)bufsiz) { // default buffer was too small, create bigger dynamic buffer bufP = new char[actualsize+1]; actualsize = vsnprintf(bufP, actualsize+1, aFormat, args); if (actualsize>0) { aStringObj += bufP; } delete [] bufP; } else #endif { // small default buffer was big enough, add it if (actualsize<0) return; // abort, error aStringObj += buf; } #ifndef NO_VSNPRINTF va_end(args); #endif } // vStringObjPrintf // old-style C-formatted output into string object void StringObjPrintf(string &aStringObj, const char *aFormat, ...) { va_list args; va_start(args, aFormat); // now make the string vStringObjPrintf(aStringObj,aFormat,false,args); va_end(args); } // StringObjPrintf // old-style C-formatted output appending into string object void StringObjAppendPrintf(string &aStringObj, const char *aFormat, ...) { va_list args; va_start(args, aFormat); // now make the string vStringObjPrintf(aStringObj,aFormat,true,args); va_end(args); } // StringObjAppendPrintf } // namespace sysync /* eof */ libsynthesis-3.4.0.47.1/src/sysync/stringutils.h000077500000000000000000000137501226375725500215340ustar00rootroot00000000000000/* * File: stringutils.h * * Authors: Lukas Zeller (luz@plan44.ch) * Beat Forster (bfo@synthesis.ch) * * C++ string utils * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * 2002-05-01 : luz : extracted from sysync_utils */ #ifndef STRINGUTILS_H #define STRINGUTILS_H #include #ifdef __EPOC_OS__ #include #include #else #include #include #endif #include #ifdef ANDROID #include #endif #include "generic_types.h" using namespace std; namespace sysync { // PALM OS specifics #ifdef __PALM_OS__ // StrVPrintF handles a subset of ANSI vsprintf, but normal cases are available #define vsprintf StrVPrintF #define sprintf StrPrintF // PalmOS 3.5 does not have strncmp, use our own enhanced strnncmp #define strncmp sysync::strnncmp // PalmOS does not have vnsprintf, we need to simulate them #define NO_VSNPRINTF #define NO_SNPRINTF #endif #if defined(WINCE) || defined(_MSC_VER) || defined(__EPOC_OS__) // WinCE and Symbian do not have vsnprintf, as well as Visual Studio #define NO_VSNPRINTF #define NO_SNPRINTF #endif #ifdef NO_VSNPRINTF int vsnprintf(char *s, int sz, const char *formatStr, va_list arg); #endif #ifdef NO_SNPRINTF int snprintf(char *s, int sz, const char *formatStr, ...); #endif /// @brief Return passed pointer as C string, if pointer is NULL, empty string is returned const char *alwaysCStr(const char *aStr); // Assign char ptr to string object // NOTE: NULL is allowed and means empty string void AssignString(string &aString, const char *aCharP); // Assign char ptr to char array // NOTE: NULL is allowed and means empty string void AssignCString(char *aCStr, const char *aCharP, size_t aLen); // trim leading spaces/ctrls and everything including and after the next space/ctrl // NOTE: NULL is allowed and means empty string void AssignTrimmedCString(char *aCStr, const char *aCharP, size_t aLen); // standard mangling increment #define SYSER_NAME_MANGLEINC 43 // save mangled into C-string buffer uInt16 assignMangledToCString(appCharP aCString, cAppCharP aCode, uInt16 aMaxBytes, bool aIsName, uInt8 aMangleInc=SYSER_NAME_MANGLEINC, cAppCharP aSecondKey=NULL); // get unmangled into string void getUnmangled(string &aString, cAppCharP aMangled, uInt16 aMaxChars=100, uInt8 aMangleInc=SYSER_NAME_MANGLEINC, cAppCharP aSecondKey=NULL); // get unmangled into buffer void getUnmangledAsBuf(appCharP aBuffer, uInt16 aBufSize, cAppCharP aMangled, uInt8 aMangleInc=SYSER_NAME_MANGLEINC, cAppCharP aSecondKey=NULL); // Note: NULL allowed as empty string input for struXXX // case insensitive and whitespace trimming strcmp sInt16 strutrimcmp(const char *s1, const char *s2); // case insensitive strcmp which allow wildcards ? and * in s2, NULL allowed as empty string input sInt16 strwildcmp(const char *s1, const char *s2, size_t len1=0, size_t len2=0); // case insensitive strpos, returns -1 if not found sInt32 strupos(const char *s, const char *pat, size_t slen=0, size_t patlen=0); // case insensitive strcmp sInt16 strucmp(const char *s1, const char *s2, size_t len1=0, size_t len2=0); // byte by byte strcmp // Note: is compatible with standard strncmp if len2 is left unspecified sInt16 strnncmp(const char *s1, const char *s2, size_t len1=0, size_t len2=0); // testing #ifdef SYNTHESIS_UNIT_TEST bool test_strwildcmp(void); #endif // parser for tag="value" type string format cAppCharP nextTag(cAppCharP aTagString, string &aTag, string &aTagValue); // direct conversion of value (usually from nextTag()) into uInt16 uInt16 uint16Val(cAppCharP aValue); // direct conversion of value (usually from nextTag()) into uInt32 uInt32 uint32Val(cAppCharP aValue); // direct conversion of value (usually from nextTag()) into bool bool boolVal(cAppCharP aValue); // returns true on successful conversion of string to bool bool StrToBool(const char *aStr, bool &aBool); // returns true on successful conversion of string to enum bool StrToEnum(const char * const aEnumNames[], sInt16 aNumEnums, sInt16 &aShort, const char *aStr, sInt16 aLen=0); const char *tristateString(sInt8 aTristate); const char *boolString(bool aBool); // return number of successfully converted chars // Note: despite the names these functions take *fixed-size* integers sInt16 StrToUShort(const char *aStr, uInt16 &aShort, sInt16 aMaxDigits=100); sInt16 StrToShort(const char *aStr, sInt16 &aShort, sInt16 aMaxDigits=100); sInt16 StrToULong(const char *aStr, uInt32 &aLong, sInt16 aMaxDigits=100); sInt16 StrToLong(const char *aStr, sInt32 &aLong, sInt16 aMaxDigits=100); sInt16 StrToULongLong(const char *aStr, uInt64 &aLongLong, sInt16 aMaxDigits=100); sInt16 StrToLongLong(const char *aStr, sInt64 &aLongLong, sInt16 aMaxDigits=100); sInt16 HexStrToUShort(const char *aStr, uInt16 &aShort, sInt16 aMaxDigits=100); sInt16 HexStrToULong(const char *aStr, uInt32 &aLong, sInt16 aMaxDigits=100); sInt16 HexStrToULongLong(const char *aStr, uInt64 &aLongLong, sInt16 aMaxDigits=100); sInt16 HexStrToUIntPtr(const char *aStr, uIntPtr &aIntPtr, sInt16 aMaxDigits=100); #ifndef NO_FLOATS sInt16 StrToDouble(const char *aStr, double &aDouble, sInt16 aMaxDigits=100); #endif sInt16 CStrToStrAppend(const char *aStr, string &aString, bool aStopAtQuoteOrCtrl=false, char ignore='\0'); sInt16 StrToCStrAppend(const char *aStr, string &aString, bool aAllow8Bit=false, char ignore='\0'); // makes hex char out of nibble char NibbleToHexDigit(uInt8 aNibble); // add a hex byte to a string void AppendHexByte(string &aString, uInt8 aByte); // old-style C-formatted output into string object void vStringObjPrintf(string &aStringObj, const char *aFormat, bool aAppend, va_list aArgs); // old-style C-formatted output into string object void StringObjPrintf(string &aStringObj, const char *aFormat, ...) #ifdef __GNUC__ __attribute__((format(printf, 2, 3))) #endif ; void StringObjAppendPrintf(string &aStringObj, const char *aFormat, ...) #ifdef __GNUC__ __attribute__((format(printf, 2, 3))) #endif ; } // namespace sysync #endif // STRINGUTILS_H libsynthesis-3.4.0.47.1/src/sysync/superdatastore.cpp000077500000000000000000001455751226375725500225600ustar00rootroot00000000000000/* * File: SuperDataStore.h * * Author: Lukas Zeller (luz@plan44.ch) * * TSuperDataStore * "Virtual" datastore consisting of an union of other * datastores, for example a vCal datastore based on * two separate vEvent and vTodo datastores. * * Copyright (c) 2002-2011 by Synthesis AG + plan44.ch * * 2002-08-05 : luz : created * */ // includes #include "prefix_file.h" #include "sysync.h" #include "syncappbase.h" #include "superdatastore.h" #ifdef SUPERDATASTORES using namespace sysync; // sub-datastore link config // ========================= // config constructor TSubDSLinkConfig::TSubDSLinkConfig(TLocalDSConfig *aLocalDSConfigP, TConfigElement *aParentElementP) : TConfigElement(aLocalDSConfigP->getName(),aParentElementP) { clear(); fLinkedDSConfigP=aLocalDSConfigP; } // TSubDSLinkConfig::TSubDSLinkConfig // config destructor TSubDSLinkConfig::~TSubDSLinkConfig() { clear(); } // TSubDSLinkConfig::~TSubDSLinkConfig // init defaults void TSubDSLinkConfig::clear(void) { // init defaults fDispatchFilter.erase(); fGUIDPrefix.erase(); // clear inherited inherited::clear(); } // TSubDSLinkConfig::clear #ifndef HARDCODED_CONFIG // remote rule config element parsing bool TSubDSLinkConfig::localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine) { // checking the elements // - identification of remote if (strucmp(aElementName,"dispatchfilter")==0) expectString(fDispatchFilter); else if (strucmp(aElementName,"guidprefix")==0) expectString(fGUIDPrefix); // - not known here else return inherited::localStartElement(aElementName,aAttributes,aLine); // ok return true; } // TSubDSLinkConfig::localStartElement #endif // superdatastore config // ===================== TSuperDSConfig::TSuperDSConfig(const char* aName, TConfigElement *aParentElement) : TLocalDSConfig(aName,aParentElement) { clear(); } // TSuperDSConfig::TSuperDSConfig TSuperDSConfig::~TSuperDSConfig() { clear(); } // TSuperDSConfig::~TSuperDSConfig // init defaults void TSuperDSConfig::clear(void) { // init defaults // - no datastore links TSubDSConfigList::iterator pos; for(pos=fSubDatastores.begin();pos!=fSubDatastores.end();pos++) delete *pos; fSubDatastores.clear(); // clear inherited inherited::clear(); } // TSuperDSConfig::clear #ifndef HARDCODED_CONFIG // config element parsing bool TSuperDSConfig::localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine) { // checking the elements // - links to sub-datastores if (strucmp(aElementName,"contains")==0) { // definition of a new datastore const char* nam = getAttr(aAttributes,"datastore"); if (!nam) return fail("'contains' missing 'datastore' attribute"); // search sub-datastore TLocalDSConfig *subdscfgP = static_cast(getParentElement())->getLocalDS(nam); if (!subdscfgP) return fail("unknown datastore '%s' specified",nam); // create new datastore link TSubDSLinkConfig *dslinkcfgP = new TSubDSLinkConfig(subdscfgP,this); // - save in list fSubDatastores.push_back(dslinkcfgP); // - let element handle parsing expectChildParsing(*dslinkcfgP); } // - none known here else return TLocalDSConfig::localStartElement(aElementName,aAttributes,aLine); // ok return true; } // TSuperDSConfig::localStartElement #endif // resolve void TSuperDSConfig::localResolve(bool aLastPass) { if (aLastPass) { // check for required settings // %%% tbd } // resolve inherited inherited::localResolve(aLastPass); } // TSuperDSConfig::localResolve // - create appropriate datastore from config, calls addTypeSupport as well TLocalEngineDS *TSuperDSConfig::newLocalDataStore(TSyncSession *aSessionP) { // Synccap defaults to normal set supported by the engine by default TSuperDataStore *sdsP = new TSuperDataStore(this,aSessionP,getName(),aSessionP->getSyncCapMask()); // add type support addTypes(sdsP,aSessionP); return sdsP; } // TLocalDSConfig::newLocalDataStore /* * Implementation of TSuperDataStore */ /* public TSuperDataStore members */ TSuperDataStore::TSuperDataStore(TSuperDSConfig *aDSConfigP, TSyncSession *aSessionP, const char *aName, uInt32 aCommonSyncCapMask) : TLocalEngineDS(aDSConfigP, aSessionP, aName, aCommonSyncCapMask) { // set config ptr fDSConfigP = aDSConfigP; if (!fDSConfigP) SYSYNC_THROW(TSyncException(DEBUGTEXT("TSuperDataStore::TSuperDataStore called with NULL config","lds1"))); // reset first InternalResetDataStore(); // for server, all configured subdatastores are automatically linked in // (for client, only those that are active will be linked in at dsSetClientParams() time) if (IS_SERVER) { // create links to subdatastores TSubDSConfigList::iterator pos; for(pos=aDSConfigP->fSubDatastores.begin();pos!=aDSConfigP->fSubDatastores.end();pos++) { // add link addSubDatastoreLink(*pos,NULL); // search datastore } } } // TSuperDataStore::TSuperDataStore void TSuperDataStore::addSubDatastoreLink(TSubDSLinkConfig *aDSLinkConfigP, TLocalEngineDS *aDatastoreP) { TSubDatastoreLink link; // start not yet pending link.fStartPending = false; // set link to subdatastore's config link.fDSLinkConfigP = aDSLinkConfigP; if (aDatastoreP) link.fDatastoreLinkP = aDatastoreP; // we already know the datastore (for client, it might not yet be in session list of datastores) else link.fDatastoreLinkP = fSessionP->findLocalDataStore(link.fDSLinkConfigP->fLinkedDSConfigP); // find actual datastore by "handle" (= config pointer) // make sure datastore is instantiated if (!link.fDatastoreLinkP) { // instantiate now (should not happen on server, as all datastores are instantiated on a server anyway) link.fDatastoreLinkP=fSessionP->addLocalDataStore(link.fDSLinkConfigP->fLinkedDSConfigP); } // save link fSubDSLinks.push_back(link); // Important: We need to get the iterator now again, in case the list was empty before // (because the iterator set in InternalResetDataStore() is invalid because it was created for an empty list). fCurrentGenDSPos=fSubDSLinks.begin(); } void TSuperDataStore::InternalResetDataStore(void) { // init fFirstTimeSync=false; TSubDSLinkList::iterator pos; // cancel all pending starts for(pos=fSubDSLinks.begin();pos!=fSubDSLinks.end();pos++) { pos->fStartPending=false; } fSuperStartPending = false; // make sure this is set in case startSync() is not called before generateSyncCommands() fCurrentGenDSPos=fSubDSLinks.begin(); } // TSuperDataStore::InternalResetDataStore TSuperDataStore::~TSuperDataStore() { InternalResetDataStore(); } // TSuperDataStore::~TSuperDataStore // Session events, which need some distribution to subdatastores // ============================================================= // Methods overriding TLocalEngineDS // ---------------------------------- bool TSuperDataStore::canRestart() { TSubDSLinkList::iterator pos; for (pos=fSubDSLinks.begin();pos!=fSubDSLinks.end();pos++) { if (!pos->fDatastoreLinkP->canRestart()) { return false; } } return true; } // obtain Sync Cap mask, must be lowest common mask of all subdatastores uInt32 TSuperDataStore::getSyncCapMask(void) { // AND of all subdatastores uInt32 capmask = ~0; // all bits set TSubDSLinkList::iterator pos; for (pos=fSubDSLinks.begin();pos!=fSubDSLinks.end();pos++) { capmask = capmask & pos->fDatastoreLinkP->getSyncCapMask(); } return capmask; } // TSuperDataStore::getSyncCapMask bool TSuperDataStore::syncModeSupported(const std::string &mode) { TSubDSLinkList::iterator pos; for (pos=fSubDSLinks.begin();pos!=fSubDSLinks.end();pos++) { if (!pos->fDatastoreLinkP->syncModeSupported(mode)) { return false; } } return true; } void TSuperDataStore::getSyncModes(set &modes) { // Initialize with content from first subdatastore. TSubDSLinkList::iterator pos = fSubDSLinks.begin(); if (pos!=fSubDSLinks.end()) { pos->fDatastoreLinkP->getSyncModes(modes); ++pos; } // Remove any mode not found in any of the other subdatastores. while (pos!=fSubDSLinks.end() && !modes.empty()) { set b; pos->fDatastoreLinkP->getSyncModes(b); set::iterator it = modes.begin(); while (it != modes.end()) { if (b.find(*it) != b.end()) { ++it; } else { set::iterator del = it; ++it; modes.erase(del); } } pos++; } } // process Sync alert from remote party: check if alert code is supported, // check if slow sync is needed due to anchor mismatch // - server case: also generate appropriate Alert acknowledge command TAlertCommand *TSuperDataStore::engProcessSyncAlert( TSuperDataStore *aAsSubDatastoreOf, // if acting as subdatastore uInt16 aAlertCode, // the alert code const char *aLastRemoteAnchor, // last anchor of client const char *aNextRemoteAnchor, // next anchor of client const char *aTargetURI, // target URI as sent by remote, no processing at all const char *aIdentifyingTargetURI, // target URI that was used to identify datastore const char *aTargetURIOptions, // option string contained in target URI SmlFilterPtr_t aTargetFilter, // DS 1.2 filter, NULL if none const char *aSourceURI, // source URI TStatusCommand &aStatusCommand // status that might be modified ) { TAlertCommand *alertcmdP=NULL; TAlertCommand *subalertcmdP=NULL; TStatusCommand substatus(fSessionP); SYSYNC_TRY { // alert all subdatastores TSubDSLinkList::iterator pos; for (pos=fSubDSLinks.begin();pos!=fSubDSLinks.end();pos++) { subalertcmdP=pos->fDatastoreLinkP->engProcessSyncAlert( this, // as subdatastore of myself aAlertCode, // the alert code aLastRemoteAnchor, // last anchor of client aNextRemoteAnchor, // next anchor of client aTargetURI, // target URI as sent by remote, no processing at all aIdentifyingTargetURI, // target URI (without possible CGI) aTargetURIOptions, // filtering CGI (NULL or empty if none) aTargetFilter, // DS 1.2 filter, NULL if none aSourceURI, // source URI substatus // status that might be modified ); if (subalertcmdP) { // get rid of this, we don't need it (server case only, client case does not generate an alert command here anyway) delete subalertcmdP; } // check if processing alert had a problem // Notes: // - When we have a subalertcmdP here, it is the server case, which means a non-zero status code // (such as 508) at this point is ok and should not stop processing alerts. // Only in case we have no alert we need to check the status code and abort immediately if it's not ok. // - 508 can happen even in client for the rare case the server thinks anchors are ok, but client check // says they are not, so we need to exclude 508 here. if (!subalertcmdP && substatus.getStatusCode()!=0 && substatus.getStatusCode()!=508) { // basic problem with one of the subdatastores // - propagate error code aStatusCommand.setStatusCode(substatus.getStatusCode()); // - no alert to send return NULL; } // this one is pending for start pos->fStartPending=true; } // set flag to indicate this subdatastore has init pending // Now all subdatastores should be successfully alerted and have current anchor infos ready, // so we can call inherited (which will obtain combined anchors from our logicInitSyncAnchors) alertcmdP = inherited::engProcessSyncAlert( aAsSubDatastoreOf, // as indicated by caller (normally, superdatastore is not subdatastore of another superdatastore, but...) aAlertCode, // the alert code aLastRemoteAnchor, // last anchor of client aNextRemoteAnchor, // next anchor of client aTargetURI, // target URI as sent by remote, no processing at all aIdentifyingTargetURI, // target URI (without possible CGI) aTargetURIOptions, // filtering CGI (NULL or empty if none) aTargetFilter, // DS 1.2 filter, NULL if none aSourceURI, // source URI aStatusCommand // status that might be modified ); // entire superdatastore is pending for start fSuperStartPending=true; } SYSYNC_CATCH (...) // clean up locally owned objects if (alertcmdP) delete alertcmdP; if (subalertcmdP) delete subalertcmdP; SYSYNC_RETHROW; SYSYNC_ENDCATCH return alertcmdP; } // TSuperDataStore::engProcessSyncAlert // process status received for sync alert bool TSuperDataStore::engHandleAlertStatus(TSyError aStatusCode) { // show it to all subdatastores TSubDSLinkList::iterator pos; for (pos=fSubDSLinks.begin();pos!=fSubDSLinks.end();pos++) { pos->fDatastoreLinkP->engHandleAlertStatus(aStatusCode); } // all subdatastores have seen the alert status, so let superdatastore handle it as well return TLocalEngineDS::engHandleAlertStatus(aStatusCode); } // TSuperDataStore::engHandleAlertStatus // Set remote datastore for local void TSuperDataStore::engSetRemoteDatastore( TRemoteDataStore *aRemoteDatastoreP // the remote datastore involved ) { // set all subdatastores to (same) remote datastore as superdatastore itself TSubDSLinkList::iterator pos; for (pos=fSubDSLinks.begin();pos!=fSubDSLinks.end();pos++) { pos->fDatastoreLinkP->engSetRemoteDatastore(aRemoteDatastoreP); } // set in superdatastore as well TLocalEngineDS::engSetRemoteDatastore(aRemoteDatastoreP); } // TSuperDataStore::engSetRemoteDatastore // set Sync types needed for sending local data to remote DB void TSuperDataStore::setSendTypeInfo( TSyncItemType *aLocalSendToRemoteTypeP, TSyncItemType *aRemoteReceiveFromLocalTypeP ) { // set all subdatastores to (same) types as superdatastore itself TSubDSLinkList::iterator pos; for (pos=fSubDSLinks.begin();pos!=fSubDSLinks.end();pos++) { pos->fDatastoreLinkP->setSendTypeInfo(aLocalSendToRemoteTypeP,aRemoteReceiveFromLocalTypeP); } // set in superdatastore as well TLocalEngineDS::setSendTypeInfo(aLocalSendToRemoteTypeP,aRemoteReceiveFromLocalTypeP); } // TSuperDataStore::setSendTypeInfo // set Sync types needed for receiving remote data in local DB void TSuperDataStore::setReceiveTypeInfo( TSyncItemType *aLocalReceiveFromRemoteTypeP, TSyncItemType *aRemoteSendToLocalTypeP ) { // set all subdatastores to (same) types as superdatastore itself TSubDSLinkList::iterator pos; for (pos=fSubDSLinks.begin();pos!=fSubDSLinks.end();pos++) { pos->fDatastoreLinkP->setReceiveTypeInfo(aLocalReceiveFromRemoteTypeP,aRemoteSendToLocalTypeP); } // set in superdatastore as well TLocalEngineDS::setReceiveTypeInfo(aLocalReceiveFromRemoteTypeP,aRemoteSendToLocalTypeP); } // TSuperDataStore::setReceiveTypeInfo // init usage of datatypes set with setSendTypeInfo/setReceiveTypeInfo localstatus TSuperDataStore::initDataTypeUse(void) { localstatus sta=LOCERR_OK; // set all subdatastores to (same) types as superdatastore itself TSubDSLinkList::iterator pos; for (pos=fSubDSLinks.begin();pos!=fSubDSLinks.end();pos++) { sta = pos->fDatastoreLinkP->initDataTypeUse(); if (sta!=LOCERR_OK) return sta; // failed } // set in superdatastore as well return TLocalEngineDS::initDataTypeUse(); } // TSuperDataStore::initDataTypeUse // SYNC command bracket start (check credentials if needed) bool TSuperDataStore::engProcessSyncCmd( SmlSyncPtr_t aSyncP, // the Sync element TStatusCommand &aStatusCommand, // status that might be modified bool &aQueueForLater // will be set if command must be queued for later (re-)execution ) { // start sync for all subdatastores bool ok=true; bool doqueue; TSubDSLinkList::iterator pos; for (pos=fSubDSLinks.begin();pos!=fSubDSLinks.end();pos++) { // Note: this will cause subdatastores to call their own startSync, // so we do NOT need to iterate over subdatastores in our startSync! doqueue=false; // if in init phase (entire superdatastore pending to start) // only call subdatastores that are still pending for start, too ok=true; if (!fSuperStartPending || pos->fStartPending) { ok=pos->fDatastoreLinkP->engProcessSyncCmd(aSyncP,aStatusCommand,doqueue); if (!doqueue) { // this one is now initialized. Do not do it again until all others are initialized, too pos->fStartPending=false; } else { // we must queue the entire command for later (but some subdatastores might be excluded then) aQueueForLater=true; // queue if one of the subdatastores needs it } } if (!ok) return false; } // start sync myself ok=TLocalEngineDS::engProcessSyncCmd(aSyncP,aStatusCommand,doqueue); if (doqueue) aQueueForLater=true; // queue if one of the subdatastores needs it // if we reach this w/o queueing, start is no longer pending if (!aQueueForLater) fSuperStartPending=false; // done return ok; } // TSuperDataStore::processSyncCmd // SYNC command bracket end (but another might follow in next message) bool TSuperDataStore::engProcessSyncCmdEnd(bool &aQueueForLater) { // signal sync end to all subdatastores bool ok=true; bool doqueue; TSubDSLinkList::iterator pos; for (pos=fSubDSLinks.begin();pos!=fSubDSLinks.end();pos++) { doqueue=false; ok=pos->fDatastoreLinkP->engProcessSyncCmdEnd(doqueue); if (doqueue) aQueueForLater=true; // queue if one of the subdatastores needs it if (!ok) return false; } // signal it to myself ok=TLocalEngineDS::engProcessSyncCmdEnd(doqueue); if (doqueue) aQueueForLater=true; // queue if one of the subdatastores needs it return ok; } // TSuperDataStore::engProcessSyncCmdEnd #ifdef SYSYNC_SERVER // process map localstatus TSuperDataStore::engProcessMap(cAppCharP aRemoteID, cAppCharP aLocalID) { TSubDatastoreLink *linkP = NULL; localstatus sta = LOCERR_OK; // item has local ID, we can find datastore by prefix linkP = findSubLinkByLocalID(aLocalID); if (!linkP) { sta = 404; // not found goto done; } // let subdatastore process (and only show subDS part of localID) sta=linkP->fDatastoreLinkP->engProcessMap( aRemoteID, aLocalID+linkP->fDSLinkConfigP->fGUIDPrefix.size() ); done: return sta; } // TSuperDataStore::engProcessMap #endif // SYSYNC_SERVER // called to process incoming item operation // Method takes ownership of syncitemP in all cases // - returns true (and unmodified or non-200-successful status) if // operation could be processed regularily // - returns false (but probably still successful status) if // operation was processed with internal irregularities, such as // trying to delete non-existant item in datastore with // incomplete Rollbacks (which returns status 200 in this case!). bool TSuperDataStore::engProcessRemoteItem( TSyncItem *syncitemP, TStatusCommand &aStatusCommand ) { bool regular=true; string datatext; #ifdef SYSYNC_SERVER TSyncItem *itemcopyP = NULL; #endif // show PDEBUGBLOCKFMT(( "SuperProcessItem", "Processing incoming item in superdatastore", "datastore=%s|SyncOp=%s|RemoteID=%s|LocalID=%s", getName(), SyncOpNames[syncitemP->getSyncOp()], syncitemP->getRemoteID(), syncitemP->getLocalID() )); // let appropriate subdatastore handle the command TSubDatastoreLink *linkP = NULL; TSyncOperation sop=syncitemP->getSyncOp(); string remid; TSubDSLinkList::iterator pos; #ifdef SYSYNC_SERVER if (IS_SERVER) { switch (sop) { // Server case case sop_wants_replace: case sop_replace: case sop_wants_add: case sop_add: // item has no local ID, we need to apply filters to item data PDEBUGPRINTFX(DBG_DATA,("Checkin subdatastore filters to find where it belongs")); linkP = findSubLinkByData(*syncitemP); if (!linkP) goto nods; PDEBUGPRINTFX(DBG_DATA,( "Found item belongs to subdatastore '%s'", linkP->fDatastoreLinkP->getName() )); // make sure item does not have a local ID (which would be wrong because of prefixes anyway) syncitemP->clearLocalID(); // remembert because we might need it below for move-replace remid=syncitemP->getRemoteID(); // let subdatastore process regular=linkP->fDatastoreLinkP->engProcessRemoteItem(syncitemP,aStatusCommand); // now check if replace was treated as add, if yes, this indicates // that this might be a move between subdatastores if ( (sop==sop_replace || sop==sop_wants_replace) && !fSlowSync && aStatusCommand.getStatusCode()==201 ) { // this is probably a move from another datastore by changing an attribute // that dispatches datastores (such as a vEvent changed to a vToDo) // - so we delete all items with this remote ID in all other datastores PDEBUGPRINTFX(DBG_DATA,("Replace could be a move between subdatastores, trying to delete all items with same remoteID in other subdatastores")); TStatusCommand substatus(fSessionP); for (pos=fSubDSLinks.begin();pos!=fSubDSLinks.end();pos++) { if (&(*pos) != linkP) { // all but original datastore substatus.setStatusCode(200); itemcopyP = new TSyncItem(); // - only remote ID and syncop are relevant, leave everything else empty itemcopyP->setRemoteID(remid.c_str()); itemcopyP->setSyncOp(sop_delete); // - now try to delete. This might fail if replace above wasn't a move // itemcopyP is consumed PDEBUGPRINTFX(DBG_DATA+DBG_DETAILS,( "Trying to delete item with remoteID='%s' from subdatastore '%s'", itemcopyP->getRemoteID(), linkP->fDatastoreLinkP->getName() )); regular=pos->fDatastoreLinkP->engProcessRemoteItem(itemcopyP,substatus); #ifdef SYDEBUG if (regular) { // deleted ok PDEBUGPRINTFX(DBG_DATA,( "Found item in '%s', deleted here (and moved to '%s')", pos->fDatastoreLinkP->getName(), linkP->fDatastoreLinkP->getName() )); } #endif } } PDEBUGPRINTFX(DBG_DATA,("End of (possible) move-replace between subdatastores")); regular=true; // fully ok, no matter if delete above has succeeded or not } goto done; case sop_archive_delete: case sop_soft_delete: case sop_delete: case sop_copy: // item has no local ID AND no data, only a remoteID: // we must try to read item or attempt to delete in all subdatastores by remoteID // until found in one of them // get an empty item of correct type to call logicRetrieveItemByID itemcopyP = getLocalReceiveType()->newSyncItem(getRemoteSendType(),this); // - only remote ID is relevant, leave everything else empty itemcopyP->setRemoteID(syncitemP->getRemoteID()); // try to find item in any of the subdatastores for (pos=fSubDSLinks.begin();pos!=fSubDSLinks.end();pos++) { linkP = &(*pos); // always start with 200 aStatusCommand.setStatusCode(200); // item deleted by a failed engProcessRemoteItem()? if (!syncitemP) { // recreate it for next attempt syncitemP = getLocalReceiveType()->newSyncItem(getRemoteSendType(),this); syncitemP->setRemoteID(itemcopyP->getRemoteID()); syncitemP->setSyncOp(sop); } if (sop!=sop_copy && linkP->fDatastoreLinkP->dsDeleteDetectsItemPresence()) { // attempt to delete, consuming original item on success regular=linkP->fDatastoreLinkP->engProcessRemoteItem(syncitemP,aStatusCommand); // must be ok AND not 404 (item not found) if (regular && aStatusCommand.getStatusCode()!=404) { PDEBUGPRINTFX(DBG_DATA,( "Item found in subdatastore '%s', deleted it there", linkP->fDatastoreLinkP->getName() )); // done goto done; } else { // syncitemP was deleted by engProcessRemoteItem() (for // example, in TStdLogicDS::logicProcessRemoteItem()), // so we must remember to recreate it from the copy for // another attempt if there is one syncitemP = NULL; } } else { // try to read first to determine whether the subdatastore contains the item; // necessary because the subdatastore is not able to report a 404 error in // the delete operation when the item does not exist PDEBUGPRINTFX(DBG_DATA+DBG_DETAILS,( "Trying to read item by remoteID='%s' from subdatastore '%s' to see if it is there", itemcopyP->getRemoteID(), linkP->fDatastoreLinkP->getName() )); regular=linkP->fDatastoreLinkP->logicRetrieveItemByID(*itemcopyP,aStatusCommand); // must be ok AND not 404 (item not found) if (regular && aStatusCommand.getStatusCode()!=404) { PDEBUGPRINTFX(DBG_DATA,( "Item found in subdatastore '%s', deleting it there", linkP->fDatastoreLinkP->getName() )); // now we can delete or copy, consuming original item regular=linkP->fDatastoreLinkP->engProcessRemoteItem(syncitemP,aStatusCommand); // done regular=true; goto done; } } } // none of the datastores could process this item --> error // - make sure delete reports 200 for incomplete-rollback-datastores if (aStatusCommand.getStatusCode()==404 && sop!=sop_copy) { // not finding an item for delete might be ok for remote... if (fSessionP->getSessionConfig()->fDeletingGoneOK) { // 404/410: item not found, could be because previous aborted session has // already committed deletion of that item -> behave as if delete was ok PDEBUGPRINTFX(DBG_DATA,("to-be-deleted item was not found, but do NOT report %hd",aStatusCommand.getStatusCode())); aStatusCommand.setStatusCode(200); } // ...but it is a internal irregularity, fall thru to return false } // is an internal irregularity regular=false; goto done; case sop_reference_only: case sop_move: case sop_none: case numSyncOperations: // nothing to do or shouldn't happen break; } // switch } // server #endif // SYSYNC_SERVER #ifdef SYSYNC_CLIENT if (IS_CLIENT) { switch (sop) { // Client case case sop_wants_replace: case sop_replace: case sop_archive_delete: case sop_soft_delete: case sop_delete: case sop_copy: // item has local ID, we can find datastore by prefix linkP = findSubLinkByLocalID(syncitemP->getLocalID()); if (!linkP) goto nods; // remove prefix before letting subdatastore process it syncitemP->fLocalID.erase(0,linkP->fDSLinkConfigP->fGUIDPrefix.size()); // now let subdatastore process regular=linkP->fDatastoreLinkP->engProcessRemoteItem(syncitemP,aStatusCommand); goto done; case sop_wants_add: case sop_add: // item has no local ID, we need to apply filters to item data linkP = findSubLinkByData(*syncitemP); if (!linkP) goto nods; // make sure item does not have a local ID (which would be wrong because of prefixes anyway) syncitemP->clearLocalID(); // let subdatastore process regular=linkP->fDatastoreLinkP->engProcessRemoteItem(syncitemP,aStatusCommand); goto done; case sop_reference_only: case sop_move: case sop_none: case numSyncOperations: // nothing to do or shouldn't happen break; } // switch } // client #endif // SYSYNC_CLIENT nods: // no datastore or unknown command, general DB error aStatusCommand.setStatusCode(510); PDEBUGPRINTFX(DBG_ERROR,("TSuperDataStore::processRemoteItem Fatal: Item cannot be processed by any subdatastore")); // consume item delete syncitemP; regular=false; goto done; done: #ifdef SYSYNC_SERVER delete itemcopyP; #endif PDEBUGENDBLOCK("SuperProcessItem"); return regular; } // TSuperDataStore::engProcessRemoteItem // - must return true if this datastore is finished with // (if all datastores return true, // session is allowed to finish sync packet with outgoing message bool TSuperDataStore::isSyncDone(void) { // check subdatastores bool done=true; TSubDSLinkList::iterator pos; for (pos=fSubDSLinks.begin();pos!=fSubDSLinks.end();pos++) { done=done && pos->fDatastoreLinkP->isSyncDone(); } // check myself return done && TLocalEngineDS::isSyncDone(); } // TSuperDataStore::isSyncDone // abort sync with this super datastore (that is, with all subdatastores as well) void TSuperDataStore::engAbortDataStoreSync(TSyError aStatusCode, bool aLocalProblem, bool aResumable) { // abort subdatastores TSubDSLinkList::iterator pos; for (pos=fSubDSLinks.begin();pos!=fSubDSLinks.end();pos++) { pos->fDatastoreLinkP->engAbortDataStoreSync(aStatusCode,aLocalProblem,aResumable); } // set code in my own ancestor TLocalEngineDS::engAbortDataStoreSync(aStatusCode,aLocalProblem,aResumable); } // TSuperDataStore::engAbortDataStoreSync // - must return true if this datastore is finished with // (if all datastores return true, // session is allowed to finish sync packet with outgoing message bool TSuperDataStore::isAborted(void) { // check subdatastores TSubDSLinkList::iterator pos; for (pos=fSubDSLinks.begin();pos!=fSubDSLinks.end();pos++) { if (pos->fDatastoreLinkP->isAborted()) return true; // one aborted, super aborted as well } // check myself return TLocalEngineDS::isAborted(); } // TSuperDataStore::isAborted // called at very end of sync session, when everything is done // Note: is also called before deleting a datastore (so aborted sessions // can do cleanup and/or statistics display as well) void TSuperDataStore::engFinishDataStoreSync(localstatus aErrorStatus) { // inform all subdatastores TSubDSLinkList::iterator pos; for (pos=fSubDSLinks.begin();pos!=fSubDSLinks.end();pos++) { pos->fDatastoreLinkP->engFinishDataStoreSync(aErrorStatus); } // call inherited inherited::engFinishDataStoreSync(aErrorStatus); } // TSuperDataStore::engFinishDataStoreSync // Internal events during sync to access local database // ==================================================== // Methods overriding TLocalEngineDS // ---------------------------------- // called at sync alert (before generating for client, after receiving for server) // - obtains combined anchor from subdatastores // - combines them into a common anchor (if possible) // - updates fFirstTimeSync as well localstatus TSuperDataStore::engInitSyncAnchors( cAppCharP aDatastoreURI, // (Note: unused in superdatastore) local datastore URI cAppCharP aRemoteDBID // (Note: unused in superdatastore) ID of remote datastore (to find session information in local DB) ) { bool allanchorsequal=true; localstatus sta=LOCERR_OK; // superdatastore has no own anchors, so collect data from subdatastores fFirstTimeSync=false; TSubDSLinkList::iterator pos; for (pos=fSubDSLinks.begin();pos!=fSubDSLinks.end();pos++) { if (pos==fSubDSLinks.begin()) { // Server case note: // Subdatastore's engInitSyncAnchors() MUST NOT be called here, because this routine will // always be called after all subdatastore's engProcessSyncAlert() was called // which in turn contains a call to engInitSyncAnchors(). // Client case note: // Subdatastore's engInitSyncAnchors() MUST NOT be called here, because this routine will // be called from TSuperDataStore::engPrepareClientSyncAlert() after iterating through // subdatastores and calling their engPrepareClientDSForAlert(), which in turn // contains a call to engInitSyncAnchors(). // This means we can safely assume we have the fLastRemoteAnchor/fNextLocalAnchor info // ready here. // - Assign references of first datastore // Note: remote anchor must be same from all subdatastores fLastRemoteAnchor=pos->fDatastoreLinkP->fLastRemoteAnchor; // - these are used from the first datastore, and might differ (a few seconds, // that is) for other datastores fLastLocalAnchor=pos->fDatastoreLinkP->fLastLocalAnchor; fNextLocalAnchor=pos->fDatastoreLinkP->fNextLocalAnchor; } else { // see if all are equal allanchorsequal = allanchorsequal && pos->fDatastoreLinkP->fLastRemoteAnchor == fLastRemoteAnchor; } // also combine firstTimeSync (first time if it's first for any of the subdatastores) fFirstTimeSync = fFirstTimeSync || pos->fDatastoreLinkP->fFirstTimeSync; } // make sure common anchor is valid only if all of the subdatastores have equal anchors if (sta!=LOCERR_OK || fFirstTimeSync || !allanchorsequal) { fLastLocalAnchor.empty(); fLastRemoteAnchor.empty(); } // superdatastore gets adminready when all subdatastores have successfully done engInitSyncAnchors() if (sta==LOCERR_OK) { changeState(dssta_adminready); // admin data is now ready } // return status return sta; } // TSuperDataStore::engInitSyncAnchors // - called at start of first command (prepare DB for reading/writing) bool TSuperDataStore::startSync(TStatusCommand &aStatusCommand) { DEBUGPRINTFX(DBG_HOT,("TSuperDataStore::startSync")); // make sure we start generating with first datastore fCurrentGenDSPos=fSubDSLinks.begin(); // NOTE: Do NOT iterate subdatastores, because these were called already // by engProcessSyncCmd (server case) or engProcessSyncAlert (client case) return true; // ok } // TSuperDataStore::startSync /// check is datastore is completely started. /// @param[in] aWait if set, call will not return until either started state is reached /// or cannot be reached within the maximally allowed request processing time left. bool TSuperDataStore::engIsStarted(bool aWait) { // check subdatastores bool ready=true; TSubDSLinkList::iterator pos; for (pos=fSubDSLinks.begin();pos!=fSubDSLinks.end();pos++) { ready=ready && pos->fDatastoreLinkP->engIsStarted(aWait); } // check myself return ready && inherited::engIsStarted(aWait); } // TSuperDataStore::engIsStarted // remove prefix for given subDatastore // @param[in] aIDWithPrefix points to ID with prefix // @return NULL if either datastore not found or prefix not present in aIDWithPrefix // @return pointer to first char in aIDWithPrefix which is not part of the prefix cAppCharP TSuperDataStore::removeSubDSPrefix(cAppCharP aIDWithPrefix, TLocalEngineDS *aLocalDatastoreP) { if (!aIDWithPrefix) return NULL; TSubDSLinkList::iterator pos; for (pos=fSubDSLinks.begin();pos!=fSubDSLinks.end();pos++) { if (pos->fDatastoreLinkP == aLocalDatastoreP) { // check the prefix if (strnncmp( aIDWithPrefix, pos->fDSLinkConfigP->fGUIDPrefix.c_str(), pos->fDSLinkConfigP->fGUIDPrefix.size() ) ==0) return aIDWithPrefix+pos->fDSLinkConfigP->fGUIDPrefix.size(); // return start of subDS ID else return aIDWithPrefix; // datastore found, but prefix is not there, return unmodified } } return NULL; } // TSuperDataStore::removeSubDSPrefix // private helper: find subdatastore which matches prefix of given localID TSubDatastoreLink *TSuperDataStore::findSubLinkByLocalID(const char *aLocalID) { TSubDSLinkList::iterator pos; for (pos=fSubDSLinks.begin();pos!=fSubDSLinks.end();pos++) { if (strnncmp( aLocalID, pos->fDSLinkConfigP->fGUIDPrefix.c_str(), pos->fDSLinkConfigP->fGUIDPrefix.size() ) ==0) { // found return &(*pos); } } return NULL; // not found } // TSuperDataStore::findSubLinkByLocalID // private helper: find subdatastore which can accept item data TSubDatastoreLink *TSuperDataStore::findSubLinkByData(TSyncItem &aSyncItem) { TSubDSLinkList::iterator pos; for (pos=fSubDSLinks.begin();pos!=fSubDSLinks.end();pos++) { PDEBUGPRINTFX(DBG_DATA+DBG_DETAILS,( "Testing item data against of subdatastore '%s'", pos->fDatastoreLinkP->getName() )); if (aSyncItem.testFilter(pos->fDSLinkConfigP->fDispatchFilter.c_str())) { // found return &(*pos); } } return NULL; // not found } // TSuperDataStore::findSubLinkByData // only dummy, creates error if called bool TSuperDataStore::logicRetrieveItemByID( TSyncItem &aSyncItem, // item to be filled with data from server. Local or Remote ID must already be set TStatusCommand &aStatusCommand // status, must be set on error or non-200-status ) { aStatusCommand.setStatusCode(500); DEBUGPRINTFX(DBG_ERROR,("TSuperDataStore::logicRetrieveItemByID called, which should never happen!!!!!!")); return false; // not ok } // TSuperDataStore::logicRetrieveItemByID // only dummy, creates error if called // - Method takes ownership of syncitemP in all cases bool TSuperDataStore::logicProcessRemoteItem( TSyncItem *syncitemP, TStatusCommand &aStatusCommand, bool &aVisibleInSyncset, // on entry: tells if resulting item SHOULD be visible; on exit: set if processed item remains visible in the sync set. string *aGUID // GUID is stored here if not NULL ) { delete syncitemP; // consume aStatusCommand.setStatusCode(500); DEBUGPRINTFX(DBG_ERROR,("TSuperDataStore::logicProcessRemoteItem called, which should never happen!!!!!!")); return false; // not ok } // TSuperDataStore::logicProcessRemoteItem // - returns true if DB implementation can filter during database fetch // (otherwise, fetched items must be filtered after being read from DB) bool TSuperDataStore::engFilteredFetchesFromDB(bool aFilterChanged) { // only if all subdatastores support it bool yes=true; TSubDSLinkList::iterator pos; for (pos=fSubDSLinks.begin();pos!=fSubDSLinks.end();pos++) { yes = yes && pos->fDatastoreLinkP->engFilteredFetchesFromDB(aFilterChanged); } return yes; } // TSuperDataStore::engFilteredFetchesFromDB // - called for SyncML 1.1 if remote wants number of changes. // Must return -1 if no NOC value can be returned sInt32 TSuperDataStore::getNumberOfChanges(void) { sInt32 noc,totalNoc = 0; TSubDSLinkList::iterator pos; for (pos=fSubDSLinks.begin();pos!=fSubDSLinks.end();pos++) { noc = pos->fDatastoreLinkP->getNumberOfChanges(); if (noc<0) return -1; // if one of the subdatastores does not know NOC, we can't return a NOC // subdatastore knows its NOC, sum up totalNoc+=noc; } // return sum of all NOCs return totalNoc; }; // TSuperDataStore::getNumberOfChanges // show statistics or error of current sync void TSuperDataStore::showStatistics(void) { // show something in debug log PDEBUGPRINTFX(DBG_HOT,("Superdatastore Sync for '%s' (%s), %s sync status:", getName(), fRemoteViewOfLocalURI.c_str(), fSlowSync ? "slow" : "normal" )); // and on user console CONSOLEPRINTF(("")); CONSOLEPRINTF(("- Superdatastore Sync for '%s' (%s), %s sync status:", getName(), fRemoteViewOfLocalURI.c_str(), fSlowSync ? "slow" : "normal" )); // now show results if (isAborted()) { // failed PDEBUGPRINTFX(DBG_ERROR,("Warning: Failed with status code=%hd",fAbortStatusCode)); CONSOLEPRINTF((" ************ Failed with status code=%hd",fAbortStatusCode)); } else { // successful: show statistics on console PDEBUGPRINTFX(DBG_HOT,("Completed successfully - details see subdatastores")); CONSOLEPRINTF((" Completed successfully - details see subdatastores")); } CONSOLEPRINTF(("")); } // TSuperDataStore::showStatistics // - returns true if DB implementation of all subdatastores support resume bool TSuperDataStore::dsResumeSupportedInDB(void) { // yes if all subdatastores support it bool yes=true; TSubDSLinkList::iterator pos; for (pos=fSubDSLinks.begin();pos!=fSubDSLinks.end();pos++) { yes = yes && pos->fDatastoreLinkP->dsResumeSupportedInDB(); } return yes; } // TSuperDataStore::dsResumeSupportedInDB // helper to save resume state either at end of request or explicitly at reception of a "suspend" localstatus TSuperDataStore::engSaveSuspendState(bool aAnyway) { // only save here if not aborted already (aborting saves the state immediately) // or explicitly requested if (aAnyway || !isAborted()) { // only save if DS 1.2 and supported by DB if ((fSessionP->getSyncMLVersion()>=syncml_vers_1_2) && dsResumeSupportedInDB()) { PDEBUGBLOCKFMT(("SuperSaveSuspendState","Saving superdatastore suspend/resume state","superdatastore=%s",getName())); // save alert state fResumeAlertCode=fAlertCode; TSubDSLinkList::iterator pos; if (fResumeAlertCode) { // let all subdatastores update partial item and markOnlyUngeneratedForResume() for (pos=fSubDSLinks.begin();pos!=fSubDSLinks.end();pos++) { // save partial state if any if (pos->fDatastoreLinkP->fPartialItemState!=pi_state_save_outgoing) { // ONLY if we have no request for saving an outgoing item state already, // we possibly need to save a pending incoming item // if there is an incompletely received item, let it update Partial Item (fPIxxx) state // (if it is an item of this datastore, that is). if (fSessionP->fIncompleteDataCommandP) { fSessionP->fIncompleteDataCommandP->updatePartialItemState(pos->fDatastoreLinkP); } } // mark ungenerated pos->fDatastoreLinkP->logicMarkOnlyUngeneratedForResume(); } /// @note that already generated items are related to the originating /// localEngineDS, so markPendingForResume() on existing commands will /// directly reach the correct datastore /// @note markItemForResume() will get the localID as presented to /// remote, that is in case of superdatastores with prefixes that need to be removed fSessionP->markPendingForResume(this); } // let all subdatastores logicSaveResumeMarks() to make all this persistent localstatus globErr=LOCERR_OK; for (pos=fSubDSLinks.begin();pos!=fSubDSLinks.end();pos++) { localstatus err=pos->fDatastoreLinkP->logicSaveResumeMarks(); if (err!=LOCERR_OK) globErr=err; } PDEBUGENDBLOCK("SuperSaveSuspendState"); return globErr; } } return LOCERR_OK; } // TSuperDataStore::engSaveSuspendState #ifdef SYSYNC_SERVER /// @brief called at end of request processing, should be used to save suspend state /// @note subdatastores don't do anything themselves, to make sure superds can make things happen in correct order void TSuperDataStore::engRequestEnded(void) { // variant for superdatastore - also handles its subdatastores // For DS 1.2: Make sure everything is ready for a resume in case there's an abort (implicit Suspend) // before the next request. Note that the we cannot wait for session timeout, as the resume attempt // from the client probably arrives much earlier. if (testState(dssta_syncmodestable)) { // make sure all unsent items are marked for resume localstatus sta=engSaveSuspendState(false); // only if not already aborted if (sta!=LOCERR_OK) { DEBUGPRINTFX(DBG_ERROR,("Could not save suspend state at end of Request: err=%hd",sta)); } } // let datastore prepare for end of request (other than thread change) TSubDSLinkList::iterator pos; for (pos=fSubDSLinks.begin();pos!=fSubDSLinks.end();pos++) { pos->fDatastoreLinkP->dsRequestEnded(); } // then let them know that thread may change for (pos=fSubDSLinks.begin();pos!=fSubDSLinks.end();pos++) { pos->fDatastoreLinkP->dsThreadMayChangeNow(); } } // TSuperDataStore::engRequestEnded #endif // - called to let server generate sync commands for client // Returns true if now finished for this datastore // also sets fState to dss_syncdone when finished bool TSuperDataStore::engGenerateSyncCommands( TSmlCommandPContainer &aNextMessageCommands, TSmlCommand * &aInterruptedCommandP, const char *aLocalIDPrefix ) { PDEBUGBLOCKFMT(("SuperSyncGen","Now generating sync commands from superdatastore","datastore=%s",getName())); bool finished=false; string prefix; while (!isAborted()) { // check for end if (fCurrentGenDSPos==fSubDSLinks.end()) { // done, update status changeState(dssta_syncgendone,true); break; } // create current prefix AssignString(prefix,aLocalIDPrefix); prefix.append(fCurrentGenDSPos->fDSLinkConfigP->fGUIDPrefix); // call subdatastore to generate commands finished=fCurrentGenDSPos->fDatastoreLinkP->engGenerateSyncCommands( aNextMessageCommands, aInterruptedCommandP, prefix.c_str() ); // exit if not yet finished with generating commands for this datastore if (!finished) break; // done with this datastore, switch to next if any fCurrentGenDSPos++; } // while not aborted // finished when state is dss_syncdone PDEBUGPRINTFX(DBG_DATA,( "superdatastore's engGenerateSyncCommands ended, state='%s', sync generation %sdone", getDSStateName(), dbgTestState(dssta_syncgendone,true) ? "" : "NOT " )); PDEBUGENDBLOCK("SuperSyncGen"); // also finished with this datastore when aborted return (isAborted() || testState(dssta_syncgendone,true)); } // TSuperDataStore::generateSyncCommands #ifdef SYSYNC_CLIENT // Client only: initialize Sync alert for datastore according to Parameters set with dsSetClientSyncParams() localstatus TSuperDataStore::engPrepareClientSyncAlert(void) { localstatus sta; // not resuming by default fResuming = false; fResumeAlertCode = 0; // prepare all subdatastores that were parametrized to participate in a sync by dsSetClientSyncParams() TSubDSLinkList::iterator pos; for (pos=fSubDSLinks.begin();pos!=fSubDSLinks.end();pos++) { TLocalEngineDS *dsP = pos->fDatastoreLinkP; if (dsP->testState(dssta_clientparamset)) { // configured for sync, prepare for alert sta = dsP->engPrepareClientDSForAlert(); if (sta!=LOCERR_OK) return sta; // error // collect slow sync status fSlowSync = fSlowSync || dsP->fSlowSync; // collect resume alert code if (dsP->fResuming) { // subdatastore would like to resume if (fResumeAlertCode!=0 && fResumeAlertCode!=dsP->fResumeAlertCode) { // different idea about what to resume -> can't resume PDEBUGPRINTFX(DBG_ERROR,("subdatastores differ in resume alert code -> cancel resume of superdatastore")); fResuming = false; } else { // resume is possible (but might be cancelled if another subdatastore disagrees fResumeAlertCode = dsP->fResumeAlertCode; fResuming = true; } } } } // now init my own anchors and firstsync state, which are a combination of my subdatastore's sta = engInitSyncAnchors(NULL,NULL); if (sta!=LOCERR_OK) return sta; // error // determine final resume state if (fResuming) { PDEBUGPRINTFX(DBG_PROTO,("Found suspended session with Alert Code = %hd for all subdatastores",fResumeAlertCode)); } else { // superdatastore can't resume, cancel all subdatastore's resumes that might be set for (pos=fSubDSLinks.begin();pos!=fSubDSLinks.end();pos++) { pos->fDatastoreLinkP->fResuming = false; } } // all successful return LOCERR_OK; } // TSuperDataStore::engPrepareClientSyncAlert // Init engine for client sync // - determine types to exchange // - make sync set ready localstatus TSuperDataStore::engInitForClientSync(void) { localstatus sta = LOCERR_OK; // first let all subdatastores init for sync TSubDSLinkList::iterator pos; for (pos=fSubDSLinks.begin();pos!=fSubDSLinks.end();pos++) { sta = pos->fDatastoreLinkP->engInitDSForClientSync(); if (sta!=LOCERR_OK) return sta; } // now change my own state return inherited::engInitDSForClientSync(); } // TSuperDataStore::engInitForClientSync // Client only: returns number of unsent map items sInt32 TSuperDataStore::numUnsentMaps(void) { // add maps from all subdatastores uInt32 num=0; TSubDSLinkList::iterator pos; for (pos=fSubDSLinks.begin();pos!=fSubDSLinks.end();pos++) { num+=pos->fDatastoreLinkP->numUnsentMaps(); } return num; } // TSuperDataStore::numUnsentMaps // called to mark maps confirmed, that is, we have received ok status for them void TSuperDataStore::engMarkMapConfirmed(cAppCharP aLocalID, cAppCharP aRemoteID) { // we must detect the subdatastore by prefix TSubDatastoreLink *linkP = findSubLinkByLocalID(aLocalID); if (linkP) { // pass to subdatastore with prefix removed linkP->fDatastoreLinkP->engMarkMapConfirmed(aLocalID+linkP->fDSLinkConfigP->fGUIDPrefix.size(),aRemoteID); } } // TSuperDataStore::engMarkMapConfirmed // - client only: called to generate Map items // Returns true if now finished for this datastore // also sets fState to dss_done when finished bool TSuperDataStore::engGenerateMapItems(TMapCommand *aMapCommandP, cAppCharP aLocalIDPrefix) { TSubDSLinkList::iterator pos=fSubDSLinks.begin(); bool ok; string prefix; PDEBUGBLOCKDESC("SuperMapGenerate","TSuperDataStore: Generating Map items..."); do { // check if already done if (pos==fSubDSLinks.end()) break; // done // create current prefix AssignString(prefix,aLocalIDPrefix); prefix.append(pos->fDSLinkConfigP->fGUIDPrefix); // generate Map items ok=pos->fDatastoreLinkP->engGenerateMapItems(aMapCommandP,prefix.c_str()); // exit if not yet finished with generating map items for this datastore if (!ok) { PDEBUGENDBLOCK("MapGenerate"); return false; // not all map items generated } // next datastore pos++; } while(true); // done // we are done if state is syncdone (no more sync commands will occur) if (testState(dssta_dataaccessdone)) { changeState(dssta_clientmapssent,true); PDEBUGPRINTFX(DBG_PROTO,("TSuperDataStore: Finished generating Map items, server has finished , we are done now")) } #ifdef SYDEBUG // else if we are not yet dssta_syncgendone -> this is the end of a early pending map send else if (!dbgTestState(dssta_syncgendone)) { PDEBUGPRINTFX(DBG_PROTO,("TSuperDataStore: Finished sending cached Map items from last session")) } // otherwise, we are not really finished with the maps yet (but with the current map command) else { PDEBUGPRINTFX(DBG_PROTO,("TSuperDataStore: Finished generating Map items for now, but server still sending ")) } #endif PDEBUGENDBLOCK("MapGenerate"); return true; } // TSuperDataStore::engGenerateMapItems #endif // SYSYNC_CLIENT /* end of TSuperDataStore implementation */ #endif // SUPERDATASTORES // eof libsynthesis-3.4.0.47.1/src/sysync/superdatastore.h000077500000000000000000000352421226375725500222120ustar00rootroot00000000000000/* * File: SuperDataStore.h * * Author: Lukas Zeller (luz@plan44.ch) * * TSuperDataStore * "Virtual" datastore consisting of an union of other * datastores, for example a vCal datastore based on * two separate vEvent and vTodo datastores. * * Copyright (c) 2002-2011 by Synthesis AG + plan44.ch * * 2002-08-05 : luz : created * */ #ifndef SuperDataStore_H #define SuperDataStore_H // includes #include "configelement.h" #include "syncitem.h" #include "localengineds.h" #ifdef SUPERDATASTORES using namespace sysync; namespace sysync { class TSuperDataStore; // forward #ifndef OBJECT_FILTERING #error "SUPERDATASTORE needs OBJECT_FILTERING" #endif // sub-datastore (contained datastore) link config class TSubDSLinkConfig: public TConfigElement { typedef TConfigElement inherited; public: TSubDSLinkConfig(TLocalDSConfig *aLocalDSConfigP, TConfigElement *aParentElement); virtual ~TSubDSLinkConfig(); // properties // - filter applied to test if incoming item is to be processed // by this datastore string fDispatchFilter; // - GUID prefix to create super-GUIDs out of individual datastore GUIDs string fGUIDPrefix; // - linked datastore's config TLocalDSConfig *fLinkedDSConfigP; // - reset config to defaults virtual void clear(); protected: // check config elements #ifndef HARDCODED_CONFIG virtual bool localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine); #endif }; // TSubDSLinkConfig typedef std::list TSubDSConfigList; // sub-datastore link typedef struct { TLocalEngineDS *fDatastoreLinkP; TSubDSLinkConfig *fDSLinkConfigP; bool fStartPending; } TSubDatastoreLink; typedef std::list TSubDSLinkList; // super datastore config class TSuperDSConfig: public TLocalDSConfig { typedef TLocalDSConfig inherited; public: TSuperDSConfig(const char* aName, TConfigElement *aParentElement); virtual ~TSuperDSConfig(); // properties // - contained subdatastores TSubDSConfigList fSubDatastores; // public methods // - create appropriate datastore from config, including creating links to subdatastores virtual TLocalEngineDS *newLocalDataStore(TSyncSession *aSessionP); // - reset config to defaults virtual void clear(); protected: // check config elements #ifndef HARDCODED_CONFIG virtual bool localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine); #endif virtual void localResolve(bool aLastPass); }; // TSuperDSConfig class TSuperDataStore: public TLocalEngineDS { typedef TLocalEngineDS inherited; private: void InternalResetDataStore(void); // reset for re-use without re-creation public: TSuperDataStore(TSuperDSConfig *aDSConfigP, TSyncSession *aSessionP, const char *aName, uInt32 aCommonSyncCapMask=0); virtual ~TSuperDataStore(); virtual void dsResetDataStore(void) { InternalResetDataStore(); inherited::dsResetDataStore(); }; // add links to subdatastores void addSubDatastoreLink(TSubDSLinkConfig *aDSLinkConfigP, TLocalEngineDS *aDatastoreP); // abort virtual void engAbortDataStoreSync(TSyError aReason, bool aLocalProblem, bool aResumable=true); virtual bool isAborted(void); // test abort status // Sync operation Methods overriding TLocalEngineDS (which need some distribution to subdatastores) // - process Sync alert for a datastore virtual TAlertCommand *engProcessSyncAlert( TSuperDataStore *aAsSubDatastoreOf, // if acting as subdatastore uInt16 aAlertCode, // the alert code const char *aLastRemoteAnchor, // last anchor of client const char *aNextRemoteAnchor, // next anchor of client const char *aTargetURI, // target URI as sent by remote, no processing at all const char *aIdentifyingTargetURI, // target URI that was used to identify datastore const char *aTargetURIOptions, // option string contained in target URI SmlFilterPtr_t aTargetFilter, ///< DS 1.2 filter, NULL if none const char *aSourceURI, // source URI TStatusCommand &aStatusCommand // status that might be modified ); // - process status received for sync alert virtual bool engHandleAlertStatus(TSyError aStatusCode); // - Set remote datastore for local virtual void engSetRemoteDatastore(TRemoteDataStore *aRemoteDatastoreP); // - set Sync types needed for sending local data to remote DB virtual void setSendTypeInfo( TSyncItemType *aLocalSendToRemoteTypeP, TSyncItemType *aRemoteReceiveFromLocalTypeP); // - set Sync types needed for receiving remote data in local DB virtual void setReceiveTypeInfo( TSyncItemType *aLocalReceiveFromRemoteTypeP, TSyncItemType *aRemoteSendToLocalTypeP); // - init usage of datatypes set with setSendTypeInfo/setReceiveTypeInfo virtual localstatus initDataTypeUse(void); // - SYNC command bracket start (check credentials if needed) virtual bool engProcessSyncCmd(SmlSyncPtr_t aSyncP,TStatusCommand &aStatusCommand,bool &aQueueForLater); // - SYNC command bracket end (but another might follow in next message) virtual bool engProcessSyncCmdEnd(bool &aQueueForLater); // - called to process incoming item operation. // Method must take ownership of syncitemP in all cases virtual bool engProcessRemoteItem( TSyncItem *syncitemP, TStatusCommand &aStatusCommand ); #ifdef SYSYNC_SERVER // - called to process map commands from client to server virtual localstatus engProcessMap(cAppCharP aRemoteID, cAppCharP aLocalID); #endif // - must return true if this datastore is finished with // (if all datastores return true, // session is allowed to finish sync packet with outgoing message virtual bool isSyncDone(void); // - called at very end of sync session, when everything is done virtual void engFinishDataStoreSync(localstatus aErrorStatus=LOCERR_OK); // Abstracts of TLocalEngineDS protected: // check if all subdatastores can restart bool canRestart(); // obtain Sync Cap mask, must be lowest common mask of all subdatastores virtual uInt32 getSyncCapMask(void); // intersection of all sync mode sets in the subdatastores virtual bool syncModeSupported(const std::string &mode); virtual void getSyncModes(set &modes); // Internal events during sync for derived classes // Note: local DB authorisation must be established already before calling these // - prepares for Sync with this datastore // - updates fLastRemoteAnchor,fNextRemoteAnchor,fLastLocalAnchor,fNextLocalAnchor // - called at sync alert, obtains anchor information from local DB // (abstract, must be implemented in derived class) virtual localstatus engInitSyncAnchors( cAppCharP aDatastoreURI, // local datastore URI cAppCharP aRemoteDBID // ID of remote datastore (to find session information in local DB) ); // - called at start of first command (prepare DB for reading/writing) virtual bool startSync(TStatusCommand &aStatusCommand); /// check is datastore is completely started. /// @param[in] aWait if set, call will not return until either started state is reached /// or cannot be reached within the maximally allowed request processing time left. virtual bool engIsStarted(bool aWait); // - only dummy, creates error if called virtual bool logicRetrieveItemByID( TSyncItem &aSyncItem, // item to be filled with data from server. Local or Remote ID must already be set TStatusCommand &aStatusCommand // status, must be set on error or non-200-status ); // - only dummy, creates error if called virtual bool logicProcessRemoteItem( TSyncItem *syncitemP, TStatusCommand &aStatusCommand, bool &aVisibleInSyncset, // on entry: tells if resulting item SHOULD be visible; on exit: set if processed item remains visible in the sync set. string *aGUID=NULL // GUID is stored here if not NULL ); // - returns true if DB implementation can filter during database fetch // (otherwise, fetched items will be filtered after being read from DB) virtual bool engFilteredFetchesFromDB(bool aFilterChanged=false); // - called for SyncML 1.1 if remote wants number of changes. // Must return -1 if no NOC value can be returned virtual sInt32 getNumberOfChanges(void); // - called to show sync statistics in debug log and on console SUPERDS_VIRTUAL void showStatistics(void); // - called to generate sync sub-commands // Returns true if now finished for this datastore // also sets fState to dss_syncdone(server)/dss_syncready(client) when finished virtual bool engGenerateSyncCommands( TSmlCommandPContainer &aNextMessageCommands, TSmlCommand * &aInterruptedCommandP, const char *aLocalIDPrefix ); // Suspend/Resume // - helper to save resume state either at end of request or explicitly at reception of a "suspend" // (overridden only by superdatastore) virtual localstatus engSaveSuspendState(bool aAnyway); // - returns true if DB implementation supports resume (saving of resume marks, alert code, pending maps, tempGUIDs) virtual bool dsResumeSupportedInDB(void); #ifdef SYSYNC_CLIENT // Client only: initialize Sync alert for datastore according to Parameters set with dsSetClientSyncParams() /// @note initializes anchors and makes calls to isFirstTimeSync() valid virtual localstatus engPrepareClientSyncAlert(void); // Client only: init engine for client sync (superdatastore aware) virtual localstatus engInitForClientSync(void); // Client only: called to generate Map items // - Returns true if now finished for this datastore // - also sets fState to dss_done when finished virtual bool engGenerateMapItems(TMapCommand *aMapCommandP, cAppCharP aLocalIDPrefix); // Client only: returns number of unsent map items virtual sInt32 numUnsentMaps(void); /// client: called to generate sync sub-commands to be sent to server /// Returns true if now finished for this datastore /// also sets fState to dss_syncdone(server)/dss_syncready(client) when finished virtual bool logicGenerateSyncCommandsAsClient( TSmlCommandPContainer &aNextMessageCommands, TSmlCommand * &aInterruptedCommandP, const char *aLocalIDPrefix=NULL ) { return LOCERR_NOTIMP; }; // Client only: called to mark maps confirmed, that is, we have received ok status for them virtual void engMarkMapConfirmed(cAppCharP aLocalID, cAppCharP aRemoteID); #endif // SYSYNC_CLIENT #ifdef SYSYNC_SERVER // Server only: /// server: called to generate sync sub-commands to be sent to client /// Returns true if now finished for this datastore /// also sets fState to dss_syncdone(server)/dss_syncready(client) when finished virtual bool logicGenerateSyncCommandsAsServer( TSmlCommandPContainer &aNextMessageCommands, TSmlCommand * &aInterruptedCommandP, const char *aLocalIDPrefix=NULL ) { return LOCERR_NOTIMP; }; // - only dummy, creates error if called virtual localstatus logicProcessMap(cAppCharP aRemoteID, cAppCharP aLocalID) { return false; }; // dummy, should never be called // - called at end of request processing in server virtual void engRequestEnded(void); // Dummies, should never be called in Superdatastore, as all DB processing takes // place in subdatastores // - check if conflicting item already exist in list of items-to-be-sent-to-client virtual TSyncItem *getConflictingItemByRemoteID(TSyncItem *syncitemP) { return NULL; }; virtual TSyncItem *getConflictingItemByLocalID(TSyncItem *syncitemP) { return NULL; }; // - called to check if content-matching item from server exists virtual TSyncItem *getMatchingItem(TSyncItem *syncitemP, TEqualityMode aEqMode) { return NULL; }; // - called to prevent item to be sent to client in subsequent engGenerateSyncCommands() // item in question should be an item that was returned by getConflictingItemByRemoteID() or getMatchingItem() virtual void dontSendItemAsServer(TSyncItem *syncitemP) {}; // - called when a item in the sync set changes its localID (due to local DB internals) // NOTE: this is not called for superdatastores, only real datastores, so it's NOP here virtual void dsLocalIdHasChanged(const char *aOldID, const char *aNewID) {}; // - called to have additional item sent to remote (DB takes ownership of item) virtual void SendItemAsServer(TSyncItem *aSyncitemP) {}; #endif // SYSYNC_SERVER /// called to have all non-yet-generated sync commands as "to-be-resumed" virtual void logicMarkOnlyUngeneratedForResume(void) {}; /// called to mark an already generated (but probably not sent or not yet statused) item /// as "to-be-resumed", by localID or remoteID (latter only in server case). /// @note This must be repeatable without side effects, as server must mark/save suspend state /// after every request (and not just at end of session) virtual void logicMarkItemForResume(cAppCharP aLocalID, cAppCharP aRemoteID, bool aUnSent) {}; /// called to mark an already generated (but probably not sent or not yet statused) item /// as "to-be-resumed", by localID or remoteID (latter only in server case). /// @note This must be repeatable without side effects, as server must mark/save suspend state /// after every request (and not just at end of session) virtual void logicMarkItemForResend(cAppCharP aLocalID, cAppCharP aRemoteID) {}; /// save status information required to possibly perform a resume (as passed to datastore with /// markOnlyUngeneratedForResume() and markItemForResume()) /// (or, in case the session is really complete, make sure that no resume state is left) /// @note Must also save tempGUIDs (for server) and pending/unconfirmed maps (for client) virtual localstatus logicSaveResumeMarks(void) { return LOCERR_NOTIMP; }; // must be derived (or avoided, as in superdatastore) public: /// remove prefix for given subDatastore /// @param[in] aIDWithPrefix points to ID with prefix /// @return NULL if not found /// @return pointer to first char in aIDWithPrefix which is not part of the prefix cAppCharP removeSubDSPrefix(cAppCharP aIDWithPrefix, TLocalEngineDS *aLocalDatastoreP); private: // find subdatastore which matches prefix of given localID TSubDatastoreLink *findSubLinkByLocalID(const char *aLocalID); // find subdatastore which can accept item data TSubDatastoreLink *findSubLinkByData(TSyncItem &aSyncItem); /** @deprecated moved to localEngineDS // combined first-time sync flag (collected from subdatastores) bool fFirstTimeSync; */ // this flag is set at alert and cleared after all subdatastores have fully initialized bool fSuperStartPending; // list of subdatastores TSubDSLinkList fSubDSLinks; // currently generating subdatastore TSubDSLinkList::iterator fCurrentGenDSPos; }; // TSuperDataStore } // namespace sysync #endif // SUPERDATASTORES #endif // SuperDataStore_H // eof libsynthesis-3.4.0.47.1/src/sysync/syncagent.cpp000077500000000000000000004422231226375725500214740ustar00rootroot00000000000000/* * File: syncagent.cpp * * Author: Lukas Zeller (luz@plan44.ch) * * TSyncAgent: Provides functionality to run client or server * sessions. * Unifies former TSyncClient and TSyncServer * * Copyright (c) 2002-2011 by Synthesis AG + plan44.ch * * 2009-09-30 : luz : created from syncclient.cpp and syncserver.cpp * */ // includes #include "prefix_file.h" #include "sysync.h" #include "syncagent.h" #include "syncappbase.h" #ifdef HARD_CODED_SERVER_URI #include "syserial.h" #endif // includes that can't be in .h due to circular references #ifdef SYSYNC_SERVER #include "syncsessiondispatch.h" #endif #ifdef SYSYNC_CLIENT #include "syncclientbase.h" #endif #ifdef SYSYNC_TOOL #include #endif namespace sysync { #ifdef SYSYNC_TOOL // Support for SySync Diagnostic Tool // ================================== // test login into database int testLogin(int argc, const char *argv[]) { if (argc<0) { // help requested CONSOLEPRINTF((" login [ ] []")); CONSOLEPRINTF((" test login to database with syncml user/password and optional deviceid")); return EXIT_SUCCESS; } TSyncSession *sessionP = NULL; const char *username = NULL; const char *password = NULL; const char *deviceid = "sysytool_test"; // check for argument if (argc<2) { // no user/password, test anonymous login if (argc>0) deviceid = argv[0]; } else { // login with user/password username = argv[0]; password = argv[1]; if (argc>2) { // explicit device ID deviceid = argv[2]; } } // get session to work with sessionP = static_cast(getSyncAppBase())->getSySyToolSession(); bool authok = false; // try login if (username) { // real login with user and password authok = sessionP->SessionLogin(username, password, sectyp_clearpass, deviceid); } else { // anonymous - do a "login" with empty credentials authok = sessionP->SessionLogin("anonymous", NULL, sectyp_anonymous, deviceid); } if (authok) { CONSOLEPRINTF(("+++++ Successfully authorized")); } else { CONSOLEPRINTF(("----- Authorisation failed")); } return authok; } // testLogin // convert user data into internal format and back int convertData(int argc, const char *argv[]) { if (argc<0) { // help requested CONSOLEPRINTF((" convert [] []")); CONSOLEPRINTF((" Convert data to internal format of specified datastore and back")); return EXIT_SUCCESS; } TSyncSession *sessionP = NULL; const char *datastore = NULL; const char *rawfilename = NULL; const char *inputtype = NULL; const char *outputtype = NULL; // check for argument if (argc<2) { CONSOLEPRINTF(("required datatype name and raw file name arguments")); return EXIT_FAILURE; } datastore = argv[0]; rawfilename = argv[1]; if (argc>=3) { // third arg is explicit input type inputtype=argv[2]; } outputtype=inputtype; // default to input type if (argc>=4) { // fourth arg is explicit output type outputtype=argv[3]; } // get session to work with sessionP = static_cast(getSyncAppBase())->getSySyToolSession(); // configure session sessionP->fRemoteCanHandleUTC = true; // run generator and parser in UTC enabled mode // switch mimimal debugging on sessionP->getDbgLogger()->setMask(sessionP->getDbgLogger()->getMask() | (DBG_PARSE+DBG_GEN)); // find datastore TLocalEngineDS *datastoreP = sessionP->findLocalDataStore(datastore); TSyncItemType *inputtypeP = NULL; TSyncItemType *outputtypeP = NULL; if (!datastoreP) { CONSOLEPRINTF(("datastore type '%s' not found",datastore)); return EXIT_FAILURE; } // find input type if (inputtype) { // search in datastore inputtypeP=datastoreP->getReceiveType(inputtype,NULL); } else { // use preferred rx type inputtypeP=datastoreP->getPreferredRxItemType(); } if (!inputtypeP) { CONSOLEPRINTF(("input type not found")); return EXIT_FAILURE; } // find output type if (outputtype) { // search in datastore outputtypeP=datastoreP->getSendType(outputtype,NULL); } else { // use preferred rx type outputtypeP=datastoreP->getPreferredTxItemType(); } if (!outputtypeP) { CONSOLEPRINTF(("output type not found")); return EXIT_FAILURE; } // prepare type usage if (inputtypeP==outputtypeP) inputtypeP->initDataTypeUse(datastoreP, true, true); else { inputtypeP->initDataTypeUse(datastoreP, false, true); outputtypeP->initDataTypeUse(datastoreP, true, false); } // now open file and read data item FILE *infile; size_t insize=0; uInt8 *databuffer; infile = fopen(rawfilename,"rb"); if (!infile) { CONSOLEPRINTF(("Cannot open input file '%s' (%d)",rawfilename,errno)); return EXIT_FAILURE; } // - get size of file fseek(infile,0,SEEK_END); insize=ftell(infile); fseek(infile,0,SEEK_SET); // - create buffer of appropriate size databuffer = new uInt8[insize]; if (!databuffer) { CONSOLEPRINTF(("Not enough memory to read input file '%s' (%d)",rawfilename,errno)); return EXIT_FAILURE; } // - read data if (fread(databuffer,1,insize,infile)data=newPCDataStringX(databuffer,true,insize); delete[] databuffer; // create and fill a Sync item TSyncItem *syncitemP = inputtypeP->newSyncItem( smlitemP, // SyncML toolkit item Data to be converted into SyncItem sop_replace, // the operation to be performed with this item fmt_chr, // assume default (char) format inputtypeP, // target myself datastoreP, // local datastore statusCmd // status command that might be modified in case of error ); // forget SyncML version smlFreeItemPtr(smlitemP); if (!syncitemP) { CONSOLEPRINTF(("Error converting input file to internal format (SyncML status code=%hd)",statusCmd.getStatusCode())); return EXIT_FAILURE; } CONSOLEPRINTF(("\nNow copying item and convert back to transport format\n")); // make new for output type TSyncItem *outsyncitemP = outputtypeP->newSyncItem( outputtypeP, // target myself datastoreP // local datastore ); // copy data outsyncitemP->replaceDataFrom(*syncitemP); delete syncitemP; // convert back smlitemP=outputtypeP->newSmlItem( outsyncitemP, // the syncitem to be represented as SyncML datastoreP // local datastore ); if (!syncitemP) { CONSOLEPRINTF(("Could not convert back item data")); return EXIT_FAILURE; } // forget converted back item smlFreeItemPtr(smlitemP); return EXIT_SUCCESS; } // convertData #endif // SYSYNC_TOOL #ifdef PRECONFIGURED_SYNCREQUESTS // Implementation of TSyncReqConfig // ================================ // config for databases to sync with TSyncReqConfig::TSyncReqConfig(TLocalDSConfig *aLocalDSCfg, TConfigElement *aParentElement) : TConfigElement("syncrequest",aParentElement), fLocalDSConfig(aLocalDSCfg) { clear(); } // TSyncReqConfig::TSyncReqConfig TSyncReqConfig::~TSyncReqConfig() { // nop so far } // TSyncReqConfig::~TSyncReqConfig // init defaults void TSyncReqConfig::clear(void) { // init defaults // - local client datatstore subselection path or CGI (such as "test" in "contact/test") fLocalPathExtension.erase(); // - remote server DB layer auth fDBUser.erase(); fDBPassword.erase(); // - remote server datastore path fServerDBPath.erase(); // - sync mode fSyncMode=smo_twoway; fSlowSync=false; // default to non-slow // - DS 1.2 filtering parameters fRecordFilterQuery.erase(); fFilterInclusive=false; // clear inherited inherited::clear(); } // TSyncReqConfig::clear // config element parsing bool TSyncReqConfig::localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine) { // checking the elements if (strucmp(aElementName,"localpathextension")==0) expectString(fLocalPathExtension); else if (strucmp(aElementName,"dbuser")==0) expectString(fDBUser); else if (strucmp(aElementName,"dbpassword")==0) expectString(fDBPassword); else if (strucmp(aElementName,"dbpath")==0) expectString(fServerDBPath); else if (strucmp(aElementName,"syncmode")==0) expectEnum(sizeof(fSyncMode),&fSyncMode,SyncModeNames,numSyncModes); else if (strucmp(aElementName,"slowsync")==0) expectBool(fSlowSync); else if (strucmp(aElementName,"recordfilter")==0) expectString(fRecordFilterQuery); else if (strucmp(aElementName,"filterinclusive")==0) expectBool(fFilterInclusive); // - none known here else return inherited::localStartElement(aElementName,aAttributes,aLine); // ok return true; } // TSyncReqConfig::localStartElement // resolve void TSyncReqConfig::localResolve(bool aLastPass) { if (aLastPass) { // check for required settings // %%% tbd } // resolve inherited inherited::localResolve(aLastPass); } // TSyncReqConfig::localResolve // create appropriate type of local datastore from config and init sync parameters TLocalEngineDS *TSyncReqConfig::initNewLocalDataStore(TSyncSession *aSessionP) { // - create appropriate type of localdsP TLocalEngineDS *localdsP = fLocalDSConfig->newLocalDataStore(aSessionP); // - set parameters localdsP->dsSetClientSyncParams( fSyncMode, fSlowSync, fServerDBPath.c_str(), fDBUser.c_str(), fDBPassword.c_str(), fLocalPathExtension.c_str(), fRecordFilterQuery.c_str(), fFilterInclusive ); return localdsP; } // TSyncReqConfig::initNewLocalDataStore #endif // PRECONFIGURED_SYNCREQUESTS // Implementation of TAgentConfig // ============================== TAgentConfig::TAgentConfig(const char* aName, TConfigElement *aParentElement) : inherited(aName,aParentElement) { clear(); } // TAgentConfig::TAgentConfig TAgentConfig::~TAgentConfig() { clear(); } // TAgentConfig::~TAgentConfig // init defaults void TAgentConfig::clear(void) { // clear inherited inherited::clear(); // Note: we always clear both client and server fields - even if we'll only use one set later #ifdef SYSYNC_CLIENT // init client auth defaults (note that these MUST correspond with the defaults set by loadRemoteParams() !!! fAssumedServerAuth=auth_none; // start with no auth fAssumedServerAuthEnc=fmt_chr; // start with char encoding fAssumedNonce.erase(); // start with no nonce fPreferSlowSync=true; // auth retry options (mainly for stupid servers like SCTS) #ifdef SCTS_COMPATIBILITY_HACKS fNewSessionForAuthRetry=false; fNoRespURIForAuthRetry=false; #else fNewSessionForAuthRetry=true; // all production Synthesis clients had it hardcoded (ifdeffed) this way until 2.9.8.7 fNoRespURIForAuthRetry=true; // all production Synthesis clients had it hardcoded (ifdeffed) this way until 2.9.8.7 #endif fSmartAuthRetry=true; // try to be smart and try different auth retry (different from fNewSessionForAuthRetry/fNoRespURIForAuthRetry) if first attempts fail // other defaults fPutDevInfAtSlowSync=true; // smartner server needs it, and it does not harm so we have it on by default #ifndef NO_LOCAL_DBLOGIN fLocalDBUser.erase(); fLocalDBPassword.erase(); fNoLocalDBLogin=false; #endif #ifdef PRECONFIGURED_SYNCREQUESTS fEncoding=SML_XML; // default to more readable XML fServerUser.erase(); fServerPassword.erase(); fServerURI.erase(); fTransportUser.erase(); fTransportPassword.erase(); fSocksHost.erase(); fProxyHost.erase(); fProxyUser.erase(); fProxyPassword.erase(); // remove sync db specifications TSyncReqList::iterator pos; for(pos=fSyncRequests.begin();pos!=fSyncRequests.end();pos++) delete *pos; fSyncRequests.clear(); #endif // clear inherited inherited::clear(); // modify timeout after inherited sets it fSessionTimeout=DEFAULT_CLIENTSESSIONTIMEOUT; // SyncML version support fAssumedServerVersion=MAX_SYNCML_VERSION; // try with highest version we support fMaxSyncMLVersionSupported=MAX_SYNCML_VERSION; // support what we request (overrides session default) #endif #ifdef SYSYNC_SERVER // init server defaults fRequestedAuth = auth_md5; fRequiredAuth = auth_md5; fAutoNonce = true; fConstantNonce.erase(); fExternalURL.erase(); fMaxGUIDSizeSent = 32; // reasonable size, but prevent braindamaged Exchange-size IDs to be sent fUseRespURI = true; fRespURIOnlyWhenDifferent = true; // modify timeout after inherited sets it fSessionTimeout=DEFAULT_SERVERSESSIONTIMEOUT; #endif } // TAgentConfig::clear #ifndef HARDCODED_CONFIG // config element parsing bool TAgentConfig::localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine) { if (IS_CLIENT) { // check the client elements #ifdef SYSYNC_CLIENT // - defaults for starting a session if (strucmp(aElementName,"defaultsyncmlversion")==0) expectEnum(sizeof(fAssumedServerVersion),&fAssumedServerVersion,SyncMLVersionNames,numSyncMLVersions); else if (strucmp(aElementName,"defaultauth")==0) expectEnum(sizeof(fAssumedServerAuth),&fAssumedServerAuth,authTypeNames,numAuthTypes); else if (strucmp(aElementName,"defaultauthencoding")==0) expectEnum(sizeof(fAssumedServerAuthEnc),&fAssumedServerAuthEnc,encodingFmtSyncMLNames,numFmtTypes); else if (strucmp(aElementName,"defaultauthnonce")==0) expectString(fAssumedNonce); else if (strucmp(aElementName,"preferslowsync")==0) expectBool(fPreferSlowSync); else if (strucmp(aElementName,"newsessionforretry")==0) expectBool(fNewSessionForAuthRetry); else if (strucmp(aElementName,"originaluriforretry")==0) expectBool(fNoRespURIForAuthRetry); else if (strucmp(aElementName,"smartauthretry")==0) expectBool(fSmartAuthRetry); // - other options else if (strucmp(aElementName,"putdevinfatslowsync")==0) expectBool(fPutDevInfAtSlowSync); else if (strucmp(aElementName,"fakedeviceid")==0) expectString(fFakeDeviceID); else #ifndef NO_LOCAL_DBLOGIN if (strucmp(aElementName,"localdbuser")==0) expectString(fLocalDBUser); else if (strucmp(aElementName,"localdbpassword")==0) expectString(fLocalDBPassword); else if (strucmp(aElementName,"nolocaldblogin")==0) expectBool(fNoLocalDBLogin); else #endif // serverURL is always available to allow define fixed URL in config that can't be overridden in profiles if (strucmp(aElementName,"serverurl")==0) expectString(fServerURI); else #ifdef PRECONFIGURED_SYNCREQUESTS if (strucmp(aElementName,"syncmlencoding")==0) expectEnum(sizeof(fEncoding),&fEncoding,SyncMLEncodingNames,numSyncMLEncodings); else if (strucmp(aElementName,"serveruser")==0) expectString(fServerUser); else if (strucmp(aElementName,"serverpassword")==0) expectString(fServerPassword); else if (strucmp(aElementName,"sockshost")==0) expectString(fSocksHost); else if (strucmp(aElementName,"proxyhost")==0) expectString(fProxyHost); else if (strucmp(aElementName,"proxyuser")==0) expectString(fProxyUser); else if (strucmp(aElementName,"proxypassword")==0) expectString(fProxyPassword); else if (strucmp(aElementName,"transportuser")==0) expectString(fTransportUser); else if (strucmp(aElementName,"transportpassword")==0) expectString(fTransportPassword); // - Sync DB specification else if (strucmp(aElementName,"syncrequest")==0) { // definition of a new datastore const char* nam = getAttr(aAttributes,"datastore"); if (!nam) { ReportError(true,"syncrequest missing 'datastore' attribute"); } else { // search datastore TLocalDSConfig *localDSCfgP = getLocalDS(nam); if (!localDSCfgP) return fail("unknown local datastore '%s' specified",nam); // create new syncDB config linked to that datastore TSyncReqConfig *syncreqcfgP = new TSyncReqConfig(localDSCfgP,this); // - save in list fSyncRequests.push_back(syncreqcfgP); // - let element handle parsing expectChildParsing(*syncreqcfgP); } } else #endif // - none known here return inherited::localStartElement(aElementName,aAttributes,aLine); #endif // SYSYNC_CLIENT } else { #ifdef SYSYNC_SERVER // check the server elements if (strucmp(aElementName,"requestedauth")==0) expectEnum(sizeof(fRequestedAuth),&fRequestedAuth,authTypeNames,numAuthTypes); else if (strucmp(aElementName,"requiredauth")==0) expectEnum(sizeof(fRequiredAuth),&fRequiredAuth,authTypeNames,numAuthTypes); // here to maintain compatibility with old pre 1.0.5.3 config files else if (strucmp(aElementName,"reqiredauth")==0) expectEnum(sizeof(fRequiredAuth),&fRequiredAuth,authTypeNames,numAuthTypes); else if (strucmp(aElementName,"autononce")==0) expectBool(fAutoNonce); else if (strucmp(aElementName,"constantnonce")==0) expectString(fConstantNonce); else if (strucmp(aElementName,"externalurl")==0) expectString(fExternalURL); else if (strucmp(aElementName,"maxguidsizesent")==0) expectUInt16(fMaxGUIDSizeSent); else if (strucmp(aElementName,"sendrespuri")==0) expectBool(fUseRespURI); else if (strucmp(aElementName,"respurionlywhendifferent")==0) expectBool(fRespURIOnlyWhenDifferent); // - none known here else return inherited::localStartElement(aElementName,aAttributes,aLine); #endif // SYSYNC_SERVER } // ok return true; } // TAgentConfig::localStartElement #endif // HARDCODED_CONFIG // resolve void TAgentConfig::localResolve(bool aLastPass) { if (aLastPass) { if (IS_CLIENT) { #ifdef SYSYNC_CLIENT #ifdef PRECONFIGURED_SYNCREQUESTS // - resolve requests TSyncReqList::iterator pos; for(pos=fSyncRequests.begin();pos!=fSyncRequests.end();pos++) (*pos)->Resolve(aLastPass); #endif #endif // SYSYNC_CLIENT } else { #ifdef SYSYNC_SERVER if (!fAutoNonce && fConstantNonce.empty()) ReportError(false,"Warning: 'constantnonce' should be defined when 'autononce' is not set"); #endif // SYSYNC_SERVER } } // resolve inherited inherited::localResolve(aLastPass); } // TAgentConfig::localResolve // Implementation of TSyncAgent // ============================= // constructor TSyncAgent::TSyncAgent( TSyncAppBase *aAppBaseP, TSyncSessionHandle *aSessionHandleP, const char *aSessionID // a session ID ) : TSyncSession(aAppBaseP,aSessionID) { // General #ifdef ENGINE_LIBRARY // init the flags which are set by STEPCMD_SUSPEND, STEPCMD_ABORT and STEPCMD_TRANSPFAIL fAbortRequested = false; fSuspendRequested = false; fEngineSessionStatus = LOCERR_WRONGUSAGE; #ifdef NON_FULLY_GRANULAR_ENGINE // - erase the list of queued progress events fProgressInfoList.clear(); fPendingStepCmd = 0; // none pending #endif // NON_FULLY_GRANULAR_ENGINE // - issue session start event here (in non-engine case this is done in TSyncSession constructor) SESSION_PROGRESS_EVENT(this,pev_sessionstart,NULL,0,0,0); #endif // ENGINE_LIBRARY #ifdef SYSYNC_SERVER // reset data counts fIncomingBytes = 0; fOutgoingBytes = 0; #endif fRestartSyncOnce = false; fRestartingSync = false; // Specific for Client or Server if (IS_CLIENT) { #ifdef SYSYNC_CLIENT #ifdef HARD_CODED_SERVER_URI fNoCRCPrefixLen = 0; #endif #ifdef ENGINE_LIBRARY // engine fClientEngineState = ces_idle; #endif // reset session now to get correct initial state InternalResetSession(); // restart with session numbering at 1 (incremented before use) fClientSessionNo = 0; #endif // SYSYNC_CLIENT } else { #ifdef SYSYNC_SERVER // init answer buffer fBufferedAnswer = NULL; fBufferedAnswerSize = 0; #ifdef ENGINE_LIBRARY // engine fServerEngineState = ses_needdata; fRequestSize = 0; #endif // init own stuff InternalResetSession(); // save session handle fSessionHandleP = aSessionHandleP; // link to handle // get config defaults TAgentConfig *configP = static_cast(aAppBaseP->getRootConfig()->fAgentConfigP); fUseRespURI = configP->fUseRespURI; // create all locally available datastores from config TLocalDSList::iterator pos; for (pos=configP->fDatastores.begin(); pos!=configP->fDatastores.end(); pos++) { // create the datastore addLocalDataStore(*pos); } #endif // SYSYNC_SERVER } } // TSyncAgent::TSyncAgent // destructor TSyncAgent::~TSyncAgent() { if (IS_CLIENT) { // make sure everything is terminated BEFORE destruction of hierarchy begins TerminateSession(); } else { #ifdef SYSYNC_SERVER // forget any buffered answers bufferAnswer(NULL,0); // reset session InternalResetSession(); // show session data transfer PDEBUGPRINTFX(DBG_HOT,( "Session data transfer statistics: incoming bytes=%ld, outgoing bytes=%ld", (long)fIncomingBytes, (long)fOutgoingBytes )); // DO NOT remove session from dispatcher here, // this is the task of the dispatcher itself! CONSOLEPRINTF(("Terminated SyncML session (server id=%s)\n",getLocalSessionID())); // show end of session in global level POBJDEBUGPRINTFX(getSyncAppBase(),DBG_HOT,( "TSyncAgent::~TSyncAgent: Deleted SyncML session (local session id=%s)", getLocalSessionID() )); #endif // SYSYNC_SERVER } } // TSyncAgent::~TSyncAgent // Terminate session void TSyncAgent::TerminateSession() { #ifdef SYSYNC_CLIENT if (IS_CLIENT && !fTerminated) { InternalResetSession(); #ifdef ENGINE_LIBRARY // switch state to done to prevent any further activity via SessionStep() fClientEngineState = ces_done; #endif } #endif // SYSYNC_CLIENT inherited::TerminateSession(); } // TSyncAgent::TerminateSession void TSyncAgent::InternalResetSession(void) { if (IS_CLIENT) { #ifdef SYSYNC_CLIENT // use remote URI as specified to start a session fRespondURI = fRemoteURI; #ifdef HARD_CODED_SERVER_URI #if defined(CUSTOM_URI_SUFFIX) && !defined(HARD_CODED_SERVER_URI_LEN) #error "HARD_CODED_SERVER_URI_LEN must be defined when using CUSTOM_URI_SUFFIX" #endif #ifdef HARD_CODED_SERVER_URI_LEN // only part of URL must match (max HARD_CODED_SERVER_URI_LEN chars will be added, less if URI is shorter) fServerURICRC = addNameToCRC(SYSER_CRC32_SEED, fRemoteURI.c_str()+fNoCRCPrefixLen, false, HARD_CODED_SERVER_URI_LEN); #else // entire URL (except prefix) must match fServerURICRC = addNameToCRC(SYSER_CRC32_SEED, fRemoteURI.c_str()+fNoCRCPrefixLen, false); #endif #endif // set SyncML version // Note: will be overridden with call to loadRemoteParams() fSyncMLVersion = syncml_vers_unknown; // unknown // will be cleared to suppress automatic use of DS 1.2 SINCE/BEFORE filters // (e.g. for date range in func_SetDaysRange()) fServerHasSINCEBEFORE = true; // no outgoing alert 222 sent so far fOutgoingAlert222Count = 0; #endif } else { #ifdef SYSYNC_SERVER // %%% remove this as soon as Server is 1.1 compliant //fSyncMLVersion=syncml_vers_1_0; // only accepts 1.0 for now %%%% #endif } } // TSyncAgent::InternalResetSession // Virtual version void TSyncAgent::ResetSession(void) { // let ancestor do its stuff TSyncSession::ResetSession(); // do my own stuff (and probably modify settings of ancestor!) InternalResetSession(); } // TSyncAgent::ResetSession bool TSyncAgent::MessageStarted(SmlSyncHdrPtr_t aContentP, TStatusCommand &aStatusCommand, bool aBad) { if (IS_CLIENT) { #ifdef SYSYNC_CLIENT return ClientMessageStarted(aContentP,aStatusCommand,aBad); #endif // SYSYNC_CLIENT } else { #ifdef SYSYNC_SERVER return ServerMessageStarted(aContentP,aStatusCommand,aBad); #endif // SYSYNC_SERVER } } void TSyncAgent::MessageEnded(bool aIncomingFinal) { if (IS_CLIENT) { #ifdef SYSYNC_CLIENT ClientMessageEnded(aIncomingFinal); #endif // SYSYNC_CLIENT } else { #ifdef SYSYNC_SERVER ServerMessageEnded(aIncomingFinal); #endif // SYSYNC_SERVER } } // starting with engine version 2.0.8.7 a client's device ID (in devinf) is no longer // a constant string, but the device's unique ID string TSyncAgent::getDeviceID(void) { if (fLocalURI.empty()) { if (IS_SERVER) return SYSYNC_SERVER_DEVID; // return default ID else return SYSYNC_CLIENT_DEVID; // return default ID } else return fLocalURI; } // TSyncAgent::getDeviceID // ask syncappbase for device type string TSyncAgent::getDeviceType(void) { // taken from configuration or default for engine type (client/server) return getSyncAppBase()->getDevTyp(); } // TSyncAgent::getDeviceType bool TSyncAgent::checkAllFromClientOnly() { bool allFromClientOnly=false; // Note: the map phase will not take place, if all datastores are in // send-to-server-only mode and we are not in non-conformant old // synthesis-compatible fCompleteFromClientOnly mode. #ifdef SYSYNC_SERVER if (!fCompleteFromClientOnly) #endif { // let all local datastores know that message has ended allFromClientOnly=true; for (TLocalDataStorePContainer::iterator pos=fLocalDataStores.begin(); pos!=fLocalDataStores.end(); ++pos) { // check sync modes if ((*pos)->isActive() && (*pos)->getSyncMode()!=smo_fromclient) { allFromClientOnly=false; break; } } } return allFromClientOnly; } #ifdef SYSYNC_CLIENT // initialize the client session and link it with the SML toolkit localstatus TSyncAgent::InitializeSession(uInt32 aProfileSelector, bool aAutoSyncSession) { localstatus sta; // Select profile now (before creating instance, as encoding is dependent on profile) sta=SelectProfile(aProfileSelector, aAutoSyncSession); if (sta) return sta; // Start a SyncML toolkit instance now and set the encoding from config InstanceID_t myInstance; if (!getSyncAppBase()->newSmlInstance( getEncoding(), getRootConfig()->fLocalMaxMsgSize * 2, // twice the message size myInstance )) { return LOCERR_SMLFATAL; } // let toolkit know the session pointer if (getSyncAppBase()->setSmlInstanceUserData(myInstance,this)!=SML_ERR_OK) // toolkit must know session (as userData) return LOCERR_SMLFATAL; // remember the instance myself setSmlWorkspaceID(myInstance); // session must know toolkit workspace // done return LOCERR_OK; } // TSyncAgent::InitializeSession // select a profile (returns false if profile not found) // Note: base class just tries to retrieve information from // config localstatus TSyncAgent::SelectProfile(uInt32 aProfileSelector, bool aAutoSyncSession) { #ifndef PRECONFIGURED_SYNCREQUESTS // no profile settings in config -> error return LOCERR_NOCFG; #else // get profile settings from config TAgentConfig *configP = static_cast(getRootConfig()->fAgentConfigP); // - get encoding fEncoding=configP->fEncoding; // SyncML encoding // - set server access details fRemoteURI=configP->fServerURI; // Remote URI = Server URI fTransportUser=configP->fTransportUser; // transport layer user (e.g. HTTP auth) fTransportPassword=configP->fTransportPassword; // transport layer password (e.g. HTTP auth) fServerUser=configP->fServerUser; // Server layer authentification user name fServerPassword=configP->fServerPassword; // Server layer authentification password #ifndef NO_LOCAL_DBLOGIN fLocalDBUser=configP->fLocalDBUser; // Local DB authentification user name (empty if local DB is single user) fNoLocalDBLogin=configP->fNoLocalDBLogin; // if set, no local DB auth takes place, but fLocalDBUser is used as userkey (depending on DB implementation) fLocalDBPassword=configP->fLocalDBPassword; // Local DB authentification password #endif fProxyHost=configP->fProxyHost; // Proxy host fSocksHost=configP->fSocksHost; // Socks host fProxyUser=configP->fProxyUser; fProxyPassword=configP->fProxyPassword; // Reset session after profile change // and also remove any datastores we might have ResetAndRemoveDatastores(); // if tunnel, that's all for now if (aProfileSelector==TUNNEL_PROFILE_ID) return LOCERR_OK; // - create and init datastores needed for this session from config // Note: probably config has no sync requests, but they are created later // programmatically TSyncReqList::iterator pos; for (pos=configP->fSyncRequests.begin(); pos!=configP->fSyncRequests.end(); pos++) { // create and init the datastore fLocalDataStores.push_back( (*pos)->initNewLocalDataStore(this) ); } // create "new" session ID (derivates will do this better) fClientSessionNo++; return LOCERR_OK; #endif } // TSyncAgent::SelectProfile // make sure we are logged in to local datastore localstatus TSyncAgent::LocalLogin(void) { #ifndef NO_LOCAL_DBLOGIN if (!fNoLocalDBLogin && !fLocalDBUser.empty()) { // check authorisation (login to correct user) in local DB if (!SessionLogin(fLocalDBUser.c_str(),fLocalDBPassword.c_str(),sectyp_clearpass,fRemoteURI.c_str())) { return localError(401); // done & error } } #endif return LOCERR_OK; } // TSyncAgent::LocalLogin // process message in the instance buffer localstatus TSyncAgent::processAnswer(void) { InstanceID_t myInstance = getSmlWorkspaceID(); Ret_t err; // now process data DEBUGPRINTF(("===> now calling smlProcessData")); #ifdef SYDEBUG MemPtr_t data = NULL; MemSize_t datasize; smlPeekMessageBuffer(getSmlWorkspaceID(), false, &data, &datasize); #endif fIgnoreMsgErrs=false; err=smlProcessData( myInstance, SML_ALL_COMMANDS ); if (err) { // dump the message that failed to process #ifdef SYDEBUG if (data) DumpSyncMLBuffer(data,datasize,false,err); #endif if (!fIgnoreMsgErrs) { PDEBUGPRINTFX(DBG_ERROR,("===> smlProcessData failed, returned 0x%hX",(sInt16)err)); // other problem or already using SyncML 1.0 --> error return LOCERR_PROCESSMSG; } } // now check if this is a session restart if (isStarting()) { // this is still the beginning of a session return LOCERR_SESSIONRST; } return LOCERR_OK; } // TSyncAgentBase::processAnswer bool TSyncAgent::restartSync() { if (IS_CLIENT) { // Restarting needs to be done if: // - all datastores support restarting a sync (= multiple read/write cycles) // on client and server side (expected not be set if the engine itself on // either side doesn't support it, so that is not checked separately) // - no datastore has failed in current iteration // - client has pending changes: // - server temporarily rejected a change, queued for resending // - an item added by the server was merged with another // item locally (might have an updated queued, need to send delete) // - change on client failed temporarily // - the app or a datastore asked for a restart via the "restartsync" // session variable if (!getenv("LIBSYNTHESIS_NO_RESTART")) { bool restartPossible=true; // ... unless proven otherwise below bool restartNecessary=fRestartSyncOnce; // one reason for restarting: requested by app int numActive = 0; // clear the flag after we checked it fRestartSyncOnce=false; if (fRestartSyncOnce) PDEBUGPRINTFX(DBG_SESSION,("try to restart sync as requested by app")); for (TLocalDataStorePContainer::iterator pos=fLocalDataStores.begin(); pos!=fLocalDataStores.end(); ++pos) { TLocalEngineDS *localDS = *pos; if (localDS->isActive()) { numActive++; if (!localDS->canRestart()) { PDEBUGPRINTFX(DBG_SESSION,("cannot restart, %s does not support it", localDS->getName())); restartPossible=false; break; } if (localDS->isAborted()) { PDEBUGPRINTFX(DBG_SESSION,("cannot restart, %s faileed", localDS->getName())); restartPossible=false; break; } if (!localDS->getRemoteDatastore() || !localDS->getRemoteDatastore()->canRestart()) { PDEBUGPRINTFX(DBG_SESSION,("cannot restart, remote datastore %s matching with %s does not support it", localDS->getRemoteDatastore()->getName(), localDS->getName())); restartPossible=false; break; } } // check for pending local changes in the client if (localDS->numUnsentMaps() > 0) { PDEBUGPRINTFX(DBG_SESSION,("try to restart, %s has pending map entries", localDS->getName())); restartNecessary=true; } // TODO: detect temporarily failed items (server sent an add/update/delete // that we had to reject temporarily and where we expect the server to // resend the request) // detect pending changes (for example, 409 handling in binfile client) if (localDS->hasPendingChangesForNextSync()) { PDEBUGPRINTFX(DBG_SESSION,("try to restart, %s has pending changes", localDS->getName())); restartNecessary=true; } } return restartPossible && restartNecessary; } } return false; } // let session produce (or finish producing) next message into // SML workspace // - returns aDone if no answer needs to be sent (=end of session) // - returns 0 if successful // - returns SyncML status code if unsucessfully aborted session localstatus TSyncAgent::NextMessage(bool &aDone) { TLocalDataStorePContainer::iterator pos; TSyError status; TP_START(fTPInfo,TP_general); // could be new thread // default to not continuing aDone=true; #ifdef PROGRESS_EVENTS // check for user suspend if (!SESSION_PROGRESS_EVENT(this,pev_suspendcheck,NULL,0,0,0)) { SuspendSession(LOCERR_USERSUSPEND); } #endif // done if session was aborted by last received commands if (isAborted()) return getAbortReasonStatus(); // done & error // check package state if (fOutgoingState==psta_idle) { // if suspended here, we'll just stop - nothing has happened yet if (isSuspending()) { AbortSession(fAbortReasonStatus,true); return getAbortReasonStatus(); } // start of an entirely new client session #ifdef HARD_CODED_SERVER_URI // extra check to limit hacking if (fServerURICRC != SERVER_URI_CRC) { // someone has tried to change the URI DEBUGPRINTFX(DBG_ERROR,("hardcoded Server URI CRC mismatch")); return LOCERR_LIMITED; // user will not know what this means, but we will } #endif // - check if we have client requests if (fLocalDataStores.size()<1) { PDEBUGPRINTFX(DBG_ERROR,("No datastores defined to sync with")); return LOCERR_NOCFG; } // %%% later, we could probably load cached info about // server requested auth, devinf etc. here // use remote URI as specified to start a session fRespondURI=fRemoteURI; // get default params for sending first message to remote // Note: may include remote flag settings that influence creation of my own ID below, that's why we do it now here loadRemoteParams(); // get info about my own URI, whatever that is #ifndef HARDCODED_CONFIG if (!static_cast(getRootConfig()->fAgentConfigP)->fFakeDeviceID.empty()) { // return fake Device ID if we have one defined in the config file (useful for testing) fLocalURI = static_cast(getRootConfig()->fAgentConfigP)->fFakeDeviceID; } else #endif { if (!getSyncAppBase()->getMyDeviceID(fLocalURI) || devidWithUserHash()) { // Device ID is not really unique, make a hash including user name to make it pseudo-unique // create MD5 hash from non-unique ID and user name // Note: when compiled with GUARANTEED_UNIQUE_DEVICID, devidWithUserHash() is always false. md5::SYSYNC_MD5_CTX context; uInt8 digest[16]; // for MD5 digest md5::Init (&context); // - add what we got for ID md5::Update (&context, (uInt8 *)fLocalURI.c_str(), fLocalURI.size()); // - add user name, if any if (fLocalURI.size()>0) md5::Update (&context, (uInt8 *)fServerUser.c_str(), fServerUser.size()); // - done md5::Final (digest, &context); // now make hex string of that fLocalURI = devidWithUserHash() ? 'x' : 'X'; // start with X to document this special case (lowercase = forced by remoteFlag) for (int n=0; n<16; n++) { AppendHexByte(fLocalURI,digest[n]); } } } // get my own name (if any) getPlatformString(pfs_device_name,fLocalName); // override some of these if not set by loadRemoteParams() if (fSyncMLVersion==syncml_vers_unknown) fSyncMLVersion=static_cast(getRootConfig()->fAgentConfigP)->fAssumedServerVersion; if (fRemoteRequestedAuth==auth_none) fRemoteRequestedAuth=static_cast(getRootConfig()->fAgentConfigP)->fAssumedServerAuth; if (fRemoteRequestedAuthEnc==fmt_chr) fRemoteRequestedAuthEnc=static_cast(getRootConfig()->fAgentConfigP)->fAssumedServerAuthEnc; if (fRemoteNonce.empty()) fRemoteNonce=static_cast(getRootConfig()->fAgentConfigP)->fAssumedNonce; // we are not yet authenticated for the entire session fNeedAuth=true; // now ready for init fOutgoingState=psta_init; // %%%% could also set psta_initsync for combined init/sync fIncomingState=psta_idle; // remains idle until first answer SyncHdr with OK status is received fInProgress=true; // assume in progress // set session ID string StringObjPrintf(fSynchdrSessionID,"%hd",(sInt16)fClientSessionNo); // now we have a session id, can now display debug stuff #ifdef SYDEBUG string t; StringObjTimestamp(t,getSystemNowAs(TCTX_SYSTEM)); PDEBUGPRINTFX(DBG_HOT,("\n[%s] =================> Starting new client session",t.c_str())); #endif // - make sure we are logged into the local database (if needed) status=LocalLogin(); if (status!=LOCERR_OK) return status; // create header for first message no noResp issueHeader(false); } else { // check for proper end of session (caused by MessageEnded analysis) if (!fInProgress) { // give an opportunity to let make outgoing message end and flush xml end message FinishMessage(true, false); // end sync in all datastores (save anchors etc.) PDEBUGPRINTFX(DBG_PROTO,("Successful end of session -> calling engFinishDataStoreSync() for datastores now")); for (pos=fLocalDataStores.begin(); pos!=fLocalDataStores.end(); ++pos) (*pos)->engFinishDataStoreSync(); // successful end PDEBUGPRINTFX(DBG_PROTO,("Session not any more in progress: NextMessage() returns OK status=0")); return LOCERR_OK; // done & ok } } // check expired case #ifdef APP_CAN_EXPIRE if (getClientBase()->fAppExpiryStatus!=LOCERR_OK) { PDEBUGPRINTFX(DBG_ERROR,("Evaluation Version expired - Please contact Synthesis AG for release version")); return getClientBase()->fAppExpiryStatus; // payment required, done & error } #endif if (fOutgoingState==psta_init || fOutgoingState==psta_initsync) { // - if suspended in init, nothing substantial has happened already, so just exit if (isSuspending() && fOutgoingState==psta_init) { AbortSession(fAbortReasonStatus,true); return getAbortReasonStatus(); } // - prepare Alert(s) for databases to sync bool anyfirstsyncs=false; bool anyslowsyncs=false; TLocalEngineDS *localDS; for (pos=fLocalDataStores.begin(); pos!=fLocalDataStores.end(); ++pos) { // prepare alert (Note: datastore may be run by a superdatastore) localDS = *pos; status=localDS->engPrepareClientSyncAlert(); if (status!=LOCERR_OK) { // local database error return localError(status); // not found } if (localDS->fFirstTimeSync) anyfirstsyncs=true; if (localDS->fSlowSync) anyslowsyncs=true; } // send devinf in Put command right away with init message if either... // - mustSendDevInf() returns true signalling an external condition that suggests sending devInf (like changed config) // - any datastore is doing first time sync // - fPutDevInfAtSlowSync is true and any datastore is doing slow sync // - not already sent (can be true here in later sync cycles) if (!fRemoteGotDevinf && (mustSendDevInf() || anyfirstsyncs || (anyslowsyncs && static_cast(getRootConfig()->fAgentConfigP)->fPutDevInfAtSlowSync)) ) { TDevInfPutCommand *putcmdP = new TDevInfPutCommand(this); issueRootPtr(putcmdP); } // try to load devinf from cache (only if we don't know it already) if (!fRemoteDataStoresKnown || !fRemoteDataTypesKnown) { SmlDevInfDevInfPtr_t devinfP; if (loadRemoteDevInf(getRemoteURI(),devinfP)) { // we have cached devinf, analyze it now analyzeRemoteDevInf(devinfP); } } // GET the server's info if server didn't send it and we haven't cached at least the datastores if (!fRemoteDataStoresKnown) { // if we know datastores here, but not types, this means that remote does not have // CTCap, so it makes no sense to issue a GET again. #ifndef NO_DEVINF_GET PDEBUGPRINTFX(DBG_REMOTEINFO,("Nothing known about server, request DevInf using GET command")); TGetCommand *getcommandP = new TGetCommand(this); getcommandP->addTargetLocItem(SyncMLDevInfNames[fSyncMLVersion]); string devinftype=SYNCML_DEVINF_META_TYPE; addEncoding(devinftype); getcommandP->setMeta(newMetaType(devinftype.c_str())); ISSUE_COMMAND_ROOT(this,getcommandP); #endif } // - create Alert(s) for databases to sync for (pos=fLocalDataStores.begin(); pos!=fLocalDataStores.end(); ++pos) { // create alert for non-subdatastores localDS = *pos; if (!localDS->isSubDatastore()) { TAlertCommand *alertcmdP; status = localDS->engGenerateClientSyncAlert(alertcmdP); if (status!=0) { // local database error return status; // not found } ///%%%% unneeded (probably got here by copy&paste accidentally): if (localDS->fFirstTimeSync) anyfirstsyncs=true; // issue alert issueRootPtr(alertcmdP); } } // append sync phase if we have combined init/sync if (fOutgoingState==psta_initsync) { fOutgoingState=psta_sync; fRestarting=false; } } // process sync/syncop/map generating phases after init if (!isSuspending()) { // normal, session continues if (fOutgoingState==psta_sync) { // hold back sync until server has finished first package (init or initsync) if (fIncomingState==psta_sync || fIncomingState==psta_initsync) { // start sync for alerted datastores for (pos=fLocalDataStores.begin(); pos!=fLocalDataStores.end(); ++pos) { // Note: some datastores might be aborted due to unsuccessful alert. if ((*pos)->isActive()) { // prepare engine for sync (%%% new routine in 3.2.0.3, summarizing engInitForSyncOps() and // switching to dssta_dataaccessstarted, i.e. loading sync set), but do in only once if (!((*pos)->testState(dssta_syncsetready))) { // not yet started status = (*pos)->engInitForClientSync(); if (status!=LOCERR_OK ) { // failed if (status!=LOCERR_DATASTORE_ABORT) { AbortSession(status,true); return getAbortReasonStatus(); } } } // start or continue (which is largely nop, as continuing works via unfinished sync command) // generating sync items (*pos)->engClientStartOfSyncMessage(); } } } } else if (fOutgoingState==psta_map) { // hold back map until server has started sync at least (incominstate >=psta_sync) // NOTE: This is according to the specs, which says that client can begin // with Map/update status package BEFORE sync package from server is // completely received. // NOTE: Starfish server expects this and generates a few 222 alerts // if we wait here, but then goes to map as well // (so (fIncomingState==psta_map)-version works as well here! // %%%% other version: wait until server has started map phase as well // %%%% if (fIncomingState==psta_map) { if (fIncomingState>=psta_sync) { // start map for synced datastores for (pos=fLocalDataStores.begin(); pos!=fLocalDataStores.end(); ++pos) { // Note: some datastores might be aborted due to unsuccessful alert. if ((*pos)->isActive()) { // now call datastore to generate map command if not already done (*pos)->engClientStartOfMapMessage(fIncomingState just generate a Alert 222 and wait for server to complete PDEBUGPRINTFX(DBG_PROTO+DBG_HOT,("Client finished so far, but needs to wait in supplement outgoing state until server finishes phase")); } else if (fOutgoingState!=psta_init) { // NOTE: can be psta_init because "if" begins again after psta_init checking // to allow psta_init appending psta_sync for combined init/sync // no known state return 9999; // %%%%% } } // if not suspended // security only: exit here if session got aborted in between if (isAborted()) return getAbortReasonStatus(); // done & error if (!fInProgress) return 9999; // that's fine with us // now, we know that we will (most probably) send a message, so default for aDone is false from now on aDone=false; bool outgoingfinal; // check for suspend if (isSuspending()) { // make sure we send a Suspend Alert TAlertCommand *alertCmdP = new TAlertCommand(this,NULL,(uInt16)224); // - we just put local and remote URIs here SmlItemPtr_t itemP = newItem(); itemP->target = newLocation(fRemoteURI.c_str()); itemP->source = newLocation(fLocalURI.c_str()); alertCmdP->addItem(itemP); ISSUE_COMMAND_ROOT(this,alertCmdP); // outgoing message is final, regardless of any session state outgoingfinal=true; MarkSuspendAlertSent(true); } else { // Determine if package can be final and if we need an 222 Alert // NOTE: if any commands were interruped or not sent due to outgoing message // size limits, FinishMessage() will prevent final anyway, so no // separate checking for enOfSync or endOfMap is needed. // - can finalize message when server has at least started answering current package // OR if this is the first message (probably repeatedly) sent outgoingfinal = fIncomingState >= fOutgoingState || fIncomingState==psta_idle; if (outgoingfinal) { // allow early success here in case of nothing to respond, and nothing pending // StarFish server does need this... if (!fNeedToAnswer) { if (hasPendingCommands()) { // we have pending commands, cannot be final message outgoingfinal=false; } else { // no pending commands -> we're done now PDEBUGPRINTFX(DBG_PROTO,("Early end of session (nothing to send to server any more) -> calling engFinishDataStoreSync() for datastores now")); // - end sync in all datastores (save anchors etc.) for (pos=fLocalDataStores.begin(); pos!=fLocalDataStores.end(); ++pos) (*pos)->engFinishDataStoreSync(); // successful end PDEBUGPRINTFX(DBG_PROTO,("Session not any more in progress: NextMessage() returns OK status=0")); // done & ok aDone=true; return LOCERR_OK; } } } } /* A dummy alert indicates this is a message with only alert222 request*/ bool dummyAlert = false; if (!outgoingfinal) { // - send Alert 222 if we need to continue package but have nothing to send // (or ALWAYS_CONTINUE222 defined) #ifndef ALWAYS_CONTINUE222 if (!fNeedToAnswer) #endif { /* End-less loop detection * Some servers will never end and triggers client sends * ALERT222 forever. Detect this scenario and abort the session if * detected. * It is still valid for the server to use ALERT222 to "keep-alive" the * connection. * Therefore the loop detection criteria is: * - Nothing to send except the 222 Alert (!fNeedToAnswer) * - 5 adjacent 222 alerts within 20 seconds * - no status for an actual sync op command received (fOutgoingAlert222Count will be reset by those) * because a server sending pending status in small chunks could also trigger the detector otherwise */ if (!fNeedToAnswer) { dummyAlert = true; if (fOutgoingAlert222Count++ == 0) { // start of 222 loop detection time fLastOutgoingAlert222 = getSystemNowAs(TCTX_UTC); } else if (fOutgoingAlert222Count > 5) { lineartime_t curTime = getSystemNowAs(TCTX_UTC); if (curTime - fLastOutgoingAlert222 < 20*secondToLinearTimeFactor) { PDEBUGPRINTFX(DBG_ERROR,( "Warning: More than 5 consecutive Alert 222 within 20 seconds- " "looks like endless loop, abort session" )); AbortSession(400, false); return getAbortReasonStatus(); } else { fOutgoingAlert222Count = 0; } } } // not final, and nothing to answer otherwise: create alert-Command to request more info TAlertCommand *alertCmdP = new TAlertCommand(this,NULL,(uInt16)222); // %%% not clear from spec what has to be in item for 222 alert code // but there MUST be an Item for the Alert command according to SyncML TK // - we just put local and remote URIs here SmlItemPtr_t itemP = newItem(); itemP->target = newLocation(fRemoteURI.c_str()); itemP->source = newLocation(fLocalURI.c_str()); alertCmdP->addItem(itemP); ISSUE_COMMAND_ROOT(this,alertCmdP); } } // We send a response with no dummy alert, so reset the alert detector if (!dummyAlert) { fOutgoingAlert222Count = 0; } // Normally the package will be closed normally when the client is // ready. The exception is if we might want to restart the sync // session. This is checked below. bool finalprevented = false; // send custom end-of session puts or restart session if (!isSuspending() && outgoingfinal && fOutgoingState==psta_map) { // End of outgoing map package; let custom PUTs which may transmit some session statistics etc. happen now // TODO: this code is not reached when fOutgoingState==psta_map is skipped // by ClientMessageEnded() (see "All datastores in from-client-only mode, and no need to answer: skip map phase"). // A bug? For restarting a sync, the problem is avoided by // disabling the standard-compliant "skip map phase" in favor // of "let client enter map phase" mode (fCompleteFromClientOnly). issueCustomEndPut(); if (restartSync()) { // don't allow if we are going to restart sync in // ClientMessageEnded(), also remember that we did that finalprevented=true; // flag for TSyncAgent::ClientMessageEnded() fRestartingSync=true; } } // message complete, now finish it FinishMessage( outgoingfinal, // allowed if possible finalprevented // final not allowed when restarting sync ); // Note, now fNewOutgoingPackage is set (by FinishMessage()) // if next message will be responded to with a new package // debug info #ifdef SYDEBUG if (PDEBUGMASK & DBG_SESSION) { PDEBUGPRINTFX(DBG_SESSION,( "---> NextMessage, outgoing state='%s', incoming state='%s'", PackageStateNames[fOutgoingState], PackageStateNames[fIncomingState] )); for (pos=fLocalDataStores.begin(); pos!=fLocalDataStores.end(); ++pos) { // Show state of local datastores PDEBUGPRINTFX(DBG_SESSION,( "Local Datastore '%s': %sState=%s, %s%s sync, %s%s", (*pos)->getName(), (*pos)->isAborted() ? "ABORTED - " : "", (*pos)->getDSStateName(), (*pos)->isResuming() ? "RESUMED " : "", (*pos)->fSlowSync ? "SLOW" : "normal", SyncModeDescriptions[(*pos)->fSyncMode], (*pos)->fServerAlerted ? ", Server-Alerted" : "" )); } } PDEBUGENDBLOCK("SyncML_Outgoing"); if (getLastIncomingMsgID()>0) { // we have already received an incoming message, so we have started an "SyncML_Incoming" blocks sometime PDEBUGENDBLOCK("SyncML_Incoming"); // terminate debug block of previous incoming message as well } #endif // ok return LOCERR_OK; // ok } // TSyncAgent::NextMessage // called after successful decoding of an incoming message bool TSyncAgent::ClientMessageStarted(SmlSyncHdrPtr_t aContentP, TStatusCommand &aStatusCommand, bool aBad) { // message not authorized by default fMessageAuthorized=false; // Check information from SyncHdr if ( aBad || (!(fSynchdrSessionID==smlPCDataToCharP(aContentP->sessionID))) || (!(fLocalURI==smlSrcTargLocURIToCharP(aContentP->target))) ) { // bad response PDEBUGPRINTFX(DBG_ERROR,( "Bad SyncHeader from Server. Syntax %s, SessionID (rcvd/correct) = '%s' / '%s', LocalURI (rcvd/correct) = '%s' / '%s'", aBad ? "ok" : "BAD", smlPCDataToCharP(aContentP->sessionID), fSynchdrSessionID.c_str(), smlSrcTargLocURIToCharP(aContentP->target), fLocalURI.c_str() )); aStatusCommand.setStatusCode(400); // bad response/request AbortSession(400,true); return false; } // check for suspend: if we are suspended at this point, this means that we have sent the Suspend Alert already // in the previous message (due to user suspend request), so we can now terminate the session if (isSuspending() && isSuspendAlertSent()) { AbortSession(514,true,LOCERR_USERSUSPEND); return false; } // - RespURI (remote URI to respond to) if (aContentP->respURI) { fRespondURI=smlPCDataToCharP(aContentP->respURI); DEBUGPRINTFX(DBG_PROTO,("RespURI set to = '%s'",fRespondURI.c_str())); } // authorization check // Note: next message will be started not before status for last one // has been processed. Commands issued before will automatically // be queued by issuePtr() // %%% none for now fSessionAuthorized=true; fMessageAuthorized=true; // returns false on BAD header (but true on wrong/bad/missing cred) return true; } // TSyncAgent::ClientMessageStarted // determines new package states and sets fInProgress void TSyncAgent::ClientMessageEnded(bool aIncomingFinal) { TLocalDataStorePContainer::iterator pos; // show status before processing PDEBUGPRINTFX(DBG_SESSION,( "MessageEnded starts : old outgoing state='%s', old incoming state='%s', %sNeedToAnswer", PackageStateNames[fOutgoingState], PackageStateNames[fIncomingState], fNeedToAnswer ? "" : "NO " )); bool allFromClientOnly=false; // process exceptions if (fAborted) { PDEBUGPRINTFX(DBG_ERROR,("***** Session is flagged 'aborted' -> MessageEnded ends package and session")); fOutgoingState=psta_idle; fIncomingState=psta_idle; fInProgress=false; } // if aborted else if (!fMessageAuthorized) { // not authorized messages will just be ignored, so // nothing changes in states // %%% this will probably not really work, as we would need to repeat the last // message in this (unlikely) case that fMessageAuthorized is not set for // a non-first message (first message case is handled in handleHeaderStatus) DEBUGPRINTFX(DBG_ERROR,("***** received Message not authorized, ignore and DONT end package")); fInProgress=true; } else { fInProgress=true; // assume we need to continue allFromClientOnly=checkAllFromClientOnly(); // new outgoing state is determined by the incomingState of this message // (which is the answer to the message of the previous outgoing package) if (fNewOutgoingPackage && fIncomingState!=psta_idle) { // last message sent was an end-of-package, so next will be a new package if (fIncomingState==psta_init) { // server has responded (or is still responding) to our finished init, // so client enters sync state now (but holds back sync until server // has finished init) fOutgoingState=psta_sync; fRestarting=false; } else if (fIncomingState==psta_sync || fIncomingState==psta_initsync) { // server has started (or already finished) sending statuses for our // or its own // client can enter map state (but holds back maps until server // has finished sync/initsync). In case of allFromClientOnly, we skip the map phase // but only if there is no need to answer. // Otherwise, this is most probably an old (pre 2.9.8.2) Synthesis server that has // sent an empty (and the status for it has set fNeedToAnswer), so we still // go to map phase. if (allFromClientOnly && !fNeedToAnswer) { fOutgoingState=psta_supplement; // all datastores are from-client-only, skip map phase PDEBUGPRINTFX(DBG_PROTO+DBG_HOT,("All datastores in from-client-only mode, and no need to answer: skip map phase")); } else { fOutgoingState=psta_map; // Some datastores do from-server-only or twoway, so we need a map phase allFromClientOnly=false; // do not skip map phase } } else { // map is finished as well, we might need extra packages just to // finish getting results for map commands fOutgoingState=psta_supplement; } } // New incoming state is simply derived from the incoming state of // this message if (fRestartingSync) { PDEBUGPRINTFX(DBG_HOT,("MessageEnded: restart sync")); fOutgoingState=psta_init; fIncomingState=psta_init; } else if (aIncomingFinal && fIncomingState!=psta_idle) { if (fIncomingState==psta_init) { // switch to sync fIncomingState=psta_sync; } else if (fIncomingState==psta_sync || fIncomingState==psta_initsync) { // check what to do if (allFromClientOnly) { // no need to answer and allFromClientOnly -> this is the end of the session fIncomingState=psta_supplement; fInProgress=false; // normally, at end of map answer, we are done } else { fIncomingState=psta_map; } } else { // end of a map phase - end of session (if no fNeedToAnswer) fIncomingState=psta_supplement; // this only ALLOWS ending the session, but it will continue as long // as more than OK for SyncHdr (fNeedToAnswer) must be sent fInProgress=false; // normally, at end of map answer, we are done } } // continue anyway as long as we need to answer if (fNeedToAnswer) fInProgress=true; } // show states PDEBUGPRINTFX(DBG_HOT,( "MessageEnded finishes : new outgoing state='%s', new incoming state='%s', %sNeedToAnswer", PackageStateNames[fOutgoingState], PackageStateNames[fIncomingState], fNeedToAnswer ? "" : "NO " )); // let all local datastores know that message has ended for (pos=fLocalDataStores.begin(); pos!=fLocalDataStores.end(); ++pos) { TLocalEngineDS *localDS = *pos; // let them know localDS->engEndOfMessage(); if (fRestartingSync) { // finish current session as far as the datastore is concerned localDS->engFinishDataStoreSync(LOCERR_OK); // and start again localDS->changeState(dssta_adminready); localDS->fFirstTimeSync = false; // unsetting flow sync leads to new sync mode: // - slow sync -> two-way sync or one-way if data direction was limited // - refresh sync -> one-way sync in same direction // - one-way sync -> do it again localDS->fSlowSync = false; } // Show state of local datastores PDEBUGPRINTFX(DBG_HOT,( "Local Datastore '%s': %sState=%s, %s%s sync, %s%s", localDS->getName(), localDS->isAborted() ? "ABORTED - " : "", localDS->getDSStateName(), localDS->isResuming() ? "RESUMED " : "", localDS->isSlowSync() ? "SLOW" : "normal", SyncModeDescriptions[localDS->getSyncMode()], localDS->fServerAlerted ? ", Server-Alerted" : "" )); } fRestartingSync = false; // thread might end here, so stop profiling TP_STOP(fTPInfo); } // TSyncAgent::ClientMessageEnded // get credentials/username to authenticate with remote party, NULL if none SmlCredPtr_t TSyncAgent::newCredentialsForRemote(void) { if (fNeedAuth) { // generate cretentials from username/password PDEBUGPRINTFX(DBG_PROTO+DBG_USERDATA,("Authenticating with server as user '%s'", fServerUser.c_str())); PDEBUGPRINTFX(DBG_PROTO+DBG_USERDATA+DBG_EXOTIC,("- using nonce '%s'", fRemoteNonce.c_str())); // NOTE: can be NULL when fServerRequestedAuth is auth_none return newCredentials( fServerUser.c_str(), fServerPassword.c_str() ); } else { // already authorized, no auth needed return NULL; } } // TSyncAgent::newCredentialsForRemote // get client base TSyncClientBase *TSyncAgent::getClientBase(void) { return static_cast(getSyncAppBase()); } // TSyncAgent::getClientBase // retry older protocol, returns false if no older protocol to try bool TSyncAgent::retryOlderProtocol(bool aSameVersionRetry, bool aOldMessageInBuffer) { if (fIncomingState==psta_idle) { // if we have not started a session yet and not using oldest protocol already, // we want to retry with next older SyncML version if (aSameVersionRetry) { // just retry same version PDEBUGPRINTFX(DBG_PROTO,("Retrying session start with %s",SyncMLVerProtoNames[fSyncMLVersion])); } else if (fSyncMLVersion>getSessionConfig()->fMinSyncMLVersionSupported) { // next lower fSyncMLVersion=(TSyncMLVersions)(((uInt16)fSyncMLVersion)-1); PDEBUGPRINTFX(DBG_PROTO,("Server does not support our SyncML version, trying with %s",SyncMLVerProtoNames[fSyncMLVersion])); } else { // cannot retry return false; } // retry retryClientSessionStart(aOldMessageInBuffer); return true; } // session already started or no older protocol to try return false; } // TSyncAgent::retryOlderProtocol // prepares client session such that it will do a retry to start a session // (but keeping already received auth/nonce/syncML-Version state) void TSyncAgent::retryClientSessionStart(bool aOldMessageInBuffer) { TAgentConfig *configP = static_cast(getRootConfig()->fAgentConfigP); // now restarting PDEBUGPRINTFX(DBG_HOT,("=================> Retrying Client Session Start")); bool newSessionForAuthRetry = configP->fNewSessionForAuthRetry; bool noRespURIForAuthRetry = configP->fNoRespURIForAuthRetry; // check if we should use modified behaviour (smart retries) if (configP->fSmartAuthRetry && fAuthRetries>MAX_NORMAL_AUTH_RETRIES) { if (newSessionForAuthRetry) { // if we had new session for retry, switch to in-session retry now newSessionForAuthRetry = false; noRespURIForAuthRetry = false; } else { // if we had in-session retry, try new session retry now newSessionForAuthRetry = true; noRespURIForAuthRetry = true; } PDEBUGPRINTFX(DBG_PROTO,("Smart retry with modified behaviour: newSessionForAuthRetry=%d, noRespURIForAuthRetry=%d",newSessionForAuthRetry,noRespURIForAuthRetry)); } // now retry if (newSessionForAuthRetry) { // Notes: // - must apparently be disabled for SCTS 3.1.2 and possibly Mightyphone // - must be enabled e.g for for Magically Server // Create new session ID StringObjPrintf(fSynchdrSessionID,"%hd",(sInt16)++fClientSessionNo); // restart message counting at 1 fIncomingMsgID=0; fOutgoingMsgID=0; // we must terminate the block here when we reset fIncomingMsgID, as NextMessage // only closes the incoming block when fIncomingMsgID>0 PDEBUGENDBLOCK("SyncML_Incoming"); } if (noRespURIForAuthRetry) { // Notes: // - must apparently be switched on for Starfish. // - must apparently be switched off for SCTS 3.1.2. // make sure we send next msg to the original URL fRespondURI=fRemoteURI; } // - make sure status for SyncHdr will not be generated! forgetHeaderWaitCommands(); // check if we have already started next outgoing message if (!fOutgoingStarted) { if (aOldMessageInBuffer) { // make sure we start with a fresh output buffer // Note: This usually only occur when we are not currently parsing // part of the buffer. If we are parsing, the remaining incoming // message gets cleared as well. getClientBase()->clrUnreadSmlBufferdata(); } // start a new message issueHeader(false); } else { if (aOldMessageInBuffer) { PDEBUGPRINTFX(DBG_ERROR,("Warning - restarting session with old message in output buffer")); } } // - make sure subsequent commands (most probably statuses for Alerts) // don't get processed AbortCommandProcessing(0); // silently discard all further commands // - make sure possible processing errors do not abort the session fIgnoreMsgErrs = true; } // TSyncAgent::retryClientSessionStart #endif // SYSYNC_CLIENT #ifdef SYSYNC_SERVER // undefine these only for tests. Introduced to find problem with T68i #define RESPURI_ONLY_WHEN_NEEDED // create a RespURI string. If none needed, return NULL SmlPcdataPtr_t TSyncAgent::newResponseURIForRemote(void) { if (IS_CLIENT) { return NULL; } // do it in a transport-independent way, therefore let dispatcher do it string respURI; // empty string if (fUseRespURI) { getSyncAppBase()->generateRespURI( respURI, // remains unaffected if no RespURI could be calculated fInitialLocalURI.c_str(), // initial URI used by remote to send first message fLocalSessionID.c_str() // server generated unique session ID ); // Omit RespURI if local URI as seen by client is identical if (getServerConfig()->fRespURIOnlyWhenDifferent) { // create RespURI only if different from original URI if (respURI==fLocalURI) { respURI.erase(); DEBUGPRINTFX(DBG_SESSION,( "Generated RespURI and sourceLocURI are equal (%s)-> RespURI omitted", fLocalURI.c_str() )); } } } // Note: returns NULL if respURI is empty string return newPCDataOptString(respURI.c_str()); } // newResponseURIForRemote // called after successful decoding of an incoming message bool TSyncAgent::ServerMessageStarted(SmlSyncHdrPtr_t aContentP, TStatusCommand &aStatusCommand, bool aBad) { // message not authorized by default fMessageAuthorized=false; // Get information from SyncHdr which is needed for answers // - session ID to be used for responses fSynchdrSessionID=smlPCDataToCharP(aContentP->sessionID); // - local URI (as seen by remote client) fLocalURI=smlSrcTargLocURIToCharP(aContentP->target); fLocalName=smlSrcTargLocNameToCharP(aContentP->target); // - also remember URI to which first message was sent // %%% note: incoming ID is not a criteria, because it might be >1 due to // client retrying something which it thinks is for the same session //if (fIncomingMsgID==1) { if (fOutgoingMsgID==0) { // this is the first message, remember first URI used to contact server // (or set preconfigured string from ) if (getServerConfig()->fExternalURL.empty()) fInitialLocalURI=fLocalURI; // use what client sends to us else fInitialLocalURI=getServerConfig()->fExternalURL; // use preconfigured URL // Many clients, including SCTS send the second login attempt with a MsgID>1, // and depending on how they handle RespURI, they might get a new session for that // -> so, just handle the case that a new session does not start with MsgID=1 if (fIncomingMsgID>1) { PDEBUGPRINTFX(DBG_ERROR,( "New session gets first message with MsgID=%ld (should be 1). Might be due to retries, adjusting OutgoingID as well", (long)fIncomingMsgID )); fOutgoingMsgID=fIncomingMsgID-1; // to make it match what client expects } } // - remote URI fRemoteURI=smlSrcTargLocURIToCharP(aContentP->source); fRemoteName=smlSrcTargLocNameToCharP(aContentP->source); // - RespURI (remote URI to respond to, if different from source) fRespondURI.erase(); if (aContentP->respURI) { fRespondURI=smlPCDataToCharP(aContentP->respURI); DEBUGPRINTFX(DBG_PROTO,("RespURI specified = '%s'",fRespondURI.c_str())); } if (fRespondURI==fRemoteURI) fRespondURI.erase(); // if specified but equal to remote: act as if not specified // More checking if header was ok if (aBad) { // bad header, only do what is needed to get a status back to client fSessionAuthorized=false; fIncomingState=psta_init; fOutgoingState=psta_init; fNewOutgoingPackage=true; // issue header to make sure status can be sent back to client if (!fMsgNoResp) issueHeader(false); // issue header, do not prevent responses } else { // check busy (or expired) case if (serverBusy()) { #ifdef APP_CAN_EXPIRE if (getSyncAppBase()->fAppExpiryStatus!=LOCERR_OK) { aStatusCommand.setStatusCode(511); // server failure (expired) aStatusCommand.addItemString("License expired or invalid"); PDEBUGPRINTFX(DBG_ERROR,("License expired or invalid - Please contact Synthesis AG to obtain license")); } else #endif { aStatusCommand.setStatusCode(101); // busy } issueHeader(false); // issue header, do not prevent responses AbortSession(0,true); // silently discard rest of commands return false; // header not ok } // now check what state we are in if (fIncomingState==psta_idle) { // Initialize // - session-wide authorization not yet there fSessionAuthorized=false; fMapSeen=false; // - session has started, we are processing first incoming // package and generating first outgoing package // (init, possibly changed to combined init/sync by in this package) fIncomingState=psta_init; fOutgoingState=psta_init; fNewOutgoingPackage=true; } // authorization check if (fIncomingState>=psta_init) { // now check authorization if (!fSessionAuthorized) { // started, but not yet permanently authorized fMessageAuthorized=checkCredentials( smlSrcTargLocNameToCharP(aContentP->source), // user name in clear text according to SyncML 1.0.1 aContentP->cred, // actual credentials aStatusCommand ); // NOTE: aStatusCommand has now the appropriate status and chal (set by checkCredentials()) // if credentials do not match, stop processing commands (but stay with the session) if (!fMessageAuthorized) { AbortCommandProcessing(aStatusCommand.getStatusCode()); PDEBUGPRINTFX(DBG_PROTO,("Authorization failed with status %hd, stop command processing",aStatusCommand.getStatusCode())); } // now determine if authorization is permanent or not if (fMessageAuthorized) { fAuthFailures=0; // reset count if (messageAuthRequired()) { // each message needs autorisation again (or no auth at all) // - 200 ok, next message needs authorization again (or again: none) fSessionAuthorized=false; // no permanent authorization aStatusCommand.setStatusCode(200); // - add challenge for next auth (different nonce) aStatusCommand.setChallenge(newSessionChallenge()); PDEBUGPRINTFX(DBG_PROTO,("Authorization ok, but required again for subsequent messages: 200 + chal")); } else { // entire session is authorized fSessionAuthorized=true; // permanent authorization // - 212 authentication accepted (or 200 if none is reqired at all) aStatusCommand.setStatusCode(requestedAuthType()==auth_none ? 200 : 212); // - add challenge for next auth (in next session, but as we support carry // forward via using sessionID, we need to send one here as well) aStatusCommand.setChallenge(newSessionChallenge()); PDEBUGPRINTFX(DBG_PROTO,("Authorization accepted: 212")); } } } // authorisation check else { // already authorized from previous message PDEBUGPRINTFX(DBG_PROTO,("Authorization ok from previous request: 200")); fMessageAuthorized=true; } // Start response message AFTER auth check, to allow issueHeader // to check auth state and customize the header accordingly (no // RespURI for failed auth for example) if (!fMsgNoResp) { issueHeader(false); // issue header, do not prevent responses } } // if started at least } // if not aBad // return startmessage status // debug info #ifdef SYDEBUG if (PDEBUGMASK & DBG_SESSION) { PDEBUGPRINTFX(DBG_SESSION,( "---> MessageStarted, Message %sauthorized, incoming state='%s', outgoing state='%s'", fMessageAuthorized ? "" : "NOT ", PackageStateNames[fIncomingState], PackageStateNames[fOutgoingState] )); TLocalDataStorePContainer::iterator pos; for (pos=fLocalDataStores.begin(); pos!=fLocalDataStores.end(); ++pos) { // Show state of local datastores PDEBUGPRINTFX(DBG_SESSION,( "Local Datastore '%s': State=%s, %s%s sync, %s%s", (*pos)->getName(), (*pos)->getDSStateName(), (*pos)->isResuming() ? "RESUMED " : "", (*pos)->fSlowSync ? "SLOW" : "normal", SyncModeDescriptions[(*pos)->fSyncMode], (*pos)->fServerAlerted ? ", Server-Alerted" : "" )); } } #endif // final check for too many auth failures if (!fMessageAuthorized) { #ifdef NO_NONCE_OLD_BEAHVIOUR AbortSession(aStatusCommand.getStatusCode(),true); // local error // avoid special treatment of non-authorized message, we have aborted, this is enough fMessageAuthorized=true; #else // Unsuccessful auth, count this fAuthFailures++; PDEBUGPRINTFX(DBG_ERROR,( "Authorization failed %hd. time, (any reason), sending status %hd", fAuthFailures, aStatusCommand.getStatusCode() )); // - abort session after too many auth failures if (fAuthFailures>=MAX_AUTH_ATTEMPTS) { PDEBUGPRINTFX(DBG_ERROR,("Too many (>=%d) failures, aborting session",MAX_AUTH_ATTEMPTS)); AbortSession(400,true); } #endif } // returns false on BAD header (but true on wrong/bad/missing cred) return true; } // TSyncAgent::ServerMessageStarted void TSyncAgent::ServerMessageEnded(bool aIncomingFinal) { bool alldone; TPackageStates newoutgoingstate,newincomingstate; TLocalDataStorePContainer::iterator pos; bool allFromClientOnly=false; // Incoming message ends here - what is following are commands initiated by the server // not directly related to a incoming command. PDEBUGENDBLOCK("SyncML_Incoming"); // assume that outgoing package is NOT finished, so outgoing state does not change newoutgoingstate=fOutgoingState; // new incoming state depends on whether this message is final or not if ((aIncomingFinal || (fIncomingState==psta_supplement)) && fMessageAuthorized) { // Note: in supplement state, incoming final is not relevant (may or may not be present, there is // no next phase anyway // find out if this is a shortened session (no map phase) due to // from-client-only in all datastores allFromClientOnly=checkAllFromClientOnly(); // determine what package comes next switch (fIncomingState) { case psta_init : newincomingstate=psta_sync; break; case psta_sync : case psta_initsync : // end of sync phase means end of session if all datastores are in from-client-only mode if (allFromClientOnly) { PDEBUGPRINTFX(DBG_PROTO+DBG_HOT,("All datastores in from-client-only mode: don't expect map phase from client")); newincomingstate=psta_supplement; } else { newincomingstate=psta_map; } break; case psta_map : case psta_supplement : // supplement state does not exit automatically // after map, possibly some supplement status/alert 222 messages are needed from client newincomingstate=psta_supplement; break; default: // by default, back to idle newincomingstate=psta_idle; break; } // switch } else { // not final or not authorized: no change in state newincomingstate=fIncomingState; } // show status before processing PDEBUGPRINTFX(DBG_SESSION,( "---> MessageEnded starts : old incoming state='%s', old outgoing state='%s', %sNeedToAnswer", PackageStateNames[fIncomingState], PackageStateNames[fOutgoingState], fNeedToAnswer ? "" : "NO " )); // process if (isAborted()) { // actual aborting has already taken place PDEBUGPRINTFX(DBG_ERROR,("***** Session is flagged 'aborted' -> MessageEnded ends package and session")); newoutgoingstate=psta_idle; newincomingstate=psta_idle; fInProgress=false; } // if aborted else if (isSuspending()) { // only flagged for suspend - but datastores are not yet aborted, do it now AbortSession(514,true,getAbortReasonStatus()); PDEBUGPRINTFX(DBG_ERROR,("***** Session is flagged 'suspended' -> MessageEnded ends package and session")); newoutgoingstate=psta_idle; newincomingstate=psta_idle; fInProgress=false; } else if (!fMessageAuthorized) { // not authorized messages will just be ignored, no matter if final or not, // so outgoing will NEVER be final on non-authorized messages // %%% before 1.0.4.9, this was fInProgress=true // DEBUGPRINTFX(DBG_ERROR,("***** Message not authorized, ignore and DONT end package, session continues")); // fInProgress=true; PDEBUGPRINTFX(DBG_ERROR,("***** Message not authorized, ignore msg and terminate session")); fInProgress=false; } else { // determine if session continues living or not // - if in other than idle state, session will continue fInProgress = (newincomingstate!=psta_idle) || // if not idle, we'll continue !fMessageAuthorized; // if not authorized, we'll continue as well (retrying auth) // Check if we need to send an Alert 222 to get more messages of this package if (!aIncomingFinal) { // not end of incoming package #ifndef ALWAYS_CONTINUE222 if (!fNeedToAnswer) #endif { #ifdef COMBINE_SYNCANDMAP // %%% make sure session gets to an end in case combined sync/map was used if (fMapSeen && fIncomingState==psta_map && fOutgoingState==psta_map) { DEBUGPRINTFX(DBG_HOT,("********** Incoming, non-final message in (combined)map state needs no answer -> force end of outgoing package")); newoutgoingstate=psta_idle; } else #endif { // detected 222-loop on init here: when we have nothing to answer in init // and nothing is alerted -> break session // %%% not sure if this is always ok if (fIncomingState<=psta_init) { PDEBUGPRINTFX(DBG_ERROR,("############## Looks like if we were looping in an init-repeat loop -> force final")); fInProgress=false; fOutgoingState=psta_idle; } else { // not final, and nothing to answer otherwise: create alert-Command to request more info TAlertCommand *alertCmdP = new TAlertCommand(this,NULL,(uInt16)222); // %%% not clear from spec what has to be in item for 222 alert code // but there MUST be an Item for the Alert command according to SyncML TK // - we just put local and remote URIs here SmlItemPtr_t itemP = newItem(); itemP->target = newLocation(fRemoteURI.c_str()); itemP->source = newLocation(fLocalURI.c_str()); alertCmdP->addItem(itemP); ISSUE_COMMAND_ROOT(this,alertCmdP); } } } } else { // end of package, finish processing package if (fIncomingState==psta_init) { // - try to load devinf from cache (only if we don't have both datastores and type info already) if (!fRemoteDataStoresKnown || !fRemoteDataTypesKnown) { SmlDevInfDevInfPtr_t devinfP; TStatusCommand dummystatus(this); if (loadRemoteDevInf(getRemoteURI(),devinfP)) { // we have cached devinf, analyze it now localstatus sta = analyzeRemoteDevInf(devinfP); PDEBUGPRINTFX(DBG_ERROR,("devInf from Cache could not be analyzed: error=%hd",sta)); } } // - if no DevInf for remote datastores cached or received yet, // issue GET for it now if (!fRemoteDataStoresKnown) { // if we know datastores here, but not types, this means that remote does not have // CTCap, so it makes no sense to issue a GET again. #ifndef NO_DEVINF_GET // end of initialisation package, but datastores not known yet // (=no DevInf Put received) --> ask for devinf now PDEBUGPRINTFX(DBG_REMOTEINFO,("No DevInf received or cached, request DevInf using GET command")); TGetCommand *getcommandP = new TGetCommand(this); getcommandP->addTargetLocItem(SyncMLDevInfNames[fSyncMLVersion]); string devinftype=SYNCML_DEVINF_META_TYPE; addEncoding(devinftype); getcommandP->setMeta(newMetaType(devinftype.c_str())); ISSUE_COMMAND_ROOT(this,getcommandP); #endif } } } // make sure syncing local datastores get informed of end-of--message if (fIncomingState==psta_sync || fIncomingState==psta_initsync) { // end of an incoming message of the Sync Package // - let all local datastores know, this is now the time to generate // commands, if needed // Note: if there are SyncEnd commands delayed, this means that this is // not yet the time to start commands. Instead, when all // queued SyncEnd commands are executed later, engEndOfSyncFromRemote() // will be called with the endOfAllSyncCommands flag true instead // of now. for (pos=fLocalDataStores.begin(); pos!=fLocalDataStores.end(); ++pos) { (*pos)->engEndOfSyncFromRemote(aIncomingFinal && !delayedSyncEndsPending()); } } // Detect outgoing package state transitions // - init to sync if (fOutgoingState==psta_init && newincomingstate>psta_init) { // new outgoing state is sync. // Note: In combined init&sync mode, sync command received in init state // will set outgoing state from init to init-sync while processing message, // so no transition needs to be detected here newoutgoingstate=psta_sync; fRestarting=false; } // - sync to map else if ( (fOutgoingState==psta_sync || fOutgoingState==psta_initsync) && // outgoing is sync.. (newincomingstate>=psta_initsync) && // ..and incoming has finished sync !allFromClientOnly // ..and this is not a session with all datastores doing from-client-only ) { // outgoing message belongs to Sync package // - ask all local datastores if they are finished with sync command generation alldone=true; for (pos=fLocalDataStores.begin(); pos!=fLocalDataStores.end(); ++pos) { alldone = alldone && (*pos)->isSyncDone(); } if (alldone) { // outgoing state changes to map (or supplement if all datastores are from-client-only PDEBUGPRINTFX(DBG_HOT,("All datastores are done with generating ")); newoutgoingstate=psta_map; #ifdef COMBINE_SYNCANDMAP // %%% it seems as if 9210 needs combined Sync/Map package and if (fMapSeen) { // prevent FINAL to be sent at end of message DEBUGPRINTFX(DBG_HOT,("********** Combining outgoing sync and map-response packages into one")); fOutgoingState=psta_map; } #endif } } // - map (or from-client-only sync) to idle else if ( (fOutgoingState==psta_map && newincomingstate==psta_supplement) || (allFromClientOnly && (fOutgoingState==psta_sync || fOutgoingState==psta_initsync)) ) { // we are going back to idle now newoutgoingstate=psta_idle; // session ends if it doesn't need to continue for session-level reasons if (!sessionMustContinue()) { PDEBUGPRINTFX(DBG_HOT,("Session completed, now let datastores terminate all sync operations")); for (pos=fLocalDataStores.begin(); pos!=fLocalDataStores.end(); ++pos) { // finished with Map: end of sync (*pos)->engFinishDataStoreSync(); // successful } // session ends now fInProgress=false; // let custom PUTs which may transmit some session statistics etc. happen now issueCustomEndPut(); } } // - if no need to answer (e.g. nothing to send back except OK status for SyncHdr), // session is over now (as well) if (!fNeedToAnswer) fInProgress=false; } // else // Now finish outgoing message #ifdef DONT_FINAL_BAD_AUTH_ATTEMPTS // - PREVENT final flag after failed auth attempts if(FinishMessage( fOutgoingState!=newoutgoingstate || fOutgoingState==psta_idle, // final when state changed or idle !fMessageAuthorized || serverBusy() // busy or unauthorized prevent final flag at any rate )) #else // - DO set final flag after failed auth attempts if(FinishMessage( !fMessageAuthorized || fOutgoingState!=newoutgoingstate || fOutgoingState==psta_idle, // final when state changed or idle serverBusy() // busy prevents final flag at any rate )) #endif { // outgoing state HAS changed fOutgoingState=newoutgoingstate; } // Now update incoming state fIncomingState=newincomingstate; // show states PDEBUGPRINTFX(DBG_HOT,( "---> MessageEnded finishes : new incoming state='%s', new outgoing state='%s', %sNeedToAnswer", PackageStateNames[fIncomingState], PackageStateNames[fOutgoingState], fNeedToAnswer ? "" : "NO " )); // let all local datastores know that message has ended for (pos=fLocalDataStores.begin(); pos!=fLocalDataStores.end(); ++pos) { // let them know (*pos)->engEndOfMessage(); // Show state of local datastores PDEBUGPRINTFX(DBG_HOT,( "Local Datastore '%s': State=%s, %s%s sync, %s%s", (*pos)->getName(), (*pos)->getDSStateName(), (*pos)->isResuming() ? "RESUMED " : "", (*pos)->fSlowSync ? "SLOW" : "normal", SyncModeDescriptions[(*pos)->fSyncMode], (*pos)->fServerAlerted ? ", Server-Alerted" : "" )); } // End of outgoing message PDEBUGPRINTFX(DBG_HOT,( "=================> Finished generating outgoing message #%ld, request=%ld", (long)fOutgoingMsgID, (long)getSyncAppBase()->requestCount() )); PDEBUGENDBLOCK("SyncML_Outgoing"); } // TSyncAgent::ServerMessageEnded void TSyncAgent::RequestEnded(bool &aHasData) { // to make sure, finish any unfinished message FinishMessage(true); // final allowed, as this is an out-of-normal-order case anyway // if we need to answer, we have data // - SyncML specs 1.0.1 says that server must always respond, even if message // contains of a Status for the SyncHdr only aHasData=true; // %%% first drafts of 1.0.1 said that SyncHdr Status only messages must not be sent... // aHasData=fNeedToAnswer; // %%% // now let all datastores know that request processing ends here (so they might // prepare for a thread switch) // terminate sync with all datastores TLocalDataStorePContainer::iterator pos; for (pos=fLocalDataStores.begin(); pos!=fLocalDataStores.end(); ++pos) { // now let them know that request has ended (*pos)->engRequestEnded(); } } // TSyncAgent::RequestEnded // Called at end of Request, returns true if session must be deleted // returns flag if data to be returned. If response URI was specified // different, it is returned in aRespURI, otherwise aRespURI is empty. bool TSyncAgent::EndRequest(bool &aHasData, string &aRespURI, uInt32 aReqBytes) { // count incoming data fIncomingBytes+=aReqBytes; // let client or server do what is needed if (fMessageRetried) { // Message processing cancelled CancelMessageProcessing(); // Nothing happened // - but count bytes fOutgoingBytes+=fBufferedAnswerSize; PDEBUGPRINTFX(DBG_HOT,( "========= Finished retried request with re-sending buffered answer (session %sin progress), incoming bytes=%ld, outgoing bytes=%ld", fInProgress ? "" : "NOT ", (long)aReqBytes, (long)fBufferedAnswerSize )); aHasData=false; // we do not have data in the sml instance (but we have/had some in the retry re-send buffer) } else { // end request RequestEnded(aHasData); // count bytes fOutgoingBytes+=getOutgoingMessageSize(); PDEBUGPRINTFX(DBG_HOT,( "========= Finished request (session %sin progress), processing time=%ld msec, incoming bytes=%ld, outgoing bytes=%ld", fInProgress ? "" : "NOT ", (long)((getSystemNowAs(TCTX_UTC)-getLastRequestStarted()) * nanosecondsPerLinearTime / 1000000), (long)aReqBytes, (long)getOutgoingMessageSize() )); // return RespURI (is empty if none specified or equal to message source URI) aRespURI = fRespondURI; } if (!fInProgress) { // terminate datastores here already in case we are not in progress any more // here. If any of the datastores are in progress at this point, this is a // protocol violation, and therefore we return a 400. // Note: resetting the session later will also call TerminateDatastores, but then // with a 408 (which is misleading when the session ends here due to protocol // problem. TerminateDatastores(400); } //%%% moved to happen before end of SyncML_Outgoing //PDEBUGENDBLOCK("SyncML_Incoming"); if (fRequestMinTime>0) { // make sure we spent enough time with this request, if not, artificially extend time // - get number of seconds already spent sInt32 t = (sInt32)((getSystemNowAs(TCTX_UTC)-getLastRequestStarted()) / (lineartime_t)secondToLinearTimeFactor); // - delay if needed if (t sleeping %ld seconds", (long)fRequestMinTime, (long)t, (long)fRequestMinTime-t )); CONSOLEPRINTF((" ...delaying response by %ld seconds because requestmintime is set to %ld",(long)fRequestMinTime,(long)(fRequestMinTime-t))); sleepLineartime((lineartime_t)(fRequestMinTime-t)*secondToLinearTimeFactor); } } // thread might end here, so stop profiling TP_STOP(fTPInfo); #ifdef SYDEBUG // we are not the main thread any longer getDbgLogger()->DebugThreadOutputDone(); #endif // return true if session is not in progress any more return(!fInProgress); } // TSyncAgent::EndRequest // buffer answer in the session's buffer if transport allows it Ret_t TSyncAgent::bufferAnswer(MemPtr_t aAnswer, MemSize_t aAnswerSize) { // get rid of previous buffered answer if (fBufferedAnswer) delete[] fBufferedAnswer; fBufferedAnswer=NULL; fBufferedAnswerSize=0; // save new answer (if not empty) if (aAnswer && aAnswerSize) { // allocate buffer fBufferedAnswer = new unsigned char[aAnswerSize]; // copy data if (!fBufferedAnswer) return SML_ERR_NOT_ENOUGH_SPACE; memcpy(fBufferedAnswer,aAnswer,aAnswerSize); // save size fBufferedAnswerSize=aAnswerSize; } return SML_ERR_OK; } // TSyncAgent::bufferAnswer // get buffered answer from the session's buffer if there is any void TSyncAgent::getBufferedAnswer(MemPtr_t &aAnswer, MemSize_t &aAnswerSize) { aAnswer=fBufferedAnswer; aAnswerSize=fBufferedAnswerSize; PDEBUGPRINTFX(DBG_HOT,( "Buffered answer read from session: %ld bytes", fBufferedAnswerSize )); } // TSyncAgent::getBufferedAnswer // returns remaining time for request processing [seconds] sInt32 TSyncAgent::RemainingRequestTime(void) { if (IS_CLIENT) { // clients don't process requests, so there's no limit return 0x7FFFFFFF; // "infinite" } else { // if no request timeout specified, use session timeout sInt32 t = fRequestMaxTime ? fRequestMaxTime : getSessionConfig()->fSessionTimeout; // calculate number of remaining seconds return t==0 ? 0x7FFFFFFF : // "infinite" t - (sInt32)((getSystemNowAs(TCTX_UTC)-getLastRequestStarted()) / (lineartime_t)secondToLinearTimeFactor); } } // TSyncAgent::RemainingRequestTime // process a Map command in context of server session bool TSyncAgent::processMapCommand( SmlMapPtr_t aMapCommandP, // the map command contents TStatusCommand &aStatusCommand, // pre-set 200 status, can be modified in case of errors bool &aQueueForLater ) { bool allok=false; // assume not ok localstatus sta; // remember that this session has seen a map command already fMapSeen=true; // Detecting a map command in supplement incomin state indicates a // client like funambol that send to many in pre-map phases // (such as in 222-Alert messages). So we reset the session state back // to incoming/outgoing map to correct this client bug if (fIncomingState==psta_supplement) { // back to map phase, as client apparently IS still in map phase, despite too many // sent PDEBUGPRINTFX(DBG_ERROR,( "Warning: detected command after end of Map phase - buggy client sent too many . Re-entering map phase to compensate" )); fIncomingState=psta_map; fOutgoingState=psta_map; } // find database(s) // - get relative URI of requested database const char *targetdburi = smlSrcTargLocURIToCharP(aMapCommandP->target); TLocalEngineDS *datastoreP = findLocalDataStoreByURI(targetdburi); if (!datastoreP) { // no such local datastore aStatusCommand.setStatusCode(404); // not found } else { // local datastore found // - maps can be processed when we are at least ready for early (chached by client from previous session) maps if (datastoreP->testState(dssta_syncmodestable)) { // datastore is ready PDEBUGBLOCKFMT(("ProcessMap", "Processing items from Map command", "datastore=%s", targetdburi)); allok=true; // assume all ok SmlMapItemListPtr_t nextnode = aMapCommandP->mapItemList; while (nextnode) { POINTERTEST(nextnode->mapItem,("MapItemList node w/o MapItem")); PDEBUGPRINTFX(DBG_HOT,( "Mapping remoteID='%s' to localID='%s'", smlSrcTargLocURIToCharP(nextnode->mapItem->source), smlSrcTargLocURIToCharP(nextnode->mapItem->target) )); sta = datastoreP->engProcessMap( #ifdef DONT_STRIP_PATHPREFIX_FROM_REMOTEIDS smlSrcTargLocURIToCharP(nextnode->mapItem->source), #else relativeURI(smlSrcTargLocURIToCharP(nextnode->mapItem->source)), #endif relativeURI(smlSrcTargLocURIToCharP(nextnode->mapItem->target)) ); if (sta!=LOCERR_OK) { PDEBUGPRINTFX(DBG_ERROR,(" Mapping FAILED!")); aStatusCommand.setStatusCode(sta); allok=false; break; } // next mapitem nextnode=nextnode->next; } // while more mapitems // terminate Map command allok=datastoreP->MapFinishAsServer(allok,aStatusCommand); PDEBUGENDBLOCK("ProcessMap"); } else { // we must queue the command for later execution aQueueForLater=true; allok=true; // ok for now, we'll re-execute this later } } // database found return allok; } // TSyncAgent::processMapCommand // get next nonce string top be sent to remote party for subsequent MD5 auth void TSyncAgent::getNextNonce(const char *aDeviceID, string &aNextNonce) { fLastNonce.erase(); if (getServerConfig()->fAutoNonce) { // generate nonce out of source ref and session ID // This scheme can provide nonce carrying forward between // sessions by initializing lastNonce with the srcRef/sessionid-1 // assuming client to use nonce from last session. sInt32 sid; // use current day as nonce varying number sid = time(NULL) / 3600 / 24; generateNonce(fLastNonce,aDeviceID,sid); } else { // get constant nonce (if empty, this is NO nonce) fLastNonce=getServerConfig()->fConstantNonce; } // return new nonce DEBUGPRINTFX(DBG_PROTO,("getNextNonce: created nonce='%s'",fLastNonce.c_str())); aNextNonce=fLastNonce; } // TSyncAgent::getNextNonce // - get nonce string for specified deviceID void TSyncAgent::getAuthNonce(const char *aDeviceID, string &aAuthNonce) { // if no device ID, use session default nonce if (!aDeviceID) { TSyncSession::getAuthNonce(aDeviceID,fLastNonce); } else { // Basic nonce mechanism needing no per-device storage: // - we have no stored last nonce, but we can re-create nonce used // for last session with this device by the used algorithm if (getServerConfig()->fAutoNonce) { if (fLastNonce.empty()) { // none available, produce new one sInt32 sid; // use current day as nonce varying number sid = time(NULL) / 3600 / 24; generateNonce(fLastNonce,aDeviceID,sid); } } else { // return constant nonce fLastNonce=getServerConfig()->fConstantNonce; } } DEBUGPRINTFX(DBG_PROTO,("getAuthNonce: current auth nonce='%s'",fLastNonce.c_str())); aAuthNonce=fLastNonce; } // TSyncAgent::getAuthNonce // info about server status bool TSyncAgent::serverBusy(void) { // return flag (which might have been set by some connection // limit code in sessiondispatch). // When app is expired, all server sessions are busy anyway #ifdef APP_CAN_EXPIRE return fSessionIsBusy || (getSyncAppBase()->fAppExpiryStatus!=LOCERR_OK); #else return fSessionIsBusy; #endif } // TSyncAgent::serverBusy // access to config TAgentConfig *TSyncAgent::getServerConfig(void) { TAgentConfig *scP; GET_CASTED_PTR(scP,TAgentConfig,getSyncAppBase()->getRootConfig()->fAgentConfigP,DEBUGTEXT("no TAgentConfig","ss1")); return scP; } // TSyncAgent::getServerConfig #endif // SYSYNC_SERVER // info about requested auth type TAuthTypes TSyncAgent::requestedAuthType(void) { if (IS_SERVER) { #ifdef SYSYNC_SERVER return getServerConfig()->fRequestedAuth; #endif } else { return auth_none; // client does not require auth } } // TSyncAgent::requestedAuthType // check if auth type is allowed bool TSyncAgent::isAuthTypeAllowed(TAuthTypes aAuthType) { if (IS_SERVER) { #ifdef SYSYNC_SERVER return aAuthType>=getServerConfig()->fRequiredAuth; #endif } else { return true; // client accepts any auth } } // TSyncAgent::isAuthTypeAllowed // called when incoming SyncHdr fails to execute bool TSyncAgent::syncHdrFailure(bool aTryAgain) { if (IS_CLIENT) { // do not try to re-execute the header, just let message processing fail; // this will cause the client's main loop to try using an older protocol return false; } else { #ifdef SYSYNC_SERVER if (!aTryAgain) { // not already retried executing // special case: header failed to execute, this means that session must be reset // - Reset session (aborts all DB transactions etc.) ResetSession(); PDEBUGPRINTFX(DBG_ERROR,("Trying to recover SyncHdr failure: =========== Session restarted =====================")); // - now all session infos are gone except this command which is owned by // this function alone. Execute it again. aTryAgain=true; } else { // special special case: header failed to execute the second time DEBUGPRINTFX(DBG_ERROR,("Fatal internal problem, SyncHdr execution failed twice")); aTryAgain=false; // just to make sure SYSYNC_THROW(TSyncException("SyncHdr fatal execution problem")); } return aTryAgain; #endif } } // TSyncAgent::syncHdrFailure // handle status received for SyncHdr, returns false if not handled bool TSyncAgent::handleHeaderStatus(TStatusCommand *aStatusCmdP) { if (IS_CLIENT) { #ifdef SYSYNC_CLIENT TAgentConfig *configP = static_cast(getRootConfig()->fAgentConfigP); bool handled=true; const char *txt; SmlMetInfMetInfPtr_t chalmetaP=NULL; SmlChalPtr_t chalP; // first evaluate possible challenge in header status chalP = aStatusCmdP->getStatusElement()->chal; if (chalP) { chalmetaP = smlPCDataToMetInfP(chalP->meta); if (chalmetaP) { sInt16 ty; // - get auth type if (!chalmetaP->type) AbortSession(401,true); // missing auth, but no type txt = smlPCDataToCharP(chalmetaP->type); PDEBUGPRINTFX(DBG_PROTO,("Remote requests auth type='%s'",txt)); if (StrToEnum(authTypeSyncMLNames,numAuthTypes,ty,txt)) fRemoteRequestedAuth=(TAuthTypes)ty; else { AbortSession(406,true); // unknown auth type, not supported goto donewithstatus; } // - get auth format if (!smlPCDataToFormat(chalmetaP->format, fRemoteRequestedAuthEnc)) { AbortSession(406,true); // unknown auth format, not supported goto donewithstatus; } // - get next nonce if (chalmetaP->nextnonce) { // decode B64 uInt32 l; uInt8 *nonce = b64::decode(smlPCDataToCharP(chalmetaP->nextnonce), 0, &l); fRemoteNonce.assign((char *)nonce,l); b64::free(nonce); } // - show PDEBUGPRINTFX(DBG_PROTO,( "Next Cred will have type='%s' and format='%s' and use nonce='%s'", authTypeNames[fRemoteRequestedAuth], encodingFmtNames[fRemoteRequestedAuthEnc], fRemoteNonce.c_str() )); } /* %%% do not save here already, we don't know if SyncML version is ok moved to those status code cases below that signal // let descendant possibly save auth params saveRemoteParams(); */ } // now evaluate status code switch (aStatusCmdP->getStatusCode()) { case 101: // Busy // Abort AbortSession(101,false); break; case 212: // authentication accepted for entire session fNeedAuth=false; // no need for further auth PDEBUGPRINTFX(DBG_PROTO,("Remote accepted authentication for entire session")); case 200: // authentication accepted for this message // if this is the first authorized message we get an OK for the synchdr, this is // also the first incoming message that is really processed as init message if (fIncomingState==psta_idle && fMessageAuthorized) { // first incoming is expected to be same as first outgoing (init or initsync) fIncomingState=fOutgoingState; PDEBUGPRINTFX(DBG_PROTO,("Authenticated successfully with remote server")); } else { PDEBUGPRINTFX(DBG_PROTO,("Authentication with server ok for this message")); } // let descendant possibly save auth params saveRemoteParams(); break; case 501: // handle a "command not implemented" for the SyncHdr like 513 (indication that server does not like our header) case 400: // ..and 400 as well (sync4j case, as it seems) case 513: // bad protocol version case 505: // bad DTD version (NextHaus/DeskNow case) // try with next lower protocol PDEBUGENDBLOCK("processStatus"); // done processing status if (!retryOlderProtocol()) { // no older SyncML protocol we can try --> abort AbortSession(513,false); // server does not know any of our SyncML versions } break; case 401: // bad authentication // Bad authorisation if (fAuthRetries==0) // if first attempt is rejected with "bad", we conclude that the // last attempt was carrying auth data and was not a attempt to get challenge // from server. Therefore we count this as two tries (one get chal, one really failing) fAuthRetries=2; else fAuthRetries++; // just count attempt to auth /* %%% no longer required, is tested below at authfail: if (fAuthRetries>MAX_AUTH_RETRIES) { AbortSession(401,false); // abort session, too many retries break; } */ // Treat no nonce like empty nonce to make sure that a server (like SySync old versions...) // that does not send a nonce at all does not get auth with some old, invalid nonce string included. if (chalmetaP && chalmetaP->nextnonce==NULL) fRemoteNonce.erase(); // otherwise treat like 407 goto authfail; case 407: // authentication required // new since 2.0.4.6: count this as well (normally this happens once when sending // no auth to the server to force it to send us auth chal first). fAuthRetries++; authfail: PDEBUGPRINTFX(DBG_ERROR,("Authentication failed (status=%hd) with remote server",aStatusCmdP->getStatusCode())); // Auth fail after we have received a valid response for the init message indicates protocol messed up if (fIncomingState!=psta_idle) { AbortSession(400,true); // error in protocol handling from remote break; } // Check if smart retries (with modified in-session vs out-of-session behaviour) are enabled if (!configP->fSmartAuthRetry && fAuthRetries>MAX_NORMAL_AUTH_RETRIES) { fAuthRetries = MAX_SMART_AUTH_RETRIES+1; // skip additional smart retries } // Missing or bad authorisation, evaluate chal if (!chalmetaP || fAuthRetries>MAX_SMART_AUTH_RETRIES) { #ifdef SYDEBUG if (!chalmetaP) { PDEBUGPRINTFX(DBG_ERROR,("Bad auth but no challenge in response status -> can't work - no retry")); } #endif AbortSession(aStatusCmdP->getStatusCode(),false); // retries exhausted or no retry possible (no chal) -> stop session break; } // let descendant possibly save auth params saveRemoteParams(); // modify session for re-start PDEBUGENDBLOCK("processStatus"); // done processing status retryClientSessionStart(false); // no previously sent message in the buffer break; default: handled=false; // could not handle status } // switch donewithstatus: // Anyway, reception of status for header enables generation of next message header // (plus already generated commands such as status for response header) if (!fMsgNoResp && !isAborted()) { // issue header now if not already issued above if (!fOutgoingStarted) { // interrupt status processing block here as issueHeader will do a start-of-message PDEBUGBLOCK PDEBUGENDBLOCK("processStatus"); issueHeader(false); PDEBUGBLOCKDESC("processStatus","finishing processing incoming SyncHdr Status"); } } // return handled status return handled; #endif // SYSYNC_SERVER } else { // nothing special return inherited::handleHeaderStatus(aStatusCmdP); } } // TSyncAgent::handleHeaderStatus // - start sync group (called in client or server roles) bool TSyncAgent::processSyncStart( SmlSyncPtr_t aSyncP, // the Sync element TStatusCommand &aStatusCommand, // pre-set 200 status, can be modified in case of errors bool &aQueueForLater // will be set if command must be queued for later (re-)execution ) { if (IS_CLIENT) { #ifdef SYSYNC_CLIENT if (fIncomingState!=psta_sync && fIncomingState!=psta_initsync) { aStatusCommand.setStatusCode(403); // forbidden in this context PDEBUGPRINTFX(DBG_ERROR,("Sync command not allowed outside of sync phase (-> 403)")); AbortSession(400,true); return false; } // just find appropriate database, must be already initialized for sync! // determine local database to sync with (target) TLocalEngineDS *datastoreP = findLocalDataStoreByURI(smlSrcTargLocURIToCharP(aSyncP->target)); if (!datastoreP) { // no such local datastore PDEBUGPRINTFX(DBG_ERROR,("Sync command for unknown DS locURI '%s' (-> 404)",smlSrcTargLocURIToCharP(aSyncP->target))); aStatusCommand.setStatusCode(404); // not found return false; } else { // save the pointer, will e.g. be used to route subsequent server commands fLocalSyncDatastoreP=datastoreP; // let local datastore know return fLocalSyncDatastoreP->engProcessSyncCmd(aSyncP,aStatusCommand,aQueueForLater); } return true; #endif // SYSYNC_CLIENT } else { #ifdef SYSYNC_SERVER // Init datastores for sync localstatus sta = initSync( smlSrcTargLocURIToCharP(aSyncP->target), // local datastore smlSrcTargLocURIToCharP(aSyncP->source) // remote datastore ); if (sta!=LOCERR_OK) { aStatusCommand.setStatusCode(sta); return false; } // let local datastore prepare for sync as server // - let local process sync command bool ok=fLocalSyncDatastoreP->engProcessSyncCmd(aSyncP,aStatusCommand,aQueueForLater); // Note: ok means that the sync command is addressing existing datastores. However, // it does not mean that the actual processing is already executed; aQueueForLater // could be set! // if ok and not queued: update package states if (ok) { if (fIncomingState==psta_init || fIncomingState==psta_initsync) { // detected sync command in init package -> this is combined init/sync #ifdef SYDEBUG if (fIncomingState==psta_init) DEBUGPRINTFX(DBG_HOT,(" started init package -> switching to combined init/sync")); #endif // - set new incoming state fIncomingState=psta_initsync; // - also update outgoing state, if it is in init package if (fOutgoingState==psta_init) fOutgoingState=psta_initsync; } else if (fCmdIncomingState!=psta_sync) { DEBUGPRINTFX(DBG_ERROR,( " found in wrong incoming package state '%s' -> aborting session", PackageStateNames[fCmdIncomingState] )); aStatusCommand.setStatusCode(403); // forbidden fLocalSyncDatastoreP->engAbortDataStoreSync(403,true); // abort, local problem ok=false; } else { // - show sync start DEBUGPRINTFX(DBG_HOT,( " started, cmd-incoming state='%s', incoming state='%s', outgoing state='%s'", PackageStateNames[fCmdIncomingState], PackageStateNames[fIncomingState], PackageStateNames[fOutgoingState] )); } } return ok; #endif // SYSYNC_SERVER } } // TSyncAgent::processSyncStart #ifdef ENGINEINTERFACE_SUPPORT // Support for EngineModule common interface // ========================================= /// @brief Get new session key to access details of this session appPointer TSyncAgent::newSessionKey(TEngineInterface *aEngineInterfaceP) { return new TAgentParamsKey(aEngineInterfaceP,this); } // TSyncAgent::newSessionKey #ifdef ENGINE_LIBRARY TSyError TSyncAgent::SessionStep(uInt16 &aStepCmd, TEngineProgressInfo *aInfoP) { #ifdef NON_FULLY_GRANULAR_ENGINE // pre-process step command and generate pseudo-steps to empty progress event queue // preprocess general step codes switch (aStepCmd) { case STEPCMD_TRANSPFAIL : // directly abort AbortSession(LOCERR_TRANSPFAIL,true); goto abort; case STEPCMD_ABORT : // directly abort AbortSession(LOCERR_USERABORT,true); abort: // also set the flag so subsequent progress events will result the abort status fAbortRequested=true; aStepCmd = STEPCMD_STEP; // convert to normal step goto step; case STEPCMD_SUSPEND : // directly suspend SuspendSession(LOCERR_USERSUSPEND); // also set the flag so subsequent pev_suspendcheck events will result the suspend status fSuspendRequested=true; aStepCmd = STEPCMD_OK; // this is a out-of-order step, and always just returns STEPCMD_OK. fEngineSessionStatus = 0; // ok for now, subsequent steps will perform the actual suspend goto done; // no more action for now case STEPCMD_STEP : step: // first just return all queued up progress events if (fProgressInfoList.size()>0) { // get first element in list TEngineProgressInfoList::iterator pos = fProgressInfoList.begin(); // pass it back to caller if caller is interested if (aInfoP) { *aInfoP = *pos; // copy progress event } // delete progress event from list fProgressInfoList.erase(pos); // that's it for now, engine state does not change, wait for next step aStepCmd = STEPCMD_PROGRESS; return LOCERR_OK; } else if (fPendingStepCmd != 0) { // now return previously generated step command // Note: engine is already in the new state matching fPendingStepCmd aStepCmd = fPendingStepCmd; fEngineSessionStatus = fPendingStatus; fPendingStepCmd=0; // none pending any more fPendingStatus=0; return fEngineSessionStatus; // return pending status now } // all progress events are delivered, now we can do the real work } #endif // NON_FULLY_GRANULAR_ENGINE // Now perform the actual step if (IS_CLIENT) { #ifdef SYSYNC_CLIENT fEngineSessionStatus = ClientSessionStep(aStepCmd,aInfoP); #endif // SYSYNC_CLIENT } else { #ifdef SYSYNC_SERVER fEngineSessionStatus = ServerSessionStep(aStepCmd,aInfoP); #endif // SYSYNC_SERVER } #ifdef NON_FULLY_GRANULAR_ENGINE // make sure caller issues STEPCMD_STEP to get all pending progress events if (fProgressInfoList.size()>0) { // save pending step command for returning later fPendingStepCmd = aStepCmd; fPendingStatus = fEngineSessionStatus; // return request for more steps instead aStepCmd = STEPCMD_OK; fEngineSessionStatus = LOCERR_OK; } #endif // NON_FULLY_GRANULAR_ENGINE done: // return step status return fEngineSessionStatus; } // TSyncAgent::SessionStep #ifdef PROGRESS_EVENTS bool TSyncAgent::HandleSessionProgressEvent(TEngineProgressInfo aProgressInfo) { // handle some events specially if (aProgressInfo.eventtype==pev_suspendcheck) return !(fSuspendRequested); else { // engine progress record that needs to be queued // - check for message if (aProgressInfo.eventtype==pev_display100) { // this is a pointer to a string, save it separately // extra1 is a pointer to the message text // - save it for retrieval via SessionKey fAlertMessage = (cAppCharP)(aProgressInfo.extra1); // - don't pass pointer aProgressInfo.extra1 = 0; } // queue progress event fProgressInfoList.push_back(aProgressInfo); } return !(fAbortRequested); } // TSyncAgent::HandleSessionProgressEvent #endif // PROGRESS_EVENTS #endif // ENGINE_LIBRARY #ifdef SYSYNC_SERVER // Server implementation // --------------------- #ifndef ENGINE_LIBRARY // dummy server engine support to allow AsKey from plugins #warning "using ENGINEINTERFACE_SUPPORT in old-style appbase-rooted environment. Should be converted to real engine usage later" // Engine factory function for non-Library case ENGINE_IF_CLASS *newServerEngine(void) { // For real engine based targets, newServerEngine must create a target-specific derivate // of the server engine, which then has a suitable newSyncAppBase() method to create the // appBase. For old-style environment, a generic TServerEngineInterface is ok, as this // in turn calls the global newSyncAppBase() which then returns the appropriate // target specific appBase. Here we just return a dummy server engine base. return new TDummyServerEngineInterface; } // newServerEngine /// @brief returns a new application base. TSyncAppBase *TDummyServerEngineInterface::newSyncAppBase(void) { // For not really engine based targets, the appbase factory function is // a global routine (for real engine targets, it is a true virtual of // the engineInterface, implemented in the target's leaf engineInterface derivate. // - for now, use the global appBase creator routine return sysync::newSyncAppBase(); // use global factory function } // TDummyServerEngineInterface::newSyncAppBase #else // old style // Real server engine support /// @brief Executes next step of the session /// @param aStepCmd[in/out] step command (STEPCMD_xxx): /// - tells caller to send or receive data or end the session etc. /// - instructs engine to abort or time out the session etc. /// @param aInfoP[in] pointer to a TEngineProgressInfo structure, NULL if no progress info needed /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure TSyError TSyncAgent::ServerSessionStep(uInt16 &aStepCmd, TEngineProgressInfo *aInfoP) { uInt16 stepCmdIn = aStepCmd; localstatus sta = LOCERR_WRONGUSAGE; // init default response aStepCmd = STEPCMD_ERROR; // error if (aInfoP) { aInfoP->eventtype=PEV_NOP; aInfoP->targetID=0; aInfoP->extra1=0; aInfoP->extra2=0; aInfoP->extra3=0; } // if session is already aborted, no more steps are required if (isAborted()) { fServerEngineState = ses_done; // we are done } // handle pre-processed step command according to current engine state switch (fServerEngineState) { // Almost done state case ses_almostdone: // everything done, except for termination of session // - do it now TerminateSession(); // - now done fServerEngineState = ses_done; // fall through to done state // Done state case ses_done : // session done, nothing happens any more aStepCmd = STEPCMD_DONE; sta = LOCERR_OK; break; // Waiting for SyncML request data case ses_needdata: switch (stepCmdIn) { case STEPCMD_GOTDATA : { // got data, check content type MemPtr_t data = NULL; smlPeekMessageBuffer(getSmlWorkspaceID(), false, &data, &fRequestSize); // get request size SmlEncoding_t enc = TSyncAppBase::encodingFromData(data, fRequestSize); if (getEncoding()==SML_UNDEF) { // no encoding known so far - use what we found from looking at data PDEBUGPRINTFX(DBG_ERROR,( "Incoming data had no or invalid content type, Determined encoding by looking at data: %s", SyncMLEncodingNames[enc] )); setEncoding(enc); } else if (getEncoding()!=enc) { // already known encoding does not match actual encoding PDEBUGPRINTFX(DBG_ERROR,( "Warning: Incoming data encoding mismatch: expected=%s, found=%s", SyncMLEncodingNames[getEncoding()], SyncMLEncodingNames[enc] )); } if (getEncoding()==SML_UNDEF) { // if session encoding is still unknown at this point, reject data as non-SyncML PDEBUGPRINTFX(DBG_ERROR,("Incoming data is not SyncML")); sta = LOCERR_BADCONTENT; // bad content type aStepCmd = STEPCMD_ERROR; // Note: we do not abort the session here - app could have a retry strategy and re-enter // this step with better data break; } // content type ok - switch to processing mode fServerEngineState = ses_processing; aStepCmd = STEPCMD_OK; sta = LOCERR_OK; break; } } // switch stepCmdIn for ses_needdata break; // Waiting until SyncML answer data is sent // (only when session needs to continue, otherwise we are in ses_done) case ses_dataready: switch (stepCmdIn) { case STEPCMD_SENTDATA : // sent data, now wait for next request fServerEngineState = ses_needdata; aStepCmd = STEPCMD_NEEDDATA; sta = LOCERR_OK; break; } // switch stepCmdIn for ses_dataready break; // Ready for generation steps case ses_generating: switch (stepCmdIn) { case STEPCMD_STEP : sta = ServerGeneratingStep(aStepCmd,aInfoP); break; } // switch stepCmdIn for ses_generating break; // Ready for processing steps case ses_processing: switch (stepCmdIn) { case STEPCMD_STEP : sta = ServerProcessingStep(aStepCmd,aInfoP); break; } // switch stepCmdIn for ses_processing break; case numServerEngineStates: // invalid break; } // switch fServerEngineState // done return sta; } // TSyncAgent::ServerSessionStep // Step that processes SyncML request data TSyError TSyncAgent::ServerProcessingStep(uInt16 &aStepCmd, TEngineProgressInfo *aInfoP) { localstatus sta = LOCERR_WRONGUSAGE; InstanceID_t myInstance = getSmlWorkspaceID(); Ret_t rc; // now process next command PDEBUGPRINTFX(DBG_EXOTIC,("Calling smlProcessData(NEXT_COMMAND)")); #ifdef SYDEBUG MemPtr_t data = NULL; MemSize_t datasize; smlPeekMessageBuffer(getSmlWorkspaceID(), false, &data, &datasize); #endif rc=smlProcessData( myInstance, SML_NEXT_COMMAND ); if (rc==SML_ERR_CONTINUE) { // processed ok, but message not completely processed yet // - engine state remains as is aStepCmd = STEPCMD_OK; // ok w/o progress %%% for now, progress is delivered via queue in next step sta = LOCERR_OK; } else if (rc==SML_ERR_OK) { // message completely processed // - switch engine state to generating answer message (if any) aStepCmd = STEPCMD_OK; fServerEngineState = ses_generating; sta = LOCERR_OK; } else if (rc==LOCERR_RETRYMSG) { // server has detected that this message is a retry - report this to the app such that app can // first discard the instance buffer (consume everything in it) if (smlLockReadBuffer(myInstance,&data,&datasize)==SML_ERR_OK) smlUnlockReadBuffer(myInstance,datasize); // indicate that transport must resend the previous response PDEBUGPRINTFX(DBG_ERROR,( "Incoming message was identified as a retry - report STEPCMD_RESENDDATA - caller must resent last response" )); aStepCmd = STEPCMD_RESENDDATA; fServerEngineState = ses_dataready; } else { // processing failed PDEBUGPRINTFX(DBG_ERROR,("===> smlProcessData failed, returned 0x%hX",(sInt16)rc)); // dump the message that failed to process #ifdef SYDEBUG if (data) DumpSyncMLBuffer(data,datasize,false,rc); #endif // abort the session (causing proper error events to be generated and reported back) AbortSession(LOCERR_PROCESSMSG, true); // session is now done fServerEngineState = ses_done; // step by itself is ok - let app continue stepping (to restart session or complete abort) aStepCmd = STEPCMD_OK; sta = LOCERR_OK; } // done return sta; } // TSyncAgent::ServerProcessingStep // Step that generates (rest of) SyncML answer data at end of request TSyError TSyncAgent::ServerGeneratingStep(uInt16 &aStepCmd, TEngineProgressInfo *aInfoP) { bool done, hasdata; string respURI; // finish request done = EndRequest(hasdata, respURI, fRequestSize); // check different exit points if (hasdata) { // there is data to be sent aStepCmd = STEPCMD_SENDDATA; fServerEngineState = ses_dataready; } else { // no more data to send aStepCmd = STEPCMD_OK; // need one more step to finish } // in any case, if done, subsequent steps will terminate the session and return STEPCMD_DONE if (done) { // subsequent steps will all return STEPCMD_DONE fServerEngineState = ses_almostdone; } // request reset fRequestSize = 0; // finished generating outgoing message // - make sure read pointer is set (advanced in case incoming // message had trailing garbage) to beginning of generated // answer. With incoming message being clean SyncML without // garbage, this call is not needed, however with garbage // it is important because otherwise outgoing message // would have that garbage inserted before actual message // start. smlReadOutgoingAgain(getSmlWorkspaceID()); // return status return LOCERR_OK; } // TSyncAgent::ServerGeneratingStep #endif // ENGINE_LIBRARY #endif // SYSYNC_SERVER #ifdef SYSYNC_CLIENT #ifdef ENGINE_LIBRARY // Client implementation // --------------------- /// @brief Executes next step of the session /// @param aStepCmd[in/out] step command (STEPCMD_xxx): /// - tells caller to send or receive data or end the session etc. /// - instructs engine to suspend or abort the session etc. /// @param aInfoP[in] pointer to a TEngineProgressInfo structure, NULL if no progress info needed /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure TSyError TSyncAgent::ClientSessionStep(uInt16 &aStepCmd, TEngineProgressInfo *aInfoP) { uInt16 stepCmdIn = aStepCmd; localstatus sta = LOCERR_WRONGUSAGE; // init default response aStepCmd = STEPCMD_ERROR; // error if (aInfoP) { aInfoP->eventtype=PEV_NOP; aInfoP->targetID=0; aInfoP->extra1=0; aInfoP->extra2=0; aInfoP->extra3=0; } // if session is already aborted, no more steps are required if (isAborted()) { fClientEngineState = ces_done; // we are done } // handle pre-processed step command according to current engine state switch (fClientEngineState) { // Idle state case ces_done : { // session done, nothing happens any more aStepCmd = STEPCMD_DONE; sta = LOCERR_OK; break; } case ces_idle : { // in idle, we can only start a session switch (stepCmdIn) { case STEPCMD_CLIENTSTART: case STEPCMD_CLIENTAUTOSTART: // initialize a new session sta = InitializeSession(fProfileSelectorInternal,stepCmdIn==STEPCMD_CLIENTAUTOSTART); if (sta!=LOCERR_OK) break; // engine is now ready, start generating first request fClientEngineState = ces_generating; // ok with no status aStepCmd = STEPCMD_OK; break; } // switch stepCmdIn for ces_idle break; } // Ready for generation steps case ces_generating: { switch (stepCmdIn) { case STEPCMD_STEP : sta = ClientGeneratingStep(aStepCmd,aInfoP); break; } // switch stepCmdIn for ces_generating break; } // Ready for processing steps case ces_processing: { switch (stepCmdIn) { case STEPCMD_STEP : sta = ClientProcessingStep(aStepCmd,aInfoP); break; } // switch stepCmdIn for ces_processing break; } // Waiting for SyncML data case ces_needdata: { switch (stepCmdIn) { case STEPCMD_GOTDATA : { // got data, now start processing it SESSION_PROGRESS_EVENT(this,pev_recvend,NULL,0,0,0); // check content type now MemPtr_t data = NULL; MemSize_t datasize; if (smlPeekMessageBuffer(getSmlWorkspaceID(), false, &data, &datasize) != SML_ERR_OK) { // SyncML TK has a problem when asked to store an empty message: // it then returns SML_ERR_WRONG_USAGE in smlPeekMessageBuffer and // leaves datasize unset. Happened after an application bug. // // Avoid undefined behavior and proceed without data (easier than // introducing an additional, untested error path). data = NULL; datasize = 0; } // check content type SmlEncoding_t enc = TSyncAppBase::encodingFromData(data, datasize); if (enc!=getEncoding()) { PDEBUGPRINTFX(DBG_ERROR,("Incoming data is not SyncML")); sta = LOCERR_BADCONTENT; // bad content type #ifdef SYDEBUG if (data) DumpSyncMLBuffer(data,datasize,false,SML_ERR_UNSPECIFIC); #endif // abort the session (causing proper error events to be generated and reported back) AbortSession(sta, true); // session is now done fClientEngineState = ces_done; aStepCmd = STEPCMD_ERROR; break; } // content type ok - switch to processing mode fIgnoreMsgErrs=false; // do not ignore errors by default fClientEngineState = ces_processing; aStepCmd = STEPCMD_OK; sta = LOCERR_OK; break; } case STEPCMD_RESENDDATA : // instead of having received new data, the network layer has found it needs to re-send the data. // performing the STEPCMD_RESENDDATA just generates a new send start event, but otherwise no engine action fClientEngineState = ces_resending; aStepCmd = STEPCMD_RESENDDATA; // return the same step command, to differentiate it from STEPCMD_SENDDATA SESSION_PROGRESS_EVENT(this,pev_sendstart,NULL,0,0,0); sta = LOCERR_OK; break; } // switch stepCmdIn for ces_needdata break; } // Waiting until SyncML data is sent case ces_dataready: case ces_resending: { switch (stepCmdIn) { case STEPCMD_SENTDATA : // allowed in dataready or resending state // sent (or re-sent) data, now request answer data SESSION_PROGRESS_EVENT(this,pev_sendend,NULL,0,0,0); fClientEngineState = ces_needdata; aStepCmd = STEPCMD_NEEDDATA; sta = LOCERR_OK; break; } // switch stepCmdIn for ces_dataready break; } case numClientEngineStates: { // invalid break; } } // switch fClientEngineState // done return sta; } // TSyncAgent::ClientSessionStep // Step that generates SyncML data TSyError TSyncAgent::ClientGeneratingStep(uInt16 &aStepCmd, TEngineProgressInfo *aInfoP) { localstatus sta = LOCERR_WRONGUSAGE; bool done; //%%% at this time, generate next message in one step sta = NextMessage(done); if (done) { // done with session, with or without error fClientEngineState = ces_done; // blocks any further activity with the session aStepCmd = STEPCMD_DONE; // terminate session to provoke all end-of-session progress events TerminateSession(); } else if (sta==LOCERR_OK) { // finished generating outgoing message // - make sure read pointer is set (advanced in case incoming // message had trailing garbage) to beginning of generated // answer. With incoming message being clean SyncML without // garbage, this call is not needed, however with garbage // it is important because otherwise outgoing message // would have that garbage inserted before actual message // start. smlReadOutgoingAgain(getSmlWorkspaceID()); // next is sending request to server fClientEngineState = ces_dataready; aStepCmd = STEPCMD_SENDDATA; SESSION_PROGRESS_EVENT(this,pev_sendstart,NULL,0,0,0); } // return status return sta; } // TSyncAgent::ClientGeneratingStep // Step that processes SyncML data TSyError TSyncAgent::ClientProcessingStep(uInt16 &aStepCmd, TEngineProgressInfo *aInfoP) { InstanceID_t myInstance = getSmlWorkspaceID(); Ret_t rc; localstatus sta = LOCERR_WRONGUSAGE; // now process next command PDEBUGPRINTFX(DBG_EXOTIC,("Calling smlProcessData(NEXT_COMMAND)")); #ifdef SYDEBUG MemPtr_t data = NULL; MemSize_t datasize; smlPeekMessageBuffer(getSmlWorkspaceID(), false, &data, &datasize); #endif rc=smlProcessData( myInstance, SML_NEXT_COMMAND ); if (rc==SML_ERR_CONTINUE) { // processed ok, but message not completely processed yet // - engine state remains as is aStepCmd = STEPCMD_OK; // ok w/o progress %%% for now, progress is delivered via queue in next step sta = LOCERR_OK; } else if (rc==SML_ERR_OK) { // message completely processed // - switch engine state to generating next message (if any) aStepCmd = STEPCMD_OK; fClientEngineState = ces_generating; sta = LOCERR_OK; } else { // processing failed PDEBUGPRINTFX(DBG_ERROR,("===> smlProcessData failed, returned 0x%hX",(sInt16)rc)); // dump the message that failed to process #ifdef SYDEBUG if (data) DumpSyncMLBuffer(data,datasize,false,rc); #endif if (!fIgnoreMsgErrs) { // abort the session (causing proper error events to be generated and reported back) AbortSession(LOCERR_PROCESSMSG, true); // session is now done fClientEngineState = ces_done; } else { // we must ignore errors e.g. because of session restart and go back to generate next message fClientEngineState = ces_generating; } // anyway, step by itself is ok - let app continue stepping (to restart session or complete abort) aStepCmd = STEPCMD_OK; sta = LOCERR_OK; } // now check if this is a session restart if (sta==LOCERR_OK && isStarting()) { // this is still the beginning of a session, which means // that we are restarting the session and caller should close // possibly open communication with the server before sending the next message aStepCmd = STEPCMD_RESTART; } // done return sta; } // TSyncAgent::ClientProcessingStep #endif // ENGINE_LIBRARY #endif // SYSYNC_CLIENT // Session runtime settings key // --------------------------- // Constructor TAgentParamsKey::TAgentParamsKey(TEngineInterface *aEngineInterfaceP, TSyncAgent *aAgentP) : inherited(aEngineInterfaceP,aAgentP), fAgentP(aAgentP) { } // TAgentParamsKey::TAgentParamsKey // - read local session ID static TSyError readLocalSessionID( TStructFieldsKey *aStructFieldsKeyP, const TStructFieldInfo *aFldInfoP, appPointer aBuffer, memSize aBufSize, memSize &aValSize ) { TAgentParamsKey *mykeyP = static_cast(aStructFieldsKeyP); return TStructFieldsKey::returnString( mykeyP->fAgentP->getLocalSessionID(), aBuffer,aBufSize,aValSize ); } // readLocalSessionID // - read initial local URI static TSyError readInitialLocalURI( TStructFieldsKey *aStructFieldsKeyP, const TStructFieldInfo *aFldInfoP, appPointer aBuffer, memSize aBufSize, memSize &aValSize ) { TAgentParamsKey *mykeyP = static_cast(aStructFieldsKeyP); return TStructFieldsKey::returnString( mykeyP->fAgentP->getInitialLocalURI(), aBuffer,aBufSize,aValSize ); } // readInitialLocalURI // - read abort status static TSyError readAbortStatus( TStructFieldsKey *aStructFieldsKeyP, const TStructFieldInfo *aFldInfoP, appPointer aBuffer, memSize aBufSize, memSize &aValSize ) { TAgentParamsKey *mykeyP = static_cast(aStructFieldsKeyP); return TStructFieldsKey::returnInt( mykeyP->fAgentP->getAbortReasonStatus(), sizeof(TSyError), aBuffer,aBufSize,aValSize ); } // readAbortStatus // - write abort status, which means aborting a session TSyError writeAbortStatus( TStructFieldsKey *aStructFieldsKeyP, const TStructFieldInfo *aFldInfoP, cAppPointer aBuffer, memSize aValSize ) { TAgentParamsKey *mykeyP = static_cast(aStructFieldsKeyP); // abort the session TSyError sta = *((TSyError *)aBuffer); mykeyP->fAgentP->AbortSession(sta, true); return LOCERR_OK; } // writeAbortStatus // - read content type string static TSyError readContentType( TStructFieldsKey *aStructFieldsKeyP, const TStructFieldInfo *aFldInfoP, appPointer aBuffer, memSize aBufSize, memSize &aValSize ) { TAgentParamsKey *mykeyP = static_cast(aStructFieldsKeyP); string contentType = SYNCML_MIME_TYPE; mykeyP->fAgentP->addEncoding(contentType); return TStructFieldsKey::returnString( contentType.c_str(), aBuffer,aBufSize,aValSize ); } // readContentType // - write content type string static TSyError writeContentType( TStructFieldsKey *aStructFieldsKeyP, const TStructFieldInfo *aFldInfoP, cAppPointer aBuffer, memSize aValSize ) { string contentType((cAppCharP)aBuffer,aValSize); TAgentParamsKey *mykeyP = static_cast(aStructFieldsKeyP); mykeyP->fAgentP->setEncoding(TSyncAppBase::encodingFromContentType(contentType.c_str())); return LOCERR_OK; } // writeContentType // - read connection URL static TSyError readConnectURI( TStructFieldsKey *aStructFieldsKeyP, const TStructFieldInfo *aFldInfoP, appPointer aBuffer, memSize aBufSize, memSize &aValSize ) { TAgentParamsKey *mykeyP = static_cast(aStructFieldsKeyP); return TStructFieldsKey::returnString( mykeyP->fAgentP->getSendURI(), aBuffer,aBufSize,aValSize ); } // readConnectURI // - read host part of connection URL static TSyError readConnectHost( TStructFieldsKey *aStructFieldsKeyP, const TStructFieldInfo *aFldInfoP, appPointer aBuffer, memSize aBufSize, memSize &aValSize ) { TAgentParamsKey *mykeyP = static_cast(aStructFieldsKeyP); string host, port; splitURL(mykeyP->fAgentP->getSendURI(),NULL,&host,NULL,NULL,NULL,&port,NULL); // old semantic of splitURL was to include port in host string, // continue doing that if (!port.empty()) { host += ':'; host += port; } return TStructFieldsKey::returnString( host.c_str(), aBuffer,aBufSize,aValSize ); } // readConnectHost // - read document part of connection URL static TSyError readConnectDoc( TStructFieldsKey *aStructFieldsKeyP, const TStructFieldInfo *aFldInfoP, appPointer aBuffer, memSize aBufSize, memSize &aValSize ) { TAgentParamsKey *mykeyP = static_cast(aStructFieldsKeyP); string doc, query; splitURL(mykeyP->fAgentP->getSendURI(),NULL,NULL,&doc,NULL,NULL,NULL,&query); // old semantic of splitURL was to include query in document string, // continue doing that if (!query.empty()) { doc += '?'; doc += query; } return TStructFieldsKey::returnString( doc.c_str(), aBuffer,aBufSize,aValSize ); } // readConnectDoc // - time when session was last used static TSyError readLastUsed( TStructFieldsKey *aStructFieldsKeyP, const TStructFieldInfo *aFldInfoP, appPointer aBuffer, memSize aBufSize, memSize &aValSize ) { TAgentParamsKey *mykeyP = static_cast(aStructFieldsKeyP); // return it return TStructFieldsKey::returnLineartime(mykeyP->fAgentP->getSessionLastUsed(), aBuffer, aBufSize, aValSize); } // readLastUsed // - server only: check session timeout static TSyError readTimedOut( TStructFieldsKey *aStructFieldsKeyP, const TStructFieldInfo *aFldInfoP, appPointer aBuffer, memSize aBufSize, memSize &aValSize ) { TAgentParamsKey *mykeyP = static_cast(aStructFieldsKeyP); // check if session has timed out bool timedout = mykeyP->fAgentP->getSessionLastUsed()+mykeyP->fAgentP->getSessionConfig()->getSessionTimeout() < mykeyP->fAgentP->getSystemNowAs(TCTX_UTC); // return it return TStructFieldsKey::returnInt(timedout, sizeof(bool), aBuffer, aBufSize, aValSize); } // readTimedOut // - show if this is a server (for DB plugins) static TSyError readIsServer( TStructFieldsKey *aStructFieldsKeyP, const TStructFieldInfo *aFldInfoP, appPointer aBuffer, memSize aBufSize, memSize &aValSize ) { TAgentParamsKey *mykeyP = static_cast(aStructFieldsKeyP); return TStructFieldsKey::returnInt(mykeyP->fAgentP->getSyncAppBase()->isServer(), sizeof(bool), aBuffer, aBufSize, aValSize); } // readIsServer #ifdef SYSYNC_SERVER // - server only: read respURI enable flag static TSyError readSendRespURI( TStructFieldsKey *aStructFieldsKeyP, const TStructFieldInfo *aFldInfoP, appPointer aBuffer, memSize aBufSize, memSize &aValSize ) { TAgentParamsKey *mykeyP = static_cast(aStructFieldsKeyP); return TStructFieldsKey::returnInt(mykeyP->fAgentP->fUseRespURI, sizeof(bool), aBuffer, aBufSize, aValSize); } // readSendRespURI // - write respURI enable flag static TSyError writeSendRespURI( TStructFieldsKey *aStructFieldsKeyP, const TStructFieldInfo *aFldInfoP, cAppPointer aBuffer, memSize aValSize ) { TAgentParamsKey *mykeyP = static_cast(aStructFieldsKeyP); mykeyP->fAgentP->fUseRespURI = *((uInt8P)aBuffer); return LOCERR_OK; } // writeSendRespURI #endif // SYSYNC_SERVER #ifdef SYSYNC_CLIENT // - write (volatile, write-only) password for running this session // (for cases where we don't want to rely on binfile storage for sensitive password data) TSyError writeSessionPassword( TStructFieldsKey *aStructFieldsKeyP, const TStructFieldInfo *aFldInfoP, cAppPointer aBuffer, memSize aValSize ) { TAgentParamsKey *mykeyP = static_cast(aStructFieldsKeyP); mykeyP->fAgentP->setServerPassword((cAppCharP)aBuffer, aValSize); return LOCERR_OK; } // writeSessionPassword #ifdef ENGINE_LIBRARY // - read display alert static TSyError readDisplayAlert( TStructFieldsKey *aStructFieldsKeyP, const TStructFieldInfo *aFldInfoP, appPointer aBuffer, memSize aBufSize, memSize &aValSize ) { TAgentParamsKey *mykeyP = static_cast(aStructFieldsKeyP); return TStructFieldsKey::returnString( mykeyP->fAgentP->fAlertMessage.c_str(), aBuffer,aBufSize,aValSize ); } // readDisplayAlert #endif #endif // SYSYNC_CLIENT static TSyError readRestartSync( TStructFieldsKey *aStructFieldsKeyP, const TStructFieldInfo *aFldInfoP, appPointer aBuffer, memSize aBufSize, memSize &aValSize ) { TAgentParamsKey *mykeyP = static_cast(aStructFieldsKeyP); return TStructFieldsKey::returnInt(mykeyP->fAgentP->fRestartSyncOnce, sizeof(bool), aBuffer, aBufSize, aValSize); } // readRestartsync // - write respURI enable flag static TSyError writeRestartSync( TStructFieldsKey *aStructFieldsKeyP, const TStructFieldInfo *aFldInfoP, cAppPointer aBuffer, memSize aValSize ) { TAgentParamsKey *mykeyP = static_cast(aStructFieldsKeyP); mykeyP->fAgentP->fRestartSyncOnce = *((uInt8P)aBuffer); return LOCERR_OK; } // writeRestartSync // - write error message into session log TSyError writeErrorMsg( TStructFieldsKey *aStructFieldsKeyP, const TStructFieldInfo *aFldInfoP, cAppPointer aBuffer, memSize aValSize ) { TAgentParamsKey *mykeyP = static_cast(aStructFieldsKeyP); string msg; msg.assign((cAppCharP)aBuffer, aValSize); POBJDEBUGPRINTFX(mykeyP->fAgentP,DBG_ERROR,("external Error: %s",msg.c_str())); return LOCERR_OK; } // writeErrorMsg // - write debug message into session log TSyError writeDebugMsg( TStructFieldsKey *aStructFieldsKeyP, const TStructFieldInfo *aFldInfoP, cAppPointer aBuffer, memSize aValSize ) { TAgentParamsKey *mykeyP = static_cast(aStructFieldsKeyP); string msg; msg.assign((cAppCharP)aBuffer, aValSize); POBJDEBUGPRINTFX(mykeyP->fAgentP,DBG_HOT,("external Message: %s",msg.c_str())); return LOCERR_OK; } // writeDebugMsg // accessor table for session key static const TStructFieldInfo ServerParamFieldInfos[] = { // valName, valType, writable, fieldOffs, valSiz { "localSessionID", VALTYPE_TEXT, false, 0, 0, &readLocalSessionID, NULL }, { "initialLocalURI", VALTYPE_TEXT, false, 0, 0, &readInitialLocalURI, NULL }, { "abortStatus", VALTYPE_INT16, true, 0, 0, &readAbortStatus, &writeAbortStatus }, { "contenttype", VALTYPE_TEXT, true, 0, 0, &readContentType, &writeContentType }, { "connectURI", VALTYPE_TEXT, false, 0, 0, &readConnectURI, NULL }, { "connectHost", VALTYPE_TEXT, false, 0, 0, &readConnectHost, NULL }, { "connectDoc", VALTYPE_TEXT, false, 0, 0, &readConnectDoc, NULL }, { "timedout", VALTYPE_INT8, false, 0, 0, &readTimedOut, NULL }, { "lastused", VALTYPE_TIME64, false, 0, 0, &readLastUsed, NULL }, { "isserver", VALTYPE_INT8, false, 0, 0, &readIsServer, NULL }, #ifdef SYSYNC_SERVER { "sendrespuri", VALTYPE_INT8, true, 0, 0, &readSendRespURI, &writeSendRespURI }, #endif #ifdef SYSYNC_CLIENT { "sessionPassword", VALTYPE_TEXT, true, 0, 0, NULL, &writeSessionPassword }, #ifdef ENGINE_LIBRARY { "displayalert", VALTYPE_TEXT, false, 0, 0, &readDisplayAlert, NULL }, #endif #endif { "restartsync", VALTYPE_INT8, true, 0, 0, &readRestartSync, &writeRestartSync }, // write into debug log { "errorMsg", VALTYPE_TEXT, true, 0, 0, NULL, &writeErrorMsg }, { "debugMsg", VALTYPE_TEXT, true, 0, 0, NULL, &writeDebugMsg }, }; // get table describing the fields in the struct const TStructFieldInfo *TAgentParamsKey::getFieldsTable(void) { return ServerParamFieldInfos; } // TAgentParamsKey::getFieldsTable sInt32 TAgentParamsKey::numFields(void) { return sizeof(ServerParamFieldInfos)/sizeof(TStructFieldInfo); } // TAgentParamsKey::numFields // get actual struct base address uInt8P TAgentParamsKey::getStructAddr(void) { // prepared for accessing fields in server session object return (uInt8P)fAgentP; } // TAgentParamsKey::getStructAddr // open subkey by name (not by path!) TSyError TAgentParamsKey::OpenSubKeyByName( TSettingsKeyImpl *&aSettingsKeyP, cAppCharP aName, stringSize aNameSize, uInt16 aMode ) { #ifdef DBAPI_TUNNEL_SUPPORT if (strucmp(aName,"tunnel",aNameSize)==0) { // get tunnel datastore pointer TLocalEngineDS *ds = fAgentP->getTunnelDS(); if (!ds) return LOCERR_WRONGUSAGE; // opens current session's tunnel key aSettingsKeyP = ds->newTunnelKey(fEngineInterfaceP); } else #endif return inherited::OpenSubKeyByName(aSettingsKeyP,aName,aNameSize,aMode); // opened a key return LOCERR_OK; } // TAgentParamsKey::OpenSubKeyByName #endif // ENGINEINTERFACE_SUPPORT } // namespace sysync // eof libsynthesis-3.4.0.47.1/src/sysync/syncagent.h000077500000000000000000000543551226375725500211460ustar00rootroot00000000000000/* * File: SyncAgent.h * * Author: Lukas Zeller (luz@plan44.ch) * * TSyncAgent: Provides functionality to run client or server * sessions. * Unifies former TSyncClient and TSyncServer * * Copyright (c) 2002-2011 by Synthesis AG + plan44.ch * * 2009-09-30 : luz : created from syncclient.h and syncserver.h * */ #ifndef SYNC_AGENT_H #define SYNC_AGENT_H #include "engine_defs.h" //%%% we still need this at this time #define NON_FULLY_GRANULAR_ENGINE 1 #ifdef NON_FULLY_GRANULAR_ENGINE namespace sysync { // queued progress events typedef std::list TEngineProgressInfoList; } #endif #include "syncsession.h" #include "localengineds.h" #include "remotedatastore.h" #include "engineinterface.h" using namespace sysync; namespace sysync { #ifndef SYSYNC_SERVER // dummy session handle type for client-only case to allow unified constructor class TSyncSessionHandle { }; #endif // Support for SySync Diagnostic Tool #ifdef SYSYNC_TOOL int testLogin(int argc, const char *argv[]); int convertData(int argc, const char *argv[]); #endif /// @brief server engine state typedef enum { ses_needdata, ///< need SyncML request data, waiting for STEPCMD_GOTDATA ses_processing, ///< ready to perform next STEPCMD_STEP to process SyncML messages ses_generating, ///< ready to perform next STEPCMD_STEP to generate SyncML messages ses_dataready, ///< data is ready to be sent, waiting for STEPCMD_SENTDATA ses_almostdone, ///< session done, but termination delayed until next step ses_done, ///< session done numServerEngineStates } TServerEngineState; /// @brief client engine state typedef enum { ces_idle, ///< client engine is idle and can be initialized with STEPCMD_CLIENTSTART ces_generating, ///< ready to perform next STEPCMD_STEP to generate SyncML messages ces_dataready, ///< data is ready to be sent, waiting for STEPCMD_SENTDATA ces_resending, ///< data already sent, but app indicates with STEPCMD_RESENDDATA that it needed to resend the data ces_needdata, ///< need response data, waiting for STEPCMD_GOTDATA ces_processing, ///< ready to perform next STEPCMD_STEP to process SyncML messages ces_done, ///< session done numClientEngineStates } TClientEngineState; #ifdef PRECONFIGURED_SYNCREQUESTS // config for databases to sync with class TSyncReqConfig: public TConfigElement { typedef TConfigElement inherited; public: TSyncReqConfig(TLocalDSConfig *aLocalDSCfg, TConfigElement *aParentElement); virtual ~TSyncReqConfig(); // General sync db settings // - local client datastore involved TLocalDSConfig *fLocalDSConfig; // - local client datatstore path extension (such as "test" in "contact/test") string fLocalPathExtension; // - remote server DB layer auth string fDBUser; string fDBPassword; // - remote server datastore path string fServerDBPath; // - sync mode TSyncModes fSyncMode; // - slowsync bool fSlowSync; // - DS 1.2 filters string fRecordFilterQuery; bool fFilterInclusive; // public methods // - create appropriate localdatastore from config and init client request params TLocalEngineDS *initNewLocalDataStore(TSyncSession *aSessionP); protected: // check config elements #ifndef HARDCODED_CONFIG virtual bool localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine); #endif virtual void clear(); virtual void localResolve(bool aLastPass); }; // TSyncReqConfig // Sync DB config list typedef std::list TSyncReqList; #endif // forward class TSyncAgent; #ifdef SYSYNC_SERVER class TSyncSessionHandle; #endif #ifdef SYSYNC_CLIENT class TSyncClientBase; #endif // agent (client or server) config class TAgentConfig: public TSessionConfig { typedef TSessionConfig inherited; public: TAgentConfig(const char *aElementName, TConfigElement *aParentElementP); virtual ~TAgentConfig(); #ifdef SYSYNC_CLIENT // Local client config // - syncml version TSyncMLVersions fAssumedServerVersion; // we use this version for first connect attempt // - PUT devinf at every slow sync?? (smartner server needs this) bool fPutDevInfAtSlowSync; // - default auth params TAuthTypes fAssumedServerAuth; TFmtTypes fAssumedServerAuthEnc; // start with char encoding string fAssumedNonce; // start with no nonce bool fPreferSlowSync; // Ask server for slow sync instead of refresh-from-server: // both have the same effect, but have different pros and cons. // Defaults to true, the traditional behavior of libsynthesis. // Some old servers only support slow sync. Some new ones // work better with refresh, because they throttle clients // which do slow syncs excessively. // auth retry options (mainly for stupid servers like SCTS) bool fNewSessionForAuthRetry; // restart session for auth retries bool fNoRespURIForAuthRetry; // send retry to original URI for auth retries bool fSmartAuthRetry; // try to be smart and try different auth retry (different from fNewSessionForAuthRetry/fNoRespURIForAuthRetry) if first attempts fail #ifndef NO_LOCAL_DBLOGIN // - user/pw to access local DB string fLocalDBUser; string fLocalDBPassword; bool fNoLocalDBLogin; // if set, no local DB login is required, fLocalDBUser is used as userkey #endif // - server URI (used for PRECONFIGURED_SYNCREQUESTS, but also to predefine server URL in config for fixed-server apps) string fServerURI; #ifdef PRECONFIGURED_SYNCREQUESTS // Preconfigured sync request settings // - encoding SmlEncoding_t fEncoding; // - server layer user / pw string fServerUser; string fServerPassword; string fSocksHost; string fProxyHost; string fProxyUser; string fProxyPassword; // - transport layer user / pw string fTransportUser; string fTransportPassword; // - DB sync requests array TSyncReqList fSyncRequests; #endif #ifndef HARDCODED_CONFIG // - for debug only - used to fake a devID in the config file (useful when testing) string fFakeDeviceID; #endif #endif // SYSYNC_CLIENT #ifdef SYSYNC_SERVER // General server settings // - requested auth type (Auth requested in Chal sent to client) TAuthTypes fRequestedAuth; // - minimally required auth type (lowest auth type that is allowed) TAuthTypes fRequiredAuth; // - use automatic nonce generation for MD5 auth (empty nonce if false) bool fAutoNonce; // - constant nonce string to be used if autononce is off. If empty, no nonce is used string fConstantNonce; // - constant external URL, if set, it is used to generate RespURI (instead of Target LocURI sent by client) string fExternalURL; // - max size of GUID sent if client does not specify a MaxGUIDSize in devInf. 0=unlimited uInt16 fMaxGUIDSizeSent; // - respURI bool fUseRespURI; bool fRespURIOnlyWhenDifferent; #endif // SYSYNC_SERVER // check config elements #ifndef HARDCODED_CONFIG virtual bool localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine); #endif virtual void clear(); virtual void localResolve(bool aLastPass); #ifdef SYSYNC_SERVER // create appropriate session (=agent) for this server virtual TSyncAgent *CreateServerSession(TSyncSessionHandle *aSessionHandle, const char *aSessionID)=0; #endif #ifdef SYSYNC_CLIENT // create appropriate session (=agent) for this client virtual TSyncAgent *CreateClientSession(cAppCharP aSessionID) = 0; #endif }; // TAgentConfig // default profile ID #define DEFAULT_PROFILE_ID 0xFFFFFFFF #define TUNNEL_PROFILE_ID 0xFFFFFFFE class TSyncAgent: public TSyncSession { typedef TSyncSession inherited; public: TSyncAgent( TSyncAppBase *aAppBaseP, TSyncSessionHandle *aSessionHandleP, cAppCharP aSessionID // a session ID ); virtual ~TSyncAgent(); virtual void TerminateSession(void); // Terminate session, like destructor, but without actually destructing object itself virtual void ResetSession(void); // Resets session (but unlike TerminateSession, session might be re-used) void InternalResetSession(void); // static implementation for calling through virtual destructor and virtual ResetSession(); #ifdef ENGINEINTERFACE_SUPPORT #ifdef ENGINE_LIBRARY // Support for EngineModule common interface /// @brief Executes next step of the session /// @param aStepCmd[in/out] step command (STEPCMD_xxx): /// - tells caller to send or receive data or end the session etc. /// - instructs engine to abort or time out the session etc. /// @param aInfoP[in] pointer to a TEngineProgressInfo structure, NULL if no progress info needed /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure TSyError SessionStep(uInt16 &aStepCmd, TEngineProgressInfo *aInfoP); #ifdef PROGRESS_EVENTS // Handle (or dispatch) Session level progress event virtual bool HandleSessionProgressEvent(TEngineProgressInfo aProgressInfo); #endif // PROGRESS_EVENTS #endif // ENGINE_LIBRARY /// @brief Get new session key to access details of this session virtual appPointer newSessionKey(TEngineInterface *aEngineInterfaceP); #endif // ENGINEINTERFACE_SUPPORT // Server & Client common: // - message start and end virtual bool MessageStarted(SmlSyncHdrPtr_t aContentP, TStatusCommand &aStatusCommand, bool aBad=false); virtual void MessageEnded(bool aIncomingFinal); // - handle status received for SyncHdr, returns false if not handled virtual bool handleHeaderStatus(TStatusCommand *aStatusCmdP); // - start command group virtual bool processSyncStart( SmlSyncPtr_t aSyncP, // the Sync element TStatusCommand &aStatusCommand, // pre-set 200 status, can be modified in case of errors bool &aQueueForLater // will be set if command must be queued for later (re-)execution ); // - info about needed auth type virtual TAuthTypes requestedAuthType(void); virtual bool isAuthTypeAllowed(TAuthTypes aAuthType); // - called when incoming SyncHdr fails to execute virtual bool syncHdrFailure(bool aTryAgain); // device info (uses defaults in this base class, override to customize) virtual string getDeviceType(void); virtual string getDeviceID(void); #ifdef SYSYNC_CLIENT #ifdef ENGINE_LIBRARY // set profileID to client session before doing first SessionStep virtual void SetProfileSelector(uInt32 aProfileSelector) { fProfileSelectorInternal = aProfileSelector; /* default is just passing it on */ }; #endif // ENGINE_LIBRARY // session set-up // - initialize the client session, select the profile and link session with SML instance // for the correct encoding localstatus InitializeSession(uInt32 aProfileSelector, bool aAutoSyncSession=false); // - selects a profile (returns false if profile not found) // Note: This call must create and initialize all datastores that // are to be synced with that profile. virtual localstatus SelectProfile(uInt32 aProfileSelector, bool aAutoSyncSession=false); // - Prepares connection-related stuff. Will be called after all // session init is done, but before first request is sent virtual localstatus PrepareConnect(void) { return LOCERR_OK; }; // retry older protocol, returns false if no older protocol to try bool retryOlderProtocol(bool aSameVersionRetry=false, bool aOldMessageInBuffer=false); // prepares client session such that it will do a retry to start a session // (but keeping already received auth/nonce/syncML-Version state) void retryClientSessionStart(bool aOldMessageInBuffer); // - check if session is just starting (no response yet) bool isStarting(void) { return fIncomingMsgID==0; }; // Session and DB management // - perform login to local DB to allow accessing datastores later localstatus LocalLogin(void); // - let session process message in the SML instance buffer localstatus processAnswer(void); // - let session produce (or finish producing) next message into // SML instance buffer // returns aDone if no answer needs to be sent (=end of session) // returns <>0 SyncML error status on error (no SyncML answer could be generated) localstatus NextMessage(bool &aDone); // URI to send outgoing message to virtual cAppCharP getSendURI(void) { return fRespondURI.c_str(); }; // use respondURI // login cAppCharP getServerUser(void) { return fServerUser.c_str(); }; cAppCharP getServerPassword(void) { return fServerPassword.c_str(); }; void setServerPassword(cAppCharP aPassword, sInt32 aPwSize=-1) { if (aPwSize<0) fServerPassword = aPassword; else fServerPassword.assign(aPassword, aPwSize); }; // transport layer login cAppCharP getTransportUser(void) { return fTransportUser.c_str(); }; cAppCharP getTransportPassword(void) { return fTransportPassword.c_str(); }; // proxy/socks hosts cAppCharP getSocksHost(void) { return fSocksHost.c_str(); }; cAppCharP getProxyHost(void) { return fProxyHost.c_str(); }; cAppCharP getProxyUser(void) { return fProxyUser.c_str(); }; cAppCharP getProxyPassword(void) { return fProxyPassword.c_str(); }; // special behaviour virtual bool devidWithUserHash(void) { return false; }; // do not include user name to make a hash-based pseudo-device ID by default // session handling // - get client base TSyncClientBase *getClientBase(void); #endif // SYSYNC_CLIENT #ifdef SYSYNC_SERVER virtual SmlPcdataPtr_t newResponseURIForRemote(void); // response URI // Request processing // - end of request (to make sure even incomplete SyncML messages get cleaned up properly) bool EndRequest(bool &aHasData, string &aRespURI, uInt32 aReqBytes); // returns true if session must be deleted // - buffer answer in the session's buffer if transport allows it Ret_t bufferAnswer(MemPtr_t aAnswer, MemSize_t aAnswerSize); // - get buffered answer from the session's buffer if there is any void getBufferedAnswer(MemPtr_t &aAnswer, MemSize_t &aAnswerSize); // - get byte statistics virtual uInt32 getIncomingBytes(void) { return fIncomingBytes; }; virtual uInt32 getOutgoingBytes(void) { return fOutgoingBytes; }; // session handling // - get session Handle pointer TSyncSessionHandle *getSessionHandle(void) { return fSessionHandleP; } // returns remaining time for request processing [seconds] virtual sInt32 RemainingRequestTime(void); // info about server status virtual bool serverBusy(void); // return busy status (set by connection limit or app expiry) #endif // SYSYNC_SERVER #ifdef SYSYNC_CLIENT // variables protected: // - socks and proxy hosts if any string fSocksHost; string fProxyHost; string fProxyUser; string fProxyPassword; // - remote SyncML server layer login string fServerUser; // Server layer authentification user name string fServerPassword; // Server layer authentification password // - remote transport layer login string fTransportUser; string fTransportPassword; // - local DB login #ifndef NO_LOCAL_DBLOGIN bool fNoLocalDBLogin; string fLocalDBUser; string fLocalDBPassword; #endif // Authorisation // - get credentials/username to authenticate with remote party, NULL if none virtual SmlCredPtr_t newCredentialsForRemote(void); // get credentials to login to remote server virtual cAppCharP getUsernameForRemote(void) { return fServerUser.c_str(); }; // specified user name // internal processing events // - message start and end virtual bool ClientMessageStarted(SmlSyncHdrPtr_t aContentP, TStatusCommand &aStatusCommand, bool aBad=false); virtual void ClientMessageEnded(bool aIncomingFinal); // if set, SML processing errors will not be reported // (in case session wants to re-try something) bool fIgnoreMsgErrs; // incrementing client session number 0..255 uInt8 fClientSessionNo; #ifdef HARD_CODED_SERVER_URI uInt32 fServerURICRC; uInt8 fNoCRCPrefixLen; #endif #ifdef ENGINE_LIBRARY // Engine interface // - process step TSyError ClientSessionStep(uInt16 &aStepCmd, TEngineProgressInfo *aInfoP); // - Step that generates SyncML data TSyError ClientGeneratingStep(uInt16 &aStepCmd, TEngineProgressInfo *aInfoP); // - Step that processes SyncML data TSyError ClientProcessingStep(uInt16 &aStepCmd, TEngineProgressInfo *aInfoP); // - internal profile selector (can be ID or index) determined with // SetProfileSelector(), to be used with SelectProfile() uInt32 fProfileSelectorInternal; // - Client engine state TClientEngineState fClientEngineState; #endif // ENGINE_LIBRARY // - client side consecutive Alert 222, used to detect endless loop uInt32 fOutgoingAlert222Count; // Loop detecting time frame to avoid wrong detection of "keep-alive" message lineartime_t fLastOutgoingAlert222; // - called when essential status was received resets clien side Alert 222 loop detector // because receiving essential status means real session progress virtual void essentialStatusReceived(void) { fOutgoingAlert222Count = 0; }; public: // - can be cleared to suppress automatic use of DS 1.2 SINCE/BEFORE filters // (e.g. for date range in func_SetDaysRange()) bool fServerHasSINCEBEFORE; #endif // SYSYNC_CLIENT // flag controlled by app or datastore via "restartsync" session // variable: if true, the agent will try to restart the sync and // then clear the flag bool fRestartSyncOnce; #ifdef SYSYNC_SERVER public: // respuri bool fUseRespURI; protected: // access to config TAgentConfig *getServerConfig(void); // internal processing events // - message start and end virtual bool ServerMessageStarted(SmlSyncHdrPtr_t aContentP, TStatusCommand &aStatusCommand, bool aBad=false); virtual void ServerMessageEnded(bool aIncomingFinal); // - request end, called by EndRequest, virtual for descendants virtual void RequestEnded(bool &aHasData); // - map operation virtual bool processMapCommand( SmlMapPtr_t aMapCommandP, // the map command contents TStatusCommand &aStatusCommand, // pre-set 200 status, can be modified in case of errors bool &aQueueForLater ); // Session level auth // - get next nonce string top be sent to remote party for subsequent MD5 auth virtual void getNextNonce(const char *aDeviceID, string &aNextNonce); // - get nonce string, which is expected to be used by remote party for MD5 auth. virtual void getAuthNonce(const char *aDeviceID, string &aAuthNonce); // restarting a sync session is allowed in non-standard mode // TODO: introduce DevInf extensions and use that instead virtual bool allowAlertAfterMap() { return fCompleteFromClientOnly; } #ifdef ENGINE_LIBRARY // Engine interface // - process step TSyError ServerSessionStep(uInt16 &aStepCmd, TEngineProgressInfo *aInfoP); // - Step that generates SyncML data TSyError ServerGeneratingStep(uInt16 &aStepCmd, TEngineProgressInfo *aInfoP); // - Step that processes SyncML data TSyError ServerProcessingStep(uInt16 &aStepCmd, TEngineProgressInfo *aInfoP); // - Server engine state TServerEngineState fServerEngineState; // - request size MemSize_t fRequestSize; #endif // ENGINE_LIBRARY // set if map command received in this session bool fMapSeen; // standard nonce generation (without persistent device info) // %%% note: move this to session when we start supporting client auth checking string fLastNonce; // last nonce, will be returned at getAuthNonce() // busy status bool fServerIsBusy; // buffered answer MemPtr_t fBufferedAnswer; MemSize_t fBufferedAnswerSize; // data transfer statistics uInt32 fIncomingBytes; uInt32 fOutgoingBytes; // server session handle TSyncSessionHandle *fSessionHandleP; // the session "handle" (wrapper, containing server specific locking etc.) #endif // SYSYNC_SERVER #ifdef ENGINE_LIBRARY // Common for client & server #ifdef NON_FULLY_GRANULAR_ENGINE // progress event queue until engine is fully granular TEngineProgressInfoList fProgressInfoList; // pending step command and status during progress retrieval steps uInt16 fPendingStepCmd; localstatus fPendingStatus; public: string fAlertMessage; protected: #endif // NON_FULLY_GRANULAR_ENGINE // current session status localstatus fEngineSessionStatus; // suspend and abort requests bool fSuspendRequested; bool fAbortRequested; #endif // ENGINE_LIBRARY // instead of sending at the end of the last message, // the agent is going to ask the server for another sync session; // set in NextMessage() for restarting in ClientMessageEnded() bool fRestartingSync; // true if the SyncML client shall continue the session // by sending another package with , instead of closing // the session bool restartSync(); // true if all active stores are in "from client only" mode and // the engine is not in the fCompleteFromClientOnly mode // => map phase can be skipped bool checkAllFromClientOnly(); }; // TSyncAgent #ifdef ENGINEINTERFACE_SUPPORT // Support for EngineModule common interface // ========================================= #if defined(SYSYNC_SERVER) && !defined(ENGINE_LIBRARY) #warning "using ENGINEINTERFACE_SUPPORT in old-style appbase-rooted environment. Should be converted to real engine usage later" // Define dummy server engine class - no implementation of actual server engine routines, // defaults from TEngineInterface (returning error codes) will be used. class TDummyServerEngineInterface : public TEngineInterface { typedef TEngineInterface inherited; public: // constructor TDummyServerEngineInterface() {}; // appbase factory virtual TSyncAppBase *newSyncAppBase(void); }; // TDummyServerEngineInterface #endif // SYSYNC_SERVER and not ENGINE_LIBRARY // session runtime parameters class TAgentParamsKey : public TSessionKey { typedef TSessionKey inherited; public: TAgentParamsKey(TEngineInterface *aEngineInterfaceP, TSyncAgent *aAgentP); virtual ~TAgentParamsKey() {}; // open subkey by name (not by path!) virtual TSyError OpenSubKeyByName( TSettingsKeyImpl *&aSettingsKeyP, cAppCharP aName, stringSize aNameSize, uInt16 aMode ); protected: // get table describing the fields in the struct virtual const TStructFieldInfo *getFieldsTable(void); virtual sInt32 numFields(void); // get actual struct base address virtual uInt8P getStructAddr(void); public: // the associated server session TSyncAgent *fAgentP; }; // TAgentParamsKey #endif // ENGINEINTERFACE_SUPPORT } // namespace sysync #endif // SYNC_AGENT_H // eof libsynthesis-3.4.0.47.1/src/sysync/syncappbase.cpp000077500000000000000000003462471226375725500220220ustar00rootroot00000000000000/* * TSyncAppBase * Base class for SySync applications, is supposed to exist * as singular object only, manages "global" things such * as config reading and session dispatching * * Copyright (c) 2002-2011 by Synthesis AG + plan44.ch * * 2002-03-06 : luz : Created */ #include "prefix_file.h" #include "sysync.h" #include "syncappbase.h" #include "scriptcontext.h" #include "iso8601.h" #include "syncagent.h" #include "multifielditem.h" // in case we have no scripts... #ifdef SYSER_REGISTRATION #include "syserial.h" #endif #ifdef DIRECT_APPBASE_GLOBALACCESS #include "sysync_glob_vars.h" #endif #include "global_progress.h" // globally accessible progress event posting #ifndef ENGINE_LIBRARY // can be called globally to post progress events extern "C" int GlobalNotifyProgressEvent ( TProgressEventType aEventType, sInt32 aExtra1, sInt32 aExtra2, sInt32 aExtra3 ) { #ifdef PROGRESS_EVENTS TSyncAppBase *baseP = getExistingSyncAppBase(); if (baseP) { return baseP->NotifyAppProgressEvent(aEventType,NULL,aExtra1,aExtra2,aExtra3); } #endif return true; // not aborted } // GlobalNotifyProgressEvent #endif // not ENGINE_LIBRARY namespace sysync { #ifndef HARDCODED_CONFIG // SyncML encoding names for end user config const char * const SyncMLEncodingNames[numSyncMLEncodings] = { "undefined", "wbxml", "xml" }; #endif // SyncML encoding names for MIME type const char * const SyncMLEncodingMIMENames[numSyncMLEncodings] = { "undefined", SYNCML_ENCODING_WBXML, SYNCML_ENCODING_XML }; #if !defined(HARDCODED_CONFIG) || defined(ENGINEINTERFACE_SUPPORT) // platform string names for accessing them as config variables const char * const PlatformStringNames[numPlatformStrings] = { "platformvers", // version string of the current platform "globcfg_path", // global system-wide config path (such as C:\Windows or /etc) "loccfg_path", // local config path (such as exedir or user's dir) "defout_path", // default path to writable directory to write logs and other output by default "temp_path", // path where we can write temp files "exedir_path", // path to directory where executable resides "userdir_path", // path to the user's home directory for user-visible documents and files "appdata_path", // path to the user's preference directory for this application "prefs_path", // path to directory where all application prefs reside (not just mine) "device_uri", // URI of the device (as from getDeviceInfo) "device_name", // Name of the device (as from getDeviceInfo) "user_name", // Name of the currently logged in user }; #endif #ifdef ENGINEINTERFACE_SUPPORT #ifdef DIRECT_APPBASE_GLOBALACCESS // Only for old-style targets that still use a global anchor #ifdef ENGINE_LIBRARY #error "Engine Library may NOT access appBase via global anchor any more!" #endif // With enginemodulebase support, the global anchor is the enginebase module, // not syncappbase itself. #define GET_SYNCAPPBASE (((TEngineInterface *)sysync_glob_anchor())->getSyncAppBase()) // get access to existing Sync app base object, NULL if none (i.e. if no TEngineInterface) TSyncAppBase *getExistingSyncAppBase(void) { TEngineInterface *eng = (TEngineInterface *)sysync_glob_anchor(); return eng ? eng->getSyncAppBase() : NULL; } // getExistingSyncAppBase // global function, returns pointer to (singular) app base // object. With EngineInterface, this is ALWAYS a member of // TEngineInterface, so we create the global engineinterface if we don't have it // already. TSyncAppBase *getSyncAppBase(void) { TSyncAppBase *appBase = getExistingSyncAppBase(); if (appBase) return appBase; // no appBase yet, we must create and anchor the TEngineInterface #ifdef SYSYNC_CLIENT ENGINE_IF_CLASS *engine = sysync::newClientEngine(); #else ENGINE_IF_CLASS *engine = sysync::newServerEngine(); #endif // we must init the engine to trigger creation of the appbase! if (engine) engine->Init(); return GET_SYNCAPPBASE; } // getSyncAppBase TEngineInterface *getEngineInterface(void) { return (TEngineInterface *)sysync_glob_anchor(); } // getEngineInterface // free Sync Session Dispatcher void freeSyncAppBase(void) { TEngineInterface *eng = getEngineInterface(); if (eng) { // kills interface, and also kills syncappbase in the process delete eng; } } #endif // DIRECT_APPBASE_GLOBALACCESS #else // ENGINEINTERFACE_SUPPORT // Old style without enginemodulebase: the global anchor is syncappbase #define GET_SYNCAPPBASE ((TSyncAppBase *)sysync_glob_anchor()) // global function, returns pointer to (singular) app base // object. If not yet existing, a new app base is created TSyncAppBase *getSyncAppBase(void) { if (!sysync_glob_anchor()) { // no dispatcher exists, create new one // (using function which will create derived app // specific dispatcher) sysync_glob_setanchor(newSyncAppBase()); } // dispatcher now exists, use it return GET_SYNCAPPBASE; } // getSyncAppBase // get access to existing Sync app base object, NULL if none TSyncAppBase *getExistingSyncAppBase(void) { return GET_SYNCAPPBASE; } // getExistingSyncAppBase // free Sync Session Dispatcher void freeSyncAppBase(void) { if (sysync_glob_anchor()) { // object exists, kill it now delete GET_SYNCAPPBASE; sysync_glob_setanchor(NULL); } } #endif // not ENGINEINTERFACE_SUPPORT #ifdef SYDEBUG // static routines for accessing appbase logs from UI_Call_In/DB_Callback extern "C" void AppBaseLogDebugPuts(void *aCallbackRef, const char *aText) { if (aCallbackRef) { POBJDEBUGPUTSX(static_cast(aCallbackRef),DBG_DBAPI+DBG_PLUGIN,aText); } } // AppBaseLogDebugPuts extern "C" void AppBaseLogDebugExotic(void *aCallbackRef, const char *aText) { if (aCallbackRef) { POBJDEBUGPUTSX(static_cast(aCallbackRef),DBG_DBAPI+DBG_PLUGIN+DBG_EXOTIC,aText); } } // AppBaseLogDebugExotic extern "C" void AppBaseLogDebugBlock(void *aCallbackRef, const char *aTag, const char *aDesc, const char *aAttrText ) { if (aCallbackRef) { bool collapsed=false; if (aTag && aTag[0]=='-') { aTag++; collapsed=true; } static_cast(aCallbackRef)->getDbgLogger()->DebugOpenBlock(TDBG_LOCATION_NONE aTag,aDesc,collapsed,"%s",aAttrText); } } // AppBaseLogDebugBlock extern "C" void AppBaseLogDebugEndBlock(void *aCallbackRef, const char *aTag) { if (aCallbackRef) { if (aTag && aTag[0]=='-') aTag++; static_cast(aCallbackRef)->getDbgLogger()->DebugCloseBlock(TDBG_LOCATION_NONE aTag); } } // AppBaseLogDebugEndBlock extern "C" void AppBaseLogDebugEndThread(void *aCallbackRef) { if (aCallbackRef) { static_cast(aCallbackRef)->getDbgLogger()->DebugThreadOutputDone(true); // remove thread record for global threads } } // AppBaseLogDebugEndThread #endif // root config constructor TRootConfig::TRootConfig(TSyncAppBase *aSyncAppBaseP) : TRootConfigElement(aSyncAppBaseP), fCommConfigP(NULL), fAgentConfigP(NULL), fDatatypesConfigP(NULL) #ifdef SCRIPT_SUPPORT , fScriptConfigP(NULL) #endif #ifdef SYDEBUG , fDebugConfig("debug",this) // init static debug config member #endif { // config date is unknown so far fConfigDate=0; #ifndef HARDCODED_CONFIG // string for identifying config file in logs fConfigIDString=""; #endif } // TRootConfig::TRootConfig TRootConfig::~TRootConfig() { // clear linked if (fAgentConfigP) delete fAgentConfigP; if (fDatatypesConfigP) delete fDatatypesConfigP; if (fCommConfigP) delete fCommConfigP; #ifdef SCRIPT_SUPPORT if (fScriptConfigP) delete fScriptConfigP; #endif } // TRootConfig::~TRootConfig void TRootConfig::clear(void) { // root config variables // - init PUT suppression fNeverPutDevinf=false; // - init message size fLocalMaxMsgSize=DEFAULT_MAXMSGSIZE; fLocalMaxObjSize=DEFAULT_MAXOBJSIZE; // - system time zone fSystemTimeContext=TCTX_SYSTEM; // default to automatic detection #ifdef ENGINEINTERFACE_SUPPORT // - default identification fMan.clear(); fMod.clear(); #endif // - init device limit #ifdef CUSTOMIZABLE_DEVICES_LIMIT fConcurrentDeviceLimit=CONCURRENT_DEVICES_LIMIT; #endif // remove, (re-)create and clear linked config branches (debug last to allow dbg output while clearing) // - global scripting config #ifdef SCRIPT_SUPPORT if (fScriptConfigP) delete fScriptConfigP; fScriptConfigP= new TScriptConfig(this); if (fScriptConfigP) fScriptConfigP->clear(); #endif // - communication config if (fCommConfigP) delete fCommConfigP; installCommConfig(); if (fCommConfigP) fCommConfigP->clear(); // - datatypes registry config if (fDatatypesConfigP) delete fDatatypesConfigP; installDatatypesConfig(); if (fDatatypesConfigP) fDatatypesConfigP->clear(); // - agent config if (fAgentConfigP) delete fAgentConfigP; installAgentConfig(); if (fAgentConfigP) fAgentConfigP->clear(); // clear embedded debug config (as the last action) #ifdef SYDEBUG fDebugConfig.clear(); #endif // clear inherited inherited::clear(); } // TRootConfig::clear // save app state (such as settings in datastore configs etc.) void TRootConfig::saveAppState(void) { if (fAgentConfigP) fAgentConfigP->saveAppState(); if (fDatatypesConfigP) fDatatypesConfigP->saveAppState(); if (fCommConfigP) fCommConfigP->saveAppState(); } // TRootConfig::saveAppState // MUST be called after creating config to load (or pre-load) variable parts of config // such as binfile profiles. If aDoLoose==false, situations, where existing config // is detected but cannot be re-used will return an error. With aDoLoose==true, config // files etc. are created even if it means a loss of data. localstatus TRootConfig::loadVarConfig(bool aDoLoose) { // only agent may load variable config if (fAgentConfigP) return fAgentConfigP->loadVarConfig(aDoLoose); else return LOCERR_NOCFG; // no config yet } // TRootConfig::loadVarConfig #ifndef HARDCODED_CONFIG // root config element parsing bool TRootConfig::localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine) { // debug if (strucmp(aElementName,"debug")==0) { #ifdef SYDEBUG // let static TDebugConfig member handle it expectChildParsing(fDebugConfig); #else ReportError(false,"No debugging features available in this version"); expectAll(); // no debug code, simply ignore settings #endif } // config ID/date else if (strucmp(aElementName,"configdate")==0) expectTimestamp(fConfigDate); else if (strucmp(aElementName,"configidstring")==0) expectMacroString(fConfigIDString); else #ifdef ENGINEINTERFACE_SUPPORT // - product identification (in devInf) if (strucmp(aElementName,"manufacturer")==0) expectMacroString(fMan); else if (strucmp(aElementName,"model")==0) expectMacroString(fMod); else if (strucmp(aElementName,"HardwareVersion")==0) expectMacroString(fHwV); else if (strucmp(aElementName,"FirmwareVersion")==0) expectMacroString(fFwV); else if (strucmp(aElementName,"DeviceType")==0) expectMacroString(fDevTyp); else #endif // config variables if (strucmp(aElementName,"configvar")==0) { const char *nam = getAttr(aAttributes,"name"); if (!nam) return fail("Missing 'name' attribute in 'configvar'"); string val; if (!getAttrExpanded(aAttributes,"value",val,false)) return fail("Missing 'value' attribute in 'configvar'"); getSyncAppBase()->setConfigVar(nam,val.c_str()); expectEmpty(); } // options else if (strucmp(aElementName,"neverputdevinf")==0) expectBool(fNeverPutDevinf); else if (strucmp(aElementName,"maxmsgsize")==0) expectUInt32(fLocalMaxMsgSize); else if (strucmp(aElementName,"maxobjsize")==0) expectUInt32(fLocalMaxObjSize); else if (strucmp(aElementName,"maxconcurrentsessions")==0) { #ifdef CUSTOMIZABLE_DEVICES_LIMIT expectInt32(fConcurrentDeviceLimit); #else expectAll(); // no configurable limit, simply ignore contents #endif } // time zones else if (strucmp(aElementName,"definetimezone")==0) expectVTimezone(getSyncAppBase()->getAppZones()); // definition of custom time zone else if (strucmp(aElementName,"systemtimezone")==0) expectTimezone(fSystemTimeContext); // license else if (strucmp(aElementName,"licensename")==0) { #ifdef SYSER_REGISTRATION expectString(fLicenseName); #else expectAll(); // simply ignore contents for versions w/o registration #endif } else if (strucmp(aElementName,"licensecode")==0) { #ifdef SYSER_REGISTRATION expectString(fLicenseCode); #else expectAll(); // simply ignore contents for versions w/o registration #endif } #ifdef SCRIPT_SUPPORT else if (strucmp(aElementName,"scripting")==0) { // let linked TScriptConfig handle it expectChildParsing(*fScriptConfigP); } #endif else // Agent: Server or client if ( (IS_CLIENT && strucmp(aElementName,"client")==0) || (IS_SERVER && strucmp(aElementName,"server")==0) ) { // Agent config if (!fAgentConfigP) return false; return parseAgentConfig(aAttributes, aLine); } // Transport else if (strucmp(aElementName,"transport")==0) { // transport config if (!fCommConfigP) return false; if (!parseCommConfig(aAttributes, aLine)) { // not a transport we can understand, simply ignore expectAll(); } } else if (strucmp(aElementName,"datatypes")==0) { // datatypes (type registry) config if (!fDatatypesConfigP) return false; return parseDatatypesConfig(aAttributes, aLine); } else { // invalid element return false; } // ok return true; } // TRootConfig::localStartElement #endif // resolve (finish after all data is parsed) void TRootConfig::localResolve(bool aLastPass) { // make sure static debug element is resolved so // possible debug information created by resolving other // elements go to the correct locations/files // Note: in XML configs, the debug element is resolved immediately // after parsing (has fResolveImmediately set) and will // not be re-resolved here unless the element was not parsed at all. #if defined(SYDEBUG) && !defined(SYSYNC_TOOL) // - for SysyTool, do not resolve here as we don't want to see all of the // DBG blurb on the screen created by resolving the config fDebugConfig.Resolve(aLastPass); #endif // set zone for system if one was defined explicitly if (!TCTX_IS_SYSTEM(fSystemTimeContext) && !TCTX_IS_UNKNOWN(fSystemTimeContext)) { getSyncAppBase()->getAppZones()->predefinedSysTZ = fSystemTimeContext; getSyncAppBase()->getAppZones()->ResetCache(); // make sure next query for SYSTEM tz will get new set zone } // MaxMessagesize must have a reasonable size if (fLocalMaxMsgSize<512) { SYSYNC_THROW(TConfigParseException(" must be at least 512 bytes")); } // make sure we have the registration info vars updated #ifdef APP_CAN_EXPIRE getSyncAppBase()->updateAppExpiry(); #elif defined(SYSER_REGISTRATION) getSyncAppBase()->isRegistered(); #endif // make sure linked elements are resolved #ifdef SCRIPT_SUPPORT if (fScriptConfigP) fScriptConfigP->Resolve(aLastPass); #endif if (fAgentConfigP) fAgentConfigP->Resolve(aLastPass); if (fDatatypesConfigP) fDatatypesConfigP->Resolve(aLastPass); if (fCommConfigP) fCommConfigP->Resolve(aLastPass); // finally, get rid of macros (all scripts are now read) #ifdef SCRIPT_SUPPORT if (fScriptConfigP && aLastPass) fScriptConfigP->clearmacros(); #endif #if defined(SYDEBUG) && defined(SYSYNC_TOOL) // - for SysyTool, resolve now, where resolving dbg output has gone /dev/null already fDebugConfig.Resolve(aLastPass); #endif // try to resolve variable config here, but without forcing new one if (aLastPass) { loadVarConfig(false); } } // TRootConfig::localResolve // Base datatype config // init defaults void TDataTypeConfig::clear(void) { // clear properties fTypeName.erase(); // no type fTypeVersion.erase(); // no version #ifdef ZIPPED_BINDATA_SUPPORT fZippedBindata=false; fZipCompressionLevel=-1; // valid range is 0-9, invalid value will select Z_DEFAULT_COMPRESSION #endif fBinaryParts=false; // no binary parts fUseUTF16=false; // no UTF-16/Unicode translation fMSBFirst=false; // default to Intel byte order for UTF16 // clear inherited inherited::clear(); } // TMIMEDirTypeConfig::clear #ifdef CONFIGURABLE_TYPE_SUPPORT // config element parsing bool TDataTypeConfig::localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine) { // checking the elements if (strucmp(aElementName,"typestring")==0) expectString(fTypeName); else if (strucmp(aElementName,"versionstring")==0) expectString(fTypeVersion); else if (strucmp(aElementName,"binaryparts")==0) expectBool(fBinaryParts); #ifdef ZIPPED_BINDATA_SUPPORT else if (strucmp(aElementName,"zippedbindata")==0) expectBool(fZippedBindata); else if (strucmp(aElementName,"zipcompressionlevel")==0) expectInt16(fZipCompressionLevel); #endif else if (strucmp(aElementName,"unicodedata")==0) expectBool(fUseUTF16); else if (strucmp(aElementName,"bigendian")==0) expectBool(fMSBFirst); // - none known here else return false; // base class is TConfigElement // ok return true; } // TDataTypeConfig::localStartElement // resolve void TDataTypeConfig::localResolve(bool aLastPass) { // check if (aLastPass) { // Note: type strings might be set explicitly or implicitly by derived classes // Note2: all types must have a version (SCTS will fail without). For example // Starfish's text/plain notes have Version "1.0" if (fTypeName.empty() || fTypeVersion.empty() ) SYSYNC_THROW(TConfigParseException("datatype must have non-empty 'typestring' and 'versionstring'")); } } // TDataTypeConfig::localResolve #endif // Datatype registry TDatatypesConfig::TDatatypesConfig(const char* aName, TConfigElement *aParentElement) : TConfigElement(aName,aParentElement) { clear(); } // TDatatypesConfig::TDatatypesConfig TDatatypesConfig::~TDatatypesConfig() { clear(); } // TDatatypesConfig::~TDatatypesConfig // init defaults void TDatatypesConfig::clear(void) { // remove datatypes TDataTypesList::iterator pos; for(pos=fDataTypesList.begin();pos!=fDataTypesList.end();pos++) delete *pos; fDataTypesList.clear(); // clear inherited inherited::clear(); } // TDatatypesConfig::clear TDataTypeConfig *TDatatypesConfig::getDataType(const char *aName) { TDataTypesList::iterator pos; for(pos=fDataTypesList.begin();pos!=fDataTypesList.end();pos++) { if (strucmp((*pos)->getName(),aName)==0) { // found return *pos; } } return NULL; // not found } // TDatatypesConfig::getDataType #ifdef CONFIGURABLE_TYPE_SUPPORT // config element parsing bool TDatatypesConfig::localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine) { // checking the elements if (strucmp(aElementName,"datatype")==0) { // definition of a new data type // - get name const char *nam = getAttr(aAttributes,"name"); if (!nam) return fail("Missing 'name' attribute in 'datatype'"); // - get basetype const char *basetype = getAttr(aAttributes,"basetype"); if (!basetype) return fail("Missing 'basetype' attribute in 'datatype'"); // - call global function to get correct TDataTypeConfig derived object TDataTypeConfig *datatypeP = getSyncAppBase()->getRootConfig()->newDataTypeConfig(nam,basetype,this); if (!datatypeP) return fail("Unknown basetype '%s'",basetype); // - save in list fDataTypesList.push_back(datatypeP); // - let element handle parsing expectChildParsing(*datatypeP); } // - none known here else return inherited::localStartElement(aElementName,aAttributes,aLine); // ok return true; } // TDatatypesConfig::localStartElement #endif // resolve void TDatatypesConfig::localResolve(bool aLastPass) { // resolve all types in list TDataTypesList::iterator pos; for(pos=fDataTypesList.begin();pos!=fDataTypesList.end();pos++) (*pos)->Resolve(aLastPass); // resolve inherited inherited::localResolve(aLastPass); } // TDatatypesConfig::localResolve #ifdef SYDEBUG // debug config constructor TDebugConfig::TDebugConfig(const char *aElementName, TConfigElement *aParentElementP) : TConfigElement(aElementName,aParentElementP) { // do not call clear(), because this is virtual! } // TDebugConfig::TDebugConfig void TDebugConfig::clear(void) { // set defaults fGlobalDbgLoggerOptions.clear(); // set logger options to defaults fSessionDbgLoggerOptions.clear(); // set logger options to defaults fDebug = DEFAULT_DEBUG; // if <>0 (and #defined SYDEBUG), debug output is generated, value is used as mask fMsgDump = DEFAULT_MSGDUMP; // if set (and #defined MSGDUMP), messages sent and received are logged; fSingleGlobLog = false; // create a separate global log per app start fSingleSessionLog = false; // create separate session logs fTimedSessionLogNames = true; // add session start time into file name fLogSessionsToGlobal = false; // use separate file(s) for session log fXMLtranslate = DEFAULT_XMLTRANSLATE; // if set, communication will be translated to XML and logged fSimMsgRead = DEFAULT_SIMMSGREAD; // if set (and #defined SIMMSGREAD), simulated input with "i_" prefixed incoming messages are supported fGlobalDebugLogs = DEFAULT_GLOBALDEBUGLOGS; fSessionDebugLogs = DEFAULT_SESSIONDEBUGLOGS; if (getPlatformString(pfs_defout_path,fDebugInfoPath)) makeOSDirPath(fDebugInfoPath); else fDebugInfoPath.erase(); // none // make sure that defaults are applied a first time NOW, BEFORE reading first config localResolve(true); #ifndef SYSYNC_TOOL // and make sure final resolve takes place early when element finishes parsing // (but not for SYSYNC_TOOL, where we want no debug output at all during config read & resolve!) fResolveImmediately = true; #endif // clear inherited inherited::clear(); } // TDebugConfig::clear // resolve (finish after all data is parsed) void TDebugConfig::localResolve(bool aLastPass) { if (aLastPass) { #ifdef SYDEBUG // we have debug #ifndef HARDCODED_CONFIG // XML config - user options settings are parsed into fSessionDbgLoggerOptions // - by default, global logging has same options as configured for session... fGlobalDbgLoggerOptions = fSessionDbgLoggerOptions; if (fLogSessionsToGlobal) { // ... and these settings are used as they are, if session and global // logging are identical... } else { // ...but when they are different, we have a few hard-coded things for global logging: #ifdef MULTITHREAD_PIPESERVER // - for pipe server, global logs should be per-thread fGlobalDbgLoggerOptions.fFlushMode=dbgflush_flush; // flush every log line fGlobalDbgLoggerOptions.fSubThreadMode=dbgsubthread_separate; // separate per thread fGlobalDbgLoggerOptions.fTimestampForAll=true; // timestamp for every message #else if (IS_SERVER) { // - global log for ISAPI/XPT *Servers* is always in openclose mode (possibly multiple processes accessing it) fGlobalDbgLoggerOptions.fFlushMode=dbgflush_openclose; // open and close for every log line } fGlobalDbgLoggerOptions.fSubThreadMode=dbgsubthread_linemix; // mix in one file #ifdef MULTI_THREAD_SUPPORT fGlobalDbgLoggerOptions.fThreadIDForAll=true; // thread ID for each message #endif #endif } #endif // initialize global debug logging options getSyncAppBase()->fAppLogger.setMask(fDebug); // set initial debug mask from config getSyncAppBase()->fAppLogger.setEnabled(fGlobalDebugLogs); // init from config getSyncAppBase()->fAppLogger.setOptions(&fGlobalDbgLoggerOptions); // install outputter, but only if not yet installed in an earlier invocation. We only want ONE log per engine instantiation! if (!getSyncAppBase()->fAppLogger.outputEstablished()) { getSyncAppBase()->fAppLogger.installOutput(getSyncAppBase()->newDbgOutputter(true)); // install the output object (and pass ownership!) getSyncAppBase()->fAppLogger.setDebugPath(fDebugInfoPath.c_str()); // global log all in one file getSyncAppBase()->fAppLogger.appendToDebugPath(fGlobalDbgLoggerOptions.fBasename.empty() ? TARGETID : fGlobalDbgLoggerOptions.fBasename.c_str()); if (fSingleGlobLog) { // One single log - in this case, we MUST append to current log fGlobalDbgLoggerOptions.fAppend=true; } else { // create a new global log for each app start getSyncAppBase()->fAppLogger.appendToDebugPath("_"); string t; TimestampToISO8601Str(t, getSyncAppBase()->getSystemNowAs(TCTX_UTC), TCTX_UTC, false, false); getSyncAppBase()->fAppLogger.appendToDebugPath(t.c_str()); getSyncAppBase()->fAppLogger.appendToDebugPath("_global"); } } // define this as the main thread getSyncAppBase()->fAppLogger.DebugDefineMainThread(); #endif } }; // TDebugConfig::localResolve #ifndef HARDCODED_CONFIG // debug option (combination) names const char * const debugOptionNames[numDebugOptions] = { // current categories "hot", "error", "data", "admin", "syncml", "remoteinfo", "parse", "generate", "rtk_sml", "rtk_xpt", "session", "lock", "objinst", "transp", "scripts", "profiling", "rest", // flags mostly (not always) used in combination with some of the basic categories "userdata", "dbapi", "plugin", "filter", "match", "conflict", "details", "exotic", "expressions", // useful sets "all", "minimal", "normal", "extended", "maximal", "db", "syncml_rtk", // old ones "items", "cmd", "devinf", "dataconf" }; const uInt32 debugOptionMasks[numDebugOptions] = { // current categories DBG_HOT, DBG_ERROR, DBG_DATA, DBG_ADMIN, DBG_PROTO, DBG_REMOTEINFO, DBG_PARSE, DBG_GEN, DBG_RTK_SML, DBG_RTK_XPT, DBG_SESSION, DBG_LOCK, DBG_OBJINST, DBG_TRANSP, DBG_SCRIPTS, DBG_PROFILE, DBG_REST, // flags mostly (not always) used in combination with some of the basic categories DBG_USERDATA, DBG_DBAPI, DBG_PLUGIN, DBG_FILTER, DBG_MATCH, DBG_CONFLICT, DBG_DETAILS, DBG_EXOTIC, DBG_SCRIPTEXPR, // useful sets DBG_ALL, DBG_MINIMAL, DBG_NORMAL, DBG_EXTENDED, DBG_MAXIMAL, DBG_ALLDB, DBG_RTK_SML+DBG_RTK_XPT, // old names that are mapped to new masks DBG_DATA, // formerly: DBG_ITEMS DBG_PROTO, // formerly: DBG_CMD DBG_REMOTEINFO, // formerly: DBG_DEVINF DBG_PARSE+DBG_GEN // formerly: DBG_DATACONV }; uInt32 TDebugConfig::str2DebugMask(const char **aAttributes) { expectEmpty(); // enable may not have content // process arguments const char* dbgopt = getAttr(aAttributes,"option"); if (!dbgopt) { ReportError(false,"debug enable/disable, missing 'option' attribute"); } sInt16 k; if (StrToEnum(debugOptionNames,numDebugOptions,k,dbgopt)) { return debugOptionMasks[k]; } ReportError(false,"unknown debug option '%s'",dbgopt); return 0; } // TDebugConfig::str2DebugMask // debug config element parsing bool TDebugConfig::localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine) { // checking the elements if (strucmp(aElementName,"mask")==0) expectUInt32(fDebug); else if (strucmp(aElementName,"enable")==0) fDebug = fDebug | str2DebugMask(aAttributes); else if (strucmp(aElementName,"disable")==0) fDebug = fDebug & ~str2DebugMask(aAttributes); else if (strucmp(aElementName,"logpath")==0) expectPath(fDebugInfoPath); else if (strucmp(aElementName,"msgdump")==0) expectBool(fMsgDump); else if (strucmp(aElementName,"xmltranslate")==0) expectBool(fXMLtranslate); else if (strucmp(aElementName,"simmsgread")==0) expectBool(fSimMsgRead); else if (strucmp(aElementName,"sessionlogs")==0) expectBool(fSessionDebugLogs); else if (strucmp(aElementName,"globallogs")==0) expectBool(fGlobalDebugLogs); // options for TDebugLogger else if (strucmp(aElementName,"logformat")==0) expectEnum(sizeof(fSessionDbgLoggerOptions.fOutputFormat),&fSessionDbgLoggerOptions.fOutputFormat,DbgOutFormatNames,numDbgOutFormats); else if (strucmp(aElementName,"folding")==0) expectEnum(sizeof(fSessionDbgLoggerOptions.fFoldingMode),&fSessionDbgLoggerOptions.fFoldingMode,DbgFoldingModeNames,numDbgFoldingModes); // source link settings always available, even if feature is not: // allows adding the setting to configs unconditionally, without // triggering config parser errors else if (strucmp(aElementName,"sourcelink")==0) expectEnum(sizeof(fSessionDbgLoggerOptions.fSourceLinkMode),&fSessionDbgLoggerOptions.fSourceLinkMode,DbgSourceModeNames,numDbgSourceModes); else if (strucmp(aElementName,"sourcebase")==0) expectPath(fSessionDbgLoggerOptions.fSourceRootPath); else if (strucmp(aElementName,"indentstring")==0) expectCString(fSessionDbgLoggerOptions.fIndentString); else if (strucmp(aElementName,"fileprefix")==0) expectRawString(fSessionDbgLoggerOptions.fCustomPrefix); else if (strucmp(aElementName,"filesuffix")==0) expectRawString(fSessionDbgLoggerOptions.fCustomSuffix); else if (strucmp(aElementName,"filename")==0) expectRawString(fSessionDbgLoggerOptions.fBasename); else if (strucmp(aElementName,"logflushmode")==0) expectEnum(sizeof(fSessionDbgLoggerOptions.fFlushMode),&fSessionDbgLoggerOptions.fFlushMode,DbgFlushModeNames,numDbgFlushModes); else if (strucmp(aElementName,"appendtoexisting")==0) expectBool(fSessionDbgLoggerOptions.fAppend); else if (strucmp(aElementName,"timestamp")==0) expectBool(fSessionDbgLoggerOptions.fTimestampStructure); else if (strucmp(aElementName,"timestampall")==0) expectBool(fSessionDbgLoggerOptions.fTimestampForAll); else if (strucmp(aElementName,"showthreadid")==0) expectBool(fSessionDbgLoggerOptions.fThreadIDForAll); else if (strucmp(aElementName,"subthreadmode")==0) expectEnum(sizeof(fSessionDbgLoggerOptions.fSubThreadMode),&fSessionDbgLoggerOptions.fSubThreadMode,DbgSubthreadModeNames,numDbgSubthreadModes); else if (strucmp(aElementName,"subthreadbuffersize")==0) expectUInt32(fSessionDbgLoggerOptions.fSubThreadBufferMax); else if (strucmp(aElementName,"singlegloballog")==0) expectBool(fSingleGlobLog); else if (strucmp(aElementName,"singlesessionlog")==0) expectBool(fSingleSessionLog); else if (strucmp(aElementName,"timedsessionlognames")==0) expectBool(fTimedSessionLogNames); else if (strucmp(aElementName,"logsessionstoglobal")==0) expectBool(fLogSessionsToGlobal); else return false; // invalid element return true; } // TDebugConfig::localStartElement #endif #endif #ifndef ENGINE_LIBRARY // in engine library, all output must be in context of an engineInterface/appBase // Debug output routines // // If a fDebugLogOutputFunc callback is defined, // it will be used for output, otherwise global gDebugLogPath // file will be written uInt32 getDbgMask(void) { #ifdef SYDEBUG TSyncAppBase *appBase = getExistingSyncAppBase(); if (!appBase) return 0; // no appbase -> no debug return appBase->getDbgMask(); #else return 0; #endif } // getDebugMask TDebugLogger *getDbgLogger(void) { #ifdef SYDEBUG TSyncAppBase *appBase = getExistingSyncAppBase(); if (!appBase) return NULL; // no appbase -> no debuglogger return appBase->getDbgLogger(); #else return NULL; #endif } // getDbgLogger // non-class DebugPuts void DebugPuts(uInt32 mask, const char *text) { #ifdef SYDEBUG // use global debug channel of appBase for non-object-context output TSyncAppBase *appBase = getExistingSyncAppBase(); if (!appBase || appBase->getDbgMask()==0) return; // no appbase or debug off -> no output TDebugLogger *dbgLogger = appBase->getDbgLogger(); if (!dbgLogger) return; dbgLogger->DebugPuts(mask,text,0,false); #endif } // DebugPuts // non-class print to debug channel void DebugVPrintf(uInt32 mask, const char *format, va_list args) { #ifdef SYDEBUG // use global debug channel of appBase for non-object-context output TSyncAppBase *appBase = getExistingSyncAppBase(); if (!appBase || appBase->getDbgMask()==0) return; // no appbase or debug off -> no output TDebugLogger *dbgLogger = appBase->getDbgLogger(); if (!dbgLogger) return; dbgLogger->DebugVPrintf(mask,format,args); #endif } // DebugVPrintf // non-class print to debug channel void DebugPrintf(const char *text, ...) { #ifdef SYDEBUG va_list args; if (PDEBUGMASK) { va_start(args, text); DebugVPrintf(DBG_TRANSP, text,args); va_end(args); } // if (PDEBUGMASK) #endif } // DebugPrintf void smlLibPrint(const char *text, ...) { #ifdef SYDEBUG va_list args; va_start(args, text); DebugVPrintf(DBG_RTK_SML,text,args); va_end(args); #endif } // smlLibPrint void smlLibVprintf(const char *format, va_list va) { #ifdef SYDEBUG DebugVPrintf(DBG_RTK_SML,format,va); #endif } // smlLibVprintf // entry point for SyncML-Toolkit with // #define TRACE_TO_STDOUT void localOutput(const char *aFormat, va_list aArgs) { #ifdef SYDEBUG NCDEBUGVPRINTFX(DBG_RTK_SML,aFormat,aArgs); #endif } #endif // not ENGINE_LIBRARY // Console printout. Only enabled when defined(CONSOLEINFO) // non-class print to console void ConsolePrintf(const char *text, ...) { #ifdef CONSOLEINFO const sInt16 maxmsglen=1024; char msg[maxmsglen]; va_list args; msg[0]='\0'; va_start(args, text); // assemble the message string vsnprintf(msg, maxmsglen, text, args); va_end(args); // write the string ConsolePuts(msg); #endif } // sysyncConsolePrintf // non-class Console output void ConsolePuts(const char *text) { #ifdef CONSOLEINFO // show on app's console equivalent AppConsolePuts(text); #endif // console enabled } // sysyncConsolePuts // TSyncAppBase // ============ /* SyncML toolkit callback function declarations */ extern "C" { /* message callbacks */ static Ret_t smlStartMessageCallback(InstanceID_t id, VoidPtr_t userData, SmlSyncHdrPtr_t pContent); static Ret_t smlEndMessageCallback(InstanceID_t id, VoidPtr_t userData, Boolean_t final); /* grouping commands */ static Ret_t smlStartSyncCallback(InstanceID_t id, VoidPtr_t userData, SmlSyncPtr_t pContent); static Ret_t smlEndSyncCallback(InstanceID_t id, VoidPtr_t userData); #ifdef ATOMIC_RECEIVE /* these callbacks are NOT included in the Toolkit lite version */ static Ret_t smlStartAtomicCallback(InstanceID_t id, VoidPtr_t userData, SmlAtomicPtr_t pContent); static Ret_t smlEndAtomicCallback(InstanceID_t id, VoidPtr_t userData); #endif #ifdef SEQUENCE_RECEIVE static Ret_t smlStartSequenceCallback(InstanceID_t id, VoidPtr_t userData, SmlSequencePtr_t pContent); static Ret_t smlEndSequenceCallback(InstanceID_t id, VoidPtr_t userData); #endif /* Sync Commands */ static Ret_t smlAddCmdCallback(InstanceID_t id, VoidPtr_t userData, SmlAddPtr_t pContent); static Ret_t smlAlertCmdCallback(InstanceID_t id, VoidPtr_t userData, SmlAlertPtr_t pContent); static Ret_t smlDeleteCmdCallback(InstanceID_t id, VoidPtr_t userData, SmlDeletePtr_t pContent); static Ret_t smlGetCmdCallback(InstanceID_t id, VoidPtr_t userData, SmlGetPtr_t pContent); static Ret_t smlPutCmdCallback(InstanceID_t id, VoidPtr_t userData, SmlPutPtr_t pContent); #ifdef MAP_RECEIVE static Ret_t smlMapCmdCallback(InstanceID_t id, VoidPtr_t userData, SmlMapPtr_t pContent); #endif #ifdef RESULT_RECEIVE static Ret_t smlResultsCmdCallback(InstanceID_t id, VoidPtr_t userData, SmlResultsPtr_t pContent); #endif static Ret_t smlStatusCmdCallback(InstanceID_t id, VoidPtr_t userData, SmlStatusPtr_t pContent); static Ret_t smlReplaceCmdCallback(InstanceID_t id, VoidPtr_t userData, SmlReplacePtr_t pContent); /* othe commands */ #ifdef COPY_RECEIVE /* these callbacks are NOT included in the Toolkit lite version */ static Ret_t smlCopyCmdCallback(InstanceID_t id, VoidPtr_t userData, SmlCopyPtr_t param); #endif static Ret_t smlMoveCmdCallback(InstanceID_t id, VoidPtr_t userData, SmlMovePtr_t param); #ifdef EXEC_RECEIVE static Ret_t smlExecCmdCallback(InstanceID_t id, VoidPtr_t userData, SmlExecPtr_t pContent); #endif #ifdef SEARCH_RECEIVE static Ret_t smlSearchCmdCallback(InstanceID_t id, VoidPtr_t userData, SmlSearchPtr_t pContent); #endif /* Other Callbacks */ static Ret_t smlHandleErrorCallback(InstanceID_t id, VoidPtr_t userData); static Ret_t smlTransmitChunkCallback(InstanceID_t id, VoidPtr_t userData); /* print callback */ void smlPrintCallback(String_t outputString); } // extern "C" declaration // constructor TSyncAppBase::TSyncAppBase() : fIsServer(false), fDeleting(false), fConfigP(NULL), fRequestCount(0), #if defined(PROGRESS_EVENTS) && !defined(ENGINE_LIBRARY) fProgressEventFunc(NULL), #endif #ifdef ENGINEINTERFACE_SUPPORT fEngineInterfaceP(NULL), #else fMasterPointer(NULL), #endif fApiInterModuleContext(0) // reset all callbacks #ifdef SYDEBUG // app logger ,fAppLogger(&fAppZones) #endif { // at the moment of creation, this is now the SyncAppBase // (set it here already to allow getSyncAppBase() from derived constructors) #ifdef ENGINEINTERFACE_SUPPORT #ifdef DIRECT_APPBASE_GLOBALACCESS getEngineInterface()->setSyncAppBase(this); // set the link so getSyncAppBase() via EngineInterface works immediately #endif #else #ifdef ENGINE_LIBRARY #error "DIRECT_APPBASE_GLOBALACCESS is not allowed with ENGINE_LIBRARY" #endif sysync_glob_setanchor(this); #endif #ifdef MD5_TEST_FUNCS md5::dotest(); #endif // init profiling TP_INIT(fTPInfo); TP_START(fTPInfo,TP_general); #ifdef EXPIRES_AFTER_DATE // - get current time sInt16 y,m,d; lineartime2date(getSystemNowAs(TCTX_UTC),&y,&m,&d); // - calculate scrambled version thereof fScrambledNow = ((sInt32)y-1720l)*12l*42l+ ((sInt32)m-1)*42l+ ((sInt32)d+7l); /* #define SCRAMBLED_EXPIRY_VALUE \ (EXPIRY_DAY+7)+ \ (EXPIRY_MONTH-1)*42+ \ (EXPIRY_YEAR-1720)*12*42 */ #endif #ifdef APP_CAN_EXPIRE fAppExpiryStatus = LOCERR_OK; // do not compare here, would be too easy #endif #if defined(SYDEBUG) && defined(HARDCODED_CONFIG) fConfigFilePath = ""; #endif #ifdef SYSER_REGISTRATION // make sure that license is standard (no phone home, no expiry) in case there is NO license at all fRegLicenseType = 0; fRelDuration = 0; fRegDuration = 0; #if defined(EXPIRES_AFTER_DAYS) && defined(ENGINE_LIBRARY) fFirstUseDate = 0; fFirstUseVers = 0; #endif #endif // TODO: put this somewhere where the return code can be checked and reported to the user of TSyncAppBase fAppZones.initialize(); } // TSyncAppBase::TSyncAppBase // destructor TSyncAppBase::~TSyncAppBase() { fDeleting=true; // flag deletion to block calling critical (virtual) methods #if !defined(ENGINEINTERFACE_SUPPORT) || defined(DIRECT_APPBASE_GLOBALACCESS) sysync_glob_setanchor(NULL); #endif // stop and show profiling info TP_STOP(fTPInfo); #ifdef TIME_PROFILING if (PDEBUGMASK & DBG_PROFILE) { sInt16 i; PDEBUGPRINTFX(DBG_PROFILE,("Non-Session CPU usage statistics: (system/user)")); // sections for (i=0; iReportError(true,"Recursive config variable $(%s) in <%s>",vn.c_str(),aElementName); n=n2+1; // do not expand continue; } } // found value - substitute n-=2; // substitute beginning with leadin n2+=1; // include closing paranthesis aString.replace(n,n2-n,vv); if (aCfgVarExp<2) { // do not allow recursive macro expansion n+=vv.size(); // continue searching past substituted chars } } else { // not found - leave macro as-is if (aCfgElement) aCfgElement->ReportError(false,"Undefined config variable $(%s) in <%s>",vn.c_str(),aElementName); n=n2+1; // continue search after closing paranthesis } } else { if (aCfgElement) aCfgElement->ReportError(false,"Unterminated $(xxx)-style config variable in <%s>",aElementName); } } return true; } // TSyncAppBase::expandConfigVars #endif // not HARDCODED_CONFIG localstatus TSyncAppBase::finishConfig() { #ifdef SYDEBUG fAppZones.getDbgLogger = getDbgLogger(); #endif fAppZones.loggingStarted(); return LOCERR_OK; } #ifdef HARDCODED_CONFIG localstatus TSyncAppBase::initHardcodedConfig(void) { localstatus err; // initialize for receiving new config fConfigP->clear(); // now call initializer in derived root config err=fConfigP->createHardcodedConfig(); if (err!=LOCERR_OK) return err; // make sure it gets all resolved fConfigP->ResolveAll(); // is ok now return finishConfig(); } // TSyncAppBase::initHardcodedConfig #else // report config errors void TSyncAppBase::ConferrPrintf(const char *text, ...) { const sInt16 maxmsglen=1024; char msg[maxmsglen]; va_list args; msg[0]='\0'; va_start(args, text); // assemble the message string vsnprintf(msg, maxmsglen, text, args); va_end(args); // output config errors ConferrPuts(msg); } // TSyncAppBase::ConferrPrintf // report config errors to appropriate channel void TSyncAppBase::ConferrPuts(const char *msg) { #ifdef ENGINE_LIBRARY // engine variant string filename; // - get config var to see where we should put config errors if (!getConfigVar("conferrpath", filename)) return; // no output defined for config errors // a config error path is defined if (strucmp(filename.c_str(),"console")==0) { // put message directly to what is supposed to be the console #ifdef ANDROID __android_log_write( ANDROID_LOG_DEBUG, "ConferrPuts", msg ); #else AppConsolePuts(msg); #endif return; // done } #else // ENGINE_LIBRARY // old variant - output to predefined path #ifdef CONSOLEINFO ConsolePuts(msg); return; #elif defined(__PALM_OS__) return; // PalmOS has no file output #endif // prepare file name string filename; if (!getPlatformString(pfs_defout_path,filename)) return; makeOSDirPath(filename); filename+=CONFERRPREFIX; filename+=TARGETID; filename+=CONFERRSUFFIX; #endif // not ENGINE_LIBRARY #ifndef __PALM_OS__ // now write to file FILE * logfile=fopen(filename.c_str(),"a"); if (logfile) { string ts; StringObjTimestamp(ts,getSystemNowAs(TCTX_SYSTEM)); ts.append(": "); fputs(ts.c_str(),logfile); fputs(msg,logfile); fputs("\n",logfile); fclose(logfile); } #endif // __PALM_OS__ } // TSyncAppBase::ConferrPuts /* config reading */ // XML parser's "userdata" typedef struct { XML_Parser parser; TRootConfigElement *rootconfig; } TXMLUserData; // prototypes extern "C" { static void startElement(void *userData, const char *name, const char **atts); static void charData(void *userData, const XML_Char *s, int len); static void endElement(void *userData, const char *name); } static localstatus checkErrors(TRootConfigElement *aRootConfigP,XML_Parser aParser) { const char *errmsg = aRootConfigP->getErrorMsg(); if (errmsg) { aRootConfigP->getSyncAppBase()->ConferrPrintf( "%s at line %ld col %ld", errmsg, (sInt32)XML_GetCurrentLineNumber(aParser), (sInt32)XML_GetCurrentColumnNumber(aParser) ); aRootConfigP->resetError(); return aRootConfigP->getFatalError(); // return when fatal } else return LOCERR_OK; // no (fatal) error } // checkErrors // callback for expat static void startElement(void *userData, const char *name, const char **atts) { TRootConfigElement *cfgP = static_cast(userData)->rootconfig; XML_Parser parser = static_cast(userData)->parser; SYSYNC_TRY { cfgP->startElement(name,atts,XML_GetCurrentLineNumber(parser)); } SYSYNC_CATCH (exception &e) cfgP->ReportError(true,"Exception in StartElement: %s",e.what()); SYSYNC_ENDCATCH // check for errors checkErrors(cfgP,parser); } // startElement // callback for expat static void charData(void *userData, const XML_Char *s, int len) { TRootConfigElement *cfgP = static_cast(userData)->rootconfig; XML_Parser parser = static_cast(userData)->parser; SYSYNC_TRY { cfgP->charData(s,len); } SYSYNC_CATCH (exception &e) cfgP->ReportError(true,"Exception in charData: %s",e.what()); SYSYNC_ENDCATCH // check for errors checkErrors(cfgP,parser); } // charData // callback for expat static void endElement(void *userData, const char *name) { TRootConfigElement *cfgP = static_cast(userData)->rootconfig; XML_Parser parser = static_cast(userData)->parser; SYSYNC_TRY { cfgP->endElement(name); } SYSYNC_CATCH (exception &e) cfgP->ReportError(true,"Exception in endElement: %s",e.what()); SYSYNC_ENDCATCH // check for errors checkErrors(cfgP,parser); } // endElement // config stream reading localstatus TSyncAppBase::readXMLConfigStream(TXMLConfigReadFunc aReaderFunc, void *aContext) { localstatus fatalerr; // clear (reset to default) all config TP_DEFIDX(last); TP_SWITCH(last,fTPInfo,TP_configread); MP_SHOWCURRENT(DBG_HOT,"start reading config"); // initialize for new config fConfigP->clear(); fConfigP->ResetParsing(); // read XML appChar buf[CONFIG_READ_BUFSIZ]; sInt16 done; // - create parser XML_Parser parser = XML_ParserCreate(NULL); SYSYNC_TRY { // init user data struct TXMLUserData userdata; userdata.parser=parser; userdata.rootconfig=fConfigP; // pass pointer to root config here XML_SetUserData(parser, &userdata); XML_SetElementHandler(parser, startElement, endElement); XML_SetCharacterDataHandler(parser, charData); do { bufferIndex len=0; // callback reader func if (!(aReaderFunc)(buf,CONFIG_READ_BUFSIZ,&len,aContext)) { fConfigP->setFatalError(LOCERR_CFGREAD); // this is also fatal ConferrPrintf( "Error reading from config" ); break; } // %%% changed stop criterium to smooth EngineInterface API //done = len < CONFIG_READ_BUFSIZ; done = len == 0; if (!XML_Parse(parser, buf, len, done)) { fConfigP->setFatalError(LOCERR_CFGPARSE); // this is also fatal ConferrPrintf( "%s at line %ld col %ld", XML_ErrorString(XML_GetErrorCode(parser)), (sInt32)XML_GetCurrentLineNumber(parser), (sInt32)XML_GetCurrentColumnNumber(parser) ); break; } else if (fConfigP->getFatalError()) break; } while (!done); XML_ParserFree(parser); if (!fConfigP->getFatalError()) { // now resolve fConfigP->ResolveAll(); // display resolve error, if any const char *msg = fConfigP->getErrorMsg(); if (msg) { // this is fatal only if error was thrown in Resolve. // Some warnings might be set with ReportError and // will not cause abort. ConferrPrintf(msg); } } // check if ok or not if ((fatalerr=fConfigP->getFatalError())!=LOCERR_OK) { // config failed, reset // %%% do not clear the config here //fConfigP->clear(); ConferrPrintf( "Fatal error %hd, no valid configuration could be read from XML file", (sInt16)fatalerr ); TP_START(fTPInfo,last); return fatalerr; } } SYSYNC_CATCH (...) XML_ParserFree(parser); fConfigP->clear(); fConfigP->setFatalError(LOCERR_CFGPARSE); // this is also fatal ConferrPrintf( "Exception while parsing XML, no valid configuration" ); TP_START(fTPInfo,last); return LOCERR_CFGPARSE; SYSYNC_ENDCATCH TP_START(fTPInfo,last); #if defined(APP_CAN_EXPIRE) && defined(RELEASE_YEAR) && defined(SYSER_REGISTRATION) if (fAppExpiryStatus==LOCERR_TOONEW) { ConferrPrintf( "License is invalid for software released on or after %04d-%02d-01", (fRelDuration / 12) + 2000, (fRelDuration) % 12 + 1 ); } #endif #ifdef APP_CAN_EXPIRE if (fAppExpiryStatus!=LOCERR_OK) { if (fAppExpiryStatus==LOCERR_EXPIRED) { ConferrPrintf("Time-limited License expired"); } else { ConferrPrintf("Missing or bad License Information"); } ConferrPrintf("Please contact Synthesis AG to obtain new license information"); fConfigP->setFatalError(fAppExpiryStatus); // this is also fatal return fAppExpiryStatus; } #endif #ifdef SYSER_REGISTRATION // check if config should have locked sections with a certain CRC value sInt16 daysleft; uInt32 shouldcrc; string s; bool ok=false; // - get restriction string from licensed info ok = getAppEnableInfo(daysleft, NULL, &s)==LOCERR_OK; string restrid,restrval; const char *p = s.c_str(); // start of license info string while (ok && (p=getLicenseRestriction(p,restrid,restrval))!=NULL) { if (restrid=="l") { // lock CRC StrToULong(restrval.c_str(),shouldcrc); ok=shouldcrc==fConfigP->getConfigLockCRC(); } } if (!ok) { ConferrPrintf("Locked config sections are not valid"); fConfigP->setFatalError(LOCERR_BADREG); // this is also fatal return LOCERR_BADREG; } #endif // ok if done MP_SHOWCURRENT(DBG_HOT,"finished reading config"); return finishConfig(); } // TSyncAppBase::readXMLConfigStream #ifdef CONSTANTXML_CONFIG // stream reader for reading from compiled-in text constant static int _CALLING_ ConstantReader( sysync::appCharP aBuffer, sysync::bufferIndex aMaxSize, sysync::bufferIndex *aReadCharsP, void *aContext // const char ** ) { // get cursor const char *readptr = *((const char **)aContext); // read from constant if (!readptr) return false; size_t len = strlen(readptr); if (len>aMaxSize) len=aMaxSize; // - copy if (len>0) strncpy(aBuffer,readptr,len); // - update cursor *((const char **)aContext)=readptr+len; *aReadCharsP=len; // return number of chars actually read return true; // successful } // ConstantReader // config file reading from hard-wired Constant localstatus TSyncAppBase::readXMLConfigConstant(const char *aConstantXML) { const char *aCursor = aConstantXML; return readXMLConfigStream(&ConstantReader, &aCursor); #ifdef SYDEBUG // signal where config came from fConfigFilePath=""; #endif } // TSyncAppBase::readXMLConfigConstant #endif // stream reader for cfile static int _CALLING_ CFileReader( appCharP aBuffer, bufferIndex aMaxSize, bufferIndex *aReadCharsP, void *aContext // FILE * ) { FILE *cfgfile = (FILE *)aContext; // read from file size_t len = fread(aBuffer, 1, aMaxSize, cfgfile); if (len<=0) { if (!feof(cfgfile)) return appFalse; // not EOF, other error: failed len=0; // nothing read, end of file } *aReadCharsP=len; // return number of chars actually read return appTrue; // successful } // CFileReader // config file reading from C file localstatus TSyncAppBase::readXMLConfigCFile(FILE *aCfgFile) { return readXMLConfigStream(&CFileReader, (void *)aCfgFile); } // TSyncAppBase::readXMLConfigCFile // read config from file path localstatus TSyncAppBase::readXMLConfigFile(cAppCharP aFilePath) { localstatus fatalerr; // open file FILE* cfgfile=fopen(aFilePath,"r"); if (cfgfile) { // yes, there is a config file. Get its date getRootConfig()->fConfigDate = getFileModificationDate(aFilePath); // now read the config file (and possibly override fConfigDate) if ((fatalerr=readXMLConfigCFile(cfgfile))!=LOCERR_OK) { fclose(cfgfile); PDEBUGPRINTFX(DBG_ERROR,( "==== Fatal Error %hd reading config file '%s'", fatalerr, aFilePath )); return fatalerr; // config file with fatal errors } fclose(cfgfile); #if defined(SYDEBUG) && !defined(SYSYNC_TOOL) string t; StringObjTimestamp(t,getRootConfig()->fConfigDate); // now write settings to log PDEBUGPRINTFX(DBG_HOT,( "==== Config file '%s' read: Last Config Change=%s, Debug=0x%08lX, Lock=%ld", aFilePath, t.c_str(), (long)PDEBUGMASK, (long)fConfigP->getConfigLockCRC() )); PDEBUGPRINTFX(DBG_HOT,( "==== Config file ID = '%s'", getRootConfig()->fConfigIDString.c_str() )); #endif CONSOLEPRINTF(("- Config file read from '%s'",aFilePath)); #ifdef SYDEBUG if (getRootConfig()->fDebugConfig.fSessionDebugLogs || getRootConfig()->fDebugConfig.fGlobalDebugLogs) { CONSOLEPRINTF(("- Debug log path: %s",getRootConfig()->fDebugConfig.fDebugInfoPath.c_str())); } // signal where config came from fConfigFilePath=aFilePath; #endif // config found return LOCERR_OK; } else { DEBUGPRINTFX(DBG_ERROR,("==== No Config file found under '%s'",aFilePath)); // reset config to defaults fConfigP->clear(); return LOCERR_NOCFGFILE; } } // TSyncAppBase::readXMLConfigFile #ifndef ENGINE_LIBRARY // standard reading of config on predefined paths localstatus TSyncAppBase::readXMLConfigStandard(const char *aConfigFileName, bool aOnlyGlobal, bool aAbsolute) { localstatus fatalerr; SYSYNC_TRY { // - get path where config file should be string cfgfilename; sInt16 attempt= aOnlyGlobal ? 1 : 0; // if only global, don't look in exe dir (e.g. for ISAPI modules) while (true) { // count attempt attempt++; if (aAbsolute) { if (attempt>1) { // no config file found return LOCERR_NOCFGFILE; } // just use path as it is cfgfilename=aConfigFileName; } else { // try paths if (attempt==1) { // first check if there's a local copy if (!getPlatformString(pfs_loccfg_path,cfgfilename)) continue; // none found, try next } else if (attempt==2) { // if no local config file, look for a global one if (!getPlatformString(pfs_globcfg_path,cfgfilename)) continue; // none found, try next } else { CONSOLEPRINTF(("- No config file found, using default settings")); // reset config to defaults fConfigP->clear(); return LOCERR_NOCFGFILE; // no config } // add file name makeOSDirPath(cfgfilename,false); cfgfilename+=aConfigFileName; } fatalerr=readXMLConfigFile(cfgfilename.c_str()); if (fatalerr==LOCERR_OK) break; // config found, ok } // attempt loop } // try SYSYNC_CATCH (...) ConferrPrintf("Fatal Error (exception) while reading config file"); return LOCERR_CFGREAD; SYSYNC_ENDCATCH return LOCERR_OK; // ok } // TSyncAppBase::readXMLConfigStandard #endif // ENGINE_LIBRARY #endif // HARDCODED_CONFIG /* progress sevent notification */ #if defined(PROGRESS_EVENTS) && !defined(ENGINE_LIBRARY) // event generator bool TSyncAppBase::NotifyAppProgressEvent( TProgressEventType aEventType, TLocalDSConfig *aDatastoreID, sInt32 aExtra1, sInt32 aExtra2, sInt32 aExtra3 ) { TProgressEvent theevent; if (fProgressEventFunc) { // there is a progress event callback // - prepare event theevent.eventtype=aEventType; theevent.datastoreID=aDatastoreID; theevent.extra=aExtra1; theevent.extra2=aExtra2; theevent.extra3=aExtra3; // - invoke callback (returns false if aborted) return fProgressEventFunc( theevent, fProgressEventContext ); } // if no callback, never abort return true; // ok, no abort } // TSyncAppBase::NotifyAppProgressEvent #endif // non-engine progress events /* logfile outputs */ /* SyncML toolkit callback handlers */ Ret_t TSyncAppBase::EndMessage(VoidPtr_t userData, Boolean_t aFinal) { if (!userData) return SML_ERR_WRONG_PARAM; // call Session SYSYNC_TRY { return ((TSyncSession *) userData)->EndMessage(aFinal); } SYSYNC_CATCH (exception &e) return HandleDecodingException((TSyncSession *)userData,"EndMessage",&e); SYSYNC_ENDCATCH SYSYNC_CATCH (...) return HandleDecodingException((TSyncSession *)userData,"EndMessage",NULL); SYSYNC_ENDCATCH } // TSyncAppBase::EndMessage Ret_t TSyncAppBase::StartSync(VoidPtr_t userData, SmlSyncPtr_t aContentP) { if (!userData) return SML_ERR_WRONG_PARAM; // call Session SYSYNC_TRY { return ((TSyncSession *) userData)->StartSync(aContentP); } SYSYNC_CATCH (exception &e) return HandleDecodingException((TSyncSession *)userData,"StartSync",&e); SYSYNC_ENDCATCH SYSYNC_CATCH (...) return HandleDecodingException((TSyncSession *)userData,"StartSync",NULL); SYSYNC_ENDCATCH } // TSyncAppBase::StartSync Ret_t TSyncAppBase::EndSync(VoidPtr_t userData) { if (!userData) return SML_ERR_WRONG_PARAM; // call Session SYSYNC_TRY { return ((TSyncSession *) userData)->EndSync(); } SYSYNC_CATCH (exception &e) return HandleDecodingException((TSyncSession *)userData,"EndSync",&e); SYSYNC_ENDCATCH SYSYNC_CATCH (...) return HandleDecodingException((TSyncSession *)userData,"EndSync",NULL); SYSYNC_ENDCATCH } // TSyncAppBase::EndSync #ifdef SEQUENCE_RECEIVE Ret_t TSyncAppBase::StartSequence(VoidPtr_t userData, SmlSequencePtr_t aContentP) { if (!userData) return SML_ERR_WRONG_PARAM; // call Session SYSYNC_TRY { return ((TSyncSession *) userData)->StartSequence(aContentP); } SYSYNC_CATCH (exception &e) return HandleDecodingException((TSyncSession *)userData,"StartSequence",&e); SYSYNC_ENDCATCH SYSYNC_CATCH (...) return HandleDecodingException((TSyncSession *)userData,"StartSequence",NULL); SYSYNC_ENDCATCH } // TSyncAppBase::StartSequence Ret_t TSyncAppBase::EndSequence(VoidPtr_t userData) { if (!userData) return SML_ERR_WRONG_PARAM; // call Session SYSYNC_TRY { return ((TSyncSession *) userData)->EndSequence(); } SYSYNC_CATCH (exception &e) return HandleDecodingException((TSyncSession *)userData,"EndSequence",&e); SYSYNC_ENDCATCH SYSYNC_CATCH (...) return HandleDecodingException((TSyncSession *)userData,"EndSequence",NULL); SYSYNC_ENDCATCH } // TSyncAppBase::EndSequence #endif #ifdef ATOMIC_RECEIVE Ret_t TSyncAppBase::StartAtomic(VoidPtr_t userData, SmlAtomicPtr_t aContentP) { if (!userData) return SML_ERR_WRONG_PARAM; // call Session SYSYNC_TRY { return ((TSyncSession *) userData)->StartAtomic(aContentP); } SYSYNC_CATCH (exception &e) return HandleDecodingException((TSyncSession *)userData,"StartAtomic",&e); SYSYNC_ENDCATCH SYSYNC_CATCH (...) return HandleDecodingException((TSyncSession *)userData,"StartAtomic",NULL); SYSYNC_ENDCATCH } // TSyncAppBase::StartAtomic Ret_t TSyncAppBase::EndAtomic(VoidPtr_t userData) { if (!userData) return SML_ERR_WRONG_PARAM; // call Session SYSYNC_TRY { return ((TSyncSession *) userData)->EndAtomic(); } SYSYNC_CATCH (exception &e) return HandleDecodingException((TSyncSession *)userData,"EndAtomic",&e); SYSYNC_ENDCATCH SYSYNC_CATCH (...) return HandleDecodingException((TSyncSession *)userData,"EndAtomic",NULL); SYSYNC_ENDCATCH } // TSyncAppBase::EndAtomic #endif Ret_t TSyncAppBase::AddCmd(VoidPtr_t userData, SmlAddPtr_t aContentP) { if (!userData) return SML_ERR_WRONG_PARAM; // call Session SYSYNC_TRY { return ((TSyncSession *) userData)->AddCmd(aContentP); } SYSYNC_CATCH (exception &e) return HandleDecodingException((TSyncSession *)userData,"AddCmd",&e); SYSYNC_ENDCATCH SYSYNC_CATCH (...) return HandleDecodingException((TSyncSession *)userData,"AddCmd",NULL); SYSYNC_ENDCATCH } // TSyncAppBase::AddCmd Ret_t TSyncAppBase::AlertCmd(VoidPtr_t userData, SmlAlertPtr_t aContentP) { if (!userData) return SML_ERR_WRONG_PARAM; // call Session SYSYNC_TRY { return ((TSyncSession *) userData)->AlertCmd(aContentP); } SYSYNC_CATCH (exception &e) return HandleDecodingException((TSyncSession *)userData,"AlertCmd",&e); SYSYNC_ENDCATCH SYSYNC_CATCH (...) return HandleDecodingException((TSyncSession *)userData,"AlertCmd",NULL); SYSYNC_ENDCATCH } // TSyncAppBase::AlertCmd Ret_t TSyncAppBase::DeleteCmd(VoidPtr_t userData, SmlDeletePtr_t aContentP) { if (!userData) return SML_ERR_WRONG_PARAM; // call Session SYSYNC_TRY { return ((TSyncSession *) userData)->DeleteCmd(aContentP); } SYSYNC_CATCH (exception &e) return HandleDecodingException((TSyncSession *)userData,"DeleteCmd",&e); SYSYNC_ENDCATCH SYSYNC_CATCH (...) return HandleDecodingException((TSyncSession *)userData,"DeleteCmd",NULL); SYSYNC_ENDCATCH } // TSyncAppBase::DeleteCmd Ret_t TSyncAppBase::GetCmd(VoidPtr_t userData, SmlGetPtr_t aContentP) { if (!userData) return SML_ERR_WRONG_PARAM; // call Session SYSYNC_TRY { return ((TSyncSession *) userData)->GetCmd(aContentP); } SYSYNC_CATCH (exception &e) return HandleDecodingException((TSyncSession *)userData,"GetCmd",&e); SYSYNC_ENDCATCH SYSYNC_CATCH (...) return HandleDecodingException((TSyncSession *)userData,"GetCmd",NULL); SYSYNC_ENDCATCH } // TSyncAppBase::GetCmd Ret_t TSyncAppBase::PutCmd(VoidPtr_t userData, SmlPutPtr_t aContentP) { if (!userData) return SML_ERR_WRONG_PARAM; // call Session SYSYNC_TRY { return ((TSyncSession *) userData)->PutCmd(aContentP); } SYSYNC_CATCH (exception &e) return HandleDecodingException((TSyncSession *)userData,"PutCmd",&e); SYSYNC_ENDCATCH SYSYNC_CATCH (...) return HandleDecodingException((TSyncSession *)userData,"PutCmd",NULL); SYSYNC_ENDCATCH } // TSyncAppBase::PutCmd #ifdef MAP_RECEIVE Ret_t TSyncAppBase::MapCmd(VoidPtr_t userData, SmlMapPtr_t aContentP) { if (!userData) return SML_ERR_WRONG_PARAM; // call Session SYSYNC_TRY { return ((TSyncSession *) userData)->MapCmd(aContentP); } SYSYNC_CATCH (exception &e) return HandleDecodingException((TSyncSession *)userData,"MapCmd",&e); SYSYNC_ENDCATCH SYSYNC_CATCH (...) return HandleDecodingException((TSyncSession *)userData,"MapCmd",NULL); SYSYNC_ENDCATCH } // TSyncAppBase::MapCmd #endif #ifdef RESULT_RECEIVE Ret_t TSyncAppBase::ResultsCmd(VoidPtr_t userData, SmlResultsPtr_t aContentP) { if (!userData) return SML_ERR_WRONG_PARAM; // call Session SYSYNC_TRY { return ((TSyncSession *) userData)->ResultsCmd(aContentP); } SYSYNC_CATCH (exception &e) return HandleDecodingException((TSyncSession *)userData,"ResultsCmd",&e); SYSYNC_ENDCATCH SYSYNC_CATCH (...) return HandleDecodingException((TSyncSession *)userData,"ResultsCmd",NULL); SYSYNC_ENDCATCH } // TSyncAppBase::ResultsCmd #endif Ret_t TSyncAppBase::StatusCmd(VoidPtr_t userData, SmlStatusPtr_t aContentP) { if (!userData) return SML_ERR_WRONG_PARAM; // call Session SYSYNC_TRY { return ((TSyncSession *) userData)->StatusCmd(aContentP); } SYSYNC_CATCH (exception &e) return HandleDecodingException((TSyncSession *)userData,"StatusCmd",&e); SYSYNC_ENDCATCH SYSYNC_CATCH (...) return HandleDecodingException((TSyncSession *)userData,"StatusCmd",NULL); SYSYNC_ENDCATCH } // TSyncAppBase::StatusCmd Ret_t TSyncAppBase::ReplaceCmd(VoidPtr_t userData, SmlReplacePtr_t aContentP) { if (!userData) return SML_ERR_WRONG_PARAM; // call Session SYSYNC_TRY { return ((TSyncSession *) userData)->ReplaceCmd(aContentP); } SYSYNC_CATCH (exception &e) return HandleDecodingException((TSyncSession *)userData,"ReplaceCmd",&e); SYSYNC_ENDCATCH SYSYNC_CATCH (...) return HandleDecodingException((TSyncSession *)userData,"ReplaceCmd",NULL); SYSYNC_ENDCATCH } // TSyncAppBase::ReplaceCmd #ifdef COPY_RECEIVE Ret_t TSyncAppBase::CopyCmd(VoidPtr_t userData, SmlCopyPtr_t aContentP) { if (!userData) return SML_ERR_WRONG_PARAM; // call Session SYSYNC_TRY { return ((TSyncSession *) userData)->CopyCmd(aContentP); } SYSYNC_CATCH (exception &e) return HandleDecodingException((TSyncSession *)userData,"CopyCmd",&e); SYSYNC_ENDCATCH SYSYNC_CATCH (...) return HandleDecodingException((TSyncSession *)userData,"CopyCmd",NULL); SYSYNC_ENDCATCH } // TSyncAppBase::CopyCmd #endif Ret_t TSyncAppBase::MoveCmd(VoidPtr_t userData, SmlMovePtr_t aContentP) { if (!userData) return SML_ERR_WRONG_PARAM; // call Session SYSYNC_TRY { return ((TSyncSession *) userData)->MoveCmd(aContentP); } SYSYNC_CATCH (exception &e) return HandleDecodingException((TSyncSession *)userData,"MoveCmd",&e); SYSYNC_ENDCATCH SYSYNC_CATCH (...) return HandleDecodingException((TSyncSession *)userData,"MoveCmd",NULL); SYSYNC_ENDCATCH } // TSyncAppBase::MoveCmd /* Other Callbacks */ Ret_t TSyncAppBase::HandleError(VoidPtr_t userData) { if (!userData) return SML_ERR_WRONG_PARAM; // call Session SYSYNC_TRY { return ((TSyncSession *) userData)->HandleError(); } SYSYNC_CATCH (exception &e) return HandleDecodingException((TSyncSession *)userData,"HandleError",&e); SYSYNC_ENDCATCH SYSYNC_CATCH (...) return HandleDecodingException((TSyncSession *)userData,"HandleError",NULL); SYSYNC_ENDCATCH } // TSyncAppBase::HandleError // %%%% Ret_t TSyncAppBase::DummyHandler(VoidPtr_t userData, const char* msg) { if (!userData) return SML_ERR_WRONG_PARAM; if (userData) { // session is attached SYSYNC_TRY { return ((TSyncSession *) userData)->DummyHandler(msg); } SYSYNC_CATCH (exception &e) return HandleDecodingException((TSyncSession *)userData,"DummyHandler",&e); SYSYNC_ENDCATCH SYSYNC_CATCH (...) return HandleDecodingException((TSyncSession *)userData,"DummyHandler",NULL); SYSYNC_ENDCATCH } else { DEBUGPRINTFX(DBG_HOT,("DummyHandler (without session attached): msg=%s",msg)); return SML_ERR_OK; } } // TSyncAppBase::DummyHandler /* SyncML toolkit callback address table */ static const SmlCallbacks_t mySmlCallbacks = { /* message callbacks */ smlStartMessageCallback, smlEndMessageCallback, /* grouping commands */ smlStartSyncCallback, smlEndSyncCallback, #ifdef ATOMIC_RECEIVE /* these callbacks are NOT included in the Toolkit lite version */ smlStartAtomicCallback, smlEndAtomicCallback, #endif #ifdef SEQUENCE_RECEIVE smlStartSequenceCallback, smlEndSequenceCallback, #endif /* Sync Commands */ smlAddCmdCallback, smlAlertCmdCallback, smlDeleteCmdCallback, smlGetCmdCallback, smlPutCmdCallback, #ifdef MAP_RECEIVE smlMapCmdCallback, #endif #ifdef RESULT_RECEIVE smlResultsCmdCallback, #endif smlStatusCmdCallback, smlReplaceCmdCallback, /* other commands */ #ifdef COPY_RECEIVE /* these callbacks are NOT included in the Toolkit lite version */ smlCopyCmdCallback, #endif #ifdef EXEC_RECEIVE smlExecCmdCallback, #endif #ifdef SEARCH_RECEIVE smlSearchCmdCallback, #endif smlMoveCmdCallback, /* Other Callbacks */ smlHandleErrorCallback, smlTransmitChunkCallback }; /* sml_callbacks struct */ /* Context record to find back to appbase and store userData */ typedef struct { TSyncAppBase *appBaseP; void *userDataP; } TSmlContextDataRec; /* SyncML toolkit callback implementations */ // macros to simplify access to contex #define GET_APPBASE(x) (((TSmlContextDataRec *)x)->appBaseP) #define GET_USERDATA(x) (((TSmlContextDataRec *)x)->userDataP) /* message callbacks */ static Ret_t smlStartMessageCallback(InstanceID_t id, VoidPtr_t userData, SmlSyncHdrPtr_t pContent) { return GET_APPBASE(userData)->StartMessage(id,GET_USERDATA(userData),pContent); } static Ret_t smlEndMessageCallback(InstanceID_t id, VoidPtr_t userData, Boolean_t final) { return GET_APPBASE(userData)->EndMessage(GET_USERDATA(userData),final); } /* grouping commands */ static Ret_t smlStartSyncCallback(InstanceID_t id, VoidPtr_t userData, SmlSyncPtr_t pContent) { return GET_APPBASE(userData)->StartSync(GET_USERDATA(userData),pContent); } static Ret_t smlEndSyncCallback(InstanceID_t id, VoidPtr_t userData) { return GET_APPBASE(userData)->EndSync(GET_USERDATA(userData)); } #ifdef ATOMIC_RECEIVE /* these callbacks are NOT included in the Toolkit lite version */ static Ret_t smlStartAtomicCallback(InstanceID_t id, VoidPtr_t userData, SmlAtomicPtr_t pContent) { return GET_APPBASE(userData)->StartAtomic(GET_USERDATA(userData),pContent); } static Ret_t smlEndAtomicCallback(InstanceID_t id, VoidPtr_t userData) { return GET_APPBASE(userData)->EndAtomic(GET_USERDATA(userData)); } #endif #ifdef SEQUENCE_RECEIVE static Ret_t smlStartSequenceCallback(InstanceID_t id, VoidPtr_t userData, SmlSequencePtr_t pContent) { return GET_APPBASE(userData)->StartSequence(GET_USERDATA(userData),pContent); } static Ret_t smlEndSequenceCallback(InstanceID_t id, VoidPtr_t userData) { return GET_APPBASE(userData)->EndSequence(GET_USERDATA(userData)); } #endif /* Sync Commands */ static Ret_t smlAddCmdCallback(InstanceID_t id, VoidPtr_t userData, SmlAddPtr_t pContent) { return GET_APPBASE(userData)->AddCmd(GET_USERDATA(userData),pContent); } static Ret_t smlAlertCmdCallback(InstanceID_t id, VoidPtr_t userData, SmlAlertPtr_t pContent) { return GET_APPBASE(userData)->AlertCmd(GET_USERDATA(userData),pContent); } static Ret_t smlDeleteCmdCallback(InstanceID_t id, VoidPtr_t userData, SmlDeletePtr_t pContent) { return GET_APPBASE(userData)->DeleteCmd(GET_USERDATA(userData),pContent); } static Ret_t smlGetCmdCallback(InstanceID_t id, VoidPtr_t userData, SmlGetPtr_t pContent) { return GET_APPBASE(userData)->GetCmd(GET_USERDATA(userData),pContent); } static Ret_t smlPutCmdCallback(InstanceID_t id, VoidPtr_t userData, SmlPutPtr_t pContent) { return GET_APPBASE(userData)->PutCmd(GET_USERDATA(userData),pContent); } #ifdef MAP_RECEIVE static Ret_t smlMapCmdCallback(InstanceID_t id, VoidPtr_t userData, SmlMapPtr_t pContent) { return GET_APPBASE(userData)->MapCmd(GET_USERDATA(userData),pContent); } #endif #ifdef RESULT_RECEIVE static Ret_t smlResultsCmdCallback(InstanceID_t id, VoidPtr_t userData, SmlResultsPtr_t pContent) { return GET_APPBASE(userData)->ResultsCmd(GET_USERDATA(userData),pContent); } #endif static Ret_t smlStatusCmdCallback(InstanceID_t id, VoidPtr_t userData, SmlStatusPtr_t pContent) { return GET_APPBASE(userData)->StatusCmd(GET_USERDATA(userData),pContent); } static Ret_t smlReplaceCmdCallback(InstanceID_t id, VoidPtr_t userData, SmlReplacePtr_t pContent) { return GET_APPBASE(userData)->ReplaceCmd(GET_USERDATA(userData),pContent); } /* other commands */ #ifdef COPY_RECEIVE /* these callbacks are NOT included in the Toolkit lite version */ static Ret_t smlCopyCmdCallback(InstanceID_t id, VoidPtr_t userData, SmlCopyPtr_t pContent) { return GET_APPBASE(userData)->CopyCmd(GET_USERDATA(userData),pContent); } #endif static Ret_t smlMoveCmdCallback(InstanceID_t id, VoidPtr_t userData, SmlMovePtr_t pContent) { return GET_APPBASE(userData)->MoveCmd(GET_USERDATA(userData),pContent); } #ifdef EXEC_RECEIVE static Ret_t smlExecCmdCallback(InstanceID_t id, VoidPtr_t userData, SmlExecPtr_t pContent) { /*%%%tbd return GET_APPBASE(userData)->ExecCmd(GET_USERDATA(userData),pContent); */ return SML_ERR_INVALID_OPTIONS; } #endif #ifdef SEARCH_RECEIVE static Ret_t smlSearchCmdCallback(InstanceID_t id, VoidPtr_t userData, SmlSearchPtr_t pContent) { /*%%%tbd return GET_APPBASE(userData)->SearchCmd(GET_USERDATA(userData),pContent); */ return SML_ERR_INVALID_OPTIONS; } #endif /* Other Callbacks */ static Ret_t smlHandleErrorCallback(InstanceID_t id, VoidPtr_t userData) { return GET_APPBASE(userData)->DummyHandler(GET_USERDATA(userData),"ErrorCallback"); } static Ret_t smlTransmitChunkCallback(InstanceID_t id, VoidPtr_t userData) { /*%%%tdb return GET_APPBASE(userData)->TransmitChunk(GET_USERDATA(userData),pContent); */ return SML_ERR_INVALID_OPTIONS; } /* end callback implementations */ /* RTK interfacing */ Ret_t TSyncAppBase::setSmlInstanceUserData( InstanceID_t aInstanceID, void *aUserDataP ) { void *ctxP = NULL; if (smlGetUserData(aInstanceID,&ctxP)==SML_ERR_OK && ctxP) { static_cast(ctxP)->userDataP=aUserDataP; return SML_ERR_OK; } return SML_ERR_MGR_INVALID_INSTANCE_INFO; // invalid instance (has no TSmlContextDataRec in userData) } // TSyncAppBase::setSmlInstanceUserData Ret_t TSyncAppBase::getSmlInstanceUserData( InstanceID_t aInstanceID, void **aUserDataPP ) { void *ctxP = NULL; if (smlGetUserData(aInstanceID,&ctxP)==SML_ERR_OK && ctxP) { *aUserDataPP = static_cast(ctxP)->userDataP; return SML_ERR_OK; } return SML_ERR_MGR_INVALID_INSTANCE_INFO; // invalid instance (has no TSmlContextDataRec in userData) } // TSyncAppBase::setSmlInstanceUserData // create new SyncML toolkit instance bool TSyncAppBase::newSmlInstance( SmlEncoding_t aEncoding, sInt32 aWorkspaceMem, InstanceID_t &aInstanceID ) { SmlInstanceOptions_t myInstanceOptions; Ret_t err; #ifndef NOWSM #error "Only NOWSM version is supported any more" #endif // Set options // - encoding myInstanceOptions.encoding=aEncoding; // - total size of instance buffer // (must have room for both incoming and outgoing message if instance // is used for both) myInstanceOptions.workspaceSize=aWorkspaceMem; // - maximum outgoing message size myInstanceOptions.maxOutgoingSize=0; // %%% disabled for now, can be set later with setMaxOutgoingSize() // - create user data record TSmlContextDataRec *smlContextRecP = new TSmlContextDataRec; if (!smlContextRecP) return false; smlContextRecP->appBaseP=this; // pointer to find back to this syncappbase w/o the help of global vars smlContextRecP->userDataP=NULL; // userData will be SySyncSession pointer, but now session is not yet determined // - now instantiate (thread-safe!) err=smlInitInstance( &mySmlCallbacks, // callbacks &myInstanceOptions, smlContextRecP, &aInstanceID // where to store the instance ID ); // - return instance or NULL if failed if (err==SML_ERR_OK) { DEBUGPRINTFX(DBG_RTK_SML,("////////////// sml Instance created, id(=instanceInfoPtr)=0x%08lX",(long)aInstanceID)); return true; // success } else { DEBUGPRINTFX(DBG_ERROR,("************ smlInitInstance returned 0x%hX",(sInt16)err)); aInstanceID=NULL; // none return false; // failed } } // TSyncAppBase::newSmlInstance void TSyncAppBase::freeSmlInstance(InstanceID_t aInstance) { // forget instance now // - accept no-instance if (aInstance==NULL) return; // - there is an instance // - free context record void *ctxP; if (smlGetUserData(aInstance,&ctxP)==SML_ERR_OK && ctxP) delete static_cast(ctxP); // - free instance itself Ret_t err=smlTerminateInstance(aInstance); DEBUGPRINTFX(DBG_RTK_SML,("////////////// sml Instance freed, id(=instanceInfoPtr)=0x%08lX, err=0x%hX",(long)aInstance,(sInt16)err)); #ifdef SYDEBUG if (err!=SML_ERR_OK) { DEBUGPRINTFX(DBG_ERROR,("smlTerminateInstance returned 0x%hX",(sInt16)err)); } #endif } // TSyncAppBase::freeSmlInstance // determine encoding from beginning of SyncML message data SmlEncoding_t TSyncAppBase::encodingFromData(cAppPointer aData, memSize aDataSize) { SmlEncoding_t enc = SML_UNDEF; if (aData && aDataSize>=5) { // check for WBXML intro sequences // Only SyncML 2.0 (OMA-TS-DS_Syntax-V2_0-20090212-C.doc, Paragraph 5.4, WBXML Usage) specifies it explicitly: // For the purposes of OMA-DS, WBXML 1.1, WBXML 1.2 and WBXML 1.3 are functionally equivalent, and // all MUST be accepted in implementations that support WBXML. Effectively, this merely requires the // WBXML parser to accept 01, 02 or 03 as the first byte of the document. // About WBXML Versions, the WireShark Wiki http://wiki.wireshark.org/WAP_Binary_XML says: // The initial WBXML 1.0 specification was not adopted. It is significantly different from the subsequent WBXML // versions (1.1, 1.2 and 1.3). Those subsequent versions are almost identical. // Now check for valid WBXML versions: First byte is vvvvmmmm where v=major version-1, m=minor version uInt8 wbxmlvers = *((cUInt8P)aData); if ( wbxmlvers=='\x01' || // WBXML 1.1 wbxmlvers=='\x02' || // WBXML 1.2 wbxmlvers=='\x03' // WBXML 1.3 ) { // WBXML version ok, check FPI // - a WBXML integer defines the FPI (multi-byte, MSByte first, Bit 7 is continuation flag, Bit 6..0 are data. LSByte has Bit7=0) cAppCharP fpi = ((cAppCharP)aData)+1; if ( (*fpi=='\x01') || // FPI==1 means "unknown public identifier". Some Funambol servers use this (memcmp(fpi,"\x00\x00",2)==0) || // Public identifier as string (memcmp(fpi,"\xA4\x01",2)==0) || // Public identifier 0x1201 for SyncML 1.2 (memcmp(fpi,"\x9F\x53",2)==0) || // Public identifier 0x0FD3 for SyncML 1.1 (memcmp(fpi,"\x9F\x51",2)==0) // Public identifier 0x0FD1 for SyncML 1.0 ) enc=SML_WBXML; } // check XML now if not detected WBXML. if (enc==SML_UNDEF) { // could be XML // - skip UTF-8 BOM if there is one cUInt8P p = (cUInt8P)aData; if (p[0]==0xEF && p[1]==0xBB && p[2]==0xBF) p+=3; // skip the BOM // now check for XML if (strnncmp((cAppCharP)p,"(enc); } // TSyncAppBase::encodingFromContentType // save app state (such as settings in datastore configs etc.) void TSyncAppBase::saveAppState(void) { if (fConfigP) fConfigP->saveAppState(); } // TSyncAppBase::saveAppState // manufacturer of overall solution (can be configured, while OEM is fixed to Synthesis) string TSyncAppBase::getManufacturer(void) { #ifdef ENGINEINTERFACE_SUPPORT if (fConfigP && !(fConfigP->fMan.empty())) return fConfigP->fMan; string s; if (getConfigVar("custommanufacturer", s)) { return s; } #endif // if no string configured, return default return CUST_SYNC_MAN; } // TSyncAppBase::getManufacturer // model (application name) of overall solution string TSyncAppBase::getModel(void) { #ifdef ENGINEINTERFACE_SUPPORT if (fConfigP && !(fConfigP->fMod.empty())) return fConfigP->fMod; string s; if (getConfigVar("custommodel", s)) { return s; } #endif // if no string configured, return default return CUST_SYNC_MODEL; } // TSyncAppBase::getModel // hardware version string TSyncAppBase::getHardwareVersion(void) { string s; #ifdef ENGINEINTERFACE_SUPPORT if (fConfigP && !(fConfigP->fHwV.empty())) { return fConfigP->fHwV; } if (getConfigVar("customhardwareversion", s)) { return s; } #endif // if no string configured, return default getPlatformString(pfs_device_name, s); return s; } // TSyncAppBase::getHardwareVersion // firmware version (depends a lot on the context - OS version?) string TSyncAppBase::getFirmwareVersion(void) { string s; #ifdef ENGINEINTERFACE_SUPPORT if (fConfigP && !(fConfigP->fFwV.empty())) { return fConfigP->fFwV; } if (getConfigVar("customfirmwareversion", s)) { return s; } #endif // if no string configured, return default getPlatformString(pfs_platformvers, s); return s; } // TSyncAppBase::getHardwareVersion // hardware type (PDA, PC, ...) string TSyncAppBase::getDevTyp() { #ifdef ENGINEINTERFACE_SUPPORT string s; if (fConfigP && !(fConfigP->fDevTyp.empty())) { return fConfigP->fDevTyp; } if (getConfigVar("customdevicetype", s)) { return s; } #endif // if no string configured, return default if (isServer()) return SYNCML_SERVER_DEVTYP; else return SYNCML_CLIENT_DEVTYP; } // TSyncAppBase::getDevTyp // device ID (can be customized using "customdeviceid" config variable) // Returns true if deviceID is guaranteed unique bool TSyncAppBase::getMyDeviceID(string &devid) { #ifdef ENGINEINTERFACE_SUPPORT if (getConfigVar("customdeviceid", devid)) { return true; // custom device ID is assumed to be guaranteed unique } #endif // use device ID as determined by platform adapters return getLocalDeviceID(devid); } // TSyncAppBase::getMyDeviceID #ifdef APP_CAN_EXPIRE void TSyncAppBase::updateAppExpiry(void) { // this is the basic check. Some other checks // are spread in various files to disguise checking a little #if defined(EXPIRES_AFTER_DAYS) || defined(SYSER_REGISTRATION) // check soft expiry fAppExpiryStatus = appEnableStatus(); // check hard expiry only if demo, that is, if no valid license is installed if (fAppExpiryStatus==LOCERR_OK && fDaysLeft>=0 && !fRegOK) #endif { fAppExpiryStatus = #ifdef EXPIRES_AFTER_DATE // check hard expiry date fScrambledNow>SCRAMBLED_EXPIRY_VALUE ? LOCERR_EXPIRED : LOCERR_OK; #else // no hard expiry, just ok if enabled LOCERR_OK; #endif } } // TSyncAppBase::updateAppExpiry #endif #ifdef SYSER_REGISTRATION // checks if registered (must be implemented in base class) // returns LOCERR_EXPIRED, LOCERR_TOONEW or LOCERR_BADREG if not registered correctly localstatus TSyncAppBase::isRegistered(void) { #if !defined(HARDCODED_CONFIG) || defined(ENGINEINTERFACE_SUPPORT) // we have licensing in the config file or using engine interface, check it return fConfigP ? checkRegInfo(fConfigP->fLicenseName.c_str(),fConfigP->fLicenseCode.c_str(),false) : LOCERR_BADREG; #else // no license checking at this level (maybe overriden method provides check) return LOCERR_EXPIRED; #endif } // TSyncAppBase::isRegistered // get (entire) registration string void TSyncAppBase::getRegString(string &aString) { #if !defined(HARDCODED_CONFIG) || defined(ENGINEINTERFACE_SUPPORT) // we have licensing in the config file or set via engine interface, use it if (fConfigP) aString=fConfigP->fLicenseName; else #endif { aString.erase(); } } // TSyncAppBase::getRegString #endif // safety checks #if !defined(APP_CAN_EXPIRE) && defined(RELEASE_VERSION) && !defined(NEVER_EXPIRES_IS_OK) #error "Warning: Release version that never expires!" #endif #ifdef APP_CAN_EXPIRE // make sure we have a valid variant code for the target #ifndef SYSER_VARIANT_CODE #error "SYSER_VARIANT_CODE must be defined in target_options.h" #endif // check enable status of application localstatus TSyncAppBase::appEnableStatus(void) { // safety check - app w/o initialized config is NOT enabled // Note: agentconfig tested here, but all other config sections are created in clear() at the same time if (!fConfigP || !(fConfigP->fAgentConfigP)) { return LOCERR_WRONGUSAGE; } // check registration (which will disable normal expiry) #ifdef SYSER_REGISTRATION localstatus regsta = isRegistered(); // ok if registered #else #ifndef APP_CAN_EXPIRE localstatus regsta = LOCERR_OK; // not registerable, not exprining - just run forever #ifndef NEVER_EXPIRES_IS_OK #error "WARNING: Completely unlimited operation w/o license or expiry - is this intended??" #endif // not NEVER_EXPIRES_IS_OK #else localstatus regsta = LOCERR_BADREG; // not registerable, assume no license, must be eval which expires #endif // APP_CAN_EXPIRE #endif localstatus sta = regsta; // check expiry (only if registration has not already defined one) #ifdef APP_CAN_EXPIRE #ifdef NO_LICENSE_UNTIL_HARDEXPIRY // we don't need a valid license code until hard expiry date hits // so if we have a failure now, let the hard expiry decide if (regsta!=LOCERR_OK) { #ifdef SYSER_REGISTRATION fDaysLeft=1; // simulate expiring tomorrow #endif sta = LOCERR_OK; // ok if we find no hard expiry later // then let hard expiry decide #ifndef EXPIRES_AFTER_DATE #error "WARNING: NO_LICENSE_UNTIL_HARDEXPIRY without EXPIRES_AFTER_DATE - running forever w/o license - indended that way?" #endif } #endif sInt32 td = lineartime2dateonly(getSystemNowAs(TCTX_UTC)); #if defined(EXPIRES_AFTER_DAYS) || defined(NO_LICENSE_UNTIL_HARDEXPIRY) if (regsta==LOCERR_BADREG || regsta==LOCERR_WRONGPROD) { // not registered (for this product), check if we are in evaluation period #ifdef EXPIRES_AFTER_DATE // check hard expiry first if (fScrambledNow>SCRAMBLED_EXPIRY_VALUE) { #ifdef SYSER_REGISTRATION fDaysLeft=0; // hard-expired #endif sta = LOCERR_EXPIRED; } else #endif { #ifdef EXPIRES_AFTER_DAYS // (bfo found that we need to check for > demo days too, as // otherwise some clever guys could install with the // clock 20 years in the future and then set the clock back) uInt32 vers; lineardate_t firstuse; getFirstUseInfo(SYSER_VARIANT_CODE,firstuse,vers); sInt32 d = firstuse+EXPIRES_AFTER_DAYS - td; fDaysLeft = d>0 && d<=EXPIRES_AFTER_DAYS ? d : 0; sta = d>0 ? LOCERR_OK : LOCERR_EXPIRED; #else // Do NOT change the status to expired! - just pass on the license error status // which might be ok here in case we have a NO_LICENSE_UNTIL_HARDEXPIRY //sta = LOCERR_EXPIRED; #endif } } #endif #else fDaysLeft=-1; // App cannot expire, no limit #endif return sta; } // TSyncAppBase::appEnableStatus // get registration information to display (and check internally) localstatus TSyncAppBase::getAppEnableInfo(sInt16 &aDaysLeft, string *aRegnameP, string *aRegInternalsP) { #ifndef SYSER_REGISTRATION // no registration if (aRegnameP) aRegnameP->erase(); if (aRegInternalsP) aRegInternalsP->erase(); aDaysLeft = -1; // no expiring license (altough hardexpiry might still apply) return appEnableStatus(); #else // we have registration localstatus sta = appEnableStatus(); if (sta!=LOCERR_OK) { if (aRegnameP) aRegnameP->erase(); if (aRegInternalsP) aRegInternalsP->erase(); return sta; // not enabled } // do an extra check here aDaysLeft = fDaysLeft; if (fDaysLeft==0) SYSYNC_THROW(exception()); // exit app, as fDaysLeft must be > 0 or -1 here // get strings if requested if (aRegnameP || aRegInternalsP) { string s; // get entire string getRegString(s); // check for separation into a visible (name) and and invisible (email or license restriction) part size_t n,m; size_t l=s.size(); // - first priority: license restrictions in form ::x=something n=s.find("::"); if (n!=string::npos) { // found a license restriction m=n; // everthing before special separator belongs to name, rest to internals } else { // - second priority: a simple email address at the end of the string n=s.rfind('@'); if (n==string::npos) { n=l; m=l; // no email, entire string is name } else { n=s.rfind(' ',n); if (n==string::npos) { n=l; m=l; // no email, entire string is name } else { m=n+1; // do not return separating space in either name nor internals } } } // now remove spaces at the beginning to avoid // invisible registration info int i = s.find_first_not_of(' '); if (i==string::npos) i=0; // no non-space -> start at beginning /* int i; for (i= 0; iassign(s, i,n); if (aRegInternalsP) { if (massign(s,m,l-m); else aRegInternalsP->erase(); } } return sta; #endif } // TSyncAppBase::getAppEnableInfo #endif // APP_CAN_EXPIRE #ifdef EXPIRES_AFTER_DAYS // make sure we have a valid variant code for the target #ifndef SYSER_VERSCHECK_MASK #error "SYSER_VERSCHECK_MASK must be defined in target_options.h" #endif /// @brief get time and version of first use. Version is included to allow re-evaluating after version changes significantly void TSyncAppBase::getFirstUseInfo(uInt8 aVariant, lineardate_t &aFirstUseDate, uInt32 &aFirstUseVers) { #ifndef ENGINEINTERFACE_SUPPORT // no first use date in base class, is overridden in derived platform-specific appBase classes. aFirstUseDate=0; aFirstUseVers=0; #else // use values stored into engine via settings keys aFirstUseDate=fFirstUseDate; aFirstUseVers=fFirstUseVers; #endif } // TSyncAppBase::getFirstUseInfo /// @brief update first use info to allow for repeated eval when user installs an all-new version /// @return true if update was needed /// @param[in] aVariant variant context to perform update /// @param[in,out] aFirstUseDate date when this variant and version was used first. /// Will be updated /// @param[in,out] aFirstUseVers version that relates to aFirstUseDate. /// Will be updated to current version if version check allows re-starting demo period. bool TSyncAppBase::updateFirstUseInfo(lineardate_t &aFirstUseDate, uInt32 &aFirstUseVers) { // update if current version is significantly newer than what we used last time if ( aFirstUseDate==0 || ((aFirstUseVers & SYSER_VERSCHECK_MASK) < (SYSYNC_VERSION_UINT32 & SYSER_VERSCHECK_MASK)) ) { // current version is different in a relevant part of the version number, so reset first use aFirstUseDate = getSystemNowAs(TCTX_UTC) / linearDateToTimeFactor; aFirstUseVers = SYSYNC_VERSION_UINT32; return true; } // no updates return false; } // TSyncAppBase::updateFirstUseInfo #endif // EXPIRES_AFTER_DAYS #ifdef SYSER_REGISTRATION // helper to get next restriction out of license string const char * TSyncAppBase::getLicenseRestriction(const char *aInfo, string &aID, string &aVal) { const char *p; char c; bool quotedval=false; // if no info or at end of string, return NULL if (!aInfo || *aInfo==0) return NULL; // find next restriction aInfo=strstr(aInfo,"::"); if (!aInfo) return NULL; // no more restrictions found // get ID of restriction aInfo+=2; // skip :: p=strchr(aInfo,'='); if (!p) return NULL; // no more restrictions found // - assign ID aID.assign(aInfo,p-aInfo); aInfo=p+1; // skip = // get value of restriction aVal.erase(); if (*aInfo==0x22) { // starts with doublequote -> treat as quoted value quotedval=true; aInfo++; } while ((c=*aInfo)) { aInfo++; if (quotedval) { // quoted string ends with " and can contain backslash escapes if (c==0x22) break; // done after closing quote if (c=='\\') { if (*aInfo==0) break; // quote without char following, stop here c=*aInfo++; // get next char } } else { // unquoted string ends with next space if (isspace(c)) break; } // save char aVal+=c; } // return where to continue scanning for next item return aInfo; } // TSyncAppBase::getLicenseRestriction // checks registration code for CRC ok and compare with // predefined constants for product code etc. localstatus TSyncAppBase::checkRegInfo(const char *aRegKey, const char *aRegCode, bool aMangled) { uInt32 infocrc; // extract information from registration code localstatus regSta = LOCERR_OK; fRelDuration=0; // do not allow registration text less than 12 chars if (strlen(aRegKey)<12) regSta=LOCERR_BADREG; // too short code is a bad code else if (!getSySerialInfo( aRegCode, // code fRegProductFlags, fRegProductCode, fRegLicenseType, fRegQuantity, fRegDuration, fLicCRC, // CRC as included in the license code infocrc, aMangled )) regSta=LOCERR_BADREG; // no code is a bad code if (regSta==LOCERR_OK) { // code is basically ok, check standard info if (!( // product code ( (fRegProductCode == SYSER_PRODUCT_CODE_MAIN) #ifdef SYSER_PRODUCT_CODE_ALT1 || (fRegProductCode == SYSER_PRODUCT_CODE_ALT1) #endif #ifdef SYSER_PRODUCT_CODE_ALT2 || (fRegProductCode == SYSER_PRODUCT_CODE_ALT2) #endif #ifdef SYSER_PRODUCT_CODE_ALT3 || (fRegProductCode == SYSER_PRODUCT_CODE_ALT3) #endif #ifdef SYSER_PRODUCT_CODE_ALT4 || (fRegProductCode == SYSER_PRODUCT_CODE_ALT4) #endif #ifdef SYSER_PRODUCT_CODE_ALT5 || (fRegProductCode == SYSER_PRODUCT_CODE_ALT5) #endif #ifdef SYSER_PRODUCT_CODE_ALT6 || (fRegProductCode == SYSER_PRODUCT_CODE_ALT6) #endif #ifdef SYSER_PRODUCT_CODE_ALT7 || (fRegProductCode == SYSER_PRODUCT_CODE_ALT7) #endif #ifdef SYSER_PRODUCT_CODE_ALT8 || (fRegProductCode == SYSER_PRODUCT_CODE_ALT8) #endif #ifdef SYSER_PRODUCT_CODE_ALT9 || (fRegProductCode == SYSER_PRODUCT_CODE_ALT9) #endif ) // special SYSER_PRODFLAG_MAXRELDATE product flag && ( ((SYSER_NEEDED_PRODUCT_FLAGS & SYSER_PRODFLAG_MAXRELDATE)==0) || // either maxreldate flag is not required... (fRegProductFlags & SYSER_PRODFLAG_MAXRELDATE) || // ..or it is present.. (fRegDuration!=0) // ..or there is a time limit, which means that the even if the flag is required, product can run with a timed license without the flag ) // test other product flags (all except SYSER_PRODFLAG_MAXRELDATE) && ((fRegProductFlags & (SYSER_NEEDED_PRODUCT_FLAGS & ~SYSER_PRODFLAG_MAXRELDATE)) == (SYSER_NEEDED_PRODUCT_FLAGS & ~SYSER_PRODFLAG_MAXRELDATE)) && ((fRegProductFlags & SYSER_FORBIDDEN_PRODUCT_FLAGS) == 0) )) regSta=LOCERR_WRONGPROD; // anyway, check if CRC is ok if (!(fLicCRC == addNameToCRC(infocrc,aRegKey,aMangled))) { regSta=LOCERR_BADREG; // bad CRC is bad registration (and has precedence over wrong product) // make sure we do not enable exotic functionality fRegProductFlags=0; fRegLicenseType=0; fRegQuantity=1; fRegDuration=0; fRelDuration=0; } } // Now if we have OK, app is registered, but maybe limited // by time or max release date. if (regSta==LOCERR_OK) { // - check max release date limit first if (fRegProductFlags & SYSER_PRODFLAG_MAXRELDATE) { // duration is a release duration // - in case this is a max release date limited license, this // excludes time limited - max release date licenses are always permanent fRelDuration = fRegDuration; fRegDuration = 0; // Now check if this build has a hard-coded release date #ifdef RELEASE_YEAR // license valid only up to release date specified, check that // if (fRegDuration > (RELEASE_YEAR-2000)*12+RELEASE_MONTH-1) // plain if ( fRelDuration && (fRelDuration*3+48 <= 3*((RELEASE_YEAR-2000)*12+RELEASE_MONTH-1)+48) ) { // a bit disguised // license is not valid any more for a build as new as this one fRegOK=false; return LOCERR_TOONEW; } #endif } // - check for expired license now // Note: we don't check demo period (days after first use) here if (fRegDuration!=0) { lineardate_t ending = date2lineardate(fRegDuration/12+2000,fRegDuration%12+1,1); sInt32 d=ending-lineartime2dateonly(getSystemNowAs(TCTX_UTC)); fDaysLeft = d>0 ? d : 0; if (d<=0) { // license has expired fRegOK=false; return LOCERR_EXPIRED; } } else fDaysLeft=-1; // unlimited by registration } // if it is not ok here, registration code is bad fRegOK=regSta==LOCERR_OK; // save for further reference return regSta; // return status } // TSyncAppBase::checkRegInfo // checks if current license is properly activated // - note: must be called at a time when internet connection is available localstatus TSyncAppBase::checkLicenseActivation(lineardate_t &aLastcheck, uInt32 &aLastcrc) { bool ok = true; // - check if already activated if ( fRegLicenseType && ( (aLastcrc != fLicCRC) || // different license than at last activation (aLastcheck==0) || // never checked at all (aLastcheck+180 < lineartime2dateonly(getSystemNowAs(TCTX_UTC))) // not checked in the last half year ) ) { // re-check needed ok = checkLicenseType(fRegLicenseType); // update check date even if we fail (but only if we checked once before) // to prevent failed sync sessions when reg server has a problem if (ok || aLastcheck) { aLastcheck = lineartime2dateonly(getSystemNowAs(TCTX_UTC)); } // update CRC only if we could validate the new CRC if (ok) { aLastcrc = fLicCRC; } } // show it to user if (!ok) { #ifndef ENGINE_LIBRARY APP_PROGRESS_EVENT(this,pev_error,NULL,LOCERR_BADREG,0,0); #endif } // return status return ok ? LOCERR_OK : LOCERR_BADREG; } // TSyncAppBase::checkLicenseActivation #endif #ifdef CONCURRENT_DEVICES_LIMIT // check if session count is exceeded void TSyncAppBase::checkSessionCount(sInt32 aSessionCount, TSyncSession *aSessionP) { // Check if session must be busy (due to licensing restrictions) // - some minor arithmetic to hide actual comparison with limit #ifdef SYSER_REGISTRATION // number of users from license or hardcoded limit, whichever is lower sInt32 scrambledlimit = 3*(CONCURRENT_DEVICES_LIMIT!=0 && CONCURRENT_DEVICES_LIMIT=scrambledlimit && scrambledlimit!=42) #ifdef CUSTOMIZABLE_DEVICES_LIMIT // compare with configurable limit, if not set to zero (=unlimited) || (((aSessionCount<<2) > fConfigP->fConcurrentDeviceLimit*4) && fConfigP->fConcurrentDeviceLimit) #endif ) { // make session busy (not really responding) aSessionP->setSessionBusy(true); PDEBUGPRINTFX(DBG_HOT,("***** Limit of concurrent sessions reached, server response is 'busy'")); // info CONSOLEPRINTF(("- concurrent session limit reached, rejecting session with BUSY status")); } } // TSyncAppBase::checkSessionCount #endif // factory methods of Rootconfig // ============================= // Create datatypes registry - default to Multifield-capable version void TRootConfig::installDatatypesConfig(void) { fDatatypesConfigP = new TMultiFieldDatatypesConfig(this); // default } // TSyncAppBase::newDatatypesConfig #ifndef HARDCODED_CONFIG bool TRootConfig::parseDatatypesConfig(const char **aAttributes, sInt32 aLine) { // currently, only one type of datatype registry exists per app, so we do not // need to check attributes expectChildParsing(*fDatatypesConfigP); return true; } // TRootConfig::parseDatatypesConfig #endif } // namespace sysync #ifdef CONFIGURABLE_TYPE_SUPPORT #ifdef MIMEDIR_SUPPORT #include "vcarditemtype.h" #include "vcalendaritemtype.h" #endif #ifdef TEXTTYPE_SUPPORT #include "textitemtype.h" #endif #ifdef RAWTYPE_SUPPORT #include "rawdataitemtype.h" #endif #ifdef DATAOBJ_SUPPORT #include "dataobjtype.h" #endif namespace sysync { // create new datatype config by name // returns NULL if none found TDataTypeConfig *TRootConfig::newDataTypeConfig(const char *aName, const char *aBaseType, TConfigElement *aParentP) { #ifdef MIMEDIR_SUPPORT if (strucmp(aBaseType,"mimedir")==0) return new TMIMEDirTypeConfig(aName,aParentP); else if (strucmp(aBaseType,"vcard")==0) return new TVCardTypeConfig(aName,aParentP); else if (strucmp(aBaseType,"vcalendar")==0) return new TVCalendarTypeConfig(aName,aParentP); else #endif #ifdef TEXTTYPE_SUPPORT if (strucmp(aBaseType,"text")==0) return new TTextTypeConfig(aName,aParentP); else #endif #ifdef RAWTYPE_SUPPORT if (strucmp(aBaseType,"raw")==0) return new TRawDataTypeConfig(aName,aParentP); else #endif #ifdef DATAOBJ_SUPPORT if (strucmp(aBaseType,"dataobj")==0) return new TDataObjConfig(aName,aParentP); else #endif return NULL; // unknown basetype } // TRootConfig::newDataTypeConfig // create new profile config by name // returns NULL if none found TProfileConfig *TRootConfig::newProfileConfig(const char *aName, const char *aTypeName, TConfigElement *aParentP) { // create profiles by name #ifdef MIMEDIR_SUPPORT if (strucmp(aTypeName,"mimeprofile")==0) return new TMIMEProfileConfig(aName,aParentP); else #endif #ifdef TEXTTYPE_SUPPORT if (strucmp(aTypeName,"textprofile")==0) return new TTextProfileConfig(aName,aParentP); else #endif return NULL; // unknown profile } // TRootConfig::newProfileConfig } // namespace sysync #endif // only one of XML2GO or SDK/Plugin can be on top of customagent #ifdef XML2GO_SUPPORT #include "xml2goapiagent.h" #elif defined(SDK_SUPPORT) #include "pluginapiagent.h" #endif // ODBC can be in-between if selected #ifdef SQL_SUPPORT #include "odbcapiagent.h" #endif namespace sysync { // Create agent config - default to customImpl based agent void TRootConfig::installAgentConfig(void) { #if defined(XML2GO_SUPPORT) fAgentConfigP = new TXml2goAgentConfig(this); // xml2go (possibly on top of ODBC) #elif defined(SDK_SUPPORT) fAgentConfigP = new TPluginAgentConfig(this); // plugin/SDK (possibly on top of ODBC) #elif defined(SQL_SUPPORT) fAgentConfigP = new TOdbcAgentConfig(this); // ODBC only #else fAgentConfigP = NULL; // none #endif } // TSyncAppBase::installAgentConfig #ifndef HARDCODED_CONFIG bool TRootConfig::parseAgentConfig(const char **aAttributes, sInt32 aLine) { const char *typenam = getAttr(aAttributes,"type"); bool parseit=false; #ifdef XML2GO_SUPPORT if (strucmp(typenam,"xml2go")==0) parseit=true; #endif #ifdef SDK_SUPPORT if (strucmp(typenam,"plugin")==0) parseit=true; #endif #ifdef SQL_SUPPORT if (strucmp(typenam,"odbc")==0 || strucmp(typenam,"sql")==0) parseit=true; #endif if (parseit) { expectChildParsing(*fAgentConfigP); } return parseit; } // TRootConfig::parseAgentConfig #endif // Support for SySync Diagnostic Tool #ifdef SYSYNC_TOOL #include // special RTK instance just for translating WBXML to XML #define GET_XMLOUTINSTANCE(u) ((InstanceID_t)GET_USERDATA(u)) #define ERRCHK(CMDNAME,GENFUNC) { Ret_t r = GENFUNC; if (r!=SML_ERR_OK) CONSOLEPRINTF(("Error converting %s to XML -> XML output truncated!",CMDNAME)); } // SyncML toolkit callback implementations for sysytool debug decoder // userData must be instance_id of XML instance to generate XML message into static Ret_t sysytoolStartMessageCallback(InstanceID_t id, VoidPtr_t userData, SmlSyncHdrPtr_t pContent) { // Note: we must find the SyncML version in advance, as fSyncMLVersion is not yet valid here sInt16 hdrVers; StrToEnum(SyncMLVerDTDNames,numSyncMLVersions,hdrVers,smlPCDataToCharP(pContent->version)); smlStartMessageExt(GET_XMLOUTINSTANCE(userData),pContent,SmlVersionCodes[hdrVers]); return SML_ERR_OK; } static Ret_t sysytoolEndMessageCallback(InstanceID_t id, VoidPtr_t userData, Boolean_t final) { ERRCHK("End Of Message",smlEndMessage(GET_XMLOUTINSTANCE(userData),final)); return SML_ERR_OK; } static Ret_t sysytoolStartSyncCallback(InstanceID_t id, VoidPtr_t userData, SmlSyncPtr_t pContent) { ERRCHK("",smlStartSync(GET_XMLOUTINSTANCE(userData),pContent)); return SML_ERR_OK; } static Ret_t sysytoolEndSyncCallback(InstanceID_t id, VoidPtr_t userData) { ERRCHK("",smlEndSync(GET_XMLOUTINSTANCE(userData))); return SML_ERR_OK; } #ifdef ATOMIC_RECEIVE /* these callbacks are NOT included in the Toolkit lite version */ static Ret_t sysytoolStartAtomicCallback(InstanceID_t id, VoidPtr_t userData, SmlAtomicPtr_t pContent) { ERRCHK("",smlStartAtomic(GET_XMLOUTINSTANCE(userData),pContent)); return SML_ERR_OK; } static Ret_t sysytoolEndAtomicCallback(InstanceID_t id, VoidPtr_t userData) { ERRCHK("",smlEndAtomic(GET_XMLOUTINSTANCE(userData))); return SML_ERR_OK; } #endif #ifdef SEQUENCE_RECEIVE static Ret_t sysytoolStartSequenceCallback(InstanceID_t id, VoidPtr_t userData, SmlSequencePtr_t pContent) { ERRCHK("",smlStartSequence(GET_XMLOUTINSTANCE(userData),pContent)); return SML_ERR_OK; } static Ret_t sysytoolEndSequenceCallback(InstanceID_t id, VoidPtr_t userData) { ERRCHK("",smlEndSequence(GET_XMLOUTINSTANCE(userData))); return SML_ERR_OK; } #endif static Ret_t sysytoolAddCmdCallback(InstanceID_t id, VoidPtr_t userData, SmlAddPtr_t pContent) { ERRCHK("",smlAddCmd(GET_XMLOUTINSTANCE(userData),pContent)); return SML_ERR_OK; } static Ret_t sysytoolAlertCmdCallback(InstanceID_t id, VoidPtr_t userData, SmlAlertPtr_t pContent) { ERRCHK("",smlAlertCmd(GET_XMLOUTINSTANCE(userData),pContent)); return SML_ERR_OK; } static Ret_t sysytoolDeleteCmdCallback(InstanceID_t id, VoidPtr_t userData, SmlDeletePtr_t pContent) { ERRCHK("",smlDeleteCmd(GET_XMLOUTINSTANCE(userData),pContent)); return SML_ERR_OK; } static Ret_t sysytoolGetCmdCallback(InstanceID_t id, VoidPtr_t userData, SmlGetPtr_t pContent) { ERRCHK("",smlGetCmd(GET_XMLOUTINSTANCE(userData),pContent)); return SML_ERR_OK; } static Ret_t sysytoolPutCmdCallback(InstanceID_t id, VoidPtr_t userData, SmlPutPtr_t pContent) { ERRCHK("",smlPutCmd(GET_XMLOUTINSTANCE(userData),pContent)); return SML_ERR_OK; } #ifdef MAP_RECEIVE static Ret_t sysytoolMapCmdCallback(InstanceID_t id, VoidPtr_t userData, SmlMapPtr_t pContent) { ERRCHK("",smlMapCmd(GET_XMLOUTINSTANCE(userData),pContent)); return SML_ERR_OK; } #endif #ifdef RESULT_RECEIVE static Ret_t sysytoolResultsCmdCallback(InstanceID_t id, VoidPtr_t userData, SmlResultsPtr_t pContent) { ERRCHK("",smlResultsCmd(GET_XMLOUTINSTANCE(userData),pContent)); return SML_ERR_OK; } #endif static Ret_t sysytoolStatusCmdCallback(InstanceID_t id, VoidPtr_t userData, SmlStatusPtr_t pContent) { ERRCHK("",smlStatusCmd(GET_XMLOUTINSTANCE(userData),pContent)); return SML_ERR_OK; } static Ret_t sysytoolReplaceCmdCallback(InstanceID_t id, VoidPtr_t userData, SmlReplacePtr_t pContent) { ERRCHK("",smlReplaceCmd(GET_XMLOUTINSTANCE(userData),pContent)); return SML_ERR_OK; } #ifdef COPY_RECEIVE static Ret_t sysytoolCopyCmdCallback(InstanceID_t id, VoidPtr_t userData, SmlCopyPtr_t pContent) { ERRCHK("",smlCopyCmd(GET_XMLOUTINSTANCE(userData),pContent)); return SML_ERR_OK; } #endif static Ret_t sysytoolMoveCmdCallback(InstanceID_t id, VoidPtr_t userData, SmlMovePtr_t pContent) { ERRCHK("",smlMoveCmd(GET_XMLOUTINSTANCE(userData),pContent)); return SML_ERR_OK; } #ifdef EXEC_RECEIVE static Ret_t sysytoolExecCmdCallback(InstanceID_t id, VoidPtr_t userData, SmlExecPtr_t pContent) { ERRCHK("",smlExecCmd(GET_XMLOUTINSTANCE(userData),pContent)); return SML_ERR_OK; } #endif #ifdef SEARCH_RECEIVE static Ret_t sysytoolSearchCmdCallback(InstanceID_t id, VoidPtr_t userData, SmlSearchPtr_t pContent) { ERRCHK("",smlSearchCmd(GET_XMLOUTINSTANCE(userData),pContent)); return SML_ERR_OK; } #endif static Ret_t sysytoolHandleErrorCallback(InstanceID_t id, VoidPtr_t userData) { return SML_ERR_OK; } static Ret_t sysytoolTransmitChunkCallback(InstanceID_t id, VoidPtr_t userData) { return SML_ERR_INVALID_OPTIONS; } static const SmlCallbacks_t sysyncToolCallbacks = { /* message callbacks */ sysytoolStartMessageCallback, sysytoolEndMessageCallback, /* grouping commands */ sysytoolStartSyncCallback, sysytoolEndSyncCallback, #ifdef ATOMIC_RECEIVE /* these callbacks are NOT included in the Toolkit lite version */ sysytoolStartAtomicCallback, sysytoolEndAtomicCallback, #endif #ifdef SEQUENCE_RECEIVE sysytoolStartSequenceCallback, sysytoolEndSequenceCallback, #endif /* Sync Commands */ sysytoolAddCmdCallback, sysytoolAlertCmdCallback, sysytoolDeleteCmdCallback, sysytoolGetCmdCallback, sysytoolPutCmdCallback, #ifdef MAP_RECEIVE sysytoolMapCmdCallback, #endif #ifdef RESULT_RECEIVE sysytoolResultsCmdCallback, #endif sysytoolStatusCmdCallback, sysytoolReplaceCmdCallback, /* other commands */ #ifdef COPY_RECEIVE /* these callbacks are NOT included in the Toolkit lite version */ sysytoolCopyCmdCallback, #endif #ifdef EXEC_RECEIVE sysytoolExecCmdCallback, #endif #ifdef SEARCH_RECEIVE sysytoolSearchCmdCallback, #endif sysytoolMoveCmdCallback, /* Other Callbacks */ sysytoolHandleErrorCallback, sysytoolTransmitChunkCallback }; /* sml_callbacks struct */ // WBXML to XML conversion int wbxmlConv(int argc, const char *argv[]) { if (argc<0) { // help requested CONSOLEPRINTF((" wbxml2xml []")); CONSOLEPRINTF((" Converts to XML using SyncML-Toolkit")); CONSOLEPRINTF((" If no output file is specified, input file name with suffix '.xml' is used")); return EXIT_SUCCESS; } // check for argument if (argc<1 || argc>2) { CONSOLEPRINTF(("1 or 2 arguments required")); return EXIT_FAILURE; } // open input file FILE *inFile = fopen(argv[0],"rb"); if (!inFile) { CONSOLEPRINTF(("Error opening input file '%s', error=%d",argv[0],errno)); return EXIT_FAILURE; } // prepare a instance for decoding the WBXML InstanceID_t wbxmlInInstance; if (!getSyncAppBase()->newSmlInstance( SML_WBXML, 500*1024, // 500k should be waaaaay enough wbxmlInInstance )) { CONSOLEPRINTF(("Error creating WBXML parser")); return EXIT_FAILURE; } // install the sysytool callbacks (default are the normal appbase ones) smlSetCallbacks(wbxmlInInstance, &sysyncToolCallbacks); // prepare instance for generating XML output InstanceID_t xmlOutInstance; if (!getSyncAppBase()->newSmlInstance( SML_XML, 500*1024, // 500k should be waaaaay enough xmlOutInstance )) { CONSOLEPRINTF(("Error creating XML generator")); return EXIT_FAILURE; } // link output instance as userdata into input instance getSyncAppBase()->setSmlInstanceUserData(wbxmlInInstance, xmlOutInstance); // read WBXML original file into workspace MemPtr_t wbxmlBufP; MemSize_t wbxmlBufSiz, wbxmlDataSiz; Ret_t rc; rc = smlLockWriteBuffer(wbxmlInInstance, &wbxmlBufP, &wbxmlBufSiz); if (rc!=SML_ERR_OK) { CONSOLEPRINTF(("Error getting WBXML buffer, err=%d",rc)); return EXIT_FAILURE; } wbxmlDataSiz = fread(wbxmlBufP,1,wbxmlBufSiz,inFile); if (wbxmlDataSiz==0) { CONSOLEPRINTF(("No data in WBXML input file or error, err=%d",errno)); return EXIT_FAILURE; } fclose(inFile); CONSOLEPRINTF(("Read %ld bytes from WBXML input file '%s'",wbxmlDataSiz,argv[0])); smlUnlockWriteBuffer(wbxmlInInstance,wbxmlDataSiz); // decode do { rc = smlProcessData(wbxmlInInstance, SML_NEXT_COMMAND); } while (rc==SML_ERR_CONTINUE); if (rc!=SML_ERR_OK) { CONSOLEPRINTF(("Error while decoding WBXML document, rc=%d",rc)); } else { CONSOLEPRINTF(("Successfully completed decoding WBXML document")); } // write to output file // - determine name string outFileName; outFileName = argv[0]; if (argc>1) outFileName = argv[1]; else outFileName += ".xml"; // save output FILE *outFile = fopen(outFileName.c_str(),"w"); if (!outFile) { CONSOLEPRINTF(("Error opening output file '%s', error=%d",outFileName.c_str(),errno)); return EXIT_FAILURE; } MemPtr_t xmlBufP; MemSize_t xmlDataSiz; rc = smlLockReadBuffer(xmlOutInstance,&xmlBufP,&xmlDataSiz); if (rc!=SML_ERR_OK) { CONSOLEPRINTF(("Error reading decoded XML from converter WBXML document, rc=%d",rc)); return EXIT_FAILURE; } CONSOLEPRINTF(("Writing %ld bytes of XML translation to '%s'",xmlDataSiz,outFileName.c_str())); fwrite(xmlBufP,1,xmlDataSiz,outFile); fclose(outFile); // done return EXIT_SUCCESS; } // wbxmlConv #endif // SYSYNC_TOOL } // namespace sysync // eof libsynthesis-3.4.0.47.1/src/sysync/syncappbase.h000077500000000000000000000627531226375725500214640ustar00rootroot00000000000000/* * TSyncAppBase * Base class for SySync applications, is supposed to exist * as singular object only, manages "global" things such * as config reading and session dispatching * * Copyright (c) 2002-2011 by Synthesis AG + plan44.ch */ #ifndef SYNCAPPBASE_H #define SYNCAPPBASE_H #include "configelement.h" #include "profiling.h" #include "debuglogger.h" #include "syncitemtype.h" #include "engineinterface.h" #include "global_progress.h" // expat if not hardcoded config #ifndef HARDCODED_CONFIG # ifdef HAVE_EXPAT #include # elif defined(HAVE_SYS_XMLTOK) #include # else /* HAVE_BUILTIN_XMLTOK */ #include "xmlparse.h" # endif #endif namespace sysync { #ifdef SYSYNC_TOOL // WBXML to XML conversion int wbxmlConv(int argc, const char *argv[]); #endif // XML config doc name (can be overridden in target_options if needed) #ifndef XMLCONFIG_DOCNAME #define XMLCONFIG_DOCNAME "sysync_config" #endif #ifndef XMLCONFIG_DOCVERSION #define XMLCONFIG_DOCVERSION "1.0" #endif // progress event posting macros // Note: engine libraries only have session level progress events #ifdef PROGRESS_EVENTS #ifndef ENGINE_LIBRARY #define APP_PROGRESS_EVENT(a,e,d,x,y,z) a->NotifyAppProgressEvent(e,d,x,y,z) #endif #define SESSION_PROGRESS_EVENT(s,e,d,x,y,z) s->NotifySessionProgressEvent(e,d,x,y,z) #define DB_PROGRESS_EVENT(d,e,x,y,z) d->getSession()->NotifySessionProgressEvent(e,d->getDSConfig(),x,y,z) #else #ifndef ENGINE_LIBRARY #define APP_PROGRESS_EVENT(a,e,d,x,y,z) true #endif #define SESSION_PROGRESS_EVENT(s,e,d,x,y,z) true #define DB_PROGRESS_EVENT(s,e,x,y,z) true #endif // non-class print to console (#ifdef CONSOLEINFO) extern "C" void ConsolePrintf(const char *text, ...); extern "C" void ConsolePuts(const char *text); // direct print to app's console, whatever that is // NOTE: implemented in derived xxxx_app.cpp void AppConsolePuts(const char *aText); #ifndef HARDCODED_CONFIG // debug option (combination) names const sInt16 numDebugOptions = 37; extern const char * const debugOptionNames[numDebugOptions]; extern const uInt32 debugOptionMasks[numDebugOptions]; // non-class print to report config errors void ConferrPrintf(const char *text, ...); #endif // provides additional context info void writeDebugContextInfo(FILE *logfile); extern "C" { /* moved to sysync_debug.h to make them accessible by just importing it // non-class debug output functions void DebugVPrintf(const char *format, va_list args); void DebugPrintf(const char *text, ...); void DebugPuts(const char *text); uInt16 getDebugMask(void); */ // entry point for XPT part of SyncML-Toolkit with // #define TRACE_TO_STDOUT // functionally equal to DebugPrintf void localOutput(const char *aFormat, va_list aArgs); #ifdef NOWSM // entry points for SML part of SyncML-Toolkit void smlLibPrint(const char *text, ...); void smlLibVprintf(const char *format, va_list va); #endif } // static routines for accessing appbase logs from UI_Call_In/DB_Callback #ifdef SYDEBUG extern "C" void AppBaseLogDebugPuts(void *aCallbackRef, const char *aText); extern "C" void AppBaseLogDebugExotic(void *aCallbackRef, const char *aText); extern "C" void AppBaseLogDebugBlock(void *aCallbackRef, const char *aTag, const char *aDesc, const char *aAttrText ); extern "C" void AppBaseLogDebugEndBlock(void *aCallbackRef, const char *aTag); extern "C" void AppBaseLogDebugEndThread(void *aCallbackRef); #endif #ifndef HARDCODED_CONFIG extern const char * const SyncMLEncodingNames[]; #endif extern const char * const SyncMLEncodingMIMENames[]; // forward declarations class TSyncSession; class TSyncAppBase; class TAgentConfig; class TDatatypesConfig; class TSyncDataStore; class TCommConfig; class TDataTypeConfig; class TSyncItemType; class TRootConfig; #ifdef SCRIPT_SUPPORT class TScriptConfig; #endif // prototype for dispatcher creation function // Note: This function must be implemented in the derived TSyncAppBase // class' .cpp file. This allows different SySync Apps to be // implemented by simply including the appropriate TSyncAppBase // derivate. THIS FUNCTION IS NOT IMPLEMENTED in SyncAppBase.cpp! TSyncAppBase *newSyncAppBase(void); #ifdef ENGINEINTERFACE_SUPPORT // only as an intermediate legacy solution we still grant appBase direct access #ifdef DIRECT_APPBASE_GLOBALACCESS // get access to Sync app base object, creates new one if none exists TSyncAppBase *getSyncAppBase(void); // get access to existing Sync app base object, NULL if none TSyncAppBase *getExistingSyncAppBase(void); // We also need a way to access the engineInterface if we are in old AppBase code TEngineInterface *getEngineInterface(void); // free Sync app base object - which means that engineInterface is deleted void freeSyncAppBase(void); #endif #else // get access to Sync app base object, creates new one if none exists TSyncAppBase *getSyncAppBase(void); // get access to existing Sync app base object, NULL if none TSyncAppBase *getExistingSyncAppBase(void); // free Sync app base object void freeSyncAppBase(void); #endif // communication (transport) config object class TCommConfig : public TConfigElement { private: typedef TConfigElement inherited; public: TCommConfig(const char *aElementName, TConfigElement *aParentElementP) : TConfigElement(aElementName,aParentElementP) {}; // nothing special so far }; // TCommConfig /* %%% this was a useless intermediate class. We now call the unilib config TAgentConfig (union of TClientConfig and TServerConfig) // agent configuration (an agent is a server or a client) class TAgentConfig : public TConfigElement { typedef TConfigElement inherited; public: TAgentConfig(const char *aElementName, TConfigElement *aParentElementP) : TConfigElement(aElementName,aParentElementP) {}; // - MUST be called after creating config to load (or pre-load) variable parts of config // such as binfile profiles. If aDoLoose==false, situations, where existing config // is detected but cannot be re-used will return an error. With aDoLoose==true, config // files etc. are created even if it means a loss of data. virtual localstatus loadVarConfig(bool aDoLoose=false) { return LOCERR_OK; } }; // TAgentConfig */ // single data type configuration abstract class // Note: derived instances are created using the global newDataTypeConfig() function class TDataTypeConfig : public TConfigElement { typedef TConfigElement inherited; public: TDataTypeConfig(const char *aElementName, TConfigElement *aParentElementP) : TConfigElement(aElementName,aParentElementP) {}; // properties // - type name string string fTypeName; // - type version string string fTypeVersion; #ifdef ZIPPED_BINDATA_SUPPORT // if flag is set, payload data will be bool fZippedBindata; sInt16 fZipCompressionLevel; #endif // if flag is set, we can use binary blocks within text (how this is done depends on actual type) bool fBinaryParts; // Unicode payload settings bool fUseUTF16; // 16-bit unicode rather than UTF-8 bool fMSBFirst; // byte order for unicode // create Sync Item Type of appropriate type from config virtual TSyncItemType *newSyncItemType(TSyncSession *aSessionP, TSyncDataStore *aDatastoreP) = 0; // get a descriptor for selecting a variant of a datatype (if any), NULL=no variant with this name virtual TTypeVariantDescriptor getVariantDescriptor(const char *aVariantName) { return NULL; }; protected: #ifdef CONFIGURABLE_TYPE_SUPPORT // check config elements virtual bool localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine); virtual void localResolve(bool aLastPass); #endif virtual void clear(); }; // TDataTypeConfig // datatypes list typedef std::list TDataTypesList; // datatypes registry configuration class TDatatypesConfig : public TConfigElement { typedef TConfigElement inherited; public: TDatatypesConfig(const char *aElementName, TConfigElement *aParentElementP); virtual ~TDatatypesConfig(); // properties // - list of registered data types TDataTypesList fDataTypesList; // public methods TDataTypeConfig *getDataType(const char *aName); protected: #ifdef CONFIGURABLE_TYPE_SUPPORT // check config elements virtual bool localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine); #endif // resolve is needed also for hardcoded types! virtual void localResolve(bool aLastPass); public: virtual void clear(); }; // TDatatypesConfig #ifdef SYDEBUG // debug Config element class TDebugConfig : public TConfigElement { typedef TConfigElement inherited; public: // create root config TDebugConfig(const char *aElementName, TConfigElement *aParentElementP); virtual void clear(void); // the debug info path string fDebugInfoPath; // global template for TDebugLogger options TDbgOptions fGlobalDbgLoggerOptions; TDbgOptions fSessionDbgLoggerOptions; // other global debug options // - if <>0 (and #defined SYDEBUG), debug output is generated, value is used as mask uInt32 fDebug; // if set (and #defined MSGDUMP), messages sent and received are logged; bool fMsgDump; // if set, communication will be translated to XML and logged bool fXMLtranslate; // if set (and #defined SIMMSGREAD), simulated input with "i_" prefixed incoming messages are supported bool fSimMsgRead; // if set, session debug logs are enabled by default (but can be disabled by session later) bool fSessionDebugLogs; // if set, global log file is enabled bool fGlobalDebugLogs; // if set, only one single global log file is created (instead of one for every start of the app) bool fSingleGlobLog; // if set, only one single session log file is created (instead of one for every session) bool fSingleSessionLog; // if set, ISO8601 timestamp will be added as part of the session log filename bool fTimedSessionLogNames; // if set, session logs will be embedded into global log. Note: only reliably works in unthreaded environments bool fLogSessionsToGlobal; protected: #ifndef HARDCODED_CONFIG // parsing virtual bool localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine); #endif // resolving (finishing) virtual void localResolve(bool aLastPass); private: uInt32 str2DebugMask(const char **aAttributes); }; // TDebugConfig #endif class TProfileConfig; // forward class TAgentConfig; // forward // root Config element class TRootConfig : public TRootConfigElement, noncopyable { typedef TRootConfigElement inherited; public: // create root config TRootConfig(TSyncAppBase *aSyncAppBaseP); virtual ~TRootConfig(); // - factory methods for main config aspects virtual void installCommConfig(void) = 0; virtual void installDatatypesConfig(void); virtual void installAgentConfig(void); // - parsing of main config aspects #ifndef HARDCODED_CONFIG virtual bool parseCommConfig(const char **aAttributes, sInt32 aLine) = 0; virtual bool parseDatatypesConfig(const char **aAttributes, sInt32 aLine); virtual bool parseAgentConfig(const char **aAttributes, sInt32 aLine); #endif #ifdef CONFIGURABLE_TYPE_SUPPORT // - profile configs (MIME profiles, text profiles, etc.) virtual TProfileConfig *newProfileConfig(const char *aName, const char *aTypeName, TConfigElement *aParentP); virtual TDataTypeConfig *newDataTypeConfig(const char *aName, const char *aBaseType, TConfigElement *aParentP); #endif // - hardcoded types #ifdef HARDCODED_TYPE_SUPPORT virtual void createHardcodedTypes(TDatatypesConfig *aDatatypesConfig) = 0; #ifndef NO_REMOTE_RULES #error "%%%% warning: hardcoded type with remoterule support is not tested yet. Should work with old addProperty() calls propertyGroup is 0 by default which should disable grouping" #endif #endif // - hardcoded other config #ifdef HARDCODED_CONFIG // setup config elements (must be implemented in derived RootConfig class) virtual localstatus createHardcodedConfig(void) = 0; #endif // Clear config virtual void clear(void); // save app state (such as settings in datastore configs etc.) virtual void saveAppState(void); // MUST be called after creating config to load (or pre-load) variable parts of config // such as binfile profiles. If aDoLoose==false, situations, where existing config // is detected but cannot be re-used will return an error. With aDoLoose==true, config // files etc. are created even if it means a loss of data. virtual localstatus loadVarConfig(bool aDoLoose=false); // date when config has last changed lineartime_t fConfigDate; #ifndef HARDCODED_CONFIG // string for identifying config file in logs string fConfigIDString; #endif // flag to suppress sending devinf to clients that do not request it bool fNeverPutDevinf; // transport/environment config TCommConfig *fCommConfigP; // Agent (Server or Client session) config TAgentConfig *fAgentConfigP; // datatypes config TDatatypesConfig *fDatatypesConfigP; #ifdef SCRIPT_SUPPORT // global script definitions TScriptConfig *fScriptConfigP; #endif // embedded debug config #ifdef SYDEBUG TDebugConfig fDebugConfig; #endif #ifdef CUSTOMIZABLE_DEVICES_LIMIT // active session limit sInt32 fConcurrentDeviceLimit; #endif #ifdef ENGINEINTERFACE_SUPPORT // for engine libraries, MAN/MOD/HwV/DevTyp can be configured string fMan; string fMod; string fHwV; string fFwV; string fDevTyp; #endif #if defined(SYSER_REGISTRATION) && (!defined(HARDCODED_CONFIG) || defined(ENGINEINTERFACE_SUPPORT)) // licensing via config file or engine interface is possible string fLicenseName; string fLicenseCode; #endif // SyncML encoder/decoder parameters uInt32 fLocalMaxMsgSize; // my own maxmsgsize uInt32 fLocalMaxObjSize; // my own maxobjsize, if 0, large object support is disabled // - System time context (usually TCTX_SYSTEM, but might be explicitly set if system TZ info is not available) timecontext_t fSystemTimeContext; protected: #ifndef HARDCODED_CONFIG // parsing virtual bool localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine); #endif // resolving (finishing) virtual void localResolve(bool aLastPass); private: }; // TRootConfig } // namespace sysync // now include rest (some of the config classes are // required by these includes already) #include "sysync.h" #include "syncsession.h" namespace sysync { /* TSyncAppBase is a global, singular object which is instantiated ONCE * per application. */ class TSyncAppBase : noncopyable { friend class TDebugConfig; public: // constructors/destructors TSyncAppBase(); virtual ~TSyncAppBase(); // request count sInt32 requestCount(void) { return fRequestCount; }; sInt32 incRequestCount(void) { return ++fRequestCount; }; // config access TRootConfig *getRootConfig(void) { return fConfigP; }; // - combine URI and session ID to make a RespURI according to transport virtual void generateRespURI( string & /* aRespURI */, cAppCharP /* aLocalURI */, cAppCharP /* aSessionID */ ) { /* nop, no RespURI */ }; #ifdef HARDCODED_CONFIG // create hardcoded config (root config element knows how) localstatus initHardcodedConfig(void); #else // config error printing virtual void ConferrPuts(const char *msg); void ConferrPrintf(const char *text, ...); // config reading localstatus readXMLConfigStream(TXMLConfigReadFunc aReaderFunc, void *aContext); virtual localstatus configStatus(void) { if (!fConfigP) return LOCERR_NOCFG; return fConfigP->getFatalError(); }; #ifdef CONSTANTXML_CONFIG localstatus readXMLConfigConstant(const char *aConstantXML); #endif localstatus readXMLConfigCFile(FILE *aCfgFile); localstatus readXMLConfigFile(cAppCharP aFilePath); #ifndef ENGINE_LIBRARY localstatus readXMLConfigStandard(const char *aConfigFileName, bool aOnlyGlobal, bool aAbsolute=false); #endif #endif // HARDCODED_CONFIG #ifdef APP_CAN_EXPIRE localstatus fAppExpiryStatus; // LOCERR_OK = ok, LOCERR_BADREG, LOCERR_TOONEW or LOCERR_EXPIRED = bad #endif #ifndef HARDCODED_CONFIG // access to config variables bool getConfigVar(cAppCharP aVarName, string &aValue); bool setConfigVar(cAppCharP aVarName, cAppCharP aNewValue); bool unsetConfigVar(cAppCharP aVarName); bool expandConfigVars(string &aString, sInt8 aCfgVarExp, TConfigElement *aCfgElement=NULL, cAppCharP aElementName=NULL); #endif #ifdef SYDEBUG // path where config came from string fConfigFilePath; // access to logging for session TDebugLogger *getDbgLogger(void) { return &fAppLogger; }; uInt32 getDbgMask(void) { return fAppLogger.getMask(); }; // factory function for debug output channel #ifndef NO_C_FILES virtual TDbgOut *newDbgOutputter(bool aGlobal) { return new TStdFileDbgOut; }; #else virtual TDbgOut *newDbgOutputter(bool aGlobal) = 0; #endif #endif // SYDEBUG // app time zones GZones *getAppZones(void) { return &fAppZones; }; // Profiling TP_DEFINFO(fTPInfo) // Handle exception happening while decoding commands for a session virtual Ret_t HandleDecodingException(TSyncSession *aSessionP, const char *aRoutine, exception *aExceptionP=NULL) = 0; // access to SyncML toolkit bool newSmlInstance(SmlEncoding_t aEncoding, sInt32 aWorkspaceMem, InstanceID_t &aInstanceID); Ret_t getSmlInstanceUserData(InstanceID_t aInstanceID, void **aUserDataPP); Ret_t setSmlInstanceUserData(InstanceID_t aInstanceID, void *aUserDataP); void freeSmlInstance(InstanceID_t aInstance); // determine encoding from beginning of SyncML message data static SmlEncoding_t encodingFromData(cAppPointer aData, memSize aDataSize); // determine encoding from Content-Type: header value static SmlEncoding_t encodingFromContentType(cAppCharP aTypeString); // virtual handlers for SyncML toolkit callbacks, must be separately derived for server/client cases // - Start/End Message: derived method in server case actually creates session virtual Ret_t StartMessage( InstanceID_t aSmlWorkspaceID, // SyncML toolkit workspace instance ID VoidPtr_t aUserData, // user data, should be NULL (as StartMessage is responsible for setting userdata) SmlSyncHdrPtr_t aContentP // SyncML tookit's decoded form of the element ) = 0; // test if message buffering is available virtual bool canBufferRetryAnswer(void) { return false; }; // must be set in server bases // non-virtual handlers, are always called with userData containing valid session pointer // - end of message Ret_t EndMessage(VoidPtr_t userData, Boolean_t aFinal); // - grouping commands Ret_t StartSync(VoidPtr_t userData, SmlSyncPtr_t aContentP); Ret_t EndSync(VoidPtr_t userData); Ret_t StartSequence(VoidPtr_t userData, SmlSequencePtr_t aContentP); Ret_t EndSequence(VoidPtr_t userData); Ret_t StartAtomic(VoidPtr_t userData, SmlAtomicPtr_t aContentP); Ret_t EndAtomic(VoidPtr_t userData); // - sync commands Ret_t AddCmd(VoidPtr_t userData, SmlAddPtr_t aContentP); Ret_t AlertCmd(VoidPtr_t userData, SmlAlertPtr_t aContentP); Ret_t DeleteCmd(VoidPtr_t userData, SmlDeletePtr_t aContentP); Ret_t GetCmd(VoidPtr_t userData, SmlGetPtr_t aContentP); Ret_t PutCmd(VoidPtr_t userData, SmlPutPtr_t aContentP); #ifdef MAP_RECEIVE Ret_t MapCmd(VoidPtr_t userData, SmlMapPtr_t aContentP); #endif #ifdef RESULT_RECEIVE Ret_t ResultsCmd(VoidPtr_t userData, SmlResultsPtr_t aContentP); #endif Ret_t StatusCmd(VoidPtr_t userData, SmlStatusPtr_t aContentP); Ret_t ReplaceCmd(VoidPtr_t userData, SmlReplacePtr_t aContentP); Ret_t CopyCmd(VoidPtr_t userData, SmlCopyPtr_t aContentP); Ret_t MoveCmd(VoidPtr_t userData, SmlMovePtr_t aContentP); // - error handling Ret_t HandleError(VoidPtr_t userData); Ret_t DummyHandler(VoidPtr_t userData, const char* msg); // flag to indicated deletion in progess (blocking virtuals for debug info) #ifdef SYSER_REGISTRATION // somewhat scattered within object to make reverse engineering harder uInt16 fRegProductCode; // updated by checkRegInfo uInt8 fRegLicenseType; // updated by checkRegInfo #endif // convenience version for getting time lineartime_t getSystemNowAs(timecontext_t aContext) { return sysync::getSystemNowAs(aContext,getAppZones()); }; protected: // Server or client bool fIsServer; // Application custom time zones GZones fAppZones; // Destruction flag bool fDeleting; // config TRootConfig *fConfigP; #ifndef HARDCODED_CONFIG // user-defined config variables TStringToStringMap fConfigVars; #endif // request count sInt32 fRequestCount; // count of requests public: // this is called to control behaviour for builds that can be client OR server bool isServer(void) { return fIsServer; }; #ifdef SYSER_REGISTRATION // somewhat scattered within object to make reverse engineering harder bool fRegOK; // updated by checkRegInfo, used to disable hard-coded-expiry #endif #if defined(PROGRESS_EVENTS) && !defined(ENGINE_LIBRARY) // callback for progress events TProgressEventFunc fProgressEventFunc; void *fProgressEventContext; // event generator bool NotifyAppProgressEvent( TProgressEventType aEventType, TLocalDSConfig *aDatastoreID=NULL, sInt32 aExtra1=0, sInt32 aExtra2=0, sInt32 aExtra3=0 ); #endif // non-engine progress events #ifdef ENGINEINTERFACE_SUPPORT // owning engineInterface TEngineInterface *fEngineInterfaceP; #else // "master" pointer, to allow callbacks to refer to "master" object which creates appbase void *fMasterPointer; #endif // save app state (such as settings in datastore configs etc.) virtual void saveAppState(void); public: // - inter-module context (needed for pooling global per-process ressources like Java VM) CContext fApiInterModuleContext; #ifdef SYSER_REGISTRATION // somewhat scattered within object to make reverse engineering harder uInt8 fRegProductFlags; // updated by checkRegInfo uInt16 fRegQuantity; // updated by checkRegInfo sInt16 fDaysLeft; // updated by appEnableStatus() and/or checkRegInfo(). 0=expired, -1=not limited #endif // identification // - identification of the application (constant for monolithic builds, configurable for engine library) string getManufacturer(); string getModel(); string getHardwareVersion(); string getFirmwareVersion(); // - device type, only used for clients string getDevTyp(); // - device ID, can be customized via "customdeviceid" config var bool getMyDeviceID(string &devid); // - hardwired information (cannot change, always identifying Synthesis engine and its version cAppCharP getOEM(void) { return SYSYNC_OEM; } // hardwired, not configurable in target options cAppCharP getSoftwareVersion(void) { return SYSYNC_FULL_VERSION_STRING; } // hardwired to real version number // expiry checking #ifdef EXPIRES_AFTER_DATE sInt32 fScrambledNow; // scrambled now, set at syncappbase creation #endif #if defined(APP_CAN_EXPIRE) || defined(SYSER_REGISTRATION) // check if app is enabled localstatus appEnableStatus(void); // get registration information to display localstatus getAppEnableInfo(sInt16 &aDaysLeft, string *aRegnameP=NULL, string *aRegInternalsP=NULL); #else localstatus appEnableStatus(void) { return LOCERR_OK; } // app is always enabled //#warning "WARNING: non-expiring app - is this intended?" #endif #ifdef APP_CAN_EXPIRE // updates fAppExpiryStatus according to registration and hardcoded expiry date void updateAppExpiry(void); #endif #ifdef SYSER_REGISTRATION // updated by checkRegInfo uInt8 fRegDuration; uInt8 fRelDuration; uInt32 fLicCRC; #if defined(EXPIRES_AFTER_DAYS) && defined(ENGINEINTERFACE_SUPPORT) lineardate_t fFirstUseDate; uInt32 fFirstUseVers; #endif // checks if registered (must be implemented in base class) // returns LOCERR_EXPIRED, LOCERR_TOONEW or LOCERR_BADREG if not registered correctly virtual localstatus isRegistered(void); // checks and saves registration info passed. Returns true if registration is ok // (note: derived class must implement saving) virtual localstatus checkAndSaveRegInfo(const char *aRegKey, const char *aRegCode) { return LOCERR_BADREG; } /* no implementation */ // checks registration code for CRC ok and compare with // predefined constants for product code etc. virtual localstatus checkRegInfo(const char *aRegKey, const char *aRegCode, bool aMangled=false); // extended license type depending check (such as activation) virtual bool checkLicenseType(uInt16 aLicenseType) { return aLicenseType==0; }; // defaults to ok for type==0 // checks if current license is properly activated localstatus checkLicenseActivation(lineardate_t &aLastcheck, uInt32 &aLastcrc); // scan for license restrictions static const char * getLicenseRestriction(const char *aInfo, string &aID, string &aVal); // get registration string virtual void getRegString(string &aString); #endif // - check for Feature enabled virtual bool isFeatureEnabled(uInt16 aFeatureNo) { return false; /* none enabled by default */ }; #ifdef CONCURRENT_DEVICES_LIMIT // check if session count is exceeded void checkSessionCount(sInt32 aSessionCount, TSyncSession *aSessionP); #endif #ifdef EXPIRES_AFTER_DAYS // gets information of first use for a given variant of the software. virtual void getFirstUseInfo(uInt8 aVariant, lineardate_t &aFirstUseDate, uInt32 &aFirstUseVers); // update first use info to allow for repeated eval when user installs an all-new version bool updateFirstUseInfo(lineardate_t &aFirstUseDate, uInt32 &aFirstUseVers); #endif private: // to be executed after reading config stream or hard-coded config localstatus finishConfig(); // debug logging #ifdef SYDEBUG TDebugLogger fAppLogger; // the logger #endif }; // TSyncAppBase } // namespace sysync #endif // SYNCAPPBASE_H // eof libsynthesis-3.4.0.47.1/src/sysync/syncclientbase.cpp000066400000000000000000000335211226375725500225010ustar00rootroot00000000000000/* * TSyncClientBase * Abstract baseclass for client * * Copyright (c) 2002-2011 by Synthesis AG + plan44.ch * */ #include "prefix_file.h" #include "sysync.h" #include "syncclientbase.h" #include "syncagent.h" namespace sysync { #ifdef ENGINEINTERFACE_SUPPORT // Support for EngineModule common interface // ========================================= #ifndef ENGINE_LIBRARY #warning "using ENGINEINTERFACE_SUPPORT in old-style appbase-rooted environment. Should be converted to real engine usage later" // Engine factory function for non-Library case ENGINE_IF_CLASS *newClientEngine(void) { // For real engine based targets, newClientEngine must create a target-specific derivate // of the client engine, which then has a suitable newSyncAppBase() method to create the // appBase. For old-style environment, a generic TClientEngineInterface is ok, as this // in turn calls the global newSyncAppBase() which then returns the appropriate // target specific appBase. return new TClientEngineInterface; } // newClientEngine /// @brief returns a new application base. TSyncAppBase *TClientEngineInterface::newSyncAppBase(void) { // For not really engine based targets, the appbase factory function is // a global routine (for real engine targets, it is a true virtual of // the engineInterface, implemented in the target's leaf engineInterface derivate. // - for now, use the global appBase creator routine return sysync::newSyncAppBase(); // use global factory function } // TClientEngineInterface::newSyncAppBase #else // EngineInterface methods // ----------------------- /// @brief Open a session /// @param aNewSessionH[out] receives session handle for all session execution calls /// @param aSelector[in] selector, depending on session type. For multi-profile clients: profile ID to use /// @param aSessionName[in] a text name/id to identify a session, useage depending on session type. /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure TSyError TClientEngineInterface::OpenSessionInternal(SessionH &aNewSessionH, uInt32 aSelector, cAppCharP aSessionName) { TSyncClientBase *clientBaseP = static_cast(getSyncAppBase()); localstatus sta = LOCERR_WRONGUSAGE; // No client session may exist when opening a new one if (clientBaseP->fClientSessionP) return LOCERR_WRONGUSAGE; // check type of session if (aSelector == SESSIONSEL_DBAPI_TUNNEL) { // initiate a DBAPI tunnel session. #ifdef DBAPI_TUNNEL_SUPPORT // Create a new session, sessionName selects datastore sta = clientBaseP->CreateTunnelSession(aSessionName); if (sta==LOCERR_OK) { // return the session pointer as handle aNewSessionH=(SessionH)clientBaseP->fClientSessionP; } else { // error: make sure it is deleted in case it was half-constructed if (clientBaseP->fClientSessionP) { delete clientBaseP->fClientSessionP; clientBaseP->fClientSessionP = NULL; } } #else return LOCERR_NOTIMP; // tunnel not implemented #endif } else if ((aSelector & ~SESSIONSEL_PROFILEID_MASK) == SESSIONSEL_CLIENT_AS_CHECK) { // special autosync-checking "session" #ifdef AUTOSYNC_SUPPORT // %%% tbi return LOCERR_NOTIMP; // %%% not implemented for now #else return LOCERR_NOTIMP; // no Autosync in this engine #endif } else { // Create a new session sta = clientBaseP->CreateSession(); // Pass profile ID if (sta==LOCERR_OK) { clientBaseP->fClientSessionP->SetProfileSelector(aSelector & SESSIONSEL_PROFILEID_MASK); // return the session pointer as handle aNewSessionH=(SessionH)clientBaseP->fClientSessionP; } } // done return sta; } // TClientEngineInterface::OpenSessionInternal /// @brief open session specific runtime parameter/settings key /// @note key handle obtained with this call must be closed BEFORE SESSION IS CLOSED! /// @param aNewKeyH[out] receives the opened key's handle on success /// @param aSessionH[in] session handle obtained with OpenSession /// @param aMode[in] the open mode /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure TSyError TClientEngineInterface::OpenSessionKey(SessionH aSessionH, KeyH &aNewKeyH, uInt16 aMode) { // %%% add autosync-check session case here // must be current session's handle (for now - however // future engines might allow multiple concurrent client sessions) if (aSessionH != (SessionH)static_cast(getSyncAppBase())->fClientSessionP) return LOCERR_WRONGUSAGE; // something wrong with that handle // get client session pointer TSyncAgent *clientSessionP = static_cast((void *)aSessionH); // create settings key for the session aNewKeyH = (KeyH)clientSessionP->newSessionKey(this); // done return LOCERR_OK; } // TClientEngineInterface::OpenSessionKey /// @brief Close a session /// @note It depends on session type if this also destroys the session or if it may persist and can be re-opened. /// @param aSessionH[in] session handle obtained with OpenSession /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure TSyError TClientEngineInterface::CloseSession(SessionH aSessionH) { TSyncClientBase *clientBaseP = static_cast(getSyncAppBase()); // %%% add autosync-check session case here // Nothing to do if no client session exists or none is requested for closing if (!clientBaseP->fClientSessionP || !aSessionH) return LOCERR_OK; // nop // must be current session's handle if (aSessionH != (SessionH)clientBaseP->fClientSessionP) return LOCERR_WRONGUSAGE; // something wrong with that handle // terminate running session (if any) clientBaseP->KillClientSession(LOCERR_USERABORT); // closing while session in progress counts as user abort // done return LOCERR_OK; } // TClientEngineInterface::CloseSession /// @brief Executes next step of the session /// @param aSessionH[in] session handle obtained with OpenSession /// @param aStepCmd[in/out] step command (STEPCMD_xxx): /// - tells caller to send or receive data or end the session etc. /// - instructs engine to suspend or abort the session etc. /// @param aInfoP[in] pointer to a TEngineProgressInfo structure, NULL if no progress info needed /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure TSyError TClientEngineInterface::SessionStep(SessionH aSessionH, uInt16 &aStepCmd, TEngineProgressInfo *aInfoP) { TSyncClientBase *clientBaseP = static_cast(getSyncAppBase()); // %%% add autosync-check session case here // must be current session's handle (for now - however // future engines might allow multiple concurrent client sessions) if (aSessionH != (SessionH)clientBaseP->fClientSessionP) return LOCERR_WRONGUSAGE; // something wrong with that handle // get client session pointer TSyncAgent *clientSessionP = static_cast((void *)aSessionH); // let client session handle it return clientSessionP->SessionStep(aStepCmd, aInfoP); } // TClientEngineInterface::SessionStep /// @brief returns the SML instance for a given session handle /// (internal helper to allow TEngineInterface to provide the access to the SyncML buffer) InstanceID_t TClientEngineInterface::getSmlInstanceOfSession(SessionH aSessionH) { TSyncClientBase *clientBaseP = static_cast(getSyncAppBase()); // %%% add autosync-check session case here // must be current session's handle (for now - however // future engines might allow multiple concurrent client sessions) if (aSessionH != (SessionH)clientBaseP->fClientSessionP) return 0; // something wrong with session handle -> no SML instance // get client session pointer TSyncAgent *clientSessionP = static_cast((void *)aSessionH); // return SML instance associated with that session return clientSessionP->getSmlWorkspaceID(); } // TClientEngineInterface::getSmlInstanceOfSession TSyError TClientEngineInterface::debugPuts(cAppCharP aFile, int aLine, cAppCharP aFunction, int aDbgLevel, cAppCharP aPrefix, cAppCharP aText) { #if defined(SYDEBUG) static_cast(getSyncAppBase())->getDbgLogger()->DebugPuts(TDBG_LOCATION_ARGS(aFunction, aFile, aLine /* aPrefix */) aDbgLevel, aText); return 0; #else return LOCERR_NOTIMP; #endif } #endif // ENGINE_LIBRARY #endif // ENGINEINTERFACE_SUPPORT // TSyncClientBase // =============== #ifdef DIRECT_APPBASE_GLOBALACCESS // Only for old-style targets that still use a global anchor TSyncClientBase *getClientBase(void) { return static_cast(getSyncAppBase()); } // getClientBase #endif // DIRECT_APPBASE_GLOBALACCESS // constructor TSyncClientBase::TSyncClientBase() : TSyncAppBase(), fClientSessionP(NULL) { // this is a client engine fIsServer = false; } // TSyncClientBase::TSyncClientBase // destructor TSyncClientBase::~TSyncClientBase() { // kill session, if any KillClientSession(); fDeleting=true; // flag deletion to block calling critical (virtual) methods // delete client session, if any SYSYNC_TRY { // %%%%%%%% tdb... } SYSYNC_CATCH (...) SYSYNC_ENDCATCH } // TSyncClientBase::~TSyncClientBase // Called from SyncML toolkit when a new SyncML message arrives // - dispatches to session's StartMessage Ret_t TSyncClientBase::StartMessage( InstanceID_t aSmlWorkspaceID, // SyncML toolkit workspace instance ID VoidPtr_t aUserData, // pointer to a TSyncAgent descendant SmlSyncHdrPtr_t aContentP // SyncML tookit's decoded form of the element ) { TSyncSession *sessionP = static_cast(aUserData); // the client session SYSYNC_TRY { // let session handle details of StartMessage callback return sessionP->StartMessage(aContentP); } SYSYNC_CATCH (exception &e) return HandleDecodingException(sessionP,"StartMessage",&e); SYSYNC_ENDCATCH SYSYNC_CATCH (...) return HandleDecodingException(sessionP,"StartMessage",NULL); SYSYNC_ENDCATCH } // TSyncClientBase::StartMessage #ifdef DBAPI_TUNNEL_SUPPORT // - create a new client DBApi tunnel session localstatus TSyncClientBase::CreateTunnelSession(cAppCharP aDatastoreName) { localstatus sta; // create an ordinary session sta = CreateSession(); if (sta==LOCERR_OK) { // determine which datastore to address sta = fClientSessionP->InitializeTunnelSession(aDatastoreName); } // done return sta; } // TSyncClientBase::CreateTunnelSession #endif // DBAPI_TUNNEL_SUPPORT // create a new client session localstatus TSyncClientBase::CreateSession(void) { // remove any possibly existing old session first KillClientSession(); // get config //TAgentConfig *configP = static_cast(getSyncAppBase()->getRootConfig()->fAgentConfigP); // create a new client session of appropriate type // - use current time as session ID (only for logging purposes) string s; LONGLONGTOSTR(s,PRINTF_LLD_ARG(getSystemNowAs(TCTX_UTC))); fClientSessionP = static_cast(fConfigP->fAgentConfigP)->CreateClientSession(s.c_str()); if (!fClientSessionP) return LOCERR_UNDEFINED; // check expiry here return appEnableStatus(); } // TSyncClientBase::CreateSession // initialize the (already created) client session and link it with the SML toolkit localstatus TSyncClientBase::InitializeSession(uInt32 aProfileID, bool aAutoSyncSession) { // session must be created before with CreateSession() if (!fClientSessionP) return LOCERR_WRONGUSAGE; // initialitze session return fClientSessionP->InitializeSession(aProfileID, aAutoSyncSession); } // create a message into the instance buffer localstatus TSyncClientBase::generateRequest(bool &aDone) { return getClientSession()->NextMessage(aDone); } // TSyncClientBase::generateRequest // clear all unprocessed or unsent data from SML workspace void TSyncClientBase::clrUnreadSmlBufferdata(void) { InstanceID_t myInstance = getClientSession()->getSmlWorkspaceID(); MemPtr_t p; MemSize_t s; smlLockReadBuffer(myInstance,&p,&s); smlUnlockReadBuffer(myInstance,s); } // TSyncClientBase::clrUnreadSmlBufferdata // process message in the instance buffer localstatus TSyncClientBase::processAnswer(void) { return fClientSessionP->processAnswer(); } // - extract hostname from an URI according to transport void TSyncClientBase::extractHostname(const char *aURI, string &aHostName) { string port; splitURL(aURI,NULL,&aHostName,NULL,NULL,NULL,&port,NULL); // keep old semantic: port included in aHostName if (!port.empty()) { aHostName += ':'; aHostName += port; } } // TSyncClientBase::extractHostname // - extract document name from an URI according to transport void TSyncClientBase::extractDocumentInfo(const char *aURI, string &aDocName) { string query; splitURL(aURI,NULL,NULL,&aDocName,NULL,NULL,NULL,&query); // keep old semantic: query part of aDocName if (!query.empty()) { aDocName += '?'; aDocName += query; } } // TSyncClientBase::extractDocumentInfo // - extract protocol name from an URI according to transport void TSyncClientBase::extractProtocolname(const char *aURI, string &aProtocolName) { splitURL(aURI,&aProtocolName,NULL,NULL,NULL,NULL,NULL,NULL); } // TSyncClientBase::extractProtocolname // delete and unlink current session from SML toolkit void TSyncClientBase::KillClientSession(localstatus aStatusCode) { if (fClientSessionP) { // Abort session if (aStatusCode) fClientSessionP->AbortSession(aStatusCode,true); // remove instance of that session freeSmlInstance(fClientSessionP->getSmlWorkspaceID()); fClientSessionP->setSmlWorkspaceID(0); // make sure it isn't set any more // delete session itself TSyncAgent *clientP = fClientSessionP; fClientSessionP=NULL; delete clientP; } } // TSyncClientBase::KillSession } // namespace sysync // eof libsynthesis-3.4.0.47.1/src/sysync/syncclientbase.h000066400000000000000000000137631226375725500221540ustar00rootroot00000000000000/* * TSyncClientBase * Abstract baseclass for client * * Copyright (c) 2002-2011 by Synthesis AG + plan44.ch * */ #ifndef SYNCCLIENTBASE_H #define SYNCCLIENTBASE_H // general includes (SyncML tookit, windows, Clib) #include "sysync.h" #include "syncappbase.h" #include "syncagent.h" namespace sysync { // forward declarations class TSyncSession; class TSyncAgent; class TSyncClientBase; #ifdef ENGINEINTERFACE_SUPPORT // Support for EngineModule common interface // ========================================= // Engine module class class TClientEngineInterface: public TEngineInterface { typedef TEngineInterface inherited; public: // constructor TClientEngineInterface() {}; #ifndef ENGINE_LIBRARY // appbase factory (based on old appbase-root method) is here virtual TSyncAppBase *newSyncAppBase(void); #else // Running a Client Sync Session // ----------------------------- /// @brief Open a session /// @param aNewSessionH[out] receives session handle for all session execution calls /// @param aSelector[in] selector, depending on session type. For multi-profile clients: profile ID to use /// @param aSessionName[in] a text name/id to identify a session, useage depending on session type. /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure virtual TSyError OpenSessionInternal(SessionH &aNewSessionH, uInt32 aSelector, cAppCharP aSessionName); /// @brief open session specific runtime parameter/settings key /// @note key handle obtained with this call must be closed BEFORE SESSION IS CLOSED! /// @param aNewKeyH[out] receives the opened key's handle on success /// @param aSessionH[in] session handle obtained with OpenSession /// @param aMode[in] the open mode /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure virtual TSyError OpenSessionKey(SessionH aSessionH, KeyH &aNewKeyH, uInt16 aMode); /// @brief Close a session /// @note It depends on session type if this also destroys the session or if it may persist and can be re-opened. /// @param aSessionH[in] session handle obtained with OpenSession /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure virtual TSyError CloseSession(SessionH aSessionH); /// @brief Executes sync session or other sync related activity step by step /// @param aSessionH[in] session handle obtained with OpenSession /// @param aStepCmd[in/out] step command (STEPCMD_xxx): /// - tells caller to send or receive data or end the session etc. /// - instructs engine to suspend or abort the session etc. /// @param aInfoP[in] pointer to a TEngineProgressInfo structure, NULL if no progress info needed /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure virtual TSyError SessionStep(SessionH aSessionH, uInt16 &aStepCmd, TEngineProgressInfo *aInfoP = NULL); virtual TSyError debugPuts(cAppCharP aFile, int aLine, cAppCharP aFunction, int aDbgLevel, cAppCharP aLinePrefix, cAppCharP aText); protected: /// @brief returns the SML instance for a given session handle virtual InstanceID_t getSmlInstanceOfSession(SessionH aSessionH); #endif // ENGINE_LIBRARY }; // TClientEngineInterface #endif // ENGINEINTERFACE_SUPPORT #ifdef DIRECT_APPBASE_GLOBALACCESS // access to client base TSyncClientBase *getClientBase(void); #endif /* TSyncClientBase is a singular object that can set-up and * start Sync client sessions. * It also receives calls from SyncML toolkit callbacks and * can route them to the active TSyncSession */ class TSyncClientBase : public TSyncAppBase { typedef TSyncAppBase inherited; #ifdef ENGINEINTERFACE_SUPPORT friend class TClientEngineInterface; #endif public: // constructors/destructors TSyncClientBase(); virtual ~TSyncClientBase(); // Session flow entry points // - create a new client session localstatus CreateSession(void); #ifdef DBAPI_TUNNEL_SUPPORT // - create a new client DBApi tunnel session localstatus CreateTunnelSession(cAppCharP aDatastoreName); #endif // - initialize client session and link it with the SML toolkit // (session must be created with CreateSession() before) localstatus InitializeSession(uInt32 aProfileID, bool aAutoSyncSession=false); // - create a message into the instance buffer, returns aDone==true if none needed any more localstatus generateRequest(bool &aDone); // - clear unread data in the instance buffer (received and to-be-sent) void clrUnreadSmlBufferdata(void); // - process message in the instance buffer localstatus processAnswer(void); // - get current session TSyncAgent *getClientSession(void) { return fClientSessionP; }; // - remove and kill current session void KillClientSession(localstatus aStatusCode=0); // handlers for SyncML toolkit callbacks // - Start/End Message: identifies Session, and creates new or assigns existing session Ret_t StartMessage( InstanceID_t aSmlWorkspaceID, // SyncML toolkit workspace instance ID VoidPtr_t aUserData, // pointer to a TSyncAgent descendant SmlSyncHdrPtr_t aContentP // SyncML tookit's decoded form of the element ); // Session handling // - extract hostname from an URI according to transport virtual void extractHostname(const char *aURI, string &aHostName); // - extract document info (name/auth) from an URI according to transport void extractDocumentInfo(const char *aURI, string &aDocName); // - extract protocol name from an URI according to transport virtual void extractProtocolname(const char *aURI, string &aProtocolName); protected: // Handle exception happening while decoding commands for session // (Former KillSession) virtual Ret_t HandleDecodingException(TSyncSession * /* aSessionP */, const char * /* aRoutine */, exception * /* aExceptionP */=NULL) { return SML_ERR_UNSPECIFIC; /* %%%% nop so far */ }; private: // the current session TSyncAgent *fClientSessionP; }; // TSyncClientBase } // namespace sysync #endif // SYNCCLIENTBASE_H // eof libsynthesis-3.4.0.47.1/src/sysync/synccommand.cpp000077500000000000000000004700401226375725500220120ustar00rootroot00000000000000/* * File: SyncCommand.cpp * * Author: Lukas Zeller (luz@plan44.ch) * * TSmlCommand, TXXXCmd.... * Wrapper classes for SyncML Commands and the associated SyncML * Toolkit mechanics. * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * 2001-05-30 : luz : created * */ // includes #include "prefix_file.h" #include "synccommand.h" #include "syncsession.h" // %%%% debug hack switch //#define DEBUG_XMLRESPONSE_FOR_WBXML 1 //#undef DEBUG_XMLRESPONSE_FOR_WBXML // Status for Results is not needed according to SyncML 1.0.1 // specs but 9210 seems to need it. // Note: future versions of the standard will require // status for all commands, so this is going to be the default #define RESULTS_SENDS_STATUS 1 // Map statuses are sent immediately, even if they will be part // of sync-updates-to-client package (instead of map-acknowledge) // This seems to be the normal case #define MAP_STATUS_IMMEDIATE 1 #ifndef SYNCCOMMAND_PART1_EXCLUDE using namespace sysync; namespace sysync { void TSmlCommandPContainerClear(TSmlCommandPContainer &aContainer) { while (!aContainer.empty()) { delete aContainer.front(); aContainer.pop_front(); } } } /* command name list, used for cmdRef */ const char * const SyncCommandNames[numSmlCommandTypes] = { "SyncHdr", "Sync", "Sync", // note this is actually SyncEnd, but as we send this as cmdRef, it MUST be named "Sync" as well "Add", "Alert", "Delete", "Get", "Put", "Map", "Results", "Status", "Replace", "Copy", "Move", "Sequence", "Atomic", "[unknown]" }; /* * Implementation of TSmlCommand */ /* public TSmlCommand members */ // base constructor (to be called by all derived constructors) TSmlCommand::TSmlCommand( TSmlCommandTypes aCmdType, // the command type bool aOutgoing, // set if this is a outgoing command (to avoid confusion) TSyncSession *aSessionP, // associated session (for callbacks) uInt32 aMsgID // (optional, for receiving only) the Message ID of the command ) { // save info fCmdType=aCmdType; fMsgID=aMsgID; fSessionP=aSessionP; fOutgoing=aOutgoing; // init fWaitingForStatus=0; // not yet waiting for any statuses fCmdID=0; // no ID yet, will be either set at issue() or read at StartProcessing() fNoResp=false; // respond by default fDontSend=false; // send by default fEvalMode=false; // no eval fPrepared=false; fAllowFailure=false; // debug DEBUGPRINTFX(DBG_PROTO,("Created command '%s' (%s)", getName(), fOutgoing ? "outgoing" : "incoming")); } // TSmlCommand::TSmlCommand // get name of command const char *TSmlCommand::getName(void) { return SyncCommandNames[fCmdType]; } // TSmlCommand::getName #ifdef SYDEBUG TDebugLogger *TSmlCommand::getDbgLogger(void) { // commands log to session's logger return fSessionP ? fSessionP->getDbgLogger() : NULL; } // TSmlCommand::getDbgLogger uInt32 TSmlCommand::getDbgMask(void) { if (!fSessionP) return 0; // no session, no debug return fSessionP->getDbgMask(); } // TSmlCommand::getDbgMask #endif TSyncAppBase *TSmlCommand::getSyncAppBase(void) { return fSessionP ? fSessionP->getSyncAppBase() : NULL; } // TSmlCommand::getSyncAppBase // get name of certain command const char *TSmlCommand::getNameOf(TSmlCommandTypes aCmdType) { return SyncCommandNames[aCmdType]; } // TSmlCommand::getNameOf // start processing a command void TSmlCommand::StartProcessing( SmlPcdataPtr_t aCmdID, // ID of command Flag_t aFlags // flags of command ) { // get command ID StrToULong(smlPCDataToCharP(aCmdID),fCmdID); // get noResp state fNoResp=(aFlags & SmlNoResp_f)!=0; PDEBUGPRINTFX(DBG_HOT,("Started processing Command '%s' (incoming MsgID=%ld, CmdID=%ld)%s",getName(),(long)fMsgID,(long)fCmdID,fNoResp ? ", noResp" : "")); } // TSmlCommand::StartProcessing // - Prepare for issuing, evaluate size of command sInt32 TSmlCommand::evalIssue( uInt32 aAsCmdID, // command ID to be used uInt32 aInMsgID, // message ID in which command is being issued bool aNoResp // issue without wanting response ) { MemSize_t res; bool ok; fPrepared=false; // force re-prepare // start evaluation run smlStartEvaluation(fSessionP->getSmlWorkspaceID()); fEvalMode=true; SYSYNC_TRY { // - call issue to get size ok=issue(aAsCmdID,aInMsgID,aNoResp); // - back to normal mode fEvalMode=false; smlEndEvaluation(fSessionP->getSmlWorkspaceID(),&res); if (!ok) res=-1; // no room, error /* %%% hack to force unsendable-sized syncop commands: #ifdef RELEASE_VERSION #error "%%%%remove this debuh hack!!!" #endif if (dynamic_cast(this)!=NULL) { // always oversized res=0; } */ } SYSYNC_CATCH (...) fEvalMode=false; smlEndEvaluation(fSessionP->getSmlWorkspaceID(),&res); SYSYNC_RETHROW; SYSYNC_ENDCATCH // return available space after sending this command return res; } // TSmlCommand::evalIssue void TSmlCommand::PrepareIssue( SmlPcdataPtr_t *aCmdID, // ID of command Flag_t *aFlags // flags of command ) { if (!fPrepared) { fPrepared=true; // set Command ID if (aCmdID) { // remove old if (*aCmdID) smlFreePcdata(*aCmdID); // create new *aCmdID=newPCDataLong(fCmdID); } // add NoResp flag if requested if (aFlags) *aFlags |= fNoResp ? SmlNoResp_f : 0; } if (!fEvalMode) { #ifdef SYDEBUG if (aCmdID) { if (*aCmdID==NULL) SYSYNC_THROW(TSyncException("No Command ID set at evalIssue() but requested one at issue()")); } #endif // save workspace size immediately before sending to calc message size fBytesbefore=fSessionP->getSmlWorkspaceFreeBytes(); #ifdef DEBUG_XMLRESPONSE_FOR_WBXML // %%% debug hack %%% force output to be XML smlSetEncoding(fSessionP->getSmlWorkspaceID(),SML_XML); #endif } } // TSmlCommand::PrepareIssue #ifndef USE_SML_EVALUATION // get (approximated) message size required for sending it uInt32 TSmlCommand::messageSize(void) { // default, should be enough for most commands return DEFAULTCOMMANDSIZE; } #endif // finalizes issuing a command (updates message size) void TSmlCommand::FinalizeIssue(void) { fSessionP->incOutgoingMessageSize(fBytesbefore-fSessionP->getSmlWorkspaceFreeBytes()); // update msg size #ifdef DEBUG_XMLRESPONSE_FOR_WBXML // %%% debug hack %%% force input to be WBXML again smlSetEncoding(fSessionP->getSmlWorkspaceID(),SML_WBXML); #endif } // TSmlCommand::FinalizeIssue // finalizes issuing a command (updates message size) bool TSmlCommand::queueForResponse(void) { return (!fNoResp && !fSessionP->fOutgoingNoResp); } // TSmlCommand::queueForStatus // returns true if command must be put to the waiting-for-status queue. // If false, command can be deleted bool TSmlCommand::issue( uInt32 aAsCmdID, // command ID to be used uInt32 aInMsgID, // message ID in which command is being issued bool aNoResp ) { // set command ID and Message ID (for further compare with incoming statuses) fCmdID=aAsCmdID; fMsgID=aInMsgID; fNoResp=aNoResp; return fEvalMode; // evaluation ok, but base class commands cannot be issued } // TSmlCommand::issue // execute command (perform real actions, generate status) // returns true if command has executed and can be deleted bool TSmlCommand::execute(void) { // non-derived execute (such as map received by client): protocol error TStatusCommand *statusCmdP=newStatusCommand(400); ISSUE_COMMAND_ROOT(fSessionP,statusCmdP); // done return false; } // TSmlCommand::execute // - test if command matches status bool TSmlCommand::matchStatus(TStatusCommand *aStatusCmdP) { // match if cmdID and msgID are the same return ( (fMsgID==aStatusCmdP->fRefMsgID) && (fCmdID==aStatusCmdP->fRefCmdID) ); } // TSmlCommand::matchStatus // handle status received for previously issued command // returns true if done, false if command must be kept in the status queue bool TSmlCommand::handleStatus(TStatusCommand *aStatusCmdP) { // base class just handles common cases TSyError statuscode = aStatusCmdP->getStatusCode(); if (statuscode<200) { // informational switch (statuscode) { case 101: // in progress, wait for final status POBJDEBUGPRINTFX(fSessionP,DBG_HOT,("Status: 101: In progress, keep waiting for final status")); return false; // keep in queue //break; default: // unknown POBJDEBUGPRINTFX(fSessionP,DBG_ERROR,("Status: %hd: unknown informational status -> accepted",statuscode)); return true; } } else if (statuscode<300) { if (statuscode==202) { // accepted for processing POBJDEBUGPRINTFX(fSessionP,DBG_PROTO,("Status: 202: accepted for processing, keep waiting for final status")); return false; // keep in queue } // successful POBJDEBUGPRINTFX(fSessionP,DBG_PROTO,("Status: %hd: successful --> accept as ok",statuscode)); return true; // done with command } else if (statuscode<400) { // redirection // %%% - we cannot handle them, abort for now POBJDEBUGPRINTFX(fSessionP,DBG_ERROR,("Status: %hd: redirected --> we cannot handle this, abort session",statuscode)); fSessionP->AbortSession(412,false,statuscode); // other party's fault: incomplete command return true; // done with command } else if (statuscode==418) { POBJDEBUGPRINTFX(fSessionP,DBG_PROTO,("Status: 418: already existed on peer --> accept as ok")); return true; // done with command } else if (statuscode<500) { // originator exception (we sent some bad stuff) POBJDEBUGPRINTFX(fSessionP,DBG_ERROR,("Status: %hd: originator exception",statuscode)); if (!fAllowFailure) fSessionP->AbortSession(500,false,statuscode); // our fault return true; // done with command } else { // must be recipient exception POBJDEBUGPRINTFX(fSessionP,DBG_ERROR,("Status: %hd: recipient exception",statuscode)); if (!fAllowFailure) fSessionP->AbortSession(statuscode,false,statuscode); // show other party's reason for error return true; // done with command } // just to make sure return true; // done with command } // TSmlCommand::handleStatus // generate status depending on fNoResp and session's fMsgNoResp TStatusCommand *TSmlCommand::newStatusCommand(TSyError aStatusCode, const char *aStringItem) { TStatusCommand *statusCmdP = new TStatusCommand(fSessionP,this,aStatusCode); if (aStringItem) statusCmdP->addItemString(aStringItem); return statusCmdP; } // TSmlCommand::newStatusCommand // generate and send status depending on fNoResp and session's fMsgNoResp void TSmlCommand::issueStatusCommand(TSyError aStatusCode) { // issuePtr can handle NULL in case no status was generated... fSessionP->issueRootPtr(newStatusCommand(aStatusCode)); } // TSmlCommand::issueStatusCommand TSmlCommand::~TSmlCommand() { TSmlCommandPContainerClear(fPendingStatusReplies); PDEBUGPRINTFX(DBG_PROTO,("Deleted command '%s' (%s MsgID=%ld, CmdID=%ld)",getName(),fOutgoing ? "outgoing" : "incoming", (long)fMsgID,(long)fCmdID)); } // TSmlCommand::~TSmlCommand void TSmlCommand::queueStatusCmd(TSmlCommand *aSyncCommandP) { fPendingStatusReplies.push_back(aSyncCommandP); } bool TSmlCommand::hasQueuedStatusCmds() const { return !fPendingStatusReplies.empty(); } void TSmlCommand::transferQueuedStatusCmds(TSmlCommandPContainer &commands) { while (!fPendingStatusReplies.empty()) { commands.push_back(fPendingStatusReplies.front()); fPendingStatusReplies.pop_front(); } } /* end of TSmlCommand implementation */ /* * Implementation of TSyncHeader */ /* public TSyncHeader members */ // constructor for receiving Sync header TSyncHeader::TSyncHeader( TSyncSession *aSessionP, // associated session (for callbacks) SmlSyncHdrPtr_t aSyncHdrElementP // associated SyncHdr content element ) : TSmlCommand(scmd_synchdr,false,aSessionP) { // save element fSyncHdrElementP = aSyncHdrElementP; } // TSyncHeader::TSyncHeader // constructor for sending SyncHdr TSyncHeader::TSyncHeader( TSyncSession *aSessionP, // associated session (for callbacks) bool aOutgoingNoResp // if true, entire message will request no responses ) : TSmlCommand(scmd_synchdr,true,aSessionP) { // prevent two simultaneous messages if (fSessionP->fOutgoingStarted) SYSYNC_THROW(TSyncException("Tried to start new message before finishing previous")); // let session create the structure (using session vars for info) fSyncHdrElementP=fSessionP->NewOutgoingSyncHdr(aOutgoingNoResp); // now outgoing message IS started fSessionP->fOutgoingStarted=true; } // TSyncHeader::TSyncHeader // returns true if command must be put to the waiting-for-status queue. // If false, command can be deleted bool TSyncHeader::issue( uInt32 aAsCmdID, // command ID to be used uInt32 aInMsgID, // message ID in which command is being issued bool aNoResp ) { // prepare basic stuff TSmlCommand::issue(0,aInMsgID,false); // now issue if (fSyncHdrElementP) { // issue command with SyncML toolkit, no CmdID or flags to set here PrepareIssue(NULL,NULL); if (!fEvalMode) { Ret_t err; #ifdef SYDEBUG if (fSessionP->fXMLtranslate && fSessionP->fOutgoingXMLInstance) { err=smlStartMessageExt(fSessionP->fOutgoingXMLInstance,fSyncHdrElementP,SmlVersionCodes[fSessionP->fSyncMLVersion]); if (err!=SML_ERR_OK) { // problem with XML translation PDEBUGPRINTFX(DBG_ERROR,("XML translation disabled due to sml error=%04hX",err)); fSessionP->fXMLtranslate=false; } } #endif if ((err=smlStartMessageExt(fSessionP->getSmlWorkspaceID(),fSyncHdrElementP,SmlVersionCodes[fSessionP->fSyncMLVersion]))!=SML_ERR_OK) { SYSYNC_THROW(TSmlException("smlStartMessage",err)); } FinalizeIssue(); // we don't need the status structure any more, free (and NULL ptr) now FreeSmlElement(); } else // just evaluate size return smlStartMessageExt(fSessionP->getSmlWorkspaceID(),fSyncHdrElementP,SmlVersionCodes[fSessionP->fSyncMLVersion])==SML_ERR_OK; } else { DEBUGPRINTFX(DBG_ERROR,("*** Tried to issue NULL synchdr")); } // header will normally receive status return queueForResponse(); } // TSyncHeader::issue // handle status received for previously issued command // returns true if done, false if command must be kept in the status queue bool TSyncHeader::handleStatus(TStatusCommand *aStatusCmdP) { // status for SyncHdr if (!fSessionP->handleHeaderStatus(aStatusCmdP)) { // session could not handle item return TSmlCommand::handleStatus(aStatusCmdP); } // status handled return true; // done with command } // TSyncHeader::handleStatus // execute command (perform real actions, generate status) // returns true if command has executed and can be deleted // NOTE: synchdr is a special case: if it returns FALSE, // session must be reset and synchdr must be re-excecuted bool TSyncHeader::execute(void) { const char *verDTD; const char *verProto; TStatusCommand *statusCmdP=NULL; sInt16 statuscode=400; bool hdrok=true; if (!fSyncHdrElementP) SYSYNC_THROW(TSyncException("empty header")); if (!fSessionP) SYSYNC_THROW(TSyncException("missing fSessionP")); // first get message ID to be able to generate statuses fMsgID=0; // none by default if (StrToULong(smlPCDataToCharP(fSyncHdrElementP->msgID),fMsgID)) { // got msgID, check if ok if ( fMsgID==uInt32(fSessionP->fIncomingMsgID-1) && fSessionP->fAllowMessageRetries // check if we want to allow this (7250 for example seems to retry messages) ) { // this seems to be a transport-level retry of the previous message PDEBUGPRINTFX(DBG_ERROR,("*********** WARNING: Remote resent MsgID %ld",(long)fMsgID)); // set back incoming ID fSessionP->fIncomingMsgID = fMsgID; // -> we should resend the previous answer again. if ( fSessionP->getSyncAppBase()->canBufferRetryAnswer() ) { // we can resend answers PDEBUGPRINTFX(DBG_ERROR,("last answer buffered -> sending it again")); fSessionP->fMessageRetried=true; return false; } else { // use not foolproof poor man's method // %%% This will fail if the previous message received has // changed datastore/session/package states, but will work if // the retry is within a phase (probable case for long sessions) PDEBUGPRINTFX(DBG_ERROR,("No buffered answer to resend -> just process msg again (WARNING: possibly messes up session state)")); } } if (fMsgIDfIncomingMsgID)) { // bad Message ID (lower than previous): forget previous session, start new one PDEBUGPRINTFX(DBG_ERROR,("Bad incoming MsgID %ld, expected >=%ld -> Aborting previous Session, starting new",(long)fMsgID,(long)fSessionP->fIncomingMsgID)); return false; // session must be restarted, this command re-executed } } else { // header without session ID is bad statuscode=500; statusCmdP=newStatusCommand(statuscode); // log file entry PDEBUGPRINTFX(DBG_ERROR,("Missing incoming MsgID -> Aborting Session")); hdrok=false; // cannot start } // Assign session-var anyway fSessionP->fIncomingMsgID=fMsgID; // now check header for conformance SYSYNC_TRY { // get info out of SyncHdr if (hdrok) { // get noResp flag (which is valid for the entire message) fNoResp=(fSyncHdrElementP->flags & SmlNoResp_f)!=0; fSessionP->fMsgNoResp=fNoResp; // copy to session flag // test SyncML version compatibility verProto=smlPCDataToCharP(fSyncHdrElementP->proto); verDTD=smlPCDataToCharP(fSyncHdrElementP->version); sInt16 ver; // find version for (ver=1; verfSyncMLVersion=(TSyncMLVersions)ver; break; } } // - Protocol Version TSyncMLVersions maxver = fSessionP->getSessionConfig()->fMaxSyncMLVersionSupported; TSyncMLVersions minver = fSessionP->getSessionConfig()->fMinSyncMLVersionSupported; if ( ver=numSyncMLVersions || ver>maxver || (IS_SERVER && fSessionP->fSyncMLVersion!=syncml_vers_unknown && fSessionP->fSyncMLVersion!=ver) ) { // unsupported protocol version (or different than in first message): Status 513 // - Make sure we have a valid SyncML version if ( fSessionP->fSyncMLVersion==syncml_vers_unknown || fSessionP->fSyncMLVersion>maxver ) { // use highest version we know for the answering message fSessionP->fSyncMLVersion = maxver; } else if (fSessionP->fSyncMLVersionfSyncMLVersion = minver; } // - Set status statuscode=513; statusCmdP=newStatusCommand(statuscode); // - add version(s) we support in data item string vs; for (sInt16 v=minver; v<=maxver; v++) { if (!vs.empty()) vs+=", "; vs+=SyncMLVerProtoNames[v]; } statusCmdP->addItemString(vs.c_str()); // - log file entry PDEBUGPRINTFX(DBG_ERROR,("Unsupported or changing verProto %s -> Aborting Session",verProto)); hdrok=false; // bad header } // protocol version known, check if DTD matches else if (strcmp(verDTD,SyncMLVerDTDNames[ver])!=0) { // wrong DTD version for this protocol version: Status 505 statuscode=505; statusCmdP=newStatusCommand(statuscode); statusCmdP->addItemString(SyncMLVerDTDNames[ver]); // log file entry PDEBUGPRINTFX(DBG_ERROR,( "Wrong verDTD %s, expected %s -> Aborting Session", verDTD, SyncMLVerDTDNames[ver] )); hdrok=false; // bad header } // if ok so far, continue header processing if (hdrok) { PDEBUGPRINTFX(DBG_HOT,("Started Processing of message #%ld (%s)",(long)fSessionP->fIncomingMsgID,SyncMLVerProtoNames[ver])); // take a look at SyncHdr Meta SmlMetInfMetInfPtr_t metaP=smlPCDataToMetInfP(fSyncHdrElementP->meta); if (metaP) { // max (outgoing) message size if (metaP->maxmsgsize) { smlPCDataToLong(metaP->maxmsgsize,fSessionP->fMaxOutgoingMsgSize); PDEBUGPRINTFX(DBG_REMOTEINFO,("MaxMsgSize found in SyncHdr: %ld -> set for outgoing msgs",(long)fSessionP->fMaxOutgoingMsgSize)); } // max (outgoing) object size (SyncML 1.1 only) if (metaP->maxobjsize) { smlPCDataToLong(metaP->maxobjsize,fSessionP->fMaxOutgoingObjSize); PDEBUGPRINTFX(DBG_REMOTEINFO,("MaxObjSize found in SyncHdr: %ld",(long)fSessionP->fMaxOutgoingObjSize)); } } // call server/client specific message start in derived classes statusCmdP=newStatusCommand(200); // prepare OK default status (will possibly be modified by MessageStarted()) hdrok=fSessionP->MessageStarted(fSyncHdrElementP,*statusCmdP); } else { //#warning "comment the next line to have server respond like pre-1.0.8.29" // call client/server specific message start routine, but with error flag // Note: we already have a status command (containing an error) fSessionP->MessageStarted(fSyncHdrElementP,*statusCmdP,true); } } // complete and send status, if any if (statusCmdP) { statusCmdP->addTargetRef(fSessionP->fLocalURI.c_str()); statusCmdP->addSourceRef(fSessionP->fRemoteURI.c_str()); // issue as SyncHdr status (if successful status) TStatusCommand *cmdP = statusCmdP; statusCmdP=NULL; statuscode=cmdP->getStatusCode(); // get actual status code fSessionP->issueRootPtr(cmdP,false,statuscode==200); } // set session vars according to header success or failure // - ignore all further incoming commands when header is not ok // NOTE: bad cred will NOT (any longer, SyncFest #5) be flagged as bad header // but instead MessageStarted may have aborted command processing if (!hdrok) fSessionP->AbortSession(400,true); // bad request // free this one now, is not needed any more FreeSmlElement(); } SYSYNC_CATCH (...) // make sure owned objects in local scope are deleted if (statusCmdP) delete statusCmdP; // re-throw SYSYNC_RETHROW; SYSYNC_ENDCATCH // done with command, delete it now: return true return true; } // TSyncHeader::execute void TSyncHeader::FreeSmlElement(void) { // remove SyncML toolkit element(s) FREEPROTOELEMENT(fSyncHdrElementP); } // TSyncHeader::FreeSmlElement TSyncHeader::~TSyncHeader() { // free command elements, if any (use explicit invocation as this is a destructor) TSyncHeader::FreeSmlElement(); } // TSyncHeader::~TSyncHeader /* end of TSyncHeader implementation */ /* * Implementation of TSyncCommand */ // constructor for sending Sync Command TSyncCommand::TSyncCommand( TSyncSession *aSessionP, // associated session (for callbacks) TLocalEngineDS *aLocalDataStoreP, // local datastore TRemoteDataStore *aRemoteDataStoreP // remote datastore ) : TSmlCommand(scmd_sync,true,aSessionP), fInterruptedCommandP(NULL) { // save params fLocalDataStoreP=aLocalDataStoreP; fRemoteDataStoreP=aRemoteDataStoreP; // create internal sync element fSyncElementP = SML_NEW(SmlSync_t); // set proto element type to make it auto-disposable fSyncElementP->elementType=SML_PE_SYNC_START; // Cmd ID is now empty (will be set when issued) fSyncElementP->cmdID=NULL; // default to no flags (noResp is set at issue, if at all) fSyncElementP->flags=0; // set source and target fSyncElementP->target=newLocation(fRemoteDataStoreP->getFullName()); // remote is target for Sync command fSyncElementP->source=newLocation(fLocalDataStoreP->getRemoteViewOfLocalURI()); // local is source of Sync command // no optional elements for now fSyncElementP->cred=NULL; // %%% no database level auth yet at all fSyncElementP->meta=NULL; // %%% no search grammar for now // add number of changes for SyncML 1.1 if remote supports it fSyncElementP->noc=NULL; // default to none if (aSessionP->fRemoteWantsNOC) { sInt32 noc = fLocalDataStoreP->getNumberOfChanges(); if (noc>=0) { // we have a valid NOC value, add it fSyncElementP->noc=newPCDataLong(noc); } } // not yet in progress (as not yet issued) fInProgress=false; } // TSyncCommand::TSyncCommand // constructor for receiving Sync Command TSyncCommand::TSyncCommand( TSyncSession *aSessionP, // associated session (for callbacks) uInt32 aMsgID, // the Message ID of the command SmlSyncPtr_t aSyncElementP // associated Sync content element ) : TSmlCommand(scmd_sync,false,aSessionP,aMsgID), fInterruptedCommandP(NULL) { // save sync element fSyncElementP = aSyncElementP; fInProgress=false; // just in case... // no params fLocalDataStoreP=NULL; fRemoteDataStoreP=NULL; } // TSyncCommand::TSyncCommand // handle status received for previously issued command // returns true if done, false if command must be kept in the status queue bool TSyncCommand::handleStatus(TStatusCommand *aStatusCmdP) { // catch those codes that do not abort entire session TSyError statuscode = aStatusCmdP->getStatusCode(); bool handled=false; switch (statuscode) { case 404: // datastore not found case 403: // forbidden case 406: // bad mode case 415: // type(s) not supported case 422: // bad CGI case 510: // datastore error case 512: // sync failed case 514: // cancelled if (fLocalDataStoreP) { // there is a local datastore to abort fLocalDataStoreP->engAbortDataStoreSync(statuscode,false); // remote problem } if (fInProgress) { // make sure sync command is finished now fInProgress=false; // Note that setting fInProgress to false // is only completely safe in issue(). // Here it is allowed as we KNOW that syncCommand // is root level, so session's handleStatus() // will properly clear the fInterruptedCommandP // (this would not work if this command was nested) } handled = true; break; default: handled=TSmlCommand::handleStatus(aStatusCmdP); break; } return handled; } // TSyncCommand::handleStatus // mark any syncitems (or other data) for resume. Called for pending commands // when a Suspend alert is received or whenever a resumable state must be saved void TSyncCommand::markPendingForResume(TLocalEngineDS *aForDatastoreP, bool aUnsent) { // only act if this is for our local datastore and unsent // (sent ones will be in the status wait queue, and will be found there) if (aUnsent && fLocalDataStoreP==aForDatastoreP) { fSessionP->markPendingForResume( fNextMessageCommands, fInterruptedCommandP, fLocalDataStoreP ); } } // TSyncCommand::markPendingForResume // analyze command (but do not yet execute) bool TSyncCommand::analyze(TPackageStates aPackageState) { TSmlCommand::analyze(aPackageState); // get Command ID and flags if (fSyncElementP) { StartProcessing(fSyncElementP->cmdID,fSyncElementP->flags); return true; } else return false; // no proto element, bad command } // TSyncCommand::analyze // execute command (perform real actions, generate status) // returns true if command has executed and can be deleted bool TSyncCommand::execute(void) { TStatusCommand *statusCmdP=NULL; bool queueforlater = false; if (fSyncElementP) SYSYNC_TRY { // determine database to be synced (target LocURI) // - generate default OK status statusCmdP = newStatusCommand(200); // - add source and target refs from item statusCmdP->addSourceRef(smlSrcTargLocURIToCharP(fSyncElementP->source)); statusCmdP->addTargetRef(smlSrcTargLocURIToCharP(fSyncElementP->target)); PDEBUGPRINTFX(DBG_HOT,( "Processing Sync, Source='%s', Target='%s'", smlSrcTargLocURIToCharP(fSyncElementP->source), smlSrcTargLocURIToCharP(fSyncElementP->target) )); // - check for MaxObjSize here SmlMetInfMetInfPtr_t metaP=smlPCDataToMetInfP(fSyncElementP->meta); if (metaP && metaP->maxobjsize) { smlPCDataToLong(metaP->maxobjsize,fSessionP->fMaxOutgoingObjSize); PDEBUGPRINTFX(DBG_REMOTEINFO,("MaxObjSize found in Sync command: %ld",(long)fSessionP->fMaxOutgoingObjSize)); } // - let session do the processing queueforlater=false; fSessionP->processSyncStart( fSyncElementP, *statusCmdP, queueforlater // will be set if command must be queued for later re-execution ); if (queueforlater) { // we don't need the status now delete statusCmdP; } else { // Sync command execution completed, send (or save) status now #ifdef SYNCSTATUS_AT_SYNC_CLOSE // %%% don't send, just save for being sent at fSessionP->fSyncCloseStatusCommandP=statusCmdP; #else // - issue status for item ISSUE_COMMAND_ROOT(fSessionP,statusCmdP); #endif /* %%% no need to abort session, failing sync command stops sync with this datastore anyway // make sure session gets aborted when Sync is not successful if (!ok) { fSessionP->AbortSession(500,true); } */ // free element FreeSmlElement(); } } SYSYNC_CATCH (...) // make sure owned objects in local scope are deleted if (statusCmdP) delete statusCmdP; // re-throw SYSYNC_RETHROW; SYSYNC_ENDCATCH // return true if command has fully executed return !queueforlater; } // TSyncCommand::execute // returns true if command must be put to the waiting-for-status queue. // If false, command can be deleted bool TSyncCommand::issue( uInt32 aAsCmdID, // command ID to be used uInt32 aInMsgID, // message ID in which command is being issued bool aNoResp ) { // prepare basic stuff TSmlCommand::issue(aAsCmdID,aInMsgID,aNoResp); // now issue if (fSyncElementP) { // generate (first) opening (or evaluate) if (fEvalMode) return generateOpen(); generateOpen(); // generate commands, update fInProgress generateCommandsAndClose(); // Make sure this is not counted as command (will be counted in issuePtr(), so // decrement here). Note that this must be done AFTER calling generateCommandsAndClose(), // because generating needs the correct count (and this is not yet included by now!) fSessionP->fOutgoingCmds--; // we're now one below the real count, but that will be compensated when returning to issuePtr } else { DEBUGPRINTFX(DBG_ERROR,("*** Tried to issue NULL sync")); } // return true if command must be queued for status/result response reception return queueForResponse(); } // TSyncCommand::issue // - test if completely issued (must be called after issue() and continueIssue()) bool TSyncCommand::finished(void) { // not finished as long there are more syncOps to send; // incoming are always finished after executing return (!fInProgress || !fOutgoing); } // TSyncCommand::finished // generate opening bracket bool TSyncCommand::generateOpen(void) { // issue command Start with SyncML toolkit fPrepared=false; // force re-preparing in all cases (as this might be continuing a command) PrepareIssue(&fSyncElementP->cmdID,&fSyncElementP->flags); if (!fEvalMode) { #ifdef SYDEBUG if (fSessionP->fXMLtranslate && fSessionP->fOutgoingXMLInstance) smlStartSync(fSessionP->fOutgoingXMLInstance,fSyncElementP); #endif Ret_t err; if ((err=smlStartSync(fSessionP->getSmlWorkspaceID(),fSyncElementP))!=SML_ERR_OK) { SYSYNC_THROW(TSmlException("smlStartSync",err)); } FinalizeIssue(); // show debug PDEBUGBLOCKFMT(("sync","Opened Sync command bracket", "Reopen=%s|SourceURI=%s|TargetURI=%s|IncomingMsgID=%ld|CmdID=%ld", fInProgress ? "yes" : "no", smlSrcTargLocURIToCharP(fSyncElementP->source), smlSrcTargLocURIToCharP(fSyncElementP->target), (long)fMsgID, (long)fCmdID )); PDEBUGPRINTFX(DBG_HOT,( "%sOpened bracket, Source='%s', Target='%s' as (outgoing MsgID=%ld, CmdID=%ld)", fInProgress ? "Re-" : "", smlSrcTargLocURIToCharP(fSyncElementP->source), smlSrcTargLocURIToCharP(fSyncElementP->target), (long)fMsgID, (long)fCmdID )); // calculate (approx) max free space for data fSessionP->fMaxRoomForData = fSessionP->getSmlWorkspaceFreeBytes()-fSessionP->getNotUsableBufferBytes()- // what is free DEFAULTCOMMANDSIZE; // minus a standard command size // now we are in progress fInProgress=true; return true; } else return smlStartSync(fSessionP->getSmlWorkspaceID(),fSyncElementP)==SML_ERR_OK; } // TSyncCommand::generateOpen // generate commands for inside of the bracket void TSyncCommand::generateCommandsAndClose(void) { // generate new commands only if message is not full already if (!fSessionP->outgoingMessageFull()) { // check for unassigned fLocalDataStoreP as this seems to happen sometimes in the cmdline client PPOINTERTEST(fLocalDataStoreP,("Warning: fLocalDataStoreP==NULL, cannot generate commands -> empty command")); if (fLocalDataStoreP) { fInProgress = !( fLocalDataStoreP->engGenerateSyncCommands ( fNextMessageCommands, fInterruptedCommandP ) ); } } // issue command End with SyncML toolkit // - save workspace size immediately before sending to calc message size fBytesbefore=fSessionP->getSmlWorkspaceFreeBytes(); #ifdef SYDEBUG if (fSessionP->fXMLtranslate && fSessionP->fOutgoingXMLInstance) smlEndSync(fSessionP->fOutgoingXMLInstance); #endif Ret_t err; if ((err=smlEndSync(fSessionP->getSmlWorkspaceID()))!=SML_ERR_OK) { SYSYNC_THROW(TSmlException("smlEndSync",err)); } FinalizeIssue(); PDEBUGPRINTFX(DBG_HOT,( "Closed bracket, %sfinal", fInProgress ? "NOT " : "" )); PDEBUGENDBLOCK("sync"); } // TSyncCommand::generateCommandsAndClose // - continue issuing command. This is called by session at start of new message // when finished() returned false after issue()/continueIssue() // (which causes caller of finished() to put command into fInteruptedCommands queue) // returns true if command should be queued for status (again?) // NOTE: continueIssue must make sure that it gets a new CmdID/MsgID because // the command itself is issued multiple times bool TSyncCommand::continueIssue(bool &aNewIssue) { aNewIssue=false; // never issue anew! if (!fInProgress) return false; // done, don't queue for status again // command is in progress, re-open a bracket in this message // - get new CmdID/MsgID fCmdID = fSessionP->getNextOutgoingCmdID(); fMsgID = fSessionP->getOutgoingMsgID(); // - now issue open generateOpen(); // first try to execute queued sub-commands that could not be sent in last message fSessionP->ContinuePackage( fNextMessageCommands, fInterruptedCommandP ); // then generate more commands if needed (updates fInProgress) generateCommandsAndClose(); // new sync command must be queued for status again return true; } // TSyncCommand::continueIssue void TSyncCommand::FreeSmlElement(void) { // remove SyncML toolkit element(s) FREEPROTOELEMENT(fSyncElementP); } // TResultsCommand::FreeSmlElement TSyncCommand::~TSyncCommand() { // free command elements, if any (use explicit invocation as this is a destructor) TSyncCommand::FreeSmlElement(); // forget any queued sub commands TSmlCommandPContainer::iterator pos; for (pos=fNextMessageCommands.begin(); pos!=fNextMessageCommands.end(); ++pos) { // show that command was not sent DEBUGPRINTFX(DBG_ERROR,("Never sent prepared Sub-Command '%s', (outgoing MsgID=%ld, CmdID=%ld)", (*pos)->getName(), (long)(*pos)->getMsgID(), (long)(*pos)->getCmdID() )); // delete delete *pos; } fNextMessageCommands.clear(); // clear list // - interrupted command // NOTE: interrupted subcommands may NOT exist in any of the main command // queues, because these OWN the commands and will delete them // at ResetSession(). if (fInterruptedCommandP) { // show that command was not sent DEBUGPRINTFX(DBG_ERROR,("Never finished interrupted sub-command '%s', (outgoing MsgID=%ld, CmdID=%ld)", fInterruptedCommandP->getName(), (long)fInterruptedCommandP->getMsgID(), (long)fInterruptedCommandP->getCmdID() )); delete fInterruptedCommandP; fInterruptedCommandP=NULL; } } // TSyncCommand::~TSyncCommand /* end of TSyncCommand implementation */ /* * Implementation of TSyncEndCommand */ // constructor for receiving Sync Command TSyncEndCommand::TSyncEndCommand( TSyncSession *aSessionP, // associated session (for callbacks) uInt32 aMsgID // the Message ID of the command ) : TSmlCommand(scmd_syncend,false,aSessionP,aMsgID) { // nop so far } // TSyncEndCommand::TSyncEndCommand // execute command (perform real actions, generate status) // returns true if command has executed and can be deleted bool TSyncEndCommand::execute(void) { bool queueforlater=false; // let session do the appropriate processing fSessionP->processSyncEnd(queueforlater); // return true if command has fully executed return !queueforlater; } // TSyncEndCommand::execute TSyncEndCommand::~TSyncEndCommand() { } // TSyncEndCommand::~TSyncEndCommand /* end of TSyncEndCommand implementation */ /* * Implementation of TAlertCommand */ // constructor for sending Alert TAlertCommand::TAlertCommand( TSyncSession *aSessionP, // associated session (for callbacks) TLocalEngineDS *aLocalDataStoreP, // local datastore uInt16 aAlertCode // Alert code to send ) : TSmlCommand(scmd_alert,true,aSessionP) { // save datastore fLocalDataStoreP = aLocalDataStoreP; // save Alert Code fAlertCode = aAlertCode; // create internal alert element fAlertElementP = SML_NEW(SmlAlert_t); // set proto element type to make it auto-disposable fAlertElementP->elementType=SML_PE_ALERT; // Cmd ID is now empty (will be set when issued) fAlertElementP->cmdID=NULL; // default to no flags (noResp is set at issue, if at all) fAlertElementP->flags=0; // data is alert code fAlertElementP->data=newPCDataLong(fAlertCode); // no optional elements for now fAlertElementP->cred=NULL; fAlertElementP->itemList=NULL; } // TAlertCommand::TAlertCommand // constructor for receiving Alert TAlertCommand::TAlertCommand( TSyncSession *aSessionP, // associated session (for callbacks) uInt32 aMsgID, // the Message ID of the command SmlAlertPtr_t aAlertElementP // associated Alert content element ) : TSmlCommand(scmd_alert,false,aSessionP,aMsgID) { // save alert element fAlertElementP = aAlertElementP; // no params fLocalDataStoreP=NULL; } // TAlertCommand::TAlertCommand // analyze command (but do not yet execute) bool TAlertCommand::analyze(TPackageStates aPackageState) { TSmlCommand::analyze(aPackageState); // get Command ID and flags if (fAlertElementP) { StartProcessing(fAlertElementP->cmdID,fAlertElementP->flags); return true; } else return false; // no proto element, bad command } // TAlertCommand::analyze // execute command (perform real actions, generate status) // returns true if command has executed and can be deleted bool TAlertCommand::execute(void) { TStatusCommand *statusCmdP=NULL; TSmlCommand *alertresponsecmdP=NULL; SYSYNC_TRY { // get alert code sInt32 temp; if (!smlPCDataToLong(fAlertElementP->data,temp)) { // non-numeric alert PDEBUGPRINTFX(DBG_ERROR,( "Non-Integer Alert Data: '%s', cannot handle", smlPCDataToCharP(fAlertElementP->data) )); statusCmdP = newStatusCommand(400,"Alert Data not understood"); } else { fAlertCode=temp; PDEBUGPRINTFX(DBG_HOT,( "Code=%hd. %s Cred. Analyzing Items", fAlertCode, fAlertElementP->cred ? "has" : "No" )); // intercept special codes if (fAlertCode==221) { // %%% tdb PDEBUGPRINTFX(DBG_ERROR,("*********** RESULT ALERT 221 received in bad context")); statusCmdP = newStatusCommand(400,"221 Alert in bad context received"); } else if (fAlertCode==222) { // request next message in packet PDEBUGPRINTFX(DBG_HOT,("Next Message in Packet Alert (222): flag sending waiting commands")); // - acknowledge 222 alert statusCmdP = newStatusCommand(200); // - add source and target refs statusCmdP->addTargetRef(fSessionP->getLocalURI()); statusCmdP->addSourceRef(fSessionP->getRemoteURI()); // - issue status for item (but not being sent alone with SyncHdr status) // (treat it like ok-synchdr-status = NOT to be sent if there's no real command following) { TSmlCommand* p=statusCmdP; statusCmdP=NULL; fSessionP->issueRootPtr(p,false,true); } // - signal occurrence of 222 alert to session fSessionP->nextMessageRequest(); } else { // normal alert, walk through items SmlItemListPtr_t nextitemP = fAlertElementP->itemList; while (nextitemP) { if (nextitemP->item) { // - check for MaxObjSize here SmlMetInfMetInfPtr_t metaP=smlPCDataToMetInfP(nextitemP->item->meta); if (metaP && metaP->maxobjsize) { smlPCDataToLong(metaP->maxobjsize,fSessionP->fMaxOutgoingObjSize); PDEBUGPRINTFX(DBG_REMOTEINFO,("MaxObjSize found in Alert command: %ld",(long)fSessionP->fMaxOutgoingObjSize)); } // process alert item with common code // - generate default OK status statusCmdP = newStatusCommand(200); // - add source and target refs from item statusCmdP->addSourceRef(smlSrcTargLocURIToCharP(nextitemP->item->source)); statusCmdP->addTargetRef(smlSrcTargLocURIToCharP(nextitemP->item->target)); PDEBUGPRINTFX(DBG_HOT,( "- Processing Alert Item (code=%hd), Source='%s', Target='%s'", fAlertCode, smlSrcTargLocURIToCharP(nextitemP->item->source), smlSrcTargLocURIToCharP(nextitemP->item->target) )); // - let session process the alert item alertresponsecmdP = fSessionP->processAlertItem( fAlertCode, nextitemP->item, fAlertElementP->cred, *statusCmdP, fLocalDataStoreP // receives involved datastore (Note: if Alert cmd has multiple items, this will finally contain only the datastore of the last item, others might differ) ); // - issue status for item ISSUE_COMMAND_ROOT(fSessionP,statusCmdP); // - issue result (e.g. acknowledge alert) for item, if any if (alertresponsecmdP) { fSessionP->queueForIssueRoot(alertresponsecmdP); } } // next nextitemP=nextitemP->next; } // while } // normal alert code with item } // numeric alert code // free element FreeSmlElement(); } SYSYNC_CATCH (...) // make sure owned objects in local scope are deleted if (statusCmdP) delete statusCmdP; if (alertresponsecmdP) delete alertresponsecmdP; // re-throw SYSYNC_RETHROW; SYSYNC_ENDCATCH // done with command, delete it now: return true return true; } // TAlertCommand::execute // returns true if command must be put to the waiting-for-status queue. // If false, command can be deleted bool TAlertCommand::issue( uInt32 aAsCmdID, // command ID to be used uInt32 aInMsgID, // message ID in which command is being issued bool aNoResp ) { // prepare basic stuff TSmlCommand::issue(aAsCmdID,aInMsgID,aNoResp); // now issue if (fAlertElementP) { // issue command with SyncML toolkit PrepareIssue(&fAlertElementP->cmdID,&fAlertElementP->flags); if (!fEvalMode) { #ifdef SYDEBUG if (fSessionP->fXMLtranslate && fSessionP->fOutgoingXMLInstance) smlAlertCmd(fSessionP->fOutgoingXMLInstance,fAlertElementP); #endif Ret_t err; if ((err=smlAlertCmd(fSessionP->getSmlWorkspaceID(),fAlertElementP))!=SML_ERR_OK) { SYSYNC_THROW(TSmlException("smlAlertCmd",err)); } FinalizeIssue(); // show debug #ifdef SYDEBUG PDEBUGPRINTFX(DBG_HOT,("Alert Code %s sent", smlPCDataToCharP(fAlertElementP->data) )); // normal alert, walk through items SmlItemListPtr_t nextitemP = fAlertElementP->itemList; while (nextitemP) { if (nextitemP->item) { // show alert item PDEBUGPRINTFX(DBG_HOT,( "- Alert Item: Source='%s', Target='%s'", smlSrcTargLocURIToCharP(nextitemP->item->source), smlSrcTargLocURIToCharP(nextitemP->item->target) )); } // next nextitemP=nextitemP->next; /// @note %%% we should not send more than one item for now! if (nextitemP) DEBUGPRINTFX(DBG_ERROR,("More than one item - handleStatus is not prepared for that!")); } // while #endif // we don't need the status structure any more, free (and NULL ptr) now FreeSmlElement(); } else return smlAlertCmd(fSessionP->getSmlWorkspaceID(),fAlertElementP)==SML_ERR_OK; } else { DEBUGPRINTFX(DBG_ERROR,("*** Tried to issue NULL alert")); } // return true if command must be queued for status/result response reception return queueForResponse(); } // TAlertCommand::issue bool TAlertCommand::statusEssential(void) { // Alert 222 status is not essential return !(fAlertCode==222); } // TAlertCommand::statusEssential // handle status received for previously issued command // returns true if done, false if command must be kept in the status queue bool TAlertCommand::handleStatus(TStatusCommand *aStatusCmdP) { /// @note: This is a simplified implementation which KNOWS that /// we do not send Alerts with more than one item. If we did one /// day, we'd have to extend this implementation. // if this alert command was created by a datastore, let it handle it if (fLocalDataStoreP) { // pass to local datastore if (fLocalDataStoreP->engHandleAlertStatus(aStatusCmdP->getStatusCode())) return true; // datastore handled it } // let SmlCommand handle it return TSmlCommand::handleStatus(aStatusCmdP); } // TAlertCommand::handleStatus // add a String Item to the alert void TAlertCommand::addItemString( const char *aItemString // item string to be added ) { if (fAlertElementP && aItemString) { addItem(newStringDataItem(aItemString)); } } // TAlertCommand::addItemString // add an Item to the alert void TAlertCommand::addItem( SmlItemPtr_t aItemP // existing item data structure, ownership is passed to Alert ) { if (fAlertElementP) addItemToList(aItemP,&(fAlertElementP->itemList)); } // TAlertCommand::addItem void TAlertCommand::FreeSmlElement(void) { // remove SyncML toolkit element(s) FREEPROTOELEMENT(fAlertElementP); } // TResultsCommand::FreeSmlElement TAlertCommand::~TAlertCommand() { // free command elements, if any (use explicit invocation as this is a destructor) TAlertCommand::FreeSmlElement(); } // TAlertCommand::~TAlertCommand /* end of TAlertCommand implementation */ /* * Implementation of TUnimplementedCommand */ // constructor for receiving command TUnimplementedCommand::TUnimplementedCommand( TSyncSession *aSessionP, // associated session (for callbacks) uInt32 aMsgID, // the Message ID of the command SmlPcdataPtr_t aCmdID, // command ID (as contents are unknown an cannot be analyzed) Flag_t aFlags, // flags to get fNoResp TSmlCommandTypes aCmdType, // command type (for name) void *aContentP, // associated command content element TSyError aStatusCode // status code to be returned on execution ) : TSmlCommand(aCmdType,false,aSessionP,aMsgID) { // get command ID StrToULong(smlPCDataToCharP(aCmdID),fCmdID); // save noResp fNoResp=(aFlags & SmlNoResp_f)!=0; // forget element smlFreeProtoElement(aContentP); // save status type fStatusCode=aStatusCode; } // TUnimplementedCommand::TUnimplementedCommand // execute command (perform real actions, generate status) // returns true if command has executed and can be deleted bool TUnimplementedCommand::execute(void) { TStatusCommand *statusCmdP=NULL; DEBUGPRINTFX(DBG_HOT,("UNIMPLEMENTED, started dummy processing, (incoming MsgID=%ld, CmdID=%ld)",(long)fMsgID,(long)fCmdID)); SYSYNC_TRY { statusCmdP = newStatusCommand(fStatusCode); statusCmdP->addItemString("Unimplemented Command"); ISSUE_COMMAND_ROOT(fSessionP,statusCmdP); } SYSYNC_CATCH (...) // make sure owned objects in local scope are deleted if (statusCmdP) delete statusCmdP; // re-throw SYSYNC_RETHROW; SYSYNC_ENDCATCH // done with command, delete it now: return true return true; } // TUnimplementedCommand::execute /* end of TUnimplementedCommand implementation */ /* * Implementation of TSyncOpCommand */ // constructor for receiving command TSyncOpCommand::TSyncOpCommand( TSyncSession *aSessionP, // associated session (for callbacks) TLocalEngineDS *aDataStoreP, // the local datastore this syncop belongs to uInt32 aMsgID, // the Message ID of the command TSyncOperation aSyncOp, // the Sync operation (sop_xxx) TSmlCommandTypes aCmdType, // the command type (scmd_xxx) SmlGenericCmdPtr_t aSyncOpElementP // associated syncml protocol element ) : TSmlCommand(aCmdType,false,aSessionP,aMsgID) { // save datastore fDataStoreP=aDataStoreP; // save operation type fSyncOp=aSyncOp; // save element fSyncOpElementP = aSyncOpElementP; // no remainder to be sent as next chunk fChunkedItemSize = 0; fIncompleteData = false; // no suspended part of item fStoredSize=0; fUnconfirmedSize=0; fLastChunkSize=0; } // TSyncOpCommand::TSyncOpCommand // constructor for sending command TSyncOpCommand::TSyncOpCommand( TSyncSession *aSessionP, // associated session (for callbacks) TLocalEngineDS *aDataStoreP, // datastore from which command originates TSyncOperation aSyncOp, // sync operation (=command type) SmlPcdataPtr_t aMetaP // meta for entire command (passing owner) ) : TSmlCommand(scmd_unknown,true,aSessionP) { // save datastore fDataStoreP=aDataStoreP; #ifndef USE_SML_EVALUATION // no items yet fItemSizes=0; #endif // no remainder to be sent as next chunk fChunkedItemSize = 0; fIncompleteData = false; // no suspended part of item fStoredSize=0; fUnconfirmedSize=0; fLastChunkSize=0; // command type not yet determined fSyncOp=aSyncOp; // create internal alert element fSyncOpElementP = SML_NEW(SmlGenericCmd_t); // set default to make sure it is disposable (will be adjusted when items are added) fSyncOpElementP->elementType=SML_PE_GENERIC; // Cmd ID is now empty (will be set when issued) fSyncOpElementP->cmdID=NULL; // default to no flags (noResp is set at issue, if at all) fSyncOpElementP->flags=0; // insert meta, if any fSyncOpElementP->meta=aMetaP; // no optional elements for now fSyncOpElementP->cred=NULL; fSyncOpElementP->itemList=NULL; // determine command type switch (fSyncOp) { case sop_wants_add: case sop_add: fSyncOpElementP->elementType=SML_PE_ADD; fCmdType=scmd_add; break; case sop_copy: fSyncOpElementP->elementType=SML_PE_COPY; fCmdType=scmd_copy; break; case sop_move: fSyncOpElementP->elementType=SML_PE_MOVE; fCmdType=scmd_move; break; case sop_wants_replace: case sop_replace: fSyncOpElementP->elementType=SML_PE_REPLACE; fCmdType=scmd_replace; break; case sop_archive_delete: fSyncOpElementP->flags |= SmlArchive_f; goto dodelete; case sop_soft_delete: fSyncOpElementP->flags |= SmlSftDel_f; case sop_delete: dodelete: fSyncOpElementP->elementType=SML_PE_DELETE; fCmdType=scmd_delete; break; default: SYSYNC_THROW(TSyncException("Invalid SyncOp in TSyncOpCommand")); //break; } // switch } // TSyncOpCommand::TSyncOpCommand #ifndef USE_SML_EVALUATION // get (approximated) message size required for sending it uInt32 TSyncOpCommand::messageSize(void) { // default, should be enough for most commands return TSmlCommand::messageSize()+fItemSizes; } #endif // handle status received for previously issued command // returns true if done, false if command must be kept in the status queue bool TSyncOpCommand::handleStatus(TStatusCommand *aStatusCmdP) { // check if this is a split command if (fIncompleteData) { // must be 213 if (aStatusCmdP->getStatusCode()==213) return true; // something wrong, we did not get a 213 PDEBUGPRINTFX(DBG_ERROR,("chunked object received status %hd instead of 213 --> aborting session",aStatusCmdP->getStatusCode())); // reason for aborting is incomplete command (reception) fSessionP->AbortSession(412,true); // local problem } else { // end of non-split SyncOp means that possibly saved // parts of partial outgoing item are now obsolete if (fDataStoreP->fPartialItemState==pi_state_save_outgoing) { fDataStoreP->fPartialItemState=pi_state_none; // not any more PDEBUGPRINTFX(DBG_PROTO+DBG_EXOTIC,("chunked object received final status %hd --> forget partial item data now",aStatusCmdP->getStatusCode())); // - forget stored data in case we have any if (fDataStoreP->fPIStoredDataP) { if (fDataStoreP->fPIStoredDataAllocated) smlLibFree(fDataStoreP->fPIStoredDataP); fDataStoreP->fPIStoredDataP=NULL; fDataStoreP->fPIStoredDataAllocated=false; // not any more } // - clear URIs fDataStoreP->fLastSourceURI.erase(); fDataStoreP->fLastTargetURI.erase(); // - clear other flags fDataStoreP->fLastItemStatus=0; // none left to send fDataStoreP->fPITotalSize=0; fDataStoreP->fPIUnconfirmedSize=0; fDataStoreP->fPIStoredSize=0; } } // let datastore handle this // Note: as fDataStoreP is linked to the generating datastore, this will never be // a superdatastore. engHandleSyncOpStatus() is prepared to convert // superID prefixed localIDs back to subDS's localID bool handled=false; if (fDataStoreP) { handled=fDataStoreP->engHandleSyncOpStatus(aStatusCmdP,this); } if (!handled) { // let base class handle it handled=TSmlCommand::handleStatus(aStatusCmdP); } return handled; } // TSyncOpCommand::handleStatus // mark any syncitems (or other data) for resume. Called for pending commands // when a Suspend alert is received or whenever a resumable state must be saved void TSyncOpCommand::markPendingForResume(TLocalEngineDS *aForDatastoreP, bool aUnsent) { // only act if this is for our local datastore, and only outgoing ones! if (fOutgoing && fDataStoreP==aForDatastoreP && fSyncOpElementP) { // go through all of my items SmlItemListPtr_t itemListP = fSyncOpElementP->itemList; SmlItemPtr_t itemP; while (itemListP) { itemP=itemListP->item; if (itemP) { // call datastore to mark this one for resume fDataStoreP->engMarkItemForResume( smlSrcTargLocURIToCharP(itemP->source), // source for outgoing items is localID smlSrcTargLocURIToCharP(itemP->target), // target for outgoing items is remoteID fIncompleteData ? true : aUnsent // if not completely sent yet, always treat it as unsent! ); } itemListP=itemListP->next; } } } // TSyncOpCommand::markPendingForResume // mark item for resend in next sync session (if possible) void TSyncOpCommand::markForResend(void) { if (fOutgoing && fDataStoreP) { // go through all of my items SmlItemListPtr_t itemListP = fSyncOpElementP->itemList; SmlItemPtr_t itemP; while (itemListP) { itemP=itemListP->item; if (itemP) { // call datastore to mark this one for resume fDataStoreP->engMarkItemForResend( smlSrcTargLocURIToCharP(itemP->source), // source for outgoing items is localID smlSrcTargLocURIToCharP(itemP->target) // target for outgoing items is remoteID ); } itemListP=itemListP->next; } } } // TSyncOpCommand::markForResend // let item update the partial item state for suspend // Note: this may only be called for an item that is actually the partial item void TSyncOpCommand::updatePartialItemState(TLocalEngineDS *aForDatastoreP) { if (!fOutgoing && fDataStoreP==aForDatastoreP && fDataStoreP->dsResumeChunkedSupportedInDB()) { // save info for only partially received item fDataStoreP->fLastItemStatus = 0; // no status sent yet // pass current item data // - get last item data SmlItemListPtr_t itemnodeP=fSyncOpElementP->itemList; while (itemnodeP) { if (!itemnodeP->next) { // this is the last item fDataStoreP->fPartialItemState=pi_state_save_incoming; // - get total expected size fDataStoreP->fPITotalSize=0; SmlMetInfMetInfPtr_t metaP = smlPCDataToMetInfP(itemnodeP->item->meta); if (!metaP || !metaP->size) { // item has no meta or no meta-size, so size must be in meta of command metaP = smlPCDataToMetInfP(fSyncOpElementP->meta); } if (metaP) smlPCDataToULong(metaP->size, fDataStoreP->fPITotalSize); // - get data if (itemnodeP->item && itemnodeP->item->data) { // dispose current contents if these were separately allocated // (otherwise, we can just overwrite the pointer) if (fDataStoreP->fPIStoredDataP && fDataStoreP->fPIStoredDataAllocated) smlLibFree(fDataStoreP->fPIStoredDataP); // datastore does NOT get owner of the data! fDataStoreP->fPIStoredDataAllocated=false; // we still own that data, session must NOT try to dispose! fDataStoreP->fPIStoredSize=itemnodeP->item->data->length; fDataStoreP->fPIStoredDataP=itemnodeP->item->data->content; } // - get amount of stored data that is unconfirmed // (=the size of the most recently received chunk. This is unconfirmed // until the next chunk arrives, because we don't know before that if the // status 213 has reached the sender) fDataStoreP->fPIUnconfirmedSize=fLastChunkSize; // summarize PDEBUGPRINTFX(DBG_ADMIN,( "State of partially received item: total size=%ld, received=%ld, unconfirmed=%ld", (long)fDataStoreP->fPITotalSize, (long)fDataStoreP->fPIStoredSize, (long)fDataStoreP->fPIUnconfirmedSize )); // done break; } itemnodeP=itemnodeP->next; } // while } } // TSyncOpCommand::updatePartialItemState // get source (localID) of sent command cAppCharP TSyncOpCommand::getSourceLocalID(void) { if (!fSyncOpElementP) return NULL; if (!fSyncOpElementP->itemList) return NULL; if (!fSyncOpElementP->itemList->item) return NULL; return smlSrcTargLocURIToCharP(fSyncOpElementP->itemList->item->source); } // TSyncOpCommand::getSourceLocalID // get target (remoteID) of sent command cAppCharP TSyncOpCommand::getTargetRemoteID(void) { if (!fSyncOpElementP) return NULL; if (!fSyncOpElementP->itemList) return NULL; if (!fSyncOpElementP->itemList->item) return NULL; return smlSrcTargLocURIToCharP(fSyncOpElementP->itemList->item->target); } // TSyncOpCommand::getTargetRemoteID // add an Item to the sync op command void TSyncOpCommand::addItem( SmlItemPtr_t aItemP // existing item data structure, ownership is passed to SyncOp command ) { // add item if (fSyncOpElementP) { addItemToList(aItemP,&(fSyncOpElementP->itemList)); #ifndef USE_SML_EVALUATION fItemSizes += ITEMOVERHEADSIZE + strlen(smlSrcTargLocURIToCharP(aItemP->target)) + strlen(smlSrcTargLocNameToCharP(aItemP->target)) + strlen(smlSrcTargLocURIToCharP(aItemP->source)) + strlen(smlSrcTargLocNameToCharP(aItemP->source)); SmlMetInfMetInfPtr_t metaP = smlPCDataToMetInfP(aItemP->meta); if (metaP) fItemSizes+=strlen(smlPCDataToCharP(metaP->type)); if (aItemP->data) fItemSizes+=aItemP->data->length; #endif } } // TSyncOpCommand::addItem // helper: add dataPos EMI to meta static void addDataPos(SmlMetInfMetInfPtr_t aMetaP, uInt32 aDataPos) { // - find end of emi list or existing datapos SmlPcdataListPtr_t *emiPP = &(aMetaP->emi); /* version that searches for existing datapos and will replace it while (*emiPP!=NULL) { if (strucmp(smlPCDataToCharP((*emiPP)->data),"datapos=",8)==0) { // found existing datapos break; } emiPP = &((*emiPP)->next); } if (*emiPP==NULL) { // - add new EMI *emiPP=(SmlPcdataListPtr_t)smlLibMalloc(sizeof(SmlPcdataList_t)); (*emiPP)->next=NULL; } else { // - replace existing smlFreePcdata((*emiPP)->data); } */ while (*emiPP!=NULL) emiPP = &((*emiPP)->next); // - add new EMI list element *emiPP=(SmlPcdataListPtr_t)smlLibMalloc(sizeof(SmlPcdataList_t)); (*emiPP)->next=NULL; // - set new data string s; StringObjPrintf(s,"datapos=%ld",(long)aDataPos); (*emiPP)->data = newPCDataString(s.c_str(),s.size()); } // addDataPos void TSyncOpCommand::saveAsPartialItem(SmlItemPtr_t aItemP) { // - forget stored data in case we have any if (fDataStoreP->fPIStoredDataP) { if (fDataStoreP->fPIStoredDataAllocated) smlLibFree(fDataStoreP->fPIStoredDataP); fDataStoreP->fPIStoredDataP=NULL; fDataStoreP->fPIStoredDataAllocated=false; // not any more } // save only when we can actually store chunk resume data if (fDataStoreP->dsResumeChunkedSupportedInDB()) { // - save URIs fDataStoreP->fLastSourceURI=smlSrcTargLocURIToCharP(aItemP->source); fDataStoreP->fLastTargetURI=smlSrcTargLocURIToCharP(aItemP->target); // - copy current item's data now (before the split!) fDataStoreP->fPIStoredDataAllocated=true; // separately allocated buffer, not connected with item any more fDataStoreP->fPIStoredSize=aItemP->data->length; // length of unsplitted item's buffer fDataStoreP->fPIStoredDataP=smlLibMalloc(aItemP->data->length); smlLibMemcpy((uInt8 *)fDataStoreP->fPIStoredDataP,aItemP->data->content,aItemP->data->length); // - set other flags fDataStoreP->fLastItemStatus=0; // none left to send fDataStoreP->fPartialItemState=pi_state_save_outgoing; fDataStoreP->fPITotalSize=fChunkedItemSize; fDataStoreP->fPIUnconfirmedSize=fDataStoreP->fPIStoredSize; // just a copy } } // TSyncOpCommand::saveAsPartialItem // - possibly substitute data with previous session's buffered left-overs from a chunked transfer // for resuming a chunked item transfer. bool TSyncOpCommand::checkChunkContinuation(void) { if (fChunkedItemSize==0 && fDataStoreP && fDataStoreP->fPartialItemState==pi_state_loaded_outgoing) { // this is a so far unchunked item, and there is // to-be-resent data from the previously suspended session // - check if the command contains the partially sent item SmlItemListPtr_t itemListP = fSyncOpElementP->itemList; while (itemListP) { if ( itemListP->item && strcmp(smlSrcTargLocURIToCharP(itemListP->item->source),fDataStoreP->fLastSourceURI.c_str())==0 && strcmp(smlSrcTargLocURIToCharP(itemListP->item->target),fDataStoreP->fLastTargetURI.c_str())==0 ) { // detected to-be-continued chunked item PDEBUGPRINTFX(DBG_PROTO+DBG_HOT,( "Resuming sending chunked item Source='%s', Target='%s' -> replacing data with rest from suspended session", fDataStoreP->fLastSourceURI.c_str(), fDataStoreP->fLastTargetURI.c_str() )); // Do not send meta size on all but first chunk SmlMetInfMetInfPtr_t metinfP = itemListP->item->meta ? (SmlMetInfMetInfPtr_t)(itemListP->item->meta->content) : NULL; if (metinfP && metinfP->size) { smlFreePcdata(metinfP->size); metinfP->size=NULL; } // But make sure item knows the original total size (prevents splitCommand to add meta size again) fChunkedItemSize = fDataStoreP->fPITotalSize; // now add dataPos as : fPITotalSize-fPIStoredSize // - make sure we have meta if (!metinfP) { itemListP->item->meta=newMeta(); metinfP=(SmlMetInfMetInfPtr_t)(itemListP->item->meta->content); } // - add it (total - what remains to be sent) addDataPos(metinfP,fDataStoreP->fPITotalSize-fDataStoreP->fPIStoredSize); // update buffered data info if (itemListP->item->data) { // substitute original data with buffered rest of data from last session // (so in case the item has changed in the local DB, we'll still send the original data of // which the receiver already has seen a part) PDEBUGPRINTFX(DBG_PROTO+DBG_DETAILS,( "original data size of item=%ld, total size at time of suspend=%ld, rest being sent now=%ld", (long)itemListP->item->data->length, // current total size (long)fDataStoreP->fPITotalSize, // total size at time of suspend (long)fDataStoreP->fPIStoredSize // what we will send now )); // dispose current data smlLibFree(itemListP->item->data->content); // set new data from last session itemListP->item->data->length=fDataStoreP->fPIStoredSize; itemListP->item->data->content=fDataStoreP->fPIStoredDataP; // data is now owned by item fDataStoreP->fPIStoredDataP=NULL; fDataStoreP->fPIStoredSize=0; fDataStoreP->fPIStoredDataAllocated=false; } else { PDEBUGPRINTFX(DBG_ERROR,("WARNING: internal error: to-be-resumed item contains no data?")); } fDataStoreP->fPartialItemState=pi_state_none; // consumed now fDataStoreP->fPITotalSize=0; fDataStoreP->fPIUnconfirmedSize=0; // substitution of item data done // (don't check other items - we have ONE item only, anyway in the current implementation) return true; } // next item itemListP=itemListP->next; } } // no chunk continuation return false; } // TSyncOpCommand::checkChunkContinuation // check if split is possible at all bool TSyncOpCommand::canSplit(void) { // Sync Op commands can be split when remote supports mechanism return fSessionP->fRemoteSupportsLargeObjects; } // - try to split (e.g. by SyncML 1.1 moredata mechanism) command by reducing // original command by at least aReduceByBytes and generating a second // command containing the rest of the data // Returns NULL if split is not possible or not worth trying in the current situation // (e.g.: only ridiculously small part would remain) TSmlCommand *TSyncOpCommand::splitCommand(sInt32 aReduceByBytes) { SmlItemListPtr_t *itemListPP; TSyncOpCommand *remainingDataCmdP=NULL; // nothing remaining so far SmlItemListPtr_t remainingItems=NULL; // check other conditions if (!fSyncOpElementP) return NULL; // now find where we should split do { // start of list itemListPP = &(fSyncOpElementP->itemList); // check if any items if (*itemListPP==NULL) break; // no more items // find last item while ((*itemListPP)->next) itemListPP = &((*itemListPP)->next); // get it's data SmlItemPtr_t itemP = (*itemListPP)->item; SmlPcdataPtr_t dataP = itemP->data; // check if we should split this item if ( canSplit() && // remote can handle large objects (that is: chunked transfers) dataP && // there is data dataP->contentType!=SML_PCDATA_EXTENSION && // it's not an extension dataP->length > aReduceByBytes+MIN_SPLIT_DATA // remaining length of first part is large enough to make splitting worth doing now ) { // split within this item // Prepare original item // - make sure we have meta if (!itemP->meta) itemP->meta = newMeta(); // create meta as we haven't got one yet SmlMetInfMetInfPtr_t metinfP = (SmlMetInfMetInfPtr_t)(itemP->meta->content); // - set size if this is the first chunk if (metinfP->size) smlFreePcdata(metinfP->size); if (fChunkedItemSize==0) { // first chunk // - set dataPos to 0 addDataPos(metinfP,0); // Note: we don't need to buffer when sending the first chunk. // If we get suspended before the second chunk is being generated, the item will // start over from beginning anyway (and we can use data from the DB). fChunkedItemSize=dataP->length; metinfP->size=newPCDataLong(fChunkedItemSize); PDEBUGPRINTFX(DBG_PROTO+DBG_HOT,( "Item data too big (%ld) - must be chunked using , %ld bytes to be sent later", (long)fChunkedItemSize, (long)aReduceByBytes )); #ifdef SYDEBUG // %%% should not happen, but I'm not sure it really won't if (fDataStoreP->fPartialItemState==pi_state_loaded_outgoing) { PDEBUGPRINTFX(DBG_ERROR,("WARNING - internal error: Splitting new item apparently before previous session's item has been resent")); } #endif } else { // this item is NOT the first chunk -> save stuff we need to PDEBUGPRINTFX(DBG_PROTO+DBG_HOT,( "Remaining data still too big (%ld/%ld) - must be chunked again, %ld bytes to be sent later", (long)dataP->length, (long)fChunkedItemSize, (long)aReduceByBytes )); // Note: in this case, the item already has a dataPos - no need to add one here! // Resume the item in the middle rather than resending it in full. // IMPORTANT: It is essential not to store the fLastSourceURI/fLastTargetURI // on the first chunk, as it then probably still contains info from // the previous session. saveAsPartialItem(itemP); } // - set itemP->flags |= SmlMoreData_f; // - create new data for original item (original data is in dataP) itemP->data = newPCDataStringX( (uInt8 *)dataP->content, // original data dataP->contentType==SML_PCDATA_OPAQUE, // opaque if original was opaque dataP->length-aReduceByBytes // reduced length ); // Create additional item for next message // - new item SmlItemPtr_t nextItemP = newItem(); // - with meta nextItemP->meta = newMeta(); SmlMetInfMetInfPtr_t nextMetinfP = (SmlMetInfMetInfPtr_t)(nextItemP->meta->content); // - SyncML 1.1.1: The element MUST only be specified in the first chunk of the item. nextMetinfP->size=NULL; // no size in remaining items // - copy other meta if (metinfP->maxobjsize) nextMetinfP->format=newPCDataString(smlPCDataToCharP(metinfP->maxobjsize)); // We NEED this one of ZIPPED_BINDATA_SUPPORT! if (metinfP->format) nextMetinfP->format=newPCDataString(smlPCDataToCharP(metinfP->format)); if (metinfP->type) nextMetinfP->type=newPCDataString(smlPCDataToCharP(metinfP->type)); if (metinfP->mark) nextMetinfP->mark=newPCDataString(smlPCDataToCharP(metinfP->mark)); //%%% if we ever decide to carry over EMI here, make sure we don't copy dataPos=x, as // addDataPos() code relies on no dataPos being present when called. //if (metinfP->emi) nextMetinfP->emi=newPCDataString(smlPCDataToCharP(metinfP->emi)); // %%% not needed yet if (metinfP->version) nextMetinfP->version=newPCDataString(smlPCDataToCharP(metinfP->version)); // - copy source and target nextItemP->target=newOptLocation(smlSrcTargLocURIToCharP(itemP->target),smlSrcTargLocNameToCharP(itemP->target)); nextItemP->source=newOptLocation(smlSrcTargLocURIToCharP(itemP->source),smlSrcTargLocNameToCharP(itemP->source)); // - copy flags except nextItemP->flags = itemP->flags & ~SmlMoreData_f; // - now copy rest of data nextItemP->data = newPCDataStringX( (uInt8 *)dataP->content + dataP->length-aReduceByBytes, // original data minus what we have in original item dataP->contentType==SML_PCDATA_OPAQUE, // opaque if original was opaque aReduceByBytes // reduced length = remaining bytes ); // - original data can now be disposed smlFreePcdata(dataP); // Add correct data position to the next item now. addDataPos(nextMetinfP,fChunkedItemSize-aReduceByBytes); // Now insert new item containing remaining data to beginning of list for next chunk SmlItemListPtr_t ilP = SML_NEW(SmlItemList_t); ilP->next=remainingItems; ilP->item=nextItemP; remainingItems=ilP; // count reduction aReduceByBytes=0; // done break; } else { // Split between items fChunkedItemSize=0; // no chunking in progress now // - get last itemlist element SmlItemListPtr_t ilP = *itemListPP; // - cut it out of original list *itemListPP=NULL; // - put it at the BEGINNING of the remaining items list ilP->next=remainingItems; remainingItems=ilP; // - count reduction aReduceByBytes -= dataP ? dataP->length : 0; // loop to check second-last item } // repeat as long as reduction goal is not met } while (aReduceByBytes>0); // check if any items left in original command if (fSyncOpElementP->itemList == NULL) { // none left in original list, can't split // - put back remaining list to original item fSyncOpElementP->itemList = remainingItems; // - cannot split return NULL; } // now create new command containing the remaining items if (remainingItems) { if (aReduceByBytes<=0) { // duplicate meta SmlPcdataPtr_t splitMetaP = copyMeta(fSyncOpElementP->meta); // make new command remainingDataCmdP = new TSyncOpCommand( fSessionP, // associated session (for callbacks) fDataStoreP, // datastore from which command originates fSyncOp, // sync operation (=command type) splitMetaP // meta for entire command (passing owner) ); // now pass remaining items to new command remainingDataCmdP->fSyncOpElementP->itemList = remainingItems; // next command must know that it part of a chunked transfer remainingDataCmdP->fChunkedItemSize = fChunkedItemSize; // original command must know that it must expect a 213 status fIncompleteData = true; } else { // remaining items not used, delete them smlFreeItemList(remainingItems); } } // return split-off command return remainingDataCmdP; } // TSyncOpCommand::splitCommand // - test if completely issued (must be called after issue() and continueIssue()) bool TSyncOpCommand::finished(void) { return (fOutgoing) || // outgoing commands are always finished (new split mechanism actually splits the command in two separate commands) (!fOutgoing && fSessionP->fIncompleteDataCommandP!=this); // not part of an incoming chunked data transfer } // TSyncOpCommand::finished // analyze command (but do not yet execute) bool TSyncOpCommand::analyze(TPackageStates aPackageState) { TSmlCommand::analyze(aPackageState); // get Command ID and flags if (fSyncOpElementP) { StartProcessing(fSyncOpElementP->cmdID,fSyncOpElementP->flags); return true; } else return false; // no proto element, bad command } // TSyncOpCommand::analyze // Adds data chunk from specified command to this (incomplete) command // includes checking if sync op and item source/target match and // checks for size match #define MISSING_END_OF_CHUNK_ERROR 223 // End of Data for chunked object not received localstatus TSyncOpCommand::AddNextChunk(SmlItemPtr_t aNextChunkItem, TSyncOpCommand *aCmdP) { SmlItemListPtr_t incompletenode; SmlItemPtr_t incompleteitem; SmlPcdataPtr_t newdata; localstatus sta; // find last item in this command incompletenode = fSyncOpElementP->itemList; if (!incompletenode) return 412; // incomplete command while (incompletenode && incompletenode->next) incompletenode=incompletenode->next; incompleteitem = incompletenode->item; // check for data integrity if (!incompleteitem) return 412; if (!incompleteitem->data) return 412; if (!aNextChunkItem) return 412; if (!aNextChunkItem->data) return 412; // check for item compatibility // - commands must have same sync op if (getSyncOp() != aCmdP->getSyncOp()) goto missingeoc; // not a status - will be converted to alert // - must have same source and target URI if ( strcmp(smlSrcTargLocURIToCharP(incompleteitem->source),smlSrcTargLocURIToCharP(aNextChunkItem->source))!=0 || strcmp(smlSrcTargLocURIToCharP(incompleteitem->target),smlSrcTargLocURIToCharP(aNextChunkItem->target))!=0 ) goto missingeoc; // not a status - will be converted to alert // - must have same PCData type and not extension if ( incompleteitem->data->contentType != aNextChunkItem->data->contentType || aNextChunkItem->data->contentType == SML_PCDATA_EXTENSION ) return 400; // originator error, bad request // append data from next chunk to incomplete item newdata = SML_NEW(SmlPcdata_t); // - same content type as previous data had newdata->contentType = incompleteitem->data->contentType; newdata->contentType = incompleteitem->data->contentType; // - set new size newdata->length = incompleteitem->data->length + aNextChunkItem->data->length; // - remember size of chunk we're adding now in the incomplete command aCmdP->fLastChunkSize = aNextChunkItem->data->length; // - allocate new data for updated item (including an extra NUL terminator) newdata->content=smlLibMalloc(newdata->length+1); if (newdata->content==NULL) return 413; // request entity too large // - copy existing content smlLibMemcpy(newdata->content,incompleteitem->data->content,incompleteitem->data->length); // - add new chunk smlLibMemcpy((uInt8 *)newdata->content+incompleteitem->data->length,aNextChunkItem->data->content,aNextChunkItem->data->length); // - set the NUL terminator in case item is parsed as C string *(((uInt8 *)newdata->content)+newdata->length)=0; // - free old data in item smlFreePcdata(incompleteitem->data); // - insert updated data incompleteitem->data = newdata; // Now check if we are complete if ((aNextChunkItem->flags & SmlMoreData_f) == 0) { // end of chunk, verify size // - get total size from meta (of original item) SmlMetInfMetInfPtr_t metaP = smlPCDataToMetInfP(incompleteitem->meta); if (!metaP || !metaP->size) { // item has no meta or no meta-size, so size must be in meta of command metaP = smlPCDataToMetInfP(fSyncOpElementP->meta); if (!metaP) { PDEBUGPRINTFX(DBG_ERROR,("Chunked item has no meta -> no size found")); return 424; // no meta: Size mismatch } } sInt32 expectedSize; if (!smlPCDataToLong(metaP->size, expectedSize)) { PDEBUGPRINTFX(DBG_ERROR,("Chunked item had no or invalid meta in first chunk")); return 424; // bad size string: size mismatch } // - check for size match if (incompleteitem->data->length != expectedSize) { // check if size mismatch could be due to duplicate transmit of unconfirmed data if (fUnconfirmedSize == uInt32(incompleteitem->data->length - expectedSize)) { // size mismatch is exactly what could be caused by duplicate transmit PDEBUGPRINTFX(DBG_PROTO+DBG_HOT,( "Detected duplicate chunk in reassembled item due to resume without dataPos (%ld bytes at %ld) -> adjusting", (long)fUnconfirmedSize, (long)fStoredSize-fUnconfirmedSize )); // - cut out duplicate smlLibMemmove( ((uInt8 *)incompleteitem->data->content+fStoredSize-fUnconfirmedSize), // to end of confirmed data ((uInt8 *)incompleteitem->data->content+fStoredSize), // from end of stored data incompleteitem->data->length-fStoredSize // everything between end of stored data and end of item ); incompleteitem->data->length = expectedSize; // adjust length *((uInt8 *)incompleteitem->data->content+expectedSize)=0; // add new safety terminator fUnconfirmedSize=0; // no data unconfirmed any more } else { PDEBUGPRINTFX(DBG_ERROR,( "Chunked item has wrong size (%ld, expected=%ld) after reassembly", (long)incompleteitem->data->length, (long)expectedSize )); return 424; // size mismatch } } // successfully reassembled sta=0; } else { // not yet completely reassembled sta=213; } // get MsgID and CmdID from added chunk's commnd fCmdID = aCmdP->getCmdID(); fMsgID = aCmdP->getMsgID(); // copy actual cmdID tag (to make sure we don't get the wrong CmdID when re-processing the command later) smlFreePcdata(fSyncOpElementP->cmdID); // ged rid of current ID fSyncOpElementP->cmdID = smlPcdataDup(aCmdP->fSyncOpElementP->cmdID); // copy ID from last added chunk // return status code return sta; missingeoc: // missing end of chunk TAlertCommand *alertCmdP = new TAlertCommand(fSessionP, NULL, (uInt16)223); SmlItemPtr_t alertItemP = newItem(); alertItemP->target=newOptLocation(smlSrcTargLocURIToCharP(incompleteitem->source)); alertItemP->source=newOptLocation(smlSrcTargLocURIToCharP(incompleteitem->target)); alertCmdP->addItem(alertItemP); // issue the alert fSessionP->issueRootPtr(alertCmdP); // signal failure of reassembling chunked item return MISSING_END_OF_CHUNK_ERROR; } // TSyncOpCommand::AddNextChunk // SyncOp commands can execute out of order except when they // contain chunked items, because then we would have to issue // a 213 Status immediately, which would violate the ordering // of Status replies. bool TSyncOpCommand::canExecuteOutOfOrder() { SmlItemListPtr_t *itemnodePP=&(fSyncOpElementP->itemList); while (*itemnodePP) { SmlItemListPtr_t thisitemnode = *itemnodePP; if (thisitemnode->item && thisitemnode->item->flags & SmlMoreData_f) { return false; } itemnodePP = &(thisitemnode->next); } return true; } // execute command (perform real actions, generate status) // returns true if command has executed and can be deleted bool TSyncOpCommand::execute(void) { TStatusCommand *statusCmdP=NULL; SmlItemListPtr_t *itemnodePP, thisitemnode; localstatus sta; TSyncOpCommand *incompleteCmdP; bool queueforlater,processitem; bool nostatus; SmlItemListPtr_t tobequeueditems=NULL; SYSYNC_TRY { // get datastore pointer if we do not have one yet if (fDataStoreP==NULL) { // in case we did not get the pointer at creation - that is, when the enclosing // was delayed - we must now get datastore as set by the current command fDataStoreP = fSessionP->fLocalSyncDatastoreP; if (fDataStoreP==NULL) { statusCmdP=newStatusCommand(404); // no datastore, we can't process items for it ISSUE_COMMAND_ROOT(fSessionP,statusCmdP); return true; // command executed } } // get command meta if any SmlMetInfMetInfPtr_t cmdmetaP=smlPCDataToMetInfP(fSyncOpElementP->meta); // process items DEBUGPRINTFX(DBG_HOT,("command started processing")); itemnodePP=&(fSyncOpElementP->itemList); while (*itemnodePP) { queueforlater=false; // do no queue by default processitem=true; // process by default nostatus=false; // set to true if someone else is responsible for updating fLastItemStatus thisitemnode = *itemnodePP; // no result nor status so far statusCmdP=NULL; // check for NULL item if (!thisitemnode->item) { PDEBUGPRINTFX(DBG_ERROR,("command with NULL item")); statusCmdP=newStatusCommand(400); // protocol error ISSUE_COMMAND_ROOT(fSessionP,statusCmdP); return true; // command executed } // check if we are resuming a partially transmitted item (but MUST have data) if ( fSessionP->fIncompleteDataCommandP==NULL && thisitemnode->item->data && // item must have data fDataStoreP->fPartialItemState==pi_state_loaded_incoming && strcmp(smlSrcTargLocURIToCharP(thisitemnode->item->source),fDataStoreP->fLastSourceURI.c_str())==0 && strcmp(smlSrcTargLocURIToCharP(thisitemnode->item->target),fDataStoreP->fLastTargetURI.c_str())==0 ) { // this is the last item sent in the previously suspended session if (fDataStoreP->fPIStoredSize==0) { // No item was left only partially received from the suspended session. // But we must handle the special case where the final status of the last item sent // in the suspended session did not reach the recipient, so we now see the last chunk again. // In this case, simply re-issue the status and ignore the contents if (fDataStoreP->fLastItemStatus) { // item already processed, just repeat sending the status PDEBUGPRINTFX(DBG_PROTO,("Received last chunk for already processed item -> just resending status %hd",fDataStoreP->fLastItemStatus)); statusCmdP = newStatusCommand(fDataStoreP->fLastItemStatus); processitem=false; // do not further process the item, just status fDataStoreP->fPartialItemState=pi_state_none; // chunked transfer from last session finally done } } else { // we have a partially received item left from the suspended session // continue it PDEBUGPRINTFX(DBG_PROTO+DBG_HOT,( "Resuming receiving chunked item Source='%s', Target='%s'", fDataStoreP->fLastSourceURI.c_str(), fDataStoreP->fLastTargetURI.c_str() )); // simulate a meta size from suspended session's saved item size // - create meta if none there if (!thisitemnode->item->meta) thisitemnode->item->meta = newMeta(); // - now check/generate meta size SmlMetInfMetInfPtr_t metinfP = (SmlMetInfMetInfPtr_t)(thisitemnode->item->meta->content); if (metinfP->size) { #ifdef __MWERKS__ #warning "%%% maybe use presence of meta size to know that this is NOT resuming, that is as an implicit dataPos=0" #endif /* if I understand correctly, size MUST NOT be present on any but the first chunk. If that's correct, we could discard the saved partial item from a previous session in case we see a size (because this would mean the item is retransmitted as a whole and sender does not support resuming a partial item */ // item has meta size, check if correct uInt32 thissize; if ( !smlPCDataToULong(metinfP->size, thissize) || thissize!=fDataStoreP->fPITotalSize ) { PDEBUGPRINTFX(DBG_ERROR,( "Resumed item size does not match (expected=%ld, found=%ld)", (long)fDataStoreP->fPITotalSize, (long)thissize )); statusCmdP = newStatusCommand(424); processitem=false; // do not further process the item } } else { // item has no meta size, create it now metinfP->size=newPCDataLong(fDataStoreP->fPITotalSize); } SmlPcdataPtr_t newdata=NULL; uInt32 dataPos=0; if (processitem) { // save sizes confirmed/unconfirmed data in this command object // (for possible reassembly adjustment when command is complete) fUnconfirmedSize=fDataStoreP->fPIUnconfirmedSize; fStoredSize=fDataStoreP->fPIStoredSize; // Determine Data position // - check if we have it in EMI (Synthesis-Oracle enhancement) // datapos=NUM SmlPcdataListPtr_t emiP = metinfP->emi; // start with item meta EMI bool foundDataPos=false; for (uInt16 i=0; i<2; i++) { while (emiP) { if (emiP->data) { const char *p = smlPCDataToCharP(emiP->data); if (strucmp(p,"datapos=",8)==0) { // correct lead-in, get number now if (StrToULong(p+8,dataPos)>0) { PDEBUGPRINTFX(DBG_PROTO+DBG_DETAILS,("found datapos=%ld",(long)dataPos)); foundDataPos=true; // found dataPos break; } else { PDEBUGPRINTFX(DBG_ERROR,("invalid number in datapos, ignoring it")); } } } // check next emiP=emiP->next; } // done if found if (foundDataPos) break; // try with cmd meta if (!cmdmetaP) break; // we don't have a command meta, no point to search emiP = cmdmetaP->emi; // cmd meta EMI } if (foundDataPos) { // we have a dataPos value // - no unconfirmed size any more for this item (but we still need the datastore-level vars // below to do the copying fUnconfirmedSize=0; // - confirmed size is the data position now fStoredSize=dataPos; } else { // without known dataPos, we assume all received data confirmed for now // and will adjust at end of item if needed dataPos = fDataStoreP->fPIStoredSize; } // - check integrity if (dataPos>fDataStoreP->fPIStoredSize) { PDEBUGPRINTFX(DBG_ERROR,( "Data position invalid (max allowed=%ld, found=%ld)", (long)fDataStoreP->fPIStoredSize, (long)dataPos )); statusCmdP = newStatusCommand(412); processitem=false; // do not further process the item } if (processitem) { // - combine new and old data newdata = SML_NEW(SmlPcdata_t); // - same content type newdata->contentType = thisitemnode->item->data->contentType; // - set new size newdata->length = dataPos + thisitemnode->item->data->length; // - allocate new data for updated item (including an extra NUL terminator) newdata->content=smlLibMalloc(newdata->length+1); if (newdata->content==NULL) { statusCmdP = newStatusCommand(413); processitem=false; // do not further process the item } } } if (processitem) { // copy already received content up to dataPos smlLibMemcpy(newdata->content,fDataStoreP->fPIStoredDataP,dataPos); // forget data stored at DS level fDataStoreP->fPIStoredSize=0; if (fDataStoreP->fPIStoredDataP) { // only free if not owned by an item if (fDataStoreP->fPIStoredDataAllocated) smlLibFree(fDataStoreP->fPIStoredDataP); } fDataStoreP->fPIStoredDataP=NULL; // append content just received in this item smlLibMemcpy((uInt8 *)newdata->content+dataPos,thisitemnode->item->data->content,thisitemnode->item->data->length); // - set the NUL terminator in case item is parsed as C string *(((uInt8 *)newdata->content)+newdata->length)=0; // - free old data in item smlFreePcdata(thisitemnode->item->data); // - insert new data thisitemnode->item->data = newdata; } /* No, we need to keep pi_state_loaded_incoming until we get // Finished processing left-overs from last session fDataStoreP->fPartialItemState=pi_state_none; */ // Now we can treat this as if it was the first (or only) chunk of a non-resumed item } // if we have partial data received in last session } // if item is the same as last item in suspended session if (processitem) { processitem=false; // only process further if we detect complete data // check if this item is complete (not chunked by ) if (thisitemnode->item->flags & SmlMoreData_f) { // no, it's only a chunk if (thisitemnode->item->data==NULL) { PDEBUGPRINTFX(DBG_ERROR,("Chunked item has no ")); statusCmdP->setStatusCode(412); // do not further process the command, issue status and exit ISSUE_COMMAND_ROOT(fSessionP,statusCmdP); return true; // processed (with error) } // - return appropriate status statusCmdP = newStatusCommand(213); // chunked item accepted and buffered // - no items may follow the chunked one if (thisitemnode->next) { PDEBUGPRINTFX(DBG_ERROR,("Chunked item had additional items after the chunked one")); statusCmdP->setStatusCode(400); // do not further process the command, issue status and exit ISSUE_COMMAND_ROOT(fSessionP,statusCmdP); return true; // processed (with error) } if (fSessionP->fIncompleteDataCommandP==NULL) { // This is the first chunk, save this as the original command (as it contains all meta) fSessionP->fIncompleteDataCommandP = this; // make sure that already executed items will not get saved *itemnodePP=NULL; // disconnect not-yet-executed items from executed ones smlFreeItemList(fSyncOpElementP->itemList); // free executed items fSyncOpElementP->itemList = thisitemnode; // put not-yet-executed, partial item into command // make sure moredata flag is not set on reassembled item thisitemnode->item->flags &= ~SmlMoreData_f; // save size of the chunk fLastChunkSize=thisitemnode->item->data->length; } else { // this is a chunk in the middle, combine its data // with the already buffered incomplete command // and update MsgID/CmdID. If source and target do not match, // statusCmdP will set to appropriate error code sta=fSessionP->fIncompleteDataCommandP->AddNextChunk(thisitemnode->item,this); if (sta) statusCmdP->setStatusCode(sta); // set error if any } PDEBUGPRINTFX(DBG_PROTO+DBG_HOT,(" set: Chunk (%ld bytes) received (plus possible carry over from suspend) and buffered",(long)fLastChunkSize)); } else { // Complete item or end of chunked item processitem=true; incompleteCmdP = fSessionP->fIncompleteDataCommandP; if (incompleteCmdP) { // end of chunked item, add final chunk and check for errors sta=incompleteCmdP->AddNextChunk(thisitemnode->item,this); if (sta==MISSING_END_OF_CHUNK_ERROR) { // command should have been end of chunked data, but wasn't. // Alert 223 is already issued. // - dispose of failed incomplete command delete incompleteCmdP; fSessionP->fIncompleteDataCommandP=NULL; // - process item as new command } else if (sta==0) { // successfully reassembled command, execute it now PDEBUGPRINTFX(DBG_PROTO+DBG_HOT,("Last Chunk received (%ld bytes), item is reassembled",(long)fLastChunkSize)); // - first remove global link to it to avoid recursion fSessionP->fIncompleteDataCommandP=NULL; // - execute now (and pass ownership) // issues appropriate statuses, so we don't need to deal with it; // in fact, we must not touch fLastItemStatus because we don't // know the status nostatus=true; fSessionP->process(incompleteCmdP); // - this item is processed now, continue in loop if there are more items processitem=false; // do not process the item normally // Note: statusCmdP is NULL here, so no extra status will be issued for the // item (process() should have already caused appropriate statuses to // be generated. } else { // some error with this item, generate status statusCmdP = newStatusCommand(sta); PDEBUGPRINTFX(DBG_ERROR,("Adding next chunk to item failed with status=%hd",sta)); // - dispose of failed incomplete command delete incompleteCmdP; fSessionP->fIncompleteDataCommandP=NULL; // do not process anything any further processitem=false; // do not process the item normally fDataStoreP->fLocalItemsError++; // count this as an error } } else { // save size of the chunk (if item has ANY data at all) fLastChunkSize=thisitemnode->item->data ? thisitemnode->item->data->length : 0; } if (processitem) { // - get remote and local IDs of item const char *remoteID=smlSrcTargLocURIToCharP(thisitemnode->item->source); const char *localID=smlSrcTargLocURIToCharP(thisitemnode->item->target); // prepare OK status for item statusCmdP = newStatusCommand(200); // let session process the item PDEBUGPRINTFX(DBG_PROTO+DBG_HOT,( "Item (syncop: %s) started processing, remoteID='%s', localID='%s'", SyncOpNames[(sInt16)fSyncOp], remoteID, localID )); queueforlater=false; if (fSessionP->processSyncOpItem( fSyncOp, // the operation thisitemnode->item, // the item to be processed cmdmetaP, // command-wide meta, if any fDataStoreP, // related datastore pointer *statusCmdP, // pre-set 200 status, can be modified in case of errors queueforlater // set if processing of item must be done later )) { // fully ok (no internal change of requested operations or // silent acceptance of deleting non-existant item) } else { // Internal processing of items showed some irregularity, but // status to remote peer can still be ok (for example when trying // to delete non-existant item in datastore with incomplete rollbacks, // processSyncOpItem() will return false, but Status=200. PDEBUGPRINTFX(DBG_PROTO,( "Irregularity in execution of item, status=%hd", statusCmdP->getStatusCode() )); } } // if processitem } // if complete item } // if processitem // now generate status or queue for later // - remember as last item for possible suspend and resume fDataStoreP->fLastSourceURI = smlSrcTargLocURIToCharP(thisitemnode->item->source); fDataStoreP->fLastTargetURI = smlSrcTargLocURIToCharP(thisitemnode->item->target); if (queueforlater) { PDEBUGPRINTFX(DBG_PROTO,( "Item could not be processed completely now -> will be queued for later processing" )); // item processing could not complete, we must queue this and all other items // in this command for later processing. However, re-assembling chunked // items must proceed as normal. fDataStoreP->fLastItemStatus = 0; // no status sent yet // Therefore, we move this item from the original list to a list of to-be-queued items addItemToList( thisitemnode->item, // the item &tobequeueditems // place pointer to next node here ); // cut item out of original list to make sure it does not get disposed with it // - itemnodePP points to pointer to list start or a "next" pointer in a node // (which in turn points to thisitemnode). Now let it point to the next item node. // - this also advance processing to the next item *itemnodePP = thisitemnode->next; // - dispose of the item node itself thisitemnode->next=NULL; // disconnect subsequent nodes thisitemnode->item=NULL; // disconnect item (which is now in tobequeueditems list) smlFreeItemList(thisitemnode); // dispose of node // - and the status command delete statusCmdP; statusCmdP = NULL; } else { // count incoming net data if (thisitemnode->item->data) { fDataStoreP->fIncomingDataBytes+=thisitemnode->item->data->length; } // item processed // - remember status (final only) for possible suspend and resume sta= statusCmdP ? statusCmdP->getStatusCode() : 0; if (!nostatus && sta!=213) { // final status received, save it for possible resend fDataStoreP->fLastItemStatus = sta; // but forget data stored at DS level fDataStoreP->fPIStoredSize=0; if (fDataStoreP->fPIStoredDataP) { // only free if not owned by an item if (fDataStoreP->fPIStoredDataAllocated) smlLibFree(fDataStoreP->fPIStoredDataP); } fDataStoreP->fPIStoredDataP=NULL; // make sure it gets saved fDataStoreP->fPartialItemState = pi_state_save_incoming; } // - issue status for it if (statusCmdP) { // add source and target refs of item statusCmdP->addTargetRef(smlSrcTargLocURIToCharP(thisitemnode->item->target)); // add target ref statusCmdP->addSourceRef(smlSrcTargLocURIToCharP(thisitemnode->item->source)); // add source ref // issue ISSUE_COMMAND_ROOT(fSessionP,statusCmdP); } // advance to next item in list itemnodePP = &(thisitemnode->next); } } // item loop // free this one in advance (only if command is finished) if (finished() && !tobequeueditems) FreeSmlElement(); // update item list in command for queuing if needed if (tobequeueditems) { // there are to-be-queued items, insert them instead of the original item list // - delete current item list (only contains already processed and statused items) smlFreeItemList(fSyncOpElementP->itemList); // - insert to be queued items instead fSyncOpElementP->itemList=tobequeueditems; } } SYSYNC_CATCH (...) // make sure owned objects in local scope are deleted if (statusCmdP) delete statusCmdP; // re-throw SYSYNC_RETHROW; SYSYNC_ENDCATCH // if not all items could be executed, command must be queued for later re-execution. // (all successfully executed items are already deleted from the item list) return !tobequeueditems; } // TSyncOpCommand::execute // returns true if command must be put to the waiting-for-status queue. // If false, command does not need to be put into waiting-for-status queue // and can be deleted if finished() returns true bool TSyncOpCommand::issue( uInt32 aAsCmdID, // command ID to be used uInt32 aInMsgID, // message ID in which command is being issued bool aNoResp // dummy here, because Status has always no response ) { // prepare basic stuff TSmlCommand::issue(aAsCmdID,aInMsgID,aNoResp); // now issue if (fSyncOpElementP) { // issue command with SyncML toolkit (no flags) PrepareIssue(&fSyncOpElementP->cmdID,&fSyncOpElementP->flags); // CmdID and flags Ret_t err; InstanceID_t wspid = fSessionP->getSmlWorkspaceID(); switch (fCmdType) { case scmd_add: #ifdef SYDEBUG if (fSessionP->fXMLtranslate && fSessionP->fOutgoingXMLInstance && !fEvalMode) smlAddCmd(fSessionP->fOutgoingXMLInstance,fSyncOpElementP); #endif err=smlAddCmd(wspid,fSyncOpElementP); break; #ifdef COPY_SEND case scmd_copy: #ifdef SYDEBUG if (fSessionP->fXMLtranslate && fSessionP->fOutgoingXMLInstance && !fEvalMode) smlCopyCmd(fSessionP->fOutgoingXMLInstance,fSyncOpElementP); #endif err=smlCopyCmd(wspid,fSyncOpElementP); break; #endif case scmd_move: #ifdef SYDEBUG if (fSessionP->fXMLtranslate && fSessionP->fOutgoingXMLInstance && !fEvalMode) smlMoveCmd(fSessionP->fOutgoingXMLInstance,fSyncOpElementP); #endif err=smlMoveCmd(wspid,fSyncOpElementP); break; case scmd_replace: #ifdef SYDEBUG if (fSessionP->fXMLtranslate && fSessionP->fOutgoingXMLInstance && !fEvalMode) smlReplaceCmd(fSessionP->fOutgoingXMLInstance,fSyncOpElementP); #endif err=smlReplaceCmd(wspid,fSyncOpElementP); break; case scmd_delete: #ifdef SYDEBUG if (fSessionP->fXMLtranslate && fSessionP->fOutgoingXMLInstance && !fEvalMode) smlDeleteCmd(fSessionP->fOutgoingXMLInstance,fSyncOpElementP); #endif err=smlDeleteCmd(wspid,fSyncOpElementP); break; default: SYSYNC_THROW(TSyncException("TSyncOpCommand:issue, bad command type")); } if (!fEvalMode) { if (err!=SML_ERR_OK) { SYSYNC_THROW(TSmlException("smlAdd/Copy/Replace/DeleteCmd",err)); } FinalizeIssue(); // show items SmlItemListPtr_t itemP = fSyncOpElementP->itemList; while (itemP) { // count net data sent sInt32 itemlen=0; if (itemP->item && itemP->item->data) { itemlen=itemP->item->data->length; fDataStoreP->fOutgoingDataBytes+=itemlen; } // show item source and target PDEBUGPRINTFX(DBG_PROTO,( "Item remoteID='%s', localID='%s', datasize=%ld", smlSrcTargLocURIToCharP(itemP->item->target), smlSrcTargLocURIToCharP(itemP->item->source), (long)itemlen )); if (fChunkedItemSize>0 && !fIncompleteData) { #ifdef SYDEBUG PDEBUGPRINTFX(DBG_PROTO+DBG_HOT,( "Last Chunk (%ld bytes) of large object (%ld total) sent now - retaining it in case of implicit suspend", (long)itemlen, (long)fChunkedItemSize )); #endif if (itemlen>0) saveAsPartialItem(itemP->item); } // next itemP=itemP->next; } // we don't need the data any more, but we should keep the source and target IDs until we have the status // - get rid of data if (fSyncOpElementP->itemList) { // - free possible extra items (shouldn't be any - we always send single item per command) smlFreeItemList(fSyncOpElementP->itemList->next); fSyncOpElementP->itemList->next=NULL; // - free data and meta part of this item, but not target and source info if (fSyncOpElementP->itemList->item) { smlFreePcdata(fSyncOpElementP->itemList->item->meta); fSyncOpElementP->itemList->item->meta=NULL; smlFreePcdata(fSyncOpElementP->itemList->item->data); fSyncOpElementP->itemList->item->data=NULL; } } } else return err==SML_ERR_OK; // ok if evaluation had no error } else { DEBUGPRINTFX(DBG_ERROR,("*** Tried to issue NULL status")); } // sync op commands do need status return true; // queue for status } // TSyncOpCommand::issue void TSyncOpCommand::FreeSmlElement(void) { // remove SyncML toolkit element(s) FREEPROTOELEMENT(fSyncOpElementP); } // TSyncOpCommand::FreeSmlElement TSyncOpCommand::~TSyncOpCommand() { // free command elements, if any (use explicit invocation as this is a destructor) TSyncOpCommand::FreeSmlElement(); } // TSyncOpCommand::~TSyncOpCommand /* end of TSyncOpCommand implementation */ #endif // SYNCCOMMAND_PART1_EXCLUDE #ifndef SYNCCOMMAND_PART2_EXCLUDE /* * Implementation of TMapCommand */ // constructor for receiving Map command TMapCommand::TMapCommand( TSyncSession *aSessionP, // associated session (for callbacks) uInt32 aMsgID, // the Message ID of the command SmlMapPtr_t aMapElementP // associated syncml protocol element ) : TSmlCommand(scmd_map,false,aSessionP,aMsgID) { // save element fMapElementP = aMapElementP; fInProgress=false; // just in case... // no params fLocalDataStoreP=NULL; fRemoteDataStoreP=NULL; } // TMapCommand::TMapCommand #ifdef SYSYNC_SERVER // Server only receives Maps // analyze command (but do not yet execute) bool TMapCommand::analyze(TPackageStates aPackageState) { TSmlCommand::analyze(aPackageState); // get Command ID and flags if (fMapElementP) { StartProcessing(fMapElementP->cmdID,0); return true; } else return false; // no proto element, bad command } // TMapCommand::analyze // execute command (perform real actions, generate status) // returns true if command has executed and can be deleted bool TMapCommand::execute(void) { TStatusCommand *statusCmdP=NULL; bool queueforlater; SYSYNC_TRY { // prepare a status statusCmdP = newStatusCommand(200); // let session actually process the command queueforlater=false; fSessionP->processMapCommand(fMapElementP,*statusCmdP,queueforlater); // check if done or queued for later if (queueforlater) { delete statusCmdP; } else { // now issue status, if any if (statusCmdP) { statusCmdP->addTargetRef(smlSrcTargLocURIToCharP(fMapElementP->target)); // add target ref statusCmdP->addSourceRef(smlSrcTargLocURIToCharP(fMapElementP->source)); // add source ref #ifdef MAP_STATUS_IMMEDIATE // issue status right now (might cause map statuses // returned in sync-updates-to-client package #4 instead of map-confirm #6 ISSUE_COMMAND_ROOT(fSessionP,statusCmdP); #else // issue status only if outgoing package is map-response fSessionP->issueNotBeforePackage(psta_map,statusCmdP); #endif } // free this one in advance FreeSmlElement(); } } SYSYNC_CATCH (...) // make sure owned objects in local scope are deleted if (statusCmdP) delete statusCmdP; // re-throw SYSYNC_RETHROW; SYSYNC_ENDCATCH // return true if command has fully executed return !queueforlater; } // TMapCommand::execute #endif #ifdef SYSYNC_CLIENT // Client only sends maps // constructor for sending MAP Command TMapCommand::TMapCommand( TSyncSession *aSessionP, // associated session (for callbacks) TLocalEngineDS *aLocalDataStoreP, // local datastore TRemoteDataStore *aRemoteDataStoreP // remote datastore ) : TSmlCommand(scmd_map,true,aSessionP) { // save params fLocalDataStoreP=aLocalDataStoreP; fRemoteDataStoreP=aRemoteDataStoreP; // create new internal map element fMapElementP=NULL; // none yet generateEmptyMapElement(); // not yet in progress (as not yet issued) fInProgress=false; } // TMapCommand::TMapCommand // generate empty map element void TMapCommand::generateEmptyMapElement(void) { // free possibly still existing map element if (fMapElementP) FreeSmlElement(); // create internal map element fMapElementP = SML_NEW(SmlMap_t); // set proto element type to make it auto-disposable fMapElementP->elementType=SML_PE_MAP; // Cmd ID is now empty (will be set when issued) fMapElementP->cmdID=NULL; // set source and target fMapElementP->target=newLocation(fRemoteDataStoreP->getFullName()); // remote is target for Map command fMapElementP->source=newLocation(fLocalDataStoreP->getRemoteViewOfLocalURI()); // local is source of Map command // no optional elements for now fMapElementP->cred=NULL; // %%% no database level auth yet at all fMapElementP->meta=NULL; // %%% no meta for now // map itemlist is empty fMapElementP->mapItemList=NULL; #ifndef USE_SML_EVALUATION // no item sizes fItemSizes=0; #endif } // TMapCommand::generateEmptyMapElement // returns true if command must be put to the waiting-for-status queue. // If false, command can be deleted (except if it is not finished() ) bool TMapCommand::issue( uInt32 aAsCmdID, // command ID to be used uInt32 aInMsgID, // message ID in which command is being issued bool aNoResp ) { // prepare basic stuff TSmlCommand::issue(aAsCmdID,aInMsgID,aNoResp); // now issue if (fMapElementP) { // add as many Map items as possible, update fInProgress // BUT DONT DO THAT IN EVAL MODE (would be recursive, as generateMapItems() // will call evalIssue() which will call this routine....) if (!fEvalMode) generateMapItems(); // issue command, but only if there are any items at all if (fMapElementP->mapItemList) { // now issue map command PrepareIssue(&fMapElementP->cmdID); if (!fEvalMode) { #ifdef SYDEBUG if (fSessionP->fXMLtranslate && fSessionP->fOutgoingXMLInstance) smlMapCmd(fSessionP->fOutgoingXMLInstance,fMapElementP); #endif Ret_t err; if ((err=smlMapCmd(fSessionP->getSmlWorkspaceID(),fMapElementP))!=SML_ERR_OK) { SYSYNC_THROW(TSmlException("smlMapCmd",err)); } FinalizeIssue(); // show debug DEBUGPRINTFX(DBG_HOT,( "Generated Map command, Source='%s', Target='%s'", smlSrcTargLocURIToCharP(fMapElementP->source), smlSrcTargLocURIToCharP(fMapElementP->target) )); } else return smlMapCmd(fSessionP->getSmlWorkspaceID(),fMapElementP)==SML_ERR_OK; } else { if (fEvalMode) return true; // evaluated nothing, is ok! DEBUGPRINTFX(DBG_PROTO,("Suppressed generating empty map command")); return false; // do not queue, delete command now } // keep smlElement, as we need it to mark confirmed map items // at handleStatus(). } else { DEBUGPRINTFX(DBG_ERROR,("*** Tried to issue NULL sync")); } // return true if command must be queued for status/result response reception return queueForResponse(); } // TMapCommand::issue // - test if completely issued (must be called after issue() and continueIssue()) bool TMapCommand::finished(void) { // not finished as long there are more syncOps to send return (!fInProgress || !fOutgoing); } // TMapCommand::finished // - continue issuing command. This is called by session at start of new message // when finished() returned false after issue()/continueIssue() // (which causes caller of finished() to put command into fInteruptedCommands queue) // returns true if command should be queued for status (again?) // NOTE: continueIssue must make sure that it gets a new CmdID/MsgID because // the command itself is issued multiple times bool TMapCommand::continueIssue(bool &aNewIssue) { aNewIssue=false; // never issue anew! if (!fInProgress) return false; // done, don't queue for status again // we can generate next map command only after we have received status for this one if (isWaitingForStatus()) return true; // still in progress, still waiting for status // command is in progress, continue with another command in this message // - create new Map command generateEmptyMapElement(); // - issue again with new command ID fCmdID = fSessionP->getNextOutgoingCmdID(); fMsgID = fSessionP->getOutgoingMsgID(); // new map command must be queued for status again // but only if something was actually issued (map command issue can // be nop if there are no map items present) return issue(fCmdID,fMsgID,fNoResp); } // TMapCommand::continueIssue // add as many Map items as possible, update fInProgress void TMapCommand::generateMapItems(void) { // let datastore add Map items (possibly none) fInProgress = !( fLocalDataStoreP->engGenerateMapItems(this,NULL) ); } // TMapCommand::generateMapItems // add a Map Item to the map command void TMapCommand::addMapItem(const char *aLocalID, const char *aRemoteID) { // make item SmlMapItemPtr_t mapitemP = SML_NEW(SmlMapItem_t); mapitemP->target=newLocation(aRemoteID); mapitemP->source=newLocation(aLocalID); #ifndef USE_SML_EVALUATION // update size fItemSizes += ITEMOVERHEADSIZE + strlen(aLocalID) + strlen(aRemoteID); #endif // add item to item list SmlMapItemListPtr_t *mapItemListPP = &(fMapElementP->mapItemList); // find last itemlist pointer while (*mapItemListPP) { mapItemListPP=&((*mapItemListPP)->next); } // aItemListPP now points to a NULL pointer which must be replaced by addr of new ItemList entry *mapItemListPP = SML_NEW(SmlMapItemList_t); (*mapItemListPP)->next=NULL; (*mapItemListPP)->mapItem=mapitemP; // insert new item } // TMapCommand::addItem // remove last added map item from the command void TMapCommand::deleteLastMapItem(void) { // make item #ifndef USE_SML_EVALUATION #error "Not implemented for old non-eval method any more" #endif // kill last item in item list SmlMapItemListPtr_t *mapItemListPP = &(fMapElementP->mapItemList); // find last itemlist pointer pointing to an item while (*mapItemListPP && (*mapItemListPP)->next) { mapItemListPP=&((*mapItemListPP)->next); } // aItemListPP now points to the pointer which points to the last item list element (or is NULL if no items there) if (*mapItemListPP) { // delete rest of list, which consists of one item only smlFreeMapItemList(*mapItemListPP); // NULL link in previous item or beginning of list *mapItemListPP=NULL; } } // TMapCommand::deleteLastMapItem // handle status received for previously issued command // returns true if done, false if command must be kept in the status queue bool TMapCommand::handleStatus(TStatusCommand *aStatusCmdP) { bool handled=false; if (aStatusCmdP->getStatusCode()==200) { handled=true; // is ok // mark maps confirmed if (fLocalDataStoreP) { // go through all of my items SmlMapItemListPtr_t mapItemListP = fMapElementP->mapItemList; SmlMapItemPtr_t mapItemP; while (mapItemListP) { mapItemP=mapItemListP->mapItem; if (mapItemP) { // call datastore to mark this map confirmed (no need to be sent again in next session / resume) fLocalDataStoreP->engMarkMapConfirmed( smlSrcTargLocURIToCharP(mapItemP->source), // source for outgoing mapitem is localID smlSrcTargLocURIToCharP(mapItemP->target) // target for outgoing mapitem is remoteID ); } mapItemListP=mapItemListP->next; } } } // anyway, we can now get rid of the map items in the command if (fMapElementP) FreeSmlElement(); // check if base class must handle it if(!handled) { // let base class handle it handled=TSmlCommand::handleStatus(aStatusCmdP); } return handled; } // TMapCommand::handleStatus #endif // client-only map implementation // Common for Client and Server #ifndef USE_SML_EVALUATION // get (approximated) message size required for sending it uInt32 TMapCommand::messageSize(void) { // return size of command so far return TSmlCommand::messageSize()+fItemSizes; } // TMapCommand::messageSize #endif void TMapCommand::FreeSmlElement(void) { // remove SyncML toolkit element(s) FREEPROTOELEMENT(fMapElementP); } // TMapCommand::FreeSmlElement TMapCommand::~TMapCommand() { // free command elements, if any (use explicit invocation as this is a destructor) TMapCommand::FreeSmlElement(); } // TMapCommand::TMapCommand /* end of TMapCommand implementation */ /* * Implementation of TGetCommand */ // constructor for receiving command TGetCommand::TGetCommand( TSyncSession *aSessionP, // associated session (for callbacks) uInt32 aMsgID, // the Message ID of the command SmlGetPtr_t aGetElementP // associated syncml protocol element ) : TSmlCommand(scmd_get,false,aSessionP,aMsgID) { // save element fGetElementP = aGetElementP; } // TGetCommand::TGetCommand // constructor for sending command TGetCommand::TGetCommand( TSyncSession *aSessionP // associated session (for callbacks) ) : TSmlCommand(scmd_get,true,aSessionP) { // create internal get element fGetElementP = SML_NEW(SmlGet_t); // set proto element type to make it auto-disposable fGetElementP->elementType=SML_PE_GET; // Cmd ID is now empty (will be set when issued) fGetElementP->cmdID=NULL; // default to no flags (noResp is set at issue, if at all) fGetElementP->flags=0; // no optional elements for now fGetElementP->cred=NULL; fGetElementP->lang=NULL; fGetElementP->meta=NULL; fGetElementP->itemList=NULL; } // TGetCommand::TGetCommand // set Meta of the get command void TGetCommand::setMeta( SmlPcdataPtr_t aMetaP // existing meta data structure, ownership is passed to Get ) { if (fGetElementP) fGetElementP->meta=aMetaP; } // TGetCommand::setMeta // add an Item to the get command void TGetCommand::addItem( SmlItemPtr_t aItemP // existing item data structure, ownership is passed to Get ) { if (fGetElementP) addItemToList(aItemP,&(fGetElementP->itemList)); } // TGetCommand::addItem // add a target specification Item to the get command void TGetCommand::addTargetLocItem( const char *aTargetURI, const char *aTargetName ) { SmlItemPtr_t itemP = newItem(); itemP->target = newLocation(aTargetURI,aTargetName); addItem(itemP); } // TGetCommand::addTargetLocItem // analyze command (but do not yet execute) bool TGetCommand::analyze(TPackageStates aPackageState) { TSmlCommand::analyze(aPackageState); // get Command ID and flags if (fGetElementP) { StartProcessing(fGetElementP->cmdID,fGetElementP->flags); return true; } else return false; // no proto element, bad command } // TGetCommand::analyze // execute command (perform real actions, generate status) // returns true if command has executed and can be deleted bool TGetCommand::execute(void) { TStatusCommand *statusCmdP=NULL; TResultsCommand *resultsCmdP=NULL; SmlItemListPtr_t thisitemnode,nextitemnode; SYSYNC_TRY { // process items thisitemnode=fGetElementP->itemList; while (thisitemnode) { nextitemnode = thisitemnode->next; // no result nor status so far statusCmdP=NULL; resultsCmdP=NULL; // get Target LocURI if (!thisitemnode->item) SYSYNC_THROW(TSyncException("Get with NULL item")); string locURI=smlSrcTargLocURIToCharP(thisitemnode->item->target); DEBUGPRINTFX(DBG_HOT,("processing item with locURI=%s",locURI.c_str())); // let session (and descendants) process it // - default to "not found" status statusCmdP = newStatusCommand(404); resultsCmdP=fSessionP->processGetItem(locURI.c_str(),this,thisitemnode->item,*statusCmdP); // now complete and issue status statusCmdP->addTargetRef(locURI.c_str()); // add target ref ISSUE_COMMAND_ROOT(fSessionP,statusCmdP); // issue results, if any if (resultsCmdP) { ISSUE_COMMAND_ROOT(fSessionP,resultsCmdP); } // next item thisitemnode=nextitemnode; } // free this one in advance FreeSmlElement(); } SYSYNC_CATCH (...) // make sure owned objects in local scope are deleted if (statusCmdP) delete statusCmdP; if (resultsCmdP) delete resultsCmdP; // re-throw SYSYNC_RETHROW; SYSYNC_ENDCATCH // done with command, delete it now: return true return true; } // TGetCommand::execute // returns true if command must be put to the waiting-for-status queue. // If false, command can be deleted bool TGetCommand::issue( uInt32 aAsCmdID, // command ID to be used uInt32 aInMsgID, // message ID in which command is being issued bool aNoResp ) { // prepare basic stuff TSmlCommand::issue(aAsCmdID,aInMsgID,aNoResp); // now issue if (fGetElementP) { // issue command with SyncML toolkit PrepareIssue(&fGetElementP->cmdID,&fGetElementP->flags); if (!fEvalMode) { #ifdef SYDEBUG if (fSessionP->fXMLtranslate && fSessionP->fOutgoingXMLInstance) smlGetCmd(fSessionP->fOutgoingXMLInstance,fGetElementP); #endif Ret_t err; if ((err=smlGetCmd(fSessionP->getSmlWorkspaceID(),fGetElementP))!=SML_ERR_OK) { SYSYNC_THROW(TSmlException("smlGetCmd",err)); } FinalizeIssue(); // we don't need the status structure any more, free (and NULL ptr) now FreeSmlElement(); } else return smlGetCmd(fSessionP->getSmlWorkspaceID(),fGetElementP)==SML_ERR_OK; } else { DEBUGPRINTFX(DBG_ERROR,("*** Tried to issue NULL get")); } // return true if command must be queued for status/result response reception return queueForResponse(); } // TGetCommand::issue bool TGetCommand::statusEssential(void) { // get status is not essential in lenient mode return !(fSessionP->fLenientMode); } // TGetCommand::statusEssential // handle status received for previously issued command // returns true if done, false if command must be kept in the status queue bool TGetCommand::handleStatus(TStatusCommand *aStatusCmdP) { // base class just handles common cases TSyError statuscode = aStatusCmdP->getStatusCode(); if (statuscode>=500) { // %%% for SCTS, which rejects GET with status 500 in some cases POBJDEBUGPRINTFX(fSessionP,DBG_ERROR,("Status: %hd: 5xx for get is passed w/o error",statuscode)); return true; } // let ancestor analyze return TSmlCommand::handleStatus(aStatusCmdP); } // TGetCommand::handleStatus void TGetCommand::FreeSmlElement(void) { // remove SyncML toolkit element(s) FREEPROTOELEMENT(fGetElementP); } // TGetCommand::FreeSmlElement TGetCommand::~TGetCommand() { // free command elements, if any (use explicit invocation as this is a destructor) TGetCommand::FreeSmlElement(); } // TGetCommand::~TGetCommand /* end of TGetCommand implementation */ /* * Implementation of TPutCommand */ // constructor for receiving command TPutCommand::TPutCommand( TSyncSession *aSessionP, // associated session (for callbacks) uInt32 aMsgID, // the Message ID of the command SmlGetPtr_t aPutElementP // associated syncml protocol element ) : TSmlCommand(scmd_put,false,aSessionP,aMsgID) { // save element fPutElementP = aPutElementP; } // TPutCommand::TPutCommand // constructor for sending command TPutCommand::TPutCommand( TSyncSession *aSessionP // associated session (for callbacks) ) : TSmlCommand(scmd_put,true,aSessionP) { // create internal get element fPutElementP = SML_NEW(SmlPut_t); // set proto element type to make it auto-disposable fPutElementP->elementType=SML_PE_PUT; // Cmd ID is now empty (will be set when issued) fPutElementP->cmdID=NULL; // default to no flags (noResp is set at issue, if at all) fPutElementP->flags=0; // no optional elements for now fPutElementP->cred=NULL; fPutElementP->lang=NULL; fPutElementP->meta=NULL; fPutElementP->itemList=NULL; } // TPutCommand::TPutCommand // add Meta to the get command void TPutCommand::setMeta( SmlPcdataPtr_t aMetaP // existing meta data structure, ownership is passed to Get ) { if (fPutElementP) fPutElementP->meta=aMetaP; } // TPutCommand::setMeta // add an Item to the get command void TPutCommand::addItem( SmlItemPtr_t aItemP // existing item data structure, ownership is passed to Get ) { if (fPutElementP) addItemToList(aItemP,&(fPutElementP->itemList)); } // TPutCommand::addItem // add a source specification Item to the put command and return a pointer // to add data to it SmlItemPtr_t TPutCommand::addSourceLocItem( const char *aTargetURI, const char *aTargetName ) { SmlItemPtr_t itemP = newItem(); itemP->source = newLocation(aTargetURI,aTargetName); addItem(itemP); return itemP; } // TPutCommand::addSourceLocItem // analyze command (but do not yet execute) bool TPutCommand::analyze(TPackageStates aPackageState) { TSmlCommand::analyze(aPackageState); // get Command ID and flags if (fPutElementP) { StartProcessing(fPutElementP->cmdID,fPutElementP->flags); return true; } else return false; // no proto element, bad command } // TPutCommand::analyze // execute command (perform real actions, generate status) // returns true if command has executed and can be deleted bool TPutCommand::execute(void) { TStatusCommand *statusCmdP=NULL; SmlItemListPtr_t thisitemnode,nextitemnode; SYSYNC_TRY { // process items thisitemnode=fPutElementP->itemList; while (thisitemnode) { nextitemnode = thisitemnode->next; // no result nor status so far statusCmdP=NULL; if (!thisitemnode->item) SYSYNC_THROW(TSyncException("Put with NULL item")); // get Source LocURI string locURI=smlSrcTargLocURIToCharP(thisitemnode->item->source); DEBUGPRINTFX(DBG_HOT,("processing item with locURI=%s",locURI.c_str())); // let session (and descendants) process it // - default to not allowed to put status statusCmdP = newStatusCommand(403); fSessionP->processPutResultItem(true,locURI.c_str(),this,thisitemnode->item,*statusCmdP); // now complete and issue status statusCmdP->addSourceRef(locURI.c_str()); // add source ref ISSUE_COMMAND_ROOT(fSessionP,statusCmdP); // next item thisitemnode=nextitemnode; } // free element FreeSmlElement(); } SYSYNC_CATCH (...) // make sure owned objects in local scope are deleted if (statusCmdP) delete statusCmdP; // re-throw SYSYNC_RETHROW; SYSYNC_ENDCATCH // done with command, delete it now: return true return true; } // TPutCommand::execute // returns true if command must be put to the waiting-for-status queue. // If false, command can be deleted bool TPutCommand::issue( uInt32 aAsCmdID, // command ID to be used uInt32 aInMsgID, // message ID in which command is being issued bool aNoResp ) { // prepare basic stuff TSmlCommand::issue(aAsCmdID,aInMsgID,aNoResp); // now issue if (fPutElementP) { // issue command with SyncML toolkit PrepareIssue(&fPutElementP->cmdID,&fPutElementP->flags); if (!fEvalMode) { #ifdef SYDEBUG if (fSessionP->fXMLtranslate && fSessionP->fOutgoingXMLInstance) smlPutCmd(fSessionP->fOutgoingXMLInstance,fPutElementP); #endif Ret_t err; if ((err=smlPutCmd(fSessionP->getSmlWorkspaceID(),fPutElementP))!=SML_ERR_OK) { SYSYNC_THROW(TSmlException("smlPutCmd",err)); } FinalizeIssue(); // we don't need the status structure any more, free (and NULL ptr) now FreeSmlElement(); } else return smlPutCmd(fSessionP->getSmlWorkspaceID(),fPutElementP)==SML_ERR_OK; } else { DEBUGPRINTFX(DBG_ERROR,("*** Tried to issue NULL put")); } // return true if command must be queued for status/result response reception return queueForResponse(); } // TPutCommand::issue void TPutCommand::FreeSmlElement(void) { // remove SyncML toolkit element(s) FREEPROTOELEMENT(fPutElementP); } // TPutCommand::FreeSmlElement TPutCommand::~TPutCommand() { // free command elements, if any (use explicit invocation as this is a destructor) TPutCommand::FreeSmlElement(); } // TPutCommand::~TPutCommand /* end of TPutCommand implementation */ /* * Implementation of TStatusCommand */ // constructor for generating status TStatusCommand::TStatusCommand( TSyncSession *aSessionP, // associated session (for callbacks) TSmlCommand *aCommandP, // command this status refers to TSyError aStatusCode // status code ) : TSmlCommand(scmd_status,true,aSessionP) { // save status code fStatusCode=aStatusCode; // get reference info if (aCommandP) { // referring to a command fRefMsgID=aCommandP->getMsgID(); fRefCmdID=aCommandP->getCmdID(); fRefCmdType=aCommandP->getCmdType(); // - set flag to suppress sending this status when NoResp is set fDontSend= aCommandP->getNoResp() || fSessionP->getMsgNoResp(); } else { // referring to SyncHdr of current message fRefMsgID=fSessionP->fIncomingMsgID; fRefCmdID=0; // "command" ID of SyncHdr is 0 fRefCmdType=scmd_synchdr; // is SyncHdr // - set flag to suppress sending this status when NoResp is set fDontSend=fSessionP->getMsgNoResp(); } // create internal status element fStatusElementP = SML_NEW(SmlStatus_t); // set proto element type to make it auto-disposable fStatusElementP->elementType=SML_PE_STATUS; // Cmd ID is now empty (will be set at Issue to ensure correct sequential ordering in case this status is not immediately sent) fStatusElementP->cmdID=NULL; // status refers to message of specified command fStatusElementP->msgRef=newPCDataLong(fRefMsgID); // status refers to ID of specified command fStatusElementP->cmdRef=newPCDataLong(fRefCmdID); // add name fStatusElementP->cmd=newPCDataString(getNameOf(fRefCmdType)); // no status code yet (will be added at issue()) fStatusElementP->data=NULL; // no optional elements for now fStatusElementP->targetRefList=NULL; fStatusElementP->sourceRefList=NULL; fStatusElementP->cred=NULL; fStatusElementP->chal=NULL; fStatusElementP->itemList=NULL; } // TStatusCommand::TStatusCommand // %%%% (later obsolete) constructor for generating status w/o having a command object TStatusCommand::TStatusCommand( TSyncSession *aSessionP, // associated session (for callbacks) uInt32 aRefCmdID, // referred-to command ID TSmlCommandTypes aRefCmdType, // referred-to command type (scmd_xxx) bool aNoResp, // set if no-Resp TSyError aStatusCode // status code ) : TSmlCommand(scmd_status,true,aSessionP) { // save status code fStatusCode=aStatusCode; // get reference info fRefMsgID=fSessionP->fIncomingMsgID; fRefCmdID=aRefCmdID; fRefCmdType=aRefCmdType; // - set flag to suppress sending this status when NoResp is set fDontSend=aNoResp; // create internal status element fStatusElementP = SML_NEW(SmlStatus_t); // set proto element type to make it auto-disposable fStatusElementP->elementType=SML_PE_STATUS; // Cmd ID is now empty (will be set at Issue to ensure correct sequential ordering in case this status is not immediately sent) fStatusElementP->cmdID=NULL; // status refers to message of specified command fStatusElementP->msgRef=newPCDataLong(fRefMsgID); // status refers to ID of specified command fStatusElementP->cmdRef=newPCDataLong(fRefCmdID); // add name fStatusElementP->cmd=newPCDataString(getNameOf(fRefCmdType)); // no status code yet (will be added at issue()) fStatusElementP->data=NULL; // no optional elements for now fStatusElementP->targetRefList=NULL; fStatusElementP->sourceRefList=NULL; fStatusElementP->cred=NULL; fStatusElementP->chal=NULL; fStatusElementP->itemList=NULL; } // TStatusCommand::TStatusCommand // constructor for receiving status TStatusCommand::TStatusCommand( TSyncSession *aSessionP, // associated session (for callbacks) uInt32 aMsgID, // the Message ID of the command SmlStatusPtr_t aStatusElementP // associated STATUS command content element ) : TSmlCommand(scmd_status,false,aSessionP,aMsgID) { // save element fStatusElementP = aStatusElementP; } // TStatusCommand::TStatusCommand // analyze status bool TStatusCommand::analyze(TPackageStates aPackageState) { TSmlCommand::analyze(aPackageState); // get Command ID and flags if (fStatusElementP) { StartProcessing(fStatusElementP->cmdID,0); // get status code sInt32 temp; if (smlPCDataToLong(fStatusElementP->data,temp)) fStatusCode=temp; else { PDEBUGPRINTFX(DBG_ERROR,("Malformed status code: '%s'",smlPCDataToCharP(fStatusElementP->data))); return false; // bad status } // get message reference if (!fStatusElementP->msgRef) { // no MsgRef -> must assume 1 (according to SyncML specs) fRefMsgID=1; DEBUGPRINTFX(DBG_PROTO,("No MsgRef in Status, assumed 1")); } else if (!smlPCDataToULong(fStatusElementP->msgRef,fRefMsgID)) { PDEBUGPRINTFX(DBG_ERROR,("Malformed message reference: '%s'",smlPCDataToCharP(fStatusElementP->msgRef))); return false; // bad status } // get command reference if (!smlPCDataToULong(fStatusElementP->cmdRef,fRefCmdID)) { PDEBUGPRINTFX(DBG_ERROR,("Malformed command reference: '%s'",smlPCDataToCharP(fStatusElementP->msgRef))); return false; // bad status } #ifdef SYDEBUG // warn if error (don't treat slow sync status or conflict indication as errors) // - 418 = item already exits: sent by Funambol server when both client and // and server have a new item which is considered identical by the server // (must be really identical, minor difference will lead to a merged item // which is sent back to the client without the 418). See Moblin Bugzilla #4599. if (fStatusCode>=300 && fStatusCode!=508 && fStatusCode!=419 && fStatusCode!=418) { PDEBUGPRINTFX(DBG_ERROR,( "WARNING: RECEIVED NON-OK STATUS %hd for &html;&html;command '%s'&html;&html; (outgoing MsgID=%ld, CmdID=%ld)", fStatusCode, (long)fRefMsgID, (long)fRefCmdID, (long)fRefMsgID, (long)fRefCmdID, smlPCDataToCharP(fStatusElementP->cmd), (long)fRefMsgID, (long)fRefCmdID )); } else { // show what we have received PDEBUGPRINTFX(DBG_HOT,( "RECEIVED STATUS %hd for for &html;&html;command '%s'&html;&html; (outgoing MsgID=%ld, CmdID=%ld)", fStatusCode, (long)fRefMsgID, (long)fRefCmdID, (long)fRefMsgID, (long)fRefCmdID, smlPCDataToCharP(fStatusElementP->cmd), (long)fRefMsgID, (long)fRefCmdID )); } // - source and target refs if (PDEBUGMASK & DBG_HOT) { SmlTargetRefListPtr_t targetrefP = fStatusElementP->targetRefList; while (targetrefP) { // target ref available PDEBUGPRINTFX(DBG_HOT,("- TargetRef (remoteID) = '%s'",smlPCDataToCharP(targetrefP->targetRef))); // next targetrefP=targetrefP->next; } SmlSourceRefListPtr_t sourcerefP = fStatusElementP->sourceRefList; while (sourcerefP) { // target ref available PDEBUGPRINTFX(DBG_HOT,("- SourceRef (localID) = '%s'",smlPCDataToCharP(sourcerefP->sourceRef))); // next sourcerefP=sourcerefP->next; } } // - optional items if (PDEBUGMASK & DBG_ERROR) { SmlItemListPtr_t itemlistP = fStatusElementP->itemList; while (itemlistP) { // item available PDEBUGPRINTFX(DBG_HOT,("- Item data = %s",smlItemDataToCharP(itemlistP->item))); // next itemlistP=itemlistP->next; } } #endif return true; // good status } else return false; // no proto element, bad command } // TStatusCommand::analyze // returns true if command must be put to the waiting-for-status queue. // If false, command can be deleted bool TStatusCommand::issue( uInt32 aAsCmdID, // command ID to be used uInt32 aInMsgID, // message ID in which command is being issued bool aNoResp // dummy here, because Status has always no response ) { // now issue if (fStatusElementP) { // prepare basic stuff TSmlCommand::issue(aAsCmdID,aInMsgID,true); // set status code in structure (but only once, in case we are evaluating before issuing) if (fStatusElementP->data==NULL) fStatusElementP->data=newPCDataLong(fStatusCode); // Status is meant to have a CmdID. SyncML 1.0 docs say no, but this was corrected in 1.0.1 // issue command with SyncML toolkit (no flags) PrepareIssue(&fStatusElementP->cmdID,NULL); // CmdID (SyncML 1.0.1 conformant) if (!fEvalMode) { // PrepareIssue(NULL,NULL); // no CmdID, no flags #ifdef SYDEBUG if (fSessionP->fXMLtranslate && fSessionP->fOutgoingXMLInstance) smlStatusCmd(fSessionP->fOutgoingXMLInstance,fStatusElementP); #endif Ret_t err; if ((err=smlStatusCmd(fSessionP->getSmlWorkspaceID(),fStatusElementP))!=SML_ERR_OK) { SYSYNC_THROW(TSmlException("smlStatusCmd",err)); } FinalizeIssue(); // show debug #ifdef SYDEBUG // - warning for non-ok (don't treat slow sync status as error) if (fStatusCode>=300 && fStatusCode!=508) { PDEBUGPRINTFX(DBG_ERROR,("WARNING: Non-OK Status %hd returned to remote!",fStatusCode)); } // - what was issued PDEBUGPRINTFX(DBG_HOT,("Status Code %s issued for Cmd=%s, (incoming MsgID=%s, CmdID=%s)", smlPCDataToCharP(fStatusElementP->data), smlPCDataToCharP(fStatusElementP->cmd), smlPCDataToCharP(fStatusElementP->msgRef), smlPCDataToCharP(fStatusElementP->cmdRef) )); // - source and target refs if (PDEBUGTEST(DBG_HOT)) { SmlTargetRefListPtr_t targetrefP = fStatusElementP->targetRefList; while (targetrefP) { // target ref available PDEBUGPRINTFX(DBG_HOT,("- TargetRef (localID) = '%s'",smlPCDataToCharP(targetrefP->targetRef))) // next targetrefP=targetrefP->next; } SmlSourceRefListPtr_t sourcerefP = fStatusElementP->sourceRefList; while (sourcerefP) { // target ref available PDEBUGPRINTFX(DBG_HOT,("- SourceRef (remoteID) = '%s'",smlPCDataToCharP(sourcerefP->sourceRef))) // next sourcerefP=sourcerefP->next; } } #endif // we don't need the status structure any more, free (and NULL ptr) now FreeSmlElement(); } else return smlStatusCmd(fSessionP->getSmlWorkspaceID(),fStatusElementP)==SML_ERR_OK; } else { DEBUGPRINTFX(DBG_ERROR,("*** Tried to issue NULL status")); } // status does NOT await any answer, and can be deleted after issuing return false; // don't queue for status } // TStatusCommand::issue // add a target Ref to the status (no op if ref is NULL) void TStatusCommand::addTargetRef( const char *aTargetRef // Target LocURI of an item this status applies to ) { SmlTargetRefListPtr_t *targetreflistPP; if (fStatusElementP && aTargetRef && *aTargetRef) { // Note: empty refs will not be added targetreflistPP=&(fStatusElementP->targetRefList); // find last targetreflist pointer while (*targetreflistPP) { targetreflistPP=&((*targetreflistPP)->next); } // targetreflistPP now points to a NULL pointer which must be replaced by addr of new targetreflist entry *targetreflistPP = SML_NEW(SmlTargetRefList_t); (*targetreflistPP)->next=NULL; (*targetreflistPP)->targetRef= newPCDataString(aTargetRef); } } // TStatusCommand::addTargetRef // add a source Ref to the status (no op if ref is NULL) void TStatusCommand::addSourceRef( const char *aSourceRef // Target LocURI of an item this status applies to ) { SmlSourceRefListPtr_t *sourcereflistPP; if (fStatusElementP && aSourceRef && *aSourceRef) { // Note: empty refs will not be added sourcereflistPP=&(fStatusElementP->sourceRefList); // find last sourcereflist pointer while (*sourcereflistPP) { sourcereflistPP=&((*sourcereflistPP)->next); } // sourcereflistPP now points to a NULL pointer which must be replaced by addr of new sourcereflist entry *sourcereflistPP = SML_NEW(SmlSourceRefList_t); (*sourcereflistPP)->next=NULL; (*sourcereflistPP)->sourceRef= newPCDataString(aSourceRef); } } // TStatusCommand::addSourceRef // add a String Item to the status (only if not empty) void TStatusCommand::addItemString( const char *aItemString // item string to be added ) { if (fStatusElementP && aItemString && *aItemString) { addItem(newStringDataItem(aItemString)); } } // TStatusCommand::addItemString // add an Item to the status void TStatusCommand::addItem( SmlItemPtr_t aItemP // existing item data structure, ownership is passed to Status ) { if (fStatusElementP) addItemToList(aItemP,&(fStatusElementP->itemList)); } // TStatusCommand::addItem // move items from another status to this one (passes ownership of items and deletes them from original) void TStatusCommand::moveItemsFrom(TStatusCommand *aStatusCommandP) { if (fStatusElementP && aStatusCommandP) { // pass item list to new owner fStatusElementP->itemList = aStatusCommandP->fStatusElementP->itemList; // remove items from original aStatusCommandP->fStatusElementP->itemList = NULL; } } // TStatusCommand::moveItemsFrom // add Challenge to status // challenge data structure ownership is passed to Status void TStatusCommand::setChallenge(SmlChalPtr_t aChallengeP) { if (fStatusElementP) { if (fStatusElementP->chal) { // get rid of old challenge smlFreeChalPtr(fStatusElementP->chal); fStatusElementP->chal=NULL; } // set new fStatusElementP->chal=aChallengeP; } } // TStatusCommand::setChallenge // set Status code void TStatusCommand::setStatusCode(TSyError aStatusCode) { fStatusCode = aStatusCode; } // TStatusCommand::setStatusCode void TStatusCommand::FreeSmlElement(void) { // remove SyncML toolkit element(s) FREEPROTOELEMENT(fStatusElementP); } // TResultsCommand::FreeSmlElement TStatusCommand::~TStatusCommand() { // free command elements, if any (use explicit invocation as this is a destructor) TStatusCommand::FreeSmlElement(); } // TStatusCommand::TStatusCommand /* end of TStatusCommand implementation */ /* * Implementation of TResultsCommand */ // constructor for receiving command TResultsCommand::TResultsCommand( TSyncSession *aSessionP, // associated session (for callbacks) uInt32 aMsgID, // the Message ID of the command SmlResultsPtr_t aResultsElementP // associated syncml protocol element ) : TSmlCommand(scmd_results,false,aSessionP,aMsgID) { // save element fResultsElementP = aResultsElementP; } // TResultsCommand::TResultsCommand // constructor for generating results TResultsCommand::TResultsCommand( TSyncSession *aSessionP, // associated session (for callbacks) TSmlCommand *aCommandP, // command these results refer to const char *aTargetRef, // target reference const char *aSourceRef // source reference ) : TSmlCommand(scmd_results,true,aSessionP) { // create internal results element fResultsElementP = SML_NEW(SmlResults_t); // set proto element type to make it auto-disposable fResultsElementP->elementType=SML_PE_RESULTS; // Cmd ID is now empty (will be set when issued) fResultsElementP->cmdID=NULL; // results refer to message of specified command fResultsElementP->msgRef=newPCDataLong(aCommandP->getMsgID()); // results refer to ID of specified command fResultsElementP->cmdRef=newPCDataLong(aCommandP->getCmdID()); // no meta for now fResultsElementP->meta=NULL; // target reference if specified if (aTargetRef) fResultsElementP->targetRef=newPCDataString(aTargetRef); else fResultsElementP->targetRef=NULL; // source reference if specified if (aSourceRef) fResultsElementP->sourceRef=newPCDataString(aSourceRef); else fResultsElementP->sourceRef=NULL; // no items for now fResultsElementP->itemList=NULL; } // TResultsCommand::TResultsCommand // returns true if command must be put to the waiting-for-status queue. // If false, command can be deleted bool TResultsCommand::issue( uInt32 aAsCmdID, // command ID to be used uInt32 aInMsgID, // message ID in which command is being issued bool aNoResp // issue without wanting response ) { // prepare TSmlCommand::issue(aAsCmdID,aInMsgID,aNoResp); // now issue if (fResultsElementP) { // issue command with SyncML toolkit (no flags) PrepareIssue(&fResultsElementP->cmdID,NULL); if (!fEvalMode) { #ifdef SYDEBUG if (fSessionP->fXMLtranslate && fSessionP->fOutgoingXMLInstance) smlResultsCmd(fSessionP->fOutgoingXMLInstance,fResultsElementP); #endif Ret_t err; if ((err=smlResultsCmd(fSessionP->getSmlWorkspaceID(),fResultsElementP))!=SML_ERR_OK) { SYSYNC_THROW(TSmlException("smlResultsCmd",err)); } FinalizeIssue(); // show debug DEBUGPRINTFX(DBG_HOT,("results issued for (incoming MsgID=%s, CmdID=%s)", smlPCDataToCharP(fResultsElementP->msgRef), smlPCDataToCharP(fResultsElementP->cmdRef) )); // we don't need the results structure any more, free (and NULL ptr) now FreeSmlElement(); } else return smlResultsCmd(fSessionP->getSmlWorkspaceID(),fResultsElementP)==SML_ERR_OK; } else { DEBUGPRINTFX(DBG_ERROR,("*** Tried to issue NULL result")); } // SyncML 1.0: result does NOT await any answer, and can be deleted after issuing // SyncML 1.0.1: all commands will receive a status (except Status) return true; // queue for status/result } // TResultsCommand::issue // add a String Item to the results void TResultsCommand::addItemString( const char *aItemString // item string to be added ) { if (fResultsElementP && aItemString) { addItem(newStringDataItem(aItemString)); } } // TResultsCommand::addItemString // add an Item to the results void TResultsCommand::addItem( SmlItemPtr_t aItemP // existing item data structure, ownership is passed to Results ) { if (fResultsElementP) addItemToList(aItemP,&(fResultsElementP->itemList)); } // TResultsCommand::addItem // set Meta of the results command void TResultsCommand::setMeta( SmlPcdataPtr_t aMetaP // existing meta data structure, ownership is passed to Get ) { if (fResultsElementP) fResultsElementP->meta=aMetaP; } // TResultsCommand::setMeta // analyze command (but do not yet execute) bool TResultsCommand::analyze(TPackageStates aPackageState) { TSmlCommand::analyze(aPackageState); // get Command ID and flags if (fResultsElementP) { StartProcessing(fResultsElementP->cmdID,0); return true; } else return false; // no proto element, bad command } // TResultsCommand::analyze // execute command (perform real actions, generate status) // returns true if command has executed and can be deleted bool TResultsCommand::execute(void) { TStatusCommand *statusCmdP=NULL; SmlItemListPtr_t thisitemnode,nextitemnode; // process items thisitemnode=fResultsElementP->itemList; while (thisitemnode) { nextitemnode = thisitemnode->next; if (!thisitemnode->item) SYSYNC_THROW(TSyncException("Results with NULL item")); // get Source LocURI string locURI=smlSrcTargLocURIToCharP(thisitemnode->item->source); DEBUGPRINTFX(DBG_HOT,("processing item with locURI=%s",locURI.c_str())); // let session (and descendants) process it // - default to ok status statusCmdP = newStatusCommand(200); fSessionP->processPutResultItem(false,locURI.c_str(),this,thisitemnode->item,*statusCmdP); #ifdef RESULTS_SENDS_STATUS // now complete and issue status statusCmdP->addSourceRef(locURI.c_str()); // add source ref ISSUE_COMMAND_ROOT(fSessionP,statusCmdP); #else // suppress (forget) status delete statusCmdP; #endif // next item thisitemnode=nextitemnode; } // free element FreeSmlElement(); // done with command, delete it now: return true return true; } // TResultsCommand::execute void TResultsCommand::FreeSmlElement(void) { // remove SyncML toolkit element(s) FREEPROTOELEMENT(fResultsElementP); } // TResultsCommand::FreeSmlElement TResultsCommand::~TResultsCommand() { // free command elements, if any (use explicit invocation as this is a destructor) TResultsCommand::FreeSmlElement(); } // TResultsCommand::TResultsCommand /* end of TResultsCommand implementation */ /* * Implementation of TDevInfResultsCommand */ // constructor for generating devInf results TDevInfResultsCommand::TDevInfResultsCommand( TSyncSession *aSessionP, // associated session (for callbacks) TSmlCommand *aCommandP // command these results refer to ) : /* %%% if strictly following example in SyncML protocol specs * DevInf results don't have a source or target ref, only the item has TResultsCommand(aSessionP,aCommandP,SYNCML_DEVINF_LOCURI,NULL) */ TResultsCommand(aSessionP,aCommandP,NULL,NULL) { // standard result is now created // - create meta type /* %%% if strictly following example in SyncML protocol specs, meta * must be defined in the result/put command, not the individual item */ string metatype=SYNCML_DEVINF_META_TYPE; fSessionP->addEncoding(metatype); fResultsElementP->meta=newMetaType(metatype.c_str()); // - add local DevInf item to result // Note: explicit GET always returns entire devInf (all datastores) addItem(fSessionP->getLocalDevInfItem(false,false)); } // TDevInfResultsCommand::TDevInfResultsCommand // - try to shrink command by at least aReduceByBytes // Returns false if shrink is not possible bool TDevInfResultsCommand::shrinkCommand(sInt32 aReduceByBytes) { // measure current size (with current CmdID/MsgID) sInt32 origfree = evalIssue(fCmdID,fMsgID,fNoResp); // extract original devInf SmlItemPtr_t origDevInf = fResultsElementP->itemList->item; // remove it from the item list fResultsElementP->itemList->item = NULL; smlFreeItemList(fResultsElementP->itemList); fResultsElementP->itemList = NULL; // create reduced version of the devInf // - only alerted datastores if initialisation is complete (i.e. we KNOW which datastores the sync is about) // - no CTCap property lists SmlItemPtr_t reducedDevInf = fSessionP->getLocalDevInfItem( fSessionP->getIncomingState()>psta_init, // alerted only if init complete true // no CTCap property lists ); // insert it into command addItem(reducedDevInf); // measure again sInt32 nowfree = evalIssue(fCmdID,fMsgID,fNoResp); // decide if we are successful if (nowfree-origfree>=aReduceByBytes) { // new devinf matches size requirement smlFreeItemPtr(origDevInf); // discard original devInf return true; // shrink successful } else { // new reduced devInf is still too big fResultsElementP->itemList->item = origDevInf; // restore oiginal devInf smlFreeItemPtr(reducedDevInf); // discard reduced one return false; // cannot shrink enough } } // TDevInfResultsCommand::shrinkCommand // mark devinf as sent when issuing command bool TDevInfResultsCommand::issue( uInt32 aAsCmdID, // command ID to be used uInt32 aInMsgID, // message ID in which command is being issued bool aNoResp ) { fSessionP->remoteGotDevinf(); return TResultsCommand::issue(aAsCmdID,aInMsgID,aNoResp); } // TDevInfResultsCommand::issue void TDevInfResultsCommand::FreeSmlElement(void) { // remove SyncML toolkit element(s) // - result might already be freed! if (fResultsElementP) { FREEPROTOELEMENT(fResultsElementP); } } // TDevInfResultsCommand::FreeSmlElement TDevInfResultsCommand::~TDevInfResultsCommand() { // free command elements, if any (use explicit invocation as this is a destructor) TDevInfResultsCommand::FreeSmlElement(); // NOTE: fResultsElementP is NULLed so invocation of base class destuctor does no harm } // TDevInfResultsCommand::TDevInfResultsCommand /* end of TDevInfResultsCommand implementation */ /* * Implementation of TDevInfResultsCommand */ // constructor for generating devinf Put command TDevInfPutCommand::TDevInfPutCommand( TSyncSession *aSessionP // associated session (for callbacks) ) : TPutCommand(aSessionP) { // standard put is now created // - create meta type /* %%% if strictly following example in SyncML protocol specs, meta * must be defined in the result/put command, not the individual item */ string metatype=SYNCML_DEVINF_META_TYPE; fSessionP->addEncoding(metatype); fPutElementP->meta=newMetaType(metatype.c_str()); // - add local DevInf item to result // Note: PUT of server only returns alerted datastore's devInf addItem(fSessionP->getLocalDevInfItem(IS_SERVER,false)); } // TDevInfPutCommand::TDevInfPutCommand // mark devinf as sent when issuing command bool TDevInfPutCommand::issue( uInt32 aAsCmdID, // command ID to be used uInt32 aInMsgID, // message ID in which command is being issued bool aNoResp ) { fSessionP->remoteGotDevinf(); return TPutCommand::issue(aAsCmdID,aInMsgID,aNoResp); } // TDevInfPutCommand::issue void TDevInfPutCommand::FreeSmlElement(void) { // remove SyncML toolkit element(s) // - result might already be freed! if (fPutElementP) { FREEPROTOELEMENT(fPutElementP); } } // TDevInfPutCommand::FreeSmlElement TDevInfPutCommand::~TDevInfPutCommand() { // free command elements, if any (use explicit invocation as this is a destructor) TDevInfPutCommand::FreeSmlElement(); // NOTE: fResultsElementP is NULLed so invocation of base class destuctor does not harm } // TDevInfPutCommand::~TDevInfPutCommand /* end of TDevInfPutCommand implementation */ #endif // SYNCCOMMAND_PART2_EXCLUDE // eof libsynthesis-3.4.0.47.1/src/sysync/synccommand.h000077500000000000000000001032231226375725500214530ustar00rootroot00000000000000/* * File: SyncCommand.cpp * * Author: Lukas Zeller (luz@plan44.ch) * * TSmlCommand, TXXXCmd.... * Wrapper classes for SyncML Commands and the associated SyncML * Toolkit mechanics. * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * 2001-05-30 : luz : created * */ #ifndef SyncCommand_H #define SyncCommand_H // includes #include "sysync.h" using namespace sysync; namespace sysync { // forward class TSyncDataStore; class TLocalEngineDS; class TRemoteDataStore; // default command size #define DEFAULTCOMMANDSIZE 200; // Command Types (Note: not only strictly commands, but all // SyncML protocol items that need command-like processin // are wrapped in a command, too, e.g. "SyncHdr" typedef enum { scmd_synchdr, scmd_sync, scmd_syncend, scmd_add, scmd_alert, scmd_delete, scmd_get, scmd_put, scmd_map, scmd_results, scmd_status, scmd_replace, scmd_copy, scmd_move, scmd_sequence, scmd_atomic, scmd_unknown, numSmlCommandTypes } TSmlCommandTypes; // forward class TStatusCommand; class TSyncSession; class TSyncAppBase; // abstract base command class class TSmlCommand : noncopyable { public: // constructor for ALL commands TSmlCommand( TSmlCommandTypes aCmdType, // the command type bool aOutgoing, // set if this is a outgoing command (to avoid confusion) TSyncSession *aSessionP, // associated session (for callbacks) uInt32 aMsgID=0 // the Message ID of the command (0=none yet) ); virtual ~TSmlCommand(); // methods #ifdef SYDEBUG TDebugLogger *getDbgLogger(void); uInt32 getDbgMask(void); #endif // - get session owner (dispatcher/clientbase) TSyncAppBase *getSyncAppBase(void); #ifndef USE_SML_EVALUATION // - get (approximated) message size required for sending it virtual uInt32 messageSize(void); #endif // - analyze command (but do not yet execute) virtual bool analyze(TPackageStates aPackageState) { fPackageState=aPackageState; return true; }; // returns false if command is bad and cannot be executed // - execute() can be called even if there are other already queued commands. // True by default, exceptions must be defined explicitly. virtual bool canExecuteOutOfOrder() { return true; } // - execute command (perform real actions, generate status) virtual bool execute(void); // returns true if command could execute, false if it must be queued for later finishing (next message) // - get number of bytes that will be still available in the workspace after // sending this command. sInt32 evalIssue( uInt32 aAsCmdID, // command ID to be used uInt32 aInMsgID, // message ID in which command is being issued bool aNoResp=false // issue without wanting response ); // - issue (send) command to remote party // returns true if command must be put to the waiting-for-status queue. // If returns false, command can be deleted virtual bool issue( uInt32 aAsCmdID, // command ID to be used uInt32 aInMsgID, // message ID in which command is being issued bool aNoResp=false // issue without wanting response ); // - try to split (SyncML 1.1 moredata mechanism) command by reducing // original command by at least aReduceByBytes and generating a second // command containing the rest of the data // Returns NULL if split is not possible virtual TSmlCommand *splitCommand(sInt32 /* aReduceByBytes */) { return NULL; /* normal commands can't be split */ }; virtual bool canSplit(void) { return false; /* normal commands can't be split */ }; // - try to shrink command by at least aReduceByBytes // Returns false if shrink is not possible virtual bool shrinkCommand(sInt32 /* aReduceByBytes */) { return false; /* normal commands can't be shrunk */ }; // - possibly substitute data with previous session's buffered left-overs from a chunked transfer // for resuming a chunked item transfer. virtual bool checkChunkContinuation(void) { return false; /* normal commands can't split and so can't continue */ }; // - test if completely issued (must be called after issue() and continueIssue()) // or completely executed (must be called after execute() to see if command can be deleted) virtual bool finished(void) { return true; }; // normal commands finish after issuing/executing // - continue issuing command. This is called by session at start of new message // when finished() returned false after issue()/continueIssue() // (which causes caller of finished() to put command into fInteruptedCommands queue) // returns true if command should be queued for status (again?) // NOTE: continueIssue must make sure that it gets a new CmdID/MsgID in case // the command itself was NOT yet issued (normally this does not happen, but...) virtual bool continueIssue(bool & /* aNewIssue */) { return true; } // - test if command matches status bool matchStatus(TStatusCommand *aStatusCmdP); // - handle status received for previously issued command // returns true if done, false if command must be kept in the status queue virtual bool handleStatus(TStatusCommand *aStatusCmdP); // - mark any syncitems (or other data) for resume. Called for pending commands // when a Suspend alert is received or whenever a resumable state must be saved virtual void markPendingForResume(TLocalEngineDS *aForDatastoreP, bool aUnsent) { /* nop */ }; // - mark item for resend in next sync session (if possible) virtual void markForResend(void) { /* nop */ }; // - generate status depending on fNoResp and session's fMsgNoResp // NOTE: always returns a Status (NoResp is handled by not SENDING status) TStatusCommand *newStatusCommand(TSyError aStatusCode, const char *aStringItem=NULL); // properties bool getNoResp(void) { return fNoResp; }; // noResp condition bool getDontSend(void) { return fDontSend; }; // send inhibited condition void dontSend(void) { fDontSend=true; }; // prevent sending this command void allowFailure(void) { fAllowFailure=true; }; // allow failure (don't abort session if this command returns 4xx or 5xx status) const char * getName(void); // name of command uInt32 getCmdID(void) { return fCmdID; }; // ID of command uInt32 getMsgID(void) { return fMsgID; }; // Message ID TSmlCommandTypes getCmdType(void) { return fCmdType; }; // get command type bool isWaitingForStatus(void) { return fWaitingForStatus>0; }; void setWaitingForStatus(bool w) { if (w) fWaitingForStatus++; else if (fWaitingForStatus>0) fWaitingForStatus--; }; TPackageStates getPackageState(void) { return fPackageState; }; virtual SmlPcdataPtr_t getMeta(void) { return NULL; }; virtual bool isSyncOp(void) { return false; }; virtual bool neverIgnore(void) { return false; }; // normal commands should be ignored when in fIgnoreIncomingCommands state virtual bool statusEssential(void) { return true; }; // normal commands MUST receive status void queueStatusCmd(TSmlCommand *aSyncCommandP); // to be called by TSyncSession::issuePtr() bool hasQueuedStatusCmds() const; void transferQueuedStatusCmds(TSmlCommandPContainer &commands); // transfer ownership of pending commands to caller protected: // helper methods for derived classes // - get name of certain command const char *getNameOf(TSmlCommandTypes aCmdType); // - start processing a command void StartProcessing( SmlPcdataPtr_t aCmdID, // ID of command Flag_t aFlags // flags of command ); // - prepare elements for issuing void PrepareIssue( SmlPcdataPtr_t *aCmdID=NULL, // ID of command Flag_t *aFlags=NULL // flags of command ); void FinalizeIssue(void); // finalizes issuing a command (updates message size) // returns true if command must be queued for status or result response virtual bool queueForResponse(void); // - generate and issue status depending on fNoResp and session's fMsgNoResp void issueStatusCommand(TSyError aStatusCode); // - free smlProtoElement structure (if any). Includes precautions if structure contains // parts that are not owned by the command itself virtual void FreeSmlElement(void) { /* nop in base class */ }; // debug #ifdef SYDEBUG // print to (session-related) debug output channel void DebugPrintf(const char *text, ...); #endif // session TSyncSession *fSessionP; // command info TSmlCommandTypes fCmdType; TPackageStates fPackageState; // incoming or outgoing package state of this command (may be different from current state for delayed commands) bool fOutgoing; // set if outgoing command bool fNoResp; uInt32 fCmdID; // command ID uInt32 fMsgID; // message ID // message size calculation uInt32 fBytesbefore; // commands that should not be sent (e.g. a "response" to a NoResp command) bool fDontSend; // set to signal to issue that this is a size evaluation issuing, not a real one bool fEvalMode; // set if PrepareIssue() was already called bool fPrepared; // set if command may fail with status 4xx or 5xx without aborting the session bool fAllowFailure; private: uInt16 fWaitingForStatus; // count for how many statuses a command is waiting TSmlCommandPContainer fPendingStatusReplies; // Status commands which could not be sent yet. }; // TSmlCommand // Unimplemented command class TUnimplementedCommand: public TSmlCommand { typedef TSmlCommand inherited; public: // constructor for generating devinf results TUnimplementedCommand( TSyncSession *aSessionP, // associated session (for callbacks) uInt32 aMsgID, // the Message ID of the command SmlPcdataPtr_t aCmdID, // command ID (as contents are unknown an cannot be analyzed) Flag_t aFlags, // flags to get fNoResp TSmlCommandTypes aCmdType=scmd_unknown, // command type (for name) void *aContentP=NULL, // associated command content element TSyError aStatusCode=406 // status code to be returned on execution (default = unimplemented option 406) ); virtual bool execute(void); private: TSyError fStatusCode; }; // TUnimplementedCommand // Sync Header "command" class TSyncHeader: public TSmlCommand { typedef TSmlCommand inherited; public: // constructor for receiving SyncHdr TSyncHeader( TSyncSession *aSessionP, // associated session (for callbacks) SmlSyncHdrPtr_t aSyncHdrElementP=NULL // associated SyncHdr content element ); // constructor for sending SyncHdr TSyncHeader( TSyncSession *aSessionP, // associated session (for callbacks) bool aOutgoingNoResp=false // if true, entire message will request no responses ); virtual ~TSyncHeader(); virtual bool execute(void); virtual bool issue( uInt32 aAsCmdID, // command ID to be used (is dummy=0 for SyncHdr) uInt32 aInMsgID, // message ID in which command is being issued bool aNoResp=false // issue without wanting response FOR ENTIRE message ); // returns false, because command can be deleted immediately after issue() virtual bool statusEssential(void) { return false; }; // header status is not essential (per se - of course it is for login) // - handle status received for previously issued command // returns true if done, false if command must be kept in the status queue virtual bool handleStatus(TStatusCommand *aStatusCmdP); protected: virtual void FreeSmlElement(void); SmlSyncHdrPtr_t fSyncHdrElementP; }; // TSyncHeader // Alert Command class TAlertCommand: public TSmlCommand { typedef TSmlCommand inherited; public: // constructor for receiving Alert TAlertCommand( TSyncSession *aSessionP, // associated session (for callbacks) uInt32 aMsgID, // the Message ID of the command SmlAlertPtr_t aAlertElementP // associated Alert content element ); // constructor for sending Alert TAlertCommand( TSyncSession *aSessionP, // associated session (for callbacks) TLocalEngineDS *aLocalDataStoreP, // local datastore uInt16 aAlertCode // Alert code to send ); virtual ~TAlertCommand(); virtual bool analyze(TPackageStates aPackageState); virtual bool execute(void); virtual bool issue( uInt32 aAsCmdID, // command ID to be used (is dummy=0 for SyncHdr) uInt32 aInMsgID, // message ID in which command is being issued bool aNoResp=false // issue without wanting response ); // returns false, because command can be deleted immediately after issue() virtual bool statusEssential(void); // depends on alert code if it is essential // - add a String Item void addItemString(const char *aItemString); // item string to be added // - add an Item void addItem(SmlItemPtr_t aItemP); // existing item data structure, ownership is passed to Command // - handle status received for previously issued command // returns true if done, false if command must be kept in the status queue virtual bool handleStatus(TStatusCommand *aStatusCmdP); protected: virtual void FreeSmlElement(void); SmlAlertPtr_t fAlertElementP; uInt16 fAlertCode; // alert code // involved datastore TLocalEngineDS *fLocalDataStoreP; }; // TAlertCommand // Sync Command class TSyncCommand: public TSmlCommand { typedef TSmlCommand inherited; public: // constructor for receiving Sync TSyncCommand( TSyncSession *aSessionP, // associated session (for callbacks) uInt32 aMsgID, // the Message ID of the command SmlSyncPtr_t aSyncElementP=NULL // associated Sync content element ); // constructor for sending Sync TSyncCommand( TSyncSession *aSessionP, // associated session (for callbacks) TLocalEngineDS *aLocalDataStoreP, // local datastore TRemoteDataStore *aRemoteDataStoreP // remote datastore ); virtual ~TSyncCommand(); virtual bool analyze(TPackageStates aPackageState); virtual bool execute(void); virtual bool issue( uInt32 aAsCmdID, // command ID to be used (is dummy=0 for SyncHdr) uInt32 aInMsgID, // message ID in which command is being issued bool aNoResp=false // issue without wanting response ); // - test if completely issued (must be called after issue() and continueIssue()) // or completely executed (must be called after execute() to see if command can be deleted) virtual bool finished(void); // normal command finish // - continue issuing command. virtual bool continueIssue(bool &aNewIssue); // - handle status received for previously issued command // returns true if done, false if command must be kept in the status queue virtual bool handleStatus(TStatusCommand *aStatusCmdP); // - mark any syncitems (or other data) for resume. Called for pending commands // when a Suspend alert is received or whenever a resumable state must be saved virtual void markPendingForResume(TLocalEngineDS *aForDatastoreP, bool aUnsent); void setLocalDatastore(TLocalEngineDS *aLocalDataStoreP) { fLocalDataStoreP=aLocalDataStoreP; } TLocalEngineDS *getLocalDatastore() const { return fLocalDataStoreP; } protected: virtual void FreeSmlElement(void); SmlSyncPtr_t fSyncElementP; private: // internals bool generateOpen(void); void generateCommandsAndClose(void); bool fInProgress; // set if bracket must be re-opened in next message (=not finished) // variables for sync needing more than one message TSmlCommandPContainer fNextMessageCommands; TSmlCommand *fInterruptedCommandP; // involved datastores and mode TLocalEngineDS *fLocalDataStoreP; TRemoteDataStore *fRemoteDataStoreP; }; // TSyncCommand // Sync End Command (closing bracket: ) // Note: used for receiving only, when sending, the closing // bracket is part of TSyncCommand production process. class TSyncEndCommand: public TSmlCommand { typedef TSmlCommand inherited; public: // constructor for receiving TSyncEndCommand( TSyncSession *aSessionP, // associated session (for callbacks) uInt32 aMsgID // the Message ID of the command ); virtual ~TSyncEndCommand(); virtual bool execute(void); }; // TSyncEndCommand // bytes required for empty item (approx) /* */ #define ITEMOVERHEADSIZE 90 // minimum size of data for a first split #define MIN_SPLIT_DATA 200 // SyncOp (Add/Delete/Replace/Copy/Move) command class TSyncOpCommand: public TSmlCommand { typedef TSmlCommand inherited; public: // constructor for receiving SyncOP command TSyncOpCommand( TSyncSession *aSessionP, // associated session (for callbacks) TLocalEngineDS *aDataStoreP, // the local datastore this syncop belongs to uInt32 aMsgID, // the Message ID of the command TSyncOperation aSyncOp, // the Sync operation (sop_xxx) TSmlCommandTypes aCmdType, // the command type (scmd_xxx) SmlGenericCmdPtr_t aSyncOpElementP=NULL // associated syncml protocol element ); // constructor for sending command TSyncOpCommand( TSyncSession *aSessionP, // associated session (for callbacks) TLocalEngineDS *aDataStoreP, // datastore from which command originates TSyncOperation aSyncOp, // sync operation (=command type) SmlPcdataPtr_t aMetaP // meta for entire command (passing owner) ); virtual ~TSyncOpCommand(); virtual bool isSyncOp() { return true; }; virtual bool analyze(TPackageStates aPackageState); virtual bool canExecuteOutOfOrder(); virtual bool execute(void); #ifndef USE_SML_EVALUATION // - get (approximated) message size required for sending it virtual uInt32 messageSize(void); #endif // - add an Item to an existing Sync op command void addItem(SmlItemPtr_t aItemP); // existing item data structure, ownership is passed to SyncOpCmd // returns true if command must be put to the waiting-for-status queue. // If false, command can be deleted bool issue( uInt32 aAsCmdID, // command ID to be used uInt32 aInMsgID, // message ID in which command is being issued bool aNoResp // dummy here, because Status has always no response ); // - try to split (e.g using SyncML 1.1 moredata mechanism) command by reducing // original command by at least aReduceByBytes and generating a second // command containing the rest of the data // Returns NULL if split is not possible virtual TSmlCommand *splitCommand(sInt32 aReduceByBytes); virtual bool canSplit(void); // - possibly substitute data with previous session's buffered left-overs from a chunked transfer // for resuming a chunked item transfer. virtual bool checkChunkContinuation(void); // - test if completely issued (must be called after issue() and continueIssue()) // or completely executed (must be called after execute() to see if command can be deleted) virtual bool finished(void); // normal command finish /* %%% not used any more with new splitCommand // - continue issuing command. This is called by session at start of new message // when finished() returned false after issue()/continueIssue() // (which causes caller of finished() to put command into fInteruptedCommands queue) // returns true if command should be queued for status (again?) // NOTE: continueIssue must make sure that it gets a new CmdID/MsgID in case // the command itself was NOT yet issued (normally this does not happen, but...) virtual bool continueIssue(bool &aNewIssue); */ // - handle status received for previously issued command // returns true if done, false if command must be kept in the status queue virtual bool handleStatus(TStatusCommand *aStatusCmdP); // - mark any unstatused mapitems for resume. Called for pending commands // when a Suspend alert is received or whenever a resumable state must be saved virtual void markPendingForResume(TLocalEngineDS *aForDatastoreP, bool aUnsent); // - mark item for resend in next sync session (if possible) virtual void markForResend(void); // - let item update the partial item state for suspend void updatePartialItemState(TLocalEngineDS *aForDatastoreP); // - get sync op TSyncOperation getSyncOp(void) { return fSyncOp; }; // - get source (localID) of sent command cAppCharP getSourceLocalID(void); // - get target (remoteID) of sent command cAppCharP getTargetRemoteID(void); protected: localstatus AddNextChunk(SmlItemPtr_t aNextChunkItem, TSyncOpCommand *aCmdP); void saveAsPartialItem(SmlItemPtr_t aItemP); virtual void FreeSmlElement(void); SmlGenericCmdPtr_t fSyncOpElementP; #ifndef USE_SML_EVALUATION uInt32 fItemSizes; // accumulated item size #endif TSyncOperation fSyncOp; // Sync operation (sop_xxx) TLocalEngineDS *fDataStoreP; // SyncML 1.1 data segmentation uInt32 fChunkedItemSize; // size of object currently being chunked bool fIncompleteData; // set for commands that do not tranfer the final chunk (and must be answered with 213 status) // SyncML 1.2 resuming a chunked item transmission uInt32 fStoredSize; // from previous session uInt32 fUnconfirmedSize; // from previous session uInt32 fLastChunkSize; // size of last chunk received in THIS session (=probably unconfirmed reception, will probably be sent again from remote) }; // TSyncOpCommand // Map command class TMapCommand: public TSmlCommand { typedef TSmlCommand inherited; public: // Common for client and server virtual ~TMapCommand(); #ifndef USE_SML_EVALUATION // - get (approximated) message size required for sending it virtual uInt32 messageSize(void); #endif // - constructor for receiving MAP command TMapCommand( TSyncSession *aSessionP, // associated session (for callbacks) uInt32 aMsgID, // the Message ID of the command SmlMapPtr_t aMapElementP // associated syncml protocol element ); #ifdef SYSYNC_SERVER // Server implementation virtual bool analyze(TPackageStates aPackageState); virtual bool execute(void); #endif // SYSYNC_SERVER #ifdef SYSYNC_CLIENT // Client implementation // - constructor for sending MAP TMapCommand( TSyncSession *aSessionP, // associated session (for callbacks) TLocalEngineDS *aLocalDataStoreP, // local datastore TRemoteDataStore *aRemoteDataStoreP // remote datastore ); virtual bool issue( uInt32 aAsCmdID, // command ID to be used (is dummy=0 for SyncHdr) uInt32 aInMsgID, // message ID in which command is being issued bool aNoResp=false // issue without wanting response ); // - test if completely issued (must be called after issue() and continueIssue()) // or completely executed (must be called after execute() to see if command can be deleted) virtual bool finished(void); // normal command finish // - continue issuing command. virtual bool continueIssue(bool &aNewIssue); // - add map item void addMapItem(const char *aLocalID, const char *aRemoteID); // - remove last added map item from the command void deleteLastMapItem(void); // - handle status received for previously issued command // returns true if done, false if command must be kept in the status queue virtual bool handleStatus(TStatusCommand *aStatusCmdP); #endif // SYSYNC_CLIENT protected: virtual void FreeSmlElement(void); SmlMapPtr_t fMapElementP; private: // internals #ifdef SYSYNC_CLIENT void generateEmptyMapElement(void); void generateMapItems(void); #endif bool fInProgress; // set if command must be continued in next message (=not finished) // involved datastores and mode TLocalEngineDS *fLocalDataStoreP; TRemoteDataStore *fRemoteDataStoreP; #ifndef USE_SML_EVALUATION // size uInt32 fItemSizes; // accumulated item size #endif }; // TMapCommand // Get command class TGetCommand: public TSmlCommand { typedef TSmlCommand inherited; public: // constructor for receiving GET command TGetCommand( TSyncSession *aSessionP, // associated session (for callbacks) uInt32 aMsgID, // the Message ID of the command SmlGetPtr_t aGetElementP=NULL // associated GET command content element ); // constructor for sending command TGetCommand( TSyncSession *aSessionP // associated session (for callbacks) ); // add an Item to the get command void addItem( SmlItemPtr_t aItemP // existing item data structure, ownership is passed to Get ); // set Meta of the get command void setMeta( SmlPcdataPtr_t aMetaP // existing meta data structure, ownership is passed to Get ); // get meta of the get command virtual SmlPcdataPtr_t getMeta(void) { return fGetElementP==NULL ? NULL : fGetElementP->meta; }; // add a target specification Item to the get command void addTargetLocItem( const char *aTargetURI, const char *aTargetName=NULL ); virtual ~TGetCommand(); virtual bool analyze(TPackageStates aPackageState); virtual bool execute(void); virtual bool issue( uInt32 aAsCmdID, // command ID to be used uInt32 aInMsgID, // message ID in which command is being issued bool aNoResp=true // status does not want response by default ); // returns true if command must be put to the waiting-for-status queue. If false, command can be deleted virtual bool statusEssential(void); // can be essential or not // - handle status received for previously issued command // returns true if done, false if command must be kept in the status queue virtual bool handleStatus(TStatusCommand *aStatusCmdP); protected: virtual void FreeSmlElement(void); SmlGetPtr_t fGetElementP; }; // TGetCommand // Put command class TPutCommand: public TSmlCommand { typedef TSmlCommand inherited; public: // constructor for receiving PUT command TPutCommand( TSyncSession *aSessionP, // associated session (for callbacks) uInt32 aMsgID, // the Message ID of the command SmlGetPtr_t aPutElementP=NULL // associated PUT command content element ); // constructor for sending command TPutCommand( TSyncSession *aSessionP // associated session (for callbacks) ); // add an Item to the put command void addItem( SmlItemPtr_t aItemP // existing item data structure, ownership is passed to Get ); // set Meta of the put command void setMeta( SmlPcdataPtr_t aMetaP // existing meta data structure, ownership is passed to Get ); // get meta of the put command virtual SmlPcdataPtr_t getMeta(void) { return fPutElementP==NULL ? NULL : fPutElementP->meta; }; // add a source specification + data Item to the Put command SmlItemPtr_t addSourceLocItem( const char *aTargetURI, const char *aTargetName=NULL ); virtual ~TPutCommand(); virtual bool analyze(TPackageStates aPackageState); virtual bool execute(void); virtual bool issue( uInt32 aAsCmdID, // command ID to be used uInt32 aInMsgID, // message ID in which command is being issued bool aNoResp=true // status does not want response by default ); // returns true if command must be put to the waiting-for-status queue. If false, command can be deleted protected: virtual void FreeSmlElement(void); SmlPutPtr_t fPutElementP; }; // TPutCommand // Status command class TStatusCommand: public TSmlCommand { typedef TSmlCommand inherited; friend class TSmlCommand; // command may look into status public: // constructor for generating status TStatusCommand( TSyncSession *aSessionP, // associated session (for callbacks) TSmlCommand *aCommandP, // command this status refers to, NULL=response to message header TSyError aStatusCode // status code ); // constructor for generating status w/o having a command object (e.g. dummy) TStatusCommand( TSyncSession *aSessionP, // associated session (for callbacks) uInt32 aRefCmdID=0, // referred-to command ID TSmlCommandTypes aRefCmdType=scmd_unknown, // referred-to command type (scmd_xxx) bool aNoResp=true, // set if no-Resp TSyError aStatusCode=0 // status code ); // constructor for receiving status TStatusCommand( TSyncSession *aSessionP, // associated session (for callbacks) uInt32 aMsgID, // the Message ID of the command SmlStatusPtr_t aStatusElementP=NULL // associated STATUS command content element ); virtual ~TStatusCommand(); virtual bool analyze(TPackageStates aPackageState); // analyze status virtual bool execute(void) { return true; }; // cannot be executed #ifndef USE_SML_EVALUATION // - get (approximated) message size required for sending it virtual uInt32 messageSize(void) { return fDontSend ? 0 : TSmlCommand::messageSize(); }; #endif virtual bool issue( uInt32 aAsCmdID, // command ID to be used uInt32 aInMsgID, // message ID in which command is being issued bool aNoResp=true // status does not want response by default ); // returns true if command must be put to the waiting-for-status queue. If false, command can be deleted // status building tools // - add a target Ref void addTargetRef(const char *aTargetRef); // Target LocURI of an item this status applies to // - add a source Ref to an existing status void addSourceRef(const char *aSourceRef); // Source LocURI of an item this status applies to // - add a String Item to an existing status void addItemString(const char *aItemString); // item string to be added // - add an Item to an existing status void addItem(SmlItemPtr_t aItemP); // existing item data structure, ownership is passed to Status // - move items from another status to this one (passes ownership of items and deletes them from original) void moveItemsFrom(TStatusCommand *aStatusCommandP); // - set Status code void setStatusCode(TSyError aStatusCode); // - set Challenge of an existing status (overwrites existing one, if any) void setChallenge(SmlChalPtr_t aChallengeP); // existing challenge data structure, ownership is passed to Status // properties // - get status code TSyError getStatusCode(void) { return fStatusCode; }; // - get status Sml Element const SmlStatusPtr_t getStatusElement(void) { return fStatusElementP; } protected: virtual void FreeSmlElement(void); SmlStatusPtr_t fStatusElementP; // info TSyError fStatusCode; // status code uInt32 fRefMsgID; // referenced message ID uInt32 fRefCmdID; // referenced command ID TSmlCommandTypes fRefCmdType; // referenced command type }; // TStatusCommand // Results command class TResultsCommand: public TSmlCommand { typedef TSmlCommand inherited; public: // constructor for generating results TResultsCommand( TSyncSession *aSessionP, // associated session (for callbacks) TSmlCommand *aCommandP, // command this status refers to const char *aTargetRef, // target reference const char *aSourceRef // source reference ); // constructor for receiving command TResultsCommand( TSyncSession *aSessionP, // associated session (for callbacks) uInt32 aMsgID, // the Message ID of the command SmlResultsPtr_t aResultsElementP // associated syncml protocol element ); virtual ~TResultsCommand(); virtual bool neverIgnore() { return true; }; // result for devInf we requested should never be ignored virtual bool analyze(TPackageStates aPackageState); virtual bool execute(void); virtual bool issue( uInt32 aAsCmdID, // command ID to be used uInt32 aInMsgID, // message ID in which command is being issued bool aNoResp=false // issue without wanting response ); // returns true if command must be put to the waiting-for-status queue. If false, command can be deleted // results building tools // - add a String Item to results void addItemString(const char *aItemString); // item string to be added // - add an Item to results void addItem(SmlItemPtr_t aItemP); // existing item data structure, ownership is passed to Status // set Meta of the results command void setMeta( SmlPcdataPtr_t aMetaP // existing meta data structure, ownership is passed to Get ); // get meta of the results command virtual SmlPcdataPtr_t getMeta(void) { return fResultsElementP==NULL ? NULL : fResultsElementP->meta; }; protected: virtual void FreeSmlElement(void); SmlResultsPtr_t fResultsElementP; }; // TResultsCommand // DevInf Results command (specialized TResultsCommand derivate for sending devInf) class TDevInfResultsCommand: public TResultsCommand { typedef TResultsCommand inherited; public: // constructor for generating devinf results TDevInfResultsCommand( TSyncSession *aSessionP, // associated session (for callbacks) TSmlCommand *aCommandP // command this status refers to ); virtual ~TDevInfResultsCommand(); virtual bool issue( uInt32 aAsCmdID, // command ID to be used uInt32 aInMsgID, // message ID in which command is being issued bool aNoResp ); virtual bool statusEssential(void) { return false; }; // results status is not essential // - try to shrink command by at least aReduceByBytes // Returns false if shrink is not possible virtual bool shrinkCommand(sInt32 aReduceByBytes); protected: virtual void FreeSmlElement(void); }; // TDevInfResultsCommand // DevInf Put command (specialized TPutCommand derivate for sending devInf) class TDevInfPutCommand: public TPutCommand { typedef TPutCommand inherited; public: // constructor for generating devinf Put TDevInfPutCommand( TSyncSession *aSessionP // associated session (for callbacks) ); virtual ~TDevInfPutCommand(); virtual bool issue( uInt32 aAsCmdID, // command ID to be used uInt32 aInMsgID, // message ID in which command is being issued bool aNoResp ); virtual bool statusEssential(void) { return false; }; // devInf Put status is not essential protected: virtual void FreeSmlElement(void); }; // TDevInfPutCommand } // namespace sysync #endif // SyncCommand_H // eof libsynthesis-3.4.0.47.1/src/sysync/syncdatastore.cpp000077500000000000000000000235421226375725500223630ustar00rootroot00000000000000/* * File: SyncDataStore.cpp * * Author: Lukas Zeller (luz@plan44.ch) * * TSyncDataStore * * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * 2001-xx-xx : luz : created * */ // includes #include "prefix_file.h" #include "sysync.h" #include "syncdatastore.h" #include "syncsession.h" using namespace sysync; /* * Implementation of TSyncDataStore */ void TSyncDataStore::init(TSyncSession *aSessionP) { // save link to session fSessionP=aSessionP; // no sync capabilities by default fCommonSyncCapMask=0; // name not known fName="[unknown]"; // no types fRxPrefItemTypeP = NULL; fTxPrefItemTypeP = NULL; // no max GUID size yet fMaxGUIDSize = 0; // unlimited (that is, maximum possible with longlong) size and ID #ifdef __BORLANDC__ fMaxMemory = numeric_limits::max(); fFreeMemory = fMaxMemory; fMaxID = numeric_limits::max(); fFreeID = fMaxID; #elif defined(LINUX) || defined(WINCE) || defined(_MSC_VER) || defined(__EPOC_OS__) fMaxMemory = LONG_MAX; fFreeMemory = fMaxMemory; fMaxID = LONG_MAX; fFreeID = fMaxID; #else fMaxMemory = numeric_limits<__typeof__(fMaxMemory)>::max(); fFreeMemory = fMaxMemory; fMaxID = numeric_limits<__typeof__(fMaxID)>::max(); fFreeID = fMaxID; #endif fCanRestart = false; // rest ist like reset InternalResetDataStore(); } // TSyncDataStore::init TSyncDataStore::TSyncDataStore(TSyncSession *aSessionP) { init(aSessionP); } // TSyncDataStore::TSyncDataStore TSyncDataStore::TSyncDataStore(TSyncSession *aSessionP, const char *aName, uInt32 aCommonSyncCapMask) { // basic init init(aSessionP); // make sure we have SyncML minimal Caps, save it fCommonSyncCapMask=aCommonSyncCapMask | SCAP_MASK_MINIMAL; // save name of datastore fName = aName; } // TSyncDataStore::TSyncDataStore void TSyncDataStore::setPreferredTypes(TSyncItemType *aRxItemTypeP, TSyncItemType *aTxItemTypeP) { // save standard Rx and Tx preferences fRxPrefItemTypeP = aRxItemTypeP; fTxPrefItemTypeP = aTxItemTypeP ? aTxItemTypeP : aRxItemTypeP; // add them to the tx/rx lists fRxItemTypes.push_back(fRxPrefItemTypeP); fTxItemTypes.push_back(fTxPrefItemTypeP); } // TSyncDataStore::setPreferredTypes void TSyncDataStore::InternalResetDataStore(void) { // empty for now } // TSyncDataStore::InternalResetDataStore TSyncDataStore::~TSyncDataStore() { InternalResetDataStore(); } // TSyncDataStore::~TSyncDataStore // - returns session zones GZones *TSyncDataStore::getSessionZones(void) { return fSessionP->getSessionZones(); } // TSyncDataStore::getSessionZones #ifdef SYDEBUG TDebugLogger *TSyncDataStore::getDbgLogger(void) { // commands log to session's logger return fSessionP ? fSessionP->getDbgLogger() : NULL; } // TSyncDataStore::getDbgLogger uInt32 TSyncDataStore::getDbgMask(void) { if (!fSessionP) return 0; // no session, no debug return fSessionP->getDbgMask(); } // TSyncDataStore::getDbgMask #endif TSyncAppBase *TSyncDataStore::getSyncAppBase(void) { return fSessionP ? fSessionP->getSyncAppBase() : NULL; } // TSyncDataStore::getSyncAppBase // check if this datastore is accessible with given URI // NOTE: URI might include path elements or CGI params that are // access options to the database; derived classes might // therefore base identity check on more than simple name match uInt16 TSyncDataStore::isDatastore(const char *aDatastoreURI) { // base class only implements case insensitive name comparison return strucmp(fName.c_str(),aDatastoreURI)==0 ? fName.size() : 0; } // TSyncDataStore::isDatastore /// @brief checks if specified type is used by this datastore /// @return true if type is used by this datastore /// @param aSyncItemType[in] type to be checked for being used /// @param aVariantDescP[out] if not NULL, will receive the variant descriptor associated with that use bool TSyncDataStore::doesUseType(TSyncItemType *aSyncItemType, TTypeVariantDescriptor *aVariantDescP) { // true if either used for send or for receive TSyncItemType *rx, *tx; rx=getReceiveType(aSyncItemType); tx=getSendType(aSyncItemType); // determine usage variant if needed if (aVariantDescP) { *aVariantDescP = getVariantDescForType(aSyncItemType); } // used if used as rx or tx return (rx!=NULL || tx!=NULL); } // TSyncDataStore::doesUseType // - returns type that this datastore can use to send data to specified datastore // Note: if possible, use preferred Rx type of specified datastore, if this // is not possible, use preferred Tx type of this datastore, else // use any matching pair. TSyncItemType *TSyncDataStore::getTypesForTxTo( TSyncDataStore *aDatastoreP, // usually remote datastore TSyncItemType **aCorrespondingTypePP ) { TSyncItemTypePContainer::iterator pos; TSyncItemType *corrP; TSyncItemType *txtypeP=NULL, *corrtypeP=NULL; // none found so far TSyncItemType *preftxP=NULL, *preftxcorrP=NULL; // none found so far // if no datastore there: none if (!aDatastoreP) return NULL; // get common type for transmitting TO specified datastore // - loop through all send types of myself for (pos=fTxItemTypes.begin(); pos!=fTxItemTypes.end(); ++pos) { // - check if remote has this type if ((corrP=aDatastoreP->getReceiveType(*pos))!=NULL) { // found matching type // - save pointers (we found at least one matching type) txtypeP=*pos; // TSyncItemType of this datastore corrtypeP=corrP; // TSyncItemType of other datastore // - check if preferred by remote if (aDatastoreP->getPreferredRxItemType()==corrtypeP) { // yes, this is best case, save it and stop searching preftxP=txtypeP; preftxcorrP=corrtypeP; break; // done } // - if found, but not preferred by remote, check if its our own preference if (getPreferredTxItemType()==txtypeP) { // remember in case we don't find the remote's preferred type preftxP=txtypeP; preftxcorrP=corrtypeP; // but continue because we might find remote's preferred } } } // Now txtypeP/corrtypeP are NULL if no match found // Now preftxP/=preftxcorrP are NULL if no preferred match found // check if we found a preferred if (preftxP) { // use it instead of last found (or NULL if none found) txtypeP=preftxP; corrtypeP=preftxcorrP; } // return send type if (aCorrespondingTypePP) *aCorrespondingTypePP = corrtypeP; // corresponding TSyncItemType of other datastore return txtypeP; } // TSyncDataStore::getTypesForTxTo // - returns type that this datastore can use to receive data from specified datastore TSyncItemType *TSyncDataStore::getTypesForRxFrom( TSyncDataStore *aDatastoreP, // usually remote datastore TSyncItemType **aCorrespondingTypePP ) { TSyncItemTypePContainer::iterator pos; TSyncItemType *rxtypeP=NULL, *corrP; // get common type for receiving FROM specified datastore for (pos=fRxItemTypes.begin(); pos!=fRxItemTypes.end(); ++pos) { // loop through all receive types of myself if ((corrP=aDatastoreP->getSendType(*pos))!=NULL) { // found rxtypeP=*pos; if (aCorrespondingTypePP) *aCorrespondingTypePP = corrP; // corresponding TSyncItemType of other datastore break; } } // return receive type return rxtypeP; } // TSyncDataStore::getTypesForRxFrom // get datastore's SyncItemType for receive of specified type, NULL if none TSyncItemType *TSyncDataStore::getReceiveType(const char *aType, const char *aVers) { return ( TSyncItemType::findTypeInList( fRxItemTypes, aType, aVers, false, // version doesn't need to match true, // but we want an implemented type NULL // no datastore link comparison ) ); } // TSyncDataStore::getReceiveType // get datastore's SyncItemType for receive of specified type, NULL if none TSyncItemType *TSyncDataStore::getReceiveType(TSyncItemType *aSyncItemTypeP) { return ( getReceiveType ( aSyncItemTypeP->getTypeName(), aSyncItemTypeP->getTypeVers() ) ); } // TSyncDataStore::getReceiveType // get datastore's SyncItemType for send of specified type, NULL if none TSyncItemType *TSyncDataStore::getSendType(const char *aType, const char *aVers) { return ( TSyncItemType::findTypeInList( fTxItemTypes, aType, aVers, false, // version doesn't need to match true, // but we want an implemented type NULL // no datastore link comparison ) ); } // TSyncDataStore::getSendType // get datastore's SyncItemType for send of specified type, NULL if none TSyncItemType *TSyncDataStore::getSendType(TSyncItemType *aSyncItemTypeP) { return ( getSendType( aSyncItemTypeP->getTypeName(), aSyncItemTypeP->getTypeVers() ) ); } // TSyncDataStore::getSendType // description structure of datastore (NULL if not available) SmlDevInfDatastorePtr_t TSyncDataStore::getDatastoreDevinf(bool aAsServer, bool aWithoutCTCapProps) { // get Datastore description (when I am a Server) return newDevInfDatastore(aAsServer, aWithoutCTCapProps); } // TSyncDataStore::getDatastoreDevinf // private helper for setDatastoreDevInf void TSyncDataStore::registerTypes( TSyncItemTypePContainer &aSupportedXmitTypes, SmlDevInfXmitListPtr_t aXmitTypeListP, TSyncItemTypePContainer &aLocalItemTypes, // list to look up local types (for reference) TSyncItemTypePContainer &aNewItemTypes, // list to add analyzed types if not already there TSyncDataStore *aRelatedDatastoreP ) { while (aXmitTypeListP) { if (aXmitTypeListP->data) { // register TSyncItemType *itemtypeP = TSyncItemType::registerRemoteType(fSessionP,aXmitTypeListP->data,aLocalItemTypes,aNewItemTypes,aRelatedDatastoreP); // add to list aSupportedXmitTypes.push_back(itemtypeP); } // next aXmitTypeListP=aXmitTypeListP->next; } } // TSyncDataStore::registerTypes /* end of TSyncDataStore implementation */ // eof libsynthesis-3.4.0.47.1/src/sysync/syncdatastore.h000077500000000000000000000153111226375725500220230ustar00rootroot00000000000000/* * File: SyncDataStore.h * * Author: Lukas Zeller (luz@plan44.ch) * * TSyncDataStore * * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * 2001-xx-xx : luz : created * */ #ifndef SyncDataStore_H #define SyncDataStore_H #include "syncitemtype.h" #include namespace sysync { // forward class TSyncItemType; class TSyncSession; class TSyncAppBase; class TSyncDataStore : noncopyable { private: void init(TSyncSession *aSessionP); // internal init void InternalResetDataStore(void); // reset for re-use without re-creation public: TSyncDataStore(TSyncSession *aSessionP); TSyncDataStore(TSyncSession *aSessionP, const char *aName, uInt32 aCommonSyncCapMask=0); virtual ~TSyncDataStore(); virtual void engResetDataStore(void) { InternalResetDataStore(); }; virtual void announceAgentDestruction(void) { /* nop */ }; ///< called while agent is still fully ok, so we must clean up such that later call of destructor does NOT access agent any more // set preferred type support void setPreferredTypes(TSyncItemType *aRxItemTypeP, TSyncItemType *aTxItemTypeP=NULL); // access datastore // - get name (as used in path) const char *getName(void) { return fName.c_str(); } // - return display name (descriptive) virtual const char *getDisplayName(void) #ifndef MINIMAL_CODE =0; // implemented in derivates #else { return getName(); }; // just return normal name #endif // - check if this datastore is accessible with given URI // NOTE: URI might include path elements or CGI params that are // access options to the database; derived classes might // therefore base identity check on more than simple name match virtual uInt16 isDatastore(const char *aDatastoreURI); // - returns if specified type is used by this datastore bool doesUseType(TSyncItemType *aSyncItemType, TTypeVariantDescriptor *aVariantDescP=NULL); // - true if data store is able to return 404 when asked to delete non-existent item virtual bool dsDeleteDetectsItemPresence() const { return false; } // - get common types to send to or receive from another datastore TSyncItemType *getTypesForTxTo(TSyncDataStore *aDatastoreP, TSyncItemType **aCorrespondingTypePP=NULL); TSyncItemType *getTypesForRxFrom(TSyncDataStore *aDatastoreP, TSyncItemType **aCorrespondingTypePP=NULL); // - get datastore's type for receive / send of specified type TSyncItemType *getReceiveType(TSyncItemType *aSyncItemTypeP); TSyncItemType *getReceiveType(const char *aType, const char *aVers); TSyncItemType *getSendType(TSyncItemType *aSyncItemTypeP); TSyncItemType *getSendType(const char *aType, const char *aVers); virtual TTypeVariantDescriptor getVariantDescForType(TSyncItemType *aItemTypeP) { return NULL; }; // - get preferred Item types TSyncItemType *getPreferredRxItemType(void) { return fRxPrefItemTypeP; }; TSyncItemType *getPreferredTxItemType(void) { return fTxPrefItemTypeP; }; // - get max GUID size sInt32 getMaxGUIDSize(void) { return fMaxGUIDSize; }; // - memory limits sInt64 getFreeMemory(void) { return fFreeMemory; }; sInt64 getMaxMemory(void) { return fMaxMemory; }; sInt64 getFreeID(void) { return fFreeID; }; sInt64 getMaxID(void) { return fMaxID; }; bool canRestart() { return fCanRestart; } virtual bool syncModeSupported(const std::string &mode) { return fSyncModes.find(mode) != fSyncModes.end(); } virtual void getSyncModes(set &modes) { modes = fSyncModes; } // - session TSyncSession *getSession(void) { return fSessionP; }; // description structure of datastore (NULL if not available) // - get description structure, but ownership remains at TSyncDataStore SmlDevInfDatastorePtr_t getDatastoreDevinf(bool aAsServer, bool aWithoutCTCapProps); // - set description structure virtual bool setDatastoreDevInf( SmlDevInfDatastorePtr_t /* aDataStoreDevInfP */, // the datastore DevInf TSyncItemTypePContainer & /* aLocalItemTypes */, // list to look up local types (for reference) TSyncItemTypePContainer & /* aNewItemTypes */ // list to add analyzed types if not already there ) { return true; /* nop for base class */ }; // helpers // - returns session zones GZones *getSessionZones(void); // - return pure relative (item) URI (removes absolute part or ./ prefix) virtual const char *DatastoreRelativeURI(const char *aURI) = 0; // - get debug mask/logger #ifdef SYDEBUG TDebugLogger *getDbgLogger(void); uInt32 getDbgMask(void); #endif // - get session owner (dispatcher/clientbase) TSyncAppBase *getSyncAppBase(void); protected: // obtain new datastore info, returns NULL if none available virtual SmlDevInfDatastorePtr_t newDevInfDatastore(bool /* aAsServer */, bool /* aWithoutCTCapProps */) { return NULL; } // no description in base class SmlDevInfXmitListPtr_t newXMitListDevInf(TSyncItemTypePContainer &aTypeList); // obtain Sync Cap mask, defaults to value passed at creation by session virtual uInt32 getSyncCapMask(void) { return fCommonSyncCapMask; }; // SyncML-exposed name (SourceRef in DevInf) of the datastore string fName; // Maximal size of GUIDs sent to that (remote) datastore, so if real local GUID // is longer, temporary GUIDs that meet MaxGUIDSize must be created by the server. sInt32 fMaxGUIDSize; // Information about datastore memory (could be enormous, so provide longlongs here) sInt64 fMaxMemory; // maximum number bytes for datastore sInt64 fFreeMemory; // number of free bytes sInt64 fMaxID; // maximum number of ID sInt64 fFreeID; // free IDs bool fCanRestart; // if set, then the datastore is able to participate in multiple sync sessions; in other words after a successful read/write cycle it is possible to restart at the reading phase set fSyncModes; // all supported sync modes that we know about (empty unless SyncCap was parsed) public: // Type of items in this datastore (read-only, can be used by multiple Datastores simultaneously) // - receiving types (also used as default item type) TSyncItemType *fRxPrefItemTypeP; TSyncItemTypePContainer fRxItemTypes; // - sending types TSyncItemType *fTxPrefItemTypeP; TSyncItemTypePContainer fTxItemTypes; protected: // session TSyncSession *fSessionP; // common (session) Sync capabilities uInt32 fCommonSyncCapMask; // type registering void registerTypes( TSyncItemTypePContainer &aSupportedXmitTypes, SmlDevInfXmitListPtr_t aXmitTypeList, TSyncItemTypePContainer &aLocalItemTypes, // list to look up local types (for reference) TSyncItemTypePContainer &aNewItemTypes, // list to add analyzed types if not already there TSyncDataStore *aRelatedDatastoreP ); }; // TSyncDataStore } // namespace sysync #endif // SyncDataStore_H // eof libsynthesis-3.4.0.47.1/src/sysync/syncitem.cpp000077500000000000000000000065501226375725500213330ustar00rootroot00000000000000/* * File: SyncItem.cpp * * Author: Lukas Zeller (luz@plan44.ch) * * TSyncItem * Abstract Base class of all data containing items. * TSyncItems always correspond to a TSyncItemType * which holds type information and conversion * features. * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * 2001-06-18 : luz : created * */ // includes #include "prefix_file.h" #include "sysync.h" #include "syncitem.h" #include "syncappbase.h" using namespace sysync; // equality mode names const char * const sysync::compareRelevanceNames[numEQmodes] = { "never", // irrelevant, only for fields with really unimportant data (such as REV) - note that this also prevents inclusion in CRC change detection "scripted", // relevant, but actual comparison is done in a script - standard compare loop must not check it (but it is automatically included in CRC change detection) "conflict", // for conflict, all fields that have user data should use at least this "slowsync", // for slow sync, all fields that must match for identifying records in slow sync "always", // always relevant, fields that must always match (first-time sync match set) "n/a" }; const char * const sysync::comparisonModeNames[numEQmodes] = { "all", // compare all fields, even irrelevant ones "n/a", // n/a (scripted) "conflict", // compare fields relevant for (normal sync) conflict detection "slowsync", // compare fields relevant for slow sync match "firstsync", // compare fields relevant for first time slow sync match (possibly relaxed comparison rules) "age", // no test for equality, only for age (returns SYSYNC_NOT_COMPARABLE if age comparison not possible) }; /* * Implementation of TSyncItem */ /* public TSyncItem members */ TSyncItem::TSyncItem(TSyncItemType *aItemType) { fSyncOp=sop_none; fSyncItemTypeP=aItemType; } // TSyncItem::TSyncItem TSyncItem::~TSyncItem() { for (SyncItemAux_t::iterator it = fSyncItemAux.begin(); it != fSyncItemAux.end(); ++it) { delete it->second; } } // TSyncItem::~TSyncItem TSyncItemAux *TSyncItem::getAux(EngineLevel level) const { SyncItemAux_t::const_iterator it = fSyncItemAux.find(level); return it == fSyncItemAux.end() ? NULL : it->second; } void TSyncItem::setAux(EngineLevel level, TSyncItemAux *aux) { fSyncItemAux[level] = aux; } // assignment (IDs and contents) TSyncItem& TSyncItem::operator=(TSyncItem &aSyncItem) { // - IDs setRemoteID(aSyncItem.getRemoteID()); setLocalID(aSyncItem.getLocalID()); // - syncop setSyncOp(aSyncItem.getSyncOp()); // - Contents replaceDataFrom(aSyncItem); // done return *this; } // TSyncItem::operator= // get session zones pointer GZones *TSyncItem::getSessionZones(void) { return getSession() ? getSession()->getSessionZones() : NULL; } // TSyncItem::getSessionZones #ifdef SYDEBUG TDebugLogger *TSyncItem::getDbgLogger(void) { // commands log to session's logger return fSyncItemTypeP ? fSyncItemTypeP->getDbgLogger() : NULL; } // TSyncItem::getDbgLogger uInt32 TSyncItem::getDbgMask(void) { if (!fSyncItemTypeP) return 0; // no session, no debug return fSyncItemTypeP->getDbgMask(); } // TSyncItem::getDbgMask #endif TSyncAppBase *TSyncItem::getSyncAppBase(void) { return getSession() ? getSession()->getSyncAppBase() : NULL; } // TSyncItem::getSyncAppBase /* end of TSyncItem implementation */ // eof libsynthesis-3.4.0.47.1/src/sysync/syncitem.h000077500000000000000000000203611226375725500207740ustar00rootroot00000000000000/* * File: SyncItem.h * * Author: Lukas Zeller (luz@plan44.ch) * * TSyncItem * Abstract Base class of all data containing items. * TSyncItems always correspond to a TSyncItemType * which holds type information and conversion * features. * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * 2001-06-18 : luz : created * */ #ifndef SyncItem_H #define SyncItem_H // includes #include "syncitemtype.h" namespace sysync { // default command size #define DEFAULTITEMSIZE 50; // equality relevance / mode typedef enum { // RELEVANCE COMPARE MODE eqm_none, // not relevant at all (*) compares ALL fields, even not-relevant ones eqm_scripted, // relevant, handled in script n/a eqm_conflict, // relevant for conflicts only compares all somehow relevant fields for conflict comparison eqm_slowsync, // relevant for slow sync compares only fields relevant for slow sync eqm_always, // always relevant (e.g firsttime) compares only always-relevant fields (first time slowsync) eqm_nocompare, // n/a prevent equality test in compareWith totally numEQmodes } TEqualityMode; // (*) Note: eqm_none fields will be silently merged in mergeWith(), that is, if no other // fields are merged, mergeWith will report "nothing merged" even if eqm_none field might // be modified // Fields with eqm_none will also not be included in CRC calculations for detecting changes. // Names for TEqualityMode when used as field relevance extern const char * const compareRelevanceNames[numEQmodes]; // Names for TEqualityMode when used as comparison mode extern const char * const comparisonModeNames[numEQmodes]; // merge options #define mem_none -1 // do not merge at all #define mem_fillempty -2 // fill empty fields of winning item with loosig item's field contents #define mem_addunassigned -3 // add fields of loosing item to winning item if it has this field not yet assigned (not just empty) #define mem_concat 0 // simply concatenate field contents // NOTE: any positive char constant means intelligent merge using given char as separator // forward class TLocalEngineDS; class TSyncAppBase; class TSyncItemAux { public: virtual ~TSyncItemAux() {} }; class TSyncItem : noncopyable { public: TSyncItem(TSyncItemType *aItemType=NULL); virtual ~TSyncItem(); // access to type virtual uInt16 getTypeID(void) const { return ity_syncitem; }; virtual bool isBasedOn(uInt16 aItemTypeID) const { return aItemTypeID==ity_syncitem; }; // get session pointer TSyncSession *getSession(void) { return fSyncItemTypeP ? fSyncItemTypeP->getSession() : NULL; }; // get session zones pointer GZones *getSessionZones(void); // assignment (IDs and contents) virtual TSyncItem& operator=(TSyncItem &aSyncItem); // access to IDs // - remote ID const char *getRemoteID(void) { return fRemoteID.c_str(); }; void setRemoteID(const char *aRemoteID) { fRemoteID = aRemoteID; }; bool hasRemoteID(void) { return !fRemoteID.empty(); }; void clearRemoteID(void) { fRemoteID.erase(); }; // - local ID const char *getLocalID(void) { return fLocalID.c_str(); }; void setLocalID(const char *aLocalID) { fLocalID = aLocalID; }; bool hasLocalID(void) { return !fLocalID.empty(); }; void clearLocalID(void) { fLocalID.erase(); }; virtual void updateLocalIDDependencies(void) { /* nop here */ } // - changelog support #ifdef CHECKSUM_CHANGELOG virtual uInt16 getDataCRC(uInt16 crc=0, bool /* aEQRelevantOnly */=false) { return crc; /* always empty */ }; #endif // access to operation TSyncOperation getSyncOp(void) { return fSyncOp; }; void setSyncOp(TSyncOperation aSyncOp) { fSyncOp=aSyncOp; }; // access to visibility // object filtering #ifdef OBJECT_FILTERING // New style generic filtering // - check if item passes filter and probably apply some modifications to it virtual bool postFetchFiltering(TLocalEngineDS *aDatastoreP) { return true; } // without filters, just pass everything // Old style filter expressions // - test if item passes filter virtual bool testFilter(const char *aFilterString) { return (!aFilterString || *aFilterString==0); }; // without real test, only empty filterstring pass // - make item pass filter virtual bool makePassFilter(const char *aFilterString) { return (!aFilterString || *aFilterString==0); }; // without real implementation, works only with no filter string #endif // compare abilities // - test if comparable at all (correct types) virtual bool comparable(TSyncItem & /* aItem */) { return false; }; // - test if comparison can find out newer (greater) item // NOTE: this should reflect the actually possible sorting state // related to current contents of the item (for example, a vCard // that COULD be sorted if it HAD a REV date may not return true // if the actual item does not have a REV property included. virtual bool sortable(TSyncItem & /* aItem */) { return false; }; // clear item data (means not only empty values, but NO VALUES assigned) virtual void cleardata(void) {}; // replace data contents from specified item (returns false if not possible) // - aAvailable only: only replace contents actually available in aItem, leave rest untouched // - aDetectCutOffs: handle case where aItem could have somhow cut-off data and prevent replacing // complete data with cut-off version (e.g. mobiles like T39m with limited name string capacity) virtual bool replaceDataFrom(TSyncItem & /* aItem */, bool /* aAvailableOnly */=false, bool /* aDetectCutoffs */=false, bool /* aAssignedOnly */=false, bool /* aTransferUnassigned */=false) { return true; }; // no data -> nop // check item before processing it virtual bool checkItem(TLocalEngineDS * /* aDatastoreP */) { return true; }; // default is: ok enum { MERGE_OPTION_FROM_CONFIG, /**< merge as defined in the field list */ MERGE_OPTION_CHANGE_OTHER, /**< ensure that the other item is the same as this item */ MERGE_OPTION_CHANGE_THIS /**< ensure that this items is the same as the other */ }; // merge this item with specified item. // Notes: // - specified item is treated as loosing item, this item is winning item // - also updates other item to make sure it is equal to the winning after the merge // sets (but does not reset) change status of this and other item. // Note that changes of non-relevant fields are not reported here. virtual void mergeWith(TSyncItem & /* aItem */, bool &aChangedThis, bool &aChangedOther, TLocalEngineDS * /* aDatastoreP */, int mode = MERGE_OPTION_FROM_CONFIG) { aChangedThis=false; aChangedOther=false; }; // nop by default // remote and local ID string fRemoteID; // ID in remote party (if this is a server: LUID, GUID otherwise) string fLocalID; // ID in this party (if this is a server: GUID, LUID otherwise) // compare: returns 0 if equal, 1 if this > aItem, -1 if this < aItem // SYSYNC_NOT_COMPARABLE if not equal and no ordering known virtual sInt16 compareWith( TSyncItem & /* aItem */, TEqualityMode /* aEqMode */, TLocalEngineDS * /* aDatastoreP */ #ifdef SYDEBUG ,bool /* aDebugShow */=false #endif ) { return SYSYNC_NOT_COMPARABLE; }; #ifdef SYDEBUG // show item contents for debug virtual void debugShowItem(uInt32 aDbgMask=DBG_DATA) { /* nop */ }; // get debug channel TDebugLogger *getDbgLogger(void); uInt32 getDbgMask(void); #endif // - get session owner (dispatcher/clientbase) TSyncAppBase *getSyncAppBase(void); // Opaque auxiliary data, for use in the different levels that the item passes through. enum EngineLevel { LOCAL_ENGINE, STD_LOGIC_DS, CUSTOM_DS, PLUGIN_API }; TSyncItemAux *getAux(EngineLevel level) const; void setAux(EngineLevel level, TSyncItemAux *aux); protected: // operation to be performed with this item at its destination TSyncOperation fSyncOp; TSyncItemType *fSyncItemTypeP; private: // cast pointer to same type, returns NULL if incompatible TSyncItem *castToSameTypeP(TSyncItem *aItemP) { return aItemP; } // all are compatible TSyncItem typedef std::map SyncItemAux_t; SyncItemAux_t fSyncItemAux; }; // TSyncItem } // namespace sysync #endif // SyncItem_H // eof libsynthesis-3.4.0.47.1/src/sysync/syncitemtype.cpp000077500000000000000000001020471226375725500222330ustar00rootroot00000000000000/* * File: SyncItemType.cpp * * Author: Lukas Zeller (luz@plan44.ch) * * TSyncItemType * Type description and converter (template) for TSyncItem. * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * 2001-05-16 : luz : created * */ // includes #include "prefix_file.h" #include "sysync.h" #include "syncitemtype.h" #include "syncitem.h" #include "synccommand.h" #include "syncsession.h" #ifdef ZIPPED_BINDATA_SUPPORT #include "zlib.h" #endif using namespace sysync; /* * Implementation of TSyncItemType */ /* TSyncItemType members */ void TSyncItemType::init( TSyncSession *aSessionP, TDataTypeConfig *aTypeConfigP, const char *aCTType, const char *aVerCT, TSyncDataStore *aRelatedDatastoreP ) { // link to config fTypeConfigP=aTypeConfigP; // link to session fSessionP=aSessionP; // set type name and vers (if any) fTypeName=aCTType; if (aVerCT) fTypeVers=aVerCT; // set relation to a specific datastore (if any) fRelatedDatastoreP=aRelatedDatastoreP; // assume local fIsRemoteType = false; #if defined(ZIPPED_BINDATA_SUPPORT) && defined(SYDEBUG) // data compression accounting fRawDataBytes=0; fZippedDataBytes=0; #endif } // TSyncItemType::init TSyncItemType::TSyncItemType( TSyncSession *aSessionP, TDataTypeConfig *aTypeConfigP, const char *aCTType, const char *aVerCT, TSyncDataStore *aRelatedDatastoreP ) { // only basic init init(aSessionP,aTypeConfigP,aCTType,aVerCT,aRelatedDatastoreP); } // TSyncItemType::TSyncItemType TSyncItemType::~TSyncItemType() { #if defined(ZIPPED_BINDATA_SUPPORT) && defined(SYDEBUG) // show compression statistics, if any if (fSessionP && fRawDataBytes && fZippedDataBytes) { POBJDEBUGPRINTFX(fSessionP,DBG_HOT,( "##### Type '%s', zippedbindata send statistics: raw=%ld, compressed=%ld, compressed down to %ld%%", getTypeName(), (long)fRawDataBytes, (long)fZippedDataBytes, (long)(fZippedDataBytes*100/fRawDataBytes) )); } #endif } // TSyncItemType::~TSyncItemType // get session zones pointer GZones *TSyncItemType::getSessionZones(void) { return getSession() ? getSession()->getSessionZones() : NULL; } // TSyncItemType::getSessionZones #ifdef SYDEBUG TDebugLogger *TSyncItemType::getDbgLogger(void) { // commands log to session's logger return fSessionP ? getSession()->getDbgLogger() : NULL; } // TSyncItemType::getDbgLogger uInt32 TSyncItemType::getDbgMask(void) { if (!fSessionP) return 0; // no session, no debug return fSessionP->getDbgMask(); } // TSyncItemType::getDbgMask #endif // helper to create same-typed instance via base class TSyncItemType *TSyncItemType::newCopyForSameType( TSyncSession *aSessionP, // the session TSyncDataStore *aDatastoreP // the datastore ) { // create new itemtype of appropriate derived class type that can handle // this type MP_RETURN_NEW(TSyncItemType,DBG_OBJINST,"TSyncItemType",TSyncItemType(aSessionP,fTypeConfigP,getTypeName(),getTypeVers(),aDatastoreP)); } // TSyncItemType::newCopyForSameType // check if type is supported // - if version specified is NULL, first name-matching flavour is returned // - if type has no version, it matches any versions given // - if aVersMustMatch is set, version must match (both w/o version is a match, too) bool TSyncItemType::supportsType(const char *aName, const char *aVers, bool aVersMustMatch) { if (!aName) return false; // no support for unnamed if (!aVers) aVers=""; // empty version return ( strucmp(fTypeName.c_str(),aName)==0 && ( ((*aVers==0 || fTypeVers.empty()) && !aVersMustMatch) || strucmp(fTypeVers.c_str(),aVers)==0 ) ); } // TSyncItemType::supportsType bool TSyncItemType::supportsType(SmlDevInfXmitPtr_t aXmitType, bool aVersMustMatch) { if (!aXmitType) return false; // null type not found return ( supportsType( smlPCDataToCharP(aXmitType->cttype), smlPCDataToCharP(aXmitType->verct), aVersMustMatch ) ); } // TSyncItemType::supportsType /// @brief get CTCap entry /// @param aOnlyForDS[in] /// - if NULL, CTCap is generated suitable for all datastores /// - if not NULL, CTCap is generated specifically for the datastore passed const SmlDevInfCTCapPtr_t TSyncItemType::getCTCapDevInf(TLocalEngineDS *aOnlyForDS, TTypeVariantDescriptor aVariantDescriptor, bool aWithoutCTCapProps) { SmlDevInfCTCapPtr_t ctcap=NULL; // get item type and property description (part of ), if any // - first see if we have (and are allowed to show) property descriptions at all SmlDevInfCTDataPropListPtr_t proplistP = NULL; if (fSessionP->fShowCTCapProps && !aWithoutCTCapProps) proplistP = newCTDataPropList(aVariantDescriptor); // - and if we should report field level replace capability to remote bool acceptsFieldLevel = getSession()->getSyncMLVersion()>=syncml_vers_1_2 && canAcceptFieldLevelUpdates(); if (proplistP || acceptsFieldLevel) { // there are properties available for this item, create DevInfCTCap ctcap = SML_NEW(SmlDevInfCTCap_t); // - add type name ctcap->cttype=newPCDataString(getTypeName()); // - for DS 1.2, add the VerCT if (getSession()->getSyncMLVersion()>=syncml_vers_1_2) ctcap->verct=newPCDataString(getTypeVers()); else ctcap->verct=NULL; // - init the flags ctcap->flags= acceptsFieldLevel ? SmlDevInfFieldLevel_f : 0; // - add property list ctcap->prop=proplistP; } return ctcap; } // TSyncItemType::getCTCapDevInf // intended for creating SyncItemTypes for remote databases from // transmitted DevInf. bool TSyncItemType::analyzeCTCap(SmlDevInfCTCapPtr_t aCTCapP) { // Note: derived classes will possibly get some type-related info out of the CTCaps return true; } // TSyncItemType::analyzeCTCap /// @brief copy CTCap derived info from another SyncItemType /// @return false if item not compatible /// @note required to create remote type variants from ruleMatch type alternatives bool TSyncItemType::copyCTCapInfoFrom(TSyncItemType &aSourceItem) { // no generic CTCap info to copy return true; } // TSyncItemType::copyCTCapInfoFrom // - static function to search type in a TSyncItemTypePContainer TSyncItemType *TSyncItemType::findTypeInList( TSyncItemTypePContainer &aList, const char *aName, const char *aVers, bool aVersMustMatch, bool aMustBeImplemented, TSyncDataStore *aRelatedDatastoreP // if not NULL, type must be specific to this datastore (or unspecific) ) { TSyncItemTypePContainer::iterator pos; // first priority: return type which is specific to aRelatedDatastoreP for (pos=aList.begin(); pos!=aList.end(); ++pos) { if ((*pos)->supportsType(aName,aVers,aVersMustMatch)) { // found, return if implementation is ok and related to the correct datastore (or no relation requested) if ( ( !aMustBeImplemented || (*pos)->isImplemented() ) && ( (aRelatedDatastoreP==NULL) || ((*pos)->getRelatedDatastore()==aRelatedDatastoreP) ) ) return (*pos); // return it } } if (aRelatedDatastoreP) { // second priority: return type which is expressedly not specific to a datastore for (pos=aList.begin(); pos!=aList.end(); ++pos) { if ((*pos)->supportsType(aName,aVers,aVersMustMatch)) { // found, return if implementation is ok and related to the correct datastore if ( (!aMustBeImplemented || (*pos)->isImplemented()) && ((*pos)->getRelatedDatastore()==NULL) ) return (*pos); // return it } } } return NULL; // not found } // static TSyncItemType::findTypeInList // - static function to search type in a TSyncItemTypePContainer TSyncItemType *TSyncItemType::findTypeInList( TSyncItemTypePContainer &aList, SmlDevInfXmitPtr_t aXmitType, // name and version of type bool aVersMustMatch, bool aMustBeImplemented, TSyncDataStore *aRelatedDatastoreP // if not NULL, type must be specific to THIS datastore (or unspecific) ) { return ( findTypeInList( aList, smlPCDataToCharP(aXmitType->cttype), smlPCDataToCharP(aXmitType->verct), aVersMustMatch, aMustBeImplemented, aRelatedDatastoreP ) ); } // static TSyncItemType::findTypeInList // - static function to add new or copied ItemType to passed list TSyncItemType *TSyncItemType::registerRemoteType( TSyncSession *aSessionP, SmlDevInfXmitPtr_t aXmitTypeP, // name and version of type TSyncItemTypePContainer &aLocalItemTypes, // list to look up local types (for reference) TSyncItemTypePContainer &aNewItemTypes, // list to add analyzed types if not already there TSyncDataStore *aRelatedDatastoreP ) { return ( registerRemoteType( aSessionP, smlPCDataToCharP(aXmitTypeP->cttype), smlPCDataToCharP(aXmitTypeP->verct), aLocalItemTypes, aNewItemTypes, aRelatedDatastoreP ) ); } // static TSyncItemType::registerRemoteType // - static function to add new or copied ItemType to passed list // If type is already in aNewItemTypes, nothing will be added TSyncItemType *TSyncItemType::registerRemoteType( TSyncSession *aSessionP, const char *aName, const char *aVers, // name and version of type TSyncItemTypePContainer &aLocalItemTypes, // list to look up local types (for reference) - aRelatedDatastoreP does NOT relate to the types here, as these are local ones TSyncItemTypePContainer &aNewItemTypes, // list to add analyzed types if not already there TSyncDataStore *aRelatedDatastoreP // if NULL, type is not related to a specific (remote!) datastore ) { if (!aName) SYSYNC_THROW(TSyncException("cannot register type w/o name")); #ifdef SYDEBUG if (aSessionP) { // Show warning if no version if (!aVers || *aVers==0) { POBJDEBUGPRINTFX(aSessionP,DBG_REMOTEINFO,("WARNING: Registering type with no version specification!")); } } #endif // - check if type is already in the list (version must match, but implementation not required TSyncItemType *newitemtypeP = findTypeInList(aNewItemTypes,aName,aVers,true,false,aRelatedDatastoreP); if (newitemtypeP) { POBJDEBUGPRINTFX(aSessionP,DBG_REMOTEINFO+DBG_EXOTIC,( "Type already registered as '%s' Version='%s'", newitemtypeP->getTypeName(), newitemtypeP->hasTypeVers() ? newitemtypeP->getTypeVers() : "[none]" )); } else { // - check if one of the local item types supports this type // Note: SySync engine only has one global list of supported types. It might contain multiple entries for // the same type, when related to different datastores. The following search will find the first with // matching name - this is no problem as long as all types with same name have the same CLASS type // (as the only reason to look up in local types is to create the correct class' instance). When // actually USED later by datastores, each datastore finds it's own INSTANCES via it's tx/rx(pref). // No need for version match, but for implementation TSyncItemType *localitemtypeP = findTypeInList(aLocalItemTypes,aName,aVers,false,true,NULL); // local types are not specific to a datastore if (localitemtypeP) { // %%% test for conforming version if type being registered has no version spec // local itemtype exists that can support this type/vers // - create new item type of same class (type-specialized derivate of TSyncItemType) // - but relate it to the remote datastore (for DS1.2, or none for DS1.1 and earlier) newitemtypeP = localitemtypeP->newCopyForSameType(aSessionP,aRelatedDatastoreP); } else { // no local support of this type // - create base class item just describing the type found // (but without handling abilities) newitemtypeP = new TSyncItemType(aSessionP,NULL,aName,aVers,aRelatedDatastoreP); } // this is a remote type! newitemtypeP->defineAsRemoteType(); // add item to list aNewItemTypes.push_back(newitemtypeP); POBJDEBUGPRINTFX(aSessionP,DBG_REMOTEINFO+DBG_HOT,( "Registered Type '%s' Version='%s', %s%s, related to remote datastore '%s'", newitemtypeP->getTypeName(), newitemtypeP->hasTypeVers() ? newitemtypeP->getTypeVers() : "[none]", newitemtypeP->isImplemented() ? "implemented by local type " : "NOT implemented", newitemtypeP->isImplemented() ? newitemtypeP->getTypeConfig()->getName() : "", aRelatedDatastoreP ? aRelatedDatastoreP->getName() : "" )); // Only show this if we REALLY have a local type-to-DS relation (NEVER so far - that is in 3.1.2.1) if (newitemtypeP->isImplemented() && localitemtypeP && localitemtypeP->getRelatedDatastore()) { POBJDEBUGPRINTFX(aSessionP,DBG_REMOTEINFO,( "- Implementation is exclusively related to local datastore '%s'", localitemtypeP->getRelatedDatastore()->getName() )); } } // if not already in list return newitemtypeP; } // static TSyncItemType::registerRemoteType /// @brief static function to analyze CTCap and add entries to passed list /// @todo %%% to be moved to TMimeDirItemType (as basic TSyncItemType does not really know the VERSION property) bool TSyncItemType::analyzeCTCapAndCreateItemTypes( TSyncSession *aSessionP, TRemoteDataStore *aRemoteDataStoreP, ///< if not NULL, this is the datastore to which this type is local (DS 1.2 case) SmlDevInfCTCapPtr_t aCTCapP, TSyncItemTypePContainer &aLocalItemTypes, ///< list to look up local types (for reference) TSyncItemTypePContainer &aNewItemTypes ///< list to add analyzed types if not already there ) { bool versfound = false; // create one TSyncItemType for each type contained in this CTCap if (aCTCapP) { // type name const char *name = smlPCDataToCharP(aCTCapP->cttype); // - from DS 1.2 on, we should have the verct without digging into properties const char *vers = smlPCDataToCharP(aCTCapP->verct); if (vers && *vers) { // we have a non-empty version from verct (new DS 1.2 devinf) #ifdef SYDEBUG if (aSessionP) { PLOGDEBUGBLOCKFMTCOLL(aSessionP->getDbgLogger(),("RemoteCTCap", "Registering remote Type/Version from >=DS 1.2 style CTCap", "type=%s|version=%s", name, vers)); } #endif // valenum shows version supported TSyncItemType *newitemtypeP = registerRemoteType( aSessionP, name,vers, // name and version of type aLocalItemTypes, // list to look up local types (for reference) aNewItemTypes, // list to add it to aRemoteDataStoreP ); // now let new item process the CTCap if (newitemtypeP) newitemtypeP->analyzeCTCap(aCTCapP); #ifdef SYDEBUG if (aSessionP) { PLOGDEBUGENDBLOCK(aSessionP->getDbgLogger(),"RemoteCTCap"); } #endif versfound=true; } else { // - pre-DS 1.2 hack: try to find VERSION property SmlDevInfCTDataPropListPtr_t prlP = aCTCapP->prop; while (prlP) { // get property name const char *n = smlPCDataToCharP(prlP->data->prop->name); if (n && strcmp(n,"VERSION")==0) { // version property found. Now create flavour for each ValEnum SmlPcdataListPtr_t velP = prlP->data->prop->valenum; while (velP) { vers = smlPCDataToCharP(velP->data); if (vers) { versfound=true; // found at least one #ifdef SYDEBUG if (aSessionP) { PLOGDEBUGBLOCKFMTCOLL(aSessionP->getDbgLogger(),("RemoteCTCap", "Registering remote Type/Version from old style CTCap w/o verct", "type=%s|version=%s", name, vers)); } #endif // valenum shows version supported TSyncItemType *newitemtypeP = registerRemoteType( aSessionP, name,vers, // name and version of type aLocalItemTypes, // list to look up local types (for reference) aNewItemTypes, // list to add it to aRemoteDataStoreP ); // now let new item process the CTCap if (newitemtypeP) newitemtypeP->analyzeCTCap(aCTCapP); #ifdef SYDEBUG if (aSessionP) { PLOGDEBUGENDBLOCK(aSessionP->getDbgLogger(),"RemoteCTCap"); } #endif } // if version is not null // next velP=velP->next; } // while valenums break; // VERSION found, done with properties for now } // while properties prlP=prlP->next; } // while } if (!versfound) { // version is NULL, for a start, create type w/o version #ifdef SYDEBUG if (aSessionP) { PLOGDEBUGBLOCKFMT(aSessionP->getDbgLogger(),("RemoteCTCap", "Registering remote Type w/o version from CTCap", "type=%s|version=[none]", name)); } #endif TSyncItemType *newitemtypeP = registerRemoteType( aSessionP, name,NULL, // name, but no version aLocalItemTypes, // list to look up local types (for reference) aNewItemTypes, // list to add it to aRemoteDataStoreP ); // now let new item process the CTCap if (newitemtypeP) newitemtypeP->analyzeCTCap(aCTCapP); #ifdef SYDEBUG if (aSessionP) { PLOGDEBUGENDBLOCK(aSessionP->getDbgLogger(),"RemoteCTCap"); } #endif // this is ok, too return true; } // without version } return versfound; } // static TSyncItemType::analyzeCTCapAndCreateItemTypes // get type as transmit format SmlDevInfXmitPtr_t TSyncItemType::newXMitDevInf(void) { SmlDevInfXmitPtr_t xmitP; xmitP = SML_NEW(SmlDevInfXmit_t); xmitP->cttype=newPCDataString(getTypeName()); xmitP->verct=newPCDataString(getTypeVers()); return xmitP; } // TSyncItemType::newXMitDevInf // static helper: get type list as transmit format SmlDevInfXmitListPtr_t TSyncItemType::newXMitListDevInf( TSyncItemTypePContainer &aTypeList, TSyncItemType *aDontIncludeP ) { SmlDevInfXmitListPtr_t resultP = NULL; SmlDevInfXmitListPtr_t *listPP = &resultP; TSyncItemTypePContainer::iterator pos; for (pos=aTypeList.begin(); pos!=aTypeList.end(); ++pos) { if (aDontIncludeP!=(*pos)) { // only if item in list does not match "except" item // new list item (*listPP) = SML_NEW(SmlDevInfXmitList_t); (*listPP)->next=NULL; // add type (*listPP)->data=(*pos)->newXMitDevInf(); // next listPP=&((*listPP)->next); } } return resultP; } // TSyncItemType::newXMitListDevInf // create new empty sync item TSyncItem *TSyncItemType::newSyncItem( TSyncItemType *aTargetItemTypeP, // the targeted type (for optimizing field lists etc.) TLocalEngineDS *aLocalDataStoreP // the datastore ) { if (!aLocalDataStoreP) { PDEBUGPRINTFX(DBG_ERROR,("Trying to call newSyncItem w/o datastore")); return NULL; } // test if implemented at all if (!isImplemented()) { PDEBUGPRINTFX(DBG_ERROR,( "Tried to create SyncItem for unimplemented SyncItemType '%s' (%s)", fTypeName.c_str(), fTypeVers.c_str() )); return NULL; } // check for compatibility with targeted type if (!isCompatibleWith(aTargetItemTypeP)) { PDEBUGPRINTFX(DBG_ERROR,( "Local type (%s) is not assignment compatible with remote target type (%s) - probably multiple types with same name/version but different fieldlists in config", getTypeConfig()->getName(),aTargetItemTypeP-> getTypeConfig()->getName() )); return NULL; } // get appropriate item TSyncItem *syncitemP = internalNewSyncItem(aTargetItemTypeP,aLocalDataStoreP); // return new item (if any) return syncitemP; } // TSyncItemType::newSyncItem // create new sync item from SyncML data TSyncItem *TSyncItemType::newSyncItem( SmlItemPtr_t aItemP, // SyncML toolkit item Data to be converted into SyncItem TSyncOperation aSyncOp, // the operation to be performed with this item TFmtTypes aFormat, // the format (normally fmt_chr) TSyncItemType *aTargetItemTypeP, // the targeted type (for optimizing field lists etc.) TLocalEngineDS *aLocalDataStoreP, // local datastore TStatusCommand &aStatusCmd // status command that might be modified in case of error ) { TSyncItem *syncitemP = NULL; // test if implemented at all if (!isImplemented()) { DEBUGPRINTFX(DBG_ERROR,( "Tried to create SyncItem for unimplemented SyncItemType '%s' (%s)", fTypeName.c_str(), fTypeVers.c_str() )); aStatusCmd.setStatusCode(415); ADDDEBUGITEM(aStatusCmd,"Known, but unimplemented Item Type"); return NULL; } PDEBUGBLOCKFMT(("Item_Parse","parsing SyncML item", "SyncOp=%s|format=%s|LocalID=%s|RemoteID=%s", SyncOpNames[aSyncOp], encodingFmtNames[aFormat], smlSrcTargLocURIToCharP(aItemP->target), smlSrcTargLocURIToCharP(aItemP->source) )); SYSYNC_TRY { // get appropriate item type syncitemP = internalNewSyncItem(aTargetItemTypeP,aLocalDataStoreP); // get local and remote IDs if (syncitemP) { // set operation type syncitemP->setSyncOp(aSyncOp); // an appropriate syncitem was created, set target and source now // - we have received this item from remote, so target=myself, source=remote party syncitemP->setLocalID(relativeURI(smlSrcTargLocURIToCharP(aItemP->target))); #ifdef DONT_STRIP_PATHPREFIX_FROM_REMOTEIDS syncitemP->setRemoteID(smlSrcTargLocURIToCharP(aItemP->source)); #else syncitemP->setRemoteID(relativeURI(smlSrcTargLocURIToCharP(aItemP->source))); #endif PDEBUGPRINTFX(DBG_DATA+DBG_DETAILS,( "Created new item of datatype '%s', localID='%s' remoteID='%s'", getTypeConfig()->getName(), syncitemP->getLocalID(), syncitemP->getRemoteID() )); if (aSyncOp!=sop_delete && aSyncOp!=sop_archive_delete && aSyncOp!=sop_soft_delete && aSyncOp!=sop_copy && aSyncOp!=sop_move) { // Item has data, parse it // - uncompress data first if zippedbindata selected in type #ifdef ZIPPED_BINDATA_SUPPORT if (fTypeConfigP->fZippedBindata && fSessionP->getEncoding()==SML_WBXML && fSessionP->getSyncMLVersion()>=syncml_vers_1_1) { // this type uses zipped bindata and we have WBXML (we cannot use zipped bindata in XML) // - get input data MemPtr_t zipBinPayload = NULL; MemSize_t zipBinSize = 0; MemPtr_t expandedPayload = NULL; sInt32 expandedSize = 0; if (aItemP->data) { if ((zipBinSize=aItemP->data->length)>0) { zipBinPayload = (MemPtr_t) aItemP->data->content; } } // uncompress it, if we have data at all if (zipBinPayload) { // - contains expanded size of payload for pre-allocating the buffer SmlMetInfMetInfPtr_t metaP = smlPCDataToMetInfP(aItemP->meta); if (metaP && metaP->maxobjsize) { smlPCDataToLong(metaP->maxobjsize, expandedSize); } if (expandedSize>0) { // we have data to expand AND we know how big the output will be (if we did not get MaxObjSize, this // means that the data is not compressed expandedPayload = (MemPtr_t) smlLibMalloc(expandedSize+1); // we need one more for the terminator // uncompress the payload with gzip z_stream zipstream; // - no special alloc zipstream.zalloc=NULL; zipstream.zfree=NULL; zipstream.opaque=NULL; // - no input yet zipstream.next_in=NULL; zipstream.avail_in=0; // - init deflate inflateInit2(&zipstream,15+32); // 15=default window size, +16=sets gzip detect flag (+32: sets gzip+zlib detect flag) // - actually inflate item's ... zipstream.next_in=zipBinPayload; zipstream.avail_in=zipBinSize; // - ...into new buffer zipstream.next_out=expandedPayload; zipstream.avail_out=expandedSize; int err = inflate(&zipstream,Z_SYNC_FLUSH); // - replace compressed by expanded data if everything's fine if (err==Z_OK && zipstream.avail_in==0) { // make sure data is null terminated expandedPayload[expandedSize]=0; // set expanded data in place of compressed aItemP->data->length=expandedSize; aItemP->data->content=expandedPayload; // forget compressed data smlLibFree(zipBinPayload); } else { // if failed, get rid of unneeded buffer smlLibFree(expandedPayload); } // clean up zip decompressor inflateEnd(&zipstream); } // if expected data size is known (from maxobjsize), i.e. was sent compressed } // if input data available at all } // if zippedBinData enabled #endif // convert payload (as a whole) from known format encodings if (aFormat==fmt_b64) { MemSize_t origSize = aItemP->data->length; cAppCharP origData = (cAppCharP)aItemP->data->content; if (origSize) { // something to decode, do it and replace original content aItemP->data->content = b64::decode(origData, origSize, (uInt32 *)&(aItemP->data->length)); // we don't need the original data any more b64::free((void *)origData); } } // convert payload (as a whole) from UTF16 (Unicode) to UTF-8 if (fTypeConfigP->fUseUTF16) { // get original size MemSize_t origSize = aItemP->data->length; cAppCharP origData = (cAppCharP)aItemP->data->content; if (origSize) { // we usually don't need more memory than the original string utf8Payload; // now convert appendUTF16AsUTF8( (const uInt16 *)origData, origSize/2, fTypeConfigP->fMSBFirst, utf8Payload, false, false ); // replace contents if (MemSize_t(utf8Payload.size())data->content,utf8Payload.c_str(),origSize+1); // include terminator byte in copy aItemP->data->length=origSize; } } // fill in data, if any (virtual method implemented in descendant) if (!internalFillInData(syncitemP,aItemP,aLocalDataStoreP,aStatusCmd)) { // delete item, as it could not be filled properly delete syncitemP; PDEBUGPRINTFX(DBG_ERROR,("Could not fill item -> immediately deleted, none returned")); syncitemP=NULL; // none any more } } } PDEBUGENDBLOCK("Item_Parse"); } SYSYNC_CATCH (...) PDEBUGENDBLOCK("Item_Parse"); SYSYNC_RETHROW; SYSYNC_ENDCATCH // return new item (if any) return syncitemP; } // TSyncItemType::newSyncItem // - create new SyncML toolkit item from SyncItem SmlItemPtr_t TSyncItemType::newSmlItem( TSyncItem *aSyncItemP, // the syncitem to be represented as SyncML TLocalEngineDS *aLocalDatastoreP // local datastore ) { SmlItemPtr_t smlitemP = NULL; PDEBUGBLOCKFMT(("Item_Generate","generating SyncML item", "SyncOp=%s|LocalID=%s|RemoteID=%s", SyncOpNames[aSyncItemP->getSyncOp()], aSyncItemP->getLocalID(), aSyncItemP->getRemoteID() )); SYSYNC_TRY { // allocate an empty smlItem smlitemP = newItem(); // data only if not delete, copy or map TSyncOperation syncop = aSyncItemP->getSyncOp(); if (syncop!=sop_delete && syncop!=sop_archive_delete && syncop!=sop_soft_delete && syncop!=sop_copy) { // let virtual method implemented in descendant fill in data and, possibly, meta. if (!internalSetItemData(aSyncItemP,smlitemP,aLocalDatastoreP)) { SYSYNC_THROW(TSyncException("newSmlItem: internalSetItemData() failed")); } // convert payload (as a whole) to UTF16 (Unicode) if (fTypeConfigP->fUseUTF16) { string utf16bytestream; appendUTF8ToUTF16ByteString( (cAppCharP)smlitemP->data->content, utf16bytestream, fTypeConfigP->fMSBFirst, lem_none, 0 ); // dispose old data smlLibFree((appPointer)smlitemP->data->content); // create new data block smlitemP->data->content= (void*)( (const char *)smlLibMalloc(utf16bytestream.size()+2) ); smlitemP->data->length = utf16bytestream.size(); // copy contents memcpy((appPointer)smlitemP->data->content,utf16bytestream.c_str(),utf16bytestream.size()); } // compress data if zippedbindata selected in type #ifdef ZIPPED_BINDATA_SUPPORT if (fTypeConfigP->fZippedBindata && fSessionP->getEncoding()==SML_WBXML && fSessionP->getSyncMLVersion()>=syncml_vers_1_1) { // this type uses zipped bindata and we have WBXML (we cannot use zipped bindata in XML) // compress the payload with gzip if there IS any data MemSize_t expandedSize = 0; MemPtr_t expandedPayload = NULL; MemPtr_t zipBinPayload = NULL; // - get expanded data if (smlitemP->data) { if ((expandedSize=smlitemP->data->length)>0) { expandedPayload = (MemPtr_t) smlitemP->data->content; } } if (expandedPayload) { // there is data to send - zip it and send it as binary // - assume output will not be bigger than input zipBinPayload = (MemPtr_t) smlLibMalloc(expandedSize); if (zipBinPayload) { // compress the payload with gzip z_stream zipstream; // - no special alloc zipstream.zalloc=NULL; zipstream.zfree=NULL; zipstream.opaque=NULL; // - no input yet zipstream.next_in=NULL; zipstream.avail_in=0; // - init deflate int comprLevel = fTypeConfigP->fZipCompressionLevel; if (comprLevel>9 || comprLevel<0) comprLevel=Z_DEFAULT_COMPRESSION; deflateInit(&zipstream,comprLevel); // - actually deflate item's ... zipstream.next_in=expandedPayload; zipstream.avail_in=expandedSize; // not more than uncompressed version would take // - ...into new buffer zipstream.next_out=zipBinPayload; zipstream.avail_out=expandedSize; int err = deflate(&zipstream,Z_SYNC_FLUSH); // - replace compressed by expanded data if everything's fine if (err==Z_OK && zipstream.avail_in==0) { // compression ok, set compressed data in place of original smlitemP->data->length=zipstream.total_out; smlitemP->data->content=zipBinPayload; // forget original data smlLibFree(expandedPayload); // only if we have succeeded, we will set the maxobjsize and format Otherwise, we'll send uncompressed data SmlMetInfMetInfPtr_t metaP = smlPCDataToMetInfP(smlitemP->meta); if (!metaP) { // we have no meta yet at all, create it first smlitemP->meta = newMeta(); metaP = (SmlMetInfMetInfPtr_t)(smlitemP->meta->content); } // - store expanded size in meta maxobjsize if (metaP->maxobjsize) smlFreePcdata(metaP->maxobjsize); // delete if there is already something here metaP->maxobjsize=newPCDataLong(expandedSize); // - set format to "bin" as a flag that contents are compressed if (metaP->format) smlFreePcdata(metaP->format); // delete if there is already something here metaP->format=newPCDataString("bin"); } else { // if failed, get rid of unneeded buffer smlLibFree(zipBinPayload); } // update statistics #ifdef SYDEBUG POBJDEBUGPRINTFX(fSessionP,DBG_DATA,( "zippedbindata item statistics: raw=%ld, compressed=%ld, compressed down to %ld%%", expandedSize, smlitemP->data->length, smlitemP->data->length*100/expandedSize )); fRawDataBytes+=expandedSize; fZippedDataBytes+=smlitemP->data->length; #endif // clean up zip compressor deflateEnd(&zipstream); } // can allocate } // if any payload at all } #endif } // set source and target (AFTER setting data, as item data might influence item ID // in some special cases (as for Nokia 9500-style email) // - we will send this item to remote, so target=remote party, source=myself smlitemP->target=newOptLocation(aSyncItemP->getRemoteID()); smlitemP->source=newOptLocation(aSyncItemP->getLocalID()); PDEBUGENDBLOCK("Item_Generate"); } SYSYNC_CATCH (...) PDEBUGENDBLOCK("Item_Generate"); SYSYNC_RETHROW; SYSYNC_ENDCATCH // return smlItem return smlitemP; } // TSyncItemType::newSmlItem /* end of TSyncItemType implementation */ // eof libsynthesis-3.4.0.47.1/src/sysync/syncitemtype.h000077500000000000000000000267551226375725500217130ustar00rootroot00000000000000/* * File: SyncItemType.h * * Author: Lukas Zeller (luz@plan44.ch) * * TSyncItemType * Type description and converter (template) for TSyncItem. * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * 2001-05-16 : luz : created * */ #ifndef SyncItemType_H #define SyncItemType_H #include "sysync_globs.h" namespace sysync { // for hardcoded config, we do not use any C++ strings #ifndef CONFIGURABLE_TYPE_SUPPORT // string pointers only #define TCFG_STRING const char * #define TCFG_CSTR(s) s #define TCFG_ASSIGN(s,c) { if (c) s=c; else s=""; } #define TCFG_CLEAR(s) s="" #define TCFG_ISEMPTY(s) (!s || *s==0) #define TCFG_SIZE(s) (s ? strlen(s) : 0) #else // C++ strings #define TCFG_STRING string #define TCFG_CSTR(s) s.c_str() #define TCFG_ASSIGN(s,c) { if (c) s=c; else s.erase(); } #define TCFG_CLEAR(s) s.erase() #define TCFG_ISEMPTY(s) s.empty() #define TCFG_SIZE(s) s.size() #endif // forward class TSyncSession; class TSyncItemType; class TSyncItem; class TStatusCommand; class TDataTypeConfig; class TLocalEngineDS; class TRemoteDataStore; class TSyncDataStore; // container types typedef std::list TSyncItemTypePContainer; // contains item types // type variant descriptor (for now, a simple pointer, if needed we can make it a class later) typedef void * TTypeVariantDescriptor; const uInt16 ity_syncitem = 0; // must be unique class TSyncItemType : noncopyable { private: void init( TSyncSession *aSessionP, TDataTypeConfig *aTypeConfigP, const char *aCTType, const char *aVerCT, TSyncDataStore *aRelatedDatastoreP ); public: // constructor TSyncItemType( TSyncSession *aSessionP, TDataTypeConfig *aTypeConfigP, const char *aCTType, const char *aVerCT, TSyncDataStore *aRelatedDatastoreP ); // destructor virtual ~TSyncItemType(); // access to type virtual uInt16 getTypeID(void) const { return ity_syncitem; }; virtual bool isBasedOn(uInt16 aItemTypeID) const { return aItemTypeID==ity_syncitem; }; // differentiation between implemented and just descriptive TSyncTypeItems virtual bool isImplemented(void) { return false; }; // base class is descriptive only // differentiation between type describing local and remote items bool isRemoteType(void) { return fIsRemoteType; }; void defineAsRemoteType(void) { fIsRemoteType = true; }; // compatibility (=assignment compatibility between items based on these types) virtual bool isCompatibleWith(TSyncItemType *aReferenceType) { return this==aReferenceType; } // compatible if same type // get session pointer TSyncSession *getSession(void) { return fSessionP; }; // get session zones pointer GZones *getSessionZones(void); // ret related datastore (can be NULL for session-global types like before DS 1.2) TSyncDataStore *getRelatedDatastore(void) { return fRelatedDatastoreP; }; // helper to create same-typed instance via base class // MUST BE IMPLEMENTED IN ALL DERIVED CLASSES! virtual TSyncItemType *newCopyForSameType( TSyncSession *aSessionP, // the session TSyncDataStore *aDatastoreP // the datastore ); // apply default limits to type (e.g. from hard-coded template in config) virtual void addDefaultTypeLimits(void) { /* nop */ }; // Prepare datatype for use with a datastore. This might be implemented // in derived classes to initialize the datastore's script context etc. virtual void initDataTypeUse(TLocalEngineDS * /* aDatastoreP */, bool /* aForSending */, bool /* aForReceiving */) { /* nop */ }; // Filtering // - add keywords and property names to filterCap virtual void addFilterCapPropsAndKeywords(SmlPcdataListPtr_t &aFilterKeywords, SmlPcdataListPtr_t &aFilterProps, TTypeVariantDescriptor aVariantDesc) { /* nop */ }; // - check for special filter keywords the type might want to handle directly virtual bool checkFilterkeywordTerm( cAppCharP aIdent, bool aAssignToMakeTrue, cAppCharP aOp, bool aCaseInsensitive, cAppCharP aVal, bool aSpecialValue ) { return true; /* we do not handle this specially, handle at DS level or include into filter expression */ }; // - init new-style filtering, returns flag if needed at all virtual void initPostFetchFiltering(bool &aNeeded, bool &aNeededForAll, TLocalEngineDS * /* aDatastoreP */) { aNeeded=false; aNeededForAll=false; }; // item read and write // - test if item could contain cut-off data (e.g. because of field size restrictions) // compared to specified reference item virtual bool mayContainCutOffData(TSyncItemType * /* aReferenceType */) { return false; }; // generally, no // - try to extract a version string from actual item data, NULL if none virtual bool versionFromData(SmlItemPtr_t /* aItemP */, string & /* aString */) { return false; }; #ifdef APP_CAN_EXPIRE // test if modified date of item is hard-expired virtual sInt32 expiryFromData(SmlItemPtr_t /* aItemP */, lineardate_t & /* aDat */) { return 0; }; // default to not expired #endif /// create new empty sync item TSyncItem *newSyncItem( TSyncItemType *aTargetItemTypeP, ///< the targeted type (for optimizing field lists etc.) TLocalEngineDS *aLocalDataStoreP ///< local datastore ); /// create new sync item from SyncML data TSyncItem *newSyncItem( SmlItemPtr_t aItemP, ///< SyncML toolkit item Data to be converted into SyncItem TSyncOperation aSyncOp, ///< the operation to be performed with this item TFmtTypes aFormat, ///< the format (normally fmt_chr) TSyncItemType *aTargetItemTypeP, ///< the targeted type (for optimizing field lists etc.) TLocalEngineDS *aLocalDataStoreP, ///< local datastore TStatusCommand &aStatusCmd ///< status command that might be modified in case of error ); /// create new SyncML toolkit item from SyncItem SmlItemPtr_t newSmlItem( TSyncItem *aSyncItemP, ///< the syncitem to be represented as SyncML TLocalEngineDS *aLocalDatastoreP ///< local datastore ); /// @brief get CTCap entry /// @param aOnlyForDS[in] /// - if NULL, CTCap is generated suitable for all datastores /// - if not NULL, CTCap is generated specifically for the datastore passed const SmlDevInfCTCapPtr_t getCTCapDevInf(TLocalEngineDS *aOnlyForDS, TTypeVariantDescriptor aVariantDescriptor, bool aWithoutCTCapProps); /// @brief analyze CTCap for specific type virtual bool analyzeCTCap(SmlDevInfCTCapPtr_t aCTCapP); /// @brief copy CTCap derived info from another SyncItemType virtual bool copyCTCapInfoFrom(TSyncItemType &aSourceItem); /// @brief returns true if type is able to ACCEPT field level updates virtual bool canAcceptFieldLevelUpdates(void) { return false; }; /* no by default */ // - static function to search type in a TSyncItemTypePContainer static TSyncItemType *findTypeInList( TSyncItemTypePContainer &aList, const char *aName, const char *aVers, bool aVersMustMatch, bool aMustBeImplemented, TSyncDataStore *aRelatedDatastoreP ); static TSyncItemType *findTypeInList( TSyncItemTypePContainer &aList, SmlDevInfXmitPtr_t aXmitType, // name and version of type bool aVersMustMatch, bool aMustBeImplemented, TSyncDataStore *aRelatedDatastoreP ); // - static function to analyze CTCap and add entries to passed list static bool analyzeCTCapAndCreateItemTypes( TSyncSession *aSessionP, TRemoteDataStore *aRemoteDataStoreP, // if not NULL, this is the datastore to which this type is local (DS 1.2 case) SmlDevInfCTCapPtr_t aCTCapP, TSyncItemTypePContainer &aLocalItemTypes, // list to look up local types (for reference) TSyncItemTypePContainer &aNewItemTypes // list to add analyzed types if not already there ); // - static function to add new or copied ItemType to passed list static TSyncItemType *registerRemoteType( TSyncSession *aSessionP, const char *aName, const char *aVers, // name and version of type TSyncItemTypePContainer &aLocalItemTypes, // list to look up local types (for reference) TSyncItemTypePContainer &aNewItemTypes, // list to add analyzed types if not already there TSyncDataStore *aRelatedDatastoreP ); static TSyncItemType *registerRemoteType( TSyncSession *aSessionP, SmlDevInfXmitPtr_t aXmitTypeP, // name and version of type TSyncItemTypePContainer &aLocalItemTypes, // list to look up local types (for reference) TSyncItemTypePContainer &aNewItemTypes, // list to add analyzed types if not already there TSyncDataStore *aRelatedDatastoreP ); // static helper for creating rx/tx type lists static SmlDevInfXmitListPtr_t newXMitListDevInf( TSyncItemTypePContainer &aTypeList, TSyncItemType *aDontIncludeP ); // type support check virtual bool supportsType(const char *aName, const char *aVers, bool aVersMustMatch=false); bool supportsType(SmlDevInfXmitPtr_t aXmitType, bool aVersMustMatch=false); // - get type name / vers virtual cAppCharP getTypeName(sInt32 aMode=0) { return fTypeName.c_str(); }; virtual cAppCharP getTypeVers(sInt32 aMode=0) { return fTypeVers.c_str(); }; void setTypeVers(const char *aVers) { fTypeVers=aVers; }; bool hasTypeVers(void) { return !fTypeVers.empty(); }; // - read type as Rx/Tx entry SmlDevInfXmitPtr_t newXMitDevInf(void); // - get config pointer of type TDataTypeConfig *getTypeConfig(void) { return fTypeConfigP; }; // - get debug #ifdef SYDEBUG TDebugLogger *getDbgLogger(void); uInt32 getDbgMask(void); #endif protected: // methods // obtain property list for type, returns NULL if none available virtual SmlDevInfCTDataPropListPtr_t newCTDataPropList(TTypeVariantDescriptor aVariantDescriptor) { return NULL; } // no properties available // Item data management // - create new sync item of proper type. // NOTE: aTargetItemTypeP is passed to allow creation of optimized items for // reception by a specific target type (e.g. common field list optimization etc.) virtual TSyncItem *internalNewSyncItem( TSyncItemType * /* aTargetItemTypeP */, TLocalEngineDS * /* aLocalDatastoreP */ ) { return NULL; } // no op in base class (returns no item) // - fill in SyncML data (but leaves IDs empty) virtual bool internalFillInData( TSyncItem * /* aSyncItemP */, // SyncItem to be filled with data SmlItemPtr_t /* aItemP */, // SyncML toolkit item Data to be converted into SyncItem (may be NULL if no data, in case of Delete or Map) TLocalEngineDS * /* aLocalDatastoreP */, // local datastore TStatusCommand & /* aStatusCmd */ // status command that might be modified in case of error ) { return false; } // no op in base class (cannot fill) // - sets data and meta from SyncItem data, but leaves source & target untouched virtual bool internalSetItemData( TSyncItem * /* aSyncItemP */, // the syncitem to be represented as SyncML SmlItemPtr_t /* aItem */, // item with NULL meta and NULL data TLocalEngineDS * /* aLocalDatastoreP */ // local datastore ) { return false; } // no op in base class (leaves item untouched) // session pointer TSyncSession *fSessionP; // the config for this type TDataTypeConfig *fTypeConfigP; private: // the related datastore (for DS 1.2) TSyncDataStore *fRelatedDatastoreP; // the item's type name and version string fTypeName; string fTypeVers; #if defined(ZIPPED_BINDATA_SUPPORT) && defined(SYDEBUG) sInt32 fRawDataBytes; sInt32 fZippedDataBytes; #endif // flag if this is a remote type bool fIsRemoteType; }; // TSyncItemType } // namespace sysync #endif // SyncItemType_H // eof libsynthesis-3.4.0.47.1/src/sysync/syncml_globs.h000077500000000000000000000034271226375725500216400ustar00rootroot00000000000000/* * File: syncml_globs.h * * Authors: Lukas Zeller (luz@plan44.ch) * Beat Forster (bfo@synthesis.ch) * * Global SyncML definitions/macros/constants * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * */ #ifndef SYNCML_GLOBS_H #define SYNCML_GLOBS_H #include "generic_types.h" #ifdef __cplusplus #if defined _MSC_VER && !defined WINCE #include #endif // Consistent support for Linux, MacOSX CW & XCode & Visual Studio #if defined __GNUC__ || defined _MSC_VER #include #else #include #endif // we need the namespace std using namespace std; namespace sysync { #endif // basic SyncML constants #define SYNCML_HDRCMDNAME "SyncHdr" // SyncML Encodings (to be appended to SYNCML_MIME_TYPE and SYNCML_DEVINF_META_TYPE #define SYNCML_ENCODING_XML "xml" #define SYNCML_ENCODING_WBXML "wbxml" // - spearator between MIME-Type and encoding string #define SYNCML_ENCODING_SEPARATOR "+" // SyncML content type constants #define SYNCML_MIME_TYPE "application/vnd.syncml" // plus encoding // SyncML charset #define SYNCML_DEFAULT_CHARSET "utf-8" // prefix for relative URIs #define URI_RELPREFIX "./" // SyncML DEVINF constants #define SYNCML_DEVINF_LOCNAME "Device Information" #define SYNCML_DEVINF_META_TYPE "application/vnd.syncml-devinf" // plus encoding ! #define SYNCML_META_VERSION "syncml:metinf" // SyncML Filter grammars #define SYNCML_FILTERTYPE_CGI "syncml:filtertype-cgi" #define SYNCML_FILTERTYPE_CGI_VERS "1.0" #define SYNCML_FILTERTYPE_INCLUSIVE "INCLUSIVE" #define SYNCML_FILTERTYPE_EXCLUSIVE "EXCLUSIVE" // SyncML encodings // Note: SmlEncoding_t is defined in the RTK smldef.h #define numSyncMLEncodings (SML_XML-SML_UNDEF+1) #ifdef __cplusplus } // namespace sysync #endif #endif // SYNCML_GLOBS_H // eof libsynthesis-3.4.0.47.1/src/sysync/syncml_tk.h000077500000000000000000000001451226375725500211420ustar00rootroot00000000000000/* sysync SyncML toolkit includes */ #ifndef SYNCML_TK_HPP #define SYNCML_TK_HPP #include #endif libsynthesis-3.4.0.47.1/src/sysync/syncsession.cpp000066400000000000000000007212001226375725500220510ustar00rootroot00000000000000/* * TSyncSession * Represents an entire Synchronisation Session, possibly consisting * of multiple SyncML-Toolkit "Sessions" (Message composition/de- * composition) as well as multiple database synchronisations. * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * 2001-05-07 : luz : Created * */ #include "prefix_file.h" #include "sysync.h" #include "syncsession.h" #include "syncagent.h" #ifdef SUPERDATASTORES #include "superdatastore.h" #endif #ifdef SCRIPT_SUPPORT #include "scriptcontext.h" #endif #ifdef MULTI_THREAD_SUPPORT #include "platform_thread.h" #endif #include #include #ifndef SYNCSESSION_PART1_EXCLUDE namespace sysync { // enum names // ---------- // SyncML version info const char * const SyncMLVerProtoNames[numSyncMLVersions] = { "undefined", "SyncML/1.0", "SyncML/1.1", "SyncML/1.2" }; const SmlVersion_t SmlVersionCodes[numSyncMLVersions] = { SML_VERS_UNDEF, SML_VERS_1_0, SML_VERS_1_1, SML_VERS_1_2 }; const char * const SyncMLVerDTDNames[numSyncMLVersions] = { "???", "1.0", "1.1", "1.2" }; const char * const SyncMLDevInfNames[numSyncMLVersions] = { NULL, "./devinf10", "./devinf11", "./devinf12" }; #ifndef HARDCODED_CONFIG // version for use in config files const char * const SyncMLVersionNames[numSyncMLVersions] = { "unknown", "1.0", "1.1", "1.2" }; #endif // auth type names for config const char * const authTypeNames[numAuthTypes] = { "none", // no authorisation "basic", // basic (B64 encoded user pw string) "md5", // Md5 encoded user:pw:nonce }; // sync mode names const char * const SyncModeNames[numSyncModes] = { "twoway", "fromserver", "fromclient" }; #ifdef SYDEBUG // package state names const char * const PackageStateNames[numPackageStates] = { "idle", "init", "sync", "initsync", "map", "supplement" }; // sync operations const char * const SyncOpNames[numSyncOperations] = { "wants-add", "add", "wants-replace", "replace", "reference-only", "archive+delete", "soft-delete", "delete", "copy", "move", "[none]" // should be last }; #endif // sync mode descriptions const char * const SyncModeDescriptions[numSyncModes] = { "two-way", "from server only", "from client only" }; #ifdef SCRIPT_SUPPORT // builtin functions for status-handling scripts // integer STATUS() static void func_Status(TItemField *&aTermP, TScriptContext *aFuncContextP) { TErrorFuncContext *errctxP = static_cast(aFuncContextP->getCallerContext()); aTermP->setAsInteger( errctxP->statuscode ); } // func_Status // void SETSTATUS(integer statuscode) static void func_SetStatus(TItemField *&aTermP, TScriptContext *aFuncContextP) { TErrorFuncContext *errctxP = static_cast(aFuncContextP->getCallerContext()); errctxP->newstatuscode= aFuncContextP->getLocalVar(0)->getAsInteger(); } // func_SetStatus // void SETRESEND(boolean doresend) static void func_SetResend(TItemField *&aTermP, TScriptContext *aFuncContextP) { TErrorFuncContext *errctxP = static_cast(aFuncContextP->getCallerContext()); errctxP->resend= aFuncContextP->getLocalVar(0)->getAsBoolean(); } // func_SetResend // void ABORTDATASTORE(integer statuscode) static void func_AbortDatastore(TItemField *&aTermP, TScriptContext *aFuncContextP) { TErrorFuncContext *errctxP = static_cast(aFuncContextP->getCallerContext()); if (errctxP->datastoreP) { errctxP->datastoreP->engAbortDataStoreSync(aFuncContextP->getLocalVar(0)->getAsInteger(),true); // we cause the abort locally } } // func_AbortDatastore // void STOPADDING() static void func_StopAdding(TItemField *&aTermP, TScriptContext *aFuncContextP) { TErrorFuncContext *errctxP = static_cast(aFuncContextP->getCallerContext()); if (errctxP->datastoreP) { errctxP->datastoreP->engStopAddingToRemote(); } } // func_StopAdding // string SYNCOP() // returns sync-operation as text static void func_SyncOp(TItemField *&aTermP, TScriptContext *aFuncContextP) { TErrorFuncContext *errctxP = static_cast(aFuncContextP->getCallerContext()); aTermP->setAsString( SyncOpNames[errctxP->syncop] ); } // func_SyncOp const uInt8 param_OneInteger[] = { VAL(fty_integer) }; const uInt8 param_TwoIntegers[] = { VAL(fty_integer), VAL(fty_integer) }; const uInt8 param_OneString[] = { VAL(fty_string) }; const TBuiltInFuncDef ErrorFuncDefs[] = { { "STATUS", func_Status, fty_integer, 0, NULL }, { "SETSTATUS", func_SetStatus, fty_none, 1, param_OneInteger }, { "SETRESEND", func_SetResend, fty_none, 1, param_OneInteger }, { "ABORTDATASTORE", func_AbortDatastore, fty_none, 1, param_OneInteger }, { "STOPADDING", func_StopAdding, fty_none, 0, NULL }, { "SYNCOP", func_SyncOp, fty_string, 0, NULL }, }; const TFuncTable ErrorFuncTable = { sizeof(ErrorFuncDefs) / sizeof(TBuiltInFuncDef), // size of table ErrorFuncDefs, // table pointer NULL // no chain func }; // void SETSTATUS(integer statuscode) static void func_GetPutResSetStatus(TItemField *&aTermP, TScriptContext *aFuncContextP) { TGetPutResultFuncContext *gprctxP = static_cast(aFuncContextP->getCallerContext()); gprctxP->statuscode= aFuncContextP->getLocalVar(0)->getAsInteger(); } // func_GetPutResSetStatus // integer ISPUT() static void func_IsPut(TItemField *&aTermP, TScriptContext *aFuncContextP) { TGetPutResultFuncContext *gprctxP = static_cast(aFuncContextP->getCallerContext()); aTermP->setAsBoolean(gprctxP->isPut); } // func_IsPut // string ITEMURI() static void func_ItemURI(TItemField *&aTermP, TScriptContext *aFuncContextP) { TGetPutResultFuncContext *gprctxP = static_cast(aFuncContextP->getCallerContext()); aTermP->setAsString(gprctxP->itemURI); } // func_ItemURI // void SETITEMURI(string data) static void func_SetItemURI(TItemField *&aTermP, TScriptContext *aFuncContextP) { TGetPutResultFuncContext *gprctxP = static_cast(aFuncContextP->getCallerContext()); aFuncContextP->getLocalVar(0)->getAsString(gprctxP->itemURI); } // func_SetItemURI // string ITEMDATA() static void func_ItemData(TItemField *&aTermP, TScriptContext *aFuncContextP) { TGetPutResultFuncContext *gprctxP = static_cast(aFuncContextP->getCallerContext()); aTermP->setAsString(gprctxP->itemData); } // func_ItemData // void SETITEMDATA(string data) static void func_SetItemData(TItemField *&aTermP, TScriptContext *aFuncContextP) { TGetPutResultFuncContext *gprctxP = static_cast(aFuncContextP->getCallerContext()); aFuncContextP->getLocalVar(0)->getAsString(gprctxP->itemData); } // func_SetItemData // string METATYPE() static void func_MetaType(TItemField *&aTermP, TScriptContext *aFuncContextP) { TGetPutResultFuncContext *gprctxP = static_cast(aFuncContextP->getCallerContext()); aTermP->setAsString(gprctxP->metaType); } // func_MetaType // void SETMETATYPE(string data) static void func_SetMetaType(TItemField *&aTermP, TScriptContext *aFuncContextP) { TGetPutResultFuncContext *gprctxP = static_cast(aFuncContextP->getCallerContext()); aFuncContextP->getLocalVar(0)->getAsString(gprctxP->metaType); } // func_SetMetaType // void ISSUEPUT(boolean allowFailure, boolean noResp) // use ITEMURI, ITEMDATA and METATYPE to issue a PUT command static void func_IssuePut(TItemField *&aTermP, TScriptContext *aFuncContextP) { TGetPutResultFuncContext *gprctxP = static_cast(aFuncContextP->getCallerContext()); if (gprctxP->canIssue) { TPutCommand *putcommandP = new TPutCommand(aFuncContextP->getSession()); putcommandP->setMeta(newMetaType(gprctxP->metaType.c_str())); SmlItemPtr_t putItemP = putcommandP->addSourceLocItem(gprctxP->itemURI.c_str()); // - add data to item putItemP->data = newPCDataString(gprctxP->itemData); // issue it if (aFuncContextP->getLocalVar(0)->getAsBoolean()) putcommandP->allowFailure(); // allow failure (4xx or 5xx status) aFuncContextP->getSession()->issueRootPtr(putcommandP,aFuncContextP->getLocalVar(1)->getAsBoolean()); } } // func_IssuePut // void ISSUEGET(boolean allowFailure) // use ITEMURI and METATYPE to issue a GET command static void func_IssueGet(TItemField *&aTermP, TScriptContext *aFuncContextP) { TGetPutResultFuncContext *gprctxP = static_cast(aFuncContextP->getCallerContext()); if (gprctxP->canIssue) { TGetCommand *getcommandP = new TGetCommand(aFuncContextP->getSession()); getcommandP->addTargetLocItem(gprctxP->itemURI.c_str()); getcommandP->setMeta(newMetaType(gprctxP->metaType.c_str())); // issue it if (aFuncContextP->getLocalVar(0)->getAsBoolean()) getcommandP->allowFailure(); // allow failure (4xx or 5xx status) aFuncContextP->getSession()->issueRootPtr(getcommandP,false); // get with noResp does not make sense } } // func_IssueGet // void ISSUEALERT(boolean allowFailure, integer alertcode) // use ITEMDATA to add an Alert item static void func_IssueAlert(TItemField *&aTermP, TScriptContext *aFuncContextP) { TGetPutResultFuncContext *gprctxP = static_cast(aFuncContextP->getCallerContext()); if (gprctxP->canIssue) { uInt16 alertcode = aFuncContextP->getLocalVar(1)->getAsInteger(); TAlertCommand *alertCommandP = new TAlertCommand(aFuncContextP->getSession(),NULL,alertcode); // - add string data item alertCommandP->addItem(newStringDataItem(gprctxP->itemData.c_str())); // issue it if (aFuncContextP->getLocalVar(0)->getAsBoolean()) alertCommandP->allowFailure(); // allow failure (4xx or 5xx status) aFuncContextP->getSession()->issueRootPtr(alertCommandP,false); // Alert with noResp not supported } } // func_IssueAlert const TBuiltInFuncDef GetPutResultFuncDefs[] = { { "SETSTATUS", func_GetPutResSetStatus, fty_none, 1, param_OneInteger }, { "ISPUT", func_IsPut, fty_integer, 0, NULL }, { "ITEMURI", func_ItemURI, fty_string, 0, NULL }, { "SETITEMURI", func_SetItemURI, fty_none, 1, param_OneString }, { "ITEMDATA", func_ItemData, fty_string, 0, NULL }, { "SETITEMDATA", func_SetItemData, fty_none, 1, param_OneString }, { "METATYPE", func_MetaType, fty_string, 0, NULL }, { "SETMETATYPE", func_SetMetaType, fty_none, 1, param_OneString }, { "ISSUEPUT", func_IssuePut, fty_none, 2, param_TwoIntegers }, { "ISSUEGET", func_IssueGet, fty_none, 1, param_OneInteger }, { "ISSUEALERT", func_IssueAlert, fty_none, 2, param_TwoIntegers } }; const TFuncTable GetPutResultFuncTable = { sizeof(GetPutResultFuncDefs) / sizeof(TBuiltInFuncDef), // size of table GetPutResultFuncDefs, // table pointer NULL // no chain func }; #endif #ifndef NO_REMOTE_RULES // Remote Rule Config // ================== #define DONT_REJECT 0xFFFF // config constructor TRemoteRuleConfig::TRemoteRuleConfig(const char *aElementName, TConfigElement *aParentElementP) : TConfigElement(aElementName,aParentElementP) { clear(); } // TRemoteRuleConfig::TRemoteRuleConfig // config destructor TRemoteRuleConfig::~TRemoteRuleConfig() { if (fOverrideDevInfBufferP) smlFreeProtoElement(fOverrideDevInfBufferP); clear(); } // TRemoteRuleConfig::~TRemoteRuleConfig // init defaults void TRemoteRuleConfig::clear(void) { // init defaults // - id fManufacturer.erase(); fModel.erase(); fOem.erase(); fFirmwareVers.erase(); fSoftwareVers.erase(); fHardwareVers.erase(); fDevId.erase(); fDevTyp.erase(); // - options fRejectStatusCode=DONT_REJECT; // not rejected fLegacyMode=-1; // set if remote is known legacy, so don't use new types fLenientMode=-1; // set if remote's SyncML should be handled leniently, i.e. not too strict checking where not absolutely needed fLimitedFieldLengths=-1; // set if remote has limited field lengths fDontSendEmptyProperties=-1; // set if remote does not want empty properties fDoQuote8BitContent=-1; // normally, only use QP for contents with EOLNs in vCard 2.1 fDoNotFoldContent=-1; // normally, content must be folded in MIME-DIR fNoReplaceInSlowsync=-1; // normally, we are allowed to use Replace (as server) in slow sync fTreatRemoteTimeAsLocal=-1; // do not ignore time zone fTreatRemoteTimeAsUTC=-1; // do not ignore time zone fVCal10EnddatesSameDay=-1; // use default end date rendering fIgnoreDevInfMaxSize=-1; // do not ignore max field size in remote's devInf fIgnoreCTCap=-1; // do not ignore CTCap fDSPathInDevInf=-1; // use actual DS path as used in Alert for creating datastore devInf (needed for newer Nokia clients) fDSCgiInDevInf=-1; // also show CGI as used in Alert for creating datastore devInf (needed for newer Nokia clients) fForceUTC=-1; // automatic decision based on DevInf (SyncML 1.1) or just UTC for SyncML 1.0 fForceLocaltime=-1; fTreatCopyAsAdd=-1; fCompleteFromClientOnly=-1; fRequestMaxTime=-1; // not defined fDefaultOutCharset=chs_unknown; // do not set the default output charset fDefaultInCharset=chs_unknown; // do not set the default input interpretation charset // - options that also have a configurable session default fUpdateClientDuringSlowsync=-1; fUpdateServerDuringSlowsync=-1; fAllowMessageRetries=-1; fStrictExecOrdering=-1; #ifndef MINIMAL_CODE fRemoteDescName.erase(); #endif fSubRulesList.clear(); // no included subrules fSubRule = false; // normal rule by default // - rules are final by default fFinalRule = true; // no DevInf by default fOverrideDevInfP = NULL; fOverrideDevInfBufferP = NULL; // clear inherited inherited::clear(); } // TRemoteRuleConfig::clear #ifndef HARDCODED_CONFIG // remote rule config element parsing bool TRemoteRuleConfig::localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine) { // checking the elements // - identification of remote (irrelevant for subrules) if (!fSubRule && strucmp(aElementName,"manufacturer")==0) expectString(fManufacturer); else if (!fSubRule && strucmp(aElementName,"model")==0) expectString(fModel); else if (!fSubRule && strucmp(aElementName,"oem")==0) expectString(fOem); else if (!fSubRule && strucmp(aElementName,"firmware")==0) expectString(fFirmwareVers); else if (!fSubRule && strucmp(aElementName,"software")==0) expectString(fSoftwareVers); else if (!fSubRule && strucmp(aElementName,"hardware")==0) expectString(fHardwareVers); else if (!fSubRule && strucmp(aElementName,"deviceid")==0) expectString(fDevId); else if (!fSubRule && strucmp(aElementName,"devicetype")==0) expectString(fDevTyp); // - options else if (strucmp(aElementName,"legacymode")==0) expectTristate(fLegacyMode); else if (strucmp(aElementName,"lenientmode")==0) expectTristate(fLenientMode); else if (strucmp(aElementName,"limitedfieldlengths")==0) expectTristate(fLimitedFieldLengths); else if (strucmp(aElementName,"noemptyproperties")==0) expectTristate(fDontSendEmptyProperties); else if (strucmp(aElementName,"quote8bitcontent")==0) expectTristate(fDoQuote8BitContent); else if (strucmp(aElementName,"nocontentfolding")==0) expectTristate(fDoNotFoldContent); else if (strucmp(aElementName,"noreplaceinslowsync")==0) expectTristate(fNoReplaceInSlowsync); else if (strucmp(aElementName,"treataslocaltime")==0) expectTristate(fTreatRemoteTimeAsLocal); else if (strucmp(aElementName,"treatasutc")==0) expectTristate(fTreatRemoteTimeAsUTC); else if (strucmp(aElementName,"autoenddateinclusive")==0) expectTristate(fVCal10EnddatesSameDay); else if (strucmp(aElementName,"ignoredevinfmaxsize")==0) expectTristate(fIgnoreDevInfMaxSize); else if (strucmp(aElementName,"ignorectcap")==0) expectTristate(fIgnoreCTCap); else if (strucmp(aElementName,"dspathindevinf")==0) expectTristate(fDSPathInDevInf); else if (strucmp(aElementName,"dscgiindevinf")==0) expectTristate(fDSCgiInDevInf); else if (strucmp(aElementName,"updateclientinslowsync")==0) expectTristate(fUpdateClientDuringSlowsync); else if (strucmp(aElementName,"updateserverinslowsync")==0) expectTristate(fUpdateServerDuringSlowsync); else if (strucmp(aElementName,"allowmessageretries")==0) expectTristate(fAllowMessageRetries); else if (strucmp(aElementName,"strictexecordering")==0) expectTristate(fStrictExecOrdering); else if (strucmp(aElementName,"treatcopyasadd")==0) expectTristate(fTreatCopyAsAdd); else if (strucmp(aElementName,"completefromclientonly")==0) expectTristate(fCompleteFromClientOnly); else if (strucmp(aElementName,"requestmaxtime")==0) expectInt32(fRequestMaxTime); else if (strucmp(aElementName,"outputcharset")==0) expectEnum(sizeof(fDefaultOutCharset),&fDefaultOutCharset,MIMECharSetNames,numCharSets); else if (strucmp(aElementName,"inputcharset")==0) expectEnum(sizeof(fDefaultInCharset),&fDefaultInCharset,MIMECharSetNames,numCharSets); else if (strucmp(aElementName,"rejectstatus")==0) expectUInt16(fRejectStatusCode); else if (strucmp(aElementName,"forceutc")==0) expectTristate(fForceUTC); else if (strucmp(aElementName,"forcelocaltime")==0) expectTristate(fForceLocaltime); else if (strucmp(aElementName,"overridedevinf")==0) expectString(fOverrideDevInfXML); // inclusion of subrules else if (strucmp(aElementName,"include")==0) { // expectEmpty(); const char* nam = getAttr(aAttributes,"rule"); if (!nam) return fail(" must specify \"rule\""); else { // find rule TRemoteRulesList::iterator pos; TSessionConfig *scfgP = static_cast(getParentElement()); for(pos=scfgP->fRemoteRulesList.begin();pos!=scfgP->fRemoteRulesList.end();pos++) { if (strucmp(nam,(*pos)->getName())==0) { fSubRulesList.push_back(*pos); return true; // done } } return fail("rule '%s' for not found (must be defined before included)",nam); } } // rule script. Note that this is special, as it is NOT resolved in the config, but // copied to the session first, as it might differ between sessions. #ifdef SCRIPT_SUPPORT else if (strucmp(aElementName,"rulescript")==0) expectScript(fRuleScriptTemplate,aLine,NULL,true); // late binding, no declarations allowed #endif #ifndef MINIMAL_CODE else if (strucmp(aElementName,"descriptivename")==0) expectString(fRemoteDescName); #endif // - final rule? else if (strucmp(aElementName,"finalrule")==0) expectBool(fFinalRule); // - not known here else return inherited::localStartElement(aElementName,aAttributes,aLine); // ok return true; } // TRemoteRuleConfig::localStartElement #endif // HARDCODED_CONFIG #endif // NO_REMOTE_RULES #endif // not SYNCSESSION_PART1_EXCLUDE #ifndef SYNCSESSION_PART2_EXCLUDE // Session Config // ============== // config constructor TSessionConfig::TSessionConfig(const char *aElementName, TConfigElement *aParentElementP) : inherited(aElementName,aParentElementP) { clear(); } // TSessionConfig::TSessionConfig // config destructor TSessionConfig::~TSessionConfig() { clear(); } // TSessionConfig::~TSessionConfig // init defaults void TSessionConfig::clear(void) { // init defaults #ifndef NO_REMOTE_RULES // - no remote rules TRemoteRulesList::iterator pos; for(pos=fRemoteRulesList.begin();pos!=fRemoteRulesList.end();pos++) delete *pos; fRemoteRulesList.clear(); #endif // remove datastores TLocalDSList::iterator pos2; for(pos2=fDatastores.begin();pos2!=fDatastores.end();pos2++) delete *pos2; fDatastores.clear(); // - no simple auth fSimpleAuthUser.erase(); fSimpleAuthPassword.erase(); // - medium timeout fSessionTimeout = 60; // one minute, will be overridden by derived classes // - set default maximum SyncML version enabled fMaxSyncMLVersionSupported = MAX_SYNCML_VERSION; // - minimum is 1.0 fMinSyncMLVersionSupported=syncml_vers_1_0; // - accept server-alerted codes by default fAcceptServerAlerted = true; // - defaults for remote-rule configurable behaviour fUpdateClientDuringSlowsync = false; // do not update client records during slowsync (but do it for first sync!) fUpdateServerDuringSlowsync = false; // do not update server records during NON-FIRST-TIME slowsync (but do it for first sync!) fAllowMessageRetries = true; // generally allow retries fCompleteFromClientOnly = false; // default to standard-compliant behaviour. fRequestMaxTime = 0; // no limit by default fRequestMinTime = 0; // no minimal request processing delay // - default value for flag to send property lists in CTCap fShowCTCapProps = true; // - default value for flag to send type/size in CTCap for SyncML 1.0 (disable as old clients like S55 crash on this) fShowTypeSzInCTCap10 = false; // - sync mode extensions may be needed for SyncEvolution, but are causing troubles with Nokia phones and some servers so these are off by default fSyncModeExtensions = false; if (IS_CLIENT) { // - Synthesis clients always behaved like that (sending 23:59:59), so we'll keep it as a default fVCal10EnddatesSameDay = true; } else { // - Many modern clients need the exclusive format (start of next day) to detect all-day events properly. // Synthesis clients detect these fine as well, so not using 23:59:59 style by default is more // compatible in general for a server. fVCal10EnddatesSameDay = false; } // traditionally Synthesis has folded content fDoNotFoldContent = false; // - default value for flag is "default" (depends on SyncML version) fEnumDefaultPropParams=-1; // - decide, whether multi-threading for the datastores will be used: // As there are some problems with older Linux versions (e.g. Debian 3.0r2 stable) the // default values are set for downwards compatibility Linux=false / all others=true // Multithreading can be switched of either by #define or by flag #if defined LINUX || !defined MULTI_THREAD_DATASTORE fMultiThread= false; #else fMultiThread= true; #endif // - do not wait for status of interrupted command by default (note: before 2.1.0.2, this was always true) fWaitForStatusOfInterrupted=false; // - accept delete commands for already deleted items with 200 (rather that 404 or 211) #ifdef SCTS_COMPATIBILITY_HACKS fDeletingGoneOK=false; // SCTS needs that #else fDeletingGoneOK=true; // makes more sense as it avoids unnecessary session aborts #endif // - abort if all items sent to remote fail fAbortOnAllItemsFailed=true; // note: does only apply in slow syncs now! // - default to system time fUserTimeContext=TCTX_SYSTEM; #ifdef SCRIPT_SUPPORT // - session init script fSessionInitScript.erase(); // - status handling scripts fSentItemStatusScript.erase(); fReceivedItemStatusScript.erase(); // - session termination script fSessionFinishScript.erase(); // - custom get handler fCustomGetHandlerScript.erase(); // - custom get and put generators fCustomGetPutScript.erase(); fCustomEndPutScript.erase(); // - custom PUT and RESULT handler fCustomPutResultHandlerScript.erase(); #endif #ifndef MINIMAL_CODE // - logfile fLogFileName.erase(); if (IS_SERVER) { fLogFileFormat.assign(DEFAULT_LOG_FORMAT_SERVER); fLogFileLabels.assign(DEFAULT_LOG_LABELS_SERVER); } else { fLogFileFormat.assign(DEFAULT_LOG_FORMAT_CLIENT); fLogFileLabels.assign(DEFAULT_LOG_LABELS_CLIENT); } fLogEnabled=true; fDebugChunkMaxSize=0; // disabled #endif fRelyOnEarlyMaps=true; // we rely on early maps sent by clients for adds from the previous session // clear inherited inherited::clear(); } // TSessionConfig::clear // get local DS config pointer by database name or dbTypeID TLocalDSConfig *TSessionConfig::getLocalDS(const char *aName, uInt32 aDBTypeID) { TLocalDSList::iterator pos; for(pos=fDatastores.begin();pos!=fDatastores.end();pos++) { if (aName==NULL) { if ((*pos)->fLocalDBTypeID==aDBTypeID) return *pos; // found by DBTypeID } else { if (strucmp((*pos)->getName(),aName)==0) return *pos; // found by name } } return NULL; // not found } // TSessionConfig::getLocalDS #ifndef HARDCODED_CONFIG // server config element parsing bool TSessionConfig::localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine) { // checking the elements #ifndef NO_REMOTE_RULES bool isSubRule = strucmp(aElementName,"subrule")==0; if (strucmp(aElementName,"remoterule")==0 || isSubRule) { // check for optional name attribute const char* nam = getAttr(aAttributes,"name"); if (!nam) nam="unnamed"; // create rule TRemoteRuleConfig *ruleP = new TRemoteRuleConfig(nam,this); ruleP->fSubRule = isSubRule; fRemoteRulesList.push_back(ruleP); expectChildParsing(*ruleP); } else #endif if (strucmp(aElementName,"sessiontimeout")==0) expectInt32(fSessionTimeout); else if (strucmp(aElementName,"requestmaxtime")==0) expectUInt32(fRequestMaxTime); else if (strucmp(aElementName,"requestmintime")==0) expectInt32(fRequestMinTime); else if (strucmp(aElementName,"simpleauthuser")==0) expectString(fSimpleAuthUser); else if (strucmp(aElementName,"simpleauthpw")==0) expectString(fSimpleAuthPassword); else if (strucmp(aElementName,"maxsyncmlversion")==0) expectEnum(sizeof(fMaxSyncMLVersionSupported),&fMaxSyncMLVersionSupported,SyncMLVersionNames,numSyncMLVersions); else if (strucmp(aElementName,"minsyncmlversion")==0) expectEnum(sizeof(fMinSyncMLVersionSupported),&fMinSyncMLVersionSupported,SyncMLVersionNames,numSyncMLVersions); else if (strucmp(aElementName,"acceptserveralerted")==0) expectBool(fAcceptServerAlerted); else if (strucmp(aElementName,"updateclientinslowsync")==0) expectBool(fUpdateClientDuringSlowsync); else if (strucmp(aElementName,"updateserverinslowsync")==0) expectBool(fUpdateServerDuringSlowsync); else if (strucmp(aElementName,"completefromclientonly")==0) expectBool(fCompleteFromClientOnly); else if (strucmp(aElementName,"allowmessageretries")==0) expectBool(fAllowMessageRetries); else if (strucmp(aElementName,"multithread")==0) expectBool(fMultiThread); else if (strucmp(aElementName,"waitforstatusofinterrupted")==0) expectBool(fWaitForStatusOfInterrupted); else if (strucmp(aElementName,"deletinggoneok")==0) expectBool(fDeletingGoneOK); else if (strucmp(aElementName,"abortonallitemsfailed")==0) expectBool(fAbortOnAllItemsFailed); else if (strucmp(aElementName,"showctcapproperties")==0) expectBool(fShowCTCapProps); else if (strucmp(aElementName,"showtypesizeinctcap10")==0) expectBool(fShowTypeSzInCTCap10); else if (strucmp(aElementName,"syncmodeextensions")==0) expectBool(fSyncModeExtensions); else if (strucmp(aElementName,"autoenddateinclusive")==0) expectBool(fVCal10EnddatesSameDay); else if (strucmp(aElementName,"donotfoldcontent")==0) expectBool(fDoNotFoldContent); else if (strucmp(aElementName,"enumdefaultpropparams")==0) expectTristate(fEnumDefaultPropParams); // Tristate!!! else if (strucmp(aElementName,"usertimezone")==0) expectTimezone(fUserTimeContext); #ifdef SCRIPT_SUPPORT else if (strucmp(aElementName,"sessioninitscript")==0) expectScript(fSessionInitScript,aLine,NULL); else if (strucmp(aElementName,"sentitemstatusscript")==0) expectScript(fSentItemStatusScript,aLine,&ErrorFuncTable); else if (strucmp(aElementName,"receiveditemstatusscript")==0) expectScript(fReceivedItemStatusScript,aLine,&ErrorFuncTable); else if (strucmp(aElementName,"sessionfinishscript")==0) expectScript(fSessionFinishScript,aLine,NULL); else if (strucmp(aElementName,"customgethandlerscript")==0) expectScript(fCustomGetHandlerScript,aLine,&GetPutResultFuncTable); else if (strucmp(aElementName,"customgetputscript")==0) expectScript(fCustomGetPutScript,aLine,&GetPutResultFuncTable); else if (strucmp(aElementName,"customendputscript")==0) expectScript(fCustomEndPutScript,aLine,&GetPutResultFuncTable); else if (strucmp(aElementName,"customputresulthandlerscript")==0) expectScript(fCustomPutResultHandlerScript,aLine,&GetPutResultFuncTable); #endif #ifndef MINIMAL_CODE // logfile else if (strucmp(aElementName,"logfile")==0) expectMacroString(fLogFileName); else if (strucmp(aElementName,"logformat")==0) expectCString(fLogFileFormat); else if (strucmp(aElementName,"loglabels")==0) expectCString(fLogFileLabels); else if (strucmp(aElementName,"logenabled")==0) expectBool(fLogEnabled); else if (strucmp(aElementName,"debugchunkmaxsize")==0) expectUInt32(fDebugChunkMaxSize); #endif else if (strucmp(aElementName,"relyonearlymaps")==0) expectBool(fRelyOnEarlyMaps); // - local datastores else if (strucmp(aElementName,"datastore")==0) { // definition of a new datastore const char* nam = getAttr(aAttributes,"name"); if (!nam) { ReportError(true,"datastore missing 'name' attribute"); } else { // get subtype attribute (some versions can have // different datastore types in same agent) const char* subtype = getAttr(aAttributes,"type"); // create new named datastore TLocalDSConfig *datastorecfgP = newDatastoreConfig(nam,subtype,this); if (!datastorecfgP) ReportError(true,"datastore has unknown 'type' attribute"); else { // - save in list fDatastores.push_back(datastorecfgP); // - let element handle parsing expectChildParsing(*datastorecfgP); } } } #ifdef SUPERDATASTORES // - superdatastore else if (strucmp(aElementName,"superdatastore")==0) { // definition of a new datastore const char* nam = getAttr(aAttributes,"name"); if (!nam) { ReportError(true,"datastore missing 'name' attribute"); } else { // create new named datastore TLocalDSConfig *datastorecfgP = new TSuperDSConfig(nam,this); // - save in list fDatastores.push_back(datastorecfgP); // - let element handle parsing expectChildParsing(*datastorecfgP); } } #endif // - none known here else return inherited::localStartElement(aElementName,aAttributes,aLine); // ok return true; } // TSessionConfig::localStartElement #endif // resolve void TSessionConfig::localResolve(bool aLastPass) { // resolve if (aLastPass) { #ifndef NO_REMOTE_RULES // - resolve rules and parse OverrideDevInf TRemoteRulesList::iterator pos; for(pos=fRemoteRulesList.begin();pos!=fRemoteRulesList.end();pos++) { (*pos)->Resolve(aLastPass); if (!(*pos)->fOverrideDevInfXML.empty()) { // SMLTK expects full SyncML message string buffer = "" "1.2" "SyncML/1.2" "1" "1" "foo" "bar" "" "" "" "1" "1" "1" "" "application/vnd.syncml-devinf+xml" "" "" "" "./devinf12" "" "" ; buffer += (*pos)->fOverrideDevInfXML; buffer += "" "" "" "" ""; MemPtr_t xml = (unsigned char *)buffer.c_str(); XltDecoderPtr_t decoder = NULL; SmlSyncHdrPtr_t hdr = NULL; Ret_t ret = xltDecInit(SML_XML, xml + buffer.size(), &xml, &decoder, &hdr); if (ret != SML_ERR_OK) { fRootElementP->setError(true, "initializing scanner for DevInf failed"); } else { smlFreeProtoElement(hdr); SmlProtoElement_t element; VoidPtr_t content = NULL; ret = xltDecNext(decoder, xml + buffer.size(), &xml, &element, &content); if (ret != SML_ERR_OK) { fRootElementP->setError(true, "parsing of OverrideDevInf failed"); } else if (element != SML_PE_RESULTS || !((SmlResultsPtr_t)content)->itemList || !((SmlResultsPtr_t)content)->itemList->item || !((SmlResultsPtr_t)content)->itemList->item->data || ((SmlResultsPtr_t)content)->itemList->item->data->contentType != SML_PCDATA_EXTENSION || ((SmlResultsPtr_t)content)->itemList->item->data->extension != SML_EXT_DEVINF) { fRootElementP->setError(true, "parsing of DevInf returned unexpected result"); if (content) smlFreeProtoElement(content); } else { (*pos)->fOverrideDevInfP = (SmlDevInfDevInfPtr_t)((SmlResultsPtr_t)content)->itemList->item->data->content; (*pos)->fOverrideDevInfBufferP = content; } } if (decoder) xltDecTerminate(decoder); } } #endif TLocalDSList::iterator pos2; for(pos2=fDatastores.begin();pos2!=fDatastores.end();pos2++) (*pos2)->Resolve(aLastPass); #ifdef SCRIPT_SUPPORT TScriptContext *sccP = NULL; SYSYNC_TRY { // resolve all scripts in same context // - init scripts TScriptContext::resolveScript(getSyncAppBase(),fSessionInitScript,sccP,NULL); TScriptContext::resolveScript(getSyncAppBase(),fSentItemStatusScript,sccP,NULL); TScriptContext::resolveScript(getSyncAppBase(),fReceivedItemStatusScript,sccP,NULL); TScriptContext::resolveScript(getSyncAppBase(),fSessionFinishScript,sccP,NULL); TScriptContext::resolveScript(getSyncAppBase(),fCustomGetHandlerScript,sccP,NULL); TScriptContext::resolveScript(getSyncAppBase(),fCustomGetPutScript,sccP,NULL); TScriptContext::resolveScript(getSyncAppBase(),fCustomEndPutScript,sccP,NULL); TScriptContext::resolveScript(getSyncAppBase(),fCustomPutResultHandlerScript,sccP,NULL); // - forget this context if (sccP) delete sccP; } SYSYNC_CATCH (...) if (sccP) delete sccP; SYSYNC_RETHROW; SYSYNC_ENDCATCH #endif } // resolve inherited inherited::localResolve(aLastPass); } // TSessionConfig::localResolve // TSyncSession // ============ // constructor TSyncSession::TSyncSession( TSyncAppBase *aSyncAppBaseP, // the owning application base (dispatcher/client base) const char *aSessionID // a session ID ) : #ifdef SYDEBUG fSessionDebugLogs(0), #endif fTerminated(false), #ifdef SYDEBUG fSessionLogger(&fSessionZones), #endif fSyncAppBaseP(aSyncAppBaseP) // link to owning base (dispatcher/clienbase) { // Inherit globally defined time zones // Note: this must be done as very first step as all time output routines will use the // session zones fSessionZones = *(fSyncAppBaseP->getAppZones()); // now mark used to avoid early timeout (will be marked again at InternalResetSession()) SessionUsed(); fLastRequestStarted=getSessionLastUsed(); // set this in case we terminate before StartMessage() fSessionStarted=fLastRequestStarted; // this is also the start of the session // show creation DEBUGPRINTFX(DBG_OBJINST,("++++++++ TSyncSession created")); // assign session ID to have debug ID on correct channel fLocalSessionID.assign(aSessionID); DEBUGPRINTFX(DBG_EXOTIC,("TSyncSession::TSyncSession: Session ID assigned")); // init and start profiling MP_SHOWCURRENT(DBG_PROFILE,"TSyncSession::TSyncSession: TSyncSession created"); TP_INIT(fTPInfo); TP_START(fTPInfo,TP_general); DEBUGPRINTFX(DBG_EXOTIC,("TSyncSession::TSyncSession: Profiling initialized")); // set fields fEncoding = SML_UNDEF; fLocalAbortReason = true; // unless set otherwise fAbortReasonStatus = 0; fSessionIsBusy = false; // not busy by default fSmlWorkspaceID = 0; // no SyncML toolkit workspace ID yet fMaxRoomForData = getRootConfig()->fLocalMaxMsgSize; // rough init // other pointers #ifdef SCRIPT_SUPPORT fSessionScriptContextP = NULL; #endif fInterruptedCommandP = NULL; fIncompleteDataCommandP = NULL; #ifdef SYNCSTATUS_AT_SYNC_CLOSE fSyncCloseStatusCommandP=NULL; #endif fCmdIncoming=NULL; // we do not know anything about remote datastores yet fRemoteDevInfKnown=false; fRemoteDataStoresKnown=false; fRemoteDataTypesKnown=false; fRemoteDevInfLock=false; // we have not sent any devinf to the remote yet fRemoteGotDevinf=false; fRemoteMustSeeDevinf=false; fCustomGetPutSent=false; // assume normal, full-featured session. Profile config or session progress might set this flag later fLegacyMode = false; fLenientMode = false; //initialize the conditonal variables to keep valgrind happy fNeedAuth = true; fRemoteRequestedAuth = auth_none; #ifdef SYDEBUG // initialize session debug logging fSessionDebugLogs=getRootConfig()->fDebugConfig.fSessionDebugLogs; /// init from config @todo: get rid of this special session level flag, handle it all via session logger's fDebugEnabled / getDbgMask() fSessionLogger.setEnabled(fSessionDebugLogs); // init from session-level flag @todo: get rid of this special session level flag, handle it all via session logger's fDebugEnabled / getDbgMask() fSessionLogger.setMask(getRootConfig()->fDebugConfig.fDebug); // init from config fSessionLogger.setOptions(&(getRootConfig()->fDebugConfig.fSessionDbgLoggerOptions)); if (getRootConfig()->fDebugConfig.fLogSessionsToGlobal) { // pass session output to app global logger fSessionLogger.outputVia(getSyncAppBase()->getDbgLogger()); // show start of log PDEBUGPRINTFX(DBG_HOT,("--------- START of embedded log for session ID '%s' ---------", fLocalSessionID.c_str())); } else { // use separate output for session logs fSessionLogger.installOutput(getSyncAppBase()->newDbgOutputter(false)); // install the output object (and pass ownership!) fSessionLogger.setDebugPath(getRootConfig()->fDebugConfig.fDebugInfoPath.c_str()); // base path const string &name = getRootConfig()->fDebugConfig.fSessionDbgLoggerOptions.fBasename; fSessionLogger.appendToDebugPath(name.empty() ? TARGETID : name.c_str()); if (getRootConfig()->fDebugConfig.fSingleSessionLog) { getRootConfig()->fDebugConfig.fSessionDbgLoggerOptions.fAppend=true; // One single log - in this case, we MUST append to current log fSessionLogger.appendToDebugPath("_session"); // only single session log, always with the same name } else { if (getRootConfig()->fDebugConfig.fTimedSessionLogNames) { fSessionLogger.appendToDebugPath("_"); string t; TimestampToISO8601Str(t, getSystemNowAs(TCTX_UTC), TCTX_UTC, false, false); fSessionLogger.appendToDebugPath(t.c_str()); } fSessionLogger.appendToDebugPath("_s"); fSessionLogger.appendToDebugPath(fLocalSessionID.c_str()); } } fSessionLogger.DebugDefineMainThread(); // initialize session level dump flags fDumpCount=0; fIgnoreIncomingCommands=false; fOutgoingXMLInstance=NULL; fIncomingXMLInstance=NULL; fXMLtranslate=getRootConfig()->fDebugConfig.fXMLtranslate; // initialize from config fMsgDump=getRootConfig()->fDebugConfig.fMsgDump; // initialize from config #endif // reset session at creation DEBUGPRINTFX(DBG_EXOTIC,("TSyncSession::TSyncSession: calling InternalResetSession")); InternalResetSessionEx(false); DEBUGPRINTFX(DBG_EXOTIC,("TSyncSession::TSyncSession: InternalResetSession called")); // show starting #ifndef ENGINE_LIBRARY // - don't show it here in library case as Agent must be ready as well to distribute event correctly SESSION_PROGRESS_EVENT(this,pev_sessionstart,NULL,0,0,0); #endif #ifdef SYDEBUG #if defined(SYSYNC_SERVER) && defined(SYSYNC_CLIENT) #define CAN_BE_TEXT "Server+Client" #elif defined(SYSYNC_SERVER) #define CAN_BE_TEXT "Server" #else #define CAN_BE_TEXT "Client" #endif if (PDEBUGTEST(DBG_HOT)) { // Show Session Start PDEBUGPRINTFX(DBG_HOT,( "==== %s Session started with SyncML (%s) Engine Version %d.%d.%d.%d", IS_SERVER ? "Server" : "Client", CAN_BE_TEXT, SYSYNC_VERSION_MAJOR, SYSYNC_VERSION_MINOR, SYSYNC_SUBVERSION, SYSYNC_BUILDNUMBER )); // show Product ID string PDEBUGPRINTFX(DBG_HOT,( "---- Hardcoded Product name: " CUST_SYNC_MODEL )); PDEBUGPRINTFX(DBG_HOT,( "---- Configured Model/Manufacturer: %s / %s", getSyncAppBase()->getModel().c_str(), getSyncAppBase()->getManufacturer().c_str() )); // show platform we're on string devid; getSyncAppBase()->getMyDeviceID(devid); PDEBUGPRINTFX(DBG_HOT,( "---- Running on " SYSYNC_PLATFORM_NAME ", URI/deviceID='%s'", devid.c_str() )); // show process and thread ID of the main session thread #ifdef MULTI_THREAD_SUPPORT PDEBUGPRINTFX(DBG_HOT,( "---- Process ID = %lu, Thread ID = %lu", myProcessID(), myThreadID() )); #endif // show platform details string dname,vers; // - as determined by engine itself getPlatformString(pfs_device_name,dname); getPlatformString(pfs_platformvers,vers); PDEBUGPRINTFX(DBG_HOT,( "---- Platform Hardware Name/Version = '%s', Firmware/OS Version = '%s'", dname.c_str(), vers.c_str() )); // - as configured PDEBUGPRINTFX(DBG_HOT,( "---- Configured Hardware Version = '%s', Firmware Version = '%s'", getSyncAppBase()->getHardwareVersion().c_str(), getSyncAppBase()->getFirmwareVersion().c_str() )); // show time zone infos lineartime_t tim; string z,ts; timecontext_t tctx; sInt16 offs; // - System local time and zone tctx = getRootConfig()->fSystemTimeContext; TzResolveMetaContext(tctx, getSessionZones()); // make non-meta TimeZoneContextToName(tctx, z, getSessionZones()); tim = getSystemNowAs(tctx); StringObjTimestamp(ts,tim); TzResolveToOffset(tctx, offs, tim, false, getSessionZones()); PDEBUGPRINTFX(DBG_HOT,( "---- System local time : %s (time zone '%s', offset %hd:%02hd hours east of UTC)", ts.c_str(),z.c_str(), (sInt16)(offs / MinsPerHour), (sInt16)abs(offs % MinsPerHour) )); PDEBUGPRINTFX(DBG_EXOTIC,(" Offset in Minutes east of UTC: %hd",offs)); // - System time in UTC tim = getSystemNowAs(TCTX_UTC); StringObjTimestamp(ts,tim); PDEBUGPRINTFX(DBG_HOT,("---- System time in UTC : %s",ts.c_str())); // - make a winter and a summer test if (PDEBUGTEST(DBG_EXOTIC)) { sInt16 y,m,d; lineartime2date(tim,&y,&m,&d); d=1;m=2; // February 1st tim=date2lineartime(y,m,d); TzResolveToOffset(TCTX_SYSTEM, offs, tim, true, getSessionZones()); PDEBUGPRINTFX(DBG_EXOTIC,( "---- System time zone offset per %04hd-02-01 = %hd:%02hd (=%hd mins)", y, (sInt16)(offs / MinsPerHour), (sInt16)abs(offs % MinsPerHour), offs )); d=1;m=8; // August 1st tim=date2lineartime(y,m,d); TzResolveToOffset(TCTX_SYSTEM, offs, tim, true, getSessionZones()); PDEBUGPRINTFX(DBG_EXOTIC,( "---- System time zone offset per %04hd-08-01 = %hd:%02hd (=%hd mins)", y, (sInt16)(offs / MinsPerHour), (sInt16)abs(offs % MinsPerHour), offs )); } } #endif DebugShowCfgInfo(); } // TSyncSession::TSyncSession // destructor TSyncSession::~TSyncSession() { // remove user data pointer because session does not exist any longer getSyncAppBase()->setSmlInstanceUserData(fSmlWorkspaceID,NULL); // make sure it is terminated (but normally it is already terminated here) TerminateSession(); // debug DEBUGPRINTFX(DBG_OBJINST,("-------- TSyncSession almost destroyed (except implicit member destruction)")); #ifdef SYDEBUG if (getRootConfig()->fDebugConfig.fLogSessionsToGlobal) { // show end of embedded log PDEBUGPRINTFX(DBG_HOT,("--------- END of embedded log for session ID '%s' ---------", fLocalSessionID.c_str())); } fSessionLogger.DebugThreadOutputDone(); #endif } // TSyncSession::~TSyncSession /// @brief terminate a session. /// @Note: Termination is final - session cannot be restarted by RestartSession() after // calling this routine void TSyncSession::TerminateSession(void) { if (!fTerminated) { // save type of ending (before fAborted gets reset in InternalResetSession()) bool normalend = !fAborted; bool allsuccess = isAllSuccess(); // do this class' reset stuff DEBUGPRINTFX(DBG_EXOTIC,("TSyncSession::TerminateSession: calling InternalResetSession")); InternalResetSessionEx(true); DEBUGPRINTFX(DBG_EXOTIC,("TSyncSession::TerminateSession: InternalResetSession called")); #ifdef SCRIPT_SUPPORT // remove the session script context if (fSessionScriptContextP) { delete fSessionScriptContextP; fSessionScriptContextP = NULL; } #endif // remove all local datastores TLocalDataStorePContainer::iterator pos1; int n=fLocalDataStores.size(); PDEBUGPRINTFX(DBG_EXOTIC,("Deleting %d datastores",n)); for (pos1=fLocalDataStores.begin(); pos1!=fLocalDataStores.end(); ++pos1) { delete *pos1; } fLocalDataStores.clear(); // clear list // remove all local itemtypes TSyncItemTypePContainer::iterator pos2; for (pos2=fLocalItemTypes.begin(); pos2!=fLocalItemTypes.end(); ++pos2) { delete *pos2; } fLocalItemTypes.clear(); // clear list #ifdef SYDEBUG // save half-begun XML translations XMLTranslationOutgoingEnd(); XMLTranslationIncomingEnd(); #endif // stop and show profiling info TP_STOP(fTPInfo); #ifdef TIME_PROFILING if (getDbgMask() & DBG_PROFILE) { sInt16 i; uInt32 sy,us; PDEBUGPRINTFX(DBG_PROFILE,("Session CPU usage statistics: (system/user/total)")); // sections for (i=0; iannounceAgentDestruction(); } } // TSyncSession::announceDestruction // - terminate all datastores void TSyncSession::TerminateDatastores(localstatus aAbortStatusCode) { // terminate sync with all datastores TLocalDataStorePContainer::iterator pos; for (pos=fLocalDataStores.begin(); pos!=fLocalDataStores.end(); ++pos) { // terminate (*pos)->engTerminateDatastore(aAbortStatusCode); } } // TSyncSession::TerminateDatastores // - resets session and removes all datastores (local and remote) void TSyncSession::ResetAndRemoveDatastores(void) { // Must reset session before ResetSession(); // remove all local datastores TLocalDataStorePContainer::iterator pos; for (pos=fLocalDataStores.begin(); pos!=fLocalDataStores.end(); ++pos) { // now actually delete them TLocalEngineDS *dsP = (*pos); if (dsP) { (*pos) = NULL; // to avoid double deletes delete dsP; } } fLocalDataStores.clear(); // remove pointers } // TSyncSession::ResetAndRemoveDatastores // reset session to inital state (new) // - this is called at creation and destruction but can be called // also when an existing session needs to be restarted. // - InternalResetSession() must be proof for being called more than // once in a row. // - InternalResetSession() must also be callable from destructor // (care not to call other objects which will refer to the already // half-destructed session!) void TSyncSession::InternalResetSessionEx(bool terminationCall) { #ifdef SCRIPT_SUPPORT // call session termination script (ONCE!) if (terminationCall && !fTerminated) { TScriptContext::execute( fSessionScriptContextP, getSessionConfig()->fSessionFinishScript, NULL, // context's function table NULL // datastore pointer needed for context ); } #endif // reset sync and datastores // - version not known in advance fSyncMLVersion=syncml_vers_unknown; // - immediately abort SYNC command in progress fLocalSyncDatastoreP = NULL; #ifndef NO_REMOTE_RULES // - no remote rules applied fActiveRemoteRules.clear(); #endif // - set defaults for >=SyncML 1.1 features fRemoteWantsNOC = false; // no, unless requested fRemoteCanHandleUTC = false; // assume remote can not handle UTC time (note that for SyncML 1.0 this will be set to true later) fRemoteSupportsLargeObjects = false; // no large object support by default // - default options fTreatRemoteTimeAsLocal = false; // do not ignore time zone information from remote fTreatRemoteTimeAsUTC = false; // do not ignore time zone information from remote fIgnoreDevInfMaxSize = false; // do not ignore specification in CTCap fIgnoreCTCap = false; // do not ignore CTCap fDSPathInDevInf = true; // newer Nokias need this, as they expect the same path in devInf as they sent in alert fDSCgiInDevInf = true; // newer Nokias need this, as they expect the same path AND CGI in devInf as they sent in alert fReadOnly = false; // always disabled unless set by SessionLogin() // - init user time zone from setting. May be modified later using SETUSERTIMEZONE() fUserTimeContext = getSessionConfig()->fUserTimeContext; #ifdef SYDEBUG fSessionLogger.setEnabled(getRootConfig()->fDebugConfig.fSessionDebugLogs); // get default value #endif #ifndef MINIMAL_CODE fLogEnabled = getSessionConfig()->fLogEnabled; #endif #ifdef SCRIPT_SUPPORT // retain session variables if InternalResetSessionEx() is called more than once in the same session // (which is normal procedure in clients, where SelectProfile calls ResetSession) // Note: fSessionScriptContextP will be deleted in the destructor if (!fSessionScriptContextP) { if (!terminationCall && !fTerminated) { // prepare session-level scripts TScriptContext::rebuildContext(getSyncAppBase(),getSessionConfig()->fSessionInitScript,fSessionScriptContextP,this); TScriptContext::rebuildContext(getSyncAppBase(),getSessionConfig()->fSentItemStatusScript,fSessionScriptContextP,this); TScriptContext::rebuildContext(getSyncAppBase(),getSessionConfig()->fReceivedItemStatusScript,fSessionScriptContextP,this); TScriptContext::rebuildContext(getSyncAppBase(),getSessionConfig()->fSessionFinishScript,fSessionScriptContextP,this); TScriptContext::rebuildContext(getSyncAppBase(),getSessionConfig()->fCustomGetHandlerScript,fSessionScriptContextP,this); TScriptContext::rebuildContext(getSyncAppBase(),getSessionConfig()->fCustomGetPutScript,fSessionScriptContextP,this); TScriptContext::rebuildContext(getSyncAppBase(),getSessionConfig()->fCustomEndPutScript,fSessionScriptContextP,this); TScriptContext::rebuildContext(getSyncAppBase(),getSessionConfig()->fCustomPutResultHandlerScript,fSessionScriptContextP,this,true); // now instantiate vars } } #endif // - remove all remote datastores TRemoteDataStorePContainer::iterator pos1; for (pos1=fRemoteDataStores.begin(); pos1!=fRemoteDataStores.end(); ++pos1) { delete *pos1; } fRemoteDataStores.clear(); // clear list // - remove all remote itemtypes TSyncItemTypePContainer::iterator pos2; for (pos2=fRemoteItemTypes.begin(); pos2!=fRemoteItemTypes.end(); ++pos2) { delete *pos2; } fRemoteItemTypes.clear(); // clear list // reset basics SYSYNC_TRY { // empty command queues TSmlCommandPContainer::iterator pos; // - commands waiting for status for (pos=fStatusWaitCommands.begin(); pos!=fStatusWaitCommands.end(); ++pos) { #ifdef SYDEBUG TSmlCommand *cmdP = *pos; // show that command was not answered PDEBUGPRINTFX(DBG_PROTO,("Never received status for &html;&html;command '%s'&html;&html;, (outgoing MsgID=%ld, CmdID=%ld)", (long)cmdP->getMsgID(), (long)cmdP->getCmdID(), (long)cmdP->getMsgID(), (long)cmdP->getCmdID(), cmdP->getName(), (long)cmdP->getMsgID(), (long)cmdP->getCmdID() )); #endif // delete, if this is not the interrupted command. // Note: only the interrupted command can also be in the status queue. // Other queues are exclusive owners of their commands. if (*pos != fInterruptedCommandP) delete *pos; else DEBUGPRINTF(("- prevented deleting because command is interrupted")); } fStatusWaitCommands.clear(); // clear list // - commands waiting for outgoing message to begin forgetHeaderWaitCommands(); // - commands to be issued only after all commands in this message have // been processed and answered by a status for (pos=fEndOfMessageCommands.begin(); pos!=fEndOfMessageCommands.end(); ++pos) { // show that command was not sent DEBUGPRINTF(("Never sent end-of-message command '%s', (outgoing MsgID=%ld, CmdID=%ld)", (*pos)->getName(), (long)(*pos)->getMsgID(), (long)(*pos)->getCmdID() )); // delete delete *pos; } fEndOfMessageCommands.clear(); // clear list // - commands to be sent in next message for (pos=fNextMessageCommands.begin(); pos!=fNextMessageCommands.end(); ++pos) { // show that command was not sent DEBUGPRINTF(("Never sent next-message command '%s', (outgoing MsgID=%ld, CmdID=%ld)", (*pos)->getName(), (long)(*pos)->getMsgID(), (long)(*pos)->getCmdID() )); // delete delete *pos; } fNextMessageCommands.clear(); // clear list // - commands to be sent in next package for (pos=fNextPackageCommands.begin(); pos!=fNextPackageCommands.end(); ++pos) { // show that command was not sent DEBUGPRINTF(("Never sent next-package command '%s', (outgoing MsgID=%ld, CmdID=%ld)", (*pos)->getName(), (long)(*pos)->getMsgID(), (long)(*pos)->getCmdID() )); // delete delete *pos; } fNextPackageCommands.clear(); // clear list // - interrupted command if (fInterruptedCommandP) { // show that command was not sent DEBUGPRINTF(("Never finished interrupted command '%s', (outgoing MsgID=%ld, CmdID=%ld)", fInterruptedCommandP->getName(), (long)fInterruptedCommandP->getMsgID(), (long)fInterruptedCommandP->getCmdID() )); delete fInterruptedCommandP; fInterruptedCommandP=NULL; } // - commands to be executed again at beginning of next message fDelayedExecSyncEnds=0; for (pos=fDelayedExecutionCommands.begin(); pos!=fDelayedExecutionCommands.end(); ++pos) { // show that command was not sent DEBUGPRINTF(("Never finished executing command '%s', (incoming MsgID=%ld, CmdID=%ld)", (*pos)->getName(), (long)(*pos)->getMsgID(), (long)(*pos)->getCmdID() )); // delete delete *pos; } fDelayedExecutionCommands.clear(); // clear list #ifdef SYNCSTATUS_AT_SYNC_CLOSE // make sure sync status is disposed if (fSyncCloseStatusCommandP) delete fSyncCloseStatusCommandP; fSyncCloseStatusCommandP=NULL; #endif // remove incomplete data command if (fIncompleteDataCommandP) delete fIncompleteDataCommandP; fIncompleteDataCommandP=NULL; } SYSYNC_CATCH (exception &e) #ifdef SYDEBUG DEBUGPRINTFX(DBG_ERROR,( "WARNING: Exception during InternalResetSession(): %s", e.what() )); #endif SYSYNC_ENDCATCH SYSYNC_CATCH (...) #ifdef SYDEBUG DEBUGPRINTFX(DBG_ERROR,( "WARNING: Unknown Exception during InternalResetSession()" )); #endif SYSYNC_ENDCATCH // remember time of creation or last reset SessionUsed(); // reset session status fIncomingState=psta_idle; // no incoming package status yet fCmdIncomingState=psta_idle; fCmdIncoming=NULL; fOutgoingState=psta_idle; // no outgoing package status yet fRestarting=false; fNextMessageRequests=0; // no pending next message requests fFakeFinalFlag=false; // special flag to work around broken resume implementations fNewOutgoingPackage=true; // first message will be first in outgoing package fSessionAuthorized=false; // session not permanently authorized fMessageAuthorized=false; // message not authorized either fAuthFailures=0; // no failed attempts by remote so far fAuthRetries=0; // no failed attempts by myself so far fIncomingMsgID=0; // expected session to start with MsgID=1, so must be 0 now as it will be incremented at StartMessage() fOutgoingMsgID=0; // starting answers with MsgID=1, so must be 0 as it will be incremented before sending a new message fAborted=false; // not yet aborted fSuspended=false; // not being suspended yet fSuspendAlertSent=false; // no suspend alert sent so far fFailedDatastores=0; // none failed fErrorItemDatastores=0; // none generated or detected error items fInProgress=false; // not yet in progress fOutgoingStarted=false; // no outgoing message started yet fSequenceNesting=0; // no sequence command open fMaxOutgoingMsgSize=0; // no limit for outgoing messages so far fMaxOutgoingObjSize=0; // SyncML 1.1: no limit for outgoing objects so far fOutgoingMessageFull=false; // limit not yet reached // init special remote-dependent behaviour fLimitedRemoteFieldLengths=false; // assume remote has not generally limited field lenghts fDontSendEmptyProperties=false; // normally, empty properties will be sent fDoQuote8BitContent=false; fNoReplaceInSlowsync=false; fTreatRemoteTimeAsLocal=false; fTreatRemoteTimeAsUTC=false; fIgnoreDevInfMaxSize=false; fTreatCopyAsAdd=false; fStrictExecOrdering=true; // SyncML standard requires strict ordering (of statuses, but this implies execution of commands, too) fDefaultOutCharset=chs_utf8; // SyncML content is usually UTF-8 fDefaultInCharset=chs_utf8; // SyncML content is usually UTF-8 // defaults for possibly remote-dependent behaviour fCompleteFromClientOnly=getSessionConfig()->fCompleteFromClientOnly; // conform to standard by default fRequestMaxTime=getSessionConfig()->fRequestMaxTime; fRequestMinTime=getSessionConfig()->fRequestMinTime; fUpdateClientDuringSlowsync=getSessionConfig()->fUpdateClientDuringSlowsync; fUpdateServerDuringSlowsync=getSessionConfig()->fUpdateServerDuringSlowsync; fAllowMessageRetries=getSessionConfig()->fAllowMessageRetries; fShowCTCapProps=getSessionConfig()->fShowCTCapProps; fShowTypeSzInCTCap10=getSessionConfig()->fShowTypeSzInCTCap10; fVCal10EnddatesSameDay=getSessionConfig()->fVCal10EnddatesSameDay; fDoNotFoldContent=getSessionConfig()->fDoNotFoldContent; // tristates!! fEnumDefaultPropParams=getSessionConfig()->fEnumDefaultPropParams; #ifdef SCRIPT_SUPPORT // call session init script if (!terminationCall && !fTerminated) { TScriptContext::execute( fSessionScriptContextP, getSessionConfig()->fSessionInitScript, NULL, // context's function table NULL // datastore pointer needed for context ); } #endif } // TSyncSession::InternalResetSessionEx #ifdef PROGRESS_EVENTS // event generator bool TSyncSession::NotifySessionProgressEvent( TProgressEventType aEventType, TLocalDSConfig *aDatastoreID, sInt32 aExtra1, sInt32 aExtra2, sInt32 aExtra3 ) { #ifdef ENGINE_LIBRARY // library build, session level events get queued and dispatched via sessionstep // - handle some events specially if (aEventType == pev_nop) return true; // just continue else { // - prepare info record TEngineProgressInfo info; info.eventtype = (uInt16)(aEventType); // - datastore ID, if any if (aDatastoreID != NULL) info.targetID = (sInt32)(aDatastoreID->fLocalDBTypeID); else info.targetID = 0; // - extras info.extra1 = aExtra1; info.extra2 = aExtra2; info.extra3 = aExtra3; // - handle it return HandleSessionProgressEvent(info); } #else // old monolithic build, pass to appbase which dispatches them to the app via callback return getSyncAppBase()->NotifyAppProgressEvent(aEventType,aDatastoreID,aExtra1,aExtra2,aExtra3); #endif } // TSyncAppBase::NotifySessionProgressEvent #endif // PROGRESS_EVENTS // get root config pointer // NOTE: we have moved this here because Palm linker // would have problems accessing it as syncsession.cpp is // large enough to have EndMessage >32k away from the // original position of this routine. TRootConfig *TSyncSession::getRootConfig(void) { return fSyncAppBaseP->getRootConfig(); } // TSyncSession::getRootConfig // forget commands waiting to be sent when header is generated void TSyncSession::forgetHeaderWaitCommands(void) { // empty command queues TSmlCommandPContainer::iterator pos; // - commands waiting for outgoing message to begin for (pos=fHeaderWaitCommands.begin(); pos!=fHeaderWaitCommands.end(); ++pos) { #if SYDEBUG>1 TSmlCommand *cmdP = *pos; // show that command was not answered DEBUGPRINTF(("Never sent command '%s', (outgoing MsgID=%ld, CmdID=%ld) because outgoing message never started", cmdP->getName(), (long)cmdP->getMsgID(), (long)cmdP->getCmdID() )); #endif // delete delete *pos; } fHeaderWaitCommands.clear(); // clear list } // TSyncSession::forgetHeaderWaitCommands // abort processing commands in this message void TSyncSession::AbortCommandProcessing(TSyError aStatusCode) { if (!fIgnoreIncomingCommands) { fIgnoreIncomingCommands=true; // do not process further commands fStatusCodeForIgnored=aStatusCode; // save status code PDEBUGPRINTFX(DBG_HOT,( "--------------- Ignoring all commands in this message (after %ld sec. request processing, %ld sec. total) with Status %hd (0=none) from here on", (long)((getSystemNowAs(TCTX_UTC)-getLastRequestStarted()) / (lineartime_t)secondToLinearTimeFactor), (long)((getSystemNowAs(TCTX_UTC)-getSessionStarted()) / (lineartime_t)secondToLinearTimeFactor), fStatusCodeForIgnored )); } } // TSyncSession::AbortCommandProcessing // suspend session (that is: flag abortion) void TSyncSession::SuspendSession(TSyError aReason) { // first check for suspend if (fSyncMLVersion>=syncml_vers_1_2) { // try suspend, only possible if not already suspended or aborted if (!fSuspended && !fAborted) { fSuspended=true; // trigger suspend fAbortReasonStatus = aReason; fLocalAbortReason = true; AbortCommandProcessing(514); // abort command processing, all subsequent commands will be ignored with "cancelled" status PDEBUGPRINTFX(DBG_ERROR,( "WARNING: Session locally flagged for suspend, reason=%hd", aReason )); CONSOLEPRINTF(( "Session will be suspended due to local error code %hd\n", aReason )); } } else { // We can't suspend, we need to abort AbortSession(500,true,aReason); } } // TSyncSession::SuspendSession void TSyncSession::MarkSuspendAlertSent(bool aSent) { fSuspendAlertSent = aSent; } // abort session (that is: flag abortion) void TSyncSession::AbortSession(TSyError aStatusCode, bool aLocalProblem, TSyError aReason) { // Catch the case that some inner routine, e.g. a plugin, detects a user suspend. It can // return LOCERR_USERSUSPEND then and will cause the engine instead of aborting. if (aStatusCode==LOCERR_USERSUSPEND) { SuspendSession(LOCERR_USERSUSPEND); return; } // make sure session gets aborted // BUT: do NOT reset yet. Reset would incorrectly abort message answering if (!fAborted && !fTerminated) { fAborted=true; // session aborted fAbortReasonStatus = aReason ? aReason : aStatusCode; fLocalAbortReason = aLocalProblem; fInProgress=false; // not in progress any more (will be deleted after end of request) PDEBUGBLOCKFMT(("SessionAbort","Aborting Session", "Status=%hd|ProblemSource=%s", fAbortReasonStatus, fLocalAbortReason ? "LOCAL" : "REMOTE" )); PDEBUGPRINTFX(DBG_ERROR,( "WARNING: Aborting Session with Reason Status %hd (%s problem) ***", fAbortReasonStatus, fLocalAbortReason ? "LOCAL" : "REMOTE" )); // In SyncML 1.1, we have a special status code to show that commands are not // executed any more due to cancellation of the session if (fSyncMLVersion>=syncml_vers_1_1) aStatusCode=514; // cancelled, command not completed AbortCommandProcessing(aStatusCode); // let all local datastores know TLocalDataStorePContainer::iterator pos; for (pos=fLocalDataStores.begin(); pos!=fLocalDataStores.end(); ++pos) { (*pos)->engAbortDataStoreSync(fAbortReasonStatus, fLocalAbortReason); } CONSOLEPRINTF(( "Session aborted because of %s SyncML error code %hd\n", fLocalAbortReason ? "LOCAL" : "REMOTE", fAbortReasonStatus )); SESSION_PROGRESS_EVENT( this, pev_sessionend, NULL, getAbortReasonStatus(), 0,0 ); PDEBUGENDBLOCK("SessionAbort"); } } // TSyncSession::AbortSession // returns true if session was a complete success bool TSyncSession::isAllSuccess(void) { return fFailedDatastores==0 && fErrorItemDatastores==0; } // TSyncSession::isAllSuccess // let session know that datastore has failed void TSyncSession::DatastoreFailed(TSyError aStatusCode, bool aLocalProblem) { fFailedDatastores++; // %%% note that this is not perfect for server, as inactive datastores are possible if (fFailedDatastores>=fLocalDataStores.size()) { // all have failed by now, abort the session AbortSession(aStatusCode, aLocalProblem, aStatusCode); } } // TSyncSession::DatastoreFailed // set SyncML toolkit workspace ID void TSyncSession::setSmlWorkspaceID(InstanceID_t aSmlWorkspaceID) { fSmlWorkspaceID=aSmlWorkspaceID; } // TSyncSession::setSmlWorkspaceID // show some information about the config void TSyncSession::DebugShowCfgInfo(void) { #ifdef SYDEBUG string t; StringObjTimestamp(t,getRootConfig()->fConfigDate); // now write settings to log PDEBUGPRINTFX(DBG_HOT,( "==== Config file='%s', Last Change=%s", getSyncAppBase()->fConfigFilePath.c_str(), t.c_str() )); #ifndef HARDCODED_CONFIG PDEBUGPRINTFX(DBG_HOT,( "==== Config ID string='%s'", getRootConfig()->fConfigIDString.c_str() )); #endif #endif } // TSyncSession::DebugShowCfgInfo #ifndef MINIMAL_CODE #include // write to sync log file void TSyncSession::WriteLogLine(const char *aLogline) { if (getSessionConfig()->fLogFileName.empty()) return; // do not write without a path // open for append FILE * logfile=fopen(getSessionConfig()->fLogFileName.c_str(),"a"); if (!logfile) { PDEBUGPRINTFX(DBG_ERROR,("**** Cannot write to logfile '%s' (errno=%ld)",getSessionConfig()->fLogFileName.c_str(),(long)errno)); return; // cannot write } // check if we need to write labels first if (!getSessionConfig()->fLogFileLabels.empty()) { // check file size if (ftell(logfile)==0) { // we are at the beginning, print labels first fputs(getSessionConfig()->fLogFileLabels.c_str(),logfile); } } // now write log line fputs(aLogline,logfile); // close file fclose(logfile); } // TSyncSession::WriteLogLine #endif // queue a SyncBody context command for issuing after incoming message has ended void TSyncSession::queueForIssueRoot( TSmlCommand * &aSyncCommandP // the command ) { fEndOfMessageCommands.push_back(aSyncCommandP); aSyncCommandP=NULL; } // TSyncSession::queueForIssueRoot // queue a SyncBody context command for issuing after incoming message has ended void TSyncSession::issueNotBeforePackage( TPackageStates aPackageState, TSmlCommand *aSyncCommandP // the command ) { if (fOutgoingState>=aPackageState) { issueRootPtr(aSyncCommandP); } else { PDEBUGPRINTFX(DBG_SESSION,("%s queued for next package",aSyncCommandP->getName())); fNextPackageCommands.push_back(aSyncCommandP); } } // TSyncSession::issueNotBeforePackage // issue a command in SyncBody context (uses session's interruptedCommand/NextMessageCommands) bool TSyncSession::issueRootPtr( TSmlCommand *aSyncCommandP, // the command bool aNoResp, // set if no response is wanted bool aIsOKSyncHdrStatus // set if this is sync hdr status ) { // now issue return issuePtr(aSyncCommandP,fNextMessageCommands,fInterruptedCommandP,aNoResp,aIsOKSyncHdrStatus); } // TSyncSession::issueRootPtr // issue object passed as pointer (rather than pointer reference) // normally used internally only bool TSyncSession::issuePtr( TSmlCommand *aSyncCommandP, // the command TSmlCommandPContainer &aNextMessageCommands, // the list to add the command if cannot be issued in this message TSmlCommand * &aInterruptedCommandP, // where to store command ptr if it was interrupted bool aNoResp, // set if no response is wanted bool aIsOKSyncHdrStatus // set if this is sync hdr status ) { bool issued=true; // NULL issue is successful issue if (aSyncCommandP) { PDEBUGBLOCKFMT(("issue","issuing command", "Cmd=%s", aSyncCommandP->getName() )); if (fCmdIncoming && aSyncCommandP->getCmdType()==scmd_status) { // Queue instead of sending immediately, see TSyncSession::process(). fCmdIncoming->queueStatusCmd(aSyncCommandP); if (fCmdIncoming->getCmdType()==scmd_sync) { TSyncCommand *syncCommandP=static_cast(fCmdIncoming); syncCommandP->setLocalDatastore(fLocalSyncDatastoreP); PDEBUGPRINTFX(DBG_SESSION,("issuePtr: store fLocalSyncDatastoreP in sync command")); } DEBUGPRINTFX(DBG_PROTO,("%s: queue reply to %s because of pending commands", aSyncCommandP->getName(), fCmdIncoming->getName() )); goto endissue; } SYSYNC_TRY { // check for not-to-be-sent commands if (aSyncCommandP->getDontSend()) { // command must not be sent, just silently discarded DEBUGPRINTFX(DBG_PROTO,("%s: not sent because fDontSend is set -> just delete", aSyncCommandP->getName() )); delete aSyncCommandP; issued=true; // counts as issued goto endissue; } // check if this commmand now triggers need to answer if (!aIsOKSyncHdrStatus) { fNeedToAnswer=true; } // check if outgoing message has already started. If not, queue command // for sending when message has started (client case, when status for // header must be evaluated before next header can be generated) if (!fOutgoingStarted) { fHeaderWaitCommands.push_back(aSyncCommandP); PDEBUGPRINTFX(DBG_SESSION+DBG_EXOTIC,( "Outgoing message header not yet generated, command '%s' queued", aSyncCommandP->getName() )); issued=true; // act as if issued goto endissue; } // check if this is a continuation of a suspended chunked item transfer // if yes, substitute the full data we currently have in the item (from // the database) with the buffered left-overs from the previous // session. aSyncCommandP->checkChunkContinuation(); // check if message size restrictions or local buffer size // will prevent command from being sent now TSmlCommand *splitCmdP = NULL; if (!fOutgoingMessageFull) { #ifndef USE_SML_EVALUATION #error "This Implementation does not work any more without USE_SML_EVALUATION" #endif // check if enough room to send data sInt32 freeaftersend=aSyncCommandP->evalIssue( peekNextOutgoingCmdID(), // this will be the ID getOutgoingMsgID(), aNoResp ); // - if room for new commands is smaller than expected message size sInt32 maxfree=getSmlWorkspaceFreeBytes(); sInt32 sizetoend=maxfree-freeaftersend; #ifdef SYDEBUG PDEBUGPRINTFX(DBG_SESSION+DBG_EXOTIC,( "Command '%s': is %hd-th counted cmd, cmdsize(+tags needed to end msg)=%ld, available=%ld (maxfree=%ld, freeaftersend=%ld, notUsableBufferBytes()=%ld)", aSyncCommandP->getName(), fOutgoingCmds, (long)sizetoend, // size of command (+tags needed to end msg) (long)(maxfree-getNotUsableBufferBytes()), (long)maxfree, (long)freeaftersend, (long)getNotUsableBufferBytes() )); #endif #ifndef MINIMAL_CODE // - check for artifical debug chunking if (getSessionConfig()->fDebugChunkMaxSize && aSyncCommandP->isSyncOp()) { // always chunk commands over the configured size uInt32 cmdSize=getSmlWorkspaceFreeBytes()-freeaftersend; if (cmdSize>getSessionConfig()->fDebugChunkMaxSize) { // simulate a different free after send to force chunking sInt32 nfas=getNotUsableBufferBytes()-(cmdSize-getSessionConfig()->fDebugChunkMaxSize)+100; if (nfas=syncml_vers_1_1) { // we can use moredata mechanism, try if it works for this command if (fOutgoingCmds>0 && sizetoend < getMaxOutgoingSize()/4) { // this is a small command, and not in best position // - command will most likely fit into next message, so end this message now fOutgoingMessageFull=true; sendable=true; // kind of "sendable" - as are confident it will be sendable in next message PDEBUGPRINTFX(DBG_PROTO,("command is less than 1/4 of maxmsgsize -> will likely fit into next message, so queue it")); } else { // - try to split // reserve about 200 bytes for Meta Size splitCmdP = aSyncCommandP->splitCommand(getNotUsableBufferBytes()-freeaftersend+200); if (splitCmdP) { sendable=true; } else if (aSyncCommandP->canSplit()) { // command is basically splittable, but not right now - end message now and try in next fOutgoingMessageFull=true; sendable=true; // kind of "sendable" - just not now, but certainly later } } } // - second choice: try to shrink (mainly devInf) if (!sendable) { // gets sendable if we can shrink it to given size sendable = aSyncCommandP->shrinkCommand(getNotUsableBufferBytes()-freeaftersend); PDEBUGPRINTFX(DBG_PROTO+DBG_HOT,( "shrinkCommand could %sshrink command by %ld bytes or more (which is needed to send it now)", sendable ? "" : "NOT ", (long)(getNotUsableBufferBytes()-freeaftersend) )); } // - third choice: send it later as first command if (!sendable) { if (fOutgoingCmds>0 && sizetoend queue and hope we'll be able to send it as only command in subsequent message")); // - command will possibly fit into next message, so end this message now fOutgoingMessageFull=true; sendable=true; // kind of "sendable" - as we are hoping it will be sendable later } else { // this WAS already the best possible position to send or really too big // - we are in trouble, this command is unsendable PDEBUGPRINTFX(DBG_ERROR,("%s: Warning: command is too big to be sent at all -> discarded/mark for resend", aSyncCommandP->getName() )); // - try again in next session (data size might be smaller then, or remote might allow larger data at some time) aSyncCommandP->markForResend(); // - just discard it for now delete aSyncCommandP; issued=false; // not issued (but also not queued again). goto endissue; } } // check if command was made sendable by splitting off a part if (splitCmdP) { // - queue command containing remaining data for issuing in next message aNextMessageCommands.push_back(splitCmdP); PDEBUGPRINTFX(DBG_PROTO+DBG_HOT,("Split command, sending a chunk, queued rest of data for sending in next message")); // - Note: fOutgoingMessageFull is not set here (as first part of cmd must be sent first) // but will be set below after issuing first part (due to splitCmdP!=NULL) } } // command too large to be sent now } // Queue if message is full, or if we have a interrupted command and // command to be sent is something other than status. This will make sure // incoming commands get their statuses before message is filled with other // explicitly generated commands if (fOutgoingMessageFull || (aInterruptedCommandP && aSyncCommandP->getCmdType()!=scmd_status)) { // - queue for issuing in next message aNextMessageCommands.push_back(aSyncCommandP); PDEBUGPRINTFX(DBG_HOT,( "No room for issueing in this message, command '%s' queued for next message", aSyncCommandP->getName() )); // - could not be issued, was queued issued=false; } else { // issue the command if (splitCmdP) fOutgoingMessageFull=true; // if we are sending a split command, message IS full after that! bool dodelete=true; if (aSyncCommandP->issue(getNextOutgoingCmdID(),fOutgoingMsgID,aNoResp)) { // command expects status and must be kept in list PDEBUGPRINTFX(DBG_HOT,("%s: issued as (outgoing MsgID=%ld, CmdID=%ld), now queueing for &html;&html;status&html;&html;", aSyncCommandP->getName(), (long)aSyncCommandP->getMsgID(), (long)aSyncCommandP->getCmdID(), (long)aSyncCommandP->getMsgID(), (long)aSyncCommandP->getCmdID(), (long)aSyncCommandP->getMsgID(), (long)aSyncCommandP->getCmdID() )); // - queue for status aSyncCommandP->setWaitingForStatus(true); // increment waiting for status count of this command fStatusWaitCommands.push_back(aSyncCommandP); dodelete=false; } else { // command does not expect status and can be deleted if it is finished PDEBUGPRINTFX(DBG_HOT,("%s: issued as (outgoing MsgID=%ld, CmdID=%ld), not waiting for status", aSyncCommandP->getName(), (long)aSyncCommandP->getMsgID(), (long)aSyncCommandP->getCmdID() )); } // Now as it is issued, count all "real" commands if (!aIsOKSyncHdrStatus) { // count outgoing "real" command, that is NOT SyncHdr OK status nor Alert 222 OK statu // Note that issuing a container command such as will have pre-decremented fOutgoingCmds // to compensate (container should not be counted) fOutgoingCmds++; } // test if finished issuing if (!aSyncCommandP->finished()) { // issuing was interrupted, continue at start of next message aInterruptedCommandP=aSyncCommandP; // remember dodelete=false; issued=false; PDEBUGPRINTFX(DBG_SESSION,("%s: issue not finished -> queued interrupted command", aSyncCommandP->getName() )); } // - delete if not queued if (dodelete) { PDEBUGPRINTFX(DBG_SESSION,("%s: issue finished and not waiting for status -> deleting command", aSyncCommandP->getName() )); delete aSyncCommandP; } // message size PDEBUGPRINTFX(DBG_PROTO,("Outgoing Message size is now %ld bytes",(long)getOutgoingMessageSize())); } } SYSYNC_CATCH (...) // exception during command issuing // - make sure command is deleted (as issue owns it now) delete aSyncCommandP; // make sure session gets aborted AbortSession(500,true); // local problem // close block PDEBUGENDBLOCK("issue"); // re-throw SYSYNC_RETHROW; SYSYNC_ENDCATCH endissue: PDEBUGENDBLOCK("issue"); } // if something to issue at all else { DEBUGPRINTFX(DBG_SESSION,("issuePtr called with NULL command")); } // return true if completely issued, false if interrupted or not issued at all return issued; } // TSyncSession::issuePtr // returns true if given number of bytes are transferable // (not exceeding MaxMsgSize (in SyncML 1.0) or MaxObjSize (SyncML 1.1 and later) bool TSyncSession::dataSizeTransferable(uInt32 aDataBytes) { if (fSyncMLVersion 0 ? leavefree : 0; } else { // limited only by workspace itself: no bytes need to be left free return 0; } } // TSyncSession::getNotUsableBufferBytes // get max size outgoing message may have (either defined by remote's maxmsgsize or local buffer space) sInt32 TSyncSession::getMaxOutgoingSize(void) { return fMaxOutgoingMsgSize>0 ? fMaxOutgoingMsgSize : getSmlWorkspaceFreeBytes(); } // TSyncSession::getMaxOutgoingSize /// @brief mark all pending items for a datastore for resume /// (those items that are in a session queue for being issued or getting status) void TSyncSession::markPendingForResume(TLocalEngineDS *aForDatastoreP) { TSmlCommandPContainer::iterator pos; // - commands not issued yet because header not yet generated for (pos=fHeaderWaitCommands.begin(); pos!=fHeaderWaitCommands.end(); ++pos) { (*pos)->markPendingForResume(aForDatastoreP,true); // unsent } // - commands not issued yet because they belong at the end of the message for (pos=fEndOfMessageCommands.begin(); pos!=fEndOfMessageCommands.end(); ++pos) { (*pos)->markPendingForResume(aForDatastoreP,true); // unsent } // - interrupted and next-message commands markPendingForResume(fNextMessageCommands,fInterruptedCommandP,aForDatastoreP); // - next package commands for (pos=fNextPackageCommands.begin(); pos!=fNextPackageCommands.end(); ++pos) { (*pos)->markPendingForResume(aForDatastoreP,true); // unsent } // - commands waiting for status for (pos=fStatusWaitCommands.begin(); pos!=fStatusWaitCommands.end(); ++pos) { (*pos)->markPendingForResume(aForDatastoreP,false); // these are already sent (except if they are waiting for chunk ok 213 status)! } } // TSyncSession::markPendingForResume /// @brief mark all pending items for a datastore for resume /// (those items that are in a session queue for being issued or getting status) void TSyncSession::markPendingForResume( TSmlCommandPContainer &aNextMessageCommands, TSmlCommand *aInterruptedCommandP, TLocalEngineDS *aForDatastoreP ) { // - all those that are in an interrupted command if (aInterruptedCommandP) { aInterruptedCommandP->markPendingForResume(aForDatastoreP,true); // these are unsent } // - all those pending for next message TSmlCommandPContainer::iterator pos; for (pos=aNextMessageCommands.begin(); pos!=aNextMessageCommands.end(); ++pos) { (*pos)->markPendingForResume(aForDatastoreP,true); // these are unsent } } // TSyncSession::markPendingForResume // continue interrupted or prevented issue of root level commands void TSyncSession::ContinuePackageRoot(void) { // check if we have anything to send, and if so, reset the count if (fNextMessageCommands.size()>0 || fInterruptedCommandP) { #ifdef SYDEBUG if (fNextMessageRequests) { PDEBUGPRINTFX(DBG_PROTO,("Fulfilling %ld Next-Message-Request-Alerts 222 by sending commands now",(long)fNextMessageRequests)); } #endif fNextMessageRequests=0; // sent something, request fulfilled } ContinuePackage(fNextMessageCommands,fInterruptedCommandP); } // TSyncSession::ContinuePackageRoot // continue interrupted or prevented issue in next package void TSyncSession::ContinuePackage( TSmlCommandPContainer &aNextMessageCommands, TSmlCommand * &aInterruptedCommandP ) { TSmlCommand *cmdP = aInterruptedCommandP; // - first restart interrupted command if (cmdP && !isAborted() && !isSuspending()) { // first check if interrupted command has received status if (cmdP->isWaitingForStatus() && getSessionConfig()->fWaitForStatusOfInterrupted) { // Command to be continued has not yet received status, so wait with continuing it PDEBUGPRINTFX(DBG_SESSION,( "Interrupted command '%s' (outgoing MsgID=%ld, CmdID=%ld) is still waiting for status -> do not continue nor send queued commands", cmdP->getName(), (long)cmdP->getMsgID(), (long)cmdP->getCmdID() )); // aInterruptedCommandP is still set, prevents sending of queued commands } else { PDEBUGPRINTFX(DBG_SESSION,("Sending command that was interrupted at end of last message")); // there is an interrupted command, continue it bool dodelete=true; // if an interrupted command must be continued, this can't be an OK for SyncHdr fNeedToAnswer=true; bool newIssue=false; // now continue issuing bool queueForStatus=cmdP->continueIssue(newIssue); // check if complete re-issuing is needed if (newIssue) { // command must be re-issued as if it was a new command PDEBUGPRINTFX(DBG_SESSION,("%s: continuing command by issuing anew",cmdP->getName())); // interruption is over for now, IssuePtr will set it again if interrupted again aInterruptedCommandP=NULL; // IssuePtr will take care of all needed status queueing and deleting command if finished etc. issuePtr(cmdP,aNextMessageCommands,aInterruptedCommandP); // never delete, as issuePtr will have done it if needed dodelete=false; } else { // no complete re-issuing needed, just check if we need to queue for status (again) if (queueForStatus) { // command expects status (again?) and must be kept in list PDEBUGPRINTFX(DBG_SESSION,("%s: continued, now queueing for status (again) as (outgoing MsgID=%ld, CmdID=%ld)", cmdP->getName(), (long)cmdP->getMsgID(), (long)cmdP->getCmdID() )); // - queue for status (note that every SyncML 1.1 chunk wants to see a status 213 in any case!) if (!cmdP->isWaitingForStatus()) { // only put to the queue again if not already waiting there fStatusWaitCommands.push_back(cmdP); cmdP->setWaitingForStatus(true); } else { // already waiting, so it's already in the queue - do not push it again PDEBUGPRINTFX(DBG_SESSION,("%s: continued command was already waiting for status, do not push again", cmdP->getName())); } dodelete=false; } } // test if completely issued now if (!cmdP->finished()) { // issuing was again interrupted, continue at start of next message // - keep aInterruptedCommandP pointer unchanged dodelete=false; PDEBUGPRINTFX(DBG_SESSION,("%s: continueIssue not finished -> queued interrupted command again", cmdP->getName() )); } else { // no interrupted command any more aInterruptedCommandP=NULL; } // delete if not queued if (dodelete) { PDEBUGPRINTFX(DBG_SESSION,("%s: continueIssue finished and not waiting for status -> deleting command", cmdP->getName() )); delete cmdP; } } // if status was received for interrupted command } // if interrupted command // send commands from queue (until interrupted again) #ifdef SYDEBUG if (!isAborted() && !isSuspending() && !aInterruptedCommandP && aNextMessageCommands.size()>0) { PDEBUGPRINTFX(DBG_SESSION,("Sending %ld commands that didn't make it into last message",(long)aNextMessageCommands.size())); } #endif TSmlCommandPContainer::iterator pos; while (!isAborted() && !isSuspending() && !aInterruptedCommandP && !outgoingMessageFull()) { // first in list pos=aNextMessageCommands.begin(); if (pos==aNextMessageCommands.end()) break; // done // take command out of the list cmdP=(*pos); aNextMessageCommands.erase(pos); // issue it (without luck, might land in the queue again --> %%% endless retry??) if (!issuePtr(cmdP,aNextMessageCommands,aInterruptedCommandP)) break; } } // TSyncSession::ContinuePackage // create, send and delete SyncHeader "command" void TSyncSession::issueHeader(bool aNoResp) { #ifdef SYDEBUG // Start output translation before issuing outgoing header XMLTranslationOutgoingStart(); #endif if (IS_CLIENT) { #ifdef SYDEBUG // for client, document exchange starts with outgoing message // but for server, SyncML_Outgoing is started before SyncML_Incoming, as SyncML_Incoming ends first PDEBUGBLOCKDESC("SyncML_Outgoing","start of new outgoing message"); PDEBUGPRINTFX(DBG_HOT,("=================> Started new outgoing message")); #endif #ifdef EXPIRES_AFTER_DATE // set 1/4 of the date here fCopyOfScrambledNow=((getSyncAppBase()->fScrambledNow)<<2)+503; // scramble again a little #endif } // create and send response header TSyncHeader *syncheaderP; MP_NEW(syncheaderP,DBG_OBJINST,"TSyncHeader",TSyncHeader(this,aNoResp)); PDEBUGBLOCKFMT(("SyncHdr","SyncHdr generation","SyncMLVers=%s|OutgoingMsgID=%ld",SyncMLVerDTDNames[fSyncMLVersion],(long)fOutgoingMsgID)); SYSYNC_TRY { // Note: do not use session's issue(), as this is designed for real commands, not headers if (syncheaderP->issue(0,fOutgoingMsgID)) { // - queue for status PDEBUGPRINTFX(DBG_PROTO,("SyncHdr: issued in MsgID=%ld, now queueing for status",(long)syncheaderP->getMsgID())); syncheaderP->setWaitingForStatus(true); fStatusWaitCommands.push_back(syncheaderP); } else { PDEBUGPRINTFX(DBG_PROTO,("SyncHdr: issued in MsgID=%ld, now deleting",(long)syncheaderP->getMsgID())); delete syncheaderP; // not used any more } DEBUGPRINTFX(DBG_PROTO,("Outgoing Message size is now %ld bytes",(long)getOutgoingMessageSize())); // - init number of commands in message fOutgoingCmds=0; // - now issue all commands that could not yet be sent because outgoing // message was not started #ifdef SYDEBUG if (fHeaderWaitCommands.size()>0) { PDEBUGPRINTFX(DBG_SESSION,("Sending %ld commands that were queued because header was not yet generated",(long)fHeaderWaitCommands.size())); } #endif TSmlCommandPContainer::iterator pos; while (!fAborted) { // first in list pos=fHeaderWaitCommands.begin(); if (pos==fHeaderWaitCommands.end()) break; // done // take command out of the list TSmlCommand *cmdP=(*pos); fHeaderWaitCommands.erase(pos); if (!cmdP) { DEBUGPRINTFX(DBG_ERROR,("There was a NULL command in the fHeaderWaitCommands queue?!?")); continue; } // issue now (as if all were OK for synchdr, because fNeedToAnswer may not be affected here!) if (!issuePtr(cmdP,fNextMessageCommands,fInterruptedCommandP,false,true)) { PDEBUGPRINTFX(DBG_SESSION,("Could not issue queued command")); break; } } PDEBUGENDBLOCK("SyncHdr"); } SYSYNC_CATCH (...) PDEBUGENDBLOCK("SyncHdr"); delete syncheaderP; // not used any more SYSYNC_RETHROW; // rethrow SYSYNC_ENDCATCH } // TSyncSession::IssueHeader // process a command (analyze and execute it). // Ownership of command is passed to process() in all cases. // Note: This method does not throw exceptions (catches all) and // is suitable for being called without further precautions from // SyncML toolkit callbacks. Exceptions are translated to // smlXXX error codes. Ret_t TSyncSession::process(TSmlCommand *aSyncCommandP) { if (aSyncCommandP) { SYSYNC_TRY { // first analyze it (before we can open the block, as we need to find cmdID fisrt) if (!aSyncCommandP->analyze(fIncomingState)) { // bad command PDEBUGPRINTFX(DBG_ERROR,("%s: command failed analyze() -> aborting session",aSyncCommandP->getName())); AbortSession(400,true); // local problem delete aSyncCommandP; } else { // command ok so far (has cmdid, so we can refer to it) PDEBUGBLOCKFMT(("processCmd","Processing incoming command", "Cmd=%s|IncomingMsgID=%ld|CmdID=%ld", aSyncCommandP->getName(), (long)aSyncCommandP->getMsgID(), (long)aSyncCommandP->getCmdID() )); SYSYNC_TRY { // - test if processing is enabled if (fIgnoreIncomingCommands && !aSyncCommandP->neverIgnore()) { // commands must be ignored (fatal error in previous command/header) PDEBUGPRINTFX(DBG_ERROR,("%s: IGNORED ",aSyncCommandP->getName())); // - still generate status (except if aborted status is 0, which means silent abort) // but DO NOT generate status for status! if (fStatusCodeForIgnored!=0 && aSyncCommandP->getCmdType()!=scmd_status) { PDEBUGPRINTFX(DBG_ERROR,(" Sending status %hd for ignored command",fStatusCodeForIgnored)); TStatusCommand *aStatusCmdP = aSyncCommandP->newStatusCommand(fStatusCodeForIgnored); issueRootPtr(aStatusCmdP); } // - delete unexecuted delete aSyncCommandP; } else if ( // Be extra careful: even if fStrictExecOrdering=false, still delay // further commands if they would overtake non-trivial commands in the // delay queue. This solves a particular problem where the Sync command // gets delayed due to slow TStdLogicDS::startDataAccessForServer(). // The server then sees a second (fake?!) Sync command (incoming MsgID=2, CmdID=0) // which it must delay instead of executing it. (fStrictExecOrdering || !onlyItemChangesPending()) && fDelayedExecutionCommands.size()>0 && aSyncCommandP->getCmdType()!=scmd_status && aSyncCommandP->getCmdType()!=scmd_alert ) { // some commands have been delayed already -> delay all non-statuses and alerts as well PDEBUGPRINTFX(DBG_SESSION,("%s: command received after other commands needed to be delayed -> must be delayed, too",aSyncCommandP->getName())); // - put into delayed execution queue delayExecUntilNextRequest(aSyncCommandP); } else { if (fDelayedExecutionCommands.size()>0 && !aSyncCommandP->canExecuteOutOfOrder()) { PDEBUGPRINTFX(DBG_SESSION,("%s: command cannot be executed with other commands already delayed -> flush queue",aSyncCommandP->getName())); fCmdIncoming = NULL; tryDelayedExecutionCommands(); } // command is ok, execute it fCmdIncomingState=aSyncCommandP->getPackageState(); // Queue Status commands issued during execute()? if (fDelayedExecutionCommands.size()>0 && aSyncCommandP->getCmdType()!=scmd_status && aSyncCommandP->getCmdType()!=scmd_alert) { // Yes, let issueRootPtr() attach to queue in aSyncCommandP and issue later // in tryDelayedExecutionCommands() resp. executeDelayedCmd(). fCmdIncoming=aSyncCommandP; } else { fCmdIncoming=NULL; } if (aSyncCommandP->execute()) { // execution finished, can be deleted if (aSyncCommandP->finished()) { if (aSyncCommandP->hasQueuedStatusCmds()) { PDEBUGPRINTFX(DBG_SESSION,("%s: command finished execution with pending Status replies -> queue command",aSyncCommandP->getName())); delayExecUntilNextRequest(aSyncCommandP); } else { PDEBUGPRINTFX(DBG_SESSION,("%s: command finished execution -> deleting",aSyncCommandP->getName())); delete aSyncCommandP; } } else { PDEBUGPRINTFX(DBG_SESSION,("%s: command NOT finished execution, NOT deleting now",aSyncCommandP->getName())); } } else { // command has not finished execution, must be retried after next incoming message PDEBUGPRINTFX(DBG_SESSION,("%s: command wants re-execution later -> queueing",aSyncCommandP->getName())); // - put into delayed execution queue delayExecUntilNextRequest(aSyncCommandP); } } // if not ignored // successfully processed fCmdIncoming=NULL; PDEBUGENDBLOCK("processCmd"); } // try SYSYNC_CATCH (...) fCmdIncoming=NULL; PDEBUGENDBLOCK("processCmd"); SYSYNC_RETHROW; SYSYNC_ENDCATCH } // if analyzed successfully } SYSYNC_CATCH (TSmlException &e) // Sml error exception somewhere in command processing // - make sure command is deleted (as issue owns it now) delete aSyncCommandP; PDEBUGPRINTFX(DBG_ERROR,("WARNING: process(cmd) SmlException: %s, smlerr=%hd",e.what(),e.getSmlError())); // - return SML error that caused this exception return e.getSmlError(); SYSYNC_ENDCATCH SYSYNC_CATCH (TSyncException &e) // sync exception during command processing // - make sure command is deleted (as issue owns it now) delete aSyncCommandP; PDEBUGPRINTFX(DBG_ERROR,("WARNING: process(cmd) SyncException: %s, status=%hd",e.what(),e.status())); // - unspecific SyncML toolkit error, causes session to abort return SML_ERR_UNSPECIFIC; SYSYNC_ENDCATCH SYSYNC_CATCH (exception &e) // C++ exception during command processing // - make sure command is deleted (as issue owns it now) delete aSyncCommandP; PDEBUGPRINTFX(DBG_ERROR,("WARNING: process(cmd) Exception: %s",e.what())); // - unspecific SyncML toolkit error, causes session to abort return SML_ERR_UNSPECIFIC; SYSYNC_ENDCATCH SYSYNC_CATCH (...) // other exception during command processing // - make sure command is deleted (as issue owns it now) delete aSyncCommandP; PDEBUGPRINTFX(DBG_ERROR,("WARNING: process(cmd) unknown exception: -> cmd deleted")); // - unspecific SyncML toolkit error, causes session to abort return SML_ERR_UNSPECIFIC; SYSYNC_ENDCATCH } // successful return SML_ERR_OK; } // TSyncSession::process // process synchdr (analyze and execute it). // Ownership of command is passed to process() in all cases. // Note: May cause session reset if message sequence numbers are not ok. Ret_t TSyncSession::processHeader(TSyncHeader *aSyncHdrP) { if (aSyncHdrP) { PDEBUGBLOCKDESC("processHdr","Processing incoming SyncHdr"); SYSYNC_TRY { // init some session vars // - do not ignore commands by default fIgnoreIncomingCommands=false; // - need to answer raises out of first non-synchdr-status command issue()d fNeedToAnswer=false; // no need yet // - initialize message status fMsgNoResp=false; // default to response for messages fIncomingMsgID++; // count this incoming message // init flag bool tryagain=false; do { // first analyze header if (!aSyncHdrP->analyze(fIncomingState)) { // bad command PDEBUGPRINTFX(DBG_ERROR,("%s: failed analyze() -> deleting",aSyncHdrP->getName())); delete aSyncHdrP; } else { // command is ok, execute it fCmdIncomingState=aSyncHdrP->getPackageState(); PDEBUGBLOCKFMT(("SyncHdr","Processing incoming SyncHdr", "IncomingMsgID=%ld", (long)fIncomingMsgID )); SYSYNC_TRY { if (aSyncHdrP->execute()) { // show session info after processing header #ifdef SYDEBUG PDEBUGPRINTFX(DBG_HOT,("Incoming SyncHdr processed, incomingMsgID=%ld, SyncMLVers=%s",(long)fIncomingMsgID,SyncMLVerDTDNames[fSyncMLVersion])); PDEBUGPRINTFX(DBG_HOT,("- Session ID='%s'",fSynchdrSessionID.c_str())); PDEBUGPRINTFX(DBG_HOT,("- Source (Remote party): URI='%s' DisplayName='%s'",fRemoteURI.c_str(),fRemoteName.c_str())); PDEBUGPRINTFX(DBG_HOT,("- Response to be sent to URI='%s'",fRespondURI.empty() ? "[none specified, back to source]" : fRespondURI.c_str())); PDEBUGPRINTFX(DBG_HOT,("- Target (Local party) : URI='%s' DisplayName='%s'",fLocalURI.c_str(),fLocalName.c_str())); #endif CONSOLEPRINTF(("> SyncML message #%ld received from '%s'",(long)fIncomingMsgID,fRemoteURI.c_str())); // - UTC support is implied for SyncML 1.0 (as most devices support it, and // there is was no way to signal it in 1.0). if (!fRemoteDevInfKnown && fSyncMLVersion==syncml_vers_1_0) fRemoteCanHandleUTC=true; // execution finished, can be deleted PDEBUGPRINTFX(DBG_SESSION,("%s: finished execution -> deleting",aSyncHdrP->getName())); delete aSyncHdrP; // now execute delayed commands (before executing new ones) PDEBUGPRINTFX(DBG_SESSION,("New message: Executing %ld delayed commands",(long)fDelayedExecutionCommands.size())); bool syncEndAfterSyncPackageEnd=tryDelayedExecutionCommands(); // check if all delayed commands are executed now if (fDelayedExecSyncEnds<=0 && syncEndAfterSyncPackageEnd) { // there was at least one queued syncend executed AFTER end of incoming sync package // This means that we must finalize the sync-from-remote phase for the datastores here // (as it was suppressed when the incoming sync package had ended) TLocalDataStorePContainer::iterator dspos; for (dspos=fLocalDataStores.begin(); dspos!=fLocalDataStores.end(); ++dspos) { (*dspos)->engEndOfSyncFromRemote(true); } } else { PDEBUGPRINTFX(DBG_SESSION,("%ld delayed commands could not yet be executed and are left in the queue for next message",(long)fDelayedExecutionCommands.size())); } // now issue next package commands if any if (fNewOutgoingPackage) { PDEBUGPRINTFX(DBG_SESSION,("New package: Sending %ld commands that were generated earlier for this package",(long)fNextPackageCommands.size())); TSmlCommandPContainer::iterator nppos; for (nppos=fNextPackageCommands.begin(); nppos!=fNextPackageCommands.end(); nppos++) { // issue it (might land in NextMessageCommands) issueRootPtr((*nppos)); } // done sending next package commands fNextPackageCommands.clear(); // clear list } // done, don't try again break; } else { // unexecutable SyncHdr // - could be resent message if (fMessageRetried) { // simply abort processing, let transport handle this PDEBUGENDBLOCK("processHdr"); return LOCERR_RETRYMSG; // signal retry has happened } // - let agent decide what to do (and whether to try again executing the command) DEBUGPRINTFX(DBG_SESSION,("%s: Cannot be executed properly, trying to recover",aSyncHdrP->getName())); tryagain = syncHdrFailure(tryagain); } // synchdr not ok } // try SYSYNC_CATCH (...) PDEBUGENDBLOCK("SyncHdr"); SYSYNC_RETHROW; SYSYNC_ENDCATCH } } while(tryagain); PDEBUGENDBLOCK("SyncHdr"); } SYSYNC_CATCH (TSmlException &e) // Sml error exception somewhere in command processing // - make sure command is deleted (as issue owns it now) delete aSyncHdrP; PDEBUGPRINTFX(DBG_ERROR,("WARNING: synchdr SmlException: %s, smlerr=%hd",e.what(),e.getSmlError())); PDEBUGENDBLOCK("processHdr"); // - return SML error that caused this exception return e.getSmlError(); SYSYNC_ENDCATCH SYSYNC_CATCH (exception &e) // C++ exception somewhere in command processing // - make sure command is deleted (as issue owns it now) delete aSyncHdrP; PDEBUGPRINTFX(DBG_ERROR,("WARNING: synchdr exception: %s",e.what())); PDEBUGENDBLOCK("processHdr"); // - return SML error that caused this exception return SML_ERR_UNSPECIFIC; SYSYNC_ENDCATCH SYSYNC_CATCH (...) // other exception during command processing // - make sure command is deleted (as issue owns it now) delete aSyncHdrP; PDEBUGPRINTFX(DBG_ERROR,("WARNING: synchdr unknown-class exception: -> deleted")); PDEBUGENDBLOCK("processHdr"); // - unspecific SyncML toolkit error, causes session to abort return SML_ERR_UNSPECIFIC; SYSYNC_ENDCATCH } // successful PDEBUGENDBLOCK("processHdr"); return SML_ERR_OK; } // TSyncSession::processHeader bool TSyncSession::onlyItemChangesPending() { TSmlCommandPContainer::iterator pos=fDelayedExecutionCommands.begin(); while (pos!=fDelayedExecutionCommands.end()) { TSmlCommand *cmdP = *pos; switch (cmdP->getCmdType()) { // A white-list of commands perform simple data changes. // These commands can be overtaken by the execution of // other commands, see TSyncSession::process(). case scmd_add: case scmd_delete: case scmd_replace: case scmd_copy: break; default: return false; } ++pos; } return true; } bool TSyncSession::onlySyncPending() { TSmlCommandPContainer::iterator pos=fDelayedExecutionCommands.begin(); while (pos!=fDelayedExecutionCommands.end()) { TSmlCommand *cmdP = *pos; if (cmdP->getCmdType() != scmd_sync) { return false; } ++pos; } return true; } bool TSyncSession::tryDelayedExecutionCommands() { bool syncEndAfterSyncPackageEnd=false; // Always try issuing the first command until queue is empty. while (!fDelayedExecutionCommands.empty()) { // execute again TSmlCommand *cmdP = fDelayedExecutionCommands.front(); // command ok so far (has cmdid, so we can refer to it) PDEBUGBLOCKFMT(("executeDelayedCmd","Re-executing command from delayed queue", "Cmd=%s|IncomingMsgID=%ld|CmdID=%ld", cmdP->getName(), (long)cmdP->getMsgID(), (long)cmdP->getCmdID() )); SYSYNC_TRY { fCmdIncomingState=cmdP->getPackageState(); if (executeDelayedCmd(cmdP)) { // check if this was a syncend which was now executed AFTER the end of the incoming sync package if (cmdP->getCmdType()==scmd_syncend) { fDelayedExecSyncEnds--; // count executed syncend if (cmdP->getPackageState()!=fIncomingState) syncEndAfterSyncPackageEnd=true; // remember that we had at least one } // execution finished, can be deleted PDEBUGPRINTFX(DBG_SESSION,("%s: command finished execution -> deleting",cmdP->getName())); delete cmdP; // delete from queue fDelayedExecutionCommands.pop_front(); } else { // command has not finished execution, must be retried after next incoming message PDEBUGPRINTFX(DBG_SESSION,("%s: command STILL NOT finished execution -> keep it (and all follwoing) in queue ",cmdP->getName())); // keep this and all subsequent commands in the queue PDEBUGENDBLOCK("executeDelayedCmd"); break; } PDEBUGENDBLOCK("executeDelayedCmd"); } // try SYSYNC_CATCH (...) PDEBUGENDBLOCK("executeDelayedCmd"); SYSYNC_RETHROW; SYSYNC_ENDCATCH } return syncEndAfterSyncPackageEnd; } bool TSyncSession::executeDelayedCmd(TSmlCommand *aCmdP) { if (aCmdP->hasQueuedStatusCmds()) { // The only way how such a command can end up in the queue is // if it has finished earlier. Now we can try to issue the // queued status replies, because all previous commands have // been dealt with. // If a Sync command was queued, all of its SyncOp commands // were also queued. We are going to execute them now for the // first time, which depends on having fLocalSyncDatastoreP // set correctly (see TSyncOpCommand::execute()). This was // set when executing the Sync command for the first time, and // must be restored here, otherwise we end up using the // fLocalSyncDatastoreP from, for example, a previously resumed // SyncOp from a different datastore. if (aCmdP->getCmdType()==scmd_sync) { TSyncCommand *syncCommandP=static_cast(aCmdP); fLocalSyncDatastoreP=syncCommandP->getLocalDatastore(); PDEBUGPRINTFX(DBG_SESSION,("executeDelayedCmd: restore fLocalSyncDatastoreP from sync command")); } // Take over ownership of all queued status commands. TSmlCommandPContainer statusCmds; aCmdP->transferQueuedStatusCmds(statusCmds); SYSYNC_TRY { while (!statusCmds.empty()) { TSmlCommand *statusCmdP=statusCmds.front(); statusCmds.pop_front(); // All commands for which we might queue statuses send // them with default parameters (see synccommand.cpp). // Therefore we can do the same here, without having to // store the parameters. issueRootPtr(statusCmdP); } } SYSYNC_CATCH (...) TSmlCommandPContainerClear(statusCmds); SYSYNC_RETHROW; SYSYNC_ENDCATCH TSmlCommandPContainerClear(statusCmds); return true; } else { return aCmdP->execute(); } } #ifdef __PALM_OS__ #pragma segment session2 #endif // %%% integrate Results command here, too (that, is, make a common // ancestor for both TStatusCommand and TResultsCommand which // is then handled here in common). // handle a status "command" // Ownership of status is passed to handleStatus() in all cases. // Note: This method does not throw exceptions (catches all) and // is suitable for being called without further precautions from // SyncML toolkit callbacks. Exceptions are translated to // smlXXX error codes. Ret_t TSyncSession::handleStatus(TStatusCommand *aStatusCommandP) { if (aStatusCommandP) { PDEBUGBLOCKDESC("processStatus","Processing incoming Status"); SYSYNC_TRY { // analyze first if (!aStatusCommandP->analyze(fIncomingState)) { // bad command PDEBUGPRINTFX(DBG_SESSION,("%s: status failed analyze() -> deleting",aStatusCommandP->getName())); delete aStatusCommandP; } else { bool found=false; // status is ok, find matching command TSmlCommandPContainer::iterator pos; for (pos=fStatusWaitCommands.begin(); pos!=fStatusWaitCommands.end(); ++pos) { if ((*pos)->matchStatus(aStatusCommandP)) { PDEBUGPRINTFX(DBG_PROTO,("Found matching command '%s' for Status",(*pos)->getName())); (*pos)->setWaitingForStatus(false); // has received status found=true; if (fIgnoreIncomingCommands) { // ignore statuses, but remove waiting command from queue if ((*pos)->finished()) delete (*pos); // unfinished are owned otherwise and must not be deleted fStatusWaitCommands.erase(pos); PDEBUGPRINTFX(DBG_SESSION,("Status ignored, command considered done -> deleted")); } else { // let descendants know when we process a required status if ((*pos)->statusEssential()) { essentialStatusReceived(); } // normally process status if ((*pos)->handleStatus(aStatusCommandP)) { PDEBUGPRINTFX(DBG_SESSION,("Status: processed, removed command '%s' from status wait queue",(*pos)->getName())); // done with command, remove from queue if ((*pos)->finished()) { // - if this is an interrupted command, make sure to remove pointer if ((*pos)==fInterruptedCommandP) fInterruptedCommandP=NULL; // - delete command itself // NOTE; if not finished, command is owned otherwise and must // persist PDEBUGPRINTFX(DBG_SESSION,("Status: command '%s' has handled status and allows to be deleted",(*pos)->getName())); delete (*pos); } else { PDEBUGPRINTFX(DBG_SESSION,("Status: command '%s' has handled status, but not finished() -> NOT deleted",(*pos)->getName())); } // - anyway, remove from list fStatusWaitCommands.erase(pos); } else { // command not yet acknowledged, keep in queue (*pos)->setWaitingForStatus(true); // is again waiting for a status PDEBUGPRINTFX(DBG_SESSION,("(intermediate) Status processed, command kept in queue, not deleted")); } } // else normal processing break; // exit for loop (iterator is not ok any more) } } // for if (!found) { // no matching command found PDEBUGPRINTFX(DBG_ERROR,("No command found for status -> ignoring")); } // now delete status delete aStatusCommandP; } // if analyzed successfully } SYSYNC_CATCH (TSmlException &e) // Sml error exception somewhere in command processing // - make sure command is deleted (as issue owns it now) delete aStatusCommandP; PDEBUGPRINTFX(DBG_ERROR,("WARNING: handleStatus SmlException: %s, smlerr=%hd",e.what(),e.getSmlError())); PDEBUGENDBLOCK("processStatus"); // - return SML error that caused this exception return e.getSmlError(); SYSYNC_ENDCATCH SYSYNC_CATCH (exception &e) // Sml error exception somewhere in command processing // - make sure command is deleted (as issue owns it now) delete aStatusCommandP; PDEBUGPRINTFX(DBG_ERROR,("WARNING: handleStatus exception: %s",e.what())); PDEBUGENDBLOCK("processStatus"); // - unspecific SyncML toolkit error, causes session to abort return SML_ERR_UNSPECIFIC; SYSYNC_ENDCATCH SYSYNC_CATCH (...) // other exception during command processing // - make sure command is deleted (as issue owns it now) delete aStatusCommandP; PDEBUGPRINTFX(DBG_ERROR,("WARNING: handleStatus unknown-class exception: -> deleted")); PDEBUGENDBLOCK("processStatus"); // - unspecific SyncML toolkit error, causes session to abort return SML_ERR_UNSPECIFIC; SYSYNC_ENDCATCH } // successful PDEBUGENDBLOCK("processStatus"); return SML_ERR_OK; } // TSyncSession::handleStatus // Session level meta SmlPcdataPtr_t TSyncSession::newHeaderMeta(void) { SmlPcdataPtr_t metaP = NULL; // create meta for initialisation message only #ifdef SEND_MAXMSGSIZE_ON_INIT_ONLY if (fOutgoingState<=psta_init) #endif { metaP=newMeta(); SmlMetInfMetInfPtr_t metinfP = smlPCDataToMetInfP(metaP); // - add max message size metinfP->maxmsgsize=newPCDataLong(getRootConfig()->fLocalMaxMsgSize); if ( (getRootConfig()->fLocalMaxObjSize>0) && (fSyncMLVersion>=syncml_vers_1_1) ) { // SyncML 1.1 has object size metinfP->maxobjsize=newPCDataLong(getRootConfig()->fLocalMaxObjSize); } } return metaP; } // TSyncSession::newHeaderMeta // create new SyncHdr structure for TSyncHeader command // (here because all data for this is in session anyway) // Called exclusively from TSyncHeader command SmlSyncHdrPtr_t TSyncSession::NewOutgoingSyncHdr(bool aOutgoingNoResp) { SmlSyncHdrPtr_t headerP; MP_SHOWCURRENT(DBG_PROFILE,"Start of outgoing message"); // set response status for entire message fOutgoingNoResp=aOutgoingNoResp; // get new number for this message fOutgoingMsgID++; // reset message size counting fOutgoingMsgSize=0; // reset command ID fOutgoingCmdID=0; // now compose Sync Header from session vars // - create empty header headerP = SML_NEW(SmlSyncHdr_t); #ifdef EXPIRES_AFTER_DATE // prepare for a check, convert back to normal value * 4 sInt32 scramblednow4 = (fCopyOfScrambledNow-503); #endif SYSYNC_TRY { // set proto element type to make it auto-disposable headerP->elementType=SML_PE_HEADER; // set version information headerP->version=newPCDataString(SyncMLVerDTDNames[fSyncMLVersion]); headerP->proto=newPCDataString(SyncMLVerProtoNames[fSyncMLVersion]); // set session ID headerP->sessionID=newPCDataString(fSynchdrSessionID); // set new message ID for this message #ifdef APP_CAN_EXPIRE // check for expiry again #ifdef EXPIRES_AFTER_DATE // - has hard expiry date if ( (scramblednow4>SCRAMBLED_EXPIRY_VALUE*4) #ifdef SYSER_REGISTRATION && (!getSyncAppBase()->fRegOK) // only abort if no registration (but accept timed registration) #endif ) getSyncAppBase()->fAppExpiryStatus=LOCERR_EXPIRED; #else // - no hard expiry date, just check if license is still valid if ( !getSyncAppBase()->fRegOK || // no registered at all getSyncAppBase()->fDaysLeft==0 // or expired ) getSyncAppBase()->fAppExpiryStatus=LOCERR_EXPIRED; #endif #endif headerP->msgID=newPCDataLong(fOutgoingMsgID); // flags headerP->flags=fOutgoingNoResp ? SmlNoResp_f : 0; // target (URI/Name of Remote party) // Note: Tsutomu Uenoyama (uenoyama@trl.mei.co.jp) sais in syncml feedback // list that server RespURI behaviour should // be reflecting received RespURI in target, so we do it: headerP->target=newLocation( fRespondURI.empty() ? fRemoteURI.c_str() : fRespondURI.c_str(), fRemoteName.c_str() ); PDEBUGPRINTFX(DBG_PROTO,("Target (Remote URI) = '%s'",fRespondURI.empty() ? fRemoteURI.c_str() : fRespondURI.c_str())); // source (URI / User-Name of local party) // NOTE: The LocName must contain the name of the user and not // the name of the device (this is a SyncML 1.0.1 correction // to make MD5 auth implementable - we need a clear-text user name) headerP->source=newLocation( fLocalURI.c_str(), getUsernameForRemote() // user name for remote login, NULL if none available ); // add respURI if local party cannot be responded to via normal URI // New added for T68i: do not send a RespURI for an aborted session if (!isAborted() && fMessageAuthorized) headerP->respURI=newResponseURIForRemote(); else headerP->respURI=NULL; // add credentials if remote needs them headerP->cred=newCredentialsForRemote(); // agent-specific meta headerP->meta=newHeaderMeta(); } SYSYNC_CATCH (...) // make sure header is disposed smlFreeProtoElement(headerP); SYSYNC_RETHROW; // re-throw SYSYNC_ENDCATCH // return it return headerP; } // TSyncSession::NewOutgoingSyncHdr // delay command for execution at beginning of next received message void TSyncSession::delayExecUntilNextRequest(TSmlCommand *aCommand) { // push into delay queue fDelayedExecutionCommands.push_back(aCommand); // a delayed (=not processed) syncstart must clear the current fLocalSyncDatastoreP, // as it is not yet known for that . This causes syncops to receive a NULL datastore // at creation, so they must check for that and get it at execute(). if (aCommand->getCmdType()==scmd_sync) { // delayed has no datastore (yet) fLocalSyncDatastoreP=NULL; PDEBUGPRINTFX(DBG_DATA,("delayExecUntilNextRequest: unsetting fLocalSyncDatastoreP for scmd_sync")); } else if (aCommand->getCmdType()==scmd_syncend) { // count delayed syncends as they need special care later fDelayedExecSyncEnds++; if (fLocalSyncDatastoreP) { // and forget current datastore - safety only, should be NULL here anyway fLocalSyncDatastoreP=NULL; PDEBUGPRINTFX(DBG_DATA,("processSyncEnd: unsetting fLocalSyncDatastoreP for scmd_syncend")); } } } // TSyncSession::delayExecUntilNextRequest // remote party requests next message by Alert 222 void TSyncSession::nextMessageRequest(void) { // count the request fNextMessageRequests++; if (IS_SERVER) { // check if we have seen many requests but could not fulfil them if (fNextMessageRequests>3) { // check for resume that does not send us an empty Sync (Symbian client at TestFest 16) PDEBUGPRINTFX(DBG_ERROR,("Warning: More than 3 consecutive Alert 222 - looks like endless loop, check if we need to work around client implementation issues")); // - check datastores TLocalDataStorePContainer::iterator pos; for (pos=fLocalDataStores.begin(); pos!=fLocalDataStores.end(); ++pos) { // see if it is currently resuming TLocalEngineDS *ldsP = (*pos); if (ldsP->isResuming() && ldsP->getDSState() from client to get things going again // - create it SmlSyncPtr_t fakeSyncCmdP = (SmlSyncPtr_t)smlLibMalloc(sizeof(SmlSync_t)); fakeSyncCmdP->elementType = SML_PE_SYNC_START; fakeSyncCmdP->cmdID=NULL; // none needed here fakeSyncCmdP->flags=0; // none fakeSyncCmdP->cred=NULL; fakeSyncCmdP->target=newLocation(ldsP->getName()); // client would target myself fakeSyncCmdP->source=newLocation(ldsP->getRemoteDBPath()); // client would target myself fakeSyncCmdP->meta=NULL; // no meta fakeSyncCmdP->noc=NULL; // no NOC // - have it processed like it was a real command PDEBUGPRINTFX(DBG_HOT+DBG_PROTO,("Probably client expects resume to continue without sending an empty -> simulate one")); PDEBUGBLOCKFMT(( "Resume_Sim_Sync","Simulated empty sync to get resume going", "datastore=%s", ldsP->getName() )); TStatusCommand *fakeStatusCmdP = new TStatusCommand(this); bool queueforlater=false; /* bool ok= */ processSyncStart( fakeSyncCmdP, *fakeStatusCmdP, queueforlater // will be set if command must be queued for later re-execution ); if (!queueforlater) { fNextMessageRequests=0; // reset that counter // and make sure we advance the sync session state // - now the real ugly hacking starts - we have to fake receiving a fFakeFinalFlag=true; } else { PDEBUGPRINTFX(DBG_ERROR,("simulated can't be processed now, we'll try again later")); } // now just simulate a processSyncEnd(queueforlater); // now let this particular datastore "know" that sync-from-client is over now (*pos)->engEndOfSyncFromRemote(true); // fake "final" PDEBUGENDBLOCK("Resume_Sim_Sync"); } } } } // server } // TSyncSession::nextMessageRequest // check if session must continue (for session-level reasons, that // is without regarding sync state of server or client) bool TSyncSession::sessionMustContinue(void) { // if there are delayed commands not yet executed after this message: session must go on if (!fDelayedExecutionCommands.empty()) { PDEBUGPRINTFX(DBG_SESSION,( "%ld commands in delayed-execution-queue -> session must continue", (long)fDelayedExecutionCommands.size() )); return true; // must continue } // if no status to wait for: session may be deleted now if (fStatusWaitCommands.empty()) return false; TSmlCommandPContainer::iterator pos; // show them #ifdef SYDEBUG for (pos=fStatusWaitCommands.begin(); pos!=fStatusWaitCommands.end(); ++pos) { TSmlCommand *cmdP = *pos; // show that command was not answered PDEBUGPRINTFX(DBG_PROTO,("- Not yet received %sstatus for command '%s', (outgoing MsgID=%ld, CmdID=%ld)", cmdP->statusEssential() ? "REQUIRED " : "", cmdP->getName(), (long)cmdP->getMsgID(), (long)cmdP->getCmdID() )); } #endif // check type of commands we miss status for bool mustgoon=false; for (pos=fStatusWaitCommands.begin(); pos!=fStatusWaitCommands.end(); ++pos) { TSmlCommand *cmdP = *pos; if (cmdP->statusEssential()) { // we need a status for at least one of these mustgoon=true; break; } } // if only one single status to wait for, check if it is // SyncHdr status; if no, session MUST continue // (otherwise, remote will not send status for SyncHdr alone) if (mustgoon) { PDEBUGPRINTFX(DBG_HOT,("SESSION CANNOT END - Not yet received REQUIRED status for some of %ld commands",(long)fStatusWaitCommands.size())); } return mustgoon; } // TSyncSession::sessionMustContinue // returns true if session has pending commands bool TSyncSession::hasPendingCommands(void) { return (!( fNextMessageCommands.size()==0 && // ..no commands to send in next message AND fDelayedExecutionCommands.size()==0 && // ..no commands to process in next message AND fInterruptedCommandP==NULL // ..no interrupted outgoing commands )); } // TSyncSession::hasPendingCommands // finish outgoing Message, returns true if final message of package bool TSyncSession::FinishMessage(bool aAllowFinal, bool aForceNonFinal) { Ret_t err; bool final=true; // finish message if any if (fOutgoingStarted) { // there is an unfinished message, finish it // - final only if no commands waiting for next message // and caller allows final final= !aForceNonFinal && ( fAborted || // if aborted, this is a final message, OR.. (aAllowFinal && !hasPendingCommands()) // ..(if allowed final AND no pending commands) ); // ...THEN this is a final package PDEBUGPRINTFX(DBG_PROTO,( "Ending message with %s%ld next-message/%ld next-package commands: %sFINAL (%sfinal %sallowed by caller)", fInterruptedCommandP ? "interrupted command and " : "", (long)fNextMessageCommands.size(), (long)fNextPackageCommands.size(), final ? "" : "NOT ", fAborted ? "ABORTED, " : "", aAllowFinal ? "" : "not " )); // - close message now sInt32 bytesbeforeissue=getSmlWorkspaceFreeBytes(); fOutgoingStarted=false; // done now fOutgoingMessageFull=false; // message finished, not full any more #ifdef SYDEBUG if (fXMLtranslate && fOutgoingXMLInstance) smlEndMessage(fOutgoingXMLInstance,final); // Now dump XML translation of outgoing message XMLTranslationOutgoingEnd(); #endif if ((err=smlEndMessage(fSmlWorkspaceID, final))!=SML_ERR_OK) { SYSYNC_THROW(TSmlException("smlEndMessage",err)); } incOutgoingMessageSize(bytesbeforeissue-getSmlWorkspaceFreeBytes()); PDEBUGPRINTFX(DBG_PROTO,("Entire message size is now %ld Bytes",(long)getOutgoingMessageSize())); // if outgoing message was not final, prevent session end // except if session is aborted (and final flag is forced nonFinal e.g. when ending session because of serverBusy() if (!final && !fAborted) fInProgress=true; CONSOLEPRINTF(("< SyncML message #%ld sent to '%s'",(long)fOutgoingMsgID,fRespondURI.empty() ? fRemoteURI.c_str() : fRespondURI.c_str())); MP_SHOWCURRENT(DBG_PROFILE,"End of outgoing message"); // dump it if configured #ifdef SYDEBUG DumpSyncMLMessage(true); // outgoing #endif } // if this message ends with , next message will be in new package fNewOutgoingPackage=final; return final; } // TSyncSession::FinishMessage // get name of current encoding const char *TSyncSession::getEncodingName(void) { return SyncMLEncodingMIMENames[fEncoding]; } // TSyncSession::getEncodingName // add current encoding spec to given (type-)string void TSyncSession::addEncoding(string &aString) { aString+=SYNCML_ENCODING_SEPARATOR; aString+=getEncodingName(); } // TSyncSession::addEncoding // set encoding for session void TSyncSession::setEncoding(SmlEncoding_t aEncoding) { Ret_t err=smlSetEncoding(fSmlWorkspaceID,aEncoding); if (err==SML_ERR_OK) { fEncoding = aEncoding; } } // TSyncSession::setEncoding // find remote datastore by (remote party specified) URI TRemoteDataStore *TSyncSession::findRemoteDataStore(const char *aDatastoreURI) { TRemoteDataStorePContainer::iterator pos; TRemoteDataStore *bestMatchP=NULL; uInt16 bestNumMatched=0; // search for BEST match (most number of chars matched) for (pos=fRemoteDataStores.begin(); pos!=fRemoteDataStores.end(); ++pos) { // test for match if ((*pos)->isDatastore(aDatastoreURI) > bestNumMatched) { bestMatchP = *pos; // best so far, but check all } } return bestMatchP; // return NULL if no match found or best matching } // TSyncSession::findRemoteDataStore // - find local datastore by URI and separate identifying from optional part of URI TLocalEngineDS *TSyncSession::findLocalDataStoreByURI(const char *aURI,string *aOptions, string *aIdentifyingURI) { string dburi; // - get relative URI of requested database const char *dblocuri = SessionRelativeURI(aURI); // In this base class implementation, identification is path, options are CGI // - separate target address and CGI (if any) const char *optionsCGI=(const char *)strchr(dblocuri,'?'); if (optionsCGI) { dburi.assign(dblocuri,optionsCGI-dblocuri); optionsCGI++; // skip '?' dblocuri=dburi.c_str(); PDEBUGPRINTFX(DBG_PROTO,("Target Address CGI Options: %s",optionsCGI)); if (aOptions) aOptions->assign(optionsCGI); } else { // no CGI contained if (aOptions) aOptions->erase(); } // assign identifying part of URL now if (aIdentifyingURI) { aIdentifyingURI->assign(dblocuri); } // find datastore now DEBUGPRINTF(("Determined relative, identifying URI (w/o CGI): %s",dblocuri)); return findLocalDataStore(dblocuri); } // TSyncSession::findLocalDataStorebyURI // find local datastore by (relative) URI TLocalEngineDS *TSyncSession::findLocalDataStore(const char *aDatastoreURI) { TLocalDataStorePContainer::iterator pos; for (pos=fLocalDataStores.begin(); pos!=fLocalDataStores.end(); ++pos) { // test for match (we do not do best-match search here because these are names // under our own control that do not contain slashes and hence no // mismatch possibilities like "/Calendar" and "/Calendar/Events" as // with Oracle server. if ((*pos)->isDatastore(aDatastoreURI)) return (*pos); // found } return NULL; // none found } // TSyncSession::findLocalDataStore // - find local datastore by datastore handle (=config pointer) TLocalEngineDS *TSyncSession::findLocalDataStore(void *aDSHandle) { TLocalDataStorePContainer::iterator pos; for (pos=fLocalDataStores.begin(); pos!=fLocalDataStores.end(); ++pos) { // test for match TLocalEngineDS *ldsP = (*pos); if ((void *)(ldsP->getDSConfig())==aDSHandle) return (ldsP); // found } return NULL; // none found } // TSyncSession::findLocalDataStore TLocalEngineDS *TSyncSession::addLocalDataStore(TLocalDSConfig *aLocalDSConfigP) { TLocalEngineDS *ldsP=aLocalDSConfigP->newLocalDataStore(this); fLocalDataStores.push_back(ldsP); return ldsP; } // TSyncSession::addLocalDataStore // - find local datatype by config pointer (used to avoid duplicating types // in session if used by more than a single datastore) TSyncItemType *TSyncSession::findLocalType(TDataTypeConfig *aDataTypeConfigP) { TSyncItemTypePContainer::iterator pos; for (pos=fLocalItemTypes.begin(); pos!=fLocalItemTypes.end(); ++pos) { // test for match if ((void *)((*pos)->getTypeConfig())==aDataTypeConfigP) return (*pos); // found } return NULL; // none found } // TSyncSession::findLocalType // - find implemented remote datatype by config pointer (and related datastore, if any) TSyncItemType *TSyncSession::findRemoteType(TDataTypeConfig *aDataTypeConfigP, TSyncDataStore *aRelatedRemoteDS) { TSyncItemTypePContainer::iterator pos; for (pos=fRemoteItemTypes.begin(); pos!=fRemoteItemTypes.end(); ++pos) { // test for match if ((void *)((*pos)->getTypeConfig())==aDataTypeConfigP) { // match only if related to same datastore or not related if (aRelatedRemoteDS == (*pos)->getRelatedDatastore()) return (*pos); // found } } return NULL; // none found } // TSyncSession::findRemoteType // get new list of all local datastores SmlDevInfDatastoreListPtr_t TSyncSession::newDevInfDataStoreList(bool aAlertedOnly, bool aWithoutCTCapProps) { SmlDevInfDatastoreListPtr_t rootP,*insertpos; SmlDevInfDatastorePtr_t datastoreP; // no list at beginning rootP=NULL; insertpos = &rootP; // go through local datastore list TLocalDataStorePContainer::iterator pos1; for (pos1=fLocalDataStores.begin(); pos1!=fLocalDataStores.end(); ++pos1) { // check if we only want alerted datastore's info (client case) if (aAlertedOnly) { if (!(*pos1)->testState(dssta_clientsentalert)) continue; // not alerted, do not show this one } // see if we have info at all datastoreP = (*pos1)->getDatastoreDevinf(IS_SERVER, aWithoutCTCapProps); if (datastoreP) { // create new list item (*insertpos) = SML_NEW(SmlDevInfDatastoreList_t); (*insertpos)->next = NULL; (*insertpos)->data = datastoreP; // set new insert position insertpos = &((*insertpos)->next); } } return rootP; } // TSyncSession::newDevInfDataStoreList // get common sync capabilities mask of this session (datastores might modify it) uInt32 TSyncSession::getSyncCapMask(void) { return SCAP_MASK_NORMAL | (getSessionConfig()->fAcceptServerAlerted ? SCAP_MASK_SERVER_ALERTED : 0); } // TSyncSession::getSyncCapMask // get new list of all local item types SmlDevInfCtcapListPtr_t TSyncSession::newLocalCTCapList(bool aAlertedOnly, TLocalEngineDS *aOnlyForDS, bool aWithoutCTCapProps) { SmlDevInfCtcapListPtr_t rootP,*insertpos; SmlDevInfCTCapPtr_t ctcapP; // no list at beginning rootP=NULL; insertpos = &rootP; bool showTy; TTypeVariantDescriptor variantDesc = NULL; // go through local datastore list // Note: rulematch types should normally not be shown, but the way to do that // is not some testing here (which is almost impossible), but profiles // defined for rulematch types should be made invisible. TSyncItemTypePContainer::iterator pos2; TLocalDataStorePContainer::iterator pos1; for (pos2=fLocalItemTypes.begin(); pos2!=fLocalItemTypes.end(); ++pos2) { showTy=true; // check for restriction to certain datastore if (aOnlyForDS) { // only show if specified datastore is using the type showTy = aOnlyForDS->doesUseType(*pos2, &variantDesc); } // see if datatype is used by any of the alerted datastores if (showTy && aAlertedOnly) { showTy=false; for (pos1=fLocalDataStores.begin(); pos1!=fLocalDataStores.end(); ++pos1) { // check if we only want alerted datastore's info (client case) if (!(*pos1)->testState(dssta_clientsentalert)) continue; // test next // see if datatype is used by this datastore if ((*pos1)->doesUseType(*pos2)) { showTy=true; break; } } } // now show if selected if (showTy) { // see if we have info at all ctcapP = (*pos2)->getCTCapDevInf(aOnlyForDS, variantDesc, aWithoutCTCapProps); if (ctcapP) { // create new list item (*insertpos) = SML_NEW(SmlDevInfCtcapList_t); (*insertpos)->next = NULL; (*insertpos)->data = ctcapP; // set new insert position insertpos = &((*insertpos)->next); } } } return rootP; } // TSyncSession::newLocalCTCapList // build DevInf of this session SmlDevInfDevInfPtr_t TSyncSession::newDevInf(bool aAlertedOnly, bool aWithoutCTCapProps) { SmlDevInfDevInfPtr_t devinfP; // Create empty DevInf devinfP = SML_NEW(SmlDevInfDevInf_t); // Fill in information for current session devinfP->verdtd=newPCDataString(SyncMLVerDTDNames[fSyncMLVersion]); // - identification of this SyncML implementation devinfP->man=newPCDataOptString(getSyncAppBase()->getManufacturer().c_str()); devinfP->mod=newPCDataOptString(getSyncAppBase()->getModel().c_str()); devinfP->oem=newPCDataOptString(getSyncAppBase()->getOEM()); devinfP->swv=newPCDataOptString(getSyncAppBase()->getSoftwareVersion()); // - identification of the device ID and type (server/client etc.) devinfP->devid=newPCDataString(getDeviceID().c_str()); devinfP->devtyp=newPCDataString(getDeviceType().c_str()); // - identification of the platform the software runs on devinfP->hwv=newPCDataOptString(getSyncAppBase()->getHardwareVersion().c_str()); devinfP->fwv=newPCDataOptString(getSyncAppBase()->getFirmwareVersion().c_str()); // Now get info for content capabilities if (fSyncMLVersionctcap=newLocalCTCapList(aAlertedOnly, NULL, aWithoutCTCapProps); } else devinfP->ctcap=NULL; // no global CTCap any more at devInf level // Now get info for datastores devinfP->datastore=newDevInfDataStoreList(aAlertedOnly, aWithoutCTCapProps); // SyncML 1.1 related flags devinfP->flags=0; // no SyncML 1.1 flags by default if (fSyncMLVersion>=syncml_vers_1_1) { // - we can always parse number of changes (whether we can make use of it is irrelevant) devinfP->flags |= SmlDevInfNOfM_f; // - check if we support UTC based time (implementations with no means to obtain time zone might not) if (canHandleUTC()) devinfP->flags |= SmlDevInfUTC_f; // we can handle UTC // - we support large object devinfP->flags |= SmlDevInfLargeObject_f; } // Now get extensions info devinfP->ext=NULL; // %%% tdb, optional // return return devinfP; } // TSyncSession::newDevInf // get devInf for this session (caller is passed ownership) SmlItemPtr_t TSyncSession::getLocalDevInfItem(bool aAlertedOnly, bool aWithoutCTCapProps) { // - create item with correct source and Meta information SmlItemPtr_t devinf = newItem(); // %%% if strictly following example in SyncML protocol specs, // source should not have a Displayname //fLocalDevInfItemP->source=newLocation(SYNCML_DEVINF_LOCURI,SYNCML_DEVINF_LOCNAME); // %%% if strictly following example in SyncML protocol specs, // source should not have "./" prefix // %%% this is disputable, DCM expects ./, so we send it again now devinf->source=newLocation(SyncMLDevInfNames[fSyncMLVersion]); // - create meta type /* %%% if strictly following example in SyncML protocol specs, meta * must be defined in the result/put command, not the individual item string metatype=SYNCML_DEVINF_META_TYPE; addEncoding(metatype); fLocalDevInfItemP->meta=newMetaType(metatype.c_str()); %%% */ // - create DevInf PCData devinf->data = SML_NEW(SmlPcdata_t); devinf->data->contentType=SML_PCDATA_EXTENSION; devinf->data->extension=SML_EXT_DEVINF; // - %%% assume length is not relevant for structured content (looks like in mgrutil.c) devinf->data->length=0; // - create and insert DevInf devinf->data->content = newDevInf(aAlertedOnly, aWithoutCTCapProps); // - done return devinf; } // TSyncSession::getLocalDevInfItem // analyze remote devinf delivered by Put or Get/Result commands // or loaded from cache by loadRemoteDevInf() localstatus TSyncSession::analyzeRemoteDevInf( SmlDevInfDevInfPtr_t aDevInfP ) { localstatus sta = LOCERR_OK; PDEBUGBLOCKDESC("DevInf_Analyze","Analyzing remote devInf"); if (!aDevInfP) { PDEBUGPRINTFX(DBG_ERROR,("Warning: No DevInf found (possible cause: improperly encoded devInf from remote)")); sta=400; // no devInf goto done; } else { // we have seen the devinf now fRemoteDevInfKnown=true; // analyze what device we have here PDEBUGPRINTFX(DBG_REMOTEINFO+DBG_HOT,( "Device ID='%" FMT_LENGTH(".50") "s', Type='%" FMT_LENGTH(".20") "s', Model='%" FMT_LENGTH(".50") "s'", FMT_LENGTH_LIMITED(50,smlPCDataToCharP(aDevInfP->devid)), FMT_LENGTH_LIMITED(20,smlPCDataToCharP(aDevInfP->devtyp)), FMT_LENGTH_LIMITED(50,smlPCDataToCharP(aDevInfP->mod)) )); PDEBUGPRINTFX(DBG_REMOTEINFO+DBG_HOT,( "Manufacturer='%" FMT_LENGTH(".30") "s', OEM='%" FMT_LENGTH(".30") "s'", FMT_LENGTH_LIMITED(30,smlPCDataToCharP(aDevInfP->man)), FMT_LENGTH_LIMITED(30,smlPCDataToCharP(aDevInfP->oem)) )); PDEBUGPRINTFX(DBG_REMOTEINFO+DBG_HOT,( "Softwarevers='%" FMT_LENGTH(".30") "s', Firmwarevers='%" FMT_LENGTH(".30") "s', Hardwarevers='%" FMT_LENGTH(".30") "s'", FMT_LENGTH_LIMITED(30,smlPCDataToCharP(aDevInfP->swv)), FMT_LENGTH_LIMITED(30,smlPCDataToCharP(aDevInfP->fwv)), FMT_LENGTH_LIMITED(30,smlPCDataToCharP(aDevInfP->hwv)) )); #ifndef MINIMAL_CODE // get the devinf details 1:1 fRemoteDevInf_devid=smlPCDataToCharP(aDevInfP->devid); fRemoteDevInf_devtyp=smlPCDataToCharP(aDevInfP->devtyp); fRemoteDevInf_mod=smlPCDataToCharP(aDevInfP->mod); fRemoteDevInf_man=smlPCDataToCharP(aDevInfP->man); fRemoteDevInf_oem=smlPCDataToCharP(aDevInfP->oem); fRemoteDevInf_swv=smlPCDataToCharP(aDevInfP->swv); fRemoteDevInf_fwv=smlPCDataToCharP(aDevInfP->fwv); fRemoteDevInf_hwv=smlPCDataToCharP(aDevInfP->hwv); // get the descriptive name of the device fRemoteDescName.assign(smlPCDataToCharP(aDevInfP->man)); if (fRemoteDescName.size()>0) fRemoteDescName+=" "; fRemoteDescName.append(smlPCDataToCharP(aDevInfP->mod)); // get extra info: "Type (HWV, FWV, SWV) Oem" fRemoteInfoString+=fRemoteDevInf_devtyp; fRemoteInfoString+=" ("; fRemoteInfoString+=fRemoteDevInf_hwv; fRemoteInfoString+=", "; fRemoteInfoString+=fRemoteDevInf_fwv; fRemoteInfoString+=", "; fRemoteInfoString+=fRemoteDevInf_swv; fRemoteInfoString+=") "; fRemoteInfoString+=fRemoteDevInf_oem; #endif // Show SyncML version here (again) PDEBUGPRINTFX(DBG_REMOTEINFO+DBG_HOT,("SyncML Version: %s",SyncMLVerProtoNames[fSyncMLVersion])); // check SyncML 1.1 flags if (fSyncMLVersion>=syncml_vers_1_1) { // - check if remote can receive NOC (number of changes) fRemoteWantsNOC = (aDevInfP->flags & SmlDevInfNOfM_f); // - check if remote can handle UTC time fRemoteCanHandleUTC = (aDevInfP->flags & SmlDevInfUTC_f); // - check if remote supports large objects fRemoteSupportsLargeObjects = (aDevInfP->flags & SmlDevInfLargeObject_f); PDEBUGPRINTFX(DBG_REMOTEINFO+DBG_HOT,( "SyncML capability flags: wantsNOC=%s, canHandleUTC=%s, supportsLargeObjs=%s", aDevInfP->flags & SmlDevInfNOfM_f ? "Yes" : "No", aDevInfP->flags & SmlDevInfUTC_f ? "Yes" : "No", aDevInfP->flags & SmlDevInfLargeObject_f ? "Yes" : "No" )); } // detect remote specific server behaviour if needed SmlDevInfDevInfPtr_t CTCapDevInfP = aDevInfP; sta = checkRemoteSpecifics(aDevInfP, &CTCapDevInfP); if (sta!=LOCERR_OK) { remoteAnalyzed(); // analyzed to reject goto done; } // switch to DevInf provided by remote rules if (CTCapDevInfP != aDevInfP) { PDEBUGPRINTFX(DBG_REMOTEINFO,("using CTCaps provided in DevInf of remote rule")); aDevInfP = CTCapDevInfP; } // Types and datastores may not be changed/added if sync has allready started if (fRemoteDevInfLock) { // Sync already started, in "blind" mode or previously received devInf, // do not confuse things with changing devInf in mid-sync PDEBUGPRINTFX(DBG_ERROR,( "WARNING: Type and Datastore info in DevInf ignored because it came to late" )); } else { if (getSyncMLVersion()ctcap; // loop through list PDEBUGBLOCKDESC("RemoteTypes", "Analyzing remote types listed in devInf level CTCap"); if (fIgnoreCTCap) { // ignore CTCap if (ctlP) { PDEBUGPRINTFX(DBG_REMOTEINFO+DBG_HOT,("Remote rule prevents looking at CTCap")); } } else { while (ctlP) { if (ctlP->data) { // create appropriate remote data itemtypes if (TSyncItemType::analyzeCTCapAndCreateItemTypes( this, NULL, // this is the pre-DS1.2 style where CTCap is on devInf level ctlP->data, // CTCap fLocalItemTypes, // look up in local types for specialized classes fRemoteItemTypes // add new item types here )) { // we have CTCap info of at least one remote type fRemoteDataTypesKnown=true; } else { PDEBUGPRINTFX(DBG_ERROR,("CTCap could not be used (missing version)")); sta=500; } } // - go to next item ctlP=ctlP->next; } // while } PDEBUGENDBLOCK("RemoteTypes"); } // if datastore; while(dslP) { if (dslP->data) { // we have DataStore info of remote datastores fRemoteDataStoresKnown=true; // there is a DataStore entry, create RemoteDataStore for it TRemoteDataStore *datastoreP; MP_NEW(datastoreP,DBG_OBJINST,"TRemoteDataStore",TRemoteDataStore(this)); PDEBUGBLOCKDESC("RemoteDSDevInf", "Registering remote Datastore from devInf"); // let new datastore analyze the devinf data if (!datastoreP->setDatastoreDevInf( dslP->data, fLocalItemTypes, // look up for datatypes here first fRemoteItemTypes // but add types here )) { // invalid CTCap PDEBUGPRINTFX(DBG_ERROR,("Invalid DataStore devInf")); delete datastoreP; // forget invalid data store sta=500; // failed } else { // CTCap set successfully, new type created // - save it in the list of remote types fRemoteDataStores.push_back(datastoreP); } PDEBUGENDBLOCK("RemoteDSDevInf"); } // - go to next item dslP=dslP->next; } // while PDEBUGENDBLOCK("RemoteDatastores"); } // else sync not started yet } // give descendants possibility to do something with the analyzed data remoteAnalyzed(); // ok done: PDEBUGENDBLOCK("DevInf_Analyze"); return sta; } // TSyncSession::analyzeRemoteDevInf #ifdef SYSYNC_SERVER // Initialize Sync: set up datastores and types for server sync session localstatus TSyncSession::initSync( const char *aLocalDatastoreURI, const char *aRemoteDatastoreURI ) { localstatus sta = LOCERR_OK; // search for local datastore first string cgiOptions; // - search for datastore and obtain possible CGI; // fallback to remote datastore URI is for Sony Ericsson C510, // which sends an empty target (= local) URI (also needs // to be done in Alert handling) fLocalSyncDatastoreP = findLocalDataStoreByURI(SessionRelativeURI((!aLocalDatastoreURI || !aLocalDatastoreURI[0]) ? aRemoteDatastoreURI : aLocalDatastoreURI),&cgiOptions); PDEBUGPRINTFX(DBG_DATA,("initSync: setting fLocalSyncDatastoreP")); if (!fLocalSyncDatastoreP) { // no such local datastore return 404; } // Local datastore is known here (fLocalSyncDatastoreP) // - now init for reception of syncops sta = fLocalSyncDatastoreP->engInitForSyncOps(aRemoteDatastoreURI); #ifdef SYNCML_TAF_SUPPORT if (sta==LOCERR_OK) { // - make sure that options are reparsed (TAF *might* change from Sync request to Sync request) sta = fLocalSyncDatastoreP->engParseOptions( cgiOptions.c_str(), true // we are parsing options from target URI ); } #endif #ifdef OBJECT_FILTERING if (sta==LOCERR_OK) { // %%% check for DS 1.2 in command as well (we do parse in already) #if (!defined _MSC_VER || defined WINCE) && !defined(__GNUC__) #warning "tbd %%%: check for DS 1.2 in command as well (we do parse in already)" #endif } #endif #ifdef OBJECT_FILTERING // Show filter summary #ifdef SYDEBUG #ifdef SYNCML_TAF_SUPPORT PDEBUGPRINTFX(DBG_FILTER,("TAF (temporary, INCLUSIVE) Filter : %s",fLocalSyncDatastoreP->fTargetAddressFilter.c_str())); #endif // SYNCML_TAF_SUPPORT PDEBUGPRINTFX(DBG_FILTER,("SyncSet (dynamic, EXCLUSIVE) Filter : %s",fLocalSyncDatastoreP->fSyncSetFilter.c_str())); #ifdef SYSYNC_TARGET_OPTIONS string ts; StringObjTimestamp(ts,fLocalSyncDatastoreP->fDateRangeStart); PDEBUGPRINTFX(DBG_FILTER,("Date Range Start : %s",fLocalSyncDatastoreP->fDateRangeStart ? ts.c_str() : "")); StringObjTimestamp(ts,fLocalSyncDatastoreP->fDateRangeEnd); PDEBUGPRINTFX(DBG_FILTER,("Date Range End : %s",fLocalSyncDatastoreP->fDateRangeEnd ? ts.c_str() : "")); #endif // SYSYNC_TARGET_OPTIONS #endif // SYDEBUG #endif // OBJECT_FILTERING // return status return sta; } // TSyncSession::initSync #endif // SYSYNC_SERVER // end sync group (of client sync commands) bool TSyncSession::processSyncEnd(bool &aQueueForLater) { bool ok=true; // inform local if (fLocalSyncDatastoreP) { // let datastore process it ok=fLocalSyncDatastoreP->engProcessSyncCmdEnd(aQueueForLater); } // end Sync bracket #ifdef SYNCSTATUS_AT_SYNC_CLOSE // %%% status for sync command sent AFTER statuses for contained commands if (fSyncCloseStatusCommandP) issueRoot(fSyncCloseStatusCommandP); #endif // no local datastore active fLocalSyncDatastoreP=NULL; PDEBUGPRINTFX(DBG_DATA,("processSyncEnd: unsetting fLocalSyncDatastoreP")); return ok; } // TSyncSession::processSyncEnd // process generic sync command item within Sync group // - returns true (and unmodified or non-200-successful status) if // operation could be processed regularily // - returns false (but probably still successful status) if // operation was processed with internal irregularities, such as // trying to delete non-existant item in datastore with // incomplete Rollbacks (which returns status 200 in this case!). bool TSyncSession::processSyncOpItem( TSyncOperation aSyncOp, // the operation SmlItemPtr_t aItemP, // the item to be processed SmlMetInfMetInfPtr_t aMetaP, // command-wide meta, if any TLocalEngineDS *aLocalSyncDatastore, // the local datastore for this syncop item TStatusCommand &aStatusCommand, // pre-set 200 status, can be modified in case of errors bool &aQueueForLater // must be set if item cannot be processed now, but must be processed later ) { // assign datastore context (%%% note: some day we will get rid of this // "global" pointer to the active datastore by moving it into the command // object and installing a hierarchical command processor.) fLocalSyncDatastoreP=aLocalSyncDatastore; PDEBUGPRINTFX(DBG_DATA,("processSyncOpItem: setting fLocalSyncDatastoreP")); // Server mode: commands affect datastores currently in sync if (!fLocalSyncDatastoreP) { // sync generic command outside sync bracket -> error aStatusCommand.setStatusCode(403); // forbidden ADDDEBUGITEM(aStatusCommand,"Add/Copy/Replace/Delete unrelated to datastores"); PDEBUGPRINTFX(DBG_ERROR,("Add/Copy/Replace/Delete unrelated to datastores")); // no success return false; } // check for aborted datastore if (fLocalSyncDatastoreP->CheckAborted(aStatusCommand)) return false; // check if we can process it now // Note: request time limit is active in server only. if (!fLocalSyncDatastoreP->engIsStarted(false) || RemainingRequestTime()<0) { aQueueForLater=true; // re-execute later... return true; // ...but otherwise ok } // process Sync operation sent by remote // - show PDEBUGPRINTFX(DBG_DATA,( "Remote sent %s-operation:", SyncOpNames[aSyncOp] )); PDEBUGPRINTFX(DBG_DATA,( "- Source: remoteID ='%s', remoteName='%s'", smlSrcTargLocURIToCharP(aItemP->source), smlSrcTargLocNameToCharP(aItemP->source) )); PDEBUGPRINTFX(DBG_DATA,( "- Target: localID ='%s', remoteName='%s'", smlSrcTargLocURIToCharP(aItemP->target), smlSrcTargLocNameToCharP(aItemP->target) )); // now let datastore handle it bool regular = fLocalSyncDatastoreP->engProcessSyncOpItem(aSyncOp, aItemP, aMetaP, aStatusCommand); TSyError statuscode = aStatusCommand.getStatusCode(); if (statuscode == LOCERR_AGAIN) { if (fStrictExecOrdering) { // Cannot reorder commands, so force execution now. If we had a way of // telling the store that it should not use LOCERR_AGAIN, we could // avoid this unnecessary "delay + flush" for each item. PDEBUGPRINTFX(DBG_DATA,("Re-executing %s-operation because is on.", SyncOpNames[aSyncOp])); regular = fLocalSyncDatastoreP->engProcessSyncOpItem(aSyncOp, aItemP, aMetaP, aStatusCommand); statuscode = aStatusCommand.getStatusCode(); } else { PDEBUGPRINTFX(DBG_DATA,("Queueing %s-operation for later.", SyncOpNames[aSyncOp])); aQueueForLater=true; // re-execute later... return true; // ...but otherwise ok } } #ifdef SCRIPT_SUPPORT // let script check status code if the operation completed TErrorFuncContext errctx; errctx.statuscode = statuscode; errctx.newstatuscode = errctx.statuscode; errctx.syncop = aSyncOp; errctx.datastoreP = fLocalSyncDatastoreP; // call script regular = TScriptContext::executeTest( regular, // pass through regular status fSessionScriptContextP, getSessionConfig()->fReceivedItemStatusScript, &ErrorFuncTable, &errctx // caller context ); // not completely handled, use possibly modified status code #ifdef SYDEBUG if (aStatusCommand.getStatusCode() != errctx.newstatuscode) { PDEBUGPRINTFX(DBG_ERROR,("Status: Session Script changed original status=%hd to %hd (original op was %s)",aStatusCommand.getStatusCode(),errctx.newstatuscode,SyncOpNames[errctx.syncop])); } #endif aStatusCommand.setStatusCode(errctx.newstatuscode); #endif // check status if (!regular) { localstatus sta=aStatusCommand.getStatusCode(); if (sta>=300 && sta!=419) { // conflict resolved with server data is not an error PDEBUGPRINTFX(DBG_ERROR,( "processSyncOpItem: Error while processing item, status=%hd", aStatusCommand.getStatusCode() )); fLocalSyncDatastoreP->fLocalItemsError++; // count this as an error, as remote will see it as such } else { PDEBUGPRINTFX(DBG_DATA+DBG_HOT,( "processSyncOpItem: Irregularity while processing item, status=%hd", aStatusCommand.getStatusCode() )); } } // done return regular; } // TSyncSession::processSyncOpItem #endif // not SYNCSESSION_PART2_EXCLUDE #ifndef SYNCSESSION_PART1_EXCLUDE // generate challenge for session SmlChalPtr_t TSyncSession::newSessionChallenge(void) { string nonce; getNextNonce(fRemoteURI.c_str(),nonce); PDEBUGPRINTFX(DBG_PROTO,( "Challenge for next auth: AuthType=%s, Nonce='%s', binary %sallowed", authTypeSyncMLNames[requestedAuthType()], nonce.c_str(), getEncoding()==SML_WBXML ? "" : "NOT " )); return newChallenge(requestedAuthType(),nonce,getEncoding()==SML_WBXML); } // TSyncSession::newSessionChallenge // generate credentials (based on fRemoteNonce, fRemoteRequestedAuth, fRemoteRequestedAuthEnc) SmlCredPtr_t TSyncSession::newCredentials(const char *aUser, const char *aPassword) { SmlCredPtr_t credP = NULL; SmlMetInfMetInfPtr_t metinfP = NULL; uInt8 *authdata = NULL; void *tobefreed = NULL; uInt32 authdatalen=0; bool isbinary=false; uInt8 digest[16]; // for MD5 digest // create auth data // - build basic user/pw string string userpw; userpw.assign(aUser); userpw+=':'; userpw.append(aPassword); // - code auth data switch (fRemoteRequestedAuth) { case auth_basic: // Note: this has been clarified in SyncML 1.1: even if B64 is inherent for // Basic auth, specifying B64 as format does NOT mean that user:pw is B64-ed twice, // but it is just an optional declaration of the inherent B64 format. #ifdef BASIC_AUTH_HAS_INHERENT_B64 // %%% seems to be wrong according to SCTS... // Note that the b64 here is PART OF THE BASIC AUTH SCHEME // so format MUST NOT specify b64 again! fRemoteRequestedAuthEnc=fmt_chr; // make b64 of string authdata=(uInt8 *)b64::encode((const uInt8 *)userpw.c_str(), userpw.size(), &authdatalen); tobefreed=(void *)authdata; // remember to free at end of routine #else // basic auth is always b64 encoded fRemoteRequestedAuthEnc=fmt_b64; authdata=(uInt8 *)userpw.c_str(); #endif break; case auth_md5: // Note that b64 encoding IS NOT part of the MD5 auth scheme. // Only if remote specifies b64 format in challenge, b64 encoding is applied if (fSyncMLVersion=syncml_vers_1_1) { // starting with 1.1, nonce is added to b64ed-MD5 and the MD5ed again // - B64 it authdata=(uInt8*)b64::encode(digest, 16, &authdatalen); // - MD5 it while adding nonce md5::Init (&context); md5::Update (&context, authdata, authdatalen); b64::free((void *)authdata); // return buffer allocated by b64::encode // - important: add colon as nonce separator md5::Update (&context, (uInt8 *) ":", 1); // - also add nonce that will be used for checking later md5::Update (&context, (uInt8 *) fRemoteNonce.c_str(), fRemoteNonce.size()); // - this is the MD5 auth value // according to SyncML 1.1, // "changes_for_syncml_represent_v11_20020215.pdf", Section 2.19 md5::Final (digest, &context); // - according to the above mentioned section 2.19, MD5 auth is // always b64 encoded, even in binary transports. This is a // contradiction to discussion in syncml@yahoogroups, particularily // a statement by Peter Thompson who stated that MD5 auth MUST NOT // be b64 encoded in WBXML. Who knows??? fRemoteRequestedAuthEnc=fmt_b64; } // syncml 1.1 // auth data is 16 byte digest value in binary authdata=(uInt8 *)digest; authdatalen=16; isbinary=true; break; default : break; } // switch if (authdata) { // create cred credP = SML_NEW(SmlCred_t); // now add auth data (format if necessary) // - force b64 anyway if content is binary but transport isn't if (isbinary && getEncoding()==SML_XML) { fRemoteRequestedAuthEnc=fmt_b64; isbinary=false; } // - create formatted version of content. Use Opaque for binary content credP->data=newPCDataFormatted(authdata,authdatalen,fRemoteRequestedAuthEnc,isbinary); // create meta and get pointer credP->meta=newMeta(); metinfP = smlPCDataToMetInfP(credP->meta); // add auth type meta metinfP->type=newPCDataString(authTypeSyncMLNames[fRemoteRequestedAuth]); // Note: aEncType==fmt_chr will not add format tag, as fmt_chr is the default metinfP->format=newPCDataFormat(fRemoteRequestedAuthEnc,false); // no format if default of fmt_chr } // free buffer if (tobefreed) b64::free(tobefreed); // return cred or NULL if none return credP; } // TSyncSession::newCredentials // check credentials // Note: should be called even if there are no credentials, as we // need a Session login BEFORE generating status with next Nonce bool TSyncSession::checkCredentials(const char *aUserName, const SmlCredPtr_t aCredP, TStatusCommand &aStatusCommand) { TAuthTypes authtype=auth_basic; // default to basic char *tobefreed = NULL; const char *authdata = NULL; TFmtTypes authfmt = fmt_chr; bool authok = false; #ifdef EXPIRES_AFTER_DATE // check for hard expiry again if ( (fCopyOfScrambledNow>(SCRAMBLED_EXPIRY_VALUE*4+503)) #ifdef SYSER_REGISTRATION && (!getSyncAppBase()->fRegOK) // only abort if no registration (but accept timed registration) #endif ) { aStatusCommand.setStatusCode(401); // seems to be hacked return false; } #endif // Check type of credentials if (!aCredP) { // Anonymous login attempt authtype=auth_none; } else { SmlMetInfMetInfPtr_t metaP; if ((metaP=smlPCDataToMetInfP(aCredP->meta))!=NULL) { // look for type if (metaP->type) { // get type (otherwise default to auth-basic) const char *ty = smlPCDataToCharP(metaP->type); sInt16 t; if (StrToEnum(authTypeSyncMLNames,numAuthTypes,t,ty)) { authtype=(TAuthTypes)t; } else { // bad auth schema authtype=auth_none; // disable checking below aStatusCommand.setStatusCode(406); // unsupported optional feature (auth method) aStatusCommand.addItemString(ty); // identify bad auth method } } // look for format // - get format if (!smlPCDataToFormat(metaP->format,authfmt)) { authtype=auth_none; // disable checking below aStatusCommand.setStatusCode(415); // unsupported format aStatusCommand.addItemString(smlPCDataToCharP(metaP->format)); // identify bad format } // - handle format and get auth data according to auth type authdata = smlPCDataToCharP(aCredP->data); // get it as is // Now check auth switch (authtype) { case auth_none: // anonymous login attempt // - no special measure needed break; case auth_basic: // basic is always b64 encoded #ifdef SYDEBUG if (authfmt!=fmt_b64) PDEBUGPRINTFX(DBG_ERROR,("Auth-basic has no b64 spec --> assumed b64 anyway")); #endif authfmt=fmt_b64; // basic is ALWAYS b64 break; case auth_md5: // verify that we have the username in clear text for MD5 auth if (!aUserName || *aUserName==0) { // username missing, probably strict (bad) SyncML 1.0 conformance, // we need SyncML 1.0.1 corrected auth (MD5 w/o username is almost // impossible to process) authtype=auth_none; // disable checking below aStatusCommand.setStatusCode(415); // unsupported format ADDDEBUGITEM(aStatusCommand,"Missing clear-text username in Source LocName (SyncML 1.0.1)"); PDEBUGPRINTFX(DBG_ERROR,("Missing clear-text username in Source LocName (SyncML 1.0.1)")); break; } // MD5 can come as binary (for WBXML) if (getEncoding()==SML_WBXML) { if (authfmt==fmt_chr || authfmt==fmt_bin) { // assume unencoded MD5 digest (16 bytes binary), make b64 uInt32 l; tobefreed=b64::encode((uInt8 *)authdata,16,&l); authdata=tobefreed; // now authdata is b64 as well authfmt=fmt_b64; } } break; case numAuthTypes: // invalid type?! break; } } // if meta } #ifndef MINIMAL_CODE // save user name for later reference if (aUserName) fSyncUserName.assign(aUserName); else fSyncUserName.erase(); #endif // check credentials if (authtype==auth_none) { // check if we can login anonymously // NOTE: do it anyway, even if !isAuthTypeAllowed() to make sure // SessionLogin is called authok=checkCredentials(aUserName,NULL,auth_none); if (!authok || !isAuthTypeAllowed(auth_none)) { // anonymous login not possible, request credentials aStatusCommand.setStatusCode(407); // unauthorized, missing credentials PDEBUGPRINTFX(DBG_PROTO,("Authorization required but none found in SyncHdr, sending status 407 + chal")); // - add challenge aStatusCommand.setChallenge(newSessionChallenge()); authok=false; } } else { // verify format (must be MD5 by now) if (authfmt!=fmt_b64) { aStatusCommand.setStatusCode(415); // unsupported format } else if (!authdata || !*authdata) { aStatusCommand.setStatusCode(400); // missing data, malformed request } else { // first check credentials // NOTE: This must be done first, to force calling SessionLogin // in all cases authok=checkCredentials(aUserName,authdata,authtype); // now check result if (!isAuthTypeAllowed(authtype)) { aStatusCommand.setStatusCode(401); // we need another auth type, tell client which one authok=false; // anyway, reject PDEBUGPRINTFX(DBG_ERROR,("Authorization failed (wrong type of creds), sending 401 + chal")); } else if (!authok) { // auth type allowed, but auth itself not ok aStatusCommand.setStatusCode(401); // unauthorized, bad credentials PDEBUGPRINTFX(DBG_ERROR,("Authorization failed (invalid credentials) sending 401 + chal")); } if (!authok) { // - add challenge aStatusCommand.setChallenge(newSessionChallenge()); } } } // free buffer if any if (tobefreed) b64::free(tobefreed); // make sure we see what config was used in the log DebugShowCfgInfo(); PDEBUGPRINTFX(DBG_HOT,( "==== Authorisation %s with SyncML Engine Version %d.%d.%d.%d", authok ? "successful" : "failed", SYSYNC_VERSION_MAJOR, SYSYNC_VERSION_MINOR, SYSYNC_SUBVERSION, SYSYNC_BUILDNUMBER )); if (IS_SERVER) { #ifdef SYSYNC_SERVER PDEBUGPRINTFX(DBG_HOT,( "==== SyncML URL used = '%s', username as sent by remote = '%s'", fInitialLocalURI.c_str(), fSyncUserName.c_str() )); #endif } // server // return result return authok; } // TSyncSession::checkCredentials(SmlCredPtr_t...) // check credential string bool TSyncSession::checkCredentials(const char *aUserName, const char *aCred, TAuthTypes aAuthType) { // now check auth if (aAuthType==auth_basic) { // basic auth allows extracting clear-text password string user,password; getAuthBasicUserPass(aCred,user,password); #ifndef MINIMAL_CODE fSyncUserName = user; #endif if (aUserName && !(user==aUserName)) { // username does not match LocName (should, in SyncML 1.0.1 and later) PDEBUGPRINTFX(DBG_PROTO,( "basic_auth encoded username (%s) does not match LocName username (%s)", user.c_str(), aUserName ? aUserName : "[NULL Username]" )); } // we have the password in clear text return SessionLogin(user.c_str(), password.c_str(), sectyp_clearpass, fRemoteURI.c_str()); } else if (aAuthType==auth_md5) { // login user and device to the service // - this is normally implemented in derived classes return SessionLogin(aUserName, aCred, fSyncMLVersion>=syncml_vers_1_1 ? sectyp_md5_V11 : sectyp_md5_V10, fRemoteURI.c_str()); } else if (aAuthType==auth_none) { // even if we have no login, do a "login" with empty credentials return SessionLogin("anonymous", NULL, sectyp_anonymous, fRemoteURI.c_str()); } else { return false; // unknown auth, is not ok } } // TSyncSession::checkCredentials(const char *...) // Helper function: // check plain user / password / nonce combination // against given auth string. bool TSyncSession::checkAuthPlain( const char *aUserName, const char *aPassWord, const char *aNonce, // given values const char *aAuthString, TAuthSecretTypes aAuthStringType // check against this ) { string upw; #ifdef SYDEBUG PDEBUGPRINTFX(DBG_ADMIN,("Username = %s",aUserName)); DEBUGPRINTFX(DBG_USERDATA+DBG_EXOTIC,("Password = %s",aPassWord)); #endif if (aAuthStringType==sectyp_anonymous) { return (aPassWord==NULL || *aPassWord==0); // anonymous login ok if no password expected } else if (aAuthStringType==sectyp_clearpass) { return (strcmp(aAuthString,aPassWord)==0); // login ok if password matches } else { // must be MD5 // - concatenate user:password upw = aUserName; upw+=':'; upw.append(aPassWord); // depends on method if (aAuthStringType==sectyp_md5_V11) { // V1.1 requires MD5b64-ing user/pw before adding nonce MD5B64(upw.c_str(),upw.size(),upw); } // now check result return checkMD5WithNonce(upw.c_str(),aNonce,aAuthString); } // unknown auth secret type return false; } // TSyncSession::checkAuthPlain // Helper function: // check MD5B64(user:pw) / nonce combination // against given auth string. bool TSyncSession::checkAuthMD5( const char *aUserName, const char *aMD5B64, const char *aNonce, // given values const char *aAuthString, TAuthSecretTypes aAuthStringType // check against this ) { if (aAuthStringType==sectyp_md5_V11) { // we have a V11 authstring, check it against our MD5B64(user:pw) return checkMD5WithNonce(aMD5B64,aNonce,aAuthString); } else if (aAuthStringType==sectyp_clearpass) { // we must generate the MD5B64(user:pw) from clear text string myAuthString = aUserName; myAuthString+=':'; myAuthString+=aAuthString; MD5B64(myAuthString.c_str(),myAuthString.size(),myAuthString); #ifdef SYDEBUG PDEBUGPRINTFX(DBG_ADMIN,("MD5B64(user:pw) stored in local DB = %s",aMD5B64)); PDEBUGPRINTFX(DBG_ADMIN,("calculated MD5B64(remoteuser:remotepw) = %s",myAuthString.c_str())); #endif // then we can directly compare them return myAuthString==aMD5B64; } else return false; // we cannot auth V1.0 MD5 against MD5B64(user:password) } // checkAuthMD5 // Helper function: // check V1.1 MD5 type auth against known md5userpass // (B64 encoded MD5 digest of user:password) and nonce // Note: This works only with V1.1-type credentials!!!! bool TSyncSession::checkMD5WithNonce( const char *aStringBeforeNonce, const char *aNonce, const char *aMD5B64Creds ) { string pattern; // pattern to match with // see if user/pw/nonce matches given MD5 // - add nonce to prepared string // For V1.0 this is "user:password" // For >=V1.1 this is MD5B64("user:password") pattern = aStringBeforeNonce; pattern+=':'; pattern.append(aNonce); // - MD5 and B64 entire thing (again) MD5B64(pattern.c_str(),pattern.size(),pattern); #ifdef SYDEBUG DEBUGPRINTFX(DBG_ADMIN ,("String before Nonce = %s",aStringBeforeNonce)); DEBUGPRINTFX(DBG_ADMIN ,("Nonce used = %s",aNonce)); PDEBUGPRINTFX(DBG_ADMIN,("Locally calculated MD5B64 = %s",pattern.c_str())); PDEBUGPRINTFX(DBG_ADMIN,("Received MD5B64 from remote = %s",aMD5B64Creds)); #endif // - now compare with given credentials return strnncmp(aMD5B64Creds,pattern.c_str(),pattern.size())==0; } // TSyncSession::checkMD5WithNonce // helper: get user/password out of basic credential string, returns false if bad cred bool TSyncSession::getAuthBasicUserPass(const char *aBasicCreds, string &aUsername, string &aPassword) { // - convert to user/pw string uInt32 userpwlen; uInt8 *userpw=b64::decode(aBasicCreds, 0, &userpwlen); bool ok=false; if (userpw) { // adjust length if already null terminated if (userpw[userpwlen-1]==0) userpwlen=strlen((char *)userpw); // extract plain-text username first const char *p=strchr((const char *)userpw,':'); if (p) { // save user name aUsername.assign((const char *)userpw,p-(const char *)userpw); // save password aPassword.assign(p+1); ok=true; } } b64::free(userpw); return ok; } // TSyncSession::getAuthBasicUserPass // check credential string (clear text pw, MD5, etc.) // This function is normally derived to provide checking of auth string // Notes: // - all auth requests are resolved using this function. // - For pre-SyncML 1.1 MD5 auth, credentials are checkable only // against plain text passwords. It's up to the derived class to decide if // this is possible or not. bool TSyncSession::SessionLogin( const char *aUserName, const char *aAuthString, TAuthSecretTypes aAuthStringType, const char *aDeviceID ) { string nonce; // get config for session TSessionConfig *scP = getSessionConfig(); // anonymous is always ok (because checking if anonymous allowed is done already) if (aAuthStringType==sectyp_anonymous) return true; // ok // check simple auth if (scP->fSimpleAuthUser.empty()) return false; // no simple auth // check user name if (strucmp(scP->fSimpleAuthUser.c_str(),aUserName)!=0) return false; // wrong user name // now check auth string if (aAuthStringType==sectyp_md5_V10 || aAuthStringType==sectyp_md5_V11) { // we need a nonce getAuthNonce(aDeviceID,nonce); } // now check return checkAuthPlain( scP->fSimpleAuthUser.c_str(), scP->fSimpleAuthPassword.c_str(), nonce.c_str(), aAuthString, aAuthStringType ); } // TSyncSession::SessionLogin // check remote devinf to detect special behaviour needed for some clients (or servers). Base class // does not do anything on server level (configured rules are handled at session level) // - NOTE: aDevInfP can be NULL to specify that remote device has not sent any devInf at all // and this is a blind sync attempt (so best-guess workaround settings might apply) localstatus TSyncSession::checkRemoteSpecifics(SmlDevInfDevInfPtr_t aDevInfP, SmlDevInfDevInfPtr_t *aOverrideDevInfP) { #if defined(SYSER_REGISTRATION) || !defined(NO_REMOTE_RULES) localstatus sta = LOCERR_OK; #endif // check hard-coded restrictions if (aDevInfP && ( false #ifdef REMOTE_RESTR_DEVID || strwildcmp(smlPCDataToCharP(aDevInfP->devid),REMOTE_RESTR_DEVID)!=0 #endif #ifdef REMOTE_RESTR_MAN || strwildcmp(smlPCDataToCharP(aDevInfP->man),REMOTE_RESTR_MAN)!=0 #endif #ifdef REMOTE_RESTR_MOD || strwildcmp(smlPCDataToCharP(aDevInfP->mod),REMOTE_RESTR_MOD)!=0 #endif #ifdef REMOTE_RESTR_OEM || strwildcmp(smlPCDataToCharP(aDevInfP->oem),REMOTE_RESTR_OEM)!=0 #endif #ifdef REMOTE_RESTR_URI || strwildcmp(fRemoteURI.c_str(),REMOTE_RESTR_URI)!=0 #endif )) { PDEBUGPRINTFX(DBG_ERROR,("Software not allowed syncing with this remote party")); AbortSession(403,true); return 403; } // check license restrictions #ifdef SYSER_REGISTRATION sInt16 daysleft; string s; // - get restriction string from licensed info sta = getSyncAppBase()->getAppEnableInfo(daysleft, NULL, &s); string restrid,restrval; const char *p = s.c_str(); // start of license info string while (sta==LOCERR_OK && (p=getSyncAppBase()->getLicenseRestriction(p,restrid,restrval))!=NULL) { const char *restr=NULL; if (restrid=="u") { // URL // we can check the remote URL without having devinf restr=fRemoteURI.c_str(); } else { if (restrid.size()==1) { // there is a restriction if (!aDevInfP) { // we cannot check these restrictions without having a devInf sta = LOCERR_BADREG; PDEBUGPRINTFX(DBG_ERROR,("License restriction needs devInf from remote but none found -> block sync")); break; } // we have devinf, we can check it switch (restrid[0]) { case 'i' : restr=smlPCDataToCharP(aDevInfP->devid); break; case 'm' : restr=smlPCDataToCharP(aDevInfP->man); break; case 't' : restr=smlPCDataToCharP(aDevInfP->mod); break; case 'o' : restr=smlPCDataToCharP(aDevInfP->oem); break; } } } // - now compare with wildcards allowed if we have anything to compare if (restr) sta = strwildcmp(restr,restrval.c_str())==0 ? LOCERR_OK : LOCERR_BADREG; // service unavailable } // - abort if not ok if (sta!=LOCERR_OK) { PDEBUGPRINTFX(DBG_ERROR,("License does not allow syncing with this remote party, status=%hd",sta)); AbortSession(403,true,sta); return sta; } #endif // SYSER_REGISTRATION // check remote rules #ifndef NO_REMOTE_RULES PDEBUGBLOCKDESC("RemoteRules","Checking for remote rules"); // get config for session TSessionConfig *scP = getSessionConfig(); // look if we have matching rule(s) for this device TRemoteRulesList::iterator pos; for(pos=scP->fRemoteRulesList.begin();pos!=scP->fRemoteRulesList.end();pos++) { TRemoteRuleConfig *ruleP = *pos; // compare with devinf (or test for default-rule if aDevInfP is NULL if ( !ruleP->fSubRule && // subrules never apply directly (ruleP->fManufacturer.empty() || (aDevInfP && strwildcmp(smlPCDataToCharP(aDevInfP->man),ruleP->fManufacturer.c_str())==0)) && (ruleP->fModel.empty() || (aDevInfP && strwildcmp(smlPCDataToCharP(aDevInfP->mod),ruleP->fModel.c_str())==0)) && (ruleP->fOem.empty() || (aDevInfP && strwildcmp(smlPCDataToCharP(aDevInfP->oem),ruleP->fOem.c_str())==0)) && (ruleP->fFirmwareVers.empty() || (aDevInfP && ruleP->fFirmwareVers==smlPCDataToCharP(aDevInfP->fwv))) && (ruleP->fSoftwareVers.empty() || (aDevInfP && ruleP->fSoftwareVers==smlPCDataToCharP(aDevInfP->swv))) && (ruleP->fHardwareVers.empty() || (aDevInfP && ruleP->fHardwareVers==smlPCDataToCharP(aDevInfP->hwv))) && (ruleP->fDevId.empty() || (aDevInfP && ruleP->fDevId==smlPCDataToCharP(aDevInfP->devid))) && (ruleP->fDevTyp.empty() || (aDevInfP && ruleP->fDevTyp==smlPCDataToCharP(aDevInfP->devtyp))) ) { // found matching rule PDEBUGPRINTFX(DBG_HOT,("Found '%s' matching for this peer",ruleP->getName())); // remember it fActiveRemoteRules.push_back(ruleP); // add included subrules TRemoteRulesList::iterator spos; for(spos=ruleP->fSubRulesList.begin();spos!=ruleP->fSubRulesList.end();spos++) { fActiveRemoteRules.push_back(*spos); PDEBUGPRINTFX(DBG_HOT,("- rule also activates sub-rule '%s'",(*spos)->getName())); } // if this rule is final, don't check for further matches if (ruleP->fFinalRule) break; } } // process activated rules and subrules for(pos=fActiveRemoteRules.begin();pos!=fActiveRemoteRules.end();pos++) { // activate this rule TRemoteRuleConfig *ruleP = *pos; if (ruleP->fOverrideDevInfP && aOverrideDevInfP) { // processing in caller will continue with updated DevInf *aOverrideDevInfP = ruleP->fOverrideDevInfP; } // - apply options that have a value if (ruleP->fLegacyMode>=0) fLegacyMode = ruleP->fLegacyMode; if (ruleP->fLenientMode>=0) fLenientMode = ruleP->fLenientMode; if (ruleP->fLimitedFieldLengths>=0) fLimitedRemoteFieldLengths = ruleP->fLimitedFieldLengths; if (ruleP->fDontSendEmptyProperties>=0) fDontSendEmptyProperties = ruleP->fDontSendEmptyProperties; if (ruleP->fDoQuote8BitContent>=0) fDoQuote8BitContent = ruleP->fDoQuote8BitContent; if (ruleP->fDoNotFoldContent>=0) fDoNotFoldContent = ruleP->fDoNotFoldContent; if (ruleP->fNoReplaceInSlowsync>=0) fNoReplaceInSlowsync = ruleP->fNoReplaceInSlowsync; if (ruleP->fTreatRemoteTimeAsLocal>=0) fTreatRemoteTimeAsLocal = ruleP->fTreatRemoteTimeAsLocal; if (ruleP->fTreatRemoteTimeAsUTC>=0) fTreatRemoteTimeAsUTC = ruleP->fTreatRemoteTimeAsUTC; if (ruleP->fVCal10EnddatesSameDay>=0) fVCal10EnddatesSameDay = ruleP->fVCal10EnddatesSameDay; if (ruleP->fIgnoreDevInfMaxSize>=0) fIgnoreDevInfMaxSize = ruleP->fIgnoreDevInfMaxSize; if (ruleP->fIgnoreCTCap>=0) fIgnoreCTCap = ruleP->fIgnoreCTCap; if (ruleP->fDSPathInDevInf>=0) fDSPathInDevInf = ruleP->fDSPathInDevInf; if (ruleP->fDSCgiInDevInf>=0) fDSCgiInDevInf = ruleP->fDSCgiInDevInf; if (ruleP->fUpdateClientDuringSlowsync>=0) fUpdateClientDuringSlowsync = ruleP->fUpdateClientDuringSlowsync; if (ruleP->fUpdateServerDuringSlowsync>=0) fUpdateServerDuringSlowsync = ruleP->fUpdateServerDuringSlowsync; if (ruleP->fAllowMessageRetries>=0) fAllowMessageRetries = ruleP->fAllowMessageRetries; if (ruleP->fStrictExecOrdering>=0) fStrictExecOrdering = ruleP->fStrictExecOrdering; if (ruleP->fTreatCopyAsAdd>=0) fTreatCopyAsAdd = ruleP->fTreatCopyAsAdd; if (ruleP->fCompleteFromClientOnly>=0) fCompleteFromClientOnly = ruleP->fCompleteFromClientOnly; if (ruleP->fRequestMaxTime>=0) fRequestMaxTime = ruleP->fRequestMaxTime; if (ruleP->fDefaultOutCharset!=chs_unknown) fDefaultOutCharset = ruleP->fDefaultOutCharset; if (ruleP->fDefaultInCharset!=chs_unknown) fDefaultInCharset = ruleP->fDefaultInCharset; // - possibly override decisions that are otherwise made by session // Note: this is not a single option because we had this before rule options were tristates. if (ruleP->fForceUTC>0) fRemoteCanHandleUTC=true; if (ruleP->fForceLocaltime>0) fRemoteCanHandleUTC=false; // - descriptive name for the device (for log) #ifndef MINIMAL_CODE if (!ruleP->fRemoteDescName.empty()) fRemoteDescName = ruleP->fRemoteDescName; #endif // - test for rejection if (ruleP->fRejectStatusCode!=DONT_REJECT) { // reject operation with this device sta = ruleP->fRejectStatusCode; PDEBUGPRINTFX(DBG_ERROR,("remote party rejected by '%s', status=%hd",ruleP->getName(),sta)); AbortSession(sta,true); return sta; } // - execute rule script #ifdef SCRIPT_SUPPORT if (!ruleP->fRuleScriptTemplate.empty()) { // copy from template string ruleScript = ruleP->fRuleScriptTemplate; // resolve variable references TScriptContext::linkIntoContext(ruleScript,fSessionScriptContextP,this); // execute now PDEBUGPRINTFX(DBG_HOT,("Executing rulescript for rule '%s'",ruleP->getName())); TScriptContext::execute( fSessionScriptContextP, ruleScript, NULL, // context's function table NULL // datastore pointer needed for context ); } #endif } // for all activated rules PDEBUGENDBLOCK("RemoteRules"); // something failed in applying remote rules? if (sta!=LOCERR_OK) return sta; #endif // NO_REMOTE_RULES // Final adjustments #ifndef NO_REMOTE_RULES if (fActiveRemoteRules.empty()) #endif { // no remote rule (none found or mechanism excluded by NO_REMOTE_RULES) if (!aDevInfP) { // no devinf -> blind sync attempt: apply best-guess workaround settings // Note that a blind sync attempt means that the remote party is at least partly non-compliant, as we always request a devInf! PDEBUGPRINTFX(DBG_ERROR,("No remote information available -> applying best-guess workaround behaviour options")); #ifndef MINIMAL_CODE // set device description fRemoteDescName = fRemoteName.empty() ? "[unknown remote]" : fRemoteName.c_str(); fRemoteDescName += " (no devInf)"; #endif // MINIMAL_CODE // switch on legacy behaviour (conservative preferred types) fLegacyMode = true; if (IS_CLIENT) { // Client case fRemoteCanHandleUTC = true; // Assume server can handle UTC (it is very improbable a server can't) } else { // Server case fRemoteCanHandleUTC = fSyncMLVersion==syncml_vers_1_0 ? true : false; // Assume client cannot handle UTC (it is likely a client can't, or at least can't properly, so localtime is safer) fLimitedRemoteFieldLengths = true; // assume limited client field length (almost all clients have limited length) } } } // show summary PDEBUGPRINTFX(DBG_HOT+DBG_REMOTEINFO,("Summary of all behaviour options (possibly modified by remote rule(s))")); #ifndef MINIMAL_CODE PDEBUGPRINTFX(DBG_HOT+DBG_REMOTEINFO,("- Remote Description : %s",fRemoteDescName.c_str())); #endif PDEBUGPRINTFX(DBG_HOT+DBG_REMOTEINFO,("- Legacy mode : %s",boolString(fLegacyMode))); PDEBUGPRINTFX(DBG_HOT+DBG_REMOTEINFO,("- Lenient mode : %s",boolString(fLenientMode))); PDEBUGPRINTFX(DBG_HOT+DBG_REMOTEINFO,("- Limited Field Lengths : %s",boolString(fLimitedRemoteFieldLengths))); PDEBUGPRINTFX(DBG_HOT+DBG_REMOTEINFO,("- Do not send empty props : %s",boolString(fDontSendEmptyProperties))); PDEBUGPRINTFX(DBG_HOT+DBG_REMOTEINFO,("- Quote 8bit content : %s",boolString(fDoQuote8BitContent))); PDEBUGPRINTFX(DBG_HOT+DBG_REMOTEINFO,("- Prevent Content Folding : %s",boolString(fDoNotFoldContent))); PDEBUGPRINTFX(DBG_HOT+DBG_REMOTEINFO,("- No replace in slowsync : %s",boolString(fNoReplaceInSlowsync))); PDEBUGPRINTFX(DBG_HOT+DBG_REMOTEINFO,("- Treat remote TZ as local : %s",boolString(fTreatRemoteTimeAsLocal))); PDEBUGPRINTFX(DBG_HOT+DBG_REMOTEINFO,("- Treat remote TZ as UTC : %s",boolString(fTreatRemoteTimeAsUTC))); PDEBUGPRINTFX(DBG_HOT+DBG_REMOTEINFO,("- Use 23:59:59 end dates : %s",boolString(fVCal10EnddatesSameDay))); PDEBUGPRINTFX(DBG_HOT+DBG_REMOTEINFO,("- Ignore field maxSize : %s",boolString(fIgnoreDevInfMaxSize))); PDEBUGPRINTFX(DBG_HOT+DBG_REMOTEINFO,("- Ignore CTCap : %s",boolString(fIgnoreCTCap))); PDEBUGPRINTFX(DBG_HOT+DBG_REMOTEINFO,("- send DS path in devInf : %s",boolString(fDSPathInDevInf))); PDEBUGPRINTFX(DBG_HOT+DBG_REMOTEINFO,("- send DS CGI in devInf : %s",boolString(fDSCgiInDevInf))); PDEBUGPRINTFX(DBG_HOT+DBG_REMOTEINFO,("- Update Client in slowsync : %s",boolString(fUpdateClientDuringSlowsync))); PDEBUGPRINTFX(DBG_HOT+DBG_REMOTEINFO,("- Update Server in slowsync : %s",boolString(fUpdateServerDuringSlowsync))); PDEBUGPRINTFX(DBG_HOT+DBG_REMOTEINFO,("- Allow message retries : %s",boolString(fAllowMessageRetries))); PDEBUGPRINTFX(DBG_HOT+DBG_REMOTEINFO,("- Strict SyncML exec order : %s",boolString(fStrictExecOrdering))); PDEBUGPRINTFX(DBG_HOT+DBG_REMOTEINFO,("- Treat copy like add : %s",boolString(fTreatCopyAsAdd))); PDEBUGPRINTFX(DBG_HOT+DBG_REMOTEINFO,("- Complete From-Client-Only : %s",boolString(fCompleteFromClientOnly))); PDEBUGPRINTFX(DBG_HOT+DBG_REMOTEINFO,("- Remote can handle UTC : %s",boolString(fRemoteCanHandleUTC))); PDEBUGPRINTFX(DBG_HOT+DBG_REMOTEINFO,("- Max Request time [sec] : %ld",static_cast(fRequestMaxTime))); PDEBUGPRINTFX(DBG_HOT+DBG_REMOTEINFO,("- Content output charset : %s",MIMECharSetNames[fDefaultOutCharset])); PDEBUGPRINTFX(DBG_HOT+DBG_REMOTEINFO,("- Content input charset : %s",MIMECharSetNames[fDefaultInCharset])); // done return LOCERR_OK; } // TSyncSession::checkRemoteSpecifics #ifndef NO_REMOTE_RULES // check if given rule (by name, or if aRuleName=NULL by rule pointer) is active bool TSyncSession::isActiveRule(cAppCharP aRuleName, TRemoteRuleConfig *aRuleP) { TRemoteRulesList::iterator pos; for(pos=fActiveRemoteRules.begin();pos!=fActiveRemoteRules.end();pos++) { if ( (aRuleName==NULL && (*pos)==aRuleP) || // match by pointer... (strucmp(aRuleName,(*pos)->getName())==0) // ...or name ) return true; } // no match return false; } // TSyncSession::isActiveRule #endif // NO_REMOTE_RULES // access to config TSessionConfig *TSyncSession::getSessionConfig(void) { TSessionConfig *scP; GET_CASTED_PTR(scP,TSessionConfig,getSyncAppBase()->getRootConfig()->fAgentConfigP,DEBUGTEXT("no TSessionConfig","sss1")); return scP; } // TSyncSession::getSessionConfig // process a Map command in context of session bool TSyncSession::processMapCommand( SmlMapPtr_t aMapCommandP, // the map command contents TStatusCommand &aStatusCommand, // pre-set 200 status, can be modified in case of errors bool &aQueueForLater ) { // if not overridden, we cannot process Map aStatusCommand.setStatusCode(403); ADDDEBUGITEM(aStatusCommand,"Map command not allowed in this context"); return false; // failed } // TSyncSession::processMapCommand // called to issue custom get and put commands // may issue custom get and put commands void TSyncSession::issueCustomGetPut(bool aGotDevInf, bool aSentDevInf) { #ifdef SCRIPT_SUPPORT // call script that might issue GETs and PUTs // - set up context TGetPutResultFuncContext ctx; ctx.isPut=false; ctx.canIssue=true; ctx.statuscode=0; ctx.itemURI.erase(); ctx.itemData.erase(); ctx.metaType.erase(); // - execute TScriptContext::execute( fSessionScriptContextP, getSessionConfig()->fCustomGetPutScript, &GetPutResultFuncTable, &ctx // caller context ); #endif } // TSyncSession::issueCustomGetPut // called to issue custom put commands at end of session // may issue custom put commands (gets don't make sense at end of a session) void TSyncSession::issueCustomEndPut(void) { #ifdef SCRIPT_SUPPORT // call script that might issue GETs and PUTs // - set up context TGetPutResultFuncContext ctx; ctx.isPut=false; ctx.canIssue=true; ctx.statuscode=0; ctx.itemURI.erase(); ctx.itemData.erase(); ctx.metaType.erase(); // - execute TScriptContext::execute( fSessionScriptContextP, getSessionConfig()->fCustomEndPutScript, &GetPutResultFuncTable, &ctx // caller context ); #endif } // TSyncSession::issueCustomEndPut // called to process unknown get item, may return a Results command. Must set status to non-404 if get could be served // (may be overridden by descendants, only called if no descendant can handle an item) TResultsCommand *TSyncSession::processGetItem(const char *aLocUri, TGetCommand *aGetCommandP, SmlItemPtr_t aGetItemP, TStatusCommand &aStatusCommand) { TResultsCommand *resultsCmdP = NULL; #ifdef SCRIPT_SUPPORT // first check if script handles it // - set up context TGetPutResultFuncContext ctx; ctx.isPut=false; ctx.canIssue=false; ctx.statuscode=aStatusCommand.getStatusCode(); ctx.itemURI=aLocUri; ctx.itemData.erase(); // - get meta type of item, if any AssignString(ctx.metaType,smlMetaTypeToCharP(smlPCDataToMetInfP(aGetItemP->meta))); if (ctx.metaType.empty()) { // none in item, get from command AssignString(ctx.metaType,smlMetaTypeToCharP(smlPCDataToMetInfP(aGetCommandP->getMeta()))); } // - execute bool hasResult = TScriptContext::executeTest( false, // do not assume script handles the GET fSessionScriptContextP, getSessionConfig()->fCustomGetHandlerScript, &GetPutResultFuncTable, &ctx // caller context ); // - update status, anyway aStatusCommand.setStatusCode(ctx.statuscode); // - create result, if script decides so if (hasResult) { // script returns true, so it has handled the GET command // - create a result command (%%% currently GET command itself does not carry src/targ URIs, only item does) resultsCmdP = new TResultsCommand(this,aGetCommandP,NULL,NULL); // - create data item SmlItemPtr_t resItemP = newItem(); // - source is get item's URI reflected (if not changed by script) resItemP->source=newLocation(ctx.itemURI.c_str()); // - data is just string resItemP->data = newPCDataString(ctx.itemData); // - add item to command resultsCmdP->addItem(resItemP); // - set result command meta if not empty string resultsCmdP->setMeta(newMetaType(ctx.metaType.c_str())); // get item handled, return return resultsCmdP; } #endif // look for ./devinf10 special case if (strucmp(aLocUri,SyncMLDevInfNames[getSyncMLVersion()])==0) { // status is ok aStatusCommand.setStatusCode(200); // prepare a devinf10 resultsCmdP = new TDevInfResultsCommand(this,aGetCommandP); } return resultsCmdP; } // TSyncSession::processGetItem // - put and results command processing // (may be overridden by descendants, only called if no descendant can handle an item) void TSyncSession::processPutResultItem(bool aIsPut, const char *aLocUri, TSmlCommand *aPutResultsCommandP, SmlItemPtr_t aPutResultsItemP, TStatusCommand &aStatusCommand) { localstatus sta = aStatusCommand.getStatusCode(); #ifdef SCRIPT_SUPPORT // first check if script handles it // - set up context TGetPutResultFuncContext ctx; ctx.isPut=aIsPut; ctx.canIssue=false; ctx.statuscode=sta; ctx.itemURI=aLocUri; // - get data of item, if any smlPCDataToStringObj(aPutResultsItemP->data,ctx.itemData); // - get meta type of item, if any AssignString(ctx.metaType,smlMetaTypeToCharP(smlPCDataToMetInfP(aPutResultsItemP->meta))); if (ctx.metaType.empty()) { // none in item, get from command AssignString(ctx.metaType,smlMetaTypeToCharP(smlPCDataToMetInfP(aPutResultsCommandP->getMeta()))); } // - execute bool hasProcessed = TScriptContext::executeTest( false, // do not assume script handles the PUT or RESULT fSessionScriptContextP, getSessionConfig()->fCustomPutResultHandlerScript, &GetPutResultFuncTable, &ctx // caller context ); // update status code sta=ctx.statuscode; if (sta!=LOCERR_OK) aStatusCommand.setStatusCode(syncmlError(sta)); // if processed, return now if (hasProcessed) return; #endif // check for ./devinfXX if (strucmp(aLocUri,SyncMLDevInfNames[getSyncMLVersion()])==0) { // remote is sending DevInf, receive it SmlDevInfDevInfPtr_t devinfP = smlPCDataToDevInfP(aPutResultsItemP->data); // save received devinf (if database supports it) saveRemoteDevInf(getRemoteURI(),devinfP); // analyze aStatusCommand.setStatusCode(200); // assume ok sta=analyzeRemoteDevInf(devinfP); if (sta!=LOCERR_OK) aStatusCommand.setStatusCode(syncmlError(sta)); } else { // unknown PDEBUGPRINTFX(DBG_ERROR,( "Unknown %s-command with URI=%s received, returning default status=%hd", aIsPut ? "PUT" : "RESULTS", aLocUri, sta )); } } // TSyncSession::processPutResultItem // process an alert item in context of session // Most handling takes place in derived classes, // this base class only implements basic stuff // - returns command to be issued after issuing status, NULL if none TSmlCommand *TSyncSession::processAlertItem( uInt16 aAlertCode, // alert code SmlItemPtr_t aItemP, // alert item to be processed (as one alert can have multiple items) SmlCredPtr_t aCredP, // alert cred element, if any TStatusCommand &aStatusCommand, // pre-set 200 status, can be modified in case of errors TLocalEngineDS *&aLocalDataStoreP // receives datastore pointer, if alert affects a datastore ) { // no alert response command by default TSmlCommand *alertresponsecmdP=NULL; TLocalEngineDS *datastoreP; string optionsCGI,identifyingTargetURI; // dispatch numeric alerts switch (aAlertCode) { // sync alerts case 200: case 201: case 202: case 203: case 204: case 205: // Sync resume alert case 225: { // Synchronisation initialisation alerts if (allowAlertAfterMap() && fIncomingState==psta_map) { // reset to state that allows a sync to start PDEBUGPRINTFX(DBG_HOT,("process alert: restart sync")); fIncomingState = psta_init; fOutgoingState = psta_init; fRestarting = true; } // - test if context is ok if (fIncomingState!=psta_init && fIncomingState!=psta_initsync) { // Sync alert only allowed in init package or combined init/sync PDEBUGPRINTFX(DBG_ERROR,( "Sync Alert not allowed with incoming package state='%s'", PackageStateNames[fIncomingState] )); aStatusCommand.setStatusCode(403); // forbidden ADDDEBUGITEM(aStatusCommand,"Sync Alert only allowed in init package"); return NULL; // no alert sent back } // find requested database by URI const char *target = smlSrcTargLocURIToCharP(aItemP->target); if (!target || !target[0]) { // same fallback for Sony Ericsson C510 as in // TSyncSession::initSync() target = smlSrcTargLocURIToCharP(aItemP->source); } datastoreP = findLocalDataStoreByURI( target, // target as sent from remote &optionsCGI, // options, if any &identifyingTargetURI // identifying part of URI (CGI removed) ); if (!datastoreP) { // no such local datastore aStatusCommand.setStatusCode(404); // not found } else { // save alerted datastore pointer (will be returned to caller, which is TAlertCommand) aLocalDataStoreP=datastoreP; // get anchors const char *nextRemoteAnchor = smlMetaNextAnchorToCharP(smlPCDataToMetInfP(aItemP->meta)); if (nextRemoteAnchor==NULL) nextRemoteAnchor=""; // some remotes may send NO anchor const char *lastRemoteAnchor = smlMetaLastAnchorToCharP(smlPCDataToMetInfP(aItemP->meta)); if (lastRemoteAnchor==NULL) lastRemoteAnchor=""; // some remotes may send NO anchor // get URIs const char *targetURI = smlSrcTargLocURIToCharP(aItemP->target); const char *sourceURI = smlSrcTargLocURIToCharP(aItemP->source); // get Filter SmlFilterPtr_t targetFilter = aItemP->target ? aItemP->target->filter : NULL; if (fRestarting) { // reset datastore first datastoreP->engFinishDataStoreSync(LOCERR_OK); } // alert datastore of requested sync // - let datastore process alert and generate additional alert if needed // NOTE: this might generate a PUT command if remote needs to see our // devInf (config changed since last sync) alertresponsecmdP=datastoreP->engProcessSyncAlert( NULL, // not as subdatastore aAlertCode, // the alert code lastRemoteAnchor, // last anchor of client nextRemoteAnchor, // next anchor of client targetURI, // target as sent from remote identifyingTargetURI.c_str(), // identifying part of URI (relative, options removed) optionsCGI.c_str(), // extracted options (e.g. filtering) CGI targetFilter, // DS 1.2 filter, if any (can be NULL if none) sourceURI, // source URI aStatusCommand // status that might be modified ); // echo next anchor sent with item back in status // %%% specs say that only next anchor must be echoed, SCTS echoes both SmlItemPtr_t itemP = newItem(); // empty item // NOTE: anchor is MetInf, but is echoed in DATA part of item, not META! itemP->data = newMetaAnchor(nextRemoteAnchor,NULL); // only next (like specs) aStatusCommand.addItem(itemP); // add it to status } break; } case 224 : // Suspend alert SuspendSession(514); break; case 100 : // DISPLAY PDEBUGPRINTFX(DBG_HOT,( "---------------- DISPLAY ALERT (100): %s", smlPCDataToCharP(aItemP->data) )); // show it on the console CONSOLEPRINTF(( "***** Message from Remote: %s", smlPCDataToCharP(aItemP->data) )); // callback to allow GUI clients to display the message if (!SESSION_PROGRESS_EVENT(this,pev_display100,NULL,uIntPtr(smlPCDataToCharP(aItemP->data)),0,0)) { // user answered no to our question "continue?" aStatusCommand.setStatusCode(514); // cancelled // Do NOT abort the session, so give the server a chance to do someting more sensible based on the 514 status. aStatusCommand.addItemString("User abort in response to Alert 100 message"); PDEBUGPRINTFX(DBG_ERROR,("User abort after seeing Alert 100 message: %s",smlPCDataToCharP(aItemP->data))); } break; case 223: // Chunking error: missing end of chunk aStatusCommand.setStatusCode(223); aStatusCommand.addItemString("Missing end of chunk"); PDEBUGPRINTFX(DBG_ERROR,( "Warning: Alert Code 223 -> Missing end of chunk for item localid='%s', remoteid='%s'", smlSrcTargLocURIToCharP(aItemP->target), smlSrcTargLocURIToCharP(aItemP->source) )); break; default : // unknown alert code aStatusCommand.setStatusCode(406); aStatusCommand.addItemString("Unimplemented Alert Code"); PDEBUGPRINTFX(DBG_ERROR,("Unimplemented Alert Code %hd -> Status 406",aAlertCode)); break; } // switch fAlertCode // return command generated (or NULL if none) return alertresponsecmdP; } // TSyncSession::processAlertItem #ifdef SYDEBUG #define XML_TRANSLATION_ENABLED #else #undef XML_TRANSLATION_ENABLED #endif #ifdef SYDEBUG void TSyncSession::XMLTranslationIncomingStart(void) { // start translation instances #ifdef XML_TRANSLATION_ENABLED if (fXMLtranslate && !getRootConfig()->fDebugConfig.fDebugInfoPath.empty()) { DEBUGPRINTFX(DBG_EXOTIC,("Initializing incoming XML translation instance")) if (!getSyncAppBase()->newSmlInstance( SML_XML, getRootConfig()->fLocalMaxMsgSize * 3, // XML should not be more than 3 times larger than WBXML fIncomingXMLInstance )) { // if instance cannot be created, turn off XML translation to avoid crashes fXMLtranslate=false; PDEBUGPRINTFX(DBG_ERROR,("XML translation disabled because of lacking memory")) } } else fXMLtranslate=false; #endif } // TSyncSession::XMLTranslationIncomingStart void TSyncSession::XMLTranslationOutgoingStart(void) { #ifdef XML_TRANSLATION_ENABLED // start translation instances if (fXMLtranslate && !getRootConfig()->fDebugConfig.fDebugInfoPath.empty()) { DEBUGPRINTFX(DBG_EXOTIC,("Initializing outgoing XML translation instance")) if (!getSyncAppBase()->newSmlInstance( SML_XML, getRootConfig()->fLocalMaxMsgSize * 3, // XML should not be more than 3 times larger than WBXML fOutgoingXMLInstance )) { // if instance cannot be created, turn off XML translation to avoid crashes fXMLtranslate=false; PDEBUGPRINTFX(DBG_ERROR,("XML translation disabled because of lacking memory")) } } else fXMLtranslate=false; #endif } // TSyncSession::XMLTranslationOutgoingStart /// @todo /// rewrite this to use a TDbgOut object to write stuff // finish and output XML translation of incoming traffic void TSyncSession::XMLTranslationIncomingEnd(void) { #ifdef XML_TRANSLATION_ENABLED if (fIncomingXMLInstance && fXMLtranslate) { // write XML translation of input and output to files DEBUGPRINTFX(DBG_EXOTIC,("XML translation enabled...")) MemPtr_t XMLtext; MemSize_t XMLsize; string fname; // - incoming // - get XML DEBUGPRINTFX(DBG_EXOTIC,("- Writing incoming XML translation")) XMLtext=NULL; XMLsize=0; if (smlLockReadBuffer(fIncomingXMLInstance,&XMLtext,&XMLsize)==SML_ERR_OK) { // save to file TDbgOut *dbgOutP = getSyncAppBase()->newDbgOutputter(false); if (dbgOutP) { // create base file name (trm = translated message) string dumpfilename; StringObjPrintf(dumpfilename, "%s_trm%03ld_%03ld_incoming", getDbgLogger()->getDebugPath(), // path + session log base name (long)getLastIncomingMsgID(), (long)++fDumpCount // to make sure it is unique even in case of retries ); // open file in raw mode if (dbgOutP->openDbg( dumpfilename.c_str(), ".xml", dbgflush_none, false, // append to existing if any true // raw mode )) { // write out the entire message dbgOutP->putRawData(XMLtext, XMLsize); // close the file dbgOutP->closeDbg(); // add a link into the session file to immediately get the file PDEBUGPRINTFX(DBG_HOT+DBG_PROTO,( "Incoming %sXML message msgID=%ld &html;&html;saved as XML translation&html;&html;", getEncoding()==SML_XML ? "" : "WB", (long)getLastIncomingMsgID(), getDbgLogger()->getDebugFilename(), // session log base name (long)getLastIncomingMsgID(), (long)fDumpCount )); } else { PDEBUGPRINTFX(DBG_ERROR,("Cannot write file")); } delete dbgOutP; } } } if (fIncomingXMLInstance) { // finally free instance getSyncAppBase()->freeSmlInstance(fIncomingXMLInstance); fIncomingXMLInstance=NULL; } #endif } // TSyncSession::XMLTranslationIncomingEnd // finish and output XML translation of outgoing traffic /// @todo /// rewrite this to use a TDbgOut object to write stuff void TSyncSession::XMLTranslationOutgoingEnd(void) { #ifdef XML_TRANSLATION_ENABLED if (fOutgoingXMLInstance && fXMLtranslate) { // write XML translation of input and output to files DEBUGPRINTFX(DBG_EXOTIC,("XML translation enabled...")) MemPtr_t XMLtext; MemSize_t XMLsize; string fname; // - outgoing // write only if session is debug-enabled // - get XML DEBUGPRINTFX(DBG_EXOTIC,("- Writing outgoing XML translation")) XMLtext=NULL; XMLsize=0; if (smlLockReadBuffer(fOutgoingXMLInstance,&XMLtext,&XMLsize)==SML_ERR_OK) { // save to file TDbgOut *dbgOutP = getSyncAppBase()->newDbgOutputter(false); if (dbgOutP) { // create base file name (trm = translated message) string dumpfilename; StringObjPrintf(dumpfilename, "%s_trm%03ld_%03ld_outgoing", getDbgLogger()->getDebugPath(), // path + session log base name (long)getOutgoingMsgID(), (long)++fDumpCount // to make sure it is unique even in case of retries ); // open file in raw mode if (dbgOutP->openDbg( dumpfilename.c_str(), ".xml", dbgflush_none, false, // append to existing if any true // raw mode )) { // write out the entire message dbgOutP->putRawData(XMLtext, XMLsize); // close the file dbgOutP->closeDbg(); // add a link into the session file to immediately get the file PDEBUGPRINTFX(DBG_HOT+DBG_PROTO,( "Outgoing %sXML message msgID=%ld &html;&html;saved as XML translation&html;&html;", getEncoding()==SML_XML ? "" : "WB", (long)getOutgoingMsgID(), getDbgLogger()->getDebugFilename(), // session log base name (long)getOutgoingMsgID(), (long)fDumpCount )); } else { PDEBUGPRINTFX(DBG_ERROR,("Cannot write file")); } delete dbgOutP; } } } if (fOutgoingXMLInstance) { // finally free instance getSyncAppBase()->freeSmlInstance(fOutgoingXMLInstance); fOutgoingXMLInstance=NULL; } #endif } // TSyncSession::XMLTranslationOutgoingEnd // dump message from specified buffer void TSyncSession::DumpSyncMLBuffer(MemPtr_t aBuffer, MemSize_t aBufSize, bool aOutgoing, Ret_t aDecoderError) { #ifdef MSGDUMP // log message currently in SML buffer if (fMsgDump && !getRootConfig()->fDebugConfig.fDebugInfoPath.empty()) { TDbgOut *dbgOutP = getSyncAppBase()->newDbgOutputter(false); if (dbgOutP) { // create base file name string dumpfilename; // regular message, StringObjPrintf(dumpfilename, "%s_msg%03ld_%03ld_%sing", getDbgLogger()->getDebugPath(), // path + session log base name (long)(aOutgoing ? getOutgoingMsgID() : getLastIncomingMsgID()+1), // just generated msgID / expected next incoming ID (long)++fDumpCount, // to make sure it is unique even in case of retries aOutgoing ? "outgo" : "incom" ); if (aDecoderError) { // append error code StringObjAppendPrintf(dumpfilename,"_ERR_0x%04X",aDecoderError); } // open file in raw mode if (dbgOutP->openDbg( dumpfilename.c_str(), getEncoding()==SML_XML ? ".xml" : ".wbxml", dbgflush_none, false, // append to existing if any true // raw mode )) { // write out the entire message dbgOutP->putRawData(aBuffer, aBufSize); // close the file dbgOutP->closeDbg(); // add a link into the session file to immediately get the file if it is XML if (getEncoding()==SML_XML) { PDEBUGPRINTFX(DBG_HOT+DBG_PROTO,( "%sing XML message msgID=%ld &html;&html;dumped to file&html;&html;", aOutgoing ? "Outgo" : "Incom", (long)getOutgoingMsgID(), getDbgLogger()->getDebugFilename(), // session log base name (long)(aOutgoing ? getOutgoingMsgID() : getLastIncomingMsgID()+1), // just generated msgID / expected next incoming ID (long)fDumpCount, aOutgoing ? "outgo" : "incom" )); } } else { PDEBUGPRINTFX(DBG_ERROR,("Cannot write file")); } delete dbgOutP; } } #endif // MSGDUMP } // TSyncSession::DumpSyncMLBuffer // Dump message in SML buffer to file void TSyncSession::DumpSyncMLMessage(bool aOutgoing) { // dump message if needed #ifdef MSGDUMP // log message currently in SML buffer if (fMsgDump && !getRootConfig()->fDebugConfig.fDebugInfoPath.empty()) { // peek into buffer MemPtr_t data; MemSize_t datasize; if (smlPeekMessageBuffer(getSmlWorkspaceID(), aOutgoing, &data, &datasize)==SML_ERR_OK) { DumpSyncMLBuffer(data,datasize,aOutgoing,SML_ERR_OK); } } #endif // MSGDUMP } // TSyncSession::DumpSyncMLMessage #endif // SYDEBUG // SyncML Toolkit callback handlers // ================================ // start of SyncML message Ret_t TSyncSession::StartMessage(SmlSyncHdrPtr_t aContentP) { #ifdef SYDEBUG fSessionLogger.DebugDefineMainThread(); #endif SessionUsed(); // session used fLastRequestStarted = getSystemNowAs(TCTX_UTC); // request started fMessageRetried = false; // we assume no message retry MP_SHOWCURRENT(DBG_PROFILE,"Start of incoming Message"); TP_START(fTPInfo,TP_general); // could be new thread #ifdef EXPIRES_AFTER_DATE if (IS_SERVER) { // set 1/4 of the date here fCopyOfScrambledNow=((getSyncAppBase()->fScrambledNow)<<2)+503; // scramble again a little } #endif // EXPIRES_AFTER_DATE // dump it if configured // Note: this must happen here before answer writing to the instance buffer starts, as otherwise // the already consumed part of the buffer might get overwritten (the SyncML message header in this case). #ifdef SYDEBUG DumpSyncMLMessage(false); // incoming #endif if (IS_SERVER) { // for server, SyncML_Outgoing is started here, as SyncML_Incoming ends before SyncML_Outgoing // but for client, document exchange starts with outgoing message PDEBUGBLOCKDESC("SyncML_Outgoing","preparing for response before starting to analyze new incoming message"); } PDEBUGBLOCKFMT(("SyncML_Incoming","Starting to analyze incoming message", "RequestNo=%ld|SySyncVers=%d.%d.%d.%d",(long)fSyncAppBaseP->requestCount(), SYSYNC_VERSION_MAJOR, SYSYNC_VERSION_MINOR, SYSYNC_SUBVERSION, SYSYNC_BUILDNUMBER )); PDEBUGPRINTFX(DBG_HOT,( "=================> Starting to analyze incoming message, SySync V%d.%d.%d.%d, RequestNo=%ld", SYSYNC_VERSION_MAJOR, SYSYNC_VERSION_MINOR, SYSYNC_SUBVERSION, SYSYNC_BUILDNUMBER, (long)fSyncAppBaseP->requestCount() )); #ifdef SYDEBUG // Start incoming translation before decoding header XMLTranslationIncomingStart(); if (fXMLtranslate && fIncomingXMLInstance) { // Note: we must find the SyncML version in advance, as fSyncMLVersion is not yet valid here sInt16 hdrVers; StrToEnum(SyncMLVerDTDNames,numSyncMLVersions,hdrVers,smlPCDataToCharP(aContentP->version)); smlStartMessageExt(fIncomingXMLInstance,aContentP,SmlVersionCodes[hdrVers]); } #endif // update encoding smlGetEncoding(fSmlWorkspaceID,&fEncoding); // create command TSyncHeader *syncheaderP; MP_NEW(syncheaderP,DBG_OBJINST,"TSyncHeader",TSyncHeader(this,aContentP)); // execute it (special case for header) return processHeader(syncheaderP); } // TSyncSession::StartMessage // special entry point to prematurely abort processing of a incoming message // and cause the necessary cleanup void TSyncSession::CancelMessageProcessing(void) { #ifdef SYDEBUG // Now dump XML translation of incoming message (as far as it was processed at all) XMLTranslationIncomingEnd(); #endif // Show premature end of input processing PDEBUGPRINTFX(DBG_HOT,( "=================> Aborted processing message #%ld, request=%ld", (long)fIncomingMsgID, (long)fSyncAppBaseP->requestCount() )); } // TSyncSession::CancelMessageProcessing Ret_t TSyncSession::EndMessage(Boolean_t final) { #ifdef SYDEBUG // generate XML translation if (fXMLtranslate && fIncomingXMLInstance) smlEndMessage(fIncomingXMLInstance,final); // Now dump XML translation of incoming message XMLTranslationIncomingEnd(); #endif // Flush pending item change commands? // // Don't retry other commands here (like a pending Sync), because // the whole purpose of delaying Sync is to give a preliminary // answer to the peer before finishing the command. // // Delaying them although we are expected to finish (final set!) // would have two drawbacks: // - Requires another message roundtrip. // - More complex state transitions which is known to not work: // Synthesis<->Synthesis sync did not complete correctly when the // server forced the client to send another message, because client // and server did not agree on the end of the session. (see // "[os-libsynthesis] temporary local ID + FinalizeLocalID"). if (final && !onlySyncPending() && !fDelayedExecutionCommands.empty()) { // TODO: tell stores explicitly that we really need the results now // instead of relying on the indirect semantic of "second call must // succeed". tryDelayedExecutionCommands(); } // End of incoming message PDEBUGPRINTFX(DBG_HOT,( "=================> Finished processing incoming message #%ld (%sfinal), request=%ld", (long)fIncomingMsgID, final ? "" : "not ", (long)fSyncAppBaseP->requestCount() )); // start outgoing message if not already done so // Note: this should NOT happen, as EVERY message from the remote should contain a SyncHdr status which // should have started the message already if (!fOutgoingStarted) { PDEBUGPRINTFX(DBG_ERROR,("Warning: incoming message #%ld did not contain a SyncHdr status (protocol violation)",(long)fIncomingMsgID)); // try to continue by simply ignoring - might not always work out (e.g. when authorisation is not yet complete, this will fail) issueHeader(false); } // forget pending continue requests if (final) fNextMessageRequests=0; // no pending next message requests when a message is final // make sure peer gets devInf Put if needed (only if it didn't issue a GET) // Note: do it here because we have processed all commands (alerts) now but // server response alerts are still in the fEndOfMessageCommands queue. // This ensures that clients gets PUT before it gets ALERTs. if (!fRemoteGotDevinf && mustSendDevInf()) { // remote has not got devinf and should see it if (!getRootConfig()->fNeverPutDevinf) { // PUT devinf now PDEBUGPRINTFX(DBG_PROTO,("Remote must see our changed devInf -> creating PUT command")); TDevInfPutCommand *putcmdP = new TDevInfPutCommand(this); issueRootPtr(putcmdP); } else { PDEBUGPRINTFX(DBG_PROTO,("Remote should see devinf, but PUT is suppressed: ")); } } // hook for placing custom GET and PUT if (!fCustomGetPutSent) { fCustomGetPutSent=true; issueCustomGetPut(fRemoteDevInfKnown,fRemoteGotDevinf); } // now issue all commands that may only be issued AFTER sending statuses for incoming commands TSmlCommandPContainer::iterator pos; while (true) { // first in list pos=fEndOfMessageCommands.begin(); if (pos==fEndOfMessageCommands.end()) break; // done // take command out of the list TSmlCommand *cmdP=(*pos); fEndOfMessageCommands.erase(pos); PDEBUGPRINTFX(DBG_SESSION,("<--- Issuing command '%s' from EndOfMessage Queue",cmdP->getName())); // issue it (doesn't matter if cannot be sent with this message, // it will then be moved into the fNextMessageCommands queue) issuePtr(cmdP,fNextMessageCommands,fInterruptedCommandP); } // now continue with package if it was discontinued in last message // %%% if (fNextMessageRequests>0) { // We have received a 222 Alert, so continue package now // %%% always continue, even if we didn't see a 222 alert ContinuePackageRoot(); // %%% } // let client or server do what is needed if (fFakeFinalFlag) { PDEBUGPRINTFX(DBG_ERROR,("Warning: heavy workaround active - simulated to get resume without sync-from-client going")); } MessageEnded(final || fFakeFinalFlag); fFakeFinalFlag=false; #ifdef SYNCSTATUS_AT_SYNC_CLOSE // make sure sync status is disposed if (fSyncCloseStatusCommandP) delete fSyncCloseStatusCommandP; fSyncCloseStatusCommandP=NULL; #endif MP_SHOWCURRENT(DBG_PROFILE,"End of incoming message"); // ok if no exception thrown return SML_ERR_OK; } // TSyncSession::EndMessage Ret_t TSyncSession::StartSync(SmlSyncPtr_t aContentP) { #ifdef SYDEBUG // generate XML translation if (fXMLtranslate && fIncomingXMLInstance) smlStartSync(fIncomingXMLInstance,aContentP); #endif // create command object TSyncCommand *commandP = new TSyncCommand(this,fIncomingMsgID,aContentP); // process it return process(commandP); } // TSyncSession::StartSync Ret_t TSyncSession::EndSync(void) { #ifdef SYDEBUG // generate XML translation if (fXMLtranslate && fIncomingXMLInstance) smlEndSync(fIncomingXMLInstance); #endif /* %%% old version: sync end is no command itself, makes queuing sequences for later processing impossible, so we made it be a separate command // process Sync End // %%% evtl. catch... PDEBUGPRINTFX(DBG_HOT,("End of command")); // Note: do not call if previous Sync start might not have been processed if (!fIgnoreIncomingCommands) processSyncEnd(); return SML_ERR_OK; */ // create command object TSyncEndCommand *commandP = new TSyncEndCommand(this,fIncomingMsgID); // process it return process(commandP); } // TSyncSession::EndSync #ifdef ATOMIC_RECEIVE Ret_t TSyncSession::StartAtomic(SmlAtomicPtr_t aContentP) { #ifdef SYDEBUG // generate XML translation if (fXMLtranslate && fIncomingXMLInstance) smlStartAtomic(fIncomingXMLInstance,aContentP); #endif // NOTE from Specs: Nested Atomic commands are not legal. A nested Atomic // command will generate an error 500 - command failed. // create command object // %%% create DUMMY command for now PDEBUGPRINTFX(DBG_HOT,("Start of Atomic bracket: return Status 406 unimplemented")); TUnimplementedCommand *commandP = new TUnimplementedCommand( this, fIncomingMsgID, aContentP->cmdID, 0, scmd_copy, aContentP, 406); // optional feature not supported // process it return process(commandP); } // TSyncSession::StartAtomic Ret_t TSyncSession::EndAtomic(void) { #ifdef SYDEBUG // generate XML translation if (fXMLtranslate && fIncomingXMLInstance) smlEndAtomic(fIncomingXMLInstance); #endif // process Atomic end // %%% not implemented, just accept PDEBUGPRINTFX(DBG_HOT,("End of Atomic bracket")); return SML_ERR_OK; } // TSyncSession::EndAtomic #endif #ifdef SEQUENCE_RECEIVE Ret_t TSyncSession::StartSequence(SmlSequencePtr_t aContentP) { #ifdef SYDEBUG // generate XML translation if (fXMLtranslate && fIncomingXMLInstance) smlStartSequence(fIncomingXMLInstance,aContentP); #endif // %%% later, implement a nestable command object and derive Sequence,Atomic and Sync // from it. Similar to nested command creation, maintain a chain of nested commands; // session will have a pointer to most recent nest and ALL commands will have a pointer // to owning command (or NULL if they are on root level). // Sequence is trivial as SySync executes command in sequence anyway // - simply keep track of nesting fSequenceNesting++; PDEBUGPRINTFX(DBG_HOT,("Start of Sequence bracket, nesting level is now %hd",fSequenceNesting)); // get cmdid sInt32 cmdid; StrToLong(smlPCDataToCharP(aContentP->cmdID),cmdid); // make status TStatusCommand *statusCmdP = new TStatusCommand( this, // associated session (for callbacks) cmdid, // referred-to command ID scmd_sequence, // referred-to command type (scmd_xxx) (aContentP->flags & SmlNoResp_f)!=0, // set if no-Resp 200 // status code ); // issue ok status // - return status issueRootPtr(statusCmdP); // - ok return SML_ERR_OK; } // TSyncSession::StartSequence Ret_t TSyncSession::EndSequence(void) { #ifdef SYDEBUG // generate XML translation if (fXMLtranslate && fIncomingXMLInstance) smlEndSequence(fIncomingXMLInstance); #endif // - keep track of nesting if (fSequenceNesting<1) { // error in nesting PDEBUGPRINTFX(DBG_HOT,("End of Sequence bracket, MISSING PRECEEDING SEQUENCE START -> aborting session")); AbortSession(400,true); // bad nesting is severe, abort session } else { // nesting ok fSequenceNesting--; PDEBUGPRINTFX(DBG_HOT,("End of Sequence bracket, nesting level is now %hd",fSequenceNesting)); } return SML_ERR_OK; } // TSyncSession::EndSequence #endif Ret_t TSyncSession::AddCmd(SmlAddPtr_t aContentP) { #ifdef SYDEBUG // generate XML translation if (fXMLtranslate && fIncomingXMLInstance) smlAddCmd(fIncomingXMLInstance,aContentP); #endif // create SyncOp command object TSyncOpCommand *commandP = new TSyncOpCommand( this, fLocalSyncDatastoreP, fIncomingMsgID, sop_add, scmd_add, aContentP ); // process it return process(commandP); } // TSyncSession::AddCmd Ret_t TSyncSession::AlertCmd(SmlAlertPtr_t aContentP) { #ifdef SYDEBUG // generate XML translation if (fXMLtranslate && fIncomingXMLInstance) smlAlertCmd(fIncomingXMLInstance,aContentP); #endif // create command object TAlertCommand *commandP = new TAlertCommand(this,fIncomingMsgID,aContentP); // process it return process(commandP); } // TSyncSession::AlertCmd Ret_t TSyncSession::DeleteCmd(SmlDeletePtr_t aContentP) { #ifdef SYDEBUG // generate XML translation if (fXMLtranslate && fIncomingXMLInstance) smlDeleteCmd(fIncomingXMLInstance,aContentP); #endif // determine type of delete TSyncOperation syncop; if (aContentP->flags & SmlArchive_f) syncop = sop_archive_delete; else if (aContentP->flags & SmlSftDel_f) syncop = sop_soft_delete; else syncop=sop_delete; // create SyncOp command object TSyncOpCommand *commandP = new TSyncOpCommand( this, fLocalSyncDatastoreP, // note that this one might be NULL in case previous sync command was delayed fIncomingMsgID, syncop, scmd_delete, aContentP ); // process it return process(commandP); } // TSyncSession::DeleteCmd // process GET commands Ret_t TSyncSession::GetCmd(SmlGetPtr_t aContentP) { #ifdef SYDEBUG // generate XML translation if (fXMLtranslate && fIncomingXMLInstance) smlGetCmd(fIncomingXMLInstance,aContentP); #endif // create command object TGetCommand *commandP = new TGetCommand(this,fIncomingMsgID,aContentP); // process it return process(commandP); } // TSyncSession::GetCmd Ret_t TSyncSession::PutCmd(SmlPutPtr_t aContentP) { #ifdef SYDEBUG // generate XML translation if (fXMLtranslate && fIncomingXMLInstance) smlPutCmd(fIncomingXMLInstance,aContentP); #endif // create command object TPutCommand *commandP = new TPutCommand(this,fIncomingMsgID,aContentP); // process it return process(commandP); } // TSyncSession::PutCmd #ifdef MAP_RECEIVE Ret_t TSyncSession::MapCmd(SmlMapPtr_t aContentP) { #ifdef SYDEBUG // generate XML translation if (fXMLtranslate && fIncomingXMLInstance) smlMapCmd(fIncomingXMLInstance,aContentP); #endif // create command object TMapCommand *commandP = new TMapCommand(this,fIncomingMsgID,aContentP); // process it return process(commandP); } // TSyncSession::MapCmd #endif #ifdef RESULT_RECEIVE Ret_t TSyncSession::ResultsCmd(SmlResultsPtr_t aContentP) { #ifdef SYDEBUG // generate XML translation if (fXMLtranslate && fIncomingXMLInstance) smlResultsCmd(fIncomingXMLInstance,aContentP); #endif // create command object TResultsCommand *commandP = new TResultsCommand(this,fIncomingMsgID,aContentP); // process it return process(commandP); } // TSyncSession::ResultsCmd #endif Ret_t TSyncSession::StatusCmd(SmlStatusPtr_t aContentP) { #ifdef SYDEBUG // generate XML translation if (fXMLtranslate && fIncomingXMLInstance) smlStatusCmd(fIncomingXMLInstance,aContentP); #endif // create command object TStatusCommand *statuscommandP = new TStatusCommand(this,fIncomingMsgID,aContentP); // handle status (search for command that waits for this status) return handleStatus(statuscommandP); } // TSyncSession::StatusCmd Ret_t TSyncSession::ReplaceCmd(SmlReplacePtr_t aContentP) { #ifdef SYDEBUG // generate XML translation if (fXMLtranslate && fIncomingXMLInstance) smlReplaceCmd(fIncomingXMLInstance,aContentP); #endif // create SyncOp command object TSyncOpCommand *commandP = new TSyncOpCommand( this, fLocalSyncDatastoreP, fIncomingMsgID, sop_replace, scmd_replace, aContentP ); // process it return process(commandP); } // TSyncSession::ReplaceCmd #ifdef COPY_RECEIVE Ret_t TSyncSession::CopyCmd(SmlReplacePtr_t aContentP) { #ifdef SYDEBUG #ifdef COPY_SEND // generate XML translation if (fXMLtranslate && fIncomingXMLInstance) smlCopyCmd(fIncomingXMLInstance,aContentP); #else #error "We will have incomplete XML translation when only COPY_RECEIVE is defined" #endif #endif // create SyncOp command object TSyncOpCommand *commandP = new TSyncOpCommand( this, fLocalSyncDatastoreP, fIncomingMsgID, fTreatCopyAsAdd ? sop_add : sop_copy, scmd_copy, aContentP ); // process it return process(commandP); } // TSyncSession::CopyCmd #endif Ret_t TSyncSession::MoveCmd(SmlReplacePtr_t aContentP) { #ifdef SYDEBUG // generate XML translation if (fXMLtranslate && fIncomingXMLInstance) smlMoveCmd(fIncomingXMLInstance,aContentP); #endif // create SyncOp command object TSyncOpCommand *commandP = new TSyncOpCommand( this, fLocalSyncDatastoreP, fIncomingMsgID, sop_move, scmd_move, aContentP ); // process it return process(commandP); } // TSyncSession::MoveCmd // - error handling Ret_t TSyncSession::HandleError(void) { // %%% tbd DEBUGPRINTFX(DBG_ERROR,("HandleError reached")); return SML_ERR_OK; // %%% } // TSyncSession::HandleError Ret_t TSyncSession::DummyHandler(const char* msg) { //DEBUGPRINTFX(DBG_ERROR,("DummyHandler: msg=%s",msg)); return SML_ERR_OK; } // TSyncSession::DummyHandler #ifdef ENGINEINTERFACE_SUPPORT // Support for EngineModule common interface // ========================================= // open subkey by name (not by path!) // - this is the actual implementation TSyError TSessionKey::OpenSubKeyByName( TSettingsKeyImpl *&aSettingsKeyP, cAppCharP aName, stringSize aNameSize, uInt16 aMode ) { #ifdef SCRIPT_SUPPORT if (strucmp(aName,"sessionvars",aNameSize)==0) { // note: if no session scripts are used, context does not exist and is NULL. // TScriptVarKey does not crash with a NULL, so we can give ok here (but no session vars // will be accessible). aSettingsKeyP = new TScriptVarKey(fEngineInterfaceP,fSessionP->getSessionScriptContext()); } else #endif return inherited::OpenSubKeyByName(aSettingsKeyP,aName,aNameSize,aMode); // opened a key return LOCERR_OK; } // TSessionKey::OpenSubKeyByName #endif // ENGINEINTERFACE_SUPPORT } // namespace sysync // factory methods of Session Config // ================================= // only one of XML2GO or SDK/Plugin can be on top of customagent #ifdef XML2GO_SUPPORT #include "xml2goapids.h" #elif defined(SDK_SUPPORT) #include "pluginapids.h" #endif // ODBC can be in-between if selected #ifdef SQL_SUPPORT #include "odbcapids.h" #endif namespace sysync { #ifndef HARDCODED_CONFIG // create new datastore config by name // returns NULL if none found TLocalDSConfig *TSessionConfig::newDatastoreConfig(const char *aName, const char *aType, TConfigElement *aParentP) { #ifdef XML2GO_SUPPORT if (aType && strucmp(aType,"xml2go")==0) { // xml2go enhanced datastore return new TXml2goDSConfig(aName,aParentP); } else #elif defined(SDK_SUPPORT) if (aType && strucmp(aType,"plugin")==0) { // APIDB enhanced datastore (on top of ODBC if SQL_SUPPORT is on) return new TPluginDSConfig(aName,aParentP); } else #endif #ifdef SQL_SUPPORT if (aType==0 || strucmp(aType,"odbc")==0 || strucmp(aType,"sql")==0) { // ODBC enabled datastore return new TOdbcDSConfig(aName,aParentP); } else #endif return NULL; // unknown datastore } // TSessionConfig::newDatastoreConfig #endif // HARDCODED_CONFIG bool TSyncSession::receivedSyncModeExtensions() { TRemoteDataStorePContainer::iterator pos; for (pos=fRemoteDataStores.begin(); pos!=fRemoteDataStores.end(); ++pos) { set modes; (*pos)->getSyncModes(modes); set::const_iterator it; for (it=modes.begin(); it!=modes.end(); ++it) { const char *nptr = it->c_str(); char *endptr; if (!*nptr) { // ignore empty mode continue; } long mode = strtol(nptr, &endptr, 10); // ignore trailing spaces while (isspace(*endptr)) { endptr++; } if (*endptr) { // non-standard character => found extensions return true; } if (mode > 32) { // Non-standed integer code! // Choosing 32 is somewhat random, not all of those // are really defined in the standard. return true; } } } return false; } } // namespace sysync #endif // not SYNCSESSION_PART1_EXCLUDE // eof libsynthesis-3.4.0.47.1/src/sysync/syncsession.h000077500000000000000000001461601226375725500215270ustar00rootroot00000000000000/* * TSyncSession * Represents an entire Synchronisation Session, possibly consisting * of multiple SyncML-Toolkit "Sessions" (Message composition/de- * composition) as well as multiple database synchronisations. * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * */ #ifndef SYNC_SESSION_H #define SYNC_SESSION_H // general includes (SyncML tookit, windows, Clib) #include "sysync.h" // specific includes #include "syncappbase.h" #include "localengineds.h" #include "remotedatastore.h" #include "profiling.h" #include "scriptcontext.h" namespace sysync { extern const char * const SyncMLVerProtoNames[numSyncMLVersions]; extern const SmlVersion_t SmlVersionCodes[numSyncMLVersions]; extern const char * const SyncMLVerDTDNames[numSyncMLVersions]; extern const char * const SyncMLDevInfNames[numSyncMLVersions]; #ifndef HARDCODED_CONFIG extern const char * const SyncMLVersionNames[numSyncMLVersions]; #endif extern const char * const authTypeNames[numAuthTypes]; extern const char * const SyncModeNames[numSyncModes]; #ifdef SYDEBUG extern const char * const PackageStateNames[numPackageStates]; extern const char * const SyncOpNames[numSyncOperations]; #endif extern const char * const SyncModeDescriptions[numSyncModes]; // secret type for SessionLogin typedef enum { // Note: changes here will change AUTHTYPE() script func API in ODBC-Agent! sectyp_anonymous, // anonymous sectyp_clearpass, // clear text password sectyp_md5_V10, // SyncML V1.0 MD5 sectyp_md5_V11 // SyncML V1.1 MD5 } TAuthSecretTypes; // minimal free message size required to end message // %%% rough approx, should always be enough #define SIZEFORMESSAGEEND 200 // Container types typedef std::list TRemoteDataStorePContainer; // contains data stores // forward declaration class TSyncAppBase; class TSmlCommand; class TStatusCommand; class TSyncHeader; class TLocalEngineDS; class TRemoteDataStore; class TRootConfig; #ifdef SCRIPT_SUPPORT // publish as derivates might need it extern const TFuncTable ErrorFuncTable; typedef struct { TSyError statuscode; TSyError newstatuscode; bool resend; TLocalEngineDS *datastoreP; TSyncOperation syncop; } TErrorFuncContext; typedef struct { bool isPut; bool canIssue; TSyError statuscode; string itemURI; string itemData; string metaType; } TGetPutResultFuncContext; #endif // SCRIPT_SUPPORT #ifndef NO_REMOTE_RULES class TRemoteRuleConfig; // forward typedef std::list TRemoteRulesList; // remote party special rule class TRemoteRuleConfig: public TConfigElement { typedef TConfigElement inherited; public: TRemoteRuleConfig(const char *aElementName, TConfigElement *aParentElementP); virtual ~TRemoteRuleConfig(); // properties // - identification of remote string fManufacturer; string fModel; string fOem; string fFirmwareVers; string fSoftwareVers; string fHardwareVers; string fDevId; string fDevTyp; // - options specific for that remote party (0=false, 1=true, -1=unspecified) sInt8 fLegacyMode; // set if remote is known legacy, so don't use new types sInt8 fLenientMode; // set if remote's SyncML should be handled leniently, i.e. not too strict checking where not absolutely needed sInt8 fLimitedFieldLengths; // set if remote has limited field lengths sInt8 fDontSendEmptyProperties; // set if remote does not want empty properties sInt8 fDoQuote8BitContent; // set if 8-bit chars should generally be encoded with QP in MIME-DIR sInt8 fDoNotFoldContent; // set if content should not be folded in MIME-DIR sInt8 fNoReplaceInSlowsync; // do not use Replace (as server) in slow sync (this is to COMPLETELY avoid replaces being sent during slowsync, for clients that crash on that such as old 9210) sInt8 fTreatRemoteTimeAsLocal; // treat remote time as localtime even if it carries different time zone information ("Z" suffix or zone spec) sInt8 fTreatRemoteTimeAsUTC; // treat remote time as UTC even if it carries different time zone information (no suffix or zone spec) sInt8 fVCal10EnddatesSameDay; // send end date-only values (like DTEND) as last time unit of previous day (i.e. 23:59:59, inclusive) instead of midnight of next day (exclusive, like in iCalendar 2.0) sInt8 fIgnoreDevInfMaxSize; // ignore specification in CTCap (when device has bad specs like in E90 for example) sInt8 fIgnoreCTCap; // ignore entire ctcap sInt8 fDSPathInDevInf; // use actual DS path as used in Alert for creating datastore devInf (needed for newer Nokia clients) sInt8 fDSCgiInDevInf; // also show CGI as used in Alert for creating datastore devInf (needed for newer Nokia clients) sInt8 fUpdateClientDuringSlowsync; // do not update client records (due to merge) in slowsync (However, updates can still occur in first-time sync and if server wins conflict) sInt8 fUpdateServerDuringSlowsync; // do not update server records during NON-FIRST-TIME slowsync (but do it for first sync!) sInt8 fAllowMessageRetries; // allow that client sends same message ID again (retry attempt) sInt8 fStrictExecOrdering; // requires strict SyncML-standard ordering of status responses sInt8 fTreatCopyAsAdd; // treat COPY like ADD (needed for Calmeno/Weblicon clients) sInt8 fCompleteFromClientOnly; // perform complete from-client-only session (non conformant, Synthesis before 2.9.8.2 style) sInt32 fRequestMaxTime; // max time [seconds] allowed for processing a single request, 0=unlimited, -1=not specified TCharSets fDefaultOutCharset; // default charset for generation TCharSets fDefaultInCharset; // default charset for input interpretation TSyError fRejectStatusCode; // if >=0, attempt to connect will always be rejected with given status code sInt8 fForceUTC; // force sending time in UTC (overrides SyncML 1.1 devInf flag) sInt8 fForceLocaltime; // force sending time in localtime (overrides SyncML 1.1 devInf flag) #ifndef MINIMAL_CODE string fRemoteDescName; // descriptive name of remote #endif #ifdef SCRIPT_SUPPORT string fRuleScriptTemplate; // template for rule script #endif // DevInf in XML format which is to be used instead of the one sent by peer. // If set, it is evaluated after identifying the peer based on the DevInf // that it has sent and before applying other remote rule workarounds. // XML DevInf directly from XML config. string fOverrideDevInfXML; SmlDevInfDevInfPtr_t fOverrideDevInfP; VoidPtr_t fOverrideDevInfBufferP; // list of subrules to activate TRemoteRulesList fSubRulesList; // flag if this is a final rule (if matches, no more rules will be checked) bool fFinalRule; // flag if this is a subrule (cannot match by itself) bool fSubRule; protected: // check config elements #ifndef HARDCODED_CONFIG virtual bool localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine); #endif virtual void clear(); }; // TRemoteRuleConfig #endif // NO_REMOTE_RULES // session config class TSessionConfig: public TConfigElement { typedef TConfigElement inherited; public: TSessionConfig(const char *aElementName, TConfigElement *aParentElementP); virtual ~TSessionConfig(); // Properties // - session timeout (in seconds) sInt32 fSessionTimeout; // - Maximally supported SyncML version TSyncMLVersions fMaxSyncMLVersionSupported; // - Minimally supported SyncML version TSyncMLVersions fMinSyncMLVersionSupported; // - support of server alerted sync codes bool fAcceptServerAlerted; #ifndef NO_REMOTE_RULES // - list of remote rules TRemoteRulesList fRemoteRulesList; #endif // - simple auth string fSimpleAuthUser; string fSimpleAuthPassword; // - local datastores TLocalDSList fDatastores; #ifndef MINIMAL_CODE // - logfile string fLogFileName; string fLogFileFormat; string fLogFileLabels; bool fLogEnabled; uInt32 fDebugChunkMaxSize; #endif bool fRelyOnEarlyMaps; // if set, we rely on early maps sent by clients for adds from the previous session // defaults for remote-rule configurable behaviour bool fUpdateClientDuringSlowsync; // do not update client records (due to merge) in slowsync (However, updates can still occur in first-time sync and if server wins conflict) bool fUpdateServerDuringSlowsync; // do not update server records during NON-FIRST-TIME slowsync (but do it for first sync!) bool fAllowMessageRetries; // allow that client sends same message ID again (retry attempt) uInt32 fRequestMaxTime; // max time [seconds] allowed for processing a single request, 0=unlimited sInt32 fRequestMinTime; // min time [seconds] spent until returning answer (for debug purposes, 0=no minimum time) bool fCompleteFromClientOnly; // perform complete from-client-only session (non conformant, Synthesis before 2.9.8.2 style) // default value for flag to send property lists in CTCap bool fShowCTCapProps; // default value for flag to send type/size in CTCap for SyncML 1.0 (disable as old clients like S55 crash on this) bool fShowTypeSzInCTCap10; // flag to enable SyncEvolution-specific sync mode extensions in outgoing devInf. bool fSyncModeExtensions; // default value for sending end date-only values (like DTEND) as last time unit of previous day (i.e. 23:59:59, inclusive) // instead of midnight of next day (exclusive, like in iCalendar 2.0) bool fVCal10EnddatesSameDay; // instead of folding long lines (as required by the standard) use one line per property bool fDoNotFoldContent; // - set if we should show default parameter in mimo_old types as list of s for each value // Note that this is a tristate: 0=no, 1=yes, -1=auto (=yes for =SyncML 1.2, // thus making it work for Nokia 7610 (1.1) as well as E-Series like E90) sInt8 fEnumDefaultPropParams; // decides whether multi-threading for the datastores will be used bool fMultiThread; // defines if the engine waits with continuing interrupted commands until previous part received status bool fWaitForStatusOfInterrupted; // accept delete commands for already deleted items with 200 (rather that 404 or 211) bool fDeletingGoneOK; // abort if all items sent to remote fail bool fAbortOnAllItemsFailed; // - Session user time context (what time zone the current session's user is in, for clients w/o TZ/UTC support) timecontext_t fUserTimeContext; #ifdef SCRIPT_SUPPORT // session init script string fSessionInitScript; // Error status handling scripts string fSentItemStatusScript; string fReceivedItemStatusScript; // session init script string fSessionFinishScript; // custom GET command handler script string fCustomGetHandlerScript; // custom GET and PUT command generator scripts string fCustomGetPutScript; string fCustomEndPutScript; // custom PUT and RESULT handler script string fCustomPutResultHandlerScript; #endif // public methods TLocalDSConfig *getLocalDS(const char *aName, uInt32 aDBTypeID=0); lineartime_t getSessionTimeout(void) { return fSessionTimeout * secondToLinearTimeFactor; }; // - MUST be called after creating config to load (or pre-load) variable parts of config // such as binfile profiles. If aDoLoose==false, situations, where existing config // is detected but cannot be re-used will return an error. With aDoLoose==true, config // files etc. are created even if it means a loss of data. virtual localstatus loadVarConfig(bool aDoLoose=false) { return LOCERR_OK; } protected: // check config elements #ifndef HARDCODED_CONFIG virtual bool localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine); virtual TLocalDSConfig *newDatastoreConfig(const char *aName, const char *aType,TConfigElement *aParentP); #endif virtual void clear(); virtual void localResolve(bool aLastPass); }; // TSessionConfig // forward class TLocalEngineDS; // Container types typedef std::list TLocalDataStorePContainer; // contains local data stores // Sync session class TSyncSession { friend class TSmlCommand; friend class TSyncHeader; friend class TAlertCommand; friend class TSyncCommand; friend class TStatusCommand; friend class TSyncOpCommand; friend class TRemoteDataStore; friend class TLocalEngineDS; #ifdef SUPERDATASTORES friend class TSuperDataStore; #endif public: // constructors/destructors TSyncSession( TSyncAppBase *aSyncAppBaseP, // the owning application base (dispatcher/client base) const char *aSessionID // a session ID ); virtual ~TSyncSession(); /// @brief terminate a session. /// @Note: Termination is final - session cannot be restarted by RestartSession() after /// calling this routine virtual void TerminateSession(void); // Announce destruction of descendant to all datastores which might have direct links to these descendants and must cancel those void announceDestruction(void); ///< must be called by derived class' destructors to allow datastores to detach from agent BEFORE descendant destructor has run // Reset session virtual void ResetSession(void); ///< resets session as if created totally new. Descendants must rollback any pending database transactions etc. void InternalResetSessionEx(bool terminationCall); // static implementation for calling through virtual destructor and virtual ResetSession(); #ifdef DBAPI_TUNNEL_SUPPORT // Initialize a datastore tunnel session virtual localstatus InitializeTunnelSession(cAppCharP aDatastoreName) { return LOCERR_NOTIMP; }; // is usually implemented in customimplagent, as it depends on DBApi architecture virtual TLocalEngineDS *getTunnelDS() { return NULL; }; // is usually implemented in customimplagent #endif // DBAPI_TUNNEL_SUPPORT #ifdef PROGRESS_EVENTS // Create Session level progress event bool NotifySessionProgressEvent( TProgressEventType aEventType, TLocalDSConfig *aDatastoreID, sInt32 aExtra1, sInt32 aExtra2, sInt32 aExtra3 ); // Handle (or dispatch) Session level progress event virtual bool HandleSessionProgressEvent(TEngineProgressInfo aProgressInfo) { return true; }; // no handling by default #endif // PROGRESS_EVENTS // called when incoming SyncHdr fails to execute virtual bool syncHdrFailure(bool aTryAgain) = 0; // Abort session void AbortSession(TSyError aStatusCode, bool aLocalProblem, TSyError aReason=0); // resets session and sets aborted flag to prevent further processing of message void MarkSuspendAlertSent(bool aSent); // Suspend session void SuspendSession(TSyError aReason); // Session status bool isAborted(void) { return fAborted; }; // test abort status bool isSuspending(void) { return fSuspended; }; // test if flagged for suspend bool isSuspendAlertSent (void) { return fSuspendAlertSent; }; // test if suspend alert was already sent bool isAllSuccess(void); // test if session was completely successful void DatastoreFailed(TSyError aStatusCode, bool aLocalProblem=false); // let session know that datastore has failed void DatastoreHadErrors(void) { fErrorItemDatastores++; }; // let session know that sync was ok, but some items had errors bool outgoingMessageFull(void) { return fOutgoingMessageFull; }; // test if outgoing full bool isInterrupedCmdPending(void) { return fInterruptedCommandP!=NULL; }; bool getIncomingState(void) { return fIncomingState; }; // stop processing commands in this message void AbortCommandProcessing(TSyError aStatusCode); // all further commands in message will be answered with given status // returns remaining time for request processing [seconds] virtual sInt32 RemainingRequestTime(void) { return 0x7FFFFFFF; }; // quasi infinite // forget commands waiting to be sent when header is generated void forgetHeaderWaitCommands(void); // SyncML toolkit workspace access void setSmlWorkspaceID(InstanceID_t aSmlWorkspaceID); InstanceID_t getSmlWorkspaceID(void) { return fSmlWorkspaceID; }; const char *getEncodingName(void); // encoding suffix in MIME type SmlEncoding_t getEncoding(void) { return fEncoding; }; // current encoding void setEncoding(SmlEncoding_t aEncoding); // set encoding for session void addEncoding(string &aString); // add current encoding spec to given (type-)string sInt32 getSmlWorkspaceFreeBytes(void) { return ((sInt32) smlGetFreeBuffer(fSmlWorkspaceID)); }; #ifdef ENGINEINTERFACE_SUPPORT /// @brief Get new session key to access details of this session virtual appPointer newSessionKey(TEngineInterface *aEngineInterfaceP) = 0; #endif // ENGINEINTERFACE_SUPPORT // session handling // - get session owner (dispatcher/clientbase) TSyncAppBase *getSyncAppBase(void) { return fSyncAppBaseP; } // - get time when session was last used lineartime_t getSessionLastUsed(void) { return fSessionLastUsed; }; // - get time when session was started and ended lineartime_t getSessionStarted(void) { return fSessionStarted; }; // - get time when last request started processing lineartime_t getLastRequestStarted(void) { return fLastRequestStarted; }; // - update last used time void SessionUsed(void) { fSessionLastUsed=getSystemNowAs(TCTX_UTC); }; // - session custom time zones object access GZones *getSessionZones(void) { return &fSessionZones; }; // - convenience version for getting time lineartime_t getSystemNowAs(timecontext_t aContext) { return sysync::getSystemNowAs(aContext,getSessionZones()); }; // debug and log printing (should NOT be virtual, so that they can be used in destructors) void DebugShowCfgInfo(void); // show some information about the config //%%%void LogPrintf(const char *text, ...); //%%%void LogPuts(const char *text); // properties TSyncMLVersions getSyncMLVersion(void) { return fSyncMLVersion; }; const char *getLocalURI(void) { return fLocalURI.c_str(); }; const char *getInitialLocalURI(void) { return fInitialLocalURI.c_str(); }; const char *getRemoteURI(void) { return fRemoteURI.c_str(); }; const char *getSynchdrSessionID(void) { return fSynchdrSessionID.c_str(); }; const char *getLocalSessionID(void) { return fLocalSessionID.c_str(); }; localstatus getAbortReasonStatus(void) { return fLocalAbortReason ? localError(fAbortReasonStatus) : syncmlError(fAbortReasonStatus); }; #ifndef MINIMAL_CODE const char *getRemoteInfoString(void) { return fRemoteInfoString.c_str(); }; const char *getRemoteDescName(void) { return fRemoteDescName.c_str(); }; const char *getSyncUserName(void) { return fSyncUserName.c_str(); }; #endif // MINIMAL_CODE sInt32 getLastIncomingMsgID(void) { return fIncomingMsgID; }; void setSessionBusy(bool aBusy) { fSessionIsBusy=aBusy; }; // make session behave busy generally bool getReadOnly(void) { return fReadOnly; }; // read-only option void setReadOnly(bool aReadOnly) { fReadOnly=aReadOnly; }; // read-only option // - check if we can handle UTC time (devices without time zone might override this) virtual bool canHandleUTC(void) { return true; }; // assume yes // helpers // - get session relative URI const char *SessionRelativeURI(const char *aURI) { return relativeURI(aURI,getLocalURI()); }; // - add local datastore from config TLocalEngineDS *addLocalDataStore(TLocalDSConfig *aLocalDSConfigP); // - add local type void addLocalItemType(TSyncItemType *aItemTypeP) { fLocalItemTypes.push_back(aItemTypeP); }; // - find local datatype by config pointer (used to avoid duplicating types // in session if used by more than a single datastore) TSyncItemType *findLocalType(TDataTypeConfig *aDataTypeConfigP); // - find implemented remote datatype by config pointer (and related datastore, if any) TSyncItemType *findRemoteType(TDataTypeConfig *aDataTypeConfigP, TSyncDataStore *aRelatedRemoteDS); // internal processing events implemented in derived classes // - message start and end virtual bool MessageStarted(SmlSyncHdrPtr_t aContentP, TStatusCommand &aStatusCommand, bool aBad=false)=0; virtual void MessageEnded(bool aIncomingFinal)=0; // - get command item processing, may return a Results command. Must set status to non-404 if get could be served virtual TResultsCommand *processGetItem(const char *aLocUri, TGetCommand *aGetCommandP, SmlItemPtr_t aGetItemP, TStatusCommand &aStatusCommand); // - put and results command processing virtual void processPutResultItem(bool aIsPut, const char *aLocUri, TSmlCommand *aPutResultsCommandP, SmlItemPtr_t aPutResultsItemP, TStatusCommand &aStatusCommand); // - alert processing virtual TSmlCommand *processAlertItem( uInt16 aAlertCode, // alert code SmlItemPtr_t aItemP, // alert item to be processed (as one alert can have multiple items) SmlCredPtr_t aCredP, // alert cred element, if any TStatusCommand &aStatusCommand, // pre-set 200 status, can be modified in case of errors TLocalEngineDS *&aLocalDataStoreP // receives datastore pointer, if alert affects a datastore ); // - handle status received for SyncHdr, returns false if not handled virtual bool handleHeaderStatus(TStatusCommand * /* aStatusCmdP */) { return false; } // no special handling by default // - map operation virtual bool processMapCommand( SmlMapPtr_t aMapCommandP, // the map command contents TStatusCommand &aStatusCommand, // pre-set 200 status, can be modified in case of errors bool &aQueueForLater ); // Sync processing (command group) // - start sync group virtual bool processSyncStart( SmlSyncPtr_t aSyncP, // the Sync element TStatusCommand &aStatusCommand, // pre-set 200 status, can be modified in case of errors bool &aQueueForLater // will be set if command must be queued for later (re-)execution ) = 0; // - end sync group virtual bool processSyncEnd(bool &aQueueForLater); // end of sync group // - process generic sync command item within Sync group // - returns true (and unmodified or non-200-successful status) if // operation could be processed regularily // - returns false (but probably still successful status) if // operation was processed with internal irregularities, such as // trying to delete non-existant item in datastore with // incomplete Rollbacks (which returns status 200 in this case!). bool processSyncOpItem( TSyncOperation aSyncOp, // the operation SmlItemPtr_t aItemP, // the item to be processed SmlMetInfMetInfPtr_t aMetaP, // command-wide meta, if any TLocalEngineDS *aLocalSyncDatastore, // the local datastore for this syncop item TStatusCommand &aStatusCommand, // pre-set 200 status, can be modified in case of errors bool &aQueueForLater // must be set if item cannot be processed now, but must be processed later ); // message handling // - get current size of message sInt32 getOutgoingMessageSize(void) { return fOutgoingMsgSize; }; // returns currently assembled message size // - get byte statistics (only implemented in server so far) virtual uInt32 getIncomingBytes(void) { return 0; }; virtual uInt32 getOutgoingBytes(void) { return 0; }; // - get how many bytes may not be used in the outgoing message buffer // because of maxMsgSize restrictions sInt32 getNotUsableBufferBytes(void); // - get max size outgoing message may have (either defined by remote's maxmsgsize or local buffer space) sInt32 getMaxOutgoingSize(void); // - returns true if given number of bytes are transferable // (not exceeding MaxMsgSize (in SyncML 1.0) or MaxObjSize (SyncML 1.1 and later) bool dataSizeTransferable(uInt32 aDataBytes); // - update outgoing message size void incOutgoingMessageSize(sInt32 aIncrement) { fOutgoingMsgSize+=aIncrement; }; // - get message-global noResp status bool getMsgNoResp(void) { return fMsgNoResp; } // - get next outgoing command ID sInt32 getNextOutgoingCmdID(void) { return (++fOutgoingCmdID); } // - get next outgoing command ID without actually consuming it sInt32 peekNextOutgoingCmdID(void) { return (fOutgoingCmdID+1); } // - get current outgoing message ID sInt32 getOutgoingMsgID(void) { return fOutgoingMsgID; } // command handling // - issue a command (and put it to status queue if it expects a result) bool issue(TSmlCommand * &aSyncCommandP, TSmlCommandPContainer &aNextMessageCommands, TSmlCommand * &aInterruptedCommandP, bool aNoResp=false, bool aIsOKSyncHdrStatus=false ); bool issuePtr(TSmlCommand *aSyncCommandP, TSmlCommandPContainer &aNextMessageCommands, TSmlCommand * &aInterruptedCommandP, bool aNoResp=false, bool aIsOKSyncHdrStatus=false); // - issue a command in SyncBody context (uses session's interruptedCommand/NextMessageCommands) bool issueRoot(TSmlCommand * &aSyncCommandP, bool aNoResp=false, bool aIsOKSyncHdrStatus=false ); bool issueRootPtr(TSmlCommand *aSyncCommandP, bool aNoResp=false, bool aIsOKSyncHdrStatus=false ); // queue a SyncBody context command for issuing after incoming message // has been processed (and answers generated) void queueForIssueRoot( TSmlCommand * &aSyncCommandP // the command ); // issue a command, but queue it if outgoing package has not begun yet void issueNotBeforePackage( TPackageStates aPackageState, TSmlCommand *aSyncCommandP // the command ); // - session continuation and status void nextMessageRequest(void); bool sessionMustContinue(void); virtual void essentialStatusReceived(void) { /* NOP here */ }; void delayExecUntilNextRequest(TSmlCommand *aCommand); bool onlyItemChangesPending(); bool onlySyncPending(); bool tryDelayedExecutionCommands(); // returns syncEndAfterSyncPackageEnd bool executeDelayedCmd(TSmlCommand *aCmdP); // wrapper around TSmlCommand::execute() which issues queued Status commands if any are pending bool delayedSyncEndsPending(void) { return fDelayedExecSyncEnds>0; }; // - continue interrupted or prevented issue in next package void ContinuePackageRoot(void); void ContinuePackage( TSmlCommandPContainer &aNextMessageCommands, TSmlCommand * &aInterruptedCommandP ); // - mark all pending items for a datastore for resume // (those items that are in a session queue for being issued or getting status) void markPendingForResume(TLocalEngineDS *aForDatastoreP); void markPendingForResume( TSmlCommandPContainer &aNextMessageCommands, TSmlCommand *aInterruptedCommandP, TLocalEngineDS *aForDatastoreP ); // access to session info from commands bool mustSendDevInf(void) { return fRemoteMustSeeDevinf; }; // - access DevInf (session owned) SmlItemPtr_t getLocalDevInfItem(bool aAlertedOnly, bool aWithoutCTCapProps); // - analyze devinf of remote party (can be derived to add client or server specific analysis) virtual localstatus analyzeRemoteDevInf( SmlDevInfDevInfPtr_t aDevInfP ); // - get possibly cached devinf for specified device, passes ownership of // created devinf structure to caller // returns false if no devinf could be loaded virtual bool loadRemoteDevInf(const char * /* aDeviceID */, SmlDevInfDevInfPtr_t & /* aDevInfP */) { return false; }; // - save devinf to cache for specified device // return false if devinf cannot be cached virtual bool saveRemoteDevInf(const char * /* aDeviceID */, SmlDevInfDevInfPtr_t /* aDevInfP */) { return false; }; // - finish outgoing Message, returns true if final message of package bool FinishMessage(bool aAllowFinal, bool aForceNonFinal=false); // - returns true if session has pending commands bool hasPendingCommands(void); // - incoming message processing aborted (EndMessage will not get called, clean up) void CancelMessageProcessing(void); // entry points for SyncML Toolkit callbacks // - message handling Ret_t StartMessage(SmlSyncHdrPtr_t aContentP); Ret_t EndMessage(Boolean_t final); // - grouping commands Ret_t StartSync(SmlSyncPtr_t aContentP); Ret_t EndSync(void); #ifdef ATOMIC_RECEIVE Ret_t StartAtomic(SmlAtomicPtr_t aContentP); Ret_t EndAtomic(void); #endif #ifdef SEQUENCE_RECEIVE Ret_t StartSequence(SmlSequencePtr_t aContentP); Ret_t EndSequence(void); #endif // - commands Ret_t AddCmd(SmlAddPtr_t aContentP); Ret_t AlertCmd(SmlAlertPtr_t aContentP); Ret_t DeleteCmd(SmlDeletePtr_t aContentP); Ret_t GetCmd(SmlGetPtr_t aContentP); Ret_t PutCmd(SmlPutPtr_t aContentP); #ifdef MAP_RECEIVE Ret_t MapCmd(SmlMapPtr_t aContentP); #endif #ifdef RESULT_RECEIVE Ret_t ResultsCmd(SmlResultsPtr_t aContentP); #endif Ret_t StatusCmd(SmlStatusPtr_t aContentP); Ret_t ReplaceCmd(SmlReplacePtr_t aContentP); #ifdef COPY_RECEIVE Ret_t CopyCmd(SmlReplacePtr_t aContentP); #endif Ret_t MoveCmd(SmlReplacePtr_t aContentP); // - error handling Ret_t HandleError(void); Ret_t DummyHandler(const char* msg); // - Other Callbacks: routed directly to appropriate session, error if none #ifdef SYNCSTATUS_AT_SYNC_CLOSE TStatusCommand *fSyncCloseStatusCommandP; #endif #ifdef SYDEBUG // Message dump void DumpSyncMLMessage(bool aOutgoing); void DumpSyncMLBuffer(MemPtr_t aBuffer, MemSize_t aBufSize, bool aOutgoing, Ret_t aDecoderError); uInt32 fDumpCount; // XML translations of communication // - recoding instances InstanceID_t fOutgoingXMLInstance,fIncomingXMLInstance; // - routines void XMLTranslationIncomingStart(void); void XMLTranslationOutgoingStart(void); void XMLTranslationIncomingEnd(void); void XMLTranslationOutgoingEnd(void); // - flags bool fXMLtranslate; // dump XML translation of SyncML traffic bool fMsgDump; // dump raw SyncML messages #endif // SYDEBUG // log writing #ifndef MINIMAL_CODE void WriteLogLine(const char *aLogline); bool logEnabled(void) { return fLogEnabled; }; #endif // MINIMAL_CODE // current database date & time (defaults to system time) virtual lineartime_t getDatabaseNowAs(timecontext_t aContext) { return getSystemNowAs(aContext); }; // devinf void remoteGotDevinf(void) { fRemoteGotDevinf=true; }; void remoteMustSeeDevinf(void) { fRemoteMustSeeDevinf=true; }; // config access TRootConfig *getRootConfig(void); // access to logging for session #ifdef SYDEBUG TDebugLogger *getDbgLogger(void) { return &fSessionLogger; }; uInt32 getDbgMask(void) { return fSessionDebugLogs ? fSessionLogger.getMask() : 0; }; #endif // SYDEBUG // Remote-specific options, will be set up by checkClient/ServerSpecifics() bool fLimitedRemoteFieldLengths; // if set, all fields will be assumed to have limited, but unknown field length (used for cut-off detection) bool fDontSendEmptyProperties; // if set, no empty properties will be sent to client bool fDoQuote8BitContent; // set if 8-bit chars should generally be encoded with QP in MIME-DIR bool fDoNotFoldContent; // set if content should not be folded in MIME-DIR bool fNoReplaceInSlowsync; // prevent replace commands totally at slow sync bool fTreatRemoteTimeAsLocal; // treat remote time as localtime even if it carries different time zone information ("Z" suffix or zone spec) bool fTreatRemoteTimeAsUTC; // treat remote time as UTC even if it carries different time zone information (no suffix or zone spec) bool fVCal10EnddatesSameDay; // send end date-only values (like DTEND) as last time unit of previous day (i.e. 23:59:59, inclusive) instead of midnight of next day (exclusive, like in iCalendar 2.0) bool fIgnoreDevInfMaxSize; // ignore specification in CTCap (when device has bad specs like in E90 for example) bool fIgnoreCTCap; // ignore entire ctcap bool fDSPathInDevInf; // use actual DS path as used in Alert for creating datastore devInf (needed for newer Nokia clients) bool fDSCgiInDevInf; // also show CGI as used in Alert for creating datastore devInf (needed for newer Nokia clients) bool fUpdateClientDuringSlowsync; // prevent updates of client records during non-first-time slow sync bool fUpdateServerDuringSlowsync; // do not update server records during NON-FIRST-TIME slowsync (but do it for first sync!) bool fAllowMessageRetries; // allow that client sends same message ID again (retry attempt) bool fStrictExecOrdering; // if set (=default, SyncML standard requirement), statuses are sent in order of incoming commands (=execution is ordered) bool fTreatCopyAsAdd; // treat copy commands as if they were adds bool fCompleteFromClientOnly; // perform complete from-client-only session (non conformant, Synthesis before 2.9.8.2 style) sInt32 fRequestMaxTime; // max time [seconds] allowed for processing a single request, 0=unlimited sInt32 fRequestMinTime; // min time [seconds] spent until returning answer (for debug purposes, 0=no minimum time) TCharSets fDefaultOutCharset; // default charset for output generation TCharSets fDefaultInCharset; // default charset for input interpretation #ifndef NO_REMOTE_RULES bool isActiveRule(cAppCharP aRuleName, TRemoteRuleConfig *aRuleP=NULL); // check if given rule (by name, or if aRuleName=NULL by rule pointer) is active TRemoteRulesList fActiveRemoteRules; // list of remote rules currently active in this session #endif // NO_REMOTE_RULES // legacy mode bool fLegacyMode; // if set, remote will see the types marked preferred="legacy" in devInf as preferred types, not the regular preferred ones // lenient mode bool fLenientMode; // if set, enine is less strict in checking (e.g. client-side anchor checking, terminating session while some status missing etc.) #ifdef EXPIRES_AFTER_DATE // copy of scrambled now sInt32 fCopyOfScrambledNow; #endif // EXPIRES_AFTER_DATE // Sync datastores // - find local datastore by URI and separate identifying from optional part of URI TLocalEngineDS *findLocalDataStoreByURI(const char *aURI,string *aOptions=NULL, string *aIdentifyingURI=NULL); // - find local datastore by relative path (may not contain any CGI) TLocalEngineDS *findLocalDataStore(const char *aDatastoreURI); // - find local datastore by datastore handle (=config pointer) TLocalEngineDS *findLocalDataStore(void *aDSHandle); // - find remote datastore by (remote party specified) URI TRemoteDataStore *findRemoteDataStore(const char *aDatastoreURI); // Profiling TP_DEFINFO(fTPInfo) // access to config TSessionConfig *getSessionConfig(void); #ifdef SCRIPT_SUPPORT // access to session script context TScriptContext *getSessionScriptContext(void) { return fSessionScriptContextP; }; #endif // SCRIPT_SUPPORT // unprotected options // - set if we should send property lists in CTCap bool fShowCTCapProps; // - set if we should send type/size in CTCap for SyncML 1.0 (disabled by default as old clients like S55 crash on this) bool fShowTypeSzInCTCap10; // - set if we should show default parameter in mimo_old types as list of s for each value // Note that this is a tristate: 0=no, 1=yes, -1=auto (=yes for =SyncML 1.2, // thus making it work for Nokia 7610 (1.1) as well as E-Series like E90) sInt8 fEnumDefaultPropParams; #ifdef SYDEBUG /// @todo /// fSessionDebugLogs should be removed (but this needs rewriting of the XML and SML dumpers) // - set if debug log for this session is enabled bool fSessionDebugLogs; #endif // SYDEBUG #ifndef MINIMAL_CODE // - se if normal log for this session is enabled bool fLogEnabled; // real log file enabled #endif // MINIMAL_CODE // - remote options (SyncML 1.1) bool fRemoteWantsNOC; // remote wants number-of-changes info bool fRemoteCanHandleUTC; // remote can handle UTC time bool fRemoteSupportsLargeObjects; // remote can handle large object splitting/reassembly // - object size handling sInt16 fOutgoingCmds; // number of outgoing commands in message, but NOT counting SyncHdr status and Alert 222 status (which are ALWAYS there even in an otherwise empty message) sInt32 fMaxRoomForData; // max room for data (free bytes available for data when startin a command) // - Session user time context timecontext_t fUserTimeContext; protected: // Session control // - terminate all datastores void TerminateDatastores(localstatus aAbortStatusCode=408); // - remove all datastores void ResetAndRemoveDatastores(void); // - session layer credential checking bool checkCredentials(const char *aUserName, const SmlCredPtr_t aCredP, TStatusCommand &aStatusCommand); bool checkCredentials(const char *aUserName, const char *aCred, TAuthTypes aAuthType); // - session layer challenge SmlChalPtr_t newSessionChallenge(void); // datastore and type vars // - list of local datastores TLocalDataStorePContainer fLocalDataStores; // - list of remote (client-side) datastores TRemoteDataStorePContainer fRemoteDataStores; bool receivedSyncModeExtensions(); // any of the remote datastores in fRemoteDataStores // had custom sync modes // - list of local content types TSyncItemTypePContainer fLocalItemTypes; // - list of remote item types TSyncItemTypePContainer fRemoteItemTypes; // - Local Database currently targeted by a Sync command, NULL if none // Note: This must be set correctly whenever sync commands (and syncend) are processed // This can be during actual receiving them, OR while processing them from the fDelayedExecutionCommands // queue. TLocalEngineDS *fLocalSyncDatastoreP; // set if we have received DevInf for remote DataStores / CTCap bool fRemoteDevInfKnown; // remote devInf known bool fRemoteDataStoresKnown; // data stores known bool fRemoteDataTypesKnown; // CTCap known bool fRemoteDevInfLock; // set after starting sync according to devInf we had to prevent in-sync devInf changes // see if we have sent or should send DevInf to remote bool fRemoteGotDevinf; // set if we sent a Put or Result containig DevInf bool fRemoteMustSeeDevinf; // set if we should force (Put) devinf to remote bool fCustomGetPutSent; // set if custom get/put has been sent to remote // DevInf // - get new sml list of all datastores (owner of list is transferred, but items are still owned by datastore SmlDevInfDatastoreListPtr_t newDevInfDataStoreList(bool aAlertedOnly, bool aWithoutCTCapProps); SmlDevInfCtcapListPtr_t newLocalCTCapList(bool aAlertedOnly, TLocalEngineDS *aOnlyForDS, bool aWithoutCTCapProps); // - get new DevInf for this session (as Result for GET or item for PUT) virtual SmlDevInfDevInfPtr_t newDevInf(bool aAlertedOnly, bool aWithoutCTCapProps); // - called to issue custom get and put commands virtual void issueCustomGetPut(bool aGotDevInf, bool aSentDevInf); virtual void issueCustomEndPut(void); // Sync processing // - prepare for sending and receiving Sync commands localstatus initSync( const char *aLocalDatastoreURI, const char *aRemoteDatastoreURI ); // Command processing // - process a command (analyze and execute it), // exception-free for simple call from smlCallback adaptors Ret_t process(TSmlCommand *aSyncCommandP); // - handle incoming status // exception-free for simple call from smlCallback adaptors Ret_t handleStatus(TStatusCommand *aStatusCommandP); // helpers for derived classes // - create, send and delete SyncHeader "command" void issueHeader(bool aNoResp=false); // - process the SyncHeader "command" Ret_t processHeader(TSyncHeader *aSyncHdrP); // Helpers for commands // - create new SyncHdr structure for TSyncHeader command // (here because all data for this is in session anyway) SmlSyncHdrPtr_t NewOutgoingSyncHdr(bool aOutgoingNoResp=false); // virtuals for overriding in specialized session derivates // - device ID must be handled on session level as it might depend on session runtime conditions // (like special pseudo-unique ID for Oracle servers when basic id is not unique etc.) virtual string getDeviceID(void)=0; virtual string getDeviceType(void)=0; // abstract, must be client or server // - get new response URI to be sent to remote party for subsequent messages TO local party virtual SmlPcdataPtr_t newResponseURIForRemote(void) { return NULL; }; // no RespURI by default // Authorisation // - required authentication type and mode virtual TAuthTypes requestedAuthType(void) = 0; // get preferred authentication type for authentication of remote party virtual bool isAuthTypeAllowed(TAuthTypes aAuthType) = 0; // test if auth type is allowed for authentication by remote party virtual bool messageAuthRequired(void) { return false; }; // no message-by-message auth by default // - get credentials/username to authenticate with remote party, NULL if none virtual SmlCredPtr_t newCredentialsForRemote(void) { return NULL; }; // normally (server case), none virtual const char * getUsernameForRemote(void) { return NULL; }; // normally (server case), none // - generate credentials (based on fRemoteNonce, fRemoteRequestedAuth, fRemoteRequestedAuthEnc) SmlCredPtr_t newCredentials(const char *aUser, const char *aPassword); public: // - URI to send outgoing message to virtual const char *getSendURI(void) { return ""; }; // none by default (and server) // - get common sync capabilities mask of this session (datastores might modify it) virtual uInt32 getSyncCapMask(void); // - check credentials, login to server virtual bool SessionLogin(const char *aUserName, const char *aAuthString, TAuthSecretTypes aAuthStringType, const char *aDeviceID); protected: // - get next nonce string top be sent to remote party for subsequent MD5 auth virtual void getNextNonce(const char * /* aDeviceID */, string &aNextNonce) { aNextNonce.erase(); }; // empty nonce public: // - get nonce string for specified device virtual void getAuthNonce(const char * /* aDeviceID */, string &aAuthNonce) { aAuthNonce.erase(); }; // - check auth helpers bool checkAuthPlain( const char *aUserName, const char *aPassWord, const char *aNonce, // given values const char *aAuthString, TAuthSecretTypes aAuthStringType // check against this ); bool checkAuthMD5( const char *aUserName, const char *aMD5B64, const char *aNonce, // given values const char *aAuthString, TAuthSecretTypes aAuthStringType // check against this ); bool checkMD5WithNonce( const char *aStringBeforeNonce, const char *aNonce, // given input const char *aMD5B64Creds // credential string to check ); protected: // - helper functions (for use be derived classes) bool getAuthBasicUserPass(const char *aBasicCreds, string &aUsername, string &aPassword); // - load remote connect params (syncml version, type, format and last nonce) // Note: agents that can cache this information between sessions will load // last info here. virtual void loadRemoteParams(void) { fSyncMLVersion=syncml_vers_unknown; fRemoteRequestedAuth=auth_none; fRemoteRequestedAuthEnc=fmt_chr; fRemoteNonce.erase(); }; // static defaults // - save remote connect params for use in next session (if descendant implements it) virtual void saveRemoteParams(void) { /* nop */ }; // - Session level meta virtual SmlPcdataPtr_t newHeaderMeta(void); // - check remote devinf to detect special behaviour needed for some clients. Base class // does not do anything on server level (configured rules are handled at session level) virtual localstatus checkRemoteSpecifics(SmlDevInfDevInfPtr_t aDevInfP, SmlDevInfDevInfPtr_t *aOverrideDevInfP); // - remote device is analyzed, possibly save status virtual void remoteAnalyzed(void) { /* nop */ }; // - tell session whether it may accept an in the map // phase and restart the sync virtual bool allowAlertAfterMap() { return false; } // SyncML Toolkit interface InstanceID_t fSmlWorkspaceID; // SyncML toolkit workspace instance ID SmlEncoding_t fEncoding; // Current encoding type in SyncML toolkit instance // Session custom time zones GZones fSessionZones; // session timing lineartime_t fSessionLastUsed; // time when session was last used lineartime_t fSessionStarted; // time when session was started lineartime_t fLastRequestStarted; // time when last request was received // session busy status (used for session count limiting normally) bool fSessionIsBusy; // session type // - SyncML protocol version TSyncMLVersions fSyncMLVersion; // - outgoing authorisation TAuthTypes fRemoteRequestedAuth; // type of auth requested by the remote TFmtTypes fRemoteRequestedAuthEnc; // type of encoding requested by the remote string fRemoteNonce; // next nonce to be used to authenticate with remote bool fNeedAuth; // set if we need to authorize to remote for next message // session ID vars string fSynchdrSessionID; // SyncML-protocol ID of this sync session (client generated) string fLocalURI; // local party URI string fInitialLocalURI; // local URI used in first message (or preconfigured with ) string fLocalName; // local party optional name string fRemoteURI; // remote party URI (remote deviceID or URL) string fRemoteName; // remote party optional name string fRespondURI; // remote party URI to send response to string fLocalSessionID; // locally generated session ID (server generated) #ifndef MINIMAL_CODE string fRemoteDescName; // descriptive name of remote (set from DevInf and probably adjusted by remoterule) string fRemoteInfoString; // remote party information string (from DevInf) string fSyncUserName; // remote user name // 1:1 devInf details string fRemoteDevInf_devid; string fRemoteDevInf_devtyp; string fRemoteDevInf_mod; string fRemoteDevInf_man; string fRemoteDevInf_oem; string fRemoteDevInf_swv; string fRemoteDevInf_fwv; string fRemoteDevInf_hwv; #endif // MINIMAL_CODE #ifdef SCRIPT_SUPPORT // Session level script context TScriptContext *fSessionScriptContextP; #endif // SCRIPT_SUPPORT // Session options bool fReadOnly; // Session state vars // - incoming authorisation bool fSessionAuthorized; // session is (permanently) authorized, that is, further messages do not need authorization bool fMessageAuthorized; // this message is authorized sInt16 fAuthFailures; // count of failed authentication attempts by remote in a row (normally, server case), will cause abort if too many sInt16 fAuthRetries; // count of failed authentication attempts by myself at remote (normally, client case) // - session state TPackageStates fIncomingState; // incoming package state TPackageStates fCmdIncomingState; // while executing commands: state when command was received (actual might be different due to queueing) TSmlCommand *fCmdIncoming; // while executing command inside process(): command being processed TPackageStates fOutgoingState; // outgoing package state bool fRestarting; // Set to true in TSyncSession::processAlertItem() while processing the first Alert from a // client which requests another sync cycle. Applies to all further Alerts, cleared // when entering fOutgoingState==psta_sync again. bool fFakeFinalFlag; // special flag to work around broken resume implementations bool fNewOutgoingPackage; // set if first outgoing message in outgoing package bool fNeedToAnswer; // set if an answer to currently processed message is needed (will be set by issuing of first non-synchdr-status) sInt32 fIncomingMsgID; // last incoming message ID (0 if none received yet) sInt32 fOutgoingMsgID; // last outgoing message ID (0 if none sent yet) bool fMessageRetried; // if set (by TSyncHeader::execute()) we have received a retried message and should resend the last answer bool fAborted; // if set, session is being aborted (and will be deleted at EndRequest) bool fSuspended; // if set, session is being suspended (stopped processing commands, will send Suspend Alert to remote at next opportunity) bool fSuspendAlertSent; // if set, session has sent a suspend alert to the remote party uInt16 fFailedDatastores; uInt16 fErrorItemDatastores; TSyError fAbortReasonStatus; // if fAborted, this contains a status code what command has aborted the session bool fLocalAbortReason; // if aborted, this signals if aborted due to local or remote reason bool fInProgress; // if set, session is in progress and must persist beyond this request // incoming Message status bool fMsgNoResp; // if set, current message MUST not be responded to. Suppresses all status sendig attempts bool fIgnoreIncomingCommands; // if set, commands dispatched will be ignored TSyError fStatusCodeForIgnored; // if fIgnoreIncomingCommands is set, this status code will be used to reply all incoming commands // - incoming data from a split data item TSyncOpCommand *fIncompleteDataCommandP; // outgoing message status sInt32 fOutgoingCmdID; // last outgoing command ID (0 if none generated yet) bool fOutgoingStarted; // started preparing an outgoing message bool fOutgoingNoResp; // outgoing message does not want response at all // termination flag - set when TerminateSession() has finished executing bool fTerminated; // session is terminated (finally, not restartable!) private: // debug logging #ifdef SYDEBUG TDebugLogger fSessionLogger; // the logger #endif // SYDEBUG // internal vars TSyncAppBase *fSyncAppBaseP; // the owning application base (dispatcher/client base) /* %%% prepared, to be implemented. Currently constant limits sInt32 fMaxIncomingMsgSize; // limit for incoming message, if<>0, causes MaxMsgSize Meta on outgoing SyncHdr sInt32 fMaxIncomingObjSize; // limit for incoming objects, if<>0, causes MaxObjSize Meta on outgoing SyncHdr */ sInt32 fMaxOutgoingMsgSize; // max size of outgoing message, 0 if unlimited sInt32 fMaxOutgoingObjSize; // SyncML 1.1: max size of outgoing object, 0 if unlimited sInt32 fOutgoingMsgSize; // current size of outgoing message bool fOutgoingMessageFull; // outgoing message is full, message must be finished and sent // context-free command queues // - sent commands waiting for status TSmlCommandPContainer fStatusWaitCommands; // - received commands that could not be executed immediately TSmlCommandPContainer fDelayedExecutionCommands; sInt32 fDelayedExecSyncEnds; // - commands that must be queued until SyncHdr is generated TSmlCommandPContainer fHeaderWaitCommands; // SyncBody-context command queues // - commands to be issued only after all commands in this message have // been processed and answered by a status TSmlCommandPContainer fEndOfMessageCommands; // - commands waiting for being sent in next outgoing message TSmlCommandPContainer fNextMessageCommands; // - commands waiting for being sent in next outgoing package TSmlCommandPContainer fNextPackageCommands; // - outgoing command that was interrupted by end of message and must be continued in next message TSmlCommand *fInterruptedCommandP; // - counter that gets incremented once per Alert 222 and decremented when package contents get sent uInt32 fNextMessageRequests; // - sequence nesting level sInt32 fSequenceNesting; }; // TSyncSession // macros #define ISSUE_COMMAND(sp,c,l1,l2) { TSmlCommand* p=c; c=NULL; sp->issuePtr(p,l1,l2); } #define ISSUE_COMMAND_ROOT(sp,c) { TSmlCommand* p=c; c=NULL; sp->issueRootPtr(p); } #ifdef ENGINEINTERFACE_SUPPORT // Support for EngineModule common interface // ========================================= // session runtime parameters (such as access to session script vars) class TSessionKey : public TStructFieldsKey { typedef TStructFieldsKey inherited; public: TSessionKey(TEngineInterface *aEngineInterfaceP, TSyncSession *aSessionP) : inherited(aEngineInterfaceP), fSessionP(aSessionP) {}; virtual ~TSessionKey() {}; protected: // open subkey by name (not by path!) // - this is the actual implementation virtual TSyError OpenSubKeyByName( TSettingsKeyImpl *&aSettingsKeyP, cAppCharP aName, stringSize aNameSize, uInt16 aMode ); // the associated sync session TSyncSession *fSessionP; }; // TSessionKey #endif // ENGINEINTERFACE_SUPPORT } // namespace sysync #endif // SYNC_SESSION_H // eof libsynthesis-3.4.0.47.1/src/sysync/syncsessiondispatch.cpp000077500000000000000000001004641226375725500235770ustar00rootroot00000000000000/* * TSyncSessionDispatch * Global object, manages instantiation and removal of * TSyncSession objects, connects requests to sessions, * Interfaces between C-coded SyncML toolkit and SySync * C++ framework. * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * 2001-05-07 : luz : Created * */ #include "prefix_file.h" // %%%% Note: CW8.2 has bugs in SEH when optimization is turned on (even if we don't use SEH // here, we might call routines with SEH so be careful here) #pragma optimization_level 0 #include "sysync.h" #include "syncsessiondispatch.h" // TSyncSessionHandle // ================== // constructor TSyncSessionHandle::TSyncSessionHandle(TSyncAppBase *aAppBaseP) : fAppBaseP(aAppBaseP), fSessionP(NULL), fOutdated(false) { OBJDEBUGPRINTFX(fAppBaseP,DBG_OBJINST,("++++++++ TSyncSessionHandle created")); MP_SHOWCURRENT(DBG_OBJINST,"TSyncSessionHandle created"); // nop } // TSyncSessionHandle::TSyncSessionHandle // destructor TSyncSessionHandle::~TSyncSessionHandle() { if (fSessionP) { POBJDEBUGPRINTFX(fAppBaseP,DBG_ERROR,("TSyncSessionHandle deleted with unterminated session (deleting now as well...)")); MP_DELETE(DBG_OBJINST,"fSessionP",fSessionP); } fSessionP=NULL; MP_SHOWCURRENT(DBG_OBJINST,"TSyncSessionHandle deleting"); OBJDEBUGPRINTFX(fAppBaseP,DBG_OBJINST,("-------- TSyncSessionHandle destroyed")); } // TSyncSessionHandle::~TSyncSessionHandle // terminate and delete session. Must protect caller from exceptions // when termination/deletion fails. // NOTE: keeps session Enter()ed, to avoid any other thread to enter. bool TSyncSessionHandle::EnterAndTerminateSession(uInt16 aStatusCode) { // no locks here, so just call TerminateSession return TerminateSession(aStatusCode); } // TSyncSessionHandle::EnterAndTerminateSession // terminate and delete session. Must protect caller from exceptions // when termination/deletion fails. // NOTE: keeps session Enter()ed, to avoid any other thread to enter. bool TSyncSessionHandle::TerminateSession(uInt16 aStatusCode) { if (fSessionP) { // - Set abort code if not zero (not aborted, regular termination) if (aStatusCode) fSessionP->AbortSession(aStatusCode,true); // assume local cause // - terminate the session, which causes datastores to be terminated as well fSessionP->TerminateSession(); // - now actually delete TSyncSession *delP = fSessionP; fSessionP=NULL; // make sure we can't delete again under any circumstance delete delP; POBJDEBUGPRINTFX(fAppBaseP,DBG_TRANSP,("TerminateSession(%hd): deleted session successfully", aStatusCode)); } else { POBJDEBUGPRINTFX(fAppBaseP,DBG_TRANSP+DBG_EXOTIC,("TerminateSession(%hd) - no op, session was already terminated/deleted before", aStatusCode)); } return true; } // TSyncSessionHandle::TerminateSession // TSyncSessionDispatch // ==================== // Support for SySync Diagnostic Tool #ifdef SYSYNC_TOOL // get or create a session for use with the diagnostic tool TSyncAgent *TSyncSessionDispatch::getSySyToolSession(void) { TSyncAgent *sessionP=NULL; // the session (new or existing found in fSessions) if (fToolSessionHP) { sessionP = fToolSessionHP->fSessionP; } else { // - create session object with given ID fToolSessionHP = CreateSessionHandle(); sessionP = static_cast(fConfigP->fAgentConfigP)->CreateServerSession(fToolSessionHP,"SySyTool"); fToolSessionHP->fSessionP=sessionP; } return sessionP; } #endif // SYSYNC_TOOL // constructor TSyncSessionDispatch::TSyncSessionDispatch() : TSyncAppBase() { // this is a server engine fIsServer = true; // other init #ifdef SYSYNC_TOOL fToolSessionHP=NULL; // no tool session yet #endif } // TSyncSessionDispatch::TSyncSessionDispatch // immediately kill all sessions void TSyncSessionDispatch::TerminateAllSessions(uInt16 aStatusCode) { try { TSyncSessionHandlePContainer::iterator pos; for (pos=fSessions.begin(); pos!=fSessions.end(); ++pos) { if ((pos->second)->fSessionP) { (pos->second)->fSessionP->AbortSession(aStatusCode,true); (pos->second)->fSessionP->ResetSession(); // reset properly before deleting // delete the session handle including the session MP_DELETE(DBG_OBJINST,"leftover session",(pos->second)); } } // delete the session list fSessions.clear(); } catch (...) { } } // TSyncSessionDispatch::TerminateAllSessions // destructor TSyncSessionDispatch::~TSyncSessionDispatch() { fDeleting=true; // flag deletion to block calling critical (virtual) methods // delete all session handles // NOTE: fSessionslock is already gone as it is owned by // derived class TerminateAllSessions(500); // server error #ifdef SYSYNC_TOOL // delete tool session if (fToolSessionHP) { fToolSessionHP->fSessionP->ResetSession(); MP_DELETE(DBG_OBJINST,"leftover session",(fToolSessionHP)); fToolSessionHP=NULL; } #endif } // TSyncSessionDispatch::~TSyncSessionDispatch // Called from SyncML toolkit when a new SyncML message arrives // - finds appropriate session or creates new one // - dispatches to session's StartMessage Ret_t TSyncSessionDispatch::StartMessage( InstanceID_t aSmlWorkspaceID, // SyncML toolkit workspace instance ID VoidPtr_t aUserData, // user data, contains NULL or char* to transport-layer supported session ID SmlSyncHdrPtr_t aContentP // SyncML tookit's decoded form of the element ) { TSyncAgent *sessionP=NULL; // the session (new or existing found in fSessions) TSyncSessionHandle *sessionHP=NULL; Ret_t err; try { // obtain session (existing or new) // - lock access to list // NOTE: Basic policy is to keep sessions locked only while executing code // that cannot throw a SE or a C++ exception, as unlocking too much // (in a general exception catcher) makes much troubles. All Code // that might throw should be executed ONLY with session list released! LockSessions(); // - now get iterator TSyncSessionHandlePContainer::iterator pos=fSessions.end(); // - get SessionID, either from transport (aUserData) or from TargetURI string sessionID; AssignString(sessionID,(const char *)aUserData); if (!sessionID.empty()) { // - transport has provided a sessionID PDEBUGPRINTFX(DBG_PROTO,( "TSyncSessionDispatch::StartMessage called with transport layer session ID='%s'", sessionID.c_str() )); } else { // - try to get sessionID from TargetURI if (extractSessionID(smlSrcTargLocURIToCharP(aContentP->target),sessionID)) { PDEBUGPRINTFX(DBG_PROTO,( "TSyncSessionDispatch::StartMessage found session ID in Target.LocURI='%s'", sessionID.c_str() )); } } // - process session ID if (!sessionID.empty()) { // we seem to have a session ID pos=fSessions.find(sessionID); #ifdef SYDEBUG if (pos!=fSessions.end()) { PDEBUGPRINTFX(DBG_HOT,( "Session found by SessionID=%s", sessionID.c_str() )); } #endif } // now enter existing session or create new one if (pos!=fSessions.end()) { // found existing session: // - get handle sessionHP = (*pos).second; // - get session object pointer sessionP = sessionHP->fSessionP; PDEBUGPRINTFX(DBG_SESSION,("Entering found session...")); // Note: We have the session list locked, so we should not wait here for entering to avoid locking the entire server // - try entering int k=0; while (true) { if (sessionHP->EnterSession(0)) break; // successfully entered // could not enter. Temporarily release sessions list and wait 10 seconds ReleaseSessions(); if (k>60) { // 60*10 = 600 sec = 10 min waited, give up PDEBUGPRINTFX(DBG_ERROR,("Found session is locked for >%d seconds, giving up -> SML_ERR_UNSPECIFIC",k*10)); return SML_ERR_UNSPECIFIC; } PDEBUGPRINTFX(DBG_LOCK,("Session could not be entered after waiting %d seconds, keep trying",k*10)); // wait sleepLineartime(10*secondToLinearTimeFactor); // we need to re-find the session here, as we had given others control over the session list LockSessions(); pos=fSessions.find(sessionID); if (pos==fSessions.end()) { ReleaseSessions(); PDEBUGPRINTFX(DBG_HOT,( "SessionID=%s has disappeared from sessions list while we were waiting to enter it --> SML_ERR_UNSPECIFIC", sessionID.c_str() )); return SML_ERR_UNSPECIFIC; } // - get handle again sessionHP = (*pos).second; k++; } // Session is entered, so we can release the list (no other thread will be able to enter same session) ReleaseSessions(); // Show that we entered the session PDEBUGPRINTFX(DBG_SESSION,("Session entered")); } // if session already exists else { // we need a new session // Note: session list is still locked here PDEBUGPRINTFX(DBG_TRANSP+DBG_EXOTIC,("No session found, will need new one")); // - count sessions not belonging to this client sInt32 othersessioncount = 0; for (pos=fSessions.begin();pos!=fSessions.end();pos++) { // - get handle sessionHP = (*pos).second; // - get session sessionP=sessionHP->fSessionP; // check if session is for same device as current request if (strcmp(smlSrcTargLocURIToCharP(aContentP->source),sessionP->getRemoteURI())!=0) { // other device, count if not outdated if (!sessionHP->fOutdated) othersessioncount++; } else { // this device, set outdated flag to prevent inactive sessions from being // counted and limiting sessions sessionHP->fOutdated=true; } } // for PDEBUGPRINTFX(DBG_SESSION+DBG_EXOTIC,( "Found %ld sessions not related to device '%s'", (sInt32)othersessioncount, smlSrcTargLocURIToCharP(aContentP->source) )); // - get sessions that need to be deleted TSyncSessionHandlePList delList; collectTimedOutSessions(delList); // - now we can release the sessions list ReleaseSessions(); // - actually delete them while session list is again unlocked deleteListedSessions(delList); // Now create new session sessionHP = CreateAndEnterServerSession(NULL); // have sessionID generated // - get session object pointer sessionP = sessionHP->fSessionP; #ifdef CONCURRENT_DEVICES_LIMIT // - now check session count (makes session busy if licensed session count is exceeded) // Note: othersessioncount does not include our own session checkSessionCount(othersessioncount,sessionP); #endif } // now we should have a sessionP if (sessionP) { // Now let session handle SyncML header (start of message) // - sessionP and sessionHP are valid here // - assign pointers to allow direct // routing and calling between session and SyncML toolkit err=setSmlInstanceUserData(aSmlWorkspaceID,sessionP); // toolkit must know session (as userData) if (err!=SML_ERR_OK) throw(TSmlException("setSmlInstanceUserData",err)); // - let session know workspace ID sessionP->setSmlWorkspaceID(aSmlWorkspaceID); // session must know toolkit workspace // let session handle details of StartMessage callback return sessionP->StartMessage(aContentP); } else { PDEBUGPRINTFX(DBG_HOT,( "No session could be created --> SML_ERR_UNSPECIFIC", sessionID.c_str() )); return SML_ERR_UNSPECIFIC; } } catch (exception &e) { return HandleDecodingException(sessionP,"StartMessage",&e); } catch (...) { return HandleDecodingException(sessionP,"StartMessage",NULL); } } // TSyncSessionDispatch::StartMessage /// @brief Collect timed-out sessions and remove them from the session list /// @param aDeletableSessions to-be deleted sessions will be appended to this list /// @note session list must be locked before call! void TSyncSessionDispatch::collectTimedOutSessions(TSyncSessionHandlePList &aDeletableSessions) { TSyncAgent *sessionP=NULL; // the session (new or existing found in fSessions) TSyncSessionHandle *sessionHP=NULL; TAgentConfig *serverconfigP=NULL; // get agent config GET_CASTED_PTR(serverconfigP,TAgentConfig,fConfigP->fAgentConfigP,"missing agent (server) config"); // - find timed-out sessions and count sessions not belonging to this client TSyncSessionHandlePContainer::iterator pos; for (pos=fSessions.begin();pos!=fSessions.end();pos++) { // - get handle sessionHP = (*pos).second; // - get session sessionP=sessionHP->fSessionP; // - check if (getSystemNowAs(TCTX_UTC) > sessionP->getSessionLastUsed()+serverconfigP->getSessionTimeout()) { // this session is too old, queue it for killing aDeletableSessions.push_back(sessionHP); } } // for // now remove the outdated sessions from the main session list // to make sure no other process can possibly access them // - session list is locked once here TSyncSessionHandlePList::iterator delpos; DEBUGPRINTFX(DBG_SESSION,( "Now removing %ld outdated sessions from the session list", (sInt32)aDeletableSessions.size() )); for (delpos=aDeletableSessions.begin();delpos!=aDeletableSessions.end();delpos++) { // - get handle sessionHP = (*delpos); // - remove session handle from the list // NOTE: session list is already locked here, RemoveSession // MUST be called with locked session list! if (!(sessionHP == RemoveSession(sessionHP->fSessionP))) throw (TSyncException("invalid linked session/sessionhandle pair")); } } // collectTimedOutSessions /// @brief Try to enter and delete the sessions passed in one by one /// @note /// - listed sessions must not be part of the sessions list any more /// - on deletion failure, "zombie" sessions will be re-inserted into the session list (to get deleted once again later) /// - intended for implementations without a session thread (XPT, ISAPI, not pipe) void TSyncSessionDispatch::deleteListedSessions(TSyncSessionHandlePList &aDelSessionList) { TSyncAgent *sessionP=NULL; TSyncSessionHandle *sessionHP=NULL; TAgentConfig *serverconfigP=NULL; // get agent config GET_CASTED_PTR(serverconfigP,TAgentConfig,fConfigP->fAgentConfigP,"missing agent (server) config"); TSyncSessionHandlePList::iterator delpos; for (delpos=aDelSessionList.begin();delpos!=aDelSessionList.end();delpos++) { try { // - get handle and session sessionHP = (*delpos); sessionP = sessionHP->fSessionP; if (!sessionP) continue; // seems to be already deleted // - terminate the session #ifdef SYDEBUG string deletedsessionid = sessionP->getLocalSessionID(); #endif PDEBUGPRINTFX(DBG_HOT,( "Terminating timed-out (older than %lld milliseconds) session '%s'...", serverconfigP->getSessionTimeout(), sessionP->getLocalSessionID() )); // - now actually delete if (sessionHP->EnterAndTerminateSession(408)) { // request timeout PDEBUGPRINTFX(DBG_PROTO,("Terminated and deleted timed-out session '%s'",deletedsessionid.c_str())); // - delete session handle itself delete sessionHP; } else { PDEBUGPRINTFX(DBG_ERROR,("Could NOT properly terminate/delete timed-out session '%s' now --> becomes a ZOMBIE",deletedsessionid.c_str())); // We cannot safely get rid of this session now, so we must put it back to the queue if (sessionHP->fSessionP) { // make it used again, so it will timeout later again sessionHP->fSessionP->SessionUsed(); // re-insert into queue LockSessions(); // however, if we now see that there is NO other session running, we'll risk crashing here and delete the session if (fSessions.size()==0) { // we'll do no harm to other sessions because there are none - try to hard-kill the session PDEBUGPRINTFX(DBG_ERROR,("No non-ZOMBIE sessions running -> risking to delete this ZOMBIE",deletedsessionid.c_str())); delete sessionHP; } else { fSessions[deletedsessionid]=sessionHP; PDEBUGPRINTFX(DBG_HOT,( "ZOMBIE session ID='%s' is now again in session list, waiting once more for timeout and hopefully clean deletion later", deletedsessionid.c_str() )); } ReleaseSessions(); } else { PDEBUGPRINTFX(DBG_ERROR,("Termination failed, but sessionP gone nevertheless")); } } } catch (...) { PDEBUGPRINTFX(DBG_ERROR,("******** Exception while trying to kill outdated session")); } } // for } // deleteListedSessions /// Create new session, clean up timed-out sessions /// @param aPredefinedSessionID : predefined sessionID, if NULL, internal ID will be generated TSyncSessionHandle *TSyncSessionDispatch::CreateAndEnterServerSession(cAppCharP aPredefinedSessionID) { TSyncAgent *sessionP=NULL; // the session (new or existing found in fSessions) TSyncSessionHandle *sessionHP=NULL; TAgentConfig *serverconfigP=NULL; // - create new session instance // NOTE: session list is unlocked here already try { #ifdef APP_CAN_EXPIRE // Check expiry (note that this check is for a server running without restart) // - get current time lineartime_t nw = getSystemNowAs(TCTX_UTC); #ifdef EXPIRES_AFTER_DATE #ifdef SYSER_REGISTRATION if (!fRegOK) // only abort if no registration (but accept timed registration) #endif { sInt16 y,mo,d; lineartime2date(nw,&y,&mo,&d); // - calculate scrambled version thereof fScrambledNow= (y-1720)*12*42+ (mo-1)*42+ (d+7); if (fScrambledNow>SCRAMBLED_EXPIRY_VALUE) fAppExpiryStatus = LOCERR_EXPIRED; // hard expiry } #endif #ifdef SYSER_REGISTRATION // - check if timed license has expired if (fRegDuration && date2lineartime(fRegDuration/12+2000,fRegDuration%12+1,1)EnterSession(1000)) { PDEBUGPRINTFX(DBG_ERROR,("New created session cannot be entered")); return NULL; } try { // Determine session ID now string SessionIDString; if (aPredefinedSessionID) { SessionIDString=aPredefinedSessionID; } else { // - create unique server-side session ID // format = aaaabbbbccccdddd // - aaaa = low word of time(NULL) >> 1 (to make sure MSB is cleared) // - dddd = high word of time(NULL) // - bbbbcccc = memory address of session handle uInt64 sid = time(NULL); sid = ((sid >> 16) & 0xFFFF) + ((sid << 47) & 0x7FFF000000000000LL) + // aaaa00000000dddd ((((uIntPtr)sessionHP)&0xFFFFFFFF) << 16); // 0000bbbbcccc0000 // - make a string of it StringObjPrintf(SessionIDString,"%lld",sid); } #ifdef CONCURRENT_DEVICES_LIMIT // some minor arithmetic to hide actual comparison with limit #ifdef SYSER_REGISTRATION // number of users from license or hardcoded limit, whichever is lower sInt32 scrambledlimit = 3*(CONCURRENT_DEVICES_LIMIT!=0 && CONCURRENT_DEVICES_LIMIT(fConfigP->fAgentConfigP)->CreateServerSession(sessionHP,SessionIDString.c_str()); sessionHP->fSessionP=sessionP; // debug PDEBUGPRINTFX(DBG_HOT,( "Session created: local session ID='%s', not yet in session list", SessionIDString.c_str() )); // info CONSOLEPRINTF(("\nStarted new SyncML session (server id=%s)",SessionIDString.c_str())); // - add it to session map LockSessions(); fSessions[SessionIDString]=sessionHP; DEBUGPRINTFX(DBG_HOT,( "Session ID='%s' now in session list, total # of sessions now: %ld", sessionP->getLocalSessionID(), (sInt32)fSessions.size() )); ReleaseSessions(); } catch (...) { sessionHP->LeaveSession(); delete sessionHP; throw; // re-throw } } // session list is not locked here catch (exception &e) { PDEBUGPRINTFX(DBG_HOT,("******** Exception: Cannot create Session: %s",e.what())); return NULL; } catch (...) { PDEBUGPRINTFX(DBG_HOT,("******** Unknown exception: Cannot create Session")); return NULL; } // return session pointer (session is entered) return sessionHP; } // TSyncSessionDispatch::CreateAndEnterServerSession // called by owner of Session dispatcher to signal end of // a request. Responsible for finishing sending answers and // cleaning up the session if needed Ret_t TSyncSessionDispatch::EndRequest(InstanceID_t aSmlWorkspaceID, bool &aHasData, string &aRespURI, bool &aEOSession, uInt32 aReqBytes) { TSyncAgent *serverSessionP=NULL; // the session Ret_t err; // In case of a totally wrong request, this method may be // called when no session is attached to the smlWorkspace aEOSession=true; // default to ending session try { err=getSmlInstanceUserData(aSmlWorkspaceID,(void **)&serverSessionP); if (err==SML_ERR_OK && serverSessionP) { // Important: instance and session must remain attached until session either continues // running or is deleted. // Normal case: there IS a session attached DEBUGPRINTFX(DBG_SESSION,("Request ended with session attached, calling TSyncAgent::EndRequest")); if (serverSessionP->EndRequest(aHasData,aRespURI,aReqBytes)) { // TSyncSession::EndRequest returns true when session is done and must be removed PDEBUGPRINTFX(DBG_SESSION,("TSyncAgent::EndRequest returned true -> terminating and deleting session now")); // - take session out of session list LockSessions(); TSyncSessionHandle *sessionHP = RemoveSession(serverSessionP); ReleaseSessions(); // - delete session now (could cause AV in extreme case) if (sessionHP) { // - now actually delete if (sessionHP->EnterAndTerminateSession(0)) { // normal termination of session PDEBUGPRINTFX(DBG_PROTO,("Terminated and deleted session")); } else { PDEBUGPRINTFX(DBG_ERROR,("Could NOT properly terminate/delete session")); } // - delete handle (including session lock, if any) delete sessionHP; } else { PDEBUGPRINTFX(DBG_ERROR,("Very strange case: Session has no sessionhandle any more -> just delete session")); delete serverSessionP; } // safety: session no longer exists, make sure instance has no longer a pointer // (altough deleting the session should already have caused nulling the pointer by now) setSmlInstanceUserData(aSmlWorkspaceID,NULL); } else { // session is not finished, just leave lock as next message might come from another thread PDEBUGPRINTFX(DBG_SESSION,("TSyncAgent::EndRequest returned false -> just leave session")); serverSessionP->getSessionHandle()->LeaveSession(); aEOSession=false; // session does not end // remove session's reference to this workspace as next request might be decoded in a different workspace // (BUT NOT BEFORE HERE, to make sure the link still exists for the delete case above!) serverSessionP->setSmlWorkspaceID(NULL); // Note: session remains linked from instance's userData } } else { // end of request that could not be assiged a session at all DEBUGPRINTFX(DBG_HOT,("Request ended with no session attached")); } #ifdef SYDEBUG dbgListSessions(); #endif return SML_ERR_OK; } catch (exception &e) { aHasData=false; return HandleDecodingException(serverSessionP,"EndRequest",&e); } catch (...) { aHasData=false; return HandleDecodingException(serverSessionP,"EndRequest",NULL); } } // TSyncSessionDispatch::EndRequest // list currently active sessions void TSyncSessionDispatch::dbgListSessions(void) { #ifdef SYDEBUG string ts; TSyncSession *sP; if (PDEBUGTEST(DBG_SESSION)) { LockSessions(); try { // View list of active sessions TSyncSessionHandlePContainer::iterator pos; PDEBUGPRINTFX(DBG_SESSION,("-------------------------------------------")); PDEBUGPRINTFX(DBG_SESSION,("Active Sessions (%d):",fSessions.size())); for (pos=fSessions.begin(); pos!=fSessions.end(); pos++) { sP =(*pos).second->fSessionP; if (sP) { // handle has a session StringObjTimestamp(ts,sP->getSessionLastUsed()); PDEBUGPRINTFX(DBG_SESSION,( "- %s :Remote URI=%s, Local URI=%s, LastUsed=%s", (*pos).first.c_str(), sP->getRemoteURI(), sP->getLocalURI(), ts.c_str() )); } else { // Strange error: handle without session PDEBUGPRINTFX(DBG_SESSION,( "- %s : ", (*pos).first.c_str() )); } } PDEBUGPRINTFX(DBG_SESSION,("-------------------------------------------")); ReleaseSessions(); // make sure list does not remain blocked } catch (...) { ReleaseSessions(); // make sure list does not remain blocked } } #endif } // TSyncSessionDispatch::dbgListSessions // buffer answer in the session's buffer if instance still has a session attached at all Ret_t TSyncSessionDispatch::bufferAnswer(InstanceID_t aSmlWorkspaceID, MemPtr_t aAnswer, MemSize_t aAnswerSize) { TSyncAgent *serverSessionP=NULL; // the session Ret_t err; err=getSmlInstanceUserData(aSmlWorkspaceID,(void **)&serverSessionP); if ((err==SML_ERR_OK) && serverSessionP) { // there is a session attached, buffer err=serverSessionP->bufferAnswer(aAnswer,aAnswerSize); } return err; } // TSyncSessionDispatch::bufferAnswer // get buffered answer from the session's buffer if there is any void TSyncSessionDispatch::getBufferedAnswer(InstanceID_t aSmlWorkspaceID, MemPtr_t &aAnswer, MemSize_t &aAnswerSize) { TSyncAgent *serverSessionP=NULL; // the session Ret_t err; err=getSmlInstanceUserData(aSmlWorkspaceID,(void **)&serverSessionP); if (err==SML_ERR_OK && serverSessionP) { serverSessionP->getBufferedAnswer(aAnswer,aAnswerSize); } else { aAnswer=NULL; aAnswerSize=0; } } // TSyncSessionDispatch::getBufferedAnswer /* Session abort */ // called by owner or derivate of Session dispatcher when // session must be aborted due to error in request processing. // Kills session currently assigned to specified workspace // Note: may not be called when session list is already locked void TSyncSessionDispatch::KillSessionByInstance(InstanceID_t aSmlWorkspaceID, uInt16 aStatusCode, const char *aMsg, uInt32 aErrorCode) { TSyncAgent *sessionP; // In case of a totally bad request, this method may be // called when no session is attached to the smlWorkspace Ret_t err=getSmlInstanceUserData(aSmlWorkspaceID,(void **)&sessionP); if (err==SML_ERR_OK) { // there IS a session attached KillServerSession(sessionP,aStatusCode,aMsg,aErrorCode); // get rid of session } else { // there is no session at all DEBUGPRINTFX(DBG_HOT,("TSyncSessionDispatch::KillSessionByInstance: smlInstance has no session to be killed")); } } // TSyncSessionDispatch::KillSessionByInstance // remove and kill session // Note: may not be called when session list is already locked void TSyncSessionDispatch::KillServerSession(TSyncAgent *aSessionP, uInt16 aStatusCode, const char *aMsg, uInt32 aErrorCode) { if (aSessionP) { LockSessions(); // make sure session log shows the problem #ifdef SYDEBUG OBJDEBUGPRINTFX(aSessionP,DBG_ERROR,( "******* Warning: Terminating Session with Statuscode=%hd because: %s (Errorcode=%ld)", aStatusCode, aMsg ? aMsg : "", aErrorCode )); #endif // remove session TSyncSessionHandle *sessionHP = RemoveSession(aSessionP); // remove session from session list ReleaseSessions(); // terminate and delete session if (sessionHP) { // - terminate and delete session DEBUGPRINTFX(DBG_SESSION,("TSyncSessionDispatch::KillServerSession: terminating session first...")); if (sessionHP->EnterAndTerminateSession(aStatusCode)) { DEBUGPRINTFX(DBG_SESSION,("TSyncSessionDispatch::KillServerSession: ...terminated, now deleting session handle")); } else { DEBUGPRINTFX(DBG_ERROR,("TSyncSessionDispatch::KillServerSession: ...Session could NOT be deleted, left in memory")); } // - delete session handle itself delete sessionHP; DEBUGPRINTFX(DBG_HOT,("TSyncSessionDispatch::KillServerSession: finished")); } else { // - session not found DEBUGPRINTFX(DBG_ERROR,("TSyncSessionDispatch::KillServerSession: no session found, session pointer seems invalid")); } } else { DEBUGPRINTFX(DBG_ERROR,("TSyncSessionDispatch::KillServerSession: ******* Tried to kill NULL sessionP")); } } // TSyncSessionDispatch::KillServerSession // Handle exception happening while decoding commands for a session Ret_t TSyncSessionDispatch::HandleDecodingException(TSyncSession *aSessionP, const char *aRoutine, exception *aExceptionP) { #ifdef SYDEBUG // determine session name const char *sname = ""; try { if (aSessionP) { sname = aSessionP->getLocalSessionID(); } } catch (...) { sname = ""; aSessionP=NULL; // prevent attempt to write to session's log } // determine routine name if (!aRoutine) aRoutine=""; // show details if (aExceptionP) { // known exception // - show it in global log PDEBUGPRINTFX(DBG_ERROR,( "******** Exception in %s, sessionID=%s: %s", aRoutine, sname, aExceptionP->what() )); // - and also in session log #ifdef SYDEBUG if (aSessionP) { POBJDEBUGPRINTFX(aSessionP,DBG_ERROR,( "******** Warning: Exception in %s: %s", aRoutine, aExceptionP->what() )); } #endif } else { // unknown exception // - show it in global log PDEBUGPRINTFX(DBG_ERROR,( "******** Unknown Exception in %s, sessionID=%s", aRoutine, sname )); // - and also in session log #ifdef SYDEBUG if (aSessionP) { POBJDEBUGPRINTFX(aSessionP,DBG_ERROR,( "******** Warning: Unknown Exception in %s", aRoutine )); } #endif } #endif // try to kill session DEBUGPRINTFX(DBG_SESSION,("******** Exception aborts session: calling KillServerSession")); KillServerSession(static_cast(aSessionP),412,"Decoding Exception"); // return error DEBUGPRINTFX(DBG_SESSION,("******** Exception: returning SML_ERR_UNSPECIFIC to abort smlProcessData")); return SML_ERR_UNSPECIFIC; } // TSyncSessionDispatch::HandleDecodingException // remove session by pointer from session list. If none found, return NULL // NOTES: // - must be called with session list locked!!! // - does not throw TSyncSessionHandle *TSyncSessionDispatch::RemoveSession(TSyncSession *aSessionP) throw() { TSyncSessionHandle *foundhandleP = NULL; // remove session from Dispatcher // - locate session DEBUGPRINTFX(DBG_SESSION,("TSyncSessionDispatch::RemoveSession called...")); TSyncSessionHandlePContainer::iterator pos; for (pos=fSessions.begin(); pos!=fSessions.end(); ++pos) { TSyncSessionHandle *sessionHP = pos->second; if (sessionHP && (sessionHP->fSessionP == aSessionP)) { // - erase in list fSessions.erase(pos); DEBUGPRINTFX(DBG_SESSION,("...TSyncSessionDispatch::RemoveSession succeeded")); // - return handle foundhandleP=sessionHP; break; // done } } // - unlock access to list return foundhandleP; } // TSyncSessionDispatch::RemoveSession // eof libsynthesis-3.4.0.47.1/src/sysync/syncsessiondispatch.h000077500000000000000000000140311226375725500232360ustar00rootroot00000000000000/* * TSyncSessionDispatch * Abstract baseclass for session manager controlling * instantiation and removal of TSySyncSession objects and * re-connecting requests to sessions. * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * */ #ifndef SYNCSESSIONDISPATCH_H #define SYNCSESSIONDISPATCH_H // general includes (SyncML tookit, windows, Clib) #include "sysync.h" #include "syncappbase.h" #include "syncagent.h" namespace sysync { // forward declarations class TSyncSession; class TSyncAgent; class TSyncSessionDispatch; // Session handle, includes dispatcher-specific stuff for handling sessions // (such as thread IDs, locks, thread termination mechanisms etc.) class TSyncSessionHandle { public: // the session TSyncAgent * fSessionP; // the app base TSyncAppBase * fAppBaseP; // - used for counting session for session limiting bool fOutdated; // - enter session (re-entrance avoidance) virtual bool EnterSession(sInt32 aMaxWaitTime) = 0; // - leave session virtual void LeaveSession(void) = 0; // - Enter, terminate and delete session. Must protect caller from exceptions // when termination/deletion fails. // NOTE: keeps session Enter()ed, to avoid any other thread to enter. virtual bool EnterAndTerminateSession(uInt16 aStatusCode); // - terminate and delete session. Must protect caller from exceptions // when termination/deletion fails. // NOTE: session must be entered already virtual bool TerminateSession(uInt16 aStatusCode); // constructor/destructor TSyncSessionHandle(TSyncAppBase *aAppBaseP); virtual ~TSyncSessionHandle(); }; // TSyncSessionHandle // Container types // - main session list typedef std::map TSyncSessionHandlePContainer; // contains sync sessions by sessionID-String // - deletable sessions list typedef std::list TSyncSessionHandlePList; /* TSyncSessionDispatch manages a list of active sync sessions * and distributes server requests to the appropriate session, * or creates a new session if needed. * * This is a global, singular object which is instantiated ONCE per server * instance. It receives calls from SyncML-Toolkit callbacks. * * The adding an deleting of sessions is done in a thread-safe way * as multiple request might be processed simultaneously in different * threads. */ class TSyncSessionDispatch : public TSyncAppBase { typedef TSyncAppBase inherited; public: // constructors/destructors TSyncSessionDispatch(); virtual ~TSyncSessionDispatch(); // immediately kill all sessions void TerminateAllSessions(uInt16 aStatusCode); // handlers for SyncML toolkit callbacks // - Start Message: identifies Session, and creates new or assigns existing session Ret_t StartMessage( InstanceID_t aSmlWorkspaceID, // SyncML toolkit workspace instance ID VoidPtr_t aUserData, // user data, should be NULL (as StartMessage is responsible for setting userdata) SmlSyncHdrPtr_t aContentP // SyncML tookit's decoded form of the element ); // - end of request (to make sure even incomplete SyncML messages get cleaned up properly) Ret_t EndRequest(InstanceID_t aSmlWorkspaceID, bool &aHasData, string &aRespURI, bool &aEOSession, uInt32 aReqBytes); // Answer resending // - buffer answer in the session's buffer if transport allows it Ret_t bufferAnswer(InstanceID_t aSmlWorkspaceID, MemPtr_t aAnswer, MemSize_t aAnswerSize); // - get buffered answer from the session's buffer if there is any void getBufferedAnswer(InstanceID_t aSmlWorkspaceID, MemPtr_t &aAnswer, MemSize_t &aAnswerSize); // Session handling // - Collect timed-out sessions and remove them from the session list void collectTimedOutSessions(TSyncSessionHandlePList &aDeletableSessions); // - Try to enter and delete the sessions passed in one by one void deleteListedSessions(TSyncSessionHandlePList &aDelSessionList); // - create new session TSyncSessionHandle *CreateAndEnterServerSession(cAppCharP aPredefinedSessionID=NULL); // - create new session handle (of correct TSessionHandle derivate for dispatcher used) virtual TSyncSessionHandle *CreateSessionHandle(void) = 0; // - extract sessionID from query string (docname or TargetURI) virtual bool extractSessionID( const char *aQueryString, string &aSessionID ) { return false; /* no sessionID found */ } // list currently active sessions to debug channel void dbgListSessions(void); // - number of sessions sInt32 numSessions(void) { return fSessions.size(); }; #ifdef SYSYNC_TOOL // get or create a session for use with the diagnostic tool TSyncAgent *getSySyToolSession(void); #endif protected: // must be implemented in derived class to make access to // fSessions thread-safe virtual void LockSessions(void) { /* dummy in base class */ }; virtual void ReleaseSessions(void) { /* dummy in base class */ }; // remove session from internal session list and return it's handle object // Note: session list must be locked while calling RemoveSession TSyncSessionHandle *RemoveSession(TSyncSession *aSessionP) throw(); // remove and kill session // Note: may not be called when session list is already locked void KillServerSession(TSyncAgent *aSessionP, uInt16 aStatusCode, const char *aMsg=NULL, uInt32 aErrorCode=0); // by pointer void KillSessionByInstance(InstanceID_t aSmlWorkspaceID, uInt16 aStatusCode, const char *aMsg=NULL, uInt32 aErrorCode=0); // by SyncML toolkit instance ID // Handle exception happening while decoding commands for a session virtual Ret_t HandleDecodingException(TSyncSession *aSessionP, const char *aRoutine, exception *aExceptionP=NULL); #ifndef NOWSM // lock to make SyncML toolkit instance creation/freeing thread safe virtual void LockToolkit(void) { /* dummy in base class */ }; virtual void ReleaseToolkit(void) { /* dummy in base class */ }; #endif private: // session map TSyncSessionHandlePContainer fSessions; #ifdef SYSYNC_TOOL TSyncSessionHandle *fToolSessionHP; #endif }; // TSyncSessionDispatch } // namespace sysync #endif // SYNCSESSIONDISPATCH_H // eof libsynthesis-3.4.0.47.1/src/sysync/syserial.h000066400000000000000000000170201226375725500207670ustar00rootroot00000000000000/* * File: syserial.h * * Author: Lukas Zeller (luz@plan44.ch) * * Serial number generator and checker * * Copyright (c) 2003-2011 by Synthesis AG + plan44.ch * * 2003-02-11 : luz : created * */ #ifndef SYSERIAL_H #define SYSERIAL_H #include "generic_types.h" #include using namespace std; namespace sysync { // variant codes // ============= #define SYSER_VARIANT_UNKNOWN 0 #define SYSER_VARIANT_STD 1 #define SYSER_VARIANT_PRO 2 #define SYSER_VARIANT_CUSTOM 3 #define SYSER_VARIANT_DEMO 10 // branding codes #define SYSER_EXTRA_ID_NONE 0 #define SYSER_EXTRA_ID_PROTO 1 #define SYSER_EXTRA_ID_DBG 2 #define SYSER_EXTRA_ID_GOOSYNC 10 // Toffa.com Goosync special version #define SYSER_EXTRA_ID_FONELINK 11 // novamedia FoneLink special version #define SYSER_EXTRA_ID_SOOCIAL 12 // soocial.com special version // product codes // ============= // PDA Clients // - universal codes for all PDA clients = pocketPC codes #define SYSER_PRODCODE_CLIENT_PDA_STD 2 // this is the former PocketPC STD code (most widespread) #define SYSER_PRODCODE_CLIENT_PDA_PRO 5 // this is the former PocketPC PRO code (most widespread) // Old platform specific PDA codes (still valid, but no longer required) // - Palm & PPC STD #define SYSER_PRODCODE_CLIENT_PALM_STD 1 // for PalmOS #define SYSER_PRODCODE_CLIENT_PPC_STD 2 // for PocketPC #define SYSER_PRODCODE_CLIENT_PALMPPC_STD 3 // combined for PPC and PalmOS // - Palm & PPC PRO #define SYSER_PRODCODE_CLIENT_PALM_PRO 4 // for PalmOS #define SYSER_PRODCODE_CLIENT_PPC_PRO 5 // for PocketPC #define SYSER_PRODCODE_CLIENT_PALMPPC_PRO 6 // combined for PPC and PalmOS // - Symbian client #define SYSER_PRODCODE_CLIENT_SYMBIAN_STD 18 #define SYSER_PRODCODE_CLIENT_SYMBIAN_PRO 19 // - Smartphone #define SYSER_PRODCODE_CLIENT_MSSMP_STD 13 // for Microsoft SmartPhone (2003) #define SYSER_PRODCODE_CLIENT_MSSMP_PRO 14 // for Microsoft SmartPhone (2003) // - ODBC client STD #define SYSER_PRODCODE_CLIENT_ODBC_STD_WIN32 7 // Win32 ODBC PRO #define SYSER_PRODCODE_CLIENT_ODBC_STD_MACOSX 8 // for Mac OS X #define SYSER_PRODCODE_CLIENT_ODBC_STD_LINUX 9 // for Linux // - ODBC client PRO #define SYSER_PRODCODE_CLIENT_ODBC_PRO_WIN32 10 // Win32 ODBC PRO #define SYSER_PRODCODE_CLIENT_ODBC_PRO_MACOSX 11 // for Mac OS X #define SYSER_PRODCODE_CLIENT_ODBC_PRO_LINUX 12 // for Linux // - Demo client #define SYSER_PRODCODE_CLIENT_DEMO 15 // Demo Client (Text only) // - Outlook client #define SYSER_PRODCODE_CLIENT_OUTLOOK_STD 16 // Outlook Client STD #define SYSER_PRODCODE_CLIENT_OUTLOOK_PRO 17 // Outlook Client PRO (with email) // - Client Libraries #define SYSER_PRODCODE_CLIENT_LIB_WIN32 18 // Win32 ODBC PRO #define SYSER_PRODCODE_CLIENT_LIB_MACOSX 19 // for Mac OS X #define SYSER_PRODCODE_CLIENT_LIB_LINUX 20 // for Linux #define SYSER_PRODCODE_CLIENT_LIB_SYMBIAN 21 // for Symbian #define SYSER_PRODCODE_CLIENT_LIB_WM 22 // for Windows Mobile #define SYSER_PRODCODE_CLIENT_LIB_PALM 23 // for PALMOS #define SYSER_PRODCODE_CLIENT_LIB_IPHONEOS 28 // iPhone OS #define SYSER_PRODCODE_CLIENT_LIB_ANDROID 40 // Android #define SYSER_PRODCODE_CLIENT_LIB_ALL 24 // ALL Platforms #define SYSER_PRODCODE_CLIENT_LIB_MOBILE 25 // ALL Mobile Platforms #define SYSER_PRODCODE_CLIENT_LIB_DESK 26 // ALL Desktop Platforms #define SYSER_PRODCODE_CLIENT_LIB_DEMO 27 // All DEMO Libraries // - Client product flags (no flags -> only XPT version allowed) #define SYSER_PRODFLAG_CLIENT_DMU 0x01 // DMU enabled #define SYSER_PRODFLAG_CLIENT_APP 0x02 // App enabled (not only library) // Servers // - Server (=usually unified server+client) Libraries #define SYSER_PRODCODE_SERVER_LIB_WIN32 39 // Win32 ODBC PRO #define SYSER_PRODCODE_SERVER_LIB_MACOSX 29 // for Mac OS X #define SYSER_PRODCODE_SERVER_LIB_LINUX 30 // for Linux #define SYSER_PRODCODE_SERVER_LIB_SYMBIAN 31 // for Symbian #define SYSER_PRODCODE_SERVER_LIB_WM 32 // for Windows Mobile #define SYSER_PRODCODE_SERVER_LIB_PALM 33 // for PALMOS #define SYSER_PRODCODE_SERVER_LIB_IPHONEOS 38 // iPhone OS #define SYSER_PRODCODE_SERVER_LIB_ANDROID 41 // Android #define SYSER_PRODCODE_SERVER_LIB_ALL 34 // ALL Platforms #define SYSER_PRODCODE_SERVER_LIB_MOBILE 35 // ALL Mobile Platforms #define SYSER_PRODCODE_SERVER_LIB_DESK 36 // ALL Desktop Platforms #define SYSER_PRODCODE_SERVER_LIB_DEMO 37 // All DEMO Libraries // - Demo #define SYSER_PRODCODE_SERVER_DEMO 50 // Demo Server (Text only) // - ODBC #define SYSER_PRODCODE_SERVER_STD 51 // STD Server (with ODBC) #define SYSER_PRODCODE_SERVER_PRO 52 // PRO Server (with ODBC) // - XML2GO #define SYSER_PRODCODE_SERVER_XML2GO 53 // xml2go Server (with ODBC and XML2GO) // - Server product flags (no ISAPI or APACHE flags -> only XPT version allowed) #define SYSER_PRODFLAG_SERVER_ISAPI 0x01 // ISAPI version #define SYSER_PRODFLAG_SERVER_APACHE 0x02 // Apache version #define SYSER_PRODFLAG_SERVER_SDKAPI 0x04 // external DB API plugins allowed // special flag: if set, time code in license does not specify when temporary // license expires, but for up to what release date (hard-coded into the binary) // this code is valid. This allows to issue time unlimited licenses that will allow // be used with new releases only up to a defined time period after issuing. // If set, the duration bits (encoded absolute month) are no longer the // expiry date, but the max release date supported. // If this bit is set in SYSER_NEEDED_PRODUCT_FLAGS, this means that the // license must either have the bit set, too, or the license must be a // time limited license. Only licenses limited neither in time nor in release // date will be rejected. #define SYSER_PRODFLAG_MAXRELDATE 0x80 // license types #define SYSER_LTYP_STANDARD 0 // standard license, nothing special #define SYSER_LTYP_SYN_REG 1 // requires activation at synthesis #define SYSER_LTYP_S2G_REG 2 // requires activation at space2go // registration checking URLs #define SYSER_SYN_REG_HOST "www.synthesis.ch" #define SYSER_SYN_REG_DOC "/reg/" #define SYSER_S2G_REG_HOST "sync.space2go.com" #define SYSER_S2G_REG_DOC "/reg/" // update checking URL #define SYSER_SYN_UDC_HOST "www.synthesis.ch" #define SYSER_SYN_UDC_DOC "/udc/" // Internals // ========= // size of serial number #define SYSER_SERIALNUM_SIZE 20 // 4*4 chars, plus 3 dashes, plus one terminator = 16+3+1 = 20 #define SYSER_SERIALNUM_MANGLED_SIZE 17 // dashes are optimized away, so 4*4+1 = 17 // max size of "name" string (only that much will be stored and tested) #define SYSER_NAMESTRING_MAX 80 // should be enough for name and email #ifdef LINUX #define SYSER_CRC32_SEED ((uInt32)4119203362LL) // phone Tiefenau :-) #else #define SYSER_CRC32_SEED 4119203362 // phone Tiefenau :-) #endif // make sure we don't ever include the generator into a product #ifndef SYSYNC_VERSION_MAJOR // generate serial void generateSySerial( char *outbuf, // must be able to receive SYSER_SERIALNUM_SIZE chars (including terminator) uInt8 productflags, uInt16 productcode, uInt8 licensetype, uInt16 quantity, uInt8 duration, const char *name, bool aIprevent ); #endif #if defined SYSER_REGISTRATION || !defined(SYSYNC_VERSION_MAJOR) bool getSySerialInfo( const char *input, uInt8 &productflags, uInt16 &productcode, uInt8 &licensetype, uInt16 &quantity, uInt8 &duration, uInt32 &crc, uInt32 &infocrc, bool aMangled=false ); #endif // SYSER_REGISTRATION uInt32 addToCrc(uInt32 aCRC, uInt8 aByte); uInt32 addNameToCRC(uInt32 aCRC, const char *aName, bool aMangled=false, uInt16 aMaxChars=32000); } // namespace sysync #endif // SYSERIAL_H /* eof */ libsynthesis-3.4.0.47.1/src/sysync/sysync.h000077500000000000000000000041151226375725500204700ustar00rootroot00000000000000/* sysync generic header file */ #ifndef SYSYNC_H #define SYSYNC_H /* Headers that might be available in precompiled form * (standard libraries) */ #ifndef SYSYNC_PRECOMP_H #include "sysync_precomp.h" #endif #if __MC68K__ // Note: STL includes may not be in precompiled headers for CW Palm v9 // (STL map crashes), so we have them here for MC68k /* - STL includes */ #include #include #include #include #endif #ifdef ANDROID #include "android/log.h" #endif /* SySync headers (not precompiled during SySync development) */ // global constants and settings #include "sysync_globs.h" #ifdef DIRECT_APPBASE_GLOBALACCESS // only in old style environment with global anchors #include "sysync_glob_vars.h" #endif /* SyncML Toolkit includes */ // - SyncML Toolkit external API extern "C" { #include "sml.h" #include "smlerr.h" #include "smldtd.h" #include "smldevinfdtd.h" #include "smlmetinfdtd.h" #include "mgrutil.h" // utilities to work with SmlXXX structs #include "libmem.h" // utilities to allocate/deallocate SML memory } // engine defs (public defines also used in SDK) #include "engine_defs.h" // utilities #include "sysync_utils.h" #ifdef SYSYNC_ENGINE #include "stringutils.h" #endif #include "lineartime.h" #include "iso8601.h" #include "debuglogger.h" // platform adapters #include "configfiles.h" /* integrated extensions into RTK sources 2002-06-20 %%% // Synthesis SyncML toolkit extensions extern "C" { #include "smlextensions.h" } */ // utility classes without cross-dependencies #include "syncexception.h" #include "profiling.h" // base classes //#include "syncappbase.h" //#include "itemfield.h" //#include "syncitemtype.h" //#include "syncitem.h" //#include "vcarditemtype.h" //#include "vcalendaritemtype.h" //#include "mimediritemtype.h" //#include "syncdatastore.h" //#include "localengineds.h" //#include "synccommand.h" //#include "syncsession.h" //#include "syncclient.h" //#include "syncserver.h" //#include "syncsessiondispatch.h" // use sysync namespace using namespace sysync; /* globals */ #endif // SYSYNC_H libsynthesis-3.4.0.47.1/src/sysync/sysync_crc16.cpp000077500000000000000000000125331226375725500220240ustar00rootroot00000000000000/* * sysync_crc16.cpp * CRC 16 checksumming functions * * Copyright (c) 2002-2011 by Synthesis AG + plan44.ch * */ #include "prefix_file.h" #include "sysync_crc16.h" namespace sysync { #define TAB_DRIVEN 1 /* 1 - fast ; 0 - small */ #define CRC_CCITT 0 /* 1 for CCITT algorithm */ #define CRC_CRC16 1 /* 1 for CRC16 algorithm */ #if TAB_DRIVEN #if CRC_CCITT /* CCITT 16 bit CRC table build using feedback value of 0x8408 */ static const uInt16 crc16_table[256] = { 0x0000,0x1189,0x2312,0x329b,0x4624,0x57ad,0x6536,0x74bf, 0x8c48,0x9dc1,0xaf5a,0xbed3,0xca6c,0xdbe5,0xe97e,0xf8f7, 0x1891,0x0918,0x3b83,0x2a0a,0x5eb5,0x4f3c,0x7da7,0x6c2e, 0x94d9,0x8550,0xb7cb,0xa642,0xd2fd,0xc374,0xf1ef,0xe066, 0x3122,0x20ab,0x1230,0x03b9,0x7706,0x668f,0x5414,0x459d, 0xbd6a,0xace3,0x9e78,0x8ff1,0xfb4e,0xeac7,0xd85c,0xc9d5, 0x29b3,0x383a,0x0aa1,0x1b28,0x6f97,0x7e1e,0x4c85,0x5d0c, 0xa5fb,0xb472,0x86e9,0x9760,0xe3df,0xf256,0xc0cd,0xd144, 0x6244,0x73cd,0x4156,0x50df,0x2460,0x35e9,0x0772,0x16fb, 0xee0c,0xff85,0xcd1e,0xdc97,0xa828,0xb9a1,0x8b3a,0x9ab3, 0x7ad5,0x6b5c,0x59c7,0x484e,0x3cf1,0x2d78,0x1fe3,0x0e6a, 0xf69d,0xe714,0xd58f,0xc406,0xb0b9,0xa130,0x93ab,0x8222, 0x5366,0x42ef,0x7074,0x61fd,0x1542,0x04cb,0x3650,0x27d9, 0xdf2e,0xcea7,0xfc3c,0xedb5,0x990a,0x8883,0xba18,0xab91, 0x4bf7,0x5a7e,0x68e5,0x796c,0x0dd3,0x1c5a,0x2ec1,0x3f48, 0xc7bf,0xd636,0xe4ad,0xf524,0x819b,0x9012,0xa289,0xb300, 0xc488,0xd501,0xe79a,0xf613,0x82ac,0x9325,0xa1be,0xb037, 0x48c0,0x5949,0x6bd2,0x7a5b,0x0ee4,0x1f6d,0x2df6,0x3c7f, 0xdc19,0xcd90,0xff0b,0xee82,0x9a3d,0x8bb4,0xb92f,0xa8a6, 0x5051,0x41d8,0x7343,0x62ca,0x1675,0x07fc,0x3567,0x24ee, 0xf5aa,0xe423,0xd6b8,0xc731,0xb38e,0xa207,0x909c,0x8115, 0x79e2,0x686b,0x5af0,0x4b79,0x3fc6,0x2e4f,0x1cd4,0x0d5d, 0xed3b,0xfcb2,0xce29,0xdfa0,0xab1f,0xba96,0x880d,0x9984, 0x6173,0x70fa,0x4261,0x53e8,0x2757,0x36de,0x0445,0x15cc, 0xa6cc,0xb745,0x85de,0x9457,0xe0e8,0xf161,0xc3fa,0xd273, 0x2a84,0x3b0d,0x0996,0x181f,0x6ca0,0x7d29,0x4fb2,0x5e3b, 0xbe5d,0xafd4,0x9d4f,0x8cc6,0xf879,0xe9f0,0xdb6b,0xcae2, 0x3215,0x239c,0x1107,0x008e,0x7431,0x65b8,0x5723,0x46aa, 0x97ee,0x8667,0xb4fc,0xa575,0xd1ca,0xc043,0xf2d8,0xe351, 0x1ba6,0x0a2f,0x38b4,0x293d,0x5d82,0x4c0b,0x7e90,0x6f19, 0x8f7f,0x9ef6,0xac6d,0xbde4,0xc95b,0xd8d2,0xea49,0xfbc0, 0x0337,0x12be,0x2025,0x31ac,0x4513,0x549a,0x6601,0x7788 }; #elif defined(CRC_CRC16) static const uInt16 crc16_table[256] = { 0x0000,0x1189,0x2312,0x329B,0x4624,0x57AD,0x6536,0x74BF, 0x8C48,0x9DC1,0xAF5A,0xBED3,0xCA6C,0xDBE5,0xE97E,0xF8F7, 0x1081,0x0108,0x3393,0x221A,0x56A5,0x472C,0x75B7,0x643E, 0x9CC9,0x8D40,0xBFDB,0xAE52,0xDAED,0xCB64,0xF9FF,0xE876, 0x2102,0x308B,0x0210,0x1399,0x6726,0x76AF,0x4434,0x55BD, 0xAD4A,0xBCC3,0x8E58,0x9FD1,0xEB6E,0xFAE7,0xC87C,0xD9F5, 0x3183,0x200A,0x1291,0x0318,0x77A7,0x662E,0x54B5,0x453C, 0xBDCB,0xAC42,0x9ED9,0x8F50,0xFBEF,0xEA66,0xD8FD,0xC974, 0x4204,0x538D,0x6116,0x709F,0x0420,0x15A9,0x2732,0x36BB, 0xCE4C,0xDFC5,0xED5E,0xFCD7,0x8868,0x99E1,0xAB7A,0xBAF3, 0x5285,0x430C,0x7197,0x601E,0x14A1,0x0528,0x37B3,0x263A, 0xDECD,0xCF44,0xFDDF,0xEC56,0x98E9,0x8960,0xBBFB,0xAA72, 0x6306,0x728F,0x4014,0x519D,0x2522,0x34AB,0x0630,0x17B9, 0xEF4E,0xFEC7,0xCC5C,0xDDD5,0xA96A,0xB8E3,0x8A78,0x9BF1, 0x7387,0x620E,0x5095,0x411C,0x35A3,0x242A,0x16B1,0x0738, 0xFFCF,0xEE46,0xDCDD,0xCD54,0xB9EB,0xA862,0x9AF9,0x8B70, 0x8408,0x9581,0xA71A,0xB693,0xC22C,0xD3A5,0xE13E,0xF0B7, 0x0840,0x19C9,0x2B52,0x3ADB,0x4E64,0x5FED,0x6D76,0x7CFF, 0x9489,0x8500,0xB79B,0xA612,0xD2AD,0xC324,0xF1BF,0xE036, 0x18C1,0x0948,0x3BD3,0x2A5A,0x5EE5,0x4F6C,0x7DF7,0x6C7E, 0xA50A,0xB483,0x8618,0x9791,0xE32E,0xF2A7,0xC03C,0xD1B5, 0x2942,0x38CB,0x0A50,0x1BD9,0x6F66,0x7EEF,0x4C74,0x5DFD, 0xB58B,0xA402,0x9699,0x8710,0xF3AF,0xE226,0xD0BD,0xC134, 0x39C3,0x284A,0x1AD1,0x0B58,0x7FE7,0x6E6E,0x5CF5,0x4D7C, 0xC60C,0xD785,0xE51E,0xF497,0x8028,0x91A1,0xA33A,0xB2B3, 0x4A44,0x5BCD,0x6956,0x78DF,0x0C60,0x1DE9,0x2F72,0x3EFB, 0xD68D,0xC704,0xF59F,0xE416,0x90A9,0x8120,0xB3BB,0xA232, 0x5AC5,0x4B4C,0x79D7,0x685E,0x1CE1,0x0D68,0x3FF3,0x2E7A, 0xE70E,0xF687,0xC41C,0xD595,0xA12A,0xB0A3,0x8238,0x93B1, 0x6B46,0x7ACF,0x4854,0x59DD,0x2D62,0x3CEB,0x0E70,0x1FF9, 0xF78F,0xE606,0xD49D,0xC514,0xB1AB,0xA022,0x92B9,0x8330, 0x7BC7,0x6A4E,0x58D5,0x495C,0x3DE3,0x2C6A,0x1EF1,0x0F78 }; #else #error "no CRC method defined" #endif /* compute 16 bit CRC using the table */ uInt16 sysync_crc16(uInt16 crc,uInt8 b) { int s, i; i = (b ^ crc) & 0xff; s = (crc >> 8) ^ crc16_table[i]; return s & 0xffff; } // sysync_crc16 #else #if CRC_CCITT /* compute 16 bit CCITT crc on the fly, doesn't use table */ /* use this one if you are tight on space. */ uInt16 sysync_crc16(uInt16 crc,uInt8 b) { int s; /* s = b ^ (crc & 0xff);*/ s = (b ^ crc) & 0xff; s = s ^ (s << 4); s = (crc >> 8) ^ (s << 8) ^ (s << 3) ^ (s >> 4); return s & 0xffff; } #endif #if CRC_CRC16 /* compute 16 bit CCR16 crc on the fly, doesn't use table */ /* use this one if you are tight on space. */ #error "this function not implemented ... " #endif #endif // calc CRC over a block of bytes uInt16 sysync_crc16_block(const void* dataP, uInt32 len, uInt16 crc) { uInt32 i; uInt8 *p=(uInt8 *)dataP; for (i=0; i #endif #ifdef __cplusplus using namespace std; namespace sysync { #endif #ifndef __PALM_OS__ #if defined __MACH__ && !defined __GNUC__ /* used for va_list support */ #include #else #include #endif #endif #ifdef __cplusplus #define SYSYCDECL extern "C" #else #define SYSYCDECL #endif /* REMARK: do not define it again for C /// @todo get rid of all GDEBUG references later #warning "get rid of all GDEBUG references later" #define GDEBUG getDbgMask() // use accessor, depends on context which one is used */ // non-class debug output functions SYSYCDECL void DebugVPrintf(uInt32 mask, const char *format, va_list args); SYSYCDECL void DebugPrintf(const char *text, ...); SYSYCDECL void DebugPuts(uInt32 mask, const char *text); SYSYCDECL uInt32 getDbgMask(void); #ifdef __cplusplus class TDebugLogger; TDebugLogger *getDbgLogger(void); #endif // debug level masks // - main categories #define DBG_HOT 0x00000001 // hot information #define DBG_ERROR 0x00000002 // Error conditions // - specialized info categories #define DBG_PROTO 0x00000010 // directly SyncML protocol related info #define DBG_SESSION 0x00000020 // more internal Session management stuff #define DBG_ADMIN 0x00000040 // administrative data management #define DBG_DATA 0x00000080 // content data management (but needs DBG_USERDATA to show actual data) #define DBG_REMOTEINFO 0x00000100 // information we get about remote party (e.g. devInf or remote rule) #define DBG_PARSE 0x00000200 // parsing external formats into internal ones #define DBG_GEN 0x00000400 // generate external formats from internal ones #define DBG_SCRIPTEXPR 0x00000800 // Script expression details #define DBG_SCRIPTS 0x00001000 // Script execution #define DBG_TRANSP 0x00002000 // transport debug (outside SySync, e.g. ISAPI) #define DBG_REST 0x00008000 // everything not categorized, includes all DEBUGPRINTF // - technical insider categories #define DBG_LOCK 0x00010000 // Thread lock info #define DBG_OBJINST 0x00020000 // object instantiation and deletion #define DBG_PROFILE 0x00040000 // Execution time and memory profiling // - external library debug info categories #define DBG_RTK_SML 0x00100000 // SyncML Toolkit SML messages #define DBG_RTK_XPT 0x00200000 // SyncML Toolkit XPT messages // - flags to select more info, usually combined with other data #define DBG_USERDATA 0x01000000 // user content data #define DBG_DBAPI 0x02000000 // DB API data (such as SQL statements) #define DBG_PLUGIN 0x04000000 // plugin debug messages (all plugins) #define DBG_FILTER 0x08000000 // Details on filtering #define DBG_MATCH 0x10000000 // Details on content matching (but no user data unless USERDATA is set as well) #define DBG_CONFLICT 0x20000000 // Details on conflict resolution, such as data merge // - more details #define DBG_DETAILS 0x40000000 // show more detailed data #define DBG_EXOTIC 0x80000000 // show even most exotic details // - useful sets #define DBG_ALL 0xFFFFFFFF #define DBG_MINIMAL (DBG_ERROR+DBG_HOT) #define DBG_NORMAL (DBG_MINIMAL +DBG_DATA+DBG_ADMIN+DBG_PROTO+DBG_REMOTEINFO) #define DBG_EXTENDED (DBG_NORMAL +DBG_TRANSP+DBG_DBAPI+DBG_PLUGIN+DBG_SESSION+DBG_PARSE+DBG_GEN+DBG_DETAILS+DBG_FILTER+DBG_CONFLICT+DBG_MATCH+DBG_USERDATA+DBG_RTK_SML) #define DBG_MAXIMAL ((DBG_EXTENDED +DBG_EXOTIC+DBG_SCRIPTS) & ~DBG_MATCH) // DBG_MATCH explicitly excluded, as it causes O(N^2) output with DBG_EXOTIC // - special sets (internally used) #define DBG_ALLDB (DBG_DATA+DBG_ADMIN+DBG_DBAPI+DBG_PLUGIN) // what used to be "DBG_DB" (more or less) #define DBG_TOOL (DBG_HOT+DBG_ERROR+DBG_ALLDB+DBG_SCRIPTS+DBG_TRANSP) // what is shown for sysytest/sysytool in verbose mode // output to console macro #ifdef CONSOLEINFO #ifdef CONSOLEINFO_LIBC // Short-circuit all of the intermediate layers and use libc directly; // useful to avoid dependencies in libsmltk on libsynthesis. // Because a lot of libs log to stderr, include a unique prefix. // Assumes that all printf format strings are plain strings. #define CONSOLEPUTS(m) CONSOLE_PRINTF_VARARGS("%s", (m)) #define CONSOLE_PRINTF_VARARGS(_m, _args...) SySync_ConsolePrintf(stderr, "SYSYNC " _m "\n", ##_args) #define CONSOLEPRINTF(m) CONSOLE_PRINTF_VARARGS m // default implementation invokes fprintf, can be set by app // @param stream stderr, useful for invoking fprintf directly // @param format guaranteed to start with "SYSYNC " (see above) #ifdef __cplusplus extern "C" { #endif extern int (*SySync_ConsolePrintf)(FILE *stream, const char *format, ...); #ifdef __cplusplus } #endif #else // CONSOLEINFO_LIBC #define CONSOLEPUTS(m) ConsolePuts(m) #define CONSOLEPRINTF(m) ConsolePrintf m #endif // CONSOLEINFO_LIBC #else #define CONSOLEPUTS(m) #define CONSOLEPRINTF(m) #endif #ifdef SYDEBUG_LOCATION /// Source location tracking in all debug messages /// Container for information about the location where a debug call was made. /// Strings are owned by caller. struct TDbgLocation { /// function name, may be NULL, derived from __FUNC__ if available const char *fFunction; /// file name, may be NULL, from __FILE__ const char *fFile; /// line number, 0 if unknown const int fLine; #ifdef __cplusplus TDbgLocation(const char *aFunction = NULL, const char *aFile = NULL, const int aLine = 0) : fFunction(aFunction), fFile(aFile), fLine(aLine) {} #endif }; # define TDBG_LOCATION_PROTO const TDbgLocation &aTDbgLoc, # define TDBG_LOCATION_ARG aTDbgLoc, # define TDBG_LOCATION_HERE TDbgLocation(__func__, __FILE__, __LINE__), # define TDBG_LOCATION_NONE TDbgLocation(), # define TDBG_LOCATION_ARGS(_func, _file, _line) TDbgLocation(_func, _file, _line), # define TDBG_VARARGS(m...) (TDbgLocation(__PRETTY_FUNCTION__, __FILE__, __LINE__), ## m) # define TDBG_LOCATION_ARG_NUM 1 #else // No links to source in debug messages # define TDBG_LOCATION_PROTO # define TDBG_LOCATION_ARG # define TDBG_LOCATION_HERE # define TDBG_LOCATION_NONE # define TDBG_LOCATION_ARGS(_func, _file, _line) # define TDBG_VARARGS # define TDBG_LOCATION_ARG_NUM 0 #endif // SYDEBUG_LOCATION // debug output macros (prevents unnecessary printf argument // calculations when SYDEBUG is UNDEFined). #ifndef DIRECT_APPBASE_GLOBALACCESS // without global access, all NC variants are always disabled #define PNCDEBUGPUTSX(lvl,m) #define PNCDEBUGPUTSXX(lvl,m,s,p) #define PNCDEBUGPRINTFX(lvl,m) #define PNCDEBUGVPRINTFX(lvl,f,a) #endif #ifdef SYDEBUG // "Public" debug info // Debug structure #define PDEBUGBLOCKFMT(m) getDbgLogger()->DebugOpenBlockExpanded TDBG_VARARGS m #define PDEBUGBLOCKFMTCOLL(m) getDbgLogger()->DebugOpenBlockCollapsed TDBG_VARARGS m #define PDEBUGBLOCKDESC(n,d) getDbgLogger()->DebugOpenBlock(TDBG_LOCATION_HERE n,d) #define PDEBUGBLOCKDESCCOLL(n,d) getDbgLogger()->DebugOpenBlock(TDBG_LOCATION_HERE n,d,true) #define PDEBUGBLOCK(n) getDbgLogger()->DebugOpenBlock(TDBG_LOCATION_HERE n) #define PDEBUGBLOCKCOLL(n) getDbgLogger()->DebugOpenBlock(TDBG_LOCATION_HERE n,NULL,true) #define PDEBUGENDBLOCK(n) getDbgLogger()->DebugCloseBlock(TDBG_LOCATION_HERE n) // current-class context debug output #define PDEBUGPUTSX(lvl,m) { if (((lvl) & getDbgMask()) == (lvl)) getDbgLogger()->DebugPuts(TDBG_LOCATION_HERE lvl,m); } #define PDEBUGPUTSXX(lvl,m,s,p) { if (((lvl) & getDbgMask()) == (lvl)) getDbgLogger()->DebugPuts(TDBG_LOCATION_HERE lvl,m,s,p); } #define PDEBUGPUTS(m) PDEBUGPUTSX(DBG_REST,m) #define PDEBUGVPRINTFX(lvl,f,a) { if (((lvl) & getDbgMask()) == (lvl)) getDbgLogger()->DebugVPrintf(TDBG_LOCATION_HERE lvl,f,a); } #define PDEBUGPRINTFX(lvl,m) { if (((lvl) & getDbgMask()) == (lvl)) getDbgLogger()->setNextMask(lvl).DebugPrintfLastMask TDBG_VARARGS m; } #define PDEBUGPRINTF(m) PDEBUGPRINTFX(DBG_REST,m) #define PPOINTERTEST(p,m) if (!p) getDbgLogger()->setNextMask(DBG_ERROR).DebugPrintfLastMask TDBG_VARARGS m #define PDEBUGTEST(lvl) (((lvl) & getDbgMask()) == (lvl)) #define PDEBUGMASK getDbgMask() // direct output to a logger #define PLOGDEBUGTEST(lo,lvl) ((lo) && (((lvl) & (lo)->getMask()) == (lvl))) #define PLOGDEBUGBLOCKFMT(lo,m) { if (lo) (lo)->DebugOpenBlockExpanded TDBG_VARARGS m; } #define PLOGDEBUGBLOCKFMTCOLL(lo,m) { if (lo) (lo)->DebugOpenBlockCollapsed TDBG_VARARGS m; } #define PLOGDEBUGBLOCKDESC(lo,n,d) { if (lo) (lo)->DebugOpenBlock(TDBG_LOCATION_HERE n,d); } #define PLOGDEBUGBLOCKDESCCOLL(lo,n,d) { if (lo) (lo)->DebugOpenBlock(TDBG_LOCATION_HERE n,d,true); } #define PLOGDEBUGBLOCK(lo,n) { if (lo) (lo)->DebugOpenBlock(TDBG_LOCATION_HERE n); } #define PLOGDEBUGBLOCKCOLL(lo,n) { if (lo) (lo)->DebugOpenBlock(TDBG_LOCATION_HERE n,NULL,true); } #define PLOGDEBUGENDBLOCK(lo,n) { if (lo) (lo)->DebugCloseBlock(TDBG_LOCATION_HERE n); } #define PLOGDEBUGPUTSX(lo,lvl,m) { if ((lo) && ((lvl) & (lo)->getMask()) == (lvl)) (lo)->DebugPuts(TDBG_LOCATION_HERE lvl,m); } #define PLOGDEBUGPUTSXX(lo,lvl,m,s,p) { if ((lo) && ((lvl) & (lo)->getMask()) == (lvl)) (lo)->DebugPuts(TDBG_LOCATION_HERE lvl,m,s,p); } #define PLOGDEBUGVPRINTFX(lo,lvl,f,a) { if ((lo) && ((lvl) & (lo)->getMask()) == (lvl)) (lo)->DebugVPrintf(TDBG_LOCATION_HERE lvl,f,a); } #define PLOGDEBUGPRINTFX(lo,lvl,m) { if ((lo) && ((lvl) & (lo)->getMask()) == (lvl)) (lo)->setNextMask(lvl).DebugPrintfLastMask TDBG_VARARGS m; } // non-class context or C-level debug output #ifdef DIRECT_APPBASE_GLOBALACCESS #ifdef __cplusplus #define PNCDEBUGPUTSX(lvl,m) { if (((lvl) & sysync::getDbgMask()) == (lvl)) sysync::DebugPuts(TDBG_LOCATION_HERE m); } #define PNCDEBUGPRINTFX(lvl,m) { if (((lvl) & sysync::getDbgMask()) == (lvl)) sysync::DebugPrintf TDBG_VARARGS m; } #define PNCDEBUGVPRINTFX(lvl,f,a) { if (((lvl) & sysync::getDbgMask()) == (lvl)) sysync::DebugVPrintf(TDBG_LOCATION_HERE lvl,f,a); } #else #define PNCDEBUGPUTSX(lvl,m) { if (((lvl) & getDbgMask()) == (lvl)) DebugPuts(TDBG_LOCATION_HERE m); } #define PNCDEBUGPRINTFX(lvl,m) { if (((lvl) & getDbgMask()) == (lvl)) DebugPrintf TDBG_VARARGS m; } #define PNCDEBUGVPRINTFX(lvl,f,a) { if (((lvl) & getDbgMask()) == (lvl)) DebugVPrintf(TDBG_LOCATION_HERE lvl,f,a); } #endif #endif // specified object-context debug output #define POBJDEBUGPRINTFX(obj,lvl,m) { if ((obj) && (((lvl) & (obj)->getDbgMask()) == (lvl))) (obj)->getDbgLogger()->setNextMask(lvl).DebugPrintfLastMask TDBG_VARARGS m; } #define POBJDEBUGPUTSX(obj,lvl,m) { if ((obj) && (((lvl) & (obj)->getDbgMask()) == (lvl))) (obj)->getDbgLogger()->DebugPuts(TDBG_LOCATION_HERE lvl,m); } #define POBJDEBUGPUTSXX(obj,lvl,m,s,p) { if ((obj) && (((lvl) & (obj)->getDbgMask()) == (lvl))) (obj)->getDbgLogger()->DebugPuts(TDBG_LOCATION_HERE lvl,m,s,p); } #define POBJDEBUGPRINTF(obj,m) POBJDEBUGPRINTFX(obj,DBG_REST,m) #define POBJDEBUGTEST(obj,lvl) ((obj) && (((lvl) & (obj)->getDbgMask()) == (lvl))) // get current logger #define GETDBGLOGGER (getDbgLogger()) #define OBJGETDBGLOGGER(obj) (obj->getDbgLogger()) #else #define PDEBUGBLOCKFMT(m) #define PDEBUGBLOCKFMTCOLL(m) #define PDEBUGBLOCKDESC(n,d) #define PDEBUGBLOCKDESCCOLL(n,d) #define PDEBUGBLOCK(n) #define PDEBUGBLOCKCOLL(n) #define PDEBUGENDBLOCK(n) #define PDEBUGPUTSX(lvl,m) #define PDEBUGPUTSXX(lvl,m,s,p) #define PDEBUGPUTS(m) #define PDEBUGVPRINTFX(lvl,f,a) #define PDEBUGPRINTFX(lvl,m) #define PDEBUGPRINTF(m) #define PPOINTERTEST(p,m) #define PDEBUGTEST(lvl) false #define PDEBUGMASK 0 #define PLOGDEBUGTEST(lo,lvl) false #define PLOGDEBUGBLOCKFMT(lo,m) #define PLOGDEBUGBLOCKFMTCOLL(lo,m) #define PLOGDEBUGBLOCKDESC(lo,n,d) #define PLOGDEBUGBLOCKDESCCOLL(lo,n,d) #define PLOGDEBUGBLOCK(lo,n) #define PLOGDEBUGBLOCKCOLL(lo,n) #define PLOGDEBUGENDBLOCK(lo,n) #define PLOGDEBUGPUTSX(lo,lvl,m) #define PLOGDEBUGPUTSXX(lo,lvl,m,s,p) #define PLOGDEBUGVPRINTFX(lo,lvl,f,a) #define PLOGDEBUGPRINTFX(lo,lvl,m) #ifdef DIRECT_APPBASE_GLOBALACCESS #define PNCDEBUGPUTSX(lvl,m) #define PNCDEBUGPUTSXX(lvl,m,s,p) #define PNCDEBUGPRINTFX(lvl,m) #define PNCDEBUGVPRINTFX(lvl,f,a) #endif //#define PTHREADDEBUGPRINTFX(lvl,m) #define POBJDEBUGPRINTFX(obj,lvl,m) #define POBJDEBUGPUTSX(obj,lvl,m) #define POBJDEBUGPUTSXX(obj,lvl,m,s,p) #define POBJDEBUGPRINTF(obj,m) #define POBJDEBUGTEST(obj,lvl) false // get current logger #define GETDBGLOGGER NULL #define OBJGETDBGLOGGER(obj) NULL #endif #if SYDEBUG>1 // full debugging, including private debug info #define DEBUGPUTSX(lvl,m) PDEBUGPUTSX(lvl,m) #define DEBUGPUTSXX(lvl,m,s,p) PDEBUGPUTSXX(lvl,m,s,p) #define DEBUGPUTS(m) PDEBUGPUTS(m) #define DEBUGVPRINTFX(lvl,f,a) PDEBUGVPRINTFX(lvl,f,a) #define DEBUGPRINTFX(lvl,m) PDEBUGPRINTFX(lvl,m) #define DEBUGPRINTF(m) PDEBUGPRINTF(m) #define POINTERTEST(p,m) PPOINTERTEST(p,m) #define DEBUGTEST(lvl) PDEBUGTEST(lvl) #define DEBUGMASK PDEBUGMASK #define NCDEBUGPUTSX(lvl,m) PNCDEBUGPUTSX(lvl,m) #define NCDEBUGPUTSXX(lvl,m,s,p) PNCDEBUGPUTSXX(lvl,m,s,p) #define NCDEBUGPRINTFX(lvl,m) PNCDEBUGPRINTFX(lvl,m) #define NCDEBUGVPRINTFX(lvl,f,a) PNCDEBUGVPRINTFX(lvl,f,a) #define LOGDEBUGTEST(lo,lvl) PLOGDEBUGTEST(lo,lvl) #define LOGDEBUGBLOCKFMT(lo,m) PLOGDEBUGBLOCKFMT(lo,m) #define LOGDEBUGBLOCKFMTCOLL(lo,m) PLOGDEBUGBLOCKFMTCOLL(lo,m) #define LOGDEBUGBLOCKDESC(lo,n,d) PLOGDEBUGBLOCKDESC(lo,n,d) #define LOGDEBUGBLOCKDESCCOLL(lo,n,d) PLOGDEBUGBLOCKDESCCOLL(lo,n,d) #define LOGDEBUGBLOCK(lo,n) PLOGDEBUGBLOCK(lo,n) #define LOGDEBUGBLOCKCOLL(lo,n) PLOGDEBUGBLOCKCOLL(lo,n) #define LOGDEBUGENDBLOCK(lo,n) PLOGDEBUGENDBLOCK(lo,n) #define LOGDEBUGPUTSX(lo,lvl,m) PLOGDEBUGPUTSX(lo,lvl,m) #define LOGDEBUGPUTSXX(lo,lvl,m,s,p) PLOGDEBUGPUTSXX(lo,lvl,m,s,p) #define LOGDEBUGVPRINTFX(lo,lvl,f,a) PLOGDEBUGVPRINTFX(lo,lvl,f,a) #define LOGDEBUGPRINTFX(lo,lvl,m) PLOGDEBUGPRINTFX(lo,lvl,m) //#define THREADDEBUGPRINTFX(lvl,m) PTHREADDEBUGPRINTFX(lvl,m) #define OBJDEBUGPRINTFX(obj,lvl,m) POBJDEBUGPRINTFX(obj,lvl,m) #define OBJDEBUGPUTSX(obj,lvl,m) POBJDEBUGPUTSX(obj,lvl,m) #define OBJDEBUGPUTSXX(obj,lvl,m,s,p) POBJDEBUGPUTSXX(obj,lvl,m,s,p) #define OBJDEBUGPRINTF(obj,m) POBJDEBUGPRINTF(obj,m) #define OBJDEBUGTEST(obj,lvl) POBJDEBUGTEST(obj,lvl) #else // public or no debugging, none or only P-variants are active #define DEBUGPUTSX(lvl,m) #define DEBUGPUTSXX(lvl,m,s,p) #define DEBUGPUTS(m) #define DEBUGVPRINTFX(lvl,f,a) #define DEBUGPRINTFX(lvl,m) #define DEBUGPRINTF(m) #define POINTERTEST(p,m) #define DEBUGTEST(lvl) false #define DEBUGMASK 0 #define NCDEBUGPUTSX(lvl,m) #define NCDEBUGPUTSXX(lvl,m,s,p) #define NCDEBUGPRINTFX(lvl,m) #define NCDEBUGVPRINTFX(lvl,f,a) #define LOGDEBUGTEST(lo,lvl) false #define LOGDEBUGBLOCKFMT(lo,m) #define LOGDEBUGBLOCKFMTCOLL(lo,m) #define LOGDEBUGBLOCKDESC(lo,n,d) #define LOGDEBUGBLOCKDESCCOLL(lo,n,d) #define LOGDEBUGBLOCK(lo,n) #define LOGDEBUGBLOCKCOLL(lo,n) #define LOGDEBUGENDBLOCK(lo,n) #define LOGDEBUGPUTSX(lo,lvl,m) #define LOGDEBUGPUTSXX(lo,lvl,m,s,p) #define LOGDEBUGVPRINTFX(lo,lvl,f,a) #define LOGDEBUGPRINTFX(lo,lvl,m) //#define THREADDEBUGPRINTFX(lvl,m) #define OBJDEBUGPRINTFX(obj,lvl,m) #define OBJDEBUGPUTSX(obj,lvl,m) #define OBJDEBUGPUTSXX(obj,lvl,m,s,p) #define OBJDEBUGPRINTF(obj,m) #define OBJDEBUGTEST(obj,lvl) false #endif // debug String macro (for omitting text from non-debug code) #ifdef SHORTDEBUGTEXTS #define DEBUGSHORT(l,s) s #else #define DEBUGSHORT(l,s) l #endif // debug String macro (for omitting text from non-debug code) #ifdef SYDEBUG #define DEBUGTEXT(m,c) m #else #define DEBUGTEXT(m,c) c #endif // "enhanced" status generation in debug mode: // adds String Item to Status with description #ifdef SYDEBUG #define ADDDEBUGITEM(s,m) { if (PDEBUGTEST(DBG_HOT)) s.addItemString(m); } #else #define ADDDEBUGITEM(s,m) #endif #ifdef __cplusplus } // namespace sysync #endif #endif // SYSYNC_DEBUG_H // eof libsynthesis-3.4.0.47.1/src/sysync/sysync_globs.h000077500000000000000000000355061226375725500216660ustar00rootroot00000000000000/* * File: sysync_globs.h * * Author: Lukas Zeller (luz@plan44.ch) * * Global definitions/macros/constants * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * 2001-xx-xx : luz : created * */ #ifndef SYSYNC_GLOBS_H #define SYSYNC_GLOBS_H #include #include "generic_types.h" // global error codes #include "syerror.h" // include sysync-independent part #include "syncml_globs.h" // include debug definitions #include "sysync_debug.h" // include global progress defs #include "global_progress.h" #ifdef __cplusplus // we need some STL basics as we define types based on STL constructs #include #include #include using namespace std; namespace sysync { #endif // local status codes (normally generated from SyncML status + LOCAL_STATUS_CODE) typedef TSyError localstatus; // configuration switches (DEFAULT_xxx are defaults for corresponding globals) // - time (in seconds) how long a session will be kept inactive before it times out #define DEFAULT_SERVERSESSIONTIMEOUT (60*5) // 5 minutes #define DEFAULT_CLIENTSESSIONTIMEOUT 20 // 20 seconds // - log file format: datastore // - client #define DEFAULT_LOG_LABELS_CLIENT "SyncEndTime\tUser\tSyncMLVers\tStatus\tSynctype\tSessionID\tRemote ID\tRemote Name\tRemote VersInfo\tDatastore\tLocAdded\tLocUpdated\tLocDeleted\tLocErrors\tRemAdded\tRemUpdated\tRemDeleted\tRemErrors\tBytesOut\tBytesIn\n\n" #define DEFAULT_LOG_FORMAT_CLIENT "%seT\t%U\t%syV\t%sS\t%tS\t%iS\t%iR\t%nR\t%vR\t%nD\t%laI\t%luI\t%ldI\t%leI\t%raI\t%ruI\t%rdI\t%reI\t%doB\t%diB\n" // - server #define DEFAULT_LOG_LABELS_SERVER "SyncEndTime\tUser\tSyncMLVers\tStatus\tSynctype\tSessionID\tRemote ID\tRemote Name\tRemote VersInfo\tDatastore\tLocAdded\tLocUpdated\tLocDeleted\tLocErrors\tRemAdded\tRemUpdated\tRemDeleted\tRemErrors\tSlowSyncMatches\tServerWon\tClientWon\tDuplicated\tBytesOut\tBytesIn\tSessionBytesOut\tSessionBytesIn\n\n" #define DEFAULT_LOG_FORMAT_SERVER "%seT\t%U\t%syV\t%sS\t%tS\t%iS\t%iR\t%nR\t%vR\t%nD\t%laI\t%luI\t%ldI\t%leI\t%raI\t%ruI\t%rdI\t%reI\t%smI\t%scI\t%ccI\t%dcI\t%doB\t%diB\t%toB\t%tiB\n" // - defines debug mask that is active by default #define DEFAULT_DEBUG DBG_NORMAL // - if 1, enables message dumps (if included) #define DEFAULT_MSGDUMP 0 // - if 1, enables XML translation of messages (independent of MSGDUMP) #define DEFAULT_XMLTRANSLATE 0 // - if 1, enables incoming message simulation (if included) #define DEFAULT_SIMMSGREAD 0 // - if true, global log file is enabled #define DEFAULT_GLOBALDEBUGLOGS false // - if true, session-spcific log files are enabled by default #define DEFAULT_SESSIONDEBUGLOGS true // - hard-wired names for debug logs #define CONFERRPREFIX "sysync_" #define CONFERRSUFFIX "_cfgerr.log" #define LOGNAMEPREFIX "sysync_" #define LOGSUFFIX ".log" #define MSGDUMPPREFIX "sysync_" #define MSGDUMPINSUFFIX "_incoming.sml" #define MSGDUMPOUTSUFFIX "_outgoing.sml" // Expiry #ifdef EXPIRES_AFTER_DATE // gcc does not like line continuations in DOS text files // scalar value representing date #define SCRAMBLED_EXPIRY_VALUE ((EXPIRY_DAY+7l) + (EXPIRY_MONTH-1)*42l + (EXPIRY_YEAR-1720l)*12l*42l) #endif // define at least the max difference above formula can have to // a real difference because of non-smooth increment with time #define MAX_EXPIRY_DIFF 15 // 42-28(Feb) = 14 #if defined(EXPIRES_AFTER_DATE) || defined(EXPIRES_AFTER_DAYS) || defined(SYSER_REGISTRATION) #define APP_CAN_EXPIRE #else #undef APP_CAN_EXPIRE #endif // Hack switches for testing with difficult clients // - if defined, strings will be encoded as SML_PCDATA_OPAQUE //#define SML_STRINGS_AS_OPAQUE 1 // - if defined, status for command will be issued after // statuses for contained SyncOp commands. //#define SYNCSTATUS_AT_SYNC_CLOSE 1 // general constants // - used by compare functions to signal compare incompatibility // (i.e. non-orderable not-equal) #define SYSYNC_NOT_COMPARABLE -999 // - maximum auth retries attempted (client) before giving up // Note: since 2.0.4.6 this includes the attitional "retry" required to request auth chal from the server #define MAX_NORMAL_AUTH_RETRIES 2 // Note: retry only once (plus once for chal request) to avoid strict servers (such as COA-S) to lock accounts #define MAX_SMART_AUTH_RETRIES 4 // when fSmartAuthRetry option is set, some additional retries happen after MAX_NORMAL_AUTH_RETRIES are exhausted // - maximum auth attempts allowed (server) before session gets aborted #define MAX_AUTH_ATTEMPTS 3 // - number of message resend retries (client) #define MAX_MESSAGE_RESENDS 3 // - number of message resend retries before trying older protocol #define SAME_PROTOCOL_RESENDS 2 // - switch on multithread support if we need it #if defined(MULTI_THREAD_DATASTORE) || defined(MULTITHREAD_PIPESERVER) #define MULTI_THREAD_SUPPORT 1 #endif // - buffer sizes #define CONFIG_READ_BUFSIZ 3048 // size of buffer for XML config reading // Max message size #ifndef DEFAULT_MAXMSGSIZE #ifndef SYSYNC_SERVER // only client #define DEFAULT_MAXMSGSIZE 20000 // 20k now for DS 1.2 (we had 10k before 3.x) #else // server (or server and client) #define DEFAULT_MAXMSGSIZE 50000 // 50k should be enough #endif #endif // Max object size #ifndef DEFAULT_MAXOBJSIZE #define DEFAULT_MAXOBJSIZE 4000000 // 4MB should be enough #endif // default identification strings #define SYSYNC_OEM "Synthesis AG" #define SYSYNC_SERVER_DEVID "SySync Server" #define SYSYNC_CLIENT_DEVID "SySync Client" #ifndef SYNCML_SERVER_DEVTYP #define SYNCML_SERVER_DEVTYP "server" // could also be "workstation" #endif #ifndef SYNCML_CLIENT_DEVTYP #define SYNCML_CLIENT_DEVTYP "workstation" // general case, could also be "handheld" or "pda"... #endif // SyncML SyncCap mask bits #define SCAP_MASK_TWOWAY 0x0002 // Support of 'two-way sync' = 1 #define SCAP_MASK_TWOWAY_SLOW 0x0004 // Support of 'slow two-way sync' = 2 #define SCAP_MASK_ONEWAY_CLIENT 0x0008 // Support of 'one-way sync from client only' = 3 #define SCAP_MASK_REFRESH_CLIENT 0x0010 // Support of 'refresh sync from client only' = 4 #define SCAP_MASK_ONEWAY_SERVER 0x0020 // Support of 'one-way sync from server only' = 5 #define SCAP_MASK_REFRESH_SERVER 0x0040 // Support of 'refresh sync from server only' = 6 #define SCAP_MASK_SERVER_ALERTED 0x0080 // Support of 'server alerted sync' = 7 // - minimum needed for conformance #define SCAP_MASK_MINIMAL (SCAP_MASK_TWOWAY | SCAP_MASK_TWOWAY_SLOW) // Support of 'server alerted sync' = 7 // - normal capabilities #define SCAP_MASK_NORMAL (SCAP_MASK_MINIMAL | SCAP_MASK_ONEWAY_CLIENT | SCAP_MASK_REFRESH_CLIENT | SCAP_MASK_ONEWAY_SERVER | SCAP_MASK_REFRESH_SERVER) // DMU / IPP locUris #define IPP_PARAMS_LOCURI_BASE "./vendor/synthesis/ipp10/" // URI used to address DMU/IPP settings/subscription #define IPP_PARAMS_LOCURI_CFG IPP_PARAMS_LOCURI_BASE "cfg" // IPP config data from server #define IPP_PARAMS_LOCURI_REQ IPP_PARAMS_LOCURI_BASE "req" // IPP request from client #define IPP_PARAMS_ITEM_METATYPE "text/plain" // meta type for IPP req and cfg PUT data items #define IPP_REQ_ACTIVATE "activate" // activate-request #define IPP_REQ_SUBSCRIBE "subscribe" // activate-request #define IPP_REQ_CHECK "check" // check-request // Remote provisioning #define SETTINGS_LOCURI_BASE "./vendor/synthesis/settings10/" // URI used to address settings #define SETTINGS_LOCURI_CFG SETTINGS_LOCURI_BASE "cfg" // settings config data from server #define SETTINGS_ITEM_METATYPE "text/plain" // meta type for settings config data // fatal errors #ifdef __PALM_OS__ #ifndef PlatFormFatalErr #define PlatFormFatalErr { ErrDisplay("PlatFormFatalErr called"); ErrThrow(999); } #endif #define PlatFormFatalThrow(x) { exception *eP=new x; ErrDisplay(eP->what()); ErrThrow(999); } #define PlatFormFatalReThrow { ErrDisplay("C++ re-throw attempted"); ErrThrow(999); } #elif defined(ANDROID) #ifndef PlatFormFatalErr #define PlatFormFatalErr { __android_log_write( ANDROID_LOG_DEBUG, "exc", "PlatFormFatalErr called"); exit(999); } #endif #define PlatFormFatalThrow(x) { exception *eP=new x; __android_log_print( ANDROID_LOG_DEBUG, "exc", "C++ exception thrown: %s",eP->what()); exit(999); } #define PlatFormFatalReThrow { __android_log_write( ANDROID_LOG_DEBUG, "exc", "C++ re-throw attempted"); exit(999); } #else #ifndef PlatFormFatalErr #define PlatFormFatalErr { printf("PlatFormFatalErr called"); exit(999); } #endif #define PlatFormFatalThrow(x) { exception *eP=new x; printf("C++ exception thrown: %s",eP->what()); exit(999); } #define PlatFormFatalReThrow { printf("C++ re-throw attempted"); exit(999); } #endif #ifdef ANDROID #define DYN_CAST static_cast #else #define DYN_CAST dynamic_cast #endif // exceptions #ifndef TARGET_HAS_EXCEPTIONS // define here depending on compiler // if not defined e.g. in target options #ifdef __EPOC_OS__ // no exceptions in EPOC #define TARGET_HAS_EXCEPTIONS 0 #elif defined(__MWERKS__) // in Coderwarrior it depends on compiler settings #if __option (exceptions) #define TARGET_HAS_EXCEPTIONS 1 #else #define TARGET_HAS_EXCEPTIONS 0 #endif #elif defined(WINCE) || defined(ANDROID) // no exceptions in eVC #define TARGET_HAS_EXCEPTIONS 0 #else // otherwise generally assume yes #define TARGET_HAS_EXCEPTIONS 1 #endif #endif #if TARGET_HAS_EXCEPTIONS // really throw #define SYSYNC_THROW(x) throw x #define SYSYNC_RETHROW throw #define SYSYNC_TRY try #define SYSYNC_CATCH(x) catch(x) { #define SYSYNC_ENDCATCH } #else // global fatal error #define SYSYNC_THROW(x) PlatFormFatalThrow(x) #define SYSYNC_RETHROW PlatFormFatalReThrow #define SYSYNC_TRY #define SYSYNC_CATCH(x) if(false) { TSmlException e("",SML_ERR_UNSPECIFIC); #define SYSYNC_ENDCATCH } #endif // checked casts (non-checked when RTTI is not there) #if defined(WINCE) || defined(__EPOC_OS__) || defined(ANDROID) // eVC + symbian has no RTTI, so we rely on having the right type and // do a static cast here #define GET_CASTED_PTR(dst,ty,src,msg) dst=static_cast(src) #else // use dynamic cast and check if pointer is not NULL #define GET_CASTED_PTR(dst,ty,src,msg) { dst = dynamic_cast(src); if (!dst) { SYSYNC_THROW(TSyncException(msg)); } } #endif // global types // library calling interface #ifndef SYSYLIBCI #define SYSYLIBCI // default to compilers default calling interface #endif // extra1 values for pev_debug #define PEV_DEBUG_FORCERETRY 1 #ifdef __cplusplus // internal field types (item field types) typedef enum { fty_string, fty_telephone, fty_integer, fty_timestamp, fty_date, fty_url, fty_multiline, fty_blob, fty_none, // note: this one is mostly internal use numFieldTypes } TItemFieldTypes; #ifdef SCRIPT_SUPPORT // built-in function definition class TItemField; class TScriptContext; typedef void (*TBuiltinFunc)(TItemField *&aTermP, TScriptContext *aFuncContextP); typedef void* (*TTableChainFunc) (void *&aNextCallerContext); typedef struct { // name of function cAppCharP fFuncName; // implementation TBuiltinFunc fFuncProc; // return type of function TItemFieldTypes fReturntype; // parameters sInt16 fNumParams; // list of parameter definition bytes const uInt8 *fParamTypes; } TBuiltInFuncDef; typedef struct { // number of functions uInt16 numFuncs; // actual functions const TBuiltInFuncDef *funcDefs; // chain function TTableChainFunc chainFunc; } TFuncTable; #endif // SCRIPT_SUPPORT // progress event class TLocalDSConfig; // forward typedef struct { TProgressEventType eventtype; TLocalDSConfig *datastoreID; // config pointer is used as ID, NULL if global sInt32 extra; // extra info, such as error code or count for progress or # of added items sInt32 extra2; // extra info, such as total for progress or # of updated items sInt32 extra3; // extra info, such as # of deleted items } TProgressEvent; // Callbacks /* %%% from old ages, probably obsolete // - XML config data reader func type typedef int SYSYLIBCI (*TXMLTextReadFunc)( appCharP aBuffer, bufferIndex aMaxSize, bufferIndex *aReadCharsP, void *aContext ); // - text message output typedef void SYSYLIBCI (*TTextMsgProc)(cAppCharP aMessage, void *aContext); */ // - progress event notification typedef bool SYSYLIBCI (*TProgressEventFunc)( const TProgressEvent &aEvent, void *aContext ); #endif // __cplusplus // local status codes (normally generated from SyncML status + LOCAL_STATUS_CODE) typedef uInt16 localstatus; // SyncML encodings // Note: SmlEncoding_t is defined in the RTK smldef.h #define numSyncMLEncodings (SML_XML-SML_UNDEF+1) // SyncML Versions typedef enum { syncml_vers_unknown, syncml_vers_1_0, syncml_vers_1_1, syncml_vers_1_2, // number of enums numSyncMLVersions } TSyncMLVersions; // conflict resolution strategies typedef enum { cr_duplicate, // add conflicting counterpart to both databases cr_newer_wins, // newer version wins (if date/version comparison is possible, like sst_duplicate otherwise) cr_server_wins, // server version wins (and is written to client, with merge if enabled) cr_client_wins, // client version wins (and is written to server, with merge if enabled) // number of enums numConflictStrategies } TConflictResolution; // package states typedef enum { psta_idle, // not started yet, no package sent or received psta_init, // initialisation package psta_sync, // sync package psta_initsync, // combined initialisation and sync package psta_map, // data update status / map psta_supplement, // extra packages possibly needed at end of session // number of enums numPackageStates } TPackageStates; /// Sync operations typedef enum { sop_wants_add, ///< like add, but is still available for slowsync match sop_add, sop_wants_replace, ///< like replace, but not yet conflict-checked sop_replace, sop_reference_only, ///< slowsync resume only: like sop_wants_add/sop_wants_replace, but ONLY for comparing with incoming add/replace from client and avoiding add when matching - NEVER send these to client sop_archive_delete, sop_soft_delete, sop_delete, sop_copy, sop_move, // new for DS 1.2 sop_none, // should be last // number of enums numSyncOperations } TSyncOperation; // Sync modes (note: slow/refresh is a separate flag) typedef enum { smo_twoway, smo_fromserver, smo_fromclient, // number of enums numSyncModes } TSyncModes; // filter identifiers #define isFilterIdent(c) (isalnum(c) || c=='_' || c=='.') #ifdef __cplusplus // forwards class TSmlCommand; // container for TSmlCommand pointers typedef std::list TSmlCommandPContainer; // contains sync commands // Free all items in container and clear it. void TSmlCommandPContainerClear(TSmlCommandPContainer &aContainer); // string to string map typedef std::map TStringToStringMap; // string to string map #endif #ifdef __cplusplus } // namespace sysync #endif #endif // SYSYNC_GLOBS_H // eof libsynthesis-3.4.0.47.1/src/sysync/sysync_precomp.h000077500000000000000000000021351226375725500222150ustar00rootroot00000000000000/* Headers that might be available in precompiled form * (standard libraries, SyncML toolkit...) */ #ifndef SYSYNC_PRECOMP_H #define SYSYNC_PRECOMP_H /* global includes */ #include "target_options.h" /* standard C includes */ #ifdef __PALM_OS__ // don't use the *.h versions! they don't work any more with CW Palm v9 #include #include #include #include #include #else #include #include #include #include #if !defined(WINCE) && !defined(MACOSX) #include // BCPPB #endif #endif /* C++/STL includes */ /* - RTTI */ #if !defined(WINCE) && !defined(__EPOC_OS__) #include #endif #if __MC68K__ #warning "STL headers excluded from precompiled headers due to problems with CW Palm v9" #else /* - STL */ #include #include #include #include #endif #if defined(LINUX) || defined(__EPOC_OS__) // gcc in standard distrs lacks the STL header #include #else #include #endif #endif // defined SYSYNC_PRECOMP_H libsynthesis-3.4.0.47.1/src/sysync/sysync_precomp_xpt.h000077500000000000000000000006011226375725500231040ustar00rootroot00000000000000/* Headers that might be available in precompiled form * (standard libraries, SyncML toolkit...) */ #ifndef SYSYNC_PRECOMP_XPT_H #define SYSYNC_PRECOMP_XPT_H // include what is needed anyway for sysync... #include "sysync_precomp.h" // ...plus XPT SyncML Toolkit includes // - SyncML Toolkit external API extern "C" { #include "xpt.h" } #endif // defined SYSYNC_PRECOMP_XPT_H libsynthesis-3.4.0.47.1/src/sysync/textitemtype.cpp000077500000000000000000000263011226375725500222410ustar00rootroot00000000000000/* * File: TextItemType.cpp * * Author: Lukas Zeller (luz@plan44.ch) * * TTextItemType * base class for plain text based items (notes, emails...) * * Copyright (c) 2002-2011 by Synthesis AG + plan44.ch * * 2002-05-29 : luz : created from MimeDirItemType * */ // includes #include "prefix_file.h" #include "sysync.h" #include "textitemtype.h" using namespace sysync; // Config // ====== // text-based datatype config TTextTypeConfig::TTextTypeConfig(const char* aName, TConfigElement *aParentElement) : TMultiFieldTypeConfig(aName,aParentElement) { clear(); } // TTextTypeConfig::TTextTypeConfig TTextTypeConfig::~TTextTypeConfig() { // make sure everything is deleted (was missing long time and caused mem leaks!) clear(); } // TTextTypeConfig::~TTextTypeConfig // init defaults void TTextTypeConfig::clear(void) { // clear inherited inherited::clear(); } // TTextTypeConfig::clear // create Sync Item Type of appropriate type from config TSyncItemType *TTextTypeConfig::newSyncItemType(TSyncSession *aSessionP, TSyncDataStore *aDatastoreP) { if (!fFieldListP) SYSYNC_THROW(TSyncException(DEBUGTEXT("TTextTypeConfig::newSyncItemType: no fFieldListP","txit1"))); return new TTextItemType( aSessionP, this, fTypeName.c_str(), fTypeVersion.c_str(), aDatastoreP, fFieldListP ); } // TTextTypeConfig::newSyncItemType #ifdef CONFIGURABLE_TYPE_SUPPORT // config element parsing bool TTextTypeConfig::localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine) { // For >2.1 engines, the text item does not have linemaps etc. in the datatype, but uses // profiles that can be shared among datatypes. To maintain compatibility with old config // files, we implicitly create and link a profile if we see profile definions at this // level // - first, check textItem specifics // %%% none // - then, check ancestor if (TMultiFieldTypeConfig::localStartElement(aElementName,aAttributes,aLine)) return true; // ancestor could parse the tag else { // ancestor did not know the tag, could be implicit profile if (!fProfileConfigP) { // there is no profile config yet, create an implicit one // - create an implicit profile with the same name as the datatype itself if (!fFieldListP) return fail("%s must have a 'use' tag before referencing fields"); TMultiFieldDatatypesConfig *mfdtcfgP = static_cast(getParentElement()); fProfileConfigP=new TTextProfileConfig(getName(),mfdtcfgP); if (fProfileConfigP) { fProfileConfigP->fFieldListP = fFieldListP; // assign field list mfdtcfgP->fProfiles.push_back(fProfileConfigP); // add to profiles } // - warn ReportError(false, "Warning: old-style config - '%s' directly in datatype '%s', should be moved to textprofile", aElementName, getName() ); } // now try to parse if (fProfileConfigP) { // let the profile parse as if it was inside a "textprofile" return delegateParsingTo(fProfileConfigP,aElementName,aAttributes,aLine); } else return false; // cannot parse } } // TTextTypeConfig::localStartElement // resolve void TTextTypeConfig::localResolve(bool aLastPass) { // check correct type of profile if (DYN_CAST(fProfileConfigP)==NULL) SYSYNC_THROW(TConfigParseException("missing 'use' of a 'textprofile' in datatype")); // resolve inherited inherited::localResolve(aLastPass); } // TTextTypeConfig::localResolve #endif /* * Implementation of TTextItemType */ TTextItemType::TTextItemType( TSyncSession *aSessionP, TDataTypeConfig *aTypeCfgP, // type config const char *aCTType, const char *aVerCT, TSyncDataStore *aRelatedDatastoreP, TFieldListConfig *aFieldDefinitions // field definitions ) : TMultiFieldItemType(aSessionP,aTypeCfgP,aCTType,aVerCT,aRelatedDatastoreP,aFieldDefinitions), fProfileHandlerP(NULL) { // save typed config pointer again fTypeCfgP = static_cast(aTypeCfgP); // create the profile handler fProfileHandlerP = static_cast(aTypeCfgP)->fProfileConfigP->newProfileHandler(this); // set profile mode fProfileHandlerP->setProfileMode(fTypeCfgP->fProfileMode); } // TTextItemType::TTextItemType TTextItemType::~TTextItemType() { if (fProfileHandlerP) delete fProfileHandlerP; } // TTextItemType::~TTextItemType cAppCharP TTextItemType::getTypeVers(sInt32 aMode) { // This function is called by TMimeDirProfile when generating the // VERSION property. Allow converting a plain text item to // iCalendar 2.0 (aMode = 2) or vCalendar 1.0 (aMode = 1) by // overriding the base version that was configured for the // underlying text item type. switch (aMode) { default: return inherited::getTypeVers(aMode); case 1: return "1.0"; case 2: return "2.0"; } } // TTextItemType::getTypeVers #ifdef OBJECT_FILTERING // get field index of given filter expression identifier. sInt16 TTextItemType::getFilterIdentifierFieldIndex(const char *aIdentifier, uInt16 aIndex) { // check if explicit field level identifier if (strucmp(aIdentifier,"F.",2)==0) { // explicit field identifier, skip property lookup aIdentifier+=2; } else if (fProfileHandlerP) { // let profile search for fields by profile-defined alternative names sInt16 fid = fProfileHandlerP->getFilterIdentifierFieldIndex(aIdentifier, aIndex); if (fid!=FID_NOT_SUPPORTED) return fid; } // if no field ID found so far, look up in field list return TMultiFieldItemType::getFilterIdentifierFieldIndex(aIdentifier, aIndex); } // TTextItemType::getFilterIdentifierFieldIndex #endif // helper to create same-typed instance via base class TSyncItemType *TTextItemType::newCopyForSameType( TSyncSession *aSessionP, // the session TSyncDataStore *aDatastoreP // the datastore ) { // create new itemtype of appropriate derived class type that can handle // this type MP_RETURN_NEW(TTextItemType,DBG_OBJINST,"TTextItemType",TTextItemType( aSessionP, fTypeConfigP, getTypeName(), getTypeVers(), aDatastoreP, fFieldDefinitionsP )); } // TTextItemType::newCopyForSameType // create new sync item of proper type and optimization for specified target TSyncItem *TTextItemType::internalNewSyncItem(TSyncItemType *aTargetItemTypeP, TLocalEngineDS *aLocalDatastoreP) { // All TextItems are stored in MultiFieldItems if (!aTargetItemTypeP->isBasedOn(ity_multifield)) SYSYNC_THROW(TSyncException(DEBUGTEXT("TTextItemType::internalNewSyncItem with bad-typed target","txit3"))); TMultiFieldItemType *targetitemtypeP = static_cast (aTargetItemTypeP); return new TMultiFieldItem(this,targetitemtypeP); } // TTextItemType::internalNewSyncItem // fill in SyncML data (but leaves IDs empty) bool TTextItemType::internalFillInData( TSyncItem *aSyncItemP, // SyncItem to be filled with data SmlItemPtr_t aItemP, // SyncML toolkit item Data to be converted into SyncItem (may be NULL if no data, in case of Delete or Map) TLocalEngineDS *aLocalDatastoreP, // local datastore TStatusCommand &aStatusCmd // status command that might be modified in case of error ) { // check type if (!aSyncItemP->isBasedOn(ity_multifield) || !fProfileHandlerP) SYSYNC_THROW(TSyncException(DEBUGTEXT("TTextItemType::internalFillInData: incompatible item class","txit4"))); TMultiFieldItem *itemP = static_cast (aSyncItemP); // process data if any if (aItemP->data) { // set related datastore so handler can access session specific datastore state fProfileHandlerP->setRelatedDatastore(aLocalDatastoreP); // for text items, the profile handler does all the parsing stringSize sz; cAppCharP t = smlPCDataToCharP(aItemP->data,&sz); if (!fProfileHandlerP->parseText(t,sz,*itemP)) { // format error aStatusCmd.setStatusCode(415); // Unsupported media type or format ADDDEBUGITEM(aStatusCmd,"Error parsing Text content"); return false; } } else { // no data aStatusCmd.setStatusCode(412); // incomplete command ADDDEBUGITEM(aStatusCmd,"No data found in item"); return false; } // ok, let ancestor process data as well return TMultiFieldItemType::internalFillInData(aSyncItemP,aItemP,aLocalDatastoreP,aStatusCmd); } // TTextItemType::internalFillInData // sets data and meta from SyncItem data, but leaves source & target untouched bool TTextItemType::internalSetItemData( TSyncItem *aSyncItemP, // the syncitem to be represented as SyncML SmlItemPtr_t aItem, // item with NULL meta and NULL data TLocalEngineDS *aLocalDatastoreP // local datastore ) { // check type if (!aSyncItemP->isBasedOn(ity_multifield) || !fProfileHandlerP) SYSYNC_THROW(TSyncException(DEBUGTEXT("TTextItemType::internalSetItemData: incompatible item class","txit4"))); TMultiFieldItem *itemP = static_cast (aSyncItemP); // let ancestor prepare first if (!TMultiFieldItemType::internalSetItemData(aSyncItemP,aItem,aLocalDatastoreP)) return false; // set related datastore so handler can access session specific datastore state fProfileHandlerP->setRelatedDatastore(aLocalDatastoreP); // generate data item string dataitem; fProfileHandlerP->generateText(*itemP,dataitem); // put data item into opaque/cdata PCData (note that dataitem could be BINARY string, so we need to pass size!) aItem->data=newPCDataStringX((const uInt8 *)dataitem.c_str(),true,dataitem.size()); // can't go wrong return true; } // TTextItemType::internalSetItemData // generates SyncML-Devinf property list for type SmlDevInfCTDataPropListPtr_t TTextItemType::newCTDataPropList(TTypeVariantDescriptor aVariantDescriptor) { // no properties here return NULL; } // TTextItemType::newCTDataPropList // Filtering: add keywords and property names to filterCap void TTextItemType::addFilterCapPropsAndKeywords(SmlPcdataListPtr_t &aFilterKeywords, SmlPcdataListPtr_t &aFilterProps, TTypeVariantDescriptor aVariantDescriptor) { #ifdef OBJECT_FILTERING // let profile add the keywords if (fProfileHandlerP) { fProfileHandlerP->addFilterCapPropsAndKeywords(aFilterKeywords, aFilterProps, aVariantDescriptor, this); } // let base class add own keywords/props inherited::addFilterCapPropsAndKeywords(aFilterKeywords, aFilterProps, aVariantDescriptor); #endif } // TTextItemType::addFilterCapPropsAndKeywords // intended for creating SyncItemTypes for remote databases from // transmitted DevInf. // SyncItemType MUST NOT take ownership of devinf structure passed // (because multiple types might be created from a single CTCap entry) bool TTextItemType::analyzeCTCap(SmlDevInfCTCapPtr_t aCTCapP) { // just let parent handle return inherited::analyzeCTCap(aCTCapP); } // TTextItemType::analyzeCTCap /// @brief copy CTCap derived info from another SyncItemType /// @return false if item not compatible /// @note required to create remote type variants from ruleMatch type alternatives bool TTextItemType::copyCTCapInfoFrom(TSyncItemType &aSourceItem) { // just let parent handle return inherited::copyCTCapInfoFrom(aSourceItem); } // TTextItemType::copyCTCapInfoFrom /* end of TTextItemType implementation */ // eof libsynthesis-3.4.0.47.1/src/sysync/textitemtype.h000077500000000000000000000103211226375725500217010ustar00rootroot00000000000000/* * File: TextItemType.h * * Author: Lukas Zeller (luz@plan44.ch) * * TTextItemType * base class for plain text based items (notes, emails...) * * Copyright (c) 2002-2011 by Synthesis AG + plan44.ch * * 2002-05-29 : luz : created from MimeDirItemType * */ #ifndef TextItemType_H #define TextItemType_H // includes #include "syncitemtype.h" #include "multifielditemtype.h" #include "textprofile.h" namespace sysync { // Text based datatype class TTextTypeConfig : public TMultiFieldTypeConfig { typedef TMultiFieldTypeConfig inherited; public: TTextTypeConfig(const char *aElementName, TConfigElement *aParentElementP); virtual ~TTextTypeConfig(); // properties // public functions // - create Sync Item Type of appropriate type from config virtual TSyncItemType *newSyncItemType(TSyncSession *aSessionP, TSyncDataStore *aDatastoreP); protected: #ifdef CONFIGURABLE_TYPE_SUPPORT // check config elements virtual bool localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine); virtual void localResolve(bool aLastPass); #endif virtual void clear(); }; // TTextTypeConfig const uInt16 ity_text=102; // must be unique class TTextItemType: public TMultiFieldItemType { typedef TMultiFieldItemType inherited; public: // constructor TTextItemType( TSyncSession *aSessionP, TDataTypeConfig *aTypeCfgP, // type config const char *aCTType, const char *aVerCT, TSyncDataStore *aRelatedDatastoreP, TFieldListConfig *aFieldDefinitions // field definitions ); // destructor virtual ~TTextItemType(); // access to type virtual cAppCharP getTypeVers(sInt32 aMode=0); virtual uInt16 getTypeID(void) const { return ity_text; }; virtual bool isBasedOn(uInt16 aItemTypeID) const { return aItemTypeID==ity_text ? true : TMultiFieldItemType::isBasedOn(aItemTypeID); }; // differentiation between implemented and just descriptive TSyncTypeItems virtual bool isImplemented(void) { return true; }; // MIME-DIR is an implementation // helper to create same-typed instance via base class // MUST BE IMPLEMENTED IN ALL DERIVED CLASSES! virtual TSyncItemType *newCopyForSameType( TSyncSession *aSessionP, // the session TSyncDataStore *aDatastoreP // the datastore ); /// @brief copy CTCap derived info from another SyncItemType virtual bool copyCTCapInfoFrom(TSyncItemType &aSourceItem); #ifdef OBJECT_FILTERING // filtering // - get field index of given filter expression identifier. virtual sInt16 getFilterIdentifierFieldIndex(const char *aIdentifier, uInt16 aIndex); #endif protected: // - analyze CTCap for specific type virtual bool analyzeCTCap(SmlDevInfCTCapPtr_t aCTCapP); // - obtain property list for type, returns NULL if none available virtual SmlDevInfCTDataPropListPtr_t newCTDataPropList(TTypeVariantDescriptor aVariantDescriptor); // - Filtering: add keywords and property names to filterCap virtual void addFilterCapPropsAndKeywords(SmlPcdataListPtr_t &aFilterKeywords, SmlPcdataListPtr_t &aFilterProps, TTypeVariantDescriptor aVariantDesc); // Item data management // - create new sync item of proper type and optimization for specified target virtual TSyncItem *internalNewSyncItem(TSyncItemType *aTargetItemTypeP, TLocalEngineDS *aLocalDatastoreP); // - fill in SyncML data (but leaves IDs empty) virtual bool internalFillInData( TSyncItem *aSyncItemP, // SyncItem to be filled with data SmlItemPtr_t aItemP, // SyncML toolkit item Data to be converted into SyncItem (may be NULL if no data, in case of Delete or Map) TLocalEngineDS *aLocalDatastoreP, // local datastore TStatusCommand &aStatusCmd // status command that might be modified in case of error ); // - sets data and meta from SyncItem data, but leaves source & target untouched virtual bool internalSetItemData( TSyncItem *aSyncItemP, // the syncitem to be represented as SyncML SmlItemPtr_t aItem, // item with NULL meta and NULL data TLocalEngineDS *aLocalDatastoreP // local datastore ); private: // member fields TProfileHandler *fProfileHandlerP; TTextTypeConfig *fTypeCfgP; // the text type config element }; // TTextItemType } // namespace sysync #endif // TextItemType_H // eof libsynthesis-3.4.0.47.1/src/sysync/textprofile.cpp000077500000000000000000001633111226375725500220440ustar00rootroot00000000000000/* * File: textprofile.cpp * * Author: Lukas Zeller (luz@plan44.ch) * * TTextProfile * utility class to parse line-by-line type text including RFC822 emails * * Copyright (c) 2002-2011 by Synthesis AG + plan44.ch * * 2005-07-26 : luz : extracted from textitemtype * */ // includes #include "prefix_file.h" #include "sysync.h" #include "textprofile.h" using namespace sysync; // Config // ====== #define X_LIMIT_HEADER_NAME "X-Sync-Message-Limit" // line map config TLineMapDefinition::TLineMapDefinition(TConfigElement *aParentElementP, sInt16 aFid) : TConfigElement("lm",aParentElementP) { // save field ID fFid=aFid; // init others clear(); } // TLineMapDefinition::TLineMapDefinition void TLineMapDefinition::clear(void) { // clear // - default: all text fNumLines=0; fInHeader=false; // not restricted to header fAllowEmpty=false; // no empty ones // - no tagged header TCFG_CLEAR(fHeaderTag); // - no RFC822 specials fValueType=vt822_plain; fListSeparator=0; fMaxRepeat=1; fRepeatInc=1; #ifdef OBJECT_FILTERING // - no filterkeyword TCFG_CLEAR(fFilterKeyword); #endif } // TLineMapDefinition::clear #ifdef CONFIGURABLE_TYPE_SUPPORT // Conversion names for RFC(2)822 parsing const char * const RFC822ValueTypeNames[num822ValueTypes] = { "text", "date", "body", "rfc2047" }; // server config element parsing bool TLineMapDefinition::localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine) { // checking the elements if (strucmp(aElementName,"numlines")==0) expectInt16(fNumLines); else if (strucmp(aElementName,"inheader")==0) expectBool(fInHeader); else if (strucmp(aElementName,"allowempty")==0) expectBool(fAllowEmpty); else if (strucmp(aElementName,"headertag")==0) expectString(fHeaderTag); // filtering #ifdef OBJECT_FILTERING else if (strucmp(aElementName,"filterkeyword")==0) expectString(fFilterKeyword); #endif // RFC(2)822 parsing options else if (strucmp(aElementName,"valuetype")==0) expectEnum(sizeof(fValueType),&fValueType,RFC822ValueTypeNames,num822ValueTypes); else if (strucmp(aElementName,"list")==0) { // list spec // - separator const char *attr = getAttr(aAttributes,"separator"); if (!attr) fail("list needs 'separator'"); fListSeparator=*attr; // - max repetitions fMaxRepeat=1; attr = getAttr(aAttributes,"repeat"); if (attr) { #ifdef ARRAYFIELD_SUPPORT if (strucmp(attr,"array")==0) fMaxRepeat=REP_ARRAY; else #endif if (!StrToShort(attr,fMaxRepeat)) return !fail("expected number or 'array' in 'repeat'"); } fRepeatInc=1; if (!getAttrShort(aAttributes,"increment",fRepeatInc,true)) return !fail("number expected in 'increment'"); } // - none known here else return inherited::localStartElement(aElementName,aAttributes,aLine); // ok return true; } // TLineMapDefinition::localStartElement #endif TLineMapDefinition::~TLineMapDefinition() { // nop so far } // TLineMapDefinition::~TLineMapDefinition // text-based datatype config TTextProfileConfig::TTextProfileConfig(const char *aElementName, TConfigElement *aParentElementP) : TProfileConfig(aElementName,aParentElementP) { clear(); } // TTextProfileConfig::TTextProfileConfig TTextProfileConfig::~TTextProfileConfig() { // make sure everything is deleted (was missing long time and caused mem leaks!) clear(); } // TTextProfileConfig::~TTextProfileConfig // init defaults void TTextProfileConfig::clear(void) { // clear properties // - init fFieldListP=NULL; #ifdef EMAIL_FORMAT_SUPPORT fMIMEMail=false; fBodyMIMETypesFid=VARIDX_UNDEFINED; fSizeLimitField=VARIDX_UNDEFINED; fBodyCountFid=VARIDX_UNDEFINED; #ifdef EMAIL_ATTACHMENT_SUPPORT // - no limit fMaxAttachments=29999; // enough // - fields not yet known fAttachmentCountFid=VARIDX_UNDEFINED; fAttachmentMIMETypesFid=VARIDX_UNDEFINED; fAttachmentContentsFid=VARIDX_UNDEFINED; fAttachmentSizesFid=VARIDX_UNDEFINED; fAttachmentNamesFid=VARIDX_UNDEFINED; #endif #endif // - remove line maps TLineMapList::iterator pos; for(pos=fLineMaps.begin();pos!=fLineMaps.end();pos++) delete *pos; fLineMaps.clear(); // clear inherited inherited::clear(); } // TTextProfileConfig::clear #ifdef CONFIGURABLE_TYPE_SUPPORT // config element parsing bool TTextProfileConfig::localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine) { /* %%% this must be enabled if we want to reference script vars #ifdef SCRIPT_SUPPORT // early resolve basic multifield scripts so we can refer to local vars if (!fScriptsResolved) %%% resolve resolvecontext; #endif */ // checking the elements if (strucmp(aElementName,"linemap")==0) { // const char* nam = getAttr(aAttributes,"field"); if (!fFieldListP) return fail("'use' must be specified before first "); // search field // %%% add context here if we have any sInt16 fid = TConfigElement::getFieldIndex(nam,fFieldListP); if (fid==VARIDX_UNDEFINED) return fail("'field' references unknown field '%s'",nam); // create new linemap TLineMapDefinition *linemapP = new TLineMapDefinition(this,fid); // - save in list fLineMaps.push_back(linemapP); // - let element handle parsing expectChildParsing(*linemapP); } #ifdef EMAIL_FORMAT_SUPPORT else if (strucmp(aElementName,"mimemail")==0) expectBool(fMIMEMail); else if (strucmp(aElementName,"sizelimitfield")==0) expectFieldID(fSizeLimitField,fFieldListP); else if (strucmp(aElementName,"bodymimetypesfield")==0) expectFieldID(fBodyMIMETypesFid,fFieldListP); else if (strucmp(aElementName,"bodycountfield")==0) expectFieldID(fBodyCountFid,fFieldListP); #ifdef EMAIL_ATTACHMENT_SUPPORT else if (strucmp(aElementName,"maxattachments")==0) expectInt16(fMaxAttachments); else if (strucmp(aElementName,"attachmentcountfield")==0) expectFieldID(fAttachmentCountFid,fFieldListP); else if (strucmp(aElementName,"attachmentmimetypesfield")==0) expectFieldID(fAttachmentMIMETypesFid,fFieldListP); else if (strucmp(aElementName,"attachmentsfield")==0) expectFieldID(fAttachmentContentsFid,fFieldListP); else if (strucmp(aElementName,"attachmentsizesfield")==0) expectFieldID(fAttachmentSizesFid,fFieldListP); else if (strucmp(aElementName,"attachmentnamesfield")==0) expectFieldID(fAttachmentNamesFid,fFieldListP); #endif #endif // - none known here else return TProfileConfig::localStartElement(aElementName,aAttributes,aLine); // ok return true; } // TTextProfileConfig::localStartElement // resolve void TTextProfileConfig::localResolve(bool aLastPass) { // nop // resolve inherited inherited::localResolve(aLastPass); } // TTextProfileConfig::localResolve #endif #ifdef HARDCODED_TYPE_SUPPORT TLineMapDefinition *TTextProfileConfig::addLineMap( sInt16 aFid, sInt16 aNumLines, bool aAllowEmpty, bool aInHeader, const char* aHeaderTag, T822ValueType aValueType, char aListSeparator, sInt16 aMaxRepeat, sInt16 aRepeatInc ) { // create new linemap TLineMapDefinition *linemapP = new TLineMapDefinition(this,aFid); // set properties linemapP->fNumLines=aNumLines; linemapP->fAllowEmpty=aAllowEmpty; linemapP->fInHeader=aInHeader; TCFG_ASSIGN(linemapP->fHeaderTag,aHeaderTag); // save email options linemapP->fValueType=aValueType; linemapP->fListSeparator=aListSeparator; linemapP->fListSeparator=aMaxRepeat; linemapP->fListSeparator=aRepeatInc; // save in list fLineMaps.push_back(linemapP); // return pointer return linemapP; } // TTextProfileConfig::addLineMap #endif // handler factory TProfileHandler *TTextProfileConfig::newProfileHandler(TMultiFieldItemType *aItemTypeP) { // check if fieldlists match as they should if (aItemTypeP->getFieldDefinitions()!=fFieldListP) { // profile is for another field list, cannot be used for this item type return NULL; } // our handler is the text profile handler return (TProfileHandler *)(new TTextProfileHandler(this,aItemTypeP)); } /* * Implementation of TTextProfileHandler */ TTextProfileHandler::TTextProfileHandler( TTextProfileConfig *aTextProfileCfgP, TMultiFieldItemType *aItemTypeP ) : TProfileHandler(aTextProfileCfgP, aItemTypeP) { // save profile config pointer fProfileCfgP = aTextProfileCfgP; // datastore settable options defaults fNoAttachments = false; fItemSizeLimit = -1; } // TTextProfileHandler::TTextProfileHandler TTextProfileHandler::~TTextProfileHandler() { // nop for now } // TTextProfileHandler::~TTextProfileHandler #ifdef OBJECT_FILTERING // Filtering: add keywords and property names to filterCap void TTextProfileHandler::addFilterCapPropsAndKeywords(SmlPcdataListPtr_t &aFilterKeywords, SmlPcdataListPtr_t &aFilterProps, TTypeVariantDescriptor aVariantDescriptor, TSyncItemType *aItemTypeP) { // search linemaps for fields with keyword TLineMapList::iterator pos; for(pos=fProfileCfgP->fLineMaps.begin();pos!=fProfileCfgP->fLineMaps.end();pos++) { // first priority: compare with explicit filterkeyword, if any if (!TCFG_ISEMPTY((*pos)->fFilterKeyword)) { // has a filterkeyword, show it addPCDataStringToList(TCFG_CSTR((*pos)->fFilterKeyword), &aFilterKeywords); } } } // TTextProfileHandler::addFilterCapPropsAndKeywords // get field index of given filter expression identifier. sInt16 TTextProfileHandler::getFilterIdentifierFieldIndex(const char *aIdentifier, uInt16 aIndex) { // search linemaps for tagged fields TLineMapList::iterator pos; for(pos=fProfileCfgP->fLineMaps.begin();pos!=fProfileCfgP->fLineMaps.end();pos++) { // first priority: compare with explicit filterkeyword, if any if (!TCFG_ISEMPTY((*pos)->fFilterKeyword)) { // compare with filterkeyword if (strucmp(TCFG_CSTR((*pos)->fFilterKeyword),aIdentifier)==0) return (*pos)->fFid; } else if (TCFG_SIZE((*pos)->fHeaderTag)>1) { // one tag char and a separator at least // if no filterkeyword defined, compare to header without separator if (strucmp(TCFG_CSTR((*pos)->fHeaderTag),aIdentifier,TCFG_SIZE((*pos)->fHeaderTag)-1)==0) return (*pos)->fFid; } } // no field ID found in profile return FID_NOT_SUPPORTED; } // TTextProfileHandler::getFilterIdentifierFieldIndex #endif #ifdef EMAIL_FORMAT_SUPPORT // find token in header data static cAppCharP findToken(cAppCharP aText, cAppCharP aTextEnd, char aStopChar, cAppCharP &aTokenStart, stringSize &aTokenLen) { // skip trailing whitespace cAppCharP e=aTextEnd; if (!e) e=aText+strlen(aText); while (aTexterase(); if (strucmp(tok,"attachment",toksz)==0 || strucmp(tok,"inline",toksz)==0) { while (*p==';') { p++; p=findToken(p,e,'=',tok,toksz); if (strucmp(tok,"filename",toksz)==0) { // filename, get it if (*p=='=') { p++; p=findToken(p,e,';',tok,toksz); aFileNameP->assign(tok,toksz); } } else { // other param, skip it if (*p=='=') { p++; p=findToken(p,e,';',tok,toksz); } } } } } else return false; // no MIME header // found MIME header return true; } // checkMimeHeaders // parse body into appropriate field(s) cAppCharP TTextProfileHandler::parseBody( cAppCharP aText, // body text to parse stringSize aTextSize, // max text to parse cAppCharP aType, TEncodingTypes aEncoding, uInt32 aContentLen, TCharSets aCharSet, TMultiFieldItem &aItem, TLineMapDefinition *aLineMapP, cAppCharP aBoundary // boundary, NULL if none ) { // empty boundary is no boundary if (aBoundary && *aBoundary==0) aBoundary=NULL; POBJDEBUGPRINTFX(fItemTypeP->getSession(),DBG_PARSE,( "Parsing body (part) with Content-Type='%s', Encoding=%s, contentLen=%ld, Charset=%s, Boundary='%s'", aType, MIMEEncodingNames[aEncoding], (long)aContentLen, MIMECharSetNames[aCharSet], aBoundary ? aBoundary : "" )); // params for parts string contentType=aType; // content type string boundary; // main boundary string filename; // attachment TEncodingTypes encoding=aEncoding; // main encoding uInt32 contentlen=aContentLen; // content len in case encoding is binary TCharSets charset=aCharSet; // main charset // helpers string decoded; string converted; TItemField *fldP; // check if alternative bool alternative = strucmp(aType,"multipart/alternative")==0; bool foundBody=false; // search for first boundary occurrence if this is multipart cAppCharP toBeParsed=NULL; // pointer to previous part to be processed size_t previousSize=0; cAppCharP prevStart=NULL; cAppCharP p=aText; cAppCharP eot=p+aTextSize; bool startpart=false; // process parts do { startpart=false; // search for a boundary occurrence if this is multipart if (aBoundary) { size_t bl=strlen(aBoundary); prevStart=p; // check for special case: if we have something to parse, and encoding is binary, // use the content-length header to skip to next boundary if (toBeParsed && encoding==enc_binary) { // we simply KNOW how much to skip until next boundary starts p=toBeParsed+contentlen; // p now points to the next boundary indicator } // now detect boundary indicator do { if (p+2+bl<=eot && strucmp(p,"--",2)==0) { p+=2; if (strucmp(p,aBoundary,bl)==0) { // start of line matches boundary startpart=true; // calc how much we skipped until finding this boundary previousSize=p-2-prevStart; // A boundary has to be preceeded by a CRLF according to rfc2046, and // this CRLF belongs to the boundary and is NOT considered to be content of the preceeding part // Therefore, the following code is only needed for error tolerance reasons - for // correctly formatted message it's just a -=2. if (previousSize>2) { if (*(p-3)==0x0A || *(p-3)==0x0D) previousSize--; if (*(p-4)==0x0A || *(p-4)==0x0D) previousSize--; } // Note: in case of binary encoding, previousSize should be contentlen here! p+=bl; } } // skip until end of line while (p0) { // parse leaf part (DO NOT CHANGE p HERE, it points to next part) // decide if this is body or attachment bool isText = contentType.empty() || (strucmp(contentType.c_str(),"text/",5)==0); if (isText && filename.empty()) { // this is a part of the body // - check if we can store multiple bodies bool multibody = aItem.getField(aLineMapP->fFid)->isArray(); if (!foundBody || multibody) { sInt16 bodyIndex=VARIDX_UNDEFINED; // not found plain text body yet (or we can store multiple bodies) if (!alternative || strucmp(contentType.c_str(),"text/plain")==0) { // strictly plain text or not alternative, store it in the first body array element bodyIndex=0; // found plain text body, discard other alternatives if we have no other body variants if (alternative) foundBody=true; } else if (multibody) { // text, but not plain - and we can store alternatives, do it! bodyIndex=++fBodyAlternatives; } // if we shall store, do it now (otherwise, fldP is NULL) if (bodyIndex!=VARIDX_UNDEFINED) { // - get MIME-type field fldP = aItem.getArrayField(fProfileCfgP->fBodyMIMETypesFid,bodyIndex); if (fldP) { fldP->setAsString(contentType); // store MIME type } // - get content field fldP = aItem.getArrayField(aLineMapP->fFid,bodyIndex); if (fldP) { // - decode decoded.erase(); decoded.reserve(previousSize); // we need approx this sizee -> reserve to speed up appendDecoded( toBeParsed, previousSize, decoded, encoding ); // - convert charset converted.erase(); converted.reserve(decoded.size()); // we need approx this size -> reserve to speed up appendStringAsUTF8( decoded.c_str(), converted, charset, lem_cstr ); decoded.erase(); // we do not need this any more // add to field fldP->appendString(converted.c_str(), converted.size()); } } } } else { // this is an attachment, ignore it if we have no attachment support #ifdef EMAIL_ATTACHMENT_SUPPORT if (filename.empty()) { // create filename StringObjPrintf(filename,"attachment%hd.bin",fExtraParts); } // save filename if (fProfileCfgP->fAttachmentNamesFid!=VARIDX_UNDEFINED) { fldP=aItem.getArrayField(fProfileCfgP->fAttachmentNamesFid,fExtraParts); if (fldP) { fldP->setAsString(filename.c_str()); } } // save type if (fProfileCfgP->fAttachmentMIMETypesFid!=VARIDX_UNDEFINED) { fldP=aItem.getArrayField(fProfileCfgP->fAttachmentMIMETypesFid,fExtraParts); if (fldP) { fldP->setAsString(contentType.c_str()); } } // now decode attachment itself decoded.erase(); decoded.reserve(previousSize); // we need approx this sizee -> reserve to speed up appendDecoded( toBeParsed, previousSize, decoded, encoding ); // save attachment data if (fProfileCfgP->fAttachmentContentsFid!=VARIDX_UNDEFINED) { fldP=aItem.getArrayField(fProfileCfgP->fAttachmentContentsFid,fExtraParts); if (fldP) { fldP->setAsString(decoded.c_str(),decoded.size()); } } // save size in extra field if (fProfileCfgP->fAttachmentSizesFid!=VARIDX_UNDEFINED) { fldP=aItem.getArrayField(fProfileCfgP->fAttachmentSizesFid,fExtraParts); if (fldP) { fldP->setAsInteger(decoded.size()); } } decoded.erase(); // we do not need this any more // done, found one extra part fExtraParts++; #else // Attachment cannot be processed // - get body field fldP = aItem.getArrayField(aLineMapP->fFid,0); // - append attachment replacement message string msg; if (filename.empty()) filename=""; StringObjPrintf(msg,"\n\nAttachment not stored: %s\n\n",filename.c_str()); fldP->appendString(msg.c_str()); #endif } } // if not empty part // done toBeParsed=NULL; // if parsing single part, we're done if (!aBoundary) return p; } // check for more parts or exit if this was the closing boundary if (startpart) { // we have found a boundary above, p=space following it // part starts here bool isPart=false; // - get headers while (pfFid); // use appropriate translator string s; switch (aLineMapP->fValueType) { case vt822_timestamp: #ifdef EMAIL_FORMAT_SUPPORT // rfc822 timestamp if (!fieldP->isBasedOn(fty_timestamp)) break; s.assign(aValue,aValSize); if (!(static_cast(fieldP)->setAsRFC822date(s.c_str(),aItem.getSession()->fUserTimeContext,false))) fieldP->assignEmpty(); break; #endif case vt822_body: #ifdef EMAIL_FORMAT_SUPPORT // falls through to plain if email support is switched off if (fProfileCfgP->fMIMEMail) { // clear body text field fieldP->assignEmpty(); fExtraParts=0; fBodyAlternatives=0; // now parse body (we should already have parsed the content headers parseBody( aValue, // body text to parse aValSize, fContentType.c_str(),fEncoding,fContentLen,fCharSet, aItem, aLineMapP, fBoundary.c_str() // boundary, NULL or empty if none ); // save number of bodies if (fProfileCfgP->fBodyCountFid!=VARIDX_UNDEFINED) { TItemField *fldP=aItem.getField(fProfileCfgP->fBodyCountFid); if (fldP) { fldP->setAsInteger(fBodyAlternatives+1); } } // save number of attachments #ifdef EMAIL_ATTACHMENT_SUPPORT if (fProfileCfgP->fAttachmentCountFid!=VARIDX_UNDEFINED) { TItemField *fldP=aItem.getField(fProfileCfgP->fAttachmentCountFid); if (fldP) { fldP->setAsInteger(fExtraParts); } } #endif break; } #endif goto standardfield; case vt822_rfc2047: #ifdef EMAIL_FORMAT_SUPPORT // text field encoded according to RFC2047 s.erase(); appendRFC2047AsUTF8(aValue,aValSize,s); fieldP->setAsString(s.c_str()); break; #else goto standardfield; #endif standardfield: case vt822_plain: // plain text default: // assign as string fieldP->setAsString(aValue,aValSize); break; } return true; } // TTextProfileHandler::parseContent #ifdef EMAIL_FORMAT_SUPPORT // add a MIME-Boundary static void addBoundary(string &aString, sInt16 aLevel, bool aForHeader=false) { if (!aForHeader) aString+="\x0D\x0A--"; StringObjAppendPrintf(aString,"--==========_=_nextpart_%03hd_42503735617.XE======",aLevel); if (!aForHeader) aString+="\x0D\x0A"; } // TTextProfileHandler::addBoundary // add a body content-type header static void addBodyTypeHeader(sInt16 aBodyTypeFid, sInt16 aBodyIndex, TMultiFieldItem &aItem, string &aString) { string bodytype; TItemField *fldP = aItem.getArrayField(aBodyTypeFid,aBodyIndex,true); if (fldP && !fldP->isEmpty()) fldP->getAsString(bodytype); else bodytype="text/plain"; aString+="Content-Type: "; aString+=bodytype; aString+="; charset=\"UTF-8\"\x0D\x0A"; } // addBodyTypeHeader // generate body (multipart/alternative if there is more than one) // if aLevel==0, content type was already set before bool TTextProfileHandler::generateBody(sInt16 aLevel, TMultiFieldItem &aItem, TLineMapDefinition *aLineMapP, string &aString) { // check if we need to add headers if (aLevel>0) { #ifdef EMAIL_ATTACHMENT_SUPPORT if (fBodyAlternatives>0) { // multiple bodies, nested multipart aString+="Content-Type: multipart/alternative;\x0D\x0A boundary=\""; addBoundary(aString,aLevel,true); // nested boundary aString+="\"\x0D\x0A"; } else #endif { // single body, add body type addBodyTypeHeader(fProfileCfgP->fBodyMIMETypesFid, 0, aItem, aString); // - end part header aString+="\x0D\x0A"; } } // now add body/bodies // - get size limit for this item sInt16 bodyindex=0; do { #ifdef EMAIL_ATTACHMENT_SUPPORT if (fBodyAlternatives>0 && fItemSizeLimit!=0) { // - opening boundary addBoundary(aString,aLevel); // nested // - content type addBodyTypeHeader(fProfileCfgP->fBodyMIMETypesFid, bodyindex, aItem, aString); // - end part header aString+="\x0D\x0A"; } #endif // get body field TItemField *fieldP = aItem.getArrayField(aLineMapP->fFid,bodyindex); if (!fieldP) break; // should not happen // now generate body contents if (fItemSizeLimit==0) { // limited to nothing, just don't send anything fLimited=true; break; } else if (fieldP->isBasedOn(fty_string)) { TStringField *sfP = static_cast(fieldP); if (fItemSizeLimit>0) { // limited string field // - check if we can add more if (fItemSizeLimit<=fGeneratedBytes) { // already exhausted, suppress body completely fLimited=true; break; } // add limited number of body bytes // - determine number of bytes to send #ifdef STREAMFIELD_SUPPORT sInt32 bodysize=sfP->getStreamSize(); if (bodysize+fGeneratedBytes > fItemSizeLimit) { bodysize=fItemSizeLimit-fGeneratedBytes; fLimited=true; } // - get appropriate number of bytes char *bodyP = new char[bodysize+1]; sfP->resetStream(); bodysize = sfP->readStream(bodyP,bodysize); bodyP[bodysize]=0; // - append to content string aString.reserve(aString.size()+bodysize); // reserve what we need approximately appendUTF8ToString( bodyP, aString, chs_utf8, // always UTF8 for body lem_dos // CRLFs for email ); // approximately, UTF-8 conversion and CRLF might cause slightly more chars fGeneratedBytes+=bodysize; // - get rid of buffer delete bodyP; #else // simply get it fieldP->appendToString(aString,fItemSizeLimit); fGeneratedBytes+=fieldP->getStringSize(); #endif } else { // no limit, simply append to content string appendUTF8ToString( sfP->getCStr(), aString, chs_utf8, // always UTF8 for body lem_dos // CRLFs for email ); // approximately, UTF-8 conversion and CRLF might cause slightly more chars fGeneratedBytes+=sfP->getStringSize(); } } else { // no string field, just append string representation fieldP->appendToString(aString); fGeneratedBytes+=fieldP->getStringSize(); } // done one body bodyindex++; // repeat until all done } while (bodyindex<=fBodyAlternatives && (fItemSizeLimit<0 || fGeneratedBytes0 && fItemSizeLimit!=0) { // - closing boundary for last part addBoundary(aString,aLevel); // nested } #endif return true; } // TTextProfileHandler::generateBody #endif // generate contents of a header or body // returns true if tagging and folding is needed on output, // false if output can simply be appended to text (such as: no output at all) bool TTextProfileHandler::generateContent(TMultiFieldItem &aItem, TLineMapDefinition *aLineMapP, string &aString) { aString.erase(); // nothing by default bool needsfolding=true; string s; // %%% missing repeats TItemField *fieldP=aItem.getField(aLineMapP->fFid); if (!fieldP) return false; // no field contents, do not even show the tag switch (aLineMapP->fValueType) { case vt822_body: // body with size restriction #ifdef EMAIL_FORMAT_SUPPORT #ifdef EMAIL_ATTACHMENT_SUPPORT // - multipart is supported if (fExtraParts>0) { // add body as first part // - opening boundary addBoundary(aString,0); // - add body on level 1 (means that it must add its own headers) generateBody(1,aItem,aLineMapP,aString); // - add attachments sInt16 attIdx; TItemField *fldP; for (attIdx=0; attIdxfAttachmentSizesFid!=VARIDX_UNDEFINED) { fldP=aItem.getArrayField(fProfileCfgP->fAttachmentSizesFid,attIdx,true); if (!fldP) continue; // get it from separate field attachsize=fldP->getAsInteger(); } else { // get it from attachment itself (will probably pull proxy) fldP=aItem.getArrayField(fProfileCfgP->fAttachmentContentsFid,attIdx,true); if (!fldP) continue; attachsize=fldP->getStringSize(); } // - check if we have data for the attachment if (attachsize==0) continue; // Prepare attachment TItemField *attfldP = NULL; // none yet string attachMsg; attachMsg.erase(); // no message // - get content type bool isText=false; fldP = aItem.getArrayField(fProfileCfgP->fAttachmentMIMETypesFid,attIdx,true); string contenttype; if (fldP && !fldP->isEmpty()) { fldP->getAsString(contenttype); } else { contenttype="application/octet-stream"; } // - check for text/xxxx contents if (strucmp(contenttype.c_str(),"text/",5)==0) isText=true; // - check if attachment has enough room if ( (fItemSizeLimit>=0 && fGeneratedBytes+attachsize>fItemSizeLimit) || // limit specified by client !fItemTypeP->getSession()->dataSizeTransferable(fGeneratedBytes+attachsize*(isText ? 3 : 4)/3) // physical limit as set by maxMsgSize in SyncML 1.0 and maxObjSize in SyncML 1.1 ) { // no room for attachment, include a text message instead fldP = aItem.getArrayField(fProfileCfgP->fAttachmentNamesFid,attIdx,true); string attnam; if (fldP) fldP->getAsString(attnam); else attnam="unnamed"; StringObjPrintf(attachMsg, "\x0D\x0A" "Attachment suppressed: '%s' (%ld KBytes)\x0D\x0A", attnam.empty() ? "" : attnam.c_str(), long(attachsize/1024) ); // set type contenttype="text/plain"; isText=true; // force in-line // signal incomplete message // NOTE: other attachments that are smaller may still be included fLimited=true; } else { // we can send the attachment attfldP = aItem.getArrayField(fProfileCfgP->fAttachmentContentsFid,attIdx,true); if (!attfldP) continue; // cannot generate this attachment } // - opening boundary for attachment addBoundary(aString,0); // - add disposition aString+="Content-Disposition: "; if (isText) { // text is always in-line aString+="inline"; } else { // non-text is attachment if it has a filename fldP = aItem.getArrayField(fProfileCfgP->fAttachmentNamesFid,attIdx,true); if (fldP && !fldP->isEmpty()) { // has a filename, make attachment aString+="attachment; filename=\""; fldP->appendToString(aString); aString+="\""; } else { // has no filename, show inline aString+="inline"; } } aString+="\x0D\x0A"; // - start content type (but no charset yet) aString+="Content-Type: "; aString+=contenttype; // - check attachment mode if (attfldP && attfldP->isBasedOn(fty_blob)) { // Attachment is a BLOB, so it may contain binary data TBlobField *blobP = static_cast(attfldP); // make sure charset/encoding are valid blobP->makeContentsValid(); // - get charset from the BLOB if (blobP->fCharset!=chs_unknown) { aString+="; charset=\""; aString+=MIMECharSetNames[blobP->fCharset]; aString+='"'; } aString+="\x0D\x0A"; // - if known, use originally requested encoding TEncodingTypes enc = blobP->fWantsEncoding; TEncodingTypes hasenc = blobP->fHasEncoding; // - make sure we use a valid encoding that is ok for sending as text if (enc==enc_b || enc==enc_none || enc==enc_binary) { enc = isText ? enc_8bit : enc_base64; } // - see if we should transmit the existing encoding if (isText) { if (hasenc==enc_7bit && hasenc==enc_8bit && hasenc==enc_quoted_printable) enc=hasenc; // already encoded } else { if (hasenc==enc_base64 || hasenc==enc_b) enc=hasenc; // already encoded } // when we are in Synthesis-special mode, and encoding is WBXML, we can use plain binary encoding // (specifying the length with a Content-Length: header) if (fItemTypeP->getTypeConfig()->fBinaryParts && fItemTypeP->getSession()->getEncoding()==SML_WBXML && (enc==enc_b || enc==enc_base64)) { // switch to 1:1 binary enc=enc_binary; StringObjAppendPrintf(aString,"Content-Length: %ld\x0D\x0A", long(blobP->getStringSize())); } // - set transfer encoding from the BLOB aString+="Content-Transfer-Encoding: "; aString+=MIMEEncodingNames[enc]; aString+="\x0D\x0A"; // - end of part headers aString+="\x0D\x0A"; // - now add contents as-is (this pulls the proxy now) appendEncoded( (const uInt8 *)blobP->getCStr(), // input blobP->getStringSize(), aString, // append output here enc==hasenc ? enc_none : enc, // desired encoding if not already encoded MIME_MAXLINESIZE, // limit to standard MIME-linesize 0, // current line size false // insert CRLFs for line breaks ); } else { // Attachment isn't a BLOB, but a string. Transmit as 8bit, UTF-8 aString+="; charset=\""; aString+=MIMECharSetNames[chs_utf8]; aString+="\"\x0D\x0A"; // - content encoding is 8bit aString+="Content-Transfer-Encoding: "; aString+=MIMEEncodingNames[enc_8bit]; aString+="\x0D\x0A"; // - end of part headers aString+="\x0D\x0A"; // - simply append string if (attfldP) { attfldP->getAsString(s); appendUTF8ToString( s.c_str(), aString, chs_utf8, // always UTF8 for body lem_dos // CRLFs for email ); } else { // append attachment suppression message aString+=attachMsg; // no attachment field, append replacement text instead } } // count added bytes fGeneratedBytes+=(aString.size()-sizebefore); } // for all attachments // - closing boundary addBoundary(aString,0); } else #endif { // message consists only of a body (which might have alternatives) // - add body on level 0 (means that it must not have own headers) generateBody(0,aItem,aLineMapP,aString); } // Body does not need any folding needsfolding=false; break; #else // no EMAIL FORMAT support goto standardfield; #endif case vt822_rfc2047: // text field encoded according to RFC2047 #ifdef EMAIL_FORMAT_SUPPORT if (fieldP->isUnassigned()) return false; // field not assigned, do not even show the tag fieldP->getAsString(s); appendUTF8AsRFC2047(s.c_str(),aString); break; #else goto standardfield; #endif case vt822_timestamp: if (fieldP->isUnassigned()) return false; // field not assigned, do not even show the tag #ifdef EMAIL_FORMAT_SUPPORT if (!fieldP->isBasedOn(fty_timestamp)) break; static_cast(fieldP)->getAsRFC822date(aString,aItem.getSession()->fUserTimeContext,true); break; #endif #ifndef EMAIL_FORMAT_SUPPORT standardfield: #endif case vt822_plain: // plain text if (fieldP->isUnassigned()) return false; // field not assigned, do not even show the tag fieldP->getAsString(aString); break; case num822ValueTypes: // not handled? break; } return needsfolding; } // TTextProfileHandler::generateContent // generate Data item (includes header and footer) void TTextProfileHandler::generateText(TMultiFieldItem &aItem, string &aString) { TLineMapList::iterator pos; // reset byte counter fGeneratedBytes=0; fLimited=false; #ifdef EMAIL_ATTACHMENT_SUPPORT fExtraParts=0; #endif #ifdef EMAIL_FORMAT_SUPPORT fBodyAlternatives=0; bool multipart=false; #endif #ifdef SYDEBUG POBJDEBUGPRINTFX(fItemTypeP->getSession(),DBG_GEN+DBG_HOT,("Generating....")); aItem.debugShowItem(DBG_DATA+DBG_GEN); #endif // init attachment limit // - get from datastore if one is related if (fRelatedDatastoreP) { fItemSizeLimit = fRelatedDatastoreP->getItemSizeLimit(); fNoAttachments = fRelatedDatastoreP->getNoAttachments(); } // - if size limit is zero or attachments explicitly disabled, // attachments are not allowed for this item #ifdef EMAIL_ATTACHMENT_SUPPORT if (fItemSizeLimit==0 || fNoAttachments) fAttachmentLimit=0; // no attachments else fAttachmentLimit=fProfileCfgP->fMaxAttachments; // use limit from datatype config #endif // generate according to linemaps bool header = (*fProfileCfgP->fLineMaps.begin())->fInHeader; // we are in header if first is in header for (pos=fProfileCfgP->fLineMaps.begin();pos!=fProfileCfgP->fLineMaps.end();pos++) { // get linemap config TLineMapDefinition *linemapP = *pos; // separate body if (header && !linemapP->fInHeader) { // add special email headers #ifdef EMAIL_FORMAT_SUPPORT if (fProfileCfgP->fMIMEMail) { // basic support TItemField *cntFldP; #ifdef EMAIL_ATTACHMENT_SUPPORT // attachments allowed, get number cntFldP = aItem.getField(fProfileCfgP->fAttachmentCountFid); if (cntFldP && !cntFldP->isEmpty()) { // we have a count field, get it's value fExtraParts=cntFldP->getAsInteger(); } else { // determine exta part number by counting attachments if (fProfileCfgP->fAttachmentContentsFid) { fExtraParts=aItem.getField(fProfileCfgP->fAttachmentContentsFid)->arraySize(); } } // limit to what is allowed if (fExtraParts > fProfileCfgP->fMaxAttachments) fExtraParts=fProfileCfgP->fMaxAttachments; if (fExtraParts > fAttachmentLimit) { fExtraParts=fAttachmentLimit; fLimited=true; } // check if we have body alternatives cntFldP = aItem.getField(fProfileCfgP->fBodyCountFid); if (cntFldP && !cntFldP->isEmpty()) { // we have a count field, get it's value fBodyAlternatives=cntFldP->getAsInteger()-1; } else { fBodyAlternatives = aItem.getField(linemapP->fFid)->arraySize()-1; } if (fBodyAlternatives<0) fBodyAlternatives=0; // now add multipart content header if we have extra parts to send if (fExtraParts>0) { // we have attachments, this will be a multipart/mixed aString+="Content-Type: multipart/mixed;\x0D\x0A boundary=\""; addBoundary(aString,0,true); aString+="\"\x0D\x0A"; multipart=true; } else if (fBodyAlternatives) { // no attachments, but multiple bodies aString+="Content-Type: multipart/alternative;\x0D\x0A boundary=\""; addBoundary(aString,0,true); aString+="\"\x0D\x0A"; multipart=true; } else { // no attachments and no body alternatives, single body // - set type header for first and only part addBodyTypeHeader(fProfileCfgP->fBodyMIMETypesFid, 0,aItem,aString); } #else // only single body supported, always UTF-8 addBodyTypeHeader(fProfileCfgP->fBodyMIMETypesFid, 0,aItem,aString); #endif // now add encoding header, always 8-bit aString+="Content-Transfer-Encoding: 8BIT\x0D\x0A"; } else { // no mail format, end headers here aString.append("\x0D\x0A"); // extra empty line } #else // end headers aString.append("\x0D\x0A"); // extra empty line #endif } // generate value string fval; bool tagandfold=generateContent(aItem,linemapP,fval); // prevent empty ones if selected if (fval.empty() && !linemapP->fAllowEmpty) continue; // prefix with tag if any bool tagged=!TCFG_ISEMPTY(linemapP->fHeaderTag); // add field contents now // generate contents from field if (!tagandfold) { // no folding necessary #ifdef EMAIL_FORMAT_SUPPORT // - add updated limit header here if message is really limited if (fProfileCfgP->fMIMEMail) { if (fProfileCfgP->fSizeLimitField!=VARIDX_UNDEFINED) { TItemField *fldP = aItem.getField(fProfileCfgP->fSizeLimitField); fieldinteger_t limit = fItemSizeLimit; // now update its value if (!fLimited) limit=-1; fldP->setAsInteger(limit); // limited to specified size // now add the updated limit header (we have no linemap for it) aString+=X_LIMIT_HEADER_NAME ": "; fldP->appendToString(aString); aString+="\x0D\x0A"; // end of header } // terminate header not before here if (header && !linemapP->fInHeader) { // end headers aString.append("\x0D\x0A"); // extra empty line } } #endif // - fVal includes everything needed INCLUDING tag AND CRLF at end // or fVal is empty meaning that the value does not need to be added at all aString.append(fval); } else { // add tag if tagged line if (tagged) { aString.append(linemapP->fHeaderTag); aString+=' '; // this extra space is common usage in RFC822 mails } // add with folding const char *p = fval.c_str(); sInt16 n=(*pos)->fNumLines; sInt16 i=0; sInt16 cnt=0; // char counter sInt16 lastLWSP=-1; // no linear whitespace found yet char c; // add multi-line field contents while ((c=*p++)) { if (c=='\r') continue; // ignore CRs if (tagged) { // apply RFC822 folding (65 recommened for old terminals, 72 max) if (cnt>=65) { // check where we can fold if (lastLWSP>=0) { // this is the last LWSP // - new size of line is string beginning with lastLWSP up to end of string cnt=aString.size()-lastLWSP; // - insert a CRLF before the last LWSP aString.insert(lastLWSP,"\x0D\x0A"); // - this one is now invalid lastLWSP=-1; // invalidate again } } if (isspace(c)) { // remember possible position for folding lastLWSP=aString.size(); // index of this LWSP } } if (c=='\n') { // line break in data if (tagged) { // for tagged fields, line break in data is used as recommended folding // position, so just fold NOW aString.append("\x0D\x0A "); lastLWSP=-1; cnt=1; // the space is already here } else { // for non-tagged fields, we might cut writing data here if no more lines allowed // - check if more lines allowed if (igetSession(),DBG_GEN,("Generated:")); if (fItemTypeP->getDbgMask() & DBG_GEN) { // note, do not use debugprintf because string is too long POBJDEBUGPUTSXX(fItemTypeP->getSession(),DBG_GEN+DBG_USERDATA,aString.c_str(),0,true); } #endif } // TTextProfileHandler::generateText // parse Data item (includes header and footer) bool TTextProfileHandler::parseText(const char *aText, stringSize aTextSize, TMultiFieldItem &aItem) { TLineMapList::iterator pos; // get options from datastore if one is related if (fRelatedDatastoreP) { fItemSizeLimit = fRelatedDatastoreP->getItemSizeLimit(); fNoAttachments = fRelatedDatastoreP->getNoAttachments(); } // parse according to linemaps pos=fProfileCfgP->fLineMaps.begin(); if (pos==fProfileCfgP->fLineMaps.end()) return true; // simply return, no mappings defined // - we are in header if first is in header bool header=(*pos)->fInHeader; #ifdef EMAIL_FORMAT_SUPPORT fContentType.erase(); // no known type fBoundary.erase(); // no boundary yet fEncoding=enc_8bit; // 8 bit fContentLen=0; // not defined until we have Synthesis-style binary encoding in parts fCharSet=chs_utf8; // UFT-8 is SyncML default fContentType.erase(); // no main content type #endif // - header has tagged fields if first has a tag bool tagged=!TCFG_ISEMPTY((*pos)->fHeaderTag); const char *p = aText; const char *eot = aText+aTextSize; // if we are starting in body, simulate a preceeding EOLN bool lastwaseoln=!header; while (pos!=fProfileCfgP->fLineMaps.end()) { // check special case of this linemap eating all of the remaining body text if (!header && (*pos)->fNumLines==0) { // Optimization: this linemap will receive the entire remainder of the message parseContent(p, eot-p, aItem, *pos); // and we are done goto parsed; } // scan input data string fval; fval.erase(); char c=0; sInt16 i=0,n=0; bool assignnow=false; bool fielddone=false; while (p<=eot) { // get char, simulate a NUL if we are at end of text c = (p==eot) ? 0 : *p; p++; // make sure we're over eot now // convert all types of line ends: 0A, 0D0A and 0D are allowed // special 0D0D0A that sometimes happens (CRLF saved through a DOS // linefeed expander) is also detected correctly if (c==0x0D) { // CR, discard LF if one follows if (p=eot || c==0 || (*p!=' ' && *p!='\t')) { // end of text or next line does not begin with space or TAB -> end of header #ifdef EMAIL_FORMAT_SUPPORT if (fProfileCfgP->fMIMEMail) { // check for MIME-content relevant mail headers first if (!checkMimeHeaders(fval.c_str(),fval.size(),fContentType,fEncoding,fContentLen,fCharSet,fBoundary,NULL)) { // check for X-Sync-Limit special header const char *h = fval.c_str(); const char *e = h+fval.size(); const char *tok; stringSize toksz; h=findToken(h,e,':',tok,toksz); if (*h==':') { // header field ++h; // check name if (strucmp(tok,X_LIMIT_HEADER_NAME,toksz)==0) { // X-Sync-Limit special header h=findToken(h,e,':',tok,toksz); TItemField *limfldP = aItem.getField(fProfileCfgP->fSizeLimitField); if (limfldP) limfldP->setAsString(tok,toksz); } } } } // note that mime headers can still be mapped to fields, so fall through #endif // - search by tag for matching linemap now TLineMapList::iterator tagpos; for (tagpos=fProfileCfgP->fLineMaps.begin();tagpos!=fProfileCfgP->fLineMaps.end();tagpos++) { TCFG_STRING &s = (*tagpos)->fHeaderTag; if ((*tagpos)->fInHeader && !TCFG_ISEMPTY(s)) { if (strucmp(fval.c_str(),TCFG_CSTR(s),TCFG_SIZE(s))==0) { // tag matches, set position to matching linemap pos=tagpos; // remove tag from input data fval.erase(0,TCFG_SIZE(s)); // remove leading spaces size_t j=0; while (fval.size()>j && isspace(fval[j])) j++; if (j>0) fval.erase(0,j); // assign value now assignnow=true; break; // break for loop } } } // search for correct map // assignnow is set if we have found a map now, otherwise, header will be ignored fielddone=true; // cause loop exit, but first check for transition from header to body and set lastwaseoln } else { // process possible folding if (p ignore line end and just keep LWSP fval+=*p++; // keep the LWSP lastwaseoln=false; // last was LWSP, not EOLN :-) continue; // just check next one } } } // - check for switch from header to body if (header && lastwaseoln) { // two line ends in succession = end of header header=false; if (tagged) { // find first non-header linemap (pos can be anywhere within header linemaps here while (pos!=fProfileCfgP->fLineMaps.end() && (*pos)->fInHeader) pos++; // but no need to store, as tagged headers have stored already } else { // end of untagged headers // assign what is already accumulated assignnow=true; } tagged=false; // just stop here if no more linemaps if (pos==fProfileCfgP->fLineMaps.end()) { goto parsed; // do not spend time and memory with parsing unneeded data } // important optimization: if the last linemap does not have a line // count restriction, process rest of text without filling it into a string var if ((*pos)->fNumLines==0) { // this linemap will receive the entire remainder of the message parseContent(p, eot-p, aItem, *pos); // and we are done goto parsed; } break; } lastwaseoln=true; // end of input line if (!tagged) { i++; // count line n=(*pos)->fNumLines; if ((i>=n && n!=0) || c==0) { // line count exhausted or end of input text, assign to field now assignnow=true; // assign fval to field now break; } else if (c) fval+='\n'; // multi-line field, eoln if not eostring } } // if end of input line else { // not end of input line lastwaseoln=false; // add to value fval+=c; } if (!c || fielddone) break; } // assign accumulated value if (assignnow) { // assign according to linemap parseContent(fval.c_str(), fval.size(), aItem, *pos); // advance to next map if not in tagged header mode if (!tagged) pos++; } // all parsed, rest of definitions is not relevant, p is invalid if (c==0) break; } // while parsed: #ifdef SYDEBUG POBJDEBUGPRINTFX(fItemTypeP->getSession(),DBG_PARSE,("Successfully parsed: ")); if (fItemTypeP->getDbgMask() & DBG_PARSE) { // very detailed POBJDEBUGPUTSXX(fItemTypeP->getSession(),DBG_PARSE+DBG_USERDATA+DBG_EXOTIC,aText,0,true); } aItem.debugShowItem(DBG_DATA+DBG_PARSE); #endif return true; } // TTextProfileHandler::parseData /* end of TTextProfileHandler implementation */ // eof libsynthesis-3.4.0.47.1/src/sysync/textprofile.h000077500000000000000000000146061226375725500215130ustar00rootroot00000000000000/* * File: textprofile.h * * Author: Lukas Zeller (luz@plan44.ch) * * TTextProfile * utility class to parse line-by-line type text including RFC822 emails * * Copyright (c) 2002-2011 by Synthesis AG + plan44.ch * * 2005-07-26 : luz : extracted from textitemtype * */ #ifndef TextProfile_H #define TextProfile_H // includes #include "syncitemtype.h" #include "multifielditemtype.h" namespace sysync { typedef enum { vt822_plain, // no conversion at all vt822_timestamp, // RFC2822 timestamp value vt822_body, // email body vt822_rfc2047, // text with RFC2047 MIME message header extensions num822ValueTypes } T822ValueType; // line map definition class TLineMapDefinition : public TConfigElement { typedef TConfigElement inherited; public: // constructor/destructor TLineMapDefinition(TConfigElement *aParentElementP, sInt16 aFid); virtual ~TLineMapDefinition(); // properties // - number of lines (0=all) sInt16 fNumLines; // - allow empty bool fAllowEmpty; // - only header lines bool fInHeader; // - tagged header TCFG_STRING fHeaderTag; // must include the separator char (for RFC822 emails, a colon) // - field id to put text into sInt16 fFid; // RFC2822 parsing properties // - type of value T822ValueType fValueType; // - list separator (0=no list) char fListSeparator; // - max number of repeats (items in list), REP_ARRAY=unlimited, for array fields sInt16 fMaxRepeat; sInt16 fRepeatInc; #ifdef OBJECT_FILTERING // - no filterkeyword TCFG_STRING fFilterKeyword; #endif #ifdef CONFIGURABLE_TYPE_SUPPORT // check config elements virtual bool localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine); #endif virtual void clear(); }; // TLineMapDefinition // line mapping definitions typedef std::list TLineMapList; // Text based datatype class TTextProfileConfig : public TProfileConfig { typedef TProfileConfig inherited; public: TTextProfileConfig(const char *aElementName, TConfigElement *aParentElementP); virtual ~TTextProfileConfig(); // handler factory virtual TProfileHandler *newProfileHandler(TMultiFieldItemType *aItemTypeP); // properties // - Note, field list is parsed here, but is a property of TMultiFieldTypeConfig // - text-line based field definitions TLineMapList fLineMaps; #ifdef EMAIL_FORMAT_SUPPORT // email-specific properties // - if set, MIME mail extra feature according to RFC 2822/2045/2046 will be used bool fMIMEMail; // - field containing body type(s) (for body alternatives, if undefined defaults to text/plain) sInt16 fBodyMIMETypesFid; // - field that contains body count sInt16 fBodyCountFid; // - overall body size limit field sInt16 fSizeLimitField; #ifdef EMAIL_ATTACHMENT_SUPPORT // - max number of attachments (for non-arrays) sInt16 fMaxAttachments; // - field that contains attachment count sInt16 fAttachmentCountFid; // - field base offsets (or array field ID) for attachment components // - attachment MIME types sInt16 fAttachmentMIMETypesFid; // - attachment contents sInt16 fAttachmentContentsFid; // - attachment sizes (in bytes) sInt16 fAttachmentSizesFid; // - attachment (file)names sInt16 fAttachmentNamesFid; #endif #endif // public functions #ifdef HARDCODED_TYPE_SUPPORT TLineMapDefinition *addLineMap( sInt16 aFid, sInt16 aNumLines, bool aAllowEmpty, bool aInHeader=false, const char* aHeaderTag=NULL, T822ValueType aValueType=vt822_plain, char aListSeparator=0, sInt16 aMaxRepeat=1, sInt16 aRepeatInc=1 ); #endif protected: #ifdef CONFIGURABLE_TYPE_SUPPORT // check config elements public: virtual bool localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine); protected: virtual void localResolve(bool aLastPass); #endif virtual void clear(); }; // TTextProfileConfig class TTextProfileHandler : public TProfileHandler { typedef TProfileHandler inherited; public: // constructor TTextProfileHandler( TTextProfileConfig *aTextProfileCfgP, TMultiFieldItemType *aItemTypeP ); // destructor virtual ~TTextProfileHandler(); #ifdef OBJECT_FILTERING // filtering // - get field index of given filter expression identifier. virtual sInt16 getFilterIdentifierFieldIndex(const char *aIdentifier, uInt16 aIndex); // - add keywords and property names to filterCap virtual void addFilterCapPropsAndKeywords(SmlPcdataListPtr_t &aFilterKeywords, SmlPcdataListPtr_t &aFilterProps, TTypeVariantDescriptor aVariantDesc, TSyncItemType *aItemTypeP); #endif // generate Text Data (includes header and footer) virtual void generateText(TMultiFieldItem &aItem, string &aString); // parse Data item (includes header and footer) virtual bool parseText(const char *aText, stringSize aTextSize, TMultiFieldItem &aItem); private: // Internal routines #ifdef EMAIL_FORMAT_SUPPORT bool generateBody(sInt16 aLevel, TMultiFieldItem &aItem, TLineMapDefinition *aLineMapP, string &aString); cAppCharP parseBody( cAppCharP aText, // body text to parse stringSize aTextSize, // max text to parse cAppCharP aType, TEncodingTypes aEncoding, uInt32 aContentLen, TCharSets aCharSet, TMultiFieldItem &aItem, TLineMapDefinition *aLineMapP, cAppCharP aBoundary // boundary, NULL if none ); #endif bool generateContent(TMultiFieldItem &aItem, TLineMapDefinition *aLineMapP, string &aString); bool parseContent(const char *aValue, stringSize aValSize, TMultiFieldItem &aItem, TLineMapDefinition *aLineMapP); // vars TTextProfileConfig *fProfileCfgP; // the text profile config element fieldinteger_t fGeneratedBytes; // number of bytes already generated (for limit checks) bool fLimited; // set if size was actually limited // externally set options bool fNoAttachments; fieldinteger_t fItemSizeLimit; #ifdef EMAIL_FORMAT_SUPPORT sInt16 fExtraParts; // number of extra parts in addition to body sInt16 fBodyAlternatives; // number of body alternatives string fContentType; // main content type uInt32 fContentLen; // content len for Synthesis-style binary parts string fBoundary; // main boundary TEncodingTypes fEncoding; // main encoding TCharSets fCharSet; // main charset #ifdef EMAIL_ATTACHMENT_SUPPORT sInt16 fAttachmentLimit; // limit for attachments in this message #endif #endif }; // TTextProfileHandler } // namespace sysync #endif // TextProfile_H // eof libsynthesis-3.4.0.47.1/src/sysync/timezones.cpp000077500000000000000000001265721226375725500215240ustar00rootroot00000000000000/* * File: timezones.cpp * * Author: Beat Forster * * Timezones conversion from/to linear time scale. * * Copyright (c) 2004-2011 by Synthesis AG + plan44.ch * * 2004-04-18 : bfo : initial version * */ /* ToDo / open issues * * 1) done 04/04/18 does not contain TZ info, how to bring it in ? -> new param * 2) 04/04/18 not yet limited to one day * 3) done 04/04/18 Is 20040101Z a valid 8601 ? (yes it is) * 4) done 04/04/20 Fill in all valid time zones * 5) done 04/04/20 Adapt straight forward conversions Enum <=> Name * 6) done 04/06/14 System time zone calculation for Linux * 7) done 04/06/14 InsertTZ / RemoveTZ implementation * 8) 06/04/12 Offset calculation for more complicated vTZ ("$") records * 9) done 07/02/26 Multi year list support */ // must be first in file, everything above is ignored by MVC compilers #include "prefix_file.h" #define TIMEZONES_INTERNAL 1 // do not import the whole thing to make life easier for standalone apps #ifdef FULLY_STANDALONE #include "sysync_globs.h" #include "sysync_debug.h" #else #include "sysync.h" #endif #include "lineartime.h" #include "timezones.h" #include "iso8601.h" #include "stringutils.h" #include "vtimezone.h" namespace sysync { static bool tzcmp ( const tz_entry &t, const tz_entry &tzi, bool olsonSupport ); static bool YearFit( const tz_entry &t, const tz_entry &tzi, GZones* g ); // ---- global structure ----------------------------------------------------------- // %%% this is now a global variable, which is BAD. Unlike a const struct array, which can be put into the // code section, this "const" is a run-time generated structure (won't work e.g. for Symbian) // We should avoid this and create that object in the app level GZones, and let further GZone objects // allow using it (without copying!) - similar mechanism as the old CopyCustomTZFrom() had // (see 8742d15b65fecf02db54ce9b7447cee09f913ad0 commit which removed it) const class tzdata : public std::vector { public: tzdata() { #ifndef NO_BUILTIN_TZ // add the global entries reserve(tctx_numtimezones); for (int i=0; i 0 && back().name == t.name) { // the previous entry wasn't really the last of its group, // fix that back().groupEnd = false; } // add new entry, assuming that it terminates its group push_back(tz_entry( t.name, t.bias, t.biasDST, t.ident, t.dynYear, tChange(t.dst.wMonth, t.dst.wDayOfWeek, t.dst.wNth, t.dst.wHour, t.dst.wMinute), tChange(t.std.wMonth, t.std.wDayOfWeek, t.std.wNth, t.std.wHour, t.std.wMinute), true // groupEnd )); // allow olson names for Android //#ifdef ANDROID -- if (t.olsonName!=NULL) back().location= t.olsonName; //#endif -- } //push_back(tz_entry("unknown", 0, 0, "x", "", tChange( 0, 0,0, 0,0), tChange( 0, 0,0, 0,0))); // 0 #endif } } tz; // --------------------------------------------------------------------------------- // GZones bool GZones::initialize() { bool ok = true; // load system wide definitions. bool nobuiltin = loadSystemZoneDefinitions(this); // %%%% later, we'll load system zones not into each GZones, but only once into // a global list. Then, the return value of loadSystemZoneDefinitions() will // determine if zones from the built-in list should be added or not // %%%% for now, we can't do that yet, built-in zones are always active if (!nobuiltin) { //%%% add entries from tz_table } return ok; } void GZones::loggingStarted() { if (!fSystemZoneDefinitionsFinalized) { finalizeSystemZoneDefinitions(this); fSystemZoneDefinitionsFinalized = true; } } bool GZones::matchTZ(const tz_entry &aTZ, TDebugLogger *aLogP, timecontext_t &aContext) { // keeps track of best match while iterating class comparison : public visitor { /** best solution so far has matching rules */ bool fRuleMatch; /** best solution has matching location */ bool fLocationMatch; /** best solution so far */ timecontext_t fContext; /** the time zone we try to match */ tz_entry fTZ; /** the TZID we try to match */ string fTZID; /** the last entry without dynYear, i.e., the main entry of a group */ timecontext_t fLeadContext; TDebugLogger *fLogP; /** time zones */ GZones *fG; public: comparison(const tz_entry &aTZ, TDebugLogger *aLogP, GZones *g) : fRuleMatch(false), fLocationMatch(false), fContext(TCTX_UNKNOWN), fTZID(aTZ.name), fLeadContext(TCTX_UNKNOWN), fLogP(aLogP), fG(g) { // prepare information for tzcmp() and YearFit() fTZ.bias = aTZ.bias; fTZ.biasDST = aTZ.biasDST; fTZ.std = aTZ.std; fTZ.dst = aTZ.dst; // setting the year here instead of 'CUR' avoids repeated calls // to MyYear() inside YearFit() int year = MyYear(g); StringObjPrintf(fTZ.dynYear, "%d", year); } bool visit(const tz_entry &aTZ, timecontext_t aContext) { if (aTZ.ident=="x") return false; // comparison with this type is not possible bool olsonSupport= false; #ifdef ANDROID olsonSupport= true; #endif bool rule_match = tzcmp( fTZ, aTZ, olsonSupport ) && YearFit(fTZ, aTZ, fG); // start of a group is an entry that has a dynYear empty or set to "CUR" (for dynamically created entries) if (aTZ.dynYear.empty() || aTZ.dynYear == "CUR") fLeadContext = aContext; if (rule_match && !fTZ.name.empty() && // empty match is NOT better !! fTZ.name == aTZ.name) { // name AND rule match => best possible match, return early PLOGDEBUGPRINTFX(fLogP, DBG_PARSE+DBG_EXOTIC, ("matchTZ: final rule and name match for %s", fTZ.name.c_str())); fContext = fLeadContext; return true; } if (!aTZ.location.empty() && fTZID.find(aTZ.location) != fTZID.npos) { // location name is part of the TZID we try to match if (!fLocationMatch || (!fRuleMatch && rule_match)) { // previous match did not match location or // not the rules and we do, so this match is better PLOGDEBUGPRINTFX(fLogP, DBG_PARSE+DBG_EXOTIC, ("matchTZ %s: location %s found, rules %s", aTZ.name.c_str(), aTZ.location.c_str(), rule_match ? "match" : "don't match")); fLocationMatch = true; fRuleMatch = rule_match; fContext = fLeadContext; return false; } } // a rule match with no better match yet? if (!fLocationMatch && rule_match && !fRuleMatch) { PLOGDEBUGPRINTFX(fLogP, DBG_PARSE+DBG_EXOTIC, ("matchTZ %s: rules match (context #%d/%d, leadcontext=#%d)", aTZ.name.c_str(), TCTX_TZENUM(aContext), tctx_numtimezones, TCTX_TZENUM(fLeadContext))); fContext = fLeadContext; fRuleMatch = true; } return false; } // visit bool result(timecontext_t &aContext) { if (fContext != TCTX_UNKNOWN) { aContext = fContext; return true; } else { return false; } } // result } c(aTZ, aLogP, this); foreachTZ(c); return c.result(aContext); } // matchTZ bool GZones::foreachTZ(visitor &v) { int i; // visit hard coded elements first for (i= 1; i<(int)tctx_numtimezones; i++) { if (v.visit(tz[i], TCTX_ENUMCONTEXT(i))) { return true; } } bool result = false; #ifdef MUTEX_SUPPORT lockMutex(muP); #endif for (TZList::iterator pos= tzP.begin(); pos!=tzP.end(); pos++, i++) { if (v.visit(*pos, TCTX_ENUMCONTEXT(i))) break; } // for #ifdef MUTEX_SUPPORT unlockMutex(muP); #endif return result; } // foreachTZ // --------------------------------------------------------------------------------- // Get signed minute offset sInt16 TCTX_MINOFFSET( timecontext_t tctx ) { return (sInt16)(tctx & TCTX_OFFSETMASK ); } // TCTX_MINOFFSET // Get time zone enum TTimeZones TCTX_TZENUM( timecontext_t tctx ) { return (TTimeZones)(tctx & TCTX_OFFSETMASK ); } // TCTX_TZENUM // Check if is a symbolic TZ info bool TCTX_IS_TZ( timecontext_t tctx ) { return (tctx & TCTX_SYMBOLIC_TZ)!=0; } // TCTX_IS_TZ // Check if is a built-in symbolic TZ info bool TCTX_IS_BUILTIN( timecontext_t tctx ) { return (tctx & TCTX_SYMBOLIC_TZ) && // is a symbolic time zone (TCTX_TZENUM(tctx) has TCTX_DATEONLY mode set (but not TIMEONLY - both set means same as both not set) bool TCTX_IS_DATEONLY( timecontext_t tctx ) { return (tctx & TCTX_DATEONLY) && !(tctx & TCTX_TIMEONLY); } // TCTX_IS_DATEONLY // Check if has TCTX_TIMEONLY mode set (but not DATEONLY - both set means same as both not set) bool TCTX_IS_TIMEONLY( timecontext_t tctx ) { return (tctx & TCTX_TIMEONLY) && !(tctx & TCTX_DATEONLY); } // TCTX_IS_TIMEONLY // Check if has TCTX_DURATION mode set bool TCTX_IS_DURATION( timecontext_t tctx ) { return ( tctx & TCTX_DURATION )!=0; } // TCTX_IS_DURATION // Check if is a unknown time zone bool TCTX_IS_UNKNOWN( timecontext_t tctx ) { return TCTX_IS_TZ( tctx ) && ( TCTX_TZENUM( tctx )==tctx_tz_unknown ); } // TCTX_IS_UNKNOWN // Check if is the system time zone bool TCTX_IS_SYSTEM ( timecontext_t tctx ) { return TCTX_IS_TZ( tctx ) && ( TCTX_TZENUM( tctx )==tctx_tz_system ); } // TCTX_IS_SYSTEM // Check if is the UTC time zone bool TCTX_IS_UTC ( timecontext_t tctx ) { return TCTX_IS_TZ( tctx ) && ( TCTX_TZENUM( tctx )==tctx_tz_UTC ); } // TCTX_IS_SYSTEM //! result is render flags from with zone info from timecontext_t TCTX_JOIN_RFLAGS_TZ ( timecontext_t aRFlagContext, timecontext_t aZoneContext ) { return (aRFlagContext & TCTX_RFLAGMASK) | (aZoneContext & ~TCTX_RFLAGMASK); } // TCTX_JOIN_RFLAGS_TZ // ---- utility functions -------------------------------------------------------------- // Specific bias string. Unit: hours string BiasStr( int bias ) { char hrs[ 80 ]; float f= (float)bias/MinsPerHour; if (bias % MinsPerHour == 0) sprintf( hrs,"%3.0f ", f ); // not with .0 else if (abs(bias % MinsPerHour)==30) sprintf( hrs,"%5.1f ", f ); else sprintf( hrs,"%6.2f ", f ); return hrs; } // BiasStr // Clear the DST info of void ClrDST( tz_entry &t ) { memset( &t.dst, 0, sizeof(t.dst) ); memset( &t.std, 0, sizeof(t.std) ); } // ClrDST // ------------------------------------------------------------------------------------- // Special cases: = 0, the one w/o dynYear // = -1, direct index bool GetTZ( timecontext_t aContext, tz_entry &t, GZones* g, int year ) { if (!TCTX_IS_TZ( aContext )) return false; int aTZ= aContext & TCTX_OFFSETMASK; if (aTZ>=0 && aTZ, it is definitely false // ----------------------- bool ok= false; //if (g==NULL) g= gz(); // either or global list #ifdef MUTEX_SUPPORT lockMutex( g->muP ); #endif int i = tctx_numtimezones; TZList::iterator pos; for (pos= g->tzP.begin(); // go thru the additional list pos!=g->tzP.end(); pos++) { if (aTZ==i && // no removed elements !! !(pos->ident=="-")) { t = *pos; ok= true; if (year<=0) break; // pass unlock now pos++; while (pos!=g->tzP.end()) { // search for the dynamic year if (t.name != pos->name) break; // no or no more t=*pos; if (year<=atoi( t.dynYear.c_str() )) break; // this is the year line we are looking for pos++; } // while break; // pass unlock now } // if i++; } // for #ifdef MUTEX_SUPPORT unlockMutex( g->muP ); #endif // ----------------------- return ok; } /* GetTZ */ void Get_tChange( lineartime_t tim, tChange &v, sInt16 &y, bool asDate ) { sInt16 day, d, sec, ms; lineartime2date( tim, &y, &v.wMonth, &day ); lineartime2time( tim, &v.wHour, &v.wMinute, &sec, &ms ); if (asDate) { v.wDayOfWeek= -1; // use it as date directly v.wNth = day; } else { v.wDayOfWeek= lineartime2weekday( tim ); v.wNth = ( day-1 ) / DaysPerWk + 1; if (v.wNth==4) { // the last one within month ? d= day + DaysPerWk; AdjustDay( d, v.wMonth, y ); if ( d==day ) v.wNth= 5; } // if } // if } // Get_tChange static bool Fill_tChange( string iso8601, int bias, int biasDST, tChange &tc, sInt16 &y, bool isDST ) { lineartime_t l; timecontext_t c; //sInt16 y, day, d, sec, ms; string::size_type rslt= ISO8601StrToTimestamp( iso8601.c_str(), l, c ); if (rslt!=iso8601.length()) return false; if (iso8601[ rslt-1 ]=='Z') { // to it for UTC only int bMins = bias; if (!isDST) bMins+= biasDST; l+= seconds2lineartime( bMins*SecsPerMin ); } // if Get_tChange( l, tc, y ); /* lineartime2date( l, &y, &tc.wMonth, &day ); lineartime2time( l, &tc.wHour, &tc.wMinute, &sec, &ms ); tc.wDayOfWeek= lineartime2weekday( l ); tc.wNth = ( day-1 ) / DaysPerWk + 1; if (tc.wNth==4) { // the last one within month ? d= day + DaysPerWk; AdjustDay( d, tc.wMonth, y ); if ( d==day ) tc.wNth= 5; } // if */ return true; } // Fill_tChange // Get int value as string static string IntStr( sInt32 i ) { const int FLen= 15; /* max length of (internal) item name */ char f[ FLen ]; // cheating: this printf format assumes that sInt32 == int sprintf ( f, "%d", int(i) ); string s= f; return s; } // IntStr bool GetTZ( string std, string dst, int bias, int biasDST, tz_entry &t, GZones* g ) { t.name = ""; t.bias = bias; t.biasDST= biasDST; t.ident = ""; t.dynYear= ""; sInt16 y; bool ok= Fill_tChange( std, bias,biasDST, t.std, y, false ) && Fill_tChange( dst, bias,biasDST, t.dst, y, true ); if (ok) t.dynYear= IntStr( y ); //printf( "tS m=%d dw=%d n=%d H=%d M=%d\n", t.std.wMonth, t.std.wDayOfWeek, t.std.wNth, // t.std.wHour, t.std.wMinute ); //printf( "tD m=%d dw=%d n=%d H=%d M=%d\n", t.dst.wMonth, t.dst.wDayOfWeek, t.dst.wNth, // t.dst.wHour, t.dst.wMinute ); //printf( "t bs=%d bd=%d\n", t.bias, t.biasDST ); // //printf( "ok=%d y=%d dyn='%s'\n", ok, y, t.dynYear.c_str() ); return ok; } // GetTZ static bool Same_tChange( const tChange &tCh1, const tChange &tCh2 ) { return tCh1.wMonth ==tCh2.wMonth && tCh1.wDayOfWeek==tCh2.wDayOfWeek && tCh1.wNth ==tCh2.wNth && tCh1.wHour ==tCh2.wHour && tCh1.wMinute ==tCh2.wMinute; } // Same_tChange /*! Compare time zone information */ static bool tzcmp( const tz_entry &t, const tz_entry &tzi, bool olsonSupport ) { bool sameName= !tzi.name.empty() && strucmp( tzi.name.c_str(), t.name.c_str() )==0; bool sameLoc = false; // by default, no olson support here //#ifdef ANDROID -- if (olsonSupport) { // allow olson names as well here sameLoc= !tzi.location.empty() && strucmp( tzi.location.c_str(), t.name.c_str() )==0; //__android_log_print( ANDROID_LOG_DEBUG, "TZ CMP", "'%s' == '%s' / '%s'\n", // t.name.c_str(), tzi.name.c_str(), tzi.location.c_str() ); } //#endif -- //printf( "name='%s' loc='%s' ident='%s' sameName=%d sameLoc=%d\n", // t.name.c_str(), t.ident.c_str(), tzi.location.c_str(), sameName, sameLoc ); if (!t.name.empty() && !sameName && !sameLoc) return false; bool idN= t.ident.empty(); if (!idN && t.ident == "?" && (sameName || sameLoc)) return true; if (!idN && t.ident == "$" && t.ident == tzi.ident && (sameName || sameLoc)) return true; /* PNCDEBUGPRINTFX( DBG_SESSION,( "tS m=%d dw=%d n=%d h=%d M=%d\n", t.std.wMonth, t.std.wDayOfWeek, t.std.wNth, t.std.wHour, t.std.wMinute ) ); PNCDEBUGPRINTFX( DBG_SESSION,( "tD m=%d dw=%d n=%d h=%d M=%d\n", t.dst.wMonth, t.dst.wDayOfWeek, t.dst.wNth, t.dst.wHour, t.dst.wMinute ) ); PNCDEBUGPRINTFX( DBG_SESSION,( "tziS m=%d dw=%d n=%d h=%d M=%d\n", tzi.std.wMonth, tzi.std.wDayOfWeek, tzi.std.wNth, tzi.std.wHour, tzi.std.wMinute ) ); PNCDEBUGPRINTFX( DBG_SESSION,( "tziD m=%d dw=%d n=%d h=%d M=%d\n", tzi.dst.wMonth, tzi.dst.wDayOfWeek, tzi.dst.wNth, tzi.dst.wHour, tzi.dst.wMinute ) ); PNCDEBUGPRINTFX( DBG_SESSION,( "t bs=%d bd=%d\n", t.bias, t.biasDST ) ); PNCDEBUGPRINTFX( DBG_SESSION,( "tzi bs=%d bd=%d\n", tzi.bias, tzi.biasDST ) ); */ if (t.bias!=tzi.bias) return false; // bias must be identical if (t.ident == "o") { // stop comparing, return result of last check return t.biasDST == tzi.biasDST; } bool tIsDst= DSTCond( t ); bool tziIsDst= DSTCond( tzi ); if (tIsDst!=tziIsDst) return false; // DST cond must be on or off for both if (tIsDst) { //if (memcmp(&t.dst, &tzi.dst, sizeof(t.dst))!=0 || // memcmp(&t.std, &tzi.std, sizeof(t.std))!=0 || if (!Same_tChange( t.dst, tzi.dst ) || !Same_tChange( t.std, tzi.std ) || t.biasDST!=tzi.biasDST) return false; } // if return !(tzi.ident=="-") && // not removed ( idN || t.ident.empty() || t.ident == tzi.ident ); /* return memcmp(&t.dst, &tzi.dst, sizeof(t.dst))==0 && memcmp(&t.std, &tzi.std, sizeof(t.std))==0 && t.bias ==tzi.bias && t.biasDST==tzi.biasDST && //%%% luz: this must be compared as well strcmp( "-", tzi.ident )!=0 && // removed ( idN || strcmp( t.ident, "" )==0 || strcmp( t.ident, tzi.ident )==0 ); */ } // tzcmp sInt16 MyYear( GZones* g ) { sInt16 y, m, d; lineartime_t t= getSystemNowAs( TCTX_UTC, g, true ); lineartime2date( t, &y,&m,&d ); return y; } // MyYear static bool YearFit( const tz_entry &t, const tz_entry &tzi, GZones* g ) { int yearS; if (t.dynYear == "CUR") yearS= MyYear( g ); else yearS= atoi( t.dynYear.c_str() ); if (yearS==0) return true; int yearI= atoi( tzi.dynYear.c_str() ); if (yearI==0) return true; if (tzi.groupEnd) return yearS>=yearI; else return yearS<=yearI; } // YearFit /* Returns true, if the given TZ is existing already * tz_entry to search for: * If == "" search for any entry with these values. * != "" name must fit * If == "" search for any entry with these values * != "" name must fit * is of the found record * is the assigned context * create an entry, if not yet existing / default: false * says, where to start searching / default: at the beginning * * supported values: * "" any (to search) * "?" name only (to search) * "o" compare offsets, but not changes (to search); name is compared if set * * "x" unknown/system * "m" military zones * "s" standard zones * "d" daylight zones * "-" removed zones * "$" not converted zones (pure text) * " " all others */ bool FoundTZ( const tz_entry &tc, string &aName, timecontext_t &aContext, GZones* g, bool createIt, timecontext_t searchOffset, bool olsonSupport ) { aName = ""; aContext = TCTX_UNKNOWN; int offs = TCTX_OFFSCONTEXT( searchOffset ); bool ok = false; tz_entry t = tc; if (!t.ident.empty() && // specific items will not contain more info !(t.ident==" ")) { ClrDST ( t ); } // if int i; // search hard coded elements first for (i= offs+1; i<(int)tctx_numtimezones; i++) { const tz_entry &tzi = tz[ i ]; if (tzcmp ( t, tzi, olsonSupport ) && YearFit( t, tzi, g )) { aName= tzi.name; //printf( "name='%s' i=%d\n", aName.c_str(), i ); ok = true; break; } // if } // for //printf( "ok=%d name='%s' i=%d olson=%d\n", ok, aName.c_str(), i, olsonSupport ); // don't go thru the mutex, if not really needed if (!ok && g!=NULL) { // ------------------------------------------- //if (g==NULL) g= gz(); #ifdef MUTEX_SUPPORT lockMutex( g->muP ); #endif TZList::iterator pos; int j= offs-(int)tctx_numtimezones; // remaining gap to be skipped // Search for all not removed elements first for (pos= g->tzP.begin(); pos!=g->tzP.end(); pos++) { if (j<0 && !(pos->ident=="-") && // element must not be removed tzcmp( t, *pos, olsonSupport )) { aName= pos->name; ok = true; break; } // if i++; j--; } // for // now check, if an already removed element can be reactivated if (createIt && !ok) { i= (int)tctx_numtimezones; j= offs-(int)tctx_numtimezones; // remaining gap to be skipped for (pos= g->tzP.begin(); pos!=g->tzP.end(); pos++) { if (j<0 && pos->ident == "-" && // removed element ? tzcmp( t, *pos, olsonSupport )) { pos->ident= t.ident; // reactivate the identifier aName = pos->name; // should be the same ok = true; break; } // if i++; j--; } // for } // if // no such element => must be created if (createIt && !ok) { // create it, if not yet ok g->tzP.push_back( t ); ok= true; } // if #ifdef MUTEX_SUPPORT unlockMutex( g->muP ); #endif // ------------------------------------------- } // if if (ok) aContext= TCTX_ENUMCONTEXT( i ); return aContext!=TCTX_UNKNOWN; } /* FoundTZ */ /* Remove a time zone definition, if already existing * NOTE: Currently only dynamic entries can be removed */ bool RemoveTZ( const tz_entry &t, GZones* g ) { //printf( "RemoveTZ '%s' %d\n", t.name, t.bias ); bool ok= false; // --------------------------- if (g==NULL) return ok; //if (g==NULL) g= gz(); #ifdef MUTEX_SUPPORT lockMutex( g->muP ); #endif bool olsonSupport= false; #ifdef ANDROID olsonSupport= true; #endif TZList::iterator pos; for (pos= g->tzP.begin(); pos!=g->tzP.end(); pos++) { if (!(pos->ident=="-") && // element must not be removed tzcmp( t, *pos, olsonSupport )) { pos->ident = "-"; //gz()->tzP.erase( pos ); // do not remove it, keep it persistent ok= true; break; } // if } // for #ifdef MUTEX_SUPPORT unlockMutex( g->muP ); #endif // --------------------------- return ok; } /* RemoveTZ */ bool TimeZoneNameToContext( cAppCharP aName, timecontext_t &aContext, GZones* g, bool olsonSupport ) { // check some special cases if (strucmp(aName,"DATE")==0) { aContext = TCTX_UNKNOWN|TCTX_DATEONLY; return true; } else if (strucmp(aName,"DURATION")==0) { aContext = TCTX_UNKNOWN|TCTX_DURATION; return true; } else if (*aName==0 || strucmp(aName,"FLOATING")==0) { aContext = TCTX_UNKNOWN; return true; } const char* GMT= "GMT"; const char* UTC= "UTC"; int v, n; char* q; tz_entry t; t.name = aName; // prepare searching t.ident = "?"; t.dynYear= ""; // luz: must be initialized! string tName; if (FoundTZ( t, tName, aContext, g, olsonSupport )) return true; /* int i; aContext= TCTX_UNKNOWN; for (i=0; i<(int)tctx_numtimezones; i++) { if (strucmp( tz[i].name,aName )==0) { aContext= TCTX_ENUMCONTEXT(i); break; } } // for if (aContext!=TCTX_UNKNOWN) return true; */ // calculate the UTC offset n= 1; q= (char *)strstr( aName,UTC ); if (q==NULL) q= (char *)strstr( aName,GMT ); if (q!=NULL && strlen( q )>strlen( UTC )) { q+= strlen( UTC ); n= MinsPerHour; } else { q= (char*)aName; } // if v= atoi( q ); if (v!=0 || strcmp( q, "0" )==0 || strcmp( q,"+0" )==0 || strcmp( q,"-0" )==0) { aContext= TCTX_OFFSCONTEXT(v*n); return true; } // if return false; } /* TimeZoneNameToContext */ bool TimeZoneContextToName( timecontext_t aContext, string &aName, GZones* g, cAppCharP aPrefIdent ) { // check some special cases if (!TCTX_IS_TZ( aContext )) { short lBias= TCTX_MINOFFSET( aContext ); aName= "OFFS" + HourMinStr( lBias ); return true; } // if if (TCTX_IS_UNKNOWN(aContext)) { aName = TCTX_IS_DURATION(aContext) ? "DURATION" : (TCTX_IS_DATEONLY(aContext) ? "DATE" : "FLOATING"); return true; } tz_entry t; aName= "UNKNOWN"; #ifdef ANDROID // setting it via param does not work currently for some reasons, switch it on permanently for Android // BUT NOT GENERALLY - IT CHANGES SEMANTICS OF THE WHOLE TIME ZONE NAMING SYSTEM! #warning "%%% overriding passed aPrefIdent argument with constant, forcing olson name output" aPrefIdent= "o"; //__android_log_print( ANDROID_LOG_DEBUG, "ContextToName", "pref='%s' / aContext=%d\n", aPrefIdent, aContext ); #endif // if aPrefIndent contains "o", this means we'd like to see olson name, if possible // %%% for now, we can return olson for the built-ins only if (TCTX_IS_BUILTIN(aContext) && aPrefIdent && strchr(aPrefIdent, 'o')!=NULL) { #ifndef NO_BUILTIN_TZ // look up in hardcoded table cAppCharP oname = tbl_tz[TCTX_TZENUM(aContext)].olsonName; if (oname) { // we have an olson name for this entry, return it aName = oname; return true; } #endif } // %%% has not yet any influence if (GetTZ( aContext, t, g )) { if (t.ident == "$") return false; // unchanged elements are not yet supported aName= t.name; } // if return true; } /* TimeZoneContextToName */ /*! Is it a DST time zone ? (both months must be defined for DST mode) */ bool DSTCond( const tz_entry &t ) { return (t.dst.wMonth!=0 && t.std.wMonth!=0); } // DSTCond /* adjust to day number within month , %% valid till year 2099 */ void AdjustDay( sInt16 &d, sInt16 m, sInt16 y ) { while (d>31) d-= DaysPerWk; if (d>30 && (m==4 || m==6 || m==9 || m==11)) d-= DaysPerWk; if (d>29 && m==2) d-= DaysPerWk; if (d>28 && m==2 && (y % 4)!=0) d-= DaysPerWk; } // AdjustDay /* Get the day where STD <=> DST switch will be done */ static sInt16 DaySwitch( lineartime_t aTime, const tChange* c ) { sInt16 y, m, d, ds; lineartime2date( aTime, &y, &m, &d ); if (c->wDayOfWeek==-1) { ds= c->wNth; } else { sInt16 wkDay= lineartime2weekday( aTime ); ds = ( wkDay + 5*DaysPerWk - ( d-1 ) ) % DaysPerWk; /* wkday of 1st */ ds = ( DaysPerWk - ds + c->wDayOfWeek ) % DaysPerWk + 1; /* 1st occurance */ ds+= ( c->wNth-1 )*DaysPerWk; AdjustDay( ds, c->wMonth, y ); } // if return ds; } // DaySwitch /*! Get lineartime_t of for a given , either from std or vice versa */ lineartime_t DST_Switch( const tz_entry &t, int bias, sInt16 aYear, bool toDST ) { sInt16 ds; const tChange* c; if (toDST) c= &t.dst; else c= &t.std; lineartime_t tim= date2lineartime( aYear, c->wMonth, 1 ); ds= DaySwitch( tim, c ); sInt32 bMins = t.bias; if (!toDST) bMins+= t.biasDST; return date2lineartime( aYear, c->wMonth, ds ) + time2lineartime( c->wHour, c->wMinute, 0,0 ) - seconds2lineartime( bMins*SecsPerMin ); } /* DST_Switch */ /* Check whether of time zone is DST based */ static bool IsDST( lineartime_t aTime, const tz_entry &t ) { bool ok; sInt16 y, m, d, h, min, ds; if (!DSTCond( t )) return false; lineartime2date( aTime, &y, &m, &d ); lineartime2time( aTime, &h, &min, NULL, NULL ); const tChange* c= NULL; if (m==t.std.wMonth) c= &t.std; if (m==t.dst.wMonth) c= &t.dst; /* calculation is a little bit more tricky within the two switching months */ if (c!=NULL) { /* if (c->wDayOfWeek==-1) { ds= c->wNth; } else { sInt16 wkDay= lineartime2weekday( aTime ); ds = ( wkDay + 5*DaysPerWk - (d-1) ) % DaysPerWk; // wkday of 1st ds = ( DaysPerWk - ds + c->wDayOfWeek ) % DaysPerWk + 1; // 1st occurance ds+= ( c->wNth-1 )*DaysPerWk; AdjustDay( ds, m, y ); } // if */ /* is the day when dst<=>std takes place */ ds= DaySwitch( aTime, c ); if (ds < d ) return c==&t.dst; if (ds > d ) return c==&t.std; /* day correct => compare hours */ if (c->wHour < h ) return c==&t.dst; if (c->wHour > h ) return c==&t.std; /* hour correct => compare minutes */ if (c->wMinute< min ) return c==&t.dst; if (c->wMinute> min ) return c==&t.std; /* decide for the margin, if identical */ return c==&t.dst; } /* if */ /* northern and southern hemnisphere supported */ if (t.dst.wMontht.dst.wMonth && mt.dst.wMonth; return ok; } /* IsDST */ static sInt32 DST_Offs( lineartime_t aValue, const tz_entry &t, bool backwards ) { if (backwards) aValue+= (lineartime_t)(t.bias*SecsPerMin)*secondToLinearTimeFactor; if (IsDST( aValue,t )) return t.bias + t.biasDST; else return t.bias; } /* DST_Offs */ /* get offset in minutes */ static bool TimeZoneToOffs( lineartime_t aValue, timecontext_t aContext, bool backwards, sInt32 &offs, GZones* g ) { tz_entry t; if (TCTX_IS_TZ( aContext )) { offs= 0; // default sInt16 year; lineartime2date( aValue, &year, NULL, NULL ); if (GetTZ( aContext, t, g, year )) { if (t.ident == "$") return false; // unchanged elements are not yet supported offs= DST_Offs( aValue, t, backwards ); } // if } else { offs= TCTX_MINOFFSET(aContext); } // if return true; } /* TimeZoneToOffs */ timecontext_t SelectTZ( TDaylightSavingZone zone, int bias, int biasDST, lineartime_t tNow, bool isDbg ) { bool dst, ok; bool withDST= zone!=EDstNone; timecontext_t t= tctx_tz_unknown; bool special= false; // possibly needed true for NGage int i; // go thru the whole list of time zones for (i=(int)tctx_tz_system+1; i<(int)tctx_numtimezones; i++) { bool tCond= DSTCond( tz[ i ] ); // are there any DST rules ? if (tCond==withDST) { if (withDST) dst= IsDST( tNow, tz[ i ] ); // check, if now in DST else dst= false; int b= bias; if (dst && special) b= bias - biasDST; if (tz[ i ].bias==b) { // the bias must fit exactly switch (zone) { case EDstEuropean : case EDstNorthern : ok= tz[ i ].dst.wMonthtz[ i ].std.wMonth; break; default : ok= true; } // switch if (isDbg) { PNCDEBUGPRINTFX( DBG_SESSION,( " %d %d dst=%d cond=%d '%s'", i, bias, dst, tCond, tz[ i ].name.c_str() )); } if (ok) { // check, if european time zone ok= (zone==EDstEuropean) == (tz[ i ].name.find("Europe") != string::npos || tz[ i ].name == "CET/CEST" || tz[ i ].name == "Romance" || tz[ i ].name == "GMT"); if (ok) { t= i; break; } } // if } // if } // if } // for if (isDbg) { PNCDEBUGPRINTFX( DBG_SESSION,( "SelectTZ: zone=%s bias=%d", tz[ t ].name.c_str(), bias ) ); } return TCTX_SYMBOLIC_TZ+t; } // SelectTZ /* get system's time zone */ static bool MyContext( timecontext_t &aContext, GZones* g ) { bool isDbg= false; // check for cached system time zone, return it if available if (g) { isDbg= g->isDbg; // luz: added safety here to avoid that incorrectly initialized GZone // (with tctx_tz_unknown instead of TCTX_UNKNOWN, as it was in timezones.h) // does not cause that system timezone is assumed known (as UTC) and returned WRONG!) // Note: rearranged to make non-locked writing to g->sysTZ is safe (for hacks needed pre-3.1.2.x!) timecontext_t curSysTZ= g->sysTZ; if (!(TCTX_IS_UNKNOWN( curSysTZ ) || TCTX_IS_SYSTEM ( curSysTZ ) )) { aContext= curSysTZ; return true; } } // if // there is no system time zone cached, we need to determine it from the operating system // - call platform specific routine bool ok = getSystemTimeZoneContext( aContext, g ); if (isDbg) { PNCDEBUGPRINTFX( DBG_SESSION, ( "MyContext: %08X ok=%d", aContext, ok )); } // update cached system context if (g && ok) g->sysTZ= aContext; // assign the system context return ok; } /* MyContext */ /* %%% luz 2009-04-02 seems of no relevance except for Symbian/Epoc -> Epoc code moved to Symbian/platform_timezones.cpp added a replacement here as it is still used from sysytest, which should return the same result (but not the debug output */ timecontext_t SystemTZ( GZones *g, bool isDbg ) { timecontext_t tctx; if (MyContext(tctx, g)) return tctx; else return TCTX_UNKNOWN; } bool ContextForEntry( timecontext_t &aContext, tz_entry &t, bool chkNameFirst, GZones* g ) { string s; string sName = t.name; bool ok = true; do { if (chkNameFirst && !sName.empty() && TimeZoneNameToContext( sName.c_str(),aContext, g )) break; // if there are no rules defined => switch it off if (t.dst.wMonth==0 || t.std.wMonth==0 || Same_tChange( t.dst, t.std )) { ClrDST( t ); } // if t.name = (char*)sName.c_str(); t.ident = ""; t.dynYear= ""; // MUST be set as this is assigned unchecked to a string // (which crashes when assigned NULL or low number) if (FoundTZ( t, s, aContext, g )) break; // with this name t.name = ""; t.dynYear= "CUR"; if (FoundTZ( t, s, aContext, g )) break; // with different name int i= 0; if (sName.empty()) sName= "unassigned"; string v; while (true) { v = sName.c_str(); if (i>0) v+= "_" + IntStr( i ); if (!TimeZoneNameToContext( v.c_str(),aContext, g )) break; // A timezone with this name must not exist i++; } // while t.name= (char*)v.c_str(); string tz_Name; FoundTZ( t, tz_Name, aContext, g, true ); // create it if (TimeZoneNameToContext( v.c_str(),aContext, g )) break; ok= false; /* t.name= (char*)sName.c_str(); string tzName; FoundTZ( t, tzName, aContext, g, true ); // create it if (TimeZoneNameToContext( sName.c_str(),aContext, g )) break; ok= false; */ } while (false); return ok; } /* ContextFromNameAndEntry */ /* returns true, if the context rules are identical */ static bool IdenticalRules( timecontext_t aSourceContext, timecontext_t aTargetContext, GZones* g ) { tz_entry ts, tt; /* only performed in TZ mode */ if (!GetTZ( aSourceContext, ts, g, 0 ) || !GetTZ( aTargetContext, tt, g, 0 )) return false; TTimeZones asTZ= TCTX_TZENUM( aSourceContext ); TTimeZones atTZ= TCTX_TZENUM( aTargetContext ); if (asTZ==atTZ) return true; // identical if (ts.ident == "$" || tt.ident == "$") return false; if (ts.bias==tt.bias && // memcmp( &ts.dst, &tt.dst, sizeof(tChange))==0 && // memcmp( &ts.std, &tt.std, sizeof(tChange))==0) return true; Same_tChange( ts.dst, tt.dst ) && Same_tChange( ts.std, tt.std )) return true; /* if (!TCTX_IS_TZ( aSourceContext ) || !TCTX_IS_TZ( aTargetContext )) return false; // get the time zones for calculation TTimeZones asTZ= TCTX_TZENUM(aSourceContext); TTimeZones atTZ= TCTX_TZENUM(aTargetContext); if (asTZ==atTZ) return true; if ( tz[ asTZ ].bias==tz[ atTZ ].bias && memcmp( &tz[ asTZ ].dst, &tz[ atTZ ].dst, sizeof(tChange))==0 && memcmp( &tz[ asTZ ].std, &tz[ atTZ ].std, sizeof(tChange))==0) { return true; } // if */ return false; } /* IdenticalRules */ /*! get system's time zone context (i.e. resolve the TCTX_SYSTEM meta-context) * @param[in,out] aContext : context will be made non-meta, that is, if input is TCTX_SYSTEM, * actual time zone will be determined. */ bool TzResolveMetaContext( timecontext_t &aContext, GZones* g ) { if (!TCTX_IS_SYSTEM(aContext)) return true; // no meta zone, just return unmodified // is meta-context TCTX_SYSTEM, determine actual symbolic context return MyContext(aContext,g); } // TzResolveMetaContext /* make time context non-symbolic (= calculate minute offset east of UTC for aRefTime) */ bool TzResolveContext( timecontext_t &aContext, lineartime_t aRefTime, bool aRefTimeUTC, GZones* g ) { sInt32 offs; // resolve possible meta context (TCTX_SYSTEM at this time) if (!TzResolveMetaContext(aContext,g)) return false; // check if already an offset (non-symbolic) if (!TCTX_IS_TZ(aContext)) return true; // yes, no conversion needed // is symbolic, needs conversion to offset bool ok = TimeZoneToOffs( aRefTime, // reference time for which we want to know the offset aContext, // context aRefTimeUTC, // "backwards" means refTime is UTC and we want know offset to go back to local offs, // here we get the offset g ); if (ok) { aContext = TCTX_JOIN_RFLAGS_TZ( aContext, // join original rendering flags... TCTX_OFFSCONTEXT(offs) // ...with new offset based context ); } return ok; } // TzResolveContext /*! calculate minute offset east of UTC for aRefTime * @param[in] aContext : time context to resolve * @param[out] aMinuteOffset : receives minute offset east of UTC * @param[in] aRefTime : reference time point for resolving the offset * @param[in] aRefTimeUTC : if set, reference time must be UTC, * otherwise, reference time must be in context of aContext */ bool TzResolveToOffset( timecontext_t aContext, sInt16 &aMinuteOffset, lineartime_t aRefTime, bool aRefTimeUTC, GZones* g ) { bool ok = TzResolveContext(aContext, aRefTime, aRefTimeUTC, g); if (ok) { aMinuteOffset = TCTX_MINOFFSET(aContext); } return ok; } // TzResolveToOffset /*! Offset between two contexts (in seconds) * Complex time zones (type "$") can't be currently resolved, they return false * @param[in] aSourceValue : reference time for which the offset should be calculated * @param[in] aSourceContext : source time zone context * @param[in] aTargetContext : source time zone context * @param[out] sDiff : receives offset east of UTC in seconds */ bool TzOffsetSeconds( lineartime_t aSourceValue, timecontext_t aSourceContext, timecontext_t aTargetContext, sInt32 &sDiff, GZones* g, timecontext_t aDefaultContext ) { bool sSys, tSys, sUnk, tUnk; sInt32 sOffs= 0, tOffs= 0; // initialize them for sure lineartime_t aTargetValue; bool ok= true; bool isDbg= false; if (g) isDbg= g->isDbg; // set default context for unknown zones if (TCTX_IS_UNKNOWN(aSourceContext)) aSourceContext=aDefaultContext; if (TCTX_IS_UNKNOWN(aTargetContext)) aTargetContext=aDefaultContext; do { sDiff= 0; if (aSourceContext==aTargetContext) break; /* no conversion, if identical context */ /* both unknown or system is still ok */ if (TCTX_IS_UNKNOWN( aSourceContext ) && TCTX_IS_UNKNOWN( aTargetContext )) break; sSys= TCTX_IS_SYSTEM ( aSourceContext ); tSys= TCTX_IS_SYSTEM ( aTargetContext ); if (sSys && tSys) break; /* calculate specifically for the system's time zone */ if (sSys) MyContext( aSourceContext, g ); if (tSys) MyContext( aTargetContext, g ); /* if both are unknown now, then it's good as well */ sUnk= TCTX_IS_UNKNOWN( aSourceContext ); tUnk= TCTX_IS_UNKNOWN( aTargetContext ); if (sUnk && tUnk) break; /* this case can't be resolved: */ if (sUnk || tUnk) { ok= false; break; } if (IdenticalRules( aSourceContext,aTargetContext, g )) break; /* now do the "hard" things */ if (!TimeZoneToOffs( aSourceValue, aSourceContext, false, sOffs, g )) return false; aTargetValue= aSourceValue - (lineartime_t)(sOffs*SecsPerMin)*secondToLinearTimeFactor; if (!TimeZoneToOffs( aTargetValue, aTargetContext, true, tOffs, g )) return false; sDiff= ( tOffs - sOffs )*SecsPerMin; } while (false); if (isDbg) { PNCDEBUGPRINTFX( DBG_SESSION,( "sSys=%d tSys=%d / sUnk=%d tUnk=%d / sOffs=%d tOffs=%d", sSys,tSys, sUnk,tUnk, sOffs,tOffs )); PNCDEBUGPRINTFX( DBG_SESSION,( "TzOffsetSeconds=%d", sDiff )); } // if return ok; } /* TzOffsetSeconds */ /*! Converts timestamp value from one zone to another * Complex time zones (type "$") can't be currently resolved, they return false * @param[in/out] aValue : will be converted from source context to target context. If==noLinearTime==0, no conversion is done * @param[in] aSourceContext : source time zone context * @param[in] aTargetContext : source time zone context * @param[in] aDefaultContext: default context to use if source or target is TCTX_UNKNOWN */ bool TzConvertTimestamp( lineartime_t &aValue, timecontext_t aSourceContext, timecontext_t aTargetContext, GZones* g, timecontext_t aDefaultContext ) { sInt32 sdiff; if (aValue==noLinearTime) return true; // no time, don't convert bool ok = TzOffsetSeconds( aValue, aSourceContext, aTargetContext, sdiff, g, aDefaultContext ); if (ok) aValue += (lineartime_t)(sdiff)*secondToLinearTimeFactor; return ok; } /* TzConvertTimestamp */ } // namespace sysync /* eof */ libsynthesis-3.4.0.47.1/src/sysync/timezones.h000077500000000000000000000450071226375725500211620ustar00rootroot00000000000000/* * File: timezones.h * * Author: Beat Forster * * Timezones conversion from/to linear time scale. * * Copyright (c) 2004-2011 by Synthesis AG + plan44.ch * * 2004-04-18 : bfo : initial version * */ #ifndef TIMEZONES_H #define TIMEZONES_H #include #include #include #include "lineartime.h" #include "debuglogger.h" #ifdef MUTEX_SUPPORT #include "platform_mutex.h" #endif using namespace std; // for string and list namespace sysync { // include the built-in time zone table #ifndef NO_BUILTIN_TZ #include "tz_table.h" #endif /// time zone table entry definition typedef struct tChangeStruct { short wMonth; short wDayOfWeek; short wNth; // nth occurance short wHour; short wMinute; tChangeStruct() : wMonth(0), wDayOfWeek(0), wNth(0), wHour(0), wMinute(0) {} tChangeStruct(short aMonth, short aDayOfWeek, short aNth, short aHour, short aMinute) : wMonth(aMonth), wDayOfWeek(aDayOfWeek), wNth(aNth), wHour(aHour), wMinute(aMinute) {} } tChange; class tz_entry { public: std::string name; /**< name, same as TZID in VTIMEZONE, e.g. CET/CEST or /softwarestudio.org/Tzfile/Europe/Berlin; see also dst/stdName */ std::string stdName; /**< optional standard time name, e.g. CEST; must be set if "name" is not a concatenation of standard and daylight name (CET/CEST); the vCalendar 1.0 code relies on that */ std::string dstName; /**< used instead of splitting "name" if (and only if) stdName is set; may be empty in zones without daylight saving */ std::string location; /**< location string as used in Olson TZID, e.g. Europe/Berlin */ short bias; /**< minutes difference to UTC (west negative, east positive */ short biasDST; /**< minutes difference to bias (not UTC!) */ std::string ident; /**< see FoundTZ() */ std::string dynYear; /**< if this time zone rule is assigned to a specific year range */ tChange dst; /**< describes when daylight saving time will become active */ tChange std; /**< describes when standard time will become active */ bool groupEnd; /**< true if the entry which follows this one belongs to a different zone or last entry */ tz_entry() : bias(0), biasDST(0), groupEnd(true) {} tz_entry( const std::string &aName, short aBias, short aBiasDST, const std::string &aIdent, const std::string &aDynYear, const tChange &aDst, const tChange &aStd, bool aGroupEnd ) : name(aName), bias(aBias), biasDST(aBiasDST), ident(aIdent), dynYear(aDynYear), dst(aDst), std(aStd), groupEnd(aGroupEnd) {} }; //const int DST_Bias= 60; // General DST offset (in minutes) // Symbian timezone categories // visible for all other systems as well #ifndef __EPOC_OS__ enum TDaylightSavingZone { EDstHome =0x40000000, EDstNone =0, EDstEuropean=1, EDstNorthern=2, EDstSouthern=4 }; #endif // Offset mask const uInt32 TCTX_OFFSETMASK = 0x0000FFFF; // time context flags // - symbolic zone flag const uInt32 TCTX_SYMBOLIC_TZ= 0x00010000; // - rendering flags const uInt32 TCTX_DATEONLY = 0x00020000; const uInt32 TCTX_TIMEONLY = 0x00040000; const uInt32 TCTX_DURATION = 0x00080000; const uInt32 TCTX_RFLAGMASK = TCTX_DATEONLY+TCTX_TIMEONLY+TCTX_DURATION; //! Get signed minute offset sInt16 TCTX_MINOFFSET( timecontext_t tctx ); //! Get time zone enum TTimeZones TCTX_TZENUM( timecontext_t tctx ); // macro to get time zone context #define TCTX_ENUMCONTEXT( tzenum ) ((timecontext_t) ((tzenum) | TCTX_SYMBOLIC_TZ)) #define TCTX_UNKNOWN TCTX_ENUMCONTEXT( tctx_tz_unknown ) #define TCTX_SYSTEM TCTX_ENUMCONTEXT( tctx_tz_system ) #define TCTX_UTC TCTX_ENUMCONTEXT( tctx_tz_UTC ) #define TCTX_OFFSCONTEXT( offs ) ((timecontext_t)((sInt16)(offs) & TCTX_OFFSETMASK )) /* // macro to get time zone and other flags #define TCTX_IS_TZ( tctx ) ((bool)(tctx & TCTX_SYMBOLIC_TZ)) #define TCTX_IS_DATEONLY( tctx ) ((bool)(tctx & TCTX_DATEONLY )) */ //! Check if is a symbolic TZ info bool TCTX_IS_TZ ( timecontext_t tctx ); // Check if is a built-in symbolic TZ info bool TCTX_IS_BUILTIN ( timecontext_t tctx ); //! Check if has TCTX_DATEONLY mode set bool TCTX_IS_DATEONLY( timecontext_t tctx ); //! Check if has TCTX_TIMEONLY mode set bool TCTX_IS_TIMEONLY( timecontext_t tctx ); //! Check if has TCTX_DURATION mode set bool TCTX_IS_DURATION( timecontext_t tctx ); //! Check if is a unknown time zone bool TCTX_IS_UNKNOWN ( timecontext_t tctx ); //! Check if is the system time zone bool TCTX_IS_SYSTEM ( timecontext_t tctx ); //! Check if is the UTC time zone bool TCTX_IS_UTC ( timecontext_t tctx ); //! result is render flags from with zone info from timecontext_t TCTX_JOIN_RFLAGS_TZ ( timecontext_t aRFlagContext, timecontext_t aZoneContext ); // ---- utility functions ------------------------------------------------------------- /*! Specific bias string. Unit: hours */ string BiasStr( int bias ); /*! Clear the DST info of */ void ClrDST( tz_entry &t ); typedef std::list TZList; class GZones { public: GZones() { #ifdef MUTEX_SUPPORT muP= newMutex(); #endif predefinedSysTZ= TCTX_UNKNOWN; // no predefined system time zone sysTZ= predefinedSysTZ; // default to predefined zone, if none, this will be obtained from OS APIs isDbg= false; // !!! IMPORTANT: do NOT enable this except for test targets, as it leads to recursions (debugPrintf calls time routines!) fSystemZoneDefinitionsFinalized = false; #ifdef SYDEBUG getDbgMask = 0; getDbgLogger= NULL; #endif } // constructor /*! @brief populate GZones with system information * * Sets predefinedSysTZ, sysTZ and adds time zones * to tzP, if that information can be found on the * system. * * Returns false in case of a fatal error. */ bool initialize(); /*! @brief log and/or add more GZones * * Called after config was read and normal debug logging * is possible. */ void loggingStarted(); /*! @brief find a matching time zone * * This returns the best match, with "better" defined as (best * match first): * - exact name AND exact rule set match * - existing entry has a location (currently only the case for * time zones imported from libical) AND that location is part of the * name being searched for AND the rule matches * - as before, but with the rule match * - exact rule set match * * If there are multiple entries which are equally good, the first one * is returned. * * When doing rule matching, the dynYear value of an existing * entry has to match the current year as implemented by the * FitYear() function in timezone.cpp. In most (all?) cases this * has the effect that historic rules are skipped. Likewise, * VTIMEZONE information sent out is based on the current rules * for the zone, regardless of when the event itself takes place. * * This is approach is intentional: it helps avoid mismatches * when historic rules of one zone match the current rules of * another. Furthermore, it helps peers which do rule-based * matching and only know the current rules of each zone. * * @param aTZ entry with rules and name set; ident is ignored * @retval aContext the matching time zone context ID; it always * refers to the tz_entry without a dynYear * @return true if match found */ bool matchTZ(const tz_entry &aTZ, TDebugLogger *aLogP, timecontext_t &aContext); class visitor { public: /** @return true to stop iterating */ virtual bool visit(const tz_entry &aTZ, timecontext_t aContext) = 0; virtual ~visitor() {} // destructor }; /*! @brief invoke visitor once for each time zone * @return true if the visitor returned true */ bool foreachTZ(visitor &v); void ResetCache(void) { sysTZ= predefinedSysTZ; // reset cached system time zone to make sure it is re-evaluated } #ifdef MUTEX_SUPPORT #endif TZList tzP; // the list of additional time zones timecontext_t predefinedSysTZ; // can be set to a specific zone to override zone returned by OS API timecontext_t sysTZ; // the system's time zone, will be calculated, // if set to tctx_tz_unknown bool isDbg; // write debug information bool fSystemZoneDefinitionsFinalized; // finalizeSystemZoneDefinitions() already called #ifdef SYDEBUG uInt32 getDbgMask; // allow debugging in a specific context TDebugLogger* getDbgLogger; #endif }; // GZones // visible for debugging only timecontext_t SystemTZ( GZones *g, bool isDbg= false ); timecontext_t SelectTZ( TDaylightSavingZone zone, int bias, int biasDST, lineartime_t tNow, bool isDbg= false ); // visible for platform_timezones.cpp/.mm bool ContextForEntry( timecontext_t &aContext, tz_entry &t, bool chkNameFirst, GZones* g ); void Get_tChange( lineartime_t tim, tChange &v, sInt16 &y, bool asDate= false ); /*! Get from * or / */ bool GetTZ( timecontext_t aContext, tz_entry &t, GZones* g, int year= 0 ); bool GetTZ( string std, string dst, int bias, int biasDST, tz_entry &t, GZones* g ); /*! Get the current year */ sInt16 MyYear( GZones* g ); /*! Returns true, if the given TZ is existing already * tz_entry to search for: * If == "" search for any entry with these values. * != "" name must fit * If == "" search for any entry with these values * != "" ident must fit * == "?" search for the name only. * * is of the found record * is the assigned context * global list of additional time zones * create an entry, if not yet existing / default: false * says, where to start searching / default: at the beginning */ bool FoundTZ( const tz_entry &t, string &aName, timecontext_t &aContext, GZones* g, bool createIt = false, timecontext_t searchOffset= tctx_tz_unknown, bool olsonSupport= false ); /*! Remove an existing entry * Currently, elements of the hard coded list can't be removed */ bool RemoveTZ( const tz_entry &t, GZones* g ); /*! Is it a DST time zone ? (both months must be defined for DST mode) */ bool DSTCond( const tz_entry &t ); /*! Adjust to day number within month , %% valid till year 2099 */ void AdjustDay( sInt16 &d, sInt16 m, sInt16 y ); /*! Get lineartime_t of for a given , either from std or vice versa */ lineartime_t DST_Switch( const tz_entry &t, int bias, sInt16 aYear, bool toDST ); /*! Convert time zone name into context * @param[in] aName : context name to resolve * @param[out] aContext : context for this aName * @param[in] g : global list of additional time zones * */ bool TimeZoneNameToContext( cAppCharP aName, timecontext_t &aContext, GZones* g, bool olsonSupport= false ); /*! Convert context into time zone name, a preferred name can be given * @param[in] aContext : time context to resolve * @param[out] aName : context name for this aContext * @param[in] g : global list of additional time zones * @param[in] aPrefIdent : preferred name, if more than one is fitting * */ bool TimeZoneContextToName( timecontext_t aContext, string &aName, GZones* g, cAppCharP aPrefIdent= "" ); /*! get system's time zone context (i.e. resolve the TCTX_SYSTEM meta-context) * @param[in,out] aContext : context will be made non-meta, that is, if input is TCTX_SYSTEM, * actual time zone will be determined. * @param[in] g : global list of additional time zones */ bool TzResolveMetaContext( timecontext_t &aContext, GZones* g ); /*! make time context non-symbolic (= calculate minute offset east of UTC for aRefTime) * but retain other time context flags in aContext * @param[in,out] aContext : context will be made non-symbolic, that is resolved to minute offset east of UTC * @param[in] aRefTime : reference time point for resolving the offset * @param[in] aRefTimeUTC : if set, reference time must be UTC, * otherwise, reference time must be in context of aContext * @param[in] g : global list of additional time zones */ bool TzResolveContext( timecontext_t &aContext, lineartime_t aRefTime, bool aRefTimeUTC, GZones* g ); /*! calculate minute offset east of UTC for aRefTime * @param[in] aContext : time context to resolve * @param[out] aMinuteOffset : receives minute offset east of UTC * @param[in] aRefTime : reference time point for resolving the offset * @param[in] aRefTimeUTC : if set, reference time must be UTC, * otherwise, reference time must be in context of aContext * @param[in] g : global list of additional time zones */ bool TzResolveToOffset( timecontext_t aContext, sInt16 &aMinuteOffset, lineartime_t aRefTime, bool aRefTimeUTC, GZones* g ); /*! Offset between two contexts (in seconds) * Complex time zones (type "$") can't be currently resolved, they return false * @param[in] aSourceValue : reference time for which the offset should be calculated * @param[in] aSourceContext : source time zone context * @param[in] aTargetContext : source time zone context * @param[out] sDiff : receives offset east of UTC in seconds * @param[in] g : global list of additional time zones * @param[in] aDefaultContext: default context to use if source or target is TCTX_UNKNOWN */ bool TzOffsetSeconds( lineartime_t aSourceValue, timecontext_t aSourceContext, timecontext_t aTargetContext, sInt32 &sDiff, GZones* g, timecontext_t aDefaultContext= TCTX_UNKNOWN); /*! Converts timestamp value from one zone to another * Complex time zones (type "$") can't be currently resolved, they return false * @param[in/out] aValue : will be converted from source context to target context * @param[in] aSourceContext : source time zone context * @param[in] aTargetContext : source time zone context * @param[in] g : global list of additional time zones * @param[in] aDefaultContext: default context to use if source or target is TCTX_UNKNOWN */ bool TzConvertTimestamp( lineartime_t &aValue, timecontext_t aSourceContext, timecontext_t aTargetContext, GZones* g, timecontext_t aDefaultContext = TCTX_UNKNOWN); /*! Prototypes for platform-specific implementation of time-zone-related routines * which are implemented in platform_time.cpp */ /*! @brief get system real time * @return system's real time in lineartime_t scale, in specified time zone context * @param[in] aTimeContext : desired output time zone * @param[in] g : global list of additional time zones * @param[in] aNoOffset : no offset calculation, if true (to avoid recursive calls) */ lineartime_t getSystemNowAs( timecontext_t aTimeContext, GZones* g, bool aNoOffset= false ); /*! Prototypes for platform-specific implementation of time-zone-related routines * which are implemented in platform_timezones.cpp/.mm */ /*! @brief platform specific loading of time zone definitions * @return true if this list is considered complete (i.e. no built-in zones should be used additionally) * @param[in/out] aGZones : the GZones object where system zones should be loaded into * @note this is called at construction of the SyncAppBase before any logging facilities are * available. This routine should load enough time zone information such that config * can be read and conversion between UTC and system local time is possible. * Use finalizeSystemZoneDefinitions() to add time zones with full logging available. */ bool loadSystemZoneDefinitions( GZones* aGZones ); /*! @brief second opportunity to load platform specific time zone definitions with logging available (and config already parsed) * Called only once per GZones instance. * @param[in/out] aGZones : the GZones object where additional system zones should be loaded into */ void finalizeSystemZoneDefinitions( GZones* aGZones ); /*! @brief get current system time zone * @return true if successful * @param[out] aContext : the time zone context representing the current system time zone. * @param[in] aGZones : the GZones object. */ bool getSystemTimeZoneContext( timecontext_t &aContext, GZones* aGZones ); } // namespace sysync #endif /* eof */ libsynthesis-3.4.0.47.1/src/sysync/tz_table.h000077500000000000000000001441721226375725500207540ustar00rootroot00000000000000/* * File: tz_table.h * * Author: Beat Forster * * Time zone information. * (CURRENTLY NOT) Automatically generated with 'read_tzi' * Conversion date: ??/??/?? * * Copyright (c) 2004-2011 by Synthesis AG + plan44.ch * */ #ifndef TZ_TABLE_H #define TZ_TABLE_H typedef enum { // special time zones tctx_tz_unknown, // 0 tctx_tz_system, // 0 tctx_tz_UTC, // 0 Coordinated Universal Time Europe, will be preferred // list of all Registry time zones tctx_tz_Afghanistan, // 4.5 Kabul tctx_tz_AKST_AKDT, // -9 Alaska tctx_tz_AKST_AKDT_2006, // -9 Alaska tctx_tz_AKST_AKDT_2007, // -9 Alaska tctx_tz_HNY_NAY, // -9 Alaska tctx_tz_HNY_NAY_2006, // -9 Alaska tctx_tz_HNY_NAY_2007, // -9 Alaska tctx_tz_Alaskan, // -9 Alaska tctx_tz_Alaskan_2006, // -9 Alaska tctx_tz_Alaskan_2007, // -9 Alaska tctx_tz_Arab, // 3 Kuwait, Er Riad tctx_tz_Arabian, // 4 Abu Dhabi, Muskat tctx_tz_Arabic, // 3 Bagdad tctx_tz_AST_ADT, // -4 Atlantik (Kanada) tctx_tz_AST_ADT_2006, // -4 Atlantik (Kanada) tctx_tz_AST_ADT_2007, // -4 Atlantik (Kanada) tctx_tz_HNA_HAA, // -4 Atlantik (Kanada) tctx_tz_HNA_HAA_2006, // -4 Atlantik (Kanada) tctx_tz_HNA_HAA_2007, // -4 Atlantik (Kanada) tctx_tz_Atlantic, // -4 Atlantik (Kanada) tctx_tz_Atlantic_2006, // -4 Atlantik (Kanada) tctx_tz_Atlantic_2007, // -4 Atlantik (Kanada) tctx_tz_ART_ARST, // -3 Buenos Aires tctx_tz_ART_ARST_2006, // -3 Buenos Aires tctx_tz_ART_ARST_2007, // -3 Buenos Aires tctx_tz_ART_ARST_2008, // -3 Buenos Aires tctx_tz_ART_ARST_2009, // -3 Buenos Aires tctx_tz_AUS_Central, // 9.5 Darwin tctx_tz_AUS_Eastern, // 10 Canberra, Melbourne, Sydney tctx_tz_Azerbaijan, // 4 Baku tctx_tz_Azores, // -1 Azoren tctx_tz_Canada_Central, // -6 Saskatchewan tctx_tz_Cape_Verde, // -1 Kapverdische Inseln tctx_tz_Caucasus, // 4 Eriwan tctx_tz_ACST_ACDT, // 9.5 Adelaide tctx_tz_Central_Australia, // 9.5 Adelaide tctx_tz_Central_America, // -6 Zentralamerika tctx_tz_Central_Asia, // 6 Astana, Dhaka tctx_tz_Central_Brazilian, // -4 Manaus tctx_tz_Central_Brazilian_2006, // -4 Manaus tctx_tz_Central_Brazilian_2007, // -4 Manaus tctx_tz_CET_CEST, // 1 Belgrad, Bratislava, Budapest, Ljubljana, Prag tctx_tz_MEZ_MESZ, // 1 Belgrad, Bratislava, Budapest, Ljubljana, Prag tctx_tz_Central_Europe, // 1 Belgrad, Bratislava, Budapest, Ljubljana, Prag tctx_tz_Central_European, // 1 Sarajevo, Skopje, Warschau, Zagreb tctx_tz_Central_Pacific, // 11 Magadan, Salomonen, Neukaledonien tctx_tz_CST_CDT, // -6 Chicago, Dallas, Kansas City, Winnipeg tctx_tz_CST_CDT_2006, // -6 Chicago, Dallas, Kansas City, Winnipeg tctx_tz_CST_CDT_2007, // -6 Chicago, Dallas, Kansas City, Winnipeg tctx_tz_HNC_HAC, // -6 Chicago, Dallas, Kansas City, Winnipeg tctx_tz_HNC_HAC_2006, // -6 Chicago, Dallas, Kansas City, Winnipeg tctx_tz_HNC_HAC_2007, // -6 Chicago, Dallas, Kansas City, Winnipeg tctx_tz_Central, // -6 Chicago, Dallas, Kansas City, Winnipeg tctx_tz_Central_2006, // -6 Chicago, Dallas, Kansas City, Winnipeg tctx_tz_Central_2007, // -6 Chicago, Dallas, Kansas City, Winnipeg tctx_tz_Central_Mexico, // -6 Guadalajara, Mexiko-Stadt, Monterrey - neu tctx_tz_China, // 8 Peking, Chongqing, Hongkong, Urumchi tctx_tz_Dateline, // -12 Internationale Datumsgrenze (Westen) tctx_tz_East_Africa, // 3 Nairobi tctx_tz_AEST_AEDT, // 10 Brisbane tctx_tz_East_Australia, // 10 Brisbane tctx_tz_EET_EEST, // 2 Minsk tctx_tz_East_Europe, // 2 Minsk tctx_tz_East_South_America, // -3 Brasilia tctx_tz_East_South_America_2006, // -3 Brasilia tctx_tz_East_South_America_2007, // -3 Brasilia tctx_tz_EST_EDT, // -5 New York, Miami, Atlanta, Detroit, Toronto tctx_tz_EST_EDT_2006, // -5 New York, Miami, Atlanta, Detroit, Toronto tctx_tz_EST_EDT_2007, // -5 New York, Miami, Atlanta, Detroit, Toronto tctx_tz_HNE_HAE, // -5 New York, Miami, Atlanta, Detroit, Toronto tctx_tz_HNE_HAE_2006, // -5 New York, Miami, Atlanta, Detroit, Toronto tctx_tz_HNE_HAE_2007, // -5 New York, Miami, Atlanta, Detroit, Toronto tctx_tz_Eastern, // -5 New York, Miami, Atlanta, Detroit, Toronto tctx_tz_Eastern_2006, // -5 New York, Miami, Atlanta, Detroit, Toronto tctx_tz_Eastern_2007, // -5 New York, Miami, Atlanta, Detroit, Toronto tctx_tz_Egypt, // 2 Kairo tctx_tz_Ekaterinburg, // 5 Jekaterinburg tctx_tz_Fiji, // 12 Fidschi, Kamtschatka, Marshall-Inseln tctx_tz_FLE, // 2 Helsinki, Kiew, Riga, Sofia, Tallinn, Wilna tctx_tz_Georgian, // 3 Tiflis tctx_tz_GMT, // 0 Dublin, Edinburgh, Lissabon, London tctx_tz_Greenland, // -3 Groenland tctx_tz_Greenwich, // 0 Casablanca, Monrovia, Reykjavik tctx_tz_GTB, // 2 Athen, Bukarest, Istanbul tctx_tz_HST_HPT, // -10 Hawaii tctx_tz_HAST_HADT, // -10 Hawaii tctx_tz_Hawaiian, // -10 Hawaii tctx_tz_India, // 5.5 Chennai, Kolkata, Mumbai, Neu-Delhi tctx_tz_Iran, // 3.5 Teheran tctx_tz_Iran_2005, // 3.5 Teheran tctx_tz_Iran_2006, // 3.5 Teheran tctx_tz_Israel, // 2 Jerusalem tctx_tz_Israel_2004, // 2 Jerusalem tctx_tz_Israel_2005, // 2 Jerusalem tctx_tz_Israel_2006, // 2 Jerusalem tctx_tz_Israel_2007, // 2 Jerusalem tctx_tz_Israel_2008, // 2 Jerusalem tctx_tz_Israel_2009, // 2 Jerusalem tctx_tz_Israel_2010, // 2 Jerusalem tctx_tz_Israel_2011, // 2 Jerusalem tctx_tz_Israel_2012, // 2 Jerusalem tctx_tz_Israel_2013, // 2 Jerusalem tctx_tz_Israel_2014, // 2 Jerusalem tctx_tz_Israel_2015, // 2 Jerusalem tctx_tz_Israel_2016, // 2 Jerusalem tctx_tz_Israel_2017, // 2 Jerusalem tctx_tz_Israel_2018, // 2 Jerusalem tctx_tz_Israel_2019, // 2 Jerusalem tctx_tz_Israel_2020, // 2 Jerusalem tctx_tz_Israel_2021, // 2 Jerusalem tctx_tz_Israel_2022, // 2 Jerusalem tctx_tz_Israel_2023, // 2 Jerusalem tctx_tz_Jordan, // 2 Amman tctx_tz_Korea, // 9 Seoul tctx_tz_Mexico, // -6 Guadalajara, Mexiko-Stadt, Monterrey - alt tctx_tz_Mexico_2, // -7 Chihuahua, La Paz, Mazatlan - alt tctx_tz_Mid_Atlantic, // -2 Mittelatlantik tctx_tz_Middle_East, // 2 Beirut tctx_tz_Montevideo, // -3 Montevideo tctx_tz_MST_MDT, // -7 Denver, Salt Lake City, Calgary tctx_tz_MST_MDT_2006, // -7 Denver, Salt Lake City, Calgary tctx_tz_MST_MDT_2007, // -7 Denver, Salt Lake City, Calgary tctx_tz_HNR_HAR, // -7 Denver, Salt Lake City, Calgary tctx_tz_HNR_HAR_2006, // -7 Denver, Salt Lake City, Calgary tctx_tz_HNR_HAR_2007, // -7 Denver, Salt Lake City, Calgary tctx_tz_Mountain, // -7 Denver, Salt Lake City, Calgary tctx_tz_Mountain_2006, // -7 Denver, Salt Lake City, Calgary tctx_tz_Mountain_2007, // -7 Denver, Salt Lake City, Calgary tctx_tz_Mountain_Mexico, // -7 Chihuahua, La Paz, Mazatlan - neu tctx_tz_Myanmar, // 6.5 Yangon (Rangun) tctx_tz_North_Central_Asia, // 6 Almaty, Nowosibirsk tctx_tz_Namibia, // 2 Windhuk tctx_tz_Nepal, // 5.75 Katmandu tctx_tz_New_Zealand, // 12 Auckland, Wellington tctx_tz_NST_NDT, // -3.5 Neufundland tctx_tz_NST_NDT_2006, // -3.5 Neufundland tctx_tz_NST_NDT_2007, // -3.5 Neufundland tctx_tz_HNT_HAT, // -3.5 Neufundland tctx_tz_HNT_HAT_2006, // -3.5 Neufundland tctx_tz_HNT_HAT_2007, // -3.5 Neufundland tctx_tz_Newfoundland, // -3.5 Neufundland tctx_tz_Newfoundland_2006, // -3.5 Neufundland tctx_tz_Newfoundland_2007, // -3.5 Neufundland tctx_tz_North_Asia_East, // 8 Irkutsk, Ulan Bator tctx_tz_North_Asia, // 7 Krasnojarsk tctx_tz_Pacific_SA, // -4 Santiago tctx_tz_PST_PDT, // -8 Pacific (USA, Kanada) tctx_tz_PST_PDT_2006, // -8 Pacific (USA, Kanada) tctx_tz_PST_PDT_2007, // -8 Pacific (USA, Kanada) tctx_tz_HNP_HAP, // -8 Pacific (USA, Kanada) tctx_tz_HNP_HAP_2006, // -8 Pacific (USA, Kanada) tctx_tz_HNP_HAP_2007, // -8 Pacific (USA, Kanada) tctx_tz_Pacific, // -8 Pacific (USA, Kanada) tctx_tz_Pacific_2006, // -8 Pacific (USA, Kanada) tctx_tz_Pacific_2007, // -8 Pacific (USA, Kanada) tctx_tz_Pacific_Mexico, // -8 Tijuana, Niederkalifornien (Mexiko) tctx_tz_Romance, // 1 Bruessel, Kopenhagen, Madrid, Paris tctx_tz_Russian, // 3 Moskau, St. Petersburg, Wolgograd tctx_tz_SA_Eastern, // -3 Buenos Aires, Georgetown (OLD) tctx_tz_SA_Pacific, // -5 Bogota, Lima, Quito, Rio Branco tctx_tz_SA_Western, // -4 Caracas, La Paz tctx_tz_Samoa, // -11 Midway-Inseln, Samoa tctx_tz_SE_Asia, // 7 Bangkok, Hanoi, Jakarta tctx_tz_Singapore, // 8 Kuala Lumpur, Singapur tctx_tz_South_Africa, // 2 Harare, Praetoria tctx_tz_Sri_Lanka, // 5.5 Sri Jayawardenepura tctx_tz_Taipei, // 8 Taipeh tctx_tz_Tasmania, // 10 Hobart tctx_tz_Tokyo, // 9 Osaka, Sapporo, Tokio tctx_tz_Tonga, // 13 Nuku'alofa tctx_tz_US_Eastern, // -5 Indiana (Ost) tctx_tz_US_Mountain, // -7 Arizona tctx_tz_Vladivostok, // 10 Wladiwostok tctx_tz_West_Australia, // 8 Perth tctx_tz_West_Australia_2005, // 8 Perth tctx_tz_West_Australia_2006, // 8 Perth tctx_tz_West_Australia_2007, // 8 Perth tctx_tz_West_Central_Africa, // 1 West-Zentralafrika tctx_tz_WET_WEST, // 1 Amsterdam, Berlin, Bern, Rom, Stockholm, Wien tctx_tz_West_Europe, // 1 Amsterdam, Berlin, Bern, Rom, Stockholm, Wien tctx_tz_West_Asia, // 5 Islamabad, Karatschi, Taschkent tctx_tz_West_Pacific, // 10 Guam, Port Moresby tctx_tz_Yakutsk, // 9 Jakutsk // http://www.timeanddate.com/library/abbreviations/timezones tctx_tz_A, // 1 Alpha Time Zone tctx_tz_ACDT, // 10.5 Australian Central Daylight Time Australia tctx_tz_ACST, // 9.5 Australian Central Standard Time Australia tctx_tz_ADT, // -3 Atlantic Daylight Time North America tctx_tz_AEDT, // 11 Australian Eastern Daylight Time Australia tctx_tz_AEST, // 10 Australian Eastern Standard Time Australia tctx_tz_AKDT, // -8 Alaska Daylight Time North America tctx_tz_AKST, // -9 Alaska Standard Time North America tctx_tz_AST, // -4 Atlantic Standard Time North America tctx_tz_AWST, // 8 Australian Western Standard Time Australia tctx_tz_B, // 2 Bravo Time Zone tctx_tz_BST, // 1 British Summer Time Europe tctx_tz_C, // 3 Charlie Time Zone tctx_tz_CDT, // -5 Central Daylight Time North America tctx_tz_CEST, // 2 Central European Summer Time Europe tctx_tz_CET, // 1 Central European Time Europe tctx_tz_CST, // -6 Central Standard Time North America tctx_tz_CXT, // 7 Christmas Island Time Australia tctx_tz_D, // 4 Delta Time Zone tctx_tz_E, // 5 Echo Time Zone tctx_tz_EDT, // -4 Eastern Daylight Time North America tctx_tz_EEST, // 3 Eastern European Summer Time Europe tctx_tz_EET, // 2 Eastern European Time Europe tctx_tz_EST, // -5 Eastern Standard Time North America tctx_tz_F, // 6 Foxtrot Time Zone tctx_tz_G, // 7 Golf Time Zone tctx_tz_H, // 8 Hotel Time Zone tctx_tz_HAA, // -3 Heure Avancee de l'Atlantique North America tctx_tz_HAC, // -5 Heure Avancee du Centre North America tctx_tz_HADT, // -9 Hawaii-Aleutian Daylight Time North America tctx_tz_HAE, // -4 Heure Avancee de l'Est North America tctx_tz_HAP, // -7 Heure Avancee du Pacifique North America tctx_tz_HAR, // -6 Heure Avancee des Rocheuses North America tctx_tz_HAST, // -10 Hawaii-Aleutian Standard Time North America tctx_tz_HAT, // -1.5 Heure Avancee de Terre-Neuve North America tctx_tz_HAY, // -8 Heure Avancee du Yukon North America tctx_tz_HNA, // -4 Heure Normale de l'Atlantique North America tctx_tz_HNC, // -6 Heure Normale du Centre North America tctx_tz_HNE, // -5 Heure Normale de l'Est North America tctx_tz_HNP, // -8 Heure Normale du Pacifique North America tctx_tz_HNR, // -7 Heure Normale des Rocheuses North America tctx_tz_HNT, // -2.5 Heure Normale de Terre-Neuve North America tctx_tz_HNY, // -9 Heure Normale du Yukon North America tctx_tz_I, // 9 India Time Zone tctx_tz_IST, // 1 Irish Summer Time Europe tctx_tz_K, // 10 Kilo Time Zone tctx_tz_L, // 11 Lima Time Zone tctx_tz_M, // 12 Mike Time Zone tctx_tz_MDT, // -6 Mountain Daylight Time North America tctx_tz_MESZ, // 2 Mitteleuropaeische Sommerzeit Europe tctx_tz_MEZ, // 1 Mitteleuropaeische Zeit Europe tctx_tz_MST, // -7 Mountain Standard Time North America tctx_tz_N, // -1 November Time Zone tctx_tz_NDT, // -1.5 Newfoundland Daylight Time North America tctx_tz_NFT, // 11.5 Norfolk (Island) Time Australia tctx_tz_NST, // -2.5 Newfoundland Standard Time North America tctx_tz_O, // -2 Oscar Time Zone tctx_tz_P, // -3 Papa Time Zone tctx_tz_PDT, // -7 Pacific Daylight Time North America tctx_tz_PST, // -8 Pacific Standard Time North America tctx_tz_Q, // -4 Quebec Time Zone tctx_tz_R, // -5 Romeo Time Zone tctx_tz_S, // -6 Sierra Time Zone tctx_tz_T, // -7 Tango Time Zone tctx_tz_U, // -8 Uniform Time Zone tctx_tz_V, // -9 Victor Time Zone tctx_tz_W, // -10 Whiskey Time Zone tctx_tz_WEST, // 1 Western European Summer Time Europe tctx_tz_WET, // 0 Western European Time Europe tctx_tz_WST, // 8 Western Standard Time Australia tctx_tz_X, // -11 X-ray Time Zone tctx_tz_Y, // -12 Yankee Time Zone tctx_tz_Z, // 0 Zulu Time Zone // size of enum tctx_numtimezones } TTimeZones; #ifdef TIMEZONES_INTERNAL typedef struct { short wMonth; short wDayOfWeek; short wNth; // nth occurance short wHour; short wMinute; } tbl_tChange; typedef struct { const char* name; const char* olsonName; short bias; short biasDST; const char* ident; const char* dynYear; tbl_tChange dst; tbl_tChange std; } tbl_tz_entry; const tbl_tz_entry tbl_tz[tctx_numtimezones] = { { "unknown", NULL, 0, 0, "x", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 0 { "system", NULL, 0, 0, "x", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 0 { "UTC", NULL, 0, 0, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 0 { "Afghanistan", "Asia/Kabul", 270, 0, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 4.5 { "AKST/AKDT", "America/Anchorage", -540, 60, " ", "", { 3, 0,2, 2,0 }, { 11, 0,1, 2,0 } }, // -9 { "AKST/AKDT", "America/Anchorage", -540, 60, " ","2006", { 4, 0,1, 2,0 }, { 10, 0,5, 2,0 } }, // -9 { "AKST/AKDT", "America/Anchorage", -540, 60, " ","2007", { 3, 0,2, 2,0 }, { 11, 0,1, 2,0 } }, // -9 { "HNY/NAY", "America/Anchorage", -540, 60, " ", "", { 3, 0,2, 2,0 }, { 11, 0,1, 2,0 } }, // -9 { "HNY/NAY", "America/Anchorage", -540, 60, " ","2006", { 4, 0,1, 2,0 }, { 10, 0,5, 2,0 } }, // -9 { "HNY/NAY", "America/Anchorage", -540, 60, " ","2007", { 3, 0,2, 2,0 }, { 11, 0,1, 2,0 } }, // -9 { "Alaskan", "America/Anchorage", -540, 60, " ", "", { 3, 0,2, 2,0 }, { 11, 0,1, 2,0 } }, // -9 { "Alaskan", "America/Anchorage", -540, 60, " ","2006", { 4, 0,1, 2,0 }, { 10, 0,5, 2,0 } }, // -9 { "Alaskan", "America/Anchorage", -540, 60, " ","2007", { 3, 0,2, 2,0 }, { 11, 0,1, 2,0 } }, // -9 { "Arab", "Asia/Riyadh", 180, 0, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 3 { "Arabian", "Asia/Dubai", 240, 0, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 4 { "Arabic", "Asia/Baghdad", 180, 60, " ", "", { 4, 0,1, 3,0 }, { 10, 0,1, 4,0 } }, // 3 { "AST/ADT", "America/Halifax", -240, 60, " ", "", { 3, 0,2, 2,0 }, { 11, 0,1, 2,0 } }, // -4 { "AST/ADT", "America/Halifax", -240, 60, " ","2006", { 4, 0,1, 2,0 }, { 10, 0,5, 2,0 } }, // -4 { "AST/ADT", "America/Halifax", -240, 60, " ","2007", { 3, 0,2, 2,0 }, { 11, 0,1, 2,0 } }, // -4 { "HNA/HAA", "America/Halifax", -240, 60, " ", "", { 3, 0,2, 2,0 }, { 11, 0,1, 2,0 } }, // -4 { "HNA/HAA", "America/Halifax", -240, 60, " ","2006", { 4, 0,1, 2,0 }, { 10, 0,5, 2,0 } }, // -4 { "HNA/HAA", "America/Halifax", -240, 60, " ","2007", { 3, 0,2, 2,0 }, { 11, 0,1, 2,0 } }, // -4 { "Atlantic", "America/Halifax", -240, 60, " ", "", { 3, 0,2, 2,0 }, { 11, 0,1, 2,0 } }, // -4 { "Atlantic", "America/Halifax", -240, 60, " ","2006", { 4, 0,1, 2,0 }, { 10, 0,5, 2,0 } }, // -4 { "Atlantic", "America/Halifax", -240, 60, " ","2007", { 3, 0,2, 2,0 }, { 11, 0,1, 2,0 } }, // -4 { "ART/ARST", "America/Buenos_Aires", -180, 60, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -3 { "ART/ARST", "America/Buenos_Aires", -180, 60, " ","2006", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -3 { "ART/ARST", "America/Buenos_Aires", -180, 60, " ","2007", { 12,-1,29,23,59}, { 1,-1,1, 0,0 } }, // -3 { "ART/ARST", "America/Buenos_Aires", -180, 60, " ","2008", { 10, 6,3,23,59}, { 3, 6,3,23,59} }, // -3 { "ART/ARST", "America/Buenos_Aires", -180, 60, " ","2009", { 10, 6,3,23,59}, { 3, 6,2,23,59} }, // -3 { "AUS_Central", "Australia/Darwin", 570, 0, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 9.5 { "AUS_Eastern", "Australia/Sydney", 600, 60, " ", "", { 10, 0,5, 2,0 }, { 3, 0,5, 3,0 } }, // 10 { "Azerbaijan", "Asia/Baku", 240, 60, " ", "", { 3, 0,5, 4,0 }, { 10, 0,5, 5,0 } }, // 4 { "Azores", "Atlantic/Azores", -60, 60, " ", "", { 3, 0,5, 2,0 }, { 10, 0,5, 3,0 } }, // -1 { "Canada_Central", "America/Regina", -360, 0, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -6 { "Cape_Verde", "Atlantic/Cape_Verde", -60, 0, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -1 { "Caucasus", "Asia/Tbilisi", 240, 60, " ", "", { 3, 0,5, 2,0 }, { 10, 0,5, 3,0 } }, // 4 { "ACST/ACDT", "Australia/Adelaide", 570, 60, " ", "", { 10, 0,5, 2,0 }, { 3, 0,5, 3,0 } }, // 9.5 { "Central_Australia", "Australia/Adelaide", 570, 60, " ", "", { 10, 0,5, 2,0 }, { 3, 0,5, 3,0 } }, // 9.5 { "Central_America", "America/Guatemala", -360, 0, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -6 { "Central_Asia", "Asia/Dhaka", 360, 0, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 6 { "Central_Brazilian", "America/Manaus", -240, 60, " ", "", { 11, 0,1, 0,0 }, { 2, 0,5, 0,0 } }, // -4 { "Central_Brazilian", "America/Manaus", -240, 60, " ","2006", { 11, 0,1, 0,0 }, { 2, 0,2, 2,0 } }, // -4 { "Central_Brazilian", "America/Manaus", -240, 60, " ","2007", { 11, 0,1, 0,0 }, { 2, 0,5, 0,0 } }, // -4 { "CET/CEST", "Europe/Zurich", 60, 60, " ", "", { 3, 0,5, 2,0 }, { 10, 0,5, 3,0 } }, // 1 { "MEZ/MESZ", "Europe/Berlin", 60, 60, " ", "", { 3, 0,5, 2,0 }, { 10, 0,5, 3,0 } }, // 1 { "Central_Europe", "Europe/Budapest", 60, 60, " ", "", { 3, 0,5, 2,0 }, { 10, 0,5, 3,0 } }, // 1 { "Central_European", "Europe/Warsaw", 60, 60, " ", "", { 3, 0,5, 2,0 }, { 10, 0,5, 3,0 } }, // 1 { "Central_Pacific", "Pacific/Guadalcanal", 660, 0, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 11 { "CST/CDT", "America/Chicago", -360, 60, " ", "", { 3, 0,2, 2,0 }, { 11, 0,1, 2,0 } }, // -6 { "CST/CDT", "America/Chicago", -360, 60, " ","2006", { 4, 0,1, 2,0 }, { 10, 0,5, 2,0 } }, // -6 { "CST/CDT", "America/Chicago", -360, 60, " ","2007", { 3, 0,2, 2,0 }, { 11, 0,1, 2,0 } }, // -6 { "HNC/HAC", "America/Chicago", -360, 60, " ", "", { 3, 0,2, 2,0 }, { 11, 0,1, 2,0 } }, // -6 { "HNC/HAC", "America/Chicago", -360, 60, " ","2006", { 4, 0,1, 2,0 }, { 10, 0,5, 2,0 } }, // -6 { "HNC/HAC", "America/Chicago", -360, 60, " ","2007", { 3, 0,2, 2,0 }, { 11, 0,1, 2,0 } }, // -6 { "Central", "America/Chicago", -360, 60, " ", "", { 3, 0,2, 2,0 }, { 11, 0,1, 2,0 } }, // -6 { "Central", "America/Chicago", -360, 60, " ","2006", { 4, 0,1, 2,0 }, { 10, 0,5, 2,0 } }, // -6 { "Central", "America/Chicago", -360, 60, " ","2007", { 3, 0,2, 2,0 }, { 11, 0,1, 2,0 } }, // -6 { "Central_Mexico", "America/Mexico_City", -360, 60, " ", "", { 4, 0,1, 2,0 }, { 10, 0,5, 2,0 } }, // -6 { "China", "Asia/Shanghai", 480, 0, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 8 { "Dateline", "Etc/GMT+12", -720, 0, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -12 { "East_Africa", "Africa/Nairobi", 180, 0, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 3 { "AEST/AEDT", "Australia/Brisbane", 600, 0, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 10 { "East_Australia", "Australia/Brisbane", 600, 0, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 10 { "EET/EEST", "Europe/Minsk", 120, 60, " ", "", { 3, 0,5, 2,0 }, { 10, 0,5, 3,0 } }, // 2 { "East_Europe", "Europe/Minsk", 120, 60, " ", "", { 3, 0,5, 2,0 }, { 10, 0,5, 3,0 } }, // 2 { "East_South_America","America/Sao_Paulo", -180, 60, " ", "", { 11, 0,1, 0,0 }, { 2, 0,5, 0,0 } }, // -3 { "East_South_America","America/Sao_Paulo", -180, 60, " ","2006", { 11, 0,1, 0,0 }, { 2, 0,2, 2,0 } }, // -3 { "East_South_America","America/Sao_Paulo", -180, 60, " ","2007", { 11, 0,1, 0,0 }, { 2, 0,5, 0,0 } }, // -3 { "EST/EDT", "America/New_York", -300, 60, " ", "", { 3, 0,2, 2,0 }, { 11, 0,1, 2,0 } }, // -5 { "EST/EDT", "America/New_York", -300, 60, " ","2006", { 4, 0,1, 2,0 }, { 10, 0,5, 2,0 } }, // -5 { "EST/EDT", "America/New_York", -300, 60, " ","2007", { 3, 0,2, 2,0 }, { 11, 0,1, 2,0 } }, // -5 { "HNE/HAE", "America/New_York", -300, 60, " ", "", { 3, 0,2, 2,0 }, { 11, 0,1, 2,0 } }, // -5 { "HNE/HAE", "America/New_York", -300, 60, " ","2006", { 4, 0,1, 2,0 }, { 10, 0,5, 2,0 } }, // -5 { "HNE/HAE", "America/New_York", -300, 60, " ","2007", { 3, 0,2, 2,0 }, { 11, 0,1, 2,0 } }, // -5 { "Eastern", "America/New_York", -300, 60, " ", "", { 3, 0,2, 2,0 }, { 11, 0,1, 2,0 } }, // -5 { "Eastern", "America/New_York", -300, 60, " ","2006", { 4, 0,1, 2,0 }, { 10, 0,5, 2,0 } }, // -5 { "Eastern", "America/New_York", -300, 60, " ","2007", { 3, 0,2, 2,0 }, { 11, 0,1, 2,0 } }, // -5 { "Egypt", "Africa/Cairo", 120, 60, " ", "", { 4, 4,5,23,59 }, { 9, 4,5,23,59 }}, // 2 { "Ekaterinburg", "Asia/Yekaterinburg", 300, 60, " ", "", { 3, 0,5, 2,0 }, { 10, 0,5, 3,0 } }, // 5 { "Fiji", "Pacific/Fiji", 720, 0, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 12 { "FLE", "Europe/Kiev", 120, 60, " ", "", { 3, 0,5, 3,0 }, { 10, 0,5, 4,0 } }, // 2 { "Georgian", "Etc/GMT-3", 180, 0, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 3 { "GMT", "Europe/London", 0, 60, " ", "", { 3, 0,5, 1,0 }, { 10, 0,5, 2,0 } }, // 0 { "Greenland", "America/Godthab", -180, 60, " ", "", { 4, 0,1, 2,0 }, { 10, 0,5, 2,0 } }, // -3 { "Greenwich", "Africa/Casablanca", 0, 0, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 0 { "GTB", "Europe/Istanbul", 120, 60, " ", "", { 3, 0,5, 3,0 }, { 10, 0,5, 4,0 } }, // 2 { "HST/HPT", "Pacific/Honolulu", -600, 0, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -10 { "HAST/HADT", "Pacific/Honolulu", -600, 0, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -10 { "Hawaiian", "Pacific/Honolulu", -600, 0, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -10 { "India", "Asia/Calcutta", 330, 0, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 5.5 { "Iran", "Asia/Tehran", 210, 0, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 3.5 { "Iran", "Asia/Tehran", 210, 60, " ","2005", { 3, 0,1, 2,0 }, { 9, 2,4, 2,0 } }, // 3.5 { "Iran", "Asia/Tehran", 210, 0, " ","2006", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 3.5 { "Israel", "Asia/Jerusalem", 120, 60, " ", "", { 3, 5,5, 2,0 }, { 9, 0,3, 2,0 } }, // 2 { "Israel", "Asia/Jerusalem", 120, 0, " ","2004", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 2 { "Israel", "Asia/Jerusalem", 120, 60, " ","2005", { 4,-1,1, 2,0 }, { 10,-1,9, 2,0 } }, // 2 { "Israel", "Asia/Jerusalem", 120, 60, " ","2006", { 3,-1,31,2,0 }, { 10,-1,1, 2,0 } }, // 2 { "Israel", "Asia/Jerusalem", 120, 60, " ","2007", { 3,-1,30,2,0 }, { 9,-1,16,2,0 } }, // 2 { "Israel", "Asia/Jerusalem", 120, 60, " ","2008", { 3,-1,28,2,0 }, { 10,-1,5, 2,0 } }, // 2 { "Israel", "Asia/Jerusalem", 120, 60, " ","2009", { 3,-1,27,2,0 }, { 9,-1,27,2,0 } }, // 2 { "Israel", "Asia/Jerusalem", 120, 60, " ","2010", { 3,-1,26,2,0 }, { 9,-1,12,2,0 } }, // 2 { "Israel", "Asia/Jerusalem", 120, 60, " ","2011", { 4,-1,1, 2,0 }, { 10,-1,2, 2,0 } }, // 2 { "Israel", "Asia/Jerusalem", 120, 60, " ","2012", { 3,-1,30,2,0 }, { 9,-1,23,2,0 } }, // 2 { "Israel", "Asia/Jerusalem", 120, 60, " ","2013", { 3,-1,29,2,0 }, { 9,-1,8, 2,0 } }, // 2 { "Israel", "Asia/Jerusalem", 120, 60, " ","2014", { 3,-1,28,2,0 }, { 9,-1,28,2,0 } }, // 2 { "Israel", "Asia/Jerusalem", 120, 60, " ","2015", { 3,-1,27,2,0 }, { 9,-1,20,2,0 } }, // 2 { "Israel", "Asia/Jerusalem", 120, 60, " ","2016", { 4,-1,1, 2,0 }, { 10,-1,9, 2,0 } }, // 2 { "Israel", "Asia/Jerusalem", 120, 60, " ","2017", { 3,-1,31,2,0 }, { 9,-1,24,2,0 } }, // 2 { "Israel", "Asia/Jerusalem", 120, 60, " ","2018", { 3,-1,30,2,0 }, { 9,-1,16,2,0 } }, // 2 { "Israel", "Asia/Jerusalem", 120, 60, " ","2019", { 3,-1,29,2,0 }, { 10,-1,6, 2,0 } }, // 2 { "Israel", "Asia/Jerusalem", 120, 60, " ","2020", { 3,-1,27,2,0 }, { 9,-1,27,2,0 } }, // 2 { "Israel", "Asia/Jerusalem", 120, 60, " ","2021", { 3,-1,26,2,0 }, { 9,-1,12,2,0 } }, // 2 { "Israel", "Asia/Jerusalem", 120, 60, " ","2022", { 4,-1,1, 2,0 }, { 10,-1,2, 2,0 } }, // 2 { "Israel", "Asia/Jerusalem", 120, 0, " ","2023", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 2 { "Jordan", "Asia/Amman", 120, 60, " ", "", { 3, 4,5, 0,0 }, { 9, 5,5, 1,0 } }, // 2 { "Korea", "Asia/Seoul", 540, 0, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 9 { "Mexico", "America/Mexico_City", -360, 60, " ", "", { 4, 0,1, 2,0 }, { 10, 0,5, 2,0 } }, // -6 { "Mexico_2", "America/Chihuahua", -420, 60, " ", "", { 4, 0,1, 2,0 }, { 10, 0,5, 2,0 } }, // -7 { "Mid_Atlantic", "Atlantic/South_Georgia", -120, 60, " ", "", { 3, 0,5, 2,0 }, { 9, 0,5, 2,0 } }, // -2 { "Middle_East", "Asia/Beirut", 120, 60, " ", "", { 3, 0,5, 0,0 }, { 10, 6,5,23,59 }}, // 2 { "Montevideo", "America/Montevideo", -180, 60, " ", "", { 10, 0,1, 2,0 }, { 3, 0,2, 2,0 } }, // -3 { "MST/MDT", "America/Denver", -420, 60, " ", "", { 3, 0,2, 2,0 }, { 11, 0,1, 2,0 } }, // -7 { "MST/MDT", "America/Denver", -420, 60, " ","2006", { 4, 0,1, 2,0 }, { 10, 0,5, 2,0 } }, // -7 { "MST/MDT", "America/Denver", -420, 60, " ","2007", { 3, 0,2, 2,0 }, { 11, 0,1, 2,0 } }, // -7 { "HNR/HAR", "America/Denver", -420, 60, " ", "", { 3, 0,2, 2,0 }, { 11, 0,1, 2,0 } }, // -7 { "HNR/HAR", "America/Denver", -420, 60, " ","2006", { 4, 0,1, 2,0 }, { 10, 0,5, 2,0 } }, // -7 { "HNR/HAR", "America/Denver", -420, 60, " ","2007", { 3, 0,2, 2,0 }, { 11, 0,1, 2,0 } }, // -7 { "Mountain", "America/Denver", -420, 60, " ", "", { 3, 0,2, 2,0 }, { 11, 0,1, 2,0 } }, // -7 { "Mountain", "America/Denver", -420, 60, " ","2006", { 4, 0,1, 2,0 }, { 10, 0,5, 2,0 } }, // -7 { "Mountain", "America/Denver", -420, 60, " ","2007", { 3, 0,2, 2,0 }, { 11, 0,1, 2,0 } }, // -7 { "Mountain_Mexico", "America/Chihuahua", -420, 60, " ", "", { 4, 0,1, 2,0 }, { 10, 0,5, 2,0 } }, // -7 { "Myanmar", "Asia/Rangoon", 390, 0, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 6.5 { "North_Central_Asia","Asia/Novosibirsk", 360, 60, " ", "", { 3, 0,5, 2,0 }, { 10, 0,5, 3,0 } }, // 6 { "Namibia", "Africa/Windhoek", 120,-60, " ", "", { 4, 0,1, 2,0 }, { 9, 0,1, 2,0 } }, // 2 { "Nepal", "Asia/Katmandu", 345, 0, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 5.75 { "New_Zealand", "Pacific/Auckland", 720, 60, " ", "", { 10, 0,1, 2,0 }, { 3, 0,3, 3,0 } }, // 12 { "NST/NDT", "America/St_Johns", -210, 60, " ", "", { 3, 0,2, 0,1 }, { 11, 0,1, 0,1 } }, // -3.5 { "NST/NDT", "America/St_Johns", -210, 60, " ","2006", { 4, 0,1, 0,1 }, { 10, 0,5, 0,0 } }, // -3.5 { "NST/NDT", "America/St_Johns", -210, 60, " ","2007", { 3, 0,2, 0,1 }, { 11, 0,1, 0,0 } }, // -3.5 { "HNT/HAT", "America/St_Johns", -210, 60, " ", "", { 3, 0,2, 0,1 }, { 11, 0,1, 0,1 } }, // -3.5 { "HNT/HAT", "America/St_Johns", -210, 60, " ","2006", { 4, 0,1, 0,1 }, { 10, 0,5, 0,0 } }, // -3.5 { "HNT/HAT", "America/St_Johns", -210, 60, " ","2007", { 3, 0,2, 0,1 }, { 11, 0,1, 0,0 } }, // -3.5 { "Newfoundland", "America/St_Johns", -210, 60, " ", "", { 3, 0,2, 0,1 }, { 11, 0,1, 0,1 } }, // -3.5 { "Newfoundland", "America/St_Johns", -210, 60, " ","2006", { 4, 0,1, 0,1 }, { 10, 0,5, 0,0 } }, // -3.5 { "Newfoundland", "America/St_Johns", -210, 60, " ","2007", { 3, 0,2, 0,1 }, { 11, 0,1, 0,0 } }, // -3.5 { "North_Asia_East", "Asia/Irkutsk", 480, 60, " ", "", { 3, 0,5, 2,0 }, { 10, 0,5, 3,0 } }, // 8 { "North_Asia", "Asia/Krasnoyarsk", 420, 60, " ", "", { 3, 0,5, 2,0 }, { 10, 0,5, 3,0 } }, // 7 { "Pacific_SA", "America/Santiago", -240, 60, " ", "", { 10, 6,2,23,59 }, { 3, 6,2,23,59 }}, // -4 { "PST/PDT", "America/Los_Angeles", -480, 60, " ", "", { 3, 0,2, 2,0 }, { 11, 0,1, 2,0 } }, // -8 { "PST/PDT", "America/Los_Angeles", -480, 60, " ","2006", { 4, 0,1, 2,0 }, { 10, 0,5, 2,0 } }, // -8 { "PST/PDT", "America/Los_Angeles", -480, 60, " ","2007", { 3, 0,2, 2,0 }, { 11, 0,1, 2,0 } }, // -8 { "HNP/HAP", "America/Los_Angeles", -480, 60, " ", "", { 3, 0,2, 2,0 }, { 11, 0,1, 2,0 } }, // -8 { "HNP/HAP", "America/Los_Angeles", -480, 60, " ","2006", { 4, 0,1, 2,0 }, { 10, 0,5, 2,0 } }, // -8 { "HNP/HAP", "America/Los_Angeles", -480, 60, " ","2007", { 3, 0,2, 2,0 }, { 11, 0,1, 2,0 } }, // -8 { "Pacific", "America/Los_Angeles", -480, 60, " ", "", { 3, 0,2, 2,0 }, { 11, 0,1, 2,0 } }, // -8 { "Pacific", "America/Los_Angeles", -480, 60, " ","2006", { 4, 0,1, 2,0 }, { 10, 0,5, 2,0 } }, // -8 { "Pacific", "America/Los_Angeles", -480, 60, " ","2007", { 3, 0,2, 2,0 }, { 11, 0,1, 2,0 } }, // -8 { "Pacific_Mexico", "America/Tijuana", -480, 60, " ", "", { 4, 0,1, 2,0 }, { 10, 0,5, 2,0 } }, // -8 { "Romance", "Europe/Paris", 60, 60, " ", "", { 3, 0,5, 2,0 }, { 10, 0,5, 3,0 } }, // 1 { "Russian", "Europe/Moscow", 180, 60, " ", "", { 3, 0,5, 2,0 }, { 10, 0,5, 3,0 } }, // 3 { "SA_Eastern", "Etc/GMT+3", -180, 0, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -3 { "SA_Pacific", "America/Bogota", -300, 0, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -5 { "SA_Western", "America/La_Paz", -240, 0, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -4 { "Samoa", "Pacific/Apia", -660, 0, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -11 { "SE_Asia", "Asia/Bangkok", 420, 0, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 7 { "Singapore", "Asia/Singapore", 480, 0, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 8 { "South_Africa", "Africa/Johannesburg", 120, 0, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 2 { "Sri_Lanka", "Asia/Colombo", 330, 0, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 5.5 { "Taipei", "Asia/Taipei", 480, 0, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 8 { "Tasmania", "Australia/Hobart", 600, 60, " ", "", { 10, 0,1, 2,0 }, { 3, 0,5, 3,0 } }, // 10 { "Tokyo", "Asia/Tokyo", 540, 0, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 9 { "Tonga", "Pacific/Tongatapu", 780, 0, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 13 { "US_Eastern", "Etc/GMT+5", -300, 0, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -5 { "US_Mountain", "America/Phoenix", -420, 0, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -7 { "Vladivostok", "Asia/Vladivostok", 600, 60, " ", "", { 3, 0,5, 2,0 }, { 10, 0,5, 3,0 } }, // 10 { "West_Australia", "Australia/Perth", 480, 60, " ", "", { 10, 0,5, 2,0 }, { 3, 0,5, 3,0 } }, // 8 { "West_Australia", "Australia/Perth", 480, 0, " ","2005", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 8 { "West_Australia", "Australia/Perth", 480, 60, " ","2006", { 12,-1,1, 2,0 }, { 1,-1,1, 0,0 } }, // 8 { "West_Australia", "Australia/Perth", 480, 60, " ","2007", { 10, 0,5, 2,0 }, { 3, 0,5, 3,0 } }, // 8 { "West_Central_Africa","Africa/Lagos", 60, 0, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 1 { "WET/WEST", "Europe/Berlin", 60, 60, " ", "", { 3, 0,5, 2,0 }, { 10, 0,5, 3,0 } }, // 1 { "West_Europe", "Europe/Berlin", 60, 60, " ", "", { 3, 0,5, 2,0 }, { 10, 0,5, 3,0 } }, // 1 { "West_Asia", "Asia/Karachi", 300, 0, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 5 { "West_Pacific", "Pacific/Port_Moresby", 600, 0, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 10 { "Yakutsk", "Asia/Yakutsk", 540, 60, " ", "", { 3, 0,5, 2,0 }, { 10, 0,5, 3,0 } }, // 9 { "A", NULL, 60, 0, "m", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 1 { "ACDT", NULL, 630, 0, "d", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 10.5 { "ACST", NULL, 570, 0, "s", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 9.5 { "ADT", NULL, -180, 0, "d", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -3 { "AEDT", NULL, 660, 0, "d", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 11 { "AEST", NULL, 600, 0, "s", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 10 { "AKDT", NULL, -480, 0, "d", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -8 { "AKST", NULL, -540, 0, "s", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -9 { "AST", NULL, -240, 0, "s", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -4 { "AWST", NULL, 480, 0, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 8 { "B", NULL, 120, 0, "m", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 2 { "BST", NULL, 60, 0, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 1 { "C", NULL, 180, 0, "m", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 3 { "CDT", NULL, -300, 0, "d", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -5 { "CEST", NULL, 120, 0, "d", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 2 { "CET", NULL, 60, 0, "s", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 1 { "CST", NULL, -360, 0, "s", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -6 { "CXT", NULL, 420, 0, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 7 { "D", NULL, 240, 0, "m", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 4 { "E", NULL, 300, 0, "m", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 5 { "EDT", NULL, -240, 0, "d", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -4 { "EEST", NULL, 180, 0, "d", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 3 { "EET", NULL, 120, 0, "s", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 2 { "EST", NULL, -300, 0, "s", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -5 { "F", NULL, 360, 0, "m", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 6 { "G", NULL, 420, 0, "m", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 7 { "H", NULL, 480, 0, "m", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 8 { "HAA", NULL, -180, 0, "d", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -3 { "HAC", NULL, -300, 0, "d", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -5 { "HADT", NULL, -540, 0, "d", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -9 { "HAE", NULL, -240, 0, "d", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -4 { "HAP", NULL, -420, 0, "d", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -7 { "HAR", NULL, -360, 0, "d", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -6 { "HAST", NULL, -600, 0, "s", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -10 { "HAT", NULL, -90, 0, "d", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -1.5 { "HAY", NULL, -480, 0, "d", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -8 { "HNA", NULL, -240, 0, "s", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -4 { "HNC", NULL, -360, 0, "s", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -6 { "HNE", NULL, -300, 0, "s", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -5 { "HNP", NULL, -480, 0, "s", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -8 { "HNR", NULL, -420, 0, "s", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -7 { "HNT", NULL, -150, 0, "s", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -2.5 { "HNY", NULL, -540, 0, "s", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -9 { "I", NULL, 540, 0, "m", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 9 { "IST", NULL, 60, 0, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 1 { "K", NULL, 600, 0, "m", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 10 { "L", NULL, 660, 0, "m", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 11 { "M", NULL, 720, 0, "m", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 12 { "MDT", NULL, -360, 0, "d", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -6 { "MESZ", NULL, 120, 0, "d", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 2 { "MEZ", NULL, 60, 0, "s", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 1 { "MST", NULL, -420, 0, "s", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -7 { "N", NULL, -60, 0, "m", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -1 { "NDT", NULL, -90, 0, "d", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -1.5 { "NFT", NULL, 690, 0, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 11.5 { "NST", NULL, -150, 0, "s", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -2.5 { "O", NULL, -120, 0, "m", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -2 { "P", NULL, -180, 0, "m", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -3 { "PDT", NULL, -420, 0, "d", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -7 { "PST", NULL, -480, 0, "s", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -8 { "Q", NULL, -240, 0, "m", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -4 { "R", NULL, -300, 0, "m", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -5 { "S", NULL, -360, 0, "m", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -6 { "T", NULL, -420, 0, "m", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -7 { "U", NULL, -480, 0, "m", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -8 { "V", NULL, -540, 0, "m", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -9 { "W", NULL, -600, 0, "m", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -10 { "WEST", NULL, 60, 0, "d", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 1 { "WET", NULL, 0, 0, "s", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 0 { "WST", NULL, 480, 0, " ", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 8 { "X", NULL, -660, 0, "m", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -11 { "Y", NULL, -720, 0, "m", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // -12 { "Z", NULL, 0, 0, "m", "", { 0, 0,0, 0,0 }, { 0, 0,0, 0,0 } }, // 0 }; #endif // TIMEZONES_INTERNAL #endif // TZ_TABLE_H /* eof */ libsynthesis-3.4.0.47.1/src/sysync/uiapi.cpp000077500000000000000000000062121226375725500206020ustar00rootroot00000000000000/* * File: uiapi.cpp * * Author: Beat Forster (bfo@synthesis.ch) * * TUI_Api class * Bridge to user programmable interface * * Copyright (c) 2007-2011 by Synthesis AG + plan44.ch * */ /* * The "TUI_Api" class acts as a standard interface between * the SySync Server and a (user programmable) module "sync_uiapi". * * It is possible to have more than one (identical) interface module, * either packed into a DLL or directly linked to the server * (or combined). * */ #include "uiapi.h" #include "sync_uiapi.h" namespace sysync { /* ---- "DB_Api_Config" implementation ------------------------------------- */ TUI_Api:: TUI_Api() { fConnected= false; uCreated= false; } // constructor TUI_Api::~TUI_Api() { /* empty */ } // destructor /* Create a context */ TSyError TUI_Api::CreateContext( cAppCharP uiName, TDB_Api_Config &config ) { typedef TSyError (*CreateU_Func)( CContext *uContext, cAppCharP uiName, DB_Callback uCB ); if (uCreated) return DB_Forbidden; uName= uiName; // make a local copy dm= &config.m; // assign reference to the methods CreateU_Func p= (CreateU_Func)dm->ui.UI_CreateContext; DB_Callback uCB= &fCB.Callback; CContext* uc= &uCB->mContext; // store it at a temporary var *uc= 0; // set it to check later, if changed uCB->cContext= config.mContext; // inherit info uContext= 0; uCB->mContext= config.fCB.Callback.mContext; TSyError err= p( &uContext, uName.c_str(), uCB ); if (!err) { uCreated= true; if (*uc==0) *uc= uContext; // assign for datastores, but only if not assigned in plug-in module } // if return err; } // CreateContext // Run the UI API TSyError TUI_Api::RunContext() { if (!uCreated) return DB_Forbidden; Context_Func p= (Context_Func)dm->ui.UI_RunContext; TSyError err= p( uContext ); return err; } // RunContext TSyError TUI_Api::DeleteContext() { if (!uCreated) return DB_Forbidden; Context_Func p= (Context_Func)dm->ui.UI_DeleteContext; TSyError err= p( uContext ); if (!err) uCreated= false; return err; } // DeleteContext // Connect the UI API TSyError TUI_Api::Connect( cAppCharP moduleName, cAppCharP mContextName, bool aIsLib, bool allowDLL ) { m= new TDB_Api_Config; m->fCB= fCB; CContext gContext= 0; TSyError err= m->Connect( moduleName, gContext, mContextName, aIsLib,allowDLL ); if (!err) { err= CreateContext( moduleName, *m ); } // if if (err) delete m; else fConnected= true; printf( "TUI connected err=%d\n", err ); return err; } // Connect // Disconnect the UI API TSyError TUI_Api::Disconnect() { if (!fConnected) return DB_Forbidden; TSyError err= DeleteContext(); if (!err) { err= m->Disconnect(); if (!err) { delete m; fConnected= false; } } // if printf( "TUI disconnected err=%d\n", err ); return err; } // Disconnect } // namespace /* eof */ libsynthesis-3.4.0.47.1/src/sysync/uiapi.h000066400000000000000000000033271226375725500202500ustar00rootroot00000000000000/* * File: uiapi.h * * Author: Beat Forster (bfo@synthesis.ch) * * TUI_Api class * Bridge to user programmable interface * * Copyright (c) 2007-2011 by Synthesis AG + plan44.ch * */ /* * The "TUI_Api" class acts as a standard interface between * the SySync Server and a (user programmable) module "sync_uiapi". * * It is possible to have more than one (identical) interface module, * either packed into a DLL or directly linked to the server * (or combined). * */ #ifndef UI_API_H #define UI_API_H // access to the definitions of the interface #include "sync_dbapidef.h" #include "dbapi.h" namespace sysync { class TUI_Api { public: TUI_Api(); // constructor ~TUI_Api(); // destructor // Connect to the plug-in with TSyError Connect( const char* moduleName, const char* mContextName= "", bool aIsLib= false, bool allowDLL= true ); bool Connected() { return fConnected; } // read status of // Run the UI API TSyError RunContext(); // Disconnect the UI API TSyError Disconnect(); TDB_Api_Callback fCB; // Callback wrapper private: TSyError CreateContext( const char* uiName, TDB_Api_Config &config ); TSyError DeleteContext(); bool fConnected; // if successfully connected to module TDB_Api_Config* m; // the module behind API_Methods* dm; // local reference to the API methods CContext uContext; // The UI context bool uCreated; // if successfully connected to ui context string uName; // local copy of }; // class TUI_Api } // namespace #endif // UI_API_H /* eof */ libsynthesis-3.4.0.47.1/src/sysync/vcalendaritemtype.cpp000077500000000000000000000163131226375725500232160ustar00rootroot00000000000000/* * File: VCalendarItemType.cpp * * Author: Lukas Zeller (luz@plan44.ch) * * TVCalendarItemType * vCalendar item type, based on MIME-DIR Item Type, uses * TMultiFieldItem as data item. * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * 2001-09-25 : luz : created * */ // includes #include "prefix_file.h" #include "sysync.h" #include "vcalendaritemtype.h" #include "rrules.h" using namespace sysync; namespace sysync { /* version info table */ const struct { sInt32 profilemode; const char* typetext; const char* versiontext; } VCalendarVersionInfo[numVCalendarVersions-1] = { // vCalendar 1.0 { PROFILEMODE_OLD, "text/x-vcalendar","1.0" }, // iCalendar 2.0 { PROFILEMODE_MIMEDIR, "text/calendar","2.0" } }; // available vCard versions const char * const vCalendarVersionNames[numVCalendarVersions] = { "1.0", "2.0", "none" }; // VCalendar config // init defaults void TVCalendarTypeConfig::clear(void) { // clear properties fVCalendarVersion=vcalendar_vers_none; // clear inherited inherited::clear(); } // TVCalendarTypeConfig::clear // create Sync Item Type of appropriate type from config TSyncItemType *TVCalendarTypeConfig::newSyncItemType(TSyncSession *aSessionP, TSyncDataStore *aDatastoreP) { return new TVCalendarItemType( aSessionP, this, fTypeName.c_str(), fTypeVersion.c_str(), aDatastoreP, fMIMEProfileP->fFieldListP ); } // TVCalendarTypeConfig::newSyncItemType // resolve (note: needed even if not configurable!) void TVCalendarTypeConfig::localResolve(bool aLastPass) { // pre-set profile mode if a predefined vCard mode is selected if (fVCalendarVersion!=vcalendar_vers_none) { fProfileMode = VCalendarVersionInfo[fVCalendarVersion].profilemode; // also set these, but getTypeName()/getTypeVers() do not use them (but required for syntax check) fTypeName = VCalendarVersionInfo[fVCalendarVersion].typetext; fTypeVersion = VCalendarVersionInfo[fVCalendarVersion].versiontext; } // resolve inherited inherited::localResolve(aLastPass); } // TVCalendarTypeConfig::localResolve #ifdef CONFIGURABLE_TYPE_SUPPORT // config element parsing bool TVCalendarTypeConfig::localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine) { // checking the elements if (strucmp(aElementName,"version")==0) expectEnum(sizeof(fVCalendarVersion),&fVCalendarVersion,vCalendarVersionNames,numVCalendarVersions); else return TMIMEDirTypeConfig::localStartElement(aElementName,aAttributes,aLine); // ok return true; } // TVCalendarTypeConfig::localStartElement #endif /* * Implementation of TVCalendarItemType */ /* public TVCalendarItemType members */ // private helper TVCalendarVersion TVCalendarItemType::getVCalenderVersionByMode(sInt32 aMode) { if (aMode!=PROFILEMODE_DEFAULT) { for (int v=vcalendar_vers_1_0; v0 ? v : 0); #else return 0; // not expired #endif } // TVCalendarItemType::expiryFromData #endif // APP_CAN_EXPIRE #ifdef OBJECT_FILTERING // get field index of given filter expression identifier. sInt16 TVCalendarItemType::getFilterIdentifierFieldIndex(const char *aIdentifier, uInt16 aIndex) { // check if explicit field level identifier if (strucmp(aIdentifier,"F.",2)==0) { // explicit field identifier, skip property lookup return TMultiFieldItemType::getFilterIdentifierFieldIndex(aIdentifier+2,aIndex); } else { // translate SyncML-defined abstracts if (strucmp(aIdentifier,"START")==0) return inherited::getFilterIdentifierFieldIndex("DTSTART",0); else if (strucmp(aIdentifier,"END")==0) return inherited::getFilterIdentifierFieldIndex("DTEND",0); } // simply search for matching property names return inherited::getFilterIdentifierFieldIndex(aIdentifier,aIndex); } // TVCalendarItemType::getFilterIdentifierFieldIndex #endif // helper to create same-typed instance via base class TSyncItemType *TVCalendarItemType::newCopyForSameType( TSyncSession *aSessionP, // the session TSyncDataStore *aDatastoreP // the datastore ) { // create new itemtype of appropriate derived class type that can handle // this type MP_RETURN_NEW(TVCalendarItemType,DBG_OBJINST,"TVCalendarItemType",TVCalendarItemType( aSessionP, fTypeConfigP, getTypeName(), getTypeVers(), aDatastoreP, fFieldDefinitionsP )); } // TVCalendarItemType::newCopyForSameType } // namespace sysync /* end of TVCalendarItemType implementation */ // eof libsynthesis-3.4.0.47.1/src/sysync/vcalendaritemtype.h000077500000000000000000000072071226375725500226650ustar00rootroot00000000000000/* * File: VCalendarItemType.h * * Author: Lukas Zeller (luz@plan44.ch) * * TVCalendarItemType * vCalendar item type, based on MIME-DIR Item Type, uses * TMultiFieldItem as data item. * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * 2001-09-25 : luz : created * */ #ifndef VCalendarItemType_H #define VCalendarItemType_H // includes #include "mimediritemtype.h" using namespace sysync; namespace sysync { // vCalendar variants typedef enum { vcalendar_vers_1_0, vcalendar_vers_2_0, vcalendar_vers_none, numVCalendarVersions } TVCalendarVersion; // Vcalendar based datatype class TVCalendarTypeConfig : public TMIMEDirTypeConfig { typedef TMIMEDirTypeConfig inherited; public: TVCalendarTypeConfig(const char *aElementName, TConfigElement *aParentElementP) : TMIMEDirTypeConfig(aElementName,aParentElementP) {}; // properties TVCalendarVersion fVCalendarVersion; // public functions // - create Sync Item Type of appropriate type from config virtual TSyncItemType *newSyncItemType(TSyncSession *aSessionP, TSyncDataStore *aDatastoreP); protected: #ifdef CONFIGURABLE_TYPE_SUPPORT // check config elements virtual bool localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine); #endif virtual void localResolve(bool aLastPass); virtual void clear(); }; // TVCalendarTypeConfig const uInt16 ity_vcalendar=103; // must be unique class TVCalendarItemType: public TMimeDirItemType { typedef TMimeDirItemType inherited; public: // constructor TVCalendarItemType( TSyncSession *aSessionP, TDataTypeConfig *aTypeConfigP, const char *aCTType, const char *aVerCT, TSyncDataStore *aRelatedDatastoreP, TFieldListConfig *aFieldDefinitions // field definitions ) : TMimeDirItemType( aSessionP, aTypeConfigP, aCTType, aVerCT, aRelatedDatastoreP, aFieldDefinitions ) { fVCalendarVersion = static_cast(aTypeConfigP)->fVCalendarVersion; }; // destructor virtual ~TVCalendarItemType() {}; // access to type virtual uInt16 getTypeID(void) const { return ity_vcalendar; }; virtual bool isBasedOn(uInt16 aItemTypeID) const { return aItemTypeID==ity_vcalendar ? true : TMimeDirItemType::isBasedOn(aItemTypeID); }; // get type name / vers virtual cAppCharP getTypeName(sInt32 aMode=0); virtual cAppCharP getTypeVers(sInt32 aMode=0); // differentiation between implemented and just descriptive TSyncTypeItems virtual bool isImplemented(void) { return true; }; // vCard is an implemented data type // relaxed type comparison, taking into account common errors in real-world implementations virtual bool supportsType(const char *aName, const char *aVers, bool aVersMustMatch=false); // try to extract a version string from actual item data, false if none virtual bool versionFromData(SmlItemPtr_t aItemP, string &aString); #ifdef APP_CAN_EXPIRE // test if modified date of item is expired virtual sInt32 expiryFromData(SmlItemPtr_t aItemP, lineardate_t &aDat); #endif // helper to create same-typed instance via base class // MUST BE IMPLEMENTED IN ALL DERIVED CLASSES! virtual TSyncItemType *newCopyForSameType( TSyncSession *aSessionP, // the session TSyncDataStore *aDatastoreP // the datastore ); #ifdef OBJECT_FILTERING // find field index for filter identifier virtual sInt16 getFilterIdentifierFieldIndex(const char *aIdentifier, uInt16 aIndex); #endif private: TVCalendarVersion getVCalenderVersionByMode(sInt32 aMode); // vCard version TVCalendarVersion fVCalendarVersion; }; // TVCalendarItemType } // namespace sysync #endif // VCalendarItemType_H // eof libsynthesis-3.4.0.47.1/src/sysync/vcarditemtype.cpp000077500000000000000000000174601226375725500223620ustar00rootroot00000000000000/* * File: VCardItemType.cpp * * Author: Lukas Zeller (luz@plan44.ch) * * TVCardItemType * vCard item type, based on MIME-DIR Item Type, uses * TMultiFieldItem as data item. * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * 2001-08-20 : luz : created * */ // includes #include "prefix_file.h" #include "sysync.h" #include "vcarditemtype.h" using namespace sysync; /* version info table */ const struct { sInt32 profilemode; const char* typetext; const char* versiontext; } VCardVersionInfo[numVCardVersions-1] = { // vCard 2.1 { PROFILEMODE_OLD, "text/x-vcard","2.1" }, // vCard 3.0 { PROFILEMODE_MIMEDIR, "text/vcard","3.0" } }; // available vCard versions const char * const vCardVersionNames[numVCardVersions] = { "2.1", "3.0", "none" }; // VCard config // init defaults void TVCardTypeConfig::clear(void) { // clear properties fVCardVersion=vcard_vers_none; // clear inherited inherited::clear(); } // TVCardTypeConfig::clear // create Sync Item Type of appropriate type from config TSyncItemType *TVCardTypeConfig::newSyncItemType(TSyncSession *aSessionP, TSyncDataStore *aDatastoreP) { return new TVCardItemType( aSessionP, this, fTypeName.c_str(), fTypeVersion.c_str(), aDatastoreP, fMIMEProfileP->fFieldListP ); } // TVCardTypeConfig::newSyncItemType // resolve (note: needed even if not configurable!) void TVCardTypeConfig::localResolve(bool aLastPass) { // pre-set profile mode if a predefined vCard mode is selected if (fVCardVersion!=vcard_vers_none) { fProfileMode=VCardVersionInfo[fVCardVersion].profilemode; // also set these, but getTypeName()/getTypeVers() do not use them (but required for syntax check) fTypeName = VCardVersionInfo[fVCardVersion].typetext; fTypeVersion = VCardVersionInfo[fVCardVersion].versiontext; } // resolve inherited inherited::localResolve(aLastPass); } // TVCardTypeConfig::localResolve #ifdef CONFIGURABLE_TYPE_SUPPORT // config element parsing bool TVCardTypeConfig::localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine) { // checking the elements if (strucmp(aElementName,"version")==0) expectEnum(sizeof(fVCardVersion),&fVCardVersion,vCardVersionNames,numVCardVersions); else return TMIMEDirTypeConfig::localStartElement(aElementName,aAttributes,aLine); // ok return true; } // TVCardTypeConfig::localStartElement #endif /* * Implementation of TVCardItemType */ // private helper TVCardVersion TVCardItemType::getVCardVersionByMode(sInt32 aMode) { if (aMode!=PROFILEMODE_DEFAULT) { for (int v=vcard_vers_2_1; v0 ? v : 0); #else return 0; // not expired #endif } // TVCardItemType::expiryFromData #endif // APP_CAN_EXPIRE #ifdef OBJECT_FILTERING // get field index of given filter expression identifier. sInt16 TVCardItemType::getFilterIdentifierFieldIndex(const char *aIdentifier, uInt16 aIndex) { // check if explicit field level identifier if (strucmp(aIdentifier,"F.",2)==0) { // explicit field identifier, skip property lookup return TMultiFieldItemType::getFilterIdentifierFieldIndex(aIdentifier+2,aIndex); } else { // translate SyncML-defined abstracts if (strucmp(aIdentifier,"FAMILY")==0) { TPropertyDefinition *propP = fProfileHandlerP->getProfileDefinition()->getPropertyDef("N"); if (propP) { // value with convdef index 0 is family (last) name if (propP->numValues>0) return propP->convdefs[0].fieldid; } return VARIDX_UNDEFINED; } else if (strucmp(aIdentifier,"GIVEN")==0) { TPropertyDefinition *propP = fProfileHandlerP->getProfileDefinition()->getPropertyDef("N"); if (propP) { // value with convdef index 1 is given (first) name if (propP->numValues>1) return propP->convdefs[1].fieldid; } return VARIDX_UNDEFINED; } else if (strucmp(aIdentifier,"GROUP")==0) { return inherited::getFilterIdentifierFieldIndex("CATEGORIES",0); } } // simply search for matching property names return inherited::getFilterIdentifierFieldIndex(aIdentifier,aIndex); } // TVCardItemType::getFilterIdentifierFieldIndex void TVCardItemType::addFilterCapPropsAndKeywords(SmlPcdataListPtr_t &aFilterKeywords, SmlPcdataListPtr_t &aFilterProps, TTypeVariantDescriptor aVariantDesc) { // add my own properties addPCDataStringToList("GROUP", &aFilterKeywords); // add basics inherited::addFilterCapPropsAndKeywords(aFilterKeywords,aFilterProps,aVariantDesc); } // TVCardItemType::addFilterCapPropsAndKeywords #endif // helper to create same-typed instance via base class TSyncItemType *TVCardItemType::newCopyForSameType( TSyncSession *aSessionP, // the session TSyncDataStore *aDatastoreP // the datastore ) { // create new itemtype of appropriate derived class type that can handle // this type MP_RETURN_NEW(TVCardItemType,DBG_OBJINST,"TVCardItemType",TVCardItemType( aSessionP, fTypeConfigP, getTypeName(), getTypeVers(), aDatastoreP, fFieldDefinitionsP )); } // TVCardItemType::newCopyForSameType /* end of TVCardItemType implementation */ // eof libsynthesis-3.4.0.47.1/src/sysync/vcarditemtype.h000077500000000000000000000074231226375725500220250ustar00rootroot00000000000000/* * File: VCardItemType.h * * Author: Lukas Zeller (luz@plan44.ch) * * TVCardItemType * vCard item type, based on MIME-DIR Item Type, uses * TMultiFieldItem as data item. * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * 2001-08-20 : luz : created * */ #ifndef VCardItemType_H #define VCardItemType_H // includes #include "mimediritemtype.h" using namespace sysync; namespace sysync { // vCard variants typedef enum { vcard_vers_2_1, vcard_vers_3_0, vcard_vers_none, // must be last as version table has no entry for that numVCardVersions } TVCardVersion; // Vcard based datatype class TVCardTypeConfig : public TMIMEDirTypeConfig { typedef TMIMEDirTypeConfig inherited; public: TVCardTypeConfig(const char *aElementName, TConfigElement *aParentElementP) : TMIMEDirTypeConfig(aElementName,aParentElementP) {}; // properties TVCardVersion fVCardVersion; // public functions // - create Sync Item Type of appropriate type from config virtual TSyncItemType *newSyncItemType(TSyncSession *aSessionP, TSyncDataStore *aDatastoreP); protected: #ifdef CONFIGURABLE_TYPE_SUPPORT // check config elements virtual bool localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine); #endif virtual void localResolve(bool aLastPass); virtual void clear(); }; // TVCardTypeConfig const uInt16 ity_vcard=104; // must be unique class TVCardItemType: public TMimeDirItemType { typedef TMimeDirItemType inherited; public: // constructor TVCardItemType( TSyncSession *aSessionP, TDataTypeConfig *aTypeConfigP, const char *aCTType, const char *aVerCT, TSyncDataStore *aRelatedDatastoreP, TFieldListConfig *aFieldDefinitions // field definitions ) : TMimeDirItemType( aSessionP, aTypeConfigP, aCTType, aVerCT, aRelatedDatastoreP, aFieldDefinitions ) { fVCardVersion = static_cast(aTypeConfigP)->fVCardVersion; }; // destructor virtual ~TVCardItemType() {}; // access to type virtual uInt16 getTypeID(void) const { return ity_vcard; }; virtual bool isBasedOn(uInt16 aItemTypeID) const { return aItemTypeID==ity_vcard ? true : TMimeDirItemType::isBasedOn(aItemTypeID); }; // get type name / vers virtual cAppCharP getTypeName(sInt32 aMode=0); virtual cAppCharP getTypeVers(sInt32 aMode=0); // differentiation between implemented and just descriptive TSyncTypeItems virtual bool isImplemented(void) { return true; }; // vCard is an implemented data type // relaxed type comparison, taking into account common errors in real-world implementations virtual bool supportsType(const char *aName, const char *aVers, bool aVersMustMatch=false); // try to extract a version string from actual item data, false if none virtual bool versionFromData(SmlItemPtr_t aItemP, string &aString); #ifdef APP_CAN_EXPIRE // test if modified date of item is expired virtual sInt32 expiryFromData(SmlItemPtr_t aItemP, lineardate_t &aDat); #endif // helper to create same-typed instance via base class // MUST BE IMPLEMENTED IN ALL DERIVED CLASSES! virtual TSyncItemType *newCopyForSameType( TSyncSession *aSessionP, // the session TSyncDataStore *aDatastoreP // the datastore ); #ifdef OBJECT_FILTERING // add extra keywords and property names to filterCap virtual void addFilterCapPropsAndKeywords(SmlPcdataListPtr_t &aFilterKeywords, SmlPcdataListPtr_t &aFilterProps, TTypeVariantDescriptor aVariantDesc); // find field index for filter identifier virtual sInt16 getFilterIdentifierFieldIndex(const char *aIdentifier, uInt16 aIndex); #endif private: TVCardVersion getVCardVersionByMode(sInt32 aMode); // vCard version TVCardVersion fVCardVersion; }; // TVCardItemType } // namespace sysync #endif // VCardItemType_H // eof libsynthesis-3.4.0.47.1/src/sysync/vtimezone.cpp000066400000000000000000001017541226375725500215170ustar00rootroot00000000000000/* * File: vtimezone.cpp * * Author: Beat Forster (bfo@synthesis.ch) * * Parser/Generator routines for vTimezone * * Copyright (c) 2006-2011 by Synthesis AG + plan44.ch * * 2006-03-06 : bfo : created from exctracts from rrules.cpp * */ // includes #include "prefix_file.h" // do not import the whole thing to make life easier for standalone apps #ifdef FULLY_STANDALONE #include "sysync_globs.h" #include "sysync_debug.h" #else #include "sysync.h" #endif #include "vtimezone.h" #include "rrules.h" #include "lineartime.h" #include "timezones.h" #include "iso8601.h" #include "stringutils.h" typedef unsigned long ulong; using namespace sysync; namespace sysync { struct RType { // RRule block definition char freq; char freqmod; sInt16 interval; fieldinteger_t firstmask; fieldinteger_t lastmask; lineartime_t until; }; // RType #ifdef SYSYNC_TOOL /*! Get boolean as const char string */ static cAppCharP Bo( bool b ) { if (b) return "true"; else return "false"; } // Bo #endif /*! Logging RType info */ static void RTypeInfo( RType &r, bool ok, TDebugLogger* aLogP ) { string runt; TimestampToISO8601Str( runt, r.until, TCTX_UTC); // get end time as string #ifdef SYSYNC_TOOL ulong* f1= (ulong*)&r.firstmask; // prepare for longlong disp ulong* f2= f1++; ulong* l1= (ulong*)&r.lastmask; ulong* l2= l1++; LOGDEBUGPRINTFX( aLogP, DBG_GEN,( "RType ok=%s freq=%c freqmod=%c iv=%d", Bo( ok ), r.freq, r.freqmod, r.interval ) ); LOGDEBUGPRINTFX( aLogP, DBG_GEN,( "RType 1st=%08X %08X last=%08X %08X '%s'", *f1,*f2, *l1,*l2, runt.c_str()) ); #endif } // RTypeInfo /*! VTIMEZONE keywords */ const char* VTZ_ID = "TZID"; const char* VTZ_BEGIN = "BEGIN"; const char* VTZ_END = "END"; const char* VTZ_STD = "STANDARD"; const char* VTZ_DST = "DAYLIGHT"; const char* VTZ_RR = "RRULE"; const char* VTZ_START = "DTSTART"; const char* VTZ_OFROM = "TZOFFSETFROM"; const char* VTZ_OTO = "TZOFFSETTO"; const char* VTZ_NAME = "TZNAME"; /*! * escapes newline ('\n'), comma, semicolon and backslash itself with backslash, * according to RFC 2445 "4.3.1 Text" value definition */ static string escapeText(const string &str) { string res; res.reserve(str.size() * 110 / 100); for (size_t i = 0; i < str.size(); i++) { switch (str[i]) { case '\n': res += "\\n"; break; case '\\': case ',': case ';': res += '\\'; // no break! default: res += str[i]; break; } } return res; } /*! * reverses escapeText(); in addition, accepts arbitrary characters * after backslash and replaces them with that character */ static string unescapeText(const string &str) { string res; res.reserve(str.size()); for (size_t i = 0; i < str.size(); i++) { switch (str[i]) { case '\\': i++; if (i < str.size()) { switch (str[i]) { case 'n': res += '\n'; break; default: res += str[i]; break; } } break; default: res += str[i]; break; } } return res; } /*! RRULE2toInternal, using RType * Converts vCalendar 2.0 RRULE string into internal recurrence representation */ static bool RRULE2toInternalR( const char* aText, // RRULE string to be parsed lineartime_t* dtstartP, // reference date for parsing RRULE (might be modified!) RType &r, TDebugLogger* aLogP ) { timecontext_t untilcontext = TCTX_UNKNOWN; bool ok= RRULE2toInternal( aText, *dtstartP, TCTX_UNKNOWN, r.freq,r.freqmod,r.interval,r.firstmask,r.lastmask,r.until,untilcontext, aLogP, dtstartP ); if (aLogP) RTypeInfo( r, ok, aLogP ); return ok; } // RRULE2toInternalR /*! internalToRRULE2, using RType * Converts internal recurrence into vCalendar 2.0 RRULE string */ static bool internalRToRRULE2( string &aString, // receives RRULE string RType r, bool asUTC, TDebugLogger* aLogP ) { bool ok= internalToRRULE2( aString, r.freq,r.freqmod,r.interval,r.firstmask,r.lastmask,r.until, asUTC, aLogP ); #ifdef SYSYNC_TOOL if (aLogP) LOGDEBUGPRINTFX( aLogP, DBG_GEN,( "RType ok=%s aString='%s'", Bo( ok ), aString.c_str() ) ); #endif return ok; } // internalRtoRRULE2 // ---------------------------------------------------------------------------------------- /*! Convert mask values into , */ static void R_to_WD( RType &r, short &aDayOfWeek, short &aNth ) { int i,j; aDayOfWeek= -1; aNth = -1; for (i= 0; i, into tChange */ static void Rtm_to_tChange( RType &r, lineartime_t tim, tChange &c ) { sInt16 mo, da, ho, mi; lineartime2date(tim, NULL, &mo, &da); lineartime2time(tim, &ho, &mi, NULL, NULL); c.wMonth = mo; c.wHour = ho; c.wMinute= mi; R_to_WD( r, c.wDayOfWeek, c.wNth ); if (c.wDayOfWeek==-1) c.wNth= da; } // Rtm_to_tChange // ---------------------------------------------------------------------------------------- /*! Convert , into mask values */ static void WD_to_R( int aDayOfWeek, int aNth, RType &r ) { r.firstmask = 0; // default values r.lastmask = 0; sInt16 index= aDayOfWeek % DaysOfWeek; bool last= aNth==WeeksOfMonth; // 5 is the last week if (last) r.lastmask = (uInt64)1<< index; else r.firstmask= (uInt64)1<<( index + (aNth-1)*DaysOfWeek ); } // WD_to_R static void AdaptDay( lineartime_t &tim, tChange c ) { sInt16 yr, mo, dowk; lineartime2date( tim, &yr ,&mo, NULL ); tim = date2lineartime( yr, mo, 1 ); // make calculation with the 1st of month dowk= lineartime2weekday ( tim ); // get weekday sInt16 da= c.wDayOfWeek - dowk + 1; if (da<1) da+= DaysOfWeek; // this is the 1st occurance of the given weekday da+= (c.wNth-1)*DaysOfWeek; AdjustDay( da,mo,yr ); // and ajust within the month tim= date2lineartime( yr,mo,da ); } // AdaptDay /*! Convert , into tChange */ static void tChange_to_Rtm( tChange c, int year, RType &r, lineartime_t &tim ) { bool noDOW = c.wDayOfWeek==-1; bool noCalc= c.wMonth==0; if (noCalc) c.wMonth= 1; sInt16 da= 1; if (noDOW) da= c.wNth; tim = date2lineartime( year, c.wMonth, da ); lineartime_t timT= time2lineartime( c.wHour, c.wMinute, 0,0 ); if (!(noCalc || noDOW)) { AdaptDay( tim, c ); // get wDayOfWeek/wNth, fitting for WD_to_R ( c.wDayOfWeek, c.wNth, r ); } // if tim+= timT; // don't forget time } // tChange_to_Rtm // ---------------------------------------------------------------------------------------- /*! Get the value from TZOFFSFROM/TZOFFSTO strings */ static bool Get_Bias( string of, string ot, short &bias ) { bool negative= ot.find( "-",0 )==0; bool positive= ot.find( "+",0 )==0; // needed because positive TZOFFSxxx should have it as per specs if (negative || positive) ot= ot.substr( 1,ot.length()-1); string h= ot.substr( 0,2 ); string m= ot.substr( 2,2 ); bias= atoi( h.c_str() )*MinsPerHour + atoi( m.c_str() ); if (negative) bias= -bias; return true; } // Get_Bias /*! Fill in the TZ info. * @return false if some information was found, but couldn't be extracted; * true if not found (in which case c, cBias, cName are unchanged) * or found and extracted */ static bool GetTZInfo( cAppCharP aText, cAppCharP aIdent, tChange &c, short &cBias, string &cName, sInt32 aNth, // take nth occurance, -1: take last TDebugLogger* aLogP ) { RType r; timecontext_t tctx; lineartime_t dtstart, dtH= 0; string a, st; bool success = true; if (aNth==-1) { // search for the last (in time) sInt32 i= 1; while (true) { a= VStr( aText, aIdent, i ); if (a=="") break; st= VValue( a, VTZ_START ); // - start time if (ISO8601StrToTimestamp( st.c_str(), dtstart, tctx )==0) break; if (dtH= aText.size()) { // end of string is okay return hit; } char eol = aText[hit + textlen]; switch (eol) { case '\r': case '\n': // found it return hit; } // keep searching offset = hit + 1; } } else { // normal string search return aText.find(aProperty, aOffset); } } // FindProperty /*! Find last instance of Property inside another string. If the property string ends in \n, then that character matches arbitrary line endings (\r, \n, end of string). If the property does not end in \n, a normal string search is done. */ static string::size_type RfindProperty( const string &aText, const string &aProperty, string::size_type aOffset = string::npos ) { if (!aProperty.empty() && aProperty[aProperty.size()-1] == '\n') { // ignore trailing \n, check for either \r or \n in aText instead string::size_type offset = aOffset; string::size_type textlen = aProperty.size() - 1; while (true) { string::size_type hit = aText.rfind(aProperty.c_str(), offset, textlen); if (hit == string::npos) return string::npos; // prefix match, now must check for line end if (hit + textlen >= aText.size()) { // end of string is okay return hit; } char eol = aText[hit + textlen]; switch (eol) { case '\r': case '\n': // found it return hit; } // keep searching, if possible if (hit == 0) return string::npos; offset = hit - 1; } } else { // normal reversed string search return aText.rfind(aProperty, aOffset); } } // RfindProperty /*! Check, if "BEGIN:value" is available only once */ static int PMulti( string &aText, string value ) { string p= Property( VTZ_BEGIN, value ); string::size_type n; n= FindProperty( aText, p ); if (n==string::npos) return 0; n= FindProperty( aText, p, n+1 ); if (n==string::npos) return 1; /* else */ return 2; } // PMulti /* vTimezones with more than one STANDARD or DAYLIGHT sequence can't be resolved */ static void MultipleSeq( string aText, int &s, int &d ) { s= PMulti( aText,VTZ_STD ); d= PMulti( aText,VTZ_DST ); } // MultipleSeq bool VTIMEZONEtoTZEntry( const char* aText, // VTIMEZONE string to be parsed tz_entry &t, TDebugLogger* aLogP) { short dBias; // the full bias for DST bool success = true; t.name = ""; t.ident = ""; t.dynYear= "CUR"; t.biasDST= 0; t.bias = 0; t.stdName = t.dstName = ""; if (!GetTZInfo( aText,VTZ_STD, t.std, t.bias, t.stdName, -1, aLogP )) { success = false; } // default value if not found (which is treated as success by GetTZInfo) dBias= t.bias; if (!GetTZInfo( aText,VTZ_DST, t.dst, dBias, t.dstName, -1, aLogP )) { // unknown failure, better restore default dBias= t.bias; success = false; } if (t.bias == dBias) ClrDST( t ); // no DST ? else t.biasDST= dBias - t.bias; // t.biasDST WILL be calculated here // get TZID as found in VTIMEZONE t.name = unescapeText( VValue( aText, VTZ_ID ) ); return success; } // VTIMEZONEtoTZEntry /*! Convert VTIMEZONE string ito internal context value */ bool VTIMEZONEtoInternal( const char* aText, // VTIMEZONE string to be parsed timecontext_t &aContext, GZones* g, TDebugLogger* aLogP, string* aTzidP ) ///< if not NULL, receives TZID as found in VTIMEZONE { aContext= tctx_tz_unknown; tz_entry t; string lName; timecontext_t lContext; if (!VTIMEZONEtoTZEntry( aText, t, aLogP )) { PLOGDEBUGPRINTFX(aLogP, DBG_PARSE+DBG_ERROR, ("parsing VTIMEZONE failed:\n%s", aText)); } // Telling the caller about the original TZID is necessary because this // code might match that TZID against an existing definition with a different // TZID. Previously it was also necessary when importing the VTIMEZONE, because // the original TZID was overwritten. Now imported definitions retain the // original TZID in t.name. if (aTzidP) *aTzidP = t.name; // return the original TZID as found, needed to match with TZID occurences in rest of vCalendar bool ok = true; bool okM= true; int s,d; MultipleSeq( aText, s,d ); if (s==0 && d==0) return false; okM= s<=1 && d<=1; // test if more than one section // find best match for VTIMEZONE: checks name and rules // allows multiple timezone, if last is ok ! if (!g) return false; // avoid crashes with g==NULL ok= g->matchTZ(t, aLogP, aContext); if (!ok && !okM) { // store it "as is" if both is not ok ClrDST( t ); t.name = aText; t.ident= "$"; t.bias = 0; return FoundTZ( t, lName, aContext, g, true ); } // if #ifdef SYSYNC_TOOL if (ok) { string existing_name; TimeZoneContextToName(aContext, existing_name, g); LOGDEBUGPRINTFX( aLogP, DBG_PARSE,( "found matching time zone with name='%s' tx=%08X %d", existing_name.c_str(), aContext, TCTX_OFFSCONTEXT( aContext ) ) ); } #endif // if not found, then try again with name and add // the entry; doing a full comparison again is // redundant here, but there is no other way to // add the entry string new_name; if (!ok) ok= FoundTZ( t, new_name, aContext, g, true ); if (ok && t.std.wMonth!=0 && t.dst.wMonth!=0) { tz_entry std; std.name = t.stdName; std.ident= "s"; // standard std.bias = t.bias; FoundTZ( std, lName,lContext, g, true ); tz_entry dst; dst.name = t.dstName; dst.ident= "d"; // daylight saving dst.bias = t.bias + t.biasDST; FoundTZ( dst, lName,lContext, g, true ); } // if return ok; } // VTIMEZONEtoInternal // ----------------------------------------------------------------------------------------- /*! Create a string with in-between BEGIN: .. END: */ static string Encapsuled( string value, string txt ) { return Property( VTZ_BEGIN, value ) + txt + Property( VTZ_END, value ); } // Encapsuled /*! Get the hour/minute string of */ string HourMinStr( int bias ) { const char* form; if (bias>=0) form= "%+03d%02d"; else { form= "-%02d%02d"; bias= -bias; } // for negative values char s[ 10 ]; sprintf( s, form, bias / MinsPerHour, bias % MinsPerHour ); return s; } // HourMinStr /*! Get TZOFFSETFROM/TO strings */ static string FromTo( int biasFrom, int biasTo ) { return Property( VTZ_OFROM, HourMinStr( biasFrom ) ) + Property( VTZ_OTO, HourMinStr( biasTo ) ); } // FromTo /*! Generate a TZ info: * - : the whole tz entry * - : STANDARD/DAYLIGHT * - : "s"/"d" * - : std / dst info * - : staring year * - : bias before changing * - : " after " * - : the debug logger */ static string GenerateTZInfo( tz_entry t, const char* value, const char* aIdent, tChange c, int y, int aFrom, int aTo, GZones *g, TDebugLogger* aLogP ) { string rTxt, dtStart; RType r; lineartime_t tim; string aName; timecontext_t aContext; bool withDST= strcmp( aIdent," " )!=0; r.freq = 'M'; // these are the fixed parameters for TZ r.freqmod = 'W'; r.interval = 12; r.until = noLinearTime; // last day r.firstmask= 0; // default values r.lastmask = 0; tChange_to_Rtm( c,y, r, tim ); TimestampToISO8601Str( dtStart, tim, TCTX_UNKNOWN); // with time, but no offset if (withDST) internalRToRRULE2( rTxt, r, false, aLogP ); t.name = ""; t.ident= aIdent; t.bias = aTo; // this is the bias to search for STD/DST name if (!FoundTZ( t, aName, aContext, g )) aName= ""; string s = Property( VTZ_START, dtStart ); if (withDST) s+= Property( VTZ_RR, rTxt ); s+= FromTo ( aFrom,aTo ); if (withDST && !aName.empty()) s+= Property( VTZ_NAME, escapeText( aName ) ); return Encapsuled( value, s ); } // GenerateTZInfo /*! Convert internal context value into VTIMEZONE */ bool internalToVTIMEZONE( timecontext_t aContext, string &aText, // receives VTIMEZONE string GZones* g, TDebugLogger* aLogP, sInt32 testYear, sInt32 untilYear, cAppCharP aPrefIdent ) { // %%% note: untilYear needs to be implemented, is without functionality so far sInt16 yy= testYear; if (testYear==0) yy= MyYear( g ); TzResolveMetaContext( aContext, g ); // we need actual zone, not meta-context int t_plus= 0; tz_entry t, tp; cAppCharP id; bool withDST= false; bool tzEnum= TCTX_IS_TZ( aContext ); if (tzEnum) { GetTZ( aContext, t, g, yy ); withDST= t.std.wMonth!=0 && t.dst.wMonth!=0; if (t.ident == "$") { aText= t.name; return true; } // just give it back } else { t.bias= TCTX_MINOFFSET( aContext ); //t.name= "OFFS" + HourMinStr( t.bias ); // will be done once at TimeZoneContextToName } t_plus = t.bias; id= " "; if (withDST) { t_plus+= t.biasDST; id= "s"; } // there is only an offset with DST // time zone start year int y_std= 1967; // this info gets lost in the TZ_Entry system int y_dst= 1987; // hard coded, because there is currently no field to store it // modify it, if dyn year is later if (!t.dynYear.empty()) { timecontext_t aDJ= aContext+1; GetTZ ( aDJ, tp, g, -1 ); // but only if not the first entry of dynYear if (t.name == tp.name && t.dynYear != tp.dynYear) { y_std= atoi( t.dynYear.c_str() ); y_dst= y_std; } // if } // if // make sure we get the right TZID string according to aPrefIdent string tzn = t.name; if (aPrefIdent || !tzEnum) { TimeZoneContextToName( aContext, tzn, g, aPrefIdent ); } // at least one STANDARD or DAYLIGHT info is mandatory aText= Property ( VTZ_ID, escapeText( tzn ) ) + GenerateTZInfo( t, VTZ_STD, id, t.std, y_std, t_plus,t.bias, g, aLogP ); if (withDST) aText+= GenerateTZInfo( t, VTZ_DST,"d", t.dst, y_dst, t.bias,t_plus, g, aLogP ); return false; } // internalToVTIMEZONE static bool NextStr( string &s, string &nx ) { string::size_type i= s.find( ";", 0 ); if (i==string::npos ) return false; // mismatch nx= s.substr ( 0, i ); s = s.substr ( i+1, s.length()-i-1 ); return true; } // NextStr /*! Convert TZ/DAYLIGHT string into internal context value */ bool TzDaylightToContext( const char* aText, ///< DAYLIGHT property value to be parsed timecontext_t aStdOffs, ///< Standard (non-DST) offset obtained from TZ timecontext_t &aContext, ///< receives context GZones* g, timecontext_t aPreferredCtx, // preferred context, if rule matches more than one context TDebugLogger* aLog ) { TzResolveMetaContext( aPreferredCtx, g ); // we need actual zone, not meta-context string s= aText; string hrs, dst, std, l, r, rslt; string::size_type i; tz_entry t, tCopy; timecontext_t cc, ccFirst, ccSlash; aContext= aStdOffs; // as default, convert it into a enum TZ string sSv; bool dbg= false; // currently no debugging do { if (s=="FALSE" ) { s= ""; break; } // no DST /* i= s.find( ";", 0 ); // TRUE if (i==string::npos ) return false; // mismatch l= s.substr( 0, i ); */ if (!NextStr( s, l )) return false; // mismatch if (l=="FALSE") { s= ""; break; } // no DST if (!(l=="TRUE" )) return false; // either "TRUE" or "FALSE" if (!NextStr( s, hrs )) return false; // mismatch if (!NextStr( s, dst )) return false; // mismatch if (!NextStr( s, std )) return false; // mismatch int minsDST= MinsPerHour; // %%% not yet perfect for Namibia !! /* i= s.find( ";", 0 ); // +XX i= s.find( ";", i+1 ); // DST time i= s.find( ";", i+1 ); // STD time if (i==string::npos ) return false; // parsing error s= s.substr( i+1, s.length()-i-1 ); */ ISO8601StrToContext( hrs.c_str(), cc ); int mins= TCTX_MINOFFSET( cc )-minsDST; i= s.find ( ";", 0 ); l= s.substr( 0, i ); r= s.substr( i+1, s.length()-i-1 ); if (l==r) s= l; // twice the same => take it once StringSubst( s, ";", "/" ); TimeZoneNameToContext( s.c_str(), aContext, g ); sSv= s; // make a copy for Olson name test later // if it perfectly fits to a named zone, take it if (GetTZ( std,dst, mins,minsDST, t, g )) { ccFirst= TCTX_UNKNOWN; // start with these defaults ccSlash= TCTX_UNKNOWN; cc = TCTX_SYSTEM; if (dbg) printf( "lv1 s='%s' %d pref=%d\n", s.c_str(), aContext, aPreferredCtx ); while (FoundTZ( t, rslt, cc, g, false, cc )) { if (dbg) printf( "lv1 rslt='%s'\n", rslt.c_str() ); if (s==rslt) { aContext= cc; break; } if (s.empty()) { if (ccFirst==TCTX_UNKNOWN) ccFirst= cc; if (ccSlash==TCTX_UNKNOWN) { i= rslt.find( "/",0 ); // a slash TZ would be the best choice if (i!=0 && i!=string::npos) ccSlash= cc; } // if } // if } // while if (ccSlash!=TCTX_UNKNOWN) aContext= ccSlash; else if (ccFirst!=TCTX_UNKNOWN) aContext= ccFirst; } // if } while (false); // check if it fits to bool pUnk = TCTX_IS_UNKNOWN ( aPreferredCtx ); timecontext_t t_Greenwich= TCTX_ENUMCONTEXT( tctx_tz_Greenwich ); ccFirst= TCTX_UNKNOWN; // start with these defaults cc = TCTX_SYSTEM; tCopy= t; // make the copy before if (GetTZ( aContext, t, g )) { if (dbg) printf( "lv2 s='%s' %d\n", s.c_str(), aContext ); if (FoundTZ( t, s, cc, g, false, cc )) { // search by correct name first if (dbg) printf( "lv2 s='%s' / loc='%s'\n", s.c_str(), t.location.c_str() ); if (!(cc!=aPreferredCtx && cc==t_Greenwich)) { // take UTC for this case if (pUnk || cc==aPreferredCtx) { aContext= cc; return true; } if (ccFirst==TCTX_UNKNOWN) ccFirst= cc; // keep it, just in case } // if } // if } else { t.bias = TCTX_MINOFFSET( aContext ); t.biasDST= 0; // no DST offset t.dynYear= ""; ClrDST( t ); tCopy= t; } // if //tCopy= t; tCopy.name = ""; // make more generic comparison tCopy.ident= ""; cc= TCTX_SYSTEM; while (FoundTZ( tCopy, s, cc, g, false, cc )) { if (dbg) printf( "lv3 s='%s' loc='%s' cc=%d\n", s.c_str(), tCopy.location.c_str(), cc ); if (!(cc!=aPreferredCtx && cc==t_Greenwich)) { // take UTC for this case if (pUnk || cc==aPreferredCtx) { ccFirst= cc; break; } if (ccFirst==TCTX_UNKNOWN) ccFirst= cc; // keep it, just in case } // if } // while aContext= ccFirst; bool ok= !TCTX_IS_UNKNOWN( aContext ); if (dbg) printf( "aContext=%d ok=%d\n", aContext, ok ); // if not ok, try to use Olson names if (!ok) { s= sSv; TimeZoneNameToContext( s.c_str(), aContext, g, true ); if (dbg) printf( "lv4 s='%s' aContext=%d\n", s.c_str(), aContext ); ok= !TCTX_IS_UNKNOWN( aContext ); } if (dbg) printf( "aContext=%d ok=%d\n", aContext, ok ); return ok; } // TzDaylightToContext /*! Create DAYLIGHT string from context for a given sample time(year) */ bool ContextToTzDaylight( timecontext_t aContext, lineartime_t aSampleTime, ///< specifies the time after which we search DST string &aText, ///< receives DAYLIGHT string timecontext_t &aStdOffs, ///< receives standard (non-DST) offset for TZ GZones* g, TDebugLogger* aLog ) { //#ifdef RELEASE_VERSION //#error "%%%missing actual implementation - this is just a q&d dummy for testing" //#endif TzResolveMetaContext( aContext, g ); // we need actual zone, not meta-context sInt16 year, month, day; lineartime2date( aSampleTime, &year,&month,&day ); // we need the active year aStdOffs= 0; // default tz_entry t, tCopy; bool found= false; bool dDone= false; bool sDone= false; lineartime_t dt = 0, st = 0; string s; do { bool ok= GetTZ( aContext, t, g ); if (!ok) return false; aStdOffs= TCTX_OFFSCONTEXT( t.bias ); // need this here in case of no DST ok= DSTCond( t ); if (!ok) { aText= "FALSE"; return true; } const int FLen= 15; char f[ FLen ]; sprintf ( f, "%d", year ); string yy= f; t.dynYear= yy.c_str(); // go further only in case of DST available s= t.name; if (s.find( "/",0 )==string::npos) { // search for a time zone with slash in it tCopy= t; tCopy.name = ""; // make more generic comparison tCopy.ident= ""; timecontext_t cc= TCTX_UNKNOWN; while (FoundTZ( tCopy, s, cc, g, false, cc )) { // search for a time zone with slash in it (which is // interpreted as separator between dstName and stdName) *or* // one which has dstName and stdName set explicitly; // prefer explicit names over splitting name tz_entry zone; if (GetTZ( cc, zone, g, -1 ) && !zone.stdName.empty() && !zone.dstName.empty()) { s = zone.stdName + ";" + zone.dstName; found= true; break; } else if (s.find( "/",0 )!=string::npos) { // Assumption here is that s contains exactly one slash, // otherwise s is not valid for stdName;dstName in vCalendar // 1.0. StringSubst( s, "/", ";" ); found= true; break; } // if } // while if (!found) { string stdName; if (t.stdName.empty()) { stdName = t.name; } else { stdName = t.stdName; } s = stdName; // create a ; string s+= ";"; s+= stdName; } // if } else if (!t.stdName.empty() && !t.dstName.empty()) { // use explicit zone names instead of splitting s s = t.stdName + ";" + t.dstName; } else { StringSubst( s, "/", ";" ); } if (!dDone) dt= DST_Switch( t, t.bias, year, true ); // get the switch time/date for DST if (!sDone) st= DST_Switch( t, t.bias, year, false ); // get the switch time/date for STD // search into future,

    ~{n|ž¦âHа„‹0ëÄ ”.Ê)—€ê"™é¤…í&^xy=oœf’9ŒbÞíàÌçuOBfh+¬¦å5 wŒùª¶N`á<ÚèýúžΡê¬ÈGpų{CÕ)*Æ™Ï5y åíåb²Æœ •|¾rã¢í-l‡¨Ïsï@ÕM@ 1¦²ÆU2T¿À¯?6†„;Êý×kx6Ñ@?ŽÜ[„väÞSŠQ Ž_zÈ‚RKWËDÀ<@ïFYÿ>6è~²ô7Ôsó´ü/óeóÛ¶Dñ{ÿ ¢§ea$EJb0"¡'«K_X‰v„H¢!Qvóß÷½™Y~Ètê ô"RË]r?ÞüæMÍ$wÊC¶Œß©GJ% aå_Åîq[ú ÖóÁºÏñ˜5s·*àé}±-÷kê SŒi!̯þ.Ñ¥i±‡SZÁ Ð £é"ëòøï#ÕPOî×…¼iS—;ꆷúˆåÞ÷gIqô$+“·?×…>øv YR:K^׬où‹•b>Þ䎋4Q둺'õ#öo_í1–¨7ua¾ Ça½.uÌëÚ›5ÆÙW¬ãIÚhâ:H ±1dø}Póþñ³\ß_œãaî F–,×7ZlPŒÈâ#/çbÄöL:úå‰Ü%90"†Ê‡óJüžwd¨×^²ÊRºÖáØÉŽ—µœU¼Ó†ïûÕU ©ôP>L†3sù°y@уžTÂI0’UEÙÂ4ɼš™ AŠ6éj× ®‰> ŽXÑ6¢ –»\C’+˜›&ÆdM¶zX1±¡ßó”êKÎ wÅvS“¹»*õJœÉzƒ0Çís¾ }ü` ²&èuPêàkõÜ"AÆòûS'p€ƒž­™–ÌÚ´Á¾¤a»~“]m‚ewP™Jݨ°Œ–±À¬¿]Ü|^.ˆLvdΙü6TÊË •bþÓfF¯1óG¼”Ù¼rÔç'¦D±®{²^­ÔªØ­«ŽéB€DYßxűÉ5TŽänêdº·*OäHch·Géfi9·g„Ù¤ƒ áÖjI‹,.íêX‡™_гB~âCñiÃãÖ ù\qN¼éœô-•uöeyëËlÙrM>*Î,cUíµIC±Ù“껼"3R¹•(wå¾6—C3W>•{Ÿó…‚—t.ã·ã×¼†3?Éz³CDŒÔ¾PBȆ*16MÜ-a»å\þOh€ÖÅÝK#Ç,hpuUeqcå%Ô ƒÂ­—ºE×^KJòÐóÛ´²ÖÖ> Å —:»à Í,éÚåAÇû {—¸ƒÑÁFû.ÌV Í=,¼‡îìºIwæl½Q¦‰¯3¢p7èÖpDP˜º° œ‰Zˆf–ìì+ê,s­»ª.2[‹Q«G©ú# ×·z‡Œf‚…'§mr8±NŽ†ê£´­R«4ûž$»™ጬ̩¯Å´}YÊß?ÞÄ̤cm_,!¬Ûå\-͵®w©<”¬I¾“O–ЇÞ=*Kå[x] W4ƒê’ I°‡ ª»x‚ò)a=´3õÉâXÁ–¬we\$C2` ="þ›’F×Vш©¬#èȃ8õuׯTÏŠ’D`ÂÖ&j »H/d↴!:Ñ` ™nj¤Q6ïEænËü€R°"-ßÔ±Õ"šª Ëý$NÝVT>ê)¶sÇ¥-‘Ò^q¡eƒ2(V«ê°wÂÙ¥U;Õ¸ìqòÂ6ñ…²¿—ý]k1 »Øc¯‘ÎìL$~gã$Ÿ6P %ʱO¢÷,>á2Ÿ_‹^R-9΄m鞘ÏCãAÁd¦<˜ Œù}ÈXc:™B'óÐAÆ}'’1È3$ÏtFÄO¾3œTô¦€Oð³þˆïqÒ‹wˆGãûk¹®Šâ6¼{ÁÍHð î˜04Àv§ÿÛØ^,ú{¶E  endstream endobj 1098 0 obj << /Type /Page /Parent 1719 0 R /Resources 1115 0 R /Contents 1116 0 R /Annots [ 1099 0 R 1100 0 R 1101 0 R 1102 0 R 1103 0 R 1104 0 R 1105 0 R 1106 0 R 1107 0 R 1108 0 R 1109 0 R 1110 0 R 1111 0 R 1112 0 R 1113 0 R 1114 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1099 0 obj << /Dest [ 672 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 435 756 451 770 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1100 0 obj << /Dest [ 672 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 389 735 405 749 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1101 0 obj << /Dest [ 672 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 128 700 145 714 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1102 0 obj << /Dest [ 672 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 469 678 485 692 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1103 0 obj << /Dest [ 672 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 151 630 167 644 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1104 0 obj << /Dest [ 898 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 351 603 387 617 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1105 0 obj << /Dest [ 672 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 446 582 463 596 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1106 0 obj << /Dest [ 1126 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 351 463 393 477 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1107 0 obj << /Dest [ 672 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 279 436 295 450 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1108 0 obj << /Dest [ 1042 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 267 366 308 380 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1109 0 obj << /Dest [ 1126 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 419 331 460 345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1110 0 obj << /Dest [ 1126 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 430 283 471 297 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1111 0 obj << /Dest [ 1032 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 229 193 265 207 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1112 0 obj << /Dest [ 1008 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 149 180 177 194 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1113 0 obj << /Dest [ 1126 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 453 132 495 146 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1114 0 obj << /Dest [ 1008 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 443 118 471 132 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1115 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1116 0 obj << /Length 4229 /Filter /FlateDecode >> stream H‰¤WÛnãÈ}×Wôc3°h²y$<¾Ì:ðeq°™çA–Z6‰2DÊï‡äòyÈ©ª¦HÉìÁ`¬f“Ý]uêÔ©êåè¸, U¹…Fø‡Ÿ87~©ÊŠÄOó Råjt|ÚäjÖð7jfõèøÓ$TÍ(ðƒ Ä7³Ñ¸¾ŒôçéƒÅf‰òÊ ^T¨,ð‹G¹Ÿ²/¯1¼œFIJ«¿ëÿÌŽMàÃÈOu«ûW5y­ÛGÌm=줛ªQ'ŸŽÔ·ÿzãϼKüDW^ gGjòRµ¿ÙÍ’7‰ô´ž{ãB«ó_ïŸåßFì1{c?ÅCy†9¶àååÅ÷"?Ô jéXl#} ßè™›zäÎËQ¨*52IêGi¨¢ÌÏs•†@RÁÇ8W;ZŒ>–;0¢Ÿûhô脈fô£ü0F’Yøø?€2ì ¤9RÕ­}°us{"0•Þ8¦î‡'s}JO…þÅ3˜»¦¹TŸ{cÿÆ}9¹Ów;;`MäljàÆÇÃ$w|à"ùŽ·ÛMͨEºQåße÷/ç´m¤UµPX×S7ñ锾ˆô¥Z?µÕºVwº±Ve~|ç)ļ±­¯:C4c±dú9‘˜hØ1cr^Þx‰¾=)Ë“Ó_<ÂáúÜ+üLßx±€âHøˆw¦_ÉQŒ}ägAn(& ý §D…#pôb9} èõ13Z,‘8W ´ƒHí¡jv¨šU°´ŠR¢€™Áˆ,~7WÏfëͼªT»Þv¡L}Ó¥TìÐc_ü} V±Ë—·LG±ŸެG,^„AžîQˆ‡Z]Ÿü㲤 2§·r«Ð_¼#D!á…š¿ÃDãgIo~ØUìhˆ`&PŽ1%-ɵGQo°e¦™…õvuoå’é'þÄΪä gq±så}ÈË#-ò2úúØ C½òŒžþƒ/A6Ì«ïÜ1ˆ›>Î}P€|Šv0 ܰõFA¼Ö”õZ¯°­ ëË´QÛÆÎýCÐc?3û˜¬¬Là Cs ¯½”RþöËMy·Ó‡wY?2 lŠšç–‡ÂrX5[oëö€éE$É1\ö{Lïs£´ØÅ­!1 ɵcÝr”X/VÌöLÿ bÄ"¤S"¬7…~›´„ó`,acÌìã°S±q/cºË±½KÔÉ¢7ÞU1±›Ì‘&tö©ù&ø÷‡Å²&ê/öª%ö ¹±Uv±£Œ¸ZV«ªíÓ ³ ù3ÈK!”ˆ¹1òÍ›´å2H *v^.$qÖdGˆÌ¡¬m9-§éæeœ¢§ø«8MÎ0oPLÈö PkN~¹*'—ßñ±>¿º¼æÁ%ɾÂ3úùp˜æˆpþž4Æ4ºzôI$©ç®d[‰þÂÉävÙª¦úÍ ”TV¥´È©j=dh†ò!q]VTÿ”+”Ÿ<ò «PG8€C#”Âú´g”Ø™;A iDvhé«ËNÓqÑõÞ*~~áÒˆöƒŒ¿þ\~ÅvÜ…˜%{)Ròu½|Uv:÷8퇪^¬7«)¹ñVà ÎüD<t˜'4ê:/ÁK‰¹QgÝíé—RŽDßœ] »Y"ŒžÜ~.%Aø"ðF˜‘C]î*y¸²¡ÊÇŠE9îE¨@˜‘8¹„¸t‚ù´ÞO«ªÕÓÒ®lÝ2\j¾¶ T£wmT’ï4ìjBž;­/…Hµµs4o /ÖÕ²å>/ãÚN3` Ü–9:Ü*O¥e¬q¡ÅÒé’0°áSÓm»¦XΦË嫯.<ª2{ÛÑá³­<ˆÝåŸF{õËÎÖ [¦ÏÓj ÍÕ*Ñ÷ðáöìã)ŒÍUk´Š š3XM»ÞØæÈÝ«Òtù2}mº’¨.N®&çGøý¶…bEý'- Öáš1–9‘ñ{«Üì=,Ó„øšÅ´±–áè€Õ‚]“憵½vŸ¶Õ³%&€=­Ãd'îÉþ]wrE6úöWé&_åFysúuq 0×ì.[¦ë(¯¥=2-H¶\A3Ä— ÚÖ½Sù`ô ýiÜtÓ¸y°—S6‘Jj(Ô,Ý/n§æUTRxâ²z?Í£tP.n9¡ÐæqW¹&ò•Tú[¢v¨¥DO»w_%ío¸¹ÕïÃVäƒ WÚézÞu±³iM´Ø6܃¤(ˆž.Ý…¯E–„ZÞͨäZ^T ÞSûW¾2ñR«èJ ô Õ‚[͵×/š~J¾^òúõ‹{|•½ë™²Ïø/¼0î[µä°˜<éÚË;ÚÁðúú¡âÛ\εJ«—õv9§ r¾–70£^Ã&Ü–ûë}Uò#²€î‘òâȅȽëfå1ze•%#-íLú¢nåV~¹ìQµ”Ç%ØSšÃKÍwíÊ(²§·OSØB¼ Þ·Ðj¯Sý}‰Éw”ïçå…ëJ‰šD7JRRÓý¸®é'’Ò!}oNéuú.aj<¼ìäŸGƒ+»"y7[KUFzmËé—Ÿ´¡ð{Qmšv,×€¶BP)9سó bÎÞÊY´kÔNoo<:á‚ËÇ•èûåi9A,p;’ž’[åóO_q!¢ªÛ´^TA8bT£÷[¹4 n,UQ‘ù&wm™ïÊñwlâE»ª4õ-Ï–.d‘~xí÷ä./ B¡Ëp;9v­Þ‡Ã®$5ƒfÉ5&(  ùT/cC™ŒF¾ª]éÈèj[/H~Btb`9|voÀŸW…–Iäˆù* Œž%ÈöË×®ésGt®ŽÈ R ×¥e!1,$™–9eL©ÌÁ²'ÊèLúR\x¹¯C–ë‡.Ì¢h[ÙØºå”˜n{lñ\ͬÿ¦ 5 u:dìP¸ÅgÊòù€ë}¼Ã7‘˜ª•—„zëÅ•/¡Ð¶˜"Uº÷ ¬õ’TªMÌŠñìÅ9 ÁŒÿÇxùô6ŠQü¾Ÿ‚#¬âÈ€±A­i²ÚC6#er‰´b°âÀ¬Çò·ß÷ªªùÏì\Ó4MS]õê÷˜VøS˹SÆu8áªN@ éˆ?+ )R*—#ªsÔI®7ðýúc­•~¨^Kä6É…ÖHùKVǺK9ír’r§ñ !»Bq}¾GÉ„D‘+b ]\áT,ŽÄâ(9ÆnÕ"+‹2¼ãé" Ï‘Õ õzwhêê˜\ÉWŒþýˆÑëzM#Ú™¡Ä™!µB )ä¿.òCÁ¬G$[à Þd–KÚ$ˆVßlÅKmNû®Ý¶:¶Fì#‚ë¬2oÚYñ¢òðÎ’¼ †} h¸üó.o½· \Ül>Dâœ=ÿ=•Ƕ,n½©O¹vαd5'Hwÿ|ÇCfO`äA³>#ŸÇýs{›ˆÍQ Ñ@Äæá îL¤ë´rÞc%Œ2õòÚ"?VÂpèá¨RšYK{<–m/j©€öË Þrž²¿ÑÛ"q (Î}­B—Õ-ٛ̄  ”cóNã)nwÔµ¢Úllà`Æ *”+€«–05Ag´0câ•–@“øN‡ šq¬y—/³ ”‚…ÿÞ´ä c¶/ý‹å+÷ºyÃ ÌØTµÄݨ„Qû„NÇ }ë=ò=ØŸÍÒÿIRó—ëREÃIÞ žÊ{«›ó¾,to[m%S_eÀÊZïÞ·CÓ6kjöÞÌ˯ýPÁÒ½7ˆru©j= [F4¥Ó¦ôxŸ½XD}ñØ0H,ûê ž‰yôž‹P½•,Fõ‰kÅzO@‡†m)ù%Õ hg~Ñaå´>fÑ;—^‚ãa²ÎËæ†ÞN¥R¬u’KôòMw;\‹¨Ûö«àžÖÔˆ Ã@…ÃlÐiˆ5 Ûñàkn¥Í9ë4{9¥ —.±«ëÙ]iBzÕ¶nìnqãåb h|j߬áÄB„Jûh§„pÍe]­[ ߣ x¿./þuùP’*‡ ƒÎV!m[Ö*í£E!اo³iæ>Ía“ƒ¯£ÇäCK«]½uh/bhÿVµ+98™àÁ'«ºj+§{@»Ñ +¦Ê}³·»[µ@<ç®5Þë¥ËùŽ'sÇó ‰Q0þðÚ|;U -óô68›nåQ¬Žz…Ú™íá!÷ìE2òÄ=fþýÝgäÿ sÞÛœêµô¾ih;]æ–&{ˆÑXÍ{AñÔ½¸kh Óî7_„ѸÂeDk°è»_&ËE§{Vû¸q]{ìûݸ‘g.™ØâŽW{\Ìë{ë?%¥ FôeS^% gF› ‹˜]Aš¡œR²î6HWº Ò”5ôdäã]‘‹+N<ê7º8áBpZ.K®•ø¶¼Ý“· ¯fÌßFt;°ËCÅ¢Àò¸­âÉÎ0×î–AÆa-ð¤?ã*Ý¢µþÛYæ_t²3? ºlÒ%’)“)#<8‹iWÿñµ ­Ñôž Þ¨ºQ×Ò˜ÎÕ~ïÛ  ’¦šVÈ÷sÕî¤nu!5Z‰¨+|Õ¡ôλRúPú±ùŽ|;ì#_·§Ž”.Æ’A¨L@=ªsä9œ›ÙÙ..ÖäÅ‘¹E|Ì'·™x-$<©º(2›š7Íó(8ÜÌve£Ò^Zi#dK?f?Š!2QÀ¼éÁÄ8+á’cÎê[}¹¨äBˆ”u$¤6|w¾× mîé¥HWìë…þ%,áLÐSvÇ –昈Úw[Ú&CšM€î£b—©Ø¥» eßgÇG»§èݸwššýDËÒîÜñɹ9¶`‹Þ–Zô  ã}¼?‡_ÕPþõå1˜eô~t•/$DÑãs ‰Œl_äÞîPªs}CÜX‘'ʼnÞì t 7 Ã]Gëfé m V°]Ss.²Š66:õ€.Ë,rm·Í… —‚¹ñ c=Ù•0 ]lxøî6 \*Õ&ìkV:“8Em> äõÔzµBÓXtú†M”¶°Íôò¢°‘ÜmE6 ƒö:[Gßá A¾ýùwËh§PòKcϳ•/Âa‹„êI¶°àºÈýóoÿ !Zà endstream endobj 1117 0 obj << /Type /Page /Parent 1719 0 R /Resources 1123 0 R /Contents 1124 0 R /Annots [ 1118 0 R 1119 0 R 1120 0 R 1121 0 R 1122 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1118 0 obj << /A << /S /GoToR /D [ 0 /XYZ null null null ] /F 1125 0 R >> /Type /Annot /Subtype /Link /Rect [ 398 393 483 407 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1119 0 obj << /Dest [ 1126 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 218 730 259 744 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1120 0 obj << /Dest [ 675 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 206 517 222 531 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1121 0 obj << /Dest [ 675 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 431 441 447 455 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1122 0 obj << /Dest [ 1135 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 236 325 277 339 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1123 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1124 0 obj << /Length 3934 /Filter /FlateDecode >> stream H‰œWÛnÛȾ×S öjX˜ 9…žþMþGÁ®­\Ëö|'’n"žâñX÷ØQR[ Ive'®ï®ÄßÿkÙ!¬[x:¡,-W›+ñx(ûé¶"!¾Ìë¥e§Rü›þ[ÿÈþº Éå:,²Ø# ‡ƒcùŽ';ÔªQ-ˆ•<ºŽ’…ÙÚ¤Ûlá‰R,T9~ä ?v’DDDR€A"Z½X-Þgc0|>qO£1E×ňHŠä(9ÏÑÉ8rAÏ,”n@o³‡Û·ùòùÓ¯O²¬{½Ö-É#)¾»‰BQÊw1Ë—dÅ(ë7Ùê•e'àjkùRw–€û›¦®Žäúd•Jbǽ(Š­z²~6™¢ÍGš:ð”ësD§ûNXž+!œ38í™ãàD0KÚêŽ-;ÑãcøC,ÑØ¨q“AÍÊ À¿ Ê*–ùÚ™9¤VA1Ù)OGs/K³Øó¯æÃûJôÔ@¼ Z!–‰¹•˜z³•¶ç`›kSüibŠ¿)Ô¸­ üP ¶P¡'76f*W¼Ùlyi>Ù6=«Á£Ï,¨.Äa£k<Ñ€'D^ôû¼ªŽ§¯~ß•½¥°áèüAù¾ý¡a݇üøJYIªSÈýìO#8ìí[l^%sü d¥yÙö]ažÊ]ÿnȼi„Ðñ¦nõÉXV7¥Û5öÂÔøIvÐÉsüÀ±RС,%|²ñKþU‹nßj0?ïűÙSý-Q7½(*·éØÄªÊÁûX®­¤™\Å”j5¦Ú¤cÆ|`Ú,‚Š|ˆAŽdpŹxÑjÊJê0+€Iô,rc­66ÙÅ‹# ©‹+ò$7úMižeU‰ªü ±ˆ¥mÙ„¯šòH[4Oê×MGìw_(6bµ–¯5¯yÁÿKŒ»'›úÆÇÖÃOYVâIu ·ØUðªuÙh@9ÑßvºèÅ2ïsr°h,È­’Û²^Á,¨ÙR´OÌá7/hhâ–ç0pb…î&£·Ñä­©¦û'SñË'(ŽR×P#M½*×û6ï˦î®D¾\–øHý…¬š BÞÖæ@†î낈j/ÉKó þ‡Àà,z®ôÏâ¬(ñd šõÖõÍMvýpw›Aúbù=¾»‡úï[Ô9á÷l¸8ºÀ¹(òq@ÍæÕ¯,Öå8FöŒ×èÒ ¥Ü?ëP€AüCgÄø„–CÌ:FNY¹‡lVÏÆ@4¢;£K:F`°u ‰š+FÅoHžhvýø!U9Dš(RrÒàjEã€21zÎì}:°)NV8ö ZÜÒ4=¹‡•/¹D¾ï›-tRAÝCe'î~ú3=ý$–º*·e?({ÖýAë1 ýd…Æ#•†ì§’Œ¨cãÄ3€  ö媦$ôÜít½¼T†$;ùãu8/C0È€Š(W¤Dqùƒ‡ã% aI+ðXFÌ«VçË#„"Ûö¢Y‰žC°!VÃþÙ¦úÂÓýçÆi:¦X)BÄÚé J‰º€4¢Øèâkö¾Hø5æD=É ¢Y‰‹þ{.±1Bãõèð¬+9•œG þ£yÔxÑY9L·îApëŠf Ǻ­„h$@vhÀr«3f>Ч3 &>þáËÃÍGš=÷Ÿ SJf·@bà#Dº”á§¢‚—õÚ²clþ‹ ­'À ÆÁ)Óö<&í«²2DЇ–DÜg´@LÂñk³&¿g<ÞwÁºä’ô1/ >A¤®ÄsÓ'ª/]-ü0þŽ•¦àHDYÕ¾+_ôéT \õ#¾™˜WPb,R5Ü%¬p XÈlœ‰¼Ç•ƒ ªhÚ¥¨ô‹®E°ˆ»ï„ÞT6'×7 P‚úÕ ?Þ<  üNLhÍDÀ­ñz3ÿýŠgC»(©F f·û™µ!7ôNÛ!) ¾BÝ W#禲 /If·¢ùF~Z¬ø%ί$ÿÇ ±Dl¢¶%ï 3Gð™ªLÎÜÉ+¼»„4”d-{¦qF<)z{jÊ;jÚ·­`ÜÊè{$•r§ß‰>_³çòÐòÇ;^Ìþ~5Ø_‰<`(ºÆI}%¸þàJÔêo³ ´Ë3Fl6?kĤƉ\ >aÜyÓó9èl$´O ~c„=áÏãWóɬg"mh4Æ7ÿv%°#¹ƒãä€@ÍqN 'DJG±*<$,” †¼Á:UòɃ’¿òÏ#ë}0»Ÿïè{pȃz(ë^›I°zä¢`IÒyQŒPËüH0Êgãõ „TU\:?ôr‡¾ƒ$Zv*k¢½“Ðèð2vú^â„ê¢`o6ÏGò½ÂäŸAd0ç}%äGœ7ž]ZÁþïõ ‚›¾jueÖ=–àÒ,Ž¢5Oõ ³m¶0à嫱k+˜¥S7Ø3g`µ]α#«m±b…Ù¬-¼ö,_Yž: }ԤβaîCFè¡=3U9©wÞ»ÞHïÂ>KœÂCö¹ï÷-ÞÎÚ‰IÌ‘<‘\øg•¸¸ªÎ¸Å`A80»áêñ,ðä èðœ½æÿ7üÑ8E\òöë©€fE<h&Ð<è7ã÷9Vа25·£¦ñþI=´øò2¶Žôy˜%¹™ ù™(„˜³ðžV· ;ˆü_;néòJúxOãú³´&Äû,2äÛs¥_-"‰úxhp½$Ä2ÂæàYà…4 ¤™i#¤­äGw{xäšìõJK¾"tâÃrï.‹Àl†™°lŸ¤ýíê8€?&€]tG÷Î`ù’+@²à ÖDàbûátBùïV­@v¾ä¯ôd…›]?ÜÝf@J3à¼ÿLïïNxhl¾ÿ1 ¡-¤ %îäãY÷ êÝCHÌÖŠŠ¡ÔØ`ØaË:ßžO?€PF—”|kán2ç‚ᓺ/5\&¡Ñ¡â¥(ª»Èýª\ïÛç2öÊaSÿ#¼Zz·¢ð>¿ÂbeKÁÛ€A£‘2IÛE­v©2æB<2ÆÅv•þû~ß9÷bÃÌ&Á¯û8÷|¯W‡nX­Ù )ì˜V‚20#ÇÎ:¥ÿ¤›D…€KünÚüÆT'Õ.ñLu(ìW‚zÜ*ùööœÿSàö,—AhJí¿ë¸1–\Â]ø:Ÿ¦–ÁÿéŒvˆx ¸ÌÜ^·X囯 ³DßîÁºKL¹c•€—“Þ–.om³Șx©í)-ÕH\ðNHF­ †%ÝŒ° .§ï5yõá£tpœ½˜ùë—ßÿ>fU—•a½Û³ ~Ù<ÄËÄyêÅKL‘x)2hŒÿô°ø²ÆŒÅ2œ3fÄËù¥¹&ò”Sk›9£E.R$Ž”Ê±TÀ†rr¬D3'AE…Òeèì€*5ê§:Bï¹;ŸÑ!èÓ¦«ëÓ¹¥m^ê9/ïˆgD µ/Ðè°{ m§#h•×: “Å`œ$uà/ŒªõÕ|ëØ_ ˜Föêb3fÅL òä{¤_>ªÔ¸º-£«&½@væ ;*‹cÑNGÞ¨ –$ \F¼<›ã HÂN~ hF¡2|ã‹Ãk ˆÓ²t¾«&P²3µ©v¤gÚ˜ßåþ¹ ÉÒž!ùB@kTA©gKC‡NUèmäç+€¸4Ô‡NŸš}W*$ØBæ-“cü£8¤º44îÝÞ‡èæ=}{*ŠM ·£P¹dÓG tAð⸠ݹ$ U^ N<Ó÷O²°³æ‚ÆAl£ú*Û–ô¨ÔBy˜qœ=êc Îʲhžq.2>«h¢À;žô;»°×tï.´eYëSVÊrfh2NXë…©Y¼…Ÿë2ô&Æöëö3¸L‚g°´QêÇd ØOÂh‚ëô9›b#¿žØãp!ÐK¹^ÓŽD¾^è_˜X’qêÿDþ7ö²ºÅ“‹¥Â§®ß“KCÜÍáÄ9¹¥v¸ˆµö%`>K5žE\Ç×'D2Î^¨ ±AÁ+‚aŠbœ½^.Ð0ÔÐh($ä¢ãž@QbT"ÂL°\ŸpªYÓ’æx½/*X%X/ml˜Òü\ ª+O~È;-«IB$Êsˆ*é×tÒh/œ™ø9-F˜Ä3 +Ét2 Mça&Û»Yž›F¬Ö,Ðd©O¹½½=±_6 õ¸v&nl[ùçSE“Æ[‰s^ô¡Êrâ<\ÌÉdP1­${§Ýd~¾]ÕX¾¿îfYÆ_þÓ¿}Vâ—Ù6 U–$ÕûKÐÅ—ÅNW¼?¿jŠûC؈6Ôyw9}NÒËx–æŸ×\k£e™}P#*NNŠþY`ï'%¹=v‹ñµt˜,ü‰&þÊ¥›ÏhpH4ê™õ‡®MÂù i*UbÍ­ðšãô]ŒÂÉpü¤Ï‰:r»Jïz*.6‰oA?”ꉇFWt.¶]kÄOe›Ó‹‡{w›b³áРD7óÞ)°kº³Ïº²ÕJ¦?;V£G#fSÄëVoºé6£Ü²xŸ£¦VÙ7¿  ›$õ9Üg†Ó̈ J¹KsO“w”òï6Kâ‘5Ú4HòuÕ$ïÕ¥Ö­1•(¯:Í ­êX]Y2¶…u±þð¹± ½5d%+õÞI¶ U‹YÀ"0t©$Û6’¿rµô±b8w`,õa(íÙ³ƒéýš(9ç endstream endobj 1125 0 obj << /Type /Filespec /F (SDK_manual.pdf) >> endobj 1126 0 obj << /Type /Page /Parent 1719 0 R /Resources 1133 0 R /Contents 1134 0 R /Annots [ 1127 0 R 1128 0 R 1129 0 R 1130 0 R 1131 0 R 1132 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1127 0 obj << /Dest [ 1204 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 246 544 295 558 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1128 0 obj << /Dest [ 1330 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 321 544 352 558 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1129 0 obj << /Dest [ 1204 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 246 298 295 312 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1130 0 obj << /Dest [ 1330 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 321 298 352 312 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1131 0 obj << /Dest [ 1074 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 356 94 397 108 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1132 0 obj << /Dest [ 1135 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 321 67 362 81 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1133 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1134 0 obj << /Length 2193 /Filter /FlateDecode >> stream H‰ìWÝnÛȾ×SÌ]‡€ÉpHФ‚À€§[‹Íb­^´q/ÆÔÈb#‘IÙq¤ïÐwìE¿sfø#ɉ÷¢Øf Åù;s~¿óÍÛåìÕr %–뙊DˆøIò(H’0Ùb¤y‹ånöê]›‹¢å=¡h‹jöê‡%îÛY„¡Âžbæ÷Ÿ3ù³¾7– oùÙ‚-D‹‚ãà ’…›Ú°¤÷Ë™¥˜Eó4ˆS%â,Ès‘*xRÀÆ$™­go—ƒ3b…-á±7Fï†äÉÞCŒ£$lH‚8Î3a‡½S³ù<È¢‰WÃyïÕ0¶6)ÄIÅ^$R¼Ñ«]Y5†GzõÔ—±ûp<—ûîò5TiÊ}'°e. ½ÝbC&ÍJÈË_t% ëë–ùWÜÂ2â‰_ZÔAŠ# Ò&‘”+_u‰Õa1è°°Rnlž‘æsçù”WV™ô…M‚ÄÉå*¦O“µ8qfjƒq‡Hú ŠÛœÈVÁ"šîE#«¨UiËÏвáÌb‚‡Å‰ÛU:ñÙE/‘]×”w‡Î´4Tl/ ô%{3F†ª®Œ8¶õ9O÷ÙwmÖú°í¬Kó—âkïè¿é¶ påIZ…cx9<.€pì }/7@n'°t•ØzH;óÙpá‹Ç±Êpݡ䶚·ì:cwîÊ#¦ðÙÕºnvX©« ±®·+Ó`ÎwÐ?0DÚC-'GM,ð´Ñ­¸3PkmºbcVÁs&«Q˜ry³ô¨CÁ*Ø–bøECBPÜè¾®Wb¿Õ…]-ÊÝ~kv¦êÄÚKdÍçÉ/!ô²Gö€9ŸÈtèÞ—BO…{ÜÝV ÏºƒöM0¢>ºò`™$ĹõqæÎ¯çƒJFç$Ö9©¶å'#b=ôÔ…d U ´ †|±ð•](ì„]%‹ y./ußÖÜÁŒ¤¡·ÙcîöR yNè¢à]î;ëÖÙW‹råa¿KRe£EÙØæd@<ˆ­Ð_ ¢•I‚îN««©G ˱Üsßà8Ï‘/h'ˆ3Ëðc°¤è$£Ïën}¨ Êh®µ[.¹C±šÇݦ¦vçº,¦úv@ÛîÐv bEÑÓk2k¢Ö¤@ìêÁ ºeuo­{,»ÀuRÓõ{Î}|‚®#žéþC`ý1²åOug¬rl¾G‰ùD7—½yÆÅÊF6hÑš€ú´…ˆŠ„Zv×»Q;´)œèmðŽ­u¹eƒŽ/uccÇÓÓL*cÉ}ÃàÌyϧâ`¾š|`þ É-¿‰,³ÐÝ©Ì\V¥]&¶˜Kûð+ôal·{Fºc×]´{yÛHr"Krr{“qó_&8If+õˆË(æ2Êq™Ôqõ?ç2*±¸\&J{wg]Vq™9è*úÞš¦cpà‰î$†(1%@(móÒ¼Äf?;§B‰0•ë¼)q"á0egÈ1¢lâØ1™ec S> 0ÖÁÎK(Öü4‡üþ“©- ˆcîÌ_Ô/‰>í¸a{‰SY·IR´NžHæÅ¶4U:å¥n޼#…ý;t3_ç/¶˹Ð˪íˆûàN¸ôŽÈ7.Õe}hÐ`¸·àCņÈNY7¦Ýøk*ëtæJÙùÙá±0ƒt’‡–OõÚ…§5žœ>roÞÛ§Ãò[nøG7ÌÍqéÍŸ>üôã_i9’·èQ¢oÔÍû•¶';s¤•Uè ·\ÙVyý˜æB:ñŠÅS¼‚£ú\?åFbùSÈš´k) |´o™Is6@ÍŒ´dÔ×v1̲*;;â´O¹ ^2Ýf! Ç b§~HSJc<Ö3DêÖ»ÀQÕTà^Ìôwåý|Y:ËH®ÌnªÖæ±ôºèô½!bjk >Œˆaư½xßÔà¥í3òy'I~-®ëê îÄb3d޵‡/´ÞãŒbjÞQâ··³?vO2­UÄÏœDéÀmÞ/gÿ4sÞÅ endstream endobj 1135 0 obj << /Type /Page /Parent 1719 0 R /Resources 1142 0 R /Contents 1143 0 R /Annots [ 1136 0 R 1137 0 R 1138 0 R 1139 0 R 1140 0 R 1141 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1136 0 obj << /Dest [ 656 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 377 598 385 612 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1137 0 obj << /Dest [ 675 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 584 88 598 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1138 0 obj << /Dest [ 1126 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 299 557 341 571 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1139 0 obj << /Dest [ 1637 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 336 261 358 275 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1140 0 obj << /Dest [ 1144 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 227 178 269 192 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1141 0 obj << /Dest [ 1168 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 435 138 475 152 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1142 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1143 0 obj << /Length 3222 /Filter /FlateDecode >> stream H‰ìWMsÛȽóWÌmU&Œï—JU^KQ9»±·,æX9@àÐBL\”¬üü‡üÇòº{‚ Öö!µ§-U‰`¦§§ûõë7?®/W«@ùjµYøòð‡Ÿ( Ü(ò•æ±›d^¨V÷‹—oºL•ÏñTWÖ‹—W×¾úÔ-<×ó|Ì)Ëáñq¡)>Ë”³úç"çE¹J=7O`8ÌÜÄ»¼&àåô'´ú£þO€·ËÀs–~è&ÚËÔ퓺~ªû;¼ ´q`IwU§^_½Pÿ¯³Œ1nñ-vc]9ž.ï^¨ëǪÿ—i·l$ÔE½v–¹VÿæÿÎ?V^ð‰ù4ç&¬.ðŽ=x||tÐõuG»Ú¦±¥‹GÏ ti_ݱ¥ËÕÂW•Zq↉¯ÂÔÍ2•øˆ¤Â£Lµf±Yü¸ƒú˜âGã]"¢9zÈQds¹^„ ‘†Yªd85c7 &Qõ²ñQû¾Fn8™›juVlMÛïZÃÃ]W¶ÕŽûóWŠG½*ùE ûz»5kYyk6Më¤x4ª3õºª?É ¥…a –8±ç§Hq"RëÅ „³TìÃp¸lÀñD^îÙäDþ`Ë—½i꾨j³VUýŠÓ2xsÀuâ¦CbŸêG}¶.ú¢sÝãt‘›is®œ»ªVg8mF‰ïmexX÷çãÖõ%o‚£Ãùa#ñU¶xýPTŠJo‹[‡ ¸u&m^ý¶³¼ñÀÉáÔ/Þ«Óvð5ÑUSÏIÜ º„Ïuß©¦Þ>Ù`ÛpN„»õSϲ$€Ê±ÂƒKÙèRf“PÔª”DHâ¯ä€m„“Ðtˆn‚%må,# ì}=´âC>ú‹•k‹[¸a¾ôÎ2CtÅ™ä€"‘óf˜tøÜ#‰™\bˆ™Ù\oj?GeëåI´©‚fÑö“)Šˆå"Ý÷mu»ïMGCŸ‰ÿÖ1¹ uÝÔf¾ï3ð~ÔfSì·½D2ûVZ'¥žòIëf Úò°Qøî¼Yýœê 5z‡Âê©\ý³µ)… ÞG °°”ƒ x–ùbJDkMôå€1}ݰ [ë²^Jj…Ú—õš Þg*?Ö -²éÅœésÕ7 ­aºF¬>0s¸jî¸ü§ jêgV£vÛ¢4dÑÁëb½†ãKÛ£1£Ø&@ÙfÙ·…Úmqoz⅘Ъfß„Üè9÷ä/ŸÈã\ƒ·Õg£6Õ«±+ZƒLÿˆ%€©›Ú¾ÑÎ2¥æËCcTzã(l†Œj‹m¿ÙõÕdþa¦ß8®šœjRÓÁžÀ¦ûí½Dôoq Âí¾CǵÙ×%ï"Þ¿¾¸XQ=Äúõú ôÕåêÍÕÛ}ã@\®ìÛKDþ —í{ûæâOo^]ÚLŸ‡]4J<8Ä–tœeˆ /‰À½ºàú õßdl¿~ hÅÚ~{‡¤ct…¾9.ä=i2 leçÙUW2}ØÁ v‡w«·ï®ÈÂITD¹œ2廦GÛ¹hê˜.7`²Tï)EÀ0SÉ£ “Ú  9bEZ&páIE‚•wnÓPº}ß¡*dñqHüwª™ØÏÜ "ÊÔÌÏòÕ5©C¤Î Iúª7÷]_ô(×HïùC'€9ˆŽ=êìzp;Ȭ±Ópl`§’æ£.›µéP]<¹%DtCVzJªþ¾›÷°Se¥>i¿ÿ«²9ð‚Ÿ+*þ¡Y+û„€ñ#Ãû{Žƒùúå™Ð¡ä3‘òí?ä~‡sæúK?€îwÐAá<÷¬ƒ¤VD 1ÎùmŸþ1ˆ˜ßYÄJr0¸£±53mª•ü0ŸÆÌ§r¶ÓFóˆå´ÞÔæÁÈ|È™E kp™]´‘ó~³©F6}b1§\’©¦4Õ(<æ®]Eí]¢è‡VñÕP÷þN s;È’´S޽«M…ÃâzsÛ  ±”q¸ j€¾>•5[Äc Âz¬¶[VQeÑ—wj˜æÓ<šQ ý³ DÂp‰ô“¨ø!J¥Œ(',¿³ñJ[´掼-¹adêNx)+ØñhpL ò,Ñ;‘XhµÝLUMDË ªüà ª(~ü ˜äa%UaÊôEŸ¹û}×c'yßïÛÃ-Ó·u“»~<©›#žïÛ=ÂRgÕæ»A6)èƒÈˆ]U`͹S}ñÙÔ‰ÂJ=r¶5¿î«ÐZ¸‘ÌP‡^D{~¡€Ó>V¯'¬4áßh,ôÈö¨ÿ»f¿]ãà|ävHr6ŒØ&àD‚P9á× oŠmg,S€'ÞWp‚ú®€ ˆ'êÌ0N”©?APŠÝn‹Íõ“Z Ï©_R ØK ”#äá8ÃÕÀÆTÎÊóÀ[B\z]÷„è&8ù6á(nÿ„>ƒnr ÀÄ„$R‹ ÇTeª ™¶s쑟®³—0âl[1a(uXû(Ÿ­ùúÚ4q@·3GFí÷Â.~Î/ºwÈËÞ¾0_Íú}QL½ç:ÄR¾‘¦LXLF,2BÞôænc׫׫¿^“¾?Fôf8-¾˾Åò+.Þñ’åÂV‹>í$Zô ´Ã¿T¬TþÃô$\:sÏWYʽ|kÄÊÚNušÀµ}1˜†|÷iÖ®i`”f£®Ÿì&å_~VvvÛbâótâÓÇù±>±äƒËÞ6¹œH,ñ<Ô.ëqÜ{¼, Qîg‘›Päƒ(œ©òA+‘/Q1Ø‘™˜ÇTƒ,ðƒ0;µÅ8É¡ç†ñ„6¬îðÓ,RHÊ;½Íe„þ]›ÇB'ÊFÀI» ¥ëÑZv™ÆeãP)­ç´ ÖŸ°’åròe ¥mû=Súõ^ÆfM› ¶·ODÖS¥’o{‡$×­øëW jgƒž]Ò%ÏŸ¶N?°;îDHXK­ "]A„,ºflɧÂG¤SÍÂg:Ãë£ÕÕ+àÓb{l TÚçÁªt—ª.·û55!dtÑkbê'«¨JðóòYÙx•Û±&ÿ¡›P7·ƒiw.p#7 f ÷AÿáòúòŸì‚‘ïëÛ¦ÙšA‚ÍAŸ#ç€êçÀN0½Å¼E¯6< t½ž>HÜlnç{?^y“<¿"Œ.ÍÒ‘1&¾Ôm«µôz#|Q ¿ßš»â¡jö­êL¢FFp¡ƒYNÛíÙ §L½ÞÕ±—K/¿3Ф6lª#ꟑvƒœ!t‰Ú™vɲù¶8j±2pY4Е†øÖ!2#१"ðÜ4›ÞAòIf)96îŒýÑ%-øÊ%ÄT'ÛSp¨OÒ¥Rt XP¦hVöŠIìþ¾çúvhKÇ¢t.žF]é£~¿/ÚÏÈ‘>‚ wQ)ä;ºoLŠƒáæØÒ›ÚµÚœêªÔõóiX²£°p@–|§9‰KNâ’ Í1·¾"*”£X„< žbÃ^`“//ˆh›zùþ'5ÞÂbĈºÏÀ3±åBËe9µô#¼ Dê‘Z52T8w¥DÿôrçM‚pŸ_አ?eÓD" u¤Ä]*^I`> ñï3³»g,›"J>|^ßÎ~;«ŸœÒRûŽÅu°Xõ—kAW(dRB沕¹¨3Á‚+줷m­3Ž&aWhÑÔâK"‹ï6ßÒÚÑœwDÔ.¾>Æì+R¬©ÌRª,¯y·ø!Ú+´§%¢iÎZ×àrÔ…´ØZ”“Òk†!ÓžÃ`Vë[³h› —Áϧ“Ýîž4PÑqÕŠ,Cåâ²´ÕŒ–0"ù1mA´w§'ÉÞH$JçÖ"¸ðù•³ç×1ŸôÆúGåˬDýd£Ù{i s<»jL’:i<›/ù„µdè‘:NP ÂüÓžÀêao¯_Ñ:1¥dÓÜÓúT4ÙÙ{Ö\«•5Ç`ÕÀTV¦P&h]6´r[k’ÌašõŽ>ÌZÀdú¼fSk`{°B† Sù ñƒ·ãü•JÂv»e*¼…Rã§ÆgÖÛy¹Z§!¤‘®ŽE겨õZ÷­V"] o¸:›Å¹ÙܼÊY='RùF-ôgh7fùÐWÉ¿à‘*_vEÿÛÉ+´ÉË9óº8Ÿ'ê$ðůëNx4¤2šð6÷Ò½Ìð½CvrPo÷Ôþjt›—? aÜe? endstream endobj 1144 0 obj << /Type /Page /Parent 1719 0 R /Resources 1148 0 R /Contents 1149 0 R /Annots [ 1145 0 R 1146 0 R 1147 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1145 0 obj << /Dest [ 1135 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 483 412 524 426 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1146 0 obj << /Dest [ 1168 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 147 162 187 176 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1147 0 obj << /Dest [ 1446 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 210 162 245 176 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1148 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1149 0 obj << /Length 2560 /Filter /FlateDecode >> stream H‰ÔWËrãºÝë+PÞ„LD_¢È)—«æÎÜšºw13k“\gSÅ E2$eó!ù‡üc9Ý J”ìy$Y¥\e Ðhtœ>øi5{µZE*T«Í,ŒT€?ü$Yä'Iªe¾ðÓ,ˆÕj7{õ¶ÏTÑóœ@õE={õþ6Tý,ðƒ ÄœbæÍÃÌù¤ ŒåÊ]ýu–ó¢\-?Oa8Îü4»¼&âåÔZ¤´ú7çŸF½(p½0öS'ÈÔý“º}ª‡-F"Ǹ°äôe¯Þ¼Ÿ«?ÿËõèwø¶ðNéN±«ÛC9üÝt‰]¯]/wÔ?ø¿û—Õ¯3>1Ÿ& üÕ;Œ±‡ÃÁwc?tzÚÕж0-}4?r ;´eK?¯f¡*Õ,Z¤~œ†*^úY¦Ò‘T8c’©ÎÌ6³ŸVÇ`Ä!¦çÑ8E7 ˆ8=ä(»ÌÑÉe`ŸI()Zx»úøéÍ»w¿|xçܹ֊ÍôÒOr{TZÙØçy&'­n‡¦í)¦¡£ôz]Öj×tF­õ ÕÐ(ŠGê/œi× 2Þ˜á«ÕI)t­îÚ÷fMÓ‹¦ö8H^ä/—Ê }‰l.ìöQ¶í‡²Þ¥U-"çÉõ"§.”Þ¸ r8˜Î]8䀢†¡¯ìB«©?¸±ódWÈÎC­+éc‘T9ذỆ²«e˜ 4lYmíªqÝꢞÔà†˜à†~†È…iy@À´ú½EóæH´Ùw ‚f‡I«Ÿ(B$»uï‹•S¶½Ä_F­eNÑ:¿)Q‹uÎSÇ “¥êöO®—:ÞJ?~ºsè¨1áÀnpÂ" t޶ƒxDÂÉHLqŽi“}W÷|\ŠB5­é¿)kj¬r3E»)Ò´¶8Qý@Sà"÷@G³6êÞ ƒÑlÉëjÜÚÕvMazÇWŸš¾/OÀÉ8Ñ8™xå™ó}Å w)¨p—»µ’uµ7”SHÛ‰¯ÕЦ¹³^_ÍÕ•ýÖVŽ…Nah›„G>²Ç¶|4.E÷kS™AÚWb «d»†À‹¨xŒa™(65cIFÐ#,˜9²ÓÙU‰Â‘dCjÒ‘¯Š¦}ºR`6E¬ä\ítë‚•çê§Ä’Gâ Ò âl©¤;òH ZFSIF0C?Nü(séÚ¨ëÎg_—|æ…³ëic¤Yû¾/º²n^ƒÊø#õ[îÁ]¤JŽè'qÌ O‚py„bxÜÜrRÏf:½Ú4î’è^>(6 Ovø’¾¼IÏys‘G8Š%]Ù¶yÛÔƒ.kX,ë×ÌóKG]Ü_z¢Ï0=U>[»®™‘xÐ q ‚bn”m©kùb¤ûho^¯®‹ª4õp£î;Í0å ÁÔ—áÎ}FìÒùíŠCoué(*}ïR%¬º„ÀÿÕ£B0BY«O–>*øÞãâ÷ª©«§¯ûŸìe—i}‹BQHÌ%Ü‹o„›mÄ“s\^Êè"¾ñ!?ú‹•[Æ*»a¾ D•‰#ΤßɽezÖ;”ó‹bí§á'ì8Ù%Êqqa?òƒ©ýäˆ-jb—ÑË ]@Î&ñE´™#(i ê¡+ï÷ƒ±Åމ[ý½c.YRÔMm.÷}!À‚¼ßœwf£÷Õ ‘̾—VÙclh7%$Â[^ )8Å?/ÿè åR‘Ü2îËž;J~  Hš4CHH¢rR˜2Ó|1ÅžjÚ½ÙÐmÌYŒ‹ŒX°öl¯fÕ¤íà€ë—:Dab°hv;½V÷ÒVX£–ÙPB[x¨¢iâYLØöÌ C/U«7eth¦áÉWh ‹£Ä›„]$èäúÖ妄?(ô÷ͰUT¾ió£ôS•y4ˆëPVnŽJ_a18  +¶Êò÷¦é¤Pñv7¹Žð¦$!tJb‰ÂHúÌ0å€a±Ì02Eþ#}$‡ðmâByˆ%–9»¥1H'™š·YZº•FÛÔŽÜN3’ é@TÑ"ÿY̽©H‘QB,*Ä#m-z°¶1f±u¼5¡½6¨s§›9åø¡#X@_áˆÑ3^òÊ.yë ªÜYê ë¡'\ít÷y”o £rÓ=’yØWº»¹Æoh5þj·B5h>ÏI7‹xËý,¹¤áè\^8‡¦û¬»f_¯{¥Ûep-ùµŒ3 ÷—““„Þ@è›ó—NH¬x"™ð¸ih“öå©PÜXÂLî°ZÍQ"= 'ÉCê–Òí(9åŽ]³§¢¼@]•Yf7-ç@-d²]Ã’u.ľr?ÂkÞIŽ- '²ˆW*3ŒEVÊ%1*Û’¶]z•–·‚cŒüôýø²ã®êíäÝq 5gëìvZ%½—Øìk;8ØA võûÚ:Á=»OMÁÍŽ‹;¼ã³*„¦ëá9;ºÔ ¿Ûíòù6—ȃ(ÎŽ­BçÜcéÅò“œ FŒóåÙØ$²ã%ôs2Ù'ž‰ìr0e‘Ý›z½ÑÜ-+àçæ5k_°„GŸDùn4}ãI'-ÜCĪÚðð—áÛzû¤0)ɺ‹Rÿ\BÇÑÒÏX˜ì.Dû-¦£ ¡UôÒªè©èQxÿ›Êä,Nba—MSØ¡G$•dpìHÞÿ/ÆpD)Ù›¯ª®Wpzöô ‹8¸$¤+\ªiªiÂVÉ%Ž•cë2óÝëœEQèìÍ\1 _˜]SŽÃ»£¦±Ã,§¸Ök¦Úk>[;TôñèÃ: …ºA]Övè+zê„‘Àb„ë%–DÎØÁ© Û3Ô“¦ügy² yßõ}Ó s‘E€…8ÍE%wGVì]Ò3P,¤þ c)›,ØÌ12(Vf`b]šRÄQMO†ïxæ=ScÓ—’æ+Ö.”:*7TÑ`øÀôNIÕU9 ðoÆw¡Šý`®48jK U²åÓà;ô/ÒcvmÓéîIíÁu´úЕƒ÷ƒ'Å19þÃÙgu AbHjÏÎköÃCCkÍ L t7°Ô=´1fÕyëd}¥3Ø”]ÆÏyýœá Z÷ÑŸGÙJ±š+Ê> endobj 1151 0 obj << /Dest [ 1150 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 401 625 442 639 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1152 0 obj << /Dest [ 1393 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 389 503 415 517 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1153 0 obj << /Dest [ 507 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 284 400 300 414 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1154 0 obj << /Dest [ 1150 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 173 346 215 360 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1155 0 obj << /Dest [ 1174 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 218 279 267 293 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1156 0 obj << /Dest [ 1393 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 389 211 415 225 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1157 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1158 0 obj << /Length 2177 /Filter /FlateDecode >> stream H‰ìWÝnã¶¾÷S zSˆ´¢þ•v³‹ÅhO¸çlz¡ÈôF…,'}óçÏEg†”ä8ÎÏÅ¢èE€X¢Èáð›Ÿïã»ùìÍ|‚‚ùr¦Bðâ<ôã8H!+?̓æ«Ù›‹>‡ªç9ôU;{óñRÁ—~øA pN5ó†ÇÝLüR~Ñ ¢äü÷YÁ‹ È¿HÑp”ûi`íòš—ÓS’ÒêÏâ!Žza =ù©r¸¾‡ËûÖÜàH(´DK¢¯{xûñþóé%ø¾Áo‰ŸˆZ¢º9Ë]mþЛ†D¢lÒ+ü—ÿËßæ?ÎøÄ|š0ðS|™¿Ç1ö`·Ûù2ò•èiWMÛ¢iÜÒÇÇÀEå†nØÒ‡ùLA ³0Iý(Ue~žCªIÀ3Æ9lôl9{7ÁˆN ¢1¡"‚ÑÃÅ.F±Ä8!ö£(ÏÀ¾ fIâgáªAH6> ¥üW2÷3g¦^é­©Î%ž"'<€Ÿ"¡{S®ÖôéTæ̽ÄóÅb­¡[‚W—ˆ»¦¼.{íôã( ÁÃ*#üìÞ1ûO{±Õá ùa²Þ…æ{Þ«!%”ÇEך²nõêö”C¹ N9œúÙDòaJÊ ²FÎ¥ô"<”‘ÊÏ…{ée"L·Ñçp%Fx®ä"x6tÔ}”éh´—©Ð£Å[÷{.½s:û gUSëÖЄj.Îì„a·i"C†‡XÀ?(ѡép“†]h^ݵú ªnµ.Míí9H$ &æuÝÔæžN÷ "c7Õ¢–1 'BÙâFƒä…¨d‚+±6®»®Ñhç¶l¶s«y´ñÈ™htF¥ã>‹·TðE³©¯·ñÂW%È%Ìõ—Ò"ãÔl»V¿¥l½×ËrÛ{êü™-,rcöé»ä\ËEƒ…s%ºµÞ¸S·_ ¿ï^}ßCÓUÃD L²ðIlxb ï¯=6ÞSw.ç\èÑØÛ†®¢ÆVƒ»E{ðäSÕ¸¨/ôz£«ÒpíA$ ÌDì‚Ô>tí®Ü,ú±Z›Æ;x¦jN`ËuX“¦¤³þѵ”8FeÂ%¶HüokÉõ1…˜Ô-—ˆ¤JÒåBº°cC.O¥~¡öŠwˆÏä—íXÃyøi ½6`:0ÒË™_ˆ¶ú\_“•æ ›b*Ö€ôƒ[’»‘fKMßl7Ô´¾E`áÖØµ¡¸vï˜où¾×„à_ïß]ØÌÆöëfû¥nñðn‰õF#Fo¼£½JM¨»4\Sã@`)–%ö=Jå_çü{;.%¹ÞÙI+má£ô2>>/Õí®®nà'ûF±‰‘ZÁ©™ VÑGêsJØiöã•Ä€¡=$b‹ ÄnçÜ¡ öÙYo¤H0†L@û3Y &F8…)´®s<î8èÞ»° Ÿ9†Ï,ÃGŽá³‰áO`·Äα1©í˜<~[Xò#~gvO„³T6ŽB<°äL˜›ÒPÊÒt Ü5gÀ¶ îÚp k·àx«8LUSWÛ¦ÜÀ^òIJ„÷ÄeÜVRa+p°Ù• :)):Ea i¥+×1«8¾N %.A1¼ú#Þè!¡ñþ€$¿’þȯÑÁqŠñŽ÷uptHÆ“ ¦Åv4¾až iÖÆ‘8KK< Õ§ ¿ ~• Φ1¦tÿ¢ŽíÍàkja5±ºÊG-L¡M}¿9ÞΠl§!mGnÝï95ÄŒ³]Ñû$hŸ”'_UG“Žú çE úµ®êemÌ*z’Õ¨ŠQC`¡·/ЍoJ`>!Ò.ÿ}I,›ˆ? ÓJK¼·•h_¨’1ب7ù•E§•›ŒçßBsþ¬w,6}V˜HP‘8"33?+^§2#·v’ ¤mù.å.Þ¿lñ¯,H|#ÁB3êW8¶=c…ê'{ó’»´m0~óQuñåÎ'Y²,MH–j’¢ÒC*ä(ÓîÂJ‡Ê4> endobj 1160 0 obj << /Dest [ 489 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 471 757 487 771 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1161 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1162 0 obj << /Length 2659 /Filter /FlateDecode >> stream H‰äWÝnÛÈFoõßd˜4ÿEÇY.²›E­`ƽ ©‘ÅF&U‘²}¾C߫ы~眡HIÞÍ"õ(Š 9œ9sÎw¾ó÷f::™NC¨é|„ÊÇ?üÄYèűŸªñ$ñÒÌÔô~trÑdªhx¯š¢¼»Ô]3ò=ß°§¹ÝããHÿ˜ßDr¦MøÐD}o’Bp”y©/rùLÈÇé)Iéô'ý«nè;ny©ö3uûE]©ÚVBmHÒMÙ¨ówÇêÏÿrÜïk|K¼D—ޝ‹Å±º~,ÛŸÍzÉB"W3ÇhõwþëüeúÇ[ÌÖ„¾—âeúk¬Áãã£çD^ ºÕе+=<ú^¨ »´`IßMG*Õ(LR/J½,Si$lŒ3µ6£ùèÍt F`‹¿‹F®OˆhF¯÷L‡ß8õ=üïôÃ@z"õ¯æª]ŸZжqbèªÓª¶V­ãfÞ€.£n4LT33Ï7’›e{ã«¶¼7M‹µXßñL¯ÅorШ¢®̺53Ê8€PeTI“-¦…«7Y³`õs]±„Ö<µdgÏűv‰Q=·Ä6¨Û8 ô7F%^xã¨[3‡F™®z­ÙV¸ŒÜ#j¹@È”xЮ“ö‚-j³¼ÍUIÂÁ1²ÆÚZÎïßóê{'Öb@Õª9^èúDË‘{'ìyk…-ËÏF=uôaœè|i@HvN.ªÊAðËíÔ%,ïˆTE.ÒØ´H[Ñ «¥aݹ²–•ò®¬òeÇu²>ê¬÷ûõ#±ž¼ÂNÉUß¶yYÁìù* 8`aËÒ ¦Û¼1ê~Ó´Ü–ÝÇBº"¯hÕ’mž/ãméÛ|{~ 'Ç^ec%¯ÁÓ ¹kHðxŸà.¢³NFN~M*‹|Ý^hÏN?ÐZ^´²J ÂÆ J®@ ]AË™œ˜×k ˜G s&|ÆÍÝÒ‘5ÉzÒ0M».!7ÔÕ~Ÿ¶6gû9vkh{Ylƒ¿gøH%ð—Õ)ç›±Þ ³A’" ‚$ëÉlõbL'%8À‡„"öìX½–%#+ö÷ ·Ð%Øлz],Kðúlß—ïÝRÉíØÅä (ÄÑ?ùŠþƒ(ï@¨r$‰z®¬ )TR¢~ä!±Qµ°÷VºM=Ÿô9Õ‰X·ðÓí¦5 ½ú”Sdô5Çœ‘+Š›­~‘€Íù¤ß"¥"™ Ù×|˜Ê¡£ó®¯à•TQ ]Û5oP!üýÛ'?è‰,Ÿ.JN"-A™(æv¹²ïâZGª_ª¸P%§7*Û—TÛ­=±¦h¿íŽ#¢äiF§(°>¼}ƒô—â¬ú+-ŠΖ\N';nLe÷”<ÝÙ~ricSÃt¯¨ü=riS äYTõž«É9ïpbñvˆç¤H¦¯/®®ŽöÜ„Dœü*UOÕjéL |Wc÷¶lÕ9 :VäÊ“«ëTpSífY2q¢4‚0â: 4‘ŸÖ¨¬ë½‚Z,5V”k멲“È…5[²“:æo›òêK{LuÉ“ÊD ªÌet({¿Zõ Y/Óÿ¦É ]þ*¥L[x{øãj¾?ÿÇ.Ö/è8OdÉ41üô¡’`*ãÞèqçJl`#0 ©ÙËÉÜôãÄöXV³ú‘“ /sF¡ÔÚábYµ2욈ÚG ñàö—€9”p $–G»ÝÂn¸ý°nŸª+89Ò×Äà±þ0`×>$K'‘̉xÛ7A¿PPm{)²çãôÒÍöLAG8L©=sý´3åã”ëÑ%±`¢]nÁ³]S¨IÚ:0&!-_Î79ß½ £øépŸ–À=/ÎìžÄ¢ëqVÎKj0¤ý#¦-/2ÏuÕÔ8AY~Ez˜q¦àOHÚ.Ô‚3¦õÔukµí7ZÛ&ì+'Ñ窪‚Ô“6›•M0lÐn§÷nŠÅ¨UÍ9 É._.•t !ÇÞ „jÕ &È(4­k…Ô&ʺ’‡ß1½ ýwñ#Ï “(=L+Ù€ýDе™;î» iâóyÊœ°Ç虜ø“|,¥ŒP²ê™Y9ÜþäÒõßѰE­ Ôà£;(Ý7_àCvXÄm*}à®±4kY§Ý8C‡ÓæVÒ»¼+ÙÀƒögD½ûáyx“¢-Ñ»>u&âÈDwÎ5ëëEr õ]ç2éJ’g'82á”— m‚Œr|3SÜš?ŒÐ Ov*W¶Ÿ¥Ýmmg¼3™8xQYI2LµmYÝ©ºZ~Q¹ˆ¿¦hívšdÇÆáöcR^ðÕ…‘ ;âº3õà¾ÁXÕ7œƒI%îçƒ媦V%C¿ª¹%DŸÓ”·Kª7*$‘?`Â*çs³¦¨t¿XTÙ ú)+b=Øn/ë¾pú4pÕÕ\mì Ñp±Øî>7}• ºéÐ<±7¨9ã!BóØ™ñA¿g„T¨eöÌìD -ûÉ(>%ÛÄ?%­RRH„×Ô+ÅÚJ!2æEÁrìQÚ=Ä" ©œ1LìµYæ¶‘ÊÕJ¦‡œNt¢[n…Ëb³´çúl·×ûÓSªË>¿e¨"T®”Xñµ¡6 µK”~5Õ¬9;e”©Y€ŸìÃŒÄØ*;íEǪVý,+y=æ†é÷˜eÃ,ó&áÿæ,;ˆß˜e“ž2ÜlGYr¦ ç¨{†ß2Fþ7§×ƒo›^3[lgµxåhlí Ò°JHÙ˜Rýš™95DjF Úá11²º“1‰ùof§bËîlÈìþææuh„KäÙoP &£ûÞ(ˆ»Ža«:gkÉJ¨¥êí‡ë“Ÿx ±_Šú~•·”ÿ¥3üïêÚ..7Úòßrf yŠëå²~D4Ý¢°)ŸŠW(Õ2Ðþ¹Ì7t]ްåîÆºÖÈâãPÛ¼ßt!MM^r€4îóbo@Æ¢×÷[Axˆ^Bª²9(Ãê|EÓê÷ü–KQ.ʪ­eßâL`'ß@,Ž7ΡéÑä%çY)œúhS•O¶O²ýˆt»ÇCÛcÍTÿA'ïËjó4´ðý¥µ.î­;κ8{I뮡.8:RÔPŸêéa¤ñ7ºy`$¾Z¡ŠƒýÌýDË®{‡êþ+{ÔTTÜÁ.‰j3ßÔ_„Lr¡ä™€±ÝU:>;»ë©ÒÞ…ä‹ÍdlÖ6“}¢Ð<‡øÏÂ8ñù¡º‘æ…‚KRŽ>š—KsŸ6ë=š%øÔcß×¢ y.A…z˜QÙÜ®ËOÉNG²7ò‰Ó †š&ð ¼¥ :Å‚»:Úµ‘_IVÔÿ]Â7¢6í¸ƒÓ,@fÝw‡Ïý‘LÏLó¹­WªkUp°CöÆžƒRóÿ1ô=„ 8ì2q ™P£×Ï#ãçæ‘Ž;κ7l4&AwŒd0GTÑl0˜FÖ4P¡i iÐb¤`¥¿›Žþ=deê endstream endobj 1163 0 obj << /Type /Page /Parent 1720 0 R /Resources 1166 0 R /Contents 1167 0 R /Annots [ 1164 0 R 1165 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1164 0 obj << /Dest [ 1411 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 484 382 519 396 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1165 0 obj << /Dest [ 1411 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 351 78 387 92 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1166 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1167 0 obj << /Length 2293 /Filter /FlateDecode >> stream H‰ìWÛŽãÈ }÷Wö©´4ºYV Ìm'lf“m¿$ÝA Ke[Y]¼RiçCöòyÈ!«$«Ý=— Y Á\,•ªXä!yH¾^/^¬×¡Äz»Báã~â4ôâØOÄêzé%©‰u½xñ¦OEÞó_ôy³xñþ.»~á{¾`O¾pÇÇãBþ>Û)D¡pÖ]\ó¡k±ò½ë‚£ÔK|#—Ï„|œž– ¾—ÿ±ê†¾ã‘—H?›“¸;5z•P*’d_öâÕû+ñ§:îï¾-½¥,_æû+qw,õßUW±HfMá¸×RüÂÿ;^ÿvÁ³5¡ï%xY¿Åkp<='òÙÓ­Š®…h\éáÑ÷B™Û¥=Kz·^¢‹p™xQˆh奩H )`cœŠN-¶‹×ë Œ(Àÿ1gt}BD2zgÏŒø­ßÃ?sä9øïe»ub(/nz'‘ªÃK*?Úß[Ç a€hÍ«¸É«R5úöJ8/a¬àCf—Öe³%­ˆ× ad·N×XYU‰,Ïí˜æczŸi‘™J4­öÙì©2­`! ¡[‘‰ƒÝªÿ—ùPÙ…Ñgnà r öŽº"ÓY¯ÛNy ‚;¶Á{~ c/ŠÒ•0¯š~ì­ÂY8úË1}‹fxÎ.Ô‹×pÀM*« õJVÛRñzUô""¾ââ%09f§^ðnl]Âx‚ û±ÕÓËüõJV©ç§3½‚Q­Àhõ¦mtV6pHÙ¼ä¨\ÉI¬MëbãšmÂê^Þ0Z6H@æPâ¨ÛK­\>O€G$ÃÀ“Nð¤V‘¬¹QÆè±ü‚Áò°K#cÓ¶•‚œY58ÀIþieÂI™ ™™ôŠx FÈvåfЈE¼’T‚ÿ¾ ’¿âŒkÚFÁó öŽ|«¶ÙPicuú™+fæ¥y^S²i“XƒºioLª¦ §hfà€BNaJ\^åÐf À¿Ð†‚üiößÔÙá–Ù‹ qÜ«ÆÈ$¦! ÊžÍôàl¶±šd"hóÖ<N =(DD—šxkÉYÿHóÌ÷.ýfcF+Hdû}Äb¶Ù\ðÑqÙ0ó&êr·×Fq%Ú¦:á\kYÉT‰€ƒÁ`Ÿ}TÆ<ØQý`=wùÞá Íš*¼¹ýì÷{ù¡Å-,‡ýËV™Ÿ};àŠ TV—F¥“Qv•8;²æeÖΪæ(ùIX\™²2s¾mì•êo¹:W 1!E<²16=m’ÃoleÑ*+‡ªÀ³t¾š¼Läf:ËAËÃMá;EÌV•Y$|šÇòAoJʯ)Ëp…b=/ñÄvá£b€ôaäͶkk<Ü~HU·ÄõÈ#DÇù©Hk}ûRÜ >D¯bÛvBðë7à÷Hþg·ùu²àxq„ Å~°šhK-‡©:]™¢ÓO3H¥¶f²¤AmíNDUáíöÁ¹µ²« Ó1±*ˆÚ¨‚±’y¼3_åX¥WòLôFe±G¿gž;yÔ›£¼Q(3½íLX~å£UFpKÖsEA"wå¶Ì¹(ˆ‘UìsFFß<[fÎ5tdjÝùwCGØd¬ß¾Ãèæãr-AÌñeOE÷,t.ó[¨Âïå¯ÿI·ô.<¸‘e„)ŒS=š#mçZ*kðç¡,–+P›Èµ4f¢ãzÆâ^0¦eó‰6(¼¥zÕñíhœ#_b„¡‹Ù•gÁImO'i©í®Í¨³° h;ˆ öõ4}€;ãè|è:J+v« ÒjÜõ¨ ˆ>ÓÛá .ðžø®1Ig½ºzB,6L9ë¡gPuö`zõíúÝ üm†¨MãKQ(±ÑcT¸Þá’âQFü¯¿,® ÊÞœÈYŒçX𩊠¦õ³ö@<IŸ˜ >P Ï•m>Åvçy>»ûÃ÷7hU«†²$‘º½~jC„߈š•M¤Xv5eWNÎ'µŸ£xŠ£˜”’ìJ¢!c¬ÇåâÝzñ¯¸"[ê endstream endobj 1168 0 obj << /Type /Page /Parent 1720 0 R /Resources 1172 0 R /Contents 1173 0 R /Annots [ 1169 0 R 1170 0 R 1171 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1169 0 obj << /Dest [ 1411 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 454 499 490 513 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1170 0 obj << /Dest [ 1411 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 228 276 264 290 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1171 0 obj << /Dest [ 1168 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 392 119 433 133 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1172 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1173 0 obj << /Length 2417 /Filter /FlateDecode >> stream H‰ìWÛŽÛÈ}×Wtö!i#šwQ†aÀ78ÞÄ£—'(ª%u–"^f0û!ù‡ücrªª)qfd dƒûZ]U]uNõëÕìÙj©P­¶³0RþðIòÈO’ S‹eêgy«ÕaöìM—«²ã5êÊzöìýu¨vÝ,ðƒ Äšr6›w3ýûbgTÇÊ[ýe¶äMKµüeÁqîgÈå=o§VšÑîÏúïFçQàÍÃØÏt«õ½º¾¯û=F"mþe󥋸¬?z©n¼èaON¾ÓJš{ü¦ºŽêŒ4ä×zó…Ÿèš—ì°+^ÀÜ/!c\F>8à ºxK† 9ŠxŒOÏÆ-ÐðK…ÛkD\u¯ºbËM‘¢¬L8=[¦ÓêU™¹—à+K:ÜÕ’£!¥…"a˜Zjݱ¾"¶Ô[²TÈx×ÜÅÆ<ôáj„ÄüìÚ©gm½S7§£ï½y„Ýuy¥êF5˜VQœèC³±ÜØÚ²èq²Û ntm Ü<ç{ pÆyQ“ú¡Sñ)ÄFÎs=÷¡¸oj(A"Ä©¡"nSôÅÔºøl]x².ëÖ‹Íä¬D«aì·7ž:÷ª)Ë¡ý•d‚4qAšøA‚(Mü8ÎJºc¼fËÐòIê'¯îÜ0ôcìͽœ4ÑõMkw¥Ý˜šÇz»µ¦í^*ôR}£a®˜ä'qš“]Iœ- ÒÓ îÞDfUt=ËõþBC¸È}é…b7ÞsUˆfJ‚Æ›SÆÔwÒ·£œžè-¹qFÂ<Š"E"¿;+G¬P.[œåˆ2–Ï…¨˜DňkÚ“G¿˜öY”«7žoOä¾iê¾°µÙ “ž3`-ôI¬Cü Èá 0x¢Õ Š“Îà Oy„©æåc­æ¼ÿaާG_çN‘¢V¥(#z¤ßÐ#LÏ–ºHlšÊ@ÎmQ Âøÿee&!MLzE‘è¾oízèMGÝP“J·o¨,Œë¦6ù’$“>ë·f[ U/Vç_9B(ý¯›í–xdÏ„ Ã’»8×"SW{ ë¶*v„°Ç¶¹EmÔird$B„‡­²“|ßœhªß½Ú4õoz$¼Q=b½ë‹Ã±S”i)k·Wâúà‘ހ޾QÓ›ö€øT„²ˆ’н4H)ëzÎ)_}¿…rb²Ø/°„0I½—kMõ•r{1säÅíx€­®éñÕ§<ý³sçSï’—ž+vÞÆMM¬àbN—Ú£$aÍŠ[ÎAhnØ Õíê˜o»¾)ܾ߃Âß#]p%äÐÞ¾~óÄ«gD;›kœÃBYÖ(Ó×?B±\|óçÕ«Oïß­®¡Áº‚ã˸w%y}qD¸[[ÀM°À[P¨A›²á5×ø .¹JÂ~>eÈAåQDà(¢Ëj½ ·–'ƒÇÃMÜÞQ¬†sÊFƼÃ0=K­aʦ8öäìòá.7JŽ·Û Põ(/"U`tãùÿ¥%(ò‚i5‹¹Gé(mÉ„¥^ ÍdÆp•NS#oð'r`;TÊn9™xrySêã—§M€ܾ$µ}¹Gx1ÙÉa€«½oX´Õ•SŠä8¾[Íþ9ü“‹ endstream endobj 1174 0 obj << /Type /Page /Parent 1720 0 R /Resources 1188 0 R /Contents 1189 0 R /Annots [ 1175 0 R 1176 0 R 1177 0 R 1178 0 R 1179 0 R 1180 0 R 1181 0 R 1182 0 R 1183 0 R 1184 0 R 1185 0 R 1186 0 R 1187 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1175 0 obj << /Dest [ 1411 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 408 743 444 757 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1176 0 obj << /Dest [ 1513 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 196 628 237 642 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1177 0 obj << /Dest [ 779 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 385 587 406 601 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1178 0 obj << /Dest [ 1174 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 258 520 308 534 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1179 0 obj << /Dest [ 1505 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 382 520 424 534 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1180 0 obj << /Dest [ 1513 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 340 376 381 390 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1181 0 obj << /Dest [ 1505 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 345 336 386 350 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1182 0 obj << /Dest [ 779 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 295 94 309 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1183 0 obj << /Dest [ 1204 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 323 255 373 269 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1184 0 obj << /Dest [ 1204 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 279 145 328 159 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1185 0 obj << /Dest [ 1212 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 332 145 381 159 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1186 0 obj << /Dest [ 1225 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 385 145 434 159 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1187 0 obj << /Dest [ 1241 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 455 145 505 159 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1188 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1189 0 obj << /Length 2597 /Filter /FlateDecode >> stream H‰¬WÛŽÛÈE^õ ¿lh6IQÔ`0€íõëÍZ/‰Õ3âZ"µ$eyöCòùÇ<äTUó2Ò¬/‰aXC²»«ëzêÔóÕäéj*£V·ªÿð'NC?ŽƒD-–s?IƒH­ö“§/šTå ï T“—“§¯Þu×L? öä“Y÷xšèŸ³;«L+oõëdɇ–jøË‚£ÔO‘ËgB>NOó„N¿ÕÿñuÞÌD~¢ƒT­ïÕ›û²ÝâK¨­Iº)õìÕTýý?ÞlŽ÷ks® /ÐùvªÞœŠöw[ïXH¤³rãÍ–Zý‹½¬þþËx Ÿ:÷ÎÙf_”j“µÙTA}õÆ[ÂófdÒO/þ¹òàªH?ûåÕËÕÕfëUûcÓªmöÁz lâcÙáPW‡ºÈZ«n »Û4 n‰ý‹jZ,Ìœ+gƇŽäAJƒpȈPTÚÛ²m< ”j+U{±¿@ g!…fÃbOò±Àem%æZ>ÜÁÕÚ¶Ý™¼’‡g'ÊóCë…XRkè¾É­…äüᢼÛyÂ{õηHÖÐG`A‡ï<_òå»òˆý Fb?ŠÒ…’×>¤‡£„ú„ŒoŒÅ~l<[«kö%?ï³ÃÍ•Úã9Ô9 !BÇ/pðýÁòãwM¸O|îÇQ’ããÀ,Èõ³îNçûÔ¥%Â:kº zœ¹½é9t†%s¨•Ž 3]άUÙfE /åÆbë%A®ºÒ¢Zg rúšÔj¹Ä´÷oêÉJ•‹2¢Çü3z˜¡fŒsÒ5Åbª®‹ÒC¸–„#R0Ò9égtqho¦×kŠˆÑ·ÈªXWžað¡e{rÛZûȱL´V>º#Pç)ßSÎÐD»£²à°.$E]gããUÑ÷7Èå×ß?ç“/Ô¨$£Þâs~««rw?U¸îA@\ Þy_ q¤‹è3BbXØÖÅúH>˜‘Žäÿg""EóVsŠî ¦nåÄpmäºÃÆ3Ô gâj‹.Ñf(({‹DmÔ¶:1~%âPf»®¨ª[•1`¢àÈ E&BUvu§ SKˆA¾‚“àž¬¶Š‰s@  .I²øX ‚Å à‚%P:c,e ö/¬ê;68ú¤ÁV=é|Ø>QY GÔö·cQ[Ûæ`ó;ÖšìÙ銉 ÈÙ„ÔJ5š)Õ¸€@V,÷ÕEøŒÞé ·«à×ÿ€šàˆ ¤ÏÒ‘²ú¶ª m~AFóÔ7K„”–í[ß» ·Û¬U…Ⱦ´ò±æ«ÏÊ‚¥îû_ߨðÖ·¶P\üɾ}KŽá\ÃÅ^Ví–À”jþKêÿ×K¡ße¶·Sí­m™[ὨÛN¡âSpQrƒÃÉ9U²•Š8Ô¿ã½­eNÁ£,c¸Xî=ìÆ‘Ž„ò ßÿ=#0›Æi%+P‡‚†Î„•T†9nbHÌvâ –'¿l–JU,CN8°_Ø/tý3צa™ù`×¼kX ²å.T4üÂ(kå™ú¹û¼uŸPx»¢|? £˜08 ”† ƒâ;aAM7\h'p1Z–2£žè¾:îÄÜ|¦Ï‡F«C»¤kojƒ¹3—&&¢<@ÝÌaEA­†Š*ÕÖA1U%‘¦„Þ‚9[ ËŒùN×éÇù(Ò0@2òåή²ÐOc_ÑE/eÅX°e®nÐoñjìx6àX&ÐTK×±.ÝsNga´Qkn1ÔÃ3çÙü>É1 ÖÞ,–Zä‘Ä2‰³Û3…IfùÉ|ϘòÀS|Uà7öâ[!#¥O©º¹À¦nBMdBË„ó爿ó‡y?åÃ_ÝùEÏ_ûÒAfð€ú6¥3—Ò9<ÇÐìÍ<'{Ìá:Ò¶­N ûÔŽ,n«#žŽìQ¯@…0–BhNž£ªæ{”SòK’áHNW‡„H\‚g”ÓW?U¨îÇ’E0Éœu˜¡®WWûªi¥Ð•ƒ´ýzÄ;5k¨”ˆôˆ¨A³F5¨[ê_öÔ.ï»áA•ǽ­‹\m\EÐQ”{æ«×d*8?üw€:QR¶¼hU#ëžHQ¹Yeµå)Œÿ·cQ“¡gŒVEWZö¶ÍËJQÀëâîÈiV;õ¥õ×]³±PšŠà˜oÉÆÛŠ©Ý0ÈÑÊšI.ö®!4DëV”U×ÅVR¼9Uà_qž¾\Mþ;G¹¡è endstream endobj 1190 0 obj << /Type /Page /Parent 1720 0 R /Resources 1194 0 R /Contents 1195 0 R /Annots [ 1191 0 R 1192 0 R 1193 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1191 0 obj << /Dest [ 489 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 306 446 313 460 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1192 0 obj << /Dest [ 489 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 436 364 443 378 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1193 0 obj << /Dest [ 1323 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 171 112 201 126 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1194 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1195 0 obj << /Length 3977 /Filter /FlateDecode >> stream H‰¼WÛ’ÛÆ­¼ò+&|¤–.¦ä­ŠÛ唢¤JT²›R Áá0 ¸+êCòùÇ<ät÷IÉ«¤Û./ÌôLwŸ>}úÕbôb±ˆT¨ëQ©ÿâÏ4‹üé4HÕlžøiÄj±½øvŸ©|ÏkµÏ«Ñ‹Þ†êa? ü ±&MNO#ýgó`U'Ê[ü4šó¦¹šþ<…á8óÓ@ìòžˆ·ÓS’Òî;ý¯o'QàMÂØOu©åQ½=Vío"m=XÒûb¯~÷Ãú뿽I‚ß ¾%~¢ /ÐùæF½}*Ú¶)ÙH¬Mµò&s­þÉÿ÷þ¶øÃˆ=fo¢ÀOñcñ{¼ã<==ù^ì‡zO§Z:¦q¤ÇÀtî^mØÒw‹Q¨ 5Š’ÔÓPÅ3?ËT"’ >N3ÕØÑzôjÑ#±$8FÝ€"¢9z/¾¿JQ–I gÉÜ\†ô¯dñTãLç³ÒgÚ¦îËØ}ɺ=¡ räáwzßz)b;ƒÏ…7õ3]y‰?Óìwo–@Óo¾Bīߪ=Lµ^# ›Bª™êA­ñ3t?m¹òÕ_Ly°´\YjU^ï »R‡j[¯Š³ ¸\¦W^ˆgu¯í‡ÜîZg²ÆÛÔ¦Ìn'Oµû[˜v7î“·Ö­¤“‘ôN·‚ùãœì}1U•ÅÙ1]·õB€±®Ù0ı#„Ö•2¸7¼ç{¯T++UnÚ_ÛZxjk>dd{Ø:³´1R¥­Ú2bSÉŸ[³y1X»R¨„ [s°'7¢ÎiïÇÔå þSx?Ú±2-ßl®‹å¡µ7J>Y«–^âDS¨Ëú îÌõ½‡üε/Guàʼn½hæŠ,—Jûª°8-zYÖËK (É¡IïuÒ#ô¼‹ôk8ë?É@jYTÀH¢ª4 ˜­^þdóöÞcÅ ÃDpK©:a—öò6ëR-?p+J¬wæòd‘ÔlaeZs£N'ìEóç°×t²<¶s§&ÑDžxgÙô£©ÝÔl(ìÆŸFˆû4™êxÍpÖ1&ñ„â²,rãMbÀ‚1LÅèe¸‚TdÝ ðÁ’æòîCA@¯AÛÉü«×¼rA§²p Á•¼cࢬ¥²@,ð芃P†ùl€yBËM0ëOŸ¹.Z”¥Ê͸i _Q¼gšr­[³4î=Áb›¦nä]©ÎóCs£äx\«ÎÝí;îPŽUydt=JåÉ—iÙËÆró2%9Ïü!rMÝéï¶»ö(A" h%|{E~RßB?i¤~yÁ›w¯_éÿçRæ9P…½â¹ðYž£m—ìE|žhß#y£LQTõ^a1ГláÇî]•#&/±ÎέÚ„çZ±Bj‹­íß™íNÕdEnÃÉó¥"/£ jˆ~™öeVºé¥…ù³ú†v]k„’™r Y̰b‘…Nfœ>ð>¢aÑøQ§ Î"êÞ¹ˆ²„á»pLù0¤õQÍÂ_¨)Ϻ¨¢N¯1‹ÏžÅì’T<ë)n¤òg'`Í S /î³Ã!1þÆVÌuæ }Ö/¹°câGg ;H{vtSξul¢övgªŠÌ A‘**nM$@—VÆ•0qŽ77*oHU /·t©ôšBíxHú´â‹ºTßiŠÔ7cÂ]ªÙ«ˆø™tCkÇ·W3a2™´)bûyw‚­áLÐ÷‡Ðõ¾´AÞ"aòoÆŒµÇùÀuHÙ£i3·@äçVÉ'̸’©èg‹Á§*G ëµïPíd~8Äh<Deo¶Þc̸m]Ÿî:î`Fë\wºð¼\Ÿ “é[ÿÂbÜEi2HŽ{B1ª7uk¥ÑY“8ðÃ[“N Ä «ÂÒ˜qÄ#ë 3uB‘‚@daH>:Ö|Ëâì3°éà÷R^o…dv·òób; ÛŠŽj¹:g¼>xjÁr#ºæ€üú/qäc˜ .ÈH"Ü“TaÜ·Ø/æ*TÃüË¸Ê ¾RþŽUÿ•ôJže,"i¯—Lr=8œSsêÇé×Ô“ƒ[?Ö•­Ì–ÒpÌŽCTßkúLQ Ô>¯ÖÃîw91ê7ö‰°û!í º}SÊÒàPOH½÷ÀëÄeûÝqƒ³E˜2IJ3£»ã†S ¶Ú2Ã#ÖMÝ \ƒçä;ïÉwîæ%èµmì€éAmÜG§Âõh›S0 M%Ö[rP…-·Ëº$]]7[L:|; -ÆÂžµi› ¡fZoÊíª}õ®*‹¿;bZüæÓsg¬^¯i'j©}ÿÿŒqž{ñ‘Ì%šÇ’>·V%ÊÏG=ÊS¬lÕbT³b©ˆSxeG^ÒÊÊȳhÝÂË^r‡Š>–ÅæåÀd§sijà¬wR}@¦2]ZÒBôšz8t¼|´㹮ݯ“¸ÇæÓ_òiw¶ØmuïèÔ)è™åÉ7¼•Ò™LŸü”¯7Þ„µ®Ac}:´íÎÅÌs5(|fÒYÙ­(®ª®úÔk8ý>ZÓøJ]v“¸>˜Ì;…I†{ògj%b ™Ÿ#]Pcêa·ÇŽ®HûµÔ¼fðxþ—`â™SÈœ‰SÉð5º¼ŠgYW«™\êÆuˆ˜·Ï.;DÌŒ??u’ñž+ûÖ@ÁÇK(,†€0QßÔÉFÐ!Cnºæ(®þþ?ØÊ6 ¦†­ðþãf)γ×k÷À¹ÇÿÆT«’@¿£A$Õ%AŽBi¿ Ðİ|cv-“+îþŸGÀOSwØw÷+N˜0®Û÷›ú r¥qïÆ7ˆ5Y¸\¼-ªÓ*$!Ô´´frZx&aÞªÉûP7ŸžòÎÄEÆ0}^¯FW¼l-íº QŸœÈ%gáÍ@TÇÀ7R¡LÃå)d†Âs?s¨‹•4n‘EϦØU!K40C¨ƒ;O¦Yí]åŸî9÷!v?ïÄl-rHZÃýí±ÊÿøZÙꡨ Ô—‡–ïÕÝ÷í]#‰÷6ï™îêê©–)ñÓ²]¡í¤hÛª”H~8ñ™w…]Kõ|'—0Dfžâ¶íq³ÿ¹ ¥Î‡,9ˆæA<"!Ù¶IÊ"µÃ&+;*/UÒÍDCAF«ß⢉¤ø”éz¥ü¯ø…{—ôà>œc–¤¿!¾î_*L§ø:»t‡Åw÷<¾»!¾¾F-`GÍ1õQRgôÁõØE‡ï8óÏJ²z„mHµn[†ä=é¯JŒd^5µˆIÆÊÙ&fO¼ÜƲ°‡—z ¯§ÿ;AôjPùÿÓM‘= V& Fƒ<è XLŸD³Ã±eè‘iù.QWU ÿî1¾b°Z«“I,TÐC_ šx&C¾?e#2àcgmF¤a¿½=g¶c÷'þÅý%9øšâƒ E}‘Hpn—…Â> …zWÑÚ«À Æ–73ËñnžxdùÀè½É]y"é%æÎ-u·ÁXPcK)+Î):¯àôúœFtîEYäê>ΣÈDž£ð‡šhÕQª¥Óf"쟛VJäPÓþ_<*‚IRÇ©.´©Tm5¨U¤ D˜§¹àpÚ¬çiËÈoøyùcæDôáèôþ™ÓÐ ¨XÀMý9£ž‡Ñ<ôÞ(:gløœ‡NøÕ<¤˜ë Ÿpñ9n¢•q êv¯ÈµuAY1Çe,á!ÆiOƒ¶Ì踈²È—?~§¿âkû¹B½¦.ˤ$•€ï_}¸~ûÕ)‰ARœ¤ðæä„„÷'äì3„ôät{rº=9]~£¥¦ËÔ ˜š]±"js s›fñ4²wsxZŸ{áBtv™È-]¢±‹g½ F¹’CÂ{%ÖÛiTcwq,S³G…·öH:ÂZƾƒ ˜‡¨¤ú¬;]q]“& u†ð5JÖ Î"À“ìfIÒ‘ g÷Ÿ¦è<аŠ?Ç2é:Ú„õ³É8úúV¡­¤M•©=±±ûÓµú•3eÁ÷wAáOjÑÞ 'ÿ|OÂN$d@RµæWA÷.©Ü(ÉÈHlàj7³-<íb‹@aI¥HCAÑ­ƒjÆLÆ30æ§ûx ÙÐ-U¹=¨¶;{–?ò ßã„{ªs½¢öß+rµ>àqà*s(óT4ßþGXdä 9v%»•ôŒQ>™µ÷i¹V{:Àcg•RtKØôûýä­5Rò:9ZI(©Ö >c„–ª¢¬í…•œžd_¤ÊNÉ †0²ûéTYWùšž³»v«ú¤‘·§$jdMçÐZçñ–o^nÖQ0IÖQoY$–™“45½‹^«ë«ßñ”@_-·úr4êkÎÖ>xêQ†­Í? 6ßrµÿíg! endstream endobj 1196 0 obj << /Type /Page /Parent 1720 0 R /Resources 1202 0 R /Contents 1203 0 R /Annots [ 1197 0 R 1198 0 R 1199 0 R 1200 0 R 1201 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1197 0 obj << /Dest [ 1150 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 107 559 149 573 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1198 0 obj << /Dest [ 489 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 416 546 424 560 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1199 0 obj << /Dest [ 1233 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 224 490 274 504 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1200 0 obj << /Dest [ 1323 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 418 249 448 263 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1201 0 obj << /Dest [ 1505 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 149 199 190 213 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1202 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1203 0 obj << /Length 3970 /Filter /FlateDecode >> stream H‰¼WÛŽÛÈE^õ ½¸ ŒhÞDQÎÂÀÎÚÞ\ {“Q;Õ’S¤À‹5ò‡äòyÈ©ª¦(ifì\vCª/Åî:U§NÝ.FÏ‹@ùj±ùòð( Ü(òb5›OÝ8ñBµØžÿÐ$*kx§š¬=ÿñÎW›f乞çcM6šô¯‡‘þ)Ý凱rÍyÓ\Í Óø¤‹WÏ tf‡¶léõbä«\‚i솱¯Â™›$*öáI…;F‰ªÍh=º]œœúXâ]zcð®GÑì½ço@”$âÈÙtîz!ý+YÉb|Ó^ÈZv½ÈÎŒíLrÚãÛ™ür.œX÷ÆÚâ¬ñ ©5–°ûM±RyãLÝ™Vy™ÝÊñ}mVêàÌØg>1%ædüK¾¬[‡Þór£JsP2f²J^`HŸ ·w•¶é2½°¤>€zÿÊA´ÜòÄÎ$¤]¬ëÒ¢8Jà&ñ\M|—b×Þ0®Éͽɺ–Nåø‚Iýv"ý‡ôÝë?.œÑ¢~Ðæ:mÍΔíGG¾sŸšÒ÷‚Ø\&Q÷óBØ]C8zóÓéõ Ä@Äœ?à8RêIòÂa »=üO~1À6Ò÷´3ÖvOrQa9{{«WÆa|‚ð–¾ÄÂënÒC7¯  è¹Cmî9ÅÇ%ˆú‰¯ûêû…CòÚFOÿÅÙ·Qœý’(®Qœùg‰8î:=¡H!蔮葫ʠÛ#ÿ¸"_P±”ómœ¼S=V K5îÆª­¸X»1@©v8±Æy7†7&Ži2dyO‰*Óˆ¡¬ßŠSÊSÈTÎ@ ‡J€(ùÛé¥g¡”X¡XOØç’Ÿ±nŒû B¤`÷›ö_Í´¡6zá £ÅÅk]¤µ3iÙÀi+¾ÌɃͶêð(«V-*òÖÔÄ»t¿7«µìZâNS·†32Ô*mTªöé¤wfày!_û*ëÙ*[Ãq„ÜÎÀ¾«nß¾¿•J S2S3™þ'•R8ú`›Ó!ú B,¸çŸ‘ýB$_h;THiÅgÊ3®)×Ëö=‘G¨í/8ÈI°ÛÚÞPD'ú£sÃ!M>XWu_É/"çþ.*Û9;Í9j#½‘ •Ë”Úå›mÿš~2ª1¥¬€+ìÒƒ) W½}Ì5’D!™±h3V¨oÔx?”ec'OŽ}þÄ–w›ëp¢XäL&”&gWøî¬Ûr _c#tg²mZ2'z÷kæv9m¤í’}Ñm@³Ä¿²ŒÎëJ¦ŒÝÀ1*K;ùe·Û·lòý-QIôõ+g2ÃØÄ¡¤ÜÁÜv~JyDuom…°°¯æ˜¹þ)rù†úîÕïժʚŽ{)‘þ?œ¼¾Î÷pH÷pv‚ƒ^ñé1îGüAܹó3‚x«úd0ú¤}ƒ(ŒH1ð¾È‡’áÄ–‚ôà ⪠Lל„…C©”nPöuÛ”§ª,’r8RÊÊŠ÷â„*ÛÍ…UP=¨ôc2D†d$Ýí­ ™uѤËÚ(´‹úØ·š›&¸¦¦SÐS$øI >’žõ#æüˆ?ß [6ÐÖûÚ GÛ†—¶ùN(‹éEŠ Ä· õ7œ‹C'ƒt8Wë¢móG™$$Œ`úKU´ê»‚=êz ’¦gBa"æ^¢ñsZtæ2ˆP«ƒ³˜x˜ÔJ22qÄÕ˜ž" P%» _ß“‹õJ|ÁΪ²5÷-®b3]ÉcÏtÀb`ØOEôÌDû‘Ùa“_¨ÌtÅ¥û^Þ¨ËìðU.8 ýÛ©&rlAê>¥0i/i |Ñý³“§YwnI€b³j·ÌKœ©’*bKÈŒh–,¾.Ùž)ÓS àô\Á¨yƒ_Ž{#'ŸòÉI#-ecõBâ͕Ųճ•ecJ*Ï8ÊÑNN…ÿƒçЪ (ÚSVÍä ×\;>yÝçûzmjbG°å$®¦®zWµæ…â"áf´ýƾ¹žÅ±¸{ð¶&јö:â|ÿÉžNrŽ6L€›Ø‹š3œ?³šfÍíÙXɳà“BÞpdrA»¼“„pÿÖ>•WžÃEÊT»"çýÌ5.ÑmžÙe—‹ØÉ„³¯`–¸œFÚžHƒ.ž‰ÿm7:Ÿ³fÜ?Ј?kÍø0 •@û6xÏjÇôI´©œ¼à4œq†’†3Íœ’š‚å*ÏÐÙ¹“fýŒ“3!¸;ɦJ¶žzJ®Ü¬òš1Y‹bdߥñ’…öG?3Ãß2c œÄ,»Þuç÷°b^ ^ÃHÂ-Œ1éPÆ’÷mËí%SÍ€Ò%ˆd¾ëd±¥I·|2ûÖ¶<÷QÜi+ýÑy3T¦…í…„¬%¢‚ïìº~ *õäß?¸L5YïÛ—$pT!ÓÈw!—c³,^éÀè %n9r°7q\#Å£k@¬"raq"IüS»·¥î£üÔàâíÁ@´×&«ê õ˜}вéÚ|y$(¨Û7×’-$ ÿqîõ%ü¤×ø“œHzÜä_ÌøšífÑWëë DªU¨ªÚÛsh§88¾Z0íVh«ô>ßu;Ç'á«Ên·ìKu%ˆÞm1Ïz©nw?"Ð }.Ííø«,áÎAú‹VŠóíŽS]žM¿Öm;Ï´8¤GB@£H?;Tz«|Ž’j—©ë ]Ýakˆä³"‡ú!¡©¨×rǵjÚÑÞÈ-Xªˆ–kFû¸,­ZaR›g°ñX§"¥ò1R_E빯Âï¯÷:Ê>÷8-@PLs×%7ÀYÎÂ)"—bﺧÂëô¯,í8î"+v"_ð¸¼ïITJ¨Mõ‘|`9Õ†Y-n^;Сgé0«Šn÷áˆÌKbtÄÐÝÞR·‰ Šxl,©pÛZ­°²÷‚æA¡ Ä ¥F!p„è"U’èNm)Ï~ógß‹xá³ÇõÓ|8Õ\NE_§ËJW+mh9“©M-¨MÏØº«OiBéa}nÄõÉ?Û·ÆäÖåQŸ3]g&Uk® Äuï^œ“Fóõ©nv]BÕíý±ÌŸGÿ3‰M†$Ðã¶îJ*·WL†¢˜œ…S8ø3<1ù„d–Ç=!Ó˜0»ŒRhÈìqY‘ÜX™uŠ:ëeºhád5>šf ¸óõ)k¥ãÑÖ5­"e¹ì…?N6¿ÊçkÑJQ—‹­ÜG5GÿìäÙÙ,4q[©Ù›â~4ïÿFÀ2°ÂOþW˜&íkídù~›æè°\§PQÊÒQ?†>LvÁ ê/T"¦6£§›Ä†Œdõk–™Åþü%±æŒþ„ßdË"¶yØÖ\Fc( z”{ߢBýí$µ÷í}£ÊO,¨ŽûP*Ÿx£¿°+¥Ã'êœYm¶•×.±=(玟6ÜÐÒÆÉþ§™»™ssïØ0x3òE[7I°ãG¿–ûtnLÍ.ÚõgÖ]ë,Óýh·É^Ÿûç&VWÝJS¸‡3Ý€±™ô0ãñ',üA¬Ôãiè¹ql·)k¨tþØ>|C6X×E™V/”Kìêø?2’GÅ„:ݤ¸}­,îDE‡§‡íé!‰»üŽÇ©Åj•ÙLZ1«ðí¡}îw8d@B] 7FZKàÜÅä]¶¾¬'o8˜ùÝYŸl¡°‘Þ’—éÙúyë4j­¡Ù¶gŸjÌáèçϘ۳c7 Õƒ4öí¯‡í¿ß1¯jE¼¢4”„¦aä¦R"ÊùÅäúæòêýÕür"/Ët†F¬.&ŸçNl̦Aç·Pð}ÏFì}ÏPcSöÌÇ(ë7žÕO{øSgyZÕ¨_ãP^¬ð¶4OUöOzòê(™îiØ<,ÇFì#y ûh ²ooï>½½ž@öé Pó#ü¹ûjêB÷Q“‰§Ùc³( ½nêŸðkÄ> Z’aâ!ÌÞ_}>[mÔf‰;‹ÆKmÄ<ŒYbñÏ€,Ö]ÝÛQ#Q†ÇcøãÓVsn)œtt€…½oGÌÿ(`: endstream endobj 1204 0 obj << /Type /Page /Parent 1720 0 R /Resources 1210 0 R /Contents 1211 0 R /Annots [ 1205 0 R 1206 0 R 1207 0 R 1208 0 R 1209 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1205 0 obj << /Dest [ 1174 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 284 550 334 564 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1206 0 obj << /Dest [ 1513 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 338 399 380 413 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1207 0 obj << /Dest [ 1174 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 400 304 441 318 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1208 0 obj << /Dest [ 1513 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 404 250 445 264 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1209 0 obj << /Dest [ 1330 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 102 102 116 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1210 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1211 0 obj << /Length 3034 /Filter /FlateDecode >> stream H‰¬WÛrÛÈ}çWLñiP%B¸t)®òe³ë-;öÆ|ŠJAàHBB\­}Ï/äòyÈé¥­¤TE æÒÝÓ}útÏëÅär±”¯7?Pþð/Ê7мD¥óØM2/T‹ûÉå›&SEÃ{<ÕÕäòÇϾºm&žëy>ö“Y7ÜMô§üÖ(?L•³øûd·æ*õÜyÁaæ&žÈå3§QœÐé/úßfgçÌüÐM´—©ëGõù±jï0hã@’nÊF½úñBýå?Î,Æ÷k±ëÒñtqw¡>ïÊö7³Y±PçÕҙ͵úÿ:]ü<áómÏMð±x‹9¶`·Û¹Nèúº!­†ÔB4Tºzn  ;uÇ’~XL|UªI'n˜ø*LÝ,S‰O*Ü1ÊÔÆLn&¯½3B[¼Coì½ë‘G4{ïòþ8D¾‡ ‘'Óxî†þ¢¯îóµ3ƒ0]å÷æÓÅïÿöÓTf6æÆlLU˜ÆÎüðô3= ]/óUšúø¯ØÜÑO®ÆI¿03\½Ì ¢³ÇŸXîus|xч†h|øä2¼=ð¢³Ï"À:ê|Ö>®á©¦Ý”Õ­uÕ}½ÄÔfg?›ò7|†þôòåØ_1`×ë%?ŒÌ:³~hWË0€Ôs±üôÓÇÅDZ´ó#Ã"¤ðwì:½|Æ]~æÆbÖ[„J¿‡jØe޾^Õ×´¶‡1롵/úÀ¹ë‘w} =¹Å^0’¹“Ün¶U‘·ØYÕÓCÈ"» ñÁÊÀ AæfßsÙõ?d™pVêE47\]Þ”fµDˆÆ*=ÐwÅgW9ƒdõ;túøËnx3Ⱦ“BgÖ_s‘ˆ,E®GÜ0ÌR%Ÿ«'‰G„¶§u¯§uÏRõ}7ŒÜÈw@yÚ øŸºÊ·mÍ®äBýBáÛIÝT×3̪²âm­ÙT9Àç£M‰®AöêíkÅi„Öap6¦ÌÞÊŒXéwFZßÔU›—•YBó æúT÷bm±LÜ´«t0`\÷®z`w÷–ÌøÌÌwi÷[«:¡ƒ_ô+ª_‘nAB×ÛÖ4ôékR=Kù¬Ò Ø„UÙ8TÛ Üci¾åòY9>jE¤î­ míë.¢$Ëzƒ9ŒQ¯‹†¤kq‡"Üæ·J‚Ø–E¾Z=ªûÜIœu£ðÙŦ¬*©êÌkU[«eÞæ×ycgW-°“®>×¹3£Ê=Ø òéjwoöm¡Ø†Óðf{hBÙy0lHc?ጊ†@> (Õ¼©¬y˜¥F‚âA–‰©>u§¯z[­Lƒ¾ %ÿ³\«Ç!PAv£Ãnܨ÷¶¿÷¶o½Ýn`Ø\oÍ…jà`_£®ÍªÞ}u\õŠ<õ Piòï‚ÓøœA\Ökø"·óSùoÅR¼Pi5×ß(É|]˜uk…Ö@Nªe§jKøJÎ:ê~mEîîÊâîH! ÒÒqôΠx*:Ã?uÕŸê–—·êŠù᪯IÜé̸{i`.µ€XªÌKÄCdÀS¨i®3Ç8DH"—lŠ`ÄWGy?ª­Ýjí%A>KKAg¤-UQÌŠ»¼º5§Cçï¯ci…DgìD™ªoÐ\Îb–ÿÈO2KÖû>:ŸšJUÆ,Í’òÂ×ÈÜ}ƒÞe%Ú´ÇíTåý,7æ×m¹!¤TKÕ¬MQbgÃÖ’kø˜b¼B—ÀN—ˆr&$ÍO]w8øÝv=,`·“ çöÁ.°¿£¶„»$D(Ór-Ór\ÚÄ 4§ÜÔnÚ:põ”“7»Ïÿ!äÀÄDÞNˆG¸÷ß à”ð9N!ÅIM+»•ÓBOí­Ù_'àîÍ÷á˜Ëµ*Ô†i§´©'¼-HI)2´ —ò êHh´*%¥Ià]øÁ?Ý DÑ•“çÔô(˜S8¨éQϲÁQMµò?uD´M±)×íËE3áy–¯Ðó©¼à­hbO_ž¬à‘öÿ‡ ~ ³+⮚ׂ¦žL i™“_;õH”ãàe˜éÏ _Þ³ UW«Ç A¡Áu\¼8Ü3ºï¨Oس‰}—¾zÈK‡­O*Ž+¦óâü Ï”G æÓŸ©ÕõGõ`6MYW ›yÞ¦A¹Ízy™u;ò̲x=~Âë^¼Ï‚˜)@öi·¦”ëº^È}ÈW[óŒŽJk˜WŸE$f¾µÎ,ƒ³Ä¼ä)óm¡óP;²Ýº×¶r€°4f$íL0ÜŒóHLy†T|©Ö¶Gq€ÕÁ|i";tü¤—’ ]ÕÕs<- ü¢ßš›|»jÅ¥ÙwTÌö:ºÑŽ´)tRù;ÛÑl‹ÁwœŠD„‰0¦hLÃlÄÍj)3j‰W´¼Å­TW&yÔ®ŽWA> ì¹XHõ­m-bÎg!At‰FCqs«\dòM»•“Ð>'üXîd¾™±\"5ɾ ”‰ÚBôr?A³Ñº/П«âfßó.eª[ð!÷Œ¨~N¨s:ÒÊ7˜¸0N¦åK~©²ÅÚÖtKͼ j¨+@YslçÄ«Üf/M±bÏnŽHŠKÊŠ*R~Sæ×+*q6$‘m¢º¸tP󻃖ù€ÔÓ½žTôpgœ¤!_†~|ˆM5e}ãF·iuæÉç t}Ê"oÑB{™.R~{Å’€)h:ïƒ|À'Ò-Õí”a*Þ&Ñ-ð¹R‚Ø‚÷Yâg5-´¯e jÞÓà\h0µ4X?·¢–UÁåé ¦­)Ç´-«4¼Ï‰v®…F¹í@`@3å’zÓmU³„…\p±¥ö×-Ë‘jD‹¸Òÿ;®ÖýhŠ aókQ­,aÇ\ÕÙ3!‘5)¡—ìÉpó똺ØçÂ’ÂbèeìJ-Ó g •‰òž³ñ ‹j—s›sÉN5“2•[¡$̲©üv7é̱B‰«XãhýY:Ç܆,é¸í€Ñ2f´ã†ÏhœB\ÇCtàñ¸Ç¶^½Ï‡Õ¡Ó% ¯bϹ‰pÉéð ã\›a/Ê›ºV”±ù_ÊËgAãwŸ’¢èÁ›oàÍ“ $(&j ooû}#˜x¤Y×´ëŸßB,½1D´ì'Æ©Miwl$) ¼GEIw]‘&|æ²ð f®z*ä!VÑB‚Ĭ\0£Q>¸ãÜÄ\O»~‡ ñ´‚?(å9š»¡jM¨’Þªn= ÑëË#\jTeF/‹à¤J÷ÀÍÚ´ ô×Òy0 ¤dê0ÁE;ç‚×\›ûÍ=aw3µÒNq!,hÑÙðm‹c$mPr øÍ„ÑÓ;¸Û¶¢[þZåç¥Ê5ܧJÎû1A†Mœað‡Ù‘zª²3i2 )Våê•Qu.TþÁÔ[Öb*½Üx`êýaö`6‡õ” endstream endobj 1212 0 obj << /Type /Page /Parent 1720 0 R /Resources 1223 0 R /Contents 1224 0 R /Annots [ 1213 0 R 1214 0 R 1215 0 R 1216 0 R 1217 0 R 1218 0 R 1219 0 R 1220 0 R 1221 0 R 1222 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1213 0 obj << /Dest [ 1241 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 386 743 435 757 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1214 0 obj << /Dest [ 1323 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 248 694 277 708 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1215 0 obj << /Dest [ 1323 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 278 660 308 674 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1216 0 obj << /Dest [ 1323 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 272 598 302 612 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1217 0 obj << /Dest [ 1323 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 494 466 523 480 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1218 0 obj << /Dest [ 1393 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 219 430 247 444 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1219 0 obj << /Dest [ 1513 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 350 316 391 330 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1220 0 obj << /Dest [ 779 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 362 208 384 222 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1221 0 obj << /Dest [ 1513 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 261 181 302 195 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1222 0 obj << /Dest [ 1174 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 131 87 181 101 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1223 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1224 0 obj << /Length 3787 /Filter /FlateDecode >> stream H‰¤WÛrÛÈ}çWÌ‹+3)Æý¢R¹J¶dÇY—íHÜò:ë<@$(a—"i²¤|Hþ!ÿ˜‡œ¾¥µ£ª”eb0˜ééé>}ºûålò|6 M`fËIÿðˆóЋc?5Y‘xiîGfv=yþªÍͼå5¾içëÉó7ç¹l'¾çûÖÌ'Ó~x;±ËËÊQnÜì·IÁ› “ù^‘Bp”{©/ryOÈÛi”¤´ûWûï³ÓÐwÓ òRëçæâޜ߯»+Ì„¶rdÛº5ÇoÌßÿ㦠Þ|K¼ÄÖηó«s~[wÿ¬š ‰l¹^¸iaÍ¿ø×ýcö× ß˜oú^Š—Ù æXƒÛÛ[ÏE^`[:µ¢c!Gzú^hç:uÅ’Ng“ÀÔf&©¥‰2/ÏMÀ’wŒsÓT“åäål0F`‰¿ou}²ˆeëÁGùCõ–ÌRçèf²¤2Èr¹E½v1tíð›°Õr{‰[É8ƒÅüšã³³ãÏoßóˉ#[þâ ¬úb]j¿8üò-Gp ¼ Vƒ‘דáàDN6NÜ4ƒŒ—.…¯Ü4ÂÃlÖ«ûCsVu78Û®]Z›9ÏÐ;´ëΔýD‰ l¾7õzQÝrTƒkñmc.Ê–àm‹/ÎÜ^UL’ÅËÓÔ‹C3…ÆQ¯/%ˆKŠPômªrQ¯/ͦ1·MÝÑÐá˜r 5šÒeöÞ3oaÆœ•,ë|´¬×uëtWò˜7õ¶{a`8€#²2Y!/н8€YSëeÐ’ö7dÖ¿•«›Š®YñٟŸá.ºT[Ú¼¾¹¾€ bòàfébK‹Ù«ôËFK`4y­æ, ~ÈŠ! ô-E€,Œ® øYw]µöLï{…áŸØžYAödÅ¢X ÒˆTlì^zSŠÕ† úñ˜ Ø3Š×Ôž:H*ìû™„ïO´!ìg?ÓÒnþâb¯ðŠh½°ç…|.à%>HéJd²ß«{rŠ T^êåÅN¢ŠаÕvHí¼\½=y ŒŽ Ôˆd+\¼qÓÜ.9öøøkFj ›P,|)$Î2f'Ñ€œ¿XÙP^W²L0¢bÌ3ý;B9&W&ü­¾M%\B" ®™  ¢¡x, PÞÉ+bΜÿíùzS5u%sF—ªV€:à ?(2EH£(©% ¼g¤ö“àå'ˆN~`ý2r/ÌFÈHõ(?‹÷°‘B&a)Äe@ˆ)ͺºý:r¢ðÿb➘?ìápÙ‚KÐ!„_®º±m»ª1‹’xQ¤OÓ.V§5‰N^3ÁW`yg¬°,Áà³_Ì€‡$ØgÄ@ýâaD¾Ã!&@ñ9G:òŽu#ˆð*$`XX× Xr&AʼngÞoº .;ÓQ¦È¢H•¶V©sÐ.e sQ™ݾ`j·Ãe)“0Ày´¹˜îQeOCi®•DW‚¢åRò +X°‚±]·Œk×2adq)¬¸ÒU8^xZëʃ!×À€î'Eé ò…MˆéË~©NȹzL‡ RzÛî-Á!ÉdËæÚ”ó©V0CTïMFl€› +J mÕprkˆk-fº’“,{„»xuOÊaï†8Üeƒ„³ÙcüÄö1Es`ÏgBûêœ"Iéw’B=Øß8PZa«‰ôJ˜£#Æö†82¶ÍZ ݑʎ€¼T“ÒžF¿’ú(囊ñS²™b60Z %4cÍ)Ç„ùÆðU¡}€ÒéŽ ]„¨d+‰ÓˆXd?L×{9|«o’ß5N‹!Nã!J3‚°_yÀÌctÛ8Tìî1¥ƒ•:j!F¶K˜F¾TJ¡E4ŒPÿtöv†Ò“Æo@¾ P#={<qÒZ$¹£L£‚ª•ÄÚ50o½4òŠz=²T™Z¿ƒ·W´e(®yÔ—~.§¬ ± ÔpJY>&QÑ©ù6 H!§r—åJ?ššËè¥ãDS¼>-Ï%ï´ŽUkUç:ª’Pºâ ŒXÑ^še‚`ÍË®E‡´þ†½iã,éý±t‚MÇ:ÀAÞäQȾÄÅÙ¡=?=›é\šR#áøñ¨‹  |TD ´Ñ³·&lŠ 5—Dʰ̱™|˜™UXžL‡Ž¸Ó½# TD‹Nyb·½ã ¨ŠŠÇEÍk%]p‘m“kÑðGßé:²¾ëïH˃۔ @J,_sÊ5Ÿ¶²À *BtÀ´yˆêl¤Éàþæf -é^Õneb ®DÆY5Ù‘Ž"¢‡ÖÐxszõ­Zëá?HNŽgNK{êãè°Òp§7ßH£F/dÎ&¨»?‰\sô¨|a2úªß½Û§[®Ë{0Y¨±æïÇYPìî¡LuYuhëˆôÞ³» »ŽÊÑjñ¤L§aç§3"YN9¯ßR&‹­¾Î$¡:íˆì‘:N…|N@õ"ÂÌÏø+Àw9ÊÍ8w„>@t=â«Cq²ÄO½¢†""?œ›8Ÿ$…(â‘$Ba9ûm¾%ÐÓ„}Osh>œPÚŽìKî@^ûq¥v(¥ëŒ§¯\hkíQ¸BG8Mµ4.¼A&¶ŽzŸZZ¥{ia‘O9=c¶=5óUy£›AνÖqñ Æ‚—j%PÝm›ªmë ƒr~…0!ˆ¯QZB“²5Û²éÌfɸvüÚ”ë…yöéµÙ®ÊyuµY-ª¦E[ 047> }ćAßžªËß}xsþóËóÙ€Õæ²«îºÇ…jõ"ß9%ŽT¢Ÿd;ŽäùÆ‘ó3jÞ8϶®°æa;&ãÆ$ßïg(Å]v䪹ïºGm g^ &s[wWÜCdÉÖƒ6ˆS5¡ZŸ>– w)”»V5qÑÀ!øùA]ÛWuG·Úbt,&­ÁWn{V/¨Ü·H‰…-Ж¶jZv!/]ÝÝPIÇ“ßË­¶8Aê–É}ÜÏ”錒͹ø;g{ vÄ-$¨âÁ>.(‰¢<3òšù^‘"&£•/19*àµdØ‹GM¢ó„¸¤†\L¬ÞΛÚåP•>v/ÍvÓvÓm³á‰9J»€z7ù]uMy€ç|T “YYËåéÀš^%9Ý,üh•”9C™¿êo©èßñÍpµ"cܵ¿ÚP&ª/_mÖÔqãsÈËvxUÀ!úÓàÒk…pD¤Î±Z-®Ëí C)®w„{’7(¡'ïNÝ\¨. ìG•Ñ QZd_1p=)’è">¸’W? {Vq?Ï£ :þV֎ܰ*/˜¦WŒ¬êðûWsGC'§ì‹ÌüñŒ²Jd?˜o(0ZËê~_§èɈíjž‹ÄüÉÌÏ2¢Ñ½Ú9e6¤çšZDTY?¶‹èP :(eœÏ¹¸%5ˆmz±eÒÿít9â“àè¥Áؘ©D•,T€#‹<`Y¯ÇëÃAQ­ÔDEÅ%(Ü£Cë°x`vl© :Pþè§¥×ÿ2^-ËiAðž¯Ð-¢Ê¦" Y(å├sñÍ\d±6¤ÄŠ"ÇŸžžÑ!Ǿ`ƒö¥Ùž~D|ßžýÞ}_ªqèk?n½©J+Ãî¹8UÍwcô0—u¯MqÁnÁ½!Ùr«1åÝVÒ7«!öæ JEÑ´«•É´K2mÒYvÚýÎÍÒéQØ8—.äÜ©‰‰és³éKúCwË1ð"þÖÌ/Û9–//'ˆ(›©—á÷{!Ó$ŽÙ8=ŠžÖ#2Öž‹LçÈôßoçmaü㎾¨HÐ_[×.ƒtáöÃ:´” _rú}?T%°µó«Ë Â_`{h |U£’Áy&YHÒ,Z·xªœ­mþçÊ/¤ó»ä'—MwKXè˜ZýI:/“iN\×ô—„AZŒk “†ÞCMH,~ ‘Ó™¢ÓnøNr7ozѾ œÙy½T¤A—Ä@áeùUœQ l#°¼‹[ÁÈ2\e×'káY·øáy´‡¥H–£Ô£†§ªbB “ªà¹T6‰-¹Ö{5Ý’«ä»~RD›±¶©öIyâPå´ÝtaÛþÉ¿:¯l5WHaDØMrc6^Çèn8Á™8e"²=•ì&š ÉˆÖÆîÀ`®¶õ©Ú¾n$›ÐæÏ$ÕhuíUè‚„D‘„úÉ#gD‚,WêW}f[š×D=Áõ}Ëê±¼µêÖ°©2 ñUŒP­#Õœ÷f%òðm=›ONÔ' Ö5?Ðón‰‹`3Å¥^þÐç‚}·…ÂÆ‚þk?àz„rÄܦY‰—vò\O.$¡öó÷iF 2ÿšÞ)æ¸$a$/iJ÷WYj/*8_ ÓÈé7A¹-ü‹´?Öœ„BÜCڢ룉ïXãÿ€ÛçÓQp=¨Ø§®ß)ŠûBç,tª…εйZ¯0cÅâNæ´&ùªÍ•¡Ê“þ&uʤqyr0æÙ†èc]HÔ‡ <¹æÕÑÖ;ÝÎÛûöíg¼VB(¥JÛnR ưEWMO½R–öíðIÀ•°–è¬ÝþP9 'ðe6ó@¡Xó2ƒMMRP–žIÃ;·‘£E-l5¹rA“¢PÝÑbojŒ þõÚ;Àpu8àÂ×!3ßt&Äæ^BÓùPDÂUµ©åXrÑ©kô­ é…8ˆÔJk,HoJ-çùr`Æâ./ÅVÕM!†̓$Áø=_Ka6Ó–fýëe­–Â’¡’Û8Òßt´·!y'–ª¦TT©:’}E1­Ô¯úL^3ÚÓ7»Q¥dä…ò¾7Í0Çb¾1ݹ¨N€ÂˆçÍŸ 5)d×0M¡£mÚ®#×¢lN¸Úµg¢w~}Ï£žþùðåߪñÿ endstream endobj 1225 0 obj << /Type /Page /Parent 1720 0 R /Resources 1231 0 R /Contents 1232 0 R /Annots [ 1226 0 R 1227 0 R 1228 0 R 1229 0 R 1230 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1226 0 obj << /Dest [ 1204 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 472 757 521 771 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1227 0 obj << /Dest [ 1513 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 350 655 391 669 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1228 0 obj << /Dest [ 1174 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 131 479 181 493 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1229 0 obj << /Dest [ 1204 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 412 121 426 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1230 0 obj << /Dest [ 1513 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 275 385 316 399 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1231 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1232 0 obj << /Length 3048 /Filter /FlateDecode >> stream H‰”WÛnÛÊ}×WÌñÓ°èÞD¥>''H6A¢‡¶öAAS£˜E $eÙçCúýÇ>t_†Ñ”ŒÂ°ÈáÌìÙ—µ×Þóa5»Z­<¡Åj3ÓžPð öÜ P‘X,C7Š•/VÛÙÕm‹´¦5JÔi1»úüC‹ŸõL¹JiX“Îæíëa&¿%?ÐþR8«Í–´i)Ê]F ØÝH±\ÚãÑv| #Ü}'ÿãÁ×¹§œ¹öÝHªX<¼ˆ/Eó_Kì}ûŽæË¯âÉT5b•Ô=­“ßË‹;y6n“‰bÀîϸŸdø»jÈ‹IÀÔÞð ë°ìtX²”i•Á^TÃ<7Î<×°2ÑXàÄà CLŽà蹪vï$ÒÈ<À”ÉÖîÒ®÷:E-U²ŠŠgd¿…|m1òýräv†l‹Œ^ ›ÈdéŠCMöjdµóö.(ýв§Þ”§‚wò£Ù$û¼a—ÆoÅ—ÏhßxTŠ9‚Õ˜âÔq ÊMWo¡[™U©†ü…:›&yLÀ„&ê&©ˆ£€“Èl"ñT&-«µ€:5Ê ×$S׸äˆ Ò¤Æ¦¯;j wËEó¡tdÄ-lIqÈ@̃Cq1ȨÔ#ë!> Rb›@j%Ís²Í0:ðŽßSàZ¬ûšš ès@™mk!*Få å$\bD†‡*h³;X,;ØÐ;¸7¢µ¢1E[m× {¢Æ>ì³6îkœ¤î#©»Î;)´ €š‚T.} Û ƒ•…£½¤`ÓÊãáy#Ò=kô@¹¥0c²=Ù%<Í‚¸6ƒ€Ó •2ÃǼ(ràØ;6¤´Ç}v1D #ʵÀòAÅㆼhì “  Æ:<}0"Ûîr³Å3Z@ÌÚ+êPJ"{±. V—¤ÝÊ[‹§´aW³FÕ4{3¦%À%ÉÉ)z‘<I^ÁrJ€"5€ÇÝRé^B_û(¦óª‡:ŠÕ“Ê=ží8\}ï¨P-àäDä%äªx‚m5 )Ú¬ @ý!7zÒìtß»ËxÀ:^×x]2"3B' %“^îÜ!ùÛJ1îö‚ðl›€ñ@îFÄ ŽôOÔ&pa[sà'öS´'µclrm¯ËýwØZ¸l‡ì±áOI¾Çp”!¢›Nå/Œ:$ Þm7© Í@DZrLéB~¯­TB: &· 0&´§×a$BŠ„+ÞÄ­žÆëL…´MsD §Ï hƒŒK[z>ʳ´Ì÷[ëk\ÁãOØr‚««Þ ¢:b]#Ž(¡â” úìŸôÿSÚëË$¤Ë– å¡Â·¨ð[T„Œ ŸQÁWŸ°¿ú„Ò~8uõ‰ÜhXxuÐõÆMî ~4Ør’ÓÁ~õ(èR‚Ò‘¤Ä8—dYïÆ—¼÷¤Ýe‡Ê¾.ŽFTØ·‚ÝÕ„îB#W÷×Ó1—¾¦ ¯Ø‚Ë[,S@™Ø×¾ÃJQˆ=±胜\ï0pceâá_⢀;{ËcDcÜÀ3_)GÉ{ç² ¯Æðâ^ /Q…ƒK# nš@¡ï »OlÝóÐ*ì9Þß§Fe»g'õ—QŸð í¨ÑÀægm 7Ïm¿Ãk„yÞåYš5ÐÜË4 ’€:Фxi;,G¸H¤Ø;AþŠ9T…ç K¦†šB›°±Pº.ò³©€¢‘ÆÙt'¡™›í®yáB;Ç:[íÎh÷'\ê¾öÉd¦ö@Yô@Yô™`¦Jf×@æyyÀ³± Ûå]' q+¬-üduYÃ#ÊaÂ|‰3P < ¢d±@ÉðÁð*þ5˜‰±åù»M$9ž‰˜A&-ÈP=Ýí?صÌ#G:@Ü&½‰¾Û h4ÐÞÄöP1#Â*cy6èyvªa & ÒkdzYiŸ4ÆfcɘŽ$P´mT†,̧Ø%ϼÀ•¯6OÍXMDEë6, \©| ËÝ0Lan;ü2á@öokíx_÷±€¾Ù¾­Í.‡í(-·[HR;j{¬z€ÅžÖP9™:=ý†¥X·–nz $(ˆcœA¶ƒ ±bŽ×Ìç7cÍ£e… ͧ§'5ï2'¤Ì!Å%“8)qsýËÝíÇ÷«÷w˜‚B8£…0Ž£ìÄü´û”²ZC \]ud¦tÙÛTƒÔÃÞ½Û ]oûþXæ}ï«.xäø·ï_¾~ÿ²ú{ èq ‚ó虞~Ã|ˆž«ï_þúy¬Ó?WŸþ¶úÓXÿ< ¦§ÏÂâ÷ßo®¯ aÁ{ 'æÛíú¼'§§Ï+¯†ŽÜßò ”¹§8¾QY;Â^oXpFáRçÃ5=}žyô²×]{_4î$|¦r’ºÊb¨ôú[oÔCWŒìÒËó@85ÿ†eñÆžmyÁ|š4u|f'¦ÏÂL/z˜ÉëÅŸbN½8üÓç‰CGÃàù­õÂýqÜýõÓ_þGz­ ÃÀñÄn]·á³8a   >*ˆúà7ÿÞÍ­kÖ&©âÛèQvI®¹dµÙÕË‚¥Šö|ª±Æ{Þ?ûï¢÷ÝÛ½/ÕËεòÀ=QFP³|=ë:âQ¾ÜŽˆC»‡Šˆ×{Ë@äoŒ³Å<Ã( ‡²ä¥„ÃÊ!”¤Üó¡§ÜÎ?®ÀT»5 ûYï*àë‡Ãú²à3‰Ã<ÿ Lä4\4ô>á3!3»$&ž’8ߪSø@¿ó ë£¬L˜ÆfÊË©“>aG&ăaÊÊGùè8T4E¨Žžë¯M)ae‡£¬êb8Æ;+åI1/扂ZÀÚéFmì,i˜¯(iVNby%ÁHiPr¬°Ž¿Ì£ÝÐ’h¢Þ%à·‡7 endstream endobj 1233 0 obj << /Type /Page /Parent 1720 0 R /Resources 1239 0 R /Contents 1240 0 R /Annots [ 1234 0 R 1235 0 R 1236 0 R 1237 0 R 1238 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1234 0 obj << /Dest [ 1241 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 129 537 179 551 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1235 0 obj << /Dest [ 1174 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 331 523 380 537 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1236 0 obj << /Dest [ 1225 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 427 483 476 497 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1237 0 obj << /Dest [ 1174 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 266 334 316 348 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1238 0 obj << /Dest [ 1204 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 199 121 213 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1239 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1240 0 obj << /Length 2691 /Filter /FlateDecode >> stream H‰ŒWínÛÊý¯§XäOHÀd¸IQ© ¹77×EÚ‰Š~\ÅŠ\Yl$Ò)˺Òwè;öGÏÌ,%YRl#µÜÏÙ3gÎ̾› ^M&±Òj2èXEø‡Ÿ$Ã$‰25§a–GC5Y^ýÔæªhyN¤Ú¢¼úðU«›v…Q¤1§}s3ð>›«t)òïÁ˜Õ( Ç6æaɾ¼&æåÔJ3Zý›÷ß½Aù†™åjºU_·u7GOìY;ymÕª·.Ô?ÿç)¾WKÃÔ«üÈ+æêë¦ê~·«o2ôL]úÁØSÿá¿þ·ÉŸ|c¾M…>&?£-Øl6¡? µ×Ò©–ŽÅÖ82D3 c¯p]sÞéýd U¥qš…ÃL«á(Ìs•i ©pÇ$W+;˜ ÞMv` 5¦DÑØ£"£÷ê-.‡ãtœÊriêÈ!:ÂI»MÑ„Öÿæ½ÿøõ½dzõKߺö>¹úôåjò7ñµß÷ö}ÿš¼ÿûä/>~úÛ‹?ôwˇa”k5iü*¾ÏÁ­žM³Ýh' Õáxåaœüpùû³Ù<¨119^|v˜Üñ¨©ÓX@}ÊËCùëÕ‡_O±LÇÀÅÙ„£³#‹Ï?aq‹³sYô—O_þüöã©MÉ8|Ĥ³£g-ÊsgÐpÏKïÛ·7—¯¦vÖ¬ìfUu¶-VÕm÷†8~`Bœï9õò™`<ø¿Î.~|´?wˆ›'ÐëãïÎ+l¯ƒ#‘úû€ŸL·$¡­"•„Ãa>RòÙ¯ÎFiÊhKÐÀa&ÚÏÑfü£.gUmUk:‡zUS~4Gù൚U~îь߭,€‹ÐÓu¶Vð÷-ý€”¯ñ„™ùn–%ùŽˆ’z…×"¯?5ugªÚ–ªª_³¢Ž¼Ý¶°,õšL ùv¬Î.cåÒܾés–¼&Ð!¥!·N *oïLå#³y 3õ),|¨³g_«w"|d@ºOr)›QÛ ÌWÈdÅ^¼“]&)útrA?ûœ1¾ ]yŸÔ]µäÕÔ‹í1¤ŒˆÜ$¦½ÄÁy"µFS«B ÓGPä=†FµÈa–ÀÓAâÝv'FÖ´‹56‚×àÁb—·ÝVÙûÂÂü™Ÿ0ñR&R'»DnX¸(ݪ²’ ¶è@×&N˜îšú™ßôEK! ïf^jÁ‡L{™ØtÁ6€2ì¶íCdɹð=QÏ‘éQªœ¨×^ö€:íÂÙ#vâÐcXÜÒsS»¯%ÉS³qC`BAÈ@€P0¿³ò ðSñާ+¦¨,:$tBÕ…ZTõwÙé‚¥"g ØHÓöÞ,oVmæ•‚²ª‹fYÕ7¿šä¡•Ù•­A^еûW$gk¸Å´ª3íwê/U»ž"¯šŽoÙËß[ótK\é¨ÒÖ]Xõ„ÿÿzõsO[¢? ÖYÍ•‚"è›d ›eº£ PT;oÖš)‚±Cè”d¦!z‚™nbgŒ@§f«fÉJ…ý€Sa2¹¿ñÙ8:M¼ÁK'ã×^/¨½2°¨‘2,ÝY/,ãA'€Bô}·[vUÑ,ÖË:<ËbìÏOz•¢’T ¬j‘촷ƇöÈ[P,ébõŠE'5& >:‘úº&àŒ3å¬|¬XÝZYà>Œ€(¥#v[š­„äïu³©AB_ó¦NêÆ%øVÏÞÿY¬#H4äAJ((ÅÜïÔý‚@×ÞÔü™S¹ÀÓw´w·YJ`•«Å™t¨ ¨²Vn«Ú'5.1¶>,¶“Ó®^têk¨´Ë½²´ÔH±rʰïî\ïJUÔ[KAI6J?ŒL¡ Mý’ÊVD¡º]57ÔŽÄnŽf´ Û¬ ¥ÞynšxÇ’º™=ÝŽÜBÀˆsŸÕDSÊj¬ïR9ÿW´$R—̤‡,Tä™é¤7Aöíø’2E²U¯Aœ¿¬Kh’ÙÎ(³½ u:+Dù^ˆÜëȉ˜Ë»)‰½©]“ÊUa W@/]÷Y¬­êçË«ÃØ»çÖЪ/rQWÓö—KÅ `\á¾­|ˇü­Ï¹µ²”.ó¤Õ› µ1¨üL·‰Â³¦ úH‰åÅÙ‚Âe>.ù™Bª¿©ªºCö`‰!¾=³Fç,/Åô‚ksÇι­œR3鞉÷†koÊ)ræb]Ò04´<2¡  WÉï`È Í¥9o…©])ãjÂܽBqÙYÇ<òD‚/Õ²ÂÃ+p n– D”á—sp¹nEˆ©®ƒñK»lV[ºaÜÌ ²Cаa}ᔊ"úmm‰ëÖ¦;¯h®Üv-TI3AA2ò5€ÇÑlIÑ ¸eeƒzÂ=Mµ{` èàçz^70bxô&Õ!jÝ ½/´+Øzºž»8* Hý‰Ð#×I’…;¨\@i—OšêwŸdË¥Q±ºS0³uå©u ã­ðÐc{:Xv|¡wíjUÝ‘b•ëÕN¸¶Ð’TèyøœZój~:Iå½¥Zv¥º<\‰<êëÇNr?]ár¶#,žle¡í¨mô5,‚{Áá#‰ø|¹¼Hê´/˜3ðžòCPå,†Ñˆ‹$j"’R £¹‘÷´¢¦ëpâÔ“eG°,LÒ=]Î9q©=., âÑÜÞÞwêˆ@å`¿“gE{k ¼…š­ë‚¯ JÛÔ©èÄ(kÒ#î„ ’‡§|Ø¿`ßOÿXÉ* endstream endobj 1241 0 obj << /Type /Page /Parent 1721 0 R /Resources 1247 0 R /Contents 1248 0 R /Annots [ 1242 0 R 1243 0 R 1244 0 R 1245 0 R 1246 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1242 0 obj << /Dest [ 1513 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 350 725 391 739 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1243 0 obj << /Dest [ 1174 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 410 631 451 645 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1244 0 obj << /Dest [ 1204 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 293 550 342 564 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1245 0 obj << /Dest [ 1204 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 457 523 506 537 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1246 0 obj << /Dest [ 1249 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 407 238 443 252 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1247 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1248 0 obj << /Length 3107 /Filter /FlateDecode >> stream H‰¼WÛnÛH}×W4òÔ$†wRaÀIƒ,&™`l`/ö>PTËâš"‘²¬ùý‡ýÇ}ØSUMQ’í$‹Y,&cŠÍîêêªS§N¿¿½½¹ ”¯n#?PþÃ#Ê7мD¥ÓØM2/T7«ÑÛm¦Š–çxª-êÑÛŸ¯}uߎ<×ó|Ì)F“þçn¤¿æ÷Fù‘¯œ›Œ¦¼hªRÏ&0fnâ‰]^ðrú'´úVÿ+Àè$𜉺‰ö25Û«ë}Ý-1hãÀ’nËV]ýsÈBåWÚ¼{=`¦CYy¡X*kõõ7*x¬ͦ-›ºeŸ9Ŷȧ`°—ìÙ}ÈkUH&%‰ñ7’È6£sµ(!ŠÑ¦t&‘^w¯û>L>LÅÊ5·c7ÌSçL2„FœI¾‡¨`ÀAûB¾‹2> fB“o5ðoÁ æÌ6ÏŽ⨸T„ú‰”êç'&f™ž…ÝOޱ@Ù‹t×mÊÙ¶3-½ú|^ÿZ/Ÿ— A×MmÔéY_Š´@ðV4‹|[uÒì{ù="”[7ª• Ñ–g°:/Nï´ ÄØd°v«?-ØØ’–C¡Xʃ÷¸T]~¯ì5/7¦è€íâˆlx¹ã{ÇìÔ§úÅ, ©f‰))^@÷ëÈ¿sÆXÛÛ¶›:Ô®æãõ_lcÎH±Œr‰ä æÉHàÕçø†Â¨|áDDÀfƒ'z¹z _av朗‹Ïüåž§L}S©eN\ãkÐ5Ïgó»ü5䣯çlÍ2øñ…¾È)PÌ3£¶äÎañœÈÞ(ymòteŽyÆYìÐ!‹Êäõv­v (ÑLlÙ§ÁBÉ·XJÏJèY­Ï©ôâ߈Ê òå%Ñ3Ë9 hQ=œ¢9ÿ\¶ÜjW]#ýy…óòiÁ!€ZGï"ÓŒ3Ê”ogȰš€Œºr2–éÿ í' G*/€…€¢ƒ®µÉ÷—üJ+ƪÐZäUÕƒP ô16&Ÿ—õ=Z«ÚmÊŽ~¾íxˆ¡•0©Ð(µ)z̤˜ñ„ý \¨ÙÁœ¾Òÿ9!1 ~Z:ÜDìä¢Y­+ÓW}rHØu貪‡©Ì1s‚+ÚŽØ¥„dlS™§œV~e*­f‡ µÞ®f†gö>9’C?tS™•©; * `çúŠt>±\ýÆõƒÞ¢@¯þúÉñ‰·¿|üé/wúÎ÷4¾uˆaë¢C[+1&d¤g:”ê!ç†XDy6x)Îï÷¬æ—îól}~Òf‡NuÃÍjéØ!âX‘f(ò¸< ÒD¾T…0¥· µ@^ªxHXTä­ÈKÀUÜ"W†³Ýpæ©q¢mvçÝ’×?jpƒ†ëJËË×Qš)ÊEY¨ÅV",ŸP¶òƒ¹<—Ϥ„byŠnØ×4¤l¿ÔëQJw‚c±>h5ë1(1P»]› …§íÚ L„0OC¬£Lf¥ô¸>ç 9>ñô±#4<¿KBR‚ŠH‡—¦þ¾¬¢ÐÍ¢ÿ©¬,_´hÇTšÀü£}^’b ôX]Ué°Ø12Tw—?$ÿ˜x=åú®l/_•Rç î‰7áY]ç+s¦¤Âëz 衬­`&0¡”™™5 F7md)$Ö2¨r;¦y´«HŠÄ¢€R€ÇÓ=Íneˆ{oa ‰0ÆØ„Fév²¨ÕéN,J¬ ôŸ!X µúF>o'/ѱ7ˆ+ÏŠ«¡Z6æ ˆ'ïú¶AMnµÀèlϤ´1«¦3jí0\s ¬Û«¼Å©[4¾J„›sÕç¦íT3{,›m µ4™¢ðZæ@ƒVòŒv%ô)ã[)“Sò`*m\¦T–’|ö­uHbÒÖ2 =a›Úñþ­¦bUX³öuo—\Ë$ûZòüü‹jû½©3ºåƒÀxDή†+E¨Uvúéb»7>Ÿ:3'-Gz И®,ìýkdâŠ*ûÛ~Û_•|·1è÷ÇÎ/¶íóB¸Ó«Æâ®"$4=~gŽ $Ôõ@†~½«ª|0êKóP2š¦ÏíÙ«¯èűÎ(Z¡ö_„—ÈÍj°Ö¬YzÃÏ· ܺÒà_;Vàe'´r™8@ý #Ä‘¶S*t d=ïmÚ9h-ÔûìÓÖÉ‹9x®¸ÿ\vKRhP?¾fÊX3†ÂM‰e¦LÒAþ&zìð=Â*r“³<åÛ`û¢–|•oz–‘®‘Ëk—óžQo_ÉzÞT~ìeO;v/›íZöCHŸx ïo™¼r|®¯úl“Bzp¨Â¬ZF¤Ÿ­tÏe%•hßJìžû¹ ÀcÌí4÷5|ix!9/ŠÃÁùAYù¶}^±¬Ž)m¤°xÛ—!qØ3Թ̗ơۦÌâÖ 0¯¶Ç3Ñ çã<Ï”" Ý0œü½EO$æˆ7N;(–ÄçíûD¶«½˜Å:7ä±Ú-­.DH/¹aˆ'±ˆ´ŠÛ“”°äçõæm=7b’—Â`±ä¯}—Ët‰€²l¸+âjzZ,Áàp ïJÜ­ÐÆr0 no/íG< ô % ¥Î·ÒT7+Þüz_Ÿyà‡n}U ¨â^" ·p1—Ÿ¨þ´ÃH ÕÕMÐ×XíkŠöi8ÿ2Î{Ù–ÏBžàQÜT¿íìNò¸sþû›Êó¸\þù( ©îÃ=åp§î”ð¿Ú÷u†„)UW’ª¡¤¯âú±±êã'w´Ð!%Ë%ÍõÁû|õ¤ kŽC'²iÚ¿ÂäÑÉ­– óú–c}áØV•8 tÔZ5Ñ5÷9ØÐÖ‹f³Rvº’Ó…euØâ[QoÐa gæþBrˆ›ÿ0SË{ÑÃö3o~P!xnöª`q#¬^”÷ÛMNW4µ(‘„™YÐ5†æœÜ„6/ÙàÇK—R{Ó…íESUÍŽ‰ü)‡¦E:I ´ËfGB°Û¯Ëÿ^-» Â@ðž¯H9¥R Æ1ÄD$‡ª‰TUÊ õÞ6´*UQR?¿ã'l¸DÃâñ¬=ëEaQ[BV Ë2MUAç°B©n›àƒ–L~4‚Óº†É¶ç!Rå>«?ûj†©ëj%6µËÞ’š«²Mµóa'fE¦Ú73B·p)GÏg:OÕtqÝ›t”½'9•G\zÚÊÔh­Xnª‰˜ÇT`²l£šÉfvJÔ艹|Ž£YîPÎ`ƒ7xFEÌx0|vsçò³ÅéÄæëDûqÎqQå†PÝÉøcåÑ>¥ÔˆÏ`®L‹Éï±:Ÿ¯ïĉ¶OóÔ{ûàðkGê²ã‚}©#¤—­yå ipË;kòÃ6˜aÅáX/:¢ÅV¤N g³†¿[Ð*Òõ£¿ûÒ‘$p?­”iZE“£Y¹?œo—oÑ¥>­·ñËóîi¹Ú¼nvU™tPy[ìè°Ú~x˜›·ÜrûºöÇLôo]—Iëß-b(o^p8m‹&k³2±YëL*†3€Mpδw°ƒ ô †-Å<Œšy­trÁncð¿ÝG endstream endobj 1249 0 obj << /Type /Page /Parent 1721 0 R /Resources 1252 0 R /Contents 1253 0 R /Annots [ 1250 0 R 1251 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1250 0 obj << /Dest [ 656 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 251 421 259 435 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1251 0 obj << /Dest [ 662 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 161 259 177 273 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1252 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1253 0 obj << /Length 2374 /Filter /FlateDecode >> stream H‰ÜWÛnãÈ}×Wtü’&`Q¼6©m`gí]8— ž<ÐdÛb,‘ŠHÙÖ~ÈþCþ1©K7EÝ'@™ìê®®:u;ü<Œ&“@øbò<ðáÁü‹ÒÀ"O‰d»*õB1™Fß7©ÈÚã‰&¯£|ñÒ <×ó|Ø“†öñ} ÿ½háGp&ŒéÐX$ž;V 8L]å±^:Ðq|Šž~”`uxÎÐ]%½T<­Åúj§°Hí€&Ù”øîÇKñç8ÃÞ— ‹ÝX–Ž'óé¥xx/ÛŸõrFJB™U…3Kñ ý:™üf@“7ç*x™ÜÂYðþþî:¡ëËoÕx-¨†+]xôÜ@æfiJšî&_”bÄÊ •/ÂÄMS¡|@R€Q*–zð<ø<éÀ}Øâm£±A×CD$¡7úÁçÝq<Žù8?úžA4›:%ˆh„çåU^WmVV3TZ[dmÖ´õR__ÀÃksqcÍOC×K}‘$>üdrÏð³ÒXuÒ(ˆ oúòØKÝ :züŒ¸»›bDB6F»‡Šñ}Ü rŒ[ì»qÀ¸É«¢lY›OŸËY«—7?¸¿½ÿéöÓõäËí—«ÑŽ#ÓC-æv¸DíØvX|ƶlSÖ¶—UY,–ú¹ü¸i¯F½·C¢±{ÂŽƒÒÃft©nRK^lBíÞ‚æÈÂïa·o>"·ÇƒÓøŸ1Üßà•ð«á°_íz¡»ªhV‹E½luažÖö©–ûÅc†Ã½òñOâPjzg <"?‚÷3œ¼fgw¨Æ'#pD|:ƒUºU£w#p}ñ–g3]ÙÒ÷.¬t^ Y¾w ˜êz¹ÔÅõÅZ7£]ÔUz õÃÒ3°%[Y·ätÔŽÉíquöÃ⃶§©1=î÷˜­—]æîZ¥ý{÷¸»½‘ïöGŽŸÛ»ãñ©nDü™(Md(M„랈Ü0LÁ¯–ƒ(P”=âu$Äó™€Þ0v}æ³Ý$½ù$`%–÷U>s «B‹LÂð–HÓ èLY€‰†…a¦º‘ç'=šÑ©¥³±á'àKºKϬ± Ü í9à[ûùß³Áº;>iI6j ëSnbi²ÒÀ§¯„ÍsbÛûh©ZËš—õÍ®¥CÒ ž‚­ —±M;lSc\V ƒ(ÛŸ±mb>Ò¼v”ä©ìDÀÕh4ÃS*o.…™ŽïÐy.i¶} åÇ ÓÃÎt_õ@ù‰f$ÛvY>­Zœ€T9ãç×f†·Û«Çú¼dF°q?`c&’Þ©ã#åmèE´Ù‹°Ï+þñokH|†‰ TVp(QÖ:´FÈ©/.H£ÎK‹  PÇ{éím§¤Ãºê_ƒÀUaÏÙ¨C­75‘ÌvèàŒàœ"A—"Æ?‘9Ã4hƒà,FR˜²1Dß¼4à Lm¸Î•ßÒ"#ï(4×S×6 !pÜŽ+‹e„Ta “ÀEòn‰è°«dÁRç-7I=/+AÌZ=o˜›ê*?.åEÿÖÊ÷ýM¼6N˜ˆý‡+{“Ù¬áLÚÕ2× ~Ò˜¡‰ä_üÌ«+ñÕ¼j-’¯Î·¤ª×ª®þÅjöÆ›ÜoªYQ5\Í DÒi?_Á·+<°«Ÿ¸pnÀ…Kç0á|SÿÙlV¿Så>8Àäû¡’Uþ{Òü;:!4Œ°HV¤çˆr·ìkÇ”6s}ÚP!RXæ&Éx8Ú5 ¯J—mCûˆîçÔ„”ä_¬Û¥RòSI³AC'N^‘r–¯ G¥r¡yCvúrsØžC‡#éŠ{Œ>v¹Ùe¤¢Fè°‚rý¦«vdõ¼šº>fÖ%áã6b #ÖßÜGãT2äS¿ GRlÑ&à©_P¨æà˜k&ow¼û‰s *ƒÔ&{POWܼÅzc“ÉlöÍúßÐkxïåEËû/ Ö¬b¸–¯ürûe/àì˜êÚ„bÁ¸zÙ3 Ú:dQ‰Éiو¬X Më‹Åׯ¬|uÜ}p7=­W„Á Fñ§©ÊVQ "‚é„¡9àн”oPZÐô ©àõœ|Ú:5¯ax-2^CœS¹|¨vÐÝ¥If©ì›DN)‘CNdeÒ¸Sy‰ CÈ¡.u‚‘5/ïô(Q Þm²ÕÅ|G(‹£Dˆ®a™%”³Ül ñЄÎû´ÌéÀÔÞ¢k¼5C bY‰iV3ÈþÖÝo$£*»±Å™!Ìè0×µ¶i™iÃ˽ðÅdnLáÃÅk&æÄIhÂbPb"×iã>qU LÔ¶ÞMgßʈ“|síäsÔQD?2jž½Ây˜ ¤eHÊYˆŠ9~v²Ð;“†bxbFo]ׇfÐÁuÚ@Š=9‘[ž“ãõª}©¹ƒ!Ýá\̵n5”‹|ª´h”Ùv˜Zñ´îšíOà…šêÆ,•Õ’?Û}Wmú®²SÈvWšb¡t±ÿõ8Ù·ÉÀKà»¶G$£îžñÖ—e“)ÆÙ ùZÑ´öŒ\VÉò>6ú¤°¤ŸË-“·—ô…ÙòP ïo‘•ž¥Ž~êu$÷ÿ€:ö ÅG° ü ¤l9‡î¶uE?Ø ²e–C² K> endobj 1255 0 obj << /Dest [ 1046 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 110 535 152 549 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1256 0 obj << /Dest [ 804 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 167 521 197 535 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1257 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1258 0 obj << /Length 2475 /Filter /FlateDecode >> stream H‰ÌWËŽÛÈÅlõoR Z4I‘Õè4`Ûƒ âx0V6qgÁ¦J-&)%ÉʇäòYäÜ{‹Ô£ÛŽö h U¬ç}ž{îëùèå|©PÍ—£0Rþðg‘ÇAª¦³ÄO³`¢æëÑË»Lï TWÔ£—?}Õc7 ü ±§ûá~¤É ã‰òæÍøÐLM–ââIæ§ÜËg">N£$¥Óõ¿#ÌŽ£À‡?ÕA¦êá¶+ÌDÚx¸Iwe§^ýt¥þúoœà»ÅZâ'ºô]¬®Ô‡}iÿiÚŠ/™è¼^xã™VÿâÿÞßæ±Æ¬Mø)>æo0Çì÷{ß›ø¡îèUCÏâj<écø‘.ÜÔŠoº›BUªQ”¤þ$ Õdêg™JCXRAÇ8S­-G¯çƒ1&!¶çÖ8Z7 ‹h¶|;Å~cCìO&ÙTÉgoÔi’øÓèĪADw|Ôa‰¼ÌŸjuÓšucMëái½­ÌíµêÔîïòo³+|Já4`€'Ä TÁ°ÐÔKL…º|TÍÆ–0 ¼EGI¥TDë2R¤•»À 5èYnx·“¢pÏPÂ(h<¾´,'W|Þ° Ù*ÔÏXæ2<‡Âc–….ËXÕÙQÕ™¨º‚§SÜÎæ #ÈWÁ)È«f_™¹µrÈå¹v¹õ֥˥ƒd¬€þ‘û­nÜèÒo€ô¾ì ¢ÓÊ ·’ gBY؈†œ=¿èŸ¤öIŠº}q­æ „+hKÃ'â\`¾S2%U¿¾•_à1ûŸÆ¾À¥èL" ÖdF™lx\ÈÖ•áQ™!Bü3YŒœ,§æäE¶0¡Er"³A;’v®X™â¨,eJ…9r¡m½1¥ÃÆÊšº×¿@ÌXÿú^íŒl‘ ô¦®÷’»,VØÉj"[óšªF¤iMŽ6)´cáÚ¼°åÎi€»:¤:«1ÿýèX‡ÂL¢ÿê))î¼ñøñîýüÎÍü…ÊÓDÿéîϯÞÝÝkz}ªï=P°ƒ¶ÜжuA„AWlFoœ ü×a“æˆ×DWdLw˜Xü¹0K”ZüG±kÚŸ?CAr=Ñfcê’T-r›[Bž…µ!¨zè'ÕW@äÙ<=&øÔQuCÐ ñ‰ñ‰„øP¦Ë'ó¸ÌÆ¢²ù#‡ W!!3êp¥ª·ë¢v‘vg›%—N*ôí𔆌§¸KD¸‚™QQg½á¸É‘QmóºÂoý¾Ap""GgrŒÎD¢ó·áøá&C“MSܳ˫­Ôó›ý`*¤¢ìœ]Ð'N¢’WöJH`Ùv–j(âáÚÁÍŒá†^ó~1Ó=OÖ/{£}YUTsó͆úΠo+œø½QCgU´á‰ãŽÌ?pÌ&” 0ÊDÄ%…‘Áì4Û¼ªjßl«…âb«òNíMU£q¢À\-Ùˆ‘Ìg¸¼pnêtêÜ!?E+=_•]ß8ÚÆnŸÂÓN‰à› Ùä”±7íŽÁ„îØbgZ”¯'ÖN%Ù‰yžòÀ¢a¢À­·½¢T¿1õ(4n);le`ÄNe¿mzaÔÊìÔ/—%Ôo ½ØÉ‡ž÷ÑE¾R}Ê} ôF@*ÀÙ¯ÁËTðò["ôWáçgxàœØÊ£*sd`U%½ì@ÑTî8œÊwB€&º¬ò‡êæÖ§ÂŽƒŒbrÙµwbÚ·NE5J/ØìlÑ·ñÐÞ:3huÞІ’&Ÿ¯ª7ë¼Þ’ ¾k AZIb⼑¾¦!Õ"ô$ñMðÉ9‚bdŒ;Mÿ¤=W¤gæÑôÛèrDõpÒëÒ,LuK3—âÔÆœÇ±cDÌJqšŠØ‰þîrÉpèÈðMcÖòýÝ;ÆÎïü~v|ßåó ù-ÕeË-ÔzŸËÀ@&·âWqË^„ñ°‡Ú àµE!MPä&šRF–¹ƒl–kîßWÁ§ÉëZ8×gÙ}Ÿ¤PЭ 'Ý¢G ܰÃuy}×'»{íb·[ÖJî¾§vãcœŸ…9õ+° ”Aœ@ ìÅ^æsL™42wË_3WÀþË­n—Ú!m(ÿisÛ±Ú q3Š*ì`=<ÝÍGÿzL” endstream endobj 1259 0 obj << /Type /Page /Parent 1721 0 R /Resources 1262 0 R /Contents 1263 0 R /Annots [ 1260 0 R 1261 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1260 0 obj << /Dest [ 991 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 389 438 417 452 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1261 0 obj << /Dest [ 1393 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 437 438 465 452 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1262 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1263 0 obj << /Length 2514 /Filter /FlateDecode >> stream H‰ÜWÛnãÈE^õ}j.,šÍ; AÁÌììb‚$vÈ84Õ’˜P¤CRÖ*’È?æ!§ª›¢$KëÅ ÈC`@nöµºêÔ©Óï“ûÅÂJ,Vå ø¦¾†^,’,rãÔ Äb;¹ÿÐ¥¢èxŽ'º¢žÜÿðY‰u7ñ\ÏS˜SL¦Cs?‘Ì×Z¨0Î⯓Œe"ñÜ,ÆÆAêÆžÙ—×ø¼œZQL«¿Èùèúž3UK/OñùP÷ôøR;ØIve'Þýp'þüogá»ÅXäF²tß¡-Øï÷®¸Jvtª¦c±5ŽtÑô\_¶kÃ;}\L”(ÅÄb7ˆ•7ME¬àI;†©hõd5y¿8:#P˜â{cô®G‘ì½ûï_…hpde®g#$e&‡f2δ²»Œ‘v½Ð^G{5éê³¥~) '†Ku¹œ?ˆ¥ƒ‡ðú”‚1->}'%¢D"ݦÙUKñ¤Å®.ÿ¾Ów¢kD¿ÁH‘×ÜÝé¥è±Íÿ¦E.Z1ÉäT²ÒbÕ´¢©µèÊzjC3U.ɘ髣™Ô$3×XÖÁÊT>;>™W”+'Ħ¥ƒ•²KíÀµlï£c~ô%6è?¶1/Là¿Ò‹* =ób äéþð¬çÜ| ¿w"´kcIÞU¸A ¾dïb¾p©¡Ó?Øl½2Ú̦-¾5ñLÆx&Æ’O+‘W•hVˆî°{¾îDþü¬ó¶¬×¢¬Y«·M¯Û]¥çbK%27ñîÉÆ»37Yµ¡DÑÔµvëi£Ö|Ð>‚/Dp qSÿè´1¦ÊÆ´e—*RBEÙÁQ©$c«R/]ñÚ»ßä½òäl›×»•C@Ê‹~gk²3´;ÍÍǘmö3l©´JÎA̽5®ÆµËõ¦§[ñc™Ã3û²Z¸VLÞðá³ï’!f­{”ßò^—¸å›ê§/ò7è#Dì¯:ÄóÇØùfÅxá¥^廪"Ê* ?’œZÝ3A¿¤ü¢‰egüåd®or6œz& e!ìû®—‚KóúÀ©u\t„}èŸÇ{ÏÂÞ >!Ô‡s×Mo­<P(v8À"Ò‚ÛÜH'½ŠF€D'ÛÌHêºç¤ˆôñ]ä}ÙÔŒp˜ïK—Ïzg>@:°…¤¶lWN}†GØY¾äžbo"üd^CKM¿°˜£þ’;•“ãë’Ž¿³Û™£Š ÒëÆãªúæ+Óa»3ˆë‚§ÐHDm¦<\Ðoí'ÿnFŽAÎŒ]O”૲†“r2)fˆÊ~ôÌÇà&’L6ìÃ.ÈÊäUEØe(pv3á œ*7ŽF{ü±bù¶b½í‰^ØõTBY˜®ŽB …²PiS€P²Ž"õ€¶ØúYkÜ+è_‚@P)G$.“:ÀØ7ak\N…ç´†Oƒˆ.s^y¾60£êòãTѲ'œÐ-_¨ÐŠâ”WLìu3»?~qzÏMZ™Ä²cÛÍ3çУì4¢åPDàßf/ºÝS§QÛë„®ž!±SÈôsÛº#@ÂagH å Á¬@êtO¥¤»è¥D¸ÙSǃlºpÁB¦ ¦¥ÄÝÐ/šºAÜoJÊD3©u¸Ò¥NY“Px2c€H¶3kb4À™ÒŽ]p‰X˜½„ÅÂFY…&˜` M„ù„]"þ‰DFßpY‹y8.€ÖdU! 6º¢-9\2ç¾- ù`_zK@F¨ƒÄ7&ÇX—~@5Ì9ÑËú•oòª&ÄnŸ¤çI™#‰¥YZp“õÅ…YSÞàEéñ¾¶°|€Ž,Œ5Æè C¼ï÷ú§~ðÿ«Sý1`ìå/ò=(À}[>ízÔ |*ùÀh Þ:–˜¬IÍÒ‰·;ö—ü?Ò¿¹ñKð¾ 3Y %Çää„´]HÓâ‚àr~š xo"®hGš™…ù6ƒô\bàˆ:ßB‰;õ†O583má…¨™´÷$5èa”˜MY®_¯Þ:¨©W5½ÁôÞLt90ÅK SAÚÐSUA,lË@RÌÁK{d'– Ë Îî²6“H€¨aên©ùÏ t ®pS¦¿-´x¸bÁ—œþÂÊl qaµfyâ?SÙ¨ð…ƒ¶n#‹ö˜¹ÖõÙx›³~††-_ÀÁ« ï OQ5k³þNØ}´ *Vˆ4Ö¤RÑm•Ì\ÞáˆÑ_Â6A6>#§ce9¥VÃ6!?¨Ä¬*·e¯—üáYÁN”Ò ×¢žu¿éèÕh0±á¾ ãWbÛ‹UÉóuµìÞf¨ ‡ÂÿO†º¢oŸš¦ÒØç%¯v×F}Û˜Kâ²wúŸ³×rü‰ä=^#–³J6€^M,©PêÍÓ³¥Gn€®ázÇ^è̃æH?,ÏøEƒõ›¼‡‚0¸– ã5¡ðNÀ`ˆ+Z冲%*÷ð³"’”¡FÞn‡ÁÙ%VÝÙ… ;Ò»ü£°Þðpiery"— +—µ=ãõvBÿ”oŸ+#“÷ûÜ µfï€r>Ù´öTVúú«ò5Í2ºâOرƒr£AHÔŠ•XAJrôìm¥6O2ÙFUHtÆ@ ®Ê5Qñm”R÷èÜ™— ÔÕ(Œì: ÇÆSsžÙá‹"ó¤Y¨Â¦^´Þ–ý†8?¤Gœn_ ÌòÚt`ƒ¬Ú! HQ¼Ë¨«Èã厺Ew¨ ÷µÛFåp‚õÑb´ØjÜ6P¤v;„ ú˜¯È_¾> endobj 1265 0 obj << /Dest [ 615 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 218 333 247 347 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1266 0 obj << /Dest [ 615 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 456 69 486 83 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1267 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1268 0 obj << /Length 2122 /Filter /FlateDecode >> stream H‰ìWÛŽÛÈ}×Wô[šÀˆæÔÂ0°k; ë Èè)v8dkÄ„"^F«|Hþ!ÿ˜‡œªjRͬ< ö ,²/u¯S‡ß¬¯Öë@ùj½Yøòð?Q¸Qä%*]Ån’y¡Zï¯Þö™*z>㩾h¯¾½õÕ}¿ð\Ïóq¦X,§ÇÃBÿ!¿7Êbå¬ÿ²Xñ¥•J=w•@p˜¹‰'rùNÀ×é)Nèö'ýÏ«ËÀs–~è&ÚËÔÝQÝ›a‹•@’t_õêëooÔŸþå,c¼wØ‹ÝXWާ‹íº=TÃßMW³PçMé,WZýƒÿwþ¼þÝ‚=foÏMð²~‡5¶àp8¸Nèúº'­†ÔB4TºxôÜ@viË’Þ¯¾ªÔ"ˆ7L|¦n–©ÄG$|Œ2Õ™ÅfñÍzFèãˆ÷8§èzÍÑCŽ"›£Èõ"ˆÜ0ÌR%¯SPÓ8vÓà,ªX³QÅ)öÉ÷a›;¢¡^7­Ùí‡ã¾sR7ÒíÞðz7T¦ó•*[Õ´¼2¨Þ¡˜7¥ÂY‚ïÁÑFÑÂ0PXŠ'ã“~g6ùXâuvE…´9'@·› «¸ðç¬â½“:¶ÍŸÃ5%ÿÃF Ûªw"ÒÚmTÅVdU~и!ÅE¢rô cA¤9íÈø Äõð6ïÊW(í’Y;+„Í^lʼSŸõÇß/ß}øãgGÝ›ÆtùÐvêPÕµU3:K„ý¾3²`°(3;ùI÷裪¹WSC S[4çÞ¸j ÇþîL‘½Q}»3ª¨+Ó =µå60tý®6NpÜ9>Á”:lM£LS´c³<Óˆ^øKj¹åÏ•s\8 .á¡6䳫~OeèëPén—×õñ†ƒ>Ç»‡Ñƒ¢¨ëÎüm¬:Sºs ¼²â4pƒˆÐé •XÈ÷e>˜¢Š$šR5¼Ó×í8]·äˆÄë«û‚ß[Jp2B]ÊKÈüy<ù¶üÊ‘ƒiÕ²5Å—!-bBü HûoLÚ~F€Ðü ùh­<«×=j%ÔvëÁþ¾¡Ø`~Öv{@Dïå™*ãú­ÜªT¥Ù Ü#;K$Š+B–[Ççé̆X‰"B^äLm„±mœeFå,¨5žóT&ØRiÇ[œ" ¨¹U¾ß£ Jå B¹_ÑgOO Ý#Mdžm> ÁŒÔu¿7Eµ9ªœ›ìI'{3ðjî[µn}ŽÎ*ÆÀ!Ðø2¤þ:V~ö±œJ(¸+«‹±"ˆ¾’±²’é^Œ•ðb¬€¯¿{|£CÉຣÚ3¼BÓ±Æá|蜔¡«íJkWñ“j|~Lö†õAC®ª ªi‡â¬zxÕo]Rñdª=¸Í{Áó¼,+ò>¯å2x·OsÀkOCò¬mx:M ómƼËbçb·… ƈ 9ÊQ"tEÑ,7U×Ceµ£¢]sA€ºŠÐ3ŠNÈåÀMÂ]8îi1Ðe.¿lÊ>Óâzp8±ööá°û…/{YµGíFáCYgË––Á¨U¹·wºÒ*5=F§Ø“üý´lê©èÓ#M ÐîECÄnÏ/sߪÍhÌ»<@wàŠ“[J{ÍÂ'CkŽ’\MÜ"ÖD9мa<å±d%A(Ë%4èAoÝ·ÓY¶oÉf=n¹ôT¢©XY5ΡC8chˆd¶Q¤>éƒÍI¸=384gÈó=·M^ DOd·¥\ c×PʹŸiuêgüqÿì+=Z­j7[õ˜:…W ¢1¦ÄÌ(jÖO\Ķr¯`s/Ës¡þÃa¢pÜtM'°í„‡Ùc`û”†–Ò< > ½úìb2s2‹$2õ®æ$2„} +…¸1æpÞQÔý­À»ÕPláBÔMì™–I Ƈ®¹‰*ºΓa$XeVt’µ ¢˜¢{>–ÓøGOç¢Øàå(*(H·Æ<l—Ñ×Rkm¶½o…OoƦ¼nTâ‚g&î4q^BEƒ–ƒ3næ­æfLÏ©hêd3Ô¬˜I6O9¨Ubšâ7à Â@ÃíŒ3¦¾þè´3ˆ«ìÿvú?%í ÿhgðãÑÎk3çg§Á/C;ߊvÏÒÎk³ä—£‡hîwÏÐMŒ®ç¿ÂNÈ›‘Á/òM™…Ì7ó’hX¨/ ç93E/€8Ì5^Â4Ã_™æ3LóÚÇæÎ4Ÿÿâ8'É5ÒYV›éL#ß…|H½^È\·e’7¥:û”Á¡HßåRçGÀ/9 ¾qÉ:çŽ;Yi$ 0RÄw$Gü@l‡:ï¨Æk¬ñÙC3ÌP8#/æÂPg-êÔÒ;‡Á‰èi¬­ 4X–ÈfjEUݘï%˜i*ŸT›ºÊx™<˜.$ÒŠf&ÉÏ¢²%žEeci`¬±KÙ}{{öŒgJ¡QçÛ7}Ni¨†#Œ'O4Rü¶›<øäÖAVóÊÙ93:Ä<êá¥wæ D?O̳êÃŒ^ˆ'íåç|Ë—(&}ß¾@’Eï׋½ ¼ endstream endobj 1269 0 obj << /Type /Page /Parent 1721 0 R /Resources 1271 0 R /Contents 1272 0 R /Annots [ 1270 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1270 0 obj << /Dest [ 1264 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 358 598 394 612 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1271 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1272 0 obj << /Length 2464 /Filter /FlateDecode >> stream H‰ìWÛrÛF}çWLùa3¨aÜ‚^—¶Yñz+‰]_v­}Áˆ5pq-ÈþCþ1{º{@PmW^S)©Ì`¦§o§OÏ÷ËÉóå2P¾Zæ?Pþðˆ’À"/VóÅÌ/TËíäùU›¨¬å5žj³jòüͯîÚ‰çzž5Ùd:¼î'ú}zg”ÅÊYþg²àM 5÷ÜE ÁaâÆžÈå=o§·YL»?è_ÌNÏ™ú¡k/Q«uóPuÌÚ8¤Û¢U¯Þ\¨ýæLg7ø6sgºp›¦d!¡N«µ3]hõ?þuþ½üÇ„-fkÏ1X¾Æk°ßï]'t}ÝÒ©†Ž…héâÕsÙ© Kº^N|U¨I0‹Ý0öU8w“DÅ><©`c”¨ÆLòÉ÷˃3BK¼ÇÞ½ë‘G4{1ŠlŒ"׋° rÃ0™+NÏfî<8ò*æ¬W±Šmò}èæ&No¨—Uݘ]™f<4EÕ–5¿îaqvùBUæÞ4ªß­ÓÎ(YU¦ê¬ëÜ( 5……ž?'ÇÉ¡‹Ã¡s9´1Yݬ[µîD7Eu§ ž,k>H¤ÁÆä4†y 7HŽ ó‡#|9᪮º´¨ÌZÕ ŽÎ\ÄÚôŽÝù_J8– »_6%ÙÖ‘×¾4—§jMY¬…b[“ƒ­‰Õ$­T&Úˆ"³o(âÏFàÌDƪ®K9÷iÙ;ˆ²ýËÊ„eüøÈ¦WˆHw]S¬úδ4ô5©äS迪Å ©WÕ•Òï+>ð9ôk“§}Ù‰ÕÉWŽÀstç|ĉ=G¹ïÇ ‰lÝ5äôÛ\u›¢uÈ@Uﺢ®TÁZÄÚÎÊ&8wH•\|ÍaGÄ/ ÆP‰É~úññކ`°/Ê’á,( öÃãuÕr¹~ï ,,ô(~uu„ØnQ{TWEg´” F›±‰4Ékëž!ChQ€‹Ã9•Ñ¡vÕ–+üçuc7´0#íT6ÔÍòCuü]—ÃЛ£4_çEfǤë{ÌoêåºÝ¥(HÕÀ»Î//h:»+dH˜éŠÜáÛ µ˜b‘$í¦æ={g(ÓgØö¤ŠØBˆö#m»z ó*ÝAòsùÀ{N ÙÙ³˜Ýkƈ»ûm*bü1©Ø[Œ.]œ£bº™öÇÅG=·×¨¦§¢L·†UÛ†ð*K‹èö€z,2ÏñöÆNÉûé…mÉuPä·\8í…ê%iò´ÄKÝgÓŠnS—˜o…z@5Pˆ“z¦›iS÷¨¿Äƒbͳ~>êd­GµÛ‚ÆTJ— \9")_p$yŸ/@q ¥XA©}æuYÊM&Ò/z“tàs™ëP5q]lûìüƒœ€›#Ÿ¡ÌG;jîZX‰^æé>A·Sº–q5=Ggøk,T!`å30Lŵ,¦ž tùìÖ¹PÈZ{‡qFÀÔîW¹\[©Ü Ž(=ãàÚj+äù®)îQÙŸ isƒdTÒ‚>hÿÄT¾†žWoÞ¢Ë*}ù (õѱ†§¯Ã‘ãÑõs ýjéø4¼~óî—þ¥€¹ÉðéÝÏý!ÝåtMÃ*EîÀ¯•úoošÂ Ç~‘W>Ø6íbìêéÖ@#2G1ëÔ®áÓäD ´_SîIBUL4§ý ÞŠY£å¤P€ÀC‡\ÛÏ}J‡È=çþ£^Ÿ…IþÍ9ÿfzÈjh–Z§Z'¨á¹2Ôñ;u/Õµ>Tº ,Ì Cifƒ-Ü_çið’¯ùl´ú{ŽÒ[4Ö¸)®kcwQâç=ôlÖ?õ6íP80G¨b×Ë„…8±àOµ3] ¿P¦LWuC= n¯ jÍð¬7šZd:‚Ìì:)–t©öô êÖ©!{åßYùg#õ´í“˜À?@IÅ]ªè£ž Xµî§,‚ ¹—%ìÇ4cåYoî{îQ­ «ÛfQÚ¼êŽþšÉ)CoS‰ˆK9Sê9½ž´ÝЉ¦4ërè@©âWQb÷¤ý=\œ²CÄW¨f€Š ¬øq;–_ò=õÓ˜é¼å‚N%îŽÃ`ÓýlÆüòm~Ñ…"*ÍWä“J©ƒÁXmŠ» Üd›Š0@å1-å…•ä| ;\~¸yRæSÝ «¥µ¤ÀÆ’ª>— ¸ÎØÙ\/'ÿøZÍQ endstream endobj 1273 0 obj << /Type /Page /Parent 1721 0 R /Resources 1275 0 R /Contents 1276 0 R /Annots [ 1274 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1274 0 obj << /Dest [ 615 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 163 102 177 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1275 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1276 0 obj << /Length 1925 /Filter /FlateDecode >> stream H‰äWÛŽãÆ}×WÔcqye °×†‘`×00ÊKvóÐCµFôRl‚¤F+Hþ!ÿ臜ªnJsóì±Æ`(²/Õu9U§ú›ÕìÍj•PL«Í,N(Â~²2 ³,*h±ÌâŒRZífoÞ%Uƒ¬‰h¨ÚÙ›ï¯cºfQE1ÖT³ùôz˜©õ­¡8[P°úi¶”MKZDᲀഠ‹ÈÉ•=‰lç·¼àÝÔ¿ŒÎ“(˜ÇiX¨¨¤›#]Ûq‹‘D™’ÔPôõ÷ô÷_‚yŽïsy˜«:ˆTµ½ ëC=þlúF„¤J·ë`¾TôOyÿXýu&‹5IøX}‹1Ñàp8„AÆjàS  Ñ82Äk&ªòC[‘ôÝjSM³$/´ˆ)]„eIE OlÌJêÍl3ûfurFcIôÐgïFì%ÞCŒ2£,Œ2,ÈÂ4-ä>'§.ò<\$÷¼Š1ïU¬›âº…q”p]ꦱ‡ÄJ†z3öµ®¾"Ý øó„™\UMmÚ‘FŒfʃi×2”ª­ñ ³4Mh»£xÁîtª,Oª,œ*ƒÞòg»#ÆC]y)°¸|ŒÊ“™Ñ2LÊ{fÆ“èØI~kÛQ×­YSÝ~%±Z¨“Xö"\LÑæÅ½—}#öfgGã^÷¹"ëÞérfå§îüïN é£òÓãX··îÊ|a—öGÒÚl‚ nÖÁ<ÎöÍèE¸aÄ‚uQÄKt"܇{"?Ûó’1ì ¶s|ì€W½ ÞVì~$ в¨‡õ¤»(XSGÊö"ì™Á:ò²q«GZ[3PkG:SÕ›#ihRœ²•H}ÒU.óÔnö†68aÜ"Á;ÝuµotO¶kÛ~ ¦¬ð™K4Oö8+ÊàJ ÝRå áP‘ ù¹“qcmc ‡U L(D{V&=)ãðåëÊ×\«25"Ónö£ø3V¬RÌ!zQ%NT…Ö¶æ>ˆ%3>¨oÍFDÎêò…#\-Nä »ÙÈì¹W–Aè |P« @uŒïD ÈSÓ¶¾Ý6GMµmëJ7@q\0ˆî’3!][ÔT€ÍœçÚQ$Œ=¡T`ɽúù9 vÉ`W\™@Õ{™~‡'’åSü/©•©[€ó°5-ð¶id!£ÀU?  2Ÿ;æML¡s7?·móHûpÏÚ]<,_àZhÄ ÀÁöŸ˜@«;ŸeÁ§ISb¾?’ep|ÏäômF…[ṀûtìG\?õ¥™¹@A¨šýÒP/Ì® l¤Ö%Jc©®Ö}È•¤}¬ÜaSËœº7~‡Z<éÓx¯Ú¸»ŠXýBçŒz÷^wWÔmõ`BZYÎø~7ÉB3Ñ®u¿¾p9i;øeÕQ÷~ée«¸ãXÿg\–&€ýƒ»gvÊÜä—¥r×£KèU™FœdÑ2©å.¾ µ3²Hèë ƒ¿hÖ;f\™ÂnÙ°ã ¨±0AÆÛ_c²û¬ªjäÌ2–8íËt•,“ßöÒ™Üó@~æ©ÜñÔ+®Ž ùªKÈ|BÛCÜýe3¡]p^‹ JÆžÌ(]7è`ïž98er$„‹ vœG~*S3„ ®¡’äò ÚùE= "Nõ_ S{¢þ“!-L*Dü“Ÿcù˜@KA­(Ò{ÝB(Qp'ßu‚…zÿî^¡M\«@7Ú'ÏÏìÏš{È–hñ‡—Â7<ܲ_¤Bûþr6¾¥éÃýÈŽñIÅO™ö°“…ö¶_ã~oé;[{†m½á¾ùvœ)ËÍíAfOE Ý9zª;t—è=@ÏD5–¨¢/‘û×snMÎnõðhY#z ®YøBñ)hgÉŸ~Ä5Ñ0UPhßuV.v° ¿­²ßÂ@>˜¯G ƒfàòÛ÷fèl»æ+ÄfßVNÙöžrÝ % âß­fÿG^€¬ endstream endobj 1277 0 obj << /Type /Page /Parent 1721 0 R /Resources 1281 0 R /Contents 1282 0 R /Annots [ 1278 0 R 1279 0 R 1280 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1278 0 obj << /Dest [ 615 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 196 611 226 625 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1279 0 obj << /Dest [ 615 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 495 427 525 441 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1280 0 obj << /Dest [ 615 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 196 231 226 245 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1281 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1282 0 obj << /Length 2026 /Filter /FlateDecode >> stream H‰ìWÍŽÛF¾ë) 95Í‘ ™;v”Kâ=p¨Öˆk‰THjäÙÙwØwÜÃ~UÕ¤43šMä Ev³»º~¿¯ú›åìÕrQHËõ,Œ(À?<’<ò“$ÈhQ¤~–1-w³W×}NU/kê«föê»›îúYàAˆ5Õl>¾gæÇòÎR˜ää-ÿ1+dSA‹À/2Žs? T®ì‰d;¿¥ïþÅü;Âì< ¼yû™ rº} ›‡fØ`&2Öƒ$Ó×=}ýÝýüožbÜá[ꧦöSm®èæXÿ´ÝV„ĦlVÞ¼0ô/ùõþ¾ü~&‹5Qàg,¿Åœhp<}/öCÓó©–…héã5ð#S¹©Hz³œ…TÓ,J3?ÎBŠ~žS“áˆÎÎÖ³o–“3âK‚ÇÞ8y7`ñb”¸%~`AâÇq¾ ŽN]¤©¿ˆÎ¼ŠoΫA¤6…!tóÃÄË¡7½^·]e2ª¯¾¤r{ô°$7¥¡yè©·ÍŠ†zg©ö ®iô vî°/4åP· ‰ˆ²w>õ“8ŽhÓƒp!eBQFõضU¹jl‹ DË6X™?ÍÄÉ´ ð£üÌ´p´,T×m3”ucWT7_J|fë<óc„}ñȤÎëÎã´±»v°úzØÚ¯žª50 ŠAˆº8Ÿ\œ;Mʆ*ÕFIC‘0=•Nª2nÛvk!ç¾Ü8 È÷—•‰'eÂì̦¯¹$3 ]}{lÏÃаJÈßP)XHò5mc%ŸX~–šÁœ[ÏRî횆 ê´ÝK¦Ô¢@dz/aÏôv@Äù£~Q"Rª #‘@®\î5œpnÕà±, É9ÐÐâ‹­¼‡önQ7<NÅ(1\ÿ8òè>qVïmU¯k¤‹C“m“ós+ ãOËkŸ~à3†M9¨Qø¼9gñÆãH[ZÙuyØT•½%(͘U½÷ĨwúÁ!"lÚè×w˜ô 8sÄRØu¦™ø÷³²÷ueûÇþì©i±™fkW0©ìÅ!+ë!l†·À9ûÖ“\솞Žß;ªêû} Ôd|øi©YrMPb}º±¨Ð·—ýtý@A¿j»Îöû¶YÕÍ­M¥J6ĨãgþÁ³tùQ 6âY6%WòÏRz=t¶Êè"‚b±a Y€Cv<ÌŒU +‘X¯ x¨²õ½]©¤—pìB^ \^Ù@!¶¦álñŹà#sÖYå½vi”2/|»¿0ØÉÆâ”…; ZaÖW»”)ü›™sìcòt³úâEx( R‰Ñf#S”™ƒÇ©{އrŠþÒ%;¼ŽMiÒµ:×î-ÇsÆcœ:7xhþ ƒ§jÉ¥‚òáf@'.!Á…°Ö͸ãprjö÷ü&SÓ7†+àTdH{ÌÃÀ+Baš{) Ç­¡âXóg,l?º=ãÞÇ Žã4ðŒŸ×ôÁ`þ‹Ÿ¿ ýp·éý­¾?}ð°Î'ݶ•ëñ÷.®‰ÈdV«À¥?:^WüOs`ò{(,Îs€ÉyK>]tF0w–"²…ÐsècÃd…0fd,GV²^Ê›9HFè„ê £ãæ%Óì›Ð<”;÷ïèqF†~‘žâ$òãè3=}¦§ÿzRÎÇWGO¶Ûwv†Ùãð Lb®Á>÷`` ÚdeY3®ÕÇq(䥯@¬H¹&u®IÌz]ƒ\˜Yxˆjj·SÐjŒ¼‚ö[gàÁ‰ätK ]7úCû±.u쪅€:²•áj•Ž_ õk|â,‚ Ž^ ¦—" pM)â'üRŒ+Wê¬p,F3m´‡A‰öb?ç\"ÿU§ONä³XÕ̶éø6“N`Û‚mˆù:CS …7¬´Þ®ëÖ-#_<º1yóB¾‚¸ÍxÓ9Ýaæ—Ü®—é>Üü®:aŽ!9ç‰S—ð„(0Àë¦ed³ a€œoºœm«£Ð4w¸êÀ5Hæaîu»•/+ +¾m›;•¸d÷ ;ýw”0Ký ÿLyxžGo]û”pÐAaܬ>¤Ä’ úõy,190ÖkÆÈN#ÛAp‰šCû) G‹ˆªMÙ•v¸…õþíû7óoßþ ©Ùîm7Ô£²{ÞUžUùÜç!™W’_CK» ~¿µªƒ@g=ØžáýöAd:¶ÊfUv«+ºeÄê> endobj 1284 0 obj << /Dest [ 817 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 638 102 652 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1285 0 obj << /Dest [ 974 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 350 598 378 612 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1286 0 obj << /Dest [ 1159 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 301 501 342 515 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1287 0 obj << /Dest [ 1159 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 301 337 342 351 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1288 0 obj << /Dest [ 1046 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 473 71 514 85 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1289 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1290 0 obj << /Length 2169 /Filter /FlateDecode >> stream H‰ÜWÛnÜÈE^ç+~j"Í;9‚ À+[-l#ˆÆ/YåCöh˜å/3V>$ÿÌCNU7ÉñhïFÖlhº›ÝÕu9uªú‡Õâõjå O¬6 Ï.þá'L}' ÝX$ËȉS7«ÝâõM—мã=®èòzñúÇ{O²é %B(û¾-×C¯:šz’T¾¢’›0äê¦V »Ë鞨`ÜjF¤ÇÝFô[dgóÔ—M-JVÀ—’g:Õ#b"³ìY‹ÄàM$GA¸…ùÔí1 KkIÁêrzkyIòø^µݰk %^éCæì`Ù öIÞ+’&d§ÔH³‰“ìqHÆà²À ,çPV•X#6àÛwRR½.T få‘ç…\FKü ¹@‰§VíËfè,þ Åe¬õMU £Ú]Ö›oUù ¬½±b™U›µÂs\GÀ•%Ü5 ˜U&•g,¹KuÓ“—/Ä«1Û‘è¯ÈyìF2C+/ÜK×e•-°ëŸ}µúÜ R÷AÒò>”Û2ߊ¡ÀÏÒ A&37eÛé½tõ9ÇzÞŒx“¿Ì§/ ɬ(­*Û"Î'a +±ÜS$Éé4©-.[UÏæQÂxy[`ªvXª=>è1.ÚX„‚†E´c,ÅÛ|÷ñ­x²l&8þÐ<)=è-;ÁöRi)–Ew8/BñRá#@ ëFZœˆ°¶Uä»1:ÕÇ(L˜ÔL¸v¶¬(Š}Y?T¦”Òjì5Ž)·‚ë¥Û'føM…$ #DZ0’ðÔ(SR–¨Èç«f蟆>ßò4k¡3‡êÆÆò’ó½P›l¨zÑðžAG”N‰éX–Ó1$yË?|ì«¥!òNz‰©èü.E"ø–EB‹°eä[ö“jE§#Ä'H‡:Û)À!ß6”â)Ê9å’ù¬÷ŽG0…~ÄÌ/wÿƒ œ­0Gwn%LXWsyÉáWÐÙXUÀk-A•Dô È ÌZªíƒÆ‰Ä!¹ˆØ¦åó”eœ…©†h¨!jxúBPØd7€Ï±7ÇË3ñB]ˆÉõPl“‚YˆFh©¢Zn"ÂçEÇÒÀÀEŸôaæÚ fHä zNÞËHТôVª¤ ‡R‹­-ÚMsþ÷½×¤Wµ>­ø÷«´ùoÊ÷;â̓šP×f.!Úâ<:ÎÑ™ëÇx­‡ÇGîàI±šgÔTùá½È«M¡(wO€ –ßašQ\©²d½Ø•ÝZm³½ ¼O«[;ÐW?"ëÁ4ã½Í¡iá ªÏªóazY‰¨©o>ÞßY7;ÊÊ"@Á™àýkh4HÑÝÆÇýxp bM£x夔«²fÍxJ,z}‰,^ʉ@ùÀ×MEPçÙÓ´fpÍóœæDЧ¿‚Gƒ(¤×È÷£ߴÙþ]yô{éÔ¿eFš2£#ÊÁ™ Aý.÷+Œåóà˧φ™‡Ú²ÝW$w -t=±”/u«îÑS%І»L¢Œ2/ûêYè/O,@奖÷Œ IØATÊ ‘ˆ&=uñq(ÍIÅ+f†çþ‚ä3£ÀÄÞ²pfföO™™nç]öYÚñg»M¥ù;¤L"L-5ÎÉQѤMAÚR7´K¦lú½µèÅdó_P¶&lfjÇLM#fj=Xëè+p~bcZÊõµG·±²bŸQHà§‘šµ.ÌÏg ÀË'I‡‡BŸ åº^rÚþŽiê µ»ô¢°©ï²:ç¹;üñ´_¥f/þÿ'5Ÿ!ƒuÓT röY5<ý±ÉøžÙ•Æ3ècÓ¥r“´åŒã÷#uLš‚õLŒL¬¿Q⑈w*nÅ”¶ÇôÜ2o›Õ[·VsR•Ues¿Tr«…L§žíÅ=êY̤HoÌ­g7Ú-û4…íÙÆ¡=ª!y”4¿4¼5þã“~2{çüÚ¼5IŒ\1栧³{ôßrößR_{·s¶jsM¦ÂXsf¬{3k¾ª~,)~Ì2U…\Ö{y¥(7Õ¿1õÏOÊH|f#‘d,‰ÞESÌþÅÙfR{ir)–›£±¿±H·ö¦êðpàáHͧA„ÓÖâÃð‡wöÛ»?SsÛäRïã/±Jù8´ÙºRB/N­ˆç?X†Dß­ÿ¼…ê¹ endstream endobj 1291 0 obj << /Type /Page /Parent 1721 0 R /Resources 1295 0 R /Contents 1296 0 R /Annots [ 1292 0 R 1293 0 R 1294 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1292 0 obj << /Dest [ 943 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 497 435 518 449 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1293 0 obj << /Dest [ 615 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 434 217 464 231 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1294 0 obj << /Dest [ 956 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 257 190 284 204 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1295 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1296 0 obj << /Length 1978 /Filter /FlateDecode >> stream H‰ÌWÛŽãÆE^õ•·&0âò&Š XÛcƒÄ6[„‘Ïúƒ›œ¹ÉØÓä­œ2F™ˆG³cêø‘Cÿ°¢›F·F·vÓÕú-™!˜!br?À"UöŠ€ §¤úë_H·¦Õđڙ¦¡{÷¼ézM¶kt_¶TéÞ–¦%»æj«½ÙnEm×N}F¦qÈ5佋OÞÅλªkW]¿a‹÷z]>šnìCz?lueʦ ÈÙ.†™º"TÀšÝ?ê~ ÝÚTAŽrZSÝaKKkÔD£©j8VL ¯±\»åT¶ÕºÃªëϽKÞÅ'ìb]Ì”®l³¿†l ¯gH2*UÌùj©®9(ƒi‚Ÿû3OduŒåµ†A‡Šºs¼ ¼ÚlK~òfº6tUTû"ˆ3—ë,LÓbNîõP óLlžU8ÊåÈ¿ì¨v-Šƒº[kº–Œ +?ê~„E±²H•?‘áXI€ýK¢å}×[ù^èQZ«7[‘ ggï쀋}ךŸ5ä@b-ä&m.HÀÊ @.JIr %q¡œ%"¤%‚‚ÒÁŽ*˜@•ccÕXS…á{Ïgöˆv‚—Û^? i}õCpº üÚŠ7Än«YãX{æÊü’šDùÉÁü u›m£­nöt§ z¤ŸJŒ ü\i2+àêŽÿØv»–‚(bFÊŽ&!u@õ~|WiíØÔT®VÌØTÆ)³1Èȕս±û»àשÉ,]„IÆE²9éõ3éör’B3 ‘“ŸF=ØM)ïOŸªÖàE¢!-›òÉÉ‹5ÀSžTÏ—µÈ0KÓ„ÑÌ¢xþœ¸B½mßUzLûðŒr/…([$|0ÿ^„(ù „ˆ‘­Ç¾òÞ)tаSwWjI Ž#Ÿ!ú,z—ôò·¬ä¢`Éî•pX¨ªôìpö÷R+bÁQ ×¨õªK\O #b6ãæyÄì3dSb—:¼SƒFk‹.³ø¥Ìð&µF’šµn´Ô˜±Œæa;±|Bi˜Ò*˜ÎU'=Àøžó8RAûq[ …þ2tР¡@—›ª—-Z'€D5³Ù²ÒÊYQ˜ÒÉ^ð—š=†£«$qH?¦ú±Ùÿ:ÑHsèTrÞ‚dÇO>ÑŒLèÍY†ª7[ûömdĽqÌZæ<éjäsšȰJ&k *Wn·9^ïOÒ Ý~~&p¿YÝcO·ÇÒ¸¹©¦¼8Sh?ñ¦¯?üxùŠRç äà»ï]åKÜ9ƒ1u-JãÿÐ.]>:|–ï°\oeoJn™k-=}Õ”Nφ?‚=¿DMG?n[·»ªŸ¤ÈÔµïl^ñT·Ò&)/4c¿X6}5ü/µó•öÒ—ÏWN]¼Å«ñž® s‰·íDü\éNž‹MæËt‹{ƒ®¹\ ¹ÌØ1-ËvkV)Tx+ÒÞ u˜ê"‡Žâ‹ÓmNƒ³3 ¤Ö·uSé§ü¥ïpn”˜õÐ^l%ã“ñwø±lF¹ÏÂC,FuÂÛ\®ph®P§þ›i}ÓÏœú0cÝ7÷×­8UΕo@± ‚•C™Õ§CN9y…Û¶“I Õ|]ŒÛð=l iÈýV['èR1¸ð;WÜæÊ¸[tñâ{áAÓiº±—f=}{éÍUYÅ©t¯ ñèžäüšÉÉ LnßßÞ~€û3õí7{÷=ݦ±SØ[m%Ì–EWÞ*á<Äq’;ÕçYJOYòÊö *äšï¸¿€ÓmgÙÙnçðã>¹Ö,$Rišå>âppcŒQêó™K6oÜ>–‚2äçá|"Æ)g8Ëgë¹t}‡ž(±åí²ªÄ4ÿ÷_kÚŒüj¡î0‡IÏSòñ·ëC‘±÷7bè`Ñm[Tk,¿Ÿ{{çö”Ö&NŽ ¾_Nþ3†Ê#J endstream endobj 1297 0 obj << /Type /Page /Parent 1722 0 R /Resources 1303 0 R /Contents 1304 0 R /Annots [ 1298 0 R 1299 0 R 1300 0 R 1301 0 R 1302 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1298 0 obj << /Dest [ 1297 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 275 689 289 703 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1299 0 obj << /Dest [ 931 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 332 689 345 703 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1300 0 obj << /Dest [ 1596 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 368 689 382 703 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1301 0 obj << /Dest [ 1340 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 381 539 412 553 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1302 0 obj << /Dest [ 1393 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 293 191 320 205 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1303 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1304 0 obj << /Length 3103 /Filter /FlateDecode >> stream H‰´WíŽÛÖEÿê)npYH\~‹2\±;.R$Å (и(®HJb–"‘ZYy¾Cß±?zfæ’ÒjWYÿHaxEò~Í=3sæÌÛùèv>”¯æË‘(ÿð¥E^¢¦³ØMR/TóÍèö]›ª¬å9žj³ztûáÎW«v乞çcN6šô‡‘þѬ åǾræ?f¼h¦¦ž;K°q˜º‰'ûòš€—ÓSœÐêŸô|ž3ñC7Ñ^ªGuw¬»5¾ºp°“nËV}ýa¬þñ_gã}‡±Øuéx:[ÕÝ¡ì~-vojSçÎd¦Õ¿ù¯óÏù_F|c¾M๠^æßà8\'t}ÝÒ©‹­q¤‹GÏ tf?­y§oç#_•jĉ&¾ §nšªÄ’ wŒRµ+FËÑÛùFècŠ÷º!¢=ø(²>Š\/7ñSç4 Ýip¨7êùr˜êL‘zÝÀ)ñÜ©~p‚p˜z§ºã¶øóMë`b ©nno†é|‘ñïÍ›±z9AŒ…UÉ{u'Ëê›V–aÅÍ›WršEy<JðŠ}ñ`_(öÝýíûÛ¾yûN-L[àÀHÃY³º³öÎÄ^_;ÕìæÄú]UÊdXò®©ùqéL" ‚•ôÒËpó7HÏpó{³,jس3e]䪬_±ß§zØÖ&NâNûÈ¡P–-dùëÖIÜTíOý+kê¥á.åêÍ¥}Þ PÁ¨t*µ&™Zeb–X¿`‘r3’=:³"“|­òBÌ~vb²+Ò ¾µÊÖfÛ2`Á¾Oö¹(”©ä±q|BÇ÷Ç ™¦üDÉ÷­ãÓ@‘•tóÀîž™Š¢&Ò¿• Ê&ršÊàݺ“]>9N0Ôs˜…f8ù䂯‰"Ýu»r±ïp[¼úšó²/ Ÿ‹-r6KJØèê`4;n0ò×Wr;Daÿ®òõRÍ“&»?zÌñ²f³5]¹(û¥ÝÑIa)'œ‹Ô"0Sv—¾ùäˆýã ×þðNøðU‚Ó­¹ÕÜ!ú\³eË/ªÿ=¬Ùùp ðo!ßK¶ËÎÁ@Æy1«`oÊR~SÐ`«c ‚,¤›R ö;Çç­sÕ5êÐÈ’{ð‘u¯â¦‘#:xJÈÊNGU|¶ve½R`lxÆ6‰ 'ç\“›Î͸êcZþe_îŠV-ËÝFQFéûº9TEŽOh³hö0Vdž\“è=èÒìVE§ú­T{l»bÑl0> œÙtrÁe¹üIWæHdž¼QŒrÄ‘|õÊaÒ#ìðDS^齃¤Íxý§ðòõ¾ªŽî³(ø§å¼QÛbJ>]r*' É qÿ¶Ä´´‘²*Yehhª7Ûª¿Ò|ö,ÍE<7H†ÃAÝO^`.˜…¾ÐF[™Ûäû €–²/9¼?‘ê9’—¶Ú:“ôtjvoVà|HFÙk›É%ìÁÀ¦ùVwb7™ÌÖ"P]òr¹,v}kU³¤¼Úºg™õEI7åzþígCH½’ºþÞ·…Éiv Qé(vRù¼žuP^ßôb# ]/õUœ¤.øŽÆ™Ìxq4N†Ñ(ˆ òÎÇc/…1W—¿0<œ=¥meYžD—«Ÿ‡B:jß#5…JGÁ pÎ'Afcê£Ö̉¾‹Ê­à×–È ¤AmÙD³Buò¯ß«¢^!PYŽÙ¶¶·­U°ŽZÉ`]€’PÑúÐ>_XI¸rHµ úLQ=©Æ) è¾k6à9ȯJ4—og5©vöcqP[hë)‰ ®2¸ €¹å´Lbo*ìÂö¥@a•®bિ¯EÕ„ÄÔë’÷;þÁ¼‡¢.Ù1—…ëLÇ1)÷5UŠe‹­ ð¶Ø ¤äŠê. ¬s³ËUËLk§ŽUÙ©@©t YÒ­ª›N-+è*GEÝìWkª"_ˆ²É!‹i>ˆ £¾)•ºélΜ઻†¡¥o$›B]g CÇ_…N:†ÿÕš4N‚½@úá3Àrˆl˜©õÿ]³kLÍ@oÔº9ˆB"÷]‚,CåæÛ($¿1‚±¶¦ÚÛQHŠq5Ÿ“KGôHoé+›]ïmrñÁÁô¢bþAÊ¡Í{pˆá#ô©)„p]ž]Uö¦!Ë$˜Ð9áÙ½HKïåWD§%ÒŠ•6 å@¥mÝEKHv+í¢ !­²ßK3€¤Êö§ƒ›Mù«¡øzŒÂ¤¯ø¿Þ©Ãól‡7_–fàœæ¡DŸ§Œª÷”„¾Þ,бSÏ|~¿mèB¨x'½œjÃú‹¢¨rè :9D d׺©rz-$"tuQ¸—-Vÿ¦éh§ŒúŠÕȃš‰D¯j¨²ªj†¨á>ªÀ ›}Õ•ÛãI€½‚ ñû4PSäE“Qk[÷¢ŸbF±æ¿äñme2´bröRÚaùÂöj6è™@‚Žr&R=‰Eê¯8ÞŠÏE†Æ4wÿ¿1⟀ö-ÐpÄ9ŒÎŠ­€ £#ùÄï㾜áÆ&W ÉÕÏ~t%Ÿ®´…Ò*ò±bZ”Î’¼e#’ëL%“9ÞsírùÙÊ"4t›K>õHåú±¿_nnÏȸm•Û•ntŸFz³º+ÓÈ8:+Mõx!…¹t¥`õ¯Ð†~pˆ1~¸æÏä÷ÉùÙ)qfrÑ÷H†…ÉîTþÐmQeU¢tàþÇ1_ƺ€n ¬é¤I|Ž´f'ЈÚK§+oû o&çkUß>9Ô—ÙÊUß5‡'-Ø•T,8Ç–HÎú¢j!ôÔüŒx’|s½C™DBžeϪW _ÎZÜ~Î{ªïí§ óRft¥¤.Ô1»LtÕœû´§b/+›ÿézIµ)Wë´SûÚ<ì0+®IÐZûn¿+N‚Qhmé„}%º¢]eçÓj.®OkÃ3ônÙù±¼Gn!v¸<ØÌŸó4Ëøÿk»Úu‚`Ÿ¯ Ä’c çeËQº´©ÒÅ $BBœqî„øûÌî,o:Öë½}ÌÌöÄÑ?dY!v©çciiU;t͵·•ähAôœL®*…„Ë"‹„ŸgÜa´!d ²hÓ¯¸WÅ3 ܫ೪Y™t"XK_¾6Ô»…ÏK'<×€çÛVÝäÀÉýŽB+ª;ž7'\ÂéÇAWg*–¿Ç›Åü%k Û((å‡f:}¹0­CŒß¶h”Ò ºÝb:VghŽ¡7ØÎç¬É¸v¬Ü“^Ð-vÐÒ`zåÐÒÁÔ]ŠÉ9[…°•É«ƒó¢U< ZºPeÜnY' ó€uÛYZÙºªÚ0ü‰EÊ ¢eQg¤è`íõ–߯7U#äÍ÷€˜ó<Â5$ÝÏšn®ŠÀm‹L H¥21ÔÙ[Q1°ÊO RA†!@(+…£ #ÉÊ- ÂO-ô_ Éß?ïþ†¤¬Š endstream endobj 1305 0 obj << /Type /Page /Parent 1722 0 R /Resources 1321 0 R /Contents 1322 0 R /Annots [ 1306 0 R 1307 0 R 1308 0 R 1309 0 R 1310 0 R 1311 0 R 1312 0 R 1313 0 R 1314 0 R 1315 0 R 1316 0 R 1317 0 R 1318 0 R 1319 0 R 1320 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1306 0 obj << /Dest [ 1379 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 146 708 174 722 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1307 0 obj << /Dest [ 1008 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 146 694 174 708 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1308 0 obj << /Dest [ 1385 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 307 694 334 708 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1309 0 obj << /Dest [ 1371 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 195 646 222 660 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1310 0 obj << /Dest [ 1008 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 207 632 235 646 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1311 0 obj << /Dest [ 1385 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 368 632 395 646 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1312 0 obj << /Dest [ 1008 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 125 597 153 611 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1313 0 obj << /Dest [ 1385 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 286 597 313 611 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1314 0 obj << /Dest [ 615 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 442 562 472 576 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1315 0 obj << /Dest [ 1330 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 167 508 197 522 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1316 0 obj << /Dest [ 779 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 399 433 421 447 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1317 0 obj << /Dest [ 1174 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 431 406 481 420 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1318 0 obj << /Dest [ 1400 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 195 191 230 205 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1319 0 obj << /Dest [ 1411 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 195 142 230 156 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1320 0 obj << /Dest [ 1495 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 150 80 191 94 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1321 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1322 0 obj << /Length 3671 /Filter /FlateDecode >> stream H‰ÌWÙŽÜÆ}ﯨ ¸LSÜàe`È–-YÓ1àhƒÃfÏ0b“í&[ãQßÈ?äósï-.½h¬yè!‹µÜºË9ç>[Ì/žrÕb5s=åàÿ‚ijƒÀ‰Tœ†v”8¾Z¬gŸ·‰Ê[žã¨6¯g¿½tÕM;slÇq1'ŸÍûÇ»™~“ÝÊ =e-þ6KyQªbÇN#lì'väȾ¼ÆãåôF´úþ—‡Ñ¹çXs×·#í$êú^]Þ×Ý-F<]XØI·e«ž~{®þúokâ}‹o¡êÒrt~{®.ïÊîS±­x_gõÒš§Zý“­÷‹ïf|c¾çØ^/0ÆÜÝÝÙ–o»º¥S :[ãHŽíéÜ ÝòN‹™«J5óÂÈö#Wù±$*ráI…;‰Ú³ÕìÙbp†ïbгïÑ»yD³÷£ÀÄ(°Û÷“XÉkïÔ8 íØ›xcÆ«˜Åw‚½®íZ œ¡ÞTY^Ü6ղض C¡^5üe«²ªR—?½Rm—u­-ìé¢îZqlJóf0Ä mwjˆ²!bãüæ’ýF&;HMÈädÈ(z¤•[ ÷Fèçžëyk-Š8Æ ¡RùN>î-¨»á@ל˜Ø±+'Ê9ñÄÌ][ È-ŠûKQÑh© –zÆÏ¶ZX1RçÖ¢“‹£ƒ=Û‹:ølN‘bìºcѹ²¸$/$Z5×]VÖÅR¡nÙ'ßìä{#`×Dú…Õt/ß~«ž(yê`x¤ýuÑûJ+IÕ äAŠÇ ÅbÁ•¦] ú‘mÑ•¥Pw›­Úɇ²¾aƒ./üþ²!Ñ—o¿·PW¾øåJc•ÌÎÉÜDoËM§V»:ïʦVe­¾©š›²Æ_w4ï‰Ø»øóçòHL ÙD$¢ÃI³mŽrñšó/;)0krI&™^ŠûèÈ鞸v|eÙêǦ“}p߬ãK%‚oÓDH†D0ypo`L€p’ᘡÜMÝf­Á(•©u‘ÁC7+¶uW™0¢8“Ãè û¤ã>©ìó1«v…jêê^!*:£MbÝ¡&ÈÛØœN‰ôÎrñ›ç…¼Ê¯ÌÅìLû0æ\è0 N‡‹ï#Äòÿ!„挙ËâcÉ€D)NDšüOA":8›%˜pOÀÄôhŠs]o© Ú#Ñû`qc¥ºèøØ‹‡|-Ë~cò­žô¸Ù©?â‚ëÔc \bÍ}†—àUc & œ µEEµ´Rò˜*ÌÕŒ#pмT/^\È‚ŸÉ¸T¿|n!µmF¿—²5“‘AA–ü$œÌ"Ø/ÑwÆuèÄ!'‘ˆŽ â#t 'è’ø² ¨ô8ù¯Ëþˆ¬" Õ ½_¾yKrÊׯÕGhòáÀ×0›mѲ8…eÐX®;¦ïNóµáT_ƒ”¤´5}®înK‹RÔ`ï­Ê³š]s](SÜò¥£P‘Ãö@qaü‡·VoŸ4¼ž‰>^’9t ’åêáØ`Âcå]òDJZ-ôøåë×?ð6O_2´þÈiL2Tﳟ9 Öúš2ú5FSÔ$zÍ<Êú/ʧiµT^¡þx¥y%ë>ߎÄ#ñ'­B¤Â8µÃȨÙ2Á'[b²Q,ºð¢.à¹WÖ>éá6ÓÉÊ1dW„£ßàº~Kfº’¼ð‡w¤'iÌ£œ2‘D $õ$ I$/Æútʃ¼)?ô¥Ôƒ^ÑrýäMÝ¿wØ‘ŒC&–æáZþU¯Åa©¢Aˆ'7›,)U=æM­‹¾Yè­‹lgjœ?U™dIÌ:pÿD%<¤0í<÷=2窃TO/xJIOu×lM=¨ªüP°Å×»²êæ¨Ö‡//./%Á_ÿøóÓ·”äçj(•$a£:I3BËrQQ™†÷¡±a|rmØED3 -ð¨ýÈõ´©Ì·¾-Rm¹Þ@àER:4H[b%\‚> Úœ-_‚®ôÑlÉ÷9àT›U¡Ì»LRÿ2£ùT/Wê¾Ù©ºaw ΆN„¯K£™Ö˜v½iNŠÍ‰ø®ž&K[ÎDíR‰Ð¬ ¨ê¦ž?½|þòå<¿Í¶YåJ*rÛž‰?ñégHžóœüÔ¬z´½\¢aøá—oo›]µTÀ.¶,t¥&}Ø+Ô?aüÏ^½$.sõ₹ÉÕO…ó_qä(ƒŽ\øéC™&Y•öl_†^:ŠóG `gʤŽz‚ióÑ©ë†ð›„Nq¾*‹jùk?°ý`©ÞÑ…C}N¹žêå5Ïéî7KÎ@¿cl?Ï›ª |€_>ïßðÌHë;À–C«Æ¢xnµÔ=XÑ=蜱ópLçAtåAÌR3ÇufìÿïDcÊÛ·òFT‡¾üéÝ@»Aþ­ ´ý&5¦gJÞИmé•®›í:«P¢™zýâO`ˆUÏ3dp¢«JÙ¶ýu*=N —àN±Çs†ãû†øq‘<59G%ÁÐÎ|›*¶‰Br&Â<&È„|HpÀ²e~ËØÎÞ'It MD6GÕYy­ƒQäÈÍ®›sO7ú˜0ö¬‘¹ÛQ¡¢ŠýŒš]wr?Bž³[Ò†Wڜʓ1Ï`Ï8ýØMdÚ¤Ï›Š¾RH3ûp3•Ê‘¼uâ]…¬ªPF"L†8ùÚ^BZt?C¢qyd®½R©LX_g•ú†M"Q·Ú²³S½fÐZf]FõúeBYW˪”±î‰ ‘ÏH„òçÉP.Ç­ nYR:§Ì)ñ’òT¿r¬²»©JÑ »†P}ÕŠÂAŠáfCȈ ˆHœ½vAô\/ëÆ0)ä¸àr!àŽPËý†&Éæ$B‡E¨×»¶#nt ¹œý9g<ò€ÙéAœŽû†ël¯7P'Et?í j‚þÚQäB‘àu³”}vFKÎTÖë¯wÔ`¬³‰]((+Ô¶Úp9ŒÔžÌU¹±v'åMÜØZw¬óreQËËó£ê@;Á/þŽ‚84¢eŒÔêT€5,ê7B%ÅQ0úì3¤®–ÅŠÕJ¢w@*Õ$„uFc)+h ’g2k/¡ ñW§ÀÐëÓ€ÃNTV~*öÉÈÛ«f×ù¼·Ž‘rÁH ¹¿oDQTe^vÀ'SàPüÉBëÅõ‡hP§Fí€ÄÂÕ÷”CžÈE˜¹[׊f•,æ>Jf5-‡¯¯5~Éh} ¹ìxÀf²>]ÁÑHͤ¥¿î+2é=²¯xˆ—¡°„ÉóÈ*¨íVv,y·§$qÚr GuÛ¬Ÿ°á Y^˜wî.íÜhöÐQãÁ|§ëGÚ¼°PÉ0°>&1À2yÀ×=x=Ù0‘ª%Z5ŬJ*TZOïr´Æ ZÒ‘`Ì›5µ6PÂÕ}f¦ýé í=H­!ûz‹ÞÿDŒ/É(‚°00y ‚ °æ£’ו!r^‚¦*™?Mz 䊬8=Ô8áM•õÍF«,òÕªá/ÿa½jzۢཿ‚KT\)VÀ`@ŠrjUõÔK•Ú Å$F±!†E©ÿ}ç},,˜$—\êt—Ý}ûöÍ›™–ôì…Hèô=nÑ WtÜ':¶½¦iË»¹ŒEà` QäèôsÿêûÏ9ú6±[kÑü2ôivãßÃêAí?³­%v—_S¢S¼4|~·Ž+#óí<*]î¨Þ*—R’ÑÁáÜ忲@ëÝQïíÊS”E(Jò€b7Ý % Ès4ûˆuår.VÔÒ;~ÂúuFb”:™çŽªü,cY«/öe¬ @&Ft/¾)‰`s œtZ•Œë">ù­£8º•åûû/˺À6}[3M‚¬<ÈbÖV“Þ±dk6±ÃDWj#ç” *àºm™q”lŸõJx]áSLNÔæ‚Òu8'f® l°œ± ¤oY ètç9Æ×YäPe4jù‚©X’í¹U”—JtNzm< ‚a÷ qdþùRænÎæÊì7l’×ü5yU“X¸“!dœs®nÝŸ¬ÌYæ»ÓáÎ uÿ®1C‘…ä¬sêHµàz,:"¢® FfÁjC]g¥´wAßðœ±s»pþ>¡¦fáQ+Žo¢eŸ‹‚ä;–y–.z¨?°\¥@驺¹L~‰’h« Γ]z–CÅõ/WH+ˆ²^ŠE+ýÓu<VýmˆVCÿ‘Ò“€y°^ÓoêÏûï;xó¯Ì´ß"°øM”¡‹nnÐo?m¨…›I«ß:ïiòö‘ye4ùH”áìh:”’,A, y8VSZˆ!™/8£MRh a2® ÃZ-ÁËf’'?ÿmä““8/zs³˜ï•Y-“8^‘ú³MýŽ É/¼V8éráüšN¾-“q£$”ÂÙÊý")œ­Nj '%ðÔå‹§“E#ì„Z¬Èß}Åd_Ê}¥«™/ºê‰daèëä4™ʼîîUÙ|û†Ÿ$ÂÂ^?AÞ,¡£ÐÞSï9Ÿá7¬æ!!…>tÕ^^˜dy†¶ýN+t²ÕöBØ&m©+%%)§DOøãk³’lÜJ_¯v¹,[¨ø¯êWޏcÛxìiZF·Ÿµ6CÍÄ7aI¬éÄÞd1–ä6”CS¬Áù¡ÚÑ''ØKóøµ-O½­d'”ÃH’Ó©vÇfWÊ" ßxË&æ ×Þ¬ìƒu/«¿Ýú/À\b endstream endobj 1323 0 obj << /Type /Page /Parent 1722 0 R /Resources 1328 0 R /Contents 1329 0 R /Annots [ 1324 0 R 1325 0 R 1326 0 R 1327 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1324 0 obj << /Dest [ 1174 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 286 592 335 606 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1325 0 obj << /Dest [ 779 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 478 134 499 148 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1326 0 obj << /Dest [ 537 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 266 121 290 135 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1327 0 obj << /Dest [ 1174 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 272 67 321 81 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1328 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1329 0 obj << /Length 3738 /Filter /FlateDecode >> stream H‰ÔW]oÛÊ}ׯ˜£ËÂbø-ªHÜÜä)‚$½ÑÍC“âb-­,62)ˆ”÷‡ô?ô?ö¡gf–¤,;‰Ñ·Â€E.÷óÌ™3gŸ/&O‹„bZ¬'qBþð“•I˜eQA³ye”Òâjòä綤e+}"j—õäÉ«1]¶“(Œ¢}–“iÿx31ïí¥£8O)Xüc2—AsšEá¼ÀÄi‘Î+cÎOyÁ£?™'h&Q0Ó°0QI·ôá¶î6hIŒ 0“i«–~zuNûO0Íñ¾Ç·<ÌMDf¹9§7U÷O·ßÊ$©±õ*˜Î ýKþ_üe"'–Ó$QXàeñm²ƒ›››0HÃØ´¼ªãe15– ñ…‰Yú¦Ìôr1‰©¢I’aZĔβ¤"’„3f%íÝd=y¾ÀHct‰î¢1¢1"FÐCŒÊÓõHΊëA™æ2ðì«ÙG7LS¼‡Âõ +M“yÃ,,ï4Áwþ­ ãêŽXÐUÃ]à#1ý°%zmoéÒÕN[,O”™Î­¨Ÿ§6ËFßV6fèuãçæKMH‹M%+éY|ç–•ÝbæƒleÁ±9l©ªi i¿ÐmsÐmJP¾‚¦qȇԓGñpr~”@W݆š§²mçöˆv·"°…ZwíövK+×Ùj‹/A2òç–˜‰s¼ÙŽj‡ãu ]8ÚVõ— TSìGÚ™><°_Aö¶ø£†"C‘醚¹qŠÑ\0Ê óŸaʦ 0É,ˆpæ#œ…Q†gˆt9#}íiR”³09Î8´ùŒ‹üªà2b½#ï·vé6Ívåö-¡)7ëF¾ìéÃ_ßÐÊv–ìr)M®m©íl箄!HNŸZa–¦ £ŸEñlÀ?AGðžb*"1†WHÌÞ=NvO™†ãdQækÊ0rÅ¢O‘›1CÙÊ‹£Ýx.@‰Ô–v²úæèÚ › Vü_-3Ì¢4$׉< '—©º øhü’ýËîÀ4 â˜£É ýºi~àH~Lˆdf€Â @$xæŒætd(–9{õî³á¬¼Òp• ƒG?A-‘‡µD2­ë„h¿ ±j<82/<"§‹ÔÉ$"5Ÿƒ»Rƒl,F©r WöRÏ"Óq–³Z“þìpxÆyØSÙ·p¤æ ÏКF¿Ð™ü¼’ÆwÁ_–¶æü;èdÈG°K;ëMÝ £m}Ë<ÖЉöøX†È4V'm„ÚqÝ@Ī`ʯ³øç!x!8i6 ÎtàøüRMxOÔìüÓÞò/¶Q55¶IgoÏéLÚ ÃYM Ó7æ¦o`*”g×ä{×¼­Ô=³×ô±Õú/üö¹ÑD¹dÈÏÛâl(Žëf;ôЦ?Ñ/ûæŠÆ½ß±1ýôˆ[‰íÌ0æP½ÝYWn»ÒfÞ˜<8GOñùÙ9!3‚9ZR…i?f¨~h¥mü(º©…wU/·N+ޏäò×lìµ#ÛWxG2†#3y·wí®©WU}Ù—ÚØÓ8Ël0 9²ä÷º¹Ku`UÕSPÊd¿©rN+åÊ­íaÛ ™=®—Gëé±èѪ~Yð‘‘dÀ\)“<(T¿sÓµ­r~€ ¸j¨n:Ò¦ EVêL¬‹±¹íÙž‡Iv·¾ª³ÐͳS8“ÍtïºãäZ:=æ™22×cÚ®ÛW‡Î)Ì…ÀŒ$måçŸ3Õ}ÓºÙ“ûj¯v[ÇeÙ}u˃ê}礨]Xí)ö;®O1ËbßY¹Bø*žCQHÃ2Iö v–V•É=õÏ™èÈ#g—•­™aZZ Ø¥Ñÿ²pntvO¹”©|•*_3?±—/Góƒy䥾OCÈ{<ÿ_xx¿‹… |•[7}™åq]*€ Ì߉húºvdŠÖ¢;¨Âþ[‡ èóV½ßª é´`â{6çÉgå0yr\4¿œÐNúv{Ùº§ÃοyÚ° ¦1õÅ%}q·»mÕ_® < îµTÜb,Xå8F3o®= ;)ÇNW ¿šBœU.@`ãÂê7?pÒÛÄ–¤æjK}jpz‰ã˜¼ùCïÓì5Œ¯½àí—À™K Ôw£ï®– \±vHlŠ„Æµ»a{ãÍX›Üh_ŒÇȧÍLu]qâ»]K™æáLóàÄÏäNÀStÜtpÀÖö-ðãl áÁ›%>®O¸þ×/0—V—/usS“]³5çeq—Lzÿ¾ïhcaöílYìãç ü6Éæ#ÉŽ8¶û‚Âu’;eþ£ëXœÎq³4^Åô3ktjêËiw»s„ûÐîБ*Ðp»r¿ )=†ë[¥·©k7Üõ<åÚ¦\^ Ç,DœxwÆ÷2¦þ1,²»Ò×þâáï[JåX‡íë˜À iÚˆE©ô;õ¿6espJ4À­ù:¸¾? “±ÂÄ_55Lûª–¯ß~xù«®vN(*ªÈ±W䇒åi8Î[Ÿ§°%^#š¥[|#2 ‚êß‘’ά¥ŠéÈ¥«½Hðæ(V«;úA¶/yµ¯ P÷÷AÚ,ÍÑ,å@\%}%ú«Ëo‘º:%õ,9*îGWÌb$užD¦µê!¯ÙÞc q$S®ÕU-%ªà.Ýþ„ÏÇÆ™§ê˜¹s5ºˆ{{?KewKAš'údÎÞ21fæôþyRîkÉÞíà#9#‡Œ“pêx ^XcéÃË7/^?מrÔvíãfZ°ÚKÒ=ȺٸúLW¿ÙWLòsY[7j€ZdÑ·%r7á äV: N<3ž‰µ“>l¢öÕhP $òq‰*zmή¿iô§£" Ò‰ªË ›5ssš 55µÞàDF?þÊœJÍB;^ûtRÙ‘‘ìíT­L÷‡–>þôæ7ç«»–sàÇMÝrS%À‚lÕ ý¢Ñ¶GÞ¶kåaiÕ?0X„´3p;pkb©ö³·?"ÍXò|Ý·ÿ7@>ÆQôÊÆòŒ«ÄƒXbƒV±/p~6£–ý—ñjÙm‚÷~¡¢¨ Ø„IÉ’ Š¢‡žÛ[Óƒl1;r]§Iþ¾³»”DÉ ÐƒSâs9;;ª”œûezþ b‘™v‡vÊjŒÔ%m ­gð^ê;ÔÈ«_3²Œ'X"ô|`^Kƒ<—¬G~ë÷S;i“U"—É];‡RÏ=ZyéTòAŒÂß»”ß$4´L½Ó+ý¢®nDîDÈDÁ ÐW-èzYËh5wé–!‰ê²®1«¶…64¤Ù@‹V„ª£ƒ¤vwºü†­i„1¥.çCÖÜùgdc­^W±ŒÔø{Ò ½³òåyÙÈË]ÿïI¡Šñ¶b³ì¹3Ó'Jæu$j4/ǂԨAD† ÇÛ²Ò[ûvL$ ×ÉÖHù&[£(FCo ™–%zÞGevúl¥1?½¬÷>¶^ôDerY¯>ŸÛÇÆ½,±,å\³CŽâ?e׊W‘[È `(:1ÏK‘Ÿ’ÚÊV:ÏgÕgTþ¦Wþ@~!ÙKe/¤²W½ª«R¯hHÉu$š¶lÔÚG¾œd‚|$± "Âo¤[ÇÝŽƒÃ S~ô+Üø¡%êªêV6â”aI¶æ§6 3žsB/ÑGݽ\°{qŠ^íÕ»ƒcäïrNLvç]+D‘çuÍÀÆ×àóf”&P$ĸØf•MlIŽDßn&O2mÆáv,Ö—¿%ëµ¶rµ6²± ª• ÖîNTnJR`ÓåŒÎ‚åæ,¬ö¸Îϳ*9$JØQXV8–cvèž4Eâ¬,"kÇŠŽ¨×´~²¥Jž¢³=A`Éß½ôìÇñ:õ£l©QIþéÛç¯ýVøºa‰¯µ=±‹ÌÏ™ù’­¯ 8q-Óȳ–"ñ:íKº0c‰rÊïow£Ê4yo:žÑ2úK΄- AÙF"³{¦QyëýÞÉ_yRå“bÂÏè­ K@òY8ÓŒüu/38À´”8¾– +dc–J6uÊ؇ñ½Pª|’,í$kiÉ“]Ñ6}Õ±}çÃ] ÒÄT„8 O×I“‡È¿öOŠ$R…Twêñ¹ÕÅffx²ñª¼È#«qc¸‚ž•˜`ßÒõ™¾rÒõÐ=+ÖMß*ÞHiœ@G¯iš±øFºË5SÝ$fÜQ)[a¥"%»B¼àª!án±Ù¢è¼&ÿ„(8‘d»\„Q[˜!GºïþçvAþlI8ÀFF6Ÿ çf>6òd¹â „+’"A–HÆœHaøh%ù5‡ˆÅ%gÁ%gÕ$d7¤f6P¶~à[n6òñ" =I3¢"˜ß ê¯jDŽ&/Ó{Vìp±ÿì÷Ë÷wÿììeV endstream endobj 1330 0 obj << /Type /Page /Parent 1722 0 R /Resources 1338 0 R /Contents 1339 0 R /Annots [ 1331 0 R 1332 0 R 1333 0 R 1334 0 R 1335 0 R 1336 0 R 1337 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1331 0 obj << /Dest [ 656 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 446 503 454 517 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1332 0 obj << /Dest [ 1466 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 146 409 182 423 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1333 0 obj << /Dest [ 1466 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 290 347 325 361 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1334 0 obj << /Dest [ 1008 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 485 220 513 234 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1335 0 obj << /Dest [ 1385 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 205 206 232 220 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1336 0 obj << /Dest [ 1204 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 89 193 139 207 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1337 0 obj << /Dest [ 1174 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 326 121 375 135 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1338 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1339 0 obj << /Length 3917 /Filter /FlateDecode >> stream H‰ŒWÛŽÛÈ}×Wt H4/I-‚|ï&°7»²ÎE¶FŒ)R&›3ž|Hþ!ÿ˜‡œªjê6rxwÄ&»«««êœSýj5y±ZE*T«Í$ŒT€ø™g‘?Ÿ‰J— ?É‚X­v“¯ûL=Ï T_4“?ޅ꾟~„˜SLfãããDÿ’ß.æÊ[ý}²äEK•þ2á8ó“@ìòšˆ—ÓÓ"¡Õ¿éEx;‹oÆ~¢ƒL­ŸÔÝSc·xiãÁ’î«^½üqªþúoo¶À¸Ã·…¿Ð•èb;Uw•ý‡éj6ë¼)½ÙR«ò_ïo«?MøÄ|š(ð VoðŽ=x||ô½ØuO»Ú¦±¥ÇÀtá^mÙÒíjªJM¢EâÇI¨âÔÏ2•„ˆ¤Âç™êÌd3yµ:#1%8Æ1ºEDsôŽ™ £¹Ÿqf’ÀÇÿ²a ÒCüé‘üÿ®v¦«ŠïÔ'ý¸­¼¥Ÿ"(jgò¦÷þ\+ëÁÿþ‡:· gTy=Õnx°©L]*/ ´,v«*·‰üLwÖ”*ügolËëî~}§øíÌExúp÷¢1ÕôD޶ƒUýÐuíДUs¯¾ ­5ý'ÏWh½Ú"ËøÖ×FínŸÛj]Þƒ7\›mþPµCGžß”ðD=˜îtû˜óJ{.qZÊötšGÄËP· asÓvFE~HÿSõˆHqìΛÓáycÞ ò‘‘@*Û ôæâš~2ͱ•G‹Sê§½ Ž6ÉØOÅcðf§ÑÛ#A(ÂܛŸéò±¦óPï©VeUª¦µêÉXe¾V½*`€BDY}Ì{LÂ4 ?š_¤*ÌÆTÑmf -Öz÷ˆS„p\UR &2,Ý,Iª9dCÿ g¾gl!Ò™Dœ—œäNu ¨÷”¢ˆ|ÜÏFõòbðè( 5Ž–—%¢m»|œ°ç yaܘ+EÊåMu´Ï»œ8Æ}}¡Ý`J…‰ó·MýÄÎ2F,~c±ÌØó‹Ô2'¾7Æ”À)mDÂÌéŽ÷Xh®Šƒ7î%ãÎc‰%XyÞ,E wtªs7íw <:Æû"Ô3ÐX²$—ÓåÑe†¦¾¹';ƒ€ÛòÏìIî&zïFcÓX‡g:qmä; ßcˆð©×OÖ-WRS¸ò7'ãK·S…D˜/áÎ}Ét­ù]󣯾ò&ƒ°n§ÖMsËÜ¥¹}®Wñâxþ…œŸÌçÌ)2EÚXy’Ü µ­ftJö%÷¸\ð4Ó¹‰ò3x¬l[•»×YñïÛYöÉ#zÍëÚM¥ZH›{7«GH0È” æ*ý‡É¡2Ò÷6[¡`†sˆ*›Q|݈yS| ·‚(H{–hµsÃ{¢ÁŒÂÓAã²~ä«Po8ÂC-óX^ªâA!S>Ë&Îdãlª’g͵u¿k·j´¬úý¹ñ}ç¾ Îäøb7žÎö¾TØþG¤põŸ%>••›´”ÀæTœ¾±c7¼Ô•Ñ®T–ÔÓüÀxs‡,³ïLO âÚ¦Ìá.ÊèÓ¸ñRò¦ÊV;~gßS•t'3é ·_KIôœSK™ÝӞτO™‰¸+ÁNµ›Ù[…:Xâu+ÅQV›ªÈ…E¹V¿ŸovÂx¶jA`&6 T`µ¢•‡]¯HðíÌ$üÅZf œÃ ¸ !4v ‚Oµq³˜AЙïyüNæ»9”„…³÷@GˆÇuSé•°¤°Ðg‹/‘ó àŸÀ½CÃGdFÔÀ¨œº$ð’ùº¯«¢²à­S†`v­„”ÂEŒÆuŽ˜.ë¬!nðJ¸2"®Yâ*S¯A,“ÁÓ ©ÿ€°ArÕ›¾§¤õÛv@㉞ÎÀu0 é¤K•7®Ý±†ÚıCd‰¼ŒÝoºÚíÛÎB`Uµ¡#`æ¾¥ªt{î$YVC°F@ÂfÇC«¼£æ’Åo›sxR}…“ìá°£¹† ê¨rþˇ¹ŒÈÅ5'rîÈÈ:QŒT¹§^ààF @ÄyÏ—ŸŽ)¬½îF¤Î‰[æK|¾M'ÙÁ©ù¼$+™~{•/‚ó^j6>2Þ( ¨4´ø…ê 2Ô 5Šúf}H ·¨AKªA4AßÕÇŸn?ÐIæúV5nU°5ú \Å ¡BŒp³~ºZoá 8Àæ/~ƒñ, !wîGÃUÏTɘL¸ñ õö 6½Ot»ãl£+T¤|©<¦¬Úº•J,1Þ¡ÖÉbF qŸŒJ¹XO|÷ßSý%hkÉ&úÄsf›ÏåxyÛÖâ2HZ‰)pT ~¡á;ÐÝ-b–‚Sˆ,oų×+™/ó,·Ì€ûŽ%þÂd˜×bÝH‡—O€£Gå…H•#müâUZ"¹ ©SÍÑ…ÄÝâŠX˜º‰_ÓoÜóÎŽÂÎå±€/·ÇĹ–‰/18eMDÁ·ÙCØP¥nˆ4sSQ¶ž©ø²  ØóæÉ¿Ýçâ8J‡S:άÜh ªOµmwã窠¼Œ\ì˜ç6*ËyÅ"Ò)׊·Ê ]#Ú§î~}§>JÇ𓼺• ¸oe+$âÜ‹Þ ç¤;”¨%µJ÷[{=ÏQMÍðcÛ}æî‘.˜ñc‰òRËÀ—VK;fEåtbDåòuUW@>ŽäÎ+-(Õ_(êüæ/Vµy0µÄ0ÑÄÍË·r=¹È ¸êã[ApL7]y`]5Hy¢4›|Ũåeý37Çõ\FEîö5ì’¸ê&ÀuRÔ=”¦]³¥”ƒ¨|ÃY|¦=c‹-º3#¥@k=îYypC³,V¢Zt÷ázÞê[ñªîŒU(×àqýö“`2•¡"Ìu©~½Oî^Ú¢«"b…Nz‰]Hz9Í…‰Î˜ÛCTÖÄÑx;r¦ÜN1›ð™íÿŸž÷\¤>Š^ÿ/‘zÞ1‘H¹VæìÚSQzWÕ9«•7¥\Ð=I8öV&/©q´LE¿81DŽo¦Ç%Ò Y"å‘kÆ)ùÿ×àýÜUï ]LÒµë}ö5DN¤Nú£¤ ¡öòöõ ò;¾p}Ù*BùuMMÚ“:íÉO%àï:’JÊ7ÌÂ!b"´OÝ;V4c)š{™À5Þp{U–Ü|¡Ë{ÜòÇæÈÝ`ÖHÿ×p>/‡£P/ ’9 …¹\w?àGLÙÄÜv7Ÿc Î¥Aµˆ@qã,U2L±0¥ÆØ:£nxçɪâ—ÀêÏ=*ouûÕ)3?Þ-ôIòx á¹;*`ºv]µ§çÀ@üÃÏèJ”âÖ‰+¼ÿ±{oPlÔ/\ÔKýgõ ¢Å»È“»½¼7öÁÀ¢&›º6;¯û½öØeã¹£;#êá¾Ëw;Ü ñ‡Ô|¥ NtAµ1׃ýßU×›¸Dßû+¬}²¥€ð·©¢JÛ”JQIW¨´ÒæÅ‡uC1 ˜nþ}Ï™™k‚V‘b®í{=wîÌù0¨r*芺Séõ\õ‡ß˜-i&ÊÈ2Y¯rxk¬{¸¦ÅܵÒë®ZÖck2Nõ_»1!ØÈdpù ÏÌæ«èä"°²ÅmÀ£2;™ùà «·iÖ5%¯JÏÑu‘w>ºrɼJ·ð²"Òæ~»·ñí½­&#Îéu£—RÈg¿¯8vÿ06Åð®›:,ƳÅ?ïØ¤‰…ÇD'L´Og¹Ù4ÿ¹ªÞ훥¤:ñõ¿@1üŽ&0áÎH!,k=´—v»tú þHdÛ©r“s”æÉàµz´[Näî2µø;¾[ù“é‰ð]ˆÞ} n®¢È•:”Ïȱ-¿’öxܯzªKUÝCwѬ0r á ßÐ@dúÌuEª›ë ”;¬£Fg‰×9Bã‹Õx=önÝî±¼-Œxn®c—¡á%A:r)Ùâ?¨žÚå¥$sŸˆü¥¹Üá(Šf/tU ´oê¯êWï7  &þü~1{üLýù“/Ì{*™ö¢ŸEˉº˜Æ'ˆjŸq0 Q €0ÌÒqšöŸÊM[1ø:£$ÅÅÍm#“Š ë©Åíæ¾[`‘ËïŽz®5‰³z~©I}¢[YR«ãÛ®ê7"Å8€ÉՀĬøOÁÏ–~£¨ô°ÓG"ö¿Pµg •C±E=1•¼åÕAÚZ ÄMȰ R&{…YÇAbÐèÞ2H²~¸ÕË)H‹~Ž*†•‰°¸÷J0t¼ÉiÄš£Hƒ>•ÊK›–@U]²Ý8›&1/z<üÅì¢Ä]9í9Š¡þÂkš¿âi誟*– †®äñŠ|ªÍGê…ØŽ¦‚á•öÞ'åìÇ=X@*KUÄV p¸®° ‹…O}´%Ô~œéh… y.ÏÞt¿lÎA'P4¡5©‚çú­­ÝÏ zïÙà»RŠå]äFäƒíô)‰;‚Î¥þ»úý~N‘žúyÐrÿQÙèÉê¦î¨  n/Þ£wÍÀeL.®Ø¹|ÃSwyþ1!¦[)4 §…íUD)æ‰û5¿t HÖgC#÷ʠðõI¥ßöÎ&mÌŸŽ"q-ç…TôtXc —©8?“÷AÚ;G|Pg ûл”]·ÿ–;ŠQ™d ,:U8”ŸÃÌöv èÚÙ©‰•µ13:¡ZWû ù×|öyv÷÷b&âðJVI§ê+‚j×à4f1Š&ñ™®ŒÓÁA¾!vÊŽs‹’DEép² È™w‰dÓdpÄ‘ëð¢èÇT”]ªÊí<‘ á$hgEbk;–§‰¶òT2w²qìýÙà5v< "wÀÁrŒ.‚Å+ÚɃƒì›+¦nE,d!ˆO+=Ѳxi«OKm;<™¯7Í3€„µà¸ß­ßè •Þ{º Ê–jçÕC¤Ê}{W¦þUà6N¦ÝŽ€{oMK{ÉœÝ}zxPáx/Ü»ðš`4EwìEàò•ÇOó910ƒ'ããÝÿ©©W^ ǵ­_y${ì¼T}ù‰-ªÙâ§ÿ‚‰ + endstream endobj 1340 0 obj << /Type /Page /Parent 1722 0 R /Resources 1345 0 R /Contents 1346 0 R /Annots [ 1341 0 R 1342 0 R 1343 0 R 1344 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1341 0 obj << /Dest [ 1174 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 224 633 273 647 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1342 0 obj << /Dest [ 1347 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 206 391 228 405 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1343 0 obj << /Dest [ 1008 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 365 377 392 391 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1344 0 obj << /Dest [ 1347 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 202 106 223 120 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1345 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1346 0 obj << /Length 3731 /Filter /FlateDecode >> stream H‰„WÛrÛÈ}çWLíCj` ââÚJ•Ek½Êê²¶àÚ­¬ò ˆ˜4—ùüCþ19Ý=/R¼¥1Ìôôt÷9Ý}žOÞäy ŒÊ(xDiàE‘«$›zqê‡*_OÞÌúT•=¯ñU_6“7îŒzì'¾çûkʉ;·ýsñX)3*'ÿÇ$ãM™J|/‹!8L½Ø¹¼'àí4šÆ´û7ýŸ³nà;® ½Xû©zØ©»]3,1èÊ$Ý×½z÷áLýí¿Ž;Å{‡oSoªkÇ×åòLÝmëá_U·b!¡.š¹ãfZý›¿çðù6ïÅxÉßcŽ5Øn·žzF÷tjEÇB4Žô0ô½@—vjÉ’.ò‰QµšÓØ c£ÂÄKSXRáŽQªºj²˜œçÏÆ –øÇÖØ[×'‹h¶ÞÞ3&Hh)<ûþeç[£}‚`7„VækÈ[õBõC1TëªTõ»“â[Un†j®Ú/gªí”c|]¨¦m\تå×Û÷ç3Uu¾–í¼Ru£Ê¢¯œ›U»P‹¢^¹Ö€®ñ Ù îó#v$GÀ¦«<Ö1–JŒ¹‘—´#Éh‡ø~*¾SÑ5êfàK$ú‘Ÿ©îÔ;ÐñÔWŽ›`üƒC3Žéœn>£(õ< [à0}Këq\Òü^ß;oÅïaz~bOÑ’4m~p"ù6”˪‡BxQ ª©~TçL±ªuhÑV-ìëZVo»ÀЬõjPòJßø XgFÚn6Z=ÙÝeUÍëæÑÉè+_ÄM½pÊ>Ç+Æ‚)#+Óî>^A`F¦2Ó¯³Ï9ŽLÇ öyY¬VžºÄ¼Ñ ^®ÇG¸ýª{½nIXW÷Ž’‘|Úö,Mö³*¾"@ŠÙ¾Â5¡;àhÕ ‹ÆúBT˜ýøéö+­éÁaÌ“yàzþÒð9öÿLÆž0Ïtdc#©eàNu·¥ßºçUÃ]<Œï9&¾¦¾ÿ L«Ž®õá"ŸÝÒåRýÙq‰®oîµ ! íR>‡áŒèöS´ ÀÓŽ“Ì1òQ¶«dyÍØ}ÞÍdú8/:ÝU³ÄªÊ¤BrÎÔW?Ð~˜ö ™1vŽæÈs$Vÿôšža¾ªç÷¯ÅjSÓU˜ùž‰O¶ˆ«ÌhM‰ŠýÐQl㺱~ÕRQˆñ©î>ýˆó‡E]­æÃîéD›Ú¼°ogÒ"r°le©Á3UŒD¥òe-lÛ#¥#&CŸ¸ÿ”¼{Ìpu E ‘RAD#3…ºW¯Ì²cH« ®žîiÊ7û Spx)xÉî~0O#:ß–àöÕfÝ€­@TƒãR$,®«*7]‡Œ±Ú©EE¤7W]»••ÐÓo@[Ì€„)C\= K ­Ü€'¬1bÊ}Guè­¯EW«jLûë†êVÿ7¬&VÏôjC¤_R¹gLΧhïT²ïMÍ~•ÌAÃx[ùâC—Ú9TP<üÄ/“†ŽIÃRú烪¬…Љ Àr6Pî˜CñPìùŸX÷híj®(’‘¹Ÿª’‰Þ™ƒ‹í&JÍßÑŠïT1 ’&êwÌ Y|’ŸSÑÔø™T”Ñ¿_Oùº*7¤¦Ès‹Ü;žºi±tXÕDz1ñ8íÿ}¾¾QµHP”M çqR?‘{÷„½ÇDY»Mk·ñéu%]¯¨A#ƦÜÞ.!ª <²’W»ÂTFg4¿Ræù¯i¤[C¥å3ß!Êœ†FQšXŸ¯7ð H4 &x ª©ì8'Tä,öhµÙÁR+ÄZ¨ª(—l3xvXÖ´\ÉoÑ(TcÍäžÊŠt\¢jëhéêØÓÁdÿÜÔ€äÆoVdì•1šƒÄz¥v¨køàÁÖ1”¨miDeL'áx÷‘ç®.ó‹«ww”O2gÄ)—È4±~Ï¢c¼Ü;üxëЪ…™!}‰±à¸0“’KßV#x(²›Õîíq텤ϯ³¯Ä‹¨C.¹Øx¯J»£'[ç\(¡¡åL1ñ7•h"gà†A‰˜\+ÖwŸrÇHÅȾJOøð  > ÇRƒTíTž°ˆLx ˜Ý^__: Ùf&$ÀÌôx{b`”ÐÙazSrØ”¬f„»&v©[¯ëÁf(ºž*å¹!Dºëì<ÚŒ¡+hL!Ã;ûB iw T"mã©k»òË(µßŒ‚ÔNžöø ð!kW°u&¸Ÿ[=éâ¹j¹Œ¦ÂÑì«d˜39ÆÇX,š(VÉ!u”nåM~@ íÝì'àzÁ3íX2à†*sæ}n þFˆô1È´°ç†x3Õ2U ©g_¬Ç ='ÎT%둉R]ÖG²ÕNm——o©~A²{ÆwÇ!“,¢—dz¾¦€ %à¸QÜ–Ç õþÚÚáõåXLÁ)ŽzGz'šLB9ŽÒç;R;Њœû8ãÈrðRÎAõó‚<<@ ÝÀJÈwSœ~k_¯Î%bÞI‘5“·ŸäÁíà &ÐMŇuÇØ›†cG¡~®:¤¤5_“ê¾üZȱH>«Õƒ}¡`×_À@(­àá%Eq ¥áo‰kÎlM`aФÁñ1$ìÚ.ü"â,f1‚—€ðBoVÆ Œ@Å !á¹Lõâè$#›t¬dLúlÚ™”¤Ì+\ædÜöÀÚ†wuuþN²±]K8‘ƒa,;RöÉ·›jK)s]ýÄÜÂÚN…!°cÓ{qÚ…ÐÁ¯²Æžô™ÐêÜ~=sý¢;<ì8¯3¹YE¡—Q'Æ“‘°kl—)T¶°]¬-d(QQÂ{¦øSؤ²ÄB'ÖßÚvŸL×;F n%H=V#QæÕzÊö¨r½9×ʶËóÁ>ûЫހ—‰DʆçžåÀíÝnI·a۪Ŧ)c¯Š®RÅ×¢^¡†w2æ3J¹\µ¡l™©‡Í švàX°ª·DÐ/ žÿYÎa}‘CÆí ÐÍHTžÍò»õ„ÑŸ.eþÍGTXÅ{Ë/œŽ;^@º¿ÖTS$êQ£¨I_ô¨Ô”-Ã5CCE¸›Êç2r 7®ÏÂ¹Û ÃÌK^•û‡Ýæÿñƒd ´œ=2aC&à1—Y4^O]ûØëu1ÔTHîœx߃™”rýq}h©ÍO2Km}50Gß¾§NõùllOж|uø\õÝQ»]Ö(Zëg&dlÀtº"i`¸Œ3}¢MßÏhŠÉ)”dº¯&­ìY9367.«øxÛªÄܪ±Çý 4[Ѱ–5j|U¹lÄ:ê©•Iù­)|Œ¦FX[ÍÎÊ/·HèÉ~fª¢Âøu®ñǾ&Dÿ%]V¿áS×ʼn/=ÌÔôÿc¼jzÛ6‚轿bP¢>"Ë0$iPôâIŠ^|aɵD@âZÊŠÿ}ß›™%iJI Ã&¹»Þ}3óæåL´5¶Ÿî~¶uƒŸ6–<}À#.Kɱ0Çß–RԦljƒÿý‹ ƒQNæ~pN¹ *ïà˜'¼Žw"Çõ:‘#ˆ)y?ºÊ?›¾Aˆe€‰e°h¥&ý»¾iÂ4ܺ”ºŸ˜ªŸ™,k´TìÒ8®¿ÝÌ,É×V€Ê}  ŒÌò„bÙ´À*À%T#£rï_ü^(g«ZU8óq¢DT•MØœÄ]tàªtêZ¼Yjñ ×øóð€úpðUÍ=Dí_qÐm(öìíüÛÕäoÈc×7‰ÚÊ¥¾Ð„½•{–Ž‘¿g€A×V„áQt]`ÎY''È  \°ø¶ËžS,çG½ÑÜ ä’Ñ1È—8 ñßZ²8HÕ$§öÁM2­c÷Ud$‚™ü7Ô)Íò(Kªÿjcn¦£®UBèÏ÷_¾üýÇç_ýÊ;$Í1…ÏÐʰŗРï˜}‰ÂW‰ÂI;⸕'{œ™†·±÷ì(^Ýò±·FNÎæbõ†¼»Ø¨é°žÇ“÷¶0«oݹ&rxÛiä$._ 9Æ…?导 Kg—ìgñð”ØÄ3pO$4ö5”ïGÉ â ó¡‹á óVD¨¹r¡·§M \…vŽëçjª…u¶Ô‹A´oDIkÄØ¼zOÒ‰át,ý†yç&¬E’ØÒHÄ OG!æ1Yü8´zGvF .ÞT÷dƒö14mQ7ðBÝÜI*®zbNFE}×;y6ïÒ‰¯Üä>"êá?м{nTŽÿìîË}MOÎ%m)óÁêãœ#º¬íÚ¶²ëåÄV„M©öÞYùý±©ÓÞÔ©˜š jáÉ %èÎÂúžA0”hïY‹¬Er‚`}Ô@‰GwþØ*Éά ;ºüTfefLÌywÜÜ÷U°Þ‰«M„·Å֙Ɨq}SÙ{Ÿ–í,ˆ‚Κú ³ÉÈ=…H†‚lv:ŠÒ,=ÿòìz¼¹ “ÔèÃk·AÁ.uG_´7W˜^æ¦EwÆ®ÕØåÀص»TcWÌ–ÇLÇ!%Ê]ñÜzq³®)¸h*f]øÙ±Ihñ´µ(`xšú>\´JãötQûµ  3ÆâÅ?³t8ªªš¨Øƒštähσ‡¹WÀQ¨ë¯á@u åœf4EæÜ]ǰ‡ÐêDAÑãµ¼æŠ×’xýó ݤ_”þ ªe¶µÅϲØÂêV›Ç¥xE=²RÞJ·¨_ؾ-3ýÂõE½[½Ÿ èöT-¼ä¡Þî´¼ò’'ôÞý°UI\—µv0$³ù~•© ^­5ù Ö³˜pÔ•¦Ãm¢ä„ŽÀ#5a´Å‚³“eº±NoôÃbëÓןþˆZÛ endstream endobj 1347 0 obj << /Type /Page /Parent 1722 0 R /Resources 1350 0 R /Contents 1351 0 R /Annots [ 1348 0 R 1349 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1348 0 obj << /Dest [ 1347 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 202 631 223 645 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1349 0 obj << /Dest [ 1352 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 167 366 189 380 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1350 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1351 0 obj << /Length 2354 /Filter /FlateDecode >> stream H‰äWÛŽãÆ}×WtüÔV\6ïœ0—µáqâÉEµF4$R )+ʇäòyH]šI”f ä-`DvuwUª:U|œO>Îç®Pb¾š(W8ð?~ìÚ¾ï„"J;ŒOÌ·“Ou,²šö8¢ÎŠÉÇ^”x«'Ží8 öd“iûx˜È¯é›*…5ÿm’СDDŽ„p±Û¡Ã÷Ò—Žã€Ó¿Ê»°:ukª<;”N,Gñr,š5¬¸R[p“¬óZ<üðAüí?Ö4€÷ dÈÜrd¶þ ^yóO]mèO¦ÅÒš&Rü‹þ[ŸÿyB“7®c‡ð2†5²àp8Ø–g+Y£VjájPiãc»23KkºéË|¢D.&nÚ^¨„Ùq,BH ðÑE¥'«Éã¼ÃS°Å9E£G×AD$¡1òMŒ|Ûñaƒo{^ ~mA‚ÀŽÜªNÔ¢êìØëY1Ø.î—‹}­«Ùøëó£xO ¥X¦MºHk-`c a@hBQ¤[ÍÐUñyæt¦¸‰íÄSTk‰bCžÊ¢IóB/E^Üž‘ì®5 ÚQ‘.EºlÁKîk+’º²;–¿›ßÚéÊâ>Ûä–B›5/ÍìÜð)©)æì³-î@‹­i!2¶—M Þ1U}1à÷µ‚ h¤ÁpeAei)0šVÓ,Ó¼‹ÿCƒ¦âM@òQp‚äaø0H‚÷ñ{¼#»Mï¡Ûy¨Bò {ÀÊñeÓTùb߀ðª$úIá¾é'ç—,ÊBSžžÁ9È`§7a”-~•s+„BR€9¸%E“¾¡rGk:Ë/E @Dy àBP–,£aöXHÁ÷ñúR4e ´ì.!pZ¿‡–€ X¼+ÓvËgùâvùâ²+?•FÕx_"‹€\••¨K0vÙ®›_A ÍöØvq¸Ð`¹YZ.ó&/‹t#vf¥2¿[Ý誯Tå+q,÷â`DEƒŽC:k°âz:p¦Kv¥Ü7"mv!L<Æ„Ò Hy™óÜlnŽfóŽ6Sì<€ðhMQœCJ#⸃0‡Ê_òùï¨(üòCŠcöøúWë9¹ÍßÖ cNîY¨/¢|±\@ÞÖÅÅÛ €3GÉÍÖ«Ùþ«4eX¸ªÓ%fzL ðtè<ÒY‹ÑL@ßa¾5×ÓÅ,žñ‹ÝÚ·}¸ð:$zÿ<ÑjâoÑ9M¯ì9H¸Ž^3ÿÇL-X[˜ ´“›ž¥w /âhmß bÄ×WΠ‚Ž]dM:Úvµ[~p:üÿt‹+ÓèÓSŒbwÎÿ(“ø¤n09‰¿…Éýž2üŽÉA/ryD\NÌ lž0 &hXBB3´@ä!¢é† øŠN§ Öôýwø’ Ï”{ÞwZ]t/”’,žñ d°Œ„éÉ£þ°ÖñH¡ib9gB©O*Ç$Õ.­k±-+d•†ã5ÅšZ[8RQ‡yºxƒFr/Äo`® ˆßcn9u‰ÜÏ ]ÂÁ+¤Ù€X×mñ=P»þGº½`o°d£¹Á@n×Xå@PÔÝ0 å_Žd²D+Õ ûîùaþðøðòå;¶¿+2cúKmºÈt ‹æA½&+™èº±9ÚâgfBÊo0î^Ω‡œ!Ã6$v%¿šë`êïm$íƒÞ] {ÿEëíƒnï‹!TêPv(~ &Ší‘X=!_¸Sò;Zp£ŒL£Ì‹l³_¶N§› „óÄùõSË3~%rÇÓÍ>ðÕaÚbÄm1 ¶‰Ë §=ƒ)fhGãÅ5ß}(´3!ð9nÛ›uÎË¢ýÅö‡cË4‘¼“3-]B¡g`‹•Ähûˆ¶/+ŸÇ3Wš{ʯ€ð Ï®f>;»,³ýV4c¸H eñjÙ—áëuÀW½Ó}d¹UÊ·»²jR˜ ˜Ûhp£¿E½.B»Ô‹ý›Ø”o5 v•^éJ8#Î×ð´BB8è1ÂtÂÞó©[Ñôª³r þõä\­z²½-ÌïEIEڜѻ²¡zz{¥¦MµÙh%péVIþÒø Qðä/<7>›dó8Ù’nóðL^3v_”pÀùãaþÀü2CÝ@o¼aGZÍxòxȤOþ@»KâwXëÕïÒ!˜¹ªŸé4r rX{SJ]`þ<[C_j3C2- £ xèdÓhËû¦ÜB^f4&™]Èët·ëx*–-¦OÞ¿ÖÁ+ I½jf¾YœrÄ”¢Ö<î›O›®ñ¼JÄþ<·Üð$¹œ¤/ t….òÒå• 6÷ºNÐæ•akSÉÐMÍ 9P1]ÑNÝØöݳ!ã¢r{NîéJEý¤áC¦+ E Ï›MyÀ$jÖé‡ÐcËDÞˆ°KÖtJ¤FjNî-0ŠŒ¿­ jù’§&Cœ8³tsgàû^µpderê ›šN­) µr_c°è±oóÌL-ºê^p˜¸ã—étFš¾Ì'±g;±ʃ±Ñö¡"è¥'«÷¥AØI}×·ÃyàÀ”â_=þŽ¸Ó £tl¤€ržŸ—?ÎßqÌßžôãò·€¼ï›mýËýÇse*p;eg–Œ GÍp54ƒâ4ƒ¡ºÕür¦Öqn¨Ž«’µ˜³Zg•&ÅôzªØÅ£× ÛƒQxãà˜pÜâ è,¾–ö—ÜEë0å~S满ÃÒ1ḥ¾7´t¤Å?¿üôy˜fŸØ¢Ÿ|þŒ¡ÿtnWp#ÕF…ãvyj`W;®E¶Ý0øæž›ãßHÁQá¸9ê§ {+Ç„íAu+Ç„£«äÝ,‹ÍñZ2ú…éªvÓ&=zzµs+#Ç„ã†ÇÃŒÄ9D³FùPVFÿ!ßlZKø—æP~ÌÍ/tÖUŽÍíJ©äF²Ž ÇMŽÔÿ¶ˆT|#kG…ãvÉ»Eôõ—çϜȟ¾¥ž0[ì_kz×¥Øpôzýrüq«;Ö®¾"ÿï J×… endstream endobj 1352 0 obj << /Type /Page /Parent 1722 0 R /Resources 1355 0 R /Contents 1356 0 R /Annots [ 1353 0 R 1354 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1353 0 obj << /Dest [ 1347 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 353 658 375 672 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1354 0 obj << /Dest [ 1330 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 188 87 217 101 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1355 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1356 0 obj << /Length 1945 /Filter /FlateDecode >> stream H‰äWÛnãF}×WÔ[š€ÅáÔÀ ‚3Yëigö&[‰TÄ–eåCòûû°§ª›ÔÅ3ãd/Ø ûV]uºêôé›ùäÕ|QHóÅ$Œ(À~’"ò“$È(Ÿ¥~V1ÍדWoû‚ª^æÔWíäÕ·w!=ô“À‚sªÉtøÜOÔûòAS˜æäÍœÌdÑŒòÀŸe0~X»²&’åü•f¼úƒú{„ÞixÓ0ö3t »Ck–艔ö`IõMO_{Eý‡7MÑÞb,õSÕxª–Wt·oÌ/z»#±*ÛÚ›Îý*ÿ½¿Í¿›HÄMøó[ô‰ûýÞ÷b?T=ïªy[˜Æ–>>?R•ëZŠ¥o據DiæÇYHqîe!$Ę´Õ“Åäf>‚‡˜œ£qD7`D” ‡3JÜ%~`BâÇq‘“m æiêçÑ ªÁl@5ÈmLì¯W(º®ï7eß¿yMïno¼ÜÏÕ[K0R—¦¼/{M^Ð0É C ÷ûn[[ÈàMq™1£ ÑÌŠÂÁƒÐ:ð¶kMÙ´º¦¦}-8æj4ë1óóá$ÆÔ³„\÷^®ôÖKáð£û}c8“+º®V û+m»ZóæÒñ©lQÎÕ[V1‚U8_Ë–*ë¯u5ý‚«ÖÁÁDd-lJÎK ×ïù#U â¢Û’ë¯l¯ûÑö§ïo«öÁ›&pŸ$ãù Ü8N+cäjgȸ_ê»ÝöÜÜçcF¿ÃL·NÍëe̶¹ßÝs3T¯Å‰ø…ÃâÉéàèÂ'ùペ{J+Dñ7=>É”ÄéÓU³ð8†Zç³¶S–š8e3¯…œÅ”BÕžxn€%¬?ïš³vM¦£²ª´]íŒqud\1‘Ú:qag Tš@3KÎ9·jÇs´¥¶\ëkŽ@ŒÕ9*‡Ü#•m€‘ 0Æ™6\™¡’’áÂÝÙYâw¦x—„³ŸôQu¶ƒç²+˜nueš®µ Ñ´o®ÈÙSƒò?z>½÷8Ô•7êòl+Z—?¡Ÿ1ç-ìàøn Ͳ4²=öžžÄ.ÇýAÅõ@®¹ÒÔX“ÔvÆ7í7ýÓì»e·–ºqÓjͱ;jíàh½iÓèZÃg]uë3!ëæ<ØC·sk%žŽ~åu•›ê|4ÿù‰ö»8=Ehžrz2ÒT4rz&dM×›­~Ô­êÒÑjù©L‰bf²ßH›oIÅ¥e¨×Æ ¨’6g‹[†”qqøIœL'”yJ¥% ,Xãå»"MÒsð§¹+$ÆôHx©µqßu+ ;åjÇ^þÿÉÛâ1Ê·` ï%¤YU2 ·t¯9ǸèÌv§ù—!R.[™-xž‘2$»î Ÿ\NF¯7˜f1é0$æì5œGå8¸|Ŷ@§ö?IÅÇÃÜa”«Ø”ë[®íMÀßoÝ­\o¤“'ýÔØ/ã:ö˦ZâZ€‘j[ÚN´¡"sŽï³=pÑŒuW7‹ƒ Œ©ó`d=³ó%—þ‹¬’D‘;«UÂ#áH+¹ÇœÉwˆiÖº“ÖΰhôøºP82 ºC…áy¹æc<(âìOYó'E*h..t¹­z ;uEÊ"…Ø¢XšO¢úyøÏ–ÿ—áC»ã­^”»•±/ d[hÇ:Sq0A9ŸLïàòLòËÜAöô¢ üÎwxòqÆŠXÞ@Ë¿„ö’×.³óýŠ% µB ©¢½c5FãfPÝ Íé¡Íª’ô'‘‹îÛ,2·@aVh¹°:“•Byf9>wÁ^Þkoš£aÕðÃÒв||®;?ÃÖH6½X€CÁ9ÄÌ'öÖìŽ"\ó‹#³5ãÞ £0’i2"›[>»< û[()J!ί©M00MŠ».Õœ³6±\Éݦ¯¶Í†Yéò–Åe¡eì ÊÌ€KöKiêÖv[jõþËÚ&:)ØÛËÎXºˆ%¸Ë‘uX¯ŸeÔs ŒPŠEñG£ÀcÉBã±l<¾Vå=ˆñdâ×/1À³äÿ½ÿ d¬Þß©üR¡®]~ óý›´,6⓸úŠ"¹aͰùûžäÊlôÁ=äî$'Å ýd˜eÉ^¤ÈèRà—\R3¼šøå pzg°™²_ !3e…޶è1ï1k­ÞÿTMþW®“ þg"³ÁþÎÛählzz›ÌèQ#.Å" –|Ž[º¶Â¾^ëº) ë"Èv€/\%¬Ðx3T0(ºÒ©=©h>T%ô©…[PŠÕ‹H€ONA‹z~&ûƤ›žfÝÎ=GkV•ÎA0aÎLÈ/Sd}§–t÷Ã÷¨Ú|xÁ)åB‚ܽm­úÍÔJ¶t}eUiû9tì̲³FÛU =.Äz'’ÛÓÝáÆNàtgA.± â–œ÷"Š—Ÿ»ºF²Ø<==}d‹]+ÜܳëZSèò4b’ÃmÐÐÏÚO/šMoæ“Û8˜t endstream endobj 1357 0 obj << /Type /Page /Parent 1722 0 R /Resources 1363 0 R /Contents 1364 0 R /Annots [ 1358 0 R 1359 0 R 1360 0 R 1361 0 R 1362 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1358 0 obj << /Dest [ 1556 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 279 165 292 179 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1359 0 obj << /Dest [ 1574 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 151 94 165 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1360 0 obj << /Dest [ 1458 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 290 124 325 138 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1361 0 obj << /Dest [ 1556 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 117 97 139 111 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1362 0 obj << /Dest [ 1562 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 92 84 115 98 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1363 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1364 0 obj << /Length 2619 /Filter /FlateDecode >> stream H‰¼WÛŽÛFžê+~j#šñ"c0€/IlÉb´//ŒÕ1¦H-IÍxò!ûûû°§ªšG3v $6 Õ·êªêSuª^­fÏW«H…jµ…‘ ðŸEù‹Eªl™øiÄjµŸ=ÝåªèxO º¢ž=ÿî:T7Ý,ðƒ Äžb6~ÞÍôÏæÆª0É•·úu¶äCK•þ2…à8÷Ó@äò™ˆÓ¯$¥Ó¿èÿF˜G7c?ÕA®Ö÷êú¾îw˜‰´õ Iwe§^~w¡þù?ož`Üb-ñ]z.vêú®ì³mÅBbmê7_jõþëýkõÃŒ-fk¢ÀO1X½Ákpwwç{±êŽnµt-DãJ??Ò…›Ú±¤oV³P•j%©§¡Š3?ÏU“ 6.rÕÚÙvöj5:#±%xè“wòˆfïáî~°À†…Çy¦d885K?‹&^ ’Á«A,6Aߥ—û ­.ûÖÔ)ú²á‰z/ß½z¡VÚ—ù™vTÙ5•ÁþZa"Ñûfà ð yCü Uós8úEK?È'ú…ƒz¡h÷º©{SÖv£Êú;9;‰u(Mýlx¦7#„HÈeçeÚ¶^âçúÖ}¯ *^¨Ë¢*½0¬LÕýÕ¹âs¾«ä7ΓùèÉÜéjjUˆ¾¢jò)Uù4‡ÅÉíS‡Â—vxêGjD£aJ‚~Ñ/ î Ý÷m¹>ö¶£a¨I2íÓ. 2VÝÔ¿ñdxÊoìÖ«^LÍïUrèÙÆnáÿHÓQ„ÒR?“ƒg¶M œîgeÃñ}¬vúÞÜÀ{êØ+}£pÁa;‚U}ÂÍØ¿¶|ÔWß÷ªÀCbÜÙ^™Nm›ªjîºÎÀo}¬V”ž½å_ØߺØDŒ;ŒQ;dV ZZyöÐå8ÊŠx{9¾ÍC ‘,'O˜œ¼’°&ÏÔ U7Oj0a¾`²/mƒ„ òæÜŒe41#:™‰/è]”;{nN³å§ýéÍ«×jÓ–îs ý<þ:F†á­5›ù±.š½7Ï@Sû²ïÇÁ,Ÿ¬–££‚4Ìn`Yë-¾ò~½Qm¼y„ f(ËŒ’µÊT•*v”Ð2쿱n}üøjŬb±t+×üXYÃé]¦z%×Zº.&ɪPË H9zÜZŹågñšŸœNo查˜ÈO³)VN•ˆ+¾ßªûæ¨ì‡ƒmK[P³)ÞS”›ueÕ¡mÖîue÷Ý…‚‚9Ô#r¿tÊú¦!1€Ì  Ð?{Œ(!œgå3 Å“xÿà 'àt²)…»CâÓsü YNñsJ‰aø?”¡C´ÇÐIèÐŒ’ #÷¬ &wo¿Ðnëà H æ_)ƒCµö` ?ûC9¨}ò ל €ÑDú‰0|¢Í†°ŒB¸éq™ŠºðÁ6‚—%#Oì< ;%‡ ÉÊôÞ>”-‹G±J޹Ëν—úÑò+yñ¡;Ä©Êßžò߃r ?%á|ôàöˆÌÒ ¦F°H¤y¹8ª”µ±|TA!ÌÏ*¨åêK¹æg$ T. )!#*!ë¦?ïL_Bæ=ç¸IÊw'”û‡¦í•%šv" ™LnàSšjumûI‚dC†q]X‚O7»áa ¤£®SéDDk±7÷¨ô;毚â2·Àq¥lÛ6m§2ÙroaomMÉYÎ’³S€Æ£@aÒÓmÛf¯ît8)”{OG ;ǽÿ9=Â"GBO]¯AF,ÆÆ íýï7‹¸ þÔf ǰ’6€2]‹xL¹ ï)¸xÔ« ÿ±¾ OýfèúÍâ¸GÎ×½A±B?.Ô$ꆃ˜9—z˲þ«ƒ÷ÊbÍyöÆÖn’©;Ñ”UÖ÷HT× &*r$QÖÅßx×|“BS‹,{ä2å2ªÌÜzvr/X8‡G´s8ÅA<^½pGÝ…\8êG‘çä’À¹^E ü÷±l¡¾©á麺'ãÈÖ-&Ý °«„æ…=^î-v‘šëGöâ¤Ác·Ð@~H„ÎÈx‚`(“!¼ŽÄûžŠÏÄ%q%aTÞÁŸ”¸A’ƒp<É¥Û|?\}'f[7a™l´)›À²Úl·"&b à¡RÈŒP„|T·Ê º ¤l7CÕ%Šeê$DÖvgnËX˜gúÂeFª¾÷åÍ®Ww†é+q)ؘŸUTn³c¸x”²[6—î6õ(|¸ÜÙVæÆ?÷IøL‹Ò¥§D^ûi² =z uÙÛýÞ®u ¼òŸ¾7Ç~w…YYîÉ~ðŇþÀ›ŒlÚ›cÏÒÆ0É“•s ÐáŒôq‘9‹ ÌNo¸8Ï_Uß·ÊÜš’É©ââ,ŸòÈGù2Š"ý©|M鯩]ûÆÕ¸W¿C“S†xI6ªa·c•ô2/ÎUÙ°®¨Ÿ$¦ùòðïÄc•·”B<Ö\Ö*ö®Ø)hQ…:À â„,yºÑ›‡è Ã4ñÏGú¬7F;±ÌuRÄG®aº³Ò~½È"3• ²ÐðI©@Ù^Jõ—º„=kãÎHr@ÞÜì˺”ÉÞ‹—¤CSÇu7wGîväÙçlQGÊ ‘käœVŠðî«© NºÚ™iËwFyO4kkkERã¡;8T¦à PøŠ8æ@ÕH7”‰pÞOÈŒµ·”8\±Woµë5,âü­G¶xRi¤õ±¬Ø_1„@ðŸº~ó×wäÆÍš.B¢Rþ?ND=b+FIüÖ›æ øiwÕP­ ®ÿþ£Ú6U`FÖjc$›÷üE?èI. t¿Ê–[Ë]Œ[ß è%ùuCÊ<çeYíÁANvâdS·ƒ äÈfì¨-ÓÁT·Ü©’hØ>MÑËÓ:Š´ÌþPY~EÇ’©&ÆžŽ7Šð™1n¥–€*pOòS CÐMO§ ûãAÆÃ<œp<ûB;é[ïBýz” ='åF–½ýø½Ëúi¸¦'[]ƒv)'Þ B®8gPU"õÈR:ZÞäå TV©~·±·%¡:S°! ­S]_=WƒÔÎv”}˜M¨%#mÝÜ“1I+ŽÐV·™„€Ï¾ ìâŽìS®‰>xÔL-~Ç©ÄÙÍQJN´ƒqoD²LgJ4:÷î/úíQXLj£ˆ6}³šýpô endstream endobj 1365 0 obj << /Type /Page /Parent 1722 0 R /Resources 1369 0 R /Contents 1370 0 R /Annots [ 1366 0 R 1367 0 R 1368 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1366 0 obj << /Dest [ 952 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 89 602 112 616 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1367 0 obj << /Dest [ 1365 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 448 259 475 273 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1368 0 obj << /Dest [ 1365 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 403 232 411 246 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1369 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1370 0 obj << /Length 2627 /Filter /FlateDecode >> stream H‰ìWÛnãÈE^õyÙ&`qxe ÌŒg»ÈlXOñä¢Z³©”5·äòyÈ©ª&©[<‹ä!@0Åf_ª«NSõa1y»XÊW‹õÄ”‡?<¢4p£ÈKÔl»Iê…j±¼ýئ*oyŽ§Ú¼š¼ýáÁWOíÄs=ÏÇœ|2í&úÙ“Q~-&¾*Ô$ˆ7L|ÎÜ4U‰O*Ü1JUc&ëɇÅàŒÐÇïÔ£w=òˆfï!F‘Qäz&Dn¦3%¯½Sgqì΂#¯â›õªÈ`¯8)ŒVïòÒdMg¾òk‡»èÝáîVñë®ÌŠJ|T»¬mÚ@òfݬ&­2™“-åGkij0:=Ö`i0w½ôÈR¿7Ô;?ÖU pËîžéa[‹×ÄõÃÂP¶åïZ®Õ¦q`çÙ>>7oÊM}—€{o=—žK­EY¥r±J Š¿aË˺†Ï+õœ•{Ç÷¡ _ƃ1~rtµ÷„ôHw]S,÷iéÕ×d’˜¼n’7cLUuez\½âŸ=ú¨ïÍ:Û—Ü:}åñg²®+>áì:G˜öÆÓõbƒD®w]e_tW?$\£½Î4å óèrï¶«xßš†x§ZSš¼kÕ¦>1¢üÊÕƒiž bƒBŠT¶Ççª+ò .£}7}ú¶Ù4±1ë3ëâS"¡ŽŸ±^Úgkn­7¾·Îàý‚ÙpWšþ ;û{›ÃÀ uØÝ=Kr÷ñ­1?:1@³v¢>}‰Ñ9þ›¯òW­CL¨äÖ à¹îF7XÓm(WO¾«í^Þe+µ4*[–³\?¥«•×ï¹—×Ê¡mùigw•ÿ™WË´•"³k‰§ ©LÙcŒ×:ŽP8D(#Ùáæ®Zàü1ö ÙS9€L‹÷¬c ;€·àÂã3¸p«F`ô4πʞû:+Ò%–`¥j‘uÕ Ús@éhž%x}öÅ!÷åY™ïKgŽ$ ÙcŸï)*©ŽÕªx2䌘c þÎëí.kŒÖ÷†°çÁ”¼,`åw²dÀ7oS"e Ñ™íÞ9E)LŽÿë@…I‘Ôt±@SjƒáLw…=¼«ºSDHú Îbÿ ÎóÉ!ÿh÷\hw§Wñè·ÚÅ,#LF÷Û™f]7[ 5 ›#ÔŒðJIÓ[ÔÙY-Xìx*€DBÁ²¨dËzÍ~#¬²­¹Á®ñu žç‰f€uŠL"D÷`v…§-"Æ‹]tÔó='ëÖIØ„<£ö` éç °1ò©g#O6õ¾\‘ÿ8+‡™FGâr^&|"ÿk&žiDŒ,¦ž˜*; (º&«ìûÚaõmP0ÎÆØ¯¢Ò§k¦bÄ©$_ÖKÓŒ©Ôá˜÷Õìr;ðB ©£ïÈf",B®ya;þ=êS|]Œ‡lqDSMDߎ¬7˜«Q_ÃîÚ ªLçžÉu˜¸~zTœ+žVµ@Bfž‚bD»oCP¬¡°HÈ—šõÈó.• Fâ‚ò)éG–êd‚,}¦ÍHl®];y¯wöCéЬ—~‡Ül·¹ðø°Œ†»;a01xtz§Vµ±‡UDÈ$T> ¶Çóȶ8½Ø¯¬"Z²²è^\ÈSב†ØZÂ2ã"… UÍ®aùiqØËVKäÄ9ÃEËjFD%l(Õ ûä€Êè:i%£¶Ý2™ÕÞÐ ™Z±7BôQ\1?U0«^’tÁ[:¤öóï„4G/ð·¯?ÃS¾¦a_m2ÙCÉ£f-Ÿa,Iñ€§ä›³þÎuagŠ²ì ¢}ÍÅW$GÑÊCïåD„–5åÞ!žØJõ6ÿEwM襔ÄK&_’º¶rŠv²õþ©kË Qf ãš[DŽPÐÖ3Žª¶#‚ûµ)¸ôeù/Ò©ÜC„'ËUlÓY/“ \eƒýŽ(ÅçþûÛ6ÒBÆoì K“gûVÆP„lH‹¬“yŒ¼L:Ls|™ôY¾ÜãÎ ü<øR$q¤-dw×e^F€žk5žyzЬP«Ä.ÖùÙtBDÍÇÙ0àr Ê7jk,—ZÙ'Q&¬Vä@Ö?b㯇^>ˆÂKÒ;þMF¦ú(=IÖ1å Ž-_ÔøÿJ­pU¾òzeV¿…܄͚'Aä…ÕC>5Ö®@hk4Ì¥$"LgJ^gH¨Áçs7N¨#Û^È–…IFèP|Ú]1\o¹¼°…ƒCUÕ.ã¹LGñ“ q.2$€ežÂc°hD{G»äc]uYQ1¥IÇ9ûFSúCý d·à¡”$!=±Ï;¡±sóΚÓ!ì3*ÁØ*1(þ†AÂÓc"XÖ5àR©ç¬Ü õ\øj4æ/ÉÑÕÞéC’Pµ-÷èbEÈ$Ÿ’õU“¼m¤Q÷™¾’Å¢òúÞ¬³}ÙÉ­ÓWŽÏqÁH¹ÇÕÃéu¸Ç.â$›¢UõŽk[)çMir¨_bÙ )¶H¢GHiÆZ¬8nô¨7‹¥’Fâ |p2 wÙ&ÊêãuYäØŘ[qSß0ñÄ oòï5JWš…×§yqèѱB¦®HH4v4†³³Í‹¡ÆÐçú„1Þ˜nßT$'Ò«6D~ý®¦`¯’ˆ¨®zá²z1˜Š6C ¤keVp¸ I˜:úô†nqÛ+oÀˆŸ¾ã†óU—é¨ÀXg%•'­1ÜÍEÄ‚Ôó„Áôªà_¶#ùÆ6 {«±‘AÒ4+Oj0¾£>3eEH´T)W¡¶$7640]lf¼;éRè²7Ô«qÑSó¶Ö “Áç{^$#®ZPÓcføžûþQ?ðä9Ê`îGå…Î:Ÿ"ÊCꢢ¢“>5äV:D÷l—Œ™ô"†ðïì>yãø4Ó¬(ev¹¾F~93®ŸÞxoÔÉQb˜5)gFóõñ™Ý Q¦L(VÖœì"°²x 9M7hÝ>‡~Äù)öH%.<%.bõR6¨w62šÂÏ¥N,Ÿ­ÒµÕÔ2”ñ£EžXœIZ¬3•4,6–n†Ý.òüÙyùÅ÷ø”„/uÒq`Dwù¿Nþédʪ5´ ½,ZÀi|¼êµ{^t?º¸•øœö Ÿ‡#C#.zª×Á™^ZLþ9¦À÷6 endstream endobj 1371 0 obj << /Type /Page /Parent 1722 0 R /Resources 1377 0 R /Contents 1378 0 R /Annots [ 1372 0 R 1373 0 R 1374 0 R 1375 0 R 1376 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1372 0 obj << /Dest [ 1365 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 456 757 484 771 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1373 0 obj << /Dest [ 1297 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 236 262 256 276 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1374 0 obj << /Dest [ 1297 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 155 185 175 199 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1375 0 obj << /Dest [ 1305 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 294 135 324 149 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1376 0 obj << /Dest [ 1305 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 234 71 265 85 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1377 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1378 0 obj << /Length 3734 /Filter /FlateDecode >> stream H‰ÌWÛŽÛÈE^õ‡Eš€ÄåýbvíÙìx X ž$ÿÌCNU5/Òhf×@†Gd³/U§Nªþz9ûr¹ ”¯–·3?Pþá'Ê7мD¥yì&™ªåvöåë}¦Ê=ÏñÔ¾lf_~ûÁWëýÌs=ÏÇœr¶è3ýc±6ÊO<å,ÿ1ËyQ®RÏÍlfnâɾ¼&àåô'´ú£þw€ÑEà9 ?tíeêæA}xhº Fmì¤÷Õ^}õí\ýí?Î"Æûßb7Ö•ãér3WŽU÷O³«y“PÍÊYäZý‹ÿ:_þ0cÙ›Às¼,ß`Œ-8®º¾ÞÓ©†ŽÅÖ8Òţ纴CÞéj9óU¥fAœ¸aâ«0u³L%>Tð1ÊÔÎÌng_/0BS¼S4Ft=BD3zcdzüÒÄsñ_–5/à§G2éÄnÛ|]íùQµw]Õ6Ь×2§7Óµ);;ŽªÛvGpfzëønª‹Nµ·üáÝ›X­ªµ‘¹uܘFMGÚY©ªá«¢+nŠþ°”æ_÷gƒë‡×Ž«~ªºM…ïÂQ 9“~åâ×vo̯|b"$ºS]«ºa߃™‹ˆ]ª[¸hùBîääN%‹U¡Â`iÈRÈ»/yÙe•ƒó}ݬï)ˆbE>auµ-jB¦êìÎ×ÚowÅÜí]mTÙnº©¦Xë§ž‡ƒçÙèyf I(‘k€àZ_;ìb¢H…X7%¸ÿè׿ƒ³¾–çkî„ÚUﱚ, õ‘ŽN…±¶Mã3¡VÛÃÉëQÓ÷V¶£ˆÛ¬hø`õ5OJ"eš²]UÍÚ7¡7‘Õ›Èõ"ÐëÃ,UòÚ<É·l¢„)Á‰=±“iõrmº•¹¯J³ÿ¥~5GH`çËÆ‡Az5W/÷ŽiÚƒŽï;šoáw£0Î(‘ïqäØdCæË¹¼IÕܶtÚ õ†'2ø»-'#¥YþÝš¦üÎÎuvp6ŠÜ,š8ë÷¾Ú#_·MWT çÕ Æ9ÕöV¾‚Õ/T°;èí.ë æ¼‚a‰ž³~'A¢ƒDÛ{ûûÊ!ô¹á >b`éb¤é”¥¯‹4g{ÅÔø7Lõâ‘é±ìñá/o™¸Lµ€¨†´5¦ µ`ÒMd]‡¨E Éô;^ñ–gBÝÖÈKFµ¨‘L\p éÇV6þˆrP.H¼ÛCwË tãp‚å¨8~2 I}È=Ü Ù8˜"COaû|zÍ’@Ub¤¥âöjƒú WDß☺~~ƺ±*û¶*o ‰ðmE@qa#$úºH4”iXëª%D'E©[0×7ÄŸ@×,SF« âQÔNZˆÒT÷4žô«až7¯dz³FÑ3dþƒ¢øRSpSÀÕ£¯T/d] ‘Œ†M» š†M!; Hæ—º– YÙ ÅT‰Q6-‰ã!w)‚Ë]†‘7÷qO0¨ÙTž£6PfH´MA%ì† =•”HJt¡xŠÇzÍéÄ¥_z!Ì”wª6œ²Ö¸m]·G{5M$S¯hò Ëüo,MÙƒ =sî,±ßØUÙRY÷ÚÛ+4ÖýË.ΚK-ú0/ ¨Þæ¨uêm”GcÃMy1ÆËãxi ËÏæáìÔ¡vû:¸àÂfòW1uBbçÝŽõ £<<€hHcÔs£'!å¸]ÆÑsÏàC~åó@˜æ¸åLû³¡g‘ÐCX­žFYíu1@ð¶‹æ¸lTåéƒf5®= ŽÝîìQعA†ûNÅž¢®¾@Þíö®ú¦Ýaj‡ugv¸â€ò¥±Íß"â[ZŸkºÛàbÉGªýpJ]üÕ¬\hê,G!ùQˆÁ““.9¢`µ¾÷|5ÓŠ;ß³b1Gfã1Ù•·µÅ /ŃêÛþùh§ÑÔ“Ô?]áÞ󅶨ë‡ù“BD¶]#5~û;V¾ÿ•òPƒ¦·¹‹ôOcŠ5ÅÖ<™d‰G¹uºÛØr.¦ªiP¡ñÞp¡ŠN:) }o¨±I¦æYSz €×¼ƒ|’¿Õ¼P¯›utåy|ÚkÈc¸k¢’ûrW!þ÷â?ÙÑm¨†ùZ4´äKŸ‘{î#ñüœYBïÒäw–.™O6\ï|·';ÉVÁˆŸG6æÈ†g‘õƒ³ÐÆZ'Gâ”ðFD8Öò—#œF8HÎ"üXî÷-"Z¬V•ä7Á¦7kS_)KTÈ”¢Ì×ÅkÝ=Ü™9j*zD´i{,˜«÷Wï¨Á9ÜÂÃÎì®^€, ~—þL.9ý-gIšÓvt—RtÑÓû®¿ŠÈûÎÔ…íûzk±í#Ý®0¡Ýâñ¾çÂEDZÛÖªØÅÖ)ñ?•»Ù%î üúåÚtB»ý/õ«SÖ¡Ó°—½¡§-‡F— ÆVßÀ1j^UA¿ˆÀ‡+yxk_;”àhLqã;;¯a–Å[aŒ}kè 3ÔÎt7Ö»¨XAáD;V)}ßïòøÎ…§w®h¬-ÑpçÂ’ï\R:"ºsÑZuVD1œN ò À^ v€b½?Ôd#yÂü½ýЩ£©u ùêÚWªMD±âî®~P›~ÅÎüñq‹±nåÑÿ¤Nù¬#õˆuÊWòËÅCê x:ì‘QÎÇÒÅÕ·û/íåÒœ(Dáýü 6S¥UÑâru?Yd“E&Ëlˆ‡ª1™üû9ýàr45“É*¨ä>ºOŸþzÊÝdS‹ˆQ!€"hŸ # ôëM%¬u=á‰c …3K™U½±óÐ·Ž¾èY¹–›Mĺ]níåV3Ú Þ ô œ;þ‚ÓÔÛeñ¢¶ŸK>gÄëñçm»w B²ÇwQ¥µ'ª¦²:‡®dUlÃ$èElOúoïr€ðŒCö(¶“V¨Ò*ÙyÁu¢ù@f™L0¥òÉÚæe^§MU_é;¼[2y9æhB8aÐÔÅv+àzK ¬¯®n)y`ê6“Ý$psûóúî^~—_Éë㶨ëx¬+cÁ´¬[ &†˜ŒìŒ¸…–«Æåy *èÙ~‘cÍ9E Ðfð¦tû` ×%¶XüÇ”® ̃b 1bÄ&þˆ{NL'€úƯ_--Õc&¬ˆQñ9=Í\%y•­v½»¶l×Χť­¸´óhŽDkÔ_ëÐn.b‹&¡$ þ“’^ `¼¬ gý’f ~èûÛrÅuI¶]’-'ã>K›QDÀ¨âéís„uSA¤S¼…þ³â^‹MQÕ-qÁ=™oŠ'µqÃ}}¤&Ö«ÿ`´C`!àJ¸"*…ø¨ùL M+éQº Ù#¶j…˜ÌÍǘü0!‹m3ÿ²Ó¨É QëaZ9Ї`É<ôŠ2ìôFnv¡6_í›Ay•ésphÚ!…U­šâÁaàôtŽ!ka…‹5L¨ý¼b-£Uº‘¯‚2ÝéSï qÇo.È87åÇ¢!‚ á6Í(àî·ô&ÀHºß’dþT ä¹HÆ3=³hŸQ¯n»›½9Öäé*iÉ•³œ @–âFV1RhF_§B£ð´=ÖC/â­÷€½ö÷;0†Ñ[1“›+ÌâŽmªµ‰X§&·­ÚVÌ8U's“éÚuØkŸ_C0ÿ §~WñÅA ø^ÞÜQÍ®Hí’ˆC~N ¢85` Æ™‘Z€C®¼íºnj¬Ç_+š> endobj 1380 0 obj << /Dest [ 1305 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 208 430 238 444 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1381 0 obj << /Dest [ 1365 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 284 241 311 255 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1382 0 obj << /Dest [ 1400 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 171 170 206 184 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1383 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1384 0 obj << /Length 2647 /Filter /FlateDecode >> stream H‰ìWÝnÛÊFoõ‹A–€EsùÏÀÇ€c+§nçÔRR¤vq@Kk‹D*"eE}¾Cß±ÙÙ%%™TšÂíÕA‹»³;;ÿóÍ›Qïx4r™`£ûžp™ÿàÇ]Û÷EI`‡±ã±Ñ¼w|^Æl\ª3+Çyïøç¡`eϱGÀ™q¯o>×=þKú ™³Fë%êRÂ"ÇNB`ìÅvè_uÇU×ñ+ñö ÿ§ »}×±ú³CîÄìnÆ›¼šÂŽË¥œx™•ììç#ö—YýÖK vÀ3Ëáã鮳êïr9SL<žæ«Ÿpöõ×úëè=¥±ÒÆuì£ ØS¬×kÛòlÁK|Uâ³Àž´áÓ±]>Ö[SÅi0ê –±ž„¶j{‘Ç,`I:ú1[ÊÞ}ïͨ6†'àˆ³kƺZ„+ë5ž1ö‹Bdžÿê qX_ØpåG'¸?\Ògd¡‰¦–‘%»·|^¨ïÙ¬Xgù“ßÒùbf)Õ$+ét±¦–²qdYÄ›V¬@Vlø§wøC´Êr툧•œË¼Ò ª‚ÍÓƒb"³±ÔÛY¬«ôÎJ‹^×¾A•¼Z%¿QÉ'•Æél&'lˆBûü3ItuþëÅÀŠ h>ƒ`ÿò|0|Mzm3vµ¯Çäp2ãñ[AÙÛŽ¯¬®>âXÛÝIln®Š[~ò +­Õ×Ù)òhˆ=Û‰‹À˽*¶âà»Ô ¬©¾ëCnÓ'¶]¿óúwÈõÛ!†¼"&ûŸ p»l"àÙä†ïç#HÇ$âƒO`û_ÿ8ø|ôîl8ºúpu> ÊÛëïékøYù içÏ¿\¶\^üôêåÅ+“eFz'ªETòì*ÐJíÔ!L<ÛÕ)ÈOޏ3LpæÙ‰»ûn¹¾,ìÐﺃÜ-uÕ–ç'¹\w ¿Ý¶j§v¿&µ­nøåÕpp­ý}y5úÐåÕÛÚ™·í|:{÷±¡¢‡²ëã0 »|@rˆÔ¸öò!ƒ…ÑAGµ“Íå 9díVj·Ì~°™eú(ó"o9mÕNî~ú—±Õ ÿøËÅÙhÐåÛá@@å°W¯:ÒëÁO/'û®ö½ƒo'w‹ï&[©q|Èn^pÈ[­TsÕš¼Ü-3€”&™Å·=/Ž- | ߎÜ-ã;A+@¶"´b€OìdUÊå¹AÛ½f_ÕæJ.7ì¾X2X°t¥(•ó*§´@&xV䄼@¾xÚ¨…rãÚc„òŒL‚D:/ò*Ír|YþZaðˆ×lõ,Ö(Ç QCFW39Ï2ðÄ ù‘š"ØIi…vÌå iÈõï)¡Ç}Áûꉙ’ùâÚ|±–5Í0+yIÔà;¢‚Œ¨ŽR{(ÁW°¶åƒ7ˆpBÙžBÙ ìn1ÝZLÖh÷†ŸáȪ–Ùݪ8KÁQX¼¿#l¤`/TT©PóžM¶F—K23+¤z’Xи2ÎpÈÈh:0‡¦§Ž¶‘hiÅ ·•X&8ƒ 3`6”ã/ Fž®ªiÆÌãi…ÑJCMZߥ#8­à³“&–tg²ŸÎ,{£Åž)œÆŽ1…Ñ|™µ\ ò?nBŠÁœý§c9-f=³Y}r—%ª™å’{Lg+Y ¶PpŒ¤Í.aèšL2¥)Ú¤mÚjâQèxD2Wéq‡z >c43†0P§QÆ¡£˜^R·¼”’aa±Å­uáÙ„†Q›ÆÑ¤GKKà­…Ú¤?ðRJ+ÉÒG¼áñ4›¥w3‰þ{2bqð¶Ê[W±ù ˜mp[•À½TSÌü¨I³DÅÿË4QÖ9:&M‰¦6 ]›0ÈB (Ÿ/ôªT@PÓ‡rcA´ì!ËÁ,+}„6YžÎAq}Z“ˆ%$ÆÝF1Øyi^TÒ [€kM(oÕ%9(ŵ’n²e²—“`._ß«ϧs›–*ͧF×;)ó]…+¶Îª©ºŽÉŽè© ,4NX^€Qì·üÖ‚0ô ’VPebž+Ki„EGpH”ÝØ©E·N;³|ÿ”ä.CNòe¶¨N5iŒêSä\tFNßôèÝn½”‹¥,Ñ`JÙVßçÔÒãÅ<ÅU†ñìñ\‘ .àÔ4!~‚² .S Ì#mL¹eÁá€h£‹ïÏ.¯Èb«TÜsULþg6jÏS¼ æÞ[ý§ý7Þœ&ÞDìj¼”„+EºèÞòÅ +l%¿Ul‘–åºXN áØû‹€M²YVG, ™Oð8›º¶ïé[#+xWé̪ÍB‚Õ´s÷•Ü×Ñ$וÕOZ Îó¥–šŒtæ` õU ýÜê#Vz (§}T íݽ®±GÜØC¤‹mN‹5;Úãa0`ŸIµJ¡â¢(€uÀ‹õ)õô€êZ@ºEæÐZhƒú‹KíÅ& š[¨¢WC…ùÊìÂŒVžP§¼W7°% Ó’LáënÕ}7ÜÓÿwÊ»o5 ‡:£qßËiAøÜ¸¯‰….•X÷J}°UbW1=ÞØ"Ĥ¥´¯LWë}¼°­«ÙcÈ.­ð3·ð@;p§P;kF"Ð ÷™T™o˜f§VT(Rö=BåPå¹µì§ä Ÿ¦Êê…iÿ¥+9B•&ðݸ˜­æy ®V ?$¦\ÞZín‰žÇ-WHÖ”½PñQì|É`2z¡¢õ5) bYà$BFý›ùób9Og³ l-–Ù<…Iê Æ;ZÛTÖÌKKÄ€^ r(½Wy8î·A™„©× ÷ðmšOØzš§ mÞÉ-ì VG+52ÑqÂÜSsY)Ñþ3…†ètõNsœÉqerA:9ÁwÄy¥i·Ûƒé)††¨à%Xë–céò€©LUmpŸ6Á˪ z`wô ,«¥Ô(¬?é²Yé6qÄ`fѦ²TqoÎä–š÷6 ·æf.W˜šŽqˆÔºûª#–¨K¼³7¶‘–’0%Ž&cwÙêX•¦yÕÝM 16…¶É `> endobj 1386 0 obj << /Dest [ 1400 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 171 757 206 771 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1387 0 obj << /Dest [ 1400 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 171 631 206 645 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1388 0 obj << /Dest [ 1385 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 275 563 302 577 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1389 0 obj << /Dest [ 1379 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 389 174 415 188 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1390 0 obj << /Dest [ 1365 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 455 147 482 161 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1391 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1392 0 obj << /Length 2995 /Filter /FlateDecode >> stream H‰ÌWmoÛÈF¿êW ²,L†ï¤ ×@ûÒ´—\é\ãâ@Q+‹ŠÔñÅŠúCúúû¡3;KQ²Eù®—E‹»³3;ûÌûËéèùtê‚ÓÅÈqÁÆøãÇ®åûvÑ8°ÂØö`º=UÇÖêŒ uZŒž¿ž8pWl˶<“ŽÌîs3ï“; Nè‚1ýy4VLcˆlk¢`/¶B›å*W±ÓW÷'ñowM×6LdzBaÇ0ÛÂd[4KÜq…4P’¨³^¼>‡¿ÿÇ0\WH ¬@d†-Òå9L6YóOYåJˆ'’bn˜cÿRLÿ2R/V¯qm+ÄÅô÷”›ÍÆ2<Ë5Ý*éZWZøi[®HõÖRIº™ŽÈ`ä¡å…x‘Ç:ˆ$àý*9ZŒ^Nw`x±Ñèѵ ¡Ðë-ãØ!…¶…ÿ™a³ÝþôIú/Ê|.«[Qßp+ 3FjÃG˜$ƵðÁέaÁt‰(Þ'†éá[òV.›JêFÎA2s·‚º©²âîfm©Þ,`&¡\tg  Äæ´Ž¹1ÇŠÄ––žXKh–݃uLÇÂg£QÌþ•ý#Å2©!¶HV³ì®-ÛZk…X¯+YË¢Iš¬,,ãóoµ§£Ð€$»‘6wÊ6àc>C£i`3ì…ŠeûLawjÑa¯ü%°|/Cz–+|úq„‰~ M,Ðp•òªäÕ\çðö:`^fšg†é¢î ÓGIúXÝÞý}ô~>WèƒpF¤H´´íŠZŸ¬.X£u¢‚&u½ÑŠTsÅ ‹°1:Ô(¾¯ÙQït?ü úH$†2rQB[$RV¸ï Àx\’²p—ÝËÐnä—Œ5ç Wëf |^’ʱ`rKÎ䋼-“‰ :7^Ä ¥áˆ “ÑëWøä1>C‹7èùä ;áŽÐòUȹÅ}ì+áïö•£y’ 0†²U!!…V,à2ÍeÂߤ|,ä—f½10kˆ+6& &øúîüj à¡ÐÖ -èw\K“PKD› ATž4r…ƒ¨õ{ Ï3;#Rˆ*.I›| e!÷ÃuçNп5à·VF@6B å”N@»t…à44þE;o–è# ¤cZêηü¥ö)q ÎI“.¥>Ðû×þAòµsx‹_×eíÀ40Ȳ;ÍÕŠ.æè´Eªß3ý#»yØ»¹®Nµ²aä΂Ëäžò݉7/7™J~*\Z˜ŽS‹ÁìÑëÒ2oWÅų¿¦³õø³Ú œ©€ŒØ¢¨à³Üž¡Gy⦊²Dô=‘ñ1è~¬T(ÖªU’£ÙXWÙ*©¶(%Pš'oÌŠ¦T0t7UÐ$³\b<*SµEöK+‘ÿ¨ËôeÌÑe,›£SfTÕɘ$v,ú+Æìî›o³ÌÒ%Ö#U‰:ú²HD«Ú>NÖÃçv̨=¸¦þbÖ™–˜Ë´A2}J%G¨óLÓæI“<*gÿ¯5;üJ5ÛûJ5{WtzÔü5_gÐÅ^̧%Ê-”åø²¶–•ÿëTÌ7{±žT¿¸7Æhø„Ÿ—gós~ñCÂ&GV.²¥üØ*'¼ƒ|GÅ–òfAðªÊP|cò$ÂÊ0 k,x´>]·T☨Õ\àÊ¢Ô]B×GW£¡{W6ò>.»dé²Äe^ÞQþ"«b^M?3)¥¤á¨ð«0ñQõ+tT&³‹:ä?Žˆn .0œæø0«d9\NƪœD¤Øá_b&« àtR÷/ý̱¹eÒ/ùW4y4œ½ Ø¥@ŠJn)bõGÜx·NZy™&9FI ‘®Þ’¨9C¥°ýÌŠƒ–ÐyHÁ¥"¢ÊBÖ %!:]òþ\òᄂLoÍå"+2ƒ©¹T·kÉZúõCwT(\¶¬ŽÜWç3ùcH4Âp•laFÖö»£*r6Zÿ¦AïàÓ”ñyKNåYZæbƒR ÁÄjŒaUÚ9„"¢¥¬%¾ù(x„݌ڬ¼§:£ºR{וîYü“8VÁ*Æú›`‹»Ú‡ù:öTtU ’¾b©5'îBÊ9»Çœ«\šÍªN©…¹T9@gß]ðxøbé#â·‚/ )uÝXð¸>ˆä‡^÷^³Wß|IVë\²Ù¨ÇÆÖ‘Ü‹®Ì½ e5j R±¹¢ÖÏR…_³kDœ®•à¾78Ô蓸¤tŠmC®3¹ùîæÕÔ0q|?Ln>üô×›Ïß¿˜L>^óæ·¾Ë_“ß½ú‰ÎLxýñÏ7nÔ•7ÓQìYvì€?ÆŠ‰Ã®åÇ`ª¿•-ž¦áŽê»è6ôÀŽ-×d‚¼w·ïkªƒWø¹Ñ_NGh8ÿáO[ã[H?¢s6Úz5R°½¹þÓ³o~xvù|Z2ü2!6©ñ vƒT… SO sœý rwwŒnÖ?Æxж»/¢”<˜½‡èGcÜóÑŸbÊÐeê[A­;‚ógß¼{vk`¬¿=Uê<Ê+á ÆƒTSOàtœý rwwà ÇùQ"¹¯ÌWi| ¯‰€—]¼»ïËà™ýœ»ïìÔ·EFL]çe7q¨%v—i•a°bãÞ¸¹º€çÔrêW¿‘#Q€V˜{àž]O¶¨t<”™ÜûEÊ9ýì¦^ÖóUY4IFCUV\PðSëÝ‰Õ /D(VG¶çì‡\­TÁ´bB¸×¿W¤¹/ªg*AG†¾OâÅ}’”—òd¦šßœG¨‹a]xo¼î,°¯ÿÁ0©þP¡“I e‘o‡ÕñzyñNžîÖ_áÌ“2HŒOð>vÐg¾@Íd14V%qæ*hŒ™•e.Qî}’·RÕ‹AXÎx§Õ˜µš°HR kp¾`õÂ߬ÏCZÔ 6=FN¸ç/j,'M•ÍÚ+.¥ TO¨‘ ,Ců¡s•k¹HÚ¼áׯ'®0û;º¯ ÝÚtåƒ÷=1̱0³—ÆS¬OS,ϰºÌú<<ÆB]”)U=¡È/2E¨æ°(+è¢[¨ÊvÜžmá²¥êïk©eQV˜†±|k¢ü/ÛU°Ú0 CÅGæB’­0vÛa°c÷n˜Á[Gcìë÷d=›Ôëɶ,É’"=)F°f”>ùv–¿ÝSHȬK Ç„ÖúPÅù:0»}-ÐnVÑdsëlîQ]Õ¥Ÿ˜’9ΘcHñˆ…aeÂÞÜ[Ì3%¹U²óM‰3ÕÑ«Q¼Ú˜~–(vø†Zž°ušº¢z9é èØã>‚à±á†,\(¹,&Ÿ‹’ª¶é£Ìg#|ÏWâ|‡lIO·ÌQF‰1ÙUA£j`êÌ“rQÐß¡ëTö/ØÖ›§,8 Oþ½ýLÛ‘$ó•Óf+,;ëuÙÈ2X]J^Np}ЬI¿Eb0“–6¬­ §y?kI·âܲœ^5;u U¿¼%zêA©|2T‡9éQÁö”—/ŠF÷Fz(œÙK¤|i¢PJÒåNB”µøEííÇ„ó'ÀŸpýX endstream endobj 1393 0 obj << /Type /Page /Parent 1723 0 R /Resources 1398 0 R /Contents 1399 0 R /Annots [ 1394 0 R 1395 0 R 1396 0 R 1397 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1394 0 obj << /Dest [ 1150 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 221 536 263 550 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1395 0 obj << /Dest [ 943 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 348 282 370 296 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1396 0 obj << /Dest [ 991 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 464 241 492 255 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1397 0 obj << /Dest [ 1400 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 196 76 232 90 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1398 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1399 0 obj << /Length 2417 /Filter /FlateDecode >> stream H‰äWÙŽÛÈ}×WÔK"`ÑÜI¼t 3FÆ­y‰{(²ÔbB‘m’jYþüCþ19÷Vq‘ZêžyM`¸ÅZîRw=÷Ýröz¹ô„+–ë™ë ÿð$žN$âEhG‰ã‹åvöú}›ˆ¬å;Žh³jöúã­+îÛ™c;Ž‹;ÙlÞîgòoé½nä kùÙ‚‰"vìEÆ~bGŽæË4“ÓWõWùo»sϱæ®oGÒIÄê nU·ÁŽ'•N²-Zñöã+ñ÷ÿXóëg¡ÊÂrd¶y%n÷E÷C5%3ñeZåÖ|!Å¿ø¯õÛò¯3~1¿Æsì‹åì±ûýÞ¶|Û•-IU$¬!ÒÆ§c{23[æt³œ¹¢3/Œl?r…ÛI""–xcˆFÍÖ³wËÁ¾‹+α5Fë:dÉÖƒã£Àv\lßOb¡—½Qã0´cobUì«â¿ úº‰•Àâª+¶ªíÒíCûwÊë7âÛN5±®q¯:+ÆnWà'’Õ½ÈÓ.]ñÍ´UÂìo•¶#TLNÃhÐË[ØN2ÑËíÕrµVïëªK‹J墨ްqc9°5ÑÙqï"\Œá¶ÐL®Z+‚Bª±B;æ÷ì°+j½WYY¨ª»>ÕzÎüq—¢÷ƒ1_2˜/1Ц•È´²ZÏð=µgÛ_~BTA²µ ¾ÖÜCðŠ*Âà|$ÓNm¡çe5½AMW{YsK‰È®kŠÕ®S--]Iʺäôç•9䪺R}Ø=c—½øU~PëtWvÚÉK~ݦõ­êŽßË‹4TY±†yNas;yµ3¼W§‡3jÆœ½Qˆ§¥,-ªH@mhy!ºô^èÏÞgÉÉEj«þÒF 8Ì\$×ăkºMÚ‰žÛNÿBã®d ‰©à$›oDMr˜5RÊry›B ’«Ô°¡¥/ÅÑŠ‚%–^æJ¥W6â³^ÏMQ;ާ܀'jˆ¤g@C½°Å„Ú?ŽŠyÿIÔŸÖО_h;ößäM~¼^ðlÖBå¯tíVú  GøædâV5ÈYmÇOŽá…^,UÖYZ²®0ïlÓŒ/Á«µCÝ F³«Dj¾Ïä´ed€Pî¨XÀÐÚ:áÔ:ao1)œËÅ'¢Lày— ´c3£dõ!”#Zª½ˆîˆÎšSm­9þD©ÒG¥­¬‰v•ùzè-Ú •ÊÒ9TÚDy±^«FU™î•=•êöJU\ÉŸDÊWŽ>Í…ΕýR˜­ƒÞ‚£Žï°Ó²mÁ“iÍ @¨Pš»ý#:UÑ##™ÄCS¯JµmBo,§A8æ´Óç4b@·«í®í`Ôn×Àí¢-L%ªîK%šz/6|À;Â3«Kkw:™¶•NæF=4ªEn·:sIÙ„^Jà[¥¸ívŽêÔ€¬ÜXàúØÊS¢ñxÁ_è¥pq svÕ%Ór§ÎäÞÙ*ç=“–ŸëNé‡\‘ˆýº²\פÓ5¹ úÎ$–>C¼Ãþ.ÔÈ-î»J_ê¸Àxr˱‹÷št**±' f?¸S°=«N}ï8/5a£©vüಣÊçSÈŽÕãlű¤£±¤ö3Àbk…76 E8·ŸØårcÐÜÂ!CCm²›ïp*‚‚ÏÏEÖÔm½îÄ-·ËPþbQ‚¡úsmzcbô/®:vHü½àX4ÈY•×·7?ݼ_Zs <ùñfùáíòæNÞYzãímÉÁ"²ð.N@ãK‡aÔ^Ä>=äfp‰øùÓA.šŒgN9£à”øü9°îˆ“D£Á@ÃBFƒòý¯_¾Ü|f£,?ý|sõúÈtäÉi¢ˆ8_Òñâ)GŸ>cóä/÷²„AòŒ}.œ¿;?~õ¸9žOc©?24íDÓA` |¨Ú‰÷MÑ©²¾'“#ÈĆ™OMàÃî ïÿstÇ*NGƒ =B”ÿ‹sSy¾¦Z£gF²l)ØS›ÎW|oˆÏíaCA]ØEk"ÄMp&&CP8G„ÃCFl¼b¡˜q)Ü~UÑŠÛ1sú]·x³ÊôÏŽš!d˜ÝݘzŽÙ1bÍõ– ò^óÛvuczáF™GZÀ޼*õÙ£ê^¦†tÇt‚9Óèy03*ˆÖе­¡¨+aÔX[Ã}¡¡¦ßý.›þ5ç¡ù˜á}Š+À7™5uj´}àFt0aú®wPMS7-€ŒAÔåóð€†’÷{Œ÷à‚@ýxb„ˆÚÖb\k…ŠD–wÖ…‰h¬ Ž© ¿RFÂÑiY^õð&’¢ÿEòSIýô™ ¥+oo¾,õ>§Ù0r¹¨ O*î £.d½ÂàC•µK˜í§°ó2è æ|R1?Yl,Îr‚kcõ‡&±üÆÎ-¯…^’b!)† ‘ÕíWÏJßÈRLyn?„Òš€[•1­æ EÞë[¨A\ÀÅô@ZlSTÙ;sÙ T‚¨åÎ08‡½Ý6º¦ËÑ×À£<‹jyYÖ{LÐ1¢á”Ò#+`^Š#E›˜dbì>(¾Âðô#ø“N%VôÞá&V,ræ¿Õ„’°pÂFL:OUÑG°(L¨Ž¨[ë­šB$0'ì¢l§Oô_Ãq2DŸô¿€û|ʲ³qqqÀp¤‘ØýÍI-gâ KébÒ>þ”/u9-ã,&½vìa.÷0y{À‰éäIç`B*Jƒ@*¯cyO{扼I´»£<V.È‹'éD‚ì/ˆ;3í òúq±QkÕP˜b<%®ÿTÔÒ¦h몥á­5:Û¤Õ½Ê_ï*Éjv — ”¨è>…&}âð©ÏÌéǽaA ‡8µ—h@ÿ¾D£ÞTÈ´S81XkÑ¿ýØXV K5/[l莑([ Öjº#»í7ªâBŠ®‚ i‡âø€ÒÓî2äb»Þ•Ü&D°¿I[ÍEåÏ蟜À’^ €€,»Ôíû·kXÂJ«*?UþAuý£zƒÑ³Zk«Ob¯/@µˆ UÄç"¤Ö•âŸêÀõ6B)¡z‹’âØ|¾t-‚ù½r˜Æþ;vX' endstream endobj 1400 0 obj << /Type /Page /Parent 1723 0 R /Resources 1409 0 R /Contents 1410 0 R /Annots [ 1401 0 R 1402 0 R 1403 0 R 1404 0 R 1405 0 R 1406 0 R 1407 0 R 1408 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1401 0 obj << /Dest [ 1411 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 194 756 230 770 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1402 0 obj << /Dest [ 1379 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 188 735 215 749 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1403 0 obj << /Dest [ 1371 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 197 714 225 728 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1404 0 obj << /Dest [ 1400 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 240 607 268 621 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1405 0 obj << /Dest [ 1016 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 458 553 486 567 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1406 0 obj << /Dest [ 1458 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 323 472 358 486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1407 0 obj << /Dest [ 1357 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 177 133 205 147 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1408 0 obj << /Dest [ 956 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 418 133 445 147 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1409 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1410 0 obj << /Length 2741 /Filter /FlateDecode >> stream H‰´WënÛÈþ¯§:,š7Q”ápìl°‹l.µP MŠ€"G7©ˆ#kÕé;ôû£ß93%[¶³ÀA,r8sîç;ß¼šôÎ'“@øb2ëùðð?Q¸QäÅb4ºqâ…b²ì_7‰ÈÞã‰&«zçon}1ozžëy>öd½Aû¸íÉé\ ?Ž„3ù­7æCc1òÜq ÁaâÆž‘Ëg>NOØN–ÿ °:")àc”ˆµêÍz¯&û`„>¶xÇÑè¢ëQD$G9Jîç¨ä(ö\üïBéàgùBÃ<ߺÙe9r£±u“rui‹ŒÛ:];b9w°œH¥Å7µ_dãĈ…BN‡Ýw±à‹³W`M°†ï&¤äÀ$Ö² ÙxƲ¸³Ì–ĆL¥Z;CXr`VhÌrýø sFãGìÉÌžqgÏØœÌÕ]‘)ñÂ˽5±µ†–GÒwèct`XdS¹^ù‘†ÉH˜×6«ñÈwƒè «^Ü6ˆgó 莄 ¿ÌS6º^+…¡Ô»•â/í7ßËþy¿Î§/ô_^˜-·ß ´ƒxóêÚv‚…Ä"ù¤ø:nör›ŸWYáŒàϬÈD£´6oÕ¼¹ö‡…U{ç’ßz䇮ëJ§E¥rQTÜb£9‰Që]N¼.'žÍÉe£Öwj-(Ö{ÊÃXöA€DÂA¶¹y˜Þ)굸ÌJgŒ¯…ª4…[‘iBˆÍ÷«‹ BÌüp_]€ª6U‰õ,­Df¼3Ž Ÿs,é³2®ÊRètÞ8„oˆÈéJÃSª?”5l$71Ø›hšË6Àag$µ^ÓV ½úòâ‘®xÖÐ*]ª³6ˆ\‚lòw‡Ü.ûh<µ~¤ØãËÊñ©¡Ó²h×gØ3M³oÛt#tË%Í—©.¦EYèÝÅ¡®nzìŸhÿ òýïoÔ,Ý”Úä%yÆ]¿Ãël­™<’°ÐôÇ 3#á „Jfi÷2àíµt÷:óXò°S24Z&@•cÆ'Á ¿´éw¬\™5*iI+Çzj—†—)û–j‘Ò6t5/­X0›0²§3¡kqëp±~th̽å¯-jðÉkg’LÆ^ÑNˆü’ðÆ·„‹™‘C…QR³N6?m'q¡=àí±Ïàm“­‹•.êJÔ3v«C¾—ä"õÅ\U¦ã•éøuZº‡ÂS9è Æ»ß*œsù®Öê¢Ýjkø1|²nÍ, ¥.ª¹Y`¯˜:/jgÀÆJ„®çâÿ{EàlBJ›4¢Ï£0§—?Æì¨Mÿ˜— §oµª­jÛQyaRTF–»Œ¬p‘f™2ívJþÇ·…V¶„Ù×£:õ‚Î߀#I&OÓF‰YQª¹h´JsJÕ¦¡ð¬¡Îfm¼DÞnÙì®+®ò%2HÏ<á/òöÓ»ë¯6úŠêÿoo^›·[пOï(j‰©Ó±üúëÕ³|ýõæ5CÏßéÌÏׯi(šÈO¦j°ãíû7·TPd£‰Jj¾-W¥"<ŸópîõðP´H±¨·Š+ƒÆ†2¤ "<’¢bãîÔ ìÒÅRÙ¢IrJ›r…)R6"ÖMÎŲ=¸Veª[̹ºQWðÆr÷^ÝÃ1ß³)û`?ãÀ‡R¡ A§F¦†¨sK»PÓèAoÃ3e6JN@¨)€¼Ñxm|^¦;K 9"S…`gå&7L;’Äı‚¥3 ÁÜê_­ë|“i»Ç½Ýaàzã=£?j÷AxPÌ{øb†[Ñ1ݶ‘¥§á1s}ð%DärV—9zžÆ+EËÀæ`Ö\é͆·NUb3c„ûÆ«Ê õÝóü*L؈?“_sò²Åx`<ú þ,:´¿Rfû{&C+ òûFQæ1FvæW4à0Õœš}ø: j«Ž÷d¼_ÞQ…oe:E³£ó.ž1± ·‰·d´««’®TߦK 0ŽúîÿKϸ8¡¾Rª½Ï‹þ(%âÔHµ\éé­lç4ÑéH‹1„Üc&:C":ôÂcÝ<®xÝðf)hv“𿕆ÚdQ-™ÏµÒ6æM€ Ç0TO©ÁBè> æ ïÒrC(Fè Ì×"Kù:PDuçœè™îík> NÂïÃy€â­´±Y[K›½MÍf: D°}M=ÈÒ’.*>ÁBÈiàåÁ95¡?ËŸx;Æ]é6Ó¼¸+€M#°t‡y%BF#ù/Ê?aì¨ßSšzgö›Xó…‹ôÚÖPrl¬ å*]Ã#>=52¥±lÔÃáÔ!3·m½þÆ sµ.îH´¡‰ ÄÛ]•ýúv *jÉ\|¸¹rŤÆ*ë­™µÖæ Ø9]DèÛ|¢ìûE&BYÊyžw] qC1n*ë•Iß„¾éSÖ˜‚>´žQª=I%5ne"yëz)Tš-D »³øCW…‡ôÞ„€cåÐTkÇe¡¤›íÙ¾¨±p¦¸’åLI1 èæ¶o”Ç[.g÷-12 w$º–)×ij{@õ´²d¦¶^ ¤pGYýVù¾ÂXÕ$f?uÉ]2¡Si™ k•‚kSAQšÈ’òÀ{Œ‹øí»çm‚x¡Ï컢K©´Å1ÉEß&8ȾØòoQ–T)iž¯•pdC.¬Mzó³<Ð|nE÷1ZÇà0ˤ]¯¶ú„I$ÀÓVt½,4ÑC¥T3- b³Ã–ÉkuDO-QÃ0(V< z¬°•ZÊ?W§35î25n3Åa]ÍRóÀqŠå™ ^¼3ÈŠU€E–ï;Ä]1Dk¨ðRa6*tæ|o›ó„sÙhµÜÁ]õ`‰`K%p NýÄ} â|4‘t“¹Ôêwnôâ%¤šeCÝùVáûü|#ƒa—öÕ;°RØÎHšM/ÍËكͫí±ò©nè¯ï}q §0_E+×Vbrº«ü}‹è@ÚsÔÂ;c´¥ÌŒä–ïo5.–3BÿÀž²»7! }ËjóC&õIL÷U !<á4󬩽3ì‹ Vä‰!w²)‚'6á8,Ø f NØ‚]´!¶ñ'¬£â²ó˜¿¯Ì1ÃÐÜlȸœÌòY±*iâ9fj¢$üãÌÚT rEu"ñÆŒQS³Vrp"'Ó2eDÑv0 #bgä]ÜgÀž(Þc.AÍ|ñ“3HN°=°áñ}¶·çättZ¹²oH•ýXW"Ä\‰ÛŠJxàÐ…nÔžFçPšÝGƒ,¡AF‹f” ’¼bqf8áå#4ªa«Tè5w KÄoÿ(‰ÃWîÀLC¨Õ†…†RŒ¦f|¥@#C!”L µŸ™¬†ZL52wêƒ&y×.Ð5ä! endstream endobj 1411 0 obj << /Type /Page /Parent 1723 0 R /Resources 1416 0 R /Contents 1417 0 R /Annots [ 1412 0 R 1413 0 R 1414 0 R 1415 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1412 0 obj << /Dest [ 1379 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 262 743 289 757 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1413 0 obj << /Dest [ 1305 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 228 286 258 300 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1414 0 obj << /Dest [ 1400 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 257 256 292 270 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1415 0 obj << /Dest [ 1379 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 262 220 289 234 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1416 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1417 0 obj << /Length 2904 /Filter /FlateDecode >> stream H‰´WÛnÉE^ùýb¸ÇsçPð°%yã×r,.‚,†dKœ˜r9CÑ̇äòyÈ©ªž )R^$2§ïU§n§ÞŒz/F£@ùjt×óåá~¢4p£ÈKÔ`»Iê…j´è½¸(S5)y§ÊIÑ{ñý¯îËžçzž=“^¿þÜöôÇìÞ(?‰•3ú{oȇ†jà¹Ã‡©›xr/Ÿ ø8}Å þ¬ÿ`¶xNßÝD{©ïÔÍ®¨f˜ ´qp“.óR½þþLýõßN?ÆxµØuîxz2;S7Û¼ú‡YÏù’PgÅÔéµú'ÿïümôC5fmÏM0]bŽ%Øn·®º¾.éUCÏâj<éâÓs=±S3¾éjÔóU®zAœ¸aâ«p঩J| © c”ªµéÝõÞŒ0B[¼}4Zt=BD3z°Qzh£ÉAâá”aL?ëgˆçCkQ´µsäFC«(Y+j ‰âk'–P8€ò+;*#STò¡€ˆÚØIÙ¢¾˜«FGçUÞ9öÍ7_Äè¬RÛÌ®î½\mdX8´ÍLÉ踵[ßwÉÓ¬I«…u —,EH·ùì1îü·‰´ÙÉÒ¯óWJ¾*6tV™4T·ÚñÙðrÜò$·Ž«äñ>Cˆk£ÄúËDœFÌÕ‘­ßÆFŸõˆÜ)rS­~ÝØ¯õÎÎ,6eW‘0(έßZûÁõbz!8|üì+o£z[dý¹q¢:Ð]/jÀ6ÐÑ'‰÷ºPf±ªvlHì‘ $½‚‰žWJ†v 6œ™‚Ís(z £z>5r…š.PŲRæk.£J-~JêË6ëU|³Ê;ç²ù|¹…'TK•M&öF»žW8"Áið»à„˜k\,°8Ujn2zHš†åc½UÈ>3šv˜T²© À÷s£&ËùfQ২²¼È‹{åøž #{‰EpPGß1ã¥\.´áDGë™JŽøóTYùTv4p<¿µ¾/Z•Õ²œ©ñ¦R“¬Pc£–w*+vjŠG(Lœ>™¸ÊTµ[Q #„gY‰6íˆt¶çÎ[ï7ËM©äF8õjmJXVå0ûV+8]Vˆs¶áûdX±âÖ±H~õ5[¬ì­æØì`C´y^P¾IõUeã9Ék媭qRöc]ðˆx‚>èc-7Aÿ©²·v§ÉÉ)­Q™°ß3¾1£EBân¹wù­ã„º s¿ö>ñÞh $69 (‘Àn®Þ_]Œœ> ˆ~{ýþòêÓ/ºúÙŽ?]ÿ(_7?¸øE–oìšüüpýîC]¾ÒÐõR_%Qà¢ÌPÅêÔ­o-ÆI½HCw9öRèqêðÓ«Í»pŽzÕÇÑááãë(·mÍLS©™‰Ÿ¸¨›\3? 6¯>Y¨>ÊÏ5(Ä;ã rÀõ»·î!ȯ?\ÖÛ~º‘M(½üÖÒXÒŸX?.½ºWKÿ—?^}º²&µ²½»üîù³·Ï_¾Øs”‘âaJüäܧWÉÎvõ´¡OÿÆr ð”©O¬¿9Nfk¢?Ï¥&ÓÛ€[8Õ#øÃt dØŒb<ÕaX°”­çžåà “‰y ¾8©²õ½©î OU(Ä&`7âgí^Fî¡dTf[ò²$j7 ÀY†ç2!åY }e³B›â/£‹PTMÙy…ßæ}S3Ç„F6 Aô9±#ä*0ëIûnœò»¾6ɇ6¬¯¼«Y‘±ŠCͼ©&š'Éj4‚w ôf$_H-DÙÊ‹s¦ÙƒGü•b·-ËA73N³Š©$ŠÓ’2ü«C©ú|~Ÿ¡u,šZA²¦0‹ñrˆ*ƒF‹ÒÍŸß ¿‹0ñ;úµÅJ(ú—Ó­pÉ¡»½&réáÉY>GAiX®Ï¿!c‹·®¯/ß\€¡Ìw¨™D° r^™[ç í8†™Pn¯‘A¢+èÚbÖ'¶}~¢Ù· ÇÀáyð'zöƒNtÈ{Nk'áZ›pâ™IA%Oq?† %y¶)ÐЀʳКP™ì•^F åwo”ñëTƒî-è:ÂOS‚sÍšâæ t¦ÃÎñ >nI¦Êá+ JÄŽ4l¼È\x¸d ^].9¼‹; r|UÂá|ú*&õŒ]Z?ÐfîŒxÈlRvh¦DˆJR[¸Y¸P¨µÊqü-jä˜rÂbl,æ„¢XaaÛ]³ÈŽLÂ9CPèB=ޣ̃½o§&óœREü˜ˆ]BÙ/€²½D8õì Ö;´Y›þ6›¥ÿ…Í@lk#ê~ÕZ"£Y²Žš¨,­]kô‘ÄÌ}Øòcj4ÜNˆO4-ÇZ6ˆí8à` ç…ª×l{Âs³kÛ^P’/VÙæk>ωQ:“µ“léJ¶³|ÂÐŒÛ ÛûIÇ4éö:¶Ñ¡HZ¦‚§«Ü¾GF kìH–g_×­Ò­ÎÅøºßØù áßå÷ªä.¢<£žvmÐ;”ŽoÝ:„ƒ­²52…ºËÍ|ª.o¸Ï¹¸¾¼bÈ’*JcwI¥,ÕÝ ‡— 5Íïîp¯u޲߮µ[ÔÚ-²5wIÚYÅ}î|}ÆÝ¤’n¶›ù’¢b ·ðE{’ÍUï•[V™,e‚& ̵³›e ía2ÉH7@aåºàúì C]ËØ+êÓV°\¦Ñ´Ú+DjŠ&›½›¬&¶ ›fsΔÃçè—ò˜™rÞ›Úü0¨±Ñìk¨WR­T†÷OfŠ/ÐõzE¸$X›¯Èƒ|ß:®zd¬§›Ô#N† M¨á>[S•+3ÉáSSK=Xz°x2&xâ'•´=›«Õ—xªÿŒnÇÓ @qWôL®ñ®/=±‘2esÝC6ßH¤`˜UjkÃCí TmdXÈÝS5ÞÍS ´öÙæÅ/€»Wª-–ºÀøÈU6HS"iÙ'ß}D6Eâi[Ɇ]ø7çìŸÉÿôûÀŒ3¾$ÉýÏ@·„¶á¶ÜP°Ì”|ÜB-…ψ`YB#¥ä«Bçw,áø¡ÍÓ¡5‡Ÿã|«¹# Ï ÙáS¾ ý$Ÿ“¾“NQë‰ EëËF“%9Ú°u´¨«ãå¹M„ßÐñ1Ùã+;²4% ÒÔCºñΡ.ìÒa~¸$òÁ«7ÐêG>üž¦,»ćp‘JýôIß:L†~“š‘ßUó#©I¥ä´šGû4¨iVkS’F,®È÷¼Tk³X¢jS £{+û;¶¿¥Q«ziÆê8)ÉÉŸ9Õü…ë?õ£õñdÃ@_iãÞ=eÒÖiý½ÔñžøN¢u¤¿ŸA«|aºäC::±ê<ë.ZÖ¸“kAî['ßgŸ/íÆÿT^Æ8‚0ݽ #‰®ÞÀ#8«‹·—ß_Rq!ŽRÈã¥é?8êªêØh²Û•?Dï°ì•K> endobj 1419 0 obj << /Dest [ 1163 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 470 743 511 757 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1420 0 obj << /Dest [ 1163 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 238 638 279 652 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1421 0 obj << /Dest [ 1168 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 377 560 418 574 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1422 0 obj << /Dest [ 1163 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 470 525 511 539 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1423 0 obj << /Dest [ 1168 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 383 447 425 461 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1424 0 obj << /Dest [ 1168 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 255 326 296 340 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1425 0 obj << /Dest [ 1168 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 404 305 445 319 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1426 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1427 0 obj << /Length 2218 /Filter /FlateDecode >> stream H‰ìWÛŽÛÈ}×Wô‹2°h²Ùl6†;^,xs±8yÈN8g†D*eEþý‡ücRÕÕÍ&)ÍH³Î`±H0Àˆ—îêªSU§?ä“7yÎYÄò»IÄYð#„%K³$*ŒY¾š¼ùíV±ùV¯ Ùv^OÞ|?‹ØývaÁšùdj/÷ïOÅ}É")™Ÿÿ}’éMKà “`8V É®ÞÃõv¼J$îþÑû‡§SúÓ(¤*v{`³CÝ>Àî•>Xò¶Õ–½ÿþ5ûë¿ýi÷x—‰Wù¡7xÍfûªýZn–ÚHìõŸfûIÿ÷ÿ–ÿ~¢#ÖÑð0p“„gÚƒý~øqy[<µÄcÁ4Àepon=hKß哈UlÂÄ2bq(ÅdH2ˆQ(¶)'w“yFÁ’pˆ†C7DD<äHsd‘Leçô Œ"½ñÕìÊî5ùÈL€¸Œ»„q xã‹ d§°Z›»­À–uK `mµ2Ï[ŸÃ¢bµfˆ‰×ÜùÂcË¢ÿ’ d–¬~ñáàÈ+éŽõü¡1×7^S/ 5~èšçoÉÌ¡ž·=º/ÛÝzQ´Æ•,ßÝøËõ̓ÞZŸM¦§Q€µùB½ÁZб¸ƒ–Ëf_Õ÷¬Ý77>³{ë²\” ¦ò!ÄýCY;güwÎ{€àR½x‘˜È¡ ¢ ö3¸AœöŒkÇòßPb8S|[ÀKBÝ·Pl8³ÔÂTg"R¥Qâþ½W‹ÙdŽt»N—À¸g©åŠS (,I )ýˆ9ÃTC u²¥Nµò¨Oô^2GÖ¾ø]æU/óªŸyX€)‘f Â-]æU?óÒäRƒÞ<†Rš9˜Ò̯Zƒ•8‡Õ7¶ ·Æ4Åüüb­â§ðøÆ×ÇÃæª+Nú°}F¾M½OþTAfÂ~^ÁçÎÌÖs-kl³Á‰«êxm ¢½¶7¶¶p(G#˜Yå\";ER““Dr’˜Ãuuo©ˆžÁ4o¿”3å{È!1U¦ßÒ/N¦V¦‰§=w¹ÍIu9ÁK˜Úˆ šÜîÖëfÓj3Ü%õél[¶Áh0=ÊG¶bŸ±H– ÌGïê¡&²uñ,Âñ#4³ó#oÄÔØñÒëï´€wnÑK\œ\ ZÀÅÏÅÛ•17 n=k*Xô±Ç®Þ4%xM=$oBð¦Þ” Yô!€ÒbI Ñ zX´;³Á¨¹:švUóS}©}›iÙéá8 œ¼§D!•k LôÞäy9õ6me®ŒŸmÓv¶Õ×ÎçÇÜU㯢Hpôzö4;ž†ß²ãEð?‚õ®ž75öeêU´Û‹öUômùõ²ddüép¢Lφ˜¤ß"­ ‡Ù~>Ä× ªùC÷©éf·º5KˆÌ omÙ-:³"ƒDÆ1ÿî«å‰®O| ;ÜÚÆÔva€@,(‘åçvJb(ñ.‘Ï|Ðßc[¤^Ž:#917Ò~^œ„y—‘žè’¡¯ˆ¨Eìç?~@̦†ìt¿Tõ¢šÃÒ»%-rÀv‚y å⣠œaŒÊÂËÀI¡ ƒ+“’œüR,w%%ìÕMË–àÙ¦X‚0ªjz¬K*ƒ¾öAÁF^ùÙŸ?1Z„y‰€xË„úšÝîZV«]¬J°0òm8@B×zÐ|—Oþ3£òMY endstream endobj 1428 0 obj << /Type /Page /Parent 1723 0 R /Resources 1439 0 R /Contents 1440 0 R /Annots [ 1429 0 R 1430 0 R 1431 0 R 1432 0 R 1433 0 R 1434 0 R 1435 0 R 1436 0 R 1437 0 R 1438 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1429 0 obj << /Dest [ 1446 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 107 577 143 591 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1430 0 obj << /Dest [ 1163 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 278 563 319 577 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1431 0 obj << /Dest [ 1163 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 296 493 337 507 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1432 0 obj << /Dest [ 1446 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 352 451 388 465 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1433 0 obj << /Dest [ 1163 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 429 424 471 438 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1434 0 obj << /Dest [ 1168 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 273 342 314 356 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1435 0 obj << /Dest [ 1168 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 283 245 324 259 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1436 0 obj << /Dest [ 1446 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 461 188 496 202 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1437 0 obj << /Dest [ 1168 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 273 161 314 175 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1438 0 obj << /Dest [ 1168 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 463 78 505 92 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1439 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1440 0 obj << /Length 3412 /Filter /FlateDecode >> stream H‰´WÛŽãÆE^õ— Œ¸$%QÔb±@œÍç2zÊn8dkÄX"i^f Hþ!ÿ˜‡œªê&©ËìØHŒ½HêKuuÕ©S§¿ÚÎÞl·‘ Õv7 #à>–Iä/—A¬Ö›•'ÁBm³7¿o•µ¼&PmVÎÞ|}ªÇvøAbM6›»¯Ï3ý—ôѨ0^+oûÏÙ†7mÔ:ð71 /?Ä.ï‰x;}[Å´û“þw„ÑyxópáÇ:HÔÃIÝŸÊn‘H–t[´êw_ß©¿ÿÇ›¯ð»ÁÜÊ_é t¶¿S÷ÏE÷£ild¡Ó2÷æ­þÅÿ{ÿØþqÆ7æÛDãÇöÆØƒççgß[ø¡néTCÇÂ4Žôñ5ð#Ù¡=[úÃvªBÍ¢Uì/âP-Ö~’¨8D$î¸LTcf»ÙWÛ!‹K‚óhŒÑ ("š£7fÆÅo>þÉŠù}q~ë­ü5< qm£v¸G¢+þÕ7ÞN«û¿~Ë£Šn£[^ßytŸ´3GSv2$Ó©l2ª—Q“«®R‡ªú^õõÊì4vzk|¹SÇ*/äÔ“7'£ ÁW¹9˜Î(±a'J/$·2»¬³G=â\ÄØtÊÚÎ*ù’{¡õy 4¸Db="$ùË$‰>™ZðÔ-¨~Ò¡k®âa‹9h±&/cHâÂ#µÌf¸ÝØÒ(¹*Jñõ”Øz ýÍJ%‡Eƒ_Ÿô;o¾ÄZùàP,u™áö¦Ã_;ñÃá½³j«4ñ#kt´9˜'ËêÈ9Ú°ïÈŸM’"‡Þ½¡0"ƒªe*=ØrE’ŸTªdî$CefÓ²æ´PRØ«y˜øëIÜáE°¢¯äPC©ËÕ1í²}Q>B¦¹S»êÓgnžŠÌ|óáåq¬Ž<íz1"ý¶FÕi·g;u2-­íú¦$?añ`TS=Oa0äzR®2@ { yp¨žÉ£¬:ôG:4QªºUŸ5ÚíSoNìÓqÒ®aš_öÞÚT´9áC£ø{¿"ì½ù¸´kü¥¥å'>"5Â$Ø8*¤o°#˜Pß›“ÝgOüÖ#dÛ|Ü÷I¿Å8Ép½`Î’ÊÁÏT=¥‡Þ(µÝ—Ž9œT‘äÅîTpIFú‘ÃÔ¥(éH“¾ú®jŽék'–í'­­›â˜6'òÕ"„RòIWD kY-cñˆ±¥”þ‚PÖ¥ã«o0,x‚Éewf/ŸÂFò½Gož píôÁdðW+b§%1.ÔÉa…±¶>»ÕF=ã³§†wZOøRÛßJÄÇÚ límY|é"Ä\¥-µkµ;õÐw*KKœ¡ª0}àôÒ¬ºSmtÚóž¾L…·¡\x ®6§V}k­}‰ùS7¦EBÓ®¨J_0ç‹ +Æìšùó‘Ê—NÆû'rtJ©<Ƨ{üê>g±•L±{M‚]Ea¤ØQ:CÝŠ–Gåg5:¡.²=-m™‡“€ëDižLã«ížy%™x!quvI«…*û4²Ç„¬Û}Õrpͱôë¦zB© ~­4çbW¬AN—ÊöioŠ™ ®Bÿ¡GM ´¿; 9B;Zè#`¼d"“áTÆjÔŸkŸ‡ÔN«¶ç‘,C\6$rZY"ÖPjiÍE&Ãå9}…‰£¯Ð‚â­5²PP­SYFtþù¯Ö†[hÊ |éÁÒ‹¶v¼ÌÜ€ižä÷õÍê€ÝûQhóWš|>ØOgF ñÌÛfÇ7=—×í÷¢ûÖÒ6b¸Ó”RãÄ{tAÕG3Ý”k‚·Ç"³g¡kçwSªw¶9C.Œ;‘bˆÑˆõÉJ¿·t¶!:»b‰ÛÅKÛ!fˆ÷h+ X>X@Þ)j¿ïdpr8ôX¿v•Uwµ³ÿR­È}VÚîóH]L 5j¸Ïƒ ‰÷}46fŸ=ÿ¥JZÿÜÆݬ©ë\þ¹¤®Èºé…˜×$V莦ÌÏbNšvéã ½X»n´ÕUVj!0é¥jŒàÕâZ5N¼²ÒЈf¬Ó†‚&^ñDÇ2Ÿ@ÔÓ;Ç-Ï!xªùé* m9t€¶Àbx’ò 2Ez²=øü,’è›ñ„ίEé)ÂÇI|ž"ÁeZ #Îè1ˆÌÙq â+áuºíܱ6Ž>ƒöD^T—¾ƒfá“¥>†ÕÀ+ªŒM[*Rå 3gy¬­%;ï !“‡AwËë÷\œ¶É1vÏ™=Û–lE ¼Ì*·to8yÚ¼H> CuÂ'ÄŽ‚z;8ázЭ©ã*K=TC2%Dpž8Œ uHÓqF¤æ7¹éZ´Îúˆ¢”žÁ¼a0ol¿¸Á&$S u„¢~aF¹ªG(êÝ®©ŽòÞ©0Ôöu]5ÈÀ‹˜iC.›^È(ò§¯À‘Ì]ӥƾ 9@©µdÌÄ+©ŒÕDmœ®ëB,IXjúÁ*ÀÒE$qš²Åz`‹õ„¦"–÷$îAö‰÷œÚI¼K)Iù¥¦XøQ8‰ãbŒãBŒûVM°ø¢4C%+E›ÒËNU¥™?‹¸>‘Àywç3‰mí|à„ŒÓ mk•KUÂ*âööA(4O¥A@Òùëç§j›Ÿ¦lâ—• Áþ%uƒ*긋YëtN—ٽʺWÉ­¥Œ>gj±ŽÐ`1,w¹ÍU×|ý%YÔZÈõ‹Š¨ž¶døæ¼97:ò rnÚ»ÉW«Ÿ+¹Àm¢bv½©w& åØ ä¯q†º®¬×(мµ}üxÖ»î‚è 5ØÚÛès;—:ÁeÅ}Qꬾ,uÆ¥!µœÜCÜ<çêi”Ì%‘¾|¨†xM^ª7ú*K›[½ml‹!n›Cƒt*yÚ$-ñ‘g%r«#¾"85-4ÎTÞ0ÌH✋›”SnlE´Ü{8B&´Ùz1+›Ø)„<–kEƒ–éiŒ w¯©pcM"&¹ý4B¬‘FKb ¸=¡ggB±£ƒØÒALY˜ß¢›˜âõ~«åêt»×kùZáŒE;¨®Ý›%þÿ’“Ân»ª1t5ÁÅ®0M{!=’iÙR[ˆõÕ;%ðãhúN‰‡â‡â] :–¯MQ>Z îN\£‰¦!t@+Ûª¢ìTQ:‰Áæ/4ÆfЛ1qÐ/lÅú’ =¶…¾dý/P;Ô8½Ç9öZÏvUT.x©®Üú`ަ¤W+È#튪D¼9 sÉ¡,ì<èúœ7¢ØV“ð\¾¦H E‘I_Á·q`;çífì—ãÉNâÛª|Ga-ˆâŽÄÞ*75É|RÈ&dFÞbB 1èäâre{ÙBæk¾¦Ï°Þ’cη×Ûxo{k.êo´¦ÜŒ{‰¹MñDU”U=°PÉÐM@¢´âÇ”]”›Î V„lŸ–Î09-_ è½Ì(“·Ôe}ò ¢ÕP¥ˆ.0³2‹E{¹]®Tmh‹”%‰×@µYy%®s÷yæF6o=zÌPì~ðÖyæL%~´˜"jè–ÎÒÇÊBÛ’°AKÛ¦¸Ü£âÿô­úp¯À-ê¾ok4%õõ7*ÓHûCÚö(¨Ï¨ªµË9û*ƒkïÑGÔ;pËÙ/ƒ†a ˆÞùŠQ7é?àÈ¥ *µ…ðÿìήâZ$Nˆ[Ü:îÖöμ¡E2/Äžõ¿»!·KCpÐ2%2#\  ¢ݹÞM×mùªm=âí:Å`Ø(ÞDâü*KHuCTxz}ÞÖf]ðÕ²€«ÓòÛ”ò+û’ÃòI5@hÁ²%¹¡mÞìâ@V÷ÒÅu!Dªõ·'Í èQ¾37ÚÒŽdûÄ;»ˆ‘LEÍ©1l¸~زގñ)U!î–™Vp`W…OÕ®òþ'Nu´U¿Ÿ][ßø«ÈbOðpÉ,X0U­+ûŠU_Yç„…4Ô"¸lá\y(ñÊçDçs¢ó)ÑyMt~šD‡Ž“!Œ§Èt>eº•ƶ ™.˜´ÌbÔ Ô^úI"’kU'üÏS"=ƒ_è·M¿ *FÂ:+Œ‘UbòYalaù7޲Ølºšcß³ {®E/´ç/ž\¶„#ûhNµ„³Õªù‡· ÞÙæŸ°_Â[ÀIy…·­´F¯i1rµ’î>A\z[²œ¥Îª‘IÀ5(Û‘žà³Ä8¨þÞ0•°^„„ Ç`öéAQŠoÄá·Û1î?Ïu&ªOEq/U¿$e€à Gp7݇é:H]à€gdÊ ŽâÏöàŒâ LF6S®f_ÂÊAy7ŒeöX6vºw·w øvB endstream endobj 1441 0 obj << /Type /Page /Parent 1723 0 R /Resources 1444 0 R /Contents 1445 0 R /Annots [ 1442 0 R 1443 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1442 0 obj << /Dest [ 1446 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 134 460 169 474 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1443 0 obj << /Dest [ 1305 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 266 433 295 447 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1444 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /F2 1668 0 R /F4 1669 0 R /F5 1671 0 R /TT2 2104 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1445 0 obj << /Length 2981 /Filter /FlateDecode >> stream H‰¼WënÛÈFÿê) ! ‰áðÎE²€l)‰[Ç2,z‹]»]ÐÔÈâF¢l‘Š£}¾Cß±?ú™¡®”³M³Ek8g.ç|ç;—9IZ¯’Äaœ%ãw˜øñ"Çò<;`aì[Ad»,™µ^–ËJ¹ÆfeV´^½rv_¶l˶9Öd­N=|j—é½`<ˆ˜™üڊ妘…¶8جÀVçÊ=ŽÜN#? Ý7Æ¿ÌvÛìp× ;bw+6\Õ3Ž!Lœd”yɺïÚìç›ß È|Ë7rÓ6²I› Ÿòê7±˜ÊC\#-Ff'6Ø?å_óïÉ_ZÒbic[>’æ¤OOO–éZÜ(éVA×âh\iah[ޑ驉<©Ÿ´8ËYËñË 8sC+ŠXÀ$ƒ^Ä¢5n$k0\Ž%ö.tmBÄè½z{à¢(R@†~lÙÚCÆŸÔbO-ÆÚ }J’DúËö´©ä¯`ã: þ4-+Ӄ鬜/Ad}˜ v}uö½´wCœÀŠ6Èe >ƒ¥¬¬yqÏ–¥‘ó€!”+Åâ“X°ñ|HÊåŒ=¤‹*O§,¯Ä¬´v­îD”u¸å„Òš¯3ÓvÖfÒ*’•¬J÷¢Rf©Ýk«|ï¶ êý/V)[ü:rhT[E²a•VËòÀ¬o²ñ½­}‹òRz›ÏÙR}U¦C„¸,­ØT¤zˆð s—ã΢÷fdyÎŽCÑh©Û6ÙáÒä`ׯ5>Z)í·gC¨>TçVh¤•Øgnhyþöqë,d»[`°òl]šX€—@0;ž<Ø1 ú*2!B,Ú%„ER(±¿áÁ7%\[*+ªyUCRB7¨Œ •~;$°xô{Ù1[,¡QÓ£ÂçMüpßËÕæ›BqÀe‘Í‹q¾ m¹13I2°‘eEM(”Ü£(Áê[øú¾C›åš*.N%²xš,ôMt ]ˆ;0‰Cl8`ñ¾)8ÎZmG©]Vó…IÕV!¶äM‰uÙØ©ãìÀ\w'6üÚØx×X„G Â#4m> çÆ©ôÙTU©2-bó±ê‹ê3¥¢©`¢6D¸Mæçµ¥¦/Utp%löðC6òàïDäÔ:“˜¨óŽñËæÓå¬`·z¿°w:º5½eùß2Ññµ¯”;yn/ÃûçÏ”½×·]Çk×±“óÁImf5A$giÁ&óéˆá7]Àg‹t±bwÓyöŽ09\|—4§à—·ïÀoÇ b¥Á(­Ò6Cs6aó Þ…)f D§+æüÃuLÊ+¨®•  ƒ\®F9å`Ž˜´ØYv¤Ó¼Zµë¬„•J³§|:e…ø$’é&0L|ÎÈæ‘¯M `³ôsÞ‘ª'ÞrÔ êÞlM7Ò—Íï~xX.æ‹JŒ,v²¬Ø˜R‰cÌAXWޑΦBöb–æÓRÙ™VUšMÀ$®¨îàt[òM7¢šóLêÝ)mä–dZ±Ç%$Œp Ü@k£™Ùq·œ²ÕÏuö®>håo §tüÀ63@»Ë)^á@FPD•u'Ê™%Íò±l s ‹Š­:‘ÔçTøê–ºñµªSº\­ÀRØXdª[+ēх"cŽŸôK;GâSž‰³òhAés†øbPÙÞ°÷¤¥@sZMjvèt¥IÐÈ÷~¸ÿ~ð}zøŠ¾ÆYÓcù€xZö([´šÄVä=ßèÈê­Žb)²É§tº%‹Šª§×yc¢¡`ÄÒ‰÷¢i“ý¸Î~¯¹Sê òxä}üWÓ él,kÐÜ$ÓÔ2z}È5rRƒJe³>²$`­>’ã‘Wc{®þÊTàýÁ®–wíd¼®Lªï™©zyŠûÔ$³jc]C Fr©€Ø3¦zNÈå£50Á ž/—’ #ãUA¤ø¼¬èyW®àPÇíO«ct{}¹»º½².£ÊúyÛ‚ ÆáÆýöQ—¢¯€&yAå7›.Gä½ÙÊ«6êÍ ±ÖÅ#](SÊÜîIj;Dm“*ýL¾&‰äºäj“ÁUÿà éÓô\nEúÕÖxo]ÛB§ÖŸݳïˆö5˜å#meÖFãª?¼þÐïž÷¯’mC®‡—ý‹^=s6\_öן ‰4é&×ö4±Ñ‰=Ø(ì»ùˆ¼Ù‰ÜÁ[sÏK©F­ãåY2Hºçß×ß×§ƒ‹·[CrOok¢×Mº{!ç"Qh7½½|Ø‹ _j|Ü?GäÍf9 jÚ1¿(”‡J½¿½ï_õÕ°7<ôúo^ó—5{jp=ì_žo^,7í”Zg×<Ç©#òf±À³kßÎ{úúñž^½þg§})5Šz'—Ýäý›—/._î+ì¸[AÜ ð¹ r~,ÈMT¤47^¿úR ´c+z†¾Íb½Ù‰ªJG 8&oDÜ Q×=EþíÌMï˵ȡӎß|Dþ|~tüز½Úég œÎgÉ@é{«YÛÞ!ªþZ3§½ç|'ˆŸQ¿IØŒšç¯½}³!cû·¦šû±{~Ý_«N‘¦¿|±¬‡/Æõ`t · ½ãŒ9&oÖžj…Ž2ƒ"JîúÙCOõœŸÈ¿"<´¢¦i暃»žQ¡Y\oVÅù8\Gäpñø?œ—½Žƒ@ „Ÿå*Äò((P”.'n—*m yÿ› –]‹«<Ç^Æ™]o¾wÛ¯ç<,8/]Zöˆ®w‰Ál®?]2ý`¶\ƒÞÀ(rãÅÙc“Ø« ÁÇáxŠèbÈnQ­™oâö‰,§®­>ù=œ8;ùÀÓÑæ\í”&Y ºìC³*iâþ‘¯¸9M[ä¥rœ3]¶‹yÙnrÌ|Cö{óŶcÊû ‰û×ê3À¯!³Ó˜2˜s´2u›+ÅKdùSJÿÈ”7úCzŸv:Eè£.ˆ.,8à§³âºÂU«¢Ë¾1~›2õ½!¬|ÇPˆ˜³ "ªQ¬1ýç’º!ºhºoвç…J}íMÁ%Þ »­ ävÍæ¸ú‹&W˜•Èú¨è ˜Q˜ìÈíË÷"Ë<y½»BAWB*úmtù2*߬«ë{Ï&ÝD‰ü'Àc4¡ endstream endobj 1446 0 obj << /Type /Page /Parent 1723 0 R /Resources 1450 0 R /Contents 1451 0 R /Annots [ 1447 0 R 1448 0 R 1449 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1447 0 obj << /Dest [ 1411 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 455 516 491 530 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1448 0 obj << /Dest [ 1174 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 275 325 324 339 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1449 0 obj << /Dest [ 1411 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 293 74 328 88 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1450 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /F5 1671 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1451 0 obj << /Length 2579 /Filter /FlateDecode >> stream H‰ÜWënÛØþ¯§8]`ÑCÀ¢yxWpb'ë6—m¬¢Ý:Å‚’Ž-n(’+R6´²ï°ïØýfÎ!ÅÈRœº(X<÷™of¾™y>N§¾Pbz3R¾ðð?aê»aèÅ"™Dnœz˜®F§/šTÌÞã‰f^ŽN_])qÛŒ<×óöÌGãîó~$¿ÏnµPñD8ÓŸF>4‰çNb\¤nì™{ùŒÏÇé+ŠéôµüÍÇìØ÷œ± ÜXz©˜mÅÕ¶l—˜ñ¥vp“lòFœ½:ÿü·3Ž0^c-r#™;žœ/OÄÕ}Þþ¢×_Ȭ\8㉿ò_ç_Ó?XcÖÆ÷܃é9æX‚ûû{× \%zUÓ³¸Oºøô\_ÎíÔ’oº˜Ž”ÈÅÈb7ˆ•7ME¬€¤€Ža*Özt3z>íÁ¶xŸ¢±C×#D$£wúRí›(M I4qßœ•O!é¼ÍÖ·º]èB·ºù¹xF@¶4p½T‰$Qø,Ï@ªGW£¸_ ýN1\¼ÔõãÇYîßfð¢Â áþáƒË€óôet0†Kt®åùÅë‹é…3ÖòåûwoÌ×Õo_ü8={ÿêbzefþþÝÅ{»ÍÌÿø—‹þômÛ™¹8‚Ëõ"D{Y‡È$ 8䬤߾zgÞÿŒÈoξÿJyC<ñq/3ÀÇÝO¥nÔ»ßéølçuc‹ì}¼øç;xøó«Ý»~ê¦ág|ïÈúóÃôÙ‘\ânh½ÏòtÚÝ¡ëáFºA& »ƒqŒ@^Ož2äâa˜C ÷ùJ7m¶Â”/kà³'â¦Z; v¬\þkV#‰iÑb!Q& Ms°nD^š mÆ“!-Mºa‘òn¨H˜s+—b¹˜ïÛlVèNËô&14 ÓjªÓÌ*ö¢*Û,/õÂRøH¥«„9^qÖ6ûE]™Í_zŠ*¨a†Û eÔü(÷w‘¡z°•›ü€K޲OA\X™01ç÷brLv2xÄ~ÈYwL>Htüµèh†ž¡`±»Å*ûØÛ_N›,»¡@Ö×øªŒä'Ô 3R¼L&7Ep΀´yóv•ÕOu|'âi^6zÝ®¸»Èj^3+}7øÜMx*9¹á§›šŠêiÎk\SI/˜“Ów7!­S^ô%z"Þd5ègÆ ÚPíÂÛ³2»µ'Q<ž}?FË÷ÿ™w=‹g{b5N~|}!Å_ÔMýžÿ“‰÷û¦¯l™öŸø¢f‰_ vÄU§N,—à—XBMü?RŽ©xjC iÈL…}Ä»éÎø±mRI)›îYP61áÔ+£¬6*ucHŸ{1SÍÈ#RùøC\ž q,9ù%²6K5×çyijîÛ‡x…jð€ß¿àÛ'r:¨dIÙ²iæ"j”Lë`׫ҵåÞt©im¶æ£œwve}G{9/óСÄß1~ä‚$>môv‘²‘Pj½ hÇ{@oN¯¤æVGP3æÆ¦ŸS(¸€»Yß²ÉB6uŸ4'ôîV«ãhîÝ’ÂȾ4Ë5óÙü˜m¦Û{æT­K®ÌAmšSwÕböËìÖš/£ÊŽåB>…ÜsäõñÁZ`WzwÉó.ŸkWœ•}£rÔ©LN°E^~$ÎAùC2nÊüçÍGƒ9&ƒ¸ÆxQá*È•—ç{Þƒ×üÝ)î´‰Nˆ±Ã¥WY‘@䢠5„hhbÍd¾ÊÌÇV|Ôœî¶T½„D”¶Þ%'FA²9_n`/Ø4 h}HÅ."äzз š\Ãô»ZzlúP î_¯uSW%7§`† z¼ d8 Ì`ØZSBÎ ±|¤/© Œä>zˆ›d€ùd'áÄ¢G%XÂþês JëhQçàêR­ãZ<ÌF.db¹¢ªêj[Îßðìk¾° 5¤ö|l—Ê”Meó"‡;ý‘<æ°pñ€ž.{õ™]Æûðup[f~kž²„P¨wlhÊ\Ûã7Ž 7âZ:£rŸ%#§æ¼/÷"™]$ÇBSHPÁn¶›g×ý{9ñšû "Iò-’ŒÚ­Õ¦i©ê§JÒt­al»W %/æÞIÿŽ5ksˆÖÒôúV·û¤ R„Õøÿ MH£ 0¥¤O=ßr1ýg‰Vèb endstream endobj 1452 0 obj << /Type /Page /Parent 1723 0 R /Resources 1456 0 R /Contents 1457 0 R /Annots [ 1453 0 R 1454 0 R 1455 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1453 0 obj << /Dest [ 1305 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 318 662 348 676 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1454 0 obj << /Dest [ 1168 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 384 534 425 548 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1455 0 obj << /Dest [ 1168 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 332 206 373 220 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1456 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F4 1669 0 R /F6 1675 0 R /TT2 2104 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1457 0 obj << /Length 3661 /Filter /FlateDecode >> stream H‰ÄWÛnäÆ}Ÿ¯èÍiÊIg!ɬU£—×Ã5Šav|hÕ§¾hœÝž8‚vòDŽeÛ{ã࢒l¬U®òùb±ŠÌ}ŽmsÌ@´5J4ˆˆï–JÕfpR‚Øqk6˜qæ,ÎJ&“š³“Ù{ÁDƒ9yç3 ؽþñƒ u<¨AkJPœ\à0OÛ¯Žfi^Üa¥ùLQêÔ„1سÏh²á/ËéápηªŽeæ$xËÕ}SÀz#ÕS®0Ø%Ún L8JxXÌÊÒ *oœ3LMAXÏ£@¬°ßœ×Ì)ˆµF³vO6s+gqoÛ!`]Þ·¸3–iã›1Bé,BQ< ˆ¦8½úy QN¤ÇÖ2ý˜×ëyb“?lÆ@Žy£ÛƼcØøÁ ßd¶s<ñQ"(–G^.à…L«^€+žÈæÛÙéü7N”­ º1H©|“©G Þ*3'ñ³:!N6¸{b 3ãIÝ‚bý–†JëFºÔ6}žNÞd ÄĘ'v£2'FprK(ulƒ•èÔ„N%å €'iËñ½az“;à® E3ß´B=PŒoW\ª£"Ò;ÀõE„'“y¶Ö’MútTT¶àŠ A¤'ªâp«*.¨­Pßò¾-žë¾R-ÊÞCVöÊ]"{ÍhűÉvDw8í«ö•7KÚú_àÜ %ÙƒzD.MÁFt_­Î‡¼Žgvù“]þ€w®;ª©Tö‰È‹}Î/¡*:ò¢n)¢ _RHG·® ©¤…zÍv$l ÒPJÂÐfÆWMËR‰ “È'í¡'òaz )h_v© Ý*óÆO•ª>h(ÐÛôÙTJäeA>«¦Óœ>M7;Kb^Sù`ëœ%+_Äà™ð¶ºä=¢™r¹eÞòKÓ9±lP(à/-®žp©ú nf*EOÓJ<(ó5W_àµlàÑ·ÀB(/JZúLðVFÇ<*V[U…df­2kyCóhÆ (@q$¸FÅvœ“ó&Ôúµ~Rî÷e>í ‚ôRÀ$aºq“Ê'J·nŠB)v•µ{*™„YÀ W&CyG!$qüÒb›?j" Ù(sŽ-  “E»ØäךGÒID+Ì'94!û¼\N|ï…¯d¬6\7ÌØÀ7“Í27o–,5bb4âÒô)É’"$·_&ÖþH%Ï…§³ö ôÔé9í€Cg|éOó-ï Çœ@MAý/uqõb0°÷¬µš 2J|â« ¬\¹õ°SÕ9e´á¤¥_$)iôrðNqÞ-¼·yN”Á’(‰&‰%¹cšüIþ‚K¹mTO…q©W„–U"&«÷Ì´•ísÉ Ù£ó®¤½™ßy3%š üšn¹=7^fEÀn•gÈøsñ–€ƒËŸ}ÛžÏÝ øáyö&-„ù5ëƒÈ¤ úúÉnçf«fÅ3¦³Å“?|õôæÿÔG†›Àß9Ô±”Ùÿvç˜eø ò e̽dŒ*IbÎüf" ¨ Ò(3NrP}¢ŠÕx¼H=ióš #,KVœÙgÍPC˜F©—¡£™õl݆‹Æïœå ­ª±È0uR |ÿn({×}GíÚoR]_‘¸ "ÌøÝÖþ!«©c@þÒ.Ê4‹©ì!Ŭ>\¨Â Î?˜‰6_0t‡€Þ5=ìûñ¡õN£Q©Xþó;•˾Ãù¨hböŒLãfuN\L- ÓñU¶ç>'”ÜôGt¹fr¯Jg;ÝU«eô™®•tx©æUÜîç/]Òc!vÎ Æ§Þ UÍQÈ=3Ë@(„ŸXZ_ر£ù"/ ,µH×â+Kü¥Ê5ìÌ w"83ú©üšÂپ˜å)£|bh7Úà~6kÖõ8,•å`ʰRäM­³¢¦NÅDfmý°`¦á‰ÅÅL-¨î²¥@š'„“glÕççœ~{jORÙš•µ>¯FþÈ4!Ù:´C"ð1T¿‰rÏ(!Ü~¹,ÜȺi«¬ä¾µIØ ¿ýù‡+vüOF _¡“%(úr,̶05¥R$ó²ß“ë^Ù‹¬}ä}ºD£ Ò†s¡sÍ^¿¾"YþŽ¿%Çü‹õ²ùm¢¸zí_±½TD²­°@«ê©Í±‡*·æBìMŒD 5þÿû¾™Ù5˜uPûùƒàeæÍ¼ß{àý©,s±¯÷\DÚÔgŒ³‘ü_é²ñÒõÝ;²©nö TSm_뵤V|OMT¨f=µÌŠpÝ‹fK³þòxc}æÞ~˜…§Óζ>É%±³ÂØîü¡Ÿ…³Û¸çQÿsÕ¼ p,ì‡üs<•<%ÞqNÄ ¨éД…¸‰Ú¯JÊ;:X1Â/kºÂ&EBtzûÀcÙÜÝ·î*ù†…jƒäÂ&JDÜ›ô)ˆçB"[éDù ~:‡vôl½¤È¦ÂÓH†ò‘Îò§º;Âád$CÆÂ+Ec;A§•b«ž=‡|È®„GòkCþšåúj&Ì ¬ðt£¼®7~Òˆ®™·oKº˜tÇ‘P✗ å²³+Aƒ ¢kÔIú×pl·1ƒMê¥Ü Qµwtü"\îµaÅ´«N‰FwÕî骂N“n>èÊå-é?ä…á³—vDP?>ÿ`Ì™òS endstream endobj 1458 0 obj << /Type /Page /Parent 1724 0 R /Resources 1464 0 R /Contents 1465 0 R /Annots [ 1459 0 R 1460 0 R 1461 0 R 1462 0 R 1463 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1459 0 obj << /Dest [ 1411 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 420 127 455 141 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1460 0 obj << /Dest [ 1446 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 459 127 494 141 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1461 0 obj << /Dest [ 1371 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 113 99 127 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1462 0 obj << /Dest [ 1379 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 103 113 130 127 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1463 0 obj << /Dest [ 1556 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 318 73 332 87 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1464 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /F5 1671 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1465 0 obj << /Length 2797 /Filter /FlateDecode >> stream H‰”WÙrÛÈ}çWô‹jUd €Ëv-ÑMhÉCÂI9bj "A 1jH²ò!ù‡ücrzÁB€ârYD÷íåÞsÏ]úC88 C‹pnÜ"&þáÇñ-æ8¦GÆË<ß´Ix?8=Ë|²Êä“d«tpúiÁÉm60™ir¬Y FÅçó€~‰ncÂÇœá?ܱÉÛ>óLu®ÜcÉíâËõÄîkú ³#Ë4FÜf5}róB/i~‡‹ÆN¢Y’‘ɧ!ùû‘‹ñ2—¹41Lºº’Ås’ÿ+Þoå!6Òµ1 (ù·ükü#üm -–ÖX&ó0Ï1'5x~~f†Í8ÍÄ­±¸GãJ†O“Yt¥§îäIÓpÀIB–ë1ÛãÄ3ß'’6:>ÙǃÍàCX‚as,1ѨÐ5"T¢Wy¦Àoì™ ÿ彆¹dÄÖ Ú³œÎí¯ˆkwsOK¹˜;ÞÝ&G¶©’‡ï«äŒŽu:y,©À³ÂÀ L±[Ÿd^Ó*<¸ƒC[^âùå%×tvu6™!GÒ:½¸ §Ÿ¦så”Ë«P|͆ xc¿G›6a‡6HÊ•6óéç«p*Ô±ÅÅÌÏ~Ì—Ô³—Æ‘ž×£A›°CÇ©iN柦á_¦ß ‚ùsˆ¸N>mÂ}3 }ªGÚ¸ çßÂo_¦mšO?N¾Î´v¼T­ŠÝBIÇêQ²MØ¡¤e¶*ùq6ù´@)sz4{´ûXÞ&ìPЬ³üËüâódþMÝ.ËQßbýù‰Nå9:¬`—ɽXâò’0K£¯¼/BÚ„­9Á ¼ZNhÜᶨ@¹©[*ò¢–vçÅŽí¯ˆ ë̓„- :äÚߢ½r}ÑPÔÛ«f½õ«zëÖ[Q`W»t“ÜÊÎaµB³ƒÖÉYlL³¬ì‡Tí••Ùࢠê%kÝìÔÌ“!,¦¢B7¨c¡Ýóë5Ò/Js¡N*««MŸÕO­>Ûõúœê2l•á€ÁÏTaô€ÈrªFåm†p•ÃØh»Íþܾo°Ês{*^·T²JI{XÕ¾ýqí:båÑî6¹`ÕG·Iª2ĺ¹b1MÏt¢Òéa¨Feujd ÔåkªW–ICUZltS¼Úöq~õ¹Ö ¡Z4ª‹ëBG«ê#ÜF¬£¶Ù¸Ç]òvO8ó‹ýí¬KiOâÛyi»¸Ÿè6ª®ç›Ž"ú9Z—‚èm-…ÖÊ}7 ÆÛã»™ÓV lÇ«ú·6ÏtÈÛ¡…UŸòÿPÒ¶­ƒ.ääù+ÄDg`j”AÌ>#ñ”Ì9j_»¥¢uÖÒîÖ¹cû+âân°÷ãιC¬žcŽÆAÊ2x” Àˆ/3ËsPÛ”¯Ô»ÄokŠ Ô3|<¡È[@–äxZm ŸÆïßÅï3Œ "¯1ŸF7Q†—šÏ\ºI°±4ºÇŒp34ñ»†– ;üÚõ¼xwqõì:Û¥y”¤ñO«7ƹêÇê÷¦'ñ+ž’Vù®ºF\Gy”X@óÝÞp¡_ü¾©ÕHî/Ÿ£￳(%+¥ŒÒÃíÑCá–g¸êŒ‡H< -šß‰§¬ÆÐŠz:R/Ç=¤@\¼V³G-Ûn_ÈþÎHü#Sñø4Ì(aÙúfitÛg•º¡u­Pš#—94Ï÷ÉÍcgbÈ©°’‹—n/Úx¥Š§iºKcõ„í…•sE®óx=ns¤ÿ“W4ì1¥TJ̦­Ò–2õbCò»$#j›ôVùT ¨ØÓŒè ÿƒåwClŽ¥»äXÿf VL³8“âì!^%›Œ=pp±Ã¡2VäÉ –¬Vq–]Ø+ÓdÒ†Qñ)ŒxÌÀ䀯{ÃÑ 8NÔ7NÚ²ü´Õë“ô–\ßgâZ0Xh î–“ê/‰„â†C‰¾FœiSuà“a÷²ººvé,»TW| u/wŠäµ¬!†Á]q¸-˜NVÐs—‚Ü7Ê5Ùìöâc¯Ì[Ré§Už ±í!Ǥëho øtHR\‚xÈWli h,fŽUz%+¥¡¸kñ"‚Ê¡éJý~žf]ØÐû$M²|¯'óä l±'±Z¯£ØÓQ ì·Éw$Ç \Pœ[U^vëùÂ+õò GÇ{¼VáB§îžíZ+—¨Kº¿ó¬M³­f4ŠÏg„N”®‹Ø-u“žbÃkÙBPÃ;ŠZì ª=-¼]j†Å1J2V@E‰±†DÕ9ã °9*Yc”‡C†©R¦ ÜàÊS¸·4X-T B+‘ªˆƒ{4oôXp.‹óLJa±b ®WN3pzþ¾„t'"äH¹0…«Ÿôpoˆ`‹Ó\'o¹d½Å7/Äà¦X0]tq:j+·r›®&·(‹$ɦ– $ºÝ PD~“S¤ø§¯¢Ú:\«G5“ÿošFù¹ É9™@Bu$•fæ”(”g‚**ˆÓ€D.A¦P…PGC4S|RQbQ¥‚>FÆ‹ÖvñVM@{sK‹K@¹¼”b- Öƒ¢TST‰Am–U‰°‚Xç”} ô\qjª&0È M¦)(Ù³G(Ø+ RmÂJ¤Ø1¢d§£`”I‡ذ–'.³§¶ endstream endobj 1466 0 obj << /Type /Page /Parent 1724 0 R /Resources 1470 0 R /Contents 1471 0 R /Annots [ 1467 0 R 1468 0 R 1469 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1467 0 obj << /Dest [ 1556 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 0 72 73 86 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1468 0 obj << /Dest [ 1556 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 757 325 771 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1469 0 obj << /Dest [ 1574 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 274 743 295 757 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1470 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1471 0 obj << /Length 2559 /Filter /FlateDecode >> stream H‰¼WënÛØFÿê)ŠCR¼ÉH ÄŽ³Ù"{i, @ãþ ¨#‹ MjEÒŽû }‡¾cô›9‡ºo²Á‹ÝX<·9s¾™ùfær:x1äÓt1ðòð~Â4pÃЋ)™DnœzcšÞ^\5)åìñ¨É«Á‹ïn|ºkžëy>öäƒQÿù8P?gwšü$ gú¯ÁDM(ñÜI ÁãÔ=#WÎrœ¿¢˜OTÿ 0; Q]V–Od¿ÅN(ÿ`z6¨ {SžU„·ª™&{VÏ)3_#èŸØf†n퇆ï†î˜&š!LB&¡ë…°VÇiBf¸±‹ºI°ãØX³ŽíÙÀeàj‰“:zÙüR­žuÍS[Ük™¬»&ºùû;,Ð<“¹6~š…—Q€³2ó÷øë3¦~6š¦‡Ý«'©ë¥;êù½v¾Q†m³¢DEu.nžlÅZžˆáy6P\yUÞGÌËyÖZlPm½v8õÅ¡V#9Ïv³ ƒRºA)µŠÀl¹QÆè}A#cC!ÞØÈ°2°À”—ºbÞ&´(*ZÚ›⥠ݠXmqh *b׈€±ªLîÀåp݌β‡#Y&™&Í×Ço¢ÎH¯ŸÏ µH0ß®èúM\E!²Î.Å› w¹(‰ÀU_þÒÕ-@•Ñ=««z®/Ρ#®^ÖôÓëË+jàê2UÝ5tß5-µôí†ãqÀX…žŸl¼<2—é&ÏV`–ò²xêrç¿Ä´!üöU‹<Xø¬æoé§<YƒS_ AÖ2¥Í̃ý½àŠK°ÑÇ\’äˆ/x.âÛòÞhK|ªÊvõ‚¬=éVü-üòGÒZð;imb±IÀHÕ]©ù¹ˆ)18XÎŒˆƒ§qžh¢¦K䃹^Àuqõ’ùI#'jÈ%§@ÁŸ­y>¦ósó¼7VE‘ˆß«?™§ «¼:@Ä7¼c¼y׈Yhó0}v„‡ìf¿M ô‘値yþ—Ï&7~*£=”©å=YÃ\ ªÍ4s‰|´`QŸišæÝª,òŒo¿Uõ'¡Žû *¦ªzâ¬B¯/刕PŸ4ý´ÎòRé{Ð-HJªÃV¯MŠHÒ7'iÝ`8ÚW &`ëKRhMÆà â²m•ÍA§ìÞÆÑ$šÔ¾›ÀIò ®ZW™×ÝLœD"1{ÂWB'<Ÿ W12¬56¤¾ÿ&¶ßWnâÆ“¯=<@Öøý7†‡Ï²ü“ĉ¯Jv)äV;\"¹Án­¸m7[Ýœs㪽D‘sgÁÜŸÌdSòïXÉRãp­²¤ÂÌ™!ÉR…’A‘6gÍ‚$Ë+»BvrÉÛe™iphUàn…§ñ‘8§«÷Î(ÁeÃwodS¬¦¯ !_ÚñåQÇoo¹zÙ ÏøÚ—ù#@lÝSî¬×pv„B|F#Aw?”¶IµOlå‘25À­úAŠ¡'® Yº º­ƒp‚Wù_ó*d$äg¢^uÆiëÌî´W  ›ìÄ϶+í{ºsú±îÓí}f'ˆúŒ›”{ÕªFeÉeë=’ +7}Pٌϟ\/7Å–û-jQeŸo¡žë²¸ç0Œ)GIÁ×#¢;c{?®ªš“ø4ä#Ì`n“&íÃtØClë*£Öx͹iÃDDbáÇk)„?s£èBõ¯àâl-Ùž2”žr()K&ÉJ²½<’½2#ÂüÕyk·3¼YÞvŽ”†YiúƒHúÞ°'®?SïÜw˜9F}›ïU»¢vË sDMÍ}rìÊpt š¦ßbŠôeö¶- ½Få¸W¸5’ô¶kF.Ò¸‚ìÆ¥ïÔÙøåXLw´Üd븾u\þ³à M^ò'Jü&‘—/ —Pm†›úvh\Õ1{ ü…™3FÆÚÜñ™ß¸9“ž+RVRV2üù‰Ú“dE´Ë¬EÅ%Û5U,(²2L£–ôJISÀ2£•=p”ä» [ž´EÞ•gt^Ø|µöWŒè~Sç ˆ=Ó¥·[ÛnÍgÌEQ"Nû«“¥ÆT±dÖ°*VMñ𘙨·“ñõûkÊˬû-½“Ÿ¦üñœ½S°Ó1lš¦Ä6M¨¿ÞmûŽgèühëÙ6þfu]jÈyÈÊÎøßD'»‘?² Úé½¾µ Ú)c>ª…ää²éÓ÷Aßœì{v n `¤"=A½j¹Ô/äÅ¡ ÞÝèV(ÑÁ¡ËÈIªÓ–ô¼A@ Ì…M0#Æ-e¦0Ë9!¢/z÷FsRqÔšõŠª.í?¸ßš©k³á½1‰IËK{¸ã`p}ÄÑ'Ó‘p çFäÅ¢2Y t<ÕÍ …Þ\;\t½“rÍ,“¨«énÒáF%R äô>¿ØÌf29#ÄÄõg‘ñŠûÒT½q¤ÌãÆËÌ`P’~~Uf¹^ÖŽøë3×&íÁ.–¯÷I©öÎônæ+ at*œ(cræuBU‚lµZë~•X¡Íú$}Aƒ^ ö[×÷´Ðm¾äÇrô“ݵt<Á…S•ÖŒ)'²Œš§*‡›4ÜDiY?jv˜“ýØqeÃÒ8kß!ýjФ¦·¤u¸>°ƒ|xËjÁ…Þ³ŸêºwЦ%öëéàÿRh— endstream endobj 1472 0 obj << /Type /Page /Parent 1724 0 R /Resources 1474 0 R /Contents 1475 0 R /Annots [ 1473 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1473 0 obj << /Dest [ 1476 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 89 87 130 101 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1474 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1475 0 obj << /Length 1798 /Filter /FlateDecode >> stream H‰ìWËŽãÆÝë+î²´8¬âSƒFó ;­ÒãE•Z´%R!K£é|HþÁÿ˜Eέ*RR·fº ØÉÀ0h±^·îóÜS¯ç“ó¹"IóÕD*Šð‡Ÿ¤Pa’Då³4ÌŠ(¦ùvòâM_PÕÛ=õU3yñþƒ¤»~…Q$±§šL‡ÏÃDüPÞi’yLÁü§ÉÌšQ…³ ‚ã"Ì"'מQö8¥Ÿ¾¿(ÌNULef"*hqOî³ÆŒ:€$Ñ×=½zEÿøO0M1î°–†©¨ƒHTë+úp¨Í¿t·±BbQ6Ë`:ôoû?øqþ׉µØZ£¢0Ã`þsVƒÃáq(EÏ·j¾¢qeˆÏ(T¢òSk+éÝ|"©¦‰J³0Î$ÅyX”Ix’`cRP§'«ÉëùèŒXbKtî£w#öˆ°ÞCŒ£$ŒlHÂ8.rrÃÁ©yš†¹:ñj”^bgô…2 Š0t­Ëns_µÛmPÀg8Ssó2ÈÃ\O×ß© Ònì™%á'íŠcQýí;ïÅ0‰cESÉœ}èîÏÇûSwÿV÷=ç…þ\­KHR¢ÁÈÊ€‘ÅÃD-‹f¡*N,“ƒ`éä¾iSÖ^Rݼ´áÉÅ(ÖçwæC€9ã¬wúzYš²°A˜¶ 8ƒôÍC­¦öÙŸTWÔ´V$\¸öP#1š~f\çNÞÎ< î­(qà“¦U‹ÄƒžÀÍŽvº«Û¥ ÂÔ[Žu÷œŽ‘¦w “Ž‘ŒU¢Î:†´°O×[”x]íí¨ëÛîæ¥k°Óêä¨ßïv­û6”}%»½îHFO#+(ü'òÿ!ÿ„êÝéƒi&€ö¬àpê¨_Æóó<óS$ïí 9R)Xù•Þs+l}f€©ˆ1Ö—õœ{†E%Ïç©Ü8I¤»‰¹ªYäYCzfI&Jy¾6”¤rþò…¨P;ÈðkGÏÐeÐL¶ý w„£lóÎ7 ÚVVkWnvì8žÞr/²‚Jó úãgßJÆßRªÿOÆÿ›"T‹0þ=IU¯wžût#YÚÜ#¨ŽqÒ{N5{>§ò¿›š ú`ó=yɯdâ2£ÈŽáß§Õ¾ bS·õÝÚpo´^ê%Kƒè¥Þ§1)€œR pjèÿJA¥îë»æ×5m•KÄçBDgý:ö0±m— ÄB÷¦t_;àœhÝÀ‰ãW®Ç»d´%ÜüúóÃO7‡# vúë/¿øab@‘zUW¥±$  xåÅÖêµ{…” ©o…~S*p±ž£Å>Àþ|LÛnø5ôˆ+®j 2Û”Øtrj»rs5 YÕ3Sžü0Ú"„ÊâY†g£áÙ{ Júóx$z½)KY_>GD|ÿöõT*ÿ#ÐЇ¿WíŸ~ 6ä E˜n¯¿øªýƒV=¤êóqGýNW(8$@½²ø³eŽ£,Ç‘ÂÕ¢NjŸPnf°æ;æ:G8 'š†]‹ d‚S½¯{À2Þ n Û.z€¢Qò¥·ë…"àäç´?OyûÞa!Ú°¯6^ Î?(êTqjpÖ“+Æ4>[Z¥ü$O<¾áR˜õ›9ýVè`Œ™H÷] ‘ h…Æ`?׳‡ÚÍ“_æÍ™pïÅaiϱI„ß±tŠãÙÛ?|“áPiû‰ER{±Ef‰Î•cׂñÕ’–Æ^îÜoåš@ñ¶íÎ_z¨Íš®ýçå:‘®—nñŸÆ¥ˆÉâHž<ô1€85ù>”øÞön>ùï.ˆzê endstream endobj 1476 0 obj << /Type /Page /Parent 1724 0 R /Resources 1483 0 R /Contents 1484 0 R /Annots [ 1477 0 R 1478 0 R 1479 0 R 1480 0 R 1481 0 R 1482 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1477 0 obj << /Dest [ 1305 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 263 484 292 498 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1478 0 obj << /Dest [ 1305 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 260 471 291 485 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1479 0 obj << /Dest [ 1323 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 315 457 345 471 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1480 0 obj << /Dest [ 656 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 189 403 197 417 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1481 0 obj << /Dest [ 1174 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 444 175 493 189 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1482 0 obj << /Dest [ 1323 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 241 135 271 149 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1483 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1484 0 obj << /Length 3219 /Filter /FlateDecode >> stream H‰¬WënÛÈFÿê)¦? ‹áðNà àXò®ÛlÜ,¶v± ¨QÌ–"½$Ç}¾Cß±?z.ËhÙé…aRœë9ß¹}çýjövµr…«íL¹Â?xù±kû¾Š( ì0v<±ÚÍÞ^4±ÈZãˆ&+go¿»Qâs3slÇQ°&›Í»Ÿ3ùçô³*ò…µúÛ,¡M‰ˆ; á`/¶C‡Ï¥=.mÇ_Aˆ»oå¿\»Ž5WžJ'ë'qóT¶÷0âJmÁI²Éqþ݉øË¿­yß5Ìv sË‘Ùý‰¸yÌÛ躠C<™–kžHñOzZ]ýqF“6®c‡ð±ZÀIðøøh[ž­dƒ·j¼ކ+møéØ®ÌÌÐ=´\Í”ÈÅÌ BÛ •ð";ŽE¨I:ú±¨õl;{¿êÁð,qÑÐuIè|c#ßv|XàÛžG‚?;P£ °#w„ªÓ£ê(Ö ä=•oÁRœ5ºÐY›oÙUôÚäÛ\oš_‹w(êÉS ŽƒõµNy€g ¯€HÛ÷&|–¼_¤EÁvö<;ˆG†F;ºCsYˆ4¤Î*þ±±D$Æ%˜7QîµÀl²NyL#¦ÿÖòee¡à¼f{þ0gòÒ²}=1')2Í~P‘2Ö¤Ã>ëv‚•ŒqPÓ: Ò$œGèÖ²¢¨q'I£´U½Ñõïï¬.W\š“ç*¶ýAs£>:8½ÿŽÌ{i*Ô£œf{.a½pC‘bâPTàV"ߘ]½JàI“˜9Ø­<ÁdU±ß•5ˆNˆÉ3¨IÑd¾àjq"!\€0ã@¸dó5¤ˆ¶T4°ÊÏ]F”û®óL|I‹½¶§ øvý?1Q=&L¦úPHÁý)©a‚@Ä¡€ªbä£k¦ÄJ0‰“@u ÙN3 œà«ñ…É 3èûL¸oJzƒ%#á¬y Hó‚[IÎãB?+6‘D¯›[‰ /˳=°à’ÏŸ«Äö£iMœ¸ÖmGA0ßí,ä èó[q'òªËñŠw$ië½¾³ÐÆ÷ã*£)š@I(Žãó,â%3W,ï¥S ÔÎ1SÙÒÁ‰,0c´ßYZÿ™ B¦™xàÿì|=“Páqç ÉùBv¾gæ üWÍKqJÇ·ÐoîFßÉëÍÝ!k %Ï‚ºìÓžÚW•Å“8°\jáÀìÀðnS€ÍøÉuë¹:ÌGåáN8V_eÐ÷€÷·” ¶ бpäbCu-¥¥6yüâ ì/–goÿ+ñ~Áˆ/Ϣߘٗ]ç…íߘîîñޠâd÷ ó ðMCk•ÏìBÜ‹#ÁŸ‘cð· Ñ…¯Q€ßbUtx†±0¡¬.%üˆ+œ"5dQëtZ ‰e ÃÛš2oµC.˜Òä:íÈæˆZ÷&ìDrc0aÌ&äÄÚ³mÎ8Üç@ÞÊËSâÉѳö-´£p Ùã~ጔ€LÉ–ª%ä§wS©æ´ÿ°ë€èìR_lIË®éb9‚oÈá ÕÂ1Õ‚«'©¨¹HK;ªÊ/K6JÊ}?âŠpŽ­/¿0 ƒœ›®¡ÚB ~ÖlNœv#òzñþ‚J%šC©>lŒŽádº£^iÛ:_ï[(cs¤'ˆ–B¥_&¢&­¬Ê—¯@PŠw¡·é¾hÙ ño¼b¢w‰Ç8ͳֈûE-ZÄýˆ¢~dhEXéU׊t‹öüFò…lmC\ yVZÜ7™ÕÔ^Õ:N dãmrùN¤ü†L(oÍâNye´wcì:¨?6UQA±e–W‹ h.•©~—7èî1ëÛÖçH0¸æ„¤áàM\£'†;¬Sô  ß´‘¯‚[¬îÍ€À¦•–´œlÌø°ê~—Èß`¶v-£]›)hãþÃx•å& Ñ«XHH©Ô¢’´T”#p~R ŠÕ,(!nß7‹“lÔŸ@<žÅñ,ïÕF ·x:—pã ç»3ùcYZˆèdéb€þ©¦âˆ•]xm£Jf'¿Ô DÍÔòTU|›áG¯*ç(ÏU}€ú¶#G¼qOà’•í~Vx¸érV„})•ªü¸Æu×0íd-h¹fM-c?ÕŠ¨LgðüÜ*<È›`Æ’M Ñ‰ÉQó¼• i CfÅž[™x¡ KÍ™O*9ñaì×lÈ·LNƒ)shMNžSF«W“‡¼;¬§•…5F3³iÚ uu}æ8ºÂª!4sù§ È‘Å,TÊ•§À‹ܦõêŠúRØ]á½™/ã•ÏèžshŠIF†ár8…⥕—Î4„«3˜DâålÑùnô.׳pÜh©e“Ÿ»¦Ê;‹"/Ÿ2¸¹º6xC )G.Õ5¢–‰‚ZÏ÷/^J4´‡y"ç<Ô}2¡+ï€êhiÏJWNÆ|“=P­ñ±@‹¥ýÝšÙ)sÓØCH“0!"”®¯$ôC†Ë-ûȆp‹~þ Ç9a±€ ;Š0 ýÊ¥½_ÔqŽ!¹S/1JRñ˜nþÍ2îˆÊçôç†do<š½À'óƺHúX{øï¿·4£Ïø~A!Ý›Ã÷æW~,U¿ËxtÎ{Âÿ 0†8C endstream endobj 1485 0 obj << /Type /Page /Parent 1724 0 R /Resources 1493 0 R /Contents 1494 0 R /Annots [ 1486 0 R 1487 0 R 1488 0 R 1489 0 R 1490 0 R 1491 0 R 1492 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1486 0 obj << /Dest [ 1495 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 215 584 256 598 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1487 0 obj << /Dest [ 1323 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 320 557 350 571 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1488 0 obj << /Dest [ 1323 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 350 463 380 477 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1489 0 obj << /Dest [ 1174 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 196 382 245 396 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1490 0 obj << /Dest [ 1323 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 350 341 380 355 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1491 0 obj << /Dest [ 1476 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 236 301 277 315 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1492 0 obj << /Dest [ 1476 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 158 247 199 261 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1493 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1494 0 obj << /Length 3051 /Filter /FlateDecode >> stream H‰¼WÛnÛÚ}×Wl° H /I†$R¤iZ뜇&} Å-‹-E*eçCúýÇ>tÍÌæE—Ø8§ha@æ¾ÏeÍš™·‹Ñ«Å"P¾Z¬F~ <üáß4 ÜéÔ‹T<Ÿ¹Qâ…j±½z·KÔrÇ{<µ[–£W?Ýúê~7ò\Ïó±g9š´Ÿ‡‘þœÞåÇ3å,þ>šó¡¹Š=wáâ0q#Oîå3§¯YD§¿è˜ž3ñC7Ò^¢îÕícÙ¬1hãà&½ËwêÍOcõ×;“Æ5ÖfîL玧—뱺=äÍwS|I¨Ó2s&s­þÉ¿Î߱ƬM๋̱‡ÃÁuB××;zÕг¸OºøôÜ@/íÔšoz¿ù*W£`¹aä«0v“DE>,© ã4Qµ­Fo1B[¼ckôÖõÈ"š­M­¦®7ņ©†I¬dØ5žÍÜ8XkÖª^ :A^èéGN¹ÕU^îLÝdi“î¾×k5vp6Æâ~‹“ñVÚáÐa}ck:w†š@CÏÉpòè¬{4”G¯2Sܔ⪩淜OàA\=VWßÓíP_¿&­uÞØ.«:Û)§©¸ãùtgD ˜)9…rgoîÉÀ6~+¥/B¾«Ê&ÍK“©¼|ÍŽuw­È[ˆ¸lÒe‹•+–ßÁÈV;„As}*Õ„ÏÃ^«³VÒY+±‚¤¥ZŠ0"Çì9ÄàíéŽÛ?tðjQÝ8Jó"½+ŒZUõëgô{ÙÚúO7oß)D£‚ äa ò'ìäGk¿¡h’š:¿Û7fGCï“ÒO s\•Uùãg{#ø,ú}cVé¾hÄ!Éo|âDŸA`{ýsýkÝäêþJÀ02mv<€Éáܹ®xr_;S𣗭AD-;áw, <ÉSÙoÔÞÞ–)DÓ¦Êr¹õ‘¼;Õ ŒÇ1¦ò²Û²å±ì˪œæp.™Ì":E¬I˜a1“VLžÙÊê2MáYÐ9üÊ¡yé¾;Ÿ‰é'-ѵrÒ›xû¢Ë.X^möC+âmgž¶¦5b&1¦Ý‘ªÒ”µ/ØŠ?2¨âÓiXùÔ¦ÂíÊú› %þÀÊEL†qUÝ?äYºjL 5…qH¦X×͵úªíR°P~òÕQ¹LªUZØå1Ëôᆢ˜?Y>S‡¼(ÔU#¦6ifTú:±¶qß:·=@0 XÜB~\U`ȈF<Ž!ßM† z‡ØÜÅò™_ÍrßäU©*`ƒS˜ãS!…æÚÐÝà`¡cšãa ÔödyïÀØÖ€EµL I{yf÷saQ\Ã\DPXÔK0ò —œ¶ ‡öï3àÑúŒ$ï\öE¥Wâ“ ´—OÃJ½„&ÿ ” l‹tiÖU‘‘Zø4Ôr‹uë\ÜJ¢¹ ¼¯Ž )Ðb‘4ãVŠN¨á¥²ãZÀÓ42½·ØÄ}ܽoÄ5G^ ‰f¬ìÓ³Ö>M‘$¸äu 2Ý7Õ&mr¸£xd£ßðfº´çSÁ6rœmõ rÚXÖùr-¢Ç 9äpCBr³>'°Ë©“tîѸ§ A"ïš–¢N¡âÆéùÞsè1ó€µãçþ„¯\µà¥5×OŸOg Y> ~JÖÙÚ=¢Á\½Ë¿P½e¨¼Aì?R@?¤¤{‰Ä‹œiœC’0¼¬Šý¦Teº1´ÀR=¤ÅûµÌ4ë´a ´ìORˆCÖ$Ô·ïÿBiÂd®º5öΜrÄf[˜‹žôg½ÍïLQ\I½°Ð»§™7x"]ÿ—t5‘R_Ùº›ã…'¾1œ‘ÀŽ ¼<€Ñ¹Çöå²@®F¢²,I*á$…€É3htª#è3=Gý”Z›“ªÇªRTŒ2„󇛱ïA×gµî˜„Øî?[ }Õð [Bß´MÄ6^.&fö„M¿ £¶"6~ɹØrñØî–$j™ö¨ ³ûq‰pàt*øÅ³zÆ–g6ÐN¡ûE•a&µ¢ ÂŒìŸrˆ±ä°ó£ S¯lxy\Ò‰mšË˶ì–ŒV$HôógLGúæhõžléc#q“Û™’ æZµ)R}}9Cœ³ZOM’èÎ¨ÇæGuà,k$×cEi¬bª³YÐü*áÒªÆË[¹¸Zšl/Ÿ—I&ð{’¡Lå^ª|%¤»è&Õ?UÊ{Ér1^æG†ŸYî¦ 60]•Gt+ž%¿“¾‘Þ0ä[6-`6]®ÓR8ÿÞdcµ/ #;íþ«ývr1žWšÄÐt•›"“šñZ2qWLÕž IÐÔ{#2cÇqù+Jà* \{ºq|¢û5oƒi ¿Öè '¦D™É¬oïΆU-YâºóB¥ÜN.ÂðœBÐ/v!tµI·×ÄÒÔ7òS 4Ÿ?\ ™ü(‰úÇôbcK¢ÁV(¿Œ‡ãHêüÚM=\⯎Ü®ªœý7ÝVø?N_‰®2S›±.ôYó`$¦=¦}šj”\A™É G˜kî@l>Ê!ËA>¦î4$<]ÌFÀlÿPtš¢ß’à­øÙØ8ËF~ UuÚ’áý-že£™?ÊF³.E’¦6ÍŽ³QÏ,ͺ H"‚ö³"^XžÅ† E¶ýâ2ˆiìv)}幈_È¿GY¦žP>ì6µ]Û¥=°”!¯ÏÚãê‘Ó¡ïeqaÇT^ËWCú­0Åí¨$æÄ–1p ™ÎíS•,ìí[™“PAco´“»êLt{Ÿú™pèÏeЛ7Twý^ÑÈG»ÕØöBŽ$¶µY0å¼'½fzO±H€±ÙI궘붠­å‰åsÏ=,ÉÈÈ]¶¹cšéíÖ¤Gm=es 3I°c#í=YسRÞë§E "Ónn£Ù×Ô¡€äÆÊ&û‹d}! ³lÐÈ–˜žy@pMÝX— P'„]Ü!2TSŠßA£çébÚÓè°î«¶Ôí¦ÅÅzRæ¶²•X•¸ŸXÕÿ«,=s Š ´ߥ´I·Ì ÿ¦œ,æ4ùÞ}ã…³r 9±œˆޏ¹¹&¿f;åâmZ“ã¥úà†jîÆÉ³@?? ÊåÚ‚«Ì¿Ã”(ÔQwÛÀ6±eö¼ ‰ÅzsVT[¶‚‡%Wç0xI¥ɇ@Ÿð´[ÈÍr§ %5Oò阪PtD˜…sÚA”bÑ"cnÕ©ÜA*Zú³ ¤îMÕí#y±-mý#¯~ä®–EN—Û>O6|Û›^`~õbØ×ž­%^ÔfU›ÝZ­êjÓ^MÅé µ{,—ªªEn»rXK} )_ÔŽ’ƒóL;S?˜Úž§:v€ºòç42{„‰HVÄk ’Xòœ\Ëã-·³z9Õ¿m¦µ¸@§Õ!g¼ƒ Qºä£GY• L`ºb@º-p¨ZéT6&ÈmøpŸÆ÷BÕJ"à©¡ †ÐˆÒD f§}!Ct€€“XÉ0 D¨iü(vƒ)ùeÓWQÖ2‰õ–…^ì‘+áó«ü¾D«“òÜê?„WË‚0¼û{‘ð*&=˜7Oˆ%1!­‰ ñïÝí(ˉ’¦e:vfKн¸éq¡Y/Sg‹óÔ¶:§Ãî¨Ú g~J†%Ô= Šàª=‘ß§ ‚“)Yçw©µâ%õ|˜!1‰ ˜˜Yð¥Çû! F؆ Wœë­ÆA‡ŒÅô• [A¸Ÿ€äóA€œö¸*U Øç•c?†•Cü ©Ë ¦«.(`Ó õëÏ ØÉÓ,1‰JêdာíÂ̛֢ª¦S/,ŸÐ«‚V•bV=uÔ±‘nœ“÷:èÛ‹V§6â ›à<Ü:t!¹YÐøxFnßœgܨ© endstream endobj 1495 0 obj << /Type /Page /Parent 1724 0 R /Resources 1499 0 R /Contents 1500 0 R /Annots [ 1496 0 R 1497 0 R 1498 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1496 0 obj << /Dest [ 1485 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 448 743 489 757 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1497 0 obj << /Dest [ 1485 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 236 141 277 155 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1498 0 obj << /Dest [ 1323 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 410 127 439 141 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1499 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1500 0 obj << /Length 2796 /Filter /FlateDecode >> stream H‰”WÛŽÛÈE^õAšÁˆf“¥1Œ¼ëõÂAÖëìh_â ŠêqM‘Z^,+’È?æ!§ªš’F3;»ðˆlvWUw:uú»Åèùb“¥ÅíÈÆáüLæq8™D)Í.§a:ZlFÏ¿oç”·2'¢6¯Fϼ¶t׎¢0Š,æä£ñð¸™÷Ù#;K)Xü6º”E—4‹Âˆ“y˜FjWÖIJœŸ¦)¯þ`þctGÁØ&aj¢9-÷t½¯º5FbãX2mÑÒ«/èïÿ ÆS¼7ø6 §¦"“¯/èzWtÿrM)F“U«`|ièßò7øÇâ/#Ù±ì&ŽÂ/‹×“v»]$¡5-{uì¦á2ÄcÆ&÷Ck±ôÃbd© Q#§wÌÌp~³4 ñO—ð™ÇÇã5ü·Á1ÞC/©¸«ê&˜„3ã2â.ïÜ*¯ûª °™¹ Æ1‰Š6à³$ýq:Ú]΀®ÿöW¬ü%'áÜÔ»ïë>°œˆ*°8ˆŽnLÕo–N]Q-Þõ¥–;oû~œÚ¬¢_ßã¸gæõ«…Lú=OyÛ·ö[“­Ì ñó.à¯øe¤uj:ŒÌMÖ¹«º›€w„/²ówÁX"öFàq Ë`j¼å—EÅkœ¾v«¬Ëøý÷Rm\!Ü½ì·øÀ‡ÇfS®p m`±øCàŠÏÈ›Þ!qkq¥Qì.ð!…Ñå!›üÈÙÜw뎖Ž*çVˆ&Íní*ê·µH4ü;I™n2l_‡(ãษØlKÌð¼AÈoÅ Èü´Sµ_²¢­>Õ¹[õƒÝºÈפaUu÷ Kýd(k~â}´®cýÂõ:añþ˜X¤¼n ¢Ü‡j5ñ5 a&¢I˜$óéëPélÎâJ‰ìñ­:×lØy0—×Ë.+ªb%¯YÀ%}Ûáhͦ¨d´uMwuá§bÄšª¬åKž•ŪE¶/üÖÃI’ļÿIdgÇ8ÛÄË•ë\³)à(tŪfW©É;Ú•¾ºÏD–n·./Ø£ŒljùY¹SçÓ¹8·Q¢EÂFôëz™ÝTí`‰ŸX-kÝEÞ ’“š­Lê´L®^Ì" NM½ü ©‘É:ðöõÓ»Zò|ºÉ*´,›&Ò;?ï?CN§—– ò˜S;¦?ËïëŠSˆÕ aå™9˜õm-Qz^ïôÒ×,u;7wuÕXÖŸÁz~HêÜúÊ5cú•8°»:}Ç[Öué`çSV «&¨²s[74@FÑ  Ö\œ Ørâ2¦e 3|¹7ÁÅãsl‘´ ƒš¤ß{×ì—jz@p.¶ÐŒNjüXâãÓ/@)w®‘¶ÀÀv8ëKÃÀþrdÏ¥®: =«ððŒ`ëY_Ÿ7 XfÿFÈ»Z¥ÏO‡ZÙÔ¨3Gñ96GnÊ›bÛ‘9–†˜Ñ‹ŠÞ kÅægúäš¶¨+ª«rþòEÈ$o6=Þ+e¿®kŠeß¹V9c¹? œ™è> IÇW*äƒyín³¾D33{¿xÚ…ÅÄÔ—Ê€4nÜ,‚„›#”÷É0™`x€¿€4tZÆ-<6¥ŸóhÆ‘.§à Dj)_Ûl½ZÙ?¢ ´NDnŠ¥Ñ£iº=ú@W‹R}lûöÈUÖs·³,êx·f-¸T¤¸¶*­°Ì¥è¢K@þN"‘¥úÁI3Ïk}#º>Yñ0_>Ñ/ÔÄwY`Åo!¶‘¾rA+'Bp:öjÅq‚£ºµ—€—Ù=YO½]©¾¯îÙøÜ‘Þ"^\ÆRBªã½ÀG·Ò ïd‚h𓻟×L„h0Y…®¿éO¿±¢u<{ƒßÔ¬>xHðÅÁ­±³š7Ë—4næ¤ÝÀpá]ˆ7z‹ŽÔ`ëîù›¢qË¢Yqù¹ÉòÒñå£oy}Fw®rM1pÁß—9æHåVçxzNvbÔ+ ;P_µª7jötTå†57\0É¿J †,±A¾tòqž°8=›(:ù»N†k®.™¬ïêMÖž?ÁAÿÝ{„³ê_oEîsòRb;u>þ2^?˜¼oÚ ¹uk”+ûDRårrÈKÆ"d—5«vÈ‚\Xiúéš/ .ð?µT¬‹¢ÛC?•ýuŽ“¼aÛs)ýÓž-ezíY°¢©Öÿ,ª¼ñW¿þŸÒ;W쉺ùµȺ¾¹ÒÚzƒ,¹öcWo‡l¹–Ê⣣7Eé6ÙGˆÜ '‡ãjè}S¡rKÚ6õ'l˜Y&BkGè'ÔöÛ-\@zÈhóxOJޏKNëÀc_²™H­rõV«¬)—ò^¥©¹ÐTÂØ1AäQÈãzW䆥Ítnô/ÓMb–åžxM)oˆ—·ºSXs©i)òŒZn¹!½ øôÍ{`¦Ç §¤óÉ»Ù{+üi+Ó¹·!ö©÷öxO{ØhÎôrÀ@Ë <é¹To;ȸ–ò¬â:AdC‚2¤¹ìù+BÌ:Ðû–ÛÄA²I.o{ï·6ê ÔW1ÆILŒ`ª2bÂå·®Y402nŒŸzüœm¶ÜžÂ‡ÛÊÉD¥`¶ïÙC Æ‘'3®bÿé¶.Ëz§/ƒv|㥣øŒÓ³pþ ÒôÍÄÏ '^^š3ÍjC\¢£JNT®¾dʘ äéÉx3¸;Ë § W3E{ÚÉ“·-Ú(t{A–ÒWë:‚|ÀMã˜Òs$óÛ'(³d¸_ñ¥æáá#äß±I(c‰àkJW«å›Û(7Pϧº ’n<ˆÞ¥¼ þù”ªàû: ¼2ľõWšb~_'0úÔ#k—J­a¯Ž/¥Ó²øó±2óÑi®2Î nòÖ÷ÔoèofØn‹"°`ÔÄÄÜîæ&ŒAW)ôšd!¯«aUÁß§¦"o{°—ܳ׷½ŸÏõëéí;>vE¹c`H´‡9ÒÏÃZ×{/_#üܪÍK´5+DQÕ͆•y:Hüi[f¹Î_×åÊAŒÈWö$OèÛû·ØKX§Bõ ‘{%B-©ÁïR§“µRöNŸQ¡öý–E£nä$ Ã*ÆëëS¢hз™oX¶ðõÎßÔ7–0¢a&0Aö%i/lƒ:Z3¾5»‡¾?ʵ.ÝzbN¤ [ððÿ®±b4‚s2K€Å?´ýŒ]_`…eÒâ3 ¸ŒöLÖ:Ø«ôÞW´RÖ:¡¨äfœÀ¬p¡Ëþ±ŒüÒœp-T^t(.J mì PJ‡%: PmU”šîZ‚+X gòóPZš¦€¥eæäWÓjd–($«Ì‚¢LpãH\¼»†p(@¹ endstream endobj 1501 0 obj << /Type /Page /Parent 1724 0 R /Resources 1503 0 R /Contents 1504 0 R /Annots [ 1502 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1502 0 obj << /Dest [ 1485 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 449 757 490 771 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1503 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1504 0 obj << /Length 4104 /Filter /FlateDecode >> stream H‰¬WÛŽÛÈE^õ ?5ƒMRI†{Ç^Lb¯€ â ŠjIŒ©æ˜—+²ÿÌCNU5EÍŒv,b#²Ù]]—S§ª^/'Ï—ËH…j¹™„‘ ð?qùq$*]Ìý$ fj¹Ÿ<ÿ¡ÍTÑòž@µ…<ÿñ:TÛvøAbO1™÷ý1ߦ©ò–ÿ˜,øÐB¥¿H x–ùI rùLÄÇéižÐéÏú_V§QàMÙŸè S«ƒº>Øn‡•H’t[¶êÕêoÿö¦s¼7ø6÷çºô]ì.Ôõ}ÙýÓ4 ™éÜ®½éB«_ø¯÷÷åŸ&l1[~‚—å%ÖXƒûû{ß›ù¡néVC×B4®ôñø‘.ÜÒŽ%½YNBUªI4OüYªYêg™JBxRÁÆ8S™l&¯—GgÌBl zcôn@Ñì½çoŸ„hpd:_ø‹þƒlŽe3ît9)ËeæÄøA,_$` ºê³~ANŒá<¬&Ú¶òjš®1]×fðŰZ®_²Õ#|R>sþ#™áˆ‡Pü©ŠÜª•Q­7÷3p éNuµzv0²øL•_«¥uÛ/Œ¡M·Î»\–¾U/ŒÎ‹ð)ïÌÞØN©íÎw‘x†É¯OYÓ)+8 }§(DG%é‘”„¡¸9–XkîÕÕ¥*­Ê!H>ôþPW’˜BèêXZ(í¶2ª©ï/Ô¦ld­SE]ñÉŒ$€½½ñ|µäÏ;à¸uW;OõNþ¦¯È1¥}p_Ó©a¹Ÿ:4“}Ñoá¶bg™5 'gAWØvêϺñÈãØr+OuaÖ½[Tî×EÏ-[/$L@Ôà´ª.r/Åb¥® ;Ô—jß½mXìâRnVÃ/yH?EH'÷ôæBàQ¯N ººpÍKKÊTåšÄ&ú›Gè†JyW¶î”ùnXÛ‚ÿö¼NòŒ‰ú‹Å‘$ aŠG9JT/H¯(áäûY Ʋ2F´k(gõÀþð}_=NÇ ´0¦c0Òs0sé¸ï)—ô¸t×y§¾õ¦9ÀÍy§8ñmK9bZSwã PÝï­é”/}‘t¼8•‹‹Ú’Z` œéœP^.‘H”îªËW¸á«·@j˜ƒºã‡a_o({.Í­†Ú°»&¡µe¹­é:~Ý\øÆu¾éLSZÁÎòN¯p¨=K’œ÷ò‚Ñyâ¼W¾ã—² è)“VfS7FÕbùj]{\8µ¬ºúéúͧ¥¯~ª;Cnõ|ë8j 醲°Ïeð9@ïàž8¿ËËŠÝõ [ ô§?×µ0j•ËnÊq\,üê9!.áÌDæÕ}~pÏâ¼16ëIò³á3s` XBë™®`Úì ]N‹Ýá°T8lŽ{¿RåúFSy™ë~™kçõêã•Úô¶èÊÚúréIžùóÿC–E.ËÖ¡ó(¸{["†ÓAÊC7O“+NO„D€\QíÇA)Q}Dn€¹ÍG„hª s}G F†ß Hž\y½Ó)KXK)]YHG~¥ÏS.ýp ß¹7wÎ]Ãû›Úî~í¨™¡b¢®6Ž{‡Û/܇ދu9|â¨åÁ *©ÝÜÉÁ‡J ü¿=ä‡lx&ÞS^µÓ#UÈ…Žøè!¹“ „Á­TS[j j[ð§—u||rð…fz[Zë â` hݶ×*À­)˜0(uò³Ù&c=umªí÷€ •´’‹$"¿)LDR¹|b±w9(Km€þdr·JÕWs3¾úóðxn•Uy4E-k2/ÑHÆXµ5Öi–CÍTu`óJ[¸½Ô —NÊo¥6¬]™= 1ã±Iáþ„˜,/ r'Ä­Mûµ«oÑø*‡“Õý®,v Ff«]~çeRâ‰PMn›úÔyÖëG‹ÏzoŠ]nIc½gW…ì*ðžQÌÄvzÌ]¥x±·%èÜ9]Sû•ÚÌæŠH€ÀÆm'vT@½$Jâ‹Pñz*9•Gü¶frW›8öÎ<Ç‘çËaU~5êÙõ›w^H¾xóÃÒ£[½õ×}u‰öí§ïÕå+Y%ÁüâÞ^óÏ»7Ï|õaCª5-¯0¯gúbh± ð¾¬*öþ}Ý|E<ŒÔɳe'ÕŒEÍ!’Tg`Å5¢˜ZAÖžª œE "oo«RöåÄßh@a]nMÝ·ÕáWé<}Ô]ýÞ¡fvÒ>!’\ö@æ{÷tvAYKOf—ÑúÐY¯8;|f˜fhÃ)•¹Ë1}°?_pBÂû‘=C-áZ@]rJÕä(M~œ Nšã˜Kôƒ!€79ÑÔ ËÊ-‹3EI éƒHQŽº¦lÓ뎡¢²G;Й-댄©pƒ¶«û2µí)Ã<Òn³4üßQ¬Ö¤?-»ø‹lrM†ˆ‘æÃÓƒo2IÄì£H žÆ¦œ·ôÝÐ2>†,¢\1ò#Øãnÿ´û&ÆcE$^â(b[YtŸ¨_ãÖ’õR/öGÉ$B=i*,“QOÊ>Û4õž·žRÆ* UDDJŠ®¨{tð Øû3rI.OJ~:¨òæ´¸€ƒ™úòc!»º”Ý>ULسä7š6Ôà¦X;±¥ûí©óIÝê‘Û1º|ݹ³D¶FCÿšseÖ{ÐDßÕSªG N5Çecràá‘=w![î¡`Õ…ZõèL¡Q%¬J¡òÏHxŒ“£÷ÃQ£ÐiDYñ€ Ñwe®>\­.ô®<Ýè· é²2ûü+§ ðý‘×ä¥Vs? JÄÉ1w«@p¾¿­xPù¹äÒ’r±™KœÃs—Ã’Á3Ô®Üî8‚ 9Êý¹ø{¦üˆdiñÄÓŒØö¹(r2`mëú¹·äi’¸^V«Œ½+M–ƒÁñ:u‘ì?ÖX‡þùÐ_ã‰Nä›eóJnG¬Ån@x€{ñ`\~>gžÎ¯ŒÜ®qa²äpb\A>Œ-ž±[AO" Avm&Ñ j¯¥™¯Å8•Ó8qžPc0‚zåO«ú$ÇJ¬ÊîÁ{µ‘l§Vh1ÄÛœØCâIá˜`(|{,‘Pr–rƒ¡…x…7Þ;ge˜¾Š¼w·S÷ tñ2¢gŽÖž¸v-\üÄËy4¨qö>¤ðÒAvP»ýàÄu|ˆ;bk:®)`:þ‰õSK·lŸ¨Áiµ;ß5ŽƒEè n²b”z¬„<õž™ -U¨Ñly4¶Ò3FzFÓ(@oqj¦? x>È!nÈHŸþâž_» ( ýŒ(›/â1f6N1á1ã*Eß¿q–TTSx׎¹›J¬Ð+ÏÄ{‰ %dâ!5îx4Í‘Âùº|Uý û…£WB‡TâNÖš”¨µ õòGa‘¾Ÿ¿Qh)QC[öÕÁ:|6ËM '•"“ˆÇCß+j†‡UùQòCL£ Ù$a6‰™Mþ·9ý°;›éss©I çè(éÈ t¨qÕÚÍ.ù–'MHH¸Ž#þ;‘jʃj{]8ª@ï#[ˆÑ¤k«,Ñט–þ$y¶‰ükzfÙÞæj¥Ã ô›v2ÈG˜5‡¹¶ |Ô1{5SzR£UºFòr˜—Æ·»ÛïCy(hâ"NÔ€(îÔM3DŒÉBÄFó!ØðÐð‡Qü+†Ç¤K ÖÑ]iåj»pÛÉè8ÙªM¤¢;¨€Uó„nØ_ñcÙ»¡V;0­±„×,ÂE¼Ž‹ƒH)\&xÎöP› ór*zd Lö6a&2/ƒ+¤je¼’ðVukå©Is$i$j@ àõ\Í_]‹­|4éÃRhš–æ¿a¡ãÁ´æå²«lÝVŽ5šØu:AÕá°·)h)‰w":zÜèè:å–N9hA±LdLááqA– šïf8Úe ùh¾Ó6F)É™.`ÕШW0ÜÚhSiiø«áN`WY|`,&ÇÈ4‚€ñ0˜–43…Ç‚Ã]îòÈKœODz.EßÈõ´Í½† Ÿ,5m¯6Àw£'49fš HcLÞsoПj™ÒGÄH"$øì‘è—h¨œ©ix]ÌÊ´-D”2Ãj¹c“¨Úg(võGC»}ÑG‡õÑ¡)®¹× 0i»‘!×—=¡0`)ý«°{&9ÅG¦à&72E=§-bÝå¥kÒמwù†h>nKs)3\=Ô4ŒÀÏÝFFI·D {›}Œ~IR]R]z=ÂyÜØeùÖTÀtÄsÄXÛ{»º5‰ë<˜<•ä²$%sÍ#A±Õ_I|7 ]h7‘ìf±ä=~€Þc_:qFú¨\{þ6b›Àjz|"jÑP{=Û–çvVôTU˜Ì—ãÆ›Y¼-^CíMí£ï|]Z|ŽI®t¡$ÇT«ÝšÆ¨e¨ŸiþuÊ/«²ÍÔ6¤q5ÝT“©ß»8ã¾*_£¯”Æ ¡ºÝ9ÌØ%-Ópù-ßAVÆ¿éžcêQXòè ¨dÝô Ve.¬(z´Mǰükê/%µz¹]ÓŸÝ ?·>-m„AËk³nƒ2 7¤…CZä¶DÛ­Ñájá“úûh7â»Ñœ.7'úKJì3`´œ”fM©¾5¿_£ûª‰tY©øÕìOH$ÎôðùÞ¸ÿç“q¯xÚy0Á ø›N•"”® ²$<ƒ> ^Joì²â½ÖUt>âˆWËâו¿zÑ -gó«`<²l<&?ögü¦®V—£ž_E]=Š{Véí]~!Ü8ÞA¢6ŽpOWwÅßͯP ÿ𣩾±} N%!?f,@ó ‚Cß²Ì7on?Ìîæ·óòüöž;¡‘³I@§é“)­›õÄ»oæaÐõåfh‰²f»µ æa_·7i½Q.˜DϬ{ù…py¶ïáóLÁzâHKƒfªM, 1\K„‘œ¢Ž¡æÔ áØ›°»¥¹Ó§2^7`ßE }Öè£q…|7ƒ°¶Ý°%D».P‹uÌ£;+˜.bqúe‘×ÀŒv™êE±Ë޳»›ôIе¦#Ïé­Fo”;A¢g:¡{ù…pãlË=Ó =ñN€.ö|rŸÉÇÍ×/Ÿ[º£3€íŽvÞ]éi1ïfßç?ß¹›¿}?ÿùqöã"v}xѾœõŨZë¯UçÒ³A}fñ?S¦žð{UŸ¿ endstream endobj 1505 0 obj << /Type /Page /Parent 1724 0 R /Resources 1511 0 R /Contents 1512 0 R /Annots [ 1506 0 R 1507 0 R 1508 0 R 1509 0 R 1510 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1506 0 obj << /Dest [ 1174 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 152 563 202 577 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1507 0 obj << /Dest [ 779 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 523 94 537 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1508 0 obj << /Dest [ 1174 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 260 482 309 496 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1509 0 obj << /Dest [ 1513 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 421 262 462 276 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1510 0 obj << /Dest [ 1513 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 89 138 130 152 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1511 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1512 0 obj << /Length 3971 /Filter /FlateDecode >> stream H‰¬WmoÛÈF¿êW ·D-š¤(Š2 I.9\›K®µ ôŠZ[¬ù¢ˆTÝéèì‡>3³”dENú¡œÅÙ×gf_γYD!ÍîaDþá'N#?Žƒ„&Ó±Ÿ¤ÁˆfÕàâU›RÞÊž€Ú¼\üpÒ};ü ±' ûÏÇù9»·NRòfÿLåД&?M x”úI råL$Çùkœðéæß¨Ã(ð†áÈOLÒ|K7Ûº[‚ëA’i‹–^üpNÿ7c½oìMá&_žÓÍcÑýf×¥™¬^xé¡É_ï³?Äb±& ü‹Ù÷ ‰¾7òCÓò­–¯…h\éã3ð#“;ÒR$½ž B*h”„4šøiJIOlŒSZÛÁÝàålçŒQˆ-ÁSoì½°GŒxo™Þ“$ðñ¿Ñ= C; ¿x4Øy4©=¯?gÕª´t׬éMQÚ*{ðR?†+‡#?5kúyÝЭ©›zXmʮشv}Ne–?´´‚gljVvM?~O•Í—Y]´U{ë©#/Þ„.ü1«+sõ§¹ZØÎ®«¢¶Å¢©s{½µíÕÅ1‘M'Ó‘¤!Mâ¿$Þ;ðá7¹ãdÇ£)|È©ÅÏÿ{w÷ˆÓE˜!nˆŸd#øûX¦©‹eˆðÇË檙wYQ—Mž•Å¢ýX^ß¼~ûúÕ þóÓ‹¿ÝšWïßÍ^¼šýú§×¿Üz•óæ/ïêó°×1âz-Ø+GJ>Ã?­e0†P—q7¿¼{õ«Sãæêâ •¢ˆšŒ¿¢ÆiöI-’)Ò+rZ\!ojû¹+×a ÿ]]ìIOuHÒ‰=Ìg™œGÊ|>Nþ:·wLúiü•,z†ÿR`;võ†4ÅŠýÑ(.{œHâ À„hAëa!VX„úÂ)°`dèªÊV×—tóç·Ô®„dóâ®È•{WXù 2ü.¨Êd½rA™¢¾§;›u›µ7áó­ˆÙ,=n4;5¡Á$:èa¯e¨J¾jjN1» ¢¾ø˜X׿ ¢ð]GaaaäðêÎÎ [.ØÊsºÊÖ úäo¹€Ãíõ±¾C‘Ìð:ÚÃkºócêTÌjÊUMÕpü ‘ŽuÓ-Ùoœ´§.Þãz(ü`^pÇ‹M×­‹ù¦³-/CsytcìÇ“ýa¼oÒ.úä¡ÇÆAÀ½=Z/œ•ÂÃz¡¢Ÿâ®ü’ÖXN¹cDØ”-æe3×Ësz°[·>ŽùÞµ×ÞìÞ^§-—<Ú{Z¼ítæOÖyUnZj»ŒûÖØÔ»záV빯g.©F¿Å1*{Ž2º³k‹†ÓžS·…µ,CáÈœSÕ(amñþvëMËùÄt]²µ¶ vñ9È ±. ý67IXz”HþHJ8Þj¬FÏàæ£Á­,¨ËîÉêw—ÍKG^:eTõÍm÷hmM°  ×c¿±¨¬$ŽÙHB ”ì?Œ%ÆÉXØC¶ _9*ö÷×v×ßµ^(‡¸×¢ä­÷ÔiûïÍ œ¹<`Ák˜ØpÛKâ‹1ü‘K‹¬ó0JH"ÓvÍÚ~×,ÌʈýÁqb cÂ"ÙCSž}ÈÈ·=<î¡&tPsI å(>~]pñ¹øxAYY6Þ0åÑQôg%»:Í–‘R[bF‚±ý6öèÄd⾉©°ByÔW£iDc-º¬ŠériM]n%„ˆÃ ®æ\Ÿ‘”¯˜8ËŽZÖxײ\‘Ý­›J1zÆ‚"ú;w¿­õéÇŽª´—J‡F›œò n™€rk”;’ݶb£nͦݸ=%”wèæµ~`Àå "8š· ð»åÀ5¦‰ºEz9!xz¡÷AÒÉ,žî³xª–6µ•Þ¥¾Ì#áe¸yqB ïd¤Ì›rSÕ>qè }¤¡G™õ¯YUÔ“Yë‚ ÓˬÊÍxF)åž=†¡ˆ$ð±ùÜ Æ½ o=®Þ÷º8‰”ájB5w84•ø‡ÿVfR*ß™˜]…/Š!%•—è5ë“ ý}úk]ŠMêªÑsœµ‰¦p*I ô*Kê™C6I/U…ê{§‰‡ &éo×tÚ$\£[NƒU8ÚûÂMxYùÈ›-ú‘ 8[#óqS⊠rHùŽ÷/EvB¼v7rLþN¸\W(ÝéT¥F·“áÆZÃW[‹FÂù‰Ô“XJ§Ï¹A"6«”qÙu )Y­¤ Stƒ 2¤ê[ƒns S5xÔ‡Z[Ÿnš#¸SÌcqgNF¶žŒÝ—y¬hͱÿXžÑÊEþ“xD2bS³¥°Ñ±ÔñÙB Q“È•Y¢eòœÀž 5JP?£|É”ØlꇃÔì–·*êÜÉZ*Ž]qŽO{bÕèÞ­+'«jfô‘›'»Ç ²ùyqt+ÊHËYñ†ðpüǦÑE•adõß'SrØþÑï‡P JDsˆ]ƒ”‡ ’zÎ…91Ò-cé–xä$QÜGÝH᥂‰RÙÏ6ÇÐg4Qæèɲ͹Xóå6¨IR@:~¹~}Nó «Ä}R  ÑÌ1¾m5ÐF:z¾DÈ1ÏRÁ#~*CmhöfâTnL÷ƒ\‘$wKסQ鎰‹÷á!eSûOgî~ÿÏñEç/sÆ/)öÆÙÓ÷Q̯£à+„KXÖ?*q`?ÈwÚm7%­äàÞx»&7]“¦ ^ »QJ¦{®N.ÄÝ#ãHš>ð®x°^j¶ô)+•´‘jdæŒ1òàŠ\ ã/^~¡Ö |a(ð|¹°+n·uÇòqW]jtkyfQRŠÍý"L5¸^¼­=ƒßSá Fæ3mîmy±r¤>ÛíZœË]¿÷B&½óà”Òê˜\?ÞIu"OÎ.É~vIÔl)®;ë†?1‹!,é?l"[€jh0KÍÊŒ&&K5»ª»CãÎJ–OwÅÐ'œ<X= ^»t·¥Î*nGÿëXÂG\G;îðTtO µT>¿¼fBçi Ã§ÎÆ>…{̲¬uËâÔ ó_Ϋ­7m$ ¿çWŒ*9+BmÇ»J"¢bºÅRUm¥È³AÌ·]ö}ÿ÷žÛ_ÆÐÝ.>ž93çò}ßÁ˰GÒÃ(æb ÅV=1økù# ŸÈp™0mù´e˜ô¨3°'@öf¬v¿½êD½¹‡3ž'ÏéZf½³h×QGP^¦{5˜ ¬‘RÐèEú'Ñ©<žÑ˜€ºÊk?е`íCfÛRò—ã€ÞšÐ’g¸&–0Ô±Z$ø5Ý ”ó:æà÷’DÝÈ«üIp œ|Þ¡ö€ÖZsí¦Ý³\þ²)Ä_/1æÍòà¬ÊoÑ ÂÅ,“H '1›]ºÏb¨Ecú”CÁ\ôŠTù<£|ðÞ)u”hr@×Õ÷Õ‚³®°G£ÌjËnÿ0¢Ã í0å?r†jöø:¹6qôd¶Äi°K-}…ÈÄ{Ö~/ÏøåYL½šq%XGÆ%b­‹wŒ£ÇîFÅ›¤ÒAªÄ‹€FUéøãKü7 ÅЇ,GXÍ}‚Ä3F#´)1vĶ— JºôC]ú!•¾G¥ßVüzJ®@KA `e-ØÑJ“í*quÉ“ÿ_¼!øÞÚÀV¡ @7ùÀ® ÕæÛ©M!R¿[7›xwyåÛ¶…˜~Ûú8žFÓ?Ù'ËdJ4y-?Ï;xs0™Zät]×;pÀ øíxº¢Ï}r±Dýa4ãGŸÇ£O#þ© ÷£/·o^Zoï*isz!®!’ÍVLžX›ó×°üŒYûÂcì 9ìêê;Ä÷(•0ÔðÕ³¹æˆ@rJhýÒ¤£5J¸%€È†”¤îˆH „Ð#?™‘vV,œSR¨o‘@úYÏŸAðN(ÅY3·‰`zZÁ“"ΙÔ$Ó `ÂZeHÆ=‹Iˆ¸‡È ‡;”„xy°kÿ¬J ¶M„«\5Ø8êæ½˜Û¨¦èî5Á°"î/­¸ÊÿƒL>*„QCÅ[a̘–Kɲ‚ìe9Éú5£­ØíÔG¨¤?Œê¡žjŠ:"5M˜EÂé§o™hIbp?)9u°d» <”Ï 5õŽ‹Kú\!Å:Ážüzy½˜¶¼zÇÀŒîò×ÕßÉrŸnn[ý("0=D³V­×Ýnc³™MÔå`:Ñↅ§l¹?ïD7˜K­] ”íwiìŠÈ€­(fJý£Ò ¥w³Ýr…d“úÛ½‚µ1Ç+aŒ[9¦ÙŒÇ¬¦3 ;=ôÈÛÿÉ­çÖ73»õC|0 5@ÿG <7¬¹0Æ»ÆF¨¼I’ã%G©"ر±" ¦‚ÝèÀä¹›·ƒ>Ð@ò4ÙêÈÖŒuÆ¥'â³×+Ü«vf뿆$ö˜ endstream endobj 1513 0 obj << /Type /Page /Parent 1724 0 R /Resources 1522 0 R /Contents 1523 0 R /Annots [ 1514 0 R 1515 0 R 1516 0 R 1517 0 R 1518 0 R 1519 0 R 1520 0 R 1521 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1514 0 obj << /Dest [ 779 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 116 502 138 516 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1515 0 obj << /Dest [ 1539 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 483 421 525 435 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1516 0 obj << /Dest [ 1539 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 92 407 133 421 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1517 0 obj << /Dest [ 1546 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 480 407 521 421 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1518 0 obj << /Dest [ 1476 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 402 259 444 273 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1519 0 obj << /Dest [ 1524 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 149 232 163 246 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1520 0 obj << /Dest [ 1546 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 260 218 302 232 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1521 0 obj << /Dest [ 1524 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 387 178 400 192 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1522 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1523 0 obj << /Length 3479 /Filter /FlateDecode >> stream H‰¼WÛŽÛÈE^õ} i^Ä‹Œ€±7^l`7±€±óÐCµ,fyÑ’ÔÈò‡äòyÈ©ª&Å‘Æö[0€†lö¥.§N~³Y¼Úl"ªÍnF*Àþ-óÈ_.ƒTe«ÄOó V›zñêmŸ«¢ç9ê‹fñê§÷¡úÔ/?BÌ)ÞøxZ8¿êOF…ÙJ¹›-V¼h¥²À_¥Ø8Îý4}yMÄËé)Iiõç?F½(p½0öS'ÈÕãY½?7Ã#‘c\ìäôe¯~ºSÿø¯ë%xïð-ñ§t§Øß©÷§røbºŠ7‰Ýl]oå¨ó¯ûÏÍŸì1{~Š—Íc N§“ïÆ~èôtª¡c±5Žôñø‘SØ¡=ïô§Í"T¥ZDIêÇi¨âÌÏs•†ˆ¤‚Ë\uf±[¼ÙLÁˆCL žGãÝ€"âpô£¥ÍÑÒ–˜°ôã8Ï”¼ŽAÍ’ÄÏ¢YTƒH<•ð±Ì#u¯»NŸ×¯ÕÖðÀ®lÊ¡Äcä´jw ‰Së~0òämË3)è±3貂/s%ñŠKoÛv4f«Êæ5ç#³½:õ³1£´0ºXr¿+Mµ­õa}e‰ÇkàͶëøèÎÓ.]Ô…SéG—ÐT¹ðÕ1¯¿~¬D`‚v‹íe£~ý6v~QO¦ë˶éUÛTçi«sâË~ù´_nc¡UH<$ Bá…a8÷W¶eÈÒ%$ÑT³(µþܹT@æ`ôà¢hg­ðïNÝOŸšÆ3g(›‚ßטѻ) µv¦©Ãù2n±Ð1…ÝXË,ùµ»eæï­ÚÚƒùæTšƒéì)œI³çù›y9ºy_6½éS™Ú4C/§5métÎ`ê~WVÿú*!UÝmfQw#l ‘„p†½ôÂŽédC9 ±S_¡S²ãÑìÜ%€Õʨ9Ù¯ƒyi¶–Éžx óå/|^v9:“£á¶ˆù%bósGoiû%“^åx!–“è 0kSʼ½>NôV°íà"~lVubBÑçg»VFF›õבMñ•¨Y6~ ‚Y:ÃЕGŠ…GQ ¼‡8ø;5åRÃ=ìŒaÇZ’ëÑ]×Ö>ÏëmFÁÁ)\·»ÎÆMÑ BÚ–(Ñ¢(Ò/Kmâ¼Vƒþ¤0‡&ÙA„ÇQè.ŠÂ:-oPUí©l>©ö0€t¥4Üæ­Èwtž_xç݈8²0Ê&»—`X¾[ލ\Ú°8×,}e }&ûãŒü~1¥®Â¼ô³å5Ãzã#å5|cläð”:´*@VFåü=´Jž.ñŒ)J„Â9SxWS"8ä;è+µ<Ê/‡0uÎ;†*À\mÕGÇn~d +ðjÛPÔ±;ú&sÄ·†;Ù³ÅÖH{7%K ƒ;¯wCðëm¢ÉvôuâM´]磫Nû²Ø«’S}¤_ñçYW»ä+ºïK3Jî´_Ä\à‚?¼xv@>µa©“…Ë@0GaîT(Wh––âÍ{Jg¨µ÷L¸Ð;Ž£ˆ=”O¦:ßQf{—å'UæRCNâ™òU6 טJ-BÊ>ARPïu Û»Khx8Ù2Š‘¶Ã¬Wìþ%ÙQdÓaLÌÏc•žý?RôÁ  QÒ€ücS•5P¿e²ÁÆ@9š¹.öf{&\ƒpni:YšN™K„Lçñ"&I£ñ’6» ¼ñ‘0Ei10Fö„+k#Å€„^ðœn=î ¡ŸtÃÕ1ìõ0fÍç<€ø2E‡>B¬!Ñ)teš­Ë×ÝMPéeÁ®tW`Ú%Ì7õ?#À«7sqToö­³ÿ@‘ÔÁ¤Ö"±%Љ|˜–º _ÿ†gçÔC >4_iÕÔ&Ùu¹¬q§7"ž¤}?[P‘^´цV¾[•¨ˆì¥¹HÛUZ¹0kaùØÂrnA±HNk B\|²µƒ>ÎÌ"5ů P¼£õ†/*ˆ ´,ÇPG³+"¯”údE 4cЊÖeù.á`oé+ãòý_ÿ¢äup©Qj\Ì\† Ú²#K;Þºà(FØ]f"تvÖ¨ø£ëG/‹þ™—áóT§ŽüN’´f“³íîJ^É北F°¢ýÎmž©i–¬WGI‘r~—²P«1´ÉÃpÔ«95R nÕ¢¦Ô´Õj4DVËt ßÊ6"c¯X(Nü š‰úÕ¬¸~ùñ _7ßR¡„£N–S¿Å]Ka٘˔þ?Úÿ½¾ù<\qX2]Y¾¢T.&Ú :Öìbz _=Œªu¼OÄŽürÌV”¼òÓžy¡LF銔VCÉÂUD.ö«G9òΆƒ-~œ[1*™¯íM…P’=¿ì°tbTß\y¢’ÉWJcûÂÅ(¹¾ÙÉVÎ’zf=HÙ^¦wÖ.È.ÃêõW¨—2qq/°î=‹¿Q³9q;ìUO}|8 ‘Ê]‡áÎWP<²ÄîØqË9y¼:rkØN‚`Nг½æûܳë^nn8“Íc¸"ôïÀEö„Völ ICW0’û@Ö5ôVUí‰[Ï3(Ãh* ï‘gœ¯¾§2PPþBN¦ÔúÒ9p÷“Ï }yààzÓ=te—h¹wœ×êÔÊÈoœU»jn¥|VòÏȹzKvóÄš@ÝWßåKTm.U\IP©ÛyÙþ]D螉Í4|MÃÓ]Уb„°Á½jÆgó2f·• 2ÏÚ|gÌÓ[ö¶¢È  *RK‰#ÙØëÃÁ4víkuE6×½ý–ðC`ÆKÒ‰O.棈æt? H¹ÙæÖΔí d Y|/¯Àx1_òú»K÷jÍ1ß™š 5ÀvtêËaB]ö¥Î|«O¢Ñ‡Ÿ]¢ÞI2Èá Ùl%¤÷eS$ Q åaX¹òžð¢ÖY“ë _ó™ÓG44´³­¯ž:ìeŸ šÃžÃf(¡Kvþ|—O›@ Åïý‰ÔH¡ù·H«H=ôÚSo=Ñ%t‘²h’~ú¾g{˜™…ì…(c<Æ~þù)u8£õƒþmô±R±Ï"þŸ“³‘‘@‰ÆÎõ[£ͼ³"&”V7ˆŠE¹ØmüHÖ>IBuxÖú“o=[¯zÿ¾{( E¿ÈD Æ//VF"ÊH°N wÎps怬k­[‘ôÐÜâDä&\ŒÈÒßãúbrQJZ›ÍHN…žFñ§ÈïËžÌv5½TH v±îÄï50‹C½ô4ì£ê¯(iæÂŠfk„α—FæÛœ*À¬IÈéåb«w} Êã QD¡êJg¿ÂšÿhÛl§Ü¸ô 6ÁíXg•TÊåØ!Tºcï(n›¼qܹ@Ø™ºÌÚŽ ŠÈ8‘D™˜M'“…¾ƒ“„ƒÃ5Ñâ³5Õ¨¶X/(ØÞÀ¹þ  i©ñëîtm§™Îä….̉Ÿ±l·wúæEA×m€Ñ¶o¨2j•° ![®óå­<ºŒ€TO‰gGÁSJïßè5äö|`Ö®SU¼W¼­Ä×BSü~PeÛ¥ödA²:ãsú¾ kÅ®„Nͽß5^dkSX”×-¬ýç Í%ËÊ‹ÖÊDk,¡ƒ»EgôÅexš§7™Ê$ö¤)œV³š§´5î.ÍÍR÷rz´I­—ˆË ¥È½wioCäèÁM;)Â:诸¨+ˆ ÇÈ´ªìVŸ\_kHݵ>ŒEYRóöš³Oiéx÷ÜêŽZઠÎSº5~Fz­÷wkP/›Nâ*Jã±&8´$]…kt:Öt ©Á,ñ%uÎhÜAÌîðF&˜ƒŽpuólxsïn®îV­cÔàÜ4jÖo\»ŠÎ”ÍÃ)š¶ÄïmTö®µ%!Qtâ Yxµ0à È MDí¤ZdAW‹; ~&}«H@ùH¶˜:ù[„ ˜µ9š±$ò¢e1ïÇÞ…Óp"Ò㨦ŒäÛOÿ“Úïà endstream endobj 1524 0 obj << /Type /Page /Parent 1724 0 R /Resources 1537 0 R /Contents 1538 0 R /Annots [ 1525 0 R 1526 0 R 1527 0 R 1528 0 R 1529 0 R 1530 0 R 1531 0 R 1532 0 R 1533 0 R 1534 0 R 1535 0 R 1536 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1525 0 obj << /Dest [ 1513 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 428 689 436 703 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1526 0 obj << /Dest [ 1539 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 419 649 461 663 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1527 0 obj << /Dest [ 662 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 254 635 271 649 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1528 0 obj << /Dest [ 1485 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 163 527 205 541 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1529 0 obj << /Dest [ 1539 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 149 500 163 514 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1530 0 obj << /Dest [ 1524 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 267 487 274 501 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1531 0 obj << /Dest [ 1546 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 89 419 131 433 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1532 0 obj << /Dest [ 1539 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 89 365 103 379 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1533 0 obj << /Dest [ 1539 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 201 325 214 339 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1534 0 obj << /Dest [ 1539 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 234 284 247 298 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1535 0 obj << /Dest [ 1539 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 278 257 291 271 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1536 0 obj << /Dest [ 1546 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 275 244 316 258 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1537 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1538 0 obj << /Length 3752 /Filter /FlateDecode >> stream H‰ÔWÛŽã¸}÷WóD¶FÔÍrÐi`7—Eöa`ŒÈtÔ6Ý­D–´²<îžÉ?äóSUÔÅ—îÁä-L[¢Èb±êÔ©Ã׳ëu¨ŒZïf&Tþá'ÎB?ŽƒT-W‰ŸfA¤ÖûÙÇß2µ9ðœ@6ÕìãOŸŒz:Ì? ælf‹þñ4ÓΟ¬2Y ¼õ?f+^´RËÀ_¥0e~ˆ]^òrzJRZýYÿ;Äè" ¼…‰üT™z|UŸ^«î#¡¶,éCqP?ü4Wû·HðÞâ[â'ºð½yž«O§¢ûjÛ’D:¯¶Þb¥Õ¿ø¯÷÷õÏ3>1Ÿ& ü/ëßcŒ=8N¾ùFhWKÛÂ4¶ôñø¡Þ¸¡g¶ô‡ǫ̃BÍÂ$õ£Ô¨hég™J "©pÆ8S­íf?®‡`DS‚óhŒÑ ("š£7f&Ë$~Ë4ðñ_– jêøîÚz¯à·ºÛ¶Ü–ÅÁKƒî~Σ¹—RÀÚüUÕÖ¾(÷]mkKû%¯:UìxjYoòR}ñVBoA!i‹ü±´8Ñζ¶ò %áñc½%&l‘ŸTF«ºSy¥òvᢾ0>Žƒ` dÒ>ýÆyßæ”ÑH¿ÒÑê‹{ÇÆòðˆàã§´>[Œ3qì§ÑÇ$SÂ8BÙKdŽ|Y eûñBr$ˆOK_aï4Ðòd;/¦£m­<s¬ìVâ{—ËpçEÚ¶^¢é?@ê|{@ì>!Êʦ»Wµ³)úU96Ô¯÷NZ©¬—é`ÜnŽÝªË˜²Óñè,þg½ÿkX1€­ñ—Ú"ýŒ‘ºŠGë\Þå/oLŒ81´¯™`÷¶"7P äø‚ƒé—•G«0 %L!6¦0)Ôæ³ºs&‚ͰWÛ÷¼ìaX˜ËNýV™ÏŸxL˜läÀ«i a ö±:îùÐÀhíÆsy—¿ìHŠC£èx„ãL«F¾Ö+ò—ÒŠCmî˜VÚƒ{"ºÊÈ^uµ/Œ6¦ˆ ÅeŸ¿ÈvJbqX:}xÁ ×Tˆpõ9ƒ3ZF]q”K­˜~AœòãØ¯€Dºaîì9<9üšHƒBí 2&-ÓõO£o2:<޾Çã\†;;òÔ +»H2ý¦ýQÈJsy·*oŸ7BËã®[лµ»SüRŸæ\šD0´‹ Сvƒ€ÄºFHC½oJÛYÿºÉ]ww§&n,F?¦nü•д⮩Hšôûã{j‹®ƒ°wS-ת¯”ÇÜMqq”xïê²dQˆÖp¢=£îlå¦þF]àÿÛ­ÚL;×7³ýèÆk—âSŸNCóÎAûn’ý¥n¦0}'Ëf¤ý^¼…S¡q˜á€Úç~ïXU“("ãòc7µ3…s|±\÷,|·µÄ¶7‘As%0”œ‘ iú‘LÛFŤ!i¤–J~#÷ô­pxRª\,Ppcû·1-ód7&>?6WWÍÏšj[ååiz×xu1ÝäGyB·ÄÇ#"ðÔP’ÄÂF‰$8~ì(zÐ(ž G³E©o-³1Ü 1ïÅÕ9ZN…‘ÜA§WÐ?B6å* ‡ŒÉŠ úæù['oõél·¼r.ŸÑŠN–áE+D¼ ±*¹Ë(wT»¨ˆ„rFþQ'ÔN»ÒpÁ‡åÌñû¦¥¼É³„]V»_¾œtd=AV}Ü<÷ðdˤ‹~K8¾©y˜ÄC(\äÇ¿¨½²¼¯½ é°ˆºçMy¤ʱã)ý†D„B¤Ün—èQVÕ•åŽ2êfåPIœ÷µÆ¶äð êøÍ]<ÅÊÄî¢ü]lQ[’'ª»eßm˜ß§ì~iâ~pF(d)ÜMTçu#ºf©‡s]r‡’Ê_Ïe)•W£ŠpÕ%ßùf×IaÇ€”†¡Š®äsÜ×+E ·ÌÍÃqÀr"Wœ*âQG†"Œ“Ü2(IÆçHÆè«½V}9,&õ -=Œé26Î5qW€vô¶|s7l)!K:ĉ„Õ¦KYZNožW7ƒÎ:@`Oü¹z"V¥N\pÊû·ØA¯Òµ¿ÂòMbj7^{žp8@±8b—ß”ƒ|óéWJ·ÏX?ˆ0ÛÛ¼âcUð~,¹Ï8÷‘ˆ0×õ­ª¬ÝŠFÜ7×lû™ï¨µA…±éîÖý üÛ˳sý»;ÅkÚããŠWE½˜Kœ±`®«r¹Ø•¢6TN-®mÝè«Ì‚­}\¨yäà~™”¾’íÞ`}ãÞy;ËïÒæ<õÚÙ|Ab-õ?‰w±à$¼ðàw*÷n”læZ³‰\¿–kó[Ýcì³MK9S`°<.ò?Æxä‡^ýdÓ'|žH´˜<Ò@Qå–è;tÈG ¾|6õ€wa­;¼ß»eÔ (’‰\7¹‘s>s6F<áY½p¼.ûvßtÐÞ`ðÌ­â²QÕqÿhÙöíîŒÝ5pݵÞTÎ ‚°ZÙ‚ªP9ÆSØŒ÷ÿp(¾ZÒ]Ô®ÀÙ‰÷œ¿mþŠ@¬4´‘H ¥ÓSi¯ô3‚Em‡BñrÞ3Þ¾[}Ö úÁ=]Ó.ó Ö\f"‚§Ö\rôNnWÿg¹½?ºš§`•^ܾŸš‰\pzíý—ñªéM¢÷üŠU¥¨¶R¨©Ê­×žP/ÍeCÖÅbmSƒ‰Ò_ß7»ØàT¹x?fggß¼y£•lIÙ4 ò&§l¢Aw'Üš ·Òü–,PüÊF4àïFüš±„|5MÖÈß-'7wXœÎ’òGˆÒ•Úú%¬:C¯4glUQàfìåSjÊ¿ê}â{$,L¤µ,ò$Ÿq^xO¼7}߉ú¥F£cI)9mRjè௉Q ÅáVU×Äv$8‚À‰›:Î"±fš}­'³Tq3úµ5 ¢OçÔZßrÛæÕ lz«Ñ#³•í»ædápý¸¼ÆÀPÜ)±7Z™ÁÛÙjïŽ/ëQ³•$\p* CÑ3.5>3"vî À¹åãvfï톳 7÷Azôò”²áwªñå[¯9<[>αq¶ëZúí‰U õö'®’¡l²`ÎhLq·L|Ô·Fœ·ŽWÿVAå'à]ÔTÆŸ!?û›‹ÃàPO3pìœIpNÍ'ýÌœ O˜é‰ƒfâšK+f†Æ.7‰fJ³™´c7B´‡¸ Dä#÷][ ÚIîä/©Dùß.ñ¤Iϲ/£…çº*rq‹º9DD*mÎ)EÍ Ê\=áâ'ÓñÆúЙ‰°;÷p~ ÔxÁâà’õ\¯Ï¯7Õ×{Ý–›­À虲c%Ø¥^êå%¦-ð ãûæÀZ¬<–M2¼Œ–oþò¥,‡ú{JX…g”1®hZT™C~˜/¢ø+!ˆ]˪!ò8mcAýdIã1æ½>°Pu®=ª±¢ñ¾y-µ½%äèu>Ø„ªµ`œ ôï¾ÂÝïip<õÏ8É'?”x¦à’÷ g/’'áEA¯ù •æÑÈ·èï‡ð5˜ª©.g¹@Î7@‹r MSÞÍISŸlÀ>sA›cfà¸]qAËF®#)„'iÃQHIbX–ˆƒ¤‡-Û°9Ùš"ÉKå–'Î6+š²-q¡Z¸ÖÕ‚ŸàGÿÂÄÖÍÑ0U]éÍI¤ò“Kë¶Ö Eî¤ß8Vþy¦&p‘x§¥áËz½4Ø\Ü l,Í4Z–ÀôãBM$·J“¹<"òèàþt/{Ç9I oKÕ?Á#Ê}B²Õ‡æÂG5Æ«+gë`=jÑgìܰÝ΢ƒZœ%3·â¿1Ÿj{ìÒÉ’bný'`m=¸Jþ:ðÚúm@pìç6Ž÷ÎŽæ7ˆÍ"(n&BCïH¾}_ßü`GÆL endstream endobj 1539 0 obj << /Type /Page /Parent 1725 0 R /Resources 1544 0 R /Contents 1545 0 R /Annots [ 1540 0 R 1541 0 R 1542 0 R 1543 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1540 0 obj << /Dest [ 1524 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 425 703 433 717 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1541 0 obj << /Dest [ 1513 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 273 451 314 465 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1542 0 obj << /Dest [ 656 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 251 270 259 284 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1543 0 obj << /Dest [ 1513 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 189 113 203 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1544 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1545 0 obj << /Length 2552 /Filter /FlateDecode >> stream H‰ìWÛŽÛÈE^õ?5ƒÍ;)c,Àkï.v‘Ë" žuÚËâΛFðª¥Ûµ—Àûå§­üElÌFvÀiXêá9uºÁ [ézq*­þÅ>È;ëÜyS¸È¨xÝFNX¯¢ê{Ö%uŠZªUoº-u]Kãu˜1Ÿ†>;çóS8$?±ÇúŽšz]÷Ä‘6>µû5ë’˜{»¥îJ‰}h¶Ûò@¶±kÛö° AªÒÓ¾œ"¦¦·-õ¤K«!gYöå}évZ691¿VµŽ•e>ò}ÈÅJRSaå~Zˆ±¬³ÖÉ1䉆>tŸfáe¸z…(«wz«iå âzá'‰Á—öRÁ ù8^+Z¶Ó.¹ÙšGO,sÇš½%|0KD0¿Q…°®Åv”áŠnˆõòã]=dÏåØÝx°Ü7=½¦ðÎó¯"ö™G0Ôà$­!Gý¸Ý‹ÉÈìN¾–ú¦¿¢DjNBÈ0B]í*«ôתÆKö‹lkP(úĨTpyµW·ŠQâ‹H|q€ù¹j÷BKÎ'N¥N*rýB-ÇóE°Ã£í.[¹^frChl³$À«Ñ…Ñ_\Íôyù¨ºª>;2³Ä¢­ÑZk9YºÑ=e?¿Qÿd¬*˪ÎîRíGªºÁÝ»EÔ-å.œÓÁªèK)ŸD41št•[7âÈ[÷µEh$áõËÚr îFr¾ŸK"°09ùlÌÉ "ûÉ›Iì9g+^ÍžKà$1Çà j3øQÌHœ¿ïžnjø†o®{»ÖTWKìC³Þ4¶·þˆ ‰ÃþÄ BâÇq‘“¾ 5C»‰Š“Ž$¨ÇA‹BUã˵(iËA½õ¤«qå"-¡¨,V¼¶ë¡ 2GwkízÓæ¯Hv,m¯¹Q7Î-~+J%a@¤£N±ê´µU·]Ò Yæ³; 3Ümúºkw£'®ºà`~: ü"91ÿézÑ[$cYsýÕí+äÜ\Ân†FêPãl„Þ†³$gÃå·T/ ý䍨TDp¿R×_¹"L8—ªÆ‚³©VÜëk0+ãJ$ùÈ1΃^a^ã(«7Ä1ó1쟽flÕmtUŽ;Ô½HÎ fqÙc¯5]ˆDæ…±N<õåG}”RÒÆZuO‚®©P9AVá`—j»ãÌŒPœ@xd¢'iØx’Œ`LÛ5TËwλ¢t”_Øó+‰Þw7F.WlZu, Ls;æïÜmw—¥~^œdËìX3ut'!Ì ­ô¾L ¤ÖëýúÈ a$±r¹eϪKŒ‹ò°ÔAGå<8 N‹ˆcKÜ'ñô žöéijî’~U;1Ã_a·ú,M„Õ¥Š˜zÞÚŽ¼#8²äàFÄÒÚ–À °Œþ„ÿð(Ñv==ÔŸ¸O£i[ 3NEÜ¿±g O·Kî‰]+)³.i´öζSÉéçIàåÄùÁHꨋÁƒ…°šfÂà Pw¯$õIëž9ºÛÉ*8Z–9R&˜ÏkìôŒiYÙ÷î( g¬º¿pK¥Kì~¾çOvÐG €ý( ”óšH|0J=”®Qc¶rPî1°‡ºÉi9þÒÉ&¸Úi:sšÞ9¹Ö’£öiÅ$÷´´w"qÃÀþé Í@ÚûùëÀWÖQŠ©‹²»9¦‘¢+††”µÛˆ‘¨IüåY6f6-ß*aw~»)ë|a`¸àå#·Ã°“ë°C¼K9¹#ô¼çù!B§&7Çè3Œ 2Ë,äy%†…uùópùٔѺ7ªÇYf(Íè’b\C5â·™ƒìh3¨GAõ¢.ä 8[©Ñ+œ>?ÚŒG°ÐEêñÁ+BÆ9Rï]ÓÀˆ2ˆ#™! £²ô×íê¹¶F»¿™)äÈ&eü©yèiÄ¡è+þ6/•mÀû^Ð͇Îh¾òwƒÌ,Œ.<îå—™™‹»ç”Ò¹ÉM_½FÒI:êuøÚ[~Y•–ì#ª÷V)¸â¸nÑ_÷ W'¸F'¾aÜ-ÜÀW6 Æ1uΦJ·u`°á<¯+L¡[Ó¸õÍMçêJâ/)ÿ|Ù†5ŽyœE\„.À3!ÐaÅrã°K‘ܺˆ{tHkð¬¾zöž”©ÞÚ¸ÕqÄçÛÎ3#Ôœ™²3qžKÊ…0ã¹NdøP;ÀuîK]}rãÓ¿4ïÅQî3–µæôwøaˆ‚Ý·mdzæŽS(E¹4½ÝÎÙˆq!ÜkhœŒñÃH¸è¶ã(&ÇDÞ–ÉMf¾>”ÅŠêÿCÙg(;Á‹‚Dlé™d?môIúMnôn@{îÜ+ÈAþ¿7v]^ñÜ(ôì¤#Á8èĦ1͵‰ƒ iMQ-ÊdÆ}-7›¦Ö¢´ z¨£ø4Ÿ²1þ™ãÖv×Ӛݘ}Ä2L¹9Ú Cc¾@Š窕­~&!zµ ô´5×&á²Nør Î[á=b#8—…]mØ¡1g\@ägÉ)«Ý”Ê/ U^©/:›È“Ì$Ji‡Ü™¹áý¡­~'ï¿•u²íG ÉÝ£‚C³¶£`«J­Ü.@³v™£Ì¥öé: ã¼Í×þBïQ·J}ußÕQ¦úcˆ/Óçš­ Ô›º­Ã]%.h®|»˜üsü±®Þ endstream endobj 1546 0 obj << /Type /Page /Parent 1725 0 R /Resources 1550 0 R /Contents 1551 0 R /Annots [ 1547 0 R 1548 0 R 1549 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1547 0 obj << /Dest [ 1513 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 452 625 493 639 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1548 0 obj << /Dest [ 1323 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 471 196 501 210 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1549 0 obj << /Dest [ 1204 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 129 121 143 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1550 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT12 1672 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1551 0 obj << /Length 2063 /Filter /FlateDecode >> stream H‰ÜWÝŽÛÆ¾×SÌM€`EóOe,ØØrâbë$ƒ]÷bDVl(R!)ËÛé;äsÑïœI”v×Þ´Eÿ @ä3çÿ|ßá×ÙàE–…"Ùr„ÂÇ—8 ½8ö1žŒ¼$õ#‘­/^µ©È[Þã‹6¯/¾™â®øžïØ“†ûÛÝ@~¯ïŒÒP¨ì/ƒ šˆ±ïMŽR/ñ­\>òqº%túVþâé0ôÕ0ˆ¼Dú©˜ß‹Ù}Õ­ð$”FA’l‹V\s!þô›ްnðnäd¡|™¯.ÄlWt5MÉB"©«…N¤øÿ«?g°ÇìMè{ ÙkØ›X ^Õ”Tf!Šê%§p,b]$Þx_8Y/œºÁ´ÿšŒ äýÕ¹aCxÀ4'&`KnåõG](t–,õ\Q=–ˆu,Í˧­°Á<4‡Y[ŠJ|ÿžJ>’߉¦i‹ºjE]•÷O›å¥y© ®DnÃc#3úBdüÑ¡Ýé–d Iì”hÕÍÑ©Pêά‘gûà ²)ëüšŒe×5Å|Û™––$ûRóyûÆÜ=U]™}}& û½6K½-;‚ôwª8Oü±}ý£ºcø‡ýøgjÄ8‚mÒ´¼0Â^GB®c$‘ݱuÛÑ(º] |Ñ‹ aûVÔ ÊÜíQõÞt‚;]P„ybf¸¸ä×¼¸âH1|±„D™§Õõrfû¸U äî£÷è¡&&¬X? Θ±¶–;€V^]]½„µ‰¼€ÿ¼ƒñ„z ÆòºYP"ö¯ã×_†–Q<:¥«ÿ4´Dÿ]Ðþ+¡%8BKà e^לںÜ*t?èÿ98÷oE“ðG“Þt+—H"ËÖûSç™?Ç–c3cgÝ~»ݪ VGEdŠt {alÊ~tj8&þU1þ·æ'Íaà€°…‚œ]Q–bnøÞ|RBš¡]ó«/ô²3{ :(kº¢ºZTf'ÖÚ¾"˜Ãù 6ì¡LtŠ2½ùò––¦r¡(ƒžø‘`g«ËòþBìVPN†iÖ$¬&Ù#Â^Ì©Q¶6±¶†Ò¾w‡®U-òUQ.—ÀçÝ{¾Ô·ú¢)y¢éoÐ ò'ÖŒÕâqŒMŽÞ»ù¹i•°YB\,k·‚0ÊE˜üçôÿø@³,Éûì¿&5л(±hH¶k#ríîP84nó‚å;ä1w'ì¿Þ‡ŽTÜÛ£âƒDÛ‰(,|ÛûóäÄ‘µ9 Å‘=ã#{:f˜p“a°â£@,_½ü ~Eià’þ ö@ÄqÐE]Ö›ºx±TÃ>egx݈§²Í›B¥rÓaÆÝ4fÃg?Ð<ɱмQü:Ïy¨ª°rïqÁqÖ¥ í×YA4ÊšXY£ß!jÞûö#ºÖ\>?};}¯h`œâ3HówÄV4|‚…ÝÚˆ¯®ß°'_ýô†«Ä¬êr¡¸¡öŒîsÓ~¢™)8”ûfñêÎ{®ÇgùÏAÙO5Ø0îÛ'ÑçJ¬4C† Æ^ÐØ¿:~MBPÔ¤Óë“XƒËÌR}–¥/ÒèXä”1ä÷ä…Gy\Ò&ºÈÅr[åP†;·UÎH«Écxlñšø$þ=Þ?ÍÆ‘® endstream endobj 1552 0 obj << /Type /Page /Parent 1725 0 R /Resources 1554 0 R /Contents 1555 0 R /Annots [ 1553 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1553 0 obj << /Dest [ 1556 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 482 689 496 703 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1554 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1555 0 obj << /Length 772 /Filter /FlateDecode >> stream H‰l”ÝnÓ0ÇïóG»²¥Æ³ã|NeÒ6`‚+¤E\0!”¦i”¦U“­”kÞ‰wà¹ào;éº*5ɱÏÇÿwŽ}{çy¢|á©€$~x„i ÂPÆ”d‘ˆS©)_{ç7]Jeg÷HêÊÖ;¿½S´ì<)¤TØSzþøº÷؇bY‘J5ñü«—Y§Œ)²u*béâZŸÀº›·(6Þ÷ìw«Hî+-b&SšèîÐö+XVqDb]ÝÑÕí„>ýá~„ïÖ"±šKV®&t·¯ûïÕ®±A4+Ú9÷3F¿ì?ÿœ¿÷¬b«&"ÆGþ6[Á~¿\ Å:“µ2i)^¥X9˜V6Ò›ÜST“D±Ð±"ˆ4¥X$Ac˜Ò®òÞu~„¡¶Èç4žèJC„YzèQ8ô(2tm²o#Ï$Ô" N€Êd*#'x‚jiÚUà„Â{äA lІÙŽúözuÖcŸ†1ˆðøæÖúùŒ§Ð|ÐìrBÓÒ-7ueí­s#T\k‘þß™gHyvŒrë“TýØÔ¤JL3üQàF;5o릢뢫ætg*Mïc3ДAZµ£ÍŽnšu%¬j{rÁÁ2}9ïGŠ2AzBQi•Ëz³iû¢n‘´n/ì$ìv8F±HÆ92ƒíB8÷iÇcP9 ¶üRnÚQu½¼|YŸo#*¢)íž]=5ÇeM1ã†`ÃAŒU/‹QÇqz^ÄŽÇUî]G톚M»º Œë–ѱРI`ŽXWoZú¨…œ` ·MQ‚ÆŒ+ƒþà¶ÐÛ¢ßÐýŸ´m–u{XE endstream endobj 1556 0 obj << /Type /Page /Parent 1725 0 R /Resources 1560 0 R /Contents 1561 0 R /Annots [ 1557 0 R 1558 0 R 1559 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1557 0 obj << /Dest [ 931 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 332 689 346 703 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1558 0 obj << /Dest [ 1596 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 369 689 383 703 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1559 0 obj << /Dest [ 1574 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 111 154 133 168 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1560 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /F2 1668 0 R /F4 1669 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R /TT10 1667 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1561 0 obj << /Length 2455 /Filter /FlateDecode >> stream H‰´WÛŽÛÈE^õ ?5‰ÃæMÔ¬3€íñkïf €±ŠliS” RkŸýòùÇ<äTWS¤.kgƒ ñÒìË©S§N=Ÿ®¦S_(1”/<üá'L|7 ½XŒ'‘'^ ¦ËÁÕ‹:YmÆx¢ÎªÁÕ«;%õÀs=OaL6µ—ù6]h¡’P8Ó &棉{î$ÆÄAâÆÏk¾ñÍçtÅôõ{ù/OG¾çŒTàÆÒKÄl/îöUó€'¾Ôf’uQ‹g¯†âïÿvFî7x¹‘,OfCq÷X4¿êMi& dZåÎh"Å?Íç—éë9±9ï¹1n¦·xfvðøøè:«dM«jZScI—žëËÌ>z03½œ”(ÄÀb7ˆ•Æn’ˆXI3†‰ØèÁ|ð|z#Pâ£Ñ¡ë"Ò ‡…6F¡ë…&sÕâ9wì÷õ¢P/àãàg쎥xZkà~;ÇŸà€8g#šýZÿùÉÚIÜP–ÛEQ=¹qpT%‡4"Á·™ãÀe¡Í ªø¤ý°Üš§øÐü>qF!¾º¹æAoÍ”-î# ã©1Î;ŽiÇïåó´Ö¹¸3{Tf‡RoÄ 3ˆïÿÅ ,ß®übUÍ‹O œ’S.òb×Oz© Åø`¢&-*¬]T×&Âcy˜Ö¦HìŽ[Žiy þüiíÄ8ëÞþTÙ}†9!P.7§û™™vx 9„,±[J+‘ñ¶xGÑ7vt–…ïe“.°%)rM? ¬O‘v(.È 93'ÍCaÆeéºÑ<@|ôLk‘–t±rRQ(5H%¡bAO׿©Î :­²³fiIÌ din÷‚_ò vöÌ„‘¦øà8>=ùM”‚J*îþŒÒ>”M³)fÛ'Ä­’„•"ž|«„ùÖQErAL%¨ÏŸŸDª—•^·34uÀ¾¥Ô˜¶€R2lS×€Z ‹HwiQ¦³Ò1I(æ«y—Jo7iS¬*±š‹T¬9ufÈ ð+–¹@ï(/6F·—Wv«— ÁYhbr ÞÂÒ^·ÛJÄX1MúiÉàÝÝ«Cùæ~™VÛ´t×ùü„ecÈLO#üÃé’æ@V½Ós'‚¬9DFWØØOæ2s&ÍlÙµM&Ç1õº˜¶ÚN̹[Í›G:ß­Þérµ^êŠö ÌÅ›¢1 kø‡ ÍeUS1ÅU&^V H+eòˆD°ÒWœÃ€¥Ÿó:âñ®´XêåÌh „l5GqEÎÓ ½±[Y>~•ÆrY”{q"€ÌèÏþÔä³/Cñh¸÷À$?û£xC¦H®Kwéq@áàéWæ3»ú¢X®K ØšttzØQOïí•W@Dij¯*Š ŸŠÄIæÓ‹@ºôJÅ?.?üHœ·¶ƒ7;~ÝÞb‡¡¬¯2¾-y »’µ“ ÀÅÇ8j/68¡•ld-«“Qè„.p.¾uU\‰Ì “bA·ƒQ›f­Ût£.KÎÓx¶-Êf²~Ú]¸×âóq–„Œ{IªÂn%fÇñj¾OzÒß#§ä—ï a¬z…–0-Y&†,¡ä!†,ç—Ð6%µCLLÚÙøÙŽmV;‚ ÏËœ3×^\núÝ*ªê'³%”-˜žk‹Á÷Š!@ik=ì1E©;ðLopͼçâõôê85Nð„ðF“¾ð‡Ýßú˜´>c±yä'TëmØ ämkˆ ©Ì³MÊÕ"ãêðQ7¢Z5ö!š @…´tXØ,ôê—íÔ‰¼ï°øå Œc‚²y…$ÍG¥×Çû¢¹ö:ëÖjÛ_ †=nl<ÆÒª­$¦³S¶³‹(I2ðnfÚ?Lj€ýŠ”?/v…©o9šðÙž{%„?ÛòçÔÌ¡4-õfÈÀGÏ®q±më*j›»Ô¹PŸ¶@Û vc¹;,ïË=džó¤Ï^‰UUî/´¼_w¼hó›TPJœ³ÝSÛºé(á÷(áÇ'ëýÉúû°õ¡UOyæÓŒÄµIÙõrÊör„$kkŽ.ŠÆÚÙ*ÑÅåÃ@¦ëÆØHÒmDäóiÕ÷ŽS®o[Q>ÞV/ã]«üÂ{o>R±ë™LôÇ?ÿ·ƒCU¡ˆÙ¶ãÜ”C"ŸµŒ=ñüèõâ~ò„=A£ ;âÖýKB}emØ1é.-ÊtV…IÛ Àn²Y&yu7½½zûîgد ŒÍU®ë¦ˆbñÕZ°ƒâ­fâk«“Òß1QY&¦%Y&eZ èjYpB¼yüÿ;÷^Z¥Ü¸ìÒ+¾ÿËÜõQŠ2ñ,73ô0'웸AØ‹SØ#ßkÌs²¥Xõ"Ó5f­ý…oßQŸÈ#Ì;°£¢´“—ÓÁe endstream endobj 1562 0 obj << /Type /Page /Parent 1725 0 R /Resources 1565 0 R /Contents 1566 0 R /Annots [ 1563 0 R 1564 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1563 0 obj << /Dest [ 1379 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 269 712 297 726 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1564 0 obj << /Dest [ 1016 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 438 159 466 173 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1565 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1566 0 obj << /Length 2095 /Filter /FlateDecode >> stream H‰”WÛnã8}÷WýD±,R÷F6@'ž`€A?íd1P,ÆÑ‘ KNÆó!ûûû°u¡.–å8ƒ±Èâ¥ê°êððv1™-Z(±xž(-<øƒŸ Ñnx‘ˆÓÐÏ‹×Éì®JIJ¢1ž¨–ådö˃«j⹞§`Ìr2m>ß'ò>[¡’P8‹ORš”ŠØsÓö7òx]š£i:~…Îþ]þWCïT{ÎTùn$½D<Äá¬_ GKãÀJ²**ñí—+ñÏÿ9ÓÚ;°…n( Ǔ˗+ñð^ԙݚñeVæÎ4•â?ôßù×â× ELÑhÏ ±˜Cyðþþî:¾«d…»Ü–†-]øô\-—¶ë…Vúi1Q¢F®)áÇn’ˆH’b ±3“çÉí¢ÃW0Ä;F£C×CD$¡gØ3 \/€ëûI,¸Ù€‡¡ëªšEÕ³¨Âåj'¨Äõv½_%5þ@ü RSUņ»²}ýrà åH»©N]ϦH³“M„fÓ['ðÎTÉÜÇ`by'ž!5ØWÁ²;'€4 dŸ È5y"ïa`(8Ó@~§xcŽ7´ÓÞ0RHhn]5C v´«¢GǼå'/Qׇ=É?ŽLÜàÿX›’O´Þˆƒán>ƒ^èº Ý‹»SŒ9x>‡Þ1lži:ìàrábí•âu“ïׯ„£»”H‘-ëâÍIaTæL±´j¢Ô=ÿzz”ÁD(\ ?+›‰nH£R%[8)Rˆòz6ÒË@±&>ä­QºPQXŸ½*½d £Æè(²o½ÄÕÁ¹É[›}¡º€<þ¶•Übë~O¿`n ÜT[+ÓÏ ¬qûíâ³,ù š} [ó{,æSá÷X,@ 0Ì[±4Ô“å¯Eù ‹¼ÀÕ}KºüO: ¹ ã‹Ñ†NÜ0˜³k"‘°{QÑÄÚÑÈ ƒ•›riÄ °Ä*øJ¬ —òœ·uñj˜ ¨Vß JÏ…HÞêH¦(Ÿ7 õÖ³îâÑÏ!K¤E¨M-‘¨Öu†Ìl ¬„·ÙY†cr»ÿtfvo8IêÞÒ%b°´}KM8£ÎV£üê¥S);ÕÔ1†¾¤riè1p-{äÉcè†>BèÐ#=Ða€–ÒZ ‰Ê§ðZÇ…€©²ÚS’þ %é#FâCâ<ì3R¿ÿ˜‘ˆ”Èxý5bé³ñ|åOþØÚìDðû÷­ä[?ðk|úsõ#³ž‘B/‚•.3Rp–‘¶ä ¶_ñ²‡»ù”Äi§ Qƒ„]Þ}Ã2ga˜4¹ç§¬^§­té)›ïºÊ­ƒÕd–x—ü€HµUÁã*0–WS›—˜xÝ÷k Ëh›qÿ·u™ Û˪„ù 8ÔT -Êö—mAöôЖ虵)ŠiìB¶SÌ)ïe•ÈDUïˆ6§làŠ_Äߺá²j¹+¶}þØW&Hù©³b]áÈ1&V>VVì „(Ü®ƒJ”¯%áL<À½¨†»‘Ž“?ý™½n׿koH7ûŒ°JŽhŒhÀT”X{ÙŸæy+’‚µž'…3Ó/˜{{¼RØw:{̤ÐU¢‚÷Y̯Õ?¨åužÕÙs±6Û Ääì-ÛÍà2«ðL\^ÏŽ¬Çpù)¼l†…õ<5¹“Fð@ob¿çÍì£òLΊ̳Æ0jŒçOg|òÇÖf_øíE l7˜|ÆþyÂö} Yta-aë–°502(-:ϪÞì@IaG}ØúøÇ‚4A"Ë/7_éCÜC™¡òç<“š; 5(àjK-Ë­´—¬ø!ÆãÊó[žf‚åú­XVCf?¹4hl¥{á ÙþnS•@QEùé%é ÑÇQGôºãImºFÊI%ñO,ßì¯@x”d)hQŸ_ºûÌz=¥õ[¢™vÔçñòßP, wÅÓ¾6V;¢·p•]ðV‡„]™¡\Fßèu~èô¤Í«íï²R,4Æ+¼äêέ¡H¾nN8¶ =yÛ¤œÕÍñ U;9:äàá¿1²­Ò–ô =ÈÀ©IRïËÒì²µÛ"þšU ‹CÝ×Å£4ë*K´­.YäDJË¢¦ÉÀKòÔq’tê˜+¬Uç¸÷-à YPpà£4µoF‹½FìyxøEpR¹ƒ…ß¼ÙºËÊG)¾Í3ñ›3»ðÌîȧµáÁâÑiEj¾)xr¨"xÒŒenvëê·nÇ]1G°Î@»­.Å÷9FÈ;ÀN ¬DMI;·xXЈ¹ÈÊ\ÜÃ- Ò¾üNIjO;±sÞø5ÒîḂ]ñÿ‹Èµ endstream endobj 1567 0 obj << /Type /Page /Parent 1725 0 R /Resources 1572 0 R /Contents 1573 0 R /Annots [ 1568 0 R 1569 0 R 1570 0 R 1571 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1568 0 obj << /Dest [ 1567 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 261 730 291 744 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1569 0 obj << /Dest [ 1556 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 141 661 172 675 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1570 0 obj << /Dest [ 1562 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 141 578 171 592 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1571 0 obj << /Dest [ 706 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 130 346 151 360 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1572 0 obj << /ProcSet [ /PDF /Text ] /Font << /F1 1670 0 R /F7 1676 0 R /TT2 2104 0 R /TT4 2109 0 R /TT6 1665 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1573 0 obj << /Length 2493 /Filter /FlateDecode >> stream H‰¬WÛŽÛÈE^õ}jR¯-r00^Û‹ ¼ëE¬§¬ƒG¤4 $j R#O>$ÿÌCNU5)ŽFZÛHlØ"Y}©ë©So棫ùz¹#gL)Êüº÷&”<ë’ߎ~…OýÕ66I8¨‚ôè·T®~¿Ý©¢lójM&â¨D—%Yx}Ÿ©aˆ×¡©Ioj405‚ñÐÔXLM5Ńß7d+Ðä¬Lƒ¹8’>±ô-qLÃÀD.“¤’:*¸úkHD?z”ñå¢ZV‹=¬ Ãû<–„*Ûrר%\‹”D®"¹<¤ð87û†óë1oš²@ÚayݹåNrsf”¸`25@͈àgÇxfçâi%ž¶gü}¹›D™ cJØ?ÎÝøbîåýžßWË5°!Õùê›b øê!¿¿·W/¶X6!Eߨ…gK9þ·º&÷岪á_ ˆÛR”¼è~¿Rëí _Vfˆ¹Qïᩳ7Ì\ÏáÏXS½h Ât€IÃ’RÝW­<ªÏ/Ü :0ý•¤0ú³§r‚L$—ztP“Ïb]sÖ`¬ åär¥»E^DòDµ‚æét_@÷ïÝâÂ"¿Å™²Oå¨çªFÎò×ÉÙÞÓñ‹a?,=Âin±^”aóá…%’»¤ŽåÊð¨Ä©a¤„¶|7=ЖÅ/,ü Ëg•Ÿ½±s—œ×j_Ó•¥å²äåî"õö ­r¦’`Í‚|5V‡‡ Š×=†œ’¯"ÿ¢Çî¥ÏÁ‰pylЦiÿT!ÿãî}˜F\û4jοð Áª‚b|{H…ÀµÙ;)÷q2Ò!fÛB]Ëíå—Üua¿¡ qšr½—uyt/NéºÍ‰]˜×„∑ 'yäAç‡w_ò ̺îñ‰K; š¹âÂãgþ?ñ¦B>®úå¬ Jn°z¨—¥Ëá‚f‚Ýï§Ø WÿÉ!{‡"ÕzäG¶$P¥Õ¦òÇ*åB Pbp@¾e‚zKN8런ÏÞ!ò‚€ÜæÅHO®ÇÞlþ(vÓ³Õ€@ùˆÄVÄ1ºE„SòTŒÕ­Ì8'Â…ü´À‰Ô›ä4wH,mE×QîÂRËj·&ËCKåYâé ^öAß:'ƒÞ ÷îZÍ·ÊqPÞúÊS2°#Æ\BôuµÞÞçkøY#€ )µš1޳ü±ü®L.S.’„‹3ª_p¼'Ý#Ï,Ž) ¼.EEÙBèóZ0“PÌ~UBÕwfulˆnî¨ÙŒÝvÿ(b£^vàX»}èÀÝĹ)ÄÒ‚ húÛV»êñ,ûÇIRH•ÌŸuj‚à³wýªœO¢xõ>zÉLê$³–<¦©›>Èúîr÷ÕNi:Ã\?ÅE4Áñ7ã¾*Ml/Cäè yâ§à·EÜß 'h‚8œì>/§ ô•kß1“(ˆ0·Šo´1æÄ!*2tgftüË+Ï‹/ÜhMÄ7úˆ†cñ¿ë›²Îï1L¬O•°}¤èÿ¹«ƒ«§Ì@!v4Ánd`ZÁG-:²½ÁéöͯFæ ܇ÕàÈpœ ;}8 Ç^ùÐöÐ÷ZþÈð>lècF‘Éxñä0ÈÛc Sqä\>'sŒµIª˜e`Ò‚ØköY”§Ei ºçÐ,+ˆCb!^<åŸ#>"ÁÂLŸš¾OßÅŸ¢a>¥ÁटHø¢ƒMdJ7DâÕæÓ£ÔtÌèÉ–zbu×RÍðé–zb}×R{ë§[ê‰õ]K5çZê‰Õ]KíVŸj©§–›–zX>ÝRODm?<½û#Ã,²#à‚Ý1,úµSÅø–Ý“ÅØ´SÕôHtÄ ßÒRÜmv7E)¶x d•ï6ÄJô¡/o/ºnÕÇ6çyK‹´ê?5A§Ô~wzO Éy÷H‡/ô®‹•XîŠMKª2€àÆú«xBÙ ýJÆòÌïÁIßÔõógÆ2Ÿ›˜qWþŽ/@Ï lˆ…¹¤íoF‰ñKãÙŞ˸\\^˜Yæ φK< $LÓ@»w½Ûí®ó¬Íš¶ªU™m-×)•Ý~lÑJ]R&¤Wðƒ™æÖôƒùÝ!ú?©O#g渴†¿¡CZSË‹—×cžÛºwÒø 3X Þp'm-Oj•ËkD!”E«¶E~½.Ô&/ò±ûí}øÖx0åå=ŠGԛŇ#cö:Ïs‡à×Aè‚ÁQ0rõ¡XùÈX]g¦#ý–‘I4æOH³¸òÕ(ß<|#È­#Òº± [“±­ßj¦ÎˆWOÞE ý_í#S.¶þÁ,Y|×o\ýÒ»@mÚV êìö®ª­9é¨6Ci¨JEµ—jW]ç€ÇØ¡m:THìëïÈž¡3É‚ý×;2£D©Q:÷·ÅêV¬ª²Íвá[’nBð˜gQà ¹á ÎªŒI…ŒOG2Q_Ò3”­­Ÿ»p¬×‡zu›Xãl±®êmÖŠÛL{Ý EIkÈ-žÛz·jwµfæ*'[è¯ÐÕ׊ý¾ïw?¿Ç„aaå~œ<Þdú>&t6*@7iÝØ[@¼ÙmK„X7zÎ\òìùÏ/,jŸ—ØØ_Éjù‹Z9F1ØÐHPEÆ;™×ChbÐM¼²ºøv§f%K‹›n§r·]vÏhócOp˜?(bòFma-רD¶ ¼’~OeÝåèá&s±›seÙ㢮*íWÖ¤o‹—ôÏÇj9QóaV;×[eâ ò2ÛÞ|:oõÔ×I¼ŽEÛ–ãœAný¬my ¬>U;q_í6¹(•ÊâÐOŸ¶»;çõÇVu®jïÌ©mV¿$÷ ßµ…Ê€:þÂ?ìkûžl6ÈÖͦº§¨kPü’€Œ$—™^¡nÛh…© ‰ çµ7Hû\­‹`˜ùÝu­š;Ä‹v?ÂÉî«]ÃÖ?ð!Žk,Û?5ùQ)ÐÐv÷ÐtˆŒKÖ¸¡ŒÄÓÍ}b UÔÓ$Gv c{·3&GBêÖgB?rz‡Æâ”J,7mÁ‘.Á$_Þ0Ç©§W[ñ’_+=X”Wr´9µ°3Ú”¼ãY™×ïõ•žœ ‚çä+1Uw»³æ¸™Éæã”Ú¨_wʤ-ÐÛ q  í8 õ`׈†Ã~6)º¢›†ÝöCAw÷|5¢WÜeuKW‡Öš'ÈÛ[ÆX ‚‰2ØX| ×5°e"òMæ÷h„£àJqIrK½¸µt½mn9™—h°š¾UˆjqO ¦R[B Gx¿¬tàpÃhÚ/g_ø‘ {n³:¿/ê.1H2è2Lw1äÆnÓrBŽ?è…6ó·w+”½þô¯À{(dOè| ™wZ¸­üty4IÀªU‘Æ•E©ÕªíÙ‘%>.‹½ÄJ{dú$™ÿЬârû‘Ëm;R£8²ÛA‹¶ó±hìío„-IƼ½æëŸÞßçý“‰ýþÚM$N#»Øù,ße1×ñR; zµhºÔB%é~¤kiUë4#-ÊQ`I¤ ›?ìU,C|%‹uïŸOkî N2,«JbäŸ)›Í§É’;ÑfËJèvgäI¦Û%lUM‡m»F[ •-@ Si:ë^LmÌ›úªà¥iUn ;‚á'±Ð¯±c§ÈæÈ„ñÚ¸šõó À+¡­ßlvH¼7YmQñ·5ñÓÈ|@ÔÙ6 ¸KzÛÁy‡£–è£Ç½Ä†Ö=„Ö5¡}Ã%tc‘Çd”JÄÕšÔ 4I€²SðèŠ Þºâ’ÙÒTa¾á~KM½´·„ºª~¯xG=•]äæýwàªÑDÏHTåjkS‹&´}íÂ/@; endstream endobj 1579 0 obj << /Type /Page /Parent 1725 0 R /Resources 1581 0 R /Contents 1582 0 R /Annots [ 1580 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1580 0 obj << /Dest [ 479 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 456 541 464 555 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1581 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1582 0 obj << /Length 2015 /Filter /FlateDecode >> stream H‰¤WÛnãF}×WòÔ ,ŠÍ» g+v‚ ìõV’ÅŽJj[P¤"R£ÑþF‚ý‡ýÇ}غ4/²™ Ãb_«ërêtõl>šÌç>h˜?Ž´þá'L}7 ½’i䯩À|3š|_§°¬yõ²M~¼×ðT<×ó4®YŽÆmó0Rï²':MÁ™MyÓÏÆ(8HÝØ¹¼ÇçíÔŠbÚý^ýÇÇѱï9c¸±òRXáþX6kñ•qP’ªó.<ƒü×GØßá\äF*w<µ\ŸÁý!oþev TV®œñTÁ¿ù×ùçü§[ÌÖøžcg~…c¬ÁáppÀÕª¦S ‹¢ñH›žë«¥Z³¤ëùHC#?ŠÝ Ö$.kô$ a ;3zÍæ3K¼SoôÞõÈ#н‡1JŸÇ¨õd{.þ÷®ôÞx±Êšì1/Ì6kÖo¬iRКJúÐyºs˜¯ 5®œ}ø–Y ËuU›ê­Yæù2+Š£ o¡Yc4šì ðSV ¬Ìc^šÕ™" PÓÆÚEõÛ³ãþlx>щ0\pÈ‹‚N”nãøŒjgV5xjâ$8²G(j·3ed,T<‹`YÞÞ€)ŸP æ,d͸ÉíÛb“¸klÁ@Ê­rZ÷˜Ö¢ÜÎ Œ™3öñ³éê†j[dKÖ7«…+€'®78‘ó†£ö *cƽ5ïÕ…3¦ã¨—VEµè1B⇠ý$º”¶B”81»T£Êf7w3@ËC´™ãÈýÙ Èì\«šMû+YKÀâÆV¤"ÄDÆ-V-ØÐɱ’ †#Ø“¶à`/CQÂìÆÉ3¦= S±næ‘Ü8D>wÒÊûŸÑ)>#ÆgÐá³Ï?²O f¦ ý,PŒØoZ   ¸Ë6pÈì(™‘}Êœ½ù£ã>{ûä}¯²Eà«v~àA- :‡y+@fûZ‚VÃÁì ŸUï™ÛbµÝV»-A;óàüßà`/â³Éí%WTZ½›\ÒYZ]Q*êvruM›‘QD¡œ]ÈLjb5’ÜØ©’ 7««ÕñŒ>Ès·¬ÉRvÝÑZÝ˶¿ gÀƒóŽâ¿óŠ?ðJ¢òáÓ}U’±‘00e–—â‡Hü S§žð­'ÂÎÖâÿÄ ­|ñ/>HÄ¿â*ºç­.«êÐM:/‚ý5¿ä÷œµB>˜»Y#ÍŠiiÇ$GYÚ+ìK¤ÅÕÚDP.{²mϪ\`YjÍD0^Ƭd2“Ã¥1%3$'î5ÊšFúùbßt–Ýi |p^fÂ)é–‚®?g›maÎOøƒ”Š$‹# .o•y…‚¾ûæ—ÿ Ò@¤Þ\?å=²¤¾]Ê0>¸ºŠ¶’†ü²Í>ÙìÂWï …d$•äßîæx/¨kªaΟ#I=”úQötp×öÞü¹ÎË'KþwÄì!cÉgðŸéÆÇ²‹‰cgh]ª~Ûçm©OKùØ^]Ó…¢vyq´ë¸"™"!äå!À®$üžÈlò›Í²1›ö'dØÕcô´ÊŠÆ–T%–Ÿ0O¯‹£´Q[ PYÃUyek7›X³ÍøƒO8ÔÛªFxÌÞ„ j)‹¾·>åÂt(U„îBî²ÙÛ3\¸þ„ÉÑ8šÖ¬YOÓ>Wrâóožž¾:&CÐlLÙpý„àëX¢n0•ɳøÌRƒË»žþ7¯(¥F endstream endobj 1583 0 obj << /Type /Page /Parent 1725 0 R /Resources 1591 0 R /Contents 1592 0 R /Annots [ 1584 0 R 1585 0 R 1586 0 R 1587 0 R 1588 0 R 1589 0 R 1590 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1584 0 obj << /A << /S /GoToR /D [ 0 /XYZ null null null ] /F 1125 0 R >> /Type /Annot /Subtype /Link /Rect [ 75 465 160 479 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1585 0 obj << /Dest [ 931 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 332 689 346 703 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1586 0 obj << /Dest [ 1297 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 350 689 363 703 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1587 0 obj << /Dest [ 1556 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 383 689 397 703 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1588 0 obj << /Dest [ 931 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 197 662 210 676 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1589 0 obj << /Dest [ 479 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 384 88 398 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1590 0 obj << /Dest [ 1596 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 125 207 139 221 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1591 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1592 0 obj << /Length 2325 /Filter /FlateDecode >> stream H‰ÌWoã¸ýߟ‚X(ØZQ¿½Üím·ÀõÖŠnŠ-Ó¶ZY2,:¹Üéw¸ïxôͲ'ÙMÑ®S9â¼™yoøíbòz±ˆ…‹õDÅ"Â~Ò2Ó4ÊE1ϼŒ±ØM^¿íKQõ¼&}ÕN^ÿA‰M?‰Â(RXSMfÃðn"Ð#T9Á⟓9oš‹" ç9 'e˜GÎ.ï‰y;²œv”¿Ä˜ÅQ0SI˜Ë¨Ë{ñá¾µ[ÌÄÒ°$ûºß|?ÿ5˜ex>à]f²"Ym§âÃ]m6‡†$R·«`6—âßü?øÇâö˜½‰£0ÇÃâæøwwwa„JöôUCŸ…i|2Ä0 cYù©-[ún1Q¢“8ËÃ$W")²¹’>¦¥8˜ÉzòíâF¢°$zˆÆˆnDˆHF1J}ŒÒ0J]˜x4àY¤IXÄg€*5Í;&(ส‚8XMmZ{=W½Á‹’ÀÃi3yÄ%~àpD³×oì†Àƨúó{ñ]»©[#šš-.‡íªÄ¯ìÜÏ€A¤ ‚v6œÈŸ­pgëÚ†w'ØTuíºÞ¹\ê Îð ‹GlE]+¬ÆDrӻϣò2OèDy—çè Pîûo»Öjx´uû†£[È“Y_yX ùA'ó=Jœ‘«þ™R}r\‹n-´øÌÉ«`– aÚ–sø¢€ÓÓ€.úp/–ºÇY*Žè¢7‡[saKÉKwg|0 ‡O—'„Kï¡n YòÒ9˜}ÆAg#>Ùˆ ÂÓv¨T,²¢ß›ª^ו°ÝYZÕ¼;eÒŸTZsm ’ª}…)eyŒ` `»É› ˆqÖ— ­rFÉ}ñb¡TZ hŽÖôô¨$á­_Â{¬XŸ•ö~o<ˆ(gfe\ JY7ýMà,ŽÇJ<{ù=Gi˜$eqÁ y4'2k$J.ÏQ.HWË9Þ çÄIJßk»QD?`̧姽9 Ï-–æ’²¹·ÝAoØŒ¡áE?»twÑ Ó$+™9T”Œe§3ù¢;¥ ¸)Uþÿß}0Z±ÒV™#² ‘¯Çñ‰+—^×CDeTòµj÷I1þ()@€;H‰A´XÕ Ki*„ƒG÷ânkü¤OIÏ>\>¨ŠÕ Ê‚J‰jšÈ¤7àßV¬þU+¼I7¹â0ݹ¹ÚšU˜:«°wf­u0”_âh5r‚â¾Ñ©¹û=Q›MWi[CR˜y,3NŸ¨ë@f ½ß7µ_²ÒAN®_TyÑèÉ3ÇYlÍcq}ë€÷’ðÞóÖ±?ꦹÇ÷QU·3½@s³ËcÝØÒ|§[:]"7fGûÉW|³' ó±€Yl›Â ÅÇ@ß`ôvcô²a 3NÂ85†¢›B›6º­v:Ðw³ gÄëý¡?˜þœö¼²ú°18`)-¦oäÀg`²sFáŠÇzÒˇ³@ƒÕB>‡¿œ"a¤Ø7Š>l ÷ $léݟΫބ™ ò#´Æ°ÞHסgD8?Ë7Ö ‹Ÿ „+ܯִ­a‘¢T"ÍQ©@ÄÔ槦pd$•QZÁXš—'JûÂgÄâ&Å‚„˜Jcˆ¢BÙÎ~M…n:LqÖôH ¼„J·º0L C½ÚÕ-ûpÆ ]^ö0:jLfåOÀ<ÛÔÿòôÁÙôßtÒU”kíÝ…ÊæWrÁ¥D1œHPJyÎ ^™+ù¤ò«lhô¸ÎÐS•1ÆÐ˜mÙ¯ë׎Z?£L]Àˆ[äqûÃzPvÆ=æ^ÎãT»´dpä'¢ÄÚ6÷ÂÍ9Hp¹=R¬Û0ðì~h Ü<‚™`ÛsŽ=m;©ö…÷jt_yÿYÂàæÞý€ ·û2÷ɇߣûE„oäp¯K\NÎÝBuðyµßãÑËDŸñvPE+ºœ’ó¿»‘ð…ÎþiO¢™ ííZÕ¹9JGYoÄ­v–p]…Ë`Z3õÇ0æe1“ þo½$Í@>ç^zÙè£Ñ‹¹/;kôJw!T²×•­oÍ5%p,ß «éà®óÉãøC|ÂÛÛóþ\'–àÞ—ývØW»E=CNË®ƒ µ~s¤tˆågÚ älƒÜÖ“ÊûaGC—“ÄÝ·*70n€{ ´¦§ŒnntEêÏw8‘ H¤ŸÇ Õ@—…||;‰Ÿï‘’‡:†®G¢Û%[º-¯uÇ`U÷œ|TzCî±€1É2…@†V hfÊSÔ ¹Á"Jß\ÒRw#îÐÌž¤œÇb·se¯½ }øËû€n³“å Z¢sšFЦA‹G°?`e…´N²«% 7o Á/øÝäòNc­{fîIeëŸHjÚA°h†˜”`ð"3ìIÅLGwRçŽoö å>§X•çò6 Ê5î%ÜÍQöSôa·O;ŠúKJðÂM¦òåP¼«lY6ìB6ž3$g^ºãAÑÀ¾Nx(Œ'›~Å K³}p„[CŠ£®§Åõ‰ d1ïv;B§!«tÅQþºº'csBÉnu¬,!2¹‘Ô P·¹ë¬‹bâJ«gã:#îB3ú×ßOq¡ 1Ö™ÝK'[°‡ÎZø¬õVÖžÙá¿¡w{2Øc¬}¨;@šPÆlpF2^ܨœq ’—‰B{•çB’\6¥’$ îN\U‡Š[B~4hü¹Ð=Aó¯¡"<ÏRâ6¼ýñ­p Âb‚½nÅf[˜&YI¾¦*ºèÓÑ‹˦±g.Û/kŽŠqÁM3ÍIþŸ4'þšs.|dÁ À‰Ç°ëÂqœ“Ü”þ3Í[(× endstream endobj 1593 0 obj << /Type /Page /Parent 1725 0 R /Resources 1594 0 R /Contents 1595 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1594 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1595 0 obj << /Length 735 /Filter /FlateDecode >> stream H‰lTÍrÓ0¾û)ö(ÍĪäÿi`:0eˆO´Y±M»Øžð ¼ïÈ]Ùi t2IV«ýù¾o׾ν«<@A¾÷T?øeˆ"™@ºŽE’Éòƒwµ20ƒ‹‘0˜Ö»ºÙ*(O )ÆÏ?›“Ç>èÒ‚ZKàùWoí’ÖJ±N°p˜‰DÎu]NàÒÉŠʾc¿ôúä¾ EÂd»lOíX¡'`–c%6Ô¼ºYÁçßÜñÜã],bVsÉLµ‚íT?l߸"!ÓmÁý5ƒŸî—ÉßyޱcH‘à!>‡`š&ÁC¡Ø@]-µÅÒØR )EÀÌâª\¥7¹§ /ˆ& ÂTd$ •äeÐ[oï]çOb„ Cäßj\Ô•¤sê]&sÖ/M¤Àïœò’üw,ç "S¨]=  F·°³@6r ÿccÏ#‘±£¥cý€‡Ê’Ú\Q3Ç¿w‘·ø«ض¬[  ;Z3‚©ô_Z×f8Rdšò#Ö˜c£ÇSp­ƒVÂæG½ØÓ­ ^š=P‰ãÁZ&å+Ѐ¦TOŒÉ$ÆÝtӠ̦ë‹AÀÛ=ÒÀ éqÞØl¬»Ùhqy"xe[½kl±r|m»rª[B±’€ ÓBz§ ÷lûñº›cyŽºçPtv€¶¡µ¶p2^ð†g¼„ü<¡`Æ[éï4âmœ&#,Ð,6uÇuã´×#DÊ|R¸$•R‡Ê ÈÝ59föùL¦•г†S½i>œæ‚ðíhûÓs¹f÷¾ï0r?Å‘œ«.ü]€ÛœGk÷]o_ŒŠ/D㙨զ¢ÅC',ÀZC*¾lFà6ƒhÇ YÁ#3F{³Íœ¶‚©ª±Ž©ÝsÂE4MwxÔnmœ¯|àÏ­F²nqo>-…¨ñ?ûšÍûŠ—‚Ófþ?>÷nr/5÷8â“þG€ï×LÞ endstream endobj 1596 0 obj << /Type /Page /Parent 1726 0 R /Resources 1602 0 R /Contents 1603 0 R /Annots [ 1597 0 R 1598 0 R 1599 0 R 1600 0 R 1601 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1597 0 obj << /Dest [ 1583 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 437 709 458 723 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1598 0 obj << /Dest [ 931 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 332 695 346 709 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1599 0 obj << /Dest [ 1297 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 350 695 363 709 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1600 0 obj << /Dest [ 1556 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 383 695 397 709 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1601 0 obj << /Dest [ 931 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 197 668 210 682 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1602 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1603 0 obj << /Length 2208 /Filter /FlateDecode >> stream H‰ÜWÛŽÛÈ}×W4æ© H4›¤(Ê0 ØÞÅ& `!b‡jIL(R![ž(’È?îÞªj‘ÆÞ ²  0bߪ«OUŸSýv5y±ZÅʨÕfbbá?i‡iej±œ‡Y%jµŸ¼x×çªìyN¤ú²™¼øîƒQÛ~…Qd0§œÌΟý»bk•Y¬þ2Yò¢¥ZDá2ƒá$³Hìòš˜—Ó×<£Õõ¿bôÎâ(˜™$Ìt”«û“úpjÜ=±¶,é¾êÕ›ï¦ê?³9ÚÆæá\WA¤ËÝT}x¨Ü?lW³‘DÍ:˜-µú'ÿþ´úÍ„O̧‰£0Ccõ ú؃‡‡‡0HB£{ÚÕÒ¶0-C|Fa¬KßµcKß®&FUjϳ0ÉŒJaž«ÌI…3¦¹êìd3y»ÀH ¦DÑÑÍè!F©QF©„‰¿Îx.Ò$\Ä€F ‘‘ã˜, ÀH½*ƒx.t]ÙÆ½~©Þ9°iÙ~Ϙ`RuÕX…Ö\_ΆLÏZôgº!T9©²m6ß)¹. - *¿@¹‚—½í},¿N¾áHqFùÅ‘ÌùDþ@ïÚÆps­ªæ%‡d¡³>§³pqêÊ€yÕŸÞòÏ|„íkÕnTó°– Î0óü^Vø…i’Ä„c™ÅˆäÀs†Ï¯ÓÞÃ5îm/ë…BŸešyžàÈ×LóïL<„U¿Rx}µû/pÃxá|LÙù#fùìAì‘^ÍvªÊc×Á¯ú¤îLÝM™kðiðÔNtÌÿï„ážÏèdŒƒ¹Èèo8 œ¸žÍu3ºîSøWÕÖöntýx8´CÈ F Ø~¾¢1ç(x¢+ï)•'õŠxÈ…íAKÖ§f0£Œ|sDU)K³4Vû3•Y®; ¹›ªÃyÎ3ݘ›9ÄÔ‹˜9ùIç‹ÐÛ[…êíé’ª®Ž÷QËÅsSáÏJÞUÛÝm!M`8½x}Ò TU8±àª½%}øÃÎ6Ã=ªšÊUE]Ín‘¦Ãh|‰©`–tdaÐ!}OUË¥Ûáºò‰ƒ#ïyùÍM™†õSöÚ;\]»'…4ãeQ×$ÎE‰¬eŽNõ, "Ò4M*Ö {éo,3ÖߪÛ¿ÿSϾ v¨~Ûà’UujʆÛP=xn8ø‡Î~æsH§dEÏ„ícOA › Sö‡Ú:[Ÿ|ˆK^¶@QuOf*Mš¸´§uÎ-Kb)hÞ+š¢N¥QÒÞL‡êgÉEš  ÎÎ¥ì°i<(E f_ŽJAå¦C$w¯¥¦z)ÌÏ <ùÐùjŠ8·Wš;îU{ëv-w¯¥ã«ueÍ©êþOÖ•ÿ3Ú—:b()Ú¨‚xŒE9tùCeä’“f»~©îPÊRoÛX(ÁÝ}Ñx¼èª¢FS×~=§È¤úî—U9‰¾kÈ•ðËè=~=GéOJÎ/R:%|¤šd®Áœ[kOñLðÉ5ÁÌÎì=0{Ýn+.àbÜPá7™28× rûyð¨ž%`J&û Ó¢òÅ=Xáò±`Õ“…ð¢®qµÝ±k艳+jh|®k<=,³§³;VŽGYsùú,¦ŠŠ`–Ž+šùxÖÞ¦n)¯ð΃“EÉ•]Ùvk \n €êØ ÚŸ«uª7M Û]NI®ß2TÄÓªFIŽøá]{”sÐõG’Ý[„G®UK LG»…6‘绳8£!A¬‘$E­è¦Ääi”.òEÚ$# ß{T©.ü”¶‘¡ú5üSì:ñÙLy¬}Ç”Üfƒ0í/"åFô/ód?}äÕ»Ò‹ ïbªìt’©ê©‘¿L3~Cä|­|ÏÞÍ“Á§ ðÜÃé"+ä™t~5­ådH6L¨è•jh˜.ÖÚ–íº¸¯å•E܇?K†âùø¢ScO]Òc'Æ=o`9JXÞÔ7P@¦krFÜHô” 9õ“å7T®f~Žw`Kt˜éºw“Öžê²\v“)3ÙYqßX¼p’H'â‰åY —ÉÛj¸cý­DÓni⨃kR¿›RRç‹!lÝg‰$H |Êy5ç¨/d³%çæ|DCóþ‰–qzT-ôÙ“%‹ îX8–@êò÷éÛÕäÇ }q endstream endobj 1604 0 obj << /Type /Page /Parent 1726 0 R /Resources 1608 0 R /Contents 1609 0 R /Annots [ 1605 0 R 1606 0 R 1607 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1605 0 obj << /Dest [ 1613 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 152 343 180 357 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1606 0 obj << /Dest [ 1604 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 193 94 207 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1607 0 obj << /Dest [ 1604 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 241 193 262 207 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1608 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1609 0 obj << /Length 2095 /Filter /FlateDecode >> stream H‰ìWÍŽãÆ¾ë){j#.I‘i ˆ=Ž1A6 <ÚKvràH­Qg)RáÏòƒäòŽ9䫪&¥ÑjwlØ0 Ä ²›Õõ__U½˜¼],"ªÅzF*À8‹ü8R5Ï?Í‚™Zl'o¿i3µl™&Pí²š¼ýî>TOí$ðƒ Ír2^÷ý·âɨ0”·øç$çC¹š~ž‚ñ,óÓ@øò™ˆÓ[’Òéú?v§QàMÙŸê Su¨º v"m^?ÒK·µaNß.&¡²j%©?KC5›ûY¦ÒžT°1ÎTc&ëÉ׋ѳ$ÁKo½G4{1Š]Œb?ˆAû³Y6W²œ:Ox5Ç Ð+¦~ìe~¦Õõʬ‹¾Ä"Ô]Ñï´]ydY-ïKsó•º7ZÞ=?áO¤;UÕ GBÇì}³]%ÐûTˆ©êÑÑîdki×é#{GÇ[=©½-Kõhá¼RÅ š”ÿhûÇ5j>CÛÆ‹)!HÚ;~½õ¢c$%†¾ºóÔ Ñ£ äȶ(G‘W|^˜våÞ›ƒ® K3}¸d>È;Zê¶EÀ3• ìvZqɉMÇxEÇ€E±å¦(KS=y9iT½rÒ¿S+‚ëžÎtEÜ‹"(ÛK#áÈ9‰èõÖ^¬ky'“–ò0«ë((çÞ}£“})é±v,ܹˆXZ8´3²GákbtÃÓelhm×­«Öÿ)Hšä–—kÀ àh‚ˆëÊì[Ó¶Bº§Ô†L×ï…ª î•£º»U¡"JkÚ×!4I?rú«gôK'kœó0u]ðy.Êžr mý€úˆ(v𜡻¦7_¶ú Hx’iÇ´pñ¸[sæ+ uBË)rÙtWc¬ô Ò;oŠ®œ¡~K]P§wu£Ö¼“k[öyð‚àÃK«º2À6t㜨1²Ý•¦3¨#+q6{uÏT"IÑÓßý™‘ÚSìÔCN’Rv½F)éžžÉg:²gÈjuç݃Dd7°DÈŒZ‚tרÌ_Õ‚‘\7Dè̃e Ü3#½5'„™ë¦NÛÊvÖ(ÇnëQ0¦çpkAÚñƒnke;|ý±U¥ýh8ÇmÕÚ°.¢ùW‚«¶&­v#@1¾uÈëVm‹,úWoÃIñ“(ŽCš Of¹Ùy®‚RrH]×EG*Jš¾±À—ï)ÉúˆELÆ4 Uï¿¿S8ŸhYø…üÏs}xb Ú—!òwhú?„¦ü%4uµÀ׌ËNáCw1HGö„ún8?èCµ´öBnñBË)ôùùæ|½vã’”ܳ÷(å½DUÜP± !®©)2pa”“p˜`·ÙO'Ô½˜÷ðEVwEy¼D6” žìe)%lÿÑCà'ðF>‰îq í|yý=ºìÖ»÷^ÿ“*à´¾%ÿ#˜‚P3õx|¦æ=‚>aÁËã”–2æF”$òž`"´ua¨ O×âv¢=ÞU~ ^F9æÄ”úÒ€—éy³Bç€9ô‰ëv[4צü)8ƒ_Œ˜Q";ÈdJ%Œ¸›zÍþ|–ºÆs!l¬Lš¯cg”ÆîñïØù[ÃÎÏ\˜¨4"M×”“‹¥y'Ó¯9¸UuçîF({ YQéÊ]™„ú©/ G÷b¿“•5ƒ@)Ü}qà&Mq"!ö©wÇV‚,×|ã˜÷·šÉBþ-¼0q·®KòTæ•!øƒÃIB½wËk沸PËœÒ+Ar¦O?ôæ .±ÛodP5,G]2Ûéƒ'è –ZŸ° ¤(…N¸!FÖêt¶uê±Ñ±„`\ µŽ2w§Ù×ö¤ eü\ «Àͦx¶uß ¿Tj@±@ÜP/©ñÑÍ·h®8h4zïeóx£Do¦¬!‡ ™cruñ ­sÞÈþbµ®„A€a×Ò¯8—‚ 7p…;Αn„äk,,.Kvï£4¡ˆgwé}CcŠ4wñ9ôAÊ!0¬É¾½;-ù·„©‰,…<_ý±G4Ÿ8ù| ž9'›¦eØÝÚ§MÇ¿^­(¬F:¶)yï±nNn„IrÝà.Äj¿1·ÚD‹<û¤˜}œGà¾Å¤r‹É¨9þ¥îhÌn,@Æ­Ë7©O¦³)w-yôÉÀt&„â.èáŽ×š†L%BBµkêÇÒMsf+™iðg‡{]L¤ˆL‡« û—<ÍOàwÝÊ6ŠR¤7SFa,†ÍÖ’ÝsÍ!w÷d¦ß.&ÿWâî endstream endobj 1610 0 obj << /Type /Page /Parent 1726 0 R /Resources 1611 0 R /Contents 1612 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1611 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1612 0 obj << /Length 1909 /Filter /FlateDecode >> stream H‰ìWÉŽÛF½ë+ ¾˜ i."EÛ Œ#ÀFì(²)1 š2—‘åÉ?äsHUus™Íã ð%ŒØkm]õúõÙjöhµòÁƒU>ó|pñ?óØwæs7‚Å2t¢Ø `µ›=zÖÄ6¼Æ…&U³G¿^x°if®ãº®Igvß<̬×ÉF‚· @¬þš-yÓ®³ŒPp;‘«åòŸ·S+Œh÷;ëGmß¶8‘寰>ÂÅQµ[ñ-)P’Õ <ýõþøWØ!ökœ Ð*„k¥Û¸8í'Y—,$°• {iÁßü+þ\ý6cÙßu"쬞ã[p88žÕVIjQ4ªt°é:¾•š¡-Kz±šyPÀÌ#'ˆ<NCäa$}œÇPËY>;[ Á<\â^Æ]—"bqôðŒææŒæŽ;Çs'âènÔE: U3QÅUì“9±ˆ1pºïÚL^Š»yÒ6eÅͺ›>y OËCrl ‘*ƒç¸0•€ó¡õÒì¨ iM yø`£«®· êeææLî”ì ™ý%àÆ!é=à·4àWViRf뮑õŠë E†îB¸~vÏ‹“¦9Tu†ˆx^m L×ÈRt„%7i刂aÌ(è¹ÁpXYÒ&뤹^}7¡/ 0 "2ö§@_ð£ OË …úö&š_À߆y¬qÁP¦*u7ä÷@ÞPåž?–ƒ¯Y â[Ä™+ž§Pˆ8ŒF¡Uï’¶À"ëç:ýÅs£´Á$RS<Äk×£]˜H¥`^q„æÖ‚X áÅ–W›4Ò’¨b,[-1_%eF…&YVšôVh,¹¥ðõ±ÛÓsG¾•¾:ï-MQÖ)_ZœJê1*k ´ ì𜠛µ!Õöh8vO`Ý€3+:tûºMh‹¶ªt[WŠP1¶>I vt–ƒÌ‡ºq•§´Ã´È‹,!v¸°ZþF"ãfuûá°çH÷Ì쥤á9:ÚM+Õ_äDºÑ4fm¥´°ÚöséÌŽ^µQ¡'{ň”N4,­MãCg„÷œ>ÍÞôŒ-fMnLÄÌáïV»ffÍÚ-FÐìÖ*’5‹ÞšÌ˜3„©í}ù¢ÜÈ© ýïH«ÂÛ1ieƒ'ê| ¹»˜b†Ü²8ouÏE F{OU¥‘›»k¼I¸Ø¸‡(ž>†×µ¼ÔU—&g߆Ѐ+k;¢Ú >R4Äz µ)¥M·sÅH~¯Zº'ðÇ$-ÙíKÍ?2SjAǪk›ÛiähžgÌËdY\2¹ãË9hOlñ¦Áf#¨œùâ#¥6ðÄ{Îñ!ÖœNbA&õJ½kƒ×†Ï€)ÉyOÅ]½A_PäP§÷‹ŒºDeÂŽ üFH¯nÖ[äW°t*pÎ|ÚùQÊfë8ªÏCC4>m0F»Rª´Ê ¾îÕùª¹½¥âU4§6šáR6‹ØÂó½î|Ä€8þip÷ÃXép÷àã®|@oÜûà°Æž~>¸~¾“¢ú¼ÓhÿnŽz s[1C"fèi` ¯Khè¨ikâUÊ´Y˜Ä¸`_&DXåÇÞ[ÄÞÖt-xÌE†…|0OSAÌ´÷Þ¾b1ç" zÊùS±IZþN,aV}».ÝÞÎOÇêr ßUµ™çøäÄ,Òä’{Ûíe×2É’5úZa¨ úÞœÑóti½Å¡jHZ~©j,ÿ#${zÄjO¶nVüäð3¹î6Xäº@X›mÕ•D¾ÜÉ×Ì›3Ôf^µ/V³ÿwÓEë endstream endobj 1613 0 obj << /Type /Page /Parent 1726 0 R /Resources 1614 0 R /Contents 1615 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1614 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F9 1677 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1615 0 obj << /Length 1800 /Filter /FlateDecode >> stream H‰ìWÉnãFE®úŠ‚/ib›;)a``Òšã–J»Rì?¢x¨™@©Ó)µÙÛwâeºŠ·y£ÔD© 9ÖEY¤î×>'´,«7-ðúLô”ß ÃŽ4¥xf5/ ýDfCex˜<igŸ¸íPõ¯êè5fn©ÅçZ¤.¬ø£duêl 3¢|U¢Ór‘¸ºÂŒ„¹V‘òZ=E£¥îÖÙr­mذÈt™) ·ê(» “¹GŠ`µ;$Zî)ÎC’"ò È—‘«ìr[ÅMV^—(šÕp×HÔ²P¥'¥‚£óƒN Uš iq‰NŒYØ9fR Þ&9>Ö…Èò{Ã|eQâõ ]õ%Õ7ÓM“—j q•êŸ61ŠPÈ8‡`S•«,O¸9¦Fe3p膄y“å9Ùi5M| KL“‹¶Z^My/¾vØ3-Tn­ãŠo%&‡hY&é«¥rtm4F!yÄ"Ö|npQEà¨T•|¡o•†£¢¬¢Â–Enpé¸üÊ^V‘0}¾¥eÇZз4}¸Iàõ壖ɻ1ì«ç¢uXyº’×òîyžw”ª·›MY5°nš zmb™e¾øÈåY=†º¼J»Ãq^—t;ZÇ÷ˆU™çåc õŠsἕ2Ÿê‚óÚÙïÖAËð'6+ÜàÖÓyõW˜×]`¤ؾ*W‡Å§¯ÿQtWä;1ŸÏÌ´ˆ/r å8—Ñï#›]±%šºBAÃŽ HCL¬‚üÜa”(f¦-°vxõôøø nÒ³g¥vyó‰Þ‡nתþžÏA}ß0ۯĀ7§¯¾3K,>fV¬*Ìæ¸ìƒÓ…#î‹>¸GåEz3ͪ$f¾1H’b&Ÿê.ÎQ7g|œ`Ev=×6Ý7§d­÷ ^½ LÄÙ!ü#¨­A z ïR°5, ’››c‚Ô¹AHø ãâˆÙ›GZ¥Fˆ{€§ ÓòFß½-¯K\Ý:‹“ûÁWg'I•Ö5ºº )UPMEv=þ)³š7™`gÎja§Úïg5›‰ÓÏjøq2†gè%õRª“¼¿‰ëzWV >A€\1…YyIí ½§^L¨À ô ×Q»nZ¤çºaáq%og™ ›Ü ÑN†ª‰îO*wAÏGmt>Ö hö-» XŒ¡Eþ 㨚 õÛ⣇΃Cx~³eÁ|ÑûŠì¾lÙºlí i8 ~;)º"áºÄq ·‚/ÃÁª3‡…û&ÙA }pœ½gVZp[^óÔÎ-XTK|ýâÊ Kx’ƒöÇÁ$ƒs(²Ÿ1ÏU‚ôcyÓ)×\`ºì=ˆºñêÃóÝõ\é콊º¯m÷ùîaz”ïåò§z]Ö ¥;Îw7·¼˜ÂYUò‘j„·:ëÇ_e.J<Õ•ûdüdc,Ãéd8Z!CÅÞ¥·@@e¾NÕ—ê÷E»àIbZù‚ʸگÛÓw|øi÷O%ðï–ÿ\ß;&°ûÄ÷hÚ¾ ûW¯ùÕ±ÿìCâODûöÙ~þæÅ7slÎê‰ù¥’ªþŸ4^gΣXÒ4Ôüa™íX˜YÖ}m®e:%¶ÏÆë\nûø†7i§í#'Sî×”æhx¼ÅbôhjÛ!> ¼~û´ºkŸYæ°n(4Páóé½Káó„Ú¾¦ùEÇ/Ðõ=ê–D÷M¬öj5 îJõ[ÂÓ#¼'1CÔ¶þó6Û['ïGÚØÿý¯wöO¶0¼ZŒþxšé endstream endobj 1616 0 obj << /Type /Page /Parent 1726 0 R /Resources 1619 0 R /Contents 1620 0 R /Annots [ 1617 0 R 1618 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1617 0 obj << /Dest [ 1016 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 378 460 406 474 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1618 0 obj << /Dest [ 672 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 149 202 165 216 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1619 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1620 0 obj << /Length 2103 /Filter /FlateDecode >> stream H‰ìWÛnãÈ}×Wü’&`ѼK( ff“ f€E¬¼$“šjYL(’![V´’Ø܇œªnêâ±g¼›A€,»»ººªºêœê7ËÑÍrQHËõ(Œ(À~’iä'IÑd–úÙ4ˆi¹ݼí§Tô"P_Ô£›w·!Ý÷£À‚2Åh<|îGêûü^S8KÉ[þm4“M3šþ,ƒâxêgÕ+{"ÙÎ_iÆ»ÿ¢~Œ0;ŽoÆ~¦‚)ÝèöP› f"¥=hR}ÙÓëw×ô矼qŠq‡µÔOUéªØ\Óí¾4?è®%±Êë•7ž)ú—ü÷þºüÃH<o¢ÀÏ0X~ƒ9±`¿ßû^쇪çS5 Õ8ÒÇgàGªpSÑôírRI£(Íü8 )žøÓ)e!"Ið1™R§GëÑ›å1q‘à2§è%ÑÃ%îŽ?H øq<A¤©?‰Î¢Š9UH‰Oa懙7E,hnº¼îÛ¦3»^ËT·ðÂ@]ŸV¼ fM›÷^r´÷M·Z¼¢÷Í}Y¶¤ÊˆHãá¸xˆ¨ŸÄqDc8„Ž§ÍŠðhËÌÚÒémc4ßiñá=ôLõº{ÐÕ§§óèi0ó#——¢Üj|ÛÔ&/k½¢²~%—4QGe.Ë32\3ç%ù:/ªR×f1DÜ>– ðǾ _¦î伦žnN?s°Õ‘u¤r>n¡»&[Âü¬ñãˆZ¾Ñë|W{øô ^É­º©õç½áðXÙ6ÎêõC^Vù]¥9̃‚' £*DÖТÙnQ‡Tážè©Åu‹âŠ@ð (÷ÀÇéá ­Ìã¬x’àt“L .ý ““M®*–Êeâ°²—\[{ м‘Ùn››²©iXÝÙ_dÚe’°y¿·Z–ß30ÌwÀŒÚ”V ÉOTá”Ø9‚9=쨬¦ÁE;µùje¿´½Ø°bPœ»)·Ûýî`÷ ±’ÓTk½r8ð»Ì(—“D³ÐI$Ïã÷³1)D~”0ül?©ì„I  ¬šj‹Nÿc§{ ˆù£’i«"WPN«Üä½idÜé/CF𤗔sÄ£ÿ xÄ_ <Äâì”Â.ˆóª)òªµ@Ûì@~ýÓèšos?º,œñð‰X—÷»ÎÒϺ¬´OgÐ~ŒwfÃ6פ}@•-Â?g[3uÄg±aL,Æ ùCnk¦îí"卨¼| ¹saÊÓ äV—©‹M×Ôåiwbu¦qªÎOCæ8ýBîT•܆ª¾¯´›qÇÙÁ…BðTÌžè >ªM³×£^“ÎáI†—…eaR6j¦\ ¥`·ù—_ènà÷ƒäºÀþw '˶Ï_ðú9ÕÛÖ¡©?zþ±ä_¼q6u×?0otËBº~ÄGBÍW–^Q+¹}XFõvZæ¥_—]†Çsª~ÓŸ‘ñäEd'(ôì¬+ø d<9óÉÊ)ÇÉŠ¢™’Œå)#­×ghì«õ“]þñÕã^:«;âÈSzJ¤Ý¿ˆcqóZRÕÛÖ>O¨ÿl½„íÎn59ÞÈÐý£ÓÁycÎ Ð\ëÈM¶uó¸#³¾¥µÆ[Ï-xæЪëž÷ÉE šéâ¶¥PXµå~¹­ñà C‡ÓúûM³«V "OÂÕ§Áµ‘: ´±t!к¢}).hB£ˆJ˜XhMUEgÄ$؉ÊZZa&- ÁäÉ/¡ÐÒݨ ë¢jì¾É>wf_0™ÜÒåÈ5ƒq ŸþdÇ;PËášøb3døµœ0s|ºm% :>´*ÿ¤–ŒTÖpsuMWZÂóßí¶+Ë$¼²åDCèÊÊ 6…ïÍøð7Ö6!oãÎm$`ÛÁŒ¡_àú’¼O7 7»kÛ¦3Äy…œév…Ùu¸ÆŽθÂ?ù”YŸbö©¿i»ò!7š“ÿ@sÔqÓ¬×e¡¯­˜®¦·ïøª"õݸ7„݂ѧ˜=ÕlYŸ£œ5£Fêwòÿ½Çæ¼¾]Êè·°N}(«JwW>}g;D+®yI³ÉÛ–0<Ëuvçgƒ€m;±Ë. ¹§ÊÉrCúáýc}×thvTÅ;½†zh|Y÷æ¶-ê~“jZî¤zépÚ¦ïË;n©𼄜Ã,~“sö–,CGàTø:ïÝ }k“ð€p&CóÔsk'¢5ÇVLݼãËlÆè¢3c~…l,ÞLOét\™}³ÏåÝ{àòÚ¡Ô;¤MŒ²åVlk¨.—‰¬=)ÙÛâ²sîè~™¿þCNRûê=º3…;_z þÊØýϾ!@«î]§O’£±•. $Ì^k~h9rƒOÖt‡ÿç4SÐ#öµ/ÔŸåÎËo—£Ò8 endstream endobj 1621 0 obj << /Type /Page /Parent 1726 0 R /Resources 1625 0 R /Contents 1626 0 R /Annots [ 1622 0 R 1623 0 R 1624 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1622 0 obj << /Dest [ 1621 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 338 652 373 666 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1623 0 obj << /Dest [ 1616 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 452 420 487 434 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1624 0 obj << /Dest [ 672 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 71 202 88 216 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1625 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 1668 0 R /F9 1677 0 R /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1626 0 obj << /Length 2450 /Filter /FlateDecode >> stream H‰äWÛŽÛÈE^õyIÑ$Å› ÃÀÚÞ]ìÂYå%;yà­×¼("5ZåCòùÇ<äTUS¤.^Hò’À€‡êKuuS§ªß­f¯V«@ùjµžùòðÂ4pÃЋU²ŒÜ8õjUÏ^½ïR•w¼ÆS]ÞÌ^}ÿà«çn湞çcM>›Ÿ‡™þcöl”¿Œ•³úe¶äMK•xî2†áEêÆžØå=o§¯(¦Ý?ëž3÷n¬½T=Õñé7 ´q`Iwe§¾ùþ^ýùŸÎ<Âïæ"7Ò¥ãé|s¯eÿ7³«ØÈBgMáÌ—Zýÿwþ²úqÆ7æÛžãÇêÆØƒÃáà: ××jèX˜Æ‘.>=7йÚ°¥oW3_•jD±»ˆ}µHÜ4U±H*Ü1LÕÎÌÖ³w«S0>–xçÑ£ëQD4GïÕwD¡ë…‚ áL¢?Å‚þlYÊœû‘\ÌZ»xš^b,ƒÖ@Âr×ÚCæ$¸øñNÕ_ "Û9€ê7Y¯òÌ7ŽÿŸ«³Â¨¶Á£òªt8ˆˆkhš^e;'„)£dù8Ñ·¼ålXÖ¾g#Ÿ àÒÁÍùqØkqžû.]á® Öb±°­t´•jq%Õg«FGà»izW ›|t‰åœÿJ“ŒçéC_Œ’3_ k'@lvm->ó(îW›L¾‡0è6ÙвP«VÀ‘éêȈN6<3膆bì®í¤Ä{ ‘²ã;¤QHÑ44ÍîÅì\õÞ™S¨7l÷ü3X^êÂY ötàÑ',]|yb*}R ,ÕˆÅXÓ¡êPV•z2ª|nÚ¸à\᪇¶6}YÙ ò¬ªäØBÝí·Žïé‚u'ëo™m›Š2¢-Ì×r#&}õþ£Ü83IiŽZn¬Án¡ýRi@YƒèP:#c/öïäÑ¥‘’ßtQÉ5ÄǦ0dRV iG¡‹ì°]cí3¾öI¶¥$Û¸ò"Ý(ú Ø`%Hcóœ¼Åßom3â†úØÃB:là¹Ì¼¸dDj!û r‡ƒ±á†Åd©°Ô€·Ñ(IìàËÛ\«ðOmo^+BÒJaËZ;ä¹*•·Í/’Æû&ïK\Õp£ÞˆŽMþ–oý¨­Â¢l#°‰»xtÎEW ‘óöæÄ<—g{»òóR=÷†%úJ”G›Oe¬àüð™¤þ“ýÛ1ÅWÞÖ[ÊR_Ä!Ô½7[0ø°+ûÞØK3èmÓHÚ¦ïT»ž*Õoô¨íwÕµ¸¨ý®Hä›ä Fç7‰ÐEr'Ê>ŠJ¤™ÁÞ¨q¨uæ)†j‡ 5 ÙÒ”ºã=UK—HÉ)Šn¡Ä›-œ’+ÒwŽ«>²mtD0øÉÊÉò{&Ðéd6[Ûy6%V¤þ ”ÈD”E;˜Pô!„º…o2â›H,ˆ(¡%èÅÌ9ZNås¢-Z}ö”m¶| ¯˜æŠ'‡e"BØÌÀ‡› ŽŽû'Çc9ÛçúáÞøGÑ\œ,#&U2Ò²–‡°.XŠ9Ykv,ß8°8mkEMèÝ êœÌWmV B• ›@¯WãÇ„X>Ü*Dtí—2™URßV«ð¼ÀL‹4¹¨rQ”ºQ˜u¶¯zñ!ý‚rùôÌœ¥Þ³Öômm÷%«¦æv*ÕGU 9w5ÃðÛñºYô7/YYeO•!/¢‹8]NˆCMO… Ç+ÑS¥*D†~#â~#±eñ Ѽ,á£K—*8bçYìV¼cs€Ûwˆ ´Ìüº­J°]—=tlÇL막€î„â á–ßÒ¥Iƒm¡ì%¸^¨k“Þ‡$”nJq¸©w×a»®êÔñf;G©”x=SÓD–hà*ŠóCv´û*®K䬴öy—ß+Te ó†;ƒ»ÊŠ=·ÚÕØš‘ûµG#Ŧ‹oF࣡¯ì.ä ÂRí*v¹m »ü¨¥SXsÉ÷“}¯àa4_žJ¾ZÓŒœOu;ÔÔ1ùN¾²I•ƒÚ ]YPOa½†<ß|Í\“¤Ê‚Ä'•2¶ô¸ôgººœø9”½VÜà½%ue‘¦Ëú¾72ŠpÛJSæ-œypæúÜቪ-/5½FM»Zì#9µ¸Æ0º×W¿N¢¯)0‹ÃÁ¤ÀÐg>›B-7QÀÛ›ªEùÝf=¤;ÖókoxïNÝÁ1Ô^é%Uržì³®ÇT»•ŸX×qƒ¯¨F‹ ¡ Žpðï«.Ý -RO áÞ@,(Ù…ÅMÇmä³FùÌmêmõÿSinø´âDiK{ZŸ=[MÞŠç%=+KyGØEN^n%3¦å½)côZAßÈÏ‚Ë9•…|YSò¿XožY•,G¤má¦ÓJ`ZkÂU²Å O4iíp•á/îªw“:Ò_‰Í|Ä|ªåZÛýnpŠÚxyær%MéEXgŸXŒ}#RѦjTƒ˜%žPɪ0»Nzô-Ô vÐÑ[˜.ß•[W“%WDŠNízP&Û¡ùÎæ7«Øu† O!›VªÊàÏJýEøÃGæZyVýÛ¡œê `•œj¨  ï3HJŠòÍ•îWå úŽž¦8T‰Ö¡Ä\÷tÎýíúŽ×åpš{ nK< }§Øh*T-àÿ±äG¬¹W àáRðA—ɘ±VwªÛo·íÁ(+´œ2ÉG$ž-HrN¾]Ӯȑ[LÝ4Ü•C4Þÿõova.éË;ÐK#uöR?µ<<,Aú hrDíPmÔ§œ[j ˜Ö2ºÛÝÛ(c¾u».Ÿ7=µP ÅÕòŒÄÛ¦^®â„Bì.Ôäš#2ýB\ðéI¿~/+ìBJl<ÏÓžM21Ò×>Q–‡ƒ=»iË7fáY°8°‡ØYÛÛLÎ"5ˆ©óãu×}«â›â‰ŠÍ[—åñ²½Ñüv5û×ôkÅ· endstream endobj 1627 0 obj << /Type /Page /Parent 1726 0 R /Resources 1632 0 R /Contents 1633 0 R /Annots [ 1628 0 R 1629 0 R 1630 0 R 1631 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1628 0 obj << /Dest [ 672 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 445 658 461 672 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1629 0 obj << /Dest [ 656 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 92 644 100 658 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1630 0 obj << /Dest [ 672 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 443 474 460 488 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1631 0 obj << /Dest [ 656 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 92 460 100 474 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1632 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1633 0 obj << /Length 1026 /Filter /FlateDecode >> stream H‰ìVMÛ6½ëWÌ‘b.?DŠ ‚I¶ P¤@ëÔ¦Y¦×*´ÒV’×»ý!ýý=tHJ²½I°9õ´XÀ+RÃá›7ožý¾H®ŠB‚€b— ÿð_j%KSn Ë53–+(n“«ƒ…j1†ªM®>®Ü gœ Œ©’ÕüxLÈ/å‘g@‹?’<Ê!ã,7˜XYfxÌÎÈpÜ?iãOÿFþ‘¸»’œ®„b†p ›GX?¶ãw$q3‘¡àÝÇWðë¿t¥qÝã;Í4©)'Õþ¬õø—ë›D‘²ÝÒUNàïðI/~JBšəÁEq{ÁñxdT1A«ó×bj¼’á#g’TÓÖ>dú¡HÔHm˜2TƬ#IÀS ½KvÉûb!C á—lœØåžØÃ¥SRÆS H™R6ƒ¸œIÍ´f™UØYæŒÛ3ÈbF,"à];–xõêöuà=#KÚI¸†esç¼”²"3 ˜” âžl™ûóàâÖHS\¿} q’ùÚ•Oi´ vBU¶PEd”~”8MGÌð#*+ÒÝSO<¸‡»ø„ø°$~z!wí·Aʤge_»]yhƈÍ>ƒÂHÛµnVÛ×ÉÁ§Jb)äÝ}Y7å¦q¾Cs‚¯“ O,È´ênoq*¡ÁæôEç8Û+‰Óº*pŒ›ÚµTdf¤r"&'ÏPÂ2ÈHü²‘ž0¥SJ8ÔÂó?„Œå TØôƒCÜBEŽÄç»ëªzDõèñã¡ÖX—_ÜÀ±Á÷9ù¢`š÷@sܬš)q}ï æ™Õ‘/êȽ:|ÐJ}vÔÇg28(ëédMgcìŒa,fç»—‹Ê§æøÆd°ëz¸q­ëË;Œ«Ûr¬ñÎrÓFœvrøL{tã%‡U!À j´ã©¡+å=ÁÝ—í]Û<†´h¬ n0ßèÕûÅ\NÕ7gh"°*ïP~^+âÔiÒß#²°Ží {Í÷¸©Î%.ÏÝÔ,¥çnjÐùÔ¹›ªè¦fvSÝÚVaÙx899 ØktXo®èI†à L^ ^t°Tië9I? ¤¾ crb¹8±þN'Ö©¾üJ~qâ'þ_øé/ÈàÄÁ‡Mðá/\øäÁÁÍìÀ“ÙÉÅռ؋ס*3YðbÀb…]Daƒ“F}â/ÌWó5d:ç#çË_¬#ÿ'ÀŽžÿ endstream endobj 1634 0 obj << /Type /Page /Parent 1726 0 R /Resources 1635 0 R /Contents 1636 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1635 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1636 0 obj << /Length 4437 /Filter /FlateDecode >> stream H‰œWÛnÛH}×Wð±¹Ñì{óQ±5vf&šE¤,,-Ó1gd)äu’ÙØ܇­K7EݲÀ"@LRdu]N:õf6¸šÍT&³Ùã@ª¬„ðÇUSºÌW¶p¡ÔÙìypu½ ÙbKï”Ùv±\ÝNeöy;(‹²”ðÎb0L—¯ñ×ús“É*dùìAEU™/‹Êa W²]úFÑçxe~ýwñoO‡ªÌ‡RN”!»ÿ–M¿­vOðD‰&KbÛn³ÑíOÙ§ÿäC ÷øÍV´y)O?eÓ×v÷½Ù,Ɉõê!V"ûýŸÿcöË€"¦hTY8¸™ÝÀ3òàõõµÈu!ÅOmðX0 GpYJ,â£'²4ž dÖfe]¡Ì´/BÈœ„Lf£ Ù¦<Þ̺dh ¯”‡ÙØg·ÄŒÊÔÈÄ™¢4\&ºJùôF^õ ¿Å„–ŠÃÃr8Od¿µÛ]¶~̇Î@Y „û—v¹Òïm¼Xe»–ïðŠëU³åœƒLçˆrER,è!…ø»c8x¨št?ÄÃôK³hk¨$ú’­êçäM™ epᎌŽòKZk|QJ »§³ñ»|è‹=$ö1Ž_¼ÍÆßšý…~UT¥Ÿû}4{;¹¥SÏœeÙćéøýì-žeÄøÓïP8y’5äzœ\D—åÐw~!°ñªKU¬ô’CˆÇêõŒ6uª:4Böa†^xq ¿c>{GÇÿW.U’øª+¬²†=~fóO…¶ÄÕÐsàÐ “ˆBSØs§vÙ²…w2D{¿æXžéì*^Ý Fƒ˜eY-ª)â|õ;çCÝM>^a¬˜Œ>æ/ÀŒ# 3sP\C”^GO–9ÄýÜGñg y´€mTåc;«×“UQÙ2%jSçÈ[÷Ä(Rdú$ˆPéåñëXÛ’[ |(­dÀtT…–§çì?\Ð'îèÌ^¹ë eÊ*šÁ ÜÌr É!+a d{>÷ÒÇÜ› SîG{+îF£\Rº±€ŒèäMU± ÊE„î½Ø1z—õj×.ñè–9q¦×„ÀN2$+¦sä…mà *™o·©—Y•ðÙõ™‰ß{i¿—b ÍÕlÛà‚,/BÀrN½öɉï Ïãè*!!÷4q°ZžêÄdÕZu…>N¹äT£:ûëÜ} æ¸Ö]¢ „=AæÌ=àÏ-¨ƒ•»®s)áô€c/àÁóë†Z’Úmà€ŠßXF®â‹V88ìl‰ºbr½õUï@ðûK^×0 Åüoüw‰pâoк÷%áèlN`òRNtGl[Š—EØ×mõ/ÛÌPJ.–/p^\iRK^#-r'u–‚ˆOoÖ¥€ŽÑhµ:ä¼…Rø¦0¶Šv¯Ñš$™‘s$PÉÐWâ’+¶ø¼%fµâ±sz¦X1ùž)Ŧ´xÆ. ¢Ù´ 2…Iu{1òiÖvæ1eÐ;q¤G4iE}ÄÜ…è+Ž>xUõ\vä²î¹ìÄ›Mý½]¶Ôë³)0·oúˆ_Û¬¬t*ù k Ï+,‹JϦP$L°.E.GS)öÄ»ØüŸ®ðBw÷ÔiÓO¹¤Ñ*/ d\¿ä–‚64VÀC·bŒ%‡_6ë/4Ý,GWáHõ¤ UbíE§;m¥r½34áz•Ò ÿícT!-sëeà)«¥¸ZZ•Éó)Êq¡¬¸æ™Sa·W@$¶Ô§â!D|iÓ̹¾ÂÐ+˜:8t ø,1#4{˜Ó—¤«PœÆûèX“c_¯hšîräµMM£?)SœŠŒšNÈ¥(;Nuº3æ(é˜Á e0†uX‚<¤ø•¯¤8Zxº û5v?&ƒxÕþ€W+–6$º~¢¯ZÞ+º®³‡Ó ô„8ì& ñ›z×,ÛUÚ‡à}u‘,bª¸å!û<öhçTý0ëVIš4ÔÆ‘ošÕGŒofÝØM›}‡ïÒLI§óÙIÔ’’CTì¹Ôüh‚G¬–&MÆñxvŵƒW‘™2u>$‘Õ~ï‹9vüAâö…;kÃ-›¾g:ÁŠ’Û­¬¢,Ó ¥ñŒƒ §ä"”b>…?d…âÖÝÝÌGÏ8Å¥Àñ-h´Þz’"Ä•6/t~™ y j'O¦œXln° *ö #‹ ™©’Ú¼›ŒcïFc8[Øæ²Ó*—…"¬”jŸ]f<&.ÎJzÁEÒæìû²ëåû`Ýñ•Š-5þZbÓ¦Õæþ…Õé&.AÙ¹E§7L±N.MÓŸÛ?Ú´»É J_•U Áú9F/y)Üï¬Ðá6͂ۆ$6jAUF€}´;–”ÕÉîѧTÅÉq.Ä.¾}|Œ“•`YÃYãsâÍ kšÕ²Žp_=àÔæÜù4âd¥:k(YÀ.`íµ]QÀQÐkŸq2ƒiŽ™.³áÑÐè•ɪK=2Yç°Ä$m‹(mÉU€F=SØ|ÿì¨TÀ.á@äJ•¤eÒ\“5±Z7LW(¡Á>Ê’¶ÎΑA! ítÒË´©¶#‹9“Ótijá)¯–Þ¶ |ï¯Ð‘<Èྸ»GEaê ±ªZJ”ä®R¨n¬ R ôßwfvfE‰\½ùÁ}Í|ó=lÁN°Æ[/H]²ÛÕÕÂÈ4\"­aJŒÞgZ’·ÀF.¡‰˜HŒØ3cýŠQô+ß©ðAp.g$”[Ôsýv4çó»D2 æ˜$+¡€øì8µ”õ>yͯb2-E lîŽI@¼?²ïqŸÐù#…ãqÏÊgÏ*¶Wtô|‰Õìsš•®6ä[Z‚š«R* ¬×ŸŸYP@–¤™æ–H«XË¢c_Î p½é]ÓÆ¦F!߉ã8· ¬8teîÚ0&Læhµýz †ªô ÅPr>ȃºÏ ½³DáGªØž¢Â6IþP`Ò¸÷ ¸ÞkÿôgÚlûíð}G%9õÈm¸q^[æŽÕáÇ \Ηïû‡d‹¬/ôƒ\àûž^«·Û§Gª‡©F’>Õ0ësüý îV“1u$ïøyö…t ÿ¼§¿<Ô˜ËTMŠ_ªû}57vÓ‘»…6ÙÝX­‰ŸC‘0 K‹SÆŸëô+Q:òßùG"ÊM®:|ÛQcÞú2<Äi/·´¼¥Á#³÷9w¥É‹g¯:ï\rz{Øóe¾¤ìq3EðXxy?n ƒº:3~Fã ®lpôfý×ÀuÑxÂ<è&5¦ša‰àìçVHOŠ>›'СË#;E)V¤aþ ýåºZÑrHž±`´’€À‘Úú›*v)öÔ 8 îY žÑqJ>_­Çz@ßJ ¼“¯ßîéBhmBm®Râ ™E´Œ>/ÐA 8‘År"òbŒg«5k¹íi¹X¾"õÞÔ8 °¨,KAPà­ª^ ]Âez6¨HÞ'¼¼Àš bˆc¼lfÄ Ï'†ÌQ¡<ÉîA£­d¸9`˦‚æà-¯V’šÖO|.P:`»(›w° Ÿºv…°ëÓÊèu^ˆÜ¶NQV=wi95؆Ñ9—ó õ@oÛŸž*ò2ÿ¯Trªï*MU\RÕÄTõ—ÛëÏPo¨üšªYuÈW#½ÔËn"—½{™&{Ӏ̖òâ xOSºntšÐuköîEk£¸œ&%Ÿ ˜ºÒ † o¤#ªW“v”ß•ûÝ]ßѸ(eØêåúX:•kà,OñílFó›B®o· ¿kB^6¯cB7ξë;4<2ÛXá¦[á>\QÔÙ&HŸl^Ø¡­&Sm†7œ^0­«.IMW¾gÆ‡ÄæòÛœ,¼§gÀ¿ÉC; qó>È2l·poftfè`%ÇÝÎÖt/_©ZW7µ#vÐÿ«©a¼t»(žUå›í¡ŒW­ÊìÓ4ùãyâgä/°OhÜlK¥÷,–…÷ôûÄ.Ü*' ^¤>aƒÍÍSMÏjOq–u©m¥ktÑ7G?_QÆàùqðÀÞU[G§‹¯'ªY˜®¤hý´ˆÇ닇êÉF6|¿)NDó†$”f¬¥»ToÉMŒq©| ˆfHßaò€ã•.¼ÔJ4r’æîÐR¡@¡`/ jÇzCuâÑÓ¹5w]–Erÿ‰~é ƒ=ŸÝ$ÅUuŸ&c^©ZkZy^:g "&ƒ778úXG?GLX4ªÄý‹Whorxæðh:r7«õP×7‰mðH=~$nâ,?ÒËÿ kj ›øâœ!¸sº* µ¹Ô© `‹¶ÄŠø’@²ë4ïÕ߯Þ=ìËïÜ;ÒÏG;‰FR+ŠfIT¸‰Ž5pEÝ ¤%²Óù´6‰üsŽò ÏAæÝȃ§}z‡âðä¼[Ï1Lr›Kn²Ñ0(ÞSqZà0ûLÜÍ,£Mò¤Õ&©ÛÈu OÛ–dÓ­ê©%G8U®ŸYahõù+þwSº…HSTšo¿1y^eÞeÎtšh¥ú_¨BÑ:ÖEjk ¯Æƒ÷‡liêϧIƒvë_þ •— endstream endobj 1637 0 obj << /Type /Page /Parent 1726 0 R /Resources 1641 0 R /Contents 1642 0 R /Annots [ 1638 0 R 1639 0 R 1640 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1638 0 obj << /A << /URI (http://www.openmobilealliance.org/release_program/ds_v12.html) /S /URI >> /Type /Annot /Subtype /Link /Rect [ 378 653 758 667 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1639 0 obj << /A << /URI (http://www.openmobilealliance.org/release_program/ds_v12.html) /S /URI >> /Type /Annot /Subtype /Link /Rect [ 71 640 388 654 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1640 0 obj << /Dest [ 686 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 339 598 355 612 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1641 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1642 0 obj << /Length 1980 /Filter /FlateDecode >> stream H‰œWI“«F¾ëW䱈x¢ÙAsó[ì°ý<>´<—ׂR«l(dõôüúɬd‘Ô‡”  ×ïû²>®ëu.¬· 7°üñ*vìUäD¾{Žërñð©I kÌ.šL/~xtá¹Y,Ûqð;Ù‚Në—Å7á&¶Ûž€/µµ ÛxÅ›±¨,|#5dUŽ[VB6`ý¾þ‰òz‡<öÆ›\ñ"ÛIØcÆ\K²¸Þ©™µªÒP¨¦µ–‰ˆÆ ìD@»“ ëºB/"¼KÆÑn»K[ÈR UfEv$²®†'¡«ºL‹âªQ›B‚Òæý¢²\_~n ª¡â›Y¥›ªO–=Fq–V ÞOâ³ÜF‰o}@œAoH¡;fÐÅüÄ_uöËWxlÓ¶kà“ñüjÆ¢0²“`ʘ»3FK“1óÎò°N²1$'Ƭ!­­ÕË-f1Ê -sØX.½õŠ5¥”ã¥yá«Ù ü•ÖÂ@Eªóþk¹åâ7lø7Ø ô~‚fÚTüÚ‡þu)9Té;/´Cü³þŒ÷(c‹kýçbi¡G®o÷í˜a¨»¶ÝÿëááååÅ®öR—ÕFÖ CZKM1Ó®( •êLÚØ%Ô±Ï|í÷œ¾Ð Ï¡ìyOõÌWü(r~údz´kË„ðe½pAÁÂTÈ…(ðlßûÂK A-ÛÅÇõQ5ý$´½€Ê‰XôŒd„#øB.¬ ÿ®ZIÝØÃü¶–K5B|.@aÕ\t ÕUË9^"Ȱ7(Þ˜À`ZÀ_Ϫr_ÈV~€M×" (ˆ ¼­±|˜£@覇ƈ±´F•ûªnSÝÂá3¶ÌWúYii…ž xV_l÷„ÛÝlòÜÁI/â*»Žk%ÔgèˆÆŽ[byLV²>ÈW ÃâÅ+—¡/vÃWE æ C3¥j±li¶“9µ¬Ù&!Á4„¦}ðž¬Ñ¡ÞÿeÄ:ö)<Äê9Îî¹ÿˉû&ê¿þŒ¦»,Cÿ¶]ØàujXð4iƒQoõŽÕoh–èÆ¿’¼óv?¶²„4Ï‘î0‡Öâ¹ ÍÇ'¶rz¶úTé-r âPe˜sCŒ‘)O„\‚ÆDq@O^T»ƒRb<àÏÄTå¹JÌy™\ô2š¼Œ&/ÙAI^!1Î4^-!+”Äþ'¸¼(ÍîõhuÑ£xò(~×#â\—ýÙ¼BÞí Âl,2Je"°qô3(*êU¿¼ø¸}\ÇBV .÷«Ü(xôâgIdÂ5«:¢ #ÙN‘Úzâ@(rç+çϸCT_éfÊ–?u3bÞ{u­§ÏŒz7äàú®C:Ô­Ê·¬Fè}K:;*P„îtW°à½w¢S ñ?þsN\sµMÞ‰ ÃòO[“î_D î¬ £yörH{¢ADêV"Ôqt$‹M·§ùq–“ý7ñ]ž0Þ*å ×f<–¬‹wêä?u/ŸtÅ-Œò©yùÄÕ¡Q[¬Êü 8—£ÙɃQÕlÖŠý) ˆqÜènF1Ú¸lÕZÈÓ[&Õ¯PVõ ß™k7Iø›Ôü¨‡c{&w¦$¼f— þ›ž€PÊ\¥Ð¾î¥)ñT…’W¦³p6*‘Õä–¡mŠÖí© '´¨-ž4DjøM ÿ‹ªѱ“/wW`u‹O¡»îÉa5"F+‹mbƦàè€Àwû-¼ÿÀ’ä<܇[oV'ØŽæù÷ 2‰lA;‹rX÷ 燀¹c Š*#†Ûuò]#@xÓ¡ñ²”(ÂM‰Ô‰|úô$ÄáýRΧ³¤ÛŸ%em’Þéô@Ü >ÝÌ#×§Ögu”mXߦŸ×Ÿá ë†È“ÂçÑ•1m-W<¹x¹; Wc‡‰ì‘$|˜#Ã+/tÖߨ%/H÷úåÝþܧ.ÇúKÓò‡Qai\¸Áø ‹„W%†Çã±:ÞP3 '¢í¯s]áèFWä„þZ×H·÷útåLºœØö˜lɤ¨|±<öáŸyp“ºSiSK:»ìêJ«æÑ÷gLû·Äñ‡èie¢çsÓŽ Ch1°éçAúà—õâÿ¦’ë endstream endobj 1643 0 obj << /Type /Page /Parent 1726 0 R /Resources 1645 0 R /Contents 1646 0 R /Annots [ 1644 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1644 0 obj << /Dest [ 1637 0 R /XYZ null null null ] /Type /Annot /Subtype /Link /Rect [ 447 670 469 684 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /H /I >> endobj 1645 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1646 0 obj << /Length 2310 /Filter /FlateDecode >> stream H‰œWÉrÛÊÝó+zÙH‰æaÛÊ‹;ϲ*¯beM±c Ñ̇äòYäÜn $%’ Êeht÷=w>÷Ãrv¿\:ÌfËõÌv˜…øñ"Çô<+`aì›Ad¹l™Ïî?ÖKkµÇbuZÌîYØì¹žY¦eÙØ“ÎæýãnÆ¿%Ï‚9–ÅŒå?g±:³Ð2㻑Xú^uÆQÇéÉèôwþ_uæŽeÌm× ¸±§=[ì‹fƒ‡ 7ñZÖì÷¿Ü±¿ÿϘûx¯ðÍ7}. ‹§›;¶ØÉæß¢ÊÔ%.OŠ•19ûúkücù§™ÒXiãXf€—å'¬)»ÝÎ4\Óæ5I$WC¤‰GËtxÚ-mÔMË™Í$›9~`ºÍÜÐŒ"ذ$ƒŽ^Ä*1[Ï>,c¸6¶XÇÖ­k‘E¸²|ú¨·dX&þëÃdÉÎ}ç¾í6„wzŽnL¿S“|Õíþ˜©A'‘eb5ñ:©žiy8ä™®…L¿ …sèKËBÉ”6®ÆõgŸ‹FTôæE’±‡ª*ÕzÅ>â×çåJÔƒô³:Q {Ž:ëàSnãVo±Suuœõaæh`)™ Ðñ9T§’çtxn›N4ØË$A+(h™¦mņЇXýºW,î‰âé{–F€(Û¶rQ«Á6É‹`;¦cŽœä¹`¹H`¿j¿,žY¢·¨ÝÈô«á!¾à¯ÃÙ¢Iš–"q¬·}$#ëÇÇnMÙÆ{jºhß§Ô'ójð°ýàÚ.O“J°r½®EC ªLš’åÉÁÒLªOyTá⤻}§>Ò i+سÞYˆ*i€’Â’íïŒJ™Ëв1ovgßåï´=ÑžSkƒjºÛåEÃÊ ¦9Ó?"ò"^dÂÚqûnkª ûUmƒù¸y. ܃2áP˜ãà¿kƒy}ìYß?$+`cmñ£(wkª¤¨· )1oض*›2-³³Q1åD%áqH/ûr ZñèËXýʧC-â òsK&óxù”‰œ¡–nT|AYOYɃ•\²¬(R•Þ|¿ãË;°»S°IÔ ÂÊ­(XZæy[ÈÔ CªàóxC9£3àTÀËâȼ)ÈÂY¨ R¬áUÒ$'}‚\‚\{”k‡G© ŽŠzº&ä(+ÆÍúSôFý£.Ì ª¯‰NõœƒÜFV6û­@ÊE­¾×‡»À(~\¬F ©tq^ÇaRè¼Ñ•m§?ì«:õ#®Ÿôsƒ@cPžCð£ñýÃkúë^ú Z ²7uMõY";rY€tã3᡺L…ú ªy]Qzäk?“|› œxI2¹R¥ï7ìê[“.ÇÎPS졟õµïoš}€º¾:ŠksX•:BÓÍyÍݳŠGSÿº5t˜fe-Æœ‚ûz®rÒ{_NÆW 0’CB²<¨µjm–ìEÅ’¶Ù”•¬“FÌ#æ³Éþ¸\~S_`¹u"éÑ9:Ç mKgÞeµèžèèùÒÑÌd›t/Qd=\÷›þýj8ü }*Ö²#¥ý¦5Ó§ë¶=EmÑ5ȃ]m{€L©§ W‚^žè5PoJÕ>ºeª?æ~Iƒ¥ÕÛá:WŒ|†š‚¦ B[i·¯Ë•<ìãŽ2bXeû¼¡d‚ZÿjEM$½¦êC%Í$ŠÚ£Aõè=èÝ)èßèz º²Ôh3Å’Ø“`kæ + º•º‘7ÑH¾zFýE¦¢@¾‹Ÿ[Y‰•6 ˰ŠnL¬Õ¢b/:3ߌʟ”JÑ—]¢±ƒÈå`•šðgšæ §õ{Ó¯³~ç…‰àlªS¬öŠ#Ü€ãÂ‹×ØÁ©ÀpŠAƹG»‰/¨5!p“§²¢PuokTÀ[¥GSÔ}M4?wý-SÁ‚Îßõ÷÷dN| ‚îÊ_d.IÓ¦’ ¶/¢ªÍ—Ó»ŽçXï¡§”§…HU­hd.J Y·Ò@çÊq†}H^,¨MÐ%™ª¹–i¢Ú0‡œ½• 8ïœ7ÞÀæõpˆ ‹#%º•"8“Š×…L±6±F°\ ^§Ì#¨*êƒÍË\3éº)+QwÜàŽÕ´Þ]ÝH4`¿ (|ã]œ#ºg ¦ø+¢ª\ƒRæeµ%V]sQnpNî™Ðêå¸QæÛf¼¨è˜»b"6\hR(D³+«,yI$>F> endobj 1648 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT8 1666 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1649 0 obj << /Length 923 /Filter /FlateDecode >> stream H‰œUÛ’Ó8}÷Wô£Ä$_b?CMí[µUc^(ÊãȃGÎÊ6 |ÿÀ?îÃvKN²d¹d¨TìÖµÏ9}ñÓ2º(K Ê&R$þð•äZ$‰Ì`Y¤"Ëe å}tñlÈ¡ü Cm£‹«kë!’BJ…{êh±7·û«ZÐR/ßE…?TÀRŠ"Ëã\d2ÜëÏhœ¬4£Ó7ì‹ÆÙ…–|¡b‘1™ÃíG¸þhÇ;œÑÌp¼‰ íO®ëø"űõT¤¬å’ÕwázÛŽŸŒëü%1«ìŠ/ Ÿý“¿)ÿˆõ9rè£SNÖO#ô ¸Êb=>Øg|ŽOuô©ÂQ³C†¶êPÿÊ›ÞÐTm79¯™íaeFðÞö[‹Ñc×­%_ –¶Ökþ aI΀«Òc«JÃѺ«žaÖ†'Ø~ÇS‚¢Ùº ³#™ñ³sœà9@9-ÚòQðë ZËTJ!ðUó¶d*´ú¨ùQÔ< ô•—HVòÔw…LÍà›ËÆív„ëßy"rvõv·Û…Š­ûÕ¼Nz¿hí´ƒÆ…©¶·óZÏ9Vméëö=jºõŸ/B„ŒÔ=i¤N-ãòÈn1[„ö¥5»©©è¨ÐP:ÃÙ¶ØIhnm¬qÕh òCã¶ÂI ë…úP-}?_c:½ÅE®µø:ñ ¿•5”0E‘ŸÛ"‰RÀ<À4E¡0¿9uµ0ÂLŸì{Êe³«Ífl{„‰óaõÇoŸ½EqV¿–ɾ_“…d_ÚPEA>bþÐÄLg=”¤ÔÄ4ô@4 €~Òæþ÷å¿a—ÕXÝREù¢‚ÚtfÀ}¿š:ã£MË”7ÕmƒZ* 3z«ÁK›³ðìýž`CHâŒà·hâ÷ø_‹†- endstream endobj 1650 0 obj << /Type /Page /Parent 1727 0 R /Resources 1651 0 R /Contents 1652 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1651 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R /TT4 2109 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1652 0 obj << /Length 2828 /Filter /FlateDecode >> stream H‰ŒW͎㸾û)t¤€±GÔ¿sØM‹]$@€éCA´DÛÊèo%ªÝžÉ;ì;æ*-¹Mºa4`ý´ªX,~õÕW?¿l>¿¼„÷^züÁ%ÎÃ]©—É.̓È{i7Ÿÿ2å^9éoo*»Íç_¿rï8m‚]pø¦Ül¯·ç û‡8J/ BÏùϦÐF…—»"ÇQ¾Kò«mBmŽwIŠÖߨŸ!¼Ý†¿åÑ.eAîí/Þ×K§Nð&dÒOlª'ï§_?yÿúŸ¿Mày„ÿ%»„Õ~ÀÊÓ'ïë¹V?äØh']åo æýWÿúÿ~ù}£w¬w»^þ ïtçóyçG;Î&\Uâ²à–ÜÁm° Yi^´§_^6Ü«½M˜¤»(å^”íòÜK9dÒƒ=ƹ7ÊÍaóóË’ŒˆÃ'Áûl¬Ù 0#LgÎ(6gŽIß]ó™ÅÑ. ÈbÀ—ã"Ú/v~Ið~ë*é‡)lìrpuï¢(Ïî<§EäY;á>äî§f8‰½T~ÎêÒ¿ Ón ðÙ<Ñ襯ì;xw¨Þ?áMÆþ ÍÙß<%Ž-îÂß²6Ü„ù51,“ÀÛò|‹ç…»ÌÖ g´a±ïGÕw¢ij%ÛÉOv1;Àú u#+Ïã<ð x¼"FW‡ ÁaYÊAüRW7JŽp—3ðò[KL|‰g·.&?…XÀ>½š«ð·!k|@VÆlàšþ¡ f¼˜;c ’uó‰N‘¨Úº¥¨.S9փ 3gÞ¢; 0q€Á¹u²T‹qrk¬×Ý®Iz—#,DyæXûÀ£¹Áÿ² 7±©4ÿ¤¢ÜÃ5…fFçœt×X„pÆJzi¶œ[éZ¤L¡EN)[“äŠ"^ȯq4ýY¶ƒºx^ާÆYá#+¸Ñt³~ã •ý" ”£¥kó/ˆ*vG.>ë˳€2 ÙÉh¤èÀ>'T…îÐVððäÆOÚOÈèͺªéKÑÔ…3,‡Av•êå[=©º;z@‹÷xrf‰‰q`žOWã+\)}Che§Ê~îÔ¡– „]ÏÕø/dßÖ­T—Ó˜c½ÆèZ¢•«p5|ËïVK×ÕÒûÕ:°X¢ŠŠ™;ÑÅꤸw‚àI5ßeìáÆ)ÕÅRÄÅMg”DôRâ%fØyá©•ôkÔØ‚ýÀJÖ¬…ï!tzmžzÒe­Ã+ðd8 èâ®7ù΀Ÿ®ª„’uçs ¤lf@&«_% $(>QÞI´´sÆãâö$7½R+ä$‹õ ,º¾+u± ©Ž"ÛKì$ë}CõLžñšÕ[©Ÿˆ wé¾'G¶¯¢k¾°ÂØ®sÃöûºãe£šÀ(zj¿ßÐê=ô†µ€lDþ€¬Fsu2u2vöâ6™ìûêr_ÏŽ„;‚CSÈ&r¬ŽÅ"ÀæQ‰€ÝLßѯn71£¦A¿æ•¢§‹èÈûÙô`;wJx¾Æ˜SŒÈØØõ#Ýõ#&ßÔp†ä ´–<€½×²©ŽüòñpW^>*Ždv“Ѓ]t}´u‡ç‡Ïž?vYžDw„%‰0¨à4NûÎT~ÈrÍQîò·‚Ï3f‰`ËíATìè]I}w4Üv)ÓM„ȳµ9“ºP>ò^ߥ‚-T$¬cFÿ,IÌÒ+½×ë8K7¼ÁeY¥»pd¹§ŽFÄfÊÚmûJ„t0(nÙ|2jI’ÓFWýÁR[„Dï7¸· ¾ig’ÞÏ;ü6­h#‰Î"w׿}}c•º˜¹˜è8e“ÔúáíZ¥E⾓˜ÉØ9êÏVgh‡Z Å $cÔµƒÕëj6v» slš˜_p3¢=OžXÌòP(Ð6ÁÅ”ftìZiüìLwuÃu:ÒäL®L Kc*Iwlv#½î­ÐN3rš].] g4f'lQ>å"‡®§ãvͰ?‚.®ð£™d£]ò¶ÔÂÔÝ%íYˆ`˜Á„Ô¾ÃcÒ̹§*[+c:pçÐà¸[¢ÆËfãÛÍr³Y¸¢€ó¼ìÁ<ë€×¾{Zdïá© ú®#N¾v4ž¤ÎÖ`Óeµý¢mæ^ÙR»h«åqál…ÁŠ· 4x4ý¬Ì*Žfm5=°”ÖÖœ½©/Õ~žäx¿õÇ*Ù~ÆæïÌ”ÕÆõ×åiî¾·âmªø9¶D=Û=Ù½+yÀÄ0锹ÙË^v1’]ÙW4^Fì¨]hél-ÿÎêª ý­•.XH„dFóS„àqéʶy}×HLûÔ‚@‡”Ù!= ty:_«5µŽ>Aõ(ÆQ\¦?¤"·€±ó†vPÏ>4¹ä:’‹ÌMÝ®øÐI+²K 'bï“gÌÎ$¸xöäØª­ xŠ9fß1³!{ 2W³CµNú&Ô½=×3d­»~•h qì%QØ‘A ½ bp4ueГa[áÌahöZ—TŸØ%®®AL§ï´4_óÄ¡)”7U“#2Çù²ªžÄ¾ƒ,âè5¢5d$#é]žšn&v­™®‹¦«“s©¥k#.&ŸücÞs5x€( µÑÚxÝÐ=¹:øv*uÝaÚºîd:íNÈÓ ?˜Þ ðš ÏÏŽ PfŸÍºÊšÖ 5ßÏ­çåVǽ!wüÄÚ0öL¦ÇÙuм“ŒsîVößà$:ÑÌ#ÖxYt¨eèvïÞ4ý}cà¦ÈÐu¼V$ÚØµmì\ÌÒã€#9Œ@£oÀžá}è‹/N6’dø4S«° £Z·iMRé®%\asèv…ü-â¯Pdž¡]äN7‰.à|jš…–94,5»åÍçÚÏ87šhìã¼™¨àËzÒRø¤É“îuø ».k—ív=Øõ\ÑÛØžI k•³QÒ£ Ä©«™'…Ýr¹Ç=Ž.™’Ç Qñlƒ?ôM%ÇïòBMœœ{±‰µÎL g‰Û™ïaêjúR4?îÚÍÛ7hÃYálçn|ߥ›ƾeÛ+ÙwÍeš‡¡Õ-WÜiB3nD¡{ªµØô0wZkÃî“§ñ;J¥{ŸáÄFSeüÉÉ\4ý^4M¤QjöAùX‡uœëêʺ׹’h q'3¼"—]Ÿ·PëVÙ')gJXr ,î<)eÎ, ž{õ±Óƒk ekÎè÷ÿö‰RS’óKóJp·ú°4¡`Æ €Ô˜š Ž¤QlûkšA[TUà„ mA(ìQ‚‘„2Mù\`*NF…8;6 z;¯Ö³3Ã^ aä¸Ì> endobj 1654 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1655 0 obj << /Length 3379 /Filter /FlateDecode >> stream H‰”WËnãÊÝë+¸l¶†Ý|/²ÈM‚ d`¼Êà" É–ľ̇ó!ù‡üc9ÕE‘²Øö(0¬¦¨®êêzœ:õÛÃîËÃr¤ópØIåxøÃ$j^äÄi¸ÏwêÝ—¿ ‰“fç y³ûòûW釷÷<‰=ùîþüø²ÿÈŽÚQu¾ïR#”:±·O#(ö“}ä±^#£Œ8=…IÿQx{¯<÷^úûHx‰óøæ|}kÆÞ(¡]hC98þýÎùçÝûß{üîCQºžÈOwÎ×—rü©ûÊ(ñEÖî}*œ›O÷‡¿ïÌÍm”·ðåá¯xg,xyyÙ»þ^ŠNÕt,TãÈ=½½ùüêd4ýía'ÒÙ©0Úû‘tüxŸ$N$áIw §×»ÃžÄï½7Vïzäa¼·Fæì¿8òöø¿pàÙŠ/Ý{_40p‹A“wBÑEFO±çuxªhŸãH,pPL‹!/gA Ž&Ç@?q4=š³šÁ%ý8FAiïP5º ŸºÒµnFþý©ÂA‰ºTë/j×üñü µ¤”léÇ:ëè»Q¥Û8õ‚³èiV 寨ÏOãÔ“g$…¶, .Žì6…«MáYÝsI—Qä`wz¬ô¡¬FÝCRv«¼Å*ÏX%Ê.+Š^ƒƒ€š_Ÿ¼uò­»¼míÆðk>–mã8Q²9ñ›¨2v7G n‹C©«b|ëôÆsË›ò…}Ìr–ˆ7Š«"M¤!ØúÞˆ­ Ì+Ý”ˆü…Ðöš2Z…沯Ê\#îåNnd]é‰Ð·Ÿi±z–çdT¢ÉjèI‰ÈÂé­¿«².G]\Bl€NUàZÇñĦ{ö"IW})»£l42Øq€ ¶€¯žð"hó¬*ß%×"·¬rÁ¥\— ÃKÛSv§¾õÄmrÏ¢'8žègyÛ¯Mž”Éû„ŽŠÊ®ìÆÿ«ÄŒ’.#ÄÅëˆhšT—its´GÝd¨Ì‚³GÊ0ç:ê$ ‡SÂJiu·ÍÜ㡚]vB†%s Ü„sFAÛ×¼¦wŽ1Ör²%AŽe“ŸtþcÈg'GÊiµŠªÅè²9” °ŒñÄËYü ©×?×8©Áß8\ŠZêÜ£*{Ô•ê'GÚnM¹_Å×'ݯF¾·qÒ"‡†g¶HZ}|í(·ÝXÖº(:ÑMu$ê,ïÛ«í-*ZZÔ\5µiƾøÁcšµÝüv%ý‰Š—‘°Hž·õ®„Œià$¬hIuf¹ëêì‡æ¾ž¡î]_» §™YŽþJra€l¬àsÝ, 2JŸâä6œ«³×l³üdø…㤛Fjí½tÙWôÑ|ê{œSƒZ1‚˜\'áeû·$ÚÐ&ê¡Ó} ]Äy‘͉›nÏû¬}ü>”?©%Ú+u-©–£‹…î4”L¤æ¬^ùW£‹‘èHÀi‹/|/_´M?‘ûc¾¦á¡¡=qí¶QÖ¦â­ÉëêY³¡ü 3òØ´ok±‹¡o<õ:+È"y3užô+N SkÁ«dq˹܊c=Ñm¥áç”}gR3Æ` :󾔞oåmµñB"ŽTÈ€BØœ_ŒNíüÍ‚c¾¢ì¹¥V·å9$TgeuUŸ`,It}Ë}7ocGu &ü:.ìÝrеißHˆR#ºÌ–@ð«’Qõ]º`fDLCð혴šÆ^Ùpí“ j ØÕqñïW¯\:e8ID5©®Û.7Uc T£V‰Ö$?Ÿhë[@%œýä{‡Ü$I£áÇn 4æ{­MR®P$c¶·Ñ/$~†ŠÍ)K îrfCAž¦vê1O•ñíÅJ<§m*‚RßH ™0jtÈg0ãÑ•óD£€y5w8däÄOü™ó¯,9“LʯÅøH•ZE®©%ƒÕ@Pþ¼å‡|(<+ayK¶g·…Vr@ÚB£ÍŸµ¡„š¼š˜$À'ÍŸ:SGÏ^3³áâ:*cÏÞŒ8ükôIMGukšè¥fZâ¶l1e3FBM¶¥I½d;õ­Õ‚m?N]‘†ÊÉ ´—|¯Ÿ&Œº˜1Òc€ù"ZÇ k|›e k%/EfFÅDAjÔ9 µ’~P+Yˆ_tX1hSd$Xö×7¸>ïšF‘ùƒ!ošë½)™D«-ßà VçÝ,Ú¹RLü¾¤Š}9é¦( F(ésÞþN¶y_dWá÷æò .+ë"Ëü%ËüùúÃTkÃÍ§Ž’öû,Ý=_Zþ"ûÜùÚœ¶0Èy™bøÝÝzšE¼N<ƒÂZ~ñ„I0Û¹Š)ã¡™¶ úâ2zY®¤–+©™º• ¬/™G‚äòCCÞ÷Å‘‰¡ã„ô:fIí¬F®ÌHžÕQ|žÙRQQŸïÍHÇŸ¦wHñÆ»Œáº¹ ù2aÕÐJ~©HI*æo9/#t ŠŒ¾˜ÓŠÙòiÞ“è"RÄ´(ðb§ [ÂG™9*_ ÓIS q•‡Rü+]ç—y· h|PÊùæ :벪â×éÔî0µd¾ò/F¥ÛÏOC7qÜý³CBáqø^ìØ­âEw¼ê¦ÞÑpúÄÉ5L¯kú÷S"ý: œ~jN¿qozñ¼ÁX°M)V³Ü™¶ðKתdãÚ[¢Ù?.äIbÞ[ßšcÖš•ñšççyb’[‰gÔkÈ#/.2¾uúOòÖ†ý¿Ö«-ÉMþçù$UùØåi 7È0Öîª"[ä"ÞÓgF=`‚$6UÉ—ÀÍ0š™îsTž»®ðpfϧ.L“㦖xÄ6 š)\NÀÛ¦xœ!¯ÒôÛ`DÿŸ#¿É)€-ôª›ÑŸçëN¥~5æ’½Êżr<ñR†^ÃÉaE‡=f®û³±+ ð2!3B«CåO·É"ž‹xܾΞ­.¿~®«øJ'W—ezð‹O¹m¾¥Ìò½o Ü×øf§Îum/ÆMCú=EuÓ£}ĉñÓî͆¦z ù55[ø1ªÿQ¿—Óë¿4 >&Ÿž^7ëA&n]C$D²¯WwÖc×úžÈã’0Tðëbj.½Q,û‰Ç`OnjˆjðîŒq“Ñ:P»á¬4êÕØQ%…Y“2n²gÆ.ÂÓN•×Ü2^ÂxP> endobj 1657 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1658 0 obj << /Length 1397 /Filter /FlateDecode >> stream H‰”WÍ’£6¾ó:Šª‘Äÿ1›¤¶*§TOÙÊ1 Äx=’wÈ;ænIä­ÙšÀVÝúÔýuóiç=îv‚p²{ñ¸ ~àç"Œc–’¬HÂ4gٽǟǜìG½†‘qßzŸŸ89Œ ã°fïóíÉ£¿—I‹‰¿ûË+´QA2)Gy˜2ƒ«m„6Ç»$Eë/ô_Ÿ‚ù”²œ<ŸÉÓ¹U¯ð‰ Ò$:Ö#ùéóùã??Hày€ï’0¡µÏèþõÓœN§ÐBNGô*Ñ-@ƒËnY(èÞ~ôª‘~ÝyœÔÄIF)'Qæ9I90I`qNé½xŸv2"KØ- » ¡š½ådfþ²”…ð·ÈÄL ÞýãôÜÝKÝH«5 #·ˆ —#cÑl£^YVÇ®³T\™EhfW…ajœz 'c:T%Þ¤TÁù¤T?dtsªºÁ®"„Ç|æÿ&&¾d‘…ö8ûÝîl÷]U·À(¢kŒè²¯lÙWföuK½%^$k*Œ·lÞϬã3¦”ŸæŠ±ãõëdoFp~у+h‚÷î€Ä˜ÑÛ½v0µ‡ƒTð;~m0Mܼ¬Ë ™I /£*?Ž~€u!U+O¸Àù#aM}¥ŸªäÝø>H ª1ØŒ/ü•xÓ#ÆœÑÞÒ™:-«îÈã%òø*òú(õØ—J¶ÀEÂ/ÀÓF<*¢lù;fqB»Ö>C¥\þш•üf¨ŽèÅ©z…“ÜyþÛœFócÙ[“Û2uV·ñØÏçù=gëÄ0–³šäÁâðJMð8ªQŽcݵMwhK8 Š9µ(]\Ú Oª?-@œ«±vл‘Ù8ÓÆ —M³ØC;H èN¡HîR¼ ÄE Šy4¥¹Ù+œâ'Õ81âLj ÊÖ8÷ö¤Af+'…Éâ71CÙŽ%”E×ZõÛ¦J°¨Ëµ¸€)æ6§-ô8:öÝj—nÓÅÙ{¾ÏhÔ—#â@Û7·Ò¢ãÃi ¬à&Ó\CÎÒxº˜aìƒbô·<›gCÿX«9`¶¾CÇ;V8åsSQh†&ݤ@®×ºÝÍrúV6NÝ?_ÌWXv@)g4/¶[¸ «å0ú8@ƒ‚›ªvÊïºñ¢X8Õ` ûª¬l½Í$$6 ´–ã™au¯ÃÛQY«=×wQE)K츮J5™;óY‡/e­’ƒY‰3 }Zð®²Ë]y,wWÞvjøvltóуCÕmëN]ò„Û‘ì½ìuÑBŽqz©\—¦lrì½î÷ݱì¸#ß$˜ã Š£î·¬{Y=×-ºGMÄaˆ­&" yA°’³Û41¯ˆðöùÿYñºà endstream endobj 1659 0 obj << /Type /Page /Parent 1727 0 R /Resources 1660 0 R /Contents 1661 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1660 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1661 0 obj << /Length 2701 /Filter /FlateDecode >> stream H‰”WÛrÛF}çWàq¦Ê¤1¸ã"†$"\¸(‹Nm©lY޵å(.K)%û!ûûyH_MZm¹,\ˆééé>}úôE»xÛ¶Ž¥¬öóB9– ÿàâEÎÊóìÀ cD¶kµ¿.Þ®#ëö‘¾±­ÇÛ‡ÅÛm£¬_öʶ|s»Xv·Ï ±ÿðË娾%Û-bZ[¡½Š0ìF«Àf»´Æ¡åxç¸úgñ_Þ.[.•» „Yÿ´š?ž¾ÀGÜI°$ï­dûÆzÿ—\úðü~óW¾¸—¶¸ýòÆjžïŸþ}÷ý+q҇Or ë?ôWþ³ýiA'¦Ó8ö*€‡6…wäÁóóóJº+%q×;ÜLÖ+¸µWޏ5¯¾%Ý.”uo-?X¹²ÜpEV  ’œÑ‹¬ïw‹Ï‹‹¶†«àûÇh ѵ1"‚¢7d¦‹_Ø+øÏK j¶ê÷è~òõÛ—ïžîo­ìáÓÝÖoŸ­2XyâëWëãï2^EâþëÓòþ¶û~ÿíÉúüûÃíÓýo]h–j{bD0EýŽÙଅ¢ª[º¦Ò ß& _+‰Q¯µ®G§FÝÎ(¤µ÷;êÍb Ñ,^¹ÄXë¦ÉªÒ²ÂøÕ 4eŽŽuŒKròP¤¤'@™a ÈØ¾æþ‡ ¬¿§÷æÝ‰ih;ƒ}½§Tç’Y[DJzœvÇÙš,L±ÉPïàçeìôbÉ1Íw“ÕH"!ªfì/-Ô%ÌPÔܽîý‘ŸJR§^×òc’ŸÂÇ?Óþõ15!ÝT¸i;ÔXýSUnòÌÜ·“jF$ѵΫu’³XÊ(ŽÈgÞ«µÙ ½´Æ“á'R7Ó)AB›f¹ÍŒ®ö ï" ¸6<Í§ÕæwDâD3%Û”J°Ê|—4—gd78Ó7·sÅpcFÇŒ!ÝààòààòààL“ՄП@[`ÛÅ¿ ×Fݽ=<9¿"=7Áï3‘̶ee⣙_{.Û9©4.¤Œ$A#Qï$W ?rU‘þ¸¡yq¢ò ߨò¡zýÁAÕ;È2kЛALõÊó z\ƒ,˜uÜ7Õ²Æh6y•ÈdD(Û=õ:Ú‡õµÎaÓ+<¡=¹©÷ÅiØ:ë RvÓ„·o»ë‘ ìG=þD/Å:o{Ük–žî•åp ÕE„¤sK Ðõˆ§ lØÖ™ ?‹"4@rû67¤‹6›Æ<·4 1®_'ïójÛ.¨âú#$¼ÄJyU5Y¹5Â}«1 Ó:ÆtŒÓŸð®×;gÒŒºù0ꌇ¨‚4 ޶ߛº>äRyÝ8OÇ`ž…Áâ¥a‡Ò<5wÇž?Ú4Ëx*…—9Õ³šžx"åé9Ø{˜VÉ_G¬'• x0®Œñ_?|ûKï>Ý}–تîî0ks¨ò{XùÃqÝ5WN5è›aÉÅÚˆ·CÙZçrúDöýµ …fÐs¡ËÓéÍËÄSfæ)O›s”œ ¬÷×îüÍòœÅXÖè5»Y•i3«˜í¡÷uí¿¨JÀ·ØÁD:Z÷ÎJýŽèQÂ|ñjŠ„eТڤ« …‚•4ÑÒ@ˆ¹AåÜw°U 0”>ׯós+:@ƒM0BO€Ñ‹^eDoy(H‡R§Kõí<2¤Œ Ú'5’tÅTSy ”{JÚÞGy¨$À¸â«Äµùñ°Î—ù9—î ‡¢2ÎM'ê.ùˆZäÍÞüdHãLÍtósA¿¯2ˆÄ2¤ÙÒý=— ¶7sDÌ—i ‹Ãuª+ˆt’¦çð¤úüÚ&¿õI;.­ŠAå“õ0²v"¨Öëƒèz˜‡](%Ž:k­(œ6ëf]I”<ð%ŽERá-wÏ9þìßQI·e<Â}<ÚÅå]Bq“›͆¨TQÏ‹YµgÓŽ5Oj[}}c†Ãq AC(TŠ-à%föŽÄõMAŒ?&)Fã’¿íàCgT…/ÇyKq5½¾‘ ÷ªõž6Á94QŸ÷:¼O½&¹å€ÙfO™Ê¥G£! YÐ6á,.ÿI¯ù‹Ó¯u1;’N4Fß]ç¶Í¸änW:ÍE/Öç‚þ$}ã騽fŽÀjšo5ªKÐSÓÕÉYkü¸ScRt;yE2Ž%iøT¦›c]øÝq‰yÏmdNþñTy:TÖÈ´õüÌcÃâ¤- ¯™­Zbü€¦’¹L¥ôU‘ýhTa&¬žpO;8ÉR@B \nÓmÅ€Ûñu}khüº]ü=þ(™A endstream endobj 1662 0 obj << /Type /Page /Parent 1727 0 R /Resources 1663 0 R /Contents 1664 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 1663 0 obj << /ProcSet [ /PDF /Text ] /Font << /TT2 2104 0 R >> /ExtGState << /GS1 2110 0 R >> /ColorSpace << /Cs8 2103 0 R >> >> endobj 1664 0 obj << /Length 2093 /Filter /FlateDecode >> stream H‰œWÍrã6¾ë)x«Fà ™kŠÔ”5öÖÇÉL*;‡qª\ÙÙwØwÜCú"i tfR.‹H4ºÝ_}5¬Þƒò¤7ü¼’Ê áQ¦‚( /Íã ÉBí ÿ^½/Ÿ2ïቾ ½§‡/«÷»^z¿<­Â %|ó°ZŸ‡Ï+qøá—GOøu•Ó¦ÜKà O`MgA²\Ú£h;ŽâwÿSüOÁêZ…þZê aæýø‡×ÿñå÷O°¢Ä£’ÄÓç'¯Ø½óîÿï¯c˜…wq‹Ï~(>½óúçÏ¿ÿçñëo$D‹¾üä¯sáý—~ý ÿX‘Åd ƒ&ÃÖHƒçççÀ×Oxê# ¢áȆa Äƒ]úD’̰’Þgo¥â$Љôtd™—Hð¤6F™÷õqõóêj¡%|¾ôÆäÝ="È{ÓÍœý—&aÿ¼}>yŸœß›¾¯Úæ¶è<ÎG!¡·–ˆ@ñ»tÚ’²Á½ü$ˆDáã—¢6ÏËvc<8=>» _ëQš©I^Gé¯5ø§m¶u ê¼Ào{Èã_d¢Ìîîâ(Ò™Ëm˜„ÉxÔæªÄÛ×pNcìpð#° :œ&¢‚{ŒD³Ññ‚ÑdE4w‡²A\Ñø‚rQôý©í6(͇HâR]Òqrq˜Î=L¤Â\Ñ丫Ûß“K³ÙÝʹ”Œ4“,%)û¢¿1Úí;5úN}‡NO„ñ× ºlcW$õè¯Ñ…;Œ…D´‡¡ò׎»Íó0 D„³\h¾@§áäÛ0š[ É‘0ÛâXóB_Ý›ºÚ£&®-‚·üÂÉè pó-F_JÑ'Ìñ3qç¯ •îxàH[¿ 5c u?ì T/ ‰ÜOBb›—ƒi6ˆs´gž˜z¼(=b¡ÖãEEp0ÜO*†mU8õ;¼Và‰Püˆð wh5JW3éŠÃ Ÿä³t…hˆºö¼œÅ&øˆ.ošÍ”c‚Îb•ÚRÕmÁÓª Æø‚€Ušâ®º-‹º‚$ËÓ×nú‹äª}B‹”šáÈèâP{ë¶í«f‡"®‹f‡ ‚ÓQƒÜm­Î¬‰£Ñ—ÝâÜÖ~DVƒ]†èAr‰þ=1cÌ7 ®g™ » ¹$.J¼×XÄøó7S»i ”¹4ØA‰ªhqÇi±§!\ÎŘâ’ÓZq’ÇßäG¤)6mSß9/„ÔžEÅÓe¦~»ÇÔ”{/Vݱ¸e?B*E¡:_“‹ \nö>ÞV‹K¦âäæx{¥ãTÒ¸h½ª®Ž£U6Y”Í-ŠA„„CÑ„LÜ“]‰í}¼­Š?E’ï-+={äC½ElJ!Ö‰­·€² -ªÓS“º2›chLC@Ò™èx FOƒ"Ï\á£3ƒ3æ8£É@y§PÄüE²Å©‘ñì{‹$ÿ§LÛÙÕmEU¥æ¹fI}5ꯢYvEœ]rªÚÛá=?ZI›VN ¦‚#“ù h€ä½é tavRñR—Åë[*â‘âd5Åkò—Ãßþ1妌ç CQ<'Ü·aàr`ú2;ñýVMcá øMèéd½ Ç@ÞG”)U—ÂB:/9]cÂdçwƒ¼×J [‹˜ÚD¯Poòô2ù½çƒÀ%íÖG´á_ ü œ!ÝöɱLr¯ ëS×vðÑ>Kn~Žx d”]EýG"\>×khrtpÄ#PM©ÎyÝú§§H”ÅP’;>¤¥ËKÀ§`ÜùävØPQКþò;fC°¾]ÃÌÕQèó îrûõ=„™N]mÍE}mÌaÚ€áñÈÚS×”–q¾l”É¢ÎÝ¡véèsÎξn¸¿«¸É¨c³î·n×"_hd,C³˜#2k´Õî%€¿©¤½w«iÁ¨=اծf×??²«“™¶8EHɱÃ:Œa¬ã¹–}qo‡rí³çïH”¬äöÏž”ñI©» :()sN *Z “È‘ð¤ ï8674|J³1·UÉcÃdÉJzH$WZ,ÁÐEgw<S5ÔÕÕ>¶•i†ªéknÆðĘ‚9§KIwȲ`à?ìŸ[Aß d¶"f:ž ’¥Àê£äB+çÒÿ`86:¦F¤(Á)BGÂj¡Sw,O©-s+“É$FãÝwÑÈ£¥{¥B ©€✠ê[ýÈØ]}gj äU-êéáN¬…Nå–‘ЍüžRÔ™œ“F—íæÉ˜› ‘šÂÏÁ°7à'©Ù9N̸*ØŸ‰3‹Å•7Xì{]ךI!öñËœúfXý9K ’ endstream endobj 1665 0 obj << /Type /Font /Subtype /TrueType /FirstChar 32 /LastChar 122 /Widths [ 278 0 355 0 0 0 0 0 333 333 0 0 0 333 278 278 0 0 0 0 0 0 0 0 0 0 278 0 584 0 584 0 0 667 667 722 722 667 0 0 0 278 0 667 556 833 722 778 0 0 722 0 611 0 667 0 0 0 0 0 0 0 0 556 0 556 556 500 556 556 278 556 556 222 222 500 222 833 556 556 556 556 333 500 278 556 500 722 500 500 500 ] /Encoding /WinAnsiEncoding /BaseFont /LGMABL+ArialMT /FontDescriptor 1692 0 R >> endobj 1666 0 obj << /Type /Font /Subtype /TrueType /FirstChar 32 /LastChar 150 /Widths [ 250 260 552 667 469 833 802 281 354 354 490 0 260 333 260 552 469 396 469 469 469 469 469 469 469 469 260 260 667 667 667 417 0 656 677 677 781 708 615 729 865 396 375 677 635 917 844 792 615 792 698 510 688 760 667 896 688 656 667 365 552 365 583 500 0 479 552 469 552 469 302 542 552 281 260 531 260 844 552 521 552 552 344 417 313 552 458 708 500 469 469 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 490 490 0 500 ] /Encoding /WinAnsiEncoding /BaseFont /LGMAFJ+Garamond-Bold /FontDescriptor 1694 0 R >> endobj 1667 0 obj << /Type /Font /Subtype /TrueType /FirstChar 32 /LastChar 46 /Widths [ 250 0 0 0 0 0 0 0 0 0 0 0 0 333 250 ] /Encoding /WinAnsiEncoding /BaseFont /LGMALP+TimesNewRomanPSMT /FontDescriptor 1696 0 R >> endobj 1668 0 obj << /Type /Font /Subtype /Type1 /FirstChar 1 /LastChar 1 /Widths [ 460 ] /Encoding 1700 0 R /BaseFont /LGMCIO+Symbol /FontDescriptor 1680 0 R /ToUnicode 1701 0 R >> endobj 1669 0 obj << /Type /Font /Subtype /Type1 /FirstChar 32 /LastChar 32 /Widths [ 250 ] /Encoding /WinAnsiEncoding /BaseFont /LGMCJA+TT127o00 /FontDescriptor 1682 0 R >> endobj 1670 0 obj << /Type /Font /Subtype /Type1 /FirstChar 32 /LastChar 181 /Widths [ 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 ] /Encoding /WinAnsiEncoding /BaseFont /LGMCME+Courier /FontDescriptor 1678 0 R >> endobj 1671 0 obj << /Type /Font /Subtype /Type1 /FirstChar 32 /LastChar 181 /Widths [ 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 ] /Encoding /WinAnsiEncoding /BaseFont /LGMCPI+Courier-Bold /FontDescriptor 1684 0 R >> endobj 1672 0 obj << /Type /Font /Subtype /TrueType /FirstChar 32 /LastChar 122 /Widths [ 250 0 417 0 438 750 0 219 271 271 0 0 219 260 219 500 0 469 469 0 0 0 0 0 0 0 0 0 667 667 667 0 0 760 563 625 729 688 573 0 771 323 0 594 635 823 781 677 531 0 625 500 583 719 802 0 0 0 0 0 0 0 0 500 0 406 406 271 406 292 219 323 417 229 208 521 219 625 427 354 406 427 302 292 250 427 344 531 500 333 417 ] /Encoding /WinAnsiEncoding /BaseFont /LGMDDG+Garamond-Italic /FontDescriptor 1698 0 R >> endobj 1673 0 obj [ /Indexed 2103 0 R 70 1674 0 R ] endobj 1674 0 obj << /Length 228 /Filter /FlateDecode >> stream H‰Õ*ÿÿÿÿÿÇÅÿŽ‹ÿwqÿUQÝ&!º/,uBBÿ½½ÿááÿ§§ÿhhÿ||ÿÙÙÿššÿééÿŒŒÿ²²ÿMMÿððÿØ9ë|™]‚º€‹úPQÐÐÿÇÇÿô½ÌÕÅÀQüðóãMuÿQNêA^ÀÓ)Q¥,ñ§ºïš±÷ÐÚó²ÃûéîçhŠâ1팦öÇÓúáèùÙáö×6?@ņi‘™f3ʰ–ïèआѺ£öñíùöóóíçÛʸä×ÊìãÙ@èÝÒ¸”qÖ®àÑ x©ŠŒ endstream endobj 1675 0 obj << /Type /Font /Subtype /Type1 /FirstChar 32 /LastChar 32 /Widths [ 260 ] /Encoding /WinAnsiEncoding /BaseFont /LGMKMF+TT132o00 /FontDescriptor 1686 0 R >> endobj 1676 0 obj << /Type /Font /Subtype /Type1 /FirstChar 1 /LastChar 1 /Widths [ 1070 ] /Encoding 1702 0 R /BaseFont /LGMLGH+TT134o00 /FontDescriptor 1688 0 R >> endobj 1677 0 obj << /Type /Font /Subtype /Type1 /FirstChar 32 /LastChar 32 /Widths [ 248 ] /Encoding /WinAnsiEncoding /BaseFont /LGMLKP+TT136o00 /FontDescriptor 1690 0 R >> endobj 1678 0 obj << /Type /FontDescriptor /Ascent 629 /CapHeight 562 /Descent -157 /Flags 35 /FontBBox [ -28 -250 628 805 ] /FontName /LGMCME+Courier /ItalicAngle 0 /StemV 51 /XHeight 426 /CharSet (/Z/at/slash/P/bracketleft/q/B/T/zero/r/backslash/C/A/one/s/exclam/bracke\ tright/D/two/t/a/quotedbl/G/asciicircum/three/u/quotesingle/x/I/N/H/unde\ rscore/v/four/E/dollar/J/w/F/five/L/percent/y/six/d/M/b/ampersand/z/seve\ n/O/c/braceleft/eight/e/Q/parenleft/bar/R/f/nine/braceright/colon/S/pare\ nright/h/semicolon/i/U/asterisk/V/less/j/g/plus/k/equal/W/comma/K/m/X/gr\ eater/l/hyphen/o/n/Y/question/period/p) /FontFile3 1679 0 R >> endobj 1679 0 obj << /Filter /FlateDecode /Length 6510 /Subtype /Type1C >> stream H‰lUyPùžž¡§‡k8šFèÁ\-¼@ð"jPÁUq¹o.A9äÔõ "qDäX9t9™n@YDT4º“¨›u¡¢ÆòzÍþ°6 [ûW¶ªë«ê×ß÷ê}ïýÞ¯1‘X„a˜™÷zŸu =’Ó5±‘š©;¯ñv?SÌÏ”ð3 ÊM0”f"é51àgšX'£#²‰.œÑb?—•ý‚&¤šA¡gg—k)’`˜,#ÇÙy±“³³³GrJ–&6:&Í~^ø|{·ånŽº9O£Ë4þ~]§qé4.›Æåök"’wEÚoÉJM‹LLµ÷J OÖ¤$kÂÒ"#œìí×$$ØLeNµˆLÔdÑ_]ˆ0‘áb‘á2ÑZ;QŒH¤OÅDKE;1+›‹×ˆÓÅÍâñKñO[‰‹¤JÒk`apÀ 7ÄOàW¤¿“ÖJŸ†Ä¥×ÒAt}_ž&|D¦%ÀÌyƒä]xÍߥVI«'x‡”|Ö…l¨ ±uñaI‰‰‰‰º¶úú&FMÐY&hV@ ¹“÷‹¤¤¶uâפÈ:©…Ò©—©ü8¸"G^Ã/½å{v»0î5§'CEäÖ|þ¬ ÚçžgÎã§Ôµ½4w¿~€>wuïK×)Éx‘š…*‚ m'ªâ+cŽÊÞ~Al*9›.%ÒËý_Æ0ä¶ü!ͽ’o“dõ¹Ú=‘ô*—l¯mÛ*¾‰fÈ*QŸ ¹²„ò2Ñšy1ïÊ!ZÈ#!'oÞþŽ–çõÃÝZ~äûÎrß²ägògþ5~cÉêÐͽ®ù?Õ÷ßaK©¸Ô˜á ç/_®kì¸RÅŸÁ}ÒŠŽ¸ÛnÀí¸ªßà~„rjŸ~Ò¹Tãòêß0¿*9 Üõ6×ƨ¤õA¸~^Û,$§ÑĨ— Ò†ÀæÒrøs¼ÈÄ ê¶„ßËϦ²GÑœ cà„{H!'äл×fE-F惱Áè!2l^æ¸X êX _‹|ÁO…ü¿ ü‘ ~„Qp/X%w`J9J× #ø°T»9 ”ð@Âï€Ý‡¹7Æ  /뢾In ŒO‰KlHj¿Ðr®™‘£Ùϰyg _>±’Rk'±Ï·º3¦¦Åg É 8¨ )‚ëTWÉ÷Ã̘õ™™d)—k¢óÝd% ¿Ê¥žAa°|ŽCÂ8£*¡ ‡l4 ¹¦<¾ÕÚ@e~ ž9x{ψÜ;A6¢”çrPÀªÏò gïèÉ$Ïçòç¨~Ob½ïÞØ`åò-~‹Ñ©ÀÌ÷C~xÿðoÿó~ŠÄKÔêÈ$e9`Ý/ŸvÈH^«»^Ùy¸üÐaE™¶\Ëü©¢¬ô¸’ü0)¡T±›æ„4]Ë`Š+÷׬‘]¯»Ñ6¬èèÈŠ®QVdפÑrm_ÉaoYh¿!áËø j`ÒÍdÿí ž¬Ä¥òÜ>H部>áFà ”fÉw|>8Sÿöm‰®dÈW-Õÿ¤GÂÇ=ûþ³}êîjò]zÞ—á.ôÒ»+À‚³ÑGcJò•h)ï 0X׊ߌhxtUí/P«Q-å¶*ÅO½ðÔ¯ÿsºý»á]ëyn?xõA¹ÐwCš…¾'Ôƒ½/ü{™Æ¸ÐªP’¬^¶ÈyÀLoܪÓ7)÷£ek½5²Â¤¸’¸¢âÃEŠ €é%Ý×'uJ0jøÑ[tTTÎfµ§b±š½Ïõ<Öuì‹­Uj“ª¶—‡Ëä9` s¦¶u?(%¼ Q§³/oÖ5¾)åRë…ÚVUü_L‡§DG¦D¶¿%JDþÂÊC¸"nIåg2°±. ŸWJqúsÿÇvµFEu]aPï½$5ÒÎí kî]@5j¥E!QƒÄ ^_0 B”aðA#>P”j—Jˆ AAä)(èÄ@5,¨ÕªMcšhÚ%ºÏʾ?zWt­{ÿý}¾³¿oïìçÚÍ ¹ a sü‡¸þ;ͧDO´`U Áè«whÁKvg®ÔÊÂK @?À‚ À©ÓA|ÙϽrðI‡F¢ƒ·å O"àqY|I7Q}ùÎòmÇäîäÙ§B¤ÈÈ-› st Ågë ê$Q’0G¤‡d)^äªÐW ®50Ò þˆžÿŒ+«æA5XjÀ¥Æµ¶z°ÆTÁ„šá´ Zõý›Íõò•èÐσ% ›„îè£zXÃ^ôàáéÚkJf5·bjXÆ­:e¨`Ì—û’Þ;ø„‡ÔͤÂ5^ìüâpSRvòˆÝnéï™D,Û,é›e‹9vQ· þ_qvon“Ò’[›°Â žÃ2}Ê–uk3åŒÄÄ?­–Тa<ßÜ’³¡V9‘Y”šb`C3®=íÔ)ÇÑ©ßЭY6×:GBݤo` DÀÛ—ow_]glRÞw€yéB!¥„+_U´LB?o4 ¾÷OáwúOïtÚ&59{‘¾f¾Ià’ƒîx—¦$ïûXÂÜŸN”Ì75ü9¿NyQ2ð jŽ~qöbk¬¼ aV«„aÔôŒ\·'®U©J­˜ïop’¸Š@#q¬üI‰"¢&þHk<`‰Šcñ¬ÿ±j0úCœ jЀc ,Ñ6¨÷4ÓL• á >lº!·Y‚mT§‡ÅÚzµ_3} BÁÑ gÚO8Ó šPòö@¥ÄÕN¨ÈÂþ ñ¬e¨0G éáoU%œ>Ö1gÃð›Ïnt&E7)³˜ÕyB}ôœÏŸÁ1ð„à êÍÍŽKRÓ!Æk#¹¼éH®@3-ºq'Æ¿t0ŒûNp‡úR[(à9º‹C_ge°wt¡á<Ôi;¸^jãÕâZKè»,î Ôé¿]qhÂýÑ Jƒ(1mLÿ$”Õ<=гQÀÑè1“Õ€øø‚̨Á™ò’‰ ا°3¼V:ZÿhåSœ,㱟ÔPK˜6'ÂhþÚu[{RVYX_oP=Òv®ßúGyùºˆÜÅrPÀ8Ú²¢N³¶| µeÔ‘lÇQbI§gˆ®¡e+Úi'œÑweuZ[åë‰!Ýè"ùM_`TÒŒ™KæÄô¾‰.OSåŠN´X­«9£(v̉æÊ¢©¹vcv½"Úw±åÙ¤jû‘²reS—•ž¶=MÚ¾}ßþŠh)Ž/‘23só2ÙR[~a~a[1c\žC¤Â"o'†úáˆ6ˆh/l.­–ûúìR{êÔóJiB~tôž# °ò„Q¯FÅ~2^H&‹®¹èv­àq¼axhü !cóÿ$pü¹è‡¨;涇úéqŽÈýH~RÁ‹oº¸;®L9”qð“tö~"«`nyÌ4n‹.:ÌD<ë"Vn£¥0UO’M%rXå»Ya§ÝV]ò‚¡ûZë×2[réòæ¤jElp™â€öЫrI*Ö,³-—Ð{ÁÄ€Ékæ(â™m÷’À¥¢Gu³eHO7Ì_¸Ú{AøÑº(YLqPq.V×ÕŸÓ,±maÄ3¼ñ³I¶u~¿¤W© ‡­cã1”É—éÔAÐi"Ç; ˆZˆ+‹¾Î˜ú~¨sÔø•€î³’ßOLøô˜EŽ9“Óá0€ó9‹{Ô{Ø(„ìî0Êkë®d;¤Ö.›½V©¯þ¬³Û·˜¼.Ò$¢; V´Ò‡h³x“MÖß A›Õo Ò’0˜&qß´ª_òÌHmÜ]>býoÔÞgAΉPWÊÊt0ŠŸÐ¡@£úƒ`ÒüñMxÁÅóâytCˆ¥Ó¹§£Õf¾ƒAtóÀ±AæMdScû˜“ ]¬ÇXæ·$bHY¢à4 ÆjóTŠBQデ «²øˆ¢ø‚QcTD¥Dð¢NçºbP * "jtÕ”Z®“Óx&[{zŒ©ò/ª†{î½}Îw¾û; 0J?á>„À9îeéìà Þï  ŽÀ&^åÔyœÍ釳íÄgÇxgg2Gðå˺ ´¾åKg» `dñûJš?îºGcœ‘4z˜œn]?ÌZ®Ò(ǽ‹ZE£ë_S×JŒPÀø»d‡j6ìq{©z»«ëÔÓ~pKbݼúX]ÚÐxeèxý,¾¥üÇsÇÅÈk³[é=pãy· êsR n4w>ÕD”È`˜<Æ‹`v!Oµz²@(àË×Ê+—N,‹;2B [¾dš\ÅY*n”7‰•G×f–æ/H3§óÅsfQD”ëÄúO_µ^¯½À$!o$¿žF°N›0Jœ’xêxù®}{KåƒÕögÅÓ5kjä·7ø#Ÿ7þf‡§LȬêÈ0/rw¼ûOŸ¼8G‚½è¥tòBž³4@/^°^çsKj&B/z߃žà&+žÞ£ÆãgÃë×îƒÎ6d”Dϼr¸Ý`ð„Ò~øši)ã–.;m”ˆŸ®ݸ ºú +ç×ÊaÔwJ<_1+~÷4C°Ï'ø7pƧÍGÏ\zï¢ô|>ÓRuÇ“V¯ãtúâ¾afø®(E?4Q&P߆dÍG.ž dóÿ‚Å”Œþa¡>Ø=òáOO®ß}I¿ƒX90LÖ.:†Ñáv¥~¡‰êèySÎnÎØ±Ù bÂì-æÉó÷gØ/˜·ªC )&€;úcŸþ~(á×ÑÆut–W5J!Í„¯t—¶^ºœRÅÀÅšµ@/RQ¢Ã]Ý¥v™6§…nMS°ûú€l¹0oÃÒæ˜þämýÕƒa:´A:ý±ñg¾9ºã¬ €æŒ¶kæTÃ>gÆc ÐNüÛ HÉz^è˜ÆOpt4åhäûÞêî¶°ž’±?46{†GìÙ-åGq_ÛîgwŠÐ붃ªF{ ¦èé(™üÇNôñnêx|¯áô«¤¸ÞIWÂ]Â~²¹vM›Åü•e-¨ÿ4"ev¬”•û.Yd±ØÄמ½|ºQ¼k‰SdÌ tA}þs0ÁÒ¬0á©ð_x 2a<xXë|ðÜ]óňY?´ƒ'¤c, öÿÁ“ áçžM:›x2´é#A?ðàžQ È"q™vwŒu²^ykg¥”¦2Rù:¢±PRåR‚œ¥8î] ÆkL#¬aìþB‡úܓŀ…Z©ökëÜÒŽììMËÅØ¹ æ/”«W¦VÆŠs2f,”…Žº~ŠÍiø•ÅÒZ8ÈÞ{ ²N¼º)øŸ2^ü͵Çö¢cLܱc]Á6ùè—Ræšñ¸ëÔV‰ôZñÈ»ojÕÛÆ uÕkNg”I»—¥—Ä‹a2fÅÊBÛôšÑ‰­oëHk`+¦¦©ê²Xëø*LÆ­Z)‰¹i¼µ1µ¯‰ä§ÃǨ~õŽ°Ï‹ADYƒŸ½€Þ1‡ÏèPÔ¡8éIÇÓ›ðð¯D(MÇ 4¿´ÃÏŒ4x™ªWWçUHBGgrÈñ Ñêü„ù$Ï5ãqZèZµÍå“+XÒc<ž¿‘’£±ûˆˆÀ¡c›_?n¼ Ý w%ꦽŒ•ÁÏZ»´c´‰¨–N†äaá|MFĉ@1hì¼€d9/}uJŠÅ熦²ú³¡þ…‡!Óèü&ޏ î+A½¡[Óè¡ÒÛÂ&ÙÏè­®VáiíÞÂ=ù»õe¹‹¶¥‹ƒ'…(eá:èq‚½Hܽõ†Ñ0‹ªnuGmbÙþ‚ÔbùmvOY‚ªìéšäoª%ÐÛÔù]Øf)l³ßÚY‡õyÛó÷ì17<,©•„6Ær²jäH; ‹JæËgG•Ì 1m\´ÿââ¬osä ñmE· ô£Ӆ¶âòyúÍk6æ˜C°ûê”IÊ·ÕñÒ%ƒXÿ¥ÕºôŽHϹ{{ý×5‘”P»ï.9fÎgbVæË29cßšª*3Ñþ‹ù¤IDz¤%'VOضÜl•…HËö´eª-  …öìtY_ŠrSÛÒoÓÀ{›»Å0Sy ƒ`§A£š`Õ@œÐª¸BË`$Â0 }à ¦4SèHtøC9— ‰eþ`×f¦‘J¥ºÑWtíPÔŽEDE¯];¹¾j$a$ÄÁG0?ƒd¡ÊÔêÉ‚y ‚Nhoĵ1œ¢œÒ¡;Í =€ç¾g§´ëÀ}9áa(¢@£ §/H`F‰›¬¹^4#×3~3p ?†p⿟\· W<ŽBõ€Mc®Ê5LÂ_}1ÎD7ŠÙÔ©–?î馵}%õé&OðQüðíÐÁwšñ¯öG°'-Þábˆ}r˜±ŒÈÓ öÓòÌ!Cž^4ÏrÕ A¼uýÃàï¥VÇ7·­f寷ÔIŒŸ¹.2ÉLýÊÌÂ/ÒÌØ“­ãS¥þfêî ì­ý”VôEi¦t`æ¥|ë:}ÞäºÁ¡óîÐNðó&7ö¹ï}H; L6þÿsY[±ò»¸Ôwö5í«kWÈï ˜ÕËÂ~¤}c§Ôo'ö¨ÛëÁrö‘]ÆQR¿íØ=Sk‚ÚåBØ÷ô›¶xÇÌý«×€´Ÿ³òÊZ9¾Ê¿OxÅüýý ¢:l ï`ÝÇÆW;óÇ…¿µg~´à·k7Û÷†Iºÿ¬ïeG瀉sâ:ÄýãŸeq5 endstream endobj 1680 0 obj << /Type /FontDescriptor /Ascent 0 /CapHeight 0 /Descent 0 /Flags 4 /FontBBox [ -180 -293 1090 1010 ] /FontName /LGMCIO+Symbol /ItalicAngle 0 /StemV 85 /CharSet (/bullet) /FontFile3 1681 0 R >> endobj 1681 0 obj << /Filter /FlateDecode /Length 251 /Subtype /Type1C >> stream H‰bd`ab`ddäóq÷uöô×®ÌMÊωXüfø!ÃøC–é‡,óq–²> endobj 1683 0 obj << /Filter /FlateDecode /Length 81 /Subtype /Type1C >> stream H‰bd`ad`ddðq÷uörÔ 142Ï70‰)ÿæëV¹ Mÿ»»á ö›‚ÝO„@Ê8áz˜™Ùºù~Lá0¼Ó§ endstream endobj 1684 0 obj << /Type /FontDescriptor /Ascent 626 /CapHeight 562 /Descent -142 /Flags 262179 /FontBBox [ -113 -250 749 801 ] /FontName /LGMCPI+Courier-Bold /ItalicAngle 0 /StemV 106 /XHeight 439 /CharSet (/F/W/L/K/parenleft/t/underscore/M/parenright/u/T/Y/O/A/H/B/k/Z/C/x/quote\ single/o/R/D/comma/percent/n/d/p/S/N/G/E/z/e/U/equal/I/f/r/V/P) /FontFile3 1685 0 R >> endobj 1685 0 obj << /Filter /FlateDecode /Length 3026 /Subtype /Type1C >> stream H‰TU Pgîž¡»Qašî3Ú3WIÈ]Eɲlð$YT@a@@#^$1ˆGE£îŠ#DÁhÔ 4вBDTtÉ–Qé_+±Ð׿M’ýgÄTmÕÔ«þÿúþï½÷½cXÆÃÀ°,ë5iâÔèaÓ—g&'f¾1!=5Áu?^·0z?VïoУîç±É‹Ål/c½—‡nõ’‘Ã-/Ö½¨á”}ìïEE/­—›{CƒÏ¹~Þ’/ñ¬gƪ‚­AA£Ô   ‰éy™ÉK’²mCâÿlHmXÛwÛ‘n;ÚmCÜ6Ô‘¾(Ñ›—•˜–e‹vħgf¤g.ÌNLPm¶ˆÔTÛtg–mzbVbf½íÎÃæÊ£ûûÿRcX†g˜,ãÍ0 à ôd9f$Ç„³Ìx†yËÀÄ0ÌË03Xæ]†™Ã0I 3ŒjŘuL-óˆØÁl ÛafXa¨3ŒéÆ ã·=þæñ±Ç%·Kæù(>?Ï¿Æ  5Â%Ïažžß÷°öÈèQÓÓ¯gBϽ=ï÷šÐ+½×SJ+ØZ;\Æ÷L+˜Zã]FDx¢§KW§¶Œ5>âBô½JGsc‡u¢<'~yÂÜôÃG+9]W‘²X…½Nƒtu¿MÁÝàË/Á ì àƒ\îã%(”MÎ71¦bg ~‘ÆBñ#£ž,; 2 2ß>ø¤ü¼RV÷ɾC ž#øˆÓÐ†Þæ©%hC”— ¡ŽHW€ QTþìˆ+(ã spº¿#VÉœ³>'u†ç]¾íÙ°·ÙÅ,¼«Œº!æGa1Þô_ÒBØÛz„Qß%âŒP=G¿ü2‘fË »Öƒ7äu"“XgëY~ BoCœ27U…õ$˜/oæ`_Å…ªüØ&aß4Ñ"Aú_à5È‰]z=Œ–Nå}µ¨Lõ¥%\UÅÞê“æËóîâO¨íNy¬ ¼Ø½/·Ý±Š:úÀV)f|AŽ‚~ÐúòÍû—¤YÅ®ÃX(M~;ß¡`(˜¢p«i¦u²õniF½é†ÛÌ-_¹àM Ê3ŸvQ! g¯ÔŸ]‘Qk Ô ß¾Pرzö¡öÁ¿ ðN†”cà]ÒrÝJÐeÂvip€²5ÂéAJWài¥$aþÇq<¢ÞtÊcTØÁÃx­ò¬ö RTîÄi‹•œäÄ–0]އ'B»¸nWTjûk¯S9Dí9NÄÇz ‰*zb>‹&‚ø;d«‚ø8z „zÄ^’œ…ê —#WU`()«¾A)í¹VIÄÄßôsð«KœëÕ6§<^…Z‚½ñúüïš þÙvzжÁë°†±§@EzF ¹Ó·ú>\î %´*0Y"xˆúÖaà>¹€{ßá(L³¼3ó_µ‰Ö”ªÕ _›Áöã÷š"v5ÉI;mµX­ÎÊ’ö½eÁ@ôBoŒÁiÐ߆Ҳik·—X!À3Å*„}¢ƒÊx]&ãtù:Áj;*èå&Á"õºS§Bvp }¬;[—ú°ýQÿD&8šª9š8ÃUsÊöRŽ)9A1¬^kÔ[eâ/dŸÈ¬rÔæ–ÏoÈßáüZÁ\µšÇ`´s`o'¸¹»r›ÉXðÎ7”fLütYߣ3*'•Îò|åØ_ƒĨŸ“á3#qõïE°Q}à”ÿ¯À—4+]Ï¢ÎÁªAPÅáõÿ‘wTØ@ùbh}‚UtKuÁ—»±…S]“3“Ï×e®›èžÛ(ÑÏn¢Ý*ÁoÜ à0ª[›OÉPhæa§3»£gñ¦5º°•÷áa§Qÿª$0†Ó@Ãp0Úq.(à÷ÂZa¹´U "ú¡0ýùãûÀ<ü©åH…úÿ™@,MتA& ¡Fï-Õ­>™Z©œ^¹;Ú‚ÿtÍ%•ëAÓÏЃ‡^íÿyjµo‘æefæ®WòÓ’Š’-c ö_v裵¥Ö/V•,]bv•ÇL`$%öÑh»õk2/ ÇvqõÅ5WÌ—ŸY¡”$ÅmYdÁ2õšÛM!‰ó þšJS>[\œÔ7_ƌ٧ ‡‘Ї/kúh‚Õ´šNºæÛ¦#°N‹ì‰xU/‡P©¼ bÕ~eV»ÿÚð]žË¶Fïl4מªëPÄUUkß;l¦ÁR{¶°;%~{¼_ð›»/îxªU¼ûM\û¦¶<Ïl8´2Îü„%Cß[\¶P¹nÇD­RX_r2£Í"^…>O/ƒáÕn8NÀäúù…Òýð\‡³|ÀD{ÔK… zÓ¾1¡;¢$ìC Þ§"?è®ó}Ü#ŒÊž€lAÓ× Ñ\—íX&LÜö×–8ÅqªúÃ:KmõŽ=UÖ¦òmÍf8%˜öåèY„Ý…"£þÐÍU¤Þ°þBÿ1~án¸æ«‡)Î,ŽðM÷v÷«Bȃa®Yyê~•«!úC)ÍàçIpŒ£1ä©_ñMôíM8h¸vþ;‹;oßÏaå&²VŠ-"Ño¹™Vª Â`ëc¹z×é/¶@îähÓy«p›`/ðÄKt]ï|Õô·4(¦b”ʰڎpôáÜ¿c1]_XHýÒvL¸ù,[¤ÿdÔú_‹åSUÆñÐÎ9…yßÁ=ã\rnm(‡5[¡\~Œ.,±!&sBÂ!§˜ÜZ`:÷‚ñCP~xEÒ»¥@cÌ"µ ‹q)#G®óJlèZ{ÎöðGÏÉþ}Ï»÷xÐJ ü‹?äw9x)ʱïå½3‚c[JE²‚A%?\;a3Öˆ®/Ý}VY;‡2‘WâQàß1bçÿèœR#¡@ÆâxûD÷¸2vǹ㒩pë zm¥òuR®ßè7–dÆ…úŽ:‡’“{ìP±-·ìdV–õÀ†˜toÐŒpŽÙà†l³û¤¯ÝSCÞêcƒê¯qNž°F÷AæÀçDô“„y·íÓyWá%=ŒO86hÄÛàh'¦l!¯ˆƒT‰¼´ëzÉ`ᵂð M4_sq»nyJs¢Sd?ÓÐÂ~‰y{ª¯8=ê cwËJfÆÇåy6æïÅDít%˜äާ;/ݼõcÓåþG w$jfŸ › =?ÁtÊd6Á*L¢µ…Ù1ã!z;éXëO𦪹娸½ñÛ#/ÁЇS£ Ø›”®†àV>«C3·s ’º½H¶W!³D<«/jgæÑ’}*[ìÃbU2Ñr‚ãZ’›³}äC¿a ƒlcbNɱ[2’sÖuÃóôÇçÚoLßÛý†úÒTÂÎ|Æ=˜—ÙÀ…ãmÇ[UOMé@ª’šž“Ÿec¾IÜ£Ñ>æŠÔ Ç4Ø(±þ¯ú/ÓØØ~±±SñÔWTg®!ÐBÜ{2úV®Ò…ª¢×rÒ”¤C7mLèÇ×0ü]mwIñ´rrÆß{ù®JT·›±X–þ„ý:;bL†òxl6ŒÊ‹{$Gqaiºwò».ô`<¡b«´¯þЙ£ê;]3åÊmïyÏ€qHÏ’²œ'™ìá9(Á|p2?ar6”ÇIT«Àü¢@\¢µ‰ïg¼7&´s<¬ý&²öˆ€&lÒÀÉËDÿÌl¢PþL"n=à4u¡ðvL,¦JÐÝÂýåu¸YŸ†·$ìÄ‹æä‚FM¡×Àj–k¬4|2*"ëhÂQVŠ!Ÿ6¾&Œjè¦ÓçDhøb9Ã%}Òbøšq} Ìw`Jm |vöIír¿{âÁ®BŒÅ—ÿ%°¬Ž endstream endobj 1686 0 obj << /Type /FontDescriptor /Ascent 0 /CapHeight 0 /Descent 0 /Flags 32 /FontBBox [ 0 0 0 0 ] /FontName /LGMKMF+TT132o00 /ItalicAngle 0 /StemV 0 /CharSet (/space) /FontFile3 1687 0 R >> endobj 1687 0 obj << /Filter /FlateDecode /Length 81 /Subtype /Type1C >> stream H‰bd`ad`ddðq÷õöuÓ 146Ê70‰)ÿæëV¹ Mÿ»»á ö›‚ÝO„@Ê8áz˜™Ùºù~¬ä0ÀjÄ endstream endobj 1688 0 obj << /Type /FontDescriptor /Ascent 0 /CapHeight 0 /Descent 0 /Flags 4 /FontBBox [ 0 0 990 730 ] /FontName /LGMLGH+TT134o00 /ItalicAngle 0 /StemV 0 /CharSet (/barb4right) /FontFile3 1689 0 R >> endobj 1689 0 obj << /Filter /FlateDecode /Length 143 /Subtype /Type1C >> stream H‰bd`ad`ddðq÷õq÷Ð 146É70‰iýáëî–a#ÃzUnƒGSãÿîn8ƒ‡ý5ÿ;ÁîïZB LŒŒÜÂI‰EI&E™é%pSÛA’ÌzÝ|2ý@£~Ö‹þ-úÙÀúg Ûö²þ»õGò×-¶? ö5l?‹~Ö³òsÂ4- endstream endobj 1690 0 obj << /Type /FontDescriptor /Ascent 0 /CapHeight 0 /Descent 0 /Flags 32 /FontBBox [ 0 0 0 0 ] /FontName /LGMLKP+TT136o00 /ItalicAngle 0 /StemV 0 /CharSet (/space) /FontFile3 1691 0 R >> endobj 1691 0 obj << /Filter /FlateDecode /Length 81 /Subtype /Type1C >> stream H‰bd`ad`ddðq÷õñÐ 146Ë70‰)ÿæëV¹ Mÿ»»á ö›‚ÝO„@Ê8áz˜™Ùºù~Là0Ä3¼ endstream endobj 1692 0 obj << /Type /FontDescriptor /Ascent 905 /CapHeight 0 /Descent -211 /Flags 32 /FontBBox [ -665 -325 2000 1006 ] /FontName /LGMABL+ArialMT /ItalicAngle 0 /StemV 0 /FontFile2 1693 0 R >> endobj 1693 0 obj << /Filter /FlateDecode /Length 21070 /Length1 39816 >> stream H‰\T xTÕþçœswC^’lPîrI„<‚È+ d’º¡ Ù¤UÙÛÙ)ôÎwï™3gÿ™3 aX ‰œqãû&V¹g¯°ÙEžª‰fãX`³èí¢ùsõMñ§æóÚ€­ß´ªÒŠ5ù €=”噥3j¦u[÷q&| QVâ)nÛ·žýåðž'ÊXÑy@g‹ֲܫ¬bnuøãî4–_½gTyèôÍl`Á–+<ÕU!£B† l¯ÏôT”tŒÚXÔŸä|«*çÌå¼ù©7ýëU³Kªò|G¯rü`K;ˆh~ÚND«8DÖe~¯øÿ¾rëŠÝÿßðî–»/Јw¨ïàOxŸnð®wqÍ8†Hd` j±u°ak~<&õ(ÚjF_lã|¶¡•mŸÆBD7в®b–ÉOx×2Fº'F •XMc­y˜Œój)a,f¢Š[nkµÞz;p@³n#1µZßig¬/Ä;6¢çi}‡}Hã(‹ÙòUÌFƒœ¢È*µ~à œxŽsPÈB+ ì½—)Šje:{Ùn™ÖQ¶êŽ)(CÒ@%œÚd+ËjE7ŽQÍ^ë±û™ZpŸS¨vÃzúh$âI®§mtDún/ñ gÄ4F©†ðJ%þˆq’ zOTj¡Z²–¦=o}Š.艜íNÞùº%2-’©Lk$—u~´ñ!.’ƒúÒ8zJô•b«œ ŽØŸ©åŒ÷fö~Žh¿ír»Ú­~´=ì»`…ó‰ÄqÛ¾Š÷(Œ+Õi½H§éK‘.¦ŠWÄ%¹AíR§ì®úT`5vãu¦Á”K¿¢2ª¥:ZGõÔJ'éŠ!&ˆgÅuY&gÉÃj$Óx5G-Õ–k+mW|nßQß_|·¬dk9r¹–pö±•+;€vœe:K¤Q…3é䤉ôÓBZM¿¥FÚEÍå$]¢«ô/ºI? 0ÙDŒpŠžL†˜-žÄÑÎtR|+þ##eO™ Ê™/+9«:¹–iŸ¼¨ª]YŒs²¶I{MkÔvkïk7l¡öƒtâ§í·ãoŸóÁ·Â·É·××l]DW>C£Ð)œ½‡i:Ÿ÷&î¸wñ …2vЧTËÈL¥é4‹ªÉ—¨vrßC‡¥Ïè:ç&ºr~L #Å8¦gD‰˜%ÖŠõ¢Yœ?H» ‘eW/GÉ)²DΕ5r“4å ùwyI~/b²T°ê¡zª8• F©©jžÚª.«ËÚdí¸öµ-ØVa[nk±ýÓþ„=ÕžcϵO±¿lßoÿ4¨€»óìÃïqßCäé’û°F PÑ¢M´q?OE±ÌÜ©¢‘VˆÔ,ziÕ¶abeㆊc¬?¯‰ïÅ0™Ech<¦‹þw¼Ùº¨·ø—¢>À5uˆkkcÏÕ¶PZ(®ÛB±— †pÌe?• ãsyžìjþ¦‚)’®‰2‡»à°JÕÜpÊ-Ø#gÑì.žN?­â>Φ·x.L dú·´ E6wÑ ù%–âYq×ø¯Ào¨X•b P-.ãM¾}´™¶x[Wú³(W^ñ5C¨]\ÝêERë‚—hŠl°]g1í*çäÛœ}»Ø#³Ô -Êø,Àr̲– Fs«ST IO!V]àéV+“•“ÿ‹xªLæ™¶Ÿo÷Až#dk¢¸sÆr_Lä ÑÀ´™ç„â*ç;þ4O±64Û&ˆ”jáÄSPÇ}y˜d½‰z«3­õHâyPgÕ²ÇF|—ÑHË|/  ðÍ9GcµLÑ®eZIÂ+ΊñbÓƒçËhÇR¾aÚÃBªöxÕgáÖ*ë¯ÜݽyÂÖ£¿ÄW\åwa´<‚¾lÑdeÊ*®÷–”˜ß§÷£q±½ŒžN½Ç#wqDGEvëÚå¡Î":†‡…†w²Û4%!Ñedèf\©âŒÑ£“ü²áa…ç>E©³*óAS/˜éZ¦±å´ÿ³L»c™vÏ’"ô¤$%ê.C7[3 ½…&庙_aäëæµŸà×ø0æNÞ »¢Ê2t“ t—™9¿Ìë*È`wM!ÁéFzIpR"š‚C˜ aÎŒ4ªš(2•Œˆt m ã¤L‡‘á2£ ¦ŒuyŠÍœ\·+#ÆéÌOJ4)½È(4aŒ4;&LcÚÒM{ Œ^î¯+õ¦Ä#ÞU-(,H-6Š=“ݦôäûctJà¸fäó_EýOdçÓÝu÷¯ÆH¯+ª\÷‹^on¾žë¾Õéÿæç³Þ+b3 ¼™zƒ8f¼ÎÑIJ|·IË8¤î¯Ä_ÕúJ —_S0]7;#2ïô>‡×D^s¯Ã‘vÀº‡K÷NpNsxŒ‘ïÉèÞÔÞ¼šßE§éÑ®$%6EtºlSxÇ»LhØýLɽµ0÷scòî!KþŒŒ'¹!L½HçLÜ×4Øÿ) oÑ`6ã'Ÿx—YÌ'RnvH/ðF õëýûM-6Âн7Á`\ûöAç®Æq~Öß'÷Z×æÍ„3>Þß"öt>SÎ15 LJœß" £*BçÇÆÖ“?´/ÃïtúxeK Y0çºïÈ: cöâ¿ÜW}PT×?ï½ûÞ®Fë*®2FøEQ?¨Ñ"Täk!¶âGSbcC“¦×!®ÐiÓê5¨©ì¸Ò“6èLBM'qš)¦mìG>˜iB§M2&Häõwî{oÝ}8Á¦í?eöÇïžs¿Î=÷œ{ï ,œWQ+¹¦×©ñ—pMÈ©‰v¯LA$w?eýï¬èo‚oJBÎŽ¬ˆ2åSª¿bÕ¥V“r•¶o Šã$«~Y´Î.E²ƒZ¢j—ÔDMÖ"(7E³3ñ3dPoïòx•R£$åF|•yÖÿò±ÉÉ7Ø©Ë|{IºÖÍ63’5/^þBœgÞ¸°ƒq W„ÃcãêjÖ„ëlBÄSq09);B%ÈÌ™øu™½Ë剑\–Í –Êã&Úårüqt¦ÍÏÅAç¦$å†+Ã[ºÌÐÖ”$_J¸[=§ž ïÊ©t§Ëì9Ém(‡¯v(YH •Vw¤(õ…¥¾¨"ØíÃw@}qðŒª¨Ù•«Ë;RQìN" H­ÊZV²Ä(XäÕ+Û'vãk$$k…THy[—BRçut mëR-ÏѩРK:þã3&»8=2%ËÓø*×ÓÊá ”í£+§‡gù¤&ö϶Šß6"êkôeQM~`g:}K/¥ RGjífhÓ) NÑhÛùp÷EûàÏÀ  ˜fëÖ[€"–Ѷ›ûbŒ]<ŽäjªðΠûõRó*æ;¤÷Ñ=À1”[Å[tÒXN;!G¿çñ±¸”Û Ï!£š ?ŠúmÐ!· ¼ ýÒíòO#¾ÕÀ€ý\ŒsÀ^ïlí,-ÕæXK9ÆÌj1Ç]à\ mÀ«:¥ê•>³õ`ªÁüu¬ÖØœ‡qö¡~ú¥B®Ayì0À€d`ŽzŠ–«“é9ðB¬¿ÌZ7ÐG;xÍÑ5Á~Û¦‘°l,ˆæü¢.7Àcbls£Æ…uZ…ÀU@"P¨¾L;ÅI¿žÐHcx‰ØOnÛidvét˜e`½DµyU¥fí2-CÝwŒCXÇvø/_õ#Z¨þÒŒ™´ñµãïŽaÌ¿ÊxØNŘ8C Ȫ0×??±o ïžnÄ\Ÿx9†Û¨X‹} ÷±=˜!ûœ÷])^޶o£Í&ôŸ—ÀÚ9&¹÷ÇX3í8l½ÆÔŠ6ðë_Àð³ dœÙ@Ý‹g*`ÓÀÐ TYÀ³ÀÌM˜W“ñŠ˜áØ”ñØÐûàCØ&cÖZÃ1¹ŸVδØcñ<ÉÆ)ª²‘Ìcr¾pÌ–glÎ)އe|WqÜ+ïó:9¦¢ŒÜƒ´–m9ˆØr˜ó6s>RK¨|q\Ã1Ëö9Ì~áX“>ANؼ"f­é2GÀQŠë5;¾ˆò:Ž1+­8Sš)O|oïïÓVñ­ÑæÒ=:¬m#ê môâ]޽¼ò.nbxú•{õ^¬³þì§'áÓoˆ~õVѯèz»ùŽNÊy½]}T–G°J¯UÇ̈­ûwõŸêE½gf»ù®ÞošXÏ㜞A%Hrú3@¸Í;OiòV)]žòD—ûE€²ô-½Ø?Îyäô%úô¼ÖHûE¿ù{%D!µŸj=~Ú‚ï§ <—z‘j<>xWLÅÅœ;–vâÕÍ|æÛ15l ÿ^±ñ¶€G?V¬9–òù,ïœÑ@­¯æ•h|ž§§ÀœøtÅi•+>ǹãÒÍònÁùîä)ìØï¬ŸÏG>ãøŒäsŽÏ§½›cú‡Õ6Ä1ŸÃ/S…×·ÚȇoÚ¹sû]fšF®yÂè4Oj“Ì“Æb”èæ ¬ûáè4‡íût®s—ZzºÉ¹Gõ ÚiŸgÇåyóýPÞ£¥Ò¾1ÆiÚ£aßqJ{›í„?aw•¨„ÏSÖ1U«C>BlbŸÈ½ º™ï¾µƒð3ßET£½Ž÷÷Í ‰ò¾XEe°ý¼ÔáNef^F­Æ -%8k{i;﯃íá½÷>Hã½~œý´Hümü4횥tBÆ÷­"b_x¶‘1»mx¼Ù'@“l—¾ýñáøb_`LÃOå{b~¤—Pr¨Å¢£9ç§“ã)ô+a[Ðoš¼¯ÒÝȯzœMõ8sHÆ…9¤µc=ã\´|ÔN7ë!ø°J®}°ÎØ:έfqŒqó{â …Å<Ê1ª¨ºFç$æ=ÝcÈßtäî~ôŸaŸÛ„¹÷CÏ}Wñ[†ßœ/ž%!ù i¿S0¿öµhùT8¾Ã{~ØGi¸/ÄÞ-À" R~ÔFƒ©óY¬$k>zDê3èUµM» qËwh·ØK_¥´X[DSÅDJ¿A®~LG´ ´Y¼DGD5°,hކWºÖ‰·%ë/Ð]¬W_…ÜDbú×Ó×ÅfªÖ:{¿¥±âì5úéßEœ¤¢ÿ׆òUh¥È­Z”?6Oq;9G§YÆy”&ûÅ@ÚêÀe³Z¿åcOa/—ãì…­Q;¯cŸ\'‹~ÜF¡Dæ%`¦ÅÃ…j#µÍê([[OßVNš=ÊQÊU€£6~Fy’;€BÜñ™Ên`Ȥg½(Ïÿ8mÉx»eÒëÀ>Œ}ü40ÔÕ´„ºc@ðk§.<×õô±ÐÍž8ùÜ5€rk¸_'çÜ‹wy&p»ÙÃ@,æ3Œ=4ÙóMÖfC ú¹d=ùô ¥ŽfÏhP.Pºô¡…@ìýO¹\Šá$fûnøìû,Àþî¾$ýûwò[1DŸS.š—À¥ÊEòi"Èi:ûý¤ÞµˆÒÈü§[ï–Ýû:š¬>M›cáÄA4§• ± í·ì=O+Æ ¨{a¤,NŒ‚ ºM;Ì6!g”;i6CM…­Ó¸rˆÊpFÜVöOk2wµßk@´>“r1~]Â~Õ[õÎþ8ûâÞØ¯Ð:ð,ðrp8ßáh|ÛçE\ÌZñ•ù,pµ¹–×rãß5×óÿ È—€>àÅÿõ\ !V`\Â;dÞ‘ýxŸÜM5DWq–|²ø ΡbðkÐáöž ŒGy"t_?I4ô!Ê@ßoÁTE"5ÛïÊ©ÐýÜîëµÇ+²úýŠèÊeà´Õ¨ ¸å÷GPþ#ø,¸ íßE¿ÇÀç¬ú«›!?<yò}@åïýàù@0 ý1ø=2â;ô¿Î×ÿþ¸QÆ›eìœîïvCÜ0;û9 »¿5œýuû[b$[~À7Ó›x÷Eb¿}>íÇaìçp,þÅzÕÆ6uásÎuìë„àB’Ç×NbSb Á„…€¯ƒ½@­.‹³”„H :Aå„HÓ—ihC-1‰mLjš¶iê½fN¨”LÙº5+P­Œi´PÚíÇúƒªÒ‚Fðžsl Œn¾~Þó>÷œããsÏû^ÃÆÔ$jÊY¼Žæµ,¯ŸEý˜ÑâýMÔ±—9Yù˜yýÊkg^¿Bóþ`ÌóÙˆyuŠyeòÆýg+ýŒ¼XâŒÞÎm6?u¹É‚3õ&jÍŸsˆÜÆó€}^Ä/¦F8ú,üè›Ùœ–=[:cgÈiÿoÿIsä—È©þ :¦áqíY,Ï`-Çô\ü¤˜)wé\þ˜}žþ_ýlžÏb¦ºô¡:`¦þžÔŸ^w<±?­.ÉúÓñP|úÞËÖ3óȼ)L{îžüÝÂðú½Ú?;‡éÏñÔó–}GØOÂ÷çÀ3™z çEP G¥Ž¡mŸ|‡øåÓÄÿuyóî5èí<ÝOÂ>OMÂÿ|«á¬à¶f°}¦ý<}ßòú\Ô‡X3qåó'•@`€oeÿkþ‰±ÿÎuù{®¡-uÓp˜VΨ—‘Óð-ð--–`©TH&€ ²h:€> 0K¦e7°®‹ˆ*Æ-U“P/ •Øù‚_¸[ÒnûóÂM|=šÖÏ­KëÐÚ4mEš¶¤:ݼ¸!­ç/Lk»Ç¯q›ï H䀑=”ý'?% 9)Í%:À$c¦E•ì‰r¯¿D2*1‰’íDIJ4žoósYŠM;rþ'ìZ:®%fÛüýÁgÙGä5`ØG¸>dâë*j7+dèF€óÀ`dWq}€ë »B,ì2©@ÐŒ€‰]†´²÷ùû¦ÜŒ½ieïág½ia—`]b—0µwã5µþ!aø*3†âÉ…ÅÃ^àO²¿Äo/P’ì —O9¬bˆ0 v_ . èöFXa]$p8 è€÷àÍp±qàmà"©T Ù;q “dçãÞ%XÀα?’B,êYö'¡ßfo ýgö¡ß‚vB³7ãN…ó'¸Ç m…®D<‡ý.QnWRAÁò(•@h:€>ÀÈFXi|»bG'gÈ8Š\…ÅÉÇBÿ‚œ’‰ºSQ½«±Ç\\xW¬„Ñïê÷2Õ{ü§p¹ð9‹ ï÷_†Å…÷Û`qá}a/,.¼ÛwÂâÂÛÖ‹ oS ,ˆ${å·å󕚦]Ô´°^¬R/V©«ÔK ¬—_ä¶ÏígñŠ ¬Ø Õ· Bц©öÕÖSíÕº¨¶j¨VOµÍTóQÍA5'ÕTª¡Ë±Uó€[«Qmœj§©£š—jª•SÍEkÔ$sÇ×.*,T"ÈŸ+è•«üÌÑuc[»ñØ@žRÂSAr•¦ÉO;¹.MTÒþâþÝÁ5l 7Žáo#üAcØFcèd X @0 L)Àv)&Þ'¤²À~`0ŠéLŒìÎLñ51±Ê̤›¸ÇÆp•âr3·ZbuX}Ö5RŸƒZœ´É™r²RP@±Ûd[’æ~‘ë‹|bšÙÖGJðGÍè¾øí%I÷žQ‚sé‰Ó€]Gk‰—z —“˜ð—‡Ìu5q°W¡ýqÇ&Üf‰{*Ãt6¿kP¹íø§ò±#É`þËqFù›+i qå¯hyuP¹à8¤¼U™”Ñò†7I¡†]‚:äX®œÔœˆ+û¸T¾ëhTv9D +؃§Z”õÞ6e ú 9¶*j }*Çf¥>ÍZÆïTª0_Ú¬Àd8Ä eNÑáÆš$Ý¡.47µššL_1ùM Mn“b*1›æÈvÙ*Ï–gɹ²,eƒÌd"ÏI¦®ª>‚¿nŽÑÊù Ä l+ãBœkTfäY¢?%EXdCè£ÛHd«Kÿ|CY’æ®kÓsʨnHKƒ¾ÜIšRëõ_D75£u€Ò#Q´êì‡IJZZ“4Å›ëöÕ­C„RÛÁÃÅ\?sðp4JŠ öŠöU¶Ú¯†!:3ÒwïSô€]¢lhÕ]ÕýÜH•D#ú6¸Ú[‡è§ôz84Dopm’VÑOÃëy»´*F’t“à½vÌ Á“ÄÅyÄ%;Ó¼iž÷ƒWÎxf3ñžÇl<å¼Xy84P^.8….œX¡ë~θGp 42.8ãçè«ÅáÅé:8ÅAç ʦ{”Ê åÐåI¢÷8Ž4'ÿj–“ßûéjðùh¢.º­=ÜUî, wúK{wéÚV—k`[”\ºäíܺm×[ºôhYWHßVr Ôµ?"ÜÎÃue¡ÒnihW»Bñ:µ.\¶%M46W×<0Ö¡©±ª›ÑY3﬚ÕXóˆp 7ò±jøX5|¬FµQŒEÄonICtu{Z'X^.ökg±;ÚP`ݳJlÞ:wѾâa$¿"y¾¨>«¬AÏxhQpQ‡ðLñÐl4[2¡¢}uîbTë™Ͷ²âëî‰õ¢ð7Céo 4u÷ðOK_ìqĺº%ë&$¢Wlˆèum­&Z;ùOÒWdÛòòÂÉÔhºq1WðFIš"ò¶zÞf6gˆÿÿ=½š?;“ ª“v“XTÒ‘†£ ¥ ¿µ½­uåO±(~`Œúh,Û‡˜6IÛ„ÿÞ,º{2Vfº3:}n‰e—cêÃW‰ŸS8¯rp!¹˜qÛÜ6Î4rÇ%ÞQsÈ¿‰Ë0 &Ù,%XoÎ0Èy¤geÿ­D©§:'™º¥–zTçsM9™"'ǘ÷‰Y–%‰“\Ÿk1kffƺ¨só-Õæ+T2Ô3ªæÛªéÓ³^üe‘ïkÖÏ|õÏMÖ['}Ï×OÖ“@½×d=µÙkk9–TQŸï)iÙÒ¹ÒR!úÏ.º¼äl•” …ׯßý8-ùáû»ëXgλÄJVª¹ó-8™íÿ!½Úc£8Îø<÷u{w{ç»óùàÎk gcCü8c0œëh@%=äP±Ë‘¤ˆG“ÒH¨ jc7 D„Siˆ †6 Ô 6•m\ñ¨Õª".iª€H[ )¨8Br(Øë~³gÔõVÝÛïÛÙ¹™o~óû¾oFV £ ':Ð.ÒòÉ»<‹5¨I)Ýïûñ¦p©1Ⱦ. Ã¥qœøª&WONH2ü‚Æ·ý6ÕØÛ²¶¨¶°—ÚOôâ»Øsóã¡û4lÜ~ìv¾mþÛøK,½˜DÕ Œüª°@ÛE1ÈN8T,òt ßê4 2”»^¯£\ît»å†åÕ42ÏëÉ÷Ï~ÿˆbé²3§ùªŠâðK„rCAƒ µVcj‹Öµô6¦ÎØOàKøÏ½ÝÛ76~xèã›öç¶V>Š»È³d¬û+¯‰4Q’Â)Bp!"Þ òXÓbm.§«¨,•©(G+a°IÁGÉxÜuô¨ÀºŠ ¨zg…Ii$ùz½„"ÖßÛØî9v§Á^è"K×Óßßï$ÉáOI àDÑ׺¾p$PCº†/Xf æMŠ ÝE©e Âh D¥H£×¹øíƒÁYÇ:è9iÜÉY,6ðGJÓß3ú&¥¥AœÀx_«ýd¿q/ ø ”ÅëYÜaúËdI²J¤$£I,1°¼ Õ!"Vp·âX}'½z®ƒþ:,Ì܃§&Aúû߃É`Ô„>aÓ˜Øà5ZúfÚÌ åU?F¡’’Æ#Ä’zp=x\½Dí¸Ýd$¢°$¾(/ht`Jff(¯,’ÊÀŽÙÁsadØã ÆÁ&zzЦ„´ìÅ;:ì>ûdzØ‚f²™F0•9€?ƒÜžµ@jò'%QLŽùˆWÓ0~2•&ü 0ž$n6mpŃÃô4i±ŸéÀu8Ùa/Œ‡‡ š4@Œ‘/û9öxݰ¨ŸwŽ(wÝ’PîX º.ÍSuQr§,3ÊeÊrõiã5Újü†ÿJ:aÜ2\ oÀóI½±Üuȸ­ßvßö¨Lgnæ¡.MåŒén"ɲº"é2ðJD$¯®“yÈ”õ|"”Šº ¨£&Óð/5ƹ“¨ÔEš,)úu‹`Bz° öU.˯›h‰LçÔ³3ì"£­ 3Ø;Z®zý„|Q§­:ÖÅ»á•ÏÈä%¹Y&òVïÙsYÖäÁw ‹ä™ ×%#™ºËI#·ài)ðtÃ#aGfc\MÍ£¯ÏÓ×·g%ÐøñC.È,1È,ÌK¹gø–»SàjÀ«V¦³‘¼˜^H hNI2%‰ß‘'ÿÔ>ôöîóøooÍ3:Á{îÍÀ½ö—I#ÞÞý7^Ñ~;xÐuX)JpN7b°&3].ic3 ç.-\­¾¢Jߌ¼È›ÔÕ®—ùË.©(¤ÒpQI,UÕ¬¤düx4:Üòc1RÂqIñLê¾j%D@“ü"šI’@^RDï’³ÖR@ð@š;.®ÿÐ5ÑN¼ŠVzdB4f:¾aŠï°¦N„tÑ”{Î"gI(·,Mô‹Ò¥Ó Ê$’Êlç%•¹3’þDÈJŠÇ_S™'YSæ‰;LÇiè"á+¨ …‚I¥‡â‚ÊÉÕÕ“ªâñBÈ‘•“¿D²úvß{zõÒe¯n^Ð|r“½×¶L™õøŒì´ÿ€W,ŠOoœ:wÛ&ûïiè^²èÝDQoó²ÃOWÐ9¾ÐÒÔWž¿MÖ§<7cÎÚ áÇK‡?åk *FÑï.&ÏF î¾Ö)0ù]³žš‰*Ý‹Áã_ˆ6£W¢­ho§ï¸»i§û×îÐåèí¨Ïãú¢QZ"ûJF›ù3Ýó ‚óó–óç¢ßõ¿îßAßòì½ÿ”ìõ}äÉA1F„‰|¤¸‹l=±¸Æð"ÌFåÄt:*ÆT#î…â&Æ8’Ÿ7¬èÂ%/¶xa6‹§S"~AyG„ûºŒ/7›¸Óé•h)^…s%V8f,盨d¹2à7F"Á€?”¨¬f§jí_^ÉØçÞ>ˆ§Ÿú#ž0íxâÔÖ}Y¸âêúŸ|BHÅg÷OâoxÏ;|éôĶî±?Ûr̾¾±WÄ÷{Ñ^ÀîŠUfæãéJ–>#æE ˜¬â|KGuH¥j‚QjØ©q¨ç„¤H~Ôø¯©÷ÅêÝ}@½ØÃÔÑÓÿ¤\EùôµV5%ÃÉ’ÃÙ’IyáH˜H. ü@£R0儨4Šæ`¿а2º‡4_ìþϸZpZ04r¾? ÀÏq•ÕY‚+wâ¿·7~¿á…Õ³×méÕ>Œk¶¼SñXêÍoÍ>`¿Ï{‚ѯ~Ã>Ó÷žmï{¦ò@uÅc×ß½úEI f½"Ã5ÀÑ…¶YA‰ÇE–eHM¹" vD •<—Î25ÓM´ˆ›©ÿ‡»êÓ¾ž%Ðh)ÇaÓ©;—KöSØCø ‚#Ï6vp'-üˆ¾Â{Øuûm÷áEÇ¡h9PôþQL$b°¹cJm•#UY9±<+‹ÇgeḬŒÆ²2q¤Uâ6ªLÞÊrJMH0›Q:„X²P=ºˆn!î7¡²Q§¹Ë™pxˆ€¸ùˆËÈf'Ç«÷°³ ÿB8i†”nX¹*9”~°]‡]q˜zÂwü”ç0Gˆà|ŽX'l[1:fr¢N-Ò&IÕÚLm]OÏQyvžžB r;4/æ›ØFþ3öW…k Obg™Ø™_²TA5E C¯ñ‹ÚxWF$2êÈþ¨¿`ÕæÁ˜ãÆÕ*j^^­»)MU4N3¹àÞS– Kš†8a˜È.)%.Ø‘t‘©–·œã6~ˆŸà—8ã³Qç*—± õLå.²ÞÒ]æÿJ¬0^-°Q\WtޛϾÙù¯×Þ¯í]{mÖ^ƒ½`†Xñ¤Ii€PZ †®p%*•h!UTB¸¨á“F QT EU“Ц`0–Q[ E %¥D4¤†6‰\š¤¢u‰•’Ø^÷Þ7»` UéÚóæÌÌî̼ûî=÷œ[wk[r)¶7§AÑ¡ªCÑ…F£« 7H-lÊ&6eº²,Cë‚…œ€ŒòÚ¢Þ }ðëü`|Pw0^ã^€b›NžÙ¦WmÈ™’UëåXvž£ÖAÜZb®„[]Â…¤ùËPÀ*WÁ°j!—Õ…]É »æÓ +ÝYÞ­oL¶Êâ—aÀj5ÊDOCy‹². ÄzeÀ³8q¼ü&gi‚Xõx†À$(åðóÛ ç2Ñ ¹ÎÝP—?™ÂÝÜËùé˜ðv Ôbaš`ÒV}·~B©/Õ—Zb“Ô`´˜kÅõÒVc›¹Ç`•™k,4WÒåâC­0¾dÒCâÀ6 ¾PBÔ2Í6™BµS¦F›Ì2ýQëQâœfL jÀ‡¦iã:õ…úC44BƒÌ?)§Ø0™ïu5˜òôÑF`’&Ñà ®ZˆÖf›ØÃ´çLJî“ûe X:0èÜœ­=QèŠBžq 8~ç`¬ªÂ`Ïú3ÃÕ÷ž\|ÃLÍ]‘ýAŸ™„¼Fæ ר˭õ,¯~cæö 3ˆg¡ˆñð¡´k¶¤]c`§k¶wrxz.œ[*×^PéP£Àæ½þ¤*²°“¤z‡Ôç ÉõmU±d‘Ï{^+®•G&o½ððª—ũϗHoM.Þ›Äb< L_ •¢’'B¶˜`EežEõ*ð3¨ ӈ؜T€Ý2E¦J”ª&‰)E‘Ë}HÆtå Jö+ $Œçé\Hi$¥­Òú´ÍZ¿&k :º€3àa_À ~Õ RI§Þ«Š‚÷Íjr¹BÉLomÐÕyÊ‚ "èƒ$¾Be¢gÞ;üÊR0œLQÁœbÞ¦?:´Äe^»Ûݰ+ÊØ¡ÀvâÙz=­Þ ˜aØ*ðxb¨`µ«V"¼}âÝ’Y¥KØA€Æ`í¿)Ò‘7§Š°`ß—vÂbõOö£}ÔûuùÁÂoUÜ"a;ND I²¥°ÑÒ±Èù†)F"ÑMU{ÎÊŠ•/¾V^«®±W;*ÖE6D{âk?Œ¢v¬FC5šZÙ˜ Z\„@YMç| àcÎ&8!pYÒœzâýÕ¤ÚjÄ5TfQG,YÖí¾p/”™{…¯ÞÑnñ^a év e&Wï¶ÐÑ.8y â]xœì% ß"K~yª8ô»KÅ‘ó¤úêŸIbûG/ü±x•^ ›ÈOÎþî_‹?=}ž¬ûmñ?ÅK$OƒD{±ø7ˆÙQÈn0GBT¨#S^:¤™$´0¹®öI¶©LçL>ø˜eæS6p¦ô2ÐÊ 4<óÁ`(ž‡ýø`Ýœ¼ƒÇÕsòvio•öpýÚ`u£¾o—öxÝ[  Á\–\–úšöä¦äSê6s»õLp¯õ’q̶>4ÿnÙÀó)Ç ;ŽåXºJÐt¼*¨„ÛÐ娪VEⱚQ ‰é:ÒB4jY&«i4+¸¨XPJ¹ Tdu8EÁ+…Tfs¦?#fê¢_ØK•¨üÏJ¬GItGkûb»´ô±±(š¤Ê’âÎÁµ.·Z /·Çœ—“Aabäf„’rõ‚̳\Ë^ì„cÁ-œ+M¨»xÌu 2C°™^ÒµAàØuµ°Ý)5dÈöªªÊ°O©¨çQ02õœæ®¦>}”>ûú¾wáO+²«¿:3qnõ·×ÌM/Ÿ}æÀ#/ý¬Ø&¬<¿ýð•ê†Ì#O·ù?xn‘˜~ZìèÜþ•oîF_Ðêgr- ìó ™ÖH"˜ƒ€"Kê0ýî —A„œQR„¶ŠD|šð€#Éj<è¬ñ[eôA9ôSåPý†ŒwdC‡f+"hXÀvc…bÜ ‚Y€n†V«¥g‹ Ù8~üóOðmU¨Œ%ð¶Ar¿¯¼LÀÌ £A­2™P¹õúEûúE§£î×í„Üùm /Ó*“f!+6[õ6½OßÇö©ûõQ}´´¾J§Õõ öŒJtpËîn?wá×AUM19̘ F$Eå0¥² ú(„.þ#OPÆNÖ]ÅH?ÛÏà˜Ï ^ÖÝ@Éóô¥Ï8)y•LÛ sï?.Ëн÷j}~÷Þ2VØ’Ã-jß´1õâ±›Ñî.ìѨšGÃŽø: ]ø¤`"ú÷I5Dp"ˆpÿ`³ÎÂ×òf-ÌŒ.êíåV ½iÒá÷ÞB˜>™ì˜W[7—<÷Æ4˜©É«ý›·m“šÀT dæýâFX„€sŒƒ>îh\bÒƒ`ÍŒÙ7„ÖÀ‹",X­t¬¸q×.dýe3JIé~!+tÒ¹^‹j¨Í1#ÞÜd47ƒ|ªìL,n^Ú\0 Íß266÷µ=kìnúqÕËñcFe‹Kufçˆ_Ä^ÍÅÎf_]Ê^®¼žeU‘4p¦W(„£Ì%åä‰Õˆj#µÑ\KsÞ•Ü–¥ÒÃ-=¬7÷$Û˜Ûªïѯf|–s:ó&‘ìÖL>ÒžG74}§‰6%[Ínóyóˆ9cÊGÌ×Ì™¢©c~›ØM0ÝM|p¥m+«M“ÚT, F3)F†é«CÑ…“É€€_Šóäÿòœ`{RÔš³^ é j¼_{d$,8ƒÉs0Á£à]¬3@üA™rUe†ézÏœã vã¹®þভ;®'YRbY–dË’åÈQâ_ Ø%$¶CÂ"  ”?”áÎü†ÐN…®=ÂQ ¶f»k¯+ëHe”Ò%ÚBŽlpüÑÁ%½wMapk²QÖ®ÙFq²÷žÃÈíbÇOŠbýø|?¿ BãCí!ºù€ÝN6„N_û/J+q\É÷ÇÆWvU’m• RE×6}£tûJç˜n†4˜*†dìXtmXqÝXmmèbœ®;V^œ)­x’\`ÃèD…ò±ŠÂ<îïG®Ù®ÈôIH;GŽOà g(£0pb騸é Ãø}¡x¬¼|þ‰Ç âù¶h2…Z¨*.—¬¨þŰv.£eè *±òLcûÙé/Έ¯ï]¢Õ{¶oóv¸7ôìÝs¬^ÌU}guuù…KË^X·ö·!ïΆš÷wÍÞ1[¶óž@кá©IϦÝé}µæ²™ãšï}¿kR¸Q¬‹Å³Jf¤~0gÒàDHxA‹yÐ6!@Çéjš®2: Ò0|zTŸªo2Z f¢3¡$°<m¢ËnaH"OgX`uévÎèá€È™0•¶pÃÄÏ(ç){ƒ½ÿž!ÐðÀÅ-<×±T›§/s¼àY¦73Í®ArÐ- xU­WRÊ&…Rt¡UlIQ´äéV–è$¡‰}¬f] 𹋯;!{T©ë8ÄòÙZÉ Å ŽÏ-ëàï1àÖÉ`(†>Í)Èf `(Q1Àš±±ÇHŒBJÇHe ¦cŒŒDj´&&ó2}³Åt8<˜FÛ¸€f Cöar%™t‡SHb é¦ÇËÖQ™-T^ 0„M”z®3ò홯‡îùúU`n[?ܵb¦—œk«X¸÷å÷ÀBõÐ)`@±·â¡¿ýG,hï\ ^ß=mí¨"Na ý9¡ÞÌ—s •hã5SÛ¤°ýšÏñðÅ|‡Ö¥Y4ô<Š=FÌ›ÃS6A·–Š!¬e ;M‹´ùK€ºD×ÉÒŠú4úk%€f"šh&iBȸgãžáCÄ!"# 㻑r'”»;ØvàâïØðPýûǰCní,è$ ‰A`%Üáð`x `XïÃþ÷@•¬!U•|¶Ó¶™²(1¹,“’ -!1BƒðØ;@ò¤)*ùãÑxlB9¤ ”5¤j®¨Ë/}xð Ó³skÝÒ¼Š²yOwwSoíO¯Õ,r¼m­I-ßÿh5dÄÔ¡¹ÔȈ|b,Øh¦8Ž–#\P®ãªe&׫y#\HŽø+¹ry&W#/dsk¹‡Ö.û8¤h²rQ]Qk¤-––©ŠÔp5…Õc.³Ž]Q¸bL*Òé-º]ø­ÿn‘¤*Œë4yâT±îd±“ˆ°þ!i!ºˆXO“¯˜e´® ÖjŸn³*®h0j ºÝ=*USM©-ª%9ÙÁ²¦bYSÿ'k*–5UÁƒhde Å í¬¬©(ÌDC¯n@ðsB·pS,†P%ÌF‡#x¶‚}› £o°¶ XÛ-Ù\ˆä-<{”¼ÝÿOá2}ƒ°Yô!þô¡ÏnAДTUQ³²²†ÌêœJ2¡ÎQb·º+›¶ù•=n;ØÚñå½ ŸýììKGV}ÙöÇ;¿:òÊËG?x©ùèbÏÜ`ÙÊ%:öÄ7ØÿfË£Æw7¿Oý¬ëÜ¥óÏ£û‚ nC×’Á²3„ߥÆ(T[p¼ZâT5ÕÉ[𮉪Ss$›$S°å :ÍÊœÕÌý/ÛÕÅq‡gvg³{wÞ{í­}¶ïÌùL›k*À‡»n}i!Pl’_I´åáʆòH”4)NU¹¨MÕ¡´ŠÔÆ Tÿ‘´RBhšªMÅK84ˆY-rÃÃv¿ßž¡å±3;·;w3ß|ßïû õ ù)ÉG$w©Æ¸„A~Š®1„@b°ãÆIòv²ŸƒÑqCH$¿WZHüü8î­lw‘‹‰|C~Ðs•wÀt§\á*±,ñµàÀoƒõ°4œœ‹L ÕHP±SHK}[iâW3Qbè-ß2…h©ål·­(™‹jZ0RÌrˆ4 *ØâÛÁ&ñÙÒCF6¤’×g°w _• ¸‚Ù/ä ‘ä˜4˜LɹW* ]”SÒJIðX†PT©«{8Ó5]Xº‘Õ˜8$Ä …>"Æ„ÂDZœ;!|¯¬®Â®¼0<<,®½ûîí¸¨»ýÈúÔË“_áÍ´æ{¿°XhYís¢^Û§i SÓ !¡EÚŠ ˆ°f¸B[7*Ãeý è‰°2˜µ¬~›§ìV»ÃVm\Q#®Èv(™PP°)SÚÕ”L¸(Û¤LBܶˣ±ßÔ´Íf5±²AK»³xý¢+½¬u9fXU¤if}áúú>ÇlñO„é”ՙޕä2d$™"x×ΉҰ1(¾oxò›sR Ãõ\"®ž={s×K¡%D×í7–¯C¾ÂYP?}±•¯’ºï­ô'õ§¤Zü·6®«2€è阱pyÖtGNw€Ê|ñ u‡¥Dôt´&oB8;™›—Ò h4PC…çaDBz£l(ô­UÖu›õzY7^ÑyF¯3²f“þl v;E§¾Êè”»Å3ÚKòúŸÄ_ôQýªñý¦X–¦ªBÑuCJn¤if =fº*DV³bšfYp`…ÉáXjºac™%Nð²‚Ôb£Í1ñ®&MéÀ!ÛRÑÈÎ2% Y‘ñVÖÌãY˜OÜ'Ä!Îè$³)Å FÑ„•‚—jÚ¾>k‚ê0XŸñ\äœ(ïÀ_8Î-áDSŸöÙœØí¼­— AÇØÍ•®GuÊnÁe’§äóª"½`8ZÐÛ çÿK]« –üLU“4«ªZ°óCUMÐüy(MÍÑš&ú à|Áÿ²\Þ8Éô©‘¡š&qdÈÅæüÓ¤û ݨ9jû/ç:á°á‹…È9Á͘ ß‹µÐÞòðåMúób'Y7ìõ’^ñzÎ3܆òW¯Nnä¿??yø»Ú©;¯óÁÉíë”Ôw&Wã¹|.Ä×ËÇ5( mTãCyjó ývÞ|¿“¥¶…rS¦¥´CÚMtÀeLSSZ¶W›Ò¨¹¥¨¾ÀãL$ôqp6‡˜©ÌVûOîª}Õ,µ÷±öý˜Y2c¾dAgŠ ›Ñ.Ö.îÕ.¯\Η/ªÒ[üaܙ熵S·)ÕP½ûÌûÿ†ËºÏp…g.QbâH!r¿kO8ãÅÞ»˜ o »gþ\5F5xÆ…¹zXZ¦eXªîÔ…õP’—Y‘È<‹vŽ¡Œ~,qÄ}/o;÷ôáŽ5üÀ¦G·þJÔ|mqÏò»'¶*û¾ÕýðÓ¯ƒCa‹¦>sÅ +盎Ç=\I˜H$+CJnÅ^9}1¬ò@›þ¨ù¤Þi~Cß`šy§9Òì.ô;Ë"ËÜÅ^—Ö%sŠ‘¢û˜×­uËuNw¤Û]çíàq©kÁÕêãÚãÖêÀfu½¶ÞÚ°•ƒdÄj“”}’t L9”} G §4:6ŒûOò ØA¨CAˆÖfóó Î ÇHª1ÿhŽ/©ÎäçA?TË!Œ½¢s€ð­$|C„¯ÏZÒæÂ˜å@aó+ò(®Å»È9½¹âx±8 KHF­×Aj!ÇöbÙ’+µ•r­¶V ¬MøHÔiÐXœB›ŠùÁ›çî®k?¼0yýäPß¾¡cßïR¢|îþí“—&Þ¹ö=^̓§ß>}öÍ·ß‚Ô7¹AÔ‚VÍ×öœÏ;ËÑšL+©ô§™ªñU_¬êI÷§ÍæDsribi²Ó\èJt%7š›œîĦäHú½Ø9ï\Å{Õ£±Ñê‹é©´›9'_(šGÄRç)çCûZÕ¤c‡Cª[Y‰*ïV†l*¯=cqÇ*XO[{-‘&Ó'ø¶+´¼Òý­iC÷1aIÎ!´ð¬ep³­oóh½RÉ26.ˆðA>ÆEŠ·ò®r¬s¤ÆœÔ˜“s:!<€Sr$3bGR0âœ$påå©¶FçÚû„Ø™¸1z7æ{ÅVòĤµ¬ˆ…“õF§EÕÇ ´sÿKvõÇ6qÝñ÷žï×;Ÿsw¶ãóÙ‰ãø7všÐÄIBñQè ¥$¢´¬„„¡Qè’±Ò„”ª Ò†v(h¢•:•¢ZËVR€I¬h*VED°– T„(j´ªêSY’½ïs‚ÒV²ï¾ç»ç»ûþøü0]Sª×xÆÞ_îîzáÆæ¶ÝÕæ‘õ?x¯wÝÀX§xæµE‹vŽ¿yhìÞoŸ1zÏuxèܧW>ýû¿` çuºn²¨ 78»Ü$G²Áf²€lÒ¤BiÁ^`ˆy_>\ˆÌõÍ /ö-¯ô­ ¯ˆôE.KW¼·¥/µ»Ac‰i¹Ò&R¯=J~ªµ‘Nò¹öïà/íÛáÿ ¨Ì-—Hþ2Î*©CIÃÖ±¡;ú ½O"Ž›¥3«§{ u@\>Œºi×ü'RH½€\Tð ä—8zôš‰åKò y\*˜ÈmeØà“‚…rŒÏv (|ù<Ûå‘ÞÊü–ìè^82š›R§™¬J3\ÔM>IfŠcÕ3Í7¥*®ªìþ§ÎŒýgí?_<ß}p´òèÆuG>\ÿ¡±N¢4·àj,{éÈ®ïæ¸þ04ô·O._ýîeVš ¬*&ºè4×ø°!à¸æ‹…ÕB¯ QS¡ õøLêA.»ùH •fö(X‰E}ØGbfQø9ƉaŠÖû¯cN!‰Ñ÷ïa$Mù-Þyç¾oO³Ü2:¾í¹Å’©ibnäq±¿dë9HTî˜Ô– y‘Q¼|pVgaÙòY?ܼÜRïvÏŸñ^z^aEÏèeÈBaüŽk€eaºËr6 1l}ŒÎM,‰­Šm¡»èöÄßUuy¨ ZÓT]µÄ0yŠ£«Áv¥¶«íîv­ÝÓ¥tÑ.µËÝ¥uySƒi=J¤ÓmêR÷3©g2½ñÞD_bŸú¶¶7³¿ê·Ó«¿×¥gŽ§Î§™I%› â“Ab2ÈÝáÄ5Ä'ƒÄdPÎ|…ã4µ)餦 ¡hªTpW—‡N‘÷˜]ɯ° v«ýsûCû’-év…½Ö¾a ön›ØgXmJY_¼0«ª.7°ƒ‰‡™ÑÃ&t¾?Ǽì%fãêöò5夼¬Tà1` nóCàø ÀBYµ»"„C Ûñóµ°¼ÆÎ·0-vzÄŽÂJ; «lnígéSdÙGr"Ë–ž(kÎâ,ÜVda<áo²“sÊ‚»‚EÙ¿Ue:›_Q{¶–jûjI­1N `Qïò–‹³Ì x"šÐ9ëüñôèB|çD9n”p`Ð8(ÄnLÚZûA`RÃlÈ' x„} ¶ëiá ~êÎ-œ¢‰G˜†‹ #ÝÞ¦š¢³a Íw¬ÙÙ‡õ¼UTONúH\ôW¥LÃkø —óDÈfä0`›ˆŸV–ÄÃ(÷hÊ45Œ3iªJ9!Œ*ŒrÐY9ƒ©²âh.›Û¶mšG¸£§»Ã×(BM:•®&õù†Æ"A°ãZÌo1mfEH‘ìS…ôW7oÙXŸÜwá­ÖÙ?ɾ±xë™6󘶮sKW PÞþñþ%¶^ú?Tö«žUsŠ“µnk™·)S‘›¿ùÙàíO4ÆËÊ}j¢nö–ö¶w~væ41þ ÉŠo! }v©¬ã©<…ÊÎfAŸÖ<*v¡€AsºÊ¨ÛåÖŠa7©áqYy„>²B~^î“÷ÈbÊé€|L>+Ë’ d X%Éšß fÉE?6pT/*è¢&îg‘4!ÍŠªRþ3éBAÜ0°ú&•ÑïÓÇÆ-@ø‘ áͺ:ã"ØÖ\.iAþRõfœá{#C²¸é‡Ô#ôøÌ_¬©Ú¾ýø‰¾\&òî;ƬUÉÊX^3öúÎÑ} «B£—–ÝRìî­§Qˆå†–Zyõò:qPŒh”Ó›T “ÄAïåw¦*Ü•Âÿs¾ Ü›P÷¦-6xÏûÙfÃ5òcÂò^˜Yd>D!Á(ñè"ÉŠ¤ˆ 3"‚FÅ #°!Ùì6Æ¿lme=/Mš§Îd ѱ«°åÊòC­†{Ðm>·hÑ®æÁ·çÿºµ~Ù;züõç-Z¼{iºwU‡•Èu‡UGÅw™óäÓŽ%*HU$,©H¤Šˆ‰˜€ökrׇŒëC¬5€íàQÃ'ëEŒbf“ øî1›(³™y6„!Ýq¶Ç{vÅgTæQ†m¸î¤±d؆]s^ÌTçQ”mtmÊДڄêÕùhžº/!K•§éj¼št*t#Ú€7MÊFºAíÇýä׫òå5ú;ô&}C=ŠªgÐIy@½ˆÎ«×Ðõ+ô…z}«V±×Qƒ( fPJmT[‘£RÑñò"k•ü€Äß²÷WG ‘ʨ"Ž¡ øËYÈ ÿ•ˆ¢æfe«¹žc¹aß¡ÜPÕ ¼”a§Q•%IU?¥*r„‰cö *“,ŠB–d•ºk4¬ÅÇqh%ôŸpÄ>‘ˆ,rh”88æ¾û覑=Ú1Ú ŽÜê©j£0à²ÀF·_¬Îõo=×_„ÝR&@r9戦š^Ô±´×ùVC£¯ã?Ž­ùË­dE0÷Õé±ç„Ôèög×>¹žì`ÍÁºCBH<ɺÃ+”»ã4ò‚2åè#q¢’&<ÆåAÍÃ)ö“¨,2£ZñÄÙÁƒŸ`Ô ‘éðcÕta¤15„%eãI0Pš‰‰  ¦ æ$ЙŒu††Œ«CÆåÜt$g‚`Âlý8+LSÉcæ2s—é2£¼~§Æor&`‡VTæ²ò4Àõ×ÎÉŠD^4ê“ÂÔöŠ$7u—(^ù\~¹L »Ë™ƒMÊY%W’Gõò ¥¹dîÿÙ¯ÖØ(®+|îÝyÏܙٱ½k¯ÃÚø±dIìÄ3Ä oã‚y8›@H-M¸@¢$(Um~$¦©ÔªMH•xÙÆ1‘B)B”4)­(¨´TT„¦r”J-¥Þí¹ãµ¤(äWûgfö»™;wgÎýÎwÎ抾´@nÕf²¹ö|g%[⬗‘u¶ˆ[¥ÍòÛb?ëu>o(iÍNCÚ¨5Ó¬Ö©s§@“ó´ü‚Ü%¼®ï!{é^í-½zÅ~óTäœøGåjä*ûØÿ­$5‘¿±”VPšAÉ‚Ò)жL5YÄ[–äj‰U›|gJ‚Aôj£/Îoâ*e ûnöjqc¢ªÙ5jÆn,QWÙìNû%[µÕr‘/ÇðÂŒ™:¤µu™Aüñ¾u™ŸÃÑe¾+D£(XRTQU÷(ªeۨקּ£à`ÎÒâ¯U™™ú•-É)ÉvœLTr£QÉÄu®6L×0L·;UvñqˆŽz P"9™Ùºi¯ç ŽË²$q×q3MPÝk–AVO; Áè#{|5Õ¦’ꕪ}ô~_i³ÉF{‡MmÞÓ¬(Y}K@çÚÓC®Å®­ R¢Ä‚Ál6Žy þ¸“eãz–U8ñÓIÁëì Üµà‹ws…¬ÜeZ'$ÓjæàmŽÖã–.ï6Rzо“¿„9í%0ógº¡ž¥ä(™R8:ZLZŠ'çÏ”êIp¡bië†Å+‚«—J©á«^½-¸Šõb*ˆs£Z9$ÕóÁÚ?üO£“>WºoÂy˜7.Û§éC]ï½O×Þ¸@;{þó[T†qè¨4ùs!1¢‰ªˆT4‘,ÈÈY]& ¥]ÄæV™ðD%¼ìµÈkònó‡ìXô˜xLz)Ì/öJ…˜Rd”Zdªö ùž&×9D:¤m¹ù:éR»´#´O?¥6c]þ üÎø“uEuFœKÓÁ±YÜÀÄBäêfò ª}„ /2eˆWeþZQ$YQˆ(*ш€)ÃxnÆ K䂚 [ªÈ(S­“pR¡V5(.€"Pã¤AŒj]pu]PE¨ˆ;]µÍ!N‹±]¯TÙQÙøâ"q§(ˆ}t¦o¦„í´² mÙbwÕìàp°ÀXa]±>ÊÞÄg+²¶f¿kþúŒí’–—Xqê6ËÍRt›ñrOãöÖÊ=½²Ä¼¨Â³¸Æ«E©¬ð?éDœŽì&È` B¢`Ài(á¡§ [HÂÈs¹ÝýÙɉՇÏç~@^¾xajîo4Mr×çÖÏh¸‘Ó‡> ó;rYü®ŠÜbáSäH)ùg#åªËMH&˜#jbÌwXJóõT+‰ºLéÅÒøû¥ ‹Wœ8AØ(;Ì’„ñx<é¥Ýel¿*ø† ’J×O²x!éŠSlÄZ­V¯5&ë“Fs·­¥tl^q‡Óë(Z笋­+Ú">el±·º[‹ž7^²_q^‰½èv©{µw¬£v¿û‰ú±û¹1d]wóÉÛFUÓ’e6‹=Ç–}ýàýp ²51¦[¨•˜9$ÜX¬ÚQ]ì0ŰZS]MScŽ£ëšÈ'€¤•¤uÉw“4ÙG§÷0´…ïöÑv_›îø}ÈyסN™ÑËH%Ì.Sù­ÀZ~J¯×Ûta‘ž×©Ž#×1´ Þ]–êDaDã mÂí"’›qkðrºœÝ4P·‚ÄùÆa„Q22 ëxÆ,PjWÀT=Õ&ŽjsôüUÐòWɵÆÍÿ¥·ÉS+›<½¬§È³+‹¼{Pi0‡AúÄjyŽÛÄϱCæÁ;Ü{&6Ï+±k¢Zîñã3•ã2vç6ÜWUß¹lRîÑ}Vºªl=+¤‡vç™Î§èú§öÏèXʳœ4jÏYä•Iöû†ÓG-S‡Üí”LB ýÀW°A¦aÖŠ½ãþ|lL i¥Îòˆ§¶9tŽÜ¢´Y«H;m—W(‹¬ äaú°ü˜²l–·)/“çå•ëd–%ä2AÎ(žüsù<‘¸·±Š&Q”WLBÎúãЩŠJeU­&Ã%Eº&šÁOT×`ðT ¢yÆTiaÝ £âQº$¼YÌoJ•ÆOL¦o®6wšŸ™Q“?WÅo™›AÝNÈ~ m°ò @œ_†³6WpÙÈ,Duo^` XC¼q9c òÅÂmJ¦Ùº‚[Ä+6ù…TÓ2Odp ƒH¤c¸š=HLɈõdnKì?­ÈM $›:H6X{åƒq#ª«GÊ„9œFdá¢8§ô}ù4€ê ÎÝ ­Æg˜ÑáÿÚoÄð9÷Ù1:Œ’ #a} ÌF² |`Ü^€ŠUãq?Xõ@̓iЏ†&2&¾pÇOêÐ.wu4¬h¼ `r7@¾ß=ßh~`Z€?`Ö/æœhAßjµB„"Dˆ!B„"Dˆ!B„"Dˆ!þÿ øá‚À[¤!Â-¢A­éXX¶3v§ÆA@UuMm»áκú»îh„&ðFÍ€Y³çÌ×2¿õ ¶-Z¼diûýËXÞ±båªì­ÿüqD  Ëž‘ ®„ PS¡¦Álh6Xí° ‚­ù|aDî(Œ¸G´ŽŽX“Ïç?üª³°_}·!ÃÚÂL˜X’—˜xþw6%ŠiN ˆ ƒ”Íwƒ²™â!P6 ]e³Ù=>N>ÚŽE™‰9¾!øx > î ¾Àp²´tC&C"CP,2© é ¥@^"PŸJråÀ¾gëö e ì@ ã/ ¼\ÿ>b ã`2æ`G1 ŒfHc¦gF8@f{ `pÆxȘ3<Ì3 ¡ Œ£P‰Ò[ñü6_9¤9Àª=V×Ñ;¯nùökýßtPž…?Ødì£ÄG endstream endobj 1694 0 obj << /Type /FontDescriptor /Ascent 861 /CapHeight 0 /Descent -263 /Flags 34 /FontBBox [ -147 -372 1168 996 ] /FontName /LGMAFJ+Garamond-Bold /ItalicAngle 0 /StemV 133 /FontFile2 1695 0 R >> endobj 1695 0 obj << /Filter /FlateDecode /Length 35777 /Length1 48848 >> stream H‰|V pTÕþÎ9÷îæi6@ °<îr“³bÂà ,ìƒ<ä‘w!Ñݼ! )E 4¥)”B/al)–âŒe´ZÒÊ]Dã¤SqJ[¬4ÅVam‹m±–lÿ{CÒ€Ú{òíùÿó?Î÷ÿçÜÉŠ,]²,¯ ö|hðJ ­.®[m†Ž–§|k¯Û°^ùÚɦï’í [›Ö¼üXþd@Î"ý[M«76®]ñ”°“ÿÞCÍ Ñú_¾L¦|? ˜YÍ´62Q_ =«yÍú¶¢þ#·IÿTµzm]”Õ®%›þéÕk¢m­–W¥ë?•ü•Ç£kloŒÚœ~—øZ×~u=ñ¦çtao]×Ðzùøow£Àê§AÈ-[‘-f"ˆ_DBü9Ëûg‚,r>ÿT¦ˆñ/y¾ êžg˜ß/uâø~L¿‰„ÅÌ/|€j–…›8ÇÎÒú%áiì¡ŠËØ(T“}%Va~Žñ2z™`ÌC9êЊ Øy®âܧ ,a s²¹ÌǾޱ3ì,{ƒ¿#&‹yâ x]rHRôyåSh`>ü¨@%‚XŽh¤ [ˆÿ~³‚gp‡Ñ…#8AüÎÒ8‡·ð!®ánÑn‚YX ÍT6›Íg+X„EYkf+Ù:ö$ÛOãyvž§ð‰ÜÉËø2^Íëy ßÄ·ðü Ÿáoòwø_D¾(uâ›â¦ ^̬u,u|:õ´zUL,PÿƒxÄdù(unu®F;õo3¶`¶ã{ØMã‡4ÿƒ4Ž †£8Ž3x ¿¦ñ{üÆeº;ÿÀÇøÿaV–Ný*a¥ìa‹ØR¦*ZX+ë`[Ø.ö}vˆd½ì_¬Ÿ[¨–b>‡Ïåó¸‡7ñõ¼oå»ù>~˜£qŠ_â}ü#ÁD²!Æ EL¹¢Z¬¢Ñ.6‹WE¯¸"ú%H) µKÏIG¤cÒ9©Wº*õËvÙ'—Ê‹ä%²&ï”*Ÿ¶¤ZÆ[œ–}–ç-—,ÿ´Ž±f[§'¨Té!ª÷s³JQl‡ÑÈ.I^xøëø{~³ãÂMÿ^<„+(–5ü̸Õx›Þ„[x‰ÞŠ×Èg,jÑ$¶Qª|”Pÿ;1N6ÆV£:–„¿Óm[Fã½mÛèf¼H=‡göìÂg͘^ÿ@Þ´\·+çþ©SœÙYêd‡2iâ„ñöqc3ÇŒÎ5rDº-í¾Ô”ä¤Ä«E–gpûÕ@DÑ]rª%%¹†®Fi!:l!¢+´¸ÛGW"¦›r·§‡<ïñô xz†<™M™ƒ9¹nů*ú9Ÿªt³å!’wùÔ°¢_3åE¦,9M%•‡ƒ"f³OÑYDñë Íš?â£|±ä$¯êmHÊu#–”Lb2Iz@m±À\f <à/Šq$¤+½LõùõRÕgPÐE¶?Z¯/­ù}v‡#œëÖ™·N­Õ¡.ÐÓ\¦ ¼æ6ºÅ«[Ím”•F9Ø©ÄÜ=Zg· µWJ½Z­é"6öHwé UŸ¾pÓß2sÝÝì'U!=ÑÛÍP:²xG¬´Ãç »ð†¶w· ÍŸ¹R1TMÛ®èÏT„†[Æo8LIsÝå•!±VýŠQFeȬ€’²Ì<"i¬eÜ ú•È*EOT¨ÍÚªÖ8MGåFÇÑqežñwQæW´ªêÐçÙÕpÔ7>6 Z寗J=JéÝ–\wÌ–>ÐéØ}iw„”ÔáBÃÍ”LwC"Öƒ­f#µ”®ˆ®Ô)Ä$¤ê<»Ðøi(„VWHnô„ut%õ/¢ÙŠŒƒ³mª¢Ý]õÚÕ»W¢wV,Ù¶›0D㺠]9²ʺ˥çä7Åꥣ%fsM}f®{ƒ^®¶Ú½œZ†¥! åQËã”wv{PKŠÞQÐÔÚ“ç ë} !åËÔòŠå!ůE_‰‘Þ°ó;·‹ðW¡éa0µ\¾}™¾•bý½ýo%†LîÃ?!öX†>&î ›¥èrAу Kæ[ZPÃ=èäLdŠ>, û·É·†waá˜'ȶpaÍSù„ù„‡Â#„¹äÿ¡Žrì„¢ÎÚ‚jÙ_nA)¡ÆâAÜ…,©sä xÔÒ寈‡ì³ä L±q¿¥V ý§&¿ŒYÞ‹ )rG¼ß’,9¿buÅûå$Qþ·i¿\އψsÍ9RöIˆLµlPOë9Äs Í‹i.á´—DéNêÃDâî–<˜D³•öΡõ©’ åRKü6ÉKx²¨žå¼³Í\]ñërWü}ÄŽ=ñÌ~¸ðœdi^A|4³îÚkŒšk2øœ¾ÄÑà7ÄÏq)„´!n÷¢Åäý?‰K±q†Ä!Bzõ"ª›²èžH@ü6õ©à7ÎÍŒ?kö¼ ùÆ l7A}]˜Ay‚ò1¸,{1M2úî¢øü—óòŠâ<ãøó¾»w»(ÊAÙm%zø‹“HdA°èÙ@ôâiü‘8bA$-Mb'Œ£ží0­“ÌÈ´$3¶q=;pª¹±±ÍL“‘™V›fÆê´j¨Qc[ëL§©×ï³{‡vú‹á³ßÝ÷Ý÷×ó>Ïóî$¯q5Æ FÌg9ìÕ{vq[Ìg-ú¸ß=†~\ X':Ç>š²«}FÛàËyÿ0·{ðÍVPƒ÷6‚¥ÜŸrlwž“xð+øÁÛ°M.˜­`o°N¢§ÙÑf%Ú¯ÓM2íq0Ï1¶ÿ=‚½G)°W)ì=8NÕÀ^/àX¾›,7]DOÈÄoÙgÙoØ?ÙGØ?8`ŸZÛžXû8ûYÒÎ|¬”‚™ˆÕVÐJa“…3ì·<ϱ¾á_ì7)eçvü_.@?e¼^ö¯Çt\[ž|bE*NÙÿþ£&ç4^9¶9¾RŠ9?'ÍÄuž;Ûrœ¸yMðYä™ƒØæELª‚j8/pl>ªðGM;f5Ž‹ÇÔ¤{¥£ßMv>AœŒWÎ-ßã5eß1;#÷pü³Â·ÊRÏìoÿ­Úy ¹#µÿ)ßH)ç¦Ôþp,r<%çºûú±<žø«21Â9×ýfbD;›Q>MŒ¸-°|œ×ßJå]õ#šáÚcǼÜÛÝ鉩œëz¾jû=ïüÒ…_’¼N×"-H/p¾ÕTÊpŸ§F»=Ê•T«4cï2iª¸FJUÚe£~å”ý q½² 1‰w”w©Á~ï6MQQ¾úäèzÊVVPƒš‹<¶‚*X•bjPþ€|胟õ nêò+´ûÂïØåü.”ËìMÜÐ÷aýç°¦·m;Âk}äŒZÆmÝi޽ôÅDê%ª°mÆï9m{%í8f+Îól+ô©M¢]l+»Í_)Ãó2™žF¼oéEÎ8 ÊEýáĨ}FÍÇú{.Ê"õ¢pa>t—=©ûGu<"îÔ±2Öý¯åÿò|RÀ/¿ÍÈßP˜ÁºIûL”JQKÒfâ½çt¯2ðY/rû=°ËeÒi½à"l÷ÊW§ÎNä™AòÛlª£ÃdJ#69§l8—y1OZÙ$2Õ’Sb¿Q•#3emÆT6t%4+©“:!©ÓÓ½Ù¸Úv·M^=-nÒ]qó'’Ú¼m’ÎàÑ ¤LCá.ÃØitCÂof*Æ#lDŒ~5sgfg&—å(™k2Ù‘Ì~µ×ݫɻrŒ uFÌÆ±—¯b¶™.0¶®)0ºÂs1SÅ,îü’<;“•±úXKLé]?ÓXHÃ#ÃÒ4–™UÏŠ[ä¥À  Df?µ‚¶GJAÜ®%\½@¢õ(ZâýQüXEý(¹ÆJ“¥*FµKaqóT–PUÄÁ¸êXM)i?(¦]Ú ]øbp¡ù\öWºb³ë4NàV–S•!1°€‚½TÑP¥6Т`¸ÑT¥Þä{q0®J5æöÐÜ »“»(àN‹$%Q†å4€Vˆƒ4û-.•T‰ PZ€"I$NeAU–H`Q jï à ø$€.æ¬Î F°ô²y¹árëeµaŸx¿û×ݲ{Cž±¡ež±Ð<Òz$zdäˆ:r$qDªòÄ}êQ0T:†k|të©~ª-@WÖÌ3‚‡c¢3²ÅX‚ ‘ ˆTFÞ‹(»[JŒõ ååãüú¿??ç¿û.ø!o‚p¼öƒNÐÚÁ×@ظÿ5öXûœ!¿îÈ+Žt9ÒáH»#mŽlwd›#[iuÄçÈdG&9’íH–#éfz¼N“À'ÀÀ[à;àUÐ v×Íà™à‰žuˆÐ¨¨±¯æ3ZôÝ¢E7iÑV-ºQ‹®ÕžÔ‹t¿^ OÕóô\ݧOÖ³u¯>QÏÐÓt]wëª.uB2µ&)!ZU²â mò[÷W‰´ç×Y®âjae‡(ÔXm-, Á?VZÁ’åiXßtRˆCÍ(µäC‚›°a\´?ßÊ^Ò4ŒŒµ`ÿÁ|Ö­û67“¯äñ¿Ü±;jx'ºØ|J3^ÓJJB«ðåÇ(?æŠX †^8Ð:þE?ÿÄ¿­{«vûªj ÙtR§êæ%aGOÉô4L½5¿°¹Úçm[l¯cQanOþi$‹w(½¤ÙÊ(®¶&®šU5«Š«pÜpÕDg&«r{æŸï$«¼(΂)©]´w”œ4õ­Ví«¿¸Æ™OÇžÔÌPÏÏvYG{G;ž¨Cì¡v®³ëÛ7âuí+¿! øܬýaGíüG–R»Íòó@«å/®±4Ü%Ÿ‹ŠkDÉž=Tòвeâ²XRµ›õSR…à3Zˆ dAõ,?‘ WEœ! <¸î½N••¸Î)“U˜õTaV¡J_ø•øøùwò«qôÙ“¸#޹æRÑóæœ4×&§§•¥á8(dwÞa:Æ2«KÓ¦uù}¥>ÓwÌwÂçºà>ß“ÅYÙåÝn—nï+tg•r©òw*ËËç”ÒîÝ­)ÓgL_0?¸XËæÍõåLÖ·2?yï..š.æäË Ò\ªº 4_†¼%Þf,([ÔXÿ¬¹Z¼&…èø$²¸@›VñŒËýO¾«>¶©ëŠßûÞóGží÷ží÷üüÅ_81þı Žý I !Áâ” á+!0 cíšJe@›ÐZA騲ÑvšÖ¤K·¡E+“ªµ°þS­ýc«Ò®š”îT©[mvžºVšª«ûñÎ=×>ïžßùó¶nê¸R»õ\í'i_| ÛV,#9Ü# ÕYPïuΆUü<ÎIvÌ ùŠèãÔ½N§gñ¸KßÑc½Þf]1l6׿îÿo"Ùj6Åì!Áô³¿ö@JñÝæá\çfkõVlœlË•ÍÄ=<=˜È ŽF={kÓø©Í벃´…•=Wzð®)Æ‘ 9Ñ{ÒAµFËrœJátôz%Õh7ò<‰­“ *Ž;¬Wò 'yþ°@ð ÔBÝ@kœVÚv…¼‚Ád4°ŒNë°[hó5F NÏ *%IppçœÞ¥êI½^ ™yüGI/òI ‚MûEBÝ.ù*ÙDDLpÕ,¼uELÀ{g³r‡­ì’˜©«À|Jny‚»}*l®Oh|9Þ†©>ÞŽEnc‚”{BðnÁMzŒr÷$Æ †–ʳe|~`¶të½n쮽9p®T;X<÷È­÷»kà_wãóÝä_ñÙÚa¹ÏÖ~6[;ŠŸ•û,­½ŒGù[äÉ'á[,‹6¢~ô¡d%ÔûÚz©´Í–N: Ã÷paŠÓ`Í<®Haí°.:‹G:‡ÑTDËêœ:¨cnæ^×ïé+´ib8¦ÉwF´“šÇ›%6Þ>§T&ãC±ÈP´o2&Ë´ùèç™Ì›Í›æšçqä7 ¹=?›%VJö'w$%§“Š»IœXݯTïW3n‰[ä>“‡E}"²Ä} ‚¬ÜàbåËÕg2°@‘|%_]”µ¸ûpRÖ†‹ÏD ¢CŸÑc@^ª5O˜ì˜Mr«Oü¥À;±ƒJÉ˺‰¸ƒ0¶&×,ð&cd²¢ˆ_#8ÓËOÏ͈,Þ† Öt¦,E›\!ÑÙLà ]c±ß\4qÄ6|åˆÏ—lêYOâ®Ñ ½&:I<Šï¨Ú/O|÷u#Iöa›ÆLÓÉmÉöøÍÇİÂùÂEk‡ÇÑ®™{VRq ÿymxU<6ÓIü©xGaS•Ö¶•ªMªïôôM ~fØ |¤Ü£X‡¥PÚ~*i …Rù""xÀyð÷x+²Ù'ðVIc$(i$±ÉòÈA.B¹Yƒ(ÅIôŸ”Ò8ýÊÂö“íóø]ÉA7 ¯2|R’ ë•ïÉCô4}Žž£ïÒ£•4 ÜZ­X«²7¸j}½”‘À/à¥êR>žà`!ÇÁ©'è N‰)¬Œ` L-‡—éLÍÓ.H™“›q¸ù¸Áïi‚­oÐæÿvå}âGºíô§ù†¶ÚŸiQÛh ô­Þ÷bh•Ó÷–C¹á«$Öº£m5OØù¦Æ EN<ÔÛ{)tøã¾R(?t•ÔÉj!Ëj! eÅe )üï«“äbÖW“¢·éæÜ¶g">Þ&6½úÒFëESn9Û³¡k2äh.X¾ø8ë-Ëjîߤ1ZyðO¥…ú ¢=è8Pñ·Ð ,˜D³ÅjkL¶¦4_]§‡Æ÷îÛààR¹À½Céô±^Ì÷öâ¡Ð‚Øèñ&Óû'4ÁñBïºcÑA¿¿ÀA"+ÆÖA5(5t7të{Ts ªA©«/Ð× µ§“.o£GìßO1CÂÂä®)—«Ýëñ0¬{½íŒsÞõ!¢8Š ¨©âÈô³SÎ)bê-Ñ]Ië*F‹R±¿x®¨(dª Ì¥e‚¬Ô'èúzëq-õ0 å#ˆ|Y;_…c+Úu~Yó!Å"ù83çz õà˜> ¸Àˆ ”[Þ̨R fñò>0‚,xxji@p“kä\œªŸðÖàÆì¯ó…è qüfg³ýÄ=-ö}Õl|< SÛ­«ŽèÙu¾Æ¦ f:F»ãšVðÓU(Æ'k²°²îfË7öö$·¬/ï¹óéÛwŠ—7ø>osðFUG4Þcó`ƒÚB?¶}´»¬wuÊ!ŠkK-ÛŸwP”ꇕtÜ?ÀPjkÁ›¹µ>Èæi¬VPJ@±¡iõàšëx{6«æ[ì6cà{ÍŽ@åÊÍçÊ—&ÙgmwÁ%™‚¹Ö@sªº…µ1g'v;öv„}mð™‹fˆ¿àëõz¡õ ¨žr’× Ds4AwQQŠx‡ÂÅèVª„ÊWJƒ%ðÉ×Ê‚Lt/_nË šág¿ß™ËäB#õÿ©Ùˆ·a$¢ÉH+´Z‚`8„8–(1ªþy|YâÕ;ïâ£|?O!^â ž·˜WþuIf¤E¨à ™e ˜D%xˆÞ :0¬ýa@Ä Në¶à¦ŽhÌß9.Xw×>}é6+Â6[¥íÐ/kÕ߯ý«åÈÙq«5ŠýøÛoý—±[¶Ð Ž€…v´QÒqˆ%Ë’¬€Jœl›Þ‰—HIØ!\Ô´pNX Ž uÐW*ÕꢜÃVŒ„D“2ÉÆÁÍ0„*# 2>ëͬ¶êöuŸšµG gþQZ[|¬;âô( ­O»©ÿ0—ßôƒÏF.<ÿÌçŸ|”jÝúúuLýüèO™ÜgN7¥ëñ òŠÊ£Rx<~<~:Næ"¨%ž!½J7kQ;ë‹Îˆ;™‰³ʜΩÔRrÏãÐÍdÉ\N—XJe !Ú¡iô+´€T<.kÁ/Þ_¬B_ÎÏõÒDër$[})·¦äü/ÓUÛÄyÇŸçž;;>ûìóËÙNlÇŽ/öå•ókŒƒŸ§&’,á%!8„ÑBBD!¡]ƒ¶(-­ZB·Š¢~€í-êØP ´}@Ú¤iÖJ›4iU•ñ)-›²Iý°ÿs >û^ž{N¾çÿÿÿ~ÿß¶õ…µ%=DG¬°·LJîÐnàΩc2Z4`Ò ? moÚ|ÕJ ÚXÆ‘¨mÛ§w;„H»ïŸ»lÞø¡­a^Šº«Ïˆr¢©EiLÕžÚÌý_Á6dCaMBŒfr2ÄÇx¿Âÿ†çxÞ.®³;ÊSÄëP_'OºblÊïñÅJÚ ËÖêÀ¶dW]v0ßXWS+Ð5¼ºö/ò?î}ZSš€àÞ%ÈEÜZÄ_-0„Aø¾‹ˆºLë ÌÆÊ'\®­F®qï?BCöécò:× Î!‰†5߈yÒüjø-ˇ®õŒ)tF2q’ *XYÄ¡[B|ÊGÍ‹tî—óèª^äÑd¸¯¦ÎÆ\­Pf¡m‰jLgJ—%z³p¬÷+4†MŒ¸h#¡÷¨4ÙÄÈahwV¨õ·ÌömÚ^¹ùvÔ;HœŒ™rTcâïoiÕZM6âW µ‘ÝQXïù—;?èšx­ÎõúÚWß|ü³‘Kx{óñ_ÿhZüûG;b‡Ýî;÷î‹¿ê ô|þ¸|˜F0–ó?\(üÇ÷P/þ^ëìéaºË=½,ò;G›F£ˆ%a9–ñŒDGü ç·xœk¶²¶wå»3ñl.mе!ŸÑr/~„º@C>BqÔ{`oEý\Â^p»!‡«^8oÀ^­©¢Rcª¦WϪóêMõ¡úµúDµÐ¡x¢rt΀JTu ±´´!ãu)¯ë|C6¾­ž†} H3ŸÍƒ–‡a¨4½Ê2@´ÐlØC@·¯ë|#íÜrØhhÆŠQ ×kJÅŒJ%À/cy¬èç”y€•ô2ýˆË‡òÐÚF‡w+Ã4·ìL:½—ífGÀ—àƒ Ó@‘ð¸ÁåQ~ d:Í÷¹((dãj¬•KûW+ÙÚx“9á§À"n‹Ùm6ÛÞÒ¶•ª”OJÙ‚Åf«.%9O§ rÌ›©i) « "ä2W4ô'­YPù8Ã8³%™MÙ&+'шuu©x{»/kšã,\BDYœ]ÄÖÏâs‰E|rA´ˆß"žÐ¬ g° ö-¤£)î Á”‘»¢(Û<ØCÐÔÔZÄÃZ¨n uàŽ/c²&Èãòqù¬&_‘Î@|§W§+«Óßi;Àí¬»ÜÊrRMÂQ×7zÕ‚^€0*dD•ëF[¡A^o2ºW¢Sq­óNGþ-§^ÌÇ*» Þxïǧ¥¹ëû×îÝ˵·FµŒ¿f“”>Qš-§˜ñ¨ûÜPºSû <9ñ¿q°ï®?Ÿ:üõå|C[tsà õ¼sëÇÇfÏSæó^zÄoiÃEÎ`¬2ñf‹`µ*ûF÷Ž ïÙ½kçùùóÁ±±ëJÜ¥(ñƦxºmpx´*9>v°(GR qÕa‚ýVQ%§à$Rœºv}v`nš)TšC¡92MÏ®õa,%Ý7§ÛÚ³yRи*S‘åñþAbèÛÑãÞ^®–›†GÇ8O4QH½Ìó9c[nÏd íí8×Ù© ôhS…íS=‹øÑ‚T(`#œÜµz¦¤ ðdëvtª~J–hFƒÖ‡Vtéõ»÷å‡ò™Èj…¸²²\Jû/€D\¡ä–£›C·2öçφù¡»®Ÿé(*ÕeýñÕ•å%EyJƒÏÍ¢Ú YðBÔÁ•UÌ=xð .—ƒ2‘¨‘1H£xÒ¨Èa‡%•1<ãI%[[ÆùÌå$ `>*=žd"Bë,M'Ò ”q©¶6‚˜9w±-h% °!ƒw§%³Ýh ÅöwMÔñ¶ Fþ¹cÔá—‚¦-6g n¨’~ˆœòŠk× ¦a¦Êe5)±½‚èë­®5ÇÆçðÒ'„x¹œÖb‰ùÚ€xÙÏOsVx 3B·»±jĉÇgf­5ŠHˆe[McãÁæÍ©r©pœ¨æ3U}]7úùˆÅë1ÇÊó._ËL< ¨.@½åÂh/ú«Ö2T.*Ù]’d'ï±Ù‡È0/y ]e’SÍsüÖÆãðßñOyÂ/b¿ffÿÏw¹Æ6užqü}ÏÍŽ/9>>çøÛqâ[|9ŽïŽíäfœåB‚´„ PØH+–¤J4 ëÖ°n£í¥û´©û@Di”­ôí†@”VhR5©HŒ±/K¡Rˈ³÷=6¨•¦IqÛRü>ïÿÿüŸß³²x§ð °^ +pnyÐ-(­@Qv¤æèIÐÌå6ˆüp¹îéŒ fܱüp „s8 XÐ ›IáùðéðR˜ c¡(E½ž“j^©YOÄÚ8\ûZùxl ÙýîÂÙ€ôÔ;ØÈH}„{Š\!¨ªE‘…° µ4U}++¾ŠÊÊG|R1‡Â‹8™Q÷½ª¦6^§›QÙeƒ{«OkBxOô-¦>;©k>ùÞù—žOwE˽!“'”;\ZÜ›ðñÉNËjT:JÑKnñ~ÆE7CxÍ-hL¢ž×ýd—(v¤c–ítÿÜYgÔ»ÁŸu>ŸÑñ¥_'^×1-Z­ÒÁ¢è^h 9^ÏxÍšd‘²E¤ìqºdÑöÓªÖr„ÛN©A$3§VÛ#svºQïvR€ ’§S› . .åX& •´µ¤A µ·ç…ÓÂÛÂ’ð¡pK`Î P@óo ¯¸ÊàSÔÉÕCZ™‰œ¢fDXgßZ*#8„øŽÏ‚Z¥4C(Ü’ˆ×EIè× T7•J§.ÿóoÏýüPStø··œb9ZÌÎ}íŠù%wÞÇøó }ÍÄÄfBﺱtåîæ…Þ™W¦¡îúqgNMú½û׃‡«_?s%hÓ˜lí?íyï$æÅMè†^¤Uh?¼)›ôVk58-bÐâÂ*‡ÃêÕ™Ñt›”[½’àõJ$­ÖQ —Ú›ÍY/ÚB)† \zWK{‚¢²ˆ6d$܉XBNÜI¶7>ŽvžmH‹Y”Cm ô ,ŠY[`°åàùåž“ðDøÏåkåÏ ßd5L®ÔA@® ò=å2ì…Y—ëข”÷”¡€Þœ…³eBS†å<€l¸CÕœSwÏ9Õ4Z´Ây–ý®Œ”éÊ f¨ÌE’tuÁ®‹þö‹Z­»+É%²tˆ’8/’çE(>Šùeÿnÿiÿ’ÿS?ã—°ñÓJˆFÆÿj a:A¤25¶ h±Ðˆ¦ÏUôd¸Z¸ £Ñ(j†©1„+QdïN¢Ö,D®wÂgá”ñ×:$“6š3OÁËfæpl ¨GÒáÈÑÃþñ7¶¾õ×J¤÷ðF©É¨-Y; ½£}i_GÜh©¤þ>/XÓÁÁC颡½ûØŽ]“åëđ⻛ò‹“åKÇ7¼b Óù‘°¼[rLŠm³QïuǺ7Úž…ÌF!àËL™èK¶Uÿ•íŸzùÔÁ›ÎáÎé\¿Kþ QÎpPv2I¨)B”='\sÁ ÌÏ¥iYOæ¸×kfqªä 5À–m%ÅÃi@|~{>~:þv|)þaüVœ‰#Ï×¥(5”–Ö0ñaOƒ1s}‡!kSOrÁ\G».X ”oÝ"Îx#‡®—lñ¼gÐЩgö…¨f:¥’)êÔ£Áï·ÚYà”û$Ý.sG‘å'/O~°–ÔÏܸۣwðFN£S¿¿œ6–=ëãåâÈoÇG2Qg¯&Í&ŸÖBy¸¶mÙÍ}Ó×÷U¿¨~¹ð¦ïÓ? a<ºþ¾Aîà½rRÔ‹"[ÑW+,£Y”(H©¸E»VUo€ŠÛsÊN8 Nüç'ít¶¶à›@¿vt­v¡u¼È+eÕâT©”¯õ¹b <À2飞ÞPfd¸¬¦ «c±7f×[}ödz‹¿'>sô†G‹û GƒP¬Žæœ‰¤0±#…H§M‹N½·ú+xƒÜ‡Ný²Ž Y¿ÜæÚïšv‘®X”CÚERÅÌóK<+0*빊ÛsÈÒᢠ¡ß[=–“,¸)ÐÁ%e”·Çøä³uœL×¥Ä]ñ”Ü™z% CåXŨï« œ«ÇM™JÁ˞Ì"½­}&â©ÑJÌiލ!Qy’Ôkš“É´ã¶|¿ÐÿË©ÜqW¢L1"òìI0KݤÎl—–0Ì€23ASÔIˆ¼-Ó¡—Ý€d(Щ7/#Lr£-þƒŒ\’ͺšCÙŒ#j -»Zjya Š ºùø}jÓ“Erj^^§úfõut³'áu“ü¥ xdž¼¨ *‚yŒ^»UÄ'*¨BZÖÐ7¬JHj¾YlæÐã$µ ÿ¿Çï“«~üøN-;dïÿ®…`™&(T Šdš@…È 0$ Ý9¤13®æÿÃC¦ òíäÔ“Eê\5õj5õÜ`wï]_%!?’Ø€+@\h…­+°UîÔQÄsº‡…?šÿÝ\”š ¤?¦þÒÐŽswÜlØ&Â3ñ¸í‚ûŠ›p»Ó¬Íe;o»`»b£mÒö&ÿ:a|½Z‹Øµ{Ê:€Î;¦,-èü> &Óy—µ6HÄv aÔû¿{m1†‡f- }ÙÃgrÙÙ>ßÙö\çðÎÏ¡yàÄQWl\Þ²µXØ:  dnì1h8[$²ed&—KuöU¿º¶ÿwý&-£q^îÌò#€X¿þËt¹7qqüœ³÷•,­¤•äµbËÖÅk IkK¶%°e[Øb±aá­$Ë@ Øø¡P0:¸´™^€¤M§¤3½¤¤-4„Æ!Ó–¦í0…Ìô!“¦MTè¤õL2ahŠÝ³kÓV»’Žö¢‡ýþßÿûýj}@…Áì-ÊD™%V²ž1}ÅL›Ò°=NçZãª2 ªQ–?©²¦F“(NEU1UYšž‰«b<®Ò¦Ü€Jñýb4ž%•ÆõÍALÌÛlÔk­‘mmí¯Ì(óÊUå¦B* `‰,ËG¿E¢Tß¼.ª °“zN}Uý»JòjXUÕ¢º_¥X“J qH·ÆÛ×wes, <™¯Bhõl÷ Ïb#˜WÁMÌ+ ‹K¬Ì ¢3žmec¾áqW^e³:›wW«FnKcôsÇŸ¤2H,ú¤°šð÷: dJÈd˜LÚÖа,¸—ô@×èv4ÀU'wë l>\J+jE((HÿÏíõÓ2v èJ$±Õ×!GëPSíí¥¦†(÷‹ ã>Ñoм}›BAõ­aÿå6b:ÎòTËðò)g¯ÃâîẠêú$¤öÁ[Ÿ„¥†‰&GsÖÚ²¡оüìénUÆCaÆÊÛ›ÆjAò7ÖÖ0|Me×-Øú^‡£Îä`°˜Ì6ÆŒâÔ–ºîîÍ+ËM5€4PA |šÝs¦í¢ïǾ?4‘Læz׋{B/„.†~"CjpŒ( EÐ[©‹ÎL¥±0R˜/\-Ü,PBrø.œC•­³^s" u²Ê8 mìÖ¾°9‡›„è¯qc›KZ)WÂíþÛfÓÍ"³5¿Å½ض0#Š,Âß\›7Có»ðo ,<š}\~¬‡©YááÒÒRUÈUáaZÁ¸™Ð‡±A›¸êÕn|ØhÈñòø\yI0¶ÕØ…ÛÕ¨ëlÙÃØ‰v¢Yn^íÐdPG~w¢ÓÝ@¬Ú¼A>«üï—ñ(‡«p£u\f'#:ÖRø˜“q»6£Z_OÈB²ˆA,ÁÇ0ñ1Íf~]v‹æÝ3èL>µû•ïKöué3©¹Ë“ÂÐÞÒyñ»ßúv¸窚žÔÜ7zñ—_î®Å@ŠFhг¹©)øÓ^è´Ó¤ A~€2Aüªeû’w†Ä˜ïúto¾3¶±KäI¡Oéé³ó&÷º§¿3êz¼Ã³éXybýH’;zþ¾€ý¹¼ò9¦â ^ÌöIüýšü¦Lòü ë"¬[òоs¤îF¤»>¶+¾ñ¡ú8@¹½$IJæAš‘nJÄU J‹ðÖµ÷C0ô.üPp¹ª˜AqSêäYîÖê0k”i­»ÊPo¿ñähÛ!I¯‹žÐÚFhŠ»È;5-vXœøãñ×*']d87öì;ãÁ É"gÙøç½·uîT7\€mÇîQ áëÙüÙÃG~¸|ïrþšjŠ.œe`sH˜nP%Ï¿ñ»£0 _’ô9ǾX¥ÂxJ Ù¬äkК4õºD¥~ …Z"rÇî¢K@¢·"k‘-áç"¡ý+#ìÆü†ŽT†èJ³ßY¹´k¡­ßÑ|üÁÑÛœÄ𠬬P㔇[³¦=Åݸò–ÊΦððÀïx+¤ Ø¡}žË9kÚ›žNŸH“éó= &Ä&b312v^>Vä4rônhdß"|µÈ•ž²¬íÖv²$*.ÂB–ß>]°Y%“%%öðp°‚x‡¾(^·4Ü‘­O5åû‚›fL>?óŹ8¸ÛbIY­Ðj-¤Únà«Ûq­- 5“B©T!¿ûøôäA\þkÇÍåu×Û499Ä‹w6•ff¦ü¥9¼~«ðï)] '„G† 0LC ºße l}Xµ­‘‡þ»Iï¨Uû3z¬jhÂø…‰Ï>Gªúa¡Š÷²¾ãpˆÿzõJEÐ9Îè<ì~I¬“zè­Ð§;âš5)Æí4¼.ÙÙm ?=éÕCÿÿ_!>Ñ¡B줴•0>ëg:ž4§œ”Ûåµ[åP:<¼7p᣷¯oâHïmÁ‰ rˆMŽt‡C¢œm¢9d}wC´!Qˆ* 9KJ?{ã8a‘¼®/C¨ÅöelžÃõ.!^vÛ9†­cØlq:­í}G(Ù~=Gð On¢h³X±…¼ðÈìë³Ç(« cºA+6³²B^¡<à0¬Ë¶Ú]5Á“Õt.³½0N”FmEÇ3{‹¨b—uÔ;ŠF/•òÈ 9”»”ÑÅ몔J®9 òŒLÈKšCs¡i hs¬ôm/#¹Dz|ßµ¢S7˜Ö$Ç“”©†4ë“×n?dMûƬ~¯ÿ„ÿŠŸôû;’ûM0ìD‰çYìFº,ÙÜô ~3F„‘ÊÈû#äÈ{ð—€Åj|{Ó˜.ߨ&Î;ŽßsÿÏöùlßùÎvb;1vœÿŽíØÆÁÁ–@Cþ°%wØ&… …Õ„¢”$„ÐÑE¬#j”UËVX7ŠhÕ¡•®Ú‹U›Pµ½ØxmÚ ¶½Èª©RÌžçìPrö)öcç¹?ßï/¿†œcCˆ¡àE¡ (ËZ( 7Xºlº¥” MAO­Â$^{šG„­¯®åWwÏõH9£z*‡[¢°bÁÕ  Bââ‚–€DƲHÌÆ,¹©4~Ùuؼ *—*ZD')MšúÉ`"¼½Ýà!¨>ýÙM¾.ŽŠ8äâ&a@ªqÌœþgaR Kõ¿6­4.Ð~«d¢­õ[.\T£F;O Gï<]»7É;ì%›)c5 (-ÑÈz9£RÑR „ X©ÉWA¢÷Šã‹D¤—ÙÖEI¼©¶žþÇ«+ ×l&Mt'e‚v4 <ž=Š£ƒ‡$„•Uücoq ƒ†³„‡!ŋрl¸ÈÙIZô÷ò¦>Q|¼W4™pÂ@»Ì‚hM^ûŸý‹új†°w3]†!g¿khÈvÃJ1O%=>)ž û²õa­^kn–¨?ðÃ{¥á޽D´¦<þZ¢²†9N•™LJ¨ñÖà5…Ê\ë}p cMYæ,©ß¤ð')úêËЃÂ^…aÿmËêúª®%è›o1УåÒMYM¥¼Ê½]=n•lÏå¡7*Ý?±VýÂÊQHˆ~ia3ëµ ÝI½"ý´­ÀOŒÈ”™±1 ž—¼mÙCïG>ŸÝÖP,lc¼Os38<|¬¯²ú';L ÀX(–¤¡²ø×‡~×¹¶ºù;‘€eQj:ó˜|èþyPSðlº‹‹¾Tüæ+ë°Tµ œÁÛ6mvÒ,Š/Âe3š Šõ>¥ì2¸Ê õ›ó3Ó×çÝ9BµÃ«“Á8ú]ؼ ~”ñ[foãÁå…›#ÙÆW³ƒÙ}ײ—o##Lgg¼äÈVß|Ãm Û ] u K“KO–ˆ'K`iéÓFXRj‘$Œ‡µ}Ú0>«]Ö.¢Ç—0í¾ö)‹=¯Î›žxíìéãcgú^Ÿïí¹Ñ?°ïmbášz¥9ýàö¯î1-¿H¤—;Rím+f¹4¨‰A¡Œb­Á]/˜!bÑ’m ŽìO^ ;¬Pr‰JÝJ RlD(ÊÃ’ÒÊɆ/‚¾r¸ ­Ø‰Ñ=µ™¾`<Çúç© BJ«øô÷²J^|cÌDçûàébÌÐJOB)ဠ+‚B…™ %¿ß|fKEÂ^ý†Ýpò—2T¼•âÛ]wïøjp€Ó aÜtT´â´LÈ¿,óS6«¿Æ]È\ÒMë¯À¡0q»m QË´l¸70e–ÙÓoaÜÒ†b Ç0œËV):H¨§ëFšçÒï”EŽýadŸ½žÙjðÔÉ”ñ› ;uËîï5´ía¬ð#3IPnÖd'EÚ9‹Ri–Fkd'mUa± ›)”êŒï|ÓJ'CKN’Þ$`‚E°D°J´ ’ÕÅÛÎ&jòåÉÆ7¯œªѤdäéfÑÆtÿÇß‹íBÝþ0»ù ¶ø{W­À•£–W—)øŸ²È¨‰ÿ‘rcØ™X}.™²¤Ñí’&g•h6éÑÍ…cZ»¶ íìÛ‰ûÉüç£6€%±6LòäÔÔsš#„95 m‚&d…aR:w>‡Ÿ›º~~fš˜›ÓF$MI¦Ó¯ jÒà öÞâÒ²”LoÛ>¨Ìνeìù~gƒèÏöaG‰ëÙå>­[ë hNÍ3¦ÓNÞÔ–µÅ܃ŸdÙcGGû„A_ÜÙ=825ËõOü +¤ÝÓpm¼.|ëbþêµ¹h2ž0_²qFÁ 9œ$³,06 ‚`p|>”èëí_^f°ªy0_¸„.嘨gc\MÕ«¹DŽ¢H¡ \ízÒ…ÃÁëVFîïÆÓãÇÇoß§®Ž?Çoƒñûའ÷åè¿Gqï(}b$„ä§°ûžÈ¯Ÿ<‘‡­æDfÒS4L• ý¦Üÿ3]ö±Mœw¿çÞÏ>Ÿïüv>¿¿‡Ä& 1BRîIì,%¤%!¹Å"!€ÓȨ )EqGK`*­«i•¨&Õí?lÓ˜ mÿ˲J ­Ë¤¬ÒX5þ LÝÚ?¦Ñj“Fºç¹K²ž}­ç~§“ìï÷÷ùþŒ1ÊÏ6(µ.(i=çBÇÐ*·Ö¢ G++ëïGâ¹FuZJÏ7$Ï‹‹ó Þ$?ÜŒI¤¦  žFê…bÜ33$S­¡Läo¤COzm[·x¸ŒïnèñŒ±v˜Ákû޵r¤R.FRÆÑºÑ ęڵž€0h>ÝOÀƒ2ÿ‹b¨>stŸ‹G”}·×hTÉñÌ«/í© ñ6‘ ÔçYŽ’SîìΨ­\G°»ÃîF¤"ÅÀ?[:´õlÿôÕÓålË7B°—0\DêÀÉÎúQ÷÷\ÃM"+RdjKÌCpöâ*I'¹ú7úÎׂ`êÖþŽm¾î’s»wùÍÔf{(e•䉴ßÍÛwã P°ð!Av±¼·WL´ÊömOç(n÷ùÖ°m~'ÇXq`“6ޤ©ý¤%Q¿·øZÔŒYì_þ%asxHš#à ¯À¦;$CÑÂ{íÚcãh9À]ÁM[Ô÷Âð˜â´º]V2º)¡#k1’²SQlû·?=paàû×Þ ºº°Õ•;@öe±îcCã`øpÊ5Ê¢„×Ú}èpßÇù„Ò£ø¸ž×³§†ÊC•¡êÐ!ª{(Oôç¶Öw¥ÕÃVç(Ö lüá+îmGm±ãàÊ`pU1®¦‚G73¾’° „™úRú¸Ý“kÍ }'û‹%‘é9Ø8!l?6SÛÆËP.š¥–ué#µ›³ É'ÍŽ z9Z€ ªÝ m‚ ÊYÛQæZ“§ÿwÈßè¯0sÁGÉPŸ»WUh„•hå%£›P42µÛž¶ÔÚhœ8 [šŠ*®¸³’Åûæë“ÊN³V:ñ"Å“fƒÆ!ÜHË¡VõGùNw,éxC†‘éšmÜ ×êõw~w昶á:'Þ+–¿{`ôøƒq¡èq›…äxŸÊœ#XkPæ*#PVªÙfm[¶íU6¯&BTnM êzÊ÷fN$ xš`•­‡*©Ã0¦–R°—ñok(ÇA¾åª·ªT}U5P VCÕp5RZ«±kñ;òïåŽoÑ¿`}Kò’wIYò-û—Œ¥žLZ&èÊŠ ú&ꃹâ­(ö1_Å_ T‚•P%\‰T¢ìÒÑåcËÇ—ŠœXzniò¯SìÝÒ½3ÍÜ=»|dyœ^,Ë‘Åè½iúò‰ׂgA^ðþ>wÁÏj²æÕ”NßÅÈ+1º,—½e¥ì+ûËr°*‡Ë‘r´+ÇmÜ”íö×W´ÑøÔd$.LÍ)„CÁ€ß§xe9ÞVÒ&§æ´\n*?æÊçǔ٩©Ïãðo‹+³çf§Î¢8Eq¿š}0‹ÇgÇ”Õt¡GÔçt0Œí×êÏNBö”õg‘qR˜~mÓ…agFoºŒßƒ©ÉxŠ›m¼¨^Ä{J9û`x,åµÁA,‡G·rùŸçAþ6øLsSØœ8÷é1W:J”PâîÏ‚Y”6Ζ:þ®‰ÕGÝ¡–(ò*°½ÀÑ£`ÐÂ4JA|\øâ‘ù Ä4‰Š rÈW0Î!—æ…†$‹P@AÌ çá†7) (ôÜHô iÖÔØääOã)ø‹¤6Štà€.óŠ+ó¨mÆ™XJîÄLŒ£`XaÚOvød‰á¾§@&M™(§Gá&=œÐc™´i6Ռᶠ¬q" „€™"hæÿ¼ 0óµ‘Fá^­¸àÜ 0&ÕçcÞfÇ£§"^Ó j,ŽIªyÊúCÊjÄEÁ¶9±gÚq€äü÷¶îâk`:i­“aÁó:þû‡Þ¸ìðºŽ& ùAþ‡sÈì¾+îËxwÅœÉüÃ,Ó2Ò´ë•2Ó!ƽãà˜ˆ2WRnšT¤0aìrE»¯øWÆË›Ú{CÞ`~ß%àÝr Z&^+.°!Î!\!ûêÇõ«—û_9¯Y·[æqÐ)ZÙÄ`T)~÷Ÿ,º[ï*›ÁÕ¶²)§Ð$hÿÍjíêïŸn—ùn`G<`¾~H¿LÉX \ÒJ~QœIŠÚrÙ¯j?ñ߬';µ‡ÚKwPt‘Z²]ÒA‰Ìvtgõ,–Ä.1û•ôß,ußÿEòY¢(½uú‰p‰²Ô&‚„uaYBÊU¤oõôj’ |žÕ\Ù¬6 ¨ºvìÿåÁèM|þ†…¡qØ0¨Ñ¡5u!†]Лy}æí"Qj —”Rïh©¨@tÜâÂh‘nC#Ô¨¢Q;Õƒê»êmõO*£©Õ[êC•T?)b¥“œØ ZzQ%rè³"ø¤vskPÑBíÿÇ™GöM>]ù¦ÛÛsdd£ÍÄëH*(‹Am¥¡µí”§ t}°·ÑbðÕ‰‰Û7éÑaG±c}61aÚâ|ž&p†9ðVàçÔÏ”—´ª 8aý8IÖ”R(³Êhj.ãKz XÖÍ÷Ò¤’ àÑ¡ÿr~õÀ*ªïjf“QâšÛÒd¡«ýìhrð¾H¶Ð_§ pWXõSжjk_ßy`¤ ˜‰ 1j†bÜuÔ/XÀÐ:~ü¥îïþ¾¦Æ‡P—fšf­¦ „tö‘#']íÖjk§X= :%ÇsvGµJ[Û¬@üÔèp1:©—+/V:Š^$Êö¡’ H5¥fèOÛl´ªj^ã2Œ±rM`Þ¨¬!5ÑÌ\ªªîg‰WÐa…ÂX²„—ôn°ìî W,À‚›;š÷6Ú´ùrh,B&ƒWP–Ô¯JC ”|æ{×ÜëØÒlÄÛï$‘*QôIŽïI;Œeà„Tƒ`9>/LChu<¾¹ûó‹Ó½'~±ï{—»üÒ_Ü™yt¼¥rrÍ»öŒw§7´Ž ù Pú–ÉÉíMTÞD™Ømû;jógÿóÌ@Ïl×ÐÑ–·ïÿø”èÑ”nÿùÌïöÖ7Ù³“«Û¾zó©õxdž ’~“®#6"wëÍ~`öýpªƒÆœ¾@æ½y_¾>ïÏh£×è3ÖýÆäC|ƒÂWïPÞ`ð†˜çE1ïÝæ{èî±Hê'Í;Ê689¥Ÿ´m.+õÝ ÑÝm‹Åb»ÂŒ2’ NGŠcŠE/ˆÄšÉ¨7)W~v¤0×?¿gwï®M}J-«"<ÉKWf£‘ãTåM}»æÇ÷Liµ}ªÙ%Öõ¤ë”ëG.ªÖ5ä‚.WTUXè›RE+åÕϺ‰SVªœ,¢”>…OðK(éGÊHòUB¾²Ü•п‚ ÕZ> ñ¸ü&ö*Œ~œC¢‰‡œžüX3hš 2ž™ãHFñêŒ*F²$Ù}P£x¿§ÞãÇ­ð?ËÁ}a²HÏñL½}Ü(h5$F€}ïâU Š?ÌzÛlFÜEAHÒÃvHÅB–îÞª–ƒ ‹~qäë>d;ò%««€oÖ _QwØõî!¼=Æ;×ðQ’¢k×¶SümÀ¦þF¦¹‚‹Qó™'<6_*¼)âBrFG§NËòJÝÈŸö•Zw”¯&54R+ÁUi>:¶å•©&ªÜÚê1 ­u; æû}›~5£5AGàÚ{¥ÞÜdJÆÊ¨á øðlfÎîçYš;6²#²‰töö?É«ta™=¡ª¦Óµfsº%ý›º*–gM¬™µP>cWš9îFZäÓiˆz±N$Mé.qTÜ"nOÓ{ÅçÓgÒïˆÒ´J´‰¿ÿ–¦|b›Ø%ö¥©š4Óf’kõûµn–¨%"CPCÄq˜x’ ¢S½ìf.kËdkÙ­\^Òœh¦l¹èœ œ£¨äiÂlçÁÛY[.8.úÓÇsgsWr$‘Óçv¡Óåó£Wÿei~5!`Bºu !TK3Cj0ä“òJx¤Hc}·”pÎÀYMt ¤Fa„é·Ä5˜^œÏF=n™àñA²›úë½ô#ñ9¨Rh(U¯&Ø:³'ÑþŽøFcªÑÃ…œ‡ŽmëÞ´/¦¥)NEuµý÷‹­‹C]¡Êñ'FV®E§Ô¿Ý][FIãBaë@¶££ÕXÒ{6LOFœÃ^Þ£SS¬Z}(g¯‡s–xÆy Õ—ñ/ξ6têšAE€Û4oòtØYïÞñÏœP( ¥$i2r:5A«4¥z¯}ÒÑ.öÄ&“ÞÑI”ßrEŽÁÜ«=7ZÖ8΃X6TàÇi`²˜+Š ýÌ'3Pg4Ù)S}C¤¹n ¯Y›#Mv–Œ8 :Àa"&ÀXVWÊåÖv¶®Âã¡Î»×¿? Ι€é-Z–bÂ*@km¢B£¯~¯&T…S£oPäš4ë¶ÿ¡ó©„=dï¨ CWA•²öµéº† VMD[Û¦§Õô¹.û˜6Î;Žßs¯öùì³}gßùŒ± ó0ǾÄ3.0 ˜ ¸Ø.$!)á%1ÉHh@ÍË’ð’Œ4$ëV6T)ª¦­Z•Jk;Ö,ª¢f[§fê´?+mÚ¦´Ú&mL‘öÇØswfjÆùžÇ~î8Œ~Ï÷÷ý|›X`5«VÒו‰3cÕw fœÀ«]×¶?ßþør:@‘€¥ŒAƒÑXg ‚ÁcqñœwàüüF#Àí®S>‘ÝÿqL¥°àÎÄG]é±<’®Ê~ýU·9?Œîk¡K3¶ÇªŒæ€b‚©‡jK*{rmþу¥]iC€öØ>,ÞÛ\11.Ì"AòâEAÊô¦¹œ4b™ópg}ùÞ¡ÈHKý}¸=ÂH Ò—©·e.|*>7ªí€~мvj<]x“Ïnzyúì‰^z«j%Ï,¼šeTϱǒ_Â;5ˆ•H¸º”Y ?P‚ƒÔÊ Y‹(¡´v­#‚iu§ª£-BsT¯÷ÿÒ ¯%^½ZîVмº¢³sÍÑ+BÿçmO´Û•¿p3QëÛ{p`lpϰ-há$ã|¡—ÌhßGcÃ6¯¬IQ ¢†ÒebåòãåïÿqÖÁ«óŒ Ø0 ¦&n08-'||ð¥þwþ3óBkyØeIJѦ×ÿ[㼞n0¢~³ÉjB0 Ø+\ã…îO¯†ÇâƒKÓÝ«à?vzag;Ûù7ñ2$AäÙhýƇ¦R‰ôÖÎ%¹GêJûúººf$2ÏÔ´aÂKþD*ÝÕgÈ ärò6Våê[”z¥ Íý5õm 2"¥ÒXíh;ßÕG0÷Á©™lù~ä"‚á€"žAyšé^_ªœ:èUƒç®·÷¼ê‘É/ñþb"Í'饱֯)µj<Z…±V½†mѧ£T.HÒ0y Q®êÍX(L™Íª‰Gw Ka*BƒßeÆf ÓÂ'åùþ.tÜVç0¡þÀÀi¿{ï¹2 8ÏKƒÄío ž­—œsÕ‹íµ"¦ëœ!š«09»Ìláøo† ™Ñe4ã o‚zøø½íížÔèîdÝJÞÃYœ$.O›ýVø±ÑF ©ÇÛï7MÉì û·ÛP´¼ãCð#`ûÐìr’j?ßù µ‡°!·Ðœü24åÓ`¿î$7áCj–Î'ξºš`®ÅnoÎÞ+Þ›%*…°»¶¬Î.ŸLÝ®ÎÜh`48”›\&1 ÙÛ¿*ârB‘˜—â I÷ÇGâ#Ñ‚tUºZ¶(Šñ•­Û?W–}[;Wäã…Å_Ùââ¹B”/¢7VVΉ/ŠÜüÂÂáÂ\;D®£8´Ì -ƒÉ™“x°a̦ô@vpè¸)ĉRY4žèØ?R;rtþê ÛÂʲqyŸ²Øœ£g”)eººléRzhS¨ VBÓ¿€~‚'/ëA3'ç±bvl| ýý;z|?2Ñ?0\˜,\/Ü/à0 ðl¢#Ý5²HÊñLLbˆÂ/®kj^]^15n’CiÆlãnÁ`C```"Û°w±— L~Ày(Ë@Î7fœý]ÍfÁÄÃ#[à¬l–‹cÅ‹Å7‹x_·ÀçÐÉ€T×.ƒ‹àÔ½_Ol1í:ët¼{ªª€û¶`‹éŽ6[ÐܬªM*°j¯§Ú3i2–´&´›w¥£ê΢ª¡¥ç¦Ú’jÔNÏÍêªöAKS ©S·H¨¦Ý6˜I±*-]UGÕÆ /·:Ò-j7ݧq‘¦9õ!m- Tµa^¥é*ªë¢Lá+Í–"QŒRUû#$ÊÂç膬 ƒM—)ÔÀÙC4IÛ`§l™¾]SNS$îÃ}íÂwèm¶JÉá0²ÍîÎ&chWÅü9—ÃgG1t:Ì5/áòŒzõÝ2«¨µb”õõ£Œ"ØÖÄÿügÇhÆCœrÛ x}ÖtÏxöµ>±1“L=k¼Ç³¶111“xx{ÜJ‡6‚Ûã¯H¦2‡NLÍœ>³¶¾ÁUõŒž½†/g•< ˜›9FAº*Q”ft9wIYP.ÐèCO_?Ö'3xì ¨ðøC Mð)äx;5Š…-ùõ)«pöl>s¼½öþÚ/×°o][ÛÀg7‘+w‘yë<:?7»jß»reó®u LËVÇêæfþnÝö†Ñðœ^•]±XïÍü›ù{y,?7¾úY/°öÎõ¢½[wŸfuœ|ö´ðDO§úXØå Ý›4Z, ¾/èš„2´>yª:Ö? ÕY_×è²d]%½=¯¯%Ëÿ¯ÀA]|ôÈ œõOúOâ‘jnd/ÐÃéÐÌJ%†ZUB¥Ü eªsú›5ÚQ3‹h‚4+ÔéU *Q5Ç@·kèØ«š#„YÝ9½ xC³C¸o‘hÛWuµJ·SÕV[™ SdÛ\„·ýÄåoZ9”%2€uɇM±ÅzÇx†òFj0˜Œ‡€l'iž\ñ[.¿™Æ~ÝWå>‰XFH-˜†äOBRí=h²@‰9ëzÎ «uåÿeºêcÚ8ïðûq¾;|¾ó'¶1þcÎ`càŒÁÇ@bB ‰!Œ:$4Ê’’4ÀJǦ¥ˆ®ÕöÏ¥™–uÊúǾþJÕ4é*-[öß´UÚÖN«´UK+¶©e›4¦©Ê0û’èõ½~}ïéN¾çù=¿ç±csÓ³ G|¢RôHü‰oa¨êoUÛf‚¶îgúrᾔ̻Çc†u€ÇÆ,Xc òD¥&«éÒѯ+nEA‘ÀraÞ.²6^Á ™]A>¶öN(¦8Ž+,{m;Çš–‰Çj³›y^[äÀÓ7¼÷R½M¢Éª†¹vVbLp?· *¨–Cè;G^™>Ò5Ù#ï;Ûa-k3zöˆeç >¿Š‡ro)…ÑøèÁ™8£ô(%¯ 2~ÕåUZ©Eå¼t„FÝѸûÂêŠ}Õ½ºFOì£Q÷hÁš\cDW=ì' £cGVVÍS]3™©™Ùütf:Käi2-’sÓ³Ós¦ÙW^*x{2[`gfÓåÑÌÑñbtÂjQ–àç.¬pË„[]cæÑà`~f| iÕy«üd“SŸ(—‡ÑÌšÙ³ñߌÏ&xù-µzÝ˦v5JJ{hýªé­\¦ÐOœé‡ÖÖŽª³§ëÉ'zÕÿÕ`ÎuV‰\5}Õ‰wðÎa{œñì|‚ðáf(‚ZwªFƒæþj¥Ðǧ‡½s¢[-ƒ/Œ!–™Xì ´¹[9œoh0u°œ ¨¬]>Û9Á”ìÔ"2ÍŽæ:ÂüZP’j Ó"có1ÛáµåÀaÊ0¼œ:)ã¾8èâQÙŸrc¼Q'a&ßÀÿò)6cUÅϱ„•M„Á„$‚Í|—…¬qðZ²UšÙì6Ô+ùUö[>™­ ! GÍýFh9d”‘]¡µ{7ze‡ Ð.2Q†¡ë ÁF*Ç„’älf¸véÛ×ÀDX­WM‡ŽQž³ݦ 1ÌÙ*¡û¹ƒ&íYè¡gèéÌBšô@:ÐC9Êõ )*wd2ˆl'DND«»}ÔâÍg†úHÿ˜ßІ†¼}Óý3c·ñ?Q„Xr’<£4=2=fªMÝyg8ðS<…üȧršÿç>’Û:2ýù‘CGD’H ïÌ’äCBß%øK ~r‘Ü$4C'Ê'Ê‹K[™Ð+•ņ±U¥ÙÖ ×CæØV1SÝ£¡!Ë ã/_ÚãZº¹[¯%‰*sÂѳgU@&a«ÆÂN½ ˆh¨4‹€|ñÎ>ìJí#i½óÀ«¦f GÃlU[“tÿ{ýª¿ýÕç:5Õ=µP¹§Ç|§‰‚tqÙ€äÐE_Ä©{çG/`A»·Vþþ‡ÏïÛwbHûòµ/” A³Û*W.vúž[tTþÑä­÷µˆ‘x;Æmñü×£ºûìoW¨Nb™(Ö™ƒ& ¼,ì´™÷GóLåJå/ÏOK¤^?v¾/Ø_„ð ’F㕹Ãʨ ½˜o<†¶qžP¨1`ó¨V‡³EêhÖbÑXSGXšL&›S |äÐ&%µä(yJÊdS)\  $ÊA< ùï.âü¨ÆÀíí°³ÉvM$”¬’ÍÖ`xø6™Ø2ö:’6=ØY w>ìôc£“¹ ní®ÇUÛÔÜŽ¦£Ý¶j_JÃô ÏEXî–ÝL1Ãgƒÿ…qã|·¡•ð¤F/€‰•耄cŠF>y½þû÷]¹Ô(FÌn³MdC²Y!!þôŸ}¦“lεxZÙ£lÆoh¥ò Ýf¯ Šâ93F”ž#˜Ž1ÚÀïý„Ïû&Jl$û¿ì#RÙ:qxåäý²W>›6ª©µÒ?…<ׇÞÎ¥êLAr^Œžƒ!‘„ꜾzËݤjo7êèJèZcj§qή:ý.UoëØÀ›oõr¥ˆ îpÙàPQ̽pÄ‘q΃ü0ûPoæ¬qo2*Å?ºÁ(òa„DH;YC·•½paŒlmÔP “êº  ch<””Õˆ ì¾Þ@(Ϲ €¨WEˆ5D³æ"`D œŽv⊅ös-vŠÓ1ìí¥ð&/-¦rK_ó118÷ꌙ«6+ÇÕÛÌ6LClå÷#ÊFÃý†Ã•+É¡©"—µ˜­Üಈœ×n²½ö‹Ùý?º&OýJ;Ô¢˜á_#×{qèT.BX†Y¢ÄNáî,Ç-!lT`ÿ“ãJCè~õ‹9¾sB@A 4E‰²Ç ð*Äõ WÖóiFÙÃÙ05¸1à-àkø;øêÊ+&×ÉovRU¡Âªö%°âÁ´BÕJ+‘†ÿ{ƒl¾‘Ç~øÏ9ß9Gì¼¥VÖf.F ÜaaõžWO”.[¿?#%-¿ãhƒnntijúh¾cl4L¹N†¤ë}žGê¡­^ÚÙ&(]ç×à¥ïß¿âíöRòsë\´#Éø"‰7z ®Ý»ÏI¿.Š%±IìA®@º~`ê„jIÖ±gD§µ¤&%Vò…'Ö,ô`ÕÇX˜M¥ Šé”t¬Ü‰„“벡̦+lEæÆ¼cøXM¼FHº0Ù'ß•‰å‡2~S¾'oÊÄš9ÈM@^î4ªÐ‘ꡨ¿R9DAm¨ 8©ž„9Á¿Dw‹*rD­jÐV:µwÔHè- ËI¨ƒôÖEnîG м$â­:‘ìï…(RÝeßõ³@Źc†ùöX°¶¾¥ß婸••w:y[×§qö˜ûêÙžYGÀÜN3£Wò=ß ?òµåq7Ûõê훾¡ØøÙ¥¡YåÆXߢËZôî’ˆqaÒɇñ¿/ÃÐùнójçt¡SèÄF¤ÒûÅ8Ü ÅÝÄ÷ˆ,‚ÎÅßbþÊàÿd¾ìÀŸbÿÀp Š7¼UKp¶À:€ÙýµM;Àìvüžý…·?0þ×a=ü*¬˜f­*¢ÀÊ#:±*@^Õdo/dß0žˆ£ãB÷!¾Mf¢Ó$fy½ÃÔ¾u÷ä§Ñhæ[ºúÁÛéX׸ÃârI‹ïþê¢Þa‡`«" ÜÉÛGÆ“ï¥öß¿]©§’C©\¯Ýöþw~ò{#ãÑ€ì:´û/r^—Á*XûOî¿ žž¦:÷L ˆ…tM)ÌåÇçÖfju’ža•úŒº¤žW7Tò¡º©n©„ªŽ“´ÆYzP%‡’¾h8쉮Bþࢢít]ÞŽŽp°»; —“¦«´ë·Ðp’ ¯±ä {±r°2t5‰áÏàgjÉ[Þ2PËÅòñòÝ2YFwŽÿ¢z¡i¸Ýhl·¬h;ûÒRZ«.ìÅmS ªVÚʰ(­(§@ª¢SUÉ ™ =G£`rÀRФ®Ýæ°k…í¢‚Øö‚Å^Ѓ;QŽ= h4Nò’Æaô„èûŽΜ; -ÌÉÖìQÍCëX˜ðaÔ@Ù†hm–‚YGwE¿=àbQ×å„ÑåüÕÂJüÛÎuºÓVŸî)î Zï:¿G_GÏþ,ÚN²1J‹?¸ÝÀY\WRîø×†Âäõœ+mw'ú»Í¦BgœÕ’£‹Agöò¸E7fÕ!j>½üdçKÜÕÞ¡Cû.ú<=™Cc?þ²db÷9±FÌa}Ð]nþ’ãMÂðÇ»/° ØÝÌM2F%ðÌcæL„ŽÖy»]¨Ì+˜Ú³NUi:ÌLqAå8ˆ×L¦ RkXp#x/¸$W‚σxðA aƒ"Y­6vÌ­zØÜ5|«ò6J"fG¾ùÿFâ™LÀÖŠÜ!ù‘\èUÁýÓ]ÓÎØÁþNqö7—‹ñÑú!ë>ü0螎Öém!ìncp±ì*-pVw»4SŸÆ˜ ÉËs9“UgðöGM–Éå©Þ£«™ÓÊ×OÁ< ÷H #‰ ®«1ç=ãOz+$•ýΉIaÜ6 *KcæyÛø¼ícð969¡?Ll(T¥¾ÐýùÝ>з sØÜ’áü)0¸ÿµÙÝ|if²XH¥I¦ÍH™y§à×ÁºÑÈPÉBq~½D}Ç@¹øR¹ –‡~Xp!0*<ÏI7¥-‰ÈIŸI¸ôü<çÅDŸøP|!’<b"‰⦸…î·D\Ô¬âAj¦BíÒã6ìNÊž ÷Ú“Ö®ÖD¦Úh%Élókícv(š•§%è²n˜“2î—͉àT¡h5ëFë©âm‚Fîé–pi*hø?‡´jo¦Ì–d~øi* øŠ%ad¤ â*Å“g–ȧœ#+S“'‚#aÛ¦ð¼ÓÛkÀúc5‚ic¦¬Æ`ƒA¾›{Ál"É ¦ž:qè½—fmB•eø6#ó‹M+|¤w™é7þ¬º3ÑXÁµqÇm±ùëËnȆ6½µ2ë ûhN±÷lå˜Õm”ÿ†&Iæ¾øÎ.ùLu‡°Øel7×2^;yßHÈT1‚eë \ø©oÍéäò\½X_ªß¨“7ê þ¹òFöqÏe7²x6›/V#îR5_®rtžëBr‰Âó5Ì †qþâÔ!p%o /Õ¸z"r! þ6âÁGFÜ\›Àp*ȹÁ†¸Ÿ2^(*Q$Ž+ÄCA)/ñÏ`©’W/T«‹HÎU´‡w0+È(*ÈUäpa'_)\FôÌêz@l¼¬6š;@ :´]Sé& Pæ)MýM>„$-f4ÇæâEÈ'4¹#˜pÍTáÿ€8$Z=h§{pk+x@JIÈrQ×çcŸÔ‚1gæ“÷†£ö¾P"TIÛm¢‡§Üc]byòõ×GÄ€Zö›]zSr–ÍšÛž/½ð·7¯ý%Û; îŒ/O"±"M´™Ã£ÇÞ-õ JgâÈ›?Z¾}DÜðƒìXLOPó§OéI‹Éç7[X¿šŽ˜¼øøðÁkRš Mr/Ø|Ð.HLM-®æ3ýƒ=ñ¾iðÇ‹ÿ£ºÜbÚH¯8>ßÜgÌx|/˜q0ØØÆ 6·€`ÀHb&ırÁ)a¥Ò6‹7]mÔD4ÝM¶Û4iUe¥íEÝTÊJÛKÚUµ<¤}ØVÊö¡/•¢îCÔH+E[©t_VÐ~ß IS1àcàœ3¿ÿï|ã¯PÜúIï\«;õîtY³ág$ÌòøÜh`¼r'ˆaäª;‡}¦NØëÎG¾#Ê\e¼‹ÀëË™“½-¾¹VƇÑNjË|VëÕù®H&œŸ9V9IÔZ| ¼`bÏ8i{&Ó>wÎ.|‰Bc-"–{ƒ.”Xvîn„ÇŠ#÷q\m™ ‡£þZ²¦ÖˆZc¡D‹3Ê >Sº£ z|ñÁ èßB}Z±|±¶ƒúnÙy\†ã¡ÓMÀS#ëá¯^Lyë `ûâ <²OõI±<•‘èo¸ä„Œx{Úù¸èd u™qî1Î c„¢tÈX²`ÏHu¾ó¢+-ßÊ I³LùYF9Nòtì^pË}EQÈà‹7½´6,p€"©¦„Wd.‹…þöáÎ&§ä!/ (W>“ýZ„€)bkïqr5›ºv‚7“,É‹}“3‡)+Xiþ]§§ED§¡š‚Mî¼—Ûß{h ´ª~çÏAq)r¬É àÇpÂ%°fCÚ©·þ}þ¥®ÁŽ{×sQÓ¸§ þ•¤›7;(Šæ6˜ï-©Ö„õa·ÔHÂì¯ï{ÔÎðOs] °¤&hÈ\ ¢ÁŽö°Óeóû1Á‹&À‰uÀ ÂØIš'‹ ¡h¶¡`‘œ‰F¸dnp÷œ Ë ¶œŸBR¡n÷C[ƒ`x¼³§rÖ½F£?[÷Œ¸@–œ…‹Üñì=ÆS®[2‚]B DOè¹½¡žv;%Â4ƒ°c¿˜è<¨Œ’‡®ákn;zD›r§¦‡ÇH†T&¼àDeùn×1ò^f|*Þz |øËë#"ãM˜š².{&•xWÙ':©>ºÝ5´ñÇÝ3‘V“‰„1‚S +ع·©(fÂ’ØU5k 4Õ…G†{B`s65›ú(Ex§W¶Há¶Öäõ*r´ni¡%³Œj(¡J¥XSQx5 køë­€G ­ í1|.vR°XÛÛ X4£bÏÒ•­ŒHŠ †€ù¬b´^08Å2D ”Z‡ª\ÆBÈžÒ &àßšŠÏLõî_˳_w™hGrJ±Že8yR¡EsAòn_Nî›™Ü-e„ÀQlcýç2¾µIÿîõ©o¯=)´]úà'“ÀWÂŒAú(pI:D%°ø¹úWeB©(U_íoÕϪÿª0ÑÀæÈF>!MqŸhš6ç)¾:_ŅЭНŒŽæªÕJm½Öà‰:ZUk­ÁàEµæPÑYÔ£r¥Z;eêÁmšX©_mp/æõtuÕ{µ¤ÖsP+h‡‰£g/hµõz÷`‡ù`Gg²pHÍM,W„¼/FçÏWW/uo³¿æ9ÁS¢ÍI²± ‡c#/Äù‡óŸÿ|þ?ó”8æçóçO—Z‹Í¿‡MôÃï%˜¦ÿPÛ˜óE¬n©ûëÉ:Yo,½“ßÊ’ÿ4ÿÏ<…åAþËÆR‰Am}êî6LHËvÙ°¨½Ç©lmw6÷¬³ÊF›õ3´Þd ‹B?¶wRðZÖ_-;r òJ<Ú°<3ï·Í-¨|µRYÏ:r¹Ñ+TÜ5ÃK†n|…µ<`\a÷³zÒ°ò(—Ë:÷à—=Ýkí uÕ‚¹«“ÓŽ ÈHGõa5…#fE€ö§BÚeê\ÏÞ'ä¨ æJ2|{Ððv&ÄÀ[ùmmìÇà4`í<ô«T¨‡RêG™±fÁ"Ó€˜æŠÑÀ%ÑâäìHë‘?¸<žéwKØ2ŠüÉwq@¹#V‡èÜÝÉà0Y‚ à̱ŒÏÊúKžA2ËÑ8MJ1ð³þ(P–c&§U`Æ$ I³ß=@ JÃ7ßl9Ó–qš’“Ì /ŠÅMosÛí‰o¹Ý®é››)Ö/²"#ÂM€ðÊÀáû çj7“4·2‰V³ > FàÇÒØe5Gêqk]zäÆâZZKñÙÞÙÞz?ï%ã‘Î6¯ËO V‰àívÞך.bþb+_¤ÛŠ­t‘íl´–°Æ 8ŒYøÊ¢©ÊÀ<…€-?'¬ÅpíþÄ ¹ivû)$ʳ¤L[aàA¤:uÇ‚M•m°’l•%ÇsÖ vËÙ6u˜.‰Àgß‹5sHh¹)$ SøìèR{}*%’¬à™ž±ŸtI”»‰å¹ì>vúÍ LÛwÇßrEm³’ÀÛH þ7‹` }—¸ˆ}üRÍG”iåîÔ‡Sš¢<þÄèìÊ¥×/sëg±î´ª¾Êà7Ìuñ‘”ßhgðú}Ú6x\;¥xC{[»±pôlýÆú†o¿Á·3Né>nUs>¦|ô_½ýþí­ÛDw"RG‰‰ìì¡­L-ú k§V.«Ë¯_¾zÜlx\¯¸9é!óoc„¢OÔ°®^P³t†ù óGFÚ…´ÝPx€ãµ7Zzj#Ó{IÄ ˜á"4‰qè¾Æ/ ¢=.±grÿ%»ÚcÛºÊø=çÜ÷þö¹¶ãı“8¶óò£IìÄÄ^ópžNœÄnÎ}$¡]”lY¡…º?ªe°n¬l´Ò4©ÄhcU‡@-`Hc$@LhRaRTQ‘@M9ç:iADÎçë«{è~¿g"^Ë4ŸñT»ä…æµZë#2Õ-i¿€Hóë<†ëÏDÂ}DTN\œ›yùP>Öü©žç‹E¤†<†ˆG‹ƒ×*ÐÆ5ÈqÀní?Í(øD¶±Í‘ŸZ ´oȨX*ƒÅM‰¸&ù^Îc0uA©žñàÆ…Ò•ë‡6§ lãbW N’ÝV‹àÑd÷¨ÏWã-Ù\ã3«+•Ã*—&ØI(¡´Dª&ï&^ Ħ½*/ËÞûèªh'’$Ê6A«P€î¨'“VÀ΢mæ 笿Nýk ±F½u {OPøï&qŸ¸én ÷ä`×ÿA‡#¼6{Mª¬ÄKš1|$¿šÍ¶Y­ޱÈnˆˆ ÅÑËžµÉbp̨~î½ï»¬¢ iXuX ¬ v 'жØBøÜ¯{'“)[vèu÷×;Ü6Qu ²"’,<ùà.ú-2AعÜüUéªí é +ȼ/èí l¸óüyùŸò=ÛZÅžªøXØ&;T˪µÙ× ›—sè$z=ƒ^G¿B<}»MXôͨï@Ži'y¸Vw˜ìÙìYÚjÑå, ÏÝhOˆÖFVCuÆ/90}ÐT ´”˶~ðük¿¯vMG†¶O¾¿7'±š_qZ6—¦?ahðOƒ_Í?;wáÓ—¿{ih{¥%Ö¾×yÅ|±êòc¯Ü¸V^HðàþžÈúÐ+L‘yXr½ÚòÇèjX;Yì‡×óÚº%_)V&,Ú%ƒ"³tÌÐQ cšŽ):&ñMhÉ5¹Ð ,V;”ËÙãìp"鉭έ»Œ5lw2å‘ÎlIš&Yz’Ã[ A”-kŒê¹z)QJ®—ÖÊRIŒ•’eѺì[†ËË+&[žÒïÝ'ÏÈøî513(P3¸sÇä ÉŸÉGŽ@èA¤~k·ŽøÈÿ¿vïDMʘQÔ¼“®Å +Èc) LÉÎÄïsd_÷i±ƒ4u„ˆ~S¸š‚˜'(/ü!+ {ÝÏNs™û\¢¦An5]œŽñ:#j+ƒ¥¡C =$éŸ[>=Ã+Ý®n§-qéÚüœè0i‚Dä9V“%_´^ö”ëZÀïOxÇt𠛯-î]ö²¢À¶úüx¡=9¬°¬x§À‹àn"âîÅ£xÖùº¸­®—Z›ó#½…'^úò Œ:ß èÂØ ¾E Ød•åx•UìŠj€üqþRå#¸Uµu8I G¿¶1 }ïGaÑÌb«è&Ïœ`nåâ¯&ÁÏN€SîžH´¹×CÍÈC4¨4VšËÕበeX@|³E?Ý „ˆ±(…‡‘Q1Ò°¥r? ¸€€äNrVUc¥H¡¬†¶"eL/3T¦ªWauY½’ÍÌdNd®gØ åÙI³‚ ª§÷vÌ(¹Ÿö3ùÙ1“6òûtý  ¨*#j#q|$<Ê’µäOt/ÔgrÕôrÞ<&÷‚èLôÅIè¥^O †…0݉6¡ ±e¢{9¬É€ajpuìø"– «w)@Ðb;·O<;•>ïYêÍ.¦îÔ½?<§¦}©P‡·ãexÇsàrúüÓ#K½Þ¦¦®ŽæÌë쪮ˆš"»IüWÈ@Éí«Ÿ½Ü<*ªE«{ã;§&_údÐS¯zñýyòo„Œ€gìï_ÃZ‡÷bå¹7©ã¶2"¼žaƘ÷sîF&×5’[ÁÊH%×þqø-¿±Hâ©=çñ 99;13#}ƒ(o$™¦å-#Œ5ßM gÀ_ÞvY­–¼‹î¯?n±ðùÌ–ñr4˜ Î/¿ä6ÈÛõà­à{AN²}Áà›A6©Aðù­Û<ੌ›¶I£éœ5öצ~ç z&“5§¤ëÞ­…Jê±µU?,¦8bÖ4¾};¤;$éZƒ~ÁÌiNLØ(·i™0M/¤9z"’-îNƒE›^]¥…¢K]-ñBúPgÔc6d!ÒíÇ þø­±´M8…úNi¬ûâýŠ®j2g ÈÅ—Š\VE÷»”±Ñ:%è‹F'[@ðu'&öîºÝU´aÅ.óœ.ŠtG‹îÂ=t„™ïævšpÔ»Y‡ôtÈ2šRM馞s0i‡COê)NJ&¼=éžÌW¸†dS&†{SÓýHñç.ñ/D/¥?HsŽtÜoDÖ`RÝ©žÜ¤w$Ç%SDxË´6ClÇ x³ŸÁßrþ‰x¿…çü·“û þ­óÏøcç?0wÃùcüS'jÇíÿ¡ºìc›¸ï0~¿ûݫϱ}>ûìËårvürqbûüÛۉń„€H¨=œ0‚G)‘©£.b,ÑÆÆ¤I#Ú {é$˜ÚU­6‰Lt]¦Á«´þ1 Eš´n ­Q§¢¡I…Ic-d¿³“À|~;}gß=ßÏó<â€Ñ)”„". þ"ª¨‹G„ï{R8'ÞaÿîQ Ú‘Ê¡ȇ…ðPhÈKTbX»Ž­`Äú§ØP¢ê¥ÛªCÜòlä-Ä ‹º Ç´‚6®½¢KÚ²v]»«w4 imÀ¶ žÞ¼f¿ùJ¤Ñz¡Wž`u ôÇ0 byì ¶ŒŽA–°{4Ž9ŽÁhmƒØoÀql1¥ÚhÌM5¦=h<™{ÒXè×îFA„OV›ƒÔ×hI±ÚØ0t‡Ô9×h4ªÆ­•ÔÀÈJ`üÅ‚i`÷îyQpˆ¢pÙíµ,Ú~_æ“ñ¨6°ÖÇAU@âSŸ³ £‘DqGškÃhZùK j-¼ìЖl›´`¥ÓB[Ø4ïërŽ|¥+)½ïÔKB{¸[ùbqz9A‰°7 ¬5VÚ«wù}Ǿ–«”n¼%V{ú-YŽem “¦iGH²ñæÃº'"r Æ^èîü| #ÚÞîzÓJ3 né(—º•„·ËgW”ž¹‘W_3‘VB¢ø‘ †Vû7?Ã_†ÿÅ2Ø÷ 혣½à$5Ø'Ä7,&ådEª$–¸5ðŒ ÅFyœÍ„vŽ"XY1,ÙõtÇ»†¨B~mÿÐ&y2†¨ò«ôâè"vˆx„à°±±ñ¬" ÚÕŒhÛÆÆ@39ðÛP@ H¢‘·ÔÅ™Df+ߢö†œjÇ¿Q>6²j|¼F×#;f` p‘ez˜¢½<ãî³ÇpÀÙ]r»Jµ¹­„ïâþê«„º¿Â?Kœ˜mWú”,iGiWvºT™ÁÓ¯žËHœÉM²‚`ÎäçV€‚¸Ì2:s=›ÿ"F`;Žý½°pFxÝdêèHgŽ’)œR+³=–…}\ê¥ñì‰ì+Ù¥,‘Íæ{¨<—O¸Toúh‚bÇâ6Z!'ˆÉqƒÃNŒµ±8;9ªûò¾C>è[tíZL šÐÉíAp³ÙгËðfÇsE¦Ð†16g&+‹wFÁ¨qÒ«-.}æ‘QFŒF‚ònëf‘i]­Ë°l ”èò; ‚ÎxUÀ‘žÜB³1©Œê Ö¬%IW"ƒLµ$|1™iÕ´è€j¦é&ÙSÏ ßœ£AˆÜpÖb,²«dR8Å*ÜÝ[¤HzÝ?ÎUpˆ. ìÌq3„)×Ù‹ÝÀìzñ+{œïpÒ8 !`-BÁFB#p¼x2ùƒÓµÝáˆ=ÁyäÇšÔ~ˆ ˆV‚„„ÃdI9qþ£}}´ä†¸¤­8éÖñ×MαÌpB+ ¿ôœÔÇå6ž‚œ š(š•ÍO6?¿…»°`¨í éÅ·ó«ÎµÜZ~­°:ÈZ­CÖ¢_$Öׇ֋ë{‰+ÖõÜz~½@¬n^.¼!åöx¬þ-ѬÔ.}NúºôžôOéS‰–¤’ïªN?tê}BŸ×—õUýcý±Î\G3úx©JzãjD¶Ržh«sm!4ª˜Å´V;`ŒéCÅ\n^â’ÄïI¥.È’C–¥Ëd´ÁôrÔm¼”ŸìET5 3jk´›úØæ¤±ìmb…ü$’Qb[GV$#h|ÞÔàŽ€X×ÝÜ%ERÜ̶Q"ëñæ}‡0›4ÛpÆw,‰›ì|A£q¢ûجӄ˜©õ|3Q`ÈÃf¦ HÁd– ¤YŠæ%SÆ{m2éþéãÁn·ÛÜfØ9Žw;-${þ½§Ÿ&„.©xľô žÍf«`häáæCòw0…· Õ¯V:j÷=„Ú¥úÔ€T5Rõ¨ÞŽÛÂãW¦”©ÎÊêæwoʵÏêæ· ×Ò•²Ç!ŽG‡GCq–(9DYéôÄÓÙ£S§Íљکr%:>Å–÷•Kár brÈ IÕ¸ 'd“Y<»gü(16lO§Òo¤ßMåt1’ŒOÔ>¨}R£ˆøÙ8ÞÜsej†‰ú1“Å!ÖNÏ2æzqb82U‡oãÃWÇÌëž±wÆð±»ïDAt\-DŽû¯ùñ[þ?úÿæ‡V?˜öÿ]²¨×êp¾þ£úûux½¾R¿W‡KuP× û|4‡žøxzZ‰p[RÍø¿ Ÿ©kc#ßTXÓ Ztâ“[J -—/¤³Žt:ÛY©Ì§ãè]\”åùÚiGMVj§eE• S3Ž©©CŒ!Ai|¦Åç%Ù‹¿MÕð|CœÈÌ‘µ$w”‡±åþé̺R-ûÉD6´þ_|mFÕd½l}¿%[ˆ6ýÓ P“ n…Îne¾Ü×½lksã„ÕæIȰ'c~=‹ttÚõ€)‡—,qÈu&læ³-Æ*¤î¤†cשè$z©hz¾k™Ï*†5×(ÝOtÆþŒ®L„ ¿RE÷㘠aôjãX´q޶¨.þTdŸ“nç–:.a–ðñs²Ù/eûç¾Dq »IøÞËŠV2Ùí͛Ӓ·³'XÙ·ÉcÉɼ{$ànb]ʹ‚ mK‰ñÖIvÚlX‹îàÉ€Có9D‘2K¾d®{›‡d‡èk¿#1³Žæ:û JçâÝœ eE›%^TmXiÂÛoy¬øKUdF/") çÙüL×ïδ:Ñî'͇Å,Ê'¸¬JIJÍ8ÚT‡–“gY†g¬NÃÒÄnÁãÃeý+: àÓR…ÝC¤ ©¼ã¾ †/KãÒ^Úê’JÖ=hö$^RiOÙS®›(—OxT§§<æQ‹==óc~çØ˜ß¡züáöbyÂ2”kH û«B•ë£O]¢†È©ÒÖ­måd9E•¹2›bYv«-ë'~£ñ¶\{Ñ’-{bÍjflËÍ µglÂÌصì'·€6 Òh¼*õ,Æ<^I\#‰ _•­ ëéZÐ)|5%W‰x•tk”[ mðmÉ»4=wUk¤$«Ìš"iª&4õ4ÌåÿKΘVb|©¹,cP›fPpž®1mã:)ª ÒÞBö2ÇÒ”Äi.Q¢X¶¥PÜÀnA-îòeB4¡âP.²;륈ÝU_'1J¶÷ûsë2OS–ik ¨é¸³¹èS~Ìsw:ïÓÜ"Rv’%,Çš“¨h†2ñnùÀ¥sÂÝ?ù$+¯É–³ñ g§Šg‰Gd cánÝ™_,[þ¸?¯Ze3v×åÓÞ´æxk+ùÖß´ÙÍ´EÓ9µ8ú0ý á/¥Î¦ŽD‘bÖöP(Nw¤‹l¢ƒ€/9‘g>ŠÍ¥ê6ÇcrÅE’¡<ÉG³Éd4„»@êKJ†7Ûþ즪Z´š)粚nðÌälIs³Y>‘ô¹½ º"¦V³M¡yéî’/yÃqÜ{ãtîõÜ­}&‡©à"…}9r?GréçŽaJ vÄ£X´k«´–Á|x¸(‘ºô_~\QŒ”©(…ÏÈÏn$ÇÅS÷Œ\€ 1X7IãÁç nq©†UHéLc¼4³ÂS Lãú\7•£6e_jÞÔäßD,®”dSE/Cx!C¥r©îò›ÎH´çzÉáî·YJ¼ÉdÅâ^ž\þyƒj{ï»Ô"¥EúQšç_Ë…‰ÓRÚêÛ͆{Ðb”ʉò)·Hv×Ç»bŠ„†¥à·?øíA¬â%rÝ$P ÁqŸ—ë6MѧÒ_K»!ý°µ…«aÁäþת‚½LQ¯Ò?bBàV˜-ùƒ–  §-i>f¯©7T*Ȉ°îQâøÈ¹@:K¼÷PÁ ŒÄHêvd•ØG?A“JL# ž)Y­s-ZI£4-Ó¦î1ª­%½…îÅÇ—Œ"D†¯Š®bÔ'U·êÄ¢ÑXƒÑc#OŸî"äš`vQ|}—;²#«ú÷‡/¼Gír*šéÙ.Aé,÷ì<Ûw™ ™„FgvÇ"©dwDóDâícW½üB«~‡mÓ®¶€¤SƒÙÝWÞ˜Ó×a3õúU&^(Àþ’õ¦|3E€[HÓ£¤è£æCÜ#‰ ϵ`”wd¤‹Üï>ú±ÀÎÙõ¸Ekc$( ²éhÒFè‹ÈKò’ÞB7ŽVÖ^#Ç £E†!Ö£áIí–"Ÿë]¿ÃêÛP_ŸpzG»v^˜ìŒÈ‚DŽX£¬tÔ³N÷hiøâ3•-ApSd›¿µ5™óÇ<áda×Õ™£ ¹¨Ížøp:ÝQÕ€µ·øs»®­¼]jQB.X=v? ‚=ägHþ`ú=û&€å ˆwøˆ›W° ö#pŒ¸`û+€ü>€½À1à hx¼Þ>œß?hrˆ—ø¡=áé¢Çެ;‹Äÿм õ7€¶×²8çú*À†e€Žz€n€=Ø·ïkóÀ¼‡ÞúÆúqŽvÆ1´.€±Æ0ñu€Êm^³çÚ‡÷8U_Ãþ†((›¨"Êf²'@Ùl@öw_G7/m÷Ä¢ÄÜü¼]§üœbÅ|Ü|!àÆàÅ  d'2q.C>CC CC*C:C)CX¿Z]' +‡™¤«‡Ó4†À°¹ÈÀ }+`ÎgúIó, Œ€2,@ˆ£Ò˜„€Úá=zì€Á˜ ¦qe8Ãþƒù'4–˜$gNÝ 5'žßæ+ƒ4XõZ¾uÁt¹SÅ¿ËÙ8#ØýP¼MF˜> endstream endobj 1696 0 obj << /Type /FontDescriptor /Ascent 891 /CapHeight 0 /Descent -216 /Flags 34 /FontBBox [ -568 -307 2000 1007 ] /FontName /LGMALP+TimesNewRomanPSMT /ItalicAngle 0 /StemV 0 /FontFile2 1697 0 R >> endobj 1697 0 obj << /Filter /FlateDecode /Length 8290 /Length1 22292 >> stream H‰\U tWþö9ÿ/I½åQ¯Ü¸òÀ ž¡¤’!ÞÏD«rƒ$H¸UŒ×¯Zê±Zc4TGot(j¦aÊ ª¡ÞF…Uê1Cªe–¸g¾d¦³Ú¹ßúïÚçœ}ÎþÎ>û| æCcÐÀ¡‰ís22ãËÙ;`l¡Ï_o´½ʶ¤Ž9Ãõ£çÊŽ]œÇrýy…þ°)W¨ñ;ÀÑ.¯`vîÎŒ&ã€.]èŸ?Þ7®üÕ¦E\þè”ÏŽú?ÔÔ¾Äv‹ü³J{…Ÿ`»h_0e¬Î…‘@×l¶=…¾YþZRw7çÐß5ÙW8>úPæ`ØC®?×?eú òæoØéªqÿ´ñþ›]Ö’KË@öJÀî‡(~MôZ4Ì ~7ùÝ ö5•ö$¸ƒÍuÝ€³ÿ߈Á:¼x(ípeè‹ñ a-z£Ÿ 6fËIXp#;#QPHC„ØØˆËx Óp × \“ú\Ç ?ÂÑÕÜå–šô A vã ÈP$ÒNWiÍÈ«L"oN™KlmÆ-iaJ‘Në{ÔCæá]ÔÇDœ0•UDJd®ÜE4²Qlu°–™I膽8/´úc¶}©æ^pÖ6‰2SanãO–`}Ù‚eYÆnO¤ÛÅv‰ã¤3Þ™îÌ©ñUåýç­žg=¿D°QðÕàºàáàm3ÂÌ&ÿ$  ™.!ˬÁíÄG¬Ä}8†¯p±šë#Qb³â#ÅÍjððÔzJoéCô—ÁÄpb¤Œ"|’#ùÄ<™/ïH‘,”ò^56poÛe§ì#>“ƒÄy©ïåžUÔÝ@ÇèíÓSõF½[Ñçô¿,ey¬D«»5ÂÊ³Š¬rëŒuÉzfGÙ^;ßÞbq4vtp wLtlp|â¸ã¨t:œƒœ9ιÎsNS#†jõî{/~ùKt”Ët»¡5KUð^Dj¿½D†3c5Lè•ú;Wj—\‘ez‚žd¶é4õTO‘ê i®£ì$‹å0²KÝPÕm+L†©»o½+Ÿ©):E9ª‚Øg­0«È¾¨‹HRoI™:ª‹t‘ù#’ì-RaoQgಮ«¨à­^¢ÖsÒ×j‚*F¦ÕÁ~† ÌûN{óÝC-•Vúœµ·´[ý(eUã”ôµZ¨×UWÙEÅ}.Íp_¦Â/ï!Y>—oe?Dvèé§^àiT-éÌG蔎–s:YU%V…É õP ׇ§uGªÄ7˜#ZÚ²v~þ1™7`­Š£¦y©&g¥="±žzÿ8x¨J±íKv1ël«ö`Úb´:‰$Þ[D&£=²—¢­Ú€¹f¾Œ£î÷§~*ì—‰H”Pªe¹Íã{®šS Ç0êSêÿ ª~†<À›ââÍ*C¼U5²ÜòR™²©¿ÅÄ8ŒfkÖ8öÚg1P"ËÜÂ*¿Š×ùæ|ÇøÐüFa«å!k•y*gl ¦#™XŒ“¢ð9÷à=d¥Sy×™‰Üá¾Qýø&dz)<»!¦ÈcŒÙj^C†šÔß™f:a‰¥FØ­­ÔØãò%ߣ¿I1u;W¨G1‰{ßiô°?Ç2ë"µ³§YnÎ#ŒùhÎ åð½‰B<`ÞÒu^ P¥&MûùBU`°)1Q‚|S@å=„íN›Ú3Íìí¬]$÷>,¹g—»wKêÚ¥s§Ž^jß®mb›OëV-ããbcZ¸›G»¢š5mҸы‘á Ô¯W·NíZ/„†Ô¬átØ–V×–í Äf¬XwzzBUÛíc‡ïÙ»Ò~ípeW»¹~í™LÏÜÿóLþgòÿ<¥®«;º'x\^·+p*ÕíÚ/£gÒ^‘êÎrîWÛý«íÕÕv-ÚÑÑœàòF槺’íòÒfæ/óf§r¹ÒÐwÊøJCBi†Ò D¸ý¥ÑCª áM*U¨Q‹¤Ü©ÞÀ‹îÔ*ãõ œéMm•à HÊXwNî^:­«]R&ðoÖ«6ªãÏÛ÷î'ÄÆçþ|†Üñ8#ûlÌOù9Sœ+ö] ¦IŒ¹sæ &Ü&TüD´Q0ŠøÉÚ’¶A!ÔF·áÙ$­M%dTE(­hZU%¡mJB[Ú"­ ’_¿Ùwï8_h¡U-7»3;»³³3;ûÜõ¦G.XÇ»¡=¾ª!cï€V¥Ây]zWgGÂT;“¼Faë6˜¾ùÑÄ;]L^TŸØ•-õ«Flâºw cWÀ<ҜȖù7™Ä¦ÅSF ï… ›ZXKìH&Le ð>xOöîÖè1æ¤ÖÌôÅúZc} Sj˜´|k°¿´4:h}@¥±€ÑšÐƒæÃ~=ÙÙPÖWBÆò­''E“FKª«ú|…¶[ûƤyùÙ5™lÉáÜjZžñ«ÂéKf`u–$tìiÿ¬Y@Æê†¿¤-³ ç±Î| >eøjÁ÷±¾é ùô€q“pþú'æt¦9îï&q“£$h;m36++9@<õ8QØX'ûs««¶ Sßà €À}ô8|Û™¬­óƒA>Þ=QZ…ŽÙÓœ°ûZåï§hM8iŠK†ɸ,éq$õ”Ž8~ƒøûbœé-ÏüøÆÇÖÖšÊøÿ ^cË›Zô¦æöD f¤Ò¾mjÕ³å 2²tK±p¸©…à©%:Boy{‚øw…âzl]ª©Íâú„êI»%üªœ ñÛ‘™™;‰<žK ¹eüw x¼`ÉQqÓ—j´“c‚ÁûT°>e-I÷dÖ†G÷Žê2/ÏPa°V.šZÛ cÌ(Y—•aÄõ@ÜHVÏ*=àÓA5¡&Œ ±”süÖ©=~3¾7‰M¬UjÚ‚÷éÊîæ¾¨²»¥=1èÃ'ÖîÖD¿PD}jq²od‰ÁîgÉÌe&wÜA}CVô ¯ïŒõH©&²¿z@!Éó:<…V›çsx<ÍæE%ÿø¦¨oMdÇ€L¬dµ|à 58£•>úlÓH¹Or²ÿ܆;¢”qK8À [m ¾¯¹S£;‚]|ƒš!kf€¿_{Bÿ4ú- ûE„Tð—ŸU@ V `ðÐŒ±&ðmžÃº:<_¥N×Yò¹Úh*°m]û*µD»‘ûXoŽ:™*Ñž Y…g2Æžµ.³ã¦ÊqmÐÛH=סÿ PäÙG~РüRÌsŒmmRÏð^­khoKÐþ 4[@—ÿÚ‹€|è|QD¬Õh¢½¾)D;ˆAïë`|>l삼}Ác±n>¨ŸÇbÎ õ‚âWâMuú´V*|¬öÍ{vöÄö³Mÿq¶/¶}l«¸cÛç r°F#Ïj{z¯‡Ä9Ú ±®£­»K(Æð\ )ØßÇ@Dë¢IžÉÖ_aã×4}/0Q‚ç:þ?.1˜ÌxÝ—Ÿßç1˜w<ÆOÏsÌplr|plÈøG<ɘåsÜßpŒÙ9ó#ñíJ€*|”ìL£ce¾ð9²Íœ <7ÇÇŒC!/·ã^¹Æûä˜Ê¢º«J®-sc+‹Vpì3U£rbˆæqÌÚ¾v¨´!ÆùÈ9áPÇÎO™# j7³ïøÜêø"CP²e®wém­TßBüw ý8è|øç°ÌÁkÚè#±ƒ„gˆªp–œ»¯äÐ ϰ²ó Á—åÚ9zEÒa1UV\®^늫WÄÍ à-Šï×(Í׆èamœÌ»ø+0wÖM ¡§âKíEuu÷ÒÔaœ#ÖçéϺ!G¹1÷ùX’ԉ׻PÎ|‡ÊœŠXy±þ(s2bØ”"\ø~–õäÝ\èÄk&._¥rõfV|æÄiV|.„ž/7.³èX¦éÚ’ïä)tÆs­áýËû±M擼ç ëwÆçÒŒþqÇ­÷å=|ŽÚ¼f!È‘¾Gpã¼¹fî³:ÜÏZêR«ûü©{èu뤘nõejjˆf§ï²R§–²Ÿ\ç¨,SGCôXú> q=ÕŽ¡†Ûu´XÖÏ¿ÐD×uy·Í–örrÖàÞ›Ž:þë¶VDO«/©ÈKæ#FšY¦yiœú'ܹKi“zØúº_ÞA1u„’j9 ]øl¢KP™«š Cr>Ê<¶ß­!>ù.hDgåÜË|öîÛ”Lw]Å}Ô†1Çå^Cò?@ÓØRw3ê æò„©HN I¯ã½ ý;0ËéÚ\Çsº—˘-:s¬ÛÞ"Š0\¯Ñ<¬’k5R­7Bå®6ëª|WÑ£êYš©6ÒCh—ʸ߅UzÙˆú¨#ˆMŸÝ—µZRë–¬÷Ûd=ÏsÕÐJùž`™›¦¸+hCÓ!KQµúæyquí×-K¾~O…¼6øñôû„ß BæËo¡÷6Usޱ ²Þ°=oïÐC\=GáÃ1œƒŠ—¥ë`úô;YønšWfS%(Þ¥6)k¥ÄiqBœ¶ºù¨¾GOª?Äù  ÚŽúýjãBÔð¥ðÕo(¡þí©à¶àí·‰ ´êR/aÜlÈ6@ïæ8 9c't.‚¾N‹Ô_Ò:uïƒKüF  ¶ô  ê•S·¸EÝîy¨É ­WåüŒMÖW$Ž¢n^Jë¦!mup7›·âmw{¥­Ùv²w±çày¥ÆhYMGšÅ>ꎈ÷0öË´U9fRQ\¹ Jã'Ô(iÐŒ›«<ÌÐæÒÏ€íhWžNØ}:¼ìÀÜg@Oºñ©À‹Ï à¿rdÙàµîÆÏ†ËoÕµPn`7FËäšÛiÖ›§-²N1Ô+¨!€{•x¶P‰:ü)ÐËé»ü¸çÞ¤i÷²ç^PÞ¡™Ò‡6¢÷³Çûç.×çÿ×|÷ œï6à iÃUÜÇ2†h¬rÞºÚ¦œGÝÞŒ»@¿ýbÇŸÎ9ÿ=ÉÏ9?Ä ©dý3—ŸÛÏ=×{õÅIz2Ndâá%ªchc<Û÷¾MuŒq_­±QWxæÎõÝ]–ë]C„›õb/±YJL`[ß%&ÄÅNC¸R–òÙÚ¨ªC[ZH“Ú 4H°CpÕv½ÜÅdy´XªH”(WªÚªRÁ´TýQUuPÑÚ¸ßÌÞkÌ:Èqšþ©Vßùæœ3¯;3çŒv¾‹ãuõõ P‡刘ö`þx]«!ùJæš)ÚàÌ£úeÜ«€¨+Û눗€<»€r ±õ/ÆŒY×ĺ²#I¿ý}ìï’ú}0?C½Ô!Ÿ½DJÀƒ#6îo뾸kÏ?–Ü¸Kþ’RçΙ¸s6pVîÕçÿpvÞÞÞú_E ö*àdŽºŒ¬Ð#÷\Mð\~¡ ðtÄœ¼¡”ƒòz å7a; ÞÆU3töÄ>¦f"'d€>n7$ÛßžNö1|ŽÿÞ®dû¡ç€‡áCf6t xø9PŽ6v??†¾ü+è+“} ¡<| øPJòг€ð»0ÆïD>ò ïÐÏ•ïõþø´l½3Â6{CL†—}*¾ëÍaÿ‰Ø~K|Ëu°æ¯™Ï½Þ8w1ök,KûEN)òh‘˦!ùã(‹wÛ#’§[ýØì1PäÎ"M[„œ9ùÎ+ó\aDZw+ý˜¼@–Å[QçÞ:—›<¸Soàÿ±MÄ5ó½,ý¿¹ ê€ß‡ž ¾aÇ4ûnwÇNÓ>o}²1ò3ÄÔ…h îe·±ÄB…@j,ž,&ŠÝŸ9–ß#FÓÿ­nÇyå¥ãò€ ô‰ú›¬žšwLZOÉKl=ãü©{ÏÎg2Iæ(RÎÝd!ÞjïÜßžCê9=oö¡1u p fÇq_”Ù€x¶gœC$äì&!è½ÀiØþÞ(|à6ú<.·›#ÃпÝ«¾/뮵°q¢ýœºoE~.óC¬™¼[ÅüI1° ð'íö·oOŒýWå·}øUè‚Û,ý(XøXö— Ï¶øìYà¡ þ‰¥ÛZ´Ûeq;ÛiÎáÞÈøs€€¡t¥ƒXºƒÐ$eßeÛäH'Á!ðö$c¹šÌ\¿üFMñûf…Ú±¤MXú&¬\V®‰¨p5Úu“u°FÔiDFÔiĪ”°o§H ½@À°î;±îƒìú¥ý{­@»ÐØÓXÇBÌj?Ûbpl²ÍñPÙ9ö–Ú`OÅge‡Zîh®)b#‚Ó-öˆº›¤wSÜ5UX7Å3³“ŒZ[#élù6 àjÜ@ò€/å€Ê6˜yÅü,{”lw#7+ͬYmNSKÊ©ï ‘ZdÒœøØF…B ÓÒu®×nóºr\%.ÃUëJ«gͬ…1ΊY«aQ––é3KŒ•ÚÒE­îvwÌÝçîw§Å´>­_е´­D3´ZmÖ íÖZµvÍÕªµ:”uî÷n7óºsÜ%nÃ]ëNãÚÙËÖãoH/д*Ö8 {{ˆâkD±OÂN 4/Ðò8 šõ<¨çÕ«V)<µÀ: Áòj£»¨?(<ž,Öt¬íä (•Ðth:4µú•!ÌÐ ™ÔLÚìHÛWbùךôÊ:¶Ïm•!ãkù}…4VHÛ ik!5Âe‘1ÂçóEýÑ@´ Ú¡Öûëõõj¿&PSPÓ¡–ùËeej±¿8P\PÜ¡r?ðÞ¡¶T÷T_¨¾\­F«ë«›«Y)>]Ü,* IžÜkÎÊ •z"Ë”ü(dp`„Ce@= *=\醵ÖnRD4´è× $·|ÂÞ&}¢$üÊ]~†?Þe.]T©Ä•Ú†¾»àï’µ“¥iAH{U¿]Ú9¤Ý†á‚«“×\Ž_)¢@F.³5ä*€ž!9Ðô*«Ão [£tã×¥t± ¡/œÁÉÌ™„ß4§7âU¦bè®B–r¿”eRæé•úÍJý—•ú÷+õ|”ã ”¹†;¢ŸŠè5½0¢£·ûH.Ñ•RjBÒ¿Iù¨”A##W¿•«”««¿’«ïÈÕ¿˜+ÚÍÆÙÕ• )ÝBÒ¥¬”ržáæú[\_ÃõR®GtzŒbt²\Ê9Rf I?<å)÷×9ú!)GOÔ ò„B$Ñ3Ý6Ã+AÃføè_fø?OoQÒèM3ï:Ì Ó UèYü­ àAðfðOI˜À'ÌðQÿ5´?ý8™ëõ_%µ²]­öW¬v/›Áõõ¨üF=B‚rÔCfð:¬Ìà~Ð fp¨Å ˆ n1ÃóydÝLòQw (b&ÕÖˆ çmà•ÉÆ+Ì hU.HЇLÿBP¾˜åyê'µr8núåŸÌ&~ÙÅlâ—“Î"ÉéÔ#'¯“¹’¦zÑN®ó†Ï‰?NnPyŒÿù<þßj¨¢f'ÿõ±\&¿LÐÀi~ÉŽ_ÌKÐÕ&ï &œp\&ÚËOb‘c¨«ÐÓ¼'¸™wû¥·Ã/>u[x?ê¯ã/ ›|Oð¼˜Ù޼î'‚_âÕáNþp Aá6Â̘—ú¿Î„yI‚VÄ;ù¼„˜J úè<ÍçcÄy~9•¯”žUý†tìr¬w¬v<æXæXäXàÈqd;f;2œ>§×™îœêœât:5§êTœÄ™‘0ŠNa†æ¤©Bª²ìU„„·¾B ÎNl:«Rª_Nc¾*Rµjy¬´¨*áùrlIQUÌYûÕµ')ýÑÐbʾ%«Öbƒ ÓÞ¬˜ï¡µg¥Å{ŸÏúûÕÚÔÅÏwo’&mפþÛu¶’ÜqܵÑê6/æ&½Ñ´¥6eä‰iÔnÓª7·¦0ì*ÂöرAÛƒ7fŠu`¥{“ÂØË½tìa ƒýñaZ²snîZ"Û„{’ß9ç;çwϹù¾ï&_Ⱦqê}McióZÒû‚æ ~ŽÆ]æ;œ`Õx\ˆ/ÛÞúÜu •³µ´(‚t¿íæéLÖü¬]3cäÔÚµ´¹3ÜæŽrc)uš;BFËN³ÜÑÔ ÅÙ U[ ÈAÈdˆV‘h ²ªEëµh¸MÅ”ZÅ:i–½H$Ü>³é@½Ö:lµÈ [ ë¬Z븵DÃýP/æ¿¿X30¿UÌß V±6"U"¤<!Jek •ÈV+ýùb:©ßŽ«O„iVÆ9êÜ6‡ó"Gú/¥˜|2«æoRÅp*N9óÝñƒ‚9±/¬ŒÜ¢DÐä×çö’ÍÍ[á¢jŽ„Õ`%_X"] t>¬V ÊV JQ½Wò©p^ÕªSåžô½Þ^èÕS^¢X™ŠõP¯©ôé4¥§¨Wšz¥©×”2eõJ&Yz [ñBRëÙ]·U®©Ÿ‡Üš–\8²Ýz8¶…„“k®¸¶š$Íl'Í'”êHt$(…O'¥Z0ì·SÂÉm¡5Wاv*€áÖp$R£êÂ[×õÁ0$Ô%C°b%|hC™´¹c×pÖ”M9e*9Uc´†-=Y%0#ß¹1¹,Ÿ–'åó²Û04 /›oˆÜ^qL,‹§ÅIñ¼è¡Äîì%Ežyw+¡¤T«§ß4,: `Qo'RO6!BO» Oæ°FlBdnø õ7ˆ9ἉúâD•"|ß‘FUê¨Iô¥#ð±j´;öìe´ùýu›®ÛTÝʉ˜€öB|ScÂoWP_G|‡ø ñÂÍÇø˜UܨïZM]bxû€ƒ)]*1 FÓ]Ò% ´Áq*±÷=0Ýœ \4H²¢:]f]$âwp€»NËÐ}Ž}É]Åcj7sÜ®ËÜÕ/xhl ç"ƒÕ^{óðìið±WÙË H;ò¼ÜøMî›—!Ž~àªÑPk¨5‚е¹à^¿vOqÃ]º®áLdØ—ÅCq%ȹ'ÚG¶”ÝŒY¬xàl€åØö»É<ì2Û|&\CÃÔk~¡ë6êQ¶GZZÊpîù»Ü“ÒÏÊÙÚl f¡ $¥ O¯ø”ç»}J¼{¯MúÎû8ß©æWNP­£Ç$é6ÄooŒFb«V®ð„ÅõÝ›·0èR‰Ä¬¥;»°eü_â&Þà8pàÀ8pàÀ8pàÀ€$+€'=…ðÀC…¿h}ø›¸ ŠÚƒ–ᡳVÃq:jµÚ\mΞ5þŸJ,ˆöÛ|ÔÌî à«î{Ð‹Ò ¸|‰Â ¶ÏA ¼nû<Æß²}º»K¶ïAÿÇÞ}‰ÞihôPQï/;”?<ézÔ8ôÂNèƒÚ`FáA‡~ÔÇaÆpœ‡Ã˜Í o#E8¼†Ñc|õÿÍÇÙõ¼¿€ ãЀ³€.x À}Ý¿g£E`gÀ ^z4úËÂ~n.Ô‚ü}Iã( Ð¾ðR™¯½-¼n¯,î‡òÙï‹{ýòïÞÕ^‹ýñ\û,Ùéo/n¸[š/ÞÒZ[•ÿÀ­Ï endstream endobj 1698 0 obj << /Type /FontDescriptor /Ascent 861 /CapHeight 0 /Descent -263 /Flags 98 /FontBBox [ -217 -315 1129 993 ] /FontName /LGMDDG+Garamond-Italic /ItalicAngle -15 /StemV 0 /FontFile2 1699 0 R >> endobj 1699 0 obj << /Filter /FlateDecode /Length 28515 /Length1 39628 >> stream H‰|V tTÕÝçÞ÷fò…ðI˜Ð¼ñ%á3HÌ $H,féLBH‰ŒÈJÁoÑòH¨õGЮâ* ¨´¾PÐ( „¢Ö*(Ö¶¬Rl@UÀ…UòzÞ„° ­M†sî9÷Þ}ö9ï­HF+$*gÍÎ/¬Yœ<îãÕ™µÍ‘hKaf°1 _Ô¶¬Ð\YbÇÞ…‹£õÍg'ž*œWV×7­Zœ¾áÛ…@Ö 9®¡.²è€œ%ù¼GxÏõ ¼ÐgBœ H´ýì†æ+­æã-ìw sš–ÕFˆž{hÛÅþ‚æÈʨ³]y÷gs¾vK¤¹®nÃiö;1Ÿ`tÙm+¬óAÇ;]^}ÿãüw€Ì9~³Z¨C )Ÿa˜mçY'¬Ocÿzé;ŽÚ»=€äÓUþûå¿»{Lë>½©Öºÿ±ÿªhb³é‡r ÕP/nÄ|Ô’ð ø»Ž÷]‡â~LG½ahGÌÃÃôžÀ1dcnâ&¡/ ðvã¨õ"û Èeý‹OFìQ y5 ™ðð-”(<¼7#1pʱG•8ø¤¡œ¿bã:ö 0šãÕˆÒi±Üºßú;g¥ðjóXƒ½†C8Ê7Ÿç:â fT¹Ü¹z,åš×`]L‡± ¿ÄìÄ Ø‹7ñüo9Í÷|͸D’Ì9•†Ð(Vh:ͤY´˜ÖÐfÚMgé¼ n EØ"vŠÝâM9Tv(~åy¥ËdµY¯XïZ'¸F[ù ¸Xu{3–QÄœJQƽ+çžWóœÜÌuÿ˜+oàIjÂ-¸•Y®Ä<é÷°kc|Ûð+ò83ÞÃ3xޱ&cö1àUüoà-üâj>Ä)üçð kqS6 cŒ¤®g 5R-'ƒÚi=EÏ’I¯ÐzÞ¦÷èÏŒèô]¤nÑOdˆLF#_Lå¢JÌóD½¸M´põ_ˆsršœ!o—kå¹Uî‘G•te¶U>SêLu‘ºF}H}ÖÑèät}ÿF7ºoè~µû#«Àšo­±~f½h´±RÄÝëÏs—ÍÓ?†gi&£‚§b.B¬‘­P j±˜QÏÏá4óÛàV~"ncµZX«Õ±Î¶ãçŒÍøU [ÛY¥çY›×q''ñ ¾À|É]>‡ï(Ž»œÄ“•Jh ¥ÓPÎMˆa*£”1ÊèFª¤y4Ÿn¢…ŒEŒ(­¢;è®î¥ûh=HÒFêàÙÊØF;éÚGûé ½E‡èëz”>¤ô£o„SÄ‹41X¸Ù"Gä‰ëù9 ‰b1ãV±Z¬ÄFÑÁ*?%öŠãâ3™ ]Ò-‡Éár¤#‹å ²QÞ#[cè’äaù¶<.?—(iÊ@e÷"])Vê•&å'ÊÊ&žPK%5‘¡æ«ej¥ú´úºú‡×1αÎñ cã-Ç)ÇEgª³¿s¤3à|".=NgÕÛYÿk>ôˆøDb¿ºCÞÎÏÑv“™²]ÙÇïJº(R¦Š;à‘¿QÖÒWò²ä|ñ°ðâ¼ÊºxY‘»Õ™ÂdNùâ–ʃÔBß‹XCÃEOü^e P2¾x|Ѹ1£ GäôæyF 647'[¿Î­eýhH¦kpFú ú§¥öKéÛ'9)1!>ÎéP)y~=ÖÌܰ©äêÓ§{m_ðB䪅°©ñRàÚS ÇÒ´k3K8sñd–ôd–\ɤm"&zó4¿®™‡}ºÖEó«‚l·ûôfž‰Ù3b¶’s’Ùq»y‡æOoði&…5¿hi0üaŸ×™˜Pª—Ö%xóЙÈf"[f@vR`Å ðw Ä%3+³\÷ùÍ2ÝgS0eŽ?²È¬¬ ú}.·;äÍ3©´V¯1¡O5ûzb)(]c:JMgìm‰]Ökyû¶®Ô„=I‹ôE‘ASFBöý<æ4ÝgN»ýãto^m4ãK»s‚/¡Üjí,kõùBöm©¥Á®NwIß¾D³]Ãx@3Ÿ¬ ^uÛß¡êÍ«¨º™µîoÓì2ªƒ± øPJÏg’öš]fOÁuºß^ 7jf¼>Uo0ÃܬÁ†‰êUîƒËK^â×q¹_3æu·9Ù¥‡"¾ÌÎþ0ªWý¶¬D+»6âÍëLé×£tgŸ¾—¤ä«º+±˜K·-fÝ+5ÙŒô2S«Õ˜IP7EN‘ýUW£¶ˆÓø"Vt ë6RŠíF¨9)ºf\‚~æôµ+‘Ë+Žœ” °M{\®ŒÇ{mÓã1GŒ°'ÅYÊ­ef“bþXo^‹Y¡GS4³‚%Ce7…ŠóYr·Ûîòú®Ô°c¶V{| 5®(É÷„L¶#û{#æÚ‘ÖÞÈ•íaÇy쟲̸Ü+ÿú¦ Ló7›4ðÿ„ëzâüøøµNEÍ1*ƒ¹c½+7l´…¸5~ # k#lDº¬Ö]KÑΊ #ê÷–Ôe½¼ÞeÚB Ä¢š£{Ô0ÓJƒÒ%B=–pI¶*fëUóƒšß_nÜå•¢˜{Ññ¯ë“—NòoØân_÷´ø8þõóoN«=8ªêŒçœ{ïY¹An  ÉPLyTÝDòJÚJŠFcåঠÓáa!‘VŠmxIŠ ™)#H ÛÊô&Å MÌÎP:J%8(P˜¶c§ºF“ mÇÜþ¾»Ù4ÆÎôñÇogÏ9ßw¾ó½îñ|湸ßè8& ¢´RQ¯^DªŠ¾„õ—<jÃ× ¯¼Ó2Ë)Uåôk¬ÿND+2ƒÖBf©F´AEÑ £"<˜ Œ,`=px ˜…ýË‚ŽËIÈ8ýÑSDeF†³[«¢á:Ñ=Fãô*çïZ-¥éaÚkdÑhYK~Yëøµ(Ý«gfÔ:ïç#½œµÝƒý3 û ì™­…i—¥n£œny2è’wâxŸïÓbT$Ë© {¾#ËIàiäôȰحTìÄ]Ÿ?!‹hµˆö¾ˆ3óá—GDŒ‹pï-‹òq‡8küQ"cRÞk@wr÷ß…îÿ(UÀ¶GpNº ÷·ž*&Fh$G‚Óqÿk|o†{oÜ9y'¶¿Ï¦Ï±¸Áö ì+ˆ¤mƒÁv}UôšÊ¢üq6ä©*ç6öuªZç–*êí22è(ã­ðÓM v_ôd8í®aÚÄ9\rATŸV«8Uè-”eÔÒTø 6ŠœÁk>‚¾õXÏÅ9Å2î|ÂùIJÚräSÜἬ½O÷¨ ªPΟ½DrŽöû çž#* ÿ"~^@‰íÀäk0“õ©ÚÈ~çØ‹*ÇÐËñjŠÓVw.â~¤²z?UEÎeË9JiˆO*r~¯{Ç¢‰üûÜ»'X%Á¾‡ ¹Ààˆ ãí¿•aÊŸÃ.Ñ«“ó7YEÇ8g9o8?9G8?ࣹˆËF¶ï •S6çYÂϨɀ0d€Vz\ `LŽÍ5ÃyËvöéÖ9¿8·“ìæ8jëlßèYÉ÷åü̃e¹>QÏO°®oÿ‘ûlÌ\Û\_If›]þ{ž£O"?â^À½À­Gô®Iu}}Á­M—SÌ8Ûýù\[\ƒYÏB¾,vñä:ù£·p}÷±Hþï]’Ñ{$9qf…> 5Q ÷·žQoÿ-sßâÞÑÿdnô1÷¦d|¸¹žúl-F<³‘_y¼ŽZ0ºà1èê÷BÝÖÇÑ»ÆqzWÔѺdßÅ+ØÐcÎ9·ïâ Ž‡¾–޹9Ä=7æ<Ößs7Ñ·ø,#Hã¹÷jß )î}/P~‡ÞvûíLÔQÍayžW…è?—i¡šO%|®²è<§V:W”Ÿ¾©F%ÖåYÌa* vwß<*S~ç/ê9çuy“6¹ëØ«¶ÑX5‘2åyŒÇ@öTË:5íV Z zÉ«ê?‹exsnMÿ‰j´|çêé-7výµíø=;œÇ<Õ¸ÿ°§µžE-Æhç–ë«&ç×_,»ÉÙº< Îí>ZmP:ÕIú‹ý8ÀW\Cî÷ :õû©}eL$©£Ÿxwy_Æø(5?Ã98KÏ£bo>¥hÎ+nïQ¾™ä|Ô~Œ*ÜÚšàÜ”¹4y󼋹ðß)ç=í–ó^ÿ7 Ìý£¯Ž§¹}ÑCþ6am;bQ…ù… •‰oÖ[Tsêå*Üõ0Î{ßÙÁg¹5Êg/K|ëÜï"s¸/âÌRœó$ê6¸ß¼r¥N£¼F+’9=˜“9n £Ÿ_GÎ.âwúy*jh¥Š:]ܿѣºø…§ÌƒÄdØ2Ê7 5x–ŠÑûŽi@ °Ì˵GT7ˆ_fxbb-ê,ŠØ¿ Ù:÷Û“c´˜Ðõ°ó–[HŽò`ˆhb™1píÿ »ÐKWbü!rÎAíò;gŸì¢í /‰¥ž¸È2“Œu»UÀ$ì«Ä¾çx‹ùñöë‚z€N_¶1ønæ‹’ßNô˜ãø–•#.ÏÒ :˜t͸æ‘ÛŒméOñ‘~_¦/Çð}ÝWê3,•­R…êÛ*¨ ^Šìáw*~ý@&#{Z´ï•޲"JÚ•Ë­ˆh ?]»ÜzÊý¿3‰ñ:ŒW>ª¤¿ÒÒfÞ¨¼’µŸ±üíb/eè¹bþIQR¶ÜÚUñ’m5•iVY鈮caª£SbvÖ¾`<úùÉ£09Á_¿¶È—V’˜HÛ5`ß8ï|×9Ç—\MiÒNÌåT1T{è§!0™md{Îç?ÕÚ|~ÄT3Ï/ΊßÐx(‹ ™¢[Œ§»1–#ÖÝæ¡5™Ö¡5ó2MABOHòÒ¼yx{¥ßå ´Ê«2=à¥žŽ¥î‹¥nˆ¥®ˆ¥’/"¿f‡¶"r¶*ͲC«@¹v¨—’_©&Nëã‘Ò’ó¨ƒLiJË~v.õs;4žÃm‡–‚ޏòâ0SÞ(qˆBóõé°¶A[b¿œìÛ/ë1󒜌‡ôŒöP©hÃZ´ô%™b'´÷.5[Å ŽÍÀ1[›«O¼^`‡­7D>Õ¥¼ãª™ Ó±uf¢V1#9ÈÅàÑ‘fÞp1ª±ÙÓ¨ZŒ¡«ËÍ|ײah"lYš´ÄzÚŒ™Tiµ\/4{JÅ tSZÍ{rÌLo™hÆ‹[U§¬·Íª#²þ—ÖÕÐ$ëJ+„Ø/˜'ÛÅA±BM¸]öëWÍ#Õ—Ím.kÖ²Š'-sq›ç0Ž÷†ÕyÀ¬©ŽèÓOZ?„ª-¡vÝËn¡ï²³›;ÌÊPDµÍu­¬Û¶*ª[Õ6`u]ÂÀUP‚{./mc7Ò3°¥Í¶ž®nçmPTE¯ÚWÍ’68˜–%Ü‘3ìà]wŽʶƒhŠü2è>;øh´|ÜBÅ  »P?ɦ!ÖÇtÔúAõvð^ÐW‡ø±ì°ÚÄ‹d§ˆïÛÝAÌn·»;@‹íàA‹òsíàpÐ,»{•Õû»)X‹XbÞ¦[ šÖõî;áãnx̶ºŽ{󟌗}lçÀß÷^Ÿïüyw‰c›¸þˆØI|çÃNìÅã;’4Ä—%›Ò¥ƒ©c£-Ѻ¢“J‘&­*“&ÕDÔü‘˜ªIûg0†ö¡yÚ´i*IöÞ9¬ÚÆ4ξ÷ãy~÷¼wïû¼Ï=7=â¾:]&ò×¾°.TÍG•»|j‘Háé°þäiã©ÅM“ïL×¹ç§3î3¼WÝsÓexäÚë‘iÕÀ71'CÃUëdu¾%“5ͤ©tMÚ­sëŠ}&â}@"ü›ZþE-?WËF©Ÿ*þŠ*~NAߥŠoPÅשâkTq†*NPŽTqœÚJ{ií¢_ ëi;m¥-t ÍÒfÚHëišÖÒš ñ†ÙÒòË {ÀSz<Ì—¡þÅB‰ä°T“Ù‘„ÝZªEY";œ(EY#w—ÂlI74>¶áÛùq¶ ÁÈXnQú§¥šíc‹8<|çôy‡Roœ>ŸÏƒÀöÿÀìЉÏðúŸÄè†o«%¼A¹¯SîŸS*‘Æ@QŠ*PT€âuª¸ Ø¥ãÙá±Òqg¾RÎ|¶äöì[$_¤’‹Ä}¥Êã{Æp¿¯b0/)Þ@ û¬jÍ­Zû6­9­Zs9ärà"¾<©\}IåÈóà¢ÂáÈqs [ò*ÜB¡J.LfA,`b¡ ªÃ}ôµºRU¯VÕ«Õa _ëOªw< ê8™W0ô÷ᱫé†tê\_‚~¯ôö«½%œ*_éÔ!>µ/ùÈ}„û9É‹xN7Ég9Èÿ8àó£Ï:¦U+©Ãà ìqc 4Hä·ï­Ö׃ûï>GC>ae_éUÙøãÞeǸþ |IÏ'J>âq{€AAk,i±ˆÂ§BGì'K¯¨´‹M›ªm}ÛúΔ•‹™M•ýd´Á±¯lªX,æð&|Ö³Î~ÎMÌN<ó¯êgs›Í*>77JDêPɃOéܾ’‡OÎΖ´¸çÝ”xù$P’"€ï çÐo­í’YK]& Aj.# '~CÞÐ’$­Ã9 &u ²à%° îHtÞkæ™ #0"ÓÆ„˜°$Íi}†eö023ÁÝÍÞÍß- <½ ™fd‰ÉNå(¡‘0"“p §iȃaz˜¨)Æä˜Á³£·ÅÛm–†)ã”éhèP†ì4vš2ô=¥#;éN]§¾Ó 9*¶¡‚P ¡£AM¿Ð/ö‡ AMO(eL™úƒš–PO°Gè5-Á¡EDd åÀKISŸ9ÉÜk¼ã»'ëX³Ç,šã„qç.'Á8ÝNÁ‰6œÐéôNÛ Íæ­óò|N–ÑDP8&“Þ3Ú!ЬIòõÆ»Âa#=˜ËñÉ ‰èä=”Hó4äØ›Æ›º2l—z0ãEý&¦Ñúúú~ü®¹AGn†Å›BÙ$Kpt ‰®Ž( êÅ>©èë›ÀŒÔ4é#aQˆvuÁøè*ì‘・2^[ÓYÎÓLê¸2ì¸Î K8cQÝ5 Bñ²‚0žë Ã& ÓÜLF"doóª°îYý %rˆ$XÒCŠ$"ËÈrí¯I˜üÕ‚^b¼Ì>®È«²ï{Ÿ>ßù|þLbâÄù4&qˆIŒ!J…-ƒABŠl|´ …’ ¡ˆ-lHm#Ä´Úøh¦šmZÛU[éFIH Ú`“ª©.š6QiÕšÑ-¬«({Î@×ý±élÙ¾×wÏó»çy~¿ß[¿¬oK42'ÚÖŠËó¾ÙXµà`Û¼M°žšŒåW­W WÑÃM^Ý:IÙ¡-Ÿ>¶uךs7V¥êvÇnª[pÚ\ž ûödóû½ùøÿZDª² @µÑHd uîÙÓ li¨+¯¢»ìyžž¶¥dúž|A7@µubq¬r¦Cm5Q'îéB8PR³×Ö ¿Î¶óI¢’ÙiÿyŸŒ¶ZÖUÔ K.a—2EDÓóváq —h7Rv• €Ï’º½‘ºuÂÖø_Ýzøå3Á2>Ytlôíü¿¬¿N[–3a)l 1ÞÝ ù[Ôŧˆ—4¦‹A%jX…1 ±jªOßåpø}PØ%qŒ×ÛÞ›pÛ!YM <Ã.euMÒp{EJž mÿž‡_~¤¶1|h¥u>Ëßûj¹¼æþèí«;.žÒ­ßY®¾kYÖVÌà=ë h%70ƒ…iÏEãÆ_ŒO Ž7t¦á§Ë‰ «Oñ‚÷ ~“{(-ƒ£ÞQâÝœ,…MÚ,MP€¥ö ÚÊpx^ÄœVÝý*É9¢ò´=/;„¡N’!"X¡õè|Ž9õ›ýÓ…VKÚDyŸUW-ˆÍœ×›Ù¶bÖ¶x<½ïµÓú;æŸÃNЦ}„±¯Sðb@Œ2üàxΞ{o‰·ügòPÁæ¬É·wóÏÝêÁ~4t‹x ·zŸ% 5$-ðÚKg l%cHR¼DœˆÌdÙE: Íbd>Ébä ]õš,Çv놢xï@,ˆý…øíh÷î5ÛçY”#ßÔT&Ë éÄO9h]h=Ë}iç’¹‡Ç>ûïÁ¬>à]$D^NW¹X˜ÅY;ká:Ùzö$û˰,û;Ç> i,DYQ¨¸ø ¤ÒNžyyž1ʇôqÚƒÂnžöðDAè M+€–*Äs~ê:Cý§uŸ‘Çq÷â§VZù.}‡R~•R:†²>îE~:O¸1ÿû`ò-íh/S)Ä£ÕÇöņ.ÂìÞ*±”‹o¤C£´›ç&¼ t?(¡§Ož>v”8™`Nì* íDÔo¶ÜiI¥ZZÜØÅEùiBʶû†.Üÿ˜ÝPMà“wܾÄÅï,fg3ðÛN¸¸ÁÚiõã®Àc¼Âö5-„_ ½N*ØÁpƒI,^:Ž}ì)÷¡Ë÷•_án¿c¿Ùá5ÖžÿB¶:]% Œn^@dî*¸nF½XI„…à^á_)c<ÎÓæü¥Àvdžӂ€ŒÿÆ>h’á ¿}‰½³˜ë³RÖü 0 #˜õÝÌÝò·øù6ÉÂôÝ㸆a£{£±eä¸óˆ>ztôØKÊ cŒ;+NHò›Ê9çωÕ]cÝg{&¿?yìÜñs£ïï{® _;tmä#÷GF¸Ë½¦´§¬ç™žýXk®Þ¬mvmÖ•,ËrY>+dŬ”•³Ž¬’ufÕIn’ŸÆÅ7¥IyÒ1©Lªãú¸‘c9.ÇçÄœ”“sŽœ’sæÔœ–såôœ;gœ/:_|¾¤6ÃeøŒ3RFÎ82JÆ™Q3ZÆíÔ ÝSf”yzƒÑàiðJ+GGB#ë–.{ê™ý³£¾>Ú×·Îo@ÐìèØ z£Ñຎ¨9’^dEÿ¶ÑÁ§_øòà ×Wî¾¾sÓõ'ê¶4´o™·r¥Þ`Ã`bçàƒ‰ÕÛüt›´Îa'‚Ñ;L–i…ÎVhï<é(k2;Ìnó7æM“¯6—š=æóÇæ¸yÙü›)L0ÍåË îÛ_;aÓÆÇŒÄpÌú{AŸÒ§ú{q¨ì)³‡®]ŸšÂsSH#úôƒO\µg²0…üÐ4ÃÕè›Ì0vŒ¬óŽŒ¬Ã•`L+å‚©E²/\Cß;TðAýý¶¥íEΧmÌÝv°Íj³­5a|kÄ¢ýŶºþ0xÅê8ˆBJBE¤æÞŸçÛW¶Ë­ˆð¨8ðŸÛ*Ûã……iWD\AEk§ÍÐH<éIÚ×Ђ«ºw"Ù¼Ñév]«-.튪‡>¼4Ú*•¨êtúAA¥\%P”`REO øJé[=ÝÉàŒY’ËGgTµ6ª<Ϋ0œõ)ëo‰š ÇÖT-ÓIEZRï –ëNÄ13ìrH% N9·?$2æW‚C'ý^Fð¸Ô:_ҵ:¯£\ÓJ=j‰>?Q9ß¡©×j}‘z½Êµwê÷Å®%ÕŽ:J•¯UF—ý·ڊù縜|—Z«q²®Jºu r!‰qSdø—VºA¤™ú¯”•¬Pœ¢ 8ÍÅQ&åtCmŒœËàNW@PU5TœjÕò÷ª‹ª}J‰K‰j鿹®úØ&®~ïïÓ>ûüíøâÄ_±°Ç6q¾.uã$8˜¦Œ™@¯n›CY3\ÂeeP”B˜FµJëPª24ihµòOÙÊ*µû#S[Mi¤S˜˜hE#ì´Ýôl¿ç»{ç“õûdDÖ•=½/ÛJر°£Ø» !þ¶L§ÇZŽÎÎMÍ&þz˜f[ˆ è>9»[œ<3½ÿòеý7†nîÿ<6÷ý¹É¹s±‡}«ã%\p¹„Ÿ½:ñîO~…>ác[æ@8מƒ¹ìtý(Í+²UÄböíSNÁÈ)p*»õÓi0=íËŽléVõúúiß„pA¸"Ì w„Gé¢B»ð™ ;!Œáyöb•Àòùáhô—Ã]Æ^dºl] kþKT1Q6Ángñ(û YvÞ¿|‘aìEؿš|Æÿò|-üR¤üdUÒiþ:Pëó,ÐÂ/5–È“çò™{ŠËÐ*gÆNœBñ…e‰M%ʨCh¿Älm1‰D)•>J㛥TúÖD w¸”Ó¤FPLO+5P¢ƒ¡øU"‘tPViRIITB´B]±¸Å[—‚_qPžÊâ¥]­+’ŠÔ¯¶ŽÒ+jÅË?T¹ÚÎ)¨„‹5SÈF p-ƒÆ£!ÕPaÜeQ¨h¢&:C#Ö]ݰUÊŸU·¬¯U©”f¹ ç)-ÔW×ÅqË6%¶j«„^…ÏÞàhÜÛçJí®6»´àâíiMw…Ž#ä:‚.ÐVFUØßŸàkË×™ªdj¥Ê\4h9ÒÊ6ªž× ¨¡3ÄÝZ¡õ³ÂŽf3{ÐYß_«–ëÑߣ 彡Rã‰íL¸»\ŠÃùU6†Th»É¦Üå±+ZÓ‹YÎNCÔIHHÑÎAQÔ:äõ9M^/£Ö¨æÜ{z§ëŒšÃã®ü¥Ú £Œ"tæpp³zc¬¬Éi3Ú)GqBJÊ'ŸÞ&ÎÕXöޏn¿´ÀY Æj:‚5ÏEXŽD'ËO[&+'ÃÓ5éf­sÖ%«š´,>Û" "Úöâï«X#æ‚=bÝškôMú1Ó‹îFЈcð²ý†Ú k˜“nðs7p»±2Ù<>Û±ÛÜŽža~ø»²áÐUÐŽ5£¦û$Ÿ~² =?ŒF¦¥%³ úÉÌ*N%`y¤FúA©–„AÆh…¡Z 0ÆŠP¶F°AåB‚²3­%ÎË K Ë¦v tâÒh}¾z°ÒÏsÖ²ð_ds!uwEDI·¶¼rc[¼Ý½ñ“ײ@uò’H˜gÜÀ< Úå|Ñ7Õ¸'<zvÄþL_°1ªe§«u&¹¾½¯ùƒM?î›ù|sSiÄ\O· +Æ6MâȆ_{®4à–ˆ$ڻצFS¯¥N'Ïmx35Ýý~÷ÇÝ_¶ßÝðÏÔCÏÃÄW)¬“IÖ¯I…ádlC›‡žu­–Ã0*’æšêe”ÈEd¶¸ˆÍÆ×ÇÝñ¶¸,ž òY}ïé»éÇiœM›Ó¾t,Ý‘&ÒY†œ¾ÆkèÜï¹Ü,÷wîGê8Wǵq/q‡9’#xÕSÅQ|×p‹w£÷÷S¯Ìëï‹FÆDE©ÕGm§~CÍP·(:J!»’¬‡¡ŒTÏÿ ØWhÎü¯lM_©¥…’jIν¢Wòˆ(ˆC§£(N,Q°PR@¨X5z„…á"Œ+ !€•@òP5|­P¨éÕ"Q’ "@ÈE *iþµÎHé \·8•.pFÍr~ý ’qøHñ¡¸J¯QÏ禃}çG#NOîÃc;—ÿ2vu›q_=´A %³—ÑZš&äé\ûÕÁòº}o,?ÜÙ*whh­J °<¨”¼žrJ©:¢‡ƒhfcødþåßémÚ€œX¶¤ ØßZöy»†Öù½œvó«×Ó¯øó÷xú%Ú]„ ; ®Š¹ðPÛÐtòµä…Ä›ÉO _$oî&ïþ“|ZP)’²œªPž´|É@!–l)t$» ßI*ôW!\h+ôŽHæËàØ=ðö^ÏólLeÌÅ[[𛏗ɴÇ;߃KXë…Kbub±¿?¾hÏmÌÊ]Ê]ÏÝÎÝÏQ|ΞÑY.w\•ÕÚ­A«hÅ­3ಸٛ5„³¢aD+ŽƒñÛÇX<“}}丧û'Áää‹ìØ ö{½Âþ‘c±Œä.dã,ÁîápªŠ…¼ Ø2ïêíï…½3€»Ò1ßÙ ÇçÍ…èÉ/ä¿ ÏÚ@¡K fÉKï˜H%’T)³p°>`’òé d«$‹Ý‹ ±Y,üÆb¿…X×mù̶¼ä²‘¨&ª-%Q„ךCQ£KòTI²$‡[1:ù"r:éí(É™JB,‰:‘žµ¬ÄÏâ&‡§n¥—JRX¹rGè–Yºw šV¨‚XA⤣xëâ@ÏrKFD4͸¢‚!@å€È—'{àu“^i„Z¹JÅÊ\‘#)´ÞloK­Ó¹yWÙ.³Ž5AʤÇM(Ê…þÌ?êf*P}U 5j€¾DûŽŽ‰vm¹ŠVó´žnÄ)½;ʹää›sC‡ÖrhWÇ%ÍÈ»?>íÿÉÖ«y®dšÍ~µ°yУè»àkå8£‘”i´Ò˜:YiJ¼‘x$¡#:E;%g©‰b*ç¾V8Q:W:ÍÏÈgä+ò’|G¾/ÿUþRærƒÜ&÷Ê{åÏe¤‡Àmžo•‰4üø †4`&Ó±çqfhr¨8D …HçãÈãPèu'9&ô>yHþD8B>9¯ãw~—GºrƒÜþ³Ú‘ÇWŸ_—ñîX]ÈWt×ã«u@Î>uÖB0"­nˆú‘#E"Ûˆ›È:¢l‘š˜ëwèF“ªÖ¨R7}@A?„(°”¡”#áPêÁ«æ,T;­ûÎD*Rß]íó[¦Á T'Téñod¶jTƒõìó5_ê¯,, ö¥[YA`Í;\Ø-1~ûwÑ^Õ<øN Ý‘¬£ºdöQoõX[,v3Žc‡ïnŠ…»mÁ£bÁ"ÐD0JCÓÁ±Sý’`ñ f†Y#7Uж‰¼K1Û·»Óâë;:e§à0Cs«8³hù‡¹ïí!ó~¸ˆ —6câ$ék§£­°‡ˆü‹µÇÐBø9$¼ Péµe,Û7c,%M=÷d ¿)>àiä(‰B"‹M@ ¡9*Ù÷ì ÷¶ÉðEg¾*ìœ:2=u1}³÷vïƒé‡Ó‚'Ïer#¹ÉÜBî;¹Os¼!‡ÞÌ¡\îàä,š9pàöíåLt$:]ˆ2Ñh²¹Yýæ·.îÙ;Èiå÷ß»µtóÆõ­[Ò›Åä2Y.ϨIm’ß½XÙu½Ò¿µ²½Ò_ØU¹|9|w¼’-¼àªx•h®ôBéE*Zò–ÂT±rb¡ræDéLé$W1|X¹c(Ý)^;9v—/h§´KÚOµ‡ÚŠö…†-¨%µ!í„Æ^Ó~­Q‚¤MkßÓi̤†ÒÚÌ$ýñ«ê)õ¦J-«Iš”ɽV­¬éä»3÷QãËÂ#øM 0ÌØˆà,§Ê»Ë“埗Ùýå…2U.ß§þ‘q SÈß }ž  äžPv,¥ƒ¤lt–ŽÓêç;g©¯ÊM½ÁÀAï³U€Vt'¤ãR=Áëþú…U©ŠÝ*üÕÆIœ™)–5[Ù]Ö’Ë®åcD…Þ£®»%̹žóà¦ê³†šs÷ú>^ÏQ÷ǵ —Tjc¾@ÀM%tht¼ª™²UÇú{‹§~jÚŠÂ-õZÀ€‡lÕ)ÕYDë{-êÞ<¦§BܸW!ð¬Vƒ]­/ÕW¯GA¸Íƒ Qê1ÑǸ4Ù$ÙelkvY Ü,«6uª–.Ž'áæ”o¤gN +0üôóc¦ØxöÜÄ–·¿án>é±4ø:,Œ± ›º“÷{äå-îýÍ fž19:Ú(шU»ý(Eqê—‹íö= 9×ÚÄêsà¨6a´ºSç2ϵƷG9ª·p†¯Ç0¢)všûcïÙl#˜å ÁМsö/ûÐÙ——¢ï±‚˜ŠU‡Ž'Ec„Œœ a‘bUû“m‡;SHÇôí•ý­Ť£¯Zƪ0ny³Õìô¼´6=ÿäwFb¤àMÊ"˜xšeiÆnfL4½YyîÁU¹ á#<Í‹ñ‰>§ên´^€¯¨H 2JïfÒ³ ‚n–2<ÈEÑÄù—Ä%Ó’…û,üÛðŸÃ_xŸúYö½é$N³8ŽoŽØ--¸ÁÈhæ}¦.lvӒ϶Å–ÒÙS8öE‰´L¶¿ULØBcS4¡üírmâ>àøýî|oûîì;ûlÇÆÎãìÄ!É…Û`;’’âB€Aph  žCK’Ö†d hSØh·†¨Û¨Uª­ƒNUUªJ+tÛT!„¦m*lÒ*`ö»sTšlŸå·eŸ¯Ñb¶‹<o›Þç8ÞfÉç¢å8'3$“4NP aØ ÜM M|Å7c¬¦pÃãûxç‘nÀÆÞ:ÏÖ ø¼ÌÁ^Ïêñì51£f3o[µ@B «XÌ×áIºÌIÑ•Ó2Z—ì@¦×5ÞjI¯KwPEì l†bϲï³×Ù,ŲíìßXÌÁnfϳ[åÃÖ“=å,)tw÷ÐBÄ"Ý‘m‘}‘±È©È;‘Ë‘k:Yï!Á6ržDIrýχ=4)“=‹T{[kä­G*á|ºüFž­ÞÃÏ”®>ò|UUûHV"IöI!æº:è$}äi‘sidIè­¦`2-×]0å§k3¤)mIa3r@“`¦ò…¦k>£T#,E¢´~95)xœF3a_ëܲÝK:Çm’Ëý*ÊÛb›ÇB`žf›³V¿üÕž:—U™CZä D+Å65><óûN™6ºYŒæÌ²÷ø)¸É”‰œ ‹ ȶ"ÍBU™éP"hÿ$?šúœ*6ZZp©â&Ò„•Yþê´ÁfÝeBÀã/ß$-øRä7heìKDžÓ€31A&dú!¿ßÁò;ù$?Äïâ_à_ä_B&¸w”;ÆMòS¦ãÈ/÷Yä2ç\í±Y˜šœ)?ûæ/ßü "´óÕ†ºÖØÊbÓx†ý >ƒŸ+­n=7•›::ulꜥ?×´ÿØæÉÍÇñh4žHtz†ÀÐPÊnç…Y0;;“›Š©@RsY/5Ó™R§y%gBs|Ö“­ÉF³]Y<›½Xärgs¥¤»ùÞªt¨¯--¶Ï2¶Ãö Xy÷Þ܆dÿK0iûÓ[)$=—¾Hu!àªÆ—>Î\Ï ë2 Šw._áÁ ?S²„J¥.•gR‚WUÕ¸úºjX¡nWSê;êeõ–J¨*EO¦@*5>ˆ™ižê¢Ð­Ôê$u•2PÔ<?¼D§äÔ¥EÕj€9*æ@¥6ÇR‹Ê…(p%Ôt Ñò»‚ŒÞù{]]ᦦUí\“j|†%¡L6{Z IªêŒÇ÷dRR&“R¦s¹y0³¨ |@™ž™ÎÍœ¦x‰¢xMüzšã0Ír¯<ëú=¯|º±IAK˜ ñ¾ˆ›zÈÍc)R ëP AòuÚôùa?ûƒuÐ Ë YíOc†±_ ý£¤æv¡¤…g-Døâ´óé°Ðb!ÑCh¡@àYZè º¢.W#j¸¹ø¡’Ž©ðÝ–3ñb[Y¬n“HŽ:$VíÜD™2ÒÍ$Ö‡må8Ê0Ks±ÑC×Ä7|½´ggK„² H#æ¨W‘žº~H}bŸÄËë ^)ªMµíM?ðМÕ@:ý%&Æd®¨1BoÂo÷~%“©”¸_µ›M>Í Ž•´6Yþb“»·”v†í|ƒDâx[ÁnÜB ”•%y¢øðY€F%ÐÕ¹ÌŹe +ÇP GN8ß+üxûÉÕôá ùg`¤óíw5Ë/Ms.ùzþÖ£¿ÔÌ08dZŠÅaaQ7”…÷  iqìþk;ÚǽUŽüŸ›„?õ9ò7NxmË*w·_-j½?|hÂ,æoü¡=ÿͧÙâ5B) Ç*óâÛÇ!îBî+c‡¯µ€––††Z«U8xp˜VµƒŒŽ&úzz±Ñ¶{-éh}rE:zàÞ!$9ž>”•û¬I[µ¡£‚L|¦F½jöÚ¤²åN*äD¹ª¤€(ÍJ·2¦œR®)¯¨JLÁN)@QæÑßÅhúÇ$p’°>µõÇLЊLÊð¥ßŸu#ÐuÿÔ¯ÿÏŽÓM§á$اuÿ®ÆWwž±™³£·÷´¢JŠ¢&YÞ3˜ƒÃƒ‰aOWHöŠð}kAg=Ýq…ý¦Ï7Ø2þ…Á&jÊŽ€(ªI9¤è®Ñ`F·Nð #YêjÐÜ¥×ÐBéL)Y#gŸ@#`z_A?jó -Ô“~"}O¬%I {t‰H¬äi¬u‘¼Éäþ5 R,i 4”¬ñØ€'hõWš¨i pˆ?Õ´{¤\ÆLâm?×ÜTí0P'|V^°qƒùÛ¬ÀÎX¥¢üm‘[s§¦˜’8œ¦L²e©l§]&{…è'i{ãñ°³|¿×ì+1Üiö©Ãã¨}Û`Ç )ؽÀÄI«z»CJ>Üç[´~Ò¢ÛVîA}Xp‹ç)@]d«ÉHJ=v+uæü¿ó»r2ðU€knÇn0´¦‚/’I~IרÞÛéž{µÜÈ1,A;dÅaè£ÈÜã;øN¼q" ȱñ²†É²ÓèüŒi½€_0Qðç5Ñ2í2øˆ&¼ÖÕž*aêMAn•½±,\¬Ûäߺ’bÂà sFÚ†þ¨v²ö£Ú‡µ†öZP;nÄzsÞ+Þû^C›x“6úXàzàac40â¶ G <Â^aL0óèc.<¢÷ƒ 8r¹„\E°.ä$rÁ¢°¨>mÈ á>ñÝÔ#xÔ`´ËÀB0§Ä勺!sXi üãuY°& ]––pÕô1·¾Å68~^Ž;þxvû‰ß~54ñuófà/^ÖcóU +‘ðÚ²·’+ëÛÛuõh¦ÆŽ¶ ÝÜ_>ˆÁ|øôGÏÿë‹Ùçr{ÞÎçq8!l:e¥mÛ?z÷ÿìrMã¾ã8ÿ{q/îà8À6ü8sà8`ƒq0`ÇØg;Vê÷ƒ¤ÉˆSÇà8"Y¤%Kšu‰’¬Ù%•ºNÚ–¬4-šª9Ù¦uR[)›´jÒÒmÒº­Z4)ÕleéZ©Ucï‡t‡>ú}ßï÷³wâ5{ßh`îÖú÷_º~4 JÍÆGØ5¼Q·¤ûGâ83BÏ SæÙôÔ4Š¥û3C£èÛ_.—x(™Ìíß“›ÆÉ¼8‰“Jr¼=†Özz¤â¶µº»ã`ü”§\W–$¿tpm±¼T.’Vñ²øžˆžÁ;"€W¢YŽ<âIc¶,“ä#i#l³Èp/W7Ó8⇮0S,m6Iõ<£öȈÿñL1ù‚%ÐùÉÉ‚HŠ¢HÂ…ß\t[D]õÀ&J¹Á­™Tö UÖÙx âîóT"Ó ¶‚H›‡¶Ø0 +†Pž::í]TÏi™§ Ïúz5ñj(zo“Ã@˜‰€Þ€‹ k!x‰6#mŒé·Êlƒé¹ ÁôG„ºV}ï0ԘΔ'°×ÀÉÉjÜÑÏÕõ7({b,U: 5H Ÿ Q M0u+@kfÞšÎ;0’§ÍT¦å}¿bž7ÍŸ’&Æ$3ÏŸ^Îô6QØ`nÉ300¼|spЙK¬uùÖ¶—»Ê§óµe§yÍ^vŽä'XO'Ê9'¬‘äÉ907÷BÓ1þÿ2ÿ:›¿Ëÿ™×ÛyÀgæ¼§z{O–\jž¥¨°rë jù‘ªeX-GüP§¥™ úBK·'Ñï•6 ½j ¨’†¯¶d-6y< ½âÀ@of~¾ÀS"ÏS[Äô¤+Nhµõi¬m–DUô¡àí‰ …Í‚b› ¦u:¨øÆpÈ ­‡Ð[ÍND 'µ÷ñ@†… ®ü—°ÖíTõ£p I©ö´!ÂxI¨#¤æŸ¶0•\ÜüRèo õ;«-F_§‹Á«$H‚5Ù[õËô^äA«wìØ¬tùfÍ_-»£ŽfLŽîz)N3z ¹m©új¶‡™ýÕÀnÎ] ¥Šyøà4pííÅ !£g#Ì@F55Š¿³IÛN_«†€ÅV=û/ðUvU»'xÖ¨'1A0F´q|¡aß­±–õÖ]Žè1ª #!Áa´…Fõf÷¸ñ"pñÈú~æ­ÂõF³‰¥‚‚ŒÿhœÁÞÚw“ä÷~â(µÍÒ£ý‹M³Ë:è­;6>ÀÚp¯®O÷ïÄÒêß÷Þk»·ý^à^qz•¹Æ¾bx…»Î¿jüŽézõ·}ßò_í¸º¹ÜÅ‹SÂT{ž>JŸ¤¿É\éú.ó£Öt1KèØP ³wƒ¶`° XDA°\Þ^p >!.¤<Øf0©~ÿÏ‘¬.ª“ÀxÂÚ|ʉ°œåmQ¥t‡1é{|­Eh bU\)Ýùn'Ò¹‚L|¥7«@UU¬öR Äü3~‘VϬB™¯Â».^Z-ÆWáÓJqÛÒ$Ô ?€æÀ&wh*€&ë~ iNuMh°ªcªnêP@Pø‚ª4¦ ÍFr kŒr46ðÙ\¿§ÚÎöžð÷ Ÿ¿„²&ÁÌ›a|Gá¬4ÖlÅýþåoüýâ%caAÆÎ§ëp€6os׆ë¬î¥þ»ícž®ô‰^ÜÑÕšhEC»šcg‹±åt1—éâ³ÅVÂófuz7>Ä—ñNÝ$ü_¼Ÿ{¿(þ”ë¶ß·uYpû :=R›×ÝA>Ó™‘Ïa ®u•»w®ÅËÝ$•r§B)%u>õ§aKçSÇS/¦þ˜ÂàG Ógâ ~GÉ>ÙöÀ¾Øo™øhD™ò¤ãC °XVOªP##+È…„P¬Š[ )ýÊY…•0|2ªä•¯+W•Ê{Ê?•OFQ¦§(ŦLU²Ô¤Q­F¸Ð‹h [ Uã}£æ?÷‹*ë– ã~¢:$ÝÇ÷««O3•‰¸ýþ%%*Jjk¾ 8G ' ç Û´CkÁpª¶`%%+3ÝŠLµZï­°¨^{ó‰!iÌêVËOÅlÂA`ÁÍUÛGåg î{–3ï`¹è/ÚŒVÁLc(i5Ñãóãv#†äÎ! !K7— Åûž©¾ñ ;8[½ wÖO·`Ά_M &’n©uàaÃO£ B¢º¯×]%4¬4JcC>X¿°~ÕNXiNϦ"Q hÊ*è!yéyÓÐçúi wÄ À^uHÛòÕˆ~¼^7j/ÓÞ”«ß¨C¼Ç|>™¦uº¬Y ™¬˜Édc==ÏI²(IrF”z²f9FbNÝ`ódóZ[d-Tn+² Ê⼩PírB.Ë+ò¯å{òDzž–ûe¤GŽ¡S“Ùç³Ç³/f¯gq*;E²¢mÌH“žlF6š¥„tRzSú½ôH"ÎI@’VP>ÁQ™df*s)óNÏdV@‚ž¤26ɯ{ j4µhÚ˜ö?”&¨'Øu¡Z*̨ŗ-ò¡¤aV`3Ž`'.Âf[ƒ65Ô5×h ¶&â¿L—{l÷Çï÷ûùî|ûü¸ó9öů‹s~ÅvÇÆ ‰//§Ø„5žoOIØ=rn×_}XÉjY;åãµ?Ðs¤BL?×ç\WÜ/Í÷îïGo†~ÚO÷.Á[xpä:‰pˆ¦‚$é`yL,K¡òXY:BT¦Ÿ‰Î&ŽeÚ°U2½G3í¸±[„PÊ•ÇFÇ m ”ûÇÐd.·Kº¿NLÚÞ7tÀr¿Å*z¬¿Ú™×îu–îï踒ÄPHªªIÖc/j|a(:eHšÍûŽúS‘ê-2Ql„û¿ Z+nƒÌß8û%ãVV¿(ÁԙdžœÀTû˜|÷ÈO^GÁÓŸd-ÐÅÃ#{Õ · mn‘6_IÎéë­óµ7—mîL!èËÚ²b§«ý£:ùr¯¼ªyÙo‰ŒA„€ä9é"E š Q Ù.÷¯\½¿ßžçŸkôƒH‹¥m|ܽùe‰e8’A€ b€ R±çÜ|êï’ûZ§{µÞo~€ß”Àÿ¢3%5’aÑE1ˆkÖ¿6KàùCb?‚èG&Û)"µÒœ¦ƒR7¹?ùðåYcën[»æQQ"žfýó )6v˜a·“=YßÍ­7Й4¦Rûr¶­B%\i¬h•H9º%=02°G6Ë&KAÅ™òŸoŸ&p‚Õ™g$Þ4ŠfvLüºôöRÔÌR+›V€² ïé ×’Êbƒ#QkÐÒZ6¬Íh_ÒNi/j¯iß×ÞÔÞÁYcµi'5¨iË`¯î`öL3D;èñ·§Ú‹í¨ý³¶‡SM=v7~ü~5'䢸òþކ…ÔQ÷]ûg™PÃSürÜÕ^rˆdÍ@¸Ið€j´dü@4|a…åZE¸dÃ+jÈ€Õj]ll±O 6_ ølÕꪫvñmL-øoñ¼b±Û‰Xsw¬˜tš¸&ÿÀ±<«œn6È2['ÚY¿Sžwï %5‹[à”tóèk}“=®ÈjÎíàzŽÛÔ¯y¬²Ò”b¶tÊöÉføŽõ1ˆæñ  ˆ×ž~áR€¥ØºúŠÃ±œvV‘D›µ±;–ðö8ó“RÒb´E‘ú¶3úáS¾ˆyeŽâ¨ægZ¯} ¯ƒQê‹/Y|«{²)Ü€}s~í=t„Lq¢›ø^ša§Î§Î§MA¶â©¤*ÍChˆ™FÓŒÙêáS\škæ2\‹Í@æˆÕ¬›LjĬë—Õˆ¨ªÕª£Mþˆˆn†À¹¡ÛÍĦÃ"•˜ð³­Ón?F¿e0¯ÛRu¨!UWï«$Pª.ƒÅ«=ÛWÃñÿNá‹»FÜÅa/l4 ª5~Rãã†~™ãe,ö ¨á¢Í¼}_9l¶R½ovï¡A] ÏÓ—òñ ku(Òºçõ¾Œžo žëŽÃ·ÁNW†¥ºqêH¥ÈÀäã¨ÿ¬ÞÑÚ2«ãõmš{v obhß»Íum‡É*ñm{ößþF—hY ÷þõ/R -[Tÿôj<–ÆÚÏ­ý. (NÍÄõ[gÍÀ‰ôDó|úDúkéß6<Ôþùgì_–Hd!ÏSÄ2àt¯ð'`"áÌO„(jÉÉòwf/a^³KpZ6é°=Ä“r儽r×\oTÃʳÆgãÄ ÆquRë¦Ç.¯­Æ³5bþd—}lwÆïwç·³}/¶Ïwö]|gÇ>¿$NαcçlǾˋ›4ïY²”¸õÖºÒ6¨M;Úµb[§î¥£e¢ !1ÔÔj“Ú”m¡¼lB&  t*Ú"/uùÝ9nAØ–ïÎ>YÖ÷åy>)!ÆäS€ Öд-¶#aŒõÈù’—tSⱉټÜò‰òô$‹÷M# äÉÙð¨\I·Ó/ÈÕÑØ¿³1šêÀ}ý‹ýèáÕ‘Œv(ó|϶êá9‡(=T8,Øe ðdŠž^H‡âRáé¨Í/ßývÂEF.êJM­gw`¡jµ” BÄö±Ú舵4AÒŸ%D”&&Dˆ!ˆÐˆ/0|µz¥J½ \å—C6tœÿ¾£>Ov'ÙºŒôn€ákÉä <êøââ @;–Œ±<’S åØ4Ì×xA¨û»¡Äÿo¾m9VÌ9‡mA7€ mÓÊèVa·¹¥*¦×né°Ý |~¦5òFÝï«wó"ãìä]®`¨«Ú¿3ºLJÒ‹Û³ óΧÕèP¶é×g ŸÂ¡HÁ_‘d¾\³Ø‚Àv1²h·z-}+ãùr¼²8Ô<…÷2D03ðËc`^’ÿR—ÖÁ¢Àúò3Ó3嘷&¢1ÞåtÐ=‘S›(ŠB bm‡›¿Ppª^\Ëè¼EìÞpÓŽ¹¡‚O"»'Ÿè¶:{-æó d•AÕüj½x ü(ÔúüáÕ¢u¯c ó›ŠÂèŠcÍS‚$ ‚°Tçl{ëCÔñÝÔ8?qmñët.G*Ž…ún„¤É9#7ÀÞõ®…Î 4¬»v§Ó'Nx©\>qÒhÁ¦ùö¡·ö Žü]ø±ºµÆÍ[аq cþ«£Fû8~`ç õ‚6™=Íe -[m­J¢m°í˜;º•¡@  @ ¡Z¢dú,Ûd[:Ÿm’úáëðÏïrÉa7ãfSÉjw.éö(¸ƒÆì´S|TÇû§Ç’t¿^xef0Sˆ]˜42j©iDžr:`IU«µQÓ˜ZMS«•·úÊÈ»àŠÉÔ}¶¯v¾Ú‰vÞHÔË‚³g…b%VagYCXvý³.á)M×µÝÚ7´«Úo´O4¢ÝÔÐ9 hÚ­©6c1!Ëp,8ƒ-¼6ÜŠ3ÝÊ\ï­å†#ó%cb[>e21·•±,3چ㲠-Å4ú‹š“a‚Xa 5‰8ø¦å˜ËoÊd°woš¾´{HËm?ò­C= F óL èqù"CóC"Oz OωÃúèq›)ÚíIZ~ð|/>÷µÍ³LìçÙ¥å#ÍŸýTõKJðÈt÷Òwöâ¸ð컚¿«„½4å‰_#,ùxšv˜ºÑԽЇ-ÿ@܈†\Ò40>š¡ý‚(•¬%xéË0W˜wŒaJjoLQ†:b±†ZbTµäüTÂÀ) `Ì{›Xçlt/€º:¦©õ~§Z±R¦Ú6вîE!Ý¢òêAõ5Õ¢ªéF?þd´¡µ¼&>ݸû¡ÒhlÞ—ÚüÖk.n£Ø@Ú¼Ðß*½)’˜éLØò-{;Í´2б‡¹y§ÅÂàR!Ö™½™p:áw*lO²4ý£Ç©v~p”åI—är¸üÑ9Z/t…ŵï6Ë·£)ñ¥›ŸÃ‚Þ¨B|þçí;B–N1ÞßáëÚ]n¦1X8רéß‚Œ"xlVmŽ6qtÌòÄ…Œ"/êâ$.s——ƒ?Í^yFyüS “`ÌMDCã늼Î#^¨“d…ȉ¼e[­«+½† Û<†u¹µ‘Ùtd¤ÆóÛj¦’gØWË›¸â–)ŠÚ*ãZ»ŠFi ïg–ËÔ=<´m?ž0ó ¼ÕD2´UÎVXofl4)Kñ_ãœÙÅtçcI>§9·LHwúìXº—:C’]s×÷«Y6êw[ÎIJB 'ãÿLØ#C8Nf‡²·j‰Y“$„ßg'´3~‚ÜÛ¼Ž½Öü×W>KqNJ Iß»i ZSЂ¨þõ çÏÒ9ºŸÎ{ 7{~,;–ñº³¾p¥ôNå}âFéúƒ·+¿¯Þ[¹³Ÿ…ŠP4q™_ óÊ RQªÝ+Ú VѪš¦óº wè¡aQ—f–õýÂa<&ÀôBDDBÂŽ¥™Ú°î¡p5xç˜Åryi†YZši¸p²Oç­Qb0· \Á,`ß!-ÕÃü2öV´^vnwö]o q}KU¿ðØ¿ÝÔ=«8Ôπϼ:ƒÎÌÜZ½¿,kJžÀm Ý&”0ÈÜ›r~²ù¤©V›ÐöþGÌZòµ“ÏÔ°ì@Rµ‘!”´ã¢ÑΖC‰ð“vDlc!Ë=`––i= p:[z—ˆc­}kkøú€Œ{¯ïËY1ÑwnÏóÚ*¿·¾­áëâÔPRŠÆ;/¶cÇy—„¼8â$@5BÂ{¼54%„Ôt´ªuÐ6¡T¬Ù¾”O]¥MM7µEl"´ÁÔi ¶Àžs^ëÑsÏóœ¸ÿïÿ{iŸÿ´Íj`IâÇïioiŸÛPÄz¦à×O=»ƒþ!~äý˜{%àÿ¡zà]`P T0”ÅÄ)ê²Pa„ŠB¡IЯ@ôœ&U™ †EIUà'” !&t ;„Âqá¬ð+áŠð­ð C„¯T/Aø{à•âB«„øð9 ª@†rC"œ„)FJ„\S‚áª×Ã,±á"Mëv*ÏçØtÔˣɂTêbJ¥U™³Fëy%Y¼¥Æå4/ÃÙ‡RFœ²©©ÅÕ§w.÷m/­.Òcâ¤|­&/G)?Ø;±ðý×=j‚ÖéeÅßüì6¼ÈIp?ö,îiªmŠÄêãƒñ¡Ô¼Ò•ŒhÂɦä)Ý[õsÍs‰¹¤º'9–Ü5´ûðÙ$~Šw:qyøòØç _tþ1û­x7ò®û?¹7wož?<ŸIÌ$ó™|{¾#??žŸ›žŸ7këÜuž@$¯êŒìîlëì÷ŒewkõL9ëû¾¤/ãk÷u¸ËT›EAK§è4ÝFgèvºƒÎÑ£ô˜êæw"3ÃŒ2¦jõ‰Ù@â³øg‰åæå–åørb¥y¥e%¾’ÐÀÈ%ÄHgwõÖp•ª>ãö aÂð {HÁä39þU²;“ÉÖ‡Íõõá˜7·Ç¶ç²0 ¡1|bvv$Ϙóy†µ‚·ˆ”¡wÂOì›à‰¨²S‰*—ÐÅ `Ñ@$ñ@<Çã2‚˜ÆÅ¶+)r†Ì]#_%ÅÌBæLË,aªOÅÜ`n!‡åà:f¨mÝ6;:;7‹Ÿ›³÷Née³³·¡ªVÞ,qûÉÃl]tÕ5PÁ§¥²r}!ŸTÊIq#ã¬ʳ »É:ŸÒIA? ?$+cÐS`¨/†x oÖ)†FkÖ·*½ŠX3'[&®`£ Û˜6ìÓ†’Ãðиf7Þ¬3‘@Ë] ªÁÊèŽo&I“‰ç[mµA«•-9XJÖôÖ—•›uû}Ęßà z®V±N…Ê‚ö‹6—™"JÜѸÜèch•íÒ|‘›")6Òþ^×ÌSÄ2³¾nRc$¡Öó¾­oó[°$´ÓEFNA,bè—Š’ª˜Nƒb!Gš©d4E´ëN“%2Ú:ärµ\ï7ÛôG«Œ¼al¯Ën6–Öâú+;c¦ˆ€ãæò>U÷‚^gðÝ ±ÖÐZG÷GÛÏ}ì±`„qS;8~ºT£5hÕFKÿ9îƒâ(ga0M[I ¡„—}v ;ЉH?èŠÅMÍÚ¸)iI¥ìémé~U ÂÚ‹y½Ã¶‰÷ñ>ÈoæC¶z¾¡,U¥ ¥âÚ¸c«c„Mߨô·–µóƒ‰tozΟGÞ±¾#bM¢mDð+êkjT­F¤€—úƒÑ y1ô—X-lš0e<^ïe±Ñ,ЦLfDBÌ’„·ÔðJ üH"êŽÑ4Ñ2á$ºÈ¿@OdŒ;}‹5d£w0ƒ˜°b±RżxJ<'~!*-¢.1q ½sé%‡”bR·4"í“Þ”ÎH¥o¤ÿJZBb¥cÒW’Bú=X@ô&³·!ƒÊO&Ñ©I(“2ø!†_Âý*«Ê/ ;»î4 ’‰L‚©,´I>°&† hÍZ\Ãî*­®š4j†äË=§Ý—LÔs(b€=¨¯Ú«Á ŠÙþZ@¯ÃI#®²Suf“ŠÈ^Ol~ÅéV(c9…²vß&>Yu•[,¡_ÔšT”FϤûUìîЮXA²½zUE| @űF Œ&­ÅÚë:ª#Õ'Wðe%Fƒûä­»:B«½j·5—1fmxÔÏy­ó¾v¾ùÒol: Wá*[ã_ª¡·š‚Ùà:BôH)òïØÂÜcË£’ÿØ¿ãñyûyîC×}öwÓ~“¿éPmãzù]Ü8ý9{Ð~šUµ ­l†ká[8É©-„àmœÕb¶›yÕî‚å Æ¡HÙ€m€"0t `dÚ ¬o©i$å©Yž"òT@:‘‘gˆ‚Fö!(L W Šíî˜3n†~"J jšïòmB¾H€êNÈ…ÃÙá1ù`ò ØL"Ñ“p@f›‚V Òš)qƒ´@!NT7 Š^z÷Ýî\Ge ÿ2“Øñä• ÷×Åbì§1´öÞÓ÷޾Ñw«Í`‰|ò‰Ïë“ÀùCÁø?_‚©`åÉXBáDF‘7åX½cÊq`YÈ-Œ^kþr\év;n25}d8DøÚ4:½ÑÄp‚Šìéq·år¤¯­-KºÍ$é./¯)Y‚)q:¹ýG¦†¿.„'kˆÔë ÍVhJ>è.˜jgÿ0½{ÇL Q.¡ÿŒÑ+$øù‰jÈ6%Õ•° ¦¦C 2™…îòáýC(Ð`\¥œÔBþ—üH!f¬KEß·.ÀšÔø|5QÈâÆ^× ØPkÝ!oà°ÆL¡…&òÀlÂòÀ¬„Ÿž–åÆ] ¶»ã÷»Wû|w¾;Ÿ}ŽcŸÏNûlÇvÎN®¾¸ö%iÞ§N“vRÒfMé‹”uQÚ”—u- mC¨E-P:X@ˆjPuí ¡üÑýhcb¼T˜ÊÄ?aÑJHmÂïÎ$ÕâœÏ¶dùû{¾Ÿçyæ}·ZexÒ(GG“Ÿí¬È(*z8B“ã2††S/N\|õ¨˜æù]뺋œÛí ã ÐèPÊž>òþD±¨¬ûÕÒG‘VŽ{eŸÛºªé¬Œ #{‘÷-ã‰nkv¦„…à !šÉd®:49B1˜/±FÂÂr )—kt»øÈäL?‰A¨’kÊ´f‹EIL«Þ‘Å^Zh`X 7”›ËÈ-çÞΑË9Ë­‚ƒVÊ==—¯‚ýÕÅêç«g«+Õ7ª·ªïUïV?ªÒ+ð‚º£UP®ÞÙÇ?€;Wn-óÜ?iÙáv­vvHf¡™F2›0¶óÿ‡ÊNðp4¥!mņæEŠ‚@Ñî'^Ь,Œ 5гYL`H@7i,ÚR“{€ßE-†ªK `Ï»HÝN2ÙÑÞ6²5ÁúX?ßOQ"ƒ¢Ù«ŒÏß§ ±^ÀûÛä¨y²Ã‡ÑÉ #åX¬8xûá—ÂÉî”úèxeªzy4ÕÚúäëå½f+“-¡RçòŸ/=+ŽÎô·?É{H€Ò.‚Á€¡œ†vÙ;|L.w‰lø™o”ìäSïþP^8ù(о«òÁk&dÊwÆO]ÜfvAŸ‡LÆòX éÖ­«>àÆ9ˆEp÷yÔ@A(ˆý‚%â“Âqo`_ú¼÷<^¸ ~-pQþVúRæšp]ü©ß[&kGÒØ{ˆ›óâŸ,ÊóÁm!}ß{Ÿß7´ûŽX™Mò;„±.GµÑôPfGvÜXf—¹eïþŒp›½í½ÍÿZ‚ Nò"®Ûʘ’ò‰’¦4BÑq‚0ôNžŸ5tÉ0ô(Q#VŒ€™÷:rޝ‚7-fŠt1DæišL¬‚~+rLYVPD¹­ Ç (Û{ô#ú}CÇYè6Õ+ü‡Çg!–PA-­ñÐâ·àäˆÇᔓ}qÈ?mצ%¨Gè:ÙÌq<¼Ç7]¾I GWÈ–§÷øló.‘XÄ5¥µ|QWS->ÜÓ*á\æ»#Ýé¶PDJD[0–çÅÂúƒ¿Gi•éÌþ!xÜèÝ ê^D{^ø0*gfü²÷”œÝ£%µEËÅäˆ2ëùqÁç•Bó ôÛˆËKÛíª{ãèeLG2ÈÏ­âBÚëL=öóRŒÌ1¹Ø>f_lž™‘1U]ß´B¬GbYGec¸ÐSã–æjrÃ)¦_±¸ðŒ@òˆŠ Á¡; ¿EÎtxZVQÓR%‰‹ÏÑttî¾Ïý„{‡û‡ÓœÆ•9Œã:Qû€è дά“–Öœµ´Öôˆµfy…`¯³àlôãÖaïóqÃÞG‡Ö6Æ¡Õ:Ijsèå"ôÐtáºÊ{99“Tâ…Ó/”wÄüÙ!†i gæjÏ힊_ï`Ø”R-̽Ü8q­šU{(²ßµ~w¢8?:¢+ 8ÁœàU“2–ã²PÉmIªí±×Â_b»$Izl8†7˜ÃI»dä-Ö€¯7Ã},ê=×*qŠJ3H0€ÎÐT„ðÇç˜TŸê.º.‡úI¶55ÝØÃ“Ÿcå`K°+óõú;€"8VˆôMG‚ÁûÞ‘ƒ@c~Äúéò·I;äfNŽOn¿yz´u¼sãClëF¦`fYÚ¢{nË=è”ÆýÖF¸¡4Æžè@>šÀ¶W-WH•*P(EMÔu-ZÅâž-¢ÍVâR¥üþÙú„T¯OÔý‚V‰wlw3†UUû•0‰dÛÉTÔΈ¤Ý5häCªzAGuxû£ìtvà*l&áa:Þ¡a• Áí¡*­•|¥·²³r´ò°BUl»ãÉúîú\ý“õçë¿©“õ;»a®¼7k<§`4Ÿ©!M“?Þ6ƒ Ú–¶Ù3ìØiŸd3%7 ç¿ü±Ó•Ó”uç^~Ü'|ŽÕ-HÙæ×]/Ç*ɸìQùKIÕ0¦óÌ1Ê~aÀXëœ ûdÆoÞŠ ™I‘U KµvÖ/j_&Qqû¹÷> s>Š×® ùÐ?qµX{ˆ¦”ïåä0ïo'Ãó!ñŽÅ1wòÓ }W0¾vv½Ð£Z©§…#ö5IŸ ÏQš–†^{{—D>Xl€]_U8êà™¿bn¬òçE+J§ÓÐ3 E ½¢dH¥’‘ !l®¾µýg$°7-Oó•b6>¼©hª‘ÂR©UpÄ¢Ýh‰/Y%¬TZgßì³—ì_pÉf3N =“F±yPµÿ³‰fjõ9»Ô¤Lðω“›ã‡”*mº5{±É/{Õ^WÝæ'ò­Y©c&EqÊCô=«V¯%¿6¢ÿåT¥_ ‡‚ S^7å´ê¨Œ¾r Ÿ×²{þí)ÊH‰ˆÎ¶Y ¥þÎléd>,u-_<ºþà‰„'Ôzý÷lDdÜm}p†#ÄW°d?`­áŒ¡•{ry4=š3ƶY~ø_ö«>¶‰óŒ?wgûÎöùîì‹íØñgÛ‰Øù²'!¾ÄùÄ!&!äÛÄV€É` ¶j«}uˆjeÿT*ª´ªÚºjê ¥l„¬*L¢ýcb›P·©Ò˜4¦VZ¡¥‚RMJ²çl'°U-ÛþØSÞ»ßÝsï×ݽÏó¼ÏïÎØÎØÏ8Nw- mí¿p\¨¸Ð±Üu%q­Ç¬1h|áJ+*;”[©.}k©HÛÆ0 HÚôÛ •ùíRU­ªb™ô†ôëkÕ„qáßPDˆÈÅH‚ÏÆÛö°=nOÙ§ì*ûù±¤3ßU©õ >Ò·DîùÙkÒ%‰”–ˆË’žpa"N¤ˆ)BEäŒe2ô%ú*M 4A㉧â©C)j*5Ÿ"Sïg„ÏÒ+xÞIÇ„;÷¥…\~"ÈøÍ•¹ Co°¾ý¹œÍXDÒù0ÈgtæõfY¯­Ó…+äA…§¼K­Û€›^·Z÷Gü‘Ñ# ÉG¶–eµ¢y½ÎPTo÷ºCQ±Âä90öæ _'f«+{xàñ乘’6(…‰½üŽDöÍ~5« ½ gÌ^Ä2¼PIöh'žî›Z½÷AQtÛhàÇÎæ+¯aØ’ü`•ä´–OM¬¾úÂàÏOœ¦ÛJã.ÇÔ‡'²5C"rñékÍß‘&¿VÇ2œVÑñxòø|ªÖ!h*Ñ> k)Sa˜»’´ìþ»›O³¬†ãù‘2V£ñ¶ONJme¥nwBšœœÓx1¥ô&Üî4?R„}x÷HB3)y™Œ£v™ø>4‘¾³A•YEâÔY‡*)‹(i÷ÊÄ"BÏg´£Jzÿ–J…Œ·•%%¡éúßG¿w=D@ȪQ¡Ð,\Td®OÓáÅ•ÈÒòMæ2™¸)s6ÙW×Ï/l¨yA¸|ù2Í --9Q¾0xp-²G7äRB™c 6}a¢@çh_oÈļ¾¹(ŸÃTdcYg(þ†<'Ì?Nuß6pèKJJ4ñ¼ÑjqÎõ,«×ê•Zhñø+âOÕ¿<ÞVâà8£³Ù¬åŒå,«Ô˜¸ú­ÇŸ°Š¢ž3+Hc´µK8ÊìòòçS±Šòúd{£ÃèØ‘÷ez4Ê}Wÿjtz#Ï–JCUmN¥Ò¨Wsf½§”ÑðÞiæ\‚ºÉSmÖéI¥J •5ë5)ª­VK¬Ç?:t{ìØ¨£ÈæäW³f]³+˜©éÞXý‰©.ž) #µßtIž'“ûÞø$6 *5™Ñö¥lS§ÅP¬¬±p6WõÅÕÏO¾ÿÊâìg‘gdþslåsêUGà–dO%*#‘¹(ZX¤Ü¦°)n¢L÷aV‰;±úüE×o\×]”Kæ.Z¿_9oSŦg#{0ž[¸;«í]&NÁ6Zãc\da5¢ ºÄjQ·‹‘qÏ>«ûY"j%x,–ÀÜTÿ|ÿ“ýÏöÿ _‰*ýö¹ÞÛÃÃ9¦–¸ÕK«?”®€„uÍ]#ç ¨6L¶êÂÈqòŠ\ùl%#?+w0ªÞ”i~€;yE¯¤cá ?A—ˆ½“ÈoÁÈG7T%+>NDÿ‰ý`¦eu`Ô0=,Èv‘ׯœ·É>‹5reÞ\Ö§D!¢TÓÜî';c[õ:µBí6—*4õ¥•mÏïMÿ¶Š3è–mŸh4·ú‚û¦²ªaµ±ÙQ«6rle£‘WÐQ[nW³&×àX;²Ë¥Khm.ƒÙèoª)öõô4ŽA¢„WÄ;ÆQóJJìåáþÀ3œ‡¯ Q¹ \ Pãjÿ”G£á€Ø-€–b€-Ÿ>­¶<¤!€¶kíïtü  ¿¥û9€ÞsIü¦¾·úqÎ틸;]#‡FqÌ~kß=…ÿ•éÈ^˜Æú=Ø¿uÿu?Ö`6±‰Mlb›ØÄ&þÿ$æ&r)J–+B-(f@£exAo€"ãF›Óå(óúü嬄P¸º¦¶"Ñ†ÆØz—vèèìêîéÝšìÛÖŸÚ>0¸chçðÈèØøÄdúá/ÿ_|¯6ðWYpA)x¡ÂP ­Ð½°†a ][Ã^rkø¡j Ú ’0ˆ­Ùµµµ¿|ÙQX÷//ÀÚí¯ìÁÀÞÂ,˜ ²eSAV¡T)kV¡Æ®{^&ƒLA¦°ÇÁ‚¬@ùTAV¡üN_÷¶ŽŽî`wv1{`þàîªÞÃÙ¹Ùéÿ¤ú ¶AÝDdaqæñ­»qöÀ ¹\ýW÷­Âu?ŒÏs0 ›÷¿ï‹+G>Ÿ¢&ßC#'ÑÂÐŒË:Cþ1ï# Nb £@I~Z¿Ã^Ò€JØ(ÿª®8ÐZepZ¸Bߦ¾UÐiy>¹ö²zŠo¹ %L®÷O¹WÚr÷£ío­v¬<¦fhÙd=æfþÇnäÄF endstream endobj 1700 0 obj << /Type /Encoding /Differences [ 1 /bullet ] >> endobj 1701 0 obj << /Filter /FlateDecode /Length 208 >> stream H‰T½Â0 „÷>…GCÚÎUX:ð# ìiâV‘ˆ¹éз')ÄKöåÓ-öÍ¡!@\Ø©ô†4ãè&V† (AÖn©ÊJ"Âí<´ õª*×(ŽgØ´³íÜs—oAœY#`s+î8h'ïŸh‘äP× ±ÏÄþ(ýIZŒòŠ.ób5tG/²¤¡Ê‹ú]ô¿ö!ºþÝþ¾Ve^–u‰–à´É×[MÌ1Ö²î’(e0„ß‹xç“ezÙK€CÈi? endstream endobj 1702 0 obj << /Type /Encoding /Differences [ 1 /barb4right ] >> endobj 1703 0 obj << /Producer (Acrobat Distiller 4.0 for Windows) /Creator () /ModDate (D:20091130164416+01'00') /Title (XML Configuration Reference for \013Synthesis SyncML\013Server & Client \ 3.4 Products\n) /CreationDate (D:20091130164308) >> endobj 1704 0 obj << /Type /Pages /Kids [ 1740 0 R 1 0 R 10 0 R 15 0 R 66 0 R 121 0 R 173 0 R 219 0 R 269 0 R 317 0 R ] /Count 10 /Parent 1705 0 R >> endobj 1705 0 obj << /Type /Pages /Kids [ 1704 0 R 1706 0 R 1707 0 R 1708 0 R 1709 0 R 1710 0 R 1711 0 R 1712 0 R 1713 0 R 1714 0 R ] /Count 100 /Parent 1715 0 R >> endobj 1706 0 obj << /Type /Pages /Kids [ 361 0 R 399 0 R 411 0 R 425 0 R 442 0 R 447 0 R 450 0 R 456 0 R 463 0 R 466 0 R ] /Count 10 /Parent 1705 0 R >> endobj 1707 0 obj << /Type /Pages /Kids [ 469 0 R 479 0 R 485 0 R 489 0 R 492 0 R 507 0 R 519 0 R 525 0 R 529 0 R 537 0 R ] /Count 10 /Parent 1705 0 R >> endobj 1708 0 obj << /Type /Pages /Kids [ 543 0 R 547 0 R 554 0 R 559 0 R 563 0 R 567 0 R 573 0 R 576 0 R 580 0 R 584 0 R ] /Count 10 /Parent 1705 0 R >> endobj 1709 0 obj << /Type /Pages /Kids [ 595 0 R 604 0 R 615 0 R 624 0 R 638 0 R 652 0 R 656 0 R 662 0 R 669 0 R 672 0 R ] /Count 10 /Parent 1705 0 R >> endobj 1710 0 obj << /Type /Pages /Kids [ 675 0 R 682 0 R 686 0 R 691 0 R 697 0 R 706 0 R 713 0 R 717 0 R 721 0 R 724 0 R ] /Count 10 /Parent 1705 0 R >> endobj 1711 0 obj << /Type /Pages /Kids [ 728 0 R 733 0 R 737 0 R 742 0 R 748 0 R 754 0 R 760 0 R 763 0 R 766 0 R 769 0 R ] /Count 10 /Parent 1705 0 R >> endobj 1712 0 obj << /Type /Pages /Kids [ 772 0 R 775 0 R 779 0 R 787 0 R 792 0 R 795 0 R 804 0 R 810 0 R 817 0 R 821 0 R ] /Count 10 /Parent 1705 0 R >> endobj 1713 0 obj << /Type /Pages /Kids [ 827 0 R 831 0 R 836 0 R 842 0 R 845 0 R 851 0 R 854 0 R 858 0 R 865 0 R 868 0 R ] /Count 10 /Parent 1705 0 R >> endobj 1714 0 obj << /Type /Pages /Kids [ 874 0 R 882 0 R 885 0 R 890 0 R 898 0 R 904 0 R 910 0 R 917 0 R 922 0 R 927 0 R ] /Count 10 /Parent 1705 0 R >> endobj 1715 0 obj << /Type /Pages /Kids [ 1705 0 R 1717 0 R 1727 0 R ] /Count 206 >> endobj 1716 0 obj << /Type /Pages /Kids [ 931 0 R 943 0 R 948 0 R 952 0 R 956 0 R 961 0 R 966 0 R 970 0 R 974 0 R 979 0 R ] /Count 10 /Parent 1717 0 R >> endobj 1717 0 obj << /Type /Pages /Kids [ 1716 0 R 1718 0 R 1719 0 R 1720 0 R 1721 0 R 1722 0 R 1723 0 R 1724 0 R 1725 0 R 1726 0 R ] /Count 100 /Parent 1715 0 R >> endobj 1718 0 obj << /Type /Pages /Kids [ 986 0 R 991 0 R 1004 0 R 1008 0 R 1016 0 R 1026 0 R 1032 0 R 1038 0 R 1042 0 R 1046 0 R ] /Count 10 /Parent 1717 0 R >> endobj 1719 0 obj << /Type /Pages /Kids [ 1054 0 R 1066 0 R 1074 0 R 1085 0 R 1098 0 R 1117 0 R 1126 0 R 1135 0 R 1144 0 R 1150 0 R ] /Count 10 /Parent 1717 0 R >> endobj 1720 0 obj << /Type /Pages /Kids [ 1159 0 R 1163 0 R 1168 0 R 1174 0 R 1190 0 R 1196 0 R 1204 0 R 1212 0 R 1225 0 R 1233 0 R ] /Count 10 /Parent 1717 0 R >> endobj 1721 0 obj << /Type /Pages /Kids [ 1241 0 R 1249 0 R 1254 0 R 1259 0 R 1264 0 R 1269 0 R 1273 0 R 1277 0 R 1283 0 R 1291 0 R ] /Count 10 /Parent 1717 0 R >> endobj 1722 0 obj << /Type /Pages /Kids [ 1297 0 R 1305 0 R 1323 0 R 1330 0 R 1340 0 R 1347 0 R 1352 0 R 1357 0 R 1365 0 R 1371 0 R ] /Count 10 /Parent 1717 0 R >> endobj 1723 0 obj << /Type /Pages /Kids [ 1379 0 R 1385 0 R 1393 0 R 1400 0 R 1411 0 R 1418 0 R 1428 0 R 1441 0 R 1446 0 R 1452 0 R ] /Count 10 /Parent 1717 0 R >> endobj 1724 0 obj << /Type /Pages /Kids [ 1458 0 R 1466 0 R 1472 0 R 1476 0 R 1485 0 R 1495 0 R 1501 0 R 1505 0 R 1513 0 R 1524 0 R ] /Count 10 /Parent 1717 0 R >> endobj 1725 0 obj << /Type /Pages /Kids [ 1539 0 R 1546 0 R 1552 0 R 1556 0 R 1562 0 R 1567 0 R 1574 0 R 1579 0 R 1583 0 R 1593 0 R ] /Count 10 /Parent 1717 0 R >> endobj 1726 0 obj << /Type /Pages /Kids [ 1596 0 R 1604 0 R 1610 0 R 1613 0 R 1616 0 R 1621 0 R 1627 0 R 1634 0 R 1637 0 R 1643 0 R ] /Count 10 /Parent 1717 0 R >> endobj 1727 0 obj << /Type /Pages /Kids [ 1647 0 R 1650 0 R 1653 0 R 1656 0 R 1659 0 R 1662 0 R ] /Count 6 /Parent 1715 0 R >> endobj 1728 0 obj << /Dt (D:20091130164416) /JTM (Distiller) >> endobj 1729 0 obj /This endobj 1730 0 obj << /CP (Distiller) /Fi 1729 0 R >> endobj 1731 0 obj << /R [ 600 600 ] >> endobj 1732 0 obj << /JTF 0 /MB [ 0 0 595 842 ] /R 1731 0 R /W [ 0 205 ] >> endobj 1733 0 obj << /Fi [ 1730 0 R ] /P [ 1732 0 R ] >> endobj 1734 0 obj << /Dm [ 595 842 595 842 ] >> endobj 1735 0 obj << /Me 1734 0 R >> endobj 1736 0 obj << /D [ 1733 0 R ] /MS 1735 0 R /Type /JobTicketContents >> endobj 1737 0 obj << /A [ 1728 0 R ] /Cn [ 1736 0 R ] /V 1.10001 >> endobj xref 0 1738 0000000000 65535 f 0000780552 00000 n 0000780754 00000 n 0000780923 00000 n 0000781105 00000 n 0000781298 00000 n 0000781463 00000 n 0000781630 00000 n 0000781806 00000 n 0000781988 00000 n 0000785462 00000 n 0000785645 00000 n 0000785805 00000 n 0000785965 00000 n 0000786134 00000 n 0000788417 00000 n 0000788926 00000 n 0000789084 00000 n 0000789242 00000 n 0000789401 00000 n 0000789560 00000 n 0000789719 00000 n 0000789878 00000 n 0000790037 00000 n 0000790196 00000 n 0000790355 00000 n 0000790514 00000 n 0000790673 00000 n 0000790832 00000 n 0000790991 00000 n 0000791150 00000 n 0000791309 00000 n 0000791468 00000 n 0000791627 00000 n 0000791786 00000 n 0000791945 00000 n 0000792104 00000 n 0000792263 00000 n 0000792422 00000 n 0000792581 00000 n 0000792740 00000 n 0000792899 00000 n 0000793058 00000 n 0000793217 00000 n 0000793376 00000 n 0000793535 00000 n 0000793694 00000 n 0000793853 00000 n 0000794012 00000 n 0000794171 00000 n 0000794330 00000 n 0000794489 00000 n 0000794648 00000 n 0000794807 00000 n 0000794966 00000 n 0000795125 00000 n 0000795284 00000 n 0000795443 00000 n 0000795602 00000 n 0000795761 00000 n 0000795920 00000 n 0000796079 00000 n 0000796237 00000 n 0000796394 00000 n 0000796551 00000 n 0000796735 00000 n 0000799129 00000 n 0000799688 00000 n 0000799847 00000 n 0000800006 00000 n 0000800165 00000 n 0000800324 00000 n 0000800483 00000 n 0000800642 00000 n 0000800801 00000 n 0000800960 00000 n 0000801119 00000 n 0000801278 00000 n 0000801437 00000 n 0000801596 00000 n 0000801755 00000 n 0000801914 00000 n 0000802073 00000 n 0000802232 00000 n 0000802391 00000 n 0000802550 00000 n 0000802709 00000 n 0000802868 00000 n 0000803027 00000 n 0000803186 00000 n 0000803345 00000 n 0000803504 00000 n 0000803663 00000 n 0000803822 00000 n 0000803981 00000 n 0000804140 00000 n 0000804299 00000 n 0000804458 00000 n 0000804617 00000 n 0000804776 00000 n 0000804935 00000 n 0000805095 00000 n 0000805255 00000 n 0000805415 00000 n 0000805575 00000 n 0000805735 00000 n 0000805895 00000 n 0000806055 00000 n 0000806215 00000 n 0000806375 00000 n 0000806535 00000 n 0000806695 00000 n 0000806855 00000 n 0000807015 00000 n 0000807175 00000 n 0000807335 00000 n 0000807495 00000 n 0000807654 00000 n 0000807812 00000 n 0000807970 00000 n 0000808155 00000 n 0000811289 00000 n 0000811859 00000 n 0000812019 00000 n 0000812179 00000 n 0000812339 00000 n 0000812499 00000 n 0000812659 00000 n 0000812819 00000 n 0000812979 00000 n 0000813139 00000 n 0000813299 00000 n 0000813459 00000 n 0000813619 00000 n 0000813779 00000 n 0000813939 00000 n 0000814099 00000 n 0000814259 00000 n 0000814419 00000 n 0000814579 00000 n 0000814739 00000 n 0000814899 00000 n 0000815059 00000 n 0000815219 00000 n 0000815379 00000 n 0000815539 00000 n 0000815699 00000 n 0000815859 00000 n 0000816019 00000 n 0000816179 00000 n 0000816339 00000 n 0000816499 00000 n 0000816659 00000 n 0000816819 00000 n 0000816979 00000 n 0000817139 00000 n 0000817299 00000 n 0000817459 00000 n 0000817619 00000 n 0000817779 00000 n 0000817939 00000 n 0000818099 00000 n 0000818259 00000 n 0000818419 00000 n 0000818579 00000 n 0000818739 00000 n 0000818899 00000 n 0000819059 00000 n 0000819219 00000 n 0000819378 00000 n 0000819536 00000 n 0000819694 00000 n 0000819879 00000 n 0000823286 00000 n 0000823807 00000 n 0000823967 00000 n 0000824127 00000 n 0000824287 00000 n 0000824447 00000 n 0000824607 00000 n 0000824767 00000 n 0000824927 00000 n 0000825087 00000 n 0000825247 00000 n 0000825407 00000 n 0000825567 00000 n 0000825727 00000 n 0000825887 00000 n 0000826047 00000 n 0000826207 00000 n 0000826367 00000 n 0000826527 00000 n 0000826687 00000 n 0000826847 00000 n 0000827007 00000 n 0000827167 00000 n 0000827327 00000 n 0000827487 00000 n 0000827647 00000 n 0000827807 00000 n 0000827967 00000 n 0000828127 00000 n 0000828287 00000 n 0000828447 00000 n 0000828608 00000 n 0000828769 00000 n 0000828930 00000 n 0000829091 00000 n 0000829252 00000 n 0000829413 00000 n 0000829574 00000 n 0000829735 00000 n 0000829896 00000 n 0000830057 00000 n 0000830218 00000 n 0000830379 00000 n 0000830538 00000 n 0000830697 00000 n 0000830868 00000 n 0000834248 00000 n 0000834801 00000 n 0000834962 00000 n 0000835123 00000 n 0000835284 00000 n 0000835445 00000 n 0000835606 00000 n 0000835767 00000 n 0000835928 00000 n 0000836089 00000 n 0000836250 00000 n 0000836411 00000 n 0000836572 00000 n 0000836733 00000 n 0000836894 00000 n 0000837055 00000 n 0000837216 00000 n 0000837377 00000 n 0000837538 00000 n 0000837699 00000 n 0000837860 00000 n 0000838021 00000 n 0000838182 00000 n 0000838343 00000 n 0000838504 00000 n 0000838665 00000 n 0000838826 00000 n 0000838987 00000 n 0000839148 00000 n 0000839309 00000 n 0000839470 00000 n 0000839631 00000 n 0000839793 00000 n 0000839955 00000 n 0000840117 00000 n 0000840279 00000 n 0000840441 00000 n 0000840603 00000 n 0000840765 00000 n 0000840926 00000 n 0000841087 00000 n 0000841248 00000 n 0000841409 00000 n 0000841570 00000 n 0000841731 00000 n 0000841892 00000 n 0000842052 00000 n 0000842211 00000 n 0000842370 00000 n 0000842541 00000 n 0000846028 00000 n 0000846565 00000 n 0000846726 00000 n 0000846887 00000 n 0000847048 00000 n 0000847209 00000 n 0000847370 00000 n 0000847531 00000 n 0000847692 00000 n 0000847853 00000 n 0000848014 00000 n 0000848175 00000 n 0000848336 00000 n 0000848497 00000 n 0000848658 00000 n 0000848819 00000 n 0000848980 00000 n 0000849141 00000 n 0000849302 00000 n 0000849463 00000 n 0000849624 00000 n 0000849785 00000 n 0000849946 00000 n 0000850107 00000 n 0000850268 00000 n 0000850429 00000 n 0000850590 00000 n 0000850751 00000 n 0000850912 00000 n 0000851073 00000 n 0000851234 00000 n 0000851395 00000 n 0000851556 00000 n 0000851717 00000 n 0000851878 00000 n 0000852039 00000 n 0000852200 00000 n 0000852361 00000 n 0000852522 00000 n 0000852683 00000 n 0000852844 00000 n 0000853005 00000 n 0000853166 00000 n 0000853327 00000 n 0000853488 00000 n 0000853647 00000 n 0000853806 00000 n 0000853991 00000 n 0000857394 00000 n 0000857899 00000 n 0000858060 00000 n 0000858221 00000 n 0000858382 00000 n 0000858543 00000 n 0000858704 00000 n 0000858865 00000 n 0000859026 00000 n 0000859187 00000 n 0000859348 00000 n 0000859509 00000 n 0000859670 00000 n 0000859831 00000 n 0000859992 00000 n 0000860153 00000 n 0000860314 00000 n 0000860475 00000 n 0000860636 00000 n 0000860797 00000 n 0000860958 00000 n 0000861119 00000 n 0000861280 00000 n 0000861441 00000 n 0000861602 00000 n 0000861763 00000 n 0000861924 00000 n 0000862085 00000 n 0000862246 00000 n 0000862407 00000 n 0000862568 00000 n 0000862729 00000 n 0000862890 00000 n 0000863051 00000 n 0000863212 00000 n 0000863373 00000 n 0000863534 00000 n 0000863695 00000 n 0000863856 00000 n 0000864017 00000 n 0000864177 00000 n 0000864336 00000 n 0000864495 00000 n 0000864680 00000 n 0000867853 00000 n 0000868309 00000 n 0000868470 00000 n 0000868631 00000 n 0000868792 00000 n 0000868953 00000 n 0000869114 00000 n 0000869275 00000 n 0000869436 00000 n 0000869597 00000 n 0000869758 00000 n 0000869919 00000 n 0000870080 00000 n 0000870241 00000 n 0000870402 00000 n 0000870563 00000 n 0000870724 00000 n 0000870885 00000 n 0000871046 00000 n 0000871207 00000 n 0000871368 00000 n 0000871529 00000 n 0000871690 00000 n 0000871851 00000 n 0000872012 00000 n 0000872173 00000 n 0000872334 00000 n 0000872495 00000 n 0000872656 00000 n 0000872817 00000 n 0000872978 00000 n 0000873139 00000 n 0000873300 00000 n 0000873461 00000 n 0000873622 00000 n 0000873783 00000 n 0000873944 00000 n 0000874129 00000 n 0000876617 00000 n 0000876853 00000 n 0000877035 00000 n 0000877196 00000 n 0000877357 00000 n 0000877518 00000 n 0000877679 00000 n 0000877839 00000 n 0000877999 00000 n 0000878157 00000 n 0000878353 00000 n 0000881791 00000 n 0000881866 00000 n 0000882127 00000 n 0000882288 00000 n 0000882449 00000 n 0000882610 00000 n 0000882770 00000 n 0000882932 00000 n 0000883094 00000 n 0000883255 00000 n 0000883416 00000 n 0000883578 00000 n 0000883738 00000 n 0000883898 00000 n 0000884094 00000 n 0000887623 00000 n 0000887908 00000 n 0000888069 00000 n 0000888229 00000 n 0000888390 00000 n 0000888551 00000 n 0000888712 00000 n 0000888872 00000 n 0000889032 00000 n 0000889193 00000 n 0000889354 00000 n 0000889515 00000 n 0000889676 00000 n 0000889837 00000 n 0000889998 00000 n 0000890157 00000 n 0000890353 00000 n 0000893866 00000 n 0000894054 00000 n 0000894216 00000 n 0000894378 00000 n 0000894587 00000 n 0000897992 00000 n 0000898151 00000 n 0000898306 00000 n 0000899290 00000 n 0000899486 00000 n 0000899647 00000 n 0000899808 00000 n 0000899969 00000 n 0000900165 00000 n 0000903410 00000 n 0000903614 00000 n 0000903775 00000 n 0000903937 00000 n 0000904098 00000 n 0000904260 00000 n 0000904455 00000 n 0000907548 00000 n 0000907707 00000 n 0000907917 00000 n 0000910578 00000 n 0000910737 00000 n 0000910919 00000 n 0000912377 00000 n 0000912605 00000 n 0000912766 00000 n 0000912927 00000 n 0000913088 00000 n 0000913249 00000 n 0000913410 00000 n 0000913571 00000 n 0000913732 00000 n 0000913944 00000 n 0000916962 00000 n 0000917158 00000 n 0000917319 00000 n 0000917480 00000 n 0000917641 00000 n 0000917853 00000 n 0000920503 00000 n 0000920683 00000 n 0000920844 00000 n 0000921069 00000 n 0000923480 00000 n 0000923639 00000 n 0000923835 00000 n 0000927267 00000 n 0000927536 00000 n 0000927697 00000 n 0000927859 00000 n 0000928021 00000 n 0000928183 00000 n 0000928345 00000 n 0000928506 00000 n 0000928667 00000 n 0000928829 00000 n 0000928991 00000 n 0000929152 00000 n 0000929314 00000 n 0000929474 00000 n 0000929671 00000 n 0000934017 00000 n 0000934262 00000 n 0000934422 00000 n 0000934584 00000 n 0000934745 00000 n 0000934906 00000 n 0000935067 00000 n 0000935228 00000 n 0000935389 00000 n 0000935550 00000 n 0000935710 00000 n 0000935922 00000 n 0000939068 00000 n 0000939264 00000 n 0000939445 00000 n 0000939605 00000 n 0000939766 00000 n 0000939950 00000 n 0000942809 00000 n 0000942989 00000 n 0000943150 00000 n 0000943360 00000 n 0000945928 00000 n 0000946140 00000 n 0000946301 00000 n 0000946462 00000 n 0000946623 00000 n 0000946784 00000 n 0000946945 00000 n 0000947157 00000 n 0000950723 00000 n 0000950919 00000 n 0000951080 00000 n 0000951241 00000 n 0000951402 00000 n 0000951600 00000 n 0000954486 00000 n 0000954666 00000 n 0000954826 00000 n 0000955051 00000 n 0000957762 00000 n 0000957966 00000 n 0000958127 00000 n 0000958287 00000 n 0000958448 00000 n 0000958609 00000 n 0000958834 00000 n 0000962536 00000 n 0000962724 00000 n 0000962885 00000 n 0000963046 00000 n 0000963271 00000 n 0000966291 00000 n 0000966471 00000 n 0000966632 00000 n 0000966801 00000 n 0000968708 00000 n 0000968888 00000 n 0000969049 00000 n 0000969233 00000 n 0000972047 00000 n 0000972243 00000 n 0000972404 00000 n 0000972564 00000 n 0000972726 00000 n 0000972936 00000 n 0000975146 00000 n 0000975305 00000 n 0000975490 00000 n 0000980736 00000 n 0000980916 00000 n 0000981083 00000 n 0000981268 00000 n 0000985985 00000 n 0000986165 00000 n 0000986326 00000 n 0000986497 00000 n 0000990967 00000 n 0000991203 00000 n 0000991364 00000 n 0000991525 00000 n 0000991686 00000 n 0000991847 00000 n 0000992008 00000 n 0000992169 00000 n 0000992330 00000 n 0000992491 00000 n 0000992662 00000 n 0000998240 00000 n 0000998460 00000 n 0000998621 00000 n 0000998782 00000 n 0000998943 00000 n 0000999104 00000 n 0000999266 00000 n 0000999428 00000 n 0000999640 00000 n 0001002886 00000 n 0001003122 00000 n 0001003283 00000 n 0001003444 00000 n 0001003605 00000 n 0001003766 00000 n 0001003927 00000 n 0001004088 00000 n 0001004249 00000 n 0001004410 00000 n 0001004595 00000 n 0001008710 00000 n 0001008930 00000 n 0001009091 00000 n 0001009253 00000 n 0001009414 00000 n 0001009576 00000 n 0001009737 00000 n 0001009898 00000 n 0001010083 00000 n 0001015020 00000 n 0001015281 00000 n 0001015442 00000 n 0001015603 00000 n 0001015764 00000 n 0001015926 00000 n 0001016088 00000 n 0001016249 00000 n 0001016411 00000 n 0001016573 00000 n 0001016735 00000 n 0001016896 00000 n 0001017057 00000 n 0001017228 00000 n 0001021590 00000 n 0001021851 00000 n 0001022012 00000 n 0001022174 00000 n 0001022336 00000 n 0001022498 00000 n 0001022660 00000 n 0001022821 00000 n 0001022982 00000 n 0001023143 00000 n 0001023304 00000 n 0001023465 00000 n 0001023625 00000 n 0001023810 00000 n 0001027710 00000 n 0001027890 00000 n 0001028052 00000 n 0001028208 00000 n 0001029373 00000 n 0001029569 00000 n 0001029730 00000 n 0001029891 00000 n 0001030053 00000 n 0001030265 00000 n 0001034773 00000 n 0001034977 00000 n 0001035138 00000 n 0001035299 00000 n 0001035460 00000 n 0001035621 00000 n 0001035833 00000 n 0001040380 00000 n 0001040539 00000 n 0001040764 00000 n 0001044684 00000 n 0001044843 00000 n 0001045068 00000 n 0001048109 00000 n 0001048313 00000 n 0001048474 00000 n 0001048635 00000 n 0001048796 00000 n 0001048958 00000 n 0001049156 00000 n 0001052563 00000 n 0001052743 00000 n 0001052904 00000 n 0001053060 00000 n 0001053964 00000 n 0001054152 00000 n 0001054311 00000 n 0001054472 00000 n 0001054655 00000 n 0001057025 00000 n 0001057221 00000 n 0001057382 00000 n 0001057543 00000 n 0001057701 00000 n 0001057871 00000 n 0001059972 00000 n 0001060192 00000 n 0001060353 00000 n 0001060513 00000 n 0001060674 00000 n 0001060835 00000 n 0001060996 00000 n 0001061155 00000 n 0001061367 00000 n 0001063699 00000 n 0001063903 00000 n 0001064064 00000 n 0001064225 00000 n 0001064386 00000 n 0001064547 00000 n 0001064759 00000 n 0001066994 00000 n 0001067174 00000 n 0001067335 00000 n 0001067545 00000 n 0001070637 00000 n 0001070817 00000 n 0001070978 00000 n 0001071160 00000 n 0001075357 00000 n 0001075516 00000 n 0001075726 00000 n 0001078343 00000 n 0001078502 00000 n 0001078732 00000 n 0001080783 00000 n 0001087523 00000 n 0001087711 00000 n 0001087872 00000 n 0001088033 00000 n 0001088229 00000 n 0001090458 00000 n 0001090638 00000 n 0001090799 00000 n 0001090995 00000 n 0001093520 00000 n 0001093708 00000 n 0001093868 00000 n 0001094030 00000 n 0001094240 00000 n 0001096968 00000 n 0001097164 00000 n 0001097325 00000 n 0001097485 00000 n 0001097647 00000 n 0001097843 00000 n 0001100690 00000 n 0001100886 00000 n 0001101047 00000 n 0001101208 00000 n 0001101369 00000 n 0001101539 00000 n 0001103616 00000 n 0001103812 00000 n 0001103973 00000 n 0001104135 00000 n 0001104296 00000 n 0001104479 00000 n 0001106733 00000 n 0001106892 00000 n 0001107047 00000 n 0001107638 00000 n 0001107797 00000 n 0001108022 00000 n 0001110735 00000 n 0001110894 00000 n 0001111090 00000 n 0001113703 00000 n 0001113862 00000 n 0001114032 00000 n 0001115820 00000 n 0001115979 00000 n 0001116175 00000 n 0001118362 00000 n 0001118542 00000 n 0001118703 00000 n 0001118899 00000 n 0001122069 00000 n 0001122281 00000 n 0001122443 00000 n 0001122602 00000 n 0001122764 00000 n 0001122926 00000 n 0001123085 00000 n 0001123281 00000 n 0001126457 00000 n 0001126645 00000 n 0001126806 00000 n 0001126967 00000 n 0001127149 00000 n 0001131299 00000 n 0001131458 00000 n 0001131683 00000 n 0001134792 00000 n 0001135012 00000 n 0001135173 00000 n 0001135334 00000 n 0001135495 00000 n 0001135656 00000 n 0001135817 00000 n 0001135976 00000 n 0001136188 00000 n 0001138913 00000 n 0001139109 00000 n 0001139270 00000 n 0001139431 00000 n 0001139592 00000 n 0001139831 00000 n 0001143391 00000 n 0001143595 00000 n 0001143756 00000 n 0001143917 00000 n 0001144079 00000 n 0001144240 00000 n 0001144451 00000 n 0001148537 00000 n 0001148717 00000 n 0001148878 00000 n 0001149103 00000 n 0001152439 00000 n 0001152635 00000 n 0001152797 00000 n 0001152958 00000 n 0001153119 00000 n 0001153316 00000 n 0001157492 00000 n 0001157672 00000 n 0001157833 00000 n 0001158058 00000 n 0001161362 00000 n 0001161550 00000 n 0001161711 00000 n 0001161872 00000 n 0001162097 00000 n 0001165094 00000 n 0001165290 00000 n 0001165451 00000 n 0001165612 00000 n 0001165773 00000 n 0001165984 00000 n 0001169390 00000 n 0001169549 00000 n 0001169774 00000 n 0001173476 00000 n 0001173672 00000 n 0001173833 00000 n 0001173994 00000 n 0001174156 00000 n 0001174367 00000 n 0001178268 00000 n 0001178427 00000 n 0001178582 00000 n 0001180557 00000 n 0001180737 00000 n 0001180898 00000 n 0001181108 00000 n 0001183221 00000 n 0001183425 00000 n 0001183586 00000 n 0001183747 00000 n 0001183908 00000 n 0001184067 00000 n 0001184263 00000 n 0001187008 00000 n 0001187167 00000 n 0001187392 00000 n 0001189743 00000 n 0001189939 00000 n 0001190100 00000 n 0001190261 00000 n 0001190422 00000 n 0001190634 00000 n 0001194842 00000 n 0001195054 00000 n 0001195215 00000 n 0001195376 00000 n 0001195537 00000 n 0001195698 00000 n 0001195859 00000 n 0001196069 00000 n 0001199224 00000 n 0001199383 00000 n 0001199566 00000 n 0001201759 00000 n 0001201947 00000 n 0001202108 00000 n 0001202269 00000 n 0001202439 00000 n 0001204913 00000 n 0001205125 00000 n 0001205286 00000 n 0001205447 00000 n 0001205608 00000 n 0001205769 00000 n 0001205930 00000 n 0001206100 00000 n 0001208448 00000 n 0001208644 00000 n 0001208806 00000 n 0001208967 00000 n 0001209128 00000 n 0001209313 00000 n 0001212321 00000 n 0001212517 00000 n 0001212679 00000 n 0001212840 00000 n 0001213002 00000 n 0001213186 00000 n 0001216190 00000 n 0001216394 00000 n 0001216555 00000 n 0001216717 00000 n 0001216879 00000 n 0001217040 00000 n 0001217225 00000 n 0001220947 00000 n 0001221135 00000 n 0001221296 00000 n 0001221457 00000 n 0001221655 00000 n 0001224982 00000 n 0001225170 00000 n 0001225331 00000 n 0001225492 00000 n 0001225690 00000 n 0001228930 00000 n 0001229110 00000 n 0001229271 00000 n 0001229467 00000 n 0001232203 00000 n 0001232448 00000 n 0001232610 00000 n 0001232772 00000 n 0001232934 00000 n 0001233096 00000 n 0001233258 00000 n 0001233420 00000 n 0001233582 00000 n 0001233744 00000 n 0001233906 00000 n 0001234102 00000 n 0001236880 00000 n 0001237068 00000 n 0001237230 00000 n 0001237391 00000 n 0001237561 00000 n 0001240408 00000 n 0001240588 00000 n 0001240749 00000 n 0001240945 00000 n 0001243787 00000 n 0001243967 00000 n 0001244129 00000 n 0001244299 00000 n 0001246907 00000 n 0001247095 00000 n 0001247257 00000 n 0001247418 00000 n 0001247601 00000 n 0001250139 00000 n 0001250327 00000 n 0001250489 00000 n 0001250650 00000 n 0001250820 00000 n 0001252754 00000 n 0001252934 00000 n 0001253094 00000 n 0001253279 00000 n 0001256664 00000 n 0001256844 00000 n 0001257005 00000 n 0001257175 00000 n 0001259386 00000 n 0001259574 00000 n 0001259736 00000 n 0001259897 00000 n 0001260067 00000 n 0001262162 00000 n 0001262366 00000 n 0001262527 00000 n 0001262689 00000 n 0001262850 00000 n 0001263012 00000 n 0001263197 00000 n 0001265701 00000 n 0001265889 00000 n 0001266050 00000 n 0001266212 00000 n 0001266397 00000 n 0001268935 00000 n 0001269192 00000 n 0001269353 00000 n 0001269515 00000 n 0001269674 00000 n 0001269836 00000 n 0001269998 00000 n 0001270160 00000 n 0001270322 00000 n 0001270483 00000 n 0001270646 00000 n 0001270809 00000 n 0001270995 00000 n 0001273773 00000 n 0001273957 00000 n 0001274119 00000 n 0001274276 00000 n 0001276440 00000 n 0001276660 00000 n 0001276822 00000 n 0001276985 00000 n 0001277148 00000 n 0001277310 00000 n 0001277473 00000 n 0001277659 00000 n 0001280909 00000 n 0001281147 00000 n 0001281310 00000 n 0001281473 00000 n 0001281636 00000 n 0001281799 00000 n 0001281962 00000 n 0001282125 00000 n 0001282288 00000 n 0001282474 00000 n 0001286695 00000 n 0001286897 00000 n 0001287060 00000 n 0001287223 00000 n 0001287386 00000 n 0001287585 00000 n 0001290184 00000 n 0001290386 00000 n 0001290549 00000 n 0001290712 00000 n 0001290874 00000 n 0001291060 00000 n 0001293390 00000 n 0001293574 00000 n 0001293737 00000 n 0001293908 00000 n 0001296058 00000 n 0001296242 00000 n 0001296404 00000 n 0001296601 00000 n 0001299674 00000 n 0001299894 00000 n 0001300057 00000 n 0001300218 00000 n 0001300380 00000 n 0001300543 00000 n 0001300706 00000 n 0001300917 00000 n 0001304105 00000 n 0001304362 00000 n 0001304524 00000 n 0001304686 00000 n 0001304848 00000 n 0001305010 00000 n 0001305172 00000 n 0001305334 00000 n 0001305496 00000 n 0001305658 00000 n 0001305821 00000 n 0001306020 00000 n 0001308431 00000 n 0001308651 00000 n 0001308814 00000 n 0001308976 00000 n 0001309138 00000 n 0001309300 00000 n 0001309462 00000 n 0001309648 00000 n 0001312066 00000 n 0001312314 00000 n 0001312476 00000 n 0001312638 00000 n 0001312800 00000 n 0001312962 00000 n 0001313125 00000 n 0001313287 00000 n 0001313450 00000 n 0001313612 00000 n 0001313798 00000 n 0001316670 00000 n 0001316936 00000 n 0001317098 00000 n 0001317260 00000 n 0001317422 00000 n 0001317585 00000 n 0001317747 00000 n 0001317910 00000 n 0001318072 00000 n 0001318234 00000 n 0001318396 00000 n 0001318556 00000 n 0001318728 00000 n 0001322977 00000 n 0001323298 00000 n 0001323460 00000 n 0001323622 00000 n 0001323784 00000 n 0001323946 00000 n 0001324108 00000 n 0001324270 00000 n 0001324432 00000 n 0001324595 00000 n 0001324757 00000 n 0001324920 00000 n 0001325083 00000 n 0001325246 00000 n 0001325409 00000 n 0001325572 00000 n 0001325735 00000 n 0001325898 00000 n 0001326070 00000 n 0001330376 00000 n 0001330596 00000 n 0001330780 00000 n 0001330943 00000 n 0001331105 00000 n 0001331267 00000 n 0001331430 00000 n 0001331616 00000 n 0001335627 00000 n 0001335690 00000 n 0001335919 00000 n 0001336082 00000 n 0001336245 00000 n 0001336408 00000 n 0001336571 00000 n 0001336733 00000 n 0001336894 00000 n 0001337080 00000 n 0001339350 00000 n 0001339579 00000 n 0001339741 00000 n 0001339901 00000 n 0001340064 00000 n 0001340227 00000 n 0001340390 00000 n 0001340553 00000 n 0001340739 00000 n 0001344038 00000 n 0001344240 00000 n 0001344403 00000 n 0001344566 00000 n 0001344729 00000 n 0001344915 00000 n 0001347552 00000 n 0001347781 00000 n 0001347944 00000 n 0001348107 00000 n 0001348269 00000 n 0001348432 00000 n 0001348595 00000 n 0001348758 00000 n 0001348929 00000 n 0001351183 00000 n 0001351367 00000 n 0001351529 00000 n 0001351742 00000 n 0001354478 00000 n 0001354671 00000 n 0001354834 00000 n 0001354995 00000 n 0001355181 00000 n 0001357551 00000 n 0001357753 00000 n 0001357916 00000 n 0001358079 00000 n 0001358242 00000 n 0001358413 00000 n 0001360907 00000 n 0001361200 00000 n 0001361363 00000 n 0001361526 00000 n 0001361688 00000 n 0001361851 00000 n 0001362014 00000 n 0001362177 00000 n 0001362340 00000 n 0001362500 00000 n 0001362663 00000 n 0001362826 00000 n 0001362989 00000 n 0001363152 00000 n 0001363315 00000 n 0001363528 00000 n 0001366202 00000 n 0001366404 00000 n 0001366566 00000 n 0001366728 00000 n 0001366891 00000 n 0001367089 00000 n 0001371143 00000 n 0001371363 00000 n 0001371526 00000 n 0001371688 00000 n 0001371851 00000 n 0001372014 00000 n 0001372177 00000 n 0001372389 00000 n 0001376436 00000 n 0001376656 00000 n 0001376819 00000 n 0001376982 00000 n 0001377145 00000 n 0001377308 00000 n 0001377470 00000 n 0001377669 00000 n 0001380780 00000 n 0001381046 00000 n 0001381209 00000 n 0001381372 00000 n 0001381535 00000 n 0001381698 00000 n 0001381861 00000 n 0001382024 00000 n 0001382187 00000 n 0001382349 00000 n 0001382512 00000 n 0001382674 00000 n 0001382860 00000 n 0001386724 00000 n 0001386944 00000 n 0001387107 00000 n 0001387270 00000 n 0001387433 00000 n 0001387595 00000 n 0001387758 00000 n 0001387957 00000 n 0001391082 00000 n 0001391302 00000 n 0001391465 00000 n 0001391628 00000 n 0001391791 00000 n 0001391954 00000 n 0001392116 00000 n 0001392315 00000 n 0001395083 00000 n 0001395303 00000 n 0001395466 00000 n 0001395629 00000 n 0001395792 00000 n 0001395955 00000 n 0001396118 00000 n 0001396317 00000 n 0001399501 00000 n 0001399694 00000 n 0001399856 00000 n 0001400018 00000 n 0001400217 00000 n 0001402668 00000 n 0001402861 00000 n 0001403024 00000 n 0001403186 00000 n 0001403399 00000 n 0001405951 00000 n 0001406144 00000 n 0001406306 00000 n 0001406469 00000 n 0001406695 00000 n 0001409286 00000 n 0001409479 00000 n 0001409641 00000 n 0001409801 00000 n 0001409987 00000 n 0001412186 00000 n 0001412370 00000 n 0001412533 00000 n 0001412719 00000 n 0001415260 00000 n 0001415444 00000 n 0001415605 00000 n 0001415776 00000 n 0001417778 00000 n 0001417980 00000 n 0001418142 00000 n 0001418304 00000 n 0001418466 00000 n 0001418637 00000 n 0001420740 00000 n 0001420960 00000 n 0001421121 00000 n 0001421283 00000 n 0001421446 00000 n 0001421609 00000 n 0001421770 00000 n 0001421967 00000 n 0001424213 00000 n 0001424415 00000 n 0001424577 00000 n 0001424739 00000 n 0001424901 00000 n 0001425098 00000 n 0001427153 00000 n 0001427373 00000 n 0001427536 00000 n 0001427698 00000 n 0001427861 00000 n 0001428024 00000 n 0001428187 00000 n 0001428413 00000 n 0001431593 00000 n 0001431904 00000 n 0001432067 00000 n 0001432230 00000 n 0001432393 00000 n 0001432556 00000 n 0001432719 00000 n 0001432882 00000 n 0001433045 00000 n 0001433208 00000 n 0001433370 00000 n 0001433533 00000 n 0001433695 00000 n 0001433858 00000 n 0001434021 00000 n 0001434184 00000 n 0001434345 00000 n 0001434531 00000 n 0001438279 00000 n 0001438490 00000 n 0001438653 00000 n 0001438815 00000 n 0001438977 00000 n 0001439138 00000 n 0001439324 00000 n 0001443139 00000 n 0001443377 00000 n 0001443539 00000 n 0001443702 00000 n 0001443865 00000 n 0001444028 00000 n 0001444191 00000 n 0001444353 00000 n 0001444516 00000 n 0001444702 00000 n 0001448696 00000 n 0001448907 00000 n 0001449070 00000 n 0001449233 00000 n 0001449396 00000 n 0001449559 00000 n 0001449745 00000 n 0001453553 00000 n 0001453746 00000 n 0001453909 00000 n 0001454072 00000 n 0001454271 00000 n 0001456702 00000 n 0001456895 00000 n 0001457058 00000 n 0001457220 00000 n 0001457391 00000 n 0001459413 00000 n 0001459633 00000 n 0001459796 00000 n 0001459957 00000 n 0001460120 00000 n 0001460282 00000 n 0001460442 00000 n 0001460639 00000 n 0001463335 00000 n 0001463537 00000 n 0001463698 00000 n 0001463861 00000 n 0001464024 00000 n 0001464221 00000 n 0001466925 00000 n 0001467145 00000 n 0001467308 00000 n 0001467471 00000 n 0001467634 00000 n 0001467797 00000 n 0001467958 00000 n 0001468171 00000 n 0001471982 00000 n 0001472184 00000 n 0001472347 00000 n 0001472510 00000 n 0001472673 00000 n 0001472884 00000 n 0001475608 00000 n 0001475828 00000 n 0001475991 00000 n 0001476154 00000 n 0001476317 00000 n 0001476480 00000 n 0001476643 00000 n 0001476854 00000 n 0001479926 00000 n 0001480137 00000 n 0001480300 00000 n 0001480462 00000 n 0001480624 00000 n 0001480785 00000 n 0001480969 00000 n 0001483463 00000 n 0001483711 00000 n 0001483874 00000 n 0001484037 00000 n 0001484200 00000 n 0001484363 00000 n 0001484526 00000 n 0001484689 00000 n 0001484852 00000 n 0001485014 00000 n 0001485185 00000 n 0001488003 00000 n 0001488214 00000 n 0001488377 00000 n 0001488540 00000 n 0001488703 00000 n 0001488866 00000 n 0001489092 00000 n 0001492073 00000 n 0001492311 00000 n 0001492474 00000 n 0001492637 00000 n 0001492800 00000 n 0001492963 00000 n 0001493126 00000 n 0001493289 00000 n 0001493452 00000 n 0001493609 00000 n 0001495904 00000 n 0001496170 00000 n 0001496333 00000 n 0001496496 00000 n 0001496659 00000 n 0001496822 00000 n 0001496985 00000 n 0001497148 00000 n 0001497311 00000 n 0001497474 00000 n 0001497637 00000 n 0001497798 00000 n 0001497981 00000 n 0001501470 00000 n 0001501663 00000 n 0001501826 00000 n 0001501989 00000 n 0001502199 00000 n 0001505257 00000 n 0001505459 00000 n 0001505622 00000 n 0001505785 00000 n 0001505946 00000 n 0001506159 00000 n 0001508815 00000 n 0001509017 00000 n 0001509180 00000 n 0001509343 00000 n 0001509506 00000 n 0001509718 00000 n 0001513456 00000 n 0001513676 00000 n 0001513839 00000 n 0001514002 00000 n 0001514163 00000 n 0001514326 00000 n 0001514487 00000 n 0001514700 00000 n 0001517574 00000 n 0001517776 00000 n 0001517934 00000 n 0001518096 00000 n 0001518259 00000 n 0001518456 00000 n 0001521092 00000 n 0001521276 00000 n 0001521437 00000 n 0001521608 00000 n 0001523483 00000 n 0001523712 00000 n 0001523875 00000 n 0001524038 00000 n 0001524201 00000 n 0001524363 00000 n 0001524526 00000 n 0001524689 00000 n 0001524915 00000 n 0001528211 00000 n 0001528449 00000 n 0001528612 00000 n 0001528775 00000 n 0001528938 00000 n 0001529101 00000 n 0001529264 00000 n 0001529427 00000 n 0001529590 00000 n 0001529776 00000 n 0001532904 00000 n 0001533106 00000 n 0001533269 00000 n 0001533432 00000 n 0001533595 00000 n 0001533792 00000 n 0001536665 00000 n 0001536849 00000 n 0001537012 00000 n 0001537224 00000 n 0001541405 00000 n 0001541625 00000 n 0001541788 00000 n 0001541948 00000 n 0001542111 00000 n 0001542274 00000 n 0001542436 00000 n 0001542647 00000 n 0001546695 00000 n 0001546943 00000 n 0001547105 00000 n 0001547268 00000 n 0001547430 00000 n 0001547593 00000 n 0001547756 00000 n 0001547919 00000 n 0001548082 00000 n 0001548245 00000 n 0001548458 00000 n 0001552014 00000 n 0001552298 00000 n 0001552461 00000 n 0001552624 00000 n 0001552786 00000 n 0001552949 00000 n 0001553112 00000 n 0001553275 00000 n 0001553437 00000 n 0001553599 00000 n 0001553762 00000 n 0001553925 00000 n 0001554088 00000 n 0001554251 00000 n 0001554423 00000 n 0001558252 00000 n 0001558463 00000 n 0001558626 00000 n 0001558789 00000 n 0001558951 00000 n 0001559113 00000 n 0001559326 00000 n 0001561955 00000 n 0001562157 00000 n 0001562320 00000 n 0001562483 00000 n 0001562645 00000 n 0001562831 00000 n 0001564971 00000 n 0001565155 00000 n 0001565318 00000 n 0001565489 00000 n 0001566337 00000 n 0001566539 00000 n 0001566701 00000 n 0001566864 00000 n 0001567027 00000 n 0001567253 00000 n 0001569785 00000 n 0001569978 00000 n 0001570141 00000 n 0001570304 00000 n 0001570488 00000 n 0001572660 00000 n 0001572871 00000 n 0001573034 00000 n 0001573197 00000 n 0001573360 00000 n 0001573522 00000 n 0001573734 00000 n 0001576304 00000 n 0001576497 00000 n 0001576659 00000 n 0001576821 00000 n 0001577033 00000 n 0001579840 00000 n 0001580024 00000 n 0001580186 00000 n 0001580357 00000 n 0001582449 00000 n 0001582687 00000 n 0001582870 00000 n 0001583032 00000 n 0001583195 00000 n 0001583358 00000 n 0001583520 00000 n 0001583680 00000 n 0001583843 00000 n 0001584014 00000 n 0001586416 00000 n 0001586578 00000 n 0001586721 00000 n 0001587532 00000 n 0001587752 00000 n 0001587915 00000 n 0001588077 00000 n 0001588240 00000 n 0001588403 00000 n 0001588565 00000 n 0001588736 00000 n 0001591021 00000 n 0001591223 00000 n 0001591386 00000 n 0001591547 00000 n 0001591710 00000 n 0001591881 00000 n 0001594053 00000 n 0001594215 00000 n 0001594386 00000 n 0001596372 00000 n 0001596534 00000 n 0001596731 00000 n 0001598608 00000 n 0001598801 00000 n 0001598964 00000 n 0001599126 00000 n 0001599297 00000 n 0001601477 00000 n 0001601679 00000 n 0001601842 00000 n 0001602005 00000 n 0001602165 00000 n 0001602362 00000 n 0001604889 00000 n 0001605100 00000 n 0001605262 00000 n 0001605423 00000 n 0001605585 00000 n 0001605746 00000 n 0001605917 00000 n 0001607020 00000 n 0001607182 00000 n 0001607353 00000 n 0001611867 00000 n 0001612069 00000 n 0001612279 00000 n 0001612488 00000 n 0001612650 00000 n 0001612821 00000 n 0001614878 00000 n 0001615062 00000 n 0001615225 00000 n 0001615396 00000 n 0001617783 00000 n 0001617945 00000 n 0001618102 00000 n 0001619101 00000 n 0001619263 00000 n 0001619420 00000 n 0001622325 00000 n 0001622487 00000 n 0001622630 00000 n 0001626086 00000 n 0001626248 00000 n 0001626391 00000 n 0001627865 00000 n 0001628027 00000 n 0001628170 00000 n 0001630948 00000 n 0001631110 00000 n 0001631253 00000 n 0001633423 00000 n 0001633894 00000 n 0001634509 00000 n 0001634737 00000 n 0001634930 00000 n 0001635114 00000 n 0001635903 00000 n 0001636697 00000 n 0001637198 00000 n 0001637252 00000 n 0001637556 00000 n 0001637740 00000 n 0001637915 00000 n 0001638099 00000 n 0001638744 00000 n 0001645348 00000 n 0001645572 00000 n 0001645916 00000 n 0001646129 00000 n 0001646302 00000 n 0001646686 00000 n 0001649806 00000 n 0001650019 00000 n 0001650192 00000 n 0001650413 00000 n 0001650649 00000 n 0001650862 00000 n 0001651035 00000 n 0001651246 00000 n 0001672409 00000 n 0001672627 00000 n 0001708497 00000 n 0001708718 00000 n 0001717100 00000 n 0001717320 00000 n 0001745928 00000 n 0001745999 00000 n 0001746283 00000 n 0001746358 00000 n 0001746608 00000 n 0001746765 00000 n 0001746937 00000 n 0001747098 00000 n 0001747259 00000 n 0001747420 00000 n 0001747581 00000 n 0001747742 00000 n 0001747903 00000 n 0001748064 00000 n 0001748225 00000 n 0001748386 00000 n 0001748476 00000 n 0001748637 00000 n 0001748809 00000 n 0001748978 00000 n 0001749149 00000 n 0001749320 00000 n 0001749491 00000 n 0001749662 00000 n 0001749833 00000 n 0001750004 00000 n 0001750175 00000 n 0001750346 00000 n 0001750479 00000 n 0001750545 00000 n 0001750570 00000 n 0001750626 00000 n 0001750668 00000 n 0001750750 00000 n 0001750811 00000 n 0001750862 00000 n 0001750902 00000 n 0001750985 00000 n trailer << /Size 1738 /ID[] >> startxref 173 %%EOF libsynthesis-3.4.0.47.1/doc/SySync_script_call_flow.numbers/000077500000000000000000000000001226375725500237215ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/doc/SySync_script_call_flow.numbers/Contents/000077500000000000000000000000001226375725500255165ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/doc/SySync_script_call_flow.numbers/Contents/PkgInfo000066400000000000000000000000101226375725500267650ustar00rootroot00000000000000????????libsynthesis-3.4.0.47.1/doc/SySync_script_call_flow.numbers/QuickLook/000077500000000000000000000000001226375725500256225ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/doc/SySync_script_call_flow.numbers/QuickLook/Thumbnail.jpg000066400000000000000000001425151226375725500302570ustar00rootroot00000000000000ÿØÿàJFIFÿâICC_PROFILEðapplmntrRGB XYZ Ø acspAPPLöÖÓ-applÆwÎ×–ž¿LmfõhŠúirXYZ,gXYZ@bXYZTwtpthchad|,rTRC¨gTRC¸bTRCÈvcgtØ0ndin8desc@edscm¨ümmod¤(cprtÌ$XYZ w0?D—XYZ Y¬ö›XYZ &–ܹóXYZ óØsf32 ·–ÿÿóW)ý×ÿÿû·ÿÿý¦ÚÀöcurvÍcurvÍcurvÍvcgtÑtÑtÑtndin0£@W€Kœ&·›P@T@333333desc LCD2080UX+mluc nbNOèptPTèsvSEèfiFIèdaDKèzhCNèfrFRèjaJPèenUSèplPLèptBRèesESèzhTWèruRUèkoKRèdeDEènlNLèitITèLCD2080UX+mmod8£f+¼ÈktextCopyright Apple, Inc., 2008ÿá@ExifMM*‡i  jÿÛC    ÿÛCÿÀj"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?þþ(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¯Ãø*oü[â‡ìñ‹áOÃ?|>ø%áÏkþ¼××âÅ]gUÒ<1©jpÜ—Ã°ÞØÙ\Egzéûß6õ¢€#§$澘?ðT߀gÅ_†ŸußüSÖ>)êÚO…ï¼K'ƒ~Ñ?¼1ñsJÿ„âãHÒ¼3à»? \]x«YÖuŒiPééûÃsµ%fB@UŠFfI¯Ÿ¾*ÁceƒŸ¾ü\ñ·„?j†¾(¶kÛÍeþjp[x&Ôœí«™Ñ ›-Ñ1ù`<„)!Œ«Õº+ðGRÿ‚Ãø÷OøÕâ/…×¼ g£Xü]ø³ðݵI5K—)gá_E¯C|ѤD–ä1Içj.å,ÇÞx{þ û)é~ø^ßtâ{ÿü>ñ_‹5? ø;P¿ðç„m¼S gNº¹¼dSolóH"Ue†S‡*ûeE~`ißðW_ÙWý¥ôÿÙwIã6£â»ßˆwŸ ´ïÇàû¿øFu/ÙÛKq}¦Ã¨!ymV&YGgáwáŠ÷ßॳÏÂÚÿ±ž©¤|cñÆMBÓI¿¿_ øVãS³ðÕ®£s%µœ÷²EóÇ’E /H±ªï”Ƹjý¢¿,4¯ø,§ì'¨|Kø½ðæÿǾ-ðÅŸƒì|U?Šu_ÜÛø{^_®uØôëÍ¥o$°çÍT;XÇæ$r~ÿ‚ÚþÆÞ5·ÖZ} öð©a/‚’çMñO€îô«Á‰õ&ÓôiÖ9°^)ä÷®BÆÀžC(ý{¢¿+~+Áb¿c¯„‰âËMPüañw‹tˆzÿÃi|;áÏ \jZ­Þ££YC{ªÜÃg/gkoq¼äóPÌBžoÆ_ð[¯Ø[Áþ%°Ñ£Õ¾/øÇÃo¥x/Ä7¾+Ð<y} èº7‰Š®‘¨Þ] ÛoÎèŸ8Þñ°áÊ€~»Q_šcþ Éû!Gñ[âÿÃKûÿ‹W‡¼'ˆ-5ÿÏàÍCþØoô[f¹ÕìWUXÌ&{HÑüÅ8RèÑ£;µè_²ü?öý¶t/‰ZŸÁû/ŠZWˆ<' …î¯á¿xn}+Y[ëf¹Óïc¶—™ »‰¡p~bŒ¤+ îª+ùßý›à¾~ ñÇÁíSãíð/âç‚nuÿx³Bøqàoø;UÖ¼M«è ­£«\@# åÛ` Þ3²)KCóȤÐO†ðTÏÙcãgÇ³ÇÁ†ø­ñcÄž)ð~“ãû-sBðµÍƃa j÷3Z^Þ^à%¢Éöi" 沦ÜîÚú9E?ßµüâçÀoø(%Ïì‚¿ ¾xÂðj´Ñ®>&x¯PðÝ÷Å85/í7ãY>’ÍhÒŒ7),²Dê dW׿ðXØ®Ãã/ů‚·÷Äa¬xF?G>µÿÕÀÑ5ÍK@±kígI°¼?%Íí¤ #IÀýÜYŠ6?Rh¯È/Áo?box/ÅŸ5X>;ü3ðnŸðÏPø½§Þø·ÁWZJø¯Âö’A—zbËó]î{«uTþ|erï4¿ø+Ïì}©üyÙåî¾*i^/YL}JóÃÅ£ÇâÒ?µåðñ¼ÿWý§–dh:­òãe~ Ñ_ž?ࢾý¨¿cÿжìÑðgãÿÄ/ hÚö¯áUðÌú-ïĆÃíQG¦¬à™Òg"•T©”8]Øçó{ö9ÿ‚íiÿ>|aø»ûIÙþÏÚGß Øxzó[o‡Zî§y®øëRÔÁ¬5ÍT³µ½µû4²Æd¼^ÛhƒòÐô_E~[|Kÿ‚½þÊ_ ¼k¬ü;]ã×Äo[øïZøke§xGÁ—:¼Ú½* NúÎÍa9˜Ã«¿²$ªÌ61òÿÁh?b«3àV±á)>9|MÓüuá+?#xWÀZ–¬þðýÍãXŨjñÁ=”mv’Á‚¬ûà—åÚ…¨õ†Šü˜ÿ‚«ÿÁC¼ûxcàNµá/xO ø»\¼Òµ¿ˆ>6mY<'àŠÛ΄ê-¥Z\Ý!ºÝDû%(åØ\_ð[/Ù»á·ÁÏÙׯ¿´y‡Lñ׌¼!/Žu¨>ÎÞ8Ð|)áè¯EœšõÆ¥hŠ‹§Š!_1Iuhó„~ÑÑ_š^ÿ‚°þÉÞ,ø÷ñ‡à6‚ßu9<ý«Š<_oá[™ü3¥Üéö"úòÚKÈ÷xàmÀº,r’7‘°§Äí¿à²¾'þÏ6´ÀÏ|BÓü57Ž< á‹[¿xfûM²×,¼A©Ãioyc-ºÊ·–B@È1¾Á:Äý™¢¿,´Ïø,_ìYªü\ñ—Â;}câ”2éŸð”[éÞ%ŸÂW‘xwÅÚŽ“ën—¨2ˆon­c†bñ©ù2lgÚqß~Ç?ðS¯Ù§öâñ†¡ào„_|?âðn“ñLÅÞºÑWÄ~¿vŽ NŦéy¨Ñù‡Ë¹HbúEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPæGí­ÿëñ7íaã]CÆžý±~;þÍÉ­ø&ãáçŒ4-"ÓNÖt?è²Êòn6:œ3Amx†Io"Q(V rqå^ÿ‚>øsà_Ä¿ø£öbý¬?hßÙïá¼:<9ã hïa:øâÓÂÐ-¶˜&½šºµ/n¢ Ÿ³² ãʹ&¿c( Èmþ -à/üý™¾xkâŽu™¾üEñgÅ K¨-c:Þ£¬G¬³¸Ú $(uy6²a¿t™'-Ÿÿeø v¿¨~ÅÞ øKûhþПµÇð Sø-¦èVCJ{/†6ÚÄ7:ƒYÜA½û™mm‚=Ã>Ø£òÆs‘ý8Ñ@Ÿ?´ì#{ûBüý>x‹öƒñï‡~:|-ñã |NÓ49oa×ìm¥¶û\¶YÉÐÜ\$–û/ øö–ÿ‚ xö­Ñ¼9iñ“öÝý£¾ x’ËàíW\ñ&™£kwR¾«.§ý£f.-JiSù²y m ZEwèŠüuÕàŽ_ µˆ> ø‰uñŸâBêzÄˆßæ--Iwâ¿ Ç ][¯ÉŸ.£FIÜ\įÇAÿ?øCÁ¯‹ÿ“ã—Å#¥øÃáç‡wWßd³ó¬í¼êÖ—1›L—;Gš\ü€WíÝüÀøWþ û`ØÁH¾x³NÐüCàØãŸ´/‰þ:[Cuã}+RÐä“SÓ¯RW³´ŽÎ=R;»‹«²í Ämn­?—$›À¡ÿ¶÷üGáßíÉû@|/øéãŒ>0ð„žŸF¸¶³Ót !õ 4ûãx­§jÏlu4ÎØŽqÅ$@El±ýo¢€? <7ÿý–t_~Ò7º‡Šõ}gá§Ä-?ÆÖ_ð è0_è'ÄÛÿ´=e,ÿ´æXüÙ…ºI6Ø–VR$@ð­#þ­ñ»Å?imãWíIñ#Ç~ Ö|ð¦ÏÁ?¥³ÑâÖ´­{ºÕåý²gÃÛ´Q¢–2£yÍ4äœôþ”( çóÆßð@…>>Ó_[ñ?íãÿ|i‰^*ø•/‹|AàÿkOs¯ØYÚj6¯¦]YµLÙC, "¨ÚH>Ñâø"ÏÁm{Á´_€4ïŠÞ>ðÖñÁÿ üp–Zn èöÞ¸óíe‚8¡HC\¶|Õ±®O–¨8¯Ùº(ñÎãþùákísöˆð…ïíSûCÅû"|IÔÕ|]ð{Äž0¸Ñeøcàÿ…ÖºF¤ÑJ¶¶:½h®Œª¡äžv¾•¥' ¸ ª â¿Fh ÇÚ»þ iûWüAø­7‰¿loÚ7ÿ³Ä[C×/øWûø#áìáØÛÇ_.<¤ü&ø¿âWůø)íâ‚Wt /ÅRè^Ýỉњ9î ·..Cˆæ{»’ò‘o…›÷úŠüSý‹à’–ÿ¾ÿÁ7âÄsQøñði¼QâÝÙº]AãøŽÂh5I®'•|Ù=Ëùn6³“wÏxþ“§üÓ¾[þÏß¶×í+ð+WÑ| mð×Åš®o¥‹Ïx~ßZºÕ­ã2KnçO¸Ž[Û¨ÅŶ×1LTކ¿sh †ÿkïØïÆ´Ž§ð‡Æ¿ jŒÿ²ÇÄÿ¾£ž§áèí5=;Z²½a¹´ÔtËøä´¾\"4m"n‰Áe?1Ïæ&£ÿä~ˉáÏ?†~*xÒÃV𧆵? ëzž¹á_x‰üWe­K¬ÝKäj62Ûi÷&îâçd¶±¦È§h‚¯è~ŠümÔÿà_ õ_ÛƒNýµßãOŽtéí¨¾™c¤x{DÓ¯m’ëJ:p²—S‚Ñn¯,`ŒÚÝU% K2®Êñ¿…¿ð@ŸƒŸ 4Ÿ‰¶QüyñÅÍ÷‰üWà?Þ6“á}A³iü5« JÞY,´ûx­e»ºl¹»òÕÝq…R9ýö¢€?,?à‰ í¼iq5ïíñ¯Vø¥j~:ñ€~Mo§ ;ÀšïŠ-¯ Ôoc¸XÕÚ Ô/ZÞÝ’&ÍÅ}?û0ÿÁ:< û0|PøCñGÿügâGÁÿ´€¶·ð[¤Wšn›uöˆõ1¨apç†UÄ`t¿E( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ¼³ã—Å?‚þ-|fÔ4‹¿XxOÃz—ˆæ°‚EŽ[Ôµ¶yÚ%fùU˜!ž5êuæß>èßþ|Oø;â+ýSKМ–VWº-ûÁ¾DI%-l’FÑ9‘¶H¬…P–ÚåÒÃñ=îª?º—oó·â}ÑÎ<Tù*a"Þ¾÷>=}¥gmmîóiwªŽ¶lûÙ?àë_ÙºIàµöuñ¤—2ÎmcAâÍ<´’‚@6òrÊ1þÐõ¦ÇÿZþÎosse'ìÓñÒò+‰-ž+ØÆåÑ‚6.HÜ@ÏBkâ3ÿuÿ‚NøKÔ¼A}}û{hòZAkxÖóÞhtÑÍqjÖ‚(”3ȇ6ò7– [¨o+pVõVÿ‚ Á.uŸŽ~øa©ø·öÅOx³H’ö×QšçJŽ#ŸMk÷Šeka$r˜Œ˜ ‡i 2µ’ÃñUÿ‰§¥#ÑyÏÑç‘5ƒWºÓŸkuÖûßm-¯–¿Cø:×ös’êÆÆÛöiø‡}ws4pE¿‰lemάÊNÕùAy)ÿáCeÿÄWÁºWü¯þ Qkâ Üiú‡íÑeã[¯²]\X%ï‡ ú¨·ŒÅupª ªýžHÜ*ovf¯]ñÇüWþ Ñà_øŸÀמ;ýº5»ýìA©M¦Ëáé’Ò´‹_=“Ê粪dzÎue•£`çCŒ®½„ÖÚßÙïòGÔpÖkô_p¨óŒ-E.gËìåŒk—§74“æ{´´[]ŸJÿÄO¿?èÓ>)ÿáCeÿÄQÿ>ü ÿ£Lø§ÿ… —ÿ_0h¿ðJ/ø&ÞµcñFò/‰?¶Å³xGÂgÅÚ¦ûÏ=¼–ãi1Et‘5«¸Þ¿7š"x. rÃ?ø$ßü£âÏÄmᇄ|kûyKâËØ¬žk ÇglZÆk×—Î0l–%ŽÂdSõËOaÇ_Ïü“ü¥þÔú#ÿÐ6#ïÅòÃéÏø‰÷áýgÅ?ü(l¿øŠ?â'ß„ôiŸÿð¡²ÿâ+ã»ø&/üP°‚m#Ä¿ðP _W–K•Nˆøq$1ÁröóHdxÖ "  ¾ï߯@a¸¯o{ÿÿ‚oØ|8Ѿ*\|Nýµ…/¼[„£1]xz[ˆ&‘w$óB—…OÊp.eÝä=‡<òOòíO¢?ýb>üWÿ,>ÿˆŸ~Ѧ|Sÿ†Ëÿˆ£þ"}øAÿF™ñOÿ /þ"¾ƒþ Ùÿ¾šßM¼þß6V·VVú„orš8‚KÓhÌUá ˆØ~8VÉÈO†¿à•ÿðOßø_BÒ¼eûo]kšöh¥ß‡~Ϧ­Üñ[$³æ64¢m1ù­ ’6Œ‡'°ã¯çþIþAý©ôGÿ lGߊÿå‡×ñïÂú4ÏŠøPÙñÄO¿?èÓ>)ÿáCeÿÄVÿïø77ö/øðÿÀßl>2þÔz}Ž»£ÙëÁ5î’^ž”#bÇ€ØÈãŽ+²ÿˆfÿc¯ú.?´×þé_üƒG°ã¯çþIþAý§ôHÿ |Gߊÿ凗ÄO¿?èÓ>)ÿáCeÿÄQÿ>ü ÿ£Lø§ÿ… —ÿ^£ÿÍþÇ_ô\i¯ü Ò¿ùø†oö:ÿ¢ãûMàn•ÿÈ4{:þxÿäŸä?í?¢Gýâ>üWÿ,<»þ"}øAÿF™ñOÿ /þ"ø‰÷áýgÅ?ü(l¿øŠõø†oö:ÿ¢ãûMàn•ÿÈ4Ä3±×ýÚkÿt¯þA£Øq×óÇÿ$ÿ þÓú$Ð>#ïÅòÃË¿â'ß„ôiŸÿð¡²ÿâ(ÿˆŸ~Ѧ|Sÿ†Ëÿˆ¯Qÿˆfÿc¯ú.?´×þé_üƒGüC7ûÑqý¦¿ð7Jÿä=‡<òOòí?¢Gýâ>üWÿ,<»þ"}øAÿF™ñOÿ /þ"™'üðz4yöLø§…Ÿø¨lÿøŠõOø†oö:ÿ¢ãûMàn•ÿÈ4É?àÙØâHä¾8þÓx`Tÿ¦é]ÿíÆ“¡Ç_Ïü“üfD~¸|Gߊÿå‡ô=áMz?x_Ã~(†ÚK8u+ {õ…Ø3D%\)#‚FìVýbxkB¶ð¿‡üQ“Xð¾½} ]j‡P·‹Oš{s)âV]ª^8^@¤çŽ¢¸«Oø:/ö_¾¸¸¶·ø1âv’9c‡sxšÅRGxVdÄaó+d9¯›kßø%Çüöãö£ý®¼gñŸTøÿ+ÛJ¾(ÕF“â½8\êWš€IÚXÉ…Ø·mÈNíªÃy$ƒÅü9ÿ‚*ÿÁ/þ%|Aøá Gûa Ý•Z¤¾"Ò6i÷ „·óíP4Ñy‹ÐJ6!tÊÇÓN‡õsõ*UøYEsA?WWo–—>Ńþý—înfµ‹àÇŠ $vÒï>&±XÝg2¶¹X·•'Ÿºs[Zü×ûÕµ&†âb-µû9/H¬Ê¸V *|§ž}«â‡¿ðFÏø%Šn#ûS:¥Ñ£(‰Z)C ù€¦vAªÞÿ‚uþÀ¾7Ñ> x«KñWí‘aá}O¶¼iõ;½Æ[Ù&¿’ÌF©<*!Eeži™#ŒHC²` ᫇·àäŸþTÿ3êïøˆÇágýÄ¿üÙÿñ4ÄF? ?èØ>%ÿàöÏÿ‰¯‹/?ಯ†¼ âø,?kmSHñ/ˆuM+I†=@†í¬­%¶ApÑÍn£Ì•f’E‹wÊ°Ì ¬©¿cø&ŒQ=ßü&?·yÓ¼íVÝ'm?IO6K(–FUF€HL›Žß—)g(¸$¾ú¸{~þIÿåOó>èÿˆŒ~Ѱ|KÿÁíŸÿGüDcð³þƒâ_þlÿøšùÅ¿ðN?ø'׃î¾Yê>8ý²šoxV×Åš[I>k‚iÄ"¤¸Ž4×%Ùä+P1#yn»ûþÁ:%Õ݃^þÙòj/m%ö›o6±áˆöÕvârK*6KUaÓyY_ ý\~߀?’ùSüϼ¿â#…Ÿôlÿð{gÿÄÑÿü,ÿ£`ø—ÿƒÛ?þ&¾y‹þ —ÿõ—ö~ñ·í>)þÕé hϧj;]ègSIþØ-l˜ÀyÊKà€q’1^a ~Áß°?Œ5¿†Ú†uŸÛB;¿êº}¶›6­}áÛH¤Óîu1§‹Õ6‘È”HD ¦m±™<¸/…þ®/oÀÉ?ü©þgÚ¿ñÂÏú6‰ø=³ÿâhÿˆŒ~Ѱ|KÿÁíŸÿ_$ÙÁ5¿d_øF5¯j+ûbÞéãÆ¿ð†éÚV§áù.u°L×n'Š$†=óyaKùCcŽÄÿ±OüûO>ÿ„WÄÿµ·‰MôÜj >©¡ZÉ¢$’¼QyªmØ&6m™ Êñݼ WÂöüÃÛðòOÿ*™÷üDcð³þƒâ_þlÿøš?â#…Ÿôlÿð{gÿÄ×Ã^ý‰¿àþ+ñ…tKOþÚKk¬ßYivw0É¢^*ÜÜHÊ<ƶ‚HÐ*…,…üå%”ÄH¯Òßø‡—öRÿ¢ÉûCÿà^™ÿÈtï…þ®߀?’ùSüÍ/€¿ð]‡?>5ü-ø/¦þÏ>?ðî¡ânÛE†þãXµ’+G•°$eUËè9¯Þ:üYø)ÿ:ý›¾|]øoñ“Ã_>9j¾ ðίo¬ÙÛ_Üéío<±6Ud j¬T÷ÚÀû×í5qb];þìüÛç’ºðþÄMBÞõù·¿÷›èQEsQEQEQEQEQEQEQEQEU6JÅ–ÎÔ1v”‘Ér0[êGÖn•áŸèV+¦hÚ‘¥iÊï"Áon‰f‘¤c€1’ìÍõ$Öå^KKIr%¶·*w ?)ÆGÐà~Tão‘&0BePB¶Ñ•®jšŠ€[[i¼CŒ¶Á“Ž8AwC‘ˆ,ÛFXŽ„úô•KEbê¾ðþ¹¥ßhšÎ‰¥jš=ÔÚæÖxâž/î2‘‚¼žÖ¢[[Æûã·†7À\ªp8𩨠 ¼qWh  ÖVVzm¦§ÚÛØØ[İÁ H!@ ª£€:Vh¢€ (¢€ (¢€ (¢€ (¢€ (¢€?:~?xßöæÐ>*x¾ |ð—|œ0éÂî P·ÎÆÙÚY'{ØåܺˆF"U@#´»±›iÿ?à§÷GE?³÷€î-Ò[$Ö&·µŠ[†t‘n'XÓQ(7”À¶>T`A,1ïf¿¾8ø¯«xãÁ?µG~x:æçI¸¨‘ãO³G*HŠYÊF’IU>vCq|KÁ?±‡íh$øW}ã¯Û#ÆpÙXçÉâÃPÕd[æO)® Oyç8™ã-æåY|ÉŒª(ëˆ_ðQÕðì×|øau¬ÙiBY?´-¢‚MJõ®í¢h£ê£ýæ»,B†‘ÜÚ&“ª¾ø•ûvX|)ñ¾¯mû7ü?»ø¯mâˆìôm: awš9„Êd,÷jÛ„ª"ÞJó qcÎ4¿Ø3öŠ+¦Ö?mïj×¾TZŒ€]ºÜ[¡»"³\¸1ÿ¥7Ë€HÀfm‘•õ?d¯‹^#øaáß xÃãGˆŠô/ÜëÚ%Ü—×mäi±ÚÏegfÍñ¾LRw \3³$ ê?‡¼eûxÜiÞ?´ñGÁ¯†v7Öž´Ô<7>™"ÄgÕä[v’̬—*ˆ÷ÜÄ[p[£ƒ‰v¦mÏŽ¿à šd‘ê_¾k—Éd·&úÊÝ2Ò3F¯h–²j#s çç3*•ŠF뵩oÙoãÔ <+á{?ÚÓâ:·ñLZö«¯4ŸÚV©l„rÌþ\Kµ[b²0%Ã332ÓaïÚ÷L]/Ç¿µßüV‹{öè.ïT·›Oe™åHâ1Þ¨#{Þá¤UcVX §ÇÿðQÍ>ÃB´Ùïá7Š/¥¸šïTŽ"måiŸ`òä!\q´»D±°F*â®Eâ¿ø(7ü ÞÖ,¾ø2÷Ç÷W^"“S‡TÓ­¡†ÚÞ&‰ôȼˆµA” ¢ ö‰6ïÞÿÜ«ŸdÚâŽ/éž'¼³¿-³h¡K Ü¡e¶’ÖùNÒq&ÀÌJ’¥£lãÑí¼wûsMà_^]|)ømeã»/ÝÛZA¡Õ4m%’9UMÒl–y’(”™_;,˜Rkîj(åO^1ý©«¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š+Åi/ŠŸÁ/ÙëãŸÆML°Öõ xGWñ­Ó²Ãw5­¤“¬nWæ Å$s‚q^Õ\wÄOø[⯀|mðÇÇ|š·ƒ‡±ÃØŒ%,Â…\|\èÆqsŠÝÁI9%ªÕ«­×ª?ˆý?þàøÃ=õÞ›«þÌ¿<;|—¿c†+Jýžçæ*$ !IOŒÎ.?üµñHÙÃwkû=üº2ÛËq nÔȱ’e† §ÿþ¶ø“£ _X·Z]爬.àxnä†Îà(¸™n|Ø×{>èð$ »Á·¨Á)¿` ‡Ÿ ¼umÿ§ñÔ÷÷·Z¥–­¡Eâ/´º8P´·ÆÁwH%Šy¥PcA'”Ø8¿/—ñwúͼ¹•¶ÿ¯Mïæ}Ðñ“ÁSörÈÜ·÷sk%kÛ£ueð¥~[ß[ü[üŸñRêîÖÊÙ÷àijÍ"Ƙ¸Õqó DÐÜ=«°ºÕ|ÄVi0À`„ ňáqÍ}ãø$Ïì_ðëÇŸm4ßø%Ö­ãïh×¢*}Å$ŠòþGAp·,_1Iè”ÈÑ9(V<‘zŸÿÁ#¿a+]ÐotÏø%OŠüc£^èzGˆ5iÿá8׿´ ¿e-h‘…x¥–Ü*‚Ï4|ÉÈQÉÃý\âno÷½?Ä¿ùQë/|Tø~óºÿ—5,•ÿæ`Ûwµ¶ÒþóÆãþâø£mr°Éû:ü âRó›PGÆTFNæmªFA Ö¥¿ü“ñ†ûXÓô=7önø?©_Ü\[ÛþêëSÛϳ6ÖŽ6#þuöß‚à“ß°'ÄŠ~ð&­ÿ½×ü/á뚈ïø—P[w j4×Lö-İ‚KÎŒVA‘IA”‘~´«Ú= ’ÛQÔü@òK,𥽬°µüWR[ÜO6<— DÇwcJ\3Æ7ýæ26ò~kþöºùÜü;Ç_< Ìp)ðNIW Z3¼Ü㣇+Vÿy©ö¬ö[o©ù¥?ü«ñV<g¯‚·2oDeš¢ì&H‘%p<èË/QššçþÃøë&‘¥jšì·ðÄ/{zl-àõ«v,g*yCpÏ\€:×Úÿ‚DÁ<õÝK⧈5Ÿø%¿Ä½TÑü9öý.üYâE‡SŒ^˜–ÔÄ2#x㎔%‘•‘ ùi¾ ÿ‚\~Ä—–šï‡¼=ÿ¤ñ&¿alŸkcwâïEhÎ¥!‹Él¦Y)*ªô¶ÆöŽPЯt¸oŠ/&.ýï%÷iM==Uüº-Gˆ¸iߟ nÖOïÖ£ü¼úüesÿg|V³‹¯ÙëàÄrÄÅdEºÕ$ …v|8O.@ÅI©ç¥P‹þßøžmîî/?g¿ƒ:o‘ÅÄ©5Þ§¹ †Y#iHP~_Ý»ûTžÕõ´ÿðMغóCÔ®tÿø$gŽí;ñï„|=ÿ¥ø‹â;OÔm´ûMv/ë’A} ðIr÷"ó D“*)Pw´†Â ñEµÅäËçÿ.J—pÕî°¿ù+ÿå§Ç~ÿƒ¦ÿhAª\é³Áø­ínÍ›5Åö£˜Â4}Ê8ă¯>ÕÔÄMÿ´—ý7Àÿü_ÿ{Ÿ„?à›±½§‰4m$ÿÁ+~ xgÃwzü. öÞ)ñJË™–~»PE$i”J’¤|Ãqšî¾%ÿÁ4?d]Wø øþ «ñÄ‹£%÷‘©ÉãO¸1Ý¥¤8•vÜHæD»Ù¥>ËŸÞùãO'Ãlæý–2 >o_ý6zØn&àŪàäåä¿û¡ò—üDßûIѳ|ÿÁ¥ÿøÔSÿÁÎ_´œPM(ý™~¨[Ú—üà}kõ3àüãþ ·ñŸÁú¿Š5Ù;Äž’ÓZ½Ðü—ñö³p·sZIä\K …/´$ÈŒ3¹c Æp=½ÿàƒ?ðL〚ñVÿ ¦µÈÿÀªÃýWã¯ú ‡ßÿÜÍ×ðGýÏîÿî‡êÿ‚5éüSàÏøžê­nu.ÖþH£$¬m,JåA<àÅtõ›¢éÑôJ…­ô»+h­-£.X¤Q¨E<œ9<Ö•~ûIIE)n~Q§&ã±üþПðrïÅ_´wÆ‚w³wÛ xWÅz‡†“^—T¸>{Ãç¼{¢Vß–ŠIQ´7ÅyeŸügâëÆ~ü.¶²–â{K‰%Ô¶^4G2”À'•ä¸ãÒ¿G?j¿ø$¿ì×{ûC|Iø¥kûxwãM¶µ¦±ª ŸZŠïSžòMFKøÅì3ȹ_³DR!Ðo#CµJšòÿÿÁ.¿`­gAø¡«kŸðKoÃÚï†[FþÆz¶¾‰©Ãsp°¼¿»‰äŒZ'ï Ißdy$ ôÕj?Ëý}çêô¸ƒ†£žþ±v•ùùŸ[ÁÖ>1ºy]>|/]xöñuÖ¹ øF-_Cñ ׊¼G.“«ê®`V´]¤yûF,ÞL€ªàâã_mcý}祃â~ PýþMù+/Æ¡ò§üDMû@ÿÑ»üÿÁíñ7íÿFïðsÿwµîþý‡?eÏxÇáÿ…5ßø%ïÇ_Økz¤ºtÚľ3ÖZßHHç´×8lF6ãæÚÞ[…b6tß°ìÃq¬x@Ò¿à›ÿP´×.tk9¯¼gâ˜íµ[˜âŽé%ŽÝÐD#6Fr }ØÌ¤>×íðßËý}çWúÓÀßô?»ÿº ÿ~Ð?ônÿ?ðg{YšßüuñëBÑ5½vëösøC5µœ÷²$zîçXã.@ÉÆH\s]•§ì©û8ßéskZOüGÇúîŸa=ÍŽ¤x³Åfᮢ¸Ž…‡h‘@žFU2&<´ù›ÕT/¿àŠðNý_A½‚×ধeswfñ§Ûø{_·Y›û/ûBîæY¶Y­Øñ„´NÉ‚§V´ßðuOŒ¢×ì¼?ÿ 'áƒ\´ ÛùúŽÝ9ÀR<Î3‚X®á¥v+Þì?à–³oƒ|)£ÉâŸø&>™ãûÕÑྶm"mwMû<òØÃ=Õœ˜B»ç1 ³¡£¯\ñ7üóþ ïá›kz/üTº–ûÃZg‰œÉ©x‰eÓ/æyD–ì¶öÓ2µ·–»ÉÄÅ®aÛ_1Ò–' ü¿‡üÞxz¬¿³®®·¦ïe½íˆI·³iE[d›ÓãÿSë»çI>ü‡ÊûW˜Ò\êJ«ä y>m¸'i’Aâºi?àçˆiú¨ÿ>}ƒP³ŸP‚Qq©0KhˆY%“ ûµV!Ilrq^©¨ÿÁ;dmëL¹ðGOI¤\¥Ó¥§ˆµ©/!ó(ÔÌÆ5†&hüÔ‘?-×dõM3þ ©ûxƒKñÅýÇüO\Ò-¼)ºx_L¹ÖüD÷:ƒ6¦ö“<%ÑR(^ØEpH©/ïdZXœ/X_yèá¼DðÙ){l®ïKZî¯ö­tæí­¼Ï‰õOø:³ÅšmýÚü øu}qol÷kÕ ªLþY  #•‚RˆÈB}3r_ø:‹Å(Ž`ø/ð®úãíW jŽó]CHñ/ËÁQÏ$Ý¿<ú¦ÿþ •ûÚxsàçŠ4ïø&%èðf³áËùuÏÿix„ßiz‚NñEj6FØI#k•Mñ¨v¼FfŽ/2Jè4øK¬Øk—ZRY^x«^Åô„)wârŽû¼eÉ ã¡b°ÖúùŸc‡ñ#ÁŪ™EW++Ùi~¿òüùÏöfÿ‚ã|jøéûBüø7­üø]¡i&ñ ¦sykvó[G+`ºùKÙâ¿¥ºüåøoÿ ý†~xûÁÿ¼ ð›UÒ"ñ^ ’ÚkZ>‘/Ùç·¸³y$0Î7Co;˜Œ‘Sw!Ñ(®roþÇz½…¾¯¨ø³ö¦°¶Ô›Ä÷—/©ÅiºÛ:ys«¾"™£!–ÝÏ„J¢ 4ú£Ø~Ð#à·ˆüâŒþñ'Ç}6óN¹Ò5vÕ"¶ŽóSO*s§^%­¼B8eš)¢ÂÆY —î–ROŒ·ÃÛÎÓÇWþ ‡öðü#0é¶Wú=”·qOU’©s,ÅìÞd¶’i¶×fb‡Ûßj¿b-æÒëÅßÿiM" sO’};^{+^þÆ {¥ûoÚ­ãÅlÍlñ*Må:HÕÞ{ˆtߨfúÓàm§‹|aã«-^ÆÒËáÖ“sª[Zyöw—3jPÇæpħûV|=ŸÅ±‰-í¬¯Æ^co^}ê›Vk¢HÀÊ¡ZV/·k„_EñGÂø)F£Š4+/ÚÀsxvHâµÓî Hlu6Œ–K…²dYci|¸”:å#00óÉ~)ø;ûxcÁö~:Ô5ßÖÖ0þÕ™5Ûm×IŸN6½•Õ»ïŠ YŒaÏï²F±„¥G}¦Y~ϱüð?‡ôþÓ'ÃrÿküEX·´Òﯯ­´Z|ÅÇšîÓ"]Ûˆ+Iyn®¾Q*õwÄo‡ÿ¶ö™ã½g[ø]ñßÀºO‚5_Åtšv¾‘Ü}ŠÐ¢Æ¶ÖäÁ¹w°Ë!w$ŸÝ”ÉÌz_ƒ¿oMÀ¿tMwãÃxâÿKÒ-<4öòA¨,J×ò¾ÛQ“‰™Ê*B©Â ãó½¼ ûøCñåå­Çí ¬ÝhÖÚ}íØhâK$¸6²Ý!ûJHΛc†O6]ᔵK¬ü0ýЦ‡Uѵ¿ü’Hà°Òm>×eap·†}>ýà’È6éTH·Eö…eG"Ö1!ŽØúiðSÁ_·.‡ãÿjŸ>/xžm&é¼A§ÙYD¬š‹;ˆ–ÝÒÞ&ò•$9Ïœàɳí«[ÛKè#º²º·»¶~RHÜ2·núWáÅmWöWø…¨Ïà?|Gý£ü9âéšV‡}¤¶™fҥ倸ó.·¢˜åšÞ+6–e‰™É„`ÛkÌ~'øcö?ð^¡—„>.øÁüccugâ]ZMFÚÆæ]oO]ytñ.ø-ãß Øü>±Ó i¢_j m ÝÄ„+ù©ö)]œ}å“ÌØØ" L‡ÖþþÓŸ >2ÏáÛË®G.«`÷öbò×Êó-ìî]8cóoí\•e”fšø£öÇð/ì“®|VñO‰~4|wø…ð¿_·ðÍŒZ®™ÒZÉkÉšib¼É$a >ð¡¥*BP ³ðóþ g¥Þx¯Ný¡ü1âiþÀ×Mig”ÑßÜîpð ˆ ©à‚e eóm·ðÿíÛ}àÿ†ž5µøƒáÿø‡ûüCe®][–‚è]ÜH¯2GiäHE»Â’,BÝäe<@ü¿ñEÿ‚~ë^øyá‹¿ÚCâ…,´ ë6pÒ4k¸dÕt¹µflEgþ‘̸fˆ~ñQ˜±RìÜ]ÿÃßø'¶¯Ú·ü5oÅ;Káy<×1C¢ãIMt¹k–’ÔËo˜íGšdùÐù#\3}…ðCÂÿðPGTÒüsñǶºn‡ÌŒÞÕ$²Zœ)w…¸xlÄ ¿Ú >[hwï sè_ü1ñûÁ¾=øýñ‡Dø¤‡OO ]ÏàÏ Í©+ÚÁxé‡Ìš c¨Ó[L'™òGtÌ»YÉ4üøqû ê_´xü-ñÓÆÞ,ñeõµÃZIw:D70Y´·ñÝ[[À«—p“\"J<É”´ ¹u¯ ³øûêžÖ¦¼ý¢h Zuk%“\Ò$¼º½–ö4`°ÚËb]ƒ8šx$‚’JdBb ô#Þý¿´ïië_~xÁföÅ55¢†o jIq,IËþ…¶þSHÄÍ+J%EØ‰Çø¿ÀðSy5ïIá/Œÿ‡‰!›AI­R9£ÑÄ’Šç6lÊG;æâPоì¡ñgöNøWá7áGïŒ>3ñί®™`:ÕŽ¡=Ã\NÑ[®éZ‚6•V??w”ó™rå…{~ÜŸ³:ÙýªûÇ×:dÂy-šÞ]"ñäï7ýTL¬±€FRV èd)¹räÁŸÛMð¿¬õŽºn«â©bðœšÒËooom5­ñ¸ÕH °D p®ñüªKÆ‘¡ØÙý{ðONø­¥|=Òì¾3êú~¹ãµšàÍ=¼©.a2±ˆ<‘ÁHá6å’ÆxÛÆãGà÷Çÿ…,µ+߆~"Ÿ[i —i-ŹˆHÒ¢•2¢¬«æA<{â.›à‘weHÍ@Q@Ÿ~þ×ú¯ÆOŠ2ø/ñÇH²ðòZCi¥øz÷R†K[YÞÒÜH²Âl¤hX2™‘·±&aŸí8~ðoíãáÿ†öšˆ~4x[øãyâA«Ìò]ÃäɤǦÛÃ$PÆl†#K½²I ,&;g„¸Ì¿i?þÇ'ö‡ñn·ñ/öŠø‹ðëâ»é†æ[9®BiìV(µ¶@ñ«B YÙßz©Š6—ª++Âþý‰>KwâÝ#ãßÄiô¯ˆ>Ömt–+y{ v2D²lo³¿•"Él!Š96»í쪨¹áGöëÓ¬¼-wñwö ø1ðóL‚ÓD‡ÄÖ—·zhÕt›é§Š{‹ygkn%–ÜJ"  „œ=v þÁLtÏø_^øñÇá–« Ë©Ø>·eŽhÿ³cžå¥ŽqvŽXÔ¸ ±H˱·ùKx7ö6¶ø®è–_h|_®ø‡Äòèú¹¼Õ´‡ÅêÝ£%¬¯u º¬®ä¢<Ó¶íòÀŽÁž5o¶~'A¢Ýü7ñý¯‰ÁHÚ5oþÒ_ ­ü{zt»¬­Ô&éo%üóJ›A+Lßè­…`%š7Ü^½;Âþý±¼9ij¬|fÐ5ëº-ÚxkKÔõ;Yÿ³õ(á´XfGN„å¥ -‚]Äþø7ûxSÞºß~,h>ð&¿§E‰õ¿ GæYê³ÛÜ,v±¼ÖfåRœ«BʱÀáÃašZèÿá]þÆ_¾-üP²ñ¯íñŸþ{Ÿ7…u;»›&¶Ïwlm•bž ]t‘Χ(HŒüÌ2õÁ¿~ÜÚw‰~jÿh/„þ-ð»Í}gâ‹HmŠÏs¯“6¯¼M¼\E+Ȥ–VYÝùƒÔ¾ÿÁGï¥Ö#ðÿíðÃ]žÂ hmÜù0Ko¨=‰Q¡öË1tI#ÁO áJ’ß¿Âßø'•«CâÖý¤þ)iúͦ•sª[høI ’ÄjO©b+%ÓÂFÞSÜùJ ÚI6ìÑÝüÿ‚ø7C›BÕ¿j¿Š†+›]B[™t†¶˜¬ 0™%ûi:Æ-ÙÙ€Ù8ˆ²‰€ú–O…ŸðSk]ÄÖºŸíðìYÏ¥Í$³Eq70]I>ùZ™,m‘•0ÈPŒn!×ÞtþÖGÆo Ïů j¿ ÞÛK—TÓnuä—lV–ðÝñ6Ÿö½>âÒ{#KX®/®]"ó‹$Nìc³*òNy]—Àïø'n¥â=+Kð÷í#âíÄÚd±%Õ´ogy5Ò¨Ýûm’apÌ¥š"Cý¡¡%<Ï(¢¼'ðÏöôѵ=OOðïí5àO_Aâxä×mu‹ˆu9ôÝ;ìöÞ\(VÒ6åÃÌñ±#c&Í¥‹ŸÔ‹kËKÄym.`¹dx™‘ÃêÅxîGb¯ÃþϰÃcD·Ç_ü;M3P¹ÒÌpè[lõJÛL‡OººXùw»…˜©.’L²DÜ–ŒúÖ§ÿùøMñ§á^¥âƒŸõéø…u8×UÖ4˜Ò1 Ì¡%…íÞ6Am$r´0:¨†bÄ`@?]èªö–ÿd´µµÞÒùQ¬{VÀÆjÅQEQEQEQEQEQEQEQEQE~,xsâ'…a¿ÒäÕÿ`X'ø£o«jw:£é1]Á…nÕã’KlÍæÆ¢5€í片îÃq˜~&|8ÓµHá¹ý€´I<4ºêIäÁ{;‰dÛÚܱ ½S÷ 8òÕ‘›_·TPäÇÃß|#ñ‡Ä…ø{ã¯Ø:ÏÀ:7ŒaÕTÕ/¬ Ý»A%š¸†xͨ'ŽöxäLˆ’V•wHÏ“ú?À_‚·?ð}£á_€æ:¯ÚN¥»Lˆý¸Ï ¼34œ|ÌñZZ¡'’°F3òŠõª(ÃuÙ»à½ö©¤kxJÒ/lâ´¶Á~Ì·öÒ[Io ¡0$HÚÎÛh=(: Q'ìËû=ͪx§ZŸà×ûW\‘¥Õç“K‰ÛPf—Îc&GÍ™ÿ÷¹ëÍ{•á÷ÿ³WÀ=SBð߆5/„¾ ¿ðö‘ÄZu”ÖJðÛ¤Òy²®ÓÓÙùÀ¼­+_€-<=…"ø{áçÐÖæÆ;yc2ùVó¼/,jÎK*³[ÀØ`Ã*+ר Ÿ¡ý•gkhµ-~xFÖ ´‰nR(YÍÍ’¤~ðyiûÏ¿òš¬Åû/~ÎÐý¬GðcáØŽx~Îñ23Çä¼QHÚ€Ç#©Úwry¯x¢€hðèðéß <°¸kË7:lm$ Ä 0vŒÝÒ3’X­Ä “¸Õ«€_´È<5m§|)ðŒ5Õ•æ’±i‘(Ó¦µ¶ŽÚÙâÀù PÅiº±¨zíãÞø ð¯À>'>*ðo…­<;zá!·µ&;[S:Û¤Í#äBëin ¤C§5ð—íoâƒø™ãMOÅß²&­ñóÅ÷:>ö«™-åšÓ’FÁŒù2*23H §ïü¸ ×êu|IñÂ×öܹø»jßoü'að\hñ¥ÚÉ%§öƒÞùêÌðyð°GØ ~ó|[X¡ð@ÈÞ&ñ/ûŸ„Ú§Æ ~ÃÞðw‰ô?Kà¸l|K 4³Ï¤¥»ÈÒAB»îäx×qeí±¯ƒÚ÷â­ÅÖ­ÿ Ëð/Gžïâ Þ‡ªÙj »{¨´ÿø™8¼”Gq¹&“È ÎñŒ›6°ÚؼIüž8õ_ì_ü%±Ž Å–IÅ“²j- hU2бÄTÆ"‡p¬æ]ìS…‚ÿÁ@®¾øŒ&¹ðÆãâ<8´’ÐG=«Û6…åƒqe#vUÈaV™”1 „¨ü9ø×¯¿‹<%²÷Â_ ßhz­¨é÷ãÃwëo.¢Ö“DÐZI½¥pbHâ‘Ö';äV†6ÊVw…¼qa¦kÔ4¯Ø«áž£©IjiÞ»IÍàÔe‰çGgxÒÛËBb™Ze-"†hATo¤¥ÒÿàªbÁXø—áDÚ‰±rËV‘"]-ül/îoæ bDØÅ^L×Y¢ø{þ 9ý©¦E¨xÃáÛÏÍÐÞà^ª¶E²3Áæ*:’&v;÷òŠ.hãKÿjsøƒá§‹ôoÙIÕlü-nš¤žÑ5-94mYä¶û=„öÍû±eutLå@Þe <©YøÁ{¦jš2êRþÂ’Gi{yu¯Ë£é½°€@öm’k[RIaJ³=½»LØR®>ãø¦ÿÁ@%×¼P¿5ÿÛi’jwÿÙr]}ŒÛÛÚ³‘m¹ &b© ÅÍ×9ò>Jàeð¿üïJ×5ht¯ˆ?™ý¿i?üe×uO x³á±ðóT²ÓÅÜó4—B%*4dËoÝÅ–ArÞLù ±Kù‡ÃßþÙúo~ø§ÇÞ'Ñ|UjÚ¶ ¾/·º{†ÆÁ­TÛ›–ë$XåR£ê‘ï|/? ôQEù…ñÿâÂ?üm×§Ô?c{ŸŠ~9’â×KÔõèôÆv—O¹†Ò0o!Ä ¤ï–¤³ WS€0¼ñ_Â_¾xÏUÔ¿aKÏ x[ÂzŒvn¼¸–cq}ñΧ¬hâ½&ßH¼žçKX ÇQ‰abÐUbûÀ+´+ž‡¥vuÃüN²ñ¥ðßâá q¼1âÉôKèt½H:!ÓîÚMºEd]ŽU²ÊÀcGù?áŸŒß ümðãJðÞ§ûÉ£øNëQ‚{öÚg´¬ Üí["³yÞf 4³q 1¹|{øWã½V/øÛþ »­j~"Ô!±Õîn¯í÷ Ë~¶ O—lùhã(áNM¬NÍÕïš’ÁA<+¢ZϬ|MøUá /M´M"ÚmZòÍÿ·î›-ijKVB¿4k‘º_¾r§Ÿ¶›þ ÚïÄ üXøgâ-AîE¾™k©jšdói·[O"â(-Ô*¬;ÉXÀ•¦Ž6Üa”ü_ñWÁÏ„ß4ü×­ì´ ¾½¸Õt»)­/Zõã¶žåV ŠÒÀѱ.«š*I…—ˆ¿mWáÅí3ÆŸ~h_l…n,¯´­gLtÅo+ûF)‹DËÊ7y0[ÌÄaV ’~ÛÖ~0Ðô­?Ä?°7ÄRÐÁ4Ú<hŽ®æ¹µ»]ÒÛª¤r"í]Äy¿hE «¹†ŸÆŸøSÁ.t}öÖ5 ˆüQýµˆ4¨ÁªÝXI ÊÜÏ p‡r.%2€ŒÌZÞ'%±±}çÁÚ7íÀ—¾=ðç~!ø#XðµÏƒõ? ê6[Zê—š©-ö{–‘a(’l³^ga!÷|ùªü3ÿ‚§…4û? ø’Kÿ5¤ÖÖÚ‘ñ‰4ÈP^†K˜$ ‹™™­q(šO#k…dòËŸÚ#áï|Iÿ O‹à™¾!ñÍåì—Ζ{·¸Ü e"khѼÏ*QAÜÌgf•LŸªŸ²ïŒ®ü}ðsKñEç€tŸ†o>¯­Ç“cçy z¥Ôi:™¢‰ßÎU1¦ã) `ŠùÿÅ2þßúçŒoµ¿ÇàO |7¹ºÓ§´Ó'¼³šþÚËì² ÈľSÄÓ5Á·hX–A܇Ë4;|úîßþ =g¤»xçPð¾¦N”ñ ð ŒKý´4Ëáæå« F½60ä²¢Ê&Ý‘€ÔZ*­—ÚþÅiöó¾ò“ÎÙ÷|Ì ØöÎjÕQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEñ_í#ûYþÐ÷þ"¿?>!|>:†•œmôÖG·¶™%f7¨ÒvQ nÏÊ Œ’Û¾Ô¢€?+|Wÿ¶ð¯‰%ÓD?¾ Xi±M5ÝÕ”¶°ÜCª\Kf–ò´ûˆ2,¬‹,ŠOÎÀr½jÅçüÿÃÓA®ÁkñûâݤWÚ|V~Wš Ò%Ìs‰R0ÁH&5p;#ÎBá¿R¨  ½ÎÿOÒììµ-L뱩G¹0ˆŒÃ'¨à`pH'8­J( Š( Š( Š( Š( Š( Š( Š( Š( ¹ox^?ø3ž ›P»Ò¡Õ´Û9®­ñæÛ‰cd.™ãrîÈ÷ÔÑ@^~Á>?ÿáQé_:ÿÁPüðö‡ø‡ð#ǯ¬h—:L:eå­õ¶%üWݼêZO+&€Ä›ä~œ¤”×Íþÿ‚æü)½Ñ|OâG­xºFöû«ë-§ûHòôÉ?Ñ‘@iÓn§Üv?î˜ùdÙß~Î?DøwÿLøWñGÆïðû¾3¾_%•ýäÆûÂ÷6¶öÍgËwlò¿Ê³Â—¨ ØÎ+ˆðüÇÂ_üyyá¿ZøƒYðvà]GǺ4)í“J´·²G¶e2Ï$ð]Å:mÇîÝ8fm£ó—Aý±¼+á?xoAðçì¥ñ_ÃЧî~YêúF¥ÅŸkÛÛý´:Ù EhÝ@·FÏ•nãvUc1|(ý­¼#v¿4_ ~Ë~)øeaâ¦ñF›rE†›ki¦ZZÇö‡7N›‡†éÿÖm5ebÍ#öŒ;3ëWâ›·4~ùywÌý²ÿ‚Ì~Ïúž¤_é^=Ö5‹‹û+=FÎÆÏÂ7SÝÜ[ÜßGa ˆÓ<ÉRØœáf܇[‘á_ø*Ã?x#âÄ x¿PÕ|á}/ê·éák­¢Õíb¹)ýéfH§„¼j7)•G®?4Ž ¼/qáˆ~ý˜ü[«ø³Yøw¢;Af°A¦iž]ì— §[[I`ÐÛA÷˜òÜ$hÂå ,ŒÄ:úŸ´—„t;OËáÏÙöÖãP¿ðï„í&Ñmìì-.5k{ˉlæ±»“û,ÆÐXâ2†_%Ãm@BÒþÒ‡gý|Çþ£bÿš?|¿ùï¹ÿൟ³,:n¿«'ÅÈïl´Í;LÕožÛÃsʶÐ^ýŸÊÜê|°T][™2À ““ÃbÞ¡ÿŽø3iâk¯Zx¾}V[]^÷Ã÷‹pn¿´ášÒ­à·´ây/#Xß(§eù‡çÞ¡ñkáÌúŽï4/ÙïÀºÎ‰i¬xGC½´¿Ó4û$Ã÷vpÏÍ×üJd\ZNí•̦ ²øóðÓÅZ§tøe)E×/<%yu«i:Lšì@ÃæÞ»¶˜VI%mØ–uƒæue KûNŸf7À˜ËÛš?|¿ùõ£à¯ü£á÷í âûÏ|*ñ”šö©™ý¯òørâÚÖòØEe+˜e“ #"j6EÔr¾zŽ¡±õ'ü-ÿÏö“ÿ€ý•?Úwí‡gá x⥧ÁµðDwº?ŒïV ;«Ô$]&Ö)$zj,ìZª0ð µàðÝ~ ~ÖÞ>ø³ãŸ†~¿ðw<áhWš•®©¨j‘—šò Ý xŽš¢â3I¬Ñpçä8›Ìé­u | Œ””T£wç.¶òó?c?áoøóþ´Ÿüÿì¨ÿ…¿ãÏùþÒðÿ²¯•~Çâú[Q<<÷„1yu8ÔÄZÍÛFߟdgÂßñçüÿi?øÿÙQÿ ÇŸóý¤ÿàÿe]·ü3‡èwøÿVßübøgÿÐïñÿ­¿øÅv/c‰ÿ…¿ãÏùþÒðÿ²£þÿ?çûIÿÀ?þÊ»oøgÿÐïñÿ­¿øÅðÎ>ÿ¡ßâ7þ[ñŠÇÿ ÇŸóý¤ÿàÿeGü-ÿÏö“ÿ€ý•vßðÎ>ÿ¡ßâ7þ[ñŠ?áœ|;ÿC¿Äoü ¶ÿãŽ'þÿ?çûIÿÀ?þÊø[þ<ÿŸí'ÿÿû*í¿áœ|;ÿC¿Äoü ¶ÿãÃ8øwþ‡ˆßømÿÆ( Oü-ÿÏö“ÿ€ý•ð·üyÿ?ÚOþÿöUÛÃ8øwþ‡ˆßømÿÆ(ÿ†qðïýÿ¿ð*ÛÿŒP8Ÿø[þ<ÿŸí'ÿÿû*?áoøóþ´Ÿüÿì«¶ÿ†qðïýÿ¿ð*ÛÿŒQÿ ãáßúþ#àU·ÿ ,q?ð·üyÿ?ÚOþÿöTÂßñçüÿi?øÿÙWmÿ ãáßúþ#àU·ÿ£þÇÿô;üFÿÀ«oþ1@Xâáoøóþ´Ÿüÿì¨ÿ…¿ãÏùþÒðÿ²®ÛþÇÿô;üFÿÀ«oþ1Gü3‡èwøÿVßüb€±ÄÿÂßñçüÿi?øÿÙQÿ ÇŸóý¤ÿàÿe]·ü3‡èwøÿVßübøgÿÐïñÿ­¿øÅc‰ÿ…¿ãÏùþÒðÿ²£þÿ?çûIÿÀ?þÊ»oøgÿÐïñÿ­¿øÅðÎ>ÿ¡ßâ7þ[ñŠÇÿ ÇŸóý¤ÿàÿeGü-ÿÏö“ÿ€ý•vßðÎ>ÿ¡ßâ7þ[ñŠ?áœ|;ÿC¿Äoü ¶ÿãŽ'þÿ?çûIÿÀ?þÊø[þ<ÿŸí'ÿÿû*í¿áœ|;ÿC¿Äoü ¶ÿãÃ8øwþ‡ˆßømÿÆ( Oü-ÿÏö“ÿ€ý•ð·üyÿ?ÚOþÿöUÛÃ8øwþ‡ˆßømÿÆ(ÿ†qðïýÿ¿ð*ÛÿŒP8Ÿø[þ<ÿŸí'ÿÿû*?áoøóþ´Ÿüÿì«¶ÿ†qðïýÿ¿ð*ÛÿŒQÿ ãáßúþ#àU·ÿ ,q?ð·üyÿ?ÚOþÿöTÂßñçüÿi?øÿÙWmÿ ãáßúþ#àU·ÿ£þÇÿô;üFÿÀ«oþ1@XÇð¿Åêž#Ñ4ÛÛÍ5í'¹Hä k´•'œÜWÓÕáÚÀ AÖtÍjxîòkY–uŠââÝ£ŽÌ ‘ô"½Æ…Q@Q@Q@Q@Q@Q@Q@Q@q_~Éÿ ÷Ç?ohRËû"ïÎ26Õ å6r{ w®Ö¸ïˆr¬>ñ¬Î’È«¥]1TBìÀDÜ“ì9¨«ð³¯üxz¯Ìü˜ó>uþ×ðÏM¿ò=?ÖR™>œ“¬xh“ŒÿÄÔsÿ‘+cþM?þ€þ'ÿÁ5×ÿ£þM?þ'ÿÁ5×ÿ¯Š¼¼Ïê[Sï»þ eøjI'XðÙ$äŸíQÉéÿ=(ó¾cÛ>Çý…Gÿ­øI4ÿúxŸÿ×_ünøI4ÿúxŸÿ×_ün‹ËÌ\´»Ãîÿ‚d~’¤ë%s·þ&£ü‰Iæ|4εü5œmÿ ééþ²¶?á$Óÿèâü]ñº?á$Óÿèâü]ñºw—˜Z—x}ßðN_XÓ~ø‹JÕ4/¿‚5ý úµ½²¾½ŽâÞöZ)cw+"H*À‚ TÖ–¿ ì,íôë ¿XéñDÅo ‘Åh¢*«áU@0WEÿ &Ÿÿ@ÿàšëÿÑÿ &Ÿÿ@ÿàšëÿÑyyýâä¥{ÞøüËø[ÿA àÉøº<¿…¿ôð§þ —ÿ‹­ïøI4ÿúxŸÿ×_ünøI4ÿúxŸÿ×_ün‹ËÌ|´»Ãÿÿ‚`ù è#áOü/ÿG—ð·þ‚>ÿÁ’ÿñu½ÿ &Ÿÿ@ÿàšëÿÑÿ &Ÿÿ@ÿàšëÿÑyy‡-.ðÿÀà˜>_ÂßúøSÿKÿÅן¾)üiðĽbÓàÐñ7‰ü*ž¼6®«oý“¬·qyû\S³ýŸíºcb±.ô,\~„ÿÂI§ÿÐ#Äÿø&ºÿãuùÃñóMø½â/ŒÚí×Â=oLðÄÒøBóMQu}}ìwOy‘\-Øå…@Xåˆ\ΦàŽ#ÞV¤cïÝöò<ŒæS_ פUÿ3æ;ÿÚÃöܽñ7ˆ<‡—Kñ }r´÷’æYoEÍŒp¯&ª-âi–kÂÖï¸Â-ÁÏÍzÞ³ñ÷ö¸׋M¦® §‰4ÇÐþÇw½—FÈ.ãŸÌÕŠZØ»‰WiR»°+âšÏ‚¿okoÄžÕ~ ksxa|é°÷§NÒãÖMÍ“´zs\´±Gé’pˆ“y¨<¸xǦx¯Â¶ w¾:×Å«O xOQÔÖþ c{$'D´Õ`·º—He‰Ax™Œ‰/™ålÊ$|ìñU´³ÿÉ¥åä|¬0´µºÿÉWŸ™Ôh?¿kY¼E¡ÁâýV³Ðá7Ï&•x€Éá¶kø•¥ó5W+"ìgg@K Ù5(ƹ?ã×íÙ¦Üx H¼ðæ•ã+“ªëÑx’øêMmb,tï³0Õ$dwJë“ÐD$ðZWÂoÛ»L:=—ƒ>?hør×Åï¬j_Cw«Mý%äó=‚Êö*ËBð ËKbHÀJÓ²øqûbÚx³Á¯>6Ú\hÚE¾±‰aŸP¸k]HIK®Ý)b¶ŠÞx¤›Ê`î7˜ŒåAÊxª¿Íÿ“KÏ˯®ö)a©Y{¿ù,|¼ÿNçsiñËöÒ¾Šh.ŒZdgÂ:µ÷Ú£³u™µ¥.¶vˆ®²¡ÁF;·#”ûчù8XjÛ_ÅZ·Å_ ø6ÊÓK»Ð´&h®56Ü[êrYÚO<j¬W®Ì×h©Ž5 „ÌX74o†·|>ÓtýgãZêþ0‹Ãš Ô-ZkhµfkϳÏ0:D†áUe²*Ëål6Ì<¹CœÁñG¶W‡ü9=ï„Oþ;]…ñÃÑèz27‡Oþ;G•û7ÿÐÅðïÿÉÿÇk·ÿ…‡áßú<{ÿ„µÿÿ£þ‡è\ñïþ×ÿüf€8+öoÿ¡‹áßþ“ÿŽÑå~Íÿô1|;ÿÁòñÚíÿáaøwþ…Ïÿá-ÿÆhÿ…‡áßú<{ÿ„µÿÿ #Êý›ÿèbøwÿƒäÿã´y_³ý _ÿð|Ÿüv»øX~ÿ¡sÇ¿øK_ÿñš?áaøwþ…Ïÿá-ÿÆhˆò¿fÿú¾ÿàù?øíWìßÿCÿü'ÿ®ßþ‡è\ñïþ×ÿüføX~ÿ¡sÇ¿øK_ÿñšâ<¯Ù¿þ†/‡ø>Oþ;G•û7ÿÐÅðïÿÉÿÇk·ÿ…‡áßú<{ÿ„µÿÿ£þ‡è\ñïþ×ÿüf€8+öoÿ¡‹áßþ“ÿŽÑå~Íÿô1|;ÿÁòñÚíÿáaøwþ…Ïÿá-ÿÆhÿ…‡áßú<{ÿ„µÿÿ sDà(Ö4Ó k¾¸Öüåû*A¬¤’4‚¨î>Ø5í•ÀØxçB¾¾´³ƒAñ¤K Ey¼9{ hOvwˆ*r@®ú€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ ãþ!ÈÑx Æ’¤2Ü2éWL#Lnså7q'Üï]…r~<ÿ‘#Åÿö ¹ÿÑMYÕøYÙ—ÿ¼CÕ~gå‡öõ÷ý 'ÿ¾­øýÛ×ßô(øŸþúµÿãõÑÑ_ ̻־Æ_Îÿò9Ïíëïú|Oÿ}Zÿñú?·¯¿èQñ?ýõkÿÇ룢ŽeØ=Œ¿þäsŸÛ×ßô(øŸþúµÿãôo_Уâûê×ÿ×GE˰{;ü?Èç?·¯¿èQñ?ýõkÿÇèþÞ¾ÿ¡GÄÿ÷Õ¯ÿ®ŽŠ9—`ö2þwø‘Îo_Уâûê×ÿÑý½}ÿB‰ÿï«_þ?]s.Áìeüïðÿ#œþÞ¾ÿ¡GÄÿ÷Õ¯ÿ£ûzûþ…ÿßV¿ü~º:(æ]ƒØËùßáþG9ý½}ÿB‰ÿï«_þ?_2|aý‚~9~Ð)½øƒ£Gâ/ 蟅®ü<ÛE¦yóÛÜ\EpdiÍâÈt©‹iWp/¹~¾¯Ñï†?òO|ÿ`øôÖŽQKùjÝrë§üŸâe[†„©»ÞV×ÓÊÇòésÿdý¥ï<_¬‹CY¹ð\þ oAwye{Û\ØÈ8íaŽÞ³aÜ?'Þƒã/ø#¿Å¿]xÚçÅ6º–½oâ/i¾'Õ¬/ìt»›««;ŹL¨mØv˜ÈòÍØu濨J+µðvGÍ-<×ùy‘®,ÄëîÇ_'þgó5¬Á'¾;ëêk‹yâm­ük{ã:-: 2ÜX]Ü5±doþufÆXsçJp2ç5ø#ïÇmrÃÀº]æ¹ã ]/@»ñ=Í­¥•¾—¼««™ ‘¼Fý‘–&–M¥%[nW’¨Š*#ÁxUkJZy¯òóe¾/Å=Ô~çåçä,šoü›ãf“sá³§x§â–¥i¯áí6ÆÖçNŽ+Kk×Ê€o›åO<¨*ˆ»Ô Úºÿ‚=üZºÓümfº}õ«ë´ð¬-¬Z-8n^s5¼o©²‚ÆM»[;DP|ÄFþ h¦ø7 õæ—Þ½{¸·¾Ì~çéÜþV ÿ‚<þО&Õ>3ë4û›»íÅöþ"Ó"¶º°¹±O³ÏoÕÛÑEQEQEQEQEQEQEQEQEÇ|CˆOà/ÂÏ4júUÒ–Ê2æ&ä0äq]qþÇÿ ûÇÚ"&Óÿ²nüñ"†S”Û²QŒÔUøY×€þ<=Wæ~[Â3gÿAÿàÞãÿ‹£þ›?ú x¯ÿ÷ü]~kK­þ×6ºþŸw~k¾"6÷¶+¦è°¥ž›öûCçA3\ù“Bl–ñs"%Ç$_ºÚ29ß ^þÛ­¡øG]ñg‡¾ …ñ-µþ‰k¦hÉe$¬¶Í¤\\Iæ—Ž%at®¶òI!ýÞáó_ö2îIÿiÒ½½Ÿõ§‘ú—ÿÍŸýV’ô &mWh DË ½Ãù—A@Äî…¤ *Ix'Ä?ðPOøRûQ×ü5ð[Á–÷^Ò5]&h|9¦E«®¬f³–êÒ[k™|¸f1ØŠHÙØx#¿nÑþ=çØbó éP–-·œ“&½|žüîýͼK”Ÿ//ÅÑߣò=—þ¦ÿC?Ä_ü)¯øåð­4oúþ"ÿáM{ÿÇ+Šó?fÏúü/ÿÁD?ün3ölÿ /ÂÿüCÿÆëèOÆN×þ¦ÿC?Ä_ü)¯øåð­4oúþ"ÿáM{ÿÇ+Šó?fÏúü/ÿÁD?ün3ölÿ /ÂÿüCÿÆèµÿ…i£ÐÏñÿ kßþ9Gü+Mþ†ˆ¿øS^ÿñÊâ¼ÏÙ³þ€¿ ÿðQÿ£Ìý›?è ð¿ÿÿñºíáZhßô3üEÿš÷ÿŽQÿ ÓFÿ¡Ÿâ/þ׿ür¸¯3ölÿ /ÂÿüCÿÆèó?fÏúü/ÿÁD?ün€;_øVš7ý ÿð¦½ÿã”´ѿègø‹ÿ…5ïÿ®+Ìý›?è ð¿ÿÿñº<ÏÙ³þ€¿ ÿðQÿ ÊÏhÑxçÆ± WÄnW¼PÏ©ÌÌØ™ÆI-’}ÍrŸØ–ÿô׿ða7ÿZ^7‡ðšøÇì–¾[Oí[Ï(%¢ ç>06ð1Šæ7øþ}ü9ÿ€ÉÿÄ×j±ú…E¶ÝÍ_ìKú kßø0›ÿŠ£ûßþ‚Z÷þ &ÿâ«+€ÿçßßø ŸüMüÿ>þÿÀdÿâièiîy}æ¯ö%¿ýµïüMÿÅQý‰oÿA-{ÿñU•¿ÀóïáÏüOþ&þÿŸà2ñ4hç—Þjÿb[ÿÐK^ÿÁ„ßüUØ–ÿô׿ða7ÿY[üÿ>þÿÀdÿâhßà?ù÷ðçþ'ÿFîy}æ¯ö%¿ýµïüMÿÅQý‰oÿA-{ÿñU•¿ÀóïáÏüOþ&þÿŸà2ñ4hç—Þjÿb[ÿÐK^ÿÁ„ßüUCy¬k4ÝcÆ~Õ¼jºæŸcqqX^Î÷•”Š ,Ï I'Š¡¿ÀóïáÏüOþ&«Ý?|–ÛmáÜñÒÙ?øš°Ñ§*‘Œ”Zmuÿ€~|k_ðTÛÙü;ðËÄ>øñöÖúþKˆõQóÎ^ò(ÌrAbë [¡·É/ÌV顤_SѿࢶV©£ÜÞÍàoŒÚ_‰ŸJѦ·Ñ®‡ˆ(o'Õ¤³¼Y.ÆžWd0n€T.cÞH¾ ßàŸù÷Ð?ðøš7ø'þ}ôü_þ&š¦¼r;µMü£þGÉž&ÿ‚”~ÚzO‡¼Mâ]à—ÇÿÃg>‰tz†­o'Û,æi&±D)¥íXÂò‘*‚êŠk;Å_ðRÏÛY`øƒeá…´“¥x–ßK±¿ÕbÖg·Ô¬@dŽÚÕÙ¤Ú²c‘3H2ŠÿboðOüûèø ¿üMüAß@#ÿeéÿ|ÓökÈC‡})ýÑÿäO–|3ÿ)ý¬üP|{¤|=ø¯âMV×uêóCñ5ÍüVm§"G<‹*[ù%ð\C³ªº@$…ßÒ¿oÏÛWšÎÙ¼=ñJŠ_ ëô—²\x™ã¶¹·âÞÈ#i(Ï,„ä¡Úߺ“ËnMß@[Aðþʶ²Ó|/gl¿v8l£D_  SïðO{}ÿ—ÿ‰¡S^EG#Ãu?º>_Ýþ®|‹ü§öÁ×ïþ øsÁø…¯kÚ…t½jw¸ÔuˆZÚò{(.d¶º¶û'™ ó¢D…îƬ"ÚÛ‡èG†~8|^ñ‡t-rO‰ÿ­d»´ŠáãkÛ¸LlÊ 'Hæ^sÄˆŽª§Šò¸áðSOqሮ%Úe‘l4¸ˆ\œ™©·ø'þ}ôü_þ&š„|°ù6.ó…7òùXüø—ñ7Sø©ðÿOÕ>$xãSÓ¦Õ`ŽkyõxæBÜ«ÔJý|¯Â¯ áñ£á‡ØàÑVëûjßË)n¡ƒnìq_ºµÍˆJúqÖ:ðTc«}›wòH(¢Šç>(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š+”ñßü‰^.çñ-¹çþÙµuuÇüBó¿áñ§ÙÌBãû*ëg˜ ]ÞSc8çJίÂÎ̽ÿ´CÕ~gó©íOûJÁ«Y¶©û3ëøfçÆw¾ŽK+^{»{(uKKxõ c’ÉBÅ5”×Wk"–„}—Ë2nlb?Úëö¢Òfø]¤Ãû)üMøk¨Çâ®ëí j:*ØËi5ÏØZIÊž|Ilû˜o8ˆË:”¯Ð|xÇþzøSþýOÿÅQÿÏ_ ß©ÿøªø¾höGõ%oç—ܼÏ?ö¿ý¬o<kâkÏÙ^ѼMÿ…îºú4öä’ÞjQÉv°ÙB`²G»È·Ü³”˜ý±Y• 5¾*þÚþÛOwª|%Ó¯'»ÿ„6ÏJYt}~ÖÆâÿS¹–»xç–Í^âxCZ²Û* pe ¡•ÂþˆcÆ?óן÷êþ*£’Leÿ„BP0 Çt<·Z/È—N¿-”åDxŸÀÿŠŸüoã‰:ņð­ì¬—N»Ð£[[æim§²·–TšéÓì’ËòMH°òX²¨Áo¥¼É?ç£þuÌãÆ?óÓŸ÷êþ*ŒxÇþzxSþýOÿÅVm\ï£VQV•ßÈé¼É?ç£þty’ÏGüë™ÇŒç§…?ïÔÿüUñüôð§ýúŸÿŠ¥Ëækõ—ü¬é¼É?ç£þty’ÏGüë™ÇŒç§…?ïÔÿüUñüôð§ýúŸÿŠ£—Ì>²ÿ•7™'üôÎ2Oùèÿs8ñüôð§ýúŸÿŠ£1ÿžžÿ¿SÿñTrù‡Ö_ò³¦ó$ÿžù×èçÃ"OÃïI?Ùðõÿv¿/qãùéáOûõ?ÿ_ Ÿcø¢| á#mwà·û[ÛÜ–ÆÞÿ={9*÷ß¡ùŠuy°”ôkÞýîôWžy?çóáçþ\ÿñÊ<¿‹óùðóÿ®øå}!øqètWžy?çóáçþ\ÿñÊ<¿‹óùðóÿ®øåzçž_Åùüøyÿ€×?ür/âÇüþ|<ÿÀkŸþ9@‡Eyç—ñcþ>à5Ïÿ£Ëø±ÿ?Ÿ?ðçÿŽP¡Ñ^yåüXÿŸÏ‡Ÿø sÿÇ(òþ,ÏçÃÏü¹ÿã”ù%ñÜøûÇ$»ý³}ßþ›½r;ßûÍùÖ‡Š?á9ñ¯'‡ ßÚ÷›öG.ÝÞ{çlã5ÊcÄóÓ@ÿ¿rÿñUÜ™ú½žâÑìmïï7çF÷þó~u‰ÿÏMþýËÿÅQÿÏMþýËÿÅS¹¯´òfÞ÷þó~toï7çX˜ñüôÐ?ïÜ¿üUñüôÐ?ïÜ¿üUiäͽïýæüèÞÿÞoα1â?ùé ß¹øª1â?ùé ß¹øª.ÓÉ›{ßûÍùѽÿ¼ßbcÄóÓ@ÿ¿rÿñTcÄóÓ@ÿ¿rÿñT\=§“6÷¿÷›óª×nþC|ÍÔw¬Üxþzh÷î_þ*«Ýù-ºMtŽ_þ*œ^§N §ï¡£Ý~c÷¿÷›ó£{ÿy¿:ÈÆ½ÿ=4Oû÷'ÿF5ïùé¢ß¹?øªÞçß{gÙšûßûÍùѽÿ¼ßdc^ÿžš'ýû“ÿŠ£÷üôÑ?ïÜŸüUlû3_{ÿy¿:7¿÷›ó¬ŒkßóÓDÿ¿rñTc^ÿžš'ýû“ÿŠ¢áíŸfkïï7çF÷þó~u‘{þzhŸ÷îOþ*ŒkßóÓDÿ¿rñT\=³ìÏhø$Ì~/ü7Ë7ü…íûÿµ_µµø}ð4k?ð¸þùϤ¶m÷lIcwlœWî qbž¨ü‡ÄißOü?¨QEÊ~tQEQEQEQEQEQEQEÇüCG—À^4Ž9¤¶vÒ®€‘,‡ÊnFàFG¸"» ã¾!ÃÇ€¼k»ÌO¥]#mr§&H#êk:¿ :ðLJªüÏËOìM[þ‡/ß‹Oþ1Gö&­ÿC—ˆ?ïŧÿ¤ÿ„GBþæ¯ÿƒK¿þ;Gü":÷5üÝÿñÚøŽeý$V{ ¿òy¿Øš·ý^ ÿ¿ŸübìM[þ‡/ß‹Oþ1IÿŽ…ýÍ_ÿ·üvøDt/îjÿø5»ÿã´s/é ö;äòÿ!±5oú¼Aÿ~-?øÅØš·ý^ ÿ¿Ÿüb“þ ûš¿þ nÿøíðˆè_ÜÕÿðkwÿÇhæ_ÒAì*vÿÉåþBÿbjßô9xƒþüZñŠ?±5oú¼Aÿ~-?øÅ'ü":÷5üÝÿñÚ?áп¹«ÿàÖïÿŽÑÌ¿¤ƒØTíÿ“Ëü…þÄÕ¿èrñýø´ÿãbjßô9xƒþüZñŠOøDt/îjÿø5»ÿã´Â#¡sWÿÁ­ßÿ£™I°©Ûÿ'—ù ý‰«ÐåâûñiÿÆ(þÄÕ¿èrñýø´ÿãŸðˆè_ÜÕÿðkwÿÇhÿ„GBþæ¯ÿƒ[¿þ;G2þ’aS·þO/òûVÿ¡ËÄ÷âÓÿŒWèGà øŠ_øJDøŸã[dkˆ-tݨ6ôµ'ó&¿=¿áп¹«ÿàÖïÿŽ×è߆>¹ð'„§“þ#ØDÇoˆ5ÛØ ð? örfœß¡ùŸ‰ôä°´ù—Úþfú>èîÿáñ/ýoÿà.™ÿÈ”Ââ_ú*Þ9ÿÀ]3ÿ‘*øU^õñgþZÿ£þWƒý|Yÿ…£ÿÇëèÅ ÿáñ/ýoÿà.™ÿÈ”Ââ_ú*Þ9ÿÀ]3ÿ‘*øU^õñgþZÿ£þWƒý|Yÿ…£ÿÇèøCüKÿE[Ç?ø ¦ò%ð‡ø—þŠ·ŽðLÿäJƒþWƒý|Yÿ…£ÿÇèÿ…Uàÿ_áE¨ÿñúŸþÿÿÑVñÏþéŸü‰Gü!þ%ÿ¢­ãŸüÓ?ù ÿ…Uàÿ_áE¨ÿñú?áUx?×ÅŸøQj?ü~€'ÿ„?Ä¿ôU¼sÿ€ºgÿ"Qÿ‰è«xçÿtÏþD¨?áUx?×ÅŸøQj?ü~øU^õñgþZÿ åßöÁý¹tŸÙßö‰øðó]Ò|]â+]:_U¼¼[›®¯gImÚ(`·ò·ºÈ.3X·E"J6<ãÆðQxž.ñÞ½ xäøfÆÃ@Õ´¸íïtéu-rÇR´†çÏKA™„JÈÅÎÖ’'@Û¸¨þ;ðæ•Žf Q韷—†uOúV›á?‰³Ýê:–¥`‘›½eD´µŽéÙc-¾Y¼¹6XÃN“/”ȃ_~ÿ`é¿õÿÀûþ.ý…§sΧÏ_ôûþ.™¯Õë7âÏͯÿÁEüâo i¾8·Ò|i¤iwñ¾šn¥y¦[j—2éû4P¸ŒÈò237DÉÕ[]×í»dúgŽo4=TÖ5­Ásø°hÛšZÞÜÉm©Ocym•FEX¼4MÊf2#c_rÿ`i½?âcúÿ¸ÿâéN…§0 L‚6ÿÇýÇOO¿E˜ý…nÿ‹>øyûrØ|FŸáÄ–^ ñ¿†ô]wÄ2øvêÿVÕ´˜ Òî>dj)K‰\‡_³£yªÊÒX ûôé·à|C«ÿ\­ÿøÕ`øgáÇ‚< é¾ð‡íü-á›$1Ùéú|ÒÛÛZ¡bÅR4`ª73ÔšÜÿ„Kþî¡ÿ×ü]4™t¨ÔKÞ׿ÇfßÿÐū߻þ5Uî´ëÿ%ü$:±éÿ,íÿøÕMÿþ—ýÝCÿ®?øº¯uáý,BÇmÿoù~Ÿÿ‹¦¯s» {hiÕu}ý ¿ìûïúêŸ÷îþ7Gö}÷ýõOû÷ÿ¦ÿ`éŸÜ¾ÿÀÙÿøº?°tÏî_àlÿü]ocï=œûäÒÿ!ßÙ÷ßôÕ?ïÜünìûïúêŸ÷îþ7MþÁÓ?¹}ÿ³ÿñt`éŸÜ¾ÿÀÙÿøº,Î}¿òiïìûïúêŸ÷îþ7Gö}÷ýõOû÷ÿ¦ÿ`éŸÜ¾ÿÀÙÿøº?°tÏî_àlÿü]g>ßù4¿Èwö}÷ýõOû÷ÿ£û>ûþƒú§ýûƒÿÓ°tÏî_àlÿü]Ø:g÷/¿ð6þ.‹³Ÿoüš_äz¿ÀÛÈþ1ü3wÖµÐkä£G ót8ŒÈ×î ~| Ñ´ø>2|3š5¼óY·#uÜÌ3»Ð¶ã_¸uÅŠÝ’x‰±ïü½ÛëæQEsž…Q@Q@Q@Q@Q@Q@Q@qÿÝâð$Ž.]t«¢#B9ò›¸“î@®Â¹?È‘âÿû\ÿ覬êü,ìËÿÞ!ê¿3ò¿ûoVÿ¡7Ä÷þÓÿÑý·«ЛâûÿiÿÇ뤢¾™v?­=Œ¿þäsÛz·ý ¾ ÿ¿öŸü~í½[þ„ßßûOþ?]%s.Áìeüïðÿ#›þÛÕ¿èMñýÿ´ÿãômêßô&øƒþÿÚñúé(£™vc/ç‡ùßöÞ­ÿBoˆ?ïý§ÿ£ûoVÿ¡7Ä÷þÓÿ×IE˰{;ü?Èæÿ¶õoú|Aÿí?øýÛz·ý ¾ ÿ¿öŸü~ºJ(æ]ƒØËùßáþG7ý·«ЛâûÿiÿÇèþÛÕ¿èMñýÿ´ÿãõÒQG2ìÆ_Îÿò9¿í½[þ„ßßûOþ?_¡9ÿÀ­3ÿ’ë¿¢¾ü<à?á0ñ/ýŸÿàV™ÿÉtÂaâ_ú%>9ÿÀ­3ÿ’ë¿¢€8øL{ðq)ÄŠå´¯ÿè^Õ¿ïí¿ÿ¯Føÿ#÷Žì3}ÿ£Þ¹ï[«ÐƒäZôòÿ#ûJÿþ…í[þþÛÿñÚ?´¯ÿè^Õ¿ïí¿ÿ­Š)šò>ïðÿ#ûJÿþ…í[þþÛÿñÚ?´¯ÿè^Õ¿ïí¿ÿ­Š(GÝþäcÿi_ÿн«ßÛþ;Gö•ÿý Ú·ýý·ÿãµ±EÈû¿ÃüŒí+ÿúµoûûoÿÇhþÒ¿ÿ¡{Vÿ¿¶ÿüv¶( 9wø‘ý¥ÿBö­ÿmÿøíWºÔoÌ-ÿö¬9òÖßÿŽ×A\ߌa×î|)â; ^éúoŠd²4Ë‹¸ÌAvPˆžE²‡ÚHî¡ntààý¬u{®Ýý ßí ïújŸ÷òþ9Gö…÷ý5Oûùÿ¯ÍÀÿðPÝ_ÅÞ,ð–½ña´ŸÊ–Ú¸k"‡Q˜j ŠXôèÞk˜›ìÒí†4U`!˜’ÃÔ'ð_í£öMgû+ĺ5…õÇ…´{în¼U ÍÄz…½äw$ñ(X#’âÞM¾{E"«Æ¿¹ÆÓ˜úøâdÕí/¹‘ö·ö…÷ý5Oûùÿ¥þоÿ¡Uÿ¿ñÊüòñÂÛËľñ7‡uߌZtŸÚ7º<ŸhмAqemͳ^Em2iNñ ˆVå~bìãÃ*†SêËàŸÚbßYWÙ¦“kñ:-~ÊKÜ$§Ã_gò¤³‘#° !È,°¹uù2–]äæe*òoi}Ëü­¿´/¿èªßÈ?øåÚßôÕ?ïäür¾ ´øqû|èºÿmtόּcâ b}uõ‹˜g¿×4égÝh±ºX"Ûâ&1$e|9’DÄb-;á÷ü*ÖÛáâ¿Æ/ÜÞ[øOQƒÄFþkiÖó_xæX%ˆÃ¦EˆQ¼†Q´mù·¬»q#æd¬LûKî^_çø3ïí ïújŸ÷òþ9Gö…÷ý5Oûùÿ¯†5†ÿ¶µö•ã›Eø–ß¿ðtVRxŽÆ7[7™..&‡EVÀ… Pñ ŠOÝ):s±x[öíñ®§ñÂi|q¨xHƒÄÖOá‹}e —±Ie,ÐÛÜÿf¾Ûg_·D%&y3cˆ+o.%Ò_rÿ#õ{àmõäŸþ£èºŒu‹p]¤„…ùºœHOä+÷¿þ›£ñOáQ¾Hã¾þÒ´ó•z¬œn°»†sÎzàt¯ÛŠäÅnÌôû¥,Ã>7u·wÇþC§õzßÊþàþÙË?çü?ð5þfößô3ø§þÿEÿÆèþÀ›þ†ÿßè¿øÝ2ÓÅ6÷ºÞ™acâ+íKL’8u+xt»‡—N‘ãY&P™‰š7W€%YXpA­/·Ý|§þ¯`Œø‘Ýò?ïß±£êõ¿•ýÁý³–ÏøàküÊØÐÏâŸûýÿ£ûoúüSÿ¢ÿãu}ïî“q xÙãvt;±Œôÿ–uήöv÷wšŒ--!ŒÍ,²è×H‘FK³ðª''Ž(ú½oåplåŸóþøÿ2¯ößô3ø§þÿEÿÆèþÀ›þ†ÿßè¿øÝO´&Ž9¢Ñ<],N¡Ñ×Gº*êFAGÈ#½?û]ÿèãüÝñº_W­ü¯î휳þÃÿ_æUþÀ›þ†ÿßè¿øÝ~‚ü9ðUäÞð”«ãÿÀ­a³Ûá~^ƒ0×ÀŸÚïÿ@ÿà–ëÿ×Û>øßà-Á¾Òõ#âûkû{8âš?øGuØÀr2! þëåªFo5§cóŸ1ØJ¸jkR2j]$ŸGæÏVÿ„ûþŠ'ÄûÿoÿÆhÿ„ûþŠ'ÄûÿoÿÆk•ÿ†økÿ?.ÿÂoQÿãÃ@ü5ÿŸá7¨ÿñŠ÷ÏÇN«þkïú(Ÿ?ïý¿ÿ£þkïú(Ÿ?ïý¿ÿ®Wþá¯üüx»ÿ ½GÿŒQÿ ð×þ~<]ÿ„Þ£ÿÆ(ªÿ„ûþŠ'ÄûÿoÿÆhÿ„ûþŠ'ÄûÿoÿÆk•ÿ†økÿ?.ÿÂoQÿãÃ@ü5ÿŸá7¨ÿñŠê¿á¾ÿ¢‰ñþÿÛÿñš?á¾ÿ¢‰ñþÿÛÿñšåá ~ÿÏÇ‹¿ð›ÔøÅðÐ? çãÅßøMê?üb€:¯øA¯¿è¢|@ÿ¿öÿüføA¯¿è¢|@ÿ¿öÿüf¹_øh†¿óñâïü&õþ1Gü4Ã_ùøñwþzÿ ÉßhòÇã¯ÆuÿÊWW¼]Ï,e›¿' Ö¹Oì™?è7®ÿßÔÿâ+Ѽa¯ªx»Åz¥…üa=Χuq ÿdÜ ñ¼¬ÊpS# ޵Îdø‹þ…/àªþ&»T—sôÊ8¼7"¼×ßÿç?²dÿ Þ»ÿSÿˆ£û&Oú ë¿÷õ?øŠèÿ²|EÿB—Œ?ðU?ÿGöOˆ¿èRñ‡þ §ÿâió.æŸ\Ã:ûÿàœçöLŸô×ïêñdÉÿA½wþþ§ÿ]öOˆ¿èRñ‡þ §ÿâhþÉñý ^0ÿÁTÿüM˸}s üëïÿ‚sŸÙ2Ðo]ÿ¿©ÿÄQý“'ýõßûúŸüEtÙ>"ÿ¡KÆø*Ÿÿ‰£û'Ä_ô)xÃÿSÿñ4s.áõÌ7ó¯¿þ ÎdÉÿA½wþþ§ÿGöLŸô×ïêñÑÿdø‹þ…/àªþ&ìŸÐ¥ãüOÿÄÑÌ»‡×0ßξÿø'9ý“'ýõßûúŸüESÔ,µÅÌúî¶F¦Gf‘0ª9'îvºÿìŸÐ¥ãüOÿÄÕKÃþ ¾±º² øà$¨ccŸu€F W@£)A…%}ÎŒ&7 ªÅ¹­×_ø'Ë~Ðÿf°°¿í#k¯ 7‹í­^áVê}c–Ct°˜÷•ÙÇÜ|§ãå8žÿãÿÀÍ"ã[´Ö¾4Yh—n…câ]@^N![M2ì…¶¸fhöâF!@¶X dŒËiûü/²µÓìí¾üXHí,³-µ}¥‚ØG{dk‚ã ¨Þ¨9È ‚0¸³®þÆß ¼M¡ kŸ þ(jÑ-<;-«j:ØK« i –ñ͉¿~Ñm’Iº@¨m§|˺>¥fÔ-üZwÿü3Wý¢gÍÞgö€ð¾›öd²’7Tˆ–ëoÙ³òu—zmItË Ï'ÇÏÖ×ÖºmÿÆ?I¾¸Ö®<=kåÚ@nõR'–÷ ÜUgˆ’8ÃŽkCþïáÒÛ%•¯Â¯Šzfž—v:„V¶Zž¹k½Í©ŒÁ4qÅ:¬n™™@.Ñ«>â3\÷‰ÿbø¯Æú/uüaq³}¯j:\·•Å–¹yqn1™&f)¤h0˜â`ª®ŽªªeÝÍèÏÚøüоxïÀ¿4;ü9ñýß‹4(¯n4énmÛj¥Ì.c–20r¬¥4ÇsSÊí$žRLY`Fvfòâ›™ˆ\“]öŠèNñþ çÿâj”£Üê§›`¹W=h_ÊküÎcû2Oú k_÷ñ?øŠ?³$ÿ Æµÿÿˆ®ŸûÅ?ô'xÇÿsÿñ4`x§þ„ïÿà®þ&Ÿ4;—ý­€ÿŸÑÿÀ×ùoÀÝ=ãøÇðÎCªjÒ…ÖmÎב ·ÍÐüµû_Œ´_AñsáÌ×>ñM¬ «Û—–]:dDº–+€=Í~Ï×!«è~[Ǹš5kÓt$¤­ÑߨQEÎ|QEQEQEQEQEQEøëûKÿÁ)¼9ûG|føÓñ·Vñˆ´/x‹AµÑ |;ø“'ÄÿŒÞ"ñ‡µ 2þ3w«!K¡h4Å0iÛºióǃ¸„Ô®FOVôÿþÉmào–ÿ¢ñ‡Äí_Y‹TÔïÓMŸRmD—ÕÄ–˜cË«¡ÎÜŸìÛSÛåûÐуèhþÙ­äñ ²Ïï}ÿðÉk/ø&¶·kci¦?íûBI¦Å¥øŸKH#Ô¡‰bMZc2!î2Eæ³–‘¤22§1ì\z©û[?Œ4x_âÇOèšwŒ4ÿiš ®½Yiv6èÌt¨Gš¬±5Ì·7F,Ên=¬Š€~“àú0} Û5¼…ÿË,þ÷ßÿø'Ÿ±ž•à]köP×<«xËÃ÷¿ ÒêrÅqlÒüAžXcŽIïݤ Èþ_.DŽŠ# ¯*Õ¿a_ˆG⟉t_ŠG‚u?êÞ0ñ5¤ºè†cg<"H´¨QKùñýº†’IcÚ–b$l² ýKÁô4`ú?¶kyþ!–Yýï¿þùÿð+ö3¹ø ñáï´OüLñF— Bñ¦«]Á<.íc ¼²Äí)0<ÒFóÌ@1åÇË·-ãzÇüVçÄgö·ñÏ㎡á‡Ô|Uy>˜×Ð y¡Ö-â‰á`f,æ?-‰iLÖiSb)ýdÁô4`ú?¶kyüC,³ûßüžð Þ¯à_x'ÀñøY¯ãÑt{-%gŽæ uœA DF„`ìÎÝÇÆMuŸðšë_ô&\àÆ©ƒèhÁô4lÖòø†Yg÷¾ÿø¿øMu¯ú.?ðc zîàŸ‰úî•§ë6> °ûÌK4[õˆƒm###i¯Áô5ú;ðËþIìþƒ^–[Ž©VMLø~9á,&]B0÷»vÕß§¡òçü+?‹_ô%éŸø9ÿˆ£þŸÅ¯úôÏüÇÿÄWÛ´W²~b|Eÿ Ïâ×ý zgþcÿâ(ÿ…gñkþ„½3ÿ1ÿñöíñü+?‹_ô%éŸø9ÿˆ£þŸÅ¯úôÏüÇÿÄWÛ´PÄ_ð¬þ-З¦àæ?þ"øV¿èKÓ?ðsÿ_nÑ@³øµÿB^™ÿƒ˜ÿøŠ?áYüZÿ¡/LÿÁÌüE}»E~Jêߧѵ]OG½ð^§öËK‰-fÙ{.ôb­ƒžFA¬ÿø]‹ÿB^±ÿpqÿÂ}ãžü†o¿ô{×#ƒèk©QGÞÒáÌ;Šnÿyì¿ð»þ„½cÿàÿ?áv/ý zÇþÁþ5ãX>†ŒCOØ¢ÿÕ¬7ŸÞ{/ü.Åÿ¡/XÿÀ¸?Æø]‹ÿB^±ÿpxÖ¡£ÐÑìP«Xo?¼ö_ø]‹ÿB^±ÿpð»þ„½cÿàÿñ¬CF¡£Ø ÿV°Þyì¿ð»þ„½cÿàÿ?áv/ý zÇþÁþ5ãX>†ŒCG±Aþ­a¼þóÙáv/ý zÇþÁþ4ÇøßjY¼¬cþ¿ ÿñÜC\ÿŠíõ›¯ ëöÞ¹µ±ñ¶sGa=Àc7%ßoÍ´1ãœ(TQ¶…𲩻ê×Sß?á{BrG‚õ“ÿop'ü/x?èLÖ?ð2ñ¯Åíö]ý¬u« ·Å¿ÒêÞ)Ó<â] cEñV¥jcÕ/e—ìZƒ[%´qÜIo G’F ïPHæÞ©ð+öòºº×ŸJý¤4=#FŸÂÖº^Ÿ§.«pò麔rÀ^èÞ>žÏ3²G12˜Á>~ÃUVì#Ø÷àíwNzÿ/ó?e¿á{ÁÿBf±ÿ(øí 8 ÖIÿ¯¸?Æ¿þ |ýµ5h<|>~Òï໋­GJ“B7š´—ÂÏOŠÍcº…÷X.W¸_;Íhu-$`œó~'ýžÿnÿEãí?Qý¡ü>‰}â{m_G¶¶Ôol œr‡6ï$v'•„Oôum¬]ÿx cØG³ pN ˹ýëúÿ‡?iÿá{ÁÿBf±ÿð½¡ëÿ^±úüƒükò;Â??m 9ô©|+øõá/ˆoо |T¸ñÞ…?†¢ÓoìeÕ®vW±Ü\ȲEoäùs¹ŠX#{†xܘŠ6ñ·êÌCT°ñ:©pJíI|×ù\ü,øÉ³ñ#ÁHð¦«hnu(bµÔ,#Éê@9?…~£WâÁ áoü6àÿÈbßÿB¯Úêç¯MEè|ät05¡ ³W×Ô(¢ŠÀøð¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢¿jOÙÿþ 1­þÕ¾6~ÏŸõ­+ÀZG†í¿áðmíÌÒi>.Ö :šOðù« ¾k|çBìÖñªº'›?h_ðSË…~?ñ|áMSâ´wÞðîŸk 1\X*Y>ªÏ9œÆ.$/jα#E UƒPî}qßáŽãÀ^4‚`Z'Ò®•€b¤ƒg‘Èü+ùñž×þ t¶w_føCð…ïd´ðôˆd{p¶“´ñ3‰TOûí³ãçgŒƒƒ¶ÒzÏ~ÿ‚ j²sXh6¶øÓ©_ë‰âIìÒÞÊ/è§í"ËìòÍ/–v¢Û´Ò’ÒâGÚ„‚Í]4m‡©ÉR3µìÓ>˜ÿ„WÃÿóíwÿ×ürøEtù÷»ÿÀûþ9_‘šŽ¯ÿ&—Pñ§‰-<û9ÛÜ%ž¯aá­&КÑ]î´Æ´ººf`ehâ’.6åBo ì zgÆ+OÛ¼wàïü±øŸ‚í­áû‰lŸqâFÒµ=Y&o–ïÌ+DArP¹dF)àÿd?ùùý}çëßñãÿ@ÿj~“ÿÂ+ ϽßþÜñÊ?áÐ?çÞïÿî?øå~vxQý¸&ñç€/<¤þÉ–Ÿ~ß§/ˆlm4›<ÙìÅ»dJ̲.¬à&áºÖÝW*ùi¼S«~Û¶~)¸ÿ„?Ãÿ²&·áYÿá,š!y§YÂö!..“Dˆ3³À¶r3à2YÒQªd?ùùý}áÿ?ôøÿö§èoü"ºüûÝÿà}Çÿ£þ]þ}îÿð>ãÿŽWæ³Mûnø›ÄW}Ö‰û4x7Âqÿc\išƒÁbnÖP©ö£w´ÛeÚÆo2Ì,¢!·ÏTÄ¿ðP‰üëGá×ìy§ÁqáëkÆ´ÓÆy´íFMDyöqI<ˆ³M ™`’HÞGPÅ”ü´d?ùùý}áÿ?ôøÿö§éÇü"ºüûÝÿà}Çÿ£þ]þ}îÿð>ãÿŽWæ¶™ðûöª±Õ¿eVÓÇ¿ M7áÖ•¡üB·Õ…í­Æ¼d¨^²©Ss)Xc%¬Ҳ “ži5_ø(þ£¡4§Cý¼7­GhÌ‘>•¦N×7_f””|LQ#+ÆÊK$V“lÔÙþ~_xÄGýþ?ý©úÿ®ÿ>÷øqÿÇ(ÿ„W@ÿŸ{¿ü¸ÿã•ð_íí!â[VÐ>é~ÊpkúOã¤~ÒòøZñå´ó§ÛÞËK+z¦îä«¡´ÎWÉ6ø*0Èl};çüÿŸO‡ßøÿGöCÿŸŸ×Þñãÿ@ÿjbÿÂ+ ϽßþÜñÊýøsð×Â>ð•Ä–š·˜ö1Û«]¾‚\ øSÏø'ÿ>Ÿ¿ð þ"¶ ²øi41Ëm¡xn[v£G¥‚¬=ˆLb»p8'JM¹\ù^+⥣j‡³³½ï¾žˆýÿ…]àßùôÖðoyÿÇhÿ…]àßùôÖðoyÿÇkóóû;áßý úþ ¿û ?³¾ÿп ÿà«ÿ°¯LøSôþwƒçÓYÿÁ½çÿ£þwƒçÓYÿÁ½çÿ¯ÏÏìï‡ô/è?ø*ÿì(þÎøwÿBþƒÿ‚¯þ€?@ÿáWx7þ}5ŸüÞñÚ?áWx7þ}5ŸüÞñÚüüþÎøwÿBþƒÿ‚¯þÂìï‡ô/è?ø*ÿì(ôþwƒçÓYÿÁ½çÿ£þwƒçÓYÿÁ½çÿ¯ÏÏìï‡ô/è?ø*ÿì(þÎøwÿBþƒÿ‚¯þ€?@ÿáWx7þ}5ŸüÞñÚ?áWx7þ}5ŸüÞñÚüüþÎøwÿBþƒÿ‚¯þÂìï‡ô/è?ø*ÿì(ç_x{F‡Ç^5†8.4ÕïA»˜î%òå?°´Ÿùã?þKÿÅWÑó^|ŽYc¸‡á¤w Å]d´€2°<‚ äúÔnøÿ<þÿà-¿ÿ[ª¾GÖÈ"¢—²þ¾ãçOì-'þxÏÿRÿñTai?óÆü —ÿН¢þÝðþyü/ÿÀ[þ&·|ÿž ÿðßÿ‰§í|ŠÿX£ÿ>¯¸ùÓû Iÿž3ÿàT¿üUØZOüñŸÿ¥ÿâ«è¿·|ÿž ÿðßÿ‰£íßçŸÂÿü·ÿâhö¾Aþ±Gþ|ÿ_qó§ö“ÿûu·ÿâhU¼hq,c5/c{?ë¡ò¿ö6—ÿ<¦ÿÀ™øª?±´¿ùå7þËÿÅWÔÿÚ³ÿ§ÂÏü¶ÿâhþÓýŸý>à-·ÿZ{uØú/õò?ô øÿö§ËØÚ_üò›ÿeÿâ¨þÆÒÿç”ßø/ÿ_SÿiþÏþŸ ?ðÛÿ‰£ûOöôøYÿ€¶ßüMÝvõò?ô øÿö§ËØÚ_üò›ÿeÿâ¨þÆÒÿç”ßø/ÿ_SÿiþÏþŸ ?ðÛÿ‰£ûOöôøYÿ€¶ßüMÝvõò?ô øÿö§ËØÚ_üò›ÿeÿâ¨þÆÒÿç”ßø/ÿ_SÿiþÏþŸ ?ðÛÿ‰£ûOöôøYÿ€¶ßüMÝvõò?ô øÿö§–| Ò´è¾1ü3–8å.³nW7wzÁ¯Ü*üÊøaðNOˆž M|9þØ:Œ"ÛìÖÐ,¾fxÚBä¥~šÖgÌö±ñÜKœ¬mHÍSä²·¯à‚Š(¬š (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ äüxHðG‹È8?Ù—?ú)«¬®?âÊþñ¢Á*C9Ò®‚;&ð­å6 úd}k:¿ ;2ÿ÷ˆz¯ÌüÚó$ÿžùÑæIÿ=ó®cì>+ÿ¡“EÿÁKÿòEañ_ý š/þ _ÿ’+á¹WÌþ´öóþGÿ’ÿ™Óù’ÏGüèó$ÿžù×1öÿÐÉ¢ÿà¥ÿù"°ø¯þ†Mÿ/ÿÉr®ÿ˜{yÿ#ÿÉÌéüÉ?ç£þty’ÏGüë˜ûŠÿèdÑðRÿü‘GØ|WÿC&‹ÿ‚—ÿäŠ9WÌ=¼ÿ‘ÿä¿ætþdŸóÑÿ:<É?ç£þuÌ}‡Åô2h¿ø)þH£ì>+ÿ¡“EÿÁKÿòE«¿æÞÈÿò_ó:2OùèÿdŸóÑÿ:æ>Ãâ¿ú4_ü¿ÿ$QöÿÐÉ¢ÿà¥ÿù"ŽUßóo?äù/ù?™'üôÎ2Oùèÿsañ_ý š/þ _ÿ’(ûŠÿèdÑðRÿü‘G*ïù‡·Ÿò?ü—üὈþz?ç_£Ÿ ‰?¼I$ÿgÃ×ýÚü¼ûŠÿèdÑðRÿü‘_ ŸtŸ‰mà? 5·Ž<'Â-Šþ‘™FÞ„ý¬gò¯k%^ûסùŠu%,%;ů{˳ìÙïWÿcüQÿ¡ïÁÿøNKÿÉ”cüQÿ¡ïÁÿøNKÿÉ•ôgáç¢Q^wýñGþ‡¿ÿá9/ÿ&QýñGþ‡¿ÿá9/ÿ&P¢Q^wýñGþ‡¿ÿá9/ÿ&QýñGþ‡¿ÿá9/ÿ&P¢Q^wýñGþ‡¿ÿá9/ÿ&QýñGþ‡¿ÿá9/ÿ&P¢Q^wýñGþ‡¿ÿá9/ÿ&QýñGþ‡¿ÿá9/ÿ&PäŸÄsãïìOöÍ÷únõÈïï7çZ<´ññÏDÚî—,ÃW¼˦²†o=ò@óŽ>™?Zå>˯ÐkNÿÀÿãµÞ¶?W¡7È´éåþfÞ÷þó~toï7çXŸe׿è5§àñÚ>˯ÐkNÿÀÿã´Íyßgø™·½ÿ¼ßßûÍùÖ'Ùuïú ißøßüv²ëßôÓ¿ð¿øíÎû?ÃüͽïýæüèÞÿÞoα>˯ÐkNÿÀÿã´}—^ÿ Öÿ€ ÿÇhwÙþæmïï7çF÷þó~u‰ö]{þƒZwþ7ÿ£ìº÷ý´ïüoþ;@s¾Ïðÿ3o{ÿy¿:­vïä7ÌÝGzÍû.½ÿA­;ÿÿŽÕ{«]wÉlë:qòàßüv„õ:pU¶†uÛ¿¨ýïýæüèÞÿÞoαþÏ­Ð[OÿÀÿã´}ŸZÿ ¶Ÿÿ€-ÿÇk{Ÿ{í¥ü¯ðÿ3c{ÿy¿:7¿÷›ó¬³ë_ôÓÿð¿øígÖ¿è-§ÿà ñÚ.Ú_Êÿó67¿÷›ó£{ÿy¿:Çû>µÿAm?ÿ[ÿŽÑö}kþ‚Úþ·ÿ¢áí¥ü¯ðÿ3c{ÿy¿:7¿÷›ó¬³ë_ôÓÿð¿øígÖ¿è-§ÿà ñÚ.Ú_Êÿó=§à“1ø¿ðß,ßò·ïþÕ~Ö×áïÀØ5eøÇðͦÔ줈k6å•lÊ–ºgÌ8ü~áW+t~Eâ4›ÄSº·»åßÈ(¢Šå?: (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ äüyÿ"G‹ÿìsÿ¢šºÊæ¼eiy¨xGÅ:u¬—×ói÷C ²«K!‚¨,B‚O$R**«Å£«5ð”¶M~gæeÝÿ¦ø½ÿDË[ÿÁŽÿÉ4¦ø½ÿDÏ[ÿÁŽÿÉ5ñ¿Q­ü¬þœÿ[²Ïùÿ¼á(®ïþ7Åïú&zßþ tïþI£þ7Åïú&zßþ tïþI£ê5¿•‡úÝ–Ïøýç Ewð©¾/Ñ3Öÿðc§òMð©¾/Ñ3Öÿðc§òMQ­ü¬?Öì³þÇï8J+»ÿ…Mñ{þ‰ž·ÿƒ;ÿ’hÿ…Mñ{þ‰ž·ÿƒ;ÿ’húoåaþ·eŸóþ?yÂQ]ßü*o‹ßôLõ¿üéßü“Gü*o‹ßôLõ¿üéßü“GÔk+õ»,ÿŸñûΊîÿáS|^ÿ¢g­ÿàÇNÿäš?áS|^ÿ¢g­ÿàÇNÿäš>£[ùX­ÙgüÿÞp•ú=ðÇþIìþƒ_¦ø½ÿDÏ[ÿÁŽÿÉ5õσu¿hðþ‰}ð¯Ç-ykk2˜îtÂ¥€ÁÁû_"½l£8M¹«h~uâ>w„Åa©ÃQI©_GäÏd¢¸øL¼AÿD«Çÿ÷ÿLÿäÊ?á2ñý¯ÿßý3ÿ“+ß?;ú+€ÿ„ËÄôJ¼ÿôÏþL£þ/Ñ*ñÿýÿÓ?ù2€;ú+€ÿ„ËÄôJ¼ÿôÏþL£þ/Ñ*ñÿýÿÓ?ù2€;ú+€ÿ„ËÄôJ¼ÿôÏþL£þ/Ñ*ñÿýÿÓ?ù2€;ú+€ÿ„ËÄôJ¼ÿôÏþL£þ/Ñ*ñÿýÿÓ?ù2€?#> ÈýãŸû ßè÷®F¾†ñWÀOúÏŠ|K¬Ùü3ÔÅÞ¡suýON åfhààŠÁÿ†qøñÿDÒûÿºÿ$Wb¨¬~—G5Ã($æ¶<^ŠöøgôM/¿ðk§ÿòEðÎ??èš_à×OÿäŠ~Ñw5þÖÃ:<^ŠöøgôM/¿ðk§ÿòEðÎ??èš_à×OÿäŠ=¢îÚØoçG‹Ñ^Ñÿ ãñãþ‰¥÷þ tÿþH£þÇãÇýKïüéÿü‘G´]Ãû[ üèñz+Ú?áœ~<Ñ4¾ÿÁ®ŸÿÉÃ8üxÿ¢i}ÿƒ]?ÿ’(ö‹¸ka¿/U®ÿÔ7ÔW¸ÿÃ8üxÿ¢i}ÿƒ]?ÿ’*ÿfïRDÈ¿ /sïªéÿü‘MT÷7ÂgUV-Ô[£çÚ+Üÿá™~?Ñ4»ÿÁ®ŸÿÉÃ2ü~ÿ¢iwÿƒ]?ÿ’+omçÚ¬ùüþÞxeîðÌ¿¿èš]ÿà×OÿäŠ?á™~?Ñ4»ÿÁ®ŸÿÉ{h÷õŸ/ÿŸÑûÏ ¢½Ïþ—ã÷ýK¿üéÿü‘Gü3/Çïú&—ø5Óÿù"máþ³åÿóú?yá”W¹ÿÃ2ü~ÿ¢iwÿƒ]?ÿ’(ÿ†eøýÿDÒïÿºÿ$Qí£Ü?Ö|¿þGï9ß‚_òWþØbßÿB¯Úúü±øUû>üjð÷įëºß€.tý"ÓR†{™Î¥dâ(Á嶤ÅÐkõ:¸ñ2Mè~_Ç™… ExJ„”’]=BŠ(®sáŠ( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ÿÙlibsynthesis-3.4.0.47.1/doc/SySync_script_call_flow.numbers/SySync diagram_plugin_small.jpg000066400000000000000000003324571226375725500320240ustar00rootroot00000000000000ÿØÿàJFIF––ÿá6ŠExifMM*bj(1r2‡i¤Ð––Adobe Photoshop CS Macintosh2007:07:13 13:02:02  ' ,&(.5THHÿØÿàJFIFHHÿí Adobe_CMÿîAdobed€ÿÛ„            ÿÀ "ÿÝ ÿÄ?   3!1AQa"q2‘¡±B#$RÁb34r‚ÑC%’Sðáñcs5¢²ƒ&D“TdE£t6ÒUâeò³„ÃÓuãóF'”¤…´•ÄÔäô¥µÅÕåõVfv†–¦¶ÆÖæö7GWgw‡—§·Ç×ç÷5!1AQaq"2‘¡±B#ÁRÑð3$bár‚’CScs4ñ%¢²ƒ&5ÂÒD“T£dEU6teâò³„ÃÓuãóF”¤…´•ÄÔäô¥µÅÕåõVfv†–¦¶ÆÖæö'7GWgw‡—§·ÇÿÚ ?õT’I)$²2qñh~FM¬¢ŠÆë-±Á­hñsÝíjJJ¨õ·Ó:ac2ï ºßæqØ×[}Ÿñ8´6Ì‹vþvʽ‹¨uN¿ÔñmwF¬àÐãSîhnVAiµâÕxôºuy-k««/>«ný'ô ÿMÓOFÅé®ê˜Cn=Õ‹ò]ºÛÞÖ‡XÿµZóv]÷ÓúJý+ÿMÿ¡T¹ˆcÆ*Ý•ðú~XËÆI´þ¯×òÏêxUôúŒEÙîõ-ˆ—“ðŸ·þÞê8öÀ žŸÔ2#íý[.î¿ì}‘ŸnÛý|û;~°ÝxôŒ+2²‹CÝ¿o£^æ—µ—dÓcè{Üæú? ½þŸñOS8?YsNìœÚ°j1ñªõ$n­Ößiß¿nÏæmÿÒk?/7ÍKæÈ0ÝŽ‡þoEÔ» t§‘AÉ’ì»mÈÔ­læ]wÒwµfgô¯«x½oÕÀÀª§âf–UKûüGùÆµŽ±»­Ùÿ]Væíº›ºRÊÈv3ªÈ½ÁµîÅý'«èÙ»Ûþ÷îÿ®Ö£×*¦îµÓ[mlµŸfÍ!¯k^ߥÓáÀ<9ªvBVrO'¦w¬¿súË¡)ínm?-´Vѱ2Ö±÷eôëYF¿¡vE5U‰f5Ž»)”Ûêƒúÿ„°Ì³„ÌwåeõNvKò=WeÔÓk­f>1ýªÌÛ}}•~—Ò¦­}_Ízõ1C'¦}^cE™XxUµÇh±õVÏtǪ;Ö;ó’§Ö¹Ý#7.†ÔvŸFÛ_WýnޤܬK©ÓùÌzý/øDèó¤ $üÑâàÿ ×8ÿãlÇ•–ÀÄ—W§}bê·4œK°úíM–×» & j¿s+¼äce~ƒ&ÏÀ§{Ö¶Ö>›“Ü;‹ðsŸ;pòÛéXèŸèî—cæ}ûE~Jãò:m–rñ1ú‹víõqç( ú@»§äÚßåY‚šœœ›v ëTwIêM5æ5¬aÛk«¹—ý¯ôŸf«íx¾­¡õ™ëåZûUÜ?‘ê3¿èOíÿÕ˜±°O£ó?'Ñ’\gEêùË:]ç6ºœ[‘Ѳì?j¤4þ—ìyy[-µÌõ+kñóm¯êÿ´q½5ÓôΫ‡Õ1ý|WiÙm64²Úž>•9Y¶Êmþ¿üe¢Z8³Ã-ðGÍ i8ýMÄ’IH…$’I)ÿÐõT’CÉȣܜ‡Šè¡Ž²ÛÃZѽïwõZR£Ôqzf+²²œC c ž÷¸íªŠ*o¾Û­²ºØ±N-ýFúsº»@}õ10$:¬w~eÖÇèòºƒÓ1‡üÞø\¼…Šr:•ìêÙÔº‡Á–}*+pÛêÚÏÍê9Lþ{þâQú•ö®Ü‘uLž¡c†Kim·KmΟe¶ö‡5·5™¬­ûê®ö³þÕý*ÈçyÓ’GÃóä¿›¿øô×¾gZ®Œúº~5/ÎË{¿O]%¿¡g´ºÜ‡¼íc¶Ùú*¿ÂÿÁ¨Õ=7«œy?cêu¸ṵ̈ ™T7Ûµ•çTÇgUÿvªÏÿOZ®çáý]Ç«§ã ®£‘±­Ço±öÀw¾çµ¶ý—­eßdgôZš¯ÑÅ®ÛiÒÏÂgQÁ~=…Ô9ᯮÏϦÖݱÛ}\kØË>Ÿ¦ÿæÿ›T=1¡U iÄ~i¬àþªZ™¶u6Y^HÅWYe–Xöµ”œãëU‰uný_·óñlþwÿBfôwc×öϬL\ÏJÚ/õHª‹+ÈÜmmÆÇWSm¯sh§#¬?ÐUüßé=*j[Ö:þc,©¾ŸN·šrHß{ï¬MŒ¥ÙLû6=Îs‹cêͶÜ[©»ô ÆvPxËÄÂý)5šòóÈ·Šl±®¿1ïö{rhýOÒÞÌœKѲ›”‘‰Ž(LJæ®-{$¿{ý_<9yʉÐKXþ‘“¶Ú>£—ŸR×õ]­uqU7d׵쪻ð©u.{>Ïê1Þ§ôŒ¬«ö~“Ø\î«E½Kì|,Ñ‹‘IÆÁ´âz eN v͘¶,v³/öYÕºµ5ŸDÔöYw¸=öï­—ìfí–3ÔÙüÕöÞqÁèÄ®ë5·ôMŠÁ ­­{_nÍï§×Èý/鯲ÛYè'ðÆ{ÊrÂË—¦\<0‹,y~>¡Ð˜CW¨³­t‚Ð2½ZZ×µbÞÆ‡0‹+~û)ôGcw·Þ¡_JèÝ@SnM«»cq2‹ëc_êXÖ¾×b×e¢ÙG¡èÿ‚YßkÌÊ˽Ý/«a–¿cqñ½FØC@«Õ²ëföÞÏÏõoæ~C,d²æÙÕ:[o °œüY®Êý¯·%þ­v}·ÓÅÚÚëþkí_Û®•Ãä'(H‹áâõj?ÍÊ8{÷ÙŒoļ:7w¦áåb²Ó—”ìÛ­x"×H¶´2ºÛ[œö³ÝêÛfÏôŸðh}B¦gåctè‘C›™}­%¶TƸýš¼k™úL|Œëëþr›+·ìxù?é+TpºŽ`vÌ{šÆ‰8™¥µä‚?ž§5’ÛîÆšëÈfUWzV?Ò·¨2ßSÓ?O®ž¡Óò±îµõgd¸YÕceÕXí›+c.õ?V¦Š«ÃÅ»ô¸×U_©ôí±Fa8Hä‘ÔUJ#äâôñðzxx?ô¢Ò4­Òþ¯l¯´cWeٹᔚéë5ÔÛ3±Zï¦üšZÝ™Ô6¿ûWElËǯÕý¾ì´j-Ï¿6›®s1º†;X1úÝD Lšmþ‰sý½A¹v¿ÛEvo®ÏS'ì6ú>½u,ž•“éu7dÞëËÝE£cªö¹ßgeþ†Ö_m[}96~‡gÛ-·ÑûFJ¹™ƒ@Ƕ‡SëôÛK•†Á%…Ó¿¨tÆÃ¶\Ýï~F#éæ3Ô²šýVœÉñæ”%"?Íæ‡ãû¿ú­¯“ ˜tù ö7ª ÃeWölìxûF1; :};¨²ëâݵÞû?à®®œš®¢«Ë€Âêy/{0òri¯«b±×ôž¤H5ߎíîjmO»ÓÁÊǦ½Ì»#Öº¿Ö§âz˱éLu,1sê8Ù5¸Õ—Šâênh¥.s~ŸÒm”ÛþÊrú;Vß-Ì{ ‰PÉëå˜ÿ9êÿÐj‘Mä’IXCÿÑõUÍuÊ:¿\wHmu'ÓÉˤ>fAý&%o«óñ1³.×7f_Øëÿ´ù5­n¹Ôÿet¬ŒàÏVÚÚE_¿u…´âÓÿ]Ȳº÷.tê} ë¼›o¨ºÃ˜Âk»Ö°ú¹YTßQÐü‹œ÷û³üój—Ä3Œxø"YlXÞ0ý"Û˜Ž eÄz~ïï;X/ʲ¯Ù8Øî}ÝF«VKœY@{aî¢Ûª=–¾ŸVÍ–7Ó¿ù¯Ò~—ÓŸgúµ‚+Ãk²³óÑ]n;}{ÚÖVûöËYêú{_c?ŸÊôýïþvä^·Ô°Èfs]Ô1‰´ÒÐ2X ?Ò1+ÛVcßð¸^žGýѱnaæâgc·+ædPÿ£c ‰ZïήÖî÷ÖÿÒ1b’c+‹ܸO¦réÅû¿ÝfÇ–Àßæ<ÑV>/Õìggå»íW$zn{cÔºÇ]ؘM>ïMöï·Ñ¯þ±E¢ÆZ##;+ ¹Y­©§!Þ®3)ÜcÀ×ã2ýßK%¬wé}?Ñ©ät¾Ÿ•Ü›è^ÖŠÃ¥ÂZ×ŒŠ˜ö±Ím¾•íõ¨õ?™·ù¥Ö:ÍùÙ…ƒaªŠœY•–ÃsÆ–bâ=¿ÍúC+-¿Í?õ|oÓú¶ÐGëtý-ç9~ˆýسcÇ,’€²ÕëÙ4·«ïéa¹YNg¡Ôke,5ëvF[Ygë”î}Ä©¶äYgé=³Ò¨;#'ú~M—Í—cÓý]µ?í7èFUŸñi[~MÇe{[]u€*ǯkL5žÆ=ÌkYêYú[¬w§þšÅLÓÖsÚÖÙkq±ÞǶÑ[\Ç8º_mAÇí öúUäSe˜õ>Ñ_øEfÀè+N9|燳¯‹ qDc7šCôB<_ËôÛ$ôΙuôÒÊ٥㶹í¸ú«ßío¹þ¢!êØch~HcœCKLµÄ¹¾›w6·±Ì{,÷~Us:?Meøù9 ¦†ÝE¯îM[½*ÇÚ7¾”Ùgø_OÔþ{Ô±á6ô'ÛëYëÚïU÷˱ïØ^ñ]ræ³{k®ŠÛ^ïúïªõ ‡µ9X ¶^)#íŠÞòê߾Žûr]~=.,±öl±­p!¾›·oý&ç7Ú£Vic_Ó2,ÅiÌkêã}Í?e¼¾½Žÿº¯ÆÿŒUkoAÉÇwNĽ¸â×ïu5ŸNÒïäÕ–Íÿñ{+ýÊýOÓJÿÚ¸ºÁi»<ÛsíF:ÇŸA­už»îÙc›ú¦ÿÙÔWOô¤¸FÈ×äÈ7ÿ ë(‰ Öxõ1—÷¾eò¨ªË½JË:}ž˜ª¬ÜgÆ3}Ú?ÜvEžµõ~±oÙÿYÈô²½k‘l·"œª±º®úî­ÓƒÕhX\6·ßM׾Ͷý¢›*ô.Æý6e?ÎY<¥^Òw8;~+Ü×8´{à?ÃQù›ö~úV´bRêlÜî‘cK-k\Cñštõh{IöôµÿÚ/ç+ýSÕ¡‘NjÛôõT¿õóygŠ<&pïëãÔ±²3±±­ª›œàû, kŸ¥­/°TúëÜÿçvz?ðˆù}««õL½HvOÙë'³1XÜg4'íŸmrÆÞÌŸ¬õš¬¥Ã«7šœÿ\¢ül¦z¬£Ñõ¯³cþÏwýkÕõ–7!—™ÉwÊ&:S§þåsdÏ;ùq‚?ÄÿÐÝkm¦’ÁuŒ¨Øí•‡¸7sÿÑ׸ûßü–¨?·!Ùx¶¿4ˆvM1/±­Ë¡ÿ Í­¿÷až£?ÀÝJÎËõ,úʼn[+õ[C– Ûv‡ŸNËaÿ™Oê϶ªžÿµ3Z׸€9&>õTƒ²Ÿ¯è°\±˜Ê2"D^~©õ«6¬ÙÙ,™92ÔñœEUãÎËrv?~FKœæãQë~«U×zßm³ÑØè†âýŸŒvúE˜ïhÜ6í¦ÆðžŸÓÿ„QÀ´ÝëutËyŸ j‹©Æþmß§ÌwþLzs¨3ÓÜ1œïwÙ\ Æ|έ¥žüG?ý6èÿîµÊÔ`#–òýÞ?ýÜøwÅñá'1›Cš Cþñ©^+1ÇÛú§¥WÙkkXûl`kZúýKw»&û“‘è7Ñõ?Oé~±jÙ™yº’üŽÅ&íßL@Dl:U•Œe¬ÙsE¬<±à8šùJ‹r°¢¸ÙKGôK\Kô÷î~3¿ÿSù8¥& (ïo­èkê–ú›`ýÙ»tlú_šŠ"Çe¹1Â_6‡hËiÿƒ&ÓêÄê5ž£Š,ûKA­y¦ÓcòíìÆ»è1÷íõ>Ïú?ZÌ+I{¹-©È{nȽìnÆ’Iµû¿7رM§ãžÆ¹ÁŒª›Í•7]Û]íûF/ó”#ÕÇÿ®¹™œ§ŠñÞ$bÐùÜ×ûS˜Í®·wú,OJøl…ÝrN\1ùéKôªçå”yy xÎÜ:G ýÿûå¨ê­Á²Î™ŒÓ–OÙ@xmu>¾÷û¿¡ÿ9MT³#'ìÖz›=ñîË{®¾Ö¿1Í ©ûbšÜÏPÐæc;Ôõ=Ýgé²¾Ñw¿ô~ŸÐE̤œ-¸Ì ³.Å­£kCë—úMc6µ­¾¿Wþ¼“]Œmµ®Æ‡Ö|ZὟô\¯`äð⑘C¼ÏýÏî°òæ98¸‡Ê}1ýÆ_»ý×?¦=ùxvâ]cÞø Þâ^Fòæúvk¿Ö¥Íßv-¶½þ¿èÿCTº3î4[U­ƒUŽíA1±Þêͱ»š¡ÿ£ýÏô„˾ÚsðÜûcàêMd˜ÞHÚývïQŒ÷ÿà¤HŒL\ðZâróì“Q°ÄAõ.m-=›>•¿ñU[þ Yd„Ç_æÿW+ý(ËäÿÐ]¿«¹¿`úÃ…q1VQv äÏø_Òâ;OÝË«Ðgþ^”¼ƒ-Ö·Û(%·RßZ’9RFUø-,^­ûCöwí=ߪú?ißÿ·ÖÝþbi Òæ±ðó˜f?ÊJãB\?ôxÿÓ¿€óf#/:œ—[’ëöÛ•ÿ£“Ó‰M9d°¼Ùl—oqxÅ®y¯|º½þMú{=:«gø5G¥egŽ•‚ÓÜöŒjC_ëÒÝÃÓg¿kŽæîV~ÕÔòµßûJæò œ“7T¥~¸u—÷œI‰qÌØõ~¨÷EÓðòqº†u–ÖWÇ¡p°Øís¶Õg¬çä}[ÿÑ9_ó~‚±Ôï~7LÌȬŕÐóYþY_ø+Ø¡ö®¥ÿ•§ÿbiU:­ùÏÁs.Âôj}¸í}ž½v@9ƒ¬nr"2žHñpêcë‰Óåýä€e8“üGÍûäÙ›zN{+®Ë[(c)fÑ·s%—7ØÏÒ{©µR®–ô®~Mf]õ×`¦,yû>.Üf{1½7äúÖÒÏgÚ=e?¬ÖUöQk«!ðc¶‚Öî6Ñ.g»óþƒ=êôuôå¯õ€gå±û™0ã–ÙòÂþ´e8Gþé¥Ul¥¬ª½+¨3àѵ«"ÌL¬lg¼Ã==ÄÆ£Õ½ƒ!Žu¡ìcÛºŠíoè]_ó^ÿê-uKªdߎöZi¤5î¸×é›t۵ͫ'ùÊ›?¤ôýêÔIºîú3{|RÐ=8ý?Ôù¾‰Ì5<¹®¶¡I.tú±÷æ¿Ûíý7¨úØ‚î,ôšÚšÆ}¤°‡>I´²=ÍÛíô6·wþŒV2:Ëiuí4ümîµ»À†7Óô-ÇIõÙµ¿àýêMê66ƒŽ‘êÙSØëšÖHVç¹·þ“w¬ÏѶ´ï^ì$}§§å—ïmò|ÜQÿ˜‹ö^[²Ÿ}—n/­ÌÜZïuBŸEß¡s½&[úMþ§ü'£ê¡·£åú“Ÿ^ÑI¨Vlj77!»Ï¢êŸìk½Gú¤ÿFƒoTêM§"¶¸ˬ·݃ÛMFæÜ×7o§¹®Çc=ÿ÷!jãdï¿&›,i{- ª¹hvßN» ún÷9é!Ûýåc-Ç£ÅûÙ}Uÿ%Åe”ãÓ]›M•±­vÁ ‘û€þj±ÒŒb»ÿÚKC{þŽv7ù¸÷WWýi K¦i™šŽ;¾eoýK€úψGÄ`d~„¸G÷Lô7Ææ8: ƒ"|–~ Et;q‹uÔ7ú¬{OþeJÐ]4†ÍVíuÖ9ÏÖ²§Zr öìØú¶3÷=OOôµúŒÛof^sjÆuíûDïVÁ&œmÍÛsšåh49YÔÁîÓÕÿGû¬zÌ·×-û;ÃÈÜZÒèÎý›,vÝþÆ2ÚPúŤ[†}Jª8–:è U•¾ÂúmýZç³Òý_ô¶³ôžÏÑ— çÜÖŠñ¬¡í$‡‹hx÷5Õ9¯­Ö5¯ö?ÙþŽßÒ$á{«®·`ÚEM k¾Õ[]¾ŸºÊìc½¿MÔÁ—CˆG^þ‰o€=P†—AÂ{®‡í¿úê7~wìÿ±kþLÿª\£.ËnÐÜØzô蜷w?ÿ™ôýßiKpÿË8ôýOæÿ“¿è!-Ç›8AÉËš:d£!¹õªÿÿÔ½ÒÚ[Ó±jüêkçIv3¿éT§‹™‰–\1nmþ™û&íÁ¾è÷{«±¾ÏÜSôÝFoQÄtnÇμéû¹u:¿ègmY”:–}cʯx¹Íc¡°2mfC}v·Ö¶ºîüÏÖkõ=OÑó¹q—½{,põÖjkXÝÆÝ[þvMìý®õúRÏWý*Õö74èæøƒ£›þjdÏ ã04ôÎ?ËûÈ—¦qzdÞµXÈéùm;lh2e»ƒ·Uµ¯ý7¢çú?£±Ÿé?F«ç—ÝÐ}x¥,« µs»ÍvK+ªÀÛ+k[VEm­íV:s^Ì!ˆ÷8[†]†÷ú1·æÞ³ øÙ z¯Ól®œ»ðq°lf5vYëdZýæËãôε¯sÞêï­¿OÕõ?OgÙê¢õ~&†šð1ýÖLr–9 GæÃ1’'§£ÿEj˜5’WØÙXÈËcÊH‡¹ž¡iq nÏkŸî~ß ‹è;]‚é";/ ´»úôÿE¿þ¿øT£Šü¼+q˜Z×?ió·ÚöÙîÙïüÏÍVbA£z¾¢cæ#ÌrÃ6&'8Dëë­!/îäôÉz(¦ã}Ðû½r`Èfßk>…-ªÆWú&ïýßz%´Pks­¥`&×K¥À;·iÝnÑýugH²ú6^)ÜÊîe@\Ö¾Ã[ª·uþ¥¾ÍÜn÷u ZÚϽÙ%ÙV1í YS¨­¦ç;Ò¶–½íôO¿þ)>ý&3–qˆ&F#}å“Õ?OèÊNȪ§Ö©»Ó¡`Û=ö5ÌsÂ;ùÖ~ÿó‰¾Í@»×ôk¥ØÝülþr7ýb ÞŽàÿP=¬¸—{7o v?Ù·èý ¿LÒ°ƒKØòÒç–˜¯è ­î ÙV×Ùùÿú1hYa)Ê@Kˆ³ë»®–UÂÝSé{Cr²ôs¾uãµ´8éÿ VBϰmªˆûMçeðŸs¿à±™úkõ"&p·¸Øxï»”º²öÁsvúa›™-sŸ×[üßé=oæýéËËÇy}Ì*8Ƽ'Ž^£ÿ9B²ëè¶ãxÈ®ë ÿ8,†ïß¶ÌŠvØÃ[¿Ew³ù¯N¯ ‰Šw}¦Ñ¨»*ç4ÿ%„b7ÿm‘LtÌ'دu,iû­££Ôî{ì¹õÔÝï·ÙþG³cÕ;½x¸Ò?ûvoz²¼”'ôc_áKÿEG—•öPÇÝ`~ð'{Fêª c^íÙý_üÝž¡Õ.¾ŒVº‡zw:Æ0‚ÞeÏadÿ'éäÕ\úêÌê¸øÎg©è—ìpÜã¾çYúOж´Ú{=_WùÚ?D‹Ôîê8Xö5Ž©Î7Íq2ÏsÿI·c=¬vÍ–³þô_¢¸–ħ"2yŒpéê>™ÎtšªÛpŠÛû5ŸøÓÌ{½·g×ý¥ÿP¹Ü»·Þ>•u½íópiôÿγjôŸØ£þkþÁݧØ~ÿþ³ömèKpÁÎKõÜ´¯Åÿ:ÿÿÕèþ²ãý—ë n úž7iþ{Û¿7uØ™_æ`¬Lîš/ËÇˤVËXñö—ʆßcö7}ÎkY²–¹ÌÙþ“ô~§Ö¾ŸvoIu˜­/ÌÁ{rñX&^êýLý Å~F'ý}sY]õ²Úú­h²·x±Ã{þaXß„±æc¶A¯÷£é—üÞ7‰†Q~˜üG¥f%™âßUÞ…˜¶ï.Ø\Â6ÙO¸í¯Ôo·Õúh×ßF=.¿"ÆÓK>•0Ñàßå;÷Xßzª3Ý“íénCf–òF3~;ÏÒgXÇæñ?Eþ“.¥WÔ«ª×öÿÒÚ@mY÷¡®{xçgرi{ÛöoÑd~ÐõžõqÿXTÄ$t—èƒè=5„ Ò_¢>_ÓeeöW˜sÝC±ð. ¢ûn"·îkœÜL×ãmõ(Çý'Ùl³!ì»Óº›,Ǫ¼tÝOûëΡûf)^vXÝëÌW}¾Ês~ÏS?Jû}KjÉû=-W5®k™cCÚàZö›½ßàžúè­ÿ®ÿ=K*±›Õ02›v'P¨RÖ Ö7$KÃ}1ê·Ö÷RýÙlªý™5úôÿ…Vá*ù}QýßÒƒ©ðߊæäcî )à'ÕûЗèµRW,èmv.EÔ7³E`'ÖÛ‘ÿ³jø}B¬šqÆF;½jí³y¦Á‘¥»v} ý?´~ÿæ)a(̈ÄúBôœ¿üaäsÇ ’ý Cü/šPR–íx¥7d¸K1ÙÈã{÷{i§÷¯»ôh®ÀsXëró^*`.¢ÁCCZ78ºÏÖrí»+Qûn¬ ¶ç–׎Cêu–ŽÙ‘nC}oYõÚßA÷úž«ì§ý*±ôxL߈c‰¿ÞŸýÌ#ó'ª†aUffQÜý¿¦¶¶¹Á•ƒüÆ;c{™¿é»éä[úK6~ÓN997¿©X÷WMŒÓC]¾§7é šÝìs?–ÇUêúþ·é?í; ΟfNc³2Àkæ¦í6×YöºŸ»Òýèmÿ‘êâe~‡ÒV2òŸ[¾Ç†Z2Ã[.‰f;ö[c>«·ú'øOç,ý[ùË1Ôb<ƒ™)JDÎdï~2(srü¦WUFú°žÖnÛúê~Žçâ1þ½µzµ~šÊ?ÂÕé£S}9 /¥ûÃ׈-sOî[SöÙSÿã­âtì|.’쌬{×µŸdÞømŒ±Íu·3.¿Sü¥üí먒ٿ["Ÿ[Ñ¥‰Ó,êOÞ–mΆå ]5–Ù”÷mþy¯ôuã[ú/º¯ð~¢±,1'‹åùèÈÿU~lâ» ³ßü¾ÍEw?,ÂÙ.k\æ^Ú©w­s+ÛÿžÿœU:c™•—“ÔY¯ ¬0ⱎ÷YKM®ô][ÓSg«O³ü/AÕúVèÅÖd³í8M×íøí'k@Ü]›ˆÝöãíçèõñ¿Ò}‘Pì!í³Ü×´‚?œ×7Úÿë(4-ÜsÇ—†Xä bxŒkÕÆzɱÓ0ÎWéø Kl½·]¤GŒ»7ÿ&ËÙ‹ÿ¡ Ô—õ§‡¿+­³=WÓÉôÔ1lÏŶæf²:uM}£,Ù¸ÔÆ Í£ßúÆc[H÷dXÏSÖõ)ý/¥½ DHôÌ|Ð:z¿©ÿz¢,’=2ÇúßÕb󕇒Ìj[gQ©í}¢ Aɦ¦mgÓµÌnu£ýYsÙÿ —é§#¦õf?Á™[õip-¹› sE´»Ò˧k÷}&ìRÈ¡´Ùx¶Œ®­ÆXÚØ-ºªÅvÙ…Ó±ë¿õve9Úûr¿U£#';"ïæëS¾Š²2êÂêXÖäo­ïƳ2ºEí5ú_¢£;¥Yèdzž¥c1þË—G¡újí®ÏQhÃý¯pþÍ!½ÿ/ë6H—«ûÜ-VtlZ²Ù•SœÇ6ï]ì1µÎÛ{?3ÒÛý+þôuUüÒ|ÏùKÿ åÕa-7ý[Í­Ö6ŒŒÊ½"ö+ÉkKƒ^ g×}ßFÆÿ†X]RŒús°¶gz޲œ×;¡;pÚÇ1Žßì÷)¹hN\Æ0M@CòÉ›”„Ç3ŽR7\_ÞùdÛpkšZà××4ðC†×4ÿYª¿§ƒÓikîx©£‹òºÂv¶¯m¶îµîôke^àÙ³ÓUÆ?V·Ù®~{ð7?2šk¢íõk¬e?¿“Fúv~“ÕôÕÜ^ˆÊkÍûE4ääµÏ¬Ú\ë6×gÙï6åÞç=›]û®ôÿë~§§­7©”jëO^¿à»>à;/ñZ–fä]íÆ­'&Öiÿi±¬þkwýÈËÿ­ã-«ßSîê½.ÌÜl‘‡SŸhÆa`´Ûki»'>ÛfݶÛUµþ‹ÓÉÙú__þÓÖÆî™Ó¨k°œÌì²÷°ºÀ@ôþÐÚËú ~u9ߤÿØ•›‡Õ:§KvCú5卑õ».üF:×¶ªßž.mŸcõ^vÛö{jͶ¿Òþ“ùõ$áÁŒœgƒ]e/L¥àædF†˜Vì¬èØìçÑFP[½Ç+Ž;šÈe¾µÖ~ŠšÿX³eJÿ^ú­“Ññp¯Ïµ¹mÉqnIh ¯'éâý’ÏfCi{=\_Z×úÏÈô?šûO¢µ0.=#®þÖÊuv»¨ZÜ~£w£]^Ÿªí”[C™ÕCr¾ÏÌ‹r_e~ŽE×z˜ËSë7U¢Þ‰‚湤ìêYZöÖߤì*›kl©ù··÷™gØéý=¿¥û5vG.fdÇACæïþõªPÊ2G¨ë_½o5õ{¨uâü°õK>-‚¶c\FX6´7í·¬~Ý^#YéÕUUæWú^êÿÑÙnìNÔ®Ùi?Vz¶S¶úµE˜Y6<Æê\öÕOÛœÖþ{0z‡¬ÿûWS¾šÏªŽé·`ýa§«ºH,fE¬®›+©‰•mL¡õ»ôž…¿dÿµõ]þ‘SÂÌO³äî·©¶œ®¹øÆÇ· æRï§k±½_ÔgóßÎþŸÔP“r$G£. ÈÆ áËŽýq:oò—¾ÃÃÇÁħ žž>3UL’a¬7;ÜïhF\·Ô¶æN[ª½î赇M„ÙÔK2Ý‹uŸ¥û nÛ‹]O¶ÿÓÓ‘èz4z~§R›M_o×íØß‚ÿEÿ×õT’I8ßXºíJÙ‘‹`ÇêxÀýš÷ cšu³-÷Y‰vßøÊlýbŸÒV¹zì³{ê¾§ceÑ#æ\Â~‹Úñí»ÈýM£·þïR¦z Íë] «ÔÁkFM».¨ÖOÓhÜË)·ü>=Ͳ‹¿sÙZ«Íò‘Î,zr ¥ÿs6c—ŽaÚciÜÉâk鸵æ;2°[kÉu‚IyklvâïæÙcÙ]LÙWý·O¦<ÐrïfÛsCšñ¹Ž´Z–Úߣm85Ý_7ÿÏú]; þôUìÜn­Ó­ô2°Ý‘mŽ-ij®4ÞïðU¼þ‘Ý6Û7~“í«UúK+Ì»ÒzCn8{Üne_I¶²ÝÌ{ñì麛tö~Ð˯ô;?˜éؽŸð*·!Éd—1ŘÅUÅúGôxOõZPÅ8HÏ 7 !zÜ¿Gü!³¥u,kñU¼¶Œªnci{>Êöä:ÌL×;7¥ìöÖ2žŸ•ƒ¿ùºqÿšE»'&þ­cÙ‘n7Iqª«1›ê¼dZßÓdßCÎulm Â{1_]›ò2}_})ëÁêý.G¥œlœv3ÛE¬ôž^ÚÜßUÏ©í­ößs(õþ}öÿ8™ù=?;*Œ~§Òî«-î5cÝe\Hg¥ŸI¯&ÿI›?Gÿ þlÏ L%pã:ÿè̼`›EÃÑ/ïp§¯©µÍq£}VÜQ¨ì›êÌm6TßI¿£²æÅ.­çôË2ðvåãÙX§)¯-º²!ÇmsÚÿnöµûU¾£SGTêVÜêqë¯Ò¶ë’_oO¹ù—]KóÝêØÏõqª©Îû>NG¯fÏô¸uì ­Ë=C8_½¹bê[/¢ÖY‹‹gçþr©Ëâöó‚\~Ī¿½™— ŒrÆVw<1?Ýý' §õvu\L.›–Y‘ÒØ1nuNÝc¬ôëè÷g6·º¿ÒW—ˆú2?Wû¥ÿr±6BY¿¢`RÚ±ßkæSEV¼Ü×½ÛÏèeÑê7ß¡ê=Šå9™™½O«e:¾¥Š ØÌ¯µšß[Nfï³àú¸ø•²ßÒä>ÚýSùõ üï«6ZN[Û{šÐËMa ,ÛVK+w¥‘éý«}mÈõ¿ÃÂ(þõÁÌ ¸Äö”x?Dy:ðÄF2 ‰zÔœrqqzÏìî²íõbÞ*ϯö;sl­¯«ÓÈ®ºnnÛ-ôïÇýNG§mXÞ«ÿV»¥¯«Y“ÓË~¯ãá×Ñh{ØÎ[aËc\ædQçщöìgz´Uèßu·ìŒFëiY}C!÷ôK*ÂÁ~>6F3Ãn`¦£[.m·]éb‹_UT:¿W#ô>«)ý*»‰GIÆwN£¤f¡“SloUÊǃŽjp¿"†¾Æï§ÖÇͲªz}LµùaúÿàT¹y©æÄrX„ñšáù¸£%þ ¦°ãä#+Ÿ­=;þ’6·ü€þ‘ë~À};6f9Ö2íãec£7v]íúûE¾–GóTaú¬ª¯µ÷—tŽŒÖcãS ¿&¿cjk‹ýjñšÀÝ·þuW·ÔeÖzÿÍ[W¨•‚Æç7Ï}4ßcó0l¯oèò6¼u _Ó¶ê¿M]ögc~‹ô®z?ÑÔ®¾¬ o²tÚ[¾§²¦ÒÑìc­»óSn½Õ1öýŸí­»èõ,«×õ˜æ'ÈlGò Ìqá…j:JDñN_Ôƒ+kÂé˜t ñ…Å$b´€\׺ë=^×ú7Ù]vú;6z·~¯ú4>‘Òòú¯PuV<³¨ÚÉËɨAÂijùº1ÜẬÜêØßF«}Kq?O—ÿ‘,LÞ¡ÔK1Yêu;¯½ƒÓéøïs/®œ–T÷Q•œÇ±·cQ»íÿ¤[F/ó½çIé8}# bbAq²ëžw[m®þw'"Ïð—[ÿ¨ëôꮺӉ`æy€=0Ó¥ÐÿÐÛØôbãÕ‹ŽÁ]1µÕXá¬hØÆê´"¤’kAÿÐõT’I)$’IM^©Ó©ê;'§^÷×N]nªÇTí¯ pÚ펇Ô®;ªý^ê¸äÝk憆uNš6ä±­ géú[±ÿ£«Õé–zÞ—«]tz÷zÚH‰²ÙÀK~œbuN¨l}u6¾µUaζÌx§&¶·vöe`¼Têò}Íe8ÿffÿFÏÏV›õ‹ší¶ú²q~ÍWÚ,mµ ±¸Þ›¿u–}¤ú5îe^¦Å×õ‰Òz oÄ®÷°Ev¹±k5Ýú†m¾ŸúÕŒY¶ýT{dàõLª@!Ì«#fem îæ²ÌߤÝßÓT£1þZµåÊö£ÿ7þùä*éÝ6ÊK°‚Ú sì¦Û]Õ½®s÷äôÿQ¸_"‰ý[íøÔ_ú:}{2VçOe5õ®ƒV;·SK2k¬îÜv²Š*f÷~þÁïPÎú‹Ÿ}‚ç“föØ÷ nÄuŽnã¶û*¿7Ô­Î~뱞¯ç«]êÇQÁêx¹ÆÂÃÅÆ7½íźÛ\û.eTnÙ~=;=´{ßê¦ÜjT¿5цN8Y¿Ýìãô|\lž…Ò}z›i«‡W¼NÓé´iýoÎJ®«Ðñr¨Á  ,ºß³VI­¡Ísñ›ïsjý¬Ûq«¶¿Qž§«ZÒÁú¯õ›]€S)m…·¼Á±¯s”{·÷Ѫú—š-6?;özÖ;Œ°Ød:ï[6î¡ú_s¿Ié,ÁÊä$ñ /OS®y¬`úú\JzænCwQÒ²‹Ý>Žâ í6V÷^önô×Òïëÿì?®Ý7ªgåZ}w«žÀYÒñk6äR\gõÛ[¶Œ7û½'³2Úü×óvúÞ¯U_ÔÞ”ísìÈêfwmË´šôìì,³à¿ûx«g–ãâÔÊ(fŒª¦†1£ù,`kZ¥'Ò¡ýÝçOþõŠ\Ü¿Fôýïûؼ_PèXrp>ÛeuÑöK+ʯ§Uúl‹=' ÇfG¥FCªõk®Œ:Ÿê?ô/Î}XŸ êî_WÉûa¤ôÜrÃ_Û^ÀÌë?G·‚ì ]îýc'õÏôXØÿÏ®á%fŒ#ÃAïjC‹æ6Oé}ø8?˜˜U h¬CXßôž÷:_ew¾Ëlý%¯÷ج$’,*I$’SÿÙÿí^¸Photoshop 3.08BIM8BIM%F ò‰&¸VÚ°œ¡°§w8BIMê"× com.apple.print.PageFormat.FormattingPrinter com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.FormattingPrinter i865 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2005-10-11T08:11:41Z com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMHorizontalRes com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMHorizontalRes 72 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2005-10-11T08:11:41Z com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMOrientation com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMOrientation 1 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2005-10-11T08:11:41Z com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMScaling com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMScaling 1 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2005-10-11T08:11:41Z com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMVerticalRes com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMVerticalRes 72 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2005-10-11T08:11:41Z com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMVerticalScaling com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMVerticalScaling 1 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2005-10-11T08:11:41Z com.apple.print.ticket.stateFlag 0 com.apple.print.subTicket.paper_info_ticket com.apple.print.PageFormat.PMAdjustedPageRect com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMAdjustedPageRect 0.0 0.0 819.21260515348172 575.9999831792876 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2007-07-13T10:56:58Z com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMAdjustedPaperRect com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMAdjustedPaperRect -8.5039370078740166 -9.6377952755905518 833.38583349993849 585.63777845487823 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2007-07-13T10:56:58Z com.apple.print.ticket.stateFlag 0 com.apple.print.PaperInfo.PMCustomPaper com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PaperInfo.PMCustomPaper com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2005-10-11T08:11:41Z com.apple.print.ticket.stateFlag 1 com.apple.print.PaperInfo.PMPaperName com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PaperInfo.PMPaperName iso-a4 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2005-10-11T08:11:41Z com.apple.print.ticket.stateFlag 1 com.apple.print.PaperInfo.PMUnadjustedPageRect com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PaperInfo.PMUnadjustedPageRect 0.0 0.0 819.21260515348172 575.9999831792876 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2005-10-11T08:11:41Z com.apple.print.ticket.stateFlag 1 com.apple.print.PaperInfo.PMUnadjustedPaperRect com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PaperInfo.PMUnadjustedPaperRect -8.5039370078740166 -9.6377952755905518 833.38583349993849 585.63777845487823 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2005-10-11T08:11:41Z com.apple.print.ticket.stateFlag 1 com.apple.print.PaperInfo.ppd.PMPaperName com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PaperInfo.ppd.PMPaperName iso-a4 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2005-10-11T08:11:41Z com.apple.print.ticket.stateFlag 1 com.apple.print.ticket.APIVersion 00.20 com.apple.print.ticket.privateLock com.apple.print.ticket.type com.apple.print.PaperInfoTicket com.apple.print.ticket.APIVersion 00.20 com.apple.print.ticket.privateLock com.apple.print.ticket.type com.apple.print.PageFormatTicket 8BIMéxHH4@ÿøÿ÷BJg{àHHØ(dÿh 8BIMí––8BIM&?€8BIM 8BIM8BIMó 8BIM 8BIM' 8BIMõH/fflff/ff¡™š2Z5-8BIMøpÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿèÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿèÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿèÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿè8BIM@@8BIM8BIM_,'SySync diagram_plugin',nullboundsObjcRct1Top longLeftlongBtomlong,Rghtlong'slicesVlLsObjcslicesliceIDlonggroupIDlongoriginenum ESliceOrigin autoGeneratedTypeenum ESliceTypeImg boundsObjcRct1Top longLeftlongBtomlong,Rghtlong'urlTEXTnullTEXTMsgeTEXTaltTagTEXTcellTextIsHTMLboolcellTextTEXT horzAlignenumESliceHorzAligndefault vertAlignenumESliceVertAligndefault bgColorTypeenumESliceBGColorTypeNone topOutsetlong leftOutsetlong bottomOutsetlong rightOutsetlong8BIM( ?ð8BIM8BIM 5p Ø'5TÿØÿàJFIFHHÿí Adobe_CMÿîAdobed€ÿÛ„            ÿÀ "ÿÝ ÿÄ?   3!1AQa"q2‘¡±B#$RÁb34r‚ÑC%’Sðáñcs5¢²ƒ&D“TdE£t6ÒUâeò³„ÃÓuãóF'”¤…´•ÄÔäô¥µÅÕåõVfv†–¦¶ÆÖæö7GWgw‡—§·Ç×ç÷5!1AQaq"2‘¡±B#ÁRÑð3$bár‚’CScs4ñ%¢²ƒ&5ÂÒD“T£dEU6teâò³„ÃÓuãóF”¤…´•ÄÔäô¥µÅÕåõVfv†–¦¶ÆÖæö'7GWgw‡—§·ÇÿÚ ?õT’I)$²2qñh~FM¬¢ŠÆë-±Á­hñsÝíjJJ¨õ·Ó:ac2ï ºßæqØ×[}Ÿñ8´6Ì‹vþvʽ‹¨uN¿ÔñmwF¬àÐãSîhnVAiµâÕxôºuy-k««/>«ný'ô ÿMÓOFÅé®ê˜Cn=Õ‹ò]ºÛÞÖ‡XÿµZóv]÷ÓúJý+ÿMÿ¡T¹ˆcÆ*Ý•ðú~XËÆI´þ¯×òÏêxUôúŒEÙîõ-ˆ—“ðŸ·þÞê8öÀ žŸÔ2#íý[.î¿ì}‘ŸnÛý|û;~°ÝxôŒ+2²‹CÝ¿o£^æ—µ—dÓcè{Üæú? ½þŸñOS8?YsNìœÚ°j1ñªõ$n­Ößiß¿nÏæmÿÒk?/7ÍKæÈ0ÝŽ‡þoEÔ» t§‘AÉ’ì»mÈÔ­læ]wÒwµfgô¯«x½oÕÀÀª§âf–UKûüGùÆµŽ±»­Ùÿ]Væíº›ºRÊÈv3ªÈ½ÁµîÅý'«èÙ»Ûþ÷îÿ®Ö£×*¦îµÓ[mlµŸfÍ!¯k^ߥÓáÀ<9ªvBVrO'¦w¬¿súË¡)ínm?-´Vѱ2Ö±÷eôëYF¿¡vE5U‰f5Ž»)”Ûêƒúÿ„°Ì³„ÌwåeõNvKò=WeÔÓk­f>1ýªÌÛ}}•~—Ò¦­}_Ízõ1C'¦}^cE™XxUµÇh±õVÏtǪ;Ö;ó’§Ö¹Ý#7.†ÔvŸFÛ_WýnޤܬK©ÓùÌzý/øDèó¤ $üÑâàÿ ×8ÿãlÇ•–ÀÄ—W§}bê·4œK°úíM–×» & j¿s+¼äce~ƒ&ÏÀ§{Ö¶Ö>›“Ü;‹ðsŸ;pòÛéXèŸèî—cæ}ûE~Jãò:m–rñ1ú‹víõqç( ú@»§äÚßåY‚šœœ›v ëTwIêM5æ5¬aÛk«¹—ý¯ôŸf«íx¾­¡õ™ëåZûUÜ?‘ê3¿èOíÿÕ˜±°O£ó?'Ñ’\gEêùË:]ç6ºœ[‘Ѳì?j¤4þ—ìyy[-µÌõ+kñóm¯êÿ´q½5ÓôΫ‡Õ1ý|WiÙm64²Úž>•9Y¶Êmþ¿üe¢Z8³Ã-ðGÍ i8ýMÄ’IH…$’I)ÿÐõT’CÉȣܜ‡Šè¡Ž²ÛÃZѽïwõZR£Ôqzf+²²œC c ž÷¸íªŠ*o¾Û­²ºØ±N-ýFúsº»@}õ10$:¬w~eÖÇèòºƒÓ1‡üÞø\¼…Šr:•ìêÙÔº‡Á–}*+pÛêÚÏÍê9Lþ{þâQú•ö®Ü‘uLž¡c†Kim·KmΟe¶ö‡5·5™¬­ûê®ö³þÕý*ÈçyÓ’GÃóä¿›¿øô×¾gZ®Œúº~5/ÎË{¿O]%¿¡g´ºÜ‡¼íc¶Ùú*¿ÂÿÁ¨Õ=7«œy?cêu¸ṵ̈ ™T7Ûµ•çTÇgUÿvªÏÿOZ®çáý]Ç«§ã ®£‘±­Ço±öÀw¾çµ¶ý—­eßdgôZš¯ÑÅ®ÛiÒÏÂgQÁ~=…Ô9ᯮÏϦÖݱÛ}\kØË>Ÿ¦ÿæÿ›T=1¡U iÄ~i¬àþªZ™¶u6Y^HÅWYe–Xöµ”œãëU‰uný_·óñlþwÿBfôwc×öϬL\ÏJÚ/õHª‹+ÈÜmmÆÇWSm¯sh§#¬?ÐUüßé=*j[Ö:þc,©¾ŸN·šrHß{ï¬MŒ¥ÙLû6=Îs‹cêͶÜ[©»ô ÆvPxËÄÂý)5šòóÈ·Šl±®¿1ïö{rhýOÒÞÌœKѲ›”‘‰Ž(LJæ®-{$¿{ý_<9yʉÐKXþ‘“¶Ú>£—ŸR×õ]­uqU7d׵쪻ð©u.{>Ïê1Þ§ôŒ¬«ö~“Ø\î«E½Kì|,Ñ‹‘IÆÁ´âz eN v͘¶,v³/öYÕºµ5ŸDÔöYw¸=öï­—ìfí–3ÔÙüÕöÞqÁèÄ®ë5·ôMŠÁ ­­{_nÍï§×Èý/鯲ÛYè'ðÆ{ÊrÂË—¦\<0‹,y~>¡Ð˜CW¨³­t‚Ð2½ZZ×µbÞÆ‡0‹+~û)ôGcw·Þ¡_JèÝ@SnM«»cq2‹ëc_êXÖ¾×b×e¢ÙG¡èÿ‚YßkÌÊ˽Ý/«a–¿cqñ½FØC@«Õ²ëföÞÏÏõoæ~C,d²æÙÕ:[o °œüY®Êý¯·%þ­v}·ÓÅÚÚëþkí_Û®•Ãä'(H‹áâõj?ÍÊ8{÷ÙŒoļ:7w¦áåb²Ó—”ìÛ­x"×H¶´2ºÛ[œö³ÝêÛfÏôŸðh}B¦gåctè‘C›™}­%¶TƸýš¼k™úL|Œëëþr›+·ìxù?é+TpºŽ`vÌ{šÆ‰8™¥µä‚?ž§5’ÛîÆšëÈfUWzV?Ò·¨2ßSÓ?O®ž¡Óò±îµõgd¸YÕceÕXí›+c.õ?V¦Š«ÃÅ»ô¸×U_©ôí±Fa8Hä‘ÔUJ#äâôñðzxx?ô¢Ò4­Òþ¯l¯´cWeٹᔚéë5ÔÛ3±Zï¦üšZÝ™Ô6¿ûWElËǯÕý¾ì´j-Ï¿6›®s1º†;X1úÝD Lšmþ‰sý½A¹v¿ÛEvo®ÏS'ì6ú>½u,ž•“éu7dÞëËÝE£cªö¹ßgeþ†Ö_m[}96~‡gÛ-·ÑûFJ¹™ƒ@Ƕ‡SëôÛK•†Á%…Ó¿¨tÆÃ¶\Ýï~F#éæ3Ô²šýVœÉñæ”%"?Íæ‡ãû¿ú­¯“ ˜tù ö7ª ÃeWölìxûF1; :};¨²ëâݵÞû?à®®œš®¢«Ë€Âêy/{0òri¯«b±×ôž¤H5ߎíîjmO»ÓÁÊǦ½Ì»#Öº¿Ö§âz˱éLu,1sê8Ù5¸Õ—Šâênh¥.s~ŸÒm”ÛþÊrú;Vß-Ì{ ‰PÉëå˜ÿ9êÿÐj‘Mä’IXCÿÑõUÍuÊ:¿\wHmu'ÓÉˤ>fAý&%o«óñ1³.×7f_Øëÿ´ù5­n¹Ôÿet¬ŒàÏVÚÚE_¿u…´âÓÿ]Ȳº÷.tê} ë¼›o¨ºÃ˜Âk»Ö°ú¹YTßQÐü‹œ÷û³üój—Ä3Œxø"YlXÞ0ý"Û˜Ž eÄz~ïï;X/ʲ¯Ù8Øî}ÝF«VKœY@{aî¢Ûª=–¾ŸVÍ–7Ó¿ù¯Ò~—ÓŸgúµ‚+Ãk²³óÑ]n;}{ÚÖVûöËYêú{_c?ŸÊôýïþvä^·Ô°Èfs]Ô1‰´ÒÐ2X ?Ò1+ÛVcßð¸^žGýѱnaæâgc·+ædPÿ£c ‰ZïήÖî÷ÖÿÒ1b’c+‹ܸO¦réÅû¿ÝfÇ–Àßæ<ÑV>/Õìggå»íW$zn{cÔºÇ]ؘM>ïMöï·Ñ¯þ±E¢ÆZ##;+ ¹Y­©§!Þ®3)ÜcÀ×ã2ýßK%¬wé}?Ñ©ät¾Ÿ•Ü›è^ÖŠÃ¥ÂZ×ŒŠ˜ö±Ím¾•íõ¨õ?™·ù¥Ö:ÍùÙ…ƒaªŠœY•–ÃsÆ–bâ=¿ÍúC+-¿Í?õ|oÓú¶ÐGëtý-ç9~ˆýسcÇ,’€²ÕëÙ4·«ïéa¹YNg¡Ôke,5ëvF[Ygë”î}Ä©¶äYgé=³Ò¨;#'ú~M—Í—cÓý]µ?í7èFUŸñi[~MÇe{[]u€*ǯkL5žÆ=ÌkYêYú[¬w§þšÅLÓÖsÚÖÙkq±ÞǶÑ[\Ç8º_mAÇí öúUäSe˜õ>Ñ_øEfÀè+N9|燳¯‹ qDc7šCôB<_ËôÛ$ôΙuôÒÊ٥㶹í¸ú«ßío¹þ¢!êØch~HcœCKLµÄ¹¾›w6·±Ì{,÷~Us:?Meøù9 ¦†ÝE¯îM[½*ÇÚ7¾”Ùgø_OÔþ{Ô±á6ô'ÛëYëÚïU÷˱ïØ^ñ]ræ³{k®ŠÛ^ïúïªõ ‡µ9X ¶^)#íŠÞòê߾Žûr]~=.,±öl±­p!¾›·oý&ç7Ú£Vic_Ó2,ÅiÌkêã}Í?e¼¾½Žÿº¯ÆÿŒUkoAÉÇwNĽ¸â×ïu5ŸNÒïäÕ–Íÿñ{+ýÊýOÓJÿÚ¸ºÁi»<ÛsíF:ÇŸA­už»îÙc›ú¦ÿÙÔWOô¤¸FÈ×äÈ7ÿ ë(‰ Öxõ1—÷¾eò¨ªË½JË:}ž˜ª¬ÜgÆ3}Ú?ÜvEžµõ~±oÙÿYÈô²½k‘l·"œª±º®úî­ÓƒÕhX\6·ßM׾Ͷý¢›*ô.Æý6e?ÎY<¥^Òw8;~+Ü×8´{à?ÃQù›ö~úV´bRêlÜî‘cK-k\Cñštõh{IöôµÿÚ/ç+ýSÕ¡‘NjÛôõT¿õóygŠ<&pïëãÔ±²3±±­ª›œàû, kŸ¥­/°TúëÜÿçvz?ðˆù}««õL½HvOÙë'³1XÜg4'íŸmrÆÞÌŸ¬õš¬¥Ã«7šœÿ\¢ül¦z¬£Ñõ¯³cþÏwýkÕõ–7!—™ÉwÊ&:S§þåsdÏ;ùq‚?ÄÿÐÝkm¦’ÁuŒ¨Øí•‡¸7sÿÑ׸ûßü–¨?·!Ùx¶¿4ˆvM1/±­Ë¡ÿ Í­¿÷až£?ÀÝJÎËõ,úʼn[+õ[C– Ûv‡ŸNËaÿ™Oê϶ªžÿµ3Z׸€9&>õTƒ²Ÿ¯è°\±˜Ê2"D^~©õ«6¬ÙÙ,™92ÔñœEUãÎËrv?~FKœæãQë~«U×zßm³ÑØè†âýŸŒvúE˜ïhÜ6í¦ÆðžŸÓÿ„QÀ´ÝëutËyŸ j‹©Æþmß§ÌwþLzs¨3ÓÜ1œïwÙ\ Æ|έ¥žüG?ý6èÿîµÊÔ`#–òýÞ?ýÜøwÅñá'1›Cš Cþñ©^+1ÇÛú§¥WÙkkXûl`kZúýKw»&û“‘è7Ñõ?Oé~±jÙ™yº’üŽÅ&íßL@Dl:U•Œe¬ÙsE¬<±à8šùJ‹r°¢¸ÙKGôK\Kô÷î~3¿ÿSù8¥& (ïo­èkê–ú›`ýÙ»tlú_šŠ"Çe¹1Â_6‡hËiÿƒ&ÓêÄê5ž£Š,ûKA­y¦ÓcòíìÆ»è1÷íõ>Ïú?ZÌ+I{¹-©È{nȽìnÆ’Iµû¿7رM§ãžÆ¹ÁŒª›Í•7]Û]íûF/ó”#ÕÇÿ®¹™œ§ŠñÞ$bÐùÜ×ûS˜Í®·wú,OJøl…ÝrN\1ùéKôªçå”yy xÎÜ:G ýÿûå¨ê­Á²Î™ŒÓ–OÙ@xmu>¾÷û¿¡ÿ9MT³#'ìÖz›=ñîË{®¾Ö¿1Í ©ûbšÜÏPÐæc;Ôõ=Ýgé²¾Ñw¿ô~ŸÐE̤œ-¸Ì ³.Å­£kCë—úMc6µ­¾¿Wþ¼“]Œmµ®Æ‡Ö|ZὟô\¯`äð⑘C¼ÏýÏî°òæ98¸‡Ê}1ýÆ_»ý×?¦=ùxvâ]cÞø Þâ^Fòæúvk¿Ö¥Íßv-¶½þ¿èÿCTº3î4[U­ƒUŽíA1±Þêͱ»š¡ÿ£ýÏô„˾ÚsðÜûcàêMd˜ÞHÚývïQŒ÷ÿà¤HŒL\ðZâróì“Q°ÄAõ.m-=›>•¿ñU[þ Yd„Ç_æÿW+ý(ËäÿÐ]¿«¹¿`úÃ…q1VQv äÏø_Òâ;OÝË«Ðgþ^”¼ƒ-Ö·Û(%·RßZ’9RFUø-,^­ûCöwí=ߪú?ißÿ·ÖÝþbi Òæ±ðó˜f?ÊJãB\?ôxÿÓ¿€óf#/:œ—[’ëöÛ•ÿ£“Ó‰M9d°¼Ùl—oqxÅ®y¯|º½þMú{=:«gø5G¥egŽ•‚ÓÜöŒjC_ëÒÝÃÓg¿kŽæîV~ÕÔòµßûJæò œ“7T¥~¸u—÷œI‰qÌØõ~¨÷EÓðòqº†u–ÖWÇ¡p°Øís¶Õg¬çä}[ÿÑ9_ó~‚±Ôï~7LÌȬŕÐóYþY_ø+Ø¡ö®¥ÿ•§ÿbiU:­ùÏÁs.Âôj}¸í}ž½v@9ƒ¬nr"2žHñpêcë‰Óåýä€e8“üGÍûäÙ›zN{+®Ë[(c)fÑ·s%—7ØÏÒ{©µR®–ô®~Mf]õ×`¦,yû>.Üf{1½7äúÖÒÏgÚ=e?¬ÖUöQk«!ðc¶‚Öî6Ñ.g»óþƒ=êôuôå¯õ€gå±û™0ã–ÙòÂþ´e8Gþé¥Ul¥¬ª½+¨3àѵ«"ÌL¬lg¼Ã==ÄÆ£Õ½ƒ!Žu¡ìcÛºŠíoè]_ó^ÿê-uKªdߎöZi¤5î¸×é›t۵ͫ'ùÊ›?¤ôýêÔIºîú3{|RÐ=8ý?Ôù¾‰Ì5<¹®¶¡I.tú±÷æ¿Ûíý7¨úØ‚î,ôšÚšÆ}¤°‡>I´²=ÍÛíô6·wþŒV2:Ëiuí4ümîµ»À†7Óô-ÇIõÙµ¿àýêMê66ƒŽ‘êÙSØëšÖHVç¹·þ“w¬ÏѶ´ï^ì$}§§å—ïmò|ÜQÿ˜‹ö^[²Ÿ}—n/­ÌÜZïuBŸEß¡s½&[úMþ§ü'£ê¡·£åú“Ÿ^ÑI¨Vlj77!»Ï¢êŸìk½Gú¤ÿFƒoTêM§"¶¸ˬ·݃ÛMFæÜ×7o§¹®Çc=ÿ÷!jãdï¿&›,i{- ª¹hvßN» ún÷9é!Ûýåc-Ç£ÅûÙ}Uÿ%Åe”ãÓ]›M•±­vÁ ‘û€þj±ÒŒb»ÿÚKC{þŽv7ù¸÷WWýi K¦i™šŽ;¾eoýK€úψGÄ`d~„¸G÷Lô7Ææ8: ƒ"|–~ Et;q‹uÔ7ú¬{OþeJÐ]4†ÍVíuÖ9ÏÖ²§Zr öìØú¶3÷=OOôµúŒÛof^sjÆuíûDïVÁ&œmÍÛsšåh49YÔÁîÓÕÿGû¬zÌ·×-û;ÃÈÜZÒèÎý›,vÝþÆ2ÚPúŤ[†}Jª8–:è U•¾ÂúmýZç³Òý_ô¶³ôžÏÑ— çÜÖŠñ¬¡í$‡‹hx÷5Õ9¯­Ö5¯ö?ÙþŽßÒ$á{«®·`ÚEM k¾Õ[]¾ŸºÊìc½¿MÔÁ—CˆG^þ‰o€=P†—AÂ{®‡í¿úê7~wìÿ±kþLÿª\£.ËnÐÜØzô蜷w?ÿ™ôýßiKpÿË8ôýOæÿ“¿è!-Ç›8AÉËš:d£!¹õªÿÿÔ½ÒÚ[Ó±jüêkçIv3¿éT§‹™‰–\1nmþ™û&íÁ¾è÷{«±¾ÏÜSôÝFoQÄtnÇμéû¹u:¿ègmY”:–}cʯx¹Íc¡°2mfC}v·Ö¶ºîüÏÖkõ=OÑó¹q—½{,põÖjkXÝÆÝ[þvMìý®õúRÏWý*Õö74èæøƒ£›þjdÏ ã04ôÎ?ËûÈ—¦qzdÞµXÈéùm;lh2e»ƒ·Uµ¯ý7¢çú?£±Ÿé?F«ç—ÝÐ}x¥,« µs»ÍvK+ªÀÛ+k[VEm­íV:s^Ì!ˆ÷8[†]†÷ú1·æÞ³ øÙ z¯Ól®œ»ðq°lf5vYëdZýæËãôε¯sÞêï­¿OÕõ?OgÙê¢õ~&†šð1ýÖLr–9 GæÃ1’'§£ÿEj˜5’WØÙXÈËcÊH‡¹ž¡iq nÏkŸî~ß ‹è;]‚é";/ ´»úôÿE¿þ¿øT£Šü¼+q˜Z×?ió·ÚöÙîÙïüÏÍVbA£z¾¢cæ#ÌrÃ6&'8Dëë­!/îäôÉz(¦ã}Ðû½r`Èfßk>…-ªÆWú&ïýßz%´Pks­¥`&×K¥À;·iÝnÑýugH²ú6^)ÜÊîe@\Ö¾Ã[ª·uþ¥¾ÍÜn÷u ZÚϽÙ%ÙV1í YS¨­¦ç;Ò¶–½íôO¿þ)>ý&3–qˆ&F#}å“Õ?OèÊNȪ§Ö©»Ó¡`Û=ö5ÌsÂ;ùÖ~ÿó‰¾Í@»×ôk¥ØÝülþr7ýb ÞŽàÿP=¬¸—{7o v?Ù·èý ¿LÒ°ƒKØòÒç–˜¯è ­î ÙV×Ùùÿú1hYa)Ê@Kˆ³ë»®–UÂÝSé{Cr²ôs¾uãµ´8éÿ VBϰmªˆûMçeðŸs¿à±™úkõ"&p·¸Øxï»”º²öÁsvúa›™-sŸ×[üßé=oæýéËËÇy}Ì*8Ƽ'Ž^£ÿ9B²ëè¶ãxÈ®ë ÿ8,†ïß¶ÌŠvØÃ[¿Ew³ù¯N¯ ‰Šw}¦Ñ¨»*ç4ÿ%„b7ÿm‘LtÌ'دu,iû­££Ôî{ì¹õÔÝï·ÙþG³cÕ;½x¸Ò?ûvoz²¼”'ôc_áKÿEG—•öPÇÝ`~ð'{Fêª c^íÙý_üÝž¡Õ.¾ŒVº‡zw:Æ0‚ÞeÏadÿ'éäÕ\úêÌê¸øÎg©è—ìpÜã¾çYúOж´Ú{=_WùÚ?D‹Ôîê8Xö5Ž©Î7Íq2ÏsÿI·c=¬vÍ–³þô_¢¸–ħ"2yŒpéê>™ÎtšªÛpŠÛû5ŸøÓÌ{½·g×ý¥ÿP¹Ü»·Þ>•u½íópiôÿγjôŸØ£þkþÁݧØ~ÿþ³ömèKpÁÎKõÜ´¯Åÿ:ÿÿÕèþ²ãý—ë n úž7iþ{Û¿7uØ™_æ`¬Lîš/ËÇˤVËXñö—ʆßcö7}ÎkY²–¹ÌÙþ“ô~§Ö¾ŸvoIu˜­/ÌÁ{rñX&^êýLý Å~F'ý}sY]õ²Úú­h²·x±Ã{þaXß„±æc¶A¯÷£é—üÞ7‰†Q~˜üG¥f%™âßUÞ…˜¶ï.Ø\Â6ÙO¸í¯Ôo·Õúh×ßF=.¿"ÆÓK>•0Ñàßå;÷Xßzª3Ý“íénCf–òF3~;ÏÒgXÇæñ?Eþ“.¥WÔ«ª×öÿÒÚ@mY÷¡®{xçgرi{ÛöoÑd~ÐõžõqÿXTÄ$t—èƒè=5„ Ò_¢>_ÓeeöW˜sÝC±ð. ¢ûn"·îkœÜL×ãmõ(Çý'Ùl³!ì»Óº›,Ǫ¼tÝOûëΡûf)^vXÝëÌW}¾Ês~ÏS?Jû}KjÉû=-W5®k™cCÚàZö›½ßàžúè­ÿ®ÿ=K*±›Õ02›v'P¨RÖ Ö7$KÃ}1ê·Ö÷RýÙlªý™5úôÿ…Vá*ù}QýßÒƒ©ðߊæäcî )à'ÕûЗèµRW,èmv.EÔ7³E`'ÖÛ‘ÿ³jø}B¬šqÆF;½jí³y¦Á‘¥»v} ý?´~ÿæ)a(̈ÄúBôœ¿üaäsÇ ’ý Cü/šPR–íx¥7d¸K1ÙÈã{÷{i§÷¯»ôh®ÀsXëró^*`.¢ÁCCZ78ºÏÖrí»+Qûn¬ ¶ç–׎Cêu–ŽÙ‘nC}oYõÚßA÷úž«ì§ý*±ôxL߈c‰¿ÞŸýÌ#ó'ª†aUffQÜý¿¦¶¶¹Á•ƒüÆ;c{™¿é»éä[úK6~ÓN997¿©X÷WMŒÓC]¾§7é šÝìs?–ÇUêúþ·é?í; ΟfNc³2Àkæ¦í6×YöºŸ»Òýèmÿ‘êâe~‡ÒV2òŸ[¾Ç†Z2Ã[.‰f;ö[c>«·ú'øOç,ý[ùË1Ôb<ƒ™)JDÎdï~2(srü¦WUFú°žÖnÛúê~Žçâ1þ½µzµ~šÊ?ÂÕé£S}9 /¥ûÃ׈-sOî[SöÙSÿã­âtì|.’쌬{×µŸdÞømŒ±Íu·3.¿Sü¥üí먒ٿ["Ÿ[Ñ¥‰Ó,êOÞ–mΆå ]5–Ù”÷mþy¯ôuã[ú/º¯ð~¢±,1'‹åùèÈÿU~lâ» ³ßü¾ÍEw?,ÂÙ.k\æ^Ú©w­s+ÛÿžÿœU:c™•—“ÔY¯ ¬0ⱎ÷YKM®ô][ÓSg«O³ü/AÕúVèÅÖd³í8M×íøí'k@Ü]›ˆÝöãíçèõñ¿Ò}‘Pì!í³Ü×´‚?œ×7Úÿë(4-ÜsÇ—†Xä bxŒkÕÆzɱÓ0ÎWéø Kl½·]¤GŒ»7ÿ&ËÙ‹ÿ¡ Ô—õ§‡¿+­³=WÓÉôÔ1lÏŶæf²:uM}£,Ù¸ÔÆ Í£ßúÆc[H÷dXÏSÖõ)ý/¥½ DHôÌ|Ð:z¿©ÿz¢,’=2ÇúßÕb󕇒Ìj[gQ©í}¢ Aɦ¦mgÓµÌnu£ýYsÙÿ —é§#¦õf?Á™[õip-¹› sE´»Ò˧k÷}&ìRÈ¡´Ùx¶Œ®­ÆXÚØ-ºªÅvÙ…Ó±ë¿õve9Úûr¿U£#';"ïæëS¾Š²2êÂêXÖäo­ïƳ2ºEí5ú_¢£;¥Yèdzž¥c1þË—G¡újí®ÏQhÃý¯pþÍ!½ÿ/ë6H—«ûÜ-VtlZ²Ù•SœÇ6ï]ì1µÎÛ{?3ÒÛý+þôuUüÒ|ÏùKÿ åÕa-7ý[Í­Ö6ŒŒÊ½"ö+ÉkKƒ^ g×}ßFÆÿ†X]RŒús°¶gz޲œ×;¡;pÚÇ1Žßì÷)¹hN\Æ0M@CòÉ›”„Ç3ŽR7\_ÞùdÛpkšZà××4ðC†×4ÿYª¿§ƒÓikîx©£‹òºÂv¶¯m¶îµîôke^àÙ³ÓUÆ?V·Ù®~{ð7?2šk¢íõk¬e?¿“Fúv~“ÕôÕÜ^ˆÊkÍûE4ääµÏ¬Ú\ë6×gÙï6åÞç=›]û®ôÿë~§§­7©”jëO^¿à»>à;/ñZ–fä]íÆ­'&Öiÿi±¬þkwýÈËÿ­ã-«ßSîê½.ÌÜl‘‡SŸhÆa`´Ûki»'>ÛfݶÛUµþ‹ÓÉÙú__þÓÖÆî™Ó¨k°œÌì²÷°ºÀ@ôþÐÚËú ~u9ߤÿØ•›‡Õ:§KvCú5卑õ».üF:×¶ªßž.mŸcõ^vÛö{jͶ¿Òþ“ùõ$áÁŒœgƒ]e/L¥àædF†˜Vì¬èØìçÑFP[½Ç+Ž;šÈe¾µÖ~ŠšÿX³eJÿ^ú­“Ññp¯Ïµ¹mÉqnIh ¯'éâý’ÏfCi{=\_Z×úÏÈô?šûO¢µ0.=#®þÖÊuv»¨ZÜ~£w£]^Ÿªí”[C™ÕCr¾ÏÌ‹r_e~ŽE×z˜ËSë7U¢Þ‰‚湤ìêYZöÖߤì*›kl©ù··÷™gØéý=¿¥û5vG.fdÇACæïþõªPÊ2G¨ë_½o5õ{¨uâü°õK>-‚¶c\FX6´7í·¬~Ý^#YéÕUUæWú^êÿÑÙnìNÔ®Ùi?Vz¶S¶úµE˜Y6<Æê\öÕOÛœÖþ{0z‡¬ÿûWS¾šÏªŽé·`ýa§«ºH,fE¬®›+©‰•mL¡õ»ôž…¿dÿµõ]þ‘SÂÌO³äî·©¶œ®¹øÆÇ· æRï§k±½_ÔgóßÎþŸÔP“r$G£. ÈÆ áËŽýq:oò—¾ÃÃÇÁħ žž>3UL’a¬7;ÜïhF\·Ô¶æN[ª½î赇M„ÙÔK2Ý‹uŸ¥û nÛ‹]O¶ÿÓÓ‘èz4z~§R›M_o×íØß‚ÿEÿ×õT’I8ßXºíJÙ‘‹`ÇêxÀýš÷ cšu³-÷Y‰vßøÊlýbŸÒV¹zì³{ê¾§ceÑ#æ\Â~‹Úñí»ÈýM£·þïR¦z Íë] «ÔÁkFM».¨ÖOÓhÜË)·ü>=Ͳ‹¿sÙZ«Íò‘Î,zr ¥ÿs6c—ŽaÚciÜÉâk鸵æ;2°[kÉu‚IyklvâïæÙcÙ]LÙWý·O¦<ÐrïfÛsCšñ¹Ž´Z–Úߣm85Ý_7ÿÏú]; þôUìÜn­Ó­ô2°Ý‘mŽ-ij®4ÞïðU¼þ‘Ý6Û7~“í«UúK+Ì»ÒzCn8{Üne_I¶²ÝÌ{ñì麛tö~Ð˯ô;?˜éؽŸð*·!Éd—1ŘÅUÅúGôxOõZPÅ8HÏ 7 !zÜ¿Gü!³¥u,kñU¼¶Œªnci{>Êöä:ÌL×;7¥ìöÖ2žŸ•ƒ¿ùºqÿšE»'&þ­cÙ‘n7Iqª«1›ê¼dZßÓdßCÎulm Â{1_]›ò2}_})ëÁêý.G¥œlœv3ÛE¬ôž^ÚÜßUÏ©í­ößs(õþ}öÿ8™ù=?;*Œ~§Òî«-î5cÝe\Hg¥ŸI¯&ÿI›?Gÿ þlÏ L%pã:ÿè̼`›EÃÑ/ïp§¯©µÍq£}VÜQ¨ì›êÌm6TßI¿£²æÅ.­çôË2ðvåãÙX§)¯-º²!ÇmsÚÿnöµûU¾£SGTêVÜêqë¯Ò¶ë’_oO¹ù—]KóÝêØÏõqª©Îû>NG¯fÏô¸uì ­Ë=C8_½¹bê[/¢ÖY‹‹gçþr©Ëâöó‚\~Ī¿½™— ŒrÆVw<1?Ýý' §õvu\L.›–Y‘ÒØ1nuNÝc¬ôëè÷g6·º¿ÒW—ˆú2?Wû¥ÿr±6BY¿¢`RÚ±ßkæSEV¼Ü×½ÛÏèeÑê7ß¡ê=Šå9™™½O«e:¾¥Š ØÌ¯µšß[Nfï³àú¸ø•²ßÒä>ÚýSùõ üï«6ZN[Û{šÐËMa ,ÛVK+w¥‘éý«}mÈõ¿ÃÂ(þõÁÌ ¸Äö”x?Dy:ðÄF2 ‰zÔœrqqzÏìî²íõbÞ*ϯö;sl­¯«ÓÈ®ºnnÛ-ôïÇýNG§mXÞ«ÿV»¥¯«Y“ÓË~¯ãá×Ñh{ØÎ[aËc\ædQçщöìgz´Uèßu·ìŒFëiY}C!÷ôK*ÂÁ~>6F3Ãn`¦£[.m·]éb‹_UT:¿W#ô>«)ý*»‰GIÆwN£¤f¡“SloUÊǃŽjp¿"†¾Æï§ÖÇͲªz}LµùaúÿàT¹y©æÄrX„ñšáù¸£%þ ¦°ãä#+Ÿ­=;þ’6·ü€þ‘ë~À};6f9Ö2íãec£7v]íúûE¾–GóTaú¬ª¯µ÷—tŽŒÖcãS ¿&¿cjk‹ýjñšÀÝ·þuW·ÔeÖzÿÍ[W¨•‚Æç7Ï}4ßcó0l¯oèò6¼u _Ó¶ê¿M]ögc~‹ô®z?ÑÔ®¾¬ o²tÚ[¾§²¦ÒÑìc­»óSn½Õ1öýŸí­»èõ,«×õ˜æ'ÈlGò Ìqá…j:JDñN_Ôƒ+kÂé˜t ñ…Å$b´€\׺ë=^×ú7Ù]vú;6z·~¯ú4>‘Òòú¯PuV<³¨ÚÉËɨAÂijùº1ÜẬÜêØßF«}Kq?O—ÿ‘,LÞ¡ÔK1Yêu;¯½ƒÓéøïs/®œ–T÷Q•œÇ±·cQ»íÿ¤[F/ó½çIé8}# bbAq²ëžw[m®þw'"Ïð—[ÿ¨ëôꮺӉ`æy€=0Ó¥ÐÿÐÛØôbãÕ‹ŽÁ]1µÕXá¬hØÆê´"¤’kAÿÐõT’I)$’IM^©Ó©ê;'§^÷×N]nªÇTí¯ pÚ펇Ô®;ªý^ê¸äÝk憆uNš6ä±­ géú[±ÿ£«Õé–zÞ—«]tz÷zÚH‰²ÙÀK~œbuN¨l}u6¾µUaζÌx§&¶·vöe`¼Têò}Íe8ÿffÿFÏÏV›õ‹ší¶ú²q~ÍWÚ,mµ ±¸Þ›¿u–}¤ú5îe^¦Å×õ‰Òz oÄ®÷°Ev¹±k5Ýú†m¾ŸúÕŒY¶ýT{dàõLª@!Ì«#fem îæ²ÌߤÝßÓT£1þZµåÊö£ÿ7þùä*éÝ6ÊK°‚Ú sì¦Û]Õ½®s÷äôÿQ¸_"‰ý[íøÔ_ú:}{2VçOe5õ®ƒV;·SK2k¬îÜv²Š*f÷~þÁïPÎú‹Ÿ}‚ç“föØ÷ nÄuŽnã¶û*¿7Ô­Î~뱞¯ç«]êÇQÁêx¹ÆÂÃÅÆ7½íźÛ\û.eTnÙ~=;=´{ßê¦ÜjT¿5цN8Y¿Ýìãô|\lž…Ò}z›i«‡W¼NÓé´iýoÎJ®«Ðñr¨Á  ,ºß³VI­¡Ísñ›ïsjý¬Ûq«¶¿Qž§«ZÒÁú¯õ›]€S)m…·¼Á±¯s”{·÷Ѫú—š-6?;özÖ;Œ°Ød:ï[6î¡ú_s¿Ié,ÁÊä$ñ /OS®y¬`úú\JzænCwQÒ²‹Ý>Žâ í6V÷^önô×Òïëÿì?®Ý7ªgåZ}w«žÀYÒñk6äR\gõÛ[¶Œ7û½'³2Úü×óvúÞ¯U_ÔÞ”ísìÈêfwmË´šôìì,³à¿ûx«g–ãâÔÊ(fŒª¦†1£ù,`kZ¥'Ò¡ýÝçOþõŠ\Ü¿Fôýïûؼ_PèXrp>ÛeuÑöK+ʯ§Uúl‹=' ÇfG¥FCªõk®Œ:Ÿê?ô/Î}XŸ êî_WÉûa¤ôÜrÃ_Û^ÀÌë?G·‚ì ]îýc'õÏôXØÿÏ®á%fŒ#ÃAïjC‹æ6Oé}ø8?˜˜U h¬CXßôž÷:_ew¾Ëlý%¯÷ج$’,*I$’SÿÙ8BIM!SAdobe PhotoshopAdobe Photoshop CS8BIMÿá8http://ns.adobe.com/xap/1.0/ 1 295 300 1 150/1 150/1 2 2007-07-13T13:02:02+02:00 2007-07-13T13:02:02+02:00 2007-07-13T13:02:02+02:00 Adobe Photoshop CS Macintosh uuid:d747b9af-32d2-11dc-84a7-c4efaea405a2 adobe:docid:photoshop:60020505-1ffd-11db-9d58-ef56d46c77e0 adobe:docid:photoshop:7582ff4d-32d3-11dc-84a7-c4efaea405a2 image/jpeg ÿâ XICC_PROFILE HLinomntrRGB XYZ Î 1acspMSFTIEC sRGBöÖÓ-HP cprtP3desc„lwtptðbkptrXYZgXYZ,bXYZ@dmndTpdmddĈvuedL†viewÔ$lumiømeas $tech0 rTRC< gTRC< bTRC< textCopyright (c) 1998 Hewlett-Packard CompanydescsRGB IEC61966-2.1sRGB IEC61966-2.1XYZ óQÌXYZ XYZ o¢8õXYZ b™·…ÚXYZ $ „¶ÏdescIEC http://www.iec.chIEC http://www.iec.chdesc.IEC 61966-2.1 Default RGB colour space - sRGB.IEC 61966-2.1 Default RGB colour space - sRGBdesc,Reference Viewing Condition in IEC61966-2.1,Reference Viewing Condition in IEC61966-2.1view¤þ_.ÏíÌ \žXYZ L VPWçmeassig CRT curv #(-27;@EJOTY^chmrw|†‹•šŸ¤©®²·¼ÁÆËÐÕÛàåëðöû %+28>ELRY`gnu|ƒ‹’š¡©±¹ÁÉÑÙáéòú &/8AKT]gqz„Ž˜¢¬¶ÁËÕàëõ !-8COZfr~Š–¢®ºÇÓàìù -;HUcq~Œš¨¶ÄÓáðþ +:IXgw†–¦µÅÕåö'7HYj{Œ¯ÀÑãõ+=Oat†™¬¿Òåø 2FZn‚–ª¾Òçû  % : O d y ¤ º Ï å û  ' = T j ˜ ® Å Ü ó " 9 Q i € ˜ ° È á ù  * C \ u Ž § À Ù ó & @ Z t Ž © Ã Þ ø.Id›¶Òî %A^z–³Ïì &Ca~›¹×õ1OmŒªÉè&Ed„£Ãã#Ccƒ¤Åå'Ij‹­Îð4Vx›½à&Il²ÖúAe‰®Ò÷@eНÕú Ek‘·Ý*QwžÅì;cвÚ*R{£ÌõGp™Ãì@j”¾é>i”¿ê  A l ˜ Ä ð!!H!u!¡!Î!û"'"U"‚"¯"Ý# #8#f#”#Â#ð$$M$|$«$Ú% %8%h%—%Ç%÷&'&W&‡&·&è''I'z'«'Ü( (?(q(¢(Ô))8)k))Ð**5*h*›*Ï++6+i++Ñ,,9,n,¢,×- -A-v-«-á..L.‚.·.î/$/Z/‘/Ç/þ050l0¤0Û11J1‚1º1ò2*2c2›2Ô3 3F33¸3ñ4+4e4ž4Ø55M5‡5Â5ý676r6®6é7$7`7œ7×88P8Œ8È99B99¼9ù:6:t:²:ï;-;k;ª;è<' >`> >à?!?a?¢?â@#@d@¦@çA)AjA¬AîB0BrBµB÷C:C}CÀDDGDŠDÎEEUEšEÞF"FgF«FðG5G{GÀHHKH‘H×IIcI©IðJ7J}JÄK KSKšKâL*LrLºMMJM“MÜN%NnN·OOIO“OÝP'PqP»QQPQ›QæR1R|RÇSS_SªSöTBTTÛU(UuUÂVV\V©V÷WDW’WàX/X}XËYYiY¸ZZVZ¦Zõ[E[•[å\5\†\Ö]']x]É^^l^½__a_³``W`ª`üaOa¢aõbIbœbðcCc—cëd@d”dée=e’eçf=f’fèg=g“géh?h–hìiCišiñjHjŸj÷kOk§kÿlWl¯mm`m¹nnknÄooxoÑp+p†pàq:q•qðrKr¦ss]s¸ttptÌu(u…uáv>v›vøwVw³xxnxÌy*y‰yçzFz¥{{c{Â|!||á}A}¡~~b~Â#„å€G€¨ kÍ‚0‚’‚ôƒWƒº„„€„ã…G…«††r†×‡;‡ŸˆˆiˆÎ‰3‰™‰þŠdŠÊ‹0‹–‹üŒcŒÊ1˜ÿŽfŽÎ6žnÖ‘?‘¨’’z’ã“M“¶” ”Š”ô•_•É–4–Ÿ— —u—à˜L˜¸™$™™üšhšÕ›B›¯œœ‰œ÷dÒž@ž®ŸŸ‹Ÿú i Ø¡G¡¶¢&¢–££v£æ¤V¤Ç¥8¥©¦¦‹¦ý§n§à¨R¨Ä©7©©ªª««u«é¬\¬Ð­D­¸®-®¡¯¯‹°°u°ê±`±Ö²K²Â³8³®´%´œµµŠ¶¶y¶ð·h·à¸Y¸Ñ¹J¹Âº;ºµ».»§¼!¼›½½¾ ¾„¾ÿ¿z¿õÀpÀìÁgÁãÂ_ÂÛÃXÃÔÄQÄÎÅKÅÈÆFÆÃÇAÇ¿È=ȼÉ:ɹÊ8Ê·Ë6˶Ì5̵Í5͵Î6ζÏ7ϸÐ9кÑ<ѾÒ?ÒÁÓDÓÆÔIÔËÕNÕÑÖUÖØ×\×àØdØèÙlÙñÚvÚûÛ€ÜÜŠÝÝ–ÞÞ¢ß)߯à6à½áDáÌâSâÛãcãëäsäü儿 æ–çç©è2è¼éFéÐê[êåëpëûì†ííœî(î´ï@ïÌðXðåñrñÿòŒóó§ô4ôÂõPõÞömöû÷Šøø¨ù8ùÇúWúçûwüü˜ý)ýºþKþÜÿmÿÿÿî!Adobed@ÿÛ„      ÿÂ,'ÿÄ    !10 @A24"PB3$%7#56 !1AQ"aq2#BR3 ‘0¡Ñbr‚ÒCS“$4´7@±’cD„”%•&vP¢sƒ³Ótu'ÁÂâTEµ6fg !1AQ"aq2‘¡±BR ðÁÑbr‚’#0²3@á¢CSs4ñÂÒc$P³â“ÿÚ ÷ïÀ"’ê2¯ïGQõ©¯zÁˆô²Xƒ½ä…BlóŒ©^H­^VÏA^ж Ü-U“žûgÇw€ä#nK¾S»Ou yØx,l¥\—3ü“Yß =+¡fó»8LŒõRr…®ÖR¦g‘lüCMñlÿÑCJ8¯ð¬¥’ê©ÆXo£d®aàV-ŸP•56²þl.¸Öð  Ò®<9zï;Ë}Ví¹ó|`໹L‚¼âÂHmÅñ «0"ÜÓ-Ï_|؃{ÓèMZ`vsU=D„s¾ïÑ’½:ºSÞð\yíÄ×´yZ‘‡}~.$ Úiä ðä‰0ý“ö&å.WèZyçPºuþÓ‘jÞ‚~ï­È׫T_sȶ»úræI&4—›¹¸7v/À{KðWO9ö›•*E£ž€R;Z,<³îÀ˜û_¤gÔî¦! H*%Éní×^•ÊM¾Í­8>4!žj—ð²G8 h·ŽÜóùO¨ù»¿6Óè&îõøhCÏ|EÅ¢ÊÔRJžÁË©QêÂKŽ˜ŽùówV6ÆùQl®þ¹Øû”,eVÁ t†áº°É˜Jxµ^LÍÎÍ» r×O<¢úMqéZ‘fC¼…^3å¤ôM¿gË›ô#v7®œYʶg^³ØHòü~Bv“Ûù|)}’·+\ëŠîËt[ËGkWæ#÷xÎÖëU@;O%¢lì‘ê>à é¯ÌlÛÃÛ:#ªQ¢WÚÏÉö‹›à?°Ö$ý&×Ðì •ëçå×0—E|.}K¾{ÞyèM´BéËûHîƒÇó«u¢6ZYvi¬¿}6g#—ãØjARêµ÷‰å¾zJIY6¶ô>Õ‹¤4É‚Í(wIm+3¹õd³þ„ozl¾ 3¾ãÔ'Õ&Ópksù#k›ÄJ³dã ˆæ‰ïšš‡“ç_Ú¦²ŠR #3\tDXSÒ°§‘ï(["†VÎ×n,˜ù}ÍÕ¨1ë>¶8VÌ»“ž©HôZíÍÏçÔ¶š÷vƒ Pv«·è_Ö?7óþ1óF²Áu³ñú]¨¯IpFœ]húÌñ–ŸyY,Tùã)+lÕ(‚ÎF'¿ž™Ò½üõTlô"Í­ýRù#AÚ)í6sXgxÚmoè/+ñaú2veq¶}¶qx/¬IT€Åìg2—æt@9q˜ÐnD„èŠså^•¤IÛl ™8Jù=W¹5+òBz)eb“ê{93JsŽr´KF…r6{½a±ÓŸvvô\ê1Å&ÇÐÞ*gcQ; L_Hœœû”‹ødä^ÃmNýÇáY€ñÏ6~^Á6I'zå“Ã×s“𾓒I\5Ö°%mž¡¦«.©êŸxe$}¡eq`0½7ÑGg¶Þ&¥”ƒtDX"NXÕ»®w>Ôn[÷/j<úß¼ÐiË,òì>ÒqùãÓ¨š/yÉVTüíŠ×‹4îÉõ++,fÙ½ ÓëÕjÓ¬=êÎèQúÛ¬S‹ìdÉæÀ„I†kq¨’è{u/U¦Ñ4²^˜o5ÿ£°ïÚî"¿N%æ½£?ªÙ(ìSØ6ô?$2ÚÆ?šQûõÂßRªõnÝc|×aY±QÈK<ÛÀϳ†7}R{GÐó7ßi¥^Ñ›ìî{O.À/^Øùs+J`‚°²ô¦°½7^N|íilÑy}õ…Ï)%t‚ÖNƒÅmkM}¸µ.Òˆq/b۳νþeŽø¥‡eSÌú™[-3öµ Iï–ëÍŸÓ@®WËqÌm@±ZPÕš×÷Dß›UA—Æ2¸´)x)’Pî®ùËâ²$¤³8â>¤máƒÞ—ó}¢¶å¼~ØÎt *ëJE‚slG¡Y²n+öõÒ|váoÏ8Óš§\JÎ˺ ¢8;Z´« cW'¬Oh˜t·õ wáüx‚°ŒöM——:lòü­é?“™¾WÖ{k2Fn*¬CrýólŸ«<|Äwª^[T^®-a­Ü;¿À|Eû›óg’_:bô7>CŽ÷€»i“ó_ SrR»ß‘yïÒ߃ŸAV%2[!¦ë=µÍò¾£Û$ÛÚV/Qb¶³6Ú\€ûçq/ÿ+/ˆû´ŠÛŽ'O5Þ8"«9–±ÃcU ëieEGõw»ü9à¢5ª©_´Ùéw†ÕþZjÕÀ×)]Ïíɧ¯ øC€[¹«Ï[س8· ¹È-Ÿ;Zxk.ö²ëϹ³Ý‡¼ö™F¹ötá¶ô»5Y·ü~5ì³lö°%â…ü·€ìSð’ž—lÃFDºiÄFÄÞ:ª7Û-¦ñ_FJLc÷Ó]Œ}J¶ý­2õôS™%Š´fªÄÚkÅdi«þXt5‰§˜kôÌoân!•°sÊXc{ô„±MÊ™¶jDFÕý*ÈöB´MÏî’IåY,[rö_ê)§+/Š…Ô`²y-ƒ1}ÉÄV´c;‚ʯ'Xä"\z…%¾j·S[ηˆÂÓŽe+3B­ú'Àw€œu¸UOÎ8—'³²úµ”„¿ykiõ®ï>aï¦ô whºõ18¯}!k k’d§d§ò=&—ºÌ1”úõ§ç„*Qó¯KØU¤P#¤z KŸÖ¥ØoêQ—6œæ…¾×¤ ÙÀ²Q¸°hR>wÂlK, !P1;Öè«eäk-®Ãzsêoß9~í~šx¡¦QZ¯=bù:Îc1lÎ1·ý]%ê‰Øè|¤ìQöóÒ•¥ôV¾êÚǯë?‚G¤ª­Ï¬ÇX(VÕQÅÚš¹¾þcð¦Ñä P‘uçæÜ?b’u¢Õ`uÀΦ$¾;Û Z‚à1ýz¥šÕé‘â%ÇÀj”VáÄcoúºKÕ8˜®íLfR©û½˜×<‹·J§-2>ÄeõÏ/mÒª‡S·†‰¥ÉÒͯšE„ïÆü¶… ÇóL§wkM®§Ö—2oÖ’²‚§]€ÊÈ|i7{÷Ѷ1Øè±èðÞáhn»ô>Õ×ur i&QbÏ©f¢Û-|òÃÔ"ûb;'÷çÔæì¨g]V?nɾD«¬à ?ʽ" Ü<Áò9õ§væ¦\¬×2TÒ®ªŽjSêÛ=•w°Ù]:ç”4»­»¥nrlÞš}e¹XZ¬jÊaÕÕh”eqeýÖ¹‡_ËP×w BzHžSçb»!È›áã/óåM«îɹGõ•p(§æ6ÏjU¸ó—öÉ9i*UµMÞÙÛtœ¤¡îv—L«8„å‘…ó‡ãÂ3…ú‹köÃ+‚¨y†¥VvÊïÆœ×[¨yÅ ¦…ãúóïJçÔÄ3v¬O«Zuæùí/œÏl…A?2p¬š}Iª®UD'ÓºýÉÑiJ8ùW{\òË‘ ”’­CjΪœu½Ã4µ…ê§cl5?#Z-b=Ã5Êù©Q¥ö Iâ:YéËÓÜÕgJ»"úßç%s €-¸y[”çÛüŸ;Li×ÇïÑœP§ïqßwlu\÷ZágwÒÖƒEpɆµ'©Wx”,ÞTL¾bjvs´é<—ÐüºY{K¿,6,¿ØõHG–XÜŒôïÆGdàÖ{×!ª5¢6Ie¯Y¹¨¢k YHl{Ľ þ5][ñ¹ÖÔ]ƒ7ÚÐÒ‘X]óÇFÛ µÚ‹…`eTíµCLœÛæRž!§õ;Î^ÿÌGеÒV¯àÎrÕæî>D¢H(|aŒ½šµgiÚ.ÀÇÃwn;Ìß>£ #pÝLù„é³™ Õ ú’ÞµkXéf^ ò‰>8+¾…¨ï!Çqy=ä?i¸Ý2Ϩj,,7vÕ¨Ÿžöª“Ú6SOí?¹¸+—5 r§àå*ã›ÃÖÀÓ‚IÔtQÔj©ïWfÚ‚º,i7²¨ïß2—ÉÅX ÷—xÿÚýC®Bû´[Lw´‘ q²ßŸ½K"í’‹= é—RkYg› Ù”Å¶Ó äK¬ItÕ/ðÂ=²^ÆÆ,²Û9uqü»ÇãÔ((Â~´º ‹>À¨Y\24RŒkíMx·Ñ Æì—Í n•ÀÿÁÊL5ŒJáv~šÇ9ŽlŽYò­*Ê(PmÌ 3ÙWóåtÊûù°ÿÈ$åd…µ¶]¾ÅEp Ýâ É `EØ¿­ç‹¶ËÃd-œ±?€´ßQŽò*×ÿ)‚f`“Û!}7ž˜ŒW9Âð‹ÅO Y ¿þæ"¢ª3m"¢ˆ¨Undmʬ É *ÕùßÅ­5}ˆEÄ ¨cBÝ~3ŽZ*éDqî}’i¨R †"')¸]² gf“~º–C'³®Ü¸„0}ÂlCî‹¥Q;+¼‚ 3¶&àÖ©ž>ÊËtÑ­Dгxú)´¡k–—°XÙÊnSý#˜K¡¤M‘Ñ ¾#©ÐÄ]‹žåx˜ Ô0åè°‚zø>ÌÁ¶6$yïW# RhŠÄ¡Ûšm0~ÆãXfã$«ÏãC6QʶG £Ø¬Åh‰·‡n ¨T„é«vG5×-\¦å?Ñ¿[…Á²:4]d´ºm’J8R^ñç EÌqfÉïã£ðП¹`Í“t—`ݳ PxÊ©g1ØÆË3cPƒQÅ=ÓpFZE‰"Db¯4MALìlîäSœ`ýlAwQN“P’$R-9–”»Y¢V!€Áñß­#ŽG×Uv”‘Ô‹\LÞ³§J9S _¦Ýi 1pk3£6N»*ÿ­G¥„ežÇ†Ç›Ê!\R²Á\RV8P°@‘‰Èµdà ¼3I€U3&h R޲@e¾Y’èºn¡dZ’awi|s2©F4~ùWËÄC«$e$›Ç²Us.R@´UU;–ñdSÇË ïØ á»Uc¬lkéÑNA!º¢ºˆ™u›?É(¹š±³™Â’õá*g23ÅxÍfkUeÌ°Ø šÆ’YHÇmjîTíÑwUŸ,Ã/†ãh!Ý«_Mà$ªÍUp¹×R=ñ™ªåÀ®¤B¬›#5" ³e\ªÆ1´>,±Ö>7ˆ]EŠD‰rD޲€ %ß5§6TNÑR°sª#Ü(ÞÅ·˜ÆÒ¯#T‘­ÓeœIDΉâæ¼zZ®ä®‚¹¬»PMcÛ€÷ø,2ÁÄÆ L%»¢øW•I>­ZªéTJ!,bÄîÎtÐE³æTÇPÇZ,¶ ðÐË‹6UI‰™œÉL 2Eø:nfêã†ȩ́ìÑëÍÄy'.€L´Êƽ‘›Õ:½OÀývL§ª¿VoVf¡Õ”É8W1ãŒ}™¾;bVå{$ƒrCYW•T²hÛ áSB¸T áƒG8ú¾² I'$ƯHñ1‚QÉ6xng˘µF ¼„ÖqË$r÷PÂPDýÇÈ8²oŒùÓ6Âågðʳ!J'R:FÈùw ‚"=â\Šâ3Ф"‹©› 0‰‡â)„£!›ì9 ™(%kŒ½oY®·jéãFH³LÀü@ ÷)°C¾ |G.o½¤^VL²jÙÓZHž´ó±]Ɔ8¸@­Mø‰‡€@@c#Â=0Ò–Ž÷éäEEÃ¼ŽˆlÀ‚>#ÐÝŠ ÈCù‡~Øä½›9×dr¸ÙûQz .+*ûvóR~ã*MÀïÂaÀc °DDRb')ÃÄÝ󾮟¤§|ï„KÈð¦ŒDK!8n‚Áw.wÄØÆ0!ÇòÍ¿œŽ5›l’i(<’ÆB7¤^Œf4\ÚEÈ8\ˆûtGòT‰¢_$Ê@\UºPÂs:$"i·€ÆGÀŠ”K!—ðWª#ØýÂSœ@/‘±ÐwO¾]Ôó—ꥑê¨ôH¾œzóRpéˆF  9Pþg¹X ÍT“Xþ`s}uYÛ;g`ê™<Î@ì ˆD@>géê¶yÔÅ?§þ]ŒßÓ’'’ì£NÁ"jÏ‘šºB+ëEcD ù”EP\#S)Ìì‡ñ4j  2QB"Øé¨”z‡)(c.ÜÈH„E°C¸€÷ă¹ú@Év1ÈöO¶læ¿éÊÚÊ%•:§Œ0¼‹éQ_»Œoî\cØ“µN ǘtb¹ €a^'î )¬Šë‘'pA)_Ôx¿¨=#ú ý„…î=ûbظ©¼J™ æ ˜ýúròËÜÅeef K R‘Ô‚ìjù<Ä: <1Æn…²§ne›”ÂQAÑ^§ð&ñdÊaÁÀL?LÂR€ƒË;v詾hýD¾%ÇFî|]¬›Ö†hº*ŠGž”AáXº3Eæ%Ï$|cáò‘Ù4Ä29É@îA³•¨ÙtÞô#âDâR@çÄÈ#ÛŒr)Àn‚8"‡¨n†7‘ºlX¿n÷ªi™C: ôÚ®!Ä‚‹²Ê7Æ’jˆ¿€‡ yŸ ,(ô( …µÕÆ‘i¡ŸL0‰üò.8_*uÒDÏáÐu.ÌpÅSì8àþ$íÖ×÷6ASRpJÆÐ1 AÈé˜.‹´q¬ª e¤øî¹€D)—iƒ9µ”X‘èÀ\L#„OåŒÙ¨ñDˆÞ9[îRH%¢O°&©“Äœý\ŸÈÿ¢ ¹d=ãÌtígjd3ôÚ-b` 9$¼zÍBP¸šÇOÌÍ$š.I袔÷%úaÃæ ÷”#ã|dÎÎ4[ƒ¤±M©È Ì$ S3èM ÜpbaÜÃá°ÃUšè2’NHùŸ´RI pú9W&èC˜†`otÉx•ˆ^†Tç,÷%úuE%3ÐK¼ö T0œÕWÂI’o¨éZ£ÐY_„ 8$Àì?þ´*—XéÈ'8Ýë_j´DÀ4 ‘|g Ôn¥~,$d4#Ö¢w¥TE«%3í>XÊ!r®BA6.”ÄkÏÆõ” ‰¤šVTS@®¼@SQTtñgJaNbeÕXÝÄ0¦ò Ü¿€.uaŒW½UšÉ¤Y¶Ê¢t…«Ã· Y´6dÇíŒê z¸xQíeft^-d̼aÒ+ ÿ¸Eb¤ÙŸ{ÃMƒü2.)휺3(õTç„¥ ¤0œT—|!{bð¡âaî?†É¸NÓVR\fà¨*îtŽ“Ê4¿vþ%7®Æ9ÙŽ-š[Ý>FAdð®Ì ±þáãc9Žr· ’ÖgÊYN­ Ô*a+!웽‘pìW|‚ÂË ca Û;`ž{è9l›”í4åbÇ¢u*•ò³@åL@bó™)Ì’õÖªcªÒ‰£ hWi¬Ú}‰°*ÉÙ¦áŒÁJ3ÅZ3Yc,#{nÖ~)dPrEH¤¿oò.ØRvϦÏ@€úF(,´!Q3&mwæx澂k b‰$º.©Uhй%؈TCÔ\ÐʆwÃs dµŒÏÒi&å 8~áÆ3LN¼¼‚ei"­ ä…‹,öÁØ=ÄD@¸ú³Õ†’Ä­E•$Û¼ò6(‰‡íÐU3Ý^¸W+%TŽü¼‹üš"Uœ+×P¦AxÑ y$g !mj)ÍÙ=âyS”õÑ0öÀ"&Îß®ÑùÛN‹’€.Ø~Sbj‘@ÇÑF1ÒŒXæ(ý õ1„È7Qs9r™¼I„² ¶.1ˆró!ëɰ7|÷Àà‘Y,MãS‰¢ ™©Á:­L¤‰ƒwêò7Õ()ê¶n²’ ¦é«·Ë⯜"ʴѶ@:vþ·lMâäÂË®I"”ßy/oåøaDILG©²&!Ñ€ÄÿÿÚýPLG,Ã<¡‹ÛÄ£‚™pRÁLpC·ñAÀ0áñÆ€àç|¢8RQùg|ùŽvÀ3}Ð2D6+ÑLZ²ØØ½eÁ1vª =»`€l1D?"}ð¶}§o˜Ná‚=°ßF_ô1Iƒ”¥YFå)Êlåqº¸ö1v˜Û;÷Ã'úäO·_®AÙüʰ0 ôeý¾"«B·9Š1-¹‘G$”1ñým3È#ý0Ä`‡oÔ!~6°çãk ,‘0ÿtCI“ŒV€&~vNì&Já'¸SüYS,sÿP« EÉ#vJwíŠã){ˆlíŸÏçÓ¿~´çO±Яۦܘöm“#&¡T/W-’rEkfm‰Ü»I2;ØÃ°V"Ä”fÈ÷ʹìˆñ'¾#ðËÛ”fú&ÆÒD>¡ñVèçv Û$ÝŽl§¨ˆ€„2žœŸK*ú‹•]tJ|œOÔaß,E9¤}#碦z*g¢¦z g ¦K‡‰˜N¼àœ ®›‚ö}z0´OÎ(ƒôWïñÝ£å™ÈäLáÔÓˆ+ÛÉ)ÚmÄÁ:wIéãÔÒQ‰›Åç‘s̸ù³Ï$©&1-Ç=BcÓÍÿ”ì»Ô_}õþ}ñþ}ñþ}ñþ}íþ}íþMTV4Îâi/ÖËV}zXW`ñk—»ƒVR¶-c”„T’Õ'Q¥@‘ÏZÁFB2~­f,¤§¨L/Õ3ù‹ßmÑÏ4*eƒt-_2tWhtî9)R7½Ç§qÎãóÈz˽LšH‹ôŽs·1ŒH”ýI.Ÿsoég¹ûžL©é±íò»%âü¼•jÄÍIr¶Q‰«ŒÐ3ô Ci›!fký6t‚ìЪ=hUÛìÈÕ)zbÁ䍛-†Å’î® ‘oao.^›*De‡(ª¡G¸TÑõጫ&ío¨ÃKÊe½oJ+/ˆw.Aªpjª‡9ؘ\°éoPøØ]9ÇÐÇh–“»°eú ì¢l›W¨Hš¾å7ðÒÐPNå ×Ú+ã1¦@80Æä¸Ì?pð;$üÌ"•¢›,š~ šB²lW²® p«MŠçÁŽ[úñÙ«” UáÖ'”ÚžNq%L‘åS(¨ÉصT팻rœJ:Wf’]·Á!Lˆ]»d›'ð_làà@;k$¹‘H©­ŒíR©—&\˜VÈAByÀe}™[3ÍŠóÔ{ЦUHé¹›ª’ž™åߤä­ u¤¤ŒøØÑ’ÎŽÝ ˆ€€Å»/›–$02z³%µŽèm2Ÿ~ÿˆZob°&™S+—"\bØ¥(ˆ@Γ–OÐzž,ŠkeSl“Ô,ç@2að¾yÒìÃÑuÔ„1̨´rª,B˜J.{?KË,a‘Œ€‡1‘¼% ‚··kóEAt×/l펤ز[5¾MXd&pz¡»@ãŽcå ¢ªÔ‹¹”ØSÓTÝ$έ—ËŒ—²Žëa÷ìú7‰0ò¥nV‘©*‘Š%dñFŠºjš©ã9u@ÊÇ£ wMTlbˆ€±³I±Í«dõ~äýRªg2«¦ˆÚe ¬u³ )qÛ±î_ DÄT)@¡"ã°BÙÞEŒ%­œ§[Ü·»}ðOÖÕ+ÏrÕŽ8r£ƒäc²7Vi§¹(‡aÆoUh§¶IðvÄ—:`Æp€t‘fà’mPA(ßî’þŒvCÓf&"I"ˆöÅž™\$€,Ÿ¨DQ*@ªäK2*â³&tòôé–H[Ú<ÆÁ3Yʤd‘MS\®Û{e"ž¦ ;du‡¡$Ñ#¶®¡D:cœ±¿Ý%ýV~™à¢øé_E3L1‹,±R*Ê™SF­Ü¬Y{×.ã:Jb–²`Åqƒõ ‰ªdÅp$ª.ôŽ“à³T™dN‰áصȚ¯Ö4;Æøª©®'Šd¦ãŒ`ÂrHFH£†v¹ðÉL)J@3žøR ÄV=RcN\(ý' +ŒÛ*ågè9dᥞA¸ÂKI¼µy¬ˆL×\FÂ!ß,õñ`¦4tvª‘0”AD̘·rdBBU' Ûض†r›féZÿÕ,%YebÌC/tÁ˜ó”àRSæÑØ/‚UT7¦¢‚Š)„{™.@µE—XßpÕ¹ë•òÆ'v‰2频Ö<yaÙ€BÓ5÷È‘bX+êF©–Tq,WÊ”O¼r³v¯…xc ‚i™C.C|ªxW&ðgÿ]TÅD +*Þ²ÅÈ3#7" åoD‹8:¢ƒ×,eäxWlC-Œ¡™²4¬ §ñâÕ26nÜV\eU´K‘Š ²$X– Ê‘ãÑ$Œ©üI ™•(…Ï¥[2 ºÐ ŽkÇL­Yªä[ú"¤xˆÒÉ‰àæ‹ ­ÉÓzc˜âÚ=Ò­ÑM$ltŽ—âÅVE³v‘iÊIŠ D0ÇÐ;ƒKI#‚ŠC~ˆ€NS»áÈb•äi©v»w%9TŠÎ7p†0štäñ/JÔ…µ¤8< QÄ"+E`«È¶Ï»íñêž-Ü®OF« t\È·:„'àÎ<ˆ ǤlW&p²Òrm ›ºt£•?R^ ´‰e\nãÁ2bNK•+·(,‘Z*ƒHv‡]A(”Á2 Ï-íÓ;Çjœù³ù5¡´âÎ9y°m¸âKœVü[Dl‰üW‡ºyøn>qª¿¨Aq3]ñ¶›ª¸É.Õµ(°©Ç¹æy³~Sk®\qãgÈÿ ùó(ÆsÜЊ²¾}¬·¾ÙÍw¥õ>§DDDpL'¶A%pßeh¸NGñ&Ý¢okpSp<Ÿâg²Ü1{Ùµº/’ÛNv½·4‡"êðznéCiÌ ¹=rÍ]¸Bÿµy]U²k*ÛÞ\ר0cǰöÙ»Z©ë—^AÄh[¤£Fqf:ÍCã¾§£Ð·Ò ‰Ôé(¨@C$ `æc­PÔ¶ õ›ŽRUö¼z¤ÎRµ¶o™¹I„bµ]£K)TÙÐÛ…†¾ÛûCI¨Å’÷]½ª;λú[ckS4½‘Gºì»¦m×[Õr• q±y97^®AU#9 Áî³°ª•zã_×:C^k»+‘:_R¯%ËMcNÜä8G:UYšK—:V¤‹elKOÏÇ‚hrZ¼ï}‹ZÊ&çÕÛ-AÃ97Z…Ñp²“YP¶ÀÞ«û YVö3FWÇ3c²-ÄØÛ=Xv4>ò¯ï*¯èZ-êUr’ÊÅÈ[Þlí¦• ºcKNl)y‰ší.Jnè­Ã»vîЄ۟í"F~c€QÝ:Ï_ÔnVfž†ÓûRÅUÖ7Iý|ûÖkT>²ÚÍo°/Û‰e9:ÂÂnEþ#nROBo8˜ómílúWcÆr6ôýš2,mº­åuEËXCä¤U#lRªvåé‹Eí«v¦Ò¦[`¬ÚŸiÔ7= ãØsÊݳ›'“•}yiÕÌà÷Ü>ÏØqº²’F÷þRlZB“œŸÕ»‹I¸E_j­ô‚››KÒN}‹¼§ðñ‚”Á×›lÿìt@‘|„ŠÂlÛ‰mÝ%°_KŤ»Í1¬nÁ%¥¹Ö7f^ô©Ø?g"Ïrqæ¹£·ìñvª­zï]‚^á2–³·Íq¾á7$¯vš*¤á/‡•ÛNË[ƒ×”*Þ¯¥n­ÝXÒ1‘ÚÂý¹7ƬԘ×ÌrçjECÖê[qìù-YF—{íÅ­3})«'n懅‡®°ËfÖÖôWl^7‘d â=§ ìñèë;= j–ín{õ»­k°úÓv¢êY&6>;¬Ù n0<†ÖŒáÛé¿xÙ²;'_ÇìŠÎÇÙ6]³¦u }êÉ«x§k•×V?‚BA”K/®»öýQå»úŠòÐõ=X­WbêUý•¯cö]n¥[B£]Ý1;žõmÐÚÍår2Ùl­Qk—Ý©°ù$0PÕ¨¯¦Y÷M6KnÛ[7%NRÁ ºû·Mkýšz¦€®ìHF¬®u‡»Ê«´kVVâb­ÀÛbK]4@Në­w´bhÛéJ' »Ð³,_GLÇlg°©{b³*öri/%ªì;›JرÙöVÑ­v skP:óâîéÍU»vÌÛ®‚›ÂÔoZyæ¯åu.ã2 =.úÕ¯?=häm—æ#°¯Ñšî”¥ÆÍr¢ñÅ”k¨èõ§.5¹ÈM Àí¹£\ÙU³Z·4Êí¤$Ù9ƒ¾[µBÕ;++ms1–Ò»¶×cUõ.ͲšîHÚ>ø#›’5:„”äU¿haXׂrí›2AH*׸GÛèW_t t\~ÖQ/¯Mx!'²¬ïK[㸊ÀCˆv½ìàÛy³Ýûmø¢ÃJ›Wö»3H[~îcµå“”€Ñï6TU×£Ò~;ÉÃz²Fi«ÃU’~ÊŽÅJº½9#=+«f+©Ê°ämû›6ëªVlÖÝ‘^·Ôì[ö¥_–“ÛF”«ä5å—–Ãf‘þ¡›Œ{p»0r«Ö+Ÿï{ÓY6ÈÁÉFÛgýGÖÁ9¸3k´VV‘öæ¿lÛ‘fªs+9¾ÌˆŽ‹ˆ‹ØÉDÞÿË9‘á"€J`¶¥«h¹®·Ü&dzoˆcÖ&û”Á›Ê•i¹2ƒgµžãÍQuWMÈ7·Ð6-*“c¹iÖ:þ΄̎“¶)TÔ4WT±EE-9­…ýïnEÖmZz¸Y¹eVE²:Œ“„Í™kN—IÖ5Šªù/g„Ó Y6R †çÈçã§ÐÔîGéÈÞ;ò^aF ðï‹¢ ·Vµ&ˆä+ø';éhÖ´[„zïýšºåÇ^@;øDÁ³5Á¸»µ¾™#2Öº´Ï­õ åÕͧªº¯o²ë¦Ps‘6X½w’¦UâS«èJæÝX´øþœ2IÖñM»3›?yR$µµ_ZÕ\ûí»¡Zõ¼'ƹ”µ ~>-(=³fÛúDQÖºýÆ6U'ù Æ>NëÛ⤛Kç=žégT.)ñ³Œv.ÃÁ,J%®JÈÒÇ­#e,¿˜·š•‹áÚz¹(QÉ\µß.uKåm䋾?]£¥#&²ÕclÎ5ž´ÓîzÌŸå;ý§aÚõß&T“åìbv4ŠLeõ3ÈÇózÞ^¶èY_ðä$Ë(-uFã,ö|M²±°õuñ´æ¢Öu³\5F·c²vÕvvœåË8æ´]ݸé\z«Õëz–í>¾§ºïIд¥6¹l™µ;¶8Ñ»bs/@QjÇO«MHª'Kˆ´î]‰ñr BÖ7ý* rÓ iË\#«cLIÓ¦Ä{ŽÃ+Û”¥`4m†GaÅîÚ&ÍŸ‡ªBi7VG“Û,A[Úd º¾Zqôt„¦ Û|±BC‹/¸Ë­¬ïmUtõfØ}%Œ»é0[U~ÞÚª}“Ïí[NJc‡L¦ Â^ç²)š{ZëÉ¿µ^B'£µ«½{O SœÍXäš³¬TÛ((zÄ'Ç¿¸÷Läd²—={sé//_‰…¯M\Ò°1×óMqÙ·Ûy9 d%OY\îî+o=:Òá°k4eöÎê¦JkJ¦Ài\ÒÚ»bmk½ßg ÆœväŸ*ÕÒ¿·7’¨Svu‹T»ä–ÌØÚÚ•%Kœ¨B^·¶°…ŠÖÚn?oíeeÚk=P;ÇŒãšßÑ—ºHF×ÕåtF‘ªè-ú;[Qëý×OØ´£Åµ˜?c*Æ÷%\²Y5rÊÞ>õ®§ëóµþMÇ­#¯¶uOc@Ü´v¡¾ºäN¨Š£jKŸgP7'ù_œ,J<š¾=à"[C›.Û£³m[ó§µÞÇOÔz„}8HeÄšŒ¾Ù¿o­m¡wžó¡Jܪ©ýÏl6¥khJš÷kÄm&:ÒµþÃolÑ ñÃŽš½új¢“„¶'~Ï7[ÖEæ¬ÞÎmq±Ñ©öì±ñ£™=]­ö• ñ#²iwîFrŽèÒ¨ÚA¼´3íû9lKL­#TÉò”*³ý»¬Óíõ–ù¾YhèRÕ»s’z.†õ¾ÝÚ÷¯ž*Ü4æéÛ6yªf»B.«¸lôèyÉ ã­3@Àþµ‹‹Û“E¹1µŽÊ™oÝ Mä½rlõ[•JóЉ¹#ʳ_ÉL6‚²ÑŠÕ»¶aãû9±ù0dÁ„b_ë>Z®5J<{-Ù¬GÜù„®˜˜ÜrùnÜTª”Ç!õO$&uDíº±X¯kE¶¹(ž³Õô-=Pþji-Q»!æø“ºõÐØàª4™*n Ò×o´eÉ—Ҝټs”´ržv9ív!±'ÙÕö”dÜU·v KÜ,:Bÿ­¸ÑKZŸDwnØ8Û·ÁÕšGSé8‰æ2ñúw{VÌÿ ‰xœ‡}×”ËÆÃ+þ!DY´íÚU£Œúë‚Ú/n¦ö°ªþ"¯b'Ò YG¼JµÄB‰€#OÊÙæ ñ¸.£±IÈn5 x]$‘…¹< E8jíõU¥{vÜÞð*OM„°ŒEiæ9vR0:X7¨…ýêÍÐw8)ë2¿â ÈÀƒ´‘‡ö‰¿pðæÇ±F>˜tW”¶|OÄ{”pŽýU<ÅÖ~¢xGbøG£äÑÀ,ý¢ ˆì¹÷S÷…^¿bØ$µÈ:“'Ô'Å ÁÃh4å]ÀÕŒ'QV@œŠ,ua@óYc éÖHmKá,ú´ˆ‚3¢œÄkk‹,Áé˜L+ XêDE\{7gBƒÂC¬³4,’§…tNÖ$ÆQW’ºÅ-È,§I%cÌà™`„Ã@‰5åó–ÅÀ3ÃCŽèÒ(í -\‡>ãp·p÷¿ ?Ù<Þa›ÏR‹Îø£Ëòÿ¦„bά$2œ”®/µE˜’NdâOiè[vlj‚ê8(c-ó4¯vâ¢êÆ%¡C‹LÚ¼1ðê’1¢ÆÔTƒ¨ƒâ¥t À¥ÄSŸ5jKAÇ– ÀËHvÄ<陕x±¥å…²±£ÞF€W`F¹––8×/þê~ð®cý×ýãRŽËØHö„ænFâÚÇ¡õ Žk—±{¯G–ßšÞŸa¬EÞU·ázßý·®‹r·Sœ·2tïj ¬å8зÏ,:e†:”»™hԺݕtž¶Ú/˾²³Ÿp´k>S€5%§J…Êh'6rØ x¼j¯áãÇ8Á^{«U‡’3Sƒ/jý"W¯û ±ËEËÛ~ûÛÏÙˆì£{˜rîvŸ`Ô0£Ëç{–­ïkYÜN²ž5êÔ:,\ hÙ¶ªZÙ¬÷2¸§ XâU‰Ðm£c—N *%ãV¥æ¸+ª&O†s4C»6³%FE·è^늶«± |R`Õ;kA¶A’1€$0C‰ûL£¾r­:'V©YÕ£L˜lÁœÅXeÔýá\Çû¯ûÇ¢ÄÞ!/€È dü˧8Hò×&=F•?¦Û¸ ­ÆC´iÒÜ™Åc<¦¡ÔŒód`ú®–âêCš‘*{Táéú…µæWâ<7‡eщìpÔßÿ“|¶¡ÅaánÆÐ‚èŒ Sª0Šk|ú l£¨¸H×B <:‰‚—˜³w&€A!Ñ£PS°jÒHé4¶9èVÈ>Jß{á=~·MHý©,` n[‘hLšàͺ“rý¬ÎÈзiu1ùâNuœ(8.ÚlŽñ˜=G#¼Ró<¸‹Æ¥û'ß·Úþ¨Q$ìÓ5Æ‹5hUm|6ˆ¹0%Î*Úg~um'ùnd6¶Ð Å ¶µ·‰xð“ºh_¶…L%Á+î¸÷´'tÕÐK]¸®cÀ c : ·`0¦¿æ2“0#J±Õ¤Da?]rÿî§ï æ?ÝÞ= q«&*A2½›¨Ýr· Óâ|°þŒ$™Cm¼¾bÚÚ„ ¾m±{V¦ºöýâÚŸaÓ#8£äG“mVݸºTfÈ3hëèêWÄÚå þ¥ãü4ôñ¶åuåÿU_2rº  ©>«ˆ>Ä Z½pÿ3É‚t²“§‹0F`²˜˜‰ÛO“'_\ÝÒc+­ p*¨8ŒãKgžFò O‰4˜hÚÈcò”·-°ea ŒA_³,LG•åLXŸõ?þ‡½™Ø:Ѐ-€NzŠíÐâ+´SYå!‹“”a\|µË'}»š‡å¸ïWÿ'8³ðÞSi¿7H­\ŦU90âCØë+ëè[V†§rÉÀU¿é¼¹Õo—D™xÿûàN¡×Mfð†ChœârÛE­Q°tlmÜ™}‡1°Ñ翦 ›a¸™†–¯h‚F¡Ä»jåë×B2¬"´A†²O !Ìç#Œ·-ÌåÌ:æPüK³´dî -ÛLXH#"Ïè?²nG–nƒ°÷À>È÷¾#†CÔÌØ`¥ŽÚýd¡Ýu0üé?»Bý¡­WöϘ£~)ê\Fuåß- ¹wÐt3:U PŽןÌêBŽ*Ø´ yAm]näNÒfƒ°Ð¦[ Ñq1&Æ2¢üˆ¹¶IàöXäõ·á4QÁ p î#a«|¿2ПnaÂÌ Ý`p{Ú@KLØ,êi8Ó]å‹Ü´#YQäÚÚݲ˜88{ц*PpÎýSFçô×76›MòýÝ—ZãÕA²\Cž*Êi®û ÇØ\ và½u6SUͮرïØ:–ùéê?"ß(§›ï7‡Ð¸þ/.ÙrŒ6aÞ:Žúàr÷ùˆ?IþËcÂ~Òa´ŠêÊ7…Ôê¶ßu†ÆWDù7GÿIH>Ófû„‹k%®¸ T ·„NÖ>Š›u+ .–¶‡[†­YŽúǸlr`ê ÷–‡x—=‹ô˜¯Ó¶ øŸˆú<#ÑPXÆì‡ taQ¨ÆãˆôýKzOÄœ'Ñá>ª7-1qâysï(i¸ÃJéc‡v9eE4è y`ƒ&ñlðÌíš-a¼Û`I`ž­Ý[Æ=ÔôÚ^û¶ÆÎ·A–Ö\)T»B‚ I€§5GhÛJü½ZOàšN ®r†F'ª›˜¸¦áÔJ«b¨'Ò2ÔÓØ+HXQÄžÞ‰Ž’Ì`fÚ¹Ì}‰îØ;„ [@Æ££¯JËá^f¤t&5#Žâ¸2ž¢´D“š*êU†Â>ƒÐUkmâF­·jŸhƒ×_ÏYClÛ0-1Ó]‰Mq™VêÆ)¼ðC“&sÇoÏ„”F{bÈâQ³lÙ9TYØ÷’h3CÞßš§föëÙ²¤™'åêS‹[/zÿñoQÛEXFm¥åí ƒ¯Æg9åèÙЦÀ&à2#ÿMôy›ü*ÐÆÐÈ1ñ C5œ€ŽÚì¨U" Ñ‡-ý·pDnèºÀÁa ~žÔ+ʼ¢å½Ç5û­šû:¨¿(ÚÆÔ8\Ù8ë_EFÚ“üfý€}Ñö¼{¿g­Gë(üê6}á³xà=ïÓOñíþŠÓi@ÞvžÓ·ÙAºKF=µDï,ƒâbÇðˆ¶=Ù 5›\«’©«Q[`4ŠðÇâ®1¨ø¼YûÑ„ï§pT°>`]miÿH{IW·Ž)3"¼à…A&%ˆ±Œ$ŸTtì%l)Å’ÌAî©9ž€DƒFýô ÖÈÒÙ1m£Ž8åRs4˜(9NÚ+ Æî•VÃTGa¢“1ÒÍ iÙ¿³¢Fb2¨5±ŸºvéÝ¿¿ävaÓÙîê©4O@=}Ÿ±þ"O²:t]F·Š•¹*šP]•äi*}sýóVÞ\êÕƒÀ`gÃFõaþò˜êÖãm5“”ꚺÀÇ ê´Îfûh¹pP‘~Žªtb4x«¦sl;0¤*Ê!@ÄÔt¨ê­½Õ×YVU•eYVTpè½×¤úTtX‰Ç³mfÝÖ@ʬ©p M¨L)S'NÒP¾žRçþ½?‘ŠýT ˜Äc»û¨9ÔQQ©µ—P0q¸zªÛµ{M;È*ª5¶þÅWy:1¥$ì³ öWuøíð’¿@¡ªbqŒãluÓ]°°JH-sUÁsTy~X5ÇTE}[H<@p·v¡íç¡ئ–7|ËŽ jˆBvtéÛféü·ñ)èd·aTF‰viÀã€Ê£wÏ KÃßýáƒzúZT4 &€6‚IÌQÄHÙ8Ö¹¤çL¤):gžt­ ÊM2˜s'!B`ƒ‘™Ø¾ÞŒ1è'péŒ@'£ÓÐj*Åð6²žð{¢æ‹…J´F´²a:Úãíˆ*}´Zãbq$ÌõÎÚ6ÚëmK2 ,ÒЂ5= Á J¬uô?*r¾„¾¼Iì#¿¡lÚ“¦HŒ"s3õÖ¢Áˆ 0î¡+ŽÙê›–m¼K÷¶Ä=c¥µ˜E®Ä‚3§yÀˆª@á\ éõmHï«#àÏÕWÀc Äú¨Ú€êGF'3EODïè&¶¸TŠ$ô¼ô\ŒÒ~øKth¼ÉÔªU<Æ2UYáB²QÂfjåÅÒº›Á*YdI'D 8 ám\ÒVC nÈ— „™ Â¨‰¦PšpA£ËàÌpÀ;ñlOBÜC ¤Ú Š^fß‚ðÔ:¾¿…¦…À&3ÁÀŽúb.êe@tAˆVm¬'h00F"¼Ñã1ÿpê;w“¥ZIÄŸ’.¾[>¿«ÓÓmé`TüÍ Áépèdo a}Tö4b§¸Ò¸ÁGxÚ7µi-Ë™m+lAˆUDÀ*™‚x±¤¼¢J01ÙóÏft¬ÊHŒÉ&L’Äí=ÃÓÑåØBÇnà7±8(ë&ôß8\ºÄ²éþ¼cl9ñ†@T[wž-)- l˜Ä‰£|1ÐÓ‰]:Ÿ8U™Óö².[0GÎñZ­`ûSojï±ûwF¾¿ª V=Ì•;=èßaÑNÁCgoI;úW˜QÃtc÷×ZÁôü€¨ c“Ø+Wõ†Ùe7ßo ±énªòmjÏúi€=n|NzÛÑA”Á‚6¶¿™_â®W¯eÀ>Û¹ºØ»º›-dÄs5®Ù,5#Nž!ÆWÙ¶ƒ)‚2"£™ükŸâ\hƒSeƒŽ¬ûÔãPDtÀYiUIÅ·üþ}}S³¢|Gè´¨N™Áwa²rì¨ð¿Ä>‘·Û×_¨%~!—~îˆ52OAÞ~CÛQƼK÷—gâ½ã¤_æ˜X²r,8Ÿý´ñ7n ×FßôôòÀÜ8ÞoÅ’¤ôÕ²m»yŠÌ÷µpÚ+80˵:¸jzðÏ ^´qƒ“š°Ú 3Ëx=å÷­6ã½OºÛr8ôq¹Õ‚‡&|°|D dÆÚ7èÖNiAÄïðÉÛê ¯€D Š‘¨ pÞÙ¤GT!˜üõTéX‰¨;r¬z<»}çbŠT$*å'iÞh‹üjàâ%‘÷ É eí ‚`o2}5üªñn̓¿:ú·˜Ø=¿%žÀ eøË-Ÿ{Q9cÄ bA•ó~ðÿ1Çé©ÿ×lçÔÏÜ(ݼåØí&è:†®‰BÍA[Ý}ôŸt÷cüË0WŽ'S2™uóN—pE1á]:¦AÏ ]²`äFjÃj°Úý+W+Ãpx­ûmŸyz¼C …1¨Aë©Þè‚ÚbÁWÜd†þ±D²€Ì.9ƒà±‘«:$3 c;g¯èŒª×ß_héV8cP:8xSk}[Í Z•{N'¬üû(…"sS˜‘ˆê¨U‚@ÕŒÉöz o4N[ëù‹W °`õõQv”fWgucPq*qùO`àsS¹†Gè=DÓ[¸!”Fâ: ¤‘,Y º›Bª[üOpÎpëò‹«°ÏI§áœ‰c ›*ÊóCZ£ $’4uD/‹‹ÂÔ÷t%·PXÛ Y¢dµÂIqɘ`žÊH#Fv·sŸÂëÉVQÅ£%kƒ&Ôf21kH¸ŸãéŽþ¬I œ»*×ß_hù:m)cÕA¹“?deÞv÷zhµ°ÁWpŸª‹1’s&›—c„Jý#é¢÷`ÚM·'Ô7 n]Ž#ì9Žï®…•ÀÜÌý‘³¿£ k¯åÿ=`q(ãjŒ›µvýœvtjBTâ$ÀàFƼÄPŽ„**ÁffˆB¸Bá"p%š!©­j W2&'lNppœŽc 6® ²dº€?TÄ*¹>ìäF+‰ÒY0¼Û‚Üô€"VÛÄéeOyxT@|e¨Û¸!‡Ï1c øZA©ÏÙ;XðŽÚ>Xú¨ÀÀ0®Ù“öIÐbj9‹Jçý#éÂïo©†¡éX>ªà½m»Êþðm¸H §om`¤÷á´Þˆö×”fOª¦ë>…úýu ¨î|’†ãPîa‚ì´Öïâ¬V'šv8uŠ:WÌ×?Ft%]O Ö»¦[Ô;:S 2#1Su‹³Xœ~TóìÑsùìû§Ýü½ zц±µOQÈõV…n0Ag*Yõ¶³ Þí„ca¸R¤€qÈö†TÀ¸4±‹Lñ;'#¼a•^Õ*„$ƒ¥r!žfçä)ysüG‡¹Õð'៴iÕ|E‡¢÷× ÉëV’¸°ç*´“ÄæÃ-⪋H*­ Äéȉέýáí¥v0¡>_¥nFö?@¢¬º]q‰ÀŽª»l±…$De6ô¨3’iMÁÀq2`€Ë¥ÓOn*ižé‘ “¤ð±À-½tYŒ´ÑN[µ¶Íõ¨™'jzg£ص»€2°‚DV¤–°Ç…¾ð·^ãï¹Ùuî’@n£‰Ìmʼۀkô¬–:îάÚáÛYâêèóœ~˜=EóQÝâ=€m n¬HÁ¶ú~¹«T£@ëúª[+]£0¯«Ù@Lé$‰Æ óë§S$¼ ' ¦jßÞÚò×2‚;€4ÎG„G`š•}r§3髉xË.Ýù}~®º– ³n¨Èv;úªn´Ã¨ì1€7÷}9V¢OU@ý‹[º¡•„r#çýÔoY—±é)÷¾ÎæôãÒ¶í‰f ¼œªß,¸éÅŽö9žó€ê´4vPe$FÊ€0œk†Tõ¡¾º,1ŒIE¡1žÏm#2àÆþÚE7…#»²µØÄŸŒ_nú‘³‘ÝöO_¶™¬¶’ÌdÆ8Ej¸ÅŽòf“”»ú†4´8b'*ÕË· Å”c˜;^Éïì"ì‡Î~{hx×úûó히# ÿgH4oòÛ{?ïºpÜvQG0Àƒ¢=p`%S·Þnïë'uc™ÄýTí¤4â7‚2ºwP 3êÛïÃu{6׃NÄ•vüöSÙSœ{$}5ƒŠùï¯áHú«ÊÐLç'áDZxf¿µú—»NŒªÚïeöеË[:˜i&=Ø÷Ѽ2mê˜#×"ƒŸ Á»7÷gA…uôFÊÃöÄÜX¸ 0n N2:ˆ=QVÐ.•¶ŒñÝ0'y;Lµ¥ˆƒ:NSwGë©Vƒ³¶#<û«tã¶wG__ª¼«jM±â#ãóúh]…Q‰öMNñ]ÿM-¶0 šÐƒbH%¤Ç‡ Ù\DèbLiq 01ƃY^( a–Lê[P2W4®&1œ'P‹ê \m¢'£>Ú6m) s'3Õ='£ÈsÄ™u®ÏF^Žœ3þÁ¦%}tE³¥Œê#we e@îËÒ$Ÿ@ DÆ;8Ç¢¥H=íã;:úª`m& n®ÿ¦mI3Ѧږ=T«¤Ë}e`î2"*\Œ@ß+¨„ä8£Nf'É˪›‹+ñ GÖ;ëŒ?o'åï öU¿º¾ÁÐU€ ç×ÛZD¨Ç#9áïMj·‹“Khˆ Ⱥhkñ±,Óœý‚BòöüW3û)ï uÖ®_„î>õ(à« ‡çA¬?k;zqèž#v O¢¤[Ð7¹ÓêŽT_™æU@ÎGt±ú(óã½° ™Œx)˜¥Á !µ«i&$1Ù^@T†Ñ:ŸN¨3'® ×Wñýàkôï«õ:Ç­OÑ_­`‘¾ÙÖ=7ª¡Nãƒ~SAv0“MÌ8†¹øPxGÒzè:œšÓpc°íŸUi|AɆGê=_µŸ–-ZRÌr粃sme~–ú½5«‘´ ‡Ò%·œÆ9õáJ-Ü:’èˆð²\]VµšÏ =µxè*oCÁ1¦âÜ&:¸#¦µuŠÈa¼Àu ÝŠƒÈÂýÐ[ËòÖ‰œå‰Ò6Šþh[Yc#Ý ÏXÝdS² !|°–ÌT á3NÀª÷•Ip 3áÏ*¹jö’-ŒÖu1<9#Hß$R›¡d’¨ +œ0;0ÈѵÁt.hçˆNPþÍC¾—–e)N­1’àœI(â­,ÖòlÉ' :£#¤}Q$Iœ6€ßg¯††F2+Pä~ƒ×í¯ŸÏººÿc'§šêé[ÖüJg·xì# [Öü,'³xí 7›"ÃfBu«g#^W. Æ4Ú]d$`#¬×éØ[c}ÇÇò¤ûkšUû–ǵÉöW9w¸ ÿ¶¸y˽áýµÁÌ«}ûqëB=•úœºÜí¶?•ôŸ]7††lÖà(Çv&&P{+]¨Ô*êâUÆK Én²qyV! b kÎ|dÜ)M Œ¶DQOœAÄ0Æ5#g´a¾¿T›–~8â_÷Ùö‡} ƒMrØÂ1\qÝ’q`3ÈPK¬rj @ݰo¢Ž%Mh8ƒá;ÇÖ6ôOì±ùüöô|þsчKÙåíyŠq’a¶êmÄcÕÏÜ7~ÂÊZÉûX÷PKJFÀ®îª4L cA×"‡/‘¢ê‡S±€#×Z¹ †ßþ·—´{=äü'º¿ú¬‹<Ã` ‚¯³ò3¸Ãl¢yppÄ€aÚ?†ö"œNÜ3¡ÊÞ’À\Ä1AÆcáÌO¦$Q½Ë V³kcÝÞÖþ•ôPt2Fõ1’DiÇb.d ‚£H™`pcöѼ庶î;Žú(ã‰L¯°ì¬~_—dDÁ†öÛdeÛ5t¿ÂsþþÑêù1²§ _æå-ì\™û~ÿê¡nÒ…QƒrÙa‚Ba›Ã¨Ì(' «7Ù¼›AšÕÔzn qŠV «oeu\K¶ßd¶8ž¢jê#ë³d=ÁŒé¹pi(~ì3²ioÙYkj.[Ìvð1SáÓêÈaW2Z˜WÄÈL»˜1ëD€)®ÌËÄãK2ùbÐâ·vÑÃIÌ4I4³ÀÅ­î«]G N鞃jò‡C˜?<úó­CUÞXwÜ´=®ƒó/X¯1`«Ã6˜ýP2 woìƒMç¡·i mb®}É8¶‹„¤Qæ¬Òln(÷ö(ýñß@ƒ úé^Ø,&B†2œ‘;3Ê(1IØvWž¾$Ï­º¦Úé·µÛîÚdzÓN,Ë_^ ÇÞŒÔ €#-³ü—½´_¼rúè’dš`Eæ%×¼;~/Që­v˜óÏhïù+ÍókŽh‡fæa¿pÙ™Ç*à’Ä*ï9Ég%ç {ê·ÝÉ·rÐ0Ö^ËI‚"Ha#Oo˜qqYUpIeIi&DéQM1E±“3”箿Zâ'Þ`=¦Œ^N½ ŸÝ£ÏQÛ+í¦ÍźÀû ::‚Ca˜; Î…žU £÷5±†[PƬX‰Æc²¿•5wYømÚ÷m+™–÷²€:ŒÒ]\5¨h9€FÞ†æye›'–Ç»¾å±ûË·1C˜åáU´dTꎻ¯…_˜c©p•:Âà1³‹ Çðn°Ù”ì9¯££ÉåÔݹ´ —ï¶Kíê¡saq¶ ÂÒ÷fç­°ê¨ÐÅD%Þ%êŸî>¢>BrË’ Gï6^íùå¦*Ãhùâ:æD}¡áï¯tŽ¡@¡rëì9îÎ_mO>óxý•Ù½»:/0P¶m’¡‰Å™£ë¨P`Іް MÎ]'z ù“IõÔòËGúw¿Q;ˆ¸¿â¡cž¶y{‡“6ßî\?…¡©¼ËJÚ›Y‘2ÑWuqôèuù€“u”+Ë„ˆ‚aF:cdÒ§4¾EÖ0ˆâœ´{qÜØtk\9k­ˆÙjáÛÔŽ+u- K&$d{FÊ6o©ü*¢\¶Âª1vå×^õ6­¨©‹¶Î"<2}ÕǬQåmÚWˆ ž# émkâWÛ 26áZÃ* âvÄ ÞÞbpQ¼Éžãnï*‹ £,ÇA¸£¨}ßxz1îé,rÓÞ>óݳÕKnbNpLw 'ºµêVI‰R;ˆÁíMipAƒÑ6› ªqSÝ¿¬Aë¥<ÓVõbqϤûØo7šCÊ•6€täÙÕßE·n%»¦^Ú‘¡ÉÏd®¯z4YˆDAØæó­r‡Âž—‡Äç4¶v(âaœ ­(D\•DÜ>[Z¼Ñ³R$žüÅy–õ^äÆ`ñ]°7ƒËCo¼ƒx èC)İŠ~k˜:È ÚÄ-cŒ±9ç«oCŽhh‚Qéݶr£ÊØp¿óXmnHFT1ŒfÍ…@KŸ±ÔíÚß@MiÄ«a«ÏeÕYH´W]ÛÑ’øÜ–V8FÚ†Y 2aß.ú Òa’Êk O„¶ iFf%Ìq—AVİàjå†ÍFG¼cÑpŒØi‹dô3%§¹#L¤†Yƒƒè¦h`ÏÄC “³g¶…Ñ:Ï„²NŽ!Œã0¨ YW,_¶€HÝ8ô1'*NUr´1ë¸|gþÑÙA¬\%v©Ê7Öz¢…»çÉ»×á?W¬uÔƒ†ýžšÕÑÿÉlþšì¼ëþk ¶Ôàƒ&#žyí´ì uÆ£m¿NvÄ2oY¯0N@bI1´žƒ}²²¥ÿH?1IÄššH9†›úk]?ËGÚ @n,8dG‹¥·lU2`\åy~^ï0Ö¿ˆP`ž£–Ü„á4—´2kéa ³±†8ôó<Ï,|ÏåÃjW‰:dXšµÍ”Ñæ ‰˜ÄŒðÝÓc–ò]üéãQÁn>/˜Ãji¬ÝPÈà†h4ßÓ¹‹¤Û´‘—™løÎm𑔊€ t9Uc-h”?‡Â{Ö: °DÃG—–aÄŠZæ¦Vû@m~‰8Ntׯ6”\ϰu“²¯^‚ ´,XˆÉY*“"÷ôZ½µ;˜}j:>²OÕЋ¦â”Äiy]QâÐÀ=T†¨2Aœ{vÑTàH*· *kâ•„Cálóéc¶íÈü6Äþózº Kº‘#]·MCˆÁÒ};©D.J7(Á}T·Ø~¥ó'î­§Ð:9®wúoõ³|crÓAÃ"s$ì†ÒĉZþý}åVB_PN’ŒH¦cy«\×õSqÔóÂù|Di´¬@8IÏ~‘Vy!Ì^{|Õ†7 ?¢YOºeepá¯êlo7›oÎUBþ%ÐF¦LÙ³âÙ_Ò¹ûWîk»p!RߦQá º&fff¹õºH6X‹ýÀ´¢t¸CüIÀžÞ±\•Îbàp-rÚß[Mp‰ýU`aøtœ5c8bkú)åÚà¶ÞbìY˜©ƒ¬äøå†X@Ê­·>ïy®^*·mß „“§KÚéS³‡t#¢×<£M¡¿Û¹—åxüÇä^³±Ô8íS¤úˆé-~â .¾&ã$øBa-:½W.\]JŠXŒçH˜Æ”=»(×БåH"!´¸Èáˆ` Ž‹ßfÐÃèè»ÕÔ>A¶åYHÚªNP12GgO-oìüì~€)V ’0“Ž@m¡ÀÁÉÍ“FpÜsðÕ«YêaV¹uÊÚ*ú>¾:ï-mœâIä x5ü&–‡/q@fc frˆ vE'%rØ{Ha#‡#ö÷ÒóÚ›¨4«G®àwbiïù æ8!š1`Ø4ìâï«v”)hÊ,`‡zî4.s6ã¬$úvŽ£4¿ÌXGÐ!er„FYU¦P8[ÀpOú¿˜µËÛ[“:‚‰xØXùsïÛ`;bWü@R¶ð:$Uƒñj_JÏ´t­Ë*Zæ’Z6äÎÆ{ŽÓLL©‘¿ ¾ŠÒÖs§K-’u%f#$8jž.‹ë¾Û{EãŸîá>ƒ^è5á>ƒ^è5á>ƒ^ô´»­[öM(VØ9|[2έ#!P"_Ì8Ä‚vFí•Ê!ÈÜÐ>š=7nÿMKÕ·Ó¥ÏêñdaŽ´ "..)¼€@q\±ŒÀÇ ê©þbÜjÑâ1šýẘò×R朒 vÓÚ³~ÛÝUc¤0&TÎ#§±Î*))­ ‚:_2rú P"YÙô4L¨ ˜Ä®êæMð£Ê¼Qt‚8Fù'˜¦O…ÜzŠV¸Z#z¶ rŒ;+–m×W×"³šÌzk˜·mRâsYôùr¡+Ž #PÓt¨X œàDÔ5Çdø Æ)èœGQ1YH«‚F(ÛFãÑuë €€¯ã¿¦¿Žþšþ;úkøïé5üwüÆ¿Žÿ˜Õ·c%­!øcë¥ÙF’ gŽsýóVÞnZ°¹œprŒÔ_hùyS˜±Ïùœ:APØø˜O #Ç2F5ËXA7M¿&ôdX§ w7î­Jå] ¼îãsIm]@p÷Wõ^_‘·å‡åÀ@£J: ²OÃi¥åW“{|ÚYpÎmûÚN©|øöHÜyN{–F­½ÛdAբ쌳Ãëjþ›d)‹|¹ `Ƴæ“—ˆû+šµ—¼Åﳉ"2ÚE+€8爜zú; ™Üú\ÒéÕ§Óœìî¥×âŒ{jŧ­qAÆ3_ñÓÑýõÿ=ß_ñÓÑýõÿ=ÿ=ÿ=ì9t¬rÜEÞ¸>:Dâ6о— †ª¸šqpÛ*_O,ûíéüŒE('H‘Žìsî¡pë ¨¨ÖÚ˨8Ü:²«7F\}Unúäê­ù€?!osõ„`âÌ ”Fs‘Ìá´ü‰èϦ÷0ËFo@1ë¥Sœ Áup˜âˆmñ¶† Aý¸W.»‹7åSôž—ºZ©0bAÒ{Dá9tq6Ll]!@ÄêZçìÙEöÝm½‡ 7ăÕ"†¬¶öQ¹i`•Â_SëÕ4ÍqÕ@]``Þ¼»ëÍR ’°Këvu_wAêÒ7Ú¸Gá¸'÷”ô5»vD`øø—afœ8 ¨‰ÄŸEZËÙà=™¯Ò;ºySjóÙ v”tÀœ³Œâ®Ý·ýJï6-Úfde`ˆ:†£°vÕ¡¢ê¥Ó¤9X@ÓIœzôÌM7(RåÇA.m®¡l}¬g °0í®[™µvõ”<ÀA  LFÆâ´õ©«öM«®öJ‚ÚÓ0}¨«=ÃÌÓDY¸ûøviÈÉÏ}?–¬létq¥ÐõŒséNMOöþÚC7¤é^‚饎 p<` ˜ï Hйse´ øœÏ±z 8 ª–.¸%%5?ê/ŒÒYxvçÐÏ¥•†·ÀÀmš`2‚_Vg$éè¾w€¿˜Ñfïjý#éè}/4F¤´r5}Ðh³Ls$Ì÷×”¨5b€’ª 2иjgˆ0H¿¢ç,ÍBß^$õˆïèK6¤é’#Ÿݵ¬°b »¨Jã¶z°¡fóE‹ü-¸u÷gØú‘—G-ü¢+µ«šÈb€Lă¶®ÛæyN^Ê=§]Và6¢§HÁŽç\Ÿ$y¶¯ka¨@YsžGÄ2®v÷$ü»¥øgó+Y0L°JâHdF×+ä(%y³pÉ À0$LmØ+ú»•Í-â8¤6ˆg\‹w–VWµ¯F¥ffḧŽÿ¨Ý½vÀ³ré ték,HÕ$â3Af0$€fjç5þ_‚ØÿÖ»{\ËvE8aß'm¯4¶¬#ã;ÍI¯5¼W˜¿áÉ?Â'¿¡î@O†Xé¾Î2ÝUiÙP\W´4ŒIB †+÷NqE¬*±ƒ%˜&œ0n,; ´ïwQ(ʳY™¤øDáÕЖ¶»ú”í#¡ã4†ôgê'£H•¿ˆW[‚ Ï c3NâSxd'2£¼(Û}$Ha©™T0Âxx™ À˜Ò£tpìÂï8ž…t0ÊA¢…û~ ÃPê>ú÷5 €Lf> p#¼SwS"¤x±ˆVy„àê ¦ÄRÿMæØ öÄ!>òü=¿W`OÈ7ïòáœæe†®Ý$KjÒ…Eù-ý3–nó˜úÞ}ýÇ}aXf6ÆýÇê «¤å“;†R \ú=f‚¨€Á€èµa¯yÝX—áĬBÀ¨Ì±ßMt*’Y—Z¨_5T®@cQÎ’ÃÚw¶æYjÓ§’qŒ"ì¥F®#*ã½FX׿¡,Œ­§­Ìûè(Ù0 ÷ÓZlÔ‘è Ø;qãh¤T’Rx´„rUEȼq¤º• Ò³Ò#2IÆI$ÿÓ£E¥,}C¬œ€í£Èù¡î’YcÀ­ mºÇV™¨4¶ï¼YRZ6ÌjŒHžÚ7à 0JéÔù¬Οµ¥½eŠº™RòŸÔX[æ€ÇÂÿxì?k#ïAÄü¹8MÊÿMl2{Ã!½mo?o!îÉÆ´®_?]pCAâÇ!×»¬ì¡sHÈ쟞ݕ&šýËe•†G‰s ´6gnæXpëÕ³¨ŒÁíèÓqC Ä=‹´* “¸óÊ­‚¯eâW^‚u22‰IVŒ„ôIÊ®ßø˜‘Ù’ú£¤_\ýåúÄ|€ª$œ€ÌÖ®q¸¿Ó_â9 ÿUyH»_åøŽl{}0FUüÒxÇñW¯eÁÔÞöæè[`ìBjl@L€¹}ã™­v‰a¬©JC¤c+»vÚ ¦ÈŠ[ÇëØc°æ;°û4"ð´ÿ ÿå—æÓZ­0q½HaêžwQw± =tW—žaþÆ ßq¸.ªÓÌ0K_餅ümâ~þª€¢ºD‰30 õuлŒÜFGÛÖz<¥Èxý¿]pœ«Í²ÅxÛ÷†L: |èÐ~1à?xfž±ÙAr;é­]‘³ô¡wÌw ¥T9Õ£Q¡³3c1¿¡àñ\à‹Ä{–~C ñ%í;Æ"íö­ì'Äßqsnܺè§&¾X9¹Æãwûƒ©}4„£6µb×g†Ùa¶£&p¨"@¹o1°äAÍHÚ 3ËÞ]¶Îã½~î8ô~£F\^ZŸ1¶Õo/Ì'@Œ  âwˆÓ¨íõPWŒ@" ‚DR056/º÷ÒZþmô³x›"{hk毙üÆÈ­O.w±,ÄMq+\È;±¦F2Jn=DXôÐ0d ôïǯ8ÈtyV¼[NÅ]L½õLj3Ž`ýQP6W–;þªÛj·µîÚ§³¼ ‹ŸÚrooWO’§‚έïz0^ãòY­-?baS⓳@ë¯Ðmχû‰·ï7¢‹ÝbÌvž‰¸%} 6ÆÑ 6ÇÛç Þè8³Ä5™:Yý5Ǧg ƒÑ®Ùƒ‘m 6Š/Êàþõ­£®ßĽ^!ÐB˜ õ݆®=Ѥ¶˜€`*û‚ éÅe˜\¸a¿†…c#Ù×Vtȧn®¹Ù¸ ¢q«_}}¢—°{:⮢ Ô~£G_ -ªέÇë «èÓg-­ÿŽþÚÒH¹ž³P;E` í®#ZÔçè©ÌuP$8’7®…¾bnÛëú‡ÂÚñ9û#gkd(èR¨ËÑZí™?dãôTs•ŽÿúGÒ+‚ã'S CÒ°}UÁvÛw•öжÇIÁ×mŽCa®cÝÚáP½¦}•úŒ[«!è€\vÜý{(«â åóŠÀHê­6³ Û;vú)|a°üòè[vD¹ÊŠ]$:íÐA¡K ÍÄ=xúè]Qa†ãõm.°ÿÏ¿}jhd&aƒêëùQ^u¡úL!ÝÙ»ÑÐ.!‚=ch=GmiˆYˆ,Ú›V }ÛJ2lb¡'Ç#Øi•p4“·Lã§nü¨Y·oHR4ɘQ9À´ËâA4,{ï ÿö¯áž³Wn·»Ü=5Ço£®–å±+pë9ú¶“‹˜=G ·Ñi9¶24Ÿx{hEp¯¦ˆˆ"™IÊ~µCVGØDeØúòÈÔš‹xÿU'•Ž ¬HÄŸžç¨â·û§?F~ší‚Ìrµ67[3»ì¤í¥æm‰)ƒGÿðŸQ ˆ 1È ê/°RÆX“€''çLáZPþš`½gkwìêíùeJ°‚ j\m1Àîû-׸ííè WP&íêœÆÜ«Ìp5 P²[‰ÀŒà¨ãÑæ¸à·k{£é4ÊH,¸ñ ¼jR³×*f‚¨’r¤·lãlf>"e£³*ÌDã‰óë§S'TbNã4Ÿx{kHÎ-¼‹=&* j;É?D 6ÓÂÊucoÕ‰ŠÕ\Gê¦tBUD“³çë­6›‡á8îî4öî[‚£ÅH8m˳¦{6“™ÇÐ'!Ô(Ù³>i˜ Ù9"tÎD’Û?î Ì9÷àé$MTU'2“^]±6„‚À‰S1V†Õ‚ ²µC—0bì®îÖÛ¸vþÄÛ¸)ÀƒFí©k[ö¯SuuúzB –cuš×Çís™îúy‹ xO¶¶¤Díú7˜@1 >¾ø©Y^ÌG®‹#†‘E±1HÅpÆþÚÛ:è=³Å?3ÛPp¸¹¤u{+‡=dÖ&M•áôN&­Ü¸5Z&{¿»×@Ú‚„aQ³¯E²5 ämQ²WÙ–ÒB07³{IövW“euÈ2>%¬©Ä Â@3Ö¿ ŒTn$xˆ’5h–0ÓNˆA¸¼V˜>˰…889‚6Ñ[po>;Lu™ÇH÷Wûè»$É=²ƒ•¼˜íOüñôn¢¬#0sy·,…í÷›»/M<+€úO}[·æŽ=ÒâÓ¾0ÄQea„aÖÙ C$à$ÑV“Û_¦äwáèÊ…§†Vñ‚i‘º¯4¯8úEcm½#¢|Ñè?]y¥ËŒ cé o b2Ì{+ôíªö }9ÕÆ½”¶Á“‡²…™à}›Œ`~ƒAíÙÔ½£5ìa…Zç9f‚‘ Ѩa2‘ôV³ tŽ&ˆ,{ç3RAbHFdœ‡·†¼?¢Ë ÛA áŸf1‡\Èí‰x:8yÌ/¬úé®Ý:™³?=›¿juˆxÁ†¿xí¤å­,V c ·³·n&ƒ ij!IâöˆÂsèX ÆÉa•uN;0Õ¨>¹Å` >õe„dÜ&”¢“æ b7l^ͦ™`é*Aïþüjà qD•Yº¤ºÝ&q\ H\'ÅŒm® #‰:ÈÌœHÌáEo7 ‰ÇןeIþÄHõú² ->¥X€0ÈÈp8çŽ4UÓFY0’HÆ|Dã=öÊ‘8 â@Úg*I˜Ãi Ž^è-i¥mR 038j08R¾ dá 7~ vSÀÁŽØÂ¸u‘HŽx‚ÌHÓ2<;©-? #1ÇH;ÆD©#…~£„X&2{x”Á¡vÊ—` d«”I1¨˜ß5´.åÃ×cШìJ €':¿³AÄW±=X{+„°ïÚ( ½Â6iÑ_Ÿô@²?7÷W µäýUUì\×Ö=ñ슟ÿ'ÿÚ?þ‰ð<…Ê”·f»1‹2òϹt—À[¬„/Ê%_Ù½vð·ÊÞo’ÄqTcåYËÑpš¢O'@f«Óœ>‘‘W[Îä..ᘆ½#c”“ò›üM£ñ#)mæŒm®ìëæë—ïÿ}†]f+·ñD ¸Bâ'þ³_÷ŽÇs#/Þ9}är»×ÚB3›þmr­ýgDº,:ò¦ÖE…¤—˜•βè“ór$Ý®±_Ì8i›CgƦݻ[>dY²æ[7 ŽôpçÇdTß’„JF"‰ºî‰©!3›ðÓP«¡Y¿9y"dí „©Qcȇ}-…3(„B¨½¤*¤¤„#ÈópßœiÄ ñªÖi2êÚ6I[ R½«B!KxRUàn3ÂeÚ}<{#F¿n†ƒäºúì·t0Œˆ »Ä?/´Ï¢þÀ’}îy6S¯ ¢zdé. L²Ø&än8j‚"‰ÕUWdÔÜs売ù„¼†áG›•Âtjð¸¢ì_Éiå÷ìˆ*§MÑt¯ó×:Í©¥½ÎqO«ØíRø³*äÔ­%ЧBØÙòÒ·Ç|}KоçùͬXÂvªø“óÞõ$ºKâªn.”•UU|UuÑzn»{4¨(ª¨›ª"oÓQ°G%dó)]ÈbÀV´ëØ’ÜGGvìÜ]tG~í—}¶×4Šx–‘¢~šÉã><ä.Cr,JÚ,MËxTÛ´ .Œ!É\p n5ëÇD4MÄÇtßeßS¥Eù„Æñ ÏUHqæF­…jãXC[ƒ%¨À‚ëvo©"–èj„;uB›9—Èj.Å­÷RÙ¨LÎ ÈÍ;\uöA)ˆu‰x\BlÉ|wqÇfö%IˆX3S2¶ »“G܈ݻ ’¢Èe–Æ;€ }Ä] 0|9ã¿Ë“.·~¹§ï“MdÜ:ʸg"{±ÙjS(’füY !#m6êv‰ú‰„Só·TÅÉóƣɩů+ÿ65±ºTd· ´ãQ^°Žß{ n´éýÝãÜ|®óõ¾7HH%Ê,× |Á–÷Vl0/ ãIéû:j»æŸŠæqœd$kýnbäîC…º]¾CÍ6“k»•vD’Ïjy¹¨'}_“cö£Õ·urZ—ö×À›y’ $ûýÇ3‹ø›—Î\×v—ƒÐ¼ÛPi»¾ë¹³›Ç¯ëIIÕòoª.£rgÌV]+5–Ókå|¼Å*q\fÖ®B²üé=e!“^ùn*(‡j¦¢UÕÁYY^Ú3¶@ÄvÙ¦›Aö"k»eÛ}·òßWÙQ;Ôs©zíürƒÖ¯ÁŽ`½x™€)§q}Ôó][ÓâX5ÆQlÅ_¯F²\bÊ´~…ÌŽyÁ3[á5ûôŒ­‰ª®ûí÷°Š—êêîàZP~SD@iÊ×ê,Y˜ÔÛ9ëúÛM"h>§D(7|•g‹Ï˜XZ¶Ôüœ¥ºõ\†’=xµ*®úÒ]qÇf»CW­/2‡v¶!´iùk­ÛÎjþ\i¨6sÎ[ºN:7`è¾æ¯ü‘ÿûdqz)*§ð…E]ÿý=v”U¶mšlM̆Ãè¿j8¥zÉ1¦å*÷$êøC[ WÚ/AV ëEÒów%qǦŸƒZ7e}V›x"Á»b¨žÄ4Ñ5açêAšw¼p< 6ÿ+®qTzl¨º[ÈØ†Cò³š”$­¥–¦¦nC-¾¥Å“ Çhä¿ e8q\}7l‹qDÙ6Ÿ‘pÓ2±l’,èÕRÈ Š•³š¬¬`™®–³ƒ]Cþ°/¯"[ƒà;ê7%cKŒ@°´bƒ£l o¨) ZÁd52|⸓q”E÷Òî4m R³O”^_‹Ãùŵœ4µ ñ–GaL•‹Sq×½6œVQÁC‘ 0BîBUÕ_|ÎbÌð¶whèÄÇræä,œ'#}z V[ü~? -Äè‚F«¤T]Ñ|ú=¶U–ÝÂÇ1ºÇ.æòÅà3÷Ç Q<“Ú½®Ž7̸àï—9;ƒÜ€­”<Ë0cÁ'iÔâxIp}welAuãür.3C•Üñ}ùŸ5'd<~$ã„D¾ÝWr3KðÜOó.&;É£Õ©ËÀ}*k’Oº ÎøIÑ;Ñ£%ë­6]‰<úxë–ñy\–³{«HŸ*G}Ïàº,h\YTs"!<‘FÛfC ×Å:jæê¢»ê·93#oø©›[ió1üié_—¹_lN¼´RåË/V\&•(„  E{ÝÕdª\vŸgƒù]vI8…Ù‘ ™©$_Í'’®âØ@íDØE6Mgó2H‰SÆÅ$3™‚DcZìHã-öžÙw§”Gu÷‘>òí¡»žBµ„äfe´ ô·‰%Ù´à´Ð(”X2 îîÙ ¯rm¦'•6].ÊDäŠÖ,U̘:ôµnh1!ÀBi脎4ˆ]ç÷{¶æ)L÷z2¸÷ yžñP.Ç*Ÿ!îÙEv^¨½S\aÿ„hÿÐÒ!.ÿUOf¹À˜!ãi’©òi.Iqš¸–R.†ª‘³"# -ż¨Ié¶ž>òmiiÎÙF3&¬^ŽÝUö7We‰³9.:”ÎÖÛìÜ^BDíÝMHåmŒ[VÚwxϾãí‹­ *ª!¶Bc¿ˆª*t]YS˰›5‰sRò3-¡5%fC%Þ(J$‹Úi¾Ê‹ç§®x8´áK7\W¤c°¿ëRaª¢ªI¢”JÈwm²”uh“ËXø|ÝñE~7gA%¢Å9î·,±ÆdnËÆú‚Í©1qPÄ_i »ú"êƒ&ùxÉdg•3*Û¨ª›A–TÅ…¯D’òJ}˜SÊÈÅl&ŠúÞ€6¶ÆZ¹âüëŽÉä—@Ý´Ø–QÚ—Gy\2?/ztQ2'™lç4ðÆGÀ Ûy²TðGp`¹æÿ—˜{­‡Jx¦eجqêNPKx»ìb´?ò7‹ÕDFz¦«s®:ÈâäØÕ¢*36:ªN‡G#ÈdÐ\aæ×¡¶à‰Šø§ô[ï.ª–1Ùlés¦<½±áAŒûò/tÝW¯AET¬äϘÚå¦Ãê¤ þ/ùn#GaW(õfÏ&í÷&ØmÔY]Ùá±rëôlŸbx&¦å…Ë4tp=in¡™*¢ L²Ð›¯8J¨‚ÛbFKàš±¥“%Œ›¹.•A›(f„Å”(lÊŽªãF‚à/ˆ˜¦û*jÿ‹yZHå¾–Ö=™J/um¡wÔ^¶ža>2!ù:.&Ÿ›a-ˆ¢‚¹&l—–Zñ#pÔDQ=ªºÇ cì[a¶9[tW¹8=iiVTGñ™Dy«pZ€ üuw·ª¨ïÛ¬Úå 9óÁ5%ˆc.årŒi ù†o”ó-1i&â›$€AQ[-LÀòœ¦&gŠä5Á&ë—^v5Üæûn«$)0]½!}µt6ýâŽÂœw5ü…ë¼{Œ°›¬:€íG®ÞbÝ¢ˆÛR¥´Œ0qàÅ3⬫ˆ¦jN/rïMÇá…SäUõÃë¶•ìIvÆÂ `ˆÝ„uDu[ “µvUDšæ­™!À²=½ÕDDJ¹ïkŒ? ¶þ£ë²ÿù5Õ6Õµ=µ4+«æÉ›Êé ³0 { MœÜQrëüÚg¬‹cˆÃŒ–^WIY[« Æji0{‘¶A!í ÛÜ!ÝtWX@¿y‘Úå£70•W=1Ë·ñVâ„XÔuö}ÅètKÞUºŽûjeã!s¼²ÂnI›»5Б/ãç¹îµ!ð÷\6XšRŠ¢ª>Š.Ä%”\»—‘øÖ¶-ûÅQŒ1²[Ø—ED"ôßÅÃé÷t–ÿ-áŒÆmmø‚ýç¥â·Ø ‘äN×Jq«ì/iSMõÈxÖÀ_3¶a®UGw;–¨ÜFÛ~;Ê5>'£ê4Ô†„Ñ´>õouqÎ:çð›ÆœrÉɹœë7NT[E˜äÈêà;Q Ö^t›uéNv°ßb#iyÌŸ'™Å¼’ÄZû.Jãöd*âùœ)í›ÑÇÓON-ƒ‰+2ƒgÁñP-M±¥f^?•cR?-ä;·fã³÷âÌgÍeVÁÁ÷…|Q?¡[òubPijb3¯LŸ1åìq÷žùì €õUê» *¤.~çøC.Š&¼MÄÊhý~ôèfŸqûgÃo]õOÃýÛ{"}}Ìrìs¹@¢”Ñ0ÔóQ#7g)ç[HÉ3í P‘7-‘js¾anV7ªGªUíHœÐÎuÚFÞ—'Ñ—O=†Q‹VýÙL›m¡¦Ç*£SUŒ‰þ#bÓ^¼ÇŽD‡{PuÂ2Ù7UèšÆ>i1˜nÊwã-'2ÓÅW-0yN¡È{°QTÞªu~)¿>ÏP|4M>Ì £Ê+ÑI§€%A°1¤$îEu²Eê›*. CÅê_|êl¬ìè§ÚÉvÆdmÁ¦¥7CêF «L¶Ð¦ê¨ƒÜ½wüë?¯…~â"EÄ`÷Ù]<«à-×B¤uòîO¯DQòõh0ÑÉùŬz:§‘tt—4‘®@]M·Íþað^!¥†è3b˜½,WêÛG:í÷Õ ¿Wð‘WÉ5cÉ¿4œ±–áõñ%XK´¬»ZÖ ˆÈù5¶,bTNÅèž>ZÊeä/,Èj’¥«+Ì#½ÉcÌ•U5ÁŒ2*Kc!ƒ'PIEU:ûÞ:L—(ã²aÝ) Ö=ýëUš aÜ¥ £lOÒTQO-)c\ñÊ4ªP¹jÙ”þÉ»ÏnŸ§[ÔrÎ1ž²v[| ¦‰ä³* •}ªÒýšÛ’¸*Ù!··­’`“ZÈ¢¢y™B44ì]\73glÏùÖ8ú”;V¸œeâŒf@.“'±ˆ‘쪛.Ýu.UNA@÷Åb9­K«æ–Z}×áJx¼ ¸t!]Vp?Í¡¬ÈmgÃw‰yò¾Íl€•^¦ª„Ü F^lôv_T÷wí\' Áøâ^eSqiñ¹ÖS)Ô Œ–îáóGÛ¬b3fsm]49n‰0ÌfÔ{…;;q?™–Ü–%O)3X.ãY  ë5Ym7våI|Á 2j*-¸HŽGsÞÙ6Ô«XuòqlÖµ‘Çvj‰eÛ´Ÿ‰@¦ÝÀ_y—E; ˆ|Ñ? ]åÙ]¼jk„õ…å̳ìf4fMÇ }ˆ‰àUz']W|ÆrudЬN\/–þ.ž«YÔíþ$²ewOÌ'ÊÈ®ÿʦÞù)}QSG#-ÍfTN¾®Æ#º«*Í‘!Ù¯§Ã°£ëˆ2Žª#®¨·¸î¤7<«Ë_›9.r|,ƒ¿ˆqaåñm¸u–VØô’&à+l´„‘Oµáõš6Û?M]³·°­Æh*i†äM}˜™ßf£0Ž8 Øwk`)ç²"yjÔ¥{Îñ©NDËøÊÒ@9qT H-»)‘ mÿ¼Ñ(ûá±'ŽÈüYl7*$¦Í™Q^6ÝiÁP6ÌW¢‰ ª*/ŠjÿåîÿÉs¶x­~YàRÇY2,±é†fåSò!j?å¡6N:[#$Ú¢.ÛiÏãìÕx““÷xÓ¤ÏuµÛfì²xÕS¡QlÛ¤¸à®>ˆÅ¬L”ë3JËhÎ3xP"5*L¹ž©8ãòÂÂn!‰!'rvê²69™L |C‘X:ip÷n…Q\³±×'°Â ;]mc8D‹°©¯v¹6Bcqë^SøLÁ¨Rå„s®É«2I QÍÈà(¹ÙÛÑÏe¹Å²»Ë }Éõ×5lÕ%Ùd,ÊnÖ96,¥É†ÃÆlª€2¢ˆž>³žgðì¯Wo ÆdUÕ”XUðQøòyÆÜã²t£*©ˆ¢}Ñ릹U›8’¯O'±¹žÜ¨ŠàðÚŒÜv÷qPŒm)¶ú&û ¦Ë¬žÆš+tµµ,â°©³IsgÃzFuÙódÖ1}dHjÁ‹ŠˆŠ¾;nšÉç5ø‘»SÃmWL«¶ÛYl¶rŸ!eŠá2?q‘U$NÄTBÖk‹æÏÕÙ×`5ͽ*ú ]K Fó»[€*ãL*È-zN:*‰³ˆF*½µòXu%ac6m}2ÙºÄ+–æÖ˜ ‡63ÝêM©‚¡2ñ ÷ÛêevœÇæ*jPeË.2̦^Beä"e"Ý)¢š úc0ïùëáG*¬ðººýòŽ_ÄòFÂù¡\ðü,vÔ•%´óû<󌩴 Ầ§W>¦Ü{ÎÅyY/LÅ·[/L“îª"ôTð××?dùW¤y0sùŽe•¤Ë&E–¨–Ýb(H*øÁêˆ6Ê#MÄA×}OãL_¤eLc¡>ÆºÊÆXMaªö‘=’z­×z‚Ž—¨£ºìZ:û(ð3,.†¶¢HìiL8í>㲉'BP…z¢¢ê?ËÇÌDùwg"t\[ËÓq‰.ŒV¿‡of2M›2‰µVØ”$>¸n½ûï—âùVPÏ!ãôbÕQCq«êá+& ;ÇŒå¨3-–˜ª‡Ü~‚+Žº[² _óÁL¶ÿ+bñR&Q‰!úQ³Œ}•Ýêy~C-•bºª·¼«¢ôJ t™=[yài\m…0ïFûû‰wíE]ºjSW ¯ c ÝñæHÌzûzse¾èÓ{%:ÔõKŒ?Ǿ3ŸŠß`zµ˜î; ã×TCb7$:ä©E(zqÛzSÊO=é¸*dª‚›'O¢öÐ+ñlÅÉxÝï’óAÛ2©Åé»Vû™T^ý…åªL¾•L`ÝGGR3Œð*ƒñžÕq‡D›4_MXfÓ›YrúVGKPZn½Éñ>É’4UõcÉ-Þ $DUTñ-ÛÅp ,ªÞ²+Uìã8,¶}¦#"ƒ1Ý}ÁouDGNÞ¿^—øg‰ª0è§û» ÒãÔ·ö– X:¢¿Q;­ì¹’“ñŽã ÔXÈyOn‘eüÄæÆ~k-·­åú GîÇÈqeKêW«¤4©ööi?Џ‚»,н±Ân^ÛÚ,Áƒ_°]]Kò²LjÞäfn)™Cr’kÊÙ!4€ëý‚dˆ@M:ª$ˆ¢¨º ¬Iˆ  ž=&$™Ki¥µ™ñRl˜PÝzYª¡w¸â÷) ï¥Ä0ËòRlàB2°eù–9•ô× .•zÊ“0Þ­ABq·ÝÙC·gê¢ÈL†M¬º›¨ÍÉ>'cÄÊO©œ Û‚ój=í*Žé±'Tݪî\”þ{Æ=ÈÔaŽÆöU"«°C”üFÓ¢|[#õ¸;®ú‡iW5™õóÙ ö1\Y}—pq·THI¢¢ìºÊsl&¸ß©b¤×$ÀD¤¸³áDp_bž+©9°Ÿ3•5–QMÔl;CÝÕV=5OŠeÓœu¬2¦|7U‘#0áL­ˆN½´p' ¦ÌMEÄàÛÞ·Äòª¶nqûØåʹäèb½P„“¨!Q$EN©¨Ÿ*¼ƒÈ.ãÙ)8Sø_œŽ¾4ë[ªxŒ˜; §ä§d[¸@ + Q\6SÔ ÞG8o.µ«Å(ç]@²r͘ÓäT³›RÖÅ•!ùQâÌ}IÙ–rm€–ç¦Ð<^¡jW3Ö6Mpo)ØG‰óFÚ/£ElòŒx™s A%gö§TíyQTWM>àû¸ËÍ’n$$›¢¢¢îŠŸÊÆø‡‹fü/3ó„‡é±+NÿÈ«;|…áò,áï÷ž&Ñ7êšÇ0 F*Ä Æb X}ëÜóÆª¦ô—ÏÄÝ}Â'%ê¤JºÅ¬r_L[ʯ©bD—Ò8̃e&l©ŒHÑŽÙ«míÞó6ŠEÒ¿;äÌajøú-J̨uÙ__¦°áFˆàµ: r"ª¼ ¢ìg ›D5î¶2³®qÖJ|ÕFa´o7„2÷Œ‘h7]×ÝòM@ÉÇðú>6‚Ù5¶âIM£~t™”†f3 þ9ÂåÄ2(®öª§^õƒKWW‹Ò°nÉv46xÔÞx…¡m±#5R"Ûª®ë¨¼wòû"~#2¾}‰ä.Z3Vý½u$¯Êçv£büªã9À!fk’B.ÒAôÊ´.aûpˆÀÛ?HX9HØ£ÄК© )]¼t»÷'QÛÇ\›ü½A‡Ê´Ù‰ æE] JÇ¥År·ô¬ûl™&åŠ#æÓN ¨I²whfsNg'1T1Ájʬi…è½…²G¥íûOšïû:jª‚ª%c‚Í|ŽÈ¢{´ú¿.Ìë(쉡}º·ÜR”Mª‹ ‰¸¨J*‰²uÔ;f®ÃžÃRb<¢AÞÓ†Ùvš!&註*o­Õ6Onº¦ßn»¶^ßÚòÓ•Y<+êÇSg Ø0܆—ìv_­:édð¾k#Š ¦¼{¶¸ë¾>ãHd²aïídÕötr7×ño2[6äF-¦¶Ó°nÁôœZûQAiÒp=Õ^í÷W»Rã˜ö ÜfÎLú*ù_ sfpÄVš­‹5VýqŸ_Tû»œTåDAÔ*ÌÛ—?!¬‰6²ß:šŒµÖm3+ù«ÊÁöÇTº¾!Þ;ÊÈøò¾NEÄ2Ý)™FÝÇêQÅîvË^‚Ÿ}؈½¤›“{/…NUŠÛ1wAvÀɪµŠ[¶à/ó(®èB¨Š*ŠŠˆ©©ÜµGTÌé5v•ÙQ\­<ìËÕïGb¬ÞžŠëÐëkÑNL†b‚) ¯†å©¥ã4Ò±ºGl"Zr•L§‚žòK 0xüwОy¤Büs2ì÷D‹GG*cÔÖ°¤³iˆå0×¶e5¼Eï‰>1¦Ê„ÙýäßÞ!^‹©5WXë>kã[féùJž…§¦2Ôö[Yö®TGeÒ²¯ž¨NED˜bI<Z›KÍôÏÍüéÛL×dG ûy¸ìµ$ŒÝûPnrÕ“VÝ7ˆª¨jH™Ênobý„œçœ’Í%'.p—ôšŠNï$T8©ß5oÒ-¶Ý“:ÒÎSPkkc».ÂsÄ€Ó,2 n8d½DQUU|µ{óGMž_q®Ipá×pƒñ;] Šj1Z°­}©dâ,·[-•;ƒ´“dÔ\{ægƒ:ëƒ0Q£²q ÆJ‚ )I ú· Wî½»{ø8‰©57P*ó,7(ˆ‰"âÔêùÑœMÄ‘S¼ WÄHW¢õßTøÅ È Š¬ r^˜ø°Òlr$›Ž¸¨72UÛÏMPN¶° ‘Ò¾òŽú­YYP¬ªßIdIiöí4ê¶BIâž •˜óV?—¶I"êÝÿŠŸ5÷ MÙ2žØ{Üp‰UvDDM„Q׋쫭k8{5e+q¼Ï…ÉÀ9Q©ÍeqlÞQ`&é¶l ˜i  w@ä ¾±Ún]Êñè :Å¬Šƒq¨v“#´NMv: ¸BámÜ ª]¨Z·Ë³ ¸˜æ3BÂÉ·¹œ~›,¶žÕñ"%è"(¤K² *®Ú‘!ÚñO¾½¬Õ4e&Ë_ï“ï ÄðdÔpWß$EÙ!ÑãÕq©iàd:Øm£Myªøªøª¯U^ªºëÑ=«á§®hæ56ñh\…G*3¾„Ò Œ]'4íï]Ñ|õ€fì\À°È¶ö8_&âÆÁÚ ˆ¤¯">­'j‹èÛ/n(j».é¬^Ç© “ËhncúhÓox’“×OUÅtZp—mþκ̪«2$¿Àøå‹Œ¶+-¾o•}ÕÓ ë^5%OÀ&ŸxWpïÕV[ŠÂk—aÇs"±tíËÓŠöÚ`‰×Év+¨£cl»*§E]“qÖFy¼«p/à›¯¦º%yà”ËJ’å6ñO°Uˆ“tCUáEÛWr3Û{zÄnÂê õvR¡¥\}…µw4ï0ꊓnö¢™}º¯õ‰ÌzÒ^='™Oc³e ¾{ŠÜrÿî@QK»eEÛ[*lº—C“TE¼¦œ=²k¥‚kì$óO!T$ò]"ÌzË‘¸i•ÙÇœî—c þÒª{óá¶ž;þ+cûBšfú±cÍ¢ÉÞbÞùÊBi–²†c¶HÄY²AÕ¥>ÞýˆT»P\è›%øgØÔœ'ÃY‰\ÜtIs¤W]I/Qº†ß’€ü³ôÕLýÞÖv £|™ŠÂ‘'‰2ww+`ÑÛU:·_DRÈ+£ÝQEE–Èô!÷Ñ;“¤K*ÙlZTÛF f°Hëc>À`Iº—éMcy† Ï0©+›‰a0 ˜j$°ŠŒ%sÒT…STÓ@¤DÈ¡¿ß計¸5ÖT’ñ»Ñ…Ë È(üGþëaª!"öª/¼;/ž©>dñV ɸËùN™•@[¼5ç¥6»ì„ü_‰¿]ÐÃõ¶ÓÔ-tmdâ~äž_ÈYz6=ŠH,©¤_$ÕO=BËî³înÁ§7tÅÕ¬’°ˆÊÎ¥f#[1,¨æãhÛ@›Šî«×X‡$b2¾3Í*ãÚÕ:¿|[|•·õ\l·"EO/äaß.øüÃwÏ•I`•‡‡Ö ?tîãÔVBqT¶ðÔxpذᴠCŠÚl 4Р6‰à‚(ˆš~$¦•SdÔ¨¯€¸Ó­’l@`H¢H©âŠ›ië—|¡œf ά‹>¾õeâ3‰UTþ±Uz±ÓßïÇ^ÝüCmDÁ9²O r¬…Œ7!t>È“mÊšÔ{cÍUè(¢çõšT$QT訽é¼Ìó†(1Œn!͹¶»M’"u#%T÷ˆ•uÔ@äJ÷èøö•ÿ‹â~!•àÒ'î®nÛû®Ìp}æÚ-Å]¾þë¥Uê«âº‰gcM„»‰¬Õc•1‡cc%vb?¬{4Ïzþ»„‚ŸoM\åõÐr{¼o* ¸žuÅPåyx­¸Fˆì”yïIÆÉµ3°Sq$-d¹Ó}]ÌuD Fv#î±\ø½×ä›îº.5ØʶØ"n‚¤»ê{õõìD“lÿÅZ>ÃbJ‚!ê¼B›™öŠ'quÙ4§’å5ú'UK¬G/ø./ô´è5È”Šnš›ë{¼×Ĉ£²HKõªèZo’éãªô’¯EOçy DÒ9äµWà½Qk¦1%™£%þ–®k­j#IDr Ø«hIŽà¨“n8&©²ôëÓËMbÜ}E&û¾~%îvöGfé³:- 6Õ~83 ½ðmÍÈýíÐvN½½Þ?˸Çq›äXÑ$J*(´°ìBï«ø©¸¨ˆù ®éäPÛ8ÖFµf¶BŠIe™M¡Š8»ôßmüË蟛a^²ã{'ŠW"ñÌTî(jK»¶ôí'A!OyöÝ1÷‡eN•ܕǯEÈòjj 78ÜÍ“])m˜Ìɉ"M+¨¨Ú—j¡{‡î©&¤ñ×!_ÎnòÖiTe¬ÄH¬«Éez !?êt>Òt –Ú‡ÅÓ\PâŽD–ëœS-Å^ÊK“îvE ôduv.ëл›O-v¢*ªôíOÔ¬C‚÷'ò3ëØ½3 ‘ ï±Zدs1EÄ}ç?¬Ó6¼Ó~Þ@ãõœqTŽGÆ ’l¢¦É/©9Áÿúª{M´Ø M4( 4‚ )ÑE6DDö&‘S¢§T]r'Ë›þDÄw8˜ v-änî¹­úlÄ£ÀSõ]%ðOäs71«&޲rñ¯š®à5ëÄ–2Y_d»"uwóÇÙü‡ñ쾊EM#©ÁšÚ ù8Ùt&Í<Œ <—M3ˆØ¿Î|_d^:Èå d•¬"ýÚ‹—7I" ÷X•×dAÔ¶°û—"äÕ)ÿxð ––¾þ°üÆT}ý‘\;|‹JªH(‰º’ª""'Šª¯DDÐÍŒ÷­À\ida†ÂOÜå7ñ [záäTØâD$PŠ+Ð˹ÏbkÇr%ñöªë7±n¾F‹Ë—Q[’K‘øò§WdÇÜiQ¨Íª*"‘w.ʽGaÜ9]SÏk‘.fÝ……~A5÷Åê©Ôm6f‘‘„Dp D;S`ÙzïÙ¤õ Is dH&[…Ùì„áö"‘uÔ¼i‘òf­O™äIÄè©*ÅP„‰<Á”"û4Gžr,ØðÝ]ËÄTª ~ÁÉE)o'µHÇf½hgÅ*îS¤²’äûI顪þv2ÃL¶ üȉ¥ã´ø¯ˆ¸h¿ ‘uññ*楢î›ø)"^D/ÅVôéä96Zê8žeÝg‡öš=²Ùú½ãDöj5ŸÔ=ÆùLÂF „çEê™çá´+!Dl•|ÎÃòÙugù¶Sl·‰uf“£¤…vz6#ê®÷*/bvì›Ûô꺕ɶׅ,,·óõÎb?!Ì‚\ $hø«À™ †¢Ð{Ý».ÈIªÚÎB©^1ͬäx8¥«í‘ÌW×vJ‚Kë&Ê‚}°÷ðÖþ ¦ö5g†9ÉÇ÷œbþYl.‡“pçBOºÛ½z!jÆsxíksí§5ek3áZW_›Yᨪ« §io¸ùjÃÎíÞ?"iª©“zV ’9M|V¿ÔeÑC^ÑO$EÔi¼¹âu5‘Ã*ªÅ»Ööíßq£9rÛRXÂùªnÄ~»’¡žÁª18øT$I¯ãAÑø©_!cJøøÊ"ëP¶=œRRß»t]-¤{40Ñðnß'ž*óu±Éw‚0ûϺE°6ŹtM–ßйȭã›m ™#õí¹%KÔr-|a™ÜwWwM¶ó×ó}H¸Sø~õ›{6šûòhe'Â]Åéâ‡Â4OÚ_-A´­’k¬£µ*Æ—pu— ·|Ð…QSèå@€_õí]+‘1F‘}ç.lˆ`Ö€§š¬§ÛèžZİÆKÔ\v±ˆ²ä/‹Ò»{å·9…³Ë2Òa/© úˆûE=𲤴e$W[Fr,ÖW§snjì¾Jž(¾K×Yœüv⪪Ίõj¡à!­îH .8óó‰\˜®HTšPDhznž:VfW7.‹g[bÊ*!ˆ>Ñ¢ø.Û¢¦è©©Ö¡ì­Ù¿ yá4¥dóÐÔ²„Z‰èF‚¤é*{ä¾Tß}¼ÓR«æ´BžË‘¦2IºNŠŠ§Ö*©ªLRâYKÉ8bÎwÝ8âîá·PiùsŠ‹×c€ë ‹ç×èùpáæË½Œƒ+•›ä¬ ø×â1½fEÄý“›)·ñQÒªõUñ]QW^rV)‚;WfÝÛ¹klJ¯³Vu¦š“ Çš7s½P“¼G¢í¬~©eRÚUb£ùõ¹2áØ± J|S d¦¤Š„)·º[j~%'òô¢Î#5[¦-¡VÝ¿ ]õe`¶„ø#BÚzJhgÜIºt]5=úH4·y;«ar0éš qÕMÛd¥WÇyöy=õh» }Ñ>‰3f¾1aBdäL”k°¶ËB¦á’ûQUu’s-³Fͯ)Ê4l9ºÍ‹Bmš8Ûˆ„Û‚»‰ &èH¾ÅN¿FMžAÅÙ´È"@õd¹¶Âl¦ãŽÂÙHíRAê¾; /EÔٮ˪—.¥iâ¤)OA1BlL–šG~òm;w×ñ ¬N±"}‘Æ©i´mö§E~¹"|Þ2QÄD$TûÚ‚Æ•n-"XɄٵÝóVÂ"ö"ª¯ÑË~ëž(buÙ…[d¾ïæ4O~Y9?hØÁÔ?Ft~/ñí5?T&ßÉ~ÚR§Ö¬·êÛèËkmãÞUgxL› z»#Ç£5:͸aZ-d?Ô*摳ªæÊ«Õ•îÖ,Ì£‚ãíSÁ\«nlÀ"`wßÕ6QBê‰ã¬f¢C0ë'Å,>VAùDЬ$u¡íÅ-·àÍLQ¹Úi{48¼§Ø4jÒÊ\(Q ×"Á‹&IœxqÉäCìi½¼Q¹KdDÛè©ãÊlj‹^^»‹Š‹¡÷Û¯sy®§Ô11þÙ5&F<(MxqÁ6ÚhPDòDM8Ð8&ë(„óBH¦_uHSª"ùoã©PßÖp$!ÆÄÙ4OtÚt¸WoO·TÜgÆ95¦3OȌʓ›á ¸ÖÁ¥h‘$I…ê÷9 ä8¾‚ eØ[—DÛQ`@Ž Âd#ÊÒl ´Úv€ '’"m«\n»Ífãé¾@õ[{µ|ÅK´ÕT|ú"oÓ~‹ªÛËåÖ Œp&‚†PÓtDT‘o-ô›.þöûê5md&+«¡7VÅ–ZðlìO¢}M‹)"¾Ò;°ç°Iº/‚¶à¯Ú$º=\û‚¢?ü+ùBÛ…åÞLTU­íÓ騈».-žž£âƒe’Iô~Ô‹¶ú‹è ûŽÝ Éò”±gå\G&rÒn²:¼ÈX°@;l©Úh›ôÝXæ9løÉ¿@rvU`®zž½¤çJDÇIÅûÿˆjÞh‰¬ë“%q¼¢Ìëq…^¾%AhÝžÄyÄqÕöªýÞeÇ\½Ê%‘“âU·Z— SÔô›BEî"%^ˆ%ÚJ©¸ùp÷:JõáF#ÕKâFr+î8ØIFT•:§r§Ö¡×Y×'9m>#ùŽUø|÷A#×GyÀlP‘·EÛǵ5A‡†]aWÈX¼‡2eL"{Öq§”d‘6BmmÇÃÃ\× ò cyN7° Ñ95dÇøW_v2§s¦›.æžu×ç¹EºØ_\3_.¹É °‚!ÕÒŠø¢ì¿N[^)Ù;Ç`_°>K2µÅ%SëVÉ¥_£¯‡ž¤Ìʲ::’¯+ÝiŠ*£~ÖT4i‰ó? [»JN©!õð^ÔdvÖÕÍÛ@¦®“:]c€ òw³µÄ!ëÛ¶ê5QËÃ)¬ù¢D˜â$ãNGøqnICšÉªw ¢)ï '‡Ñ-ct‘‚ä44sOZ»XÏ’§öˆZø¿Q>Óõ½_.Í»»¿›Ròêy^]–Þ¯U%›}4ÑU|÷O¥eN¨º‡”ãð®1«ˆr@]Õ‹,9ê¾’iØäù¶M¼â!8¨…ç­þ˜LW½\ÊácñØÕ%c¢ŸR8ùþd3ÊÂ5JD­”âZL{áãÆ$h»uí‹Ó-•KeÛÇmX¶y.;iŠTGucWÐä_Ä s§$T)*¦ŠätUŒñûå¹+Ĉ›¹!Œ]“+èå yyüL€øv6úýGmcÔ,¦ÁO]'ÚM¶(kúKuúâ× «fgÞô³gep¿iÁA5úÉ}‰×ÒGÅmã0Ŭ·é»Ü¢Ë#Óµm‡¶Õ^:ª=­ Txì3P!¶KviWrûWP¯\©ŒåÕk ¾ÐöYTTVÀüPv%éõê}ÑbµËkhÓÌYNôQ öä ƒÂâ&Ⱦ ª¡.Û®ªjÝÇ`9[Bê?IšEn+¨ª¨mêª*怜2,^ºæ{‚ÜÉL‰9Ú>EÑIØ[¦¡ î+[f•Í£0=V–‡ª6 »~χժGÀ۸Øcæ ˆü—ÞFQ|öÒ^VaõPmÄÕÆçµPÀËÄ>è/_Dú2ªM¿®HF_1x\d“ëGWXvHkÜíÝ4)Rþ8ÙWÿ= FIi§`ä›db„Œ7÷ÝQUß°|ËÁ5t) Ë…1 ~$¶I ·Zq€À‡t!$]ÑS\/t=\»ª +í ~!´_íã}5×8å[ÓïÖ­èÑ>8Ū8‚ê§&ÂK‚ÜVÕUò¶¾ú ©&ʾJšþ,ª@)e^.,¦ÐVP")1Ü«·x¢¢ªyjK˜åôÀ„HÊÂï¦K¾ÝÈžì»/‚êκ›*©²¼ƒKÁXÌqÅ6#TA÷¶íꂺ›M–Dƒ÷ ~aBôFxuZ…ÞáïÚ½zxlºŠ -a–R,¢j4ëÅÔÏQE{‰¾¾ïÕ¬ÉÛ–¢´XýóÕ¾²m –ÓtSî3ܾ´ÛìúDU7BTEO©uŽEUÝ*åZ×·ý„[)-Š~„DÖ-‘g³òU¥Èk,k&1_2oóè rm´ÑmÕß¿bíRÙI=”c-+ïÀ2l+N2¡±@hU·‘„vØ“n¸¦rª Âä ”ïUÛd}©,–ëìØõþrÏøÀþ®¿Î™ÿÕ×#SRWSd´<˜›¥²Fü¥\†Ý#*ºØ zé**¯EÕe[–Í*øLDr[އ{ÊËBÚ¸^÷‰vï¡3 »°§Breü—«ú.è$Ñ;Ü`‹ú†j?V¿Ïc"y~3Ýk)޳¢—¯M`ßo¬ß^èÎ&ß{Gfª¾ ü¶Ès=ÛÄÏúšã{«þ1Ç­nçTïkc* ›Ï>Ûî¶Dá*õ_sm²[þ€ÿd¯ýžÞ¿Ù)ÿg5ýM² OþÍgúšÿd—ý˜Çõ4?ý ÄvÝ7Þ­îu›Ñ@ŠÔt\‰•A‰‘@m†Br“M€§ADO-^̃‰ã¹n$Åt‡3Xòe4ªÀ“hذÜPU5UU%U1ìÙ=gXòWa±‹ü‘†gàäóõÏÆr ú œ§ŒÕÇìT袞;ï¨óîVexÜ·WØdÈ*¯ÙߣOa/ûÿFé¿N½<F§»ƒ`yf'ÊÿšvÁHm9·¿ÞyÖĽÅ4Ý}ÑM—ÅU7]aÜ·±~íÊuÇ34o ¹%誌¼»&ÝE_í\ ʬv{²ò ›–6-“›¹9Y'‘å]APWÉ5δ8MRÒ³k‰6Ý31[XñóÄm´H‚G¹Šl½WP±ˆüy>“>¯Ççǵ¶~­EF@°^¯|ž¤ž¶Þê’&ßwÏ®šcÐ%ÇÈé¬nj%°,­ð–h`*­ì…²*’"ù)"ë†j†ïÃÔbN7e4/I%º3{¸Ñ;QUÃ_ök<­¹Ä²9îÚdr¦Æz%6ý=Ô:©uUO.š‹(› L¶ð¶i±Š8(H„žJ›ì¿@*ø!"ÿOT’?VÂÂæcKíìä¯éMbÿ”Zæ,‹;ø¼Ä-ÖZ´?—nª¨¾‚~Þ{wtÖ/üf]ùbVGL„·U•ØýÊïwímÓ»}µÇ6QBt ¬ò¦<ÈN¢¨:з!ǶTè¢+¾—ÿ§TÛèÏû½³ªoñGýÞ¿ÙÕ/ø¢þï_ìæ“üIu¯ösIþ!º×û9£ÿ£ÿøµÍkhÚv\×Útcì MÇ2EßÅ7Ó•Ö_–¹#õîx›ŠŸïê=ôsȲzWذo&´‰úé”n<ÓeÁ…!ÐWmåFÌÁ„KeTEMÓ¦ú—Ç·Xeuüš[)õ™i‰¿!kà, ¡‘-¹M«`2{›ä™íâ)·ÓóޝºPó”¸h?â®ë¢ÉûĵtüzѺÅ|§#Ó’! ³H†:¢¢¢£ªˆ;mç« r)ãvŸ‘EÈ,£*6(í¥<­½O(6AuÑîî_Ý^î›k‘j₹5)žª¬Šõmõ÷2‰ª{¨ä„żó$ö>عÿÞú~ò¯M—¯—³Pî/²ëxÕ|Æ'űˆû‚;Ÿvꊨª¨£æ©ç¢T%Nï½·Mv÷/jx&ý5·q*'–ëå®îõîöï×J=ËÚ¾)¿M~ð¿uׯђ^¸» Md©Cõ˜4J úKdÖ BðöI®£†2ÇØû£®ÿçšêUãOeÑ£crÛ£¬‹7S"Ë®îÕˆGW7½ Mú§ôõX¹ %¥ÄZƒ=»GâdºÃ@'+v ÀQt·T]üw× R¼¡qivøûº¸ÀKþ„O£on®2,½ Z«,¬\iÁld0ðÇs±{ULQÒAîN›ïì]lºrœ"¸îó€­;èÆXMÂh^q$!úë#½{TUvM¶÷¾ŽA—¾ÊÆ9f£ö”W?¦ºþFËÖÿS‘ú[{ÝÿÃß ¶ÞÝõó)‡úiŽòöC&3+Ó¶5â1nÆÉìT”»jXÀq¦g“.$d  òŠúdà ‰¡l¤ˆ¨ªž ªÜk0¸; ø·nG¶‹[‹•u´gZO ·ç/¸ú§)Q¯GÔCUNº–îiT6“ÿ©m¦ Í®BRDSpc8àö÷'¸i×ÏMáVð_‡ÔF¼bòŠ,5F–ÚVK‡1=EšSšî%Dp”wÜ•vúg ¢NPÁØÉx!Øcr‰§íøib¿biStEÝSXæI’ó]ÖMbõ££sƨ þ[d6ÛÌÖÁ¿“Píqå%4ðNåÔiÐb|ppâIm[uàEVÝlº‰".Ä+à½5•q¬¥_‰ã»w¡@î]ÉÊ™j²«]Oj+'ÙöЧӄvE;b}Ù1kcÃþ˜÷£jŠ}ˆªHš¿³¯æ;îFn–šL¹´“ØØ-¨’¼¹v©§oj'ת JËØ°/ŸHŒÝȆ!©$]¾‘¸†½Ê›¢—gvȺ“Š}ÅÔêÀG/äUEø–«ÅQUåBB÷QQKµo·¦°ì޲÷"Æk¤åÍ×0å{m£Òi7Px}aDh‘wEÝ~°]dÔîR_XÏÅd«6Á(8Ø®Æú¹ê" b»&å²îºÆ."„ûdz0îÆ(kcúÓåí÷ÑÝ{¡*¯·Vk_m]•…¼¢²kЗÕßdpI6]—eEò_§ ㆽïâûfäÞ oîSÕ˘E·‘ƒi¿Š–½ÔDî_tSï–²,³ ‹Œò¶rzë&§UÚ¬L¢ª%GcN@i‰ˆØˆ»é/r¢ö¯qt]Óhs‚ícòØmç«_QWc™Š4â‚÷®Ë²ªo«7E{âñþ$ÄPfÝÈYŸj0ÀoöýIxѦc6O<êø6*D_¡Qê¼®—̯#̱Æ~ºMYI´±†&ø•6ýqÖî/BTBÒx"’þŽº°³ ™Õ³Ø;;xbÃæÛ„P›(¨Ão2Ås©)'orúi¶¦ã‘‘JVaaSŽEñ#¶±dO?uÅ×åš|Âü¥åévz}¿ðuËð=8Ü›‡c¤Ûd7«ýz9ŠžÕDe•_µ>Œ`mqFm¢[Ô|QMvšã,zS°d G%DY ÃŽJÑ¡+ïÅ¿´u¶’©š:˜Œˆ×ÓÇdc7µ÷‘¡dP;wêˆ}1—Úå6 c¯»+º¯ªƒ>ÒTHPÁ¸*üóõB,(@â˜!¨8ê**l¢$DÑ <WÁQ|Ñ~Œ'•'8§#>ÝAIi,“òûDé×amÑq°ÒfŽ6H„ÛƒÕWª*/±S®²|÷2Á”Wó'ÈI« àØn?kŠg².¹lŠ¿wEI³£¯²‡*fwkØßç—Hø{mR&‰‚QU^åMÕE6Õ1Âhо #òCm¢ªþTû»Åž¨ž?ù{Ëþ ×É4$†ˆ@b»¡"õEEOTú0åÅkâÙËÇî?0“[­´Ñˆö‰zŠ=ÈJ;*'–¯ëïðWiKa&Ó«@ùHu’UKÜ#^»¦Éã®<Ã[€Âßc¹XÚFø–VA) ݤ»8=w×$Úá¶8µ” §²mãwÛ"¨ÈIÄ7›S Nò$DBBM“d]`ãK¹@ÎÞ·”N8 Åm ÀïÛ{tÙ5ó5ÈŒ£‚íãë6ªò“oŠ#‰¿¸›˜ýíql¯fÆ÷ ‰&æ/ñëâzC®§¡1’DNþ¾÷_¯eE¿µ²ÆÆ-o_X­Ù¿fáFkuo×qÒ!ïE%ê+Õ‡_}Ðe†œ}ã^Ñî"%_DM×W¼³`É6cWƒGu ª(Ƥì½Ef=»ŸØ jà ±qÚö‡R`M†]öòfØ„۬º*6b¾(Bª‹¦8âíçÆ,”ËŠòW•I`}â©âøHŒ‹³{þñ½¶ê›%Û»¼R<»I‡*PºóJñ'MÜFœ%ÛÏmE­¬ˆÕ}|&Ѩp˜ÛððþFÉ⾑‚V8c…R< ÉW¬ªˆ¾B¨cMÄñ76E}Sî»â»i¦i¸Ñ£6-°È"m¶Ú ˆŠx Š&ÉìMLtטëJ1-$A8òf`’#õò^lI@ÅÚ_ ‹ÁQu£iÆëàw›Æ®¼ë®š¸ëÏ8]MÇ ”‰WÏU-iˆ^]c·n|M­å;?ðc }TîŒØ¸ã›6ªŠ=ª*½wµTà ¸ÁÚÙHmè-Öº„þÂ=ñZ#F×ÓÝ•|×eèšÌòçõkxwb¦;ªÛ)•ë–ËûCËõÑÉttmz™]$òŒ,…\K|}ೈ-íúÎOì%Ö7˜V.ðrzȶqÓöRKbâ‚ý`J¢¿ZjƭǤF ÎGY1ôd5Þ*ˆlºˆª+ÔI¢õÖcg|‘j¡e% ÈØ»6³o¤5"(¸Í™i?cuçÀ€H[m;Sn»ë#ĦÈr$\’½ú÷å2ˆ¦Ú<;w —BÙvÜW¡'E躻]hõ—糂c¢LµÎó+Øôp ½8‚ê©¿)ß&bÇm ×Ü_ÅWQ~a‹dáœmþkÉÕKÛ w^îbâEsHC`8h¨&jï¦Eº §FŸaÐ}‡À\aöÕ „Ä“¢¡"¢¢ë"ʸëbÓ”ïâÅ \€\i¹Ñ*Ü%nKÎI‹m˜´Dˆ¢£¾ýʫ۶«øÙübñeåíM¡‹vVYD¨ ›;Ž-,Ï{N¢¾ÙØÎM ãªçl[Ѝ<ÃÀ»µ";©Õ·[.¢Iáönšcä‡ÊÃ’ê1‹ò’liôn5ª'HÒQ:w¯¸çŠ*.úEEED!$]ÑQ|Íùfã„¶Ø©¸á*ˆ§URU舞ÕÓÔØ§*±ÜV2>MèH+³‘iГg]_{î–ë¶ c¸ô®©®ñÅTˆˆ—sqÃ^¦á—¼D½UtÃ8CÙkt’ÞÿY1š•ж#L©Kîp~· tqåBVÑ•TÙÓn+ç\ÁqêìrÖ@È †¦zhãl4Ó††Û “»’6‚=:êDÉ„X‘7åÊu{A¶›#2UðAU][ó;ød‹ü.â?äø¸B%[zêhΩ,¶á :2ÜüC@.ý‘6ÜvÝ-±›f-¡oÚé4ªŽ2~m¾Ñ"Fžbh‹ô+jè¶°ÍPŠ$ÆAö•SÁ{BMÓÛ¶¦ÙÎqªÚjH†ü“Am˜ìëÚž‰²"'ÔšÇÚz¦ã»8c2…«Ò6EÚ¶Tþ&L+ÞïjP¬†Ìšwn‚®É­‡~Ôè;ªªìžªõUѺñ£l´*o8]@Sr%û7ÔîL±ŒL[ó¦Ia—§¨›85[¤†×ÕøHÀàÿé>…EMÑ|S\ÇÀ΂± ½ÍLª¶€ÅtæÉ‰õÒÚYu²è ãfŠ„‹õ¦œ—Ã×LB*™q¦Dë‡7ê£]?ßv7ÔÞf‚¿‘(m8ÖÈ•Vé•Z÷Kþ"ÉŽøÎ'Ö¤?f‚M\èöQ7 ÁSê&Ô“[*m®ˆ«¾ŠUµ„Z¸À›œ‰‰ý“Š)£…Ç´6|‹=A_¬iY¬h½¯YH@`Sû%ú´ÔÎY¹fMp’8ÏQ›V"¢î):Jö½-SÌ}Ö÷òTÔxq#µ FѸñXm¦›è ˆ"ˆžH›jó Z(Ó²¶›f°ë,±øê*ÉWº½är‰ @Å}Ñ!ßÍ+9-§A*sq vÒCV E°ŒÑ,"2Pu¦‰MͶUqÃS5良j®žâ\~AŽ1Nm½Ê·¬jj÷µNɧ‰¸©»Û}ÔM½©«›,f§Ua¬±ù´x=„ä8ÄŠ-¸‘…}Uh6"QÊšþ%¡Ÿ'ËÄ(©Qy<‚[ øRA|ÑÄߨI¦àrµ[p")#q¹ ¤ ʇUWaø¶º¹ ×Ï»pßÀ‘4ĨψÒ[cIhÛp 7БSÁSSèoa…M›~”ØdFb„„žð’l¨Š›.š¾,žêýšè×ãõ·¤¯ËÂS›þ”…DpБ¡õU<~Œo‹1§ ¼›˜.âbO*“ Í%[ k·€Ç†.¸KåÓT¥ d…GŒ×Eª§ˆ> E†Ð°È'ö ŸO|ÌÖ°^H\S•U´ÝO½x$Ÿµ+çzO}Bn.º/T!]ÑQ|)Zâu¢’÷ÎpÂIÝ=€šËX‰”RR[TÔb|2ärÇ'‹4#¯­Ô4x}EtÁ‡m@¥õ|öøˆ2™›LÀ$ÇpmI£VÌPÁTUD…ES~ŠŠŸDÜ_"iÏ„’@ü9ñ‹Ó—c+ÝdGS«o2^ðª}‹ÑWMñW*8ÛyËM˜¾RéAÊ µÿ)¿@” ûö7ÝÞÅt¨¨„„Š„*›¢¢ø¢¢ût¡Œâp Šó÷™'Ô°ÜÊl#6¥]DÄ6ý6AåRPûª«Ómµ±©þ;A€œ‘b³IL[dRûàÓÔ“¨êÊ(ÌŸÜ.¤(žðí²Ë´ vO£]a"¦Î$èÎC•tRAv;ì:ˆ@bª>½;[ ÊŒòv½ð4óBEý)£˜x,:‰î*©O£qú—w_=á8Ȫý©¬Û#Çólîºf?Eac7çï>Ç«9ºÚ¼J=›¢tóÖ=gqšgNÙÖC—*9ß<Ó^£ì†ˆŒ‹k¶ä»uÐÌk ‡e<qŸnOZ<Šž}Ó\y~ÄÔaɲ:¼j1'ùG܈…:~ pÜÕúÑÛP²ÆíŠò’Å(Ó4SIÑŒ*r 6AFEMMG·ÃÅQ5“âWÖqì¨ù Ùðq1ã‹`.=ÜÌYòâ€(6Ú£Í8ŠHá®Ú‡<­‡dÝu¢\bØÌN`R>möHضۀùþ*´-£@» ¢í¾‘?B&žã1|Ìžþ&ÉQ;ãc±¡8j I'FÛñEêº\KŽñË …ú¸ÎXY$VÖLÇ•HQùöîFfd›í¿’"lš…+Œ 0ÌŸ²«YXüÖ£Öä4* 2ßmòzÈl_4õ{½ÑAV‘<,ï§³‰¶¯,‰LÁŽc£Šˆ„­²Ú ‡r¦ë²xª®£`2Ø5â¾>XwÜÍ/oÛÜ^­m/ŸÅz¯§“#·‰&§e?+·ñ°iŽ™ÈÃ÷ŠëجÃUR4‚cÜý[„ª»z]Ío²zbuüÉØµò"«XÅâ 58G¢»W<cÎoh·öŠkeM•ó1¼ºê.=‰ÑÃÇ©!§àVÁio3-º™¯™©/šý|b_0óJªÛƒ DèßåUf-8ô$’ ©ê5à»!"Š–‡‰PýÕÏ“Ù=ìV‚ ùq…ºùeSZi$D†ó"–}Åõ\õ½>ÎâVÞeÀy—„M—›$ 0$ÜHI7EEEÝ>‡1ì¢?5Óãš³2¶úµ.÷™uµê„Ÿbî5æWÒÃyÁsK-öC¹{[xØîäyz¿ºsÇt]ôÛ­ºÓ¢†Ó ¨@bIº’nŠŠQSUOÚ×32Mà´¥c¹FœÐmIðS5íîEDök¤Â¦»uS-±ÞB²’ÃoL³¶q ®dzÍOºšvû„>ê´b©¨µÕÙ ¹tx펄TÅ´«G$—,7³°Iøˆ‡‰‰wÛï¾ü¼9Š™xÆ;“È¤Ç „/0P°p‚o½AÎîåpÜUïBAµÊ?øNãý Ýaßü†·ý¯£Ž¹ÆË-1¹rjî)"£^¼ŠËI„žØYx•QuòßW­dÏ–;$Ì¿Œ£ÑRX¬1ã<ÑÇyWnó÷;PöQûº‡Žcì9¦¨¬0ã¦ñwÖ…œýØC3T]úHN³>ÎÒso?–¢ ‹)Ç0©È‘ðÑAÃFšU3TíDóÕ¾mÀ¹ÝLzžBH–9{]ù=“ÑÙFX”Ù´ãcŸ¤ˆéžË·¼;¦¡Gù…âúÊœRC€Õ‡%a$L[ÞH>¼ê¹müH°›în6㊠ú««.*ÈbļvS¯¹IˆfŠºe”Vœ6Ù·¡uÅu·Ûv3ˆèÞ@Ô›¾²“Í\|Æî9ÇoƒyMsIÕF¶ÄûZž›ìÓý®m°‰šé¼C ¹o ¶ŠÑ`v‘Ý…k êqzañОuŽÎ¸J½ ¾öÚÂx²€–DlV¼YfI³“纪ôé®ù©ÈfâïíÛËù8÷ÌžTvY× ÆÖYM;¤^á²U²†IتŸÇÖ&={õY}I5»{˜­M«žÒî0ð¡¶iö¢õO%éôEŸnS¢âÅ(˜Çê«nX¡jb†³æK´µpH›EAVcEt…TÕP“µ¼‰¬z×®œâ­8\²1¤KŠ¢$’:@jª‚Ž"¢wm²¦¹wX¹Ai”WJ,–¦ 8ϼ‡Øž¡=%U#lÎêñ4(F#º¯r"ëÇ¿<½Íh¬ç1MMžNƒyZF£Áªe†Xv[iéïÜÓF †ænö¦•6Tòú%WØDf| Í`Él]eæ6 q³EOT× W|»,YÜs‚xw>E5­~õÞç¦A¢”¢gáÚPïB"i.ݓɼ_2‹7‹sr÷WÊA"+Åá¼)»ü4 UûªºþΑvèI¸¯’¢ù§Ñki[O ¾ÊôÁ˹ñ˜m§¦H¨ù‚"¸¢„»)uë®QÿÂwèNëÿä5¿è}$KÐA72^ˆˆžj¾I§hqV¤ò6Xä8þÏ6Ñxo*oî_RUOf›•ÊÖ­3FŽÅãJG +ÅEw“ÑÉD:t ü:k Á°–áÕ_çY V‰ºãb0à?hò22 ¡ÙãíO¼¨‰ç¢Åñ¼~=Í£_÷Ó4¸e¹V×ÒMžvsî ) *¯kIø`}²±l^Ôqo-V»“ñýK[¤ZÛH†ÝVEè ¯{rA±÷E Q6ÕUU]\¼“+Ée v!ˆW©:ÒkŸq–A7ÙÄÍ}ÐÔ—VYžxä[ÎqÏ™ms†=øõpÅ{ؤ­%ê‘Ø^¦Iû×72胷 ñ¬xÉÌ]s;⦑;YHvF«i^Âx'ÂLï$]ѳÛmb&$eEEWd‘‹k·ÝâÕ~1E‘QJ->ÛHQß«Xâ‚ÉÀÒƒ±´í&ɦ™~–2œIQÓ&Ç>§`d˱›ò5×ö‹P9w›Æ²Ü³Bˆwî@e¬’•ÃlÚr$±}°›» Á@ÑQWmÑwþR‰"’l¨½QQt˜ìv~y†Ñéëñ·Ù¨e/UÈäJiÕ6Ú<-«Ì½,öF/QÂî&6ÖÖåÁŸW<ÈÒMµúÄÛqÛ$TTQ1EEñM4Æ0ÈÍÏóãü{Z]QË9h¨/š'÷¨¡Üó‹àˆ;/ޱ,HFË"³—! UVUÅrÂï#½–¤ü“½Í×^qIÂUTA»•CSó‡âóŒA»óGèÐÍvû…1ˆÇºø™§µ4ÌþåK܆Ÿ4n::ãfÀ­F˜D@‹ÑZ{m¼4£a„b<™µé7´v–aµbصÝõ »klŸƒ¹&ˆ“ﻥ«vÛ³µï»ºk®A¨ü²ûu‡NP»ë?E(Øq§=ãF]1ß~ÁDÙ5cX[Ù–wÉq&þ{‡3…Uˆ^â³£)0n[©E§7&œeóüQê¾é¦at³2 ™z¨á1‹À‹[mQVòìÐÓˆëñ‚ Åâôw\S.Ž{£ôc8‡!ár¹‘²["Åhç~Wz-Š+ó£Ù‚)AŒÃ{,‡‰6íU×!bÜÇ9 nmÁ¦Ck(z÷+™ie,‘'«l(m¢$Ï¢¼Û@]â@ïvÉ»ó8Wæ'0­²Œ*ä _?&2ŠGÈwQa×M–§²à¦Š!xjö¿$£\[:Áî$ãyö1êzÁÒ  ò~õ‡›0u“ý`$Ô|︲ã^P¯ÊÞJÆH¶©²ú3QYœÂìˆMHEN5ˆq¯Ìž6ÔéY•´l{æL>9¹_kc)TcƲ¨9_qUI¯Q•]×ðÅùYg•‰iä±½@+ØóŠ¡±&3ž-¼Ã‚.6iÔIuaÁ<·#â³ZHå/ ÌÔ=8ù}/ksÙòIL¦Á-¤]ĽôÜ ¢ËÈc$šë˵TDŠ;ý„ Ii QÆ”»Ueë§lfÖˆã³âÊŒb'5_R• ½±‘2‰|MÔ· ˆÙA4BغnO¿SaјÒ‡%Ø®‹¨Üˆä ó'Ø«Úm’*¯T_PXX²SåbsÚ†½÷Œ`ˆ2MÆvSb‹êz$]À»{…ï"n‰©¹ÎEž·ucÄ’ö[¤çž&ûÎÔdWÄ•vEÃåc ‚啱o² ‹Ô‘ic1¡rD‰®äD&¤*¾â'oM—\có^Û›qu¯Ár°*G' ¹Tj&#ÔÒ!+rÁÁ[Ué×TùΖeæ¢-qv Hà=?#’óhãInäI Ùøm‡¼ªª¢%}Ëüµaï–óF4µˆªUøýP›•([¨²Ò®î9÷žss-úkù…f¹x½|8‡4ƀѾÿðÔÃGãØ£-¢“Ÿ–ËpQKÒ'6M@ÉksÚ¾FµÉBÁ0|F[·¸;´ÔXÑÌÈWï¸çh7×½Qzk=å>a¶©ÆržRÈÏ&Ì¥uÕFûmCXÔ—QφŽËm©þ¹÷/††@<ÙG6ÑÑ’†*Ú¶©Ü††‹ÛÛ·]÷Ûnº{æbú1á_Còù á÷&¼j¬[dÝ«äâŠÆŠ¿àÐϧr/òÇ·”ö?“QÈKN=Ï Š~aClÚ~¨ê»w}ךUíp7ë± ¯òÝ[8Ï/c úò£1ºW_×n¢ÝÕ3„‰ê0î߈}“Ü o¢Âž»”f kÖmé7$Cv29ÐôÔ„N «ÜSKÑK˜xìÇ)»É‰˜µ­ eîH‰^Ëq Õ™:CŠƒ*[¢;µã¹.ÚUöõÖ?”WXr2åæùRc¸Uhú—¶î8¾ëké~*J›¸~=5VçÞ]ü›Ýåh®qæ9ŸF9œuÀVáËdÍÁH2ä¶f-¸Û¾öþ›Ê½ËÀyG,ðÓ¸¼?3ü¢Ó‘)¬¢ÚãRceŠ¥£ŽïssS}ÆÕÖQG̼7·Èò;iè¨"»6âÎBìÛ 2ÆEíö"'U]‘:®³®n™N-oÊ—1­qš·=Ù•ô•ñW¯û/:ÒÄ?«Þ‰¨2†Áº¹oN¯I½ïO¼ÁG%RîDí=ÑvîÙu‘UËqû'²¡°v2Ÿ7i¨o+݉ßݺíæ›m®X_ÿ§Ýÿ¡;ªFªc ëHU–uõÇ·d§k–4ÁŒ[ôÙßG³¯·T<ÃÁ–pÞ»äëj:íøÐ¹¢è®︯QºåWo¹§,ôɹNio6kËܽÆ1ã¶ëQã6¥ÕhôjwRXÏ‘€ÊÇÊpʲޘ4¤ì£‹:$r|Ì…—tQW¢ï×C"ÒÂ-drT~[Ͱ «àˆN¢®±Š|u¸ßæ÷õ˜Ö8õœ†­je«ÈË/Ì(J,Š®ê¢›—Aªš‰™óöF\Ó“Õÿ–¥u B´ÛNõ&j{”ôúþ$³stëÚ+©ð¸‡¶çH˜_if÷8‹`8ýlR‹$³$ô$ºË;1ÔRÛe ñ×úËùSåðãܦÈI¼—&YÍzEòòkŸ' —¸†l¨Ž“¿`ð ÄiÅhŒ{…UuiSâ¸þ-2Knȸº‡,'M E7M×›.ÔOx·]¼×Mcìfñ¤G%×ÝäÑ_„R+&z(ì[kç¶Y2ír7¦ã.4ó.ª¢îŠš¦ùWãb~£ñ(1OrØ…ÚU´ŽnMÓ0è¢ ÎµØ»‘?vÊ™öõDÕN7W1OCC šúj¨ €Ìh±i¦Å<Qú:Ë×dcÙf8ñOãþD«í Z+ ¶G£šýöÏd™?qÑè]{H[âq­cäËÉ¢ _¯UN—@}ez!¯x/QEO¦Îúê`WÓÒÅzu¤çaf;¦á¯Ø)áçá¨ø¥¤wë3™è‘rÞ_ÔdbüG\òþEŽw'Vdݽø"**‚¹Ü=LñÞO°…o f±M$Ga;GЄê÷¶ƒ²(»·EMCÃiùK5¨â&­«n&póÓ³¨Wª¥·6+pŸžÛÒà´4@Ëݪ‰¶É®3®äI9%w9É•ÌWX“&ʳ ΞA²Û2Mc7;´ÝQdöíQÑNùoù¹ão˜:ÄÜÇÌcŒK†CÅét†Ž!mæô!_n£]sw ơœ°‡W3q|‚5ÌØ>cˆn·`6o8#Ü€]»¦ú©…xìé6÷Î<Ý=O_.ÖÊZÇ'ɘpšuÒÑQH»{StÝuȘëUÙ|+«¬jÒd ø•ôRrDˆ®6Øw9w"DÜ•<×XÕc‘oŽÂ%\(ÏDf‚Ý×=V˜1ÈŠ„¨H©ÑvÕÇb¸Vwqo.EuÎN¼´¡›SSSmX߯Ñä°]ž,'ÇGšÃB@Ònûj¢_´—œUÊõMã<у´Ùäu­oðWM}6/j$OV,•N©÷š=Û4EMr%wúЛÆpLB¶iv1l¥X:çÃ=-T#£n5±6}TS§œ‰\¥s‹e9[Œ›2ì9ͼžöB(±Zç«Ú«º¢$x¢ºvª/]Ûb•ç="Uô¶¨Ð °û²# “¼‡i”LGbصÄÜCÈáqÊøÛEÉ—Œ-ò¼f']z–ݦ”JT¸„¤-¥ƒD„ŠàûÔ“°*åàÓb'äATÛacªv«bȈmÔLQQwMõ#åÌàñÿØ…†OǼ†m9/ >ð”¼~ÿ'mØO8çk®wl˜(ºŠ•ÔÌKb’F]j,Œë&ÖúÞJûÎÈç{òŸ5]È—tý‘ÓØFLÎmùÄYÃy&ÊÚrvŒ ·â£ÈVÁôVûšGDTw1«¹ºi«ÛªfYkzlf†mMŒZÆvèm¯»e„cÖ…FÒ¤™ÏÖÊ6¥°¯ºÄ“f8¹è·ß²ûÛc×øí’Gs$¯üÎÓm‹PÞM«ŽDïWwO¼ˆ£õégåœuMap‹¸_´ÇÀÙ' èjÌ„Tö÷êÖê³–¹;Xäêû #ír9 5†DÃâµÿ.³ø‚s½ý½Ñ>‰¹þ®¸6À“‹Ÿå°n0 ¿ÄMI‘W Ë8ìYºÿdgpÉ£‚b†ê¨Š»o£4Ê8Vì%øŠ‚/joýêÅÔÔ¯š&ki òá2&kA—Ü« mGéQ«hgExc¸ÛÌÉ‹"2â¾öÄ%ÑwÓ™¦c]r ´p ³:øVãH±}ßuoðÙî芀ˆ¤"=äj›é‰/D“ymc6-]1Z­éÓ¦©¤v[GL‘³%7EIUzh0rÇU¾-É*.U’5éül'䯒®ÅhÆBô=›yZÙµ÷QÔB Kƒ8;LÓ¬Y’8&+!ÅqªZÙzOµ™Ú§½‚Têj¦êˆ€÷—]Y=*̳.QÍ] ü›É2›@“i0G`iëèDŽŠ Ã½ =z’’¯ô7X} y‡À›y— 6!!]ÑQS¢¢éüÃå—"ƒÆrìæ$Œ›ŠíšvFcÞIë=; ŽÖ¾¨ª½Ñ¿ •´ÝKMq›†rê®$É <ù†ËÙN6KÉ3‡º®¨;»·‰G @ý5-…ÎÄ$BEÔÜ{,°ÆÛ¯¾™lçä,ÊXSr úé«^J·•ßuLMxTt[#ôÅ[*l©©g‘ãuö²æVʧvÑÖㆠ֙ 5-lL ‘{ û&_Ð ©6›–Ȥ‹¬qÌeBÿ‘q»øY–3QÀzCqÔ9ÖSž@UPŽÁÐ2-‘{¶ê½4ż=þÚ¸'DßÇÒ’Â:ÿjI§~¾(”¿Ï)ÅÖM—ÑÕ¥ÕÆ7,úúÂC qÆ™¦-ûä›™ õQDë œîsEÍòæ5hãWÔm7 ,yñ뛟¤Ù„RûŽbzˆÒ©!ôATUßO¥%En˜Ö½kŠ­f%¾79`Ûæ>Ø<û( ûƒcÚŠ¤½»¬š®JÈäE¢nÖ¾U”³l°A‘-» -@2ó0ެ«MI"?\K¦ê¹'2ÇóÚüʺ$L¢0‘£½%ºô®›0¸Éœ&ò’®în^*º¢âJ®#ĹV—Œ5x–{üL˜ó®×0‘3¯(_m´pÚ5CÛ»ÅWXÏ"ó­Í?Ài)Î=ãLH$-Ul¹­+XL™/g¦IôU[ìÛE%Ü•uÑv_%Ó?sÜÇ%ÕmÑšÌɶû¤°ž@6m¨>×@‘(*¤‚*‹Ý×U|òýòùšf«!³‹#½ ÅÚVáüƹce»+øuQUQwÇtNî¨y‚™Ý•þ4â r­ƒN]ü¤)ï §BF…ü—GKŸ%Vþ³äÃkºdÂñï™5Õ9ÖuÂ]N©´ˆÕ…eœwbXÀ|PÚ}‡Á[u§z˜’¢¢ø¦ ßÝ̶åyø»îDËIUØÅz:E5tÝŸQTˆu ÕíEéþåTTÝÅ4Vy‡cïÞ©V°U¨~Gù…iFª›ôÜôKÅŸ2\ƒû³Qq.&[ZÚoÐE›v}ËoˆÒ¥)q_!°Ú/i^ÑZc²M<޶TÆÑõ{j×0– (ÈíÁæì.)ùJ¡ —çÒà î¨ÕR¯–“º¿…±P_~Ï µp~´áÅÿ„šEÊ~eñ¼Q²Oňa@ó»ù I¶#oµZ] òg/rŸ)ïþqY;!*zÓö§ÂQµ§Ô¦º yÄ8¾7` ¿çm@mû_Ê|„vI.þ×?òŸÿÙlibsynthesis-3.4.0.47.1/doc/SySync_script_call_flow.numbers/document-thumbnail.tiff000066400000000000000000000257041226375725500304020ustar00rootroot00000000000000MM*(îÿÿ·ÿÿÿ·ÿÿÿ·ÿÿÿ·ÿÿÿ·ÿÿÿ·ÿÿÿ·ÿÿÿ·ÿÿÿ·ÿãÿþŸþÏÑÿþoÿŽÿãÿþþ¿þÿþ¿þ_þ¿þoþþ¿þoþþŸþþ_þŸþûÿþ?þÏû_þïþþþÏûŸþÏþoþŸþoþþ¯ÿ»ÿãÿþþ¿þÿþ?þÿû?þïþþ_þOþþ¿þ?þÿþ?ûÿþ?þ¿ûþ¿þþ_þ¯ûþ¿þ?þÿþ?þ¿þÿ»ÿãÿþþ_þþþ_þþ?þÿþ¿þ_ûþ¿þ?þÿþ?ûÿþ?þ¿û?þßþŸþOþ¯û?þ¿þ?þÿþ?þ¿þÿ»ÿªÿþ¿þÿ”ÿÿÿ·ÿÿÿ·ÿÿÿ·ÿãÿ óô÷Üßèóô÷èêïõÿÜßèóô÷ÿâÿÜßèÜßè˜ÿãÿŠ©ÅÊØÜß蹿Ð\j’ÐÔàûÿs¢¹¿Ðþÿ­´É¢ªÁ¹¿ÐÅÊØÜß袪ÁÜßè\j’¢ªÁs¢†ÿS¢ªÁ­´ÉÅÊØóô÷¢ªÁÜß蹿Э´ÉÜßèÐÔࢪÁóô÷­´ÉÅÊØóô÷­´É¹¿ÐÐÔàèêﹿÐóô÷¢ªÁÜßè­´É¢ªÁÜßè\j’èêïãÿãÿÜß芩ÅÊØ¢ªÁs¢ûÿÜßè–Ÿ¹Š©þÿgtš¢ªÁÅÊØs¢s¢Š©¢ªÁs¢ÐÔࢪÁ†ÿs¢ûÿG¢ªÁ¹¿Ðs¢s¢ÅÊØ¢ªÁ–Ÿ¹–Ÿ¹ÅÊØgtš\j’¢ªÁ¹¿Ðs¢¢ªÁÐÔàs¢¢ªÁŠ©s¢gtš¢ªÁÐÔàs¢àÿãÿ¹¿ÐŠ©¹¿Ð¢ªÁŠ©ÐÔàþÿ)¢ªÁÐÔàŠ©óô÷s¢¢ªÁÐÔàs¢–Ÿ¹–Ÿ¹ÐÔàgtšÅÊØs¢†ÿSÅÊØŠ”±¢ªÁÅÊØs¢–Ÿ¹s¢ÐÔࢪÁ¹¿Ðs¢ÐÔàs¢¢ªÁÅÊØŠ”±s¢­´ÉŠ”±s¢ÅÊØŠ©¹¿Ðs¢¢ªÁÐÔàgtšèêïãÿÿÿùÿ–Ÿ¹Âÿÿÿ·ÿãÿ§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§ ¹Ô§¹Ô§¹Ô§¹Ô§¹Ôãÿãÿêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóê ñóêñóêñóêñóêñóãÿãÿêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóê ñóêñóêñóêñóêñóãÿãÿ—£»êñóêñóÁÊ×êñóÕÝåÕÝåÕÝåÕÝåÕÝåÁÊ×ÕÝåÕÝåêñó—£»êñóÁÊ×ÕÝåËÔÞËÔÞàçìàçìÕÝåÕÝåÁÊ×ÕÝåÕÝåêñó¬¶É—£»¶ÀÐËÔÞ—£»àçìêñó¬¶É—£»êñóËÔÞËÔÞËÔÞàçìÕÝåÕÝå—£»àçìêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóê ñóêñóêñóêñóêñóãÿãÿ—£»êñó¢¬Â¬¶É¢¬Â‚­ÁÊ×n|Ÿ‚­‚­¢¬Â—£»™´êñó—£»ËÔÞn|ŸËÔÞx…¦—£»¢¬ÂÁÊ×—£»‚­¢¬Â—£»™´êñóËÔÞ™´¢¬ÂÁÊׂ­àçìêñó™´‚­êñóx…¦‚­¶ÀЗ£»n|Ÿ‚­‚­àçìêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóê ñóêñóêñóêñóêñóãÿãÿ‚­—£»¢¬Â‚­¶ÀЗ£»êñó‚­¬¶É—£»ÁÊ×ÁÊ×—£»êñó—£»ÕÝå™´¢¬Ân|Ÿ‚­¶ÀЂ­n|Ÿ—£»ÁÊ×ÁÊ×—£»êñóÁÊ×™´™´ÁÊ×™´ÕÝåàçì™´¬¶É¶ÀЗ£»—£»êñó—£»‚­¬¶É™´ÕÝåêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóê ñóêñóêñóêñóêñóãÿãÿêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñó¬¶Éêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóê ñóêñóêñóêñóêñóãÿÿÿ·ÿãÿ Š”±¢ªÁ–Ÿ¹èêïþÿ èêﹿÐèêïÐÔàûÿ èêïóô÷¢ªÁèêïþÿèêïþÿÅÊØÜß袪Áóô÷Üßèóô÷èêïÐÔàèêïèêïþÿóô÷Üßèóô÷ÜßèèêïÐÔàþÿÐÔàþÿèêïÜßèèêïóô÷ÐÔàóô÷¢ªÁþÿÐÔàÅÊØèêïþÿèêïÜßèÜßèÿôÿãÿ¢ªÁþÿ¢ªÁ¢ªÁþÿ ¢ªÁ¢ªÁŠ”±¢ªÁûÿ ¢ªÁÐÔàgtšèêïþÿ#­´É¹¿Ð­´ÉÐÔàŠ”±ÐÔàŠ©¢ªÁŠ”±­´É¢ªÁ–Ÿ¹þÿ/ÅÊØs¢ÐÔࢪÁŠ©­´ÉЩЩÐÔàs¢¹¿Ð–Ÿ¹¢ªÁŠ©ÅÊØŠ”±þÿÅÊØ¹¿Ð¢ªÁþÿ¢ªÁgtšÅÊØÿôÿãÿŠ”±¢ªÁ–Ÿ¹­´É¢ªÁŠ”±¢ªÁ¹¿Ðs¢ûÿ ЩД±Š©ÐÔàþÿ#èêïs¢ÐÔàÐÔà–Ÿ¹ÐÔàŠ”±ÐÔࢪÁÐÔàÐÔࢪÁþÿ/–Ÿ¹Š”±¹¿ÐÐÔࢪÁÐÔà–Ÿ¹–Ÿ¹èêÁÐÔàÐÔàÅÊØ–Ÿ¹èêþÿÜß袪Á­´É¢ªÁŠ”±¢ªÁŠ”±ÿôÿÿÿ·ÿÿÿ·ÿãÿêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóê ñóêñóêñóêñóêñóãÿãÿ—£»êñóêñóÁÊ×êñóÕÝåÕÝåÕÝåÕÝåÕÝåÁÊ×ÕÝåÕÝåêñó—£»êñóÁÊ×ÕÝåËÔÞËÔÞàçìàçìÕÝåÕÝåÁÊ×ÕÝåÕÝåêñó¬¶É—£»¶ÀÐËÔÞ—£»àçìêñó¬¶É—£»êñóËÔÞËÔÞËÔÞàçìÕÝåÕÝå—£»àçìêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóê ñóêñóêñóêñóêñóãÿãÿ—£»êñó¢¬Â¬¶É¢¬Â‚­ÁÊ×n|Ÿ‚­‚­¢¬Â—£»™´êñó—£»ËÔÞn|ŸËÔÞx…¦—£»¢¬ÂÁÊ×—£»‚­¢¬Â—£»™´êñóËÔÞ™´¢¬ÂÁÊׂ­àçìêñó™´‚­êñóx…¦‚­¶ÀЗ£»n|Ÿ‚­‚­àçìêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóê ñóêñóêñóêñóêñóãÿãÿ‚­—£»¢¬Â‚­¶ÀЗ£»êñó‚­¬¶É—£»ÁÊ×ÁÊ×—£»êñó—£»ÕÝå™´¢¬Ân|Ÿ‚­¶ÀЂ­n|Ÿ—£»ÁÊ×ÁÊ×—£»êñóÁÊ×™´™´ÁÊ×™´ÕÝåàçì™´¬¶É¶ÀЗ£»—£»êñó—£»‚­¬¶É™´ÕÝåêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóê ñóêñóêñóêñóêñóãÿãÿêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñó¬¶Éêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóê ñóêñóêñóêñóêñóãÿãÿêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóêñóê ñóêñóêñóêñóêñóãÿãÿ§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§¹Ô§ ¹Ô§¹Ô§¹Ô§¹Ô§¹Ôãÿÿÿ·ÿÿÿùÿèêïÂÿãÿ ¹¿ÐÜßèÜßèÜßèæÿÜß蹿ÐÐÔàÅÊØ¹¿ÐæÿÜßèÿîÿ¹¿Ðs¢¹¿ÐèêÁ–Ÿ¹þÿŠ”±¢ªÁèêïÜßè–Ÿ¹¹¿Ðãÿãÿ#¢ªÁŠ©ÐÔàÐÔ๿Њ”±èê±¢ªÁ­´ÉŠ”±èêïþÿ#ÐÔࢪÁ¹¿Ð­´És¢Š”±óô÷­´É–Ÿ¹èê±¢ªÁþÿ;èêï\j’èêï­´É–Ÿ¹èê±¢ªÁ­´ÉŠ”±ÅÊØŠ”±Š”±óô÷­´É–Ÿ¹èêï–Ÿ¹­´Éèêï¤ÿЩД±ûÿÐÔàŠ©þÿs¢ÐÔàþÿŠ©óô÷s¢ãÿãÿ#¢ªÁÐÔàs¢ÐÔà–Ÿ¹s¢ÐÔàs¢ÐÔࢪÁ¢ªÁÐÔàþÿ ÐÔࢪÁ¢ªÁ¢ªÁ¢ªÁ¢ªÁÐÔà\j’–Ÿ¹¹¿Ðgtšøÿs¢þÿ/\j’–Ÿ¹¹¿Ðs¢ÐÔࢪÁ¢ªÁ¢ªÁ¢ªÁ¢ªÁÐÔàs¢ÐÔࢪÁs¢óô÷žÿs¢–Ÿ¹þÿÐÔàŠ©ûÿŠ©Üßès¢þÿs¢ãÿãÿ¢ªÁþÿ–Ÿ¹ÐÔàgtšŠ©¹¿Ðs¢ÐÔࢪÁ¢ªÁÐÔàþÿ ÐÔࢪÁ¢ªÁ¢ªÁs¢s¢èê±¢ªÁÐÔàs¢øÿ2Š©ÐÔàŠ”±¢ªÁÐÔàs¢ÐÔࢪÁ¢ªÁ¢ªÁs¢s¢èê±Š”±ÐÔàs¢žÿ¹¿Ðs¢–Ÿ¹èêÁŠ©þÿ¢ªÁŠ©óô÷ÅÊØŠ”±–Ÿ¹ãÿÿ÷ÿÐÔࢪÁ‰ÿÐÔàÂÿÿÿ·ÿÿÿ·ÿÿÿ·ÿÿÿ·ÿÿÿ·ÿÿÿ·ÿÿÿ·ÿÿÿ·ÿÿÿ·ÿÿÿ·ÿÿÿ·ÿÿÿ·ÿÿŽÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©ÈÿÿŽÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©ÈÿãÿÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©ÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÝÿÿŽÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©ÈÿÿŽÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©ÈÿÿŽÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©ÈÿÿŽÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©ÈÿÿŽÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©ÈÿÿŽÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©ÈÿÿŽÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©ÈÿÿµÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©ÈÿÿµÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©ÈÿãÿÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©ÊÕåÊÕåÊÕåMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©ÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÝÿÿµÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©ÈÿƒÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©ÑÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©ÈÿƒÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©ÑÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©ÈÿƒÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©ÑÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©ÈÿƒÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©ÑÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©ÈÿƒÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©ÈÿƒÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©ÈÿƒÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©ÈÿƒÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©ÈÿãÿÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©ÊÕåÊÕåÊÕåMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©ÊÕåÊÕåÊÕåMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©ÊÕåÊÕåÊÕåMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©ÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÊÕåÝÿƒÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©ÈÿƒÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©ÈÿªÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©ÈÿªÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©ÈÿªÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©ÈÿÑÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©ÈÿÑÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©ÈÿÑÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©ÈÿÑÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©øÿMr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©Mr©ÈÿãÿNs©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ns©Ýÿÿÿ·ÿÿÿ·ÿÿÿ·ÿËÿ¹¿Ð¢ªÁÐÔࢪÁ¢ªÁéÿ¹¿Ð¢ªÁÐÔ๿Њ©Üßèìÿ¹¿Ð¢ªÁÐÔà–Ÿ¹Š©éÿ¹¿Ð¢ªÁÐÔàŠ”±–Ÿ¹óô÷ìÿèê±þÿ¢ªÁ–Ÿ¹óô÷ìÿèê±þÿÐÔࢪÁ¿ÿËÿ¢ªÁþÿ ¢ªÁs¢Š”±èêïìÿ¢ªÁþÿ¢ªÁþÿ¢ªÁéÿ¢ªÁþÿ ¢ªÁ–Ÿ¹Š”±óô÷ìÿ¢ªÁþÿ ¢ªÁŠ”±Š”±ÐÔàéÿ¢ªÁþÿ¢ªÁÐÔàÐÔàéÿ¢ªÁûÿ¢ªÁ¿ÿËÿ¹¿Ð¢ªÁÐÔࢪÁŠ”±èêïìÿ¹¿Ð¢ªÁÐÔ๿Ðèêïéÿ¹¿Ð¢ªÁÐÔàŠ”±Š”±èêïìÿ¹¿Ð¢ªÁÐÔ๿ЖŸ¹óô÷ìÿèêïs¢èêÁ–Ÿ¹óô÷ìÿèêïs¢èêïÐÔàs¢¿ÿÿÿ·ÿÿÿ·ÿÿÿ·ÿÿÿ·ÿÿÿ·ÿÿÿ·ÿÿÿ·ÿÿÿ·ÿÿÿ·ÿ nn)€(æS)–‡s()œ(ADBEmntrRGB XYZ ÏacspAPPLnoneöÖÓ-ADBE cprtü2desc0dwtpt”bkpt¨rTRC¼gTRCÌbTRCÜrXYZìgXYZbXYZtextCopyright 1999 Adobe Systems Incorporateddesc Apple RGBXYZ óQÌXYZ curvÍcurvÍcurvÍXYZ y½AR¹XYZ Vø¬/XYZ &"±plibsynthesis-3.4.0.47.1/doc/SySync_script_call_flow.numbers/index.xml.gz000066400000000000000000002210461226375725500261760ustar00rootroot00000000000000‹ì}ksÛ¸–í÷û+RΗ™ª‘Ã÷#3ž[qÝ©J§S±Oç~ë¢%Úâ‰$ª(*‰û×ß lI€‰²( ™©>–H û±öZÿó-/~„É&ŠWWú¥vñÿ÷ÿüÏbózO·Ëp•¾€V›×›ûàêbž¦ëׯ^ÍÂá"^‡Ée°^/ÂËi¼|µ –áfLÃÍ+8õ"ÿU÷e¿ùµ‰òýüùóò§y'¯ MÓ_ý¿?>ÝLçá2˜D«M¬¦aö«Å¦ë•›‹0¾|Ì.´ìjŽniÚÅ èûëï®.>ݼcãÿ#ž…‹ ‚ßÓ4ú^]¼÷ß_ðßZ׎ ?ÓmïÚþ`zïß¿û`¿ñá+zòÏh5‹Â=µ^è®þB·\÷…¯/4ø?ÝÑà?ºë½ §n~L~F³t'ûøcøfFóôêÂÐmúÕ¯« [×/Møg™¶f{¶ozôÈãÕ…i¸¢#ð'Ó)v±iNÖI ×Ñ,×Ðý‹ÿ%z“>.ÂÍ< Ó|ü7nnòoaôÿû?›{výóG8MãdBÉýèö/ú=ý)¹gpf4ƒItu‘wÛEL®aTáä>ŽÓ0™ÜÅ³Ç ßÔ$šá¥ “0¿ÒÇÉ2XÓ/b˜[QúHÿ^m—waB/‹ÂxðÑ¥kx<÷¯þ÷`–~tóáö&MâïáÖ4ùŠÁW<‰u~‘n."øß« x2Ðfö è‡i°¾º¸Û¦)ýôï8‚wˆþG1qò&4ëéâ4XDwI†³Iòp7¡§LH¿q0íÒõ,S7]Ó3-Gó}9ö@Áö5øo:ž‡îÈ![wËÕ<×va2Ûº‰ÇàÅÕÉ!·5H¡s«úx¿à6ìõ<ØÀ}Ĉ÷4\®ÓGölð\vY“xÃ7ôæáßâß^ÓïI¼]ÍJBðTÙ ‰=˜fOUÒ¹fyÚoøÙÕyæÒÙT›¹‹møâ÷0˜Áb™MàM¸àYÂç,ÆÈg1!‡šÅ†áZ¶æ{ºk:ºgê.7‹MX¿<Ãt,XÒ,Ï÷Ø1:-ß‚¥f²¥ù–éklŠ÷™Æ8nÁ4ÞÄ‹|‰yöÓØMãOáìÖ´9È“±O`‘–aßò5ÝwtÍótO³-Ú¶ û¸Ö:°J°µìÀN|_s\Çs}vé¾ë0ŽûÜ×a\žªY‡?D‹Å©,Â8ŠÃ.Â?ç`uÔŒ b}öŸ{Øßs_<ÑÚ“Î=¶~ÞÅ YFǹûã޳xKea öŸŠ8‚s_©ù_›ŠÁ&š¾øÏñ‹ß’höŸcö¥°ÿòy¨]xÊ~î”t „Y3}ð£átË1cÏ{xîSÑ‘NÅÌ¢õŠˆÝ?ñ™ˆƒËþ\м<¡N=ƶE‘Å™ÆîåàXŽd!²:âÆ2'7¢Ž^—¸ÑˆŸ8†ã—G á¸Ï}§±¶Æœ;>£ ÝãÎoã¸Ï} Ö…i§ß’àñTâEl‡5¤¹'Ã4!dé®é›º­™ÌU¢¹'ÃÒ! éX u]Û éÇ<ùd˜.Ä=uÃ0 ¢o;;xXlÜg?ÅÙ§š»?âÀ“Þ–w: ŸâÜM]˜FÂ<þ¨}Öñ#ÇËá³qŸý:*ÏeYüSâ#Šã ÍY6ð³ŸÆÂD±g«`”$øx&­J`$ A0Öà tÓDþI¬ÃmY,´y÷Kaɼ²a²©ì1œ½AÛÄ:‘„Þ–ÈØwØ|*ÂÙoï X “@v ±¨âßõSKScGAS pÕ22ÄÁÉLó¶ÔØ>Óœ+l9°å0®D×±æ£!®¯ttáO6GË:¤Ø¬C‹OlËw¡ÈÄq5ê¥gõUú7 Oƒ˜UÊqA -¾òa¶=MØ~VlàçîƒÂ$Wf5Œ¿<õÿHó×µÁÐ- ¤t×w²¬£Æ€äXc€ üìç¯0)VŠÊŽÚkÃz¥£eLÛ E~`lßuùÂ*ƒ–¾Â"kêºp¾2Р(nÇs`Ú›šåïPÈ~îaDÀW^Ùú;âLëøa ܧ›3–É}4ËX˜2c1µ‰ðm³!"¼R!™ <†ã‚•Áp^Ô¾°üJ1 ‡«,ëYÅw/ûBš1;J°áXHrVU-?¬€Àr;yÄX06’Ã,ØOs`£8{³W˜:c+ë¸ Þ¶ŒÙsMSã*;Ú‚*̳UÒãžÁm‰¶}‚·'oùŽ+w4ËW\F̆àÜ2™…{:SA¥ËæËh/%s˜¡-SvPsá˜ù‰q%׎e.˜âäšÌÿmžãĽ/6Šs÷¾LaÒ¬£;ÛÆasgƒb):A²£›M|‚ãOÙ²îvÚI#ªG*²%+p´-]˜òÊcWãÝÂZvÌyûü‰ÆÉwÊš^aÒþtó-;ÂqiÀÂ>] :§Ù[D‹ægòÝJÃè’ks—»ŽÓ4^þ$ѪžÙf¸© ëv—Ö¸s°óãj¦mDðTæ»CcÜ)_ZðîÈ>ÝÚwÂÛ`õ#ØÜ@è¡Ì:Þ™À¼C[ü)ñ*²õ®'kŒ»à¿6áM$)ÜÒð3ebo{‚âÅ¿{“Ü™ŸÂû´Û<5NO>O%m•Ÿ5âŸI79HA0¡×h£Œ¿¼W«å[ó%‰à'8ìM¯ËçÔl[äNü@ùúzGeq×ûJ¤†z¸²Æ*Ïaèç*k»ìm¼î6Èö•VÜTiéõ¢–"Ø¢©+}ñÅ<ü• ©3¿)æá¥ì'ÂaΆp$Çãx<lÜgïwt¢ï=•¹ÜV½OòÉR4¦"ó¥†BèQ§ÂYÇO=ª=.dƱrÖ¦˜É7Wyq–uý°;û ‘ìqÁ$Ž l¬Y>T%–¥«~ãˆõGlàgoTŠÑŒ”o¼±ì£Â*Žè )T18-9ªbÌú%¬Û'nn²QŒeå<–¹iIÅO‚†Œuÿ°&§œÔ=ØŸ}ÇõuÍå%- ¤ImÝM<Íp,s2eRÇq4à„6¡âX£u{‡ÂM6ðsÇ¡aµpSD9vÉÑhÎV‚Ì>–…øXN˜ÕÎÏ{ žƱäãi첟ý4'¨*HáS`8µÚJŽO"¶ÏFqöv‚8ë”GUO$ßdµå›†¨Ã2ÂÊ:|ö«bS¡ðIlëçZ/ŒÌ’gOkj ³RÊòÑÆZÙk˜ºtJ“Sár>2ìjmõêÿ‡âŒð~ؤIü=Ä¿o>ÜÞÐ%Œ|{L¿?$ñvµ#üSÒ„ôÄË‚wFž‚ßͺœse6„swºminÁ¾1bª.Öý“žˆÒRݳ²!mi–èT@ólÇ™‹—ÇÁeã>w+Ò&‡ +òDX<Ù0›ãÒ¢d>ûé']<m,;6ÔCXÈKÄ·0KÈ´$ÇP¨Fü»>ܱlàgo… S?5ªÃÑ.í¶œÏ>yÈS':d7g, ô±P|¶0¿T³F(ec8މ;ß/M—»%Më¦ÝÆ+;DŠ]¯?¦¹ òM4zÚ¥jì`R6ùZŠ‘ýÔ™å²výuÀX‡Ç² ŠHð*œùšˆØJ„uÿ8[ø¥q<4>ø¹»ZŽ4óôi­6'1Ù0Ž5§Æ~î«°#'–ͦñ‰àEÙHÎp&+ŽZbÌ:Âı'^|ˆ‹pÇØ;ƒ‡L°Ÿ½) .g*KoŒ8ùï´ÑÌîu}2f'6бlèÇ :â¢$âV:$Êú}ØÅoŒÕÍlàg¿ˆŠ«–(öùâN[êê ±ÔãaŸÙ¸Ç²ì+šå´d¥Æ½ö³âi˜t»ÿg¿Š¶0êå èÑBœ§ÈI ê©\u¿ÅµK¥pþx'ÝQ9õލùÆžÚÙ/›ÒÊ¥1““9OQ´4Æô=ø¹Ûœ®˜S¯\.:Ú5—õþHÿñ&6¼-ІãW•sq‡ÀCZª¬Ãç¾Ù»âD ×ß?b½?qFR6б,‚Ç Ö»âÌô;üŽ á°uNR#Ô´Ýÿ7ÏðM’¬äD7|ϾRË´¡ÅsyVR]ó<à+õótGCì@ðºOÉ øX¦ð±Ÿ®4ß”ã Fûdý?ì..Ï;Ä‘ üìço [Þ¸'ï1“NÃî]%ÈD§®X‰ —N ‡ÇFr† ª¢Ï£3Y^5îµô)O2C` µT¥¢è §¢d¼Ìã¶e¥N—ÇžÆÙGääx• ~Ü«äQsNÆñêE\E¸GÖV¯½ìiÄ4¬÷G²M=Ót4Í´ Ã5]ÝЙ6ýr 1~á±>Á*6ðswö=¹Ô˜gíS$š¤!ª#¢SØã:ûYÛ.ü4þ¼•‡ƒ8ÒÒ{Dà üì'±0Õ•QSÚæõYuê¬TìæŒez+“ëÉÓ`åêÓײ1g‰&ƆpîÁOšÔ:`6‚ãÌEB¯¢ûŽ$+&Ñ/­Šj¶çŽãY¾­—`p2ùç9¶iÀ`±S6𱬧ǂxM*R'`í³¢êÒ·èü¥ O³Qu”¡b|Ýu,”z]ÓÐ-×`Ç0Ѐh_s\Çs=ÓÞÛÙ/ÀÒ:¬¬˜uì¸.¯-†Fñ~´jÒ ƒ¥®£{.L˜&¯6mÃìu @]†c» =Í©MCXÍ·\ø‰¦»º§S£¬¬‹û9¯¿ÓèP6)„séÝùøîê´­Þ·7äˉ<ÄKMY)+Ú˜D3¦Ï•Äë0I'Ë`M%¯âu0ÒGú÷j»¼ z=üóê¢dªß_0]/þG|¯25¯wAÞFËðCœ,ƒ”¶ ê_Ñê¶^]üñjöêññÅüõrù"ÈšîØœè4¼ÚíãDÆÄ£1ž7xÂIWQÓE+­‰.ø%H‚‡$XÏé#¡]g_UÝ·/å³»?À¼IœäQRÀ W)|‚ÿ^]TOb>»ä¡ÿŒ“Ùßä1|Ó9¨­=ÌáÁB›ßÃpý)Z…›ÛøŽ„ ~½9¾¹)7ü,¢‡Õ®+»Ïì•®ÜåòÏîãUzý#}Vºxê•~¶ˆ6iqïWÛÅ‚MÐòLú·Á;%›ô6^GÓÏtŽã· 8& :~d·ï6¸»Iãõ¿Lã©ðb¥ïãmJšùþIgø¦¿E³”Ýh2ŠÏÁ/x5~?Â4šŸÃm˜ÍÒÚèÓÛâUî‚MH.|3îSüŠ~$¯÷ê ü•Þ̃Yü³Ò³·ñ"NØÃÌïa~KŠ£›yüóãêöÏ·ÙtIVyãùtÚVÆYü|J.óâ×&bïy9ê9Ó4ÁÐq!#㛺­™F3¸ þ½†{{„Á÷ëð>NØ yCdk•>Ìü ].ùß“eõ[”Î?ÃüÂ˰Û+¼…µc¥Yöçýý&d­€]GÍ?AÅl‹ð¾t×èrGÖôüVе0ËW®Ò™ÙÖ.˜Rlk¼…Ñ}ƒÝ°$éÙfRL+[°°ÑÞûq¹†9¥Ãnú’VEÀ݃³pp¨à:+„7Úø3Ù¶'MpƒDSŽ}•G/ÿëåKíòåË—ÿ=ÉÿäÏ›…ôš¬0Ù6•F¦ÛŒƒ)X€ñ .ð¯›wüOW!,)Ñí‰êõa‰Ÿ¤óx» V³Í$÷€®.îƒÅ&äÛ¹‡…ŠL¼I0… ÓÇ«‹ :l,ÛMHŽšk ‹Qv9l‡mÔî¬è¤OÁ#¼(Å~¼ ŸëVw^w“ k²·Jg4[?ÀÞ†|ñ&³šp XF«h¹]þ'Ñ?°ª‹+x±¥–+o·ævxCØÁV u’„÷l®~}ÿøC53ªdM¾¾]®Ø2¼f3xÚl5¥s/i~ÇXWW˜u$+Wö÷]œ¦ñ2ûD·ò!—..ãü#H¢¬ù¾V#¢½¯zNö´ÈBÄÌ(z²7E«-¼Y'JžYT¹)(_?«×»l)øx.|:z‡ÛÜÄvæXVÛÀk¯üÅŠ÷;&±ó“¤OQ9°±åë¤r OS9€È~FNc§È]nf7ƒÊË$·Ay™YäGy™\x=óaOÕËDcAy™Çð2ûjÊÕ,2(=óð¤ÞëN®&>åjîçjB¤u»’zR‚¸‹ÏJ’3³';9‰Vr°úËhe—+D#óôƪ™LˆÑž¼ íM¶ˆï*’£¹iz:™8:´ê ,îܨƒ@•ø ŸÔœt¿—S|/}dh™ý²,Y„ çHæi.[tÀÜ£8Ù©²ä¡ªìc‘œÌÝÂÎùåHªt% Q']9¬Ñˆßs7»YL`Z½ ïƒí‚€% Õó–¤ôÚò¼¥”‡Zµ4‰j+f©àjÂ]x¼è!ê³~fp¹R_Ûr&-&6£'¢r&UÄà˜r&Âr¶Â¡(ž$>Æ'MvMaæf®„™ëJ=<>°›Ê[ âR¡ã:N¸®è¸:êè¶’;Fྦྷµ "÷\äÞ„³WˆäKI ;“Ü»L£û{:ggÑ~òˆø@zâ¦Ã¯HO¡cž…¤üP5o“)\‰¢¸:¿ßdŸ-Ýö%É^Oçáôûf U‡3ý»C6T€îm Ê•üž-©x×ò¿ÿ(¸ÃÅ”¸J–¦‚å×§BSÓEH¥KâžQ^×9RØÄ¶Ãs IïÐ V~[§;ë#¾¨7!q,à%à¾Ûyˆ³šj½Jö^CIu8ƒÛ·iÃNHÝè\“´S_}†™p®|í‘_ Ú™Ö›Ôc54ó7±÷Uà¸nÂSø®J¢õYHÙJ‚WéÍ6¿†dQk›/Ò>JšEW», ¥ë0=ÅþXk­ú¨vè¶Ø˜ Ô¡ê™PÎ1as„ì§5lNþGŒÍéÄÙ¿,ŠK±`5±`)D⻢+Šâ»"¬jŠï ;G^‰Wɉ·v}RŠ£HílvNóÇ¡sý-Œ—aš<–âìK.ûîÍý=w:‹Æ’HÂæS<ýÎ ¨š³,º.Äà „Œ7 óZãQ…è­£±8/ž°Ž7!¤­übÄ‚Ákà¤M‘e}­Æõ†—‡l°¦g˜¨¼­ %ÈÅÀ7ý“Ž#{nF$¸™F9v+Ù¹Ÿ—C¿mè5Áʳ} "¡³Gq›åp#9‡Ô¬—K š™x¥>ˆvé;†iù9÷ Û2}‹jg:‡,ZË…)…ׇ.þ¼Ók „%£S÷fáBùR’`HåuPúÐ<ÓÒ}6}Q¶Q·AíÃðlqmOcñmª¦àë¦ ñmÓô`8~…Œž §©¯ÕPÚ@a~`̯=rŒ®u ögç‹·±ø.—Èçb8~DqÒÈ,¾ù#Î(Q+TéáÌR-aCD3¯¢ü¸y‡‰«pÖk¤÷ &3BÑÜà¸í™¶khPg .<8½‡¶zÁ;&-Ø&x‡@âMUóŽÿZ${ÇŽ3Š h†õ‡U¾óE>­ËÏzs>âw½î…Ò¿[°m°øYѺÉ᱌/àßo`%ݰůÒ9kUÄZá$ð˜G³Y¸Â¿×D5/ ƒï|Ĺ”æ2*bÍrâÂrj¤Tãê9Õd·1Pñ:µHÖgjÌbˆ›ÎJuñÑ~¢AÃL‡±UªÈX rçMv°3TÈ–ÙæþÖ°"ö\TÈvoÀù8C¶Ç‘Sà¦bø– åÐUN¡WäN2õ%´®†P ‹X >ž¯¹ Á¾¢b6µº;³E0jùJk†ÐÁ¬mt 0ÞFËÛêˆÃ[øçÕůf¯_Ì_/—/.Ú¥9ÑΉW»-a©âŸÍäêÚ¹µ‹VZ]°U¥’ÇK~ÏA¶•¦Ø@ñO0*À”*wZ©+*uÅ&uEiÉ™aš®ï¹†kú¦yY–˜¥%g†¥CÆÖ±ËumÃd‰YZrf˜®g¸ºaº~ ôÖ¬$ ¦ßa‘ÌB;JsQi.ÒÍCi..rµí‘k.J«ò‘ W¡ÛŽ‚nëcv© IÙ`= ® Ÿˆ ’ìÁØ]Æ“²CIÏI 4ßF7ßpm[7(é£𩾛k¹ž3tßgÇPàMø3%W·HÛÕäz ìtÊÔ^ž&í¨kç $W‡š•âî4]BÉÕÉBRFܧ“«Ãu|G¹:DM7ÉÕågTåê‹ÈÕv«éIÉÕåaŸzú§{šèÈ \‰&} ga2áA F E¸ Â}i¾•Zº©»º ˜|`ý˜!œù¡ûŽr¸šf9@÷3¶"j~è ‘ „E–mê@Y´Dø»¦_Ñ<’'Ó„*Q$€6y\ÏCêfÕŒ |BQ7,åA÷/ú‚w!íbai宓vÕ¾Qƒ´K¼=óÝå7éjØAÌ*ei4 oÑÃj®p­¢åvù{œDÿÀÊ,>®6!ÂMDº­¸Þa–&‡]6´!Hô°U•²éÙ(‹EÀ¥¥h»FsU´]ж‹Ûä®cº ø†?UA¯a—zœ,ƒ5†{ªùn`ÌzÂÏ=œ¬x»ê¼]blÉÊRÄ]§B&3±xšŠ¸Kw©2(EÜ¥"Q*Ue`—Ù!½ª Š Mj) ï¼éëû”>•/nšðéÝ',ƒj,U-…ðá>yõÚÀ.>—çî’=sÕñu7ž€¹JRô"»û8N!ÝÄ?Ué š–TŒ1•¾ ¶É³c’V0©âE‰Aƒ‡§L‰¡r*W rÔ“ ðªOÀ^óqü$mM=´N¹å³±êVѨñK`ÂÜ>[{”—·”¿ÆûkΘ†ñ™(m°Š „Ú?=¹.àŽj8ûÓë{뢗×\—wþz‘늘‘ë:؇$ÜÄÛdN…T~óûMöÙÒ-Í󀚘ÎÃé÷Ívyuá:¦ãyÚ="«FF®kØ–I¹Ð_á4Ê:”e E¬€€LÞx»JK‡ˆ2Ʀ]gXhj‡gú¨ÄÄT¼ B£}¬ioûÔßÈê]nBâÞ½oèÍõ_`-Íà)lÚž€´¤©â ´Sßöw¹w—I‡}i½G=:äæ{fuÄ­W`à!| ×a¶> )'ZcCCp²Hxqûð¶=CjÝ8\Å­{"ü9´Ä£ <$Ÿ` ‘Õ£(8©×b‚’©ßÃÅàä?‡Û0Û„O9Ø¥Lª‰›*oRåMÑšUäK¤3«e^5±óIXxžM€²=YY5U’Rº RâsQAʽ¹uÇ *9·n‰'E‘ë†r U¼¥’…Ä=ämmæP ýóäºí BE®+,%ˆR€6¹n)8©$w¾h1wÅ^»J“˜P ‘bô0OsŒ | ƒí·|€ÔÁÒ‹ìnwì¯Íªe7ÓDyãü]Sp¡>ØÝçî·Gý‹]ùá¼îÈÇ'¢üðÁÀBÇ¡o5m×ömË2]Xn<›Šæü­–Äi†îÙ¦cºeúV_smÓ$üÀüj0} Åß:0kþòÖ)Y»à(2ª×°5–VÖåоuÄô­È›òôô­¦Å cÏÀµ“xŸ4VqNœpBÑk‚ÓTìµ9w"Gn ¸àFÆ×–!72\Mó,G6|Có-ž½ÖÔlਅÿX¶¯;®Å‹Y¾£¹š§q#×ѳß)öZ¤[=lAökŽâ…ª?Sõg{ן LŒ€[ÿ³õal4MQ†’«ì÷ %ÀÂ¥k¾ƒ›ð>Iâä[¬@íz{øwzâÇwXZR.$f+„]¿ã«Žr—úzC¿™xx·—! XDð¿W˜ìû*_Vâ1 ÖWwÛ4¥‡þG«« ú¼ô® å LçkðÏ2=Ç×t½TÀNrŒ2”KŽek<Ë@ïVõÁÙÀ×ó`…,x¯Qº‰¹2(žœUcâ',ÍÌn.ÿ7-¹_@ÙHÃið‘³N*Gð¥é)i]2«S‚¿†)C Ô’‚Î)ü÷ê¢ù›…÷Áv‘JfNF¹:ñ ë`6+úè÷’5_rÓÂ!WÁÍÍ£þ†kR‚»¹Ât&2ÇT\Á þy.6hî§í4š°@a‹™K¸‰þ‘ʹ"ßc½ºô3òðq’I)nø‰mDÊêðm‡eéSvšxÂQ¦½+}™œVÖ |Û8Ó¾{]´x_ÿžsJÙ+ïg® ,ΰ„Ï"x­øæ 9Ž`Ë7+[ÉÖQ\a0É‚„¾¢´µ«‹‰~i»š ŠÞ®fkŽAØÂ¯7ùE>ßü±¥4ào’$x„KÐs²¾À­×|‡²¾ÜÀ÷¬?÷ ¢IV'²äíµtûÄCA¶ÊÖ5_×4“IÛÒ¥[r µ­Ä¿ƒ¥›è^A‹Ð¦g[†i€nEö”FØcÌXŸXŒYßoÌø"Ð? Ç´-Ÿ¹tÌ’ctÌ’c½ÆŒû LœžåYˆßåStïZ©䨴" ï-›¿>®Ôñý=ðêƒæ‹Â›°ÝdŸò7A»4Éž¯iºîƒcgx>›ë-V„ÀÏjûx/½k ?%~ñK¶ÚQ%näß¾T† ¼"ΞùPQš]£4è"¯oÁ½Ší€B$‹Z†ˆÑd®Z))ÿ=#dÝýþA,iÔ¶CŸeñŒŠÒô³ïâÅ ¥]”hµ‚ý¬Bjm—w—§­&.úW\áäB“à|âêÓÉ"œ¡âd¤>MßÔ5C Є:È´+Éí—Âë¶&ñ£V|“éótDÑãfŠàèœá«Û?ßf/…ï°W!{i¶\Â#OÎwIÏö1»Ë “q]ÓïðÆ®0V­”Ò”RšRJëκß}/‡­ø&…—-œ BîÜ(µlN*’,í.µáà6öPHS˜òyQJÒWú<`½"¸‰žN¨Ïg¼åuˆåŽ¡>ñ Ë‚¸‚a¥;{4š,j„Ò½¢Ú2’cºfÈ[Ê#šû: ô2µÀx1ô>C’“Y»éÙpšš#χ¸CC{=X›ÇÀ7¼×Óéj£q{ \h#¬Su8CæÉ}œgߥäªà™ÐÍî„7ìš^©‚َ皌C¸Kë(bxÝ×wd„ ³ö:m=ÔÙ¦;ý¾&‹¸¶áö‡ªèÒÐ6WK{h[ìpQЩ‰£th.3-z™fÒè9m¥Ø…z¾ ¯ Ò'ZÓáj…WI¢þ;Üyéãf~e‡fónîdGäˆÈdÍSBëpº]„vs˜ Å¥Gë +¦Ûžn½ˆÊŽ! _ü;I^ãFÚo>Ù3 ÅÊ¡ëoMWhMDwj_?CÜŒ‹Úâ/±ò—‹šÁß¡Žë<2Onðã4S?V+†Õ®õ9l&—A9Ê‘™#ÑeG+ü†¨‘c©|u…6‹Qx:QzŒ ‚Ú7ƒÀ™›[*ìè>4 8PF;<ø—: BYßET` u‰:´G³=âÀ;" ÀÄ:0[C70c’•ÑbÙM„@ï¼^´Ÿ²Ž¶ax<®ªŠ[´7A­ TºÍ)0]yU„þí=”Dµyï¡ÓÕNÍ}Pù‚ÃéÛ5cPƒG¹œû òé4<,h÷%J9­B„³f¹-Süe­L~-ƒ”Éc³@æD¤ª•™?23¿ÓÖSØùYÅâA ã=§{>ùMß(øÑ€8ÂÎbÚâ[8{ßÿZ/ ¨·gI/.ohIÌ>R¯Ê¦» En™ XHh|rl€XŽrMH ÷¤Ê÷Eè î1YkúEÏ —%Ô`,·Ëßã$ú`ñqü.€ÚùmihCJØû.V"¬ÞʱøFŒ Ì.bçê KWD*#lË¿nÀtá¦o­"®-S‰(]âÝt‰&®ÅÊöçL\›YUâÚ[ª Šô1â#g‚9BODC(>€<5X\]dÜä<¤™yÇØHljìdÖRNÌZ5`2 ‚h¥ýÈBJ+jwÓJÈë–õ䌌+¡°”à>ŒÆ¼*•ùåµ¹åÃVÕ i8 ÈÜQFÙeã=)ö8d?S±*à˜þ¥óÏP~‰S³†_å\¼ñ`[‡5•XìâÙšJˆF«¨Õ")Ô˰@ï-ä¦m9%Î Ž„â–™R²¦`ÚQ+Œ)|µjá¯ðxÑC^÷üm¸X”L-,X†okü‚·ù¹½”†Ë Ê̦˜S]õ ÀàFLж€Ã^BU¿7×1 ®6RÏÄ2bŽe€ñ.L_–2™¼š½z||1½\¾Š´f§æDWÅ«ÝE¸4Â6"9qC(ÑUø"E” ÆÅ;1ˆ-y §˜ºø€\É"ãU1%S¹À6LÁøK`јMú`üU8O…ó”°yI~|Âæ²r!ºÍgfTÀT7$äÚQ„Í9dÚíçíò.$œd`ŒL0t°Øahì« Õõò¿^¾Ô._¾|ùß“üOþ¼YH “õØŸrMÖÈt›€PÑôì¾\à_7(_ÄŽ®Â‡ b2´*«×pæ$ÇÛ (æ±uHlˆ4N®.îƒÅ&äÛÉd@&Á.LAZ•‰X° m7!9FÌo0õ²Ëa;L–Fd¶ñ÷‹¥êëϧ0d‰×Kn*£…¥„Ý9aw0N3!!™ úLA‚)W±´ U±â^ "üA¿›0Åçî¸Ö¢êôÍ¥fvfpwtÏ÷ Xì,ÛóL—Ò±tËÑ ÏE$dÔV•‡ î6·ƒº§ëÀ1(ÚÕ–PÑy Þ"÷NñŒ>žmUeü+ ªZ\à ˆ¾±yôõý Óç|͉Ã-*ÌkG½piÃÕÞbÞï/Л‹I†Kz0Lùž%Nêá~61Üz_ÐÕo¾DÑ¡ëX.¹þƒv°[G"êMM 7­KàDZãœEN„ ñèž{¡65^€7Ùf7À °ó³÷Ur{¢Y7ƒÛ×NÙŠh4'¦ÜÔ£³kq;õÉ?ÈŒƒˆJ±·³×0›úò T;3䣀µPÒ£Ö«@·°ïð¾†ë0H[Ÿ…Œ¨¨¹¡!¢no¶iü5Ü€–a[°SÚGI¢•ºËÚ +þÈ–†by®µV6Þææâ£B@[%¬–€Ñ«‚£aBo!úP 37¦àhI©UbºçOQGa.Ñ®‚£öÇäâ&Ú]maÊ(ù7UlBýËñ$ðE‘+87;M×+Ï;8ŠP=Jp´DÿÙfa©à(õÅxµ ŽÒ$Á¢²¿6 uTRÅòB¸qG›â’b¨“`ƒ)—vÕ¤u‘m>6Ùù2y€š§ôÏžKá¬\îÈßÂx¦I™:ú}ɹéïÞÜßs§O(ŠD06ŸbÂî~u‘&Û‘J«Ôj‚!õ¥Mü¼º°æž_]8y ÙÏOX3¡QzUY¥AúŠ6AÌŒ¬¯Õ vÃðòP"ņ‰ÉÛª)ÊןüW$£›ä£â~S4·…Ý%‘•F4û°UL)£©˜%âêŽ_<¿s¦”lñá¢)P™8¸Ââ“°<ßÀöÏ’ªi<¥Y©*Æ´ô}ˆìM‹?n@8ÊÉsªU´zŠoC…@(ÌþÙâÃ0Ï¡B G ”øåÑaƒØ@ò •ÑȈxF:8£`ƒî‚+cLŠöGu_°ôˆ¸2˜„œÓ‰^hþˆ¦áDQñ ÝeIÓÐ Û³-‹'z÷MüçššTð&Ó¥p3ßÒu×±\Kó-Ó×<ƺ^&zÇ:/„­{ ƒú d×€ „Ê r Ú5OóLK÷yôœGGjÀ(}Ûµ=â ‚×8Ýt rÀ4=ÏJ\*ÃiêkZ1îK—ạ¿™1Δ¢¡Zñp8Âyð#ªˆ´¥Oø*>y+Äâð–Rq_Âe×pVþu—™#£sÂe†&Š—‰ÏØ#`&šÛ3Üý®ã Å«i‰{£[©¥°Bï:Œ‰ w1ÜÐxÃ]B’êÓ;×`—ª«<½íIÆ. Ã"¢áP>.Tp>ºé{P@àš`%yšæò¦f˜† üÙ`ÕÙ6l$£}Q2ÌkhbYSüµ!ÄÔoZ„÷iö÷]œ¦ñ2û”Dsz( ÷`±"Gwwž1§rœKô0¹ˆÚ„Þ¾.6Bh?ò.ßÓ0ÄD•gìY×^aÂé¸ÑtgÆ_¦^æÎfÏðP¬5½$Ն̗I¨ ßMliç«úò_´%ú?´ɫi%nlC@ˆ+åi#‡ï–> ÓFJ%Áô‹†Ï–)Â%AQ}\¢óô¨$hòùoPÛîÀê90MJaÉSCS ÿÎL)üÄL©Ü¨ã¯±W®®£ÔA‹3·óÄmйý~»ÊBÆIÓ}GsálXt)Y:ò5œ+@)æ`gUù§ßý†º8ýÎŒ‡·ñr®RzÆÇw2A`³‰¿#^ ÿ䳯¨37Á¤ÙE÷¤‰L—d#5n§í9žÍbV «¦]õƒøpjXdø²'IüáÎ 7]»Ô©dœ¦é<Ý’1R Yð—€ÈÆ-ÐîÛÄ‹œžOÎú ·ÔìÞò“7.¼_?¨®T#'•#8ƒ @a'”ä·28ã&y¦e6ÂÒZ˜q–‹UCĨ.M.>­.|î¾1Ï= TÞ,ÕÄT†[nY8â~ü‹$lE$u6·ñC˜ÎCdøílŠž[©xSÚŒÆOÛi4 àí‡Ü»"Új3vH$ä&»H…hpW—£o_>Á·í‹Q~–xþAŒ4E:û20JÖ |Õ8]ðî&ï^»IõåÌË/¨ ÞÖíY«/¿º¼!GàÉÑlÍf´ÙÞŒ!¤B#HxQ=ý¨\ß1]ÍÖêà8¸žoö8¿Æç›?¶”«ÿM’pzNÖ¸³ñšïOÖ`†`µö€%Œ¬LdÝ« Ç÷<ô²áéžçz:ƒ‘ÐeÛG$‡ã8Ãp|¹a¯aVƒl ¦å¦ãàûÍrßöÉ?€$“áå…Ò{ŒbÌì†íZÄÔ8f‚P!{•gk€_a):d!°…î\]Œ Ì|Ê3¿Ë§çÞ<&µº–ÒŠ-¸ ‰!q¢e¯LþQJê{.M¶Y뾡ù†ç³‰¾³=–ÏŸÜÂÍ@ïí¯Œ;«d|•(óQ㘪mP´ðϘÔWÎò651ÑÚB™I¾ ±!>zÓoÓJ߫؞H×îJ]£âª`iÀtý6ôd‹Ÿï‚MHÖà›ytŸá ÉG2KW äD,ßzòäqÑë`úýpv«Y­âºW9šO›¯ÛEÈ)räߣ¹/Mçq‡IˆKÕ:¨Z‡±Ô:ÔØ+3ç&]é»®éÖ뽨—òŒÙ¾’ÂKzÿªQÅórQûðÅ-òNO\-1'Gœ&ü\òæˆ3Å΃"Xj3,IœêÀäŸF¢éêˆpy½¤\¹I¸ ä¸9,½r­¡ü¢b‘ÅEª:-‘ûn.H?« ÎdZîæß åJïa›r¼ÀÙïgE©ŠÛÞú§ÀòÃ'5~)ðÖYÒAM¾ÍU?Â,|_/¶<üU(÷ú„P5SZåNÈÞ+8a¤g9º±c¨sღf›¾ÿ±l_w\‹÷Ô-Ø*fà á =ûÂO*üäzý s‹çÑl’”ÝâÂë$ ¾óøÇsÄOö3wÄ…d#+³F¯³T™H“ò\|›f .^dˆf û6X³ëFÉ&½×Ñ–•8~ÜÆ‚¢?…?BÒhK)&ù•Ú˜øé)Š-í¨J!=ñ=Á-"IÙ&!#_Y€×±…Õ¶À*}¯„ÔËáh%¤Þ_H}—h“IÓýö@1ìöÀ¤ì"ÛO™S›ac0빫xµÚ>Ϭ0N ªm®¥ ö±ýAŒ ûQØ€€`Áf»“ÍT "8Økó²„Ô…XX¥<8åÁ8½¾§w.µÙ°¹M§ô!”>Ĉô!úíe%x=˽ê$÷z$‡O½ÀõÔÑÈ ©®(V8d,RŒ2Û3cKa–û@Åšsçèï?w®$–æ BÇòÅûLø,úM¬ÊûÎÔ°å Ã`?#ÀÚÆ$fÙZˆöªV r©¼;2Ëþ¼¿ß„ìŽLƒu”B½È?€ŠY~‘TöñwmW9ù]‚š EÜ7¨i•êÐÙ^jÇÄJwÇ¿Ÿ.©F“ ¡ô³ÕJaüüú=Ln([Mf 0/ÑL6á,¼É5àØ ³Ðlæ¡‚»Ìλø‘©k†…Q„å Ã’r™ý – Ú¸‚0·¹\¦‚U†à@†`§XJ.®b)Êr<ÙXJ‰ÁŸíÏÆí?´S•ý·‚’ÝÃÙ;Ø´ÂC¡üÎsíò†8ÛDÊ^üÇçøÅoI4ûOÅ-ä*“ˆ¼%¦c”>Çs-eh£ý¢%WŒ¡‡+PˆÑ£—óî“oìf—뉯 ‡é]W¤ÎŠÔùuG®M¥Ïy©Àûš,žÝæ¶ÄæÌbŠùPN®Éß/zgEó°*€Õ‰L\;#5¢e@¬Ñ~áöz`bÄá¸ÁÍ*k(ûš€ ¨h@>šA ;S2¢e»7%#ŽôlÙ­ûk©;]]H±øLå­aÐEEw=rºkKÎþʪOóÝÉABÊ<³ Š!YÖíNªÜ Öœ*Ô¦LܘŸhðKëòÔa“+ò?>.׋¨+ò{îþ’V;)ÿà¥[ýOFgJ½Ô Þ„i>Á­‘ÔÆËÿzùR»|ùòåOò?yÞ{†[›¬ aµ©4¢˜÷?¾»º¸ùì¿UõÄËÅ4Ø^Ê ¥¬pH¡ æëa¼P4‹•šÉÖíL+;0Íw!$Ê„|x€Û`™9|5BW"8x*>d½5.VyÊ)”òØ5‘o¬¦Ó%x‚'¬è¢·ÕŠgVt*XñQ4~ŠüH±@¬)ù©ê„qèa2æg¡Ø&ƒleŽ_§`ÈP)cSŒŸXÊMçÝô\f`)dôñ¨›®¤Ë„—(d#fX/Ü£¾UcÂè#=r aep+Þì3çÍ6M×÷\Ã%%j cUÒb´tÇ©FͶ\×6Lž7Û0]Ïpuƒðf[¶ShzåšL ¡úÒ°‘B¨ž9B•@ùirE ¹È%]€_T7¢|kTpBÅ&Uó ÷I`“ôq² Öô‹Qƒøšä@íÖ9î.vrñS9÷3Q\ÃÚhš}¥O2KĶԘíM½óä*mû”u@hKÑÈÑéQÁ/¨ÒgUú<¢Òg*=<,Nó?ÏÖõïjδ$2Ÿ—IÓ¡ÚÈ]¥çF>žó|뎭°ED”œàIˆ‡H}îÏpØàL§ð(ÈévEü°ì„D뫳âc+‚£Ä_ËÜv$“Oáì‚ãþGUŸì‰?­ Y;¦³z¬#ÂÝ«üéDP!eR>ëò)ò¨‚UpBçÀwUp¢ NЖ˜0¸³"<8áæ!«˜Y¹¥À+xÅ6Sc°DÏ6¢ ÀU©:¨BÈë1ú‹_›ˆ³IX{ ,Þw Ï&½ÔÌv¿tˆ0á|èE¶l7½xE­òr”—sò^NA§¸Ówštl6Ýï¿Éˆƒm”YÁ#2Uç®F—Ó±Ä]͇ÙëuFŸCþ:㻽ßëüÄ6U§UÇ-X6ñ"šõ_h•^}-- }–YÌ8ŸßsÁq÷\²%YøhÌwÌ ™G+x~›MÛf«]2³wÅHצ¶òu»çî.5åqemj­dÓáÓìy_ ¸Áä̬ëŽs7éý2Úl¢Ø£!ܳnDlz@Oº ¥Û$¼DעŢ®µ´S,×ûÙ“èULŽŽª¾(ç’ÔPæ—+´_€®ÐZÇEk! P¡µ€á/}í£ºD©â{˜Î…Ö*¸"„•fJ¥A©4ŒL¥¡ÏfçÞ¤Áô{86zܹQjÚœRYÚ[jÃÁ]ìžxbZ’®Ò§Aú¸Ÿ¸…žP”;<\”O|òðŸë`¥;;4,j„½ç½ÚÒ‰T6Ƴ1˜¹¯ÿ!n£ : Ÿ!¹‡Y¬]ãól8MÍ‘çÓ….iGl^äÛë:ôÜwƈ[`ýèŸ"Ô¥rÿZÚÃG»ÃEY½Oø\E{sÙïõfHcè2K³FõhMß  w|ºÍÌÙîKÎÛáÎKw÷fó›²÷‚‰¶Z¢­Ã)Q,>téùôŸëè¶§[‹çÒ÷’cˆíÿŽÇöuê7îdpÂú[“'ŠZÀd7Ûw™·ãê".Ô3Ê䔄0ù(S—‹¡)$á*DPý)Ê*§Ö,¤áðȉ)aHî4(ùÆ¡dÄ æ.“‰¡þ‹ì®?²kV[† b¹ ù3Ó¾ïît÷„z!¢­®,ƒ@8š[*v°>®¾]'ä a‡‡s…èv-ÌŸ mŒthn¶M^K ‚ðw¶@‚Ž;ýßßoBØð`Ì¢íà+ø1FX¶ ”š¦ëPàžï a¡ÚÍb"ŸPª‚uªrÄEÝV‘Ì*ýëÄ?ÜwãIšãc;=ÊÓÙ3O‚í˜m©Ý'Už%ˆÈŽ)ä>p¾nÙ±qú~Ïð4¶SI_Ñ9ÿFßÿZ/2Ü0̃Zs`×!߈÷ëŒǵ¹„2cÓÓJHpû©à–çÛ†åø†á;¾§{Ì|£ôE°W†nÀqK·4Ç`pêJZ¾«{–k˜àƒ:–c ÊÄè;!¡¡›Õßñü°·NaÁi /Μ®{ƒbÁý˜œ,ªmå ‡ƒëZ˧ãe=Î;zfpðþºg‹?ìm®kè y| ûÔž|8ìñÀ˜p]Cãø Ž|¸G£`á´.²£gÜÏíV°pÂhÏ*áj„Ç|O/Ïí÷½óuO wðeÙ6^¾J‘x*Ï«‹ßÃÅ0=*,œ…ý,\Á‰÷œƒ¼ÛÜè¼D\ÁÂ,\ÁÂkؽ£ÂÂä/²dÖÓáÂ;1†}`¸Žš 'ñÃñSÐðŽT'2xù3„†TΔÛ‚® á™s¤ á2 ‚†cqãWPÐðBë¼ÄFQÎ÷UÁ£6©Ü8)h¸ˆ ¥wAóž4ÜÀ›¥ á1èP‰Kye%¨ÌA˜]&ÓYAÃ로&6\×ë”ðØãἡÓG‡ãQèðx&éc¶¨uò–WÐæ6WU€á8™¢>¬D„„!@D -=%ÄpïIELŸ°ÆÁh8«ŒÓß¾¼Í!ë4‚×kü9^Ñ‘¥0 b™¶‚ÄÕ"­U³iœŸÌlh&Óÿ­vâ4hx'mâÂCÎ òË@g&ÀM Ä=Áâê⨟_8:×Óòw,ãšË g?`ÝΩ YÑýd¬3ÚR–O{“U‡| Aó¶ÆEfu¼ IxÏÊk¾¾ÿLݾ}áNŸ€I!Ô­uà˜Èò6Þ®Ò6†Y¬ ­)àt£÷•»}KØà4Ó„Ç‹þ³”$“~‚6Né¶!Ì(æHnÕmþ“ /áÀFßÞvÑq ãøÿlëW Å]ÝëTç‡iU+®htqOðÛ—²àßÄÁåCº(Íñ ]ÌÌX*ï^DnµãVƒò, oƒ5Ó¸Œ`s¹×Ñ¥¿ð[¥9ŽbÏÜ=ÌoIQö½Jß«Û?ßâM˜¢NZÙlåpÏrt¨Ý:N‹.‚L¾ÁÔlÓ·à?–íëh9à1V´ãh®Fä@ÜÁѳߕ´”0) ¿ÊG•0éýëùãz®‚4ĉ¯„I)(; À›—‚o…±’Y‚­[¦ú”Ùrm6£Œ$‹^K؈HVêãr½ˆ 0H”—œ(äž–‚¤Õáu­8¿»~k*–¢ë7x%[¥ät38Ÿ@nòÄä­ÀÂcþÔÀòVÌñŒA£q»‹ð˜ðï»8Mãeö)‰æôP®1›Ù]°WÉC´Údêßl¨NÑP='Ó÷$¯#6‡Wx l´ÚÆ[rqŸóR債ÕëÝï!oÅDq™ûÖâ’U}Èë8Oò¯pšÆ@ËÈ9ßtÐ?è÷R?’ûD ‡»äI6_úS„!nç`î‚hñq< Èí]´ ’GžIƒ»¦_O˜äÖ&úb~Âô`’WDÿ…’äA#3ÐYâšxOhlà·4ú¥˜[`YÀ~¸yX÷$œ½BÏ9%ýîLò@ÇeÝßÓ΢ üäC6ôÄM‡_‘žBÇ<ROÂM¼M¦p%ŠeÃz§ùý&ûL*·Aµ‹=‡Óï›-¼¾?óì»{f9Âd%¥õä÷ìà]˧_ã.fÄu<{`&”t!ÙThjºè $t‰ºÈhȲ¨‹°~œÍy—ƒÚd×nî¥÷ô&$v¼cCÜ÷úˆ‹AëE²—ð:%»ܽvõ ôKpÚrÊUø2KÚ©¯=ƒÌ7GÄê6ë0àÕz“ú¬…‚yÑñ*pðLx _Ãu¤­ÏBjO66Äh…:É^ç<ü §o¶iü5$kÚÎ6¯¤ Qˆ±ËÊ “ ËÞÎbw¬µV»G5‘X ›Óç;QQÍ=}•Šç#òÎZïlŽésëj-έÜA–Ωùl½dŽäö|S•â1`ʰx/v ‘dI)g.a —§4Îlºši:Àòä{žnx³š‘Êt|Íôu×õ|5#8Å™bЄ6m×Ð< Âc¥83후w+Ï<æþGɔZ˱ŠË^[BXp™Ü-ßõx Á¬YŽg»ži‚×Çî3}ž«é– bκaW¦Ç̸žu¸~&ðw9㈮?xS Ãåã 4ÂÂßÂx¦IYà}ɹÁïÞÜßs§OP‡Xs›O1Ñì¿6Ù†5€hñ6 „ÿ/ó´aX83À–d&íÓvš)GÓ_‚j6£#ü–ÙÊúZ? ÃËÍf̉c9ËÛÊh2Éýê*¸Ëý¦ìr·åÎëX>…Î8g[ÜhÙÑ#ç F0èÃraû¶e™®a۞ͳšÃ×>ÌqCirÇtYØ‚Ntßö5×6MÝñ\߀ŸÖ›†S~Kâí°¼tÓ,üAàEÎ?løäÙ<Í3-Ýg3ß[à̃WÔ}²§±u‡£“áÃxÛ-²Š ‡ÓÔתç3PPBHµø:CÝœäìÜ"'ž \Øåù\çÁ¨"ØØÆ ÂU%°8…¨ Êfï³­ip@sÀÒÇÍ; 3†³6[&0‘y¾­mãÞuÁäJ÷ Ä€m¶è ƒPßAÄgT·Ód«l"0±‰.ÛF„ÃyÿÃ=òz@Rl;• z}p\:8ÕÒ˜ ™©¥ªWâŸ|¶¹o&¸/©êÐÈíZ½·‹z‹ÑóG¼åù@G²Äדý„²,ïÔ,±w¤ HsA¥ ª!q;Âdô~5«žY=´¼ÝèîÊÀ*‡@@D”3-Mø³4eéÁ‰®áœ=¥Šìñ ÜjÜ-’'Wsûoå¦| éAɤ(¯÷¥¤ïúþZ™çJ'ëw'Ý1–ýÜ]™æ'dŽÿΕ\ãíÃ<ƒÑ…kÒƒÍmü¯$q2á›{08ñ´`=¬– ˆ“eëWé¾äò»à'+HÉüã·h–²±õ ¨J1tAãêU] JßÃëLÖ±OápÑ×$(PõÈÅqWô…&ww>G‰²*3oj?BE]¼Î]° É¥oæÑ}` ‰–D¦Â›Â*…Û7ûE{N´ñWn ž‡€â]&wðäMÀ÷¬o ‚£yòáëvrS,ÿi«“Jt˜P@±^@uÈ÷ü©ÂkEB5e`°•ÕÃ6S”vî{…—,¯½˜Ã¿…ä6H*¼d©h‡nf¼d‘êTŸƒáØZ3*öÍŠ«ò83·fñ‘1¤a'*»ÎÖR3@ïO?ü1¶ƒ™ÔbŠCd`]T)\³ö«ªzPm†ð®ã82ˆË«TÄs»ˆþlù¿]Ì¢{UVÿ¬ÔÒ…#‡²*0⃓ýâ×&bè*òrNaVÜN,œÉÖª¬DˆIST™Š*stT™ª¬„.uוä9äNMVVÒÝÔT"BT w†aÄBAˆö¨*é—Ké‚M4}ñŸã¿%Ñì?'ª œiºÖ”TxûÜ=ŒyRözQô]@ï@;UЭ º£5 áçA „dÆG(V¢é£nlŠÄ ~£EFpÄG 9&$†>nbB"Û50°øï:ÿ\5’Ç`?B*Vz@ö#i¤°…Hi§ô¸—ÕÂ~$Ž ›È·%|^,8 a’N8%)ÕÞ‘5ªám´ 1Æ*Ë þñjöêññÅüõrù"hªS4'ºê°l‹ý.úÚŸáÄÄj+‚‚;Æív±öŒi (—p„yá_ég{¦«»-×lõRW»Jøu/ÍšèȸpO—VgŽ«!û*¼ü¯—/µË—/_þ÷$ÿ“?oN£e/Ö€äÏ™nH¼L'Óx[ä¿nÞñ?]…£Ž~0€Wå§„• *ïbª‘7“MV!ͪ¸žÞZDÀmM‚)\/˜üs‚%ôl(ÛMHŽ'äÇq'¾º¸›°i­<ýˆÕiÛÁõjÐ@Ñ2ZEËíò÷8‰þE+X|\mBÜTDE˜| =_ÚXû»’Ö£Ç'À ÇeðA!Ûþ±}à'Æö‘—íð×Èñ »P{HCM½+C¼2TÜæ!øAZv™Ÿó( ᥃Gè ´Pš é>ˆÁÿ@Í‘EGos²®&2JQ5÷>¬•:_’{dÞÊ1R¦`A˜+ļ'eíÄ{ÂX·»ñžSªçIù߉+ß®|'z†;e¶ÉÈøN`U¯MnE5]ùNÊä‘<$ƒMþ§"<1³½užŒðù}DôG­d§Íxâ Š¹²EGN©Ru [oRÆÑЬO„ 9ÏñÄD“­)œ¢ØNFÀvÒ„µsÛ}“ü>§XJo׿ å{oùg{döÃþïÒQ9Qã`„¨ò€ fT@Fþé±q=Ë€ â6(Pæd`kd©=«€Ì‘xvxŸLœz܃gGÞ–æUŸCñãà»ÒÞ@ñãìZTÛG’â-••ç¢D47xD·*³;æÊ·ac.žÞüýÌñV‡‚qµÖý%µ|ò΄”ç9©+È D>+gâÎD§çYºˆÃy6nDžt~º¼./J±S–dœEú×”UNK ˜ò€ÝÏÂ;Kñ÷å2’íôz=,-{庺¥»ëõèŽcÊ»ÓD¨øûd ›ð÷á*ÞÝÁ5õ•Z"Tk…Úf,t<0A~–œ 6_€Ÿ‡hʤdK¢ðl.´·7ô{Æ©ÍÁÊñû¿KÒš¥ï°A‚‚]†Y×Åußï¾Da'NÔ.eæ– ì®@íY€&Ò]‹g•6L×´A±èŒ ,OŒ üƦá8¾ï»†nèß•I¥¹JÜU8p$  û)¸ _…p/JL5Ñ¡5¸¤ù!M§q礽¥w•(¨ÿkâô!d6AúƒÀsm€‚$˜Lc¤wÛ´;„l¯îÈËÞmÓçLîΩAòùyó¸„üjÛË.S~aS¢©µláAò­òˆèWœ»ýOvEô´O‰]{,`Wõ³ô‘IÊ)Q&Ϫªðž£"¡¸V n=t3¥¿ÜsŽ4µ“¯k§ñæâ\ëk}¶÷NŸ”H‡«ÑñdìqWóaö{¡œ.¡Ñ›+½Û¦)ýôoØ@¯.èoðýÙ± èò0f-⧯p} û‚`%úÚtëK C¯¥3ogødpàÃ=™lY®ß}úÞ3WdÕ"ÀßÚ*<22ÂJ‘Ö¶òµ»ç_2ûxƒW×Ö=>3ƒéðiz¥¯Ü`xölœ»Iï—ÑfåP´G%ócÇÕ¤[Ma§Гˆ .PŠÞF@)ûÐËË«‡ZÚ)Öý¬Jô-f\€˜+Ô¢6r…PTïB ‹‹†u¿ té&êÖp6¬wÛ¹QzÓOÉÉ•ö–Î.¸‹}'©úËa¶cf9‹»JŸŒ¡ŸÑ‚1»SòB°ÇÃy!â[–y˜Æë´¬…Õßà-êêŠa J/—[E!K“¼¥ÜÙÚwm¤—©yíÅHpy$ðŒ³íA`ÃijŽ<²RhAæ dz\‡Þè}gŒ¸6ÞþAL]jôû×Ò>Ú.Êtê*•NÍeO¶×›!µ«p;—Ƶê–dß- ·ÿ\²4E=ÛÉy;ÜyéãîÞl~Sö¿`TQ´bäÎÂ:œNÁl×Kr$Màè¶§[èBQߥ×Äǘd¢ðw¼d"ï˜HûÍ»©=ý1£s×s`ßežìˆÂ‡FfÁu8Ås’^évá9ø Ìœ`yþ#{}{rk’¢uˆNƒA2Í-ËMŸ îk§d¹²g¹ÒÕUŠzïèÐ]Å"¦uJD¦Š†‘C¦ £€‹ïï\$cuI‚Y´zv÷WÕ ¶5òO×}Xä Ïw:EPåX¤zF9“\Íý.©œÇ8ªÙxÐg¬8쥈‹”~÷‘>×ì³–Ëu ûuòð ɺ$ú•¥t;6NgùÍi¬±’¾¢=ü-œ=„ï­KˆW½œ&ÞÓlhI"´]ƒ•즨B}%’ºhT1©SP­òþDFŸ¨’ 1“Ò‹©tÐϱyäžbWš] wD…¿?þ¾Ûú4(¨ˆÒ`soÊj†æ[ŽÂ¬X †eàgLwŠHþ«»ž©£u¡:f* MTÇaôr˜Ôëüs•ë…8Õ1PÏ< Õ±, šÉ«3ú»šdøñ©ŽKâ¼–>/Euœ‘G)æø¬·ל²Þv³Þêëèm‰"÷8"BV§õä°§nÃïÄÀ6 Ö +&³avD#]ú ¥mˆñižãúºÏgt|Íu4‡T’è¶æ¹;†(k]Ç4LÝp¡Ò„Õ“ð$ùÄGòx†˜ õ)k .?’™ X’×DÓ˜3»ðÉö¨ÝCݧ¦¬µ÷ ¬E†,@²B¡Ù-€Õ °y9®$œ½B½átúµA´˜PµemùŒ²Ö±|¹+e­˜^hÁ½¦áã‘QÖšånu¤])kÙ»Zd“ÿ©kæZ@ÎÛR¢z0ÆZWZ6ÛJÆz⌵Žäã2Öš–lìò(°ï0‰¿†ë0H[¡Ò2ä×mcCCËHèfÛ0pSîîÌ1ö= ×$³¹¹àH˜à×¢†oîÁâÃÏ­4QJþSø#\TD¿E³”Ýè^2D“ëx1ËÖ´Ú/ÏDsòÒ0,ÓñGwXçZhâ2lnúži:®é™–§iøv¯©'¦¦áVÃ×<ÛB…CK®˜’ªTR•Jª2W¥$ià(Ù¤d/è)U©´Ï‚"0ßIÉÍYP˜¦ªfIxÏ ‡¯ï?\]@ cˆïö09›£–å;Ä µð0ýùÉd¸ ­”£Ãh}ªèð¾Ña׳LˆƒÀìp4ß÷XM1Åû»pÀœ(üÇÃ…ÛºëX.„Œm×Ò4[Y${‡Ãž 2YmÙìSeÏføßîìbŠ>ûiè³»ežXž ž¤œ+8$Ó¤¤„‚íLtMð=È Y¦©y2œLÇú)\‚,’cÚP?äºÒ«,c·”–þÔEé vâö7pè×€ý†e Byþˆ¦áDZâÀ‘©»ž«œîón—§Ûà‘žmù¶k{H+ÄÜ.Ÿ.pÀº5F-NS_«Ê‹MAþ)$A4·í²Þ—¦0|ÞðÅGåäZ«6N…püˆ*Ô ‚©¬4M(Q+ÑòL¨-+ÐüÃȱ wT\8aø¸ym wöÎÚ@êÒp5ËŒ´¶Y\þ·0^†iR®ÀÎh¹ðÞ»7÷÷à)e§OPó°¥r€´=ÂF » »Eÿ }h ŠÏ¨²Pæ¼… ' œ…Ùú÷<˜(ó”x㪹šrM‚‡$XÏ«¬•õ`lø¶QWÑX"CÍG#o`šÒ;¾ˆ6)åeNÚ‚@Éþ[>0ƒÒü·ÁŸ 3ÜÆëhŠnn%dŠgá}°]¤ðæÞ€Ï²Á/Óx*¼Xéûx›ïK¨¢±åÐsgy†>æ$2]4œzôbÀYͪ3Bp4±¾n!*Ï¿Çâ¯jK¢Ã{HÚ¥ ÅþŒ'œc€Œ{›r ¨ÜõùÍŸ | ¼ž)=^,⟄“([§ŠÙÌf-ö!ÉóhÊv„,e³-n4×fžÑáÓT<0!/Bö>M£e°€÷ ?ÿŒ Fò-<¾$f9 ª`·!O¼ýg|€ŒqqC’ËnÍf»“Í4QAÔ!‚¨dyh;pÔ8—Ñ`CÊe&Iß‚'šA/þãsüâ·$šý'‡‰ ?>D¾”#ý<ÂÌÇ¡!7³P–•ëÜ$8w¤/“jØm€*¥ô¨ñ¢ c1¶ü'ÜýØ)â[2¦\p¶êžƒqî ÝnDʨ@3¹ÁZPFÅýëùãz®Z‹+È<šÍBBMýÀ‡ðX ¾_‡bc'ä«#‰IMÊü Àð¿'@™oQ:ÿ V.^†ÙlB»¬v¬dëþI9'X{°¦öÞ?A õøl9 ïK¦Ø>™ÙóHè8?÷<’X ”³Vè(ÂF²¸– PV"¡ÊÆ[š×É>SEz£*Òk40Å)þŠYÒ¸jå„›­Ö“ª j™Hí±'¬ DÎ…î5ä@UTÔÚè•׫eçTëYKP˜ïºÏ¢&°÷.÷”-»UêT³ªVMØAÍÀɤ‰z÷ë6áš4~Mk% ï~ÃÚB &©¸ºÈ1Ö™¤+žãÇM§‰‹öNlÀn¾W@­U´måÈN¢ÉJÃðO>:‚ucP”‹U¹'¤7Íz,PíÛÄ‹< ¤àĬ0Mâ'üÝþoRÕVÔÙ`•[‘F”×ã`ìŸÅŸË¨iæ§Lýp•Bº þ{u!<­c™Î´?ë`6ƒ¬{éß@$ý.+=¢1]Ì/ý}§i¼Ì>Ñ:9ò!¿ýÅ5öÊ w”ÉiDt– ºåGVÅmÊŸšìLñƒ+Ããv$]ߥ2dJÊ=êF{: ¡–¤…½ªbŒ@yûaõØô…¯zÍ1ÕÕco¨OLª¦©>0&¹˜š/SŸäWÙÇQ°´Í 6ûÆw¬„"˜RUÃ~oÌPåwe¸3«óå+í+5ÀùG®Ôz÷:ûlúWË”ñó]° IãfÝgòªjòRkRŽ~…@XQ“÷¾8º½à«Û?ßâï¿Ã.˜7^FW8XéÏŸÀ‘ ÖY/ö®?çëÅK…äÔ‰ ÌUý9±ÆŸW©XÍái\KÐЕý+XlÃ7¿¢My‡Éò ,ÉÈ›†ãY8¥†f)©&®)›<Ér+ƒý.~„DÜñs¸ ŸCa‡Z¢_w,óUK4Ùý¹›U/õ}Õ¼ý–è’÷Î/Ñ·Q ™ßZ§‰­:¨Y¬Öiî…<<÷“2¥•“€‘á(¬ ½Öi&j²(+¬ÓŸÂ‡p5{NësIŒXÙÑÄX3¸åR…:xk®DÁ§Båp%ÂHÍ£ÁQ¬8¥ -Lñ´°=ý¦YB Öç·P›õ'$Ú¡Lé2Ëäa"ÌÊ”V¦tQØ“ÏTAS¬¨ ÀÖ¸g•áhrfFŸŠ ¡ÑŠ #‚ÅÕŧpö&n†û¢Ra‡GÚê~3ÛÏp–¾Z|ÝjB*‚R?Ö‘çÅxÚGâ8 [1på#Ï%(„æ!ÊÿÎPø‰¡}I2r:Å]÷úã;*£Æ•þ kiÙ ¦(ëFUôß”xô„"ºµçø\˜ê:d ÏCá9$4»0°H™t*\mÏõ<Ë))ÓׄJL3‹õ"šfN®z¹›Ý%È䂆.Ô‘˜º¯ƒøœ@bêùírÚÔ¾§DèôR"î*Gxˆ¶ÈSò-+~»5ª¥ôW•ÒÐè)š#ÐÐØ¥hæKL.Å@Ã1Ѐ±z?–…;ž¹[«ß•ÖNjTùðÙùŽÚœº§Ù3ŽP·{ú5t Ä99£Ê3\Ëñ_ÍqÏõ=&9R2¼Fí<#µTõ.›$…Y %ï7W¨ö¨ÉÅÊ»²zk—Kd¡¸ÝØs\$öÛ‰=JP€<;·áÔ*SL{Î^!q`JØ|€ÌgÂVL½mNýGÈ—£;6.»òåÜÍì»À³ØÌBÊ Ôéqµ¢È8”?BJÀNT®Ä—Ñ‹ô˜¦`R>Sƒ²3U‹›”f«ïé4-†€¿ê,s<ÁcÈ–žã0æä¶C•…¥õy+œŠ8˘ sx—‡ W—À»b›[Ô ´= –PÆ„V3'+t·ýöÞµý.¿™)‚Ú¡#èªÈÀ1"’1ù*¥"\d XÎpã¾ñÜÕÙ0ñŸeŽ Ô¤ÌM¢Ë÷4Ó7 £™ºå˜|¶Å´ àîÒ=Û0mßu³,ÍP&—¼3]ï ¬€cH1/6¾½9£ÉãL¬*? ­C“¬Ò´=pøsb!>t Šäo´$ȵÉ`6Z(þŠ3ª›Ûà¯u²ÈŠØ}‡ .}Ë­‰™xJèÞÝh÷0…Ï #Û+rQ×êB:S]J¥ØýJFF%رg@þ¶cÏr’ÿâJâÈ£Ù¯ŠŠ{ÇDÁ Gƒì0M¥}”vˆâñŠFÙË„ê”å% $ž(¸faÖšEwª@Ϥù=E˜«Š¬p‘•â•6²Â*4Td%Sýá¹ièwâý½Øpã¤ty›0‰ÂMäöí ý9nѬBŽ[üþïr%&ÿ6ø¼_$‡-&ª„ÚMãÝ—(ìä)M]ò.tþLî-™Ž <í¦Aß×u–y A"Û<®åi-!hÝ,€tGŽžć¾fšŽëûN†,)S¼Kº c¸ʶõ)¸ _âMDvÛäqKlØ9z¶Skp’ùYüOãÎI{K'À›$ þµ qJ‘ÁB”¾ÄP,V H>žO0M ®wÛ´;Ÿ€wf¯îÈxÎ{·MŸ3¹;§ò”…}…Qïo€’{KXI¸ŒéMz[š"lä-DËÒ;ØYÑ¢¡|‚äóóæq ˆ÷¶—]&ŦDSkÙ‰ÚåÉY¶1tJ,ÛØcË6€¸ÒG¶tcÙn¸eôÐÍ”¶³çij'_×NãÍÅ5¸Ö×úlï;©¬Š •ÐájtA<{AÜÕ|˜ý^ht>ä/4gÓ iï¶iJ?ý6Ы ú|vªƬBœ&)ç#_ÙmÁ €„}¿éÖ—†^K-Þù3|28ðážL¶,×ï>}ï™+2€Q:Ü´«ÿV W¨À˜“\µ¶•¯Ý=÷x©A«k럙Átø”C£¯Ü`xölœ»Iï—ÑfýÀ ‘£+Ê$ ü¾(=•?ryh7o2|›€8;F>ô2ÄÊsBÞN±nìgU¢o!0;à°«á§6²˜kn·9ÀÒóW÷Ë@—nÒ`ú=œ ëÝvn”ÞôSrr¥½¥³îb_ãIš>ÌvŒIYIWéÓ€1ô3ZP—û”¼ìñp^ˆø–eæŸD{!}ÜyÑ¢®®¨¶ ôr¹K>*E!K“¼¥ÜÙÚwm¤—©yíÅHpy$ä>gÛ5‚À†ÓÔy>d¥>Ì‚ lÅ‚Üý:ôFï;cÄ-°ñöbêR£‡Œ«¥=|´;\´Ä^ʇNۛ˞l¯7CjWáv.kÕ-ɾ[@oÿ¹diŠz¶ÿ’óv¸óÒÇݽÙü¦ì~ÁP hÅÈ…u8Ý.‚d0ÛõÒƒ¼üs›ê–¡Qt/#ý£ɱJ†¡½ß¼›ÚÓ?iˆA2Ï«ÕE!»Ù¾Ë¼¸ 9p˜×âT®»_Fx«þW…8(w2Ö$5Ec Ó`Œ@sKÅrÓ+¨ƒª}§d¹b‡³\éê* Å ½wth/ üJWŸRÊ ,ÇV RžIÝ×ñýý&†A¤/I‚Y´ÝÀQüÈViºØ¦bxºîÃ"ox¾Ó)‚*—¯G82 ½Üï’ÀyŒ£šýÉÄ3‰ÜÌ ²Üœ])þ ÜGú\wXg¹;üíK9>1ñJИ ðw׫áÌ-É”ŽA¾OªB%¶‚JÒ‘»pÀT¬Š‰Ð} „ ¦R%›ô6^GS„LÚ…ÄÇ:Ã3^—¾Á¢w«©Ø;í³·–½ÒFÉ^iœ’ü}Ð7¸PN¤#PjpÑC@B³œZ%Õ¬Tú~}Ä’Þ"¯N T¹ÎC•‹í¨Ýwº<ÀOp?É¿d ¢ŽS{‡ü¦¯¿q¬˜±°¯àùFÈ»ßÿZ/×Ç'hZ’àkÀÆÝò'4Z׽ +}è]Ôiûý.ö­¨4¡ÑNÔ­X9ã9éu`éU:¡¼¢Ò7RúF°2@í3Ö6Û50M“hÍ´ÂóõLéÁ¾L€í+rgÄ{O«¾Q‡R";ÛxÊ5®ï˜¾ÌÖwÄãÄï/.s¼á#zò¼”<¬–ð4èÏJ^¸+ÎJ¡+¨ 3tÞ'×ñbv÷fÞDŸ]âÁ_Ú¦oêš¡;PŒÕí8Ÿ3—žEð0ižW•ìjìCâƒtÇsñ»€7û¤ O_>$(~ùŸoc¥,;ZeÙ;»›•»Ó*ÉhZ+»{÷¨×Ýe¿ˆ–ÁCȱfá}°] ä›mýM§‰KñX TóbiùAÍî"œ’Ê7ÖÆ‚Ä™‰yT9pMªFð–ß`œÕÓ…Ç!t¨Ø,( Ö!ã€GòßSÊÚ1ºây°“·F´LúW½p· méì©ÞÝꡜªV=šÇá¹ ½>¹¿bJn’×dó;æº&üYšñ»Åc î·W@ɲ0ÃÐëSèF;“©¢Rï{JV3z5#Ù{\²~w5¡;DWvÉÝ R•¬[ì€}ç*¿™³šÆ¸TV'{éûzL¤JL£cæ¿pª>aú¨‹m)*†«ižåèPq yr‹×@250æ-øeû:pö1î* ‡²|Gs5O3 X´ ó¯§Ç•ÊüÙÅ"þI*²ÕK8Ó›Òf*¯SãÎ7\••Ûøê7àl†×Üᅦáú[”Î?ƒ™‚ï*»½BÕÛÚ±ü O©TJ^pû§Æ9ÁŽfèãä.ž=â~‡ò ÑLÂæ°· )bjL"”ö,C$•‘¡þx5{õøøbþz¹|p”n5vAs¢«V(lNƒÖÚ¢ $Æ­§h­w£µH³Œ{¨”¸ËÚ*¯§bâX‡Š—a`Ö!\(ëÐ~¬C½³ãNFÄ×-f‚cä*Ê~±ŒDb&¢ÓžqÌQ²§3Á‚t~1“ÆH˜*‘ ºq¨Hư{Ò›7t2PE2 $xb‘ ÓÙ@×pIÒ&8®°Ë°tt –a¹. ð‘ ÃtA{ª ’aÙûYI^"J…sH’ˆ×PWÿ<á«Y-`U?Zò¿E³t^‰f"`±ÚRþ3îpž:ëÌ¡¦’m*ÙF=ÊÑ2zñÑNàÀŽz¥ ½†ÿ‚䘣.F)Cç€Ùže¤PÇCPž|ãÁ žíÊΗX”bÍÔr¨’ó(Ù¨¥g;À(r.ÿÞÁ„,ƒÜû‡N†Ñï…À4r9 A–‰»øW;vC|â3ŽD`mß)E"°Ç‡ŽD`³ZàHì'(²Y…ÿdS¨æáBå¢[áiâ —/íU&}F³Ôeõœu0›AF“2èß•ýnb#à“ÆZ1¾ï¡vÿ¾‹Ó4^fŸ’èaNe˜lîÒpï÷…JˆA,nSŒç ÿã"‘{tk&|‹4|¸}ŽW!?ÙÈo+«™xÎ è ±ózR@(*øŸoÞÏ&’áWJ¥×ÔÚ%ý¢õË´üóê"Óä";âݨ¼¡Åœ1¾µIݪcÌÅ×½®ãDt-T%nÓÀ·¦Ô’œé±@F%üEŸ ›¨‚GF#eàbFPcÐð(õ?$ ò«I¦«Wzå?U%s€âÄ ¸ÿꂼ÷ôóT›ýPær ‡&?!7?!ëÞÕEšlC6Cú_¯p´Ëã w´ËcñüÑ. üÑ.{éÑ.VãÑ.ƒ£]ž±¶ ðޓ͸²–‰Ö­|=kß—Œ½÷¥®ë½:Oöôø§”?º[ÀL7íB&>8n {^´ºÅ»iï#e»n+bø0*‹b;ëØƒ ìß³‰÷o×ø††«õ áº;@C¸‚Ю…4„«Z¹!Ù g“YâKd–z>¡•W“Lûö…ØTh¾gñŽÜÌo>]¬yXqÑ–/à¡',(<íDÂ!ˆ¼÷‹¹WJó¤üA&3ëlÄüA­e¬8¨ö„²ïXÙÜ4MØ ¡Óóˆx˜µt‹pú3NfçâxûÀR££KI6·ñC˜Î3j+Šå}s师— ‡EOÞ‘ÚµX¢C~f—b E¦ 9­©ª•PµŠ©ƒ9vC² ôgêèoVR\·“UÙâ¸è0I#^½Éˆ,pKºYn—¿ÇIô@ˆ‚ÅÇ0—Êžõ Ù¿Ú.(»zcPú Vɪõ:‡ÿ™‡BÂÿèõ`øÿÎÂÿø‰…ÿ yøÿ yˆ².앾Ȟ‰eğ$CCÊò£Õ6Þ’qvÈ@·û' vO]öÔd×é½$Ï®(ý©ë2çe&3Kö“K“6=®Ô³Œþ5Ü-1O‡Ü´×÷îednïvÖ|ï›í¸µ›ÍYì|E¾X ÈáʾU]X%ñd`&6K¿pêŽÍhœ;¥ ª>{?r>rU¤$²BWQÍßIjÒwƒ÷«Ê0®2¬x® cqÐçj®È*ºCfè¤Gß{ysw6‰Ü·÷¾¶Tv!ε†` Þ–IO6X=3¢:y/ŽÎðPY½(!:h7:a:$¾‹ôÍ*Ñ~“«78 ÿA›MflgΗ|ìø–|'+zTm³ÁÊCø¬õ7™MÙ£o‚YÔz™Ìís™Ì íñ0¬xoKžöà^"`ìý{‡{ ïÐ7k‡ßÙÂÓã¾A)Sï{°Ãm3vX〰«w×rÔo[€P$€ÐýíÙáéìð¾å^vžåÄß=~5kýïÀwM϶­}³w˜P¹Ù{p|éPLëùP@ 5µ¼X¢cjŽay¦æ†§yƒÌRv0¨°52Ìw-Íq ¥ZÑJ4Þ§µDY®¿²¥Tز]ýšju ,T}Ð;'ím®•GdPèŒ!÷·¯ ½TGØx—©Ðwk»¤ÊÒí'‚$¾T¼ÕØ»•>g2‚Óx?$}Í4Ù†Ñ^D Ö&\ЏÜS4TÖF>A†SB%S¢U•é÷Q“4Ë~B•M¬ÇƒT6åáB1IãS<ÝsŽ4µ“¯k§ñæâ:)~-ÍϾÃéC_·D2…›ðŽŒü—Þõ$öîý^h„Ê_h OÈ\ßmS,]ùwA% ýM'%B)éêanÍF§„š›³8¿²Û‚&º¬ ›x‘ãôðì¼~ÂTÆ·ÄÚ¤·ž×^î÷dÐ>Ã'ƒîÉd˲pÕÎ…ÊçR å¦¤L+²Â.KiQ^Ø­¹­|íî¹ÇK z\][÷øÌTí(Ø×ÏðìÙ8µ<Ñ ¿Œ6›èG8˜¢=&«A;˜Ý0â€áwmzyh7 ($?o£á,füï2Ð’˜~«¥|gÚÛb ë~]Ͼ£\+_æ9å»Cò â>—soR` gíþhÛTä Ý¥7ý”œ\ioéì‰ÒÔju•> ¢{ßË A8Ý)y!Øãá¼ñ-ƒ»I=Ì?QXjçEKÚ{Ó{¹ÜÒ( U‰oò¸i`lïµQ*FÏ®ÛQJ Ãn»iÒ(L‡æÈó!+õ¢õdŒ¢3ƒ´ûuè+¸ïŒ·ÀÆÛ?ˆ©K2®–öp’îpÑR ¿¹´7—=Ù^o†t*ávÞüj”l¿ƒûÏÍW+6urÞw^ú¸™­Ð¡ÙܼÞ{ÁÀP Ñ*­œíz³§ÛE f»^z>ý "¶§[ @RX³²c4Á ùÄâ•÷›wS{ú'b!ž® æ@ý†cíc¡¦†6àÙ*³àÚyÙRŸËïÌÁ_`æçÏV”;k’’œYÃÊÙæQäÚŒìvXƒûY®N;%Ë{<œåJWWa(¦Ã"/¢û•îÚ£kz“‘YŠ âzd2F¬¼¾dzƒÊ >™Î+Ú1¯™ž Y°m[#ÿt݇EÞð|§SUïD8xÙº†ññ±‰Ò>GÊþyuÁÙ•y\¤º7v*ß1ÒÀÉÁ¼í~<¼B2£‰~ei׎Ó[N~Ówµâ:s!$}Eóú[8{ßÿZ/â eöršøiCKŒu V²ÛœÊ@q½AÚ;@•ŒxfvÞtvþåÎÕe» ¤r1ËŽub}qH°ô2ÜΘŠRæÛ·äëŒT„«C¢lÄäf“R”uuør››<¯4Nz½¼ÙѱIx é™o~E›/a2BÐÑÝïª m¡óæÐ×\·=S—ñCln‰.Û·ñú81ÂdÿÀDcSp±· Ëö'dô4´y®ÓyÛ­”Fü»´—ÅYóçý»ðv„ˆk½±%E>NѵM†¨Ó±Vµ¶¢Ö]®^¯3Q·êol†>6:%ßE Ê'ÿ–D³þi„ËD¾tðŸç€Ü§çé6óÄ3º[rÇ0\ ³ó}Å÷Vƒp¨ôUKc̦ÊZªì9ý^]…æ$Ly*ó]D+‰©!o"_|ˆÜÈ·`±{ŒWa3ô"¤ñc&&›¯],©?á݃5Ÿ¼gmK•ÜCÊ—,â89æShé@ñŽ‘ÉÄÞ³^·¤²’×UÖT¶ÏóFÆ»pA¡Û—°@µnÒ‡_34äÍb€²T㮼wŒµ¥±ÜSB+ðá–nðØ`âÄœñróÝ_ô[ÆtðpPgP¶,ƆnÛžéiúy¤‡,×¥gW³}Ïùfä}û‡¢¶}pÍÿÏÞ›.·d뢯ÂPEœÛ§(s¼¯w„Ç*ǵÝ>–zWwÿq@$$¢M<¬R?ýýV®ÌDH I€–d¡ê‡E ‘s®\ã·£’>®¸#<àcBQF·Ügh€”:¤ß鞤kÓ{¾3Õ^ŒƒzÌ,uPµ)‹ÊæMæ"»úD?ho} Öáö2˜}C¸á7·McîV³ý‚jŦe‰r|ýüŠÚãE\Þå“QÎá§ Î@Bˆ»üäTf›êülbˆ¶ ë¯×ÞMWÉÀ@›ã1Ôň™»?oRó Ž2géá%12û“ÓˆÒ’Û¢ÐaÚ´š(Û®ÕdºùP´šÆxÄy†) }´p ýypXµ>»IÛ jBkDôÒ^ÑíŸéQ¢:1Ä÷k¸ž^ø{!šþæmœŒ¬ÜªÉz ô'@Jz;°ôÃy!»—'“WUŠ­¨NM¾"ƒ2¿žô$oÐ}xü]˜[‘”Yè´½†kÉÖûgÑ’uλÃîÔ’ó@sÌuÙª3©í^)¼pŒ9+X¶VS!ÚH€o‚ÃL {¹ŒÎ›V`e–G¥ü=w»¹Kæ¾n®¸Ói9…÷¸.+[æœIÅOç8ÅæIcÕè½§È¢ûöˉl3 dAÅ’:C^<ÙK½h.}.¬>Ö#$Û²W¤‰’d¡À§CÐ9)´9ùX>ºlÚ¨“×ë½ÉŸ: /ÀY§xæ^O²éÚÐd„¡Iš ÞŸeèlÉP½ÔÌ1ýxEy}ãW‡!·’Ž7-¶NÇÝóñn¸2 GJnºE#XºEñlæZ Ž ·E­ Jc®JUŸ¡üºÄnØ;>øßK¸‡žç„äV¦6T”ÛÕ%æÀÒÅN²W#ÆÄAÈ9mVÓÒY‰bÈ35D6ÙCfÉy4äRfu4ffÀª­¢Ì'0”¨ ÷¯2ÆÐÖJÂöC8ûV´Ì™×_f%b™q1£Ÿca’à ifB·?™öú£Á°Ã®4Ð~áM§7ì"‰y·3èN¾ ´sÝóQÜ À7í÷¦¶“k9»K¼óiò¾„µy®F‘û…w'ýE}lã‡Ô µa¬Ù ™|rб¹I"Ópö6L()ØôYUK‹ÆR˜¤õ¬Ì*}ÑÑJ)HÇ*1.—Þdr>Áov8žhe.¨}ÏG“áp€¤÷:ZÉzçdõC+¢è™L»Åô¬7bÆDyˆ±¢EéR˜ô™b§wËŽ3W¥ÌýÃê6ï‡ÜŠä%´¡ð:¨ófûØô\Ç6\}Þúß`P³´Q*ò.nXyíÑ„ºÀŽ¡l¼´Âò0†áa<O`}è:8åhÒsÃhÜ‚ÂõûÝá€?霌F]XºØ¯£B”º©l³cdÓgîѶsÕ8/ãNoÌ–o¢tÝóÉæ“ñgk8v¦ºËÝó0q@©§x<1$³&Æ9]ÌNõˆ[{ŠÄš63l¦ëàÏ"GG‘4¡ (¨Eì»}þbg²Ê×+xcÒg#ë=º|ÅÒZW—^¿`æª-¶£}ð×7Å^B™Á¦î+³B©D o…Eºˆ‹Ë”,Ùë!]q7Y¯2¿^¾D*GͽÍw¤¸¢”6ö…“y>˜ &9²œ©Œ×fn—z¸*½Y²«C£J±_Æ<ÐÉt ȪE«ùXÅ^Ju^ VΪI¬¹Â¸š‹3ý¤»#ˆ ñ¤ÓôGÜVÌFXÀy¯ÛíMÃî¤IcÒc÷~﹯êFÓ)ÞA>é;ý‘P*¼ÊÚÙô>°úØr>›æfóFHlk}f³Êà!°”§PlÁ¬ çÖh6]£Óu±Ç‘ºTä^¶ÑS&¨}4Ї¬°Dâ´j ¤EÕ©æw²ÑÏø>m4EÊõRV9†ú¸—©ks£rQïËô‘ÈD&{\ßdÌ]ŒéóþíÂôeúgGL_N…ú¢ÕŽë…¼Šy]˜"0Û„íõ$Ô?Ú¥"_ku‘±Ô‰æãf‰z£(\ë– éš@ú/CåÓiqg¶E fM?±¸Å5&¢¦½[ˆüí³»Tsð-¨ c=Ú±·²¥4ïÉâÓcˆŠ–ßä™JV™©£C0ý}rîë ͬtÀ.cÏÕ'“7Ó•’ß1Ú*Ö¬Jmùï{P²§iý¶ƒ‚lûãÁt2“À°À.9ô{kžt;PsÅuöBÍÖ±QIn¬N’w°ÆbÙárŒMÝ|ú ²G~ SR ükA-Òm¥œ÷K¤å°'®&uI%Ë.OA_B¾dJåjÖí¿Âr«M(ÿªÓŒH‘˜A$ N¦” Bqù †ào×{SèÀ–©g³1¶:™.ÉPÀjlHS’/ÚðéªvÞ3U°‰Ÿ¾×ƒÑC¥Î`U‡ýPuÓþb=Ô Cèúµ¾ãwú â¡fUÎE]\»ÛÉó><î¼ë ¬±jâÚò÷©ÑÐ?6ô‘aG \CîE1MG(®k°­\¤kÁdk÷Sòwªî`•˜TÓÃ&Á‡ ‚«øæšƒf²«”<º-«:8åÕ”Oñ޹C’BW"¦Ö+…ïÔÞqG5B"5«‘»'²$Þ³ýh©:é¨ÇôÁRibGÕ¦ŒqH—UëéG»§f^3y% §£Î`4©QÏx'®™ŒwVzkkyãh‘Ô˜Ê×›°‰°éµh_•2ŠXªBcì—Yç31Ý– «û‰¼GjàÕ‹ªm±£]%?EkiÓL)q7Ó˜°Ëdˆ½B$~|G± Û€É*¾·$¥Ù[o#ut ‡õ}–ÒËM°¾_4µzl™øjGå!°jý²„îÒ¨œì æ¹+ž´»ý"´Ž:dã5å´õ¢udye­BÜh¶Ñ’c…<6ZN%ÂÜõõÎßKm½:f£§ñrånÊ‚° Ã{? F·×ÃÅ—­3¡Œ© •`8uY}ÎËÝ\ç}••~{¸þ¿83¹땉çSU,É <ÖáEWkxãmƒýbÌŠX¬ÌSXO8À€k(åFc*ïÌù̪Dsä;÷GÉ[§W½d2ª’j‹Áq"•È)<9Y¤âjL¾IMUÓÏéÉ®Î4ˆ–r;* ŠÓÕ°4|Ú»‹D?â¬ÁFð>Dc@ 0XÀËVG3¤ƒÒ`')1²f­¼ÜìEŠ'éµ^Ê3[ó£|ÓWeÊ™­Îͧ4ZíãÆÞ/^†V×F(ŽE9°8‚¢6tŒ´wƒåI»¾ºÍó£‹îîgFwÅã—š¿H[PÕŒ-µ¶jÑqÄO˜ø¬b2 ’#<9mïßþ.‰_Ôq=‡U•¡<…™övWjŽ'’Àc ŽEó3ÉqÅ!db¼WW¤Àòîüíñ*`ÊÉ”UÉ#Õf NºÀÚÍËâ<~„s ü– `ŒyUèCQ—sv¤8ޝ#Û£™ÒFœ"{âšh”êàíõ`ÜfP[-nR‚ßL×”¶1&ˆ¯'X.#ß D.a³V®™îHü¡>Dƒ<ßú»ð`þ6ëíX´¸Þ©ßƒî ƒx³‘´,|`ÑVÞxz5{W|ùÀ!lÐ÷RIÃó¥Â¬ Úd™Ûh3¼ çw5l‚‘ᡤ6A^ÕQè(”¡YÁª5k=æ8kÚîcÃ98i^åÉïsAÔ0ï|÷rd½ê ‚ÂVÔù{åfŽé+{²<x¯eÔ“¦;µl8¦ÔÀaËn Ù™ÂIr¡ƒšÌ=*lÝâ’X…/þÆ÷öǯEnE5hf/_öៈZÑUŸ¹_2ª°Ý’eHCVtjü@=o•.fvŸÇ‚š3™¹¸?ÏqRÄ ìQПC*Ú|–ÎÖ ¼¼å…)¤Mä¹") éŒY—ã¬%6R)úˈ1ÕÛ\]É Ø:¸äš—•CŠ˜è¶¯¶]S-%U6Ƽ'´t¬mJhŽ^U»}-x[(3Xï)“XêÝBÝÔ–ŸÆJägµ£èwÿËep³^¡^¹CzGáTï×p8Ë2ýÛãBsêàÖÁ M´~+³Np;à vJ½8Ÿãn‘l—ø;¶Ÿ=ñ¬=ä°7ÑÅŸKØÔßWGýÚè2ý,ˆë0Ö.û7êÂu¸\†·(Të­Ú‹6³ŒZ/r¿5Uº¬¬ÀÏSˆii›úâã¸ÎÉÑ:Z0I·1ë†.\Âãå-rò:½Lej2QŠ5ƒžÉ¿ Vþ»p»òø8ØÒM<›?»»k-ž¯V-ÏàcËTgZÔEÁ­@cæäíêI~ވ̉æ6£6[ƒõÌ’-Èbʯ¼è–Ì”Bi–­•ØúñjÂ`ìëâŒZm0q0ŒÕÁ§5OË—æ1))µ»RUÛÚ¯bZ0•ƒ©Ö“kAѤrB Í0¦ic˜³ÉC‘)™Jël~êî¹Gš¼Àžñ—eLX2)yž ‹X Æ¥ÚÈ0+Ò¨ «k`ŸÒ†%¹m4´ÀöPlXƒL“Mž¬v#VäK|ïF,›z¤Œ¬škZÁˆÅ"@9#– ÜŒXÉO´‹}C5bGWWs¿?{F,Óáùç6bq.ø¸šºP #‰[Ió’ƒåd’©¨*c9É3>ø h÷aÄêå˜ÎïLj5Éto(³+m‡­K¯¹wähk2bYŒù÷iÄêšýiŒXdê7ÕÊOLjÕ3}ÔäuD¶ »e¬º+ÓR4íà 4EØ™~†N‰ Q.ðxÚƒm ?}ä¤1Ò‘t:Ø4ìD”ÇaÚçå+i ªÅ9™U2¼bîÇòe¡§eŒkz7–¯8ÞC°|± ä`ùBz;A ²-_ÖIËbF¹`ZÂH-7úÏfû*rTˆ«À͹ r¶„nŠSyëpÍ&2þ™ 2 ˜#fGSê5iBk/„7W»„ Bv(jUtBdˆ f)ó7pG¥ìs.Ãc=Q_ä++M™†=µwÌÖRî¿æ4˜~¿l¦M“q…Û¹ó‚nñžE™HOȶ¹jˆŠõ"¨f&#…òþŽõA>Q E¼.‹ëŒ¸¢Ewk íetYdɤ£¶*ìêwsqË ¹(Q ‹:5ä †£ÃFR Ï·W[·W#Ÿ»EÅÜö1S »™?—vö‹c°ùˆ }/Î~ùõ—_:ç¿üò˵õŸf¹¹?Ã)]¶áì1ów/ÎFá„Í‘Í[ëgwí’­¿8{ýû;óóµƒÜßå!OöUpb‡•Þ½»öÎ's<úîá-w¬Ã—­\o‘g ®ämo†½™Hah8ì|zGb'¼­TõDlÖqV¥BbÂæn&Ïl3i $¶ˆ¶Ø…×\…Ëy)ð­>Ò_\úNQ9Y_¸º6cûÉ¿ý|Ñ~…v>^ª;)úÔ~Ðâ'MRóîêÏYä7÷Œ0†ÛÛtLÿKÿ657î#Ïrqv”ÿ­ß5…äÓ!7D!`ÃN'œí05gú„Ú #]¦c̈bY¢‘taꛌ¶Jy¾”ÚÚ´nÿü”~3öýóêªßüI/eooËÜã*ÑÃs9'Á0üÐãJÞi™+ƒØù¿æQåÏÊÕ8›š½{ÝèYͻמ³óAîÞ²óé¶áŽœÏÓûÁ•8Ïn‚ÈdI/+r ë‘ñj ¹ÞðjÄóÝ/¯Æ+Qöf>9¯VŽpg]“«fŸ)„æ¬W¦Ï”-`§ˆÁC^a€5#WJw8îw‘(ÛPfƒƒ…7 øÐ &ƒ‡¬¿$Xé ˜|á€s±Û¼R|„)Gfª”ÓƒéÃ|œÊANnJz½ ·ßvd ݡ‹?ÔV¾ÈÑî®gKoéͲ½uµó¬8û‰ð½ e£„:ÌpIÒð7eê4ʰUIxp×ÕlV•F«Ÿ= Úª#ã k2 ¼öÖß½]JÏæ'pó”µMiVmfƒá+_ªÅι²#%ËÔg”ùû Á¼ú¬¹(ZL»‹lù*’„æRïÆÍ¨1¾ìr ƒp¼ñ¤Î(³=LÈ©V£0›sj=9YU­ `«zg;«ÊÄÄ8L´=`¦d}F1ÀsÖ;T{…1Bü)Òâ™úìdâú(§\µÙjÕšV𯑧)„ Ä?»êÊ ÍdTmŠ„Ý.bs)¤òTf摲3¸V1‹ìÉêhD… ¸f:CÚ[†P^ÜíöþŠ2BÊÍ6˜ äG~ý3ã0v‡½qgÜ0nW±.B¡˜ñNã7Z¾S«N öñ‹´x†\zÉA.¼VÛóm[‹ý¥¤‰¤ ¯[^¹}ó|ÄO·Êß%,ë‘´¬?Žm=.`”Zp9 K¢±Z}€à÷À nls¼%N¡±ÇfôD6Ÿ¹8ÙB)º^hñgšqÿóWåê5= M-%ñœC Üwy@$ùz ÜqÚ댺Ý^§7†ç]oÌ—€ôÉ÷áË7"Û+àÇ «Z‹1-£––$Úp[Ì-di4ж7ðÛÆö®áØ3£‰NdŒ.CŸr»ñSé ‡€;öɰӃ–À©æ‰ëáD¶:ìâÁT9Õô†Ðâ ªô&‹¬W^¸½ÝŒjÅQ‹…ÔÓ!šÔM":Y®cÏþÐÓ[ *Û»ÓÇ•€àÀ 鎺}ì'ºŠNƒ^Šm)%D”¶ºœHˆàÃwaô ’†¤¥Æc5\&½öJJ…”N"†>ZÇ:ö¬mŒµ?ÄX[†—q’µŠØuã¸f“e$'ïvÎŽœdƒÉf‚g_³q¬úÎf°Q‚|Ë |ÁRŒÇ(=é¦à*p“ïÒŠ>–×k½ÂËKV¥Èzá)g’~ÿÒhŠߌ@>Ž]¯"çîìdÅ'㻜ÎW=»‡il³{îªìžòG>ƒÞbGÒ‘SpÔä{5zì fÜÿÆ÷êÁø^¹úäþHÅ×½Ú‰KñH…Z·ÇlS”Ö)–nø8/ªZ˜\'G¦ª†þÉýa¿+’ÈvX9#G„# 'ãŽ$ô¥a”G(ß¡˜ ü X‘%¸$…$ðc„Åz¶w9ö_)NËi¢N¤Q¸WbR´K9­V‰%¨g¹J„gEýd®µ¡T–ºGHÍz“â§¢ ûhˆl¶†Ës^Í“î¤3ŒFpl6ÓNÇãé›Ýþ°×I”ßýŒ.Ï£lBVúŽâ •qƒJæ`pðÉ!ØÊ¨ àe]{î .‹òf‰R´º”v®ŽY9”ã´s¬cmto€Zò.‰"52§Ò9<Јqɨð“+á+²ÕÝXª°ý§wŸ(CðL…=¿_ŠŠÉïcöš)ò²êܹ¦âöÌ]šRïãßž¹‡ä(DïH•G¦pÇ=”èÚ* ^ž×y0KEzQXÈɵEŽôÌ¢Ò3éU¦ïÂÝXÒƒâäô¯Ù»à9;÷²p7žZÚwÜöPÎñQx»ž$Eω¸ŽŽå™»R‹âަ%âŠbë”±œÃ8YhìhxùöÔÉ,x¢}'ú€}WFÕÑí”–OAÛ¿ÑtØ5ÒÃþDx¨AÓáNW…‚´ ]ýIŒÈÕéj-f'Òv¯÷yU™dŒtÏë§Ø¢cì.!ÞŽ&#d&kªr@©8Èð×qT-á†û¹(.Á9¯‹ÙÇÒ7ƒ¡æÉKZkäÓÕTÝÅü~¨Šê~ÜN$4”⟌͹õ¯%þåí;2,DHSí¡HÕ\æV)íŽúàÅÜ Žk•!)=KóS«Ô²x“’&«F'– R|®²^Ä •ò¡:5ðŸãË×ÒŽK’r†D¾FèDWâ}óÝGŘ×n$-µ›Ê©GÊQ£Sº‚°{ÉÄè•ñ½£wRÒŠxrѨ¢PP]eP…Ã)¯y?¥ÓI6+E1Ь~“‡bõ«¸{ª{=Ü‹ÂéGŠ3'¸gËk4JmV' e©*w%–ÉrÚØeV`Ýã•xL¦+ ov"U~M’7HŸr‘)µ…é<Œ‹¥ExE ív¿—%Œ™¸ïC"Bz>$„v\â· Ü÷À‡Ñáà*Í4…tpH *&TÂ[‡k¢ß!Åär÷œÿ^øþþ¿ÿ_üŒ|zÛ­w§URŸ.>€#»ô_ÒãvÑ÷fi]ÎH-ÚÆ\Äjäô‹³m°Ù·À…/ƒõMkçÿ߃¿ž!m#ÊŠÚT HSŒäŒFð†âè÷©7¢änëëÐèå~GèƒPpÞøáÊßo£ñ\¼{óòú:Xû¿É7í.Ø]ð÷!œ}óç/ÎöۃϬ½ýaë- UG4sûâ¬N{=dºÁb‚dC#ÿ«¤-‹Ì׬p¥Vê¨gîÊ,,êúSo¿;úKv¨¡‹v‘ Y«Ú籊B†2ò øbJ$M'9•ðžð×£ëŠñŸ/ÎbI‰·þÍk;•ªNR…âëùÖ»¥MÙGÙŠÂ4Ž­;q.ëºò¬Ý.¿òݾÂÃ:Oúc¤åN/kf!×5‹#b@Îu¼DÑÐ5éÏWáÜ_šÊfñÝGzJgVìv:©âq‹•NÃëé›áëÞ«A·ÿ²?xû²?AôbÄ^½é »ýÑ+¾ë~Ô–€¥@dEzY#G@­±Ç1Þè `×þìtãÅÙµGqðÔíŸ 6VÛ_SÑ3~Ç'Ù]Scû åÐÂÙzÃ9fѽø/å-€ŸÜi]{¾æs­ ñPôC5>6¡ aÚ¶ø¤‹ªÔ¢ô´xK/oƒù»f Ãm`žñ·[$°?¿ö{¡zÚœwGCäEh±Úl4ÒtÅ]9²M²fõ"Quw<8G,ßyL¦4+¼‘3ê–42]·|‘¬»;:öû½N¿[ÐëÞø|„èhä¿êô‡”‚MjN’ƒÈ(—hW™µ2F1ìÓ¥>íO¦H7`šý<=({¹äÓsd“ëwGö]4ÓsjAߓޠ×dµÜµ–K¶ŒH‚¼ÕBýö©‰úzÝñyg‚klÜl€/Ú«V/’ûw¨É‘<'ÒYk»À´i¡À ø’3¡åìG›hò‹³©ºYÀª´·qŽô'Ázî«›O½î¿p‘ù@îöÄgÄêÜíÃz¢Öסb¤ÿI×ÌÛÛ¬Yùü;Ô<µt™‰°Y1R§]ã P(­}æ\DZº{‚˨>Ѩ'Uµ{ܪ¶v!®©ºmÞ‚EÀœ–ÉF~ÏdÕýººŠRu×Ôí¾¥Û6mÈ1›¤Ï²´¹ûGÛÖF=©ª•ÕËáÔX7I_2ÿÆQǵ༭ݖܥQ5g_¨ao£¢ä” jšmÔ“ªZÌ6I‘¬%–]–æFf‰Ž ËÊY·~Â,oßXŵÐek—ë!̶>×D—­½®‰0Ûº]]¶w»ÂlëvMtÙÚíš³µÛõÐe{·ë!ÌÖn×C—íÝ®‡0Ûº]]¶v».Â,­¾’0œæ’„YÉ(N7´b ^<}¢¸èNFò%^gì.yðßÖé‡Oð­½~ðôÞÖë‡Oî­½~ðÔÞÚëOìm½®‹ÖK§Ä„7ùÝ¥™Xä„,xC‘ax*šëº#ŠŽ™¬QC‘ãzÛšØïSRd‰fÐPä:ÔÕ'ÔŠ4 ENR‰†ûŽßÙuù‰Ø$'­¡–ð< En(rC‘e&ÌÆfX†³¯ÇC¤±&ªeþ¦£õ!6_È´›ïN't¨¶øX´59†J÷üí«m™šÚ¼Þö3Ï ¿9ÅYy\s{3tüN8þËǵ*Çóø/ïc'¿*÷ñåñsû@¿$&›øhÁK.ÂmðŸp½/ŽqH¸ZYäî²SN%#Ô•¢<;V2–蘞ÅÜRÏâNù©gqçÔ‡Ô³¸“–sÏtÀ~.ÈÃ1Û,æQ@èXnÑÝS–ž ‚œˆ¥Cr¦TŪ­Öâ˜Ç,vObÄ1ø“±L=À6€'1â®ìJCŽA4ÆT!ÖžÔŸ÷%ñ¡ŸÔ*?nîë(òõô¸/«ÿ¤6öÓ㾤[úSZåÁÓÓ} žžåqðôt_2ÖçIå§gy<=îKæE;~c«hí\¼#üܺœƒ3îAWÎÑ\]³ýt9+¡·÷váa;‹²"4ýu¸žmý½/òä½A‘ QDåœÜûîÛ”>[“,½ä•S‡d©òâÁS˜þär(˰,™w^ã%§ö«é™Á±Ø_ïE¨ÚI)HâedŠ‘nN§ mPÏÄ• 1#'gë:ܶ.ü-b[wëþÞímRgmT#ÝQlémô9 ¯¯w>\ÈÚêÂÇøùÏ#Æ?Ô©ºÍKwA]ÀèÿyD8=mœ£º .Dtÿ<¢ gA©Ðþ³Þ.ÜøkÌô^@Ö7µùh(šn³^™ØÕÒÓåÐS³#é¬Î©ÙȆ^­önã­ÕÆ“j£®©ÜY622Ÿ÷GÓ.§4TDDGÕj"b’­p‹œ»Q>(‘R8MÇ. ã—*àVŒø*œß‰¯7\ÆÉôÅ‘4øÝŸ_#°7CN`™áôì¿%9j-ýïþ’CðLTCÿuÓOIbe_õ*e”§RºyôŒ'_‡T+2§ôèq£c’mgànË8¹Äh$Uw’Aܺ0T¹ m;i<<ïƃQGd}°[‰®o qlý‡¼™˜{äFm¦\jñâÌ „nk:Êc2Æ#;œpÂØì%±4Á"m´8¬vÂzk4ÖqÙ4ÖÚŸZ1»Ò¥®$C6ªíÄÜ­ “¼åêŽúçÃÉÙÊûƒØŠ)œÁÊÌì­`×¢¤«àvýÖ†2ƒ+¸cVð¯ö•$:\áT)5­«fÎc¦¬4áì+a,zò6(ç1} {ÉÂÊ÷ƶ<Å‚‡¥–£¬í+÷Ö›-ZBfmáíZÁ~× oq¥úûVxÝÚ/üd†Ù6Øìw¿¶¼õ¼\·V‡å>Ø ç·þv×òPA°þ.¿û(³ny±åÿUÕ$÷ —)zý ®ë½¿¼R„ëÒ©6A Õ¦±Èh-c²ÎµëÎG½nüÒÓ#«&ÈdÑ¢·þ¾H)¿â`b’Ã5/›ø'V¯X½ž¿¶®{l*<ôH­îc=HƒþzŽ„ãb'lý™|§_ª²yp4å5Ï#Ün3›Ãî¾ œ#WÜ«¡vk’agœøIç|4X:¹\w\tg:ÜäϽ}} FcÈÁn£™¨D¶VÎ\B·[,DĆó!¼‘f%{0E×€ÛŽßÕwkÉÓsöÀä|0lj«Zo«þ&â^«lƒzº hœ'LFç Du9«¼·xåኪ2ƒùu»9 483AKs‡SÄþº b$²…[ù›"*:p¢¢7]†yùdÔ­ÍqÞêŽûçÁ`ÐïÇ%”èÜ©C$Õ[Üuÿ}¹ [sG Mkîö­³›exå-ÏÔ¢ >ìÜóÖÿxÛ€4¿»ÖÜ¿Ö`¸#äÍfT /[×ÛpÕÂ=Ý QñVÕµkvtÁ^¼½¸xÿ·OÿóòË_þ*îÞ‹·—±gׇõlævç’AôUümha´¦Ck.ŠØƒä×9óÝáù°ßïub7X´XVâ%&^Œ–ÿg°#V•XšùÛZÒ•pÞzݺ ­[o½oíCÁÈÊ¥hßsH&`7WÐÆo±Ƈ¿b¦ýÔ´¢^#U‡êÀÿ³k}WëêÂìbˆÛ|V8=ÆäÖfþéL·ƒi¿;ŠkÿJœµˆXO±€|`®}²¤Á¼f–’ʈÃví[ö®`€~$¤Éáã‡ÖY$œ±¨BGl‚‰5å’Ùì°ZU¬/–ßšOŽqKÖ9ë:ãA/vIºÌ9M·šèÛEPcþ“=§3C³¦y¢‰lNk{íÍè¤aνHV8o].ü»Ö ŠXyVôGªNMZ1©ö‹ÿóáOüb.?žýíͫ׆8™q¤Š¨•q“×8ç½îè¼3™LFqÖ$=ë©kÂØèæ¤Ûvwr7+ R÷î@K‚óÚÛÎ[X¼/ï^Oz½–¿ò‚¥œ}󰈥ZËÅk]þr¾ký¨ûsþ¿–ûÿo– £ÿëfÿ_e‘«H'F.$-•ZÌóÖçm°ò¶w‚Pb h)RRí)¹Å‚T+ƒ´ev KWþÂûÀþÙú‹ÖÊß‚pßü Òºq^KŒþUìVj Ò¨¿Á ½78©‡Q¯äxl‹˜'·}“Ã<•7ëبQ.K3øg5zL˜z¿öXœ`ç ASlªîê¶âº žY&TëR ‹[C#m«-g<4nòÓ6d\ß§mȸ±NÛA¦OÛapkh¬w]¹Í`ØFN§y˜-}•W-96©Tž6eL·ƒ»®;uºÃ|“nŒ€H;áKÀAýgX·qŒ§n‚«q`OÛq`OÛq`OÛq`kk¨`{G×­I¾’³l%ýÁy·Û™ô§×u°… Ï[¢§?;€S>o½ò¼/YÉ…BÎw *"ÕKZ é¤Ã1ô)n MóQÚfxÇÜ­I€Ög¯' Ñ;ÝÁhXÍ|-¨PE« â6ˆa¶é×ÊÅ$ä´ $Ä­!WêkÚ*OBÜšÌ%!ýñô|Ü…Þp—gkA·éúʇ<£Œ´¬LrŽTa½†( ƒä,!ŽkAªu}€!¯5;À^»â­ÙŸ}s¸n #‘dOOcܪ…Ƹ5™Kc: "㉕ ãÌ Æm®çÑ 0§mÈ 0§mÈ 0µ5TžÂ¸5™Ka½Ñù¸ß&íå( Æ<“%)hÜX‹½Ù?›ûkhP%逊ôˆ)É…ÿiBá´EÍu0ƒBIØHñGZt¶k÷qgê$Uàjܪ…â¸5Y@qŽÂÕCìUÈŽÛ8*Ó6dÓ6dÚ*OvÜšÌglzHD·ÈPò=†ƒÌ³óÈ0B 6'¼5ÌqÄËøç7ç&CƒJjl$iŒ;ËÃÖß).¡£.¡1(‹cK9¤¥H}騒ëI4=ÉÝf/G˜)ظ¦ë¸[›#•LÑêAD ZÊ*–Cˆé¬¼%Œ΄Òt­vëú˜.ÙµµTd@3¨ÝÍçhÈLƒþp8™Þ=Àq,!3Ý.|˜i¹ÈD„œfp0…«±ð>$5LB\ˆè‹`v”©HX4Vá܇A ï mQžzˆ²éÙ.|…²íÈ]@˜‡áD@V¬£©“›CzêäÖRêäÖ’ëî7©Ói[2i’cKGëîM*âÖæ(ÏåÌ]Rõæ«`½õ½ù3%4é“ÛröByÆÔÝåÆ/à||4¤\YÊ \Lžh"aJ‡Ã ˆ¬‰=ºòñ’&¸õÁá…0ž/ásO†}ò-‚VGP¢Œ‰"/¼®›×t-'×6sMNÝ®ïñpXù)Å2´ÇÁ5¢•Dl‚ŒQâ ñ¥ô™wñ}5E/7/Ç*ôÇ­¥*ôÇ­¥*ôç´-™¬‹cKXÇ–ja]ÜÚÌe]ܵÑ*ê'ß‹Üņå8œ<þ <ùÖ«ÓàœI×A¨w„?!° ZRP!哼‚Jˆ,섨"`TÀ*݉ˆ)Ò áp;D8¬îXEÔzOjë9BÂ5Ix"‚oK-D)³4ÀdÁVMjý…âÈDx'GJƒvþüZµ ɧì5…çš ]zœ¦rW-Xm…êt7_Ñ*„Ø­¥*„Ø­¥*„ø´-™„ر¥ZŒunmæëŽ1{°Sžä@\•–¦ˆê6G60KæÖhØjLÚ »œGÀ«ý?´óµÐƒÌÎ êúÇïo¿¼¡ô(Ö•Jë€TH¢Á5øP–‘›É„nuصüu¸]…‡HÜaôÐ bGðZ€ÎM˜ ‰O!±+‚{Ø®„ªLØ·7ÒtHŽdÝíº¢¥}kžMö ôK¾¨<À¹ãÀÇ:ì//^è\ê6ÅG1Ö´*œ¶%“¢ž¶%Óïá´-™ï´-™Z:·–*Dȃعï ŠcK8Ç–*p('nÉĨu[§qŠãèr9”£‚ƒ½kèèBsö 1N­ã(êáSeôÔ ³ã gS³—ãRÄ ž€bY %ðíâìÈßSñ­Ò³IÒn[ ;Û·þ ɉ]ì ᯈ-áè|+ .H©Ÿ%ÖöÙ‘ÁR&¸›jRæÖRRæÖRRvÚ–LRæØ’#»câI;¶T‡ÖY{\.Ô\­ý˜BÝ@X‹ÕQå=\‡’§±ïRv4˜:»\ c!BRs£ü-µ è¼õ‰¼©„Šºø¤Õ¤oØ"röÝËo¥tµ›td%ÒŠ³œU‚Ù.%õÝSs¥¤)@˜§)Hƒ| ‹¤‚r˜Ü³¡áyÝbޝ %9¶TAJ:qK&)tÛ6®c2Iái[2ù­Ó¶dHIŽëTEJrs­ÂZ¸µT…µpk© kqÚ–ÌóäØRÖ±¥ZX ·6sY‹ ùXõ(ª.V0¤„°ßäIc=Çáä;@FJç7r’à-D.f»; ÝLƒD#½ ÄÞ<.Õ0ù¯ ²Ö§-rª[‚=¨çœkÿË2øæs!²v…€S¦B$ÛP0¹`\àí½ €önQ¨­hòy"Ù#Ôzn^¤U(™[KU(™[KU(Ùi[2)™cK(™cKµP2·6 \›ŽhÙlC÷O8Æ9¶{ræ8¦|r6„i*ÊŸÎ!eÂ\ÇaÍÔ¥ÞGÒn&@*tŸ Ü€€¸¿¡pØ_áó³„×Ï_S—ðY>ZÔÜÀä.Ma[ÿß>R  iŠ&Ôrr4bÄ~òwR™> ¨A&…ó¸ˆÊ%º×íÝÝ ©ÔÌlÅ„“°¶½ÜymM_7nùмÐÇE”¯B+ÝZªB+ÝZªB+OÛ’I+[ª@+[ª…Vºµ™ÏõQtwo4uÊVÅPð¹q™:%ÇÑ)ÆG“ÑÐ-E¢&dˆ›ãà]‰u¿}ºò÷·„°¿…÷ctßÖfùµï“Ï$˜µ!›ã³€OZ_/$˜Q~ò´<”­çæ$[…丵T…丵T…䜶%“ä8¶Tä8¶T Éqk3_‡} ¥¡p&8žŽŽG*ß×–mÐM@ˆ™iŠ#Ól¨Ì1²ÃÓ_œ)’tßß|ÓÚP ŠÄÉ©¤%Oè½—aLHÂPTHàD’4É^çT8p2œX:V€ts­B¡ÜZªB¡ÜZªB¡NÛ’I¡[ªÅaÀ­Í\‡É1¬Ê2„ Tspƒ£»€=(¯çÖf.‰êOXÛ¥øJ…ål„WœÎ‡¨ ö*‚ A,)¶ ÒÖFfúæßqR Š]!A³µFâ0Í81^­éhp$WäæõY…渵T…渵T…朶%“æ8¶T Íqk³³íU{“÷¯;vi7sH=„Ç­Í|à¶,ü“ag8‰gð,Ü&Ý©•µæoâäƒ N’8üÙ~JG7ßË*ÄÆ­¥*ÄÆ­¥*Äæ´-™ÄƱ¥Zˆ[›uD’3_u:ã6G:“%„¹5š/„!Xo4é%³SgèÆeFpëÝøB›+tUWáüNüÚü·Ôš³§d!ýIàÛ2X¿J­‰xYÒLsST¾\_mŸýw-î’©K†(Ý ¦å ÓÅÔÿ E¹cKH¦cKH¦cKµàµ8¶™×‚ää6ß[M™×…®cïí;go3ñ½Ûö«€Øâ8mÇÑÎmx‹ÌÞúÅc£ÎÂå‹3Ãíɱù1pÈ-Øh-_BL¦i„„¿ƒf ,be¡•t·ó€aæHr‚„˜yW\ã·½P&—EkÙ"!º€[8l60Kˆ¿e«ªÅÏ[*EœÈN¾¿% ½6!5T ™*ŠHú{l oßÍë·°N×6sqïå Ø¿Žƒ©Bnݖʵ%ƒCuÓñF×–ŽÇ¬rl)‡‰kwF4n×ÿÀ7À[¶ÃëkDÜ¿8ãÈDì°hú1§KLÑDuß”ÏôÜwóSÍOõÜ#°Õ1Q+¹l ý¼¢ì¢]·‡¶ã8+xh;¶äêÍlıž¸%ó »í×1™\Ìi[24M'ž=“UqSí¾›3i­cKUD·1¹ÞTæy:mKæyrl©ÂèØR†sǽQ»‡6’~Ý„õyh»'ߥqtÞöR ûå\´¥zXxì!«¡lŽÏ©Ÿ¥KµðôZß_{[¸çàZýkmM!­%48„›áìçW˜¶Âï$ŽLÒ;, HX·¸•ÈQâQFe{÷‰>F Úž0‡¸'­Œ¿Ñwt+ÍÇߘžwFý(?ñ)R”‹Üâ1+Q(ñ‰·‘Wa\ÜZr½äMB{Ú–LB{Ú–LÆå´-™ŒËi[2·–ª0.n‘U·–ª0.n-Ua\ÜZªGwêÖf¾îy>;]7\kRœº¤ŠâÔ±%7¨kit*Tœºu¢ ‹"<û½A<ïüIU¨ñ˜´xlR‘l)ŽÈZ3 ÷AN• Â6г2X¿YÍU˜º¹˜Ö£0ul3Waú㮩-uI{Ú–L†Å±¥ ’¡cK´¥Ž-e“½zµ¥*q¥ƒ¶ÔÑE1O ™ŽÏûƒé¨3í)¬O±Çï(µu°ƒì‰ ø¬xQ»¦ÔmŒU·–ª§mÉ<¿§mÉ8NÛ’)pœ¶%Sàpk©ŠÀáæóWEàpk©ŠÀáÖR•ûð´-™çɱ¥:üÛúnmÖ©ÿ%Mæ]B̃ë6Ç,ÈNn®³—¯.ž÷q¯O ™nTè¼€py€çC2…ˆ BRd„AcIÑÙ@Ù1à"ºÑtÚGBŠkñ€Ðþú Šd1…s#X±GˆBÆ:%™àbªÄm°_ˆTï­³?Ïâè ¢¾)á2\?ç‘ÁnA1þ¶-”‹¤s%•+;Ø ¿vÓ#°vŽ“B`*~‰¬Ù‚'XlÃ5”¹sNRÐÐÿ·ø[8ÃÃ?5ë#<׊BÁûnþ‹Uˆ¦[KUˆ¦[KUˆæi[2‰¦cKµM·6s‰æQˆÈu¾¨D,ÝàH,í!OŽ*?ò ß9ƃIgËÆZ.ò ¢(ȸÌD†0Ì+$u&˜ÀµOp!Þ–°*D~y•­ ©sˆÍAøŽL1ps_¬@[[ª@[[ª@[NÜ’A[\[ªƒ¶8¶YD%Ý©HM\…¼8ŽÁ‘¼dðbŽèz‘m¬7öã‰ËY®#ò‚…ÚF<¦1Š|À9•˜´ÝA¤A$¾ìÙ-9Èáßk€3£å€kk†-¢€¶¼ßrîU•\LñO¿2÷÷'Cåì«•1Ž&—©‰öK¿Ü*«Ð/·–ªÐ/·–ªÐ/·–j±` ÜÚÌ·`áòíô:ÃÎ8–D¥l¶Ö#a¿ mã`\—Ê*ëkÉV̱тD]“óqj© èØ’ÄºÙBäÌ¢œ€!AQøˆ€Ž |QÞç"Ïz"Tç-Jr#ÉÆ È]üþöÇ·ÿxûúï—oÿ"©õ"Ç6ó Ñ1©Ùe„Õ‘W½IŠÜ†âzlMRtÚ–LRtÚ–LRtÚ–LRT[KåV.%êõ¦çÝ^ßMäÂ'ÉœuÀŸ «gè¸ù*æ2õ'ÓópOKZå_‹äœJõÆßÃ{¤”a™ðÖ0³ÂpXÃ)¼ÚyÀàmÿ÷/ï9eá̾ãiÝ}Ç™É1è—I#hDëš4Ëmu"S*`™>0 Ñq&5sëCÅy0¾&«­V[IçÜZru®0éÜi[2Ü\wòX%s²JYºnN’õ°(Žmæ²(cÇõÆýƒsó ]L· ëΗÈvæšÓÛ<õn#ªÂ©œ¶%óŸ¶%óŸ¶%ó×ÖRŽÐTä—ìxä tÕ¸À§ý~ƒ«œªZ\ã^몛ZŸÿ~ùkëËÛ‹¿¸¤+ý··—Î÷y[à;Y2ødÅ„.Òû¬9±àqx]7Ëz–c›¹«й^w0q§X`¡ê Unƒ©B«NÛ’I«NÛ’I«NÛ’I«jk©Vgbœ?ä.%—¡i Û€¶è÷Í6˜s~ ‚u!?ß÷o^œ}ºxI9ËÛ’òÒ;ÀÝø3]àâÝå%¡Œ^àÍ^´ Bœ-C@ˆßávîo_œí·_õ‚ž‹Ve*D?jZÕü.XBÙ|áïeÕû»¯'ü5µ=qví-w>·D˜…‡5P)¤åDÖm붬<ê8—5»Øš9@-öh”ÇÕáºøÝ}q¦F¤lQ„µáfµ!E|4¹¢õ ÀèAT¡ÖÂ9·¬ˆþøzëm×øâk™/¨†p–ò®KoÛ&G®eü)ÉDõ+ŒÉ3ñÍû ×Þãõ›ðv •>VJÎ÷féÍüE¸ŒÖN|'3ÌêI¾ñÉÐÅœÝÅ»7/¯¡Fò“oÚHÒNóçÑí¿ªîC8ûFË'¶„èØ(D[oyA†ªéPGÓHÄíwÔíŒÝ â{ã1ðº£ñt4™D2ñ´sޏŸag2ž°E˜çw" é ©‘?É£½×=Ÿàëqo`:»ßA6;ô'“Ád܇M¹;Ã^δ³Ìër·dÐ:LßfÌÚ»=ž´·>àÅqúòöÝ‹3LËoüþB¼ÖÌ¿(Í}‹f¼]q˜+o÷ ¨½[x¿½ñö‹¶:ôhèÊÿà‚ÅcsÙ^‰ÇŸñôBlÑ/.nlߨ ïï9Uõâìc«ƒÿ?´äº {“ÎX N²w§=”ï´èßµÄ÷\¡ÞfˆFWÓnt›·wþ(gзKlOð]‚€`cíbó˜M›º±%‡aY\c®,Xvmï|œ ÔÇžížZ¸‹ãþ´7dc¯Ü³±Ù0ÓX‹¿"m;uøH4Cí&sþ¼-¾0vÏ&©þ\PUü€„?üØ,*м‚Ý„þ_|Œ O¾p…ˆ¨ÌÛ7øMŸÓ2ñþ»¸#¶¸…î’qòëfy¸ Ö_w€Xžÿ{s#J΃ÎÙÝÚ[—ù€:Ft¢;•tlq½kóeÔÍÃ)8‘^Ž/ή&^¿suå%ö²&ÕÑ´0Ñ'öZ܇ÞsèÙø.q’gë*ÿ²SE: ª ú;¾F|TŒ–ž¶œäI$ZbÉl½[º›vLÒ€Y@:=ÍÈ›‹¯e¹µ0þV™$å= ë¥-ïdš¸—!y&voùÏg.þ·ßÀ Íü×|›Šõ•‡ÚDÃsÕëtW#Ãô?o@zyä€hÞÄŸ˜‹gË666_¥øu«:f§÷FÏ™à‹Úñ’iÑ%K ¤ñôÇç ~&/`p\‘\\ì/ÿÏ+`1Î\\ˆt*—[ßÿnTÜ4QøÝ^ÓƒÙ"XηÐd¤( W ´2?ÐåRU]‰UM”=FC~'h'ç>êCxEùïìc1ÚË÷Y R1Çú7fÔiá³£¹Z¢ºØ ‘Þí‚®E¥ ŠvÄÑ6h­yà%±år‚î}ÇPC:Ÿxb|tù?⹤P6GˆŒ†”'^y;0µòtü“¨—Yö“#¬Cx‚n{Æp^VWò$ñŸR¬òžó]z­hùdÁ‹ý6üFó/0{T&E<2 .Ô†~F `OËm{àßg¬p¸ æÄ!H`Boƒ;ú°ß‹WÿÈ*}#’Ã%tiîÙ5Ú£”²ä ¨Fà|¶7W$'b6©ç|Åc4óIˆ”ðÝÞx0à;Å;»ÌwW9ï<ê®”ZDi–‹w_ä¼ð Œœí›"q””Ì» ‘lE.—–×6x&úÅ×>fÿ¶Ï:ž¾òfßn¶±ç±õ°,­äW¸:8£ j3¾w艹Ŷ0/·u ?ð½ËLäSÜ»|j›½ËË<ò»C¢jP!ОJª:gKã÷OHùü6»˜µáÖ],‡‡Mˆ‡Ì$~ЋÞ,x&(üxÀì.Còþó‘_P˜¸ÉŒù’°‘ø7TÊ<¥æ(P òøg×°ã’× W p&^qYår©l´±s¨Ó_{þê\»Dw?ÿ •9?“æ@˜B`¢Üìøá>dW–dS±çX2ªúåíâÏ®ƒínn‚Ù'aO1ŒOØ‚JÁŸ4ÿî/¿û”dè“y‘ÑØc‰u8p„IEM_,‚k¹CÅO²I¬oä`6¿Xxóð61öפßOLOTôv·o߯/ÿöZ-¼ðÛ’Ë­6ÆÁ˜Iêrô¹0#¸["»ÿEVþKÙ „@¬)²ýFúûÔš¥ßêSðå°ôèçlHÖd{}/²RF m)Ð_-cFžLj{ߟ˜/wàÒ[ßTÊÐõ!Úìæóëp¹ oQ……tßä“›˜û ÿU0K.±uÃhÒpˆ^ š‘8r”\N*8^\-ŒUáík,ß6”‡fÜ,öïqP±õö»Ã;”xç›"&§y÷Tp„2!I ÿ+aÁ»„e†_,î6p)‡eKþ æhE}7À¶}{%²g'*‚ÃÜ u×3¯W_¿DÏüžˆãˆ5û„-Ç5ÊéµNaê]l[þM¤!ãZfÞF,ÍD,°Ü/þulÖí!ʬ§Òn{Š_)l˼pˆ«µœ÷ Ò4;q1‰¿ CåŸ?ó³ö¯"PS•Ar‰¾ª¿¯Â=b]Ô/±øôCî¢6¸W©„?EJå†7€ä:éÝž,£îöK½:ÜíÆ`}Ôˆ}Ò >„„°üRç×xÊ<ɤØÜAAQ5§54ëŽ)Û&üËüË`åñåYÓÇgógww­Åóժ婂¡³Lu¶bÜÏL®`(ýbÙºªù‚µÙŠTã¨r4¥Òc@¬Ÿ…¥‚"‚ýá -å¤,'$>LÒ@;œšùB¼bP ˜¯ÌË-f×.ŠgkX6É:7,Õ†ec¡aÙb‚mòDz•¼îd1byþ€l‘o“05©‹Áôm¢+ßZ‰­ïá À;®Þû>£V[Xú6˜VÒÀуi½4K¶{̸r)éÏ>ò‘r5ýå×_~éœÿòË/ÿÕÖšå¤ÐÓQ/;å³&+™¶à fwp´›ƒÇyýû;óÓµ1`Êá2Þ>Dòö~Nq¬»¶6w™Áb²•k—$,´óˆè£íÛ¬(“ȹï(ªLDÓ°'I>¸ÔÔÚ %9ïRj¼ï6“ÝJêñÒ¼V¬„òö¶3ZZÝ—Öå’Œ%E]–3¦:ÔÊI„“䕯¤ŸfJÊHî*Ä‚°^ jº]Àÿ5åÖŠx“ÎùÁwô߸;ì ‡ã¾`ùª&ÑŠ],Œä7)ËÅ)ÖÖ²-›#uÞÁuœ W¦û~†Haùé]“ú¬G¡C”¸÷©Ù”½h•DfE¥2Ü‹¢ÒÍ–ãf!=5µî*pbÆFÓØÜØ ×ØÜ8 *%Á66·Ææ&xø‡assºÊºÀ)r|ÅÁgcÒ¾Ëâ²EcV°@4ž FÌiã ¢Ô4'Hã òØ“ŸŠ‘‹15„‡¥Hœˆ„/ÎDX½¡áŠ~[݆¹ŽLWD…šFîp¢ ÊŠ‘£f¶éNN£‘’[ ®°vtãíŸÞ<ðŠyMªó"ƒJ¦;CAU*‰²¹ˆëR=Y$Û·°çÄüoÞÊ &ê‰ç@å4|¹Û°`ÂÎÅ¿x­Açj½Ÿ„ÖÐ8J™0YBÚʨ'}êÙsœ‰ÛF~òvu²7õ.Æ$«K…Í _L;±_ü ”#…«‘騗[Q w/ûð‹OH³E;&³UØn‡2ä!ÖŽbºRµ%wD‰ Éô64n¢œà‚¤}º@=RÇ"•‰è°è«þ‘R'’¡3ÙSÊq´¤O.{ÊÕ/t²ö©ñɃ¦&Bë‹ÕcÚ‹¦: ¡3¢ _n&Øìñ˵1}™×v¦©¡0’°ÌEa |v›ƒ¥™Ê^Β݉…Ï+Ï鈟y¿&•×$ƪ•É3!Sâ¤òL°z1e0Šò™è„ fžkd®3‰€¼ƒ£ü%ñ…ÏŸf§Ù’PG]ò– žcnÅŸ6Ì~¡¥㛸Ð\¤Éà>s Ô ¿±vÜ·µ#X úèvø´ec8>tW ,çŸ&.¹’‘Q²OJ¦ ¸haŠ—jV^u;z¦nøg 3¶X¢âÑÆ¦$ÅÇ¥B˜k‹³-€ÌC#ÍÇLÈfú¬'kB6ÅJÅÆe0²µØ–¸y‰ÊÈVÜ•+O.O™0êõH^3˜ô†ƒþÙ®SA¾%ÚG‘߀ƒHÙN¡>(Õ½¹ÿ=@ªÉ̤:cJ©ÓO:“þ ;•1§ÔéG“Qo2L‡ãá¤#ôp †w>íöÇÈtØï#eót*™fS¾/èkÒpR›e×Ô„ÇŒ)å¬llНÑÂÞO›ØÊ´¡wƒ¿ð¾á¶Èp»ÎLƒ›:mµ$ I.¥E櫘[EŽKk ÞïÞpâHÿøÜGrµ ëŒÆ}´ª‰÷锦Yª¦>ôKâôPŽ,ä¹”áàFNN{‰ Ê&ëØl¶Ã:̕ڂ›ð°CÄ<¼5H—aWªJÔ†*ø®Ù=Xê“5‘VÑ´AÉ/™Á 9o›È·§*-7¥Ç#a:§ZpÌ^®/©¥‘|Í^pœêµìv$q.¬²;ˆé0,ZF“²ãAhÓ¡%§ÎÞ°ìˆz*Ÿt"CÌ(@!-KFÏ>xWþRîð@¦à³/å„—Rl’%}eKY ‹S¢Ò»¶LªMŽå/Î<’ñþÚWžù÷5~*º¿ñ3ÑýµÏ¾¾÷×>›}ï¯}QëhŸY‚¦Ùè—¦kÅ÷Ó´òýT–î7å²VÏ\%½t„+›ÇX¨lìÆuD—e6ŽY[ôuDŠÜÆ|ñM¹&Hú†G÷ZÉŠäÅRGM|EÔQ“ ç«atL¶ëèà:jbRZGMÕº†ybòïSÖV—»:–;P°î Pê|'xáxŠÄ‘ÀK;0KU&-‡ qö‰üÃ8üOIf:Ž£@ú2=kbhù‰5bYÀàõAK¸t3¦äÔqcÚ ã[…çy|© ¿îáŽß%öQ›I}i€ §#& Yá=ƒ–Ê–Wõ»ÌšjÃùhM^z ™É=Ü,óÅT*¼Z晊Á‡Çó•g;Ë.$„|A[Ì®géJ b¹jÆc& Í7?ÙÐÞ¢ý!Vw¡“¬•ÝZsoïíÂÃv曄 Ölë#Ï Ñ\$<ñ.DqQƒÑWü›vß;á6ÂWj鮼þèe{·ñg)šx7x!é¢(ˆ£è¯ø-‚G#í$5KÏÙç)XÂú¥fªfñæÂß˪Yr`ò©‘;˜d‹{—:!©¦ìµ¬ÛÖmYyÔq.kvduŽôd{­|ýæßIe,w¿»/Τ±k³p%`CVÞ†.=ÂOo2B«Š,ƒ‚‡Û¯·žÈ7ö5ýÉǃHhg|©Ó©k]ÜËXVð9ê16Ìé¨Ycžc±±z©M‘T¬ãöè‹Öä2êxK{¬ÅMäÑEsé ó¶{öþë_ÿüúõåföÀ» f_¿ŠGçëÕÕ^–z&z¶{†t0ûˆ(øÀÞ6ÛwvçûàúZÔ=gks%¿aZÜË4[áÃÀ[‰û¼¸Þ©ß0–w&“Þˆ¯ÕÙŸ}Û´i0ÏÆ=£GWÀN Ä0ïkÎm|îň¨)ù€×í5–¨^ý(3¼,úál,ç€È7v‰\ò—â^áÀIó“xú»À¿DÕŸ¨¹Ž~¬)šCQ\!û3Rê3»)’ôŒÖ¥±˜Ç*«.Ø&Ä})éj<‚ÛEÅfHG&•2;•Í-qøÆ.½¨»…jBÓ¡¸b¦½füºI†Œècìð÷cÉ’^ B÷`sɳ*çgÍkÒ5NdøÈM€æjw‡¬Xk’3aËð Ð{—•‡Oqï²PÙìÝœ|Ç’üêÄ0–³r8{ó‘÷ðs‡=Ûÿÿlœø†/®#á®Ï'ý!yÞõƃÑ DcÞsö¼³¿žwï”ç³}Dhó(0ß=Í.ÎI÷#Õ]œ‰`«àS$Ä|5[8’MDQÆÐ 2áMëÀïlžÌ#*¹zâüÒ”¨ÝeÈ'¹sùÚivn1®Ãƒg!F,…>EúË7O³‹‹4?h2Ì2èÜÀòj6p ƒæ0ÁBÚϺm°qm—#Žx¡-ì¢?¢D~NEf^[v×0“÷L:õLaï)'kš°¹0Ð28Ôòñ s«Æ¦ ‘TµÛÉÑÓ`ɵcŸ‰[hÿ’…ᛜûðp³`Ò7ßß|€å|wÞà¿•~/d ~y Eÿ~Ðd>Ë %qɹ® C€¬r¹”™œc£s¯½ s@èΖ ý‰ŸS…´ˆq~ØA.öáf'Á ™µ©½ù\æeúà7l Ÿ(FÖoòºÁðëϸÑâxñÉ‚;!"7ˆ 1à ðOºÎÎç¦SÄÅ;Êó-žµ‡ÒW<„"œo% ‡S#3Ë>„Yžßˆü´ôCÒrétlÜþõ94g¹LáÕ\˜£%‡)‰< Ȳ‡ YVl´j@Ëd½ˆð%¶ž¸JÄÎG8Æš™A ÏF³³ö/À8ƒhJ¶qÀF1Á¯j!ät¹Æjæ6z‹tT·ï×—{­˜uá&YtÅÌ î·áÙü­«8v_º•5¹xžÍ·ž¹‡‘‹÷t(g™ù ~&”3ÓK0oÆl[ýÀíl½l€Ûó€ÛÇ9)£%ÏÜÀ¼AÈJàêêH/'!Î š|xV}K&O­Œ3^k¦0áK%W' N”Z8v&bøwðön½CÀ±éâ™ÔÕæG×¥°å¡¸øŸDõšä€ù÷•·ó¾®e®â‡Ä’G2AdBIÊ„”x«·Í—ÃÒ7X}ýœ-=Éšl¯¯ÜVöbë;iQÊ}‚ÇGŒˆTÔ4Ù¾›lß?&Û· …-N?ª3ÁXìbÂ_%Ñ~?¹ Z¦…"×Óèpö”V]ù#²ýóð(.Œ*æ‘;9ÿEÎãüW, KÌÄg¹| õÔ鯦ÆîÆ:AÁú%LÝÝX¹¬Ãq”н_u*í|—Å…‹æV²ä§üÝ_~÷÷]ÿä#ÎÖ0ª4·Rs+¥\Ÿ Óm­Çì *Õ2TíÛ^¶ö䎿ðI£·ëéNf~±Âfâ ç0»£c9ɘ‡è¬yªž$o_W¦·.cðát¸´,[8KNÇÀäUc$¦°óWOö÷ŒŠê€úxy؇_|Âs,Ú1™ÜuF¶Û¡ y(JHÇ)÷ ˆD”Åì8Á³˜ÓöéõH‹”Êr lPÿ2Xùä—äq §E_ýñÙüÙÝ]kñ|µjyyl±¥:›„Æ­Q ‰LÃ÷0S£’C¢¶’"áPúæ…–êE#uJ”Ÿ”hÄn÷@…§EÏôËíóI©ß/—ÕO_n®_nNdyòßH™ðÍÕD¡‘: Ô™'ïÙÍ:~ÄUa ¥Û©ìê,9ž˜7Ȉcˆß¯Émâè<·l*ŸDe0’IJ<ÎÈ$òsq ‡Šµ@…,·9ãÓ5k#êaª³ëÚ‰8?°øÓ†ÝÂ/"Ȗ蛸ÜlÏP^¥<ÍEˆ¡R9)`Ãzj\ÿÖ,1"ÖD'7ÑÉÑcôlm‚.€˜‡SRo"‹)‡•"e_,øÀ„Œû™‚-‰úb1Çœ0+âñt¶äp“ˆyh¬È1+²HÏIKõ”åyÓ•Tv0ÇHvH]È cXâ&*ƒL_˸7!¡´ŽÒ&ŒzýR( &½á ?H%²)—hE~“©'¡?(Õ½¹ÿ=@ÚªíÍ%( ·Âg޹ŽtÎǔء;žt&}$Ô”1'vèG“Qo2L‡ãá®M:6ç|Úí1é°ßŸ`8S!zÇ£u úš´ÔfhÓÇÄ¥…tÙÚ,°:Í­[z7ø ï{n®3ÓäÌÖN[-~ŒuX°Ø8•å[5¬5Pïwo8I›?w©yqKfaQóG«š8¸³¼ª)–·+œ@º&{‰ Ê&ëØ’K^Ö¡¡Èb#ã»ÇNÙ–%TWµàƒÂéj›pŸÂµÊ Gàgó%½ÀóA ¨ q‡ïaù_ï9›H¼ªM?:w¥LôÆ¢DS:fUàb¥Êõ%¹ddPf/È™xcº{ÁnGRçÂ*»I‹KNÊŽ§×-; Þ°ìˆz“ôˆDêmZÉëXÖŒÖñƒwå/åd²ðŒµìsî#±M–ôYÛ’‘°Î‰ZïÚðÙNçä^ŽmI>õ3²A³U0¼¾FR•[T¼BÒäýBxÈGyKkŸî­ý»ÛÞ_û<Å÷׾Џ§õï±”tãgª{íó-{ísØkí[¨š‚iÊVâŠ0Y«pE•%ýM¹¬å3—I¯yå2ÃÔ…D÷4¥[ŽESé ‰*|·êBâ[}MlP„$¯¶²5ñÕRCMò’¨£&&÷uÔÄ„»Žš˜×Q“ Z¬¾v=&‹uô‰ \¼¦¬½.·µ£§Í/øwFÑAoý£û¦ò‚ëÆ uaÑÁ»CL«ðPoãÒœ½–bÜ24¦fÌ— 22td*äLÌaÑ!‹‡÷I0«,”ðúPò$ƹ Áw¹C +ÍÆØ—4å¡O«‚X#÷o„o9–õˆÝ¤>-»qÕÊ–?f8‡VqBstq_°”Ì¿KZËÂ1*õ¡©–r·Í?C*«²¾ .fW(-}”wÓÈËŒñ‰ñR(vÄE(Ås‹÷æåõµáCÔî1‰+¯©Ñ2)œ‚ºl‘ß+¯ {‰lMMw¤c]T‡¥;³¢—±9²Ì(> É£ JÉÏWáÜ_šn¬â»ô3FÓÀx_Ó¿ó–x-)ዳiÿõ«Qò¶ójÚë º¯:^ÿíÛ×o;ò?®à°jGn—;%Óã(³³äh”–TN¿áú»ö÷` Px×HÝHwÎïÄœÝlƒyj„¿á¡`8#n­¢3’üVph§.óëE0‡]äB‰‡\´£Ó&‰¦¯f¤ß¢*uwH­Ž·ôéEöØ6¬Ñy¾‘ó·[…€ùü:ØsÜ;?U[Œ†öS×EG_n1yê®kÓÈÉñO’'!s‘¨M§6š Zc °ŒÑàXSŸ3zt™mS3m<æã,æºùæç™Ú[´?Äê.Âmð`ÅyÐô•ÛZsoïíÂÃvf¦ÿ½_4ÛúC!:‰ïB·5}Å¿©1¦ìá6 'Ð:åïWzÙÞmüYŠŽ]àÍ^HZ& âÀhå"ýØ% (ò†¥r¢fxé"lêÈTͰâÍ…¿—U3ÇÏ$O#oD$˜z‡–¥ër¯eݶnËÊ£ŽsY³ë …s€JíµÚô›'Õ¨Ü üî¾8Ó€Sj ‘41 Wöcåm6fêŸOoB§ŠÍÕ ·_o=‘âkú“‘”ÎøRÇ%ª«XÜ¥XÖ;Âü‰ y5æ9Û `‘´}G*ÅAñûе£ dÔñ–öX[¢’l<º.ýŒb{`ÝþãŸÿú×?¿~}¹ÙàJ÷n‚ÙׯâÑùzuµ—¥ž‰žížm¶á>¢ ~xÁ²-8µó}p}-æzΆ6æJ}Át¸7ž23 >¼Xl_\ïÔoX¹;“IoÄ×àláϾíHº4˜M;WáG="ÿ;îÂRs^ãó.FCMÉÇ@«n¯±<íðêß@ˆá%Ñg‹`9ßút{Ïß¿yqöéB.÷Kq§p¶ùI¼ý݇‹‹“ï_¢êOÔÙbMÑ Šâ˜öâìâ°ÚQõ±Rf/%c«Gd4&ˆ LŸÉ¸³ ¿$Ï{2û°Õv¬ƒÕaõ»6ï½_ÃØ• ÔÆ¢¹AÃÍ©#Ӌ˃d+{dLƒ%IŽ}&êÊ«Yj’tÔ˜ðx¦ygÓL©°E¾¦Â «\.UTª Ö/æXÓ×Þ†¿Id‡Ò?üÒ¶+ÈÅ>ÜHo¸}8³6{.SW|ð¿ûÔa«Ü"Ð'Ü3`–O1ŒX›õMÌHÒ¤¾1ÂB#µÿÕ$dþŠys6©oXpgÛ`#ɳ&jŒMþÂ|òw›¼ öê§p¼R¾š7þ«­ï}{åQÐQ€s’̤_î6Þ ®Ñ÷ßaêç¸~éê:Ÿ›ÞïP ÔX5Ö@5<›ŠiÂ7 á@Bø,جp½"àz ÝôU–XéÊßò—_ù¥sþË/¿üW[ÿÉŽÿÑ“³Á~m¸»Î|ãÑ®ç®çh–%ÏܤøJƒ­ë¼NOœMŒÖç(³qwØÇ}aæ‰ã‰1y1Ü›ð¥’Pøiu%_ƒ±3ü;¸z·(i‡©ÄMêjó#„ëRØF:ËŸHõ*c)á-ÿÍG¾Õÿ¾‚W&…],‚kyk‹ŸPë@!Áh¦s!ðÇekBh­`ŽÞ"µëíûõåß^ó÷ßàj§+òG iÒz‹Ï£D&”¤RŠÀ~oõ¶ùrXúF½ú9[z2Õ[Æë+d¥•½Øz³oºßÐÒ{û¢1¾w¿;¼Ã‚½køÞÀ÷:RX‡DS»˜0÷ÇÐï‡ ×aA˪ƒ/¡F‡ÓèpNs—5w8¦¿ \EÞ ˆåÌüÇ£@_¹A`Ëbô-Ãæÿl£~h—â¢4¢•—ŠC =øÔ'qᢹ•,‰%oÆ„0c ‹‰…×ÜJ?öV*…Ï%ñû+àm%—p³ ÖKè:D`?u«¸¢ßVÅ‚L¿ ”žüè„gžrGýÁí%]F ±ÞÌäµöŒ„ÉÚ#ó,„y *jfÚ^ ŸUT;b.U^1>õPÀ<·o·Þ&æÃð6ñ„s r½\nØX± ÁØ ½Öp,â…Þσ-`.T¼vâüˆ½ÙB ¢ˆ¯ØH"ü6ý¹¥V~¯k’ˆ+o{C±rÄ[¯°!Ð(- r¢¸U½6ÖYÈH p\>êâÀ"jÜuîÛ]Çv¢Szu3Ïh“’šh†-Õ±)©%¾›9 i©©µʹ·bÝ(×çd¾”!ZlRX™)¬pϨ`Rh¸¬Ú‡ç‡šå’ÜZ•s(wΧõYIe¯%ïK×c½¾“É‹2ÓW—…ÄÕˆk¥kNrìfnàKÅb£b¡›)¸áË,Uϼ¬bS’߆b‡+|©PáÞ¯¼¶ë]–.Õz ,NƒÃÕOº\˸-‹—‡+êAÙ¼AÂwW6̬Tr–­õ˜­m‰ÍD‡²ñÂÅ•åÞ…¡@O$Ýá>¬gÇef+l&ž&¸;:&SƒyP£ÎSõ¤OÛü®–=722N&ÎZv ÉÞÎ’Óñ7`¬K…Í _:õU=9Û±¶ŠBò†Ø#)’ˆCJe›ŠåçɦˆÀ›¡§/ûð‹O`ŽE;&V™b-£  ¯#Ÿ¼"å;Nð̉\ ®©óQH&Ym¤Îº¥NVÑHÿ٥Θ¿ïìÌôõìøÁsè¬^ÿþÎluíC#|—Xá ÌOùÃÉ ú«ð°Ã¶kk ^^½†'éÔÚÞ z³»g55†G€«xGTŒtsB1ªê‘äõÇJ9‘åI2ÕH1©S…Æ7÷¨Ôŧ•:3%ÉLcƒ%¾âˆœ/ƒµ›,íTâ%geæ}ÖuF\Ôû5yÀ–Tåsž ×Í{Äñ‘-創@…Ü´9ãÓ5Ûcêaª³ëÚ §b†½Ú°[ø…– oâ2¹=¯xa”rNÄ…ñ1T*'…Luxôþe°òÉ%Þc0‹«ÄÇgógww­Åóժ凪Lu¶+”[#ø€LŸËa¦1/Õh¢6[ƒ…ô$7>YæÉ„VË÷=[c9„ °a¢Æ‡Ê1ä:Ê‚N~Œž­MÐÅA*UI`„˜.—K…öü(GÕÓÇ‚LeÝ¥Êë%¦1´]¢ï‘+%€Š²ÞÛ;£ÖR’7«I‘—NÉÓ& ÓöÞ‘2Ó×fKÎ7‰x¿FžÉóz©ž²•H=î~¦°UÛl¬d_îOáZ¥ï…#ð‹3úVzçƒPAb옛—ù¡);žnT'­s¾‹É9³j/×—äÒâµä´¹±(Ø cwGRçÂ*»ƒ˜CÆ3꜔O¯[v@½aÙé”Ò ´b‘—mù¶5£g¼+)·x r}Û×rÂk)¶É’>k[h#{¢Ö»vʽÛ ¡w|êgÙÄ8¾;{:W)½B†ãýBxÈG KkŸ©ÌýµÏ\ú½µ4ä÷Û>/ñýŸ Ä÷×>[†ï¯}6¼ß_û|ëÔÑ>‘²U³Q0MÙJ\QÓÊWTYÒß”ËZ>s™ôÚ‘ '¹@*Íä…D÷_°¾SÜØ$Tá{¼Uß–kbƒ"pzyµ•­I¢$×P_5ôI’û:jbÂ]GML‚먉‰i51Y¬£&&pñš²öºÜÖvŽ^óïŒ\݉äÈÓúG­|i#¯¶‚C7¡ÊÄYVˆÅI:˜ÇÕÒô¢Kñ@Ú.cjÆ| Bx'2td*äbÐùÔQ‹Í•Ãû$˜UJx}ñ–à’# ÈÜ(…®j•]¾ybˆiŽr°¶£¤ê#œbÔ§e7®ðœvØèB'å8µÃ݇Ó¼tÕ3•{¸/øLòÝT*ÐZ¦ŠáP©EHµ<å6ÿ Ù…´¬_èRܪ#Š}UÃMLò5µ])E²ÍpSŒÝ(H®¹>ÏÝ>JF/’Ý«yL° —BÛ%¸™œÞ"ܾyy}m8Vµ{|g—W_iAžRÝ:Ðô½R_ÙK$ÕWR1¯Ó~_»'ªKG•c'¶q,v,1p‚Ôîi¥’Ÿ¯àN»4ø*ž°ôTz¾²VéïkúwÞ¯åõðâlúº7}ûæÕÛΫ—“i÷õ¨Óé½|ùöõ;†íìÈ‹å°jG¾¨ÜeöÊ#XáH›ÜÞ"\Å|ÅKéWÚÆ0ص¿»0Ýwo¤Ö?Š“¿ö–;ŸÉ›m0Oð7<” g¤&c®Â…ƒ&õOÙ7îóB$)Ñ…x|ú!•쫼·¨€p¦*uwàÅL·½¼ æ{lVs!é•íÃÓy-‰ùü:Ø3?ívχÃét:'Ãi¬( µ©Û˜"r%Ää+¢M3EÞ”’æ A–ôcm:µ´ˆ|#Ñ’KØíkˆwbù}N“"=¾ÔJ¹*±6Í7kdlƒ<}zMƒc]S–Rû@ÞhO‰±Ð)ëÊnǹ·÷váa;3ó0_‚Am}8em†w¦w!Ѝ\KO8Œò^ “.tWQ¬’b‰b>e½&i%7jJÖ¨Z¶xÁ½¸øûÇ¿¼ü«tûŸ.>D6½7â  [Vn{À ¶ü×7Ÿí -ÌìõGYáž@Þýþ›fKoÂÎ_p½çß½å!ZÝö…¿gXýÙŠ;…¸“½ìÌ-7`¹´eÓ¨ÙCÙŒü›A$-9r;a¹-1‹Ñ ¯iÉŒÊj™òù»Ã’Åü-Ýgä^òž¿óâ SˆB”f‡âú°Ä!Xz7˜98’³<0^§19£iò&=§;N‡_Ë®Mó,ĺhN‹î´uëóU~ª­/oˆ¢­ÿÊeë ^вì¹[Ÿ ?xë -N¥­¯øÞÇ»õy=È­/óºˆê÷ø”mý×.[_×­/o´¼÷¥QYÞÇ}Kòx÷¾ŒÙ|ˆdŸ̧"ûR»P´÷߸ì}¡§rÞû|ýà½/ýõ*ì}¥”{¼{_ ßçÞ'&(’˜K"…uGávop /…¸Û“ü ½lï6þ,¥)¹À› ¼ÚQÐ!Äo¹¹sP³ôœwo°„ŽÜoªf8h •½¬ÚŒ×€‡¬È¡£K½CËB—¢¸,®ÛÖmYyÔqî‡Ùu([æÁ ñ)J÷Ù@z¯0ûŠßÝgJ[¬é¶gáJ -"EùÆÌ¸úéÂAÔ½N¸ý*™ÿ¯éOÒÒ kŒlGY²Ý¯CÌ<à„öþÒ!@ÞgÎ[³`3]‚Ä ."™qbÓ£×BÍ¡¨£)wE²¦Ã&û€ýKC“ ëã½ZFnVŽŸšcéA9•nÉ,`î%I±RÉOX<)ç•Ï4¹€”së‘‚¸¬¸ÇbˆÜ2Ê/M€©êIç"Z†‹„Ï\1TŽ’ ‰eûb±¯–Þú›ÚØ‹²¶ VÈ–%ûuqØl–>íso)kE…ËHǪ‹¯kè‰lý5ÉãGLÑ'aVRÜ'"eéýÆ”U>ý€f'Cnw>ÈÒ©TÞ©Õr$Y¹äx/JdÉ Éé±dI¾Ëäl:h€æ ‘ºzò«âCSHtŸÖAŽë«äHLt9È ­d™YZ¬rrüÎnÝÈÃæFκ5üü²9ÈŽ¬u\»Yý G2¯ËANèXËd>wŠa±ÝÈñ;»ð šƒüpò›§~‰·J×Ìš+WÁ¼âQÂ]ˆý‡N¯q8b€¼0ï³ÅðêéË;Ö*üÉʺ˜IòâÝ[²Ç¶¥oÀÆ#çKAñÙwÏþñÏýëŸ_¿¾$ùê£w̾~Î׫«½,õLôl÷l³ ÷!`ìðà –í‹Ãjw¾®¯…¢bÎÁìªSæörè9fŠ,il2fŒtv¹Þ©ßÌíL&½«wg ömwXaÔƒÞ|0Iíœ+v"!Kæ¬Æg]Œ…š’‘`·½Æâ´Ã«#©/ˆ~8[Ë9ik«° íWÍ©oâ5è?\\˜{ÿå>Q{ÄàÄÚ¢Œ™N?/½`MõÇŠ™ýDš•%ò¬è1­ ƒ<â5y°RË¥ ¶ LP:Ôêü”ÞC4›…[LO^Ç¢²¹Å"—9c“_±Ý‡Nò{†¤Zl^q ìè{éáu%4„íX¤òIQ«8Qn,V²"™ç› Á?Ž÷õ* á2À¿ÊLù[ñ¾÷6H¶rØsœÛ¿CJ’"¾QÖíÜ<×™!æ“þ‚Ì{ãÁh€?ò~ç sû;džñN™£‹ 7”¥&=äÏü¢Ýeˆ·çÈð²^OôƒiÀ.\êâÒÒI@Vʤ•ç”ÿ†Ð2ëxå@>:vÙV…ÝqÔÜbÒåkxn>`Ù[8Góï]6;<ŽËnºÍÞÍA‹‘äWcÞ>X ÌŽvÙ»˜wùOHÇLtŸü.–ámVÀDéþÀ 1û}>AB,+:Î-ñ‘X‡×xU85}±®÷jvð“Rí­oø¡×]ˆü‰±#4†Ø»zõDEo‘Jýöýúòo¯Õ‹ˆ@¹ÜjcŒ™¼Fè\ôyÐîÏ„¶ŸµÇíɯ¡žWÙ»¾é)ÅñöX9ÎÈúæ Ò±Æ@hŒç×árÞ¢ ( ³œSLnbn4€ûl0K.±uÃhÒpˆ^ š‘8rs­Ç‹«…µ*¼%¸šž_N}4š8ÿhx~'8r¾/¼9œú™Ž±£ÿŸ?ó³öP≅0E²ÐNÀ›êï«p¿a——q~ L ãhe½¢ îU}¸IYÈLG€'àäØê‘oêÈŸZ&¡Q“)ÅRåäW•‹(öA“!‰€nLÆå®;|„üsó5<[Œ=$ö4ò˜HnËÛØåhpú9;v$k²½ÖXQ>j Mßðl ÏÆ‰ÉYæ{<[É|€²˜5RéíŸWIUd¾ò kK©dºXÅs)I\$N¼Tcžh 5Ãõ6y¢µÈSäåøLv«É)Ë)¥1»œ„8¥dx˜VVÊ8c»ˆ{¾rRc¤Aª/G´‹Mä|…-{4°?ü;x{·ãË´&åŠ|`㺶‘Î’¸øŸDõšTi= 5j¤Ç½OFYö¢ÑU Ĺ&•¨´Ü‹®Ò‘ÂæÄ|D`¿Œéøu813c“庱»±Q¯±»ql`{#-ª§Ñá< Žã]–cPŠ èü].2íæétU »Þ7–v!i¼AT·Ü‘F¶±,4Þ BCÆ  «ŽÉÎân³fã^ý‰2øÕž6¯¶¾÷í•xTY@Ë”¥;Ó®¤_îÈÎüž\åþ@"ÑO0uq3)ëá¤ó0, ä–$ÑRÑÈfº™|E+ J²›eôôíÚz¿H.d¨¸¢ßVçw®#3Þ^åÒ&?:ᙧ´“*A‡tSð•¬aéÚ£äË™¶3-2ÛuVUØ6b.•íFl!õPd§mßbŸÇ´Œ@˜‹}#¨œÆo †X˜ëe¸AJÙB¯5œéžèý<ØêBÀeÀkg!žÁØ›-¢¨øŠ$ÂÝÓŸ[jå÷º&™·måmošú¢Ò%üêï·¼ã9@«µ­³‘÷’|ls°@¤sF˜v#‡]Nlr,ËsWµq×Á”Ûl‚¤ÝööDŪ”4_‘:Md]˲ X®ÆÆBjðáHwEË”m!e«—j,¤Ömlš”3÷zν•ê<–+iÌJª‰Bc%ýs(ü‚ƒÆÕ}µSŒtn ø8 hèÚf-²/Õj%•”Yò>¿ûxtÉY¯ïèª'2ñ}ûxÁ=oÉZd\÷æý {QPs’Û`ÁÂÀ—ŠaÅ"èÓÉsc°T@”ˆ.«Ø”ä·¡VÁí\*\¸÷+0pÀu¤–Jµƒ‹Ó‘`EµE㈀ZÆm²ÞrÜyuG= å'|ý"˜&ÁÔ)°™ðS¶f­Çh]Kܳì·ÂÅíË Ÿ¸ DÕ1óHšÚq¼ý ›QÛ䕇¨ª9&pW´1=žv¦,¨'}ÚjÚsæ~Oœµì’½)œ%§ã¯ãœ›ÁL;±_üïí WÃn)ª¨æåa"ýüIŠvLf3ª°ÝeÈC¬ yˆn„TmÉ¥*q!ÙÏ®L>›‡'„l؉HJ1ƒ*­EoXÞiô‡‰:qIɶ;]ÄNvå¨_ì”ÉÀÇÜðd"¾òA“©F쌉š(4bç;3oîL{€E}x„†2%x¥¬–v*û:K–Gaïþÿí]YsÛÆš}Ÿ_¡r^fª.m‚;=婲,ÙÑ”ìë1•ÉM^T ŠˆIBEv4¿~¾­Ý@c!„Z‡{-¢Ñ;º¿õò¨+ÇV"Ó\¬1¿åCwñæÞ×nåGCš9{;ŸÅ[‚ˆ’^|M¿`Ë'wŸõ˜àî/ч¯L =F÷%6Ýb47ñËî¢8D¿½ù§€û¯ï…™(夳Ú,Áø´$Ìæˆz¤êüºbg`Pú§ ¼…h+ñŽ­”—™Dò$Ð28ÀÆåqdÙ³8‡ ÀuE(L5¶UxjÙyØÄ¶6±­Ï.¶µI»h bž~ºq®ågÎò#L7v¸£ì¬ãAQÄÂ_çM.€7I„‡F¡·zí=yÎ ½ -F¤›æ$ÑÒJºúÜ‹íÂ2_i©¡% .E^ìA§Û›Þ¨ÓïuÇ=±"›q…ö¡ÈDD2m0 TêÞ,øsU.½ÎÉu¼á¨=êö¼±hÄL®ãõ£AgÔïûÃþ¨Má7þk"×{Ý! dÜïvG0œ±Í©áõ5í=©Í½«X1>ÆòeVsò²÷¥>7{Ç4ΧúSäçÕ»!XøßÂhSæ½²®3Ó«D¡³§®ZÒÞ¤=âJË|XVlE‹:‡&¨‹øŒIÚ‚Ù^#5=»2»¥u&ã>ØÖĶ‹ê¶¦.˜”­Éóè$—÷•5Ê]â¬Mα¹ˆuø,µ?8 á>­0o Ö•úO€‚ðj™€Ÿ¢5Ç‹ó¾$4¶¦ ¢`w1ë-P‘cø/räiCǧ sæu˜ÀÓ…°›Ír—ëÊqÉv‚(sdv5.RPÐc6Â*%{–£¨ÎQÕñt¼ªêô«Ž¨3ÊŽw -J°›^3\ÇKÿ&XʃµòZÒ6Yâk-‡5™7›Yë}‹—ñ„ß¼@ Iþê!nM³@Fó9À1+n8zÔú‰#/èÈbÏöÙóx¼ö9Óâxí³‰ñhí÷:éxíó-s¼öU†Ä‘ö?S=qüì|®cþ§šëÓ'[…+jôÃWTÕ£¿)—·|æ2éµÃ<“ iœ¹PH×óÈ¿WVxOÕ…Ä"ÅÅ ÌÕRµ&¾Zê¨IÒñjè“`7ÿxMrp×0ºÁuÔći5ñ±XGM|ÀÙ5åíuÙÖn‰7?Éï©´·Âpx¯M¡ØÐƒCP¬#¤n‡î`òtØêä--‚ŠVR!ŽwФ#×"g¡çc+Žè 0*Ë_°÷ó€Âëƒ"˜s…ïò}r]÷û>ïÇ^Þì^JÅŠQÞæa»I½jÄdÓ'¬¼Mnªby ·Ý<«sØx´­Ø +÷áÆàMηS¥dk!ö`~ )Òð¿ ÔH–6¥U$¥J°JÛ§óÅìÊ+ sO¸×™J^ZH݉WdÚ¡«P¸Ø«ÄñÁ[ÝV£µRˆ ˨ÃVã.‘o«é·µQ2‰ Â>éÓš#Ç¡iæ¿Ûkk-å*šK3Þ†Þûˆ¿ÂŒá40æã/küÿÙ =–£ðÍ‹q÷Ýé ;´OÇN¯Ói·;Ýóówçmù+Ø­Z ‚Y¬4_ü9a°~¶™“'”²·¾…q‰¿Œ¹/·bâNÒÂù õvÎ2#ü?Ê£)nQÖÜ Sp¸B“2öÝ ‚EáOÞÔ aÐeøý#—lkîz<¢±ÀÍeX£î ¦­ÁS| #[Ø5lÒЧ`l6˜Þfý>·œú画Gö¤ëÂ/_.;šy9eÑ x•ç]aO–ŸÕ<à˜¯&!få¥k†ÙNäTsøÞåƒû©r í]^³fï Ž‹b+0‡{³”‘¿‹Y­›úÀîx³Û²;þÑÜè­¬G›“Üœ¿ÜH¸Q·±paoЃ°÷Ñͱpîg —óLűü‡ÐxE»˜W¯ÙÅåXÃü æ-úb^ºf —%ÆY(-¹¨£u`Ÿˆ˜'Ló"Õ£ä—=‰ZÞˆuÕç¸sÅɱjse au8Ž–zø Ÿ†œèl+‘Ø^Ì1ë`€JxtŽouUávÇš[¬º'nó"L˜‡/B°*ó w±¨¯Ïþü• ç.A˜RŒê1ÌúÌsÜÀ¬Ã6¸€ŒR|©z³*óT7° )ö¦%Øî@0¨>U`Z ç ãï§Ó59vE„OtöXNßTÕ*\‡«Ýêgíî»Xƒó+/g"›`€rPA¹Z{°fvØ>ì¼XŒipй¹g¢.ÖÌJ“TdñD¸6•Š£¼ŠÊ—ós°ülÁkù)‹ÈðÈ郩gú¥†Ø¦!¶|é¯ow Íx-—ÑwØO ±MCln E â”8ì_™¬Žôq‹‰YòØ(Ƹ,úWbs%ês63£#&ïýüÙ§ßZœMúz!œ¥EÌNSÿ”m>z~B¼±ø‡6]PFtm}±ÅyÑË—Q§xírÎöÁ–akÉÜw,[ÃÖˆXHÊ)Þ åu @àDYopĬŒß†°Ú…ƒý“¨&ˆ´ !`57B›)‡4l„‡ m œzcZŒŒR/v×§Î"±Ô;ÝAÞÅz (¤ì ±œ?¿7Ÿ®ƒ[ ü&ùÊå'¯ àwˆ·v1pÄ-íñ23T¤è|ãS¼rËŸBƒþ@€…ôP `Œ'<ÃèkÛ)ôRÕSÀ÷×ᮄW˜âVƒ¼f"¯*‹õœ‘×~û¬Ë dC¯ôÃ.™“S‚KE,·Œv]¬]°ŠÈÑñï!ôû)9L+nÚX[ T—ÅÖ¦""¶W´z\áu X=Ip…ØÓ—K•¿š}ª·Í—Ý2øÓøR™º’®I¿f<¾ÒÙp·Ü}(€»{ž°å´ ÚçpŒ‘¿ßÊ-?Î\‡ -¯/ ŸÓØpNcÃÉ\ãíu¼»ƒTÊé&¼C÷RcÃIù@ÇÛžwY9×è@ž×ÄV.š[‰c@HOlÂARÛ€> Ò f9±ZŽ9Mga§Õ¿æVjn%–€ ù¦æÃo¥*Ð[nˆEý lQœe¸ÆD°D€Ë0q%ï‰ÔEãËe¼L ôŒ¨2f—b²™è÷˜œÿ* &]{Q¾}.)¯`ÂçU¦šKÅ÷BãS?†sëûÆ¿³¬Œç©wÙËi Œ¹aÃ2W‚=ácÏBÄ„ø|n÷‚°3 lgA¿A¦‘?]D ½Å¹HC̵òs]“€®üÍ-fÆz ÅëÁ¯€ 09aâªJqÎB;ÐbXË—Àº¤1¯¼<Ðrcg-|°†qúØñ:®O:¶cÒˆfØTQn ã´!ˆ—ºH9±q‘ÅEZ¾›œT|L5nRËMª…ÆMú§ErÞßiª¤\vêÊx·:ܸrÕiy£> ¦îÈ ¹ kŠÛP1É;W (îb¥rnBBªË[øqÂí¼ÚlReZËÊ·²V³Å6"—FŠ­VwR ׿ -À¿¥¸rKê1;SÄ€µ×PMCYâÒŵظ& §–™Ï%ý*mÆfƒ…ˆÆ `æ/ˆb f™z²_Û쾎‘÷¾úÖò[H÷¦t–öÙkÖç_ÚŒ¦e‡ù«‡“=§¢:Ð>Þî¶Ñ—ñËvŒÅÞf2¨åTá:ëe,q̵ç@½3W—Ìõ78ì‡ûû$‘úÜžG;wHápXí,"•”¥êLdš‹5ÒÌ>ËÆôêŒ&½ðl 9¤K¤.Št}6 Wàž-Ÿ©ÙQT_W¼ðgÑw†x ºð[øÞ0Æ;¶âìæ /ÏT®ÄvÏþ´¿0Ó©®ÂU€añ>£­8Â%>¾š½º¿?Y¼^­N|㫪R+…Š[C>±Ü¸Ë~®C/Óhª¶Š9[ûà¾TZ¾GÝj‘—Ä4qDMÑN  Ú¹½A:hC~iŽz¬qDMâE“xñP/=ö/°jX ¦¹ÛR‘/–ÍÐu‰^J8 ·õÞÞ9µº:PlÕpæ™/´º¦3¤Übâê@AT¾Z_pB(Ž#9 £“ž³BoPDzVê†zN´ @­ý_³{·Æbû˜° ð~-­àPý·ýr<èt{À£Ðuú½î¸'’¼©WhŠ|H0 TêÞ,ø‘U.¿ÃÙ¼á¨=êö¼±hÄÌîàõ£AgÔïûÃþ¨M¼ ýrìu‡0q¿ÛÁpÆ"4§†SÔ×´÷ä>ûZ\m:-}Ÿ²ekóÁêÏv¿6ônþ·0Ú”y¯¬ëL«-…µ¤½I{D––ù°Ø¹™WaÒ°6A]ÄgLÚÌö©yqË^ZgÒüÁ¶&öžU·5u›ŽÈñ<.]y_›Ü%~ÀÚä›ËX‡Ï’×;ë³tŸÎ)îcŒ"WLé¶È¿2$cí2dÁ§h­Øy‰xß­DSŽQ°ãpu&q#FUݨf²NH‡0›·ŠËÊuå¸ä(¹¬¸£ ÓâZhfî=&'¬R²g1 ÷¿B¯ê€:ýª#ÒŒÑÆ$6.Š D:Ö ×ñÒ¿ –²ÅC¡îÎYË Ñ6Yâk-?6¦§j½oñ%ýšBÌa›A¢õSñjX„æs@dÖ¦øŒ· Š’OXLkŸAï×>uÇkŸqyŽ×>½­ý>;?×>oñ㵯r4ŽôýõÙ£TÇø§šëÓ'[…+ªËÇÚ\QUþ¦\Þò™Ë¤×]8…Â…p'Þáze¤Ú$XáËÿ[ÆÙÛùܤkuÙŽ±‡µ²?~9îx£¡x)ÐhÙuEÈu‹ æÛ. VÉÙ º/QVꀰŽ&‡AÓÀ¦Á‡69_Ôë+À9^š_3½÷…ùKLŠ¿¬Ñ´8;¡Ç"¼y1î¾;tÇoÛ§ãN§×é·Ûîùù»sÆmm³vúW+‰DŽ•]ì`È£€Ÿ3¥Á—‘~ɱˆ[ßÂ8„N˜¸Ê·âòI€æþ2dý7á,3Âð£ 0š¢”bè´ MŠ<´[qߌïõ"œaTJý¨†¡A±óøá8c•¼±e>üŽ( o^tG/Gmo4è :=˜ÄäâÓ;HÕ ’z&³¢rópËhRª¾©ñh¸¹Ýq{ÐQRdNÛï%˜ÜÇã>¸¹Ôžv4í,–jYo[Y<²ÙZØ>F°ÊK¶´d¶ðËÃÀ·9N¤1q0ùÉÌÁ3Z‰€éi<ÐU/ŒŸ¹*qóÎÓ™¼%âh©ˆK‹L*å«”çTÇ,;f¬Ù )ËÁ¡’®*܆Ks‹‰¹cº…4§ ®¥½“Ýð"æN~à[˜-fÏq ó!Ôlaw‚«¹…ÅÀ«Éðêy,(ù›™—|êqöÍnËaŽDˆ“KïˆÊé'¹X ¹G=ùj63ûSÓØÉâáof–·ŸãÉ,Ò³.8ä¬h3ËÉL1TH– ¤ç¸%¸#»AŸßÞóm#bñ“’ݼ³Nuïïcžã>æs¨.ÜààIùaë|œÅú,w²Äc–Ëè;Tá@j5áq ŠAΪr£á2\§‚H´ _àCÛ%mÔ‰~ÞôãïàŠ¼Þ¤Â&©rLCH²G.W »ÈÑÀª=}Xµ\…§«fzðí! ÔÝ 7’¤)ñÓ?~ú©ýò§Ÿ~úÏ–þ'Çz ,8ÐÔ‚h•i “°øB°øÊáZbj¸Ê,®2V-YURIÅ^;›™j“÷ˆIO¿µ’û‘?SQÿ†ÏmáQ\Å™:þÛlƒ{U_*l^²í¾ù°y •ihĪ8ê¹®Ôî°Ý…àÀl¼Îh <¤b÷»ƒq»;ö†ÃÀË;’½F¡-j¶v·?ì´Nbò²xìåÉk¸xUR®Ë@(‘"´2”¼£6Ñ]°ÙÞc죕h“J¾^…ëpµ[ý¬³%.Ö š'že±‰pÌuä~ û€e—«æÆl8@³ÝB¢—–É¢Ýí‚Å­¯Apw ò]|Ý‚0lD¸»ƒ»äíúü7›`ti¥¹: ÛÊ¢¬O¥#žé«è.œòÌCÊÈ¡s·Ü‚:ÙFw"do£)…êɨ5¥¹õ»HÈ—Á·`™ªúWÌBãßæ Ò~‚ ,Ñ~uª[þç`ù-ØBð§ mÖz‰%j®ñÇPŽž,ÂùVéð',VPó™:ªgN™]OIò¸Ž¿_¬¯þùNm Nk©qÒë\¦Q½Õ‹ä&DdÞ‹û»ÄÕoÕŸ”Pª0 nƒÓMà= @Š•ú¤C(Óô÷˜}ãf¾ݯ€¶ö ¾nF¾[ç—y¦[ø²[ÿ$$7IVóïH+þ?`)duÝãuS³x%€0OU¼¢h€O;. ô’aáf_‡ø¿‡ØõÌõ7#FÒ÷k1äK]—lrcL @íp™Þû˜µ\R3„ÞùwÎ+NïÆq-ªåÚsß³êâKßÍ%–+ônã`n¾åÁ(Wic¤œxÔúMMdÓm¼{ÒÕûÀ´‚,B\¼Ý žnÂ;yAOss'ø¨§Ò­ÐÙÇ©èïÕOØÊñä³|®@/«Q|, Ó¸¡]—‚ágÉ»3ŸûþŸÓ#T|öãoª,È;Mû/Ëy¨…­¹hžÐEéÿÅ©VMÐD4ÁüFKú-wh¸+á)1mOO‰ ü|ÃS"ø×,)O‰ 'íÏSÒg_k<²Å÷ãIaZâ#¶dž”þ‘yRúGæIé™'…¹µŽ·ÿ$¼åhߟ ÕÑþ_ÀS"k?pE5ü#èÏÊRŒeç¥^žšÛŸ§D.¤:*øj©£¦ÚO丯£Oµ1žÈ\CŸä0­£¦ÚO䀫§d¯r×ÍXl)ââGhˆ²CT6²¬ õ‚HƒLÈ\6§fGã%o’fJÒ fÑ¡¾3)­Ê1=Z¦¹/¡¯‰0ôs t¨n!Ðmü7_rñßâjp®¦AÉ _ýøjöêþþdñzµ:ñUøjÅê\Å*®°-AñÑš<Ö…¤+07®ašPU^Œ¿£ é R ÿ 1ke Ï"cÊÁá’Nœ*˜d³(mV×b§³-*¥)Tù£OµI²Ò…ô‡Qs<«Ð>ÕxֽӅ̬^ ”®”¦sÀI7̰ڙ™Žæ5WV™Ÿ­¹àr´Ôuù—]p Û6 B˜É{¿d.!6ÉÍeì—•|,_Îß¿y«õ .¸r‘äCm®7ózK>‹š¯7v×ABZ“ ›6(p†l¥ë­’xÇž9Îiˆ)[!üõÄ¿cE’»‰¯âßÚç ‘VÍUâ•<+ ®ðŸÓ—C 6Û¬}`¬95 ÂÆÖËü\„0WNgK˜BJ)BJ¿,ÐÊè–ù0‘ªÕ÷ÛY@Ùµklï²LÕÍeT-© 4iš`¥RÓ±¡~la:jë;hÚ†°úëçóÔ;Â#‚å4mf0êÆ2‚T?¤˜ÄÇšh‹¼"ø|n€j…èZ®`ÁþæíÖŸ.ˆ‡Þb÷yaƒ™£V~®kò•¿¹E uàea'6`Ø… @- IˆûÕÚ8g!Y¦‘ÕmÕÚV˜˜›²ÒŠ)Ý“ jŠ,MyíIOÞG¬×€üù±n¯‘Ý’ªÓ³ÁÉ@5…µC-dè쌤¹Yr椸 èQBV{¥”.V åé&$ §Lë±’FÃ(«-ÿ)@_×1·ZÝI)\ÿ*‡‚€Xdi–eç9ë1;SÛ›§ 4^º¸RŽ÷å$@¥èQê˜ùžþðÓ_Vi3j›œúR7ƒ ŒËNf+–`š¾ rêÉ~mõ칞ãÃçó§hW§{S:K{}þgïfàî<¬Ã—àKW#×$\XQ†”·»mô%@³²“ÛÇœ*\×C•ãÁjÇtX_^É!¡ç­ìFʱw Cvþ ÉmÜ:`¡‰d ¨¹ЭÄö[çIZ½Ê½°é䱯öeÙ¾ôÇq°íË¥s€pòí5ðnìï†CØ ïæRúr9%ffLõøÝM-Ôm”p´Sco¯:…N”È0kDéúD«`»¹·d¥[ùÑ%ÎÞÎçFñ'ݼF1+¾Œ¦_PôÉÖÀöPÌnó—Curo@'šÿ¸q!BS`WÊ ÜEqˆF zóO!>ö_ßã¿äûSMëÙãÓò,›êióëŠ éŒCTèŸ]™ÑÐZzTÆ;¶ÖZ&þ9¼8¶×3c@Ä]«­„aD¹²¶JIžg.ä€ûã~¯GÄ #Žþõ_$ü<îôFoˆÝ¡Ép:FŽ…~·ë FÃq^ÍblWè4ù°‰vHG 'C¥1Í‚o!ð%çŽ-‘{uÔu{ÞX¶:fäõ£Agƒ‚!Úb, TË1ñFÀƒnw„­LßbC†—ô5­“Ôe4é9 hl!¨¦Àª²µY6Ì&Ko*µoÐÁ{,üoa´)Ó -+‚©«å×’c¿¬C3´L–™ “†õÝrŸ1?x0Ûk¤¦½Df·´Î¤ùƒ/vnU¿D:ŠZ.4Úì-â.‘¾Fº=ù á"é$öÁ¼«Ä9¾ô²W5–YEß^p·KÑòúгۉ¬T{˜ÕyÊ™æ©Â9…{­ÙÁ—F˜zœ‰†Fô<”RU 1uE–G;ä sì–ÄDÔ€n«Owýôˆ#fàSy÷ó{³Õu¤ á·@¹y8=P°ö)øW¢] ¶Ñ¸¥éNß¼˜û˘½=RtØl(>µü)4èOa»·xò¥2ÑÃ3Üiè;¢UTõüh4c…XÙA®;­0V¶’w½| Óyù6Ü3Þ¹ÎÍÈ‘õoFkG=ƒÍx±ºŠp[aSösÝ9™MéªµÒæ¬ä¬óòý™ïo—o8uKP’¥yj¿ZÆr¢/‡?Õ+áz™g%‰ðcKª(‹l̪~Ïwûã—cÿ‡"ßãul³Ùë¾°`¾ò8J.²äÎW·DCˆÄRÇHd=«‰G´8õæ¥h½¾‚Ó}™™¾ø+Ì_ÙóËÃ0f'T­ÀF½y1î¾;tÇçíÓq§Óæ¹v§{~þî¼-ÿq»U+1ÑðøsrnY?[jš™ƒã@âÖ·0¡æmr+ÊRVÀ7 õvÎ2#ü?Ê£éØÄý½Úä½ ‚·;Ç^ܲ.ć”þ‘‹¶5—;¨î1 ë «ÔýA:&xЏg Û§;z9j{£AoÐéÁ,öºÂ +ÀM€TkêAªz%غkŒ_zÞx<©>‘lÕÎR©v¼ÔÔ‡]¯×ëw=P§e'óü±<§8&ZØ´‰°GÁ›ßÂ[,2ð.“±,°´ÉÔÀ3ZÒ€92<^Õ-ãgc:Óï°ÒyGE~Ó¤5ïoXÓŽˆ#ò•©}?Ë~Ä=Åøìš#£êvœù[?Žv›)›"/Î(²R¦›RÈðÀ…\2BEÔ¥6]Ó¯7ÑŸä¥í¶ôoáðaq ¾1EâfÇw?-Š¢Õ©»¿êÔÕ¸*2›‚ò«>O³{\Õ^î<¶ËÙ^5ü Μ#Ïpï±Ípÿ±uXÄÏdz%ëñtXpoO‡îå˜FM}oÐU!¼`tU(ñµb +ÕòI&›wê²Ø–œ5ªi¦î¡‚ŠÅçÍä—ïÿýí?®¾ürþwÿ!u.¢xË¡>gx¯ñeÆw1K€BcF/”eŠ'*œT^ª¥È¥%ý£Ñ@p0Ä]SÛæß’$—®¾¬!œ J³=up±q'ÔYë¸M½vFÂ¥¾ãmª=Ò£q¶qZdßdq¹H"\ðß(|²£/ÚlõZ}š¼%9¹'‹[ñ]0ÍèMx2¢;QACÚ ¿) X¼­Jñ„ßy—„KpÑ L¦fðrQxçVª6 ›:Z<1 bï eR¬D¼‘º]Ý–Ê“ŽsY³ë ûÌäv Šëz_ƒûx꣢ÉþöÞ¼ÐSj ‰d5Vªdjè¹3f÷,$+'F!“›j¥.Ú\÷‰ê:ûÊÇíeãM½”êOº;,kÊÂÖm̳ï ²ïS´¬dTGÕgȨãEÑ{9À@ŽšëU¦+˜·øÕ¿~ûý÷ß®¯ßÞÝ-ƒþm8½¾¦Ÿ^®W7[)õŠz¿ê¹mVbøÃ—­ÉnŸ¼C±°^nÃùœš˜±·ˆÓ‹ö{••¾hŽT|,,AóÆ}~«¿{^¯=u‰ÄÕxœ‰ãÁM;˜Ýܰçt͘r8¡Óœi{%h|Ø”ü ,9­5,X+ºùòx‘ôÓE¸œ½ÝØ3²øÃôØ„c¾“®WU‘Ó ÐNІÎŒ°M!­"Q7>MìÆð¼‚Âw~È1†¬’üòþ†Ú6ø¬EÄ5iþåä×hó•x¤ 0ÄóéÒA;Py~"Õ f˜š_¤7Òž]Å ßI÷ЍHÈ”ÿÊ~ 4Ÿž 1ðé!¬ø»l‘aûaZ"Ñ ‰ARk‹Æ¸%/™^?,Áÿ²–Œ ­T9á³-x—“IŸcp[ën7êöÛjx0˜oè-©å/«nüL­«—²²0~gÜ*j~ÕM™œ>[Qõï‰Sû{ª6h”áŠ-þ隆œýò6þúçã5¾£,šœ¿ž‚Ϫ¬ˆÀÛNa)ŠºSíh-Ô\ Z Y44‡yD\N΢é­&ȼ‰ÿ—}ûIh(”)ƒåæÐЊ•% N0’Ó*(ƒ:mËÝ–¶×jËY¨Jþ·àváôëe}ý¼èìàû¡Ã*­ërò.º»W†˜·1Ø×ŒØýæ°¤¦Ë G(a´ÁgB/άa9Œ»aµ|}u•U¬Ð;ÍŸì$¸Å-R:$G¾¬µTÅò$~Œ`¥n)§ØÉè!ow Ét•/Dÿ´3œzçïߟAÀÛÞøôÔ{{æy£Þéø}¿£EÉÜ:­µ#>|6å­þüùúÒKÅÛëŽ×n_Oî×Û$@“ÚÄ®±§²Õb‘äÔ€S‚|´KrtïBM7ì|wl¾ËÝW?>ùŽs¾å)´Ìxen— HæxY½#02#æ6§Þ°Ê‰a¸¬] ûhÌÐSˆm;F~ÿ ^çôP.¶˜n„ŸýçÜ·{êâaCuRTã‚Ížgtìˆmß› »ïj‡'ßx«KK7ÀýÛÿ-~YÚ3í libsynthesis-3.4.0.47.1/doc/SySync_script_call_flow.pdf000066400000000000000000005423701226375725500227550ustar00rootroot00000000000000%PDF-1.3 %Äåòåë§ó ÐÄÆ 4 0 obj << /Length 5 0 R /Filter /FlateDecode >> stream xÍ][“[7Ž~ׯ`åeí*»-Ý·¦¦jÆqv²›KìL¶j½²ú´[3ºtt±ãýõû$€ï\Ô}º£ìLü }ø©ŸÂ_ÂO¡˜] G“Ñ$¼ñÓ( †óáÕd> óÑÿ/æa_†Ã6¼z}„å! â¿ÃÒãA ŒÑt8 ³ñ¬‡7¡5éÇÿ ŸçÓb4Lñi:-†Ãñ(~Í&³Q¬é8aL¦C<;‡Môû‘Ö3ÚÚha2)Òskjë´Û*uZÔñd¤1âx 4çÆiŒê¨Î£ÒqÔOÏ1NcDP‹:JcÄbžžcD§1"¦¶1ŽJcÄ~~Žƈ 6ÆQi„8žOãH4Bj}ƈ³IcÇNcDPëã(OF#NŒfs=v#NÆq+Ç£†<ŽÆˆ ÖÇQž¬Ëãx4Tšóè4Fµ1ŽJc‹üÍõØiŒjc•ƈýü#:ûy½Òº+G³æº&!¢Ç^}eÚ8ŽœÆˆ Ö{-OÖ¥gä+ÓƈXqõ¹)yôuäˆNcDPës=R!§ù9š¢¢Pë½6#N¦:ÆãÐiŒˆ•T×=C¥1" G|Žyt#‚ZG˜]j) ‹ÒœG§1"¨õq”Ö‘Æ<#¥9¢ÓÔÆ8*‹y~ŽzM4B,`‰ëãh4FlY3…ÓÔú8Ê“uÝS`mešõšhŒ8iZ®BiÌ£¯Gt#êú MQ(M;S8A­Ïµ3F#“¦U #âÉúÌÈ“õ™Œ›VhŒˆ'ë½–'뽆צ4›¢1"ž¬K¸ˆJ"´YS¸DhÓ¦h+‰ÐÆM—ÌI„6n:dJ"´Ñ´¡ÔŠv=ó<óþÕx6†3|*&84c|c¬xÙp磗f£ÁÕxŽ?oÂh0¿‚«?6ZoM´!0å¹5µuÚmO3âtžŸ$D¥1ât:WDoë´vÄl9°…ÀZ„pô°…€¦žN¦Ò¥ù nFÁœ²³j4bŸœ2mÛ#Ú-!ªSƈJcDwÊÑiŒ¨N#*Ý)sD§1¢:eŒ¨4Ft§Ìƈê”1¢Ò‘œ2C$!Bá¨"24#ºSæˆNcDuʈGrÔü-n`ÑiŒ¨†•Æ<ºSæˆNcDuÊQi„HN™!Í)#D£1¢;eŽè4FT§Œ•ƈî”9¢ÓQ2FT#ºSæˆNcDuÊQiŒèN™#:Õ)cD¥"9e†H4B4§Œƈî”9¢ÓQ2FT#º£æˆNcDuÊQiŒèëÃÖŽ(Ñžé¤?…ùÁ§Á¡ŒÉ\lÏx6+†cQÔMm?(úa0Ð`ÑlZ“BL×tØïϦ¢ñ'ýÁdÚJóa2]ãøÉ6Þœ  †ÆiÐÙyò¶N»%DÕ1›jkq”*ˆ…ì<9¢ÓQÇ‹3­‚è¡GtZ;b´÷"q0„:h ÛMfcõÒбÞ3Ú:8m:ºê'Û®mi3ùÖÚ=ò`4ò]¤uöu"b¦qwœG}’æˆ:@UDó^ŒŸ M¬¾eM4GÔ¶UD“SBÔ'™G§9¢¶­"š9"D}’æˆÚ¶Š¨ Ó[Ó¢¶·Ð¢¦™Ñ¶UÄÁª²Âˆú¤ÓÖ­!æèm§`&æÆeÏh$âd_Óä‘h$ÒºææÇ·äå®­ƒ´Î4•¨ÑH QŸdD§9¢ÉcѤ‚õIFtš#jÛ*&„¨O2¢ÓQÛVU¦¼5fFýx{ fÆhލm«ˆ&)ÖšäÑh$4fÚ¶Š¨2Å<ê“N#y$Dm[C4y„"ŽzåQi,pÿ¢Üº†ëIì.ÓX‡ØBUóa¤4o¤u-Þ3åQ[“!D—GGT‰ª"ºT8¢>É<:͵mÑ¥ÂõIFtš#jÛ*¢Ê”·fyÔ·°<:¢¶­"º¤hk–G¥±<:¢¶­"ªL1ú¤ÓXQÛÖU%®–÷âf›Fò(Qµ˜fs‰êäQZc=p žM¦yë ­ãsî6EÄL#y´Ö$FóÖŒ¨UE4©°Öd¯FöšxÔ¶UD•)ï!E Q[3Ú¶Š¨2ňú¤ÓH‰Gm[E4I1~HFòHˆÚ¶Š¨2åülÜ6¢¶æ^kۢɣêBÒ…ÒX!áuý(qÚ¦~,tÅ‘ÿh4–G_3ªáz‚ØÔÖšåQßÂòè­]vë‘.BÔ'ƒÑX½µJT•G—å‡åQic£jÛ*¢Ê”óCú‘xÔÖµmÑ¥BùayTË£÷ZÛVU¦˜G}Òi¤‰Gm[C4yDT>ê=–G¥‘<æãÆ~†h¬ѺÇçoıXßÏbs?c­YQ¥9Pk•²ÑXµ5ëG¥‘éÇLϸ?ŸõQO%a2Ó4–g‘¢+²ÍûC$Q <×ù·ä•]9q–“?ˆby[N9ž² ¹&„NrZNþp\̘_Z*Özƒê2­FC l.C!áÂÑx2œû½Ø5ð ,‡b0ÃHH9›„+g•eœ¨B›aLPš6RÌ+™ô!&©›;•ï`4\L†:*Ú6ÍBO¨9|áˆJ#D*š2D¢¢MÑÚ2#zÑ”#:µhŠ•ƈÈdsèˆNcD-šbD¥1"2lÙásD§1¢æâQiŒè¹8Gt#j.Ž•ƈž‹sD§1¢æâQiŒè¹8Gt#j.Ž•Fˆv©#Ñ–EmÉ£ÑQãä¤`+…TÊyÏrqÄ£ÑÛŠºôPqóˆUX_3THå|û:Rn‚”Gå0 #‚š-o¥u¶³F£\œ!-G½6õšŠ¦‘ósJíYÑ#z~Îyô\œ¶ ð>tþ™GÍÅ1¢Ò˜GÏÅ9¢ÓQsqŒ¨4Fô\œ#:5LjJ#DÊÅ"ÑÑrq„h4FlY3•B*}OÏŠ¦QÃÒŒˆµ•eOÛÆ-{SeË×#*[ÖŒlÏmS¢ï‰Û©úš‘mW~·IMi[ØJ+®âqÔ¢)æQiÌ#\ö¼ŽÑi„hES„h4B¤¢)C$#jÑ#*½ÊƈZ4ňJcD/¤rD§1¢M1¢ÒÑ‹¦ÑiíˆâÜD—(z‡ÈŸ"³²¨š÷ ñÍ72GË|£^ô&£ùi[d`g(ÒK*w:™p3¹9y2ÆŸÑÖ=£‘×b¯&Ú­3d^ ùõJƒ‡èˆîµ8¢ÓQ½FÌ´ ¢{-Žè4FT¯…3­‚è^‹#:ÕkaÄL« º×âˆNcDõZ1Ó*ˆîµ8¢ÓQ½FÌ´ ¢{-Žè4FT¯…3Ék1D¢¢y-„¨´ ¢{2Žè4F5ke“=õd*ˆ®ÑiŒ¨˜yÌ´ ¢{-Žè4FtOÆyÌ4F$¯Å‰FˆæµJ« º×âˆNcDõZ1Ó*ˆîµ8¢ÓQ½FÌ´ ¢{-Žè4FT¯…3­‚è^‹#:ÕkaÄLcDòZ ‘h„h^ !*­‚螌#:ÕkaÄL« º'ãˆNcDõZ1Ó*ˆ¾>ÑiŒØ²fÔ“© º×âˆNcDõZ˜ÇL« º×âˆN#DóZQiŒH^‹!ÕkaÄL« º×âˆNcDõZ1Ó*ˆîµ8¢ÓÚÅq(ÆñÄ_ï3ÂK+‰Ñáõ[q#úˆ &áík:D¨ÿ^¼d†B-]Â!š#b3½ŠÉËaÞK_$ô6Y|¸u„4ŸÁo™¥/±yON<>Ü<åMñjí¤ðùá÷2Û°rSå;ÌÒ·.íCj?E‰Û¸‡™¼;~éôvmjØíÔ<~Ü>̽¶ü‹ïÆÇ.-s¿§Cìq¬ßù[—öúæáLë·|éôöÜz‚8£÷;}{L¿'Ó¹ö[>vá;÷{Kû-‚–¿ti®Œ'Þmë?²Û#ä¡lÐ'ñÛ£ºMñ± ßÚml@|º'é[—öÚo¸x2ÝqÔäs§—çÆã9ü1ëvúö˜n(ÎR.»°»Íu;ëÒ^9Î|ºÇò¥ÓÛµõ‡ô¼ßñÛ£úÝŸZ¿ñ± ߹ߣ)ŽÙÙ›ó·.í3çÊ{¿ã—No×Ö1=ZÌGÑö[>vá[û]óÑ£Å|”Å>¢ßC òùÎߺ´WÎ%¤Ú|(_:½][ã4õ;~{L¿‹¹isùØ…ï<ßÅ,kó8aù[—ö™óëÄú¿tz»¶Æ*ñ~ñÛ£ú=²%Zàc¾µßðë|¾q5ƒ|ëÒ^9/Èk)äË£ZXŸñ›õ' †³~¿˜ÀƒDŽs>†ö‘Ó9œÅ¹xrÿñG‡\`Ñï« Ú5q±¹ªží<¼O‰§Œë—^ÀcMiŇ<Èß¿ H3&wЧ÷Ý&¼úfp…ÃáÝMxöv¹_ÝÃr±^¯¶áüéTn—HJîöám¹ÿTâ_¶K|>V»íóÞ»¿…7ïàûF÷ÕªôßÌžc| \wË"¿2Ë–¶A–”ô?5ËžÚÖQ.¦ñ6“Á?7ßÒ÷¡W£n¦­Àõs¬›˜¨ç{gdMÕåÙÛæ‰RyN¿`ù‡yc¦•Öå§rý<ðúòÔ¢†;)ÜŠÏ)=ÄŽ·V¹ÉË«ÂN¯¦¾^‡ãu - ÙþÛGÇÊ~ìù­É7e«UT;¼×¨Lä×_¯nnÊ}¹=^9fÅé±t¥8=Ý,DCÙ4-ÔÍ ëjŠ9{`a¹ÛËŸ>Ï”¹5ΔUÚ=¤RLåÉ!Ō𙫺Zþn÷+÷uO¦ œ§hÿóPýrs1DÑâ9¾ÜŒµŽ—¥¦œ·xþÕ»Àxá«3ã%|}X@Ù¶²e‚jlY*<\Ⱦ&áªO£°—P+[f_å4g,¥‘Ç­3ƒbÜÅhY{ëVcù7ŒÖ»[Q21a³;ÃW×»‹õW:rQS/Úõ]ã…]ô]¶×Wᯋýjña]Âuy³ÚÂ8ÝBDs%«®÷?¤]oë¢ÝË¥øxM¸Ùï6ª6ìÐÙ½öïNÑl®}÷ʦF{ûæíÛoÿôÇ¿þîû÷ÏÞ? ôí›w5êS_7j(ЛÓvyÄžñPS ¦«\š «’4µìtn¶µWijNnƒ—(MY¶Cùóê þ˜5W£4ºÞÐ4—×§½L×ZâUøö&|ÙÂçÅöŽ;Mï¾×t‘ñز¤¾ü¼º>ãœ5zЄnʇø@›òXî!øÔ™36½Ã+š2q‚ækÊœ 7@ãÆT§…¥c¤«é_O~ŤñŠOª j’mÏ%;Z¼î²mO•mhÌ(׿Y„›ò³zõíÝo¼¯)'MInØ~ß®°•aÞ—kˆÏµ(G1ñ­sØáMyôÉ|‰”DGkwy³Xžµ¥ÞÒ”Èã·=WáÝmùQÔí“;Ò”Ž,qÖ±§USUš… È,¼ýËw?ã¿è<õ5Mu‰ €_ýéëß¿ö!«{æúšÌ‹ëÛ]æ­½Šãc½hN–ù6%gª¨ultYY©É$‹ÿàËá$+ä>½^ì¯Vá÷ß¼žE(7‹Õûû6CÙáÕÍ…E6+e›×N¸Y•ëëCxÿ ¼¨Œ™|êû›Kè7ñ køb¿}ÿüEí>¨_ÕµH•þ«ðçýj³ØÃc{â4˜8#XÇ:öê*˜ÚË±Ú ¶A à¬é0üÍÅw¸+—+ ö‡òvñiµ;í1Ô:÷›r/òã °´W?>µßÍõx³ZC%›yDZÊ |QkËr\`ªE ë–IsTv7rTÈ“a#ØÅuo„šñ)²yÄ«Å?¾Ý®Ž¯Õa!› ᔣ¬>:•] tÑÍ…yÔ‹â/Ê#âHÖClÔã@-jw+Œg2ð¾ÂØõ씨]j?ËÕh¿d~-Î7C™K¢*cËBÃÏnV{ìòGØ¢•Ë܃«ðuÜ‚«;ÿ2‚yàqk^RÛ™L oñ|I:vúKzP †ˆyO 󵡛¿3ë7b[i`»DP §n[âÀ¢ô L¥ØŽ¬äváh}(±ÖÅHqìTUµF·­¯áÁ Ð Í=3S}áæ„PpXžÚ¤=nXÞ–Ë¿W×<*gS (†!/9òHfÍšBùÝ/ÓÊ×¥e¿Xa\5†>îõ2­Q5x[»8wÇW×åû¦<¦j¿‚FÆ_S±-ÅÍj [ã)ØžÈ9ohKáÜTè~—_(ÖÅß¶7[nïŸ eìÒs³*Æ–Ï…¤NÀ,îa!Õü ¬ŒÝg1ë$þåÕÇ+^ø“xaËÝ ¡œø\Àfw}Ú—uÖö€vÒz·ÿØ»aá=:¬Ü´)à]Lð;)ͰXÃl· 8éȇpeÀ‹NéF7(zmŽÜf}óù¶DJO˜/fsŠH“ÆŒ(öšª‰S!׃º ÑÄov×âãoÐ`Ȱ±ÝìÀs3¦q]Þå¼| ,:)|9HxMV Gñþên;G;>–n½ÐtK÷´šÅõfµÝ—‹ë/-3î&ÜøºôCÀÌŸ/±ÊÌ ‡ðí$Z}J~|%ø¡„XçpwãRƒŠnøe²ù‘°8¬MœeäÎÍÛ¯øuöƒ+÷™p£Ž)r÷™’áûXïNmkŒF\ý]zÄçç‹G¼j¯‡RKÉJƒÛW`WW_²9a¹^ݓӴŸ‘q½˜Þ‚/:Ì›„š­ØŸf‰e'Ôu–1ôe¿µó°ÎB¸~©Üì ‹Â„óºü´‚²IŠ5q_â°eÚ,Žp4RÀdyÚKŠOÉÃ/b]…÷IòWiM\˦Ÿv™Þ:ÏwSoÑË ¤æd?ùf½øˆÂ ¤Ê)¸ŸòJ0|Í‹¶M­ÝGO¹Hú®Nµ>M[&µ>C²µX²hã(-²‹9ÐC9ðsƃ†-‰«[È}åâ 5ºmW&Ìñ”ùö#JÉ/øe{*Ú‘$¿`ˆ2~SÊ®ºŒ«–aì¹ÜI¤üî×…u×w¸c¬»x_í¬ð*‹&mR°‘ð„,˜´9<®6eÃq€w°ºAÝN jȪDHŠWÅ–9Hp¬n=^,Â}1……Þq‹%ÑàË›oû%¬¤÷ºx•y”ÍW‡h¶ØØNĽ“T}!k‡R·âXñ‡¥ÀM¦C–À—.’m þ€‚œ˜ã”yÊÖ%| ×ïú›ÝV”bŒŒï¥ Xq†|:(ß×èA}—‹JÌœŒó f8ŽOÃ/»ôûr±€bFÑìIUtކ½&ÑȘO“ÎEI[•ׯÐ5È&*¢bòø¤QKûækÉ¢Âÿ‘’¥ì¯B;׬{z ]¼Ç‹É xCÜÝm[!W i™WLÝú"Cíó œ=E õ8~«õEzCˆt!Q`‰è±@B—'IA0üÛïß@ÆPQu1} H,I%E Ó,û9Q$R@x:„r»Ûov§ƒ$ûÍ™l:½S ÁpE@bÙüj»„ë3ãØßÀYˆ{Ñ8ÂÃaÑ„Gû!fÄ+׋ýÇì éœ8Øm—¤Sžbo£$]ì-‰P¾ù©1ª²’+å´Yå@•ìd!Ÿ÷Ð$ø˜¬Y Ĭ¥pT™Ì¸äû®Â7hñ›Å~¿øò[øjwØ9s-Q~•é> ùö‡óJÈ%8¾Ê’Ö|b5‘Ë”>Ã7>¹GÇr[®Ë5ñZÇ]¿`p?{Š31Ñ wúg85ÍQM»`N´›P«zfS”{†‹ù4¨ß¾«¦ií‚°‹/-ü®U›µ_ÜÀȤ߻É1¶ž°¾dôÅØ7¥ôÜúŠß?[¯þ^¦÷‰G¼CúA^½ž; š‚£›VâO›jŠ¡Õ%ܾÀ).ÙKG=jÂaW.‰p /•¨ýï¿Û²ÿ½Ûïbá³”Ô·œ}6ÆD>º1æÊSï›jŒq£”³ês*sÙ.f9޾¥†QŒó=à‹pºÃ(cدáâË÷ÏÁ O º&iÛ{Ø&78nJE³p$2´úˆŽÌ=Äa_þ­Dí5¾¤²qŒeÃ*6nç1Ë9Dý¶Dñ dîdZR_"àÛÝöåáËÅÀ{¤ŸÊz³äH:FÈ! µÔ4©,Rh#,Þ¬>ú;+¦Ún+½¸©Æm¦:àÜ£6¦.l«ÇƒI›­6™Bp9Eús•Ðü¡<~– Ëñ3rÎ1šëz^Úh[–¼€þ8 ÷™|{̸Œúz…ÂÝ¥N‘ǹÐûÏ.nMƨ©hÙJ-Ôã¯,=Á”Ø¥¶…×pŸ›ãžË´´ˆ¬2øiá½vJ§è$Vö÷²¼ ÔOĉI§>²÷ݪõn‡¤>â>ômºâ<ËM]aÓKĽÎ~|ß9‰‘ç¾n$lÛd?d~ñôæS×âA¬wÐË«û7MÆÔ¥W~á,÷wRuœ &’ÕÇL¬ï%³†€»ËÕŠ/¿ä*;‰‡Š] [åÛÒÄB„dð¾Ë'?zÈZe=Ô;ý.?ãi›¡NÁ ½´­>Ïxci`{ž\êP)ã÷¨ÍðHKÕ`kdHw±µ±”´[ŠÈÚâUÙ²‡=3òv÷¡Œ|7OÄö5z—\3ÿ%áÙñtÖfs¢³úðÀ_2ðÝø2I&Mníž"Hôƒã]«êHULZ¹Ž°¸Ø{~Š|µê8½«²¡–›:ŽBO 4ä<…hü£¿ïÂñ8~›NÐùˆ„% íšï_%Q8ž·Ö…ê†(Z.”£Ÿî §3¢L„äw½,[ˆ›vº)½9¶RPÔ”À|C†-y\P àb•§ÍXm#–S¢M±pkPÂÓš J9©kÔ`ã ¢ •J±©\Þ Wݼ,¦çïht¤€xOò=ZÖ„˜`ò¹RŠ uר1:ÝÝ¡¦,~ÎÑÇPþtÞÆÝ’^<~–â„—âÓËrJëL†CËãY…zŽÁ6y `ÈUƒÖÂØûd W8 ] Éõóñ ΋‡ƒ&T­«†ƒ¢c¤¢’Â?Õ4¾¸‹!׋^kFžÌ›íçíòý‹»ç܃ÚËDåÇ×~?”¯Žf>²òÐ~Š a zÕ7øˆr ©>ƒÓ…=-ªvä¸Yt¼råÙ"Ÿ±‘™‡“%@ÙlÍd× š$ášþoJ89ëýÖˇ¼7ÍbŸD¡va‹W¢€Ï˜8ö |N‡Ês9¿ù#üM9ÈsDb~›z…`„›¬êâBô,þ,âå×ÙðeVǪb!.¸¸ Ê«­÷Õö+ÅZ'dÖ ·Þïü«î î[nÙ-‰Òj3Ú®X] õ¶è¸U~¼ÑÎׇö/4Ù.(r7‚Xe]ßÖ ÷j//Ä,öì›õŽî{ u¾ü%`lÖyc-©Û;xP!¨õb†.k—u~.jZÄ.O[ó“÷ˆŽÜñ‡ZÛÊÈoÆ_ª¾¼Ú˜å°¬äo¤P¿vÔˬqõîAû­Ä4d]ЬOº=Ë"A%u°Æ³YŠ<†+ ™Ø%êiÓx!®dÓ8íÇ¢ÉÄ›']âц¯Ž·RV†¯~þªš'B÷>—šu¸¨pCg_$²ƒÃ;ÑÊ)ûP"(e’ŒyHûi©ŠªûÝu~à›ûK9]¿XKÑÁ—Þ½Ýï¶pX®ëþ€F–(TLõˆo\¬~#Š*ÌE‹½ªl€íº²ÊæÒxJA¥_²|*A¥)Îîùœ`>ó¹Ø\Š*¡å„²d²·8Ãr8àX.ò&ñ †Ö«J9 Œþ5Äæìhë/ˆb¸h±ß©} ˜¹bêm¹_'(SÑ-xÜÉ ™ª§ ˆè§ luØXë bƒ+Ê‚N…@M|.ÑRs!–e!ýÃö¸æ§ÇðÍC‹ê,çMïÅÝyU%E}ösÊ^N8ê„´k|Rþ Š4ÕäÁ<ÆîòŽ¿é󫜛ÂclÙ´ w1dвó^Üõ¦2˜d£K|×ÛB®:†ãñŸåm,£Ä㼤8_ü`û¦ñÃ8òжÆ~œüTñW¦ @Nù«·xóÝwoþëÍëÞ½‰—Y ¥X ©vò]Q[ o9nZ¸V™(÷r ›¯¸:IÔ2ÃØʼ‹hÖæÝ¶5øyxžN¼–Ë©A˜âÀXK-e ¡:À¤|=e¶QQÝÒsï ù×é-k'ãÉ%MM9·äÚØæfê5 -–~ÞÇËÞw¿Blëº".ÀWyǹÚbb€Þ°èÐänÜ+ÙË‘N»ú]¯6Ûøýæó%’¸Ë[þ=p9vÓG…[ É+6³•ƒ€-«[¼zŽâ*cÉÎòâîÉ/;?‚±ŠõãQôThŠHnæë1‹> endobj 6 0 obj << /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] /ColorSpace << /Cs2 8 0 R /Cs1 7 0 R >> /Font << /F1.0 9 0 R /F3.0 11 0 R /F2.0 10 0 R >> /XObject << /Im1 12 0 R >> >> endobj 12 0 obj << /Length 13 0 R /Type /XObject /Subtype /Image /Width 295 /Height 300 /ColorSpace 14 0 R /Interpolate true /Intent /RelativeColorimetric /BitsPerComponent 8 /Filter /DCTDecode >> stream ÿØÿàJFIF––ÿá6ŠExifMM*bj(1r2‡i¤Ð––Adobe Photoshop CS Macintosh2007:07:13 13:02:02  ' ,&(.5THHÿØÿàJFIFHHÿí Adobe_CMÿîAdobed€ÿÛ„            ÿÀ "ÿÝ ÿÄ?   3!1AQa"q2‘¡±B#$RÁb34r‚ÑC%’Sðáñcs5¢²ƒ&D“TdE£t6ÒUâeò³„ÃÓuãóF'”¤…´•ÄÔäô¥µÅÕåõVfv†–¦¶ÆÖæö7GWgw‡—§·Ç×ç÷5!1AQaq"2‘¡±B#ÁRÑð3$bár‚’CScs4ñ%¢²ƒ&5ÂÒD“T£dEU6teâò³„ÃÓuãóF”¤…´•ÄÔäô¥µÅÕåõVfv†–¦¶ÆÖæö'7GWgw‡—§·ÇÿÚ ?õT’I)$²2qñh~FM¬¢ŠÆë-±Á­hñsÝíjJJ¨õ·Ó:ac2ï ºßæqØ×[}Ÿñ8´6Ì‹vþvʽ‹¨uN¿ÔñmwF¬àÐãSîhnVAiµâÕxôºuy-k««/>«ný'ô ÿMÓOFÅé®ê˜Cn=Õ‹ò]ºÛÞÖ‡XÿµZóv]÷ÓúJý+ÿMÿ¡T¹ˆcÆ*Ý•ðú~XËÆI´þ¯×òÏêxUôúŒEÙîõ-ˆ—“ðŸ·þÞê8öÀ žŸÔ2#íý[.î¿ì}‘ŸnÛý|û;~°ÝxôŒ+2²‹CÝ¿o£^æ—µ—dÓcè{Üæú? ½þŸñOS8?YsNìœÚ°j1ñªõ$n­Ößiß¿nÏæmÿÒk?/7ÍKæÈ0ÝŽ‡þoEÔ» t§‘AÉ’ì»mÈÔ­læ]wÒwµfgô¯«x½oÕÀÀª§âf–UKûüGùÆµŽ±»­Ùÿ]Væíº›ºRÊÈv3ªÈ½ÁµîÅý'«èÙ»Ûþ÷îÿ®Ö£×*¦îµÓ[mlµŸfÍ!¯k^ߥÓáÀ<9ªvBVrO'¦w¬¿súË¡)ínm?-´Vѱ2Ö±÷eôëYF¿¡vE5U‰f5Ž»)”Ûêƒúÿ„°Ì³„ÌwåeõNvKò=WeÔÓk­f>1ýªÌÛ}}•~—Ò¦­}_Ízõ1C'¦}^cE™XxUµÇh±õVÏtǪ;Ö;ó’§Ö¹Ý#7.†ÔvŸFÛ_WýnޤܬK©ÓùÌzý/øDèó¤ $üÑâàÿ ×8ÿãlÇ•–ÀÄ—W§}bê·4œK°úíM–×» & j¿s+¼äce~ƒ&ÏÀ§{Ö¶Ö>›“Ü;‹ðsŸ;pòÛéXèŸèî—cæ}ûE~Jãò:m–rñ1ú‹víõqç( ú@»§äÚßåY‚šœœ›v ëTwIêM5æ5¬aÛk«¹—ý¯ôŸf«íx¾­¡õ™ëåZûUÜ?‘ê3¿èOíÿÕ˜±°O£ó?'Ñ’\gEêùË:]ç6ºœ[‘Ѳì?j¤4þ—ìyy[-µÌõ+kñóm¯êÿ´q½5ÓôΫ‡Õ1ý|WiÙm64²Úž>•9Y¶Êmþ¿üe¢Z8³Ã-ðGÍ i8ýMÄ’IH…$’I)ÿÐõT’CÉȣܜ‡Šè¡Ž²ÛÃZѽïwõZR£Ôqzf+²²œC c ž÷¸íªŠ*o¾Û­²ºØ±N-ýFúsº»@}õ10$:¬w~eÖÇèòºƒÓ1‡üÞø\¼…Šr:•ìêÙÔº‡Á–}*+pÛêÚÏÍê9Lþ{þâQú•ö®Ü‘uLž¡c†Kim·KmΟe¶ö‡5·5™¬­ûê®ö³þÕý*ÈçyÓ’GÃóä¿›¿øô×¾gZ®Œúº~5/ÎË{¿O]%¿¡g´ºÜ‡¼íc¶Ùú*¿ÂÿÁ¨Õ=7«œy?cêu¸ṵ̈ ™T7Ûµ•çTÇgUÿvªÏÿOZ®çáý]Ç«§ã ®£‘±­Ço±öÀw¾çµ¶ý—­eßdgôZš¯ÑÅ®ÛiÒÏÂgQÁ~=…Ô9ᯮÏϦÖݱÛ}\kØË>Ÿ¦ÿæÿ›T=1¡U iÄ~i¬àþªZ™¶u6Y^HÅWYe–Xöµ”œãëU‰uný_·óñlþwÿBfôwc×öϬL\ÏJÚ/õHª‹+ÈÜmmÆÇWSm¯sh§#¬?ÐUüßé=*j[Ö:þc,©¾ŸN·šrHß{ï¬MŒ¥ÙLû6=Îs‹cêͶÜ[©»ô ÆvPxËÄÂý)5šòóÈ·Šl±®¿1ïö{rhýOÒÞÌœKѲ›”‘‰Ž(LJæ®-{$¿{ý_<9yʉÐKXþ‘“¶Ú>£—ŸR×õ]­uqU7d׵쪻ð©u.{>Ïê1Þ§ôŒ¬«ö~“Ø\î«E½Kì|,Ñ‹‘IÆÁ´âz eN v͘¶,v³/öYÕºµ5ŸDÔöYw¸=öï­—ìfí–3ÔÙüÕöÞqÁèÄ®ë5·ôMŠÁ ­­{_nÍï§×Èý/鯲ÛYè'ðÆ{ÊrÂË—¦\<0‹,y~>¡Ð˜CW¨³­t‚Ð2½ZZ×µbÞÆ‡0‹+~û)ôGcw·Þ¡_JèÝ@SnM«»cq2‹ëc_êXÖ¾×b×e¢ÙG¡èÿ‚YßkÌÊ˽Ý/«a–¿cqñ½FØC@«Õ²ëföÞÏÏõoæ~C,d²æÙÕ:[o °œüY®Êý¯·%þ­v}·ÓÅÚÚëþkí_Û®•Ãä'(H‹áâõj?ÍÊ8{÷ÙŒoļ:7w¦áåb²Ó—”ìÛ­x"×H¶´2ºÛ[œö³ÝêÛfÏôŸðh}B¦gåctè‘C›™}­%¶TƸýš¼k™úL|Œëëþr›+·ìxù?é+TpºŽ`vÌ{šÆ‰8™¥µä‚?ž§5’ÛîÆšëÈfUWzV?Ò·¨2ßSÓ?O®ž¡Óò±îµõgd¸YÕceÕXí›+c.õ?V¦Š«ÃÅ»ô¸×U_©ôí±Fa8Hä‘ÔUJ#äâôñðzxx?ô¢Ò4­Òþ¯l¯´cWeٹᔚéë5ÔÛ3±Zï¦üšZÝ™Ô6¿ûWElËǯÕý¾ì´j-Ï¿6›®s1º†;X1úÝD Lšmþ‰sý½A¹v¿ÛEvo®ÏS'ì6ú>½u,ž•“éu7dÞëËÝE£cªö¹ßgeþ†Ö_m[}96~‡gÛ-·ÑûFJ¹™ƒ@Ƕ‡SëôÛK•†Á%…Ó¿¨tÆÃ¶\Ýï~F#éæ3Ô²šýVœÉñæ”%"?Íæ‡ãû¿ú­¯“ ˜tù ö7ª ÃeWölìxûF1; :};¨²ëâݵÞû?à®®œš®¢«Ë€Âêy/{0òri¯«b±×ôž¤H5ߎíîjmO»ÓÁÊǦ½Ì»#Öº¿Ö§âz˱éLu,1sê8Ù5¸Õ—Šâênh¥.s~ŸÒm”ÛþÊrú;Vß-Ì{ ‰PÉëå˜ÿ9êÿÐj‘Mä’IXCÿÑõUÍuÊ:¿\wHmu'ÓÉˤ>fAý&%o«óñ1³.×7f_Øëÿ´ù5­n¹Ôÿet¬ŒàÏVÚÚE_¿u…´âÓÿ]Ȳº÷.tê} ë¼›o¨ºÃ˜Âk»Ö°ú¹YTßQÐü‹œ÷û³üój—Ä3Œxø"YlXÞ0ý"Û˜Ž eÄz~ïï;X/ʲ¯Ù8Øî}ÝF«VKœY@{aî¢Ûª=–¾ŸVÍ–7Ó¿ù¯Ò~—ÓŸgúµ‚+Ãk²³óÑ]n;}{ÚÖVûöËYêú{_c?ŸÊôýïþvä^·Ô°Èfs]Ô1‰´ÒÐ2X ?Ò1+ÛVcßð¸^žGýѱnaæâgc·+ædPÿ£c ‰ZïήÖî÷ÖÿÒ1b’c+‹ܸO¦réÅû¿ÝfÇ–Àßæ<ÑV>/Õìggå»íW$zn{cÔºÇ]ؘM>ïMöï·Ñ¯þ±E¢ÆZ##;+ ¹Y­©§!Þ®3)ÜcÀ×ã2ýßK%¬wé}?Ñ©ät¾Ÿ•Ü›è^ÖŠÃ¥ÂZ×ŒŠ˜ö±Ím¾•íõ¨õ?™·ù¥Ö:ÍùÙ…ƒaªŠœY•–ÃsÆ–bâ=¿ÍúC+-¿Í?õ|oÓú¶ÐGëtý-ç9~ˆýسcÇ,’€²ÕëÙ4·«ïéa¹YNg¡Ôke,5ëvF[Ygë”î}Ä©¶äYgé=³Ò¨;#'ú~M—Í—cÓý]µ?í7èFUŸñi[~MÇe{[]u€*ǯkL5žÆ=ÌkYêYú[¬w§þšÅLÓÖsÚÖÙkq±ÞǶÑ[\Ç8º_mAÇí öúUäSe˜õ>Ñ_øEfÀè+N9|燳¯‹ qDc7šCôB<_ËôÛ$ôΙuôÒÊ٥㶹í¸ú«ßío¹þ¢!êØch~HcœCKLµÄ¹¾›w6·±Ì{,÷~Us:?Meøù9 ¦†ÝE¯îM[½*ÇÚ7¾”Ùgø_OÔþ{Ô±á6ô'ÛëYëÚïU÷˱ïØ^ñ]ræ³{k®ŠÛ^ïúïªõ ‡µ9X ¶^)#íŠÞòê߾Žûr]~=.,±öl±­p!¾›·oý&ç7Ú£Vic_Ó2,ÅiÌkêã}Í?e¼¾½Žÿº¯ÆÿŒUkoAÉÇwNĽ¸â×ïu5ŸNÒïäÕ–Íÿñ{+ýÊýOÓJÿÚ¸ºÁi»<ÛsíF:ÇŸA­už»îÙc›ú¦ÿÙÔWOô¤¸FÈ×äÈ7ÿ ë(‰ Öxõ1—÷¾eò¨ªË½JË:}ž˜ª¬ÜgÆ3}Ú?ÜvEžµõ~±oÙÿYÈô²½k‘l·"œª±º®úî­ÓƒÕhX\6·ßM׾Ͷý¢›*ô.Æý6e?ÎY<¥^Òw8;~+Ü×8´{à?ÃQù›ö~úV´bRêlÜî‘cK-k\Cñštõh{IöôµÿÚ/ç+ýSÕ¡‘NjÛôõT¿õóygŠ<&pïëãÔ±²3±±­ª›œàû, kŸ¥­/°TúëÜÿçvz?ðˆù}««õL½HvOÙë'³1XÜg4'íŸmrÆÞÌŸ¬õš¬¥Ã«7šœÿ\¢ül¦z¬£Ñõ¯³cþÏwýkÕõ–7!—™ÉwÊ&:S§þåsdÏ;ùq‚?ÄÿÐÝkm¦’ÁuŒ¨Øí•‡¸7sÿÑ׸ûßü–¨?·!Ùx¶¿4ˆvM1/±­Ë¡ÿ Í­¿÷až£?ÀÝJÎËõ,úʼn[+õ[C– Ûv‡ŸNËaÿ™Oê϶ªžÿµ3Z׸€9&>õTƒ²Ÿ¯è°\±˜Ê2"D^~©õ«6¬ÙÙ,™92ÔñœEUãÎËrv?~FKœæãQë~«U×zßm³ÑØè†âýŸŒvúE˜ïhÜ6í¦ÆðžŸÓÿ„QÀ´ÝëutËyŸ j‹©Æþmß§ÌwþLzs¨3ÓÜ1œïwÙ\ Æ|έ¥žüG?ý6èÿîµÊÔ`#–òýÞ?ýÜøwÅñá'1›Cš Cþñ©^+1ÇÛú§¥WÙkkXûl`kZúýKw»&û“‘è7Ñõ?Oé~±jÙ™yº’üŽÅ&íßL@Dl:U•Œe¬ÙsE¬<±à8šùJ‹r°¢¸ÙKGôK\Kô÷î~3¿ÿSù8¥& (ïo­èkê–ú›`ýÙ»tlú_šŠ"Çe¹1Â_6‡hËiÿƒ&ÓêÄê5ž£Š,ûKA­y¦ÓcòíìÆ»è1÷íõ>Ïú?ZÌ+I{¹-©È{nȽìnÆ’Iµû¿7رM§ãžÆ¹ÁŒª›Í•7]Û]íûF/ó”#ÕÇÿ®¹™œ§ŠñÞ$bÐùÜ×ûS˜Í®·wú,OJøl…ÝrN\1ùéKôªçå”yy xÎÜ:G ýÿûå¨ê­Á²Î™ŒÓ–OÙ@xmu>¾÷û¿¡ÿ9MT³#'ìÖz›=ñîË{®¾Ö¿1Í ©ûbšÜÏPÐæc;Ôõ=Ýgé²¾Ñw¿ô~ŸÐE̤œ-¸Ì ³.Å­£kCë—úMc6µ­¾¿Wþ¼“]Œmµ®Æ‡Ö|ZὟô\¯`äð⑘C¼ÏýÏî°òæ98¸‡Ê}1ýÆ_»ý×?¦=ùxvâ]cÞø Þâ^Fòæúvk¿Ö¥Íßv-¶½þ¿èÿCTº3î4[U­ƒUŽíA1±Þêͱ»š¡ÿ£ýÏô„˾ÚsðÜûcàêMd˜ÞHÚývïQŒ÷ÿà¤HŒL\ðZâróì“Q°ÄAõ.m-=›>•¿ñU[þ Yd„Ç_æÿW+ý(ËäÿÐ]¿«¹¿`úÃ…q1VQv äÏø_Òâ;OÝË«Ðgþ^”¼ƒ-Ö·Û(%·RßZ’9RFUø-,^­ûCöwí=ߪú?ißÿ·ÖÝþbi Òæ±ðó˜f?ÊJãB\?ôxÿÓ¿€óf#/:œ—[’ëöÛ•ÿ£“Ó‰M9d°¼Ùl—oqxÅ®y¯|º½þMú{=:«gø5G¥egŽ•‚ÓÜöŒjC_ëÒÝÃÓg¿kŽæîV~ÕÔòµßûJæò œ“7T¥~¸u—÷œI‰qÌØõ~¨÷EÓðòqº†u–ÖWÇ¡p°Øís¶Õg¬çä}[ÿÑ9_ó~‚±Ôï~7LÌȬŕÐóYþY_ø+Ø¡ö®¥ÿ•§ÿbiU:­ùÏÁs.Âôj}¸í}ž½v@9ƒ¬nr"2žHñpêcë‰Óåýä€e8“üGÍûäÙ›zN{+®Ë[(c)fÑ·s%—7ØÏÒ{©µR®–ô®~Mf]õ×`¦,yû>.Üf{1½7äúÖÒÏgÚ=e?¬ÖUöQk«!ðc¶‚Öî6Ñ.g»óþƒ=êôuôå¯õ€gå±û™0ã–ÙòÂþ´e8Gþé¥Ul¥¬ª½+¨3àѵ«"ÌL¬lg¼Ã==ÄÆ£Õ½ƒ!Žu¡ìcÛºŠíoè]_ó^ÿê-uKªdߎöZi¤5î¸×é›t۵ͫ'ùÊ›?¤ôýêÔIºîú3{|RÐ=8ý?Ôù¾‰Ì5<¹®¶¡I.tú±÷æ¿Ûíý7¨úØ‚î,ôšÚšÆ}¤°‡>I´²=ÍÛíô6·wþŒV2:Ëiuí4ümîµ»À†7Óô-ÇIõÙµ¿àýêMê66ƒŽ‘êÙSØëšÖHVç¹·þ“w¬ÏѶ´ï^ì$}§§å—ïmò|ÜQÿ˜‹ö^[²Ÿ}—n/­ÌÜZïuBŸEß¡s½&[úMþ§ü'£ê¡·£åú“Ÿ^ÑI¨Vlj77!»Ï¢êŸìk½Gú¤ÿFƒoTêM§"¶¸ˬ·݃ÛMFæÜ×7o§¹®Çc=ÿ÷!jãdï¿&›,i{- ª¹hvßN» ún÷9é!Ûýåc-Ç£ÅûÙ}Uÿ%Åe”ãÓ]›M•±­vÁ ‘û€þj±ÒŒb»ÿÚKC{þŽv7ù¸÷WWýi K¦i™šŽ;¾eoýK€úψGÄ`d~„¸G÷Lô7Ææ8: ƒ"|–~ Et;q‹uÔ7ú¬{OþeJÐ]4†ÍVíuÖ9ÏÖ²§Zr öìØú¶3÷=OOôµúŒÛof^sjÆuíûDïVÁ&œmÍÛsšåh49YÔÁîÓÕÿGû¬zÌ·×-û;ÃÈÜZÒèÎý›,vÝþÆ2ÚPúŤ[†}Jª8–:è U•¾ÂúmýZç³Òý_ô¶³ôžÏÑ— çÜÖŠñ¬¡í$‡‹hx÷5Õ9¯­Ö5¯ö?ÙþŽßÒ$á{«®·`ÚEM k¾Õ[]¾ŸºÊìc½¿MÔÁ—CˆG^þ‰o€=P†—AÂ{®‡í¿úê7~wìÿ±kþLÿª\£.ËnÐÜØzô蜷w?ÿ™ôýßiKpÿË8ôýOæÿ“¿è!-Ç›8AÉËš:d£!¹õªÿÿÔ½ÒÚ[Ó±jüêkçIv3¿éT§‹™‰–\1nmþ™û&íÁ¾è÷{«±¾ÏÜSôÝFoQÄtnÇμéû¹u:¿ègmY”:–}cʯx¹Íc¡°2mfC}v·Ö¶ºîüÏÖkõ=OÑó¹q—½{,põÖjkXÝÆÝ[þvMìý®õúRÏWý*Õö74èæøƒ£›þjdÏ ã04ôÎ?ËûÈ—¦qzdÞµXÈéùm;lh2e»ƒ·Uµ¯ý7¢çú?£±Ÿé?F«ç—ÝÐ}x¥,« µs»ÍvK+ªÀÛ+k[VEm­íV:s^Ì!ˆ÷8[†]†÷ú1·æÞ³ øÙ z¯Ól®œ»ðq°lf5vYëdZýæËãôε¯sÞêï­¿OÕõ?OgÙê¢õ~&†šð1ýÖLr–9 GæÃ1’'§£ÿEj˜5’WØÙXÈËcÊH‡¹ž¡iq nÏkŸî~ß ‹è;]‚é";/ ´»úôÿE¿þ¿øT£Šü¼+q˜Z×?ió·ÚöÙîÙïüÏÍVbA£z¾¢cæ#ÌrÃ6&'8Dëë­!/îäôÉz(¦ã}Ðû½r`Èfßk>…-ªÆWú&ïýßz%´Pks­¥`&×K¥À;·iÝnÑýugH²ú6^)ÜÊîe@\Ö¾Ã[ª·uþ¥¾ÍÜn÷u ZÚϽÙ%ÙV1í YS¨­¦ç;Ò¶–½íôO¿þ)>ý&3–qˆ&F#}å“Õ?OèÊNȪ§Ö©»Ó¡`Û=ö5ÌsÂ;ùÖ~ÿó‰¾Í@»×ôk¥ØÝülþr7ýb ÞŽàÿP=¬¸—{7o v?Ù·èý ¿LÒ°ƒKØòÒç–˜¯è ­î ÙV×Ùùÿú1hYa)Ê@Kˆ³ë»®–UÂÝSé{Cr²ôs¾uãµ´8éÿ VBϰmªˆûMçeðŸs¿à±™úkõ"&p·¸Øxï»”º²öÁsvúa›™-sŸ×[üßé=oæýéËËÇy}Ì*8Ƽ'Ž^£ÿ9B²ëè¶ãxÈ®ë ÿ8,†ïß¶ÌŠvØÃ[¿Ew³ù¯N¯ ‰Šw}¦Ñ¨»*ç4ÿ%„b7ÿm‘LtÌ'دu,iû­££Ôî{ì¹õÔÝï·ÙþG³cÕ;½x¸Ò?ûvoz²¼”'ôc_áKÿEG—•öPÇÝ`~ð'{Fêª c^íÙý_üÝž¡Õ.¾ŒVº‡zw:Æ0‚ÞeÏadÿ'éäÕ\úêÌê¸øÎg©è—ìpÜã¾çYúOж´Ú{=_WùÚ?D‹Ôîê8Xö5Ž©Î7Íq2ÏsÿI·c=¬vÍ–³þô_¢¸–ħ"2yŒpéê>™ÎtšªÛpŠÛû5ŸøÓÌ{½·g×ý¥ÿP¹Ü»·Þ>•u½íópiôÿγjôŸØ£þkþÁݧØ~ÿþ³ömèKpÁÎKõÜ´¯Åÿ:ÿÿÕèþ²ãý—ë n úž7iþ{Û¿7uØ™_æ`¬Lîš/ËÇˤVËXñö—ʆßcö7}ÎkY²–¹ÌÙþ“ô~§Ö¾ŸvoIu˜­/ÌÁ{rñX&^êýLý Å~F'ý}sY]õ²Úú­h²·x±Ã{þaXß„±æc¶A¯÷£é—üÞ7‰†Q~˜üG¥f%™âßUÞ…˜¶ï.Ø\Â6ÙO¸í¯Ôo·Õúh×ßF=.¿"ÆÓK>•0Ñàßå;÷Xßzª3Ý“íénCf–òF3~;ÏÒgXÇæñ?Eþ“.¥WÔ«ª×öÿÒÚ@mY÷¡®{xçgرi{ÛöoÑd~ÐõžõqÿXTÄ$t—èƒè=5„ Ò_¢>_ÓeeöW˜sÝC±ð. ¢ûn"·îkœÜL×ãmõ(Çý'Ùl³!ì»Óº›,Ǫ¼tÝOûëΡûf)^vXÝëÌW}¾Ês~ÏS?Jû}KjÉû=-W5®k™cCÚàZö›½ßàžúè­ÿ®ÿ=K*±›Õ02›v'P¨RÖ Ö7$KÃ}1ê·Ö÷RýÙlªý™5úôÿ…Vá*ù}QýßÒƒ©ðߊæäcî )à'ÕûЗèµRW,èmv.EÔ7³E`'ÖÛ‘ÿ³jø}B¬šqÆF;½jí³y¦Á‘¥»v} ý?´~ÿæ)a(̈ÄúBôœ¿üaäsÇ ’ý Cü/šPR–íx¥7d¸K1ÙÈã{÷{i§÷¯»ôh®ÀsXëró^*`.¢ÁCCZ78ºÏÖrí»+Qûn¬ ¶ç–׎Cêu–ŽÙ‘nC}oYõÚßA÷úž«ì§ý*±ôxL߈c‰¿ÞŸýÌ#ó'ª†aUffQÜý¿¦¶¶¹Á•ƒüÆ;c{™¿é»éä[úK6~ÓN997¿©X÷WMŒÓC]¾§7é šÝìs?–ÇUêúþ·é?í; ΟfNc³2Àkæ¦í6×YöºŸ»Òýèmÿ‘êâe~‡ÒV2òŸ[¾Ç†Z2Ã[.‰f;ö[c>«·ú'øOç,ý[ùË1Ôb<ƒ™)JDÎdï~2(srü¦WUFú°žÖnÛúê~Žçâ1þ½µzµ~šÊ?ÂÕé£S}9 /¥ûÃ׈-sOî[SöÙSÿã­âtì|.’쌬{×µŸdÞømŒ±Íu·3.¿Sü¥üí먒ٿ["Ÿ[Ñ¥‰Ó,êOÞ–mΆå ]5–Ù”÷mþy¯ôuã[ú/º¯ð~¢±,1'‹åùèÈÿU~lâ» ³ßü¾ÍEw?,ÂÙ.k\æ^Ú©w­s+ÛÿžÿœU:c™•—“ÔY¯ ¬0ⱎ÷YKM®ô][ÓSg«O³ü/AÕúVèÅÖd³í8M×íøí'k@Ü]›ˆÝöãíçèõñ¿Ò}‘Pì!í³Ü×´‚?œ×7Úÿë(4-ÜsÇ—†Xä bxŒkÕÆzɱÓ0ÎWéø Kl½·]¤GŒ»7ÿ&ËÙ‹ÿ¡ Ô—õ§‡¿+­³=WÓÉôÔ1lÏŶæf²:uM}£,Ù¸ÔÆ Í£ßúÆc[H÷dXÏSÖõ)ý/¥½ DHôÌ|Ð:z¿©ÿz¢,’=2ÇúßÕb󕇒Ìj[gQ©í}¢ Aɦ¦mgÓµÌnu£ýYsÙÿ —é§#¦õf?Á™[õip-¹› sE´»Ò˧k÷}&ìRÈ¡´Ùx¶Œ®­ÆXÚØ-ºªÅvÙ…Ó±ë¿õve9Úûr¿U£#';"ïæëS¾Š²2êÂêXÖäo­ïƳ2ºEí5ú_¢£;¥Yèdzž¥c1þË—G¡újí®ÏQhÃý¯pþÍ!½ÿ/ë6H—«ûÜ-VtlZ²Ù•SœÇ6ï]ì1µÎÛ{?3ÒÛý+þôuUüÒ|ÏùKÿ åÕa-7ý[Í­Ö6ŒŒÊ½"ö+ÉkKƒ^ g×}ßFÆÿ†X]RŒús°¶gz޲œ×;¡;pÚÇ1Žßì÷)¹hN\Æ0M@CòÉ›”„Ç3ŽR7\_ÞùdÛpkšZà××4ðC†×4ÿYª¿§ƒÓikîx©£‹òºÂv¶¯m¶îµîôke^àÙ³ÓUÆ?V·Ù®~{ð7?2šk¢íõk¬e?¿“Fúv~“ÕôÕÜ^ˆÊkÍûE4ääµÏ¬Ú\ë6×gÙï6åÞç=›]û®ôÿë~§§­7©”jëO^¿à»>à;/ñZ–fä]íÆ­'&Öiÿi±¬þkwýÈËÿ­ã-«ßSîê½.ÌÜl‘‡SŸhÆa`´Ûki»'>ÛfݶÛUµþ‹ÓÉÙú__þÓÖÆî™Ó¨k°œÌì²÷°ºÀ@ôþÐÚËú ~u9ߤÿØ•›‡Õ:§KvCú5卑õ».üF:×¶ªßž.mŸcõ^vÛö{jͶ¿Òþ“ùõ$áÁŒœgƒ]e/L¥àædF†˜Vì¬èØìçÑFP[½Ç+Ž;šÈe¾µÖ~ŠšÿX³eJÿ^ú­“Ññp¯Ïµ¹mÉqnIh ¯'éâý’ÏfCi{=\_Z×úÏÈô?šûO¢µ0.=#®þÖÊuv»¨ZÜ~£w£]^Ÿªí”[C™ÕCr¾ÏÌ‹r_e~ŽE×z˜ËSë7U¢Þ‰‚湤ìêYZöÖߤì*›kl©ù··÷™gØéý=¿¥û5vG.fdÇACæïþõªPÊ2G¨ë_½o5õ{¨uâü°õK>-‚¶c\FX6´7í·¬~Ý^#YéÕUUæWú^êÿÑÙnìNÔ®Ùi?Vz¶S¶úµE˜Y6<Æê\öÕOÛœÖþ{0z‡¬ÿûWS¾šÏªŽé·`ýa§«ºH,fE¬®›+©‰•mL¡õ»ôž…¿dÿµõ]þ‘SÂÌO³äî·©¶œ®¹øÆÇ· æRï§k±½_ÔgóßÎþŸÔP“r$G£. ÈÆ áËŽýq:oò—¾ÃÃÇÁħ žž>3UL’a¬7;ÜïhF\·Ô¶æN[ª½î赇M„ÙÔK2Ý‹uŸ¥û nÛ‹]O¶ÿÓÓ‘èz4z~§R›M_o×íØß‚ÿEÿ×õT’I8ßXºíJÙ‘‹`ÇêxÀýš÷ cšu³-÷Y‰vßøÊlýbŸÒV¹zì³{ê¾§ceÑ#æ\Â~‹Úñí»ÈýM£·þïR¦z Íë] «ÔÁkFM».¨ÖOÓhÜË)·ü>=Ͳ‹¿sÙZ«Íò‘Î,zr ¥ÿs6c—ŽaÚciÜÉâk鸵æ;2°[kÉu‚IyklvâïæÙcÙ]LÙWý·O¦<ÐrïfÛsCšñ¹Ž´Z–Úߣm85Ý_7ÿÏú]; þôUìÜn­Ó­ô2°Ý‘mŽ-ij®4ÞïðU¼þ‘Ý6Û7~“í«UúK+Ì»ÒzCn8{Üne_I¶²ÝÌ{ñì麛tö~Ð˯ô;?˜éؽŸð*·!Éd—1ŘÅUÅúGôxOõZPÅ8HÏ 7 !zÜ¿Gü!³¥u,kñU¼¶Œªnci{>Êöä:ÌL×;7¥ìöÖ2žŸ•ƒ¿ùºqÿšE»'&þ­cÙ‘n7Iqª«1›ê¼dZßÓdßCÎulm Â{1_]›ò2}_})ëÁêý.G¥œlœv3ÛE¬ôž^ÚÜßUÏ©í­ößs(õþ}öÿ8™ù=?;*Œ~§Òî«-î5cÝe\Hg¥ŸI¯&ÿI›?Gÿ þlÏ L%pã:ÿè̼`›EÃÑ/ïp§¯©µÍq£}VÜQ¨ì›êÌm6TßI¿£²æÅ.­çôË2ðvåãÙX§)¯-º²!ÇmsÚÿnöµûU¾£SGTêVÜêqë¯Ò¶ë’_oO¹ù—]KóÝêØÏõqª©Îû>NG¯fÏô¸uì ­Ë=C8_½¹bê[/¢ÖY‹‹gçþr©Ëâöó‚\~Ī¿½™— ŒrÆVw<1?Ýý' §õvu\L.›–Y‘ÒØ1nuNÝc¬ôëè÷g6·º¿ÒW—ˆú2?Wû¥ÿr±6BY¿¢`RÚ±ßkæSEV¼Ü×½ÛÏèeÑê7ß¡ê=Šå9™™½O«e:¾¥Š ØÌ¯µšß[Nfï³àú¸ø•²ßÒä>ÚýSùõ üï«6ZN[Û{šÐËMa ,ÛVK+w¥‘éý«}mÈõ¿ÃÂ(þõÁÌ ¸Äö”x?Dy:ðÄF2 ‰zÔœrqqzÏìî²íõbÞ*ϯö;sl­¯«ÓÈ®ºnnÛ-ôïÇýNG§mXÞ«ÿV»¥¯«Y“ÓË~¯ãá×Ñh{ØÎ[aËc\ædQçщöìgz´Uèßu·ìŒFëiY}C!÷ôK*ÂÁ~>6F3Ãn`¦£[.m·]éb‹_UT:¿W#ô>«)ý*»‰GIÆwN£¤f¡“SloUÊǃŽjp¿"†¾Æï§ÖÇͲªz}LµùaúÿàT¹y©æÄrX„ñšáù¸£%þ ¦°ãä#+Ÿ­=;þ’6·ü€þ‘ë~À};6f9Ö2íãec£7v]íúûE¾–GóTaú¬ª¯µ÷—tŽŒÖcãS ¿&¿cjk‹ýjñšÀÝ·þuW·ÔeÖzÿÍ[W¨•‚Æç7Ï}4ßcó0l¯oèò6¼u _Ó¶ê¿M]ögc~‹ô®z?ÑÔ®¾¬ o²tÚ[¾§²¦ÒÑìc­»óSn½Õ1öýŸí­»èõ,«×õ˜æ'ÈlGò Ìqá…j:JDñN_Ôƒ+kÂé˜t ñ…Å$b´€\׺ë=^×ú7Ù]vú;6z·~¯ú4>‘Òòú¯PuV<³¨ÚÉËɨAÂijùº1ÜẬÜêØßF«}Kq?O—ÿ‘,LÞ¡ÔK1Yêu;¯½ƒÓéøïs/®œ–T÷Q•œÇ±·cQ»íÿ¤[F/ó½çIé8}# bbAq²ëžw[m®þw'"Ïð—[ÿ¨ëôꮺӉ`æy€=0Ó¥ÐÿÐÛØôbãÕ‹ŽÁ]1µÕXá¬hØÆê´"¤’kAÿÐõT’I)$’IM^©Ó©ê;'§^÷×N]nªÇTí¯ pÚ펇Ô®;ªý^ê¸äÝk憆uNš6ä±­ géú[±ÿ£«Õé–zÞ—«]tz÷zÚH‰²ÙÀK~œbuN¨l}u6¾µUaζÌx§&¶·vöe`¼Têò}Íe8ÿffÿFÏÏV›õ‹ší¶ú²q~ÍWÚ,mµ ±¸Þ›¿u–}¤ú5îe^¦Å×õ‰Òz oÄ®÷°Ev¹±k5Ýú†m¾ŸúÕŒY¶ýT{dàõLª@!Ì«#fem îæ²ÌߤÝßÓT£1þZµåÊö£ÿ7þùä*éÝ6ÊK°‚Ú sì¦Û]Õ½®s÷äôÿQ¸_"‰ý[íøÔ_ú:}{2VçOe5õ®ƒV;·SK2k¬îÜv²Š*f÷~þÁïPÎú‹Ÿ}‚ç“föØ÷ nÄuŽnã¶û*¿7Ô­Î~뱞¯ç«]êÇQÁêx¹ÆÂÃÅÆ7½íźÛ\û.eTnÙ~=;=´{ßê¦ÜjT¿5цN8Y¿Ýìãô|\lž…Ò}z›i«‡W¼NÓé´iýoÎJ®«Ðñr¨Á  ,ºß³VI­¡Ísñ›ïsjý¬Ûq«¶¿Qž§«ZÒÁú¯õ›]€S)m…·¼Á±¯s”{·÷Ѫú—š-6?;özÖ;Œ°Ød:ï[6î¡ú_s¿Ié,ÁÊä$ñ /OS®y¬`úú\JzænCwQÒ²‹Ý>Žâ í6V÷^önô×Òïëÿì?®Ý7ªgåZ}w«žÀYÒñk6äR\gõÛ[¶Œ7û½'³2Úü×óvúÞ¯U_ÔÞ”ísìÈêfwmË´šôìì,³à¿ûx«g–ãâÔÊ(fŒª¦†1£ù,`kZ¥'Ò¡ýÝçOþõŠ\Ü¿Fôýïûؼ_PèXrp>ÛeuÑöK+ʯ§Uúl‹=' ÇfG¥FCªõk®Œ:Ÿê?ô/Î}XŸ êî_WÉûa¤ôÜrÃ_Û^ÀÌë?G·‚ì ]îýc'õÏôXØÿÏ®á%fŒ#ÃAïjC‹æ6Oé}ø8?˜˜U h¬CXßôž÷:_ew¾Ëlý%¯÷ج$’,*I$’SÿÙÿí^¸Photoshop 3.08BIM8BIM%F ò‰&¸VÚ°œ¡°§w8BIMê"× com.apple.print.PageFormat.FormattingPrinter com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.FormattingPrinter i865 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2005-10-11T08:11:41Z com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMHorizontalRes com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMHorizontalRes 72 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2005-10-11T08:11:41Z com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMOrientation com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMOrientation 1 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2005-10-11T08:11:41Z com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMScaling com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMScaling 1 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2005-10-11T08:11:41Z com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMVerticalRes com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMVerticalRes 72 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2005-10-11T08:11:41Z com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMVerticalScaling com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMVerticalScaling 1 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2005-10-11T08:11:41Z com.apple.print.ticket.stateFlag 0 com.apple.print.subTicket.paper_info_ticket com.apple.print.PageFormat.PMAdjustedPageRect com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMAdjustedPageRect 0.0 0.0 819.21260515348172 575.9999831792876 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2007-07-13T10:56:58Z com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMAdjustedPaperRect com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMAdjustedPaperRect -8.5039370078740166 -9.6377952755905518 833.38583349993849 585.63777845487823 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2007-07-13T10:56:58Z com.apple.print.ticket.stateFlag 0 com.apple.print.PaperInfo.PMCustomPaper com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PaperInfo.PMCustomPaper com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2005-10-11T08:11:41Z com.apple.print.ticket.stateFlag 1 com.apple.print.PaperInfo.PMPaperName com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PaperInfo.PMPaperName iso-a4 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2005-10-11T08:11:41Z com.apple.print.ticket.stateFlag 1 com.apple.print.PaperInfo.PMUnadjustedPageRect com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PaperInfo.PMUnadjustedPageRect 0.0 0.0 819.21260515348172 575.9999831792876 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2005-10-11T08:11:41Z com.apple.print.ticket.stateFlag 1 com.apple.print.PaperInfo.PMUnadjustedPaperRect com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PaperInfo.PMUnadjustedPaperRect -8.5039370078740166 -9.6377952755905518 833.38583349993849 585.63777845487823 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2005-10-11T08:11:41Z com.apple.print.ticket.stateFlag 1 com.apple.print.PaperInfo.ppd.PMPaperName com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PaperInfo.ppd.PMPaperName iso-a4 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2005-10-11T08:11:41Z com.apple.print.ticket.stateFlag 1 com.apple.print.ticket.APIVersion 00.20 com.apple.print.ticket.privateLock com.apple.print.ticket.type com.apple.print.PaperInfoTicket com.apple.print.ticket.APIVersion 00.20 com.apple.print.ticket.privateLock com.apple.print.ticket.type com.apple.print.PageFormatTicket 8BIMéxHH4@ÿøÿ÷BJg{àHHØ(dÿh 8BIMí––8BIM&?€8BIM 8BIM8BIMó 8BIM 8BIM' 8BIMõH/fflff/ff¡™š2Z5-8BIMøpÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿèÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿèÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿèÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿè8BIM@@8BIM8BIM_,'SySync diagram_plugin',nullboundsObjcRct1Top longLeftlongBtomlong,Rghtlong'slicesVlLsObjcslicesliceIDlonggroupIDlongoriginenum ESliceOrigin autoGeneratedTypeenum ESliceTypeImg boundsObjcRct1Top longLeftlongBtomlong,Rghtlong'urlTEXTnullTEXTMsgeTEXTaltTagTEXTcellTextIsHTMLboolcellTextTEXT horzAlignenumESliceHorzAligndefault vertAlignenumESliceVertAligndefault bgColorTypeenumESliceBGColorTypeNone topOutsetlong leftOutsetlong bottomOutsetlong rightOutsetlong8BIM( ?ð8BIM8BIM 5p Ø'5TÿØÿàJFIFHHÿí Adobe_CMÿîAdobed€ÿÛ„            ÿÀ "ÿÝ ÿÄ?   3!1AQa"q2‘¡±B#$RÁb34r‚ÑC%’Sðáñcs5¢²ƒ&D“TdE£t6ÒUâeò³„ÃÓuãóF'”¤…´•ÄÔäô¥µÅÕåõVfv†–¦¶ÆÖæö7GWgw‡—§·Ç×ç÷5!1AQaq"2‘¡±B#ÁRÑð3$bár‚’CScs4ñ%¢²ƒ&5ÂÒD“T£dEU6teâò³„ÃÓuãóF”¤…´•ÄÔäô¥µÅÕåõVfv†–¦¶ÆÖæö'7GWgw‡—§·ÇÿÚ ?õT’I)$²2qñh~FM¬¢ŠÆë-±Á­hñsÝíjJJ¨õ·Ó:ac2ï ºßæqØ×[}Ÿñ8´6Ì‹vþvʽ‹¨uN¿ÔñmwF¬àÐãSîhnVAiµâÕxôºuy-k««/>«ný'ô ÿMÓOFÅé®ê˜Cn=Õ‹ò]ºÛÞÖ‡XÿµZóv]÷ÓúJý+ÿMÿ¡T¹ˆcÆ*Ý•ðú~XËÆI´þ¯×òÏêxUôúŒEÙîõ-ˆ—“ðŸ·þÞê8öÀ žŸÔ2#íý[.î¿ì}‘ŸnÛý|û;~°ÝxôŒ+2²‹CÝ¿o£^æ—µ—dÓcè{Üæú? ½þŸñOS8?YsNìœÚ°j1ñªõ$n­Ößiß¿nÏæmÿÒk?/7ÍKæÈ0ÝŽ‡þoEÔ» t§‘AÉ’ì»mÈÔ­læ]wÒwµfgô¯«x½oÕÀÀª§âf–UKûüGùÆµŽ±»­Ùÿ]Væíº›ºRÊÈv3ªÈ½ÁµîÅý'«èÙ»Ûþ÷îÿ®Ö£×*¦îµÓ[mlµŸfÍ!¯k^ߥÓáÀ<9ªvBVrO'¦w¬¿súË¡)ínm?-´Vѱ2Ö±÷eôëYF¿¡vE5U‰f5Ž»)”Ûêƒúÿ„°Ì³„ÌwåeõNvKò=WeÔÓk­f>1ýªÌÛ}}•~—Ò¦­}_Ízõ1C'¦}^cE™XxUµÇh±õVÏtǪ;Ö;ó’§Ö¹Ý#7.†ÔvŸFÛ_WýnޤܬK©ÓùÌzý/øDèó¤ $üÑâàÿ ×8ÿãlÇ•–ÀÄ—W§}bê·4œK°úíM–×» & j¿s+¼äce~ƒ&ÏÀ§{Ö¶Ö>›“Ü;‹ðsŸ;pòÛéXèŸèî—cæ}ûE~Jãò:m–rñ1ú‹víõqç( ú@»§äÚßåY‚šœœ›v ëTwIêM5æ5¬aÛk«¹—ý¯ôŸf«íx¾­¡õ™ëåZûUÜ?‘ê3¿èOíÿÕ˜±°O£ó?'Ñ’\gEêùË:]ç6ºœ[‘Ѳì?j¤4þ—ìyy[-µÌõ+kñóm¯êÿ´q½5ÓôΫ‡Õ1ý|WiÙm64²Úž>•9Y¶Êmþ¿üe¢Z8³Ã-ðGÍ i8ýMÄ’IH…$’I)ÿÐõT’CÉȣܜ‡Šè¡Ž²ÛÃZѽïwõZR£Ôqzf+²²œC c ž÷¸íªŠ*o¾Û­²ºØ±N-ýFúsº»@}õ10$:¬w~eÖÇèòºƒÓ1‡üÞø\¼…Šr:•ìêÙÔº‡Á–}*+pÛêÚÏÍê9Lþ{þâQú•ö®Ü‘uLž¡c†Kim·KmΟe¶ö‡5·5™¬­ûê®ö³þÕý*ÈçyÓ’GÃóä¿›¿øô×¾gZ®Œúº~5/ÎË{¿O]%¿¡g´ºÜ‡¼íc¶Ùú*¿ÂÿÁ¨Õ=7«œy?cêu¸ṵ̈ ™T7Ûµ•çTÇgUÿvªÏÿOZ®çáý]Ç«§ã ®£‘±­Ço±öÀw¾çµ¶ý—­eßdgôZš¯ÑÅ®ÛiÒÏÂgQÁ~=…Ô9ᯮÏϦÖݱÛ}\kØË>Ÿ¦ÿæÿ›T=1¡U iÄ~i¬àþªZ™¶u6Y^HÅWYe–Xöµ”œãëU‰uný_·óñlþwÿBfôwc×öϬL\ÏJÚ/õHª‹+ÈÜmmÆÇWSm¯sh§#¬?ÐUüßé=*j[Ö:þc,©¾ŸN·šrHß{ï¬MŒ¥ÙLû6=Îs‹cêͶÜ[©»ô ÆvPxËÄÂý)5šòóÈ·Šl±®¿1ïö{rhýOÒÞÌœKѲ›”‘‰Ž(LJæ®-{$¿{ý_<9yʉÐKXþ‘“¶Ú>£—ŸR×õ]­uqU7d׵쪻ð©u.{>Ïê1Þ§ôŒ¬«ö~“Ø\î«E½Kì|,Ñ‹‘IÆÁ´âz eN v͘¶,v³/öYÕºµ5ŸDÔöYw¸=öï­—ìfí–3ÔÙüÕöÞqÁèÄ®ë5·ôMŠÁ ­­{_nÍï§×Èý/鯲ÛYè'ðÆ{ÊrÂË—¦\<0‹,y~>¡Ð˜CW¨³­t‚Ð2½ZZ×µbÞÆ‡0‹+~û)ôGcw·Þ¡_JèÝ@SnM«»cq2‹ëc_êXÖ¾×b×e¢ÙG¡èÿ‚YßkÌÊ˽Ý/«a–¿cqñ½FØC@«Õ²ëföÞÏÏõoæ~C,d²æÙÕ:[o °œüY®Êý¯·%þ­v}·ÓÅÚÚëþkí_Û®•Ãä'(H‹áâõj?ÍÊ8{÷ÙŒoļ:7w¦áåb²Ó—”ìÛ­x"×H¶´2ºÛ[œö³ÝêÛfÏôŸðh}B¦gåctè‘C›™}­%¶TƸýš¼k™úL|Œëëþr›+·ìxù?é+TpºŽ`vÌ{šÆ‰8™¥µä‚?ž§5’ÛîÆšëÈfUWzV?Ò·¨2ßSÓ?O®ž¡Óò±îµõgd¸YÕceÕXí›+c.õ?V¦Š«ÃÅ»ô¸×U_©ôí±Fa8Hä‘ÔUJ#äâôñðzxx?ô¢Ò4­Òþ¯l¯´cWeٹᔚéë5ÔÛ3±Zï¦üšZÝ™Ô6¿ûWElËǯÕý¾ì´j-Ï¿6›®s1º†;X1úÝD Lšmþ‰sý½A¹v¿ÛEvo®ÏS'ì6ú>½u,ž•“éu7dÞëËÝE£cªö¹ßgeþ†Ö_m[}96~‡gÛ-·ÑûFJ¹™ƒ@Ƕ‡SëôÛK•†Á%…Ó¿¨tÆÃ¶\Ýï~F#éæ3Ô²šýVœÉñæ”%"?Íæ‡ãû¿ú­¯“ ˜tù ö7ª ÃeWölìxûF1; :};¨²ëâݵÞû?à®®œš®¢«Ë€Âêy/{0òri¯«b±×ôž¤H5ߎíîjmO»ÓÁÊǦ½Ì»#Öº¿Ö§âz˱éLu,1sê8Ù5¸Õ—Šâênh¥.s~ŸÒm”ÛþÊrú;Vß-Ì{ ‰PÉëå˜ÿ9êÿÐj‘Mä’IXCÿÑõUÍuÊ:¿\wHmu'ÓÉˤ>fAý&%o«óñ1³.×7f_Øëÿ´ù5­n¹Ôÿet¬ŒàÏVÚÚE_¿u…´âÓÿ]Ȳº÷.tê} ë¼›o¨ºÃ˜Âk»Ö°ú¹YTßQÐü‹œ÷û³üój—Ä3Œxø"YlXÞ0ý"Û˜Ž eÄz~ïï;X/ʲ¯Ù8Øî}ÝF«VKœY@{aî¢Ûª=–¾ŸVÍ–7Ó¿ù¯Ò~—ÓŸgúµ‚+Ãk²³óÑ]n;}{ÚÖVûöËYêú{_c?ŸÊôýïþvä^·Ô°Èfs]Ô1‰´ÒÐ2X ?Ò1+ÛVcßð¸^žGýѱnaæâgc·+ædPÿ£c ‰ZïήÖî÷ÖÿÒ1b’c+‹ܸO¦réÅû¿ÝfÇ–Àßæ<ÑV>/Õìggå»íW$zn{cÔºÇ]ؘM>ïMöï·Ñ¯þ±E¢ÆZ##;+ ¹Y­©§!Þ®3)ÜcÀ×ã2ýßK%¬wé}?Ñ©ät¾Ÿ•Ü›è^ÖŠÃ¥ÂZ×ŒŠ˜ö±Ím¾•íõ¨õ?™·ù¥Ö:ÍùÙ…ƒaªŠœY•–ÃsÆ–bâ=¿ÍúC+-¿Í?õ|oÓú¶ÐGëtý-ç9~ˆýسcÇ,’€²ÕëÙ4·«ïéa¹YNg¡Ôke,5ëvF[Ygë”î}Ä©¶äYgé=³Ò¨;#'ú~M—Í—cÓý]µ?í7èFUŸñi[~MÇe{[]u€*ǯkL5žÆ=ÌkYêYú[¬w§þšÅLÓÖsÚÖÙkq±ÞǶÑ[\Ç8º_mAÇí öúUäSe˜õ>Ñ_øEfÀè+N9|燳¯‹ qDc7šCôB<_ËôÛ$ôΙuôÒÊ٥㶹í¸ú«ßío¹þ¢!êØch~HcœCKLµÄ¹¾›w6·±Ì{,÷~Us:?Meøù9 ¦†ÝE¯îM[½*ÇÚ7¾”Ùgø_OÔþ{Ô±á6ô'ÛëYëÚïU÷˱ïØ^ñ]ræ³{k®ŠÛ^ïúïªõ ‡µ9X ¶^)#íŠÞòê߾Žûr]~=.,±öl±­p!¾›·oý&ç7Ú£Vic_Ó2,ÅiÌkêã}Í?e¼¾½Žÿº¯ÆÿŒUkoAÉÇwNĽ¸â×ïu5ŸNÒïäÕ–Íÿñ{+ýÊýOÓJÿÚ¸ºÁi»<ÛsíF:ÇŸA­už»îÙc›ú¦ÿÙÔWOô¤¸FÈ×äÈ7ÿ ë(‰ Öxõ1—÷¾eò¨ªË½JË:}ž˜ª¬ÜgÆ3}Ú?ÜvEžµõ~±oÙÿYÈô²½k‘l·"œª±º®úî­ÓƒÕhX\6·ßM׾Ͷý¢›*ô.Æý6e?ÎY<¥^Òw8;~+Ü×8´{à?ÃQù›ö~úV´bRêlÜî‘cK-k\Cñštõh{IöôµÿÚ/ç+ýSÕ¡‘NjÛôõT¿õóygŠ<&pïëãÔ±²3±±­ª›œàû, kŸ¥­/°TúëÜÿçvz?ðˆù}««õL½HvOÙë'³1XÜg4'íŸmrÆÞÌŸ¬õš¬¥Ã«7šœÿ\¢ül¦z¬£Ñõ¯³cþÏwýkÕõ–7!—™ÉwÊ&:S§þåsdÏ;ùq‚?ÄÿÐÝkm¦’ÁuŒ¨Øí•‡¸7sÿÑ׸ûßü–¨?·!Ùx¶¿4ˆvM1/±­Ë¡ÿ Í­¿÷až£?ÀÝJÎËõ,úʼn[+õ[C– Ûv‡ŸNËaÿ™Oê϶ªžÿµ3Z׸€9&>õTƒ²Ÿ¯è°\±˜Ê2"D^~©õ«6¬ÙÙ,™92ÔñœEUãÎËrv?~FKœæãQë~«U×zßm³ÑØè†âýŸŒvúE˜ïhÜ6í¦ÆðžŸÓÿ„QÀ´ÝëutËyŸ j‹©Æþmß§ÌwþLzs¨3ÓÜ1œïwÙ\ Æ|έ¥žüG?ý6èÿîµÊÔ`#–òýÞ?ýÜøwÅñá'1›Cš Cþñ©^+1ÇÛú§¥WÙkkXûl`kZúýKw»&û“‘è7Ñõ?Oé~±jÙ™yº’üŽÅ&íßL@Dl:U•Œe¬ÙsE¬<±à8šùJ‹r°¢¸ÙKGôK\Kô÷î~3¿ÿSù8¥& (ïo­èkê–ú›`ýÙ»tlú_šŠ"Çe¹1Â_6‡hËiÿƒ&ÓêÄê5ž£Š,ûKA­y¦ÓcòíìÆ»è1÷íõ>Ïú?ZÌ+I{¹-©È{nȽìnÆ’Iµû¿7رM§ãžÆ¹ÁŒª›Í•7]Û]íûF/ó”#ÕÇÿ®¹™œ§ŠñÞ$bÐùÜ×ûS˜Í®·wú,OJøl…ÝrN\1ùéKôªçå”yy xÎÜ:G ýÿûå¨ê­Á²Î™ŒÓ–OÙ@xmu>¾÷û¿¡ÿ9MT³#'ìÖz›=ñîË{®¾Ö¿1Í ©ûbšÜÏPÐæc;Ôõ=Ýgé²¾Ñw¿ô~ŸÐE̤œ-¸Ì ³.Å­£kCë—úMc6µ­¾¿Wþ¼“]Œmµ®Æ‡Ö|ZὟô\¯`äð⑘C¼ÏýÏî°òæ98¸‡Ê}1ýÆ_»ý×?¦=ùxvâ]cÞø Þâ^Fòæúvk¿Ö¥Íßv-¶½þ¿èÿCTº3î4[U­ƒUŽíA1±Þêͱ»š¡ÿ£ýÏô„˾ÚsðÜûcàêMd˜ÞHÚývïQŒ÷ÿà¤HŒL\ðZâróì“Q°ÄAõ.m-=›>•¿ñU[þ Yd„Ç_æÿW+ý(ËäÿÐ]¿«¹¿`úÃ…q1VQv äÏø_Òâ;OÝË«Ðgþ^”¼ƒ-Ö·Û(%·RßZ’9RFUø-,^­ûCöwí=ߪú?ißÿ·ÖÝþbi Òæ±ðó˜f?ÊJãB\?ôxÿÓ¿€óf#/:œ—[’ëöÛ•ÿ£“Ó‰M9d°¼Ùl—oqxÅ®y¯|º½þMú{=:«gø5G¥egŽ•‚ÓÜöŒjC_ëÒÝÃÓg¿kŽæîV~ÕÔòµßûJæò œ“7T¥~¸u—÷œI‰qÌØõ~¨÷EÓðòqº†u–ÖWÇ¡p°Øís¶Õg¬çä}[ÿÑ9_ó~‚±Ôï~7LÌȬŕÐóYþY_ø+Ø¡ö®¥ÿ•§ÿbiU:­ùÏÁs.Âôj}¸í}ž½v@9ƒ¬nr"2žHñpêcë‰Óåýä€e8“üGÍûäÙ›zN{+®Ë[(c)fÑ·s%—7ØÏÒ{©µR®–ô®~Mf]õ×`¦,yû>.Üf{1½7äúÖÒÏgÚ=e?¬ÖUöQk«!ðc¶‚Öî6Ñ.g»óþƒ=êôuôå¯õ€gå±û™0ã–ÙòÂþ´e8Gþé¥Ul¥¬ª½+¨3àѵ«"ÌL¬lg¼Ã==ÄÆ£Õ½ƒ!Žu¡ìcÛºŠíoè]_ó^ÿê-uKªdߎöZi¤5î¸×é›t۵ͫ'ùÊ›?¤ôýêÔIºîú3{|RÐ=8ý?Ôù¾‰Ì5<¹®¶¡I.tú±÷æ¿Ûíý7¨úØ‚î,ôšÚšÆ}¤°‡>I´²=ÍÛíô6·wþŒV2:Ëiuí4ümîµ»À†7Óô-ÇIõÙµ¿àýêMê66ƒŽ‘êÙSØëšÖHVç¹·þ“w¬ÏѶ´ï^ì$}§§å—ïmò|ÜQÿ˜‹ö^[²Ÿ}—n/­ÌÜZïuBŸEß¡s½&[úMþ§ü'£ê¡·£åú“Ÿ^ÑI¨Vlj77!»Ï¢êŸìk½Gú¤ÿFƒoTêM§"¶¸ˬ·݃ÛMFæÜ×7o§¹®Çc=ÿ÷!jãdï¿&›,i{- ª¹hvßN» ún÷9é!Ûýåc-Ç£ÅûÙ}Uÿ%Åe”ãÓ]›M•±­vÁ ‘û€þj±ÒŒb»ÿÚKC{þŽv7ù¸÷WWýi K¦i™šŽ;¾eoýK€úψGÄ`d~„¸G÷Lô7Ææ8: ƒ"|–~ Et;q‹uÔ7ú¬{OþeJÐ]4†ÍVíuÖ9ÏÖ²§Zr öìØú¶3÷=OOôµúŒÛof^sjÆuíûDïVÁ&œmÍÛsšåh49YÔÁîÓÕÿGû¬zÌ·×-û;ÃÈÜZÒèÎý›,vÝþÆ2ÚPúŤ[†}Jª8–:è U•¾ÂúmýZç³Òý_ô¶³ôžÏÑ— çÜÖŠñ¬¡í$‡‹hx÷5Õ9¯­Ö5¯ö?ÙþŽßÒ$á{«®·`ÚEM k¾Õ[]¾ŸºÊìc½¿MÔÁ—CˆG^þ‰o€=P†—AÂ{®‡í¿úê7~wìÿ±kþLÿª\£.ËnÐÜØzô蜷w?ÿ™ôýßiKpÿË8ôýOæÿ“¿è!-Ç›8AÉËš:d£!¹õªÿÿÔ½ÒÚ[Ó±jüêkçIv3¿éT§‹™‰–\1nmþ™û&íÁ¾è÷{«±¾ÏÜSôÝFoQÄtnÇμéû¹u:¿ègmY”:–}cʯx¹Íc¡°2mfC}v·Ö¶ºîüÏÖkõ=OÑó¹q—½{,põÖjkXÝÆÝ[þvMìý®õúRÏWý*Õö74èæøƒ£›þjdÏ ã04ôÎ?ËûÈ—¦qzdÞµXÈéùm;lh2e»ƒ·Uµ¯ý7¢çú?£±Ÿé?F«ç—ÝÐ}x¥,« µs»ÍvK+ªÀÛ+k[VEm­íV:s^Ì!ˆ÷8[†]†÷ú1·æÞ³ øÙ z¯Ól®œ»ðq°lf5vYëdZýæËãôε¯sÞêï­¿OÕõ?OgÙê¢õ~&†šð1ýÖLr–9 GæÃ1’'§£ÿEj˜5’WØÙXÈËcÊH‡¹ž¡iq nÏkŸî~ß ‹è;]‚é";/ ´»úôÿE¿þ¿øT£Šü¼+q˜Z×?ió·ÚöÙîÙïüÏÍVbA£z¾¢cæ#ÌrÃ6&'8Dëë­!/îäôÉz(¦ã}Ðû½r`Èfßk>…-ªÆWú&ïýßz%´Pks­¥`&×K¥À;·iÝnÑýugH²ú6^)ÜÊîe@\Ö¾Ã[ª·uþ¥¾ÍÜn÷u ZÚϽÙ%ÙV1í YS¨­¦ç;Ò¶–½íôO¿þ)>ý&3–qˆ&F#}å“Õ?OèÊNȪ§Ö©»Ó¡`Û=ö5ÌsÂ;ùÖ~ÿó‰¾Í@»×ôk¥ØÝülþr7ýb ÞŽàÿP=¬¸—{7o v?Ù·èý ¿LÒ°ƒKØòÒç–˜¯è ­î ÙV×Ùùÿú1hYa)Ê@Kˆ³ë»®–UÂÝSé{Cr²ôs¾uãµ´8éÿ VBϰmªˆûMçeðŸs¿à±™úkõ"&p·¸Øxï»”º²öÁsvúa›™-sŸ×[üßé=oæýéËËÇy}Ì*8Ƽ'Ž^£ÿ9B²ëè¶ãxÈ®ë ÿ8,†ïß¶ÌŠvØÃ[¿Ew³ù¯N¯ ‰Šw}¦Ñ¨»*ç4ÿ%„b7ÿm‘LtÌ'دu,iû­££Ôî{ì¹õÔÝï·ÙþG³cÕ;½x¸Ò?ûvoz²¼”'ôc_áKÿEG—•öPÇÝ`~ð'{Fêª c^íÙý_üÝž¡Õ.¾ŒVº‡zw:Æ0‚ÞeÏadÿ'éäÕ\úêÌê¸øÎg©è—ìpÜã¾çYúOж´Ú{=_WùÚ?D‹Ôîê8Xö5Ž©Î7Íq2ÏsÿI·c=¬vÍ–³þô_¢¸–ħ"2yŒpéê>™ÎtšªÛpŠÛû5ŸøÓÌ{½·g×ý¥ÿP¹Ü»·Þ>•u½íópiôÿγjôŸØ£þkþÁݧØ~ÿþ³ömèKpÁÎKõÜ´¯Åÿ:ÿÿÕèþ²ãý—ë n úž7iþ{Û¿7uØ™_æ`¬Lîš/ËÇˤVËXñö—ʆßcö7}ÎkY²–¹ÌÙþ“ô~§Ö¾ŸvoIu˜­/ÌÁ{rñX&^êýLý Å~F'ý}sY]õ²Úú­h²·x±Ã{þaXß„±æc¶A¯÷£é—üÞ7‰†Q~˜üG¥f%™âßUÞ…˜¶ï.Ø\Â6ÙO¸í¯Ôo·Õúh×ßF=.¿"ÆÓK>•0Ñàßå;÷Xßzª3Ý“íénCf–òF3~;ÏÒgXÇæñ?Eþ“.¥WÔ«ª×öÿÒÚ@mY÷¡®{xçgرi{ÛöoÑd~ÐõžõqÿXTÄ$t—èƒè=5„ Ò_¢>_ÓeeöW˜sÝC±ð. ¢ûn"·îkœÜL×ãmõ(Çý'Ùl³!ì»Óº›,Ǫ¼tÝOûëΡûf)^vXÝëÌW}¾Ês~ÏS?Jû}KjÉû=-W5®k™cCÚàZö›½ßàžúè­ÿ®ÿ=K*±›Õ02›v'P¨RÖ Ö7$KÃ}1ê·Ö÷RýÙlªý™5úôÿ…Vá*ù}QýßÒƒ©ðߊæäcî )à'ÕûЗèµRW,èmv.EÔ7³E`'ÖÛ‘ÿ³jø}B¬šqÆF;½jí³y¦Á‘¥»v} ý?´~ÿæ)a(̈ÄúBôœ¿üaäsÇ ’ý Cü/šPR–íx¥7d¸K1ÙÈã{÷{i§÷¯»ôh®ÀsXëró^*`.¢ÁCCZ78ºÏÖrí»+Qûn¬ ¶ç–׎Cêu–ŽÙ‘nC}oYõÚßA÷úž«ì§ý*±ôxL߈c‰¿ÞŸýÌ#ó'ª†aUffQÜý¿¦¶¶¹Á•ƒüÆ;c{™¿é»éä[úK6~ÓN997¿©X÷WMŒÓC]¾§7é šÝìs?–ÇUêúþ·é?í; ΟfNc³2Àkæ¦í6×YöºŸ»Òýèmÿ‘êâe~‡ÒV2òŸ[¾Ç†Z2Ã[.‰f;ö[c>«·ú'øOç,ý[ùË1Ôb<ƒ™)JDÎdï~2(srü¦WUFú°žÖnÛúê~Žçâ1þ½µzµ~šÊ?ÂÕé£S}9 /¥ûÃ׈-sOî[SöÙSÿã­âtì|.’쌬{×µŸdÞømŒ±Íu·3.¿Sü¥üí먒ٿ["Ÿ[Ñ¥‰Ó,êOÞ–mΆå ]5–Ù”÷mþy¯ôuã[ú/º¯ð~¢±,1'‹åùèÈÿU~lâ» ³ßü¾ÍEw?,ÂÙ.k\æ^Ú©w­s+ÛÿžÿœU:c™•—“ÔY¯ ¬0ⱎ÷YKM®ô][ÓSg«O³ü/AÕúVèÅÖd³í8M×íøí'k@Ü]›ˆÝöãíçèõñ¿Ò}‘Pì!í³Ü×´‚?œ×7Úÿë(4-ÜsÇ—†Xä bxŒkÕÆzɱÓ0ÎWéø Kl½·]¤GŒ»7ÿ&ËÙ‹ÿ¡ Ô—õ§‡¿+­³=WÓÉôÔ1lÏŶæf²:uM}£,Ù¸ÔÆ Í£ßúÆc[H÷dXÏSÖõ)ý/¥½ DHôÌ|Ð:z¿©ÿz¢,’=2ÇúßÕb󕇒Ìj[gQ©í}¢ Aɦ¦mgÓµÌnu£ýYsÙÿ —é§#¦õf?Á™[õip-¹› sE´»Ò˧k÷}&ìRÈ¡´Ùx¶Œ®­ÆXÚØ-ºªÅvÙ…Ó±ë¿õve9Úûr¿U£#';"ïæëS¾Š²2êÂêXÖäo­ïƳ2ºEí5ú_¢£;¥Yèdzž¥c1þË—G¡újí®ÏQhÃý¯pþÍ!½ÿ/ë6H—«ûÜ-VtlZ²Ù•SœÇ6ï]ì1µÎÛ{?3ÒÛý+þôuUüÒ|ÏùKÿ åÕa-7ý[Í­Ö6ŒŒÊ½"ö+ÉkKƒ^ g×}ßFÆÿ†X]RŒús°¶gz޲œ×;¡;pÚÇ1Žßì÷)¹hN\Æ0M@CòÉ›”„Ç3ŽR7\_ÞùdÛpkšZà××4ðC†×4ÿYª¿§ƒÓikîx©£‹òºÂv¶¯m¶îµîôke^àÙ³ÓUÆ?V·Ù®~{ð7?2šk¢íõk¬e?¿“Fúv~“ÕôÕÜ^ˆÊkÍûE4ääµÏ¬Ú\ë6×gÙï6åÞç=›]û®ôÿë~§§­7©”jëO^¿à»>à;/ñZ–fä]íÆ­'&Öiÿi±¬þkwýÈËÿ­ã-«ßSîê½.ÌÜl‘‡SŸhÆa`´Ûki»'>ÛfݶÛUµþ‹ÓÉÙú__þÓÖÆî™Ó¨k°œÌì²÷°ºÀ@ôþÐÚËú ~u9ߤÿØ•›‡Õ:§KvCú5卑õ».üF:×¶ªßž.mŸcõ^vÛö{jͶ¿Òþ“ùõ$áÁŒœgƒ]e/L¥àædF†˜Vì¬èØìçÑFP[½Ç+Ž;šÈe¾µÖ~ŠšÿX³eJÿ^ú­“Ññp¯Ïµ¹mÉqnIh ¯'éâý’ÏfCi{=\_Z×úÏÈô?šûO¢µ0.=#®þÖÊuv»¨ZÜ~£w£]^Ÿªí”[C™ÕCr¾ÏÌ‹r_e~ŽE×z˜ËSë7U¢Þ‰‚湤ìêYZöÖߤì*›kl©ù··÷™gØéý=¿¥û5vG.fdÇACæïþõªPÊ2G¨ë_½o5õ{¨uâü°õK>-‚¶c\FX6´7í·¬~Ý^#YéÕUUæWú^êÿÑÙnìNÔ®Ùi?Vz¶S¶úµE˜Y6<Æê\öÕOÛœÖþ{0z‡¬ÿûWS¾šÏªŽé·`ýa§«ºH,fE¬®›+©‰•mL¡õ»ôž…¿dÿµõ]þ‘SÂÌO³äî·©¶œ®¹øÆÇ· æRï§k±½_ÔgóßÎþŸÔP“r$G£. ÈÆ áËŽýq:oò—¾ÃÃÇÁħ žž>3UL’a¬7;ÜïhF\·Ô¶æN[ª½î赇M„ÙÔK2Ý‹uŸ¥û nÛ‹]O¶ÿÓÓ‘èz4z~§R›M_o×íØß‚ÿEÿ×õT’I8ßXºíJÙ‘‹`ÇêxÀýš÷ cšu³-÷Y‰vßøÊlýbŸÒV¹zì³{ê¾§ceÑ#æ\Â~‹Úñí»ÈýM£·þïR¦z Íë] «ÔÁkFM».¨ÖOÓhÜË)·ü>=Ͳ‹¿sÙZ«Íò‘Î,zr ¥ÿs6c—ŽaÚciÜÉâk鸵æ;2°[kÉu‚IyklvâïæÙcÙ]LÙWý·O¦<ÐrïfÛsCšñ¹Ž´Z–Úߣm85Ý_7ÿÏú]; þôUìÜn­Ó­ô2°Ý‘mŽ-ij®4ÞïðU¼þ‘Ý6Û7~“í«UúK+Ì»ÒzCn8{Üne_I¶²ÝÌ{ñì麛tö~Ð˯ô;?˜éؽŸð*·!Éd—1ŘÅUÅúGôxOõZPÅ8HÏ 7 !zÜ¿Gü!³¥u,kñU¼¶Œªnci{>Êöä:ÌL×;7¥ìöÖ2žŸ•ƒ¿ùºqÿšE»'&þ­cÙ‘n7Iqª«1›ê¼dZßÓdßCÎulm Â{1_]›ò2}_})ëÁêý.G¥œlœv3ÛE¬ôž^ÚÜßUÏ©í­ößs(õþ}öÿ8™ù=?;*Œ~§Òî«-î5cÝe\Hg¥ŸI¯&ÿI›?Gÿ þlÏ L%pã:ÿè̼`›EÃÑ/ïp§¯©µÍq£}VÜQ¨ì›êÌm6TßI¿£²æÅ.­çôË2ðvåãÙX§)¯-º²!ÇmsÚÿnöµûU¾£SGTêVÜêqë¯Ò¶ë’_oO¹ù—]KóÝêØÏõqª©Îû>NG¯fÏô¸uì ­Ë=C8_½¹bê[/¢ÖY‹‹gçþr©Ëâöó‚\~Ī¿½™— ŒrÆVw<1?Ýý' §õvu\L.›–Y‘ÒØ1nuNÝc¬ôëè÷g6·º¿ÒW—ˆú2?Wû¥ÿr±6BY¿¢`RÚ±ßkæSEV¼Ü×½ÛÏèeÑê7ß¡ê=Šå9™™½O«e:¾¥Š ØÌ¯µšß[Nfï³àú¸ø•²ßÒä>ÚýSùõ üï«6ZN[Û{šÐËMa ,ÛVK+w¥‘éý«}mÈõ¿ÃÂ(þõÁÌ ¸Äö”x?Dy:ðÄF2 ‰zÔœrqqzÏìî²íõbÞ*ϯö;sl­¯«ÓÈ®ºnnÛ-ôïÇýNG§mXÞ«ÿV»¥¯«Y“ÓË~¯ãá×Ñh{ØÎ[aËc\ædQçщöìgz´Uèßu·ìŒFëiY}C!÷ôK*ÂÁ~>6F3Ãn`¦£[.m·]éb‹_UT:¿W#ô>«)ý*»‰GIÆwN£¤f¡“SloUÊǃŽjp¿"†¾Æï§ÖÇͲªz}LµùaúÿàT¹y©æÄrX„ñšáù¸£%þ ¦°ãä#+Ÿ­=;þ’6·ü€þ‘ë~À};6f9Ö2íãec£7v]íúûE¾–GóTaú¬ª¯µ÷—tŽŒÖcãS ¿&¿cjk‹ýjñšÀÝ·þuW·ÔeÖzÿÍ[W¨•‚Æç7Ï}4ßcó0l¯oèò6¼u _Ó¶ê¿M]ögc~‹ô®z?ÑÔ®¾¬ o²tÚ[¾§²¦ÒÑìc­»óSn½Õ1öýŸí­»èõ,«×õ˜æ'ÈlGò Ìqá…j:JDñN_Ôƒ+kÂé˜t ñ…Å$b´€\׺ë=^×ú7Ù]vú;6z·~¯ú4>‘Òòú¯PuV<³¨ÚÉËɨAÂijùº1ÜẬÜêØßF«}Kq?O—ÿ‘,LÞ¡ÔK1Yêu;¯½ƒÓéøïs/®œ–T÷Q•œÇ±·cQ»íÿ¤[F/ó½çIé8}# bbAq²ëžw[m®þw'"Ïð—[ÿ¨ëôꮺӉ`æy€=0Ó¥ÐÿÐÛØôbãÕ‹ŽÁ]1µÕXá¬hØÆê´"¤’kAÿÐõT’I)$’IM^©Ó©ê;'§^÷×N]nªÇTí¯ pÚ펇Ô®;ªý^ê¸äÝk憆uNš6ä±­ géú[±ÿ£«Õé–zÞ—«]tz÷zÚH‰²ÙÀK~œbuN¨l}u6¾µUaζÌx§&¶·vöe`¼Têò}Íe8ÿffÿFÏÏV›õ‹ší¶ú²q~ÍWÚ,mµ ±¸Þ›¿u–}¤ú5îe^¦Å×õ‰Òz oÄ®÷°Ev¹±k5Ýú†m¾ŸúÕŒY¶ýT{dàõLª@!Ì«#fem îæ²ÌߤÝßÓT£1þZµåÊö£ÿ7þùä*éÝ6ÊK°‚Ú sì¦Û]Õ½®s÷äôÿQ¸_"‰ý[íøÔ_ú:}{2VçOe5õ®ƒV;·SK2k¬îÜv²Š*f÷~þÁïPÎú‹Ÿ}‚ç“föØ÷ nÄuŽnã¶û*¿7Ô­Î~뱞¯ç«]êÇQÁêx¹ÆÂÃÅÆ7½íźÛ\û.eTnÙ~=;=´{ßê¦ÜjT¿5цN8Y¿Ýìãô|\lž…Ò}z›i«‡W¼NÓé´iýoÎJ®«Ðñr¨Á  ,ºß³VI­¡Ísñ›ïsjý¬Ûq«¶¿Qž§«ZÒÁú¯õ›]€S)m…·¼Á±¯s”{·÷Ѫú—š-6?;özÖ;Œ°Ød:ï[6î¡ú_s¿Ié,ÁÊä$ñ /OS®y¬`úú\JzænCwQÒ²‹Ý>Žâ í6V÷^önô×Òïëÿì?®Ý7ªgåZ}w«žÀYÒñk6äR\gõÛ[¶Œ7û½'³2Úü×óvúÞ¯U_ÔÞ”ísìÈêfwmË´šôìì,³à¿ûx«g–ãâÔÊ(fŒª¦†1£ù,`kZ¥'Ò¡ýÝçOþõŠ\Ü¿Fôýïûؼ_PèXrp>ÛeuÑöK+ʯ§Uúl‹=' ÇfG¥FCªõk®Œ:Ÿê?ô/Î}XŸ êî_WÉûa¤ôÜrÃ_Û^ÀÌë?G·‚ì ]îýc'õÏôXØÿÏ®á%fŒ#ÃAïjC‹æ6Oé}ø8?˜˜U h¬CXßôž÷:_ew¾Ëlý%¯÷ج$’,*I$’SÿÙ8BIM!SAdobe PhotoshopAdobe Photoshop CS8BIMÿá8http://ns.adobe.com/xap/1.0/ 1 295 300 1 150/1 150/1 2 2007-07-13T13:02:02+02:00 2007-07-13T13:02:02+02:00 2007-07-13T13:02:02+02:00 Adobe Photoshop CS Macintosh uuid:d747b9af-32d2-11dc-84a7-c4efaea405a2 adobe:docid:photoshop:60020505-1ffd-11db-9d58-ef56d46c77e0 adobe:docid:photoshop:7582ff4d-32d3-11dc-84a7-c4efaea405a2 image/jpeg ÿâ XICC_PROFILE HLinomntrRGB XYZ Î 1acspMSFTIEC sRGBöÖÓ-HP cprtP3desc„lwtptðbkptrXYZgXYZ,bXYZ@dmndTpdmddĈvuedL†viewÔ$lumiømeas $tech0 rTRC< gTRC< bTRC< textCopyright (c) 1998 Hewlett-Packard CompanydescsRGB IEC61966-2.1sRGB IEC61966-2.1XYZ óQÌXYZ XYZ o¢8õXYZ b™·…ÚXYZ $ „¶ÏdescIEC http://www.iec.chIEC http://www.iec.chdesc.IEC 61966-2.1 Default RGB colour space - sRGB.IEC 61966-2.1 Default RGB colour space - sRGBdesc,Reference Viewing Condition in IEC61966-2.1,Reference Viewing Condition in IEC61966-2.1view¤þ_.ÏíÌ \žXYZ L VPWçmeassig CRT curv #(-27;@EJOTY^chmrw|†‹•šŸ¤©®²·¼ÁÆËÐÕÛàåëðöû %+28>ELRY`gnu|ƒ‹’š¡©±¹ÁÉÑÙáéòú &/8AKT]gqz„Ž˜¢¬¶ÁËÕàëõ !-8COZfr~Š–¢®ºÇÓàìù -;HUcq~Œš¨¶ÄÓáðþ +:IXgw†–¦µÅÕåö'7HYj{Œ¯ÀÑãõ+=Oat†™¬¿Òåø 2FZn‚–ª¾Òçû  % : O d y ¤ º Ï å û  ' = T j ˜ ® Å Ü ó " 9 Q i € ˜ ° È á ù  * C \ u Ž § À Ù ó & @ Z t Ž © Ã Þ ø.Id›¶Òî %A^z–³Ïì &Ca~›¹×õ1OmŒªÉè&Ed„£Ãã#Ccƒ¤Åå'Ij‹­Îð4Vx›½à&Il²ÖúAe‰®Ò÷@eНÕú Ek‘·Ý*QwžÅì;cвÚ*R{£ÌõGp™Ãì@j”¾é>i”¿ê  A l ˜ Ä ð!!H!u!¡!Î!û"'"U"‚"¯"Ý# #8#f#”#Â#ð$$M$|$«$Ú% %8%h%—%Ç%÷&'&W&‡&·&è''I'z'«'Ü( (?(q(¢(Ô))8)k))Ð**5*h*›*Ï++6+i++Ñ,,9,n,¢,×- -A-v-«-á..L.‚.·.î/$/Z/‘/Ç/þ050l0¤0Û11J1‚1º1ò2*2c2›2Ô3 3F33¸3ñ4+4e4ž4Ø55M5‡5Â5ý676r6®6é7$7`7œ7×88P8Œ8È99B99¼9ù:6:t:²:ï;-;k;ª;è<' >`> >à?!?a?¢?â@#@d@¦@çA)AjA¬AîB0BrBµB÷C:C}CÀDDGDŠDÎEEUEšEÞF"FgF«FðG5G{GÀHHKH‘H×IIcI©IðJ7J}JÄK KSKšKâL*LrLºMMJM“MÜN%NnN·OOIO“OÝP'PqP»QQPQ›QæR1R|RÇSS_SªSöTBTTÛU(UuUÂVV\V©V÷WDW’WàX/X}XËYYiY¸ZZVZ¦Zõ[E[•[å\5\†\Ö]']x]É^^l^½__a_³``W`ª`üaOa¢aõbIbœbðcCc—cëd@d”dée=e’eçf=f’fèg=g“géh?h–hìiCišiñjHjŸj÷kOk§kÿlWl¯mm`m¹nnknÄooxoÑp+p†pàq:q•qðrKr¦ss]s¸ttptÌu(u…uáv>v›vøwVw³xxnxÌy*y‰yçzFz¥{{c{Â|!||á}A}¡~~b~Â#„å€G€¨ kÍ‚0‚’‚ôƒWƒº„„€„ã…G…«††r†×‡;‡ŸˆˆiˆÎ‰3‰™‰þŠdŠÊ‹0‹–‹üŒcŒÊ1˜ÿŽfŽÎ6žnÖ‘?‘¨’’z’ã“M“¶” ”Š”ô•_•É–4–Ÿ— —u—à˜L˜¸™$™™üšhšÕ›B›¯œœ‰œ÷dÒž@ž®ŸŸ‹Ÿú i Ø¡G¡¶¢&¢–££v£æ¤V¤Ç¥8¥©¦¦‹¦ý§n§à¨R¨Ä©7©©ªª««u«é¬\¬Ð­D­¸®-®¡¯¯‹°°u°ê±`±Ö²K²Â³8³®´%´œµµŠ¶¶y¶ð·h·à¸Y¸Ñ¹J¹Âº;ºµ».»§¼!¼›½½¾ ¾„¾ÿ¿z¿õÀpÀìÁgÁãÂ_ÂÛÃXÃÔÄQÄÎÅKÅÈÆFÆÃÇAÇ¿È=ȼÉ:ɹÊ8Ê·Ë6˶Ì5̵Í5͵Î6ζÏ7ϸÐ9кÑ<ѾÒ?ÒÁÓDÓÆÔIÔËÕNÕÑÖUÖØ×\×àØdØèÙlÙñÚvÚûÛ€ÜÜŠÝÝ–ÞÞ¢ß)߯à6à½áDáÌâSâÛãcãëäsäü儿 æ–çç©è2è¼éFéÐê[êåëpëûì†ííœî(î´ï@ïÌðXðåñrñÿòŒóó§ô4ôÂõPõÞömöû÷Šøø¨ù8ùÇúWúçûwüü˜ý)ýºþKþÜÿmÿÿÿî!Adobed@ÿÛ„      ÿÂ,'ÿÄ    !10 @A24"PB3$%7#56 !1AQ"aq2#BR3 ‘0¡Ñbr‚ÒCS“$4´7@±’cD„”%•&vP¢sƒ³Ótu'ÁÂâTEµ6fg !1AQ"aq2‘¡±BR ðÁÑbr‚’#0²3@á¢CSs4ñÂÒc$P³â“ÿÚ ÷ïÀ"’ê2¯ïGQõ©¯zÁˆô²Xƒ½ä…BlóŒ©^H­^VÏA^ж Ü-U“žûgÇw€ä#nK¾S»Ou yØx,l¥\—3ü“Yß =+¡fó»8LŒõRr…®ÖR¦g‘lüCMñlÿÑCJ8¯ð¬¥’ê©ÆXo£d®aàV-ŸP•56²þl.¸Öð  Ò®<9zï;Ë}Ví¹ó|`໹L‚¼âÂHmÅñ «0"ÜÓ-Ï_|؃{ÓèMZ`vsU=D„s¾ïÑ’½:ºSÞð\yíÄ×´yZ‘‡}~.$ Úiä ðä‰0ý“ö&å.WèZyçPºuþÓ‘jÞ‚~ï­È׫T_sȶ»úræI&4—›¹¸7v/À{KðWO9ö›•*E£ž€R;Z,<³îÀ˜û_¤gÔî¦! H*%Éní×^•ÊM¾Í­8>4!žj—ð²G8 h·ŽÜóùO¨ù»¿6Óè&îõøhCÏ|EÅ¢ÊÔRJžÁË©QêÂKŽ˜ŽùówV6ÆùQl®þ¹Øû”,eVÁ t†áº°É˜Jxµ^LÍÎÍ» r×O<¢úMqéZ‘fC¼…^3å¤ôM¿gË›ô#v7®œYʶg^³ØHòü~Bv“Ûù|)}’·+\ëŠîËt[ËGkWæ#÷xÎÖëU@;O%¢lì‘ê>à é¯ÌlÛÃÛ:#ªQ¢WÚÏÉö‹›à?°Ö$ý&×Ðì •ëçå×0—E|.}K¾{ÞyèM´BéËûHîƒÇó«u¢6ZYvi¬¿}6g#—ãØjARêµ÷‰å¾zJIY6¶ô>Õ‹¤4É‚Í(wIm+3¹õd³þ„ozl¾ 3¾ãÔ'Õ&Ópksù#k›ÄJ³dã ˆæ‰ïšš‡“ç_Ú¦²ŠR #3\tDXSÒ°§‘ï(["†VÎ×n,˜ù}ÍÕ¨1ë>¶8VÌ»“ž©HôZíÍÏçÔ¶š÷vƒ Pv«·è_Ö?7óþ1óF²Áu³ñú]¨¯IpFœ]húÌñ–ŸyY,Tùã)+lÕ(‚ÎF'¿ž™Ò½üõTlô"Í­ýRù#AÚ)í6sXgxÚmoè/+ñaú2veq¶}¶qx/¬IT€Åìg2—æt@9q˜ÐnD„èŠså^•¤IÛl ™8Jù=W¹5+òBz)eb“ê{93JsŽr´KF…r6{½a±ÓŸvvô\ê1Å&ÇÐÞ*gcQ; L_Hœœû”‹ødä^ÃmNýÇáY€ñÏ6~^Á6I'zå“Ã×s“𾓒I\5Ö°%mž¡¦«.©êŸxe$}¡eq`0½7ÑGg¶Þ&¥”ƒtDX"NXÕ»®w>Ôn[÷/j<úß¼ÐiË,òì>ÒqùãÓ¨š/yÉVTüíŠ×‹4îÉõ++,fÙ½ ÓëÕjÓ¬=êÎèQúÛ¬S‹ìdÉæÀ„I†kq¨’è{u/U¦Ñ4²^˜o5ÿ£°ïÚî"¿N%æ½£?ªÙ(ìSØ6ô?$2ÚÆ?šQûõÂßRªõnÝc|×aY±QÈK<ÛÀϳ†7}R{GÐó7ßi¥^Ñ›ìî{O.À/^Øùs+J`‚°²ô¦°½7^N|íilÑy}õ…Ï)%t‚ÖNƒÅmkM}¸µ.Òˆq/b۳νþeŽø¥‡eSÌú™[-3öµ Iï–ëÍŸÓ@®WËqÌm@±ZPÕš×÷Dß›UA—Æ2¸´)x)’Pî®ùËâ²$¤³8â>¤máƒÞ—ó}¢¶å¼~ØÎt *ëJE‚slG¡Y²n+öõÒ|váoÏ8Óš§\JÎ˺ ¢8;Z´« cW'¬Oh˜t·õ wáüx‚°ŒöM——:lòü­é?“™¾WÖ{k2Fn*¬CrýólŸ«<|Äwª^[T^®-a­Ü;¿À|Eû›óg’_:bô7>CŽ÷€»i“ó_ SrR»ß‘yïÒ߃ŸAV%2[!¦ë=µÍò¾£Û$ÛÚV/Qb¶³6Ú\€ûçq/ÿ+/ˆû´ŠÛŽ'O5Þ8"«9–±ÃcU ëieEGõw»ü9à¢5ª©_´Ùéw†ÕþZjÕÀ×)]Ïíɧ¯ øC€[¹«Ï[س8· ¹È-Ÿ;Zxk.ö²ëϹ³Ý‡¼ö™F¹ötá¶ô»5Y·ü~5ì³lö°%â…ü·€ìSð’ž—lÃFDºiÄFÄÞ:ª7Û-¦ñ_FJLc÷Ó]Œ}J¶ý­2õôS™%Š´fªÄÚkÅdi«þXt5‰§˜kôÌoân!•°sÊXc{ô„±MÊ™¶jDFÕý*ÈöB´MÏî’IåY,[rö_ê)§+/Š…Ô`²y-ƒ1}ÉÄV´c;‚ʯ'Xä"\z…%¾j·S[ηˆÂÓŽe+3B­ú'Àw€œu¸UOÎ8—'³²úµ”„¿ykiõ®ï>aï¦ô whºõ18¯}!k k’d§d§ò=&—ºÌ1”úõ§ç„*Qó¯KØU¤P#¤z KŸÖ¥ØoêQ—6œæ…¾×¤ ÙÀ²Q¸°hR>wÂlK, !P1;Öè«eäk-®Ãzsêoß9~í~šx¡¦QZ¯=bù:Îc1lÎ1·ý]%ê‰Øè|¤ìQöóÒ•¥ôV¾êÚǯë?‚G¤ª­Ï¬ÇX(VÕQÅÚš¹¾þcð¦Ñä P‘uçæÜ?b’u¢Õ`uÀΦ$¾;Û Z‚à1ýz¥šÕé‘â%ÇÀj”VáÄcoúºKÕ8˜®íLfR©û½˜×<‹·J§-2>ÄeõÏ/mÒª‡S·†‰¥ÉÒͯšE„ïÆü¶… ÇóL§wkM®§Ö—2oÖ’²‚§]€ÊÈ|i7{÷Ѷ1Øè±èðÞáhn»ô>Õ×ur i&QbÏ©f¢Û-|òÃÔ"ûb;'÷çÔæì¨g]V?nɾD«¬à ?ʽ" Ü<Áò9õ§væ¦\¬×2TÒ®ªŽjSêÛ=•w°Ù]:ç”4»­»¥nrlÞš}e¹XZ¬jÊaÕÕh”eqeýÖ¹‡_ËP×w BzHžSçb»!È›áã/óåM«îɹGõ•p(§æ6ÏjU¸ó—öÉ9i*UµMÞÙÛtœ¤¡îv—L«8„å‘…ó‡ãÂ3…ú‹köÃ+‚¨y†¥VvÊïÆœ×[¨yÅ ¦…ãúóïJçÔÄ3v¬O«Zuæùí/œÏl…A?2p¬š}Iª®UD'ÓºýÉÑiJ8ùW{\òË‘ ”’­CjΪœu½Ã4µ…ê§cl5?#Z-b=Ã5Êù©Q¥ö Iâ:YéËÓÜÕgJ»"úßç%s €-¸y[”çÛüŸ;Li×ÇïÑœP§ïqßwlu\÷ZágwÒÖƒEpɆµ'©Wx”,ÞTL¾bjvs´é<—ÐüºY{K¿,6,¿ØõHG–XÜŒôïÆGdàÖ{×!ª5¢6Ie¯Y¹¨¢k YHl{Ľ þ5][ñ¹ÖÔ]ƒ7ÚÐÒ‘X]óÇFÛ µÚ‹…`eTíµCLœÛæRž!§õ;Î^ÿÌGеÒV¯àÎrÕæî>D¢H(|aŒ½šµgiÚ.ÀÇÃwn;Ìß>£ #pÝLù„é³™ Õ ú’ÞµkXéf^ ò‰>8+¾…¨ï!Çqy=ä?i¸Ý2Ϩj,,7vÕ¨Ÿžöª“Ú6SOí?¹¸+—5 r§àå*ã›ÃÖÀÓ‚IÔtQÔj©ïWfÚ‚º,i7²¨ïß2—ÉÅX ÷—xÿÚýC®Bû´[Lw´‘ q²ßŸ½K"í’‹= é—RkYg› Ù”Å¶Ó äK¬ItÕ/ðÂ=²^ÆÆ,²Û9uqü»ÇãÔ((Â~´º ‹>À¨Y\24RŒkíMx·Ñ Æì—Í n•ÀÿÁÊL5ŒJáv~šÇ9ŽlŽYò­*Ê(PmÌ 3ÙWóåtÊûù°ÿÈ$åd…µ¶]¾ÅEp Ýâ É `EØ¿­ç‹¶ËÃd-œ±?€´ßQŽò*×ÿ)‚f`“Û!}7ž˜ŒW9Âð‹ÅO Y ¿þæ"¢ª3m"¢ˆ¨Undmʬ É *ÕùßÅ­5}ˆEÄ ¨cBÝ~3ŽZ*éDqî}’i¨R †"')¸]² gf“~º–C'³®Ü¸„0}ÂlCî‹¥Q;+¼‚ 3¶&àÖ©ž>ÊËtÑ­Dгxú)´¡k–—°XÙÊnSý#˜K¡¤M‘Ñ ¾#©ÐÄ]‹žåx˜ Ô0åè°‚zø>ÌÁ¶6$yïW# RhŠÄ¡Ûšm0~ÆãXfã$«ÏãC6QʶG £Ø¬Åh‰·‡n ¨T„é«vG5×-\¦å?Ñ¿[…Á²:4]d´ºm’J8R^ñç EÌqfÉïã£ðП¹`Í“t—`ݳ PxÊ©g1ØÆË3cPƒQÅ=ÓpFZE‰"Db¯4MALìlîäSœ`ýlAwQN“P’$R-9–”»Y¢V!€Áñß­#ŽG×Uv”‘Ô‹\LÞ³§J9S _¦Ýi 1pk3£6N»*ÿ­G¥„ežÇ†Ç›Ê!\R²Á\RV8P°@‘‰Èµdà ¼3I€U3&h R޲@e¾Y’èºn¡dZ’awi|s2©F4~ùWËÄC«$e$›Ç²Us.R@´UU;–ñdSÇË ïØ á»Uc¬lkéÑNA!º¢ºˆ™u›?É(¹š±³™Â’õá*g23ÅxÍfkUeÌ°Ø šÆ’YHÇmjîTíÑwUŸ,Ã/†ãh!Ý«_Mà$ªÍUp¹×R=ñ™ªåÀ®¤B¬›#5" ³e\ªÆ1´>,±Ö>7ˆ]EŠD‰rD޲€ %ß5§6TNÑR°sª#Ü(ÞÅ·˜ÆÒ¯#T‘­ÓeœIDΉâæ¼zZ®ä®‚¹¬»PMcÛ€÷ø,2ÁÄÆ L%»¢øW•I>­ZªéTJ!,bÄîÎtÐE³æTÇPÇZ,¶ ðÐË‹6UI‰™œÉL 2Eø:nfêã†ȩ́ìÑëÍÄy'.€L´Êƽ‘›Õ:½OÀývL§ª¿VoVf¡Õ”É8W1ãŒ}™¾;bVå{$ƒrCYW•T²hÛ áSB¸T áƒG8ú¾² I'$ƯHñ1‚QÉ6xng˘µF ¼„ÖqË$r÷PÂPDýÇÈ8²oŒùÓ6Âågðʳ!J'R:FÈùw ‚"=â\Šâ3Ф"‹©› 0‰‡â)„£!›ì9 ™(%kŒ½oY®·jéãFH³LÀü@ ÷)°C¾ |G.o½¤^VL²jÙÓZHž´ó±]Ɔ8¸@­Mø‰‡€@@c#Â=0Ò–Ž÷éäEEÃ¼ŽˆlÀ‚>#ÐÝŠ ÈCù‡~Øä½›9×dr¸ÙûQz .+*ûvóR~ã*MÀïÂaÀc °DDRb')ÃÄÝ󾮟¤§|ï„KÈð¦ŒDK!8n‚Áw.wÄØÆ0!ÇòÍ¿œŽ5›l’i(<’ÆB7¤^Œf4\ÚEÈ8\ˆûtGòT‰¢_$Ê@\UºPÂs:$"i·€ÆGÀŠ”K!—ðWª#ØýÂSœ@/‘±ÐwO¾]Ôó—ꥑê¨ôH¾œzóRpéˆF  9Pþg¹X ÍT“Xþ`s}uYÛ;g`ê™<Î@ì ˆD@>géê¶yÔÅ?§þ]ŒßÓ’'’ì£NÁ"jÏ‘šºB+ëEcD ù”EP\#S)Ìì‡ñ4j  2QB"Øé¨”z‡)(c.ÜÈH„E°C¸€÷ă¹ú@Év1ÈöO¶læ¿éÊÚÊ%•:§Œ0¼‹éQ_»Œoî\cØ“µN ǘtb¹ €a^'î )¬Šë‘'pA)_Ôx¿¨=#ú ý„…î=ûbظ©¼J™ æ ˜ýúròËÜÅeef K R‘Ô‚ìjù<Ä: <1Æn…²§ne›”ÂQAÑ^§ð&ñdÊaÁÀL?LÂR€ƒË;v詾hýD¾%ÇFî|]¬›Ö†hº*ŠGž”AáXº3Eæ%Ï$|cáò‘Ù4Ä29É@îA³•¨ÙtÞô#âDâR@çÄÈ#ÛŒr)Àn‚8"‡¨n†7‘ºlX¿n÷ªi™C: ôÚ®!Ä‚‹²Ê7Æ’jˆ¿€‡ yŸ ,(ô( …µÕÆ‘i¡ŸL0‰üò.8_*uÒDÏáÐu.ÌpÅSì8àþ$íÖ×÷6ASRpJÆÐ1 AÈé˜.‹´q¬ª e¤øî¹€D)—iƒ9µ”X‘èÀ\L#„OåŒÙ¨ñDˆÞ9[îRH%¢O°&©“Äœý\ŸÈÿ¢ ¹d=ãÌtígjd3ôÚ-b` 9$¼zÍBP¸šÇOÌÍ$š.I袔÷%úaÃæ ÷”#ã|dÎÎ4[ƒ¤±M©È Ì$ S3èM ÜpbaÜÃá°ÃUšè2’NHùŸ´RI pú9W&èC˜†`otÉx•ˆ^†Tç,÷%úuE%3ÐK¼ö T0œÕWÂI’o¨éZ£ÐY_„ 8$Àì?þ´*—XéÈ'8Ýë_j´DÀ4 ‘|g Ôn¥~,$d4#Ö¢w¥TE«%3í>XÊ!r®BA6.”ÄkÏÆõ” ‰¤šVTS@®¼@SQTtñgJaNbeÕXÝÄ0¦ò Ü¿€.uaŒW½UšÉ¤Y¶Ê¢t…«Ã· Y´6dÇíŒê z¸xQíeft^-d̼aÒ+ ÿ¸Eb¤ÙŸ{ÃMƒü2.)휺3(õTç„¥ ¤0œT—|!{bð¡âaî?†É¸NÓVR\fà¨*îtŽ“Ê4¿vþ%7®Æ9ÙŽ-š[Ý>FAdð®Ì ±þáãc9Žr· ’ÖgÊYN­ Ô*a+!웽‘pìW|‚ÂË ca Û;`ž{è9l›”í4åbÇ¢u*•ò³@åL@bó™)Ì’õÖªcªÒ‰£ hWi¬Ú}‰°*ÉÙ¦áŒÁJ3ÅZ3Yc,#{nÖ~)dPrEH¤¿oò.ØRvϦÏ@€úF(,´!Q3&mwæx澂k b‰$º.©Uhй%؈TCÔ\ÐʆwÃs dµŒÏÒi&å 8~áÆ3LN¼¼‚ei"­ ä…‹,öÁØ=ÄD@¸ú³Õ†’Ä­E•$Û¼ò6(‰‡íÐU3Ý^¸W+%TŽü¼‹üš"Uœ+×P¦AxÑ y$g !mj)ÍÙ=âyS”õÑ0öÀ"&Îß®ÑùÛN‹’€.Ø~Sbj‘@ÇÑF1ÒŒXæ(ý õ1„È7Qs9r™¼I„² ¶.1ˆró!ëɰ7|÷Àà‘Y,MãS‰¢ ™©Á:­L¤‰ƒwêò7Õ()ê¶n²’ ¦é«·Ë⯜"ʴѶ@:vþ·lMâäÂË®I"”ßy/oåøaDILG©²&!Ñ€ÄÿÿÚýPLG,Ã<¡‹ÛÄ£‚™pRÁLpC·ñAÀ0áñÆ€àç|¢8RQùg|ùŽvÀ3}Ð2D6+ÑLZ²ØØ½eÁ1vª =»`€l1D?"}ð¶}§o˜Ná‚=°ßF_ô1Iƒ”¥YFå)Êlåqº¸ö1v˜Û;÷Ã'úäO·_®AÙüʰ0 ôeý¾"«B·9Š1-¹‘G$”1ñým3È#ý0Ä`‡oÔ!~6°çãk ,‘0ÿtCI“ŒV€&~vNì&Já'¸SüYS,sÿP« EÉ#vJwíŠã){ˆlíŸÏçÓ¿~´çO±Яۦܘöm“#&¡T/W-’rEkfm‰Ü»I2;ØÃ°V"Ä”fÈ÷ʹìˆñ'¾#ðËÛ”fú&ÆÒD>¡ñVèçv Û$ÝŽl§¨ˆ€„2žœŸK*ú‹•]tJ|œOÔaß,E9¤}#碦z*g¢¦z g ¦K‡‰˜N¼àœ ®›‚ö}z0´OÎ(ƒôWïñÝ£å™ÈäLáÔÓˆ+ÛÉ)ÚmÄÁ:wIéãÔÒQ‰›Åç‘s̸ù³Ï$©&1-Ç=BcÓÍÿ”ì»Ô_}õþ}ñþ}ñþ}ñþ}íþ}íþMTV4Îâi/ÖËV}zXW`ñk—»ƒVR¶-c”„T’Õ'Q¥@‘ÏZÁFB2~­f,¤§¨L/Õ3ù‹ßmÑÏ4*eƒt-_2tWhtî9)R7½Ç§qÎãóÈz˽LšH‹ôŽs·1ŒH”ýI.Ÿsoég¹ûžL©é±íò»%âü¼•jÄÍIr¶Q‰«ŒÐ3ô Ci›!fký6t‚ìЪ=hUÛìÈÕ)zbÁ䍛-†Å’î® ‘oao.^›*De‡(ª¡G¸TÑõጫ&ío¨ÃKÊe½oJ+/ˆw.Aªpjª‡9ؘ\°éoPøØ]9ÇÐÇh–“»°eú ì¢l›W¨Hš¾å7ðÒÐPNå ×Ú+ã1¦@80Æä¸Ì?pð;$üÌ"•¢›,š~ šB²lW²® p«MŠçÁŽ[úñÙ«” UáÖ'”ÚžNq%L‘åS(¨ÉصT팻rœJ:Wf’]·Á!Lˆ]»d›'ð_làà@;k$¹‘H©­ŒíR©—&\˜VÈAByÀe}™[3ÍŠóÔ{ЦUHé¹›ª’ž™åߤä­ u¤¤ŒøØÑ’ÎŽÝ ˆ€€Å»/›–$02z³%µŽèm2Ÿ~ÿˆZob°&™S+—"\bØ¥(ˆ@Γ–OÐzž,ŠkeSl“Ô,ç@2að¾yÒìÃÑuÔ„1̨´rª,B˜J.{?KË,a‘Œ€‡1‘¼% ‚··kóEAt×/l펤ز[5¾MXd&pz¡»@ãŽcå ¢ªÔ‹¹”ØSÓTÝ$έ—ËŒ—²Žëa÷ìú7‰0ò¥nV‘©*‘Š%dñFŠºjš©ã9u@ÊÇ£ wMTlbˆ€±³I±Í«dõ~äýRªg2«¦ˆÚe ¬u³ )qÛ±î_ DÄT)@¡"ã°BÙÞEŒ%­œ§[Ü·»}ðOÖÕ+ÏrÕŽ8r£ƒäc²7Vi§¹(‡aÆoUh§¶IðvÄ—:`Æp€t‘fà’mPA(ßî’þŒvCÓf&"I"ˆöÅž™\$€,Ÿ¨DQ*@ªäK2*â³&tòôé–H[Ú<ÆÁ3Yʤd‘MS\®Û{e"ž¦ ;du‡¡$Ñ#¶®¡D:cœ±¿Ý%ýV~™à¢øé_E3L1‹,±R*Ê™SF­Ü¬Y{×.ã:Jb–²`Åqƒõ ‰ªdÅp$ª.ôŽ“à³T™dN‰áصȚ¯Ö4;Æøª©®'Šd¦ãŒ`ÂrHFH£†v¹ðÉL)J@3žøR ÄV=RcN\(ý' +ŒÛ*ågè9dᥞA¸ÂKI¼µy¬ˆL×\FÂ!ß,õñ`¦4tvª‘0”AD̘·rdBBU' Ûض†r›féZÿÕ,%YebÌC/tÁ˜ó”àRSæÑØ/‚UT7¦¢‚Š)„{™.@µE—XßpÕ¹ë•òÆ'v‰2频Ö<yaÙ€BÓ5÷È‘bX+êF©–Tq,WÊ”O¼r³v¯…xc ‚i™C.C|ªxW&ðgÿ]TÅD +*Þ²ÅÈ3#7" åoD‹8:¢ƒ×,eäxWlC-Œ¡™²4¬ §ñâÕ26nÜV\eU´K‘Š ²$X– Ê‘ãÑ$Œ©üI ™•(…Ï¥[2 ºÐ ŽkÇL­Yªä[ú"¤xˆÒÉ‰àæ‹ ­ÉÓzc˜âÚ=Ò­ÑM$ltŽ—âÅVE³v‘iÊIŠ D0ÇÐ;ƒKI#‚ŠC~ˆ€NS»áÈb•äi©v»w%9TŠÎ7p†0štäñ/JÔ…µ¤8< QÄ"+E`«È¶Ï»íñêž-Ü®OF« t\È·:„'àÎ<ˆ ǤlW&p²Òrm ›ºt£•?R^ ´‰e\nãÁ2bNK•+·(,‘Z*ƒHv‡]A(”Á2 Ï-íÓ;Çjœù³ù5¡´âÎ9y°m¸âKœVü[Dl‰üW‡ºyøn>qª¿¨Aq3]ñ¶›ª¸É.Õµ(°©Ç¹æy³~Sk®\qãgÈÿ ùó(ÆsÜЊ²¾}¬·¾ÙÍw¥õ>§DDDpL'¶A%pßeh¸NGñ&Ý¢okpSp<Ÿâg²Ü1{Ùµº/’ÛNv½·4‡"êðznéCiÌ ¹=rÍ]¸Bÿµy]U²k*ÛÞ\ר0cǰöÙ»Z©ë—^AÄh[¤£Fqf:ÍCã¾§£Ð·Ò ‰Ôé(¨@C$ `æc­PÔ¶ õ›ŽRUö¼z¤ÎRµ¶o™¹I„bµ]£K)TÙÐÛ…†¾ÛûCI¨Å’÷]½ª;λú[ckS4½‘Gºì»¦m×[Õr• q±y97^®AU#9 Áî³°ª•zã_×:C^k»+‘:_R¯%ËMcNÜä8G:UYšK—:V¤‹elKOÏÇ‚hrZ¼ï}‹ZÊ&çÕÛ-AÃ97Z…Ñp²“YP¶ÀÞ«û YVö3FWÇ3c²-ÄØÛ=Xv4>ò¯ï*¯èZ-êUr’ÊÅÈ[Þlí¦• ºcKNl)y‰ší.Jnè­Ã»vîЄ۟í"F~c€QÝ:Ï_ÔnVfž†ÓûRÅUÖ7Iý|ûÖkT>²ÚÍo°/Û‰e9:ÂÂnEþ#nROBo8˜ómílúWcÆr6ôýš2,mº­åuEËXCä¤U#lRªvåé‹Eí«v¦Ò¦[`¬ÚŸiÔ7= ãØsÊݳ›'“•}yiÕÌà÷Ü>ÏØqº²’F÷þRlZB“œŸÕ»‹I¸E_j­ô‚››KÒN}‹¼§ðñ‚”Á×›lÿìt@‘|„ŠÂlÛ‰mÝ%°_KŤ»Í1¬nÁ%¥¹Ö7f^ô©Ø?g"Ïrqæ¹£·ìñvª­zï]‚^á2–³·Íq¾á7$¯vš*¤á/‡•ÛNË[ƒ×”*Þ¯¥n­ÝXÒ1‘ÚÂý¹7ƬԘ×ÌrçjECÖê[qìù-YF—{íÅ­3})«'n懅‡®°ËfÖÖôWl^7‘d â=§ ìñèë;= j–ín{õ»­k°úÓv¢êY&6>;¬Ù n0<†ÖŒáÛé¿xÙ²;'_ÇìŠÎÇÙ6]³¦u }êÉ«x§k•×V?‚BA”K/®»öýQå»úŠòÐõ=X­WbêUý•¯cö]n¥[B£]Ý1;žõmÐÚÍår2Ùl­Qk—Ý©°ù$0PÕ¨¯¦Y÷M6KnÛ[7%NRÁ ºû·Mkýšz¦€®ìHF¬®u‡»Ê«´kVVâb­ÀÛbK]4@Në­w´bhÛéJ' »Ð³,_GLÇlg°©{b³*öri/%ªì;›JرÙöVÑ­v skP:óâîéÍU»vÌÛ®‚›ÂÔoZyæ¯åu.ã2 =.úÕ¯?=häm—æ#°¯Ñšî”¥ÆÍr¢ñÅ”k¨èõ§.5¹ÈM Àí¹£\ÙU³Z·4Êí¤$Ù9ƒ¾[µBÕ;++ms1–Ò»¶×cUõ.ͲšîHÚ>ø#›’5:„”äU¿haXׂrí›2AH*׸GÛèW_t t\~ÖQ/¯Mx!'²¬ïK[㸊ÀCˆv½ìàÛy³Ýûmø¢ÃJ›Wö»3H[~îcµå“”€Ñï6TU×£Ò~;ÉÃz²Fi«ÃU’~ÊŽÅJº½9#=+«f+©Ê°ämû›6ëªVlÖÝ‘^·Ôì[ö¥_–“ÛF”«ä5å—–Ãf‘þ¡›Œ{p»0r«Ö+Ÿï{ÓY6ÈÁÉFÛgýGÖÁ9¸3k´VV‘öæ¿lÛ‘fªs+9¾ÌˆŽ‹ˆ‹ØÉDÞÿË9‘á"€J`¶¥«h¹®·Ü&dzoˆcÖ&û”Á›Ê•i¹2ƒgµžãÍQuWMÈ7·Ð6-*“c¹iÖ:þ΄̎“¶)TÔ4WT±EE-9­…ýïnEÖmZz¸Y¹eVE²:Œ“„Í™kN—IÖ5Šªù/g„Ó Y6R †çÈçã§ÐÔîGéÈÞ;ò^aF ðï‹¢ ·Vµ&ˆä+ø';éhÖ´[„zïýšºåÇ^@;øDÁ³5Á¸»µ¾™#2Öº´Ï­õ åÕͧªº¯o²ë¦Ps‘6X½w’¦UâS«èJæÝX´øþœ2IÖñM»3›?yR$µµ_ZÕ\ûí»¡Zõ¼'ƹ”µ ~>-(=³fÛúDQÖºýÆ6U'ù Æ>NëÛ⤛Kç=žégT.)ñ³Œv.ÃÁ,J%®JÈÒÇ­#e,¿˜·š•‹áÚz¹(QÉ\µß.uKåm䋾?]£¥#&²ÕclÎ5ž´ÓîzÌŸå;ý§aÚõß&T“åìbv4ŠLeõ3ÈÇózÞ^¶èY_ðä$Ë(-uFã,ö|M²±°õuñ´æ¢Öu³\5F·c²vÕvvœåË8æ´]ݸé\z«Õëz–í>¾§ºïIд¥6¹l™µ;¶8Ñ»bs/@QjÇO«MHª'Kˆ´î]‰ñr BÖ7ý* rÓ iË\#«cLIÓ¦Ä{ŽÃ+Û”¥`4m†GaÅîÚ&ÍŸ‡ªBi7VG“Û,A[Úd º¾Zqôt„¦ Û|±BC‹/¸Ë­¬ïmUtõfØ}%Œ»é0[U~ÞÚª}“Ïí[NJc‡L¦ Â^ç²)š{ZëÉ¿µ^B'£µ«½{O SœÍXäš³¬TÛ((zÄ'Ç¿¸÷Läd²—={sé//_‰…¯M\Ò°1×óMqÙ·Ûy9 d%OY\îî+o=:Òá°k4eöÎê¦JkJ¦Ài\ÒÚ»bmk½ßg ÆœväŸ*ÕÒ¿·7’¨Svu‹T»ä–ÌØÚÚ•%Kœ¨B^·¶°…ŠÖÚn?oíeeÚk=P;ÇŒãšßÑ—ºHF×ÕåtF‘ªè-ú;[Qëý×OØ´£Åµ˜?c*Æ÷%\²Y5rÊÞ>õ®§ëóµþMÇ­#¯¶uOc@Ü´v¡¾ºäN¨Š£jKŸgP7'ù_œ,J<š¾=à"[C›.Û£³m[ó§µÞÇOÔz„}8HeÄšŒ¾Ù¿o­m¡wžó¡Jܪ©ýÏl6¥khJš÷kÄm&:ÒµþÃolÑ ñÃŽš½új¢“„¶'~Ï7[ÖEæ¬ÞÎmq±Ñ©öì±ñ£™=]­ö• ñ#²iwîFrŽèÒ¨ÚA¼´3íû9lKL­#TÉò”*³ý»¬Óíõ–ù¾YhèRÕ»s’z.†õ¾ÝÚ÷¯ž*Ü4æéÛ6yªf»B.«¸lôèyÉ ã­3@Àþµ‹‹Û“E¹1µŽÊ™oÝ Mä½rlõ[•JóЉ¹#ʳ_ÉL6‚²ÑŠÕ»¶aãû9±ù0dÁ„b_ë>Z®5J<{-Ù¬GÜù„®˜˜ÜrùnÜTª”Ç!õO$&uDíº±X¯kE¶¹(ž³Õô-=Pþji-Q»!æø“ºõÐØàª4™*n Ò×o´eÉ—Ҝټs”´ržv9ív!±'ÙÕö”dÜU·v KÜ,:Bÿ­¸ÑKZŸDwnØ8Û·ÁÕšGSé8‰æ2ñúw{VÌÿ ‰xœ‡}×”ËÆÃ+þ!DY´íÚU£Œúë‚Ú/n¦ö°ªþ"¯b'Ò YG¼JµÄB‰€#OÊÙæ ñ¸.£±IÈn5 x]$‘…¹< E8jíõU¥{vÜÞð*OM„°ŒEiæ9vR0:X7¨…ýêÍÐw8)ë2¿â ÈÀƒ´‘‡ö‰¿pðæÇ±F>˜tW”¶|OÄ{”pŽýU<ÅÖ~¢xGbøG£äÑÀ,ý¢ ˆì¹÷S÷…^¿bØ$µÈ:“'Ô'Å ÁÃh4å]ÀÕŒ'QV@œŠ,ua@óYc éÖHmKá,ú´ˆ‚3¢œÄkk‹,Áé˜L+ XêDE\{7gBƒÂC¬³4,’§…tNÖ$ÆQW’ºÅ-È,§I%cÌà™`„Ã@‰5åó–ÅÀ3ÃCŽèÒ(í -\‡>ãp·p÷¿ ?Ù<Þa›ÏR‹Îø£Ëòÿ¦„bά$2œ”®/µE˜’NdâOiè[vlj‚ê8(c-ó4¯vâ¢êÆ%¡C‹LÚ¼1ðê’1¢ÆÔTƒ¨ƒâ¥t À¥ÄSŸ5jKAÇ– ÀËHvÄ<陕x±¥å…²±£ÞF€W`F¹––8×/þê~ð®cý×ýãRŽËØHö„ænFâÚÇ¡õ Žk—±{¯G–ßšÞŸa¬EÞU·ázßý·®‹r·Sœ·2tïj ¬å8зÏ,:e†:”»™hԺݕtž¶Ú/˾²³Ÿp´k>S€5%§J…Êh'6rØ x¼j¯áãÇ8Á^{«U‡’3Sƒ/jý"W¯û ±ËEËÛ~ûÛÏÙˆì£{˜rîvŸ`Ô0£Ëç{–­ïkYÜN²ž5êÔ:,\ hÙ¶ªZÙ¬÷2¸§ XâU‰Ðm£c—N *%ãV¥æ¸+ª&O†s4C»6³%FE·è^늶«± |R`Õ;kA¶A’1€$0C‰ûL£¾r­:'V©YÕ£L˜lÁœÅXeÔýá\Çû¯ûÇ¢ÄÞ!/€È dü˧8Hò×&=F•?¦Û¸ ­ÆC´iÒÜ™Åc<¦¡ÔŒód`ú®–âêCš‘*{Táéú…µæWâ<7‡eщìpÔßÿ“|¶¡ÅaánÆÐ‚èŒ Sª0Šk|ú l£¨¸H×B <:‰‚—˜³w&€A!Ñ£PS°jÒHé4¶9èVÈ>Jß{á=~·MHý©,` n[‘hLšàͺ“rý¬ÎÈзiu1ùâNuœ(8.ÚlŽñ˜=G#¼Ró<¸‹Æ¥û'ß·Úþ¨Q$ìÓ5Æ‹5hUm|6ˆ¹0%Î*Úg~um'ùnd6¶Ð Å ¶µ·‰xð“ºh_¶…L%Á+î¸÷´'tÕÐK]¸®cÀ c : ·`0¦¿æ2“0#J±Õ¤Da?]rÿî§ï æ?ÝÞ= q«&*A2½›¨Ýr· Óâ|°þŒ$™Cm¼¾bÚÚ„ ¾m±{V¦ºöýâÚŸaÓ#8£äG“mVݸºTfÈ3hëèêWÄÚå þ¥ãü4ôñ¶åuåÿU_2rº  ©>«ˆ>Ä Z½pÿ3É‚t²“§‹0F`²˜˜‰ÛO“'_\ÝÒc+­ p*¨8ŒãKgžFò O‰4˜hÚÈcò”·-°ea ŒA_³,LG•åLXŸõ?þ‡½™Ø:Ѐ-€NzŠíÐâ+´SYå!‹“”a\|µË'}»š‡å¸ïWÿ'8³ðÞSi¿7H­\ŦU90âCØë+ëè[V†§rÉÀU¿é¼¹Õo—D™xÿûàN¡×Mfð†ChœârÛE­Q°tlmÜ™}‡1°Ñ翦 ›a¸™†–¯h‚F¡Ä»jåë×B2¬"´A†²O !Ìç#Œ·-ÌåÌ:æPüK³´dî -ÛLXH#"Ïè?²nG–nƒ°÷À>È÷¾#†CÔÌØ`¥ŽÚýd¡Ýu0üé?»Bý¡­WöϘ£~)ê\Fuåß- ¹wÐt3:U PŽןÌêBŽ*Ø´ yAm]näNÒfƒ°Ð¦[ Ñq1&Æ2¢üˆ¹¶IàöXäõ·á4QÁ p î#a«|¿2ПnaÂÌ Ý`p{Ú@KLØ,êi8Ó]å‹Ü´#YQäÚÚݲ˜88{ц*PpÎýSFçô×76›MòýÝ—ZãÕA²\Cž*Êi®û ÇØ\ và½u6SUͮرïØ:–ùéê?"ß(§›ï7‡Ð¸þ/.ÙrŒ6aÞ:Žúàr÷ùˆ?IþËcÂ~Òa´ŠêÊ7…Ôê¶ßu†ÆWDù7GÿIH>Ófû„‹k%®¸ T ·„NÖ>Š›u+ .–¶‡[†­YŽúǸlr`ê ÷–‡x—=‹ô˜¯Ó¶ øŸˆú<#ÑPXÆì‡ taQ¨ÆãˆôýKzOÄœ'Ñá>ª7-1qâysï(i¸ÃJéc‡v9eE4è y`ƒ&ñlðÌíš-a¼Û`I`ž­Ý[Æ=ÔôÚ^û¶ÆÎ·A–Ö\)T»B‚ I€§5GhÛJü½ZOàšN ®r†F'ª›˜¸¦áÔJ«b¨'Ò2ÔÓØ+HXQÄžÞ‰Ž’Ì`fÚ¹Ì}‰îØ;„ [@Æ££¯JËá^f¤t&5#Žâ¸2ž¢´D“š*êU†Â>ƒÐUkmâF­·jŸhƒ×_ÏYClÛ0-1Ó]‰Mq™VêÆ)¼ðC“&sÇoÏ„”F{bÈâQ³lÙ9TYØ÷’h3CÞßš§föëÙ²¤™'åêS‹[/zÿñoQÛEXFm¥åí ƒ¯Æg9åèÙЦÀ&à2#ÿMôy›ü*ÐÆÐÈ1ñ C5œ€ŽÚì¨U" Ñ‡-ý·pDnèºÀÁa ~žÔ+ʼ¢å½Ç5û­šû:¨¿(ÚÆÔ8\Ù8ë_EFÚ“üfý€}Ñö¼{¿g­Gë(üê6}á³xà=ïÓOñíþŠÓi@ÞvžÓ·ÙAºKF=µDï,ƒâbÇðˆ¶=Ù 5›\«’©«Q[`4ŠðÇâ®1¨ø¼YûÑ„ï§pT°>`]miÿH{IW·Ž)3"¼à…A&%ˆ±Œ$ŸTtì%l)Å’ÌAî©9ž€DƒFýô ÖÈÒÙ1m£Ž8åRs4˜(9NÚ+ Æî•VÃTGa¢“1ÒÍ iÙ¿³¢Fb2¨5±ŸºvéÝ¿¿ävaÓÙîê©4O@=}Ÿ±þ"O²:t]F·Š•¹*šP]•äi*}sýóVÞ\êÕƒÀ`gÃFõaþò˜êÖãm5“”ꚺÀÇ ê´Îfûh¹pP‘~Žªtb4x«¦sl;0¤*Ê!@ÄÔt¨ê­½Õ×YVU•eYVTpè½×¤úTtX‰Ç³mfÝÖ@ʬ©p M¨L)S'NÒP¾žRçþ½?‘ŠýT ˜Äc»û¨9ÔQQ©µ—P0q¸zªÛµ{M;È*ª5¶þÅWy:1¥$ì³ öWuøíð’¿@¡ªbqŒãluÓ]°°JH-sUÁsTy~X5ÇTE}[H<@p·v¡íç¡ئ–7|ËŽ jˆBvtéÛféü·ñ)èd·aTF‰viÀã€Ê£wÏ KÃßýáƒzúZT4 &€6‚IÌQÄHÙ8Ö¹¤çL¤):gžt­ ÊM2˜s'!B`ƒ‘™Ø¾ÞŒ1è'péŒ@'£ÓÐj*Åð6²žð{¢æ‹…J´F´²a:Úãíˆ*}´Zãbq$ÌõÎÚ6ÚëmK2 ,ÒЂ5= Á J¬uô?*r¾„¾¼Iì#¿¡lÚ“¦HŒ"s3õÖ¢Áˆ 0î¡+ŽÙê›–m¼K÷¶Ä=c¥µ˜E®Ä‚3§yÀˆª@á\ éõmHï«#àÏÕWÀc Äú¨Ú€êGF'3EODïè&¶¸TŠ$ô¼ô\ŒÒ~øKth¼ÉÔªU<Æ2UYáB²QÂfjåÅÒº›Á*YdI'D 8 ám\ÒVC nÈ— „™ Â¨‰¦PšpA£ËàÌpÀ;ñlOBÜC ¤Ú Š^fß‚ðÔ:¾¿…¦…À&3ÁÀŽúb.êe@tAˆVm¬'h00F"¼Ñã1ÿpê;w“¥ZIÄŸ’.¾[>¿«ÓÓmé`TüÍ Áépèdo a}Tö4b§¸Ò¸ÁGxÚ7µi-Ë™m+lAˆUDÀ*™‚x±¤¼¢J01ÙóÏft¬ÊHŒÉ&L’Äí=ÃÓÑåØBÇnà7±8(ë&ôß8\ºÄ²éþ¼cl9ñ†@T[wž-)- l˜Ä‰£|1ÐÓ‰]:Ÿ8U™Óö².[0GÎñZ­`ûSojï±ûwF¾¿ª V=Ì•;=èßaÑNÁCgoI;úW˜QÃtc÷×ZÁôü€¨ c“Ø+Wõ†Ùe7ßo ±énªòmjÏúi€=n|NzÛÑA”Á‚6¶¿™_â®W¯eÀ>Û¹ºØ»º›-dÄs5®Ù,5#Nž!ÆWÙ¶ƒ)‚2"£™ükŸâ\hƒSeƒŽ¬ûÔãPDtÀYiUIÅ·üþ}}S³¢|Gè´¨N™Áwa²rì¨ð¿Ä>‘·Û×_¨%~!—~îˆ52OAÞ~CÛQƼK÷—gâ½ã¤_æ˜X²r,8Ÿý´ñ7n ×FßôôòÀÜ8ÞoÅ’¤ôÕ²m»yŠÌ÷µpÚ+80˵:¸jzðÏ ^´qƒ“š°Ú 3Ëx=å÷­6ã½OºÛr8ôq¹Õ‚‡&|°|D dÆÚ7èÖNiAÄïðÉÛê ¯€D Š‘¨ pÞÙ¤GT!˜üõTéX‰¨;r¬z<»}çbŠT$*å'iÞh‹üjàâ%‘÷ É eí ‚`o2}5üªñn̓¿:ú·˜Ø=¿%žÀ eøË-Ÿ{Q9cÄ bA•ó~ðÿ1Çé©ÿ×lçÔÏÜ(ݼåØí&è:†®‰BÍA[Ý}ôŸt÷cüË0WŽ'S2™uóN—pE1á]:¦AÏ ]²`äFjÃj°Úý+W+Ãpx­ûmŸyz¼C …1¨Aë©Þè‚ÚbÁWÜd†þ±D²€Ì.9ƒà±‘«:$3 c;g¯èŒª×ß_héV8cP:8xSk}[Í Z•{N'¬üû(…"sS˜‘ˆê¨U‚@ÕŒÉöz o4N[ëù‹W °`õõQv”fWgucPq*qùO`àsS¹†Gè=DÓ[¸!”Fâ: ¤‘,Y º›Bª[üOpÎpëò‹«°ÏI§áœ‰c ›*ÊóCZ£ $’4uD/‹‹ÂÔ÷t%·PXÛ Y¢dµÂIqɘ`žÊH#Fv·sŸÂëÉVQÅ£%kƒ&Ôf21kH¸ŸãéŽþ¬I œ»*×ß_hù:m)cÕA¹“?deÞv÷zhµ°ÁWpŸª‹1’s&›—c„Jý#é¢÷`ÚM·'Ô7 n]Ž#ì9Žï®…•ÀÜÌý‘³¿£ k¯åÿ=`q(ãjŒ›µvýœvtjBTâ$ÀàFƼÄPŽ„**ÁffˆB¸Bá"p%š!©­j W2&'lNppœŽc 6® ²dº€?TÄ*¹>ìäF+‰ÒY0¼Û‚Üô€"VÛÄéeOyxT@|e¨Û¸!‡Ï1c øZA©ÏÙ;XðŽÚ>Xú¨ÀÀ0®Ù“öIÐbj9‹Jçý#éÂïo©†¡éX>ªà½m»Êþðm¸H §om`¤÷á´Þˆö×”fOª¦ë>…úýu ¨î|’†ãPîa‚ì´Öïâ¬V'šv8uŠ:WÌ×?Ft%]O Ö»¦[Ô;:S 2#1Su‹³Xœ~TóìÑsùìû§Ýü½ zц±µOQÈõV…n0Ag*Yõ¶³ Þí„ca¸R¤€qÈö†TÀ¸4±‹Lñ;'#¼a•^Õ*„$ƒ¥r!žfçä)ysüG‡¹Õð'៴iÕ|E‡¢÷× ÉëV’¸°ç*´“ÄæÃ-⪋H*­ Äéȉέýáí¥v0¡>_¥nFö?@¢¬º]q‰ÀŽª»l±…$De6ô¨3’iMÁÀq2`€Ë¥ÓOn*ižé‘ “¤ð±À-½tYŒ´ÑN[µ¶Íõ¨™'jzg£ص»€2°‚DV¤–°Ç…¾ð·^ãï¹Ùuî’@n£‰Ìmʼۀkô¬–:îάÚáÛYâêèóœ~˜=EóQÝâ=€m n¬HÁ¶ú~¹«T£@ëúª[+]£0¯«Ù@Lé$‰Æ óë§S$¼ ' ¦jßÞÚò×2‚;€4ÎG„G`š•}r§3髉xË.Ýù}~®º– ³n¨Èv;úªn´Ã¨ì1€7÷}9V¢OU@ý‹[º¡•„r#çýÔoY—±é)÷¾ÎæôãÒ¶í‰f ¼œªß,¸éÅŽö9žó€ê´4vPe$FÊ€0œk†Tõ¡¾º,1ŒIE¡1žÏm#2àÆþÚE7…#»²µØÄŸŒ_nú‘³‘ÝöO_¶™¬¶’ÌdÆ8Ej¸ÅŽòf“”»ú†4´8b'*ÕË· Å”c˜;^Éïì"ì‡Î~{hx×úûó히# ÿgH4oòÛ{?ïºpÜvQG0Àƒ¢=p`%S·Þnïë'uc™ÄýTí¤4â7‚2ºwP 3êÛïÃu{6׃NÄ•vüöSÙSœ{$}5ƒŠùï¯áHú«ÊÐLç'áDZxf¿µú—»NŒªÚïeöеË[:˜i&=Ø÷Ѽ2mê˜#×"ƒŸ Á»7÷gA…uôFÊÃöÄÜX¸ 0n N2:ˆ=QVÐ.•¶ŒñÝ0'y;Lµ¥ˆƒ:NSwGë©Vƒ³¶#<û«tã¶wG__ª¼«jM±â#ãóúh]…Q‰öMNñ]ÿM-¶0 šÐƒbH%¤Ç‡ Ù\DèbLiq 01ƃY^( a–Lê[P2W4®&1œ'P‹ê \m¢'£>Ú6m) s'3Õ='£ÈsÄ™u®ÏF^Žœ3þÁ¦%}tE³¥Œê#we e@îËÒ$Ÿ@ DÆ;8Ç¢¥H=íã;:úª`m& n®ÿ¦mI3Ѧږ=T«¤Ë}e`î2"*\Œ@ß+¨„ä8£Nf'É˪›‹+ñ GÖ;ëŒ?o'åï öU¿º¾ÁÐU€ ç×ÛZD¨Ç#9áïMj·‹“Khˆ Ⱥhkñ±,Óœý‚BòöüW3û)ï uÖ®_„î>õ(à« ‡çA¬?k;zqèž#v O¢¤[Ð7¹ÓêŽT_™æU@ÎGt±ú(óã½° ™Œx)˜¥Á !µ«i&$1Ù^@T†Ñ:ŸN¨3'® ×Wñýàkôï«õ:Ç­OÑ_­`‘¾ÙÖ=7ª¡Nãƒ~SAv0“MÌ8†¹øPxGÒzè:œšÓpc°íŸUi|AɆGê=_µŸ–-ZRÌr粃sme~–ú½5«‘´ ‡Ò%·œÆ9õáJ-Ü:’èˆð²\]VµšÏ =µxè*oCÁ1¦âÜ&:¸#¦µuŠÈa¼Àu ÝŠƒÈÂýÐ[ËòÖ‰œå‰Ò6Šþh[Yc#Ý ÏXÝdS² !|°–ÌT á3NÀª÷•Ip 3áÏ*¹jö’-ŒÖu1<9#Hß$R›¡d’¨ +œ0;0ÈѵÁt.hçˆNPþÍC¾—–e)N­1’àœI(â­,ÖòlÉ' :£#¤}Q$Iœ6€ßg¯††F2+Pä~ƒ×í¯ŸÏººÿc'§šêé[ÖüJg·xì# [Öü,'³xí 7›"ÃfBu«g#^W. Æ4Ú]d$`#¬×éØ[c}ÇÇò¤ûkšUû–ǵÉöW9w¸ ÿ¶¸y˽áýµÁÌ«}ûqëB=•úœºÜí¶?•ôŸ]7††lÖà(Çv&&P{+]¨Ô*êâUÆK Én²qyV! b kÎ|dÜ)M Œ¶DQOœAÄ0Æ5#g´a¾¿T›–~8â_÷Ùö‡} ƒMrØÂ1\qÝ’q`3ÈPK¬rj @ݰo¢Ž%Mh8ƒá;ÇÖ6ôOì±ùüöô|þsчKÙåíyŠq’a¶êmÄcÕÏÜ7~ÂÊZÉûX÷PKJFÀ®îª4L cA×"‡/‘¢ê‡S±€#×Z¹ †ßþ·—´{=äü'º¿ú¬‹<Ã` ‚¯³ò3¸Ãl¢yppÄ€aÚ?†ö"œNÜ3¡ÊÞ’À\Ä1AÆcáÌO¦$Q½Ë V³kcÝÞÖþ•ôPt2Fõ1’DiÇb.d ‚£H™`pcöѼ庶î;Žú(ã‰L¯°ì¬~_—dDÁ†öÛdeÛ5t¿ÂsþþÑêù1²§ _æå-ì\™û~ÿê¡nÒ…QƒrÙa‚Ba›Ã¨Ì(' «7Ù¼›AšÕÔzn qŠV «oeu\K¶ßd¶8ž¢jê#ë³d=ÁŒé¹pi(~ì3²ioÙYkj.[Ìvð1SáÓêÈaW2Z˜WÄÈL»˜1ëD€)®ÌËÄãK2ùbÐâ·vÑÃIÌ4I4³ÀÅ­î«]G N鞃jò‡C˜?<úó­CUÞXwÜ´=®ƒó/X¯1`«Ã6˜ýP2 woìƒMç¡·i mb®}É8¶‹„¤Qæ¬Òln(÷ö(ýñß@ƒ úé^Ø,&B†2œ‘;3Ê(1IØvWž¾$Ï­º¦Úé·µÛîÚdzÓN,Ë_^ ÇÞŒÔ €#-³ü—½´_¼rúè’dš`Eæ%×¼;~/Që­v˜óÏhïù+ÍókŽh‡fæa¿pÙ™Ç*à’Ä*ï9Ég%ç {ê·ÝÉ·rÐ0Ö^ËI‚"Ha#Oo˜qqYUpIeIi&DéQM1E±“3”箿Zâ'Þ`=¦Œ^N½ ŸÝ£ÏQÛ+í¦ÍźÀû ::‚Ca˜; Î…žU £÷5±†[PƬX‰Æc²¿•5wYømÚ÷m+™–÷²€:ŒÒ]\5¨h9€FÞ†æye›'–Ç»¾å±ûË·1C˜åáU´dTꎻ¯…_˜c©p•:Âà1³‹ Çðn°Ù”ì9¯££ÉåÔݹ´ —ï¶Kíê¡saq¶ ÂÒ÷fç­°ê¨ÐÅD%Þ%êŸî>¢>BrË’ Gï6^íùå¦*Ãhùâ:æD}¡áï¯tŽ¡@¡rëì9îÎ_mO>óxý•Ù½»:/0P¶m’¡‰Å™£ë¨P`Іް MÎ]'z ù“IõÔòËGúw¿Q;ˆ¸¿â¡cž¶y{‡“6ßî\?…¡©¼ËJÚ›Y‘2ÑWuqôèuù€“u”+Ë„ˆ‚aF:cdÒ§4¾EÖ0ˆâœ´{qÜØtk\9k­ˆÙjáÛÔŽ+u- K&$d{FÊ6o©ü*¢\¶Âª1vå×^õ6­¨©‹¶Î"<2}ÕǬQåmÚWˆ ž# émkâWÛ 26áZÃ* âvÄ ÞÞbpQ¼Éžãnï*‹ £,ÇA¸£¨}ßxz1îé,rÓÞ>óݳÕKnbNpLw 'ºµêVI‰R;ˆÁíMipAƒÑ6› ªqSÝ¿¬Aë¥<ÓVõbqϤûØo7šCÊ•6€täÙÕßE·n%»¦^Ú‘¡ÉÏd®¯z4YˆDAØæó­r‡Âž—‡Äç4¶v(âaœ ­(D\•DÜ>[Z¼Ñ³R$žüÅy–õ^äÆ`ñ]°7ƒËCo¼ƒx èC)İŠ~k˜:È ÚÄ-cŒ±9ç«oCŽhh‚Qéݶr£ÊØp¿óXmnHFT1ŒfÍ…@KŸ±ÔíÚß@MiÄ«a«ÏeÕYH´W]ÛÑ’øÜ–V8FÚ†Y 2aß.ú Òa’Êk O„¶ iFf%Ìq—AVİàjå†ÍFG¼cÑpŒØi‹dô3%§¹#L¤†Yƒƒè¦h`ÏÄC “³g¶…Ñ:Ï„²NŽ!Œã0¨ YW,_¶€HÝ8ô1'*NUr´1ë¸|gþÑÙA¬\%v©Ê7Öz¢…»çÉ»×á?W¬uÔƒ†ýžšÕÑÿÉlþšì¼ëþk ¶Ôàƒ&#žyí´ì uÆ£m¿NvÄ2oY¯0N@bI1´žƒ}²²¥ÿH?1IÄššH9†›úk]?ËGÚ @n,8dG‹¥·lU2`\åy~^ï0Ö¿ˆP`ž£–Ü„á4—´2kéa ³±†8ôó<Ï,|ÏåÃjW‰:dXšµÍ”Ñæ ‰˜ÄŒðÝÓc–ò]üéãQÁn>/˜Ãji¬ÝPÈà†h4ßÓ¹‹¤Û´‘—™løÎm𑔊€ t9Uc-h”?‡Â{Ö: °DÃG—–aÄŠZæ¦Vû@m~‰8Ntׯ6”\ϰu“²¯^‚ ´,XˆÉY*“"÷ôZ½µ;˜}j:>²OÕЋ¦â”Äiy]QâÐÀ=T†¨2Aœ{vÑTàH*· *kâ•„Cálóéc¶íÈü6Äþózº Kº‘#]·MCˆÁÒ};©D.J7(Á}T·Ø~¥ó'î­§Ð:9®wúoõ³|crÓAÃ"s$ì†ÒĉZþý}åVB_PN’ŒH¦cy«\×õSqÔóÂù|Di´¬@8IÏ~‘Vy!Ì^{|Õ†7 ?¢YOºeepá¯êlo7›oÎUBþ%ÐF¦LÙ³âÙ_Ò¹ûWîk»p!RߦQá º&fff¹õºH6X‹ýÀ´¢t¸CüIÀžÞ±\•Îbàp-rÚß[Mp‰ýU`aøtœ5c8bkú)åÚà¶ÞbìY˜©ƒ¬äøå†X@Ê­·>ïy®^*·mß „“§KÚéS³‡t#¢×<£M¡¿Û¹—åxüÇä^³±Ô8íS¤úˆé-~â .¾&ã$øBa-:½W.\]JŠXŒçH˜Æ”=»(×БåH"!´¸Èáˆ` Ž‹ßfÐÃèè»ÕÔ>A¶åYHÚªNP12GgO-oìüì~€)V ’0“Ž@m¡ÀÁÉÍ“FpÜsðÕ«YêaV¹uÊÚ*ú>¾:ï-mœâIä x5ü&–‡/q@fc frˆ vE'%rØ{Ha#‡#ö÷ÒóÚ›¨4«G®àwbiïù æ8!š1`Ø4ìâï«v”)hÊ,`‡zî4.s6ã¬$úvŽ£4¿ÌXGÐ!er„FYU¦P8[ÀpOú¿˜µËÛ[“:‚‰xØXùsïÛ`;bWü@R¶ð:$Uƒñj_JÏ´t­Ë*Zæ’Z6äÎÆ{ŽÓLL©‘¿ ¾ŠÒÖs§K-’u%f#$8jž.‹ë¾Û{EãŸîá>ƒ^è5á>ƒ^è5á>ƒ^ô´»­[öM(VØ9|[2έ#!P"_Ì8Ä‚vFí•Ê!ÈÜÐ>š=7nÿMKÕ·Ó¥ÏêñdaŽ´ "..)¼€@q\±ŒÀÇ ê©þbÜjÑâ1šýẘò×R朒 vÓÚ³~ÛÝUc¤0&TÎ#§±Î*))­ ‚:_2rú P"YÙô4L¨ ˜Ä®êæMð£Ê¼Qt‚8Fù'˜¦O…ÜzŠV¸Z#z¶ rŒ;+–m×W×"³šÌzk˜·mRâsYôùr¡+Ž #PÓt¨X œàDÔ5Çdø Æ)èœGQ1YH«‚F(ÛFãÑuë €€¯ã¿¦¿Žþšþ;úkøïé5üwüÆ¿Žÿ˜Õ·c%­!øcë¥ÙF’ gŽsýóVÞnZ°¹œprŒÔ_hùyS˜±Ïùœ:APØø˜O #Ç2F5ËXA7M¿&ôdX§ w7î­Jå] ¼îãsIm]@p÷Wõ^_‘·å‡åÀ@£J: ²OÃi¥åW“{|ÚYpÎmûÚN©|øöHÜyN{–F­½ÛdAբ쌳Ãëjþ›d)‹|¹ `Ƴæ“—ˆû+šµ—¼Åﳉ"2ÚE+€8爜zú; ™Üú\ÒéÕ§Óœìî¥×âŒ{jŧ­qAÆ3_ñÓÑýõÿ=ß_ñÓÑýõÿ=ÿ=ÿ=ì9t¬rÜEÞ¸>:Dâ6о— †ª¸šqpÛ*_O,ûíéüŒE('H‘Žìsî¡pë ¨¨ÖÚ˨8Ü:²«7F\}Unúäê­ù€?!osõ„`âÌ ”Fs‘Ìá´ü‰èϦ÷0ËFo@1ë¥Sœ Áup˜âˆmñ¶† Aý¸W.»‹7åSôž—ºZ©0bAÒ{Dá9tq6Ll]!@ÄêZçìÙEöÝm½‡ 7ăÕ"†¬¶öQ¹i`•Â_SëÕ4ÍqÕ@]``Þ¼»ëÍR ’°Këvu_wAêÒ7Ú¸Gá¸'÷”ô5»vD`øø—afœ8 ¨‰ÄŸEZËÙà=™¯Ò;ºySjóÙ v”tÀœ³Œâ®Ý·ýJï6-Úfde`ˆ:†£°vÕ¡¢ê¥Ó¤9X@ÓIœzôÌM7(RåÇA.m®¡l}¬g °0í®[™µvõ”<ÀA  LFÆâ´õ©«öM«®öJ‚ÚÓ0}¨«=ÃÌÓDY¸ûøviÈÉÏ}?–¬létq¥ÐõŒséNMOöþÚC7¤é^‚饎 p<` ˜ï Hйse´ øœÏ±z 8 ª–.¸%%5?ê/ŒÒYxvçÐÏ¥•†·ÀÀmš`2‚_Vg$éè¾w€¿˜Ñfïjý#éè}/4F¤´r5}Ðh³Ls$Ì÷×”¨5b€’ª 2иjgˆ0H¿¢ç,ÍBß^$õˆïèK6¤é’#Ÿݵ¬°b »¨Jã¶z°¡fóE‹ü-¸u÷gØú‘—G-ü¢+µ«šÈb€Lă¶®ÛæyN^Ê=§]Và6¢§HÁŽç\Ÿ$y¶¯ka¨@YsžGÄ2®v÷$ü»¥øgó+Y0L°JâHdF×+ä(%y³pÉ À0$LmØ+ú»•Í-â8¤6ˆg\‹w–VWµ¯F¥ffḧŽÿ¨Ý½vÀ³ré ték,HÕ$â3Af0$€fjç5þ_‚ØÿÖ»{\ËvE8aß'm¯4¶¬#ã;ÍI¯5¼W˜¿áÉ?Â'¿¡î@O†Xé¾Î2ÝUiÙP\W´4ŒIB †+÷NqE¬*±ƒ%˜&œ0n,; ´ïwQ(ʳY™¤øDáÕЖ¶»ú”í#¡ã4†ôgê'£H•¿ˆW[‚ Ï c3NâSxd'2£¼(Û}$Ha©™T0Âxx™ À˜Ò£tpìÂï8ž…t0ÊA¢…û~ ÃPê>ú÷5 €Lf> p#¼SwS"¤x±ˆVy„àê ¦ÄRÿMæØ öÄ!>òü=¿W`OÈ7ïòáœæe†®Ý$KjÒ…Eù-ý3–nó˜úÞ}ýÇ}aXf6ÆýÇê «¤å“;†R \ú=f‚¨€Á€èµa¯yÝX—áĬBÀ¨Ì±ßMt*’Y—Z¨_5T®@cQÎ’ÃÚw¶æYjÓ§’qŒ"ì¥F®#*ã½FX׿¡,Œ­§­Ìûè(Ù0 ÷ÓZlÔ‘è Ø;qãh¤T’Rx´„rUEȼq¤º• Ò³Ò#2IÆI$ÿÓ£E¥,}C¬œ€í£Èù¡î’YcÀ­ mºÇV™¨4¶ï¼YRZ6ÌjŒHžÚ7à 0JéÔù¬Οµ¥½eŠº™RòŸÔX[æ€ÇÂÿxì?k#ïAÄü¹8MÊÿMl2{Ã!½mo?o!îÉÆ´®_?]pCAâÇ!×»¬ì¡sHÈ쟞ݕ&šýËe•†G‰s ´6gnæXpëÕ³¨ŒÁíèÓqC Ä=‹´* “¸óÊ­‚¯eâW^‚u22‰IVŒ„ôIÊ®ßø˜‘Ù’ú£¤_\ýåúÄ|€ª$œ€ÌÖ®q¸¿Ó_â9 ÿUyH»_åøŽl{}0FUüÒxÇñW¯eÁÔÞöæè[`ìBjl@L€¹}ã™­v‰a¬©JC¤c+»vÚ ¦ÈŠ[ÇëØc°æ;°û4"ð´ÿ ÿå—æÓZ­0q½HaêžwQw± =tW—žaþÆ ßq¸.ªÓÌ0K_餅ümâ~þª€¢ºD‰30 õuлŒÜFGÛÖz<¥Èxý¿]pœ«Í²ÅxÛ÷†L: |èÐ~1à?xfž±ÙAr;é­]‘³ô¡wÌw ¥T9Õ£Q¡³3c1¿¡àñ\à‹Ä{–~C ñ%í;Æ"íö­ì'Äßqsnܺè§&¾X9¹Æãwûƒ©}4„£6µb×g†Ùa¶£&p¨"@¹o1°äAÍHÚ 3ËÞ]¶Îã½~î8ô~£F\^ZŸ1¶Õo/Ì'@Œ  âwˆÓ¨íõPWŒ@" ‚DR056/º÷ÒZþmô³x›"{hk毙üÆÈ­O.w±,ÄMq+\È;±¦F2Jn=DXôÐ0d ôïǯ8ÈtyV¼[NÅ]L½õLj3Ž`ýQP6W–;þªÛj·µîÚ§³¼ ‹ŸÚrooWO’§‚έïz0^ãòY­-?baS⓳@ë¯Ðmχû‰·ï7¢‹ÝbÌvž‰¸%} 6ÆÑ 6ÇÛç Þè8³Ä5™:Yý5Ǧg ƒÑ®Ùƒ‘m 6Š/Êàþõ­£®ßĽ^!ÐB˜ õ݆®=Ѥ¶˜€`*û‚ éÅe˜\¸a¿†…c#Ù×Vtȧn®¹Ù¸ ¢q«_}}¢—°{:⮢ Ô~£G_ -ªέÇë «èÓg-­ÿŽþÚÒH¹ž³P;E` í®#ZÔçè©ÌuP$8’7®…¾bnÛëú‡ÂÚñ9û#gkd(èR¨ËÑZí™?dãôTs•ŽÿúGÒ+‚ã'S CÒ°}UÁvÛw•öжÇIÁ×mŽCa®cÝÚáP½¦}•úŒ[«!è€\vÜý{(«â åóŠÀHê­6³ Û;vú)|a°üòè[vD¹ÊŠ]$:íÐA¡K ÍÄ=xúè]Qa†ãõm.°ÿÏ¿}jhd&aƒêëùQ^u¡úL!ÝÙ»ÑÐ.!‚=ch=GmiˆYˆ,Ú›V }ÛJ2lb¡'Ç#Øi•p4“·Lã§nü¨Y·oHR4ɘQ9À´ËâA4,{ï ÿö¯áž³Wn·»Ü=5Ço£®–å±+pë9ú¶“‹˜=G ·Ñi9¶24Ÿx{hEp¯¦ˆˆ"™IÊ~µCVGØDeØúòÈÔš‹xÿU'•Ž ¬HÄŸžç¨â·û§?F~ší‚Ìrµ67[3»ì¤í¥æm‰)ƒGÿðŸQ ˆ 1È ê/°RÆX“€''çLáZPþš`½gkwìêíùeJ°‚ j\m1Àîû-׸ííè WP&íêœÆÜ«Ìp5 P²[‰ÀŒà¨ãÑæ¸à·k{£é4ÊH,¸ñ ¼jR³×*f‚¨’r¤·lãlf>"e£³*ÌDã‰óë§S'TbNã4Ÿx{kHÎ-¼‹=&* j;É?D 6ÓÂÊucoÕ‰ŠÕ\Gê¦tBUD“³çë­6›‡á8îî4öî[‚£ÅH8m˳¦{6“™ÇÐ'!Ô(Ù³>i˜ Ù9"tÎD’Û?î Ì9÷àé$MTU'2“^]±6„‚À‰S1V†Õ‚ ²µC—0bì®îÖÛ¸vþÄÛ¸)ÀƒFí©k[ö¯SuuúzB –cuš×Çís™îúy‹ xO¶¶¤Díú7˜@1 >¾ø©Y^ÌG®‹#†‘E±1HÅpÆþÚÛ:è=³Å?3ÛPp¸¹¤u{+‡=dÖ&M•áôN&­Ü¸5Z&{¿»×@Ú‚„aQ³¯E²5 ämQ²WÙ–ÒB07³{IövW“euÈ2>%¬©Ä Â@3Ö¿ ŒTn$xˆ’5h–0ÓNˆA¸¼V˜>˰…889‚6Ñ[po>;Lu™ÇH÷Wûè»$É=²ƒ•¼˜íOüñôn¢¬#0sy·,…í÷›»/M<+€úO}[·æŽ=ÒâÓ¾0ÄQea„aÖÙ C$à$ÑV“Û_¦äwáèÊ…§†Vñ‚i‘º¯4¯8úEcm½#¢|Ñè?]y¥ËŒ cé o b2Ì{+ôíªö }9ÕÆ½”¶Á“‡²…™à}›Œ`~ƒAíÙÔ½£5ìa…Zç9f‚‘ Ѩa2‘ôV³ tŽ&ˆ,{ç3RAbHFdœ‡·†¼?¢Ë ÛA áŸf1‡\Èí‰x:8yÌ/¬úé®Ý:™³?=›¿juˆxÁ†¿xí¤å­,V c ·³·n&ƒ ij!IâöˆÂsèX ÆÉa•uN;0Õ¨>¹Å` >õe„dÜ&”¢“æ b7l^ͦ™`é*Aïþüjà qD•Yº¤ºÝ&q\ H\'ÅŒm® #‰:ÈÌœHÌáEo7 ‰ÇןeIþÄHõú² ->¥X€0ÈÈp8çŽ4UÓFY0’HÆ|Dã=öÊ‘8 â@Úg*I˜Ãi Ž^è-i¥mR 038j08R¾ dá 7~ vSÀÁŽØÂ¸u‘HŽx‚ÌHÓ2<;©-? #1ÇH;ÆD©#…~£„X&2{x”Á¡vÊ—` d«”I1¨˜ß5´.åÃ×cШìJ €':¿³AÄW±=X{+„°ïÚ( ½Â6iÑ_Ÿô@²?7÷W µäýUUì\×Ö=ñ슟ÿ'ÿÚ?þ‰ð<…Ê”·f»1‹2òϹt—À[¬„/Ê%_Ù½vð·ÊÞo’ÄqTcåYËÑpš¢O'@f«Óœ>‘‘W[Îä..ᘆ½#c”“ò›üM£ñ#)mæŒm®ìëæë—ïÿ}†]f+·ñD ¸Bâ'þ³_÷ŽÇs#/Þ9}är»×ÚB3›þmr­ýgDº,:ò¦ÖE…¤—˜•βè“ór$Ý®±_Ì8i›CgƦݻ[>dY²æ[7 ŽôpçÇdTß’„JF"‰ºî‰©!3›ðÓP«¡Y¿9y"dí „©Qcȇ}-…3(„B¨½¤*¤¤„#ÈópßœiÄ ñªÖi2êÚ6I[ R½«B!KxRUàn3ÂeÚ}<{#F¿n†ƒäºúì·t0Œˆ »Ä?/´Ï¢þÀ’}îy6S¯ ¢zdé. L²Ø&än8j‚"‰ÕUWdÔÜs売ù„¼†áG›•Âtjð¸¢ì_Éiå÷ìˆ*§MÑt¯ó×:Í©¥½ÎqO«ØíRø³*äÔ­%ЧBØÙòÒ·Ç|}KоçùͬXÂvªø“óÞõ$ºKâªn.”•UU|UuÑzn»{4¨(ª¨›ª"oÓQ°G%dó)]ÈbÀV´ëØ’ÜGGvìÜ]tG~í—}¶×4Šx–‘¢~šÉã><ä.Cr,JÚ,MËxTÛ´ .Œ!É\p n5ëÇD4MÄÇtßeßS¥Eù„Æñ ÏUHqæF­…jãXC[ƒ%¨À‚ëvo©"–èj„;uB›9—Èj.Å­÷RÙ¨LÎ ÈÍ;\uöA)ˆu‰x\BlÉ|wqÇfö%IˆX3S2¶ »“G܈ݻ ’¢Èe–Æ;€ }Ä] 0|9ã¿Ë“.·~¹§ï“MdÜ:ʸg"{±ÙjS(’füY !#m6êv‰ú‰„Só·TÅÉóƣɩů+ÿ65±ºTd· ´ãQ^°Žß{ n´éýÝãÜ|®óõ¾7HH%Ê,× |Á–÷Vl0/ ãIéû:j»æŸŠæqœd$kýnbäîC…º]¾CÍ6“k»•vD’Ïjy¹¨'}_“cö£Õ·urZ—ö×À›y’ $ûýÇ3‹ø›—Î\×v—ƒÐ¼ÛPi»¾ë¹³›Ç¯ëIIÕòoª.£rgÌV]+5–Ókå|¼Å*q\fÖ®B²üé=e!“^ùn*(‡j¦¢UÕÁYY^Ú3¶@ÄvÙ¦›Aö"k»eÛ}·òßWÙQ;Ôs©zíürƒÖ¯ÁŽ`½x™€)§q}Ôó][ÓâX5ÆQlÅ_¯F²\bÊ´~…ÌŽyÁ3[á5ûôŒ­‰ª®ûí÷°Š—êêîàZP~SD@iÊ×ê,Y˜ÔÛ9ëúÛM"h>§D(7|•g‹Ï˜XZ¶Ôüœ¥ºõ\†’=xµ*®úÒ]qÇf»CW­/2‡v¶!´iùk­ÛÎjþ\i¨6sÎ[ºN:7`è¾æ¯ü‘ÿûdqz)*§ð…E]ÿý=v”U¶mšlM̆Ãè¿j8¥zÉ1¦å*÷$êøC[ WÚ/AV ëEÒów%qǦŸƒZ7e}V›x"Á»b¨žÄ4Ñ5açêAšw¼p< 6ÿ+®qTzl¨º[ÈØ†Cò³š”$­¥–¦¦nC-¾¥Å“ Çhä¿ e8q\}7l‹qDÙ6Ÿ‘pÓ2±l’,èÕRÈ Š•³š¬¬`™®–³ƒ]Cþ°/¯"[ƒà;ê7%cKŒ@°´bƒ£l o¨) ZÁd52|⸓q”E÷Òî4m R³O”^_‹Ãùŵœ4µ ñ–GaL•‹Sq×½6œVQÁC‘ 0BîBUÕ_|ÎbÌð¶whèÄÇræä,œ'#}z V[ü~? -Äè‚F«¤T]Ñ|ú=¶U–ÝÂÇ1ºÇ.æòÅà3÷Ç Q<“Ú½®Ž7̸àï—9;ƒÜ€­”<Ë0cÁ'iÔâxIp}welAuãür.3C•Üñ}ùŸ5'd<~$ã„D¾ÝWr3KðÜOó.&;É£Õ©ËÀ}*k’Oº ÎøIÑ;Ñ£%ë­6]‰<úxë–ñy\–³{«HŸ*G}Ïàº,h\YTs"!<‘FÛfC ×Å:jæê¢»ê·93#oø©›[ió1üié_—¹_lN¼´RåË/V\&•(„  E{ÝÕdª\vŸgƒù]vI8…Ù‘ ™©$_Í'’®âØ@íDØE6Mgó2H‰SÆÅ$3™‚DcZìHã-öžÙw§”Gu÷‘>òí¡»žBµ„äfe´ ô·‰%Ù´à´Ð(”X2 îîÙ ¯rm¦'•6].ÊDäŠÖ,U̘:ôµnh1!ÀBi脎4ˆ]ç÷{¶æ)L÷z2¸÷ yžñP.Ç*Ÿ!îÙEv^¨½S\aÿ„hÿÐÒ!.ÿUOf¹À˜!ãi’©òi.Iqš¸–R.†ª‘³"# -ż¨Ié¶ž>òmiiÎÙF3&¬^ŽÝUö7We‰³9.:”ÎÖÛìÜ^BDíÝMHåmŒ[VÚwxϾãí‹­ *ª!¶Bc¿ˆª*t]YS˰›5‰sRò3-¡5%fC%Þ(J$‹Úi¾Ê‹ç§®x8´áK7\W¤c°¿ëRaª¢ªI¢”JÈwm²”uh“ËXø|ÝñE~7gA%¢Å9î·,±ÆdnËÆú‚Í©1qPÄ_i »ú"êƒ&ùxÉdg•3*Û¨ª›A–TÅ…¯D’òJ}˜SÊÈÅl&ŠúÞ€6¶ÆZ¹âüëŽÉä—@Ý´Ø–QÚ—Gy\2?/ztQ2'™lç4ðÆGÀ Ûy²TðGp`¹æÿ—˜{­‡Jx¦eجqêNPKx»ìb´?ò7‹ÕDFz¦«s®:ÈâäØÕ¢*36:ªN‡G#ÈdÐ\aæ×¡¶à‰Šø§ô[ï.ª–1Ùlés¦<½±áAŒûò/tÝW¯AET¬äϘÚå¦Ãê¤ þ/ùn#GaW(õfÏ&í÷&ØmÔY]Ùá±rëôlŸbx&¦å…Ë4tp=in¡™*¢ L²Ð›¯8J¨‚ÛbFKàš±¥“%Œ›¹.•A›(f„Å”(lÊŽªãF‚à/ˆ˜¦û*jÿ‹yZHå¾–Ö=™J/um¡wÔ^¶ža>2!ù:.&Ÿ›a-ˆ¢‚¹&l—–Zñ#pÔDQ=ªºÇ cì[a¶9[tW¹8=iiVTGñ™Dy«pZ€ üuw·ª¨ïÛ¬Úå 9óÁ5%ˆc.årŒi ù†o”ó-1i&â›$€AQ[-LÀòœ¦&gŠä5Á&ë—^v5Üæûn«$)0]½!}µt6ýâŽÂœw5ü…ë¼{Œ°›¬:€íG®ÞbÝ¢ˆÛR¥´Œ0qàÅ3⬫ˆ¦jN/rïMÇá…SäUõÃë¶•ìIvÆÂ `ˆÝ„uDu[ “µvUDšæ­™!À²=½ÕDDJ¹ïkŒ? ¶þ£ë²ÿù5Õ6Õµ=µ4+«æÉ›Êé ³0 { MœÜQrëüÚg¬‹cˆÃŒ–^WIY[« Æji0{‘¶A!í ÛÜ!ÝtWX@¿y‘Úå£70•W=1Ë·ñVâ„XÔuö}ÅètKÞUºŽûjeã!s¼²ÂnI›»5Б/ãç¹îµ!ð÷\6XšRŠ¢ª>Š.Ä%”\»—‘øÖ¶-ûÅQŒ1²[Ø—ED"ôßÅÃé÷t–ÿ-áŒÆmmø‚ýç¥â·Ø ‘äN×Jq«ì/iSMõÈxÖÀ_3¶a®UGw;–¨ÜFÛ~;Ê5>'£ê4Ô†„Ñ´>õouqÎ:çð›ÆœrÉɹœë7NT[E˜äÈêà;Q Ö^t›uéNv°ßb#iyÌŸ'™Å¼’ÄZû.Jãöd*âùœ)í›ÑÇÓON-ƒ‰+2ƒgÁñP-M±¥f^?•cR?-ä;·fã³÷âÌgÍeVÁÁ÷…|Q?¡[òubPijb3¯LŸ1åìq÷žùì €õUê» *¤.~çøC.Š&¼MÄÊhý~ôèfŸqûgÃo]õOÃýÛ{"}}Ìrìs¹@¢”Ñ0ÔóQ#7g)ç[HÉ3í P‘7-‘js¾anV7ªGªUíHœÐÎuÚFÞ—'Ñ—O=†Q‹VýÙL›m¡¦Ç*£SUŒ‰þ#bÓ^¼ÇŽD‡{PuÂ2Ù7UèšÆ>i1˜nÊwã-'2ÓÅW-0yN¡È{°QTÞªu~)¿>ÏP|4M>Ì £Ê+ÑI§€%A°1¤$îEu²Eê›*. CÅê_|êl¬ìè§ÚÉvÆdmÁ¦¥7CêF «L¶Ð¦ê¨ƒÜ½wüë?¯…~â"EÄ`÷Ù]<«à-×B¤uòîO¯DQòõh0ÑÉùŬz:§‘tt—4‘®@]M·Íþað^!¥†è3b˜½,WêÛG:í÷Õ ¿Wð‘WÉ5cÉ¿4œ±–áõñ%XK´¬»ZÖ ˆÈù5¶,bTNÅèž>ZÊeä/,Èj’¥«+Ì#½ÉcÌ•U5ÁŒ2*Kc!ƒ'PIEU:ûÞ:L—(ã²aÝ) Ö=ýëUš aÜ¥ £lOÒTQO-)c\ñÊ4ªP¹jÙ”þÉ»ÏnŸ§[ÔrÎ1ž²v[| ¦‰ä³* •}ªÒýšÛ’¸*Ù!··­’`“ZÈ¢¢y™B44ì]\73glÏùÖ8ú”;V¸œeâŒf@.“'±ˆ‘쪛.Ýu.UNA@÷Åb9­K«æ–Z}×áJx¼ ¸t!]Vp?Í¡¬ÈmgÃw‰yò¾Íl€•^¦ª„Ü F^lôv_T÷wí\' Áøâ^eSqiñ¹ÖS)Ô Œ–îáóGÛ¬b3fsm]49n‰0ÌfÔ{…;;q?™–Ü–%O)3X.ãY  ë5Ym7våI|Á 2j*-¸HŽGsÞÙ6Ô«XuòqlÖµ‘Çvj‰eÛ´Ÿ‰@¦ÝÀ_y—E; ˆ|Ñ? ]åÙ]¼jk„õ…å̳ìf4fMÇ }ˆ‰àUz']W|ÆrudЬN\/–þ.ž«YÔíþ$²ewOÌ'ÊÈ®ÿʦÞù)}QSG#-ÍfTN¾®Æ#º«*Í‘!Ù¯§Ã°£ëˆ2Žª#®¨·¸î¤7<«Ë_›9.r|,ƒ¿ˆqaåñm¸u–VØô’&à+l´„‘Oµáõš6Û?M]³·°­Æh*i†äM}˜™ßf£0Ž8 Øwk`)ç²"yjÔ¥{Îñ©NDËøÊÒ@9qT H-»)‘ mÿ¼Ñ(ûá±'ŽÈüYl7*$¦Í™Q^6ÝiÁP6ÌW¢‰ ª*/ŠjÿåîÿÉs¶x­~YàRÇY2,±é†fåSò!j?å¡6N:[#$Ú¢.ÛiÏãìÕx““÷xÓ¤ÏuµÛfì²xÕS¡QlÛ¤¸à®>ˆÅ¬L”ë3JËhÎ3xP"5*L¹ž©8ãòÂÂn!‰!'rvê²69™L |C‘X:ip÷n…Q\³±×'°Â ;]mc8D‹°©¯v¹6Bcqë^SøLÁ¨Rå„s®É«2I QÍÈà(¹ÙÛÑÏe¹Å²»Ë }Éõ×5lÕ%Ùd,ÊnÖ96,¥É†ÃÆlª€2¢ˆž>³žgðì¯Wo ÆdUÕ”XUðQøòyÆÜã²t£*©ˆ¢}Ñ릹U›8’¯O'±¹žÜ¨ŠàðÚŒÜv÷qPŒm)¶ú&û ¦Ë¬žÆš+tµµ,â°©³IsgÃzFuÙódÖ1}dHjÁ‹ŠˆŠ¾;nšÉç5ø‘»SÃmWL«¶ÛYl¶rŸ!eŠá2?q‘U$NÄTBÖk‹æÏÕÙ×`5ͽ*ú ]K Fó»[€*ãL*È-zN:*‰³ˆF*½µòXu%ac6m}2ÙºÄ+–æÖ˜ ‡63ÝêM©‚¡2ñ ÷ÛêevœÇæ*jPeË.2̦^Beä"e"Ý)¢š úc0ïùëáG*¬ðººýòŽ_ÄòFÂù¡\ðü,vÔ•%´óû<󌩴 Ầ§W>¦Ü{ÎÅyY/LÅ·[/L“îª"ôTð××?dùW¤y0sùŽe•¤Ë&E–¨–Ýb(H*øÁêˆ6Ê#MÄA×}OãL_¤eLc¡>ÆºÊÆXMaªö‘=’z­×z‚Ž—¨£ºìZ:û(ð3,.†¶¢HìiL8í>㲉'BP…z¢¢ê?ËÇÌDùwg"t\[ËÓq‰.ŒV¿‡of2M›2‰µVØ”$>¸n½ûï—âùVPÏ!ãôbÕQCq«êá+& ;ÇŒå¨3-–˜ª‡Ü~‚+Žº[² _óÁL¶ÿ+bñR&Q‰!úQ³Œ}•Ýêy~C-•bºª·¼«¢ôJ t™=[yài\m…0ïFûû‰wíE]ºjSW ¯ c ÝñæHÌzûzse¾èÓ{%:ÔõKŒ?Ǿ3ŸŠß`zµ˜î; ã×TCb7$:ä©E(zqÛzSÊO=é¸*dª‚›'O¢öÐ+ñlÅÉxÝï’óAÛ2©Åé»Vû™T^ý…åªL¾•L`ÝGGR3Œð*ƒñžÕq‡D›4_MXfÓ›YrúVGKPZn½Éñ>É’4UõcÉ-Þ $DUTñ-ÛÅp ,ªÞ²+Uìã8,¶}¦#"ƒ1Ý}ÁouDGNÞ¿^—øg‰ª0è§û» ÒãÔ·ö– X:¢¿Q;­ì¹’“ñŽã ÔXÈyOn‘eüÄæÆ~k-·­åú GîÇÈqeKêW«¤4©ööi?Џ‚»,н±Ân^ÛÚ,Áƒ_°]]Kò²LjÞäfn)™Cr’kÊÙ!4€ëý‚dˆ@M:ª$ˆ¢¨º ¬Iˆ  ž=&$™Ki¥µ™ñRl˜PÝzYª¡w¸â÷) ï¥Ä0ËòRlàB2°eù–9•ô× .•zÊ“0Þ­ABq·ÝÙC·gê¢ÈL†M¬º›¨ÍÉ>'cÄÊO©œ Û‚ój=í*Žé±'Tݪî\”þ{Æ=ÈÔaŽÆöU"«°C”üFÓ¢|[#õ¸;®ú‡iW5™õóÙ ö1\Y}—pq·THI¢¢ìºÊsl&¸ß©b¤×$ÀD¤¸³áDp_bž+©9°Ÿ3•5–QMÔl;CÝÕV=5OŠeÓœu¬2¦|7U‘#0áL­ˆN½´p' ¦ÌMEÄàÛÞ·Äòª¶nqûØåʹäèb½P„“¨!Q$EN©¨Ÿ*¼ƒÈ.ãÙ)8Sø_œŽ¾4ë[ªxŒ˜; §ä§d[¸@ + Q\6SÔ ÞG8o.µ«Å(ç]@²r͘ÓäT³›RÖÅ•!ùQâÌ}IÙ–rm€–ç¦Ð<^¡jW3Ö6Mpo)ØG‰óFÚ/£ElòŒx™s A%gö§TíyQTWM>àû¸ËÍ’n$$›¢¢¢îŠŸÊÆø‡‹fü/3ó„‡é±+NÿÈ«;|…áò,áï÷ž&Ñ7êšÇ0 F*Ä Æb X}ëÜóÆª¦ô—ÏÄÝ}Â'%ê¤JºÅ¬r_L[ʯ©bD—Ò8̃e&l©ŒHÑŽÙ«míÞó6ŠEÒ¿;äÌajøú-J̨uÙ__¦°áFˆàµ: r"ª¼ ¢ìg ›D5î¶2³®qÖJ|ÕFa´o7„2÷Œ‘h7]×ÝòM@ÉÇðú>6‚Ù5¶âIM£~t™”†f3 þ9ÂåÄ2(®öª§^õƒKWW‹Ò°nÉv46xÔÞx…¡m±#5R"Ûª®ë¨¼wòû"~#2¾}‰ä.Z3Vý½u$¯Êçv£büªã9À!fk’B.ÒAôÊ´.aûpˆÀÛ?HX9HØ£ÄК© )]¼t»÷'QÛÇ\›ü½A‡Ê´Ù‰ æE] JÇ¥År·ô¬ûl™&åŠ#æÓN ¨I²whfsNg'1T1Ájʬi…è½…²G¥íûOšïû:jª‚ª%c‚Í|ŽÈ¢{´ú¿.Ìë(쉡}º·ÜR”Mª‹ ‰¸¨J*‰²uÔ;f®ÃžÃRb<¢AÞÓ†Ùvš!&註*o­Õ6Onº¦ßn»¶^ßÚòÓ•Y<+êÇSg Ø0܆—ìv_­:édð¾k#Š ¦¼{¶¸ë¾>ãHd²aïídÕötr7×ño2[6äF-¦¶Ó°nÁôœZûQAiÒp=Õ^í÷W»Rã˜ö ÜfÎLú*ù_ sfpÄVš­‹5VýqŸ_Tû»œTåDAÔ*ÌÛ—?!¬‰6²ß:šŒµÖm3+ù«ÊÁöÇTº¾!Þ;ÊÈøò¾NEÄ2Ý)™FÝÇêQÅîvË^‚Ÿ}؈½¤›“{/…NUŠÛ1wAvÀɪµŠ[¶à/ó(®èB¨Š*ŠŠˆ©©ÜµGTÌé5v•ÙQ\­<ìËÕïGb¬ÞžŠëÐëkÑNL†b‚) ¯†å©¥ã4Ò±ºGl"Zr•L§‚žòK 0xüwОy¤Büs2ì÷D‹GG*cÔÖ°¤³iˆå0×¶e5¼Eï‰>1¦Ê„ÙýäßÞ!^‹©5WXë>kã[féùJž…§¦2Ôö[Yö®TGeÒ²¯ž¨NED˜bI<Z›KÍôÏÍüéÛL×dG ûy¸ìµ$ŒÝûPnrÕ“VÝ7ˆª¨jH™Ênobý„œçœ’Í%'.p—ôšŠNï$T8©ß5oÒ-¶Ý“:ÒÎSPkkc».ÂsÄ€Ó,2 n8d½DQUU|µ{óGMž_q®Ipá×pƒñ;] Šj1Z°­}©dâ,·[-•;ƒ´“dÔ\{ægƒ:ëƒ0Q£²q ÆJ‚ )I ú· Wî½»{ø8‰©57P*ó,7(ˆ‰"âÔêùÑœMÄ‘S¼ WÄHW¢õßTøÅ È Š¬ r^˜ø°Òlr$›Ž¸¨72UÛÏMPN¶° ‘Ò¾òŽú­YYP¬ªßIdIiöí4ê¶BIâž •˜óV?—¶I"êÝÿŠŸ5÷ MÙ2žØ{Üp‰UvDDM„Q׋쫭k8{5e+q¼Ï…ÉÀ9Q©ÍeqlÞQ`&é¶l ˜i  w@ä ¾±Ún]Êñè :Å¬Šƒq¨v“#´NMv: ¸BámÜ ª]¨Z·Ë³ ¸˜æ3BÂÉ·¹œ~›,¶žÕñ"%è"(¤K² *®Ú‘!ÚñO¾½¬Õ4e&Ë_ï“ï ÄðdÔpWß$EÙ!ÑãÕq©iàd:Øm£Myªøªøª¯U^ªºëÑ=«á§®hæ56ñh\…G*3¾„Ò Œ]'4íï]Ñ|õ€fì\À°È¶ö8_&âÆÁÚ ˆ¤¯">­'j‹èÛ/n(j».é¬^Ç© “ËhncúhÓox’“×OUÅtZp—mþκ̪«2$¿Àøå‹Œ¶+-¾o•}ÕÓ ë^5%OÀ&ŸxWpïÕV[ŠÂk—aÇs"±tíËÓŠöÚ`‰×Év+¨£cl»*§E]“qÖFy¼«p/à›¯¦º%yà”ËJ’å6ñO°Uˆ“tCUáEÛWr3Û{zÄnÂê õvR¡¥\}…µw4ï0ꊓnö¢™}º¯õ‰ÌzÒ^='™Oc³e ¾{ŠÜrÿî@QK»eEÛ[*lº—C“TE¼¦œ=²k¥‚kì$óO!T$ò]"ÌzË‘¸i•ÙÇœî—c þÒª{óá¶ž;þ+cûBšfú±cÍ¢ÉÞbÞùÊBi–²†c¶HÄY²AÕ¥>ÞýˆT»P\è›%øgØÔœ'ÃY‰\ÜtIs¤W]I/Qº†ß’€ü³ôÕLýÞÖv £|™ŠÂ‘'‰2ww+`ÑÛU:·_DRÈ+£ÝQEE–Èô!÷Ñ;“¤K*ÙlZTÛF f°Hëc>À`Iº—éMcy† Ï0©+›‰a0 ˜j$°ŠŒ%sÒT…STÓ@¤DÈ¡¿ß計¸5ÖT’ñ»Ñ…Ë È(üGþëaª!"öª/¼;/ž©>dñV ɸËùN™•@[¼5ç¥6»ì„ü_‰¿]ÐÃõ¶ÓÔ-tmdâ~äž_ÈYz6=ŠH,©¤_$ÕO=BËî³înÁ§7tÅÕ¬’°ˆÊÎ¥f#[1,¨æãhÛ@›Šî«×X‡$b2¾3Í*ãÚÕ:¿|[|•·õ\l·"EO/äaß.øüÃwÏ•I`•‡‡Ö ?tîãÔVBqT¶ðÔxpذᴠCŠÚl 4Р6‰à‚(ˆš~$¦•SdÔ¨¯€¸Ó­’l@`H¢H©âŠ›ië—|¡œf ά‹>¾õeâ3‰UTþ±Uz±ÓßïÇ^ÝüCmDÁ9²O r¬…Œ7!t>È“mÊšÔ{cÍUè(¢çõšT$QT訽é¼Ìó†(1Œn!͹¶»M’"u#%T÷ˆ•uÔ@äJ÷èøö•ÿ‹â~!•àÒ'î®nÛû®Ìp}æÚ-Å]¾þë¥Uê«âº‰gcM„»‰¬Õc•1‡cc%vb?¬{4Ïzþ»„‚ŸoM\åõÐr{¼o* ¸žuÅPåyx­¸Fˆì”yïIÆÉµ3°Sq$-d¹Ó}]ÌuD Fv#î±\ø½×ä›îº.5ØʶØ"n‚¤»ê{õõìD“lÿÅZ>ÃbJ‚!ê¼B›™öŠ'quÙ4§’å5ú'UK¬G/ø./ô´è5È”Šnš›ë{¼×Ĉ£²HKõªèZo’éãªô’¯EOçy DÒ9äµWà½Qk¦1%™£%þ–®k­j#IDr Ø«hIŽà¨“n8&©²ôëÓËMbÜ}E&û¾~%îvöGfé³:- 6Õ~83 ½ðmÍÈýíÐvN½½Þ?˸Çq›äXÑ$J*(´°ìBï«ø©¸¨ˆù ®éäPÛ8ÖFµf¶BŠIe™M¡Š8»ôßmüË蟛a^²ã{'ŠW"ñÌTî(jK»¶ôí'A!OyöÝ1÷‡eN•ܕǯEÈòjj 78ÜÍ“])m˜Ìɉ"M+¨¨Ú—j¡{‡î©&¤ñ×!_ÎnòÖiTe¬ÄH¬«Éez !?êt>Òt –Ú‡ÅÓ\PâŽD–ëœS-Å^ÊK“îvE ôduv.ëл›O-v¢*ªôíOÔ¬C‚÷'ò3ëØ½3 ‘ ï±Zدs1EÄ}ç?¬Ó6¼Ó~Þ@ãõœqTŽGÆ ’l¢¦É/©9Áÿúª{M´Ø M4( 4‚ )ÑE6DDö&‘S¢§T]r'Ë›þDÄw8˜ v-änî¹­úlÄ£ÀSõ]%ðOäs71«&޲rñ¯š®à5ëÄ–2Y_d»"uwóÇÙü‡ñ쾊EM#©ÁšÚ ù8Ùt&Í<Œ <—M3ˆØ¿Î|_d^:Èå d•¬"ýÚ‹—7I" ÷X•×dAÔ¶°û—"äÕ)ÿxð ––¾þ°üÆT}ý‘\;|‹JªH(‰º’ª""'Šª¯DDÐÍŒ÷­À\ida†ÂOÜå7ñ [záäTØâD$PŠ+Ð˹ÏbkÇr%ñöªë7±n¾F‹Ë—Q[’K‘øò§WdÇÜiQ¨Íª*"‘w.ʽGaÜ9]SÏk‘.fÝ……~A5÷Åê©Ôm6f‘‘„Dp D;S`ÙzïÙ¤õ Is dH&[…Ùì„áö"‘uÔ¼i‘òf­O™äIÄè©*ÅP„‰<Á”"û4Gžr,ØðÝ]ËÄTª ~ÁÉE)o'µHÇf½hgÅ*îS¤²’äûI顪þv2ÃL¶ üȉ¥ã´ø¯ˆ¸h¿ ‘uññ*楢î›ø)"^D/ÅVôéä96Zê8žeÝg‡öš=²Ùú½ãDöj5ŸÔ=ÆùLÂF „çEê™çá´+!Dl•|ÎÃòÙugù¶Sl·‰uf“£¤…vz6#ê®÷*/bvì›Ûô꺕ɶׅ,,·óõÎb?!Ì‚\ $hø«À™ †¢Ð{Ý».ÈIªÚÎB©^1ͬäx8¥«í‘ÌW×vJ‚Kë&Ê‚}°÷ðÖþ ¦ö5g†9ÉÇ÷œbþYl.‡“pçBOºÛ½z!jÆsxíksí§5ek3áZW_›Yᨪ« §io¸ùjÃÎíÞ?"iª©“zV ’9M|V¿ÔeÑC^ÑO$EÔi¼¹âu5‘Ã*ªÅ»Ööíßq£9rÛRXÂùªnÄ~»’¡žÁª18øT$I¯ãAÑø©_!cJøøÊ"ëP¶=œRRß»t]-¤{40Ñðnß'ž*óu±Éw‚0ûϺE°6ŹtM–ßйȭã›m ™#õí¹%KÔr-|a™ÜwWwM¶ó×ó}H¸Sø~õ›{6šûòhe'Â]Åéâ‡Â4OÚ_-A´­’k¬£µ*Æ—pu— ·|Ð…QSèå@€_õí]+‘1F‘}ç.lˆ`Ö€§š¬§ÛèžZİÆKÔ\v±ˆ²ä/‹Ò»{å·9…³Ë2Òa/© úˆûE=𲤴e$W[Fr,ÖW§snjì¾Jž(¾K×Yœüv⪪Ίõj¡à!­îH .8óó‰\˜®HTšPDhznž:VfW7.‹g[bÊ*!ˆ>Ñ¢ø.Û¢¦è©©Ö¡ì­Ù¿ yá4¥dóÐÔ²„Z‰èF‚¤é*{ä¾Tß}¼ÓR«æ´BžË‘¦2IºNŠŠ§Ö*©ªLRâYKÉ8bÎwÝ8âîá·PiùsŠ‹×c€ë ‹ç×èùpáæË½Œƒ+•›ä¬ ø×â1½fEÄý“›)·ñQÒªõUñ]QW^rV)‚;WfÝÛ¹klJ¯³Vu¦š“ Çš7s½P“¼G¢í¬~©eRÚUb£ùõ¹2áØ± J|S d¦¤Š„)·º[j~%'òô¢Î#5[¦-¡VÝ¿ ]õe`¶„ø#BÚzJhgÜIºt]5=úH4·y;«ar0éš qÕMÛd¥WÇyöy=õh» }Ñ>‰3f¾1aBdäL”k°¶ËB¦á’ûQUu’s-³Fͯ)Ê4l9ºÍ‹Bmš8Ûˆ„Û‚»‰ &èH¾ÅN¿FMžAÅÙ´È"@õd¹¶Âl¦ãŽÂÙHíRAê¾; /EÔٮ˪—.¥iâ¤)OA1BlL–šG~òm;w×ñ ¬N±"}‘Æ©i´mö§E~¹"|Þ2QÄD$TûÚ‚Æ•n-"XɄٵÝóVÂ"ö"ª¯ÑË~ëž(buÙ…[d¾ïæ4O~Y9?hØÁÔ?Ft~/ñí5?T&ßÉ~ÚR§Ö¬·êÛèËkmãÞUgxL› z»#Ç£5:͸aZ-d?Ô*摳ªæÊ«Õ•îÖ,Ì£‚ãíSÁ\«nlÀ"`wßÕ6QBê‰ã¬f¢C0ë'Å,>VAùDЬ$u¡íÅ-·àÍLQ¹Úi{48¼§Ø4jÒÊ\(Q ×"Á‹&IœxqÉäCìi½¼Q¹KdDÛè©ãÊlj‹^^»‹Š‹¡÷Û¯sy®§Ô11þÙ5&F<(MxqÁ6ÚhPDòDM8Ð8&ë(„óBH¦_uHSª"ùoã©PßÖp$!ÆÄÙ4OtÚt¸WoO·TÜgÆ95¦3OȌʓ›á ¸ÖÁ¥h‘$I…ê÷9 ä8¾‚ eØ[—DÛQ`@Ž Âd#ÊÒl ´Úv€ '’"m«\n»Ífãé¾@õ[{µ|ÅK´ÕT|ú"oÓ~‹ªÛËåÖ Œp&‚†PÓtDT‘o-ô›.þöûê5md&+«¡7VÅ–ZðlìO¢}M‹)"¾Ò;°ç°Iº/‚¶à¯Ú$º=\û‚¢?ü+ùBÛ…åÞLTU­íÓ騈».-žž£âƒe’Iô~Ô‹¶ú‹è ûŽÝ Éò”±gå\G&rÒn²:¼ÈX°@;l©Úh›ôÝXæ9løÉ¿@rvU`®zž½¤çJDÇIÅûÿˆjÞh‰¬ë“%q¼¢Ìëq…^¾%AhÝžÄyÄqÕöªýÞeÇ\½Ê%‘“âU·Z— SÔô›BEî"%^ˆ%ÚJ©¸ùp÷:JõáF#ÕKâFr+î8ØIFT•:§r§Ö¡×Y×'9m>#ùŽUø|÷A#×GyÀlP‘·EÛǵ5A‡†]aWÈX¼‡2eL"{Öq§”d‘6BmmÇÃÃ\× ò cyN7° Ñ95dÇøW_v2§s¦›.æžu×ç¹EºØ_\3_.¹É °‚!ÕÒŠø¢ì¿N[^)Ù;Ç`_°>K2µÅ%SëVÉ¥_£¯‡ž¤Ìʲ::’¯+ÝiŠ*£~ÖT4i‰ó? [»JN©!õð^ÔdvÖÕÍÛ@¦®“:]c€ òw³µÄ!ëÛ¶ê5QËÃ)¬ù¢D˜â$ãNGøqnICšÉªw ¢)ï '‡Ñ-ct‘‚ä44sOZ»XÏ’§öˆZø¿Q>Óõ½_.Í»»¿›Ròêy^]–Þ¯U%›}4ÑU|÷O¥eN¨º‡”ãð®1«ˆr@]Õ‹,9ê¾’iØäù¶M¼â!8¨…ç­þ˜LW½\ÊácñØÕ%c¢ŸR8ùþd3ÊÂ5JD­”âZL{áãÆ$h»uí‹Ó-•KeÛÇmX¶y.;iŠTGucWÐä_Ä s§$T)*¦ŠätUŒñûå¹+Ĉ›¹!Œ]“+èå yyüL€øv6úýGmcÔ,¦ÁO]'ÚM¶(kúKuúâ× «fgÞô³gep¿iÁA5úÉ}‰×ÒGÅmã0Ŭ·é»Ü¢Ë#Óµm‡¶Õ^:ª=­ Txì3P!¶KviWrûWP¯\©ŒåÕk ¾ÐöYTTVÀüPv%éõê}ÑbµËkhÓÌYNôQ öä ƒÂâ&Ⱦ ª¡.Û®ªjÝÇ`9[Bê?IšEn+¨ª¨mêª*怜2,^ºæ{‚ÜÉL‰9Ú>EÑIØ[¦¡ î+[f•Í£0=V–‡ª6 »~χժGÀ۸Øcæ ˆü—ÞFQ|öÒ^VaõPmÄÕÆçµPÀËÄ>è/_Dú2ªM¿®HF_1x\d“ëGWXvHkÜíÝ4)Rþ8ÙWÿ= FIi§`ä›db„Œ7÷ÝQUß°|ËÁ5t) Ë…1 ~$¶I ·Zq€À‡t!$]ÑS\/t=\»ª +í ~!´_íã}5×8å[ÓïÖ­èÑ>8Ū8‚ê§&ÂK‚ÜVÕUò¶¾ú ©&ʾJšþ,ª@)e^.,¦ÐVP")1Ü«·x¢¢ªyjK˜åôÀ„HÊÂï¦K¾ÝÈžì»/‚êκ›*©²¼ƒKÁXÌqÅ6#TA÷¶íꂺ›M–Dƒ÷ ~aBôFxuZ…ÞáïÚ½zxlºŠ -a–R,¢j4ëÅÔÏQE{‰¾¾ïÕ¬ÉÛ–¢´XýóÕ¾²m –ÓtSî3ܾ´ÛìúDU7BTEO©uŽEUÝ*åZ×·ý„[)-Š~„DÖ-‘g³òU¥Èk,k&1_2oóè rm´ÑmÕß¿bíRÙI=”c-+ïÀ2l+N2¡±@hU·‘„vØ“n¸¦rª Âä ”ïUÛd}©,–ëìØõþrÏøÀþ®¿Î™ÿÕ×#SRWSd´<˜›¥²Fü¥\†Ý#*ºØ zé**¯EÕe[–Í*øLDr[އ{ÊËBÚ¸^÷‰vï¡3 »°§Breü—«ú.è$Ñ;Ü`‹ú†j?V¿Ïc"y~3Ýk)޳¢—¯M`ßo¬ß^èÎ&ß{Gfª¾ ü¶Ès=ÛÄÏúšã{«þ1Ç­nçTïkc* ›Ï>Ûî¶Dá*õ_sm²[þ€ÿd¯ýžÞ¿Ù)ÿg5ýM² OþÍgúšÿd—ý˜Çõ4?ý ÄvÝ7Þ­îu›Ñ@ŠÔt\‰•A‰‘@m†Br“M€§ADO-^̃‰ã¹n$Åt‡3Xòe4ªÀ“hذÜPU5UU%U1ìÙ=gXòWa±‹ü‘†gàäóõÏÆr ú œ§ŒÕÇìT袞;ï¨óîVexÜ·WØdÈ*¯ÙߣOa/ûÿFé¿N½<F§»ƒ`yf'ÊÿšvÁHm9·¿ÞyÖĽÅ4Ý}ÑM—ÅU7]aÜ·±~íÊuÇ34o ¹%誌¼»&ÝE_í\ ʬv{²ò ›–6-“›¹9Y'‘å]APWÉ5δ8MRÒ³k‰6Ý31[XñóÄm´H‚G¹Šl½WP±ˆüy>“>¯Ççǵ¶~­EF@°^¯|ž¤ž¶Þê’&ßwÏ®šcÐ%ÇÈé¬nj%°,­ð–h`*­ì…²*’"ù)"ë†j†ïÃÔbN7e4/I%º3{¸Ñ;QUÃ_ök<­¹Ä²9îÚdr¦Æz%6ý=Ô:©uUO.š‹(› L¶ð¶i±Š8(H„žJ›ì¿@*ø!"ÿOT’?VÂÂæcKíìä¯éMbÿ”Zæ,‹;ø¼Ä-ÖZ´?—nª¨¾‚~Þ{wtÖ/üf]ùbVGL„·U•ØýÊïwímÓ»}µÇ6QBt ¬ò¦<ÈN¢¨:з!ǶTè¢+¾—ÿ§TÛèÏû½³ªoñGýÞ¿ÙÕ/ø¢þï_ìæ“üIu¯ösIþ!º×û9£ÿ£ÿøµÍkhÚv\×Útcì MÇ2EßÅ7Ó•Ö_–¹#õîx›ŠŸïê=ôsȲzWذo&´‰úé”n<ÓeÁ…!ÐWmåFÌÁ„KeTEMÓ¦ú—Ç·Xeuüš[)õ™i‰¿!kà, ¡‘-¹M«`2{›ä™íâ)·ÓóޝºPó”¸h?â®ë¢ÉûĵtüzѺÅ|§#Ó’! ³H†:¢¢¢£ªˆ;mç« r)ãvŸ‘EÈ,£*6(í¥<­½O(6AuÑîî_Ý^î›k‘j₹5)žª¬Šõmõ÷2‰ª{¨ä„żó$ö>عÿÞú~ò¯M—¯—³Pî/²ëxÕ|Æ'űˆû‚;Ÿvꊨª¨£æ©ç¢T%Nï½·Mv÷/jx&ý5·q*'–ëå®îõîöï×J=ËÚ¾)¿M~ð¿uׯђ^¸» Md©Cõ˜4J úKdÖ BðöI®£†2ÇØû£®ÿçšêUãOeÑ£crÛ£¬‹7S"Ë®îÕˆGW7½ Mú§ôõX¹ %¥ÄZƒ=»GâdºÃ@'+v ÀQt·T]üw× R¼¡qivøûº¸ÀKþ„O£on®2,½ Z«,¬\iÁld0ðÇs±{ULQÒAîN›ïì]lºrœ"¸îó€­;èÆXMÂh^q$!úë#½{TUvM¶÷¾ŽA—¾ÊÆ9f£ö”W?¦ºþFËÖÿS‘ú[{ÝÿÃß ¶ÞÝõó)‡úiŽòöC&3+Ó¶5â1nÆÉìT”»jXÀq¦g“.$d  òŠúdà ‰¡l¤ˆ¨ªž ªÜk0¸; ø·nG¶‹[‹•u´gZO ·ç/¸ú§)Q¯GÔCUNº–îiT6“ÿ©m¦ Í®BRDSpc8àö÷'¸i×ÏMáVð_‡ÔF¼bòŠ,5F–ÚVK‡1=EšSšî%Dp”wÜ•vúg ¢NPÁØÉx!Øcr‰§íøib¿biStEÝSXæI’ó]ÖMbõ££sƨ þ[d6ÛÌÖÁ¿“Píqå%4ðNåÔiÐb|ppâIm[uàEVÝlº‰".Ä+à½5•q¬¥_‰ã»w¡@î]ÉÊ™j²«]Oj+'ÙöЧӄvE;b}Ù1kcÃþ˜÷£jŠ}ˆªHš¿³¯æ;îFn–šL¹´“ØØ-¨’¼¹v©§oj'ת JËØ°/ŸHŒÝȆ!©$]¾‘¸†½Ê›¢—gvȺ“Š}ÅÔêÀG/äUEø–«ÅQUåBB÷QQKµo·¦°ì޲÷"Æk¤åÍ×0å{m£Òi7Px}aDh‘wEÝ~°]dÔîR_XÏÅd«6Á(8Ø®Æú¹ê" b»&å²îºÆ."„ûdz0îÆ(kcúÓåí÷ÑÝ{¡*¯·Vk_m]•…¼¢²kЗÕßdpI6]—eEò_§ ㆽïâûfäÞ oîSÕ˘E·‘ƒi¿Š–½ÔDî_tSï–²,³ ‹Œò¶rzë&§UÚ¬L¢ª%GcN@i‰ˆØˆ»é/r¢ö¯qt]Óhs‚ícòØmç«_QWc™Š4â‚÷®Ë²ªo«7E{âñþ$ÄPfÝÈYŸj0ÀoöýIxѦc6O<êø6*D_¡Qê¼®—̯#̱Æ~ºMYI´±†&ø•6ýqÖî/BTBÒx"’þŽº°³ ™Õ³Ø;;xbÃæÛ„P›(¨Ão2Ås©)'orúi¶¦ã‘‘JVaaSŽEñ#¶±dO?uÅ×åš|Âü¥åévz}¿ðuËð=8Ü›‡c¤Ûd7«ýz9ŠžÕDe•_µ>Œ`mqFm¢[Ô|QMvšã,zS°d G%DY ÃŽJÑ¡+ïÅ¿´u¶’©š:˜Œˆ×ÓÇdc7µ÷‘¡dP;wêˆ}1—Úå6 c¯»+º¯ªƒ>ÒTHPÁ¸*üóõB,(@â˜!¨8ê**l¢$DÑ <WÁQ|Ñ~Œ'•'8§#>ÝAIi,“òûDé×amÑq°ÒfŽ6H„ÛƒÕWª*/±S®²|÷2Á”Wó'ÈI« àØn?kŠg².¹lŠ¿wEI³£¯²‡*fwkØßç—Hø{mR&‰‚QU^åMÕE6Õ1Âhо #òCm¢ªþTû»Åž¨ž?ù{Ëþ ×É4$†ˆ@b»¡"õEEOTú0åÅkâÙËÇî?0“[­´Ñˆö‰zŠ=ÈJ;*'–¯ëïðWiKa&Ó«@ùHu’UKÜ#^»¦Éã®<Ã[€Âßc¹XÚFø–VA) ݤ»8=w×$Úá¶8µ” §²mãwÛ"¨ÈIÄ7›S Nò$DBBM“d]`ãK¹@ÎÞ·”N8 Åm ÀïÛ{tÙ5ó5ÈŒ£‚íãë6ªò“oŠ#‰¿¸›˜ýíql¯fÆ÷ ‰&æ/ñëâzC®§¡1’DNþ¾÷_¯eE¿µ²ÆÆ-o_X­Ù¿fáFkuo×qÒ!ïE%ê+Õ‡_}Ðe†œ}ã^Ñî"%_DM×W¼³`É6cWƒGu ª(Ƥì½Ef=»ŸØ jà ±qÚö‡R`M†]öòfØ„۬º*6b¾(Bª‹¦8âíçÆ,”ËŠòW•I`}â©âøHŒ‹³{þñ½¶ê›%Û»¼R<»I‡*PºóJñ'MÜFœ%ÛÏmE­¬ˆÕ}|&Ѩp˜ÛððþFÉ⾑‚V8c…R< ÉW¬ªˆ¾B¨cMÄñ76E}Sî»â»i¦i¸Ñ£6-°È"m¶Ú ˆŠx Š&ÉìMLtטëJ1-$A8òf`’#õò^lI@ÅÚ_ ‹ÁQu£iÆëàw›Æ®¼ë®š¸ëÏ8]MÇ ”‰WÏU-iˆ^]c·n|M­å;?ðc }TîŒØ¸ã›6ªŠ=ª*½wµTà ¸ÁÚÙHmè-Öº„þÂ=ñZ#F×ÓÝ•|×eèšÌòçõkxwb¦;ªÛ)•ë–ËûCËõÑÉttmz™]$òŒ,…\K|}ೈ-íúÎOì%Ö7˜V.ðrzȶqÓöRKbâ‚ý`J¢¿ZjƭǤF ÎGY1ôd5Þ*ˆlºˆª+ÔI¢õÖcg|‘j¡e% ÈØ»6³o¤5"(¸Í™i?cuçÀ€H[m;Sn»ë#ĦÈr$\’½ú÷å2ˆ¦Ú<;w —BÙvÜW¡'E躻]hõ—糂c¢LµÎó+Øôp ½8‚ê©¿)ß&bÇm ×Ü_ÅWQ~a‹dáœmþkÉÕKÛ w^îbâEsHC`8h¨&jï¦Eº §FŸaÐ}‡À\aöÕ „Ä“¢¡"¢¢ë"ʸëbÓ”ïâÅ \€\i¹Ñ*Ü%nKÎI‹m˜´Dˆ¢£¾ýʫ۶«øÙübñeåíM¡‹vVYD¨ ›;Ž-,Ï{N¢¾ÙØÎM ãªçl[Ѝ<ÃÀ»µ";©Õ·[.¢Iáönšcä‡ÊÃ’ê1‹ò’liôn5ª'HÒQ:w¯¸çŠ*.úEEED!$]ÑQ|Íùfã„¶Ø©¸á*ˆ§URU舞ÕÓÔØ§*±ÜV2>MèH+³‘iГg]_{î–ë¶ c¸ô®©®ñÅTˆˆ—sqÃ^¦á—¼D½UtÃ8CÙkt’ÞÿY1š•ж#L©Kîp~· tqåBVÑ•TÙÓn+ç\ÁqêìrÖ@È †¦zhãl4Ó††Û “»’6‚=:êDÉ„X‘7åÊu{A¶›#2UðAU][ó;ød‹ü.â?äø¸B%[zêhΩ,¶á :2ÜüC@.ý‘6ÜvÝ-±›f-¡oÚé4ªŽ2~m¾Ñ"Fžbh‹ô+jè¶°ÍPŠ$ÆAö•SÁ{BMÓÛ¶¦ÙÎqªÚjH†ü“Am˜ìëÚž‰²"'ÔšÇÚz¦ã»8c2…«Ò6EÚ¶Tþ&L+ÞïjP¬†Ìšwn‚®É­‡~Ôè;ªªìžªõUѺñ£l´*o8]@Sr%û7ÔîL±ŒL[ó¦Ia—§¨›85[¤†×ÕøHÀàÿé>…EMÑ|S\ÇÀ΂± ½ÍLª¶€ÅtæÉ‰õÒÚYu²è ãfŠ„‹õ¦œ—Ã×LB*™q¦Dë‡7ê£]?ßv7ÔÞf‚¿‘(m8ÖÈ•Vé•Z÷Kþ"ÉŽøÎ'Ö¤?f‚M\èöQ7 ÁSê&Ô“[*m®ˆ«¾ŠUµ„Z¸À›œ‰‰ý“Š)£…Ç´6|‹=A_¬iY¬h½¯YH@`Sû%ú´ÔÎY¹fMp’8ÏQ›V"¢î):Jö½-SÌ}Ö÷òTÔxq#µ FѸñXm¦›è ˆ"ˆžH›jó Z(Ó²¶›f°ë,±øê*ÉWº½är‰ @Å}Ñ!ßÍ+9-§A*sq vÒCV E°ŒÑ,"2Pu¦‰MͶUqÃS5良j®žâ\~AŽ1Nm½Ê·¬jj÷µNɧ‰¸©»Û}ÔM½©«›,f§Ua¬±ù´x=„ä8ÄŠ-¸‘…}Uh6"QÊšþ%¡Ÿ'ËÄ(©Qy<‚[ øRA|ÑÄߨI¦àrµ[p")#q¹ ¤ ʇUWaø¶º¹ ×Ï»pßÀ‘4ĨψÒ[cIhÛp 7БSÁSSèoa…M›~”ØdFb„„žð’l¨Š›.š¾,žêýšè×ãõ·¤¯ËÂS›þ”…DpБ¡õU<~Œo‹1§ ¼›˜.âbO*“ Í%[ k·€Ç†.¸KåÓT¥ d…GŒ×Eª§ˆ> E†Ð°È'ö ŸO|ÌÖ°^H\S•U´ÝO½x$Ÿµ+çzO}Bn.º/T!]ÑQ|)Zâu¢’÷ÎpÂIÝ=€šËX‰”RR[TÔb|2ärÇ'‹4#¯­Ô4x}EtÁ‡m@¥õ|öøˆ2™›LÀ$ÇpmI£VÌPÁTUD…ES~ŠŠŸDÜ_"iÏ„’@ü9ñ‹Ó—c+ÝdGS«o2^ðª}‹ÑWMñW*8ÛyËM˜¾RéAÊ µÿ)¿@” ûö7ÝÞÅt¨¨„„Š„*›¢¢ø¢¢ût¡Œâp Šó÷™'Ô°ÜÊl#6¥]DÄ6ý6AåRPûª«Ómµ±©þ;A€œ‘b³IL[dRûàÓÔ“¨êÊ(ÌŸÜ.¤(žðí²Ë´ vO£]a"¦Î$èÎC•tRAv;ì:ˆ@bª>½;[ ÊŒòv½ð4óBEý)£˜x,:‰î*©O£qú—w_=á8Ȫý©¬Û#Çólîºf?Eac7çï>Ç«9ºÚ¼J=›¢tóÖ=gqšgNÙÖC—*9ß<Ó^£ì†ˆŒ‹k¶ä»uÐÌk ‡e<qŸnOZ<Šž}Ó\y~ÄÔaɲ:¼j1'ùG܈…:~ pÜÕúÑÛP²ÆíŠò’Å(Ó4SIÑŒ*r 6AFEMMG·ÃÅQ5“âWÖqì¨ù Ùðq1ã‹`.=ÜÌYòâ€(6Ú£Í8ŠHá®Ú‡<­‡dÝu¢\bØÌN`R>möHضۀùþ*´-£@» ¢í¾‘?B&žã1|Ìžþ&ÉQ;ãc±¡8j I'FÛñEêº\KŽñË …ú¸ÎXY$VÖLÇ•HQùöîFfd›í¿’"lš…+Œ 0ÌŸ²«YXüÖ£Öä4* 2ßmòzÈl_4õ{½ÑAV‘<,ï§³‰¶¯,‰LÁŽc£Šˆ„­²Ú ‡r¦ë²xª®£`2Ø5â¾>XwÜÍ/oÛÜ^­m/ŸÅz¯§“#·‰&§e?+·ñ°iŽ™ÈÃ÷ŠëجÃUR4‚cÜý[„ª»z]Ío²zbuüÉØµò"«XÅâ 58G¢»W<cÎoh·öŠkeM•ó1¼ºê.=‰ÑÃÇ©!§àVÁio3-º™¯™©/šý|b_0óJªÛƒ DèßåUf-8ô$’ ©ê5à»!"Š–‡‰PýÕÏ“Ù=ìV‚ ùq…ºùeSZi$D†ó"–}Åõ\õ½>ÎâVÞeÀy—„M—›$ 0$ÜHI7EEEÝ>‡1ì¢?5Óãš³2¶úµ.÷™uµê„Ÿbî5æWÒÃyÁsK-öC¹{[xØîäyz¿ºsÇt]ôÛ­ºÓ¢†Ó ¨@bIº’nŠŠQSUOÚ×32Mà´¥c¹FœÐmIðS5íîEDök¤Â¦»uS-±ÞB²’ÃoL³¶q ®dzÍOºšvû„>ê´b©¨µÕÙ ¹tx펄TÅ´«G$—,7³°Iøˆ‡‰‰wÛï¾ü¼9Š™xÆ;“È¤Ç „/0P°p‚o½AÎîåpÜUïBAµÊ?øNãý Ýaßü†·ý¯£Ž¹ÆË-1¹rjî)"£^¼ŠËI„žØYx•QuòßW­dÏ–;$Ì¿Œ£ÑRX¬1ã<ÑÇyWnó÷;PöQûº‡Žcì9¦¨¬0ã¦ñwÖ…œýØC3T]úHN³>ÎÒso?–¢ ‹)Ç0©È‘ðÑAÃFšU3TíDóÕ¾mÀ¹ÝLzžBH–9{]ù=“ÑÙFX”Ù´ãcŸ¤ˆéžË·¼;¦¡Gù…âúÊœRC€Õ‡%a$L[ÞH>¼ê¹müH°›în6㊠ú««.*ÈbļvS¯¹IˆfŠºe”Vœ6Ù·¡uÅu·Ûv3ˆèÞ@Ô›¾²“Í\|Æî9ÇoƒyMsIÕF¶ÄûZž›ìÓý®m°‰šé¼C ¹o ¶ŠÑ`v‘Ý…k êqzañОuŽÎ¸J½ ¾öÚÂx²€–DlV¼YfI³“纪ôé®ù©ÈfâïíÛËù8÷ÌžTvY× ÆÖYM;¤^á²U²†IتŸÇÖ&={õY}I5»{˜­M«žÒî0ð¡¶iö¢õO%éôEŸnS¢âÅ(˜Çê«nX¡jb†³æK´µpH›EAVcEt…TÕP“µ¼‰¬z×®œâ­8\²1¤KŠ¢$’:@jª‚Ž"¢wm²¦¹wX¹Ai”WJ,–¦ 8ϼ‡Øž¡=%U#lÎêñ4(F#º¯r"ëÇ¿<½Íh¬ç1MMžNƒyZF£Áªe†Xv[iéïÜÓF †ænö¦•6Tòú%WØDf| Í`Él]eæ6 q³EOT× W|»,YÜs‚xw>E5­~õÞç¦A¢”¢gáÚPïB"i.ݓɼ_2‹7‹sr÷WÊA"+Åá¼)»ü4 UûªºþΑvèI¸¯’¢ù§Ñki[O ¾ÊôÁ˹ñ˜m§¦H¨ù‚"¸¢„»)uë®QÿÂwèNëÿä5¿è}$KÐA72^ˆˆžj¾I§hqV¤ò6Xä8þÏ6Ñxo*oî_RUOf›•ÊÖ­3FŽÅãJG +ÅEw“ÑÉD:t ü:k Á°–áÕ_çY V‰ºãb0à?hò22 ¡ÙãíO¼¨‰ç¢Åñ¼~=Í£_÷Ó4¸e¹V×ÒMžvsî ) *¯kIø`}²±l^Ôqo-V»“ñýK[¤ZÛH†ÝVEè ¯{rA±÷E Q6ÕUU]\¼“+Ée v!ˆW©:ÒkŸq–A7ÙÄÍ}ÐÔ—VYžxä[ÎqÏ™ms†=øõpÅ{ؤ­%ê‘Ø^¦Iû×72胷 ñ¬xÉÌ]s;⦑;YHvF«i^Âx'ÂLï$]ѳÛmb&$eEEWd‘‹k·ÝâÕ~1E‘QJ->ÛHQß«Xâ‚ÉÀÒƒ±´í&ɦ™~–2œIQÓ&Ç>§`d˱›ò5×ö‹P9w›Æ²Ü³Bˆwî@e¬’•ÃlÚr$±}°›» Á@ÑQWmÑwþR‰"’l¨½QQt˜ìv~y†Ñéëñ·Ù¨e/UÈäJiÕ6Ú<-«Ì½,öF/QÂî&6ÖÖåÁŸW<ÈÒMµúÄÛqÛ$TTQ1EEñM4Æ0ÈÍÏóãü{Z]QË9h¨/š'÷¨¡Üó‹àˆ;/ޱ,HFË"³—! UVUÅrÂï#½–¤ü“½Í×^qIÂUTA»•CSó‡âóŒA»óGèÐÍvû…1ˆÇºø™§µ4ÌþåK܆Ÿ4n::ãfÀ­F˜D@‹ÑZ{m¼4£a„b<™µé7´v–aµbصÝõ »klŸƒ¹&ˆ“ﻥ«vÛ³µï»ºk®A¨ü²ûu‡NP»ë?E(Øq§=ãF]1ß~ÁDÙ5cX[Ù–wÉq&þ{‡3…Uˆ^â³£)0n[©E§7&œeóüQê¾é¦at³2 ™z¨á1‹À‹[mQVòìÐÓˆëñ‚ Åâôw\S.Ž{£ôc8‡!ár¹‘²["Åhç~Wz-Š+ó£Ù‚)AŒÃ{,‡‰6íU×!bÜÇ9 nmÁ¦Ck(z÷+™ie,‘'«l(m¢$Ï¢¼Û@]â@ïvÉ»ó8Wæ'0­²Œ*ä _?&2ŠGÈwQa×M–§²à¦Š!xjö¿$£\[:Áî$ãyö1êzÁÒ  ò~õ‡›0u“ý`$Ô|︲ã^P¯ÊÞJÆH¶©²ú3QYœÂìˆMHEN5ˆq¯Ìž6ÔéY•´l{æL>9¹_kc)TcƲ¨9_qUI¯Q•]×ðÅùYg•‰iä±½@+ØóŠ¡±&3ž-¼Ã‚.6iÔIuaÁ<·#â³ZHå/ ÌÔ=8ù}/ksÙòIL¦Á-¤]ĽôÜ ¢ËÈc$šë˵TDŠ;ý„ Ii QÆ”»Ueë§lfÖˆã³âÊŒb'5_R• ½±‘2‰|MÔ· ˆÙA4BغnO¿SaјÒ‡%Ø®‹¨Üˆä ó'Ø«Úm’*¯T_PXX²SåbsÚ†½÷Œ`ˆ2MÆvSb‹êz$]À»{…ï"n‰©¹ÎEž·ucÄ’ö[¤çž&ûÎÔdWÄ•vEÃåc ‚啱o² ‹Ô‘ic1¡rD‰®äD&¤*¾â'oM—\có^Û›qu¯Ár°*G' ¹Tj&#ÔÒ!+rÁÁ[Ué×TùΖeæ¢-qv Hà=?#’óhãInäI Ùøm‡¼ªª¢%}Ëüµaï–óF4µˆªUøýP›•([¨²Ò®î9÷žss-úkù…f¹x½|8‡4ƀѾÿðÔÃGãØ£-¢“Ÿ–ËpQKÒ'6M@ÉksÚ¾FµÉBÁ0|F[·¸;´ÔXÑÌÈWï¸çh7×½Qzk=å>a¶©ÆržRÈÏ&Ì¥uÕFûmCXÔ—QφŽËm©þ¹÷/††@<ÙG6ÑÑ’†*Ú¶©Ü††‹ÛÛ·]÷Ûnº{æbú1á_Còù á÷&¼j¬[dÝ«äâŠÆŠ¿àÐϧr/òÇ·”ö?“QÈKN=Ï Š~aClÚ~¨ê»w}ךUíp7ë± ¯òÝ[8Ï/c úò£1ºW_×n¢ÝÕ3„‰ê0î߈}“Ü o¢Âž»”f kÖmé7$Cv29ÐôÔ„N «ÜSKÑK˜xìÇ)»É‰˜µ­ eîH‰^Ëq Õ™:CŠƒ*[¢;µã¹.ÚUöõÖ?”WXr2åæùRc¸Uhú—¶î8¾ëké~*J›¸~=5VçÞ]ü›Ýåh®qæ9ŸF9œuÀVáËdÍÁH2ä¶f-¸Û¾öþ›Ê½ËÀyG,ðÓ¸¼?3ü¢Ó‘)¬¢ÚãRceŠ¥£ŽïssS}ÆÕÖQG̼7·Èò;iè¨"»6âÎBìÛ 2ÆEíö"'U]‘:®³®n™N-oÊ—1­qš·=Ù•ô•ñW¯û/:ÒÄ?«Þ‰¨2†Áº¹oN¯I½ïO¼ÁG%RîDí=ÑvîÙu‘UËqû'²¡°v2Ÿ7i¨o+݉ßݺíæ›m®X_ÿ§Ýÿ¡;ªFªc ëHU–uõÇ·d§k–4ÁŒ[ôÙßG³¯·T<ÃÁ–pÞ»äëj:íøÐ¹¢è®︯QºåWo¹§,ôɹNio6kËܽÆ1ã¶ëQã6¥ÕhôjwRXÏ‘€ÊÇÊpʲޘ4¤ì£‹:$r|Ì…—tQW¢ï×C"ÒÂ-drT~[Ͱ «àˆN¢®±Š|u¸ßæ÷õ˜Ö8õœ†­je«ÈË/Ì(J,Š®ê¢›—Aªš‰™óöF\Ó“Õÿ–¥u B´ÛNõ&j{”ôúþ$³stëÚ+©ð¸‡¶çH˜_if÷8‹`8ýlR‹$³$ô$ºË;1ÔRÛe ñ×úËùSåðãܦÈI¼—&YÍzEòòkŸ' —¸†l¨Ž“¿`ð ÄiÅhŒ{…UuiSâ¸þ-2Knȸº‡,'M E7M×›.ÔOx·]¼×Mcìfñ¤G%×ÝäÑ_„R+&z(ì[kç¶Y2ír7¦ã.4ó.ª¢îŠš¦ùWãb~£ñ(1OrØ…ÚU´ŽnMÓ0è¢ ÎµØ»‘?vÊ™öõDÕN7W1OCC šúj¨ €Ìh±i¦Å<Qú:Ë×dcÙf8ñOãþD«í Z+ ¶G£šýöÏd™?qÑè]{H[âq­cäËÉ¢ _¯UN—@}ez!¯x/QEO¦Îúê`WÓÒÅzu¤çaf;¦á¯Ø)áçá¨ø¥¤wë3™è‘rÞ_ÔdbüG\òþEŽw'Vdݽø"**‚¹Ü=LñÞO°…o f±M$Ga;GЄê÷¶ƒ²(»·EMCÃiùK5¨â&­«n&póÓ³¨Wª¥·6+pŸžÛÒà´4@Ëݪ‰¶É®3®äI9%w9É•ÌWX“&ʳ ΞA²Û2Mc7;´ÝQdöíQÑNùoù¹ão˜:ÄÜÇÌcŒK†CÅét†Ž!mæô!_n£]sw ơœ°‡W3q|‚5ÌØ>cˆn·`6o8#Ü€]»¦ú©…xìé6÷Î<Ý=O_.ÖÊZÇ'ɘpšuÒÑQH»{StÝuȘëUÙ|+«¬jÒd ø•ôRrDˆ®6Øw9w"DÜ•<×XÕc‘oŽÂ%\(ÏDf‚Ý×=V˜1ÈŠ„¨H©ÑvÕÇb¸Vwqo.EuÎN¼´¡›SSSmX߯Ñä°]ž,'ÇGšÃB@Ònûj¢_´—œUÊõMã<у´Ùäu­oðWM}6/j$OV,•N©÷š=Û4EMr%wúЛÆpLB¶iv1l¥X:çÃ=-T#£n5±6}TS§œ‰\¥s‹e9[Œ›2ì9ͼžöB(±Zç«Ú«º¢$x¢ºvª/]Ûb•ç="Uô¶¨Ð °û²# “¼‡i”LGbصÄÜCÈáqÊøÛEÉ—Œ-ò¼f']z–ݦ”JT¸„¤-¥ƒD„ŠàûÔ“°*åàÓb'äATÛacªv«bȈmÔLQQwMõ#åÌàñÿØ…†OǼ†m9/ >ð”¼~ÿ'mØO8çk®wl˜(ºŠ•ÔÌKb’F]j,Œë&ÖúÞJûÎÈç{òŸ5]È—tý‘ÓØFLÎmùÄYÃy&ÊÚrvŒ ·â£ÈVÁôVûšGDTw1«¹ºi«ÛªfYkzlf†mMŒZÆvèm¯»e„cÖ…FÒ¤™ÏÖÊ6¥°¯ºÄ“f8¹è·ß²ûÛc×øí’Gs$¯üÎÓm‹PÞM«ŽDïWwO¼ˆ£õégåœuMap‹¸_´ÇÀÙ' èjÌ„Tö÷êÖê³–¹;Xäêû #ír9 5†DÃâµÿ.³ø‚s½ý½Ñ>‰¹þ®¸6À“‹Ÿå°n0 ¿ÄMI‘W Ë8ìYºÿdgpÉ£‚b†ê¨Š»o£4Ê8Vì%øŠ‚/joýêÅÔÔ¯š&ki òá2&kA—Ü« mGéQ«hgExc¸ÛÌÉ‹"2â¾öÄ%ÑwÓ™¦c]r ´p ³:øVãH±}ßuoðÙî芀ˆ¤"=äj›é‰/D“ymc6-]1Z­éÓ¦©¤v[GL‘³%7EIUzh0rÇU¾-É*.U’5éül'䯒®ÅhÆBô=›yZÙµ÷QÔB Kƒ8;LÓ¬Y’8&+!ÅqªZÙzOµ™Ú§½‚Têj¦êˆ€÷—]Y=*̳.QÍ] ü›É2›@“i0G`iëèDŽŠ Ã½ =z’’¯ô7X} y‡À›y— 6!!]ÑQS¢¢éüÃå—"ƒÆrìæ$Œ›ŠíšvFcÞIë=; ŽÖ¾¨ª½Ñ¿ •´ÝKMq›†rê®$É <ù†ËÙN6KÉ3‡º®¨;»·‰G @ý5-…ÎÄ$BEÔÜ{,°ÆÛ¯¾™lçä,ÊXSr úé«^J·•ßuLMxTt[#ôÅ[*l©©g‘ãuö²æVʧvÑÖㆠ֙ 5-lL ‘{ û&_Ð ©6›–Ȥ‹¬qÌeBÿ‘q»øY–3QÀzCqÔ9ÖSž@UPŽÁÐ2-‘{¶ê½4ż=þÚ¸'DßÇÒ’Â:ÿjI§~¾(”¿Ï)ÅÖM—ÑÕ¥ÕÆ7,úúÂC qÆ™¦-ûä›™ õQDë œîsEÍòæ5hãWÔm7 ,yñ뛟¤Ù„RûŽbzˆÒ©!ôATUßO¥%En˜Ö½kŠ­f%¾79`Ûæ>Ø<û( ûƒcÚŠ¤½»¬š®JÈäE¢nÖ¾U”³l°A‘-» -@2ó0ެ«MI"?\K¦ê¹'2ÇóÚüʺ$L¢0‘£½%ºô®›0¸Éœ&ò’®în^*º¢âJ®#ĹV—Œ5x–{üL˜ó®×0‘3¯(_m´pÚ5CÛ»ÅWXÏ"ó­Í?Ài)Î=ãLH$-Ul¹­+XL™/g¦IôU[ìÛE%Ü•uÑv_%Ó?sÜÇ%ÕmÑšÌɶû¤°ž@6m¨>×@‘(*¤‚*‹Ý×U|òýòùšf«!³‹#½ ÅÚVáüƹce»+øuQUQwÇtNî¨y‚™Ý•þ4â r­ƒN]ü¤)ï §BF…ü—GKŸ%Vþ³äÃkºdÂñï™5Õ9ÖuÂ]N©´ˆÕ…eœwbXÀ|PÚ}‡Á[u§z˜’¢¢ø¦ ßÝ̶åyø»îDËIUØÅz:E5tÝŸQTˆu ÕíEéþåTTÝÅ4Vy‡cïÞ©V°U¨~Gù…iFª›ôÜôKÅŸ2\ƒû³Qq.&[ZÚoÐE›v}ËoˆÒ¥)q_!°Ú/i^ÑZc²M<޶TÆÑõ{j×0– (ÈíÁæì.)ùJ¡ —çÒà î¨ÕR¯–“º¿…±P_~Ï µp~´áÅÿ„šEÊ~eñ¼Q²Oňa@ó»ù I¶#oµZ] òg/rŸ)ïþqY;!*zÓö§ÂQµ§Ô¦º yÄ8¾7` ¿çm@mû_Ê|„vI.þ×?òŸÿÙ endstream endobj 13 0 obj 111919 endobj 15 0 obj << /Length 16 0 R /N 1 /Alternate /DeviceGray /Filter /FlateDecode >> stream x…ROHQþÍ6„ˆA…xˆw •)¬¬ ÚvuY•m[•Ò¢gߺ£³3Ó›Ù5Å“]¢É`¨‰µé²™…}v*Ëìðèñ²bç{aÿ[QÓÀ'a?d‡yÖ­ö®Sà{„=5àήÅñÚŠ^-C÷T#hŒsMÄÓ×9s¤ˆï1Ô˜÷F9¦ 1w–ª7€;aYªf ±]û®ê%î{wÓã;Ñ›9 \ Ir±ÙÐ< X}‹°I<>ÎUàw¨˜À¹‰ÜÍ(÷Õg£RVzWÆOã¹ñÅøelÏ€~¬v×{|ÿéãu×¶><ùzÜ9®½UaVqe ÝÿÇ2„Ù'9¦ÁÓ¡YXkØväšÌL° (Ä>—ú’UÜÕîí¸EÌP>,l%ºKTn)Ôê=ƒJ¬+Øvp’Ä,Z¸Skº9xwØ"zmùMW²ë†þúözûÚòmʨ)(ͳDf”±[£äÝxÛýf‘Ÿ8:¾ç½ŠZÉþIE?…9Z*òUôVPÖÄog~¶~\?¥çõAý< =­ŸÑ¯è£¾ tIÏÂsQ£Ið°i!â Šƒ3ÔNTcâ)ñò´[d‘ý@ýf endstream endobj 16 0 obj 704 endobj 8 0 obj [ /ICCBased 15 0 R ] endobj 17 0 obj << /Length 18 0 R /N 3 /Alternate /DeviceRGB /Filter /FlateDecode >> stream x…”MHaÇÿ³±Ñ—ÅÐÁ$T& RÓõ+S¶eÕL b}wg§™Ý-E"„è˜uŒ.VD‡ˆNá¡C§:D™u‰ £E^"¶ÿ;“»cT¾03¿yžÿû|½ÃURŽcE4`ÊλÉÞ˜vztLÛüU¨F\)Ãs:‰Ÿ©•Ïõkõ-iYj”±Öû6|«v™P4*wd>,y<àã’/ä<5g$©4Ù!7¸CÉNò-òÖlˆÇCœžTµS“3—q";È-E#+c> ëvÚ´Éï¥=íSÔ°ßÈ79 Ú¸òý@Û`Ó‹ŠmÌÜv×Ulõ5ÀÎ`ñPÅö=éÏGÙõÊËjöÃ)ÑkúP*}¯6ß~^/•~Ü.•~ÞaÖñÔ2 nÑײ0å%Ôìfüäý‹ƒž|U °À9Žlú¯7?ûÛ‰j`¨‘Ël7¸òâ"çtæœi×ÌNäµf]?¢uðh…ÖgM Zʲ4ßåi®ð„[é&LYÎÙ_Ûx {xOö¹$¼î̥߬S]œ%šØÖ§´èê&7ïgÌž>r=¯÷·g8`候ï 8rʶâ<©‰ÔØãñ“dÆWT'“ó<çeLß~.u"A®¥=9™ë—š]ÜÛ>31Ä3’¬X3ñßüÆ-$eÞ}ÔÜu,ÿ›gm‘g…6ï64$Ñ‹áÀEzL*LZ¥_ÐjÂÃä_•å]½XážÏy¸[Æ?…Xs åšþNÿ¢/ë ú]ýó|m¡¾â™sϚƫk_Wf–ÕȸA2¾¬)ˆo°Úz-diâôä•õáê2ö|mÙ£Éâj|5Ô¥ejÄ8ãÉ®e÷E²Å7áç[Ëö¯éQû|öIM%ײºxf)ú|6\ kÿ³«`Ò²«ðä.> stream x–wT×ÇßÌl/´]–"eé½·¤.½H•& ËîKYÖe°7D"ŠˆV$(bÀh(+¢Xì "J F•ÌÆõ÷;'ùýNÞw>ó}÷žwçÞûÎ(!a¬@¶P"Žô÷fÆÅ'0ñ½D€6p¸¹¢Ð(¿h€®@_63u’ñ_ àõ-€Z®[„3™éÿïC‘+K€ÂÑ;?—‹r!ÊYù‘LŸD™ž’)c#c1š ʪ2NûÄæú|bOó²…<ÔG–³ˆ—Í“qÊó¤|”‘”‹òü|”o ¬Ÿ%Í üez6Ÿ“ †"Ó%|n:ÊÖ(SÄÑ‘l”ç@ ¤}Å)_±„_€æ ;G´D,HK—0¹&Lgg3€ŸŸÅ—H,Â9ÜLŽ˜Çdçd‹8Â%|úfYP’Õ–‰ÙÑÆÙÑÑÂÖ-ÿçõ›Ÿ½þd½ýäñ2âÏžAŒž/Ú—Ø/ZN-¬)´6[¾h);h[€êÝ/šþ>ä híûê{²yI—HD.VVùùù–>×RVÐÏë:|öü{øêù ¢‚¡[£°R¡Fá„ ”"MÑF1L1[±Tñ°âeÅ'Jx%C%_%žR¡Ò¥óJ#4„¦GcÓ¸´u´:ÚÚ(G7¢Ò3è%ôïè½ôIe%e{ååååSÊC „aÈdd1ÊÇ·ïT4U¼Tø*›TšTT¦Uç¨zªòU‹U›Uoª¾ScªùªeªmUkS{ ŽQ7UPÏWߣ~A}b}Žëîœâ9ÇæÜÕ€5L5"5–iÐèјÒÔÒô×iîÔ<¯9¡ÅÐòÔÊЪÐ:­5®MÓv×hWhŸÑ~ÊTfz1³˜UÌ.椎†N€ŽTg¿N¯ÎŒ®‘î|ݵºÍºôHz,½T½ ½N½I}mýPýåúúw ˆ,ƒtƒÝÓ†F†±† Û Ÿ©-5j4ºoL5ö0^l\k|ÃgÂ2É4ÙmrÍ6u0M7­1í3ƒÍÍf»ÍúͱæÎæBóZóA Š…—EžE£Å°%Ã2Är­e›ås+}««­VÝV­¬³¬ë¬ïÙ(ÙÙ¬µé°ùÝÖÔ–k[c{ÃŽjçg·Ê®Ýî…½™=ß~ýmšC¨Ã‡N‡ŽNŽbÇ&Çq'}§d§]Nƒ,:+œUʺäŒuöv^å|Òù­‹£‹Äå˜Ëo®®™®‡]ŸÌ5šËŸ[7wÄM×ã¶ßmÈéžì¾Ï}ÈCǃãQëñÈSÏ“çYï9æeâ•áuÄë¹·µ·Ø»Å{šíÂ^Á>ëƒøøûûôú*ùÎ÷­ö}è§ë—æ×è7éïà¿Ìÿl6 8`kÀ` f 7°!p2È)hEPW0%8*¸:øQˆiˆ8¤# ÝzžÁ<á¼¶0¶-ìA¸Qøâð#pá5#m"—GvGÑ¢’¢G½ŽöŽ.‹¾7ßx¾t~gŒ|LbLCÌt¬OlyìPœUÜŠ¸«ñêñ‚øö|BLB}ÂÔßÛŒ&:$%ÞZh´°`áåEꋲJ’Oâ$OÆ&Ç&N~Ï ãÔr¦RSv¥LrÙÜÜgIsKÛ–6žî‘^™>!` ª/22öfLg†e̜͊ÍjÎ&d'gŸ* 3…]9Z99ý"3Q‘hh±Ëâí‹'ÅÁâú\(wan»„ŽþLõH¥ë¥Ãyîy5yoòcò( z–˜.Ù´dl©ßÒo—a–q—u.×Y¾fùð ¯ûWB+SVv®Ò[U¸jtµÿêCkHk2×ü´ÖzmùÚWëb×uj®.Y￾±H®H\4¸ÁuÃÞ˜‚½›ì6íÜô±˜W|¥Äº¤²ä})·ôÊ76ßT}3»9uso™cÙž-¸-Â-·¶zl=T®X¾´|d[è¶Ö fEqÅ«íIÛ/WÚWîÝAÚ!Ý1TRÕ¾Sç–ï«Ó«oÖx×4ïÒØµi×ônÞî=ž{šöjî-ÙûnŸ`ßíýþû[k k+àäx\S×ý-ëÛ†zõú’ú…‡Eêjpjh8¬q¸¬n”6ŽI§¾ökÎ×:úçöŸð8wÝçúÅ7®Þœw³ÿÖü[·‡nón?¹“uçÅݼ»3÷VßÇÞ/~ ð ò¡ÆÃÚŸM~nr:5ì3Üó(êѽîȳ_ry?Zø˜ú¸rL{¬á‰í““ã~ãמ.x:úLôlf¢èWÅ_w=7~þÃož¿õLÆM޾¿˜ý½ô¥Ú˃¯ì_uN…O=|ýzfºøÚ›CoYo»ßž›É_õÁäCÇÇà÷g³ggÿ˜óü endstream endobj 20 0 obj 2615 endobj 14 0 obj [ /ICCBased 19 0 R ] endobj 3 0 obj << /Type /Pages /MediaBox [0 0 1333 858] /Count 1 /Kids [ 2 0 R ] >> endobj 21 0 obj << /Type /Catalog /Pages 3 0 R >> endobj 22 0 obj << /Length 23 0 R /Length1 19420 /Filter /FlateDecode >> stream x¼ |”ÕÕ?~ï}¶Ù÷}’ÌL&™,CÈ6!"yIX"V3h$¬nUÀ *¸!n%Ú V[&ˆ jÚÖÚÖWZ«Uk_ó¶X«•Ÿ¼}©%3ÿï}& ¶ýýþŸßoÂ}ÎÝÎ]Î=÷ÜsÎ}%„˜ÈV"uÅËzéaÖ‰œ_ñ°âªáÏŸ¾qº‡eÒêÞK®ˆÜèßEˆî·„Hs.¹üÚÕÊwß=Mˆ¥ˆøùkV-[ùåmK&ÒÐ ü káxÕô3¤ŸDºhͯٵV"ÍÛßsùºËí~úqB&­DzÎË®é•Ù¿DúÒáµË®XõÀ5÷=ˆ4ú#Žë®Ü(æI×#}éµ½Võ6GV „L¾œÛ:äQüñŸ‰Èd0L.Ëá¹üÇrOàýoâ¿”HhDÐòuÚS?VÇhD„˜ÇrþXˆ•؈8ˆ“¸ˆ›x´ ^â#~ A’GòI a´RH¢¤ˆKGHžö“<1†${ìlÈôdñ2Ù§˜t~.Œu›&?$¿£¥4LèWÄKNS?­&3‰H¾ÄœQr?F±ì¦ôä!‹ÈL*¢NœÜAÎ^•ý„œGî!gŸ£7eŸBùNò3r#øO‘’z2õ‘Uäá#’Ì>Dtdf?™Ì§²Œ¼ƒ¿/0Ž{É}äÇôúìiôê"7¡½FÒLš³/gÏrr‡¸KzWÿ,¹›ÉPë¦I/¡§™d1YK®&}ä)ò ê Ò»Ò‰ìw²c½œ¤cê!ŸÐ::›=!š²S²ïƒ#†ÈÏ1_þ7,^(î—.Ì4e;‚•yŽè ôe©FºkôÆìcÙg°®1R ŠÌA?ËÉÍäeò:ùoò7¶%»…Ì ÐóOi> Ó(þó³Íl³ðÙva´›È^’"ir„¹Žlm¿GÈ!òämò7ò?äµÑ‰t }Œ¦èýŒéY!›ËzÙnöû‘0G¸[xY¬§Š—‰oˆïK·I;”eJæÌ¾Ì½™e~}.ûkðŽíÇH(z#¸â òy ­¿Gþ@þÈùíO¦KèÅèåJz;½þˆþ”þš~ŠYbÛá¯Mf-èuÛ:ÝÄîe÷¡÷7ñw”½ÏþÀþʾ$¡P˜ ¬R pTø³hcâx±Zœ+.³X™iº´@zRzZzE:!7Ê+å^ù/ÊMÊ-º_–þg†dÖdR™ð®œt(ñ]ò8øþÖà è`Ä#ä$V!@#´ãn m´Î¦Ћè*zÝFï¡{èÃôqú f€90c³f¶€-c«Ø-l»“Âßö:{‡½ËŽcä^!*Ä…ja¦°D¸PX‹9l6 ·€²w O o o  ŽcÕ¼b¸I¼N|PÜ/-/]¿Ç¥—¤aé×ÒéŒÌ䀜'WÊ—ÊOÊTde‚Ò¡lW~«ü®—æÑrŒ< Þ?÷c~ìÁös‰[èqdçS2çnÇ:,À®øÒ$d°.^ޱ¹™_trtYSŠéó¤Žþ”l‘™ *Ž4ý€ˆ¯²óÈÛ´›úÅýÂZé,Bž†4ÚÅ^`ÏÓ©äkd‹Ù#¡Ñ'ÉGà÷kÈ}ô2z%yš§“è ´žn!¿ea½…4fg"ÕÓ™ôÁÈâJrñ¹)üÛm O2ßÍâõOƒd7Vô‡äCúò•²ŸAº FË eî¿ßJ¸ÔëÂ>Û‚ý臹\~“¢ÜJ½œþo§÷ÿ›™Y‰SìSê£Å´ûá¸t•´KzJ:$ýXzC®µo!ƒ£ÿn6`+ȯɧäKªÃÚøÉ8’Àx'bìär–^$Óh€ôbÏ–BŽO›É•hå&Pïìç±7N@N\D~LÞ¥Œz1£è_‡vÚAç¥äJ²+x3@ÎJHíròWÌÛB'²èOEK»!µ†1¦ÈŸAí¬6®q -t1Úú’\@V¢‡ ¤ƒ$mÙÃTsH‹ð+лˆÚÈTZH¿¼nìP NÅéO”‘q™9Ù‰¬GxgLùý8½‚ä<º£°b£ÄMç’ºÌ|Œá-BÔæ…jÓ”ó'Oj˜X_—¨­©®ª_1.^^VZ+.ŠF¡‚ü¼`ÀïózÜ.§Ãn³ZÌ&£A¯SdI%ãZ£mÝáT¬;%Æ¢3fTðtt2–}#£;FVÛ·ë¤ÂoоUSEÍÕÿTSÍÕTÏÕ¤¶p#i¬n†So´DÃtɼNÄïl‰&éãZ|¶ߥÅ͈G"@·úÖ´„S´;Üšj»jM_kwKÅ8zÐh˜¶ÊP1Ž45"–òF{RïªE˜·uÒAFtfL1ˆ¶´¦üQ ¢¡¸uÙÊTǼÎÖ–`$’¬—¢ÓVD—§HtjÊתiZ7)yZJѺ ÷¤0²#|pÜp߃6²¼;nZ]¹ì¢Î”° m´¦ìqôÛ’ò^wÌ÷u;¦unûfiPèkõõ„yå¾¾máÔð¼Îoà#¼…dm—·u÷µ¡ë;°Rí ÂèÝšìLÑ[Ñe˜Ï„Ï*7¿UÑVžÓ}i8¥N®é»´KèK‘ù×FÒ€:”!ÖpßÂÎh$ÕŒ&—µät‘¾ù×øÕ°ÿÛ%ãÚì9´XÇ"&ó7#«@ô\™ÓªóXûüs”¥|DÑ™)µ"Œ‘tF1§‰ü±j"é[1 €_’+µ+Ò“ÒOëî³Mâù˜"MIŶh¸ï ˆÿìÛ9ËÆräbÛ„r>9Çj)ºìl<§ÊË9‹(Ó°¦ã-]W1îªA6!Úk €|¤´]–œT òG"|w ªd9©­ó:sé0YLµ2žL±n^‚Ì•¸ñ’­gKΡwGÁɇ4uÝÒÅÎý³Ú<ÎÖ5“RÔó(^•+o_mŸ·¤3ÜÚ×=Æµí ¿•Ê•s‚‚n(‹¥œÓ:… C±  •‚)/Zr® ¦”XŒ24v‡¦Ô2h¸-eëž‘{& ‘ÈØ–ùWœAE÷ ¤Áì Ž¥¯ÑÆf‘šgnÔ©ÉßJkt¦>¡}!$k_¸¤¯Ïð­²6Ȳ¾¾¶h¸­¯»oÙ`vëòhØíbûÙþ¾ÞVH¡Ü‚fì¦ÚîHb*kè$°-#S+pHA ÂÞÃN[…L=ÄhFVY“ê$’˜ˆA3”øu²”a 4FôP2}Ä·jmœc;Ù8{´‘4!n;ƒGuUıãAqpŸ ÃgT‰üƒ„Åa‚å¿H8Hï‚}#‘)ªç6éK‰ÉÒjœ|‘J¥“ŒƒT§¹NÌèɳ§ùâè£kö(iš}¼Ú ÕUtÃz§Pq w×ÑšñhÒ~útæsÞþ¦Ì}‚r©éY½Î(”AZ åGèD£Á°Æ”"«fŒUat~Ó%W5lô8ïàä(µ7;ïÃq»dY)™0¡>zõ—oZR¿h»ú_¿îÎÞðƼ勸½ù::ý#´&N»ñjP˜Hey¢hГc4,UIL: {ãiN¯.N¤ÆS¤éxÓqt:Q„ש?ó1 3‡gþ‡?±"˜Ë²ìÇÒÅÒ[ÐúßQçܦßîÚîÙKöȯé+üÖø… /Ö—šJÍe®2Ï&i“þ6I§8¯×éõ–±r¡XRJ¥¥ô¯ ?5JMt.È9ßFè`F³Ãv_Bƒ3 ]¢z}¢Î¢Z KûR+k¥VÕíKXi©Zè¨0ÖÏ-‹ÉçDk*P•GóÜ%ý µ*!¥JÀ2w 7/ÈÑsýìãsl]§º@QÐuôd¼ký±8‡<ÒU]EºhWW•d1&v‰„½¯‹E e»ÍS[3Al¢¡©™7>Ë|¹^GÔüäÊšÌïO\õ½_þ¼ÿª§XðŸаHÖÒû÷^œjÛp˧™¯2Ÿ~¶›ÓŽÁB%Ò2ð™ ‹½E­-•J Ó½«ÄU&©ÜÛàáIzÖx¤ï„à¶àƒÒn£²SœŽb«Mç/9 P…“HoLðy©Î­ŽTEXÄî“°­ÊÆlƒlÇ@¸zl¾|̶u­?Ç̵ÍÀ7ŸçzÚåŒÔx=‡Û]ѵ×ÖÔOau‰X¬$½å?×}ã`wEýêÙ7/ÿþè[´ô××ÏXÚØxù‚)ÏJGòb¯d>þgoî_Ñ^_9Sgq,þéSO^í°äøäèô·`®z²AmÒI¢,+a]•î%݇:±R·KÇt:"ˆÅŒ2=Ñ)Mò\˜ óì|«ŒÌ(êÃ4Lª8c`V†oÎJ[ÆÆÙ'»øç“r4Tv­$[#fXk¸±ÙŽNf+G‘ŽœÎË÷,’%l6¹Ìf“Õä6{=ÅN›‹v»ú]Ìå"á'ç&:Ë }A-!f›™™,é—Sò°|Tåm½QŽVEY4âþ&Õ «W|½‚|Wv?ÙÅ·%¤ï7YX;M¶wYn°ýDü~Ȧõ]] hFOÅãñ:#ÂxÚ±oÏR5º›­ûëÛ[_y¹û†K2ß}gËW7þþíKçÎ(:ô±tdî/nzâwyo{:óGÚôt22úˆ0§¨sê¬ M8i)™•ý³ø7Èöqô¨zÞ}0ÿpéÏÆ‰ànp·/¾JZUºQ¾Æ¼±ô=Ó;QSҰȲ¨0]cZí¸$ÒSzɸ«óoËß19¢ƒÙ‘‚P‚Cu•?˜W8/úráËQq}áúè…7Fÿ«ð¿¢rÜPn.*,Š6˜ÑvC»¹¥pZôRóªèµæë ·›û ÷ö›Ÿ,tê z³\(Gý¿ÙS¨F f‘zûT8±ÎG×ùöú˜ï[E‚ÙaÕhi°Â%{Z'ª¨ gV7ÝEû¡' Ã\ý_¢h°ÁÿUQ®÷}žõR¯êô&¼íJI,0>TÒoKAš¶ÓÏí9 ä¯øÍ˜Pm_Ðy¨“8DºpœœŒoàÇÉúøÉ®ø±Ü?æð6ti{:Ü)=‚ùS@£cðOigC!È€Ü×Óž:ªZ æ°£Á +Ïû‹j1!ÏÜ`ðñàl€ùú—<(³i ;U÷$Ã$s]aè8Ó<­°-ºÏðƒBéJž÷Å~‚i›¯°.1aBmXÌoŠìvy=¢ÆYüì›EýÛvÞ}Þù‰¡ÿÕ½mËç?€ëÊ«dÞuÞpÃ3+ÇM¤©77Ý‘%/e>ͼCÿw÷í×ÎKÌ :ÆO^|í3½¯®þÛ/ÌëWÔ6$Š+W_ñâŽÍ\F!-)¹ºCö°Ÿô©¢WlØ®úéºézåýbÛnÛö=î‡=ûmÏy~çþH>%Í&Ž@¥Ø©7Ãæ7-Ô‚Ã@-TƒÁî ÐÜdá`U°?8ƒr8ì¯òû??3Õ›¾Þrü$ÜmGS kÛNËΈ“çÄ™P9j³°h!?ëFçÎë7o ÐÒªß}æ7ïmvåKGÎüùʼnK®¸d÷3BüL&súýÝÉe/Ú|ŠËܙٿÀo8þÔº^]£tyR¾'0+8#ofñïmÚõümþ b«ý—Än‹Ýã¿7°/0|-ðó I–Ínì÷”Èeî¤ÿjvÛ'?+ÿL6½”xÏÆò‹jªíãÌEj||¢H-,ÅߟXWt¦ˆµås.¯²XçåS’oËOåÿ=_ÌÏGk‰Š\®Y2²(¢æÙ›"jІ‡/ˆ ²ÏŠŠÉlÇ>”iÅDq¨¡ª.cAuLW¦/5'C¦½&2Ѭ‰šT‹'a ÌMÐD7Öõ®*JimYd©—~è¥s½K½ë¼‚×_ÛÓ|ö$Ä.Y¼‹Ûе6 uŒ«çÇÁÇ8¿GøÞÑñxޡӕùt}òx.1DвÃÏó ‹V±®x² Pº N{~¸®ïâ: ´âZ.—ÇÁ –È2–’szýxe¸E˜3;VYêèªlü7o¾0Ø.‹3ŸmŠ0ãû]ßqñÃ÷üôüŽuí éÅ>-ªïl9¿µÖfdÿÐ}ÉíÏeï¸õü¼z¿®­-}û’;ÛóŠÃyóZ'g~ã¨ñ•4N^\«/ZE8?l?ܧÁyäÑ!âÈžV« õÁéAæX,/6,ö,ö%ó¾Tä:q²y²³.Ø*¶›Û­Áû”õ“  `Ò’ââ«á4­Äàè½´ÀVÆ„á2ÕD{ÉVôçÏoÊQ|}ãì㣞ƒ³YÓü¸nÏU²*î´NÕ¸Z^mXíYíëÉ“º’¤KÓK@<ø¥HVâvbKäĈ¶úoJ¿’ÉŒ]xPu$f^Ûuó-—¬ºM:2zâ¾ÌÇ™¿gNdÞ¿0ù+bnïÞ§?µ†’E˜{ö‚Ÿü—:¯Óšt@¹µö8z<7ø®õ?À0ýÌö3ßïlïø>‘?Ñ}âüÄ}ZvNtNtÏrÌò´ù’¦“2ÉQï©÷ WKW[·I·Y·ûŸtì÷ 9{ôγ¾`‚Ãg®„¥ÖÌsü Zí óø£  ™Ãn$*ªõHí.pêH#Ea¯By.J3˜#s!`A%âò:s¤ä67â'ǹÑÐu <ËmÀœlMsF‚ÆWê%ÎvÜ~3ŠÕ™¿ZVÌí¹aËe«ÝÔ?ùÆ'™¿RÏñW>bŸÕ,Xx÷S/>ráºÊ¿ï±HZ¼ŸóÍBÐŽÛ VÜíR+I9iH:rܲ¬qZ¯ï-ØZÀ& Ó$wÂ?Kh1Ír·øÔë9Ÿ¤%#çÕbT,V,…Á[f1Ç(ç«•vrÞ‰èüùÚöä3\*Ç1š:³5¼bî‘{ =Ž·È]ðþÕMÐQ[ã…EýMV—eþÑ|pÉs™d^IßDý£ŽÊ–ë–Ý~Ë%+·=raW:¸ný÷1Û™Þ§Î_ûÄ÷Ÿ{l/æÛŒù–€W\$~oˆØ°OÚŒ ê2ï¶=)í7<¯Þ<Ðé\t›.·æ,¼fø¹éû¦ÓÊ—fsž5Ï­BF¸U‹=au¿ä~Ó-¸9WX š4hñ²;U¨{ŽK·…Y|®!ö´Ö¡™ùáœùYX–ƒñŠôåiPµB öƒ¤0áYêp€Ì¢Ñáãä.2*$B+Ý9&ª,XZ°®`oX`èT³5‚ÉÃø·ìÐãPT—O-u5ùÔ+Â>.­ù)ŸlÕ&‚>!TÒ êq˜>[õd×zŽ×  |Ri/©½aŠ–lŽ4Å oú—¡]Z÷T²ðN-¼{ÜÞ&^'ž¬l„x†éÒûP;/!-`"ËÑ0ŽHÎãDˆh§§“ÊŠìe_Qß„Odþzku½uœ:äQU¸iÙÔ%%Â5‹/jl¤t~åC={÷À ñÌk™oØ1ƒ^~Ý–iÓ®ärÇ ðgè 2¨Ââ¦åbض'Å­>I'¾äcn¹»Å‰n‹“séuV#]jÌÂhä a©Ýê¡Yõðd íž@Ó²ÓeÐ×6éæê:t‚®ÔVi_jgöA*ªf‹3Æ\KI¿gØÃ<œ'ô¦„Çï½fˆõÀ©_O"•{’Ît5žìò#>œ[ÜâDh£¡ÆŠßØIä¬Õ´«¯Â·»Ö…bõ=Òðà¦k®ŒM›r^Ýo~“ùø1ÖqÛ- Š~bk˜×þ‡3Ï 3µ½Ÿ™'vk:D%£.¿:[>s˜Ì½Õ·™·V‹a »B¨¢µ¬VPé46M¸Ðšt%‹—-ÆR]f=m?ítL6×z&—ÖŽƒBíi/mwÂ4ê5Ü…SÛh2ËMæ‹Çë®0› òùŠøxVÛÚ°Ø5&0šr°´<·`kåÕ‰ÜFлƒÚÑ¿T‰Ó!k C'¸Ñ­øüry™1ðq¡£÷ûÕ´"hP5Ú¢ˆÃ_uNúœ“?¶ã¶Ñc\ñÃjô$7—ñ;«€Ÿ°±5ÆâhìKíв ÷¾ñ{ïì·^“[ÖWOñ%e«ã=•[¤Ë+yø©¦üuÑc ì­ƒ­/ UÁÉU®%cᮥͺüÒÅkë‹æÍÃïܰœÒ—~º•*SzŸß™ùÛÏÜÜ}É]·¯Yus[ÉDwAÄS½øá>»ómj¤Ýfú G.mºËÂnþÁ£}÷‰þGÁ€÷À&OB®{HZ[i×ÀXHÛT:ÕþŸôïT¯H©ˆuÚר%J™Óew8£VNÔ|AÑ .·¯r 1^ %èiVOõ 3T@OaQb—¯ßÇz}'|ìsü¡®˜‡‹>ÕŠºýnzÂMÝ~oSNìÑó%p+åÔXJ“ÿÜ =šz5K§y/pØ¡ 07X."ÐGæQúôí/.{dn~æãð¼óÚÖÖf`eŽ~´wFïí;GïfÕû—Ôµl¿mô3Ló^lÄ"Êý’W=FÖd74©ú=ÛªOé‡õGõŸë¥¾[¿Eß I8|œbªæ_Ht"Y’ÑÀœ™|vúHQBôëÆæ¥Í*wŽiÛSs i^!¨‰âN>h„{sNñ03gþ1KŒýã}èl°QÎqæRËøá b[¥nËJŸçB[¤~dHÜÑLˆQΚÚXˆ_ü—±h¢aƒ¦g¡ç1ÿÏf܆ïÁ^/¡“‡H°»Ðd«É-{L !¡KøÑÖªkõµDMa¡²l¾»lkÙÞ²ïËû•}¦gågM©²£e#eRVYÖ‚—Ê>,“ËÔ@^¢ é­Z¡¤DD%Ï…aÚ pÍ_-›Ý^ÌË‹•@P«-æ°«KêºítÈ3ÈÚTk ËÏCÞº<Ú ¿*òÃ0âzDšÌvÀªoâP€q— j‰ÚŒÐˆPT’(Q'—¨,y³äÃÁZ*ÙZ"’pIUI¶D,ñ—þ)džš¬ítø*!Oრ=µ¾‹ƒ³ iÓ˜²é8¶¼¶ãAÏ q®öÓ8|âàLWÓþq½Ê´äƒ~Í«›©°cxõÇ/Úôx)86¿dÞä5ã34Mh^S‘ùXŒÝýƒ…‹-\zQËžÑ$[úÝñ3vìÎ0Ööð’qm·<8zü¢˜ÄšyÈ^Õ§8½Î%º5:qP¤X-[‹®Åú‰M’µ kW,fÙd4Bc4æ!Ú†%4‹FþwÖ`Œ™àX*KÃÿÄéªí[=Ùýí}«Q æÔ··®æIâ^|Mw‹|k£jDÂö“™‹æ5Ì܇_ÚñV×CsC¬à‡«&vÜ’Î„ÄØ#‡¦­¹å;Ø Ø¯ó¡—=„¹š¡Å? Îø ýX÷¥óK·øû \ˆ~ɯgIÛbçbOÒ÷Û#ïÑ=`Ô¿Í~/} Ûô±ô±ü³m¿î—ìWò«ºŸ™¤Mºíò-:Ü>4z9‘\¢âjPÝÁÞ Z"ä[jwÎxÑ®%4Ã…Ku}m5tÑŸH» ÒáÇN8°úÄí‚áR+þ†üžß7úÈÓDæõÏîÉ|ÙGû׮½ÿþµkw³Â;¨Ü—yíóÿμzKöÉï>ùdÿ#OâuAFvd.À|mлRÇOtÎp2GBh078Áa¦y¦³%ø÷ žÛngõñSÊ߃:ì oÚi£÷ûgí4{™ÅbÙlšnügKmöñF0½íØ¿Øj”37?Ǹ­ö ý›Àuïæ¼ÎM n¬qÜsîÔÚAåÚg.¢,sf¨sç\,²ç®ÕËoºmÅ%·cq;Vfþ33š9•y¯mÑè'ÂÐÀÓìœëàbîË1w;ÞxT­w4²„9ájÌ›ÅZÌ-®YyºÞÍ×¹½‰¤”4\`^ìLz“Åùû ûòNëO™¿t™ìÄäK+¡fscU±Úd G,®˜Ý®«ú6j „rÇÿ)ÜLœÿÉo™ª´+¾~Œ=Raµ³ÇÛã_ƒœÚ¹ýQËYXüô¦Úy3¿„™õß_úì¦>* _úp#2'n]¹zû-Ë–Ý“¹œy¦/¸}/µáÍÐ’ ýªM8ô½½§<ü çwŠ7lˆP¯­ÿ“jéÕ[è\n’„JG§e¥×K4«)db;MYk2Í51Ó »Z-SìrɆR¢·é«ô½zQØâØë`K[G¢ÃFb÷ˆeª‘±­pD2ê·7 Ѽœ‚ ýòܦ>ÕåŸS1qc7à}ÎëI{Ê» =U‡ çƒ†š‰ØØä9nÈ)›²öó}=í²–îäÓÏ›<¿RŒ=pYKÝ㛟Êü7æX…=mÃËÙ+ê°l—£º¯ÝÝãØãz äþr½âjs1Çóæ!Ëk‘¢§Í§ å2ó"ó*óýÆû ‡LJsT-j‰]R¸2¶Í±Íu[áÍEúúX«Üfœežkm‹L…‡¶¨$Voª‹pd]‘"$»>â3—˜ £JQ¡:îJÓ5®kÝW•m*¿Ý}KùCîûËŠš·ÒÞ;|–ÿ <5NöFÛꩨ`9šâ;¼¯#&V¢Vƒ²"3ƒ"éƒÄà D;.Ç]úƒÝdrÄ…¸56 ò a†¼GØ#k¾aõšqÓAB£(J¢ÞhMA=’Kï7¸M¦()K¤ }©¡ÄTMê¥)ú62M—f(3õW“kÄ«%\®6m#·‹Û$\¶™Þ#ï‰oKoëß3¼mú”|*“Žé?53ýü]<%VNéÿn8eªÀ[o©úऄÃC?˜}_Kx }®Œð”Ì¥·gáç*cK '©Y+×G´rÕˆ¶eB0Êã 8HÏÇXv/¿Ì­ü¡WŒ¢ÌÎ zÀóÕ˜ÂÀLxµB4 ’Á¨èu²NQ$I9˜ `b¨´4Á% ¦Ð5ë©…„Aó+ˆA%µ S¿ù'C4ÓVþÙ£ßèhÀ?êË1£ÙhÚ“Ç´q×LCžÞŒ’_GòÁ"p€³€pÙȨš0ãÓisr‚ߨšxÎ ~äp€ÔHk pöà$¹fÄùËÉÿш Ðd&Eí¯=G­IÝ™§3{îxläáï³§Gñšö.¾ ¯ïÝ=êŽRåç"Û£ ÑèÛÊ 3^\ ˆ>¹T®'u3h’^O7)†+è$¥ÎRöO˧}±SÊ q’aš8Çðª¨;ß°PLVŠW®¡7îw+G o‹ÎÌ‚¨À‹ãÃb¹¡Vl2´‰z·è7L2Ì1\fØ/>'¾n8%êñ–ω‡KŒw qލn“=AE¼÷Æ—@Gô:ÓâpYE"+@³D%«§(!ĘÞŘ^’ƱâFÊ£ªÅÆ‘\x—B–$è«:½ÞHà»"-×êT£nÕ\ó^óˆY0 <›ÕÂ¥z…êàþSØEü6\$«¾–ë! N÷ãrõ”#•9ù Ø&Ç×Ç·Ýð“mã}c10…æ±ó6äXýYC\Í'˜kŒ1H×úõÀë7ÔRmeñÓ-™»é/üŒÎÊì¡Û3ûß}ŸE™ù€eô£¿¦33ÏaY1P |¨ó±®Nš8ä(•¨“OÞg‚ÞG¼Â2Hä1.CËp¼ˆf£E¶1â”E'^ÅÁËpwC¡¤ T­æJK) »«ÜÝn;Óø.Œ%4›#¯ áÆöÕçOláKBKT=ÓRxo„§´¨yco¸¸LÕDêìQ?+—­£Ú~½6̶„?ôxWenkA®ò×|;ÙÜ}òÍ”ÛJ]í)ŽûI8îÓ¢Éb½²' ø¿¤¦^IüU³½Éisúñpøš ­N Áaé\[ÉÜFR,¬¬nYÖ[à©?M£™íÓŠ§]°¥cÞÿÔºåû±©,ìogØP×òó 혯Læè_;êÐßFgr¼.Rè›YµÚfO( ÕØ—ô´Õ§¦›:i'ë¡=l‹C÷¡xÔô¹8b •âcÊóxÅ_G t¡ª×CdÑJÓcšÊ`µÙˆa§¸*k86ÜCã‡ô†Z›•/T~Õb®ó[ñ⒵ʪZ·XekÔ†%ÆŠ®–l5íâÆC6“—§h<%kFƒ_[&Xök¾sÖràæZW|Þ4…åŽ÷ pC2ûdãñø.G¿8†'ŽÈ/ŽÑõ9N‚U-z_‚â· РèøjòKMædâzm±ôƒ±Áh3!˜5¥7Ijëè„zY‘ð’)U&ÔFÜ…ô®å•Õ™íÂÚÌ¥;7åÑßÓ×{+Ê>y-3îaåËÜz`9Loœìøl×Rkã:¿Žç’ŸüžÅÎA}fž¼·.P'øF×~€Ê”Ì2ÍF¾ú*3ÏÖz®d¬‰ÉÈb Ør“‹7±§ÈëÒkdÂ}âŸÈÈ»ðQi1¹y»gÞ+^If"à"À…€ÍÀõiñ?‘{€w/J>ÙŒ¼»æ#ì@¸PÈ×ðªP?„ôÀ5Ê DhB°ˆ_öá[Pü­ÆwX¿Â7l#l<¾ÿêtÂñSi‰¼\Q6+§tgô×.5|jl4n0ozÅ<Éú+!eø¾¤’Ô’:Ìf"i!­øn:¾¯™Ifáû˜óÉ\|‹2ÌÇW 1žÅøÖ¥ß+-Á‡á«$òc²PxˆXÁÓ¡ì°°gÀæªQ…¬ÎµÙ&ÜO:I ³É0#넻ɆêíéŠêš!0Xjl¨¿ƒ„¶"¤Oª¥UÄxýNoþæ´Õ®á}']•ÈEl¾šŽf—p ¡Â*a-^ áCµµüTa`>àra%|œê€ÕV³ý5¡z¾Û*Cq³àÁ×P!¡Eà߯òj›Ò–\?›Ò¥å5ÍašàÓªX3I ªNPÒ5¡ðó‚Š‘ªÂíxs–ïö´Í]ó¢p« àÂ9$lE-oÈú¢` •|& ôæš]Í&a!¦¹d aŒ”ìÕžª°6†Ð_«ó&$\–t¶ iwhøyá^­¿{x+èoJZWËÁ€ÙR3ܬ¦ 4%܊ߥõ¶k 6ßyÅ„RR…À@Ô-ˆmAÌ&ô!Ö‡eêÃÒôaiú0Š>|hJ„í(ÙŽ:•Âu¤W¸šìBØ‹¸ˆ ¸Ó  _:wº¨´fHð >PÂö¨Ø+_’¥òˆÌÂÍAfÖä(D Ù ÊÔ8’Ÿ!D؇pB=B BB1B¡>V´Nµp¬ÉK"a„zâÁ[ÄaשCÌL÷ üÔLô¼Ÿ’Rà=Ÿ.©L—Ìx.]²<Æaܲó>‹Mõ4àt芔?L‡žGêÉ4®iWºd<À…é’7BÍfºŠ&G]8`Þ<=?ZŒjóÒ¡2€xº$Æk—££b”–ÑNr q »(×S4šŒÚ…éP¯­#%|ááëІ'!ÎÓÂôùí©j Ýú ãý+ öx/ŒûætèÍâAºX5„^¨ø.*7‡ÒÍ^çÃÁ1˜âðÙоâí¡‡Ñ->z04>tWÅ ÙwbÜÛµ.Ò¡›ð¡åÓª3´5TÚXq,tehVhYh~¨«ùéÐE¡ø0I¶ÚÓ‡Chp&fQœM/ÆX0Ķе!5Tj¿ÀéK&ò®ÁÉ/p à…h­÷q oy1zO‡ÕR»Z®œPv)*S•ÉJT)T ”|Å¥sèl:‹Î¤3ètpU‰øVˆè\ÜV‹sUÜ%ó7ºˆ M/rjqØìˆçôp8Ht úqÊ)ÀѼ`*mO ¯ íËéS ¢ƒÔ0oIJŠN¥)G;i_8551Þ>¨dç§êãí)¥ãÂ΃”Þ•DnŠÝ>HÉÂÎAšåY·ùÃ)¹õN\æPê¿õÎd’øãEþþX‘oóäHð}r¬È†l{tªv5Ç—ƒp|~OÝžŠ,À]5XßÊÿû5»’ÿ´biíiÁ?¤7jaã•¿¹¸„×ü×߯÷Û´iÓ•ñØÇ[¥í©r8Ç&ð[sEAWÝ-Iä?›'ZÞA½¾®Æ1º‘wÇcp±‚*.!ˆÂúå~…q+bã@ ¿f݋ж ÀjdW§+5{™]=PXÌí—•u9û”§ÓH w.Õ•ÃâTíˆì*ÞU±«¾¿¸¿¢¿ž;ÿïCfh?JÓ•û²1~åYb º1 bsO:~,—¯™/ý<jüJÍ“wn9Îâs¼ÿlæ¨ý®ÔšçÙ…ñäQ­ ¬F®ïM¹ªñx.¢a‚Ê /"ÿ—Chë endstream endobj 23 0 obj 14133 endobj 24 0 obj << /Type /FontDescriptor /Ascent 905 /CapHeight 722 /Descent -212 /Flags 32 /FontBBox [-628 -376 2034 1011] /FontName /HEGFHG+Arial-BoldMT /ItalicAngle 0 /StemV 0 /Leading 33 /MaxWidth 2000 /XHeight 525 /FontFile2 22 0 R >> endobj 25 0 obj [ 278 0 0 0 0 0 0 238 0 0 0 0 278 0 0 0 0 0 0 0 0 0 0 0 0 0 333 0 0 0 0 0 0 0 0 722 722 0 611 0 0 278 0 0 611 0 0 0 667 0 722 667 0 722 0 0 0 0 0 0 0 0 0 0 0 556 611 556 611 556 333 611 611 278 0 0 278 889 611 611 611 611 389 556 333 611 556 778 556 556 500 ] endobj 9 0 obj << /Type /Font /Subtype /TrueType /BaseFont /HEGFHG+Arial-BoldMT /FontDescriptor 24 0 R /Widths 25 0 R /FirstChar 32 /LastChar 122 /Encoding /MacRomanEncoding >> endobj 26 0 obj << /Length 27 0 R /Length1 23072 /Filter /FlateDecode >> stream x­| |[ŵ÷̽Ú-KW‹eɲ¤+É’Ù–¼&vœè:¶ãØ!±³;`섘$° ì‰Yšeo›Ð² ŠÍâx eKÉcM ÅiKÙÓ¤¼ ÄÒ÷Ÿ‘œ¥ð¾ïý~ß“}æÌvÏ™;3çÌ™3#J1’!"åÌs— ’[h-rÞÌ}ÕÀ™K®:eóé„4+HÇÎ]rñ îŸÚË‘DZ>oɹýÿ°\¾éÍH—œÝ¢š†ôsHw®éüÓÖ_Í$¤ÅHHŽyìc$Ò¼„¸#àíTD<-Ñ=ò $ u²‰‰˜‘’ˆ…X‰ØIRÕ§„¨n%n`¯¸”x Ieà/Éu(û”ä$Ç ÞGíÝÂç,²›"ýÝA~‹°°l ×QϽ<|)¹†ü-3“õh[”v‘ÇH1ò÷‘9•܉¿ï²’—Q¾;õ2¼MðúEÈ»é—è‚GðáÝv«BämšR}I­âd-]OÿKìý;A!)ìLµ‘yäZò ]iêq& 9—\Nn!¿¤fH—Ú‡^q€wKêÔ+è¯sÉ62J'vª®HmÁ“óÉyäVò$-Wõ©^ÿkòêÔ@ê-ôÝ äAšEý .I-"ùd2‰“ÓÉëàŠ?*«ŠÇSÉ?¥¶~„4‚Òzp½…ü;ÙCþA›éÛª°š$iÊ—z=õÆež½Šø“h€Î  ¹â›â÷5'iÅÓ§“~²œ 5ä!ü=†V¤Õ´†6 ÍBp½p»ð¢x›ê Õ:ŒÌzò,&‚Š–P…΢óé£ô-úzëñŠ$A{d¼oi!§¼ï&ŒÔ+¼ÕûÈ8¥hÁYt€^Aï¥[énúgá%qj¦êËÔY©kð²FÅAü¤L…ßÇÉÙŽçÿ Ž.´½ŠÆñ~W §kÅj±S ¾£Z¤zL= 22 =½€t‘Ë0r·_ƒê ä}ò5 ÒéôGߣI![xT¬oŸVQ•¢º]õrÒ’üMr4y0Õ’êNÅû-%W“ëÉmä7äA̸'AmŒ¶ÒSè\º˜öâuôú}‘~%¨„Ó…§Ä°¸Z¼T¼L¼]<¢ ©.U½«^›ìIÞ–ÜžŠ¥ÎG‹¯O}¶š!O“H;ZzY‰™1HÖ’‹ÑæËÑçW¡å×ò¿›ñ¿Ïgȳè—ýä+r„êi65Qáo2†·ê¢ЛèÝô~úú)ýV hID¨æË1ž÷ / o ˆ‰Ï‰o‹o«ªÙª…˜…©WµE3U÷ÆûŽ>1~×ø=I!YœìIiSîT~ª5õDêÅÔ¾Ôß!¹2)żœ™ºœlƬÅH½Ž¸’ö7ò)æóÍB h˜Î¦§Ó+ÑÓס¯Aƒ¿G0sž £ø{»èÐ=èý÷é~ú7úÅäÂB->]8K¸LxXx^xQHŠY¢[ ¢?Ä~ôéâñA¼Ã[â?ÄoU&•MVMQõ«nU=ªzAµOõƒºU=[}‘Æ¢¹I³‰ÏB&?'|h‹P úí†üÑãO / e.gÿËá ô[ò NþFÇ1ËoÀß•ä3ÈÑ"¡‰~‚™ôk:‰ÞJïD¡ŸÜ@w‘­ä>ñ1úžp5¹ Ò_N¾DH…´œ^/äCÞ"Œ¿bf솼üChE|7FÚIv‹»é ù'ýšÞLâ]ú„²œ¾E&Óëi3Y%“ ¹€îÆ ÃG­¨¨ú4èÛåL÷ªn¾n§I«°…¿ýMt ÙJ‹1ßvÓÓȘªVõb˜é·“»Ð¼í¤€ü6õ3òot)äøIj ¿ &§ˆ‡UXMR‡TuKJH.%{SsÉkÐX’ø™I>¤7BoÌ$P¹7µ*UÙ¸;Õv^CV…êFµÚx‰°Š¼ ÝªùHÓ ©ÐPõ¥êeêyêYê&õ$u…ºXíW»ÔfµAuPõ'ÕÕ¿©îW]Ù-W娌âGПÛÄ»ÅÅq¶Ë1'=¢JøNø»ð¹ðGa¯°KxDXOh凩WRw§:SSS“R¶d2y$ùbòñä½ÉÛ“?K%“}ã/ýÓÑ·n;úýf|/ô× ôµäX.L-N’úòfOÝ–šš|ŸnÂ;†È8äë èÕÛ0.÷£o» áa&•H’!ÐCï¡|;ysì"ÒGNÕ, ï0$óê̬})ceÅ GŸ‚19ÐÒ…Xi_"¥î‚Æ6.2 oR9ùR-sÖ§Yä¯tùO’'Çï·‡5ëvÍ#äˆæ—â ¸Ü(´¨-ª(æü¸0@oN–< :í2²]õ7²å”®E§.\0ÞÜÎŽ9ímñiS¦Ô×MžTS]UY‹–—•FJŠ‹ á‚`À/û¼ž|wžË™ëȱ۬ÉlÊ6fô:­F­JJ[‚3úäD¸/¡ gÎ,céàd,9!£/!#kÆÉu2{n ŠNª© æYÿRSI×TŽÕ¤’Ü@ÊJå– œØÝ”Géâ¹]ˆßÜì–x|6«Â<‘„ß'äçŠf9Aûä–ÄŒµ+6¶ô5—•ÒmY†¦`S¿¡¬”l3d!š…X"78¸æN£<"ä¶Ôoˆ.ï˜È 6·$\A< 2b¨eɲDçÜ®–f·ßß]Vš Mg—&HpzÂáUHg“Ð4%´œ¼2×!7ÊÛJwm¼iT"Kû"ÆeÁeKNïJˆK@£%a‰€os"÷ÒÇ“ nmêÚpb©[ÜØâ\)³Ê7n[çvð¬ÛÏ(twƒžB3ú6Îë›0TÔEãXóÙ«¤_ª?ØÂrúΖúàôàŠg÷a@ò6&ȼKüÃyyÊöÔ~’×"o\Ðô'âî`÷’æümv²qÞ%#.Ev\RVºM²¤{s›Éœ‰³OŒô£§Óe<Æ«³Ø¬yǺ“²Û æÑ™2ZÒÄ‹LfAÿd²ñÌÉèu|º)žJ,Ã0¬Lè›ú6Jõ,]Iê”7!öà¯NÎY’ÉÑ„$H2 Ùä86ÁtÉD<‰$JJؼÐ6a ÑÆi<]SVºvTØ”d téìÂcÝõQô¹ßÏFõÆQ…,E"14·+–ÉR÷0Q¢‘î„ÐÇJvM”ä,d%C%Çï bú>‰U›ƒ„.|ìß,9l-+êÔñ)îO—Ïšœ5wq—ܲ±/3Ug-8)•.gŠ~CY&–°5u‰nMmÄ·ÈK1O_|¬ ]Æ„*„ ŸÉËFµ:LEžCå ©of:ì6øýAù=4š:Äžâèøc™×HÔG2 M7;1å¤ôIÍ3ng-€¢f-X¼q£á¤²ÄœHÂJèC˜'‰ìPÂÄã¶Ð°Ã´0"'L}!hó±E©´°ë·¿[î’ J Yœ‡¢‡÷DVó•… Zf‚.䄹!'•Ž6ÔM:÷bÕ !ÆÕêB )”°ð¸#4ì²°X8oë±0(ùQ X¤†ÿwÀÿ¹¡„+ä$Rƒî(É´…ë‡MXgWŸ{ t)ÞÿêЮ„†w/d Óý…·CûÑ`ü§É.€Ü&:"ø‡”v_É$ÐE'~@A S©mJYi1Âcr8ˆä°I)÷A C'»ƒþîÑT 2ÂÒ¡/„^—û6ö!LÌ/a¥aÙ uÐîÆc"êÎÀª´q㌠øKv—±%[À®Ž¨–« Vy-™¢x5ÚCX%ÕªC"1hÔ‡DQÈÓkU‡(qéf]æŒÌ‘7Ìo˜#}Ó0[o ñ†ñ±*‹ßò[üËUä¨,î:ª¨ÉDVíb<ºS©î¾hªÔ”¨i¬œªkµÁÚxI</Zv®ér“^-çÈwê^Ô¼*¿£ùXóM­Žc+ûáá^áŠÝÛf±ÅJ&½®˜—Lª6Z £©]JÔ+WK†Nƒ † ‚Áß[J;Jiii±])«¬¶÷[%¿W[lª¦Õ~UV6=éï Ð{XoÍŠòêr7ÄF……ŠU«äšâ>­¬iE­krüiþæ=‘Ùãðê‘Ö$~`u<~ZD1KJÙ⸤˜½,°Ç#‘H÷ˆµ.ºzÍÕk"¨²R»FP‰5uõ8–ÜœÃñpúQ<\g­«³ÔI_Q "øTÄHÏjººÇ_£Ñášê‚ªÊÜšêp0 M§kk'ÕÖVU:r,,°k°be9ö\GUeí$Ñ7{Ç)üj?ë¹´cà´[j½Åuö‚ºS~¥ì|;Ø·ºlÅ‹'»+µ?Û+.~âì+ÿd¯(¯/ÈžRžΕr\lJ.®+/«£Ω…E«¿¾’ÍŸÔ—©1Õj v{%t³R¡ôzƒQ|Z÷²îSÝ÷z•OŒ¾)dc´@þ²ä¨æ¨œ*È.Pôæx˜÷>"Š!«š§œˆ¸UÀ­Â:b2K«ÍžãȘÙÞ6BŽÙy¹.o[¶œ]d‚Aå%¿Jk6ù Y>6¤v¢•øx*ÚN­&¡¥ûµTËy[ qm^) ™0!{.qÈŽ˜ãMǘã #åÐnqPÇD5‡+ræå|&DVó)Àä Ò³ºgöLÌ…¸¥n5Flr$²MÄî©l%Kª¦x~˜``+bM—(yÅ%²_­÷«}>Z¬G k>Z¢+òÔ¡‘È•W^IÚ\¢HáÂ,cØXTf…‚Ę E!(N— ±@ÕA˜0Ê•bþEzhYM-lR;Á¤)Ìá3§¶ªÊ’‰P60GØ¡ËfÝÛñ.-J~òé¼»ZµÇ•¶ ŸâÂá+‡†·Þzë}jK²º¢"ùÁžß'”W²Ù ^Ä£÷¬O$._}Ë-Xí×@Öo„¬GÈAeö>ËÛö÷ ö~nýÄþIÁç…?Øtv}P¨µö[–[ûsÎ*úÁ¨É2Rk›uva·õOö}_Ú?/Ðæ¹²D­±¹Üc¶¤—ÜÔ=JýOȥŨüÅZý(mWô‚ÆádiæxÙ0I®šAï~¯ÐéÝã¼ye6.΃aJÂr8 «Â®Ò?¤±gõlHsr Äúc6~âãKKz˜Ð |¹uLð˜ˆK:%Û7°@Ï7T( ÖÕÝL²º‡rùc²( ‡ umF0íZ5Õ*>*,­«+/ñä8Ë箻則_š;5X2µgcò›ƒ×>I ¾\x«¸<o»¦}šÓ:àŽýöª‹oÌ“fO+ižzÚ™×~ú!õÉL·Nƒü}ž‘¿A%jÈÒ™Ô9âa•²|9>Y*‘³¢9QY.ù0üa —>˸|´À,3y+áS™É"O9q+6&}ÙA¸k휞O+`z:Úè ?A§·ÍpÎacÒgÓê }ÙY¹‡OÏDËLè vÁ#мÒ™<ŸÔ!õJÒ 4&”R’n§D%W¤m3&Y±ž´°IL妥Lúꘈ˜ˆ1=IÄœÁB“5h ùH¡ A6Ÿ `i *.É2–dA¾Š¾ Í2“ .}²ßž#ç@¾üv”æ8Ž•ž _mäz™¤7·&#_¶äK55ئ@Ïθ{Þ§ÉOhÑ»÷ÌâòL‹×-¿V[~xŽISeq Íúý®¨HÕ••Ÿ ]l¼§c¼Ï†|yH½W1ŒZGíϸïVe¦ö+mùÞêeÂ*ûï5ïköÚ÷º>Õ|fÿÌõ_ÂÍYÚÿéû.h®Õ´jëJûJçÙygûÎ þ\ØâÛ|Ìwð{W–G«³l^ªC‡Ž”ÔW3¬]ê!ÝpH‡êxÊêU<5\ÞÌ,º^ªx‡¼Â&/õŽR§RCk0N?"ù5>BÍp-¼IÄ´ƒb4WÃàð³¥=î÷;´*¿”åú†ÉEY0}F‚3âÏ 3 þÁ‚êýY4+/\pE=ÅnS‚5>Û M°)Ùæj›+Ô¶*­—Ùý1›2¢Ù‡¹ZD,uQ¨é5È;Àú)¯âòÇÙ;ŒØ‹Òæé •ãá"¾C¼ÿÞ³:©šQ”)„íXúÞQô–ܸ¯Ap4õÎ00ÓL@ýúP«“¸N€è«‚‰Ùá€o šW«Zyôù77®y~Ž·x²·(ùÚ¦o’ûh|ÏÿY53*ÿ5z×ÊwÅèK+ìõ¥Eù¡&êx}/5wUµŸ{ʲµ]‹ua ¦ð¢ÕmÐUt¶â׺sÝ…îInÕÝa*˜%kQ²£pÜ%2±`æxÛƒ¢g¥*ÞeÌfKm£ñD9gf ѲØ8U¥eåÑXEe¡;Oª–.Žk‹ &Þ¶¥¥µº@™=AM=˜cýE~±.+«"ËÊJK%gÌ©8;}Î!§Æ©1/Óë…e:‰ÄލGéŠQöÇü‚?¯&o1S&rž”s±1))vc|@Ú"=!í”TDêzSRI®êQJ·M¨yÌ„¥†A63fŒ4Iƒt ¾yã,rà“iöÁƒíJ ÷×ôP‹?mLù™ÉuÂÂYÅR•nhA§³E4'SUè§Ì ¿…—.eáÒWw.‹O.¶…×/=k6m`yÂΤ‰I;ú5 ç\·Í7¹4:EëšZ6‡e0ûŠLO.P½ þ–„H½Y©3 ‚Ö˜kô[+¬Ó­£¾Qÿ+¾Wüß~W‘%¹}!Ù Ýa<ìûÁÿ}á‘ÃeG*² ™n¯`‚¤G¤pê©!%§,v+QO0-èJQ¥Öh1&FÐïm³ç†­vG^Ôã(5ûƒZr©@5Q¿'Ël _D]aáã4lÑ?¡ß©S¯ÔïÒï׋>}Tß¡õyUÖ>«`}¹”›c>¹Cî•äAY½S¦²«²mù„Êÿ¤ã´:­õ±ÉÀâ ½ßðqü€tË2_˜agL¬<¦ÿ Þîdý_Rî ”J}¤Ü‹ â/öÑ2_ô¸•Öÿ± w~…;TÅòÃAêÎ;¦á™þ7†Šƒê¢”…H¦ Ú„qU3¡ü-vXåÆUem͉‹Á‰k€8vU¼=xÚsk?c‘¿œ±¢ùæöÿÄr÷ŸsnŽ?tá…1;¦²áw¬ºï¶œ5gYi)ÍÝýš[–l[ýàƒ«×<ð“û<ÈýcûÉä+Å5¦§CS¨!Ó!m4ç:®Âû|çÄÌæ¢â’HiY4«øÑržö•ôzÝÄȳÒû¯€ß/ŸH†LžT›ö¿fê>ém›LàÕ|D1Ó#˜ÞÅEE‹dp9™´Jº=ÄÄÀ|ÐçÕ?Ë4ÅbCÔWA+\uéÁïYÍw•LJãÛK Â?pø7´ø6ˆB,ùV{JææÍtý¤Ú\K5—Eíò'ìÝÛ”«›Î~ðÜ9ÎØ´ö/Úâ1×ì‚èéÍ+»;r+âퟷÇ+œsøš KwV84óÞµÉõf_ÒÉ>‰Òó;äHMWr脼´ 9ÂXÌÂXˆ8‹}q;¡XX²²§ LìréÔS%[1 i%Ëö3'+Ðl¦_Âqgõ‰ƒ :æÒžÈ5xÛ¢B\èÀQÐaÖÖ]J¶©.Ž\’¯É6ÔÏ"×NH&½Xźۜ“#Ûcö>»hwyßÏ… v•4~b…}|<¾«#ævE ;lCr‚5tb3ù¯úOH¦Ò7l ·²ð›˜m£¶ìÛ—¼l¼‘M^iµ†yÚ‚¾¹}S¡~[¹ØNµ-µ]h²m̽®ì?Ê^¾mû0÷­²}³}^aþm4aÛ‘ûdÙŽè¿Ûþ#çÕ\ÊvOîíe[m÷çü6÷2m?–ýMdc`SÅ-6d‹TÔWô’…¶ÅÞ í~ÛGl¢>ƒå¢6Ðï¿.ðjà«ÀÁoc{psP ~Ul¾ÿûu¯_‰½í?â×ÿ½ö{wÅ~gßÜ{Ó®ƒ?`ÿpk s ·×øÓˆ; œ§Ì®¶/œ_c5S…äWDIÈöMkC‘HS5ðÐHç<†w ϪáÙÍ,Ù¦Ôί È­5²¿Qnöωuú{c›Ü›ò7y6y7ù²ì wÛó‚Õªœ¨„'-³2Vb?³…Xv‰ àxùPëF—Á•çÎ÷x}²?01_ÌXë=ôøyÈD~®·­\i­‘Êåò­å‰òCåjR>V.”ã ”Àôš±rZ^plÁvXÜêHíw¨|ŽMŽ'°9VÁìRᇢ””V;”ºÇ«Æá°7²6²vM´y¢½hçp¾Â:G1ZôÇÏn&šdò¶ù QÐqD™_ÃÜ4ŠÞf·Ûlö` ÀRØ“Ù+*bLÉUÛy0ÓUc¬ .ûZûÚ˜h#»?X«0T¥ãˆê©+¶“žCÂXI—`mµ ·?iµÚÒ —É g¶Ñ÷顤؈š]qŽ ŽƒQŠë]•€­b‡ð=ôï·ŠË&{ýË\Þà²ØŸ#úe‚a™Å®À—dßA¿ 6áAÅbÅ ƒ‘¾9ðaÛQjÉ­cÖhD·¡<¢¾BzIµ¡Ü‰$‹:#RUq<¸z ¢=nò2÷“’]ÄlÑo„ø7Hº],©¡;½Œn'v¦°Üé¹ œvVPnébÆ)zìy+ØÆ— 놓)7nW²+ˆå³ùÇHÚæiŽ‘ödÒ#]”IsŒ4¼?¼>ÇHfÒ# #›³æi.”6l" ÙÐYàAæ9”)TŒ±†ÛÓÑŽ$ †²¬q; ™`°Ù5‚Áæä‘ÿ‘¢G$˜H™`@Åð¾6^QÑcVؼ5«²àÒÂ(bA! ¼,ð° ŸA Š#1æn¬`—ä§“.3’òYfA YÀÇúÿ#è^ašž}ؖ橊º‰ ¦oà¥dôÉ3h aÇkvÃ?…ÏêÕkzHÏš5«WÃÉ4aúLJÛËië9¨¥–³£'Ò;Á¿th« ‹1[Eê¾£Ü6þª=ØG&e«Hz…Ÿ}eÄ]Η•×’{Ó+LaxÄëË•X_NÁúâ$ë”,r|/3¡R˜!óã­ w#;(ž¨«÷¶9Q9cÏæY$6T|Ÿ!K1©OÚʶ®‰û´Â:+ç»`îþ‰Õ2½Ý?þŽì]RáÆ&ÓÅ%ŠcÌLÔ<êy´ôYÏvï³¥»=¯—ê¬Ìm9’ä~EÅŸ¬¶øÊ×ûÖ—oòm*ßâÛR>æ+7TèÆ&Å…8«­7UOVlˆX¤º¦vÒäºú)Sž¶0óð¸_gâäÜlj4XFÐæ€ 1õmVOœºû¼?Qל®ÇžQŒVõÄ}yÙŽ4Y…ÀôF…é7LÉä{ÛÌÛQá%ß[VRCµÓóü†¿ê"ƒvº¦¦º:Ê1`§Š•à©\‡RYÃݳn¶yë«'ü¶ª>Ç cȱ١²:Fé!Åâ•}1ŸàcêÁÇFNáEOZà ÀÎáš0'  §Âª>8 ‡Â›á0dÏ„Ù3aP&eåxt¸AšÂ:Ô®Ù2…š§l26eÿ”CSÔoòˆÈ K—ŧ(SãÕS”ÆéÕS†šZ›9 ±Sæ#Ö¹Ái=ÕS\MñŒû‚‹V$²fuOçR#Sè”íB’4I‡{ºùZð D•iL\ÃLu°Æ8­±qZ¼]¼©¾"TZZ™ÚyU²¦¾¬¬NØ-°ºZ’g¦塲¦t-I2rL4uz¸™ù¤Xá’OoýÌzªÏ›ä%LöSyùP”ú¢4êª=yûǼ4€ Íšž€ØòAž˜cØ_ s3G*–ÌXž0Š™aúé-aÕÄðÝ9yCÇÓg/`CÃǨ zFë9ó&öƒ1gGzÐZb±Õ‹oM^^x°µ¹ºÉW4©;yµÙ[ŸÞšé×é¡Â^ðTøh/ÃX™±üwåŒg„QÍ{†}¦¬ïæ¼ç|×õ{oþ§¦o…ï4Ù/»^v Ö¶s>q}éV}à|/ÿsáSÍ'†/MŸ[µËœgç? ~Hÿ`Öo³6kW giú ç˜Î¶.shì~£6™s§Ø-jw=UäYáTy®°ðŸ.¦Ô‰ºíÈñ`K}€?è`[<| +J–;`ÖÇ­,ÈabìN‹ Α¨¹/¡!«™ ¨ÚtŸ¦ÏT—]¿ù¦¹îúÔ7QñšÝ­K~uãŽçnØø}jퟮ¾ò£K.;pý_^qæüÁá ûzŽÓƒðiÝŽþ “jºW‰ŽûÆ‹ÇËÇWk4nCXxÚÿ²oñûeŸR¦ñ¹q|è–Ã*kó]ŘUÇÎᄎ¸•Ê‚RÝ KþÉ»jx.£á'Ü’låù±G4ÏÛær’ë "~OÞ×Å­SSé/Àí1S!ëå`LVäNY$²$Ëò~Y•©œWë¾4/Ïå"á¯q;Á\"1cáÍÌ¡†v ;ԨɜfŽ>a~F‰9«áêb'ˆðsÄãðT¾â0ãà‚ûVªÎcŠîÄ3DoUuQ‰7X„K¼…>ZDP䋸pº]9áæ:á$1VÂùWePUŠÑñ'yº¬¥åîü²P¹;T—æ£|ÂÆŽ3:5]Êla&Ò¹°€Ë¤ÊYPÆü‹å,àéæG=¡ÿΪâZ‡’üèg🲓j;…\q³“pžNœ?šyÏÜ·hÑ·>Óq`o¾¹÷îÅSŸ¸òªÇW'\á Åb3*bÉ¿Ž¾~Íyåôg‘k»Ïïh›wï=Ü>\ÝÉæ[1½ø™Ò»4ÔÊÖ%”WcÚ%á é l•‰éRæW²ÕÇ÷Ðÿâg{n¶—M{lTÇïNXܪùѽO³uV‹\­¶(­ü¡j‹)¯R±J¾\ŽxÃ?mwUÓbSÖ(õ(~s§iò\¢“!Òº>ˆµf3Îbò"”`[ÈÔ©%@üÌIÞéïóú5~WÉ pn:0ï÷'0Ú™«göæIÅp¥C~Í©“”« {@(Wî(µš%A”SPm-A"YvØjŒåfÙ§Ï•³Ö_›ucì­¬£¦Oêþ\ÿ]T”si¬ W¬*7ˆ*¢-ð;Œ®˜P.cìc,0Âñ4R^YmÈ`¤w ×× É/­­K—³Ò‘Îù,Í1/oïH—ó§[ÙÓ;àÍb4•¬¦š˜« IK}†Ê>¯°º¾A4 £Â*¥%VnÅÊEÿ$­¯e}ËÁÑÜÒÑ"øZh‹ U·(µ5-ïMÚ ÉUÜeÕ¹K˜oûý"ñÇqBó^ž¡ÐoÏRà¶énœajÓ2( I›¥„´KÚ/i¤¼6í³ÂBØ38ÉËòzæøªäªX•X…Qôþ`u•kfGúü7Ò3ûp,Oæž €XÝóqv)ìØÉñLåx? ˜Ð8ÈeóúÄÏKú(%«Ùqþj6YóˆbÈŽ7±` ZXÐÌîfs`˜möóö!cf4ëvEã9€Ç‡¯X:]'º¸¶dÏ0­Éh(¹ˆ€¡%ÞÊpµ0®–ŒÖ<±ÅˆwSææaG‰ê1ç†8LϨÍBœ8ÀÂIŸC!›5Ö`]fØbcvp³Ö‘“y@l®<¯á¢¾yàΕk–ÜøQ÷qsÀÞ:TiŠ^sêÍsB55~;~Ϻ7Z¯n°ùM%“%yRh²ð Ÿ¯Ð‚›D’9??tëÜóÚÏñy³Mñö–öxqeQq©ÃY”—gÍko;ç¼¶eî|Š*›œååLYÜ¡ú¾ òذKç¥ÃŠ/„¯ð„C!FDí·d º¨Ëe/+.¦ƒÆýFÍ\EŸW*H{çÂo±3ÿu'<؃ö„}—}¿ýÝ !“e ÙÕvWÙ\ý©s î3¬² iïÙéï‘8Õ0?¢Ð~8f›œú}Ì/ãHV› a\PljI_À¡ì}O>¿ ×óo¤»ýø™_µ»dÕ/¯­òM‘+’cgîÜÉõT;ÓL”/h8í럞ãoÊkˆy¢\L_d…09aw²_§¼è«»Å›°N销!'Œžù™ ¦<ÓJÃJùY]lšlZ£{ÍŸ™5¬Ÿpcâ†%+PÚÛ{|e:ÙÄd+%G±+6ŪX”\Å©ä+Ål<ñ²]zc¿·Ø¥Ñ0p(ý¯ß˜¥ p‚Ó‡ƒø‚Î~*¡ßó"þg=ޤÜŒ{‹eÈJ}Vju•œlÜÂí62ü;ñ¾¥×ž'qláaF=öƒ›°>á1¹ ‚…[ “&Òªÿ5/DžV:¥C’€Í€V1È– ‡ÐõH€UQzm× ´Š$wâky8êÄaU‚¨ÁgëHp=T­ þ…Õyã=yN(Ûžy.e›œ»²uÞZ·A—ö7;3Þfh© ƒLX§lÜ ^Ÿ¢ì‚÷ˆš¡ Û}+¹e™,D$'ŒÊ tç3{cZûsîä C(b£0‚‡8Æu †mäiOÈÆïUÕVeŽàƒøÚ^Æ%És`g +þ4/·2ÞN]LâÉGÞK>âaQjÃ1 sþwôe“ïäpîÚ(ìd3¢®¼Î˾ŸJñ>¢úOÌ‹°øåœÍÖÍ9‚^0‹šKð‰ŽÐ¶»ìû„½Ö÷sÞ }!|fý4ç“t½C¸Ãv·ýîÐau—uWÎÙcÝ“sì·îÏI‘CÖ¯s²ÈP}/N9°ª’!Ü^%Cù5d(¯Æ®äÕØØ ´öV[3é]#xiŽyÚ•N+W#Â.Ú Y‡2¬´>"Y¥œ^ÒiíÌÙBX»õ%B(T'Ô†Ú„¡Ó-óWÙn²¿I_^µ¾d{Ãþr΄v…¿£)‹‡É‚>¤ »¨W°„á)´*ÜN›Ã§Ò ©i³í±1¥ÈASña\õa–ì3ù5¯«¾£ú—àð3ÀËD¹btÒô]Éb±î8v4>° „v ÷÷H²Û'lgÍ8pÙ'/æÞÃô-P¶,fHA‚ B¸[¶J1ä8ì9 û}ŽI»(¼Ðj±CvpøƒÛ>¥ˆI—ÕV*²‡sD…B›•Šì{É9bØNl®Ù½}”ž­H^¯Çc0è5XÂðÅ@ƒc‡ð±(~¢5È…k?9„ §Dæ²¶Ò†¯]þa;¾ØqcK¬˜‰3-^éPú˜ç7ðcÜ߯Îz6\ñ;é¡ÃÐñ;ü™¸ A½§šO `6I†™ƒŸIå„dñM¿Ã‰S›3Û·¦^ÃÖÍ·Õ"@ê#ÅT†²îÄ@BöLq äGÏXqÁ‰`‚HÃ#k؉Ôñ¿1¹ä`ö‚ Ÿ½À¼aXÍøìæi´€§yÂÍÓÀ<6ñ40ÒC#hÒó4l.žæõm<½k˜§ÑVþ<0Kgձ䶬µyã»)¶Gk(ûú(óuTñC (›­Ê6¡bÒZåg/<6¹.Þ¾³=^àþé¡ÎSœ±xû íñIµÿ½4y°S¬‹0ER.;“ÏÒÙÉÚ’¹;P\§odöQ¾‡¡[ÊDA¹fºy9ß|Yef—¤ Nõ¬õ^g¾Ö{»Gmb™w 0 3î@0h¾Íükóvò¤ùe³Fåµ{7˜î0ýÞ«ŽÒrS±t‡ççÞû½O{^'/{>ñ¬[•ÍæFó<ó*óäwæƒä Y4טדõæ[Í$3úG¹(«¦T {L3̋̋¥EÞsÈJÓrï¥äRÓ#äó—ä ówÄâ–lÞ ˜&›g˜›½{É»^½UÖË9K6ÊÙQkÔµGsôQK£·Åíñœ[‡]×aé°väôZz­½¶^{oŽÎl6¡+ÊÊ$ÆÛh¤ìú»Žf2ÿË*k¤Ž\'ß™{àœL!À‚U·î…PÚÛYZvÌ bñGO±E÷&9'‘mHÙ×%s£á¤“vvªŽó ì‰g^ÏK,ìe^\¨T« Kee£Â¸´íP &3N&þ¨xØ6À„ ™zD†’Ò¡5á vê#Ä+Ü¥H ßu<à [ÍÔœ41#+kÐC%ÏzÏ~èî|z=,ØWÏÑ{ñ ß8} „ÝÁMÆq×áçž%vÑ_Ãà+uîñ¥:­/ø¹1W‘ˆ–ü¦ÝPÛqi೑\;©}'ƒ¹§'´=ƒ5[ ˜ëLˆo3g¦ÒŽËïkøÃ¬Lxš´CœÍC,`ÝÊV|ò1¼f ‹mPôÑÓ iVN¾ôÍi&|·3Éšv;Ç$ ^Ú‰›:š¹î3q…Nþ²²:Þþ,òæ¯MÇrþB[¼¶&Y2› b²‘-ðohá}\”>:LÓ÷ÓK;äïèÒ´,Â9ı!3&?-öšŽèôøê >/}(„'pê£ä5Å)#%z^Ÿà9Í#ãwÃ>ؼ(SÿòX +eŸ\Õn²ЭÚúx ``:àö δ®D½€«§"~xàNÀÏ^¸¥ŽG@¿’ÊB‘°_Ü«ú‹zæ#íýºÊ¬¥Y¯d¿cú­¹^Zc9Û³½l¿.çÖÜ]®kxërÉטq×à}x£¤¿.²Jý6|ÇèQ¬y¬7Ø/5à~YûÌ–…§6Fš.\³²Íœþ‹:ç—MXµlö^Õ’A|_ø§>¹ÈlÆÝŸø‰™¤ ¿[0 ßž¥“ÌÅ·ÎçãÛ½§’Eønr7YLNß¶È×8UEIà‡9Æ€^@àMÀà @‡ï¥ënÞ`%jâÃUã( Ia/`ìXjb[[‡j¢ˆÉ‘,S¥¯±ß3[*„1„ @ÀO›ì#ƒ<6„p3mE˜à±]ÓϰR,‡c5÷öDžÏraŸ°Šs“…½à²µ÷b·¸Wx˜çJÂûh“Æ   ‚ïç^çaá=x^Þ#{¢ðžpË'¼;\mö5Ž ï §òôÂÂëø{ ¯âït¨™Ãkü­^%»„WI €ù}€AÀfÀ.€½óÞm«ðÂ(BÐ`õ_#›;XeQ;ŠXœÓêEHÉzárÜñßNë…‹—.\Z/\¸°pÏDl5` à|ž³ ±sçxÎ ÄVΜƒœðèç<Àc<Àc€óðÎc@Dl5` €ñÀ¤ðà<„ˆ­œ `<ÚÁƒ"¼p àR{‡vÐoývÐoçôÛA¿ôÛA¿ÓoývÐoývN¿ôÛA¿ôÛ9ýzN¿ôëA¿ôë9ýzЯýzЯçôëA¿ôëA¿žÓ¯ýzЯýza`›ª¾1õ`PõœA”3ˆ‚A ¢`å ¢`ƒ(D9ƒ(DÁ QÎ Q0ˆ‚A”¿@ô£ ý(§?Æéþèþ§?úc ?úcœþèþèqúc ?úc ?Æéþèþ§¿^Xމô(àqLµõ™€e€~ÀYˆõXÖ }€%€¥<ç4ÄNôÎà9‹ëtóœùˆ-,œŠœð9|ú9ŸðŸðà|Àg|Àg€óNCìt@€ñÀr:>à3Àù ó[X`|zÁ§Wx„,/±3Ëýö>½àÓ >½àÓËùô‚O/øô‚O/çÓ >½àÓ >½œO/øô a¨‚S/çÔNàÔÎ9u€S8u€SçÔNàÔNœS8u€S8upNàÔNàÔÁ9u€SÞ¨|:8Ÿ8øÔƒ‡p&` ÀÞ&qðˆƒGœóˆƒG<âàç<âà8xÄ98xÄÁ#qÎ# %œG<¢à(ç(xDÁ#ÊyDÁ# QðˆrQðˆ‚G<¢œG<¢à(ç1pcà1cà1ÆyŒÇxŒÇç1cà1cœÇxŒÇxŒqcà1cà1Æx—Ó…Ëh¤äHË÷šû [!#[ +Ë 3‹ ­&HJ$&¹(ƒ|”BN !/!HEÒᇔȯ°4ÏÍ~òCc­þ­¿mÜŠ¶nA›—¡í‹ÐÂV´´ -n@Ëch_ÚYŠö¢Ý!´.€VúÑZY˜¯¸¼wüs™ïÀÀj@ 0Jó”XF?¶Z € 27Û}ÄáÀ.ÎjÑ)¹ÂTvɦÏópÆÃ‹xx [yX¯ävf?ß™½±3{ 3»·3»»3{Fgv}gö³4IÖʧŠg]öí벯[—}úºìöuÙÓ×e7®Ë®[—]».;ЏL¿¢ ¨økÞÁÃ[XH~àá?y¸Ÿ‡gð°‡2½´a8›à+âG†ýSñÞ‡‡ý@†ýKöWûž£â !”øèýÃþ3û›aÿ< åÃþ ³†ý@Ó‡ýM@Oúc¾ïý£*møþì_ã{ËßîKøë|÷±¼aß^”å[ãøúý%¾eéìEiÔÄÐÓ¾©þG}eéœÒtÎB›Þ¦ßífÖ®³ê$IgÔt:F§Ò ¸õwí~¥”íÙíüî%Ø”¨x\‚ N!Ö,ÄèlÀûvSa&LÝ&LJØÄY¬ùÓé¬Ä®3ɬ¥râ›ùÁQj˜»8¡N§ ë,2kÁôÈùÎY ×üY‰ùøžQajb¨y–ŒOÂ5'w5w'Â<:J â•™¸‚x}&>„xk&Žú݉I‘Y£ÚÔ¼ÄäȬ„¾ó´®m”þ¬©„p=¨,è¥)–u­›ýt¾JE}×Þìf8uíÍÝÝı6¯î4KÝŒæŸúxf_óqwt$ãüb9Œwç%ŠÑ÷8.7h}UZ_PËògÍGææÇµ›[´›1éL§'qǬù]‰”/–‰ÌÂ8Ηá:âÂÔ–æíÂ4†º»¶»¶ ñv16îÚŠ—> endobj 29 0 obj [ 600 600 600 600 600 600 600 600 600 0 600 600 600 600 600 600 0 600 600 600 600 600 600 0 600 ] endobj 11 0 obj << /Type /Font /Subtype /TrueType /BaseFont /JHEUVA+CourierNewPS-BoldMT /FontDescriptor 28 0 R /Widths 29 0 R /FirstChar 97 /LastChar 121 /Encoding /MacRomanEncoding >> endobj 30 0 obj << /Length 31 0 R /Length1 30956 /Filter /FlateDecode >> stream xŒ} `Õÿ{oŽ™½fï3Én’Ýp¢å‘K  rƒÈ)‚g¨ˆ¨hëY+xTñ*ÄšRêQ¥ÐzU[•¶ hEiK© Ùüïí°íÿÿo–}ó͛ٙ7ï;Þ÷ýÞ÷B !ÒB$bM_0m‘ôw¹5oñïôåË÷/úÝrB胄¨½f-š½`ò;Ûë„(¿}åÊY¯¬ûSˆç#„4=2gæ´ÿÊN©'dþü¾ßTx8p½ù‹°_:gÁ²ŽçB—`ÿGØÿæÊ…Ó§5ÿñ¢„\¹û7.˜¶b‘ü²ã>B8°Ÿ¸jÚ‚™ï$^†ý*¾¿háÒeªËfbÿ"ì?ºhÉÌEg÷~Žý/ 1ºPGñᢒläRQÃx¥ø“ˆLA©ÄF4¢ ÚÈ¥=Oó68í"nbññ“ ŠÚ “‰’‰“RHŠp·$)&%ùߟٔ’I“2RN*H%É*Òƒô$Õ¤éMúRKú’~¤?@êÈ@2ˆÔ“s”]$‚oTyšDä4îDº>Ã÷ßfçváÇù–}Û´ç¿„l"/йäò ÙCáW›ÉNÒF^'!2„íäeò!u(Ǻžì:^U‘xž6òÚ!e;WeÐo z©ý>Ïõsò9@Kè/ØBÅ¡ôQ,åÚ®wÀñÞd"Zû4~ù)ý»Ÿ›¤Wåa]çúåÞÛäWäO4J«é:‰U°…ìQi ¤« ¿íMf¹èïqõi†î`¶_zB~N>©dv¹À‘4ù1ù ùuâIt)ý}þ… f—³³?K?’Ÿ‘g›†§¾Œ, w’çÈ¿¨— ãè¥t½ž®¦÷Їè>z€aç± l>ûZš#-–^–ÏÇg¼¼T¾Y¹M¹C=’œÝ›ýmö_]}ºn#ã «ÐúûÈ£x²d?ùŸOÈŸ©BíÔ…O‚&éDz>7Ò;éãt}†¶á.èŸéçôïôŸô$#ø¨,Æ’¬Ÿ¶„]Ã~Äaûñ9À¾dßJ!©XÊH}¥z©QZˆV­–Öã³]ú“•÷Ë]èç>ÊýÊe“òœ²G9¦:l?ЈöÖ©':+;?Î’ìšìýÙ­Ù¶®?Aó¸¾Å¡iõhý4|æß÷Câ6“·©}¥•ô\zzær:.¦+Г·Ð‡éOEÛFw£—Þ§_£ÍNmîÉú²óÙ|.c3Ùb¶žÝËÚØ{ì;É&Ù%·*¥áR“4SZ&­”î—Z¥·¤¤?K'¤SøtɆ\$Ëi9#—/—¯–•?“?S¦*o*‡UC] Þ¦¶«³õ³kkgk²ÝmÛa{Gk†tþ’l'/ž10^¥UÒPi;¹‹ÕÈööÈóåd†4ŠARÙ&º†Ý@ÛX©²BÄÑÑ䘜F_¿Ê6°l4ŠŽ¤ãÉ<Ö;wMÕ/? ª^þ%9*ïÆ³ýW^¡:èìkÕA¶RÂêpÏ_I½äŒô&ùPú„ÚäÇÈdƒ†èQö´4Rð²|®2™$¥GÈϤÅô² …¥=©­ƒ¦ÏÂ.L }è7R‘ØhHQé/äf2Ÿýž…¯!Ðòlr©¡×“ÏÈSЊ å*µR Ð7Ø\y-óÑ6Âägðtu´”JŠŸÜB›¤‡Õ¯Ùäj²_6ÈÇÒóhý~ö3i”|L¹˜ÎÜ@n#‹»V‘•Êdùwt6‘è$’’º]/õ‘“ØÞ«26m´{ìÀyÒ(Ô„!9A.&ÂB<ŒÏƒ°2$h.tüX±ß6uk'³…Õ!D~3{1™Òõy¨k6¹ªë^Òö`u×õ¸â&r˜ÜM6Ñ[³×‘E°þ@·/R†±ýʰ®l-û€g÷Ÿ¿èí “/ðùFÎU^"kå÷ÉxÒе®ë]Hw9,ìCä r!9„§ü w¸@ê 5ÙÑlK×0iž÷2®ëé®"j9]W’1d7ù©M!ÓlkðÄ çY çžS?h`Ý€þ}kkúôîUݳGU¦²¢¼,*-)N&Š â±h$ ü>¯Çt»œ»¡k6U‘%FIÕÐ’a͉Öts«œ.¹à‚|¿d*¦UÑÜš@Õ°ïŸÓšà¿›†Cß;Ó™³þíL+w¦uúLj&êI}ªÄÐ’Dë¾!%‰v:eÜdÐw)iL´ô(A¯´t2‰$††ç I´ÒæÄÐÖaËç¬Ú<¤GÝb7— žiô¨"[ ;H;¨ÖPÉ¢-4t. ¸…͉Gl– Ú)ÁOq)5tڌֱã&K&{TµÒÁÓK®h%%ç·º3â2XܦUÜj·IÌmÅÓ;[ª:Ö®k7ÉÍÇŒ’Ó¦Nn•¦áC[=ÜwHkèÚCá3»¸¸wðäÕgIk‡†ç&øÉk×®N´n7ù¬ßÆ’ü ¸~ËRÚ×í×S#Ç'p7vkãäVz+n™àOŸ*÷|3K†òšæy‰V½äü’9kç5ƒ5ѵ­äâ•ɭѨµ³ë ‰M¬0¹$ÙÚ+iœ6$¾ÅOÖ^¼r[ÄJD¾¤GÕÓ“ëØ-.wžp8Ï&f¢ÓsÇ%NçÔÈ‹O÷,å-*ÑjA¢¦'Ð’É%x¦¼˜9€¬> À_#ůZg€#s[õÁÍkͼH[•”Y’XûO (9úå÷k¦åkÔ”ùOÂr99-j­tZ7ݚɴVVr± OÑÆsÅ~ßUËÛYIÉ"3 ºŒEßNkXîO&9ƒïh·ÈØim79·Ÿ WĶ«:ÓØÊšù‘Žî#‰üHK÷‘Ó?o.$· '5Ъ¥Oÿs›AßÐ9[iðÿqxfîøÈñ%#ÇM™œº¶9/µ#'|o/wœw(ú ÇòT«oðd)ÆPÇ)“ÄQåÔ)§OÁÎdG«œÂ?UõŒv›©541¬Õl¾ W6Éd^gþ?jï:Æ%6g~–ŒÖ™|CsÍnô½ýï5ϱV9&‡œ0eíZã{Ç j¹VŽÈo ñdÂädbp+™ÍLá_{WÇþmŒµZè2™-Õ±üî÷NŒåÔˆ?.=ª†Áf®];¬$1lmóÚií]-W”$Ì’µ;Ù¶gí¢¡°v9ÁiïÚuG¬uغFôØ:êÁÈù\O˜œrÁ.Ý`Äa’¹ƒŠpEB¬r~£‡T[;{ÈòE>$Ã&¢$¢©Ê!&íÆÀ¯Ã ìIÂóD}gýhóxý¨ÎzÒÚ<…¢w¯¤'éI¡ öN%¤ŽS–BN’ù¹LÚÆ®A\¡Às¿z'o¶§j•ö®o¬âtE­]50ÔÈ”(ŠjÿJ×4IbĦÕn½Eg:zÑ 8ݵúÇT’뵜žZq,~:œAC2¼%fg¦ Í@ƒL|:ëQP·®Ž{÷¢™ŒOê[jD¹¾Ï¾õÞ×KÚFCÇŽe?Ï•Š2Ue¢i+@‰*_1"­JÐõ”Ñy*¿£y¢é(i8*®Þ»Wî²kzŠ‹yÿùÏìWèVJ®ÏŽcÍÊÛˆìαŒ27%¦×¦™f;­ÙF6¸4l-mƒë2"™RB’¤ç=?Y'.Ýyâ¨yׯo@—Ò&šfžÚþýúר6|&¥ŸÜ÷›QSv¯ZYvNI†f²ãvÓo¨ë«;Oh\{ÿK/g‹²‰ïݦå(gå&Ó “¯Î[`l(¶mdƒt™ zÒfšl"ˆoÚÜnAjs:ñ¥å6 6Ñí*r1×óÞ|3øû·vúJˆ§¶,OM€É:W¡Ï‹Ï)»vÕî)£ögÇуôO»wÞ¿vÊïNv~øUöïYMôÓ³ÙéÍˆÉ 2z»A|Nm§c­4•꣭'“°CÔ¶cà¯.„÷µR´Ñþ؃è¯ãMÇ™GÁk0„3þ¨Ù)Ó»W ¸íWmeýúõß±oì%}êúIûö-¾#=*2GíçÑv6-€ìWY‘El‘ÄFÑQ¸e aQeNˆÈ‹îäÒu¨Éü”T:Ú»YL›|}“óXmß¾ÍÇi»P¬Fû%’²ÂŒ7·>×ÈÍDÞˆãeÑÎMBfrÍÚµoß>þ[DÛ¬2"‘ñ;‰ÔõñVkïúØJøë(“6H›%&-'Ô³¡®ÐIéaGÀ»gp{yÛµèzóøQ3'/«•ž™¦̽\n2™­¡ô™õÙÉåËïø×Ù¦tBúÚ•[K÷˜Î°Ï§Nt¶woóxñ•¥›&¨B¿RØÞuÄ ñ ùѸ G N'Êvö’å`F(”(2=Œ%Š jÕïìãå>R}” I/÷ÂYŒma§oèðz™¸¡¥»= r÷9hÙ½>6±ÐÏëøµ·âÒ¸}›ÝÎ&‚øÒrq™üowËdr÷ãw7³ú R©/)¯¨/Ù^ÓÞˆÛF8\ó3\×z¯õÝîÝí==;u¼bÑÇbfÜ,0 MõçämðU4lõ®cV´Ð05Uýu<êÇ£Z< ®hѸä,4ÛÙ“ÛÆx¨§†·ó' ¢;Ü”9Œ¥¡·ÑÛV²¤–¾ÄV·1éËáÙÞ€€{!»‰Él+%Eôî-wÿNd8…1m8ÚÙtÈã ÕÁ¾„êV»zf\`)76Àø£¼ M´iIcc*L÷‡„÷ë×·6]R,Ľ¦pÆBµÉ¶SýY(õÄÃ_oz躰¦O^ø$ðÌ·èÊO_éøbþ‚ÕwfO|ðAöÄ=WÜ6έ·Ïš½fàˆõãWmzá7=-Å*œ·ñÃO6Îz ¢jïšÝ]„ÒŽ»A'̹åæË§¯¾åTרõcžjùÁ³›¸ýZDþ,âŒÑrÜ-µ(LRTIcÊKl *%6e+³Ô]t,|›±½Ÿ£Ï%dÕäzšÀϯ¶]2E(\ýÑÑæ ©ŽŽ:Š¿p£4B\Ã`ái€ÒÀ"éÍSY‰±U›èÃÛ€kýb[ÎÞ¯ -ìnêL%›Âxàù  ŠEy”\Ôç0¼×«$ª%ªäÛðiZP?ê(oÄiðˆò S}%zªKz“­ÊNÛFhý¶ì,Þ”(ðSlÄEgï .7Fp oËß`WyÍq«‘‹5×Ou¢"Êj³—9[›£7›k¤õæÊ«j‡yÌ´kJ#àűæ{«ùÇ?œÿpé²CvÊ. a¼"˧KSm6h 8Æ/î½¹¹Þ“„ÍáÇ!&A¡¾± IÐã„ìðãWz¡¢h…ª¤¶³E–N4Ç磌í¢v0Ûny 2Ó&]<pÝ'²´^¦r;¥–}¬£Ãö‰CZï ¾oºmûmì&[‹Ù~è~ï}1ö/Ž@†ñ/ F#æÑ£$ÜP=ÚpŽþññ0㹺gXl…p{êêV›{÷ºöî]­ä¶.G¶ÚÇl-D˜Ó&»%Ͷ \T®tÉbŒ¦ü¯#j‰””|I)]¦Ú$Vó[6ù£ç:üØôo +Ž×(»¾Fwg‡°)ôþ×Üyç• ‘ÈŸƒW ù•Ô·“ÈàÊp»](ËÃJ&•Ì*Yªß¢«s£W+‹ô¥ö›•›íjYP—Âe•…Á]÷y +++*H¼ =W„¡˜há´êà^›ÚÞõ©UÃ-¨êå–RUyß«¿:Hð\õsIP'¤ÒŽ8ÿ…Ãàç9¸døYŽhUAa‚r Iðãàê a¸ÁÏñ]›`sŽPyÍ1 ×Õ”4•kU®‹¸ ÑÆÎ¨£ÇsU™ü¸†#°ÖðÓëëª=Ü-§Bãh.QãIöáVE¶ÅÅJh²OnPK— ¢èÓÿ\†ôý,½éÍ¥³fßz÷%-¿X—ý!=gÕ€ GûÁ£Ù?З¥O8á¾uÙ”];g^öTMÙî–Ù[š{K{‚³FXXqr£Í1`þ°‹Wb£dV×gÊrø_äííÓÙ¼FsC•x¾#Öå¼w¤s:,ϲ‚rKÁzò°òœôSçN©Íùšó9TðË[à)(*ÕrOeÇ5ýfTæ®ÞÖò:ܳÃêQ^gº •c¾B‡+”u3í¾¤”ÒhQ(Ш†1Q¨E §£·yÌÓ4Š[1”ÜoÀHèáæ .wSÓbth†.¡!U.).EÇyKkúÈ!ú¯Xe¿—[i¹mÏ9Ù_>š}ÿÇ›éà=¤Uƒ^©ÙóÃgþ2uÁ§·=ñgÆz}òôªß¦·|³ÇÆ{Ï~}ÏKÙÏ×îæ2Í€êe dÚÞ;lU'Šè`-'Ÿ³ÐM44Z§E]ˆ•np!ÕâFŸ0KÑ¢ó¾A s¾é¾Â¾¼ roÇ¿½{ ^iõ“b6MÕMÖd5ކ™j7  †¤‚þ /(©1)”¤^аOÒ áIôc&S‰¿U´‰Ëh±7àgÐT²OÞï*ƒ\>J¿}nÊË–Ž¾öž}·f·Ðº{~Ú{訮ýBö-eW à¢+²û÷>Í>3­Ï ýzýü©OÿUY|¶Ï·ÙÉ}V@U 5Íf#’ÌÝÐ íD³qù(0½µ¶ Ò… #ádFÔ)ëÿsŸqÍý¾Â:]š!¡ŸMê•JKIÒb)Fp$x'Rª† ]|^ÒtYª#;ž¬¬™IPfîdæÇ`.ã¨ùPM1ÇøïÙ’–2ZVNÔ0y…IOÏóŠ<ÊlVO„æó0ªÛëÌà±°Ïm&¾<€H‘Kbñh<—TGÚLÒEi-h=v$IÐíKâd¿/aÃ^±’JÒ¸²í÷ (Ô“IR*¡€„ ç˜I¾C!ðv}SžïY`ÈÖ“Á„pÂï•aDú{¤‹Ø‚»³6þ>»¡mû‡ ”Þ›Þœ¼bÇÂ[÷\“°š²{n5{[¼Ì»‹m"NÚ{«’ ÛÛ2º‘°7Ù©}ÒEí8ÂÚ¤è±îE&î3éńҬ´(P¶i›‡€Ç!›êÃP}‡€ŽžÞ9Ô„¨ÝÀMl÷!§ˆNVß ‚lzž B^&Ž®“Á÷è½'b‘­(åP¸eüf‹Ëà‘ Ôï¾³#YçªJÖÄ{gGÿ:WŸþ‚ÜÞµ=Ðõü¯Q Y Ô¨±ˆCýúÓ$ÌR<bvüÒ^ÁH_ä5(/e'mÎNVvüû=Œý±tê»aò›'ûÊO&„®<]]Ñé [¼ðœ=ÕÂŽ ÀpŽXINi6 !¡Æl’¤é2cºM“¥„ªB…rVDÞt+9]‚±µ¢\Ø”¦„&ìcíÍöEö»b×àï@À:,'Œ÷ÿÇ.äí·,ìÓ÷ìw>`18˺MV¦‰®&ÂHÞK§-6& (åž0'‡-qŒöà‹O­–@nìÝ‹žàB›f «CèÛ±cXfõÉ‘}êlÅèì“#ymIçµ—ÔÙ\~|}|ÿøÈ‚Y2ÀÉo¶òä®(ÿÊ&ÖP>ŽPÏ#¯Il×k§²`Ù*ù&°«åd X}:ü›”wG#¿¶ÆFÝÔoúý±P,&˦췇ì1ù™Ð׫.) ÇX¢ÀòŒñ YÑÉÊdýs¢çrß”ÐåáIÑKbw„bf¤P’¼…v=NÀÁãÁ7v r£ˆcÂåñ…° Ž Äw ˜"[´¥€¸Óœ‹ªàQÎ|DâÝ‘M.´ÉùB°@Ix|óÁ#„7>“$ûÈÜ ñM“ÔôÁäCxC¦Ó5´ß›tØsmÙ¯ìÏîÚô:-xÿ4¶òó{~“}Ÿýš. ?Ù“ýé?ÉnÜþ:òó쿲ûi-m£öfçâ¹òíD>ÇV«j¦g¾Ÿ4Gú/5/õËvG!¬ …¹{N4oZ±´fòç€9=n ?O‹&¢ÿ¢ag‚þoÒÚíîþ§·9{0îÅhs±èÞ1y‡7ç]ÀiAJ!‚<–Lz°phNÄ'¬âÞQWÞÛøUöìzÝîG›.ê}Köve—Ë;sÇ‚—²ÏKtÝMSo8s²ƒ|;å+ÈòFèë¾ËÓÒ,î`ö8r’àyú‹ü%j¥Ò#”IRêCÓ)…F¤›”‰%“Ó •ë¤k•uÒ:å>äß=Iž“Þ%ï“áÃáh\ÉJe"7)÷†ïO¿›–SÁÊtm°.="<">´hhÉÈô$m²gb`J|JÁ¤¢K—ÏUf槯Kß¿+ý‡ðÓ{˜Ý|gk¬vák@¬NûÕÊ@EfR°\²•§ÃA…¨@k¢ ã;D)-,tKL+-´éÑ´/ÌÝu_·ì‚8"dÄ1!» r²Ë +Åe×w!‹&*[*Ye2 e~¦]ȯ=Rñïò;*¢ùzÞÕOù†ùFnLlj"0Îî%)¸Ø@–Ίڹ”£¶_^¼=\Öû§Ëä®^R÷èOžøÕkÙÝ›[éÐ7¸È_Õùé¦ÏAÒ?Èþ™Æþ8gê¥3Ò”Y]wÝ¥tê‡Ð»~‘ýé‡Û³ŸÜYÝô­ÛJfßÏâäìoÊE ûÁ¶:äÓSVÒkwQo¿ø”¢YÚ‚"@|p×Die)ìè21yÄý*‰ 9ÂÛÞõçmÞh-¶Ç¶—Õzø~AY­™ß“û8þûméÜqœ/ŽcË[#@¤\Æ/LŒ·O/ˆ/ÑW¸Vºo5Ö¸p>ãnwq}æ6áç$ç6îsOÅüÒ_{÷b«lº4]^*-“åTY_©.>Xa»¨`hÑÒaeã¥FÛÔ‚KÊo÷¹J8¼Í^ŽHuén¢¬›ÀÉàaîä“sNÎ8ù„5ŒŸTîL—²R©,ÕÏ][2$5´zJbRÉÄÔ•öyÎù®Yþ™á•ök׺o0¯.]šºMZk¿Ý¹Ö}§ykéÍ©{÷»ïæ'T{$ÓÞX:ª§+hšŠ¨WîÓ;$cFœ=VÆn±X*èìQX–¢)%踕Ãå {è……AIŒtÄøM¹pŸošÄÔDõÑÜ'fõH•ºœv% ´-†ä:äÖ©4UZŒ:@/±Q\‘M¼£ÏQd, ðBxW&MбHRZ„L3È­–¯¿¥‚[£ÅêiRA+øÀír±‰ Ž[N~¥Šh<MCC¿‡@ ûÞ€ÈÃÿÞ |”‹ô΃M£Aæ€É $ø Di""<Ä‹ã<$€ãé GŠ`2êôl¡¯!¿JËÄôŸâ’ã˜((‡fÌíezê‹ÎË_¿aá³ãÇN”½rÜÜÙ7þýGO|{›²ËýÂ3­Õ  Ln¹ö¶“?y-û‡èûæUw^rþÒ!Cg—„¦eú?1sá/fÌ}k•뎻V]:¦¦f~ù í˯޿t’ÿ¹¬öB¬º vÑFn·œ +D—ÔBZ#¦á–nA+¥/ª ʪùÔ¥Û)å{bÙE ­ñ±ûÖÄŸs¡ùÀ‚š¬ð“¿¢¶ã¡3jf†ñí<Ôô)7¹!_$Û !éa¾l¼6Sœ/¼ðÝ?rí} ~ÇQüäËH»'Ë“µ749È_þs­Ü@`mÏrî_Ð?Xé ’öTxÓá:ÒÏSçíA†{Fx‡‡'“K<“½—„͵ÝùŽ´jLdµJ­cˆ2Ä120A™à¸40C™á˜X¦,s\p+Ž[x‘Ýïf‚àçZHXкº˜U(É@T:ßʬ;]n·¹ÊÞ@0ì߆ ¾ux=|kM ô$”ø)%aEÓ a ö:t½0àéõ8Üî„éñ›¦Ç«;´p@q{L蚤HaÓí֑цä"öz=˜¼‹†BQó<Ž# â@Àׄñ¸ >剴Ó;¶äœƒ¦hdT'À„Îh¤3/PæL–«6JÍ^÷Ú'¥ÑXðÅïÆ”Ä{|úËìU/eß,³…üÙ7 « Ü÷×RéãÎhöËÜÑ&ý ÁlÓºÄÌá'Ÿv˜ëìÈm·*0&EhÐÎ*¼¾´¿4@ ptõõö÷^_›¬õòim·a 'Ul‘¢"¶Ð²ƒÖ•8 ó³$^\C¯±³´\a+·WºÒÞ~ò@m _ñm‚ܤMµOqMðΦ3åyÚ|û\×LïÕòµ÷ ®ñ^ã»M^k[kÜ'·k/z_•ßÐÞ—¯}àzÏû™|D;âúÔ[gò Ëãthyi×x eûf'ò„ÝA~3l Ù ?8b¹8eªXR»Ä`Iàr.xà›˜ÕyÖuÊ“ì% 6>¤Ý;©i:=^ŸÏN‰ÎœvÉá3ìT5™O7|¾Ñ‘ ¦KÌéL8$¿Ã!Á&!Ý’ùœð‰V ÈgÂä.L½_þbÂXot’ÑŽ¬·Ëóæ§Ý2Ô6Ëkî7%$5^n ñö$¹ùÉŒ>Î¥¶)|8r´éh!¸ƒÍy´¼\­|OH šº:·›Ëe½&ij{“Ó½ûà†æ¿ÛWn­n­=RG¹KŽÕÁ1ù!â6¾‘Ñ;buZq¬¼ïØçàX‡U¯óÁý•ðuº‚¡zŸ7:GCœP/É Á|lõDÀVì­³; ’çPR¬·œbœrøB¨ó…PÇ)ª»M¹íé&bþ7Ì%òñNÛÊn¥ÐYÿ¬ã3jŒ/é=˜–½ÝÙÉ2Dzw%{²ëÙ)öóìš«Æ^Boíuê[fïÑwla–rlç®#r\>«:ú³V•îÔ+#Îhe…³²@i l`åˆÊ&gSå<çÜÊæ^k·U<üqôg œ‡9|$‡û{$ =y¶|Gä¥ò½‘ýå¿ |T® R¤þ‡¸Â9ñÂìNé˵f"ß/ …3U•µur]Õù‚ªIZcf–67³Ü±Úñ†ã[ç·OÿZ•ÍêÒÚPŸ¤?|yÅ V¯v5¸îvmpu¹” ®Í®¯]’ ÖS$›~!¼{(,2x¢K¤b¹Tž¨årÅ¥P;{vGø>äâÙà0·¢ÂuZfô‰KöŠiæ4‚( ~V*‰áËîPáËÜ”F©Ì½Y8„‡ÄqÑ ¨ù#÷ÒÔ‰¥âFØÏùd¥íìRËUf‘´™N¤{¥7§•:ŽðB¼·ƒûÉéÞ¼Îr" «®£Žm¬£uˆ2[çñ+†RáâêÒWÔý*+RT¦bÀÁ•HiSÃ"®ðÃk8?Th.J13¨öp¡\Œ9þ Ê ü ¦ÓiÀ-3‡óˆáò,;‘3ˆ\8þ×´øèbìp…¡w®y=åy,dqJ…Ã̳¹0}Í?}‘¶+RÏ…Ã ÿ:øƒ¡’´¤Ú\’x²N’êg윷y÷ð¥ôÿálZ3tÍM+ ZÃW¸}ͳcM=T¼;ºbï©}Ìóxºàæ‰Ãž»uôªÑ~—3Zš2®êqNãâðâ;FZÓ.ì¹âØÉ[Ï@?*›å£ª/h¾tÌ9×À¾3rdšcË&) -Ö©âp—*}•¡ŠÒPÔZÄŠŠa??¾¨h}‘:ÐW¬^¼(Ú¤59'»›‚—EçiW:縯 ^í(úÀñaèÃÈŸ}_†¾Œü¥à`QWQ$¡T»«ý½”·¥\ä«ÌR>,ø§üé0.Ye$Ç eâ.{¸ô€šv øs‹]Îe1Ø…”ÚEþŒŸu3<9°H\NA.=¯±ª9GíË€Ô!~Dæ¤FJ1ÖA‰m¤­ô•‹Û5†")a@œ² ¸€Q!,T8áÔË…>%„…8U§¬ ¿5…D¡ôó[ÐHáðþßs¥¹\,á3Ë@¥„qà.Bø'rr¸¬p$Š,N–À¯FÄ0ÑD²_™„€ ¢Ë3¥=žn[²åŠÍ‹­ìß_Þ=ŸÕN¼gùó?½zùó˜ËüçÝcîþõÒì×Ù÷~BïeâûÞ<ðê>1~í:"…ÍŠÒ)yŸ»Öu“›ºí”OE.Â|§ìÛmḌ¢›ÆŸß&žß†(4pV”BÊ÷½óª–ͽM}ø—»æÃu-Šö ÷5ûšC?f?–v>i>uhΈ1Í•æ)W;9[œO9¶ë;ŒíGSOa’«ør÷B÷MnÉÌðg­•½Äüh3šµ¦1Oª·ÛŽP°»q4½Ô¥ñîvÇàß–Ú3EðáÁY‚E–àÏ‚+QÁ•ñ@é~-²5 ÍÅO²ü$›0±¶Þ±Ú½ùÈ|É€¦%ùõ; åž÷Ñ%Ç3G—ˆg‡Â{êªÍ¦Cø'"hp®i?Ðoàá^.ŸŽ–9ï¤ú-_ÿìÃì¿–|~û ,Ú¹iÊšgŸ¼eÞ]ôÖЋûi5ž§lÕæÇbó¯üåÛïíù×ÉaàÙ'ÐIä®Ñ‰Ö““)g­sˆSéëï¿„M0.öÏf3”™úts¼£èå]ßG‘þÃþ¯Cº,*ÊD¹ÂŽŒríEA©³gp ëëɆ:‡ùGÄ/1&9g;«Ÿ¿£Ç]& H.;R¢bRJöp %);eš<ÔôXžfO‹ÊÉe"§¢/×@Œ¸¸¡õ¨\‚çŽg™·ôd~bë²ÉœEcl’­Pˆœ°Õ¶B>ºØ„úq±äsœ·¶HaíØ³t­iñ¨£§õ‹k˜X–Pô”£ðÞð=£i|N.Ù—Ûcäàuôì¤Ú3÷ÞôîÕóÞ¹¹ùþêm‰ç¯^þÓM×­xì¶G×|b•ÖŽ;¹;à}ë׿xõ÷örž„-„žÀ³ñV¨ˆÄ˜œkRšô‰ö™Ò|e¡>Ó®!Üá«ÓR¬J—íªújççÙ¯©ÿïbû©#ÆÖ[§¯ëüs ˜tûõÏÐI¡'Úh̽ƒ–g?Î~k&6ïšCï»m𜧄ô‰-ÀFCÔiúuêŽTGzE°L%òcÇ#ÎgœZÔYîltDäï‘òhQmæ”î¸A,ã÷É’JŒ ~êïòYr(%#5ú^&Þ½Ôò­•‰Õ®'4bqE‰XN( ñ ¬ªœ×b®:¤JøSBu¸&~®@ø=÷Ôñ)sA|÷"ïfòD8²›î"Ir«ˆ äF 4P>¿z®?ðˆ£0'Žy«†£ˆXEB“ßô¨ºMÕà'™ð‰GuǰéHXJMY‚éξ5}± – †£€š@‰gë† ¾èÍË/šÐçâ!û÷K¯[<¿vØ%ÞŸÚ¯Xwjtâüì8é èD!2pZÍv»â¯²§üÙ‡úU½ RPeOû«JêìýüÚ‡ù'Ù&ÛçØ¿3þpõ,©*;·äܲ‹ÊÖWm¬²õKö«h¨f–Z1!9¡b®mzrzEsUKÕ‡eG’_•|]æ Õ@;ÛÒV÷ÙÄXb&!ò‘¤…t€ÛÙ V%wC‹ã#¨IÕ©pø@ˆš!+Ôj ÉUËØÄ*‘A†Mø•°…„a A¦ÅÒ˜/r†ŸŸ³Û°8e]ÈÕ*´ÌMS¤¸¨ô÷~÷'î.·\änpÁP'tÆ +†eXR`|naÝx=KD2UË’ÜÀ!¬Ëq’8,Zù7×yè_…ÕÁ¾P¦l‡xÚ¤p#ùÜOHå ì ØŽëQúì5³6Ûû ^vÚ°‹.oýñ«~{çîkŸšù‡?ÿâ¡§n¸~Ó ×®Ø49:.ÕgÆ”þ­wÐú¤t݃-§æ}³ÅsRåo;^yë—¯þ’cM«‘xÍó*ýtÚN„àBµ˜ ?ÈW©Sr_¼ a—SUC‘Ú†ÐÜ/tǛɡ)ݪéWÛ¥ÓÑÃlb& )¬å¢ôsA@ù¥åá‡Tyt¢ŽôQ‹ì!®*:T %b{ I°bÿò‚@Œ l¨¶_mkðX- n ¶»‚rùS¹„m8†çRt^ˆ åûN˜TNX!¡¥9× kÐÐî´‡ïr>!aB-ëC9G†ƒ§ã ŒLù܇Lž±Ýì)Û9—CKB;]x9NÊ¥:bÔ©A/ OGXE Ô¹¤6p`<JÄ:$5àYÝvcÇòŸl»zþØ;ëáþýÞ¦'鼜=¶úºñwÝÐùtr …CðûldŸu™Þ?Á}½¾QoÕ;ôOôcºèEú"¬ݯ:¨wéF‘/ˆ‰^]•nD¢Ê†jKaéy£Ü*wÈeµC>&3"'äؓ圿Ì&‚È÷Ö&€e2Ò‚P ˆc9Ë"‡Çƒ8…¼ ðJ­ý{ï!ÅMàñùµ <àâÃÄ’Å_jŠ‘|M[[›ü×ýûOäôÉaÖ»ÇJÈ♽ä]k¨¬¤”Ar ^ ¢„4E±ÉXO¢øuÚ Ù£Ømü íª-îq¯‡E2ãp8S†±ÞN‹ì ö1v ‘ÆwV. ù´3,ØEdi‡ÿ‚KPjü9ìB·íŸÿ…$ ÓZ-<žy:Úä0ãbÒ0ŠÇxªÜ´µ(…¯6µ\NµK3ÝiÍ4bTwÙbH%åÁ—HÖh®ï™·AÅokËÎ)îWÔ¿_[ÍyŒ?ÿío¿½î!׈{å©'7î5ƒë+dAúýbgÓ¬áW©“Ô)ºävþC9¡"5Œ«0±ÜÄ2°êåÊPå#–˜˜ž(]c0¯šð%kòÛæ-«ÅYÇÚ°õbÎ IQaÝ‚U–Yí¯+ÔÆdãéjãCé/ªí)•–¨i[J«Sè Î1ÎF¹QlkÔoW*鯪¿“ßS©ŸÛþ¥~«¼†K™!=h/vù¦l*R T ›Št4ÀÀÊ|B@V8 m·«]Ü–ÔpÞ(ÅÀúÝV2!âØ¢ëáÙS„¥/Ú€÷r0è~Öê-t ­'B’ ‚Dèº(ð ®÷‡óOÉá³Îæ5œÒQ|^ÎÏ žbƒ˜â4:3̘'ùD™¯@´íZ½$ÊÚb¤3 O4—‰S[ƒ|óñV“ŸÎ7bÏ!6[ìùl¨F¯ñ[y?’©æân~½(ð«[ÃüÇ_n‰åNGÚ[É DI¸@âÁÙ ¡ôÙϳóè+g» ônÚš]Þ9ƒ]›½”ËåÍ(ú }ýËE(HPǶþrI¶µ}sÛ^½sÛÜšö+…áÆD¹ Ê'Š<Å1E*R!m°KÁ*w¾ª9gàù•ÀN,o‡g³ÐšìlkÏ£|p˜ë¸ò@BŽ×9 ëÊÁån“¢K8Ñ ò¶‹Œ–¿o»Àª%ðÆ„ùâ&‹ïñ?ž¢{s›HÑųc UÓð™Jèk<Í0— ÊP©ß[£ìÎÚ”|H>¤ÿ)t8¡¼«œH°–(Ññ@å’¸à.…ª%X¡eHÑõ©)–‚s¥Öc­ÌÏ#’qЬãbíñsÓŒ}¬>ææÙøP{„ƒ[ˆ1Çr¹R<~ËÇ1´Ér„Sëc4&.;}¹˜¸ö¿²<ür11JÆDèÚlnpŽáQ'b?‡ÿÅÚq½ a5%)z€@÷6VD¸þI¼¯óÜ8[ÿ„Å%A¡ü*y¶·üÂIÃþ‰”¦ÚéŠmÿn9_°ãÐéÕ 0Êg?ìt $ø wžáA %†ºòÉ€îSZi¿Ã£^g { Î/ào€{ϘŸA‘®…}öÀýXŸ§æ- èÆ_?úì¶’©ç.úQÛä­(§ï}ù“wmÞÑYÆ~rååï{²ó¶uÅŠ±ßÓù×îs} y Ò,Ÿ"©>¶Él7ÿ"}æ;&ð©KYõ˜•&}Ð<>î Ë Íïò½ð¹¨tN—ÃU~VXø\vámÙ…·….ïmÙÅÐm/æÌ@›ð¶ìÂÛÂþ·9†Ú…·…ýXeȇ>áÐÙiR·Fcb ¸ç>f‹ÂíᎰƪ¾@Pèæ ,ˆÏiÞ<ÛáÊ©à‡ ®9Ô0çpåp>~ ï¿;p£CX¶uV²´Aj¾W e̽Ö\>ê9í…Unh† ë–Ì4ðuÞ<“ù² ˜SÌ3p.s X®`lŽÅ«¿ú£æÇÆšF[åü –>-§Ø7t.e·]µà¼{ßê̯íü  |t’¿#ü©o|Ö€ÈÈ:b-åTDðÚŒˆc¸z6ImÔf«s5­ÖèìjŽôŽ  OU¦ê›MÞ¦àÅáÊ}†¹À» 8#| èªâ¼TÂd®q©ãJi¦2Ó¸Òa„â²Í£á/‰è'&Á&¦Ïxlj€N äã:W8>&Ú'Î Ap¶ƒè°|¥©Ú^X³j3m À:½?•àõ#8œÚUJ.øŠU”Dà@€òz+, òË —ä‘ÞQ+€­Âˆòâ(@…&¼ôát_sY¬óá—>^¯_¡\¡Ë|tâ'úÌþ`æÿ¼pvX4äÉÛõ¼î¯w|’=ºsëêÛ¶n»uõV¼à¬ì®åÙ?uîûëh!u¾õæ[¿ýÕ›¿Xúêì\9 zñ¶‡+¬»fós¤)7$Z¬(Qá()èèSp~Á¢Äú„6040vaèÂX£v©cjhjlž6ß1×\šëH¼íÿ(üQôíÂCþC…]‰`‰œ13¾ò@Y$æó°ý¯YÓîq⺄N\‘Ò5 Ëh6Z 9!˜˜ …ïö©eç¬4+±Ïm¹È9½Úà¸@pèˆU»ÛXF}5¬Æ›"ä¿#çÝ€¹°ÈyÀ\ƧóÂ" l=˜‹Ü+˜I30§g'ŸäŒ1ó‡ËÁH®“ÜÞv£å¾nÊE¬Œµe,‡?—¯~rà½sÖ˜wõ'×M¹»§ç©å+ž{zÙÒ-Ù¹ÊËkÇ[×õàÙ“w\4°ó¤ôä¾½o¾ûæ¯ßç8ÞÙ¹ÒAðÐ$qÚϺËÎ2¬2<ˆd+jC !22²¾pc¡Rë«5ñ ‰öŽM÷M5¶¾£¾ëýTýÜñEج`ÅŽ ²Éû:F°aŽ)l.ûÀñ‡ð_‚ŸG>bn*;ýQà¬.Õ\ޏB®ÂQV75Ý–»ÙÝâ– Q(¸ç`Ì@eu 0Â-ÀÔb0å¬tùèÇ…ðEÄé Â~,óü'ÊZÊ£©(a*f¨¹-RPø}â¿ ¬Çy(öoŒÁ[p¶ùƒµ|k™.¼ÂŠöœZpe+ˆlðŽø„´(øR1 ÜLúøP&Ç{Ú‹ÑY±|áÚ>üçÕ·~.‡áBcP&ø/# þ«ˆ #ùŽ`2{«­´?ݯ;PIA}*l.ˆ\Ö³ x?€øbWÕʨ¸U8|sŸŽ>¬¡OKÖ‡#ø¥DÜ“ˆp›$r½Ì& ‚7€V„7"QêFØ-šçN‘3h"¬„X–‡‹?éo#½ó0=½;‰âlb\]2:?žÉ,>ëüXœÔpt±˜ç1 O6å8Çø—Ÿ ÇÒY«¬Ga à´Çôš>SR‹‰ÑËm1ªô@QèÇnÒU#Å%N‡Vˆ£¼L7ÔŒ#Ef÷·ø‹—êsD3•™U«‡uÿ5!ßIý¾þbj€O±—á]°µ˜IÏ9fg’Xòõ mØê¾ýºëWôMýðՇƜ7 òžñ7¼<ÅÓêX:÷úyÁ`uì–W˜4÷Õö@ωÏ_2sÈ9%áTŸ«F_Y^”¹àºÙá‹§^Ü¿$^à3Jkλ~ê” —<ÏíUi×ßY¥òÞåƒuµd°$ÍñÌ¥€h‰Ks8 *‘ ‰·å¾%»Û,Æ"§7å ]6m¨>´Ù¶ïÞXo“ ü§¶V[‡íÞHÆÁfÀà¶ þ.R$PÃã2Qó4Ôpè2ç™ññ”°]8ó-m»ØZªù‚ê Ú1¿âA7‘š`*âaETÄ,!­„¼Ülϧž„D´"à{§„ü¼°ŸG…C"ðÄþ žr­Nì ÑŽ Æk€ ð%z,ÊE7F[£]Q9 hšÐ0P=¡ÐêÈF)ÎyT‘JuκˆQ×GG¾ `À8úŸÁÆÞïXÉ,ÆGeÓåt;y>%±Ù#NÍ“ƒñ΄\šV~~³ Ìâ ! A©áúw/{bŒio³{®7î®Am´]°`LߥìÞÎmwö>nüÝkX‡MÁ0I:þô‹|î@Hш¡©T=®[ÊP©ÎœµË´Ø‹}JŠ=u·ðNOŽ€³Vã’\¿Ø†-L²ØâŒß[za²–”£ÀÞK¦C‚(°÷¡ucyO¬GávTr=mÔ‘¾Æd¸1 ïÎiÔ&ë³è,6W›«¯ H'd+µú5ÆjºšÝ&Ýn[£­ÕBÔï1ž'/“m[Œ7ȯŒɻƗä/ÆIrܨÂãa4ÊIÚèoŒ!^¾cyƒµ ‚ÚÚ<ò¦ãyø£´é¸åæŒ4ˆMyê2¯N-ObµLQv˜Àê2ÈhÆw_f_†TŸNjîoLé†_× LkÙ®,ᶈÔUÕfèH¯Uªñ>žbͲ¬Ü{il»P +ÔiÌÒÌ¢Åö/~ǵ a;‘ú =ÄW1@]ëN#Œ/žIMlÓ)ò“º (2•Dn±H%E)ýYöÊŸJ!çìËÙ«ätç-³NXÎÖñ€|¨È }òá• º×p{¹‡*,P.-L”è°wÚ0K]‘Ï)O‚—8€Ü.˜2ÀðÊ)%ö D‰o= ªýátÀha­“«Ö ÙTG U9cçArʾ}æ{ûÌwðR:ž€,2ÅóñGãcE Zè§•r…Á.ô\ê¹Ë#y0,Š%ÖE‹ä`[Ç,½(YkƱf ú}Ìz±¨´VVºOé¯"Yµcí¹æ5‰OòÛâZÌ^€X6e«Ô2.¼úß6Pä" W-Û(m¤}°{¸çBï¥î‹½óm3´ÙÞ•êµ¶eÚNu—{‡÷ŸêI½Üî)'åÎ2W¹»Ì[í@ú{¯ÑnÓ”p½žðÀÀˆå‘QÇ›šÂðmð«YSø¿g…çõ?ºäH ·!÷–yZ8ÿŽl-?¹ i ¶¯E¤øºº´‘^îrlŠ7Š#[kÇc)ºÖu`‹­ªG¶&‘.^#Òŵ®ƒ[l‰\­µü5[;ù…vÀĵa¯lµõâWÜJ°]¹;¾¸¸ÿ]Hü΃ôm#!'ø»Eƹ˜=paå»·ŽTá ßâã°#W8ģ䞙XýγÓEVº/$RÓ¥2‰ŽÌ¾´ë™¹æ™úž³cs¶í¥g*Þ‡‰ùñ!ϯÙU¾¹Í:ù!»~û©ýb,rc,úlIÿ˜‹njWe¦#uÁ ™t ¿Ü] pÀßÌ{Ñí¥n$(ó9 kl¤nŠû~ù~ ¯†rw(j‡íM·î¶‚uQɧœQ³/h_Eï²kÕÞKäF[£}²ëú ñ ýEÖîxÝþk×[æ‡Ò»úo0ÞnõBö¸×ã;á^à>Èç”[dã5®* ð¿eÏRU)—?®b än¬¤D¹Ûí4Og›†Š· æ«äU™©Óùã¯bf*uv ¹Šx)äÆ/õŽpÞè(6ÜÓTýF ©ã±-u¬Ú"^7Ør%¤YñØížëEÀÚt<7``¼0ã]˜âgg‹ãÕ¦ùƒ¿âT¤‹#Y\$ŠïÍ•ØpáÅ,Æ> Õæ ÔþErxA£8T'áË÷1Ñ„¦X¯@~w²NG8þ×( Tê¦Fž® ï¼_ÿþ|®H*£nzKö¡?=Ñ3^•Úö~özÇGÌ~ÎÊiöÛá½Î¯9™utþ†^ؘmÂs%‘oòd$Jÿ•—‘ÃïÆú¸½ª]õY^d_XŽD^V"Õ™èGÑð>L’ðÖa½ 8ÛÜq ûô±µ ^WîŸäÞlH–ÓCå½jM^à•|Þ 3ì-³—9Êœýýœ}]yìåÞrßÁFo£¯10×;×77°R]î\é¹ÖmàVçZÏ:ï:ßíþMöÝæKž]þ/ŒÏüÿtvšßú»â…ÝôÙã1Ù=Ä} ÒE"§›/Úó’³¶xÿ%VÒ`ñ‹ÞCÄï󥼆;nÌaÊn 6°ÌÆá°«üùIÜŒ³êø+qog ÛÝè ËßÎ&Xö¯åe—{_Á»9Úéù;Ü´˜ Á4NÈõ^ÃÔË1Æ!ut‰µ ço«F&®ÑK\ÓˆÎëäï„ñ׆Íã‡"xïâ£Q,‚^Åð!·þ gF;{‚“‹Œ_|0²Õ{†½y oâ8Bì]G¸ùÊ‹ÕNâïúïÙ0Šñ® hÙöÔæÏBzxŠ5’"š}eÿ9Öù1pcàE P¹É?¨ªþ‚'­Ø³ ö|”).Êü¥-{åy¥½®ŸT›ýŒY^›ï.Ë;ºzÕõËÙü“¯o>¿q<÷ƒËa{Þ\¹èfËémgohÌKûxC|¦û7–‚ž Ï{{¬ AT°r½ÚDVº1‚côús*À&hSô±æ•t:›ðå:ºL»N¿ƒÞŠÅlßÒã,ÑÒ´BËèuÚOµ÷©kË‹f –ÁÀ yÇ*A8ÍêÃLwŠ2,b”¿’MS2xDcš“`¿Üc#ÿ>ýù¶æ¹=ŸŸ .›…½M6bæêܯú¾D9 DÞ¸È7ÆÝ%N6I¶ äueoåu‘CyçÈ#ÀQØÇ’¦&òM¤Ž2à2$/ }þpŽBw#ý3ؽà¯ÌÙó~Ä ê"”Y 4yõ?-ü@8§Û°Þ{‘ïG¹øž€½혠­€ À~ƒ(Xw‘gå: !æÐq:‰Ø2ÅÆnãaãÕ¼—MšÙiþR£h–6Ëù|_þ“…‹ o=[\lUl¾’—|lß5¯q~÷‚«emå í ?^t¾b§ã[•Êqç~Pµ¹–TV]¯¾Xs¤Vuÿ}ñSKº–>â9²ìWË/¯ø½>6ć2 jUîîÛA¦ ý\„Øb¤ÅèÙsãeœ-¤;ÒÚóÀ×=Áo?¶iëºNÉ)»XÌu›ÅŸ5ç“RHfcŠ- ¸e…ç1¿%ìG “"È´’6Ä­ZK¢ˆ’µŽÜ‡ÿ{w .ÒzD”éDĪ.Ä´é&1Dûz±p"$Ùi VÊÈ  „CÖí@0Œ&bÍy¶Aï&€€‰ e©ƒw2PÏI•Þ²Õ+“›ôdïC2™~ ¦ëu÷ë:|¯NkÖi_[¥»W„t½x™®íµ^ •§ó‹¼“A<³L.Œl‡¤ì5bÅS²œ3, €á1ZÝ0ØÓ5nïè„ÁH(æd§ˆºÅ³“š**ñóY–Í`ì8»Î>ÑsØ'éâïhp-û€œ&ûŸ÷Ùûd7»†¶AúQ`¸Ì&v Ÿ÷ð¹Ê®+{—Ô~ &€ÀÌÞ…´±wÄf#¥°ýcï@ÚØ|­+VvÖev9;Éþ˜jhòž‘†§>gðÚœQV‘3ì¥Þ ûCêæRža¦U?\ÉÞ" Û*¤ P Ø˜`]‚u‰hÀc@Àõ9¤ PÙ4p¸„Ù.‘Ð(ìb ÍdØ…”;ă¥Qu·,9{“‰sœg¯Ký;ö[©ß€F`<6Í^O99  Ÿ Œ Ú]ü<öjºÆÎ³Á6Nâõ€hú€ÀÄ&XUêanG%gÉ4޶œ¥ÈGRÿ‚WH` ¸ïÁ6¦ án¾ĨŠiqîC?ER÷ƒ°„p?ù<,!ÜßÝK÷Ö°„p?¼–îž>XB¸Û;aAdØÑ_×,æ íS5heÃè¥aôÒ0ziL‹¹‰cg/¦êêÐc‡ž¥u\§Ú+T[OµãT¤Ú.ªí¡Újªm¤š‡jª9© ÚYÚˆ®Ðhàå/$›åT›¦ÚKT‹SÍMµZªÕPM¥ s¥îÅŽ‘*ûs¥ïöy­XGzÔ…ÍÚ…Ý~ò•©Hj•N^èº*]ç×Ó+š½Û‚ml §0 Sä=ÀˆšÂf4…J¦PÒô“À L`Wá{ŒHi…¬ü@°˜Lruf°*Œlƒ«xZ®X=¤h)6…1çb.L¶ê°ylm†œw;i»3ëd ¤´‡W{‰‚ ÿ‹Æ>+ú×gEÄ´°làrvÓõHêf%ÏÐRî³<¸€þ„8ñ´§MÄMk¡I\¦ï$EøW;íM9ºPÌšr/ãã´X”ã7æá æ_gùÛjÆHSüOðœão9öñ7ê3 <¯¸1@Š«’zÆÑÈ_š–Ô=È8œâ»„ã?p´òÇ2cPÏØG*`åëÝ=¼ õ…›y Ž:Ǹ߱‘¯ÖYwŠ2c|%VÁ£›uXÙ¥ÙhµSVø† f‰Zf>dîÆ[3w™½æef—™›+ÍæùŠ]±)ÅJ¡’¯(¸UlÄŒD™/žÅöˆß¼ù&›PâÇó§KÛ†# •?xâ¸F¼îJó QÝÂëé“$ºYMüsCu†æßߓȫÑ„=J¢¡D£'š1g×'<Ñ„¹ãÁî$¥bð&Ø3Šø;š®½":^©¢%{÷W½dïþXŒ”—îô—ûí¾’¦5áÛˆ~éì‹sÇÜ‚³Ð¹¥ÜS™8ÝÐ8YKx…‘­Ä­‰ðYgÒðF$|†~*T¬ûŒÁGÿY/ü_8‹fh—ä•~ ¶(ð'Q¨ŠSçÖyµ(^PàY,¤Vòj-É3RÁKÆk"ád 8e*‰KN¼LýoÎt-8µà”jdZr¦K5ÁIød5(NP(â$JŠƒ.’¹æII©ÏQöÍQöÉ– úÚHލ¦èÚ,§è8sÝøÿŒÁ®ÏÓ-±ÞBõWGþÄs;-Oh›U59ˆæîß<ð¨Ð›±êÁpb :¬&[d¹/e÷Šì–êp’ôF:»“½Ápª%Щގ¥[;V5|¡­}sm­ê¸M[¢2Ì$¤&[e¹/µÕ ²[E[ ¢­ÑVk U¶Eä6ÞÑTH(†+©Ó¬ Ûk…+*µm÷É·ÅU¾«b'$'HB‚"ˆ\ ¶ëåÁåA‘…}JdÃmÍe•ïjqUŒÓ¹,Ü%Õ!âÚßAÊ#…õ¿8¸†vˆÁÐ¥Gøn»€A¨¸p|ˆ`Zˆ:\;ûqíœ4›áíÇàkžõDp-©;WÀÙ,ˆÃQøV ŸÅ’#~ukë·¼ÓØÙ4 8é‰Ç g´“áPÐÙƒn@œ±qœ.‰‰8°Šãe¢ølmâ{èS)â‚_9>‹¡9+×C9- Š"ñÙÊ#z‰üŸlS endstream endobj 31 0 obj 21848 endobj 32 0 obj << /Type /FontDescriptor /Ascent 905 /CapHeight 723 /Descent -212 /Flags 32 /FontBBox [-665 -325 2028 1006] /FontName /XEGZWL+ArialMT /ItalicAngle 0 /StemV 0 /Leading 33 /MaxWidth 2000 /XHeight 525 /FontFile2 30 0 R >> endobj 33 0 obj [ 278 0 355 0 0 0 0 191 333 333 0 0 278 333 278 278 0 0 556 0 0 0 0 0 556 0 0 0 584 0 584 0 0 667 667 722 722 667 611 778 722 278 0 0 556 833 722 778 667 778 722 667 611 722 667 944 667 0 0 0 0 0 0 0 0 556 556 500 556 556 278 556 556 222 222 500 222 833 556 556 556 556 333 500 278 556 500 722 500 500 500 ] endobj 10 0 obj << /Type /Font /Subtype /TrueType /BaseFont /XEGZWL+ArialMT /FontDescriptor 32 0 R /Widths 33 0 R /FirstChar 32 /LastChar 122 /Encoding /MacRomanEncoding >> endobj 1 0 obj << /Title () /Author (Lukas Zeller) /Creator (Apple Numbers 1.0.2) /Producer (Mac OS X 10.5.4 Quartz PDFContext) /CreationDate (D:20080827130750Z00'00') /ModDate (D:20080827130750Z00'00') >> endobj xref 0 34 0000000000 65535 f 0000180451 00000 n 0000009579 00000 n 0000126627 00000 n 0000000022 00000 n 0000009559 00000 n 0000009693 00000 n 0000123815 00000 n 0000122864 00000 n 0000141523 00000 n 0000180278 00000 n 0000157573 00000 n 0000009879 00000 n 0000122013 00000 n 0000126590 00000 n 0000122036 00000 n 0000122844 00000 n 0000122900 00000 n 0000123795 00000 n 0000123851 00000 n 0000126569 00000 n 0000126711 00000 n 0000126761 00000 n 0000140985 00000 n 0000141007 00000 n 0000141247 00000 n 0000141700 00000 n 0000157204 00000 n 0000157226 00000 n 0000157459 00000 n 0000157758 00000 n 0000179697 00000 n 0000179719 00000 n 0000179954 00000 n trailer << /Size 34 /Root 21 0 R /Info 1 0 R /ID [ <4cf718985bb264c6d382c471b1a1ca6e> <4cf718985bb264c6d382c471b1a1ca6e> ] >> startxref 180657 %%EOF libsynthesis-3.4.0.47.1/doc/engine_settings_keys.rtf000077500000000000000000000175111226375725500223560ustar00rootroot00000000000000{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf430 {\fonttbl\f0\fswiss\fcharset0 ArialMT;\f1\froman\fcharset0 TimesNewRomanPSMT;} {\colortbl;\red255\green255\blue255;} {\info {\author Lukas Zeller} {\*\company Sherwood Forest}}\paperw11905\paperh16837\margl1417\margr1417\margb1134\margt1417\vieww19240\viewh20720\viewkind0 \deftab720 \pard\tx2414\pardeftab720\li2556\fi-2556\ri0 \f0\b\fs20 \cf0 /engineinfo general info about engine (read-only)\ \pard\tx2414\pardeftab720\li2556\fi-2556\ri0 \b0 \cf0 version - SySync full version string\ platform - name of the platform\ \ \pard\tx2414\pardeftab720\li2556\fi-2556\ri0 \b \cf0 /configvars configuration variables (volatile)\ \pard\tx2414\pardeftab720\li2556\fi-2556\ri0 \b0 \cf0 platformname - name of the current platform\ platformvers - version string of the current platform\ globcfg_path - global system-wide config path (such as C:\\Windows or /etc)\ loccfg_path - local config path (such as exedir or user's dir)\ defout_path - default path to writable directory to write logs and other output by default\ temp_path - path where we can write temp files\ exedir_path - path to directory where executable resides\ userdir_path - path to the user's home directory for user-visible documents and files\ appdata_path - path to the user's preference directory for this application\ prefs_path - path to directory where all application prefs reside (not just mine)\ device_uri - URI of the device (as from getDeviceInfo)\ device_name - Name of the device (as from getDeviceInfo)\ user_name - name of the currently logged-in user\ conferrpath -for Synthesis SyncML engine library only: path of the file to output configuration parsing error messages. Can be set to "console" to di-rect the error messages to the standard output (note that a usable standard output might not exist for certain platforms).\ \pard\tx2414\tx2414\pardeftab720\li2556\fi-2556\ri0 \cf0 xxxx - user-defined variables (can also set to override default value of one of the above)\ \pard\tx2414\pardeftab720\li2556\fi-2556\ri0 \cf0 \ \pard\tx2414\pardeftab720\li2556\fi-2556\ri0 \b \cf0 /licensing license (volatile, text/code must be set every time app ist started)\ \pard\tx2414\pardeftab720\li2556\fi-2556\ri0 \b0 \cf0 licensetext - license text\ licensecode - Writeonly: license code (setting it will recalculate all the following status variables)\ regStatus - Readonly: TSyError status code of currently set license\ regOK - Readonly: if true, license is ok\ productCode - Readonly: product code from license\ productFlags - Readonly: product flags from license\ quantity - Readonly: licensed quantity\ licenseType - Readonly: license type\ daysleft - Readonly: number of days left of expiring license or demo mode (-1 = not expiring)\ \ \pard\tx2414\pardeftab720\li2556\fi-2556\ri0 \b \cf0 /profiles Client settings profiles (persistent)\ \pard\tx2414\pardeftab720\li2556\fi-2556\ri0 \b0 \cf0 settingsstatus - TSyError status of the settings. MUST BE CALLED AT LEAST ONCE before opening subkeys\ overwrite - (volatile) boolean flag. In case opening settings would cause deleting incompatible settings, this is done only if overwrite is set to true.\ \pard\tx2414\pardeftab720\li2556\fi-2556\ri0 \b \cf0 / Profile ID (as assigned by engine when profile is created)\ \pard\tx2414\pardeftab720\li2556\fi-2556\ri0 \b0 \cf0 profileName - display name of the profile\ protocol - transport protocol: 0=included in URI, 1=http, 2=https, 3=wsp, 4=obex_irda, 5=obex_bt, 6=obex_tcp\ serverURI - SyncML Server URI\ URIpath - Path element appended to SyncML Server URI (e.g. in case URI is hardcoded)\ serverUser - SyncML Server user\ serverPassword - SyncML Server password (stored in disguised form)\ transportUser - user for login at the transport level (e.g. HTTP auth)\ transportPassword - password for transport level login (stored in disguised form)\ socksHost - SOCKS proxy address\ proxyHost - HTTP proxy address\ proxyUser - user for login at the proxy\ proxyPassword - password for proxy login (stored in disguised form)\ encoding - SyncML encoding (1=WBXML, 2=XML - note that not some client builds only support WBXML)\ syncmlvers - SyncML version to use to start session (0=automatic, 1=1.0, 2=1.1, 3=1.2)\ useProxy - If set to true, this indicates that configured proxy server(s) should be used\ useConnectionProxy - if set to true, this indicates that OS-defined, connection specific proxies should be used\ timedSyncMobile - Number of minutes for mobile timed autosync (0=none)\ timedSyncCradled - Number of minutes for cradled timed autosync (0=none)\ \pard\tx2414\pardeftab720\li2556\fi-2556\ri0 \b \cf0 \ /autosynclevels\ / Autosync level ID, 0..2, 0=first priority, 2=least priority\ \pard\tx2414\pardeftab720\li2556\fi-2556\ri0 \b0 \cf0 mode - Autosync mode for this level (0=IPP, 1=timed, 2=off, 3=server alerted)\ startDayTime - minute of the day when autosync starts in this level\ endDayTime - minute of the day when autosync ends in this level\ weekdayMask - weekdays where autosync is enabled in this level (Bit 0=Sun, 1=Mon .. 6=Sat\ chargeLevel - percentage of battery charge needed to enable autosync (0..100, 100=with AC supply only)\ memLevel - percentage of memory free needed to enable autosync (0..100)\ flags - flags reserved for future use\ \pard\tx2414\pardeftab720\li2556\fi-2556\ri0 \b \cf0 \ /targets Targets (databases available for sync in this profile)\ Target ID is the as defined in the config\ \pard\tx2414\pardeftab720\li2556\fi-2556\ri0 \b0 \cf0 enabled - if set to true, this datastore will be included in next sync\ forceslow - if set to true, next sync will be a slow sync\ syncmode - sync mode: 0=twoway, 1=from server only, 2=from client only\ limit1 - sync range limit (such as number of days in the past, depends on datastore)\ limit2 - sync range limit (such as number of days in the future, depends on datastore)\ extras - flags for sync range limist (depends on datastore)\ localpath - local database path (if any), to differentiate multiple instances of the same database type\ remotepath - remote (server) database path\ localcontainer - local container name, if any (usage depends on datastore implementation)\ dbname - Readonly: name of the related (in the XML config)\ lastSync - Readonly: time of last successful sync\ lastToRemoteSync - Readonly: time of last sync that sent data to the remote party (server)\ resumeAlertCode - Read: if != 0, next sync will be a resume. Write: set to 0 to prevent resume. DO NOT WRITE OTHER VALUES THAN 0.\ \pard\tx2414\tx2414\pardeftab720\li2556\fi-2556\ri0 \cf0 dispName - Readonly: the datastore's display name as configured with (if none configured, this returns same as "dbname")\ \pard\tx2414\pardeftab720\li2556\fi-2556\ri0 \b \cf0 \ Session key unnamed implicit per-session key obtained by OpenSessionKey()\ \ \pard\tx2414\pardeftab720\li2556\fi-2556\ri0 \b0 \cf0 connectURI - URI to use to connect to SyncML server. Note that this might be different from the original Server URI in profile's "serverURI" as the SyncML server might request sending requests to another URI during a sync session.\ contenttype - content type string to use for the HTTP "Content-Type:" header.\ \ \pard\tx2414\pardeftab720\li2556\fi-2556\ri0 \b \cf0 /sessionvars Session context script variables (for PRO engines with scripting only)\ \pard\tx2414\pardeftab720\li2556\fi-2556\ri0 \b0 \cf0 - name of any script variable defined in session context scripts (like ).\ \pard\tx2414\pardeftab720\li2556\fi-2556\ri0 \f1\fs24 \cf0 \ \pard\tx2414\pardeftab720\li2556\fi-2556\ri0 \f0\fs20 \cf0 \ }libsynthesis-3.4.0.47.1/libsynthesis_contributor_agreement.doc000066400000000000000000001240001226375725500245310ustar00rootroot00000000000000ÐÏࡱá>þÿ NQÿÿÿÿRÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿì¥Áq` Áð)1bh£N N N N N N N b b b b b 8š 4Î d2 ÅìH ^ Lª ª ª ª ª ª ª ª ª ª ª ª ª ±h!°ÅÅÅÅÅÅM "o o o o o o o o o ª £2 H H H H H H H H H H H H H H H H H H H H H o Æ œœœœœœœœœœœœœœœœœ°°°°°°°!(A!A!A!A!A!A!A!A!A!A!A!A!A!A!A!A!A!A!A!A!A!A!A!A!A!A!A!A!A!A!A!A!A!A!A!A!A!A!A!A!A!A!A!A!A!A!A!A!A!A!A!A!A!A!A!A!A!A!A!A!A!A!A! libsynthesis contributor agreement These terms apply to your contribution of materials to a product or project owned or managed by us and designated below ('project'), and set out the intellectual property rights you grant to us (plan44.ch and Synthesis AG) in the contributed materials. If this contribution is on behalf of a company, the term 'you' will also mean the company you identify below. If you agree to be bound by these terms, fill in the information requested below and provide your signature. Read this agreement carefully before signing. The term 'contribution' means any source code, object code, patch, tool, sample, graphic, specification, manual, documentation, or any other material posted or submitted by the Contributor(s) designated below to the Project. With respect to any worldwide copyrights, or copyright applications and registrations, in your contribution: you hereby assign to us joint ownership, and to the extent that such assignment is or becomes invalid, ineffective or unenforceable, you hereby grant to us a perpetual, irrevocable, non-exclusive, worldwide, no-charge, royalty-free, unrestricted license to exercise all rights under those copyrights. This includes, at our option, the right to sublicense these same rights to third parties through multiple levels of sublicensees or other licensing arrangements; you agree that each of us can do all things in relation to your contribution as if each of us were the sole owners, and if one of us makes a derivative work of your contribution, the one who makes the derivative work (or has it made) will be the sole owner of that derivative work; you agree that you will not assert any moral rights in your contribution against us, our licensees or transferees; you agree that we may register a copyright in your contribution and exercise all ownership rights associated with it; and you agree that neither of us has any duty to consult with, obtain the consent of, pay or render an accounting to the other for any use or distribution of your contribution. With respect to any patents you own, or that you can license without payment to any third party, you hereby grant to us a perpetual, irrevocable, non-exclusive, worldwide, no-charge, royalty-free license to: make, have made, use, sell, offer to sell, import, and otherwise transfer your contribution in whole or in part, alone or in combination with or included in any product, work or materials arising out of the project to which your contribution was submitted, and at our option, to sublicense these same rights to third parties through multiple levels of sublicensees or other licensing arrangements. Except as set out above, you keep all right, title, and interest in your contribution. The rights that you grant to us under these terms are effective on the date you first submitted a contribution to us, even if your submission took place before the date you sign these terms. Any contribution we make available under any license will also be made available under a suitable FSF (Free Software Foundation) or OSI (Open Source Initiative) approved license. With respect to your contribution, you represent that: it is an original work and that you can legally grant the rights set out in these terms; it does not to the best of your knowledge violate any third party's copyrights, trademarks, patents, or other intellectual property rights; and you are authorized to sign this contract on behalf of your company (if identified below). These terms will be governed by the laws of Switzerland. Any choice of law rules will not apply. Please designate the Project for which you would like to contribute materials: Project name:Please designate the Contributor(s) and the Project for which you would like to contribute materials: Nameemail addressmailing addresstelephone/faxOn behalf of the Contributor(s) listed above, you agree to the terms of this agreement (Please print clearly): Company:Your name:Your title:Your signature: Date: To deliver these terms to us, scan and email a signed copy to us at opensource@plan44.ch.  libsynthesis contributor agreement - derivative work based on Sun Contributor Agreement This document is licensed under a Creative Commons Attribution-Share Alike 3.0 Unported License  HYPERLINK "http://creativecommons.org/licenses/by-sa/3.0/" http://creativecommons.org/licenses/by-sa/3.0/ libsynthesis contributor agreement - Page  PAGE 2/ NUMPAGES 2 libsynthesis contributor agreement - Page  PAGE 1/ NUMPAGES 2 ÏDÐÉêyùºÎŒ‚ªK© àÉêyùºÎŒ‚ªK© ^http://creativecommons.org/licenses/by-sa/3.0/F$$If–l”hÖ\ÊZŠÄ%Ê 0 :aölö4Ö4Öl4Ö4Öl4f4 Ö‡Ö ÿÿÿÿ`Ö ÿÿÿÿÔ€ÖÖ‚ÖƒÖ„ÖÖ(ÿÿÿÿÿÿÿÿÿÿÿÿ†œ@ñÿ@NormalCJsH mH tH _HaJDAòÿ¡DDefault Paragraph Fontdióÿ³d Table Normal.aöö4Ö4Öl4Ö4Öl (kôÿÁ(No ListÌþñÿòÌ Free FormE$$$¤¤dð*$1$@& ]„^„`„$a$-DMÆ ÿÿY568:;<7S*CJOJPJQJ@ˆphsHmHH*>*KHEHfHqÊ ÿÿîþñÿîBody An$$$¤¤dð*$1$@& ]„^„`„$a$-DMÆ ÿÿÆ& 0`Àð P€°à@Y568:;<7S*CJOJPJQJ@ˆphsH mH H*>*KHEHfHqÊ ÿÿþþñÿþAgreementTitlen$$$¤¤Œdð*$1$@& ]„^„`„$a$-DMÆ ÿÿÆ& 0`Àð P€°à@Y568:;<7S*CJOJPJQJ@ˆphsH mH H*>*KHEHfHqÊ ÿÿþñÿ"NumberedParagraphn$$$¤x¤dð*$1$@& ]„^„`„$a$-DMÆ ÿÿÆ& 0`Àð P€°à@Y568:;<7S*CJOJPJQJ@ˆphsH mH H*>*KHEHfHqÊ ÿÿþñÿ2SubParagraphBulletn$$$¤¤dð*$1$@& ]„^„`„$a$-DMÆ ÿÿÆ& `Àð P€°à@Y568:;<7S*CJOJPJQJ@ˆphsH mH H*>*KHEHfHqÊ ÿÿÔþñÿBÔ TableContentsE$$$¤¤dð*$1$@& ]„^„`„$a$-DMÆ ÿÿY568:;<7S*CJOJPJQJ@ˆphsH mH H*>*KHEHfHqÊ ÿÿôþñÿRô CCLicensen$$$¤¤dð*$1$@& ]„^„`„$a$-DMÆ ÿÿÆ& 0`Àð P€°à@Y568:) 0 00#R$‰°Ð°`°Ð/ °à=!°Ä"°ÄDHT V   ô ö ”–Ê̲´¨ª¦¨²´ÆÈZ\ÊÌ~€  ¢ V!X!""¼"ýóðçäßÜ×ÔÏÌÇÄ¿¼·´¯¬§¤Ÿœ—”Œ‡„|wtolgdCJCJEHCJCJEHCJCJEHCJCJEHCJCJEHCJCJEHCJCJEHCJCJEHCJCJEHCJCJEHCJCJEHCJCJEHCJCJEHCJCJEHCJCJEHCJCJEHCJCJOJPJQJCJ5CJ$OJPJQJCJ$%¼"Ø"Ú"Ü"¨#²#Î#î# $$$$$$$$$"$$$&$($,$.$0$2$6$8$:$<$@$B$D$F$J$L$N$P$T$V$X$Z$\$:%L%N%P%f%h%j%‚%„%†%¦%¨%ª%¬%¸%º%¾%r&t&v&x&z&|&~&ýüüùöóðíüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüêçüüäüüáüüÞüüüÛüüØüüüÏÆ«4jUCJOJPJQJsHmHtHujhCJOJPJQJCJOJPJQJCJCJCJCJCJCJCJCJCJCJCJCJCJA~&€&0'ò'ô'l(n(p(Ì(Î(Ð(Ò(Ô(÷ôñìëàÛÔ͈Cëˆ568:;<79XTS*CJOJPJQJ@ˆphÿRHdsHmHtH_HH*>*KHEHwhÿ *ehrÊÿfHqÊ ÿÿˆ568:;<79XTS*CJOJPJQJ@ˆphÿRHdsHmHtH_HH*>*KHEHwhÿ *ehrÊÿfHqÊ ÿÿ 0JjU CJphþ>* jUjUj jUCJCJCJOJPJQJ Ô(Ö(Ø(,).):)<)>)@)B)D)X)Z)\)^)»º²¥ˆ{sf^QI<6jUCJsH mH 6CJsH mH 6jUCJsH mH 6CJsH mH 6jUCJsH mH 6CJsH mH 6jUCJsH mH 6CJsH mH 6jUCJsH mH 6CJsH mH 6jUCJsH mH 6CJsH mH ˆ568:;<79XTS*CJOJPJQJ@ˆphÿRHdsHmHtH_HH*>*KHEHwhÿ *ehrÊÿfHqÊ ÿÿ^)`)b)¶)¸)Ä)Æ)È)Ê)Ì)Î)â)ä)æ)è)»º²¥ˆ{sf^QI<6jUCJsH mH 6CJsH mH 6jUCJsH mH 6CJsH mH 6jUCJsH mH 6CJsH mH 6jUCJsH mH 6CJsH mH 6jUCJsH mH 6CJsH mH 6jUCJsH mH 6CJsH mH ˆ568:;<79XTS*CJOJPJQJ@ˆphÿRHdsHmHtH_HH*>*KHEHwhÿ *ehrÊÿfHqÊ ÿÿè)ê)î)ð)»ºuˆ568:;<79XTS*CJOJPJQJ@ˆphÿRHdsHmHtH_HH*>*KHEHwhÿ *ehrÊÿfHqÊ ÿÿˆ568:;<79XTS*CJOJPJQJ@ˆphÿRHdsHmHtH_HH*>*KHEHwhÿ *ehrÊÿfHqÊ ÿÿHV  ö –Ì´ª¨ûù×מžžžž|! & F`„åþÆ2 0`Àð P€°à@9 & F^„ `„VÿÆ] ª`Àð P€°à@  `Àð P€°à@! & F`„åþÆ2 0`Àð P€°à@¤È ¨´È\Ì€ÆÆ¤¤k9 & F^„ `„VÿÆ] ª`Àð P€°à@  `Àð P€°à@! & F`„åþÆ2 0`Àð P€°à@9 & F^„ `„VÿÆ] ª`Àð P€°à@  `Àð P€°à@€¢ X!""¼"Ø"Ú"ÆÆ¤¤ž˜˜$If¤d¤d! & F`„åþÆ2 0`Àð P€°à@9 & F^„ `„VÿÆ] ª`Àð P€°à@  `Àð P€°à@Ú"Ü"¨#²#Î#:4..$If¤d¤dÄ$$If–l”hÖ0© Ä%© aölö4Ö4Öl4Ö4Öl4f4 Ö‡Ö ÿÿÿÿ`Ö ÿÿÿÿÔ€ÖÖ‚ÖƒÖ„ÖÖÿÿÿÿÿÿÿÿpÖÿÿÿÿÿÿÿÿ,ÖÖÖÖÖ2Ö2Ö2Ö2Ö2Ö2Ö2Ö2ÖÿÿÿÿpÖ(ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ,ÖÖÖÖÖ2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2ÖF$$If–l”~Ö\ÊZŠÄ%Ê 0 :aölö4Ö4Öl4Ö4Öl4f4 Ö‡Ö ÿÿÿÿ`Ö ÿÿÿÿÔ€ÖÖ‚ÖƒÖ„ÖÖ(ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿpÖ(ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ,ÖÖÖÖÖ2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2ÖF$$If–l”~Ö\ÊZŠÄ%Ê 0 :aölö4Ö4Öl4Ö4Öl4f4 Ö‡Ö ÿÿÿÿ`Ö ÿÿÿÿÔ€ÖÖ‚ÖƒÖ„ÖÖ(ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿpÖ(ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ,ÖÖÖÖÖ2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2ÖF$$If–l”~Ö\ÊZŠÄ%Ê 0 :aölö4Ö4Öl4Ö4Öl4f4 Ö‡Ö ÿÿÿÿ`Ö ÿÿÿÿÔ€ÖÖ‚ÖƒÖ„ÖÖ(ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿpÖ(ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ,ÖÖÖÖÖ2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2ÖF$$If–l”~Ö\ÊZŠÄ%Ê 0 :aölö4Ö4Öl4Ö4Öl4f4 Ö‡Ö ÿÿÿÿ`Ö ÿÿÿÿÔ€ÖÖ‚ÖƒÖ„ÖÖ(ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿpÖ(ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ,ÖÖÖÖÖ2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2ÖÎ#î# $ $$$$$$$$$$ $"$$$&$($*$,$.$0$2$4$6$8$ùùôùùùùïùùùùêùùùùåùùùùàùùFfï Ff§Ff_FfFfÏ$If2Ö2Ö2Ö2Ö2Ö2ÖF$$If–l”~Ö\ÊZŠÄ%Ê 0 :aölö4Ö4Öl4Ö4Öl4f4 Ö‡Ö ÿÿÿÿ`Ö ÿÿÿÿÔ€ÖÖ‚ÖƒÖ„ÖÖ(ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿpÖ(ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ,ÖÖÖÖÖ2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2ÖF$$If–l”~Ö\ÊZŠÄ%Ê 0 :aölö4Ö4Öl4Ö4Öl4f4 Ö‡Ö ÿÿÿÿ`Ö ÿÿÿÿÔ€ÖÖ‚ÖƒÖ„ÖÖ(ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿpÖ(ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ,ÖÖÖÖÖ2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2ÖF$$If–l”~Ö\ÊZŠÄ%Ê 0 :aölö4Ö4Öl4Ö4Öl4f4 Ö‡Ö ÿÿÿÿ`Ö ÿÿÿÿÔ€ÖÖ‚ÖƒÖ„ÖÖ(ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿpÖ(ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ,ÖÖÖÖÖ2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2ÖF$$If–l”~Ö\ÊZŠÄ%Ê 0 :aölö4Ö4Öl4Ö4Öl4f4 Ö‡Ö ÿÿÿÿ`Ö ÿÿÿÿÔ€ÖÖ‚Ö8$:$<$>$@$B$D$F$H$J$L$N$P$R$T$V$X$Z$\$:%L%N%ùùôùùùùïùùùùêùùùùåßùù¤d¤dFfFfÇFfFf7 $IfN%P%f%h%:44$IfÄ$$If–l”hÖ0´ Ä%´ aölö4Ö4Öl4Ö4Öl4f4 Ö‡Ö ÿÿÿÿ`Ö ÿÿÿÿÔ€ÖÖ‚ÖƒÖ„ÖÖÿÿÿÿÿÿÿÿpÖÿÿÿÿÿÿÿÿ,ÖÖÖÖÖ2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Öh%j%‚%„%:44$IfÄ$$If–l”hÖ0´ Ä%´ aölö4Ö4Öl4Ö4Öl4f4 Ö‡Ö ÿÿÿÿ`Ö ÿÿÿÿÔ€ÖÖ‚ÖƒÖ„ÖÖÿÿÿÿÿÿÿÿpÖÿÿÿÿÿÿÿÿ,ÖÖÖÖÖ2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö„%†%¦%¨%ª%:444$IfÄ$$If–l”hÖ0´ Ä%´ aölö4Ö4Öl4Ö4Öl4f4 Ö‡Ö ÿÿÿÿ`Ö ÿÿÿÿÔ€ÖÖ‚ÖƒÖ„ÖÖÿÿÿÿÿÿÿÿpÖÿÿÿÿÿÿÿÿ,ÖÖÖÖÖ2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Öª%¬%¸%º%:44$IfÄ$$If–l”€Ö0´ Ä%´ aölö4Ö4Öl4Ö4Öl4f4 Ö‡Ö ÿÿÿÿ`Ö ÿÿÿÿÔ€ÖÖ‚ÖƒÖ„ÖÖÿÿÿÿÿÿÿÿpÖÿÿÿÿÿÿÿÿ,ÖÖÖÖÖ2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Öº%¼%¾%r&t&v&:8888Ä$$If–l”hÖ0´ Ä%´ aölö4Ö4Öl4Ö4Öl4f4 Ö‡Ö ÿÿÿÿ`Ö ÿÿÿÿÔ€ÖÖ‚ÖƒÖ„ÖÖÿÿÿÿÿÿÿÿpÖÿÿÿÿÿÿÿÿ,ÖÖÖÖÖ2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Öv&x&z&|&€&0'ò'Ð(Ò(Ô(Ö(Ø(`)b)ê)î)ð)ýýûûûûûù÷ù÷ò÷ò÷û$a$;<7S*CJOJPJQJ@ˆphsH mH H*>*KHEHfHqÊ ÿÿø*ÿÿÿÿIŽŽŽ‘¼"~&Ô(^)è)ò)¨€Ú"Î#8$N%h%„%ª%º%v&ò) !"#$%&'ÿÿUnknownù7fj“Xÿ€.579DFsz|~‰‹‘!ÿ€“ÿ€!ÿ€“ÿ€ðlðð,bð$¶,^N¤O¢ªŽŽ]µ“ðWÿ1Pnð)¶,^N¤O¢ªŽŽ]µ“ðWÿ‰PNG  IHDRYŒ aÞ%iCCPICC Profilex…”MHaÇÿ³±Ñ—ÅÐÁ$T& RÓõ+S¶eÕL b}wg§™Ý-E"„è˜uŒ.VD‡ˆNá¡C§:D™u‰ £E^"¶ÿ;“»cT¾03¿yžÿû|½ÃURŽcE4`ÊλÉÞ˜vztLÛüU¨F\)Ãs:‰Ÿ©•Ïõkõ-iYj”±Öû6|«v™P4*wd>,y<àã’/ä<5g$©4Ù!7¸CÉNò-òÖlˆÇCœžTµS“3—q";È-E#+c> ëvÚ´Éï¥=íSÔ°ßÈ79 Ú¸òý@Û`Ó‹ŠmÌÜv×Ulõ5ÀÎ`ñPÅö=éÏGÙõÊËjöÃ)ÑkúP*}¯6ß~^/•~Ü.•~ÞaÖñÔ2 nÑײ0å%Ôìfüäý‹ƒž|U °À9Žlú¯7?ûÛ‰j`¨‘Ël7¸òâ"çtæœi×ÌNäµf]?¢uðh…ÖgM Zʲ4ßåi®ð„[é&LYÎÙ_Ûx {xOö¹$¼î̥߬S]œ%šØÖ§´èê&7ïgÌž>r=¯÷·g8`候ï 8rʶâ<©‰ÔØãñ“dÆWT'“ó<çeLß~.u"A®¥=9™ë—š]ÜÛ>31Ä3’¬X3ñßüÆ-$eÞ}ÔÜu,ÿ›gm‘g…6ï64$Ñ‹áÀEzL*LZ¥_ÐjÂÃä_•å]½XážÏy¸[Æ?…Xs åšþNÿ¢/ë ú]ýó|m¡¾â™sϚƫk_Wf–ÕȸA2¾¬)ˆo°Úz-diâôä•õáê2ö|mÙ£Éâj|5Ô¥ejÄ8ãÉ®e÷E²Å7áç[Ëö¯éQû|öIM%ײºxf)ú|6\ kÿ³«`Ò²«ðä.€:)(œµk×ÊxÖm¥NtÖÔÎUËV!¿[~¬Y³FLþí·ß¢|ùò¨Y³&üüüP¥J¬\¹R^¥åþôÓO¸wç"·lG©ó´õúû,þû†½rpľ…ß/OÞ¹sg,_¾Ül1™1¯W¯¶lÙ‚ (Íù á¡E‹2{ONGK->}½zõBÅŠõG⬨mÛ¶•M§PŸ>}j|N‹ëÚµ+Ž:‚øûñàzH¸éüŒ1Bð—íË–-ÃØ±c*ûö틞={âæÍ›èÑ£‡ÀûP¹5j„(åx铸aY¡÷„ì`pÀÏ›"DÐÜÝÅ‹KX“¦ì[©R%ÁPNhÇ/;g3šÚ¥ß.J¼Ú±cG³¡÷ïßþýûcÊ”)˜8q"(B†)µoß^„óïp=$nÜùsçáäè„V­ZIÛ“'O0oÞ<ù=uêTY+µVo£†¿~ýZž“'|ëÆ-Ù0i´ñËLÈ4¯ààþƒ²[\„©9Ò=|øIIIï±OLLÄ£GD0úÃvíÚ¡aÆ2ÑýQû3„ý¹ª¹/Ù²eƒ§§§Ù#k7LL‰ïp-•³ÖµŽ°CŸQ°`Aög÷øñc§téÒFô;9rä#—7T¸¨ÈÇÇG®OT{;3±I{F_f½˜Ó¼ÖpP¾N6lgÔ)S!!!"ìW¯^aøðáÒ¿dÉ’ð÷÷==Î…ÒüHçƳ¯¾h¯õ«¦41E´hJÖ"Ë0‘ïp쥦”ªâgÆÜ:O®q×®]»ÒAòÃx[W(Þ“8¾mk0²ƒ™@ÇÆÄÊÓ H¢ÁÆ¡]ºtÁµk×Я_?øúúŠƒÛ·oÆ'ÑD‘"E0`ÀñÐÆ ç»t&ôÈôÞÄN.>SRŠÉð›BË1%ÂP‹-ŒM„///ã=Т(Œ¼®yíL>·|ÂOÇpFM{öìÁŒ¡'_`”òüùs™ƒ¹Ü½û.Ya²“Õ”Û,¡ö1e%™NœÎ“¦@é4ˆS4%ƨ>!eãÆ(^¼¸8*î:Ÿ‘òçÏ/¿cccñ2ñ%ì fî4ÒÞ¦ÁËç]²Á¤åèÄøœŽmëÖ­ÒÔ»wï÷ …¸M*Q¢„1„ãÚJ—)í[·#::Zp™ó¤Õ±?Ã7:@ÂÞèÑ£E­[·x!¯¨=QwE‹5òd»-d¦VÜ¡W*¾%1LÒIO0˜e‘˜fÒãsBÏž=A*THž2(lݤoßH4=½]ÒùbzÏ´¶˜{1I¨U¦D ÔIwLú=ktÖž¥*ƒõy§å;ÖîUõÒ>¤Aã†pU¥= ™‘EôÑh~î cVBCm¥)±ß„ ÀL°N:rþüyP°Ô š«íر¡¡¡(Z¼‚TáȸÐ'J-¬P±‚܆® EXh’^' 7oÞ\ÆfÝdéÒ¥èÓ§Nž<‰ÎÝ‚•¶vqÝq|¿ª•ñBù‡5«WKÒD ¬qá˜&œq˜fOá›ašÃHB'š2ãd:–ÖíÛ G¯RÑŸÛr¥P8 UÃ6ª$å’¼æìä,Wj'©¼ÂÛvÚ£¢_E†òÐâ‹`‰4úÈ1„‡…«Déºôpqv‘ÍÑ¡®zêÂÓ»´7Þ$›[…Ë÷n9g½@d&) ™Që¨[6nFHHÊéE.Ø491åLMàÇ”˜òRÀÄ×ÀâlLŸÛò›Ââ¢ýªUÇÅŒëZÌ5I"8F/¥¼J¢ˆòú\˜%DXƒëT Úuk£ªªÖÅ]Ãõk×%²b®@xùx©ya©¹dUÀ–cŠYrvq†!Å &Ó¢u œˆ>Ë—/ æ®_¿^" Ë—3º?tèè°HA­šÃÝÃ]jø–ËgŒj|ËøÊáLâ&¤¦¥âmš:‚R¿-7Ú’‡å=­’VPɯ’@sGM®0ÂÈQ gó„È’‡µ{nåJâŸÖV9—üj÷¸Ã^ªfêSÆG2¿)ã'+ìzâß’%K ‡iÖ˜š¶ÑI²¾À¤ ²Â¿oÆ=tÔ&M3åõGýMHz¤þ¦õ›d ²yê—\U°­­Z¿Z‹Üó‹6&dŒ¦2iW1¤¦’Ma²RëtñâEMUÍ4•¶Ê;ʵ•a«´mû¶k=ûüÍl}¼ÿ…+mŽ‹7£zõëaðð!’¿_¹|?ÌýAaÖ»t›áN@@€œŒ™`è'#̤Ó”›+Èéò—.¶ùõ ¦Oš&i²Ù@Y¸aÙ”IÚ^ܺuKŠê4G†‡¯hÑ¢’›ÆÐ™±'´°ÒÈ”ÿöíÛÒmLÄX<ú”dUÚµ ÒÂ#7i[÷DŠf«ÐH+X¨ Õ¾j2Ò®ðVS'ßZÈÔ‰Ú–ZdÔ/ÚÔYÓ´|nn¾§¿ŸÑUŪšJ4•$h*×TÍZ£å('¥©PSS‡ šÂl›ÇÉ“'¦RsMïµ³gÏjmÚ´‘wGŽ©)˜ÓÔyŸÍ¼2š7ŸYÕdõ@¨VÝZøkŸžP• Ö5._º¬N«ÿÇK,Í¢’«*¼x(Çæ[¶´88ž£¥¦¤âÐþCøçâ¥{ë%1ÖÞ»w¯dœ¬3£ä¹#Óú‚¬ \=ÔÓàÁƒ% – ³4ÂXäâ1ÇüXÊTÈú7ãn‚PæÉ› ÓÞýÓ‡ŠQùŸ7œÜÇíúXÖ®lýúõ œ.ñ™Þ“Óf•Xì¢u³ØiÓ¦¡C‡ °éÈùœò)„œ)\duò´þ„;Zãç$éÇÛÃçœágæý¹LùþüÉ ÂåHöIEND®B`‚ŸÑUŪšJ4•$h*×TÍZ£å('¥©PSS‡ šÂl›ÇÉ“'¦RsMïµ³gÏjmÚ´‘wGŽ©)˜ÓÔyŸÍ¼2š7ŸYÕdõ@¨VÝZøkŸžP• Ö5._º¬N«ÿÇK,Í¢’«*¼x(Çæ[¶´88ž£¥¦¤âÐþCøçâ¥{ë%1ÖÞ»w¯dœ¬3£ä¹#Óú‚¬ \=ÔÓàÁƒ% – ³4ÂXäâ1ÇüXÊTÈú7ãn‚PæÉ› ÓÞýÓ‡ŠQùŸ7œÜÇíúXÖ®lýúõ œ.ñ™Þ“Óf•Xì¢u³ØiÓ¦¡C‡ °éÈùœò)„œ)\@ñÿÿÿ€€€÷ð&ððÊð( ð ðð’² ð³ ðBA¿ÀËœ1Ö×ÿ„ð…ð†ð‡ðC"ñ‘’ððð< ð C ð¿ÿ ?ð>øôlJsèN‰ÿÿÿÿÿÿÿÿÿtèN‰ÿÿÿÿÿÿÿÿÿuèN‰ÿÿÿÿÿÿÿÿÿvèN‰ÿÿÿÿÿÿÿÿÿwèN‰ÿÿÿÿÿÿÿÿÿxèN‰ÿÿÿÿÿÿÿÿÿyèN‰ÿÿÿÿÿÿÿÿÿ^„`„ÆCJpho(EH.^„`„ÐCJpho(EH^„`„ CJpho(EH^„`„pCJpho(EH^„`„@ CJpho(EH^„`„CJpho(EH^„`„àCJpho(EH^„`„°CJpho(EH^„`„€CJpho(EH^„ª`„vƪCJpho(EH" ^„`„ÐCJpho(EH^„`„ CJpho(EH^„`„pCJpho(EH^„`„@ CJpho(EH^„`„CJpho(EH^„`„àCJpho(EH^„`„°CJpho(EH^„`„€CJpho(EH^„`„ÆCJpho(EH.^„`„ÐCJpho(EH^„`„ CJpho(EH^„`„pCJpho(EH^„`„@ CJpho(EH^„`„CJpho(EH^„`„àCJpho(EH^„`„°CJpho(EH^„`„€CJpho(EH^„ª`„vƪCJpho(EH" ^„`„ÐCJpho(EH^„`„ CJpho(EH^„`„pCJpho(EH^„`„@ CJpho(EH^„`„CJpho(EH^„`„àCJpho(EH^„`„°CJpho(EH^„`„€CJpho(EH^„`„ÆCJpho(EH.^„`„ÐCJpho(EH^„`„ CJpho(EH^„`„pCJpho(EH^„`„@ CJpho(EH^„`„CJpho(EH^„`„àCJpho(EH^„`„°CJpho(EH^„`„€CJpho(EH^„ª`„vƪCJpho(EH" ^„`„ÐCJpho(EH^„`„ CJpho(EH^„`„pCJpho(EH^„`„@ CJpho(EH^„`„CJpho(EH^„`„àCJpho(EH^„`„°CJpho(EH^„`„€CJpho(EH^„`„ÆCJpho(EH.^„`„ÐCJpho(EH^„`„ CJpho(EH^„`„pCJpho(EH^„`„@ CJpho(EH^„`„CJpho(EH^„`„àCJpho(EH^„`„°CJpho(EH^„`„€CJpho(EHÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿø`iTimes New RomanTimes New RomanESymbolSymbolA&ArialArialaÒ0é0®0Î0Ò‰´0 Pro W3Ò0é0®0Î0Ò‰´0 Pro W3ATimesTimesQHelveticaHelvetica#ˆÐhäŠ 'äŠ '!ƒÖ„ÖÖ(ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿpÖ(ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ,ÖÖÖÖÖ2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö2Ö0 :aölö4Ö4Öl4Ö4Öl4f4 Ö‡Ö ÿÿÿÿ`Ö ÿÿÿÿÔ€ÖÖ‚Ö€#@(0(       Root EntryBPafouÿ (-29@CEÿÿÿÿÿÿÿÿ€>ÕÞ±€…uæ·”ÍO@1Table\jw~…’œ£¦¬°¼ÆËÏÔ×Þêíòû ÿÿÿÿ€…u淔̀…uæ·”ÍA!WordDocumentPaSiEÿÿÿÿ€…u淔̀…uæ·”Í1bData    ÿÿÿÿÿÿÿÿÿÿÿÿ€…u淔̀…uæ·”ÍWþÿÕÍÕœ.“—+,ù®DÕÍÕœ.“—+,ù®|8 ( 0 þÿà…ŸòùOh«‘+'³Ù0SummaryInformation  (ÿÿÿÿÿÿÿÿ€…u淔̀…uæ·”ÍHDocumentSummaryInformation8ÿÿÿÿÿÿÿÿÿÿÿÿ€…u淔̀…uæ·”ÍObjectPool p8°¡°A ÑÉ©P“ÿÿÿÿÿÿÿÿÿÿÿÿ€…u淔̀…uæ·”Íÿÿÿÿ0`Æp°€œÐJ@°° Cðþ€Åp…0àm°—à•ààаk°À^ðŸÿÿÿÿÿÿÿÿÿÿÿÿ€>ÕÞ±€>ÕÞ±ÿÿÿÿþÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ &7 !"#$%+'()*,0-./L1234568B9:;<=>?@AþÿÿÿCDEFGHIJKMþÿÿÿþÿÿÿPþÿÿÿþÿÿÿþÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿlibsynthesis-3.4.0.47.1/libsynthesis_contributor_agreement.pages000066400000000000000000006457671226375725500251170ustar00rootroot00000000000000PK\1AiH à image.png‰PNG  IHDRYŒ aÞ%iCCPICC Profilex…”MHaÇÿ³±Ñ—ÅÐÁ$T& RÓõ+S¶eÕL b}wg§™Ý-E"„è˜uŒ.VD‡ˆNá¡C§:D™u‰ £E^"¶ÿ;“»cT¾03¿yžÿû|½ÃURŽcE4`ÊλÉÞ˜vztLÛüU¨F\)Ãs:‰Ÿ©•Ïõkõ-iYj”±Öû6|«v™P4*wd>,y<àã’/ä<5g$©4Ù!7¸CÉNò-òÖlˆÇCœžTµS“3—q";È-E#+c> ëvÚ´Éï¥=íSÔ°ßÈ79 Ú¸òý@Û`Ó‹ŠmÌÜv×Ulõ5ÀÎ`ñPÅö=éÏGÙõÊËjöÃ)ÑkúP*}¯6ß~^/•~Ü.•~ÞaÖñÔ2 nÑײ0å%Ôìfüäý‹ƒž|U °À9Žlú¯7?ûÛ‰j`¨‘Ël7¸òâ"çtæœi×ÌNäµf]?¢uðh…ÖgM Zʲ4ßåi®ð„[é&LYÎÙ_Ûx {xOö¹$¼î̥߬S]œ%šØÖ§´èê&7ïgÌž>r=¯÷·g8`候ï 8rʶâ<©‰ÔØãñ“dÆWT'“ó<çeLß~.u"A®¥=9™ë—š]ÜÛ>31Ä3’¬X3ñßüÆ-$eÞ}ÔÜu,ÿ›gm‘g…6ï64$Ñ‹áÀEzL*LZ¥_ÐjÂÃä_•å]½XážÏy¸[Æ?…Xs åšþNÿ¢/ë ú]ýó|m¡¾â™sϚƫk_Wf–ÕȸA2¾¬)ˆo°Úz-diâôä•õáê2ö|mÙ£Éâj|5Ô¥ejÄ8ãÉ®e÷E²Å7áç[Ëö¯éQû|öIM%ײºxf)ú|6\ kÿ³«`Ò²«ðä.€:)(œµk×ÊxÖm¥NtÖÔÎUËV!¿[~¬Y³FLþí·ß¢|ùò¨Y³&üüüP¥J¬\¹R^¥åþôÓO¸wç"·lG©ó´õúû,þû†½rpľ…ß/OÞ¹sg,_¾Ül1™1¯W¯¶lÙ‚ (Íù á¡E‹2{ONGK->}½zõBÅŠõG⬨mÛ¶•M§PŸ>}j|N‹ëÚµ+Ž:‚øûñàzH¸éüŒ1Bð—íË–-ÃØ±c*ûö틞={âæÍ›èÑ£‡ÀûP¹5j„(åx铸aY¡÷„ì`pÀÏ›"DÐÜÝÅ‹KX“¦ì[©R%ÁPNhÇ/;g3šÚ¥ß.J¼Ú±cG³¡÷ïßþýûcÊ”)˜8q"(B†)µoß^„óïp=$nÜùsçáäè„V­ZIÛ“'O0oÞ<ù=uêTY+µVo£†¿~ýZž“'|ëÆ-Ù0i´ñËLÈ4¯ààþƒ²[\„©9Ò=|øIIIï±OLLÄ£GD0úÃvíÚ¡aÆ2ÑýQû3„ý¹ª¹/Ù²eƒ§§§Ù#k7LL‰ïp-•³ÖµŽ°CŸQ°`Aög÷øñc§téÒFô;9rä#—7T¸¨ÈÇÇG®OT{;3±I{F_f½˜Ó¼ÖpP¾N6lgÔ)S!!!"ìW¯^aøðáÒ¿dÉ’ð÷÷==Î…ÒüHçƳ¯¾h¯õ«¦41E´hJÖ"Ë0‘ïp쥦”ªâgÆÜ:O®q×®]»ÒAòÃx[W(Þ“8¾mk0²ƒ™@ÇÆÄÊÓ H¢ÁÆ¡]ºtÁµk×Я_?øúúŠƒÛ·oÆ'ÑD‘"E0`ÀñÐÆ ç»t&ôÈôÞÄN.>SRŠÉð›BË1%ÂP‹-ŒM„///ã=Т(Œ¼®yíL>·|ÂOÇpFM{öìÁŒ¡'_`”òüùs™ƒ¹Ü½û.Ya²“Õ”Û,¡ö1e%™NœÎ“¦@é4ˆS4%ƨ>!eãÆ(^¼¸8*î:Ÿ‘òçÏ/¿cccñ2ñ%ì fî4ÒÞ¦ÁËç]²Á¤åèÄøœŽmëÖ­ÒÔ»wï÷ …¸M*Q¢„1„ãÚJ—)í[·#::Zp™ó¤Õ±?Ã7:@ÂÞèÑ£E­[·x!¯¨=QwE‹5òd»-d¦VÜ¡W*¾%1LÒIO0˜e‘˜fÒãsBÏž=A*THž2(lݤoßH4=½]ÒùbzÏ´¶˜{1I¨U¦D ÔIwLú=ktÖž¥*ƒõy§å;ÖîUõÒ>¤Aã†pU¥= ™‘EôÑh~î cVBCm¥)±ß„ ÀL°N:rþüyP°Ô š«íر¡¡¡(Z¼‚TáȸÐ'J-¬P±‚܆® EXh’^' 7oÞ\ÆfÝdéÒ¥èÓ§Nž<‰ÎÝ‚•¶vqÝq|¿ª•ñBù‡5«WKÒD ¬qá˜&œq˜fOá›ašÃHB'š2ãd:–ÖíÛ G¯RÑŸÛr¥P8 UÃ6ª$å’¼æìä,Wj'©¼ÂÛvÚ£¢_E†òÐâ‹`‰4úÈ1„‡…«Déºôpqv‘ÍÑ¡®zêÂÓ»´7Þ$›[…Ë÷n9g½@d&) ™Që¨[6nFHHÊéE.Ø491åLMàÇ”˜òRÀÄ×ÀâlLŸÛò›Ââ¢ýªUÇÅŒëZÌ5I"8F/¥¼J¢ˆòú\˜%DXƒëT Úuk£ªªÖÅ]Ãõk×%²b®@xùx©ya©¹dUÀ–cŠYrvq†!Å &Ó¢u œˆ>Ë—/ æ®_¿^" Ë—3º?tèè°HA­šÃÝÃ]jø–ËgŒj|ËøÊáLâ&¤¦¥âmš:‚R¿-7Ú’‡å=­’VPɯ’@sGM®0ÂÈQ gó„È’‡µ{nåJâŸÖV9—üj÷¸Ã^ªfêSÆG2¿)ã'+ìzâß’%K ‡iÖ˜š¶ÑI²¾À¤ ²Â¿oÆ=tÔ&M3åõGýMHz¤þ¦õ›d ²yê—\U°­­Z¿Z‹Üó‹6&dŒ¦2iW1¤¦’Ma²RëtñâEMUÍ4•¶Ê;ʵ•a«´mû¶k=ûüÍl}¼ÿ…+mŽ‹7£zõëaðð!’¿_¹|?ÌýAaÖ»t›áN@@€œŒ™`è'#̤Ó”›+Èéò—.¶ùõ ¦Oš&i²Ù@Y¸aÙ”IÚ^ܺuKŠê4G†‡¯hÑ¢’›ÆÐ™±'´°ÒÈ”ÿöíÛÒmLÄX<ú”dUÚµ ÒÂ#7i[÷DŠf«ÐH+X¨ Õ¾j2Ò®ðVS'ßZÈÔ‰Ú–ZdÔ/ÚÔYÓ´|nn¾§¿ŸÑUŪšJ4•$h*×TÍZ£å('¥©PSS‡ šÂl›ÇÉ“'¦RsMïµ³gÏjmÚ´‘wGŽ©)˜ÓÔyŸÍ¼2š7ŸYÕdõ@¨VÝZøkŸžP• Ö5._º¬N«ÿÇK,Í¢’«*¼x(Çæ[¶´88ž£¥¦¤âÐþCøçâ¥{ë%1ÖÞ»w¯dœ¬3£ä¹#Óú‚¬ \=ÔÓàÁƒ% – ³4ÂXäâ1ÇüXÊTÈú7ãn‚PæÉ› ÓÞýÓ‡ŠQùŸ7œÜÇíúXÖ®lýúõ œ.ñ™Þ“Óf•Xì¢u³ØiÓ¦¡C‡ °éÈùœò)„œ)\duò´þ„;Zãç$éÇÛÃçœágæý¹LùþüÉ ÂåHöIEND®B`‚PK\1Aװ޲ÆÆthumbs/PageCapThumbV2-1.tiffMM*Àúþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþíþþ ÿíÿþ þñþþÿíÿþþñþþ$ÿíÿþ$þñþþ&ÿíÿþ&þñþþ&ÿíÿþ&þñþþ&ÿíÿþ&þñþþ&ÿíÿþ&þñþþ&ÿíÿþ&þñþþ&ÿíÿþ&þñþþ&ÿíÿþ&þñþþ&ÿíÿþ&þñþþ&ÿíÿþ&þñþþ&ÿíÿþ&þñþþ&ÿíÿþ&þñþþ&ÿíÿþ&þñþþ&ÿíÿþ&þñþþ&ÿíÿþ&þñþþ&ÿíÿþ&þñþþ&ÿíÿþ&þñþþ&ÿíÿþ&þñþþ&ÿíÿþ&þñþþ&ÿíÿþ&þñþþ&ÿíÿþ&þñþþ&ÿíÿþ&þñþþ&ÿíÿþ&þñþþ&ÿíÿþ&þñþþ&ÿíÿþ&þñþþ&ÿíÿþ&þñþþ&ÿíÿþ&þñþþ&ÿíÿþ&þñþþ&ÿíÿþ&þñþþ&ÿíÿþ&þñþþ&ÿíÿþ&þñþþ&ÿíÿþ&þñþþ&ÿíÿþ&þñþþ&ÿíÿþ&þñþþ&ÿíÿþ&þñþþ&ÿíÿþ&þñþþ&ÿíÿþ&þñþþ&ÿíÿþ&þñþþ&ÿíÿþ&þñþþ&ÿíÿþ&þñþþ&ÿíÿþ&þñþþ&ÿíÿþ&þñþþ&ÿíÿþ&þñþþ&ÿíÿþ&þñþþ&ÿíÿþ&þñþþ$ÿíÿþ$þñþþþ?þTþYþYþYþYþYþYþYþYþYþYþYþYþYþYþYþYþYþYþYþYþYþYþYþYþYþYþYþYþYþYþYþYþYþTþ?þþñþþ þþ$þ&þ&þ&þ&þ&þ&þ&þ&þ&þ&þ&þ&þ&þ&þ&þ&þ&þ&þ&þ&þ&þ&þ&þ&þ&þ&þ&þ&þ&þ&þ&þ&þ&þ$þþ þñúþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþíÍÍÍÍ-8n€8¸RSv‡s H~ HLinomntrRGB XYZ Î 1acspMSFTIEC sRGBöÖÓ-HP cprtP3desc„lwtptðbkptrXYZgXYZ,bXYZ@dmndTpdmddĈvuedL†viewÔ$lumiømeas $tech0 rTRC< gTRC< bTRC< textCopyright (c) 1998 Hewlett-Packard CompanydescsRGB IEC61966-2.1sRGB IEC61966-2.1XYZ óQÌXYZ XYZ o¢8õXYZ b™·…ÚXYZ $ „¶ÏdescIEC http://www.iec.chIEC http://www.iec.chdesc.IEC 61966-2.1 Default RGB colour space - sRGB.IEC 61966-2.1 Default RGB colour space - sRGBdesc,Reference Viewing Condition in IEC61966-2.1,Reference Viewing Condition in IEC61966-2.1view¤þ_.ÏíÌ \žXYZ L VPWçmeassig CRT curv #(-27;@EJOTY^chmrw|†‹•šŸ¤©®²·¼ÁÆËÐÕÛàåëðöû %+28>ELRY`gnu|ƒ‹’š¡©±¹ÁÉÑÙáéòú &/8AKT]gqz„Ž˜¢¬¶ÁËÕàëõ !-8COZfr~Š–¢®ºÇÓàìù -;HUcq~Œš¨¶ÄÓáðþ +:IXgw†–¦µÅÕåö'7HYj{Œ¯ÀÑãõ+=Oat†™¬¿Òåø 2FZn‚–ª¾Òçû  % : O d y ¤ º Ï å û  ' = T j ˜ ® Å Ü ó " 9 Q i € ˜ ° È á ù  * C \ u Ž § À Ù ó & @ Z t Ž © Ã Þ ø.Id›¶Òî %A^z–³Ïì &Ca~›¹×õ1OmŒªÉè&Ed„£Ãã#Ccƒ¤Åå'Ij‹­Îð4Vx›½à&Il²ÖúAe‰®Ò÷@eНÕú Ek‘·Ý*QwžÅì;cвÚ*R{£ÌõGp™Ãì@j”¾é>i”¿ê  A l ˜ Ä ð!!H!u!¡!Î!û"'"U"‚"¯"Ý# #8#f#”#Â#ð$$M$|$«$Ú% %8%h%—%Ç%÷&'&W&‡&·&è''I'z'«'Ü( (?(q(¢(Ô))8)k))Ð**5*h*›*Ï++6+i++Ñ,,9,n,¢,×- -A-v-«-á..L.‚.·.î/$/Z/‘/Ç/þ050l0¤0Û11J1‚1º1ò2*2c2›2Ô3 3F33¸3ñ4+4e4ž4Ø55M5‡5Â5ý676r6®6é7$7`7œ7×88P8Œ8È99B99¼9ù:6:t:²:ï;-;k;ª;è<' >`> >à?!?a?¢?â@#@d@¦@çA)AjA¬AîB0BrBµB÷C:C}CÀDDGDŠDÎEEUEšEÞF"FgF«FðG5G{GÀHHKH‘H×IIcI©IðJ7J}JÄK KSKšKâL*LrLºMMJM“MÜN%NnN·OOIO“OÝP'PqP»QQPQ›QæR1R|RÇSS_SªSöTBTTÛU(UuUÂVV\V©V÷WDW’WàX/X}XËYYiY¸ZZVZ¦Zõ[E[•[å\5\†\Ö]']x]É^^l^½__a_³``W`ª`üaOa¢aõbIbœbðcCc—cëd@d”dée=e’eçf=f’fèg=g“géh?h–hìiCišiñjHjŸj÷kOk§kÿlWl¯mm`m¹nnknÄooxoÑp+p†pàq:q•qðrKr¦ss]s¸ttptÌu(u…uáv>v›vøwVw³xxnxÌy*y‰yçzFz¥{{c{Â|!||á}A}¡~~b~Â#„å€G€¨ kÍ‚0‚’‚ôƒWƒº„„€„ã…G…«††r†×‡;‡ŸˆˆiˆÎ‰3‰™‰þŠdŠÊ‹0‹–‹üŒcŒÊ1˜ÿŽfŽÎ6žnÖ‘?‘¨’’z’ã“M“¶” ”Š”ô•_•É–4–Ÿ— —u—à˜L˜¸™$™™üšhšÕ›B›¯œœ‰œ÷dÒž@ž®ŸŸ‹Ÿú i Ø¡G¡¶¢&¢–££v£æ¤V¤Ç¥8¥©¦¦‹¦ý§n§à¨R¨Ä©7©©ªª««u«é¬\¬Ð­D­¸®-®¡¯¯‹°°u°ê±`±Ö²K²Â³8³®´%´œµµŠ¶¶y¶ð·h·à¸Y¸Ñ¹J¹Âº;ºµ».»§¼!¼›½½¾ ¾„¾ÿ¿z¿õÀpÀìÁgÁãÂ_ÂÛÃXÃÔÄQÄÎÅKÅÈÆFÆÃÇAÇ¿È=ȼÉ:ɹÊ8Ê·Ë6˶Ì5̵Í5͵Î6ζÏ7ϸÐ9кÑ<ѾÒ?ÒÁÓDÓÆÔIÔËÕNÕÑÖUÖØ×\×àØdØèÙlÙñÚvÚûÛ€ÜÜŠÝÝ–ÞÞ¢ß)߯à6à½áDáÌâSâÛãcãëäsäü儿 æ–çç©è2è¼éFéÐê[êåëpëûì†ííœî(î´ï@ïÌðXðåñrñÿòŒóó§ô4ôÂõPõÞömöû÷Šøø¨ù8ùÇúWúçûwüü˜ý)ýºþKþÜÿmÿÿPK\1AÿrÌŽ/¼/¼QuickLook/Thumbnail.jpgÿØÿàJFIFÿá@ExifMM*‡i ‹ ÿÛC    ÿÛCÿÀ‹"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?þþ(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š+ˆø™®jÞøsãÏhRYE­iú=åí£\ÂeˆK,ë½)eÈ#¸®Þ¹Ïøj߯~ñ7„nïõ.ÓT°ŸO–æÓËóàIP£2yˆé¸8ܬ3ÔúrT÷³·©­ ET‹ž×W?”ÏÁp?km{öRñgǵ/Ùùþ,hßtŸˆ×áþ¤!¸¹Ÿ]’ɤŽéµm†"Œ¢ÂJÈ’eÙ™0µú±§Ái¿e!ðï…ü_¥|Oð—Ç Åà›ßjvv:ž´Öùbß5è³q$9h„w2<‡Šïòוøþû+x#Áž%ðütý«¼Qá½WáÝ—Ã+ˆµ=GA šM¶¤ú„R+[é18šFÉ*S¦y®çÇ¿ðDOÙ£âW…þ&x{Æ¿>5x¢ëƺÏöïŒ/u|?túýÔvÑÛZ?—6–ðÙ½ªD¾DÖqÁ21f.Ûˆ¯G:r«7 "õ^_¼zz{7çªG5›”:%£ÿÀ#¯›çNÝÓ×wo^Òÿà«ß³î²ßí¬<ñáµ^ߨø·M—G´Š÷Dk[#zòK ݇´ |aÙ‚› |Çñ?þ ­ðƒMøsm⯂ß>=|Dñ=Æ»àý6ßKÕtëmÍc¯¹ZŠîøØ+€¤«–^B©ß^ðþ ¤¥§ŽîxÚ$o è­ïÆ9Ûø!wì÷qá×ðñý£?kDÙmàÛkÁ{áÕŸMÿ„rBúsÇ·G Íó2Éæ+† €aÍ{Xs|>ã}Þ­ÎÞ±Q²z®i+Ý)UTöo‘®o{{Ùi_[7$Úß•4¬ìøOƒ¿ðYý Ãß´í#ð_ö½Òo<¢èŸ.|àÿi¾’5£‹K]@ÛÞÎnæó.‚o6€pXg×ôßø.Ÿì­Xx~MÄ~,Ôï˜8®ŠãþÕðsZýœü?û*xïö†ý¤þ,|ÒKA¥è¾-O j°ØØd†ÍV] ƒänÝËvŒˆ|óŒUÞ*”o¬”`ºµÏ«êå{y]½mr’—>»7?UyK’Þ\¶ºÑÞÉiv¸†ÿðY…v>/ñ§…þ/ë÷þ"Ôþ#ËàßøjËÃK¡ê–El#º6w¨ß‹yvÂêìNĉÜ_vþÐß·wÁÿÙÃÄ>ðW‰<3ñwÇŸuý*}~ßþðóêZ•¦•A=äІR2ꥴ¬Ü$nx¯ƒn?à‚?²Å׃|wðâ÷ãí­ü9ñ³»¢jçÚ¼7PÛÃ2[´úCMo,i{'ŽA:œþóŠû'ãüÛáÿÅï‹?³ïÇ_ übøóð âçÃ&hú߃oôö“PѦTY¬.¢Ôìîà•"þñcI”ò²)­§î&ôÑ?”-¯ý¿¾­¸Ýïbé§ï9zÞ¼×_ù/É4ºmãÚÏüWö:ÑåñÁoŠWþ´›X±³ÖâÑ£KMoQÓ Yïì-–Y’>ØÇ1 ¨ÎÀ­xwÄ¿ø._Â}?Áú&¯ðkàÇŸˆ>)½ñw…<8ºf«§Úé -5µó-5óîFøÞ0ÅP•l˜ Á>âÿø"Gì¿âæñmŸü,~ðΡy¯jÚv—cy¤¼^Õux ûûi.tùeye@p·4jĮ̀#ïþsðïLkûF~ÖQÝ%Ï„nìïV÷ë6Ÿ.€†;nŽå Y7«îÎFÖÃW&ÉήŠðnݯy¯šÑm£ïªX®{KØÛí¥{ö´·Í½^«¶;ãÏüOáΗàÚJøKà¾øðåol5Ÿx‡ámö«á êvæ"ñ]\Z\¤s’² G û˜œEq_³¯üûT·øÃñOáOíQ£Üßè‹ã-'ž ñ‡…<%Ž•wqy¤­ìv·~~¡4©4¸#ˆÒ!¹SÉú’çþ 9ðrûà—í‰ð"ûãí!{áoºËëÞ*¾’ïD7ú}ӈÛ'fÄ å.|ä˜õÁ¬þûû<é~:Ò<_ªüJøíâýßÄšw‹î<;©_i£NÔµ‹+!gis7‘cÿ»Œd"H‘—%™OkÔ-¥Úî´½âçnªÖ’Žºé}6rN [TçoÅBýéÓSÊ>,Át?fÿüñÏÅχ>1|DÖ¬<©x»JÒe°¶²]J+Kï°J­+ÎD{.HVà’¹eÜ+Øá§†ÛÁÚ7Ľâ7„üM=¯‡añ,‘XÁ>á=cW¶óìtÛ‹?Í,À­‘+æ¼dâ¾²ÿ‚þÍpé>5ðÆ¥ûGþ׺ÿ‚µk·Ñ.u-¶‹§ßßýºT·x´t™gù•¦–SŽpâ½WRÿ‚-þÎ:î¡¥]ø‡â¿í ¯YùÞÔ5ëKCKòüUªhÑ4Z~¡tRÁZ9cB-±†Ø»£<çjN“II[UKÊé[Êßöõ¬íÍlª9¥efýïM£o=_7m7ÖÈúöFÿ‚Œ|ý´­ü_«ü&øwûHh¾Ñíf¹oø—À·šn“©˜¦’¢³º`c»‘6ÊÄ[#w+Ánൿ±ÆŸ.³¦ëwƽÅQK£E¥è—^U¾ñÔîd¶²òLV$±8+xÖîrê ‚~¶ý•ÿc/~ɳµÏìÑàOˆüSà§›S–-G\»²]RÓí²<’å²µ·EØÒ1F(\q–8¯ÅŸðo³häÒ¿f_Ú›ö‚Ô¼E¨Ýif¼ž. \¤Ú ¥ô×»bØnn–wB­tí¼æÈÇ„œUh­\4½·ë{v诪ÝÛ¶øh©RnzO[.šmw»O]žËN¿rið[Ù_Ä6_.<+ðÃö±ñ¦£â›^ËEÓ4?ɨßÝ\i·Km|žE¼®àBí–“Q@Y]«%à¼ÿðN÷}^ÜxûÄé¨%Ä6ºM¬¶PE7ˆ¦’îK@+Î>ω¢{ö` ça i~ÇŸðK¯ü7×>|Oý >6ëZ—>\x‡Nð^•áM ÃZ.‘>…¨HMFÖÃI†?µmUÜm$}ç%˜—ðCŸÙâo†~-ø3eû@þÖÚ7¹¼f¿¼'¢ZëšP‹áÞ¾/ïíz|§§ÌŽßºÔ^ò ¤…EÉ5²„í=¼µÒëå{]®—ÑÛr]¥Í˦º_^v­u{j’m6ÒºåÅð^ŸØcÂÚ™âx,~<øÇÃSøR?\j…~ßo¦iøXÉ<ïØSÁòÌk¹Ü‚bYG5Ðkð\ØoÃ:‰5^üQð¯ˆt¯^øróÃú®– ’ZØ-ü÷¾`òVÕÒA™DŒ]cTi—IñÇþÇðƒöŒ“ÄÚ‡ÅÚƒö½ñˆõ¿[ü;ÖuA{áÄŸQ°Šýo…Á_ìcs™×'ÊD„)*±(Æ9{¿ø!ŸÀãÉ~/x{ö’ý®<#ñ¢?Ây¥ø®ÂûÃÆïD¿m:=>X¡†M­$‚Kx£ —LC.åe9Í(Ò²»×Þó_å}4äß­ßÈ(ÙÅóî¶ó÷:ïgÏuégÜô¿ Áeÿd¯|FÑ>øOAøã®O¨xŠÓÂÖúÄ>ŒéGQºÓÛP³ˆÏçÿËź³!àŒIåñ^áÿçýµ¯oŸÙþ÷ãì¿ |CðƒJ“ÅÞ‹¦Yj7V÷]ÙÚ^IwÃ#ÌæSŒ6à7.ø·üëá?¯>2Ý~Òµ†¯â›ŸˆšoÄˈ¯/<=,3ê¶v c lN‘æ˜|‡eaæo%·o>¬ýŠÿb¿þÂÿ µï„ß <{ñWƺ×oµËOÞZN43u3M%µ¹··‡1yŽÍ™|É2Ç2€3¡(òOÚ-zä·¾Ú¶åm-eÑÚøO;-UÖ¾^ÿÿiçvúbÑE‘¨QEQEQEQEQEQEQEVfµªG¡èú¦³5¦§¨Eio%ÃAen×RÛciã@É8´éÈ#8Í k}O“|ûk| ñî· hQj¾"ð}Æ­¨jºF•?‰4Ù4«}OPÓõÓ®¬à–}©4ëu±¬hK8ŒÈ£*íî|]øQ<)qÄÿ‡“@És"ºkVÅY-ÿ×°!ðD_Ƈ¾+äÍö;øEâo¯„ô¯‹_uí+Hñ‰¦º‘L‹íG]Mfî"Èò®ÈöaÍ#íyÁÿ‚fü ×<¢|;Óþ&üVÓ&ðÈŸN]KO°Ð¬çšG³…"û\)¥­– "Dµ•VæÞhÚ[xšE©Z©4êIGáµâ÷º¶—ü5[§ÒÊî¢KáwÖϦÏÓ·Nyé÷N¯ñÏྨøJ×~,ü8ѵ [HŸ_Ó#ºÖ­âþÐÓ!hV[È‹8 µÄ¸Ê99äV}Çíû>Zj7ÚE×ÇoƒvÚµ¬‰ ͬž(±Y­äp #¡—r–Éb¼â§ì;ðËâ7„~øwQñ×|¦ø:Çì¶RiÖ:Û΋wiwº{Yôù,ö‰lâ;#†8‚–Û·Ïü_û~Íÿ |âÿøÃâ§ŠüðêÊYüAªê3cZÙiÐôàÄ‘`#ŠÓKƒiA;v¿2K^žz«y­/Ót»ÙDÛ÷9Vûùhþýl¾~ZýçüSøa«Yßj:WÄêz}­„z¥Ìöúż‘ÛÙ:oK—er&R9ùHäW+ûFþÏZUÌöz§Çƒ:mÜV ªIÇŠ,cxì›îÜÒ‚"=œü§Ö¾yðgì…ð‡M_žð‡ÅO‰Pêþ#Ó[Gñ YÜØC.˜Ó¦ä¹H£´X>Ðe’) UmꈫñbÁ4luËÿŠV þ6Í®G kZ<~MAôÿ?ÃÚ¼-{qy5ÉKÎ6ú¹X“E°ÆY %‹„SM·gkÛ~¶ýS¿©2“Z¥uÿ?ÅÝo¦þGê_…?ioþ3Õ¼I¤h¼-,šišâ[Ø£·¾‰íÒq=´…¶ÜD#‘I’2Tg“]$?¾\xƒ[ðœ_~iº¤:þžu›u¸´Ôe‰fŽÑã/¸LñººÇÅX0kä½?öðW„|gámwGÖµ›¿[x¼kªÝjZšÅuòÅ"´q%­¼Qµ½ÃM+N’±L¨€`.Ö¡û0ü ø÷ãüZÒ~'x¯ÄQ_¬ºF©gasc6ža–+I%·­šEó97‡Þ©•]ƒE%v¯ß_M5üZõò±w²wÞÚzë£üÏÈú¿Qø¥ðËH“W‡VøàM.]>FŠýnu{xÍ“„”3,„ebi¡¬«¿ÿì-å÷Åï…öVx æÍ¯Ú"`ùx92cŸ6/ûøŸÞù§Ç¿²„|eñ;âÅ/êz‡….u+ßE¢K¡ê3Ìc¸±¹Áw-¼Ñµ²LÓ•FÄl8ÔHì0©ÏhÿðO…ž ñv‘ã{_‹_,ôm3P‡YMçûôÁv—V—/34ó:ï{(²eUVqå+Xu[Ú;_~¿Ö=<í¤Ôu³ÿ‚ôÓﺿ‘öV³ñWá‡/ï´¯üHð…ª[[%å͵î±o¶öîÁWWpUˆPÄ`’9®G^ý¤ÿg¯ ]ZØøƒãÂ]&ú{Û}:8&ñ ¨‘®g CÝù ùÏ\×Ïò~Οþ4x“â‹ Öôñ&˜°ýžÚÕc:Åd†'tevhÊHÙ°qOø&ïÂ$Ñõÿ]|cøØözÜ2Û\@÷0’k\«Sþ%ùÚ >|.Y˜’N2VšIÝwÛOM¥æb§+Iµè¿¯ëSíñ³àÈÔ¬tsñoáˆÕî¯[M¶µþß´ó®.Ôá Dó74€ðP ÃÒ²þ#|~øEð·O×®ü[ãÏ ÚßiË ¹Ó“P€Þ©•ÂD¾QpÀ»«»“Œ×κWìð³F×ÛÅxçâSëE­¡™Æ–KZÛ>Ïe“嬎¡²ƒó~j—Æ?³/Á _ê_µ?о,ð©ÕõöÖa^Ø´BúcJ#imävI(¥ 2® ]óK¥_Ãþùäí'm–Ÿ­ü—ãåÓéþ9ü±Õmü;­|RøyáïºBí£êå¤ð™@Ø I¼1ÎÇ'¦j”ÿ´GÀ+mbããgˆu©-ç»Kfñ v†rÉÿu…cÙˆšðoŽ¿±/Ãߌ÷þ8ñ/‰¾$|R𤺭¾.dÑF›Ù¢@bÌO%”’´“’XçÛŠò»¯ø'Â=wÃö1_|pøÕ¨Û]jŸÛQO¨Aáéþ×<®$U’ô£ËÀùd‰6ꦕ¢ï¾þ_ç×ÖÅÅ­y¿¯øÀû>oÚàœ:´ú1ø«ðéî`B÷lºõ™[´0ó¿{˜ò##š¿áŒÿ<]¬j¾Ó+Ÿ‰¿µoC¶’Ê µ½>ÒmäHãògû%¬hÆÅ*’nUs¹@l®Hèï¿—_ëR!4ù¯ºÿ/Ã_ÃSèÏükø;ñû0xâŸÃßIz³½œzv±o<—K ”•‘QË0FVV pA¬ê>i^Õ|cª|Røu¦øFÆàÚßj·Ý´vvsƒƒ“3„G¬A¯œü!ûü,øKâ[߉rxçâü·ÛW ªOfmàxR]’nŠÙV4‘ÆÃ÷‘šò¿bÝQøQ®Ÿ|WâCâßé~-}w[›N—ÊŠbM±‹OØÄ£¾|rƒ’:Ö2’×—ËñikÚ˛וwiiZÑmÃU­º7dßçʾ~Zý·eñ×àŽ¥uŽñ“áV¡zòÇCˆmÞG‘‰2Y¤Šä|/ûTþÏþ1ñ¿ÄŸ‡º'Å Iâo ÝÚXë1Ë{qÇ=Ä~dIŒÛ%8à„'k|§ŠðK¿ø'/Á;Ï \x.o|Eo \Ý\Ü_[y–í©<±Êñ3-¨`¢Hë) #v0›ëŸðJ߆Zô>-ƒVý¢?iwÓµ¡m© Íáô[‹("Çi¸i;ÕW;Õ„ÙçÌ®Šjž¼íÿMkÿ€ßM5ë§½5ä¼u}¾ë}úúYoÌù>óÐþ9|ñG‰.¼ᯋ?éëŠÝ·øÉðÂ}Aì޼%nLCm,š¥°ŽýåŒH‹ ó?xJœà ž£#šø_à÷ìUðÛUð'üK}ñ‹Ä^"ñµÖ›n³¤Ë¥´2Û:l’ Ø&åAÇ‚˜+’À¿ÏY–ðL?†úµÓÙø«RºÒ|%§¤šf“c¦­ëßéÏFít×–,!™™«Zˆž3€²œ k8¨´ž÷×Ó¿N½;k®Æ”§î½,¿;útèÞ—ŽýëáÏŽ¼aâ_žøµðßÅ%°±þÓ¾±Óµ»k™¬í<LjÍ"Æä¢ #‘KÈõütø%pÐ%¿Æ/…“¼¨dˆ'ˆmÈ£~XbN@òß‘ýÆô5ãþý‘ô Fñ‹®|Wø³ã˜uo ?„5 u/ì˜d¸µ/)Y³ic ”¨`6°U.®Û™¼ÛTÿ‚o~Îþ!Õ¼%â_KñXñn©ÿlC©Ç«}Š[‹¡.ôiVÙ#‚™Û÷.nçÌcWÓçI».¯~ý4òþ¶™¹r9EkÑ|º¿_'þWi~ ë€âçÃ` ÕÓIµ×í%ÅÛVßåþð‚O¼AW1á/Ú[à¯>/[h_t³ð.¥“â]Bk…ŠÂÆæ[h®UEË.hòUˆV%N_5ø¯þ ÙðO^ñ.‰ãoøÛÇýšó;[ÝÙèRÙË ’¤¯¬Úslùã–XÊL†5)"“Ñxö(ðƒ´ÏøzÛãOÅŸkúž±¤øš;ýB]Ýé2YZGeoåGŒq4F(J·¥‹9 6çFÎsÞÚ/>hõíËÌí¦º_Ozï÷þ¶ûÝ®úvw÷~žƒã/ ¸|Eskñ[áµÍ¾åÿkI»jË¥ù˜Ùçø‹vF7ã9âªY|uø#©ÃÎñá^¡nó=ºIˆm$W•c²$Áa+‘Ô+ès^¡þÂß ü7ð3[ýŸ´M{Æ–> ½Õ´Í`JO76’Y]Û]Cf×Ëdßk>b;à¶0ò?ÿÁ;> êíàŸ ê_¾2èÓÀÑÜØXÚ6…¿kQj<Öˆé…X ‚ Jªç0ãrâgñ%S·ËE}:õFª1pro[½<¾Î½/×{qi¾ ø,åÐ~-|2Ö㸎y­ÚÓ^µ˜O$‰™JÈwʰb8]§8Å%¿Æ¿ƒw–¿m²ø³ðÎöÓì²ß "×­]M¼oå¼ ‰1±\„-Ð1Á9¯Ï¯~Àþ ÇñLøkûAüR²ñæ“eq£K`Í£}ŠÊîãKž¯öc:ž·k3j"{{«)nîîš+l΃l¤-+[¬™’´tÓK•ïoǪïÒÊé>ê÷3JV»Zë§Ý¾šu»ÖÝ>ðÒÿj¯:œ_ndñö¢YøïH“[ð´úœ©g­‰TiHLMÇÌA$ ze§Å/†WúBx‚Çâ7/t1¾‹W·{v2B'ÛóDD‹Ï(w9¯¼9û2ü ø¹ð¿á‡¡|_×~3xWÀ~g‡¢Ô÷K¸]bëOÔífh¯$µ´XÖXot¸Cýa*ÑÈ¥sŒCðöeøâÙj×À^ø«xcLÕµ©¼K·àíJ;õÒfk¶•m,dÔ­æ­ LZÄ’Aµ =«µbyTeìõ’z/.mþå¿k£nHßWý[üú[mnö>Ä´ø£ðÏP²Öµ+ˆ¾¾Ó´Øc¸Ôn!ÕíÞ;œe$•ƒâ5`2 `Ò²$øáðj8u™‡Å†Ó >É5Кí«Û²ggȹB±À%—‘_6øö$økðoáwŽü üPø¹¥hZ–›§C}¨µÝ‚Kh¶'ÚR4´[T–E\LþOïFFï˜ø/ÂÏø&wÀx"ðOÅO…ÿ´/Ç+àlíï´MnÊ_´w1›M n],E06ú ’.ä+¶iÈ14U*qršŒ´KGkêïk««muÞÍy®z¼©¤ôô·_šM¤ítìö£_ >)x7ã‡Âþß]j~ñNg¯è×3ÛIo$öW1,±;G (êJ°t"½¼»àÂàOÁï†?ü;­x‡Äz…t+-ÊÿV0Û¸-¡X’I¼QBd* ·—.s…Šõ¬b¤«IQøní}í}/·O$*wå\Û…Q\å…Q@Q@q?¼%uã߇~:ðE—‰õ^kEÞ™±§¶Û-剣Œ:Ü9êvÕÊøçF¸ñ‚ü[áû[3Sº¾Ónm#¶½žH-îãe $‘"!'’9¬««ÂJ×ÑÿZ]ýÈß '‘’v³ZÿÃé÷Ÿ•:Oü¢óÅš…lj->>ü1¿ðìöZ•ªØøSú®—§éWO’XÇi®ù1 ê_='K0¥«§’ð«œ?~ÂßlüSðGÃòüAÑþ'x6ßPŠïT¿»Ó!ÒÃ^Ai¢A x`½„F]´¹§cgÖÉlÐyÊZÿ€eÚᔾøaáߌ"±Ñ£»ÖL‰å쨞Kìøouˆ!¶z¤ö[%ܰ=ĺ\³¤Ââd{³„ÿ°Ïí‘©]|5oüKÓüW6 ”3ê×_üF/ T}&[¯$ ­%İjDNÅeãm’2C訫Æ—º”|šZé§Xµï%-ô¼’׎X‰Ò‹œSriíÓïÚ÷miµÛ³dºüÆzo‚´‡¾ ý¤üâß[ZÉgqg©øyþÓ º6™§\‚ÒjÍŸ´«‰„‚E‘õÞ¬È^IüMÿ·ñ_޼ñÃÖÿ´OÃkëoÃ<uuàKR±6RÛ]$m$×MºËj÷möimÖ–ñà ¬Æ8æNÛÿ³ü=f±¿ñOǽ&ëYƒ]Ñã[»3YÓá¶+s ´ƒJ´’Í‹É" —,­©KGöß„?k¯‡úgN¹ãøžúë–Zv…a}â;ë«]7UŠÚ8ÄŸdVew'ìí1bX¹WÄ剫 žÒ-s=ztWWéºKó7rö‘´ž‹¦½ZW·þLúé}Î ö£ý‡´ï‹þ1Ô>.'ÆÏ ü*ÕÛìQ¦¡.›p¢÷ÉI¡m6úh5g¹Ó¦2æKUx˜¼hD¡•JÕÒÿ`¸-eÒ5+¯Žú]çƒí.-"ŽÂä›â‡JLW„Ò ŠiÍ3JíÛ+—!š^3À°×Ç¿…¾)ÑE¯ˆ>üWømáGÄRx;MÖ®%‚æÆ-bÖ&¸¼}ö“Ä.á¼ûqRD‹$œêL{?¡x_öoý¤ôO‚_|¡ø¯Ã7&ð‡…ô:î6HÓçÖì`‘o5ÖÊ×l0ȯo¶C¶Ð/”¨8Ò•âÒz+~;ÿà7wévì÷b•Ww¿}:ÿNËwÀè¾~ÀZÁ­#ãm…·ÆøÍ0é¾'Ô,þxCÂéà‹ ?í«]9uþÕŠR%†ÞHî • ’?’LÇûØO—º3Zö²ïíWwðOâ÷ïüVþßñ¯}i¨é3ËñYb5+™æ·7kl—p½±´„,BEýÜŸ'$ÉÅü5ý”ÿmÿøëÀ /Æ;+?„6z§öŽ£¤iž>»Ü’ý¾iò©s£È&¶6þM»Y,–èwI"˨g™Ñö•¯6´²¿GîÉ~Ïçfe<\ª%Κ½ß𳋶—ß’=Õ®\×`x^m"Ïáÿ‰¥žÒæöÎØI¥Z&–4Kdeä™Éi¢­áŠ$.$ºl°Ý©ißðLmdxGTðWŠ>)|&ñ¾‡{¡6$Z×€oµ!g´§Û-¾Ù¬ÊaIÁ-sYep¬ w«øÛàí‹â_ø£TÓþ!i:/…Ÿ[žKQcãÝVÞMWL{6KpÖëgåé²Û\°¬*Ü"bB7mg¬þÉŸ¶EýΨËñ‰µb ®î Éø¡¯Ø!ž[{Ø© 6­jÄ.!ÃF­Ç(®b–&jjªo™¤þ{¤ú]wÚíjìùz•ogue§ã¿£·Ý{­Z`é> ñ†ñk_ñƒ¼CðËLµ¸‡NÒïô±³5¤G¸š8¢e-:ìÞ\('vw_(ZÿÁ9|dÚî·â [ãׄ®u)uKM¹´ð<ÖóèóKt&2ÄÇStYBª¦õEÉ]ÅyÛF»ûþÑ>7ƒÅžø’š¡i%Äf¨ûo¶Ë,ñ±›J[“++# ~ÕžZ,*(fÉø‡û þÛþ3X<,†ï˜I¾ŠÞiZâO’‘Ç %MS«8ÅI4Þš|ÓüÛ}´ò<Ü?¾ÜZÞÿw4—ß®ìñgÿ‚y|bŸS³ººý¥> :Öø]Z[Ûü8»‰âA±í2mX‰y `€ôÓø¹ûj¾,‹áO€µx[JдOI£ÿÂms¥F%µ½ÞÅ ¬fù%¶†å“+¹w.r*_þÌÿ·%Ø´añÊJK$“Çÿ æ­j·dmœ4V„ªmøŒ‘œÕ}ö@ý§"ð–­áÍkÆö‚Hb³¶¶½ø®ê¶«dc¹–[«2L®òÆCÌB…9Jš›öêšùÚé?×½žªé£¿ÙòÇNÏåw×á飷Fø?Œ¿ðMÿOà k?…Þ%ðŠ/#6PÁ¦I¡˜l¯`f€N·j×ê·6¨#yc€°eiærI:žÿ‚YXÄú…–·ñ³Fø‹áV¾Pðjš>¥y0´_8¶žáõv³òâyG“þŠ4Q¼Ðn³ûþßøB×ádž>5éGÁ“βK-çÄýzÍÍ*éÐI‹Iqÿ\òÅ"nà6zŠf?Û¯TÐ_DðŸÆ}À2,®Ö“XøÛSÁ  3X†˜¸(|çD)òžI:©· Qºå¿^¿ð4ÓͲ=¤£WGæÚÚëU÷Ýïe¢ºêz'ÀØûþ߈|U§Ë¥h~oGá½*Ò+ kM6úûÉhäÔmí"äƒt[#xŒ£{!p¶kľ(~À_ô»O‡þøg7…u¯VÆçXµÓôÇÓ#‡ìédu:’“æºdË3F2¡fù÷çø ûUÿÂ¥øwàØ~([Gâí/^ºž÷T—Å÷·W2ém$j.e²2M0r÷Š1Ž$5'¾ ~ØÞ"ømðÃ@Òþ/èZ'ެtUµÕõ ;]Ô,â]EfV7J^)žñd„4L“Ÿ·˜ ¶1k¹ÝÊöqùÚò¿¢z[Í+Y`_*å‚qV+ò­5½ì“ù=Û×çýGþ |ŸÙX]üZø]áÛ¦I­¬nm¼ñ\YO=¼ 4Juûç{pç*UÆVHåRÀýñ?öXÕ<{㟆Z|Þ/Öü84Ï]è—þ"laM~èÆR×ËûÕ{vy¦ý×”‡Î ¸àã|eû!|rñÏÁßøÄþ6]kÄGìüUcu?Žõg»DŽÞte‹QòÕ³‰&Ü»C(PW€vטêÿ±÷íÍ­ê­¯|v·ñ-톨×zMëøîòÅV¢Á¥oµ‘]¡Y¸•'H²ê `ÏÔ•¤ôM?-U´ìÕÞš^ËÎÝuñ“pSz»=,®½ï¹ÞÉß§­\ð_ìi¯ü%ø•à¯GñóÀ:_‡¬¯?µµ- K"%Ť§Q i'Rû¢˜~ï?( /†éÿ°·þ-øƒâ‹¾"kžðþ?Š/üK¤ê7ºu¶ÿ‚R\x³Ãâ]OöŠð๷ŽÞÞðø"k‹s`³ÜN¶ª­ªº4 ÒÄ>ë-º€å)ô¯ÆØ6÷â‡Ä;¯ØxÿÀ^K¯ Ûxjö8|ßl‘âŠhÖê;´½FŒÃæ$–ÊQŒ,Œ÷€ýïÂÚ/Hø»û=_øÄþо ø{F·Ó¼K¦7ˆï„ºƒ¦Y[W†ã ör²É$rpù#£yÏÀ/ÛƒRµ³I>+èþÖÆ¦fºÔ¬|uª\%ØK«fBÖ[1{hî"{%/ M(twc¹5©7Ïtú½té{}÷vó}®Ö\4K^ÝþÕ¯÷Y_®š&ô}WÅoØ_[ø‘ñãÅö¿ãÒt;=:êÊãEž{ɧ[híÌÂê;ØÀaŠ4O– ¸º•›ñ³öUø…¨ü<ð/†|2¾ø£yi£è~Ô´ôØaŠX­uH.$¸û(–š9!óÖHVTÈTPQ󔿳Ïíãð×áÿ‡åñ/Äï|LÖOöfŸ¬®•ñ/Ä\]¼“i‹<±ìwB›“Qv‘ G*…Ú0±õIû/ÿÁD¬ºUçÇ=S³[ x#¾_‰ZÕ¥ÅÄñX^F’:&švq-«9I0ënY”±*ù¬$iÔѧï^û«Ç^ªö|ÎÝõÚÈï.œËk|¿'{ùZ÷‘¹«ÿÁ5‰áM@ý¤tÝ*ÏKº´¸W½ð…ÅÝÄ« …©ŒÊºœn£´™Xd‚—;H`™}ÿ‚ké·ZçÃy´ßÚKÅþ ŸÂ:ÔºšižÒì­ ŽôÛËYçí2ÚO#ÞšhÝC˜£2U\{oÀ½ö‚ðç|qªk×>$ñçnüHºUœ:Ö§{i.ƒd-äšîíÈ?nO·† ±ÁþŒb °L¿Èúwì/û\xãÅþ!øcñ+Mðï‹/£Óô÷¸“⎽pÚ½…¾Á Ùs*£"ÜšXÀV`LN´àÓ_k+¥¿~‰ù^×ÙåZ*ræ“Ö:.šk~Û]ïøéáÿØƾ øk |'Ðh /Äþ ³ñÖ¯ãí|Wà˜.’úë«ÉšÅ’ÂâÎ °­Ò˜œ&VhVL¶4Ùðì7Ã~øgâ‚´öñ3YOwwƒ™ šæ;¡5ÄóÛý´‰Þá›z0ÀbÏ€=ñ£öný¬¼A¤ü¹øiñIË4‰IòÍu¿qÚâ_ÓŸ‚_î>|ø_ð²ïZ´ñχtMB #gëA ÆeXL’ƒmÈC#ã8Üz×ʾül‡àÁK;_êöµFŸ&‘¢·ˆ4©oõkY²è/ä‹öw–Ù YŸÌœ Y„-‡m±¿™xÃövýºá°ñ„ÞøË¤êz³>¥o«xëV³‚õe‹VŽÒf–;9ÞÍ K­7tq¤Šïd\ã|šûW)J îÒo§»ÍÊý=æ½^¾êæ3X(s©éu~ÿi®m<ÚºòVV~ëýG†x.c[ÍÄD0$G½K\σü;gá_éú5•®š4³E$by¼¥Y€$f=^ƒ¥tÕÎÕ‡up¢Š) (¢Š(¢Š+'_´Ôïô=fÇEÕeÐõ‰­eŠÖõ#IÒb¤,d©ÁÃ9Vµr¾:Ö.ü?à¯kÖù·ÖZmÍÔ+æ÷:FÌ⎑ԣãû­ÐኜcNR•ì“Û—™­·4£½úŸ—ÚÇ…à¢>1øUªéü7aªxªIîí­-|3­i›Ö ô;ÅižáÖÌÂÉw$PÆb,Ø!›Ò.¾“áÿÛ[áÀŠü:ðŽõ‹WÞ2ûn“ks­hײ%ö-šïÿL¼0Zò£Ç&]ÝB†Þ|p~ß_´—Ä øOú?Ã4øc©êšÏ‡¬SX¶½“RÕþÁ)ÑôÆ•¬jS¢e$ˆ9™•0R?Pÿ‡€ü{¿Ñ.µ_~Íþž|+â1.µã COûMÄVšd©¦M"G[¥žúky•”k6!Œ‘AèÐÀT£)Ïw>Xëm¢ã?-Îý9–šÄRÄÊ›ü»N]mï©G[õZÙ.©o­ìØÁûøcÄÚ¶Ÿàßx‡HøUyww"]jZ,ú®–gñ’Ë5¿›=Â\±´hòDÑ|©Ì›`ô¯ˆw_·´«ðÓÂð_Ø´ž/ã«×C”Å«}¿ME_ôéÀQöGÔ„ "‰#\3a_/ø(ÇÄKÍà­cà%²ëI©Y@/tËÝBóN–ÎmGQ±y–w±‰KÄ4ñrñgp†ê»ßYžý¿>4˜d]sा!Ö¤Ñ,õfx¯%µÓ¥½û œ²é6ˆlþЗrÉ=Ï• >Mœ ÈŸuyª.T©Ë¥—þK§á¯©éÒ›r•['{·=oþ_Ó#½ñOü6 ÅÒ[øÅ†¿ ½¬M¼žHçu´‰ÉšMHogœN“Db…@d0º€Ku~ºÿ‚ˆxá_í)§|DÐ>!h(6ëuà™t¼/o«KSSV³¶/q%¢È,#ÒÛ}ÙU2ÜK‰bôö½øµ¬üÕ|ymð{áùñì^$Ðthtƒâ›Ñdmµ´ p÷?Ù¾j´"yw €©0`È™bžk¢ÿÁB¾"\êÚ•â?ZG†ŸSÕÒÂÉŽ¯}.ý×övMk!6‘^Æ×2ÈÖáß÷vá²7“˜J×±K™»jÖº$ü–½oÞ˱);_Eóóõù~/Us”ð_ðR?üFÐ|†Öo€²ý¾h®mí.žþÆâÖÌE–Ü´v÷ uzKÜ<)îe[WÛ)LLV%ÝûY.U“Û¿øzi«êîO±q“¤÷·Ýe¿dýäý|•Ž[Ç^1ÿ‚’øᶯãïÝx‘5»:;½N =;Ã/¤Ú0-ËEºoµPÓË-#f(ÃnG¡'¿à©^Š÷Àžñ§‹-õîôM[P_ ilÚXZò$º…D‹8THhŒrG» $q×ø+öªý¢|Gð¿Ç¿­äÑïÚÓâœv™i¨[M¦éϠɦióf¸m<ÌÁ'žáÂ0ÆT1³®ÖU¡uûzüqÔ¡Ó¼asð7ľ ‹K‘¥ºðe­Ä—z¾­/ötÒ½•ÜsiêmvÉå—IëÓíÅi³O}Ì(ÃÚKžM_®º$·ûGuikcØÿf¿þÖzçÄ-wßõý:ËBÓ4»»ÍMJé¦÷G¸[˨m!¸ˆÐ´Z{ÍÉ&Q¡‘}©Ãi>-ÿ‚€xÃÃvÚïƒum_Òf:¥¾“ªiñi¯£$7 YÝ\­ÂBRÚhŒ‚A.²EC±›6®ÿnŸÚ×âügû%êž,ðÆ¿~ll¼U¡^ÞÞéjžcB—rȶ`EÏ%šd’Ue¸”.Ý»oŽ?¶ÏþüXÕ¾ø[àþŸâ¿³­‚GQÔ/tû`óN‰ .¶RîÛ3‚ ¡ØA‘yÄUm¸Ti.mº'­ÿí¯OŠïUºÃË™Åu×tìž–½û«ë¯k'­Û{ÏÛYø1­>­ðÿijüV´ñ-ƒivÚ¼º ËXÖ/2rm.LK ‘dnHŸkp|ßàH¿à¦6ZÍëjø‹á˜5Y&Õ5I¥_ jj5olê)ö{@Ë9€ùO!™—œkøYûcxÿâo—àKÍXørù'fÔl¦I^é¬Ã"2Ï4k·p")ae*žKáø(çÇÏê:z_þ̾µð´––—7 °ñf¡ue\5ª­À/¥F­m\8–]à‡æ U©·V¯Ók?–¼­úúØÑÍ¥ÈÒßñ¾ßù5½>óJÿÃßðP‹ËíCû~Û⿊tócmmf°\xJßÊ”HL×D,©¶ãka “Ôå}ïHýôÏŽ­¥üIøQ©k—:‡„´ Z[@%»²:¥¯ˆ.,¿Òl.^Ú!’>6)ßsI’@Á9Ú‡íñÞM[Ôµ¯Ù÷_ð_öMÞ—xE•ü²nYÜ7É ¼“éÌ“Hþ\Û£@¬ªa&XšL.GÀÛâ§Ä‰º/ƒuO‡›´Í~ûíñM©½Õ‘Ðìš;}Öl°ÛssI'˜’:ãcæ@ •t¢çe½ýo®ÿ{í²ÖÊÏEÒƒ­-v}ûl—t¼þ&÷Õp áoø(ô~°øc¨[øÇ\ð/ü#óÙ¥ÓG 6©<«H¶÷W)naçÌò§$s€e9äõ:NŸÿ=ƒÁÚ-Ž‚šf¬éúE¥¬öÅÖ“åÏt¾Z ڭ̈39™ZF”6Ò3ê~.ý³þ+xWÆ>#ðlß³ÜÊúv³u¤¶©q¨ÜG¦Ü•ƒÏ¶1̶¬ ¸\Æ£Y°„A¦ü=ý´>)üAøŸà‡6ÿ<7 µõÛíM©ëWöòhŠÉ!Œ)ÓÌsÏò¢ìóÿxñœiÉÉr'w4ŸŸVŸÜúô³{ݩҼg²¿¦öiuÝtê­ÐÝøÙáßÚ?âì‘â^ø3Åš—Çy ÒæÝ kvI-ɸæ[KŸ´Û•X•X1—Ê-’H+’žÇã§Á¿‚z ׆5­GNø×«øÌ‰ô¿O§É?ˆmä“ÈI-£’$d„«£N#Úä猉?·¿‹<â_ˆv× u«¼/¨ÞXùwé–·^…™må $Y#•aãåAä/¿à¤¿ô›Yõ€þ ÔôAoömç‡üM{«‹ûƒnó0&=9aHÁQs6Ðç TŒŠs”¢¥§Åò|º|ÔWž¯ä«EÅ{ oÑùÙ­úï•ö:Ùõ?ø)—-œ×z>¹â`†K{ø4ˆ|7’ãÎ öÍu:¢ù#{‰q0°PWh¨¿kŒß¶§Âx·Ä^ðn£ÁÈôKxáÔ¥Ÿ@X¢Ôœ&J=ÅÂÉ ]KÜ#À01€A4m¿à¡_¬íQõƒšeö£y<ƒO¶€êpy` Â)›ì’íe¼˜ 3÷Gjøû[|Aø‹ã)ü7ñGჾXǦÚN×zõíüy8 ˆ‰%„*Ð8Y™—V_/½g*2‹Šk§éå×_¾ÞFÕ ù}¤•“ó·Tým¥½.ºÜùîßÄðQýcLÐ\*¶á¢y#[»y¼’å^Dw—2D‚}Kwíç¨üð†µpÙuo%ºÉ³÷ÏîÒR3¹kç¹?lÏÚ3áÏÆßŽCÄšoŒ¼oð¯KÔõ{M/tx’ÇP1ÜCQEqgd&€BŽÒ<“™–XÁ1ýÖa¹ñþ -ñR üDдŸ…Â/‡Ã×éúõ²ê7öšˆŽo-PM§#ÜndC0ˆßx Îfº2rŒeµf¯k­vü5ß~—±”àéÎTåöMôÛïë¦ÍÛgd{'¼5ûix³à®‰s׊t¯‹ÚwŠ~ݦÏjtt¼[Ao Qu±KœÈWç1òo˜gxsFý¹¾"üøÅ üm¶×´/‰oy§®Ž4KmO äÜ@ÓM§Í¡qæÄÊ®ËöÕ…ó”hÊœ?Œ_µ‡Çÿ†Ö_nôÝJÖL¾Ó>Ñ|'­|4× Ñ5uÕ/£Ô¤»[‡ÓL vÏv°ÈˆTü®RNAV‘Ž ÒµSM»hÚ¿f­ªÿÀt~½Z uŸ,gn©úß[zk·cÏSÿ‚–éÁ-Ö‹{âG´X7AhžŽMR×÷;Žd•/y›rîK|(ÚAÆî:ÓZÿ‚žß[ëwž!ð/Äa¢j6æÝô›vðjj:L>D`½¬¢ðÂ×&V~ùÞˆq†Ú[fãþ Sâd‡HŽ?ƒ¾Óµ;«»øÕuÏM¥BðŒѰim †…UR›˜¶ä`š×ü'ãvƒ¾ÊÿöqðqÕ™¬í‘£ñ6§%œ\@ÓG<Ó&’Æ+7*± †P|Ç °·Èxར• _™[o$´­ÉµçÅìúußðýÔÌ_…ß¶…tÙßÅzWŒ~!ü3Ôt_3ÅsêÚ–¨ÚÚÎ'g–mHM$Ú(K:ËhÇ.±hƦjËû]|Qý–| ¯-ø¨ê2Í«iÞ½ÒáûvÖWq" ¯¢·$v·‘Š˜¦R~FW›ëŸðQόޔMâ/Ù›ÃÚ­„š™Óc_ x“QÔ§…KÝ*ÜʲiP…E¶÷|ü¢TëOA{ûv|uzx?>i7G`Zæ SÔãV–KC+$ÙöæHDsÊVP㘳´€@ßN\Î_oM½é9=u²½þZ;Ý—Rö|®ò¤µþìTvÒýz뵺ťEÿÑo|=á *ý²¾6è–¾ ø[i?‰¯~Ò~ð¯í5Oøí5ÛýP>ƒP×´ûå¿»:¦©, k×Hó¶£2Ô#*îNÃÿ·Ÿí=­ßƒ5_‚¾¶ñ¦…-òø²]búM;Ya§K1k4M5>Ñ=½ÂÅÅ¿îÕ<Æ>b•݇í¡ñçÃOàߨ|/°øµâk»Ï±ÞjºÖ³.˜Ð|öåfe´ÒÌE'K‡kP‰Ú@ò CþISÑßæµÓO¹o·ÞiU^0«=,Ÿ­­Í¯Ë·çcgÃwðPÍcµ6‹ãÆÚ$­£]ÍðþïE“ÃPjhž¢‘ZÚ—žHͧǦ¸’ô,~uÃåÐH¼çÃpÁJüã­;º…þ Ið‚û[:”úž¥…õKí/ÍÕµÙÕ agöHì÷ºyó£Ý/’ŒHá÷[/Ûcâ4ÿ³eïÇÙ>¥íúkV–) iºÄ·‘ÚȈey#¹µÅ»3¤–ÑcNVÕ¼{Nÿ‚‰|HK¹|3kð³Âž"[{û¨Ç‰|ZúsÞÔ/m᎘L­ª¾Ñÿ*@ÿ8RÍ×VRÕÊ §~‰K¿Tõù§³"¥xß[«ß£ïË}»­=n•š?]£ß±<Ìy˜±ëO¯Éý;öîøÆuP?Â? Ü$W¶±^Ãqâ«…µ¶m•§{&M <ÄɽUfp ÚwG“ý;û6~Õ°|wÔ¼sa«hþð”ÖÜšN™mo­ý²òô"9i%„D¦ÌrrJȲœq^\*)mçøs/Ëñ>âŠ*Ê (¢€ (¢€ (¢€ k2¢³»@2I<N¦H¥ÑФ‚3Œâ“òþ*ð׋ü?aâÏ kÚOˆ|1ušÛP³e·¸Œ £©*ËyW‹xköµýšücâkxcã?µ¿Ý]­…µŒy–{†‚+…F>f0OÀ±Íý×Rzï…^ñgÃÏøsÂú—м;¯é–_£-´·7RÝ™£‘®d¢#ÈŒ…]аt Q¾Qø™û Š·ßÿá+ñ¿‚õx‹â-—cÓ/ü"×0Ú-¾‹o§-«î¼fn— 0Xöœ/–HYÔ”•œUõW]mÌ“ùòÞKÒÛèkIAÂ\îÎÎÞnÚ/KÙt>ÿ¼¼´Óín/¯î­¬l¢RòÍ3„HÔu,Ç€©«5ù¥áÏø'ö±§|ý¡~ø£â§„¾"kž8EUÖ5ï ßj6á’i¦‰¯¬nuI!»´æ0 6… Š(ݘ¢:ù޵ÿ¶Ô¼Qàï‰ñ'Æ?êZÞ·aâ;;M\øWRy´ùõ7åfÖ\ ˜c6x>β»V®ÉS‡5”´ïgå×îó1£ï5Ïîþ?‘úÏ­kzO‡të_\Ô-´½2,y“ÌÛQ2p2~¤U?xOÃ>0³³ÓüU é^!±·¼·Ô`†ò•"º‚E–€nÇ"««uVPF¾Søû%ƒ/ñRͼKáMKÞ%¶0-†Ÿáæ³[ûv¡:9ßq*H+Ø Q±p¶‰ƒ´ª'Ïcþ Íâ»ßhZ&¿ñ»Âwz…²Z‹BÃÁÓÙ=ÔÖóDÿi*5Ä×qEå_Ûnƒ–!”l§¤½×?¿õ_Šó5åIµëKþo§Gä~£=íœs=³Ý@.–31‹pß°p[o\g½r¾ ø‹àˆ_ðø›Lñé7ßÙš¢[¹/§ÝùQÍäJ¤åËí ²)î+óø%v‡uâ?ê·>8økq£Z>œ“éïà6o6ÒÖö;±k›ÿÝÅ#‰LˆÂDf6ß”‡oƒà—Sx,kú½ŸÅß j:»¼‡QÍǃ$Ýq,QÚ¤p]*߇¹µCj®±yŠË#0gì¦÷×OMŸÏ·Nædܤ¦¬•¬ûß}<¿õgûwI:œz:ÞÇ&¤ûñÛJ€X1 @e8$E7Yñ‰áäÓä×5[-).îá°¶3¸Q=Ì®8—=Y˜€rkòÃLÿ‚fkúL˧|lð^‘ºî-GQ‡Kð,–qx‚u·±„Åz¢ßh·u±UhÛæ1ÈɼpÕïÿÿbؾøþMã=Å­*Ý$‘É È—!$x^–y.äýÝ»Cˆ”¡Ú›Wqêþ_ðËñ·Cj‰/…ßú_ð~ï3îŠ+ò÷â‡ü§SñÞ¯âíÃ|3ðëÄZ­ûß cOðÅÊêv…¦W!n"Ôc<Æ&8Y\p SÎé¿ðM_ÀÖözÆo‡W~:2iW:Hð^§4/ûéf“d—zÜÓL’H¥y|½»U‚áT§­5)i.ßð}L§+6’¾¾Z®ûŸªº¦—§kzmþ«Ù[jZUÔMͼÈ9ãa†F‚$Qèº.“á½Jðö¦Ùèú¼vvV–шáµ*FŠ8UU8_øö&ñ¼9ñ£B±øÃ¦Êþ+ÒF™o»Ãm%¾TGËvòº*žJÌ‘`ª‡qoš_þ £ã éZÞ³ÿ 3Lø‰ã+ÈFŸº‡[Eº´÷âI®õ;„D·i£©I7uÚ€ãmÆÖm¿—w®½.í¯MB\Þï*½Ý½“¿¥ôv×M™û3E|!ñ»ö.Ô~.xSáw‡´o‹ú¯ÃKö† µ;5ešþGÃM S"Å ‘÷ÈÆòÔp|_Zÿ‚oxR:½¾ñƒÀF‹©o{ëà›©c¶c—äÚª'Ù­ö—>Qß˶E._y«õµü»ú~>F³I½/øm§ç÷¦^ðg„|g{§x7Âþð¥…Íܺ…Ì:uœvéqu!Ì“8@;Y'¹®–¿15ø'¶¿}w¥§ü-/Yèv>#þÓ†ÖËÂzŽŸ%柷ÛÝÍi¬D×Àra|´E ¦“è¿c?|KñÇŒ¼MuñCÁƒGÔ.­.líîü%,÷ñFŠD¶WbùVæÑŽ8„1˜Ü¹óÁÒ?Õ¶·ê¾^ewwÿWóùŸWx¦ëá/޵ë‚Þ2oø§Ä/§®ºþÔ9åk5”F·^Sƒò‰PàpÇÍwšf—¥h:m®•£éöZF“n›!·¶ˆG*;*¨ÀJü}¾ÿ‚XxîïÇ~.—öŽð–­o •¾™$z‡‚õ¶k‰uû/o-µ¨e¸dÙ¶"6*|¥–L~ÁøŸû4|AøÇ¤xKLñoÄ èÿØ—×+f,tË©Rk2‘¬7™u½o#(ÄK¹†[…êMMESN/Wºóþ¬¾÷rWį·õý}ÇÔºŽü#âk Sðö»g­iº™™ln-·IÁŒø`00TŽqÈ"º‰n ƒÊóçŠî#Mìö=g©ö¯Çíkþ Çâ«9ßÁž ñ˜Ñ¬5(înuÃbmmCŬÉqw<Ù"GG€þ0x¯WðgüïPðçˆü_ûxŸÆ6ñWŠõ/Œ>¸¶¾Õ¯o`†O Ì. ½Â(Xîf[à.eµeßk*¤^Q'åzòŸÁ1¼eá«ï Í«~ÑZO °Ô­o/g¾ðÅý¶£â/%RâúêÏW…®ohÛ9P€'æh¥+9éµúîµû¶óüG8¤Ý´ówÿ-~gë­Cöˆ<ókçÄnBy†=Ãp\ãv:ã=ëó[ã?ì³ñ«ã¯ÄÏ…Z—u?‡V/¦øzòßéº+È4ÝCí%à{(¦½[ÈSÜù¡”ºü»¸óÝþ Ÿã]Zÿ„‡þWÁí[T’åMßÚþLé¨Y}ªiÍ”¿ñ6ÞabQ•REøiQ´•妯ðvO¦ûúw&¢´¤–¶·ÏDôü½{£Zvðcâå΋ñCOÑ| ãËë`ö¶çÙ"¸–’Ѥ¥w¯“€p'­z½Í½ÜB{YṄôxÜ2ŸÄWóÇì•âÙ–òaà/|2¾Òµ}En|JƒÃ3ØÉz™¼ÈRñÕ®c]òò©ÎxLJZÿÁ3.´¸uÛ|hÓ¼#¥Íí„z'…¾Âl G›O!nŠ=¥Ç–MÄ{WÍi†Ìf•íôÓ_'¥ÿWòî5gÌå½ì¼Ö½|´Ðý:Ó|Yá½c]ñ†tÍfÊ÷_ÒÔ­³%‘–1$aÇmÈCc] |qðkövø•ð?P¿ø‡àÃúž£n÷Öw:ÌM±KvC› ·l1‡HÁS¸á«å;ßø&g§¸Ó"¶ý¥ôÆÐmãÔáû÷ƒ¥žW†ñ®K@n#Ôc–X×ÏŒ?Θiœ­Ó÷vþ¿¯ÄSÒ-¯->ZýÌýs®_Â>5ðŸt©µ¿ëúo‰4˜î§±’âÖMè—Èc–#èÈêTŽÄügø“ÿ½ñý׌| má|?¿øuw¨Öü5ôúëj¶>k |7uš[Cºÿj¯(³˜4±ÄÙåR>vÝ„UâšvmKð³WÿMµVvm~íÚ¾š_ç½·Û¿Ü~µh¾1ðω-´íXµÕìuKCa=¾^+¨ß\ ¸ù—¿9®–¿%t/ø&¿ÄiÚ†—á?ÚÀ6zK‹+I¼ø{qq¥J«›ñ\[ YDñÎÖWº†Bd¼ÜY¶7›ô÷Ä¿ÙÃâÅx{Àºü-àý?Þ'Òµ¯Üèš<¬íik‡·ž ›‡‚C$2üáÑcd*dI“Zð¦¯Èïÿ麿ÎÏÉÂí¤úþßç§[yŸfWx¡~x;ÅןüO£øKKñÒ[ÀVm05ì¨ÂTUÕ ÈÁRPrÁ¸ _˜¾ÿ‚gxïQð—u kâ£|(ñ ØÈº®‘§i÷Q>üÙÚÛ®£m%–ª±‹õkff¸—ÎIÅZù·û]ßüëW×4{;xóà»N,mâžßMøo%¶š/Q5ekØm¤ÔäòdvÔÕÉÞÄ ‰‹+E¾©íÝwOÒÿ‡º!Ìâ妺úm÷þÊÿ¥ðÍÌ1O ‰!u ­ýàzóχÞøWàµÔ4o†>ð‡…m¶Ç,ñhöÛBÊwlÁB0ØÏ¾ ñ'ì ñ3_ML'ÇŸ‡1_IâXuØu[‡³Í©¼‰Þ;IîUC(‚iÿÑf(aa/2W+iÿÆÕ4½&O h¿<1á¿Cá«]#Fðtº}®š;´MJPÛ¡Ú"x®/–ð»>bùWʹ·ÓþúùŠRµšü­×]þîºúŸ­WÆŸÿf¯~ÏZ£Eá?|;ÕüÎÖ¼x¸<ÿ):6£©Ü|Iñ„>.axöê}6ݷܽ¢JÆÀLêZ¬¸l‘í'$¾ ü8ÿ‚¤I­ø2è|QÕæÑäÿ‘’ÆãSТ·IšûNYþÊ`°i¤ðo˜Ê$¸Œ>_*×Ã? ~Ü^–OhÞ/ñs¶©âÏé·>ñn—©kÛtäÔ/g²¼YgÔQl÷Â-¡ŒÆK¿½FuVSþÒ?¶÷ Ò,¼á¨üXšs<–‡F¾–ÿK°’M$5ÝΓ¢QÊO-ôJq¼¤ã‘“q™áªÝûEûu¥Õ~+­ïîý«= VØÎtouû×½Ô[WOÍì·–êè–ÛáOü–ÿÅ~¶×¼Q¨¿Â» ]=n¬O‰¬¦¿¿¸ŠÒÞ)<Ù n"yMürä¶ÐY¤Þ©Û|3ÿ‚’Ë£x'J±ø‡yà«{$²‡X‡E›AU¹Ž9-ˆKA-“¬ˆRæ) K2ȧ°ü>ø±û[jšï‚5߉¾ñ…ô8µBÏÄz ƒ¡%"ŽÞóÈxîúàÍ¥läVŒ ¬í;e–?Ðämèµ— 0ÁZÒWƒ¾Žîýõþ¶ég¦–9åKÞjïk}×Z}ûõgÄž&¸ý­¼_ð÷Á–š—ªøÅš]òéþ(uŸNk¿/öj{a#‚8…äƒp•™ ”*|ÈO)ÿgí½¦~ÎãO‹ÇºŸŠÿhKz9o.ïo4¨-¬ì„ÃzÛ,ÑLKë&kô"Šæ«ïJRÛšÛtÙéÚöüZØÞR¼c¹àïÝëײì~L¶•ûzhš·lµŸ‰ÿ†¿¬ë¶°Im6Ÿ§^é°Ú¹œ^šÃNo²¬²KãK¡s¸«zÇí àÛGÅž.ñÂïÞi_M òVßW´µ{Ôû<€À ·ó¡œÏå6ÿ0ÆÈe~ãþ‡QD-ŸÖý?«²¥+»ÿ]ÏÖësñçÂ??࢞oøE|?âÛýá„sµÎµþˆÚœòIy+Æí%£ÃöPÏl0åáˆÎ0ÞÍñ;á¯íÃuðûà^‘ðÛã/Ä;/ÚÃ/5 gðè½½­È·OŸOkvU›œD‘ü¿{wJý ¢¶•kÔökø}ß®â¥.Vš[}Ç䮡à/ø)­{¬þ%ÔaÑí|·†_øH¬ žòXç™Ñ¤6ÐF”0«¦0 ÏcRûáü7Xѵ µo‰>-Öu!`&ƒFÔgð´š\šŸÚâ,3ý˜Ó, Èbfwq¼n€ÛúëED*5.b*.hJ­ýUú.Öé׿~fxÀÿµF¬üFø—ñwK|WoámrÏEÖ´ù¬¯/­Qßζ¶EH‰”«.Fc`[nSµyï„<%ÿ!Õ¼3¡jÖ¼G-†¡g ý„šÜ2ê:tŒ¨dŠú´‰$V¶$e$FùY“ï/ë­+ky[óüu:=¾–i=o•¾ï#ò>‡?ðSÿ³Êxñìµ+»x ýݾµ`ÐÁy³*0‚êÞu†—d{sò™1ǧx_á§ím |;ñmÞ™·ÃßõZj:ÁMJÂ{Ëë/!’äÚÉä­¼ndØÑù«€†9àþ‘QD¤ßÝoÅ?ÑE¥%+lïø5ú³ó÷Oð7íµeð_âןñGQÖ>9ÜÝ!ðßÛáÒÛL¶…6жÑÀê®ÒHΤ–PÀÛüKð‹þ ãX_ëÚáðØÑ£I4‹½#ZÒ®¦MEƒƒ:ý¦ÃˆdY€vTùW'Ÿ×:(‡»%.ßð?Ëï2«(òíÿ§¡ù-®|.ÿ‚‡ÍáíNÅþ#ø³Åº½Ì °ßÉá–Ó²8lEöÅCʆϲ ¬Ý;àçüÃ+g‡üaãHVᣇUøºÊí¢O>Vylâ»íáàÅ„ØcRª8߯tV”êòô2xeÍ{¿½Ÿ’Ú¯ì×ûR|BøWñÓGø›uñG]³Ð¢]LkF;û‹+øfy-ü»EXAŠ3åùÑÿ¬À!‘럳–ûRi¿5ï üNø«ã_ü?Ó4h'˜júL6ÒÁ Ûª\Aaµâ¬*²É,8Jé… ¿Ch®xÂÛ¾ñ¾¶Úúöô;fàán­ú_—ô¾lülо~ßžŸÅz·‚5Ýa5­TDš¬·ºþ›u&¥åEi¸ŽY y<ý‰rÊÁ9Œ63¹>‚ñ¯À?‰~+ñ½sâ¿‚ìi/C੼?«hšÍõŠÏa¬I!'R*"†ÖC$l"’HU$ŒD hûŽ?Dh­ÝKÚëoòkõ;vDÖ¨ç''¥ûz§÷è•÷µ×V~YÚü5ÿ‚‚A¦øzÒOˆúÆŠlV%»¶Ð¦ÑVÖîâ-ÃlêÚIÉ×ÊÖ`VNT¯6ñ¯ìÅûføÿᇉ|âø¿ÄÒ˥˦Zi¾"Ôô+ý5®%Óïà’ïÏ’ÊKäËÏÌ$.«ŠäoÙZ+Nûÿ]?¯½t.Ž"P©í#Þþ_%Ðü‰³ø?ÿÐ<5ô?ëz—…'ÒžÊÞ[ÝwKµÔ4,õöy¶¶k½¼é, MR³îVóz[/†ŸðQ=RïAµ¼ø¹â/éqjX¿6·-鸵_· ´Ö­ ]¯`³®DŒÐ¹ŽO½$¿ª4VÕgÏGÚ×ëóîüþ{Š5¹RI-<¿¯ømÊ{‡µ„phVk_YxYG†Ž—kh¿mÑ5ˆnàmRwš7f™&·[ÐÒÈÉóJBËp³"EWãÁŸÛ{Äõˆ_õ6ÐlmôíCE·ÖtíWNI¦\\[<)counÑ¥ÌaœÝoŒ²¥Ãí¬TSG)ªW3ÓûÊÏðº^Z;œÜžç³éîù¿vÖÕôºMß­Þìü†ñî•ûsø×ÄŸÁN,õ^CñâÞKˆoõM!%Öôé쎥%¤ê–·Bk9^Ey-Lkj¹Y­df>S•›îŸÙ_Á>5ðà KGñöˆú½sâŸë"ÞKø¯$^j—7Q$„ó L»‚äÈÜßxý#Ejª¾NKv^zÛó¿çþl(¢ŠÈaEPEPEPT5]NÛFÓ5 ^ô]5¬/q(‚žBФ±Æ »`pª '€ «õŸ«YO©izŽŸkªêÌð<1ÞÚÌöŒÊ@•¨ñ–Rr7£.@Ê‘ÅLÛ³±PµÕÎá_Å |aðµÏŠü'ˆ-mmõÝ"òÓTÓ¥²»³¼¶™¡š'ŠP!”á†U”«) ƒ^ áïÛ«à‰õKEÒï|bšÝ¨ŸÌ²ºÑf¶™Œ:Üš$ÁVP»¼»ØÊ;}ÕFŠR|¹#võ¿ƒ?/þøsEðË|^ø™ñ*ÊΕ’_[é 6¡<Ò$u3XXÛn›rÈÅ€]ís3È$r¬žPß°ÇÀñ“Wø÷k¥xŽÇâ}æ±{­I}¢Û[*=:H–&?#dI8„‚Ÿi~ óU$Ó]tÖÝ]º_dÞºÞËM[æI4âú;é~‘¾·¶îÚ_Mu·Ù}®ûZþÏ&ñ¾ðçHø­àËŸÞ‰bK5Ô c äqÙHÖÊåVïËÔmA’ì’î€MzT¿~Á®]øb‰ÿ!ñ,1Yϧ>µl.a¸1Ž&Œ¾õw ÅTŒ§à×Êz?ìà ûÃ7Ö¿~4ʺLºdÖ±MýŒÊ>Æú3€HÓÁćCµß‚?×\lòó•…®þÆß³¯Æß‰:Ç->(Ïâ[øŠ}{S³µƒÃš¤0I,vp wIôùš“iKÀ­ÚMnág c¦´iÿË·ÓñÓðø¾äTTlœžÿ†þ—éó¿Cëh~;ü¹¼N·øËð¦}AìåÔñ›HÖ±îó' $Év¶çû£iÉàÕ]oö„øáËïéšçÆ_†n©«Ïco¥ÚÉ®[yÚ„—r,v¢$¹Ä®ê€Cn5ùݨÁ1~^jmà?üVñ}§ÖÚÉ| “jeö«iª[ZG™c¿ÓåŠD‚-FA ±Û$Q0×iúW°ç„ü ©-ç…~0|`ÐôäÖ´Í~2Ú ;K[»e·IDH4ÜÅÔv±G,(V%PL nøp”!í¿»u¯[_^ö²¿}VÚé•YY>]ìþþvÚïÍ®‰ËèãÁŸëZ‡4Š¿µ_ZjóhØÃ«ÀÓ¦¥qÉ%¦ÍÛŒ¨²ÆY$o©µoŒ?ü;}¨[ë¿þhz”1Ø]Gw®ZÃ,7 ¥Ò à«• ÁO$d_?꟱'€5߈7ž=×¼}ñ;\ŽoÛøt{—ÓþÅk4VwpEKEœF—I(-+93J¥Êùk!âÿø'¿€|iãøóVøÃñ¸j:ܳË-²¡³Z\Z쉤ÓZ`ª—R•#áˆê2§(¨ÚÏuïy=4]ﯧžïhÆ.÷v×OMu×ç§×«ñ_ákéÚ®°Ÿ¼úMгÞÝ fÜÃf«#DL¿j":Ä|ÈËÔUWã/Âl¿¾2ÜJ°[‘®ÚþþRΡçù˜˜ärŒ;ño‡²ç†´Ÿ üwð÷ôûK»ˆ­ÝÖ«ak¨Ïqkmjñˆ’(<ÕQàwXÑMq)‰.ÞC¤ÿÁ2goøu¼-á½Oân™¥Mk¨Ø_ùú²_¾¡kzðÍu5ÜRìó.!ûAhö0šYœæ8.*6÷žºÁûºwòØÎ{û¾ð>÷¿nì÷mcöÂýôM#Çž"ºø—áË øv [‹ÝFÚî)ín<ó(D‚Tb³É˜d–×qñçàÚZIugñ;À:ÉYVž·i,ža,6ãÌëò?~Fô5òï‹?àžŸüOi§Ckñ‡ã„î­t«m;1´`ßfŠÞæ réÏçK™76Ϊ¥vüÁ Ô¿àšŸ³¥íÇÅ«û¿‰«ãKci¬Ïk«#¨Îó‡“ Ñ<•vœ©Xò¿k¹Æ<ÃZB4š\ͯé~þVêÖ%ò«ÓÕöÛ§~÷¿“Þëcé/ þÒlJ…à ¢t¹Ìk™ˆÜÐu¿ØƒÁz÷ˆ5/j?¾+]ÊÚÅZËý”ðhbîßȺµ‡6>dÊ…².^wBÄ£&9Uì¯Û_]?=_[Y;»óyÛÓ[í©í»Ý=òÛãçÀ«ÛÛý6ÏãOÂk½JÖW†êÞ/Ù´–Ò*–dueX*± ò“Ú ƒãÿÁ[¦Õå·ø§ðò}*Á _j)®Ú5¥›‡ åÉ “ûˆlWÄžÿ‚}[ØYü:°ñÕÊhºâOÖڼɥéó4°ÙÛ›{X^a7Ê“­Ã¸+¸e×ä:_¿`)¼Iá/i þ&ø³HÕloÖWûdÚ}ªMnÚ‰¾•|È´Ù%ئ6ÑåI |ÊÖ ;6íêÿæºwfœ«U}¿ÿËñØúƒJý­?fÝVX-GÆŸ‡v£.¦txm/5‹xn%ºÚ]Qc/¸î@]N0Ëó9¯føF? Éâ¯GàñÚN¬×Ñ 1üôó·lÛïœWÁšüwᆢk×?¾#¦·kæ»Ãi‘‰3,k4K°'Éa¨RĪýÒö-öQ¶Ò¾…?¾*kž ³áñ|ös^èÛÈòy©pð>âÀlœHЍª¡EŠåvzéùkøíåøóÑsnòÑYúÞú/»{ÚÖ{èpÓ~/|&ÖN¸ºGŇz«ivéy© mnÚ_ìèee›kŸ-ä3`Zʾø÷ð/L²›RÔ¾4|&Óôøíã»’yüGgqÀç )f“‚t8â¼;ß±Ã? |%ø‡ðƒÃž+øƒ£hþ"¹²_Û5„wšmÀ”Íæ@E¯–xÌØ™%ã⼿ư”[JÕ¼ã¯Üøž?ÿoÍu«6Ÿ‘<êöê!žÉæÊ '%Q3Q'­£ýO~ËU{´¶ŽÍ¿éÃlµÖëK^_aÝüxø!a§Vóã»]4Ê!Yäñ šÆÒ@ÆL!9äz×9âOÚoào„4k kÄÿü%¢ÅqN ›R·óâ·fÛö‡A!+êdû I¯ðì+àÝ#ź߈OÁ©¥]éP麈ºI’É_l³ÅuA²´ŒdûVÙ7Êñºÿt-x$?ðN½Z WñÕÅíí·ŠâÎî[›5’ßDq ‘B¦˜#ûKÁ ­ÇÊV³³½½?O×ð×[ktRjõ·û®í×{~:uÓîMöøC¬ÉâÞ-Ó4=?K’hï/µ;˜m-“Ë—Ë,G·Ýqò0<RkŸ´—ÀmöËHºø»ðâã_ºi’ÓNƒ\´k›·ˆ#H¨ž`Ë"ÈŒGPâ¾qÿ‡y|:³þǓßþ6øRëM¾þÐÓ¥³“Hsi)•ä#lÚ{¬ˆCº”:ílãp )\ÿÁ:>Þê^'Õ/>5üzºŸV–I.ƒ¾‡€Ž±)HÓ7mÆâHä—»®ÿð>þ½¼Ê\¼Ö{Wþºþ_\KñÃàÅ¿”.þ-ü2²‘î×O 6¿hö³·ø2­ù—äûß0ã‘[oñ7á¼z?ü$R|AðDzÛ?³þÜÚ´ßí[¶ùfý¾fàFÌîϯŽôOø'oÂ?éÚ™¦øçâœQiV ¥XHÒéÒI šº:DÅìÛÌ*Éì üÄ#hZ‡ì ðÒ÷àUçìùkñã‡à¹õ™µ¦–ÒòŦ¤·&´’Þ|ÈXCJŠUv…´¼—Ýç¯]í¦½wµÝ®âÊË]áÿ[tû{ñí#ð'þ×¼Wqñcáþ£¤é·qØ^bÚáá»rÛ•G'Í9'Þ# ®šÿãÂ]#R&µñ7áþ‡¯yvò¶Ÿ}¬ÛAuÍ(´Ná×y .G'šùþáðîÑ®´ß‹¿ôZÊÎM=/ þÅß5´›<ØÝN16ÿ-2Û7.ߦN{oб/ÿ‹ä^"Ö¼_ãK I5 ò©c£]Á ¶µû7’ÑÞXL¬’& 1b°ÌOH1×îýoú?½yµVº;~7ÛîëÜ÷)þ:|!ƒV“H< qq¸ûkǬڔÓL[7‰ÿy˜ÏνG~qÆpl¿j_Ù£PžþÚÏö„ø)=Í­ÕÅ•Äð”YŠxlÑdÎänv=kâ†ðM{+- ÅZGÅ/1[ë©ÜG Á§²Ë-ºF7˧¬¬)m Á³4~Y˜ªö»Ø#À—F¹£7ÅÏÂÚöѬÖV¸Ò¥¸³F¹ŠâB“K`Ò¹‘¢Ãy­ Úî&åø~6ÿ=?#Y¨iÊÞÿ…÷ë~ÿ/=>€Ó¿hϺƣâ ?Gø«à Ut†š=fæ fÙ Ò$ŒFZ9ßÌÄm‰S¯÷†qÅi§ÇÒÜj–‘üføQ%ÝŠE-ìKâ+2öi'ú¶y™@ÿÂ[íšùÁ_ðMÿ†~Ñü7¢ø{âïÇo¤Ln´ãq&Žæ ƒ%¬!Û§®íÍj¤©ù{ |›04Oø%À/ é°éŒ¾,éZlEÞà›LI-d0ÚÂ$Še²Äê¶‘mdKŽTí®˜BžŠRéÛ¯ü{ÚËWwnG*œÛ[þþ? ó»zr¥/½¼_ñÁ>ƒK½ñ‡‰t?iw~aKÛëØmíãDŒÈÎÏ#¨ d‘œw㚎Š n4Ä6ÿü>©Ã-Λ|šÅ»[êÆ»¤’)í‘Uyb¤€95óÇÅÏØ÷HøóàÝ?Á_þ-|JÖ쬵]RúÊâÒßK‚hín¡šÝlŸu£¬‰ 3W*$bŠÒ3œæ®¹û#è÷>øWðöÇR¼Õ|#£xÊçÆWz•íè´Ô¢™ä–_"²‚(ž)y#u|HNᜒKGwu÷i{ú~Få>v­¢O[îÖÖVëÝ÷Õ#è5øÏðyÜÆŸ>¼‚á­JvÔŸ=Z$hþÿß <*W¨3F:²ç¦ð·Œ¼!ã/ûsÁ>*ðߌt_5áûf•}Üb¬›ãb»”‚ÎA×ÅðO?†ZFŸá{üKø½á³¤Ac§ZOk&—$­¦Z´-‹ùöR+ 6ñæR<ò\`­~ü4Ñþ|5ð_Âÿê:®¯£hz|:uµÕúÛ­ÄñÆ¡CIöx¢‹q‘¨ö¥¦¿‡ŸŸ[z]ë×K½ä•´þ‘èÔQEI!EPEPEPEPEP$VxäEs@oîŸZüÖ¹ý‘h»ûÍæëãËÙI ó}®};[ÖíÞæU¿³¸‡S×/ÎðZËm-°Q[©1]ðÉúY^ â|~¼ý¢>øÛÃÿü;£~ÎV^Ô¬¼Eà‰<;·šÖ«#Äm/Rü¶øYAŒ ­æäí(’÷Óõ×¶óÙvm=-Ì©JÉ¿ë{Á~Iú?‚´ØãE”~ƒ^øËªëbÎ-:ÒîìxëıêS[E&ƒ-ÌK{öƒq¶åô«²ê_íÄ6ñæoÚÖÿaoŽwÞ-‡ÇZÇmCÞ(¶Y^)Gˆõ¹¡Ô#Iu†µ±»‹ÏUžþÒ·c#n‘MŠ(Ñê\x·öáñ/ü,Éþø“Oñ—†l9k>2ÓïÊÿd^øÏÄ kei!Ôž;“ϪÄ×–ª&DŽR–1ýѵšÑo¿à§ºžµâ+]·ñ'‡tH/íl4ÛÈto ¼—šaÕ FÔí x¶‰tòÁöAY¡hˆ‘ݰtíþ !©ø‡Ã¿¼W®x¿Àº½—öžw-Í—‡ Ó`³kû^ha½»[y\Í ê"»ÂIdÆËÚJ »«k}»ÿNýüÓΖ.Œ^š>»¥u¿m›J÷j-~ÂÑ_›:oŒm½[öGÐ|]áë#ãßŽšŽ¢¢Þ] ô ºdoäǨ(¾дwi»1ä'x‹â†üsã-:ëB½bÒÂÃÆ8RV ®×23[³\lO.f.ê­4gÊ9_£¾+Çûm[|\½¿øeÿ ”¿ u +MD‡@’-"í-ï ‚îJYîÌLdgO%\ÄÁÆMt¿Ï×K¯/Ç}¤S6Gn¾M&»ß˪Ôý ¢¿;þ5x‡öó±ñTWŸê:ž›w¡Ã+jv_ØO¦iš±ºóce¼ºŠñºû(R±ÈÉ9…güGñ¯í#{âO„ú€íÒßâÒxBÚãÆšU„º}õÞˆe¸·ÓT¬õþµû×ßó?Bè¯ÆûÿÁXå¹—T‡À>%µKfñéš›x@Ũ#L›çi-ï †HLž^6ê»ã#9ô]{ß·‰ðOáÌ߬~$Y|CƒÅw—š¾¯_øy®ïl$9Oµ2Hö»Xì¶‘[pN1‘ZN<©=ïoÅ¥úÝù&Rw|½nÿ}üö^gê]ùñ¯ÁŸ¶w~ èN•©|QƒÅO¨j]Ûè·:…ýÕƒª}–KÖ‘ü…xØ3±È™!r¬¤©Óø?'íÿ§|@Óü9ãè5 ‡:nƒ4VÚ†§¦hRm݈q^Og~³A0”d, ÇÍrb7æ”_ÙWõÑ»/=—«ò)ZÑÍ–¶³õßµµôý&¢¿$gÔà§z¦à©SGñŸÚßY·ñ,cð…þ˜²Dëa%®/®àuŠ`™ŸsDÑ“pê1ã¸ÿ‚§MvÑÅã:K˜""M3ÂM{l±ó>Ðoʼ’8U•~ÏRI±÷u…;»7`¬¹)ûMü–¯îþ¿öŠü­Õ¼'ûpk?³„´ŸKñ¾ÿâäºö£ý»•¨ø^ fµ–Þ_#.Ò$BÎ9 ±H·9ÛÀ1¯>Šø* ¶Pø*O |VÒt{'’Ò-vÒóÁwkÕ¹†f2\“<+2·îöܪ7ÍU WI¶–«ñIþ³ó¹åÌí·ü;_¥ý?dè¯Ïïz¯í¹§øó\¸øQ x—^øtšu¬–pX+ÓsöwÅ‹Ù6JL¥¹’]¥B¸ù›ÄÈu.æ{‘s[ψ¿•qü®ñ†ñψÿo/‡z>$xïÀ†ÓNÒÞèiWßh¯äÁ;iê‘°$ ³]'!š3嬲,JDUVÑɽ¯ø;iÞÿfۚ›“Iu·^ýû[©ûE~!èþ3ÿ‚¯x†ÒÂóÃë^&𾣜"ÖãÒ|-hÐD[J73¤2Ý’ÎDš°RCLj"*¬Jùž‹»ÿEŽóLÒ‡üZömk%Äš¡Ó|';}¯ì1³J¿ÚùPùí(I#IŸz ÿ»Ã?M|#‚RæNýž¿5ºþ–åB4y¢Õ½mùÛúÕè~»Ñ_Ÿ´¯Û;ûWâ»|D›âF»§Éà«Ë?A||2–sêÂ{¶‰™mH%xÞÙb!ÚŸ>ÖËxJçöì²ðOÄx5? Á¹Zü#±É.” &áQŠ8ãiÏ¿˜Ñ¼Ó4Næ0Qe®H»»y'÷¶­ê­wÙ5ÝÊ6iwmzhµôÖß&~ˆÑ_ž:W†lO|=øçcñUñm¶¯&•·„­-WE·yä£ý¤¼•ºÞd’D·ÜPPYÿ‚¢h7ÚׇüKãYÛ§Ø%³Ó|- î©`ú‚®dš]I#M^+Ef(-–ÁË©:ù~7ÿ/ÅyÚ|ÿ®Ÿçø3õÒŠüÄ2ÁD¯êÒy|A¥)ºž¸¶³ðãH–‚qöI ß#'œÖå¾Ô²+¢ÎÈýÞsÄC¬ÿÁQßÅ-¤&™®ÙxM,$¸µÕ/4 ÝËqvö,^ ¡­’‘]KÙÞ¥.¶Ó$ãæ©®dÝíe}­É©5r¿ó_×ü>ÚŸ®TWç׋‡í™©xGöÕ´¯ jº'ħðôvÞ3}:÷D¾mö]GH"9.¼ˆ¦?e‹†H6üŠFþa©ÝÿÁMl< ­_ÚéWÚ爤ðÎw§[ZËá´Ô-õ¹¢Hï­%ŠR¶´–¦q"ÜŸ5uFpmÕÍΕ“m­¿iåÖýŽˆÑ¼y®¾óõRŠüb>ý¾4ÍsâqÒþøþÓÂ>"¼Ôžò[mgÃóëÐ\ÍvÀX«ç†2í IH!óü¼HWéßÁ _ÄW> ±ðߊüã_ ëú µ†—w&±ä8Ôæû¼Ï4C4«2+Êг’?{ ÀeB»c†n¥>w£²võ½×É¥ëtìŒ*¾Zœ‹U®¾JÖûîý,{QLaEPEPEPEóŽ´ùgâÿÚ{ö¬ð!ñφ~øÇZ>›s¬ù6’ø'ÄR]ê.·¯ÑN¨ÀDµ§Ê‘H]g_,áâ'ÍüMñOöÅñOŒ´ßFLÔõhïî<5­K=¯Ùµ;‹Y –Ö&¡,®’YÝ[Åok#KoÐ^DE°<5ÿ׬£ðEž½ðãKø þ%Öuk+Yð.¡u¬icÊÕ¤±†&¸¶±hÐ %Óci%hÁûT´$.kŽø‰ÿQÑ~k>³ÕåðØê:ÒëöÚ‰--.uaÚ͆EH„1É¥ƒ5˲¬i÷”Åz#t䣣¿äöóWOMZ+>S%…©ÔµéFö¶ÛmõW>Ÿø‡ûB~Ò¾Ð~ÜøsàÔ>!×5= uY-ô^x$¼ñ=´@ÇÖgË–Y×íQ‡Û B€îeÃñßíûPø#áÇÀoAð¼aâ_i y­[i~×%þǼ“É•m^-qk²&™Y®s$C! Y¿ý¬´Tø%eñCH±ð6§âÆP¼ð÷ü&6ožonL»ÝÛ‰Äå]£)*£9Í~~ߺÄ­^K¾x’K4°yÝ´9ÛY¸†xá´–A$Ä ?kUŽrpæ7ܱñœ'g)RÚIßÎ×.©iÙum¸…Üc5³üôÿƒ¿#Èï?k¯Û6Éü=¥/ÀkÝJée¹šúOxªr¢g‰PNRaæÜ2wŽ6þ^cfÍp:'í!ûtëž;ðLj|Iðß\Ñ´{-8ïlm~xŠÛOþѸšÃuÔ‚YÎEspžBå‹@òoP¬«Ù\ÿÁN4›OøÄí½Cá¹Ù¸°ñ„7ºuܺ•œ"aä.xäºhîm[æ…üîÀ#Aaÿ^ðƯá;é^øyuáxKµ¸¼ÿ…ƒGÝõÇ“nƒËµvòÈ(K°R €Prk|:”e(ó^éoç×òÌñ“w‹²[ìïª~¾]µíc³Ò¿j¿ÚÍ牼MðBóÃíuvÖ–P|=ññ–Xìa¸h¥¹ˆùvé3I*¥Ìˆ!¡òÜ´´yWˆk¿Û#Å~Òô«ƒ^-ðˆµ]2æèjzWÃ_ȺDâ,JâæÖ3¹dC ‘2®ü†I>`£ë¶Ïƒ>6x‹Ç~¾°ð§€nô{û}"8îs4p´ˆ®Ü‚ßN|Pý¢þ!Yê_ ®¾ø:ÓâG†¼Jú­ƒ-Å”¶·–7v‚Bdx®%†O$´2EòÄìY‘‡Éó˜ükÿ8Ñ’×KÑtÍ3Ã_¼Q«è§XÒ½¬,W`ªHí ÖWE É‚t%YˆØ9¯PøUû^7Äø|x›àN/‹$Ó5[‹}w·w X´ûkùm®!IÒÁe%¶ërÊÅ¥$–;T£7+Y_§’Õ?¹ë¥»w§$å)(ôZk¥ök¯g­ÛÙ·Ó#µ§í/qã‡ú'Œ¾x†ËBÖîtèd¾²ð&½"ØI4Э̲«¥·Ù•ä q)X\¦å dWã/Ú›ö½øcñoÅžÑþø“Çþ¿×î“âÿøš{m5´Io#éÖsùé'™#$ª¨‘„fvd—!ÿा/ðF³ñ—Qñׄ>j¾Ò5]E-QPøÇûJþÞzŸ†µï x3ádžøŸàØèE—Z“]´Ó.lÁù_¼·ºº7²JåYã`\–ÉQ^c©ÁLt‹oø‡Á6|'&µ¤ÞOk¨ÇyãX­žÔDÌrfe}¡X#ã0O3oÿð¶Ÿã/ýàO€Î½w¥]j­scãÍ5 rÆÖF†9<©DsΪÙV(%X·’Xça«ÂQN÷Mþ ¦û[å{k~U©¿ÆÚþ-¥kü´½í}ÕÅðí»ûG|@7º§†þØ +ýEøâ«è­­–P‡b2£yÌ‹åK¹VA»j>|nOÛƒ]Ô´Í./ÙÛÅ>ÑîÝ'Ö?áQø®þK,óHm™#b§5Q’ îËÁé<7ûwZhŠm|ðsào4£w6¥0Ñ|R¶×ñÚæ,ÜÍa.™äiml·;óÅ_ñükDðÌÖ:ìøW¨|<š+å7ÒüF³´žÞî Œ"ÞçíGofÊÃ2‰fÌjÈ~lñèQ¯N‹p潕®ïu{¾·¾Ú«;lsTk’]®õí{[m4º~›žÉñOö…ý©¼ ñsÆþðÃøƒádm6]/‚uˆ£^53ÀÚ‚;Û—%™ƒ•=›œ„øÅûTþоø“âŸøàWŠÆ¬¥&tÏ™$m"˜â˳+:—*’Ú7õV²zuV¿Ÿ­Ê'({º]­~í5ÒÎúu»Õ´’>±oŽÿ㿇±ü/ñu¿‚µ¯ÿhꚕDŽõ=šUÛD®½ÜAí"`IVŠG áÍ|qgûlþØ׺hÒ~è¾$ðíûÝIg¬Ûx+ÄæÙš$|Ù£Ãp<ÍÊ1s#Eœ¢üÝ6 ÿ‚¥è·V¡©Éð¯Â÷¶ñèÇSŽ 7⛩I|~Ηa6êñOÁŽÌFÕ‰õ_?nŸ k þ;øƒáÁïèZgí>Õ ƒëöÖQM3:ù‚æÖÞœ£y“tÖಂH gV”ôµÝ¼µùéun®ÉmtíBÑŠkâå³ýíî½-{Yê¼×Ŷ‡íá}WRÓtï„>ø†öVöŸÚÇNðŠ‘´ .-¢š9¥ŽÝ.§¸ä1´ÄfK Í¿íOûXøo]ÕlüaðÃQñ¼×²5„7ŸH €$Ž#7 ²IÂlj"É}…¸‚¿n_Éá¿‹Ÿ!ø?¥iÇNÐ-üEªêZ>¥i ¼"qlb½™’3nñŸÞ)e[|I¸}ÑæZ¯ü—Þó‰þø_C2xvÏ]±¸“â>’të·ž_/ìÿÚ_òÆg[‡&±ó€4xy¶”S½—ŸNui¾­^Ú+#%^>ÍKKmç~þ_]´]nß²~Ïß´¿ÄxÆÿYøÏá?Š_´»›xt{[K¯ëº}‹ê?l™DVÛ“|J¤±vŒ Ø`N6±ñëö³‡Æ&ðßþ¤:E¦¤ÑGu®x ÄWfü>¡, Å24P¬kbLîeÄŠITÃ4þ 'iq«jZ ß„þxNé¢ÔMÿmEÖªm!/:[D¶íóFpÆ%þ탖ÁÅqúGü'A– è2ü2kísSÕ­ô«InæÞ6$u2ÌUáY Y“yF T•©âý®?ihu+3Xø#âkKhô¹u;=NÏá·ˆ/¡×Xo j±ÄŬ¦€ùy±·“Ò°?iïø(Wü >'ñÿÂÿ‡Ú¿€4hY´·z†£ ÓH’Åp^'´cÄÊÑ¡ Ô©ìO—â/ÛÄÞðOÂ+¹l< ©Ýk~±ñ«¬?ˆ¡°6©%ääÃlñH% eÀ&D %±\”1 ­Ò^_7k­zr·¯šÕÙ§V.Œ:½òe?;Ém×]5GÏíûhø–ßÄšÍ×€~%ézF©•v4ëOk6wúȺš-šæš]®á’&‘1#ùAÛõŸÀÚgâ'ü ,ß¼ {àO‰š„:Ƥ'„¼CRÒÙã¹v‘bEyUFÆÛ?&Ø`¿1\ÿÁNµ ïÙÝh¾ ð›àNïEÕSñ…´w³‰tèQ£1Ææ'†kÓÆÀ«JHÀ)fø+û~§ÅøþïSð†ìüAáßÅã9†â6Ô´ÝHW‚µ¶TR… (IÃB2;ôÇ9R”ÖÎ;õZ6šï¢»ßþÝØê)^qëÓg´lÞ»I­.·w×UÅCûW~ÙPZÂëö~mJþÏN\Ãà­rÚrg­âI´ l©9rÂ0¤{»¯~Ó_´ï†¾ j^)_7z÷Ž!Õ›NkÔð¶¶–6ñµÁŽ)Ž™oΫ:`ǹà‰Ðg,ªŒ‰^Á`þZxµ48|1á½sÆY펵¦xÎÒê:>ª¡vª}ÕLí+’jè~|6ß?ø7ÿlÔ|N<{áígß¼}âÍ7ŦŸmq£üAÓm-$³m|éº{";5ÕÄ;X,—‰ÍŠD [ÏY4äšÛKoùÚö7èŽWMÆÑ{í÷ÝzhÚû¶Ü÷‹Úóö©·ñ_Œü/âo€šþ‹c½§XèzýŸÃ¯ê67:uÅ´Ì÷r¤CÍ.âk6\)EݰÏŸ:ÐjïÚÿÁ‘ø1þüLø…âk­wY’Ò÷Zøyâ†=5n/|ƒ%Ü6âÞ=¦’5—Ë.“DÅ‚Ÿ5½3öý¼<]û>|F½Ðït¿‚É¡èš=¯ˆõ}6ùz½õÓõK«—Ž'·#Sa¶a+¬ŠÂ ,?ðT ÚiÑx‚_„Úýφ$}9ÅÍ–¦—s[¥Ô÷6ém5¼Q™c¾Y­Â½¸ ˆ.!g™T±L±0~Îö²z'¿hýîZ馺+FsR‹Ûîïù|Õ÷¤~Òß¶”–š®·¤~Í:ö»o-ÍÜBËQÑo´ë‹{ˆô»[ø²³ÎUmæ?k³Ý œGuä}ðd õWìÛñ×ÄŸ|/áËŠZøSâf£ö©…¿‡uÝ6Ócº1E#¦«iÖó1ï†Eqb†Hñ!ñþ á=gàߌë¢xN±ñW‰Ú<³xóNŸFü¹¥‰Ž©kç[‡™!Ø‘}ï9ÄGi‡ŸÁÿ+:Œ¾þÊø9§ˆ5hµKÿEkr‘¼©Óü‘nÍý¬¥Ÿu‰#ƒÎ;ò·RI>GZÉ÷½–þm¸»[Euæ¦ýï}[¿•ÞŸ$š¿V“ò©tWæ³ÿ×—MÖ"„–¾Ô4ý?Å3k­x‹ìRé’èžB^}ž;‹0/S}Ì^\«¶Pͼ »¼ëÅßðTX,¼Y¨ xcÀÚŸƒtkÖäŸÅÖÑMs%„Wït¸1þâh—OfDùã”Üžll%òó§FsŠ”UÓÕzmO3lCöIʦ–Ó箞º=7Ðý¢¿<g/ÛßFø½­øwÂÿtO|7Öu-çU†ko5í –=Ytï°´oÅr²Mj¦9YöF’mf¡ÕšMÁO£ÛäìÿaFi¶—Oøp¢Š)QEQEQE‡8;p[¶ih Ïo~Õ<â‰Úï¯ø—Cð犴?\[èšœ­w£$$ˆ\$p–&;•Ý•Îà8®óáí±ðâG‰~øSI}^ÞO™dð´·kg Ü ¥Ûj+f­î<ÁAŸbHÅc‘‡ ¬~п± ¶¥âû_ŒÂÏxÚ÷T»½Õ¬5=ë­Kû&k”‡QœÃ›öGe4Ñ4‡zG „mòßmx>)~Â_ |E¥øgá7€~ [|AÒ®- Hðÿ‡­tË"ØÜA¥´ê|˜Õ¼¡±Hsol ›3XNXÓNµß6ÏÉ¥ù4ߥïäêÆ\ҊѦռÓð=N ~ÝŸ ô}Q¼?âO øòŹ»µvÖ-ŸΧ6Ù{ÞkÿeÜqåä),Ö¹i¿à ^𿌾 øwâÃïøFÛK¸‰-vG÷CåÛùßjQ.Äd’qþ¥¥VEÜ’Üñü;¿]øyiñÄß þëÿ¼Bn ŠîëÀQ\¦±Ew-ÃùfÔ¼°˜®o¤yJ˜ÌwͶG'Òõ؇WðÅïŠü[û;|&ðÇlüNt-âûÀ‘K&«kÛ ·…ÎÄGHäŒ:˜¾ë¹W*©¶”¶ß[Ý¥åÕ¤»ý÷Ú¼bŸ4omwî“oðNúig¿H|û}ü/ñ¹s}mð³â,Ñëku¡^è:öŒÚ¯‡Í­”°j·&ÙŸÉ·-¨Æ«¼îErαä}=¦~ÑõqþÑZ:_ê^ šÍî–;wµ{§òähÚ‰¼¡*Ȭ… €«†VÃÃZ§Åïø&§‚|iàK]àWÂy`º’÷W‡Ä:wÔH4;Ñmy³ºÚµóbei“dJkȤ®çá×ÄŸØ{Æ~×ßVøKðïÂñëÚ>™»áë-ú½‡›u,"òÞ^‚9%¸c3iœ³‚y¯k EòïÑôíÙ_u¯ÎÉ4–S”yôÑvûž÷ÓKôòîÏgðÏí—à¯øÄáÿÄ­E¶ñ‡tÈ.!³ûV¿qumm4ÿÁ8$ðìþð}—Á»oêon"ÓüðérµªƒÊéj WEbÞCcòó¹sÏÞü^ÿ‚Xi~6Oê6?³NŸñ:ÊÊÒö;Ùü kðG5²Ûì-mö€c“쌨¿2~áðÆ­©ò9.u¥Öß/ÆêOòÛ[¾ü©ÞÏú~Zëÿõ~Ö?¼­CðúÛá·Ž<[u£ëøoOƒHÒ-õˆíâ˜YBÓÍÇ$pH½¶G·…°Û^Y'íùð“âwñ/ïŠ^ÐuMFç¶v× wÚåî-“É‚K[Ïôrd¹æGŒnF!öa øòçö-øãà­oâ]Þ¥áKÝ õ{+ ÏéºsÏ­\Ç8Ù+Ik!½Wy{#W-ʃš±¢j°'Œ´ßx¿DøðwXÓ´Ï'OÕu$ð ä’(ÂZ$†Ô‰vyKäÄ]ÆJ‚¬¤¥f¤½oùýÖZÿEÅ;«Û§É¯Ë_›;Ÿ€Ÿ´·ÃOŠ:šü=ø࿈ÓtÛImíæÔ좂Ûu«$RÛ.&iwÆÍ´–@­µŠ³ âz×í]á/üwñ¶£¯|ø¦ióÍáÍ[ÄÍyÞÁoöwŽh­ÅÓyV­öœ6ÄY™ÑKDÀLß´?üÄíׄ ð7‚†îf›JÔP#…c³i85g/o®÷üz¾©ìFÁ©Aë²Ó£þ¿­æ_Ú×÷Ÿ ¼5ñ#DøYñ§P¶Öo›O²ÓçÑ#´»Cåy©q$w3D¾C)V¬sœ@ðßþÞ~ 3øwDÒ¾x×âˆíçÒoõ0t¨b·³I]xžy@[„Þ5 |1G;X_…ŸÿcCá®e'Âo‡¿ ¼#§O,ö>_ C:hÎZx¥¸0ÚÀÑ[G¶Ý7 ´üÌ9ã¾ Õ¿à–ò|Hñ·¢x‹À~+ºÕ“wölþi:r[ª"¢ºÙEPPE²²ƒ òToç¡BÕ’Ñkßd´ûîïÚÄP­MÅNZ§òÝùù[Céãûjøn?‡šÄ÷øOñ: Áâ«ogÓD’C,Ìu¿jâI>d8›*BÆÜgRóöÖø=cðÎ÷⮯¦øÓKðäºuœËug xSÆZÆœÖéþk}RöÎ ¶™cµ•ÀHœ|Á¾U ÕN Eï¶Ï_ëüÉN>í·º¿š¾Ëµ×¯o5Ìx[þ =¡Í?‰-~$| ø½áFþÑŠÇÃöºu•¾¯>¶ï™öeŽÒwo´ Y@òÎ>IœW«h·¯ÁOøêO‡‡¾*j4‹Q‹OÔ4ø|>Íu¤#F®·7pó­`!Ô•žJ‚ šó]7Å¿ðM_ÞKà~|+ºO Ácuð¦XâÔ'’??0£Ø+ªŒ¾ÐJnÁ"¾±±øû8ë—~ñ¼¾ɬXÏý¥¤_ÜxNÚ+Í:v@†X̉`r€)#k`Ò•eh½ÌÆi®eµî×§OUÒÿ}ígå^*ý·>ø?Æž%ð-þ‡ã©üG§j«¤ÞC ºÊîv™b’u™á;Ô mlår2k‚›þ ;ðrÊm?OÕþ|wÓu[ÿ14|ñ½Ü×îYu Y^³ÎYXÊL±±ÞYTî땨­þȲ‡‰¬ÓNñ'ìËû?øƒOTòÖ ïiÓÆ©ò|¡^ýÜ|Ó4ôQäåµKßÈÒ¥¹½ÝµûúÁü…ã?ÚƒBðåÿ‡ô«?|@¸žûJ²Ö¥¼—LE·Òí®.…²%¼É2Ê_+±È#'޾/ü[áóø£O‹Køgñ/Uð\ñÜÕ"²·$ÉF¾jþÿkEºXã<ùˆìC¢…b>ÒÖ~ |$ñ Ö¾ü?ÔÝlaÓ#’mÝÞ+X¤ób…X¦U#“çE+€ÀÍx—ÂïØwögøW£ÿcX|,ðOŠbK†¹·—YÐtÙ^ЗˆÄvè‰ó*±`»Ù”330ÍP»½úþ;}ÛÿZÅTù=ÍýßÿcÂÿ¶·†|SàŸˆä ¼}§x÷Ú¾¿yá «½-uãŸ>RÄÂìÂÊÌ ù¥Ä[ƒä‚*{oÛWÀº¶ñmÀu?h^ÿ„ˆhÆ;HŸV„Ï%¿—ï8· 'ŠHÈ•ãû»¹R¤ûn‹û>|ðׇµ¯øwà—Â=Âz–œÚ>¡¥ÙønÎ;ëݺÖXR0 ÞùS½¸äÕ;à?Á #Eñ?†´¿ƒ¿ ´ï ëv’XktªZê¶®<Ä#Ù,l²Œ ÍrjêºMÊËF´õ×ðòüI¤¤—¾îÿá¿àöÜüúøGûRüø[Š4~ xÇáηeywswb¥µSq¦D×Õ͢Æë9ÔB6 *v)VV?Fø3ö¾Ó Ót GS¾»¿[U»7–NËqd‘Åpà¼{JÅT·Ýfש¿ì§û.É»Ìý›~¾ëshÙðvœsósúŸ¸|ùþ^Ÿ¾“ûí[¯Ùëà¹jÃOø7Å:æ•6‹¯hú-¶¦ö¯–SÏ .0r«ÁÅ,Lã½+ì÷ôi~6#JIY)õjïÊéËæÕÒ>\×?à¤ü*o­¼Sà?Œz»kisu6˜úeœ×)åE$Ë ºtÝ,Q3¡Ý°µ™_ä¬è¿à¢Þ ±¾ž/|øãá;æ76úfo«k:ܱI8?g‹M¹¸VÜ–Ó8Œ‘'ÉŒn*§è‹?Øóö]HÐ4½göø-âù´ë?°Ã{«xGL¸¹hÏ™»sy|ÆY‹m,œ|Ç;Þ ý—fKªÏâŸÙßàg‰./ÌM}%ÿ„¬'këÆd//±•YwgA*_*”z®¿æ¾zëÓMõ2¤çÊÔÒéoÕ=üµ·ùokûdø_ð|SàøçÅ·Ú‹4ïêz0vzÍÔöñ,ÒCsqC¥ÊM‰vHñ|Ñ£†MÞ=á/ø(—§ð¿„õ/|(ø™áÏß-·Û¢³µ´¸´µže±°˜Ü ¤¯©YÇ`3eÕ$dûL|ø>4-cÂß𪾠ê0Þ_éÇD¶6··:ÔØòiIòWc¹F‡7àïí#àOÚâå­åïÂ_ˆþ¿ÓtëSÁú•øk6¹²›MÒîn£¹µ†Žãý6XÙv…*á·ªûOÄØëöpø› ^躯ÂO‡ú5ô–1i±júv`—ö–‰/˜ I$ÁˆÁ¢uh]ÕÑ•˜§á÷ìÙð;á Ñn¼3ðÏÁ1xŠÆÒ[(µ©4‹_íŠHáŠUó’5*¯µºM©²Þ 4UÂ+Ióv|¿¯¯¥ÇIÁ+Nÿ/—O=Vû|•~~Û_ï|#á;À >6xgÂÚŠYÝéÏ«ZÂÒÝ›é´ÖI$y/$™ÿ¶l¥v”îį¸ïGAç^ýª~ü=ñŒ5üñF›¡ël5‹mt^ ¤µ´’-ëʸ·žëÌžm}öÅh1Èçil¹àý•¿f+m>"ßöuø“¨²ŽÕ<'`!ŽÜ%ºU[B´µP ` X1a-?e_Ù‡NÒ4ýMýœ¾éº%š¢YÚAàý9 ³ '–‚©¶;kd-¼+Ѫ³¢œ4öi_Ͻ­¶ž¾E·JÖIê|¡­ÿÁG¼¤ø—ÀMðÇâ&“£jÑæH¯l¢}RôNm“M6q[K*J.g¸h±,‘º2e•T†¯Ð?x®ÏÇ^ðÏŒ´ý7Ä5–©cüVzµ„–WÖ‹"O <2®pѰ ¬#"¼+ß±ÏìÝ¢ø Oøy­ü øqñH'Y'ñ‡4ë¹ïLÁ¯)ê®Î±Ä¬ÛAag;E}¤húO‡ô­7BÐt½;DÑ,àK[;;H-aE ‘ÆŠ¢¨rSVO›W¥»%moø#ï§ŸüÀÑ¢Š)€QEQEQEQEx'ˆ?fÏ…ž%ý¢>þÔº­ˆ¤ø»áê^ÒgX¹ŽÍ,/^'¸GµWHÅ¡Œ†e$m‹n¯¶¿“·Þ켓o[Y¾úëþW‡[¬½;öKø¥ø«Ä1µðψ›UÕíï-uxgñ>«=ޝÄÓÌëqi%Ë[Îî® ~dmå ™cؼ «oØËöyÓç´Ÿ x³BÓ¡±Ñ´ø4½;Æͦ™o™°Y´vPÝ­²J‹hÒ¬bI#EŽFtkåû¿ØOTñš|NÔîüUðëOÕ·á Sá二ڤš\Ú­ãDÓÉ!‘¿å®à˜•Œˆq±Wš¾ ÿ‚yüZÔ¾"ø›Oø§¯øk\ð…¤:%†™¬\i’É¡§Ú>—,°ˆ?µV3Œ­À" ò4o(žxßÙ>ÿÁ<Ñ<;suâ·7ö'ÅÚµÁû4ß»xYé”[‘„ò0# ¨» ÆŸû ~Ëzv»eªi>ñe†·em ³ oë©æÚ*L‰op‹{¶xšRb˜4nÁY•š4+ó>¿ÿÏÔn|sðb|_ðXñ'Œü?‰ÿ “àÉôë»O*êúx¼×“Ë<·¦5…eˆª¡Ù"b„WÕù§¤¹uŠïü·ÛO¹™ëíeÙIÙ÷[s|Õôß§›úKIýŽþèÚf¤Zé.lì-ã´´7ž9×n¤†ÏÉù¯ЍI(+Í<ûþÇÚž‹5çÃ}'Æ:o‡Ž¬.xÇúý…µ®§kpÊóC½ê$oFŽWŒ+H‹åH]ÊùÚãþ ùã½'_‡YÓ¿hv‰§ØÛÛjÔü }}¦Mh.a¢¸Yµß1âýÌ¢/5ØÅæpÌ«±½§Àÿ±ý®áO^ ðÇÅÏAªxž×ìz…Ή¡µ¼ÖW^lÒÇ%È®Ó7•2ÆCb¨`¡.Whívþi«?ŸÞŸÞ[ŠIK®‹å³_-=Qëcà7ìÇe¨k “Cq¯ë7öþ)º‰u;ù/ å³n‚ìÜù†H¤B¿!Þ­„ÀÈLÓKý™> èžñ7ý+ÂÚ—„õ}Dj÷.µ~dÀ Jf2[ɘѷDÉóßx±>à¿Ø‚׺OŽ:_xj[x}´5ºµðï“6†ây„q;NÅ­ÌÁ‘·g ‚â|#ý‹\Å d%+•R<÷@øûAã­/áÞ—®ë‡Ä=/:u¶Ÿuñ]º»mBÜ}›Þ6ä‰v°ŒåUmâ³ôߨÛÄø{ñ«ÁOñÏF‹ÄÞ9·‚Ê+›ÞÆ"y˜Îlž÷3Ï"ÊFYP·”„ôg|'ýƒ|KðÿÅ:ˆ¼Iñ£Cñ|G©C5¼šÕ¥K›h<·ó`"~`Ùu¥RRçm;«?›åvüt×£èaR B0ŠëD®¯§–¶ô4nÿb_ØgÄžÔt 7ÃwÿÙzQm=£Òü[¬„Ó¥•\`$7[A>k“Æy®Ïá¯ì;ðóÂ_ ZùZËþ _¬hÖ3Zxoãw¼/)¶†Æ9´ïMlcµŒ>ȱ¨«‚Ά.73Ç ¿ðOÿŠž ñgÃk/‡þ&ðwÄO†ÑßɨjE4÷´¶K½òîyjlñ¹ó2g¶W”˜–6]§rï9Êqå”ï{hïnùo×þÎz«Ýp²Wz5é§]WõÐûíÿcßÙ¯FðÊxøàø~øMb°MãMzvq0Œ:‰Zí¤LˆÜ6àí#'<Ž?àž_õ¯†w üÐ"ð·‡ô¿ÁªkÚÜV±yKwª^=ÝÔã$î’W%¹êy¯Ï¿þÂ6Þø7ñSà6»ñ?Á~.>&‡N¸ó.ü*X¤ÖÒ‡7WIzÿiiA-˜þaœž1OQýçøsû?ücðžµã£âÍK]¶´†ÚêÆ8td°¿ŽAäêGíwDfI6;ØuŒ!WÎRQ㦟=-øm÷mÓiB.I·w·¢Ñþ¯O/=K¨¯ËŸÿÁ<¼SªÝh:ï‡~;iÚ>½¦Ø¢Ù\_xmï’âá Š9~Ö‘^[­Ì–I4òv4̓×:ÿ¿àŸºÿ€>|\ðª|`ð®§ñ+Å+¦)ñ/ü!ò¬QÅk°›i­ßPy'·«n‰g‡#$ä–㥮ªÖó×ôß_‘ËRmJ *êW»þ]íë}6ïä~—ÖMö»¤éÖWz…ÕìBÒXæhÁÆå‚…!9ɸ¯Íkø',šŒWÖº·Äß j6ÜK;ÛIáyÚ "‘ƒ 7Œßáí  ‹xØ“ ³.çÎj¾‡ÿرÐï5 F|'þÔy¤½¶½À2Eu ä—PÏ%ÃȺ¸ 2Ì-?ø×™¬´vZê¾î¯å¿_¼ý ðo<'ñÃZWŒ¼â+Å^¾ŒËg¨YJ%‚å2FåaÁ~£§kºN­q{m¦ßE{%¾Ï4Æ A¹C.[ Ž„×äÇ…ÿàšËàÈôMáÇÇ_‡z·e* R#àÖ™uXEÕ´òM4j1âížÃ9%v¸Ìm› Ñ¿àœW>Óô9~3ø'DðŠýšÛL°ðƒéÖQ3%º%ÈA~Ê/#hsÊ)™ò“,œ–ï§ü·Ù~)N÷­.®ÞŸðß×Cõvª_ßZé–w…ì¤K¾FX¨ú($þùñàÏØgÄž øñ?àŸÅï Ü\xŒiŸñ5oÈR&‚8y&¯ØÎóù,Å„‘Òdî#œßþÄ>#øqð³â¿€µßÚÏYÖ|] ÚèI¬\èr!µ½X ¡æÞ½Ä…\CöªS)·8 Á^I=­o7×îzyö9ë^6å×ÒÛ÷×ÒÇß^ñ¿…|e&¹†5›}dé·azbVÛ Âýè÷èv“‚<‚+cYÖ4¿i®¿®_Ûiz-´·——S6Øí K¼Œ{*¨$ŸA_pÁ?&Ó>xgà†…ñšD6~7½ñ}ü–žº±±ÖæYäxd‚ÏQ†a*´ÁÖaqþ²0æ3¥Á:þ(Yë>"ŸUý¡~x—Ãz§ÛZ]>÷áÝÓ5…ĶpۥݤŸÛ`¸ 4’lo5de!Nçl1 ¥%OV“³èÝ—ìÛkåçrð¶•M<ºïåu{kó?S4_L×ô­?[ѯ`Ô´›¸RâÚâ#”š6V¸ æ²toøcÄ:¿ˆ4-V‡QÔô¹D7é6Ø$9ùwãkA);H à‚+á½7öAø+¡üðÿŽ|3£øwOׯ³…¯†ž"ò#c5´–³Ù­ßΆIÈ)"bhãlddßÑ?díào‹¾xâw€£ñtþ*—^_]øWíˆgis"_[ÅyÝJcg¤DNA#¡ºîÎNšºI[¾­_î»õ¶†t.áSFï-íë{/Kù~Q_žß?a[߇Ÿ þ*ü:ñOÅæñ™ñFg¥=ü:ÙäÓï`‰Õoã3Ïq+æ9'•ãF‹åÀb£Ë.ÿà›ÿÙñ|?ÑGí 6¼–W³ëúu?VÒ4i$eDPK18zÖâŸøª=Bok:~µ ­ËÙÜ=¼Ö)—‘Üd~uðGÂïØNøswñ^Õüm¡j>ñ/ƒÛÂqZZè×vϦÇ%Œ6Ó%¤—æD6Ë"´òƒ+îvnÿà•z­Ä_ØÚ_Ç߇ú;”…5m/Mð~¥¦Úêºx²µ²ŠÒhì5È'H"[{‰­ü¹Åq0‘Xùl²mF1•W;FÚ?;»«z$þvé¬JrQ‹Kvï䬭Ù;¶Öý?½§íGL³m?N°°iÞé …"26s&ÐNI<ã¹?Z½Q%®†‘m«°¢Š) (¢Š(¢Š(¢Š(=ýh¤9ÁÛݳIù˜ß³×í¹'Œ¼AwuñÏH½ðlþ#¿Ôô¨Û^¿[>Ò[ë9cŠá>Eäkoì HcT¸ˆ$ˆ×N¿?fÿÛÀø§á½_â·‡¼/y7„SCðAÒµé5'×+goLº|ºlW“4s‘ ™üÔ”n‰HPže¨¿üz?‹7×4?xÿC°Ôõ :]@ êvö6÷Zé…ìmdÔàDñÉ¥›‰'ÅÁ€”+¥iÞý¾là¹ÖôÛÍSRñœ«£É9ñü#ö\@ÚäWV›¬–R¦ÞÒXnäùÝ<ãº@¤ÖÉ>Ž?z¿Þ¯¾êÜ·¶¦U$¦Þ¦¥ÒÍÝiÛÕmÕõi÷ÿ³íy¨x[Wðïí$Þ µŠýå¿Ò/µ­W[HlËÛoÁxfÇÛ™2šÓûCM°Ñnä›C_ô˜no{‹6µ„ÏdâØ]ÎÎ)Õ14›w…7ÒÚÛ¯ø{ëÖío£}ÉNiBqkm5Õé}šþš²ÕhtŸ þ~Ö¿|[¦x‚óÄö?¼.þ´Ó5-WñÆ¥y:ê¦î6žúÞ{ˆk„ÌLrDÌåaTx8~Câ7ÀÛ[Åÿ>"êÚ?ÄÍÃÿ/.ÞãE‚Ïâ.µg j_ïü{âÝÖÃIÖ-4Šæ(Ê9+ݺ7övøÙῃiá/ ëÚnã+Ÿ_jÚËÛø»R ¨ÚM,Œ/Úq F]\D¨#% y ÄÕ‰šíQ6©ð§TðW‡¼aew7…bk›QôçÔìoÚê×íŠæÞC¥µòÙ›¯+æ6¦@pH+œ·ð—í—âÿ„´ÿêÞ4ÜéñYøNÏN]Ì«îr.£’9r'Ú"Þ'•bó ›n+jÑr©Í+_E¦Þìº[K>Tû8Û¦ÜÞ×ÜŒm¦þzÁ-zì÷Þ÷{ïæs~ËŸ·Å¶—¡XÛ~Ñ××Ol|GwÄ;Ë[›ýˆÏlÓi1Yû¦0GŽSˆ˜ªëé?´çìÝûQ|a×uû üDÑ#ðÍŠÛ¾“uâCL·ÔÐÛJm4vÖÒy#Ï0Ì'Œ´„!BðÞ`|UÿHžQcíN1Å,lº“ÂÒAvQ¸ÊLWFH%–Ñ-Ë0†hÔÌH„hÇ»xÛIý­/~>ü1Ö|9¦x£HøX‰¢ÉâGÓn´R÷G÷Ÿj·Ü7˜ñ#23ùJŒT,±ùj¡VTêB?z×ÝkÕ½¬¹}RiuH'.XÎ{Ù=;ít»·Í¦»¦âÓWNø÷ðKöŸñ'‰®à_ôÿxF}Z$§Æš…ŒÚUÊÛ͘­VÎx%¤FggFýÞq» 0¾%|ý®ü_yðu´¿ŠÖšu†—áˆì¥gñƒáM–‹§jmõ¼w¾0Õ/f•-Œ"h•ŸMó-â14m<]êà3gð/ÀÛ£Iñî‡âoül±»Ñ ñdW÷ú}ÏŒnõ+ÝCƒVé§ZIo&×UÙ%ÅÄLð¬Œ掻ÿØ~Õš†>8Ác¯Ühž3m#K}ïRÓà„¶¸±ÊnƒE¾{dWo)äˆ1%WËž<ðü“Æß<+¦üCðä%ñl·7i©/…u2Õ,àVÛH³¼¶²«¶áªïSäùD›GM¸¾TÖoçk»Û]–éÑ+œ8Êü”Ü’nëd®ôWK­¾-mÕ4ïcêCáWí•syûL¾“ñÁ^Myü 󷈵 åÓ^?õIj¢Ïr ˜$ÊÁs_9xö@ý³4VmPø…| 5®› |YÕ‚Z£ÜÉ,èîÚJÜÏ!ÞŸÏF8*@^kÐþ"ü=ý°lþ|½ø'‰ü5ñsE—[ó ¿½Ó¯-Íy~ÍúËpÂ[vÔ9•2¸)ƒO²~Ü>/ýž™¼[Ämâ³x©$¹ÓtËo éדiºËlŒ/®mZ+!š+’Œ2#qŠÂPäÒ.üºt×[z¾É^Ú7ÍÚ—ðϼ9ñKú–—k¥è×PøRÇQ]*é.î ò<}¾-Niä›a ñÏ q°¬¤QRîÛþ ›4ÞÕ|;ªx1ô™5w]GNÖÆ™my–pÌðE,mpÊîÂFTî®÷M{G%Ó^Ÿ~vÛ^–iKýƒ›ë«VmÞÊöÒÿðV…?‡Ÿ²gí኿¾$x—âLJ~ ˜5 ¨üVº‡5e›SÓÝÁ€[²ÚbÜDC9µ@HÎCœ(jôO~Ì´O¾.i^#ñOÄ ;^øqgãµÏìÉ:ø±¥ë?-õKk»«ëˆz½®£l.'‘á0%ˆHð agýàB AÁÎ×>~ÔV?³¿„´Ý?“|UÔµ«ûå꾎îëÌ‚u¥–wH²¿—"E¸û„ç <Šø* ¶Pø*O |VÒt{'’Ò-vÒóÁwkÕ¹†f2\“<+2·îöܪ7ÍW‡‹ŒUÚèµô½ûÙ7kõ뱺©yµ¶ÿ¾ý/å3è|ý®|Câˆ3hž?ÒôÝãWó4«›oj¶’ÜéF9|»wµKSŒ°HÑæXdÜ,¼Û÷O˲~Ç¿ðQ)üA{¨ëÿô?ÙGqyw¦~(kºSXܹ»[yÖ;m=£"¤¶O%ÃÆÌ®í–P_Ø?háû{Mñuõ¯„^ñv¡á]&ÍG‡çÓo4‚Už ar÷p^]@ò^G ŸÊEo³m–Éæý‡‡ÿomAÛXÔuoOâD¶Ô†˜oôÿ ÙZYʶм– ®$A<ªñ1Ýq°ÛW NtqÍ7kÙ-ÕûmçÞÞ}´ª±rj:>oM/}m­å·]xþÅ?µ^«¬êºŽ…ñ¦ jKVú»5kCJC ¸¦ßj>Ú®épr¹UóDŠU€ ·ì¥ûvÜêâm_â×…ÅÒK;“âµuk¥“y ¢³Éb ¹bŠãl‘¤*«á‰[Þ8Ÿþ U{â;-/|A{M2çS¼ðµÿ„üÕ»[<ðZ=óÄæ/žt: Z8[c+2‡è58¿à£^ð•ìžÒ÷Z NžÓO4)õké%Xní#‚Yb´”ˆnVI/B7Ú>LjÂãº.Wd¯¯]w뮾{ês%vé¾¾õß]šWòÓM•Ÿ™ ŸìÕûqÇã¿ ø¶_Ëý‡eqÁÐÏÄ PÛ¤›¬Ä剱?kŽAã¬S ±›…UÚJoþÑ¿²÷Æ¿ÚWWøeã9íl|Õô¨þ%ëcEº‚{‰wZ(<©%>r¯ÚBÃ.Õ)’§mu-?à ‹'Á»Ï‚ZŸ„õ yì­âñ¶ªl4÷³”7—,±*ä4Œ³‰‚,6<Ÿ<2ùtø)Šîÿá7凂¶ÖçÓcðüw0‚ùJÚI$»’Öb,v³/Ú‘¤—-¢ÄÞœS·ºÛVÑÞ/Ë]tk­–Qt  ›»µD“[Ù>–FîÛ»lõ…ÿ?lÝÛã¤Þ=øÇo¬ëÚ¦’l¼) ñT·V6’#FÆÜéqIe"‡X^ušäÊ#Y|¸äÜÀuoÙSþ )£â wÂß´\>t·û3O½øƒ©¬6Zi¸»–KݧL¯#Dö°-ã+ͤ˜m“ë¯Ù7Xý¢EѼ7ûFx?â7‡<Õâ“]µeuEFû;gNYÖi&·%¤hB9;0ýe¢°©.ismñm§Åfüítš×G®å5ug­­ø&½/i=~ãóëâgìûûPx‡6úgÆ;ä›Oдý?[»¶ñŽ¥¢>§v‚è]Ì#³·(ZA%¹Y V3€¸ü©ã?Ùþ +㈿ |]uñKàðÒü7â«o®|k¬O6§j-õ+k›Ÿû5dÓ Ñ\Y“=¼„†‚Aåíc¿öŠ!6¥)3æôw¾‹d¯Óg³DÕ§ÅEôI}Ê×õóÞú­lÏÌÿ†_nâ'üSãz†ƒiâ}Nï^Ógñ…Ö©i¬i’D±ÀÐÛdm$Anò\Ai×÷æD–8׿cÏÚçGø‰ñ+Ç |}áß ëz­Î«Ž©{ñZžCcq7ˆ® Ž[y¬å‰|™õ=8Gï#€A3E€Rþ»ÑN3q‡${5ç­º¿N§Tq &šM?óo¥µ»ß}ä_|-ãü,ð·‡>#ë:޽ãSy=Ö¸ÚÄ€´¬Ë¼k[f¸¥T;BŒBŒî9cë´QJsæm³š1²°QE%Q@Q@Q@x6¿ã?´?Ãßh´Íwö{¿Ð5+ïxý¼M3h:¤Oµ±]9—θ«H|Ô;SË;°J†÷šCÈ{w†iîá[É ­Ì­on¯hÛ¤™QQeG¢,Ñ|ôýœu“I_¯2ßNï¶›]$®^:ЪÛ÷TæOk=½é«Ý¦Þ–ò+ø(ïÅëgAðgÀ‡’jqãÇyi®øÖãO»µº¼›KFôùžXâKë–w^#k%W \+ÇÞü3ý¹þ+øïâG‚|ªüÐ<1o¬j7}²]wPs´3[Ã, ?³B øÌ²ÈÖ»ñåAæK´^yðûöÄðo„µßxšÿön‡Zø©«jI}wàË-Áäk©þËko,÷ºŠ=ìÍ®÷¸@¨É ®ÀcÅz‡ü·á槯èþ°ø?ñjó]½3ÜÃl—z ”é°ÞÅe5öÇ¿W)Ä¡Z=¾qÚÁ#‘ð‡Ju"ç/mÖÉõß²Öí[EºÝ©/i+_g×KkÛïïmöòÝoöêøáà_Š~3ƒÅ4ÝkÁö—ú{iÖ°ßÅ5¬qßÛÛÛL«”ó\M$s™U‚yQåàšöÿƒ¿µŸÅß‹žøÇâM7áW†í|A¢h1êzwwujú•À¸¿‰Ò[Ÿ*EâÖCH@œgx*OÒ¿><øcö†ðV—ãÿéÚ§‡®íâ6»hãš9|éàšÚX yöóC%»¤‰4q²¸dÆäu_SñO…<1ãjþñŸ‡´_x[P­¯´ÝFÕ.-¯"n I‚®§¸ Š^ÎTèºøÒ·7[÷ê¿«míœå·5íÙ/Gø§ó?5¯?à þ>¶Âº ýž5¸´=JÊbU¸þÑŽûNÒe¶¹¹Ké`ûùBÁr"±hå¹El¢NçÅŸ¶WÅ}à×ÂÏ‹þý›|SãÈuû­FÖïJÒVîkÛ‚y–9„ml­åË%Õœ'2F£p;ëô"ÚÚÚÊÚÞÎÎÞ KH‘bŠ(*D€`*À *zUõ‹TôwZïê­çë§àb¢ù“oK5m7¾Žöé¶Ö}®~0|^ý¬¿i;ø«JðüÞ*ðXÙ4ɧE§ÚêQÍ#Gk$`yšzÈŒ7Ȇ=òäî!¸}óãí¿ñ+áwƽwáµ·À;ľ ŠóMÓíµè5»€ðˆ¥’[˨Ÿ• ¥¸ŒotžGùÇÊý#¢•%ËW®úúÚßu¿µöœïm4ô½úõýÏ öÃøŒŸ>-|Nñ‡Ã>ËVѵhl´½Ê;ç’{yT™ä0üé#t—lQùeKä×—ZÿÁHYss_KZÞ}ïëòÓmѪjÖk«.‹ú×]ÏÈ}SöòøË®øgBÓµ?…ëð‡ÄÝ•ÕÜwºMäúœº—s²$—ízrBÒȆEW[ïtj÷ŸµćÞ,›OÓ<áûÏé_ÙWWwðø¡¿ÔÐË$‘›gÓ¥ˆB6]gWËš>ÿÕ WJÓ5Ý6ûFÖ´ë_Hº‰ ¹µ¹‰eŠâ6de`C:ƒVïºîÿ[.ú]zÛÔµ5}WõuþV]¯ßSñ’ø(—Çk¥Òüm ü;ð>«á^Ñl­4ý;VŸXMÃÊ|»Û„·²ISjç@Ò‚€) ó_Oøwö²ñ×>|Zñ¾ ¼ðïˆü7y¥ÚÁsg0Š j9Ì%® i`¸òÇÎùŠH̨ áÇÝ^ð—…ü¤A x?ÃÚ/…ôH¹ŽÒÂÙ ‰O®Ôv®†º*U‹øcoø{ÿÀßô¶PÝIŸŸ~ ý¯>+ø·áÆ_ˆ1üðññG…b†þÓ]¼˜j–Yf˜¬`ç$HÌ#HŸsmLÀטø§þ ñSÃÉ£ÝEû6^ÝÚN ×ѽÝò\hö†,7sF,‰ͽ;‡Ü§‘Šý,ñ‚ü!ñA»ð·Žü/áÿxfwçÓõK8î­¦dpèZ9RUÕXdpTÕÒ"$h±Æª‘¨T =c[ÞO—ÝMõóéý-e8Þéi®Ÿ§ëþgçï…l/ˆú·Ã/ˆß|Gð‹ÃÚ‰¤ÜÙZYGkªj7—›o™5ä?Ùé%²F[扈’£8à5ÿÛ¿ã›<Ö:wìùáÙ¯’úæÅþÝâ ëhâH£gŽô‘§<‚Úèä3"3r ŒPè©iÛêßçwó±•/uZZÿÿø åæ~SÛþÚ?úâøöéøåáÍ'HÐþ'|)‡ÄW’K•Ÿˆ-¤¼•õK–’1Or-¼éçÈ”,$–0O×*+XM-ÕÕÿ¥åoÏ{•VW‹QѽŸoø~¿…Éß ~Ý¿•¶ê¿  ñ6­w5°UŠòâÖÂ9<«_2Ö Ø™#™Œò°Iä—& 0Ê7½'¿¶ßuo?¾+x‹àņ‡âM9m´;FúÿíjŽ& ÏöÝ] …äØNç^qú3E:µ“²µíò×õZ~;™(Ù-{ü¿§úŸZßüÆvGÅZOÀ3Z±ÓVÐ8åíÿñn×Å$ÐàøkâÝ.¤¶¹›Ä†+ë›×­²#iðZ¤J–¨“\&<ø÷°þ™øwá·Ãßë÷ˆ|+à øo]Õ.$ºÔo,tø šúgbÏ$ŒŠ ³1,ÄòX’rNk¶¤åV’Õ¯¹ùµ.{ßM4ôïëÿ Òß¾ý²¼i®|&ñ¿Æø"=/K´ÔôĶÒfÑõ+;í.ÂêÖ't¯»¸’NLh¨€yKû;~Ú/ñw[ŸAøðãTø55ž>’ׯ$–ú´×¶ÒÍöxähФј& ÉÀ }†7ŽGû¶¢–'hZhb™£22Ê FÁ†z3îhæå¦ö·••Ÿ­÷ר8{×OM~öî¾å¥´ºó?,uoø(OÅ -t»éÿf­JßLºD¬—·R\é"©Ó.’GXîÑDÎȬÀ*£gíê> þÒŸçý>|d‡LÓ~x“QÔ5'“EÐu!¨ ›HôFh¢yï4ÂÐËçÃ+nÀIµ”1Fý+¢°¢¥9IÝi¥¾ÿë¥ú.¤y¹¹t×O¿òºóÐüƒöòø‹}â AÐþ é²Áu®Ï¢Ms­jƒiïmz°J“°ÒÚ#4Öå®íV"Ë:!denвÿ‚’üQGÑïõ¿ÙŠâæþâÖk™íô^æüY£Ûê®%³‚}¡¦š)8dµ³ Έ߮TV²w½¿­?ÏQFqQµµïó.Ëä~I\ÿÁF~-ÙZøËQŸök°ÔôßY[Üê#J×/n.õ“ìN·zl3ið¦£hc¸¹ÃÇ(‘ä²x­ã»•¼µõßÚcöÔø‡ðFûÅ ø~#^Øé¢îÚÚïQ¼°{ÐÚuÍÚ\æ+)ȵ@–nê¯"ÏqÙ’ªÿ¢UsFÉ[müôÿ=tûŒæô÷tüL_ ÝkÞÑ/|Ci¦Xk³ZE-äS¼öðÌTXätFu 3"’9 t­ª(©“»º&)¥fQEHŠ( Š( Š( ¼çRøÁð«Gø›á¯‚Ú·Äoißu:çWÒ|36¥ jz••¹Q5ÄVå¼ÇŽ2ë¹€ f½¸»ï‡u?h_uø.ÿân—cs¥éž"ŸK‚MON³‘§·†ä¯›Rã.ŠÁXÆ„ƒn¯¶¿“·ãkù\Úo§æ¯ø^Þv<;Pø¥ûÁi¯ëº§Œg˜ìšêâ=Rîiì65ŵÍÂÏç9à´3ÙÝy…îÚÖrÛ|·# ÓõÙr]3Xñ—ÁgÒôeK«Û˜-¬öéÀK*+± ò~öÔ»ãAãþÇ_ 5»ßk^>ñ×uïßëw7~¸ŸNŽ16œÚwØ<‰®. bì% µZi¥¹D†FR½…û%ü Ð|-ñ?ÂÚ7мm‡.Ÿrùé¯Þ–›…?hŸØßÿüIáßë_| âé-¿².µÛLŽÿû>wCbŒåO³Étø|°n+,+Ùli:Žã}j×â„΅ỵ-wP’.ÓK¶v™’LàFky•¾l©ƒm¯ñgìMû?x‡Zñ&§¨ø¯âw¨Ï-äðXx•­ZÜÉu ãùE@–0g·I>VÜàSŠ¥ð‹À²‡Âë­cà÷…:x  ø„Iu©ê: ŒñÞ\j\\G wsÍz%û<‘2Cž ÆPÒ‡fÍvÿb?ø¯Iñ$Þñw‰|3ã[Ý>þÆ+û¶û]·úDæqç@†&•c’¡dC‚U‹)*s©{Edz¿¯D¼´jþw¶Ôrj¦š«…îßž©ÚÝ×fz>û^þν힗ñ‡áÖ§f’êÓ^²¹YÊ´«$kS4û£0˸4` ’¬öÐý“":$z‡íðƒB½Ô¡·žÆÏT×`±»¹YäX¢Ûì’îy.ÝÛF2ÀÐ?à_ ÃþÓ¾"ëï5]-!Xg‚8,c‰¢•åŽHÄqïŠeyùèë1bX¾âMzO…?b„þ Õ­õm\ø“G«Úk¢ÕÃÄ÷°Ù#™`V8Ô¡;qÀ±:ÒI4ª>®öí}­·]Ýî7$ÜšVÑ[^½àwòØú"?‰?æ×5¯ Åã? ?ˆ4ëS{h/Í´€c28ÏÊ£räž›†q‘^s?íQû5ÚÛKywñãá5¤hòI$Úõ´kEÜÛ‹8ÚBüØ8;yéÍf\~Ë? ï>!üBø™{/Œ/|Aâ}*]SIuii&ÂR,üð€È¬¡l•sgɼSû xÿÃúì^ñgcñ•Ý·ö¦¹&¦%¸³VK;©UгÉ3*ítSι8ɾFÖöünïÛ¥­Ýé¢ÔÖ*<öoOøo_>û-ÏU“öÈý“aѵ_Ü~Ò-´ ŽKëÙ|MfY+†(ev,a‚67§+ñ7í½û7ø[Áš·o¾%xFòÚݧX,¬õÝ:{­KÊ+»È s±ÌÖuUñV°Ç‚äñf±â/k·±Ï¢®—öK5¶£4Ï:Osss7œÐLîÑ¢¡Kx™# ›˜ä|MÿõÐuïŠ7ž2´ø•®iž¿7jÚq³Šk«É'•$˜-Ä™X•Œi·djɃ†äÕJ/–ÉûÎþ‰ôó¶÷ÓªÓs7tÒÓK÷óû¿G©ôw‡?jÿ€^3Ò5gÁÿ<5â{m?B‹Äwmy†ÞÅøW{‡e¶Sœ‚QŒàsZ¾ý§?g¿i~(Õü%ñ£áˆ-4(Äšñ²×­.F‰Â’.)c#rƒ“ŽG<ŠäôoÙ#ᆇ ³Ô¼pçÄÚShú³É¨‚Ó@z2áG€Àt<äóXÞý|ðÃÃ~3Ó>júœ:¶«£O¢¡ñ#>©e Ríݾx^@vŒ"ŸqÍ[k–O­½nì½-oÄÆš«Í+ZêïÊÊïï¿üÔuÚ?à‘$QjŸ>iÒ9 ‚mbÜÇneºÊ@êA©¼?ûCüñf«â Ãþøƒ\ÒmÿT³³Ö­åŸM¶lí–dV-¶Ó‚Àgàº?ì ð'KÐt½müCkåØéö÷†ÊúH–öæÍH¶¹&C$¡¡ÜÂ52 B°|W¡øCöOøgàß øóÁ–š§µmÄvðÁ©=ö°ò\f0vKÊÑÁ9È8ÈqSQYË—]íçÛüßÝæºi¸¸®mô¿–×ûµKïò6ïjßÙ—L¶kÝOãÿ 2Ñb3´·>!µ‰UQÉg?2ðyù—ŽEs·¶Ÿì±nÒAÇO†w:‹dY[jÚÜêÎ!óŠ[<î‘ND1(åWøŠ×3©~ÿõ«©ïõkân³¨Möi§¸¼ÖÚy%»Qc»Ë©Û.ØÕNݨpIRÄš±£þÅ t)ç¸Ó¼Añ) ¶w6.²j‰"˜ç‡É€Ñœ1Nã¡äV‰BÎ÷¿ë§ü¾O«J—/*ï×·—ãküí²o{Á¶Wìåãk Zâ?Š^ ðæ©§4£RÒõfÈ]éÂ?¼ò¬3Hª÷+ŽõoAý°?g/YÜk:gÅoÿÂ-FQ«\jVð[ˇt!VG<·o3ËòÊ©*ç}¬þÁ?5í&].ÿSø˜öqc ݾºð\[YÅíU£Q˜Ü»Ü²x`½¿ìð6ËI´Ðì5O‰ö:U½£iöÑG®·î-ÌJ“"2Ë"‘!n †U`G–úíÿ ÿåýåú[ñþ¶=Û´ìÿñÏÅz‡€þ5|.ñ­Ž„æ-bm'\¶»M5ÃmÛ)ÈC»åÁç êöZ.§}ñ TðÔš½ö´º=ö®otø§»ŠXî[Ü+ÆÐ¸ž\ÂÁ£ùöíØ§ÂïØ»àïÁÏ ø§Á½ø‹¦øgVÒŸI–5ùä’Ù/-åŠb|á+w3¶Ó÷ ŠSå»å½º}Û}ã§{{ûÝ}Ý_¯—㥞ž•û\ü*ñÄíá†\ñL×ßeû>³§µ¤Úkyñܺüâ4m&V^CÆk°Õÿi¿ÙãAº»²Ö¾6|1Òï ™­åŠ}ft,ŒF g…ŠSžŸº“û­øSûü ø/â#ÄžŸÇv7vW‹{3jbX†ºll)€¹¼œàcï/eZ×?`¿Ù·ÅšV½ øËÂÚÏ‹ô;á +i}ªO²ÊÒ)neKHŒl­ä†»¹\±d™£bS ò«rëßï_¥þãžÙÁ¹YK§Uú?^×êz}ßíMû6ØjºÆ…}ñßá5¦·§À×7ÖrëÖË=¬@Æ :Ü£3DG>jcï ò¶×ì³'‡¼a¯øKãÉ’hºuÞ¥uaá¯Xß]H–öÿh‘,ÁùeN”|é’7 æ›»9kµx6›4I±ºg&0€A.˜å Ùø³ö›øàßé^Õþ+ü9_ÞEauŠ|Ca é³»œÃowåM21‰ä ªË’å r¯ñì)á}bÿÃw>øãÚ=fêûZŽæågmBÒæ=Kíñ0UòäÔ¥;ðÛQvª©Øéê>>ý”~xÞ µ‹Pñ/Øô[k(`˜KC¥ÜIsd|¬ʳJY×xó$ ©8­Rê¾ëëó¶ÚêôvµÞµãZ“ÖÏWµöZ+»^íïek_bÿí¹û/iºìzE߯?-›ØÜÞ®¦º½«Ú³A°Ën6Èd3*Iì ÊË ,öï|Sø}ñKN¯€Q¸a´;€ÌZ´žÚþMþ.Ëç}‡Ñ¿ëÓ—sã¤ÿ‚dxWþޱñFoŒ2}BïÄâ/²ÅiDÍqw,–þ\l°É«uåȲFÀ˜c¸AÒ­ÊåØÁ.ŠMÒ}4NÛ=U­~ñO^—w‹m;9þîj+Uw¯g{ß¿¼Ûû½ä½ÛùÇÄø%Ç‚~!Ol³üL½ðž”š‰ÔËAðÝ…„M˜4ر¨QMEòðSçnèâd§?üËÂfÓP6.4Ívå$·¸Ôãð½ƒO{m%ŒöåÁ2¾Ó3ÛUa/‚²®Aó|(ý»¼añÄÞñ×þ!h–º\:&ŸöÛ_j¶šv¡oér^N· aÍ#¤7©A²B×7p£É’/døOû=~Ü~ø‡ðûZø‹ñ¦ûZð]ž­}u¬YÅñk£p<è|‰Do¡Ä%†X#5‹:f)q)íaß$£8»suíÓ^»i¥í³²½ŠÍ¯züÍzúõó×Õw²=[ãì#ðƒãWÇüo×¼Wâ½Çz5¥´wZ~›-´všêGæÄ­{DÏ2{›ûm…‚ywÓ<ÅŠHügQÿ‚[xGPðÿƒáhOk¦Ê×·0O†l…Ö›wp·è×òË6E¾! WÊ^NæœÕ¿cßÚûGøãˆ>"xj ›OPº²š÷â.¸wos}m(Šâg*¤qÛ¥Ä) ;FŒË${å=áŸìëû]xÀ?lüaãí2ãâgˆ|;™¡j°üKÖïRÂê+«÷Œþúɦ!¹LðÆÒ¹‡çµXí„ÅTt!QË–I^Û´Ûz_Ê÷ü‘Ï <^!»lùT»­ýßß¹ì?¿e­?Ä¿µ/‹ÇÆ>Òõ¹c†·Õ|?oug#‹;»@%ó[2odãý…^A5çÿ`_ ~пí~#ø«â•ÕͶ“m£ê:h—ZuØH¦SçBç. ›z,…ŒeÒ8o$›ö`ý½ïu-rÖ÷ã6–t*š8oˆš„ñÇmý£4¦á“I2É*Û˜¹ûIrU£*yÀéÿ±GíÛà»K§øyñwBÑu ¾Ío·âv°dÖmcûQ›t×:]Á†âc%¾.6K$YTº¯Ì®åg²Z_î·ãýhˆ-)I]^ÎÛtwÓu¢óî·KíOÿ±~™ðKÇö¾5Ó|{6³iÚZÑ-`û7ÄaŽdùÒÙ¤…`Ç$Ùi«éRjsh‰©éï¬Ç¸’ÐL¦dˆœ)ÁIã8Å|á¿€_´ö‰ð›ÆšßÅí_Uøy¯i³Ay}ãKÛϵhEl³Z}¡là3ÎVçtöÖùÌ‹ ÇËu¼û8||ð—¾;\·ŠtmOã>»ºèzÍÇ‹õ&$E¸ÇólÚ…#- ry›<ÇRÌE/f¢ùo¢·žúþ×îF¶í­ÿM:÷¶Ÿ{?Ag¸‚Ö..§ŠÚÝç’F ª=I< z:H‹$n²FÀ2°9 =E~zx+àíq>™ñ2Ç⇌¼ ªXëž½Ó­´Ãâ}GTMÕîV£ž[XG’ uWf·iw¢à•>%ìÃÿÓ4= ÂÚÆOizU–•u§Çz¿õi®ãi-bDb³il“˜HêX«¢ªà`-r{Í7Ûó’u“ôdF¥ÚÑ«ßôùëwÓ¡úõE~süaø-ûlx¦Ûà}¿€>&x3F“KÒÓÆEâÝ_JþÔ¸,‚V…µË8(«Ë'š¬F«Tß>þÑ>øË¦é^,ø—ã=WÀúvˆòjPÞjZ¦§osx\}Ã}rb ¦h¼·Ïî÷H0£«^¿‡ùôý7)ÊË俇è\wv³O=´W0Ksß65pZ<ôÈê3Ž3S×ä3þÌ_·uŽ»ñÅ7‰þ/‰õ›˜£–ø|M×-›RáWEÓ[’DÙ E“*ß:õ>¹û<üøçàŸŠúмsãy| ¥è—2jV— Öõ[[­Nk©»[_^´fTHL‘ˆÜ$Š€8AÖT’Ô®ÿà]ï¯d´Ýëk;o:ikëEnÝ},·Úÿ£´WçWÁÙëö§øâ½üEñRàë#t±À|_ªkžd2ØG$w°¯šûäüÆrÈb’ ÄÞþÏ·f­iy?ü-ÂZ̶wqD–_u{Ëx5;ïó-Š T6›LQ7ÌŒÄdÄ’çqONÿÕþ~{]jG+ëýy|ûíݧ¡ú—Ua¾²¹žêÖÞòÖ{¨Æ’hI€år=kòÆ?Ù»öò²M X|lÑŒ–÷QÉi{ã½bè^34 ²¤±¸)2–‘n$€,j~jë> þÍ´Ž‡ñoÁ¿>*j^ mF\ë0èþ>Ö.Ú›V…Z@ÖP%ñ+µn2AR0u(´ß7õÓúéÔÖT’Mó#ô’êîÒÆº¾º·³¶\’W«“’xä?"»µžk‹xn­æ¸„,jà´DŒÀr29æ¿5/?e¿Úõ¼CñMŸöŒÓüEà+é7øcI¸Ôµk{« ]#/Ú.L³+pBB ÈW äcüýšiÿž8>;¶O x²#c%¾£§Iñ?Y¼}h¤-Ì{fUä[÷’ȸPÌ0¢(Â2ƒ”Ÿo믥÷èYµ'oÇoÑ»y«vgêÅÝ­¢¤—w6ö¨ÌLŽ3€g¹ô©e–8c’i¤H¢E,îÇ@ä’OA_›_ÿfïÚ{ãŸUµñõ–àñ]>ˆž-¾²û@Ëuh-Ù$ŠU”­ÔÌpüã ò]7öQý¼<3¬ÌÚ?Å_ ø‚‰Ö}CYÔþ'ë¢ëTbhodtùmcTb l#~Á!ÚäŠÎÏ‘Éîº}ß.÷Õí¥Ö¦M+«=á«ÿ$ý$º©%úûÄPÇqm4W6î$‘°eqêàÔv÷–—žÙ.­®¼¹)<· å¸ê§î5ðÂÙïö’ðö™ãý/âoÄXõˆõ¯ Þé*m|oªÜ-Ëù‚) F·ˆZíW’®ÈÉ×iß±ßí‹á?êzwÃo‚¥ÔoÒ}R Š:¼u’\ÉÍÞ—?‘;+Dï/’í#FVBà–3^|½_Ÿ_먹W'5õ¾ÞVNÿ{·ÉŸ°TW¾þÕ>#ñ;ÿÂãM*ÛÃQèútV÷ÍãmGO»[„’?¶[=­µŸ‘(š4v[Ã"M9UGÌ>\“öWÿ‚’íx®]?ö–ÑßG½Óæ·°ûWŒµ9 ·²êb[ \ â»2ȲÇ3¤À,ˆHò÷£INVm-÷ò·ç}=íîóº_ÓñWü6õµºÛö>Šü¨Ñ?f¿Û¦æöîÿÆŸã¼½]VK¤5K{+˜ÄЙ-ãÓQí”Æ’«[<×( gÌrÌÕèð~Ï_´ö•ð—ào€ô‰‰£êZ •í®ºãÆz­Ô·÷M$ k}öÙ¡ûEȈ$û­¥Î [ cÑß}?¿§«Õ¥v«“»ïúŸ ¾•«Á¥êš~¤m¦kko:ÉäL¿z6ÚNÖÁäV…~lj¿hƒ¿²'Äï†^ðt—~4¶ðEÍÖ®øÅÚ…Þ¥ªx‰ä˜µ·Ú£D,³)r¾c(ŒÁoÔ¾þß¾ðÕÖªŸõƒd4éÛB†Ûź注YjR]ZϧZÝÛµª5å´N²[ÜLóÅ#[K#;dMcNö×{}öª²õBP÷¹[·ùiÚý½¾û~ÐQ_ üTø%ûNkº/Ã#áÇÆãOÒ,ཿŸ\ºµo㹉î'uX¦‰q– ³Ü–Y/ó/ âÙ³ö«Oƒ_<-áOŒ:Çü, ÂÚ’ëw÷uXÿ¶¼A)µh™®^Îg–¶ñ7É #¥¼…T/Jû;[«ßUå§â¾Y§zŠÓwè´Z?7{Û²éfÿI HrI¨m®­¯mỳ¸‚îÖE±8d‘OBàŠü¬±ý›¿nÝ&SugñzÏV‰¡µ·š×Vø›ªÜ<ö¨426-.$I[ìú û\q$‡í1¶Ñ¸ˆ¹ï€¿²7íàø¼Ὲß,4ŸèÏ¢[>™áŠ:¡µ:mµ–Ç·Ž?ì˜& ³õv¸ÿIL4‚2bãI=ßõý>¥{{®Z·:wÒöë³üt·Í{—õîŠüØø½ðöËñÇň:…~$hþøS}ì¸->"k:uÜ{4÷Š2ÐÃdËûKï*b®±£2³dWè‡áÕmô-ß]’ u¤µ‰.Ú)LˆÓˆbªXg<•R}aMóG™éåý[Ô÷gʵóû¿ÏðfÅQLŠ( Š( Š( Š*­õäz}•ÝôÉu,0ÆÒ²Á Í#2B¢Î}‚Ià MÛV4®ì‹TWŸü4ø•áïŠÞOøffßOûmö,7Ö­o<6·2[O)êVXr¤©ÆA"¾yð÷íÕðÄúŽ¥¢éw¾1MnÔOæY]h³[LÆnM`«(]Þ]ìe¾ê£E)>\‘»>ª=^Þz7§É7è® 5'²v~M»%êÞžº?i^-ÿ‚ŽOñŸÄú6¹ð¿Å–ßW¸}Uµºð³Ë[©„)tèÈté-âBÍ_nG¹„ø—ËηÕॺ¯‡ážÄž×&Ò즎ßQ‹Ã=¶ K®¥ Íï– Fö$’Âè}— ~Ö¿³Ç‰¼o£ü9Ò>+x2çÆ7¢X’Íu(ÃyvR5ƒ²¹U»òõGd»$»€ ^•/Åß„ðk—~ŸâÃÈ|KÌVséÏ­[ ˜n$ c‰£/½]±U#'iÀ85s„¢ÕÕ¶ùÛ®»Þêýôï­)ï¦ÿ†·ÿ5éuÓOÎ/Kÿñg†uùeRñ‰n¯‡ñŽåÒR2§ô^Žÿîo#Ó­þ2ü)ŸP{9uxrûúf¹ñ—ᆛªjóØÛév²k–Þv¡%Ü‹¨‰îq+º„ Û† b©K™(·}—í§ž«OŸÉ΢·¼¬“¿Ü¿Éê|¦ø³öÜøƒû7|ø‹ðÛZ×¼EñkûSY¹Õlöh0XÝÛ½­âØÃs c ÌHÖ›§²u2á,Íë;¤épñ1û±¶6?Ƶöž‰ñÇàωu­GÚÅ_‡Ú¯ˆ-5y´ ìaÕàiÓRŠ8ä’ÓfíÆTYc,€7ŒÕ­_ã7ÁÿÝ^Øëßþh—¶×Ieq æ»k ÁpêYauw]”ò@'µf§{+)-=¶ü,õÑïªòƒŒ›úoñoéwµ¬ÒÓCãƒ7·m·Ä¹t/‰vº»ü8°Ñîc°¿Ôl4'Mfçuȉîf²¼Y¡”b× ¯”È_qVå~rø‘à?ø)Ä‹]ßSÕ~*趯mh'·ðõ׆-†ª."’âãt¯ºkXÄl-%™de¸ŽN6þ¯‹ LÕõ±ñ+À £iñ¼·÷cY¶òlQdxÙ¥}ûcãt%ˆ‘‡PEr÷ÿ´wìû¦ZéW×ß>Ag-¤6RÿÂEhVéîf[„"O›Í”ˆÐŽŽ5œ¢çdõ{~7ûúS*q^--o—üá=ïþ UªøÚ-+ÄKâo x55 2ɯ,´o ÈfÓšæ=ñõar±-Á’gåâHšÌ­è~+xOöÅѾ'üRñŸÁ];ÅW—ÚƒEg¤]êRè“YÇvÌÈ¢6‘e[WŸMØŸqÊ•Lšû?Rý¢~i éª|pøEc*Ãqpc“ÄvaÌPfp¾fHqåïŠØÑ>3ü!ñ'‡G‹´/Š?õO y6· ±naŽ;„fÝ„ó]Ø,Åk6“KoÖÛýÎÞ¯¦ƒRq’¿Kiéùï¯ÈøßÅz§íÕ¡|ð¦§á¿øÓÆÿî1•¬Z>oc¢FðY‡a<–7 },wLÑ”*ob¶+"8ØÈT¯%øïð> !©Íñ—áL:qm‚á¼Ef#-…8ÜdÆpëÿ}/¨®Ç[ñŸƒü5¤[xƒÄ~,ðÖ ÎѬ7··ñAo1|l #°V-‘Œr1\T¡ËöZúßï{zmÔÖsmÛn¿×—_ÏCàOËÿ¶ðwÆýsÇqÜk>1ŠÖÒhðE¡Á Øódó§FOÚ<¡+q"C¼¶ÕÇOð‡‡¿oÿøBÇNð¿„>$ø{P˜˜ïf×ïü56¥,L÷d7Úb¸¸‰7ÂÀy,§„0 £#ý¤þxWF½×µŒ_ Ö DhïäëVÒ»j%K-UrMÃ8‹ïœp*µŸí=û<Þx'Møˆß~XxFîÁµ(Ëh‚Àª­!`Ï•1îÁåIÁÁ­ëTn.mYhï¶Ëõ½ß¯bhÞqÞíï¯W·¦Ëµ»Üüõ×>þݾ-ðŸöOˆ/¾3j“ W³ŽKÙü)m{hëµÇ5”‹ºI%VÆï“A5«â ÿà¥/moáTÓ>(]Á,k?ü$:+x> ˆcC‘ «s(Q;ànòâ1c8eâ¿K×âŸÃ7ŠÚoøX~ TšÖ Ø·ê°){y—tR€[;]ySÐŽ”Ýâ·Âï^ÙiÞø“àj7+¾Þ bÞy']¥²ŠŽK  œŽÀšªS”$´¿/F¿5ÞûýÏM5S†‰4ﯯõ¡ù½+ÁG,t«û x[SÐ#ŽX—Nƒ‘ÞÕæ&âI‹Ü2-Ò‚ A\ÂW;Æî+× ÑüQy§Íw¨Å,’4×>m¬SÄÍpªÀ;‚1X7úÿü›H²ŽêøÅÌó%¶±ÿ„f+ˆ$/2¡žâ(šÙWÌ#,fç[Šý·øÓð’kvšo‰^°‘ݧ†ãYµI-LØò–Aæ|…ó…¯lÔ–þj‡n™ñcᮢßh{LA®ÚÉûõRÍÊÿ|($¯P8ª•Fç)Ûw{tKk.ËçúÓš¬¾þº·wçþGÊOyûfØ|2øAæéÞ:×|q¨ê7-â¶¶ÃQ_h ¾m”Æó G´”Å$·;YJlãÀ¯nÿà©—~)ŽâÒÓV°ð‚ qn–þ3µÃ,K$r³Íþ¡Ìñ´¼Ú¨¹ÈoÓK‹? -4½\ºø—ðþÛEÔ·gÞI¬Û,ø )Ëí“”¤òÃÖ¼ÃÆµ·ì÷à.¡ñ7Äÿ Ú\¦M¼1êK. ª#iZG,ëÊ!Àؤ±àfœª®iI¥­Ýº/ø údªr”T#é~»ßïv·¥ÑùµãO‡ðQoü*‘~7DÞØÙ Õï|#£kj 2\_ ›ö´ÂpGÜ+´™K1íoìà§Q[ZxF+¯ˆ7š!Ž‹^°‡RŠÚ6‹÷S‰›ÊnMÆ(Ú IÃ)û¿¦6> êé²Ù|Yøit—–©}iåë¶­ö›g8YS|ÈI0È'½S¶øùð:ò][|bøa-Ÿ‡^õ鯻kåhÍ,bH„ï¿l[Ñ•—qF#ß”§Ëm¯o-5ù½|ßÈËW'~××{?žÇç«ÿÁImí/tý+ÃZŸ†”k3ý™¶xvfŸJf—2Ë›†U½ ä²m>IŸrá~øø¨üXXèÿt?§‹m‘„Úµ÷öbDo`¤¥ŒÌ‹&аˆŸ0Ç9¢‹ãOÁÉ䵊‹? æ–uáT×­I™eRÑþ`ê¬T¼‘œTŸ> j¼:‡Æ/…—ºôŽbŽÊÚ=ø ÅDbMÄ€¬qŽŠ} O7K 4¬–¯üÏS¢¼;\ý§?g ZÝÞëß> iVðZ5ü¦oY)Kep6<Ìì BîÆ2qÖµîþ=ü°ñ%σõ‹tïCge¨Kcs¬AÑÛÝ3-´…Y‡”`ŸÞÚqš”›Ûúþ¬Í’ÑžµEpÚ÷Äÿ†¾¸»´ñGÄ?xrîÞÙogŠÿV··x-˰wP³ñ’yªšWÅï„úìwShŸþk1A —5¦µm0Š$‰%wm®p«‘¹'€®Œx ™oFú"¬ïcÑ(¯›¼û\þÏ¢Ôæð'Å x¥-^Ë?e¿€™àºHž˜÷8ó e•‘r:’1]UŸí ð_Vñ_„|á߉ñgˆu¿µ›tJ ÍËoĬÞS’ª¬ ’xÜ õ«”t’± J×=žŠò‹?uey4¿Œÿ 5$[ÆÓÙ­üEg JÚ¶CûÀŒ¬Sï`qƒ\ÿ…?jOÙ§Çz¦±¢x+öƒø+âÝ_OÿÛ}7ÅW/mû´î !ÆHØú\õ?×ê]Ÿõ÷~zïErú¯ü¡ßÃ¥k~/ð¾ªK ÜÇmu¨E²DÒ¬K V`J™0Y•z+ MøÁð—YŸM¶Ñþ)|:Õno\Eg¶·m+]¹y,a\—;¢•p3ÌN:©ÀµîÏE¢Š(¢Š(¢Š(¢Š(ª:¤÷úuý¶¥{£ÜM ÅݲÆÒÛ1 Jeê«.G Ž*õšº°Ó³¹ã ¾ h´ÿìÏ kZ´:+ͨjöBÒÂÞÚÿPºf–õ’ÞÞ1›ƒñ—¤wG‡¡~dz?Š>&]~Ó^MfçÆÚ®­}®&¯i©³Bd¸Ó#Ó%‰#`cò6À³y,¥Ò™ð_šûbE.Ž€àF}+ò[Jÿ‚dxƒIñ߇¼SÇm}ßW“Y¾Ñ“ú¥¤W—­©O|·àÚë1¯Û}½¸’T–&¶†H¤†Dë•=–Vùu^–Z/$´KD¦ÔµÙ¶ß]{ë»m»ú¶üý~ãö/øQðÞ_ëzÏÇ‹š]•–§¡XéÂùôo.[´¹ÐÒÞ <n&ÑìÑ€ “q0O/1ù]/?`?„ßþ Ëñ#]ñ/‹$Öeñ Lj&·—JÐo-¤y °È w§JP#é–sG:2Ý$‘³„;ÏZOüñ4ákc{ñáþ¹áøt_Ø+Ÿ êÕ͕ż÷^lO«µ«ÚÝÉm€Ì³<²‰Cì¥ðöC×~\üm¾Ð®üE¨¤þ´Ðü=e©^@‘Üj eWš”/4ÖñÝ4ø¼©%&3§³(S+¼»WÄIÆnNí'kuWZmÖËôZ3¦ܱŒ­g§OŸNîþ]QçÁ+ü ¬ÏªøS^ø‡ãóðÞÂÏOo ÊntíGQÒu[UÌì·Út°´q.¦É»y–Ék‘倇߼5ûx+áæ¥߇¾4üXðÞœuÝ+[µÓ"A†Ò ëqo‰ 4㺎Ú(å‚2#P -ß>;øeÿÙø¬xÃWßúÖHå¶•Ñ®Òð‰^ãÈ’‰ KæÛ¼QýÑi9ï~À~;ñ¯Åøíþ=xoFðÄ—/s£éV¾ “í÷NÆâY5¶½ÃÅ&ÐÖ¨™¿ˆo<´%üß-“_àÒ7K½Ýöívõ:êb*CÚ:zëuýíõ×n›þˆô{¿Ù7\Oƒ´¯„ôÍCñçÄJêðí®,4¥*±Æ"Àé;^w y×­’íÊÃÿÖø_±>¹ůú|ÓH÷k º3Aò_é] i¥×|ç,¡‚Œ(<×¥ë_³Ž¢øÏñgãM·4]{JÖü+y Ûøa4‚ãs¬&2×fôE.׉±º LÀ:òOÄž ÿ‚[xÊ_i××Åøb}Cæ í´-JH<;©Kcoo+Y­¾¶¶Ëùr™Õã˜ÌòoY# –Šk™$ôJß-²¶úF?zìoÍoµÖýuzjý9žúÚö½Ùô>ÿÄø/áÈ4¸ôß|Nµ¹´·†Õ.-¬<=k$±Å4Ædò4´ û4e`duA½˜ó]®›ûxgà ~2xS¾,ñÅK¯iözf®|UªE ”ïoÙÚícÓm¢†–^dxbBïgoÈ'ü'ÆZïˆþ%ø‚ãÄž øG¦Üx¾fÓô+M÷ìÞƒ‹"¿l];X·y%Sßg;ÐAæÑH +zkÁ6/ü)ð~™*ê>c/Ãy$™ä¸’íñ]Q˜}²_0•&Lòs§V^Í.kó%uê”Þú7ªZÝ_Cš()9í+ýí;~‰ßf­¹×j?°Çìåñ'P¾ð…¿ÅˆW(ð“YÝ\%íœ×š.ªö-n5k‹i]¦ž ìÂc$nÛ›nwgØ¢ýþøHør[ÄÞ<ÕôÝDfáíÖ,>Ö—9×ìê¼Ø—ç…blÁ9å¿gOÙCâçì÷5õ—ü.O|DÐõq®´÷~»¶»KHb»%»Ba¹^â w‚<¸J€ ž#¡Á/ ³¼Õµ|Uð·‰üEq&èu'ð„ËsfnüµG}AÈÚ÷°Æî$2N!%'8¾g§•ß_ºï}:øiTå„%]I=tŠÖËÏšËn÷vÕ{ÿÃýŸ&Ò5ý'Oñ?Æm3ûGY´×dž]|j-mqÒÊ‚¾ŠxàLÈ¢ü°ÂzzþÆú5ï‚< ào|Wøâ{/ ±·ðÝäöúj\XiÆÁ,^Ê@–¢…h•É‘ãóHÅYp¸ðþ ½ýŸá+ %þ3^hž ›G¾—BÒf†ÆöðÈðKÛ»«¨ÚiJíïèÖ¿­ÔöðCà-‡Áý'áñÅ>ðì/ŽÊÚþÕôátº¦.žwY˜NAUÃGæ>|ó\‰?à˜_ üX4xu¿¥²±»°[E6‹BP°¨S£àØ¿Ážø‰oñ#Iøñ6]A®'¾Ô¬t´³Ö/%‹Êk‰DvK*6ÁŒC$Ižvæ¾rÕà›:¶¥§êJ|lÒ­l$[t³|/(K‚7fkHP_ ¶Ó>lyùÈR ã¶ñWìâ_|>øaà7øé;é~Ôšê}2m.ö îÜÊΩ:µÌ2G•Øíu,`©ÌL¤¥f£+ÉîÿîßmÛÓ«[ìeEF×Ñtù%§¯*[–7E ¸Qm%­Þ™i,@ðíÝŠ#!òÐ˾(»Ñ€ÁÏø'mûøfkø_µ¿ŠJ¹Óä¼¶Ñ|‹[©šãη¸–%¸ó³Ý\Gº7e21ëšoì«â¯€ºŸìßâÏø[þdÓ--ô{ýÂø^i×hâG—þ&7·Œñï"I+„«3Š#&©»o¦ô³×É$•ûîµ&n“·ådî¿ï§Gä­wöøA⿾ø â}cÇw>Ò.~Ù§¤Ý[è„óle%›J‚Ú$ Hb±ÆŠ^4b>Q^UâÿÙÛöhðâkšæ£ñïÇ´½}/HÔÙïôæŠÍÚ;[{x&’îÎG-1Ž™˜³<‡ 79è?à›séº>—£éÿ|Kª5¾—&š·Ú¾”“]Z·›#¤ð4±HO%‰ º% ÇsÞ;ÿ‚fjž(Ò!ðΉñWán…á#s¥\M¥Üü;–îÝÑí\Í MSÈmØy§~¸ÚØ%º©rʳS•£&®ü®¯t¯´oßî"z‘§´imÚúÙ|íØõM_þ ùð‚ÂÚæêŠ´¶–ò»k¸N˜ÓY_ ¬ÑæÁ“¤(¥]>I+œ=·ì³cÂoˆ_ >ühñ_‹õ÷ÔôHoî¼Dúní6{`vp-ôàžk¤y!¢h÷T éåŸðKˆ-tŸŠz„?hÏx~ãÄ3[˦É=‚N<'åÈ>k3±H²U",ÒJ Y‰Î§„ÿàžþ?ðÄ |F´øËðæêûIy¯mtËo jºeˆÔ<·Xîü»mh#Jìçíd™&P¸HÙC‰¥5 (ɨèöÖñPåêöµ·Ú1Ù$dß4®ã¯}:ó_ñ³ë¼·mš:ïüOÁö/aáxö÷O¼K>âÇSÕ-í Ò-"’9{9l¬£»YÙ£Æß=">t¹NÃÛÜÁ9~Ü?޼oñ6+ ~îþîöÚ5Ò”!º–æIQ$>nÜÝHçc€¹$î-Gâ÷ìEâÿŒ,¾.ß|[ðptk.åôß\É·ÊR9 òí* #e;’0¥‰!–Ìß±Šbðàý/ãp{h|LúõÆ‹«hÿÃMní){lEÌsCù Åþ’ËF„!Æ+N<¶ìúzþ‹^ý ዪԓnÒÕß«²Õùôù\ó¿ Á:¿fïøbË]ð‡Åïˆ:Η7©£ZxvÍn¦¶’䬨¶ÒÒ?0Iq#3*ì ¾ì¾ï¡~)~ž ø·â‡ñ?ˆþ$üSeðáðÅÖ›Ó å£Ã$7êöm ’hœ+uUò¢¡._æ?à™šþ…¡Yè~øÏðÿÂqZ oQh¼7üL¯å%3·—ª# PÆÏ¸’¬Cn,Oø'Å_øN%ðÝŸˆ|?¡x^ÓÃPiöÞ&µ²¸ŠÞþùšÚ[©å¶MT]0à1½»1]’K"܉%§ZsJSø´ßÑ»õµž‰o­×S*T)Âïdï·ª^[­[ògÜ¿¿aßüCñöãÛω¿ô7°³´±´Ò¬›J’Ê šÊUÀ¹±–Q¹¬!݉9|H*±ç‡>ø×Æ^#Úõ­Ï†¬|#g+êæ¾µ†2­}spÅmã«$%â- ­°-ò…V\þË^%ñ'­à‡|GðãSø{¢j4ú:¦‹¨\JöÖ°§ÆóP™ÝÚmæ7y$ÙUq+ççÝ+þ ÷¬xsÇ_ omüm¬jÙ÷q«j¶V°ZØÝØÇk }’âÚi¥–Iî. ´ºi¢ØCZº–_5üÆßÅN÷‹mz¦®ß•Ûi«ÛW¾‡L+ÍEE»hžéçk-{ú3¢oØŸà…‡ÄO hºïí)ñ‹Pø›§XG¨G ìúwöæ]2%žULEl¾yy€¦ÏTðgì—ðËöt¼Ð¾!Z|Vø“iáïÚ[™ì/†—ö+ûˆ¬c°K‰6+*ÊÑG yvÍlê¤DYŽï™,à˜~ ŠãCÕ|kñwá÷ĸ´‹ÛmRÛH‡†;[©a¸yÙ<¹µG ždJ”T‘•ù«{_‚¿bÝJOÙþ/†Þ%ñ†®·Ww0]M¥ø†ÒÓW´ŠÚØfµµºHÂý¦K{h"¶¬¼ìóÌl–¯¬Õ©Eª’÷“Ñ%§“éµß}¯¥ÑÈ’^D½Ë%Ú·­šõ¶¶gáÿø'χ>!øÁ:׌þ.üFÑ ë)¢è²YêöÖÚ† °_ÜÿdÙE`†ìmbÇ(žÜܤ¯äŠX;“̵ø%¦¬“j—Þøß x{Sº]ZèˇµX-BæîòhåÛg­[ù‘®’Úâ)K™¡¶„FöÅP§Ñ^.ý|Iâ… þè´_§†´™t×¹‹B½ºY™®l¦SŸ©4ÐÆ‚Ñ$³NÄH¹“ä!ñŸ¹IÆ–×R·šºZùt}o²* ÎJu4v’¿”¬ÚÓ»û­¡±ñ;öD‡ãŒ? ¼=ñ—Ä—?ôÃú¶•¬x‡Ï:f­â?·Z}–h%‚Î8í„ —.ÜZÛ:"”P°ý>XüEðßÅ%ø‡ñM¼[g¨ZêWî§LHµù­Ñ#·7(,°» þãÉ-½‹–`¥|_ø&玵 #ÁšV¹ñçÁ:´ºm†©eyvžÔm&Õ'žà‡S[ë(}å¡[™eY#¸vÅoógŠ?à™Þ$Õ%¸o üyѼ#¦›I,WG·ð­Çö]Õ»kR6óDšŠÊ±œË}’kc"ÌÞq”$IÍi©-Ö©ö÷¯òï¢í}MkF3\²wN÷^©_O;[ײÔý_7V¢å,šæxÈdX‹ì€€X¸ŸqS×çÏÄ/ØY|aâ¿…Þ1Ó|gá kïxJËÂ7vº¿†¦Õ"×- ¹y2É-èœÛ¾ç-’LL‰m!rbe—ê€ÿ î> |:Ðüuâ8¼a-µ¥©Õäµ’;íSɵ†qy$“J×b,Ò’¹A©fªi8ÉÉ٦컮f“ò¼líÓTc)IJÖÓOÆ7t®¼ôg³QE…Q@Q@Q@x.¿àÿן´OÃßxã‡tÙÎËÃú•—ˆ¼'‡c–óZÕdx¥ê_–ß«(1µ¼Ãœ¥=êŠKµÿ×ë§gfµH/£]ÿÎÿ§Ý¦Ìü¦›Wÿ‚”ZÝx÷W:u*÷[]H¶‡ÂAsmöe, K%Á7š<™•—ç•·Œy‘Eá¾ÿ‡³h^:ø¡ãMCáv³ýŸ«x{H·¶û§á뫳¨ÚêÑÝLl®5´C&œöÏ“4 ×d Àˆ/í|lý n>.ižÔü¬GðæMP±»½¼ð~¸³˜Í樱L—RâáU¶´9ed+:•`¯¯Ô?m?Ú†ËZÔÛKø-?Ž|"°Ðþ'èÿô-gÃ2jzÝ¥¶“¦ÿk2=¼×—vÑIy=°j ÛáßµXêW>k-ÓAäê­¶’]K‹g—í)¯ïÔÄ%) ¯jøñëãmÇŽo­?h›{M ú½†–ž·Ó~ëºpMBkëèdŠ{«‰%]Þ\V¶D„¨“yùXcæÏ~ÖµÍïÆ(àÑþ|[Óü# øƒS³i"ð¶–¾š`¿.'W€ý£È’Ú)“ìÓ)œM b†êß5¬îÜŸdÒW]—M<ûõjû4¹¿º¾R»OÓ;«-wú?—¶ÍïÃO?ð—Mø†5£oáq™¡Fb³[©Mnâîh§àò_7QÁ(c òù ¾)â_ø)¦…¨éöz€üm㛽²ž[½Kþ+pðý¡ã¹Ö+¸ÉO!c•]¸’F0ÄhšŸíûgèzNµ­ß~ÏêE4–PAiàÊÑF·NƒUcSI<-,ÿd†&Ÿ÷¢%wuù½sâgíûQøOFð¾øiâ/Þh:n¡©Û[hºÅÕ´×SH‘ݬ2c’ÜZ†3®bIçO,L®‹[¾Ëæ•ý5åÕìïn¶*œ}îkí}/Ý¥êÖº=¬¯²¹óÇì¿üÁŸ|u¨üQð'Æ{?„:·ˆ.üO$:»xcT¸œ+O‰í7Új嬗íÌmâµ·t%%3óßèŒÞ4ý·o|Og/Àχ>7·ð–­¡A}k5ì^  ]µ…Û5½Üw‰q拃f§ËY‘H~YCÿüeý§ô |×#ðQ¾ø®xRýn_k²éÚ=ì×›¢’Ú7gâŽYÙ¥Y3¶UÞñ_íñßHƒá4?ÁíwPÖ5 ˬê|!¬I Ú„F ú˜ƒcÒH†ó;„{âwVøÌJ„ù&’q÷t×dÖ÷wÛOD’w³0¾úU#ªš[ùÛ_'®­÷mí¥/ÙÿÇ¿¶=ž­®ÞþÒß ¼aÅÖ•¥ØéºM¶yma$« Éx—–÷‹=ijËç4Ö¶ì<¼ÇÜòÍÿÕ¼o©xj÷Ã÷— '¾Ô@½±´ÐÞK»O0yH¶haÞ±=Ìžg–ìª F²'íIûcÞÜ^ù t+H†uŠÖö‡>$œêмq2Ï䣇µÚï$mïlÀX²†Âù/‚hßÛ¿Jð¬z‰¾x§ÄÒÞø.­ã—ÀÚò^xv æM¶—+ÿMÙ¼ÄHB,[$ÎêÍ®i(Ûeo-âµîõo¶éôO*˜¨E?6Ÿ]=Ù?’èÖéÙï©õÇÀX¾8|;ðˆü#­ü2ø…mã­NIot»JúÎþÎÖH´«D 4±ÝÉåïž9UTp\8 ¸üµâτ߷ÅKµÔ¾"ZüO’ÞÞÎXt‹m6÷Ãv¦3$¶Dý±K•2öÄ/„Ë¿¤ñ‡í{ûcXØéÞÒ> kVÞ(’ÎäÝk|"ñEíŒ3,fHÞ8Q²A#Ë1´€–;ƒ¹ZòþÕµ¦“gâ üñ´¶sögÔ|¯™ï”ÉpVåC*¾ÄÙù20l`êMÊ^×KËð³·Ê÷_%wd›]4oË˾Ÿzÿ€þnÛ¸§é_³½¯í±}âí.ßãž/ð_€­"Ôì_ÙžŽ"É'—m™oww<˜Àt|E!ÉóBŸ”Cð0þÝ–:ðæ•ñ./ÞxÞãS]RïÄØ2I}jMË[z}f”ßÛÜiÒyyذ‹v$ß0AîŸô¿žøCñ‡á¶§ð×âd?.©­èšý…õœá„1Ãj³5ã¢;0v¹E ’¼ež$ý§ÿi»O„~ñ‡þêw>;¾¶ÔžïL»ðÖ®¢âêÚéáK)WαóãO=$˜:B 僾<øÓûLxoá'ŸÁà‰¼EñP’õï4Ý/ÁZñ‚Íqˆ–{XÚI×OšSqû¡k™ÒäçMk/qúó=WÏ®ÖF“£í*BÚ8Ý¥òW¾ÿð÷ìÒù§âà¤ÿ | ©øÙl|m%…” 5夶þévÁHèD¥ä(72®æ,ØÉ#å;Ÿ<„pE¡xšÏÃú]”¶~R»\´޹"+s>ñÂ`ÙñmÇükËŸ‡þ ´ñf¢ïÚ›\\è°Ç{»NËyNdS!†àykEl%à´Ñ¨$ãx{ö«ý».¯îω?g+JÓ•„,~ÖËK:Â’ÞÒ–à³"Ȥ §ÌfäS@ý²ÿjË üaâ½càgÅËñ{we¿‡ág‰ö$ÆekX¦HHK<ÅîGîU“? V–Ë×Þ²V·WkÛtÚ½¹¡|0÷šP޶rüM7Ù=µ³Iµt›=ÛÄv¶î£ð—àö¯¦ê¿,~'Ç ºõ¥‡…mgw‘#íw ÷3ÚŸ(‡ÿ[ƒ’rCi{ÿ–ÿ[Ò§Òþ%ÚiÖz’ÇR•<#j¶È1°„˜mIÉÌQÈ¡ˆ À#Ð>þÔ5OXx³âž™­øCà寔GÙeøIâ]:þÏTkÑÅ4·¶€1Ÿ$$™2+ üDý©ÿny¼1â-cßüEyu¡Ü[]ÙYh¾Öbºñl'Qx «L¶È×lÛål"z;}#ñ›öŽý¢üg¤]|5ø3¨øâ9<'¸­/…5e“U¿o<=’Á2ØÉŽ) N¤ì_Ÿµò;omÕõ³¾ú'®»o}¶œ¯Ús[ûÞZio>ŽË},Ï?Ôõ¯ø(Ö‘-¾£oáíOÅöÖÐ;êbèúаƒÈOw,!f]÷x¹òИSËÚ§ð¡ûwÛüñ׊üs¢øÏQøÓ5Õ‚éþ#Ã1Ogi¾!tÖ ­hól2•ûTû7(à¦ø¡ñ—ö ð†ð€øcÃ^×õ­WKZü‰à-væ+9Þ{h•V8fÝoµg’B“1r-ÛîY>]·ý¸l¯Zhšžû5xëÃÆ(,ïïôÝCáW‰VkÂlï[$•€Ž2ÓÇj¿1ŒHUão½V©¾GÑm~Özýö׺ØÃ“žjWÛî|Ú«þ–Û©é¤ßðR[ Ööðéëö›ä–X­|2e‹a$^d¥ïò-Ò¸dcÈÂn4ƒÃ·mþ¯¯uñcSÐ?¶cÔZÆøxHÙÜÀú­³‹xÞ' ¾q•rÑÿ¬”• ÉÙ~Õß¶†³qi«êÿ§O Z­ÓÅ¢øÅ‘Þji/AípÂéå¤ù‘[çy´£<úíWûX_ë‹âȾ|M¼ŽK½7F½Ñgð>µcvßÚºŒ2ßÚÇw@ÌmÒÒGW¸¬gr™Çª•êk¼]š{kßï^KïEóª‹ÝÑoÛg¶»uíuòd> ҿ࢟ <#á ØiU¥Ÿw¯ß÷tZ쮼üÿIÓ5 'â]Î¥i¯üe³ðTš4ú}…Þ“ÿ®µ©¤ódzE7—q>ØîÏ“‡O´ “,j¢ç4ø)¿ÄK_øCñt¶×zhͪNšÝí¥ŸŸw"<šsê6¶RL“=¸wFB֙à †Õ÷kö…ý¨<7ðCPñe§Ã9|sñ&^Á{v”½›“I%«žé-4÷½^®êõKê§+sÙ6ÿ¸·òøM^Û;w?´½÷íúº—‰¡ýôôòÓMÿ‰kÇ%¼û´Û’Ä}¶du½MAmB‡?e6Ò>wI–O¾¼;e¨éÚ‹a«êú†¿ªÃiW7×i Oy(PWX" Ç$ˆÕW'€~pþÏÿ´7íqªüHøeð‡âŸÂûwÒ×LI5¿Íàïii«1†vc™ ÖÖÒÂÉj²-Õ ~Ñ#DwFb?¦õÕ^›‚KFž©®º¿óý«O7QT´õZ-Oø?ÒßRŠ(®c¬(¢Š(¢Š(¢Š(¢¼_ý¥¾øgö‡ø{û+ë> Ôíþ5ø§@Ô¼M¢é«¥]¼7:}“Ä—25ÊÆ`Œ©š1µÜ1Ü097j+wÁ6þä›~I±IÙ9=•¿’ûÛKÕ¤|u}ÿ¾¶ñ†¥áoƒ:>µ4Z桤Âö^1ŽW‘lÛWóÕãû.äºdÒ%xí—yu™ tÃc„¼ÿ‚Œø7ᆙÞ•ð{ÂÚ‡w=µ·ØüU¤éÞÖ5 Î:]&¥p ‡I" À4—{âÚÇdõ/¿Ú[ön³ø¡}û7ü.ÿ„¶®­­ÝêÖíktÑiK$·2Î÷M¾5–S)Œ(*ÙÜ #+yk?Ø÷Dø¡¨êßÚÞ&_ˆ—Z=¼žk躬ÈÚT—^\S[©ŒÂ‘M2º ¾@fÜH)Õ„u–Wéÿ[¥®ÛïkkZq”¥ìÕ’¾›õ²ûºý×9ÿ†?·¢|\øµàox[Ãàð¦«w¯i÷7SøÀIªØ^éë(û¶QÛ‘ÓŒžKK‘ónTGû>~ÞÒühñ~ƒà;ø>}vëXÕô[©¼7â‘©E§OköçG‘œ@VÉ­ä—KÀðùd)qî÷?¶Àí;áůÅNóǺ'‚ç}@‰oüªÚܬ6jísröÒÛ¬é ,n|Æ@&âT&Õ?à¡ÿ^ë\³ðŽñ^Õ´û=FîêãP𶩦YÙÛÛÅiä’[S<<ÖƯmÁ$#íòÝ\íJ ëkÿÁOþkÓ®§jþÓ|U¤ø²ê×U[·ºuº†Áa„ÈLЇÍ%È‹;qÀa‹¡5E)ï+ë¶¶¶ž¥Þ·Z6tûhEí³O^ÎÖ¾ŠûèôÑìÏ™|ûq\볦ñ×PønšªA«ØhÞ ·ÐµS© ´[ÛJ·(`šEQu˜›ÇûÎX(fá5/ø)V—¡i÷:—‰þè~´†[Ë{‰5oGj–ò\BmîY­ñÒÍîPäË‹"œå+è~ѳ¹£ü'ñ‹üGs=¦¥â ËÛKݼ·:½˜O ·ùLÒBÐL|¶W»2(*וêŸðQO…V¾?ñ÷ôo ø‹U]/OŽk}M´ÝF+KQ€+eq(²hí7‡‡Ë•݃™ € ‘F+9ré®ÛÙ(þ®íi½¢¯{ôcì¡YÝíw¥ß3]}RzéfßVtIûpi0|о/ëÚ/ß hÚ׊.<3¢O¨øÚ´é¤ŽâKu7žG—o$²DV8€³¼i¸ãçOˆðV|>{5/ƒÞv<—ÌnŠ`ŒZCj—m*Ì¥Áû#í„nÈ’3¼ Û~—ðíõð_ž¸ñƸuÍ+8¢—V†ÇGÔõÑKÛE:¤î,Ók7™µHRŽGÊÇ$Qÿ‚‡þÊzºèñˆümàèôûxo/îµÏêú]­¿˜$ÚâêÚ8CbåðC”žµO–«æÒ{_¥¶ºów¿¢°RÄÓ’\®÷ÿä¿ËÝõÕŸ2ê_ðRjDðÙø[áf«Á©Ã¥Mu¥xÖ-M#ºžöòÞŒ2ZÆäm´Ý!%Yö¨|f¨x‹þ ¿ƒ<bð·í÷ðRöÔYx¶×Åþñš_\ZM£Zx{SÔ]#Iî#[„h­A’-Ù™Õv©;I<hé--v¾JÛ+úïé~åÊœ›r[-=Ÿ­¼¼™à:—üçLðLJdÔåðVñS[ˆÖæ#Äöæ8Ä‹n[?”>Ñm8/#eBÖÈë~Ý÷“~κÇÛ_„k…uxô}SIÑu©5V±–Hc• =­«¼Ã oÝ!S»9ì_ lÏÙë㈴|:ñ.·âíBúÚ[¸.l¼?}=º"ÈHšé!0[±HÈêK£Gÿ%f'í×û4Íg§ê6~7¿Õ¬n×Q6ÒéúMÕïÚÍÊ\"#vwFPXAŒQ‹œTZ·+j龉=_š²·ÞîE 3|ºó[G¦í­=;Ÿ3x£þ “á ø‹Dð½×ÂùN¹©hPë¶Ök«m}oÆÒžÖXt>Z3JçÙ^™ñÃöüÑ> ë²Ô¼ i¨hÚŽ‡m®Nmi­`‚)P9ÜM»‚‚ëƒAà‘]Ô·Ïì×sä[ÿiüK{Ùî ´'ÀzÛ]Ý2±à†YV2>rŠv÷­/þÚ| ñ'Røm«Üø† cL–(5‹«Ÿ êñÚ[y‘cHn–Íí®…ÉQ*ÜçŠÂ£ýÜf“ëÑôôÞQù«?ˆºQnMoúZÍþRÓÏË_‹ü'ÿ1ñÄÚÏŠnu†Þ×¼%{xrXož’1ˆ‚“ ?2Œ§#3ìåÊœ^‹O¹ÙÞþ©?ø%Ô¡4ùßñWIz+éêº4| ¥ÿÁ\´}WÂ>$’O ü-_YªØ>§¥üA²¿ÒtÛùZq×aSív¶CÊÿ™`TgÊÞ¾´ñoí»à_‡?³ï>-ë>$økâýZòM.ÇSŠÓĶööö÷w1*%Ã*œndW ¸«]î¹û_ü/‹áÖ±ñÂ:‰üuÖ‰i-»Ì÷´¶Ò“*ŒÛÈ«»ÎŒH6œ…n•æº?íÛðJÆ×NÖõo ø¯Ã7Ú¸›U´´ðŽ·u¨%àuˆ¯—™ã‡ïË(ÛómÛÈÒ½zwå^íí»ùÛ¦ëô)>—»ü5ô¯Ë篈?ðT+K QáÛ ü:ðιªÊ±u{ÿEq¤›T’ææAXf‘d+?0‘ăú•gà¿_øGEðóøCÂa¹¶ÓÆŸ ³‰ÁóÒ-»†;ƒÈ¯ž4_Û#áΫ¡üRñÅÖâÈþxrM0[êz=õõÞ®.Ôm1ÙEng„à7v;@5†à ÿ³CÅblõˆº¥õ×Ùŵ…Ÿ‚õyïdižD@`[s,ctRÒ*¢íÉ`5­H¸GÞVkwøíѤ֟æ„¥dµßç{[òü϶zp8WÄZGíåð‚b‰ôßøVîanöºPðö¥ª¬rB%gžÞÒÚDEPÃæŠI—æ(C(©ñ+öùøMá/ƒ¾øÉà-7^ø»¡kóÜA¢&6òn¼†Q+´Š®BŒ»Ë8 I#:éÓ‹”ôK™œ$¥dº«ü·¿¥º(¯‹í¿oÙöagÌŸìu,c¾x%ð&´‚2cyíj¥UŽBÑ©.6ò¹*¥ÿíÏû8iþ›Åóx«Ä3èŠ¥Ûøzþy®0fEp™%oÜKò*–;0$Q§)|*ÿÕ¿2cR2µžÿðÿª>¼¢¾Bøaûgü-ø‹àßx¶k_è­áÄ–ãR´M SžF¶YZ!, mRKŒ²R4fVHâ³Çíóû7­Õ½æ¯ñ H½–&ž8µjÖŽñ«¬làKn¹Pí·#º·\Vu$¡¬ôÛ}7Ûúî«lïÿû6Šüíð—ü_áζ¾3ÿ„Â>'ð·ü#º­Ýޝ4V—º”E w†µû-«Ëq)ŽÜ·’cïmVvOS¥Á@¾ j>!½°–?Úh¸† &þÁÕ«sxn'‚hN6‚â1€±nR¬®žÍòóôÔOUýuüµô>颾?ñí“àüYñ/ÂßéZåÔ/¦¦ŒÚMî­y¬ ”„³›K{s$)ÜD®ä²ª¶÷(¡¶óÚ—üà#èoðÇŒ¼S¯Üi³ßéúwü#z¤;Ù-$¸UºqjæÅ £y&P#`p•T ê=•ÿ ΪXj“iE^öüv×cî+俇¿¶Á?ø Ä^7oǤ¾‡wa¤ëö[%•ôÍRí⎠.QYÞI'…Så]âXÜ|ެjé_¶‚5{Ÿˆ~$KÒ> xSßÛúïŠ5F¸²–Ðåâû,–ਅb—Îid£d ¦aµX¸;OMÿ}ý5ù®èæ¥5R*PÖú/]­ë~‡Ów¾ðŽ¥â-/Åú…|9âÛž -RkžîÎ6ûÉ¥w¢žáHº:ø«Åß·W  7†íüSã‹ÍRxÌV¶=üÓKfe‚)'…`·“Ïek›s°crHX6±ƒð÷öûøiãÝkX† aðïÚdC¹µŽþæïÄQ,&…â¶û”w[ô ¸‘ ç »™*rŸÂ»¿º×ü_ÍÞÛ;D«A;7®‰úë¿mßenêÿyÑ_jŸðPßÙ—GÔÓJ½Ôþ, šñì|äøwâ·I£K·^agåF`7^pv/-w…ó"ß"ÁC¿e mÖö×ⱩéâãP¶¸¸°ðö£{žÖ~p¸7&ìÁ$·šæìÄè`lKˆÉ:R‹JJÍšÇ[µÓúý¶h¯þþÔÿ¾2xÏUøyào\oXiqë7ÚN§£]é·–vrM$1ÌðÜÆ’ä’)V96ùrùRùlûoÑ¥·þº'ªþ¯¯äQEIAEPEPEPG^´RyƒCãý á÷ìEð÷â%÷ô%ø#áo‰gX{+›ÄÖ`ŽìêW/u#Z°2çÌ‘înŸÉ#–‘Ø.FG™|`ðßü—á^™¬kŸ¬þ éÓéwѬ–¯|²ßEtþtðÙG Èd™§–+U7—t@Ùjô þÄß ü)ñ#Ã?¬|Oã»­oGÕîõ[.ÉàE¸}NG·lÛy“U¹emâUÄ`IâNÆŸðNƒÞ5{É'ñ·Å]_í RþÂ]>{3JÛ]ßCOi!’9¦w8›Ì(ˆÚ< a‰Œå£k¾úõVõºù'ÕÙ9j©Ó‹vþ¯{þ6õM·g¡Ù”ý‡þ%|+øm%ψ¾ ø‡á—Ù.µOMsâ$ˆÛ¼r-Ó$¦bdŒ¤²Ç2–d*î’¤Šò]áŸìYá{Ãÿ üA üQâ+{ÿÙk÷².ÍOO¾½œ’êHž:œ¨¦AŽV}®ÅÜØ×ÿà˜ß"ý®ûI“IŸÌÓ<;rÑ$ðÉq¥É%´‰÷+û–E‘n$Y–UÚ«ë_¿b‡´_‹cŸ¦‘-ŒPJ‰y Ðfómd1xŽ£i`8#Ñ”¡ÍVù[w]R³¶½u·k®×Ó…:ŠŸ÷•½º¾—í{]ïnÚñ~#øGÿåñ•6£âˆgOAd¿ÔÌ·^ €ÛG¿h†òE&}‰›«µ—nµÄû²Ò>z¯é±ž¿áÏxoÅÚïÈzžêþÓûCÄ‘^˜cÔ ždÛÞ|ù &p9*Gy«ÿÁ7~ø¢mZûÆŸ¾,xÓ[Ôt } SÔõ 7Ã_l½0‰UnüÈô”òed™ÑÖ,0LDä’ûþ ­ð‡P{Ù$ø‘ñ’Õ®uí;‘o6—w3‹æ¼ ð­’Ä;2Ø$òÉRç‚3GhÙ½ܺµëÿ뢺“©%(Ê7VÓ]ßmWãòµµ~Æÿc?ˆ^øqàÛ}Cà¿ü(÷òj^°Mn Èu+äœÌ÷¨•…Ü«92—;ØJw“¿æ®…?ðO†Vz¤[~x.Ëí-§_ùþ!†’ëh_.bóó*¢…ß—M£nÜWŸü?ýu?„üãßüB¹¼øy¤ÚCÚj©ffwŽÞl46ö1¤§É·A¾lm <Çl¡Â¯asÿñøy{â¿x¯Qø½ñ«S—U¸º¹{K”Ð¥†Ñ¦†ò&3i†`od ¾F#ËŒFðê¤bï$ÿ›ï¾—õþ¼õ¤Üì«ikyïñ[ÑÛµõ"‹á/üZÏCÔ'HÿfÄðäð®™y#ø†ØÛÜGêZmëúÃ^×ÓéÏh_°Žá?ü7ð³ðËÁ—ò.©£i~ µÖ–ðàH«M‹hЀXFCžI5ÉÞøSþ Ù¢kšUÅÿˆ~Ùø’KËk+bþ+Cq<÷ þL}£s‰MÃâ6Ê¿šx9®3Ç¿ðL„¿KþÐø¯ñKšÊíï­ÚÚß@•<ò·jHntÉaœ)½•‚JŽ™TÊ‘¸7ciÿòøe§]ý¯Kø•ñSK_´}£ìÖöº vÙ-lÌžHÓ<±}•À0Ü »v\±ió]iäÿ«m¹ÑJ-IÚú÷Öý{÷¹î >þÍZ±/Å?„Þ ðJêÚ„&õÍ&äÏý¨r–Uv[‡PYG,ꤨ`2*‡ü1·ìÄ5SÄIð{Ã1x‚úâ[»ëèÚd¸½ž@¡å–@û¤rWsB¨Q€1]wÀß‚WÀ?é>ðÇŒüyâ XAäYYë70Ü A¼·Èâ%(ÎÕq*¢"€¶V,ÞšÛkݤôcæóû"~Î ªèšëü+Ñ$ÖtÛ‰.¬.šy̶’9Ì…É$ɽpÀŽ*Šß²wÁß‹o‹áÔ´k¯xYd–ã\Ó$ö)’3Èžhx²#,˜d+µæ¾–¢³i8òtíó¿æ“%;5.«oÇüßÞûŸ-xsö8ø£xsOðö±áýSÇD oö­gR¸žY#A„C‡ G à` ôýžþ ¯‡õŸ ¿€t‹Q¹Žòþ9ÞI^îdÈFy‹¶ÐH¶$cŠöZ*¥&ï~¤¥k[¦ß—äx¹ýþ j^>Ó…®åI®-ÌÓnv@D`I¿ÌU@J¢† ªv¨ŠÄ‹öVø펣û%½¶`ÐÈon‰L@æNFTpr8¯ è©i^㾜½—5¯Ùà¼ÞñÇ€|¡Ëð¿OñťƧq¡¾ÉŸÈ™eEO3rÄ © C6ݧšÒÒd/Ù³BÖ,üA¢ü#ðΑ¬Á2\$ö†X|»¿xU\Ä»’H%‹19$šúFЧ&÷þ´·ä†äÞ¬ù¾/Ùöo†ïNÔ"øU¡­õ£¶›Îœ¼@ B€ù™ØT((~CµxùF5õ?Ù‡à³á‹j |=wáë}J]b([ÌöÙé'iyŽî@,YŽì ç½æŠr“’ånèGÏÒþËn-®­n~é×1Í4w,eº¸wŽTªèæMѶÙ$RP‚UÙNA ùwÄØ#özñ±:>ƒðËW}F FæÿÓ k‹–ˆÊÈ›™XÆ¡æ’Aål;Î쓜ý¥E%&¶ºá¯Ù·àÏ„ôÝwLÑü©©l-u9e½¸’]A<Ó)29|îiˆÁ,ÄžµÎj_±çìÕ¬ÉÚÏÂm X•YYMÜ÷mô˜ä8RìX¯BØ$>–¢”ýï‹QF)+#äÏþÄ¿³¾¯á¿èz­¼¬AuÚž—#­ÄSMѵÈZ7”,òá¤VûØ Ž+rÃöAýží-thî~iú–¥f"a-ÄâââT21–GWšFšc&~ÿšá·E}/EZ©%³"µ¬x¦»û:|ñ/Œaøƒ­ü=ѯ|iÂé¨î‘&Q,j™VËÚˆ?¸Ûp;Wo¿eÿÙöþY%“á/ƒ­ ’êSN¶vÿeK¹/¥inÚUˆªÌe•ÞB\7ï¸Ã×¼ÑYr«rô4çw½ÿ¤x†Ÿû7|Ó4={ÖŸ´A¤jimâHÒJî¶òù¶ádv/•(G°®É>uÃ|Õ³ üø_áx5ûox]4xõKXm/Ìw ÷ÆC»~åq’w©X–,O5êÔUÍó_›[‘d’è|¿¤þÅ¿²Ï‡îmï<;ðSÁÞ¼‚Ê:Ö]5d´{x„!©ƒÚ ˜ö±ò—$â¬Ý~Ç?³ÜWPIðwÂÑÁ4‹1Ž6ŽU6Å$Œ#¡³´ÚÉ´¯ÙãÚFÑ_KÑTªIjŸõ¿ç©5)ÆM¹+ßþòÐù™ÿcÙ‰“P‰>xZÖÚêêîúX-̰Â'¹IRåÖ4p‘™„ó™6½§™Û-#±uçìsû0êGYmOàǃõ3©Aqkªý©oíˆe… h®·±ûR£eÞ#XÐ \ ú^Š=¤¯{–÷o¹ä¾øðŸÀzíŠCð£QÑü1àk–ÒæÌ,ºlV"îv†ÝÞ=‚ÙBD¥™ðû@T&¢täªòìÞËÍ«/¹ë¿_#*xªS5=W–»í¯ü ôòX¿³ïíéâïŒÞ0ð…µÏ€*ðU¾´Ú´Q&Ymíç¶²‚ò-êñ¤ÑE4r²¬ÏŒ7ý§µ=Àñ§ü¦üJ¿]±ðß‹t&þin|7¨\Cy! ¸y oq 1ae‰ü ü‡çsþ ñÞlúÇìñyoh’jÓ,w7ÓÜi÷–íp‘ÚÏVlË%Á†9!Û»tS«`éþÝ Ѽâ/ø£Yðµ¾·6¥»Îþ»’7ÙŠÜÚySÁ¢8RA#pŠ¡ëŸö‚ø± |$ð]ö‘‹ñÄš®¯®ÙÜêzÖ¢4‰,ííÌïF¶Ú|±I&£Eo”–rNï,ñíÝñVçX¹Ô4x{áÿ‚m?³Öþz(5]R8Ü3¸KHDwo”Ef8•YŠh뺶ÿ‚xGZÑ|Kwá¿…þ Ÿ^Ñí-nõ-7Qñ‰k-š\¡’ݘ%ÜŽË$`QX‚Fà£,IM¸Ejž¾¦“~i¨­nÓo{ni%l“¿ý»kú]ÞÛ^Ëk {ÿøÃ¬gàïxJ)ü?6œuXï}¶–©R*\Dø–gŒÉ‰ a3ŒR yfƒûh|ø_7ˆµíKàµç‡¼_}§\øŠóQÓ4Í2Èë–Ëzö¯7Éy)fHbw–@Ý¡=ÇÅ¿¶×<ká­GYøkñëwz šýÕ”'O–ãL²[¯³6].LR·›’)í9# U&”lõW_ÍÖÝì×ôÞ³:MUå¶«[yyö½ý~ãä~Ùÿ´½Œsi–é$ uÙ“MÓšæãV+$ím–KP±C";áI:ŸùnݾÁøeû[?‹¾kÞ2ñw‡|?áÇmy©iº•íåì×v1m¤Í&V%%Š5”!_¾yÆf§ûfµ×Áæø•áÿ†z¾‰©¾¿‡…Ž¿¨Ù)³yb2%Ë›YåŽDË#FWƒ\÷ÂÛ«Døƒãü5×>xžÇâÔ(º¬°ÜiiicQr¹½iváÉ*çI¬dÝG%NÉËo-¿¢Ýôß̪©B©%¢ÑùÙëówüÑÿय¢7Ú‡ìó –‘öHÙšVökÈfhÃ3I°*±&ye‘Î39ÇgqûU|Yð·Áoþ>]6/ˆ¾(ÕmõW¾†êäé6×oÀŽ•SM–UM­¹Z1vä‰Èf­ÿ,ð‡|u%†«¥ÃuàËò Ðü‹Ë%¿žD”Å<’Fn‹„WÇR•¹‚}àí­£üoÕ5Eø_âëmjÆÆââq£§Í·Qï"Ò&iÒGvU7–#ù¹p5¬*ÆT}¬c£Öúì“¿ùéä»JJ'Ú}ë×}õèýOœ`ÿ‚„üaþЊÆO‚–îñÔÙ$úž§kiXK¼ot¶—‘È>X®@<1‡Íÿøç§ÙkŸìÉáÛ»Û +[ë‹-+Ä÷sOsÀ2Ëiö>î£s$LYJ"¼›boP—þ Oð¤h“ëö¿þ&_Ù[é’j÷Š‘Z«ÚÀ“½¼œ<ÃÌdš6FTÝýá•ÉŸ¿n Tø ñáV‰g¨‹oM ]­ôÖ×"ÐÃm%ÄÒŽê4‘‚ÇOÉå” ÕÓWýâÖž?ÍÇR¤í ëÓæíù5ærzŸíñnÃöpÐ>4^ü>°>¿wdÞ†[­1Z4ŽVŠþÑe=Âgj+0,1ýÓÝÚßâ\_ü/ñŽo‚vúž þ!M^ÒôBîìéë#’êô5šâ13Æ­û¤*ŒÏÑ qrÿÁGü5cáÝ/X¾øCñ¯RhtýFê]>?SºŠÌ\•/ÕÁ´WåSírC/ŒžÏâ¿íOðODñÂ{?‰ß ÿ¶uçÒí|]¢^Ý[ÛOk¥\JÑÃû‹©qÜ œg ¯å¶à<çJ¥4—2ºn+}|׫I½´½ýp)¦úYIíçù'§™æiû}|L‚]-µÏÙðxvÖt t“ê7rÜi7¦t‹û>t†ÍÕn0d—î·¾¹aûT|B?üã/|6ð~‰â=jm6Ñ`ÕµÛ+4VÄkq2iÂH¦” ¦-›†Ýç‚|U?à¦Z}§ˆ.áOƒ^<ø…ámNH†/¼7s£…˜2[y‘Ü=Ƥ«¹ZåHuJ«`€Û–ßðR/ ë×ÂÛÃß×/¬> ÝüV×lÓSºXúêÔRïäW·0é¤ZE’eû\;·’†_{Ö¿à  t¯Íáû?øÃÄRnÔÞtûÍ6C,:|ñAxZ3t%ŠHÞe")]À` ¸Ù\•ÿ+ð÷ˆ4í YÐþüKžÖòÕ®¾Ãq«èÐê,=>Ku>ØmØÈº‚g|ñ”òۆȥ §y¸é¿Ë_ò{vfT0µ%.dî»Áõ[¿CéoÙ‹ö„¹ý ¼ w¬kž?¼gm}es¥ïšdòຖÝ.¢y¡‰ž)LE”=5ñ‹>5~Ñÿ u_‰ºõÅ|U±ð·Ž›G&µ¥é¶vúÆ=ë:ËKóƒ…†#xDë¸7Y?ü[Rðo¨Öžl™K•R–7„…FX¤•£ ÿ½eΞp”\ÕÔ’jýWuknÚùZÞw9¨ÅÂKÞ×ðßîIþ7òá|;û}üZ¹ÔÒ _à•¬Ö1ëºÐÛKr.†«©X\j™¢n­È³‚hãD¦;ê$Uº¿‰?µ_Æo~Ðá¸4- Qð†ªt»9c¹‚K«K‡ðúÅxÒ}–Vyb:…㣣†MÜ¡déßþ ;ðz/‰š?à ¼5ã/í;­FÃKŸP…­n,t»‹««‹XÒêH¥cjLÖÏi•#.ñFË,Q?¨ü`ý®¼?ðÃÅö>ðïß|cñÚ xÉðåΚ Z4w† wu™¦’ÉáEˆ»y’ü‰i5VÖNé_kÙ?Á~o[ÚÆ)Éòê—ù¸ïëø¥çý™ÿm‹_´GÄŸøROƒV?ô[=æîÆ]L_Æ5­@y/Šy @°î#º/83s0h†<ß·ÇÆ)¼7k¬éÿ²ÖµmªÏ£Ç¨Ziº•ýÄêwBââÒæÎÜGlí+ÚÍoçJÁJ›Iá™çmt·¿ðPŸ„¾6Ò`Ó´o„¾9ø¡á wL³’)-î4e«YjSµ½™_µÞF&Šæ ò‚¡—Ë  GAâÚm<ðáFµðƒáΙá TðUþ¥£èv¶q[é-lÖCjÍoz©Æ.[÷p¤¨þ^Ñ4_3š§¸ùÓ“¿Vœ¯ÛÉ=ö²å{”5r¨ìÔ›~KHÙ-]Õ“ûï¯O¥þü\> ¼ñƒi0é&¯¨iðÚb—0CpñÇ:™bˆ‘¸ ;²¬Ã }®±¼;ýµý¢ÿÂIw¦ßøƒì±}¶{;V¶‚YöíM$“œ)‘Ènnµ³ZM$ìºWù™Á¶®úÿVùlQEAaEPEPEP$ cpù(AÎ3œ~ùÕàOÁ<~zû÷·»ÕEìšÖ§§ß^Ü,ÞÜÚÝ´ïs¼0EpgŠwªF΢VãÏ賜#Á0 Éè=ëóãNø?û[j“øïÇuˆ¾%×oï¯.¬uÈ´s¯O©-¼Oh`†ç3Ç<6vJб‘f{u©cÃ…¹š}¿U§ÏóIYßBMÛOëG¯ßo“}AðŸÅ¿ØÏÇ$Ñãötÿ‚~ko£üI[ðºAâ bãÄvú®ñ.þÖÛÅ7Ë%£Ëz~ÿÁ;ü*4ïÿjü5ðÔaáРÒOfd"DŠÄBnÀ %¡H@ÀòA ó1n£ÁŸ³ÇìKgàè> ø#RÒ§ðíηo­Å¦Ù|CÔ&¹¸¾Óímm†$[Ó;$vö–ÑÉo)‘š½÷eNÍ;ô·š¿½ûwUæõÐè•·Ÿßm?Áw2õ¯Ú_öÒtgVÓÛáž­y¦\ǾÄhKm%®¢f¶ŠfšK9¥ó‘ 3˜Ì†e1–Ý“ÔøcöŒý•bøOð£öˆ´Ó,t ø†Ú1 ]éþ¸»¹cu ÜIc·‘¤ŒŒ––жÂw°¯5¼øÿù³Ó5‰"¸ðˆ’V‚ßR‚Ïq6©$!Rq›ÌÏ$BÐÚB]<‡ÚGÏžWÂÿe/|9ðW¿„Ú¯‰> üøeªÛø†ãM¹Ô5+;[[<ÝZý–+—»F´ƒu´Û‘ËP‰ 9ËDÜ{Ç^Êö“öî½uVõŠ©ÞðÙ'§weËÓùôé£ï·¥x7öý¼em½¬xwÁ^Ôïnu};í:w/«Ão!•¤†Xbu“ÌÙç,aŒŒí$WOÆØûÄÏñMðž‘ðëÆ^1Ðô©µ½[CÁ|¡g™ð©YJ¡‘¾u2€Àð‹OÙËþ Ãã}_\ðü ¨h7U᱄Ãñ\Ò!–YíÌ¡¬Z+øÕÇ—1*ð}Ìü…p1ê²ÜþÅ_¥Ñu¯Éa |P»—C‡R½ñΣ¨hÚ¥ävÄ»™§»{h.$Ž ¦pVY]K³`VÖ’IûÖ²Þ{}îÎÖòK¶±^ûkUvß’NïîŠuÛ1µ¯Û?öñ†,nîîü'âï[i²½¯…¥ðܲêÖ~TI3Z›I ómÛiFTe]êU0 ž¯Ný«ÿdÍ "ÄsxsÁ~1Ö­cŽÿM·ðõÕÄ·q'îÈfŠ×÷ñE¸#±"-±ö7ËUîgØ«KÅÞ,ŸÄ¿ØÖV§Kñ-ÒüOÕ-í`›N ðŠIÕcA·¥EFPN[¦ü$ý„õÝRË\ÒüOà]vîk™lí<Ï,M4ʯ%¼q­ÞÏÞmY @`°ó6ç-[ÍÅÉòêŸùü÷Ow×ñÎÍE[uþKòwù}Éš×íûøwáï…~&xSÃÞñŸ‡ïoŸHѤм*Òq Eʰ£"ÆIß&Ä Ã 3­ð×ö‚ýˆ~#ê¾ð?ƒµ?…kâí[Kš;=]mnãµý¦[wŠHTÄ»s/–áC¨Þš²|'àÏØ¿âÏ‚ôŸƒ?‰gñ^ƒáýrçMÒíîø‘n,ôM_Âw÷ÞÐ?á!m"ëÃÓE}áí7hV²É–ªÊ­PêP |×⯀ßðN¯ j£Äw1øËÄsj„1½Þ•ñ+_¿†)Äl°”‹Q"(ÐÎêc "@ÜEÑn?cÏ‚úÇü3ð³â4:7ŒµÍëPŠÞçÅ×þ °½~êg¶²¹¾h%¸Q"ÄVUPÄ€™Ôƒ»Ž­-¿¼£ëµîü‘¼m{?/¹½z?ÏsÒ5oÚ/ö+ð©¯|?°ðµôÖÇgü#ò›9æ•TÛ†Û|‡–æ~vgƒâÏì¡áÝ'Â~?Ò“À–My=í¦…qm •gý¡k²iÐZùŒn!šæÚ)Õ-ä+4eÀx÷a[ŠÜÿ…Wû êžѾ IâŸkžÒZ}nßLŸâÅÔñœ%ÓÉ%ÛLûyû‡$94«§I.Ÿ£ÿä"(»Æ.K×ÖÛàOîó'›ö…ý½sY·ðlú¤Ç¬_5Ÿ„î5.ÄæH-[Í\q*ˆÿ´'ì×ð’MØø7]x£IIŸUð¿…¯bxt™$tiMÕ¬ÑѲD*Þx9eN >ü*øAû&­®|Wµøý¥Åðã^³¶KM"óÅ—Zt©i ºË,—û¤‰dVò™R6r~w”`°uÏ‚¿³'Œ¯¼;áJýo5 éÞm½•¯õ.-l_s 'XnÕæŒîb}㜃QRQ·^«Ë[§ø|®U9ZOŸ¶þwV~›üìp¾ý aí%ô?‡Ú¼­jš G¬WñÜêWÖ~p ³M:<ÅÌ$vbÑ!±ÿ û·ÓÇÆŸí.ÍûHÿ5Væßl­nÌn¤½{‘M+FWÌò£S· tÛ«¶öÿƒm;?!Æ.éµ§_¹ÛúísoNý­?`+ÉÅ®¬x3Zxk†:W‚¯.ÒØÑ>æ†Ñ–6m¬»I À¯NðÆÙ3âο¥øGÂòøKľ#ºÓÞ,&ðÔÑÌ,ðC,Öêc€°ùKa—8¯'ð‡Â¯Ø‹PÕ¯ü7¥êúÕõìpéÚEµæ§ñX¹´/Ïm¥Ä×ÌnTG+àFÇíè :ñF­û |"Ö5¿kúÄ]_ê'@þ×›XÕ|­6õŒVâ8$’ë13™¢O5v©ÈËñÄ»{OgßeÕëm½ù»u1nJ<ÏOËk¯É¿E~‡ÒÞ/ø•û9x/ã?†>ø‡À¾‡Äº®ƒq©Árº-³ÚE¦ìÌ@Þ$ w¤aNFH¬ïü]ý|gªYi^Ó|#q¬Ý[É໋Y¦M˜ -ª’7 ?î€ÿw ^kgoû'üø…sá«ï‡®<{§júf·sy.¯§Ýi—­`ÂÙ¼ÿ´$ªŸg‘ƒ"Xoˆ5ÇXOû(øãÿ‚ï4[}bÿþ­2ë]Ón.tû«ø­<ùM”º„zåÃm‡å p!,¸")]I)»Þÿæþí¼íwk¶·©BVn)è®ôÛEky=¯®—²Oè/|Xý¼9ªkºˆ-ük|©6z‡ÂÒIðE.g]ënRX!æVRÑÄÇ2&¹‹ÿÚßö2´¾Ð­ÜÉ~tÔºW6ÞÔç‡IŠÝcgd‘,ÈŠ?Þ(FCµÎUK W_…?°¦³¬ø¾ÛÆž¼{»Ùµi¦‡â=Ó[[µùÛ0…áŠÞ¢ kã ¯ø'›ñ ÛÃ^-ñŸ…n5o۵ė7^<¸“N¸-v±¡g¼ò÷97†5@vmr6aMtö³Ÿüö &æ'ñV—¬hw·ZÜ®£ñgU¾ƒP–i.KÃ(ŸQu›s]Ü-· 8PT ´9-ªþ´ü¿ËcZœ‹{«ÿÁþ¾ýÏWð×ÇÙÄž7Ò¼á×ð´¾9¿óm"¶>¸‚eó¼âÑJÏl¢7Ș…¯˜ˆÜ9®mÿhØ[BÖµ½m_ជ®øw÷7Iá¹ “KêêØmÆÕkˆ.â]¼4¡eœ_|'ýŠnü£x‡À,ð߈¾"ÚÝF`k/ˆww—Of³¢¬‘-ã,Æ%º™ º¶ÕeR0ˆ͗ß°OÆO|Cñæ½ðóMðŸˆõy®ôWÅšƒË¡]\\Gu¼‰âMÐJ'Óâ1º4l^ÜI QÇE¯ÃøôӪ߭öfU%ôî¼´¾½õµ­¦ûž§?íûøKNø;â»+ÿ­Š4æÕ|w£xbk¶¾³I!ŒËÙmÙ£Q%ä3·ç¹E3€rüIûWþÈþ m+ÆÖ3ø:K³5„’j'LÚÛj’ÂI3Ò¼Oaðî[~kOPÖ5”Ó5¹Òi­µT‚i.BòÞÌÒ G6MÈi:;œ£xòj’Öû¾·ÓÖÞißFE&ý›ö«Þ¾ëd½ä·ù=ofšÙkúsðÏâg€~.ø>ÃÇ? ¼EcâŸO-Å´7vèè¢X&x&Œ«ª²2I£+C)q]õ|Çðâ7Âïí9þx×âµ¶±¡x~ÃÄ7 â—Ôo.VÊòæîKÛé$’áÚK+¡ƒ+²¬jNâ-ôåUhZZ^ÞdSm­BŠ(¬‹ (¢€ (¢€ (¢€”2²œàŒüœÔfŸÙ[ÂÞ0ñž£âßÚ¿â5ö£ª¡’ÞúçAh48®n¢É˜(!–úH|뉇*)q_¬2'™Ç’»E~d_Á?õcAøÑ¡ˆÖZ >=ð[ü7ñD’é§S’ïFŽÿR¸¶»µ2J‘ÁvbÕ¯_:)ãiLo´ª”ŠNV–ݯ_&ü­rãFœô¨ífµµú¤ôÓh¶÷I´–í‡þ ‰ðŽm[Ã:®¥ñGâæ¼494]>ßS³ðõävºlFon†m-Z¶¶d¸ ö Ð©3¶î£ãì™ðrO…t?|høŸðÏÁ°Ó4:kÒ³ªˆæ³[tž9ì%I&‘í¢Œ t‰™Õ,»~mð/ü{Æ×~'Ó~"jþ9Ò~J¾%½¼¾ðÁÓo¤‚îÖ-WR¸²¾ßc¬ÇÔDw6À\J%ŒC’ÖØÛåý¦~ɦüñÏÀ‰¼KðãZÐõËí6òán<%:[VÑÎá#¿Çq'ÙüÈîb•$†R’ åUW(ÁÓ…šº~W[7Ûâ“Òþ±ÓŒ]eRoTš¿”µ’×Í/R·ÁØëῆdHÄó'’żÚ鯉›©Ï{Ù4›ÝݧkmÑ_¦›³Ÿ„¥rÇKt鵿V¿È¥ãߨöWø~ƒUñ·ÅŸø*ß]×®tÝ:y,ü?Éyª›˜Áf:Y–ä´·óˆáåpólCƒ°ú§Ã¿Øwà_Áoš?Å?Æž4»ñ*øÿFÕ<áK¿@ÐêWVº 1¢5Çž¢ k¨¤†6YZà§îË{wõ­^¢þÉ~ ¹øñ'AÑþ*ü^o4Ķ—QWÓ£»°ˆÜ]ܫ۱VÝy ýêH6ª2·ËkÿÒñ¤úï…µm{ãŸÃO[i)§ýšßUøs5Æeµ¼¶¹ŽbN«ƒ"˜#•.žkÝAê5ø&ô×~Ô¬4[êWPhk-´Ú Ë¥I=£'Û%1[ÞÅxEäq[£)¼ÂÛœ7<«ÉÒŒ[o¥»%kkýX!Fœª§¬µ}Û½ÿ=nÿÉ;6?ðM¿ÙëÅÞÕ4vø«ñ{ÅV?ot»š-CN´¸ŠEPjÏgg ,dÝùHÚHèkÞuØ»áλ¡hZN£â¾¡g­^ëÓj(,]FêêÏìs™bû7ÙðÐñòF¤¸ó\_Š¿doxÏàçÄ?†p|DÒ|}­kv±]M§O«E­¬PE‚sžl¢L†feÊÎÊIø{À_ðN/ŠÖv~·ñÝŸ‚õýaõËÛSPŸBŠU»±ò±¯x©³Ý\nÊ!¼ÈDŒ ¿$óÚ-ÊÑÛç¬wèµµÓ}5Ñ šPŒ\zs/KÅßÖéZëºî¿|ûü(øoð×â7¿ kþ,´ðçˆçGšse¤ Ë8W•mÖu²pªÒIµ®Ìò(rÀ¯/Ö¿à˜ÿ 5­oQÖ§øÛû@ØÅs%¼ÓXÚÍ¢­©xeº•#i¬U·]Èw) ò§9¶\?ðM­3²¼ø™Út¦÷Tž Hu QþÖ³î7jbHÁ†bÊÂE9Âà\Á4¼Cí½ÖûFê²Íƒ&•î«¥^Mw Æ%“m¶£oi,MncŠXå¶‘äòcK‚ǺU\âÔçño׿ûì¼õ»ê(B1½´ôõVôïåky ¿eoÙËá7Ä/|_‹öø‡ñQžK¨4¨uË=î;çµHâe…àÒ’æ&€Zœù£6Ì߯ß`´ý€~ [YÖuÏüañMÍ׈m¼IÚ¯ìíΟÖ[!ies …TÀµÅÕúçAlª€ nµ…8¨.h=¯øÖóRrŒ­ußþæ|ïðÏöøuð·Ãü1¢ø×Çz•¿‰aH$»»³Ñ–÷NE ðXFó|чÿJ3à’ 86ÿ‚pü=ž)šûã_Ç«íNB²5ë6‡ÆUB«'î´ÅRFs·sÕHâ¿D(¥í%ÍΞ¶Käµ_ˆF«IÅlïžÿyùÙðûþ ¹ðËÀ>&·ñ[üWøµã-Z;û}LK¬iþyÌr;“çC¥G0GÞCF lT9'ß/?f ê|añŽ÷Ç>>½¾Öti4IôIÓM—K·â11^ÐÏ’J¼­=PŽ+éz)JWw~kïÑþÎnMÉîÝþiÞÿ~¾oV~[Á<~ØE§ÙiŸ¾9éÚ=¼B?°‰ô›ˆ¤ ¦ÓºæÂI* UDuEq„Ô¿àž^ÔüA¦ø‚ããgÇrÖ),v6ŒÚ#ÛÚ+¼nB†ÓKðc^­“ÎIã TTArÉJ:49T“VlüöÐ?à›Ÿ¼/ã?øËBñgíŽ$rG¦Oi¢ÝÙ\PÛ>žòBw ûàx¤ÜHß· =sRýþêSüXÔ&½ÔåÖü_¨K{}q¦éWRA ¨#šÅDÖl³ZȃkÅp&È8ÈÀÇÕ´UMóoçøÙ¿¾Ú„êJRç“×G~·I¤ýRo]ÿãÏÙËö#øAû3jšŽ¯àËŸx’ö[:ÎMu,®%Ñíí ¬vÓGn“FŒª7!v^P \ý‡ì)ðòkûûïëú·ˆJøRïÁZR=†žë¤éòÍ<‹qšÚIÚý¡×Ìßå° ˜ºçî:(›æ|Ïú¿_]^»êËX‰êソ ¿#óƒXÿ‚d|ÖuëÏOã_-Ì—öš„Q¾‡á‰ÒŠŠHÉ—Igž9ƒ32NÒ*3„q^¯ñ—ö$ø_ñÓÅ>ñ_*ñ–µ­hšy°5; Uº>dî³—K– í¯ú3¬¤nV9';Rÿ‚~üÔ¼­xI¯üMouªjÍÞ«¬Çk¦&£ª[êBì\ÙM"Úx1y6̯˜§y%÷}ÍE8Í­Ÿõ{þdÁrÉJ:5ý^zî~xhÿðN†º>»«ë+ñƒãŽ¡m=ºØÙé÷'C{}Ñ^fH ?Ù¢Rªg–IËVuÇüKáäö¾ÓWã¿ím£iÎ:Í%ÐÚ8--§†Xm‹>˜ÒH£ÈTÞìÓmwĈaúAECI´ßOÐ)ESø4þ¿àŸÛÁ=~ÿ£Í®|XøÏâíLÛÛÚ^Þj/¤¬ºŒ1G¦ -ì"X*ÕËFˆC0T {àìàÙɼ+¥x/Ç9Öü!¥^ZêPÙjâÐÈ—6Ú¾‰l­`V%´™Õ‘‹Ë)`Ȫ¾î¢º^.§¼¯¤ô}šM»z]·êÛêÆ¾²ý,¿$—¢GÇß b¿†¥:,JââHcŠ(Õ0~¸¢ŠÒ¥YMÞNì˜Å-õe`¢Š+1…Q@Q@QÕ.nì´ÝBòÇNŸX½Š’Hî\)"5g!cÀ,@ç’^¬ícGÒ7°ð–¦ÑØ6¶^È«]L4/³Ü¤+rÒ-£¶´±àN &"„È=Äß¶ßÿ |GÕþ_|9øí©kVzŸöl—_†_P·e_²y×_èîò-´o³ófdU_?<ˆæ1òz+~ÂÆú†™ðà-޵áI5}ACÑQl­´ÛÁkÿkSö8ü©´ˆB+β€H°´JЮ4_دÇv÷ÿu~ÎÞ"›JÕ—^¼Ôî´­6î]?Wš¶ûI˜+rÑÆ°yŠÌì"†;@Õ«FZÓV²¿ÞÒOÓI_³Ó¡´©¨YM;ÞϦ«]7ÖÍz­zž<ŸðSo€RÚxgT¶ð·ÆOEÕÊ[XÞiÚLë&¢æõSMd¶¸’Tº/§ÝFѲ‘ùr´NBפXþÚñ¼ð—âïˆÍî¿aáËù&†ÇNþÁ¾mä– ¨î®c™%·†æ95‰ ½„ð§Ãø'oįüWM ÿfoŠæçöÚgˆ<6mô]BÇKÒãæ*ð‰$T •dºŒƒt:·Œ¿à™ºˆ4µ‚Ëö7Ô<|úkÚØÂž‡Sl.`û$¡ghÛ’Ëlñæ6xLcs 5h*©´ùtvëkÝö½ÒjêÝôwç¨ÛMC{5óé÷]hüû¤½ ~Ú¾Óüa©x?Å~ø‹ái¢ñT~†ñã´º‚6âÖÖ Â-çy#†K›¥ˆ»×k<ЉóU½_öÕø[¤ø»Æ>>øãQ:eî“okln<Ó Ï.鄚$‘»-§Qó¡Jãn>)ÿÁ<´?jþ6—ì«câX¯nu]oÄés¡Ã=•üqÙ–šêC"ÜZ1`D›[åKbX­ñg죭ßÞ¬šÏ…h‹ïëúGÚ3&›ª›òF–GoÊ<êÊT<ˆn7s¼“ŒãÇYY'æï–¶ºæ}ºè´WUró_MߢÖ×ùÛ×mõtþÿÁA¾|Z¼ðM—ß|]ñKø…¢:k&™mh_Ì>{‰®Æc,Cà6îÊŽÛÅ¿¶GÃëíáùü-ñZžKëÍ:Â{ Ki"Õ.--Úâñ"Ý:°0DŒì$T-‚#+7Nºýü'ñ[½Òlÿe¯ |UÒîÉÔ.`²Ó-õ=>æ5·„™$ $Ñn-S$‚ðŽ®x?üEÿ‚vZø³Q¸M7ögñW޼E«ÙÝkí§[hòê/30µP¿ Vb©‘÷0UÚ 2\±{É;y·nWæ–·ÚýÐܠܤ¶_†÷Wïðô令±sÿ ø~gÓGøKñ«_ÑnZåÖþ }9íb¶¹›í(’^,ŽöVE]¡òèJ’1/¿à :†<{ý‰ã?…´ß I?Ø^ê.´k×’Í!†ê4¹e*æíy uS÷ö€Ì=_â‘ûxF5Š^ý–ü7k5œºÊÜkÚV—`G¸/2Hʼn}ÏsTmüCûjþ=ð›áüñ·‰|I%ëÚêZ6—¦Ý<»wi$žEùÀu³1‚ÐF+¥ò[_õþ½Sïe£Ši4Ÿõgýy5óæî¿oI®­¥€|ycá8~Â×Þ ¼ŽÐÛÂ×o¶ w&๎á[–P`‚sÅ.…ÿø®|Eð‡ÂÿìŠZW‰u™-VºÒ¢öës,[<’$Ì1+\Â.æŽà»[/uø&-¯Šu]Ã? ÿeï^év¿mµ½—šF˜·q™$ó°(³-ì2ùEæØn õ+ öñ©ø’þÎsi^¿ƒM“T¸ðíœ1i·Nc’$Šy"ÞQSpʸ!”c¡:JQæNÝ{îýzÙtÙõfV¿;þ¬¿áþ3¶øÛû]ü'ýŸ|Kká‰1øŸO¼¸ÓV´šhäŠö‘RQï»Å¼;¨\„Ëò# Áÿ¶·Âÿ|D·øYoᯉ/ŒŽ º]Ôö"Ø]Ì‚9&`~Pè÷¯Ì0O8¡©ûXkº‘/Ä¿†réšF›.…¥ø^çR³’ÃOGo*Q, — ùL ¶íÑßX~Å>Ôþø»QÒ?fÿ k"Ñeð¦©-–ñ[JT«ZJT2+’¸Ø@bT ’r¥ð¾—×ïzyinÿ†®jVvÑôû—ë]Pý½¾iÚ–§¥Éð¯ãíÔö¦à¼–Ú 3C²9Œ*í"\‰eC)Lã'hæ³-¿à¡? îu;í| ý£[µºŠÂîÎÛðÞÍotౄ­µÄ›ÊF¦FdÝ_â-òÓµ_~À_µ‹¿x^Ù×Tø¬ºMÊÛÂ=ŽÞ Ó­'fšaèÙá´nÌÅX·BFF¨ÿÁ9õŸ év2ðŸìÇ¡Ko ¾¯&â/DKëSe,‰Ô€Ê&Ys·,Ë·&¥FP_½ÓEù¿=¬ŸÏ]•ž“唚§~¶òÚÉüßÝç©oþGðâçѼ7ñ“Ä÷Vox5+]3æâãGKy<·’ñLÙ‚ØO±€ef ¬ Ûð'íÕ៉ï|1ðwâò èkwPêM¶šêi2Y"›²¥Y[sïä9?ø«þ úÚv‘â}ágÀ_æÚàÃxwIÑ5lÌeÚ@Òº€’¼QŽw õ¯Wøf?bè¾'¿øwáÙâÒÚ}*{oZÙézlrChU Å¥òĸ »ÐI’ x­Ý4âåÕ¯çÑÛ·[?•ºœõ½¢QÑ~;®¾—['ÔòÁCü©h…ï>|Gðž½oz–¦ÊmnDêÒ$e¢u¸Äž[º«ÎrP:üÕõoÁ/‹ò|ið~ã8þx×ÀvK#šĖNd +ÇÁ¶¸”s³w8àŽùò\WŸðIùeÓ<#o§þÁÓÝ-¸¹³Ò"Ó´'–8céMʪà`…àé^¯ðËã_ì5¡x–ÛÀß¼cû?ZøŸPÔ›F:ƒRÑä{Å]í ¢ÉHB äù˜ž¹4K•ü+Gk~_‹üt•;Ôz÷émÿ/éaQ_-èÿ¶oìë«øã_ð Ÿ4Y°2®ý^T°Žõ¢r’ˆì²JÂl8ùY«¢Õj¿ÙËJ𯅰¾¼]övbýd»¼_5"&82ÈÉ%Tãp'ší|Eñ¿à÷„µ¨¼9â‰Þðþ¿ Œ¥•æ¥S6òÆ äù±àuýâqÈ£üíóíêiÉ-í¾¿#Ô¨¯ _ÚOàå÷‡¼[âoxÓDñN—¡ÝYYê2Û^A1Ktш@žæH­Û>j$9ÎÑ—! íi€Z…õùu¶ÿ=¾óéj+Añ'‡üQi5ÿ‡5­3\²Žy-¤–Öe‘Rdb®„©á•uVÝ&‚áER¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(®2ûáÇÃÍOÇZÅ GÀ~ ¿ø™¥ØÜézgˆ¦Òà“TÓ¬çdiíá¹e2ņ8Ë¢°V1¡ àc³¯×ÿfÏ…ž%ý¢~þÔº­—ˆŸâ÷…ü?©xgI¸X¹ŽÍ,/^'^Õ\A#†2”‘´z.~%=~Oóz?&Þ¶³Ïåù¯ËT½W-¡~Ïß uø™›âO_/‰lõ=#Y‰ï‚·—5äòHUL`¡Ie¸TaÆÖ#æHã<û%~Î×¾ ø·£xSñ#èÞ-Ôm£ñ%Ö›ªî÷No³þðD«’~èC3HŽÓGpÊ^(ã9sûjJh Ý;â–áoxëÃZ¯‡ˆô_ ý›YÑ#¸Ô//-š+—ººÀoeÌdg×Êå‰ÞÁ4<]{áßèöÿ<9áëøn”¾ð}Æ—máÉ$ºÔ.YBš‘xb¸:†Ë¤æt· a—:ZSµ­ÍšòRºOºWr^gF#—šU#.f¤Ú}]â¯/&ÚQïev¶·Ñÿ ¿àŸß³ïÂíO[Ôô8üy©CB¼ðåÌŽ·,Л ›m2ÚXÕ@O•¤X(#yLG2HZ+ÿØCà¬qx«V›^ñêkz’Á¨jwš¨spѵ“$òªŒÊ4û4')ÏÌîí‹ðÃö&»øt|s·âƒuk®xFO I§Ç¢]Igk+8a4fòúâéb_™E¸¸•+÷J|kTÿ‚aÁ¬èzׄu?Šº ß‚ï,¡±‹Jo Hmt˜‘¥ŽÚ&½dH®üÙî6ܳ¦ÅÂà–Þ­iÎO™·îÚ÷éy._K;ö÷šÞæ6SITïëo…Ý|×ßûð“ö ð·„t;BñÏÅ=OÅž'®/#›E¶ƒJV¤ 3˜ÿy#«y…2;˜Ð,jÅTVí¯ì“û6|1øáß]ü@ñÝ—õ]^°ƒPñœoî’h®Ò‰Ô€›ìÈÐ* L@I a|Uý‚âGÄß|OƒÇ^ѯt¯ ÛøcQÓ„ ÙêðÄ’*¯Ëx¯ eic€³ìšiŸ,‡­ñþ á |Zñ_ƒmÜoë'gÊü“¾»{ªÖ¾žñƒö0ýw‚ÙÛ- EþÀ¿|k¢ø›Cñuߎ|Cm¬ß麶¦÷Ñoº¿²‘^ÚèH…#ÁŒ'ÜSŒäŸ>ð?ì«x{á÷Ç?x·â¾—ñÿÆf—QÔtJo6(ÝÝRò Rh§Á•ãÝm „FæÕëÉ?á×zÜKâ[OÚK=2æ;q¥J4­F[½-ñºkX–mUì$±Cå¬6²Y²Æk´È|±¼í̽ëÚË®Ûéèý/¹¬j9i'e~¾vMõè—ž‹Ñ}ñöBøSñ¦÷Ã> ñoŠ~#kZž—¦>oy·Ë¡SŽß)A+ Êì¡KHæþþÌߴωüAø}âïˆ:·ˆt]Bs{jò=”ײ  ÎèP$„ »•ýÙÚ ‚Ñ®ÞZOØfDøOàŸ…š<+¦iº?ˆu­rHm<-öm?Uûy¸cçÛGt7O—&T™]ym°c˜5ßÙTÑ?g­௄õ¹ñT~+]nÛÅZ=•®.—3\ù­{qÎërÅIY@ eÉù8N\²p‹´_âäÕÛ_{}ݵКÒ|š6í}<’’_6¬½Ge®þÁ_¼C£÷ˆ¾-EËL]m¼@ЕYÈd Šn.æ$Œ0Îp*Ÿ‹¿g…þkŸtŸé~Ñ}¬îÄ}¨-ü_hžØÃ ÃfÈ€R¬=ÄŸø'ÅÏŽþ øwán‰ñ~×á׉-âßNÔ¥ž8£C$ÚMŸ³f·Ç1; Á ÙÚÿÁ:—FÕ¼m«è_-ðèÒñ­Þ©® ÀfŠ[eýÞÑÊÜÈÆ2àã!qŸñ þ åàÍgÂúæ‹ðçÇ^#ðmþ§yÍôš‚ý¾ ‚Èï#,jÑí•ÄŒ»‰t¬ly¯ ñü'Ç÷žÔt _Ž>ÖõYoæÔe“Wð–¥x·2y¦X§ŒK¬°´½Gö¨°»1ˆ‹Ÿ³ì3ñ{Gñ—‚>%üRñ.‘¡^hú­Æ¡.”m®–kÙ^_1gCcªý@ï™nÑ’d†68­]iU—ï$ô¶­ôÒÊÞM½/çe©Š©Q;µ}?o饺uz³Ý,`OþÔ‡ˆõÏüA¹ñ®¨¶¶Wð\¤1Ü´`ãH#®0¨ *@À5»á?ÙÓÞŸö„ð%<4>$ø»I‚ò´Û€ºv‘Ö’ÞK§Ie<ù³Da¾Âcy«â¿Øê:ß5¿|VÔ|%.µ®Å¬ÛÅ.–.DR‡í6öíиIäÙ#f T…Q¸×‹^Á8ütt«í;Gý ¼5¦Çus̶÷> ¸º¶µ+4r˜íjhmã-B«|¬ÌÙ9 Ï757 =µ½UÚò³Ý­õ·réÆ0Ö=öÞÝ_Ë¿Ìô¯ ÿÁ>¾Þx/ øûâ|oqö(t·¹Ò¯L€ÚÂå’€Äî3-Æìíôo~Ã>ø§Â>2е?ˆÒëš$¯-ƒÝkUMäV~pØÏ'IóÞÛéÖ¾ ’ÆYÉ#Ë RIª´p¼ªû €"çæ#ÑUÅTI4ï×Ñß§þ•ë݉Чð¥¢Úéu^½vÿ€{Ä?Ø£öw»—Æ3ñ÷ˆ¼si¤ÝÊÚ…è¸×v[[gœÊîTF,àdôç#Šô¨>ü,ñ6ƒà Zx³Æ:”:ߨnã¼V{Ëè„RHÏåygr·`]½@¯‡ö ¼ñìÝð÷ᇈ|Aáñã;Vm~]KÄ~·ÖÞfŠh–0¶ò[¢Érª,¨ßòÌýìî®/Jÿ‚oj6ÐÙi‡Åo?„ ¼Žâ=.ËÁs[Åi#ÈâbÈ3‚aPÊÃUÉÅÇ›m-åoø-Ã¨Óø¹’w}^»uI^úýÅ߆?±/ûýwâg‡uŸ·¾6K i®'Ó4{x,§Ñn¥…•|çÃÈY |l$!ûáA5ôOÃØ³à‡ÂxÇž‡ÄñkúF‘y¢YOq¨n1X\0w…Ü(y£V‘egTffP˜Ÿ’µïØ;â7†¾xëÁ>£ð“â^«â_húÅÕ´ þÌÓb´<©žêÚ]I¾Úì¿3‘,EÛ¢ö©%ÿ‚cêúž¼«âo~ñWÃÖŠyô[ïNòObà"´¿Ú^K•ó”)’a@C`ЍÜn´i%êÜ7ÊíÆúÞÛœøk©¾m.Ûmvæ’_;.n›ì{&‡û ~Ë?ln‡µOø_D×o—Yë^U­Íë\}¦/%vBÐí†àåžµë~<ýŽþüDñˆ'ˆ´2ö"d°RݧHÅB‡Ž!U@¨±C²U]±ƒÍ|ð³þ £ã?i1ku_xsÆpÚ\éðÜËáx¦¿Äå¼û…hu "…Þ61¬ÆEPòY}{û9~Èþ:ý™µ?áñÿíc÷ai«éÃÂÒXE”̤Ùíº•â‘ Änï ªÉµp 4Sät¦ì»tÕ˧k;ú¶ìµ¶5jOÚ;jŸ^º(ýú¯¹$tþ ýоxJùµø«âHˆÞZ]¼C]À÷È‘©!õX£V\íÊ3HÍÁÙ~Å_³õ¶±ðx·XþÎÒmÖ÷@»Õ!¼{}>Xã†#"M nFŠ6NèØçvMxEÏüªk;_ÿÂ!ñcá—†µ{Ø®—x~4¦Eç^ÌÌÂ=J=ò¼—P»É€³[~ðÙRø%Ïfø“¦øÿ_ý¡¼­E±KëX<ªiókŸgœÍåÝÅ®ºq|¬VgÌ[ ÈðH²?~öšßV·³·ãÑtÚÛjT*ÔMÛDÞ¶ì¯gÓ½ÿíçÖçê—Ãÿ¤\hQx›Ä¾#Ó„ìök©Î&{8 nÌŠrÍïÚ·nüMáûèþ¼Õì­üI¨[Ü]ÙY;â[¨`1‰Gp†hôóÖ¿&¼#ÿ·ñ/‚¼oàýãŸÒñ´X´]CQ›À×É© M1dyµL’ía<‡s1^»ä²³I§¢ÿÁ2üa 'Ã=fÃãç‚fñ=ö¯©]øââÆÉi“{ê¾l›Ùä¼ï’ᡔݗ¦¬#íçº]u×§¯fÛÕê·Ôr§YCTïòÒëïzYh½Öú†âæÞÖ?:êxm¢Ü©¾G 73Q“Ü’õ$ üü¶ýš~3ü8ý˜þ+|ÐüeῊÚEç…õ»}&Ò~Ũ¦§u-Ãà “í+–ñ¤‘ i\\1žIÝ›pð˜¿à˜:íäút÷_>Cᵑ/“×¾{›m:a­Á«­¼@jžX·ŠX"Œ«yc%t¬gŸºî¯óëÓåø•¾Óëý?Ç×~Çëñ Iw5¥Ý¥ý­½õÕ½í”È$Šhœ:J„d2°à‚;ŠüŠÑ?à–:…LJ5 oã_‡5ÍbÀK·²økRškß2âÁ¥¸?iÖ%Xî&·³xeh•bsw;ù?<‹'П³‡ì›ñCöj¾ÓWÃ?þj~ºƒCÓµÝÏÁ2iV0ÛÙX\Á$ºj-ä²Z<²,C$“Avò„@ò—]iÓƒƒ”¥gÚÏ»ëÛ¯éÛ J\î)i®¿+íÞú[¿‘÷ÍùáàoØ./ üjð·Åß|AÒ|ršL­,v7z»îîï-FGk¶ûCH’ÜùE¥[K|ö€?Cë—þ¶ÿ;š=ÚèQE (¢€ (¢€ (¢€ Cœ¸ÝÛ4µàºþ£ûJGûDü=Ó<3á¿„—?²Ô¾Ô¤ñF©w{r¾"¶ÖƒÅö(í¢Qä5»/æ;³´‚»pâÕ¨÷¿à›ý,¼ìº£}¿Îß¯Ý®Èøã?À¿Û³âŽã= XñMÖ¯áË©µ‹6Ò-µ{kkا‡Y†ÖTýÊ–b¹Ò¼È.w5«:*eŸfûáßügR»Õ4³ñKÇ~Ñ"Žhô›ý"ÿÃmu$M¨ÞãíKu§J†ajúyS û©ƒ0aþ‘Øøöý«4Ûω:vð{B×BñMï‡-õ-óP¶Ô¶XO¨[º¥¥Ä’ªÈcfÏ"¦Ë§œíd‡é¼3ûT|jÕüñÛZÖ> ø÷Dñ…¬âk#ðÿ]"þí¯oà1ÀŒŠu5Xí­¥-fî6Ü» „ë·E»h’~v–ßðVñºæ·ºi“rTæ­«I¯+_^Ïÿ&³µÚ‘›û@|1ý­î~$O®üñV½¢Ø6…ig=üg@Ž}Nâ =PF“Éqfó²©ìä`Q±öD—Ç|Ið;öäñRøëÂ%Öuá¬ÐjóiÚ|úæ—w§4÷zƒÇÛ\Û5ÄiM§4D©°ÚȬÁIúO þ×µö·®xj?­ô}X×lô™–óÀ^-·–Ì >ֿ䳋W«¼·1Å=ÂClk²IKÈ_øÑûa~Ô>øÍãŸø#ösñwŠü§¶Úâx_»IŸÈƒj¤–êbºWšáFøˆÚ!˜0Â<ˆ,D©rÝ_~—óíç§oSJÒs‹„’ÑGü—Ï£ù˜>øSûvøiþ ’ À±ê7·Ú~ƒe©éV°Kgs¬]\ÜF­¦‘/š)PÄÛ–YƒWçègð7íýá­boøDµÝwÄÚ]Ʊ ò¾µâÍ=Ý-wiEÎ~õ—¢ž\Q"'È :xÒþÕŸ·Æâ sÄÒü ñO‚­Ê'…ãø}®iв›«TµŽ¶”G<“I;“XZ2‘2³/¶Ûþѵf±ªêTøoqgàÍ7TÑ+½;À>"ŽëÄÓÝ –å#cº… u‘–X²#Œ”¬ª¿´ºô×[ùíúug5»ûA~Ѷ? ~x†çàŽ¯6»¬ë7úV·m¤è·÷SÙZ$óEm¨$!‘àŽEH¦`ìïÈB¬¤~boÛÏö™¿—^Ò|ðpjךMÖ‘¥Ëe¨x3Ä3_¹•,šêév(ûJÀ.%±˜äU,S¦„dêÆÑMÆÉ쯧+û÷õzÜÒP•œ%®­éoævWWM-´vii½Ï~ý¢þ~ÖºŸˆt­OÀ?2i«aªøŠ÷Ož':¤s$0È’È¢Ç%v)±÷¹?k×äî™ûa~Õ^(ÿ„Ãð|ñOõˆ ÔæÓõKÿ„^(šßP° äI·s€Ò2Í´,g&½7âíûMøgJø}‚¾]xÎþóCÒ®ïn®¼¬Ân¤Úgòç²kvùšÎlÌÁˆ »I®vù¢¤¶VKäŸÝ¤^öéÝ4iòÞ7½îõókõ—çÙŸ¢´Wæ‡ÄoŠŸµÕïß‚ž3ðŽ>‡ã˜<þÔ_ï¯øËð¶W”éacøgâ­¤·þÐUe‰Z)ÌYE™£Uù±ƒ^ñÿãWí?¤ê*øuðÿÀ~(±Ñ!)`5ûO 꺭ý¼!  {ÛþîçÎ "ÒîDz¡RJÝ»/ÃüמúÉYÛ}¿ÿ“ü:´~˜Q_üLøÝûB|8ø®ü=ð_€,>!øOð妳oª-œ÷—**[¼sÇÇŸ$Êå¥Ú‘|Ñ//»&¼'[ý²l w¶ðΗû=k1øÆâx’ ·økâk­/ìîÑ´´Ñ-8v>SÊ®»Nì`šª4ÝI(C­íÓgn¾º_t›WIµž"j”J›%w×¥úWinÒ­”WÂ?hoŽÞø¯ø#@økª_éú}µƒQ| ¬ê—©2/›}ö¬ae†L£YïûA8m šùçZý±mMLŸÄ7ß³ìBR—H´ð/ˆ.î90+•¸V•ýó>vav UN›ž±þ¿®½žTÒÑ­Tz»~?×äöjÿ®´WâO‡¿à¡¶¯à=3Æzwìë}ã»;ûiot˽ῊÚù>Ë;ˆˆ ,²OÂ]YDÔ/ ~ŠøûQ~Ôÿ¾!|>ð—Ä‚úo„´Yµ4¼º“D¾Ó¦±2íy^ Ù–eŠá$„ÀëŠÌ“䀞©eõSqjÖÑê´i]“x{E³Iýû~-o±úYE~E|SøÁûTjÏ¢xׯ¶šµî«ž¡{cáGU‹A„kKÖ¨- $r \·œÍ¹A2ÚêÿiOŽÿ´oÃÏx¿Á¿~|[Õ´äÕ4¡c®éž Ö5“wg4–Ñù´qù¢[…{ƒ˜—˰ܯ%ªB5ÒM¯º×üôêÚi&í{Œ\ªº+uküÝ–¿Ÿe«²½¿R¨¯É«Ú¿öÐñ'‚-&~Âcâ­÷ÄÿøJüoà½cÃÞ"ø‹eãØôËÿµÌ6‹o¢ÛéËjû¯™ƒÛ¥ÂÌ=§ å’Õâ}Ö?y{·è÷J^WI¶½;»†´©ÍÕ÷ege¾¶|©éÕÚûyhº…á»7Ó¼;¢é:žÓÍtÐY[$´ÒÈÒK!Tny›«3rI5¡-ͼ2[Å4ðÅ,¬R%gÊÀ!Aêp Àì ¯Éû/ø&§Ž-ô«øÛö›¿¶ñ|Þ ‹W>$µÒ/Úúx® C*]j“Ûù›.¥'‚8$Ž%ƒ¼1¸ïu¿ø'þ£¯þÏ¿ þOñ/ÁÚ?|/{©jPxŠÇÃ7ÒGkuy§^YÍ-ŒWz¬÷V/þ™$Šßl”©Ü£àk8¤åg{ZÝßD½nûIÝ®m/{ùvõ»û»Ÿ¥4Wä­üãOŽz}CÇ¿'Ö/¬í¬ÖEðüñiÈ‘j"D€ÞjÓα´×Ñʱ™HO²Æ£ Gå{·ÁØ¢çáÄËoÿÂÇÓõ]4»)ôKm íà’9w3fº›Éc+É!0÷™Ìó>B“eÏ(ô[>þ]×Ïår¥Ëm^ë¶¶ùÝk§£³>ÞÖµÍ/ÃÖ'RÖn¾Çd$HŒ…€f`£;A dõè;×—iŸ´OÀíkIö—ñKÁך1¿Ót±r·`!¼¿òþÇOñÏæÅ±z¶õÇZøßÁ¿ðN¹¼sâ+­ã׈5qs­iú®—kªè­m Eo~'kx«A#¶ŠÎ×tŽä-¨r¤ `)õ„Þ1øaãˆþñtZ¶³á­eÌþadí¥ùÁ5»Þ9–)Œ<€êUXŒ±¬dä•Ö¾_w_¿§Þv:tÔù\®¯ºôÝ_]ýÑú+ó«áwìUâÓü_ñ…ñþ§«xr]'D¶¸]BÒ}<¢Uµ6 ößf¡[t– î¾sløwÁø'_Œ'ðv‘Æ[éwOmkí„zbG:<*|Éa^Ëoiö­ånbV&X¢$«­®ìº%ø·§É%_™Ïow›úéþoîï¡û \æ•àïèZÆ·â¾ÑõýM•õë[¢¸Ô ,Š¡¤ bkòëÆðL ïAk§ß|x:í¨ðݾ‹sw­hws]Ü]'˜³]³Ôm¬È$Ä‘½³óL¬¥E^׿à™÷Wz¥¬žø³áxh_½åÆ•§øfúÍ$é"'W³Õa+4 :ùNC"˜‡îÈ +vN6ë{ù~:§ÿMß¼»ZÞw½ÿðÆú£Z·ÅO‡Zö§öÏŒ4]7ìWöÚ]ß.ß"îr0œÿ’Žù®ùÝ#G’GTAff8zšüçµý‚$¼ø#ñà׌ükðçÅVÚõþ{<ßð…4V׿×kûw½^K>Ðe4[›qÚ3wàwìn|®üb´Ônµ_øCµhzuž¡­Åœ“I‚âú”´±ÆÈñÀ!šSˆàU@Ëf¯­ÿ­?ÏOÇk²’×Ëñø­ù{ßzÞÈû³@ño†¼TÚÂøs[Óõ£atl¯ ¼Å¼áü²GÚê~Œ*¼ká9üauðþ-MÃ`º¤º`“ý!- „mþæâ}M~\KÿÁÔ ÑtÝ7Cø­ð×ÃÒCÊiþ»±¶Õ,-¼¤Ëk«G)ŒNÊ 3ä `øñûø·âî¿¡jþøËáßÚZxzÃA{{ï Üj0·ž9¼Ñ7öŒR)>^%œg%ßœÔ^º÷·ÊÏ_¾ÊÞ¾¢­£´5_ðW§KÿZ¡õRþþËK±¼Ôõ¨l´ûxšiæ‘¶¬H£%‰ìùƒü6ÎËVø§«Ú|vñ\©â) ±ÓgÒ k/\Ê\@„®ÊpVY\L7†ØµÜüvý…5OŽº~‘¥ëß-t+-&æKÏùæi`d…#Žâ(ÒÞç'϶ÚQþQ¸Šº‘JÜ®ÿ¦õI|ïÞ×.[é·ü5×âþïCëañÛáÿ FÞ<Ñb›]ˆ\iQÈ]ê"ûM¬ ¢3aC6$NEz>«¬iº,0Üê—BÒ %XʱÛ¦p8u<æ¾ñÇìMÿ mÏììtÿx{ÁðxK²Ò£¹Òt;‹+ëÈ"UI­D^¤bkZOÄY!°JŠóh¿à›VöZ´>5êZõ–±x“Gm®øvÚæ×Lƒ÷¢H¢ŽÝàfÞ²-#¿Ê€lñ]¦ãUÝŸ’Ù¿6½lLãôºW]›½×¾^Wéúw±ÏsC"M ¨eu9 Bê+?x~o\øB=VÕ¼O ¢ßÉe“æ-»6Ñ&?»»Œú×åcÁ3&ø–Ò{?xËÀÑhÚ4zV±àù5+›7Šef{{„¾…bŠhÁI!16âwoÀÙS.n[Û«_…þæì¾~LQK™]éÿÁ/5°mâð¿ü9mo¦éúo‡<1h‰ö6‚8mјTŽ5ÂŒ°àõz=BMfE£iIâ­ÒÒKñl‚æX‹,M&7‰ N$ãšüÒ‡þ Ӯ٢çüoÓ¬’²ûO Ê£J‚,}Š[á²Õü½íÖààm~ÀÞ7ð×>øË_øÕàï.=å×—ámJÂïWnܼk¼ Y%žX%IShÆFã¼R”µvõô×n½?àKHi«í÷¡^(ñg…| dšÇ‰u]Þææ;TrŒÏs;p¨ª€³¶8áTž$'‡|qáßø—Kð׈tÍgRÑ®–ÇU‚ 7=„åAƒª±FVö ×Ä7?°£j?ôÏŠúÇÄ=][?ÿÂMÿ‡ ËÜ÷,‘É#\àɸ ¡UŒ ¤#â'ìâˆ_5߈—¿¼3ƒu=mõKÝO Îר 9-Öò=A –L’ÞQ\íù Pk8=5ìþNñ²û¹¾ä:Ú5É®ºúZ[m×—ï/ÑúçµÿxoÂÒh1x‹X²Ò$Õ/ÓLÓÄÍ·íwlŽë ú±XÜãÑM|ðûþ óÿÁß &øáâOêþ7²šÍ5kG·ÿ‰Ê¥¦XâµhKÆÓ¼²„2 žfÅ`ªsW?ðOÚkhþøÉàŸ‡>’‚ÆßHðDÐ^éá’ïs$é©*]—B"]»1óÜ.¬Teh»­5ü÷í·õ­Ú7jþŸ§õøŸ¨UÎø«Å¾ðN‹wâ/ê°hºº<“ÝJÇ*3³1íPªÄ“À¾,øûê!øŸÆP½üW—úÜw^´¶H®|U§3kQÛ»^hùQÞI§ ƶѦÅÚ¥2Š'<ŸKÛ­û~‡¢ák'×ð¾ÿuÞ¶ÚÝOØj+Àÿg/…þ2øCð˾ ñ‡Œ­|oªÛéо¥¨>ž^j:³—’òîW‰–ód}Á"†%N@È /¾S­¸§{uîa ]\(¢ŠÌ ¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Šç¼Yâ]?Á¾×|Wª¬Ï§iö²]̱”Ê£$.öUÉè2Àdõ3šŠr{"£'eÔèh¯Žü?ûs|Ö|{ᯇZ§ˆl¼®êº4úͱÖu½"'¶I-™Rñå«]"”@(à°ù7úßí9û8iú,ž$Ô~>|Ó|>’¤/}sâk8 Y€ˆ]¤ ‰ ä’1ZÕƒ†²Óú±+]µ=ÆŠùjÏöÐýšõOhßto‹ Ö5;Ùd¶[¸u‹1iÊÇ‚ ï*´’:KU‰_!Ôœ]ÿí/ðÖÊ+»‹?5é¥dKk{?Ø™.Ÿ`T/2¡%³¸ƒŒÔKMÆâÕïÐ÷J+Î$øÃðž/§‹%ø—à8¼.ׇO]Eµh³]ÚaÚ_wsœ×'ª~Óÿ³f‡=¥¶·û@|Ñ®n.ZÎÚ;¿YB÷3¨,cŒ4€»árp§ÐÓQmÙ ¥Ïs¢¾L“öæý”.4Û‹ï üwøUã;Ø”I&›§x—OËyPHašxØ)heŸ½±¶ç­x;öÛý•œ÷6vêÅKHÎàsÇò@ëÅR§'}6Ü·NJ×[ÿ_©õMà3~ÕŸ³%®“§k·ÿ´Á½+H¼kD¶¸½ñ¥²Î÷8û:2A—° ¿x’3]n½ñ¿àÏ…uKÄß>øX†Ô^Ík{­[Ã,Vä$eg)ŸQëIŧgЇµûž£ExM¯íGû5__j:]—íðVïR³6âîÞ?Y4–¦sˆC¨“+æ8Üzf³õ¿ÚëöSðÕý®•â?Ú_à©Ï3[Ám{ã > g”1Rˆ¯(,Û•—<©©r»ØqWØúŠñ Wö™ýœt=NÛEÖþ>|Ò5™îVÎ K¯ÙE4ó°R"Di3éò€Oμr+»ðÄ_üSðÝ¿Œ~øŸJñ‡…¦–X!Ô,dó ™ãrŽº0 ÈÈÈ<ÒZíýW_xù]¯ýuÿ'÷3´¢¾E·ý¶¾ÂÓñ‡Â­gS¿ð½Þˆ×‘ÞëZ„–‹¥FÖÅÁæIÙ­ðÎ}¡"Á•7`=HþÑÿ³Ú½ìmñËáKmkíŸÚ†ÝÉ +3!‚2íD]Ò’Ù«¯5ý&L´n/u¿—õsÚ(¯ñïÆï|<Õ|%¥ê¶ú¾¦5› CS¶¸°Ë[ÚE’;f@ìHv+ä°dg7á§Ç]?âOüyà5øñÁzž…¥Ð¹ÖmíE¶­mp›ã𶏔§pb¸Ì8o/c+5F-ÿ_×õ~Ì$ì“}Os¢Š*@(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š+‰øà âŸüKðûŪ'‡õ[ckvl®ZÞ,NÙ• 8-¦Y£TŽ#óª’HÀ ƒö\òïýkþoïtw_Õ÷ûì|Écû&ü.Ó4†¾Óo§rnF›*1ddrÊìη>âNêó?°/>*ÍãWIñßÄok¾!w7ÞV¯rÖq‰%ÈÑ[¤ˆ‰+:!óNæÚ¦>Q™OÞ´Sm»ymå·ù Ž—K¯õúŸÜþÀ¿³þ¯ká§ñ‹u«kö_]K©F#‚k©îíVÚá×jfÛ(£gc1ôFQYÐÁ9etÓ<;§Ýø&]Jm"Ö;=2òWnlQ7k†wmàn,îÄ’ÄŸºh¦¤Öû·/OóÕýïsáþ ×û3xoAÒ#òtë™î´ë¹5×¶rM$o# ¾k³yQ‚ò3ÈU@,@ôŸ‚þ ü:ð.àMðý¾ª<8’¦}ª}}aæ\¤òƒ"–Î dq^©E?i+rßA=eÌ÷>U׿c¯„^#ø{¨|8Ô'ñ¬:]Ö¿yâk‹ë]Yíõ 5 •™%—ÏŒRVy+†\‚¤šño ÿÁ9~iþ'›^ñ†³qã‹[mbÏ[Ñ¡½±†ytÛ›q"£y×"gl¬žAÞÏ *îÄþ‰ÑD*J/™?éZßu•‚k™r½¿Î÷ûîÏñÀßxëÅšo‹¼Auâ î¬ìWO·µŽåRÞ(„é1ÂíÜž4ÜCr)㊿ðÇá&ð°ø©ô¿ø×Äsjú„š•ÌšÍÿÚZ9ª¦p¾€ä€Õh¨Žš/?ÅÝýïQI_WýYY~Q@Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ÿÙPK\1A§"O6é6éQuickLook/Preview.pdf%PDF-1.3 %Äåòåë§ó ÐÄÆ 4 0 obj << /Length 5 0 R /Filter /FlateDecode >> stream x­œËr#·†÷ýØ¥UÅ‘y§˜¬—“r6‰cUÍÂÊÂZ¢=žn™3r̼_+Ï’ƒ¾`7È%Í,H¡ƒs¿Í_Ü7î7vã˱ý›,¦‹«ÕÚÍÆëËñz¼vóñØí~po]ã¾øòãĽûè&îã;[`Oü’‰ûàf“ôgõs÷gw5¾ZÏV3÷³6H#[w xùv þY(‹ñx¹Z3(iÄC1Ħ1#ÂþrFÏåbÜýï†ÞäÞÕ»î/×nržÚçd5½œMW·\ºëî‹ëëÉåØ(½¾sß¹úç 8uõñóöÂHøxQ…/û†¡O[¾ýgd€åpïâ”6.¯êO»c{=æSks&«Ë•«Ý÷÷úÎvᳪ?0P»pÿv×w_]™Ÿä‘ðh>[_.WÓµñ¨ <šÂ£Ú]¸ëŸÎ<ÌŸºù•ñr=‰@g5Æ_Gfl¡E¬cÀ}ŠSØ}è*“M’û>Nyx@{-kݾ}Üe‚ÞiÝ>~º0EÌÄß6®½saW…BL›çˆ±¤Šîa×nQ ž»vçüÔ#õ]Ä+Mû47`±ñkû¨6 tŸ¦ÝîÝ£ÔYø4“ìùJÓ“íd¼(wÃæ’»‚ÆÔ»ý!R,[ínê?À€"»‚3έꛋQN°ÐaS¸ÖT!ÀþH3ݯ†9,Q>ïKù©ü!y™?0{ؽ“jÞoÎ^ÝýP†LÐ]!Üz1c7µLB+æóK0Ûæl1=¨Îu}=˜¬£w5#¯ð®ß‚Î^¬W…*ª¡ÓËÅÜûÀ?ãƒÿœ› FS#ºòi¶Û7ãåÌ4à r–5]:÷õ]BÜ)ð»Ô{OJ¥àcÞgÁÍ0ÍÛ>"wÞ]1hähñ w‰^`äþ¾VJt`œ4­dGç2®¾€ç«‚€a^s× [8ÅÌ1ÅÏ~y„HÑÖ7Ö.~3ÉÅ’8‰Á˜k®÷WöxC® à<÷á*(Û= §K÷/‚„dº‚@Ju‡š€¹Nº&‡ÆÚüî"h¦ŽÆ\@9íB÷ ßšûK ºêJ…'¥}A/û‚®ê‰~~Ò¸´„}á&ÜÊòõ“i£8Åҫ伂6kcN8Um“]_0ˆ¡QHеO¬¶´¿V’d+•¹ö6ä}UÍ4–¡mÅeòêÌbÕÖ;÷Zôb”ð}ÈR†Àö£,¿x0°ŸARîÂ3t*úWó€=AŒ‰m3zFqY‰jrUª. Ý›, >bä6-8>2TzÂz8coÙ7›½k™"‡í“óÀ@¦1vK ™€ÌÜC+»M‹°.í×ÓÇ[p5æóÉf1ªÄDJÝ—'¢ÝݤhbÉ—”W„m«úTb//ó„âtN¢œ×‹BO6£‹Ê:} ëZž¯ûyH:±¸êkšé{IFw]§téê;PÆ:`fXRÕ¿2ÁSþ(¾a 3 ðy0êŠ9SÊàŒr¥S¤9äfÌ:˜Õf®YÞp Gû `yp´›(dQÚ"úNÝ#Ð*¤PÚ!‹Ià·³®@Õmû !AÚîÚÇû­kÖr8Louä¡÷y00³Ã¼a -·ÅƒD…uFõÇ£$8NdÉvćXæUµä¸+¸ƒÀ&pLÚÀæÍ½ug)f`^#Ö—»‚¹PùÓs2»Biå3»Y^›„Vì9™Ýj Pcf‡"û`¦xü^²ñm}í RÚ}–cëÎîž|/vè<ºë«óŸï<êÙgwC°áˆ§×,ìíɳ» 1OícD 73é!u“‰z@aZºv ù r×îÎÜww@ôaàóŸ© ÏhŒHG¢q¦S,í™ÝÐ{R>Ö‹® =/6Ʋ»rž®m N]?¦QÖËy_‡¾Ë{Hàog\Ï:N¾ÒqBU«Á ^#KÏŸsœà[²ò·Ïîú;ëúWv-Þ{Ô#;»ëŸicà6C'.}ií$u:ñŵÁœÑ)m(X~°í-Œ^6rN*;„ÚuaæC¨æN0ŒRÝ‘Q °©LíÏV­kG&r ð+»DD¤˜ãÓ¼Æð˜.Ed=u€R%˜*¸=´*þR»ß2©BLR:Œ ’ðɇº0èÍ‘º0&v²º¯M²€mÖ€ÀRõöÜW,‚ð׳B“0Ç,ðVgý(‹Ôê&e9HàVpÑ*ü*ŒzY}Kù—u+=ôÀ®#‰t¨ã›qRžWØíMÿEàû8kÒ ß‹`&z¦tƒ^HE´©¦ê‘»ÏßèºF/¥Eg¹‹aðèd»—jÔ'¼!ån“4TtÁø-ÊxýTåVœFÄœüÐaHO¤±ñ–X÷¬š(O€»nÁb:íÛÃ9.ö˜$†PÍňz‘£w|±íèO¦]’9'âRÔ³ìÅ#%)€²Ð éuÞ‹XeªYº SÌ™0ÐEŸ q˜ø(5ÉP¼‚sI÷ÌõÇ1Îfi¯æšO=8Ë€DæÅlP ›Ú˜“*„¬˜¥¤ü÷¸6ÀòÞabô™J”¸„ iJ‘Eã«TI‹Å€Èzþ UR®1ï«h3ºØuvÒ+z/2“f0Õν8Ën[S³*ÜýQæÄêEôÏR?+]ÍFnìÎ*àd5L–ÔÂ,kè1]ô/‹›Åf eÓ@-½i¯4qÅæ:r9…3­Ì}Fì癥Çè…Ñ Œ2%=•8›ÿ­ü[¼©GʨÅjPŠ›2|¶b©ub‚}¤$Tĉ‘pV®‹{µ P¨©R‰C Ôaâ‹)¶$—?³CNí)´Ü¦ÏNÐéjt½àcw£ ÄvœsKœ@œò>鞤_l"³mþâÈØX&"Sb|w–s=ªWÃÒº»BºK?¤_ñI<Â&2´í{§w$R”ìä1˜¿v3ž*Æ ,»È*š¤½Ù†½ü§Vö"Zz›2ê‡5B âéé^´!6lÈ=Ê$t´gqth˜2=hµ|ÞGØ›þÛӋõàHÔ|Äé#Jc8QîÀP*$_½Ê¦p” —Üò7ýÈÇ@FµvŸÉQ%CÉÌì2Ñ›ãþŠ7ù–/±—±ã÷, Á0§ùí»ˆcl—¼¥€ú÷áëPœ¶±+–/ýT´Ç×g¹a~ÂÊÒM¯!c*sSk?õYȳ—É /y}­wëú$@y\I†QÈœÿ†"ü,Ý6 !Œ¹Šßai×Knðv]ïålXA-ÎÈç†%Täõ®ñúíÉ®w WV$iôÛ ž§._`¥ò<ÓÍÀÅi©vË£v´Äû¯sö½ìÞ¥}í³oƒÚ¯‘MØœ(d@LžÚoe(#°ÃìÀ5ý¾Î*õÚÝû´6{U½×–§O‚î[°Ÿ…ºÉ芦¥,=©olÇú®X´f™6O}°^0Æê¬x×ñËì·ë€,—CûýýÅïë –tfÓB¤ØßïY¥£EÝãÒJfëîÝû&L!ó°_UoT÷:½ä­¦k_Ñ@2iåÁQr±Ý±×;ÂB3åT…[ô™ÓU@õœúû9Áî½Àë9uRA_ùy6Ù¢å9J4ŒŒ]ëq¹õ&îRÛ/a¸¶â“q-¤;xñ%þDJÓNÿDŠ IçÝÄg½âliÝ¿>R½B7qÙA=ðêÆ\ïûÀ^H#ºõ°M®÷¿±J'n%Ïš¯ Ÿ¼¬`Lj“TXb”ŽöååkUÙª¢Rî~—$ë>ù¥…›;ùRƒÔ!K*ldºqÝïÇHrÈþXÉ®c§x _Ÿ^®1ÀݧDt§+<ý7ÉçUJ¡½:"–ÞƒK¯¢40ñ¤Ï°Þ3¦Eñs¢Ø°Edÿ޲«ž<= b>6òÖö%AÔ_¼òÄ~ñˆˆëi‚üÍÿ*6û endstream endobj 5 0 obj 4515 endobj 2 0 obj << /Type /Page /Parent 3 0 R /Resources 6 0 R /Contents 4 0 R /MediaBox [0 0 309.0909 400] >> endobj 6 0 obj << /ProcSet [ /PDF /Text ] /ColorSpace << /Cs2 8 0 R /Cs1 7 0 R >> /Font << /TT3.0 11 0 R /TT2.0 10 0 R /TT1.0 9 0 R /TT4.0 12 0 R >> >> endobj 13 0 obj << /Length 14 0 R /N 3 /Alternate /DeviceRGB /Filter /FlateDecode >> stream x–wTSهϽ7½Ð" %ôz Ò;HQ‰I€P†„&vDF)VdTÀG‡"cE ƒ‚b× òPÆÁQDEåÝŒk ï­5óÞšýÇYßÙç·×Ùgï}׺Pü‚ÂtX€4¡XîëÁ\ËÄ÷XÀáffGøDÔü½=™™¨HƳöî.€d»Û,¿P&sÖÿ‘"7C$ EÕ6<~&å”S³Å2ÿÊô•)2†12¡ ¢¬"ãįlö§æ+»É˜—&ä¡Yμ4žŒ»PÞš%ᣌ¡\˜%àg£|e½TIšå÷(ÓÓøœL0™_Ìç&¡l‰2Eî‰ò”Ä9¼r‹ù9hžx¦g䊉Ib¦טiåèÈfúñ³Sùb1+”ÃMáˆxLÏô´ Ž0€¯o–E%Ym™h‘í­ííYÖæhù¿Ùß~Sý=ÈzûUñ&ìÏžAŒžYßlì¬/½ö$Z›³¾•U´m@åá¬Oï ò´Þœó†l^’Äâ ' ‹ììlsŸk.+è7ûŸ‚oÊ¿†9÷™ËîûV;¦?#I3eE妧¦KDÌÌ —Ïdý÷ÿãÀ9iÍÉÃ,œŸÀñ…èUQè” „‰h»…Ø A1ØvƒjpÔzÐN‚6p\WÀ p €G@ †ÁK0Þi‚ð¢Aª¤™BÖZyCAP8ÅC‰’@ùÐ&¨*ƒª¡CP=ô#tº]ƒú Ð 4ý}„˜Óa ض€Ù°;GÂËàDxœÀÛáJ¸>·Âáð,…_“@ÈÑFXñDBX$!k‘"¤©Eš¤¹H‘q䇡a˜Æã‡YŒábVaÖbJ0Õ˜c˜VLæ6f3ù‚¥bÕ±¦X'¬?v 6›-ÄV``[°—±Øaì;ÇÀâp~¸\2n5®·׌»€ëà á&ñx¼*Þï‚Ásðb|!¾ ߯¿' Zk‚!– $l$Tçý„Â4Q¨Ot"†yÄ\b)±ŽØA¼I&N“I†$R$)™´TIj"]&=&½!“É:dGrY@^O®$Ÿ _%’?P”(&OJEBÙN9J¹@y@yC¥R ¨nÔXª˜ºZO½D}J}/G“3—ó—ãÉ­“«‘k•ë—{%O”×—w—_.Ÿ'_!Jþ¦ü¸QÁ@ÁS£°V¡Fá´Â=…IEš¢•bˆbšb‰bƒâ5ÅQ%¼’’·O©@é°Ò%¥!BÓ¥yÒ¸´M´:ÚeÚ0G7¤ûÓ“éÅôè½ô e%e[å(ååå³ÊRÂ0`ø3R¥Œ“Œ»Œó4æ¹ÏãÏÛ6¯i^ÿ¼)•ù*n*|•"•f••ªLUoÕÕªmªOÔ0j&jajÙjûÕ.«Ï§ÏwžÏ_4ÿäü‡ê°º‰z¸újõÃê=ꓚ¾U—4Æ5šnšÉšåšç4Ç´hZ µZåZçµ^0•™îÌTf%³‹9¡­®í§-Ñ>¤Ý«=­c¨³Xg£N³Î]’.[7A·\·SwBOK/X/_¯Qï¡>QŸ­Ÿ¤¿G¿[ÊÀÐ Ú`‹A›Á¨¡Š¡¿aža£ác#ª‘«Ñ*£Z£;Æ8c¶qŠñ>ã[&°‰I’IÉMSØÔÞT`ºÏ´Ï kæh&4«5»Ç¢°ÜYY¬FÖ 9Ã<È|£y›ù+ =‹X‹Ý_,í,S-ë,Y)YXm´ê°úÃÚÄšk]c}džjãc³Î¦Ýæµ­©-ßv¿í};š]°Ý»N»Ïöö"û&û1=‡x‡½÷Øtv(»„}Õëèá¸ÎñŒã'{'±ÓI§ßYÎ)ΠΣ ðÔ-rÑqá¸r‘.d.Œ_xp¡ÔUÛ•ãZëúÌM×çvÄmÄÝØ=Ùý¸û+K‘G‹Ç”§“çÏ ^ˆ—¯W‘W¯·’÷bïjï§>:>‰>>¾v¾«}/øaýývúÝó×ðçú×ûO8¬ è ¤FV> 2 uÃÁÁ»‚/Ò_$\ÔBüCv…< 5 ]ús.,4¬&ìy¸Ux~xw-bEDCÄ»HÈÒÈG‹KwFÉGÅEÕGME{E—EK—X,Y³äFŒZŒ ¦={$vr©÷ÒÝK‡ãìâ ãî.3\–³ìÚrµå©ËÏ®_ÁYq*ßÿ‰©åL®ô_¹wåד»‡û’çÆ+çñ]øeü‘—„²„ÑD—Ä]‰cI®IIãOAµàu²_òä©””£)3©Ñ©Íi„´ø´ÓB%aа+]3='½/Ã4£0CºÊiÕîU¢@Ñ‘L(sYf»˜ŽþLõHŒ$›%ƒY ³j²ÞgGeŸÊQÌæôäšänËÉóÉû~5f5wug¾vþ†üÁ5îk­…Ö®\Û¹Nw]Áºáõ¾ëm mHÙðËFËeßnŠÞÔQ Q°¾`h³ïæÆB¹BQá½-Î[lÅllíÝf³­jÛ—"^ÑõbËâŠâO%Ü’ëßY}WùÝÌö„í½¥ö¥ûwàvwÜÝéºóX™bY^ÙЮà]­åÌò¢ò·»Wì¾Va[q`id´2¨²½J¯jGÕ§ê¤êšæ½ê{·íÚÇÛ׿ßmÓÅ>¼È÷Pk­AmÅaÜá¬ÃÏë¢êº¿g_DíHñ‘ÏG…G¥ÇÂuÕ;Ô×7¨7”6’ƱãqÇoýàõC{«éP3£¹ø8!9ñâÇøïž <ÙyŠ}ªé'ýŸö¶ÐZŠZ¡ÖÜÖ‰¶¤6i{L{ßé€ÓÎ-?›ÿ|ôŒö™š³ÊgKϑΜ›9Ÿw~òBÆ…ñ‹‰‡:Wt>º´äÒ®°®ÞË—¯^ñ¹r©Û½ûüU—«g®9];}}½í†ýÖ»ž–_ì~iéµïm½ép³ý–ã­Ž¾}çú]û/Þöº}åŽÿ‹úî.¾{ÿ^Ü=é}ÞýÑ©^?Ìz8ýhýcìã¢' O*žª?­ýÕø×f©½ôì ×`ϳˆg†¸C/ÿ•ù¯OÃÏ©Ï+F´FêG­GÏŒùŒÝz±ôÅðËŒ—Óã…¿)þ¶÷•Ñ«Ÿ~wû½gbÉÄðkÑë™?JÞ¨¾9úÖömçdèäÓwi獵ŠÞ«¾?öý¡ûcôÇ‘éìOøO•Ÿ?w| üòx&mfæß÷„óû endstream endobj 14 0 obj 2612 endobj 8 0 obj [ /ICCBased 13 0 R ] endobj 15 0 obj << /Length 16 0 R /N 1 /Alternate /DeviceGray /Filter /FlateDecode >> stream x…UMlUgתŠ´U+•'þZEi´ * ®:i"×ÍRm×ÏñÖ›Ýewí6QO¹T!® „z¨Z~ÔæÒ^ЍTTÈ©H­ ª8â›õÚY‡CÖzö÷æÍÌ›ùfÆKÔ}Ñð<»KÍ;¡_˜Ìξ<{Ltß .Ò¨‡ðfàeK¥ ÆŽëHþí|î}K)–ÜÜ˾:Ï6Ý¥Ë20¡uË-æD|ÿÝXÏU·©ºú$Ö~uB}NR‡I¨/¨ÔçÕ<¤ÃêþÈÆ‡í¼®çÁ7ޅצ§×¨žŒçÜŽúÏ{ç%ÿUËüæÍß:,ÝvÜsˆ«¹ksöÜ$GÈ­ëÿ³!“|];ûåöD„bU½xüfϵ³t$Y‹¨:åµHßNßI¯âûVz-é#ýCz Ÿ[”E½ìˆÙydÇʈëx0q€ˆê¨+G¿·#Ç؅бéGœ¹‘U€ ü ËZÄT²æ‰žèÈ—sgWœs;<ïć̫|½x¯HK}úÇú/úúwú¯úªþÐÏÑ´ú¤Õ%Q÷)o)Ÿ)_)—”Ï•ë$”+ÊŠrY¹ª|¤|ݧ®(—à…u[=×ì±vfšq1ܱAÄk3o,mEp gë™Kä¶ñ†Î~nߥÔvjjyíaíqmBëÕöi´mÚ Ö€6ªíÆÉÎvߨq5y¶’=kÑlÄf³’UüúˆÒÀg=.žS‹f·E§#‚¨fàÿÓÊs…¹H½‚ÞµÔ]ê€:ÏQV݇I!ž´ÌH&ŸÉ’Èôf†3™ÃŒ}sÊDf7N‡ñ=ÒΈY1“:yÉ„sÚd{}^ø_‰{‰½4€mìd(ÏàE”s½ßš«†bPןY¼"¥sÌþ>aضˆŽáË@ú Yî'~ÿ²ÑG£÷jjëu³î7š2J¥¾&ú"jˆê endstream endobj 16 0 obj 1088 endobj 7 0 obj [ /ICCBased 15 0 R ] endobj 18 0 obj << /Length 19 0 R /Filter /FlateDecode >> stream x­\KsÜÈ ¾óWôqTµ¦ùæ0§$Ú’J%»±R©Tœƒ-É–w¥íØÚÿ}¾~|Ø3’¬áH‡!Aâk~¡ÑüÅýè~q•«Ê ußôëqrm5•ÕTM®«*·»vÿr÷úüsí.?»Ú}¾žx–Úݹ¶ÖÛâ6ÜF¸uµžÚ±u·R€Rn܇ˆâlqH·EDé«j§Ê (%¢@ èPöUø÷…¹Wö²—wî®nâSüvë²qýÚ]ܹ×mYA³‹n5–gîâ'÷§ X:7^gXy½,fóbþãV?œy)·º=ƒðø½N¿ïÂo±úÌøÀ]ñJ}J<7‘Ë­¾dhîË ø2;)y·ý){û2ÝÅ}ØîÜoäæSÂâk7îëöAŸo¨Ë•ã%üYŠ'öÖ]&¸í†´_ÿ@’ðÝ%ÙkZ¬„—/P±ÖïÎÜÝÅ_båzÇoÆ.ßô®í†r¬ÇÆ5]WÖ]ݹ©ì§~êÆ"ùUîÓ¼(w?”mÝ6ðåf¬ËaF×’v+´BJñ´¼ä[wc¨ä¾C; ’¶åºÅ?p˶oá¸ÍP—´†ìñbOÒ>¶×:¶Ùͪ®‡&HV Õ¤-GüyÔ¡ ´ Y i§aÑò”vJ4/m(x†èß´/ƒHšETÞç}? ß»ó7©)¾9/žhŠj[Z­¿[·ez t[ë5””zŽ£ªô\7îMìëJäeÕ[ä"‘ ;@tËø›F4c/i~þÈ-*ÊwŽèŠº ëÁcù«1™hRÂ1zdà(ÇëP }7¶C/eät•ZiòRúʺ.ÛÐâ8U7ôý—ôبÍÌùà Q˜AƒF…ùa»îç:Ðbå¤cf÷Åþl¯3zf.Ò(ü²Éøê¦-žÐ‹='ee*=)pH2£{ð'‡¤8âét>‥CÀv÷VG÷gŽâl®0ºåP³Ñ-"QZ[dÚÝ"_›nÅêå£[„›©æIÅJU£hŽîAÝ(#_xdt3†ßs(é®ê ]Gß:ºÕ]ÆÎî0ºŽn-fG˜¹…ñ‚£i:º9)å¶Ø/Ù·g¡¶ä>Ýè6ŽvðïÚ¶)×ͺ Ò²“fG·¦-ÇvìÐ9+¯Òn\ÝNe‡?‹8®Ë=Æ\E$­h•[y•ýѳ6xK¹ïB)S7a¢ˆžÛÓ,¢òÎe&7f (%(fI›! ¯EœÙÂv3;âÍ@³v¬Æ²ö¾µ£Ò¬É}çh3çm–I+ZåV;*ÍÚ‘ÜÖŽ¤aÖ"vTnµ£ÒìL†ÜÖŽ¤Aëd[+£Îd,¢Ú±ÊÁO»üÜþHš±cãÛhÕ×ÖŽ†fíHnkGÒP ÉG Ã-v44kGr[;’fìh¸ÅކfíHnkGÒŒ ·ØÑÐn´m‚jMèoÕz0-æÇëõ„YœXž4¼g¬qh$qô6á¸ÛBm&4߇± GºXÂÑ[å!:Å(cÇjëõb£MzÉ­ò(G¢…ëL[L‰¦™‘ðf YKõcÙŒÍzæg‰gz'Ä™}¢ÒQy-"-j)!Î,••¦ˆÊ;CdßåmšÕ„¤©Ÿ¹Æ ¯ET;bÍ0X±›öÚfíØaÌì‡afÇDËìHnÓ^ ¢ÚQÕŽÑØBd46K4m¯îEFå!ª-QíH¹­ ¢ðZDµ#¨u_ÏV™^ž@³vlº²ê°€²-7Ñ2;’ÛÚ‘4í÷\£ˆjG‹8³E’Qí¨ˆJSDå!Z[Pkiʨ¶5ˆÂkÕŽ}°ÞŸÃ iÖŽ}º¦óÑ6åM´ÌŽä¶v$ÍÚQÕŽÑØBd46K4늨¼3Dµ… › ¢Ò ¢ðZDc D.êi67‘ÍØÑÏb1Ùäev$·µ#iÆŽäF͈I ˆÆ"£ÚQ…Fn /iQm!ˆÆfª5}”Ü‘¼¤=Šx82óTtoà£1ÓtS©Q™+|xzAÜ$­) b =Ñ üeˆõÚ7ÄW÷@_ˆ××¥ 3åïkT§wð„×£·]ˆ¸F´ÑZcú°´oJ„ä+µåº+rZˆ[#f+Úô¾¥ˆ17¬+Ū1^x|Uµ~ÀÇÐÝ=Ý-r÷„‘ÜøKÜ=bDw'úwOxÉ݉¾Ô†tw¢/q÷ˆaÜ=.r÷ˆaÜ=•²ÔÝ“lÑÝS!KÝ=ÂwO…,u÷¦iŒ»§»Eîž0’»‰»GŒèîD_âî /¹;Ñw÷„zw¢/q÷ˆaÜE,éÝ#†q÷TÊRwO²EwO…,u÷cÜ=²Ôݧ óvîñf‘³Gˆäë |‰«ˆèé z‰£G´äç úx7ÉËô'ÆÇþÆÃcK< ý;–°Ô½ŠñîXÂRçÎ6éæ9y‘Ãç`Éõs2Ò7ŽŸÍg`±9dÄfÑü>CH Lôs2¶)ŽñçP©ÙääEk€ Ì4¥ìI½h𔙿•=Y¼NÈðÒ‚!£¢®–­2<Ó ³'¨3¿£¼˜]ûfÝÈÚorñîXß²°X§ø½4¿¤l¸;,š5×€ w'€­!%—€>oÁß­ˆ+@À†»SÀ¢Õ˜,‹pwX´R&nNŠF1W¥+áàh~ùÏ`dœ0Û\]UÛªoÌ©Ôažm‚˜hØHõKõÿÈ óY‘K³M¸U³M‚ »¸´É‰‡òNV{w‡dæ&zQeë@¶ž‘æ÷§ÛE¢*ì\Ôçc˜¬'30'„y%Èàˆ™WW;òHn .æYz÷5!!z¸u³HM…}©šÏ©Gu7_¦¨„hEQŒ…v£†EŠ*ìKÍ“PX¬³û›í&^«×)ç3Xþ—×ã3 NL3nŠ—¤Ü>’àÔ!óâ®°©½HÜú;3Y7î=u¸¡¼TîƒÛ~8WR”¢×J.Žæñä)J£+ˆw«IS l¦÷Û_)Ów!¯–‚}”6Âç"Þ6]&½WKˆùG;º«È0S0“)k—K$Ê!y»îí¡|æ¨!á¤xr»{1¤Y§y"Ç3¤œûXÿ¬î®$í1«‹5C)¢xH惯oÏžH¥ª»²:Ì„Ržpß#ûÛ—š&üh"U=„Œ"?ùM–&,´¸ñi© ›GE’OA`ê°ðž.ʧê¶²@‘Ä Í‰ýÝÏî=Í*"³œ+·Ý¸7gÆT|@àaãæÇ4cµÏt8s}‡=­ÕhÍ•)V‡”yiº)Ö&m¨¾±ª7ÊøÝª/깫-½çá€4±Ü>[ԙI¹r|´!"î¤!¸séyi{¶ –ªu¥³„(+¢jAnÏà⯸…ÖËØn^IåJ\$Û‡Îõ×O:øÏgü“~²¹ßîXº⯩—`áÏqhÛ°}s Ÿù¶ž9¶ìöÛ÷ …äï=–à2ÜÊà/eM¶ÑŽˆœTJj2㟙º+·»³›¾ƒ[}dI¹‰‰C;jÍ“"^ý:¹Ùû¯¯„Fï"<ê —ÚÚ°ÊêÚu‡ÓN¿Å¤/,ÔÅ›ó§æ(Ò—†æW78®Š˜»ÿŒÏ¯×n$í¶ð¬×?\ï.¯ï¿<¼»u»O@îðÁ_£þH²Ã¡L^ÿù®vßoñvìœñ¹•×ÿ¸¾}÷åÓ¯×çÛÛíîÓÝõ—ݧË"„Xl¼‡ŽÜÞ"ycô®'ÿ‹©u£làÜQ¾ù‚©SnwÓ×'Ÿ>W­‹•c훓؇º|vˆtmŽpƒô%÷î#®Û¡ì‹ë—¿p Ø “ aÀ™÷à¸ï>ò©6žÂ/}¬}ö¿Ž³o®®ª5תÑù×1ÈPoÂRP©Q¢"ÒÇwàœœÙ\cE˜ªxÙÈüãÿò[ãV endstream endobj 19 0 obj 3818 endobj 17 0 obj << /Type /Page /Parent 3 0 R /Resources 20 0 R /Contents 18 0 R /MediaBox [0 0 309.0909 400] /Annots 24 0 R >> endobj 20 0 obj << /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] /ColorSpace << /Cs5 21 0 R /Cs2 8 0 R /Cs1 7 0 R >> /Font << /TT4.0 12 0 R /TT3.0 11 0 R >> /XObject << /Im1 22 0 R >> >> endobj 24 0 obj [ 25 0 R 26 0 R ] endobj 22 0 obj << /Length 23 0 R /Type /XObject /Subtype /Image /Width 45 /Height 16 /Interpolate true /ColorSpace 27 0 R /SMask 28 0 R /BitsPerComponent 8 /Filter /FlateDecode >> stream xÍT[L“göv1‰!˜æ’•ž)‡ È„ZZN£–€T…F’qˆ%[ÁpË"‚+T(R„ZKùKK¨ŒL0šp!/11 xF¸ðÄÖYJÕ]ïÏ›üß÷½ïû¼Ï÷>ïÃÞT•Æ Ñèÿ É`†° ÃõÜi°oÁ ³Ø,v;$”½kÿĹ`°˜ÐB`ö 4bS½{S‚ûÍÂn°FûàЋº_Ó¬h¾,oìÔ¨L·Í¦[f¨>)ƒ·Lë@ýïõç+Ê*ªêP_‡ûž¥0ß±´uµ•K+`ðë•ßÅ8<¸g`%p‚èà@¡Q ›qpØ„¾­@t‚LŽˆˆˆŒŒÄbâbäírëŸ60tóí¡Î^'‘#>-nnn–ÉdǹÇÏW–YîX–””Hx|^CCC‹¼%??ŸŸÂWëÕptB!.¢ƒôàÒÕwƒB£Oïß¿¿±±ñâÅ‹ùùy©TêçïñÒ/C#Ø;87MúØc±:ngg§¦¦fqqq}}] HeRˈRZ^š››ûôéÓ{÷îñäÉUç.m„ƒ» l4«Ûˆï"$…’wïÞÖõëéé!‘ü•Ý¨Ž“¢”_¨¨(¯€åìì¬P(¼zõ*ÖsssñœøÑgÔÅsÖÖÖ Exx8øp¹Ü—/_J$Y} ný1 déç:NG@~xxxeeåíÛ·wïÞœœ|ÿþ}^^Š…Ò8iXGmÂL¡eȂШÈ(Ê«W¯àõƒ ]Õ×õG»<''Ú¢¢"»ÝŽ m±X´Z­¸ð´Ê%\-=CPUUµ½½––÷ºº:Ô:55õìÙ³>´ÛìT:.ÐÈÊÍ&ðÇÇǽ¼¼ ÀÉ©)=7Õ×TmÐvww£(Ïž=£R©°T*•…Å…Ÿ£‘ÀMhmi]XX`2™€Â½ÂÂÂÆÆÆ€üæÍ›‰‰ 4³ÞÜ郎6\¾$‰ ÝÚÚ"‘Hj6™“yH/F€ÃåDOOO??^2OÓ¯ cóy|dcuuõñãÇSSS%%%¤Ò•–¦s¥çüIþ )0 èë À @_?_¬Ý ¾òó=òÍhqŽ(nZç0kŽ/3ç¤Þ¬Ïç}Lf‡²CÃBÑ–è7•¶ë‚LêùÅžåÝii)ILô™3gÐT®*¬Y,Vcc#Þ LÞ 7íç¶ÑßG#½È*J¬è¼†¹Ã«•.xxx|ÎE.—ã}ËÊÊÒëõ˜73œ´µµUWW ÷?pÜa‰lÄ%Ä%p9ÌæÁƒ_º¸mñ>>nÿ·íß#ñƒæ endstream endobj 23 0 obj 1328 endobj 28 0 obj << /Length 29 0 R /Type /XObject /Subtype /Image /Width 45 /Height 16 /ColorSpace /DeviceGray /Interpolate true /BitsPerComponent 8 /Filter /FlateDecode >> stream xóûøŸXðÑï3±JêHQK‚±£JG\Ü"ÁÇ·ÚaËo endstream endobj 29 0 obj 35 endobj 30 0 obj << /Length 31 0 R /N 3 /Alternate /DeviceRGB /Filter /FlateDecode >> stream x…”MHaÇÿ³±Ñ—ÅÐÁ$T& RÓõ+S¶eÕL b}wg§™Ý-E"„è˜uŒ.VD‡ˆNá¡C§:D™u‰ £E^"¶ÿ;“»cT¾03¿yžÿû|½ÃURŽcE4`ÊλÉÞ˜vztLÛüU¨F\)Ãs:‰Ÿ©•Ïõkõ-iYj”±Öû6|«v™P4*wd>,y<àã’/ä<5g$©4Ù!7¸CÉNò-òÖlˆÇCœžTµS“3—q";È-E#+c> ëvÚ´Éï¥=íSÔ°ßÈ79 Ú¸òý@Û`Ó‹ŠmÌÜv×Ulõ5ÀÎ`ñPÅö=éÏGÙõÊËjöÃ)ÑkúP*}¯6ß~^/•~Ü.•~ÞaÖñÔ2 nÑײ0å%Ôìfüäý‹ƒž|U °À9Žlú¯7?ûÛ‰j`¨‘Ël7¸òâ"çtæœi×ÌNäµf]?¢uðh…ÖgM Zʲ4ßåi®ð„[é&LYÎÙ_Ûx {xOö¹$¼î̥߬S]œ%šØÖ§´èê&7ïgÌž>r=¯÷·g8`候ï 8rʶâ<©‰ÔØãñ“dÆWT'“ó<çeLß~.u"A®¥=9™ë—š]ÜÛ>31Ä3’¬X3ñßüÆ-$eÞ}ÔÜu,ÿ›gm‘g…6ï64$Ñ‹áÀEzL*LZ¥_ÐjÂÃä_•å]½XážÏy¸[Æ?…Xs åšþNÿ¢/ë ú]ýó|m¡¾â™sϚƫk_Wf–ÕȸA2¾¬)ˆo°Úz-diâôä•õáê2ö|mÙ£Éâj|5Ô¥ejÄ8ãÉ®e÷E²Å7áç[Ëö¯éQû|öIM%ײºxf)ú|6\ kÿ³«`Ò²«ðä.> stream x…UßoÛT>‰oR¤? XG‡ŠÅ¯US[¹­ÆI“¥íJ¥éØ*$ä:7‰©Û鶪O{7ü@ÙH§kk?ì<Ê»øÎí¾kktüqóÝ‹mÇ6°nÆ¶ÂøØ¯±-ümR;`zŠ–¡Êðv x#=\Ó% ëoàYÐÚRÚ±£¥êùÐ#&Á?È>ÌÒ¹áЪþ¢þ©n¨_¨Ôß;j„;¦$}*}+ý(}'}/ýLŠtYº"ý$]•¾‘.9»ï½Ÿ%Ø{¯_aÝŠ]hÕkŸ5'SNÊ{äå”ü¼ü²<°¹_“§ä½ðì öÍ ý½t ³jMµ{-ñ4%ׯTÅ„«tYÛŸ“¦R6ÈÆØô#§v\œå–Šx:žŠ'H‰ï‹OÄÇâ3·ž¼ø^ø&°¦õþ“0::àm,L%È3â:qVEô t›ÐÍ]~ߢI«vÖ6ÊWÙ¯ª¯) |ʸ2]ÕG‡Í4Ïå(6w¸½Â‹£$¾ƒ"ŽèAÞû¾EvÝ mî[D‡ÿÂ;ëVh[¨}íõ¿Ú†ðN|æ3¢‹õº½âç£Hä‘S:°ßûéKâÝt·Ñx€÷UÏ'D;7ÿ®7;_"ÿÑeó?Yqx endstream endobj 33 0 obj 1047 endobj 21 0 obj [ /ICCBased 32 0 R ] endobj 3 0 obj << /Type /Pages /MediaBox [0 0 309.0909 400] /Count 2 /Kids [ 2 0 R 17 0 R ] >> endobj 34 0 obj << /Type /Catalog /Pages 3 0 R /Version /1.4 >> endobj 26 0 obj << /Subtype /Link /A 35 0 R /Rect [74.24242 44.39392 159.2433 44.94949] /Type /Annot /Border [ 0 0 0 ] >> endobj 35 0 obj << /URI 36 0 R /Type /Action /S /URI >> endobj 36 0 obj (http://creativecommons.org/licenses/by-sa/3.0/) endobj 25 0 obj << /Subtype /Link /A 37 0 R /Rect [74.24242 39.39392 159.2433 44.39392] /Type /Annot /Border [ 0 0 0 ] >> endobj 37 0 obj << /URI 36 0 R /Type /Action /S /URI >> endobj 10 0 obj << /Type /Font /Subtype /TrueType /BaseFont /USHFDS+Helvetica /FontDescriptor 38 0 R /Encoding /MacRomanEncoding /FirstChar 32 /LastChar 32 /Widths [ 278 ] >> endobj 38 0 obj << /Type /FontDescriptor /FontName /USHFDS+Helvetica /Flags 32 /FontBBox [-951 -481 1445 1122] /ItalicAngle 0 /Ascent 770 /Descent -230 /CapHeight 717 /StemV 98 /XHeight 523 /StemH 85 /AvgWidth -441 /MaxWidth 1500 /FontFile2 39 0 R >> endobj 39 0 obj << /Length 40 0 R /Length1 5056 /Filter /FlateDecode >> stream x½X{pEþõ-/U>.7WNåÄÓ“`y¯P\(qݨœDíM„"ã˜rÀµZÙ5É`{ãÊ}.ƒ¡Í½ ±Î…¦Ç”ÎÂ=JK¹¯ßc½qeâ˼iÊ´énåZ×GJY¾á`°K]õJQùËÊd4DšŠN=ÞLe¢k—2¡I.þLÔì ÛGEl_Ü3_9Óí«-œ¾Ç`·öÕ”{ ¶Ñ;­¦`OaM¾§°^ñVççC_ö¼}‹ýzûûT{±½ÀžgwÛsíãYŽ ÇOéŽT‡Ãa7Ø㕊íë¥JÐÒÛç°9dƒ= §t‚²œ‡þ䂃ã ól^Fã Ö{4ƒkPŽÙ,Íf°C} ×!¯"qM²×qÃæh>éìnÃF[¯ì©tVfÍΜQíû¡[ÈŠ ß‹ør2—¾§®1 tõ©\1]Áátç°òƒ²{B‘ªââºÅúzº:ZýÍÒüÔ¾½§Í©G›TõHG¨º˜jjnã2Ñ»´ˆOïÐ|ê‘«ÝEáVîÑ|G¨Õ¿$p¤ÕñÅ{¼=~-ì ö5U­]9b¬mɱÖV}ÏXU¼³µ|¬&«ÝEc­äá&>ÖJ>ÖJ>V“·É‹OÞßÞXuK7v§êo¯Sõ‚F½vÑò€®†ƒ>ƒ=§oÉ”!?Er”r¤2RˆÌwPßårp©ù‰üe všÿ+°¨ý¼ ƒ•³h€î¦}t˜lôôº¤X~Û+è(½Å&ÑU8{%2¨ž^b¦ùµÒïßM§h7¡t´é¤ñˆîds#l/ô&Úbþ†&Ótºƒž¢èu'5˜}ˆ.¦¥tzÑþE¦ G¤±æ“æGä Eès "¯™õæaÊ¢ª¢x·ÐIæß5ÛÈI@÷0=JûéiúŒÝÆŽšmfyÚ<ƒ­ê¤‰Ôˆ²‰egÄÃÒæÃæ?ÍA0Q@E5D»è·èÿ0ÊŽV?»‰u³]l·ànŽJ[å ƒß‚‡Bš‡RCkè.0ÐOÏÐè+ö¹à3ÄnñYóZó¿”Fu˜%ŸI„zPîDÙ‰9`66…Íe l»ŸífoEÂR! üRX/|".WˆÄ7¤[¤¸¼C~Ж6xÎg¾IÈE×ÓZڌ٢Óô}ÍDô5‘yX«b7 DÙ>¡ŸígýB`§…ƒì}ö!ûœd!]/ ÝÂ.¡W8%¼"¶‹»Å‡Ä÷ÅsÒlY÷ËÛ<ö¿ 6 n|Ŭ0Ϙ_âˆu+SE i…1Û.º†~…YB9ŒU{†ž¥¬ò!›HgéK°@,‹å°©lÊBvkeíìv夅åBH2… ÂD¡Qh:…¨ð¦sÅ"q¾¸\<Œò¼ø–x^M5ØòEèwû´ ªŸµô–~¥îv£êw¶ùT…T¿^ÝÓó‡|¥%¬ß :RKKøÁá¥4Þ±NsÛpÀÒ\žá×s4Ÿ_ÏÖ #&züá½aQÀïËu»ƒðÁµ8€1JKÚuà¤íé-ZËvÃKM!®…Wt1Ô…ï+³XŸ ùô ?v~gkþuÁSŽÄªuoh;Èåfˆ[á°êUt+l t¶uÇØ¤nâ™à u¨zŠV¥µÅ:B —â9ÞëðÕ©!Ïöf[FiI¿ss…³ï/S:‡Ë ·ssB~z{Âÿú—ÎÍÏ|Y·8Iã hµÀ©«ÍÖ ÀNç·ÈtŠ5OO¸‚ Ólž¹º€=#ztÙSÖ£Ã0Ú| p¡_<%;ÇzU‘ŠeÌÄJ!?CScçð´ig?é ylžŒsă|¡“{Egáa½‡?,=˜u›SkãëÛc­)lÍé¿À›SÃ1ëãðo¸u5Þ&Kê JialgÐ`æVƒ|®~¼£Š«n@¸„oµvƇQZG‘ÚU%j5F®æ{E©±Ú–˜Z­¶a3IK"‰ËÀ`c<ÑŒè æ&ÕH08ý”ñ~Ðé± zèêÒr•}‹¤)%x˜Šy E=êËÕ½¾ VÛw ! `çƒÈ*O"âMíÎ!ÌS¹¼ñ«½àÝ%Š.‚±ï³1 ¹õX,7Æo Û`t±Ã;ä0ˆ§pÊ m@[Ík­[sVsz ¶ôðŽÂ;û¥ž–Ä–?ÚiÃÓ/Ã3FÃðÌQ1\‘D:‚áYÀ\ÁþùÇðì W^šao7@ÎZ¯ÅpÕebxîhöŠa醫ÙÏž÷ã1\3‚áÚK3ãW:¾,Ò!Õ¤‡ð¾ÍÿeðNÒi|»‰ø¨2ñ¿Œ£ OTG†At•ÛÐÅ÷ ’P ºý=:ŽDËŠ£rJùÕ™îÌ|Ô*i§ñÍßå§¾žkH ÎãÖeFðÍò}‹V€áë+Ú†ÿ£hicMµ¯±¸&²º'ÒÝÞFN"Ê“§‰æÐÅIa®¸þ ½b± endstream endobj 40 0 obj 2706 endobj 9 0 obj << /Type /Font /Subtype /TrueType /BaseFont /DNHCPQ+Times-Bold /FontDescriptor 41 0 R /Encoding /MacRomanEncoding /FirstChar 32 /LastChar 121 /Widths [ 250 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 500 556 444 0 444 0 500 556 278 0 0 278 833 556 500 0 0 444 389 333 556 0 0 0 500 ] >> endobj 41 0 obj << /Type /FontDescriptor /FontName /DNHCPQ+Times-Bold /Flags 32 /FontBBox [-228 -407 1778 1295] /ItalicAngle 0 /Ascent 750 /Descent -250 /CapHeight 693 /StemV 165 /XHeight 474 /StemH 46 /MaxWidth 1803 /FontFile2 42 0 R >> endobj 42 0 obj << /Length 43 0 R /Length1 11360 /Filter /FlateDecode >> stream xÍz xSU¶èÞç$9ùiÒ¤ùmÒæ$9ÍO“¦i“&¥mÚžþ7üÉ?Mm¥¥ËŸPÀ*Œ2¨ Rp.ãUt”«2\B¨˜¢£Ì ˆŒ8ƒ#ê<Ÿ:¼¸ê³£×‹Œ£4ykŸT@ßÜûÍû¾ûÝw³»÷Ú?kï½ÖÚk¯½ö>]»úÖ~”ƒ6"ñ}+zW!ág¼À龡µ¶lYQ†Ø±xÕÍ+²eõ„$ŸÜ¼|ÝâlÙtBÚÛú{eËè ÀÈTd˸`ÑÀе·gËF`ûò•}í&¹VôÞ>1?zʶ[zWô„_I’¢U+׬ŠÈw `ûªÕýø¸!Ù[P—ùNÄPÊC mFRD!5„„˜W„0á§W}š· 7ú%ÖH…ò›N ðÕ„Ó¥W^RÕÈ»Wö->”ÕòtiºTUsµEèI^ ÕøR¨¢Û÷ÜNÉN†Ò§¨mÉ6V—¢†hSÔVy)ê>šµ€:EÝ 7Em JQ›(SÔ=rRÔÝ)ê.òµ€,Eý€4EmÀ¤¨;HRÔÄ)êD)j=:E­@¥¨Ûàl A‰×·±ŒáßŰ͋m•xgï,Â;Tp¥†TM-Ù=FõA9C-‚ô3!=#`üŽê‡š—©^H is‡€¿’Z õ7@þêf…°Yêæ$–ò ªŸFƒH‰ é~!exÝ òô òè rß rã ²fPT6Èñ¨p i¿ºxE¥òéJåP¥’«$(ÿ‚â€2YH „ÔÈëâÊóqå/ãÊÇâÊž¸r^\YW6ð0òî=Bz·®Ò!%¤^!Õðòå£åO=Ê…å$òœ‹F ¿œW(?QºG”ÖåˆEyÿåbU2ÉFño0´Z-·°)ü×d— À¥,ø"ÙU¥Ï’]NNv¹Ø†||uI1bñÔ…çüÚ+"å÷ñ2ŠÀ÷ð2¡ü.òb'”ÿô¾ÝßÉ‚·³àlÒÛ •g’^€×“^€×²àÕ¤× ¥ɘ À/“1€cÉX)€—“±€’±…RÉØyÏgÁá¤9”’Iÿ]ì‹8üÔ~˜~c²+j˜ì*pg²+àŽd×$¶ÁoC{×Nð°Ê{ Ó @ÂÛ*´]h_‰¶ <Ý‚— åIûR¼LÅÄ ýnžIÿ¾¤w2LsSÒ[ žŒ•èHÆf± J<Å„Áæ ˜@ál:ÍHú÷Ú Iÿy ÚýS“þ×Ùž‚˜ˆ7†œv{Òù(`—O¬J`b5üø€rBI1â…Uq#¯0©($”sÙup$½Á(ö¤· €-é-P˜]SVò†dŒð¢%Ò}«‘_è¯àu0ÿ×],û×®"ö«½çÙ¿@¼4J” Éþ«7…¼‘ýÜ{žý³7ÈŽyËÙO½rö‚ŸcßÙþ¡½ 6=û¦WÃþ>–Ǿî<Ï}ûu×£ì1ïBöePƒ|J„ù\ö€·‚ýy,‡Ý[Î>#uZöè³'öûcè÷€w9;ìÌÖß͛ٻ@InƒqVû ØUþÞs„]é³+M²Ëœ@Üv©ó!vÀ™’¹}ÛSæì@Kg¬„#e9ËH¼,My‰Z& Ûj`Àa[¬ÖJ`Ãn抰o €)»épÛ€áްM1[ 3íO²QBl’­Š Ó‡üОdËö¡…Ù¿‡ecrvî!f>SÍ„™ ¦”q1v¦)`tÒ<©Zª’æHåR©T"I))’êR™s|;¦“¨ ˆH*¢H ¤ˆÂR Mn0QÃHJÝñ^ˆ› Þ q#Ä âí‡ gÎ&½G©aêŽaèQêjýDåzêމܽÔí¹Û©!!—Hæxh2JáÌæ~Àdª7ÕçÕiªZ›ÿFÒ#Tö4û®ýLÿ^‡¿…{]7\˜øÉ”Ù‰g ㉠Éd ãSųm]£T„ªhi¥ÂÄ;Fñj*Ò2‹ÔãÕÍq@›* ¡½TÐP€F;Ð^‚†öÒm+A;´}oK󡽊x7Ú. lïPögGòÂ0O IäÈ+ y%r‚J!àáeˆ‡ÁxH+?/#XxY~®0˜A˜Ïé”$ñŽC>' rú„f÷µf¿]h^–m^–_kd»Û³ívh¿&ºÿ¹þÆÿW"o;·õÉ–~®¥‡k釨“Ø64`Jl\h³ÚzŽ4Ø´«gaß½ý‰s\sb+×l;´Mè÷½æ'Ió6®ùz²eNÇ¡'ùþæä6~[ ×Û?<ý‰©~g®­WçšúÄߘë 2ØT2×t¡ß÷æz4O's=HæzÌ5Ÿ.ÌÕ²dvãšë~·®]›-ým­½.@Yˆ&ú 2ƒËùÄILwfÆÅ+=ýZæ]ºv¶?¡[ZŠ6¡rtüìÓHŒžBIÔˆ[ þ8Òb;´Ü„à(jOV £ö¡Ïñ|´@Ÿ¡m”­€3°ùQÆ,@sÑIdGK2iCChmGOCÛL´=s&sf+‡ÙV¢{Ñl…ü4ŠÞÇË3'á\hD· ýè\—yðL0S“ÈTÔ f4Mƒ‘;Á_^#>~†ÞÀë2÷fN‡ ÌW†Â@×>t8ø‡ð:º‘Þ-~ÞÂ*ܘ™9œ9óxPŒG÷C؉v£'Ñóh ¥qÏÄ2Ë2«3Ï#'Ì5€îB÷¡]èѯÑ_±û© µ’:´ 2ö< æ ç8zËqž‡oÁëðþ §dVe#ìDA˜q?úú:…Þ@¦àF¼Ÿ¤ÐZú!úQñøŸ3\æ# ¯ ÍBk@B[ÑAÀÿz}ˆþ‚¾LØŒY\†+pOÁöáƒMm¦öQ¨1ZJÿ#}B”“þ0óAæ2HÅ…| ã0ŒØ w‹©À3‘àj»@V¿@¿„µ:{ î4ï¡ èÏX„µØ3Y`;.Ÿ Â૯ÆO@ø#þ˜¦(Š¡côƒ"$Ú,®¯Ë82™J¿h¼¤Fµ¨NX¹.æZ3ß÷- ×íè1XÅt(ø ý+ú]Bß +˜ÆbÌj‡=°*e8¡ó8”LÁSaæâù@Q'^€áøAü#ü<„—ð¯ðIü'ü1þ#P)¦°j1j&5›º“Ú!I½I»é/DV‘OċޛŕâNñÃâýóÜø§é鑌(35³=óhæÍÌ'H÷´š»`!ð°xX wÒè!» <²ü'Ðä# GÇ`OBx Âiô?Aª„Õ;჎_rq65 +Z…ëp3p7B^ º± ߆ï„þ~ $ÿ$~4kx¼>üŸƒp\_Âßß:*aªÀóÔ©6S? 9@€ðZOé¹ôô:z7ý4ý ýý ¬ãbѰèQÑK¢7ÄHÌŠÛÅ}âuâ-⟊ŠO‹ß,)’`v01ễµ©‚pýO ¶½ˆ¨!j,‚î±KÑA¼}MI«Û°ÖzH/»¾o€Û[õc\kô3ñzèÄÃ`+*aǾ{+†„ójÅÇ©yè#T–L›C¦Ì'âµâµˆOA…MÐS;açÆ~’n[mé_dÞ¦­@âÝ`¼B@¼Ûå,âvk-,°˜óMFƒ^§ÍÓ¨sUÊ…\&e$b žsI ×ÚcK¸z"×Þî'e®*z¯«èIØ ªõ»8 é× MßÁäsñ÷0ù,&«mQõ—ØZ8[âõfΖÂ3; ÿ@3·%Æ„ü4!¿SÈ+!o·C[‹i Ù–À=¶–DëÐÀpKO³¿òÀ¾Ü_Gyh£-½‹3fv´4[ìö¸¿$›ú¸… Ä5&r}ÝI?8Éœ³:`nÉ’жå,âmKñhaÉõvu$èÞx‚ê!sh| #ל0®¿`ºVü6×rÿu ÊÙÚÛ?Üšà{¶ÐI±‡”zï‡ÒâÇ$¨ÍñŽÞ Ä"Ú³\dÏzgÏR[BÆ5rÃK{@æhVGÒÌ›…C5ft$óù|¡à/5m¨±ƒPFý þkì¦ Yø/÷dëŒ@Ó†ãçN™uU.˜ÌÍŀ̄­O˜„Z'‘¤î›âƒ_—K²¦žau5¬GBìTs¶á/,7öéwkz'j$Nõ—ˆ4’弪 Ü;‘‡w›’))$›Ñqãíqâa§Psá(¼Ñ nò§‡¨Ã’fè …â¨ðÚ!ç-±µÕ­dÝlÃ¶áØ¢a[«m\ä 4ôÇÀÎìŽ%Îé°'ø¸åj¶?¯†q|dèèÃqaéÄ…ªÀ8 •”L!ÞÎŒŽ™‰Í–ß‘€Š›Ñ‘8Úð8A)À;—˜&h.šý^hdG/~# &cÎîàì‰cÃÖa²'²åF߯à'*Rˆ UIá3 /În!œ³Yñf˜ª ÔëÛå…×±ÿXÂÁ«tCÏP$\ñŸ$áðß#áÈß%áÊ«”~G“€æJ"áªÿ: WGÂ5ÿ±„£Wé"kÚ¨ áºÿ$ ×ÿ=æÿ. 7\¥ô;nšˆ„›þë$Ü|„Ḡ9É< TˆÖ Ž~y!–B9e;U•’g‘”¡ÞíNºUP×êì0Ä·ïÑ9ð¸ü”màIÂÓÂÿçž& wòèÍÀ;:ùÉÀcSÀwòS"Ê…—õìO#€ ¸S|×â+ÔZz¹H.Z.—,”ü–i…÷•Õ²Ù‹€Güv$QÁ]Šx³ |X‚[ bXÉÅ"–¦)³L°åKáE¨ô°ýæ&Ÿoú¥è´ñètõåè4õxÕGÇ£$–—…4v¢SüñÉož|½û$ýîŒ^‘ùþˆ>4ó¨½Ê¯Õ/©ß£¦î™z±Ó» ꊕnÎ]är××OÁ[ƒ?-ÛŸ-{¶îÙúQüœçhÙѺ£õÇ=¯•ýÞcj`áqU­ˆÍS‰ì¹*¬š¬Räå9Œ"V®U448¼êr\^Þä­ÊuÐ^µoôîôRÞÕË«š¤<_àXÉÿŽÿ#Oó)jᡦÆÀéËÝgßW«/uŽŸ?£É« šH ¼Õž6ÕAa(Ðm2¿øë®//ï®»¨2R©‘0½Î*ÁÎp…‹s‹­X¯“pW¸" ‚ÿ¥Œ`¤ÒÈœÃír ÐÆøß|&û¬º%µ®ôrcš¶°²M*ÍQi¦…jfðÄ?ߺ֨ÊÑêØh¬4t£×¤˜»¬¡~Îðè­Ö<öé|±Á¦–³OÌzøÆùÅlŽZ¦Ò«ë[‡†›š¤ÕV¦óµä…­5s9òAZkÎe>yaÍ•ˆC›øö¹Ò¹º­ú#ÆWt¯è_5^Ð}©“ÙuE&_ábébÝbýmº]:©šÃ,gåj¸‚B%›[ £Y-‡ds´ í´æ+$üðôST/sª”^+Ïb6EõrN_êÍP_îQ‚ëñUaa•w——ánÔ]d$²™^>©‘åéuÄçf8M…ËƇóŠæ,™?mUã eÅSæx3ýo¯ÎÚPùxaiýŽ¢Ö^{ü£^ýøEÑããc“/ýʼntzŒ¯X+zŸ÷Ë‚DϽ™ÿE/ýsÂ}q?×¥÷ÙŠ‹èyšN[§}7¯h©m©ýEýQÛ Ý)Û×\Ž®`žýFn±}ŸNœcÇ.Æl1H•êƒb,ÔjÐ4CŒU¸\”C,–S ¼Ùþ™[@G‚¥r  À4VŸ"ÈŒCAƒ‚ÞÉuœiœ¥¶£-ýæP²¬HÅŒ_fìÑ]í¼»:°àΙKv¥¿‚‹UÅô5¢¨_añÒ›ÚÃ?è|Æoá ©uÿ‹—?·sßcx ð+Bô|úMà7YÐxù+¿/×¢*È)Tø$•hk±Z|†Jõ´ÍÊVÏ<ÏüÉýž!Ͻ¾{Kî¯Ü:éÇž}¾ŸU<[ù중ŠÑʯ˜/*òB¶2Sn¬µŠZMõut‹ËMW?fÄõF0â\#6޵:Zhgu™¬z†_æô3¹Î¹s™¹s#n–òJlÚ ¸©­S#ó%Çzàú?¿á@çðZîšÓsl¯7kþ¼Àñ·»Ç.e7MW›Îv›¦e‘éýnMž±J3!Üq3zìÎLçǺáGvi‡˜WuG ÖüzÖd¡ë7%ì<;±b®HeØå&6«2\ŠÓe0Úõ1fÄn¹¸¬­3ZqHX6¡:`Ü©³ÎV];yfä¶-WOÞvÃ@:aSåÄ:£–²]íϽÜ~»«öy|Ï÷ì`µZ«Ýá°æ.´lœöÐ{k;~ŽÏPLUç–»‡7l¹ëJ{žãÆpØœgwZ»U*£É×>o½Iå}dåýG rW¸jµ¹(±¥ÀÍ:Dðoàôb±Ò°:'91[°5Ùí{üøUkEܘk;CÿïX+&+q æÊ׈7•ïêÚôà5s7{E‰Å‚=]òœÜ{ßþ´¦ÅÃ\3XÓÜYÉÄhäßîä(ü™!¾­;i'S,=küDtArAþWÑeÉe9î¬ajzH7dÌ—/U-QÓ¨C4_BëÁµÉuJfÆl+æåá<¾‹÷)ˆçã|¾/œÂ²çì¥W/9l>Ì †Ÿm×:唈uj‘³TQÍTW›Õ9 í äNÃç[͇ ¬övK]Û§ fîF¾¾>Úå'Y«°Õ^å@ŽÁ¥¿{¯:¡>¦>£©£5Óà•u_:o®S™MjRº4ÅKc&31Hƒ×t©6jÝA0{íцÀ"÷·+€³n‚ä–Òp‚û«×á*IücAÄœuŠ9\Qe}rÞ “=†òÝ·W„÷=Üð£¼|=ã¯(ÜÔÑÜd-œ¹j lÆSOÏ®å´2F“·á8Ž<´®­ºÒ­7M®ii¹é¶>½6ý‡ SKŠŠœîH00ãÖÕ'4ú†²Øè‹Dÿì™ Ô£b|ãXijЬoÓk<¶+Ð*©LÂØ5±|…×ÙõmŠì’ž±K•ÞBMVbÜÙÀó«æÓ`9̵¯›Ìç‡ÞƒâqT? þ4©=-k(@¢ ƒ‰†Ò„ôœ8¿þ¾ÖØ-žp {jů­Ô•z"–ò¢`ÇÛ#ôܪ|GyÅâ[Óû:Çwû ýUAÓœp·¥b+µ{ŸûîЫ"ØQ£|«#OUNUQQeTEÉi~>“Ÿ_S8¹0Î,aö0Ï0G™#†W o.rÕ*uåàäœUu”³qÖ¢§«QsZ«.…U¼ËÈËLF›I-—‰‹TH€ b¬ À¨p2N§š59ä2o.üSaïˆ{áÿ½À„µ&. àžÿÖ Nƒã ¼A¢'ïýƬþrì þ<£Ú³&â‘M&&+Є3HfÂ/ B­ÿ,×<­<`)MûËZ_ê[+›scß~o”ÓÇcu…!Vã¡ZøgùrI OãØRo.Ýð8%&N |P|Àt'ýÈ,ïH/òk˜€±d@¹NµÏ°ÏxÄpÄxÁpÁø¥áKcŽX¬ Ünƒ­ÐÊ*ÙB« Ù°­-¯¤Äo-,ôæ©TJ‰R¥*´•@»_ª£Œ®bZguë%”lN™ª‚!ÍWKè²¹ÜR`óR¨¬–Éy\}\Y5 G#igÛ•3z¢¯FôØ:á—¹mËæ¾—æA™¾g·¢vø¿€)ðÕñ4þÃ`Ü]ç¡ù¨u }0|·ÅBN‚àå¯yz{ÓŒ™¾9KVô¯ñ7®\¾ý}dâ endstream endobj 43 0 obj 7880 endobj 11 0 obj << /Type /Font /Subtype /TrueType /BaseFont /SKLDXW+Times-Roman /FontDescriptor 44 0 R /Encoding /MacRomanEncoding /FirstChar 32 /LastChar 222 /Widths [ 250 0 0 0 0 0 0 180 333 333 0 0 250 333 250 278 500 500 500 500 500 500 500 500 0 0 278 278 0 0 0 0 921 722 0 667 722 611 556 722 0 333 0 0 611 0 722 722 556 0 667 556 611 722 0 944 0 722 0 0 0 0 0 0 0 444 500 444 500 444 333 500 500 278 278 500 278 778 500 500 500 500 333 389 278 500 500 722 500 500 444 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 350 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 556 ] >> endobj 44 0 obj << /Type /FontDescriptor /FontName /SKLDXW+Times-Roman /Flags 32 /FontBBox [-203 -428 1700 1272] /ItalicAngle 0 /Ascent 750 /Descent -250 /CapHeight 676 /StemV 102 /XHeight 461 /StemH 44 /MaxWidth 1721 /FontFile2 45 0 R >> endobj 45 0 obj << /Length 46 0 R /Length1 23628 /Filter /FlateDecode >> stream x½¼ |Õù0|Î,wæîû¾ÎÝoîšÜ$77ëd%ÂŽ$HXdQdƒ¨(XD­TënZWÔVƒ+UpE«­Z‹KmEkÕüÛ‹´ ™¼Ï™ûöû¾ÿïû½¿77sΙ3Û™ç<ûóœY½ê²…HƒÖ#‰ó—Í[ä?Ó+á;æ÷¯”öyBŒï‹–•ö5õ±›]¼öÂÒ¾å8BÛ/œ· ´NC]½:Jû¸êðâe«//íÃý™‹—Ï=n™ ý×-›wùèóч°¸dÞ²…¥ógÅ¡¯X~éêÒþù×AýÀŠU GÏÇ=)^„¾‘löšÑJ¤@w %¢~uq_À¹ Âð“ÿ”»cï}ý7ØÈËû¿h8_®_¹åã*iîéÛ´÷¨RС©H‚.íi®4W{ÏÙ#òuP4¢òä Š%E½ò×Ó°~nz+·MÃb³Ÿ‚ÓsrKƒ\"|JTcÀ[9¼UÿÖ<‘"cü+ECyˆ"£À#hZÏS<Ì×.hí‚…¶Qd#­k(©yt ´oözŠ…šGZ=Ë¡g9ô,‡ͽIð„9°G£‰°Gž:QÞËÁ^ìåä½,<- {YyÏOñ{0/>…?ÃÝxÊ~½ÿ…•:ÿ3¸ w£ —ïÙ8Ñÿ~ß"—׊º€öã€öX@{K@{M@û¾M‚ÃË%u“´ïOÒ¶NÒ6MÒÖNÒ>ëPÓ¢%®}6®ŒkŽk¯ŠkûãÚt®ÞÆÁá‡åò§b`œöŸã´¯ŒÓÞ5N{ý8íã´ŽÓ ã´x´aÖíÑâ«èoÕoÕ#%4÷mÕÞºú¾Ù[žõ7âìÏû“©jÿ ¾aÏ´T?Ú3í1³o@ íG €_…Úäz-ÎÉõå8'_³'›€Ë.ÝÓx?T+÷4p\„2òÁ¥{òÇ¡·fÏ´Ùþf%ÎÞ³µñäžé=·Áá²=©7üÍFCî0ÊˇC(/ß%8Z+öL‹Âéì>èHbã=~ió …øOe§øOfèù&3ÈCõÇÄ õØÿGY¨D»ÿƒìlÿïÇùÃ^œvÜÿ|öbÿS)ù‚GÛž!OAà¾GTûÌÞæ {ƒÿçòáíyù~wL“«ÛÐyÀÜæÒÌ >oUžíŸœ]åŸXzÒØ6ùŽÙ§ä×ú‡¨möú›³^Cãþº6x“=þ"¹|¿²ôðŠŒüzåãýIx=怿lZ¹?ÄbÚ?}7‡›Î¸*.ÇE¹ç㼜…7ñ^ÇkxÏó žáoyËàÈ'bx²( ¤R0¤d䶨 ‘Q˜§µñÈõøf[“£ÉÔh,v´ý‡b®Ü9·-ùŸþ¼wtMíØéí¨ oo×@ÕÔÀ¬žƒøÏø³ö¶ƒøsRõ¾€ÿÜ>EîÚz{]ã'õ âÏÛ— Â%óDrðsèçÁ ]çÉ÷A èj;ˆ¦‘ îCU£¹ lµ|Ú ¥Ó²p8­Tä´ã(+Ÿ–¥ŽË§½ANÛ½9ÑÞ¶;œÂfÐfù”Íl†œ/<—¶íÎBg©pNwN5 ßÈ+ß(Ÿ‡S¡èíÙ]‘‡vç+äÃÙï§J‡§”O‘ŸÿýáLéðöÒáípø?øÿOß–ÿÙU{Ï¿wÃ}í CísCí a›;pcÿbÇÀú Ýî%ttîó“zÞÂ{C Û6„ڻϗ¯û·Ã÷‘Ãç‡Úv£ûÚ§õì¾O\ضç|ñüöLèÞ7¯lÿÁ³n8û¬•7ÿ‡gÝLn¶’FUÈ|üSÜûûÐ[èh<š‰m=†Ç -h*¢e¸…ñoP5jG÷£çàŠµh9œÛ~‚¸ê©‘ ¯=†ÑIÃ^Ô€zà.7¡»G£íè ôÍÈŽ‘/Q]g¼;ò'”Eëá(…\(÷\ŠVà4µzdj„çÝ…žBcÛH#²¢JTÚÐ"´-C— ëàØ³è]ô; úJ£<§Í@7¢ÛÐh½„ýøJü3F9²xd):F°®»Þæ-ôgôߨˆŸÇ/xFöŒÀ³C¨µÈÇïC?C;ÐÏÉ› —áw á©x¢+G´##§à|=@MD]h\± ]or:‚^‡ßà©q\§ãx=Þ‚_¦Zh3ñF®…QòïøM„ñ_ #ÝŠn>‚ž€ß‹è·y%QÍÔzêm¤Ef2Û?rÍÈ®‘çF~ 3Â"À¿ ~ãÑjt9ÚŒn€÷¹@/ ÷a®þ††1‡ Øc؇?Â_Qˆ2R ¸Ûkôrz ½‹AÌ}ÌGl#»IzH:>²häö‘×GþoO¾™/À¯žÑ„&£©¨-X_$ãÇÝhÚìÞEÇÐGhIØïYÀ-x&¾ÿÆGñ?)Š2P~xf‚ÚDmƒß!ê(õ.í¢½tœ.§gÓwÐÛèG˜ÛØìJö§ìnÅWÜfi¾´@ê—®’žé¹säñ‘C0FCæ´…·Œ¦Á ^ˆ®a½…àŒg/Ú¿0ª§Ñ3è(ŒíèàÜi€ƒR†ƒ ‘ÃE\aœ­¸ µg"žó3÷àyx)^‡¯Æ×áûà÷3¼Þcüâ§ñëø-ü;øÇ_ÃïŸKq”ƒ QQJ¤ºà7~ó¨ùÔbj µŒº~Q»¨}Ô èFºƒž¿úý.ý;úô·Œ‹YÍ\ÉüŠ9ÊcŽ3gN²6ÇNgÏS8EE¿âÅ^î"î îÚ0þ%¼Ó¹óÑZêê;t55è 4~ê5ªfbÞ‹H=ˆîú¨]üCÀL•ÃO¿k†eðCb, ‡‚BÀïózÜ.§Ãn³ZÌ&£A¯ÓjÔ*%Ï)X†5)ÕꘈÎ`¢¡ÎÎ4Ù̓ŽyçtÌ@WÇÏëæÁ¡œ)™þÛ™béLñì™Ø¨GõéT =x£-Ä3'÷@ûæ¶Po``HnwËí­r[ mA€ íŽÅm<7Ð>ÐÑ¿xKûܶt zªt  ¡&7@­óÖ8@­äŒöW¨­}À‚6£#íó LšÜÓÞæ„Þtj·Î]0€B-úäèåä:`Û‘)=ðìtj Höt£fAhÁƒ"º`.iÍ›Õ3@Ïë æ’g“öPÛ€ýŠÏßïžiµßtÎÁ*Ò1oá–Žqît²;—ìÍ» öºˆ” ®ïíÀ×ÃàÈ ä±—Þ¢$Ø"s—”¡–Ðâ-KçÌÑ”ž=.Ñ%K4©gStÊ;éÔAÇÕuå`º9ÝLê:Áqu©þóJý¿9DjÇÕ‡?ºkÊY¸`òìÐXæ@`¾üŒµ† kЖù5>øëÅð–K”­s·ja>؈!Øò ˜EsCC_ÿ°gÞh"bø‘ƒd:ÏbÄi ;ÀFKu "夞Ýÿ¸—è{ƒ¨Í{¤ =gvzÅ :,iƒ«a'‘‚Ž2Ze©@ŒºƒÌ[`K`ËØ[Å0áLD®áÀÂ-½Yx©=K œÖ# ˆ½î³Í…½½µpŸ$¹\§oé…;,½ÔrWvNJ¥ºˆhŸÔ3¹g`}›{@l늚Ô3p°«·΂w)Ôë–8FÇœ1§Ëàx¶tÐA×Ã-z·l!÷œÚmÙâÞBh¢´?ˆÑ¿wˆ£ƒˆœBPe¯Ÿ×Bܤ#$„Vo<*èufzÁþ‡pÅÙqÕym… áÊÿC®úŸ@¸úáÂÙ‘þÂ50æpñÿ„kÏ0û2(àMx%ZDíD³a«†ýßA= ê©"bÀÎ1Áö)l °õÂf‡­¶Øâp΃°íäf£A¸Ÿ=åÉ}™Oá¼K‘Úåp?yÚd¿ú8Ÿçy ÏÃÝŒ”P§é›QÜ—ƒ: u9Ôq¸>íjØLð,xæÈh3ÐŽ(Špo$o•P+a#ÏSÒ^´Ž;aŸŒ?÷.ƒ:›îYI½!£‰¼>±ÛàOƒx3ÔôühÜ \,8p8Д ÏÔp…ô =x‡ÈŸ™äšfdÒŠl :Ú.Òܰy@%š¯ž$  ´B°…a;÷/úY 4HÌ$J\Í€všYZúj%èÇÕ£R-ø¦êA“k<÷òÿcm¡ÿ»âèãªá W€%­ÀãA7ú)~´ûéýãc޲Өì׊qœ‡û“Ò¦|N5^õz¼z¦FsX{¡.¬7è¯5ðÆ6ã'¦WÌãÌï[î·6Z÷Øî°×Úp¤_:«]A×Qw›û„ço™÷¤¯Ç÷wÿµ …q—ÁÁ¡I0ïLù`¯Ð0ë­û(<–U€ÛBô †K#ËŒ¥iÊ¥Tpc1ròʯ„Ž)Ždr‰úîáú †“õ݆ázÔT?\o8Ey.oŒ1ضðÔwl×wûéNGà1ZD»Ð0»0ªVôpGu;%*Vp+ŽR³~ª“÷«úŸ,v$'Nt?qÜh*6d]_íp>ïF벎¡òœ T)BWUVç?ñb¦<\I³î,»8ŸâtA©ßéÌ9ýÕò3gK·QËá™FÔ.z4Z†Öò3Ãh´´Qk6Ûí.æ—|§Ñi2bõ^áG¥—ë>1¡}aÛ稩ÉT,bTèUëðxsuÁ®àFƒÝdç¢1Ê8û­õ¿4ïh_›™ü‰ëÊ[†èÙ˜Ûq°~ío¥ÒéG¥÷oêÇ^pyÉ㩆ñŒñXÐ81 ¤°ÞÀ)àŸVë9½Â`T˜m0&K§ú—z§Õ&©û<àÝ'†8&{ä!¡>Dq0$.V]¨6bT¬`³›ŒÔ˜ ]¯›Qg¾gÌÕµ“ßqÝ¿ùm<_:Ùõ²N¯pÙïãùØãÛ„ž=ÒIÃüüNúŸÍÞ c‹¾Â`šâiŠVh)š7ÜÁ©­0²m ¬HškëaáòÑ‘ _5´Ê1:¸î¡b>“GWžÃ} Œ«¦*â‚Q2c6+>yë4óܱ&UkYGmKÓ‚I¿ŒÆ«¯.Óñ\¡2>~~Œeþ15†Ò^Dj ±‹^Çâ]0Kòs>GÙnÀ³`&áJJJ·^†ñ‡#_àçÁ>T£¨hfËÔj-Œœ/£œí‹Âå?.ó 4ɘ3³(BØ×ҚͶ4ç¤jÉf[å{2#S€a0žFÑhz¢‰¢0Eƒ£Ñ”zttOá2$àGvÿ áœti4ÕcÀžMÝ™ä:ÀH‡ðë ¤º ÙÅßõý)d¢w³s.|èV1ø8þJó™…>‚ÞCŸ!ºU±E-=žWl÷±ºí6-µÙ4Hñ{ªÍ®AŠÛðgž2œBMCMð.­kÅäÕDK”x¢†ÕÚUUÀ¬©*Ìy¡Åê¡¥vêª6C¡t+ª0m„‚ø>ä‚4ào^Ù‡úÂ&ceŒ i…Õb·åMĘá(!‹ …ê<µî¡qçÎ&!(|zÍÂÆË¤OŽ\³ùü+G"`–ÿã'X'}ùÓ¿ºYbëþûÅá—¤ý{ŸÇ˜zj˜ð„O~v6ȑ墳߲ÑBE-ÕJ3|ÿIþöî“åðG_²Ç|üÓ¢Q«¡)†·²<§qÀ¼Rô Îí×h´N»ã|9ÀÿA܇Fy0§Q¼¬o”ìþfè4þ&™,Ï!x1›Õh±Ù­B §ð3¨àª"yê­"•Ë<ð£¯Ú–¯¨®ªŒÉÓ>Ê Î…ÄF %®õÞþ¦›6ú>Ò: ÔöÁŸô]2-Så»åî‡ÛcSæÖ.“Þ•¾¾r¾ùåªg—_4ùL¹jï¸r٪ɩYÜ]¹dÞäL1QX²ã9éã±e®š¢_ܧ@˺^ô_NcV«`”­E_jÒji¬EšQ! \øi¼d´ß¹_E³*jûD%z@™c>a(fW?PˆŠí Zñ4¥M Ñëdôé;ÑW?|¤éoê%‘P*nÊ$àJÚz%ÌycÞ2†ŒB5]²â¯Zæ¼ýö¶áCÌÖáqôu§¯º^z O¿^žãæ‘/ékØk@w{SŒmtã*Þb…8AÂÎZ‚«Z£ÔÛ]½þR“ÛírC‹aÁLÄ¢/¢|Àí¦\N×¢U0êdDË^<°Ý:`¥¬û3à¢çvgң×çµÞuØ5\CEàkÃ,d6é2IV~ƒ"ycx­Qži˜gÐCÔ¦ù€à|‚WYå=,p»0 AY…=n&Ds²Y_Ù† x9 @Ž(àFÁ,S§Ã!`…݇1BÀ‰<ûÍÁŠK—¾¾û:›š§hê~"ò&0a«´núã×Më'ùï ê$ÓOnxý§˜^ÕD+y5‹?¶ùt•ì.³lʘÝó?’Þ7û'ùÒ%ÜèØ>Ç^8A[ÅÐùz€®ReÜ–‰ËÝØÝá¦D• dƒÛ)md3²c;…}1ƒ3K¤B, 41¼î°ÈBž«á —ÃTìÏ:ú†Œ2÷(Êü"[]ˆqF]ÖHh ah9lî*`‚U ·Cœ£$6lØ@ôP ‘jÁ®ÃÂ;¢„œ8&B\ôs_=3 ý;¾Ã5ìºýcÆ®w4¦'MÞöþ“eÜ›÷ÝxÇš‹±A:†Çaž7üŽ`Ÿ8¦óãeQSàã5‹ŸU}õ/¤W^' ð“8ÈH¢§jÐ*Ñs¥jÿ Ž^­æ·p×)^Ék’W‚S ¤AZ´á 6Z‰uNg@ØÓ ‚Y:¤ÂÐi f‚â4Ù;µz ȘDø+°V}¸[Af 2ÐwJ®Ã·KãçMo5ûl—ðÝ‹ÌËâ…†í]-0V =8òW|ýèvT%z¨2ž3–ÙÕN¢Ù•éÔe,«s:œ/ §—ŸSC†ïÕ"Ä‘0oTY¢Î4ˆrr]{*×(fRí÷7‹ÙlGKÖ6µ¥2ÍMÙÓ-Ùtks&Õ!a'èr¯ÂÌ`…Ís/Õæl%mÎ_æä8µ§Ìæ× çêuá°p1hà âw¯×uˆj2üP»CÿQ»ûÁ€_ÝzÞ¹šÞÍD£jÉMØûÆGím«•l¿Á‘O·ƒ®¥ïûsâeÅP›ò§¹å;*vä_¾šU:t¶BÄ)UU…Ž1m[T ÷¨Ô¾2Šçƒ©]1<1†›b8V¤‚.½€…1B¬®U¬ šQk0Ð¥îLÕ°eIÚWîó•«ËSê1áT¸¦©&H註©Rß=>{ø½!ÃÇ+AÖ‹Ùþ7Ù£ÐjÈ:ˆ4Çq45üÅ=E «>Çᡯ×eûú "§ÔE0˜1å7HY©’Â$ˆ\ ŠEcÀQÈ<# {!O”xYÅ"—„CÙʰ br›j­Yó“ÚÊ…—~ò§´Ô?û’ôó‹òAlß8~彘»o̽ð@!è*Ó9*æ½)Ýý;éï}ñ ¶ÍYùÄUÑ;¤“÷á}ãñ†ÞÊzéè Ãÿõܯ°?úðÎíß¾" ´¤*.¼gãØ=¶jáÎ%3oXœeX}è«ï¾"ýAúǃ÷yÊfçNü¢‰}Ï>È·Ù׋;i=mpÒNƤ7Ü~w I'™„¢H™¢¢Þ_˜®šn¿‰¾‰ÙÌoTþHû#Ýô?2Üä¿)p}s›ö6ÝmúÛ ÷øï „Û´m:ŠƒÐ4²Ûl˜r8`s:1ã¦VÜz­[W ð}Àæ¤4t9æ•^¡H™àD¥J•0Á• 'mW»Àê°Ó¦R0ކD”Ý1ˆ§‹¥((y: ×Ñ|¨Y S‡€Ôí„ס)% fO¸œÃÃÂ!êGÔ»ˆ¡ Ò&_V¾ìÄ$<#} vÈb(Ifþe¤ÈB0+Kœ¬˜´Hc“]w¸~“¡ž3ÔC¥{4l¬ÆtÐX><ªVF³XИicÅô­C_Jó'Nœ‹‹c)ßÐ9üÏ™•Óôá/&ùË\8Fé¨Êá£Ã(/ü=tjÍê‚*áíiýø²#¯öº*-E& f+?ò1ÄBæƒG&Œ]¿÷|nÿÔA÷:–8¨8o³³nÅÕ"ï8n7‹AØ¡vDmœ JM&¢M·2ösó¶ÙŸ·ÿÚNƒÔQìê§ù)vw4"›"RßqPÀˆ9R¢Fæ¤ÈÕð…Ëq àjr¸€™ÖJÔUOPkôF„¨Ñ£/ m ƒÏT@º€¦–ˆlŒ‰S¢¤êBÞ’… H ™08E(0JYAzá—:o¥*iÎ&Z®~÷wÒ_±ÿÃm»gEÛ>þªtà…½Ï¾Œ›8v~K (UÞ0í~éqé=0~ŽOΈž×|Éo_Äaœ|ý]€èëì:7:€ÓÝbÅËnü?Ⱥö»¿åÙjÞ$èÝáxØ,¸íñÉL©2 ÅRT& óŠiÏ{°³?ªÕ%Ì`­Ñ%Ð/‰DÄq½`c À!¶€!î ÒJŸ×ï x/£`"®¥ƒŠV:¡`½TqnÕY$AM!@ {‘mþ(H'«‘-Y2±*à1ŒÑ"{B`•wÿíÞÿ:üˆôU{¹tÕŠ¶–UTÛ…g­»zÒy?ûløå‹snÇݶ;ü©¿®ÕWÓ·¬ù謥wK_Ï©÷׎ê«ÌËâ³{M¼ha¬?v}ŒÖ½¢vëUXu•Î{—Ë­wbgÚK ȇÁÍÇC–»ìnäÀŽ´ÅkÑÑNXéˆÄTt8dÌ:^ÝÌÄõÞbNy}¾x‚DL$h§cµ²KµE'E©è ¥ÚŸ4ù M€™,<#À<ÙwâĉzÙšHEú@F¦ j Ð!CMh¾éÃC_'“¥zt—(½…³P3‡2 âH…/o”wÁHm¦§l_ÙÚ²Š¹J×â}Ò—i+®ûQ§-—³w^+é>ôÖK‹}§ž fEd.kå£Ò±Í“¼q©0a]Ó-± ¶ówIáýŸ™;aô¨8ó?‚q"Xöï`ô îPewŸ"áçE÷çŽó¡+ܾ‡ƒNÁí‡ÎeTœX^bTÙHÈI›‹bšL. Ì*¦äæ…œŽD8—K†·…~¢²¡‰¡çCthböVè§% ߪ(—ùÖɾ>‚DÀç `+îE°04¸ÀI¸Wƒkˆ°±QªõÄ3Zc"’Žã„yeó*#Ì+õCæE”€g]ÕßÒJľÑœec!zÙçÆTD›6d›Z×¾pDz—}Yn]I©Æ;ˤm¿ÞyóÓý/ã±0³`@š|ûØõ`‚>*}&½ Ó;BA<¦¿–‹FYK`´,|ù®_ávì;úG¶ÀÛ¨kGŒk·2$$kN˸–é· Jp—2f‹’§Ì&Þb‰J0p5†>É‘Ö,!CÀÃçÀhuÏQyîœ÷9Vò´`aݸqë¨Ù¤þ9ÎF”Å5ô-+›Ѩ¢yåé•kŠÊˆL%ÚxÚ.´RlXè¼Ì¹Ñy»óAç~§âûáºÎ†Ón£u´ÍÂhyÇ.KÆ#vñÈpLrЂþyÈ„wxÜgy(´à¾n<‚° @z2ðs‚utè>œÈ,@æTëÊn{ÌžïÀÆC3+œÚó=ÁGžŽc,MÍ<(ýŒÐ9Øù#_°À»€¦„î[~ïÀ=ÎÅÎÔ_ê¾´~æQ¨‰Ââ‹@íà ÌÀ&åCn?ïP msØU.µ1®Q§ìvS\ž MÈé»RŒ2ˆË\1„7ûúëúá¯1~-;濆©‘!ÌNÓi2?Ãõdº™ƒ.Ëؤ%„ˆy¾bЙ þ¾(ÔòÛ‡°QVB€û]ÓéI75á9´µBX‰ÿxÙ„ÐéþòÀrÉO½ÑöþœÞ$T9©èé(õÄ£yAjfî8õ3ÿôŸÉ ybiÔt}¥¬Û»!Nô Xù’é5Ëk.ú=Ó1Ë1ýºîˆáˆíuóî]û¶L+Ïg{¨G¤ƒû1–NïùâÍgA¡¶>ûÆ;ÏIÿ>yîWÔ6|ô:Nˉ0eÒëÒ3¸ó¥ýŽHƒÒÞ#/¾Œk¨K84ÉLÑALìˆØù’ë5uÀùª—2‰*_’7Ó»cgô àަC¦ /f¦9!ã˨º¸1\ÔNËJH,Êë¦Ü9÷$7 ÐQíO(‚£ZH"~ù‰"ë ²Oà„,3 fÈ$‰ÏéUk¥‰à¨Ú«›Ž)'Zj:úèéß«fÐØikE¥ÒÏÍA<°ì^$6$ûÖ¬F ÐQª +ˆxY‰nÂXÙ£¡S û>ãú&o!h¸yòm§»¬¶ùʃl‘Þü\Xäsåð‹ÌmQgrøK–Š}åôõ˜kè5µ)£¯=øö3´tÓêz"4d[0TCDñoâå®÷ÜTÌs0t$øNðxð_žAŽ ZƒÖP™'d=üNïS^J?Nã.‹‡ ‚Ûé#á2§ƒ “×ëñ†ƒO|¶™Ð¤ðÜðúð@˜ ‡5f³›ËX¨€&îNy7ò`VˆÐÓœËD°5 ÌSªH ' '•< ó²ç`„Ø$=Ûw˜øiJ å&Ö>ˆzâ’#ó–8ê“‘Ùds0 {„*l0ŒƒƒY ˜ +â¥Gã’;ÓjüÖÄÖTp%Ãs%ˆS«çüâÖ fĤõýµÍË©ÂîþO^~ ?›Ð «@D¿L‰¶ÜÓrf$nx±ºc=½æâVe4=ýøÝ¸†¿Í¥ªŸ•–­jPɰŸ>ò=t 1[œ£ÆÐZÕ•ê-ê-š?‡?‹p]|¯jz„R«¸È ª´›"¨Þ‰pÕƒ˜µUW‹½åKÊ©ò©Œ›ôø]W‹çÙ.´Q¶Qs<¢U1Œ?S0ÓL&£+ÝUƒx‰¨Gîj­A ÆÝ\ÁévAß~Ûçî»%/ê nC.ù×ä¡Åêžà ¾êIdÈ(C±&{ô¾uCdžwú¾Ýë†'®¡CYØ#œ±h€רõB<Æ _÷™¶±r•<•4k ë‚Ó‘2SÁ¦¡˜`h: GtZ¾L5'âJ•"ÅLG‚Ñ?8àeú( á5D‡˜ÑÈôe1˜7%ÇϨÎ)(¤À‚ýXvHÏ U„h|]eÇû/¸¥3{箉Ùoîì8¢‹zù²tyÅGO[—Ë-Ü÷h{Û?žók}ØÉ¤`IÂ}[¦ÜrÕòã²³—Uäç]vï›íaAä¾ù=kŠËÏè¹|Çû)'ÞG%| FÌ Ð”üøŠWh7µ ¯ÁÒŠ9VIø±Ÿ¢ŒãÜÚt‡øE:d~Åæ¦ìf#$ð¼Q«0gÀ'¬ÕðN ‹=Tļ¨ãø„ÉoœcÜfÜedŒÐµuÙ‚áíÈ‚JÞêú'Îzçdé,“ú°^Öá/÷õ†¾&Á?¢´'AH åÈЉ3׫ËÃË÷¬Mã±kÅU;¯ôW°]ÒÌ?õQ3"ª–ëtÁƒ„ox@&ýÞ‘d$üDœ5Ý5ÍÝçíõÝ¥¾Ë÷ ûiïw~e„‹¨«¹ju;×®>ϵĽĻÄ÷¨÷QŸTsÚ/Õ)¨»(M‚àŽÄCàe˜hÄlB”2ãQF£‡N›r€¹Ììƒ<\‚Þá %5ª$»Àá «"$L‚—”‚"@â%Zê*‰ Ñ.j^GjÊg§ÎËMZ­Û|¹4 í»¼¹}5zT”oZ9¼rÇÌ™}˜²><]j{w õΚÞ_ýµ~E“2*Ï·rä n5À¢²úîÌAf'2`‹3€8®‚ŒU\£ª©è­Zä\â^ã¼Ü};ºoÓo3<ˆÄiwéŸ0<y(ºíÃOëŸ6<y2úRä¥hP¾3d0œ“sQ\çråiU2•N—©TÊ,ìe2ê|eUUv£~Þä6>댺#—é݆¸:ä÷» îšx•˜Š¸R¨bpdÍ^eEyjqš+“äÊ}å)“R©*K§S&—Ë­ÎdP;«**ÐÏWU”óLM.“vªU ¥»,âªÊ•Ab&ÉÅTUÔD ݩŠòLZY ÎÐÈ îØ@.ìzBë‘¿ ª¨f} Uã,Öâ?íVÌ’}¤}.g÷°Ë1 õð™xÉa%(òjP.IXÞev8‹þ÷q<¯.D®q9dÇÑÿSÁïœH|½®ž‡v6ñęԷ’(,X¶(€ °ô8Y““=‹6»ƒ§žð¢ÝAGC&EŒÆ!5¦ 4¸2j5Ž›ç®4Sáno†7@Ž5²ÓÃWï(x+]Ǧ_éŸzB:â¿m`Ùô™€[”Ò˜¶D}§%ªåŸmàŽ‹F±ÊXer— #êɺŒËP„¨u4ʽc†·}%Ý4DõŸþÞ‰ÿ€ã›X‚v@ƒö`ï¼#¾…âØ2¾È·»ÚæÇ¶G(žã•Ê”Éî°ó—0…á0ôØÙXÈ1&äûcØ`¦cî„Q~ÛËÛ•&ÞÁ…CñDò)pí™ð·¢rLÂw$|ñÐ3ø[4r¬”¨,{¢ÿ„chx¨Øž¾n"€ÿCš Ì Ê²]V–²ýD>Û‹e%ú²\p£¾•ØæL êÍ9p=—aY©¦–vvj¬¼Iõ´áCåãçHowoþñ­Ò‰WL¢€ÏF)WR HEü¦7ªLé”L:XµUªV®©ãÀ©×º/À7¼~)CG£.ˆ³Þ@ïGDÍX#^øeôT”âb JºGuOñQÕ£êG´Ï(_S¾ž}=÷¡òÃܱò¯•C9ý >U^f÷ø-~”×ë±~lE¦ºXžÒ«ÂÂ[ò.ÓX­æÔÍ\s1fPg›ËÄòµ‰lÙ®2ªlB¢ªÕs·[˜6–¿ìnm!Jø‰a‰­ÿ`9\œØ•P YCñ“OºŒä²­kl Å5vÌQmT5E±^kd|ȶûÍnŽ|8§5(Š1ÒéÙ&Þ‡Œ1‹ï¬8¥“ÄïJ¡"¾1ð«ÊH_­áBu¤¤qd¾ ál„4$báqKHÄk¬TUaªëÒ®­õ±\ËZ ýd6[‚å3UÄêMçžxø…ö¯MØ}‘@¤¦¶­_}þ”ó®Æë¨²h¦wåùIϸâEóêM¿0Þêrg5E¾Æ¦­ wÜ}uûuÒòZ[L箌9£= -êµ},!tÀAœëYX_âit³Xö+4ø-ñø˜uòà­!E„ƒÌR…UM#¡Q͹çÕ¾6Ý ÁX$¦ÈZY±òuKA@ù=“B²™Îɹò8<! ñE±ÇD„¢Ø«w‚ɶÐ(8Íà£Î¬Fc}$•ó&d÷†ã7·êG¹*g]~Û[Òß?\þ^ +·TÞ´éê›Çlfþt‰ Åð¶\²ë_/½#ý¦'ŵ姿¥sûíÃ3Z%ªƒ,À ‹Þ™ƒ!ðŒ½ÑþØøžñ=ÇŸŒŸû¸*5È`õRåRÕëÛʵª+¬WØÔqÞîàT»ƒ²;ÌœJËjó‹¼ ¬Åf:Dµ„üà  öF mà«Æ»#a‚­†“¦"AÒ¡>ÐÈžqȊਃÚíT&„M^Cé(TFŸ9ŠômTN§0ìDPÀ‰¦ 0‘U8Yg“%¶œ-F@QžuÅþL.TÙ*¡zÕÏž¸mñäL­§Ø´vÛ}ÊWRô® ÝB1—ÉUÙ¬/?xçßÚbÓ—wl<ùÛ_Cf‘Œå›!¶øe-ú@\vWüÑøëñWSŸ¦N¤hYæªÌ™{3%Ï<•|:óFòh楚“dÞ­ÑÑÉñ *Ä«1“TõV£/`Ÿäõøn* ‚±3ÁXE6d§ÙÊZÆ”6âÊ|š«mŒÅuÉšb¢aFê m÷—a ¼»¾@Ø0ì;!ç‚S{¨„a$8"‡çÁËJ2nF«²U㩪T!ŠŠq(ª“•Q\“¨=Ù€rÁ ÀÇ™¤pMO?š­tÉkUèÁQ!“)UUiÊ›dÅhèT¦!qç5&ÿ”ôÌ !¢€D-*Ю¶©7þŒ«IŒ»ó·ÃO^:÷Æ–«oºý§ôî€5‚2-X5. «£–×Öþus%¦*W§¼²Á•ÆÜ¿Ç…ÓÌJà'®½è¿Øqxo|ä Xe³üh$ãõ÷bß~©f¹ébë•ÜZþ Í:ã5¦u–uÖÓº“zítþB~®ñ0ó²éæsåŸô| ç;h¥ŠRªh4¦ÇÐ g¾×Ìݪø¹‚R4kÕ^U¯á×à_'Øë§?0Ðû}%ìí3Ár)á/ñzþ*G‰ÿ£H\¦s#ÖqE-&™£‚;Þ‡VGG‘Íè6†‚Ñ+äY«ò ?-E³bÅÀ¥ q€='€r*P¼3|½ê¹k—lm%þø‹gÞø¯ç¯èðCjwù¥izç‹{¿xç’…škÞÇžƒ¯âðØ…ÕS”÷Œ%1}`Àå(Z# *â9U F”nBžèÇa¡Éù8D lÔlsowäÕØÏ}^N¡ˆFT´/Çñ’SÒ+d¹,ð ¬eeûáè7}ECÉ) Ê5±µK¼XšÃpØA”%Trz…ªò•¥ü…Qú%&§ðb’#›ñ¥­=–œòAϹ dÒuÑàx·þÔ· †¿ò°íË©k[ï_övGPJ¹¬Þ®xóPëðÕàË&«åT-µÐ/?3£NXY5½%ÎÛÒÙzcË ­;Ý,g ÊVWk±u)}qÍC–‡Êf³!Ó™Jº[4覢ã ÍJاç)'ƒFK—ïô'&&žOЉ1ó3\'G5u3fDmã'on—#&HÔô²ùê@o¦¡=fƒ<ªßˆºúƒSÛ ¶œm«m»ôґݽ=Ù£Ã}`òB„ßpôa’/ˆ#["GAêÿ°¯Ÿ`T 9ò]"ly¨¼FÓó•øáŸä€˜¾7cë°5tÆv•ŒÙ¼'^ 0v›@÷$59(§`ÝÊ2:O¿úì½5­ò'‘)AÛM6[øÔα“­ÓÍš'L*ã³ÛÍÞ9™ŒgÝ)mÛ÷À¡|W‹&c·¯ü&R?oåsÿl^ú‡xé´VÐ@!ŸëØ&±šŠÝ3÷²ß´Ó“Ëüµ•«žW^àèUÞì½÷?sýØp{[ÆdôÇ#½ ,¾Üš9ÿÕWÞyÅ Tà+d¿ÓŸlΡ¢­Ý†¿µc¥Ýe_³!ëÏQ¡&¬>?Ys°«Éã „’Mžl t†í&BÉd"ä2ÒŠXŽ1Xõ(ÖhårY¿OeщTbÉ,Dº`väÈ„,À‡™‰Óè ‹%$^âDïl–Ù+$-ÙQ["ÉŽˆ=æÓˆè˜pÕQŸ<1A˜7a{I˜ËÐYóY΄uØ›¦ä½5j«6µÁ9—j*ï¹ðçuòñÒÄÍ3'ÜZ9]ãQ×]Bª©¢©°6Âû¸á{:ƒõ›;/“/U¦ö|;|½Â(™WÔh9€ŽtOéŽjÐqúÄhH£oÒx"Èx8†IvãVOÀùbž;˜ç\$¬ŠÉg@};ó>2è ¥Gåðà­ì)hê–Ýk%‰cøxdkWË)²®GËHÙ)ÉUT#ÊŒLÞÔ§’ ÉTýú‹j”úœÚZ‘ÜÕîá©Â<ÉÅV76ÈGOUU—áš Fç׽ޮXUK>¯3²Eñnù2h£Mñž€u’Ûã¹UÐhÕYkHÈHqò2§›×%-äErðNûBá¬ÅJ‚)Yùm>'dH¼O$ÙfÔñAb—DŒÊì‹”é!õ* ‰½ú„ɇô1“Ët G (©l€6œûòTI9#&dþ Î*Â<…·çG›lZŒ]Y]Ú1Ý??]Ϥ&ýiÜ¥™0£1I@õí?¯›Zù uk[³Šó{T!£UÁŸ^ðļ=õBhV“Ð#ìJTƒ~#öw„{ýÖÖ‡¬_†¿ sL ˆ Õ‚ÐkéÍ- ,ÍÝmU Á`Ñd †¬–PP N5 åkyΚ³”—ç`)%hìQ_IsÑ#VªtÔSSˆ©¬åpœö†rT¬Â;7¶>v(FÇj „Õ–òlM@}ìBPµE¢³?¶ 86ÿ YÙ'K >bù:M@/ôs¼Á•tAÊÆŸlcŠÑŒa“ ÷Í! Ñ$l¢Ç#HR9ÅAç™ 3·!—6{Œ3u¦ é[}Öt-Þ±bó¯êþxëd©5dô¨”ÒkyßXIðpSé/ÇD)Êãp;ô¬òô“'Ü]C{<\×îê¿ ®å\ ktj³ß%ý¸ij`O²:ö*ðÙÁ+¢[‘ÇÛ&Í1¦VíÑl5!°'Ûm*ðÊ¡}FS–fE÷ LN€Rºô()•xÇ(ùTÈËÄSÖ×¢¶4èç¦ç8º~¶äñ(‹Sé·[œe …®×XNMž‘ç€J0É©PTÒÀJóïDOµ³2@먉‰‰õ”¡ÎÐíŸ@7Ò­žÄsðÝ— ÁÚó z˜ÅñA¦y&ÂáZO<*4yꡱµžî@H`'Á+ݪoë.ˆc;[ÅBu:ì¶°Œ¦}‚Y_ÑÞh¯hôûíznBw}]"®šD‰¨.sKú­4Õ™ÄcDm‡X]È6ß"¾%R"ô<ÙÁ˜cc³¬ •‰*Ç ý'úûž³ 'ò%Ä\‰Îu&5{”fK6©1ËÑ8rçh¶À ¼à<ȃ§ÞN˜ñØŸãÌ”]ú ký{×™a‚+K[­ºÎØ–¥æo¿¨!`W˜3Gµ¿iŠÔ0£`\Ü,Fª‹³¤ª9•ᢆþtU¯Ttqfï Š—aØCÛ¦ÒmšÙÞmî 7þhÜviÞ˜<ïòðÕSñ®y™)IgAB“§Ñ.—¦íz츧ö‚ÖêáÆ×bXô< hýSú—òª­'Å^§«ÛEÝ¡{H‚Ñ/*üù¬Ð$°‘&dÌžZO Û§‚La +õ™tÄcfh.oÒ'í1=—¯ªJ®r*7¤Ô '«M±L–¦!ßydwus½Ø·¸®'Þ2g!·Ó$Àö1%á‹;\qG^WÌ™ø^8öŠÆ3è݄ɬü§éµ“ÑÙÀ‘1E¹NiÖ%îžÍѳ*'Lk«¹¸¶Mš>¶V<¯®!X-¶K]øC²j`± (9¤©ð«”·(QJwŠØãQ5\ˆ;oeÜ^5üVg9åHÒ¨rä 3îIV×Ý*¦^R~¦¤î0ÜmÛnxÌöе! c·OWM3°µ¼#ï¤8SžW;­mN5dSÜú6=D®ˆµàvj¦¢l,@fƒ ޲k#¬";mb£ZfZ:äˆb…AeŠÂ'a  p,Fe]¢Ï(‹ä9FYipÃÚzšÍ2‰|ÚoÔ¨XÊçæCœ›£æ'Ôù Û™Dà&©ò° QU%Ï7 ѰÀ_EèùfìhÚ‡#·iœb. £¢HùZ¥ h)·RNÍ*i³à ÈÉŠŒ³Èu6´DÞxÞ¢Ž‹ïÞ¶dÜÒ ³ó‘¼ÚlšÃfÙ–Š™s¶¼ü×ý5 ±ºe¹d\Ýú»CƒÎOIÊáÇmcéCã“`½úq›R±©%PóÕÑW¤§tÖéà *é\åß/À1€öú¶8]•t% IúöÔ£™ƒ™£™ßS_dN¦¸î®á#­áã [&PšÀ¢ íVØsîH™µð4cp:Tùéej! SÄ"Y—9é@Ÿ*´mÛÒ8MÐNV^eÿÀ–Xb?,¤êËFÀx®ñd–3›ú¤6ŠÔY(”F…Ünº8^4@ܬªLu÷*¶áÑt™~Á¿G)ÙШ?š½ún•qÔ¯ž Må,Žôºoºáêó+Cc–+{š½S%Oü´%ëÞÂø‹ fW¼€š˜šôÕ»ÑmfM¼…Á £>%V¹b¼GÀµ ðºv_ùŸ?y²0}ˆ‹³>$ü²kð´ä‹6çÏxÁ9XZ¶ZA,æ³Ù¬À=!º[r’i ᥂=Ö±©kFEÓŠ+Wo_[u o2(œßl¼¬cÒ–ëÞÝ}Ký]:‰uá®[Õ°bjKÙ„ˆØ²ñü[ã*µô—yÕ Î«Õ9fõ=ýwÄú à¦楎ÙªÕ ±LiÄî e¡Š¾ BT ª1\£^-ªuXôÁ¢m*kq;DcÊféÑ]¯¸>l€Å$ÇBÓð#éÇåxÅÕtTNO‰<…èQ_:q×ÉKdH%1îÁ‰Gø¥0ÆîãB”šûÇl aPµ_êë?í°‹AœM«/MM¯FÕ ŠI‚k¥ ¦ñãÂ}NP  … B-%‡4ñ`eR©~kŸÖ±AÜ¢<™þÀ«”*/½)sæè~…%hðz†OáׄNs̨¤ý~¦¸h8gÖÙÔ‡½“ÂOøFe#_³?øÔBfÂÆ(Í­EwQ¨ *”|)OÏ[”9G0\cÙdQÂòj:ƨ]`U®\®hJçÜ·§Êe±Â”ò<ر¤¥˜jªpWÁéôTS0(Ó¹ª 7œ`ƒwÐ×r®˜5í“"xç|{Ä¥ðzÙè˜Ó_)yCe‡ËrPÿqm’ƒIt&¼+›û¤ãøZeY2bFçTà w¢:lþ™Ãð .L>QT–Êy«{„ž`O¨ß¶‰ÙÄððQ|3upúNÃ;S]UU©x…ªJaçU*ˆÀX x5…=a' !(a«.T© !kѤJMUpÚŠï){ÖRÀV U‰ÝªRðµXo¢k=cÞlíòxrå4¤ò+TV¦Îh[Gέ3*ÜåD…j(¯Ï¾ôáKšd‡eG¥åF¨É^<rId2$n&û †ŠÌ<}†Ã<¬+ &utFe‡…<Ÿg&ŠXŸß{)FœÈ^ H €ù#AÙ®… r®ÈŒâcѪ*O²Î[^Å-ù÷c˜ÏÉHó½vÔ6¶ÚwxuþJéýêÊä_Õ¦ÆÑwz°ÙgîÉ´NÎŒ³¹Là¯`²±J+&d(‡¢&ss àž<•ö©ÌÎãQá»o¡p€ÃOé×Ç“Ü—ÌtbB%ñ²Djœ²Í=.už{qj³jsê®ÔÁÔïRºÎŽ%U©$P¿Z]49@=U*§šR©dJ©v8áŸP&+õ˜‘"ióèr\î̱œÒ‚Ö[°¥Â¿XÑYßë;l`SÇÈ©€pŸâ|Fi¾?,ürÉbÙ 4ʰÎds‘e`2ÕD<ø¡ GF¥ýò¾ÁêÇæDB/™rÇ¥5Ô¥]‹l5W)éP0_?¤ïôc^Õy½ÃßRj¾Får@Ê•ŸÍ$N?÷þ 5 ñ< )¥KEí!’þU t0àG¾×ò°8ËN½DQê©& q°©&•Jmà0×á.3–£°¡cµQ]4*T‹¢ŠJ•‰ƒL=X“)*<¹]ŵhšD½>îaè³K5 :+ ,f-È¡8.'Æmè´+h;\‡ål ?òx¦–}$$NEBU„ç8Žd‰åè²sX…JT B„n~»o› yNK…¤·hC |ðNÇéC]·rÒWvºuÜE‡Ï/ÂZ||-u-ý:±—"ŸØ£ÖòƒøÄnJ“}gø(Ê‚Êv&"Aô¬?ï|líÚGv®Á×>~ÅÚ;×^A¾_‚aÊØKP zG\äçóà¸?&;,ZŽ…Ëš<™c¡úVOó±G›œõÆJ¡Ll‹ÔçËh¦ÐRkO¹b0à1ÜnΫ˜sc…ùn·“S´4ga¾ceùÊl$Væj««ŸÊз±ÎÖ¶AÂ<M/4NCÓåè]|«q&:¾GÙ‡6¡C0ÂòÈÐBS»Æ·õÌHN[²lá¥é)˗ͻ䈘q endstream endobj 46 0 obj 17667 endobj 12 0 obj << /Type /Font /Subtype /TrueType /BaseFont /CMNUXO+Times-Italic /FontDescriptor 47 0 R /Encoding /MacRomanEncoding /FirstChar 32 /LastChar 121 /Widths [ 250 0 0 0 0 0 0 0 0 0 0 0 0 333 0 278 0 500 500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 611 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 500 500 444 0 444 0 500 500 278 0 0 278 722 500 500 0 0 389 389 278 500 0 0 0 444 ] >> endobj 47 0 obj << /Type /FontDescriptor /FontName /CMNUXO+Times-Italic /Flags 96 /FontBBox [-296 -413 1661 1205] /ItalicAngle -7 /Ascent 750 /Descent -250 /CapHeight 667 /StemV 95 /XHeight 454 /StemH 42 /MaxWidth 1610 /FontFile2 48 0 R >> endobj 48 0 obj << /Length 49 0 R /Length1 12632 /Filter /FlateDecode >> stream x½{ x[ŵðÌÜ{uµëj±VKW²$K¶lË–YòvmK^ãÄÙ퀛,8 LMpàj M)Ðæ±¥(&P¹šB( Ò ”÷m¡u·éc±õν²è׿ßÿ¿ïézæÌrfæÌ™3眙{}åæ«V#5FV®؈¤Ÿ¹ÀÉ•CWº³yù1„˜Äš—®Ïæµ4Bì™K/¿fM6o©@ÈöØàêUÙ<ú`Õ dóê‘opý•[³ùœ³/¾|ÃÊéz ô‡J×l‰õî+Ö¯Îâ—• nܰåÊl¾ô}€Ý7¯žÆÇ=@ÐRy7 »¡èoŠu# X´ ÉÐ1$GqðtæoÙ3ˆ†Z±~Wœx›]¡«ýëåRþ) žøÖ{•“|ù„¦]ñ=h­˜Á¡ MŽúß&˜|@Óû¥&3‘%ZBiT !ú1ù6V£ZÄ“;Ǻc|šìBGe£,9Ø~¸Þ|x9¸ùàr˜?'ùƒqrØ}¸›tì&i2úD¼‚ÏI“=c­¼)MFÓäf†4Ù @Ÿ&»pir]šì M“hÒäê4¹€*M¾ @™&ÃiryšìÀ¦Év²4ù&M®@§É6Tš\ˆÙ §ÉÕPš :€c¤À˜,M¤_6" ^'ÅIñB)6I1'ÅôÑš 5Jüì¥x¥í æƒšsƒš5/ jžÅƒ¨ œR̦.Í©.MªK3Ò¥©íÒDº4…]bWA€uNŠ=Rì,šóš·:4?ïÐîЬìÐTthüš4þ… ß©yw§æášüïNs'”þਮS‡Oã Nèìõ±î"þÇøyä†Yòø§cî§ùF>†â´˜vŽ#^Ê?…š±ÊG‹$ø( ÈE¼þ±îJ>—u׸x¬{€ecÝËôŽu_C,EÝR“Ecîs|£/@n©Ë¹ÓCt¡=DìjÀG¶ñ—BëÄXó%|£7¢f ½F^Õ¹"áœ3Ý~šB-Ô‰õš£ü)~"žÆKÆø¡ÿÿá¢4Çø_ÒäQAÅ¿8ǟ쾃¥;M ø¹EP<Æÿ$MžâÀ‡HDã¿/–Œñ³hßv§å€½?‹}gPêr_0<Åß8Å޷CÛ‚§ø+š¥±×gÁ¥Ah µk‚çøKøoò Rûyn iÎ"iìöø)¾5(Ý$à§ø¤ûß$6ãØb@TC6Ív[•Í•óRoe{¤ÞÂٙË€Zh2ý‚Ž÷ñ›yOó¥üb^Á+FŸÆ7 âBŒ½fG·°£—±£ëØÑ%ìh;ZÍŽ–°£y쨋5É rN®•«åJ¹\.“Órû”μ/"Ð&'è<Œh)Í1 Ĉ`9AV2‚äd7„› ÜázÃv@ø„m¶B‚0’yÿ ±õ8!ß8*u:N¾A¶Mn#7M§n"[§S[É”‚Mü„8&À±„Ò8³3…oIÉv÷¤p ßêH!ˆ{­fóPƒµÁP¯µ$þNÔ/ö'B~Öÿvƒ m!…;»¯ù ˆé€õ<þ‰yŠå_eùÇX ³s! ŒJ£Â(„ÑWÙÑi«3µ¿saOêgo*"&2ÎÞÎTÉB÷Å=ã¤Ô%ã¤^½=ãè=Ò\ –£÷½€¶LB­Ýh(.@à ^D’‘ÐVfÑܤ^Dë ‘«‘[Bs“«%´s"Ú‘ÍñdâH"@¡ŸA›%”Íô3_AÙóu”=Êži‡ÔK ½4CÔÛs$/GyR¾ Õ‹²Õ%Ùê©:z¡:˜­nÍV·Bõ×xÿÿ™YÝôßé ¹va“54XC\-³ê”ÌÛ”b½ÿ§>¶Lÿ`ðJÀ#`ª‘YŒŒÔzdG(ó°ÿ™?O-ËL1¨xê‘Ì¿Q¹°¹¾;ÀσAûÐsh+ÚéëQQ!jOè!02½èP)lÊ{ÁƒØ‡Î#+jE—á÷aŒGÁF½ x~”Dw!3”¯BCÐ>5î“à½DÑEèt½„Î@ßEhZŒŽ“Ù7Pº½ŽHS™Qè©U¡õèFtkæ1TŒê §atöâ-™ ÔÏz ë6ô:yæÅ"¥Dc-`·‘Ž`vaïwD ¾è톑–@‹£°£[3›¡•U 5¢6Ôt_‹ö¢@Ùó輜\IÎ$2Ïd^~ø }>P³9mFWÂw¡§Ð8ú /!ÚŒ/sf<óbæ€Kƒœˆ‡6u`#{€ÒKÑ­Ðofü¯èxΡ_c5®Á¸ïÄwãñ›$IS»¨1šcøÌ¢\àL8^TGQ Ð}1Z`ä[Ð÷Ða ñct[±Wྟ8IYC6ãä4Eï¡Ïe>–(!°,p²(¯GsàY |»E£èX»ý@ÙCà¾+ó+4>C_b³XŽƒ8 ½·}ÿŠß#Zb&^ÒD~E…¨zjýsú“œºuê/™žLofSæi˜ý{0–8s‘O¡å@ñ*˜û¬öX;ñ¹žÝè>t= ö8zF>c¿ŠÞ@ïÂø¿C¿&Ð'è?ÁOž*Ô˜ƒ'çÂãÇÅÀµzXÕn<áx߀oÄ·ñQü4~8ÙJzHÙNv““Ÿ“7ÉYò[ò{òWJA9)ðø%º•^F?Æh™̵Ì0ó¸¬jò“©èÔÒ©åSCS§2lF›)Ì e¶g¾“IêþIâ¤éÀ_öŠ„`Uç ¹ðtƒ¤õ¡KÐJ´]k³¸yðó^˜áÃè1X§‚,½ ³û9¬ú»è×0³¿¢/Ð$š›>Û@ž qfÔ 3Z„ã|1^ŽWà5xoÂÛðµ0Ç=ðÜŠoƒYÞÇGðóøcü >Oaˆšè‰›ÁÊ´’Å𠀬'×’]ävr'9@î#‡È¿9J^nüLQ*JKù©(ôÆÃÀwG\²=i]™ÔðüžlÞ.qŒ!!êM‘~±æØLMÎb±fx¦f¶y¿¤ñ¨è磜”<öOÇ™ÉÁx ›ÿAõj©îŠ:ÓHÑÝsƒg.:ìi”pŽÃ µbyq•‹â¾6ó‡LEz UYän¾··{Ý#î‘öU#î÷ 4í— T¬é ÃÔö¬…xQ'%ô:f“«{{ãÐO•Ø4ô‘^èaÝt¥¢ð$ E‹:a‘ó»{æ÷¤†Ž”è…E…-t Øz vOo/`UÏR o_k¦94WB}<Û xîÃÐEïȈØçBQ>Œ8FÄMŸÍ§1úÛaº Dq/¤ñp7´àõ8įÇë²z0T 쟅››ÌáºYº¡e=P['q¸áˆÃÂ?ÃáÆŠÃM³”~ÃÍ@s“ÈáÄÿ‡“_ãpË?æpë,Ý@dPÛ*q¸ýˆÃÿ ‡;ÿ)Ï™¥ôkîšçˆžû¿Çáy_á0Bô™ z†<‚V’XæÏ4B+!Xè ÁeÜ©R· ¤9~C3/ä!TQNTÁå]_LÝ’yº¹?UÃéãYÈ»Ñ2I­AòïüDB(4œþß²ÿkS.!€¥„ ‚›mÔB ž-‡ôRÚž“iÖO3KeUp[€¶Ïº‘ä’ßS»©óôV¦EÆÉbƒòZ…Oq½Ò¬|]µJÝ¢>ƒˆèsɼpîOM‚‚f“ˆ‘% Ü‹ FŠBJ›ÄÈ&'T’¡{SãørÇÛOj'kçBÜ5Y‹j¹IÈBTVêÕ{ôFYUú‹8Sýù‰4uâËj‘4 ¾ßÍàù‚nGvA#ú^4C#UÓg ¡ð$Ö,±²R£‡õ ãçœSõD1,µËü9óYÆ4A» A«À @åh58ï2œÆ· ZŠ"*²ŸBû±{j¾5d·qܤU¤ëòR܇ËÁo?¿jò‹ULÓçßé€lea¿-äÑ–8ÛÜ#.†f,VÚT¹iô®›·ºÞåÍ&Ÿy"¨~W¼OŠŒV CÓFwÐbµî1Ð4cdܼšöNGçÓUt ½¦å¡=yžðI÷ÜÙ¾Pmˆ;ô4ìÒ–„¶sÇCâT­ˆût"ô%¶Ÿ°#n‚Ëõ"ò÷5Àá) ¡²"ßËVFëq±˜d,Öâ“Ù’ãY™hîÖa;Ë–D.±çþ¹œ7ª1™JªíÒÉò°™: i»’Çg×Á³ÀBXb˜³ŸÈ2IÒ •x™o1óXÜ|8bfµ˜fvy¤JÜŸ Ø¢ÅÞ¼üÊŠª(TÂBHcòqSøÁ½×&ËïÚ;\²h3-SmRP„¦é‹]9~J‘£ÓËMÚzëàŽ˜¿À¡1,®oo®(ãŸ{²'>?{_wû¼;6^`öiçhXÃ*4:íÔ«0Ã!V­eZ!g犊€oW‰kKU£Ã°sÛç@£Ãú3¿¥^b®…{­h9_kxIøÒðÖü+Ã7ûFü»óv=”?îR±ù•ù­ùT8Ç§ÜˆÒØ(T^e§.ÇŠ˜Î,˜“Ã|>°;¡f ¸UÁx®¯<(¾wä|¾reEù¬À÷žÃg@à'à™f±(æ ðf¥\RzŸB¼ ííœè¨uWEÀR3š@äg ?JO 5%Êy9^&c4VÖuw ìeFA^\ÖpÅUWì|ûÍ¿tÉ¿x`Ï‚úûnÛ©¢7{ÕKåeäJl•Ë5“êáøêÛ.ûìí7KŠ­¿~í±¹}Sçþú` ,Ú¨àÛjðm½ X¼oy‰ÀX±ÕckEìp*µ £ øXS“S¥ÿÄýˆ^«_°zx¶ÉU判Ÿ “Q¸ìÉ÷KêðäéMö:@nèLŸUbÍäI˜=w²o4åÉ>+(¸˜Õ^V$uH$ù³|U¦>¿¼:ßñß?Ñßßu[ëliܲ÷¦Cã?|‹ÚuEE¸¢$Ï^«0ئniÓpoRnî-]øè¾~"z5 ™ßP0·\T€†…ù—›@ w“Å´Æ4dÚeºÙ—é8}†þþZÍÐX(ð(•y\^€b“'§•k¶© 4ñÜÖB1Ë—#™[&Èúe¯Éþ(“ÉB…3Ú¶LÖ: &¶œ½î„Õ.©ý°”„Ùn‚u7LëzZ—5hâf‹ÎLÖ—µ @<‰Ÿ½9÷â©ÇÓ(·Ìë\Tz‘½xÑû×}ïû“ÏÛ¸=RÉëø7¯¿ÞÖ:zÊ”ù{.‰8;-±ÚËöï}æ­µùÅZtËâ¦z¨©›ÁŸrÂmÔO…íkН.¾Ñ¾«ø†Ä¾à=EûrU‘ª”TÓ-sè„rEñÂØº¢mE[ªï¡÷+5 gS³›2ê©xŽ»Ñ¨×©Ë*¢I³Ù§B<îTTÜéŽ<«”°Î@›Î혣Žo †HhŽ.~]ò¾$I&eñòG7FG£$Ú5'|ötß¹ÉX¸o‚; !»s&ÏÛmV‘°]²àe7ÅÝu¥—\ ¨©inå È”€F‚5¨*Zö8›ul.KyŽ×„(l°º"Þ´èá•F÷Âe·Äão>p°À\Vð¼Î¾KmÏÔÈ–í6wÌÝ&”TÿþíPíZ#“}q›ÎnÔÙgyö½GñsþºGš:ÿpÅ—7nžW[`¶™:÷ôìŒØ1ÙÕÌy•®2kQÍò»NÄŒÝfŸçQ´ÓiÉ[°ð»[Ÿ¼q, ì=æcê fj@§…­¬Ëâªrµ¸–º.uít±lå.Å®*JpyøÖ´16lð¢Nº°Àd¤Ëìò£ ò b´ ®å¾75ð“Ѥ‹Æ¤º:F㲨†­F•öf¯ÊÔ4r “Í”0]iº×ĘLÊWÝ(„O†Eà ïofܶ‰†8¹ Ï˜’¼7ÑvXE7N\Ѽ|æE4!ÓZÎË:vŸCÓÆ'kWŒYýfΙÕn`£%gîk²–0Å…„U-Ž7«"Ù„yÎ!£þÝŽî½W•ö*Ù]29§ã í­ö–²¥=Á*Š>@(gk>ÙRZÖr/(R=©S¨ -S|yÖ쫛g¬µLyL~^r\d,] k,ZÒ!×+lZí/6ÎÛû%ýŒÆ éá„DÐ@æc’Ëp)CûÿëÃÖ´•R䎑¢¢~PŒ·€æ³µkýZe ùüL·J|)^\òu–±¦f—ЏAëjµ¢ñû‚?G|¹Ý÷€ï/>ÊçËzL"Ã7…j¹ÐIø¼;mÅÇÂ’ºüt‚;?AÀ/ôЉpŸÉIž±×YÉ¥Ø öY’|I›ÌÚãi–æ{³6+/(¨©)pá—µ2Æ”Wí)µ+;˺ÚC1¹j/EWÎ]Øî/]B¯ŠK¡¤¤á=f²*¦Ò©Ô5ÞF³vmI[[™3THˆÚ¤ôé=J•LnÊÊðbàW ÜoûÑn¡MfÅ~¯±Ñ`Pæe;Õ^ÑA«M&ÃÖnÓ×Ët:­å4;Uºü –ãt¸IׯۨÖÑ:]¾2?ãפƒÄ¬m‘@ÑÁCè±âÓ]œvûqÉÆJ–§^XfÔ팶Tà+i]P|•¡º›e§^PÑZ£ïÊ cIéÂE¾Üœ‘ƒTØåy:ì‘q”Ò¤übnÈ 0:†kו-48m…682 Kæcæ~Я p™ð£šyµuóæ]U|Uí®b–©g› ró«¸Ê9•]Uó_èøELJª¹sç5tu5vll ¶{;:ç4W0ù~N'“ÇM]Ê¢à\»M/câMs»eL…ž³ 6½ÝÎ-Òqoðûó+ÊËyC$Â475ñ†ÆÆ®¢¨2]°`Ž’mj,F”¢ úó¹a?æü ÿ"ÿíþ1?ã÷/T2ܢȪÈõ‘G#OE~9a#]\cý¨5J`ZL æ4ãCµµâ‰ÜynbF!´JšáoBX•ì߬†øêÙ/»Hòit9È0;ëûP2Q·ƒOµ€!ÑÍ””ìn¸M¥7›eá¬`‘´ •Ç—zBºoÛžk¼ÖÔàÈ1ÙjxeÛí­nsÃŒR”ÍØ<ÖT[Öxﳄʱ6Œ×Ä+Ý•ž§èª®Õÿ.¿jÃÊ݃ÔÍfÏœ¼knz¤÷~¡Õ¼xòW‡!Çäj³j×\ÃÙëty9¤TÍÉ­ö—×}ë/äE…^au¼qQï¾e“U&U€£ò¸;µò{WÜ~A׿r"`½ðp5þxÌTU°®îžÀÃñÀKŸÕ¼x3v¦FG×ÑõܪÚʺֆ^Õ’º«]» wä¨TUЍ›ëh!à¶E*\ç1¨6(½ªN]yÄåÄY̧é‚BÀl6¹Ê#ÞàrºôAà `sbQ³Ž‚Hék.R%œ«œ7:)§Ï•p]âºÑE»Z›œ.ÎåjRb5µ5†‡NZEë€À h!f× Gq§íDiÞ'½ò ‹ ›¶›³k)ø.˜Œ™ýû5¡‹á?lf=¥j‹¶1ê~BFvn[0º¹È]§”ß@+µœ=Ñå\Pº 3¯¡w(Y‹³sss²²®‰¬›ë1:=ÉS*ÙÍL-xú¢ûõž%Ö ×”GRè¬u«ìŠç×èóµø×Ár•Õ»{þÆ¥ßìDØîgà<¨ï²_hk¡ÛÔíš^ÓÇ}­f¯æõ+†lïÞ²}¨ûÈü‘í¼îs³A¡R¨ «tÜLÓÊ@.K9*mü[àp;eq}‡Ë> Ž$8F}Ù3…¤ð7õUef’‰Fô/¼>XØýàŽË Þ¾{nÚAºGžþé/GýèÙwo\þÍ#%K?<ó9úĶÓ'O÷¶_ž8%úðM'å¥n…7á÷ s_(Àp«B3 +s8áMýþÁ · ³ˆ×¹ˆÂd\&³ŽáM9aât‚4¹ø"Vg.W°® S©n ËxÌsC®Ý.âj —„O½ Õöå:R"y'g] ñ@?sÕ3×BYÕp\^«Í*qñ„‹?}B’Ü·0–<=ÑÊÍì|Ñe¯ŠÊñ#,Æ«Ìm?].//æÝ 5­’îˆ{CŽâ‡´z—_í³çŽ3Ô­*VÉLmÝòQ}°¸ÆÊ™eì;×u]×}YV±ÀîrÓ”GÎùD>y2 سèÁ¹Úÿ-å-ª›ügeL®Þ*ÖûBµúòÐZý鎒kž¨È; A{Æôk”´›Ñx9¥ß+Ês¾;`d™€Pš_¬Ú'ÿ|Z–&}?,l½×û¨—x!-ä™àc‚BΛ×c?$从*¡Üë©8$`¯=ZU>¹ý<\-Ù­ŸH1wæ+`g,¼i²o(lìƒ(8…À©T¢Õk!HZ™ûdA˜öÒÊÍà8K.uÏzÍ¢.§¼—\k¸˜ñ¡EŽ{Û=fWt}ÝÂna§Ñ¹}Kًͪtx4v¸cJòÑÖhIúº‚»Õ&£Üƒ ¯©¾tIkQµåÚù±ØÒ~“~êÜ@ÙEÑÊ‚úykæ­Š_¾/ÏÚIäyøËéåð}É¿1NÆÅðKø5ü¿“¿“—ˬ 棜Ïrh÷¸ÝíV+¡„¢)¥Q`<e!”ÑbµXxeå p¶Ü©5ÉDÜG³OE‚AŠ#-$¨,f] àÕŒ‹!ÜÄ»’““X<Ès!¸´«%r®ÖÂvî$wBND.J>™½î%»5Ë@0WF/Ø)Qs š-.¬Ãå¬W²fâO²eù•]„úñÝrnõ†~ŽR0JšÂ8ö ú‘£ g´‡‚]»ä†šò’ŽyÚ¡eCÝ›4C«’½Ó<¹Âà©È]¨Ëùæêª¼¿ë#êj/J Ï„Û»Í˜ÔØËì¿Ó_æT:É–Z—T÷ÄW9WEïtî¯Ò …îP[¨Å­®ŽÇbñÊJ»aÚIS ‰J§–vó|aS¬:ÏCW:%ï5‘@ŽÊJÞàtæ*ÙÜ CfІKëT‰¤³%ˆ¸–ĒľÄñĹ“H$•¹\“s‘ó°&ÎeKrƃË-¶K:< îè„sYÓ!r™SÅWœKö¸Ï×þ½ ß~\~\ Ç ‡ÝÎß´èJŽž·²W™uxæh!^ŠÂ;}ÒÈfgÚ°NpÇà 2ã^|L¨ò–;îcä˜:ÂÊì95G’õîÚ»žaäjÎmU9 þÜ’ÈÊÅEÕJ•!×ÌŽÌ»y›ÇQ‹ó†R¯s.¬d´“=¶\™ÅþƦÕßèzh²Æ”§Ò€,ª|æbãœè†Òr{} eíâW<¨Ím˱ÃU4μ2µ”=C›…B+Ï%‚ÓãÈ”Fœ9xC.¸ÊZp–sK#L ±9^s§•%i\'˜Ñ*¨qä:K#l‰9fŽ{‚%5q¸’8ƒ#›htQÃ乆O&ÁøÃ Õ†BrXVn?%±ˆ‡cq[—G •${ˆf+ýÑ*ñØ×2¢Â9kHZ¸–_YÌ·åçhe:EÙÛÞ²ùódN/ÖçØZ.¸¶¬_mÖs¡`0RÕ² {VÝ·¶ aêt‰Ñ dLÕTã¶á£Ãí© Ô¹S}H-ïÐ{Ô y‘Ÿ/¬i½lâÉGNoy2ß‚…/!¬†Wï,ï7àñP9ì„$|Ø/7Ä/ æIß?‰_ï-AKá;·‹®øú^ü'ø§¹kîâžy¡EkׯÞRÜ~åÀåkáE ú/Ô[µ‰ endstream endobj 49 0 obj 8981 endobj 50 0 obj (libsynthesis_contributor_agreement) endobj 51 0 obj (Mac OS X 10.8.1 Quartz PDFContext) endobj 52 0 obj (Lukas Zeller) endobj 53 0 obj (Pages) endobj 54 0 obj (D:20120917093602Z00'00') endobj 55 0 obj () endobj 56 0 obj [ ] endobj 1 0 obj << /Title 50 0 R /Author 52 0 R /Producer 51 0 R /Creator 53 0 R /CreationDate 54 0 R /ModDate 54 0 R /Keywords 55 0 R /AAPL:Keywords 56 0 R >> endobj xref 0 57 0000000000 65535 f 0000058245 00000 n 0000004631 00000 n 0000017130 00000 n 0000000022 00000 n 0000004611 00000 n 0000004740 00000 n 0000008877 00000 n 0000007628 00000 n 0000020953 00000 n 0000017710 00000 n 0000029569 00000 n 0000048272 00000 n 0000004892 00000 n 0000007607 00000 n 0000007664 00000 n 0000008856 00000 n 0000012828 00000 n 0000008913 00000 n 0000012807 00000 n 0000012955 00000 n 0000017093 00000 n 0000013178 00000 n 0000014705 00000 n 0000013144 00000 n 0000017532 00000 n 0000017289 00000 n 0000015885 00000 n 0000014726 00000 n 0000014951 00000 n 0000014970 00000 n 0000015865 00000 n 0000015922 00000 n 0000017072 00000 n 0000017225 00000 n 0000017411 00000 n 0000017467 00000 n 0000017654 00000 n 0000017885 00000 n 0000018136 00000 n 0000020932 00000 n 0000021339 00000 n 0000021577 00000 n 0000029548 00000 n 0000030253 00000 n 0000030492 00000 n 0000048250 00000 n 0000048671 00000 n 0000048911 00000 n 0000057983 00000 n 0000058004 00000 n 0000058057 00000 n 0000058109 00000 n 0000058140 00000 n 0000058164 00000 n 0000058206 00000 n 0000058225 00000 n trailer << /Size 57 /Root 34 0 R /Info 1 0 R /ID [ <9c42d52f2953ede5b562e73783758a86> <9c42d52f2953ede5b562e73783758a86> ] >> startxref 58404 %%EOF PK\1A4.¸õèèbuildVersionHistory.plist local build-Jun 29 2012 PK\1AL9"ô|¶t index.xmlí½isÛHš ü}C}Åk’¸÷¸wmÉ.׎\åµT]]³±á€HPD$8(Yõëß>ÎÕYÞÏI’çÿút}³X»gêm£ØÙ.ÜìK>÷—ü‹ ˜_6g@¶dIÑ$ ½¸w·nèÄAøæ"ò½í}´bô@ûz·÷üå×¥»o.þ÷ÞŸLŒ‰"ÉÊ«‰$¿–´×²yñÿÈO×^=¡gQh°:ÉŸo.~ ÂåÅüÿ1gtÙíï|oáÄð¹·]èáÍõeè¢gW`ŸC8Ó·‡ãxýà€Õ€ãšJöT6oeùµb¿V¬ÿOsM?XÇw¶÷{çÞeÛݦ@ -o®oÜøv¯Ø´u»ßܹ!„ÿ|sWüŒŸv`=ùÈjျ§OÁƒçFM`@¸¹þ§yw¾{ím¿¹Ë[÷{ü.ø~l·x@QÛïð€ûvóá·Ï‚ Þ±û£³kœSaÕ¼ôcµ`n®ßqxÁ}èìÖO‚pãÄ…”]Æ«?…§cæn£|R  nÖÁãgp&~Ü{K7j¹õÕ¾pZðñOÛ¼˜QÇSU-ßë Šá6e'ïýÖM—Ý>Ù&lùv ¶ÝÈ(97ÝgÚë—›b|ÃÚ|YšY39…Xlþ-]Ê_ö1ÀnØcu˜`ÐÛäÍÏÝðâõ¦O)²fj–jh&û’4@-\¤Ÿܶ¨Œ~)é°P“_#€#îxvÅiõ`Èy‡·kiëxþÛ8vkHå£[È ¶°ÄÑmUi¼¾\Òä¾sBÞ»$3ïR=¨œŽ^ §ô’r³–î×ËU"L錦 °Fðñi·v·¨Y}ªƒts}íDñ§`é­9á·ýn€³È„ÇâD]g WŸ ѰþOÛeÑ;aèðm× ~1.ƒ³¡ªp6Ô,Ά†ÆÙÐâŒÍ;Yæ¬ðNGÖªó™çÛ4çÙRÔàö—Ëëa®J¤ôèAäÞûüÒ€¤ïÞ˧~Ð+ðÝ„Lí•ë»1–ùú\ó:PXŒ½u7;Ù·Q䯽âHhÂ?ƒ-s#^¦Ÿ‡¯xsÙå_V·ÞÆnœ‡æ§0(A¤›køìÿì½Å·ë øö9t<÷±ëJ6Âz{{ók3›`A6a.¡ÿÔìÊ–ûy­N h€9] µz½qc0…ú{±ï¢¿(_Ã"}sŸƒp5õ(´sðÜØ‡l¶6Piê’5›çÖÎߦ1š5Tî35}ô–ñ„§“gk×»_Ço.L›xÁ¥„Ç =Ú8á½· ';@”™OÑkß]Å>ʹߦ¡Øª­é*zyÄq°ÐH®Ù¶m{%+²d#¬þ:Äßft^#ú ˆ$"@¯W‚Öj¥5&ùŒÑÏŸo~ =°:hûÛ1`Õ®?ßÜ€5‹ÿÁYÄAÈu±V9¸Rçyi´óÒŽá-ÄŠ¶é. âBŒ’Y&?ánAÝð›‹w¾³ý6º§‹äÄ<Öqíº1ÍOWo.n>ÜÜdO§Ù.ÙãÐAZ1ô .wP‰É[´þ¤¬o.²–SÔtª'‡$¹xà ìЃ%fê{|L4Ç×͹‹ª€÷ð» xq¯ÁrÝoß\ÀÕœ2|.æÔ^ºÑ¥—¥ué•°9­»iR§nF§‘íN+¢(–DÑ;-‰buZUê´$ªÚ¼$óìhÎÉCºòÂ(¾ vÞ“cüU°·„…¥Éž~ 6Î6…]è‚ñ7°sðx „Ÿ<$äëp´P2sñ3Âj±¢KÕ_½I?WiüÍ×á~žÐ2w÷›¯¼Ù¼ˆ¾ì}÷7H,’o‚¯ßìœø¥á/«à¹ð‹h@´½]œ1J·Á=øv¶tpAás̯ã‡æ¥žº?ÍæøñÔ´÷ýd†”·ÙànÀJ~sË=h¯×Þ ω£ý° \¬‹Ì÷úÆû#ÓÂÙy1ؾ?H œ'r6ˆ¶‘Ðnf›ìï×¥ V!YO¤ôþyøËtKîÉá%¨KTy‡Îâ[¶—1Øþ›µÎ^òIhj|»ŠÓ­Ê q" Kð.toïÜUº¥SñÁó}æ²g/³ypÑÇI˜¾Åè@”á_$sD ñôà…ÛlŽp÷òù/à_“ï‘—Ðix}–€×]¸ÓðþnŠ^Oá+LÌs.á>ûë.ûËDŸ¸Ýùg–€"^:»ÒÚ¼§À óã½N”QÉOt¬Én;‘‹.ÄÚ[Åùf½»wÎÏvY^ÊÛ|÷¨gƒözø~ðUýùM¡l³Ù¼Â Ì+ F¶·%vãç`ë’Ìl’ð ?Áà6`ÃkçÎõoFi•irðË©ߢmÅ<ñ*Ùý-üä\´ëÛnž/ùœ¾!Ù£Ý+€Ã®Ù¨{Üæ‰F±3ñþùIî#~x=…·áÍEî)ÓÐôç uKw/{ž(NK’O.ÚõjÇÚ*rKàC¨D|›Tƒ³¡©p6”%‹·%E¹ÏhiñÎG‘y'”­<--‹gÓ ûCç‚2–'‘åžãZaÂ㘠Ԍ‹ Ú9Ë%Áõ&Ú5PÏÅ•Û<¸@.o‹B*Ë'¬ $Õ3‹Ì6€ÙÞoŠ ìm÷Á>š3—1_8 e / ±¤žÌÚ%‹ GX]ÉT¹ZZ«%{{º.\¤[¨)®Ó–B[&´eB[ÖG[ÆÄÒU~¹›Ð±ŽÍ.P©p¡Û15sÌqS¬­DC¨òƒ–¦4æŽâ2b©¿Ð Mà8š@_õ°Uè¹XÇRÕsÄLÆjÞ—Výì>"jõùæÓíáì;_¿’ 7A|F|¤Ó&>Â,Ôžðr†²šf¡éÄ#¥Qa‘z®ði,îÝONÎÕˆ2 Ë•·Z¹a §/QªFHÁrù9k“}|ƒ~BgšÔßz÷%.é¿,—Ø‹ø'83èg"/©Ô©Ø;lMÓ«Vù°·˜Ò‹‘‹]°>~hÇ;Ò»¯Òi·™!Z+Þ9¢Æ¬YÒ>.Þ¶íˆÞƒ>¼‚mYã¡|;9˜ð)&÷7±Æ\kŸ ”50òx °þˆéa³¨÷®W (áú{JˆäM‘Ñ"‚‹Òa$y7:V"QP#Nš(l¬„)ɹÐç®o>t¿}N¢{ogƒÓJ“Ÿ‚~Sü®pµhÍð;6.ãG;eè¨ç4qCm Ѻ8$Ú¸¬ÔÁrc³òÐaGž)¢vÅÉ“O‹ýߟºülTTk…(~c^ôÚu¶)–oÁU}w È­ÈNUz믉åw*ZÈŠ³¡ÚÅ "¨Y,Z¤-su—?ws†Î M³UÃRMÓJfÁ×]"]Ûí f±ìÛ]]Åeá3rñ ½VƒÐK1ÅrÖiÐ…½¼L[àíT˜ÛÙUw%¹–ŒxÞ‡ðå^•¶÷Õ¨½¯cIøÕÀE%UÌwuçeä4/„%àPÛÐy„t8¬Ñh Eá]!þ!k—<”Y¹<𡂆§¡»JíËûT&nN }ê°HŽG……ƒLî2q½ônN2~\šÛ¼4ù4Ò…ü;§5œ[¦a˜Â¼;àÃ^ßÁzsA¶È×½ºŨ\g1½ –Ø·™¶ê•Pg$祑á'xT\Ó$Y¦ç<Ï*|¶³—N2fdÉ¿¶;á|GZ'OíÑ´"lf Âm©a•0Ý=–à§Åé)‰ûôØâôˆÓS:=2¿Q(¤Åñ¡(¤[2@²PG‹cD=F-DyY¨¥_È!b…íÂèèw©×…íª²ÅRVb$©q…ÅxEFj9l‘¢×!âŽGK ŠÌ‚5Û¹–»·Û¯JÏ‘=Jþ"˜ó%žF.TÒNKL× zúµ£®ð wƒ7ø{f³ÃØ%n׋zùÙsÿ õ‘òsy(AVƒ©YV©Â4R¯’ÁíÜô%@¬Ð¨£dfÙè?ÓuKÖÉÎõ"¬ww5ïHÝ ×¸áºÇY¹Ë·€z·_Xµ®üPAãkDƒG¢eGß&P …rõÉûŽG6¸ëBùãêÅFqæhXнf@壹D•tÄ.•w‰¹.¡áKV·È‰ÚVçÂþÊ í‚žú,ž²ÔÉÝf¹{(k;}Øb-\‚“ø6ôŸ‘²¿9…~…ì*ãÏ+¦÷ψߔð²})!þpið‡–štIr>pu©+hï :LRš#Ÿ—丣ÂôwP$b¿¬ß†ÒdÌ}Nð1²…ePœ˜ÂGLWèÍÍþ•¤àÁ4y”"¿^ýðƒ4ûá‡þ>Íþ$Û¥É!w>8Q¼\ìC@¸O`o–à¿Þ\‘o·.¸tÞƒ;M2 ¿.è4^ûÈÙ.£<Ȝ̔4]Á\V0÷³tOo.°™;m°\ø&¤sJ?‡áL5ï*æ¬Ä‘WNì|œO ¯Ïb‹œY¹îÌòµƒM~\LйÓb÷iÃn¶NYéÏn¸Ø`®·ß½¨ãéU˜§÷Ï?|+ýýOÉN~Õa©æ _~üpFg˜se³}̶íôÄŽ{1–Xд2´…÷ÜÁÏqz‚;ŸÝó¿uKˆ¶Jºñ ~Ï´Ej2©µƒº¼sB!LKH_¨E‚»‹ÝâR¡GÈka{ONQ˜y½â›:KoŸ1I ÔÚ™ú a=ólD¹ú‹1ð„]7Ÿ(öSâp€CHèvÄ–[χx›ã¾*h2ÙpÐkxÆdof–„þ“e[‘lŲ †Æ•:²êæFZ?ï&hn-kKG&eêü´òtÓMPXŠõfhBuˆ¤:EÑ&­×ëÉf³™DQTCüj`‚ÖïÃ0~ýäêŽ"yjD§i]@â^v°t1?Ø¢9`,þ¥Ã“ÖûE€3Ìǧ‡áAEQ_ÇHx* ’„ƪñ/¸Û”‰´éd¾´°£ÈÓ]¾³ ü$¹ù`@ƒßÜå½ûþûÎG¼ùÞH,ΣZŽ›ºðÃax€©©s8S¸Am=ÖéÛzæÂj#¬6Âjóœ¬6¤ñähœãYmø©F‘Ô—ˆ¼YMNgÑÔ`3U“‰ªzûÒ9'–˜RhUS`Ì0©Æøà’<Ývë.À9C«µb<‹È‡Z!ªç’ÒaÐdEpn½Ë'~š/çOOu¢'h} ¸“%ökVàÉŠR£Á“Ë¿PµK±ÕðráåK\=á#ßi•)S}ÐïBOFÕ“ýÎÖ“)W'¤LgëÑ¡‘i¿ÙzHèœ&'Ahã(X-GÑKµWIeêXˆß—ÎA} ¨1²ƒÎî2×Ò³Þ Uˆ·òàø`¯ì´¯ÑXq±²O üßõDOþWžéà_ ýû_ô6¹Oà›Ó2ê #%f Í‚ø+_Ãëê–i“I5ÀjŒøà ª2²…ÊH¨Œ„ÊH¨Œ„£ïáTF-èFF†ûº Œšª[nÉÁº›]üÔÞA i²F'ÁÁ²WR÷ÙÎV`×Ü`Øå$˜\ê@Л“LÔÁ„âÍØF‹bñjQØp«î,GðPçpN±¢ÌÆBh™F©·°R¶uÃéÍ› e.£}çE‡Az96iÈiž‘~ Â{¯ÆÇ‚zœ‹j¨~ß+ŒN@ç7¨|Î,Ú"t!  ]èB@A@ç'£Ó›‰©ãË µK°ËE?‰šÐÁ—•ÏU=/öœl5¿3l5¤ô#®M&d\¨2_BãR*œÇ€N¼0Yx Õ:(Öé;NF‹ËMz@öäá…Yëm4„7)Ø4Böì Ô9• „¢÷çòÐ’Øj©&h5#=—•hÁiñxÖfŽE]5Õ’mU·Çw‡Ì±¨êŠ­ÉŠ©øCS‰+§hŠªZª©)º)Y¦)óÔ­dÊKž¢a¸BÝæp ,hÃê¯d¡¿ú+¡¿ú+¡¿:œþŠ›h¹½qã›Û' ËC„$U ãhŸ†1³£¼¶yåì¾¢Bža»S$ŠÔ¶›3å4¼Í–·9ö[Æ÷¾ Cip¬Œ‹õƒ¨ ÁìLÄ%¯l‘Z¹¿qeäq ØFWi¦³ÓYÕÁbeùé)Î7B¤Óìj½VÝtXcgb2*§ËµÑGª»=0Œz¼Õ¨á³KpœEœTÆ”³’(èYv!ªúô>¹ ….ª!ŠP§*ã®PXôRa*¢Úû:çcM5Œ‰Q^X”Ó nUf4g~Ëb}Kþ[:O]ñšhY›Éz%࿾O±è)G‡b1kŽ¥¢Ö<=ŠÅ­yz‹\sô(»æé¡·y©øõ’»byõh(ß6…õ-{øoÙ¬oÃË`}Kþ[*G…ùšÒöЊöc·oªMO^Y¨ ®a!To» r%Ô+^dFÜ,›Œ“ÈüüæâO×3ü*‚ ©€ò™æÏoƒ­[åJD»´ 5çûLÁæðHÅd}Kþ[‹ËD¨Toœ²Îëhµð("Ê£w¹°uûËåä£ë,¡G#e.§búÒüdÅÜ@Õ¨•þ NY?Œ6Õù~¿uî|w‰3¢Ö«¯¶`:¦ÚŠ•`IÓY±À,­¡þõ¡üÉò‘ˆ:AÚë–âÊ‹šöˆÒd(ûin¾c©EŠ,xn£ô.YÒÐØó*óìU¤µiUѶåØKÏ¿nÙ$H-k[1Ðñ%[ÊV­Ü“Y¶–eh-VX¯·­þ;¤:×4œ(ÑM ü› wš“ÝÑÁ‚Zçüp=Ÿâ¹,'‚‘JÙ¦ô•·ˆ­N)b«W‹ØêÌ"¶²(b+ŠØŠ"¶¢ˆ­(b{´"¶úQŠØÞCT±¾‡Â÷Pø ßCQÅ6UlO°Š­4Ó%Ù6$KV"›†¤r×umE]Û—S×¶ÓM‰D¥[QéVTº•nE¥Û3¨tËDñw5ïN¤öíc&ÕpOŠRZWõqE}\Q÷y×Çmù'Šâ>ƒ¢¸òéÅÕSWVE aV aUq#QWTÅUqEUÜãTÅF)&êäžMÜ&ô!êäŠ:¹¢NîÀŠ÷g\9w"jéFϺ–®~¤Zº²&4MBÓ$4MBÓ$ü#QLWÓ•Í}Ùåu‡á„^pw˜a¿È¼ýÜëEQ^Q”WåN„ϽL¯~¤2½ºý…è/D!ú Ñ?ez}žezO.0Sî…{O¬po?=„(åûl#ÓŽ\ÜwÀ¨EQîW”ûå~«ÌÒ,Y’ÝRLÓ²UÉ$.˜ î”jꆩ*¶&¦öl‹ûƒhÆ.÷«§Ü¯!ô`B&ô`B&ô`‘(÷ûlÊýž¢ O€ǯ>û’À¤¯±HpS$Õ  έO” æ/\•“¢û»ŒxX7&Ëo”e;ë$Ķ&á ãFÓ/ÁÆÙR¬F&Ä;ÊGÝí×_o.h²`³<Ç*šU‘óèuWZ€´ÂKuµGÕ™¤SÊi€èÒekQ±ƒ8Ê/HΙ2a©®S§U)Á¨ˆ™''VλK‰ 7‚º eœUæh%’q´Yv\ºÞÂTn,H¼Ì’Y5)E(ÂfëÚa¥Óú‚\è¡(g[2UÍ2Ô Zípßu–p§/æT(ºÑ¥—¥ué%ãðøÖÝ4©S7ÃêÔÍî´"ŠÒiI’²Ñ­»Y–D•:-‰ª6/ ­ Ÿjâ×÷§eõ:€‹f¥Úðé}má9o?b=¡&¿½o°‚\b0ZI–€vÂ,Ù)ù t“þ L£kÒ;6ré‹kç `W² 'ü-YѪ€_ÖpSVÅŸŒ«,›Æy–Ûìœ%¬ïJþ´1Á.áØ¡Oÿ¾ â8ؤ¿͇?2¢—ÃÂS£ð¹U&e>\UëÍ+VÓªtgÉéLÞ åJ˜_·I_WFñßüìsí¥µ!ó²?Ÿâ#™ XM^{™7¯=qF%—kj”0IýÂÒåaUíóè4B£5)fyÂÜxDn÷ÜÔåröéÓìéiòñãëͦ°B2©n0”/Ñšý´Ù6Ï‹‡] Tê8 ‰–ñŠ$Ê«Bfn.,IDòT?·J刮ª<ÃFê&Û°lSÜŒFh©L¬‰’É´Í,x1¶%©¶X KÓUÛ¤TÐÌÆF›K#  •>¯"ùšÕâC†9+R«$º¼¼’Í6©xÁ I²$”CÏJ94?¥ÎÀÞeg¡Æ¸/Ô0'¨†Q,¡vj—³T»@´QâS®Ìã“< l“°'¬¤[° ²!ËŒ/‰†ÎSörê÷‹xÛU»eÀ;z‘ÝeÜ,›ˆn„¨ôæâOŸÿt=ÃO ©%ð åCbbbb‰¦ ã¤9ce~tƒCÛ?“Ýã6O4ì\üKÓÕJù«é#M¦pž‰ªh.  è/ :ë:–î^öKŽå ÉUö‡a”±8bŒ£¡®q64Ά6÷d$ÞÙÈ ïtdM£Jþ´]#w>„F-îãß eƻĚ:ã]d]™é¼kb(3cð]¶”™iƒÿx…2“¹÷PRf¶Á³…c}RYf~Ld$^x‹)Š<§!éDbà›÷7;>¸À:o‹*H<–ONxïm£y[C"–Œ>„®;šó: .Oä–"gZ¤+Š»kyv‘ž÷ó #ÒªSüWYcÛ¤ûýúul]ªò÷˜ÊÞ £+xIp“²W–„¶÷¹i{ Š×L'{–zذÂ{¿)Rˆœ¼í>س?Qðy€ct‘M¿D#þïÏ`ÿ$I»„<ÀIV‘:m$ÈâOü ࢆîL m!ðwÔÍjm6.æÝ:*µg¾}]ùB©“·u|KÕZÁ¬TlTÄw êUFvÃU²¨/•f(¾ï\±[æNÀ9ñn!Jü ‘k0ÌÒÉ\4 ØæYÂæ#3Cy”9Ù®ðK”ˆÿ‡@ã"Ê\!µlÍ)‘ìOk:U"ƒ+jö¹Â”60'ä-g1ULª>û—Ða¦TQ`áhlN+Æ*Ît`°I†ä—Ú¹ZVzV…’èS`¾J,]üà¶Ý1³’Ô§iá_”ou£¿+‡Gi9*7¼‚'ÒËq|Ož³îŠ!Y$®;VÊŽ•Ž{‘'i'¾=§ %ŠÞ>!‰Ëx¸# m}ùþÈðæÃå%ć·^ì"+“¢¾,ƽ- #T®#/xãÑyã2º…Wžç?Cîu~ºLh’O:R}Hå…éON :#˜@ø'ð»än¤’‡!s÷ªC±^š å‰Pb°‚xÄîz7Êöob¤oáKtÃÊrôwS’tÎÊ…¶…êd$ÕIeèQ.'£a9ŽF¥h„ɼ’h¶¹ë´é´à\g:§[ËÆÙ”©‰„…Ч j¨Ç)G§ˆ4Ü" ·HÃ-Òp‹4܇ðì¢-~tÂ'\2Â͇-îw;”¦ ¦G(„,.b ÁñwkçXC mîó€~2VàoÇ\¿ðû¬%8ühwAlC«1ˆF]@ŒgÀ¨sGìɲ5ãbT þ¶†D %QQùgk­a‹Q¶™9³[1Èê͇ˆdl“zG#peŸ•EöY¾ì³ú3Ì>Û*õ È¼zš™WŸYzÕê™ÙTq6Õ'Lµ ÅÔtY2ER4=åÏpÙWSÒ-KÑTI2 ݶe"aªe ÿLÍU[W í¹&L-Úuäc¹™Â…L¸ 2áB&\È^¼3r.@ÕÏKƒN£Xœp.ιàå8xúh¬Ùqœ šÒvØuI;TÙ²DÞŽNy;xENûÅÞC:žynyqDÊ‘Dš®ÿà¬JÓw€0±dóƒ-¹X+¾T!íö«ÒóÄ" ¹÷îvy!H•„"N„Ô õ˜©ÑÑŒ©¢5H /,‰@„"$!¼` D}ÆHZQ D ÓÇ›àÁs«²D¹­J‚‚ûâdžq…‡ÈxúÃoÀS¡WìXäò%B¯Á=¼óÝ%á™´ôBœæùÍÅ]¯q}·8vk¸ž¸WóEËì.)p“ȆVݰAi—a•¤lÜníLÁ½qÙó—Pçš,=u–Q~ñŸ¤ZN}üûæ³ðz¤îÒ%‚‰ìc<ùðó¨Ï¾øq šV4Æí0:13,×€ßH}Â0\w³R'Ù0»_èWÆu ΋³]y>hUÄâ±ÏöA,¿ZQhbö †íòS°Lí"½œAé—¨pc:Þ¡‰Ây‹oº¢¨ßþÖ‘K½ÙÇðÎL‘_/e+È%ä]:=²å¾ýîE‡J¨*BŸ!ôBŸ!ô/PŸÁãcª$$¢Xg¹ÆÖ½(%¼FíxŠl¤f, ­¾E„j½»È?PÚ$UÆÈä8œ A R@ÂJ ¸ä‡ŒÍ(õ†‚ 5x™b´®‹Ñ¢éá,àÀ—Áü´V“å‰Ã'êi¯[=âÊ‹šöˆÒä@ô2¹H÷.FËì… µy‘jŸ2ÍR‡CÐ_&…aˆžLÍ¢èEž¡1¡§_mõ²&».ë3ݶmS×-ÝVM¬Ðfj€´DûŒU£==£7€MÎÏ©`<:2) ¯eÞo êÀ‹ê˜–±¹ë aÄÀT¹¦ŒúíæÃíû0 Âßt¥‹Xó§+ŠpÚI,eŽ*|E{åaµ{I0kÒK_ïÞÒù1tÀ±gh¥©&•šeÌ,+Ô$ÒÑ#X3»ŒÎd5‰8cžÔƒøKnÆ_¥ÛE‘§¹ùv®¸èûПÊ\ñÐÊK‰‡¦Zñˆxg¥.‚®è.%Ì“ìÛÏD\ë3Šk¥-B¡SÃBŒæjØ’l’mX¶)+º¢a®&zeIŠdZŠfJ&æjØ–¤ÚŠª–¦«¶i?Ç0Wž1 •$o¡ø˜ë¢Î)Ä®§ûÚIÄq•Ó›¢bzT 1©±†å£îöë¯7<é¸4®.O7Uئëà[˲D þ0'¶\.*QŸn%êf¥ÙÒ}ðî  ³‚€ù\ë]sD°j0‚õ6€UÕE«`¬"€UdÇ>6øpy æ{„Oõv1„·‹ðvÞ.ÂÛE$’I b¾Jj >\ðá‚|¸àÃÇ78ÝÃ5Ç­PZdEmü¡œRðGøÞ²kðGìx>D“ï)<]éÕãD`¾qƨʯJ!%£0y[t*{‡70¸‰7L¤ê7”ùŽ\ÿ´Ù!Þ¾(ñþ-W¥3lÍžÉÃxÀ´Âµì»7Ó›pk£ŸŠÚÀ#ôw‰"Ãv~WÁ?¿°¼^B‹!´B‹ñbµQFHEQæ`Ó´ì”Tí¸fúOþ÷ŒóÄhõ·«wÍ>{.Bï¨&Ïç òà…itìS®Wà@#õ*ÜÎ]@G´Ý…Fóý£Ê8¶iȺ%kŠd“ùþéïîjÞ‘„™kÜpÝöÍ]B½Sû…ÕXëÊ5Mž È Ñ²á»ÃS³ h¡\¡‚Hφî[¡A¿èv„/ÆhGyW%ÕK³G  òÑ\¢’Jb—Ê»Ä\ŒÐÕÇüµ5x  ËLÛ§¯Œn—婨M¨°… [¨°… û¬UØó–¤&ãîsŠOF“P‰3¯5‡‹Ä5›S[›ã_ÅœW€8òʉπõ‰áõ@n‘)gV¦J \ƒ@í`“_#Ót.Á´Ø}Úð›­SVú³.6˜ ê;ž^…yzÿüÃ÷·Òßÿ”àäWÝ–jÎðåÇgt†9W6ÛÇlÛNO.à¸cÉM+C[xÏü§'¸óÙ=/ü[·„h[ ¨ êñL[¤&³‘Z;ب ôñÒt¾„ôõ€j$¸»˜Ñ-.z„lŒÛ{xB4½PߌÐYzûŒÑHLé(¶QÔú=ÏF”ë¿OØ5pcðyÒa?-8¤‚„¦V ¶Üz>ÀÛ÷UA•Ɇƒ^ÃÛ0{#Í ý§¨–&[ºiˆ}¦HÉKÛ ”4v©eµän’fhšÅPËR[ÖïœÉlêÇÌàí®e‘éH©LåŸ6@.ﬡo†F!xÅ`ðòþ•µRÔBÊm`‚Ö(-ÀÓÿ‚Üáàdžß#éÔˆWÓº¤…‘ñ½ì`2SX‡lÑ®0Ôá„mìýÆ‹"ÀafÓãÓçp ¢ñg1$Õ”_pÛ)SÓy„ÒjŽ"ŒwùBÎoðÛŸäÎ…m~ ~s—÷îûï;œëæË"±Ø–zHh9nè–‡Ö9ò¬å7¾þ­&‰°aó6aóõogóá'EZ_¢Fðf5‘8ET[€Íe½Y'– ™Rh•j@)³4LršË&×4…É n·îœ3´Q+ÞÈ£ñˆlp¨â¡z.)MB,äbk’:?Í—ó§§:“ ´¾ìÉ»‘5«ÿdE©ÑÿÉeýŸ2ºþ¯nôHæ‹~6j2ÚXI·÷ dá›<_Óíb§úãŠóñ )µ7ƒcé¢úÊ#\ ·À=Pù\OÕZLÆVôË…‹n”/º…¸,ÛŠd+–mŒ}ïU66M5E¿ Uƒö;[ƒ¦\™*ž­…‡¦®aÜwë!¡³šœ ‘¡µ`_E Ö^ÿ•)|“ÏÂ{v (ÿ$ -Ä]F`™Ýô{YL"Ld½u³[³Fc…j"ÿ»žèÉÿÊ3ü+¡ÿk‚Þ&÷|sºƒCF½¿Ú— >a—éðªÚkÚdRsõGòTÅ,+³[4E¡£25@º­Íª}u<®uÈ êdÛdSï±ÎÆ Ï´v Øål°+u°èÍYQVµ†²Rœ‚Úˆ ¯¨À†[µæÁÑ“ÃÇSÄ\Q°( yfbÓ0V?¶NoÝp ¤&h™çUßyÑaÎBMª"šƒ‡…N8¯ÔX©Ç¹(kõÛø&X¼IÔø›‡Ïɦɸ)Œ›Â¸)Œ›" ípÆM~²‘1:½™˜:¾ ªt»\4ÖxÆ ¾¬|®êy±ç¤Hü¡H$¥q•h2!ãB•ùú#h‡êoá<´òÂd¹¢4Të©S§ï8+1{Äé!Ø¤Í ³Öì>„ëØ4ílïùÅB±Cp¹*HlÕU´ÿêžËÊ ´àás<ëóÊ)Ši«¦i™¦)ƒKe[Ä•ÓuC·ÅÒ U•,S6ˆ+g–¡˜à²Á~¦dê‡ÀNu+™ò›gƒŒ¾R‹k5-5çëjºA’ÄöPœŠÌ²f–·¤WEftÜ`Åöéƒr×b! VÝ­›$Àa,Þìˆõ¼ª‚¾’Bžl·“ǸÔÁ—Óoü|<>–Ç'vÆG¶ C7r¬ülõƒ¨ ¹êÀ%r±H‡ñ(äÊA$-”K½n² ´9u°Xù>zj-!²ËySÈã}t}Z?“S—§Òâô>ô§ê4o dLR‚¼½o’TÂcÕCJ¾’Ö隇€ „œFúâºT"— bú<ͧJ雵pimÈgÕôpÕÏÿJv˜uŸ¯€¦5ÊÝÛG\5B£5)Fb¾7Ñ+€Ë%ÓR4S2 |n¯ÚŠª–¦«¶I)¦6Š‚¡uP‚lÕ­Vù ´š!EÞB¥P‡V-Ô¡1 u¨¢P‡(Ô! uˆB¢PÇÑ uhG)Ô¡©¢P‡ðk~ͯYø5‹B¢PÇIêf:–{e!²iH*í³Z‰b¢˜Ç‹-æ1ÐÝ?DÁQðCü?N¹àä[Bõ§YÞcȱ?“b'N»G-ø!‹‚¢à‡(ø! ~ˆ‚Ï©à‡|:?´#üÐDNa;¶#a;?DÁQðCü?\ðcX5™(ïq6å=šÐ‡(ï!Ê{ˆò«âŸa1a ˆ(ÝñœJw0M|ð†Õ4éBÓ$4MBÓ$4MÂKùpš&QŠé\J1 Ëæ¾ÌÂKÃrÂ+³4ì°_dQ¥¡òEá%QxI^ކ/¯8“v¤âL†Põ€Põ€PˆâL‚¥>ÓâLgà) 8‰N'VÀihí…(òô‚bÞŽTj„IQöI”}eŸ*éÆg†lª¶¬j¦eé²*[dÞlY7t¼7uS×UY:HÕƒyÑ [Ò‰# ­ª—<ÃD%¡<Õ:DµŽÃá¼g_›c””l#Öïhòü?býŽáÝPDµþjˆðåÌòéc¨»¿ ¾WÍj© ¯¾!ÝÀšzådU3 ¤é#xŒÈ7ø7Íêº÷0«:NÿåÊø…¸[箨"ó¶HEÅx»ôBåÜ@¯Ñ3@%ÅÝp/¼ôÈç.)ßLÿRHŽÚlœðr8ÄçµãB>ס­IhШk寭CÅ{ðF³ŒàöFÌvåù MT±¦ýR…“‚Õ³øjE±eÏÀQØ.?ËÔzÖ«Œ ýªîÃŽ¯Ù»`ù4yKÞ§²%û4|Ø›LÉ0,3š~ 6ΖjNn4hÓ¬àc6å£îöë¯74Ëw³õšU×µbÕ¦Claî¦é6ðÖíFs~s7»jÙP]±dŸœåzÞÝ}0óïE ôVxA+öY*õZo^^ºÞÂÔ´\0Š3kµÖdd Ø£[ÀíhÀ®þð)¢qLi%tà¯7ðà£ß¾ë,!yH(c¹—nté…µlm{ɫѮ›&uêftZ ué–ìkÝMï´$ŠÕiIT©Ó’¨jó’̳£Yü«ÙÛ"A%vã<šÈ$»%œ«l‚ÄëÝ`ãÆP~ÀÔ# §¬ÅÔ‡M¦÷¸Ímf³u¢Ú ƒ cž·y͉DŸ¸r®³@Opªå¬†zÆT¡{»±• ”Öðß²XßÒ‡ÿ–^¼í˜Ÿ+_õšŒ8²6“õJRœú>¶è`*-;È’Õ¶‡¦µíaI-{(rÛ‰'4­MË¢¦(¢]$r³)GCþ´)¬oÙÃËf}Ëþ[ë[êðßR³ µH­/lÛC+ÚÝžr=Ë;›]Y(WÕ0bª·]¹‚ŠL™h…›åo“qµÞ\üéz†C!üQ>Óüùm°u«ü€h—¶c¡æ|Ÿ)À©˜¬oiÃKc‰3™ìR”d¨%²SíÈT&–›£¹~1¯ÕÍ~D‚ØäÏÎf÷÷ɇ €õE­j¶ÑÔ6k´¢¤tl,™°OpW(QY¡ZUà¦êÞã+\O,¾¨[L‘,5‘ªÜƒåÚÔ’†¶¨tm§¯=i½lA½ZÔŶAL<šÜ‚õhBL.©±-)s¤ÀíkðâV¦Õ h—²jIƒl±ˆCåŽRuñn1ð^ùÖ ãÅÂÛÔ;™ÙpÚE »q¤2’oW#˜Ú{È«]?è®Á”K¾›™º«MCÐFuÂ}uW§µË©qÁkZ.“Ç­©yJìs‰ŠÑH_…_¡ðA­É;Io[#·¾¬Øìê¬ë]ÿÁ½…3}¨/ÕÀ^a£†Ž×%Ñ‹o`Ž¢I9 e2­~ƒF¢[1Tö»7H?’r³Ù¬Ã\¢˜ŠìiÁtùe1§óîlf‹$H‡æÙÚx»?&¬œ1k¦lÎæ¯æ‚]jÍ.±¬eÇå9„M¥ÚMyzón" ÉJý·›·(ùÐo:®ïöw€|¡¾?]±V1™Â8E{ÌSlnXíñi”ÇàH³&ôÀB,ôÀB|îz`z¬T¹ +Š'dŠŽÐ N†¾fG<3ÛT¨È ©O(<=:ŽJ‘êã¨ð)ÚoŠ_†äÂÛîƒ={‡ ¡Vr=YkbÍgiÛg/àŽ¡á Y¸¾_ pa­¸lìwÁòiš·Ã'ùŠÛKð&±>0†Ý;d-ùJšÌ UÁF¢î%9ôÅu}¤cŸF‹µ¿}îfrËÉ¿‘G°KJ""›þ}Äq°I!Z d´#‡5ÜM6 ˆäÙ+ZÌt~@žEÄÉ™b_£Üë(I¾!ŽHÓ”eüáÕ?H³~øáïÓìO²]êkµóUÒ’ãÉËÅ>GfîR°øõæŠ|»u«â=¸iÊ‘â÷[3×›9Ûe4\¸öq‰G’–i¬áÔY€ï9‹'ŸI6ØG.|{”n$ùÚÊñ#·tSêWÖ¿®µpé:£šj#4Z“+À%À(b\Kð(ÙÓê‘üvÀóYœ€iÍ~ÚìOáÅÃNœ•:N°Çp»ÉH‘{.÷z½žl6›IEµ3¯B¬MxBƒ1(²àù£lkF³:Fpw¶ÃË2§è/}MêqXö7„ì/d!û Ùÿ ²?)‚MpÙ?)!^¢ÄÓÑ h§Dâwæóºõb¿±ºÄ…šÁ6;w%A4ë6õêÙYßfþÏ2tU³,Y·©µèÙ_F•ã?øA^¹»xÝ4…]~ž$M™†×å“· Â[oñíÚÝÞ7Ncðx¼ ÑÀ.‘6ã¼wï—÷nÔy@‡…\ý£_B˜ºaêVŸ]ÑçZ4áò‚ GSŸu‰{”ÜÀ icŒ{ zèüÞ8™¬Ë¶^sRØàÀë+|m¯Ý{w»|í¥ÅU~€«ÿË]Äè#ßß\˜ò,`~]Ë®HR»Æy½&BO s¾O& ¢w[W¹´®z¾®ƒœIöi,®ô¿š7N³4KæÛ·•?¦\¡sz•æØü1ô–?úëZé˜È϶‹šCL 8cˆº/k ¼èNˆW£ð*BˆTN²¢”bŸ‘vÈYzû(M¾§…’fºSÜH²l+’­X¶1hRÐy6DòøPg‚–L[îûïa-(|¸îÖ…ÊDÀbÞz>{º~®hÖbL¥©âaGݺJ ƒë ÝÇ ôþ,•ã#Ü;!Ž6Þ¢óé僘óâCô4½e}o7h2³jQYT¼aUÑóÓ|9z*ÓË8d³|µrQ#ÄT?µ€›³Mï7^ynkΰ#Ï3rFX×ðËêÊ]8ËÊÙÈ=\9» Sòv{`>N6fÑëjŒh…æú›ãû¹pfJ3MÂÿé¶!i†¦‘)ãïîjÞUv¨~Ô I¾È+p±–÷Ñx Ö1æ…I!Ñ…kÎ$“Utú·Ê5ä¿ 6êòªC0½éýùzXÕ£NA60ŒÈ5†‘Ë0Œ`‹FƒeDmmáX>²ÑïÊPÄ¡Ùp`AŽCŒ#´ *&˜j‰K°÷Aø”ìsy<3UYȃ$’½8´òLµdM±Y KÕ:(Wé(Èi˨19¦„åÌÑòø7itFHtÙm±È Ù'çßXóÉ ›%/&ç…™ËíˆÏæ×v®'°éz˜š§NSÀúbrÝÈÓéfrúÜa. x'ƒÍT4;On؇gïo…YBµïûÿÞ#ÖWFäˆÆõ¹Z DÞ€5r ‰¸œ¼ƒºM>zÀ­*mÔG§¦ãFŽ™*¹Y†g9—‡Jæ‡`“ø¡&ZÉà×@)©3Õ©Sd‡U0áåZ,¤‡Äš¬JâZPÐe龇T…©„?P3øT-IS¢jzA‡ªt¨ZE…:ªÊ”g¾®yh×p:K*k‚‰4ôôww5ï*:…ƧǔËnö«•÷½Iæú™ÈÅ …¼ƒ+eU…võ8³•‘_a©û3º[ÝF¯nAØ`KØPP«*µâ]Ÿ"ak/°Hµ Ô ÃÙß®Ò-#mHËÛ“+XÂʹzLD^7rôn8k¦WXÈVÖL¬û=¦u þû ÉO[˜ûÏäˆ#Й8‘¥Ppâ:ýs¢Ì$]§Zbb~ÐEKfoѳƒ çóš1x¼fj@É$Æd×Á‚‹«W׺":séa@ÂÛ-ãSІàZPTßšž(™ `Q8¦Ý`ü€Šaí„ö¯äºMeƒ._ÕYHÖax®Ó`ˆ´Œ'$¶×NSÔè}Tˆ knç9‘àq–$ÜÌÛ„™abªvB¨àS¿Md†¼5vŠvOp2‚P]B"÷Ïm\~ÒuhFÇù ½ÑtÙ4%]Ó$]‘L¸ÿ(Ë€ìOåd00fŧ.ɶ!Y2´l’J(>ïîjÞÑÝÝ*£­8M&”ˆE:ù M °tçA>ñ€›ËÁs|¥ìÿ*s:Ûv@®Ã€tW—©®– G¢#8úh½Zƒƒ&¹†ty.¾9÷nM•RÑŽkw¥w¬‡Eo¸‰æèwhš`U¼FäKÛp¥LâÜ—×àÌn?¨Owèè|Âý{Áô™d+“ߊžr ͱz¨ä† h‰¿wûß*¬²Óm\Õ¬ê˜Éëþ(7®j½ïc;/”-yßñÈ„f‹5ëV4@o†Ù£Pùh°áZìRy—˜ëBº?ÖT3á/ŽÂmX±Ü:ýÚ(íT«Ån¢¢Š¨¨"*ªˆjªg]MuÞ’ÔdÜ}NñE{—ô·Ü«˜ó G^9±ó°>ñPqW´3ËSÅ5,ìךü%n»è¤‚‰²û´ Mh œ²ö¹\tÎ ó<ÿù‡ïo¥¿ÿ)9ÒɯºS-mRçŽ+›íc¶mg")4Ý”ÑÖŠ¶ž;øÉNÏtçÓ|^8ºn q!À AT„úAÌÓÍÕ9h' s„ykèëUMpwyBÕjSR*å@5sôTf¬',¸1ø¼@ ²Ÿ¦‡RSUɧ¶ˆ¶] znàÜ™Šji²¥›¶L¨nïî²Á;4ë ý>Ÿ“{ýŸ ÔÍZ>r]¦éO ©7ÝíçÞBÞ†ÈêÑ& ä ÆÉÿ Å ËbàÖ°.  qS;ј®£ü`‹–†±¸ž ¬eÇL Ù4‚Š  o¬b=¬êjŽ"ŒwùBÎ]ð[¤ä>…m ~s—÷îûï;œëùêë!a¯Ïºåáu€©é´ƒéˆ'£ŠQ6Ñòê ‰ÃQ>TÈ·Z“ýÌ5Íä¨Þw„å… Z¥2Í•×$§¹lònP˜e»u‘¡Õˆz„Ë5‚C­ê}ð.)3ÅF…¥èW¬¸ÔÑŽ7Ñu9‘IQ<”Ëâ¡2ºxX7ú4¯É‰JQ´‘‘°÷ycá’Aªp-ë7$S× Ž%ªô%W\ ?’]–ø|•¸•´>ráZåk]­Äq¼ôD© ñ»°¨ÖïlK¹:iM [Iƒ². âÝU)uÏ>QBYA‘>ŠüÓ^ôÉd}ˆ&ßo—…÷(ðÐpdº ‘ÏôOï'r×òVì•݈5+ü0C üßõDOþWžéà_ ýû_ô6¹sà›ÓrZ=QIcŸˆÐçtxUÅm2©za$ÉDÑÊzŒ¢IQ|è†(•1KûÉ-Ñ¢»ÙÅOíÕ•Më5:Q´ÈV¾§nµT.-T°Ë‰bNêЈôS':l6E¤ØqÛ0ô/Cφ[UÉŸ„ÿ‡ëŽp®§`HbÌÄa”¹u¥î¯‘WèPjž&h™ù¼wÙ]‡™IV¡’¢Ð¡Y‰9¯ÂJYw¨9–«"5õ; M°Òà’qxEÕ,±ð³ŠƒÜﺫ ¥yq‹šá›¹¸Ú®‚ ×ù9Iž¿3$O’¤ŠËEc4X9pJ¤á$ׯA¥*8³˼0YvIª¸âV5YËSö£cé"²—CL>³Û*3„žlê¸Ú7y-E•ÅeÉ’ØR´ËÊ ´`î=ž“yÁTUS ]1-ÍR4Õ”U*æÑUWlM6TE1!:æ©[·”=QDÃ0“C1{¸ÐqhÆŽÛ"£ÛÁ3º:òUäŽ;ùÜq]rP3Í £>HjºYD>»áóÙqÓ«"£9®sûÀâÜ«LzêæFén3 ÛYw`í¯b ÅVMœª«“û Ôÿ‹Ó‰ðT‚–CöÆaª CËq:¹ê‡Uëmß×K”KÀeÙFpAáŠN:Pþ÷á=é´¿šn²Ph\ª&Mk¯ ÏUJÒÑšÅAã7Ç÷Ûœ1‹}Æj@•ÒÌwLß bPý‚! ý‚È/¤~‘1þÅHØœH:¡Å*o~h•’Z­æ‡V™ù¡u‘Zä‡ù¡E~h‘ú@ù¡y‚üÕRF‘ôEçåtx™@E&Е ”y/DÞO‘÷Säýy?EÞÏSÎûYÍÔÁËð:Ëg÷‘>»œž§¹£fð”EO‘ÁSdð\îÁò&÷ä Ï’Ü|îENd‘YäD~q^/-²bˆ È"ò3u‘ùŽE¾ã“ÍwÜÌ‚ŠìÆÏÄkôH¹Œ{{ ‹ÌÅ"s±È\œ^'[7,C15Ó0lE¶m“ˆÜ—t[³5𿺪X–dZ*º/ª!Y†&iª¢ê¦i?»dÆ}0Ͱ©‹y¢šõ’õ\dœ|Þ¼È/)òKŽ…½^P6ÉLãH¹#›<˜;²¯‰MdŠlŸ)R-x„¾ƒ–ý÷Ë{7ê|Óêà9Wn½Øw;&9ä3¬ƒ”"ŠD‡"Ñ¡Htøb¶@ÖˆD¡öW^è¢Ì!(«î¡‡D±þ|tKà”>ióÞ¢ 7X".òGp¤wà^)b¾)MÉý@ ltåîâuçm†}\ ½üÄNE„x³BYy¾ƒïX˜_‚¦–)ø!+øç„å¥bæùƒšÜ@CQígj1Ÿ£œ~¼ÑtÙ4%]Ó$]‘-JÕˈñ­”“¹†ÄшÅ7@îš¼®F¢ÄÕAÁAIJÑÊ¡êoZ&ÏÅÇ ôþ8Ö$B;°PBwïÝí²·v˜ FÖâ1`ˆ53ð–¡«šeÉúA´ íV tH.ºY\o,‘´y¦Ú8×1ãÉ› a”‘åíÚ[|ã“!4H—"k€•Ò CÕE–¥þ“~ë. µ›.Êï ¢Á½ndã-:œ\–ˆ'<Ñ–jµrx¢>~8"[‰¦^Ì}殼ïMØôç`ë–°J»ôÓÜõ§ª¨-tòz%‡ÎÛì7Ø`Ð5»DL! ÉÅš¨j3@â®ý<ôÀKd£Îú]xD³œÔõázˆ´•L;h¢b¦² þŸ¡i²¡¦CÆ»»šwÕ8Ó†q£ëýÅ]ùøÌGHNã lô_ ŒÁ2õK÷ÐbÆ>Qìq™TËn„æøÁ‚pø ðVKºmHØV‹8 Œww5ï*®ý îŠO}1 ¸Ld@&i“•ªèúÊ-Â*¨ŸÅ¶H€ç¿ÀQcUPLZuÈÝTò©—wà>"µÒòw[ ´ºŸÀ6ÁHׇ§9ßôÉ®\&Ék/ƒ%3fc¦,¸ÔkjÒ¾Üü÷Þ ÝÞÔž Zúþ¦%¦IIei„Gj~2¹—¨(ŠˆâhŒâhÍË“HWíîÙ {ql0.{@ºFÔ/LqŸ0büeuå.œeÅ„Krlœr}í”±lE,E‡Y8{ëó[ƒ½rºÝÒó÷+éj’ª^Þõ)5Â|Â/c5¯ÝU ‡õdYépR+án*ûS4f©£‡'œa]ÓüùmâO)ÚÑÛ±Ps¾Ï `TLÖ·´á¿¥±¤™Lvé.ךür­!äÚç®å°ùOƒux8$ðF¡¿7ûعÀ.È~Ï»FíóÊXón=5¥kOC¦öÌ·ô£ë,¡šBn^Ù¾¨¾0Ûa;ýs±['‹c»è!joˆÎoªŠ)Ú¹N›N ìFÞ»`â?è®Á”KÇ-Ó$ÕHÚþ–\¼0›ê(6T–ËëG×paHÇô]à/©5h¨†×!kK-ÃRÛ.>ªÒ“4ñ¶Û¯JÏÙ†Q`:L)RŸ¡Dæ“d0iÇʼn@Â÷ɉùúOÅgðóÊ[­\Èá´³¤6B –ËÏY›ìãôsù¯×€¤CðÑ%.î¿,—ÑÓŸ²¤Ä°é*âjÓè)Ñ4Ýýʇ½- ßŒÓ{ð‚}ôñC»3@ï×¶í߃>¼3„mYS¤|;9ð)¾æ7±ÆíîM ŒUºÉm¦‹Nï|QcÖ„YŸÇ?¡O %-¢Þº\e‰þÓÛ.ÛÅò±A$o®Ùâ£E÷©ÃHònt¬D¢ Ž2/goÖrö²eÞ^ðö‚·¼½àí_oo_Mk”§"d'4Ô!NÐhMŠé 0­Ø†’éJuߦ¦5ûi³4Ê‹‡8*uœ…$=x’G5‹PèÔ°ÕdÎ9]Óa¶¾d–mÊkdn4ôÊ’É´Í”L"–a[’j+3Zš®ÚåªJÇ!Ú\†P>ÉVÝj•¿ÀOËbGDl&ˆ¸“SÂïÔ# ¯gºd0B—dIÄ. "vIÄ.‰Ø%»$b—Dì’hÿ‚b—îŸíÆ…Ð¥?ÿð]‘åïdü’$â—DüÒÙÄ/iü­*’¶¼°p&ƒÿpèBóñÜOƒÅÌNCéþ3Ö¢,z—3Ue‘RLEI8%6j‘ΑoCCCxyCààÇGUŽ'&ônúèÅkD_ÀÔý;€nU€àÏ<¯= ^—ݤ’Y%3¡j|9Ü5 u³aQ^ÓÐæžŒÄ;YáNI‰¾âV>×*3i³ä] ÑŽ³]“’G[“¤ÜuáUœ2´D—7èuíÖ9FjdlýI½!¾î]°|šT¥ r8Ò&œ )þ„æ~_Š­àŠQ«!Uý‹‰Ñé˜O÷ÁïàRßÚmŸPïŒ?¯8ïÓ\ì+.õeŸû..öy®ú’‹|Ñë½Ã<ÓE~~>îWõn1’Ò§[|Á)ÞXöQ'ÒKþêGòQï¯4ž¿°¡ˆ:·äøö×ôHØ6kÜ€m[ßýìQ»@¢;Ù|>»¶>¿FW2(ëm½±.olCxc olá-¼±…76çTBÿAó¿U&]¸ß ÂýV¸ß ÷[á~+Üo…û­h/Üo…û­p¿= ÷[.µÎM9 ƒG.Ý’)tKB·$tK#é–ÕØ€[º^¯'›ÍfE‘P&U™Ôà˜¼ <—§ì,¥amÑYJ{¶ƒú°ŽÅ S†–žWÛÕN¸Ú¼ï|KîÚM°¦÷.OBJÃÚt ”ö‡Úñ¦tÅFCºb]¤+éŠEºb‘®X¤+~!éŠõ“®˜'í¿Ôà–ˆ÷ß]fýêè©ù¼rÏEÖâsÉZ©¦*³Í"cü·åàØì“Þ{Ûˆ|4„hªäÖEL€²÷›â—!#æm÷Á>bòÅľֲ¶¥;TK(‡FUÍOG¿£ýŽÐï<[ýS k5uyZ!Ih…­ÞàU®1¼Ê-áU.`¯ráU.¼Ê…W¹ð*^墽ð*^å«ü$¼ÊÛ;eJ¹>¹žg²PáÁJFSo óÉ:>¸‡„ž˜á»žùªÓå¥iˆ?«ƒý‚5¹"ŒèsóáöºÖ½sÀ­_BoR¨}*ø”wõ±µY7,CUdE·tM³ [[Åÿ™ªdØ&hCøØÚš,›†fj’­©¶d™U3ǨA“+¼‚0]RÅM¶;P]4"@#>Û3oócìwÞöþKð¨ôú¾Qý~3lÐö#2™\"Íøwç:qÔ9â  hBŒ©²„ ¦¡e>GüÉÞÅ8ÿé.ÀÿV'ú€ž3—‘è6•« Éù‘r0ò^[*±FÂ\Ý{¤jÒX‹}¾ê¿‘·ÿ€l†Ü+Ê¥ãüH¹\Ò`¿›Î¾Ä ‡h†8„ÐÓ˜œÂC”"rú£Ìçà_¼o.B÷¢zÌñøƒG §î¢·e’X¾_z!˜¯lóÄØ·Ê‰cg±†ŠAÜ ):Ü%jBþ]•Ðû 2ØÁü‰‰Ñu·v¦ñ:t£uà/ Œ:CÚÚô¹fÝ¢7Ü A ²ÝõWEàä« ×Qm>ø‚•zíˆ^Kz$榼ÝÇÁ7òþp;SˆŒïCÔ€2Ã];^¶úŠWáThPʇ rC9…ušë>À8mò’Ž´ÜrPʃj“ÒrLÒc²Æ$5‰—Úi è ‡V¢Y/¼&ÕíðâF×Áâ[FÅðH ±Êñ¡É0­Ó¡ê *†A¤TŽŠ[ì‚ȃ½ùÞ¨É|‚ÚÈŒ×KUYXÚ Ê„g ©³ß…üi M‹.¹f˜ KNoQ^r)[p©i¹kæ@¥-j/º¥ÖÒ-ì!»¯2£´ïBËÿOÑ•í|çÉ]¶bHÕ 4Â,Ч[….ø6Øl˜Ú€‡ø0°±r¯C£Ô¹‰Å,»A[ö:ØU¬2ÐHL6Þªûox6³t“\VMè~ÀÆD/Vš`Îsže.±¢ºd>GZnkøUXZÓ8²ºj\™7,‘yCdÞ™7DV×—˜ˆcÞ÷V¥ûȾ,³ÌOÐçW°~ñdžÀÁÕ( jÌOEGÝl ÷¬™Í 9þÚÙs®Å~fñlW‹³”9¤XÏ4{Ü®¤e?§ô¥©²¦˜ši™¶¤(ÎPuÅÖdÕV-]ØÌ&Pœ {©&x/éšÔ ¸RÅÎ~ìÒ@9d(W”^÷˜Ò°¶ê1ÿÝïUÈ´ç®#ã·bÚ:ÜbU·È]Ï5]–-šºµ‚õ[MÌæ¶lª’fÛ*k×GÜ%‹w—L±KÇÛ%•w—±KÇÛ%“w— ±KÇÛ%ƒw—t±KÇÛ%…w—äSÞ¥$ÑÄbóô­²E‹ŒUÞ­+è¯oh#ÀâÃÿK÷0uÔ?èFÈïN؃ìÄéŸúÖçã Ù,i{¨ón¡&PÞ@(ol·XÀgmÑ‚’*”²aõ^žFd¦×êDzÛbÇóqX-¥æyµßH*Š"(ülí:Ë.#.õ+Ýß–Ê%åy(—:Üҵƫ‚Ÿ”säAÕ¹_dd"²/•u)¶ °AjAûíó nrS[± æùäD`Ž`|ÍgðóÊ[­\ø­vÆÓFHÁrù9k“}|ƒ~N".¾4ù)è7Åï.`3œ¸ŸÞ ¿Ë.iåƒîƒ»í4Ø‘g¨]q”o&½àSl8»‰0ng>®±J׿õ4QÏ)lË3Y¢uqÊ´xÛµzñç°ºÁ>úø¡Ýé¢wÏÏܵ»Š¿@j?5a¹á׫¬üzÛe;—b6ˆîb€y7:B"qWêkeò¶6»‘HnÔ)¹%OÌׯdô]ë”GÌô‡³©'‘ͨMW‘ž¨}z"”Èög÷¥²ý|óé–?CÑüH ‡dI$ªã jÍO=o•pêíËp(œe8äs(Ñbj|YW ߉"‚þ¢wDÂ_. ¡ÂÁbZ¦Õõó9yŠHÔ{¬Q@'¥"#3Z´"õœDµ{¦n.ú™Ì$Ÿ¨c¡½nIrˆ+/jZNJ“Që„%ÉåÖBÐÚR^¤~Ι]ZÓ 9€ÒbåýMÏÇ `Ãó3ò|˜‚ùai{J(™7r2tCî=I² ‚c~ãZêAŠýÚÒ†ú®0ËZy¬0Dµ²²Ñ¦²EËŸvô—;ßûï½ËS¦‚+/R¬¢ÛcV¤ ËÏ®bk\O%tõU(˜ç^n–zHÒB£g&¯L»Ô±ÈéC »™Åv-N´p…ê™yºŠÞ Ø›¥e)SUL1Ú)«ˆ>%ãH¥&œâz™ èú˂Λ¬¼>Ñ6—WƒÑ´8³o×4Ô5ΆÅôÜ5 mîÉH¼³‘Þé”2|¯¸3c×fZî³¢aÛ†M©’GÉ)k¤åÇ8“=pÚÔhÎÀ6¯3°%œ‡pÆâpflq¶©§UT‰Õ®®w9½ÆR L Þ¥ …èn–V´ÃZ°BÜø¡b‡»ÞÁᓲô}%½ÃÖaWºi”æ4åßD­º‰óA†Ôö4éâ4Êij»u†ØºsÝ:Slݹn%¶î\·Î[w¦[§HbëNŒé½ –Oüû'Ÿ¿«(â w ÆÓRátÂV*ƒß‹»VcFíT¶¬KAQZ,:¡Òe£Wªe%O¬¬ä8¾,šƒG©LÅR˜pÖ]­~µìu էů— ¤±ØXŠáºËç=Y_îu°œvsNqÿEYÙª ÚõÕ£!‹3Û]Š3«ÃK¸ú£Ý¥ú£2ü·”KóÚÍ¥yßùÒøÎÁÊÂÛõeáy¸œJ5ÒzY˜*ý¢* 7µNªÝ P´Ð´ÓUN}Aûê]«v5O§áh©Ñ:M´M=°…8¹çÚÞò©è=&|V…>O¥ È ¥°¹_-¬cUó=~…ËáðL;ctºo|»9|ÝXyˆÂ±CÒ¯¶„Ëì¸ÜíHÖpóˈV»iZ½ÈVï*ãî¡°ÈØÔDlôdô£n·*l‹çjVe±uãm]5Œ¾¸yåØy£¨µ.)àMf6,l¸YJ•èIÜ¢ãžKae>[”"Ü«Ïvë4±u§Á·©áÛ„ëúÙÞTáº~¶['\×Oˆå¶êYî:wº›–^{:Ó#ÆèçÓÓ”vN®)²53…wŠðNÞ)Â;å˜Þ)ÖLø¦ß”¾)Õ¬x嘬ì 53(µ75/c9bs:ZYIºþ“mÉT5ËP/hÙ[ü¤ÎÊÅœ E1g "™†b«¶¦w‚¢]zYZ—^rVe«]7MêÔͰ:u³;­ˆ¢tZ’„EhÝÍê´$ªÔiITµyIh©”ODõ-âcG”vTÎÆ!Pµ_ˆC &½0‡@M§ì8N@°¦ôºÏÂÕð] 5õ´\ GÌߤi=Žïyx2jú‹ðdÔŒgìɨ c͹ÚÙ4!G†3ƒ&Sœšú(‡p€Ð„Ÿòùg‚ԥɌ£ _Ús¥ºp7=zR#›éa ÷‘¹CøFßá!2wˆö/#sǸüžˆQ9[V]ĨœíÖ‰x“³Ý:orÊTÕ>„bTf³½©Âìq¶['Ìçºu†Hr¶['Ì6g»uÂl3âÖ žv]–˜†œíýÞ¹wÓ]ò¶÷þóÍ…»ýúëM®R"{1Xö³)©[¤ˆ>­³»²,,”ŽŽYÕ—Z¦µÐ þ¸„G‘yn—pÛœY™Rù³ð™ý\b˜GŸk_²&¢÷fŒ‹^„–ðl)ƒÐžO’}À$ i†3Š%ÜD–áI < „'Ȳ Ú‹, uYt‘eAdYYžm–Cø"œ­l/|Îvë„_ÁÙnð+8Û­~çºu¦ð+8Û­~g»u¯àèá ÓŽc ;ްã;ްã;ްãˆö"t†Oxz-¯.<½Îvë„ fL1Ëy öLA ½L¶(Ù¾’À…Z4:nÃFŸœðÞÛFÉ´–Kì¾ý:véì¡qˆ 3l“64ÍV K5Mw*!åõ]ÇÁ&mz÷kvûŒ”¾Í !ù"à< ÃÔÙ¢"a˜:Û­†©³Ý:a˜:×­³„aê`¡wöAê[¢u¶×UX´Îvë„nêl·Nè¦Îvë„nêl·N¨aÎvë„æ0ašHAj|­lðí"½õúHoÖÍŒvÎÂ}»Š“ˆªC¦N5d–ú£ŸïÜUº=à¥N#`Åj®³ÅjBÍu®[g 5× å1ë© ‹yàˆ½Õf²fƒÿ ÙÒUI1›£fi¡-â‹ þøbF* Ͻd³Ú›DwnJ6|Ž+¥cŽ+YjHru©¢l¡=[/T£g»uB5zVùÕ®DÀ:hQ¼ÙÖøë"rë-XãH_¡õÞe;i]ýˆÛáï+,)#= ì` }× iå<¶?ïîf?µ:ïÄlÝï°‰ãC¿æßÂd5Ò‡Óü5}ÑÜÁ¿x¡ß\„î=<h+?pbo{NÝ­sç»KpPÂ=šÓko V²Þ.½ì¼€µC.m˜©Œcg±ÞÀíFÝðD«é.)MT)(ݱ×ä÷–òG€S‹7ס­ 1Y¨ê"Ð/KáH¶.תÂþl üY¡{m¤¼¶'Âò 3ÃÙòÂÌpVˆ„…÷ï©›g(åggãÎOœŸlwL­©lm ö¹¢:YìóÑ`[g¤ÁV{k°kó?¬üŠ$ò?ˆrà"ùƒHþ ’?ˆrà¢ýËKã=’CÖñFí”þ²$ŸˆŒ&KÂŽy¾Bš0džO¹"»]¹¢?›â§3Ž&êˆ:¢NÁ™Õ)%Cv¾d]¬Ofï2î¾å'Ãß £åù"¼s¾{'ŒŸg»w²0~žïÞ‰ŠÓˆÖáÛ)ËB}y¾WU¨/Ïwï„~á|÷NèÎwï„ûøùîPÅ¢>TƒåÌ: _*T7ç{O…êæ4DH%üð¡!FCŒÙ¼E0Çð£3kFW W™ŸJà‰¬½ÙÙ"=EèÍN)3·}.EÚ³ó½°B{v¾{'´g#î]º;œ›GÝ®[˜”#-’ÀÜ«+ âC€9¼C‡€Øç¶;P+±ý¹Ò9ÝNæ­ÇŸ·þˆ\bÞË'ž¹6¤žðóòxš¿Pn{ãB;Ðt˜åO¼~¢j‹0:íç,ʾ—®ïW.ÀSæúg]¦kí™€Ë /¿ÙöóÔÁ®^¾ãØâ굉çPÌ^ç ÃV½ÖY«®3fyŒ}OšYýxàâ(@56cš—´Ži‹.±Ö£à'8M+cÑV¦5h(Ðs’I˜ß 3> õ@ƒ"‚5v2Ûw¢~hžSh¤ÏW^é ô¢¾-…{1 ݕ© Ì4j. L”Õ* áDYT¡S>[´¥ òùîP ŸïÞ ÕðÙ$ïbVG=dò®n1èzŸZ­¤ªÃø’«B+¾(Oø´Æg‡’}½¬“HŸf|Îøå¥{ Ñ×&Ë,±s–Ko{Ïtr!†vˆc&ÜoÏE÷ÛóÝ;¡¼<ß½ÊËí]“¡á å6`æ"±ßç"}*g”:Z»ø¡9”@;Â¥ªÔ³%€šP¥ž@ÜWs¾¦†` uíùÞm¡3<ß½:ÃLR¯)N\®H¼¬÷« áùâ¡ <ß½ ÂóÝ;¡ < :¬éd$)›q;Å”^¯˜R›càOD5£ }çÙ¢]¨ÕNHWÝ€X¢¶“z °Ç UqLt;L"…cæ`È"Õ&Ÿµt»|oëN×®w¿Ž¡yã‚gƒ—OSRisóð·§ýV<ö”‹DŽKwE%cÝx¾°ò|¿ÇY³³ ggA.ž…9ùÚ¨/¡¶‰‚d¹nºÀŒT9Ùâš }ïù2 Bß{¾{'ô½'"gf1¾Î6Øâ.È)Àÿ^».fæÀ2-¦îöPf8_ÿõ2tajŽýÚ8Ì©4½ƒý=‰Àg<3k7·@^‹‘¼Š’¬ðÍιwÁ'ŒñÂ%OÁ¸„Ë瘀`Ò¤üžH€>'úû@x ]8ÖíÏìÎY|£¾›Ó¦…—æ?/-Ðê5NdAþ ^8à$Àúýƒ»ÅAÖ?Á«æ­¼ôìÆîwèÚ†]…oÞvùæƒ"VíXuEnnò—é‰E!ã„å$Á޳L=GòŽóÒÈð<*ê\K{? –Ë)9‰Úi„’Ühj 1{oA¯g0°@©Çóq–Äg€MÎwë‘¿Ð]óg8[âR€}Ö·š˜ì/Ëåó™ê¼„¹qJòï†kŒµ€wpk¨9‰šV¤Fíœm©e9ªtñÀ%EOÛxíF^4YÛ8ô£Ø)Òuá&ÓÉg85ÌäÜ»y¼ûëÇß»ŒÏÿ1Ï^#Ú^z‹É4PÂípî^f®mGì ¹+òv¥ˆ0pÂsF|S…Üݳžk ‰÷Î{g‰>[;/Ñ:ú ¤Þ(²ôõV ߉¢7ùÇRCÞ´š&òmönš˜Ó^Þv ÷n°qãð -š÷‡]‹o.„î]ÜgëÄûÐñaFoô…Ç7š¥Î4I’M“5ÉPûÔ;¤ù£vÍwAäÁ«‚^|Ï Oð¯d·Ò¡–DßB2-Š|O$̔˂oÞ{,]??Ê¿ná¿Ë êŒVÝkòVUlëÃå¥u¥éÚ¥¡½S®Ó0 C–Õ÷Ö{¬àô$MÓQª÷€“ ~åÇIëÊ*˜¿˜zÑôÁ‹¼;x˜WŽá± ©ÚÛÞOÝ-ß’|G|zº ƒ?Ü-åmò©RƒNˉ†ã-!ð`uɼÀG"â'ž5ÖK­½%À Y©ø°°>‹y“#ÝVAÇL‹Ô‚ .î®Jºlꦅ?¿ÓrÃÐ]NëÛ­¼8†Ëœ´2¬™*KºfX¦ž .×wÑ *òL…€ YRuY7úíJ°‹_ç RTžÂ± ›ÆC(ú% §)¼”àc’š†ûí$>ê‹›Þ¿t[t Eš‰¢{^#V$ ÕIŸï#JóÀä~SÕ±¦ôÌ'Õqdóš½GÀª:8tbÁ+Œã¢]:Ÿ¥éÌç!¹è‹ û{ãl÷Žïãc—’”døpHXtBïÀ¨7[¥í±U:lÿ¹mÙ²ª€å `¥ï…h?e]iƆÙuÆóÚcSÈ9±ûp‘Pq¶bÚFˆàmãm< ufB_ Ý:¦+X«4†’Wþ4.þñ9 þ Ö`‰÷k.1~ržŒ½Î'´Êv‚n´_Äó¬Ï¼´(óä¤$Ó ãìi´s“ô ÙWàod¹*^Õ¬÷Êó!ìÆ¹÷¤°!ð#Ó"¾Iº'_Ç¿ð÷ ]Wõñ,‹3Ðßܧ 5ò·œÇlf#Êý(Á1¼g·Ãé9àÃ0¿>:á<úš¿š—9À⣌K.s§º–±§V›™sâ#ñðòxxÅRf²mÛ–lX¶¦«²ÒЧgv?¯ôäñ5U}/óøVÒ$íRyÿîÒ6 ð|,ýƒ‘`Ë—Ãã+T_5ŠL¾Vdòí¡™|­ŽÉ·í™Â½mÍR4ENHm…Çf´+ñت43tEÕT‚Ç·ky|YQÐMd]Ñ-Ó²YB½]YÈ0g†¦@Dá€n0¾˜¼(}ŸÐ%ÕNo-Ï'$}¦J‚½]uŽ(.¿ºÈ]E½-oh·f” k$FIæg”ZN˜öd¥YíÀÍÊUÀj°ÖÁiŸ²ÈZp‡h˜¨§Y¯@î‹mSÙ¨î~Ý0ª€Í `«ÃZè”í³*í¾ÂHû;¦j#Ý1EëŽÑ ƒÜ1Y’Fºd†=Ò%³Œ‘î˜>Ö“um¬KF;rÃ\2¥ß%³ì±$~y¬KfŒuÇu¤;fË#Ý1CéŽÉš9Ú%SG»d£Q2µß%“Õ±ôj¶1»¨uÍ4{¤k&ËÚX´l´{&vϤ±î™9-Óz^3Yéš™úH׌f爘uËlu4©l¤KfècÝ1{¤+FÛ<¾+ÖÖügbþÓóŸVkþc|[Uf6©“ ÆX ÅØÄØÄØÄØŽ>¶Žî ²ÔV‡­µf—ì±ÜÔÑtØš<»¤ò+±ûhAÛïÒh¢£>–èh'9cm’Òo“de,ÉÖFÚ%Ck—ô±6Ií¹Iª2–ÑNM #i#m“©ŽµMZÏm¢)x‡q»KŠ×­Ñî’2Ö.é}1ÞXpKk—Ì‘vI‘ÆÚ$£'ï0š—‚6š Uë.™ÖX»dö½Jcºí±vÉ‹*É£m’Õo“4{´«4¾m“ôўݗw*%Ó£YôÎŒøÐ>÷Š…Ý(µñ}îaÒÕ¾®öìØ=qÇ$æ1èèÝãùg¹ Ý(m¦Ž]>屦gámïGŸˆ¡'®£cM$v}w·¶î|å|1‚#½ JštŒæèrB}ÄÜÄÜÄÜÄÜÄÜžéÜD´á‘¢ ¡»ù¡Â •Áà U~¥Z¶¡YVTá$ +iHc‡ƒ„ª=C ßIoõ÷ú{õòRñ—o-Õ”5Ó|gÙï.ß™W/,¤P¥†ÊRmÞýàyC ©9m£]9ÞNŸ™– -î¦7ä ‘f&Œ¡5M[±³„#”¼!Ôv̼!úAó†èíó†ŒeTUG‹MPGÓ¹IÊHþœ&pBχöÛ?¢¹ÖÍz1–´ý4Óõ0Û¯ôÛ~X¡}¤ý—ÆRæšcÅ&ÑÂq†‰™ÐÔ®ûßÖÕX?r¦!ñí¢{¤Êr‡T©ßVì3›wG×K㙥¤±¬‰&?e;lf)YVÇÂæ²2Öœ•~s¶Æb`h!”ÃÌXí™?l4–M-ešÖsÊòhSÖÇš²Þ÷.5gKê:å¡MÖš=‚´tˆ4q—Á´{:h†¸Æù멚‚2%-Q4Ô üvåðYòšÏ€5Ó Å*ØÉÇ]ƒØ‹ýã,Â*ËãÅvPKG"qå_ŽšdÜöEÛµŠ¼{¤Yë:Ü…´Lüõ€)ú̶ U±qÀ®œXd¡|v!M2­ÌÅ0 ]]%ï«éä7`œ‚QˆeþÁIgõF•)ÖÚûîÆt㽋¹ú¿Ï"¯+öÇ0©À·sâ5ê ÿxsñi"«öLVTÅÔMݰTÝÖ&¦¬ÏtCSmE²l &µ›\OdMšé’¢˜ª®Ûº)©2j§Ø†dɺ†•õ¨6“uÓ¶l]’m˜-´Sg’¬hº,›rÚʘ©ºfØ’žäÕ›˜’=3%M“ Sµ˜.µ3g’eØŠ­*²ãA;€r’D‹äaê3U3MÙT,dÀH¿f(*³! @ÿh§ÌlC…O5ƒ9&Ôgº¥›dÄØµ™ˆˆ©ƒ%Bù@'†aÎl0<]—ÌläÒÌ4T ¬…fJh½ p$ª¢¨–i •AíT¾Z Fn 1'OtFÇþÎÜÁb¼pâ|^M` ûtèPfÁ˜áÈB÷¿÷n”/"œ/Xžð!¼g™X=›|q%ž\^0oázïûpD°N0j$—Yëjâ3Æu>i¥ñ]) }/ŠIl¹}A{OÝÓ ¯`O–î«Ip‡)þ(Öb ö3üW“ÈÙì|ð0‘5À Sz+(7€¯&ØFõj² {¸ŽÉcxÃÁG°Kavª&€ÄøDû»Çnº¿“Ë7ü5ú[õN€#›%•'f“¶»b÷Þ”«ÿ›ˆ?ØÀ\TˆÀR<¡¿|„§qìžð}Eë”ýD8&YXŒB÷ì~ˆŸ¼‚§¾‚}^z%rÕïx«N† 6ˆé`§|k·c\Fko‡±_²õ˜ï:€Ší!FC=Ñå…h)'`7ëôàøÞ.˜»ZAbøàÂ÷û­ ÆÂ…bþ« 1gôí†;7FÇÚ C÷!Xà°Xºû}áï#ðU¾£ðÍtfyþ ƒ'ÇŸ¦+€X^OÂ… ½<É`sÝm„ЛûÝ øÛØ,AÞÛ˯ƒˆ<#³É-DTÞ|Ü °$„“`‡o\||Xp­² ¤ ®¯›ÂGëè…-‚óÀ:6>Øß¯'›½{à–O|÷Á4 àõ‹–_dü@…`ÅîæŒþ~„#Øò¬%dð”p†`§ û2@[f{WÜ9*­w@› ã ´QŸ\|lA»`ë&Í6Î7-°ÃÞƒƒ$8>ßàÛÊGðžÂ¾ë é Ÿ”ûþìË(–îß0ɽ+~ͼÔÿ¼¶ þDóÛ1¼ù€ëAhuq9=á4 €! ŠÁ.¼B§p®rÝF+°‡î™ãGlúSB!À&;¡/8’¬“aÙtõÀª ÑÜGHÀ¼øï¨×9-ËÖõ¦Â·ÞxH–ûñî`A"€ëÐô ÓÅÔŽ  Výy‚'#t:cpH·Ñ^BŠ06\%LÎ>BÔe I5!T¶ààLKÎÛTÓxÀ!BÄ.%8FˆÉn)Ī)‚ °¦ˆN'ýs2ôt2LÞóKö{iÀ+pš\„é_Á#8q ‚¥Nˆh?úémvAc „Žé#¼ï)š£àp™ñÑÃM½}DºÐÀSÝy[L^@7²„ïÑÀï«„¨…„@ì„âà1@”ÈÍdb0èG S¬)£z77“^ µ2Ü–™²#±b‡—‹”Ž÷ûï w©z¦èp„Cÿ溻œK~…= k •¯àÍ&“Ûu¾à)v"QLÊpZÀÌ"&Kp–Q_Tל]â™E@_MÀÆm!󇕰1SÐëàÛdç;@èN4 àX ÊÇ2›¼«x)\Ä NœÇó!.Lfo`ŽqSµËFÕÖ`P^Œ|¸ù0ùëˆ!o‚Uügÿ*]ÐeÿÆËH˜.i÷ú§—"¿.é=ô GòïGXŒv³^GB !aÔî vHy±oÛàÑw—÷îäÁ |xïJ¼È_¢‚nÍ¥»qÂoÑ«”ãy•#à:=ìqøf½5ß î»³‘w¡‹ô, Jµ¾T\“êÞäÎ`5î_’KÔ¸^ª§ûÛá™\suiFR)ú ¶p›k(}çÑãÀýá†>ØâG¯€ÿà+Ðdî¡ë}.ªB»Á ,v÷ì92Y2—1K.³ä“2f©ºm±ìYÍ{Ûb{"£Í—>û®¹¹’šTM#±0ckâÝû@~s4±µäòë^$01Úå¶RVTrÁ­©6Z~^\ÉC­_É€‰Õ9-«|ìeý…DÕ”%…¸²­9s™ÛRã]„»,cM¶kB̳?Bÿéo‡__¥çú2lÁí{pÒ”p0ÊE#‘"È!ÎŒ†H/ØÈ€¤@|ç uÿ+³äÎú¿±D펹ÅïSÐÆ¸Z[V{àÔ>Sw è~©õn­óƒ ^áqï˜L+v‹;€L–¯¼ÙoI5y›ù„`ôäúÀ¨SÃ5”˜9v™IÊ—¡‹~l6Ð* 6!§7kÈ@¿EDHI“_·Põz_'²xïi¦íÛd ŽÄ›‹uï^Ïç‹d@ <žYÞÏ“QGó»§iäÌÁPæÜ« _ü£äÒ\à ÷ØÍ(™2öC¢ºâ£ŸØuì7ç¿~§9xœ‚C´òîê' ¦Bý ÌF\mÛaO¨-ôñ/àÄŽÂàöD¶ úp¹Ð‰m¢è†4‘5Ùš ¦÷{ ÁPÒÈø KŽÝáå*!îžzéÞ²“oØÅMáŠç’¤ê€6-%UÍ›/ÒUO›«¸¹,ÛŠ}oBsH§ë[Æëýæn GšûÅ—‘ÏÓcLiìEøþÊxeGÃÖ‘ + òHÆþ}°ë§;ýCwÓâr «xë·Ï7É++uð+B˜¿0/o-åQ„Ÿ¥WöÿãÿPK>\1AiH à image.pngPK>\1Aװ޲ÆÆ?thumbs/PageCapThumbV2-1.tiffPK>\1AÿrÌŽ/¼/¼?&QuickLook/Thumbnail.jpgPK>\1A§"O6é6é£âQuickLook/Preview.pdfPK>\1A4.¸õèè ÌbuildVersionHistory.plistPK>\1AL9"ô|¶t +Íindex.xmlPK‡ZJlibsynthesis-3.4.0.47.1/libsynthesis_contributor_agreement.pdf000066400000000000000000001667311226375725500245560ustar00rootroot00000000000000%PDF-1.3 %Äåòåë§ó ÐÄÆ 4 0 obj << /Length 5 0 R /Filter /FlateDecode >> stream xµ\Ë’ã¶Ýó+° U¥‘õV+YÅ.'ålǪòÂ…{dIöÌÎhlùü[ù–\ð✠hJê©T/È&‹û~Ô{÷­{ïÆò·œLÝj=uÍOî{W¹/¾ú0q¯?¸‰ûðZÞú7ï8æm{7voÛ™oÝÁíŠÆx SÔ¯7ö€ß |ûÊ_ü¯ß¹/7Åä!<}p“Õt4›®&n¹t›wî‹Íf2ˬÍÎýàÊ·7M]ùs¸> Ü«öÁ½)Ês…G¸û)Œƒl:¸×aHmÓ›A‘_ë¸ëf V®t?îyåp}÷S€d°î?nó÷õ¦GŽ'.âÉ|¶-WÓµò¤žLÁ“Ò Üæ—~@ÓÀÜ©›?óÖÂÌ–±³Ñ¸c7þ&kðÀ} Cð ywÉÖB˜žÔ™Ójw®OMÄhÀk(ÌýVW®Þ9¬èED°8•"Bcܱ©·'ˆ ]Ýø¿tHµaª®þ:P‹­ŸÛEµÂr{ötv'à ª­HòºRtd9/2ÂÜb1 Ú!PŒ¡[÷„Û·à>‰tåŸ@p/{Ô:9öq0Pž D+ WSô5Ñùêc…é3®xnâR|N`2za• °8;ªâþ€‡ÄÙ«¯Û7%È(ð€pQÖ«¸ƒÇ’&Àóù˜h*Wä^´Ò‰¯V·lx2Y›Ü鿃ŒÎÄŽ\ü0(ÔS‚›FØÀ-æÞ‡ýÓÿŽ›Ç1?L°PSs92ð‰…P¶‰q(‹#8ƒ¸ˆêȹov†H‡q@7a„iâ]pËœ<CP]DvÞá¡-«?âUu¸å|´våP° À@&ñÇ:RGÃ]ã}ìŠ|Mõc6ËèíYÉ.NÁhÒ†äKMékÒš¡bÈp¦µ#ðžŠ׿;ÇIMÍ{]aëƒ+G^¼A‹}¼p%ZµrOõI N<0¬7²IDóuU}P”™2tÿ…¥€a¸R³ªt)7(îwôóUF `Vµ«‰8 ÁjQlòèý T’¨)^\Äc¿ú²]˜)®ôÖâClc=ã}~NÄiäþµA–2<A…TòP:€ º¹,ÀÅw'×Hý„¹…V0ÝW@­Ú^Á—«‚é˜zòr"€nOê–’0/ÜdéÄ熒Ö1"lB¢šSAõÆœZ¯4%=³¹uP]W樺Œ›+J­:ƒ•®”´X™o¥‡ºúIó2‹˜]ÏN£WÆ(Ì:˜s®kÈ}hx}ň,‡Q>pUGð$É5Ô„ðÜ£ÿÀ ¬ sÄÀºÆqà™B*ŽA-|¶ßU P„Õª$Cºm œN®T%õóÁÙ[ɆñZ„]c5Ñ'ËÊ0 Ã0‹Z‡‘;Öô6Iµi8ßžž€;PÃx\±X7*(4÷U¯ÔÍcɵ$Y¢²ò¡.[”©ç³…ïóA®ëE×mHy¥ð‰ËÁ5]Eáþ…ä°¯ôQˆ£kjX|¹‰Õ°-9§“¨L NnzÕÉQÖ«TgàÕߜȒÀve|@Ä+LJ‰)‚/dKë-S¦ºQí+Ê-Ÿa=ŠÝüÏñLíÍÔâË|%¬:VgÇ «¥±ìf¡XHªÅ߆d†P$P3ˆíˆÃÀƒPÝ%`dr¥6m”ïSß´| ‚”fF'ê‰ AØ36§ì2”þŒ ¬í0Ź\Jb>Ï»öSþqOÔ]-FsÅÈ`/Å祴-r]’NŒ|ç ˆÚ#]씓hHÔHœkE4„Ë tô…¸Z°¨Ä›óðK¿aÈ’Á)â ë#<°ØÉΊUºD*ܘÂî+xéh-E–ÊÆÙÞtèçTc„Y]6œû ŒàÍv8ð±…”í÷e檋Ó&^HØڵ¥+w ÚæOà)= åºÏñ1#@ÑH‹a[e•з0D¬é:S¾£ ó¢Ëlx‡™’7(, `Þ¡¡æb&|«ºzR€jX%LêO‹Rÿ£2[M32£_‡¯w¾^ ¥¯ºª~Di Ú1³á7tM}áJù×ó«Ùd²;U|H=ÇVti…é[®W@#,<àIPïtðè7ÜPéŽ(a5 £ØßO“JjàÁ2;}Umù@ItîÍLT°Í-›šƒ?’\Ñ'RCŒÌçBzÒèl\}Ä¿ ÞWZ¾QG£Íq£êÈÕÒšàt€Øû¬À]ÉÕˆ4&É¡cåíúØ‚aª”¥#%±‘®€²ûŠ—X?…thêÓþÀ²%;8IÖ›²>ã"fãqÆE@Ø@’¾Z_Dy¦ï’„S$"eÁ5YK >äÊ(àò3 ;­ßjO“m¬¡MÕ•3s€JQþ¡á™×,®4gzAæu¥º…$W;‚ÁÄ |Ðz=}Q0=x1Zôa~•”Éä%«˜€Æ *~µ7iB\Q[èéPï&"«jsoÈú™ŒYÉÅJ2ô¥hì:<°l¼Ë†I5iŒÂˆ½J¯å¥©yë’gÓu75Ñcvj¸jf3Î2à‹ (pBúøLÌ:†òCo° •Ÿò¶rŸA™9æ¥è\IGáȾºyã×rTM¹Q޹hQô+<÷ÁÚöÏÑ#‰pÍJ톕Ú<·ãÀ˜(R ïåÐc)né• ¢òÜŸ¡\Zú2ä9fÁÒ˜©°¢ÈpãVÕSÅIG[TÀ†h­> ¬‚êþ¢3Ÿå{]Óz‰ï+ž‹ªÔ¦=yc+Æ#ÞiYIhR&É6'åÂ0L’ e!mUZ°ìš!‹ô'2ÐÜ ¦ªÝhªÄ`¯h‰–•‘2‹4Ò!’LBmáî•NIBÊÁ¾ðYÃõ(·ÚÔœ³% –µ ”÷ *Ÿ¥¹é6Éw÷kfÑ.Úçk.Ý H¦ŽAEåHØð|× #Ð0¿Zò°)rM%‹2·aC•”NÖ¾ZîYBÊéÐN\¯¶¢ÔpŽÞÜTE2­Ñ”5næµÊ:OºnM2È€¦Àö#`Wªúm¤ná˜r½eL†QP½MØ{_?©íLÎ'IEª>ºè=-fD”%)”‹üXv$¨™ÐÍl©K´ä *Ê6ì™ÿJBvÔP_¼åñÛŠ¯­#nn%)òz$âw! ô¥€¯eΖåÀ›FÍm°‚%ó¡/V•HÙÇjÌ¢ãþe~ƒþ&Îv>ËÕš 4q•#  v$åZº ¤½qÒM¤!‹@Dr¡H <©[°¦ƒe˜½dÌ ÓÚþNZ¨·{KóE¼rÖ¿·ÔÙ¢Ò-‰ ±˜ïÿ{K쀩°%Ê—loÛ¹QÓn a³cBâæ–Æø¤î„ts Q°oR›"áÏqÖª_óÕ+¼È gI+‰¶x±Lˆ Yƒ9~Ø01Á «›[jÝ’¦þ*$Ý´h«ÅbÙÕýrÞ_…ȇoi¦*p$Íèž×ü:ì·1óöÜI¦{%´É”Æ^êÿTSmôì3.%K(ë W¸æÚ§¶C¹`ueX]ø. fîÕ™-“>À“¸¦h]k†ÉñHv°N]É'%8™³i¹,ûÔX4G×7ˉQ(SŠk_øYÏFË”Å*)eÅ2n>°“?PbâÆx€< n4‚4²Ÿ ÃÝ /ï<Ï”ëÂl¡V`Ði«X¶=Œƒ‚»2Ž”ª ƒ+`ni'ÜÊíéã›Û¹Øyµ"pHvÐz,1ÝÅÎñ†m´ ¹RµÝ$¤cz5\Pb¼1 §œëúcøPÉÚN78dgëâÏÀG3 ›.WH4[±%hð`cï‘“.¬T#½sî|­&Y,¢Â3²Tˆ8Âô‹T#üƒ*º?*Lظ4€ûÞñ Ð+™X¶ µXçŽ^˜6Â| ,<â‰å²à`àšøy 3þ’ªË0îk~òdFv2¡'àDÊú¿áôw¸áù63ÜGGÈޝwX…Ú‚ą̊ÿ®¬ëÈÀຒ-hÉoþ T¸Æ7±‹H¾éH uþËýôðôcIøìHU.,%gG2Ù|Ão—@*P¥ÝçâæÔ˜„"Œ9ú/ÀÀ¿ûN*,I“îþn9ëò (/È·R8î‡â†®ot …܆ñiâx•Àû>}W·êë!ŸGP׎r§à>@ÀtfKtõIK8=+_ø‚¸©¶L¿=¼¨¯6aÛžJŠ$7P8å™ì|≤žÉoXM†aüžÞ+X«h¼œ¯ŽFgÞÖ´l†ì8®\û÷öX±¿glSWùÅ%¾Ó ¹)•(j‰hj¡'ó© ˜ÆRnX¾`—r¹ìÚŸS¸k—2åB'”_rÆDÌø<X•Ûúâ¹VÜͳWo*ÛXL±Þ–‡"?r•&£â]DL2­»¾Å¡Îü†Ò„F^9õl…Ïõ3wctó†àÛMÍn§ÿouMÚݦûœ´šü*ªôÙ3Ï•ùÔì./!\•Ç–¶b|²Ó~âAIb›6ó4HÖïàß›ÚnÚrG¸ð—W½®2/û;->$;†>a}{0Wù{ÈÓ¡öQu´?þÇi:žQgri6rh+ä~GAÙO— )¶¿£ÐÖ4˜>à)J¶Ö%»}dxØ1.P¹ô€'KEèHï'ìƒË>~ÿ(û3Ei&Ö6}V“è§t´µ\.£$äêÏ¥p5ÃË¿¸ ’Ì9ýà)Á~;uú7äÿâ3¸½%vM˜Ý/eUÆŒ—ÐNÆaÓi?~‡Ü…I5ÄÔ»ú¾»ôçy«jÛ_ø‘” ˜{—¯*h;ÄÃ5ì¹b¼aÎQÀšŒXÇ#pÀ¾Üäö¥Îuó¯T&ëåh¼”ݨÕ®t}Þ,€Õ1>ƒY`kª4˜Ä99ûVqYÑk-4ÿÛWø5ÿÛW³¥ÿ‚¬ÃUBÂ1Û \¯ä³cÕ-ÊÞçnåàÙÚ¯dO9¹çxà|,è¯å7„Ñ ¤/î‚4?ÓÔ }û?Êû?> endstream endobj 5 0 obj 4415 endobj 2 0 obj << /Type /Page /Parent 3 0 R /Resources 6 0 R /Contents 4 0 R /MediaBox [0 0 612 792] >> endobj 6 0 obj << /ProcSet [ /PDF /Text ] /ColorSpace << /Cs2 8 0 R /Cs1 7 0 R >> /Font << /TT3.0 11 0 R /TT1.0 9 0 R /TT4.0 12 0 R /TT2.0 10 0 R >> >> endobj 13 0 obj << /Length 14 0 R /N 3 /Alternate /DeviceRGB /Filter /FlateDecode >> stream x–wTSهϽ7½Ð" %ôz Ò;HQ‰I€P†„&vDF)VdTÀG‡"cE ƒ‚b× òPÆÁQDEåÝŒk ï­5óÞšýÇYßÙç·×Ùgï}׺Pü‚ÂtX€4¡XîëÁ\ËÄ÷XÀáffGøDÔü½=™™¨HƳöî.€d»Û,¿P&sÖÿ‘"7C$ EÕ6<~&å”S³Å2ÿÊô•)2†12¡ ¢¬"ãįlö§æ+»É˜—&ä¡Yμ4žŒ»PÞš%ᣌ¡\˜%àg£|e½TIšå÷(ÓÓøœL0™_Ìç&¡l‰2Eî‰ò”Ä9¼r‹ù9hžx¦g䊉Ib¦טiåèÈfúñ³Sùb1+”ÃMáˆxLÏô´ Ž0€¯o–E%Ym™h‘í­ííYÖæhù¿Ùß~Sý=ÈzûUñ&ìÏžAŒžYßlì¬/½ö$Z›³¾•U´m@åá¬Oï ò´Þœó†l^’Äâ ' ‹ììlsŸk.+è7ûŸ‚oÊ¿†9÷™ËîûV;¦?#I3eE妧¦KDÌÌ —Ïdý÷ÿãÀ9iÍÉÃ,œŸÀñ…èUQè” „‰h»…Ø A1ØvƒjpÔzÐN‚6p\WÀ p €G@ †ÁK0Þi‚ð¢Aª¤™BÖZyCAP8ÅC‰’@ùÐ&¨*ƒª¡CP=ô#tº]ƒú Ð 4ý}„˜Óa ض€Ù°;GÂËàDxœÀÛáJ¸>·Âáð,…_“@ÈÑFXñDBX$!k‘"¤©Eš¤¹H‘q䇡a˜Æã‡YŒábVaÖbJ0Õ˜c˜VLæ6f3ù‚¥bÕ±¦X'¬?v 6›-ÄV``[°—±Øaì;ÇÀâp~¸\2n5®·׌»€ëà á&ñx¼*Þï‚Ásðb|!¾ ߯¿' Zk‚!– $l$Tçý„Â4Q¨Ot"†yÄ\b)±ŽØA¼I&N“I†$R$)™´TIj"]&=&½!“É:dGrY@^O®$Ÿ _%’?P”(&OJEBÙN9J¹@y@yC¥R ¨nÔXª˜ºZO½D}J}/G“3—ó—ãÉ­“«‘k•ë—{%O”×—w—_.Ÿ'_!Jþ¦ü¸QÁ@ÁS£°V¡Fá´Â=…IEš¢•bˆbšb‰bƒâ5ÅQ%¼’’·O©@é°Ò%¥!BÓ¥yÒ¸´M´:ÚeÚ0G7¤ûÓ“éÅôè½ô e%e[å(ååå³ÊRÂ0`ø3R¥Œ“Œ»Œó4æ¹ÏãÏÛ6¯i^ÿ¼)•ù*n*|•"•f••ªLUoÕÕªmªOÔ0j&jajÙjûÕ.«Ï§ÏwžÏ_4ÿäü‡ê°º‰z¸újõÃê=ꓚ¾U—4Æ5šnšÉšåšç4Ç´hZ µZåZçµ^0•™îÌTf%³‹9¡­®í§-Ñ>¤Ý«=­c¨³Xg£N³Î]’.[7A·\·SwBOK/X/_¯Qï¡>QŸ­Ÿ¤¿G¿[ÊÀÐ Ú`‹A›Á¨¡Š¡¿aža£ác#ª‘«Ñ*£Z£;Æ8c¶qŠñ>ã[&°‰I’IÉMSØÔÞT`ºÏ´Ï kæh&4«5»Ç¢°ÜYY¬FÖ 9Ã<È|£y›ù+ =‹X‹Ý_,í,S-ë,Y)YXm´ê°úÃÚÄšk]c}džjãc³Î¦Ýæµ­©-ßv¿í};š]°Ý»N»Ïöö"û&û1=‡x‡½÷Øtv(»„}Õëèá¸ÎñŒã'{'±ÓI§ßYÎ)ΠΣ ðÔ-rÑqá¸r‘.d.Œ_xp¡ÔUÛ•ãZëúÌM×çvÄmÄÝØ=Ùý¸û+K‘G‹Ç”§“çÏ ^ˆ—¯W‘W¯·’÷bïjï§>:>‰>>¾v¾«}/øaýývúÝó×ðçú×ûO8¬ è ¤FV> 2 uÃÁÁ»‚/Ò_$\ÔBüCv…< 5 ]ús.,4¬&ìy¸Ux~xw-bEDCÄ»HÈÒÈG‹KwFÉGÅEÕGME{E—EK—X,Y³äFŒZŒ ¦={$vr©÷ÒÝK‡ãìâ ãî.3\–³ìÚrµå©ËÏ®_ÁYq*ßÿ‰©åL®ô_¹wåד»‡û’çÆ+çñ]øeü‘—„²„ÑD—Ä]‰cI®IIãOAµàu²_òä©””£)3©Ñ©Íi„´ø´ÓB%aа+]3='½/Ã4£0CºÊiÕîU¢@Ñ‘L(sYf»˜ŽþLõHŒ$›%ƒY ³j²ÞgGeŸÊQÌæôäšänËÉóÉû~5f5wug¾vþ†üÁ5îk­…Ö®\Û¹Nw]Áºáõ¾ëm mHÙðËFËeßnŠÞÔQ Q°¾`h³ïæÆB¹BQá½-Î[lÅllíÝf³­jÛ—"^ÑõbËâŠâO%Ü’ëßY}WùÝÌö„í½¥ö¥ûwàvwÜÝéºóX™bY^ÙЮà]­åÌò¢ò·»Wì¾Va[q`id´2¨²½J¯jGÕ§ê¤êšæ½ê{·íÚÇÛ׿ßmÓÅ>¼È÷Pk­AmÅaÜá¬ÃÏë¢êº¿g_DíHñ‘ÏG…G¥ÇÂuÕ;Ô×7¨7”6’ƱãqÇoýàõC{«éP3£¹ø8!9ñâÇøïž <ÙyŠ}ªé'ýŸö¶ÐZŠZ¡ÖÜÖ‰¶¤6i{L{ßé€ÓÎ-?›ÿ|ôŒö™š³ÊgKϑΜ›9Ÿw~òBÆ…ñ‹‰‡:Wt>º´äÒ®°®ÞË—¯^ñ¹r©Û½ûüU—«g®9];}}½í†ýÖ»ž–_ì~iéµïm½ép³ý–ã­Ž¾}çú]û/Þöº}åŽÿ‹úî.¾{ÿ^Ü=é}ÞýÑ©^?Ìz8ýhýcìã¢' O*žª?­ýÕø×f©½ôì ×`ϳˆg†¸C/ÿ•ù¯OÃÏ©Ï+F´FêG­GÏŒùŒÝz±ôÅðËŒ—Óã…¿)þ¶÷•Ñ«Ÿ~wû½gbÉÄðkÑë™?JÞ¨¾9úÖömçdèäÓwi獵ŠÞ«¾?öý¡ûcôÇ‘éìOøO•Ÿ?w| üòx&mfæß÷„óû endstream endobj 14 0 obj 2612 endobj 8 0 obj [ /ICCBased 13 0 R ] endobj 15 0 obj << /Length 16 0 R /N 1 /Alternate /DeviceGray /Filter /FlateDecode >> stream x…UMlUgתŠ´U+•'þZEi´ * ®:i"×ÍRm×ÏñÖ›Ýewí6QO¹T!® „z¨Z~ÔæÒ^ЍTTÈ©H­ ª8â›õÚY‡CÖzö÷æÍÌ›ùfÆKÔ}Ñð<»KÍ;¡_˜Ìξ<{Ltß .Ò¨‡ðfàeK¥ ÆŽëHþí|î}K)–ÜÜ˾:Ï6Ý¥Ë20¡uË-æD|ÿÝXÏU·©ºú$Ö~uB}NR‡I¨/¨ÔçÕ<¤ÃêþÈÆ‡í¼®çÁ7ޅצ§×¨žŒçÜŽúÏ{ç%ÿUËüæÍß:,ÝvÜsˆ«¹ksöÜ$GÈ­ëÿ³!“|];ûåöD„bU½xüfϵ³t$Y‹¨:åµHßNßI¯âûVz-é#ýCz Ÿ[”E½ìˆÙydÇʈëx0q€ˆê¨+G¿·#Ç؅бéGœ¹‘U€ ü ËZÄT²æ‰žèÈ—sgWœs;<ïć̫|½x¯HK}úÇú/úúwú¯úªþÐÏÑ´ú¤Õ%Q÷)o)Ÿ)_)—”Ï•ë$”+ÊŠrY¹ª|¤|ݧ®(—à…u[=×ì±vfšq1ܱAÄk3o,mEp gë™Kä¶ñ†Î~nߥÔvjjyíaíqmBëÕöi´mÚ Ö€6ªíÆÉÎvߨq5y¶’=kÑlÄf³’UüúˆÒÀg=.žS‹f·E§#‚¨fàÿÓÊs…¹H½‚ÞµÔ]ê€:ÏQV݇I!ž´ÌH&ŸÉ’Èôf†3™ÃŒ}sÊDf7N‡ñ=ÒΈY1“:yÉ„sÚd{}^ø_‰{‰½4€mìd(ÏàE”s½ßš«†bPןY¼"¥sÌþ>aضˆŽáË@ú Yî'~ÿ²ÑG£÷jjëu³î7š2J¥¾&ú"jˆê endstream endobj 16 0 obj 1088 endobj 7 0 obj [ /ICCBased 15 0 R ] endobj 18 0 obj << /Length 19 0 R /Filter /FlateDecode >> stream x[ÛrÛÈ}ÇWÌ#Uµ¦ ˆ<%Ñæ!©T²+•JÅyÐ]Ú•H™–¼ñßçôå4À{]µœ!ûv¦{zfzFŸÒÏéSÊñoY”©iË´½MÿJëôþüs‘®?§"}¾Æ¯òËsÐrNâ1…Ö#­ötù ÝBø\§!$§Q²GŸÕM… ­µé«'zÉæÖ'톶ð9¡Ó:¥ôz©“˜D}X;§# æÃº* ÉJÓæ-öÐ{P ¡³9B§u„ÁI»EãSuC‹#tZ§”^¡ët„®Ó{ÎéC§#DÔVŽPš†°B¦ÍŒÑ°•0:›!$­!dQZ;'1™Bë‘Öj¯Ð9‰É8­GNCÈ£´ÂŒ« ¡6aµÀ.4zÉæÖ'í¶½21I>¬œÖ)¥×CHÄdœÞsNG:Ý?ˆÚ¥#”¦#,rdø@è½@¨„ÐÙ¡Ó:Âà¤Ý¢‚QZ9§ãuZ§”^¡ë$&3Õ{ÎéC§#DÔ6ŽPš†PÒU d/*a t6CHZCÈ£´rNÇäœÖ#­!Ô^¡s:&ç´9 !{\cT'vç4t±M¶Õvö(«#½Uáã~ì(²ÏŠc U*Q!=~ŠQV9'ðÄSu:‹båPâŒu!KNF1’W4öqô‘5€br]VÁšÉ¾­;uèaTw`¡s…u·Å7†² (î Öå¼Êó¼Ó½Â"¢â„åYa›C3ðMÚ4f?øq´áÛE#›'†…÷$,Æ;±‡†…@5âb…°È(fRX8£…Eˆñ°ò­3zXPL„Å‘“xİ÷‚²FâƒÊ°ÀÄuq“õYXX‡a¡ epê½Õ\ÐP !0—¥ìçÞ ìÄ@KA“ˆ5,ÈÈl‘ ÂtF ŠÉ2iÔÂbFâÃɰ¨Åx¶è¸È5¦›Ùbܳn«……uãS×è-,\ÐhXˆÕ­,©Œ édå´ 0FO.e4$ÄAJká2&å cóxNV¬FÂ!ð .c4ÂLƼi¼ÓBAi ˆ#í3†}ÙÙlq`¢|Ñ!%·(Ð&€Ÿ®LFnÈ#Кæ~ºï…Yýà”–ê¥ì„uÔåâ0¸¿…u‚³¥´h»au7ç™<õ|,ü£K€YFï*žé®…ó«Ãm'0îÔÝòïpüˆuZʵ•í—ZxUÊX£{ãÄŽgQÝ¢S{9Ü‚S{àö€«q!Å~Ùè ^­½ASü,gçÔÞ §Ì0Ó _7SÊqí è‡ û½-6 tu+@a?Ÿ+‹ëþí¢Ì£®VN¹ZüÛå3 ³¼\ÔM{‹“ê§Ôèõ§¥L³ w«¹«7jô¬ï׋Y‰fé>Šä77[òxù^¯ÕvoÓìP¸ÄØ(YN:ç‰Ñ;i»îÆl~ô+Íõý€õZñÞµÞ¦j}^aº«ý™_KŸ¼öu.”x§Žý~MžcÍñ}yجÙ~ïWžw,èÿ7˜Yÿ³wÚü÷^çàäšúï¼ü]§+šõ@shû]ÚÜíߢd³têBÆn-ö/d(ŒA÷D¯{—Ô7áØ«ÍÚôƒ^EÓ°ûWþîæá’zßÐ4‹oH¼e… ;ÍÂÞÅrt¨—’(:®ºÓÇþ€ÝkxÂõäN/q…Ó êßj÷þúÐÁ“RoZéC‡ªZî§#L-^mÑÔjæd³-øúñìàbQï}ʲw—žŸºLÏð"CÉ +J¨MÖã5‘‰òk"vüšˆ|wz>¸LçL¸L_Š6,’HTÒK–lQÈr'‹4~Õ6 RF+·çÆ'TÚV*/b9‡òC–,Á" ½Â)[©%™tk‡t¥¥D!·¶Re&äÇ2-ÒËÖËe#'ÿUÛ”.$8z‰½™‘»t¥réÎA~)Ÿ‰ôFL–Â%¤K;‰Kwr—®.]Û(EêÈ–•»4tÜ˲wk‡íJK‰Z<Öq7*—®ÜΑ™ô‰…C #$n«&µvLðÒjì§ìqÖMìÕª´’ý,7½ùØE¼LJÓ²Ó;µÝ3?4ìiì—ÐP^Ó(«“iÜÁ8tR…b©<ÌX&ë28ÃE£ÛàdÖœŽÑÇ¥Äà)Åà¸yv¢°Îøàt mp\È$ˆ9;­iƒsŽE Z“"%O>àŒA8RÌ‹Aè©:ðC£6ñ8E¶}.Þ-¨°çF{0âÅ©ºén»]7š’GŽ©ÉxjI`½8œ>(¸Rõ,x€eåt WÏÎû “—]žÎÁ!B–y´œ¸—ÅK =Š=üù†[‹nÖ_WeY#VaWFÙ#f'^2ŠX‘Fìˆýø¿Ï¤šSÉë¿í7¼CÒå‘ã4Ñ0YÀ¾Ë0¹dŸ;nuŽ Ö/³;äî©êÉ3B[ÙŽô”·AÛ;>zøê-ö¶‡uàm,‡ÇõÔ»U1«¬ ª]³ g×/_o¡¾x=q9fƒïpñB÷ðAÜÅ^_b˜º÷bô+NÛØÒdz×Ys5Ž'ŒúþÈ®Ÿ$›ôü?tN² s/N×qÀ«2Šå4å,¥±4>x WR+ž“ä>N‚7ÝcÙ—¯ay߬c6ßæ…&¬ÃxÄwùüñ÷rÈ,Òì…ÑÐuU͉ðÏ »óroW³ãF yd¨Âƒ*dø}/fñÜ™¯Â¶¯q¤9t©ƒãáïú‚+ŽFÝãa¼^&š¡£™I Aé]b!ô 1&hR]ï!ôö×tEú0™~“6ëôçê·õà9yu›Îä¸Ô¤ÙÈ4ÆN׿´ÃdÄ*Óš¿†á®&?(QáLxá%ˆxûpÒ͆ÑñÆ'Än(9JÃŒ¿ìÆc6ë‚•ÒnÒÛÚß¾§YçÑt™c½ë›lÖù¦[.ië¦St8ÀÄO„I[´³~ÎŒÊHXv(úÉ%‘¿{ö)uðOºxý²ÙR{7uw™³€&~º8é©]q|g»ªÁþüM³ÅϬšµX­²Ïî¥lŒÅq/¥ÎK …ØÚ˜¯0:\óÍö,é)pvOÃ!•vBÊÜáHW_ßÅw´“¿Á/höFqŽ×K« Öñ›ýMˆ¿N)Òî+ùÈ:½ŠrÞJÝ×ã¸íYä(06üîIoÞÿt»½¾}y}»|JÛG<âX™?¶¿i¥{²÷~.Òìÿ-Ù¢”òþ·O—¯_nÏ7O›íãóíëöñ:Sñ $LÙÝ[-þ®`Ù.RÃÌ×ÿô“߯µ{ŽÝËÕîó˜èß™²íŒçnz‰›m5L—÷h/äì/ào}!@Œˆá!‰ã]40/ïùëÎdØŸžûµ²ÏûO Ϭì¶?S$Áüv‰,{8Ð37R$á9Ø›~þ?Þ£ endstream endobj 19 0 obj 3493 endobj 17 0 obj << /Type /Page /Parent 3 0 R /Resources 20 0 R /Contents 18 0 R /MediaBox [0 0 612 792] /Annots 24 0 R >> endobj 20 0 obj << /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] /ColorSpace << /Cs5 21 0 R /Cs2 8 0 R /Cs1 7 0 R >> /Font << /TT3.0 11 0 R /TT4.0 12 0 R >> /XObject << /Im1 22 0 R >> >> endobj 24 0 obj [ 25 0 R 26 0 R ] endobj 22 0 obj << /Length 23 0 R /Type /XObject /Subtype /Image /Width 89 /Height 31 /Interpolate true /ColorSpace 27 0 R /Intent /Perceptual /SMask 28 0 R /BitsPerComponent 8 /Filter /FlateDecode >> stream xå˜wLWÉDZЍ(RE,ø¢ô©OD„qí‹ «ˆ¢¬€î‚`¥*Ò»{Œ±Å5–ÄÞbïú>?ÇÜüÂïÇOð÷²ÙÉÍÍܹsΜóÓfÔÔd­Å?»}Ã@­iÓ¦~S''lNŒMŠû=qIqñ×'lJà¡Ãg£$‰KŠäë¿‘7Š–Éèî÷ëdphÞ¼9|ÊjË w){ŠKªK+öTVîÝU¾»‚~im™ø„¤hW±2¥|”W—Tì­,¬,JÍÚŠè²uû6Ø2X\UòCæ2ÙöVæ—lÉL‰KŽG©´éÅßn¹à", ´˜Äu¬žW–_çABÖÚ’‘èâê2Ða Í¿lúÙõsîä;ù—Èè5¹¥yLÈ+¯KX‡O}Ÿà–“>iÊ$3µ&ÂHÕš4mjni1eƯ™¹™¨S-ã,½9c‹§÷xC#ÃïÄjj¨cÝÃú·ù;Šr”*¥Èi ð åP\Ü\´u´¥…êt¬¬»-^\PQhŠK¨Øš°úà9`À€ÐÐЬ¬¬ŒŒŒ[[[ "¢"eP+ì#Œ/^¤¥­ÅL''§ðððôôô-[¶õêÕ‹A‹®–?h+%—T EIMÙªÈ0ýŽúð¤!ÛÒ¥Kµ²²²¸¸xÆ 'N400;:¤çd4p „ (¼rY³æÍÌÍÍáùåË—¯_¿Þ½{÷áÇt>þ\RRbllÜB½EèêPE4JjJÙwVïÛ·ï¡C‡ ‘oïß¿R½¶zlbôúhÕ¦…<* (­)Ã#444XËÎή¼¼üãÇòk‰>’³•­[·fš•µÎŽëÉ£]_Ÿ¥‰ ­Û´îÑ£Ç7·Ë—/ëèè/lÅÈÕ«W»víŠ:I©ÉòV‡jQÀ8dÈÇ‹É÷îÝ;räÈéÓ§_¾|)FNœ8¡¯¯oÐÙÄnëFlAØš?44e8øùù=þ\p®ï}àÀSSS&÷´é¹½pG~EŠEÅ/ è?°«V­Îœ9#±}ðàA÷îÝûõë÷êÕ+iðøñãêêêŽÎC¥%B @¾cÇŽ·oßf&&Ѿ}{d YYYá)‚›ÈˆÇ¬H…TJ­¢ ²0%3Uø¯Ï§OŸ$©TtØ ðgQ÷ñîªEö“hÒ¤Éüùó%ž÷ïß߸qãŠ+V­ZµyóægÏžI¿¦NJ@Û”¶Ù /ª*ÿ+‚µ¢££Åœ””>uuugÍšÅdMMM>srrÄß‘#GbW™yY`XJ¡À$Ƹ•ÍíA’–Nnn.Ú!YIÞ˜WÇûfϛ͇–8 9#RÛ³gô«ªªŠñ ßEÄ •{ùLPo¡Žû0çÉ“'ˆÊ„äädABää“Èùöí[FRSSù$Ù¡¢0bD ŠìLLF©¢¢"IÑìÍ›7Ò/^±Ò#F°¨›ç8”­oQÆKkËÇwoÙ²%Þ-1¬ÅîÝ»¥_ÄŠÿiþ‚-€ ê`ldüúõkæ\¼xÑÐÐnû÷ï$x á‹ÚùÒ¥KŒT‘Š4'T*˜"Øvàï $š„g¶»OŸ>mÚ´! `½‚ ‹-êܹ³¶¶6I°¬¬L²sçNhMLMrŠwª°F¶u̸10ÉB¬Bn‚VjÕÕÕbœ÷µk×p_ÿ_$( @Þy÷î˜sþüyù$Â8 ¬p[&=z”>Y@Å)BÁä±î®J^\SSƒ¨L²5jÖRQQ̱··îÔ©“……Eoݺ¥¥¥E¼Ý˜¶I…°Ê䩲*÷Â… BÞ¨ãê*[šæíí}ýúué—Ð%`Á¡ ïÑ®£Yˆð‰¥¨ò°À\OOOLÀ¼á¹bu¨x C ™í9:@˜˜˜($A*>E€ÂõøwîÜ!åŠ3‡-£#¬ka³˜“ ¼v2HqOZE¬•——-M>PðkíÚµ F¯A`8 $ÖÎå qLê+>§M›F^>wƒL>ۀ߾GÝúó©"Œôµí ÌUð!qóYZZ*>y「 ²äAÒ/Òˆ`Dx[€ïàAÆ&Æ–––ò‘Yò OâùôéSsKs¨p:u‚n[ÝŠjçÔ©S„ ¤BeÞ´Áƒ “]]»þvFE{ø¾; …7€; •Aš „¡¤ä“¬Í'º#$P`{xú•+W$jQW|øð¾dëcU/ÍBKCƒá23`&ãx¨ %›,_¾|ìØ±žžž$eQ™Pk >¼Y³fQñQªåáo3K¸yº±Äœ9sĵµµ@MÙI¾vvvæWaa!qƒåyœ:‡p!üôæÍ›¸°fKM©„Wì`6Þžðñ›ä'â'¶ gNÇêx¢——¼|¼êÚXy>¶áüo™< ,$— iå߀#ž0SFEIQ„’EKenØ­[7)>`ŠmÛ¶%­pô`Ù}¶ón×® ”rWȰcÇhMÍÍv–äªÈ B& Îß ###Ožu¨bbb8ב9[‰;vNå T„ù\¹.¶oߎIp§‡]Á›9Sv^û§5ÒÍ?Måÿ¾ÿJþN endstream endobj 23 0 obj 2931 endobj 28 0 obj << /Length 29 0 R /Type /XObject /Subtype /Image /Width 89 /Height 31 /ColorSpace /DeviceGray /Interpolate true /BitsPerComponent 8 /Filter /FlateDecode >> stream xãXøŸ`!ÇRZ 4“VæÒȹ£ÆŽ†ÀhŒ†ÀhŒ†ÀhŒ†ÀÈ=4òþI¸ì endstream endobj 29 0 obj 54 endobj 30 0 obj << /Length 31 0 R /N 3 /Alternate /DeviceRGB /Filter /FlateDecode >> stream x…UßoÛT>‰oR¤? XG‡ŠÅ¯US[¹­ÆI“¥íJ¥éØ*$ä:7‰©Û鶪O{7ü@ÙH§kk?ì<Ê»øÎí¾kktüqóÝ‹mÇ6°nÆ¶ÂøØ¯±-ümR;`zŠ–¡Êðv x#=\Ó% ëoàYÐÚRÚ±£¥êùÐ#&Á?È>ÌÒ¹áЪþ¢þ©n¨_¨Ôß;j„;¦$}*}+ý(}'}/ýLŠtYº"ý$]•¾‘.9»ï½Ÿ%Ø{¯_aÝŠ]hÕkŸ5'SNÊ{äå”ü¼ü²<°¹_“§ä½ðì öÍ ý½t ³jMµ{-ñ4%ׯTÅ„«tYÛŸ“¦R6ÈÆØô#§v\œå–Šx:žŠ'H‰ï‹OÄÇâ3·ž¼ø^ø&°¦õþ“0::àm,L%È3â:qVEô t›ÐÍ]~ߢI«vÖ6ÊWÙ¯ª¯) |ʸ2]ÕG‡Í4Ïå(6w¸½Â‹£$¾ƒ"ŽèAÞû¾EvÝ mî[D‡ÿÂ;ëVh[¨}íõ¿Ú†ðN|æ3¢‹õº½âç£Hä‘S:°ßûéKâÝt·Ñx€÷UÏ'D;7ÿ®7;_"ÿÑeó?Yqx endstream endobj 31 0 obj 1047 endobj 21 0 obj [ /ICCBased 30 0 R ] endobj 32 0 obj << /Length 33 0 R /N 3 /Alternate /DeviceRGB /Filter /FlateDecode >> stream x…”MHaÇÿ³±Ñ—ÅÐÁ$T& RÓõ+S¶eÕL b}wg§™Ý-E"„è˜uŒ.VD‡ˆNá¡C§:D™u‰ £E^"¶ÿ;“»cT¾03¿yžÿû|½ÃURŽcE4`ÊλÉÞ˜vztLÛüU¨F\)Ãs:‰Ÿ©•Ïõkõ-iYj”±Öû6|«v™P4*wd>,y<àã’/ä<5g$©4Ù!7¸CÉNò-òÖlˆÇCœžTµS“3—q";È-E#+c> ëvÚ´Éï¥=íSÔ°ßÈ79 Ú¸òý@Û`Ó‹ŠmÌÜv×Ulõ5ÀÎ`ñPÅö=éÏGÙõÊËjöÃ)ÑkúP*}¯6ß~^/•~Ü.•~ÞaÖñÔ2 nÑײ0å%Ôìfüäý‹ƒž|U °À9Žlú¯7?ûÛ‰j`¨‘Ël7¸òâ"çtæœi×ÌNäµf]?¢uðh…ÖgM Zʲ4ßåi®ð„[é&LYÎÙ_Ûx {xOö¹$¼î̥߬S]œ%šØÖ§´èê&7ïgÌž>r=¯÷·g8`候ï 8rʶâ<©‰ÔØãñ“dÆWT'“ó<çeLß~.u"A®¥=9™ë—š]ÜÛ>31Ä3’¬X3ñßüÆ-$eÞ}ÔÜu,ÿ›gm‘g…6ï64$Ñ‹áÀEzL*LZ¥_ÐjÂÃä_•å]½XážÏy¸[Æ?…Xs åšþNÿ¢/ë ú]ýó|m¡¾â™sϚƫk_Wf–ÕȸA2¾¬)ˆo°Úz-diâôä•õáê2ö|mÙ£Éâj|5Ô¥ejÄ8ãÉ®e÷E²Å7áç[Ëö¯éQû|öIM%ײºxf)ú|6\ kÿ³«`Ò²«ðä.> endobj 34 0 obj << /Type /Catalog /Pages 3 0 R /Version /1.4 >> endobj 26 0 obj << /Subtype /Link /A 35 0 R /Rect [147 82.99988 315.3018 88.99988] /Type /Annot /Border [ 0 0 0 ] >> endobj 35 0 obj << /URI 36 0 R /Type /Action /S /URI >> endobj 36 0 obj (http://creativecommons.org/licenses/by-sa/3.0/) endobj 25 0 obj << /Subtype /Link /A 37 0 R /Rect [147 77.99988 315.3018 82.99988] /Type /Annot /Border [ 0 0 0 ] >> endobj 37 0 obj << /URI 36 0 R /Type /Action /S /URI >> endobj 12 0 obj << /Type /Font /Subtype /TrueType /BaseFont /GZYJJR+Times-Italic /FontDescriptor 38 0 R /Encoding /MacRomanEncoding /FirstChar 32 /LastChar 121 /Widths [ 250 0 0 0 0 0 0 0 0 0 0 0 0 333 0 278 0 500 500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 611 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 500 500 444 0 444 0 500 500 278 0 0 278 722 500 500 0 0 389 389 278 500 0 0 0 444 ] >> endobj 38 0 obj << /Type /FontDescriptor /FontName /GZYJJR+Times-Italic /Flags 96 /FontBBox [-296 -413 1661 1205] /ItalicAngle -7 /Ascent 750 /Descent -250 /CapHeight 667 /StemV 95 /XHeight 454 /StemH 42 /MaxWidth 1610 /FontFile2 39 0 R >> endobj 39 0 obj << /Length 40 0 R /Length1 12632 /Filter /FlateDecode >> stream x½{ x[ŵðÌÜ{uµëj±VKW²$K¶,Ë–Y^¯myÇÙ쀛ÄÁ „l`B ÁB‚¨JhJ6-E1Ê¥ÐB …>h ¼Gh ­»=H‹­wî•í@¿þýûþÿ}O×3g–3sÏœ9s–‘|åæ«‘ «ÖlDÒÇ\àäªá+Ý™ºüBLbÍÆK×gêZ!öÌ¥—_³&S·”"d{lhp`u¦Ž¾X> ™:†~äZåÖL=ë,À‹/ß°j¦ßó¡¢õ[gÞÄ~÷ë3øÅEƒ7l¹2S/z`×ÆÍƒ3ø¸虡%ƒ!år Ú…dè’#‚8xºó·ìD# ô¹âÄÛìJ]õ§X/—êt'%xâ›ï•M=ðåš6Å÷`´b_„24 8ê›z`êMLî—†Ìf–j¥P5¤hèÇäÛXªOîïŠó)²O“±ä`Ûá6rxóá=äàæƒ{Èaþp%9Ȭ$‡Ý‡»ÈA÷Á.’"cOT–òY)²g¼…7¥È(cŠÜÀ"»èSd.En K‘´)rMŠÜ@"7P¥È7(Sd€"E® O‘ØÙ@–"×`RäZtŠl@¥È5€˜­pŠ\ ¥È° ˆ1F L€Ér¡ÞDjðh#ÒàuR~‘”/’r“”sRNݨٰQS¯Ä¯¡!À~QÊWI¹QÐiþ8¤97¤yqHóÂæY<„:É)åŒ`êÔœêÔ$;5£šêNM´S“ß)NõÔXç¤Ü#å.ÁÒ®9ß®y«]óóvÍávͪvMi»Æß®Iá_úšwwjÞ©ÉÝ©ñîÔ8wBëŽê:tHñ4þê€É^ï*àŒŸGnX%:î~š¯·ác¨’ëÏÎÀ ÄKõ§P#öCûãh±E¹ˆ×?ÞUƧðŠñ®w-°|¼k€Þñ®KàËP—4dñ¸û_¯ÇÝÈ-M9æh§šðQ€­ãü¥0:1Þx _¯Àõ¨QB¯…7/…îl‘ðz Κ™F?C¡úÄ~ÍQþ?Y™ÂKÇùaÿ8ÿáâÇù_RäQAÅ¿8ǟ캓¥+E ù¹ÅÐ<Îÿ$CžâÀ‡HDç¿/¶Œó3hßv§ä€½?ƒ}WPšr_0…<Åß8Åï_ ³o‡ ¶OñW4Jï^Ÿ—a4ô® žã/á¿Áw¤ñ ÜÒ¼ÅÒ»Û*Oñ-AéÝÍ@~ŠorŸâÄ¡ã¼G ˆªËÔb™iË3µ^š­x4[$³’0,±¨…±! Ó/èx¿™÷4^Ê/á¼bìi|#bÑÞ!ÄÙ±ûرvl ;v;¶Ž[ÊŽµ²cìX!;–ÃŽ¹X“Ü çäZ¹Z®”Ëå29-'p.L©ôûB>Ýa’q"ÎÈ–ÊËAŽ–Ô^o%£HNvCºÒMn€4i¤ë mƒ´Ò0¤ÑôûOˆ£'È(¹î¨4鹎l›iÜFnž)ÝL¶Î”¶’a©‡ø ñÇÛJáôÎ$¾5)ÛÝ“ÄI|›#‰ ﵚÍÃuÖ:C­>Þœø;Y¿ÔØŸ]øXÿÛ.Œ…îèºæ' ¦Öóø'R~ä)–•åc%ÌŽE€0&!ŒIcÆ^eÇf¬ÎäþŽE=ÉGœ½É¨XH;{;’…‹Ü÷L:RÓ”˜ µ"èí™@¦n±½—è´åhí:@C•"4üâE4 é mUÍMjE´.¹¹%47¹ZB;'¢Ù\Ù”8R  ÐÏ ÍÊfú™¯ ìù:Ê eÏ ŠCš%€Y!ëí9’„#iß…îÅ™îÂLw¡Ô»ÐÌt·dº[ ûk¼ÿÿ¬ 6üw&hZ»¨ÁŒêê¬!®GXuRæmH²ÞÿÓ[f>ð ðJÀ#`*Y‚ŒÔzdG(ý¤ßBúóôòô4SŠÂÓ¤ÿʆÃõÝ™>ôÚ‡žC[Ñv(߀R(ˆòQ3xB‘éEç°€ŠàPÞ Ä>tYQ º ¿ïxlÔ«€çGMènd†öÕhÆç¢FÀ}¼—º]ƒŽ —И»u£%è89œ~£o¡×ñi*=3¢r´Ý„nK?†Â¨fA7c/Þ’žD}ð¬ºnG Óé7`],RJ4VæBxÓ¬À.,ààŽhÁ·ñ½]ð¦¥0â(œè–ôfeD¥H@õ¨õÝ×¢½èPöŸ TÄÁl.@›Ñ•ð†»ÑSh}†—mÚ—¾?=‘~1ýGÀ%ˆANÄØ°‘=@é¥è6˜7+þWô<çЯ±WázÜ…wâoáñ›¤‰ S»¨qšcøô¢làL8žTÇPÐ}1Z‰àÍ·¢ï¡Ã@ãÇè<¶b.Å |?q’<²†l ÇÉiŠÞCŸK,QB`'XàdP^‹æÁ³øv5ŠÆÐ°wû²‡À|væWh}†¾Ä f±qfoúþ¿G´ÄL¼¤üŠ QµÔúçô9¦iú¶é¿¤{Ò½éMé§aõïÁ»Ä•‹|º­ŠWÃÚ‡a·wÀÞ‰ÏðìF÷¡Cèa°ÇѳðæðîWÑè]xÿïÐï†Iô úOð“§€ 5æàÉÂÙðøq¸V »Ú…âa¼àñMø6 ñ >ŠŸÆ/'[Hé#ÛÉnòcòsò&9K~K~OþJ)('å¿D·ÐËéÇ-³’¹–a—•O}2›^6½bzxúTšMkÓùéáôöôwÒ)ØÕ?Iœ”#øË^Ø‘ìê<4ž.´>t Z…Ö Ë`o¶7ï~Þ +|=ûôC¥—au?‡]ýVöWôšBÓà`ÓÀgÈs>ŽÂŠZ`E‹ñ܃/Æ+ðJ¼áMx¾Ö¸žÛðí°Êûñãø~Œ?Áç " Q=q“Ø™²žƒõäZ²‹ÜAî"È}äù’$GÉ+À?iJEi)?ƒ§‰šGͧ¨MÔmÔƒÔ!êQê$õ:5I}IMQSt)§Ð×Òûèçèwàù£g"L³„YÍ\Æ\ÁŒ2w1‡™qæ]æ Y¹ ”ÛÍÞÀîfïf£ï Ÿ¡{à¤}õó Êújõ–ïE? §Hzý8p#©€³S >g½í“M>'ûñË Yh¸“fÐu„é@NHVên8×(ý¤IHO7€„¾égÒg(¼w]ú 3{8 'Þ'âú-­ÀóA¬¤JA~Wƒf)’N_¾-.І BùyÁ@®ßçÍñ¸y—3Ûa·Y-æ,“Ñ çtZZ¥TÈYCSà„4y›ûÝÉÜþ$ëmm ‹uï4 |¥¡?醦æ¯ã$Ýâ¸èú¦˜kþSÈ` s˜˜sW£êp»ÉëNžJxÝàA/ìò­ o¯;9)•;¥2+U4Pñx`„»É:”p'q¿»)Ù<<4ÚÔŸà‰šÃø2\€&ôæšÃ*qæ$jØ>d b4%íÞDSÒæ…2ôQþ¦ÕÉ®…=M ‡ÇÓ.HâÆUÞK’,–.43\š9É6&e0µ{m€ö¸Ý›âÐ%ý!õjïê‹{’ÔLєԇ’o"iÙvÎz¡:[jÚ;Óù!t&‰¿y`p´9)ô曆Õ~±6°j¢yO’½à¸í„‰Ý"¹"é™E z›Ä–þuî¤ÂÛà]×<·&Q÷5žq»]˜Hƒqkr.îñz’uoï@"ûˆ v_ó„MpÛ¾Þ.˜°î¨òË&ÂõázVy¬;2ð77fÚß8&BëŽãïìèžã ñ¶Á*’îUn  Ç K©³Á 4ºª˜ Ÿ^ LX›T4ör•°[IÆÏyÝ£Ÿ‚CÚïüý×[fZd~îS$vŠ›='0I<0[N†BÉü|ØsØŸAØ& ­Vj(  'Þœ;éV¡.àã@oeøîñˆ[¶'% K ’YØ“©»Ñ%Žq$DB½IÒ/ö›íÉZ"öŒÌöÌ ï÷‚4ý|”•”çÎýé8³±i¨2‰Íÿ {Pê‡;…‚ŽRtõÁà™‹{ %œpCA­\N¡QÜ×&`ýP)-€†|”Ê ÜÍÀ÷fàv¯{Ô=Ú¶zÔÝì¦ý„ŽÁÑÞ,}QÏZÈ÷x’B¯c®8ØÛ[ ó”‹óÀ@í…ÖÍÌPjŠLR¬ 69·«gaOr$áH ‰^ØT8BÇ€­ÇàôôöVÅ¥@ñöµÖšã@sE>ôWffÏ}¦èç\$Êç±ÑQǨxè3õFÛ Ì4¤ˆ"ž…邱¼‡Øàõx=@Vo^UçgV@áææs¸fŽnY ÔÖH®ûâ°ðÏp¸þŸâpÃ¥_ãp#ÐÜ r8ñ¿Ç᦯q¸ùs¸eŽn ²¨m‘8Üö?Äáö†Ãÿ‡çÍQú5wÍóDÏÿßãð‚¯p!úƒô$=CA«H<ýg¡U,ôЇà2îT©[Q$Ê$?‰£HK˜êÊ)'*…äöN¨/¡nM¿ÓÎÞŸª!úxên´\RkPü;‘  ‘ÃÿûGöÊÂ%¤°”Tp³­‘FhÁ³å^*Às2Íùif©­â°n´ |Ö$›üžÚM§·2Í2Nö”W+|Š”fåëªÕêfõDDŸKæ…¸SŒ<Í6!FÖDà^4_0RRÊØ&ŒlrB51t¯bz_Ž ¼ý¤zªz>äSÕ¨®š›‚*dÅE^½G€d”•§¾¨d*>?‘¢N|)^ÂGWá[ÀóÝŽì‚Fô½h†FªªÏB‘)¬7XâÅEFëÁÏ9§k‰bD—þsú=²œi€q¥‚V$€JÐ 8ï2œÂwZŠ"*²ŸBû±{z¡5d·q“Ü”U¤ëÃâ"܇KÀo?¿zê‹ÕLÃçßé€ la†`Ÿ¿-äЖJ[Ý£.†f,VÚT¹iô®›·ºÞåÍ<&…Ÿy"¨~W¼O ŒV CÓFwÐbµî1Ð4cdܼšöNGçÒåt3½–å¡=9žÈI÷ÜÙ¾Puˆ;ôÔíÒ†¶sÇCâR­ˆût2ô%¶Ÿ°#n‚”Ëõ"ò÷ÕAðƒTVšëeËbµ¸ŽXL2kq–ÉlÉò¬J4vé°e £—سÿ\ÂÕ˜L' ÕzéÔ 9X*£þdój½V†§™"K±2µì‹\éå™Á³Æ!!ê;Ì:àÃVA%3Êx‹ÑÂÓ‚5E6 nx.·É7ë§ËjÛ, §Ç­ÆŒ[P;=ëCçœN‹Ù¼ÒtŸ‰˜`ÅgÏôMž¶×LÙ­Üùê³RAoˆ£:{ͤÕ>uü챺I¨s kÿÌ.®1†ËcåâsX€rIütXd–'Z³P Nnh¸ê–«7.†:¿¿tàà“{MãKù? Ï ‹E1…7'å’Òûà»Ð>ÐÎ.Ä2PwµXT,5« D~rcôŒPS¢œ—àå2Fce=1w‡À^faäÅåuW\uÅηßü÷K—.eñ‹öt×ÞwûŽh9ý¸Ù«ÖØXB(/#Wb«\®™RTÞ~Ùgo¿Yv´üúµÇæ÷MŸû냈h£ª€ok¨]À·õ‚`ñ¾å%cÅV­9°Ã©Ô2Œ6àcM N•¾ò'î×@ôZü‚ÕÃÛ°M®*AD ýd„ŒÁeO®_R‡'Oo²×€rÃgú¬k¦NÂ깓}à)OöYAñÀÅ”¨ö2‚$©C"ÉȘå«2õùå¹þ¨'/|ÿdçí5¬³¹~ËÞ›Müð-j×¥‘ÒÂ{µÂ`›¾ã¥M#½MrsoÑ¢G÷}ðÑ«!HHÿ†ê€µe£<4",¼ ܳ›,¦5¦aÓ.Ó-þ»MÇé3ô‡ôÐj†ÆBžG©Ìár+˜»bÌè7sÖœv-9s_“}°$€)n$ì¢hq¼É~ ,põïvtí½ª¨WÉî’É9Ÿoo±7/ë –SôBé8[ãÉæ¢âæ{±@‘ŠLBÅXh™âË´t_ÍcµeÚcòëôúã"ëPÑ’hDcÑ’v¹^aÓj±qÁÞ/ég4yHAéI6#@RŒö þÖ‡­)+¥Èž( ý oÍgkÓúµ6Êòù™.•ø¥x¸8ä-è(fM.qƒÖÕjE+â÷£~Žø >r‡ïß_|”Ï—ñ˜D†o Us¡“,ðy;wÚŠE$uùé$w~’€_,éá‘>+(’“þ42k¯3’-J±ì³$ù’6™³Ç3,Íõfl þfee^^UUž ¿¬•1¦œ O‘]ÙQÜÙŠËU{)ºlþ¢6ÑRzP BaaÝ{ÌTy\¥S©«¼õfíÚÂÖÖbg(ŸµIéÓ{”*™Ü”‘á%À¯*¸ßö£ÝB«ÌŠý^/b7¢¡ ÌËv¨½:-¢ƒV›: L†­Í¦ ¯—7ètZ5Êjtªt¹A-Çépƒ®_·Q7¢£uº\e wÖ¯þHÄœm•@ÑÁCèBXñé.N»ý¸dc% ËŠK/E-³êvVÛŠŠ:ð•4‰u‡¯2Tt±ìô *Zkô]t,-Z´Ø—’3r »ýeô\”vrõµcÖ( 0#˜3ŒUW‹/¸óÜä¬Bh•4Ãß*0„°+™¿9 ñÕØ/³Iòt9È0;çûP2Q·ƒO³€!ÑÍ””Ün¸PM¥7Se!V°HZ†Êá‹<¡ ]·oˆÌ7Þ {jpd™lU¼²õŽ·9‡aÆ(Êflo¨.®¿÷YBeYë&ª*ËÜež§èòÎÁ—_µaÕî!ê³g^Î57?Ò{¿Ðb^2õ+ÃerµZµk®áì5ºœ,R¤æäVûËCë¾ùò¢B¯°:Þ¸¨wßò‡É‹*“*ÀQ9\”^õ½+ëß9°^xˆ ¸ê‚eÜTž·®æžÀÉÀKŸU½x3~¦JG×еìò겚–º^ÕÒš«]» wf©T劘›kh!à¶*\ã1¨6(½ª]IÔåÄYܧë‚BÀl 6¸J¢QÞàrºêôAà `sâ1³Ž‚Hék,P%œ«79)§Ï•p]âºÉE»Zœ.ÎåjPb5´ÖG†OZEë€ÀÑw¢.2V¢zN(þÖLH> h!æö !wR<¸3v¢¨o‚H¯ä¦¡­ÃæÌ^Jß“1{~¿& `1ü‡Í¬§HmÑÖÇÜOÈÈÎmÝc› Ü5Jù´RËÙÎî¢îŽœ:†Þ¡d-ÎŽÍMe5 dÝ|Ñé¡HŽRÉhfºûé‹î×{–ZK]Ó]H¡³Ö¬¶o/Wésµø×Á•Õ»{áÆeßìD9Øîg Ô‚wÙ/´6Ó­ê6M¯i©c˜¾V³Wsúà ¶w oÙ>Ô}dþÈv^÷¹Ù P)Ô„Uƒ@:n¡ie ›%,•¶ò›àp;e•úv—3rIpŒú21…¤ð7õ•gB3ÉD‚#úίu=¸ã2ƒ·ïž›w®Ñ§úËÑC?zöݛ֟óHGá²ϼFŽ>±íôÉÓß½ý—'N‰~ü¦“òR·Á7á÷ ó_ÈÃp«B3 +s8á›ú üƒAo^G¯s…9ȸLfÛ²"Äéirñ¬Î\¢`]A§RÝ‘ñ˜ç†]»]ÄÕ)Œœ{ªîËu¤Dò$Nιâ5€~ö" £'f¯…2ªá¸¼Z›Qâb„›?!Iî[KžžhåfO¾è2ˆWE%øãÕæÖŸ.‹””„y·BM«ä;+½!GøÀ!­ÞåWûlÁù u›ŠU2ÓÛC·~T WY9³Œ}çúÎë»î$ËK»í.7MyäœOä“'ý™„3[ŠÞœƒþo*oUÝì?+c²õ¦PXï UëKBkõ§Cr%×Êú,‹xÛÝfµÊA(šRÆCQB-V‹…7PVÞ1°å.­I&â6;}* Ri&Ae^0ãb¯f] 1pïJNNa1çBpiWMä\5­…íÜIˆ\”|2{ÍKvk†`®Œ^°S¢æA4[\X‡KX¯dÍÄO²e¹e„úñ·äÜà†~ŽR0JšÂ8þ ú‘£ g´G‚]»ôƪ’Âö,yÚ¡eC]›4C«’½Ó8µÒà)Í^¤ËúÆ`yάßõõ µ%ÐgÂ]fLªìÅö¨ßé/öGËœ‹eˬK+z*W;WÇîrî/× ùîPk¨Ù«¨¨ŒÇ+ËÊì†'M)$ÊœZÚÌñELñŠ]攼×D9ÊÊxƒÓ™­d³ƒ™))ªQ%šœÍAÄ5'–&ö%Ž'Î%˜D¢I™Í58;_kâlV67Ízp™Ðb»¤À£àŽN8—1"—ˆ*¾âDX2á^<_ûWô‚|ûqùq-„» œ¿Ñ•=oY.7ëðlh!^ŠÂ;idª³6ìÜ1xAƒÌºª¤ùÎû9¦Ž°2{VÕ‘¦ÚRwõÝÏ0rµN綪œvatÕ’‚ ¥ÊmfGܲÍã(…ÍyC©W„ŒÙNV2Ú©[¶ÌbcÓàuMU™rTE•Ï6΋m(*±×š×.ùpåƒÚìÖ,;\Eãô+Ó˨!ÐÃq´Y)´òl"8=ŽìhQÔ ™ƒ7dƒ«¬g9»(Êd‘›å5wXY’Â5‚Y+‡G¶³(ÊšãæJO°°ª®$NÅ!d.ª›:W÷ɈÐXm($‡ `åöSûˆ‹Çº$j(+%™ š-óÇÊÅ @`\ˈ w6Ö´.p-·¬,˜kËÍÒÊtŠâ·;¼Å Èœ^¬Ï²µ\pmq¿Ú¬çBÁ`´öªåö¬¾om^ÝôéB£AÉ0˜ªªÀ­#GG(ÚSJ¨s§úþ\1Ñ®÷¨ò?Ÿ_ÕrÙ䓜Þòd~6~ i¾úø{`¡x¿¿‘¿*“пl…/7Ä_@-~ÿ$þzo)Z¿s»°1àŠ_ß‹ÿ¿ÁiYÞÛÞÞZ¼výà–pÛ•—¯…/JЗ'²\ endstream endobj 40 0 obj 8971 endobj 10 0 obj << /Type /Font /Subtype /TrueType /BaseFont /XUSKSD+Helvetica /FontDescriptor 41 0 R /Encoding /MacRomanEncoding /FirstChar 32 /LastChar 32 /Widths [ 278 ] >> endobj 41 0 obj << /Type /FontDescriptor /FontName /XUSKSD+Helvetica /Flags 32 /FontBBox [-951 -481 1445 1122] /ItalicAngle 0 /Ascent 770 /Descent -230 /CapHeight 717 /StemV 98 /XHeight 523 /StemH 85 /AvgWidth -441 /MaxWidth 1500 /FontFile2 42 0 R >> endobj 42 0 obj << /Length 43 0 R /Length1 5056 /Filter /FlateDecode >> stream x½X{pEþõ-/U>.7WNåÄÓ“`y¯P\(qݨœDíM„"ã˜rÀµZÙ5É`{ãÊ}.ƒ¡Í½ ±Î…¦Ç”ÎÂ=JK¹¯ßc½qeâ˼iÊ´énåZ×GJY¾á`°K]õJQùËÊd4DšŠN=ÞLe¢k—2¡I.þLÔì ÛGEl_Ü3_9Óí«-œ¾Ç`·öÕ”{ ¶Ñ;­¦`OaM¾§°^ñVççC_ö¼}‹ýzûûT{±½ÀžgwÛsíãYŽ ÇOéŽT‡Ãa7Ø㕊íë¥JÐÒÛç°9dƒ= §t‚²œ‡þ䂃ã ól^Fã Ö{4ƒkPŽÙ,Íf°C} ×!¯"qM²×qÃæh>éìnÃF[¯ì©tVfÍΜQíû¡[ÈŠ ß‹ør2—¾§®1 tõ©\1]Áátç°òƒ²{B‘ªââºÅúzº:ZýÍÒüÔ¾½§Í©G›TõHG¨º˜jjnã2Ñ»´ˆOïÐ|ê‘«ÝEáVîÑ|G¨Õ¿$p¤ÕñÅ{¼=~-ì ö5U­]9b¬mɱÖV}ÏXU¼³µ|¬&«ÝEc­äá&>ÖJ>ÖJ>V“·É‹OÞßÞXuK7v§êo¯Sõ‚F½vÑò€®†ƒ>ƒ=§oÉ”!?Er”r¤2RˆÌwPßårp©ù‰üe všÿ+°¨ý¼ ƒ•³h€î¦}t˜lôôº¤X~Û+è(½Å&ÑU8{%2¨ž^b¦ùµÒïßM§h7¡t´é¤ñˆîds#l/ô&Úbþ†&Ótºƒž¢èu'5˜}ˆ.¦¥tzÑþE¦ G¤±æ“æGä Eès "¯™õæaÊ¢ª¢x·ÐIæß5ÛÈI@÷0=JûéiúŒÝÆŽšmfyÚ<ƒ­ê¤‰Ôˆ²‰egÄÃÒæÃæ?ÍA0Q@E5D»è·èÿ0ÊŽV?»‰u³]l·ànŽJ[å ƒß‚‡Bš‡RCkè.0ÐOÏÐè+ö¹à3ÄnñYóZó¿”Fu˜%ŸI„zPîDÙ‰9`66…Íe l»ŸífoEÂR! üRX/|".WˆÄ7¤[¤¸¼C~Ж6xÎg¾IÈE×ÓZڌ٢Óô}ÍDô5‘yX«b7 DÙ>¡ŸígýB`§…ƒì}ö!ûœd!]/ ÝÂ.¡W8%¼"¶‹»Å‡Ä÷ÅsÒlY÷ËÛ<ö¿ 6 n|Ŭ0Ϙ_âˆu+SE i…1Û.º†~…YB9ŒU{†ž¥¬ò!›HgéK°@,‹å°©lÊBvkeíìv夅åBH2… ÂD¡Qh:…¨ð¦sÅ"q¾¸\<Œò¼ø–x^M5ØòEèwû´ ªŸµô–~¥îv£êw¶ùT…T¿^ÝÓó‡|¥%¬ß :RKKøÁá¥4Þ±NsÛpÀÒ\žá×s4Ÿ_ÏÖ #&züá½aQÀïËu»ƒðÁµ8€1JKÚuà¤íé-ZËvÃKM!®…Wt1Ô…ï+³XŸ ùô ?v~gkþuÁSŽÄªuoh;Èåfˆ[á°êUt+l t¶uÇØ¤nâ™à u¨zŠV¥µÅ:B —â9ÞëðÕ©!Ïöf[FiI¿ss…³ï/S:‡Ë ·ssB~z{Âÿú—ÎÍÏ|Y·8Iã hµÀ©«ÍÖ ÀNç·ÈtŠ5OO¸‚ Ólž¹º€=#ztÙSÖ£Ã0Ú| p¡_<%;ÇzU‘ŠeÌÄJ!?CScçð´ig?é ylžŒsă|¡“{Egáa½‡?,=˜u›SkãëÛc­)lÍé¿À›SÃ1ëãðo¸u5Þ&Kê JialgÐ`æVƒ|®~¼£Š«n@¸„oµvƇQZG‘ÚU%j5F®æ{E©±Ú–˜Z­¶a3IK"‰ËÀ`c<ÑŒè æ&ÕH08ý”ñ~Ðé± zèêÒr•}‹¤)%x˜Šy E=êËÕ½¾ VÛw ! `çƒÈ*O"âMíÎ!ÌS¹¼ñ«½àÝ%Š.‚±ï³1 ¹õX,7Æo Û`t±Ã;ä0ˆ§pÊ m@[Ík­[sVsz ¶ôðŽÂ;û¥ž–Ä–?ÚiÃÓ/Ã3FÃðÌQ1\‘D:‚áYÀ\ÁþùÇðì W^šao7@ÎZ¯ÅpÕebxîhöŠa醫ÙÏž÷ã1\3‚áÚK3ãW:¾,Ò!Õ¤‡ð¾ÍÿeðNÒi|»‰ø¨2ñ¿Œ£ OTG†At•ÛÐÅ÷ ’P ºý=:ŽDËŠ£rJùÕ™îÌ|Ô*i§ñÍßå§¾žkH ÎãÖeFðÍò}‹V€áë+Ú†ÿ£(°´±®ÑW\YÝéno#'åɈÓDsè⎤Î0W\ÿ»bÆ endstream endobj 43 0 obj 2706 endobj 9 0 obj << /Type /Font /Subtype /TrueType /BaseFont /DJDPIO+Times-Bold /FontDescriptor 44 0 R /Encoding /MacRomanEncoding /FirstChar 32 /LastChar 121 /Widths [ 250 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 500 556 444 0 444 0 500 556 278 0 0 278 833 556 500 0 0 444 389 333 556 0 0 0 500 ] >> endobj 44 0 obj << /Type /FontDescriptor /FontName /DJDPIO+Times-Bold /Flags 32 /FontBBox [-228 -407 1778 1295] /ItalicAngle 0 /Ascent 750 /Descent -250 /CapHeight 693 /StemV 165 /XHeight 474 /StemH 46 /MaxWidth 1803 /FontFile2 45 0 R >> endobj 45 0 obj << /Length 46 0 R /Length1 11360 /Filter /FlateDecode >> stream xÍz xSU¶èÞç$9ùiÒ¤ùmÒæ$9ÍO“¦i“&¥mÚžþ7üÉ?Mm¥¥ËŸPÀ*Œ2¨ Rp.ãUt”«2\B¨˜¢£Ì ˆŒ8ƒ#ê<Ÿ:¼¸ê³£×‹Œ£4ykŸT@ßÜûÍû¾ûÝw³»÷Ú?kï½ÖÚk¯½ö>]»úÖ~”ƒ6"ñ}+zW!ág¼À龡µ¶lYQ†Ø±xÕÍ+²eõ„$ŸÜ¼|ÝâlÙtBÚÛú{eËè ÀÈTd˸`ÑÀе·gËF`ûò•}í&¹VôÞ>1?zʶ[zWô„_I’¢U+׬ŠÈw `ûªÕýø¸!Ù[Ù¶ëR ù<´IÐf$ERChAˆùpEC~zÕ§y r£_bT(?±é”_ÝñA8]zå%U¼ peßâ(AiÀQ-O—¦KU5W[„~ä¥P/…Ê!º}Ïí”ìd(}ŠÚ–lcu)j€6Em—¢î IQ[¨SÔ½rSÔfªµ €2EÝ 'EÝ @‘¢î OQÈRÔHSÔLŠº€$EÝ@œ¢~@”¢Ö SÔ:TŠºΖ”x}ûÇþ] Û¼ØV‰wÆñÎ"¼£!@õWjHÕÔBÝcT”3Ô"H?Ò3Æï¨~¨y™ê…ô f1wø+©ÅPäo n†QX›¥nNb)ß  *ði4ˆ”ø¸îR†× *O**÷ *7*k•‘Aeƒ¿*÷ö ©‹WT*Ÿ®TU*¹J‚ò/((“…´@H¼.®<Wþ2®|,®ì‰+çÅ•Eqeƒ#àÞ#¤w éz!ÒYBêR ¯ñ(ÿàQ>êQþÔ£\èQNò(_À¹húËyÕˆòÃ¥{DiQŽX”GñoP.V%s‘lÿC«Õr ›ÂMv™\Ê‚/’]…Pú,Ùåðçd—‹mÈÇQ—#_@]xÀ?¡½"R~/£|/Êï"/vBùIï Ðý,x; Î&½Py&éõx=éux- ^Mz­P:‘ŒÙü2s8–Œ•x9 x![ •Œð|Nú—C)™ôßžˆÈOí‡é7&»ò¡ö‡É®w&»"îHvMbüø6´W qík ¼: $¼­BÛ…ö•h»ÀÓ-x™P^´/ÅËY,A¼Ðïfà™ôïKz'Ã47%½%âÉX9€ŽdlÛ ÄsQLlŠ ÎF1¡ÓŒ¤? ÝôŸú§MÐ?5émá)(€‰xcÈ)`·'vùĪ&VÃ?Á('”#^X7ò “:BB9—]GÒûŒbOzÛØ’Þb…Ù0e%oHÆ/Z"ݱù…þ ^óÝŲí*b¿Ú{žý ÄK£D ’ì¿zSØÉÙϽçÙ?{ƒì˜·œýÔ+g/ø9öí/JЛ€aÓ³oz5ìïcyìëÎóìqз_w=Êó.d_9ȧD˜Ïex+ØŸÇrØý±åì31R§e>{b±?†~x—³ÃÎlýݼ™½ ”ä6gµ¿€]åOá=GØ•þ0»"Ù$»Ì Äa—:bœ))Û·=Ea^ÁÞ´tÆJع1R–³ŒÄËÒ”—Ø©5`’À°­6l¶UÀj­6ì&`®û¶˜²›·±mîÛs°µ0Óþ$%Ä&Ùª˜0}ÈíI¶l/Z˜-ñ{X6&gçbæ3ÕL˜©`Jcg ™F'Í“ª¥*iŽT.•J%R‘”’"©.•9Ç!°c:‰š‰ˆ¤"Ф@Š(,¥Ðä5Œ¤Ô}ï…¸ âÝ7BÜñˆë!ÞqâpæÜaÒ{”¦î†¥î ÖOT®§îÈÝKÝ>‘»r)€dN€‡&£ÎlNàL†¡zS}^¦ªµùo$=BeO³ïÚÏôïuø[¸×uÃ…‰ŸL™Ý‘x¶0ž’L¦0>%Q<ÛÖÕ1JE¨Š–æQ*L@¼c¯¦"-³H=^Ý´©ÚK… uh´í%hh/íж´CÛ÷¶4Ú  ˆw£íÊvñnev$/L#ñšD޼šW"'h ^†xŒ‡°òsñ2‚…—åç ƒ„ùœN@‰Aï8äsÂ!§Ohv_köÛ…æeÙæeÙ9ðµö@¶»=Ûn‡ök¢ûoëoü%âð¶s[ŸléçZz¸–~ˆ=‰mC¦ÄÆ…6Û¡­çHƒ-A»zö ØÛŸ8Çõ7'¶rͶCÛ„~ßk~’4oãš¡'[ætz’ïoNnã·µp½ÍñÃÓŸ˜úàwæÚzu®©Oü¹ž ƒM%sMú}o®Iót2׃d®É\ÓùéÂ\-Kf7®¹îwëÚµÙÒßÐØëâT‘…h¢"3B™w ~Hbº33.^ìé×2ïÒå°³ýÙÝ*ÐR´ •£3àgŸFbôJ¢FÜõǑۡå&´GQ x²Jµ}Žç£Åèú m£ähœ-ÈB0fš‹N";Z’I£BÃh;zÚf¢í™3™s0[9̶Ý‹v`+ä Qô>^ž9 çB#ºíGïàºÌÓ€g‚™šD> ¢5£ÉhŒÜ þò"ñ ô3ô^—¹7s8d`¾2ºö¡#ÀÁ78„×Ñôhi„ð{ôVáÆÌìÌáÌ)˜Çƒª`¬8ºÂN´=‰žGc(x&>Y–Yy9a®tºíBÿˆ~þŠ}ØO©•ÔA ­ ±ç5=ÇÑ»XŽsð<| ^‡Gð_¨8}$³*ó(a' ÂŒûÑ/ЯÐ)ôú0å¸7âø$u€ÖÒÑŠ‡Äÿœá2}MhZÚŠþÐûèCôôð`ÂfÌâ2\Ãx î„°¤hj3µ:@ÑRú颜ô‡™2—A*.ä‡aÄf¸[Lž‰WCزúú%¬Õ)Ø[p§y]@Æ"¬Å˜ÉóØq.Æm¦_x5~ÂñÇ0EQÔ£!Ñfq…x]Æ‘©ÈTBø-ð@ƒä ¥0ªEuÂÊu4Ð2˜ù¸ïl¹nGÁ*Ž @Ágè_Ñèú]Á4c(Pƒ„8ìU)Õ˜Ç1 d ž ë4ÏŠ:ñ¼oÄâáç!¼„…Oâ?áñøJ1¥€U‹Q3©ÙÔÔ.IêMÚM!²Š|"^ô®è¼Ø,®wŠï—ȘçÆ?MHdD™©™í™G3of>Ar¸§…ÐtØ ‡•ÀÃZ¸“î@AØá1å?&=:k|ÂkN£ÿ Rý#¬Þyÿtl xü ø“ƒŒ³¬¨YXÑ*\‡›»Ù:ðbÐUø6|'ðçðc ù'ñÓ Y#Àãõáwø„‹ø#àúþøÖQSžo¤~Hm„°™ú hÈê„¿Ðz:HÏ¥o¤×Ñ»é§égè×èO`‹†EŠ^½!FbVÜ.î¯oÿT|P|Zü¦øcI‘䳃yˆùVe¬Mì„ëZа½èE4@ Q#`¬p]ŠâµèkJ \݆µ°Öë@zØõÝxÜÞʨãX£Ÿ‰§Ð»@'[Q ;ö}Ø[1ô ìœwP+>NÍC¡B°dÚÌ2e>¯¯E”x *„h‚žÚ ;7ð“t#ØBhKÿ"ó6mïûàâÝ.gç°ÛXkaÅœo2ô:mžF«Ræ(ä2)#‹hðœKZ¸Ö[ÂÕ“¹¸öv?)s½PÑ{]EOÂU­ßÅIØH¿^hú&˜‹¿‡Ég1ù«˜Xm‹¢¨¿ÄÖÂÙ¯7s¶îœÙùš¹¸-1&ä§ ùB^ y»:ØZLͶî±µ$Z‡†[zšý%x”öåþ8â‘‚ œ@M½w ‰šFKÂÌ5·$ò9ÈCílé]”˜1³£¥Ùb·Çý% ÜÔÇ-L ®1‘ë›èNúÁIæœÕsûK–$€~´-g·h[ŠG {H®·«#A÷ÆT™CãK¹æ„qýӵⷹ–û¯kLPÎÖÞþáÖß³ „NŠ=¤Ô{?”¦?&AmŽw$ðf Ž!Оå"{Ö;{–Ú2®‘^Ú2G³:’fÞ,ª 4£#™Ïç ɨiC„2êoð7Xc7mȹ'[ÿûcš6?pʬ«rÁdn.d&l}Â$Ð:‰$ý“Ðpß$üâ¸\’5õ ««a=b§š³ ‰`¡¸±O¿[Ó;Q#qª¿D¤‘,çUHàÞ‰<¼Û”LI!ÙŒŽCo;…š Gáˆ^p“?…:%±¼,¤±kÜâO~ó”xàëÝ'éw¯¸`ôŠÌ‡ôGô) ™G èU~m¬~Iýý3uÏÔ‹ œÞ]PW¬tsî"—»¸®¸~ ÞüiÙ~ülÙ³uÏÖâçû¾z\}©{püüM^U`ÐDRà­ö´i¬~ Cn“ùuÈÀ_w}yxwÝE•‘J„‘èu†P v†+\œƒXlÅz„s¸Â‘Pü/ `#•F@æn—[€®0Æÿæ3ÙgÕ-©u¥×Ó´…•mRiŽJ3-T3ûƒ'þùÖµFUŽVÇFc¥¡½&ÅÜe õs~„Goµæ¹°Oç‹ 6µœ}bÖÃ7Î/fsÔ2•¦ØX]ßÚ84ÜÔ|$­6°2¯µ /l­™Ë– ÒrXs.ó¡È k®DÚÄ·Ï•ÎÕmÕ1¾¢{Eÿªñ‚îKÌ®+2ù KëëoÓíÒIÕf9+WÃ*ÙÜÍj9$›£eh§5_!áw€§Ÿ¢úx™S¥ôZy³)ªç³(púR7h†úr÷ˆäX/ˆ¯ ƒ «|¸»¼ w£î"#‘Í„ðò©H%ˆ,O¯C >7Ãi*\î0>œW4gÉüi«o(+ž2ÿÀ›é{uÖ†ÊÇ Këwµ~ðÚãõêÇ/Š ˜|é/N¤Óc|ÅZÑû¼_$zîÍü/z)èŸî‹»ø¹.½ÏV\DÏÓtÚ:íó¸yEKmKí/êÚNèNÙ¾ærtóì7r‹íûtâ;v1f‹AªTc±Ø Vƒ¦b¬Âå¢b±œjàÍöÏ,Ø8âÑò+ØAÔÊã&j5¼›O™/½_U˜P©¬:ºAðG4i„‚/]PЙp…;«Jy¡ èXVm¨p qÔƒ¿˜Rí.¬¤òÍö3vß5³Êt-º·mƉ¯±ìýRúÔ†¾ðô<Û§‹ètol9–¾R¤ŸÄm«°`ókoÃû‚ýX û±äa†´ÝÆ×tNì5ÍEsñ<:®Œ›:òò_ÈSäió´*‹½M&—«¬V'ŨbF…ƒq8Ì2˘̑«ÅµŸi)øšÖ÷\‘Ý!çÍ„õ"X?¬^"[ö,½m¦±úÙ@f ŒôvH®ã´Hã,Ű•mé7‡ú“eE*fü2cîjçÝÕwÎ\²+ý\¬*¦Ï¨=@ý ‹—ÞÔ6.øAç3~ _øH­ûÏX¼ü¹ûÃ[€_ ¤çÓo¿9È‚æÀËÈ_ù}¹UAN¡Â'©DÓX‹µ  Ðâ3Tª§m®P¶zæyæOî÷ yîõÝ[råÖI?öìóý¬âÙÊg'TŒV~Å|Q‘²•™rcí¬UÔjlª¯£[\nºú1#®7â€ç±q¬ÕÑB;«ËdÕ3ü2§ŸÉuÎÈËÌq³”WbÓîÁMm™/9Ö×ÿù Ú8‡×rל†œc{½ °Xó玿Ý=v ,ÓиiºÚt¶Û4-kŒLïwkòŒUš ᎃ˜AÐcw~`:?Ö ?²ÃH;ļª;µæ×³& ]¿Ù(AèdçÙ‰sE*Ã.7±Y•áR,˜.ƒÑ®çˆ1#vËÅemÑŠC² µÐãNuî´êÚÉ3#·mÙ¸zò¶Ò ›*$Öµ”íjØxîåöÛíXµÏã{¾g«ÕZí‡5w¡eóà´‡Þ[›Ø9ðs|†bª:·Ü=¼aË]WúÛó7†Ãæ<»ÓÚ­RM¾öyëM*ï#+ï?R»Â=P{¬ÍE‰-nÖ!‚ç!ŠþôÕ)î‚À èœÚpž‹šÁÆyÐ1~½^¡·Q ƒÂHÉ 2£Ä%qçò—Á]l(6v:K KŒ®÷?þÁøŒáã¨aÔhPKY½ÅMÜfNk„C¬Y=5E"Î*­á4•V}„³›9ˆ9-a="¥ÙÀðÅ”ŒÇmÐË-f¯>+÷ñÊœW_Rzy‹Á FÉÆ€m1­ëL¢Q0‰ðì‰ÔÑèYÁ< ÆquWÖá°`íš:²_ÈQbÔÛÃBuÖJdkì“Â% øþúmó‡ö*Ól¥Gej z*ÓÚr&Ð*ÒÖ–KƒãǦÎÞúTZ×âË)/W¸šðç­\ý¼ñ÷š\ x2%¶dGÉÄ[à¬.@7ó“ÔzÖB)sÔ•9Ö‚H‘†#Œ9«e3jÔ´¾ ^ŠRøšLa½¤À"ó6V8ÔVà}Ä`ôjÔ£T* ßÑópÀ’ƒ¬QPc0¬>KŽ<0ùYóç Óp|˱À꺺»»;#:«·o–Lbowwc#Äob²ê8<í·ïwìî‰ÖÛ×;Öׇ¶Ù·9¶·…öØ÷8ö÷„rŠ5ÅöbGq°8ÔÚÐÚ¸Ô¾Ô±4¸4¤ÙeYPE”C›²ÕÐT3_s"ç„þ­œ·ôoÕ(:íŽÎ`gH¤–±6Ê^æô#u¸!Tæ€G0BSM‘˜³Êà@笶­Óêü‘ºhÄï,PˆE2]“­WÇru‹mŸ8f2å22ISc°Ün“·7*ßRàuµ#§ÍI%œ8à,sòÎνN1|~,âÍí%~oe;ŠØ"T"‚‘²ÙÙG ùH»ÜQ狈”›‰”Ï]î9/ìØõÄÇ쾨ôEØyDmÚ­Ínbé&< Ôälª¶Oi+ª~x|¼Í-)/—º[ðç3:zµÙmVθ[ñçÓ;oVNl;aωšá|ò bô"¿^kÃJƒÒH»hw¾¢ÀP`$†j¾*nˆ«––¢"¦ê熟_4¼hßj>\`µ·[êÚ>e0s7òmôíôѾ(?ÉZ…­ö*r|.ýÝ{Õ õ1õµH­ œ¯¬ûÒysí˜zÌlR“ÒÐ¥!(^3™‰A¼¦# HµùS3蚀Ùk6n¹÷¸]œu»à$·Ä†Ü_½ÎWIâ "à¬SÌáŠ*ë“ón˜ì1”ï¾½"¼ïá†ååëEᦎæ&káÌUe3žzªxv-§•1š|¸ Çqä¡umÕ•n½irMKËM·ðéµé? l˜ZRTätG‚·®>¡Ñç0”ÅF_$úgÏ\ ËàÇ"žU`}›^£à±]VIe¾À®‰å+l¼Î®oS¤`—äðŒ]ªô"h²ãή˜_5ŸËa®}Ýd>?ô£ú1õ§IíiAXC"mL4„&¤ç4Àùõ÷å°Ænñ„ÝS+~ýk¥®Ô±”;~Ø çVå;Ê+ßšÞ×9¾ÛWè¯ šæ„»-[©Ýþ Üw§€^ÁŽå[ùxªrªŠŠ*£*JÆHóó™üüšÂÉ…qf ³‡y†9Ê1¼bxÛpÑ«V©‹('笪£œ³E8]šÓZu)¬â]F^fj4ÚLj¹L\¤B’\cF…“q:Õ¬É!—ys០{GÜØ ÿï. ¬5qðü·uoà =yï7fõ—cWð—àÕž5߈l:01Y‘€€&œAâx¨0žxIjøg¹æiåKqhÞ]ÖúRߊXÙœûö{£”˜>8«+ ±Õ‡èà8Ë—KyÇ–zsé†Ç)1qZàƒºà¦;éw@f!xGz‘_ÃŒ%Êuª}†}Æ#†#Æ † Æ/ _sÄbeÈàvl…VVÉZmȆmmy%%~ka¡7O¥RúK”*U¡­ÚýRetÓ:«[/¡dsÊT i®¨¸ŠàÑ#öDBúpà•è{Ç…C¿*P€Ÿ‰\"OÃC“"#\§I#VûÔQ’v«¥Ñ¨šŠ §‘ú7D´D« ‚cÉ×]ŠÝð¶ƒäà™Æ¨ iÁ& ¤†|’%O6Ø>sRy½X—ôYB—Íå–›—BeµLÎãê{äʪI8â YÒ¿³î®›âs¿j¬öø•†™ÁQ øUáH(Ä:;cbÓ‹ð Õ¯ñq0H;Û®œùÓ}5¢7ÀÖ ¿Ìíh[6÷½4Ê´ð=»µÃÿL¯Ž7 ð³àî:ÍG¨Kèƒá»-r/Í“›gÄnðÍY²¢¿qåòEèÿõ!Þ endstream endobj 46 0 obj 7880 endobj 11 0 obj << /Type /Font /Subtype /TrueType /BaseFont /TVOUBP+Times-Roman /FontDescriptor 47 0 R /Encoding /MacRomanEncoding /FirstChar 32 /LastChar 222 /Widths [ 250 0 0 0 0 0 0 180 333 333 0 0 250 333 250 278 500 500 500 500 500 500 500 500 0 0 278 278 0 0 0 0 921 722 0 667 722 611 556 722 0 333 0 0 611 0 722 722 556 0 667 556 611 722 0 944 0 722 0 0 0 0 0 0 0 444 500 444 500 444 333 500 500 278 278 500 278 778 500 500 500 500 333 389 278 500 500 722 500 500 444 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 350 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 556 ] >> endobj 47 0 obj << /Type /FontDescriptor /FontName /TVOUBP+Times-Roman /Flags 32 /FontBBox [-203 -428 1700 1272] /ItalicAngle 0 /Ascent 750 /Descent -250 /CapHeight 676 /StemV 102 /XHeight 461 /StemH 44 /MaxWidth 1721 /FontFile2 48 0 R >> endobj 48 0 obj << /Length 49 0 R /Length1 23628 /Filter /FlateDecode >> stream x½¼ xUÕÕ0¼÷î9wžçñÜùæŽÉMrs3žÌC A ƒ"ƒDÁ* j¥Zg+Ð:¢–0©‚#ZmÕZj+Z«æmßiró­}n@ì×ÿÿßç¾çËÍÙ{Ÿ}¦}Ö^óZû¬^uùB¤BÄùËæ­@ÒŸá„ðóVûŠû¼ !ÆsÑŠEËŠûªZ„Ø-‹.Y{Qqßt¡¶‹Î[PÜGg ®\ Å}\upñ²ÕW÷õGàþÌ%Ëç7Í…þë–Í»bìùèCØ÷]:oÙÂâù³¢PW,¿luqÿ‚ë ~`Ū…cçã^„d/^ ÏàâRIÚh%’¡;QH¿„¸/d/"aøIò¿Ý±o޶ö¬ç¥ý_Ô] Õ¯ÜòqEaî™ÛÔ÷(Ð!?{>©e¨]ꣅ¹…¹ê{Α®ƒ¢q•ƇP$.j忞†µÓpÃ[1¼}Õø4œž‘JŸTê¤áÓ¢#ÞÆám2ü·ÆIã_)ÊÃí EƒÐzžâa¾vCk7´(´"i]C!ØHÍ£[ } ´7P,Ô<âÐrèY=Ë¡g9ô0hìuÃæÀ&Áyê$i/{ °—‘öÒð´4쥥=/Åïżøþ wá)´ÞVj¼ÏàNÜ….D^\ºwÓ$ïsø!äCj|‹T^+j|ê}êã>õ->õ5>õsøFÔ ‡/‘J,jºÕïw«›»Õ ÝêênõÓ¸Eá0-š¢êg£ê¡¨úá¨úê¨z ªNFáê=h<~X**úÆ«ÿ9^ýÊxõ]ãÕ×W_9^}Ñxµ0^}¡Kt©.õ^P{«v›É¡¹›úÖmÐ÷;Ҵ·qÿã@ÖOTz‡ð {§% úÑÞiyÍx#Š1ÞhмøjÔ"ÕkqFª¯Àéøš½é\vÙÞúû¡Z¹·þ€ãb”’.Ý›=½U{§Íö6Êqvìže¨…'÷Lî­¿ —ìM¼ámÔãJátQV:@Yé.þ±Z¶wZNg÷Ã@GcCïõ¶ Qø ÷tzŠ÷TjˆžoRC•.x´åòôÎà{D¥÷ÁômÞÒ7x^/Þ‘•îwÇ4©º=½7Àm.K áé{½«²ä JïÅpÇ¥‰Nï|è¾GÔzS‰œwjúiïäô*ï¤â“ƵHwìH?%½Ö?Du£ÛÛ˜v{ëêßðÖ´À›ìõæÉå{½åŇ—¥¤×+­ŸàÃë1½%ÓJ½~x$“ÞžEÜ®‡Ëq\† s!Îù9oàu¼†Wñ žçe<ÃÞò¦¡ÑOÄ8ðd’éH%cHÉHmP"%¢0Oj áÑëñÍ–[ƒ¡^ŸokùÅ\©snKü?ý¹ïèœÚ;¸ËÝ7XF£î¾ÎÁŠ©¾Y½‡ðŸñg­-‡ðç¤êƒ}ÿ¹uŠÔ/´ôõÙ:'t÷áÏ[— Á%óErðsèçÁ ƒÓ¥û tµBÓH÷¡*QŒÜP¶R:í†âii¸ œÖB*rÚ ”–NKS'¤ÓÞ §íÙkmÙƒNaSh‹tÊ6EN€GžK[ö¤¡€³ƒ8#;£”nä–n”ÍÂ)õPôõî)Ë {²eÒáô÷‡ÅÃSЇ§H‡/øþpªxxGñð8üŸ@üÿ§oaÓÿìª}Ü»ñ¾Ö…Ö¹Ö…°Í¼q`±mpÃ…>ßž÷’¾A:<÷Âù‹I=oáཅ-ƒ-¾=H×ýÛáûÈá -{Ð}­Óz÷Ü'.lÙ{xAk&tߦ›W¶þàY7œ{ÖÊ›ÿón&7[IžµIºîßžÕJo"Ïj%Ïj%ÏÚ$n’žEÞ¾uÉÔ¦ËþÃßêË/Ÿ}Ùe³»Ql'rÃf£ïDF„F?…m¶/ M À±Â³£ïÑ ™ýd£ µ(Œ\hº äÉ:ô1ª@VàãŸâzØßÞB@ÐLthë1ÜŽ¶¢‰(–á:Ä¿A•¨Ýžƒ+Ö¢åpnú ધF_€¾JôB§@»Qꅻ܄î=‚v /Ð7£;G¿DYt=œñîèŸPm€£r Üs)Z“ÔêÑͨžwz }Œ-£õÈŒÊQ-jA‹Ðb´ ]Š®ƒcÏ¢wÑï0è;(‰2ðœ64݈nCw¢Aôöâ«ðÏùèâÑ¥h:Œ`)\w+¼Í[èÏ迱?_uî…gPj’Žß‡~†v¢Ÿ“7A/ÃïÆSñ :@—ªGËFOÃùZ€šˆ:Ñ,¸bºÞä.t½¿?ÀS£¸÷àxÞŠ_¦šh#ñG¯…Qòï:øM‚ñ_#݆n>‚ž€ß‹è·y9PÔê$­§Ef2;0zÍèîÑçF 3Â" À¿~ÐjtÚ‚n€÷¹D/ ÷a®þ†F0‡uØ cØ?Â_QˆÒS1¸Ûkôrz+½›AÌ}ÌGl=»¹ðPáÄè¢ÑÛG_ý¼=úFf>¿*xFšŒ¦¢>´`}±„w£Ýh:°{G¡TÀxÏnÂ3ñ•øø>†ÿIQ”ŽòÂ3cÔfj;üSǨwií¦£t)=›¾ƒÞN?ÂÜÆ.`W²?e÷Ⱦâ¶æ Wží½sôñÑÃ0FCæ´ƒ·Œ¦Á ^„®”`½•àŒg:¿ƒ0ª§Ñ3èŒíè$àÜ€ƒ\‚ƒ ‘Áy\‹ëaœÍ¸µgžó3÷âyx)^‡×ãëð}ðûÞ ï±~‡ðÓøuüþüNà¯á÷OŠ¥8ÊF¨0%Rð›¿yÔ|j1µ„ZFÝ ¿‡¨ÝÔ~jˆFt=ÝFÏƒß }˜~—þýú[ÆÁ¬f®b~ÅcŽ3'˜¿3§X›a{Øé2›,/= ÛÇ]Ì=ÁG{Æ¿„w:ÿo>ZKÝA}‡ÖSí@g ñS¯Q0ëð>ü@êAtÐG9èâfЍ~ ø] 0,#áP0à|^ÛåtØmV‹Ùd4èuZZ¥TÈyNÆ24¨I‰Ö@Û\ß`xî tt$É~`tÌ;¯cî ºÚ~xΠ\7ýàLμèß΋gŠçÎÄ:_-ªM&|­ßà-ßž9¹Ú7·ú|ƒÃR»Kjo“Újh \àkµ-nñ â¹¾ÖÁ¶Å[[ç¶$øÐS$€ %¹ñ jž·Äj&g´:-­ƒö´áj·`°{rok‹Sú’‰AÜ  ØáîÞÁÀ]}}p¼ãØH¡^·Ä66æŒ9YÇÓÅ»€ºnÑ·u+¹çÔÞ€0xxëVçVBÅý!Œþ½CëBä‚*CxC7\ U@p’Ž€`X}-𨠠×ÙéKøÿÂeçÆ Wfa´e„ËÿA¸âáÊÿ„sçFúWÁ˜sÂùÿ{®>ÂìËH €7á•hµ ͆­öu7ÔRyÄ€c€íSØê`ëƒÍ [#lm°EáœaÛÅÍFCp?;eÉ}™Oá¼ËÚ¥p?iÚd¿ú8ïó\ÐçânFr¨“ôͨîËA†ºê(\…v%lxáGÅ—ë99±uaË稡ÁÏcTèUÝ«ðxceÎ*ãdzÕ`åÂJ?û­ ¿4îl]›šü‰ãª[†éÙ˜Ûy¡°aío ; g-¼›Pó8vƒËKO%Œ§ÆcBãEŸœÂZ'ƒZ©å´2^f´À˜LÊ_jíf‹4¦®éÀ»NŽüpLÖ<ÒICBýˆâ`H\¤2W©×E¨HÎb5è©ö‰“®›Qc¼§}}õäw÷oyÏ/œX¿¬Ã-\~åûx>öÄø6¡woá¿ Ãüü®ð!>š½Æ~…Á4ÅÓ-SS4¯»ƒSšadÛeX7QÛMæ#Âc#¹zx•mlp]Ãùl &®4ƒûW=LU8ÀùÃdÆÊ,f|êÖiƹ㠊撶ꦆÝ¿ G+×—hx.W0¿ÆÒLµSÀKŸ¨@u4v°ÀëØ!¼fIzî Ýç(ÝaÌB7þgANi6H0þpô ü<؇Jl‰R©†‘ó%”]¥~Q¸âÇEpž…&¹sv`&Y{ššÓ馯ŒTMét³tOfôc 0 ÆS/ÚMO2P¦hpÔ!šRŽî)\‚üÈžŸÁ#ìa€6 †Z س¹+_§; Éâ~}A¡æ"vñwpo F‡é=ì\  ºUô?Ž¿R}f¢¢÷Ðgˆ.El^MOàe;<¬f‡EMm1 Qü>Ÿb‹cˆâöø¼éc'‡u§†QÃp¼KóZ± ¹Ua[ÈæC®°.Ä„ÕVE0kªsnh±Zh)íš „PȲ Lë¡ ¾© øÛˆWö£þ A_¡~Zf6Y-Y1f8JðGÂz]®2K­»T¨ßµ«Að‹ƒŸ^³°þòÂ'G¯ÙrÁU£!0Kÿñ¬)|ùÓ¿º¥ÀÖü÷‹#/ì{w`ê©Â>ø…ØÙ G–‹öÓ&6Uš(ÕÈ…ü'~úÛ ¹O¦OÀ}é^ã…&ðO‹zµŠ¦ÞÌòœÊóJÑC8s@¥RÛ­¶gðÿq?ãQÀœÆð²¶P²ë›á3ø›x¼4ƒàÅ,f½Éb5 €žzÀO¿Œ«e© ñ”#ÇÖŽ·ESƒx¹Šícå§'t•0.¬r&}¦Ì­sÁˆA"!úuvȼ!qBÈûKñ#½€ºC{J{ÊİZ™É¬ ™˜8o>‹mv…+4´Í®·Û” ÌÊL²‹5¬Ùô€CD‚SEoÑ?c\²nÀ nÛ•>vBwê$Ì®£î˜Í<¶a˜PW‘)‘a«snÁÜ»âÔ0Ër…JÉjé ,WÁÔ2:(™^]­®öìÔ®Ìñiú ÷¨Ç„6MÊ€ÇÑB¾Ëv,¿¡'—ýõ†GßþSa~}îÄRÇò3´â«ñ‚Gzï‚Ü*ùçûÞ½çÂ[…«R}ªÂ_¥6}£ÿM°KA¢ß.ÖŽ³_ÀQ\ÐŒqy®“[Ê-å×rWñÚ_ *­‚ÍfEtûuj›•2ª¨ob¢_-–c¹a(fW>铉²2Zö4¥M Ñj$ôé?Ù_;r¤éojõE‘PÊoNÅàJÚZ9ŒY}ÖÐôBÕS0㯚æ¼ýöö‘Ã̶‘ñôug®¾¾ðî¹^šãÆÑ/ékØk@w{SŒlrâ Þd†8AÌÊšü&³R%×Z:­ö2ƒÓépB‹aÁLÄe¢'$Àé¤vÇ¢YÐëêTHÍ^ì?¸Ã¹ñõŸbzU-ç•,þØâÑ’³»]ö’)í{æTxßèíö$‹¸Ñ°}޽p$„¶‰ ´]¹ÂÒ9M“–;±³ÍI‰ AÎúwPêÐdÅV û#:ï–H…HhbdÝ…=ð†-} Zui‘&Ð"âø/¶†º¿8 'dÕo;2üõºt?4@ääºæ 3¢üú)3UT˜‘+@A‘p8 ™gÄcÍe‰/©Xä’`À'Y¡,GL`SÃÍUk~R]¾pð²Oþô¯S€–Úg_*üüâ¬[7MXy/æîk_ Èù%[Ù¼7 wÿ®ð÷¾xa[æ¬|âêð…S÷áýðƾòÚ±Fþë¹_aÎôá;¾}¥0Ø”(¯»èžb縊…»–̼5d²—`å᯾;ôJá…‹²ÑXИ—ûx™,a€å EÌWÊì´\í«Áv‹BÆØ|AVÛîUrQó´O«¡ù@£¦©Û¯CSräOŸtØGFl„CÔ¨uC¤L¾¤|Y‰IxVú@m“ÄPœÌ<üKH‘†`Vš8Y1i‘Æf»îHíf]-§«…Jö2hØX‰1è 9° U,É!§HI•¹¬1 >@4ap²€oŒ²üôÂ/5îrEܘŽ5­÷w…¿bï‡Û7uÍ ·,|üÕÂÁö=û2nàØùM>¡ü†i÷/¼Æï¡ ñáé—þöEÄñ×ß8¾Î®y£8Ý-–½ìÄðCüã€ó[ž­ä ‚ÖŒ‚Ó Œ”"Z,E¥ /›ö¼ »0ÂjMÌÖ] ñ’ˆ8®Õlt8Ä0Dí~Zîq{Ý>·àfdLÈâô_–Ãr;¬›Ê!Ω8’8¨)(A`/’ÍédÖ³EK&R<†Ñ›$¯@ ¢Ò®¿Ýû_G)|ÕZZ¸zEKÓ**Š­¿Â³Ö­ïžþ³ÏF^¾Ä7çVpü×lßâÉžþëZU~5}Ë ‘Ïz°0ãîÂ×sj½Õcú*ó2À„øì^/^ˆ\¡5¯(ZV\­qßåpjíØžtÓrF£AFpòÑ€é.«Ù°-ir›4´Ý”ÛB û£†×†wûSQmŠ7n'ãc1Ún[-ïT¬Fáî0¢âoŒ¡ 0ã%€g˜§úOž£âÄÒ"£J‡vÚXQ¥2i`V97/`·Å‚™L<¸=ðë•L < C³¯L;-NøVY©Ä·Nõ÷$>¯[‰p/€…®Î.H½êÄQ­+šRëc¡dX%Ì+E˜W a^‰2/¢ü;ëªüf"öõ&æ ÐË>×'Bê¤.Ýмö…£…wqÉ¡ÉqÁæ•”b‚½¤°ý…wÞüôÀËxœÌÌï+L¾}Ü0A-|VxA£µü¸} š ‡Y“oAaYðŠÝ¿Â­Øsìl·Q×Þ~¯U NyÒOHÖ˜”p-ÐN”à.eŒ&9O ¼É å aàj }’#ÍiB†€3ºÏß1 Ðê"ž£ÒÌyïr¬èiÁºñã×Q³I9òsœÉókè[V6ÊÂaYãÊ3+×äå!‰8Š´ñ*´h¥X·Ð~¹}“ývûƒövÙ÷Ãuœ% »ÕBkh‹‰Qó¶Ý¦”Fìà‘Ígë¶Ñ6‚þ.iÈ„w¸œçx(´à¾n<‚° @z2ðó‚ylèœõI,@âTóÊ.kÄšmÃúÃ3ËœÞû=Á‡eõ‰ú#,MͰ1Í<Ÿrii*e•»\NvÚ\#6‚l}òNåÃJJ9ÍIØã&ܦ.Pl‘t%±Z†ö9¬ëCئÌ!Ú‚DÕ@ ^=‡‘Ä*c‚B¡âsXf€‚ ï9(¸ÀUÔÀœ% (ñz*WIx=øì¢v`*:€qáÌÞ¡Ñ/Þ|jó³o¼ó\á…Ožûµ_Xx'¥D˜’Âë…gpÇK- ö|ñe\E½XÄ I¦pD1±£bÇKŽ×\ÔAû«nÊ *ºç{Õl#7m­(—{¹9ˆç|–܋į$ßšY´:Jd/+ÑM30;8Pd ôÀÏg\ßàÎùu7O¾íÌc—W7^J¹0ƒM…7?ÙÛ¯y‘¹­-l|ÉRÑq¯œ™¨l¿†^sq‹<üÚƒo?CnZ]K„†äOck†Jˆ(þM¼¢Ãñž“ЏŽúßñŸðÿËuÒÏ1~³ß(q…ü¬‹ßå~ÊMiÇ«œ%Ñ Npš¢m(X¢ã”¿?fp»]î ßå ‚Ï6èÎ n™`Pe4:¹”‰ò©¢Î˜Ÿw¹ýf…=;L[“À<¡ÅtZÂpñs0?)ynðö@ˆ ÐÓýGˆŸ¦H‘Pnfuàƒ¨%.92`‰£~ ™ #³†Ø°ÌÀØ8˜‚©à°"^z0.º3Íúïa]FlMW4,0W„8µzÎ/n¸qF¤°a ºq9•Û3ðÉËá‡"ë  ¶U ¢_¦Ž†›ím ØSnd±²m½æ’fy8Ùsâî#ßf²5À–­ªSH°ïýŒº†˜-N‹a}`­â*åVåVÕŸƒŸ…¸N¾OÑ¢” .tƒâõæÐŠwB\åæDuÅz±¯tI)Uº3‘r’¯c½8Ýr‘…²ì £!µ‚a¼©œ‘fR)¹Xî¬ÂKD-rVªuŠ?êärv§ú¸œg/Ø-YQ›sê2ñ¿ÆGÁÍWöú‡ðÕO"]FGéòUécïô¯>aÓ½ÓðíZ7l;is ŸNÃáŒyì8Ƭâ1®ûºŸÈüs•«¤é(÷%YCPãïAòL›„Âg€]@¢ iÔ|‰¢Ç¢r…,Áô Aïí!x‰>ŠDBx Ñã!æG42}i æMÑñ3¦3€F )°`/–ÒÄ3DB_WÞvå oéHß¹{RzÆ›»ÚŽjÂn¾$YZöÑ%ÓÖe2 ÷?ÚÚògçüZ´3É:X’pßÖ)·\½|ÁøôìeeÙy—ßûfkP(L8zßüÞIUùúå‹gô^±óýŽ„ï§¾„G#fhÊ ~üzÙ+´“ÚwSÀ×`iÅ «$¼ØKQúñNuÒÏCü"0¾bqRV£’ x^¯–SàV«x;ÐÅ^ªa^Ôp|ÌàÕÏÑo×ïÖ3zèÚ‹:­‡Àð¶¥A¥ouíÉ“ç¼s’t–È}X+éðÀ—ûûuÃ_“àQÚ㠤΅r$èD™ë•¥Áå{W¦ñصâª]WyËØÎÂÌ?ýQ3BЦëtჄo¸@&ýÞ‘d$üDœÕã˜æìw÷yîRÞåyÐù´û;¯<Ä…”•\¥²•kUNw,q.q/ñ<ê~Ô£ÕEýÖ‹@uòk."J“ 8CÑ8F&2%O¹äá°Ï¦Q'l`.3¢à÷— ÷D#gyCQ*Ê.p8Hª S`ÆE%„ x‘…»Š"h¬‹š7Ж˜òÙéé™îøøšqW û¯hl]MæVެÜ9óGf¡Ì÷(ÃaußΑ¯ÞYóÁû«Ÿ£6¬h‡¥ù–~Á­XTAVßÈìD:l²ûG±Š«Ue}‹ìKœkìW8oG·ãíÚíºуø!õníº‡B…÷£ýøiíÓº'CO†_ ½öKw†ì†³sŠËàL¦4©ˆ'’É…Bž†½TJ™-¯¨(ÃN4Àœúgíagèá­SUœÁgÎY­!G• ®Ù'/+õA-Ns¤’¾L©§4aË%ÉdÂàp8•©T j{EYY úùвRž©Ê¤’v¥B&w–„™HÌ$¹˜Š²ªP¤;UVšJÊ«ÁÂmû}ÈOƒCh’ãD…Um¨¢ªìùê!ü§}ŠY’´ßaïqØF 9/:Œ eXr#C Ê%‰kÀ»ÌngÑÿÞ ŽgàõÀ…È5›ä8ú*8ð‰¯ÕÔòPÃÎfž8“úW…K6‚'ir’gÑb•cðÔ>C´;èãhȤˆÐ8 ÄôáÑ:GJ©ÄÑã󜕾F*ØåNñ:ȱFpzxjñ9w¹ãxÏUÞ©' G½· .ë™ ¸EÉõISØs¦@5ý³Üqá0Vè+ Î’D=Y“rèòµ‡y½»}dûW…›†©3?ûðpt3KÐhÂìý€wÄ·°KWÂçùVG«ÀüØòãÅs¼\ž0XmVžãb†`0„+ ØÚ¶ 7‚uF:âŒéåu9ݼUnàm\0ÅŸמ+ÊÛcî¨-扞Áߢvȱ’£’ôÉ“¶á‘áüxúºˆþj€0+(ËVIY®KùlÍC”•èËREÀúWbs˜3,¨7çÁõ|~„%¥šZÚÑ¡2c`ðeÚÕ‚×—N˜Sx»kÓÈol.œ¼qE7|6L9âꈯÇoºÃò„FÀ¤ýÛ e…•kj8pê5o ð ¯_ÆÀѨâ¬7ÐûAçQ#V‰}>¦¸H›ŒRîQÜ“Tñ¨òõ3ò×䯧_Ï|(ÿ0s¼ôkùpF;ƒO”–X]^“eµZ¬W–ªÌ—&´ $3ñ¦lˆKÕW*ùú:e#טè”鯱tm,]²»„*¢¨h¶Eœ-þ&¦E„å/{š›ˆ~r„Dbk?XŽÔž vd%CÖÐEüäÃÄ“.!¹$GkêQ•sTH–… a¬Wãê2­d±Ã:ŽDi cŒ4Z¶÷ }Ää9'NAé$ñ»âD¨ˆo üªÒEk0W*ªG™/H`8a ‰X8DÜ’ñ)V˜ê¼¬s[m$Ó´¶€~2 Mþ‹³©”"dv'3O<üBkˆWǬž/TUÝRGO¨¼`ÊôõxUNõ­¼ x^í¢ž‹¢ÍgZ•ç«,êš`ÛÝë[¯+,¯¶D4Îòˆ=Ü[×ä«\ÛOÁâBĹž…õ%6F7‹%ߨ°L…ïQã›»‘ o ÈBd–ÊÌJ õJÎ9_¯ô´h†(FBYÚt،ͯ[ ’ÈïÙì’ÍtøHÊ…¦Àæò©t>•'Œ]:( "Æn­L²…ÆÀiu`5ë#а”7!¹7¤¸1¸U9ÊQ>ëŠÛÞ*üýÃåïùª±|kùM›×ßܾ…ù—ß!Êd#Û3ñνôNá7½ F¨.==/ù›Ûo™Ñ\ Š0H :éÝ9ÏØ¸­ðGôïéß³ýIÿ¹‡«P‚ V.•/U,1/±\)_«¸Ò|¥Eå­6N¡³Ú(«ÍÈ)Ô¬: ±ÈÛÀZlt)TSÀ žj_H×¾j¼'$ت;eÈ$îüØYG€¤Ž9¨nAa@ØàÖ…‘F€B¡÷ÃHëS‡¥t QáÀNœhÚI…“t6IbKÙbTå PWHe­â*Wýì‰ÛONU»ò k·ß÷7,{%AïÞØ%ä3©L…Åüòƒwþ­%Ò£¿¢mÓ©ßþ2‹$ü(Ø ³À/«Ñâ²»¢F_¾šø4q2!CËRW§nLÝ›z,þxê©øÓ©7âÇR/U}ÿ õn•†ŽOˆQ^yœéV¸”ÛôŸµÛíòÜ*”Aceü‘²tÀJ³åÕŒ!©ÇåÙ$W]‰J?“6DD)ÂŒÖæZî/Á@ÿxOm €°`ØRʧöpÃHpD σ—•dÜŒUEd«ÈG‰\å£PTÆËø*V}²å‚A³I9àš ž~4›é¢3Ö,Ó‚£B"Sª¢Ü5HŠÑЩT]4ä̪ Þ)É™~]H‰Z”¯UiQÊnüW7w×oGž¼lîMëoºý§ôŸ9„ëëR-˜U«¡–ä×Öœùuc9¦*S#¿ªÎ‘Äܿǹ3ÌŠá'®½ø¿Øyxotô Xe³ üh$ãõ÷bÿ~©j¹áóUÜZþJÕ:ý5†u¦uæ3šSZu?W„yÙðó¹üOZ¾Ž„óm´\AÉ´ Óí´Ìåšï6r·Ê~.£dj¥ÛBÕ­û5ø× özétô^O{û y°\ŠøK¼Þ„¿JÑG¢CÀÿ—hœˆ5‡a“Aâ¨àŽ÷`»ÕÐadÑ» ¡`´2iÀª<ËO‹QÀlXñ0$`)A`Ï  \rÔ…ïŒ\¯xîÚ%Ûê±?þâ™7þëùÇk}üÒYzY’Þõâ¾/Þ¹t¡êš÷±ëЫ88na唥½ãHL˜p9ŒÖˆ¹œ‚xvE €¦+üqPhp…>Ð6ZlúÛmY%ö²y›“ÉÂ!íñEq´è”t i. <ëÀ#iÉ~8öM^WtJ‚rMlí"ï–fÓ±e ^Šly1aŒ~‰ÉÅÉܘäÁHfEtiócŧ|Ð{cÆ™´zMØ?Á©=ýmÝÆ‘¯\lërêÚæû—½ÝV#”³»3Ú8Ü<²|Ùdµƒ* Mô ÀÏŒ¨VVÍ@o‰óÆ5u4ߨtCó.'ËFÙœ¼ÙÑœo^J_Rõé!›¼Ñ¨Ku$âÆö;©ð]c™öéØtùdÐh©éÙolRìùkŸ”áðÙ9ª>¯™1#l™0y[x‡1A¢ªÍVúúRu­ äQýFÔÔšÚ¢³d,Û,;, ¤—ŽîéëMé“"üºcïŒ|@É9*ÐÀ‡ý£ÒPH‘ï"aK;@åE0Κ¯Äÿ$Äð½[ƒÍ³¶k¤hÌf¥ 8ñ±Ûº'©ÈA9ëV’ÑYúÕg¯|è­iå? Mñ[.´©Ò™È§vœlî1ªž0(ôÏî°7ºç´¥ª0žugaûþg;›T)k´uå7¡Úy+/ fó…ˆ—Mk òY±†m+©È=s/ÿM+=¹Ä[]¾êyù…^ŸVáNß{ÿ3× ¶¶Ô¨ zo4Ô·Àäɬ™ó_ý¥W¾@u¾Bö;ýÈæ :(ZZ-ø[+–[Vð5ëÒÞ hpÁêóÓe@ð7ã :\_ ÞàJûgÙn,Ç=-‹dY‹"õf.“özÁ@Úè`™.OC¤ fGŠLHp™8βXBâE!NôÀf‰½BҒŶ!’l Y#0˜Ž WóÉ„y¶…¹¤3Ÿ¥LÈ1‡½aJÖ]¥4«ís©†ÒÞ‹~^ã+P˜4£¬qæÄ[Ë{ í.eÍ¥ô᪠š ªC¼‡¹§Ã_»¥ãòÂ⥢ÂåRU_Šo‡¯Wè ÆU*B ãÝS€£tœ~1PiT®2|6Ÿ®Ûê²Ýêòy!_Ìâoóœ Iãô)og#^ßG:-¡ô°~¼•< ]’{­(qt߃líJ)¥QÒõhÉ)9%¹ ‚jD™‘Èû‘ÚD¼®.ž¨Ýpq•\›QšËâ»[]<•›Wp°•õuÒÑÓzEÅåø£F{ŒÑx5y·ŠãGÊVU“€ÀëŒn-ˆxôN)´I 'x—ÏÜít¹nTjeÚR…(yÓÌjâ&ò"x§ý`Úd&Á”´ô6Ÿ2$Þ'’l3æø ±K"F¥ ö„J´z†Ä^mÌàAÚˆÁƒõ%P‰CPU6@ˆÏyª¨‹œ“2ÿçá?ž…ÂÛóà 5ÆŽ´&iëñÎOÖ2‰î?¿,`ÔÇ ¨¾ýçúq‰E¡ŸP·¶4*8¯KЛeü™OÌÛ[[&dV`5 =Ê®DUè7â@[°×7`Þd~Èüeð» ÇøÂ¾°PéË }¦¾Ì"ßÒÌÝf…à÷ç &Àl øEÿTƒPj2—fÌSii–R‚Æö5-ò`e¨2F‡]U¹ˆÂ\ Çiw CEÊÜs#"‡#t¤:GhQi*MWù”ǃp U':ˉ`›€ðacð_—–|²Äà#–ßÉá3äôB?Çëq¤lð`üI6ö˜ØË–0 rßô!b‚MÂ&Z 9‚$•ƒPtž¡0së2I£K?sQG’þ±ÙcNVã+¶üªæÐ·M.4ô.…¼ðZÖ3® ¸¸²©ô—íaŠrÙœ6-+?óäI§OeUÑ.×¹§òoCk9‡‹Â*Ò¨Âw~Ü âÙ°'Y {5øì`ÑÍÈeõ->ƒê8S­t©¶ô؃“­xåÐ~½!M3„¢ÀûŒF"'@1]zŒ”мcŒ|*sä%â)éoRšê4‚}ós];»àrÉóSé·›ì%2™¬U™NOž‘å€J0É©•ÓÀJóïDW¥½ÜGé}k¨I±Iµ”®F×åH7ä’Í®ØsðÝ?ÁÚs¡Z˜Å ~¦¹&ú‚ÁjWÔÈ5¸j|qÕ®._@åc»á•nÕ6sæÄqÍb®2tšXFÕ:Ѩ-k­·–Õ{½V-7±«¶&UtF¢ªKÝ’|+Iu$‡p»¨n+séÆ[Ä·DªC„ž'Ûcd\š• 2‰@å„nàä@¿ Às®AàDþ „8"+ѹΦfÑlÑ&Õ§Àc9g#Bî<Í”œYðÔ[ S"û󜙒Kt­ï:Û#LtD#I³YÓÙ˲ÔümÕùÌãssæï¬ô6L)ÔÍÈ™C—4Š¡Êü¬BÅœr“pqÝ@²¢¯wpF÷ ŠŸbØ€MÝ¢ÐlžÙÚnì ÖÿhüŽÂ¼ö,ïpñ•Sñîy©)q{®€&O£UËõØvOõ…Í•#M¨Æ°è xÐú§ô/¥U[OŠ}vG—ƒºCó£WЕy³i¡A`C .Áç'Șõ]Õ.Ÿ/¶O™Â"VjSÉËÈÐ\Ö Õ[#Z.[&øå\9ä,”3NH©AOV"©4MC¾óèžÊ æZ±o!p?RK¼ d: ÎBnE¦I&€ígŠÂ1µ9¢¶0(¼Žˆ=ö½pìgÑ»“YùOÓ!i'c³Cíy•±FnÔÄîžÍѳÊ'Nk©º¤º¥Ð3®Zœ^Sç¯[ øC—¼b`±(9 *ó*ä·M÷•F&¼XHvˆØåRÔ]„›¾2j­y«£”r$iT>úGÐwŒ$«ën/É?“Swèî¶ìÐ=fùFÁZ‰±Z{Ótl5oËÚ)Îå•vs‹] ÀÔA§¶E ‘+b-8c†š!/ Ù #¬ê kÃÈJ›ÃX/‡–‘ƒ–ÙÂØÂ@¡SÂðI(‹QI—èwÊ")Vê…MÊù-§¹ò‘—_ÂÌ™WNá¾ê;oY±öž[CÔØX8óþËïëxß_~Áö޽ù𸬖à\Ò‘÷@~oû*å•Âö»C»BFND¾‰ðŠ¢ âÖ öóºfµ+{<˜jv•}°ùô’Òà„µõ4›Ò¥bÙ¤W¯R°”ÇÉ×8'GÍ)³e¶2‰ÀMRá$ÒÖaA£Šrž³n¢a¿Š ÐóÌØ±´[0 nÓ(Æ\ &B…‘ òµŠAÑb8n¥”šUÔfÁ+2“/çë\"h‘¼ñ¼Em—ܽ}Éø+ /ÌΆ²J£a{„e›ÊfÎÙúò_TÅÄʦåýêæß:xA¢ yLÖ2Ž>]QãÁ’MNã=ا÷{e=HÐy%×4àiÑmÌž ð‚s°¸lµŒXÌç²Y{Bt·è>$ÓÀKk¤ms猲†W­Þ±¶âÞ “Ù8¯É_y[÷ÖëÞÝsKí]•uà®YU·bjSÉÄØ´é‚Û¢ eá/ó*L¯žÕѾúž;¢z}pÓóRÃìÕj†X"×c§Ÿ2Qy_&*E;W¯UŠ A=°h›J›œ6QŸ0YzìCÇ+Žë`1ÉÈ‘cÐÔ½ÄHÞqØ^q4“RÀÀ@"OzÌ—NÜuÒ’EIŒ{pâ¾GÉQj[[°Âï°”¯®(±.cY¹­µn¥š¥ïé9ìód^¯0*ýšý1À§26…¹p&oÎ;óBµ_&çàKyZÞ$ÏØü1ÿÓf“–WÓ&Gåè#+«pd2yC2ãt9]“¦”çÁŽ%-ÙTC™³ÎH&§ü~ÁŸÌT”9á“à2«múP´ iX½«:¢“ymÊZO™!ICÄô’QÝn–ÁLÞ‘‘!éñåq>ìò')! _9Ðîƒå5é—V€‰8ýHGüu+‹í3ÀßHï{DRŒÅ3ÇQã#Gâº#ú0nÁÀ%- c’M°&aÍâ €Q›£Vš€0D‹a`¤¨&ID éNœ3Wꢇj«Õʃ{U®T¢`÷¹ ‡™LEý©ð-ű*ªðn©/W¥Jc¶ÐªýTÜdʦðNúZÎ1'=…ÞëºÀrÈÜn6Ü~æ+9/c¨ôÈoYê?®s0‰ö˜{ecá¾VeZO˜±yUxèëÄCæ0|‚ “OTà•¦2îÊ^¡×ß°lf6³]ÝGeŸG m\‡¶C×ne*+r /STȬ¼BsL¯&³ÆÌÑX.%l•¹ E.`ଭN»Cö ì ì=cM2Ør\®"°š2¾¬k tµK§¯¡‘Ì.£.W¦”†T~™ÂÌÔèõãjȹ5z™³”¨Pu¥µé—>| R“¬°ì¨¸Ü5XkÏ€gB*ÉTŠƒÄÍx?ÔP‘¹“¦Ow„‡u%°Á¤ŽÍ¨ä°æóìDëó{/ÅØ‚ÉKI0$È"Ùõ 0AΙQ|<\QáŠ×¸KK¸)Ûë| óÙöTa¾Ûê ‚úfëN·Æ[^x¿²<þ—ÃÕ‰ñô.lô{SÍ“Sã-ø+˜t䟅S”ËEQ6ƒ±Ñ—sÎõŸNzFçr)ýõðÝ·À 8 ÀáWé×Ç“Ü—δcB%Ñ’Xb¼¼Å9>1ݹ8±E±%qWâPâw MGGâŠD¨_©Ìl žÊåS ‰Dc´ß~¹¤±äcXg³¹È20‰jB.üP™-¥Pù ß`õbc,¦-rÇeUÖ$‹,UW˘Âa¶ Hßéż:¬q»G¾¥”|•Âaƒ”+/›Šyîýªê¢Y0@r‡‚Ú?B Eý«è`À|¯åaq–•z‰¢”S â`S …RÇa®Í \fGa,BÇJ½2¯—) Eåå ™z°&S”¹>"r»9ŠgR5ˆZ|ÜC×ß¾[1¨8 + LF-È¡8!%Æ­x´+hÛG¤l ?òx¶–|$$NEBU„ç8Žd‰åزsX…JT \ˆ®y;o›¸Î|K '/iRø:à¶3‡;oå _Yéæñÿ>¿kññµÔµôëÄ^>„X|r¯RÍá“{(Uú‘c( *ÛÙˆѳþ¼ë±µkÙµ_ûø•kwíZ{%ùþ| †)a/EMèq‘—Ï‚ãþ¸ä°h:,ip¥Žj›]Çm°×êË…µ¿%T›-¡™\S ¬=åò~ŸKw»1«@`rÄ™äæ;vNÖÔ˜†ùŽ”dËÓ¡H‰£¥¦v*CßÆÚ›[†ð”}ÂÊ}Å—DÛ€ªÀ§>¤%E×ñoœ ÖÓYÿaÄùÿDï‡‚Øæ’b1Ù /Æf±™m´Ì$·‡‘7‚a fÃÆ’‚]•`©Ÿ§lÁÈZÂùÏw6iKRuš…¦‰õ·ÜB}ôǹ;âBêÊŽqÓ‚&†ú}ò.9«`0Æ5“ õsS±¶R[û¦¸³«Pï¢+—RwÔýÓ½µÞäc¥ÍeË~Ê0XÇ+å¥%–ËÈ_–T)\9œåjÑp‹‘9fâ1$úžô7º-,¶þ­l„}øJ ̺ ‘¯Œ'«¾ÿ.‘CúYíöý׆ÀYŠ_:û¡jø¾P |³ 2ƒÈWÇKß}ìOå$øód4¾Ð8 õHÑ»^øVãLt|²mF‡a$2„¥‘É …¦MŸÔÓÔŸ¶dÙÂË’S–/›wéÿ1™nM endstream endobj 49 0 obj 17672 endobj 50 0 obj (libsynthesis_contributor_agreement) endobj 51 0 obj (Mac OS X 10.8.1 Quartz PDFContext) endobj 52 0 obj (Lukas Zeller) endobj 53 0 obj (Pages) endobj 54 0 obj (D:20120917093640Z00'00') endobj 55 0 obj () endobj 56 0 obj [ ] endobj 1 0 obj << /Title 50 0 R /Author 52 0 R /Producer 51 0 R /Creator 53 0 R /CreationDate 54 0 R /ModDate 54 0 R /Keywords 55 0 R /AAPL:Keywords 56 0 R >> endobj xref 0 57 0000000000 65535 f 0000059432 00000 n 0000004531 00000 n 0000018337 00000 n 0000000022 00000 n 0000004511 00000 n 0000004635 00000 n 0000008772 00000 n 0000007523 00000 n 0000031867 00000 n 0000028624 00000 n 0000040483 00000 n 0000018902 00000 n 0000004787 00000 n 0000007502 00000 n 0000007559 00000 n 0000008751 00000 n 0000012398 00000 n 0000008808 00000 n 0000012377 00000 n 0000012520 00000 n 0000017348 00000 n 0000012743 00000 n 0000015893 00000 n 0000012709 00000 n 0000018729 00000 n 0000018491 00000 n 0000018300 00000 n 0000015914 00000 n 0000016158 00000 n 0000016177 00000 n 0000017327 00000 n 0000017385 00000 n 0000018280 00000 n 0000018427 00000 n 0000018608 00000 n 0000018664 00000 n 0000018846 00000 n 0000019301 00000 n 0000019541 00000 n 0000028603 00000 n 0000028799 00000 n 0000029050 00000 n 0000031846 00000 n 0000032253 00000 n 0000032491 00000 n 0000040462 00000 n 0000041167 00000 n 0000041406 00000 n 0000059169 00000 n 0000059191 00000 n 0000059244 00000 n 0000059296 00000 n 0000059327 00000 n 0000059351 00000 n 0000059393 00000 n 0000059412 00000 n trailer << /Size 57 /Root 34 0 R /Info 1 0 R /ID [ ] >> startxref 59591 %%EOF libsynthesis-3.4.0.47.1/m4-repo/000077500000000000000000000000001226375725500161275ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/m4-repo/dk-warn.m4000066400000000000000000000071251226375725500177410ustar00rootroot00000000000000## Copyright (c) 2004-2007 Daniel Elstner ## ## This file is part of danielk's Autostuff. ## ## danielk's Autostuff is free software; you can redistribute it and/or ## modify it under the terms of the GNU General Public License as published ## by the Free Software Foundation; either version 2 of the License, or (at ## your option) any later version. ## ## danielk's Autostuff is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ## or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ## for more details. ## ## You should have received a copy of the GNU General Public License along ## with danielk's Autostuff; if not, write to the Free Software Foundation, ## Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #serial 20070116 ## DK_ARG_ENABLE_WARNINGS(variable, min-flags, max-flags, [deprecation-prefixes]) ## ## Provide the --enable-warnings configure argument, set to "min" by default. ## and should be space-separated lists of compiler ## warning flags to use with --enable-warnings=min or --enable-warnings=max, ## respectively. Warning level "fatal" is the same as "max" but in addition ## enables -Werror mode. ## ## If not empty, should be a list of module prefixes ## which is expanded to -D_DISABLE_DEPRECATED flags if fatal warnings ## are enabled, too. ## AC_DEFUN([DK_ARG_ENABLE_WARNINGS], [dnl m4_if([$3],, [AC_FATAL([3 arguments expected])])[]dnl dnl AC_ARG_ENABLE([warnings], [AS_HELP_STRING( [--enable-warnings=@<:@min|max|fatal|no@:>@], [control compiler pickyness @<:@min@:>@])], [dk_enable_warnings=$enableval], [dk_enable_warnings=min])[]dnl dk_lang= case $ac_compile in *'$CXXFLAGS '*) dk_lang='C++' dk_cc=$CXX dk_conftest=conftest.${ac_ext-cc} ;; *'$CFLAGS '*) dk_lang=C dk_cc=$CC dk_conftest=conftest.${ac_ext-c} ;; esac AS_IF([test "x$dk_lang" != x], [ AC_MSG_CHECKING([which $dk_lang compiler warning flags to use]) case $dk_enable_warnings in no) dk_warning_flags=;; max) dk_warning_flags="$3";; fatal) dk_warning_flags="$3 -Werror";; *) dk_warning_flags="$2";; esac dk_deprecation_flags= m4_if([$4],,, [ AS_IF([test "x$dk_enable_warnings" = xfatal], [ dk_deprecation_prefixes="$4" for dk_prefix in $dk_deprecation_prefixes do dk_deprecation_flags="${dk_deprecation_flags}-D${dk_prefix}_DISABLE_DEPRECATED " done ]) ])[]dnl dk_tested_flags= AS_IF([test "x$dk_warning_flags" != x], [ # Keep in mind that the dummy source must be devoid of any # problems that might cause diagnostics. AC_LANG_CONFTEST([AC_LANG_SOURCE( [[int main(int argc, char** argv) { return (argv != 0) ? argc : 0; }]])]) for dk_flag in $dk_warning_flags do # Test whether the compiler accepts the flag. GCC doesn't bail # out when given an unsupported flag but prints a warning, so # check the compiler output instead. dk_cc_out=`$dk_cc $dk_tested_flags $dk_flag -c "$dk_conftest" 2>&1 || echo failed` rm -f "conftest.${OBJEXT-o}" AS_IF([test "x$dk_cc_out" = x], [ AS_IF([test "x$dk_tested_flags" = x], [dk_tested_flags=$dk_flag], [dk_tested_flags="$dk_tested_flags $dk_flag"]) ], [ echo "$dk_cc_out" >&AS_MESSAGE_LOG_FD ]) done rm -f "$dk_conftest" ]) dk_all_flags=$dk_deprecation_flags$dk_tested_flags AC_SUBST([$1], [$dk_all_flags]) test "x$dk_all_flags" != x || dk_all_flags=none AC_MSG_RESULT([$dk_all_flags]) ]) ]) libsynthesis-3.4.0.47.1/src/000077500000000000000000000000001226375725500154335ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/DB_interfaces/000077500000000000000000000000001226375725500201235ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/DB_interfaces/api_db/000077500000000000000000000000001226375725500213415ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/DB_interfaces/api_db/DLL_interface.cpp000077500000000000000000000137571226375725500245200ustar00rootroot00000000000000/* * File: DLL_interface.cpp * * Author: Beat Forster (bfo@synthesis.ch) * * * General interface to access the routines * of a DLL. * * Copyright (c) 2004-2011 by Synthesis AG + plan44.ch * * */ #include "sync_include.h" #include "sync_dbapidef.h" #include "sync_dbapiconnect.h" #include "SDK_util.h" #include "SDK_support.h" #include "DLL_interface.h" #ifdef ANDROID #include "android/log.h" #endif #ifdef SYSYNC_ENGINE #include "syncappbase.h" #endif #ifdef JNI_SUPPORT #include "JNI_interface.h" #endif #ifdef __cplusplus namespace sysync { #endif // ------------------------------------------------------------------ #ifdef PLUGIN_DLL //! derived class for DLL access bool TDLL::Connect( cAppCharP aModName, ErrReport aReport, void* /* ref */ ) { fModName= Plugin_MainName( aModName ); return ConnectDLL( fMod, fModName.c_str(), aReport ); } // TDLL::Connect bool TDLL::GetFunction( cAppCharP aFuncName, cAppCharP /* aParams */, appPointer &aFunc, ErrMReport aReport, void* ref ) { appPointer m; /* don't overwrite if "" or in case of error */ if (*aFuncName=='\0') return true; if (!DLL_Function( fMod, aFuncName, m )) { aReport( ref, aFuncName,fModName.c_str() ); return false; } aFunc= m; return true; } // TDLL::GetFunction bool TDLL::Disconnect() { return DisconnectDLL( fMod ); } // TDLL::Disconnect #endif // PLUGIN_DLL // ---- Handler for DLL connection reporting ------------------------ static void ReportPuts( cAppCharP aText ) { #ifdef ANDROiD __android_log_write( ANDROID_LOG_DEBUG, "ReportError", aText ); #else ConsolePrintf( aText ); #endif } // ReportPuts void Report_Error( cAppCharP aText, ... ) { const sInt16 maxmsglen=1024; char msg[maxmsglen]; va_list args; msg[0]='\0'; va_start(args, aText); // assemble the message string vsnprintf(msg, maxmsglen, aText, args); va_end(args); // write the string ReportPuts( msg ); } void ModuleConnectionError( void* /* ref */, cAppCharP aModName ) { string s= "Can't connect to library " + Apo( aModName ) + "."; Report_Error ( s.c_str() ); } // ModuleConnectionError void FuncConnectionError( void* /* ref */, cAppCharP aFuncName, cAppCharP aModName ) { string s= "Can't connect to function " + Apo( aFuncName ); if (*aModName!='\0') s+= " of module " + Apo( aModName ); s+= "."; Report_Error ( s.c_str() ); } // FuncConnectionError // ------------------------------------------------------------------ static TAccess* AssignedObject( cAppCharP name, bool is_jni ) // Create object for LIB or DLL or JNI { TAccess* d = NULL; bool is_lib= false; do { #ifdef JNI_SUPPORT if (is_jni) { d= static_cast( new TJNI_Methods ); break; } // JNI (Java) #endif is_lib= IsLib( name ); if (is_lib) { d= new TAccess; break; } // LIB direct #ifdef PLUGIN_DLL d= static_cast( new TDLL ); break; // DLL (C/C++) #endif } while (false); if (d==NULL) return NULL; d->fJNI= is_jni; d->fLIB= is_lib; return d; } // AssignedObject static void FreeAssignedObject( TAccess* d ) { do { #ifdef JNI_SUPPORT if (d->fJNI) { TJNI_Methods* dj= static_cast( d ); delete dj; break; } // JNI (Java) #endif if (d->fLIB) { delete d; break; } // LIB direct #ifdef PLUGIN_DLL { TDLL* dd= static_cast( d ); delete dd; break; } // DLL (C/C++) #endif } while (false); } // ------------------------------------------------------------------ TSyError ConnectModule( appPointer &aMod, cAppCharP aModName, bool is_jni ) { TAccess* d= AssignedObject( aModName, is_jni ); if (!d) return DB_Forbidden; if (d->Connect ( aModName,ModuleConnectionError )) { aMod= d; return LOCERR_OK; } else { aMod= NULL; FreeAssignedObject(d); return DB_NotFound; } } // ConnectModule TSyError ConnectFunctions( appPointer aMod, appPointer aField, memSize aFieldSize, bool aParamInfo, ... ) /* Connect to DLL (or LIB if = "") */ { TSyError err = LOCERR_OK; TAccess* d = (TAccess*)aMod; char* p = NULL; char* q; appPointer* m = (appPointer*)aField; bool notEnough= false; bool tooMany = false; if (aParamInfo) aFieldSize= 2*aFieldSize; // do vararg handling va_list args; va_start( args, aParamInfo ); // the element before the open param list // now go thru the list of all functions and put them into the list uInt32 ii= 0; while (ii*sizeof(p)<=aFieldSize) { p= va_arg( args, char* ); if (p==NULL) break; if (p==(char*)XX) p= NULL; // XX is equivalent to NULL, but not termination of the list q= NULL; // if aParamInfo, treat them as a pair

    must be earlier than if (dt>aSampleTime ) dDone= true; if (st>aSampleTime && st>dt) sDone= true; year++; // search in next year } while (!dDone || !sDone); //lineartime_t lt= seconds2lineartime( t.bias * SecsPerMin ); string offs; timecontext_t tc= TCTX_OFFSCONTEXT( t.bias+t.biasDST ); ContextToISO8601StrAppend( offs, tc, false ); // now concatenate the result string aText= "TRUE;"; StringObjAppendPrintf( aText, "%s;", offs.c_str() ); //StringObjAppendPrintf( aText, "%+03d;", t.bias / MinsPerHour ); string dstStr; TimestampToISO8601Str( dstStr, dt, TCTX_UTC ); string stdStr; TimestampToISO8601Str( stdStr, st, TCTX_UTC ); // s must be of the format stdName;dstName here, for example CET;CEST or PST;PDT aText+= dstStr + ";" + stdStr + ";" + s; return true; } // ContextToTzDaylight // ----------------------------------------------------------------------------------------- // Get sequence between and . If these strings end in \n, then that character // matches arbitrary line endings (in other words, \n, \r, end of string). static string PeeledStr( const string &aStr, const string &bv, const string &ev, sInt32 aNth ) { string::size_type bp= 0; if (aNth==-1) { bp= RfindProperty( aStr, bv ); if (bp==string::npos) return ""; } else { sInt32 i= 1; while (true) { bp= FindProperty( aStr, bv, bp ); if (bp==string::npos) return ""; if (i>=aNth) break; i++; bp++; } // while } // if //string::size_type bp= aStr.find( bv, 0 ); if (bp==string::npos) return ""; string::size_type ep= FindProperty( aStr, ev, bp ); if (ep==string::npos) return ""; string::size_type bpl= bp + bv.length(); return aStr.substr( bpl, ep - bpl ); } // PeeledStr // Get the string between "BEGIN:[line end]" and "END:[line end]" string VStr( const string &aStr, const string &value, sInt32 aNth ) { return PeeledStr( aStr, Property( VTZ_BEGIN, value ), Property( VTZ_END, value ), aNth ); } // VStr // Get the value string between ":" and "\r?\n" string VValue( const string &aStr, const string &key ) { string res = PeeledStr( aStr, key + ":", "\n", 1 ); // strip optional trailing \r if (!res.empty() && res[res.size() - 1] == '\r') return res.substr(0, res.size() - 1); else return res; } // VValue } // namespace sysync /* eof */ libsynthesis-3.4.0.47.1/src/sysync/vtimezone.h000077500000000000000000000061471226375725500211670ustar00rootroot00000000000000/* * File: vtimezone.h * * Author: Beat Forster (bfo@synthesis.ch) * * Parser/Generator routines for VTIMEZONE * * Copyright (c) 2006-2011 by Synthesis AG + plan44.ch * * 2006-03-06 : bfo : created from exctracts of "rrules.h" * */ #ifndef VTIMEZONE_H #define VTIMEZONE_H // includes #include "timezones.h" #include "lineartime.h" #include "debuglogger.h" using namespace sysync; namespace sysync { // forward class TDebugLogger; bool VTIMEZONEtoTZEntry( const char* aText, // VTIMEZONE string to be parsed tz_entry &t, TDebugLogger* aLogP); /*! Convert VTIMEZONE string into internal context value */ bool VTIMEZONEtoInternal( const char* aText, ///< VTIMEZONE string to be parsed timecontext_t &aContext, GZones* g, TDebugLogger* aLog= NULL, string* aTzidP= NULL ); ///< if not NULL, receives TZID as found in VTIMEZONE /*! Convert internal context value into VTIMEZONE */ bool internalToVTIMEZONE( timecontext_t aContext, string &aText, ///< receives VTIMEZONE string GZones* g, TDebugLogger* aLog= NULL, sInt32 testYear= 0, // starting year sInt32 untilYear= 0, // ending year cAppCharP aPrefIdent= NULL ); // preferred type of TZID /*! Convert TZ/DAYLIGHT string into internal context value */ bool TzDaylightToContext( const char* aText, ///< DAYLIGHT property value to be parsed timecontext_t aStdOffs, ///< Standard (non-DST) offset obtained from TZ timecontext_t &aContext, ///< receives context GZones* g, timecontext_t preferredCtx = TCTX_UNKNOWN, // preferred context, if rule matches more than one context TDebugLogger* aLog= NULL ); /*! Create DAYLIGHT string from context for a given sample time(year) */ bool ContextToTzDaylight( timecontext_t aContext, lineartime_t aSampleTime, ///< specifies year for which we want to see a sample string &aText, ///< receives DAYLIGHT string timecontext_t &aStdOffs, ///< receives standard (non-DST) offset for TZ GZones* g, TDebugLogger* aLog= NULL ); // ---- utility functions --------------------------------------------------------- /*! parsing: * Get the string between "BEGIN:\n" and "END:\n" * Default: First occurance */ string VStr( const string &aStr, const string &value, sInt32 aNth= 1 ); /*! parsing: * Get the value between ":" and "\n" */ string VValue( const string &aStr, const string &key ); /*! Get the hour/minute string of */ string HourMinStr( int bias ); } // namespace sysync #endif // VTIMEZONE_H /* eof */ libsynthesis-3.4.0.47.1/src/sysync_SDK/000077500000000000000000000000001226375725500174645ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/sysync_SDK/DB_Interfaces/000077500000000000000000000000001226375725500221145ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/sysync_SDK/DB_Interfaces/demo/000077500000000000000000000000001226375725500230405ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/sysync_SDK/DB_Interfaces/demo/DLL/000077500000000000000000000000001226375725500234535ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/sysync_SDK/DB_Interfaces/demo/DLL/target_options.h000066400000000000000000000014101226375725500266610ustar00rootroot00000000000000/* * File: target_options.h * * Author: Beat Forster (bfo@synthesis.ch) * * Programming interface between Synthesis SyncML engine * and a database structure. * * Copyright (c) 2004-2011 by Synthesis AG + plan44.ch * */ #ifndef TARGET_OPTIONS_H #define TARGET_OPTIONS_H /* - find out target platform */ #ifdef __MACH__ #define MACOSX #else #if defined __MWERKS__ || defined _MSC_VER #ifndef _WIN32 #define _WIN32 #endif #else #define LINUX #endif #endif /* code is running within DLL */ #define SDK_DLL 1 /* - we are not at the SyncML engine's side here */ /* - and we need an extern "C" interface for the DLL */ #undef SYSYNC_ENGINE /* activate debug output */ #define SYDEBUG 2 #endif /* TARGET_OPTIONS_H */ /* eof */ libsynthesis-3.4.0.47.1/src/sysync_SDK/DB_Interfaces/demo/sync_dbapi_demo.c000066400000000000000000000724661226375725500263420ustar00rootroot00000000000000/* * File: sync_dbapi_demo.c * * Author: Beat Forster (bfo@synthesis.ch) * * * Programming interface between Synthesis SyncML engine * and a database structure. * * Copyright (c) 2004-2011 by Synthesis AG + plan44.ch * * * E X A M P L E C O D E * ======================== * (To be used as starting point for SDK development. * It can be adapted and extended by programmer) * */ #include "sync_include.h" /* include general SDK definitions */ #include "sync_dbapidef.h" /* include the interface file and utilities */ #include "SDK_util.h" /* include SDK utilities */ /* C/C++ support */ #ifdef __cplusplus /* this allows to have more than one of these modules in C++ */ namespace SDK_demodb { using sysync::SDK_Interface_Struct; using sysync::DB_Callback; using sysync::ItemID; using sysync::MapID; using sysync::LOCERR_OK; using sysync::LOCERR_NOTIMP; using sysync::DB_Full; using sysync::DB_NotFound; using sysync::DB_Forbidden; using sysync::ReadNextItem_Changed; using sysync::ReadNextItem_Unchanged; using sysync::ReadNextItem_EOF; using sysync::Password_ClrText_IN; #endif #include "sync_dbapi.h" /* include the interface file and utilities */ #define BuildNumber 0 /* User defined build number, can be 0..255 */ #define MyDB "DemoDB" /* example debug name */ #define MY_ID 42 /* example datastore context */ #define STRLEN 80 /* Max length of local string copies */ #if defined MACOSX && defined __MWERKS__ #pragma export on #endif /* -- MODULE -------------------------------------------------------------------- */ /* this is an example, how a context could be structured */ /**** CAN BE ADAPTED BY USER ****/ #ifdef __cplusplus class ModuleContext { public: ModuleContext() { fCB= NULL; } DB_Callback fCB; /* callback structure */ char fModuleName[ STRLEN ]; /* the module's name */ }; #else typedef struct { DB_Callback fCB; /* callback structure */ char fModuleName[ STRLEN ]; /* the module's name */ } ModuleContext; #endif /* will be casted to the ModuleContext* structure */ static ModuleContext* MoC( CContext mContext ) { return (ModuleContext*)mContext; } TSyError Module_CreateContext( CContext *mContext, cAppCharP moduleName, cAppCharP subName, cAppCharP mContextName, DB_Callback mCB ) { cAppCharP sep= ""; ModuleContext* mc; #ifdef __cplusplus mc= new ModuleContext; #else mc= (ModuleContext*)malloc( sizeof(ModuleContext) ); #endif if (mc==NULL) return DB_Full; if (subName!=NULL && *subName!='\0') sep= "!"; /* Notation: "!" */ strncpy ( mc->fModuleName, moduleName, STRLEN ); mc->fCB = mCB; DEBUG_DB( mc->fCB, MyDB,Mo_CC, "'%s%s%s' (%s)", mc->fModuleName,sep,subName, mContextName ); *mContext= (CContext)mc; /* return the created context structure */ return LOCERR_OK; } /* Module_CreateContext */ /* Get the plug-in's version number */ CVersion Module_Version( CContext mContext ) { CVersion v= Plugin_Version( BuildNumber ); /* The current plugin's SDK version is expected here */ if ( mContext ) DEBUG_DB( MoC( mContext )->fCB, MyDB,Mo_Ve, "%08X", v ); return v; } /* Module_Version */ /* Get the plug-in's capabilities */ TSyError Module_Capabilities( CContext mContext, appCharP *mCapabilities ) { char s[ 256 ]; /* copy it into a local string */ char* p= s; /* return value of sprintf contains the total string length: increment will concatenate */ p+= sprintf( p, "%s\n", MyPlatform() ); p+= sprintf( p, "%s\n", DLL_Info ); p+= sprintf( p, "%s:%s\n", CA_MinVersion, "V1.0.6.0" ); /* must not be changed */ p+= sprintf( p, "%s:%s\n", CA_Manufacturer, "Synthesis AG" ); /**** SHOULD BE ADAPTED BY USER ****/ p+= sprintf( p, "%s:%s", CA_Description, "Demo Example Module" ); /**** SHOULD BE ADAPTED BY USER ****/ *mCapabilities= StrAlloc( s ); DEBUG_DB( MoC( mContext )->fCB, MyDB,Mo_Ca, "'%s'", *mCapabilities ); return LOCERR_OK; } /* Module_Capabilities */ TSyError Module_PluginParams( CContext mContext, cAppCharP mConfigParams, CVersion engineVersion ) { ModuleContext* mc= MoC( mContext ); DEBUG_DB ( mc->fCB, MyDB,Mo_PP, " Engine=%08X", engineVersion ); DEBUG_DB ( mc->fCB, MyDB,Mo_PP, "'%s'", mConfigParams ); /*return LOCERR_CFGPARSE;*/ /* if there are unsupported params */ return LOCERR_OK; } /* Module_PluginParams */ /* Dispose the memory of the module context */ void Module_DisposeObj( CContext mContext, void* memory ) { DEBUG_Exotic_DB( MoC( mContext )->fCB, MyDB,Mo_DO, "free at %08X '%s'", memory,memory ); StrDispose( memory ); } /* Module_DisposeObj */ TSyError Module_DeleteContext( CContext mContext ) { ModuleContext* mc= MoC( mContext ); DEBUG_DB ( mc->fCB, MyDB,Mo_DC, "'%s'", mc->fModuleName ); #ifdef __cplusplus delete mc; #else free ( mc ); #endif return LOCERR_OK; } /* Module_DeleteContext */ /* ---------------------- session handling --------------------- */ /* this is an example, how a context could be structured */ /**** CAN BE ADAPTED BY USER ****/ #ifdef __cplusplus class SessionContext { public: SessionContext() { fCB= NULL; } int fID; /* a reference number. */ DB_Callback fCB; /* callback structure */ int fPMode; /* The login password mode */ }; #else typedef struct { int fID; /* a reference number. */ DB_Callback fCB; /* callback structure */ int fPMode; /* The login password mode */ } SessionContext; #endif /* will be casted to the SessionContext* structure */ static SessionContext* SeC( CContext sContext ) { return (SessionContext*)sContext; } /* Create a context for a new session */ TSyError Session_CreateContext( CContext *sContext, cAppCharP sessionName, DB_Callback sCB ) { SessionContext* sc; /*return DB_Error;*/ /* added for test */ #ifdef __cplusplus sc= new SessionContext; #else sc= (SessionContext*)malloc( sizeof(SessionContext) ); #endif if (sc==NULL) return DB_Full; /**** CAN BE ADAPTED BY USER ****/ sc->fID= 333; /* as an example */ sc->fCB= sCB; sc->fPMode= Password_ClrText_IN; /* take this mode ... */ /* sc->fPMode= Password_ClrText_OUT; */ /* ... or this */ DEBUG_DB( sc->fCB, MyDB,Se_CC, "%d '%s'", sc->fID,sessionName ); *sContext= (CContext)sc; /* return the created context structure */ return LOCERR_OK; } /* Session_CreateContext */ /* ----- "script-like" ADAPT --------- */ TSyError Session_AdaptItem( CContext sContext, appCharP *sItemData1, appCharP *sItemData2, appCharP *sLocalVars, uInt32 sIdentifier ) { /**** CAN BE ADAPTED BY USER ****/ SessionContext* sc= SeC( sContext ); DEBUG_DB ( sc->fCB, MyDB,"Session_AdaptItem", "'%s' '%s' '%s' id=%d", *sItemData1,*sItemData2,*sLocalVars, sIdentifier ); return LOCERR_OK; } /* Session_AdaptItem */ /* Check the database entry of and return its nonce string */ TSyError Session_CheckDevice( CContext sContext, cAppCharP aDeviceID, appCharP *sDevKey, appCharP *nonce ) { /**** CAN BE ADAPTED BY USER ****/ SessionContext* sc= SeC( sContext ); *sDevKey= StrAlloc( aDeviceID ); *nonce = StrAlloc( "xyz_last" ); DEBUG_DB( sc->fCB, MyDB,Se_CD, "%d dev='%s' nonce='%s'", sc->fID, *sDevKey,*nonce ); return LOCERR_OK; } /* Session_CheckDevice */ /* Get a new nonce from the database. If this returns an error, the SyncML engine * will create its own nonce. */ TSyError Session_GetNonce( CContext sContext, appCharP *nonce ) { /**** CAN BE ADAPTED BY USER ****/ SessionContext* sc= SeC( sContext ); DEBUG_DB ( sc->fCB, MyDB,Se_GN, "%d (not supported)", sc->fID ); *nonce= NULL; return DB_NotFound; } /* Session_GetNonce */ /* Save the new nonce (which will be expected to be returned * in the next session for this device */ TSyError Session_SaveNonce( CContext sContext, cAppCharP nonce ) { /**** CAN BE ADAPTED BY USER ****/ SessionContext* sc= SeC( sContext ); DEBUG_DB ( sc->fCB, MyDB,Se_SN, "%d nonce='%s'", sc->fID, nonce ); return LOCERR_OK; } /* Session_SaveNonce */ /* Save the device info of */ TSyError Session_SaveDeviceInfo( CContext sContext, cAppCharP aDeviceInfo ) { /**** CAN BE ADAPTED BY USER ****/ SessionContext* sc= SeC( sContext ); DEBUG_DB ( sc->fCB, MyDB,Se_SD, "%d info='%s'", sc->fID, aDeviceInfo ); return LOCERR_OK; } /* Session_SaveDeviceInfo */ /* Get the plugin's DB time */ TSyError Session_GetDBTime( CContext sContext, appCharP *currentDBTime ) { /**** CAN BE ADAPTED BY USER ****/ SessionContext* sc= SeC( sContext ); DEBUG_DB ( sc->fCB, MyDB,Se_GT, "%d", sc->fID ); *currentDBTime= NULL; return DB_NotFound; } /* Session_GetDBTime */ /* Return: Password_ClrText_IN 'SessionLogin' will get clear text password * Password_ClrText_OUT " must return clear text password * Password_MD5_OUT " must return MD5 coded password * Password_MD5_Nonce_IN " will get MD5B64(MD5B64(user:pwd):nonce) */ sInt32 Session_PasswordMode( CContext sContext ) { /**** CAN BE ADAPTED BY USER ****/ SessionContext* sc= SeC( sContext ); DEBUG_DB ( sc->fCB, MyDB,Se_PM, "%d mode=%d", sc->fID, sc->fPMode ); return sc->fPMode; } /* Session_PasswordMode */ /* Make login */ TSyError Session_Login( CContext sContext, cAppCharP sUsername, appCharP *sPassword, appCharP *sUsrKey ) { /**** CAN BE ADAPTED BY USER ****/ SessionContext* sc= SeC( sContext ); TSyError err= DB_Forbidden; /* default */ /* different modes, choose one for the plugin */ if (sc->fPMode==Password_ClrText_IN) { if (strcmp( sUsername,"super" )==0 && strcmp( *sPassword,"user" )==0) { *sUsrKey = StrAlloc( "1234" ); err= LOCERR_OK; } } else { /* Password will be returned */ if (strcmp( sUsername,"super" )==0) { *sPassword= StrAlloc( "user" ); *sUsrKey = StrAlloc( "1234" ); err= LOCERR_OK; } } /* if */ if (err) { DEBUG_DB( sc->fCB, MyDB,Se_LI, "%d usr='%s' err=%d", sc->fID,sUsername, err ); } else DEBUG_DB( sc->fCB, MyDB,Se_LI, "%d usr='%s' pwd='%s' => key='%s'", sc->fID,sUsername,*sPassword, *sUsrKey ); return err; } /* Session_Login */ /* Make logout */ TSyError Session_Logout( CContext sContext ) { /**** CAN BE ADAPTED BY USER ****/ SessionContext* sc= SeC( sContext ); DEBUG_DB ( sc->fCB, MyDB,Se_LO, "%d",sc->fID ); return LOCERR_OK; } /* Session_Logout */ void Session_DisposeObj( CContext sContext, void* memory ) { /**** CAN BE ADAPTED BY USER ****/ SessionContext* sc= SeC( sContext ); DEBUG_Exotic_DB( sc->fCB, MyDB,Se_DO, "%d free at %08X '%s'", sc->fID, memory,memory ); StrDispose ( memory ); } /* Session_DisposeObj */ /* Can be implemented empty, if no action is required */ void Session_ThreadMayChangeNow( CContext sContext ) { /**** CAN BE ADAPTED BY USER ****/ SessionContext* sc= SeC( sContext ); DEBUG_Exotic_DB( sc->fCB, MyDB,Se_TC, "%d",sc->fID ); } /* Session_ThreadMayChangeNow */ /* This routine is implemented for debug purposes only and will NOT BE CALLED by the * SyncML engine. Can be implemented empty, if not needed */ void Session_DispItems( CContext sContext, bool allFields, cAppCharP specificItem ) { /**** CAN BE ADAPTED BY USER ****/ SessionContext* sc= SeC( sContext ); DEBUG_DB ( sc->fCB, MyDB,Se_DI, "%d %d '%s'", sc->fID, allFields,specificItem ); } /* Session_DispItems */ /* Delete a session context */ TSyError Session_DeleteContext( CContext sContext ) { /**** CAN BE ADAPTED BY USER ****/ SessionContext* sc= SeC( sContext ); DEBUG_DB ( sc->fCB, MyDB,Se_DC, "%d",sc->fID ); #ifdef __cplusplus delete sc; #else free ( sc ); #endif return LOCERR_OK; } /* Session_DeleteContext */ /* ----------------------------------------------------------------- */ /* This is an example, how a context could be structured */ /**** CAN BE ADAPTED BY USER ****/ #ifdef __cplusplus class TDBContext { public: TDBContext() { fCB= NULL; } DB_Callback fCB; /* debug logging callback */ int contextID; /* context identifier */ int nthItem; /* for 'ReadNextItem' */ char fDevKey[ STRLEN ]; char fUsrKey[ STRLEN ]; }; #else typedef struct { DB_Callback fCB; /* debug logging callback */ int contextID; /* context identifier */ int nthItem; /* for 'ReadNextItem' */ char fDevKey[ STRLEN ]; char fUsrKey[ STRLEN ]; } TDBContext; #endif typedef TDBContext* ContextP; /* will be casted to the ContextP structure */ static ContextP DBC( CContext aContext ) { return (ContextP)aContext; } /* -- OPEN ----------------------------------------------------------------------- */ TSyError CreateContext( CContext *aContext, cAppCharP aContextName, DB_Callback aCB, cAppCharP sDevKey, cAppCharP sUsrKey ) { ContextP ac; #ifdef __cplusplus ac= new TDBContext; #else ac= (ContextP)malloc( sizeof(TDBContext) ); #endif if (ac==NULL) return DB_Full; /**** CAN BE ADAPTED BY USER ****/ ac->fCB = aCB; /* debug logging callback */ ac->contextID= MY_ID; /* example context */ ac->nthItem = 0; /* reset counter */ strncpy ( ac->fDevKey, sDevKey, STRLEN ); /* local copies */ strncpy ( ac->fUsrKey, sUsrKey, STRLEN ); DEBUG_DB( ac->fCB, MyDB,Da_CC, "%d '%s' dev='%s' usr='%s'", ac->contextID, aContextName, ac->fDevKey, ac->fUsrKey ); *aContext= (CContext)ac; /* return the created context structure */ return LOCERR_OK; } /* CreateContext */ uInt32 ContextSupport( CContext aContext, cAppCharP aContextRules ) { /**** CAN BE ADAPTED BY USER ****/ ContextP ac= DBC( aContext ); DEBUG_DB( ac->fCB, MyDB,Da_CS, "%d '%s'", ac->contextID,aContextRules ); return 0; } /* ContextSupport */ uInt32 FilterSupport( CContext aContext, cAppCharP aFilterRules ) { /**** CAN BE ADAPTED BY USER ****/ ContextP ac= DBC( aContext ); DEBUG_DB( ac->fCB, MyDB,Da_FS, "%d '%s'", ac->contextID,aFilterRules ); return 0; } /* FilterSupport */ /* -- ADMINISTRATION ------------------------------------------------------------ */ TSyError LoadAdminData( CContext aContext, cAppCharP aLocDB, cAppCharP aRemDB, appCharP *adminData ) { /**** CAN BE ADAPTED BY USER ****/ ContextP ac= DBC( aContext ); DEBUG_DB( ac->fCB, MyDB,Da_LA, "%d '%s' '%s' '%s' '%s'", ac->contextID, ac->fDevKey, ac->fUsrKey, aLocDB, aRemDB ); *adminData= NULL; return DB_Forbidden; /* not yet implemented */ } /* LoadAdminData */ TSyError LoadAdminDataAsKey( CContext aContext, cAppCharP aLocDB, cAppCharP aRemDB, KeyH adminKey ) { /**** CAN BE ADAPTED BY USER ****/ ContextP ac= DBC( aContext ); DEBUG_DB( ac->fCB, MyDB,Da_LA, "%d '%s' '%s' '%s' '%s' adminKey=%08X", ac->contextID, ac->fDevKey, ac->fUsrKey, aLocDB, aRemDB, adminKey ); return DB_Forbidden; /* not yet implemented */ } /* LoadAdminDataAsKey */ TSyError SaveAdminData( CContext aContext, cAppCharP adminData ) { /**** CAN BE ADAPTED BY USER ****/ ContextP ac= DBC( aContext ); DEBUG_DB( ac->fCB, MyDB,Da_SA, "%d '%s'", ac->contextID, adminData ); return DB_Forbidden; /* not yet implemented */ } /* SaveAdminData */ TSyError SaveAdminDataAsKey( CContext aContext, KeyH adminKey ) { /**** CAN BE ADAPTED BY USER ****/ ContextP ac= DBC( aContext ); DEBUG_DB( ac->fCB, MyDB,Da_SA, "%d adminKey=%08X", ac->contextID, adminKey ); return DB_Forbidden; /* not yet implemented */ } /* SaveAdminDataAsKey */ bool ReadNextMapItem( CContext aContext, MapID mID, bool aFirst ) { /**** CAN BE ADAPTED BY USER ****/ ContextP ac= DBC( aContext ); DEBUG_DB( ac->fCB, MyDB, Da_RM, "%d %08X first=%d (EOF)", ac->contextID, mID, aFirst ); return false; /* not yet implemented */ } /* ReadNextMapItem */ TSyError InsertMapItem( CContext aContext, cMapID mID ) { /**** CAN BE ADAPTED BY USER ****/ ContextP ac= DBC( aContext ); DEBUG_DB( ac->fCB, MyDB,Da_IM, "%d %08X: '%s' '%s' %04X %d", ac->contextID, mID, mID->localID, mID->remoteID, mID->flags, mID->ident ); return DB_Forbidden; /* not yet implemented */ } /* InsertMapItem */ TSyError UpdateMapItem( CContext aContext, cMapID mID ) { /**** CAN BE ADAPTED BY USER ****/ ContextP ac= DBC( aContext ); DEBUG_DB( ac->fCB, MyDB,Da_UM, "%d %08X: '%s' '%s' %04X %d", ac->contextID, mID, mID->localID, mID->remoteID, mID->flags, mID->ident ); return DB_Forbidden; /* not yet implemented */ } /* UpdateMapItem */ TSyError DeleteMapItem( CContext aContext, cMapID mID ) { /**** CAN BE ADAPTED BY USER ****/ ContextP ac= DBC( aContext ); DEBUG_DB( ac->fCB, MyDB,Da_DM, "%d %08X: '%s' '%s' %04X %d", ac->contextID, mID, mID->localID, mID->remoteID, mID->flags, mID->ident ); return DB_Forbidden; /* not yet implemented */ } /* DeleteMapItem */ /* -- GENERAL -------------------------------------------------------------------- */ void DisposeObj( CContext aContext, void* memory ) { /**** CAN BE ADAPTED BY USER ****/ ContextP ac= DBC( aContext ); DEBUG_Exotic_DB( ac->fCB, MyDB,Da_DO, "%d free at %08X", ac->contextID,memory ); free( memory ); } /* DisposeObj */ void ThreadMayChangeNow( CContext aContext ) { /**** CAN BE ADAPTED BY USER ****/ /* can be implemented empty, if no action is required */ ContextP ac= DBC( aContext ); DEBUG_Exotic_DB( ac->fCB, MyDB,Da_TC, "%d", ac->contextID ); } /* ThreadMayChangeNow */ void WriteLogData( CContext aContext, cAppCharP logData ) { /**** CAN BE ADAPTED BY USER ****/ ContextP ac= DBC( aContext ); DEBUG_DB( ac->fCB, MyDB, Da_WL, "%d (BEGIN)\n%s", ac->contextID, logData ); DEBUG_DB( ac->fCB, MyDB, Da_WL, "%d (END)", ac->contextID ); } /* WriteLogData */ /* This routine is implemented for debug purposes only and will NOT BE CALLED by the * SyncML engine. Can be implemented empty, if not needed */ void DispItems( CContext aContext, bool allFields, cAppCharP specificItem ) { /**** CAN BE ADAPTED BY USER ****/ ContextP ac= DBC( aContext ); DEBUG_DB( ac->fCB, MyDB,Da_DI, "%d %d '%s'", ac->contextID,allFields,specificItem ); } /* DispItems */ /* ----- "script-like" ADAPT --------- */ TSyError AdaptItem( CContext aContext, appCharP *aItemData1, appCharP *aItemData2, appCharP *aLocalVars, uInt32 aIdentifier ) { /**** CAN BE ADAPTED BY USER ****/ ContextP ac= DBC( aContext ); DEBUG_DB( ac->fCB, MyDB,"AdaptItem", "'%s' '%s' '%s' id=%d", *aItemData1,*aItemData2,*aLocalVars, aIdentifier ); return LOCERR_OK; } /* AdaptItem */ /* -- READ ---------------------------------------------------------------------- */ TSyError StartDataRead( CContext aContext, cAppCharP lastToken, cAppCharP resumeToken ) { /**** CAN BE ADAPTED BY USER ****/ ContextP ac= DBC( aContext ); DEBUG_DB( ac->fCB, MyDB,Da_SR, "%d last='%s' resume='%s'", ac->contextID, lastToken,resumeToken ); ac->nthItem= 0; /* reset counter */ return LOCERR_OK; } /* StartDataRead */ TSyError ReadNextItem( CContext aContext, ItemID aID, appCharP *aItemData, sInt32 *aStatus, bool aFirst ) { /**** CAN BE ADAPTED BY USER ****/ ContextP ac= DBC( aContext ); if (aFirst) ac->nthItem= 0; /* Show all visible items to the SyncML engine here */ /* "ReadNextItem" will be called subsequently until ReadNextItem_EOF is returned */ if (ac->nthItem>0) { *aStatus= ReadNextItem_EOF; DEBUG_DB( ac->fCB, MyDB,Da_RN, "%d aStatus=%d", ac->contextID, *aStatus ); return LOCERR_OK; } /* if */ /* This example just shows one hard coded element */ aID->item = StrAlloc( "demo_ID" ); aID->parent= StrAlloc( "demo_parent" ); *aItemData = StrAlloc( "demo_data" ); *aStatus = ReadNextItem_Changed; /* comparison not implemented here */ ac->nthItem++; DEBUG_DB( ac->fCB, MyDB,Da_RN, "%d aStatus=%d aItemData='%s' aID=(%s,%s)", ac->contextID, *aStatus, *aItemData, aID->item,aID->parent ); return LOCERR_OK; } /* ReadNextItem */ TSyError ReadNextItemAsKey( CContext aContext, ItemID aID, KeyH aItemKey, sInt32* aStatus, bool aFirst ) { /**** CAN BE ADAPTED BY USER ****/ ContextP ac= DBC( aContext ); if (aFirst) ac->nthItem= 0; /* Show all visible items to the SyncML engine here */ /* "ReadNextItemAsKey" will be called subsequently until ReadNextItem_EOF is returned */ if (ac->nthItem>0) { *aStatus= ReadNextItem_EOF; DEBUG_DB( ac->fCB, MyDB,Da_RNK, "%d aStatus=%d", ac->contextID, *aStatus ); return LOCERR_OK; } /* if */ /* This example just shows one hard coded element */ aID->item = StrAlloc( "demo_ID" ); aID->parent= StrAlloc( "demo_parent" ); *aStatus = ReadNextItem_Changed; /* comparison not implemented here */ ac->nthItem++; DEBUG_DB( ac->fCB, MyDB,Da_RNK, "%d aStatus=%d aItemKey=%08X aID=(%s,%s)", ac->contextID, *aStatus, aItemKey, aID->item,aID->parent ); return LOCERR_OK; } /* ReadNextItemAsKey */ TSyError ReadItem( CContext aContext, cItemID aID, appCharP *aItemData ) { /**** CAN BE ADAPTED BY USER ****/ ContextP ac= DBC( aContext ); *aItemData= StrAlloc( "demo_data" ); DEBUG_DB( ac->fCB, MyDB,Da_RI, "%d aItemData='%s' aID=(%s,%s)", ac->contextID,*aItemData, aID->item,aID->parent ); return LOCERR_OK; } /* ReadItem */ TSyError ReadItemAsKey( CContext aContext, cItemID aID, KeyH aItemKey ) { /**** CAN BE ADAPTED BY USER ****/ ContextP ac= DBC( aContext ); DEBUG_DB( ac->fCB, MyDB,Da_RIK, "%d aItemKey=%08X aID=(%s,%s)", ac->contextID, aItemKey, aID->item,aID->parent ); return LOCERR_OK; } /* ReadItemAsKey */ TSyError ReadBlob( CContext aContext, cItemID aID, cAppCharP aBlobID, appPointer *aBlkPtr, memSize *aBlkSize, memSize *aTotSize, bool aFirst, bool *aLast ) { /**** CAN BE ADAPTED BY USER ****/ ContextP ac= DBC( aContext ); const memSize sz= sizeof(int); int* ip = (int*)malloc( sz ); /* example BLOB structure for test (=4 bytes) */ *ip = 231; *aBlkPtr = (appPointer)ip; if (*aBlkSize==0 || *aBlkSize>=sz) *aBlkSize= sz; *aTotSize= *aBlkSize; *aLast = true; DEBUG_DB( ac->fCB, MyDB,Da_RB, "%d aID=(%s,%s) aBlobID=(%s)", ac->contextID, aID->item,aID->parent, aBlobID ); DEBUG_DB( ac->fCB, MyDB,"", "aBlkPtr=%08X aBlkSize=%d aTotSize=%d aFirst=%s aLast=%s", *aBlkPtr, *aBlkSize, *aTotSize, aFirst?"true":"false", *aLast?"true":"false" ); return LOCERR_OK; } /* ReadBlob */ TSyError EndDataRead( CContext aContext ) { /**** CAN BE ADAPTED BY USER ****/ ContextP ac= DBC( aContext ); DEBUG_DB( ac->fCB, MyDB,Da_ER, "%d", ac->contextID ); return LOCERR_OK; } /* EndDataRead */ /* -- WRITE --------------------------------------------------------------------- */ TSyError StartDataWrite( CContext aContext ) { /**** CAN BE ADAPTED BY USER ****/ ContextP ac= DBC( aContext ); DEBUG_DB( ac->fCB, MyDB,Da_SW, "%d", ac->contextID ); return LOCERR_OK; } /* StartDataWrite */ TSyError InsertItem( CContext aContext, cAppCharP aItemData, ItemID newID ) { /**** CAN BE ADAPTED BY USER ****/ ContextP ac= DBC( aContext ); newID->item = StrAlloc( "hello" ); DEBUG_DB( ac->fCB, MyDB,Da_II, "%d '%s'\nnewID=(%s,%s)", ac->contextID, aItemData, newID->item,newID->parent ); return LOCERR_OK; } /* InsertItem */ TSyError InsertItemAsKey( CContext aContext, KeyH aItemKey, ItemID newID ) { /**** CAN BE ADAPTED BY USER ****/ ContextP ac= DBC( aContext ); DEBUG_DB( ac->fCB, MyDB,Da_IIK, "%d %08X\n", ac->contextID, aItemKey ); newID= NULL; return LOCERR_NOTIMP; } /* InsertItemAsKey */ TSyError UpdateItem( CContext aContext, cAppCharP aItemData, cItemID aID, ItemID updID ) { /**** CAN BE ADAPTED BY USER ****/ ContextP ac= DBC( aContext ); if (strcmp( aID->item,"example" )!=0) updID->item = StrAlloc( "example" ); DEBUG_DB( ac->fCB, MyDB,Da_UI, "%d '%s'\naID=(%s,%s)", ac->contextID, aItemData, aID->item,aID->parent ); if (updID->item==NULL) { DEBUG_DB( ac->fCB, MyDB,"", "NULL" ); } else { DEBUG_DB( ac->fCB, MyDB,"", "updID=(%s,%s)", updID->item,updID->parent ); } return LOCERR_OK; } /* UpdateItem */ TSyError UpdateItemAsKey( CContext aContext, KeyH aItemKey, cItemID aID, ItemID updID ) { /**** CAN BE ADAPTED BY USER ****/ ContextP ac= DBC( aContext ); DEBUG_DB( ac->fCB, MyDB,Da_UIK, "%d %08X\naID=(%s,%s)", ac->contextID, aItemKey, aID->item,aID->parent ); updID= NULL; return LOCERR_NOTIMP; } /* UpdateItemAsKey */ TSyError MoveItem( CContext aContext, cItemID aID, cAppCharP newParID ) { /**** CAN BE ADAPTED BY USER ****/ ContextP ac= DBC( aContext ); DEBUG_DB( ac->fCB, MyDB,Da_MvI, "%d aID=(%s,%s) => (%s,%s)", ac->contextID, aID->item,aID->parent, aID->item,newParID ); return LOCERR_OK; } /* MoveItem */ TSyError DeleteItem( CContext aContext, cItemID aID ) { /**** CAN BE ADAPTED BY USER ****/ ContextP ac= DBC( aContext ); DEBUG_DB( ac->fCB, MyDB,Da_DeI, "%d aID=(%s,%s)", ac->contextID,aID->item,aID->parent ); return LOCERR_OK; } /* DeleteItem */ TSyError FinalizeLocalID( CContext aContext, cItemID aID, ItemID updID ) { /**** CAN BE ADAPTED BY USER ****/ ContextP ac= DBC( aContext ); DEBUG_DB( ac->fCB, MyDB,Da_FLI, "%d aID=(%s,%s)", ac->contextID,aID->item,aID->parent ); updID= NULL; return LOCERR_NOTIMP; } /* FinalizeLocalID */ TSyError DeleteSyncSet( CContext aContext ) { /**** CAN BE ADAPTED BY USER ****/ ContextP ac= DBC( aContext ); DEBUG_DB( ac->fCB, MyDB,Da_DSS, "%d", ac->contextID ); return LOCERR_NOTIMP; } /* DeleteSyncSet */ TSyError WriteBlob( CContext aContext, cItemID aID, cAppCharP aBlobID, appPointer aBlkPtr, memSize aBlkSize, memSize aTotSize, bool aFirst, bool aLast ) { /**** CAN BE ADAPTED BY USER ****/ ContextP ac= DBC( aContext ); DEBUG_DB( ac->fCB, MyDB,Da_WB, "%d aID=(%s,%s) aBlobID=(%s)", ac->contextID, aID->item,aID->parent, aBlobID ); DEBUG_DB( ac->fCB, MyDB,"", "aBlkPtr=%08X aBlkSize=%d aTotSize=%d aFirst=%s aLast=%s", aBlkPtr, aBlkSize, aTotSize, aFirst?"true":"false", aLast ?"true":"false" ); return LOCERR_OK; } /* WriteBlob */ TSyError DeleteBlob( CContext aContext, cItemID aID, cAppCharP aBlobID ) { /**** CAN BE ADAPTED BY USER ****/ ContextP ac= DBC( aContext ); DEBUG_DB( ac->fCB, MyDB,Da_DB, "%d aID=(%s,%s) aBlobID=(%s)", ac->contextID, aID->item,aID->parent, aBlobID ); return LOCERR_OK; } /* DeleteBlob */ TSyError EndDataWrite( CContext aContext, bool success, appCharP *newToken ) { /**** CAN BE ADAPTED BY USER ****/ ContextP ac= DBC( aContext ); #define TokenExample "20041110T230000Z" *newToken= StrAlloc( TokenExample ); DEBUG_DB( ac->fCB, MyDB,Da_EW, "%d %s '%s'", ac->contextID, success ? "COMMIT":"ROLLBACK", *newToken ); return LOCERR_OK; } /* EndDataWrite */ /* ----------------------------------- */ TSyError DeleteContext( CContext aContext ) { /**** CAN BE ADAPTED BY USER ****/ ContextP ac= DBC( aContext ); DEBUG_DB( ac->fCB, MyDB,Da_DC, "%d", ac->contextID ); #ifdef __cplusplus delete ac; #else free ( ac ); /* release the structure itself */ #endif return LOCERR_OK; } /* DeleteContext */ /* C/C++ support */ #ifdef __cplusplus } /* namespace */ #endif /* eof */ libsynthesis-3.4.0.47.1/src/sysync_SDK/DB_Interfaces/snowwhite/000077500000000000000000000000001226375725500241435ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/sysync_SDK/DB_Interfaces/snowwhite/DLL/000077500000000000000000000000001226375725500245565ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/sysync_SDK/DB_Interfaces/snowwhite/DLL/target_options.h000066400000000000000000000017131226375725500277720ustar00rootroot00000000000000/* * File: target_options.h * * Author: Beat Forster (bfo@synthesis.ch) * * Programming interface between Synthesis SyncML engine * and a database structure. * * Copyright (c) 2004-2011 by Synthesis AG + plan44.ch * */ #ifndef TARGET_OPTIONS_H #define TARGET_OPTIONS_H /* - find out target platform */ #ifdef __MACH__ #define MACOSX #else #if defined __MWERKS__ || defined _MSC_VER #ifndef _WIN32 #define _WIN32 #endif #ifndef WIN32 #define WIN32 #endif #else #define LINUX #endif #endif /* code is running within DLL */ #define SDK_DLL 1 /* - we are not at the SyncML engine's side here */ /* - and we need an extern "C" interface for the DLL */ #undef SYSYNC_ENGINE /* activate debug output */ #define SYDEBUG 2 /* use internal BLOB and ADMIN implementation */ //#define DISABLE_PLUGIN_DATASTOREADMIN 1 //#define DISABLE_PLUGIN_BLOBS 1 #endif /* TARGET_OPTIONS_H */ /* eof */ libsynthesis-3.4.0.47.1/src/sysync_SDK/DB_Interfaces/snowwhite/myadapter.h000066400000000000000000000010661226375725500263050ustar00rootroot00000000000000/* * File: myadapter.h * * Author: Beat Forster (bfo@synthesis.ch) * * This bridge allows a OceanBlue module * which needn't to be changed for different * DBApi database adapters * * Copyright (c) 2008-2011 by Synthesis AG + plan44.ch * */ #ifndef MYADAPTER_H #define MYADAPTER_H //*** defs used for unified OceanBlue *** #define MyAdapter_Name "SnowWhite" #define MyAdapter_Module SnowWhite_Module #define MyAdapter_Session SnowWhite_Session #define MyAdapter SnowWhite #include "snowwhite.h" #endif // MYADAPTER_H /* eof */ libsynthesis-3.4.0.47.1/src/sysync_SDK/DB_Interfaces/snowwhite/oceanblue.cpp000066400000000000000000001035451226375725500266140ustar00rootroot00000000000000/* * File: oceanblue.cpp * * Author: Beat Forster (bfo@synthesis.ch) * * datastore plugin interface and * Base class for datastore plugins in C++ * * Copyright (c) 2008-2011 by Synthesis AG + plan44.ch * */ #include "myadapter.h" namespace oceanblue { using sysync::SDK_Interface_Struct; using sysync::DB_Callback; using sysync::ItemID; using sysync::MapID; using sysync::LOCERR_OK; using sysync::LOCERR_NOTIMP; using sysync::LOCERR_TRUNCATED; using sysync::DB_Forbidden; using sysync::DB_NotFound; using sysync::DB_Full; using sysync::Password_Mode_Undefined; using sysync::ReadNextItem_EOF; using sysync::VP_GlobMulti; using sysync::VALTYPE_TEXT; using sysync::VALTYPE_INT16; using sysync::VALTYPE_INT32; using sysync::Manufacturer; using sysync::Description; using sysync::MinVersion; using sysync::YesField; using sysync::IsAdmin; #include "sync_dbapi.h" // include the interface file and utilities #define MyDB "OceanBlue" // example debug name /* ----- OceanBlue MODULE --------------------------------------------------------- */ TSyError OceanBlue_Module::CreateContext( cAppCharP subName ) { DEBUG_DB( fCB, MyDB,Mo_CC, "'%s' mod='%s' sub='%s'", fContextName.c_str(), fModName.c_str(), subName ); return LOCERR_OK; } // CreateContext CVersion OceanBlue_Module::Version() { return Plugin_Version( 0 ); } TSyError OceanBlue_Module::Capabilities( appCharP &capa ) { string s = MyPlatform(); s+= '\n'; s+= DLL_Info; Manufacturer ( s, "Synthesis AG" ); Description ( s, "OceanBlue Adapter" ); MinVersion ( s, VP_GlobMulti ); // at least V1.5.1 YesField ( s, CA_ADMIN_Info ); // show "ADMIN" info capa= StrAlloc( s.c_str() ); return LOCERR_OK; } // Capabilities TSyError OceanBlue_Module::PluginParams ( cAppCharP /* mConfigParams */, // ignore CVersion /* engineVersion */ ) { return LOCERR_OK; } void OceanBlue_Module::DisposeObj( void* memory ) { StrDispose( memory ); } TSyError OceanBlue_Module::DeleteContext() { DEBUG_DB( fCB, MyDB,Mo_DC, "'%s'", fContextName.c_str() ); return LOCERR_OK; } // DeleteContext /* ----- OceanBlue SESSION -------------------------------------------------------- */ TSyError OceanBlue_Session::CreateContext() { DEBUG_DB( fCB, MyDB,Se_CC, "session='%s'", fSessionName.c_str() ); return LOCERR_OK; } // CreateContext // -- device TSyError OceanBlue_Session::CheckDevice( cAppCharP /* aDeviceID */, appCharP &sDevKey, appCharP &nonce ) { sDevKey= StrAlloc( "key" ); nonce = StrAlloc( "nonce" ); return LOCERR_OK; } // CheckDevice TSyError OceanBlue_Session::GetNonce ( appCharP& /* nonce */ ) { return DB_NotFound; } TSyError OceanBlue_Session::SaveNonce ( cAppCharP /* nonce */ ) { return LOCERR_OK; } TSyError OceanBlue_Session::SaveDeviceInfo( cAppCharP /* aDeviceInfo */ ) { return LOCERR_OK; } TSyError OceanBlue_Session::GetDBTime ( appCharP& /* currDBTime */ ) { return DB_NotFound; } // -- login sInt32 OceanBlue_Session::PasswordMode() { return Password_Mode_Undefined; } TSyError OceanBlue_Session::Login ( cAppCharP /* sUsername */, appCharP& /* sPassword */, appCharP& /* sUsrKey */ ) { return DB_Forbidden; } TSyError OceanBlue_Session::Logout() { return LOCERR_OK; } // -- general void OceanBlue_Session::DisposeObj( void* memory ) { StrDispose( memory ); } void OceanBlue_Session::ThreadMayChangeNow() { } void OceanBlue_Session::DispItems( bool /* allFields */, cAppCharP /* specificItem */ ) { } TSyError OceanBlue_Session::Adapt_Item( appCharP& /* sItemData1 */, appCharP& /* sItemData2 */, appCharP& /* sLocalVars */, uInt32 /* sIdentifier */ ) { return LOCERR_OK; } TSyError OceanBlue_Session::DeleteContext() { DEBUG_DB( fCB, MyDB,Se_DC, "session='%s'", fSessionName.c_str() ); return LOCERR_OK; } // DeleteContext /* ----- OceanBlue DATASTORE ------------------------------------------------------ */ TSyError OceanBlue::CreateContext ( cAppCharP sDevKey, cAppCharP sUsrKey ) { DEBUG_DB( fCB, MyDB,Da_CC, "'%s' (%s) dev='%s' usr='%s'", fContextName.c_str(), fAsAdmin?"admin":"data", sDevKey,sUsrKey ); #ifndef DISABLE_PLUGIN_DATASTOREADMIN fAdmin.Init( fCB, MyDB, "", fContextName, sDevKey,sUsrKey ); #endif #ifndef DISABLE_PLUGIN_BLOBS fBlob.Init ( fCB, MyDB, "", fContextName, sDevKey,sUsrKey ); #endif fNthItem= 0; // initialize it return LOCERR_OK; } // CreateContext uInt32 OceanBlue::ContextSupport( cAppCharP /* aContextRules */ ) { return 0; } uInt32 OceanBlue::FilterSupport ( cAppCharP /* aFilterRules */ ) { return 0; } // -- admin #ifndef DISABLE_PLUGIN_DATASTOREADMIN TSyError OceanBlue::LoadAdminData ( cAppCharP aLocDB, cAppCharP aRemDB, appCharP &adminData ) { return fAdmin.LoadAdminData ( aLocDB, aRemDB, &adminData ); } // LoadAdminData TSyError OceanBlue::LoadAdminDataAsKey( cAppCharP /* aLocDB */, cAppCharP /* aRemDB */, KeyH /* adminKey */ ) { return LOCERR_NOTIMP; } // LoadAdminDataAsKey TSyError OceanBlue::SaveAdminData ( cAppCharP adminData ) { return fAdmin.SaveAdminData ( adminData ); } // SaveAdminData TSyError OceanBlue::SaveAdminDataAsKey( KeyH /* adminKey */ ) { return LOCERR_NOTIMP; } // SaveAdminDataAsKey bool OceanBlue::ReadNextMapItem ( MapID mID, bool aFirst ) { return fAdmin.ReadNextMapItem ( mID, aFirst ); } // ReadNextMapItem TSyError OceanBlue::InsertMapItem ( cMapID mID ) { return fAdmin.InsertMapItem ( mID ); } // InsertMapItem TSyError OceanBlue::UpdateMapItem ( cMapID mID ) { return fAdmin.UpdateMapItem ( mID ); } // UpdateMapItem TSyError OceanBlue::DeleteMapItem ( cMapID mID ) { return fAdmin.DeleteMapItem ( mID ); } // DeleteMapItem #else TSyError OceanBlue::LoadAdminData ( cAppCharP /* aLocDB */, cAppCharP /* aRemDB */, appCharP& /* adminData */ ) { return DB_Forbidden; } TSyError OceanBlue::LoadAdminDataAsKey( cAppCharP /* aLocDB */, cAppCharP /* aRemDB */, KeyH /* adminKey */ ) { return DB_Forbidden; } TSyError OceanBlue::SaveAdminData ( cAppCharP /* adminData */ ) { return DB_Forbidden; } TSyError OceanBlue::SaveAdminDataAsKey ( KeyH /* adminKey */ ) { return DB_Forbidden; } bool OceanBlue::ReadNextMapItem ( MapID /* mID */, bool /* aFirst */ ) { return false; } TSyError OceanBlue::InsertMapItem ( cMapID /* mID */ ) { return DB_Forbidden; } TSyError OceanBlue::UpdateMapItem ( cMapID /* mID */ ) { return DB_Forbidden; } TSyError OceanBlue::DeleteMapItem ( cMapID /* mID */ ) { return DB_Forbidden; } #endif // -- read TSyError OceanBlue::StartDataRead ( cAppCharP /* lastToken */, cAppCharP /* resumeToken */ ) { return LOCERR_OK; } TSyError OceanBlue::ReadNextItem ( ItemID /* aID */, appCharP& /* aItemData */, sInt32 &aStatus, bool /* aFirst */ ) { aStatus= ReadNextItem_EOF; return LOCERR_OK; } TSyError OceanBlue::ReadNextItemAsKey( ItemID /* aID */, KeyH /* aItemKey */, sInt32 &aStatus, bool /* aFirst */ ) { aStatus= ReadNextItem_EOF; return LOCERR_OK; } TSyError OceanBlue::ReadItem ( cItemID /* aID */, appCharP& /* aItemData */ ) { return LOCERR_NOTIMP; } TSyError OceanBlue::ReadItemAsKey ( cItemID /* aID */, KeyH /* aItemKey */ ) { return LOCERR_NOTIMP; } TSyError OceanBlue::EndDataRead() { return LOCERR_OK; } // -- write TSyError OceanBlue::StartDataWrite() { return LOCERR_OK; } TSyError OceanBlue::InsertItem ( cAppCharP /* aItemData */, ItemID /* newID */ ) { return LOCERR_NOTIMP; } TSyError OceanBlue::InsertItemAsKey ( KeyH /* aItemKey */, ItemID /* newID */ ) { return LOCERR_NOTIMP; } TSyError OceanBlue::UpdateItem ( cAppCharP /* aItemData */, cItemID /* aID */, ItemID /* updID */ ) { return LOCERR_NOTIMP; } TSyError OceanBlue::UpdateItemAsKey ( KeyH /* aItemKey */, cItemID /* aID */, ItemID /* updID */ ) { return LOCERR_NOTIMP; } TSyError OceanBlue::MoveItem ( cItemID /* aID */, cAppCharP /* newParID */ ) { return LOCERR_NOTIMP; } TSyError OceanBlue::DeleteItem ( cItemID /* aID */ ) { return LOCERR_NOTIMP; } TSyError OceanBlue::FinalizeLocalID ( cItemID /* aID */, ItemID /* updID */ ) { return LOCERR_NOTIMP; } TSyError OceanBlue::DeleteSyncSet() { return LOCERR_NOTIMP; } TSyError OceanBlue::EndDataWrite ( bool /* success */, appCharP& /* newToken */ ) { return LOCERR_OK; } // -- blobs TSyError OceanBlue::ReadBlob ( cItemID aID, cAppCharP aBlobID, appPointer &aBlkPtr, memSize &aBlkSize, memSize &aTotSize, bool aFirst, bool &aLast ) { #ifndef DISABLE_PLUGIN_BLOBS return fBlob.ReadBlob ( aID,aBlobID, &aBlkPtr,&aBlkSize,&aTotSize, aFirst,&aLast ); #endif return LOCERR_NOTIMP; } // ReadBlob TSyError OceanBlue::WriteBlob ( cItemID aID, cAppCharP aBlobID, appPointer aBlkPtr, memSize aBlkSize, memSize aTotSize, bool aFirst, bool aLast ) { #ifndef DISABLE_PLUGIN_BLOBS return fBlob.WriteBlob ( aID,aBlobID, aBlkPtr,aBlkSize,aTotSize, aFirst,aLast ); #endif return LOCERR_NOTIMP; } // WriteBlob TSyError OceanBlue::DeleteBlob( cItemID aID, cAppCharP aBlobID ) { #ifndef DISABLE_PLUGIN_BLOBS return fBlob.DeleteBlob( aID,aBlobID ); #endif return LOCERR_NOTIMP; } // DeleteBlob // -- general void OceanBlue::WriteLogData ( cAppCharP /* logData */ ) { } void OceanBlue::DisposeObj ( void* /* memory */ ) { } void OceanBlue::ThreadMayChangeNow() { } void OceanBlue::DispItems ( bool /* allFields */, cAppCharP /* specificItem */ ) { } TSyError OceanBlue::Adapt_Item ( appCharP& /* aItemData1 */, appCharP& /* aItemData2 */, appCharP& /* aLocalVars */, uInt32 /* aIdentifier */ ) { return LOCERR_OK; } TSyError OceanBlue::DeleteContext() { DEBUG_DB( fCB, MyDB,Da_DC, "'%s'", fContextName.c_str() ); return LOCERR_OK; } // DeleteContext // ---- call-in functions ---- sInt32 OceanBlue::GetValueID ( KeyH aItemKey, string aValName, string suff ) { if (!fCB->ui.GetValueID) return -1; aValName+= suff; return fCB->ui.GetValueID ( fCB, aItemKey, aValName.c_str() ); } // GetValueID TSyError OceanBlue::GetValue ( KeyH aItemKey, string aValName, uInt16 aValType, appPointer aBuffer, memSize aBufSize, memSize &aValSize, string suff ) { if (!fCB->ui.GetValue) return LOCERR_NOTIMP; aValName+= suff; return fCB->ui.GetValue ( fCB, aItemKey, aValName.c_str(), aValType, aBuffer, aBufSize, &aValSize ); } // GetValue TSyError OceanBlue::GetValueByID( KeyH aItemKey, sInt32 aID, sInt32 arrIndex, uInt16 aValType, appPointer aBuffer, memSize aBufSize, memSize &aValSize, string suff ) { if (!fCB->ui.GetValueByID) return LOCERR_NOTIMP; AppendSuffixToID ( aItemKey, aID, suff.c_str() ); return fCB->ui.GetValueByID( fCB, aItemKey, aID, arrIndex, aValType, aBuffer, aBufSize, &aValSize ); } // GetValueByID TSyError OceanBlue::SetValue ( KeyH aItemKey, string aValName, uInt16 aValType, appPointer aBuffer, memSize aValSize, string suff ) { if (!fCB->ui.SetValue) return LOCERR_NOTIMP; aValName+= suff; return fCB->ui.SetValue ( fCB, aItemKey, aValName.c_str(), aValType, aBuffer, aValSize ); } // SetValue TSyError OceanBlue::SetValueByID( KeyH aItemKey, sInt32 aID, sInt32 arrIndex, uInt16 aValType, appPointer aBuffer, memSize aValSize, string suff ) { if (!fCB->ui.SetValueByID) return LOCERR_NOTIMP; AppendSuffixToID ( aItemKey, aID, suff.c_str() ); return fCB->ui.SetValueByID( fCB, aItemKey, aID, arrIndex, aValType, aBuffer, aValSize ); } // SetValueByID // ------------------------------------------------- void OceanBlue::AppendSuffixToID( KeyH aItemKeyH, sInt32 &aID, cAppCharP suff ) { string s= suff; if (s=="") return; s= VALNAME_FLAG + s; aID+= GetValueID( aItemKeyH, s.c_str() ); } // AppendSuffixToID // ---- convenience routines to access Get/SetValue for specific types ---- // string TSyError OceanBlue::GetStr( KeyH aItemKey, string aValName, string &aText, string suff ) { TSyError err; const uInt16 ty= VALTYPE_TEXT; const int txtFSz= 80; // a readonable string length to catch it at once char txt[ txtFSz ]; memSize txtSz; // try directly to fit in a short string first appCharP f= (char*)&txt; err= GetValue( aItemKey, aValName, ty, f, txtFSz, txtSz, suff ); bool tooShort= err==LOCERR_TRUNCATED; if (tooShort) { err= GetValue( aItemKey, aValName, ty, f, 0, txtSz, suff ); // get size f= (appCharP)malloc( txtSz+1 ); // plus NUL termination err= GetValue( aItemKey, aValName, ty, f, txtSz+1, txtSz, suff ); // no error anymore } // if if (err) aText= ""; else aText= f; // assign it if (tooShort) free( f ); // and deallocate again, if used dynamically return err; } // GetStr TSyError OceanBlue::GetStrByID( KeyH aItemKey, sInt32 aID, string &aText, sInt32 arrIndex, string suff ) { TSyError err; const uInt16 ty= VALTYPE_TEXT; const int txtFSz= 80; // a readonable string length to catch it at once char txt[ txtFSz ]; memSize txtSz; // try directly to fit in a short string first appCharP f= (char*)&txt; err= GetValueByID( aItemKey, aID,arrIndex, ty, f, txtFSz, txtSz, suff ); bool tooShort= err==LOCERR_TRUNCATED; if (tooShort) { err= GetValueByID( aItemKey, aID,arrIndex, ty, f, 0, txtSz, suff ); // get size f= (appCharP)malloc( txtSz+1 ); // plus NUL termination err= GetValueByID( aItemKey, aID,arrIndex, ty, f, txtSz+1, txtSz, suff ); // no error anymore } // if if (err) aText= ""; else aText= f; // assign it if (tooShort) free( f ); // and deallocate again, if used dynamically return err; } // GetStrByID TSyError OceanBlue::SetStr ( KeyH aItemKey, string aValName, string aText, string suff ) { // -1 automatically calculate length from null-terminated string return SetValue ( aItemKey, aValName, VALTYPE_TEXT, (appPointer)aText.c_str(), (memSize)-1, suff ); } // SetStr TSyError OceanBlue::SetStrByID( KeyH aItemKey, sInt32 aID, string aText, sInt32 arrIndex, string suff ) { // -1 automatically calculate length from null-terminated string return SetValueByID( aItemKey, aID,arrIndex, VALTYPE_TEXT, (appPointer)aText.c_str(), (memSize)-1, suff ); } // SetStrByID /* sInt16 / uInt16 */ TSyError OceanBlue::GetInt16 ( KeyH aItemKey, string aValName, sInt16 &aValue, string suff ) { memSize vSize; return GetValue ( aItemKey, aValName, VALTYPE_INT16,&aValue, sizeof(aValue),vSize, suff ); } // GetInt16 TSyError OceanBlue::GetInt16 ( KeyH aItemKey, string aValName, uInt16 &aValue, string suff ) { memSize vSize; return GetValue ( aItemKey, aValName, VALTYPE_INT16,&aValue, sizeof(aValue),vSize, suff ); } // GetInt16 TSyError OceanBlue::GetInt16ByID( KeyH aItemKey, sInt32 aID, sInt16 &aValue, sInt32 arrIndex, string suff ) { memSize vSize; return GetValueByID( aItemKey, aID,arrIndex, VALTYPE_INT16,&aValue, sizeof(aValue),vSize, suff ); } // GetInt16ByID TSyError OceanBlue::GetInt16ByID( KeyH aItemKey, sInt32 aID, uInt16 &aValue, sInt32 arrIndex, string suff ) { memSize vSize; return GetValueByID( aItemKey, aID,arrIndex, VALTYPE_INT16,&aValue, sizeof(aValue),vSize, suff ); } // GetInt16ByID TSyError OceanBlue::SetInt16 ( KeyH aItemKey, string aValName, sInt16 aValue, string suff ) { return SetValue ( aItemKey, aValName, VALTYPE_INT16,&aValue, sizeof(aValue), suff ); } // SetInt16 TSyError OceanBlue::SetInt16ByID( KeyH aItemKey, sInt32 aID, sInt16 aValue, sInt32 arrIndex, string suff ) { return SetValueByID( aItemKey, aID,arrIndex, VALTYPE_INT16,&aValue, sizeof(aValue), suff ); } // SetInt16ByID /* sInt32 / uInt32 */ TSyError OceanBlue::GetInt32 ( KeyH aItemKey, string aValName, sInt32 &aValue, string suff ) { memSize vSize; return GetValue ( aItemKey, aValName, VALTYPE_INT32,&aValue, sizeof(aValue),vSize, suff ); } // GetInt32 TSyError OceanBlue::GetInt32 ( KeyH aItemKey, string aValName, uInt32 &aValue, string suff ) { memSize vSize; return GetValue ( aItemKey, aValName, VALTYPE_INT32,&aValue, sizeof(aValue),vSize, suff ); } // GetInt32 TSyError OceanBlue::GetInt32ByID( KeyH aItemKey, sInt32 aID, sInt32 &aValue, sInt32 arrIndex, string suff ) { memSize vSize; return GetValueByID( aItemKey, aID,arrIndex, VALTYPE_INT32,&aValue, sizeof(aValue),vSize, suff ); } // GetInt32ByID TSyError OceanBlue::GetInt32ByID( KeyH aItemKey, sInt32 aID, uInt32 &aValue, sInt32 arrIndex, string suff ) { memSize vSize; return GetValueByID( aItemKey, aID,arrIndex, VALTYPE_INT32,&aValue, sizeof(aValue),vSize, suff ); } // GetInt32ByID TSyError OceanBlue::SetInt32 ( KeyH aItemKey, string aValName, sInt32 aValue, string suff ) { return SetValue ( aItemKey, aValName, VALTYPE_INT32,&aValue, sizeof(aValue), suff ); } // SetInt32 TSyError OceanBlue::SetInt32ByID( KeyH aItemKey, sInt32 aID, sInt32 aValue, sInt32 arrIndex, string suff ) { return SetValueByID( aItemKey, aID,arrIndex, VALTYPE_INT32,&aValue, sizeof(aValue), suff ); } // SetInt32ByID /* -------------------------------------------------------------------------------- */ #if defined MACOSX && defined __MWERKS__ #pragma export on #endif /* ---- MODULE -------------------------------------------------------------------- */ static MyAdapter_Module* SW_Mo( CContext mc ) { return (MyAdapter_Module*)mc; } TSyError Module_CreateContext( CContext *mc, cAppCharP moduleName, cAppCharP subName, cAppCharP mContextName, DB_Callback mCB ) { MyAdapter_Module* swm= new MyAdapter_Module; if (swm==NULL) return DB_Full; swm->fCB = mCB; swm->fModName = moduleName; swm->fContextName= mContextName; TSyError err= swm->CreateContext ( subName ); if (err)delete swm; else *mc= (CContext)swm; return err; } // Module_CreateContext CVersion Module_Version ( CContext mc ) { if (!mc ) return Plugin_Version( 0 ); return SW_Mo( mc )->Version(); } // Module_Version TSyError Module_Capabilities( CContext mc, appCharP *capa ) { return SW_Mo( mc )->Capabilities ( *capa ); } // Module_Capabilities TSyError Module_PluginParams( CContext mc, cAppCharP mConfigParams, CVersion engineVersion ) { return SW_Mo( mc )->PluginParams ( mConfigParams, engineVersion ); } // Module_PluginParams void Module_DisposeObj ( CContext mc, void* memory ) { SW_Mo( mc )->DisposeObj ( memory ); } // Module_DisposeObj TSyError Module_DeleteContext( CContext mc ) { MyAdapter_Module* swm= SW_Mo( mc ); TSyError err= swm->DeleteContext(); delete swm; return err; } // Module_DeleteContext /* ---- SESSION ------------------------------------------------------------------- */ static MyAdapter_Session* SW_Se( CContext sc ) { return (MyAdapter_Session*)sc; } TSyError Session_CreateContext ( CContext *sc, cAppCharP sessionName, DB_Callback sCB ) { MyAdapter_Session* sws= new MyAdapter_Session; if (sws==NULL) return DB_Full; sws->fCB = sCB; sws->fSessionName= sessionName; TSyError err= sws->CreateContext(); if (err)delete sws; else *sc= (CContext)sws; return err; } // Session_CreateContext // -- device TSyError Session_CheckDevice ( CContext sc, cAppCharP aDeviceID, appCharP *sDevKey, appCharP *nonce ) { return SW_Se( sc )->CheckDevice ( aDeviceID, *sDevKey,*nonce ); } // Session_CheckDevice TSyError Session_GetNonce ( CContext sc, appCharP *nonce ) { return SW_Se( sc )->GetNonce ( *nonce ); } // Session_GetNonce TSyError Session_SaveNonce ( CContext sc, cAppCharP nonce ) { return SW_Se( sc )->SaveNonce ( nonce ); } // Session_SaveNonce TSyError Session_SaveDeviceInfo( CContext sc, cAppCharP aDeviceInfo ) { return SW_Se( sc )->SaveDeviceInfo ( aDeviceInfo ); } // Session_SaveDeviceInfo TSyError Session_GetDBTime ( CContext sc, appCharP *currentDBTime ) { return SW_Se( sc )->GetDBTime ( *currentDBTime ); } // Session_GetDBTime // -- login sInt32 Session_PasswordMode( CContext sc ) { return SW_Se( sc )->PasswordMode(); } // Session_PasswordMode TSyError Session_Login ( CContext sc, cAppCharP sUsername, appCharP *sPassword, appCharP *sUsrKey ) { return SW_Se( sc )->Login ( sUsername, *sPassword, *sUsrKey ); } // Session_Login TSyError Session_Logout( CContext sc ) { return SW_Se( sc )->Logout(); } // Session_Logout // -- general void Session_DisposeObj( CContext sc, void* memory ) { SW_Se( sc )->DisposeObj ( memory ); } // Session_DisposeObj void Session_ThreadMayChangeNow( CContext sc ) { SW_Se( sc )->ThreadMayChangeNow(); } // Session_ThreadMayChangeNow void Session_DispItems ( CContext sc, bool allFields, cAppCharP specificItem ) { SW_Se( sc )->DispItems ( allFields, specificItem ); } // Session_DispItems TSyError Session_AdaptItem ( CContext sc, appCharP *sItemData1, appCharP *sItemData2, appCharP *sLocalVars, uInt32 sIdentifier ) { return SW_Se( sc )->Adapt_Item( *sItemData1, *sItemData2, *sLocalVars, sIdentifier ); } // Session_AdaptItem TSyError Session_DeleteContext( CContext sc ) { MyAdapter_Session* sws= SW_Se( sc ); TSyError err= sws->DeleteContext(); delete sws; return err; } // Session_DeleteContext /* ---- DATASTORE ----------------------------------------------------------------- */ static MyAdapter* SW( CContext ac ) { return (MyAdapter*)ac; } TSyError CreateContext( CContext *ac, cAppCharP aContextName, DB_Callback aCB, cAppCharP sDevKey, cAppCharP sUsrKey ) { MyAdapter* sw= new MyAdapter; if (sw==NULL) return DB_Full; sw->fCB = aCB; sw->fContextName= aContextName; sw->fAsAdmin= IsAdmin( sw->fContextName ); TSyError err= sw->CreateContext( sDevKey,sUsrKey ); if (err) delete sw; else *ac= (CContext)sw; return err; } // CreateContext uInt32 ContextSupport( CContext ac, cAppCharP aContextRules ) { return SW( ac )->ContextSupport ( aContextRules ); } // ContextSupport uInt32 FilterSupport ( CContext ac, cAppCharP aFilterRules ) { return SW( ac )->FilterSupport ( aFilterRules ); } // FilterSupport // -- admin TSyError LoadAdminData ( CContext ac, cAppCharP aLocDB, cAppCharP aRemDB, appCharP *adminData ) { return SW( ac )->LoadAdminData ( aLocDB, aRemDB, *adminData ); } // LoadAdminData TSyError LoadAdminDataAsKey( CContext ac, cAppCharP aLocDB, cAppCharP aRemDB, KeyH adminKey ) { return SW( ac )->LoadAdminDataAsKey ( aLocDB, aRemDB, adminKey ); } // LoadAdminDataAsKey TSyError SaveAdminData ( CContext ac, cAppCharP adminData ) { return SW( ac )->SaveAdminData ( adminData ); } // SaveAdminData TSyError SaveAdminDataAsKey( CContext ac, KeyH adminKey ) { return SW( ac )->SaveAdminDataAsKey ( adminKey ); } // SaveAdminDataAsKey bool ReadNextMapItem ( CContext ac, MapID mID, bool aFirst ) { return SW( ac )->ReadNextMapItem ( mID, aFirst ); } // ReadNextMapItem TSyError InsertMapItem ( CContext ac, cMapID mID ) { return SW( ac )->InsertMapItem ( mID ); } // InsertMapItem TSyError UpdateMapItem ( CContext ac, cMapID mID ) { return SW( ac )->UpdateMapItem ( mID ); } // UpdateMapItem TSyError DeleteMapItem ( CContext ac, cMapID mID ) { return SW( ac )->DeleteMapItem ( mID ); } // DeleteMapItem // -- read TSyError StartDataRead ( CContext ac, cAppCharP lastToken, cAppCharP resumeToken ) { return SW( ac )->StartDataRead ( lastToken, resumeToken ); } // StartDataRead TSyError ReadNextItem ( CContext ac, ItemID aID, appCharP *aItemData, sInt32 *aStatus, bool aFirst ) { return SW( ac )->ReadNextItem ( aID, *aItemData, *aStatus, aFirst ); } // ReadNextItem TSyError ReadNextItemAsKey( CContext ac, ItemID aID, KeyH aItemKey, sInt32 *aStatus, bool aFirst ) { return SW( ac )->ReadNextItemAsKey ( aID, aItemKey, *aStatus, aFirst ); } // ReadNextItemAsKey TSyError ReadItem ( CContext ac, cItemID aID, appCharP *aItemData ) { return SW( ac )->ReadItem ( aID, *aItemData ); } // ReadItem TSyError ReadItemAsKey ( CContext ac, cItemID aID, KeyH aItemKey ) { return SW( ac )->ReadItemAsKey ( aID, aItemKey ); } // ReadItemAsKey TSyError EndDataRead ( CContext ac ) { return SW( ac )->EndDataRead(); } // EndDataRead // -- write TSyError StartDataWrite ( CContext ac ) { return SW( ac )->StartDataWrite(); } // StartDataWrite TSyError InsertItem ( CContext ac, cAppCharP aItemData, ItemID newID ) { return SW( ac )->InsertItem ( aItemData, newID ); } // InsertItem TSyError InsertItemAsKey( CContext ac, KeyH aItemKey, ItemID newID ) { return SW( ac )->InsertItemAsKey ( aItemKey, newID ); } // InsertItemAsKey TSyError UpdateItem ( CContext ac, cAppCharP aItemData, cItemID aID, ItemID updID ) { return SW( ac )->UpdateItem ( aItemData, aID, updID ); } // UpdateItem TSyError UpdateItemAsKey( CContext ac, KeyH aItemKey, cItemID aID, ItemID updID ) { return SW( ac )->UpdateItemAsKey ( aItemKey, aID, updID ); } // UpdateItemAsKey TSyError MoveItem ( CContext ac, cItemID aID, cAppCharP newParID ) { return SW( ac )->MoveItem ( aID, newParID ); } // MoveItem TSyError DeleteItem ( CContext ac, cItemID aID ) { return SW( ac )->DeleteItem ( aID ); } // DeleteItem TSyError FinalizeLocalID( CContext ac, cItemID aID, ItemID updID ) { return SW( ac )->FinalizeLocalID ( aID, updID ); } // FinalizeLocalID TSyError DeleteSyncSet ( CContext ac ) { return SW( ac )->DeleteSyncSet(); } // DeleteSyncSet TSyError EndDataWrite ( CContext ac, bool success, appCharP *newToken ) { return SW( ac )->EndDataWrite ( success, *newToken ); } // EndDataWrite // -- blobs TSyError ReadBlob ( CContext ac, cItemID aID, cAppCharP aBlobID, appPointer *aBlkPtr, memSize *aBlkSize, memSize *aTotSize, bool aFirst, bool *aLast ) { return SW( ac )->ReadBlob ( aID,aBlobID, *aBlkPtr,*aBlkSize,*aTotSize, aFirst,*aLast ); } // ReadBlob TSyError WriteBlob ( CContext ac, cItemID aID, cAppCharP aBlobID, appPointer aBlkPtr, memSize aBlkSize, memSize aTotSize, bool aFirst, bool aLast ) { return SW( ac )->WriteBlob ( aID,aBlobID, aBlkPtr, aBlkSize, aTotSize, aFirst, aLast ); } // WriteBlob TSyError DeleteBlob( CContext ac, cItemID aID, cAppCharP aBlobID ) { return SW( ac )->DeleteBlob( aID,aBlobID ); } // DeleteBlob // -- general void WriteLogData( CContext ac, cAppCharP logData ) { SW( ac )->WriteLogData ( logData ); } // WriteLogData void DisposeObj ( CContext ac, void* memory ) { SW( ac )->DisposeObj ( memory ); } // DisposeObj void ThreadMayChangeNow( CContext ac ) { SW( ac )->ThreadMayChangeNow(); } // ThreadMayChangeNow void DispItems ( CContext ac, bool allFields, cAppCharP specificItem ) { SW( ac )->DispItems ( allFields, specificItem ); } // DispItems TSyError AdaptItem ( CContext ac, appCharP *aItemData1, appCharP *aItemData2, appCharP *aLocalVars, uInt32 aIdentifier ) { return SW( ac )->Adapt_Item( *aItemData1, *aItemData2, *aLocalVars, aIdentifier ); } // AdaptItem TSyError DeleteContext( CContext ac ) { MyAdapter* sw= SW( ac ); TSyError err= sw->DeleteContext(); delete sw; return err; } // DeleteContext } // namespace /* eof */ libsynthesis-3.4.0.47.1/src/sysync_SDK/DB_Interfaces/snowwhite/oceanblue.h000066400000000000000000000304531226375725500262560ustar00rootroot00000000000000/* * File: oceanblue.h * * Author: Beat Forster (bfo@synthesis.ch) * * Base class for datastore plugins in C++ * * Copyright (c) 2008-2011 by Synthesis AG + plan44.ch * */ #ifndef OCEANBLUE_H #define OCEANBLUE_H #include "sync_include.h" // include general SDK definitions #include "sync_dbapidef.h" // include the interface file and utilities #include "SDK_util.h" // include SDK utilities #include "SDK_support.h" // include more SDK support // There are reference implementations for admin data handling and for BLOBs // But they needn't to be used. The "target_options.h" defines whether to use them #ifndef DISABLE_PLUGIN_DATASTOREADMIN #include "admindata.h" #endif #ifndef DISABLE_PLUGIN_BLOBS #include "blobs.h" #endif // Use them in two different namespaces namespace oceanblue { using sysync::sInt16; using sysync::uInt16; using sysync::sInt32; using sysync::uInt32; using sysync::appPointer; using sysync::memSize; using sysync::DB_Callback; using sysync::MapID; using sysync::cMapID; using sysync::ItemID; using sysync::cItemID; using sysync::KeyH; #ifndef DISABLE_PLUGIN_DATASTOREADMIN using sysync::TAdminData; #endif #ifndef DISABLE_PLUGIN_BLOBS using sysync::TBlob; #endif // The three classes "OceanBlue_Module", "OceanBlue_Session" and "OceanBlue" should // be derived as shown in the "snowwhite" adapter example. // It is intended not to change this module, but only the derived adapter. // The name of the derived adapter is defined "myadapter.h" // Module access class OceanBlue_Module { public: virtual ~OceanBlue_Module() { }; // virtual destructor DB_Callback fCB; // local callback reference string fModName; // the module name string fContextName; // the context name virtual TSyError CreateContext ( cAppCharP subName ); virtual CVersion Version(); virtual TSyError Capabilities ( appCharP &mCapabilities ); virtual TSyError PluginParams ( cAppCharP mConfigParams, CVersion engineVersion ); virtual void DisposeObj ( void* memory ); virtual TSyError DeleteContext(); }; // OceanBlue_Module // Session access class OceanBlue_Session { public: virtual ~OceanBlue_Session() { }; // virtual destructor DB_Callback fCB; // local callback reference string fSessionName; // the session name virtual TSyError CreateContext(); // -- device virtual TSyError CheckDevice ( cAppCharP aDeviceID, appCharP &sDevKey, appCharP &nonce ); virtual TSyError GetNonce ( appCharP &nonce ); virtual TSyError SaveNonce ( cAppCharP nonce ); virtual TSyError SaveDeviceInfo ( cAppCharP aDeviceInfo ); virtual TSyError GetDBTime ( appCharP ¤tDBTime ); // -- login virtual sInt32 PasswordMode(); virtual TSyError Login ( cAppCharP sUsername, appCharP &sPassword, appCharP &sUsrKey ); virtual TSyError Logout(); // -- general virtual void DisposeObj ( void* memory ); virtual void ThreadMayChangeNow(); virtual void DispItems ( bool allFields, cAppCharP specificItem ); virtual TSyError Adapt_Item ( appCharP &sItemData1, appCharP &sItemData2, appCharP &sLocalVars, uInt32 sIdentifier ); virtual TSyError DeleteContext(); }; // OceanBlue_Session // Datastore access class OceanBlue { public: virtual ~OceanBlue() { }; // virtual destructor DB_Callback fCB; // local callback reference string fContextName; // the context name bool fAsAdmin; // true, if it is admin context uInt32 fNthItem; #ifndef DISABLE_PLUGIN_DATASTOREADMIN TAdminData fAdmin; // an internal ADMIN implementation can be used #endif #ifndef DISABLE_PLUGIN_BLOBS TBlob fBlob; // an internal BLOB implementation can be used #endif virtual TSyError CreateContext ( cAppCharP sDevKey, cAppCharP sUsrKey ); virtual uInt32 ContextSupport ( cAppCharP aContextRules ); virtual uInt32 FilterSupport ( cAppCharP aFilterRules ); // -- admin virtual TSyError LoadAdminData ( cAppCharP aLocDB, cAppCharP aRemDB, appCharP &adminData ); virtual TSyError LoadAdminDataAsKey( cAppCharP aLocDB, cAppCharP aRemDB, KeyH adminKey ); virtual TSyError SaveAdminData ( cAppCharP adminData ); virtual TSyError SaveAdminDataAsKey ( KeyH adminKey ); virtual bool ReadNextMapItem ( MapID mID, bool aFirst ); virtual TSyError InsertMapItem ( cMapID mID ); virtual TSyError UpdateMapItem ( cMapID mID ); virtual TSyError DeleteMapItem ( cMapID mID ); // -- read virtual TSyError StartDataRead ( cAppCharP lastToken, cAppCharP resumeToken ); virtual TSyError ReadNextItem ( ItemID aID, appCharP &aItemData, sInt32 &aStatus, bool aFirst ); virtual TSyError ReadNextItemAsKey ( ItemID aID, KeyH aItemKey, sInt32 &aStatus, bool aFirst ); virtual TSyError ReadItem ( cItemID aID, appCharP &aItemData ); virtual TSyError ReadItemAsKey ( cItemID aID, KeyH aItemKey ); virtual TSyError EndDataRead(); // -- write virtual TSyError StartDataWrite(); virtual TSyError InsertItem ( cAppCharP aItemData, ItemID newID ); virtual TSyError InsertItemAsKey( KeyH aItemKey, ItemID newID ); virtual TSyError UpdateItem ( cAppCharP aItemData, cItemID aID, ItemID updID ); virtual TSyError UpdateItemAsKey( KeyH aItemKey, cItemID aID, ItemID updID ); virtual TSyError MoveItem ( cItemID aID, cAppCharP newParID ); virtual TSyError DeleteItem ( cItemID aID ); virtual TSyError FinalizeLocalID ( cItemID aID, ItemID updID ); virtual TSyError DeleteSyncSet(); virtual TSyError EndDataWrite ( bool success, appCharP &newToken ); // -- blobs virtual TSyError ReadBlob ( cItemID aID, cAppCharP aBlobID, appPointer &aBlkPtr, memSize &aBlkSize, memSize &aTotSize, bool aFirst, bool &aLast ); virtual TSyError WriteBlob ( cItemID aID, cAppCharP aBlobID, appPointer aBlkPtr, memSize aBlkSize, memSize aTotSize, bool aFirst, bool aLast ); virtual TSyError DeleteBlob ( cItemID aID, cAppCharP aBlobID ); // -- general virtual void WriteLogData ( cAppCharP logData ); virtual void DisposeObj ( void* memory ); virtual void ThreadMayChangeNow(); virtual void DispItems ( bool allFields, cAppCharP specificItem ); virtual TSyError Adapt_Item ( appCharP &aItemData1, appCharP &aItemData2, appCharP &aLocalVars, uInt32 aIdentifier ); virtual TSyError DeleteContext(); // ---- call-in functions ---- virtual sInt32 GetValueID ( KeyH aItemKey, string aValName, string suff="" ); virtual TSyError GetValue ( KeyH aItemKey, string aValName, uInt16 aValType, appPointer aBuffer, memSize aBufSize, memSize &aValSize, string suff="" ); virtual TSyError GetValueByID( KeyH aItemKey, sInt32 aID, sInt32 arrIndex, uInt16 aValType, appPointer aBuffer, memSize aBufSize, memSize &aValSize, string suff="" ); virtual TSyError SetValue ( KeyH aItemKey, string aValName, uInt16 aValType, appPointer aBuffer, memSize aValSize, string suff="" ); virtual TSyError SetValueByID( KeyH aItemKey, sInt32 aID, sInt32 arrIndex, uInt16 aValType, appPointer aBuffer, memSize aValSize, string suff="" ); // ---- convenience routines to access Get/SetValue for specific types ---- /* string */ virtual TSyError GetStr ( KeyH aItemKey, string aValName, string &aText, string suff="" ); virtual TSyError GetStrByID ( KeyH aItemKey, sInt32 aID, string &aText, sInt32 arrIndex= 0, string suff="" ); virtual TSyError SetStr ( KeyH aItemKey, string aValName, string aText, string suff="" ); virtual TSyError SetStrByID ( KeyH aItemKey, sInt32 aID, string aText, sInt32 arrIndex= 0, string suff="" ); /* sInt16 / uInt16 */ virtual TSyError GetInt16 ( KeyH aItemKey, string aValName, sInt16 &aValue, string suff="" ); virtual TSyError GetInt16 ( KeyH aItemKey, string aValName, uInt16 &aValue, string suff="" ); virtual TSyError GetInt16ByID( KeyH aItemKey, sInt32 aID, sInt16 &aValue, sInt32 arrIndex= 0, string suff="" ); virtual TSyError GetInt16ByID( KeyH aItemKey, sInt32 aID, uInt16 &aValue, sInt32 arrIndex= 0, string suff="" ); virtual TSyError SetInt16 ( KeyH aItemKey, string aValName, sInt16 aValue, string suff="" ); virtual TSyError SetInt16ByID( KeyH aItemKey, sInt32 aID, sInt16 aValue, sInt32 arrIndex= 0, string suff="" ); /* sInt32 / uInt32 */ virtual TSyError GetInt32 ( KeyH aItemKey, string aValName, sInt32 &aValue, string suff="" ); virtual TSyError GetInt32 ( KeyH aItemKey, string aValName, uInt32 &aValue, string suff="" ); virtual TSyError GetInt32ByID( KeyH aItemKey, sInt32 aID, sInt32 &aValue, sInt32 arrIndex= 0, string suff="" ); virtual TSyError GetInt32ByID( KeyH aItemKey, sInt32 aID, uInt32 &aValue, sInt32 arrIndex= 0, string suff="" ); virtual TSyError SetInt32 ( KeyH aItemKey, string aValName, sInt32 aValue, string suff="" ); virtual TSyError SetInt32ByID( KeyH aItemKey, sInt32 aID, sInt32 aValue, sInt32 arrIndex= 0, string suff="" ); /* suffix handling */ virtual void AppendSuffixToID( KeyH aItemKey, sInt32 &aID, cAppCharP suff ); }; // OceanBlue } // namespace #endif // OCEANBLUE_H /* eof */ libsynthesis-3.4.0.47.1/src/sysync_SDK/DB_Interfaces/snowwhite/snowwhite.cpp000066400000000000000000000262571226375725500267120ustar00rootroot00000000000000/* * File: snowwhite.cpp * * Author: Beat Forster (bfo@synthesis.ch) * * * Programming interface between Synthesis SyncML engine * and a database structure. * * Copyright (c) 2008-2011 by Synthesis AG + plan44.ch * * * E X A M P L E C O D E * ======================== * (To be used as starting point for SDK development. * It can be adapted and extended by programmer) * */ #include "myadapter.h" namespace oceanblue { using sysync::memSize; using sysync::stringSize; using sysync::appChar; using sysync::LOCERR_OK; using sysync::DB_Forbidden; using sysync::DB_NotFound; using sysync::Password_MD5_OUT; using sysync::ReadNextItem_Unchanged; using sysync::ReadNextItem_EOF; using sysync::VP_GlobMulti; using sysync::VALTYPE_TIME64; using sysync::MinVersion; using sysync::Manufacturer; using sysync::Description; using sysync::YesField; using sysync::IntStr; using sysync::Parans; #define BuildNumber 1 // user defined build number, can be 0..255 #define MyDB MyAdapter_Name // plugin module's name #define Example_UsrKey "5678" #define ItemRdOffs 12000 // examples: first valid item for reading #define ItemOffs 15000 // first valid item // ---- module ----------------------------------------------------------------------------- // If your implementation has a higher build number, override it as done here CVersion MyAdapter_Module::Version() { CVersion v= Plugin_Version( BuildNumber ); // an individual build number DEBUG_DB( fCB, MyDB,Mo_Ve, "%08X", v ); // NOTE: do not change the version number itself return v; // as it used by the engine to } // Version // guarantee up/downwards compatibility // If your implementation has special capabilities, override them here // Your company's name and the plugin descriptiom should be added here TSyError MyAdapter_Module::Capabilities( appCharP &capa ) { string s = MyPlatform(); // some standard identifiers s+= '\n'; s+= DLL_Info; Manufacturer ( s, "Plugin GmbH" ); // **** your company's name **** string desc = MyAdapter_Name; desc+= " Plugin"; Description ( s, desc ); // **** your plugin's description **** MinVersion ( s, VP_GlobMulti ); // at least V1.5.1 YesField ( s, CA_ADMIN_Info ); // show "ADMIN" info YesField ( s, CA_ItemAsKey ); // use the routines capa= StrAlloc( s.c_str() ); return LOCERR_OK; } // Capabilities // ---- session ---------------------------------------------------------------------------- // Example password mode sInt32 MyAdapter_Session::PasswordMode() { int mode= Password_MD5_OUT; return mode; } /* Session_PasswordMode */ // Example login allowed for super:user MD5 login, resulting in = "5678" TSyError MyAdapter_Session::Login( cAppCharP sUsername, appCharP &sPassword, appCharP &sUsrKey ) { cAppCharP MD5_OUT_SU= "11JrMX94iTR1ob5KZFtEwQ=="; // the MD5B64 example for "super:user" TSyError err= DB_Forbidden; // default if (strcmp( sUsername,"super" )==0) { // an example account ("super"), hard coded here err = LOCERR_OK; sPassword= StrAlloc( MD5_OUT_SU ); sUsrKey = StrAlloc( Example_UsrKey ); // allows to access the datastore later } // if return err; } // Login // ---- utility routines ------------------------------------------------------------------- // set some contacts field as example void MyAdapter::SetContactFields( KeyH aItemKey, cAppCharP aFirst, cAppCharP aLast, cAppCharP aCity ) { SetInt32( aItemKey, "SYNCLVL", 10 ); // set some fields SetStr ( aItemKey, "N_FIRST", aFirst ); SetStr ( aItemKey, "N_LAST", aLast ); SetStr ( aItemKey, "ADR_W_CITY", aCity ); } // SetContactFields // set some events field as example void MyAdapter::SetEventFields ( KeyH aItemKey, cAppCharP aSum, cAppCharP aLoc, cAppCharP aMod, cAppCharP aStart, cAppCharP aEnd, bool allDay ) { SetInt32( aItemKey, "SYNCLVL", 10 ); // set some fields SetStr ( aItemKey, "KIND", "EVENT" ); SetStr ( aItemKey, "SUMMARY", aSum ); SetStr ( aItemKey, "LOCATION", aLoc ); SetStr ( aItemKey, "DMODIFIED", aMod ); SetStr ( aItemKey, "DTSTART", aStart ); SetStr ( aItemKey, "DTEND", aEnd ); SetInt32( aItemKey, "ALLDAY", allDay ); if (allDay) { sInt32 id= GetValueID( aItemKey, "DTSTART" ); SetStrByID( aItemKey,id, "DATE", 0,VALSUFF_TZNAME ); // timezone name } // if if (allDay) { sInt32 id= GetValueID( aItemKey, "DTEND" ); SetStrByID( aItemKey,id, "DATE", 0,VALSUFF_TZNAME ); // timezone name } // if } // SetEventFields // Get values: name, type, array size, timezone name of TSyError MyAdapter::GetFieldKey( KeyH aItemKey, sInt32 aID, string &aKey, uInt16 &aType, sInt32 &nFields, string &aTZ ) { TSyError err; aTZ= ""; err= GetStrByID ( aItemKey,aID, aKey, 0,VALSUFF_NAME ); if (err) return err; // field name err= GetInt16ByID( aItemKey,aID, aType, 0,VALSUFF_TYPE ); if (err) return err; // field type err= GetInt32ByID( aItemKey,aID, nFields, 0,VALSUFF_ARRSZ ); if (err) nFields= -1; // array size if (aType==VALTYPE_TIME64) { err= GetStrByID( aItemKey,aID, aTZ, 0,VALSUFF_TZNAME ); // timezone name } // if return LOCERR_OK; } // GetFieldKey // Display available fields of void MyAdapter::DisplayFields( KeyH aItemKey ) { cAppCharP DF= "Display_Fields"; TSyError err; sInt32 id; string vKey, vTZ, vName; uInt16 vType; sInt32 nFields; cAppCharP step= VALNAME_FIRST; while (true) { id = GetValueID ( aItemKey, step ); err= GetFieldKey( aItemKey, id, vKey,vType,nFields,vTZ ); if (err) break; bool isArr= nFields>=0; // check array condition if (isArr) DEBUG_DB( fCB, MyDB,DF, " (%2d) %s: **ARRAY** %d", vType, vKey.c_str(), nFields ); else nFields= 1; // not an array -> 1 element if (vTZ!="") vTZ= " " + Parans( "TZNAME=" + vTZ ); // for each array element do ... for (int i= 0; i // just return 15000,15001,... as valid item ids // please choose a persistent solution for a real implementation fCreItem= ItemOffs; return inherited::CreateContext( sDevKey,sUsrKey ); // and call the base method } // CreateContext // Example routine: Return 4 valid items 12000 .. 12003 TSyError MyAdapter::ReadNextItemAsKey( ItemID aID, KeyH /* aItemKey */, sInt32 &aStatus, bool aFirst ) { // Example: Constant 4 valid contact items or 2 event items for this example // See "ReadItemAsKey" for details of this example uInt32 n= 0; if (fContextName=="contacts") n= 4; if (fContextName=="events" ) n= 2; if (aFirst) fNthItem= 0; // re-initialize it if (fNthItem>=n) { aStatus= ReadNextItem_EOF; return LOCERR_OK; } // Create items 12000 .. aID->item= StrAlloc( IntStr( ItemRdOffs+fNthItem ).c_str() ); fNthItem++; // next aStatus= ReadNextItem_Unchanged; return LOCERR_OK; } // ReadNextItemAsKey // Example routine: Return 4 valid items 12000..12003 for contacts // 2 valid items 12000..12001 for events TSyError MyAdapter::ReadItemAsKey( cItemID aID, KeyH aItemKey ) { TSyError err= LOCERR_OK; string s = aID->item; do { if (fContextName=="contacts") { if (s=="12000") { SetContactFields( aItemKey, "Johann Sebastian","Bach", "Leipzig" ); break; } if (s=="12001") { SetContactFields( aItemKey, "Wolfgang Amadeus","Mozart", "Salzburg" ); break; } if (s=="12002") { SetContactFields( aItemKey, "Richard", "Wagner", "Bayreuth" ); break; } if (s=="12003") { SetContactFields( aItemKey, "Giacomo", "Puccini","Lucca" ); break; } } // if if (fContextName=="events") { // can have the same IDs as contacts, because they are independent if (s=="12000") { SetEventFields ( aItemKey, "Sechsel\xC3\xA4uten", "Bellevue", "20081110T140000Z", "20090420", "20090421" ); break; } if (s=="12001") { SetEventFields ( aItemKey, "Knabenschiessen", "Albisg\xC3\xBC\x65tli", "20081110T140000", "20090914T041500", "20090915T17" ); break; } } // if // not found err= DB_NotFound; } while (false); return err; } // ReadItemAsKey // Example routine: Debug display of the item contents. // Return item names 15000 ... TSyError MyAdapter::InsertItemAsKey( KeyH aItemKey, ItemID newID ) { // **** implementation for inserting an item must be added here **** TSyError err; sInt32 id; // ---- as an example, first and last name will be read ---- string vFirst, vLast; err= GetStr ( aItemKey, "N_FIRST", vFirst ); // get it directly id = GetValueID( aItemKey, "N_LAST" ); // or get it via id err= GetStrByID( aItemKey, id, vLast ); DEBUG_DB( fCB, MyDB,Da_IIK, "%08X %s %s", aItemKey, vFirst.c_str(),vLast.c_str() ); // ---- this is a simple loop to show the contents of each field of an item ---- DisplayFields( aItemKey ); // just return 15000, 15001, ... as valid item ids newID->item= StrAlloc( IntStr( fCreItem++ ).c_str() ); return LOCERR_OK; } // InsertItemAsKey TSyError MyAdapter::UpdateItemAsKey( KeyH aItemKey, cItemID /* aID */, ItemID /* updID */ ) { // **** implementation for updating an item must be added here **** DEBUG_DB( fCB, MyDB,Da_UIK, "%08X", aItemKey ); DisplayFields( aItemKey ); return LOCERR_OK; } // UpdateItemAsKey TSyError MyAdapter::DeleteItem( cItemID /* aID */ ) { // **** implementation for deleting an item must be added here **** return DB_NotFound; } // DeleteItem } // namespace /* eof */ libsynthesis-3.4.0.47.1/src/sysync_SDK/DB_Interfaces/snowwhite/snowwhite.h000066400000000000000000000054031226375725500263450ustar00rootroot00000000000000/* * File: snowwhite.h * * Author: Beat Forster (bfo@synthesis.ch) * * Datastore plugin classes which is derived * from the "oceanblue" classes. * * Copyright (c) 2008-2011 by Synthesis AG + plan44.ch * */ #ifndef SNOWWHITE_H #define SNOWWHITE_H #include "myadapter.h" #include "sync_include.h" #include "oceanblue.h" namespace oceanblue { class MyAdapter_Module : public OceanBlue_Module { typedef OceanBlue_Module inherited; public: /**** any of the OceanBlue_Module methods can be overriden ****/ CVersion Version(); TSyError Capabilities( appCharP &capa ); }; // MyAdapter_Module class MyAdapter_Session : public OceanBlue_Session { typedef OceanBlue_Session inherited; public: /**** any of the OceanBlue_Session methods can be overriden ****/ sInt32 PasswordMode(); TSyError Login( cAppCharP sUsername, appCharP &sPassword, appCharP &sUsrKey ); }; // MyAdapter_Session class MyAdapter : public OceanBlue { typedef OceanBlue inherited; private: uInt32 fCreItem; // an internal number for new item creation // Fill example items void SetContactFields( KeyH aItemKey, cAppCharP aFirst, cAppCharP aLast, cAppCharP aCity ); void SetEventFields ( KeyH aItemKey, cAppCharP aSum, cAppCharP aLoc, cAppCharP aMod, cAppCharP aStart, cAppCharP aEnd, bool allday= true ); // Get field information TSyError GetFieldKey ( KeyH aItemKey, sInt32 aID, string &aKey, uInt16 &aType, sInt32 &nFields, string &aTZ ); // Display fields of the work item void DisplayFields ( KeyH aItemKey ); public: /**** any of the OceanBlue methods can be overriden ****/ TSyError CreateContext ( cAppCharP sDevKey, cAppCharP sUsrKey ); // for this example, the methods will be used TSyError ReadNextItemAsKey ( ItemID aID, KeyH aItemKey, sInt32 &aStatus, bool aFirst ); TSyError ReadItemAsKey ( cItemID aID, KeyH aItemKey ); TSyError InsertItemAsKey ( KeyH aItemKey, ItemID newID ); TSyError UpdateItemAsKey ( KeyH aItemKey, cItemID aID, ItemID updID ); TSyError DeleteItem ( cItemID aID ); }; // MyAdapter } // namespace #endif // SNOWWHITE_H /* eof */ libsynthesis-3.4.0.47.1/src/sysync_SDK/DB_Interfaces/text_db/000077500000000000000000000000001226375725500235455ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/sysync_SDK/DB_Interfaces/text_db/DLL/000077500000000000000000000000001226375725500241605ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/sysync_SDK/DB_Interfaces/text_db/DLL/target_options.h000066400000000000000000000015341226375725500273750ustar00rootroot00000000000000/* * File: target_options.h * * Author: Beat Forster (bfo@synthesis.ch) * * Programming interface between Synthesis SyncML engine * and a database structure. * * Copyright (c) 2004-2011 by Synthesis AG + plan44.ch * */ #ifndef TARGET_OPTIONS_H #define TARGET_OPTIONS_H /* - find out target platform */ #ifdef __MACH__ #define MACOSX #else #if defined __MWERKS__ || defined _MSC_VER #ifndef _WIN32 #define _WIN32 #endif #else #define LINUX #endif #endif /* code is running within DLL */ #define SDK_DLL 1 /* - we are not at the SyncML engine's side here */ /* - and we need an extern "C" interface for the DLL */ #undef SYSYNC_ENGINE /* activate debug output */ #define SYDEBUG 2 //#define DISABLE_PLUGIN_DATASTOREADMIN 1 //#define DISABLE_PLUGIN_BLOBS 1 #endif /* TARGET_OPTIONS_H */ /* eof */ libsynthesis-3.4.0.47.1/src/sysync_SDK/DB_Interfaces/text_db/sync_dbapi_text.cpp000066400000000000000000001316161226375725500274400ustar00rootroot00000000000000/* * File: sync_dbapi_text.cpp * * Author: Beat Forster (bfo@synthesis.ch) * * * Example DBApi database adapter plugin * Written in C++ * * Similar behaviour as the former "text_db". * (with extensions for ARRAY and BLOB access) * * For newer engine versions, this sample code * is 1:1 used as datastore connector for the * so called demo server/client. * * Copyright (c) 2005-2011 by Synthesis AG + plan44.ch * * * E X A M P L E C O D E * (text_db interface) * */ #include "sync_include.h" // include general SDK definitions #include "sync_dbapidef.h" // include the interface file and utilities #include "SDK_util.h" // include SDK utilities #include "SDK_support.h" // and some C++ support functionality #ifndef SYSYNC_ENGINE // outside the SyncML engine we need additional stuff: #include "stringutil.h" // local implementation for CStr <=> Str conversions #include // isalnum #endif #include "admindata.h" // TAdminData class #include "blobs.h" // TBlob class #include "dbitem.h" // TDBItem class namespace SDK_textdb { // the plugin runs within a namespace using sysync::DB_Callback; // common definitions for both namespaces using sysync::ItemID_Struct; using sysync::ItemID; using sysync::cItemID; using sysync::MapID; using sysync::KeyH; using sysync::TDBItem; using sysync::TDBItemField; using sysync::TAdminData; using sysync::TBlob; using sysync::LOCERR_OK; using sysync::LOCERR_TOOOLD; using sysync::LOCERR_NOTIMP; using sysync::DB_Forbidden; using sysync::DB_NotFound; using sysync::DB_Full; using sysync::DB_Error; using sysync::Password_ClrText_IN; using sysync::Password_ClrText_OUT; using sysync::Password_MD5_Nonce_IN; using sysync::Password_MD5_OUT; using sysync::ReadNextItem_Unchanged; using sysync::ReadNextItem_Changed; using sysync::ReadNextItem_Resumed; using sysync::ReadNextItem_EOF; using sysync::VP_GlobMulti; using sysync::Manufacturer; using sysync::Description; using sysync::GContext; using sysync::MinVersion; using sysync::NoField; using sysync::YesField; using sysync::IsAdmin; using sysync::GlobContext; using sysync::GlobContextFound; using sysync::Apo; using sysync::IntStr; using sysync::VersionStr; using sysync::ConcatNames; using sysync::ConcatPaths; using sysync::CurrentTime; using sysync::CompareTokens; using sysync::CStrToStrAppend; #include "sync_dbapi.h" // include the interface file within the namespace #define BuildNumber 0 // User defined build number, initial value is 0 #define MyDB "TextDB" // textdb example debug name #if defined MACOSX && defined __MWERKS__ // export the items for Mac OS X as well #pragma export on // (for Windows, a ".def" file is required) #endif /* ------------------------------------------------------------------------------ */ /* File name prefixes for the textdb implementation */ #define P_Device "DEV_" // device info #define P_Data "TDB_" // textdb data #define P_NewItem "NID_" // new item id (for a persistent approach) /* -- MODULE -------------------------------------------------------------------- */ /* All the plugin's common variables are defined here * Normally there is just one such context per module. * These variables could be defined as global vars as well. * * The example here shows, how to handle a common AND a * module context in parallel. A module context will be * opened once for the Session environment and twice for * each Datastore (for the data and the admin part). * The idea is to have the session's plugin params as * default values for the datastore plugin params. These * default values (for gDataPath/gBlobPath and gMapPath) * will be stored at the common context. */ class CommonContext { public: CommonContext() { cInstalled = false; cEngineVersion= 0; // engine's version not yet available here cGlob = NULL; } bool cInstalled; // The module is already installed long cEngineVersion; // the engine's version GlobContext* cGlob; // structure for reaching the common context // --- local copies of ... // NOTE: These are default values if datatore specific // paths are not defined string cDataPath; // directory where to store data string cBlobPath; // " " " " BLOBs string cMapPath; // " " " " maps and admin data /* other elements can be defined here */ /* ... */ }; // CommonContext class ModuleContext { public: ModuleContext() { fCB= NULL; fCC= NULL; } // --- local copies of ... DB_Callback fCB; // the callback structure CommonContext* fCC; // reference to the common context string fModuleName; // the module's name string fSubName; // the sub path name (not used for textdb implementation) string fContextName; // the context name string fDataPath; // directory where to store data string fBlobPath; // " " " " BLOBs string fMapPath; // " " " " maps and admin data /* other elements can be defined here */ /* ... */ }; // ModuleContext /* will be casted to the ModuleContext* structure */ static ModuleContext* MoC( CContext mContext ) { return (ModuleContext*)mContext; } TSyError Module_CreateContext( CContext *mContext, cAppCharP moduleName, cAppCharP subName, cAppCharP mContextName, DB_Callback mCB ) { DEBUG_DB( mCB, MyDB,Mo_CC, "'%s' (%s)", ConcatNames( moduleName,subName ).c_str(), mContextName ); if (!CB_gContext( mCB )) return LOCERR_TOOOLD; // the new system is required ! ModuleContext* mc= new ModuleContext; // get the (unique) module context *mContext= (CContext)mc; // return the context variable mc->fModuleName = moduleName; // local copy of module's name mc->fSubName = subName; // " " " module's sub name mc->fContextName= mContextName; // " " " the contexts name (e.g. "contacts") mc->fCB = mCB; // " " " the callback reference string db= MyDB; #ifdef _MSC_VER db+= "_visual"; #endif #if defined __MACH__ && !defined __MWERKS__ db+= "_universal"; #endif GlobContext* g= (GlobContext*)mCB->gContext; if (GlobContextFound( db, g )) mc->fCC= (CommonContext*)g->ref; // connect the structure else { mc->fCC= new CommonContext; mc->fCC->cGlob= g; g->ref= mc->fCC; // connect the structure } // if g->cnt++; DEBUG_DB( mCB, MyDB,Mo_CC, "mContext=%08X gContext=%08X g->ref=%08X", *mContext, mCB->gContext, g->ref ); return LOCERR_OK; } // Module_CreateContext /* -- VERSION/CAPABILITIES ---- */ /* Get the plug-in's version number */ CVersion Module_Version( CContext mContext ) { /* The current plugin's SDK version is expected here */ CVersion v= Plugin_Version( BuildNumber ); if ( mContext ) DEBUG_DB( MoC( mContext )->fCB, MyDB,Mo_Ve, "%s", VersionStr( v ).c_str() ); return v; } /* Module_Version */ /* Get the plug-in's capabilities */ TSyError Module_Capabilities( CContext mContext, appCharP *mCapabilities ) { if (!mContext) return DB_Forbidden; ModuleContext* mc= MoC( mContext ); string s = MyPlatform(); s+= '\n'; s+= DLL_Info; Manufacturer( s, "Synthesis AG" ); // **** can be adapted *** Description ( s, "Text database module. Writes data directly to TDB_*.txt file" ); YesField ( s, CA_ADMIN_Info ); MinVersion ( s, VP_GlobMulti ); // at least V1.5.1 if (mc->fCC) { GContext( s, mc->fCC->cGlob ); } // if // Parts of the plug-in can be disabled (will not be connected and therefore not be used) // These settings are expected ath the "target_options.h" of the plugin #ifdef DISABLE_PLUGIN_SESSIONAUTH NoField( s, Plugin_SE_Auth ); #endif #ifdef DISABLE_PLUGIN_DEVICEADMIN NoField( s, Plugin_DV_Admin ); #endif #ifdef DISABLE_PLUGIN_DATASTOREADMIN NoField( s, Plugin_DS_Admin ); #endif #ifdef DISABLE_PLUGIN_DATASTOREDATA NoField( s, Plugin_DS_Data ); #endif *mCapabilities= StrAlloc( s.c_str() ); DEBUG_DB( mc->fCB, MyDB,Mo_Ca, "'%s'", *mCapabilities ); return LOCERR_OK; } // Module_Capabilities TSyError Module_PluginParams( CContext mContext, cAppCharP mConfigParams, CVersion engineVersion ) { /* Decide, which data path to take */ cAppCharP DataFilePath= "datafilepath"; // TDB_ cAppCharP BlobFilePath= "blobfilepath"; // BLB_ cAppCharP MapFilePath= "mapfilepath"; // DEV_ / ADM_ / MAP_ // ---- legacy, please use and for newer implementations #if defined LINUX || defined MACOSX cAppCharP DataPath= "unixpath"; #else cAppCharP DataPath= "winpath"; #endif // ---- END legacy ---- ModuleContext* mc= MoC( mContext ); DEBUG_DB ( mc->fCB, MyDB,Mo_PP, "EngineVersion: %s", VersionStr( engineVersion ).c_str() ); DEBUG_DB ( mc->fCB, MyDB,Mo_PP, "'%s'", mConfigParams ); // ------------------------------------------------------ // Get the data path for the textDB files char* vv; mc->fDataPath= mc->fCC->cDataPath; // as default // ---- legacy data path if (Field( mConfigParams, DataPath, &vv )) { mc->fDataPath= ""; CStrToStrAppend( vv, mc->fDataPath ); StrDispose ( vv ); } // if // ---- END legacy ---- // *** DATA PATH *** // overwrite it, if using new definition if (Field( mConfigParams, DataFilePath, &vv )) { mc->fDataPath= ""; CStrToStrAppend( vv, mc->fDataPath ); StrDispose ( vv ); } // if // *** BLOB PATH *** // the same for the BLOB files // take this as the default mc->fBlobPath= mc->fCC->cBlobPath; // take the global one if (mc->fBlobPath.empty()) mc->fBlobPath= mc->fDataPath; // or take the local data path if (mc->fBlobPath.empty()) mc->fBlobPath= mc->fCC->cDataPath; // or even more globally if (Field( mConfigParams, BlobFilePath, &vv )) { mc->fBlobPath= ""; CStrToStrAppend( vv, mc->fBlobPath ); StrDispose ( vv ); } // if // *** MAP PATH *** // and the same for the map/admin files // take this as the default mc->fMapPath= mc->fCC->cMapPath; // take the global one if (mc->fMapPath.empty()) mc->fMapPath= mc->fDataPath; // or take the local data path if (mc->fMapPath.empty()) mc->fMapPath= mc->fCC->cDataPath; // or even more globally if (Field( mConfigParams, MapFilePath, &vv )) { mc->fMapPath= ""; CStrToStrAppend( vv, mc->fMapPath ); StrDispose ( vv ); } // if // get global defaults when called for session context // Indication: fContextName> is empty. if (!mc->fCC->cInstalled && mc->fContextName.empty()) { mc->fCC->cDataPath = mc->fDataPath; mc->fCC->cBlobPath = mc->fBlobPath; mc->fCC->cMapPath = mc->fMapPath; } // if if (mc->fCC->cEngineVersion==0) // set it once mc->fCC->cEngineVersion= engineVersion; mc->fCC->cInstalled= true; // now it's really installed return LOCERR_OK; } // Module_PluginParams /* Dispose the memory of the module context */ void Module_DisposeObj( CContext mContext, void* memory ) { ModuleContext* mc= MoC( mContext ); DEBUG_Exotic_DB( mc->fCB, MyDB,Mo_DO, "%d free at %08X '%s'", mc, memory,memory ); StrDispose ( memory ); } // Module_DisposeObj TSyError Module_DeleteContext( CContext mContext ) { ModuleContext* mc= MoC( mContext ); //printf( "DEL: '%s' %08X\n", mc->fModuleName.c_str(), mc->fCB->gContext ); DEBUG_DB ( mc->fCB, MyDB,Mo_DC, "'%s'", mc->fModuleName.c_str() ); GlobContext* g= mc->fCC->cGlob; g->cnt--; if (g->cnt==0) { CommonContext* cc= (CommonContext*)g->ref; delete cc; g->ref= NULL; } // if delete mc; return LOCERR_OK; } // Module_DeleteContext // ---------------------- session handling --------------------- #if !defined DISABLE_PLUGIN_DEVICEADMIN || !defined DISABLE_PLUGIN_DEVICEADMIN /*! Each session requires a session context, which will be created with * 'Session_CreateContext' and deleted with 'Session_DeleteContext'. */ class SessionContext { public: DB_Callback fCB; TDBItem fDevList; // The current device list TDBItem* fDev; // reference string fDeviceID; // stored value of 'CheckDevice' /* other elements can be defined here */ /* ... */ }; // SessionContext /* will be casted to the SessionContext* structure */ static SessionContext* SeC( CContext sContext ) { return (SessionContext*)sContext; } /* Create a context for a new session */ TSyError Session_CreateContext( CContext *sContext, cAppCharP sessionName, DB_Callback sCB ) { SessionContext* sc= new SessionContext; if (sc==NULL) return DB_Full; sc->fDev= NULL; sc->fCB = sCB; DEBUG_DB ( sc->fCB, MyDB,Se_CC, "%d '%s'", sc,sessionName ); *sContext= (CContext)sc; // return the context variable return LOCERR_OK; } // Session_CreateContext /* ----- "script-like" ADAPT --------- */ TSyError Session_AdaptItem( CContext sContext, appCharP *sItemData1, appCharP *sItemData2, appCharP *sLocalVars, uInt32 sIdentifier ) { /**** CAN BE ADAPTED BY USER ****/ SessionContext* sc= SeC( sContext ); DEBUG_DB ( sc->fCB, MyDB,"AdaptItem", "'%s' '%s' '%s' id=%d", *sItemData1,*sItemData2,*sLocalVars, sIdentifier ); return LOCERR_OK; } /* Session_AdaptItem */ /*! Create a alphanumerical string out of (ignore all other chars) * This is an internal utility proc. */ static string AlphaNum( cAppCharP aName ) { cAppCharP p= aName; string s; while (*p!='\0') { if (isalnum( *p )) s+= tolower( *p ); p++; } // while return s; } // AlphaNum #ifndef DISABLE_PLUGIN_DEVICEADMIN /* Check the database entry of and return its nonce string */ TSyError Session_CheckDevice( CContext sContext, cAppCharP aDeviceID, appCharP *sDevKey, appCharP *nonce ) { SessionContext* sc= SeC ( sContext ); ModuleContext* mc= MoC( sc->fCB->cContext ); TSyError err= LOCERR_OK; sc->fDeviceID= AlphaNum( aDeviceID ); string s= P_Device + sc->fDeviceID + ".txt"; sc->fDevList.fFileName= ConcatPaths( mc->fMapPath, s ); err= sc->fDevList.LoadDB( true, "DEV", sc->fCB ); // load the DEV file info if (!sc->fDev) { /* get the device */ sc->fDev= &sc->fDevList; bool found= ListNext( sc->fDev ); if (!found) { /* not found -> create such an element */ err= sc->fDevList.CreateEmptyItem( s, sc->fDev ); if (err) return err; } // if } // if *sDevKey= StrAlloc( sc->fDeviceID.c_str() ); // 1:1 assigned at the moment *nonce = StrAlloc( sc->fDev->fToken.c_str() ); DEBUG_DB ( sc->fCB, MyDB,Se_CD, "devKey='%s' nonce='%s' err=%d", *sDevKey, *nonce, err ); return LOCERR_OK; } /* Session_CheckDevice */ /* Get a new nonce from the database. * If this function returns an error (as done for this implementiation here), * the SyncML engine has to create its own nonce. */ TSyError Session_GetNonce( CContext sContext, appCharP * /* nonce */ ) { SessionContext* sc= SeC( sContext ); DEBUG_DB ( sc->fCB, MyDB,Se_GN, "%d (not supported)", sc ); return DB_NotFound; } /* Session_GetNonce */ /* Save the new nonce (which will be expected to be returned * in the next session for this device */ TSyError Session_SaveNonce( CContext sContext, cAppCharP nonce ) { TSyError err= DB_NotFound; SessionContext* sc= SeC( sContext ); DEBUG_DB ( sc->fCB, MyDB, Se_SN, "%d '%s'", sc,nonce ); if (sc->fDev) { sc->fDev->fToken= nonce; sc->fDevList.fChanged= true; err= sc->fDevList.SaveDB( true, sc->fCB ); // save it } // if return err; } /* Session_SaveNonce */ /* Save the device info for */ TSyError Session_SaveDeviceInfo( CContext sContext, cAppCharP aDeviceInfo ) { SessionContext* sc= SeC ( sContext ); ModuleContext* mc= MoC( sc->fCB->cContext ); TSyError err= DB_NotFound; if (!sc->fDev) { string s= P_Device + sc->fDeviceID + ".txt"; sc->fDevList.fFileName= ConcatPaths( mc->fMapPath, s ); /* get the device */ sc->fDev= &sc->fDevList; bool found= ListNext( sc->fDev ); if (!found) { /* not found -> create such an element */ err= sc->fDevList.CreateEmptyItem( s, sc->fDev ); if (err) return err; } // if } // if if (sc->fDev) { err= sc->fDevList.UpdateFields( sc->fCB, aDeviceInfo, sc->fDev, true ); if (!err) err= sc->fDevList.SaveDB( true, sc->fCB ); } // if DEBUG_DB( sc->fCB, MyDB,Se_SD, "%d err=%d", sc, err ); sc->fDevList.Disp_Items( sc->fCB, Se_SD ); return err; } /* Session_SaveDeviceInfo */ TSyError Session_GetDBTime( CContext /* sContext */, appCharP *currentDBTime ) { string iso8601_str= CurrentTime(); *currentDBTime= StrAlloc( iso8601_str.c_str() ); return LOCERR_OK; } /* Session_GetDBTime */ #endif // DISABLE_PLUGIN_DEVICEADMIN #ifndef DISABLE_PLUGIN_SESSIONAUTH /* There are currently 4 different password modes supported: * Return: Password_ClrText_IN 'SessionLogin' will get clear text password * Password_ClrText_OUT " must return clear text password * Password_MD5_OUT " must return MD5 coded password * Password_MD5_Nonce_IN " will get MD5B64(MD5B64(user:pwd):nonce) */ sInt32 Session_PasswordMode( CContext sContext ) { //int mode= Password_ClrText_IN; //int mode= Password_ClrText_OUT; //int mode= Password_MD5_Nonce_IN; int mode= Password_MD5_OUT; SessionContext* sc= SeC( sContext ); DEBUG_DB ( sc->fCB, MyDB,Se_PM, "%d mode=%d", sc, mode ); return mode; } /* Session_PasswordMode */ /* Make login */ /* This example here shows how the different modes are working */ /* In practice, it's sufficient to support one of theses modes */ /* The chosen mode must be returned with "Session_PasswordMode" */ TSyError Session_Login( CContext sContext, cAppCharP sUsername, appCharP *sPassword, appCharP *sUsrKey ) { cAppCharP MD5_OUT_SU = "11JrMX94iTR1ob5KZFtEwQ=="; // the MD5B64 example for "super:user" cAppCharP MD5_OUT_TT = "xPlhtDgO4k2YL+127za+nw=="; // the MD5B64 example for "test:test" SessionContext* sc= SeC( sContext ); TSyError err= DB_Forbidden; // default sInt32 mode= Session_PasswordMode( sContext ); if (strcmp( sUsername,"super" )==0) { // an example account ("super"), hard coded here switch (mode) { case Password_ClrText_IN : if (strcmp( *sPassword,"user" )==0) err= LOCERR_OK; break; case Password_ClrText_OUT : *sPassword= StrAlloc( "user" ); err= LOCERR_OK; break; case Password_MD5_OUT : *sPassword= StrAlloc( MD5_OUT_SU ); err= LOCERR_OK; break; case Password_MD5_Nonce_IN: break; // currently not supported for SDK_textdb } // switch if (!err) *sUsrKey= StrAlloc( "5678" ); // allows to access the datastore later } // if if (strcmp( sUsername,"test" )==0) { // an example account ("test"), hard coded here switch (mode) { case Password_ClrText_IN : if (strcmp( *sPassword,"test" )==0) err= LOCERR_OK; break; case Password_ClrText_OUT : *sPassword= StrAlloc( "test" ); err= LOCERR_OK; break; case Password_MD5_OUT : *sPassword= StrAlloc( MD5_OUT_TT ); err= LOCERR_OK; break; case Password_MD5_Nonce_IN: break; // currently not supported for SDK_textdb } // switch if (!err) *sUsrKey= StrAlloc( "test" ); } // if appCharP pw= *sPassword; if (err && (mode==Password_ClrText_OUT || mode==Password_MD5_OUT )) pw= (appCharP)""; appCharP uk= *sUsrKey; if (err) uk= (appCharP)""; DEBUG_DB( sc->fCB, MyDB,Se_LI,"%d usr='%s' pwd='%s' => key='%s' err=%d", sc, sUsername, pw,uk, err ); return err; } // Session_Login /* Make logout */ TSyError Session_Logout( CContext sContext ) { SessionContext* sc= SeC( sContext ); DEBUG_DB ( sc->fCB, MyDB,Se_LO, "%d", sc ); return LOCERR_OK; /* do nothing */ } // Session_Logout #endif // DISABLE_PLUGIN_SESSIONAUTH void Session_DisposeObj( CContext sContext, void* memory ) { SessionContext* sc= SeC( sContext ); DEBUG_Exotic_DB( sc->fCB, MyDB,Se_DO, "%d free at %08X '%s'", sc, memory,memory ); StrDispose ( memory ); } /* Session_DisposeObj */ void Session_ThreadMayChangeNow( CContext sContext ) { SessionContext* sc= SeC( sContext ); DEBUG_Exotic_DB( sc->fCB, MyDB,Se_TC, "%d", sc ); } /* Session_ThreadMayChangeNow */ /* For Debugging only ! * Will not be called by the SyncML engine * Can be implemented empty, if not needed */ void Session_DispItems( CContext sContext, bool allFields, cAppCharP specificItem ) { SessionContext* sc= SeC( sContext ); DEBUG_DB ( sc->fCB, MyDB,Se_DI, "%d", sc ); sc->fDevList.Disp_Items( sc->fCB, "", allFields, specificItem ); } /* Session_DispItems */ /* Delete the session context; there will be no subsequent calls * to . All 'Session_DisposeObj' calls will be done before */ TSyError Session_DeleteContext( CContext sContext ) { SessionContext* sc= SeC( sContext ); DEBUG_DB ( sc->fCB, MyDB,Se_DC, "%d", sc ); delete sc; return LOCERR_OK; } // Session_DeleteContext #endif // ---- end session ------------------------------------------ // ---------- context class ---------------------------------- /*! Each datastore access requires a context, which will be created with * 'CreateContext' and deleted with 'DeleteContext'. */ typedef struct { bool allfields; // false (default): 'ReadNextItem' will return ID only / // true: returns ID + data /* other elements can be defined here */ /* ... */ } SupportType; class TDBContext { public: TDBContext( cAppCharP aContextName, DB_Callback aCB, cAppCharP sDevKey, cAppCharP sUsrKey ); ~TDBContext(); DB_Callback fCB; // callback structure for logging string fContextName; // local copy of the context name string fUserName; // unique key of usr-local string fCombiName; // unique key of dev-usr-local TDBItem fLogList; // log info TDBItem* fCurrent; // for 'ReadNextItem' int fNth; // and according counter TDBItem fNewItem; string fNewID; TDBItem fItemList; #ifndef DISABLE_PLUGIN_DATASTOREADMIN TAdminData fAdmin; // admin data handling #endif #ifndef DISABLE_PLUGIN_BLOBS TBlob fBlob; // current blob info #endif TDBItem fSupportList; SupportType fSupport; // fast readable form TDBItem fFilterList; string fLastToken; // the of the last session string fResumeToken; // suspend/resume support string fNewToken; // the of this session void ResetCounter(); TSyError RemoveAll ( TDBItem* hdK ); TSyError UpdateSupport( TDBItem* hdK, int &n ); void KeyAndField ( cAppCharP sKey, cAppCharP sField, string &s ); void KeyAndField ( TDBItemField* actKey, TDBItemField* actField, string &s ); /* other elements can be defined here */ /* ... */ }; // DBContext typedef TDBContext* ContextP; /* will be casted to the ContextP structure */ static ContextP DBC( CContext aContext ) { return (ContextP)aContext; } /* the constructor */ TDBContext::TDBContext( cAppCharP aContextName, DB_Callback aCB, cAppCharP sDevKey, cAppCharP sUsrKey ) { fContextName= aContextName; // make a local copy bool asAdmin= IsAdmin( fContextName ); fCB = aCB; DEBUG_DB( fCB, MyDB,Da_CC, "'%s' dev='%s' usr='%s' type=%s", fContextName.c_str(), sDevKey,sUsrKey, asAdmin ? "ADMIN" : "DATA" ); fUserName = ConcatNames( sUsrKey, fContextName, "_" ); fCombiName= ConcatNames( sDevKey, fUserName, "_" ); ModuleContext* mc= MoC( aCB->cContext ); #ifndef DISABLE_PLUGIN_DATASTOREADMIN if (asAdmin) fAdmin.Init( aCB, MyDB, mc->fMapPath, fContextName, sDevKey,sUsrKey ); #endif #ifndef DISABLE_PLUGIN_BLOBS fBlob.Init ( aCB, MyDB, mc->fBlobPath, fContextName, sDevKey,sUsrKey ); #endif ResetCounter(); fNewItem.init ( "newItem", aCB ); fItemList.init ( "itemID","parentID", aCB ); fSupportList.init( "support", aCB, new TDBItem ); fSupport.allfields= false; fFilterList.init ( "filter", aCB, new TDBItem ); fLogList.init ( "log", aCB, new TDBItem ); } // constructor TDBContext::~TDBContext() { DEBUG_DB( fCB, MyDB,Da_DC, "" ); } // destructor /*! Reset the counter for 'ReadNextItem' */ void TDBContext::ResetCounter() { fCurrent= &fItemList; fNth= 0; } // ResetCounter TSyError TDBContext::UpdateSupport( TDBItem* hdK, int &n ) // Update the specific field with the new value . // Create the whole bunch of missing keys, if not yet available. { TDBItem* hdI = hdK; ListNext( hdI ); TDBItemField* actK= &hdK->item; // the key TDBItemField* actI= &hdI->item; //printf( " v allfields=%s\n", // fSupport.allfields?"true":"false" ); n= 0; // init nr of valid contexts int i= 0; // init nr of total contexts while (ListNext( actK,actI ) && i==n) { // still all ? if (strcmp( actK->field.c_str(), Da_RN )==0) { fSupport.allfields= strcmp( actI->field.c_str(),"allfields" )==0; n++; } // if i++; //printf( " i=%d n=%d '%s' '%s'\n", // i, n, actK->field.c_str(), actI->field.c_str() ); } // while //printf( " n allfields=%s\n", // fSupport.allfields?"true":"false" ); return LOCERR_OK; } // UpdateSupport TSyError TDBContext::RemoveAll( TDBItem* hdK ) // Remove all elements of the list { TDBItem* hdI = hdK; ListNext( hdI ); TDBItemField* prvK= &hdK->item; // the key TDBItemField* prvI= &hdI->item; while (true) { TDBItemField* actK= prvK; // the key TDBItemField* actI= prvI; if (!ListNext( actK,actI )) break; prvK->next= actK->next; actK->next= NULL; // avoid destroying the whole chain delete actK; prvI->next= actI->next; actI->next= NULL; // avoid destroying the whole chain delete actI; } // while return LOCERR_OK; } // RemoveAll /* -- OPEN ----------------------------------------------------------------------- */ TSyError CreateContext( CContext *aContext, cAppCharP aContextName, DB_Callback aCB, cAppCharP sDevKey, cAppCharP sUsrKey ) { ContextP ac= new TDBContext( aContextName, aCB, sDevKey,sUsrKey ); if (ac==NULL) return DB_Full; // this is really fatal *aContext= (CContext)ac; return LOCERR_OK; } /* CreateContext */ /* -- GENERAL -------------------------------------------------------------------- */ #if !defined DISABLE_PLUGIN_DATASTOREADMIN || !defined DISABLE_PLUGIN_DATASTOREDATA uInt32 ContextSupport( CContext aContext, cAppCharP aSupportRules ) { ContextP ac= DBC( aContext ); DEBUG_DB( ac->fCB, MyDB,Da_CS, "'%s'", aSupportRules ); ac->RemoveAll( &ac->fSupportList ); ac->fSupportList.UpdateFields( ac->fCB, aSupportRules ); int n; ac->UpdateSupport( &ac->fSupportList, n ); DEBUG_DB( ac->fCB, MyDB,Da_CS, "allfields=%d", ac->fSupport.allfields ); return n; // number of supported contexts } // ContextSupport uInt32 FilterSupport( CContext aContext, cAppCharP aFilterRules ) { ContextP ac= DBC( aContext ); DEBUG_DB( ac->fCB, MyDB,Da_FS, "'%s'", aFilterRules ); ac->fFilterList.UpdateFields( ac->fCB, aFilterRules ); return 0; // none supported until now } // FilterSupport void ThreadMayChangeNow( CContext aContext ) { ContextP ac= DBC( aContext ); DEBUG_Exotic_DB( ac->fCB, MyDB,Da_TC, "(%08X)", ac ); ac->fNewItem.SaveDB ( false ); // possibly partly save ac->fItemList.SaveDB( false ); } /* ThreadMayChangeNow */ void WriteLogData( CContext aContext, cAppCharP logData ) { ContextP ac= DBC( aContext ); ac->fLogList.UpdateFields( ac->fCB, logData ); ac->fLogList.Disp_Items ( ac->fCB, Da_WL ); } /* WriteLogData */ /* ---- display database contents, for debugging only ---- */ /* Writes the context of items to dbg output path * This routine is implemented for debug purposes only and will NOT BE CALLED by the * SyncML engine. */ void DispItems( CContext aContext, bool allFields, cAppCharP specificItem ) { ContextP ac= DBC( aContext ); DEBUG_DB( ac->fCB, MyDB,Da_DI, "BEGIN" ); TDBItem* actB= &ac->fItemList; TDBItemField* actK; ac->fSupportList.Disp_Items( NULL, "fSupport", allFields,specificItem ); ac->fFilterList.Disp_Items ( NULL, "fFilter", allFields,specificItem ); DEBUG_( ac->fCB, "---" ); if (!actB->next) { // key titles only DEBUG_( ac->fCB, "%s", actB->c_str() ); actK= &actB->item; // the key identifier while (ListNext( actK )) DEBUG_( ac->fCB, "%s: -", actK->field.c_str() ); } else ac->fItemList.Disp_Items( NULL, "fItem", allFields,specificItem ); DEBUG_DB( ac->fCB, MyDB,Da_DI, "END" ); } // DispItems #endif // ----- end general ---------------------------------------- #ifndef DISABLE_PLUGIN_DATASTOREADMIN /* -- ADMINISTRATION ------------------------------------------------------------ */ /* (will be passed to the "admindata" module) */ TSyError LoadAdminData ( CContext aContext, cAppCharP aLocDB, cAppCharP aRemDB, appCharP *adminData ) { return DBC( aContext )->fAdmin.LoadAdminData ( aLocDB, aRemDB, adminData ); } // LoadAdminData TSyError LoadAdminDataAsKey( CContext /* aContext */, cAppCharP /* aLocDB */, cAppCharP /* aRemDB */, KeyH /* adminKey */ ) { return LOCERR_NOTIMP; } // LoadAdminDataAsKey TSyError SaveAdminData ( CContext aContext, cAppCharP adminData ) { return DBC( aContext )->fAdmin.SaveAdminData ( adminData ); } // SaveAdminData TSyError SaveAdminDataAsKey( CContext /* aContext */, KeyH /* adminKey */ ) { return LOCERR_NOTIMP; } // SaveAdminDataAsKey bool ReadNextMapItem( CContext aContext, MapID mID, bool aFirst ) { return DBC( aContext )->fAdmin.ReadNextMapItem( mID, aFirst ); } // ReadNextMapItem TSyError InsertMapItem( CContext aContext, cMapID mID ) { return DBC( aContext )->fAdmin.InsertMapItem ( mID ); } // InsertMapItem TSyError UpdateMapItem( CContext aContext, cMapID mID ) { return DBC( aContext )->fAdmin.UpdateMapItem ( mID ); } // UpdateMapItem TSyError DeleteMapItem( CContext aContext, cMapID mID ) { return DBC( aContext )->fAdmin.DeleteMapItem ( mID ); } // DeleteMapItem #endif // DISABLE_PLUGIN_DATASTOREADMIN #ifndef DISABLE_PLUGIN_DATASTOREDATA /* -- READ ---------------------------------------------------------------------- */ TSyError StartDataRead( CContext aContext, cAppCharP lastToken, cAppCharP resumeToken ) { ContextP ac= DBC ( aContext ); ModuleContext* mc= MoC( ac->fCB->cContext ); ac->fLastToken = lastToken; // store it in case of no success ac->fResumeToken= resumeToken; // used for OMA DS 1.2 suspend/resume support ac->fNewToken = CurrentTime( -1 ); // make sure that all changes will be seen DEBUG_DB( ac->fCB, MyDB,Da_SR, "last='%s' resume='%s' new='%s'", lastToken,resumeToken, ac->fNewToken.c_str() ); ac->ResetCounter(); // start with the first element string s= P_Data + ac->fUserName + ".txt"; if (mc) s= ConcatPaths( mc->fDataPath,s ); ac->fItemList.fFileName= s; // load the database into memory ac->fItemList.LoadDB( false ); // implementation could be changed to "by name" here // ------------------- s= P_NewItem + ac->fUserName + ".txt"; if (mc) s= ConcatPaths( mc->fDataPath,s ); ac->fNewItem.fFileName= s; // load the database into memory ac->fNewItem.LoadDB ( false ); // implementation could be changed to "by name" here TDBItem* act= &ac->fNewItem; ac->fNewID= F_First; if (ListNext( act )) ac->fNewID= act->itemID; return LOCERR_OK; } /* StartDataRead */ TSyError ReadNextItem( CContext aContext, ItemID aID, appCharP *aItemData, sInt32 *aStatus, bool aFirst ) { ContextP ac= DBC( aContext ); if (aFirst) ac->ResetCounter(); *aItemData= NULL; // safety setting, if no value returning cAppCharP mode= "Unused"; // default string s; ac->fNth++; if (ListNext( ac->fCurrent )) { aID->item = StrAlloc( ac->fCurrent->itemID.c_str() ); aID->parent= StrAlloc( ac->fCurrent->parentID.c_str() ); if (ac->fSupport.allfields) ReadItem( aContext, aID, aItemData ); // assume, there are two yyyymmddThhmmssZ strings, which can be // compared directly w/o conversion into lineartime *aStatus= CompareTokens( ac->fCurrent->fToken, ac->fLastToken, ac->fResumeToken ); switch (*aStatus) { case ReadNextItem_Unchanged: mode= "Unchanged"; s= Apo(ac->fLastToken ) + " >= "; break; case ReadNextItem_Changed : mode= "Changed"; s= Apo(ac->fLastToken ) + " < " ; break; case ReadNextItem_Resumed : mode= "Resumed"; s= Apo(ac->fResumeToken) + " < " ; break; } // switch s+= Apo( ac->fCurrent->fToken ); DEBUG_DB( ac->fCB, MyDB,Da_RN, "(no=%d) %s (%s): %s", ac->fNth, mode, ac->fCurrent->c_str(), s.c_str() ); return LOCERR_OK; } // if DEBUG_DB( ac->fCB, MyDB,Da_RN, "(no=%d) EOF", ac->fNth ); *aStatus= ReadNextItem_EOF; return LOCERR_OK; } /* ReadNextItem */ // The variant is not supported for textdb TSyError ReadNextItemAsKey( CContext /* aContext */, ItemID /* aID */, KeyH /* aItemKey */, sInt32* /* aStatus */, bool /* aFirst */ ) { return LOCERR_NOTIMP; } /* ReadNextItemAsKey */ static bool ItemFound( cItemID aID, TDBItem* &actL ) { appCharP p= aID->parent; if (!p) p= (appCharP)""; while (ListNext( actL )) { if (strcmp( aID->item, actL->itemID.c_str() )==0 && // search for item strcmp( p, actL->parentID.c_str() )==0) return true; } // while return false; } // ItemFound TSyError ReadItem( CContext aContext, cItemID aID, appCharP *aItemData ) { ContextP ac = DBC( aContext ); TSyError err= DB_NotFound; TDBItem* actL; TDBItemField* actK; TDBItemField* actF; int a= 0; string s, dat; *aItemData= (appCharP)""; actL= &ac->fItemList; if (ItemFound( aID, actL )) { actK = &ac->fItemList.item; // now concatenate int n= 0; actF= &actL->item; while (ListNext( actK,actF )) { s= KeyAndField( actK,actF ); if (n>0) dat+= '\n'; n++; dat+= s; } // while *aItemData= StrAlloc( dat.c_str() ); err= LOCERR_OK; } // if s= ItemID_Info( aID ); if (!err) a= strlen( *aItemData ); DEBUG_DB( ac->fCB, MyDB,Da_RI, "%s '%s' len=%d err=%d", s.c_str(), *aItemData, a, err ); return err; } /* ReadItem */ // The variant is not supported for textdb TSyError ReadItemAsKey( CContext /* aContext */, cItemID /* aID */, KeyH /* aItemKey */ ) { return LOCERR_NOTIMP; } /* ReadItemAsKey */ TSyError EndDataRead( CContext aContext ) { ContextP ac= DBC( aContext ); // no additional actions needed at this point DEBUG_DB( ac->fCB, MyDB,Da_ER, "(%08X)", ac ); // just logging return LOCERR_OK; } /* EndDataRead */ /* -- WRITE --------------------------------------------------------------------- */ TSyError StartDataWrite( CContext aContext ) { ContextP ac= DBC( aContext ); // no additional actions needed at this point DEBUG_DB( ac->fCB, MyDB,Da_SW, "(%08X)", ac ); // just logging return LOCERR_OK; } /* StartDataWrite */ TSyError InsertItem( CContext aContext, cAppCharP aItemData, ItemID newID ) { ContextP ac= DBC( aContext ); string newItemID; TDBItem* act; ItemID_Struct a; a.item = (appCharP)""; a.parent= newID->parent; if (!a.parent) a.parent= (appCharP)""; TSyError err= ac->fItemList.CreateEmptyItem( &a, newItemID, act, ac->fNewID ); if (err) a.item= (appCharP)"???"; // undefined else a.item= (appCharP)newItemID.c_str(); string s= ItemID_Info( &a ); DEBUG_DB( ac->fCB, MyDB,Da_II, "%s '%s' err=%d", s.c_str(), aItemData, err ); if (!err) { // the newly created item will now be updated => filled with content ItemID_Struct u; u.item = NULL; // no change of item u.parent= NULL; err= UpdateItem( aContext, aItemData, &a,&u ); } // if if (err) { DeleteItem( aContext, &a ); // remove it again in case of an error newID->item= NULL; } else { newID->item= StrAlloc ( newItemID.c_str() ); ac->fNewID = IntStr( atoi( newID->item )+1 ); } // if return err; } /* InsertItem */ // The variant is not supported for textdb TSyError InsertItemAsKey( CContext /* aContext */, KeyH /* aItemKey */, ItemID /* newID */ ) { return LOCERR_NOTIMP; } /* InsertItemAsKey */ TSyError UpdateItem( CContext aContext, cAppCharP aItemData, cItemID aID, ItemID /* updID */ ) // This implementation will not create a new { ContextP ac = DBC( aContext ); TSyError err= DB_NotFound; TDBItem* actI; err= ac->fItemList.GetItem( aID, actI ); // the item must exist already if (!err) err= ac->fItemList.UpdateFields( ac->fCB, aItemData, actI, false, ac->fNewToken.c_str() ); string s= ItemID_Info( aID ); DEBUG_DB( ac->fCB, MyDB,Da_UI, "%s '%s' err=%d", s.c_str(), aItemData, err ); return err; } /* UpdateItem */ // The variant is not supported for textdb TSyError UpdateItemAsKey( CContext /* aContext */, KeyH /* aItemKey */, cItemID /* aID */, ItemID /* updID */ ) { return LOCERR_NOTIMP; } /* UpdateItemAsKey */ TSyError MoveItem( CContext aContext, cItemID aID, cAppCharP newParID ) { ContextP ac = DBC( aContext ); TSyError err= DB_NotFound; TDBItem* actL; ItemID_Struct nID; nID.item = aID->item; nID.parent= (appCharP)newParID; err= ac->fItemList.ParentExist( aID->item, newParID ); if (!err) err= ac->fItemList.GetItem( aID, actL ); if (!err) actL->parentID= newParID; string s= ItemID_Info( aID ); string n= ItemID_Info( &nID ); DEBUG_DB( ac->fCB, MyDB,Da_MvI, "%s => %s err=%d", s.c_str(),n.c_str(), err ); return err; } /* MoveItem */ TSyError DeleteItem( CContext aContext, cItemID aID ) { ContextP ac= DBC( aContext ); TDBItem* act; TSyError err= ac->fItemList.GetItem( aID, act ); if (err) return err; // must exist already if (ac->fCurrent==act) ListBack( ac->fCurrent, &ac->fItemList ); err= ac->fItemList.DeleteItem( aID ); DEBUG_DB( ac->fCB, MyDB,Da_DeI, "%s err=%d", ItemID_Info( aID ).c_str(), err ); return err; } /* DeleteItem */ TSyError FinalizeLocalID( CContext /* aContext */, cItemID aID, ItemID updID ) { updID->item= StrAlloc( aID->item ); return LOCERR_OK; //return LOCERR_NOTIMP; } /* FinalizeLocalID */ TSyError DeleteSyncSet( CContext aContext ) { TSyError err; ContextP ac= DBC( aContext ); ItemID_Struct iID; appCharP itemData; sInt32 status; while (true) { err= ReadNextItem( aContext, &iID, &itemData, &status, true ); if (err || status==ReadNextItem_EOF) break; err= DeleteItem( aContext, &iID ); DEBUG_DB( ac->fCB, MyDB,Da_DSS, "%s: err=%d\n", ItemID_Info( &iID ).c_str(), err ); if (err) break; DisposeObj( aContext, iID.item ); DisposeObj( aContext, iID.parent ); DisposeObj( aContext, itemData ); } // while return err; } /* DeleteSyncSet */ /* -- BLOBs --------------------------------------------------------------------- */ #ifndef DISABLE_PLUGIN_BLOBS TSyError ReadBlob ( CContext aContext, cItemID aID, cAppCharP aBlobID, appPointer *aBlkPtr, memSize *aBlkSize, memSize *aTotSize, bool aFirst, bool *aLast ) { return DBC( aContext )->fBlob.ReadBlob ( aID, aBlobID, aBlkPtr,aBlkSize, aTotSize, aFirst,aLast ); } // ReadBlob TSyError WriteBlob( CContext aContext, cItemID aID, cAppCharP aBlobID, appPointer aBlkPtr, memSize aBlkSize, memSize aTotSize, bool aFirst, bool aLast ) { return DBC( aContext )->fBlob.WriteBlob ( aID, aBlobID, aBlkPtr,aBlkSize, aTotSize, aFirst,aLast ); } // WriteBlob; TSyError DeleteBlob( CContext aContext, cItemID aID, cAppCharP aBlobID ) { return DBC( aContext )->fBlob.DeleteBlob ( aID, aBlobID ); } // DeleteBlob #endif /* ------------------------------------------------------------------------------ */ /* If all operations for this datastore access are successful, the current * itemlist can be written to a text file and the will be returned */ TSyError EndDataWrite( CContext aContext, bool success, appCharP *newToken ) { ContextP ac= DBC( aContext ); DEBUG_DB( ac->fCB, MyDB,Da_EW, "=> %s", success ? "COMMIT":"ROLLBACK" ); TDBItem* act= &ac->fNewItem; ac->fNewItem.CreateItem( ac->fNewID,"", act ); TSyError err= DB_Error; ac->fNewItem.SaveDB ( false ); if (success) err= ac->fItemList.SaveDB( false ); // be aware that this implementation // in case of no success might have saved already a part at "ThreadMyChangeNow" if (err) ac->fNewToken= ac->fLastToken; *newToken= StrAlloc( ac->fNewToken.c_str() ); DEBUG_DB( ac->fCB, MyDB,Da_EW, "err=%d newToken='%s'", err, *newToken ); return err; } /* EndDataWrite */ #endif // DISABLE_PLUGIN_DATASTOREDATA /* ----- "script-like" ADAPT --------- */ TSyError AdaptItem( CContext aContext, appCharP *aItemData1, appCharP *aItemData2, appCharP *aLocalVars, uInt32 aIdentifier ) { /**** CAN BE ADAPTED BY USER ****/ // NOTE: will not yet be called by the SyncML engine ContextP ac= DBC( aContext ); DEBUG_DB( ac->fCB, MyDB,"AdaptItem", "'%s' '%s' '%s' id=%d", *aItemData1,*aItemData2,*aLocalVars, aIdentifier ); *aItemData1 = StrAlloc( *aItemData1 ); *aItemData2 = StrAlloc( "4:just_a_test\n" ); return LOCERR_OK; } /* AdaptItem */ /* ----------------------------------- */ void DisposeObj( CContext aContext, void* memory ) { ContextP ac= DBC( aContext ); DEBUG_Exotic_DB( ac->fCB, MyDB,Da_DO, "%d free at %08X '%s'", ac, memory,memory ); StrDispose ( memory ); } /* DisposeObj */ TSyError DeleteContext( CContext aContext ) { ContextP ac= DBC( aContext ); delete ac; // release the structure itself return LOCERR_OK; } /* DeleteContext */ } /* namespace */ /* eof */ libsynthesis-3.4.0.47.1/src/sysync_SDK/Sources/000077500000000000000000000000001226375725500211075ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/sysync_SDK/Sources/SDK_support.cpp000077500000000000000000000550741226375725500240460ustar00rootroot00000000000000/* * File: SDK_support.cpp * * Author: Beat Forster (bfo@synthesis.ch) * * Some SDK support utility functions for C++ * * * Copyright (c) 2005-2011 by Synthesis AG + plan44.ch * */ #include "sync_include.h" // import some global things #include "sync_dbapidef.h" #include "SDK_util.h" #include "SDK_support.h" #ifdef __cplusplus namespace sysync { #endif #define FLen 30 // max length of (internal) item name // --- plugin name handling ---------------------------------------- //! recognize separation bool SepFound( string name, string::size_type &pos, string sep, bool backwards ) { if (backwards) pos= name.rfind( sep, name.length()-1 ); else pos= name.find ( sep, 0 ); return pos!=string::npos; } // SepFound // returns true if in brackets: "[aaa]" bool InBracks( string name ) { string::size_type o, c; return SepFound( name, o, "[" ) && o==0 && SepFound( name, c, "]", true ) && c==name.length()-1; } // InBracks // returns true if twice in brackets: "[[aaa]]" static bool InDBracks( string name ) { string::size_type o, c; return SepFound( name, o, "[[" ) && o==0 && SepFound( name, c, "]]", true ) && c==name.length()-2; } // InDBracks bool CutBracks( string &name ) { bool ok= InBracks( name ); if (ok) name= name.substr( 1, name.length()-2 ); // cut the brackets return ok; } // CutBracks /*! Returns true, if belongs to an internal LIB. * Returns false for DLL access * The following notations are recognized as LIB: * "" * "[aaa]" * "[aaa!bbb]" * "[aaa x]" * "[aaa x!bbb]" * * "[aaa]!bbb" * "[aaa x]!bbb" * * "[aaa] x" * "[aaa] x!bbb" */ bool IsLib( string name ) { if (name.empty() || InBracks( name )) return true; // empty or embraced with '[' ']' string::size_type o, c; return SepFound( name, o, "[" ) && o==0 && SepFound( name, c, "]",true ) && ( name[ c+1 ]=='!' || name[ c+1 ]==' ' ); } // IsLib // Cut the brackets at begin/end of , if available string NoBracks( string name ) { string p; string::size_type pos; if (SepFound( name, pos )) { // check the case "[aaa]!bbb" first p= Plugin_MainName( name ); if (IsLib( p )) { p= NoBracks( p ) + "!" + Plugin_SubName ( name ); return p; } // if } // if if (SepFound( name, pos, " " )) { // check the case "[aaa] xx" if (name[ 0 ]=='[' && name[ pos-1 ]==']' && NextToken( name, p )) { p= NoBracks( p ) + " " + name; return p; } // if } // if // check now for "[aaa]" or "[aaa!bbb]" CutBracks( name ); return name; } // NoBracks /*! Add brackets at begin/end of , if not yet there */ string AddBracks( string name ) { if (!name.empty() && !InBracks( name )) name= Bracks( name ); return name; } // AddBracks static string Plugin_PartName( string name, bool asSub ) { string::size_type pos, o, c; if (!SepFound( name, pos )) { // at least one '!' must be there if (asSub) return ""; else return name; } // if int nBridge= 0; if (SepFound( name, o, "[" ) && o==0) { for (c= pos+1; c 0) name= '[' + name; } else { name= name.substr( 0, pos ); while (nBridge-- > 0) name= name + ']'; } // if while (InDBracks( name )) CutBracks( name ); return name; } // Plugin_PartName //! the part before and after '!' string Plugin_MainName( string name ) { return Plugin_PartName( name, false ); } string Plugin_SubName ( string name ) { return Plugin_PartName( name, true ); } bool WithSubSystem( string name, string &sMain, string &sSub ) { sMain= Plugin_MainName( name ); sSub = Plugin_SubName ( name ); return !sSub.empty(); } // WithSubSystem bool IsAdmin( string &aContextName ) { uInt32 fLen= aContextName.length(); uInt32 fPos= fLen - strlen( ADMIN_Ident ); bool asAdmin= aContextName.rfind( ADMIN_Ident,fLen )==fPos; if (asAdmin) aContextName= aContextName.substr( 0, fPos ); return asAdmin; } // IsAdmin // ------ command line utility functions ------------------------------------- // assign command line arguments void CLine::InitOptions( int argc, char* argv[] ) { fArgc= argc; // get copies fArgv= argv; } // InitOptions // Get th option string of void CLine::StrOpt( char opt, int n, string &value ) { int p= 0; for (int i=1; i= fArgc) return; char* s= fArgv[ i+p ]; if (*s=='-') { // search for options do { s++; if (*s==opt) { // yes, that's the one we're looking for bool ok= true; int act= i+p+1; int lim= i+n; for (int j=act; j<=lim; j++) { s= fArgv[ j ]; if (*s=='-') { // no other options allowed s++; if (*s<'0' || *s>'9') { // negative numbers ARE allowed ok= false; break; } // if } // if p++; } // for if (ok) { value= s; return; // it's ok -> assign } // if } // if } while (*s!='\0' && *s!=' '); } // if } // for } // StrOpt void CLine::GetName( int n, string &value ) { int j= 0; for (int i=1; i if (!s.empty()) s+= '\n'; // add a separator (in-between) s+= fieldName; // and the new identifier s+= ':' + fieldValue; } // AddCapa // Add a fieldname with "no" attribute void NoField( string &s, string fieldName ) { AddCapa( s, fieldName, "no" ); } // Add a fieldname with "yes" attribute void YesField( string &s, string fieldName ) { AddCapa( s, fieldName, "yes" ); } // Add a fieldname with "both" attribute void BothField( string &s, string fieldName ) { AddCapa( s, fieldName,"both" ); } // Add the minimum supported version for the plugin to : // ===> MUST be sent at StartDataRead ==> V1.0.6.X void MinVersion( string &s, CVersion internalMinVersion ) { CVersion minV= VP_ResumeToken; // At least V1.0.6.X for all ... if (minV<=internalMinVersion) // ... or even higher minV= internalMinVersion; string value; GetField( s, CA_MinVersion, value ); if (!value.empty()) { // already a min version defined ? if (VersionNr( value )>=minV) return; // it's perfectly fine already -> done RemoveField( s, CA_MinVersion, value ); // must be replaced, remove it } // if AddCapa( s, CA_MinVersion, VersionStr( minV ) ); } // MinVersion // Add sub system's version, if smaller than internal void SubVersion( string &s, CVersion subSysVersion ) { if (Plugin_Version( 0 ) information to void GContext( string &s, GlobContext* gContext ) { if (gContext) AddCapa( s, CA_GlobContext, RefStr( gContext ) ); } // CContext // Add capability error, if void CapaError( string &s, TSyError err ) { if (err) AddCapa( s, CA_Error, IntStr(err) ); } // CapaError // ---- utility functions ---------------------------------------------------------- // Allocate local memory for an item void MapAlloc( MapID rslt, cMapID mID ) { rslt->localID = StrAlloc( mID->localID ); rslt->remoteID= StrAlloc( mID->remoteID ); rslt->flags = mID->flags; rslt->ident = mID->ident; } // MapAlloc // Allocate local memory for an item void ItemAlloc( ItemID rslt, cItemID aID ) { rslt->item = StrAlloc( aID->item ); rslt->parent= StrAlloc( aID->parent ); } // ItemAlloc void BlockAlloc( appPointer *newPtr, appPointer bPtr, uInt32 bSize ) { *newPtr= malloc( bSize ); memcpy( *newPtr, bPtr, bSize ); } // BlockAlloc // ----------------------------------------------------------- // Get int value as string string IntStr( sInt32 i ) { char f[ FLen ]; sprintf ( f, "%d", (int)i ); string s= f; return s; } // IntStr string RefStr( void* a, bool asHex ) { char f[ FLen ]; #if __WORDSIZE == 64 if (asHex) sprintf( f, "%016llX", (unsigned long long)a ); else sprintf( f, "%lld", (long long int )a ); #else if (asHex) sprintf( f, "%08X", (unsigned int)a ); else sprintf( f, "%d", (int)a ); #endif string s= f; return s; } // RefStr static string HexConv( uInt32 h, cAppCharP format ) { char f[ FLen ]; sprintf ( f, format, h ); string s= f; return s; } // HexConv /*! Get byte/hex/longhex value as string */ string ByteStr( uInt8 h ) { return HexConv( h, "%02X" ); } string HexStr( uInt16 h ) { return HexConv( h, "%04X" ); } string LHexStr( uInt32 h ) { return HexConv( h, "%08X" ); } /*! Get ch as int value */ int HexNr( char ch ) { int i= 0; if ( ch>='0' && ch<='9' ) i= ch-'0'; if ( ch>='a' && ch<='f' ) i= ch-'a'+10; if ( ch>='A' && ch<='F' ) i= ch-'A'+10; return i; } // HexNr /*! Get string as hex value */ void* LHexRef( string v ) { #if __WORDSIZE == 64 long long a= 0; const int mx= 16; #else long a= 0; const int mx= 8; #endif int len= v.length(); if (len>mx) len= mx; for (int i= 0; imx) len= mx; for (int i= 0; i as version string Va.b.c.d string VersionStr( CVersion v ) { if (v==VP_BadVersion) return ""; if (v==0) return "--"; string s; for (int i= 0; i<= 3; i++) { if (!s.empty()) s= '.' + s; s= IntStr( v % 256 ) + s; v= v / 256; } // for return 'V' + s; } // VersionStr // Get as version long 0x0a0b0c0d CVersion VersionNr( string s ) { long v= 0x00000000; string a; int j= s.find( 'V',0 ); if (j==0) s= s.substr( 1, s.length()-1 ); if (s.length()==8 && // direct conversion s.find( '.',0 )==string::npos) { return LHex( s ); } // if for (int i= 0; i<= 3; i++) { a= s; j= a.find( '.',1 ); if (j>=1) { a= a.substr( 0,j ); s= s.substr( j+1, s.length()-j-1 ); } else s= ""; // if j= atoi( a.c_str() ); v= 256*v + j; } // for return v; } // VersionNr bool SameBegin( string s, string cmp ) { ssize_t w= s.length()-cmp.length(); return w>=0 && s.find ( cmp, 0 )==0; } // SameBegin bool SameEnd ( string s, string cmp ) { ssize_t w= s.length()-cmp.length(); return w>=0 && s.find ( cmp, w )==(size_t)w; } // SameEnd // Replace 0A -> 0B, TAB -> ' ' when saving void ReplaceSave( cAppCharP str, string &rslt ) { unsigned char* s= (unsigned char*)str; // support UTF8 as well char ch= '\0'; rslt= ""; while (*s!='\0') { bool ok= true; switch (*s) { case 0x0A : ch= 0x0B; break; case 0x09 : ch= ' '; break; // TAB -> SP case 0x1D : ch= *s ; break; // do not touch ARR Sep default : if (*s>=0x20 && *s!=0x7F) ch= *s; else ok= false; // ignore others } // switch s++; if (ok) rslt+= ch; } // while } // ReplaceSave // Replace 0B -> 0A, when loading void ReplaceLoad( cAppCharP str, string &rslt ) { unsigned char* s= (unsigned char*)str; // support UTF8 as well char ch= '\0'; rslt= ""; while (*s!='\0') { bool ok= true; switch (*s) { case 0x0B : ch= 0x0A; break; case 0x09 : case 0x1D : ch= *s ; break; // do not touch ARR Sep default : if (*s>=0x20 && *s!=0x7F) ch= *s; else ok= false; // ignore others } // switch s++; if (ok) rslt+= ch; } // while } // ReplaceLoad // ---------------------------------------------------------------------- string Apo ( string s ) { return "'" + s + "'"; } // Get string within single quotes string Parans( string s ) { return "(" + s + ")"; } // Get string within parans string Bracks( string s ) { return "[" + s + "]"; } // Get string within brackets void CutCh ( string &s ) { s= s.substr( 1, s.length()-1 ); } // Cut 1st char void CutLSP( string &s ) { while (s.find( " ",0 )==0) CutCh( s ); } // Cut all leading SP // Token separation bool NextToken( string &s, string &nx, string sep ) { nx= ""; CutLSP ( s ); if ( s.empty()) return false; string::size_type len= s.length(); string::size_type pos= s.find( sep, 0 ); // search for the last separator if (pos==string::npos) { nx= s; // no separation possible, result is all s = ""; } else { int sepLen= sep.length(); nx= s.substr( 0, pos ); // separate, if found s = s.substr( pos+sepLen,len-pos-sepLen+1 ); CutLSP( s ); } // if return true; } // NextToken string LineConv( string str, uInt32 maxLen, bool visibleN ) { cAppCharP BN = "\\n"; string s, nx, value; bool first= true; bool b= false; bool e= false; if (visibleN) { string::size_type len= str.length(); if (len>0) { b= str.find ( "\n", 0 )==0; e= str.rfind( "\n", len-1 )==len-1; } // if } // if while (NextToken( str,nx, "\n" )) { if (first && str.empty()) return nx; string rema; // cut \r NextToken( nx,rema, "\r" ); nx= rema; string v= nx; if (NextToken( nx,value, ":" ) && !nx.empty()) { if (!s.empty()) { if (visibleN) s+= BN; else s+= " "; } // if s+= v; } // if first= false; } // while if (b) s= BN + s; if (e) s= s + BN; if (maxLen>0 && maxLen, string string ItemID_Info( cItemID aID, string aName ) { string id; if (aID) { if (aID->item) id= aID->item; if (aID->parent) { string p= aID->parent; if (!p.empty()) id+= "," + p; } // if } // if id= Parans( id ); if (!aName.empty()) id= aName + "=" + id; return id; } // ItemID_Info // Get string string MapID_Info( cMapID mID ) { string id; if (mID) { if (mID->localID) id+= Apo( mID->localID ) + " "; if (mID->remoteID) id+= Apo( mID->remoteID ) + " "; id+= HexStr( mID->flags ) + " "; id+= IntStr( mID->ident ); } // if id= "map=" + Parans( id ); return id; } // MapID_Info // Concat and string ConcatPaths( string path1, string path2, bool isJava ) { if (path2.empty()) return path1; if (path1.empty()) return path2; if (isJava) path1+= '/'; else { #ifdef _WIN32 path1+= '\\'; #else path1+= '/'; #endif } // if return path1 + path2; } // ConcatPaths // Concat , and string ConcatPaths( string path1, string path2, string path3, bool isJava ) { return ConcatPaths( ConcatPaths ( path1, path2, isJava ), path3, isJava ); } // ConcatPaths /*! Notation: "!" */ string ConcatNames( string name1, string name2, string sep ) { if (!name1.empty() && !name2.empty()) name1+= sep; name1+= name2; return name1; } // ConcatNames static bool Chk( string s, string &aDat, cAppCharP &q, cAppCharP &qV, int offs ) { string::size_type pos= aDat.find( s, 0 ); do { // either at the beginning ... if (pos==0) break; // ... or right after a '\n' pos= aDat.find( "\n" + s, 0 ); if (pos==string::npos) return false; pos++; // without \n at the beginning } while (false); q = aDat.c_str() + pos; qV= q + s.length() + offs; return true; } // Chk static bool GetField_R( string &aDat, string aKey, string &value, bool removeIt ) { cAppCharP q; cAppCharP qV; cAppCharP qN; cAppCharP qR; value= ""; // in case of not found if (!Chk( aKey + StdPattern, aDat, q,qV, 0 ) && // is it one of these types ? !Chk( aKey + ArrayPattern, aDat, q,qV,-1 ) && !Chk( aKey + ";", aDat, q,qV,-1 )) return false; qN= strstr( q,"\n" ); // search for next separator bool last= qN==NULL; if (last) qN= (cAppCharP)q + strlen( q ); // it's the last field ? qR= qN-1; if (*qR!='\r') qR= qN; // ignore \r value.assign ( qV, qR-qV ); // get the snippet if (removeIt) { cAppCharP qE= qN; if (*qE) qE++; if (last) { // if it is the last one, cut line break before as well while (q>aDat.c_str()) { q--; if (*q!='\n' && *q!='\r') { q++; break; } } // while } // if string::size_type pos= q-aDat.c_str(); // offset to at string::size_type n = qE-q; // size of the field aDat= aDat.erase( pos, n ); } // if return true; } // GetField_R bool GetField( string aDat, string aKey, string &value ) { return GetField_R ( aDat, aKey, value, false ); } // GetField bool RemoveField( string &aDat, string aKey, string &removedValue ) { return GetField_R ( aDat, aKey, removedValue, true ) && !removedValue.empty(); } // RemoveField bool FlagOK( string aDat, string aKey, bool isYes ) { string value; GetField( aDat, aKey, value ); bool ok, emp= aKey.empty(); if (isYes) { ok= !emp && ( value=="yes" || value=="true" || value=="both" ); } else { ok= emp || !( value=="no" || value=="false" ); } //printf( "value=%-10s isYes=%-5d ok=%-5d aEmp=%-5d aKey='%s'\n", // value.c_str(), isYes, ok, aDat.empty(), aKey.c_str() ); return ok; } // FlagOK bool FlagBoth( string aDat, string aKey ) { string value; GetField( aDat, aKey, value ); return value=="both"; } // FlagBoth void FilterFields( string &aDat, string aFilter ) { string s, removedValue; cAppCharP qN; cAppCharP qR; cAppCharP q= aFilter.c_str(); while (*q) { qN= strstr( q,"\n" ); if (!qN) qN= (cAppCharP)q + strlen( q ); qR= qN-1; if (*qR!='\r') qR= qN; s.assign( q, (unsigned int)( qR-q ) ); q= qN; if (*q) q++; RemoveField( aDat, s, removedValue ); } // while } // FilterFields /* ---------- global context handling ------------------------ */ bool GlobContextFound( string dbName, GlobContext* &g ) { while (g!=NULL) { if (dbName==g->refName) break; // work is done if (strcmp( g->refName,"" )==0) { strcpy( g->refName, dbName.c_str() ); return false; } // if if (g->next==NULL) { return false; } // if g= g->next; } // while return g!=NULL && g->ref!=NULL; } // GlobContextFound /* ---------- Tunnel itemKey --------------------------------- */ TSyError OpenTunnel_ItemKey( TunnelWrapper* tw ) { TSyError err, cer; SDK_UI_Struct* ui= &tw->tCB->ui; KeyH tKey, sKey; err= ui->OpenSessionKey( tw->tCB, tw->tContext, &sKey, 0 ); if (!err) { err= ui->OpenKeyByPath ( tw->tCB, &tKey, sKey, "tunnel", 0 ); if (!err) { err= ui->OpenKeyByPath ( tw->tCB, &tw->tItemKey, tKey, "item", 0 ); cer= ui->CloseKey ( tw->tCB, tKey ); if (!err) err= cer; } // if cer= ui->CloseKey ( tw->tCB, sKey ); if (!err) err= cer; } // if return err; } // OpenTunnel_ItemKey TSyError CloseTunnel_ItemKey( TunnelWrapper* tw ) { SDK_UI_Struct* ui= &tw->tCB->ui; return ui->CloseKey( tw->tCB, tw->tItemKey ); } // CloseTunnel_ItemKey #if defined __cplusplus } // namespace */ #endif /* eof */ libsynthesis-3.4.0.47.1/src/sysync_SDK/Sources/SDK_support.h000077500000000000000000000164401226375725500235050ustar00rootroot00000000000000/* * File: SDK_support.h * * Author: Beat Forster (bfo@synthesis.ch) * * Some SDK support utility functions for C++ * * * Copyright (c) 2005-2011 by Synthesis AG + plan44.ch * */ #ifndef SDK_SUPPORT_H #define SDK_SUPPORT_H #include "sync_include.h" // import some global things #include namespace sysync { /*! Search for separators */ bool SepFound( string name, string::size_type &pos, string sep= "!", bool backwards= false ); // ---- Bracket (LIB) support /*! Returns true, if belongs to an internal LIB. * Returns false for DLL or JNI (Java Native Interface) access */ bool IsLib( string name ); /*! Returns true, if is within brackets: "[aaa]" */ bool InBracks( string name ); /*! Cut brackets, if at beginning and end * Returns true, if is within brackets: "[aaa]" */ bool CutBracks( string &name ); /*! Cut the brackets at beginning/end of */ string NoBracks( string name ); /*! Add brackets at beginning/end of * if not yet there and if not empty string */ string AddBracks( string name ); /*! Get plug-in's main path of , e.g. "aaa!bbb" ==> "aaa" */ string Plugin_MainName( string name ); /*! Get plug-in's sub path of , e.g. "aaa!bbb" ==> "bbb" */ string Plugin_SubName ( string name ); /*! Get the two path's and * Returns true, if sSub is not empty "" */ bool WithSubSystem ( string name, string &sMain, string &sSub ); /*! Returns true if names contains " ADMIN" at the end * The " ADMIN" part will be ut, if available */ bool IsAdmin( string &aContextName ); // ------ command line utility functions ------------------------------------- class CLine { public: CLine() { fArgc= 0; } void InitOptions( int argc, char* argv[] ); // assign command line arguments void StrOpt ( char opt, int n, string &value ); // Get th option string of void GetName ( int n, string &value ); bool NextOpt ( char opt, int &n, string &value ); // Get next option, if available void IntOpt ( char opt, int n, uInt32 &value ); void IntOpt ( char opt, int n, sInt32 &value ); void IntOpt ( char opt, int n, uInt16 &value ); void IntOpt ( char opt, int n, sInt16 &value ); bool Opt_Found ( char opt ); // check for a specific option private: int fArgc; char** fArgv; }; // Cline // ---- Capabilities support -------------------------------------------------------- /*! Add a fieldname with "no", "yes" or "both" attribute */ void NoField( string &s, string fieldName ); void YesField( string &s, string fieldName ); void BothField( string &s, string fieldName ); /*! Add the minimum supported version for the plugin to * NOTE: If \ is not specified or lower than the system's * minimum version, the system's minimum version will be taken. * If \ is higher, it will be directly returned. */ void MinVersion ( string &s, CVersion internalMinVersion= 0 ); /*! Add sub system's version, if smaller than internal */ void SubVersion ( string &s, CVersion subSysVersion ); /*! Sub system's name; additionally this is a capability separator * So all following capabilities belong to the sub system */ void SubSystem ( string &s, string subSysName ); /*! Add the manufacturer's to \ */ void Manufacturer( string &s, string name ); /*! Add a short description , what the module is doing to */ void Description ( string &s, string desc ); /*! Add a string to */ void GuidStr ( string &s, string guidStr ); /*! Add a string to */ void BuiltIn ( string &s, string plugin ); /*! Add global context information to */ void GContext ( string &s, GlobContext* gContext ); /*! Add capability error */ void CapaError ( string &s, TSyError err ); // ---- utility functions ---------------------------------------------------------- /* Allocate local memory for an item */ void MapAlloc ( MapID rslt, cMapID mID ); void ItemAlloc ( ItemID rslt, cItemID aID ); void BlockAlloc( appPointer *newPtr, appPointer bPtr, uInt32 bSize ); /*! Convert \ into \ string for Save/Load operations */ void ReplaceSave( cAppCharP str, string &rslt ); void ReplaceLoad( cAppCharP str, string &rslt ); /*! Get int value as string */ string IntStr( sInt32 i ); /*! Get ptr address value as string */ string RefStr( void* a, bool asHex= true ); /*! Get byte/hex/longhex value as string */ string ByteStr( uInt8 h ); string HexStr( uInt16 h ); string LHexStr( uInt32 h ); /*! Get as int value */ int HexNr( char ch ); /*! Get string as hex value */ void* LHexRef( string v ); long LHex ( string v ); /*! Get boolean as const char string */ cAppCharP Bo ( bool b ); /*! Get boolean as short const char string "v"=true / "o"=false */ cAppCharP BoS( bool b ); /*! Get as version string Va.b.c.d */ string VersionStr( CVersion v ); /*! Get as version long 0x0a0b0c0d */ CVersion VersionNr ( string v ); /* true, if starts/ends with */ bool SameBegin( string s, string cmp ); bool SameEnd ( string s, string cmp ); /*! Get a string within single quotes */ string Apo ( string s ); /*! Get a string within parans */ string Parans ( string s ); /*! Get a string within brackets */ string Bracks ( string s ); /*! Token separation */ void CutCh ( string &s ); void CutLSP ( string &s ); bool NextToken( string &s, string &nx, string sep=" " ); /*! Display a line with and removed '\n' */ string LineConv( string str, uInt32 maxLen= 0, bool visibleN= false ); /*! Get (\,\ \ \) string */ string MapID_Info ( cMapID mID ); /*! Get (\,\) string */ string ItemID_Info( cItemID aID, string aName= "" ); /*! Concatenate ,,[] with OS specific separator in-between */ string ConcatPaths( string path1, string path2, bool isJava= false ); string ConcatPaths( string path1, string path2, string path3, bool isJava= false ); /*! Notation: "!" */ string ConcatNames( string name, string subName, string sep= "!" ); // ----------------------------------------------------------------------------------- /*! Get / field from . will be returned */ bool GetField ( string aDat, string aKey, string &value ); /*! Remove field from . will be returned */ bool RemoveField( string &aDat, string aKey, string &removedValue ); /*! Check if is - "yes"/"true/"both" ( = true ) * - not available or NOT "no"/"false" ( else ) */ bool FlagOK ( string aDat, string aKey, bool isYes= false ); /*! Check if is "both" */ bool FlagBoth( string aDat, string aKey ); /*! filter out item fields from . Result is */ void FilterFields( string &aDat, string aFilter ); /* ---------- global context handling ------------------------ */ bool GlobContextFound( string dbName, GlobContext* &g ); /* ---------- UI call-in: tunnel itemKey --------------------- */ TSyError OpenTunnel_ItemKey( TunnelWrapper* tw ); TSyError CloseTunnel_ItemKey( TunnelWrapper* tw ); } // namespace #endif /* SDK_SUPPORT */ /* eof */ libsynthesis-3.4.0.47.1/src/sysync_SDK/Sources/SDK_util.c000077500000000000000000000535151226375725500227450ustar00rootroot00000000000000/* * File: SDK_util.c * * Authors: Beat Forster * * * SDK utility functions for * - version handling * - string alloc/dispose * - debug/callback * * written in Std C, can be used in C++ as well * * Copyright (c) 2004-2011 by Synthesis AG + plan44.ch * */ #include "sync_dbapidef.h" #include "SDK_util.h" #include #include #include #ifndef __MACH__ #include #endif #ifdef ANDROID #include "android/log.h" #endif #define MyDB "SDK" /* local debug name */ #define Old_SDKversionMask 0xffff00ff /* Old mask for version comparison: Omit OS identifier */ #define maxmsglen 1024 /* Maximum string length for callback string */ /* This StdC module is independent from namespace "sysync" */ /* Get the plug-in's version/subversion number * The plugin will contain a user defined 0..255 * This version number is defined by Synthesis and should not be changed: * The engine contains also a version number, and makes some comparisons. */ CVersion Plugin_Version( short buildNumber ) { #define P 256 long v; #define SDK_VERSION_MAJOR 1 /* Release: V1.9.1, change this if you need troubles */ #define SDK_VERSION_MINOR 9 #define SDK_SUBVERSION 1 /* allowed range for the local build number */ if (buildNumber< 0) buildNumber= 0; if (buildNumber>255) buildNumber= 255; v= ((SDK_VERSION_MAJOR *P + SDK_VERSION_MINOR)*P + SDK_SUBVERSION )*P + buildNumber; return v; } /* Plugin_Version */ /* Check, if is supported in * NOTE: For the SyncML engine internally everything is supported * This will be reflected with the fact that for 2.1.1.X * the engine's version was always much much higher. * Today the engine's version is equivalent to the SDK version. */ bool Feature_Supported ( CVersion versionFeature, CVersion currentVersion ) { CVersion v= currentVersion; if (v=versionFeature; } /* FeatureSupported */ /* Check, if is equivalent to */ bool Feature_SupportedEq( CVersion versionFeature, CVersion currentVersion ) { CVersion v= currentVersion; if (vlen) n= len; /* never more than the length of */ } /* if */ cp= (char*)malloc( n+1 ); if (cp) { strncpy( cp, s, n ); /* not yet NUL terminated !! */ cp[ n ]= '\0'; } return cp; } /* StrAllocN */ /* Allocate local memory for a string */ appCharP StrAlloc ( cAppCharP s ) { return StrAllocN( s, strlen( s ), true ); } /* StrAlloc */ /* !Dispose a string which has been allocated with 'StrAlloc' */ void StrDispose( void* s ) { if (s!=NULL) free( s ); } /* StrDispose */ /* ------------------ field operations ------------------------- */ bool Field( cAppCharP item, cAppCharP key, char** field ) { char* b; char* e; char* t= (char*)item; *field= NULL; while (true) { b= strstr( t,key ); if (!b) break; /* available ? */ e= strstr( b,"\r" ); if (!e) e= strstr( b,"\n" ); /* get the end of this field */ if (b==item || *(b-1)=='\r' || *(b-1)=='\n') { b+= strlen( key )+1; if (*(b-1)==':') { /* correctly separated ? */ if (!e) *field= StrAlloc ( b ); /* either the rest */ else *field= StrAllocN( b, e-b, false ); /* or till next field */ return *field != NULL; } /* if */ } /* if */ if (!e) break; t= e+1; /* go to the next field */ } /* loop */ return false; } /* Field */ bool SameField( cAppCharP item, cAppCharP key, cAppCharP field ) { char* vv; bool ok= Field( item, key, &vv ); /* get the field */ if (ok) { ok= strcmp( field,vv )==0; /* and compare it with */ StrDispose ( vv ); /* is no longer used now */ } /* if */ return ok; } /* SameField */ /* ------------------ callback system -------------------------------------- */ /* Initialize to safe defaults, useable for Std C as well * NOTE: The current = latest available will be taken */ static bool BadCB( void* aCallbackRef ) { DB_Callback cb= aCallbackRef; if (cb==NULL) { printf( "bad cb==NULL\n" ); return true; } /* if */ if (cb->callbackRef!=cb) { printf( "bad callbackRef %08lX <> %08lX\n", (unsigned long)cb->callbackRef, (unsigned long)cb ); return true; } /* if */ return false; /* false= it's ok */ } /* BadCB */ void NBlk( void* aCallbackRef ) { int i; DB_Callback cb= aCallbackRef; if (!CB_OK( cb,2 )) return; /*if ( BadCB( aCallbackRef )) return;*/ for (i=0; ilCount; i++) printf( " " ); } /* NBlk */ static void BeginBlk( void* aCallbackRef, cAppCharP aTag, cAppCharP aDesc, cAppCharP aAttrText ) { DB_Callback cb= aCallbackRef; if ( BadCB( aCallbackRef )) return; NBlk( cb ); printf( "<%s> %s %s\n", aTag, aDesc, aAttrText ); cb->lCount++; } /* BeginBlk */ static void EndBlk( void* aCallbackRef, cAppCharP aTag ) { DB_Callback cb= aCallbackRef; if (!CB_OK( cb,2 )) return; /*if ( BadCB( aCallbackRef )) return;*/ cb->lCount--; NBlk( cb ); printf( "\n", aTag ); } /* EndBlk */ static void EndThread( void* aCallbackRef ) { DB_Callback cb= aCallbackRef; if (!CB_OK( cb,2 )) return; /*if ( BadCB( aCallbackRef )) return;*/ NBlk( cb ); printf( "=EndThread=\n" ); } /* EndThread */ /* -------------------------------------------------------------------- */ void InitCallback( void* aCB, uInt16 aVersion, void* aRoutine, void* aExoticRoutine ) { DB_Callback cb= aCB; if (!cb) return; cb->callbackVersion= aVersion; cb->callbackRef = cb; /* the callback pointer is the cb itself here */ if (CB_OK( cb,1 )) { cb->debugFlags = 0; /* debug disable so far */ cb->DB_DebugPuts = aRoutine; if (aRoutine) { if (aExoticRoutine) cb->debugFlags= DBG_PLUGIN_ALL; else cb->debugFlags= DBG_PLUGIN_INT + DBG_PLUGIN_DB; } /* if */ cb->cContext= 0; /* contexts */ cb->mContext= 0; cb->sContext= 0; } /* if */ if (CB_OK( cb,2 )) { cb->DB_DebugBlock = BeginBlk; /* level 2 */ cb->DB_DebugEndBlock = EndBlk; cb->DB_DebugEndThread= EndThread; cb->lCount = 0; } /* if */ if (CB_OK( cb,3 )) cb->DB_DebugExotic = aExoticRoutine; /* level 3 */ if (CB_OK( cb,4 )) cb->allow_DLL_legacy= 0; /* false */ /* level 4 */ if (CB_OK( cb,5 )) cb->allow_DLL = 0; /* false */ /* level 5 */ if (CB_OK( cb,6 )) { cb->reserved1= 0; /* level 6 */ cb->reserved2= 0; cb->reserved3= 0; cb->reserved4= 0; } /* if */ if (CB_OK( cb,7 )) { cb->thisCB = cb; /* level 7 */ cb->logCount= 0; } /* if */ if (CB_OK( cb,8 )) { cb->thisBase = NULL; /* level 8 */ cb->jRef = NULL; cb->gContext = 0; cb->ui.SetStringMode = NULL; cb->ui.InitEngineXML = NULL; cb->ui.InitEngineFile = NULL; cb->ui.InitEngineCB = NULL; cb->ui.OpenSession = NULL; cb->ui.OpenSessionKey = NULL; cb->ui.SessionStep = NULL; cb->ui.GetSyncMLBuffer = NULL; cb->ui.RetSyncMLBuffer = NULL; cb->ui.ReadSyncMLBuffer = NULL; cb->ui.WriteSyncMLBuffer= NULL; cb->ui.CloseSession = NULL; cb->ui.OpenKeyByPath = NULL; cb->ui.OpenSubkey = NULL; cb->ui.DeleteSubkey = NULL; cb->ui.GetKeyID = NULL; cb->ui.SetTextMode = NULL; cb->ui.SetTimeMode = NULL; cb->ui.CloseKey = NULL; cb->ui.GetValue = NULL; cb->ui.GetValueByID = NULL; cb->ui.GetValueID = NULL; cb->ui.SetValue = NULL; cb->ui.SetValueByID = NULL; } /* if */ if (CB_OK( cb,9 )) { cb->SDK_Interface_size= sizeof(SDK_Interface_Struct); /* level 9 */ cb->dt.StartDataRead = NULL; /* tunnel callback functions, for internal use only */ cb->dt.ReadNextItem = NULL; cb->dt.ReadItem = NULL; cb->dt.EndDataRead = NULL; cb->dt.StartDataWrite = NULL; cb->dt.InsertItem = NULL; cb->dt.UpdateItem = NULL; cb->dt.MoveItem = NULL; cb->dt.DeleteItem = NULL; cb->dt.EndDataWrite = NULL; } /* if */ if (CB_OK( cb,11 )) { cb->dt.DisposeObj = NULL; cb->dt.ReadNextItemAsKey= NULL; cb->dt.ReadItemAsKey = NULL; cb->dt.InsertItemAsKey = NULL; cb->dt.UpdateItemAsKey = NULL; } /* if */ } /* InitCallback */ /* Initialize to safe defaults and "CB_PurePrintf", usable for Std C as well */ /* Normal debug output */ void InitCallback_Pure ( void* aCB, uInt16 aVersion ) { InitCallback ( aCB, aVersion, CB_PurePrintf, NULL ); } /* InitCallback_Pure */ /* Initialize to safe defaults and "CB_PurePrintf", usable for Std C as well */ /* Normal and exotic debug output */ void InitCallback_Exotic( void* aCB, uInt16 aVersion ) { InitCallback ( aCB, aVersion, CB_PurePrintf, CB_PurePrintf ); } /* InitCallback_Exotic */ /* The for 'InitCallback', when a simple "printf" is * requested for the callback. * * Routine must be defined as * typedef void (*DB_DebugPuts_Func)( void *aCallbackRef, cAppCharP aText ); */ void CB_PurePrintf( void* aCB, cAppCharP aText ) { DB_Callback cb= aCB; if (!CB_OK( cb,2 )) return; /*if ( BadCB( aCB )) return;*/ NBlk( cb ); printf( "%s\n", aText ); } /* CB_PurePrintf */ /* Get the size of the SDK_Interface_Struct to be copied */ TSyError SDK_Size( void* aCB, uInt32 *sSize ) { TSyError err= LOCERR_OK; DB_Callback cb = aCB; do { /* try to get the SDK_Interface_Struct of the calling engine */ if (cb->callbackVersion< SDK_Interface_Struct_V8) { err= LOCERR_TOOOLD; break; } if (cb->callbackVersion==SDK_Interface_Struct_V8) *sSize= SDK_Interface_Struct_V8_Size; else *sSize= cb->SDK_Interface_size; /* but it must neither be smaller than version 8 size nor larger than the own size */ if (*sSize< SDK_Interface_Struct_V8_Size) { err= LOCERR_TOOOLD; break; } if (*sSize>sizeof(SDK_Interface_Struct)) *sSize= sizeof(SDK_Interface_Struct); } while (false); /*printf( "sizeof=%d sSize=%d err=%d\n", sizeof(SDK_Interface_Struct), *sSize, err );*/ return err; } /* SDK_Size */ /* ---------- debug output ----------------------------------- */ /* prints directly to the screen */ static void ConsolePuts( cAppCharP msg ) { #ifdef ANDROID __android_log_write( ANDROID_LOG_DEBUG, "ConsolePuts", msg ); #else printf( "%s\n", msg ); #endif } /* ConsolePuts */ #if !defined(SYSYNC_ENGINE) && !defined(UIAPI_LINKED) /* the Synthesis SyncML engine has its own implementation */ /* => use this code in SDK only */ void ConsoleVPrintf( cAppCharP format, va_list args ) { #ifdef SYDEBUG char msg[ maxmsglen ]; msg[ 0 ]= '\0'; /* start with an empty */ vsnprintf ( msg, maxmsglen,format,args ); /* assemble the message string */ ConsolePuts( msg ); /* write the string */ #endif } /* ConsoleVPrintf */ void ConsolePrintf( cAppCharP text, ... ) { va_list args; va_start ( args,text ); ConsoleVPrintf( text,args ); va_end ( args ); } /* ConsolePrintf */ #endif /* Get the callback version of */ uInt16 CB_Version( void* aCB ) { DB_Callback cb= aCB; if (cb) return cb->callbackVersion; else return 0; } /* CB_Version */ /* Check, if structure is at least */ bool CB_OK( void* aCB, uInt16 minVersion ) { return CB_Version( aCB )>=minVersion; } /* Check, if structure supports UI callback (cbVersion>=6) */ /* static bool CB_UI( void* aCB ) { return CB_OK( aCB,6 ); } */ /* Check, if structure supports (cbVersion>=8) and <> 0 */ bool CB_gContext ( void* aCB ) { DB_Callback cb= aCB; return CB_OK ( aCB,8 ) && cb->gContext!=0; } /* CB_gContext */ /* Check, if structure supports CA_SubSytem (cbVersion>=10) */ bool CB_SubSystem( void* aCB ) { return CB_OK( aCB,10 ); } /* Check, if structure is at least and DBG_PLUGIN_DB is set */ bool DB_OK( void* aCB, uInt16 minVersion ) { DB_Callback cb= aCB; /* at least one flag must be set */ return CB_OK( aCB,minVersion ) && (DBG_PLUGIN_DB & cb->debugFlags)!=DBG_PLUGIN_NONE; } /* DB_OK */ /* Check, if structure is at least and one of is set */ bool Callback_OK( void* aCB, uInt16 minVersion, uInt16 debugFlags ) { DB_Callback cb= aCB; /* at least one flag must be set */ return CB_OK( aCB,minVersion ) && (debugFlags & cb->debugFlags)!=DBG_PLUGIN_NONE; } /* Callback_OK */ /* Normal callback output of */ void CallbackPuts( void* aCB, cAppCharP text ) { DB_Callback cb= aCB; if (!Callback_OK( aCB, 1,DBG_PLUGIN_ALL )) return; if (cb->DB_DebugPuts) cb->DB_DebugPuts( cb->callbackRef, text ); } /* CallbackPuts */ /* Exotic callback output of */ static void CallbackExotic( void* aCB, cAppCharP text ) { DB_Callback cb= aCB; if (!Callback_OK( aCB, 3,DBG_PLUGIN_ALL )) { CallbackPuts( aCB,text ); return; } if (cb->DB_DebugExotic) cb->DB_DebugExotic( cb->callbackRef, text ); } /* CallbackExotic */ static void CallbackVPrintf( DB_Callback aCB, cAppCharP format, va_list args, uInt16 outputMode ) { #ifdef SYDEBUG #ifdef __GNUC__ int isMax; #endif char message[ maxmsglen ]; char* ptr= (char*)&message; #ifdef __GNUC__ // need a copy for vasprintf() call va_list copy; va_copy(copy, args); #endif message[ 0 ]= '\0'; /* start with an empty */ vsnprintf( message, maxmsglen, format,args ); /* assemble the message string */ #ifdef __GNUC__ isMax= strlen(message)==maxmsglen-1; if (isMax && vasprintf( &ptr, format, copy ) != -1) {}; va_end(copy); #endif switch (outputMode) { case OutputNorm : CallbackPuts ( aCB, ptr ); break; /* case OutputExoticBefore: */ /* case OutputExoticAfter : */ case OutputExotic : CallbackExotic( aCB, ptr ); break; case OutputConsole : case OutputExoticBefore: case OutputExoticAfter : case OutputBefore : case OutputAfter : NBlk ( (void*)aCB ); ConsolePuts ( ptr ); break; } /* switch */ #ifdef __GNUC__ if (isMax) free( ptr ); #endif #endif } /* CallbackVPrintf */ void DEBUG_( void* aCB, cAppCharP text, ... ) { #ifdef SYDEBUG va_list args; if (Callback_OK( aCB, 1,DBG_PLUGIN_ALL )) { va_start ( args,text ); CallbackVPrintf( aCB, text,args, false ); va_end ( args ); } /* if (gDebug) */ #endif } /* DEBUG_ */ #ifdef SYDEBUG void DoDEBUG( void* aCB, uInt16 outputMode, bool withIntro, cAppCharP ident, cAppCharP routine, va_list args, cAppCharP text ) { cAppCharP dbIntro= ""; cAppCharP id = ""; cAppCharP isX = ""; cAppCharP p = ""; char* s; int size; if (*routine!='\0') { if (withIntro) { dbIntro= "##### "; if (outputMode==OutputBefore || outputMode==OutputExoticBefore) dbIntro= ">>>>> "; if (outputMode==OutputAfter || outputMode==OutputExoticAfter) dbIntro= "<<<<< "; } /* if */ id= ident; #if defined SDK_LIB isX= ": "; #elif defined SDK_DLL isX= " (DLL): "; #else isX= " (LNK): "; #endif if (*text!='\0') p= ": "; } /* if */ size= strlen(dbIntro) + strlen(id) + strlen(isX) + strlen(routine) + strlen(p) + strlen(text) + 1; s= (char*)malloc( size ); if (s) { sprintf( s, "%s%s%s%s%s%s", dbIntro,id,isX,routine,p,text ); CallbackVPrintf( aCB, s,args, outputMode ); free ( s ); } } /* DoDEBUG */ #endif /* ------------------------------------------------------------------------------------- */ void DEBUG_Call( void* aCB, uInt16 debugFlags, cAppCharP ident, cAppCharP routine, cAppCharP text, ... ) { #ifdef SYDEBUG va_list args; if (Callback_OK( aCB, 1,debugFlags )) { va_start ( args,text ); DoDEBUG( aCB, false,true, ident,routine, args,text ); va_end ( args ); } /* if */ #endif } /* DEBUG_Call */ void DEBUG_INT( void* aCB, cAppCharP ident, cAppCharP routine, cAppCharP text, ... ) { #ifdef SYDEBUG va_list args; if (Callback_OK( aCB, 1,DBG_PLUGIN_INT )) { va_start ( args,text ); DoDEBUG( aCB, false,true, ident,routine, args,text ); va_end ( args ); } /* if */ #endif } /* DEBUG_INT */ void DEBUG_DB( void* aCB, cAppCharP ident, cAppCharP routine, cAppCharP text, ... ) { #ifdef SYDEBUG va_list args; if (Callback_OK( aCB, 1,DBG_PLUGIN_DB )) { va_start ( args,text ); DoDEBUG( aCB, false,true, ident,routine, args,text ); va_end ( args ); } /* if */ #endif } /* DEBUG_DB */ /* ------------------------------------------------------------------------------------- */ void DEBUG_Exotic_INT( void* aCB, cAppCharP ident, cAppCharP routine, cAppCharP text, ... ) { #ifdef SYDEBUG va_list args; if (Callback_OK( aCB, 1,DBG_PLUGIN_INT ) && Callback_OK( aCB, 1,DBG_PLUGIN_EXOT )) { va_start ( args,text ); DoDEBUG( aCB, true,true, ident,routine, args,text ); va_end ( args ); } /* if */ #endif } /* DEBUG_Exotic_INT */ void DEBUG_Exotic_DB( void* aCB, cAppCharP ident, cAppCharP routine, cAppCharP text, ... ) { #ifdef SYDEBUG va_list args; if (Callback_OK( aCB, 1,DBG_PLUGIN_EXOT )) { va_start ( args,text ); DoDEBUG( aCB, true,true, ident,routine, args,text ); va_end ( args ); } /* if */ #endif } /* DEBUG_Exotic_DB */ void DEBUG_Exotic_DBW( void* aCB, cAppCharP ident, cAppCharP routine, cAppCharP text, ... ) { #ifdef SYDEBUG va_list args; if (Callback_OK( aCB, 1,DBG_PLUGIN_EXOT )) { va_start ( args,text ); DoDEBUG( aCB, true,false,ident,routine, args,text ); va_end ( args ); } /* if */ #endif } /* DEBUG_Exotic_DBW */ /* ------------------------------------------------------------------------------------- */ /* Start of sub block */ void DEBUG_Block( void* aCB, cAppCharP aTag, cAppCharP aDesc, cAppCharP aAttrText ) { /* callbackVersion >= 2 support for blocks */ #ifdef SYDEBUG DB_Callback cb= aCB; if (Callback_OK( aCB, 2,DBG_PLUGIN_ALL ) && cb->DB_DebugBlock) cb->DB_DebugBlock( cb->callbackRef, aTag,aDesc,aAttrText ); else /* old */ DEBUG_DB( aCB, MyDB, aTag, "%s (%s) BEGIN", aAttrText,aDesc ); #endif } /* DEBUG_Block */ /* End of sub block */ void DEBUG_EndBlock( void* aCB, cAppCharP aTag ) { #ifdef SYDEBUG DB_Callback cb= aCB; if (Callback_OK( aCB, 2,DBG_PLUGIN_ALL ) && cb->DB_DebugEndBlock) cb->DB_DebugEndBlock( cb->callbackRef, aTag ); else /* old */ DEBUG_DB( aCB, MyDB, aTag, "END" ); #endif } /* DEBUG_EndBlock */ void DEBUG_EndThread( void* aCB ) { #ifdef SYDEBUG DB_Callback cb= aCB; if (Callback_OK( aCB, 2,DBG_PLUGIN_ALL ) && cb->DB_DebugEndThread) cb->DB_DebugEndThread( cb->callbackRef ); else /* old */ DEBUG_DB( aCB, MyDB, "THREAD", "END" ); #endif } /* DEBUG_EndThread */ /* eof */ libsynthesis-3.4.0.47.1/src/sysync_SDK/Sources/SDK_util.h000077500000000000000000000151031226375725500227410ustar00rootroot00000000000000/* * File: SDK_util.h * * Authors: Beat Forster * * * Useful SDK utility functions * * Copyright (c) 2004-2011 by Synthesis AG + plan44.ch * */ #ifndef SDK_UTIL_H #define SDK_UTIL_H #include "sync_include.h" /* C/C++ and DLL/library support */ #ifdef __cplusplus extern "C" { using sysync::uInt16; using sysync::uInt32; using sysync::appCharP; using sysync::cAppCharP; using sysync::appPointer; using sysync::CVersion; using sysync::TSyError; #endif #if defined SYSYNC_ENGINE || defined PLUGIN_INFO #define DLL_Info "DLL:false" #else #define DLL_Info "DLL:true" #endif /*! Get the current version of the plug-in module. * The returned value will be incremented in future releases of the SDK. * Not to be changed by plug-in developer. * A customer defined can be set (0..255). */ CVersion Plugin_Version( short buildNumber ); /*! Check, if is supported in * NOTE: For the SyncML engine internally everything is supported * This will be reflected with the fact that for 2.1.1.X * the engine's version was always much much higher. * Today the engine's version is equivalent to the SDK version. */ bool Feature_Supported ( CVersion versionFeature, CVersion currentVersion ); /*! Check, if is equivalent to */ bool Feature_SupportedEq( CVersion versionFeature, CVersion currentVersion ); /*! Get the "PLATFORM:xxx" string as const definition */ cAppCharP MyPlatform( void ); /* ---------- allocate/dispose local memory for a string ----- */ /*! Allocate a string locally, with length \ */ appCharP StrAllocN ( cAppCharP s, int n, bool fullSize ); /*! Allocate a string locally */ appCharP StrAlloc ( cAppCharP s ); /* !Dispose a string which has been allocated with 'StrAlloc' */ void StrDispose( void* s ); /* ---------------- field operations ------------------------- */ /*! Gets the of at , if available */ bool Field ( cAppCharP item, cAppCharP key, appCharP *field ); /*! Returns true, if 's field is . */ bool SameField( cAppCharP item, cAppCharP key, cAppCharP field ); /* ---------- callback setup (for internal use only) --------- */ /*! Initialize the callback structure for debug output * For internal use only !! */ void NBlk ( void* aCB ); void InitCallback ( void* aCB, uInt16 aVersion, appPointer aRoutine, appPointer aExoticRoutine ); /*! Using 'CB_PurePrintf' as ; no overloading possible with Std C */ void InitCallback_Pure ( void* aCB, uInt16 aVersion ); void InitCallback_Exotic( void* aCB, uInt16 aVersion ); /* plus exotic output */ /*! If simple "printf" is requested for the callback. * 'CB_PurePrintf' can be given as for 'InitCallback. * For internal use only !! */ void CB_PurePrintf( void* aRef, cAppCharP aTxt ); /* Get the size of the SDK_Interface_Struct to be copied */ TSyError SDK_Size ( void* aCB, uInt32 *sSize ); /* ---------- debug output ----------------------------------- */ #ifndef SYSYNC_ENGINE /* if it is running standalone as DLL */ /* the Synthesis SyncML engine has its own implementation */ /* => use this code in SDK only */ void ConsoleVPrintf( cAppCharP format, va_list args ); void ConsolePrintf ( cAppCharP text, ... ); #endif /* Output modes */ #define OutputNorm 0 #define OutputExotic 1 #define OutputConsole 2 #define OutputBefore 3 #define OutputAfter 4 #define OutputExoticBefore 5 #define OutputExoticAfter 6 /* Get the callback version of */ uInt16 CB_Version( void* aCB ); /* Check, if structure is at least */ bool CB_OK ( void* aCB, uInt16 minVersion ); /* Check, if structure supports (cbVersion>=8) and <> 0 */ bool CB_gContext ( void* aCB ); /* Check, if structure supports CA_SubSytem (cbVersion>=10) */ bool CB_SubSystem( void* aCB ); /* Check, if structure is at least and DBG_PLUGIN_DB is set */ bool DB_OK ( void* aCB, uInt16 minVersion ); /* Check, if structure is at least and one of is set */ bool Callback_OK ( void* aCB, uInt16 minVersion, uInt16 debugFlags ); void CallbackPuts( void* aCB, cAppCharP text ); void DEBUG_ ( void* aCB, cAppCharP text, ... ); void DoDEBUG ( void* aCB, uInt16 outputMode, bool withIdent, cAppCharP ident, cAppCharP routine, va_list args, cAppCharP text ); /*! The debug logging callback call * The SyncML engine will write the text to the context assigned log file * * Input: : Callback variable of the context. The SyncML engine will * pass such a reference, when creating the module, session * or datastore context. The plug-in must store it within its * context for later use. * : Debug logging flags, bits0/1 are reserved, all others can be * defined plugin specific * : Normally the name of the plug-in module, usually defined as 'MyDB' * : The name of the current routine for reference * : The logging text in "printf" format. * ... : The parameters, defined at \ with %s, %d, %X ... */ void DEBUG_Call ( void* aCB, uInt16 debugFlags, cAppCharP ident, cAppCharP routine, cAppCharP text, ... ); /*! The same as DEBUG_Call, but only when specific DBG_PLUGIN_INT/DBG_PLUGIN_DB flag is set */ void DEBUG_INT ( void* aCB, cAppCharP ident, cAppCharP routine, cAppCharP text, ... ); void DEBUG_DB ( void* aCB, cAppCharP ident, cAppCharP routine, cAppCharP text, ... ); /*! The same as DEBUG_Call/DEBUG_INT/DEBUG/DEBUG_DB, but only, if exotic flag is set */ void DEBUG_Exotic_INT ( void* aCB, cAppCharP ident, cAppCharP routine, cAppCharP text, ... ); void DEBUG_Exotic_DB ( void* aCB, cAppCharP ident, cAppCharP routine, cAppCharP text, ... ); void DEBUG_Exotic_DBW ( void* aCB, cAppCharP ident, cAppCharP routine, cAppCharP text, ... ); /*! Special block and thread markers * If \ starts with "-", this block will be displayed collapsed by default */ void DEBUG_Block ( void* aCB, cAppCharP aTag, cAppCharP aDesc, cAppCharP aAttrText ); void DEBUG_EndBlock ( void* aCB, cAppCharP aTag ); void DEBUG_EndThread ( void* aCB ); /* C/C++ and DLL/library support */ #if defined __cplusplus } // end extern "C" #endif #endif /* SDK_UTIL_H */ /* eof */ libsynthesis-3.4.0.47.1/src/sysync_SDK/Sources/UI_util.cpp000066400000000000000000000152311226375725500231670ustar00rootroot00000000000000/* * File: UI_util.cpp * * Author: Beat Forster * * Programming interface between a user application * and the Synthesis SyncML client engine. * * Copyright (c) 2007-2011 by Synthesis AG + plan44.ch * */ #ifdef HAVE_CONFIG_H # include #endif #include "prefix_file.h" #include "UI_util.h" #include "SDK_util.h" #include "SDK_support.h" // ---- include DLL functionality ---- #if defined _WIN32 #include #define DLL_Suffix ".dll" #elif defined MACOSX #include #define DLL_Suffix ".dylib" #define RFlags (RTLD_NOW + RTLD_GLOBAL) #elif defined LINUX #include #define DLL_Suffix ".so" #define RFlags RTLD_LAZY #else #define DLL_Suffix "" #endif // ----------------------------------- namespace sysync { static TSyError NotFnd( appPointer aRef, cAppCharP /* aName */ ) { TSyError err= LOCERR_OK; if (aRef==NULL) { err= DB_NotFound; //printf( "Not found: '%s' err=%d\n", aName, err ); } // if return err; } // NotFnd // Connect to DLL static TSyError ConnectDLL( cAppCharP aDLLname, appPointer &aDLL ) { #if defined _WIN32 aDLL= LoadLibrary( aDLLname ); #elif defined MACOSX || defined LINUX aDLL= dlopen( aDLLname, RFlags ); //printf( "'%s' %s\n", aDLLname, dlerror() ); #else aDLL= NULL; #endif return NotFnd( aDLL, aDLLname ); } // ConnectDLL // Get of at static TSyError DLL_Func( appPointer aDLL, cAppCharP aFuncName, appPointer &aFunc ) { #if defined _WIN32 aFunc= (appPointer)GetProcAddress( (HINSTANCE)aDLL, aFuncName ); #elif defined MACOSX || defined LINUX aFunc= dlsym( aDLL, aFuncName ); #else aFunc= NULL; #endif return NotFnd( aFunc, aFuncName ); } // DLL_Func static bool IsLib( cAppCharP name ) { int len= strlen(name); return len==0 || (name[ 0 ]=='[' && name[ len-1 ]==']'); // empty or embraced with "[" "]" } // IsLib // Connect SyncML engine TSyError UI_Connect( UI_Call_In &aCI, appPointer &aDLL, bool &aIsServer, cAppCharP aEngineName, CVersion aPrgVersion, uInt16 aDebugFlags ) { // Always search for BOTH names, independently of environment cAppCharP SyFName= "SySync_ConnectEngine"; cAppCharP FName= "ConnectEngine"; string name= aEngineName; TSyError err= 0; bool dbg= ( aDebugFlags & DBG_PLUGIN_DIRECT )!=0; CVersion engVersion; appPointer fFunc; ConnectEngine_Func fConnectEngine= NULL; aIsServer = false; do { aCI = NULL; // no such structure available at the beginning aDLL= NULL; if (dbg) printf( "name='%s' err=%d\n", name.c_str(), err ); if (name.empty()) { // not yet fully implemented: Take default settings aCI= new SDK_Interface_Struct; InitCallback_Pure( aCI, DB_Callback_Version ); aCI->debugFlags= aDebugFlags; break; } // if if (IsLib( name.c_str() )) { if (name == "[]") { #ifdef DBAPI_LINKED fConnectEngine= SYSYNC_EXTERNAL(ConnectEngine); #endif } else if (name == "[server:]") { aIsServer=true; #ifdef DBAPI_SRV_LINKED fConnectEngine= SySync_srv_ConnectEngine; #endif } break; } // if cAppCharP prefix = "server:"; size_t prefixlen = strlen(prefix); if (name.size() > prefixlen && !name.compare(0, prefixlen, prefix)) { // ignore prefix and if we find the lib, look for different entry points aIsServer=true; name = name.substr(prefixlen); SyFName= "SySync_srv_ConnectEngine"; FName= "srv_ConnectEngine"; } err= ConnectDLL( name.c_str(), aDLL ); // try with name directly if (dbg) printf( "modu='%s' err=%d\n", name.c_str(), err ); if (err) { name+= DLL_Suffix; err= ConnectDLL( name.c_str(), aDLL ); // try with suffix next } // if if (dbg) printf( "modu='%s' err=%d\n", name.c_str(), err ); if (err) break; cAppCharP fN= SyFName; err= DLL_Func( aDLL, fN, fFunc ); fConnectEngine= (ConnectEngine_Func)fFunc; if (dbg) printf( "func err=%d '%s' %s\n", err, fN, RefStr( (void*)fConnectEngine ).c_str() ); if (!fConnectEngine) { fN= FName; err= DLL_Func( aDLL, fN, fFunc ); fConnectEngine= (ConnectEngine_Func)fFunc; if (dbg) printf( "func err=%d '%s' %s\n", err, fN, RefStr( (void*)fConnectEngine ).c_str() ); } // if } while (false); if (fConnectEngine) err= fConnectEngine( &aCI, &engVersion, aPrgVersion, aDebugFlags ); if (dbg) printf( "call err=%d\n", err ); //DEBUG_DB ( aCI, MyMod, "ConnectEngine", "aCB=%08X eng=%08X prg=%08X aDebugFlags=%04X err=%d", // aCB, engVersion, aPrgVersion, aDebugFlags, err ); if (fConnectEngine && err) return err; return NotFnd( aCI, "ConnectEngine" ); } // UI_Connect TSyError UI_Disconnect( UI_Call_In aCI, appPointer aDLL, bool aIsServer ) { // Always search for BOTH names, independently of environment cAppCharP SyFName= "SySync_DisconnectEngine"; cAppCharP FName= "DisconnectEngine"; TSyError err= 0; appPointer fFunc; DisconnectEngine_Func fDisconnectEngine= NULL; do { if (aDLL==NULL) { if (aIsServer) { #ifdef DBAPI_LINKED fDisconnectEngine= SYSYNC_EXTERNAL(DisconnectEngine); #endif } else { #ifdef DBAPI_SRV_LINKED fDisconnectEngine= SySync_srv_DisconnectEngine; #endif } break; } // if if (aIsServer) { SyFName = "SySync_srv_DisconnectEngine"; FName = "srv_DisconnectEngine"; } cAppCharP fN= SyFName; err= DLL_Func( aDLL, fN, fFunc ); fDisconnectEngine= (DisconnectEngine_Func)fFunc; if (!fDisconnectEngine) { fN= FName; err= DLL_Func( aDLL, fN, fFunc ); fDisconnectEngine= (DisconnectEngine_Func)fFunc; } // if //printf( "func err=%d %08X\n", err, fConnectEngine ); } while (false); if (fDisconnectEngine) err= fDisconnectEngine( aCI ); //printf( "call err=%d\n", err ); //DEBUG_DB ( aCI, MyMod, "ConnectEngine", "aCB=%08X eng=%08X prg=%08X aDebugFlags=%04X err=%d", // aCB, engVersion, aPrgVersion, aDebugFlags, err ); if (fDisconnectEngine && err) return err; return NotFnd( aCI, "DisconnectEngine" ); } // UI_Disconnect } // namespace sysync /* eof */ libsynthesis-3.4.0.47.1/src/sysync_SDK/Sources/UI_util.h000066400000000000000000000015551226375725500226400ustar00rootroot00000000000000/* * File: UI_util.h * * Author: Beat Forster * * Programming interface between a user application * and the Synthesis SyncML client engine. * * Copyright (c) 2007-2011 by Synthesis AG + plan44.ch * * */ #include #include "sync_dbapidef.h" namespace sysync { class UIContext { public: UI_Call_In uCI; appPointer uDLL; string uName; }; // UIContext /* Function definitions */ TSyError UI_Connect ( UI_Call_In &aCI, appPointer &aDLL, bool &aIsServer, cAppCharP aEngineName, CVersion aPrgVersion, uInt16 aDebugFlags ); TSyError UI_Disconnect( UI_Call_In aCI, appPointer aDLL, bool aIsServer ); } // namespace sysync /* eof */ libsynthesis-3.4.0.47.1/src/sysync_SDK/Sources/admindata.cpp000066400000000000000000000150331226375725500235370ustar00rootroot00000000000000/* * File: admindata.cpp * * Author: Beat Forster (bfo@synthesis.ch) * * * DBApi database adapter * Admin data handling * * Copyright (c) 2005-2011 by Synthesis AG + plan44.ch * * E X A M P L E C O D E * (text_db interface) * */ #include "admindata.h" #include "SDK_util.h" // include SDK utilities #include "SDK_support.h" namespace sysync { // the TAdminData class is part of sysync namespace #define P_Admin "ADM_" // admin table #define P_Map "MAP_" // map table // --------------------------------------------------------------------------- void TAdminData::Init( void* aCB, cAppCharP aDBName, string aMapPath, string aContextName, string sDevKey, string sUsrKey ) { fCB = aCB; // the callback for debug purposes fDBName = aDBName; // DBName, used for debug purposes myDB = fDBName.c_str(); // access the same way as in the textdb module fMapPath = aMapPath; fContextName= aContextName; fDevKey = sDevKey; fUsrKey = sUsrKey; } // Init /*! Reset the map counter for 'ReadNextMapItem' */ void TAdminData::ResetMapCounter() { fMap= &fMapList; } // ResetMapCounter // Get string string TAdminData::MapID_Flag_Str( cMapID mID, bool asHex ) { if (asHex) return HexStr( mID->flags ); else return IntStr( mID->flags ); // default is integer } // MapID_Flag_Str // Get , string string TAdminData::MapID_Str( cMapID mID ) { string id= mID->localID; if (*mID->remoteID!=0) { id+= ","; id+= mID->remoteID; } // if id+= " flags=" + MapID_Flag_Str( mID, true ); id+= " ident=" + IntStr ( (sInt32)mID->ident ); return id; } // MapID_Str // --------------------------------------------------------------------------- TSyError TAdminData::LoadAdminData( string aLocDB, string aRemDB, appCharP *adminData ) { TSyError err; TDBItem* actI; string combi = ConcatNames( fUsrKey, fContextName, "_" ); combi = ConcatNames( fDevKey, combi, "_" ); string admName= ConcatPaths( fMapPath, P_Admin + combi + ".txt" ); string mapName= ConcatPaths( fMapPath, P_Map + combi + ".txt" ); fAdmList.fFileName= admName; err= fAdmList.LoadDB( true, "ADM", fCB ); // Get all the elements of the list as a \n separated string string s= ""; actI= &fAdmList; bool found= ListNext( actI ); if (found) { TDBItemField* actK= &fAdmList.item; // the key identifier TDBItemField* actF= &actI->item; // the item current field while (ListNext( actK,actF )) { cAppCharP k= actK->field.c_str(); cAppCharP f= actF->field.c_str(); s+= KeyAndField( k,f ) + '\n'; } // while } else { // no such element: create a new one with empty admin data string newItemID; fAdmList.CreateEmptyItem( newItemID, actI ); DEBUG_DB( fCB, myDB, Da_LA, "newItemID='%s'", newItemID.c_str() ); } // if *adminData= StrAlloc( s.c_str() ); fAdm= actI; fAdmList.Disp_Items( fCB ); fMapList.fFileName= mapName; if (!mapName.empty()) { err= fMapList.LoadDB( false, "", fCB ); DEBUG_DB( fCB, myDB, Da_LA, "mapFile='%s' err=%d", fMapList.fFileName.c_str(), err ); } // if ResetMapCounter(); // and are not yes use in this implementation DEBUG_DB( fCB, myDB, Da_LA, "'%s' '%s'", aLocDB.c_str(),aRemDB.c_str() ); if (found) return LOCERR_OK; else return DB_NotFound; } /* LoadAdminData */ TSyError TAdminData::SaveAdminData( cAppCharP adminData ) { fAdmList.UpdateFields( fCB, adminData, fAdm, true ); fAdmList.Disp_Items ( fCB,Da_SA ); TSyError err= fAdmList.SaveDB( true, fCB ); if (!err) err= fMapList.SaveDB( false,fCB ); return err; } /* SaveAdminData */ // --------------------------------------------------------------------------- bool TAdminData::ReadNextMapItem( MapID mID, bool aFirst ) { if (aFirst) ResetMapCounter(); string s= "(EOF)"; bool ok= ListNext( fMap ); if ( ok ) { TDBItem* mpL= &fMapList; TDBItem* act= fMap; mID->localID = StrAlloc( act->itemID.c_str() ); mpL->Field( "0",act, s ); mID->remoteID= StrAlloc( s.c_str() ); mpL->Field( "1",act, s ); mID->flags = atoi ( s.c_str() ); mpL->Field( "2",act, s ); mID->ident = atoi ( s.c_str() ); s= MapID_Str( mID ); } // if DEBUG_DB( fCB, myDB,Da_RM, "%s", s.c_str() ); return ok; } // ReadNextMapItem TSyError TAdminData::GetMapItem( cMapID mID, TDBItem* &act ) { TDBItem* mpL= &fMapList; return mpL->GetItem_2( mID->localID, IntStr( (sInt32)mID->ident ).c_str(), mpL, act ); } // GetMapItem TSyError TAdminData::UpdMapItem( cMapID mID, TDBItem* act ) { TSyError err= fMapList.UpdateField( fCB, "0", mID->remoteID, act, false ); if (!err) err= fMapList.UpdateField( fCB, "1", MapID_Flag_Str( mID ).c_str(), act, false ); if (!err) err= fMapList.UpdateField( fCB, "2", IntStr( (sInt32)mID->ident ).c_str(), act, false ); return err; } // UpdMapItem TSyError TAdminData::InsertMapItem( cMapID mID ) { TDBItem* act; TSyError err= GetMapItem( mID, act ); if (!err) err= DB_Error; // Element already exists else { ItemID_Struct a; a.item = mID->localID; a.parent= const_cast(""); // map items are not hierarchical string newItemID; err= fMapList.CreateEmptyItem( &a, newItemID, act ); if (!err) err= UpdMapItem ( mID, act ); } // if DEBUG_DB( fCB, myDB,Da_IM, "%s err=%d", MapID_Str( mID ).c_str(), err ); return err; } // InsertMapItem TSyError TAdminData::UpdateMapItem( cMapID mID ) { TDBItem* act; TSyError err= GetMapItem( mID, act ); // Element does not yet exist ? if (!err) err= UpdMapItem( mID, act ); DEBUG_DB( fCB, myDB,Da_UM, "%s err=%d", MapID_Str( mID ).c_str(), err ); return err; } // UpdateMapItem TSyError TAdminData::DeleteMapItem( cMapID mID ) { TDBItem* act; TSyError err= GetMapItem( mID, act ); if (!err) err= fMapList.DeleteItem( act ); DEBUG_DB( fCB, myDB,Da_DM, "%s err=%d", MapID_Str( mID ).c_str(), err ); return err; } // DeleteMapItem } /* namespace */ /* eof */ libsynthesis-3.4.0.47.1/src/sysync_SDK/Sources/admindata.h000066400000000000000000000037551226375725500232140ustar00rootroot00000000000000/* * File: admindata.h * * Author: Beat Forster (bfo@synthesis.ch) * * * DBApi database adapter * Admin data handling * * Copyright (c) 2005-2011 by Synthesis AG + plan44.ch * * E X A M P L E C O D E * (text_db interface) * */ #ifndef ADMINDATA_H #define ADMINDATA_H #include "sync_include.h" // import global things #include "sync_dbapidef.h" // get some definitions #include "SDK_util.h" // include SDK utilities #include "dbitem.h" #include namespace sysync { class TAdminData { public: void Init( void* aCB, cAppCharP aDBName, string aAdminPath, string aContextName, string sDevKey, string sUsrKey ); TSyError LoadAdminData ( string aLocDB, string aRemDB, appCharP *adminData ); TSyError SaveAdminData ( cAppCharP adminData ); bool ReadNextMapItem( MapID mID, bool aFirst ); TSyError InsertMapItem( cMapID mID ); TSyError UpdateMapItem( cMapID mID ); TSyError DeleteMapItem( cMapID mID ); private: void ResetMapCounter(); TSyError GetMapItem ( cMapID mID, TDBItem* &act ); TSyError UpdMapItem ( cMapID mID, TDBItem* act ); string MapID_Flag_Str ( cMapID mID, bool asHex= false ); string MapID_Str ( cMapID mID ); void* fCB; // callback structure, for debug logs string fDBName; // database name, for debug logs cAppCharP myDB; // fDBName.c_str() string fMapPath; string fContextName; string fDevKey; string fUsrKey; TDBItem fAdmList; // admin structure TDBItem* fAdm; // admin item TDBItem fMapList; // map structure TDBItem* fMap; // map item }; // TAdminData } /* namespace */ #endif /* ADMINDATA_H */ /* eof */ libsynthesis-3.4.0.47.1/src/sysync_SDK/Sources/blobs.cpp000066400000000000000000000247211226375725500227220ustar00rootroot00000000000000/* * File: blobs.cpp * * Author: Beat Forster (bfo@synthesis.ch) * * * DBApi database adapter * BLOB (Binary Large Object) access * * Copyright (c) 2005-2011 by Synthesis AG + plan44.ch * * * E X A M P L E C O D E * (text_db interface) * */ #include "blobs.h" #include "SDK_util.h" // include SDK utilities #include "SDK_support.h" namespace sysync { // the BLOB class is part of sysync namespace #define P_Blob "BLB_" // BLOB data // BLOB constructor TBlob::TBlob() { fOpened= false; #ifdef PLATFORM_FILE fAttrActive= false; // the BLOB can have file dates and attributes fDateActive= false; #endif } // constructor // BLOB destructor TBlob::~TBlob() { CloseBlob(); } // destructor void TBlob::Init( void* aCB, cAppCharP aDBName, string aBlobPath, string aContextName, string sDevKey, string sUsrKey ) { fCB = aCB; // the callback for debug purposes only fDBName = aDBName; // DBName, used for debug purposes only fBlobPath = aBlobPath; fContextName= aContextName; fDevKey = sDevKey; fUsrKey = sUsrKey; } // Init // ------------------------------------------------------------------------- // Get the BLOB's name string TBlob::BlobName( cItemID aID, cAppCharP aBlobID ) { // if it is not an item, but e.g. an admin element => take the device key string v= aID->item; if (v.empty()) v= fDevKey; string s= ConcatNames( fUsrKey, fContextName, "_" ); s= P_Blob + ConcatNames( v, s, "_" ) + "_"; s+= aBlobID; s= ConcatPaths( fBlobPath, s ); // take a specific file path return s; } // BlobName // Get the BLOB's size. For this implementation the BLOB size is // identical to the file size. // Operation allowed also for open BLOBs size_t TBlob::BlobSize( string aBlobName ) { TSyError err; fpos_t tmp; fName= aBlobName; if (fName.empty()) return 0; // A BLOB w/o a name has size 0 bool opn= fOpened; // if not yet opened, open it temporary if (!opn) { err= OpenBlob( "rb" ); if (err) return 0; } else fgetpos( fFile, &tmp ); // save the current pos fseek ( fFile, 0,SEEK_END ); size_t size= ftell( fFile ); if (!opn) { err= CloseBlob(); if (err) return 0; } else fsetpos( fFile, &tmp ); // restore the current pos return size; } // BlobSize // BLOB will be stored as separate files in this implementation // This is the routine to open them for read or write TSyError TBlob::OpenBlob( cAppCharP mode ) { CloseBlob(); fFile= fopen( fName.c_str(), mode ); if (!fFile) return DB_NotFound; fOpened= true; fseek ( fFile, 0, SEEK_END ); fCurPos= 0; fSize = ftell( fFile ); // get total size rewind ( fFile ); return LOCERR_OK; } // OpenBlob // BLOB will be stored as separate files in this implementation // This is the routine to close the current one. TSyError TBlob::CloseBlob() { if (fOpened) { fclose( fFile ); fOpened= false; } fCurPos= 0; fSize = 0; return LOCERR_OK; } // CloseBlob // Attribute and date handling routines #ifdef PLATFORM_FILE TSyError TBlob::GetAttr( string aBlobName, TAttr &aAttr, bool &isFolder ) { TSyError err= Get_FileAttr( aBlobName, fAttr, isFolder ); //if (!err && isFolder) err= DB_Forbidden; DEBUG_Exotic_DB( fCB, fDBName.c_str(),"GetAttr", "'%s': hsadwrx=%d%d%d%d%d%d%d folder=%d err=%d", aBlobName.c_str(), fAttr.h,fAttr.s,fAttr.a,fAttr.d, fAttr.w,fAttr.r,fAttr.x, isFolder, err ); aAttr= fAttr; return err; } // GetAttr TSyError TBlob::SetAttr( TAttr aAttr ) { fAttr = aAttr; fAttrActive= true; DEBUG_Exotic_DB( fCB, fDBName.c_str(),"SetAttr", "hsadwrx=%d%d%d%d%d%d%d", fAttr.h,fAttr.s,fAttr.a,fAttr.d, fAttr.w,fAttr.r,fAttr.x ); return LOCERR_OK; // no error here } // SetAttr // ----------------------------------------------------------------------------------- TSyError TBlob::GetDates( string aBlobName, TDates &aDate ) { TSyError err= Get_FileDate( aBlobName, fDate ); DEBUG_Exotic_DB( fCB, fDBName.c_str(),"GetDates", "'%s': cre=%s mod=%s acc=%s err=%d", aBlobName.c_str(), fDate.created.c_str(), fDate.modified.c_str(), fDate.accessed.c_str(), err ); aDate= fDate; return err; } // GetDates TSyError TBlob::SetDates( string aBlobName, TDates aDate ) { fDate = aDate; fDateActive = true; TSyError err= Set_FileDate( aBlobName, fDate ); DEBUG_Exotic_DB( fCB, fDBName.c_str(),"SetDates", "cre=%s mod=%s acc=%s err=%d", fDate.created.c_str(), fDate.modified.c_str(), fDate.accessed.c_str(), err ); return LOCERR_OK; // no error here } // SetDates #endif // PLATFORM_FILE // ----------------------------------------------------------------------------------- // BLOB will be stored as separate files in this implementation // This is the routine to read the current one or a part of it TSyError TBlob::ReadBlob( string aBlobName, appPointer *blkPtr, memSize *blkSize, memSize *totSize, bool aFirst, bool *aLast ) { // This example shows two values of influence: // - the maximum value of returned is BlobBlk // - for blob sizes < BlobChk, the will be returned, else 0. #define BlobBlk 2048 #define BlobMax 2048 // checking limit for returning = 0 //#define BlobMax 10000 // checking limit for returning = 0 TSyError err= LOCERR_OK; *blkPtr = NULL; // initialize *totSize= 0; *aLast = true; if (aFirst) fName= aBlobName; DEBUG_DB( fCB, fDBName.c_str(), Da_RB, "blobName='%s' size=%d 1st=%s", fName.c_str(), *blkSize, Bo( aFirst ) ); do { // exit part if (fName.empty()) { err= DB_NotFound; break; } if (aFirst) { // special treatement for : open the file err= OpenBlob( "rb" ); if (err) { if (err==DB_NotFound) { // a not existing BLOB is not an error err= LOCERR_OK; *blkSize= 0; } // if break; } // if } // if if (!fOpened) { err= DB_Forbidden; break; } // now it must be open ! // adapt the default size if (*blkSize==0 || *blkSize>BlobBlk) *blkSize= BlobBlk; *blkPtr= malloc( *blkSize ); if (!*blkPtr) return LOCERR_OUTOFMEM; uInt32 rslt= fread( *blkPtr, 1, *blkSize, fFile ); *aLast= rslt!=*blkSize; if (*aLast && ferror( fFile )) return DB_Error; // check if already finished fCurPos+= rslt; if (fCurPos>=fSize) *aLast = true; // yes, it's done if (fSize: close the file if (*aLast) { *blkSize= rslt; err= CloseBlob(); } // if } while (false); // end exit part DEBUG_DB( fCB, fDBName.c_str(), Da_RB, "blk(%08X,%d) tot=%d last=%s err=%d", *blkPtr, *blkSize, *totSize, Bo( *aLast ), err ); return err; } // ReadBlob TSyError TBlob::ReadBlob( cItemID aID, cAppCharP aBlobID, appPointer *blkPtr, memSize *blkSize, memSize *totSize, bool aFirst, bool *aLast ) { return ReadBlob( BlobName( aID, aBlobID ), blkPtr,blkSize,totSize, aFirst,aLast ); } // ReadBlob // BLOB will be stored as separate files in this implementation // This is the routine to write the current one or a part of it TSyError TBlob::WriteBlob( string aBlobName, appPointer blkPtr, memSize blkSize, memSize totSize, bool aFirst, bool aLast ) { TSyError err= LOCERR_OK; if (aFirst) { // empty blobs needn't to be written if (aLast && blkSize==0) return DeleteBlob( aBlobName ); fName= aBlobName; } // if do { if (fName.empty()) { err= DB_NotFound; break; } if (aFirst) { // special treatement for : open the file err= OpenBlob( "wb" ); if (err) break; } // if if (!fOpened) { err= DB_Forbidden; break; } // now it must be open ! uInt32 rslt= fwrite( blkPtr, 1,blkSize, fFile ); if (rslt!=blkSize) err= DB_Error; fCurPos+= rslt; // special treatement for : close the file if (aLast || err) { CloseBlob(); #ifdef PLATFORM_FILE if (fAttrActive) Set_FileAttr( fName, fAttr ); if (fDateActive) Set_FileDate( fName, fDate ); fAttrActive= false; // it's written now fDateActive= false; #endif } // if } while (false); DEBUG_DB( fCB, fDBName.c_str(),Da_WB, "blobName='%s' blk(%08X,%d) tot=%d", fName.c_str(), blkPtr, blkSize, totSize ); DEBUG_DB( fCB, fDBName.c_str(),Da_WB, "1st=%s last=%s err=%d", Bo( aFirst ), Bo( aLast ), err ); return err; } // WriteBlob TSyError TBlob::WriteBlob( cItemID aID, cAppCharP aBlobID, appPointer blkPtr, memSize blkSize, memSize totSize, bool aFirst, bool aLast ) { return WriteBlob( BlobName( aID, aBlobID ), blkPtr,blkSize,totSize, aFirst,aLast ); } // WriteBlob // BLOB will be stored as separate files in this implementation // This is the routine to delete the current one. TSyError TBlob::DeleteBlob( string aBlobName ) { CloseBlob(); // close potential old one TSyError err= LOCERR_OK; fName= aBlobName; do { // exit part if (fName.empty()) { err= DB_NotFound; break; } if (fOpened) { err= DB_Forbidden; break; } remove( fName.c_str() ); // not existing BLOB is not an error } while (false); // end exit part DEBUG_DB( fCB, fDBName.c_str(),Da_DB, "blobName='%s' err=%d", fName.c_str(), err ); return err; } // DeleteBlob TSyError TBlob::DeleteBlob( cItemID aID, cAppCharP aBlobID ) { return DeleteBlob( BlobName( aID, aBlobID ) ); } // DeleteBlob } /* namespace */ /* eof */ libsynthesis-3.4.0.47.1/src/sysync_SDK/Sources/blobs.h000066400000000000000000000070161226375725500223650ustar00rootroot00000000000000/* * File: blobs.h * * Author: Beat Forster (bfo@synthesis.ch) * * * DBApi database adapter * BLOB (Binary Large Object) access * * Copyright (c) 2005-2011 by Synthesis AG + plan44.ch * * * E X A M P L E C O D E * */ #ifndef BLOBS_H #define BLOBS_H #include "sync_dbapidef.h" // get some definitions #ifdef PLATFORM_FILE #include "platform_file.h" #endif #include namespace sysync { /* NOTE: A BLOB object can be used for different BLOBs, * but only for one BLOB simultaneously. * If a new BLOB will be opened, the old one will * be closed automatically, if still opened. * read/write with = true will open a new one * " " " " = false will ignore */ class TBlob { public: TBlob(); ~TBlob(); void Init( void* aCB, cAppCharP aDBName, string aBlobPath, string aContextName, string sDevKey, string sUsrKey ); string BlobName ( cItemID aID, cAppCharP aBlobID ); size_t BlobSize ( string aBlobName ); // allowed also for open BLOBs TSyError ReadBlob ( string aBlobName, appPointer *blkPtr, memSize *blkSize, memSize *totSize, bool aFirst, bool *aLast ); TSyError ReadBlob ( cItemID aID, cAppCharP aBlobID, appPointer *blkPtr, memSize *blkSize, memSize *totSize, bool aFirst, bool *aLast ); TSyError WriteBlob ( string aBlobName, appPointer blkPtr, memSize blkSize, memSize totSize, bool aFirst, bool aLast ); TSyError WriteBlob ( cItemID aID, cAppCharP aBlobID, appPointer blkPtr, memSize blkSize, memSize totSize, bool aFirst, bool aLast ); TSyError DeleteBlob( string aBlobName ); TSyError DeleteBlob( cItemID aID, cAppCharP aBlobID ); #ifdef PLATFORM_FILE TSyError GetAttr ( string aBlobName, TAttr &aAttr, bool &isFolder ); // get BLOB's file attributes TSyError SetAttr ( TAttr aAttr ); // set " " " TSyError GetDates( string aBlobName, TDates &aDate ); // get BLOB's file dates TSyError SetDates( string aBlobName, TDates aDate ); // set " " " #endif string getDBName() const { return fDBName; } string getBlobPath() const { return fBlobPath; } string getContextName() const { return fContextName; } string getDevKey() const { return fDevKey; } string getUsrKey() const { return fUsrKey; } private: void* fCB; // callback structure, for debug logs string fDBName; // database name, for debug logs string fBlobPath; // params for creating BLOB's name string fContextName; string fDevKey; string fUsrKey; FILE* fFile; // assigned file bool fOpened; // Is it currently opened ? memSize fCurPos; // current position memSize fSize; // BLOB's size string fName; // BLOB's file name #ifdef PLATFORM_FILE TAttr fAttr; // BLOB's file attributes bool fAttrActive; TDates fDate; // BLOB's file dates bool fDateActive; #endif TSyError OpenBlob( const char* mode ); TSyError CloseBlob(); }; // TBlob } /* namespace */ #endif /* BLOBS_H */ /* eof */ libsynthesis-3.4.0.47.1/src/sysync_SDK/Sources/cp936_tables_inc.cpp000077500000000000000000023351601226375725500246570ustar00rootroot00000000000000const size_t ucs2_to_cp936_numelems = 44054; const treeval_t ucs2_to_cp936_elements[ucs2_to_cp936_numelems] = { 0x40E6,0x0220,0x0081,0x0081,0x0081,0x01C9,0x0081,0x0152,0x0092,0x0081,0x0081,0x0081,0x0081,0x0087,0x0083,0xA3A4, 0x0083,0xA957,0xA3FE,0x0085,0x0083,0xA956,0xA1EA,0x0081,0xA1E9,0x00F2,0x00B2,0x0092,0x0082,0x0089,0x0085,0x0083, 0xA1AB,0xA3FD,0x0083,0xA3FC,0xA3FB,0x0085,0x0083,0xA3FA,0xA3F9,0x0083,0xA3F8,0xA3F7,0x0091,0x0089,0x0085,0x0083, 0xA3F6,0xA3F5,0x0083,0xA3F4,0xA3F3,0x0085,0x0083,0xA3F2,0xA3F1,0x0083,0xA3F0,0xA3EF,0x0089,0x0085,0x0083,0xA3EE, 0xA3ED,0x0083,0xA3EC,0xA3EB,0x0085,0x0083,0xA3EA,0xA3E9,0x0083,0xA3E8,0xA3E7,0x00A1,0x0091,0x0089,0x0085,0x0083, 0xA3E6,0xA3E5,0x0083,0xA3E4,0xA3E3,0x0085,0x0083,0xA3E2,0xA3E1,0x0083,0xA3E0,0xA3DF,0x0089,0x0085,0x0083,0xA3DE, 0xA3DD,0x0083,0xA3DC,0xA3DB,0x0085,0x0083,0xA3DA,0xA3D9,0x0083,0xA3D8,0xA3D7,0x0091,0x0089,0x0085,0x0083,0xA3D6, 0xA3D5,0x0083,0xA3D4,0xA3D3,0x0085,0x0083,0xA3D2,0xA3D1,0x0083,0xA3D0,0xA3CF,0x0089,0x0085,0x0083,0xA3CE,0xA3CD, 0x0083,0xA3CC,0xA3CB,0x0085,0x0083,0xA3CA,0xA3C9,0x0083,0xA3C8,0xA3C7,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083, 0xA3C6,0xA3C5,0x0083,0xA3C4,0xA3C3,0x0085,0x0083,0xA3C2,0xA3C1,0x0083,0xA3C0,0xA3BF,0x0089,0x0085,0x0083,0xA3BE, 0xA3BD,0x0083,0xA3BC,0xA3BB,0x0085,0x0083,0xA3BA,0xA3B9,0x0083,0xA3B8,0xA3B7,0x0091,0x0089,0x0085,0x0083,0xA3B6, 0xA3B5,0x0083,0xA3B4,0xA3B3,0x0085,0x0083,0xA3B2,0xA3B1,0x0083,0xA3B0,0xA3AF,0x0089,0x0085,0x0083,0xA3AE,0xA3AD, 0x0083,0xA3AC,0xA3AB,0x0085,0x0083,0xA3AA,0xA3A9,0x0083,0xA3A8,0xA3A7,0x0081,0x0081,0x0089,0x0085,0x0083,0xA3A6, 0xA3A5,0x0083,0xA1E7,0xA3A3,0x0081,0x0083,0xA3A2,0xA3A1,0x008E,0x0082,0x0082,0x0082,0x0082,0x0082,0x0085,0x0083, 0xA988,0xA987,0x0083,0xA986,0xA985,0x0081,0x00BD,0x009F,0x0090,0x0088,0x0084,0x0082,0xA984,0x0083,0xA983,0xA982, 0x0085,0x0083,0xA981,0xA980,0x0083,0xA97E,0xA97D,0x0089,0x0085,0x0083,0xA97C,0xA97B,0x0083,0xA97A,0xA979,0x0085, 0x0083,0xA978,0xA977,0x0081,0xA976,0x0090,0x0089,0x0085,0x0083,0xA975,0xA974,0x0083,0xA973,0xA972,0x0084,0x0082, 0xA971,0x0083,0xA970,0xA96F,0x0089,0x0085,0x0083,0xA96E,0xA96D,0x0083,0xA96C,0xA96B,0x0085,0x0083,0xA96A,0xA969, 0x0081,0xA968,0x009D,0x008D,0x0085,0x0082,0x0082,0xA6EB,0x0085,0x0083,0xA6EA,0xA6E9,0x0083,0xA6E8,0xA6E5,0x0089, 0x0085,0x0083,0xA6E4,0xA6E7,0x0083,0xA6E6,0xA6EF,0x0085,0x0083,0xA6EE,0xA6E3,0x0083,0xA6E2,0xA6F1,0x0081,0x0089, 0x0085,0x0083,0xA6F0,0xA6E1,0x0083,0xA6E0,0xA6F5,0x0084,0x0081,0xA6F4,0x0083,0xA6F2,0xA955,0x00B5,0x0082,0x0082, 0x0082,0x00AB,0x0095,0x008D,0x0088,0x0084,0x0082,0xFE4F,0x0083,0xFE4E,0xFE4D,0x0082,0x0083,0xFE4C,0xFE4B,0x0081, 0x0084,0x0082,0xFE4A,0x0083,0xFE49,0xFE48,0x008A,0x0085,0x0082,0x0081,0xFE47,0x0082,0x0083,0xFE46,0xFE45,0x0087, 0x0084,0x0082,0xFE44,0x0082,0xFE43,0x0085,0x0083,0xFE42,0xFE41,0x0081,0xFE40,0x0082,0x0082,0x0081,0x0081,0x0082, 0xFDA0,0x0081,0x0097,0x0089,0x0081,0x0081,0x0081,0x0082,0x0081,0x0081,0xFD9F,0x0088,0x0082,0x0081,0x0082,0x0082, 0x0081,0xFD9E,0x0082,0x0081,0x0081,0x0082,0x0081,0xFD9D,0x0081,0x0082,0x0082,0x0082,0x0082,0x0082,0x0082,0xFD9C, 0x0082,0x1F5C,0x0F68,0x076E,0x0370,0x0172,0x0082,0x00F1,0x00B1,0x0091,0x0082,0x0088,0x0084,0x0082,0xFD9B,0x0083, 0xFD9A,0xFD99,0x0085,0x0083,0xFD98,0xFD97,0x0083,0xD9DF,0xB9EA,0x0091,0x0089,0x0085,0x0083,0xFD96,0xFD95,0x0083, 0xFD94,0xEDE8,0x0085,0x0083,0xB9A8,0xC1FA,0x0083,0xFD93,0xFD92,0x0089,0x0085,0x0083,0xFD91,0xFD90,0x0083,0xFD8F, 0xFD8E,0x0085,0x0083,0xFD8D,0xFD8C,0x0083,0xFD8B,0xFD8A,0x00A1,0x0091,0x0089,0x0085,0x0083,0xFD89,0xFD88,0x0083, 0xF6BB,0xC8A3,0x0085,0x0083,0xF6BA,0xF6B9,0x0083,0xF6B8,0xF6B7,0x0089,0x0085,0x0083,0xF6B6,0xF6B5,0x0083,0xC1E4, 0xF6B4,0x0085,0x0083,0xFD87,0xFD86,0x0083,0xF6B3,0xB3DD,0x0091,0x0089,0x0085,0x0083,0xFD85,0xFD84,0x0083,0xFD83, 0xFD82,0x0085,0x0083,0xFD81,0xFD80,0x0083,0xFD7E,0xFD7D,0x0089,0x0085,0x0083,0xFD7C,0xFD7B,0x0083,0xFD7A,0xFD79, 0x0085,0x0083,0xFD78,0xFD77,0x0083,0xFD76,0xFD75,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xFD74,0xFD73,0x0083, 0xFD72,0xFD71,0x0085,0x0083,0xFD70,0xFD6F,0x0083,0xFD6E,0xFD6D,0x0089,0x0085,0x0083,0xFD6C,0xFD6B,0x0083,0xFD6A, 0xFD69,0x0085,0x0083,0xFD68,0xFD67,0x0083,0xFD66,0xFD65,0x0091,0x0089,0x0085,0x0083,0xFD64,0xFD63,0x0083,0xFD62, 0xFD61,0x0085,0x0083,0xFD60,0xFD5F,0x0083,0xFD5E,0xFD5D,0x0089,0x0085,0x0083,0xFD5C,0xFD5B,0x0083,0xFD5A,0xFD59, 0x0085,0x0083,0xFD58,0xECB4,0x0083,0xC6EB,0xFD57,0x00A1,0x0091,0x0089,0x0085,0x0083,0xFD56,0xFD55,0x0083,0xFD54, 0xFD53,0x0085,0x0083,0xFD52,0xFD51,0x0083,0xFD50,0xFD4F,0x0089,0x0085,0x0083,0xFD4E,0xFD4D,0x0083,0xF7FE,0xFD4C, 0x0085,0x0083,0xFD4B,0xFD4A,0x0083,0xFD49,0xFD48,0x0091,0x0089,0x0085,0x0083,0xF7FD,0xF7FC,0x0083,0xFD47,0xB1C7, 0x0085,0x0083,0xFD46,0xF7FA,0x0083,0xFD45,0xF7FB,0x0089,0x0085,0x0083,0xFD44,0xFD43,0x0083,0xFD42,0xFD41,0x0085, 0x0083,0xFD40,0xFCA0,0x0083,0xFC9F,0xF7F9,0x017F,0x00FF,0x00BF,0x009F,0x008F,0x0087,0x0083,0xFC9E,0x0083,0xFC9D, 0xF7F8,0x0085,0x0083,0xFC9C,0xFC9B,0x0083,0xFC9A,0xFC99,0x0089,0x0085,0x0083,0xFC98,0xFC97,0x0083,0xFC96,0xFC95, 0x0085,0x0083,0xFC94,0xF7F7,0x0083,0xFC93,0xCAF3,0x0091,0x0089,0x0085,0x0083,0xFC92,0xFC91,0x0083,0xFC90,0xFC8F, 0x0085,0x0083,0xFC8E,0xFC8D,0x0083,0xDCB1,0xFC8C,0x0089,0x0085,0x0083,0xD8BB,0xFC8B,0x0083,0xFC8A,0xFC89,0x0085, 0x0083,0xB9C4,0xFC88,0x0083,0xFC87,0xD8BE,0x00A1,0x0091,0x0089,0x0085,0x0083,0xFC86,0xB6A6,0x0083,0xF6BE,0xFC85, 0x0085,0x0083,0xF6BD,0xFC84,0x0083,0xFC83,0xFC82,0x0089,0x0085,0x0083,0xFC81,0xFC80,0x0083,0xFC7E,0xFC7D,0x0085, 0x0083,0xFC7C,0xFC7B,0x0083,0xFC7A,0xFC79,0x0091,0x0089,0x0085,0x0083,0xFC78,0xF6BC,0x0083,0xFC77,0xEDEB,0x0085, 0x0083,0xEDEA,0xFC76,0x0083,0xEDE9,0xFC75,0x0089,0x0085,0x0083,0xFC74,0xFC73,0x0083,0xFC72,0xFC71,0x0085,0x0083, 0xFC70,0xFC6F,0x0083,0xFC6E,0xFC6D,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xF7F6,0xFC6C,0x0083,0xFC6B,0xFC6A, 0x0085,0x0083,0xFC69,0xF7F5,0x0083,0xF7F2,0xFC68,0x0089,0x0085,0x0083,0xF7F3,0xFC67,0x0083,0xF7F4,0xFC66,0x0085, 0x0083,0xFC65,0xF7F1,0x0083,0xFC64,0xF7EF,0x0091,0x0089,0x0085,0x0083,0xF7F0,0xFC63,0x0083,0xF7EE,0xF7ED,0x0085, 0x0083,0xF7EC,0xFC62,0x0083,0xFC61,0xC4AC,0x0089,0x0085,0x0083,0xFC60,0xFC5F,0x0083,0xFC5E,0xC7AD,0x0085,0x0083, 0xFC5D,0xFC5C,0x0083,0xBADA,0xFC5B,0x00A1,0x0091,0x0089,0x0085,0x0083,0xF0A4,0xC0E8,0x0083,0xCAF2,0xFC5A,0x0085, 0x0083,0xFC59,0xFC58,0x0083,0xD9E4,0xFC57,0x0089,0x0085,0x0083,0xFC56,0xFC55,0x0083,0xFC54,0xBBC6,0x0085,0x0083, 0xFC53,0xFC52,0x0083,0xFC51,0xFC50,0x0091,0x0089,0x0085,0x0083,0xFC4F,0xF7E2,0x0083,0xF7E1,0xFC4E,0x0085,0x0083, 0xC2E9,0xFC4D,0x0083,0xFC4C,0xF4EF,0x0089,0x0085,0x0083,0xFC4B,0xFC4A,0x0083,0xFC49,0xF4F0,0x0085,0x0083,0xFC48, 0xFC47,0x0083,0xFC46,0xFC45,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xFC44,0xFC43,0x0083,0xFC42,0xFC41, 0x0085,0x0083,0xFC40,0xFBA0,0x0083,0xFB9F,0xFB9E,0x0089,0x0085,0x0083,0xFB9D,0xC2F3,0x0083,0xFB9C,0xFB9B,0x0085, 0x0083,0xFB9A,0xFB99,0x0083,0xFB98,0xFB97,0x0091,0x0089,0x0085,0x0083,0xF7EB,0xFB96,0x0083,0xF7EA,0xFB95,0x0085, 0x0083,0xFB94,0xFB93,0x0083,0xFB92,0xFB91,0x0089,0x0085,0x0083,0xFB90,0xFB8F,0x0083,0xFB8E,0xFB8D,0x0085,0x0083, 0xC2B4,0xF7E8,0x0083,0xFB8C,0xFB8B,0x00A1,0x0091,0x0089,0x0085,0x0083,0xFB8A,0xFB89,0x0083,0xFB88,0xFB87,0x0085, 0x0083,0xF7E7,0xFB86,0x0083,0xFB85,0xF7E6,0x0089,0x0085,0x0083,0xF7E5,0xFB84,0x0083,0xFB83,0xFB82,0x0085,0x0083, 0xFB81,0xF7E4,0x0083,0xFB80,0xFB7E,0x0091,0x0089,0x0085,0x0083,0xC2B9,0xF5BA,0x0083,0xFB7D,0xFB7C,0x0085,0x0083, 0xFB7B,0xFB7A,0x0083,0xFB79,0xFB78,0x0089,0x0085,0x0083,0xFB77,0xFB76,0x0083,0xFB75,0xFB74,0x0085,0x0083,0xF0D9, 0xFB73,0x0083,0xF0D7,0xD3A5,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xFB72,0xFB71,0x0083,0xF0D8,0xF0D6,0x0085, 0x0083,0xF0D5,0xF0D4,0x0083,0xF0D3,0xF0D2,0x0089,0x0085,0x0083,0xF0D1,0xF0D0,0x0083,0xFB70,0xBAD7,0x0085,0x0083, 0xF0CF,0xFB6F,0x0083,0xFB6E,0xFB6D,0x0091,0x0089,0x0085,0x0083,0xFB6C,0xF0CE,0x0083,0xFB6B,0xF0CD,0x0085,0x0083, 0xF0CC,0xF0CB,0x0083,0xFB6A,0xF7BD,0x0089,0x0085,0x0083,0xF0CA,0xFB69,0x0083,0xF0C9,0xFB68,0x0085,0x0083,0xFB67, 0xFB66,0x0083,0xF0C8,0xFB65,0x00A1,0x0091,0x0089,0x0085,0x0083,0xC5F4,0xF0C7,0x0083,0xFB64,0xF0C6,0x0085,0x0083, 0xF0C5,0xC8B5,0x0083,0xF0C4,0xF0C3,0x0089,0x0085,0x0083,0xF0C2,0xF0C1,0x0083,0xB6EC,0xF0C0,0x0085,0x0083,0xBEE9, 0xF0BF,0x0083,0xF0BE,0xFB63,0x0091,0x0089,0x0085,0x0083,0xBAE8,0xF0BD,0x0083,0xB8EB,0xFB62,0x0085,0x0083,0xFB61, 0xF0BC,0x0083,0xF0BB,0xF0B9,0x0089,0x0085,0x0083,0xF0BA,0xF0B8,0x0083,0xCDD2,0xFB60,0x0085,0x0083,0xD4A7,0xF0B6, 0x0083,0xF0B7,0xFB5F,0x027F,0x017F,0x00FF,0x00BF,0x009F,0x008F,0x0087,0x0083,0xD1EC,0x0083,0xFB5E,0xD1BC,0x0085, 0x0083,0xF0B5,0xF0B4,0x0083,0xF0B3,0xF0B2,0x0089,0x0085,0x0083,0xF0B1,0xFB5D,0x0083,0xD1BB,0xC5B8,0x0085,0x0083, 0xFB5C,0xC3F9,0x0083,0xF0B0,0xBCA6,0x0091,0x0089,0x0085,0x0083,0xF0AF,0xC4F1,0x0083,0xFB5B,0xFB5A,0x0085,0x0083, 0xFB59,0xFB58,0x0083,0xFB57,0xFB56,0x0089,0x0085,0x0083,0xFB55,0xFB54,0x0083,0xFB53,0xFB52,0x0085,0x0083,0xFB51, 0xFB50,0x0083,0xFB4F,0xFB4E,0x00A1,0x0091,0x0089,0x0085,0x0083,0xFB4D,0xFB4C,0x0083,0xFB4B,0xFB4A,0x0085,0x0083, 0xFB49,0xFB48,0x0083,0xFB47,0xFB46,0x0089,0x0085,0x0083,0xFB45,0xFB44,0x0083,0xFB43,0xFB42,0x0085,0x0083,0xFB41, 0xFB40,0x0083,0xFAA0,0xFA9F,0x0091,0x0089,0x0085,0x0083,0xFA9E,0xFA9D,0x0083,0xFA9C,0xFA9B,0x0085,0x0083,0xFA9A, 0xFA99,0x0083,0xFA98,0xFA97,0x0089,0x0085,0x0083,0xFA96,0xFA95,0x0083,0xFA94,0xFA93,0x0085,0x0083,0xFA92,0xFA91, 0x0083,0xFA90,0xFA8F,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xFA8E,0xFA8D,0x0083,0xFA8C,0xFA8B,0x0085,0x0083, 0xFA8A,0xFA89,0x0083,0xFA88,0xFA87,0x0089,0x0085,0x0083,0xFA86,0xFA85,0x0083,0xFA84,0xFA83,0x0085,0x0083,0xFA82, 0xFA81,0x0083,0xFA80,0xFA7E,0x0091,0x0089,0x0085,0x0083,0xFA7D,0xFA7C,0x0083,0xFA7B,0xFA7A,0x0085,0x0083,0xFA79, 0xFA78,0x0083,0xFA77,0xFA76,0x0089,0x0085,0x0083,0xFA75,0xFA74,0x0083,0xFA73,0xFA72,0x0085,0x0083,0xFA71,0xFA70, 0x0083,0xFA6F,0xFA6E,0x00A1,0x0091,0x0089,0x0085,0x0083,0xFA6D,0xFA6C,0x0083,0xFA6B,0xFA6A,0x0085,0x0083,0xFA69, 0xFA68,0x0083,0xFA67,0xFA66,0x0089,0x0085,0x0083,0xFA65,0xFA64,0x0083,0xFA63,0xFA62,0x0085,0x0083,0xFA61,0xFA60, 0x0083,0xFA5F,0xFA5E,0x0091,0x0089,0x0085,0x0083,0xFA5D,0xFA5C,0x0083,0xFA5B,0xFA5A,0x0085,0x0083,0xFA59,0xFA58, 0x0083,0xFA57,0xFA56,0x0089,0x0085,0x0083,0xFA55,0xFA54,0x0083,0xFA53,0xFA52,0x0085,0x0083,0xFA51,0xFA50,0x0083, 0xFA4F,0xFA4E,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xFA4D,0xFA4C,0x0083,0xFA4B,0xFA4A,0x0085,0x0083, 0xFA49,0xFA48,0x0083,0xFA47,0xFA46,0x0089,0x0085,0x0083,0xFA45,0xFA44,0x0083,0xFA43,0xFA42,0x0085,0x0083,0xFA41, 0xFA40,0x0083,0xF9A0,0xF99F,0x0091,0x0089,0x0085,0x0083,0xF99E,0xF99D,0x0083,0xF99C,0xF99B,0x0085,0x0083,0xF99A, 0xF999,0x0083,0xF998,0xF997,0x0089,0x0085,0x0083,0xF996,0xF995,0x0083,0xF994,0xF993,0x0085,0x0083,0xF992,0xF991, 0x0083,0xF990,0xF98F,0x00A1,0x0091,0x0089,0x0085,0x0083,0xF98E,0xF98D,0x0083,0xF98C,0xF98B,0x0085,0x0083,0xF98A, 0xF989,0x0083,0xF988,0xF987,0x0089,0x0085,0x0083,0xF986,0xF985,0x0083,0xF984,0xF983,0x0085,0x0083,0xF982,0xF981, 0x0083,0xF980,0xF97E,0x0091,0x0089,0x0085,0x0083,0xF97D,0xF97C,0x0083,0xF97B,0xF97A,0x0085,0x0083,0xF979,0xF978, 0x0083,0xF977,0xF976,0x0089,0x0085,0x0083,0xF975,0xF974,0x0083,0xF973,0xF972,0x0085,0x0083,0xF971,0xF970,0x0083, 0xF96F,0xF96E,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xF96D,0xF96C,0x0083,0xF96B,0xF96A,0x0085,0x0083,0xF969, 0xF968,0x0083,0xF967,0xF966,0x0089,0x0085,0x0083,0xF965,0xF964,0x0083,0xF963,0xF962,0x0085,0x0083,0xF961,0xF960, 0x0083,0xF95F,0xF95E,0x0091,0x0089,0x0085,0x0083,0xF95D,0xF95C,0x0083,0xF95B,0xF95A,0x0085,0x0083,0xF959,0xF958, 0x0083,0xF957,0xF956,0x0089,0x0085,0x0083,0xF955,0xF954,0x0083,0xF953,0xF952,0x0085,0x0083,0xF951,0xF950,0x0083, 0xF94F,0xF94E,0x00A1,0x0091,0x0089,0x0085,0x0083,0xF94D,0xF94C,0x0083,0xF94B,0xF94A,0x0085,0x0083,0xF949,0xF948, 0x0083,0xF947,0xF946,0x0089,0x0085,0x0083,0xF945,0xF944,0x0083,0xF943,0xF942,0x0085,0x0083,0xF941,0xF940,0x0083, 0xF8A0,0xF89F,0x0091,0x0089,0x0085,0x0083,0xF89E,0xF89D,0x0083,0xF89C,0xF89B,0x0085,0x0083,0xF89A,0xF899,0x0083, 0xF898,0xF897,0x0089,0x0085,0x0083,0xF896,0xF895,0x0083,0xF894,0xF893,0x0085,0x0083,0xF892,0xF891,0x0083,0xF890, 0xF88F,0x0181,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xF88E,0xF88D,0x0083,0xF88C,0xF88B,0x0085,0x0083, 0xF88A,0xF889,0x0083,0xF888,0xF887,0x0089,0x0085,0x0083,0xF886,0xF885,0x0083,0xF884,0xF883,0x0085,0x0083,0xF882, 0xF881,0x0083,0xF880,0xF87E,0x0091,0x0089,0x0085,0x0083,0xF87D,0xF87C,0x0083,0xF87B,0xF87A,0x0085,0x0083,0xF879, 0xF878,0x0083,0xF877,0xF876,0x0089,0x0085,0x0083,0xF875,0xF874,0x0083,0xF873,0xF872,0x0085,0x0083,0xF871,0xF870, 0x0083,0xF86F,0xF86E,0x00A1,0x0091,0x0089,0x0085,0x0083,0xF86D,0xF86C,0x0083,0xF86B,0xF86A,0x0085,0x0083,0xF869, 0xF868,0x0083,0xF867,0xF866,0x0089,0x0085,0x0083,0xF865,0xF864,0x0083,0xF863,0xF862,0x0085,0x0083,0xF861,0xF860, 0x0083,0xF85F,0xF85E,0x0091,0x0089,0x0085,0x0083,0xF85D,0xF85C,0x0083,0xF85B,0xF85A,0x0085,0x0083,0xF859,0xF858, 0x0083,0xF857,0xF856,0x0089,0x0085,0x0083,0xF855,0xF854,0x0083,0xF853,0xF852,0x0085,0x0083,0xF851,0xF850,0x0083, 0xF84F,0xF84E,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xF84D,0xF84C,0x0083,0xF84B,0xF84A,0x0085,0x0083,0xF849, 0xF848,0x0083,0xF847,0xF846,0x0089,0x0085,0x0083,0xF845,0xF844,0x0083,0xF843,0xF842,0x0085,0x0083,0xF841,0xF840, 0x0083,0xF7AF,0xF7A0,0x0091,0x0089,0x0085,0x0083,0xF79F,0xF7AE,0x0083,0xC1DB,0xF7AD,0x0085,0x0083,0xF7AC,0xF79E, 0x0083,0xF79D,0xF7AB,0x0089,0x0085,0x0083,0xF7AA,0xF7A9,0x0083,0xB1EE,0xF7A8,0x0085,0x0083,0xF7A7,0xF7A6,0x0083, 0xF79C,0xF79B,0x00A1,0x0091,0x0089,0x0085,0x0083,0xF7A5,0xF7A4,0x0083,0xF7A3,0xF7A2,0x0085,0x0083,0xF7A1,0xF6FE, 0x0083,0xF6FD,0xF79A,0x0089,0x0085,0x0083,0xF799,0xF6FC,0x0083,0xF6FB,0xF6FA,0x0085,0x0083,0xF6F9,0xC8FA,0x0083, 0xF798,0xF797,0x0091,0x0089,0x0085,0x0083,0xF796,0xF795,0x0083,0xF794,0xF6F8,0x0085,0x0083,0xF6F7,0xF6F6,0x0083, 0xF6F5,0xF793,0x0089,0x0085,0x0083,0xBEA8,0xF6F4,0x0083,0xF6F3,0xF6F2,0x0085,0x0083,0xF6F1,0xF6F0,0x0083,0xF6EF, 0xF6EE,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xF6ED,0xF792,0x0083,0xF6EC,0xF6EB,0x0085,0x0083,0xF791, 0xF6EA,0x0083,0xF790,0xF6E9,0x0089,0x0085,0x0083,0xF6E8,0xF6E7,0x0083,0xF6E6,0xF6E5,0x0085,0x0083,0xC0F0,0xF6E4, 0x0083,0xF6E3,0xF6E2,0x0091,0x0089,0x0085,0x0083,0xF6E1,0xF6E0,0x0083,0xF6DF,0xF78F,0x0085,0x0083,0xCFCA,0xF6DE, 0x0083,0xF6DD,0xF78E,0x0089,0x0085,0x0083,0xF78D,0xF78C,0x0083,0xF78B,0xF6DC,0x0085,0x0083,0xF6DB,0xF78A,0x0083, 0xF6DA,0xF6D9,0x00A1,0x0091,0x0089,0x0085,0x0083,0xF6D8,0xF789,0x0083,0xF6D7,0xB1AB,0x0085,0x0083,0xF788,0xF6D6, 0x0083,0xF787,0xF786,0x0089,0x0085,0x0083,0xF6D4,0xF6D3,0x0083,0xF6D2,0xF6D1,0x0085,0x0083,0xF785,0xF784,0x0083, 0xF6D0,0xC2B3,0x0091,0x0089,0x0085,0x0083,0xF783,0xF6CF,0x0083,0xF782,0xF781,0x0085,0x0083,0xD3E3,0xF780,0x0083, 0xF77E,0xF77D,0x0089,0x0085,0x0083,0xF77C,0xF77B,0x0083,0xF77A,0xF779,0x0085,0x0083,0xF778,0xF777,0x0083,0xF776, 0xF775,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xF774,0xF773,0x0083,0xF772,0xF771,0x0085,0x0083,0xF770,0xF76F, 0x0083,0xF76E,0xF76D,0x0089,0x0085,0x0083,0xF76C,0xF76B,0x0083,0xF76A,0xF769,0x0085,0x0083,0xF768,0xF767,0x0083, 0xF766,0xF765,0x0091,0x0089,0x0085,0x0083,0xF764,0xF763,0x0083,0xF762,0xF761,0x0085,0x0083,0xF760,0xF75F,0x0083, 0xF75E,0xF75D,0x0089,0x0085,0x0083,0xF75C,0xF75B,0x0083,0xF75A,0xF759,0x0085,0x0083,0xF758,0xF757,0x0083,0xF756, 0xF755,0x00A1,0x0091,0x0089,0x0085,0x0083,0xF754,0xF753,0x0083,0xF752,0xF751,0x0085,0x0083,0xF750,0xF74F,0x0083, 0xF74E,0xF74D,0x0089,0x0085,0x0083,0xF74C,0xF74B,0x0083,0xF74A,0xF749,0x0085,0x0083,0xF748,0xF747,0x0083,0xF746, 0xF745,0x0091,0x0089,0x0085,0x0083,0xF744,0xF743,0x0083,0xF742,0xF741,0x0085,0x0083,0xF740,0xF6A0,0x0083,0xF69F, 0xF69E,0x0089,0x0085,0x0083,0xF69D,0xF69C,0x0083,0xF69B,0xF69A,0x0085,0x0083,0xF699,0xF698,0x0083,0xF697,0xF696, 0x047D,0x027F,0x017F,0x00FF,0x00BF,0x009F,0x008F,0x0087,0x0083,0xF695,0x0083,0xF694,0xF693,0x0085,0x0083,0xF692, 0xF691,0x0083,0xF690,0xF68F,0x0089,0x0085,0x0083,0xF68E,0xF68D,0x0083,0xF68C,0xF68B,0x0085,0x0083,0xF68A,0xF689, 0x0083,0xF688,0xF687,0x0091,0x0089,0x0085,0x0083,0xF686,0xF685,0x0083,0xF684,0xF683,0x0085,0x0083,0xF682,0xF681, 0x0083,0xF680,0xF67E,0x0089,0x0085,0x0083,0xF67D,0xF67C,0x0083,0xF67B,0xF67A,0x0085,0x0083,0xF679,0xF678,0x0083, 0xF677,0xF676,0x00A1,0x0091,0x0089,0x0085,0x0083,0xF675,0xF674,0x0083,0xF673,0xF672,0x0085,0x0083,0xF671,0xF670, 0x0083,0xF66F,0xF66E,0x0089,0x0085,0x0083,0xF66D,0xF66C,0x0083,0xF66B,0xF66A,0x0085,0x0083,0xF669,0xF668,0x0083, 0xF667,0xF666,0x0091,0x0089,0x0085,0x0083,0xF665,0xF664,0x0083,0xF663,0xF662,0x0085,0x0083,0xF661,0xF660,0x0083, 0xF65F,0xF65E,0x0089,0x0085,0x0083,0xF65D,0xF65C,0x0083,0xF65B,0xF65A,0x0085,0x0083,0xF659,0xF658,0x0083,0xF657, 0xF656,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xF655,0xF654,0x0083,0xF653,0xF652,0x0085,0x0083,0xF651,0xF650, 0x0083,0xF64F,0xF64E,0x0089,0x0085,0x0083,0xF64D,0xF64C,0x0083,0xF64B,0xF64A,0x0085,0x0083,0xF649,0xF648,0x0083, 0xF647,0xF646,0x0091,0x0089,0x0085,0x0083,0xF645,0xF644,0x0083,0xF643,0xF642,0x0085,0x0083,0xF641,0xF640,0x0083, 0xF5A0,0xF59F,0x0089,0x0085,0x0083,0xF59E,0xF59D,0x0083,0xF59C,0xF59B,0x0085,0x0083,0xF59A,0xF599,0x0083,0xF598, 0xF597,0x00A1,0x0091,0x0089,0x0085,0x0083,0xF596,0xF595,0x0083,0xF594,0xF593,0x0085,0x0083,0xF592,0xF591,0x0083, 0xF590,0xF58F,0x0089,0x0085,0x0083,0xF58E,0xF58D,0x0083,0xF58C,0xF58B,0x0085,0x0083,0xF58A,0xF589,0x0083,0xF588, 0xF587,0x0091,0x0089,0x0085,0x0083,0xF586,0xF585,0x0083,0xF584,0xF583,0x0085,0x0083,0xF582,0xF581,0x0083,0xF580, 0xF57E,0x0089,0x0085,0x0083,0xF57D,0xF57C,0x0083,0xF57B,0xF57A,0x0085,0x0083,0xF579,0xF578,0x0083,0xF577,0xF576, 0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xF575,0xF574,0x0083,0xF573,0xF572,0x0085,0x0083,0xF571,0xF570, 0x0083,0xF56F,0xF56E,0x0089,0x0085,0x0083,0xF56D,0xF56C,0x0083,0xF56B,0xF56A,0x0085,0x0083,0xF569,0xF568,0x0083, 0xF567,0xF566,0x0091,0x0089,0x0085,0x0083,0xF565,0xF564,0x0083,0xF563,0xF562,0x0085,0x0083,0xF561,0xF560,0x0083, 0xF55F,0xF55E,0x0089,0x0085,0x0083,0xF55D,0xF55C,0x0083,0xF55B,0xF55A,0x0085,0x0083,0xF559,0xF558,0x0083,0xF557, 0xF556,0x00A1,0x0091,0x0089,0x0085,0x0083,0xF555,0xF554,0x0083,0xF553,0xF552,0x0085,0x0083,0xF551,0xF550,0x0083, 0xF54F,0xF54E,0x0089,0x0085,0x0083,0xF54D,0xF54C,0x0083,0xF54B,0xF54A,0x0085,0x0083,0xF549,0xF548,0x0083,0xF547, 0xF546,0x0091,0x0089,0x0085,0x0083,0xF545,0xF544,0x0083,0xF543,0xF542,0x0085,0x0083,0xF541,0xF540,0x0083,0xF4A0, 0xF49F,0x0089,0x0085,0x0083,0xF49E,0xF49D,0x0083,0xF49C,0xF49B,0x0085,0x0083,0xF49A,0xF499,0x0083,0xF498,0xF497, 0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xF496,0xF495,0x0083,0xF494,0xF493,0x0085,0x0083,0xF492,0xF491,0x0083, 0xF490,0xF48F,0x0089,0x0085,0x0083,0xF48E,0xF48D,0x0083,0xF48C,0xF48B,0x0085,0x0083,0xF48A,0xF489,0x0083,0xF488, 0xF487,0x0091,0x0089,0x0085,0x0083,0xF486,0xF485,0x0083,0xF484,0xF483,0x0085,0x0083,0xF482,0xF481,0x0083,0xF480, 0xF47E,0x0089,0x0085,0x0083,0xF47D,0xF47C,0x0083,0xF47B,0xF47A,0x0085,0x0083,0xF479,0xC4A7,0x0083,0xF478,0xF477, 0x00A1,0x0091,0x0089,0x0085,0x0083,0xF7CE,0xF476,0x0083,0xCEBA,0xF475,0x0085,0x0083,0xF7CD,0xF474,0x0083,0xF473, 0xF472,0x0089,0x0085,0x0083,0xF7CB,0xF7CC,0x0083,0xF7CA,0xF471,0x0085,0x0083,0xF7C8,0xC6C7,0x0083,0xF7C9,0xBBEA, 0x0091,0x0089,0x0085,0x0083,0xBFFD,0xF470,0x0083,0xF46F,0xF46E,0x0085,0x0083,0xF46D,0xB9ED,0x0083,0xE5F7,0xF46C, 0x0089,0x0085,0x0083,0xF46B,0xF46A,0x0083,0xF469,0xF468,0x0085,0x0083,0xF467,0xF466,0x0083,0xF465,0xD8AA,0x017F, 0x00FF,0x00BF,0x009F,0x008F,0x0087,0x0083,0xF464,0x0083,0xF463,0xDBCB,0x0085,0x0083,0xF462,0xF461,0x0083,0xF460, 0xF45F,0x0089,0x0085,0x0083,0xF45E,0xF45D,0x0083,0xF45C,0xF45B,0x0085,0x0083,0xF45A,0xF459,0x0083,0xF458,0xF7E0, 0x0091,0x0089,0x0085,0x0083,0xF457,0xF456,0x0083,0xF455,0xF7DF,0x0085,0x0083,0xF454,0xF453,0x0083,0xF452,0xF451, 0x0089,0x0085,0x0083,0xF450,0xF44F,0x0083,0xF44E,0xF44D,0x0085,0x0083,0xF44C,0xF44B,0x0083,0xF44A,0xF7DE,0x00A1, 0x0091,0x0089,0x0085,0x0083,0xF449,0xF448,0x0083,0xF447,0xF7DD,0x0085,0x0083,0xF446,0xF445,0x0083,0xF444,0xF443, 0x0089,0x0085,0x0083,0xF442,0xF441,0x0083,0xF7DC,0xF440,0x0085,0x0083,0xF3A0,0xF39F,0x0083,0xF39E,0xD7D7,0x0091, 0x0089,0x0085,0x0083,0xF39D,0xF39C,0x0083,0xF39B,0xF39A,0x0085,0x0083,0xF399,0xF398,0x0083,0xF397,0xF7D9,0x0089, 0x0085,0x0083,0xF396,0xF7DB,0x0083,0xF395,0xF394,0x0085,0x0083,0xF393,0xF392,0x0083,0xF391,0xF390,0x00C1,0x00A1, 0x0091,0x0089,0x0085,0x0083,0xF38F,0xF38E,0x0083,0xF38D,0xF7D7,0x0085,0x0083,0xF38C,0xF7DA,0x0083,0xF38B,0xF7D8, 0x0089,0x0085,0x0083,0xF38A,0xF389,0x0083,0xF388,0xF387,0x0085,0x0083,0xF7D6,0xF386,0x0083,0xF385,0xF384,0x0091, 0x0089,0x0085,0x0083,0xF383,0xF7D5,0x0083,0xF382,0xF7D4,0x0085,0x0083,0xF381,0xF380,0x0083,0xF37E,0xF37D,0x0089, 0x0085,0x0083,0xF37C,0xF37B,0x0083,0xB8DF,0xF37A,0x0085,0x0083,0xF379,0xF378,0x0083,0xF377,0xCBE8,0x00A1,0x0091, 0x0089,0x0085,0x0083,0xF376,0xF7C7,0x0083,0xF375,0xF374,0x0085,0x0083,0xF373,0xF372,0x0083,0xF7C6,0xF7C5,0x0089, 0x0085,0x0083,0xF371,0xF370,0x0083,0xF36F,0xF36E,0x0085,0x0083,0xF36D,0xF7C3,0x0083,0xF36C,0xF36B,0x0091,0x0089, 0x0085,0x0083,0xF7C4,0xF7C1,0x0083,0xF7C2,0xF36A,0x0085,0x0083,0xF369,0xF368,0x0083,0xF7C0,0xF367,0x0089,0x0085, 0x0083,0xF7BF,0xF366,0x0083,0xBAA1,0xF7BC,0x0085,0x0083,0xF7BE,0xF365,0x0083,0xF364,0xF363,0x0101,0x00C1,0x00A1, 0x0091,0x0089,0x0085,0x0083,0xF362,0xF7BA,0x0083,0xF7BB,0xF361,0x0085,0x0083,0xF360,0xF35F,0x0083,0xF35E,0xF35D, 0x0089,0x0085,0x0083,0xF35C,0xF35B,0x0083,0xB9C7,0xE6F8,0x0085,0x0083,0xF35A,0xE6F7,0x0083,0xD6E8,0xE6F6,0x0091, 0x0089,0x0085,0x0083,0xE6F5,0xC2E2,0x0083,0xE6F4,0xE6F3,0x0085,0x0083,0xE5B9,0xE6F2,0x0083,0xE6F1,0xE6F0,0x0089, 0x0085,0x0083,0xC9A7,0xF359,0x0083,0xE6EF,0xC6AD,0x0085,0x0083,0xE6EE,0xF358,0x0083,0xF357,0xE6ED,0x00A1,0x0091, 0x0089,0x0085,0x0083,0xE6EC,0xC6EF,0x0083,0xE6EB,0xBFA5,0x0085,0x0083,0xF356,0xF355,0x0083,0xD1E9,0xB3D2,0x0089, 0x0085,0x0083,0xE6EA,0xF354,0x0083,0xE6E9,0xBAA7,0x0085,0x0083,0xC2E6,0xE6E8,0x0083,0xBDBE,0xF353,0x0091,0x0089, 0x0085,0x0083,0xC2EE,0xE6E7,0x0083,0xE6E6,0xE6E4,0x0085,0x0083,0xBCDD,0xE6E5,0x0083,0xCDD5,0xD7A4,0x0089,0x0085, 0x0083,0xE6E3,0xBED4,0x0083,0xE6E2,0xE6E1,0x0085,0x0083,0xCABB,0xE6E0,0x0083,0xC2BF,0xB2B5,0x00C1,0x00A1,0x0091, 0x0089,0x0085,0x0083,0xF352,0xC7FD,0x0083,0xB3DB,0xD1B1,0x0085,0x0083,0xCDD4,0xD4A6,0x0083,0xC2ED,0xF351,0x0089, 0x0085,0x0083,0xF350,0xF34F,0x0083,0xF34E,0xF34D,0x0085,0x0083,0xF34C,0xF34B,0x0083,0xF34A,0xF349,0x0091,0x0089, 0x0085,0x0083,0xF348,0xF347,0x0083,0xF346,0xF345,0x0085,0x0083,0xF344,0xF343,0x0083,0xF342,0xF341,0x0089,0x0085, 0x0083,0xF340,0xF2A0,0x0083,0xF29F,0xF29E,0x0085,0x0083,0xF29D,0xF29C,0x0083,0xF29B,0xF29A,0x00A1,0x0091,0x0089, 0x0085,0x0083,0xF299,0xF298,0x0083,0xF297,0xF296,0x0085,0x0083,0xF295,0xF294,0x0083,0xF293,0xF292,0x0089,0x0085, 0x0083,0xF291,0xF290,0x0083,0xF28F,0xF28E,0x0085,0x0083,0xF28D,0xF28C,0x0083,0xF28B,0xF28A,0x0091,0x0089,0x0085, 0x0083,0xF289,0xF288,0x0083,0xF287,0xF286,0x0085,0x0083,0xF285,0xF284,0x0083,0xF283,0xF282,0x0089,0x0085,0x0083, 0xF281,0xF280,0x0083,0xF27E,0xF27D,0x0085,0x0083,0xF27C,0xF27B,0x0083,0xF27A,0xF279,0x027F,0x017F,0x00FF,0x00BF, 0x009F,0x008F,0x0087,0x0083,0xF278,0x0083,0xF277,0xF276,0x0085,0x0083,0xF275,0xF274,0x0083,0xF273,0xF272,0x0089, 0x0085,0x0083,0xF271,0xF270,0x0083,0xF26F,0xF26E,0x0085,0x0083,0xF26D,0xF26C,0x0083,0xF26B,0xF26A,0x0091,0x0089, 0x0085,0x0083,0xF269,0xF268,0x0083,0xF267,0xF266,0x0085,0x0083,0xF265,0xF264,0x0083,0xF263,0xF262,0x0089,0x0085, 0x0083,0xF261,0xF260,0x0083,0xF25F,0xF25E,0x0085,0x0083,0xF25D,0xF25C,0x0083,0xF25B,0xF25A,0x00A1,0x0091,0x0089, 0x0085,0x0083,0xF259,0xF258,0x0083,0xF257,0xF256,0x0085,0x0083,0xF255,0xF254,0x0083,0xF253,0xF252,0x0089,0x0085, 0x0083,0xF251,0xF250,0x0083,0xF24F,0xF24E,0x0085,0x0083,0xF24D,0xF24C,0x0083,0xF24B,0xF24A,0x0091,0x0089,0x0085, 0x0083,0xF249,0xF248,0x0083,0xF247,0xF246,0x0085,0x0083,0xF245,0xF244,0x0083,0xF243,0xF242,0x0089,0x0085,0x0083, 0xF241,0xF240,0x0083,0xF1A0,0xF19F,0x0085,0x0083,0xF19E,0xF19D,0x0083,0xF19C,0xF19B,0x00C1,0x00A1,0x0091,0x0089, 0x0085,0x0083,0xF19A,0xF199,0x0083,0xF198,0xF197,0x0085,0x0083,0xF196,0xF195,0x0083,0xF194,0xF193,0x0089,0x0085, 0x0083,0xF192,0xF191,0x0083,0xF190,0xF18F,0x0085,0x0083,0xF18E,0xF18D,0x0083,0xF18C,0xF18B,0x0091,0x0089,0x0085, 0x0083,0xF18A,0xF189,0x0083,0xF188,0xF187,0x0085,0x0083,0xF186,0xF185,0x0083,0xF184,0xF183,0x0089,0x0085,0x0083, 0xF182,0xF181,0x0083,0xF180,0xF17E,0x0085,0x0083,0xF17D,0xF17C,0x0083,0xF17B,0xF17A,0x00A1,0x0091,0x0089,0x0085, 0x0083,0xF179,0xF178,0x0083,0xF177,0xF176,0x0085,0x0083,0xF175,0xF174,0x0083,0xF173,0xF172,0x0089,0x0085,0x0083, 0xF171,0xF170,0x0083,0xF16F,0xF16E,0x0085,0x0083,0xF16D,0xF16C,0x0083,0xF16B,0xF16A,0x0091,0x0089,0x0085,0x0083, 0xF169,0xF168,0x0083,0xF167,0xF166,0x0085,0x0083,0xF165,0xF164,0x0083,0xF163,0xF162,0x0089,0x0085,0x0083,0xF161, 0xF160,0x0083,0xF15F,0xF15E,0x0085,0x0083,0xF15D,0xF15C,0x0083,0xF15B,0xF15A,0x0101,0x00C1,0x00A1,0x0091,0x0089, 0x0085,0x0083,0xF159,0xF158,0x0083,0xF157,0xF156,0x0085,0x0083,0xF155,0xF154,0x0083,0xF153,0xF152,0x0089,0x0085, 0x0083,0xF151,0xF150,0x0083,0xF14F,0xDCB0,0x0085,0x0083,0xF14E,0xF14D,0x0083,0xF0A5,0xF14C,0x0091,0x0089,0x0085, 0x0083,0xF14B,0xF14A,0x0083,0xF149,0xF148,0x0085,0x0083,0xF147,0xF146,0x0083,0xF145,0xF144,0x0089,0x0085,0x0083, 0xF143,0xF142,0x0083,0xCFE3,0xD9E5,0x0085,0x0083,0xD8B8,0xCAD7,0x0083,0xE2CE,0xE2CD,0x00A1,0x0091,0x0089,0x0085, 0x0083,0xE2CC,0xC2F8,0x0083,0xE2CB,0xE2CA,0x0085,0x0083,0xC1F3,0xF141,0x0083,0xE2C9,0xF140,0x0089,0x0085,0x0083, 0xB2F6,0xE2C8,0x0083,0xF0A0,0xC0A1,0x0085,0x0083,0xE2C7,0xB9DD,0x0083,0xCFDA,0xE2C6,0x0091,0x0089,0x0085,0x0083, 0xF09F,0xF09E,0x0083,0xC4D9,0xE2C5,0x0085,0x0083,0xB6F6,0xF09D,0x0083,0xE2C4,0xB1FD,0x0089,0x0085,0x0083,0xF09C, 0xBDC8,0x0083,0xF09B,0xF09A,0x0085,0x0083,0xE2C3,0xC8C4,0x0083,0xB6FC,0xE2C2,0x00C1,0x00A1,0x0091,0x0089,0x0085, 0x0083,0xF099,0xCBC7,0x0083,0xB1A5,0xCACE,0x0085,0x0083,0xBDA4,0xD2FB,0x0083,0xB7B9,0xE2C1,0x0089,0x0085,0x0083, 0xE2C0,0xE2BF,0x0083,0xE2BE,0xE2BD,0x0085,0x0083,0xE2BC,0xF098,0x0083,0xBCA2,0xF097,0x0091,0x0089,0x0085,0x0083, 0xE2BB,0xF096,0x0083,0xF095,0xF094,0x0085,0x0083,0xF093,0xF092,0x0083,0xF091,0xF090,0x0089,0x0085,0x0083,0xF08F, 0xF08E,0x0083,0xF08D,0xF08C,0x0085,0x0083,0xF08B,0xF08A,0x0083,0xF7D2,0xF7D3,0x00A1,0x0091,0x0089,0x0085,0x0083, 0xF089,0xF088,0x0083,0xF087,0xF086,0x0085,0x0083,0xF085,0xF084,0x0083,0xF083,0xF082,0x0089,0x0085,0x0083,0xF081, 0xF080,0x0083,0xF07E,0xF07D,0x0085,0x0083,0xF07C,0xF07B,0x0083,0xF07A,0xF079,0x0091,0x0089,0x0085,0x0083,0xF078, 0xF077,0x0083,0xF076,0xF075,0x0085,0x0083,0xF074,0xF073,0x0083,0xF072,0xF071,0x0089,0x0085,0x0083,0xF070,0xF06F, 0x0083,0xF06E,0xF06D,0x0085,0x0083,0xF06C,0xF06B,0x0083,0xF06A,0xF069,0x0181,0x0101,0x00C1,0x00A1,0x0091,0x0089, 0x0085,0x0083,0xF068,0xF067,0x0083,0xF066,0xF065,0x0085,0x0083,0xF064,0xF7D1,0x0083,0xF063,0xF062,0x0089,0x0085, 0x0083,0xF061,0xF060,0x0083,0xF05F,0xF05E,0x0085,0x0083,0xF05D,0xF05C,0x0083,0xF05B,0xF05A,0x0091,0x0089,0x0085, 0x0083,0xF059,0xF058,0x0083,0xF057,0xF056,0x0085,0x0083,0xF055,0xF054,0x0083,0xF053,0xF052,0x0089,0x0085,0x0083, 0xF051,0xF050,0x0083,0xF04F,0xF04E,0x0085,0x0083,0xF04D,0xF04C,0x0083,0xF04B,0xF04A,0x00A1,0x0091,0x0089,0x0085, 0x0083,0xF049,0xF048,0x0083,0xF047,0xB2CD,0x0085,0x0083,0xF046,0xF045,0x0083,0xF7D0,0xF044,0x0089,0x0085,0x0083, 0xF043,0xF042,0x0083,0xF041,0xF040,0x0085,0x0083,0xEFA0,0xEF9F,0x0083,0xEF9E,0xEF9D,0x0091,0x0089,0x0085,0x0083, 0xEF9C,0xEF9B,0x0083,0xEF9A,0xEF99,0x0085,0x0083,0xEF98,0xEF97,0x0083,0xEF96,0xEF95,0x0089,0x0085,0x0083,0xEF94, 0xEF93,0x0083,0xEF92,0xEF91,0x0085,0x0083,0xEF90,0xEF8F,0x0083,0xEF8E,0xEF8D,0x00C1,0x00A1,0x0091,0x0089,0x0085, 0x0083,0xEF8C,0xEF8B,0x0083,0xEF8A,0xEF89,0x0085,0x0083,0xEF88,0xEF87,0x0083,0xEF86,0xEF85,0x0089,0x0085,0x0083, 0xEF84,0xEF83,0x0083,0xEF82,0xF7CF,0x0085,0x0083,0xE2B8,0xEF81,0x0083,0xEF80,0xEF7E,0x0091,0x0089,0x0085,0x0083, 0xEF7D,0xEF7C,0x0083,0xEF7B,0xEF7A,0x0085,0x0083,0xCAB3,0xB7C9,0x0083,0xEF79,0xEF78,0x0089,0x0085,0x0083,0xEF77, 0xECAE,0x0083,0xECAD,0xC6AE,0x0085,0x0083,0xEF76,0xEF75,0x0083,0xECAC,0xEF74,0x00A1,0x0091,0x0089,0x0085,0x0083, 0xECAB,0xECAA,0x0083,0xECA9,0xEF73,0x0085,0x0083,0xEF72,0xB7E7,0x0083,0xEF71,0xEF70,0x0089,0x0085,0x0083,0xEF6F, 0xEF6E,0x0083,0xEF6D,0xEF6C,0x0085,0x0083,0xEF6B,0xEF6A,0x0083,0xEF69,0xEF68,0x0091,0x0089,0x0085,0x0083,0xEF67, 0xEF66,0x0083,0xEF65,0xEF64,0x0085,0x0083,0xEF63,0xEF62,0x0083,0xEF61,0xEF60,0x0089,0x0085,0x0083,0xEF5F,0xEF5E, 0x0083,0xEF5D,0xEF5C,0x0085,0x0083,0xEF5B,0xEF5A,0x0083,0xEF59,0xEF58,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085, 0x0083,0xEF57,0xEF56,0x0083,0xEF55,0xEF54,0x0085,0x0083,0xEF53,0xEF52,0x0083,0xEF51,0xEF50,0x0089,0x0085,0x0083, 0xEF4F,0xEF4E,0x0083,0xEF4D,0xEF4C,0x0085,0x0083,0xC8A7,0xF2AD,0x0083,0xF2AC,0xB2FC,0x0091,0x0089,0x0085,0x0083, 0xEF4B,0xF2AB,0x0083,0xF2AA,0xB5DF,0x0085,0x0083,0xF2A9,0xF2A8,0x0083,0xB6EE,0xD1D5,0x0089,0x0085,0x0083,0xF2A7, 0xF2A6,0x0083,0xEF4A,0xCCE2,0x0085,0x0083,0xBFC5,0xD3B1,0x0083,0xEF49,0xF2A5,0x00A1,0x0091,0x0089,0x0085,0x0083, 0xCDC7,0xEF48,0x0083,0xC6B5,0xD2C3,0x0085,0x0083,0xF2A4,0xEF47,0x0083,0xF2A3,0xF2A2,0x0089,0x0085,0x0083,0xEF46, 0xBCD5,0x0083,0xF2A1,0xBEB1,0x0085,0x0083,0xC6C4,0xC1EC,0x0083,0xC2AD,0xD4A4,0x0091,0x0089,0x0085,0x0083,0xF1FE, 0xCBCC,0x0083,0xB0E4,0xF1FD,0x0085,0x0083,0xB6D9,0xB9CB,0x0083,0xCDE7,0xE7EF,0x0089,0x0085,0x0083,0xD0EB,0xCBB3, 0x0083,0xCFEE,0xF1FC,0x0085,0x0083,0xC7EA,0xB6A5,0x0083,0xD2B3,0xEF45,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083, 0xEF44,0xEF43,0x0083,0xEF42,0xEF41,0x0085,0x0083,0xEF40,0xEEA0,0x0083,0xEE9F,0xEE9E,0x0089,0x0085,0x0083,0xEE9D, 0xEE9C,0x0083,0xEE9B,0xEE9A,0x0085,0x0083,0xEE99,0xEE98,0x0083,0xEE97,0xEE96,0x0091,0x0089,0x0085,0x0083,0xEE95, 0xEE94,0x0083,0xEE93,0xEE92,0x0085,0x0083,0xEE91,0xEE90,0x0083,0xEE8F,0xEE8E,0x0089,0x0085,0x0083,0xEE8D,0xEE8C, 0x0083,0xEE8B,0xEE8A,0x0085,0x0083,0xEE89,0xEE88,0x0083,0xEE87,0xEE86,0x00A1,0x0091,0x0089,0x0085,0x0083,0xEE85, 0xEE84,0x0083,0xEE83,0xEE82,0x0085,0x0083,0xEE81,0xEE80,0x0083,0xEE7E,0xEE7D,0x0089,0x0085,0x0083,0xEE7C,0xEE7B, 0x0083,0xEE7A,0xEE79,0x0085,0x0083,0xEE78,0xEE77,0x0083,0xEE76,0xEE75,0x0091,0x0089,0x0085,0x0083,0xEE74,0xEE73, 0x0083,0xEE72,0xEE71,0x0085,0x0083,0xEE70,0xEE6F,0x0083,0xEE6E,0xEE6D,0x0089,0x0085,0x0083,0xEE6C,0xEE6B,0x0083, 0xEE6A,0xEE69,0x0085,0x0083,0xEE68,0xEE67,0x0083,0xEE66,0xEE65,0x087B,0x047D,0x027F,0x017F,0x00FF,0x00BF,0x009F, 0x008F,0x0087,0x0083,0xEE64,0x0083,0xEE63,0xEE62,0x0085,0x0083,0xEE61,0xEE60,0x0083,0xEE5F,0xEE5E,0x0089,0x0085, 0x0083,0xEE5D,0xEE5C,0x0083,0xEE5B,0xEE5A,0x0085,0x0083,0xEE59,0xEE58,0x0083,0xEE57,0xEE56,0x0091,0x0089,0x0085, 0x0083,0xEE55,0xEE54,0x0083,0xEE53,0xEE52,0x0085,0x0083,0xEE51,0xEE50,0x0083,0xEE4F,0xEE4E,0x0089,0x0085,0x0083, 0xEE4D,0xEE4C,0x0083,0xEE4B,0xEE4A,0x0085,0x0083,0xEE49,0xEE48,0x0083,0xEE47,0xEE46,0x00A1,0x0091,0x0089,0x0085, 0x0083,0xEE45,0xEE44,0x0083,0xEE43,0xEE42,0x0085,0x0083,0xEE41,0xEE40,0x0083,0xEDA0,0xED9F,0x0089,0x0085,0x0083, 0xED9E,0xED9D,0x0083,0xED9C,0xED9B,0x0085,0x0083,0xED9A,0xED99,0x0083,0xED98,0xED97,0x0091,0x0089,0x0085,0x0083, 0xED96,0xED95,0x0083,0xED94,0xED93,0x0085,0x0083,0xED92,0xED91,0x0083,0xED90,0xED8F,0x0089,0x0085,0x0083,0xED8E, 0xED8D,0x0083,0xED8C,0xED8B,0x0085,0x0083,0xED8A,0xED89,0x0083,0xC9D8,0xD4CF,0x00C1,0x00A1,0x0091,0x0089,0x0085, 0x0083,0xED88,0xD2F4,0x0083,0xED87,0xED86,0x0085,0x0083,0xED85,0xED84,0x0083,0xED83,0xBEC2,0x0089,0x0085,0x0083, 0xE8BA,0xE8B9,0x0083,0xE8B8,0xBAAB,0x0085,0x0083,0xED82,0xC8CD,0x0083,0xCEA4,0xED81,0x0091,0x0089,0x0085,0x0083, 0xED80,0xED7E,0x0083,0xED7D,0xED7C,0x0085,0x0083,0xED7B,0xED7A,0x0083,0xED79,0xED78,0x0089,0x0085,0x0083,0xED77, 0xED76,0x0083,0xED75,0xED74,0x0085,0x0083,0xED73,0xED72,0x0083,0xED71,0xED70,0x00A1,0x0091,0x0089,0x0085,0x0083, 0xED6F,0xED6E,0x0083,0xED6D,0xED6C,0x0085,0x0083,0xED6B,0xED6A,0x0083,0xED69,0xED68,0x0089,0x0085,0x0083,0xED67, 0xED66,0x0083,0xED65,0xED64,0x0085,0x0083,0xED63,0xED62,0x0083,0xED61,0xED60,0x0091,0x0089,0x0085,0x0083,0xED5F, 0xED5E,0x0083,0xED5D,0xED5C,0x0085,0x0083,0xED5B,0xED5A,0x0083,0xED59,0xED58,0x0089,0x0085,0x0083,0xED57,0xED56, 0x0083,0xED55,0xED54,0x0085,0x0083,0xED53,0xED52,0x0083,0xED51,0xED50,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085, 0x0083,0xF7B9,0xED4F,0x0083,0xF7B8,0xED4E,0x0085,0x0083,0xED4D,0xF7B5,0x0083,0xED4C,0xB1DE,0x0089,0x0085,0x0083, 0xED4B,0xF7B6,0x0083,0xED4A,0xED49,0x0085,0x0083,0xED48,0xED47,0x0083,0xED46,0xED45,0x0091,0x0089,0x0085,0x0083, 0xED44,0xF7B7,0x0083,0xED43,0xED42,0x0085,0x0083,0xBECF,0xED41,0x0083,0xED40,0xECA0,0x0089,0x0085,0x0083,0xEC9F, 0xEC9E,0x0083,0xEC9D,0xEC9C,0x0085,0x0083,0xC7CA,0xEC9B,0x0083,0xEC9A,0xEC99,0x00A1,0x0091,0x0089,0x0085,0x0083, 0xF7B4,0xEC98,0x0083,0xF7B3,0xF7B2,0x0085,0x0083,0xEC97,0xEC96,0x0083,0xEC95,0xB0B0,0x0089,0x0085,0x0083,0xEC94, 0xD0AC,0x0083,0xEC93,0xEC92,0x0085,0x0083,0xEC91,0xEC90,0x0083,0xEC8F,0xF7B1,0x0091,0x0089,0x0085,0x0083,0xEC8E, 0xEC8D,0x0083,0xEC8C,0xEC8B,0x0085,0x0083,0xEC8A,0xEC89,0x0083,0xEC88,0xEC87,0x0089,0x0085,0x0083,0xF7B0,0xEC86, 0x0083,0xEC85,0xEC84,0x0085,0x0083,0xEC83,0xEC82,0x0083,0xB0D0,0xEC81,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083, 0xD1A5,0xBDF9,0x0083,0xEC80,0xEC7E,0x0085,0x0083,0xEC7D,0xEC7C,0x0083,0xEC7B,0xEC7A,0x0089,0x0085,0x0083,0xEC79, 0xEC78,0x0083,0xEC77,0xB8EF,0x0085,0x0083,0xEC76,0xEC75,0x0083,0xEC74,0xD8CC,0x0091,0x0089,0x0085,0x0083,0xEC73, 0xEC72,0x0083,0xC3E6,0xC3D2,0x0085,0x0083,0xBFBF,0xEC71,0x0083,0xB7C7,0xEC70,0x0089,0x0085,0x0083,0xEC6F,0xB5E5, 0x0083,0xEC6E,0xBEB2,0x0085,0x0083,0xEC6D,0xEC6C,0x0083,0xBEB8,0xEC6B,0x00A1,0x0091,0x0089,0x0085,0x0083,0xEC6A, 0xF6A6,0x0083,0xC7E0,0xEC69,0x0085,0x0083,0xEC68,0xEC67,0x0083,0xEC66,0xEC65,0x0089,0x0085,0x0083,0xEC64,0xEC63, 0x0083,0xEC62,0xEC61,0x0085,0x0083,0xEC60,0xEC5F,0x0083,0xEC5E,0xEC5D,0x0091,0x0089,0x0085,0x0083,0xEC5C,0xEC5B, 0x0083,0xEC5A,0xEC59,0x0085,0x0083,0xEC58,0xEC57,0x0083,0xF6B2,0xEC56,0x0089,0x0085,0x0083,0xEC55,0xEC54,0x0083, 0xEC53,0xC5F9,0x0085,0x0083,0xB0D4,0xEC52,0x0083,0xEC51,0xEC50,0x017F,0x00FF,0x00BF,0x009F,0x008F,0x0087,0x0083, 0xEC4F,0x0083,0xEC4E,0xC2B6,0x0085,0x0083,0xEC4D,0xF6B1,0x0083,0xEC4C,0xEC4B,0x0089,0x0085,0x0083,0xF6B0,0xEC4A, 0x0083,0xEC49,0xF6AF,0x0085,0x0083,0xEC48,0xEC47,0x0083,0xEC46,0xEC45,0x0091,0x0089,0x0085,0x0083,0xEC44,0xEC43, 0x0083,0xEC42,0xEC41,0x0085,0x0083,0xEC40,0xEBA0,0x0083,0xEB9F,0xCFBC,0x0089,0x0085,0x0083,0xEB9E,0xCBAA,0x0083, 0xEB9D,0xEB9C,0x0085,0x0083,0xEB9B,0xEB9A,0x0083,0xEB99,0xC1D8,0x00A1,0x0091,0x0089,0x0085,0x0083,0xEB98,0xEB97, 0x0083,0xC4DE,0xEB96,0x0085,0x0083,0xEB95,0xEB94,0x0083,0xF6AD,0xF6AE,0x0089,0x0085,0x0083,0xBBF4,0xEB93,0x0083, 0xEB92,0xEB91,0x0085,0x0083,0xC3B9,0xF6AC,0x0083,0xD5F0,0xF6AA,0x0091,0x0089,0x0085,0x0083,0xEB90,0xCFF6,0x0083, 0xEB8F,0xEB8E,0x0085,0x0083,0xF6AB,0xD0E8,0x0083,0xEB8D,0xCEED,0x0089,0x0085,0x0083,0xEB8C,0xEB8B,0x0083,0xEB8A, 0xEB89,0x0085,0x0083,0xB1A2,0xEB88,0x0083,0xC0D7,0xC1E3,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xEB87,0xEB86, 0x0083,0xF6A8,0xEB85,0x0085,0x0083,0xEB84,0xEB83,0x0083,0xF6A9,0xEB82,0x0089,0x0085,0x0083,0xEB81,0xEB80,0x0083, 0xEB7E,0xD1A9,0x0085,0x0083,0xF6A7,0xD3EA,0x0083,0xEB7D,0xEB7C,0x0091,0x0089,0x0085,0x0083,0xEB7B,0xEB7A,0x0083, 0xEB79,0xEB78,0x0085,0x0083,0xEB77,0xF6C5,0x0083,0xEB76,0xEB75,0x0089,0x0085,0x0083,0xEB74,0xEB73,0x0083,0xEB72, 0xEB71,0x0085,0x0083,0xEB70,0xEB6F,0x0083,0xEB6E,0xEB6D,0x00A1,0x0091,0x0089,0x0085,0x0083,0xB5F1,0xEB6C,0x0083, 0xEB6B,0xF6C3,0x0085,0x0083,0xEB6A,0xEB69,0x0083,0xB3FB,0xF6C2,0x0089,0x0085,0x0083,0xD3BA,0xB4C6,0x0083,0xEB68, 0xEB67,0x0085,0x0083,0xEFF4,0xEB66,0x0083,0xB9CD,0xBCAF,0x0091,0x0089,0x0085,0x0083,0xD1C5,0xD0DB,0x0083,0xEB65, 0xEB64,0x0085,0x0083,0xD1E3,0xC8B8,0x0083,0xEB63,0xC4D1,0x0089,0x0085,0x0083,0xF6C1,0xF6C0,0x0083,0xEB62,0xEB61, 0x0085,0x0083,0xF6BF,0xEB60,0x0083,0xEB5F,0xC1A5,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xEB5E,0xEB5D, 0x0083,0xE3C4,0xEB5C,0x0085,0x0083,0xEB5B,0xDAF4,0x0083,0xEB5A,0xEB59,0x0089,0x0085,0x0083,0xEB58,0xEB57,0x0083, 0xEB56,0xEB55,0x0085,0x0083,0xEB54,0xEB53,0x0083,0xCBED,0xEB52,0x0091,0x0089,0x0085,0x0083,0xEB51,0xEB50,0x0083, 0xEB4F,0xEB4E,0x0085,0x0083,0xEB4D,0xEB4C,0x0083,0xEB4B,0xEB4A,0x0089,0x0085,0x0083,0xEB49,0xD5CF,0x0083,0xEB48, 0xEB47,0x0085,0x0083,0xCFB6,0xB0AF,0x0083,0xDAF3,0xEB46,0x00A1,0x0091,0x0089,0x0085,0x0083,0xEB45,0xB8F4,0x0083, 0xEB44,0xEB43,0x0085,0x0083,0xEB42,0xD2FE,0x0083,0xCBE6,0xEB41,0x0089,0x0085,0x0083,0xDAF2,0xEB40,0x0083,0xCBE5, 0xEAA0,0x0085,0x0083,0xEA9F,0xDAF1,0x0083,0xEA9E,0xC2A1,0x0091,0x0089,0x0085,0x0083,0xD3E7,0xEA9D,0x0083,0xEA9C, 0xEA9B,0x0085,0x0083,0xEA9A,0xEA99,0x0083,0xEA98,0xEA97,0x0089,0x0085,0x0083,0xEA96,0xEA95,0x0083,0xEA94,0xEA93, 0x0085,0x0083,0xEA92,0xEA91,0x0083,0xCFDD,0xCCD5,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xC1EA,0xDAF0,0x0083, 0xEA90,0xDAEF,0x0085,0x0083,0xEA8F,0xEA8E,0x0083,0xEA8D,0xEA8C,0x0089,0x0085,0x0083,0xEA8B,0xDAEE,0x0083,0xEA8A, 0xC5E3,0x0085,0x0083,0xCFD5,0xD4C9,0x0083,0xDAED,0xEA89,0x0091,0x0089,0x0085,0x0083,0xEA88,0xB3FD,0x0083,0xEA87, 0xD4BA,0x0085,0x0083,0xB6B8,0xEA86,0x0083,0xDAEC,0xEA85,0x0089,0x0085,0x0083,0xEA84,0xEA83,0x0083,0xB1DD,0xEA82, 0x0085,0x0083,0xEA81,0xEA80,0x0083,0xEA7E,0xEA7D,0x00A1,0x0091,0x0089,0x0085,0x0083,0xC9C2,0xDAEB,0x0083,0xEA7C, 0xEA7B,0x0085,0x0083,0xEA7A,0xCFDE,0x0083,0xEA79,0xEA78,0x0089,0x0085,0x0083,0xBDB5,0xC4B0,0x0083,0xC2AA,0xEA77, 0x0085,0x0083,0xDAEA,0xB3C2,0x0083,0xC2A4,0xC2BD,0x0091,0x0089,0x0085,0x0083,0xBCCA,0xB8BD,0x0083,0xEA76,0xDAE9, 0x0085,0x0083,0xEA75,0xCDD3,0x0083,0xB0A2,0xEA74,0x0089,0x0085,0x0083,0xDAE7,0xDAE8,0x0083,0xD7E8,0xEA73,0x0085, 0x0083,0xEA72,0xEA71,0x0083,0xEA70,0xBDD7,0x027F,0x017F,0x00FF,0x00BF,0x009F,0x008F,0x0087,0x0083,0xD5F3,0x0083, 0xD2F5,0xD1F4,0x0085,0x0083,0xB7C0,0xDAE5,0x0083,0xEA6F,0xEA6E,0x0089,0x0085,0x0083,0xC8EE,0xEA6D,0x0083,0xEA6C, 0xEA6B,0x0085,0x0083,0xDAE6,0xEA6A,0x0083,0xEA69,0xEA68,0x0091,0x0089,0x0085,0x0083,0xEA67,0xEA66,0x0083,0xEA65, 0xEA64,0x0085,0x0083,0xDAE3,0xDAE4,0x0083,0xEA63,0xB6D3,0x0089,0x0085,0x0083,0xEA62,0xDAE2,0x0083,0xB8B7,0xEA61, 0x0085,0x0083,0xE3DB,0xE3DA,0x0083,0xEA60,0xE3D9,0x00A1,0x0091,0x0089,0x0085,0x0083,0xE3D8,0xE3D7,0x0083,0xC0AB, 0xEA5F,0x0085,0x0083,0xE3D6,0xC0BB,0x0083,0xB2FB,0xE3D5,0x0089,0x0085,0x0083,0xD1D6,0xE3D4,0x0083,0xE3D3,0xE3D2, 0x0085,0x0083,0xE3D1,0xD1CB,0x0083,0xE3D0,0xEA5E,0x0091,0x0089,0x0085,0x0083,0xE3CF,0xD4C4,0x0083,0xE3CE,0xE3CD, 0x0085,0x0083,0xBAD2,0xB8F3,0x0083,0xB7A7,0xEA5D,0x0089,0x0085,0x0083,0xE3CC,0xC3F6,0x0083,0xE3CB,0xCEC5,0x0085, 0x0083,0xB9EB,0xC4D6,0x0083,0xD5A2,0xC3C6,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xE3CA,0xE3C9,0x0083,0xBCE4, 0xE3C8,0x0085,0x0083,0xCFD0,0xE3C7,0x0083,0xC8F2,0xB4B3,0x0089,0x0085,0x0083,0xCECA,0xB1D5,0x0083,0xEA5C,0xE3C6, 0x0085,0x0083,0xC9C1,0xE3C5,0x0083,0xC3C5,0xEA5B,0x0091,0x0089,0x0085,0x0083,0xEA5A,0xEA59,0x0083,0xEA58,0xEA57, 0x0085,0x0083,0xEA56,0xEA55,0x0083,0xEA54,0xEA53,0x0089,0x0085,0x0083,0xEA52,0xEA51,0x0083,0xEA50,0xEA4F,0x0085, 0x0083,0xEA4E,0xEA4D,0x0083,0xEA4C,0xEA4B,0x00A1,0x0091,0x0089,0x0085,0x0083,0xEA4A,0xEA49,0x0083,0xEA48,0xEA47, 0x0085,0x0083,0xEA46,0xEA45,0x0083,0xEA44,0xEA43,0x0089,0x0085,0x0083,0xEA42,0xEA41,0x0083,0xEA40,0xE9A0,0x0085, 0x0083,0xE99F,0xE99E,0x0083,0xE99D,0xE99C,0x0091,0x0089,0x0085,0x0083,0xE99B,0xE99A,0x0083,0xE999,0xE998,0x0085, 0x0083,0xE997,0xE996,0x0083,0xE995,0xE994,0x0089,0x0085,0x0083,0xE993,0xE992,0x0083,0xE991,0xE990,0x0085,0x0083, 0xE98F,0xE98E,0x0083,0xE98D,0xE98C,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xE98B,0xE98A,0x0083,0xE989, 0xE988,0x0085,0x0083,0xE987,0xE986,0x0083,0xE985,0xE984,0x0089,0x0085,0x0083,0xE983,0xE982,0x0083,0xE981,0xE980, 0x0085,0x0083,0xE97E,0xE97D,0x0083,0xE97C,0xE97B,0x0091,0x0089,0x0085,0x0083,0xE97A,0xE979,0x0083,0xE978,0xE977, 0x0085,0x0083,0xE976,0xE975,0x0083,0xE974,0xE973,0x0089,0x0085,0x0083,0xE972,0xE971,0x0083,0xE970,0xE96F,0x0085, 0x0083,0xE96E,0xE96D,0x0083,0xE96C,0xE96B,0x00A1,0x0091,0x0089,0x0085,0x0083,0xE96A,0xE969,0x0083,0xE968,0xE967, 0x0085,0x0083,0xE966,0xE965,0x0083,0xE964,0xE963,0x0089,0x0085,0x0083,0xE962,0xE961,0x0083,0xE960,0xE95F,0x0085, 0x0083,0xE95E,0xE95D,0x0083,0xE95C,0xE95B,0x0091,0x0089,0x0085,0x0083,0xE95A,0xE959,0x0083,0xE958,0xE957,0x0085, 0x0083,0xE956,0xE955,0x0083,0xE954,0xB3A4,0x0089,0x0085,0x0083,0xE953,0xE952,0x0083,0xE951,0xE950,0x0085,0x0083, 0xE94F,0xE94E,0x0083,0xE94D,0xE94C,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xCFE2,0xE94B,0x0083,0xE94A,0xEFF0, 0x0085,0x0083,0xEFEF,0xEFEE,0x0083,0xC1AD,0xEFED,0x0089,0x0085,0x0083,0xE949,0xC0D8,0x0083,0xEFEC,0xEFEB,0x0085, 0x0083,0xEFEA,0xEFE9,0x0083,0xEFE8,0xEFE7,0x0091,0x0089,0x0085,0x0083,0xEFE6,0xEFE5,0x0083,0xEFE4,0xC1CD,0x0085, 0x0083,0xEFE3,0xEFE2,0x0083,0xE948,0xEFE0,0x0089,0x0085,0x0083,0xEFDF,0xEFE1,0x0083,0xBEB5,0xEFDE,0x0085,0x0083, 0xE947,0xEFDD,0x0083,0xEFDC,0xEFDB,0x00A1,0x0091,0x0089,0x0085,0x0083,0xEFDA,0xE946,0x0083,0xEFD9,0xEFD8,0x0085, 0x0083,0xEFD7,0xB0F7,0x0083,0xB8E4,0xEFD6,0x0089,0x0085,0x0083,0xEFD5,0xC4F8,0x0083,0xEFD4,0xE945,0x0085,0x0083, 0xC4F7,0xEFD3,0x0083,0xE944,0xD5F2,0x0091,0x0089,0x0085,0x0083,0xEFD2,0xEFD1,0x0083,0xEFD0,0xE943,0x0085,0x0083, 0xEFCE,0xC3BE,0x0083,0xB6C6,0xEFCD,0x0089,0x0085,0x0083,0xEFCC,0xE942,0x0083,0xEFCB,0xB6CD,0x0085,0x0083,0xEFF1, 0xC7C2,0x0083,0xEFCA,0xEFC9,0x0181,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xEFC8,0xEFCF,0x0083,0xEFC7, 0xE941,0x0085,0x0083,0xEFC6,0xEFC5,0x0083,0xC3CC,0xBEE2,0x0089,0x0085,0x0083,0xBCFC,0xB6A7,0x0083,0xEFC4,0xEFC2, 0x0085,0x0083,0xEFC1,0xEFC3,0x0083,0xCFC7,0xE940,0x0091,0x0089,0x0085,0x0083,0xBDF5,0xD7B6,0x0083,0xB4B8,0xC2E0, 0x0085,0x0083,0xEFC0,0xCEFD,0x0083,0xE8A0,0xEFBF,0x0089,0x0085,0x0083,0xEFBE,0xEFBD,0x0083,0xE89F,0xEFBC,0x0085, 0x0083,0xC3AA,0xB4ED,0x0083,0xEFBB,0xD5E0,0x00A1,0x0091,0x0089,0x0085,0x0083,0xEFBA,0xEFB9,0x0083,0xEFB8,0xEFB7, 0x0085,0x0083,0xEFB6,0xCCE0,0x0083,0xC8F1,0xEFB5,0x0089,0x0085,0x0083,0xEFB4,0xEFB3,0x0083,0xD0BF,0xB7E6,0x0085, 0x0083,0xEFB2,0xEFB1,0x0083,0xD0E2,0xEFB0,0x0091,0x0089,0x0085,0x0083,0xEFAF,0xB9F8,0x0083,0xB3FA,0xEFAD,0x0085, 0x0083,0xEFAE,0xCBF8,0x0083,0xCFFA,0xEFAC,0x0089,0x0085,0x0083,0xC1B4,0xEFAB,0x0083,0xEFAA,0xE89E,0x0085,0x0083, 0xC6CC,0xEFA9,0x0083,0xD6FD,0xEFA8,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xD2F8,0xEFA7,0x0083,0xEFA6,0xEFA5, 0x0085,0x0083,0xB2F9,0xD2BF,0x0083,0xBDC2,0xEFA4,0x0089,0x0085,0x0083,0xEFA3,0xC3FA,0x0083,0xB8F5,0xEFA2,0x0085, 0x0083,0xEEFE,0xEFA1,0x0083,0xEEFD,0xEEFC,0x0091,0x0089,0x0085,0x0083,0xE89D,0xEEFB,0x0083,0xEEFA,0xCFB3,0x0085, 0x0083,0xEEF9,0xD5A1,0x0083,0xEEF8,0xEEF7,0x0089,0x0085,0x0083,0xEEF6,0xC2C1,0x0083,0xCDAD,0xEEF5,0x0085,0x0083, 0xE89C,0xEEF3,0x0083,0xEEF4,0xEEF2,0x00A1,0x0091,0x0089,0x0085,0x0083,0xEEF1,0xEEF0,0x0083,0xE89B,0xE89A,0x0085, 0x0083,0xEEEF,0xEEEE,0x0083,0xEEED,0xE899,0x0089,0x0085,0x0083,0xEEEC,0xEEEB,0x0083,0xEEEA,0xEEE9,0x0085,0x0083, 0xEEE8,0xEEE7,0x0083,0xEEE6,0xE898,0x0091,0x0089,0x0085,0x0083,0xC3AD,0xC7A6,0x0083,0xEEE5,0xC1E5,0x0085,0x0083, 0xB2AC,0xCCFA,0x0083,0xD3CB,0xEEE4,0x0089,0x0085,0x0083,0xBCD8,0xEEE3,0x0083,0xEEE2,0xD7EA,0x0085,0x0083,0xEEE1, 0xEEE0,0x0083,0xEEDF,0xEEDE,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xEEDD,0xB2A7,0x0083,0xEEDC,0xC7AF, 0x0085,0x0083,0xEEDB,0xC7AE,0x0083,0xEEDA,0xEED9,0x0089,0x0085,0x0083,0xC5A5,0xEED7,0x0083,0xEED8,0xEED5,0x0085, 0x0083,0xEED6,0xB9B3,0x0083,0xCED9,0xBEFB,0x0091,0x0089,0x0085,0x0083,0xC7D5,0xD4BF,0x0083,0xEED4,0xEED3,0x0085, 0x0083,0xB8D6,0xB1B5,0x0083,0xC4C6,0xD6D3,0x0089,0x0085,0x0083,0xB3AE,0xB6DB,0x0083,0xEED2,0xEED1,0x0085,0x0083, 0xEED0,0xB8C6,0x0083,0xE897,0xEECE,0x00A1,0x0091,0x0089,0x0085,0x0083,0xE896,0xEECF,0x0083,0xEECD,0xB5F6,0x0085, 0x0083,0xB7B0,0xE895,0x0083,0xEECC,0xEECB,0x0089,0x0085,0x0083,0xC7A5,0xEECA,0x0083,0xEEC9,0xEEC7,0x0085,0x0083, 0xEEC8,0xB6A4,0x0083,0xD5EB,0xEEC6,0x0091,0x0089,0x0085,0x0083,0xEEC5,0xEEC4,0x0083,0xE894,0xE893,0x0085,0x0083, 0xE892,0xE891,0x0083,0xE890,0xE88F,0x0089,0x0085,0x0083,0xE88E,0xE88D,0x0083,0xE88C,0xE88B,0x0085,0x0083,0xE88A, 0xE889,0x0083,0xE888,0xE887,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xE886,0xE885,0x0083,0xE884,0xE883,0x0085, 0x0083,0xE882,0xE881,0x0083,0xE880,0xE87E,0x0089,0x0085,0x0083,0xE87D,0xE87C,0x0083,0xE87B,0xF6CE,0x0085,0x0083, 0xE87A,0xE879,0x0083,0xE878,0xE877,0x0091,0x0089,0x0085,0x0083,0xE876,0xE875,0x0083,0xE874,0xE873,0x0085,0x0083, 0xE872,0xE871,0x0083,0xE870,0xE86F,0x0089,0x0085,0x0083,0xE86E,0xE86D,0x0083,0xE86C,0xE86B,0x0085,0x0083,0xE86A, 0xE869,0x0083,0xE868,0xE867,0x00A1,0x0091,0x0089,0x0085,0x0083,0xE866,0xE865,0x0083,0xE864,0xE863,0x0085,0x0083, 0xE862,0xE861,0x0083,0xE860,0xE85F,0x0089,0x0085,0x0083,0xE85E,0xE85D,0x0083,0xE85C,0xE85B,0x0085,0x0083,0xE85A, 0xE859,0x0083,0xE858,0xE857,0x0091,0x0089,0x0085,0x0083,0xE856,0xE855,0x0083,0xE854,0xE853,0x0085,0x0083,0xE852, 0xE851,0x0083,0xE850,0xE84F,0x0089,0x0085,0x0083,0xF6CD,0xE84E,0x0083,0xE84D,0xE84C,0x0085,0x0083,0xE84B,0xE84A, 0x0083,0xE849,0xE848,0x047D,0x027F,0x017F,0x00FF,0x00BF,0x009F,0x008F,0x0087,0x0083,0xE847,0x0083,0xE846,0xE845, 0x0085,0x0083,0xE844,0xE843,0x0083,0xE842,0xE841,0x0089,0x0085,0x0083,0xE840,0xE7A0,0x0083,0xE79F,0xE79E,0x0085, 0x0083,0xE79D,0xE79C,0x0083,0xE79B,0xE79A,0x0091,0x0089,0x0085,0x0083,0xE799,0xE798,0x0083,0xE797,0xE796,0x0085, 0x0083,0xE795,0xE794,0x0083,0xE793,0xE792,0x0089,0x0085,0x0083,0xE791,0xE790,0x0083,0xE78F,0xE78E,0x0085,0x0083, 0xE78D,0xE78C,0x0083,0xE78B,0xE78A,0x00A1,0x0091,0x0089,0x0085,0x0083,0xE789,0xE788,0x0083,0xE787,0xE786,0x0085, 0x0083,0xE785,0xE784,0x0083,0xE783,0xE782,0x0089,0x0085,0x0083,0xE781,0xE780,0x0083,0xE77E,0xE77D,0x0085,0x0083, 0xE77C,0xE77B,0x0083,0xE77A,0xE779,0x0091,0x0089,0x0085,0x0083,0xE778,0xE777,0x0083,0xE776,0xE775,0x0085,0x0083, 0xE774,0xE773,0x0083,0xE772,0xE771,0x0089,0x0085,0x0083,0xE770,0xE76F,0x0083,0xE76E,0xE76D,0x0085,0x0083,0xE76C, 0xE76B,0x0083,0xE76A,0xE769,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xE768,0xE767,0x0083,0xE766,0xE765,0x0085, 0x0083,0xE764,0xE763,0x0083,0xE762,0xE761,0x0089,0x0085,0x0083,0xE760,0xE75F,0x0083,0xE75E,0xE75D,0x0085,0x0083, 0xE75C,0xE75B,0x0083,0xE75A,0xE759,0x0091,0x0089,0x0085,0x0083,0xE758,0xE757,0x0083,0xE756,0xE755,0x0085,0x0083, 0xE754,0xE753,0x0083,0xE752,0xE751,0x0089,0x0085,0x0083,0xE750,0xE74F,0x0083,0xE74E,0xE74D,0x0085,0x0083,0xE74C, 0xE74B,0x0083,0xE74A,0xE749,0x00A1,0x0091,0x0089,0x0085,0x0083,0xE748,0xF7E9,0x0083,0xE747,0xE746,0x0085,0x0083, 0xE745,0xE744,0x0083,0xE743,0xE742,0x0089,0x0085,0x0083,0xE741,0xE740,0x0083,0xE6A0,0xE69F,0x0085,0x0083,0xE69E, 0xF6CB,0x0083,0xE69D,0xE69C,0x0091,0x0089,0x0085,0x0083,0xE69B,0xE69A,0x0083,0xE699,0xE698,0x0085,0x0083,0xE697, 0xE696,0x0083,0xE695,0xE694,0x0089,0x0085,0x0083,0xE693,0xE692,0x0083,0xE691,0xE690,0x0085,0x0083,0xE68F,0xE68E, 0x0083,0xE68D,0xE68C,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xE68B,0xE68A,0x0083,0xE689,0xE688,0x0085, 0x0083,0xE687,0xE686,0x0083,0xE685,0xE684,0x0089,0x0085,0x0083,0xE683,0xE682,0x0083,0xE681,0xE680,0x0085,0x0083, 0xE67E,0xE67D,0x0083,0xE67C,0xE67B,0x0091,0x0089,0x0085,0x0083,0xE67A,0xE679,0x0083,0xE678,0xE677,0x0085,0x0083, 0xE676,0xE675,0x0083,0xE674,0xE673,0x0089,0x0085,0x0083,0xE672,0xE671,0x0083,0xE670,0xE66F,0x0085,0x0083,0xE66E, 0xE66D,0x0083,0xE66C,0xE66B,0x00A1,0x0091,0x0089,0x0085,0x0083,0xE66A,0xE669,0x0083,0xE668,0xE667,0x0085,0x0083, 0xE666,0xE665,0x0083,0xE664,0xE663,0x0089,0x0085,0x0083,0xF6CC,0xE662,0x0083,0xE661,0xE660,0x0085,0x0083,0xE65F, 0xE65E,0x0083,0xE65D,0xE65C,0x0091,0x0089,0x0085,0x0083,0xE65B,0xE65A,0x0083,0xE659,0xE658,0x0085,0x0083,0xE657, 0xE656,0x0083,0xE655,0xE654,0x0089,0x0085,0x0083,0xE653,0xE652,0x0083,0xE651,0xE650,0x0085,0x0083,0xE64F,0xE64E, 0x0083,0xE64D,0xE64C,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xE64B,0xE64A,0x0083,0xE649,0xE648,0x0085,0x0083, 0xE647,0xE646,0x0083,0xE645,0xE644,0x0089,0x0085,0x0083,0xE643,0xE642,0x0083,0xE641,0xE640,0x0085,0x0083,0xE5A0, 0xF6CA,0x0083,0xE59F,0xE59E,0x0091,0x0089,0x0085,0x0083,0xE59D,0xE59C,0x0083,0xE59B,0xE59A,0x0085,0x0083,0xE599, 0xE598,0x0083,0xE597,0xE596,0x0089,0x0085,0x0083,0xE595,0xE594,0x0083,0xE593,0xE592,0x0085,0x0083,0xE591,0xE590, 0x0083,0xE58F,0xE58E,0x00A1,0x0091,0x0089,0x0085,0x0083,0xE58D,0xE58C,0x0083,0xE58B,0xE58A,0x0085,0x0083,0xE589, 0xE588,0x0083,0xE587,0xE586,0x0089,0x0085,0x0083,0xE585,0xE584,0x0083,0xE583,0xE582,0x0085,0x0083,0xE581,0xE580, 0x0083,0xE57E,0xE57D,0x0091,0x0089,0x0085,0x0083,0xE57C,0xE57B,0x0083,0xE57A,0xE579,0x0085,0x0083,0xE578,0xE577, 0x0083,0xE576,0xE575,0x0089,0x0085,0x0083,0xE574,0xF6C9,0x0083,0xE573,0xE572,0x0085,0x0083,0xE571,0xE570,0x0083, 0xE56F,0xE56E,0x017F,0x00FF,0x00BF,0x009F,0x008F,0x0087,0x0083,0xE56D,0x0083,0xE56C,0xE56B,0x0085,0x0083,0xE56A, 0xE569,0x0083,0xE568,0xE567,0x0089,0x0085,0x0083,0xE566,0xE565,0x0083,0xE564,0xE563,0x0085,0x0083,0xE562,0xE561, 0x0083,0xE560,0xE55F,0x0091,0x0089,0x0085,0x0083,0xE55E,0xE55D,0x0083,0xE55C,0xE55B,0x0085,0x0083,0xE55A,0xE559, 0x0083,0xE558,0xE557,0x0089,0x0085,0x0083,0xE556,0xE555,0x0083,0xE554,0xE553,0x0085,0x0083,0xE552,0xE551,0x0083, 0xE550,0xE54F,0x00A1,0x0091,0x0089,0x0085,0x0083,0xE54E,0xE54D,0x0083,0xE54C,0xE54B,0x0085,0x0083,0xE54A,0xE549, 0x0083,0xE548,0xE547,0x0089,0x0085,0x0083,0xE546,0xE545,0x0083,0xE544,0xE543,0x0085,0x0083,0xE542,0xE541,0x0083, 0xE540,0xE4A0,0x0091,0x0089,0x0085,0x0083,0xE49F,0xE49E,0x0083,0xE49D,0xE49C,0x0085,0x0083,0xE49B,0xE49A,0x0083, 0xE499,0xE498,0x0089,0x0085,0x0083,0xE497,0xE496,0x0083,0xE495,0xE494,0x0085,0x0083,0xE493,0xE492,0x0083,0xE491, 0xE490,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xE48F,0xE48E,0x0083,0xE48D,0xE48C,0x0085,0x0083,0xE48B,0xE48A, 0x0083,0xE489,0xE488,0x0089,0x0085,0x0083,0xE487,0xE486,0x0083,0xE485,0xE484,0x0085,0x0083,0xE483,0xE482,0x0083, 0xE481,0xE480,0x0091,0x0089,0x0085,0x0083,0xE47E,0xE47D,0x0083,0xE47C,0xE47B,0x0085,0x0083,0xE47A,0xE479,0x0083, 0xE478,0xE477,0x0089,0x0085,0x0083,0xE476,0xE475,0x0083,0xE474,0xE473,0x0085,0x0083,0xE472,0xE471,0x0083,0xE470, 0xE46F,0x00A1,0x0091,0x0089,0x0085,0x0083,0xE46E,0xE46D,0x0083,0xE46C,0xE46B,0x0085,0x0083,0xE46A,0xE469,0x0083, 0xE468,0xE467,0x0089,0x0085,0x0083,0xE466,0xE465,0x0083,0xE464,0xE463,0x0085,0x0083,0xE462,0xE461,0x0083,0xE460, 0xE45F,0x0091,0x0089,0x0085,0x0083,0xF6C8,0xE45E,0x0083,0xE45D,0xE45C,0x0085,0x0083,0xE45B,0xE45A,0x0083,0xE459, 0xE458,0x0089,0x0085,0x0083,0xE457,0xE456,0x0083,0xE455,0xE454,0x0085,0x0083,0xE453,0xE452,0x0083,0xE451,0xE450, 0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xE44F,0xE44E,0x0083,0xE44D,0xE44C,0x0085,0x0083,0xE44B,0xE44A, 0x0083,0xE449,0xE448,0x0089,0x0085,0x0083,0xE447,0xE446,0x0083,0xF6C7,0xE445,0x0085,0x0083,0xE444,0xE443,0x0083, 0xE442,0xE441,0x0091,0x0089,0x0085,0x0083,0xE440,0xE3A0,0x0083,0xE39F,0xE39E,0x0085,0x0083,0xE39D,0xE39C,0x0083, 0xE39B,0xE39A,0x0089,0x0085,0x0083,0xE399,0xE398,0x0083,0xE397,0xE396,0x0085,0x0083,0xE395,0xE394,0x0083,0xE393, 0xE392,0x00A1,0x0091,0x0089,0x0085,0x0083,0xE391,0xE390,0x0083,0xE38F,0xE38E,0x0085,0x0083,0xE38D,0xE38C,0x0083, 0xE38B,0xE38A,0x0089,0x0085,0x0083,0xE389,0xE388,0x0083,0xF6C6,0xE387,0x0085,0x0083,0xE386,0xE385,0x0083,0xE384, 0xE383,0x0091,0x0089,0x0085,0x0083,0xE382,0xE381,0x0083,0xE380,0xE37E,0x0085,0x0083,0xE37D,0xE37C,0x0083,0xE37B, 0xE37A,0x0089,0x0085,0x0083,0xE379,0xE378,0x0083,0xE377,0xE376,0x0085,0x0083,0xE375,0xE374,0x0083,0xE373,0xE372, 0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xE371,0xE370,0x0083,0xE36F,0xE36E,0x0085,0x0083,0xBCF8,0xE36D,0x0083, 0xE36C,0xE36B,0x0089,0x0085,0x0083,0xE36A,0xE369,0x0083,0xE368,0xE367,0x0085,0x0083,0xE366,0xE365,0x0083,0xE364, 0xE363,0x0091,0x0089,0x0085,0x0083,0xE362,0xE361,0x0083,0xE360,0xE35F,0x0085,0x0083,0xE35E,0xE35D,0x0083,0xE35C, 0xE35B,0x0089,0x0085,0x0083,0xE35A,0xE359,0x0083,0xE358,0xE357,0x0085,0x0083,0xE356,0xE355,0x0083,0xE354,0xE353, 0x00A1,0x0091,0x0089,0x0085,0x0083,0xE352,0xE351,0x0083,0xE350,0xE34F,0x0085,0x0083,0xE34E,0xE34D,0x0083,0xE34C, 0xE34B,0x0089,0x0085,0x0083,0xE34A,0xE349,0x0083,0xE348,0xE347,0x0085,0x0083,0xE346,0xE345,0x0083,0xE344,0xE343, 0x0091,0x0089,0x0085,0x0083,0xE342,0xE341,0x0083,0xE340,0xE2A0,0x0085,0x0083,0xE29F,0xE29E,0x0083,0xE29D,0xE29C, 0x0089,0x0085,0x0083,0xE29B,0xE29A,0x0083,0xE299,0xE298,0x0085,0x0083,0xE297,0xE296,0x0083,0xE295,0xE294,0x027F, 0x017F,0x00FF,0x00BF,0x009F,0x008F,0x0087,0x0083,0xE293,0x0083,0xE292,0xE291,0x0085,0x0083,0xE290,0xE28F,0x0083, 0xE28E,0xE28D,0x0089,0x0085,0x0083,0xE28C,0xE28B,0x0083,0xE28A,0xE289,0x0085,0x0083,0xE288,0xE287,0x0083,0xE286, 0xE285,0x0091,0x0089,0x0085,0x0083,0xE284,0xE283,0x0083,0xE282,0xE281,0x0085,0x0083,0xE280,0xE27E,0x0083,0xE27D, 0xE27C,0x0089,0x0085,0x0083,0xE27B,0xE27A,0x0083,0xE279,0xE278,0x0085,0x0083,0xE277,0xE276,0x0083,0xE275,0xE274, 0x00A1,0x0091,0x0089,0x0085,0x0083,0xE273,0xE272,0x0083,0xE271,0xE270,0x0085,0x0083,0xE26F,0xE26E,0x0083,0xE26D, 0xE26C,0x0089,0x0085,0x0083,0xE26B,0xE26A,0x0083,0xE269,0xE268,0x0085,0x0083,0xE267,0xE266,0x0083,0xE265,0xE264, 0x0091,0x0089,0x0085,0x0083,0xE263,0xE262,0x0083,0xE261,0xE260,0x0085,0x0083,0xE25F,0xE25E,0x0083,0xE25D,0xE25C, 0x0089,0x0085,0x0083,0xE25B,0xE25A,0x0083,0xE259,0xE258,0x0085,0x0083,0xE257,0xE256,0x0083,0xE255,0xE254,0x00C1, 0x00A1,0x0091,0x0089,0x0085,0x0083,0xE253,0xE252,0x0083,0xE251,0xE250,0x0085,0x0083,0xE24F,0xE24E,0x0083,0xE24D, 0xE24C,0x0089,0x0085,0x0083,0xE24B,0xE24A,0x0083,0xE249,0xE248,0x0085,0x0083,0xE247,0xE246,0x0083,0xE245,0xE244, 0x0091,0x0089,0x0085,0x0083,0xE243,0xE242,0x0083,0xE241,0xE240,0x0085,0x0083,0xE1A0,0xE19F,0x0083,0xE19E,0xE19D, 0x0089,0x0085,0x0083,0xE19C,0xE19B,0x0083,0xE19A,0xE199,0x0085,0x0083,0xE198,0xB8AA,0x0083,0xE197,0xE196,0x00A1, 0x0091,0x0089,0x0085,0x0083,0xE195,0xE194,0x0083,0xE193,0xE192,0x0085,0x0083,0xE191,0xE190,0x0083,0xE18F,0xE18E, 0x0089,0x0085,0x0083,0xBDF0,0xE18D,0x0083,0xC1BF,0xD2B0,0x0085,0x0083,0xD6D8,0xC0EF,0x0083,0xE18C,0xCACD,0x0091, 0x0089,0x0085,0x0083,0xD3D4,0xE18B,0x0083,0xB2C9,0xE18A,0x0085,0x0083,0xE189,0xE188,0x0083,0xE187,0xE186,0x0089, 0x0085,0x0083,0xE185,0xE184,0x0083,0xE183,0xE182,0x0085,0x0083,0xE181,0xE180,0x0083,0xE17E,0xF5B8,0x0101,0x00C1, 0x00A1,0x0091,0x0089,0x0085,0x0083,0xE17D,0xE17C,0x0083,0xE17B,0xE17A,0x0085,0x0083,0xF5B6,0xF5B7,0x0083,0xE179, 0xE178,0x0089,0x0085,0x0083,0xE177,0xE176,0x0083,0xF5B5,0xF5B4,0x0085,0x0083,0xF5B3,0xE175,0x0083,0xE174,0xF5B2, 0x0091,0x0089,0x0085,0x0083,0xE173,0xE172,0x0083,0xE171,0xE170,0x0085,0x0083,0xE16F,0xE16E,0x0083,0xF5B1,0xF5B0, 0x0089,0x0085,0x0083,0xE16D,0xE16C,0x0083,0xE16B,0xE16A,0x0085,0x0083,0xE169,0xE168,0x0083,0xC8A9,0xC3D1,0x00A1, 0x0091,0x0089,0x0085,0x0083,0xE167,0xE166,0x0083,0xE165,0xE164,0x0085,0x0083,0xE163,0xE162,0x0083,0xE161,0xD0D1, 0x0089,0x0085,0x0083,0xF5AF,0xF5AD,0x0083,0xE160,0xE15F,0x0085,0x0083,0xF5AE,0xF5AB,0x0083,0xB4D7,0xE15E,0x0091, 0x0089,0x0085,0x0083,0xD7ED,0xE15D,0x0083,0xB4BC,0xE15C,0x0085,0x0083,0xF5AC,0xE15B,0x0083,0xE15A,0xE159,0x0089, 0x0085,0x0083,0xE158,0xE157,0x0083,0xC4F0,0xF5A7,0x0085,0x0083,0xF5A6,0xE156,0x0083,0xE155,0xE154,0x00C1,0x00A1, 0x0091,0x0089,0x0085,0x0083,0xF5AA,0xCBE1,0x0083,0xBFE1,0xC3B8,0x0085,0x0083,0xBDCD,0xF5A9,0x0083,0xE153,0xF5A8, 0x0089,0x0085,0x0083,0xBDB4,0xF5A3,0x0083,0xF5A5,0xCDAA,0x0085,0x0083,0xE152,0xB3EA,0x0083,0xE151,0xC0D2,0x0091, 0x0089,0x0085,0x0083,0xF5A4,0xE150,0x0083,0xE14F,0xE14E,0x0085,0x0083,0xCBD6,0xF4FE,0x0083,0xBAA8,0xF5A1,0x0089, 0x0085,0x0083,0xF5A2,0xE14D,0x0083,0xE14C,0xCCAA,0x0085,0x0083,0xD4CD,0xE14B,0x0083,0xE14A,0xB7D3,0x00A1,0x0091, 0x0089,0x0085,0x0083,0xE149,0xE148,0x0083,0xD0EF,0xE147,0x0085,0x0083,0xE146,0xE145,0x0083,0xE144,0xBEC6,0x0089, 0x0085,0x0083,0xE143,0xF4FB,0x0083,0xF4FD,0xF4FC,0x0085,0x0083,0xC5E4,0xD7C3,0x0083,0xC7F5,0xF4FA,0x0091,0x0089, 0x0085,0x0083,0xD3CF,0xE142,0x0083,0xE141,0xDBBA,0x0085,0x0083,0xE140,0xE0A0,0x0083,0xDBB9,0xE09F,0x0089,0x0085, 0x0083,0xE09E,0xE09D,0x0083,0xE09C,0xE09B,0x0085,0x0083,0xE09A,0xE099,0x0083,0xE098,0xE097,0x0181,0x0101,0x00C1, 0x00A1,0x0091,0x0089,0x0085,0x0083,0xDBB8,0xE096,0x0083,0xE095,0xE094,0x0085,0x0083,0xE093,0xE092,0x0083,0xE091, 0xE090,0x0089,0x0085,0x0083,0xDBB6,0xE08F,0x0083,0xDBB7,0xE08E,0x0085,0x0083,0xE08D,0xE08C,0x0083,0xE08B,0xE08A, 0x0091,0x0089,0x0085,0x0083,0xE089,0xE088,0x0083,0xE087,0xE086,0x0085,0x0083,0xE085,0xE084,0x0083,0xDBB5,0xDBB3, 0x0089,0x0085,0x0083,0xE083,0xE082,0x0083,0xE081,0xDBB4,0x0085,0x0083,0xE080,0xE07E,0x0083,0xE07D,0xE07C,0x00A1, 0x0091,0x0089,0x0085,0x0083,0xB1C9,0xE07B,0x0083,0xE07A,0xE079,0x0085,0x0083,0xE078,0xE077,0x0083,0xE076,0xE075, 0x0089,0x0085,0x0083,0xE074,0xE073,0x0083,0xE072,0xE071,0x0085,0x0083,0xE070,0xE06F,0x0083,0xE06E,0xE06D,0x0091, 0x0089,0x0085,0x0083,0xE06C,0xE06B,0x0083,0xE06A,0xE069,0x0085,0x0083,0xE068,0xDBB2,0x0083,0xE067,0xB6F5,0x0089, 0x0085,0x0083,0xE066,0xE065,0x0083,0xE064,0xDBB1,0x0085,0x0083,0xB6BC,0xE063,0x0083,0xE062,0xE061,0x00C1,0x00A1, 0x0091,0x0089,0x0085,0x0083,0xE060,0xB5A6,0x0083,0xE05F,0xE05E,0x0085,0x0083,0xE05D,0xB3BB,0x0083,0xE05C,0xE05B, 0x0089,0x0085,0x0083,0xE05A,0xE059,0x0083,0xDBB0,0xE058,0x0085,0x0083,0xB9F9,0xE057,0x0083,0xDBAF,0xE056,0x0091, 0x0089,0x0085,0x0083,0xE055,0xB2BF,0x0083,0xD4C7,0xDBAA,0x0085,0x0083,0xE054,0xE053,0x0083,0xE052,0xDBAB,0x0089, 0x0085,0x0083,0xBFA4,0xE051,0x0083,0xE050,0xE04F,0x0085,0x0083,0xBAC2,0xDBAC,0x0083,0xDBAE,0xE04E,0x00A1,0x0091, 0x0089,0x0085,0x0083,0xE04D,0xE04C,0x0083,0xDBAD,0xE04B,0x0085,0x0083,0xE04A,0xE049,0x0083,0xDBA9,0xE048,0x0089, 0x0085,0x0083,0xD6A3,0xDBA6,0x0083,0xDBA3,0xC0C9,0x0085,0x0083,0xE047,0xE046,0x0083,0xE045,0xBDBC,0x0091,0x0089, 0x0085,0x0083,0xE044,0xE043,0x0083,0xDBA8,0xE042,0x0085,0x0083,0xDBA4,0xDBA7,0x0083,0xE041,0xE040,0x0089,0x0085, 0x0083,0xD3F4,0xDFA0,0x0083,0xDF9F,0xDBA5,0x0085,0x0083,0xDF9E,0xDF9D,0x0083,0xC1DA,0xDAFE,0x0101,0x00C1,0x00A1, 0x0091,0x0089,0x0085,0x0083,0xD7DE,0xDBA1,0x0083,0xDF9C,0xDAFD,0x0085,0x0083,0xC9DB,0xDAFB,0x0083,0xDAFC,0xDF9B, 0x0089,0x0085,0x0083,0xC7F1,0xDBA2,0x0083,0xBAAA,0xD3CA,0x0085,0x0083,0xDF9A,0xDAF9,0x0083,0xDF99,0xD0B0,0x0091, 0x0089,0x0085,0x0083,0xDF98,0xDF97,0x0083,0xDF96,0xB0EE,0x0085,0x0083,0xDF95,0xDF94,0x0083,0xC4C7,0xD0CF,0x0089, 0x0085,0x0083,0xDAFA,0xDF93,0x0083,0xDF92,0xDF91,0x0085,0x0083,0xDAF7,0xDF90,0x0083,0xDAF6,0xDF8F,0x00A1,0x0091, 0x0089,0x0085,0x0083,0xDAF8,0xDF8E,0x0083,0xDAF5,0xDF8D,0x0085,0x0083,0xE7DF,0xDF8C,0x0083,0xB5CB,0xDF8B,0x0089, 0x0085,0x0083,0xD2D8,0xDF8A,0x0083,0xDF89,0xDF88,0x0085,0x0083,0xDF87,0xDF86,0x0083,0xE5E5,0xDF85,0x0091,0x0089, 0x0085,0x0083,0xDF84,0xE5E3,0x0083,0xDF83,0xDF82,0x0085,0x0083,0xDF81,0xDF80,0x0083,0xE5E4,0xE5E2,0x0089,0x0085, 0x0083,0xDF7E,0xD1FB,0x0083,0xB1DC,0xDF7D,0x0085,0x0083,0xE5E1,0xDF7C,0x0083,0xDF7B,0xDF7A,0x00C1,0x00A1,0x0091, 0x0089,0x0085,0x0083,0xDF79,0xDF78,0x0083,0xDF77,0xDF76,0x0085,0x0083,0xD7F1,0xE5E0,0x0083,0xDF75,0xDF74,0x0089, 0x0085,0x0083,0xDF73,0xDF72,0x0083,0xDF71,0xD5DA,0x0085,0x0083,0xD4E2,0xDF70,0x0083,0xDF6F,0xDF6E,0x0091,0x0089, 0x0085,0x0083,0xDF6D,0xE5DB,0x0083,0xDF6C,0xDF6B,0x0085,0x0083,0xD2A3,0xDF6A,0x0083,0xC7B2,0xE5DD,0x0089,0x0085, 0x0083,0xDF69,0xDF68,0x0083,0xDF67,0xDF66,0x0085,0x0083,0xDF65,0xDF64,0x0083,0xE5DE,0xDF63,0x00A1,0x0091,0x0089, 0x0085,0x0083,0xDF62,0xE5DC,0x0083,0xD2C5,0xDF61,0x0085,0x0083,0xDF60,0xDF5F,0x0083,0xB5C0,0xE5D9,0x0089,0x0085, 0x0083,0xE5D8,0xE5DA,0x0083,0xB6F4,0xDF5E,0x0085,0x0083,0xB1E9,0xDF5D,0x0083,0xDF5C,0xDF5B,0x0091,0x0089,0x0085, 0x0083,0xDF5A,0xDF59,0x0083,0xD3F6,0xDF58,0x0085,0x0083,0xDF57,0xE5D7,0x0083,0xDF56,0xCBEC,0x0089,0x0085,0x0083, 0xB6DD,0xDF55,0x0083,0xDF54,0xD3E2,0x0085,0x0083,0xDF53,0xB1C6,0x0083,0xC2DF,0xDF52,0x1075,0x087B,0x047D,0x027F, 0x017F,0x00FF,0x00BF,0x009F,0x008F,0x0087,0x0083,0xDF51,0x0083,0xD2DD,0xDF50,0x0085,0x0083,0xE5D4,0xE5D3,0x0083, 0xDF4F,0xDF4E,0x0089,0x0085,0x0083,0xDF4D,0xDF4C,0x0083,0xDF4B,0xE5D6,0x0085,0x0083,0xB4FE,0xE5D5,0x0083,0xDF4A, 0xDF49,0x0091,0x0089,0x0085,0x0083,0xDF48,0xDF47,0x0083,0xDF46,0xDF45,0x0085,0x0083,0xE5CE,0xDF44,0x0083,0xDF43, 0xDF42,0x0089,0x0085,0x0083,0xB7EA,0xE5D2,0x0083,0xD4EC,0xCBD9,0x0085,0x0083,0xB3D1,0xCAC5,0x0083,0xDF41,0xB9E4, 0x00A1,0x0091,0x0089,0x0085,0x0083,0xCDA8,0xDF40,0x0083,0xDEA0,0xB6BA,0x0085,0x0083,0xE5D1,0xDE9F,0x0083,0xCDBE, 0xDE9E,0x0089,0x0085,0x0083,0xB5DD,0xE5CF,0x0083,0xD6F0,0xCDB8,0x0085,0x0083,0xDE9D,0xE5D0,0x0083,0xDE9C,0xE5CD, 0x0091,0x0089,0x0085,0x0083,0xD1B7,0xD1A1,0x0083,0xDE9B,0xDE9A,0x0085,0x0083,0xC4E6,0xE5CB,0x0083,0xE5CC,0xCCD3, 0x0089,0x0085,0x0083,0xCACA,0xCBCD,0x0083,0xCDCB,0xDE99,0x0085,0x0083,0xDE98,0xD7B7,0x0083,0xDE97,0xDE96,0x00C1, 0x00A1,0x0091,0x0089,0x0085,0x0083,0xDE95,0xBCA3,0x0083,0xB1C5,0xC3D4,0x0085,0x0083,0xDE94,0xDE93,0x0083,0xDE92, 0xE5C9,0x0089,0x0085,0x0083,0xDE91,0xDE90,0x0083,0xCAF6,0xDE8F,0x0085,0x0083,0xE5C5,0xB5FC,0x0083,0xDE8E,0xC6C8, 0x0091,0x0089,0x0085,0x0083,0xB5CF,0xE5C7,0x0083,0xE5CA,0xDE8D,0x0085,0x0083,0xE5C8,0xE5C4,0x0083,0xE5C6,0xDE8C, 0x0089,0x0085,0x0083,0xCCF6,0xDE8B,0x0083,0xDE8A,0xB3D9,0x0085,0x0083,0xC1AC,0xCEA5,0x0083,0xD4B6,0xBDF8,0x00A1, 0x0091,0x0089,0x0085,0x0083,0xDE89,0xD5E2,0x0083,0xBBB9,0xDE88,0x0085,0x0083,0xDE87,0xE5C3,0x0083,0xB7B5,0xE5C2, 0x0089,0x0085,0x0083,0xDE86,0xBDFC,0x0083,0xD4CB,0xDE85,0x0085,0x0083,0xD3AD,0xDE84,0x0083,0xDE83,0xDE82,0x0091, 0x0089,0x0085,0x0083,0xDE81,0xDE80,0x0083,0xC2F5,0xB9FD,0x0085,0x0083,0xDE7E,0xD1B8,0x0083,0xC6F9,0xDE7D,0x0089, 0x0085,0x0083,0xD3D8,0xC7A8,0x0083,0xDE7C,0xDE7B,0x0085,0x0083,0xB4EF,0xC1C9,0x0083,0xDE7A,0xDE79,0x0101,0x00C1, 0x00A1,0x0091,0x0089,0x0085,0x0083,0xDE78,0xB1DF,0x0083,0xDE77,0xDE76,0x0085,0x0083,0xE5C1,0xDE75,0x0083,0xDE74, 0xDE73,0x0089,0x0085,0x0083,0xDE72,0xC8E8,0x0083,0xB3BD,0xDE71,0x0085,0x0083,0xDE70,0xDE6F,0x0083,0xDE6E,0xB1E8, 0x0091,0x0089,0x0085,0x0083,0xDE6D,0xB1E7,0x0083,0xB1E6,0xDE6C,0x0085,0x0083,0xDE6B,0xDE6A,0x0083,0xDE69,0xC0B1, 0x0089,0x0085,0x0083,0xDE68,0xDE67,0x0083,0xDE66,0xB1D9,0x0085,0x0083,0xB4C7,0xDE65,0x0083,0xB9BC,0xD0C1,0x00A1, 0x0091,0x0089,0x0085,0x0083,0xEAA5,0xD5DE,0x0083,0xEAA4,0xD5B7,0x0085,0x0083,0xCFBD,0xD4AF,0x0083,0xE0CE,0xCAE4, 0x0089,0x0085,0x0083,0xDE64,0xBCAD,0x0083,0xB7F8,0xEAA3,0x0085,0x0083,0xEAA2,0xEAA1,0x0083,0xDE63,0xE9FE,0x0091, 0x0089,0x0085,0x0083,0xB9F5,0xBBD4,0x0083,0xB1B2,0xE9FD,0x0085,0x0083,0xC1BE,0xB8A8,0x0083,0xE9FC,0xBDCF,0x0089, 0x0085,0x0083,0xE9FB,0xE9FA,0x0083,0xDE62,0xBDCE,0x0085,0x0083,0xE9F9,0xD4D8,0x0083,0xE9F8,0xC7E1,0x00C1,0x00A1, 0x0091,0x0089,0x0085,0x0083,0xE9F7,0xE9F6,0x0083,0xE9F4,0xE9F5,0x0085,0x0083,0xE9F3,0xE9F2,0x0083,0xD6E1,0xE9F1, 0x0089,0x0085,0x0083,0xE9F0,0xE9EF,0x0083,0xBAE4,0xC8ED,0x0085,0x0083,0xC2D6,0xE9EE,0x0083,0xD7AA,0xE9ED,0x0091, 0x0089,0x0085,0x0083,0xDE61,0xD0F9,0x0083,0xB9EC,0xD4FE,0x0085,0x0083,0xB3B5,0xDE60,0x0083,0xDE5F,0xDE5E,0x0089, 0x0085,0x0083,0xDE5D,0xDE5C,0x0083,0xDE5B,0xDE5A,0x0085,0x0083,0xDE59,0xDE58,0x0083,0xDE57,0xDE56,0x00A1,0x0091, 0x0089,0x0085,0x0083,0xDE55,0xDE54,0x0083,0xDE53,0xDE52,0x0085,0x0083,0xDE51,0xDE50,0x0083,0xDE4F,0xDE4E,0x0089, 0x0085,0x0083,0xDE4D,0xDE4C,0x0083,0xDE4B,0xDE4A,0x0085,0x0083,0xDE49,0xDE48,0x0083,0xDE47,0xDE46,0x0091,0x0089, 0x0085,0x0083,0xDE45,0xDE44,0x0083,0xDE43,0xDE42,0x0085,0x0083,0xDE41,0xDE40,0x0083,0xDDA0,0xDD9F,0x0089,0x0085, 0x0083,0xDD9E,0xDD9D,0x0083,0xDD9C,0xDD9B,0x0085,0x0083,0xDD9A,0xDD99,0x0083,0xDD98,0xDD97,0x017F,0x00FF,0x00BF, 0x009F,0x008F,0x0087,0x0083,0xDD96,0x0083,0xDD95,0xDD94,0x0085,0x0083,0xDD93,0xDD92,0x0083,0xDD91,0xDD90,0x0089, 0x0085,0x0083,0xDD8F,0xDD8E,0x0083,0xDD8D,0xDD8C,0x0085,0x0083,0xDD8B,0xDD8A,0x0083,0xDD89,0xDD88,0x0091,0x0089, 0x0085,0x0083,0xDD87,0xDD86,0x0083,0xDD85,0xDD84,0x0085,0x0083,0xDD83,0xDD82,0x0083,0xDD81,0xDD80,0x0089,0x0085, 0x0083,0xDD7E,0xDD7D,0x0083,0xDD7C,0xDD7B,0x0085,0x0083,0xDD7A,0xDD79,0x0083,0xDD78,0xDD77,0x00A1,0x0091,0x0089, 0x0085,0x0083,0xDD76,0xDD75,0x0083,0xDD74,0xDD73,0x0085,0x0083,0xDD72,0xDD71,0x0083,0xDD70,0xDD6F,0x0089,0x0085, 0x0083,0xDD6E,0xDD6D,0x0083,0xDD6C,0xDD6B,0x0085,0x0083,0xDD6A,0xDD69,0x0083,0xDD68,0xDD67,0x0091,0x0089,0x0085, 0x0083,0xDD66,0xDD65,0x0083,0xDD64,0xDD63,0x0085,0x0083,0xDD62,0xDD61,0x0083,0xDD60,0xDD5F,0x0089,0x0085,0x0083, 0xDD5E,0xDD5D,0x0083,0xDD5C,0xDD5B,0x0085,0x0083,0xDD5A,0xDD59,0x0083,0xDD58,0xDD57,0x00C1,0x00A1,0x0091,0x0089, 0x0085,0x0083,0xDD56,0xDD55,0x0083,0xDD54,0xDD53,0x0085,0x0083,0xDD52,0xDD51,0x0083,0xDD50,0xDD4F,0x0089,0x0085, 0x0083,0xDD4E,0xDD4D,0x0083,0xDD4C,0xDD4B,0x0085,0x0083,0xDD4A,0xDD49,0x0083,0xDD48,0xDD47,0x0091,0x0089,0x0085, 0x0083,0xDD46,0xDD45,0x0083,0xDD44,0xDD43,0x0085,0x0083,0xDD42,0xDD41,0x0083,0xDD40,0xDCA0,0x0089,0x0085,0x0083, 0xDC9F,0xDC9E,0x0083,0xDC9D,0xDC9C,0x0085,0x0083,0xDC9B,0xDC9A,0x0083,0xDC99,0xDC98,0x00A1,0x0091,0x0089,0x0085, 0x0083,0xDC97,0xDC96,0x0083,0xDC95,0xDC94,0x0085,0x0083,0xDC93,0xDC92,0x0083,0xDC91,0xDC90,0x0089,0x0085,0x0083, 0xDC8F,0xDC8E,0x0083,0xDC8D,0xDC8C,0x0085,0x0083,0xDC8B,0xEAA6,0x0083,0xDC8A,0xDC89,0x0091,0x0089,0x0085,0x0083, 0xDC88,0xDC87,0x0083,0xDC86,0xDC85,0x0085,0x0083,0xDC84,0xDC83,0x0083,0xDC82,0xDC81,0x0089,0x0085,0x0083,0xDC80, 0xDC7E,0x0083,0xDC7D,0xDC7C,0x0085,0x0083,0xDC7B,0xDC7A,0x0083,0xDC79,0xDC78,0x0101,0x00C1,0x00A1,0x0091,0x0089, 0x0085,0x0083,0xDC77,0xCCC9,0x0083,0xDC76,0xDC75,0x0085,0x0083,0xDC74,0xDC73,0x0083,0xDC72,0xDC71,0x0089,0x0085, 0x0083,0xDC70,0xB6E3,0x0083,0xDC6F,0xDC6E,0x0085,0x0083,0xC7FB,0xDC6D,0x0083,0xDC6C,0xB9AA,0x0091,0x0089,0x0085, 0x0083,0xC9ED,0xDC6B,0x0083,0xDC6A,0xDC69,0x0085,0x0083,0xDC68,0xDC67,0x0083,0xDC66,0xDC65,0x0089,0x0085,0x0083, 0xDC64,0xDC63,0x0083,0xDC62,0xDC61,0x0085,0x0083,0xDC60,0xF5F3,0x0083,0xDC5F,0xF5F2,0x00A1,0x0091,0x0089,0x0085, 0x0083,0xDC5E,0xDC5D,0x0083,0xDC5C,0xDC5B,0x0085,0x0083,0xDC5A,0xDC59,0x0083,0xDC58,0xF5F0,0x0089,0x0085,0x0083, 0xDC57,0xDC56,0x0083,0xDC55,0xF5F1,0x0085,0x0083,0xF5EF,0xDC54,0x0083,0xDC53,0xDC52,0x0091,0x0089,0x0085,0x0083, 0xDC51,0xDC50,0x0083,0xDC4F,0xDC4E,0x0085,0x0083,0xB3F9,0xDC4D,0x0083,0xF5EE,0xDC4C,0x0089,0x0085,0x0083,0xDC4B, 0xDC4A,0x0083,0xD4EA,0xDC49,0x0085,0x0083,0xB4DA,0xDC48,0x0083,0xDC47,0xF5EB,0x00C1,0x00A1,0x0091,0x0089,0x0085, 0x0083,0xDC46,0xDC45,0x0083,0xDC44,0xDC43,0x0085,0x0083,0xDC42,0xF5EA,0x0083,0xDC41,0xF5ED,0x0089,0x0085,0x0083, 0xDC40,0xB6D7,0x0083,0xDBA0,0xF5E9,0x0085,0x0083,0xF5EC,0xDB9F,0x0083,0xB2E4,0xB5C5,0x0091,0x0089,0x0085,0x0083, 0xDB9E,0xDB9D,0x0083,0xF5BF,0xDB9C,0x0085,0x0083,0xDB9B,0xB1C4,0x0083,0xDB9A,0xDB99,0x0089,0x0085,0x0083,0xDB98, 0xDB97,0x0083,0xDB96,0xDB95,0x0085,0x0083,0xDB94,0xDB93,0x0083,0xDB92,0xDB91,0x00A1,0x0091,0x0089,0x0085,0x0083, 0xDB90,0xDB8F,0x0083,0xF5BE,0xDB8E,0x0085,0x0083,0xDB8D,0xDB8C,0x0083,0xDB8B,0xDB8A,0x0089,0x0085,0x0083,0xDB89, 0xF5E7,0x0083,0xF5E6,0xDB88,0x0085,0x0083,0xDB87,0xDB86,0x0083,0xDB85,0xDB84,0x0091,0x0089,0x0085,0x0083,0xCCA3, 0xF5E8,0x0083,0xF5E3,0xB5B8,0x0085,0x0083,0xE5BF,0xDB83,0x0083,0xDB82,0xCCE3,0x0089,0x0085,0x0083,0xDB81,0xF5E5, 0x0083,0xF5E4,0xF5DE,0x0085,0x0083,0xDB80,0xDB7E,0x0083,0xF5E1,0xDB7D,0x027F,0x017F,0x00FF,0x00BF,0x009F,0x008F, 0x0087,0x0083,0xDB7C,0x0083,0xF5DD,0xF5DF,0x0085,0x0083,0xDB7B,0xDB7A,0x0083,0xDB79,0xF5E0,0x0089,0x0085,0x0083, 0xDB78,0xDB77,0x0083,0xDB76,0xF5E2,0x0085,0x0083,0xDB75,0xF5DC,0x0083,0xF5DA,0xDB74,0x0091,0x0089,0x0085,0x0083, 0xF5D9,0xDB73,0x0083,0xD7D9,0xB2C8,0x0085,0x0083,0xDB72,0xDB71,0x0083,0xDB70,0xDB6F,0x0089,0x0085,0x0083,0xDB6E, 0xF5DB,0x0083,0xCCDF,0xDB6D,0x0085,0x0083,0xDB6C,0xF5D8,0x0083,0xBEE1,0xF5D7,0x00A1,0x0091,0x0089,0x0085,0x0083, 0xDB6B,0xDB6A,0x0083,0xDB69,0xDB68,0x0085,0x0083,0xDB67,0xDB66,0x0083,0xDB65,0xDB64,0x0089,0x0085,0x0083,0xF5D6, 0xDB63,0x0083,0xDB62,0xDB61,0x0085,0x0083,0xDB60,0xCCA4,0x0083,0xDB5F,0xDB5E,0x0091,0x0089,0x0085,0x0083,0xB3EC, 0xDB5D,0x0083,0xD3BB,0xF5D4,0x0085,0x0083,0xDB5C,0xDB5B,0x0083,0xDB5A,0xF5BD,0x0089,0x0085,0x0083,0xDB59,0xDB58, 0x0083,0xDB57,0xDB56,0x0085,0x0083,0xDB55,0xDB54,0x0083,0xDB53,0xF5D5,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083, 0xDB52,0xF5D2,0x0083,0xB6E5,0xF5D1,0x0085,0x0083,0xF5CF,0xF5CE,0x0083,0xDB51,0xBCF9,0x0089,0x0085,0x0083,0xDB50, 0xCCF8,0x0083,0xDB4F,0xDB4E,0x0085,0x0083,0xDB4D,0xC2B7,0x0083,0xDB4C,0xDB4B,0x0091,0x0089,0x0085,0x0083,0xF5CD, 0xF5BC,0x0083,0xB9F2,0xDB4A,0x0085,0x0083,0xBFE7,0xDB49,0x0083,0xDB48,0xDB47,0x0089,0x0085,0x0083,0xF5D3,0xF5D0, 0x0083,0xDB46,0xDB45,0x0085,0x0083,0xDB44,0xB8FA,0x0083,0xF5C8,0xBEE0,0x00A1,0x0091,0x0089,0x0085,0x0083,0xDB43, 0xF5CB,0x0083,0xF5C7,0xDB42,0x0085,0x0083,0xDB41,0xF5C6,0x0083,0xF5C5,0xDB40,0x0089,0x0085,0x0083,0xDAA0,0xDA9F, 0x0083,0xDA9E,0xC5DC,0x0085,0x0083,0xDA9D,0xF5CA,0x0083,0xF5C9,0xDA9C,0x0091,0x0089,0x0085,0x0083,0xB5F8,0xB0CF, 0x0083,0xDA9B,0xDA9A,0x0085,0x0083,0xDA99,0xDA98,0x0083,0xF5CC,0xDA97,0x0089,0x0085,0x0083,0xF5C4,0xD4BE,0x0083, 0xDA96,0xDA95,0x0085,0x0083,0xDA94,0xF5C1,0x0083,0xD6BA,0xDA93,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083, 0xF5C2,0xDA92,0x0083,0xF5C3,0xDA91,0x0085,0x0083,0xF5BB,0xDA90,0x0083,0xDA8F,0xF5C0,0x0089,0x0085,0x0083,0xC5BF, 0xD7E3,0x0083,0xDA8E,0xF4F5,0x0085,0x0083,0xDA8D,0xDA8C,0x0083,0xDA8B,0xDA8A,0x0091,0x0089,0x0085,0x0083,0xDA89, 0xDA88,0x0083,0xDA87,0xDA86,0x0085,0x0083,0xDA85,0xDA84,0x0083,0xDA83,0xDA82,0x0089,0x0085,0x0083,0xDA81,0xC8A4, 0x0083,0xDA80,0xDA7E,0x0085,0x0083,0xDA7D,0xCCCB,0x0083,0xDA7C,0xDA7B,0x00A1,0x0091,0x0089,0x0085,0x0083,0xDA7A, 0xDA79,0x0083,0xDA78,0xDA77,0x0085,0x0083,0xDA76,0xDA75,0x0083,0xDA74,0xDA73,0x0089,0x0085,0x0083,0xF4F3,0xDA72, 0x0083,0xDA71,0xF4F4,0x0085,0x0083,0xDA70,0xDA6F,0x0083,0xDA6E,0xDA6D,0x0091,0x0089,0x0085,0x0083,0xDA6C,0xC7F7, 0x0083,0xD4BD,0xDA6B,0x0085,0x0083,0xDA6A,0xDA69,0x0083,0xDA68,0xB3AC,0x0089,0x0085,0x0083,0xF4F2,0xDA67,0x0083, 0xDA66,0xB3C3,0x0085,0x0083,0xDA65,0xDA64,0x0083,0xDA63,0xDA62,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xDA61, 0xDA60,0x0083,0xDA5F,0xDA5E,0x0085,0x0083,0xDA5D,0xC6F0,0x0083,0xB8CF,0xD5D4,0x0089,0x0085,0x0083,0xB8B0,0xF4F1, 0x0083,0xDA5C,0xDA5B,0x0085,0x0083,0xD7DF,0xDA5A,0x0083,0xDA59,0xF4F7,0x0091,0x0089,0x0085,0x0083,0xDA58,0xBAD5, 0x0083,0xDA57,0xDA56,0x0085,0x0083,0xDA55,0xF4F6,0x0083,0xC9E2,0xDA54,0x0089,0x0085,0x0083,0xB3E0,0xB8D3,0x0083, 0xD3AE,0xC9C4,0x0085,0x0083,0xD4F9,0xDA53,0x0083,0xD4DE,0xD8CD,0x00A1,0x0091,0x0089,0x0085,0x0083,0xD8D3,0xC8FC, 0x0083,0xD7AC,0xEAE7,0x0085,0x0083,0xD7B8,0xDA52,0x0083,0xC0B5,0xEAE6,0x0089,0x0085,0x0083,0xC5E2,0xE2D9,0x0083, 0xDA51,0xDA50,0x0085,0x0083,0xB4CD,0xC9CD,0x0083,0xCAEA,0xEAE5,0x0091,0x0089,0x0085,0x0083,0xB6C4,0xB8B3,0x0083, 0xC9DE,0xEAE3,0x0085,0x0083,0xEAE2,0xEAE4,0x0083,0xEAE1,0xEAE0,0x0089,0x0085,0x0083,0xD7CA,0xD4DF,0x0083,0xC2B8, 0xC1DE,0x0085,0x0083,0xEADF,0xBBDF,0x0083,0xBCD6,0xEADE,0x0181,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083, 0xD4F4,0xEADD,0x0083,0xBAD8,0xB7D1,0x0085,0x0083,0xC3B3,0xB4FB,0x0083,0xEADC,0xB9F3,0x0089,0x0085,0x0083,0xCCF9, 0xEADB,0x0083,0xEADA,0xBCFA,0x0085,0x0083,0xB7A1,0xB9E1,0x0083,0xD6FC,0xB9BA,0x0091,0x0089,0x0085,0x0083,0xB1E1, 0xC6B6,0x0083,0xCCB0,0xB7B7,0x0085,0x0083,0xD6CA,0xBBF5,0x0083,0xD5CB,0xB0DC,0x0089,0x0085,0x0083,0xCFCD,0xD4F0, 0x0083,0xB2C6,0xB9B1,0x0085,0x0083,0xDA4F,0xB8BA,0x0083,0xD5EA,0xB1B4,0x00A1,0x0091,0x0089,0x0085,0x0083,0xDA4E, 0xDA4D,0x0083,0xDA4C,0xDA4B,0x0085,0x0083,0xDA4A,0xDA49,0x0083,0xDA48,0xDA47,0x0089,0x0085,0x0083,0xDA46,0xDA45, 0x0083,0xDA44,0xDA43,0x0085,0x0083,0xDA42,0xDA41,0x0083,0xDA40,0xD9A0,0x0091,0x0089,0x0085,0x0083,0xD99F,0xD99E, 0x0083,0xD99D,0xD99C,0x0085,0x0083,0xD99B,0xD99A,0x0083,0xD999,0xD998,0x0089,0x0085,0x0083,0xD997,0xD996,0x0083, 0xD995,0xD994,0x0085,0x0083,0xD993,0xD992,0x0083,0xD991,0xD990,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xD98F, 0xD98E,0x0083,0xD98D,0xD98C,0x0085,0x0083,0xD98B,0xD98A,0x0083,0xD989,0xD988,0x0089,0x0085,0x0083,0xD987,0xD986, 0x0083,0xD985,0xD984,0x0085,0x0083,0xD983,0xD982,0x0083,0xD981,0xD980,0x0091,0x0089,0x0085,0x0083,0xD97E,0xD97D, 0x0083,0xD97C,0xD97B,0x0085,0x0083,0xD97A,0xD979,0x0083,0xD978,0xD977,0x0089,0x0085,0x0083,0xD976,0xD975,0x0083, 0xD974,0xD973,0x0085,0x0083,0xD972,0xD971,0x0083,0xD970,0xD96F,0x00A1,0x0091,0x0089,0x0085,0x0083,0xD96E,0xD96D, 0x0083,0xD96C,0xD96B,0x0085,0x0083,0xD96A,0xD969,0x0083,0xD968,0xD967,0x0089,0x0085,0x0083,0xD966,0xD965,0x0083, 0xD964,0xD963,0x0085,0x0083,0xD962,0xD961,0x0083,0xD960,0xD95F,0x0091,0x0089,0x0085,0x0083,0xD95E,0xD95D,0x0083, 0xD95C,0xD95B,0x0085,0x0083,0xD95A,0xD959,0x0083,0xD958,0xD957,0x0089,0x0085,0x0083,0xD956,0xD955,0x0083,0xD954, 0xD953,0x0085,0x0083,0xD952,0xD951,0x0083,0xD950,0xD94F,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xD94E, 0xD94D,0x0083,0xD94C,0xD94B,0x0085,0x0083,0xD94A,0xD949,0x0083,0xD948,0xD947,0x0089,0x0085,0x0083,0xD946,0xD945, 0x0083,0xD944,0xD943,0x0085,0x0083,0xD942,0xD941,0x0083,0xD940,0xD8A0,0x0091,0x0089,0x0085,0x0083,0xD89F,0xD89E, 0x0083,0xD89D,0xD89C,0x0085,0x0083,0xD89B,0xD89A,0x0083,0xD899,0xD898,0x0089,0x0085,0x0083,0xD897,0xD896,0x0083, 0xD895,0xD894,0x0085,0x0083,0xD893,0xD892,0x0083,0xD891,0xD890,0x00A1,0x0091,0x0089,0x0085,0x0083,0xD88F,0xD88E, 0x0083,0xD88D,0xD88C,0x0085,0x0083,0xF5F8,0xD88B,0x0083,0xD88A,0xD889,0x0089,0x0085,0x0083,0xF5F9,0xD888,0x0083, 0xD887,0xD886,0x0085,0x0083,0xD885,0xD884,0x0083,0xD883,0xD882,0x0091,0x0089,0x0085,0x0083,0xC3B2,0xD881,0x0083, 0xF5F6,0xBAD1,0x0085,0x0083,0xD880,0xD87E,0x0083,0xD87D,0xF5F7,0x0089,0x0085,0x0083,0xD87C,0xD87B,0x0083,0xF5F5, 0xD87A,0x0085,0x0083,0xD879,0xD878,0x0083,0xD877,0xD876,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xD875,0xD874, 0x0083,0xB2F2,0xB1AA,0x0085,0x0083,0xF5F4,0xD873,0x0083,0xD872,0xD871,0x0089,0x0085,0x0083,0xD870,0xE1D9,0x0083, 0xD86F,0xD86E,0x0085,0x0083,0xD86D,0xD86C,0x0083,0xD86B,0xD86A,0x0091,0x0089,0x0085,0x0083,0xD869,0xD4A5,0x0083, 0xBAC0,0xD868,0x0085,0x0083,0xD867,0xD866,0x0083,0xD865,0xD864,0x0089,0x0085,0x0083,0xD863,0xD862,0x0083,0xBBBF, 0xCFF3,0x0085,0x0083,0xD861,0xD860,0x0083,0xD85F,0xD85E,0x00A1,0x0091,0x0089,0x0085,0x0083,0xD85D,0xD85C,0x0083, 0xEBE0,0xD85B,0x0085,0x0083,0xD85A,0xD859,0x0083,0xD858,0xF5B9,0x0089,0x0085,0x0083,0xD857,0xD856,0x0083,0xD855, 0xD854,0x0085,0x0083,0xD853,0xD852,0x0083,0xD851,0xD850,0x0091,0x0089,0x0085,0x0083,0xCDE3,0xD84F,0x0083,0xD84E, 0xF4F9,0x0085,0x0083,0xD84D,0xF4F8,0x0083,0xB6B9,0xD84C,0x0089,0x0085,0x0083,0xD84B,0xD84A,0x0083,0xD849,0xBBED, 0x0085,0x0083,0xD848,0xD847,0x0083,0xD846,0xD845,0x047D,0x027F,0x017F,0x00FF,0x00BF,0x009F,0x008F,0x0087,0x0083, 0xD844,0x0083,0xD843,0xD842,0x0085,0x0083,0xD841,0xD840,0x0083,0xB9C8,0xDADF,0x0089,0x0085,0x0083,0xDADE,0xC7B4, 0x0083,0xDADD,0xDADC,0x0085,0x0083,0xC6D7,0xC0BE,0x0083,0xDADB,0xDADA,0x0091,0x0089,0x0085,0x0083,0xCCB7,0xC3FD, 0x0083,0xDAD9,0xDAD8,0x0085,0x0083,0xC3A1,0xBDF7,0x0083,0xDAD7,0xC7AB,0x0089,0x0085,0x0083,0xDAD6,0xB0F9,0x0083, 0xD2A5,0xD0BB,0x0085,0x0083,0xDAD5,0xDAD4,0x0083,0xDAD3,0xD7A0,0x00A1,0x0091,0x0089,0x0085,0x0083,0xDAD2,0xC3D5, 0x0083,0xDAD0,0xD1E8,0x0085,0x0083,0xDACF,0xDAD1,0x0083,0xB2F7,0xDACE,0x0089,0x0085,0x0083,0xDACD,0xDACC,0x0083, 0xCEBD,0xDACB,0x0085,0x0083,0xDACA,0xD0B3,0x0083,0xDAC9,0xBBD1,0x0091,0x0089,0x0085,0x0083,0xB5FD,0xDAC8,0x0083, 0xC4B1,0xD2EA,0x0085,0x0083,0xD79F,0xCCB8,0x0083,0xDAC7,0xD7BB,0x0089,0x0085,0x0083,0xC1C2,0xDAC6,0x0083,0xB5F7, 0xDAC5,0x0085,0x0083,0xCBAD,0xDAC4,0x0083,0xDAC3,0xBFCE,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xB7CC,0xDAC2, 0x0083,0xB6C1,0xC5B5,0x0085,0x0083,0xDAC1,0xD6EE,0x0083,0xC7EB,0xDAC0,0x0089,0x0085,0x0083,0xCBD0,0xCBB5,0x0083, 0xDABF,0xBBE5,0x0085,0x0083,0xD3D5,0xDABE,0x0083,0xCEF3,0xDABD,0x0091,0x0089,0x0085,0x0083,0xD3EF,0xCEDC,0x0083, 0xBDEB,0xD79E,0x0085,0x0083,0xDABC,0xDABB,0x0083,0xB2EF,0xCFEA,0x0089,0x0085,0x0083,0xB8C3,0xDABA,0x0083,0xD2E8, 0xD1AF,0x0085,0x0083,0xB9EE,0xDAB9,0x0083,0xDAB8,0xB5AE,0x00A1,0x0091,0x0089,0x0085,0x0083,0xBBB0,0xDAB7,0x0083, 0xD6EF,0xB3CF,0x0085,0x0083,0xDAB6,0xDAB5,0x0083,0xCAAB,0xDAB4,0x0089,0x0085,0x0083,0xCAD4,0xDAB3,0x0083,0xDAB2, 0xDAB1,0x0085,0x0083,0xD2EB,0xD79D,0x0083,0xDAAF,0xDAB0,0x0091,0x0089,0x0085,0x0083,0xB4CA,0xD6DF,0x0083,0xDAAE, 0xD5EF,0x0085,0x0083,0xCBDF,0xD5A9,0x0083,0xD79C,0xCAB6,0x0089,0x0085,0x0083,0xD7E7,0xC6C0,0x0083,0xDAAD,0xDAAC, 0x0085,0x0083,0xD6A4,0xBEF7,0x0083,0xB7C3,0xC9E8,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xB7ED,0xCBCF, 0x0083,0xD79B,0xC2DB,0x0085,0x0083,0xB6EF,0xD0ED,0x0083,0xDAAB,0xD1C8,0x0089,0x0085,0x0083,0xDAAA,0xDAA9,0x0083, 0xBBE4,0xBDB2,0x0085,0x0083,0xD79A,0xBCC7,0x0083,0xD1B6,0xD2E9,0x0091,0x0089,0x0085,0x0083,0xD1B5,0xD799,0x0083, 0xC6FD,0xDAA8,0x0085,0x0083,0xC8C3,0xCCD6,0x0083,0xDAA7,0xDAA6,0x0089,0x0085,0x0083,0xBCA5,0xC8CF,0x0083,0xB8BC, 0xB6A9,0x0085,0x0083,0xBCC6,0xDAA5,0x0083,0xD798,0xD797,0x00A1,0x0091,0x0089,0x0085,0x0083,0xD796,0xD795,0x0083, 0xD794,0xD793,0x0085,0x0083,0xD792,0xD791,0x0083,0xD790,0xD78F,0x0089,0x0085,0x0083,0xD78E,0xD78D,0x0083,0xD78C, 0xD78B,0x0085,0x0083,0xD78A,0xD789,0x0083,0xD788,0xD787,0x0091,0x0089,0x0085,0x0083,0xD786,0xD785,0x0083,0xD784, 0xD783,0x0085,0x0083,0xD782,0xD781,0x0083,0xD780,0xD77E,0x0089,0x0085,0x0083,0xD77D,0xD77C,0x0083,0xD77B,0xD77A, 0x0085,0x0083,0xD779,0xD778,0x0083,0xD777,0xD776,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xD775,0xD774,0x0083, 0xD773,0xD772,0x0085,0x0083,0xD771,0xD770,0x0083,0xD76F,0xD76E,0x0089,0x0085,0x0083,0xD76D,0xD76C,0x0083,0xD76B, 0xD76A,0x0085,0x0083,0xD769,0xD768,0x0083,0xD767,0xD766,0x0091,0x0089,0x0085,0x0083,0xD765,0xC6A9,0x0083,0xD764, 0xD763,0x0085,0x0083,0xD762,0xD761,0x0083,0xD760,0xBEAF,0x0089,0x0085,0x0083,0xD75F,0xD75E,0x0083,0xD75D,0xD75C, 0x0085,0x0083,0xD75B,0xD75A,0x0083,0xD759,0xD758,0x00A1,0x0091,0x0089,0x0085,0x0083,0xD757,0xD756,0x0083,0xD755, 0xD754,0x0085,0x0083,0xD753,0xD752,0x0083,0xD751,0xD750,0x0089,0x0085,0x0083,0xD74F,0xD74E,0x0083,0xD74D,0xD74C, 0x0085,0x0083,0xD74B,0xD74A,0x0083,0xD749,0xD748,0x0091,0x0089,0x0085,0x0083,0xD747,0xD746,0x0083,0xD745,0xD744, 0x0085,0x0083,0xD743,0xD742,0x0083,0xD741,0xD740,0x0089,0x0085,0x0083,0xD6A0,0xD69F,0x0083,0xD69E,0xD69D,0x0085, 0x0083,0xD69C,0xD69B,0x0083,0xD69A,0xD699,0x017F,0x00FF,0x00BF,0x009F,0x008F,0x0087,0x0083,0xD698,0x0083,0xD697, 0xD696,0x0085,0x0083,0xD695,0xD694,0x0083,0xD693,0xD692,0x0089,0x0085,0x0083,0xD691,0xD690,0x0083,0xD68F,0xD68E, 0x0085,0x0083,0xD68D,0xD68C,0x0083,0xD68B,0xD68A,0x0091,0x0089,0x0085,0x0083,0xD689,0xD688,0x0083,0xD687,0xD686, 0x0085,0x0083,0xD685,0xD684,0x0083,0xD683,0xD682,0x0089,0x0085,0x0083,0xF6A5,0xD681,0x0083,0xD680,0xD67E,0x0085, 0x0083,0xD67D,0xD67C,0x0083,0xD67B,0xD67A,0x00A1,0x0091,0x0089,0x0085,0x0083,0xD679,0xD678,0x0083,0xD677,0xD676, 0x0085,0x0083,0xD675,0xD674,0x0083,0xD673,0xD672,0x0089,0x0085,0x0083,0xD671,0xD670,0x0083,0xD66F,0xD66E,0x0085, 0x0083,0xD66D,0xD66C,0x0083,0xD66B,0xD66A,0x0091,0x0089,0x0085,0x0083,0xD669,0xD668,0x0083,0xD667,0xD666,0x0085, 0x0083,0xD665,0xD664,0x0083,0xD663,0xE5C0,0x0089,0x0085,0x0083,0xD662,0xD661,0x0083,0xD660,0xD65F,0x0085,0x0083, 0xD65E,0xD65D,0x0083,0xD65C,0xD65B,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xD65A,0xD659,0x0083,0xD658,0xD657, 0x0085,0x0083,0xD656,0xD655,0x0083,0xD654,0xD653,0x0089,0x0085,0x0083,0xD652,0xD651,0x0083,0xD650,0xD64F,0x0085, 0x0083,0xD64E,0xD64D,0x0083,0xD64C,0xD64B,0x0091,0x0089,0x0085,0x0083,0xD64A,0xD649,0x0083,0xD648,0xD647,0x0085, 0x0083,0xD646,0xD645,0x0083,0xD644,0xD643,0x0089,0x0085,0x0083,0xD642,0xD641,0x0083,0xD640,0xD5A0,0x0085,0x0083, 0xD59F,0xD59E,0x0083,0xD59D,0xD59C,0x00A1,0x0091,0x0089,0x0085,0x0083,0xD59B,0xD59A,0x0083,0xD599,0xD598,0x0085, 0x0083,0xD597,0xD596,0x0083,0xD595,0xD594,0x0089,0x0085,0x0083,0xD593,0xD592,0x0083,0xD591,0xD590,0x0085,0x0083, 0xD58F,0xD58E,0x0083,0xD58D,0xD58C,0x0091,0x0089,0x0085,0x0083,0xD58B,0xD58A,0x0083,0xD589,0xD588,0x0085,0x0083, 0xD587,0xD586,0x0083,0xD585,0xD584,0x0089,0x0085,0x0083,0xD583,0xD582,0x0083,0xD581,0xD580,0x0085,0x0083,0xD57E, 0xD57D,0x0083,0xD57C,0xD57B,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xD57A,0xD579,0x0083,0xD578,0xD577, 0x0085,0x0083,0xD576,0xD575,0x0083,0xD574,0xD573,0x0089,0x0085,0x0083,0xD572,0xD571,0x0083,0xD570,0xD56F,0x0085, 0x0083,0xD56E,0xD56D,0x0083,0xD56C,0xD56B,0x0091,0x0089,0x0085,0x0083,0xD56A,0xD569,0x0083,0xD568,0xD567,0x0085, 0x0083,0xD566,0xD565,0x0083,0xD564,0xD563,0x0089,0x0085,0x0083,0xD562,0xD561,0x0083,0xD560,0xD55F,0x0085,0x0083, 0xD55E,0xD55D,0x0083,0xD55C,0xD55B,0x00A1,0x0091,0x0089,0x0085,0x0083,0xD55A,0xD559,0x0083,0xD558,0xD557,0x0085, 0x0083,0xD556,0xD555,0x0083,0xD554,0xD553,0x0089,0x0085,0x0083,0xD552,0xD551,0x0083,0xD550,0xCAC4,0x0085,0x0083, 0xD54F,0xD54E,0x0083,0xD54D,0xD54C,0x0091,0x0089,0x0085,0x0083,0xD54B,0xD54A,0x0083,0xD549,0xD548,0x0085,0x0083, 0xCCDC,0xD3FE,0x0083,0xD547,0xD546,0x0089,0x0085,0x0083,0xD545,0xD544,0x0083,0xD543,0xD542,0x0085,0x0083,0xD541, 0xD540,0x0083,0xD4A0,0xD49F,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xD49E,0xD49D,0x0083,0xD49C,0xD49B,0x0085, 0x0083,0xD49A,0xD5B2,0x0083,0xD499,0xD498,0x0089,0x0085,0x0083,0xD497,0xD496,0x0083,0xD495,0xD494,0x0085,0x0083, 0xD493,0xD492,0x0083,0xD491,0xD490,0x0091,0x0089,0x0085,0x0083,0xD48F,0xD48E,0x0083,0xD48D,0xD48C,0x0085,0x0083, 0xD48B,0xD48A,0x0083,0xD489,0xD488,0x0089,0x0085,0x0083,0xD487,0xD486,0x0083,0xD485,0xD484,0x0085,0x0083,0xD483, 0xD482,0x0083,0xD481,0xD480,0x00A1,0x0091,0x0089,0x0085,0x0083,0xD47E,0xD47D,0x0083,0xD47C,0xD47B,0x0085,0x0083, 0xD47A,0xD479,0x0083,0xD478,0xD477,0x0089,0x0085,0x0083,0xD476,0xD475,0x0083,0xD474,0xD473,0x0085,0x0083,0xD472, 0xD471,0x0083,0xD470,0xD46F,0x0091,0x0089,0x0085,0x0083,0xD46E,0xD46D,0x0083,0xD46C,0xD46B,0x0085,0x0083,0xD46A, 0xD469,0x0083,0xEEBA,0xD468,0x0089,0x0085,0x0083,0xD467,0xD466,0x0083,0xD465,0xD464,0x0085,0x0083,0xD463,0xD462, 0x0083,0xD461,0xD460,0x027F,0x017F,0x00FF,0x00BF,0x009F,0x008F,0x0087,0x0083,0xF6A4,0x0083,0xD45F,0xD45E,0x0085, 0x0083,0xD45D,0xD45C,0x0083,0xD45B,0xD45A,0x0089,0x0085,0x0083,0xD459,0xD458,0x0083,0xD457,0xD456,0x0085,0x0083, 0xD455,0xD454,0x0083,0xD453,0xD452,0x0091,0x0089,0x0085,0x0083,0xD451,0xD450,0x0083,0xD44F,0xD44E,0x0085,0x0083, 0xD44D,0xD44C,0x0083,0xD44B,0xD44A,0x0089,0x0085,0x0083,0xD449,0xD448,0x0083,0xD447,0xD446,0x0085,0x0083,0xD445, 0xD444,0x0083,0xD443,0xD442,0x00A1,0x0091,0x0089,0x0085,0x0083,0xD441,0xD440,0x0083,0xD3A0,0xD39F,0x0085,0x0083, 0xD39E,0xD39D,0x0083,0xD39C,0xD39B,0x0089,0x0085,0x0083,0xD39A,0xD399,0x0083,0xD398,0xD397,0x0085,0x0083,0xD396, 0xD395,0x0083,0xD394,0xD393,0x0091,0x0089,0x0085,0x0083,0xD392,0xD391,0x0083,0xD390,0xD38F,0x0085,0x0083,0xD38E, 0xD38D,0x0083,0xD38C,0xD38B,0x0089,0x0085,0x0083,0xD9EA,0xD38A,0x0083,0xD389,0xD388,0x0085,0x0083,0xD387,0xD386, 0x0083,0xD385,0xD1D4,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xD384,0xD383,0x0083,0xD382,0xD381,0x0085,0x0083, 0xD380,0xD37E,0x0083,0xD37D,0xD37C,0x0089,0x0085,0x0083,0xD37B,0xD37A,0x0083,0xD379,0xD378,0x0085,0x0083,0xECB2, 0xD377,0x0083,0xD376,0xD375,0x0091,0x0089,0x0085,0x0083,0xF6A3,0xD374,0x0083,0xD373,0xD372,0x0085,0x0083,0xF6A2, 0xD371,0x0083,0xD370,0xD36F,0x0089,0x0085,0x0083,0xD36E,0xB4A5,0x0083,0xF6A1,0xD36D,0x0085,0x0083,0xBDE2,0xD36C, 0x0083,0xD36B,0xD36A,0x00A1,0x0091,0x0089,0x0085,0x0083,0xD369,0xF5FC,0x0083,0xD368,0xF5FE,0x0085,0x0083,0xD367, 0xF5FD,0x0083,0xD366,0xD365,0x0089,0x0085,0x0083,0xD364,0xF5FB,0x0083,0xD363,0xD362,0x0085,0x0083,0xD361,0xBDC7, 0x0083,0xEAEF,0xEAEE,0x0091,0x0089,0x0085,0x0083,0xEAED,0xEAEC,0x0083,0xD360,0xEAEB,0x0085,0x0083,0xEAEA,0xEAE9, 0x0083,0xBEF5,0xC0C0,0x0089,0x0085,0x0083,0xEAE8,0xCAD3,0x0083,0xC3D9,0xB9E6,0x0085,0x0083,0xD35F,0xB9DB,0x0083, 0xBCFB,0xD35E,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xD35D,0xD35C,0x0083,0xD35B,0xD35A,0x0085,0x0083, 0xD359,0xD358,0x0083,0xD357,0xD356,0x0089,0x0085,0x0083,0xD355,0xD354,0x0083,0xD353,0xD352,0x0085,0x0083,0xD351, 0xD350,0x0083,0xD34F,0xD34E,0x0091,0x0089,0x0085,0x0083,0xD34D,0xD34C,0x0083,0xD34B,0xD34A,0x0085,0x0083,0xD349, 0xD348,0x0083,0xD347,0xD346,0x0089,0x0085,0x0083,0xD345,0xD344,0x0083,0xD343,0xD342,0x0085,0x0083,0xD341,0xD340, 0x0083,0xD2A0,0xD29F,0x00A1,0x0091,0x0089,0x0085,0x0083,0xD29E,0xD29D,0x0083,0xD29C,0xD29B,0x0085,0x0083,0xD29A, 0xD299,0x0083,0xD298,0xD297,0x0089,0x0085,0x0083,0xD296,0xD295,0x0083,0xD294,0xD293,0x0085,0x0083,0xD292,0xD291, 0x0083,0xD290,0xD28F,0x0091,0x0089,0x0085,0x0083,0xD28E,0xD28D,0x0083,0xD28C,0xD28B,0x0085,0x0083,0xD28A,0xD289, 0x0083,0xD288,0xD287,0x0089,0x0085,0x0083,0xD286,0xB8B2,0x0083,0xD285,0xD284,0x0085,0x0083,0xF1FB,0xD283,0x0083, 0xD2AA,0xD282,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xCEF7,0xD281,0x0083,0xD280,0xD27E,0x0085,0x0083,0xF1E1, 0xD27D,0x0083,0xD27C,0xD27B,0x0089,0x0085,0x0083,0xD27A,0xD279,0x0083,0xD278,0xD277,0x0085,0x0083,0xD276,0xD275, 0x0083,0xD274,0xD273,0x0091,0x0089,0x0085,0x0083,0xD272,0xD271,0x0083,0xD270,0xD26F,0x0085,0x0083,0xD26E,0xD26D, 0x0083,0xD26C,0xD26B,0x0089,0x0085,0x0083,0xD26A,0xF1E0,0x0083,0xD269,0xD268,0x0085,0x0083,0xD267,0xD266,0x0083, 0xD265,0xD264,0x00A1,0x0091,0x0089,0x0085,0x0083,0xBDF3,0xF4C5,0x0083,0xD263,0xD262,0x0085,0x0083,0xD261,0xD260, 0x0083,0xD25F,0xD25E,0x0089,0x0085,0x0083,0xD25D,0xD25C,0x0083,0xD25B,0xD25A,0x0085,0x0083,0xD259,0xD258,0x0083, 0xD257,0xD256,0x0091,0x0089,0x0085,0x0083,0xD255,0xD254,0x0083,0xD253,0xD252,0x0085,0x0083,0xD251,0xD250,0x0083, 0xD24F,0xD24E,0x0089,0x0085,0x0083,0xD24D,0xD24C,0x0083,0xD24B,0xCFE5,0x0085,0x0083,0xD24A,0xD249,0x0083,0xF1DF, 0xD248,0x0181,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xD247,0xD246,0x0083,0xD245,0xD244,0x0085,0x0083, 0xD243,0xD242,0x0083,0xD241,0xD240,0x0089,0x0085,0x0083,0xD1A0,0xF1DE,0x0083,0xD19F,0xF1DC,0x0085,0x0083,0xD19E, 0xD19D,0x0083,0xD19C,0xE5BD,0x0091,0x0089,0x0085,0x0083,0xD19B,0xD19A,0x0083,0xD199,0xD198,0x0085,0x0083,0xF1DD, 0xCDCA,0x0083,0xD197,0xD196,0x0089,0x0085,0x0083,0xD195,0xD194,0x0083,0xC8EC,0xD193,0x0085,0x0083,0xD192,0xD191, 0x0083,0xF1D7,0xD190,0x00A1,0x0091,0x0089,0x0085,0x0083,0xD18F,0xD18E,0x0083,0xD18D,0xD18C,0x0085,0x0083,0xF1DA, 0xF1D2,0x0083,0xF1D8,0xD18B,0x0089,0x0085,0x0083,0xD18A,0xD189,0x0083,0xD188,0xD187,0x0085,0x0083,0xF1D9,0xB0FD, 0x0083,0xD186,0xBAD6,0x0091,0x0089,0x0085,0x0083,0xD185,0xD184,0x0083,0xD183,0xD182,0x0085,0x0083,0xD181,0xF1DB, 0x0083,0xD180,0xD17E,0x0089,0x0085,0x0083,0xD17D,0xD17C,0x0083,0xD17B,0xD17A,0x0085,0x0083,0xD179,0xB9D3,0x0083, 0xD178,0xD177,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xD176,0xF1D5,0x0083,0xD175,0xF1D3,0x0085,0x0083,0xD174, 0xD173,0x0083,0xB9FC,0xC2E3,0x0089,0x0085,0x0083,0xD172,0xD171,0x0083,0xD170,0xC5E1,0x0085,0x0083,0xC9D1,0xD16F, 0x0083,0xF1D1,0xF1D6,0x0091,0x0089,0x0085,0x0083,0xD16E,0xD16D,0x0083,0xD16C,0xD16B,0x0085,0x0083,0xD16A,0xD169, 0x0083,0xD168,0xF1D4,0x0089,0x0085,0x0083,0xD167,0xD166,0x0083,0xF1D0,0xBFE3,0x0085,0x0083,0xF1CF,0xF1CD,0x0083, 0xD165,0xD164,0x00A1,0x0091,0x0089,0x0085,0x0083,0xF4C4,0xD163,0x0083,0xD162,0xD161,0x0085,0x0083,0xD160,0xD15F, 0x0083,0xC8B9,0xF4C3,0x0089,0x0085,0x0083,0xD15E,0xD15D,0x0083,0xD4A3,0xD2E1,0x0085,0x0083,0xD15C,0xD9F6,0x0083, 0xD15B,0xD15A,0x0091,0x0089,0x0085,0x0083,0xD159,0xF1CE,0x0083,0xD158,0xD157,0x0085,0x0083,0xD156,0xD155,0x0083, 0xF1CC,0xD154,0x0089,0x0085,0x0083,0xD153,0xF1C9,0x0083,0xD7B0,0xD152,0x0085,0x0083,0xD151,0xC1D1,0x0083,0xB2C3, 0xD150,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xD14F,0xD14E,0x0083,0xD14D,0xF1CB,0x0085,0x0083,0xD14C, 0xD14B,0x0083,0xD14A,0xD149,0x0089,0x0085,0x0083,0xF1CA,0xD148,0x0083,0xD147,0xD146,0x0085,0x0083,0xD145,0xD144, 0x0083,0xB8A4,0xD143,0x0091,0x0089,0x0085,0x0083,0xD142,0xD141,0x0083,0xCFAE,0xD140,0x0085,0x0083,0xB1BB,0xD0A0, 0x0083,0xD09F,0xD09E,0x0089,0x0085,0x0083,0xD09D,0xD09C,0x0083,0xD09B,0xD9F3,0x0085,0x0083,0xD09A,0xF1C8,0x0083, 0xD099,0xD098,0x00A1,0x0091,0x0089,0x0085,0x0083,0xD097,0xD096,0x0083,0xD095,0xCDE0,0x0085,0x0083,0xD094,0xD093, 0x0083,0xD092,0xD091,0x0089,0x0085,0x0083,0xD090,0xD0E4,0x0083,0xD08F,0xD08E,0x0085,0x0083,0xD08D,0xCCBB,0x0083, 0xD08C,0xD08B,0x0091,0x0089,0x0085,0x0083,0xD08A,0xD089,0x0083,0xC5DB,0xD088,0x0085,0x0083,0xB4FC,0xD087,0x0083, 0xD086,0xF4C2,0x0089,0x0085,0x0083,0xD085,0xD084,0x0083,0xF4C1,0xB0C0,0x0085,0x0083,0xD083,0xF1C7,0x0083,0xD4AC, 0xD082,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xF1C6,0xF4C0,0x0083,0xF1C5,0xD081,0x0085,0x0083,0xD080,0xD07E, 0x0083,0xD07D,0xD07C,0x0089,0x0085,0x0083,0xD6D4,0xD07B,0x0083,0xD07A,0xD079,0x0085,0x0083,0xD078,0xF1C4,0x0083, 0xD077,0xCBA5,0x0091,0x0089,0x0085,0x0083,0xD076,0xD9F2,0x0083,0xD075,0xB3C4,0x0085,0x0083,0xC9C0,0xD074,0x0083, 0xF1C3,0xB1ED,0x0089,0x0085,0x0083,0xD073,0xD072,0x0083,0xB2B9,0xF1C2,0x0085,0x0083,0xD2C2,0xE1E9,0x0083,0xBAE2, 0xD071,0x00A1,0x0091,0x0089,0x0085,0x0083,0xD070,0xD06F,0x0083,0xD06E,0xD06D,0x0085,0x0083,0xD06C,0xD06B,0x0083, 0xD1C3,0xD06A,0x0089,0x0085,0x0083,0xBDD6,0xD069,0x0083,0xD068,0xCFCE,0x0085,0x0083,0xD067,0xD066,0x0083,0xD065, 0xD064,0x0091,0x0089,0x0085,0x0083,0xD063,0xD062,0x0083,0xD1DC,0xD0D0,0x0085,0x0083,0xD061,0xD060,0x0083,0xD05F, 0xD05E,0x0089,0x0085,0x0083,0xD05D,0xD05C,0x0083,0xD0C6,0xF4AC,0x0085,0x0083,0xD05B,0xD05A,0x0083,0xD059,0xD1AA, 0x087B,0x047D,0x027F,0x017F,0x00FF,0x00BF,0x009F,0x008F,0x0087,0x0083,0xD058,0x0083,0xD057,0xD056,0x0085,0x0083, 0xF3BD,0xD055,0x0083,0xD054,0xF3BC,0x0089,0x0085,0x0083,0xD053,0xD052,0x0083,0xD051,0xD050,0x0085,0x0083,0xD04F, 0xD04E,0x0083,0xEEC3,0xD04D,0x0091,0x0089,0x0085,0x0083,0xD04C,0xD04B,0x0083,0xD04A,0xD049,0x0085,0x0083,0xD048, 0xD047,0x0083,0xD046,0xD045,0x0089,0x0085,0x0083,0xD044,0xD043,0x0083,0xD042,0xD041,0x0085,0x0083,0xD040,0xCFA0, 0x0083,0xB4C0,0xF3BB,0x00A1,0x0091,0x0089,0x0085,0x0083,0xCF9F,0xCF9E,0x0083,0xCF9D,0xCF9C,0x0085,0x0083,0xCF9B, 0xF3BA,0x0083,0xCF9A,0xCF99,0x0089,0x0085,0x0083,0xCF98,0xCF97,0x0083,0xF3B6,0xC8E4,0x0085,0x0083,0xCF96,0xF3B7, 0x0083,0xCF95,0xCF94,0x0091,0x0089,0x0085,0x0083,0xCF93,0xCF92,0x0083,0xCF91,0xCF90,0x0085,0x0083,0xCF8F,0xCF8E, 0x0083,0xF3B9,0xCF8D,0x0089,0x0085,0x0083,0xCF8C,0xCF8B,0x0083,0xCF8A,0xCF89,0x0085,0x0083,0xCF88,0xD9F9,0x0083, 0xCF87,0xCF86,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xCF85,0xCF84,0x0083,0xF3B8,0xCF83,0x0085,0x0083,0xCF82, 0xCF81,0x0083,0xCF80,0xD0B7,0x0089,0x0085,0x0083,0xCF7E,0xCF7D,0x0083,0xCF7C,0xCF7B,0x0085,0x0083,0xCF7A,0xCF79, 0x0083,0xCF78,0xCF77,0x0091,0x0089,0x0085,0x0083,0xCF76,0xCF75,0x0083,0xF3B5,0xCF74,0x0085,0x0083,0xCF73,0xCF72, 0x0083,0xF3B3,0xCF71,0x0089,0x0085,0x0083,0xCF70,0xCF6F,0x0083,0xCF6E,0xF3A8,0x0085,0x0083,0xCF6D,0xCF6C,0x0083, 0xCF6B,0xCF6A,0x00A1,0x0091,0x0089,0x0085,0x0083,0xF3B4,0xCF69,0x0083,0xCF68,0xCF67,0x0085,0x0083,0xCF66,0xF3B2, 0x0083,0xCF65,0xCF64,0x0089,0x0085,0x0083,0xCF63,0xCF62,0x0083,0xCF61,0xCF60,0x0085,0x0083,0xCF5F,0xF3AD,0x0083, 0xF2FE,0xF3AF,0x0091,0x0089,0x0085,0x0083,0xCF5E,0xCF5D,0x0083,0xCF5C,0xCF5B,0x0085,0x0083,0xCF5A,0xF3AC,0x0083, 0xF3B1,0xCF59,0x0089,0x0085,0x0083,0xCF58,0xCF57,0x0083,0xF3A1,0xCF56,0x0085,0x0083,0xCF55,0xCF54,0x0083,0xCF53, 0xCF52,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xF3B0,0xCF51,0x0083,0xCF50,0xF3AE,0x0085,0x0083,0xCF4F, 0xCF4E,0x0083,0xC2DD,0xCF4D,0x0089,0x0085,0x0083,0xCF4C,0xCF4B,0x0083,0xCF4A,0xF3AA,0x0085,0x0083,0xCF49,0xF3AB, 0x0083,0xCF48,0xCF47,0x0091,0x0089,0x0085,0x0083,0xCF46,0xF2FC,0x0083,0xCF45,0xF3A4,0x0085,0x0083,0xF3A9,0xF3A7, 0x0083,0xCF44,0xCF43,0x0089,0x0085,0x0083,0xF2FD,0xCF42,0x0083,0xCF41,0xCF40,0x0085,0x0083,0xCEA0,0xCE9F,0x0083, 0xCE9E,0xCE9D,0x00A1,0x0091,0x0089,0x0085,0x0083,0xCE9C,0xC3F8,0x0083,0xCE9B,0xCE9A,0x0085,0x0083,0xCE99,0xCE98, 0x0083,0xCE97,0xCE96,0x0089,0x0085,0x0083,0xCE95,0xF3A5,0x0083,0xCE94,0xCE93,0x0085,0x0083,0xCE92,0xF2FB,0x0083, 0xCE91,0xCE90,0x0091,0x0089,0x0085,0x0083,0xCE8F,0xCE8E,0x0083,0xCE8D,0xC8DA,0x0085,0x0083,0xCE8C,0xF2F4,0x0083, 0xCE8B,0xCE8A,0x0089,0x0085,0x0083,0xF3A2,0xCE89,0x0083,0xCE88,0xF3A3,0x0085,0x0083,0xCE87,0xF3A6,0x0083,0xF2EB, 0xCE86,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xCE85,0xCE84,0x0083,0xF2EE,0xF2ED,0x0085,0x0083,0xF2F7,0xF2EF, 0x0083,0xCE83,0xCE82,0x0089,0x0085,0x0083,0xCE81,0xCE80,0x0083,0xB5FB,0xCE7E,0x0085,0x0083,0xBAFB,0xCE7D,0x0083, 0xCE7C,0xCE7B,0x0091,0x0089,0x0085,0x0083,0xF2F1,0xCE7A,0x0083,0xF2F3,0xCE79,0x0085,0x0083,0xCE78,0xCE77,0x0083, 0xCE76,0xCE75,0x0089,0x0085,0x0083,0xCE74,0xCE73,0x0083,0xCE72,0xF2FA,0x0085,0x0083,0xF2F8,0xF2F6,0x0083,0xCE71, 0xCE70,0x00A1,0x0091,0x0089,0x0085,0x0083,0xF2F0,0xCE6F,0x0083,0xCE6E,0xCE6D,0x0085,0x0083,0xCE6C,0xCE6B,0x0083, 0xCE6A,0xF2F9,0x0089,0x0085,0x0083,0xCE69,0xBBC8,0x0083,0xCE68,0xCE67,0x0085,0x0083,0xCE66,0xF2F5,0x0083,0xCE65, 0xCE64,0x0091,0x0089,0x0085,0x0083,0xCE63,0xCE62,0x0083,0xD0AB,0xCE61,0x0085,0x0083,0xF2F2,0xCE60,0x0083,0xCE5F, 0xB2F5,0x0089,0x0085,0x0083,0xF2E5,0xD3AC,0x0083,0xCE5E,0xCE5D,0x0085,0x0083,0xCE5C,0xCE5B,0x0083,0xCE5A,0xCE59, 0x017F,0x00FF,0x00BF,0x009F,0x008F,0x0087,0x0083,0xCE58,0x0083,0xF2EA,0xF2E4,0x0085,0x0083,0xCE57,0xCE56,0x0083, 0xF2DF,0xCE55,0x0089,0x0085,0x0083,0xCE54,0xCE53,0x0083,0xF2E9,0xCE52,0x0085,0x0083,0xCE51,0xF2E6,0x0083,0xCE50, 0xCE4F,0x0091,0x0089,0x0085,0x0083,0xF2E7,0xCE4E,0x0083,0xCE4D,0xF2E2,0x0085,0x0083,0xCE4C,0xCE4B,0x0083,0xCE4A, 0xCE49,0x0089,0x0085,0x0083,0xF2E8,0xCE48,0x0083,0xCE47,0xCE46,0x0085,0x0083,0xF2E1,0xCE45,0x0083,0xF2DE,0xF2EC, 0x00A1,0x0091,0x0089,0x0085,0x0083,0xC0AF,0xCE44,0x0083,0xCE43,0xF2E0,0x0085,0x0083,0xCE42,0xC3DB,0x0083,0xCE41, 0xF2E3,0x0089,0x0085,0x0083,0xCE40,0xD6A9,0x0083,0xCECF,0xCDA0,0x0085,0x0083,0xCDC9,0xCD9F,0x0083,0xF2D1,0xD1D1, 0x0091,0x0089,0x0085,0x0083,0xCD9E,0xCD9D,0x0083,0xCD9C,0xCD9B,0x0085,0x0083,0xF2DC,0xCD9A,0x0083,0xCD99,0xF2DB, 0x0089,0x0085,0x0083,0xF2DD,0xF2DA,0x0083,0xF2D8,0xCD98,0x0085,0x0083,0xCD97,0xCD96,0x0083,0xF2D7,0xB7E4,0x00C1, 0x00A1,0x0091,0x0089,0x0085,0x0083,0xCD95,0xCAF1,0x0083,0xCD94,0xB6EA,0x0085,0x0083,0xCD93,0xCD92,0x0083,0xCD91, 0xCD90,0x0089,0x0085,0x0083,0xD3BC,0xF2D9,0x0083,0xCD8F,0xCD8E,0x0085,0x0083,0xCD8D,0xF2D3,0x0083,0xF2CF,0xF2CD, 0x0091,0x0089,0x0085,0x0083,0xF2CC,0xD5DD,0x0083,0xCD8C,0xC2F9,0x0085,0x0083,0xF2CE,0xCD8B,0x0083,0xCD8A,0xCD89, 0x0089,0x0085,0x0083,0xF2CB,0xCD88,0x0083,0xCD87,0xCD86,0x0085,0x0083,0xCD85,0xB8F2,0x0083,0xCD84,0xCD83,0x00A1, 0x0091,0x0089,0x0085,0x0083,0xCD82,0xCD81,0x0083,0xF2D4,0xF2D2,0x0085,0x0083,0xCD80,0xCD7E,0x0083,0xD6EB,0xCD7D, 0x0089,0x0085,0x0083,0xCDDC,0xF2D5,0x0083,0xCD7C,0xCD7B,0x0085,0x0083,0xCD7A,0xBBD7,0x0083,0xCD79,0xCD78,0x0091, 0x0089,0x0085,0x0083,0xF2D6,0xF2D0,0x0083,0xF2C9,0xF2C3,0x0085,0x0083,0xCD77,0xCD76,0x0083,0xB5B0,0xB9C6,0x0089, 0x0085,0x0083,0xF2C8,0xCD75,0x0083,0xC9DF,0xC7F9,0x0085,0x0083,0xCD74,0xF2C1,0x0083,0xCD73,0xCD72,0x0101,0x00C1, 0x00A1,0x0091,0x0089,0x0085,0x0083,0xCD71,0xD6FB,0x0083,0xCD70,0xCD6F,0x0085,0x0083,0xCD6E,0xCD6D,0x0083,0xCD6C, 0xF2C5,0x0089,0x0085,0x0083,0xCD6B,0xCD6A,0x0083,0xCD69,0xF2C0,0x0085,0x0083,0xF2C2,0xF2CA,0x0083,0xCD68,0xCD67, 0x0091,0x0089,0x0085,0x0083,0xF2C6,0xF2C4,0x0083,0xF2C7,0xCD66,0x0085,0x0083,0xCD65,0xF2B9,0x0083,0xCD64,0xF2BD, 0x0089,0x0085,0x0083,0xF2BF,0xF2B6,0x0083,0xF2BB,0xCD63,0x0085,0x0083,0xCD62,0xD4E9,0x0083,0xF2BC,0xCD61,0x00A1, 0x0091,0x0089,0x0085,0x0083,0xCD60,0xCD5F,0x0083,0xCD5E,0xCD5D,0x0085,0x0083,0xF2BA,0xD1C1,0x0083,0xCD5C,0xCD5B, 0x0089,0x0085,0x0083,0xCD5A,0xCD59,0x0083,0xCD58,0xCD57,0x0085,0x0083,0xB2CF,0xCD56,0x0083,0xF2BE,0xCD55,0x0091, 0x0089,0x0085,0x0083,0xCD54,0xCD53,0x0083,0xCD52,0xCD51,0x0085,0x0083,0xF2B7,0xB0F6,0x0083,0xF2B8,0xCEC3,0x0089, 0x0085,0x0083,0xCD50,0xCD4F,0x0083,0xCD4E,0xCD4D,0x0085,0x0083,0xCD4C,0xCD4B,0x0083,0xCD4A,0xC2EC,0x00C1,0x00A1, 0x0091,0x0089,0x0085,0x0083,0xD2CF,0xCAB4,0x0083,0xF2B2,0xCFBA,0x0085,0x0083,0xCBE4,0xF2B4,0x0083,0xF2B5,0xF2B3, 0x0089,0x0085,0x0083,0xBAE7,0xCD49,0x0083,0xCD48,0xCD47,0x0085,0x0083,0xCD46,0xCD45,0x0083,0xCD44,0xCD43,0x0091, 0x0089,0x0085,0x0083,0xCAAD,0xCD42,0x0083,0xCD41,0xF2B1,0x0085,0x0083,0xCD40,0xF2B0,0x0083,0xB3E6,0xCCA0,0x0089, 0x0085,0x0083,0xCC9F,0xCC9E,0x0083,0xCC9D,0xCC9C,0x0085,0x0083,0xCC9B,0xCC9A,0x0083,0xCC99,0xEBBD,0x00A1,0x0091, 0x0089,0x0085,0x0083,0xCC98,0xCC97,0x0083,0xCC96,0xD3DD,0x0085,0x0083,0xCC95,0xCC94,0x0083,0xCC93,0xD0E9,0x0089, 0x0085,0x0083,0xCC92,0xCC91,0x0083,0xCC90,0xCC8F,0x0085,0x0083,0xCC8E,0xF2AF,0x0083,0xCC8D,0xCC8C,0x0091,0x0089, 0x0085,0x0083,0xC2C7,0xC5B0,0x0083,0xC2B2,0xBBA2,0x0085,0x0083,0xF2AE,0xCC8B,0x0083,0xCC8A,0xCC89,0x0089,0x0085, 0x0083,0xCC88,0xCC87,0x0083,0xCC86,0xCC85,0x0085,0x0083,0xCC84,0xCC83,0x0083,0xCC82,0xCC81,0x027F,0x017F,0x00FF, 0x00BF,0x009F,0x008F,0x0087,0x0083,0xCC80,0x0083,0xCC7E,0xCC7D,0x0085,0x0083,0xCC7C,0xCC7B,0x0083,0xDEC2,0xCC7A, 0x0089,0x0085,0x0083,0xCC79,0xCC78,0x0083,0xD5BA,0xCC77,0x0085,0x0083,0xCC76,0xCC75,0x0083,0xCC74,0xCC73,0x0091, 0x0089,0x0085,0x0083,0xCC72,0xCC71,0x0083,0xCC70,0xCC6F,0x0085,0x0083,0xCC6E,0xCC6D,0x0083,0xCC6C,0xCC6B,0x0089, 0x0085,0x0083,0xCC6A,0xDEC0,0x0083,0xCC69,0xDEBE,0x0085,0x0083,0xCC68,0xCC67,0x0083,0xCC66,0xCC65,0x00A1,0x0091, 0x0089,0x0085,0x0083,0xCC64,0xCC63,0x0083,0xCC62,0xCC61,0x0085,0x0083,0xCC60,0xCC5F,0x0083,0xCC5E,0xCC5D,0x0089, 0x0085,0x0083,0xCC5C,0xCC5B,0x0083,0xCC5A,0xCC59,0x0085,0x0083,0xDEC1,0xCC58,0x0083,0xCC57,0xCC56,0x0091,0x0089, 0x0085,0x0083,0xCC55,0xC4A2,0x0083,0xCC54,0xCC53,0x0085,0x0083,0xCC52,0xCC51,0x0083,0xCC50,0xCC4F,0x0089,0x0085, 0x0083,0xCC4E,0xCC4D,0x0083,0xCC4C,0xCC4B,0x0085,0x0083,0xCC4A,0xDEBF,0x0083,0xCC49,0xCC48,0x00C1,0x00A1,0x0091, 0x0089,0x0085,0x0083,0xCC47,0xCC46,0x0083,0xCC45,0xDEBD,0x0085,0x0083,0xCC44,0xCC43,0x0083,0xCC42,0xD4E5,0x0089, 0x0085,0x0083,0xCC41,0xCC40,0x0083,0xCBA0,0xCB9F,0x0085,0x0083,0xCB9E,0xCB9D,0x0083,0xCB9C,0xCB9B,0x0091,0x0089, 0x0085,0x0083,0xCB9A,0xCB99,0x0083,0xCB98,0xCB97,0x0085,0x0083,0xCB96,0xCB95,0x0083,0xCB94,0xCB93,0x0089,0x0085, 0x0083,0xCB92,0xB7AA,0x0083,0xCB91,0xCB90,0x0085,0x0083,0xCB8F,0xCB8E,0x0083,0xCCD9,0xCB8D,0x00A1,0x0091,0x0089, 0x0085,0x0083,0xCB8C,0xCB8B,0x0083,0xCB8A,0xCB89,0x0085,0x0083,0xCB88,0xCB87,0x0083,0xDEBC,0xCB86,0x0089,0x0085, 0x0083,0xCB85,0xCB84,0x0083,0xCB83,0xCB82,0x0085,0x0083,0xCB81,0xC5BA,0x0083,0xCB80,0xDEBA,0x0091,0x0089,0x0085, 0x0083,0xCB7E,0xCB7D,0x0083,0xC3EA,0xB2D8,0x0085,0x0083,0xCB7C,0xCB7B,0x0083,0xCB7A,0xCB79,0x0089,0x0085,0x0083, 0xCB78,0xBDE5,0x0083,0xCB77,0xCB76,0x0085,0x0083,0xCB75,0xCB74,0x0083,0xCB73,0xCB72,0x0101,0x00C1,0x00A1,0x0091, 0x0089,0x0085,0x0083,0xCB71,0xDEBB,0x0083,0xCB70,0xCB6F,0x0085,0x0083,0xCB6E,0xCB6D,0x0083,0xCB6C,0xCB6B,0x0089, 0x0085,0x0083,0xCB6A,0xDEB7,0x0083,0xCB69,0xDEB8,0x0085,0x0083,0xCB68,0xCB67,0x0083,0xCB66,0xCB65,0x0091,0x0089, 0x0085,0x0083,0xCB64,0xCB63,0x0083,0xDEB9,0xCAED,0x0085,0x0083,0xDEB4,0xCB62,0x0083,0xCB61,0xCB60,0x0089,0x0085, 0x0083,0xD0BD,0xCB5F,0x0083,0xDEB0,0xCB5E,0x0085,0x0083,0xCB5D,0xCB5C,0x0083,0xDEAF,0xCB5B,0x00A1,0x0091,0x0089, 0x0085,0x0083,0xCB5A,0xCB59,0x0083,0xCB58,0xCB57,0x0085,0x0083,0xCB56,0xCB55,0x0083,0xDEB5,0xD1A6,0x0089,0x0085, 0x0083,0xCB54,0xCB53,0x0083,0xCB52,0xCB51,0x0085,0x0083,0xCB50,0xCB4F,0x0083,0xCB4E,0xCB4D,0x0091,0x0089,0x0085, 0x0083,0xCB4C,0xCB4B,0x0083,0xCB4A,0xDEB2,0x0085,0x0083,0xCB49,0xCB48,0x0083,0xCB47,0xCB46,0x0089,0x0085,0x0083, 0xCB45,0xCB44,0x0083,0xCB43,0xDEB1,0x0085,0x0083,0xCB42,0xDEB6,0x0083,0xB1A1,0xCB41,0x00C1,0x00A1,0x0091,0x0089, 0x0085,0x0083,0xCB40,0xCAA0,0x0083,0xCA9F,0xCA9E,0x0085,0x0083,0xC0D9,0xCA9D,0x0083,0xCA9C,0xDEAE,0x0089,0x0085, 0x0083,0xDEAA,0xDEB3,0x0083,0xCA9B,0xCA9A,0x0085,0x0083,0xCA99,0xCA98,0x0083,0xD4CC,0xCA97,0x0091,0x0089,0x0085, 0x0083,0xDEAD,0xCA96,0x0083,0xCA95,0xCA94,0x0085,0x0083,0xCA93,0xCA92,0x0083,0xCA91,0xCA90,0x0089,0x0085,0x0083, 0xCA8F,0xCA8E,0x0083,0xDEA7,0xCA8D,0x0085,0x0083,0xCA8C,0xCA8B,0x0083,0xDEA8,0xCA8A,0x00A1,0x0091,0x0089,0x0085, 0x0083,0xCA89,0xCA88,0x0083,0xCA87,0xCA86,0x0085,0x0083,0xDEA9,0xCA85,0x0083,0xCA84,0xCA83,0x0089,0x0085,0x0083, 0xCA82,0xDEA5,0x0083,0xCA81,0xCA80,0x0085,0x0083,0xDEA1,0xCA7E,0x0083,0xCA7D,0xCA7C,0x0091,0x0089,0x0085,0x0083, 0xCA7B,0xCA7A,0x0083,0xCA79,0xCA78,0x0085,0x0083,0xCA77,0xCA76,0x0083,0xCA75,0xCA74,0x0089,0x0085,0x0083,0xC8EF, 0xBDB6,0x0083,0xDEA6,0xCA73,0x0085,0x0083,0xCA72,0xCA71,0x0083,0xCA70,0xDEAC,0x0181,0x0101,0x00C1,0x00A1,0x0091, 0x0089,0x0085,0x0083,0xCA6F,0xCA6E,0x0083,0xCA6D,0xCA6C,0x0085,0x0083,0xCA6B,0xB1CE,0x0083,0xB0AA,0xDEA2,0x0089, 0x0085,0x0083,0xDDFE,0xDDFC,0x0083,0xDDFA,0xC7BE,0x0085,0x0083,0xCA6A,0xCA69,0x0083,0xCA68,0xCA67,0x0091,0x0089, 0x0085,0x0083,0xCA66,0xCA65,0x0083,0xCA64,0xCA63,0x0085,0x0083,0xCA62,0xCA61,0x0083,0xCADF,0xC4E8,0x0089,0x0085, 0x0083,0xCA60,0xCA5F,0x0083,0xCA5E,0xCA5D,0x0085,0x0083,0xCA5C,0xCA5B,0x0083,0xCA5A,0xCA59,0x00A1,0x0091,0x0089, 0x0085,0x0083,0xCA58,0xB2CC,0x0083,0xCA57,0xDDFD,0x0085,0x0083,0xCA56,0xCA55,0x0083,0xCA54,0xCA53,0x0089,0x0085, 0x0083,0xCEB5,0xCA52,0x0083,0xCA51,0xD5E1,0x0085,0x0083,0xCA50,0xCA4F,0x0083,0xCA4E,0xC2FB,0x0091,0x0089,0x0085, 0x0083,0xCA4D,0xC3EF,0x0083,0xCA4C,0xCA4B,0x0085,0x0083,0xCA4A,0xCA49,0x0083,0xDDF8,0xCA48,0x0089,0x0085,0x0083, 0xCA47,0xCA46,0x0083,0xCA45,0xCA44,0x0085,0x0083,0xCA43,0xCA42,0x0083,0xCA41,0xCA40,0x00C1,0x00A1,0x0091,0x0089, 0x0085,0x0083,0xC9A0,0xC99F,0x0083,0xC99E,0xDEA3,0x0085,0x0083,0xC99D,0xC99C,0x0083,0xDEA4,0xC99B,0x0089,0x0085, 0x0083,0xC99A,0xC999,0x0083,0xC998,0xC997,0x0085,0x0083,0xC996,0xC995,0x0083,0xC994,0xC993,0x0091,0x0089,0x0085, 0x0083,0xC992,0xC991,0x0083,0xDDFB,0xC990,0x0085,0x0083,0xC98F,0xC98E,0x0083,0xC5EE,0xC98D,0x0089,0x0085,0x0083, 0xC98C,0xC98B,0x0083,0xC98A,0xC989,0x0085,0x0083,0xDDEB,0xDDF6,0x0083,0xC988,0xDDF7,0x00A1,0x0091,0x0089,0x0085, 0x0083,0xC987,0xC986,0x0083,0xDDF1,0xBCBB,0x0085,0x0083,0xC985,0xC0B6,0x0083,0xC984,0xC983,0x0089,0x0085,0x0083, 0xC982,0xC981,0x0083,0xC980,0xC97E,0x0085,0x0083,0xB1CD,0xC97D,0x0083,0xC97C,0xDDED,0x0091,0x0089,0x0085,0x0083, 0xC97B,0xCBF2,0x0083,0xDDEA,0xC97A,0x0085,0x0083,0xC979,0xDDE9,0x0083,0xC978,0xC977,0x0089,0x0085,0x0083,0xDDEE, 0xC8D8,0x0083,0xC976,0xC975,0x0085,0x0083,0xC974,0xC973,0x0083,0xD0EE,0xC972,0x0101,0x00C1,0x00A1,0x0091,0x0089, 0x0085,0x0083,0xC971,0xDDE8,0x0083,0xC970,0xDDEF,0x0085,0x0083,0xC96F,0xDDEC,0x0083,0xC96E,0xC96D,0x0089,0x0085, 0x0083,0xDDF0,0xDDF3,0x0083,0xD5F4,0xC96C,0x0085,0x0083,0xC96B,0xC96A,0x0083,0xDDF4,0xC969,0x0091,0x0089,0x0085, 0x0083,0xC6D1,0xC968,0x0083,0xC967,0xD8E1,0x0085,0x0083,0xC966,0xC965,0x0083,0xC964,0xC963,0x0089,0x0085,0x0083, 0xC962,0xC961,0x0083,0xC960,0xC95F,0x0085,0x0083,0xC95E,0xC95D,0x0083,0xC95C,0xC95B,0x00A1,0x0091,0x0089,0x0085, 0x0083,0xC95A,0xDDF2,0x0083,0xC959,0xC958,0x0085,0x0083,0xC957,0xC956,0x0083,0xCBE2,0xC955,0x0089,0x0085,0x0083, 0xC954,0xC3C9,0x0083,0xC953,0xDDF5,0x0085,0x0083,0xC952,0xC951,0x0083,0xC950,0xC94F,0x0091,0x0089,0x0085,0x0083, 0xC94E,0xC94D,0x0083,0xC94C,0xC94B,0x0085,0x0083,0xDDE5,0xC94A,0x0083,0xDDE4,0xBDAF,0x0089,0x0085,0x0083,0xC949, 0xDDDE,0x0083,0xDDDC,0xDDDB,0x0085,0x0083,0xC948,0xC947,0x0083,0xC946,0xC945,0x00C1,0x00A1,0x0091,0x0089,0x0085, 0x0083,0xB5D9,0xC944,0x0083,0xC943,0xC942,0x0085,0x0083,0xC941,0xC940,0x0083,0xC8A0,0xC89F,0x0089,0x0085,0x0083, 0xDDDD,0xC89E,0x0083,0xDDDF,0xC89D,0x0085,0x0083,0xDDE3,0xBFFB,0x0083,0xC89C,0xDDDA,0x0091,0x0089,0x0085,0x0083, 0xC89B,0xB4D0,0x0083,0xC89A,0xC899,0x0085,0x0083,0xC898,0xDDE7,0x0083,0xD4E1,0xBAF9,0x0089,0x0085,0x0083,0xC897, 0xDDE2,0x0083,0xC896,0xC895,0x0085,0x0083,0xC894,0xC893,0x0083,0xC892,0xB6AD,0x00A1,0x0091,0x0089,0x0085,0x0083, 0xC891,0xC6CF,0x0083,0xC890,0xC88F,0x0085,0x0083,0xC88E,0xC88D,0x0083,0xDDD6,0xB8F0,0x0089,0x0085,0x0083,0xDDD8, 0xDDD9,0x0083,0xC88C,0xD6F8,0x0085,0x0083,0xC88B,0xC88A,0x0083,0xC889,0xC888,0x0091,0x0089,0x0085,0x0083,0xC887, 0xDDD7,0x0083,0xC886,0xC885,0x0085,0x0083,0xC884,0xC883,0x0083,0xC882,0xC881,0x0089,0x0085,0x0083,0xC880,0xC87E, 0x0083,0xC87D,0xC87C,0x0085,0x0083,0xDDE1,0xC87B,0x0083,0xC87A,0xC879,0x047F,0x027F,0x017F,0x00FF,0x00BF,0x009F, 0x008F,0x0087,0x0083,0xC878,0x0083,0xC877,0xC876,0x0085,0x0083,0xC875,0xC874,0x0083,0xC2E4,0xDDE0,0x0089,0x0085, 0x0083,0xC873,0xC872,0x0083,0xC871,0xDDC7,0x0085,0x0083,0xC870,0xC86F,0x0083,0xC86E,0xC86D,0x0091,0x0089,0x0085, 0x0083,0xC86C,0xC86B,0x0083,0xDDE6,0xC86A,0x0085,0x0083,0xC869,0xC868,0x0083,0xC867,0xC866,0x0089,0x0085,0x0083, 0xC865,0xC864,0x0083,0xC863,0xC8F8,0x0085,0x0083,0xCFF4,0xDDD3,0x0083,0xD3AA,0xD3A9,0x00A1,0x0091,0x0089,0x0085, 0x0083,0xC862,0xC861,0x0083,0xC860,0xC85F,0x0085,0x0083,0xC85E,0xC85D,0x0083,0xC2DC,0xDDC6,0x0089,0x0085,0x0083, 0xC85C,0xC85B,0x0083,0xC85A,0xDDC1,0x0085,0x0083,0xC859,0xC858,0x0083,0xC857,0xC856,0x0091,0x0089,0x0085,0x0083, 0xC855,0xC854,0x0083,0xDDC8,0xC853,0x0085,0x0083,0xDDCC,0xCEAE,0x0083,0xC6BC,0xC3C8,0x0089,0x0085,0x0083,0xDDC2, 0xC852,0x0083,0xC851,0xC850,0x0085,0x0083,0xC84F,0xDDC9,0x0083,0xC84E,0xCCD1,0x00C1,0x00A1,0x0091,0x0089,0x0085, 0x0083,0xDDCD,0xC84D,0x0083,0xDDBD,0xC84C,0x0085,0x0083,0xC84B,0xC84A,0x0083,0xDDC4,0xC849,0x0089,0x0085,0x0083, 0xC848,0xC847,0x0083,0xDDCF,0xDDCE,0x0085,0x0083,0xC846,0xC845,0x0083,0xC844,0xC843,0x0091,0x0089,0x0085,0x0083, 0xC842,0xB7C6,0x0083,0xC1E2,0xDDD4,0x0085,0x0083,0xC841,0xC840,0x0083,0xC7A0,0xC79F,0x0089,0x0085,0x0083,0xC79E, 0xDDD0,0x0083,0xC6D0,0xC79D,0x0085,0x0083,0xC79C,0xC79B,0x0083,0xDDBE,0xC79A,0x00A1,0x0091,0x0089,0x0085,0x0083, 0xC799,0xC798,0x0083,0xDDD5,0xB2A4,0x0085,0x0083,0xDDCB,0xC797,0x0083,0xDDC3,0xB2CB,0x0089,0x0085,0x0083,0xC796, 0xC795,0x0083,0xC794,0xDDBF,0x0085,0x0083,0xC793,0xDDC5,0x0083,0xC792,0xDDCA,0x0091,0x0089,0x0085,0x0083,0xC791, 0xC790,0x0083,0xC78F,0xC78E,0x0085,0x0083,0xBACA,0xC78D,0x0083,0xC78C,0xBEFA,0x0089,0x0085,0x0083,0xC78B,0xBED5, 0x0083,0xC78A,0xC789,0x0085,0x0083,0xB9BD,0xC788,0x0083,0xDDD1,0xC787,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085, 0x0083,0xC786,0xC785,0x0083,0xDDBC,0xDDD2,0x0085,0x0083,0xC784,0xC783,0x0083,0xC3A7,0xDDBB,0x0089,0x0085,0x0083, 0xC782,0xDDBA,0x0083,0xD3A8,0xDDB5,0x0085,0x0083,0xBBF1,0xDDB2,0x0083,0xC781,0xDDAB,0x0091,0x0089,0x0085,0x0083, 0xDDAA,0xC1AB,0x0083,0xC0B3,0xDDA8,0x0085,0x0083,0xC780,0xC77E,0x0083,0xC77D,0xC77C,0x0089,0x0085,0x0083,0xC4AA, 0xDDAD,0x0083,0xDDB3,0xDDB9,0x0085,0x0083,0xC77B,0xC77A,0x0083,0xC779,0xC778,0x00A1,0x0091,0x0089,0x0085,0x0083, 0xC777,0xC776,0x0083,0xC775,0xDDAC,0x0085,0x0083,0xC774,0xDDB8,0x0083,0xC773,0xDDAF,0x0089,0x0085,0x0083,0xDCF0, 0xC772,0x0083,0xC771,0xDDB7,0x0085,0x0083,0xC770,0xC76F,0x0083,0xC76E,0xC76D,0x0091,0x0089,0x0085,0x0083,0xDDAE, 0xDCEC,0x0083,0xC76C,0xC76B,0x0085,0x0083,0xC76A,0xC9AF,0x0083,0xC769,0xC768,0x0089,0x0085,0x0083,0xC767,0xC766, 0x0083,0xC0F2,0xC765,0x0085,0x0083,0xC764,0xC6CE,0x0083,0xDDB0,0xC763,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083, 0xC762,0xC761,0x0083,0xC760,0xC75F,0x0085,0x0083,0xC75E,0xC75D,0x0083,0xDDB4,0xDDB1,0x0089,0x0085,0x0083,0xDDB6, 0xC75C,0x0083,0xC75B,0xDDA9,0x0085,0x0083,0xBAC9,0xC75A,0x0083,0xC759,0xC758,0x0091,0x0089,0x0085,0x0083,0xC757, 0xC756,0x0083,0xC755,0xC754,0x0085,0x0083,0xD2A9,0xDDA7,0x0083,0xDDA6,0xDDA4,0x0089,0x0085,0x0083,0xD2F1,0xDDA5, 0x0083,0xDDA3,0xDDA1,0x0085,0x0083,0xD3AB,0xDCFD,0x0083,0xDCFE,0xBBE7,0x00A1,0x0091,0x0089,0x0085,0x0083,0xC8D9, 0xC753,0x0083,0xB5B4,0xDCF9,0x0085,0x0083,0xDCF6,0xDCF1,0x0083,0xC752,0xDCEA,0x0089,0x0085,0x0083,0xDCE9,0xBCD4, 0x0083,0xC751,0xC750,0x0085,0x0083,0xC74F,0xC74E,0x0083,0xC74D,0xC0F3,0x0091,0x0089,0x0085,0x0083,0xC74C,0xBBC4, 0x0083,0xDCE8,0xBCF6,0x0085,0x0083,0xDCF3,0xC74B,0x0083,0xC74A,0xC749,0x0089,0x0085,0x0083,0xC748,0xC747,0x0083, 0xB2DD,0xC746,0x0085,0x0083,0xDCF4,0xBEA3,0x0083,0xC745,0xC744,0x0181,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085, 0x0083,0xDCF5,0xC743,0x0083,0xC742,0xDCF7,0x0085,0x0083,0xC741,0xC740,0x0083,0xC6A0,0xDCED,0x0089,0x0085,0x0083, 0xC69F,0xDCFB,0x0083,0xC8E3,0xC8D7,0x0085,0x0083,0xC69E,0xB2E8,0x0083,0xD2F0,0xDCEE,0x0091,0x0089,0x0085,0x0083, 0xDCFC,0xC69D,0x0083,0xDCEF,0xC69C,0x0085,0x0083,0xDCF2,0xC69B,0x0083,0xDCFA,0xB2E7,0x0089,0x0085,0x0083,0xC3A3, 0xC69A,0x0083,0xC699,0xB4C4,0x0085,0x0083,0xBCEB,0xC698,0x0083,0xC697,0xC696,0x00A1,0x0091,0x0089,0x0085,0x0083, 0xC695,0xC694,0x0083,0xC693,0xC692,0x0085,0x0083,0xC691,0xC690,0x0083,0xC68F,0xDCE7,0x0089,0x0085,0x0083,0xDDA2, 0xDCE1,0x0083,0xC68E,0xC68D,0x0085,0x0083,0xDCF8,0xC68C,0x0083,0xDCE4,0xDCE3,0x0091,0x0089,0x0085,0x0083,0xC68B, 0xC68A,0x0083,0xDCE0,0xC689,0x0085,0x0083,0xDCD7,0xBEA5,0x0083,0xC688,0xDCDD,0x0089,0x0085,0x0083,0xC687,0xC686, 0x0083,0xDCD4,0xDCEB,0x0085,0x0083,0xDCD8,0xDCE2,0x0083,0xC3A9,0xC7D1,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083, 0xB7B6,0xC3AF,0x0083,0xD7C2,0xC685,0x0085,0x0083,0xC684,0xC683,0x0083,0xC682,0xC681,0x0089,0x0085,0x0083,0xDCDE, 0xC680,0x0083,0xC6BB,0xC67E,0x0085,0x0083,0xDCD5,0xC67D,0x0083,0xC67C,0xDCDA,0x0091,0x0089,0x0085,0x0083,0xC67B, 0xC67A,0x0083,0xD3A2,0xC679,0x0085,0x0083,0xB1BD,0xC678,0x0083,0xC677,0xC676,0x0089,0x0085,0x0083,0xC9BB,0xC675, 0x0083,0xC674,0xC673,0x0085,0x0083,0xC672,0xBFE0,0x0083,0xC8F4,0xDCD6,0x00A1,0x0091,0x0089,0x0085,0x0083,0xDCC4, 0xC671,0x0083,0xDCD3,0xDCE5,0x0085,0x0083,0xB9B6,0xB0FA,0x0083,0xC670,0xDCD9,0x0089,0x0085,0x0083,0xBFC1,0xC66F, 0x0083,0xC66E,0xDCDC,0x0085,0x0083,0xC3E7,0xC66D,0x0083,0xDCE6,0xCCA6,0x0091,0x0089,0x0085,0x0083,0xDCDF,0xDCDB, 0x0083,0xD4B7,0xC66C,0x0085,0x0083,0xCBD5,0xDCD1,0x0083,0xB2D4,0xDCC9,0x0089,0x0085,0x0083,0xDCC8,0xDCC3,0x0083, 0xC66B,0xDCC2,0x0085,0x0083,0xCEAD,0xC66A,0x0083,0xC669,0xDCD0,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083, 0xC668,0xC667,0x0083,0xDCCA,0xC666,0x0085,0x0083,0xC665,0xDCC0,0x0083,0xD1BF,0xC664,0x0089,0x0085,0x0083,0xC663, 0xC662,0x0083,0xC7DB,0xDCBF,0x0085,0x0083,0xDCC6,0xC661,0x0083,0xC660,0xDCCC,0x0091,0x0089,0x0085,0x0083,0xB7BC, 0xC65F,0x0083,0xBBA8,0xDCC1,0x0085,0x0083,0xD0BE,0xDCC7,0x0083,0xB0C5,0xB7D2,0x0089,0x0085,0x0083,0xDCBE,0xDCCE, 0x0083,0xDCCB,0xDCB8,0x0085,0x0083,0xC65E,0xC2AB,0x0083,0xBDE6,0xDCD2,0x00A1,0x0091,0x0089,0x0085,0x0083,0xC65D, 0xC65C,0x0083,0xDCCD,0xC65B,0x0085,0x0083,0xDCCF,0xC65A,0x0083,0xD6A5,0xCEDF,0x0089,0x0085,0x0083,0xC659,0xC658, 0x0083,0xDCBD,0xDCC5,0x0085,0x0083,0xDCBC,0xC657,0x0083,0xC656,0xC655,0x0091,0x0089,0x0085,0x0083,0xC654,0xC3A2, 0x0083,0xDCBB,0xC653,0x0085,0x0083,0xDCB6,0xDCBA,0x0083,0xC9D6,0xC652,0x0089,0x0085,0x0083,0xD3F3,0xDCB7,0x0083, 0xC651,0xD8C2,0x0085,0x0083,0xC650,0xC64F,0x0083,0xC64E,0xDCB9,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xC64D, 0xBDDA,0x0083,0xC64C,0xC64B,0x0085,0x0083,0xDCB5,0xB0AC,0x0083,0xDCB4,0xC64A,0x0089,0x0085,0x0083,0xC649,0xD2D5, 0x0083,0xDCB3,0xC648,0x0085,0x0083,0xC647,0xC646,0x0083,0xC645,0xE5F5,0x0091,0x0089,0x0085,0x0083,0xD1DE,0xC9AB, 0x0083,0xC644,0xBCE8,0x0085,0x0083,0xC1BC,0xF4DE,0x0083,0xC643,0xC642,0x0089,0x0085,0x0083,0xC641,0xC640,0x0083, 0xC5A0,0xF4BF,0x0085,0x0083,0xC59F,0xC59E,0x0083,0xC59D,0xC59C,0x00A1,0x0091,0x0089,0x0085,0x0083,0xC59B,0xC59A, 0x0083,0xC599,0xC598,0x0085,0x0083,0xF4BE,0xC597,0x0083,0xC596,0xC595,0x0089,0x0085,0x0083,0xC594,0xF4BD,0x0083, 0xC593,0xCBD2,0x0085,0x0083,0xC592,0xC591,0x0083,0xC590,0xC58F,0x0091,0x0089,0x0085,0x0083,0xC58E,0xC58D,0x0083, 0xC58C,0xC58B,0x0085,0x0083,0xF4BC,0xC58A,0x0083,0xC589,0xC588,0x0089,0x0085,0x0083,0xF4BB,0xC587,0x0083,0xF4BA, 0xC586,0x0085,0x0083,0xCDA7,0xC585,0x0083,0xC584,0xF4B9,0x027F,0x017F,0x00FF,0x00BF,0x009F,0x008F,0x0087,0x0083, 0xC583,0x0083,0xC582,0xC581,0x0085,0x0083,0xC580,0xC57E,0x0083,0xF4B8,0xC57D,0x0089,0x0085,0x0083,0xC57C,0xF4B5, 0x0083,0xC57B,0xB4AC,0x0085,0x0083,0xF4B4,0xCFCF,0x0083,0xB2B0,0xB6E6,0x0091,0x0089,0x0085,0x0083,0xF4B7,0xF4B6, 0x0083,0xC57A,0xB2D5,0x0085,0x0083,0xBDA2,0xF4B1,0x0083,0xC579,0xF4B0,0x0089,0x0085,0x0083,0xB0E3,0xF4B3,0x0083, 0xBABD,0xC578,0x0085,0x0083,0xF4B2,0xC577,0x0083,0xC576,0xC575,0x00A1,0x0091,0x0089,0x0085,0x0083,0xC574,0xF4AF, 0x0083,0xF4AE,0xF4AD,0x0085,0x0083,0xC573,0xD6DB,0x0083,0xCEE8,0xC572,0x0089,0x0085,0x0083,0xCBB4,0xE2B6,0x0083, 0xC571,0xC570,0x0085,0x0083,0xC56F,0xC56E,0x0083,0xC56D,0xC56C,0x0091,0x0089,0x0085,0x0083,0xCCF2,0xC56B,0x0083, 0xCAE6,0xC56A,0x0085,0x0083,0xF3C2,0xC569,0x0083,0xC568,0xC9E1,0x0089,0x0085,0x0083,0xC9E0,0xC567,0x0083,0xC566, 0xC565,0x0085,0x0083,0xC564,0xC563,0x0083,0xD3DF,0xBECB,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xF4AA,0xC562, 0x0083,0xF4A9,0xF4A8,0x0085,0x0083,0xD2A8,0xC561,0x0083,0xF4A7,0xC560,0x0089,0x0085,0x0083,0xBECA,0xD5E9,0x0083, 0xC55F,0xC55E,0x0085,0x0083,0xC55D,0xC55C,0x0083,0xC55B,0xC55A,0x0091,0x0089,0x0085,0x0083,0xD6C2,0xD6C1,0x0083, 0xC559,0xC558,0x0085,0x0083,0xC557,0xC556,0x0083,0xC555,0xB3F4,0x0089,0x0085,0x0083,0xF4AB,0xC554,0x0083,0xD7D4, 0xC553,0x0085,0x0083,0xC552,0xEAB0,0x0083,0xC551,0xC550,0x00A1,0x0091,0x0089,0x0085,0x0083,0xC54F,0xB3BC,0x0083, 0xC54E,0xC54D,0x0085,0x0083,0xC54C,0xC54B,0x0083,0xC54A,0xC549,0x0089,0x0085,0x0083,0xC548,0xC547,0x0083,0xC546, 0xC545,0x0085,0x0083,0xC544,0xC543,0x0083,0xC542,0xC541,0x0091,0x0089,0x0085,0x0083,0xC540,0xC4A0,0x0083,0xC49F, 0xC49E,0x0085,0x0083,0xC49D,0xC49C,0x0083,0xC49B,0xC49A,0x0089,0x0085,0x0083,0xEBFB,0xC499,0x0083,0xEBFD,0xC498, 0x0085,0x0083,0xC497,0xC496,0x0083,0xD2DC,0xC495,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xC494,0xD3B7, 0x0083,0xB1DB,0xECA1,0x0085,0x0083,0xCDCE,0xC493,0x0083,0xC492,0xC491,0x0089,0x0085,0x0083,0xC490,0xEBFE,0x0083, 0xE2DF,0xC48F,0x0085,0x0083,0xC48E,0xC48D,0x0083,0xC48C,0xC48B,0x0091,0x0089,0x0085,0x0083,0xC48A,0xC9C5,0x0083, 0xC489,0xC488,0x0085,0x0083,0xC487,0xC486,0x0083,0xC485,0xC484,0x0089,0x0085,0x0083,0xC483,0xC482,0x0083,0xEBFA, 0xC481,0x0085,0x0083,0xC5F2,0xC480,0x0083,0xECA2,0xC47E,0x00A1,0x0091,0x0089,0x0085,0x0083,0xC47D,0xEBF9,0x0083, 0xC47C,0xC47B,0x0085,0x0083,0xC47A,0xC479,0x0083,0xC478,0xCFA5,0x0089,0x0085,0x0083,0xC4A4,0xCCC5,0x0083,0xC477, 0xC476,0x0085,0x0083,0xB1EC,0xC475,0x0083,0xC474,0xC473,0x0091,0x0089,0x0085,0x0083,0xC472,0xC471,0x0083,0xC470, 0xEBF7,0x0085,0x0083,0xC46F,0xB8E0,0x0083,0xC46E,0xC46D,0x0089,0x0085,0x0083,0xC46C,0xC46B,0x0083,0xB2B2,0xC46A, 0x0085,0x0083,0xEBF5,0xC469,0x0083,0xC468,0xC467,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xC466,0xC465,0x0083, 0xEBF6,0xC464,0x0085,0x0083,0xB0F2,0xCDC8,0x0083,0xCCDA,0xEBF0,0x0089,0x0085,0x0083,0xEBEF,0xC4E5,0x0083,0xCFD9, 0xB8B9,0x0085,0x0083,0xC463,0xC462,0x0083,0xC461,0xC460,0x0091,0x0089,0x0085,0x0083,0xEBE9,0xC45F,0x0083,0xC45E, 0xEBEC,0x0085,0x0083,0xD1FC,0xC45D,0x0083,0xC8F9,0xEBF1,0x0089,0x0085,0x0083,0xC45C,0xC45B,0x0083,0xC45A,0xEBEE, 0x0085,0x0083,0xC459,0xEBF2,0x0083,0xC458,0xD0C8,0x00A1,0x0091,0x0089,0x0085,0x0083,0xC457,0xC456,0x0083,0xC455, 0xC454,0x0085,0x0083,0xEBED,0xC453,0x0083,0xC452,0xC451,0x0089,0x0085,0x0083,0xC450,0xC44F,0x0083,0xEBEB,0xEBEA, 0x0085,0x0083,0xC44E,0xC44D,0x0083,0xC44C,0xCDF3,0x0091,0x0089,0x0085,0x0083,0xC7BB,0xEBE8,0x0083,0xC44B,0xB8AD, 0x0085,0x0083,0xB8AF,0xC44A,0x0083,0xC449,0xC448,0x0089,0x0085,0x0083,0xEBE7,0xD2B8,0x0083,0xC0B0,0xC447,0x0085, 0x0083,0xEBE6,0xC446,0x0083,0xCCF3,0xC445,0x0181,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xC444,0xC443, 0x0083,0xC442,0xC441,0x0085,0x0083,0xC440,0xC3A0,0x0083,0xC6A2,0xC39F,0x0089,0x0085,0x0083,0xC39E,0xC39D,0x0083, 0xC39C,0xC39B,0x0085,0x0083,0xC1B3,0xC39A,0x0083,0xEBE1,0xC399,0x0091,0x0089,0x0085,0x0083,0xC398,0xC397,0x0083, 0xEBE5,0xCDD1,0x0085,0x0083,0xC396,0xB8AC,0x0083,0xC395,0xC394,0x0089,0x0085,0x0083,0xEBE3,0xC393,0x0083,0xC392, 0xC391,0x0085,0x0083,0xC390,0xC38F,0x0083,0xC38E,0xC38D,0x00A1,0x0091,0x0089,0x0085,0x0083,0xC38C,0xC38B,0x0083, 0xC38A,0xC389,0x0085,0x0083,0xC388,0xC387,0x0083,0xEBE2,0xC386,0x0089,0x0085,0x0083,0xC385,0xC384,0x0083,0xBDC5, 0xC383,0x0085,0x0083,0xEBE4,0xC382,0x0083,0xB2B1,0xC381,0x0091,0x0089,0x0085,0x0083,0xD9F5,0xC5A7,0x0083,0xEBDF, 0xC4D4,0x0085,0x0083,0xC6EA,0xD4E0,0x0083,0xEBDB,0xEBDA,0x0089,0x0085,0x0083,0xC380,0xC37E,0x0083,0xBCB9,0xC2F6, 0x0085,0x0083,0xC37D,0xC37C,0x0083,0xB4E0,0xC37B,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xC37A,0xC379,0x0083, 0xD6AC,0xC378,0x0085,0x0083,0xC377,0xC376,0x0083,0xC375,0xC4DC,0x0089,0x0085,0x0083,0xEBDD,0xC374,0x0083,0xB0B7, 0xC373,0x0085,0x0083,0xD0D8,0xC372,0x0083,0xBDBA,0xC371,0x0091,0x0089,0x0085,0x0083,0xEBD8,0xB8EC,0x0083,0xEBDC, 0xEBD7,0x0085,0x0083,0xD2C8,0xBFE8,0x0083,0xC370,0xEBD9,0x0089,0x0085,0x0083,0xE6C0,0xEBD6,0x0083,0xEBCD,0xEBCC, 0x0085,0x0083,0xEBCB,0xEBCA,0x0083,0xC36F,0xF1E3,0x00A1,0x0091,0x0089,0x0085,0x0083,0xD8B7,0xC36E,0x0083,0xC36D, 0xBAFA,0x0085,0x0083,0xC36C,0xC36B,0x0083,0xB0FB,0xEBD5,0x0089,0x0085,0x0083,0xCAA4,0xEBCE,0x0083,0xC5DF,0xEBD1, 0x0085,0x0083,0xC36A,0xEBD3,0x0083,0xC5D6,0xC369,0x0091,0x0089,0x0085,0x0083,0xC368,0xC367,0x0083,0xC366,0xC365, 0x0085,0x0083,0xC364,0xC363,0x0083,0xCCA5,0xEBD2,0x0089,0x0085,0x0083,0xB1B3,0xC362,0x0083,0xC361,0xC360,0x0085, 0x0083,0xC35F,0xC35E,0x0083,0xB5A8,0xC35D,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xEBD0,0xCEB8,0x0083, 0xEBCF,0xD0B2,0x0085,0x0083,0xD5CD,0xD6D7,0x0083,0xC9F6,0xEBC4,0x0089,0x0085,0x0083,0xEBC2,0xC35C,0x0083,0xB7CE, 0xC35B,0x0085,0x0083,0xC35A,0xEBC9,0x0083,0xC359,0xC358,0x0091,0x0089,0x0085,0x0083,0xEBC8,0xC357,0x0083,0xD3FD, 0xEBC5,0x0085,0x0083,0xC356,0xBFCF,0x0083,0xB0B9,0xEBC7,0x0089,0x0085,0x0083,0xC355,0xEBC6,0x0083,0xB7BE,0xBCE7, 0x0085,0x0083,0xC354,0xC353,0x0083,0xC352,0xB7CA,0x00A1,0x0091,0x0089,0x0085,0x0083,0xB7F4,0xC351,0x0083,0xD6AB, 0xB9C9,0x0085,0x0083,0xB3A6,0xEBBF,0x0083,0xC350,0xB8CE,0x0089,0x0085,0x0083,0xEBC0,0xB8D8,0x0083,0xB6C7,0xC34F, 0x0085,0x0083,0xD6E2,0xC34E,0x0083,0xD0A4,0xC34D,0x0091,0x0089,0x0085,0x0083,0xC34C,0xEBC1,0x0083,0xC34B,0xC34A, 0x0085,0x0083,0xC349,0xC348,0x0083,0xC347,0xC346,0x0089,0x0085,0x0083,0xBCA1,0xC0DF,0x0083,0xC345,0xC8E2,0x0085, 0x0083,0xC344,0xD5D8,0x0083,0xCBC1,0xC343,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xD2DE,0xCBE0,0x0083,0xC342, 0xC341,0x0085,0x0083,0xEDB1,0xEDB2,0x0083,0xC340,0xC2A0,0x0089,0x0085,0x0083,0xC29F,0xC29E,0x0083,0xC29D,0xC29C, 0x0085,0x0083,0xC29B,0xC29A,0x0083,0xC299,0xC298,0x0091,0x0089,0x0085,0x0083,0xC297,0xC296,0x0083,0xC295,0xF1FA, 0x0085,0x0083,0xC294,0xC293,0x0083,0xC292,0xC291,0x0089,0x0085,0x0083,0xC290,0xC28F,0x0083,0xB4CF,0xF1F9,0x0085, 0x0083,0xC28E,0xC28D,0x0083,0xC28C,0xC28B,0x00A1,0x0091,0x0089,0x0085,0x0083,0xC28A,0xC289,0x0083,0xC288,0xC287, 0x0085,0x0083,0xC286,0xC285,0x0083,0xC284,0xC283,0x0089,0x0085,0x0083,0xC282,0xC281,0x0083,0xBEDB,0xC280,0x0085, 0x0083,0xC6B8,0xC27E,0x0083,0xC27D,0xC27C,0x0091,0x0089,0x0085,0x0083,0xC1AA,0xC27B,0x0083,0xF1F8,0xC27A,0x0085, 0x0083,0xC279,0xC278,0x0083,0xC277,0xF1F7,0x0089,0x0085,0x0083,0xD6B0,0xC1FB,0x0083,0xC1C4,0xC276,0x0085,0x0083, 0xC275,0xC274,0x0083,0xF1F6,0xC273,0x6511,0x4051,0x2069,0x1075,0x087B,0x047D,0x027F,0x017F,0x00FF,0x00BF,0x009F, 0x008F,0x0087,0x0083,0xC272,0x0083,0xF1F5,0xC4F4,0x0085,0x0083,0xC271,0xC270,0x0083,0xB9A2,0xC26F,0x0089,0x0085, 0x0083,0xB5A2,0xC26E,0x0083,0xB3DC,0xC26D,0x0085,0x0083,0xC26C,0xCBCA,0x0083,0xDEC7,0xD2AE,0x0091,0x0089,0x0085, 0x0083,0xF1F4,0xC26B,0x0083,0xB6FA,0xC26A,0x0085,0x0083,0xF1F2,0xC269,0x0083,0xC268,0xC267,0x0089,0x0085,0x0083, 0xC266,0xC265,0x0083,0xC264,0xC5D5,0x0085,0x0083,0xF1F0,0xF1F1,0x0083,0xF1EF,0xF1EE,0x00A1,0x0091,0x0089,0x0085, 0x0083,0xF1ED,0xC263,0x0083,0xC262,0xF1EC,0x0085,0x0083,0xC261,0xF1EB,0x0083,0xC260,0xC25F,0x0089,0x0085,0x0083, 0xC25E,0xF1EA,0x0083,0xC25D,0xC25C,0x0085,0x0083,0xB0D2,0xD4C5,0x0083,0xBAC4,0xF1E9,0x0091,0x0089,0x0085,0x0083, 0xB8FB,0xF1E8,0x0083,0xC25B,0xF1E7,0x0085,0x0083,0xC25A,0xC4CD,0x0083,0xC259,0xC258,0x0089,0x0085,0x0083,0xCBA3, 0xB6F8,0x0083,0xF1F3,0xC257,0x0085,0x0083,0xC256,0xC255,0x0083,0xC254,0xEAC8,0x00C1,0x00A1,0x0091,0x0089,0x0085, 0x0083,0xD5DF,0xEBA3,0x0083,0xBFBC,0xC253,0x0085,0x0083,0xC0CF,0xD2AB,0x0083,0xC252,0xC251,0x0089,0x0085,0x0083, 0xC250,0xD2ED,0x0083,0xB7AD,0xC24F,0x0085,0x0083,0xC24E,0xC24D,0x0083,0xC24C,0xC24B,0x0091,0x0089,0x0085,0x0083, 0xC24A,0xC249,0x0083,0xF4E8,0xC248,0x0085,0x0083,0xB0BF,0xBAB2,0x0083,0xC247,0xF4E7,0x0089,0x0085,0x0083,0xC246, 0xC245,0x0083,0xC244,0xC243,0x0085,0x0083,0xF4E6,0xC242,0x0083,0xC241,0xF4E5,0x00A1,0x0091,0x0089,0x0085,0x0083, 0xF4E3,0xC240,0x0083,0xC1A0,0xC19F,0x0085,0x0083,0xF4E4,0xB4E4,0x0083,0xB5D4,0xC19E,0x0089,0x0085,0x0083,0xC19D, 0xC19C,0x0083,0xC19B,0xC19A,0x0085,0x0083,0xC199,0xC7CC,0x0083,0xC198,0xC197,0x0091,0x0089,0x0085,0x0083,0xF4E2, 0xCFE8,0x0083,0xC196,0xC195,0x0085,0x0083,0xC194,0xC193,0x0083,0xC192,0xF4E1,0x0089,0x0085,0x0083,0xC191,0xD2EE, 0x0083,0xC190,0xF1B4,0x0085,0x0083,0xC18F,0xC18E,0x0083,0xC18D,0xC18C,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085, 0x0083,0xB3E1,0xC18B,0x0083,0xC18A,0xC189,0x0085,0x0083,0xCECC,0xC188,0x0083,0xF4E0,0xC187,0x0089,0x0085,0x0083, 0xD3F0,0xE5F1,0x0083,0xC186,0xC185,0x0085,0x0083,0xB8FE,0xD9FA,0x0083,0xC184,0xC183,0x0091,0x0089,0x0085,0x0083, 0xC182,0xC181,0x0083,0xC180,0xF4CB,0x0085,0x0083,0xC17E,0xF4CA,0x0083,0xF4C9,0xC17D,0x0089,0x0085,0x0083,0xC17C, 0xC17B,0x0083,0xC17A,0xC179,0x0085,0x0083,0xC178,0xC177,0x0083,0xF4C8,0xC176,0x00A1,0x0091,0x0089,0x0085,0x0083, 0xC175,0xC8BA,0x0083,0xC174,0xC173,0x0085,0x0083,0xCFDB,0xC172,0x0083,0xF4C7,0xD0DF,0x0089,0x0085,0x0083,0xF4C6, 0xC171,0x0083,0xC170,0xC1E7,0x0085,0x0083,0xC16F,0xC16E,0x0083,0xC16D,0xC16C,0x0091,0x0089,0x0085,0x0083,0xC16B, 0xB8E1,0x0083,0xC16A,0xC169,0x0085,0x0083,0xC168,0xC167,0x0083,0xC166,0xC3C0,0x0089,0x0085,0x0083,0xC165,0xC7BC, 0x0083,0xC164,0xD1F2,0x0085,0x0083,0xC163,0xC162,0x0083,0xC161,0xC160,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083, 0xC15F,0xC15E,0x0083,0xC15D,0xC15C,0x0085,0x0083,0xEEBF,0xC15B,0x0083,0xC15A,0xEEC0,0x0089,0x0085,0x0083,0xC159, 0xC158,0x0083,0xC157,0xC156,0x0085,0x0083,0xEEBE,0xC155,0x0083,0xC154,0xC153,0x0091,0x0089,0x0085,0x0083,0xC152, 0xEEBC,0x0083,0xC151,0xCAF0,0x0085,0x0083,0xEEBD,0xC150,0x0083,0xC14F,0xD6C3,0x0089,0x0085,0x0083,0xC14E,0xC14D, 0x0083,0xC14C,0xD7EF,0x0085,0x0083,0xD5D6,0xEEBB,0x0083,0xC14B,0xC14A,0x00A1,0x0091,0x0089,0x0085,0x0083,0xC149, 0xC148,0x0083,0xC147,0xB0D5,0x0085,0x0083,0xEEB8,0xC146,0x0083,0xEEB9,0xC145,0x0089,0x0085,0x0083,0xC144,0xC143, 0x0083,0xC142,0xB7A3,0x0085,0x0083,0xC141,0xEEB7,0x0083,0xC2DE,0xC140,0x0091,0x0089,0x0085,0x0083,0xBAB1,0xD8E8, 0x0083,0xC0A0,0xC09F,0x0085,0x0083,0xCDF8,0xB9DE,0x0083,0xC09E,0xC09D,0x0089,0x0085,0x0083,0xC09C,0xC09B,0x0083, 0xC09A,0xC099,0x0085,0x0083,0xC098,0xC097,0x0083,0xC096,0xC095,0x017F,0x00FF,0x00BF,0x009F,0x008F,0x0087,0x0083, 0xF3C1,0x0083,0xF3C0,0xC094,0x0085,0x0083,0xF3BF,0xC093,0x0083,0xC092,0xC091,0x0089,0x0085,0x0083,0xC090,0xC08F, 0x0083,0xC08E,0xC08D,0x0085,0x0083,0xC8B1,0xC08C,0x0083,0xB8D7,0xC08B,0x0091,0x0089,0x0085,0x0083,0xF3BE,0xE7DA, 0x0083,0xBDC9,0xE7D9,0x0085,0x0083,0xE7D8,0xE7D7,0x0083,0xE7D6,0xE7D5,0x0089,0x0085,0x0083,0xC9C9,0xE7D4,0x0083, 0xE7D3,0xE7D2,0x0085,0x0083,0xE7D1,0xCBF5,0x0083,0xD3A7,0xE7D0,0x00A1,0x0091,0x0089,0x0085,0x0083,0xE7CF,0xE7CE, 0x0083,0xE7CD,0xE7CC,0x0085,0x0083,0xE7CB,0xE7CA,0x0083,0xB2F8,0xE7C9,0x0089,0x0085,0x0083,0xC08A,0xB7EC,0x0083, 0xE7C7,0xE7C8,0x0085,0x0083,0xB8BF,0xE7C6,0x0083,0xD4B5,0xE7C5,0x0091,0x0089,0x0085,0x0083,0xB1E0,0xC2C6,0x0083, 0xB5DE,0xBBBA,0x0085,0x0083,0xE7C4,0xE7C3,0x0083,0xC089,0xE7C2,0x0089,0x0085,0x0083,0xB6D0,0xE7B6,0x0083,0xE7C1, 0xE7C0,0x0085,0x0083,0xC088,0xBCA9,0x0083,0xE7BF,0xE7BE,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xC0C2,0xC3E5, 0x0083,0xBCEA,0xE7BD,0x0085,0x0083,0xE7BC,0xE7BB,0x0083,0xD7BA,0xC2CC,0x0089,0x0085,0x0083,0xE7BA,0xD5C0,0x0083, 0xD7DB,0xE7B9,0x0085,0x0083,0xE7B8,0xC087,0x0083,0xB3F1,0xB1C1,0x0091,0x0089,0x0085,0x0083,0xE7B7,0xC3E0,0x0083, 0xCEAC,0xC9FE,0x0085,0x0083,0xE7B5,0xE7B4,0x0083,0xB4C2,0xE7B3,0x0089,0x0085,0x0083,0xE7B2,0xD0F8,0x0083,0xC086, 0xE7B1,0x0085,0x0083,0xD0F7,0xBCA8,0x0083,0xE7B0,0xBCCC,0x00A1,0x0091,0x0089,0x0085,0x0083,0xCCD0,0xCBE7,0x0083, 0xC085,0xD0E5,0x0085,0x0083,0xBEEE,0xE7AF,0x0083,0xE7AE,0xCDB3,0x0089,0x0085,0x0083,0xBDCA,0xBEF8,0x0083,0xC2E7, 0xE7AD,0x0085,0x0083,0xD1A4,0xB8F8,0x0083,0xBBE6,0xE7AC,0x0091,0x0089,0x0085,0x0083,0xC084,0xC8C6,0x0083,0xE7AB, 0xBDE1,0x0085,0x0083,0xC8DE,0xB0F3,0x0083,0xE7AA,0xBEAD,0x0089,0x0085,0x0083,0xD2EF,0xC9DC,0x0083,0xE7A9,0xE7A8, 0x0085,0x0083,0xB0ED,0xE7A7,0x0083,0xD6D5,0xD6AF,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xCFB8,0xC9F0, 0x0083,0xD7E9,0xC1B7,0x0085,0x0083,0xE7A6,0xE7A5,0x0083,0xE7A4,0xCFDF,0x0089,0x0085,0x0083,0xE7A3,0xC5A6,0x0083, 0xC083,0xC082,0x0085,0x0083,0xB7C4,0xCEC6,0x0083,0xD6BD,0xB7D7,0x0091,0x0089,0x0085,0x0083,0xC2DA,0xD7DD,0x0083, 0xC081,0xC4C9,0x0085,0x0083,0xB8D9,0xC9B4,0x0083,0xE7A2,0xB4BF,0x0089,0x0085,0x0083,0xC080,0xE7A1,0x0083,0xCEB3, 0xC8D2,0x0085,0x0083,0xBCCD,0xE6FE,0x0083,0xE6FD,0xBCB6,0x00A1,0x0091,0x0089,0x0085,0x0083,0xD4BC,0xE6FC,0x0083, 0xCFCB,0xE6FB,0x0085,0x0083,0xBAEC,0xE6FA,0x0083,0xBEC0,0xE6F9,0x0089,0x0085,0x0083,0xC07E,0xC07D,0x0083,0xC07C, 0xF4EE,0x0085,0x0083,0xC07B,0xC07A,0x0083,0xC079,0xC078,0x0091,0x0089,0x0085,0x0083,0xC077,0xC076,0x0083,0xC075, 0xC074,0x0085,0x0083,0xC073,0xC072,0x0083,0xC071,0xC070,0x0089,0x0085,0x0083,0xC06F,0xC06E,0x0083,0xC06D,0xC06C, 0x0085,0x0083,0xC06B,0xC06A,0x0083,0xC069,0xC068,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xC067,0xC066,0x0083, 0xC065,0xC064,0x0085,0x0083,0xD7EB,0xC063,0x0083,0xC062,0xC061,0x0089,0x0085,0x0083,0xC060,0xC05F,0x0083,0xC05E, 0xC05D,0x0085,0x0083,0xC05C,0xC05B,0x0083,0xC05A,0xC059,0x0091,0x0089,0x0085,0x0083,0xC058,0xC057,0x0083,0xC056, 0xC055,0x0085,0x0083,0xC054,0xC053,0x0083,0xC052,0xC051,0x0089,0x0085,0x0083,0xC050,0xC04F,0x0083,0xC04E,0xC04D, 0x0085,0x0083,0xC04C,0xC04B,0x0083,0xC04A,0xC049,0x00A1,0x0091,0x0089,0x0085,0x0083,0xC048,0xC047,0x0083,0xC046, 0xC045,0x0085,0x0083,0xC044,0xC043,0x0083,0xC042,0xC041,0x0089,0x0085,0x0083,0xC040,0xBFA0,0x0083,0xBF9F,0xBF9E, 0x0085,0x0083,0xBF9D,0xBF9C,0x0083,0xBF9B,0xBF9A,0x0091,0x0089,0x0085,0x0083,0xBF99,0xBF98,0x0083,0xBF97,0xBF96, 0x0085,0x0083,0xBF95,0xBF94,0x0083,0xBF93,0xBF92,0x0089,0x0085,0x0083,0xBF91,0xBF90,0x0083,0xBF8F,0xBF8E,0x0085, 0x0083,0xBF8D,0xBF8C,0x0083,0xBF8B,0xF4ED,0x027F,0x017F,0x00FF,0x00BF,0x009F,0x008F,0x0087,0x0083,0xBF8A,0x0083, 0xBF89,0xBF88,0x0085,0x0083,0xBF87,0xBF86,0x0083,0xB7B1,0xBF85,0x0089,0x0085,0x0083,0xBF84,0xBF83,0x0083,0xBF82, 0xBF81,0x0085,0x0083,0xF7E3,0xBF80,0x0083,0xBF7E,0xBF7D,0x0091,0x0089,0x0085,0x0083,0xBF7C,0xBF7B,0x0083,0xBF7A, 0xBF79,0x0085,0x0083,0xBF78,0xBF77,0x0083,0xBF76,0xBF75,0x0089,0x0085,0x0083,0xBF74,0xBF73,0x0083,0xBF72,0xBF71, 0x0085,0x0083,0xBF70,0xBF6F,0x0083,0xBF6E,0xBF6D,0x00A1,0x0091,0x0089,0x0085,0x0083,0xBF6C,0xBF6B,0x0083,0xBF6A, 0xBF69,0x0085,0x0083,0xBF68,0xBF67,0x0083,0xBF66,0xBF65,0x0089,0x0085,0x0083,0xBF64,0xBF63,0x0083,0xBF62,0xBF61, 0x0085,0x0083,0xBF60,0xBF5F,0x0083,0xBF5E,0xBF5D,0x0091,0x0089,0x0085,0x0083,0xBF5C,0xBF5B,0x0083,0xBF5A,0xBF59, 0x0085,0x0083,0xBF58,0xBF57,0x0083,0xBF56,0xBF55,0x0089,0x0085,0x0083,0xBF54,0xBF53,0x0083,0xBF52,0xBF51,0x0085, 0x0083,0xBF50,0xBF4F,0x0083,0xBF4E,0xBF4D,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xBF4C,0xBF4B,0x0083,0xBF4A, 0xBF49,0x0085,0x0083,0xBF48,0xBF47,0x0083,0xBF46,0xBF45,0x0089,0x0085,0x0083,0xBF44,0xBF43,0x0083,0xBF42,0xBF41, 0x0085,0x0083,0xBF40,0xBEA0,0x0083,0xBE9F,0xBE9E,0x0091,0x0089,0x0085,0x0083,0xBE9D,0xBE9C,0x0083,0xBE9B,0xBE9A, 0x0085,0x0083,0xBE99,0xBE98,0x0083,0xBE97,0xBE96,0x0089,0x0085,0x0083,0xBE95,0xBE94,0x0083,0xBE93,0xBE92,0x0085, 0x0083,0xBE91,0xBE90,0x0083,0xBE8F,0xBE8E,0x00A1,0x0091,0x0089,0x0085,0x0083,0xBE8D,0xBE8C,0x0083,0xBE8B,0xBE8A, 0x0085,0x0083,0xBE89,0xBE88,0x0083,0xBE87,0xBE86,0x0089,0x0085,0x0083,0xBE85,0xBE84,0x0083,0xBE83,0xBE82,0x0085, 0x0083,0xBE81,0xBE80,0x0083,0xBE7E,0xBE7D,0x0091,0x0089,0x0085,0x0083,0xBE7C,0xBE7B,0x0083,0xBE7A,0xBE79,0x0085, 0x0083,0xBE78,0xBE77,0x0083,0xBE76,0xBE75,0x0089,0x0085,0x0083,0xBE74,0xBE73,0x0083,0xBE72,0xBE71,0x0085,0x0083, 0xBE70,0xBE6F,0x0083,0xBE6E,0xBE6D,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xBE6C,0xBE6B,0x0083,0xBE6A, 0xBE69,0x0085,0x0083,0xBE68,0xBE67,0x0083,0xBE66,0xBE65,0x0089,0x0085,0x0083,0xBE64,0xBE63,0x0083,0xBE62,0xBE61, 0x0085,0x0083,0xBE60,0xBE5F,0x0083,0xBE5E,0xBE5D,0x0091,0x0089,0x0085,0x0083,0xBE5C,0xBE5B,0x0083,0xBE5A,0xBE59, 0x0085,0x0083,0xBE58,0xBE57,0x0083,0xBE56,0xBE55,0x0089,0x0085,0x0083,0xBE54,0xF4EC,0x0083,0xBE53,0xBE52,0x0085, 0x0083,0xBE51,0xBE50,0x0083,0xBE4F,0xBE4E,0x00A1,0x0091,0x0089,0x0085,0x0083,0xBE4D,0xF4EB,0x0083,0xBE4C,0xBE4B, 0x0085,0x0083,0xBE4A,0xBE49,0x0083,0xBE48,0xBE47,0x0089,0x0085,0x0083,0xBE46,0xBE45,0x0083,0xBE44,0xBE43,0x0085, 0x0083,0xBE42,0xBE41,0x0083,0xBE40,0xBDA0,0x0091,0x0089,0x0085,0x0083,0xBD9F,0xBD9E,0x0083,0xBD9D,0xBD9C,0x0085, 0x0083,0xBD9B,0xBD9A,0x0083,0xBD99,0xBD98,0x0089,0x0085,0x0083,0xBD97,0xBD96,0x0083,0xBD95,0xBD94,0x0085,0x0083, 0xBD93,0xBD92,0x0083,0xBD91,0xBD90,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xBD8F,0xBD8E,0x0083,0xBD8D,0xBD8C, 0x0085,0x0083,0xBD8B,0xBD8A,0x0083,0xBD89,0xBD88,0x0089,0x0085,0x0083,0xBD87,0xBD86,0x0083,0xBD85,0xBD84,0x0085, 0x0083,0xBD83,0xBD82,0x0083,0xBD81,0xBD80,0x0091,0x0089,0x0085,0x0083,0xF4EA,0xBD7E,0x0083,0xBD7D,0xBD7C,0x0085, 0x0083,0xBD7B,0xBD7A,0x0083,0xBD79,0xBD78,0x0089,0x0085,0x0083,0xBD77,0xD0F5,0x0083,0xBD76,0xBD75,0x0085,0x0083, 0xBD74,0xBD73,0x0083,0xBD72,0xBD71,0x00A1,0x0091,0x0089,0x0085,0x0083,0xBD70,0xBD6F,0x0083,0xBD6E,0xBD6D,0x0085, 0x0083,0xBD6C,0xBD6B,0x0083,0xBD6A,0xBD69,0x0089,0x0085,0x0083,0xBD68,0xBD67,0x0083,0xBD66,0xBD65,0x0085,0x0083, 0xBD64,0xBD63,0x0083,0xBD62,0xBD61,0x0091,0x0089,0x0085,0x0083,0xBD60,0xBD5F,0x0083,0xBD5E,0xBD5D,0x0085,0x0083, 0xBD5C,0xBD5B,0x0083,0xBD5A,0xBD59,0x0089,0x0085,0x0083,0xBD58,0xBD57,0x0083,0xBD56,0xBD55,0x0085,0x0083,0xBD54, 0xBD53,0x0083,0xBD52,0xBD51,0x0181,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xBD50,0xBD4F,0x0083,0xBD4E, 0xBD4D,0x0085,0x0083,0xBD4C,0xBD4B,0x0083,0xBD4A,0xBD49,0x0089,0x0085,0x0083,0xBD48,0xBD47,0x0083,0xBD46,0xBD45, 0x0085,0x0083,0xBD44,0xBD43,0x0083,0xBD42,0xBD41,0x0091,0x0089,0x0085,0x0083,0xBD40,0xBCA0,0x0083,0xBC9F,0xBC9E, 0x0085,0x0083,0xBC9D,0xBC9C,0x0083,0xBC9B,0xBC9A,0x0089,0x0085,0x0083,0xC0DB,0xBC99,0x0083,0xBC98,0xBC97,0x0085, 0x0083,0xD7CF,0xBC96,0x0083,0xBC95,0xBC94,0x00A1,0x0091,0x0089,0x0085,0x0083,0xBDF4,0xBC93,0x0083,0xBC92,0xBC91, 0x0085,0x0083,0xBC90,0xCBF7,0x0083,0xBC8F,0xCBD8,0x0089,0x0085,0x0083,0xBC8E,0xBC8D,0x0083,0xBC8C,0xBC8B,0x0085, 0x0083,0xBC8A,0xBC89,0x0083,0xBC88,0xBC87,0x0091,0x0089,0x0085,0x0083,0xBC86,0xBC85,0x0083,0xBC84,0xBC83,0x0085, 0x0083,0xBC82,0xBC81,0x0083,0xBC80,0xBC7E,0x0089,0x0085,0x0083,0xBC7D,0xBC7C,0x0083,0xBC7B,0xBC7A,0x0085,0x0083, 0xBC79,0xCEC9,0x0083,0xBC78,0xBC77,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xBC76,0xBC75,0x0083,0xBC74,0xBC73, 0x0085,0x0083,0xBC72,0xBC71,0x0083,0xBC70,0xBC6F,0x0089,0x0085,0x0083,0xBC6E,0xBC6D,0x0083,0xBC6C,0xBC6B,0x0085, 0x0083,0xCFB5,0xBC6A,0x0083,0xBC69,0xF4E9,0x0091,0x0089,0x0085,0x0083,0xBC68,0xBC67,0x0083,0xBC66,0xBC65,0x0085, 0x0083,0xBC64,0xBC63,0x0083,0xBC62,0xBC61,0x0089,0x0085,0x0083,0xC5B4,0xBC60,0x0083,0xBC5F,0xBC5E,0x0085,0x0083, 0xBC5D,0xBC5C,0x0083,0xBC5B,0xF4DD,0x00A1,0x0091,0x0089,0x0085,0x0083,0xBC5A,0xBC59,0x0083,0xBC58,0xBC57,0x0085, 0x0083,0xBC56,0xBC55,0x0083,0xBC54,0xBFB7,0x0089,0x0085,0x0083,0xD4E3,0xBC53,0x0083,0xBC52,0xC3D3,0x0085,0x0083, 0xBC51,0xBC50,0x0083,0xB2DA,0xBC4F,0x0091,0x0089,0x0085,0x0083,0xF4DC,0xCCC7,0x0083,0xB8E2,0xBC4E,0x0085,0x0083, 0xBC4D,0xBC4C,0x0083,0xBC4B,0xBC4A,0x0089,0x0085,0x0083,0xBC49,0xBC48,0x0083,0xF4D9,0xF4D8,0x0085,0x0083,0xBC47, 0xBAFD,0x0083,0xBC46,0xF4DA,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xF4D7,0xBC45,0x0083,0xF4DB,0xBC44, 0x0085,0x0083,0xBC43,0xBC42,0x0083,0xF4D6,0xBC41,0x0089,0x0085,0x0083,0xBC40,0xBEAB,0x0083,0xF4D5,0xF4D4,0x0085, 0x0083,0xBBA0,0xBB9F,0x0083,0xB4E2,0xBB9E,0x0091,0x0089,0x0085,0x0083,0xBB9D,0xBB9C,0x0083,0xBB9B,0xBB9A,0x0085, 0x0083,0xBEAC,0xF4D3,0x0083,0xC1BB,0xBB99,0x0089,0x0085,0x0083,0xBB98,0xC1B8,0x0083,0xBB97,0xBB96,0x0085,0x0083, 0xBB95,0xB7E0,0x0083,0xBB94,0xBB93,0x00A1,0x0091,0x0089,0x0085,0x0083,0xBB92,0xBB91,0x0083,0xD6E0,0xD4C1,0x0085, 0x0083,0xBB90,0xF4D2,0x0083,0xBB8F,0xBB8E,0x0089,0x0085,0x0083,0xCBDA,0xF4D1,0x0083,0xF4CF,0xF4D0,0x0085,0x0083, 0xBB8D,0xBB8C,0x0083,0xBB8B,0xD5B3,0x0091,0x0089,0x0085,0x0083,0xB4D6,0xBB8A,0x0083,0xC6C9,0xBB89,0x0085,0x0083, 0xBB88,0xC1A3,0x0083,0xF4CE,0xBB87,0x0089,0x0085,0x0083,0xBB86,0xBB85,0x0083,0xBB84,0xBB83,0x0085,0x0083,0xBB82, 0xBB81,0x0083,0xB7DB,0xBB80,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xBB7E,0xBB7D,0x0083,0xBB7C,0xBB7B,0x0085, 0x0083,0xBB7A,0xBB79,0x0083,0xBB78,0xBB77,0x0089,0x0085,0x0083,0xBB76,0xBB75,0x0083,0xD7D1,0xF4CC,0x0085,0x0083, 0xC0E0,0xBB74,0x0083,0xBB73,0xBB72,0x0091,0x0089,0x0085,0x0083,0xBB71,0xBB70,0x0083,0xBB6F,0xD9E1,0x0085,0x0083, 0xC3D7,0xBB6E,0x0083,0xBB6D,0xBB6C,0x0089,0x0085,0x0083,0xBB6B,0xBB6A,0x0083,0xBB69,0xBB68,0x0085,0x0083,0xBB67, 0xBB66,0x0083,0xBB65,0xBB64,0x00A1,0x0091,0x0089,0x0085,0x0083,0xBB63,0xBB62,0x0083,0xBB61,0xBB60,0x0085,0x0083, 0xBB5F,0xBB5E,0x0083,0xBB5D,0xBB5C,0x0089,0x0085,0x0083,0xBB5B,0xBB5A,0x0083,0xBB59,0xBB58,0x0085,0x0083,0xBB57, 0xBB56,0x0083,0xBB55,0xBB54,0x0091,0x0089,0x0085,0x0083,0xBB53,0xBB52,0x0083,0xBB51,0xBB50,0x0085,0x0083,0xBB4F, 0xBB4E,0x0083,0xBB4D,0xBB4C,0x0089,0x0085,0x0083,0xBB4B,0xBB4A,0x0083,0xBCAE,0xBB49,0x0085,0x0083,0xBB48,0xBB47, 0x0083,0xBB46,0xBB45,0x047D,0x027F,0x017F,0x00FF,0x00BF,0x009F,0x008F,0x0087,0x0083,0xBB44,0x0083,0xBB43,0xBB42, 0x0085,0x0083,0xBB41,0xBB40,0x0083,0xBAA0,0xF4A5,0x0089,0x0085,0x0083,0xF4A6,0xB2BE,0x0083,0xBA9F,0xBA9E,0x0085, 0x0083,0xBA9D,0xBA9C,0x0083,0xBA9B,0xBA9A,0x0091,0x0089,0x0085,0x0083,0xF4A4,0xBA99,0x0083,0xBA98,0xBA97,0x0085, 0x0083,0xBA96,0xBA95,0x0083,0xBA94,0xBA93,0x0089,0x0085,0x0083,0xBA92,0xBA91,0x0083,0xBA90,0xBA8F,0x0085,0x0083, 0xBA8E,0xBA8D,0x0083,0xF4A2,0xBA8C,0x00A1,0x0091,0x0089,0x0085,0x0083,0xBA8B,0xBBC9,0x0083,0xF4A3,0xBA8A,0x0085, 0x0083,0xBA89,0xBA88,0x0083,0xBA87,0xBA86,0x0089,0x0085,0x0083,0xBA85,0xF4A1,0x0083,0xBA84,0xBA83,0x0085,0x0083, 0xBA82,0xBA81,0x0083,0xBA80,0xBA7E,0x0091,0x0089,0x0085,0x0083,0xBA7D,0xBA7C,0x0083,0xF3FD,0xBA7B,0x0085,0x0083, 0xBA7A,0xBA79,0x0083,0xBA78,0xBA77,0x0089,0x0085,0x0083,0xBA76,0xF3FC,0x0083,0xBA75,0xBA74,0x0085,0x0083,0xF3F9, 0xF3FE,0x0083,0xBA73,0xBA72,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xBA71,0xB4D8,0x0083,0xBA70,0xBA6F,0x0085, 0x0083,0xBA6E,0xBA6D,0x0083,0xBA6C,0xBA6B,0x0089,0x0085,0x0083,0xBA6A,0xBA69,0x0083,0xF3FA,0xBA68,0x0085,0x0083, 0xF3FB,0xBA67,0x0083,0xBA66,0xBA65,0x0091,0x0089,0x0085,0x0083,0xBA64,0xC5F1,0x0083,0xBA63,0xBA62,0x0085,0x0083, 0xBA61,0xBA60,0x0083,0xBA5F,0xC0E9,0x0089,0x0085,0x0083,0xBA5E,0xBA5D,0x0083,0xC0BA,0xBA5C,0x0085,0x0083,0xBA5B, 0xBA5A,0x0083,0xF3F8,0xBA59,0x00A1,0x0091,0x0089,0x0085,0x0083,0xBA58,0xBA57,0x0083,0xF3F7,0xF3F6,0x0085,0x0083, 0xBA56,0xBA55,0x0083,0xBA54,0xB4DB,0x0089,0x0085,0x0083,0xBA53,0xBA52,0x0083,0xBA51,0xF3F4,0x0085,0x0083,0xBA50, 0xBA4F,0x0083,0xF3F5,0xB8DD,0x0091,0x0089,0x0085,0x0083,0xBA4E,0xBA4D,0x0083,0xBA4C,0xBA4B,0x0085,0x0083,0xBA4A, 0xC2A8,0x0083,0xBA49,0xF3F1,0x0089,0x0085,0x0083,0xBA48,0xBA47,0x0083,0xBA46,0xBA45,0x0085,0x0083,0xF3F3,0xBA44, 0x0083,0xBA43,0xBA42,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xBA41,0xC6AA,0x0083,0xD7AD,0xBA40,0x0085, 0x0083,0xB9A0,0xB99F,0x0083,0xB99E,0xF3F2,0x0089,0x0085,0x0083,0xB99D,0xB99C,0x0083,0xB99B,0xB99A,0x0085,0x0083, 0xB999,0xB998,0x0083,0xB997,0xB996,0x0091,0x0089,0x0085,0x0083,0xF3E7,0xB995,0x0083,0xB994,0xB993,0x0085,0x0083, 0xF3F0,0xB992,0x0083,0xB991,0xCFE4,0x0089,0x0085,0x0083,0xB990,0xB98F,0x0083,0xB98E,0xBCFD,0x0085,0x0083,0xF3E8, 0xF3EF,0x0083,0xF3EC,0xC2E1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xF3EA,0xF3E6,0x0083,0xF3E5,0xB98D,0x0085,0x0083, 0xB98C,0xB98B,0x0083,0xF3EE,0xB9DC,0x0089,0x0085,0x0083,0xB98A,0xB989,0x0083,0xB988,0xF3E9,0x0085,0x0083,0xF3ED, 0xB987,0x0083,0xB986,0xB985,0x0091,0x0089,0x0085,0x0083,0xB984,0xCBE3,0x0083,0xB983,0xBBFE,0x0085,0x0083,0xB2AD, 0xB982,0x0083,0xB981,0xB980,0x0089,0x0085,0x0083,0xF3E4,0xB97E,0x0083,0xB97D,0xB9BF,0x0085,0x0083,0xB97C,0xB97B, 0x0083,0xB97A,0xB979,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xB978,0xB977,0x0083,0xB976,0xF3EB,0x0085,0x0083, 0xB975,0xB974,0x0083,0xB973,0xB972,0x0089,0x0085,0x0083,0xBCF2,0xB971,0x0083,0xC7A9,0xB970,0x0085,0x0083,0xB96F, 0xF3E0,0x0083,0xB96E,0xB3EF,0x0091,0x0089,0x0085,0x0083,0xB96D,0xBFEA,0x0083,0xB96C,0xF3DB,0x0085,0x0083,0xB96B, 0xB96A,0x0083,0xF3E2,0xF3E3,0x0089,0x0085,0x0083,0xB969,0xB968,0x0083,0xF3DF,0xB967,0x0085,0x0083,0xB966,0xB965, 0x0083,0xB964,0xB963,0x00A1,0x0091,0x0089,0x0085,0x0083,0xB962,0xB961,0x0083,0xB960,0xB95F,0x0085,0x0083,0xB95E, 0xB95D,0x0083,0xF3E1,0xB95C,0x0089,0x0085,0x0083,0xF3DE,0xB95B,0x0083,0xB95A,0xF3DD,0x0085,0x0083,0xB959,0xC9B8, 0x0083,0xF3D9,0xB958,0x0091,0x0089,0x0085,0x0083,0xF3D8,0xB957,0x0083,0xB2DF,0xB956,0x0085,0x0083,0xB4F0,0xB955, 0x0083,0xCDB2,0xD6FE,0x0089,0x0085,0x0083,0xBFF0,0xB7A4,0x0083,0xB954,0xB953,0x0085,0x0083,0xF3DC,0xBDEE,0x0083, 0xB952,0xB5C8,0x017F,0x00FF,0x00BF,0x009F,0x008F,0x0087,0x0083,0xB951,0x0083,0xF3CC,0xB950,0x0085,0x0083,0xF3DA, 0xB94F,0x0083,0xB94E,0xB94D,0x0089,0x0085,0x0083,0xB94C,0xB94B,0x0083,0xB94A,0xF3D6,0x0085,0x0083,0xB949,0xC1FD, 0x0083,0xB948,0xBCE3,0x0091,0x0089,0x0085,0x0083,0xB947,0xF3CD,0x0083,0xB946,0xB945,0x0085,0x0083,0xB944,0xB943, 0x0083,0xF3D5,0xB942,0x0089,0x0085,0x0083,0xF3D1,0xB941,0x0083,0xB940,0xF3D0,0x0085,0x0083,0xB8A0,0xB5DA,0x0083, 0xF3CA,0xF3CE,0x00A1,0x0091,0x0089,0x0085,0x0083,0xB89F,0xB1BF,0x0083,0xB89E,0xB7FB,0x0085,0x0083,0xF3D3,0xF3D4, 0x0083,0xB89D,0xB89C,0x0089,0x0085,0x0083,0xB89B,0xF3D2,0x0083,0xB89A,0xF3D7,0x0085,0x0083,0xB899,0xB898,0x0083, 0xB5D1,0xB897,0x0091,0x0089,0x0085,0x0083,0xF3CF,0xB896,0x0083,0xB895,0xB894,0x0085,0x0083,0xF3C8,0xB1CA,0x0083, 0xB893,0xB892,0x0089,0x0085,0x0083,0xD0A6,0xB891,0x0083,0xF3CB,0xB890,0x0085,0x0083,0xB88F,0xB88E,0x0083,0xCBF1, 0xF3C9,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xB88D,0xF3C5,0x0083,0xB88C,0xB0CA,0x0085,0x0083,0xB88B,0xF3C7, 0x0083,0xF3C6,0xB88A,0x0089,0x0085,0x0083,0xB889,0xB888,0x0083,0xB8CD,0xB887,0x0085,0x0083,0xF3C4,0xB886,0x0083, 0xB885,0xF3C3,0x0091,0x0089,0x0085,0x0083,0xD6F1,0xB884,0x0083,0xB883,0xB882,0x0085,0x0083,0xB881,0xB880,0x0083, 0xB87E,0xB87D,0x0089,0x0085,0x0083,0xB87C,0xB87B,0x0083,0xB6CB,0xB87A,0x0085,0x0083,0xBDDF,0xB879,0x0083,0xB878, 0xB877,0x00A1,0x0091,0x0089,0x0085,0x0083,0xB876,0xB875,0x0083,0xB874,0xF1B5,0x0085,0x0083,0xCDAF,0xB873,0x0083, 0xBFA2,0xB872,0x0089,0x0085,0x0083,0xB871,0xD5C2,0x0083,0xBEB9,0xBEBA,0x0085,0x0083,0xB870,0xB86F,0x0083,0xB86E, 0xB86D,0x0091,0x0089,0x0085,0x0083,0xD5BE,0xB86C,0x0083,0xB86B,0xCAFA,0x0085,0x0083,0xB86A,0xB869,0x0083,0xB868, 0xB867,0x0089,0x0085,0x0083,0xB866,0xB865,0x0083,0xB864,0xB863,0x0085,0x0083,0xB862,0xB861,0x0083,0xC1A2,0xB860, 0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xB85F,0xB85E,0x0083,0xB85D,0xB85C,0x0085,0x0083,0xB85B,0xB85A, 0x0083,0xB859,0xB858,0x0089,0x0085,0x0083,0xB857,0xB856,0x0083,0xC1FE,0xB855,0x0085,0x0083,0xB854,0xB853,0x0083, 0xB852,0xB851,0x0091,0x0089,0x0085,0x0083,0xB850,0xB84F,0x0083,0xB84E,0xB84D,0x0085,0x0083,0xB84C,0xB84B,0x0083, 0xF1C1,0xB84A,0x0089,0x0085,0x0083,0xB849,0xB848,0x0083,0xB847,0xB846,0x0085,0x0083,0xF1C0,0xF1BE,0x0083,0xB845, 0xB844,0x00A1,0x0091,0x0089,0x0085,0x0083,0xB843,0xF1BF,0x0083,0xB842,0xF1BC,0x0085,0x0083,0xBFFA,0xB841,0x0083, 0xB840,0xB7A0,0x0089,0x0085,0x0083,0xB79F,0xF1BD,0x0083,0xBFDF,0xB79E,0x0085,0x0083,0xCED1,0xB4DC,0x0083,0xB79D, 0xB79C,0x0091,0x0089,0x0085,0x0083,0xB79B,0xBEBD,0x0083,0xB4B0,0xBDD1,0x0085,0x0083,0xF1BB,0xB79A,0x0083,0xB799, 0xD6CF,0x0089,0x0085,0x0083,0xD2A4,0xB798,0x0083,0xB797,0xB796,0x0085,0x0083,0xC7CF,0xB795,0x0083,0xB794,0xB793, 0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xB792,0xF1BA,0x0083,0xB791,0xF1B9,0x0085,0x0083,0xB790,0xD5AD,0x0083, 0xC7D4,0xB78F,0x0089,0x0085,0x0083,0xCDBB,0xF1B8,0x0083,0xB4A9,0xB78E,0x0085,0x0083,0xB78D,0xB78C,0x0083,0xB78B, 0xBFD5,0x0091,0x0089,0x0085,0x0083,0xF1B7,0xF1B6,0x0083,0xC7EE,0xBEBF,0x0085,0x0083,0xB78A,0xD1A8,0x0083,0xB789, 0xB788,0x0089,0x0085,0x0083,0xB787,0xF0A6,0x0083,0xB786,0xB785,0x0085,0x0083,0xB784,0xB783,0x0083,0xB782,0xB781, 0x00A1,0x0091,0x0089,0x0085,0x0083,0xB780,0xB77E,0x0083,0xB77D,0xB77C,0x0085,0x0083,0xB77B,0xB77A,0x0083,0xB779, 0xB778,0x0089,0x0085,0x0083,0xB777,0xB776,0x0083,0xB775,0xB774,0x0085,0x0083,0xB773,0xB772,0x0083,0xB771,0xB770, 0x0091,0x0089,0x0085,0x0083,0xB76F,0xB76E,0x0083,0xCBEB,0xB76D,0x0085,0x0083,0xB76C,0xB76B,0x0083,0xB76A,0xB769, 0x0089,0x0085,0x0083,0xF0A3,0xB768,0x0083,0xB767,0xB766,0x0085,0x0083,0xB765,0xB764,0x0083,0xB763,0xB762,0x027F, 0x017F,0x00FF,0x00BF,0x009F,0x008F,0x0087,0x0083,0xB761,0x0083,0xB760,0xB75F,0x0085,0x0083,0xC4C2,0xB75E,0x0083, 0xB75D,0xB75C,0x0089,0x0085,0x0083,0xB75B,0xB75A,0x0083,0xB759,0xB8E5,0x0085,0x0083,0xB758,0xBBFC,0x0083,0xBCDA, 0xB5BE,0x0091,0x0089,0x0085,0x0083,0xB757,0xF0A1,0x0083,0xB756,0xF0A2,0x0085,0x0083,0xB755,0xB754,0x0083,0xB753, 0xCEC8,0x0089,0x0085,0x0083,0xB752,0xB751,0x0083,0xB750,0xB74F,0x0085,0x0083,0xB74E,0xB74D,0x0083,0xB74C,0xB74B, 0x00A1,0x0091,0x0089,0x0085,0x0083,0xB74A,0xB749,0x0083,0xB748,0xB747,0x0085,0x0083,0xB746,0xB745,0x0083,0xB744, 0xF6D5,0x0089,0x0085,0x0083,0xB743,0xB742,0x0083,0xB3ED,0xB741,0x0085,0x0083,0xEFFD,0xB740,0x0083,0xB6A0,0xB69F, 0x0091,0x0089,0x0085,0x0083,0xD6C9,0xB69E,0x0083,0xB69D,0xB0DE,0x0085,0x0083,0xB69C,0xB69B,0x0083,0xEFFE,0xB69A, 0x0089,0x0085,0x0083,0xB699,0xB698,0x0083,0xB697,0xB696,0x0085,0x0083,0xCBB0,0xC9D4,0x0083,0xB695,0xB3CC,0x00C1, 0x00A1,0x0091,0x0089,0x0085,0x0083,0xB694,0xB693,0x0083,0xB692,0xB691,0x0085,0x0083,0xEFF9,0xB690,0x0083,0xB68F, 0xEFFB,0x0089,0x0085,0x0083,0xEFFC,0xB68E,0x0083,0xCFA1,0xB68D,0x0085,0x0083,0xB68C,0xBBE0,0x0083,0xB68B,0xD2C6, 0x0091,0x0089,0x0085,0x0083,0xB68A,0xB689,0x0083,0xBDD5,0xB688,0x0085,0x0083,0xB687,0xB686,0x0083,0xB685,0xB684, 0x0089,0x0085,0x0083,0xB683,0xB682,0x0083,0xB3C6,0xBBFD,0x0085,0x0083,0xB681,0xEFF6,0x0083,0xB680,0xEFF8,0x00A1, 0x0091,0x0089,0x0085,0x0083,0xB67E,0xD6C8,0x0083,0xB67D,0xD1ED,0x0085,0x0083,0xC7D8,0xB67C,0x0083,0xB3D3,0xEFF7, 0x0089,0x0085,0x0083,0xB67B,0xB67A,0x0083,0xB679,0xD7E2,0x0085,0x0083,0xB678,0xB677,0x0083,0xB676,0xB675,0x0091, 0x0089,0x0085,0x0083,0xB674,0xB673,0x0083,0xC3D8,0xB672,0x0085,0x0083,0xB671,0xEFF5,0x0083,0xB670,0xB66F,0x0089, 0x0085,0x0083,0xC3EB,0xBFC6,0x0083,0xB66E,0xB66D,0x0085,0x0083,0xB66C,0xD6D6,0x0083,0xB66B,0xC7EF,0x0101,0x00C1, 0x00A1,0x0091,0x0089,0x0085,0x0083,0xB66A,0xB1FC,0x0083,0xB669,0xB668,0x0085,0x0083,0xB8D1,0xB667,0x0083,0xB666, 0xCDBA,0x0089,0x0085,0x0083,0xB665,0xCBBD,0x0083,0xD0E3,0xB664,0x0085,0x0083,0xBACC,0xC7DD,0x0083,0xB663,0xC0EB, 0x0091,0x0089,0x0085,0x0083,0xD8AE,0xD3ED,0x0083,0xB662,0xB661,0x0085,0x0083,0xB660,0xB65F,0x0083,0xB65E,0xECFC, 0x0089,0x0085,0x0083,0xB65D,0xB65C,0x0083,0xB65B,0xB65A,0x0085,0x0083,0xB659,0xB658,0x0083,0xB657,0xB656,0x00A1, 0x0091,0x0089,0x0085,0x0083,0xB655,0xB654,0x0083,0xB653,0xECFB,0x0085,0x0083,0xB652,0xB651,0x0083,0xB650,0xB64F, 0x0089,0x0085,0x0083,0xB64E,0xB64D,0x0083,0xB64C,0xB64B,0x0085,0x0083,0xB64A,0xB649,0x0083,0xB648,0xB647,0x0091, 0x0089,0x0085,0x0083,0xECFA,0xB646,0x0083,0xB645,0xB644,0x0085,0x0083,0xB643,0xB642,0x0083,0xB641,0xB640,0x0089, 0x0085,0x0083,0xB5A0,0xB59F,0x0083,0xB59E,0xB8A3,0x0085,0x0083,0xB59D,0xB59C,0x0083,0xB59B,0xB59A,0x00C1,0x00A1, 0x0091,0x0089,0x0085,0x0083,0xECF9,0xB599,0x0083,0xB598,0xB597,0x0085,0x0083,0xB596,0xECF8,0x0083,0xC2BB,0xB595, 0x0089,0x0085,0x0083,0xB594,0xBDFB,0x0083,0xD9F7,0xB593,0x0085,0x0083,0xB592,0xB591,0x0083,0xB590,0xB58F,0x0091, 0x0089,0x0085,0x0083,0xECF7,0xB58E,0x0083,0xBBF6,0xB5BB,0x0085,0x0083,0xB58D,0xB58C,0x0083,0xB58B,0xB58A,0x0089, 0x0085,0x0083,0xB589,0xB588,0x0083,0xB587,0xECF5,0x0085,0x0083,0xB586,0xBCC0,0x0083,0xB585,0xB584,0x00A1,0x0091, 0x0089,0x0085,0x0083,0xB583,0xB582,0x0083,0xC6B1,0xECF6,0x0085,0x0083,0xB581,0xCFE9,0x0083,0xB580,0xB57E,0x0089, 0x0085,0x0083,0xECF2,0xB57D,0x0083,0xECF4,0xCBEE,0x0085,0x0083,0xC9F1,0xD7A3,0x0083,0xECEF,0xECEE,0x0091,0x0089, 0x0085,0x0083,0xECF1,0xB57C,0x0083,0xB57B,0xECF3,0x0085,0x0083,0xD7E6,0xB57A,0x0083,0xB579,0xECF0,0x0089,0x0085, 0x0083,0xB578,0xB577,0x0083,0xB576,0xB575,0x0085,0x0083,0xB574,0xB573,0x0083,0xB572,0xB571,0x0181,0x0101,0x00C1, 0x00A1,0x0091,0x0089,0x0085,0x0083,0xB570,0xECED,0x0083,0xC6ED,0xB56F,0x0085,0x0083,0xECEC,0xB56E,0x0083,0xB56D, 0xB56C,0x0089,0x0085,0x0083,0xB56B,0xC6EE,0x0083,0xECEB,0xB56A,0x0085,0x0083,0xC9E7,0xB569,0x0083,0xC0F1,0xECEA, 0x0091,0x0089,0x0085,0x0083,0xCABE,0xB568,0x0083,0xB567,0xB566,0x0085,0x0083,0xB565,0xB564,0x0083,0xEDE7,0xB563, 0x0089,0x0085,0x0083,0xB562,0xB561,0x0083,0xB560,0xB55F,0x0085,0x0083,0xB55E,0xB55D,0x0083,0xB55C,0xB55B,0x00A1, 0x0091,0x0089,0x0085,0x0083,0xB55A,0xB559,0x0083,0xB558,0xB557,0x0085,0x0083,0xB556,0xB555,0x0083,0xEDE5,0xB554, 0x0089,0x0085,0x0083,0xB553,0xB552,0x0083,0xB551,0xB550,0x0085,0x0083,0xEDE6,0xB54F,0x0083,0xB54E,0xB54D,0x0091, 0x0089,0x0085,0x0083,0xB54C,0xB54B,0x0083,0xB54A,0xB549,0x0085,0x0083,0xB548,0xB547,0x0083,0xB546,0xEDE4,0x0089, 0x0085,0x0083,0xB545,0xB544,0x0083,0xB543,0xB542,0x0085,0x0083,0xB541,0xB540,0x0083,0xB4A0,0xB49F,0x00C1,0x00A1, 0x0091,0x0089,0x0085,0x0083,0xB49E,0xB49D,0x0083,0xB49C,0xB49B,0x0085,0x0083,0xB49A,0xEDE2,0x0083,0xB499,0xB498, 0x0089,0x0085,0x0083,0xB497,0xBDB8,0x0083,0xB496,0xB495,0x0085,0x0083,0xB494,0xB493,0x0083,0xB492,0xB491,0x0091, 0x0089,0x0085,0x0083,0xBBC7,0xB490,0x0083,0xB48F,0xC1D7,0x0085,0x0083,0xB48E,0xB48D,0x0083,0xEDE3,0xB48C,0x0089, 0x0085,0x0083,0xEDE1,0xB48B,0x0083,0xB48A,0xB489,0x0085,0x0083,0xB488,0xB487,0x0083,0xEDE0,0xB486,0x00A1,0x0091, 0x0089,0x0085,0x0083,0xB485,0xB484,0x0083,0xC4A5,0xB483,0x0085,0x0083,0xB482,0xB481,0x0083,0xB480,0xB47E,0x0089, 0x0085,0x0083,0xB47D,0xB47C,0x0083,0xB47B,0xB47A,0x0085,0x0083,0xB479,0xB478,0x0083,0xB477,0xB476,0x0091,0x0089, 0x0085,0x0083,0xB475,0xEDDE,0x0083,0xB474,0xB473,0x0085,0x0083,0xB472,0xBFC4,0x0083,0xEDDD,0xB471,0x0089,0x0085, 0x0083,0xB470,0xB46F,0x0083,0xC5CD,0xB46E,0x0085,0x0083,0xB46D,0xB46C,0x0083,0xB46B,0xB4E8,0x0101,0x00C1,0x00A1, 0x0091,0x0089,0x0085,0x0083,0xC0DA,0xEDDF,0x0083,0xB46A,0xB469,0x0085,0x0083,0xB468,0xB0F5,0x0083,0xB467,0xB466, 0x0089,0x0085,0x0083,0xB465,0xB4C5,0x0083,0xB464,0xB463,0x0085,0x0083,0xC4EB,0xB462,0x0083,0xB461,0xB460,0x0091, 0x0089,0x0085,0x0083,0xB45F,0xEDDB,0x0083,0xB45E,0xB45D,0x0085,0x0083,0xB45C,0xB45B,0x0083,0xB2EA,0xCCBC,0x0089, 0x0085,0x0083,0xEDDA,0xBCEE,0x0083,0xC5F6,0xB45A,0x0085,0x0083,0xB459,0xB458,0x0083,0xB457,0xB456,0x00A1,0x0091, 0x0089,0x0085,0x0083,0xB455,0xB454,0x0083,0xB453,0xB1CC,0x0085,0x0083,0xB452,0xEDDC,0x0083,0xB451,0xEDD9,0x0089, 0x0085,0x0083,0xB450,0xEDD8,0x0083,0xB44F,0xB5FA,0x0085,0x0083,0xB44E,0xB44D,0x0083,0xEDD7,0xEDD3,0x0091,0x0089, 0x0085,0x0083,0xEDD5,0xB44C,0x0083,0xB5E2,0xCDEB,0x0085,0x0083,0xB44B,0xB44A,0x0083,0xB449,0xEDD4,0x0089,0x0085, 0x0083,0xB448,0xB1AE,0x0083,0xB447,0xB446,0x0085,0x0083,0xCBE9,0xB0AD,0x0083,0xC2B5,0xB445,0x00C1,0x00A1,0x0091, 0x0089,0x0085,0x0083,0xB444,0xB5EF,0x0083,0xB443,0xEDD6,0x0085,0x0083,0xB442,0xB441,0x0083,0xB440,0xB3A0,0x0089, 0x0085,0x0083,0xB39F,0xB39E,0x0083,0xB39D,0xB39C,0x0085,0x0083,0xB39B,0xB39A,0x0083,0xC5F0,0xB399,0x0091,0x0089, 0x0085,0x0083,0xB398,0xB397,0x0083,0xB396,0xBCEF,0x0085,0x0083,0xB395,0xB394,0x0083,0xB393,0xB392,0x0089,0x0085, 0x0083,0xB391,0xB390,0x0083,0xB38F,0xB38E,0x0085,0x0083,0xC8B7,0xEDCB,0x0083,0xD3B2,0xC1F2,0x00A1,0x0091,0x0089, 0x0085,0x0083,0xEDD2,0xB38D,0x0083,0xB38C,0xB38B,0x0085,0x0083,0xB38A,0xB389,0x0083,0xB388,0xB387,0x0089,0x0085, 0x0083,0xB386,0xB385,0x0083,0xB384,0xB383,0x0085,0x0083,0xB382,0xCFF5,0x0083,0xB381,0xB380,0x0091,0x0089,0x0085, 0x0083,0xB37E,0xB37D,0x0083,0xB37C,0xEDCD,0x0085,0x0083,0xEDCC,0xCBB6,0x0083,0xB37B,0xB37A,0x0089,0x0085,0x0083, 0xCEF8,0xB379,0x0083,0xEDCF,0xB378,0x0085,0x0083,0xEDCA,0xB377,0x0083,0xEDD1,0xB376,0x087B,0x047D,0x027F,0x017F, 0x00FF,0x00BF,0x009F,0x008F,0x0087,0x0083,0xB375,0x0083,0xB374,0xB373,0x0085,0x0083,0xEDD0,0xB372,0x0083,0xB9E8, 0xB371,0x0089,0x0085,0x0083,0xB370,0xB36F,0x0083,0xB36E,0xB4A1,0x0085,0x0083,0xB36D,0xC0F9,0x0083,0xB36C,0xEDC5, 0x0091,0x0089,0x0085,0x0083,0xEDC3,0xEDC2,0x0083,0xEDC1,0xD4D2,0x0085,0x0083,0xC9E9,0xB36B,0x0083,0xB36A,0xC6C6, 0x0089,0x0085,0x0083,0xB369,0xB368,0x0083,0xB367,0xC5E9,0x0085,0x0083,0xB366,0xB365,0x0083,0xEDBE,0xEDC7,0x00A1, 0x0091,0x0089,0x0085,0x0083,0xB364,0xB363,0x0083,0xEDC9,0xB362,0x0085,0x0083,0xD5E8,0xEDCE,0x0083,0xEDC6,0xB361, 0x0089,0x0085,0x0083,0xEDC8,0xB360,0x0083,0xB35F,0xB35E,0x0085,0x0083,0xEDC4,0xB35D,0x0083,0xEDC0,0xEDBF,0x0091, 0x0089,0x0085,0x0083,0xB35C,0xD1E2,0x0083,0xB35B,0xEDBB,0x0085,0x0083,0xEDBA,0xD7A9,0x0083,0xB35A,0xD1D0,0x0089, 0x0085,0x0083,0xB359,0xC5F8,0x0083,0xEDBC,0xB358,0x0085,0x0083,0xB357,0xB356,0x0083,0xBFB3,0xC6F6,0x00C1,0x00A1, 0x0091,0x0089,0x0085,0x0083,0xB355,0xB354,0x0083,0xEDB9,0xB353,0x0085,0x0083,0xB352,0xB351,0x0083,0xB350,0xB34F, 0x0089,0x0085,0x0083,0xB34E,0xC9B0,0x0083,0xC2EB,0xEDB8,0x0085,0x0083,0xBFF3,0xB7AF,0x0083,0xCEF9,0xB34D,0x0091, 0x0089,0x0085,0x0083,0xB34C,0xB34B,0x0083,0xB34A,0xEDB7,0x0085,0x0083,0xB349,0xEDB6,0x0083,0xB348,0xB347,0x0089, 0x0085,0x0083,0xCAAF,0xB346,0x0083,0xB345,0xB344,0x0085,0x0083,0xB343,0xB0AB,0x0083,0xB6CC,0xEFF3,0x00A1,0x0091, 0x0089,0x0085,0x0083,0xBDC3,0xB342,0x0083,0xBED8,0xB341,0x0085,0x0083,0xEFF2,0xB340,0x0083,0xD6AA,0xB2A0,0x0089, 0x0085,0x0083,0xD2D3,0xCAB8,0x0083,0xB29F,0xB29E,0x0085,0x0083,0xB29D,0xB29C,0x0083,0xB29B,0xF1E6,0x0091,0x0089, 0x0085,0x0083,0xC3AC,0xB29A,0x0083,0xB299,0xB298,0x0085,0x0083,0xB4A3,0xB297,0x0083,0xB296,0xB295,0x0089,0x0085, 0x0083,0xB294,0xB293,0x0083,0xB292,0xB291,0x0085,0x0083,0xB290,0xB28F,0x0083,0xDBC7,0xB28E,0x0101,0x00C1,0x00A1, 0x0091,0x0089,0x0085,0x0083,0xB28D,0xB28C,0x0083,0xB28B,0xB28A,0x0085,0x0083,0xB289,0xB288,0x0083,0xB287,0xB286, 0x0089,0x0085,0x0083,0xB285,0xB284,0x0083,0xB283,0xB282,0x0085,0x0083,0xF6C4,0xB281,0x0083,0xEEAD,0xB280,0x0091, 0x0089,0x0085,0x0083,0xD5B0,0xB27E,0x0083,0xB27D,0xB27C,0x0085,0x0083,0xB27B,0xB27A,0x0083,0xEEAC,0xB279,0x0089, 0x0085,0x0083,0xCDAB,0xB278,0x0083,0xB277,0xEEAB,0x0085,0x0083,0xB276,0xB275,0x0083,0xB274,0xCBB2,0x00A1,0x0091, 0x0089,0x0085,0x0083,0xB273,0xB5C9,0x0083,0xD6F5,0xB272,0x0085,0x0083,0xC7C6,0xB271,0x0083,0xC6B3,0xB270,0x0089, 0x0085,0x0083,0xB26F,0xDEAB,0x0083,0xB26E,0xEEAA,0x0085,0x0083,0xEEA9,0xB26D,0x0083,0xB26C,0xB26B,0x0091,0x0089, 0x0085,0x0083,0xB26A,0xB269,0x0083,0xB268,0xB267,0x0085,0x0083,0xB266,0xB265,0x0083,0xB264,0xB263,0x0089,0x0085, 0x0083,0xB262,0xC2F7,0x0083,0xEEA8,0xB261,0x0085,0x0083,0xB260,0xCFB9,0x0083,0xEEA4,0xEEA7,0x00C1,0x00A1,0x0091, 0x0089,0x0085,0x0083,0xB25F,0xB25E,0x0083,0xB25D,0xB25C,0x0085,0x0083,0xB25B,0xB25A,0x0083,0xB3F2,0xC3E9,0x0089, 0x0085,0x0083,0xB259,0xB258,0x0083,0xB257,0xEEA6,0x0085,0x0083,0xEEA3,0xD8BA,0x0083,0xEEA5,0xB256,0x0091,0x0089, 0x0085,0x0083,0xB255,0xB254,0x0083,0xB6C3,0xB253,0x0085,0x0083,0xB252,0xB251,0x0083,0xB250,0xB24F,0x0089,0x0085, 0x0083,0xB24E,0xB24D,0x0083,0xB24C,0xB24B,0x0085,0x0083,0xB24A,0xB249,0x0083,0xB248,0xB2C7,0x00A1,0x0091,0x0089, 0x0085,0x0083,0xBDDE,0xB247,0x0083,0xB246,0xEDFE,0x0085,0x0083,0xB245,0xC4C0,0x0083,0xEEA2,0xB244,0x0089,0x0085, 0x0083,0xB6BD,0xEEA1,0x0083,0xCBAF,0xB243,0x0085,0x0083,0xB242,0xB241,0x0083,0xB240,0xB1A0,0x0091,0x0089,0x0085, 0x0083,0xBEA6,0xEDFD,0x0083,0xB19F,0xB19E,0x0085,0x0083,0xB19D,0xB19C,0x0083,0xB19B,0xB19A,0x0089,0x0085,0x0083, 0xB199,0xB198,0x0083,0xEDFA,0xEDF9,0x0085,0x0083,0xB197,0xB196,0x0083,0xB195,0xB194,0x017F,0x00FF,0x00BF,0x009F, 0x008F,0x0087,0x0083,0xB193,0x0083,0xB192,0xB191,0x0085,0x0083,0xB190,0xEDFB,0x0083,0xB18F,0xB18E,0x0089,0x0085, 0x0083,0xB18D,0xEDFC,0x0083,0xB18C,0xD5F6,0x0085,0x0083,0xD7C5,0xB18B,0x0083,0xB18A,0xB189,0x0091,0x0089,0x0085, 0x0083,0xD1DB,0xB188,0x0083,0xCCF7,0xB187,0x0085,0x0083,0xEDF8,0xBEEC,0x0083,0xBFF4,0xEDF7,0x0089,0x0085,0x0083, 0xB186,0xB185,0x0083,0xB184,0xB183,0x0085,0x0083,0xB182,0xC3D0,0x0083,0xB181,0xEDF5,0x00A1,0x0091,0x0089,0x0085, 0x0083,0xB180,0xB17E,0x0083,0xB17D,0xD1A3,0x0085,0x0083,0xD5A3,0xB17C,0x0083,0xEDF6,0xB17B,0x0089,0x0085,0x0083, 0xB17A,0xB179,0x0083,0xEDF3,0xB178,0x0085,0x0083,0xC3DF,0xD5E6,0x0083,0xB177,0xB176,0x0091,0x0089,0x0085,0x0083, 0xB175,0xB174,0x0083,0xEDF2,0xEDF4,0x0085,0x0083,0xB173,0xB172,0x0083,0xB171,0xB170,0x0089,0x0085,0x0083,0xB16F, 0xB16E,0x0083,0xB16D,0xB16C,0x0085,0x0083,0xB16B,0xB16A,0x0083,0xB169,0xEDEE,0x00C1,0x00A1,0x0091,0x0089,0x0085, 0x0083,0xB168,0xBFB4,0x0083,0xB167,0xC3BC,0x0085,0x0083,0xEDF1,0xEDF0,0x0083,0xB166,0xB165,0x0089,0x0085,0x0083, 0xEDED,0xB164,0x0083,0xB163,0xCAA1,0x0085,0x0083,0xB162,0xB161,0x0083,0xB6DC,0xB160,0x0091,0x0089,0x0085,0x0083, 0xC5CE,0xB15F,0x0083,0xB15E,0xEDEF,0x0085,0x0083,0xCFE0,0xB15D,0x0083,0xB15C,0xB15B,0x0089,0x0085,0x0083,0xD6B1, 0xB15A,0x0083,0xC3A4,0xEDEC,0x0085,0x0083,0xB159,0xB6A2,0x0083,0xC4BF,0xB158,0x00A1,0x0091,0x0089,0x0085,0x0083, 0xB157,0xB156,0x0083,0xB155,0xB154,0x0085,0x0083,0xB153,0xB152,0x0083,0xB151,0xEEC2,0x0089,0x0085,0x0083,0xB150, 0xB14F,0x0083,0xB14E,0xB14D,0x0085,0x0083,0xB14C,0xC3CB,0x0083,0xB14B,0xB14A,0x0091,0x0089,0x0085,0x0083,0xB149, 0xCAA2,0x0083,0xB148,0xB147,0x0085,0x0083,0xC5CC,0xB5C1,0x0083,0xB8C7,0xB146,0x0089,0x0085,0x0083,0xBFF8,0xB145, 0x0083,0xBAD0,0xBCE0,0x0085,0x0083,0xD1CE,0xD5B5,0x0083,0xB0BB,0xEEC1,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085, 0x0083,0xB144,0xB143,0x0083,0xD2E6,0xB142,0x0085,0x0083,0xD3AF,0xB141,0x0083,0xC5E8,0xD6D1,0x0089,0x0085,0x0083, 0xB140,0xB0A0,0x0083,0xD3DB,0xB09F,0x0085,0x0083,0xB09E,0xC3F3,0x0083,0xB09D,0xB09C,0x0091,0x0089,0x0085,0x0083, 0xB09B,0xB09A,0x0083,0xB099,0xB098,0x0085,0x0083,0xB097,0xB096,0x0083,0xB095,0xB094,0x0089,0x0085,0x0083,0xF1E5, 0xB093,0x0083,0xF1E4,0xD6E5,0x0085,0x0083,0xB092,0xB091,0x0083,0xC6A4,0xB090,0x00A1,0x0091,0x0089,0x0085,0x0083, 0xB08F,0xB08E,0x0083,0xB08D,0xB08C,0x0085,0x0083,0xB08B,0xB08A,0x0083,0xB089,0xB088,0x0089,0x0085,0x0083,0xF0AB, 0xB087,0x0083,0xB086,0xB085,0x0085,0x0083,0xB084,0xB083,0x0083,0xB082,0xB081,0x0091,0x0089,0x0085,0x0083,0xB080, 0xB07E,0x0083,0xB07D,0xF0AA,0x0085,0x0083,0xB07C,0xB07B,0x0083,0xCDEE,0xB07A,0x0089,0x0085,0x0083,0xB079,0xF0A9, 0x0083,0xB078,0xB0A8,0x0085,0x0083,0xB077,0xB076,0x0083,0xF0A8,0xB075,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083, 0xB074,0xB8DE,0x0083,0xB073,0xB072,0x0085,0x0083,0xF0A7,0xBBCA,0x0083,0xBDD4,0xB071,0x0089,0x0085,0x0083,0xB5C4, 0xB070,0x0083,0xD4ED,0xB06F,0x0085,0x0083,0xB06E,0xB06D,0x0083,0xB0D9,0xB0D7,0x0091,0x0089,0x0085,0x0083,0xB06C, 0xB5C7,0x0083,0xB06B,0xB06A,0x0085,0x0083,0xB9EF,0xB069,0x0083,0xB068,0xB067,0x0089,0x0085,0x0083,0xB066,0xB065, 0x0083,0xB064,0xB063,0x0085,0x0083,0xB062,0xF1B3,0x0083,0xB061,0xB060,0x00A1,0x0091,0x0089,0x0085,0x0083,0xB05F, 0xF1B2,0x0083,0xB05E,0xB05D,0x0085,0x0083,0xB05C,0xB05B,0x0083,0xB05A,0xB059,0x0089,0x0085,0x0083,0xB058,0xD1A2, 0x0083,0xB057,0xB056,0x0085,0x0083,0xB055,0xB054,0x0083,0xF1AE,0xB053,0x0091,0x0089,0x0085,0x0083,0xF1B0,0xB052, 0x0083,0xB051,0xB050,0x0085,0x0083,0xB04F,0xB04E,0x0083,0xF1B1,0xB04D,0x0089,0x0085,0x0083,0xF1AF,0xB04C,0x0083, 0xB04B,0xB04A,0x0085,0x0083,0xB049,0xB048,0x0083,0xB047,0xF1AD,0x027F,0x017F,0x00FF,0x00BF,0x009F,0x008F,0x0087, 0x0083,0xB0A9,0x0083,0xB046,0xB045,0x0085,0x0083,0xB044,0xB043,0x0083,0xB042,0xB041,0x0089,0x0085,0x0083,0xB040, 0xAFA0,0x0083,0xF1AA,0xAF9F,0x0085,0x0083,0xAF9E,0xF1A5,0x0083,0xF1A8,0xF1AB,0x0091,0x0089,0x0085,0x0083,0xAF9D, 0xF1A2,0x0083,0xAF9C,0xAF9B,0x0085,0x0083,0xAF9A,0xC8B3,0x0083,0xAF99,0xAF98,0x0089,0x0085,0x0083,0xF1A9,0xD5CE, 0x0083,0xF1AC,0xAF97,0x0085,0x0083,0xAF96,0xF1A7,0x0083,0xAF95,0xAF94,0x00A1,0x0091,0x0089,0x0085,0x0083,0xF1A6, 0xAF93,0x0083,0xCCB1,0xB1F1,0x0085,0x0083,0xB4F1,0xAF92,0x0083,0xAF91,0xCADD,0x0089,0x0085,0x0083,0xF0FB,0xC1F6, 0x0083,0xAF90,0xF1A3,0x0085,0x0083,0xAF8F,0xF1A4,0x0083,0xCEC1,0xAF8E,0x0091,0x0089,0x0085,0x0083,0xAF8D,0xAF8C, 0x0083,0xF1A1,0xAF8B,0x0085,0x0083,0xF0FE,0xF0FC,0x0083,0xF0F9,0xAF8A,0x0089,0x0085,0x0083,0xF0FD,0xAF89,0x0083, 0xAF88,0xAF87,0x0085,0x0083,0xAF86,0xF0F5,0x0083,0xAF85,0xAF84,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xAF83, 0xF0F8,0x0083,0xAF82,0xF0FA,0x0085,0x0083,0xAF81,0xAF80,0x0083,0xAF7E,0xAF7D,0x0089,0x0085,0x0083,0xF0F7,0xAF7C, 0x0083,0xF0F1,0xAF7B,0x0085,0x0083,0xB4E1,0xF0F6,0x0083,0xF0F4,0xAF7A,0x0091,0x0089,0x0085,0x0083,0xAF79,0xF0F3, 0x0083,0xAF78,0xAF77,0x0085,0x0083,0xB1D4,0xAF76,0x0083,0xAF75,0xAF74,0x0089,0x0085,0x0083,0xAF73,0xB3D5,0x0083, 0xAF72,0xAF71,0x0085,0x0083,0xF0F2,0xCCB5,0x0083,0xAF70,0xAF6F,0x00A1,0x0091,0x0089,0x0085,0x0083,0xAF6E,0xAF6D, 0x0083,0xF0EF,0xBBBE,0x0085,0x0083,0xAF6C,0xF0EC,0x0083,0xF0F0,0xF0ED,0x0089,0x0085,0x0083,0xAF6B,0xF0EE,0x0083, 0xF0EB,0xC1A1,0x0085,0x0083,0xAF6A,0xAF69,0x0083,0xAF68,0xC6A6,0x0091,0x0089,0x0085,0x0083,0xAF67,0xAF66,0x0083, 0xCDB4,0xAF65,0x0085,0x0083,0xAF64,0xB6BB,0x0083,0xAF63,0xF0E9,0x0089,0x0085,0x0083,0xBADB,0xD6CC,0x0083,0xAF62, 0xD1F7,0x0085,0x0083,0xAF61,0xAF60,0x0083,0xAF5F,0xAF5E,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xF0EA, 0xAF5D,0x0083,0xAF5C,0xC8AC,0x0085,0x0083,0xBEB7,0xD3B8,0x0083,0xD6A2,0xAF5B,0x0089,0x0085,0x0083,0xB2A1,0xF0E4, 0x0083,0xF0E7,0xF0E8,0x0085,0x0083,0xAF5A,0xAF59,0x0083,0xAF58,0xBCB2,0x0091,0x0089,0x0085,0x0083,0xBED2,0xCCDB, 0x0083,0xAF57,0xAF56,0x0085,0x0083,0xD5EE,0xF0E3,0x0083,0xAF55,0xAF54,0x0089,0x0085,0x0083,0xB4C3,0xF0E2,0x0083, 0xF0E1,0xC6A3,0x0085,0x0083,0xF0E5,0xF0E6,0x0083,0xB7E8,0xB4AF,0x00A1,0x0091,0x0089,0x0085,0x0083,0xAF53,0xF0DF, 0x0083,0xD2DF,0xAF52,0x0085,0x0083,0xAF51,0xAF50,0x0083,0xAF4F,0xAF4E,0x0089,0x0085,0x0083,0xBDEA,0xB0CC,0x0083, 0xF0E0,0xAF4D,0x0085,0x0083,0xD1F1,0xF0DD,0x0083,0xC5B1,0xAF4C,0x0091,0x0089,0x0085,0x0083,0xF0DE,0xAF4B,0x0083, 0xAF4A,0xBECE,0x0085,0x0083,0xB8ED,0xAF49,0x0083,0xC1C6,0xF0DC,0x0089,0x0085,0x0083,0xAF48,0xF0DB,0x0083,0xAF47, 0xF0DA,0x0085,0x0083,0xD2C9,0xAF46,0x0083,0xCAE8,0xAF45,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xAF44,0xAF43, 0x0083,0xF1E2,0xAF42,0x0085,0x0083,0xAF41,0xAF40,0x0083,0xAEA0,0xBDAE,0x0089,0x0085,0x0083,0xAE9F,0xAE9E,0x0083, 0xEEB6,0xAE9D,0x0085,0x0083,0xAE9C,0xAE9B,0x0083,0xE7DC,0xAE9A,0x0091,0x0089,0x0085,0x0083,0xAE99,0xAE98,0x0083, 0xAE97,0xAE96,0x0085,0x0083,0xEEB5,0xBBFB,0x0083,0xAE95,0xAE94,0x0089,0x0085,0x0083,0xAE93,0xB3EB,0x0083,0xAE92, 0xEEB4,0x0085,0x0083,0xAE91,0xAE90,0x0083,0xAE8F,0xAE8E,0x00A1,0x0091,0x0089,0x0085,0x0083,0xAE8D,0xAE8C,0x0083, 0xAE8B,0xB7AC,0x0085,0x0083,0xAE8A,0xAE89,0x0083,0xAE88,0xC6E8,0x0089,0x0085,0x0083,0xC2D4,0xAE87,0x0083,0xAE86, 0xAE85,0x0085,0x0083,0xAE84,0xAE83,0x0083,0xAE82,0xAE81,0x0091,0x0089,0x0085,0x0083,0xAE80,0xD0F3,0x0083,0xEEB3, 0xDBCE,0x0085,0x0083,0xC1F4,0xAE7E,0x0083,0xAE7D,0xAE7C,0x0089,0x0085,0x0083,0xAE7B,0xC5CF,0x0083,0xAE7A,0xAE79, 0x0085,0x0083,0xAE78,0xAE77,0x0083,0xCEB7,0xEEB0,0x0181,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xAE76, 0xBDE7,0x0083,0xEEB1,0xAE75,0x0085,0x0083,0xAE74,0xEEB2,0x0083,0xAE73,0xAE72,0x0089,0x0085,0x0083,0xB3A9,0xAE71, 0x0083,0xAE70,0xAE6F,0x0085,0x0083,0xAE6E,0xEEAF,0x0083,0xAE6D,0xE7DE,0x0091,0x0089,0x0085,0x0083,0xAE6C,0xAE6B, 0x0083,0xBBAD,0xEEAE,0x0085,0x0083,0xAE6A,0xB5E9,0x0083,0xC4D0,0xAE69,0x0089,0x0085,0x0083,0xB5E7,0xAE68,0x0083, 0xC9EA,0xBCD7,0x0085,0x0083,0xD3C9,0xCCEF,0x0083,0xE5B8,0xAE67,0x00A1,0x0091,0x0089,0x0085,0x0083,0xB1C2,0xF0AE, 0x0083,0xB8A6,0xAE66,0x0085,0x0083,0xCBA6,0xD3C3,0x0083,0xAE65,0xAE64,0x0089,0x0085,0x0083,0xC9FB,0xAE63,0x0083, 0xAE62,0xAE61,0x0085,0x0083,0xAE60,0xAE5F,0x0083,0xC9FA,0xAE5E,0x0091,0x0089,0x0085,0x0083,0xAE5D,0xCCF0,0x0083, 0xAE5C,0xC9F5,0x0085,0x0083,0xDFB0,0xB8CA,0x0083,0xAE5B,0xAE5A,0x0089,0x0085,0x0083,0xAE59,0xAE58,0x0083,0xEAB6, 0xAE57,0x0085,0x0083,0xEAB5,0xAE56,0x0083,0xEAB4,0xAE55,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xDDF9,0xAE54, 0x0083,0xAE53,0xAE52,0x0085,0x0083,0xAE51,0xAE50,0x0083,0xAE4F,0xAE4E,0x0089,0x0085,0x0083,0xAE4D,0xD5E7,0x0083, 0xAE4C,0xAE4B,0x0085,0x0083,0xAE4A,0xAE49,0x0083,0xEAB3,0xAE48,0x0091,0x0089,0x0085,0x0083,0xAE47,0xAE46,0x0083, 0xAE45,0xAE44,0x0085,0x0083,0xAE43,0xAE42,0x0083,0xB4C9,0xC6BF,0x0089,0x0085,0x0083,0xAE41,0xEAB2,0x0083,0xAE40, 0xADA0,0x0085,0x0083,0xAD9F,0xAD9E,0x0083,0xEAB1,0xCECD,0x00A1,0x0091,0x0089,0x0085,0x0083,0xAD9D,0xAD9C,0x0083, 0xAD9B,0xAD9A,0x0085,0x0083,0xAD99,0xAD98,0x0083,0xAD97,0xCDDF,0x0089,0x0085,0x0083,0xAD96,0xC8BF,0x0083,0xB0EA, 0xC6B0,0x0085,0x0083,0xAD95,0xF0AD,0x0083,0xAD94,0xF0AC,0x0091,0x0089,0x0085,0x0083,0xAD93,0xB9CF,0x0083,0xAD92, 0xAD91,0x0085,0x0083,0xAD90,0xAD8F,0x0083,0xAD8E,0xAD8D,0x0089,0x0085,0x0083,0xAD8C,0xAD8B,0x0083,0xAD8A,0xE8B6, 0x0085,0x0083,0xAD89,0xAD88,0x0083,0xAD87,0xAD86,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xAD85,0xAD84, 0x0083,0xAD83,0xAD82,0x0085,0x0083,0xAD81,0xAD80,0x0083,0xAD7E,0xAD7D,0x0089,0x0085,0x0083,0xAD7C,0xAD7B,0x0083, 0xAD7A,0xAD79,0x0085,0x0083,0xAD78,0xAD77,0x0083,0xAD76,0xAD75,0x0091,0x0089,0x0085,0x0083,0xAD74,0xAD73,0x0083, 0xAD72,0xE8B7,0x0085,0x0083,0xAD71,0xAD70,0x0083,0xAD6F,0xAD6E,0x0089,0x0085,0x0083,0xAD6D,0xAD6C,0x0083,0xAD6B, 0xAD6A,0x0085,0x0083,0xAD69,0xAD68,0x0083,0xAD67,0xAD66,0x00A1,0x0091,0x0089,0x0085,0x0083,0xAD65,0xAD64,0x0083, 0xAD63,0xAD62,0x0085,0x0083,0xE8B3,0xE8B2,0x0083,0xE8B5,0xAD61,0x0089,0x0085,0x0083,0xAD60,0xAD5F,0x0083,0xAD5E, 0xAD5D,0x0085,0x0083,0xAD5C,0xAD5B,0x0083,0xAD5A,0xE8B1,0x0091,0x0089,0x0085,0x0083,0xAD59,0xE8AB,0x0083,0xAD58, 0xAD57,0x0085,0x0083,0xAD56,0xAD55,0x0083,0xAD54,0xAD53,0x0089,0x0085,0x0083,0xAD52,0xAD51,0x0083,0xAD50,0xAD4F, 0x0085,0x0083,0xAD4E,0xE8B4,0x0083,0xAD4D,0xE8AC,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xAD4C,0xAD4B,0x0083, 0xE8B0,0xAD4A,0x0085,0x0083,0xAD49,0xAD48,0x0083,0xE8AF,0xAD47,0x0089,0x0085,0x0083,0xAD46,0xAD45,0x0083,0xC1A7, 0xAD44,0x0085,0x0083,0xE8AE,0xE8AD,0x0083,0xAD43,0xE8AA,0x0091,0x0089,0x0085,0x0083,0xAD42,0xAD41,0x0083,0xAD40, 0xACA0,0x0085,0x0083,0xAC9F,0xAC9E,0x0083,0xE8A8,0xD1FE,0x0089,0x0085,0x0083,0xAC9D,0xAC9C,0x0083,0xAC9B,0xAC9A, 0x0085,0x0083,0xAC99,0xB9E5,0x0083,0xAC98,0xAC97,0x00A1,0x0091,0x0089,0x0085,0x0083,0xE8A9,0xAC96,0x0083,0xAC95, 0xAC94,0x0085,0x0083,0xAC93,0xAC92,0x0083,0xAC91,0xAC90,0x0089,0x0085,0x0083,0xAC8F,0xAC8E,0x0083,0xAC8D,0xAC8C, 0x0085,0x0083,0xAC8B,0xAC8A,0x0083,0xC9AA,0xC8F0,0x0091,0x0089,0x0085,0x0083,0xAC89,0xE8A4,0x0083,0xE7F8,0xBAF7, 0x0085,0x0083,0xE8A7,0xAC88,0x0083,0xE8A5,0xAC87,0x0089,0x0085,0x0083,0xE8A6,0xAC86,0x0083,0xAC85,0xAC84,0x0085, 0x0083,0xAC83,0xAC82,0x0083,0xAC81,0xAC80,0x047D,0x027F,0x017F,0x00FF,0x00BF,0x009F,0x008F,0x0087,0x0083,0xAC7E, 0x0083,0xAC7D,0xAC7C,0x0085,0x0083,0xAC7B,0xAC7A,0x0083,0xAC79,0xAC78,0x0089,0x0085,0x0083,0xAC77,0xAC76,0x0083, 0xAC75,0xAC74,0x0085,0x0083,0xAC73,0xE8A3,0x0083,0xAC72,0xAC71,0x0091,0x0089,0x0085,0x0083,0xAC70,0xAC6F,0x0083, 0xC7ED,0xAC6E,0x0085,0x0083,0xAC6D,0xAC6C,0x0083,0xAC6B,0xAC6A,0x0089,0x0085,0x0083,0xC5C3,0xC5FD,0x0083,0xC7D9, 0xC1D5,0x0085,0x0083,0xAC69,0xAC68,0x0083,0xE7FC,0xAC67,0x00A1,0x0091,0x0089,0x0085,0x0083,0xE7FD,0xAC66,0x0083, 0xE7FE,0xAC65,0x0085,0x0083,0xE7F7,0xAC64,0x0083,0xE7FB,0xAC63,0x0089,0x0085,0x0083,0xE7F9,0xE7FA,0x0083,0xAC62, 0xAC61,0x0085,0x0083,0xD7C1,0xAC60,0x0083,0xAC5F,0xAC5E,0x0091,0x0089,0x0085,0x0083,0xAC5D,0xAC5C,0x0083,0xAC5B, 0xE8A1,0x0085,0x0083,0xE8A2,0xAC5A,0x0083,0xAC59,0xAC58,0x0089,0x0085,0x0083,0xAC57,0xAC56,0x0083,0xAC55,0xAC54, 0x0085,0x0083,0xAC53,0xAC52,0x0083,0xCBF6,0xE7F6,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xAC51,0xAC50,0x0083, 0xAC4F,0xAC4E,0x0085,0x0083,0xE7F0,0xC1F0,0x0083,0xAC4D,0xAC4C,0x0089,0x0085,0x0083,0xC0ED,0xC0C5,0x0083,0xAC4B, 0xC7F2,0x0085,0x0083,0xAC4A,0xAC49,0x0083,0xAC48,0xAC47,0x0091,0x0089,0x0085,0x0083,0xAC46,0xAC45,0x0083,0xAC44, 0xAC43,0x0085,0x0083,0xAC42,0xAC41,0x0083,0xAC40,0xABA0,0x0089,0x0085,0x0083,0xAB9F,0xAB9E,0x0083,0xAB9D,0xAB9C, 0x0085,0x0083,0xE7F5,0xAB9B,0x0083,0xAB9A,0xAB99,0x00A1,0x0091,0x0089,0x0085,0x0083,0xAB98,0xB0E0,0x0083,0xAB97, 0xAB96,0x0085,0x0083,0xAB95,0xE7F1,0x0083,0xAB94,0xE7F2,0x0089,0x0085,0x0083,0xAB93,0xE7ED,0x0083,0xAB92,0xAB91, 0x0085,0x0083,0xAB90,0xAB8F,0x0083,0xD6E9,0xAB8E,0x0091,0x0089,0x0085,0x0083,0xE7F3,0xAB8D,0x0083,0xAB8C,0xAB8B, 0x0085,0x0083,0xAB8A,0xE7EE,0x0083,0xAB89,0xAB88,0x0089,0x0085,0x0083,0xAB87,0xAB86,0x0083,0xAB85,0xAB84,0x0085, 0x0083,0xAB83,0xE7E7,0x0083,0xB7A9,0xE7E5,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xAB82,0xD5E4,0x0083, 0xAB81,0xAB80,0x0085,0x0083,0xC9BA,0xE7EB,0x0083,0xE7EC,0xAB7E,0x0089,0x0085,0x0083,0xAB7D,0xAB7C,0x0083,0xAB7B, 0xAB7A,0x0085,0x0083,0xE7E6,0xAB79,0x0083,0xE7EA,0xAB78,0x0091,0x0089,0x0085,0x0083,0xAB77,0xAB76,0x0083,0xAB75, 0xB2A3,0x0085,0x0083,0xE7F4,0xAB74,0x0083,0xAB73,0xE7E8,0x0089,0x0085,0x0083,0xAB72,0xAB71,0x0083,0xAB70,0xE7E9, 0x0085,0x0083,0xC1E1,0xAB6F,0x0083,0xCFD6,0xBBB7,0x00A1,0x0091,0x0089,0x0085,0x0083,0xE7E2,0xAB6E,0x0083,0xAB6D, 0xC3B5,0x0085,0x0083,0xAB6C,0xCDE6,0x0083,0xAB6B,0xAB6A,0x0089,0x0085,0x0083,0xAB69,0xAB68,0x0083,0xAB67,0xAB66, 0x0085,0x0083,0xE7E3,0xAB65,0x0083,0xAB64,0xE7E4,0x0091,0x0089,0x0085,0x0083,0xAB63,0xAB62,0x0083,0xAB61,0xC2EA, 0x0085,0x0083,0xAB60,0xAB5F,0x0083,0xAB5E,0xAB5D,0x0089,0x0085,0x0083,0xBEC1,0xAB5C,0x0083,0xAB5B,0xAB5A,0x0085, 0x0083,0xAB59,0xE7E1,0x0083,0xAB58,0xAB57,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xE7E0,0xAB56,0x0083,0xAB55, 0xCDF5,0x0085,0x0083,0xAB54,0xD3F1,0x0083,0xAB53,0xC2CA,0x0089,0x0085,0x0083,0xAB52,0xAB51,0x0083,0xD0FE,0xAB50, 0x0085,0x0083,0xAB4F,0xAB4E,0x0083,0xAB4D,0xAB4C,0x0091,0x0089,0x0085,0x0083,0xE2B5,0xAB4B,0x0083,0xAB4A,0xAB49, 0x0085,0x0083,0xAB48,0xAB47,0x0083,0xAB46,0xAB45,0x0089,0x0085,0x0083,0xAB44,0xAB43,0x0083,0xAB42,0xAB41,0x0085, 0x0083,0xAB40,0xAAA0,0x0083,0xAA9F,0xE2B4,0x00A1,0x0091,0x0089,0x0085,0x0083,0xAA9E,0xCCA1,0x0083,0xE2B3,0xAA9D, 0x0085,0x0083,0xAA9C,0xAA9B,0x0083,0xAA9A,0xAA99,0x0089,0x0085,0x0083,0xAA98,0xAA97,0x0083,0xAA96,0xAA95,0x0085, 0x0083,0xAA94,0xAA93,0x0083,0xE2B2,0xAA92,0x0091,0x0089,0x0085,0x0083,0xAA91,0xAA90,0x0083,0xAA8F,0xAA8E,0x0085, 0x0083,0xAA8D,0xAA8C,0x0083,0xAA8B,0xE2B1,0x0089,0x0085,0x0083,0xAA8A,0xAA89,0x0083,0xAA88,0xAA87,0x0085,0x0083, 0xE9E1,0xAA86,0x0083,0xE2AF,0xAA85,0x017F,0x00FF,0x00BF,0x009F,0x008F,0x0087,0x0083,0xAA84,0x0083,0xE2B0,0xAA83, 0x0085,0x0083,0xAA82,0xAA81,0x0083,0xAA80,0xAA7E,0x0089,0x0085,0x0083,0xAA7D,0xAA7C,0x0083,0xAA7B,0xAA7A,0x0085, 0x0083,0xAA79,0xAA78,0x0083,0xAA77,0xAA76,0x0091,0x0089,0x0085,0x0083,0xD4B3,0xBBAB,0x0083,0xAA75,0xAA74,0x0085, 0x0083,0xAA73,0xAA72,0x0083,0xE2AA,0xE2AD,0x0089,0x0085,0x0083,0xE9E0,0xAA71,0x0083,0xAA70,0xBAEF,0x0085,0x0083, 0xAA6F,0xAA6E,0x0083,0xE2AE,0xAA6D,0x00A1,0x0091,0x0089,0x0085,0x0083,0xAA6C,0xCFD7,0x0083,0xAA6B,0xE2AC,0x0085, 0x0083,0xC3A8,0xD6ED,0x0083,0xD0C9,0xAA6A,0x0089,0x0085,0x0083,0xAA69,0xAA68,0x0083,0xE2AB,0xAA67,0x0085,0x0083, 0xAA66,0xE2A9,0x0083,0xE2A4,0xAA65,0x0091,0x0089,0x0085,0x0083,0xAA64,0xE2A6,0x0083,0xE2A7,0xB2C2,0x0085,0x0083, 0xC3CD,0xAA63,0x0083,0xAA62,0xAA61,0x0089,0x0085,0x0083,0xE2A2,0xB2FE,0x0083,0xE2A8,0xAA60,0x0085,0x0083,0xE2A3, 0xAA5F,0x0083,0xAA5E,0xAA5D,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xAA5C,0xC1D4,0x0083,0xAA5B,0xAA5A,0x0085, 0x0083,0xAA59,0xE2A5,0x0083,0xAA58,0xAA57,0x0089,0x0085,0x0083,0xAA56,0xAA55,0x0083,0xAA54,0xAA53,0x0085,0x0083, 0xE1FD,0xAA52,0x0083,0xE1FB,0xAA51,0x0091,0x0089,0x0085,0x0083,0xAA50,0xAA4F,0x0083,0xAA4E,0xC0C7,0x0085,0x0083, 0xE2A1,0xE1FE,0x0083,0xAA4D,0xC0EA,0x0089,0x0085,0x0083,0xE1FA,0xAA4C,0x0083,0xAA4B,0xE1F9,0x0085,0x0083,0xE1FC, 0xE1F8,0x0083,0xD3FC,0xD5F8,0x00A1,0x0091,0x0089,0x0085,0x0083,0xE1F6,0xCAA8,0x0083,0xCFC1,0xB6C0,0x0085,0x0083, 0xAA4A,0xAA49,0x0083,0xE1F7,0xE1F5,0x0089,0x0085,0x0083,0xAA48,0xAA47,0x0083,0xAA46,0xAA45,0x0085,0x0083,0xAA44, 0xAA43,0x0083,0xBDC6,0xBADD,0x0091,0x0089,0x0085,0x0083,0xAA42,0xC4FC,0x0083,0xAA41,0xAA40,0x0085,0x0083,0xA0FE, 0xA0FD,0x0083,0xBED1,0xA0FC,0x0089,0x0085,0x0083,0xB9B7,0xA0FB,0x0083,0xA0FA,0xA0F9,0x0085,0x0083,0xA0F8,0xE1F4, 0x0083,0xA0F7,0xBAFC,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xA0F6,0xE1F2,0x0083,0xE1F3,0xA0F5,0x0085, 0x0083,0xA0F4,0xA0F3,0x0083,0xA0F2,0xB1B7,0x0089,0x0085,0x0083,0xA0F1,0xA0F0,0x0083,0xA0EF,0xB5D2,0x0085,0x0083, 0xE1F0,0xBFF1,0x0083,0xE1F1,0xA0EE,0x0091,0x0089,0x0085,0x0083,0xA0ED,0xA0EC,0x0083,0xA0EB,0xA0EA,0x0085,0x0083, 0xA0E9,0xA0E8,0x0083,0xD3CC,0xE1EF,0x0089,0x0085,0x0083,0xE1EE,0xD7B4,0x0083,0xA0E7,0xE1ED,0x0085,0x0083,0xA0E6, 0xA0E5,0x0083,0xA0E4,0xE1EC,0x00A1,0x0091,0x0089,0x0085,0x0083,0xB7B8,0xA0E3,0x0083,0xE1EB,0xC8AE,0x0085,0x0083, 0xA0E2,0xA0E1,0x0083,0xA0E0,0xA0DF,0x0089,0x0085,0x0083,0xA0DE,0xA0DD,0x0083,0xA0DC,0xA0DB,0x0085,0x0083,0xA0DA, 0xA0D9,0x0083,0xA0D8,0xA0D7,0x0091,0x0089,0x0085,0x0083,0xEAF1,0xA0D6,0x0083,0xA0D5,0xA0D4,0x0085,0x0083,0xA0D3, 0xA0D2,0x0083,0xA0D1,0xA0D0,0x0089,0x0085,0x0083,0xA0CF,0xA0CE,0x0083,0xA0CD,0xA0CC,0x0085,0x0083,0xA0CB,0xEAFB, 0x0083,0xA0CA,0xA0C9,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xEAFA,0xA0C8,0x0083,0xEAF9,0xA0C7,0x0085,0x0083, 0xEAF8,0xB6BF,0x0083,0xA0C6,0xA0C5,0x0089,0x0085,0x0083,0xA0C4,0xA0C3,0x0083,0xA0C2,0xEAF7,0x0085,0x0083,0xA0C1, 0xA0C0,0x0083,0xC0E7,0xCFAC,0x0091,0x0089,0x0085,0x0083,0xEAF6,0xEAF5,0x0083,0xA0BF,0xA0BE,0x0085,0x0083,0xA0BD, 0xCEFE,0x0083,0xCCD8,0xA0BC,0x0089,0x0085,0x0083,0xA0BB,0xA0BA,0x0083,0xC7A3,0xA0B9,0x0085,0x0083,0xA0B8,0xC9FC, 0x0083,0xA0B7,0xA0B6,0x00A1,0x0091,0x0089,0x0085,0x0083,0xEAF4,0xEAF0,0x0083,0xA0B5,0xA0B4,0x0085,0x0083,0xA0B3, 0xA0B2,0x0083,0xCEEF,0xA0B1,0x0089,0x0085,0x0083,0xC4C1,0xEAF3,0x0083,0xA0B0,0xA0AF,0x0085,0x0083,0xA0AE,0xC0CE, 0x0083,0xC4B5,0xA0AD,0x0091,0x0089,0x0085,0x0083,0xC4B2,0xA0AC,0x0083,0xEAF2,0xA0AB,0x0085,0x0083,0xC5A3,0xA0AA, 0x0083,0xD1C0,0xA0A9,0x0089,0x0085,0x0083,0xA0A8,0xEBBB,0x0083,0xA0A7,0xA0A6,0x0085,0x0083,0xA0A5,0xEBBA,0x0083, 0xA0A4,0xA0A3,0x027F,0x017F,0x00FF,0x00BF,0x009F,0x008F,0x0087,0x0083,0xA0A2,0x0083,0xA0A1,0xEBB9,0x0085,0x0083, 0xC5C6,0xA0A0,0x0083,0xA09F,0xA09E,0x0089,0x0085,0x0083,0xB0E6,0xC6AC,0x0083,0xA09D,0xA09C,0x0085,0x0083,0xA09B, 0xA09A,0x0083,0xA099,0xA098,0x0091,0x0089,0x0085,0x0083,0xA097,0xE3DD,0x0083,0xA096,0xCBAC,0x0085,0x0083,0xA095, 0xD8B3,0x0083,0xA094,0xB5F9,0x0089,0x0085,0x0083,0xB0D6,0xD2AF,0x0083,0xB8B8,0xBEF4,0x0085,0x0083,0xA093,0xA092, 0x0083,0xA091,0xB0AE,0x00A1,0x0091,0x0089,0x0085,0x0083,0xEBBC,0xA090,0x0083,0xA08F,0xA08E,0x0085,0x0083,0xC5C0, 0xA08D,0x0083,0xD7A6,0xA08C,0x0089,0x0085,0x0083,0xECE0,0xA08B,0x0083,0xA08A,0xA089,0x0085,0x0083,0xA088,0xA087, 0x0083,0xA086,0xA085,0x0091,0x0089,0x0085,0x0083,0xA084,0xA083,0x0083,0xA082,0xECDF,0x0085,0x0083,0xA081,0xA080, 0x0083,0xA07E,0xA07D,0x0089,0x0085,0x0083,0xA07C,0xA07B,0x0083,0xA07A,0xA079,0x0085,0x0083,0xA078,0xA077,0x0083, 0xA076,0xA075,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xA074,0xA073,0x0083,0xA072,0xA071,0x0085,0x0083,0xA070, 0xA06F,0x0083,0xA06E,0xA06D,0x0089,0x0085,0x0083,0xA06C,0xA06B,0x0083,0xB1AC,0xA06A,0x0085,0x0083,0xA069,0xA068, 0x0083,0xA067,0xA066,0x0091,0x0089,0x0085,0x0083,0xA065,0xA064,0x0083,0xA063,0xA062,0x0085,0x0083,0xA061,0xA060, 0x0083,0xA05F,0xECDE,0x0089,0x0085,0x0083,0xA05E,0xA05D,0x0083,0xA05C,0xA05B,0x0085,0x0083,0xA05A,0xA059,0x0083, 0xA058,0xA057,0x00A1,0x0091,0x0089,0x0085,0x0083,0xA056,0xA055,0x0083,0xDBC6,0xA054,0x0085,0x0083,0xA053,0xA052, 0x0083,0xA051,0xA050,0x0089,0x0085,0x0083,0xA04F,0xECDD,0x0083,0xA04E,0xD4EF,0x0085,0x0083,0xA04D,0xA04C,0x0083, 0xA04B,0xA04A,0x0091,0x0089,0x0085,0x0083,0xECDB,0xA049,0x0083,0xA048,0xA047,0x0085,0x0083,0xA046,0xA045,0x0083, 0xA044,0xA043,0x0089,0x0085,0x0083,0xA042,0xA041,0x0083,0xA040,0xD1E0,0x0085,0x0083,0xECDC,0x9FFE,0x0083,0x9FFD, 0x9FFC,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x9FFB,0x9FFA,0x0083,0xC1C7,0x9FF9,0x0085,0x0083,0x9FF8, 0x9FF7,0x0083,0x9FF6,0x9FF5,0x0089,0x0085,0x0083,0x9FF4,0x9FF3,0x0083,0x9FF2,0x9FF1,0x0085,0x0083,0x9FF0,0xC8BC, 0x0083,0x9FEF,0x9FEE,0x0091,0x0089,0x0085,0x0083,0x9FED,0x9FEC,0x0083,0x9FEB,0x9FEA,0x0085,0x0083,0x9FE9,0x9FE8, 0x0083,0x9FE7,0xECE4,0x0089,0x0085,0x0083,0x9FE6,0x9FE5,0x0083,0x9FE4,0xECD8,0x0085,0x0083,0x9FE3,0xECD7,0x0083, 0x9FE2,0x9FE1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x9FE0,0x9FDF,0x0083,0x9FDE,0x9FDD,0x0085,0x0083,0xB0BE,0x9FDC, 0x0083,0x9FDB,0x9FDA,0x0089,0x0085,0x0083,0xECD9,0x9FD9,0x0083,0x9FD8,0x9FD7,0x0085,0x0083,0x9FD6,0x9FD5,0x0083, 0x9FD4,0x9FD3,0x0091,0x0089,0x0085,0x0083,0xECDA,0xCAEC,0x0083,0x9FD2,0x9FD1,0x0085,0x0083,0x9FD0,0x9FCF,0x0083, 0x9FCE,0xCEF5,0x0089,0x0085,0x0083,0xECD6,0x9FCD,0x0083,0x9FCC,0x9FCB,0x0085,0x0083,0xC8DB,0x9FCA,0x0083,0x9FC9, 0x9FC8,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x9FC7,0xD1AC,0x0083,0x9FC6,0x9FC5,0x0085,0x0083,0x9FC4,0x9FC3, 0x0083,0xD0DC,0x9FC2,0x0089,0x0085,0x0083,0x9FC1,0x9FC0,0x0083,0x9FBF,0x9FBE,0x0085,0x0083,0xCFA8,0x9FBD,0x0083, 0x9FBC,0x9FBB,0x0091,0x0089,0x0085,0x0083,0x9FBA,0x9FB9,0x0083,0x9FB8,0xC9BF,0x0085,0x0083,0x9FB7,0x9FB6,0x0083, 0xECD5,0x9FB5,0x0089,0x0085,0x0083,0xECD4,0x9FB4,0x0083,0x9FB3,0x9FB2,0x0085,0x0083,0x9FB1,0xECCE,0x0083,0xECD2, 0x9FB0,0x00A1,0x0091,0x0089,0x0085,0x0083,0x9FAF,0x9FAE,0x0083,0xD6F3,0x9FAD,0x0085,0x0083,0x9FAC,0x9FAB,0x0083, 0x9FAA,0x9FA9,0x0089,0x0085,0x0083,0xECD0,0xD5D5,0x0083,0xECE3,0x9FA8,0x0085,0x0083,0xC3BA,0x9FA7,0x0083,0x9FA6, 0x9FA5,0x0091,0x0089,0x0085,0x0083,0x9FA4,0x9FA3,0x0083,0xC9B7,0x9FA2,0x0085,0x0083,0xECCF,0x9FA1,0x0083,0x9FA0, 0x9F9F,0x0089,0x0085,0x0083,0x9F9E,0x9F9D,0x0083,0x9F9C,0x9F9B,0x0085,0x0083,0x9F9A,0x9F99,0x0083,0x9F98,0x9F97, 0x0181,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x9F96,0x9F95,0x0083,0xBCE5,0x9F94,0x0085,0x0083,0xBBCD, 0x9F93,0x0083,0xECD3,0x9F92,0x0089,0x0085,0x0083,0x9F91,0x9F90,0x0083,0x9F8F,0xECD1,0x0085,0x0083,0x9F8E,0x9F8D, 0x0083,0x9F8C,0x9F8B,0x0091,0x0089,0x0085,0x0083,0x9F8A,0x9F89,0x0083,0x9F88,0x9F87,0x0085,0x0083,0x9F86,0x9F85, 0x0083,0x9F84,0x9F83,0x0089,0x0085,0x0083,0x9F82,0x9F81,0x0083,0xC8BB,0x9F80,0x0085,0x0083,0x9F7E,0x9F7D,0x0083, 0x9F7C,0xECCD,0x00A1,0x0091,0x0089,0x0085,0x0083,0xD1E6,0xECCC,0x0083,0x9F7B,0x9F7A,0x0085,0x0083,0x9F79,0x9F78, 0x0083,0x9F77,0x9F76,0x0089,0x0085,0x0083,0x9F75,0x9F74,0x0083,0xBDB9,0x9F73,0x0085,0x0083,0x9F72,0x9F71,0x0083, 0x9F70,0x9F6F,0x0091,0x0089,0x0085,0x0083,0x9F6E,0x9F6D,0x0083,0x9F6C,0x9F6B,0x0085,0x0083,0x9F6A,0x9F69,0x0083, 0xB7D9,0xB1BA,0x0089,0x0085,0x0083,0xECE2,0x9F68,0x0083,0xECCB,0xBBC0,0x0085,0x0083,0x9F67,0xECCA,0x0083,0x9F66, 0x9F65,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xECC9,0x9F64,0x0083,0x9F63,0x9F62,0x0085,0x0083,0x9F61,0x9F60, 0x0083,0xBAB8,0xD1C9,0x0089,0x0085,0x0083,0x9F5F,0x9F5E,0x0083,0x9F5D,0x9F5C,0x0085,0x0083,0x9F5B,0x9F5A,0x0083, 0x9F59,0x9F58,0x0091,0x0089,0x0085,0x0083,0x9F57,0x9F56,0x0083,0x9F55,0xB7E9,0x0085,0x0083,0x9F54,0x9F53,0x0083, 0x9F52,0xC5EB,0x0089,0x0085,0x0083,0x9F51,0xCDE9,0x0083,0x9F50,0x9F4F,0x0085,0x0083,0x9F4E,0x9F4D,0x0083,0x9F4C, 0x9F4B,0x00A1,0x0091,0x0089,0x0085,0x0083,0x9F4A,0xCFA9,0x0083,0x9F49,0xC8C8,0x0085,0x0083,0xBDFD,0xCCCC,0x0083, 0x9F48,0xBBE2,0x0089,0x0085,0x0083,0xECC7,0xC9D5,0x0083,0xB7B3,0x9F47,0x0085,0x0083,0xBFBE,0x9F46,0x0083,0x9F45, 0x9F44,0x0091,0x0089,0x0085,0x0083,0x9F43,0xD1CC,0x0083,0x9F42,0x9F41,0x0085,0x0083,0x9F40,0xD6F2,0x0083,0x9EFE, 0xC0D3,0x0089,0x0085,0x0083,0xBAE6,0x9EFD,0x0083,0x9EFC,0x9EFB,0x0085,0x0083,0x9EFA,0x9EF9,0x0083,0x9EF8,0x9EF7, 0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x9EF6,0x9EF5,0x0083,0x9EF4,0x9EF3,0x0085,0x0083,0x9EF2,0x9EF1, 0x0083,0xECC8,0x9EF0,0x0089,0x0085,0x0083,0xC1D2,0x9EEF,0x0083,0x9EEE,0x9EED,0x0085,0x0083,0x9EEC,0xCCFE,0x0083, 0xC0C3,0xCBB8,0x0091,0x0089,0x0085,0x0083,0xECC3,0x9EEB,0x0083,0x9EEA,0xB3E3,0x0085,0x0083,0xC1B6,0xECC2,0x0083, 0x9EE9,0xB5E3,0x0089,0x0085,0x0083,0xD5A8,0xECC4,0x0083,0x9EE8,0x9EE7,0x0085,0x0083,0x9EE6,0xB1FE,0x0083,0x9EE5, 0xECC6,0x00A1,0x0091,0x0089,0x0085,0x0083,0x9EE4,0xBEBC,0x0083,0xC5DA,0xCCBF,0x0085,0x0083,0xBEE6,0xECC5,0x0083, 0x9EE3,0x9EE2,0x0089,0x0085,0x0083,0x9EE1,0x9EE0,0x0083,0x9EDF,0x9EDE,0x0085,0x0083,0x9EDD,0x9EDC,0x0083,0x9EDB, 0x9EDA,0x0091,0x0089,0x0085,0x0083,0x9ED9,0x9ED8,0x0083,0x9ED7,0xECC1,0x0085,0x0083,0xECBF,0x9ED6,0x0083,0x9ED5, 0xD6CB,0x0089,0x0085,0x0083,0x9ED4,0x9ED3,0x0083,0xECC0,0xBFBB,0x0085,0x0083,0xC8B2,0x9ED2,0x0083,0xB3B4,0x9ED1, 0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x9ED0,0x9ECF,0x0083,0xD1D7,0x9ECE,0x0085,0x0083,0x9ECD,0x9ECC,0x0083, 0xB4B6,0xC2AF,0x0089,0x0085,0x0083,0x9ECB,0x9ECA,0x0083,0x9EC9,0xEAC1,0x0085,0x0083,0x9EC8,0x9EC7,0x0083,0x9EC6, 0x9EC5,0x0091,0x0089,0x0085,0x0083,0xECBE,0xB2D3,0x0083,0xD4D6,0x9EC4,0x0085,0x0083,0xD7C6,0x9EC3,0x0083,0x9EC2, 0x9EC1,0x0089,0x0085,0x0083,0xBEC4,0x9EC0,0x0083,0xD4EE,0xC1E9,0x0085,0x0083,0x9EBF,0x9EBE,0x0083,0x9EBD,0x9EBC, 0x00A1,0x0091,0x0089,0x0085,0x0083,0xBBD2,0xB5C6,0x0083,0x9EBB,0xC3F0,0x0085,0x0083,0xECE1,0xBBF0,0x0083,0x9EBA, 0x9EB9,0x0089,0x0085,0x0083,0x9EB8,0x9EB7,0x0083,0x9EB6,0x9EB5,0x0085,0x0083,0x9EB4,0x9EB3,0x0083,0x9EB2,0x9EB1, 0x0091,0x0089,0x0085,0x0083,0x9EB0,0x9EAF,0x0083,0xE5B1,0x9EAE,0x0085,0x0083,0x9EAD,0x9EAC,0x0083,0x9EAB,0x9EAA, 0x0089,0x0085,0x0083,0x9EA9,0x9EA8,0x0083,0x9EA7,0x9EA6,0x0085,0x0083,0x9EA5,0x9EA4,0x0083,0x9EA3,0x9EA2,0x1075, 0x087B,0x047D,0x027F,0x017F,0x00FF,0x00BF,0x009F,0x008F,0x0087,0x0083,0x9EA1,0x0083,0xE5B0,0x9EA0,0x0085,0x0083, 0x9E9F,0xB9E0,0x0083,0x9E9E,0x9E9D,0x0089,0x0085,0x0083,0x9E9C,0x9E9B,0x0083,0x9E9A,0x9E99,0x0085,0x0083,0x9E98, 0x9E97,0x0083,0x9E96,0x9E95,0x0091,0x0089,0x0085,0x0083,0x9E94,0x9E93,0x0083,0x9E92,0x9E91,0x0085,0x0083,0x9E90, 0x9E8F,0x0083,0x9E8E,0x9E8D,0x0089,0x0085,0x0083,0xE5AE,0x9E8C,0x0083,0x9E8B,0x9E8A,0x0085,0x0083,0xE5AF,0x9E89, 0x0083,0x9E88,0x9E87,0x00A1,0x0091,0x0089,0x0085,0x0083,0x9E86,0x9E85,0x0083,0x9E84,0x9E83,0x0085,0x0083,0x9E82, 0x9E81,0x0083,0x9E80,0x9E7E,0x0089,0x0085,0x0083,0x9E7D,0x9E7C,0x0083,0x9E7B,0x9E7A,0x0085,0x0083,0x9E79,0x9E78, 0x0083,0xE5AC,0x9E77,0x0091,0x0089,0x0085,0x0083,0x9E76,0x9E75,0x0083,0x9E74,0x9E73,0x0085,0x0083,0x9E72,0x9E71, 0x0083,0xE5AD,0xE5AB,0x0089,0x0085,0x0083,0x9E70,0x9E6F,0x0083,0x9E6E,0x9E6D,0x0085,0x0083,0x9E6C,0x9E6B,0x0083, 0x9E6A,0x9E69,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xC6D9,0x9E68,0x0083,0x9E67,0x9E66,0x0085,0x0083,0x9E65, 0x9E64,0x0083,0x9E63,0x9E62,0x0089,0x0085,0x0083,0x9E61,0x9E60,0x0083,0x9E5F,0x9E5E,0x0085,0x0083,0x9E5D,0x9E5C, 0x0083,0x9E5B,0x9E5A,0x0091,0x0089,0x0085,0x0083,0x9E59,0x9E58,0x0083,0x9E57,0x9E56,0x0085,0x0083,0x9E55,0x9E54, 0x0083,0x9E53,0x9E52,0x0089,0x0085,0x0083,0x9E51,0x9E50,0x0083,0x9E4F,0x9E4E,0x0085,0x0083,0x9E4D,0x9E4C,0x0083, 0x9E4B,0x9E4A,0x00A1,0x0091,0x0089,0x0085,0x0083,0x9E49,0x9E48,0x0083,0xE5AA,0xE5A7,0x0085,0x0083,0x9E47,0x9E46, 0x0083,0x9E45,0x9E44,0x0089,0x0085,0x0083,0x9E43,0x9E42,0x0083,0x9E41,0x9E40,0x0085,0x0083,0x9DFE,0x9DFD,0x0083, 0x9DFC,0x9DFB,0x0091,0x0089,0x0085,0x0083,0xE5A6,0xE5A9,0x0083,0x9DFA,0xE5A8,0x0085,0x0083,0x9DF9,0x9DF8,0x0083, 0x9DF7,0x9DF6,0x0089,0x0085,0x0083,0x9DF5,0x9DF4,0x0083,0x9DF3,0x9DF2,0x0085,0x0083,0x9DF1,0x9DF0,0x0083,0x9DEF, 0xB1F4,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xE4FE,0x9DEE,0x0083,0x9DED,0x9DEC,0x0085,0x0083,0x9DEB, 0x9DEA,0x0083,0x9DE9,0x9DE8,0x0089,0x0085,0x0083,0xE5A1,0x9DE7,0x0083,0x9DE6,0x9DE5,0x0085,0x0083,0x9DE4,0x9DE3, 0x0083,0x9DE2,0xE5A5,0x0091,0x0089,0x0085,0x0083,0x9DE1,0xBCA4,0x0083,0x9DE0,0x9DDF,0x0085,0x0083,0x9DDE,0x9DDD, 0x0083,0x9DDC,0x9DDB,0x0089,0x0085,0x0083,0xE5A3,0x9DDA,0x0083,0x9DD9,0xE5A4,0x0085,0x0083,0x9DD8,0x9DD7,0x0083, 0xB0C4,0x9DD6,0x00A1,0x0091,0x0089,0x0085,0x0083,0x9DD5,0x9DD4,0x0083,0x9DD3,0x9DD2,0x0085,0x0083,0x9DD1,0x9DD0, 0x0083,0x9DCF,0x9DCE,0x0089,0x0085,0x0083,0x9DCD,0x9DCC,0x0083,0xE5A2,0x9DCB,0x0085,0x0083,0x9DCA,0x9DC9,0x0083, 0x9DC8,0x9DC7,0x0091,0x0089,0x0085,0x0083,0xD4E8,0x9DC6,0x0083,0x9DC5,0x9DC4,0x0085,0x0083,0x9DC3,0xC0BD,0x0083, 0x9DC2,0x9DC1,0x0089,0x0085,0x0083,0x9DC0,0x9DBF,0x0083,0x9DBE,0x9DBD,0x0085,0x0083,0x9DBC,0x9DBB,0x0083,0x9DBA, 0x9DB9,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x9DB8,0x9DB7,0x0083,0x9DB6,0xC5EC,0x0085,0x0083,0xE4F8,0xE4F9, 0x0083,0x9DB5,0x9DB4,0x0089,0x0085,0x0083,0xE4F7,0xB3BA,0x0083,0x9DB3,0x9DB2,0x0085,0x0083,0x9DB1,0xB3CE,0x0083, 0x9DB0,0x9DAF,0x0091,0x0089,0x0085,0x0083,0x9DAE,0x9DAD,0x0083,0x9DAC,0x9DAB,0x0085,0x0083,0x9DAA,0xE4FC,0x0083, 0x9DA9,0xE4FD,0x0089,0x0085,0x0083,0x9DA8,0xE4FA,0x0083,0x9DA7,0x9DA6,0x0085,0x0083,0x9DA5,0xE4F3,0x0083,0x9DA4, 0xE4FB,0x00A1,0x0091,0x0089,0x0085,0x0083,0x9DA3,0x9DA2,0x0083,0x9DA1,0xB3B1,0x0085,0x0083,0xCCB6,0x9DA0,0x0083, 0x9D9F,0x9D9E,0x0089,0x0085,0x0083,0x9D9D,0x9D9C,0x0083,0x9D9B,0xC1CA,0x0085,0x0083,0x9D9A,0x9D99,0x0083,0x9D98, 0xE4EA,0x0091,0x0089,0x0085,0x0083,0x9D97,0x9D96,0x0083,0x9D95,0xC2BA,0x0085,0x0083,0x9D94,0xC7B1,0x0083,0x9D93, 0x9D92,0x0089,0x0085,0x0083,0x9D91,0xC5CB,0x0083,0x9D90,0x9D8F,0x0085,0x0083,0x9D8E,0x9D8D,0x0083,0x9D8C,0x9D8B, 0x017F,0x00FF,0x00BF,0x009F,0x008F,0x0087,0x0083,0x9D8A,0x0083,0x9D89,0x9D88,0x0085,0x0083,0x9D87,0xCEAB,0x0083, 0x9D86,0xE4F2,0x0089,0x0085,0x0083,0x9D85,0x9D84,0x0083,0x9D83,0xE4EC,0x0085,0x0083,0xE4EB,0x9D82,0x0083,0x9D81, 0x9D80,0x0091,0x0089,0x0085,0x0083,0x9D7E,0x9D7D,0x0083,0x9D7C,0x9D7B,0x0085,0x0083,0xD1FA,0x9D7A,0x0083,0x9D79, 0x9D78,0x0089,0x0085,0x0083,0x9D77,0x9D76,0x0083,0x9D75,0x9D74,0x0085,0x0083,0xE4F1,0x9D73,0x0083,0x9D72,0xD5C4, 0x00A1,0x0091,0x0089,0x0085,0x0083,0x9D71,0xCAFE,0x0083,0x9D70,0xE4F0,0x0085,0x0083,0x9D6F,0xE4DD,0x0083,0x9D6E, 0xC2FE,0x0089,0x0085,0x0083,0xE4F4,0xE4F6,0x0083,0x9D6D,0x9D6C,0x0085,0x0083,0x9D6B,0x9D6A,0x0083,0xE4ED,0x9D69, 0x0091,0x0089,0x0085,0x0083,0x9D68,0x9D67,0x0083,0xC4AE,0x9D66,0x0085,0x0083,0x9D65,0x9D64,0x0083,0x9D63,0x9D62, 0x0089,0x0085,0x0083,0x9D61,0x9D60,0x0083,0x9D5F,0x9D5E,0x0085,0x0083,0x9D5D,0xE4EE,0x0083,0xD1DD,0xC0EC,0x00C1, 0x00A1,0x0091,0x0089,0x0085,0x0083,0x9D5C,0x9D5B,0x0083,0x9D5A,0xC2A9,0x0085,0x0083,0x9D59,0x9D58,0x0083,0x9D57, 0x9D56,0x0089,0x0085,0x0083,0x9D55,0xE4F5,0x0083,0x9D54,0x9D53,0x0085,0x0083,0xC6E1,0x9D52,0x0083,0x9D51,0x9D50, 0x0091,0x0089,0x0085,0x0083,0xC6AF,0x9D4F,0x0083,0x9D4E,0x9D4D,0x0085,0x0083,0x9D4C,0x9D4B,0x0083,0x9D4A,0x9D49, 0x0089,0x0085,0x0083,0x9D48,0xE4EF,0x0083,0x9D47,0x9D46,0x0085,0x0083,0x9D45,0x9D44,0x0083,0xB5CE,0x9D43,0x00A1, 0x0091,0x0089,0x0085,0x0083,0x9D42,0x9D41,0x0083,0x9D40,0x9CFE,0x0085,0x0083,0x9CFD,0x9CFC,0x0083,0x9CFB,0x9CFA, 0x0089,0x0085,0x0083,0x9CF9,0xCCB2,0x0083,0xB1F5,0x9CF8,0x0085,0x0083,0xC2D0,0xC0C4,0x0083,0xC2CB,0x9CF7,0x0091, 0x0089,0x0085,0x0083,0xE4DE,0xC2FA,0x0083,0xE4DC,0xE4D9,0x0085,0x0083,0xD6CD,0x9CF6,0x0083,0x9CF5,0x9CF4,0x0089, 0x0085,0x0083,0xB9F6,0x9CF3,0x0083,0x9CF2,0xE4E4,0x0085,0x0083,0x9CF1,0xEBF8,0x0083,0xCCCF,0xD7D2,0x0101,0x00C1, 0x00A1,0x0091,0x0089,0x0085,0x0083,0x9CF0,0xBBAC,0x0083,0x9CEF,0xE4E6,0x0085,0x0083,0x9CEE,0x9CED,0x0083,0x9CEC, 0xD7CC,0x0089,0x0085,0x0083,0x9CEB,0x9CEA,0x0083,0x9CE9,0xB5E1,0x0085,0x0083,0x9CE8,0x9CE7,0x0083,0x9CE6,0x9CE5, 0x0091,0x0089,0x0085,0x0083,0xE4E8,0xB3FC,0x0083,0x9CE4,0x9CE3,0x0085,0x0083,0x9CE2,0xE4E1,0x0083,0x9CE1,0xE4E2, 0x0089,0x0085,0x0083,0xC4E7,0x9CE0,0x0083,0x9CDF,0xE4E3,0x0085,0x0083,0xC8DC,0x9CDE,0x0083,0xE4E5,0x9CDD,0x00A1, 0x0091,0x0089,0x0085,0x0083,0xE4D1,0xE4DA,0x0083,0x9CDC,0xCBDD,0x0085,0x0083,0x9CDB,0x9CDA,0x0083,0x9CD9,0x9CD8, 0x0089,0x0085,0x0083,0xCFAA,0x9CD7,0x0083,0x9CD6,0xE4E0,0x0085,0x0083,0x9CD5,0xE4DF,0x0083,0x9CD4,0x9CD3,0x0091, 0x0089,0x0085,0x0083,0xD2E7,0x9CD2,0x0083,0x9CD1,0xE4E9,0x0085,0x0083,0x9CD0,0x9CCF,0x0083,0xC1EF,0x9CCE,0x0089, 0x0085,0x0083,0x9CCD,0x9CCC,0x0083,0xE4DB,0x9CCB,0x0085,0x0083,0x9CCA,0x9CC9,0x0083,0x9CC8,0x9CC7,0x00C1,0x00A1, 0x0091,0x0089,0x0085,0x0083,0x9CC6,0x9CC5,0x0083,0xD4B4,0xE4E7,0x0085,0x0083,0x9CC4,0x9CC3,0x0083,0x9CC2,0x9CC1, 0x0089,0x0085,0x0083,0x9CC0,0xB8C8,0x0083,0x9CBF,0x9CBE,0x0085,0x0083,0xE4D3,0xBDA6,0x0083,0x9CBD,0xC0A3,0x0091, 0x0089,0x0085,0x0083,0x9CBC,0x9CBB,0x0083,0x9CBA,0xCAAA,0x0085,0x0083,0xCDE5,0x9CB9,0x0083,0x9CB8,0x9CB7,0x0089, 0x0085,0x0083,0x9CB6,0x9CB5,0x0083,0x9CB4,0x9CB3,0x0085,0x0083,0x9CB2,0x9CB1,0x0083,0x9CB0,0x9CAF,0x00A1,0x0091, 0x0089,0x0085,0x0083,0x9CAE,0x9CAD,0x0083,0x9CAC,0x9CAB,0x0085,0x0083,0xE4CE,0x9CAA,0x0083,0x9CA9,0xE4D0,0x0089, 0x0085,0x0083,0x9CA8,0x9CA7,0x0083,0x9CA6,0x9CA5,0x0085,0x0083,0x9CA4,0x9CA3,0x0083,0x9CA2,0x9CA1,0x0091,0x0089, 0x0085,0x0083,0x9CA0,0x9C9F,0x0083,0x9C9E,0xE4D2,0x0085,0x0083,0x9C9D,0x9C9C,0x0083,0x9C9B,0xD5BF,0x0089,0x0085, 0x0083,0x9C9A,0x9C99,0x0083,0xCFE6,0x9C98,0x0085,0x0083,0xBAFE,0x9C97,0x0083,0xE4D5,0xE4D4,0x027F,0x017F,0x00FF, 0x00BF,0x009F,0x008F,0x0087,0x0083,0x9C96,0x0083,0x9C95,0x9C94,0x0085,0x0083,0x9C93,0xE4CF,0x0083,0xCDC4,0x9C92, 0x0089,0x0085,0x0083,0x9C91,0x9C90,0x0083,0x9C8F,0x9C8E,0x0085,0x0083,0x9C8D,0x9C8C,0x0083,0x9C8B,0xE4D8,0x0091, 0x0089,0x0085,0x0083,0xC5C8,0x9C8A,0x0083,0x9C89,0x9C88,0x0085,0x0083,0x9C87,0x9C86,0x0083,0x9C85,0x9C84,0x0089, 0x0085,0x0083,0x9C83,0xC3EC,0x0083,0x9C82,0xD3CE,0x0085,0x0083,0x9C81,0x9C80,0x0083,0x9C7E,0xBFCA,0x00A1,0x0091, 0x0089,0x0085,0x0083,0x9C7D,0xE4D6,0x0083,0x9C7C,0x9C7B,0x0085,0x0083,0xB8DB,0x9C7A,0x0083,0xCEBC,0x9C79,0x0089, 0x0085,0x0083,0xE4CD,0x9C78,0x0083,0xCEC2,0x9C77,0x0085,0x0083,0x9C76,0x9C75,0x0083,0xE4D7,0xB2B3,0x0091,0x0089, 0x0085,0x0083,0xD4FC,0x9C74,0x0083,0xB6C9,0xC7FE,0x0085,0x0083,0x9C73,0x9C72,0x0083,0xD3E5,0x9C71,0x0089,0x0085, 0x0083,0x9C70,0xE4BE,0x0083,0x9C6F,0x9C6E,0x0085,0x0083,0xC9F8,0xE4C9,0x0083,0x9C6D,0xD3E6,0x00C1,0x00A1,0x0091, 0x0089,0x0085,0x0083,0x9C6C,0x9C6B,0x0083,0xE4C5,0xBDA5,0x0085,0x0083,0x9C6A,0xE4C2,0x0083,0xD7D5,0xE4CB,0x0089, 0x0085,0x0083,0x9C69,0xD4A8,0x0083,0x9C68,0x9C67,0x0085,0x0083,0x9C66,0x9C65,0x0083,0xC7E5,0x9C64,0x0091,0x0089, 0x0085,0x0083,0x9C63,0x9C62,0x0083,0x9C61,0x9C60,0x0085,0x0083,0x9C5F,0x9C5E,0x0083,0x9C5D,0xEDB5,0x0089,0x0085, 0x0083,0xCCED,0x9C5C,0x0083,0xD1CD,0x9C5B,0x0085,0x0083,0xBBEC,0x9C5A,0x0083,0x9C59,0x9C58,0x00A1,0x0091,0x0089, 0x0085,0x0083,0xB4BE,0x9C57,0x0083,0xC9EE,0x9C56,0x0085,0x0083,0x9C55,0xBBB4,0x0083,0x9C54,0xB4E3,0x0089,0x0085, 0x0083,0xD2F9,0x9C53,0x0083,0x9C52,0x9C51,0x0085,0x0083,0x9C50,0xE4C6,0x0083,0x9C4F,0xD3D9,0x0091,0x0089,0x0085, 0x0083,0x9C4E,0x9C4D,0x0083,0xB5AD,0xE4C4,0x0085,0x0083,0x9C4C,0xE4C1,0x0083,0xE4C7,0x9C4B,0x0089,0x0085,0x0083, 0x9C4A,0x9C49,0x0083,0xE4C8,0xCCD4,0x0085,0x0083,0x9C48,0xC4D7,0x0083,0x9C47,0x9C46,0x0101,0x00C1,0x00A1,0x0091, 0x0089,0x0085,0x0083,0x9C45,0x9C44,0x0083,0xCAE7,0x9C43,0x0085,0x0083,0x9C42,0x9C41,0x0083,0x9C40,0xCCCA,0x0089, 0x0085,0x0083,0xC1DC,0x9BFE,0x0083,0x9BFD,0x9BFC,0x0085,0x0083,0xE4BF,0xCFFD,0x0083,0xE4C0,0xD7CD,0x0091,0x0089, 0x0085,0x0083,0x9BFB,0x9BFA,0x0083,0x9BF9,0xB5ED,0x0085,0x0083,0xE4C3,0x9BF8,0x0083,0x9BF7,0x9BF6,0x0089,0x0085, 0x0083,0x9BF5,0x9BF4,0x0083,0x9BF3,0xBAD4,0x0085,0x0083,0x9BF2,0x9BF1,0x0083,0xBAAD,0x9BF0,0x00A1,0x0091,0x0089, 0x0085,0x0083,0x9BEF,0xD2BA,0x0083,0x9BEE,0x9BED,0x0085,0x0083,0xD1C4,0xE4CC,0x0083,0x9BEC,0x9BEB,0x0089,0x0085, 0x0083,0xE4CA,0xB8A2,0x0083,0xC9AC,0xD5C7,0x0085,0x0083,0xBDA7,0xC8F3,0x0083,0x9BEA,0xB5D3,0x0091,0x0089,0x0085, 0x0083,0xBBC1,0x9BE9,0x0083,0xCED0,0xE4B6,0x0085,0x0083,0xC1B0,0xE4B5,0x0083,0xC0D4,0x9BE8,0x0089,0x0085,0x0083, 0xCCCE,0x9BE7,0x0083,0x9BE6,0x9BE5,0x0085,0x0083,0x9BE4,0x9BE3,0x0083,0xCCE9,0xE4B9,0x00C1,0x00A1,0x0091,0x0089, 0x0085,0x0083,0xE4B8,0x9BE2,0x0083,0xE4B3,0x9BE1,0x0085,0x0083,0x9BE0,0xCFD1,0x0083,0x9BDF,0xD3BF,0x0089,0x0085, 0x0083,0x9BDE,0x9BDD,0x0083,0xC9E6,0xCFFB,0x0085,0x0083,0x9BDC,0x9BDB,0x0083,0xC4F9,0x9BDA,0x0091,0x0089,0x0085, 0x0083,0x9BD9,0xCDBF,0x0083,0x9BD8,0x9BD7,0x0085,0x0083,0x9BD6,0x9BD5,0x0083,0x9BD4,0xE4BC,0x0089,0x0085,0x0083, 0x9BD3,0x9BD2,0x0083,0x9BD1,0xBDFE,0x0085,0x0083,0xBAA3,0x9BD0,0x0083,0x9BCF,0xD4A1,0x00A1,0x0091,0x0089,0x0085, 0x0083,0x9BCE,0x9BCD,0x0083,0x9BCC,0x9BCB,0x0085,0x0083,0xE4B4,0xB8A1,0x0083,0x9BCA,0x9BC9,0x0089,0x0085,0x0083, 0x9BC8,0xC0CB,0x0083,0xBAC6,0x9BC7,0x0085,0x0083,0x9BC6,0xC6D6,0x0083,0x9BC5,0x9BC4,0x0091,0x0089,0x0085,0x0083, 0xE4BD,0x9BC3,0x0083,0x9BC2,0xE4BB,0x0085,0x0083,0x9BC1,0xE4B7,0x0083,0x9BC0,0xE4BA,0x0089,0x0085,0x0083,0x9BBF, 0xBFA3,0x0083,0xD5E3,0x9BBE,0x0085,0x0083,0x9BBD,0x9BBC,0x0083,0x9BBB,0xE4B1,0x0181,0x0101,0x00C1,0x00A1,0x0091, 0x0089,0x0085,0x0083,0xC5A8,0xE4B0,0x0083,0xBBEB,0x9BBA,0x0085,0x0083,0xE4AF,0xBCC3,0x0083,0xE4AB,0x9BB9,0x0089, 0x0085,0x0083,0xB2E2,0xD7C7,0x0083,0x9BB8,0xE4A5,0x0085,0x0083,0xBDBD,0xBDAC,0x0083,0xC7B3,0x9BB7,0x0091,0x0089, 0x0085,0x0083,0xE4A4,0x9BB6,0x0083,0xC1F7,0x9BB5,0x0085,0x0083,0x9BB4,0xC5C9,0x0083,0xC7A2,0xCDDD,0x0089,0x0085, 0x0083,0xBBEE,0x9BB3,0x0083,0xE4A1,0x9BB2,0x0085,0x0083,0x9BB1,0x9BB0,0x0083,0xE4AD,0x9BAF,0x00A1,0x0091,0x0089, 0x0085,0x0083,0xE4B2,0xD6DE,0x0083,0xB6FD,0x9BAE,0x0085,0x0083,0x9BAD,0xE4AC,0x0083,0x9BAC,0x9BAB,0x0089,0x0085, 0x0083,0xE4AA,0xBAE9,0x0083,0x9BAA,0x9BA9,0x0085,0x0083,0xE4A2,0x9BA8,0x0083,0xBDF2,0x9BA7,0x0091,0x0089,0x0085, 0x0083,0x9BA6,0x9BA5,0x0083,0x9BA4,0x9BA3,0x0085,0x0083,0x9BA2,0xB6B4,0x0083,0x9BA1,0x9BA0,0x0089,0x0085,0x0083, 0xC2E5,0xE4AE,0x0083,0xE4A8,0x9B9F,0x0085,0x0083,0xCFB4,0x9B9E,0x0083,0x9B9D,0x9B9C,0x00C1,0x00A1,0x0091,0x0089, 0x0085,0x0083,0x9B9B,0xC8F7,0x0083,0x9B9A,0x9B99,0x0085,0x0083,0x9B98,0xE4A9,0x0083,0x9B97,0xE4A3,0x0089,0x0085, 0x0083,0xD1F3,0x9B96,0x0083,0x9B95,0x9B94,0x0085,0x0083,0xE4A6,0x9B93,0x0083,0x9B92,0xE4A7,0x0091,0x0089,0x0085, 0x0083,0x9B91,0x9B90,0x0083,0xBDE0,0x9B8F,0x0085,0x0083,0x9B8E,0xE3FE,0x0083,0xD4F3,0xC6C3,0x0089,0x0085,0x0083, 0xD0BA,0xE3F8,0x0083,0x9B8D,0xE3F2,0x0085,0x0083,0xE3F1,0xEDB4,0x0083,0xB1C3,0x9B8C,0x00A1,0x0091,0x0089,0x0085, 0x0083,0xD3BE,0x9B8B,0x0083,0xE3F3,0xCCA9,0x0085,0x0083,0xE3FD,0xE3FA,0x0083,0x9B8A,0x9B89,0x0089,0x0085,0x0083, 0xE3F9,0xC0E1,0x0083,0x9B88,0xD7A2,0x0085,0x0083,0x9B87,0x9B86,0x0083,0xC4E0,0x9B85,0x0091,0x0089,0x0085,0x0083, 0xC6FC,0xB2A8,0x0083,0xC5DD,0xE3F6,0x0085,0x0083,0x9B84,0xC5A2,0x0083,0x9B83,0x9B82,0x0089,0x0085,0x0083,0xB7BA, 0x9B81,0x0083,0x9B80,0x9B7E,0x0085,0x0083,0xE3F4,0xE3F7,0x0083,0xB7A8,0xE3EF,0x0101,0x00C1,0x00A1,0x0091,0x0089, 0x0085,0x0083,0xE3FC,0x9B7D,0x0083,0x9B7C,0xE3EE,0x0085,0x0083,0x9B7B,0x9B7A,0x0083,0x9B79,0xC3DA,0x0089,0x0085, 0x0083,0x9B78,0xB2B4,0x0083,0xC8AA,0x9B77,0x0085,0x0083,0x9B76,0x9B75,0x0083,0xC7F6,0xD0B9,0x0091,0x0089,0x0085, 0x0083,0x9B74,0x9B73,0x0083,0x9B72,0x9B71,0x0085,0x0083,0xD1D8,0xD5B4,0x0083,0xB9C1,0xD5D3,0x0089,0x0085,0x0083, 0xD6CE,0x9B70,0x0083,0xD3CD,0xB7D0,0x0085,0x0083,0x9B6F,0x9B6E,0x0083,0x9B6D,0x9B6C,0x00A1,0x0091,0x0089,0x0085, 0x0083,0xBAD3,0xE3F5,0x0083,0xE3FB,0x9B6B,0x0085,0x0083,0x9B6A,0xBEDA,0x0083,0xE3F0,0x9B69,0x0089,0x0085,0x0083, 0xC4AD,0xBBA6,0x0083,0xE3ED,0x9B68,0x0085,0x0083,0xB2D7,0xC2D9,0x0083,0xC1A4,0xC5BD,0x0091,0x0089,0x0085,0x0083, 0xE3E3,0x9B67,0x0083,0xC3BB,0x9B66,0x0085,0x0083,0xB9B5,0x9B65,0x0083,0x9B64,0x9B63,0x0089,0x0085,0x0083,0xC5E6, 0x9B62,0x0083,0xC9B3,0x9B61,0x0085,0x0083,0x9B60,0x9B5F,0x0083,0x9B5E,0xE3E6,0x00C1,0x00A1,0x0091,0x0089,0x0085, 0x0083,0xEDB3,0x9B5D,0x0083,0x9B5C,0xE3E5,0x0085,0x0083,0xC6E3,0x9B5B,0x0083,0x9B5A,0xE3E7,0x0089,0x0085,0x0083, 0x9B59,0x9B58,0x0083,0xB3C1,0xC9F2,0x0085,0x0083,0x9B57,0xE3EC,0x0083,0xE3E4,0x9B56,0x0091,0x0089,0x0085,0x0083, 0xCED6,0xD2CA,0x0083,0xC7DF,0x9B55,0x0085,0x0083,0x9B54,0xB7DA,0x0083,0xC6FB,0x9B53,0x0089,0x0085,0x0083,0x9B52, 0x9B51,0x0083,0xD0DA,0x9B50,0x0085,0x0083,0x9B4F,0xE3EB,0x0083,0x9B4E,0xE3EA,0x00A1,0x0091,0x0089,0x0085,0x0083, 0x9B4D,0xBCB3,0x0083,0x9B4C,0xCCAD,0x0085,0x0083,0x9B4B,0x9B4A,0x0083,0x9B49,0x9B48,0x0089,0x0085,0x0083,0x9B47, 0xCDF4,0x0083,0xE3E9,0xE3E8,0x0085,0x0083,0x9B46,0x9B45,0x0083,0x9B44,0xCCC0,0x0091,0x0089,0x0085,0x0083,0x9B43, 0x9B42,0x0083,0xCEDB,0xB3D8,0x0085,0x0083,0xBDAD,0xB9AF,0x0083,0xC8EA,0xE3E1,0x0089,0x0085,0x0083,0xD1B4,0x9B41, 0x0083,0x9B40,0x9AFE,0x0085,0x0083,0xBAB9,0x9AFD,0x0083,0xC9C7,0xE3E0,0x047D,0x027F,0x017F,0x00FF,0x00BF,0x009F, 0x008F,0x0087,0x0083,0x9AFC,0x0083,0x9AFB,0x9AFA,0x0085,0x0083,0xCFAB,0x9AF9,0x0083,0x9AF8,0x9AF7,0x0089,0x0085, 0x0083,0x9AF6,0x9AF5,0x0083,0xE3E2,0xBABA,0x0085,0x0083,0x9AF4,0xBBE3,0x0083,0xD9E0,0x9AF3,0x0091,0x0089,0x0085, 0x0083,0x9AF2,0x9AF1,0x0083,0xC7F3,0xD6AD,0x0085,0x0083,0xCDA1,0x9AF0,0x0083,0x9AEF,0xD9DB,0x0089,0x0085,0x0083, 0x9AEE,0x9AED,0x0083,0x9AEC,0x9AEB,0x0085,0x0083,0xD3C0,0x9AEA,0x0083,0x9AE9,0xE3DF,0x00A1,0x0091,0x0089,0x0085, 0x0083,0xCBAE,0x9AE8,0x0083,0xEBB5,0x9AE7,0x0085,0x0083,0xC7E8,0xC2C8,0x0083,0xB5AA,0x9AE6,0x0089,0x0085,0x0083, 0x9AE5,0x9AE4,0x0083,0xEBB4,0xEBB2,0x0085,0x0083,0xB0B1,0xD1F5,0x0083,0xBAA4,0x9AE3,0x0091,0x0089,0x0085,0x0083, 0xEBB3,0x9AE2,0x0083,0xC7E2,0xEBB1,0x0085,0x0083,0x9AE1,0xB7FA,0x0083,0x9AE0,0x9ADF,0x0089,0x0085,0x0083,0x9ADE, 0xB7D5,0x0083,0xEBB0,0xEBAF,0x0085,0x0083,0xEBAE,0x9ADD,0x0083,0xC4CA,0xEBAD,0x00C1,0x00A1,0x0091,0x0089,0x0085, 0x0083,0xC6F8,0xC3A5,0x0083,0x9ADC,0xC3F1,0x0085,0x0083,0xD8B5,0xCACF,0x0083,0x9ADB,0xEBAC,0x0089,0x0085,0x0083, 0x9ADA,0x9AD9,0x0083,0x9AD8,0x9AD7,0x0085,0x0083,0x9AD6,0xEBAA,0x0083,0xEBAB,0xEBA9,0x0091,0x0089,0x0085,0x0083, 0x9AD5,0x9AD4,0x0083,0x9AD3,0x9AD2,0x0085,0x0083,0x9AD1,0x9AD0,0x0083,0x9ACF,0xEBA6,0x0089,0x0085,0x0083,0x9ACE, 0x9ACD,0x0083,0x9ACC,0xEBA8,0x0085,0x0083,0x9ACB,0x9ACA,0x0083,0x9AC9,0xEBA7,0x00A1,0x0091,0x0089,0x0085,0x0083, 0x9AC8,0xEBA5,0x0083,0x9AC7,0x9AC6,0x0085,0x0083,0x9AC5,0xCCBA,0x0083,0x9AC4,0x9AC3,0x0089,0x0085,0x0083,0x9AC2, 0xBAC1,0x0083,0xEBA4,0x9AC1,0x0085,0x0083,0x9AC0,0x9ABF,0x0083,0x9ABE,0x9ABD,0x0091,0x0089,0x0085,0x0083,0x9ABC, 0x9ABB,0x0083,0x9ABA,0xD5B1,0x0085,0x0083,0x9AB9,0x9AB8,0x0083,0x9AB7,0x9AB6,0x0089,0x0085,0x0083,0x9AB5,0xC3AB, 0x0083,0x9AB4,0xB1D0,0x0085,0x0083,0x9AB3,0xC5FE,0x0083,0xB1D1,0xB1CF,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085, 0x0083,0xB1C8,0xD8B9,0x0083,0xB6BE,0x9AB2,0x0085,0x0083,0x9AB1,0xC3BF,0x0083,0x9AB0,0xC4B8,0x0089,0x0085,0x0083, 0x9AAF,0xCEE3,0x0083,0x9AAE,0x9AAD,0x0085,0x0083,0x9AAC,0x9AAB,0x0083,0x9AAA,0xD2E3,0x0091,0x0089,0x0085,0x0083, 0x9AA9,0x9AA8,0x0083,0xECB1,0xBBD9,0x0085,0x0083,0x9AA7,0xB5EE,0x0083,0x9AA6,0x9AA5,0x0089,0x0085,0x0083,0x9AA4, 0x9AA3,0x0083,0x9AA2,0x9AA1,0x0085,0x0083,0x9AA0,0xD2F3,0x0083,0x9A9F,0xB6CE,0x00A1,0x0091,0x0089,0x0085,0x0083, 0xC5B9,0xECAF,0x0083,0x9A9E,0x9A9D,0x0085,0x0083,0x9A9C,0x9A9B,0x0083,0x9A9A,0x9A99,0x0089,0x0085,0x0083,0x9A98, 0x9A97,0x0083,0xE9EC,0x9A96,0x0085,0x0083,0x9A95,0x9A94,0x0083,0x9A93,0x9A92,0x0091,0x0089,0x0085,0x0083,0x9A91, 0x9A90,0x0083,0x9A8F,0xE9EB,0x0085,0x0083,0x9A8E,0x9A8D,0x0083,0x9A8C,0x9A8B,0x0089,0x0085,0x0083,0x9A8A,0xE9EA, 0x0083,0xE9E9,0x9A89,0x0085,0x0083,0x9A88,0x9A87,0x0083,0xD6B3,0x9A86,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083, 0x9A85,0xE9E7,0x0083,0xE9E6,0x9A84,0x0085,0x0083,0x9A83,0x9A82,0x0083,0x9A81,0xE9E8,0x0089,0x0085,0x0083,0x9A80, 0xB2D0,0x0083,0xCAE2,0xD1B3,0x0085,0x0083,0x9A7E,0xE9E4,0x0083,0xB4F9,0x9A7D,0x0091,0x0089,0x0085,0x0083,0xE9E5, 0xD1EA,0x0083,0xE9E3,0xE9E2,0x0085,0x0083,0x9A7C,0x9A7B,0x0083,0x9A7A,0x9A79,0x0089,0x0085,0x0083,0xBCDF,0xCBC0, 0x0083,0x9A78,0xB4F5,0x0085,0x0083,0x9A77,0x9A76,0x0083,0x9A75,0x9A74,0x00A1,0x0091,0x0089,0x0085,0x0083,0x9A73, 0x9A72,0x0083,0x9A71,0x9A70,0x0085,0x0083,0x9A6F,0x9A6E,0x0083,0x9A6D,0x9A6C,0x0089,0x0085,0x0083,0x9A6B,0x9A6A, 0x0083,0xCDE1,0x9A69,0x0085,0x0083,0x9A68,0xC6E7,0x0083,0xCEE4,0xB2BD,0x0091,0x0089,0x0085,0x0083,0xB4CB,0xD5FD, 0x0083,0xD6B9,0x9A67,0x0085,0x0083,0x9A66,0x9A65,0x0083,0x9A64,0x9A63,0x0089,0x0085,0x0083,0x9A62,0x9A61,0x0083, 0x9A60,0xECA8,0x0085,0x0083,0x9A5F,0x9A5E,0x0083,0x9A5D,0x9A5C,0x017F,0x00FF,0x00BF,0x009F,0x008F,0x0087,0x0083, 0x9A5B,0x0083,0x9A5A,0x9A59,0x0085,0x0083,0x9A58,0x9A57,0x0083,0x9A56,0x9A55,0x0089,0x0085,0x0083,0x9A54,0xB8E8, 0x0083,0x9A53,0x9A52,0x0085,0x0083,0xC7B8,0x9A51,0x0083,0xD0AA,0xECA7,0x0091,0x0089,0x0085,0x0083,0x9A50,0x9A4F, 0x0083,0xECA6,0x9A4E,0x0085,0x0083,0x9A4D,0x9A4C,0x0083,0x9A4B,0xBFEE,0x0089,0x0085,0x0083,0x9A4A,0x9A49,0x0083, 0x9A48,0xC6DB,0x0085,0x0083,0xECA5,0x9A47,0x0083,0xECA4,0x9A46,0x00A1,0x0091,0x0089,0x0085,0x0083,0x9A45,0x9A44, 0x0083,0x9A43,0xD3FB,0x0085,0x0083,0x9A42,0x9A41,0x0083,0x9A40,0x99FE,0x0089,0x0085,0x0083,0x99FD,0x99FC,0x0083, 0x99FB,0x99FA,0x0085,0x0083,0x99F9,0x99F8,0x0083,0xC5B7,0x99F7,0x0091,0x0089,0x0085,0x0083,0x99F6,0xECA3,0x0083, 0xD0C0,0xBBB6,0x0085,0x0083,0xB4CE,0xC7B7,0x0083,0x99F5,0x99F4,0x0089,0x0085,0x0083,0x99F3,0x99F2,0x0083,0x99F1, 0x99F0,0x0085,0x0083,0x99EF,0x99EE,0x0083,0x99ED,0x99EC,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x99EB,0x99EA, 0x0083,0x99E9,0x99E8,0x0085,0x0083,0x99E7,0x99E6,0x0083,0x99E5,0x99E4,0x0089,0x0085,0x0083,0x99E3,0x99E2,0x0083, 0x99E1,0x99E0,0x0085,0x0083,0x99DF,0x99DE,0x0083,0x99DD,0x99DC,0x0091,0x0089,0x0085,0x0083,0x99DB,0x99DA,0x0083, 0x99D9,0x99D8,0x0085,0x0083,0x99D7,0x99D6,0x0083,0x99D5,0x99D4,0x0089,0x0085,0x0083,0x99D3,0x99D2,0x0083,0x99D1, 0x99D0,0x0085,0x0083,0x99CF,0x99CE,0x0083,0x99CD,0x99CC,0x00A1,0x0091,0x0089,0x0085,0x0083,0x99CB,0x99CA,0x0083, 0x99C9,0x99C8,0x0085,0x0083,0x99C7,0x99C6,0x0083,0x99C5,0x99C4,0x0089,0x0085,0x0083,0x99C3,0x99C2,0x0083,0x99C1, 0x99C0,0x0085,0x0083,0x99BF,0x99BE,0x0083,0x99BD,0x99BC,0x0091,0x0089,0x0085,0x0083,0x99BB,0x99BA,0x0083,0x99B9, 0x99B8,0x0085,0x0083,0x99B7,0x99B6,0x0083,0x99B5,0x99B4,0x0089,0x0085,0x0083,0x99B3,0x99B2,0x0083,0x99B1,0x99B0, 0x0085,0x0083,0x99AF,0x99AE,0x0083,0x99AD,0x99AC,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x99AB,0x99AA, 0x0083,0x99A9,0x99A8,0x0085,0x0083,0x99A7,0x99A6,0x0083,0x99A5,0x99A4,0x0089,0x0085,0x0083,0x99A3,0x99A2,0x0083, 0x99A1,0x99A0,0x0085,0x0083,0x999F,0x999E,0x0083,0x999D,0x999C,0x0091,0x0089,0x0085,0x0083,0x999B,0x999A,0x0083, 0x9999,0x9998,0x0085,0x0083,0x9997,0x9996,0x0083,0x9995,0x9994,0x0089,0x0085,0x0083,0x9993,0x9992,0x0083,0x9991, 0x9990,0x0085,0x0083,0x998F,0x998E,0x0083,0x998D,0x998C,0x00A1,0x0091,0x0089,0x0085,0x0083,0x998B,0x998A,0x0083, 0x9989,0x9988,0x0085,0x0083,0x9987,0x9986,0x0083,0x9985,0x9984,0x0089,0x0085,0x0083,0x9983,0xC3CA,0x0083,0xE9DF, 0x9982,0x0085,0x0083,0xE9DD,0x9981,0x0083,0x9980,0x997E,0x0091,0x0089,0x0085,0x0083,0x997D,0x997C,0x0083,0x997B, 0x997A,0x0085,0x0083,0x9979,0xE9D1,0x0083,0x9978,0x9977,0x0089,0x0085,0x0083,0x9976,0x9975,0x0083,0x9974,0x9973, 0x0085,0x0083,0x9972,0x9971,0x0083,0xE9DE,0x9970,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x996F,0x996E,0x0083, 0x996D,0x996C,0x0085,0x0083,0xE9DB,0xE9DC,0x0083,0x996B,0xE9D5,0x0089,0x0085,0x0083,0x996A,0x9969,0x0083,0x9968, 0x9967,0x0085,0x0083,0x9966,0x9965,0x0083,0x9964,0x9963,0x0091,0x0089,0x0085,0x0083,0x9962,0xCFAD,0x0083,0x9961, 0x9960,0x0085,0x0083,0x995F,0xCCB4,0x0083,0x995E,0x995D,0x0089,0x0085,0x0083,0x995C,0xE9DA,0x0083,0x995B,0x995A, 0x0085,0x0083,0xE9D6,0x9959,0x0083,0x9958,0x9957,0x00A1,0x0091,0x0089,0x0085,0x0083,0x9956,0x9955,0x0083,0x9954, 0x9953,0x0085,0x0083,0xB3F7,0x9952,0x0083,0x9951,0x9950,0x0089,0x0085,0x0083,0x994F,0x994E,0x0083,0x994D,0x994C, 0x0085,0x0083,0x994B,0x994A,0x0083,0x9949,0x9948,0x0091,0x0089,0x0085,0x0083,0xE9CD,0x9947,0x0083,0x9946,0x9945, 0x0085,0x0083,0xCFF0,0x9944,0x0083,0x9943,0x9942,0x0089,0x0085,0x0083,0x9941,0x9940,0x0083,0xE9D3,0x98FE,0x0085, 0x0083,0xB3C8,0xE9D9,0x0083,0x98FD,0x98FC,0x027F,0x017F,0x00FF,0x00BF,0x009F,0x008F,0x0087,0x0083,0x98FB,0x0083, 0x98FA,0x98F9,0x0085,0x0083,0x98F8,0x98F7,0x0083,0xE9D2,0x98F6,0x0089,0x0085,0x0083,0x98F5,0x98F4,0x0083,0x98F3, 0x98F2,0x0085,0x0083,0x98F1,0x98F0,0x0083,0x98EF,0xC7C1,0x0091,0x0089,0x0085,0x0083,0x98EE,0x98ED,0x0083,0xE9CF, 0x98EC,0x0085,0x0083,0x98EB,0x98EA,0x0083,0x98E9,0x98E8,0x0089,0x0085,0x0083,0xE9D0,0xE9D7,0x0083,0x98E7,0x98E6, 0x0085,0x0083,0x98E5,0x98E4,0x0083,0x98E3,0x98E2,0x00A1,0x0091,0x0089,0x0085,0x0083,0x98E1,0xE9D4,0x0083,0x98E0, 0x98DF,0x0085,0x0083,0x98DE,0xD3A3,0x0083,0x98DD,0xE9C9,0x0089,0x0085,0x0083,0x98DC,0x98DB,0x0083,0x98DA,0x98D9, 0x0085,0x0083,0xBAE1,0x98D8,0x0083,0xE9D8,0x98D7,0x0091,0x0089,0x0085,0x0083,0x98D6,0x98D5,0x0083,0x98D4,0x98D3, 0x0085,0x0083,0x98D2,0xC4A3,0x0083,0x98D1,0xD5C1,0x0089,0x0085,0x0083,0x98D0,0x98CF,0x0083,0x98CE,0x98CD,0x0085, 0x0083,0x98CC,0x98CB,0x0083,0xE9CC,0xE9CB,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x98CA,0x98C9,0x0083,0x98C8, 0x98C7,0x0085,0x0083,0x98C6,0x98C5,0x0083,0x98C4,0x98C3,0x0089,0x0085,0x0083,0x98C2,0x98C1,0x0083,0x98C0,0x98BF, 0x0085,0x0083,0xB7AE,0x98BE,0x0083,0x98BD,0x98BC,0x0091,0x0089,0x0085,0x0083,0x98BB,0x98BA,0x0083,0x98B9,0x98B8, 0x0085,0x0083,0x98B7,0x98B6,0x0083,0x98B5,0xE9C8,0x0089,0x0085,0x0083,0x98B4,0xB2DB,0x0083,0x98B3,0x98B2,0x0085, 0x0083,0x98B1,0x98B0,0x0083,0x98AF,0x98AE,0x00A1,0x0091,0x0089,0x0085,0x0083,0x98AD,0x98AC,0x0083,0x98AB,0x98AA, 0x0085,0x0083,0xE9CE,0x98A9,0x0083,0x98A8,0x98A7,0x0089,0x0085,0x0083,0x98A6,0xE9CA,0x0083,0x98A5,0x98A4,0x0085, 0x0083,0x98A3,0x98A2,0x0083,0x98A1,0x98A0,0x0091,0x0089,0x0085,0x0083,0x989F,0x989E,0x0083,0x989D,0x989C,0x0085, 0x0083,0x989B,0x989A,0x0083,0xE9C6,0xE9C4,0x0089,0x0085,0x0083,0x9899,0x9898,0x0083,0x9897,0xBCF7,0x0085,0x0083, 0x9896,0x9895,0x0083,0x9894,0x9893,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x9892,0x9891,0x0083,0xE9C0, 0x9890,0x0085,0x0083,0x988F,0x988E,0x0083,0xBBB1,0x988D,0x0089,0x0085,0x0083,0xE9B6,0x988C,0x0083,0xE9B3,0x988B, 0x0085,0x0083,0xE9C3,0x988A,0x0083,0x9889,0x9888,0x0091,0x0089,0x0085,0x0083,0x9887,0x9886,0x0083,0x9885,0x9884, 0x0085,0x0083,0x9883,0xE9C2,0x0083,0x9882,0x9881,0x0089,0x0085,0x0083,0x9880,0x987E,0x0083,0x987D,0xE9BD,0x0085, 0x0083,0x987C,0x987B,0x0083,0x987A,0xC8B6,0x00A1,0x0091,0x0089,0x0085,0x0083,0x9879,0x9878,0x0083,0xC1F1,0x9877, 0x0085,0x0083,0x9876,0xE9C1,0x0083,0x9875,0x9874,0x0089,0x0085,0x0083,0x9873,0xE9BF,0x0083,0x9872,0xE9BE,0x0085, 0x0083,0x9871,0x9870,0x0083,0xD5A5,0xE9BC,0x0091,0x0089,0x0085,0x0083,0x986F,0x986E,0x0083,0x986D,0x986C,0x0085, 0x0083,0x986B,0x986A,0x0083,0x9869,0x9868,0x0089,0x0085,0x0083,0x9867,0x9866,0x0083,0xB0F1,0xE9BB,0x0085,0x0083, 0x9865,0x9864,0x0083,0xE9B0,0x9863,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x9862,0xE9C5,0x0083,0xC0C6,0x9861, 0x0085,0x0083,0x9860,0x985F,0x0083,0x985E,0x985D,0x0089,0x0085,0x0083,0x985C,0xE9C7,0x0083,0x985B,0x985A,0x0085, 0x0083,0x9859,0xE9B7,0x0083,0xE9B5,0xE9B4,0x0091,0x0089,0x0085,0x0083,0xD3DC,0x9858,0x0083,0xE9AD,0x9857,0x0085, 0x0083,0xB8C5,0x9856,0x0083,0xE9AF,0x9855,0x0089,0x0085,0x0083,0x9854,0x9853,0x0083,0xC2A5,0x9852,0x0085,0x0083, 0x9851,0xE9BA,0x0083,0xE9B1,0xBFAC,0x00A1,0x0091,0x0089,0x0085,0x0083,0x9850,0x984F,0x0083,0x984E,0x984D,0x0085, 0x0083,0x984C,0xE9A8,0x0083,0x984B,0x984A,0x0089,0x0085,0x0083,0xE8FA,0x9849,0x0083,0x9848,0xE9AE,0x0085,0x0083, 0x9847,0x9846,0x0083,0x9845,0x9844,0x0091,0x0089,0x0085,0x0083,0xE9B8,0x9843,0x0083,0x9842,0xE9B9,0x0085,0x0083, 0x9841,0x9840,0x0083,0xE9AA,0x97FE,0x0089,0x0085,0x0083,0xC0E3,0xE9AC,0x0083,0x97FD,0x97FC,0x0085,0x0083,0xB3FE, 0x97FB,0x0083,0x97FA,0xE9A5,0x0181,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x97F9,0x97F8,0x0083,0xD0A8, 0x97F7,0x0085,0x0083,0x97F6,0x97F5,0x0083,0x97F4,0x97F3,0x0089,0x0085,0x0083,0x97F2,0x97F1,0x0083,0x97F0,0x97EF, 0x0085,0x0083,0x97EE,0x97ED,0x0083,0x97EC,0x97EB,0x0091,0x0089,0x0085,0x0083,0x97EA,0x97E9,0x0083,0x97E8,0x97E7, 0x0085,0x0083,0xE9AB,0x97E6,0x0083,0x97E5,0xB4BB,0x0089,0x0085,0x0083,0x97E4,0xB4AA,0x0083,0x97E3,0x97E2,0x0085, 0x0083,0x97E1,0xE9A9,0x0083,0x97E0,0x97DF,0x00A1,0x0091,0x0089,0x0085,0x0083,0x97DE,0x97DD,0x0083,0xE9B2,0x97DC, 0x0085,0x0083,0x97DB,0x97DA,0x0083,0xD2AC,0x97D9,0x0089,0x0085,0x0083,0x97D8,0xCDD6,0x0083,0x97D7,0x97D6,0x0085, 0x0083,0x97D5,0x97D4,0x0083,0x97D3,0x97D2,0x0091,0x0089,0x0085,0x0083,0x97D1,0x97D0,0x0083,0xE9A1,0x97CF,0x0085, 0x0083,0x97CE,0x97CD,0x0083,0xE8FD,0xE8FC,0x0089,0x0085,0x0083,0x97CC,0x97CB,0x0083,0x97CA,0x97C9,0x0085,0x0083, 0x97C8,0x97C7,0x0083,0x97C6,0x97C5,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x97C4,0x97C3,0x0083,0x97C2,0x97C1, 0x0085,0x0083,0xBDB7,0x97C0,0x0083,0xE9A7,0x97BF,0x0089,0x0085,0x0083,0xD7B5,0xD6B2,0x0083,0x97BE,0xE9A3,0x0085, 0x0083,0x97BD,0x97BC,0x0083,0x97BB,0x97BA,0x0091,0x0089,0x0085,0x0083,0x97B9,0xD2CE,0x0083,0x97B8,0x97B7,0x0085, 0x0083,0x97B6,0xE9A4,0x0083,0x97B5,0x97B4,0x0089,0x0085,0x0083,0x97B3,0x97B2,0x0083,0xE8FB,0x97B1,0x0085,0x0083, 0xB9D7,0xE8FE,0x0083,0x97B0,0x97AF,0x00A1,0x0091,0x0089,0x0085,0x0083,0x97AE,0xBFC3,0x0083,0x97AD,0x97AC,0x0085, 0x0083,0x97AB,0xC0E2,0x0083,0xE9A2,0x97AA,0x0089,0x0085,0x0083,0xC9AD,0x97A9,0x0083,0x97A8,0x97A7,0x0085,0x0083, 0x97A6,0x97A5,0x0083,0x97A4,0x97A3,0x0091,0x0089,0x0085,0x0083,0x97A2,0x97A1,0x0083,0x97A0,0xE9A6,0x0085,0x0083, 0x979F,0x979E,0x0083,0xCCC4,0x979D,0x0089,0x0085,0x0083,0x979C,0x979B,0x0083,0x979A,0x9799,0x0085,0x0083,0xC5EF, 0x9798,0x0083,0xBCAC,0x9797,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x9796,0xD7D8,0x0083,0x9795,0x9794, 0x0085,0x0083,0xB0F4,0x9793,0x0083,0x9792,0x9791,0x0089,0x0085,0x0083,0x9790,0xB9F7,0x0083,0x978F,0xC6E5,0x0085, 0x0083,0x978E,0xC3DE,0x0083,0x978D,0x978C,0x0091,0x0089,0x0085,0x0083,0x978B,0x978A,0x0083,0x9789,0x9788,0x0085, 0x0083,0xE8F9,0x9787,0x0083,0xBCEC,0x9786,0x0089,0x0085,0x0083,0x9785,0x9784,0x0083,0x9783,0x9782,0x0085,0x0083, 0x9781,0x9780,0x0083,0x977E,0x977D,0x00A1,0x0091,0x0089,0x0085,0x0083,0x977C,0xE8F3,0x0083,0x977B,0xCAE1,0x0085, 0x0083,0x977A,0x9779,0x0083,0xD0B5,0xCCDD,0x0089,0x0085,0x0083,0x9778,0xCBF3,0x0083,0x9777,0x9776,0x0085,0x0083, 0x9775,0x9774,0x0083,0xC0E6,0xCEE0,0x0091,0x0089,0x0085,0x0083,0xC3CE,0x9773,0x0083,0x9772,0x9771,0x0085,0x0083, 0xC9D2,0x9770,0x0083,0x976F,0x976E,0x0089,0x0085,0x0083,0x976D,0x976C,0x0083,0x976B,0x976A,0x0085,0x0083,0x9769, 0x9768,0x0083,0x9767,0xB9A3,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x9766,0x9765,0x0083,0x9764,0xE8F7,0x0085, 0x0083,0x9763,0x9762,0x0083,0x9761,0xE8F4,0x0089,0x0085,0x0083,0x9760,0x975F,0x0083,0x975E,0x975D,0x0085,0x0083, 0x975C,0x975B,0x0083,0x975A,0x9759,0x0091,0x0089,0x0085,0x0083,0xB0F0,0xC3B7,0x0083,0x9758,0xE8E8,0x0085,0x0083, 0x9757,0xC1BA,0x0083,0x9756,0x9755,0x0089,0x0085,0x0083,0x9754,0x9753,0x0083,0x9752,0x9751,0x0085,0x0083,0x9750, 0x974F,0x0083,0x974E,0xE8F6,0x00A1,0x0091,0x0089,0x0085,0x0083,0xCDB0,0x974D,0x0083,0xE8F5,0x974C,0x0085,0x0083, 0x974B,0x974A,0x0083,0x9749,0x9748,0x0089,0x0085,0x0083,0x9747,0x9746,0x0083,0x9745,0xE8F8,0x0085,0x0083,0x9744, 0xD7AE,0x0083,0xBDB0,0xE8ED,0x0091,0x0089,0x0085,0x0083,0xE8EB,0xC7C5,0x0083,0xE8E7,0xB5B5,0x0085,0x0083,0xE8E5, 0xE8E3,0x0083,0xE8E2,0x9743,0x0089,0x0085,0x0083,0x9742,0x9741,0x0083,0x9740,0x96FE,0x0085,0x0083,0x96FD,0x96FC, 0x0083,0x96FB,0x96FA,0x087B,0x047D,0x027F,0x017F,0x00FF,0x00BF,0x009F,0x008F,0x0087,0x0083,0x96F9,0x0083,0xE8EA, 0xBDDB,0x0085,0x0083,0xBBB8,0x96F8,0x0083,0xC9A3,0xCDA9,0x0089,0x0085,0x0083,0x96F7,0xE8E4,0x0083,0x96F6,0xD7C0, 0x0085,0x0083,0x96F5,0xE8F0,0x0083,0xE8F1,0xB0B8,0x0091,0x0089,0x0085,0x0083,0x96F4,0xBFF2,0x0083,0xCEA6,0xE8E6, 0x0085,0x0083,0xCCD2,0xB9F0,0x0083,0xE8EC,0xE8EE,0x0089,0x0085,0x0083,0x96F3,0xE8EF,0x0083,0xD4D4,0xB8F1,0x0085, 0x0083,0x96F2,0x96F1,0x0083,0xB8F9,0xBACB,0x00A1,0x0091,0x0089,0x0085,0x0083,0xD1F9,0x96F0,0x0083,0x96EF,0x96EE, 0x0085,0x0083,0xE8E1,0xE8E0,0x0083,0x96ED,0x96EC,0x0089,0x0085,0x0083,0x96EB,0x96EA,0x0083,0x96E9,0x96E8,0x0085, 0x0083,0x96E7,0xD6EA,0x0083,0xE8F2,0x96E6,0x0091,0x0089,0x0085,0x0083,0x96E5,0x96E4,0x0083,0x96E3,0x96E2,0x0085, 0x0083,0x96E1,0x96E0,0x0083,0xD0A3,0x96DF,0x0089,0x0085,0x0083,0x96DE,0x96DD,0x0083,0xE8E9,0x96DC,0x0085,0x0083, 0x96DB,0x96DA,0x0083,0x96D9,0x96D8,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xC0F5,0xC6DC,0x0083,0x96D7,0x96D6, 0x0085,0x0083,0xCBA8,0x96D5,0x0083,0xCAF7,0x96D4,0x0089,0x0085,0x0083,0xC0B8,0xE8DD,0x0083,0x96D3,0xE8D3,0x0085, 0x0083,0xB6B0,0xE8D0,0x0083,0xE8CE,0xD5BB,0x0091,0x0089,0x0085,0x0083,0xB1EA,0x96D2,0x0083,0xD5A4,0x96D1,0x0085, 0x0083,0x96D0,0x96CF,0x0083,0x96CE,0xE8D9,0x0089,0x0085,0x0083,0xCAC1,0x96CD,0x0083,0xE8DF,0x96CC,0x0085,0x0083, 0x96CB,0x96CA,0x0083,0x96C9,0x96C8,0x00A1,0x0091,0x0089,0x0085,0x0083,0x96C7,0x96C6,0x0083,0x96C5,0xB2F1,0x0085, 0x0083,0xC1F8,0x96C4,0x0083,0xD6F9,0xE8CD,0x0089,0x0085,0x0083,0xBFC2,0x96C3,0x0083,0x96C2,0xBCED,0x0085,0x0083, 0x96C1,0x96C0,0x0083,0xE8D1,0x96BF,0x0091,0x0089,0x0085,0x0083,0x96BE,0x96BD,0x0083,0xB2E9,0x96BC,0x0085,0x0083, 0x96BB,0xE8DC,0x0083,0x96BA,0xC4FB,0x0089,0x0085,0x0083,0x96B9,0xD7F5,0x0083,0xE8D8,0xB9F1,0x0085,0x0083,0x96B8, 0xE8D6,0x0083,0xE8D4,0xE8CF,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x96B7,0x96B6,0x0083,0x96B5,0xC8E1, 0x0085,0x0083,0xC8BE,0xC6E2,0x0083,0xB8CC,0xC4B3,0x0089,0x0085,0x0083,0xB0D8,0x96B4,0x0083,0x96B3,0x96B2,0x0085, 0x0083,0x96B1,0x96B0,0x0083,0x96AF,0x96AE,0x0091,0x0089,0x0085,0x0083,0x96AD,0x96AC,0x0083,0x96AB,0xB1FA,0x0085, 0x0083,0xE8DA,0x96AA,0x0083,0xE8DE,0x96A9,0x0089,0x0085,0x0083,0x96A8,0x96A7,0x0083,0x96A6,0x96A5,0x0085,0x0083, 0x96A4,0x96A3,0x0083,0x96A2,0xE8DB,0x00A1,0x0091,0x0089,0x0085,0x0083,0xBCCF,0xBCDC,0x0083,0xE8D5,0x96A1,0x0085, 0x0083,0xE8D7,0x96A0,0x0083,0x969F,0xE8D2,0x0089,0x0085,0x0083,0xBFDD,0x969E,0x0083,0xE8C9,0x969D,0x0085,0x0083, 0xB7E3,0xC7B9,0x0083,0x969C,0xE8C7,0x0091,0x0089,0x0085,0x0083,0xE8C5,0x969B,0x0083,0xE8C0,0x969A,0x0085,0x0083, 0xD4E6,0xCAE0,0x0083,0x9699,0x9698,0x0089,0x0085,0x0083,0x9697,0xE8C8,0x0083,0xD6A6,0xB9FB,0x0085,0x0083,0x9696, 0xC3B6,0x0083,0x9695,0xE8C4,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xC1D6,0x9694,0x0083,0xD5ED,0x9693,0x0085, 0x0083,0x9692,0x9691,0x0083,0x9690,0xCEF6,0x0089,0x0085,0x0083,0x968F,0x968E,0x0083,0x968D,0x968C,0x0085,0x0083, 0xE8CA,0x968B,0x0083,0xCDF7,0x968A,0x0091,0x0089,0x0085,0x0083,0xE8C1,0x9689,0x0083,0x9688,0xB9B9,0x0085,0x0083, 0x9687,0x9686,0x0083,0xBCAB,0x9685,0x0089,0x0085,0x0083,0xB0E5,0xCBC9,0x0083,0x9684,0xE8CC,0x0085,0x0083,0x9683, 0x9682,0x0083,0x9681,0x9680,0x00A1,0x0091,0x0089,0x0085,0x0083,0xE8CB,0x967E,0x0083,0xE8C6,0x967D,0x0085,0x0083, 0xE8C3,0xEABD,0x0083,0x967C,0xBDDC,0x0089,0x0085,0x0083,0xB1AD,0x967B,0x0083,0xBABC,0x967A,0x0085,0x0083,0x9679, 0xE8C2,0x0083,0xE8BF,0xD1EE,0x0091,0x0089,0x0085,0x0083,0x9678,0x9677,0x0083,0xC0B4,0x9676,0x0085,0x0083,0x9675, 0x9674,0x0083,0xCCF5,0xB8DC,0x0089,0x0085,0x0083,0xCAF8,0xE8BD,0x0083,0x9673,0xB6C5,0x0085,0x0083,0x9672,0x9671, 0x0083,0x9670,0x966F,0x017F,0x00FF,0x00BF,0x009F,0x008F,0x0087,0x0083,0x966E,0x0083,0xD5C8,0x966D,0x0085,0x0083, 0x966C,0xE8BC,0x0083,0x966B,0xB4E5,0x0089,0x0085,0x0083,0xB2C4,0xD0D3,0x0083,0xC0EE,0x966A,0x0085,0x0083,0xE8BB, 0x9669,0x0083,0x9668,0xC9BC,0x0091,0x0089,0x0085,0x0083,0xE8BE,0x9667,0x0083,0xB8CB,0x9666,0x0085,0x0083,0x9665, 0xC8A8,0x0083,0xD4D3,0x9664,0x0089,0x0085,0x0083,0xC9B1,0x9663,0x0083,0x9662,0xD0E0,0x0085,0x0083,0x9661,0x9660, 0x0083,0xBBFA,0x965F,0x00A1,0x0091,0x0089,0x0085,0x0083,0x965E,0x965D,0x0083,0x965C,0xB6E4,0x0085,0x0083,0xC6D3, 0x965B,0x0083,0x965A,0xD6EC,0x0089,0x0085,0x0083,0x9659,0xCAF5,0x0083,0x9658,0xD4FD,0x0085,0x0083,0xB1BE,0xC4A9, 0x0083,0xCEB4,0x9657,0x0091,0x0089,0x0085,0x0083,0xC4BE,0x9656,0x0083,0xEBFC,0x9655,0x0085,0x0083,0x9654,0x9653, 0x0083,0x9652,0x9651,0x0089,0x0085,0x0083,0x9650,0xC6DA,0x0083,0x964F,0xB3AF,0x0085,0x0083,0x964E,0xCDFB,0x0083, 0x964D,0x964C,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x964B,0xC0CA,0x0083,0x964A,0xEBDE,0x0085,0x0083,0xCBB7, 0x9649,0x0083,0x9648,0x9647,0x0089,0x0085,0x0083,0xEBD4,0x9646,0x0083,0x9645,0xB7FE,0x0085,0x0083,0x9644,0xC5F3, 0x0083,0xEBC3,0xD3D0,0x0091,0x0089,0x0085,0x0083,0xD4C2,0x9643,0x0083,0x9642,0x9641,0x0085,0x0083,0x9640,0x95FE, 0x0083,0x95FD,0x95FC,0x0089,0x0085,0x0083,0xD7EE,0xCCE6,0x0083,0xD4F8,0x95FB,0x0085,0x0083,0xC2FC,0x95FA,0x0083, 0x95F9,0xB2DC,0x00A1,0x0091,0x0089,0x0085,0x0083,0x95F8,0xEAC2,0x0083,0x95F7,0x95F6,0x0085,0x0083,0xB8FC,0xD2B7, 0x0083,0xC7FA,0x95F5,0x0089,0x0085,0x0083,0xD4BB,0x95F4,0x0083,0x95F3,0x95F2,0x0085,0x0083,0x95F1,0x95F0,0x0083, 0x95EF,0xEAD9,0x0091,0x0089,0x0085,0x0083,0x95EE,0x95ED,0x0083,0xEAD8,0x95EC,0x0085,0x0083,0x95EB,0x95EA,0x0083, 0x95E9,0x95E8,0x0089,0x0085,0x0083,0x95E7,0x95E6,0x0083,0x95E5,0xC6D8,0x0085,0x0083,0xEAD7,0xEAD6,0x0083,0x95E4, 0xCAEF,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x95E3,0x95E2,0x0083,0x95E1,0x95E0,0x0085,0x0083,0x95DF, 0x95DE,0x0083,0x95DD,0x95DC,0x0089,0x0085,0x0083,0x95DB,0x95DA,0x0083,0x95D9,0x95D8,0x0085,0x0083,0x95D7,0x95D6, 0x0083,0x95D5,0x95D4,0x0091,0x0089,0x0085,0x0083,0x95D3,0x95D2,0x0083,0x95D1,0x95D0,0x0085,0x0083,0x95CF,0x95CE, 0x0083,0x95CD,0x95CC,0x0089,0x0085,0x0083,0x95CB,0x95CA,0x0083,0xEAD5,0x95C9,0x0085,0x0083,0x95C8,0x95C7,0x0083, 0x95C6,0xE5DF,0x00A1,0x0091,0x0089,0x0085,0x0083,0x95C5,0x95C4,0x0083,0x95C3,0x95C2,0x0085,0x0083,0xB1A9,0x95C1, 0x0083,0x95C0,0x95BF,0x0089,0x0085,0x0083,0x95BE,0x95BD,0x0083,0xC4BA,0x95BC,0x0085,0x0083,0x95BB,0x95BA,0x0083, 0x95B9,0x95B8,0x0091,0x0089,0x0085,0x0083,0xF4DF,0xEAD3,0x0083,0x95B7,0x95B6,0x0085,0x0083,0x95B5,0x95B4,0x0083, 0x95B3,0x95B2,0x0089,0x0085,0x0083,0x95B1,0x95B0,0x0083,0x95AF,0xEAD4,0x0085,0x0083,0x95AE,0x95AD,0x0083,0x95AC, 0x95AB,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x95AA,0xB0B5,0x0083,0xC5AF,0x95A9,0x0085,0x0083,0x95A8,0x95A7, 0x0083,0x95A6,0xCAEE,0x0089,0x0085,0x0083,0x95A5,0x95A4,0x0083,0x95A3,0x95A2,0x0085,0x0083,0xEAD2,0x95A1,0x0083, 0x95A0,0x959F,0x0091,0x0089,0x0085,0x0083,0x959E,0xCFBE,0x0083,0x959D,0x959C,0x0085,0x0083,0xEAD1,0x959B,0x0083, 0xD4DD,0x959A,0x0089,0x0085,0x0083,0x9599,0x9598,0x0083,0xC1C0,0x9597,0x0085,0x0083,0x9596,0x9595,0x0083,0xD6C7, 0x9594,0x00A1,0x0091,0x0089,0x0085,0x0083,0x9593,0xEAD0,0x0083,0xBEA7,0x9592,0x0085,0x0083,0xC7E7,0x9591,0x0083, 0x9590,0x958F,0x0089,0x0085,0x0083,0xCEFA,0xBEB0,0x0083,0xC6D5,0x958E,0x0085,0x0083,0x958D,0x958C,0x0083,0x958B, 0x958A,0x0091,0x0089,0x0085,0x0083,0xB3BF,0x9589,0x0083,0xBBDE,0x9588,0x0085,0x0083,0xCEEE,0x9587,0x0083,0x9586, 0xEACE,0x0089,0x0085,0x0083,0x9585,0xEAC9,0x0083,0x9584,0x9583,0x0085,0x0083,0x9582,0x9581,0x0083,0xCDED,0x9580, 0x027F,0x017F,0x00FF,0x00BF,0x009F,0x008F,0x0087,0x0083,0x957E,0x0083,0xEACF,0xEACD,0x0085,0x0083,0xD4CE,0xEACA, 0x0083,0xCFFE,0xC9B9,0x0089,0x0085,0x0083,0x957D,0x957C,0x0083,0xEACC,0x957B,0x0085,0x0083,0x957A,0xC9CE,0x0083, 0xBDFA,0x9579,0x0091,0x0089,0x0085,0x0083,0x9578,0x9577,0x0083,0x9576,0x9575,0x0085,0x0083,0x9574,0x9573,0x0083, 0xBBCE,0x9572,0x0089,0x0085,0x0083,0xEACB,0x9571,0x0083,0x9570,0xCFD4,0x0085,0x0083,0x956F,0xD6E7,0x0083,0x956E, 0x956D,0x00A1,0x0091,0x0089,0x0085,0x0083,0x956C,0x956B,0x0083,0x956A,0xEAC6,0x0085,0x0083,0xEAC7,0xEAC4,0x0083, 0x9569,0x9568,0x0089,0x0085,0x0083,0xEAC5,0x9567,0x0083,0xCAC7,0x9566,0x0085,0x0083,0xD5D1,0x9565,0x0083,0x9564, 0x9563,0x0091,0x0089,0x0085,0x0083,0x9562,0xD7F2,0x0083,0xC3C1,0x9561,0x0085,0x0083,0xB4BA,0x9560,0x0083,0x955F, 0x955E,0x0089,0x0085,0x0083,0x955D,0xD3B3,0x0083,0xD0C7,0x955C,0x0085,0x0083,0xEAC3,0x955B,0x0083,0x955A,0x9559, 0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xEABC,0x9558,0x0083,0x9557,0x9556,0x0085,0x0083,0xEABF,0xCEF4,0x0083, 0xD2D7,0x9555,0x0089,0x0085,0x0083,0x9554,0x9553,0x0083,0xBBE8,0xC3F7,0x0085,0x0083,0x9552,0xB2FD,0x0083,0x9551, 0xEABB,0x0091,0x0089,0x0085,0x0083,0x9550,0x954F,0x0083,0x954E,0xC0A5,0x0085,0x0083,0x954D,0x954C,0x0083,0xEABE, 0xB0BA,0x0089,0x0085,0x0083,0x954B,0xEAC0,0x0083,0x954A,0x9549,0x0085,0x0083,0x9548,0x9547,0x0083,0x9546,0xCDFA, 0x00A1,0x0091,0x0089,0x0085,0x0083,0x9545,0x9544,0x0083,0xBFF5,0xCAB1,0x0085,0x0083,0x9543,0x9542,0x0083,0x9541, 0x9540,0x0089,0x0085,0x0083,0xBAB5,0xEABA,0x0083,0xEAB9,0xEAB8,0x0085,0x0083,0xD0F1,0xD1AE,0x0083,0x94FE,0x94FD, 0x0091,0x0089,0x0085,0x0083,0xD4E7,0xD6BC,0x0083,0xBEC9,0xB5A9,0x0085,0x0083,0xC8D5,0x94FC,0x0083,0x94FB,0xBCC8, 0x0089,0x0085,0x0083,0x94FA,0xCEDE,0x0083,0x94F9,0x94F8,0x0085,0x0083,0x94F7,0x94F6,0x0083,0x94F5,0x94F4,0x0101, 0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x94F3,0x94F2,0x0083,0xC6EC,0xECBD,0x0085,0x0083,0x94F1,0x94F0,0x0083, 0x94EF,0xECBC,0x0089,0x0085,0x0083,0x94EE,0x94ED,0x0083,0xD7E5,0xECBB,0x0085,0x0083,0x94EC,0xECBA,0x0083,0xD0FD, 0x94EB,0x0091,0x0089,0x0085,0x0083,0x94EA,0x94E9,0x0083,0x94E8,0xECB7,0x0085,0x0083,0xC2C3,0xECB8,0x0083,0xECB9, 0x94E7,0x0089,0x0085,0x0083,0xC5D4,0x94E6,0x0083,0x94E5,0x94E4,0x0085,0x0083,0xCAA9,0xECB6,0x0083,0x94E3,0x94E2, 0x00A1,0x0091,0x0089,0x0085,0x0083,0xB7BD,0x94E1,0x0083,0x94E0,0x94DF,0x0085,0x0083,0x94DE,0x94DD,0x0083,0x94DC, 0x94DB,0x0089,0x0085,0x0083,0x94DA,0xD0C2,0x0083,0xCBB9,0x94D9,0x0085,0x0083,0xB6CF,0x94D8,0x0083,0xEDBD,0x94D7, 0x0091,0x0089,0x0085,0x0083,0xD5B6,0x94D6,0x0083,0xB8AB,0x94D5,0x0085,0x0083,0xB3E2,0xBDEF,0x0083,0x94D4,0x94D3, 0x0089,0x0085,0x0083,0xCED3,0x94D2,0x0083,0xD5E5,0x94D1,0x0085,0x0083,0x94D0,0xD0B1,0x0083,0xF5FA,0x94CF,0x00C1, 0x00A1,0x0091,0x0089,0x0085,0x0083,0xC1CF,0x94CE,0x0083,0xB6B7,0x94CD,0x0085,0x0083,0x94CC,0x94CB,0x0083,0xECB5, 0x94CA,0x0089,0x0085,0x0083,0xB0DF,0xECB3,0x0083,0x94C9,0x94C8,0x0085,0x0083,0x94C7,0xB1F3,0x0083,0xD5AB,0x94C6, 0x0091,0x0089,0x0085,0x0083,0x94C5,0x94C4,0x0083,0xCEC4,0x94C3,0x0085,0x0083,0x94C2,0x94C1,0x0083,0x94C0,0x94BF, 0x0089,0x0085,0x0083,0x94BE,0x94BD,0x0083,0x94BC,0x94BB,0x0085,0x0083,0x94BA,0x94B9,0x0083,0x94B8,0x94B7,0x00A1, 0x0091,0x0089,0x0085,0x0083,0x94B6,0x94B5,0x0083,0xB7F3,0x94B4,0x0085,0x0083,0x94B3,0xD5FB,0x0083,0x94B2,0xC7C3, 0x0089,0x0085,0x0083,0x94B1,0xCAFD,0x0083,0x94B0,0x94AF,0x0085,0x0083,0x94AE,0xBEB4,0x0083,0xEBB8,0x94AD,0x0091, 0x0089,0x0085,0x0083,0x94AC,0x94AB,0x0083,0x94AA,0xB6D8,0x0085,0x0083,0x94A9,0x94A8,0x0083,0xC9A2,0xB8D2,0x0089, 0x0085,0x0083,0x94A7,0x94A6,0x0083,0x94A5,0xB3A8,0x0085,0x0083,0xB1D6,0x94A4,0x0083,0xC1B2,0x94A3,0x0181,0x0101, 0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xBDCC,0x94A2,0x0083,0x94A1,0xB0BD,0x0085,0x0083,0xEBB7,0x94A0,0x0083, 0x949F,0x949E,0x0089,0x0085,0x0083,0xBEC8,0x949D,0x0083,0xC3F4,0x949C,0x0085,0x0083,0x949B,0xB5D0,0x0083,0x949A, 0x9499,0x0091,0x0089,0x0085,0x0083,0xF4CD,0xD0A7,0x0083,0x9498,0x9497,0x0085,0x0083,0xB9CA,0x9496,0x0083,0x9495, 0x9494,0x0089,0x0085,0x0083,0x9493,0x9492,0x0083,0xD5FE,0xB7C5,0x0085,0x0083,0x9491,0x9490,0x0083,0xB9A5,0x948F, 0x00A1,0x0091,0x0089,0x0085,0x0083,0xB8C4,0xD8FC,0x0083,0x948E,0xCAD5,0x0085,0x0083,0xEBB6,0xEAB7,0x0083,0x948D, 0x948C,0x0089,0x0085,0x0083,0x948B,0x948A,0x0083,0xD6A7,0xDFAD,0x0085,0x0083,0x9489,0x9488,0x0083,0xBEF0,0x9487, 0x0091,0x0089,0x0085,0x0083,0x9486,0x9485,0x0083,0x9484,0x9483,0x0085,0x0083,0xDFAC,0x9482,0x0083,0x9481,0x9480, 0x0089,0x0085,0x0083,0x947E,0x947D,0x0083,0x947C,0x947B,0x0085,0x0083,0x947A,0x9479,0x0083,0x9478,0x9477,0x00C1, 0x00A1,0x0091,0x0089,0x0085,0x0083,0x9476,0xC8C1,0x0083,0x9475,0x9474,0x0085,0x0083,0x9473,0x9472,0x0083,0x9471, 0xD4DC,0x0089,0x0085,0x0083,0x9470,0x946F,0x0083,0x946E,0x946D,0x0085,0x0083,0x946C,0x946B,0x0083,0x946A,0x9469, 0x0091,0x0089,0x0085,0x0083,0xDFAB,0x9468,0x0083,0x9467,0x9466,0x0085,0x0083,0x9465,0x9464,0x0083,0x9463,0x9462, 0x0089,0x0085,0x0083,0x9461,0xC5CA,0x0083,0x9460,0x945F,0x0085,0x0083,0x945E,0x945D,0x0083,0x945C,0x945B,0x00A1, 0x0091,0x0089,0x0085,0x0083,0x945A,0x9459,0x0083,0x9458,0x9457,0x0085,0x0083,0x9456,0x9455,0x0083,0x9454,0x9453, 0x0089,0x0085,0x0083,0x9452,0x9451,0x0083,0x9450,0x944F,0x0085,0x0083,0x944E,0x944D,0x0083,0x944C,0x944B,0x0091, 0x0089,0x0085,0x0083,0x944A,0x9449,0x0083,0x9448,0xB2C1,0x0085,0x0083,0x9447,0xDFA9,0x0083,0x9446,0xDFAA,0x0089, 0x0085,0x0083,0x9445,0x9444,0x0083,0x9443,0xCBD3,0x0085,0x0083,0x9442,0x9441,0x0083,0x9440,0x93FE,0x0101,0x00C1, 0x00A1,0x0091,0x0089,0x0085,0x0083,0x93FD,0xEBA2,0x0083,0xDFA8,0x93FC,0x0085,0x0083,0x93FB,0x93FA,0x0083,0x93F9, 0xC7DC,0x0089,0x0085,0x0083,0x93F8,0xDFA7,0x0083,0x93F7,0xC7E6,0x0085,0x0083,0xB2D9,0x93F6,0x0083,0x93F5,0x93F4, 0x0091,0x0089,0x0085,0x0083,0x93F3,0x93F2,0x0083,0x93F1,0x93F0,0x0085,0x0083,0xC9C3,0x93EF,0x0083,0x93EE,0xC0DE, 0x0089,0x0085,0x0083,0x93ED,0xDFA6,0x0083,0x93EC,0x93EB,0x0085,0x0083,0x93EA,0xBAB3,0x0083,0x93E9,0xDFA5,0x00A1, 0x0091,0x0089,0x0085,0x0083,0x93E8,0xDFA3,0x0083,0xDFA2,0x93E7,0x0085,0x0083,0xC4EC,0x93E6,0x0083,0x93E5,0x93E4, 0x0089,0x0085,0x0083,0x93E3,0xD7AB,0x0083,0x93E2,0xB4E9,0x0085,0x0083,0xB2A5,0xC7CB,0x0083,0x93E1,0x93E0,0x0091, 0x0089,0x0085,0x0083,0xC1C3,0x93DF,0x0083,0x93DE,0x93DD,0x0085,0x0083,0x93DC,0xB3B7,0x0083,0x93DB,0x93DA,0x0089, 0x0085,0x0083,0x93D9,0x93D8,0x0083,0x93D7,0xD7B2,0x0085,0x0083,0x93D6,0x93D5,0x0083,0x93D4,0x93D3,0x00C1,0x00A1, 0x0091,0x0089,0x0085,0x0083,0xDFA4,0x93D2,0x0083,0x93D1,0xDEFE,0x0085,0x0083,0xCBBA,0x93D0,0x0083,0x93CF,0xC8F6, 0x0089,0x0085,0x0083,0xB3C5,0x93CE,0x0083,0x93CD,0x93CC,0x0085,0x0083,0x93CB,0x93CA,0x0083,0x93C9,0x93C8,0x0091, 0x0089,0x0085,0x0083,0x93C7,0x93C6,0x0083,0xC6B2,0x93C5,0x0085,0x0083,0xBEEF,0xDEFC,0x0083,0x93C4,0xC1CC,0x0089, 0x0085,0x0083,0x93C3,0x93C2,0x0083,0x93C1,0x93C0,0x0085,0x0083,0x93BF,0x93BE,0x0083,0x93BD,0xDFA1,0x00A1,0x0091, 0x0089,0x0085,0x0083,0xC4A1,0xC3FE,0x0083,0x93BC,0x93BB,0x0085,0x0083,0x93BA,0x93B9,0x0083,0x93B8,0x93B7,0x0089, 0x0085,0x0083,0x93B6,0x93B5,0x0083,0x93B4,0x93B3,0x0085,0x0083,0xDEFD,0x93B2,0x0083,0x93B1,0x93B0,0x0091,0x0089, 0x0085,0x0083,0xC4A6,0x93AF,0x0083,0xB4DD,0x93AE,0x0085,0x0083,0x93AD,0x93AC,0x0083,0x93AB,0x93AA,0x0089,0x0085, 0x0083,0x93A9,0x93A8,0x0083,0x93A7,0xDEFB,0x0085,0x0083,0x93A6,0x93A5,0x0083,0x93A4,0x93A3,0x047D,0x027F,0x017F, 0x00FF,0x00BF,0x009F,0x008F,0x0087,0x0083,0x93A2,0x0083,0xD5AA,0x93A1,0x0085,0x0083,0x93A0,0x939F,0x0083,0xCBA4, 0x939E,0x0089,0x0085,0x0083,0xDEF0,0x939D,0x0083,0x939C,0x939B,0x0085,0x0083,0x939A,0x9399,0x0083,0x9398,0x9397, 0x0091,0x0089,0x0085,0x0083,0xCCAF,0x9396,0x0083,0xB1F7,0xD2A1,0x0085,0x0083,0xB0DA,0xDEF3,0x0083,0xC9E3,0x9395, 0x0089,0x0085,0x0083,0x9394,0xDEF4,0x0083,0x9393,0xEBA1,0x0085,0x0083,0x9392,0xB2EB,0x0083,0x9391,0x9390,0x00A1, 0x0091,0x0089,0x0085,0x0083,0xD0AF,0x938F,0x0083,0x938E,0x938D,0x0085,0x0083,0x938C,0x938B,0x0083,0xE5BA,0x938A, 0x0089,0x0085,0x0083,0x9389,0x9388,0x0083,0x9387,0x9386,0x0085,0x0083,0x9385,0xB4EE,0x0083,0xB0E1,0x9384,0x0091, 0x0089,0x0085,0x0083,0xCCC2,0x9383,0x0083,0x9382,0x9381,0x0085,0x0083,0xDEF9,0x9380,0x0083,0x937E,0x937D,0x0089, 0x0085,0x0083,0x937C,0xDEFA,0x0083,0xDEF7,0x937B,0x0085,0x0083,0xB8E3,0x937A,0x0083,0xCBD1,0xDEF6,0x00C1,0x00A1, 0x0091,0x0089,0x0085,0x0083,0x9379,0x9378,0x0083,0x9377,0x9376,0x0085,0x0083,0x9375,0x9374,0x0083,0xC9A6,0xB4EA, 0x0089,0x0085,0x0083,0x9373,0x9372,0x0083,0xB4A4,0xB2AB,0x0085,0x0083,0x9371,0x9370,0x0083,0xDEF8,0xDEF5,0x0091, 0x0089,0x0085,0x0083,0x936F,0x936E,0x0083,0x936D,0x936C,0x0085,0x0083,0x936B,0xBDC1,0x0083,0x936A,0x9369,0x0089, 0x0085,0x0083,0xC2A7,0xB8E9,0x0083,0xB2F3,0xDEEC,0x0085,0x0083,0x9368,0xC0BF,0x0083,0x9367,0x9366,0x00A1,0x0091, 0x0089,0x0085,0x0083,0x9365,0x9364,0x0083,0xDEEA,0x9363,0x0085,0x0083,0xDEDE,0x9362,0x0083,0xD4AE,0x9361,0x0089, 0x0085,0x0083,0xDEE9,0x9360,0x0083,0x935F,0x935E,0x0085,0x0083,0x935D,0xBDD2,0x0083,0x935C,0x935B,0x0091,0x0089, 0x0085,0x0083,0xBEBE,0xBFAB,0x0083,0x935A,0x9359,0x0085,0x0083,0x9358,0x9357,0x0083,0x9356,0xB4A7,0x0089,0x0085, 0x0083,0x9355,0xCED5,0x0083,0xDEEB,0x9354,0x0085,0x0083,0xDEEE,0x9353,0x0083,0x9352,0x9351,0x0101,0x00C1,0x00A1, 0x0091,0x0089,0x0085,0x0083,0x9350,0x934F,0x0083,0x934E,0x934D,0x0085,0x0083,0xD2BE,0x934C,0x0083,0x934B,0x934A, 0x0089,0x0085,0x0083,0xB2E5,0x9349,0x0083,0xCCE1,0xC3E8,0x0085,0x0083,0xDEEF,0xD7E1,0x0083,0x9348,0x9347,0x0091, 0x0089,0x0085,0x0083,0x9346,0xC8E0,0x0083,0x9345,0x9344,0x0085,0x0083,0xDEF1,0x9343,0x0083,0xDEED,0x9342,0x0089, 0x0085,0x0083,0x9341,0x9340,0x0083,0x92FE,0x92FD,0x0085,0x0083,0xDEF2,0x92FC,0x0083,0xDEE8,0x92FB,0x00A1,0x0091, 0x0089,0x0085,0x0083,0xB2F4,0x92FA,0x0083,0xB5A7,0xD6C0,0x0085,0x0083,0x92F9,0x92F8,0x0083,0xDEE2,0xC2B0,0x0089, 0x0085,0x0083,0x92F7,0x92F6,0x0083,0xEAFE,0x92F5,0x0085,0x0083,0xDEE7,0xDEDD,0x0083,0xDEE4,0x92F4,0x0091,0x0089, 0x0085,0x0083,0xB4EB,0xD1DA,0x0083,0xCDC6,0xBFD8,0x0085,0x0083,0x92F3,0xBDD3,0x0083,0x92F2,0xB3B8,0x0089,0x0085, 0x0083,0xCCBD,0x92F1,0x0083,0xC2D3,0x92F0,0x0085,0x0083,0x92EF,0x92EE,0x0083,0x92ED,0x92EC,0x00C1,0x00A1,0x0091, 0x0089,0x0085,0x0083,0x92EB,0x92EA,0x0083,0xBEF2,0x92E9,0x0085,0x0083,0xD2B4,0x92E8,0x0083,0x92E7,0x92E6,0x0089, 0x0085,0x0083,0xC5C5,0x92E5,0x0083,0xC6FE,0xCCCD,0x0085,0x0083,0xDEE1,0x92E4,0x0083,0xD5C6,0x92E3,0x0091,0x0089, 0x0085,0x0083,0xDEE5,0xB5F4,0x0083,0xCADA,0xB6DE,0x0085,0x0083,0x92E2,0x92E1,0x0083,0x92E0,0x92DF,0x0089,0x0085, 0x0083,0xB5E0,0x92DE,0x0083,0xCFC6,0x92DD,0x0085,0x0083,0x92DC,0x92DB,0x0083,0x92DA,0xC4ED,0x00A1,0x0091,0x0089, 0x0085,0x0083,0xDEE0,0x92D9,0x0083,0x92D8,0xBDDD,0x0085,0x0083,0xB4B7,0x92D7,0x0083,0x92D6,0x92D5,0x0089,0x0085, 0x0083,0x92D4,0xDEDF,0x0083,0x92D3,0x92D2,0x0085,0x0083,0xBEDD,0xDEE3,0x0083,0x92D1,0x92D0,0x0091,0x0089,0x0085, 0x0083,0x92CF,0xDEE6,0x0083,0x92CE,0xC5F5,0x0085,0x0083,0x92CD,0x92CC,0x0083,0x92CB,0xB5B7,0x0089,0x0085,0x0083, 0xBBBB,0xBCF1,0x0083,0x92CA,0xCBF0,0x0085,0x0083,0xC0CC,0x92C9,0x0083,0x92C8,0x92C7,0x017F,0x00FF,0x00BF,0x009F, 0x008F,0x0087,0x0083,0x92C6,0x0083,0x92C5,0x92C4,0x0085,0x0083,0x92C3,0x92C2,0x0083,0xB2B6,0x92C1,0x0089,0x0085, 0x0083,0x92C0,0x92BF,0x0083,0x92BE,0xBEE8,0x0085,0x0083,0xC4F3,0xC9D3,0x0083,0xBAB4,0xB0C6,0x0091,0x0089,0x0085, 0x0083,0xDEDB,0x92BD,0x0083,0xD7BD,0x92BC,0x0085,0x0083,0x92BB,0xC0A6,0x0083,0xCDB1,0x92BA,0x0089,0x0085,0x0083, 0xDEDC,0xCEE6,0x0083,0x92B9,0x92B8,0x0085,0x0083,0x92B7,0x92B6,0x0083,0xCDEC,0x92B5,0x00A1,0x0091,0x0089,0x0085, 0x0083,0x92B4,0xCDA6,0x0083,0xDEDA,0x92B3,0x0085,0x0083,0x92B2,0x92B1,0x0083,0x92B0,0x92AF,0x0089,0x0085,0x0083, 0x92AE,0xEAFD,0x0083,0x92AD,0x92AC,0x0085,0x0083,0xD5F1,0x92AB,0x0083,0x92AA,0x92A9,0x0091,0x0089,0x0085,0x0083, 0xB4EC,0xC5B2,0x0083,0x92A8,0xB0A4,0x0085,0x0083,0x92A7,0x92A6,0x0083,0xBBD3,0xBCB7,0x0089,0x0085,0x0083,0xD5F5, 0xDED8,0x0083,0xB5B2,0xC4D3,0x0085,0x0083,0xD0AE,0xCCA2,0x0083,0xCECE,0x92A5,0x00C1,0x00A1,0x0091,0x0089,0x0085, 0x0083,0xC2CE,0xD6BF,0x0083,0x92A4,0x92A3,0x0085,0x0083,0x92A2,0xCDDA,0x0083,0x92A1,0x92A0,0x0089,0x0085,0x0083, 0x929F,0x929E,0x0083,0xCCF4,0x929D,0x0085,0x0083,0x929C,0xBFE6,0x0083,0x929B,0x929A,0x0091,0x0089,0x0085,0x0083, 0x9299,0x9298,0x0083,0xB0B4,0xEAFC,0x0085,0x0083,0xD6B8,0x9297,0x0083,0x9296,0x9295,0x0089,0x0085,0x0083,0x9294, 0xB9D2,0x0083,0xB3D6,0x9293,0x0085,0x0083,0xC4C3,0xCAB0,0x0083,0xD7A7,0xC6B4,0x00A1,0x0091,0x0089,0x0085,0x0083, 0x9292,0x9291,0x0083,0x9290,0x928F,0x0085,0x0083,0xBFBD,0xDED9,0x0083,0x928E,0xCBA9,0x0089,0x0085,0x0083,0xC8AD, 0x928D,0x0083,0xB9B0,0x928C,0x0085,0x0083,0xD5FC,0xDED7,0x0083,0xCAC3,0xC0A8,0x0091,0x0089,0x0085,0x0083,0x928B, 0x928A,0x0083,0xD4F1,0xB2A6,0x0085,0x0083,0xC5A1,0xC0B9,0x0083,0xD3B5,0x9289,0x0089,0x0085,0x0083,0xBCF0,0xC2A3, 0x0083,0x9288,0x9287,0x0085,0x0083,0xC4E2,0x9286,0x0083,0x9285,0xB0DD,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085, 0x0083,0xD5D0,0xDED5,0x0083,0xD7BE,0xBED0,0x0085,0x0083,0xDED6,0xCDCF,0x0083,0x9284,0xB0CE,0x0089,0x0085,0x0083, 0xCDD8,0xBEDC,0x0083,0x9283,0xB9D5,0x0085,0x0083,0x9282,0xC1E0,0x0083,0xC5C4,0xB0E8,0x0091,0x0089,0x0085,0x0083, 0x9281,0xDED4,0x0083,0xC0AD,0xC4E9,0x0085,0x0083,0xC4B4,0xB2F0,0x0083,0xB5A3,0xD6F4,0x0089,0x0085,0x0083,0x9280, 0xB7F7,0x0083,0x927E,0x927D,0x0085,0x0083,0xC3F2,0x927C,0x0083,0xB3E9,0xD1BA,0x00A1,0x0091,0x0089,0x0085,0x0083, 0xDED3,0x927B,0x0083,0xC4A8,0x927A,0x0085,0x0083,0x9279,0x9278,0x0083,0xB5D6,0x9277,0x0089,0x0085,0x0083,0x9276, 0x9275,0x0083,0xB1A7,0x9274,0x0085,0x0083,0x9273,0x9272,0x0083,0x9271,0xCCA7,0x0091,0x0089,0x0085,0x0083,0xC5FB, 0x9270,0x0083,0x926F,0xC5EA,0x0085,0x0083,0x926E,0x926D,0x0083,0xB1A8,0xBBA4,0x0089,0x0085,0x0083,0x926C,0xC7C0, 0x0083,0xC2D5,0xBFD9,0x0085,0x0083,0xDED2,0x926B,0x0083,0x926A,0x9269,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083, 0xC5D7,0xB8A7,0x0083,0x9268,0xD5DB,0x0085,0x0083,0xBFB9,0xB6B6,0x0083,0xCDB6,0x9267,0x0089,0x0085,0x0083,0xD7A5, 0xCAE3,0x0083,0xD2D6,0x9266,0x0085,0x0083,0x9265,0x9264,0x0083,0x9263,0x9262,0x0091,0x0089,0x0085,0x0083,0x9261, 0xB0D1,0x0083,0xBEF1,0x9260,0x0085,0x0083,0x925F,0x925E,0x0083,0x925D,0xB3AD,0x0089,0x0085,0x0083,0x925C,0x925B, 0x0083,0x925A,0xBCBC,0x0085,0x0083,0xB3D0,0xD5D2,0x0083,0x9259,0xB6F3,0x00A1,0x0091,0x0089,0x0085,0x0083,0x9258, 0x9257,0x0083,0xC5FA,0x9256,0x0085,0x0083,0x9255,0xB7F6,0x0083,0x9254,0x9253,0x0089,0x0085,0x0083,0xB0E2,0x9252, 0x0083,0x9251,0xC8C5,0x0085,0x0083,0xB3B6,0xB0E7,0x0083,0xC5A4,0xD1EF,0x0091,0x0089,0x0085,0x0083,0xC9A8,0xDED1, 0x0083,0xC0A9,0x9250,0x0085,0x0083,0xD6B4,0xC7A4,0x0083,0x924F,0x924E,0x0089,0x0085,0x0083,0xBFDB,0x924D,0x0083, 0x924C,0x924B,0x0085,0x0083,0x924A,0x9249,0x0083,0x9248,0x9247,0x027F,0x017F,0x00FF,0x00BF,0x009F,0x008F,0x0087, 0x0083,0xBFB8,0x0083,0x9246,0x9245,0x0085,0x0083,0xCDD0,0x9244,0x0083,0x9243,0x9242,0x0089,0x0085,0x0083,0xC8D3, 0xB4F2,0x0083,0xB0C7,0xC6CB,0x0085,0x0083,0x9241,0x9240,0x0083,0xD4FA,0xB2C5,0x0091,0x0089,0x0085,0x0083,0xDED0, 0xCAD6,0x0083,0x91FE,0xECE9,0x0085,0x0083,0xECE8,0xC9C8,0x0083,0x91FD,0x91FC,0x0089,0x0085,0x0083,0x91FB,0xECE7, 0x0083,0x91FA,0xB1E2,0x0085,0x0083,0xCBF9,0xB7BF,0x0083,0xECE5,0xECE6,0x00A1,0x0091,0x0089,0x0085,0x0083,0x91F9, 0x91F8,0x0083,0x91F7,0x91F6,0x0085,0x0083,0x91F5,0xBBA7,0x0083,0x91F4,0x91F3,0x0089,0x0085,0x0083,0xB4F7,0xB4C1, 0x0083,0x91F2,0x91F1,0x0085,0x0083,0x91F0,0x91EF,0x0083,0xC2BE,0x91EE,0x0091,0x0089,0x0085,0x0083,0xEAAF,0x91ED, 0x0083,0xBDD8,0x91EC,0x0085,0x0083,0x91EB,0x91EA,0x0083,0x91E9,0xEAAD,0x0089,0x0085,0x0083,0xEAAE,0x91E8,0x0083, 0xEAAB,0xEAAC,0x0085,0x0083,0x91E7,0xEAAA,0x0083,0x91E6,0x91E5,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x91E4, 0xEAA9,0x0083,0xC6DD,0x91E3,0x0085,0x0083,0xD5BD,0xEAA8,0x0083,0xBBF2,0xE3DE,0x0089,0x0085,0x0083,0x91E2,0x91E1, 0x0083,0xBDE4,0xCED2,0x0085,0x0083,0xB3C9,0xCFB7,0x0083,0xC8D6,0xCAF9,0x0091,0x0089,0x0085,0x0083,0xD0E7,0xEAA7, 0x0083,0xCEEC,0x91E0,0x0085,0x0083,0xB8EA,0x91DF,0x0083,0xEDB0,0x91DE,0x0089,0x0085,0x0083,0x91DD,0x91DC,0x0083, 0x91DB,0x91DA,0x0085,0x0083,0x91D9,0xDCB2,0x0083,0x91D8,0x91D7,0x00A1,0x0091,0x0089,0x0085,0x0083,0x91D6,0x91D5, 0x0083,0x91D4,0x91D3,0x0085,0x0083,0x91D2,0x91D1,0x0083,0x91D0,0xE3C2,0x0089,0x0085,0x0083,0x91CF,0x91CE,0x0083, 0x91CD,0x91CC,0x0085,0x0083,0x91CB,0x91CA,0x0083,0x91C9,0x91C8,0x0091,0x0089,0x0085,0x0083,0x91C7,0x91C6,0x0083, 0x91C5,0x91C4,0x0085,0x0083,0x91C3,0x91C2,0x0083,0xC5B3,0x91C1,0x0089,0x0085,0x0083,0x91C0,0x91BF,0x0083,0x91BE, 0x91BD,0x0085,0x0083,0x91BC,0x91BB,0x0083,0x91BA,0x91B9,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x91B8, 0x91B7,0x0083,0x91B6,0x91B5,0x0085,0x0083,0x91B4,0x91B3,0x0083,0x91B2,0x91B1,0x0089,0x0085,0x0083,0xE3C1,0x91B0, 0x0083,0xC0C1,0xEDAF,0x0085,0x0083,0x91AF,0x91AE,0x0083,0x91AD,0x91AC,0x0091,0x0089,0x0085,0x0083,0x91AB,0xEDAE, 0x0083,0xB0C3,0x91AA,0x0085,0x0083,0xD0B8,0x91A9,0x0083,0x91A8,0x91A7,0x0089,0x0085,0x0083,0x91A6,0x91A5,0x0083, 0xB6AE,0x91A4,0x0085,0x0083,0x91A3,0x91A2,0x0083,0xBAB6,0x91A1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x91A0,0x919F, 0x0083,0x919E,0x919D,0x0085,0x0083,0x919C,0xE3C0,0x0083,0x919B,0x919A,0x0089,0x0085,0x0083,0x9199,0x9198,0x0083, 0x9197,0x9196,0x0085,0x0083,0x9195,0x9194,0x0083,0x9193,0x9192,0x0091,0x0089,0x0085,0x0083,0xE3BD,0x9191,0x0083, 0x9190,0xEDAC,0x0085,0x0083,0xBAA9,0xE3BF,0x0083,0x918F,0x918E,0x0089,0x0085,0x0083,0x918D,0x918C,0x0083,0x918B, 0x918A,0x0085,0x0083,0x9189,0x9188,0x0083,0x9187,0xEDAD,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x9186,0x9185, 0x0083,0x9184,0x9183,0x0085,0x0083,0x9182,0x9181,0x0083,0x9180,0x917E,0x0089,0x0085,0x0083,0xE3BE,0x917D,0x0083, 0x917C,0x917B,0x0085,0x0083,0x917A,0x9179,0x0083,0xD4F7,0x9178,0x0091,0x0089,0x0085,0x0083,0x9177,0xB1EF,0x0083, 0x9176,0x9175,0x0085,0x0083,0x9174,0x9173,0x0083,0x9172,0x9171,0x0089,0x0085,0x0083,0x9170,0x916F,0x0083,0x916E, 0x916D,0x0085,0x0083,0x916C,0x916B,0x0083,0x916A,0x9169,0x00A1,0x0091,0x0089,0x0085,0x0083,0x9168,0x9167,0x0083, 0x9166,0x9165,0x0085,0x0083,0x9164,0xBFB6,0x0083,0x9163,0xE3BC,0x0089,0x0085,0x0083,0x9162,0x9161,0x0083,0x9160, 0x915F,0x0085,0x0083,0xCEBF,0x915E,0x0083,0x915D,0x915C,0x0091,0x0089,0x0085,0x0083,0x915B,0x915A,0x0083,0x9159, 0x9158,0x0085,0x0083,0xBFAE,0xBBDB,0x0083,0x9157,0x9156,0x0089,0x0085,0x0083,0x9155,0x9154,0x0083,0xC2FD,0x9153, 0x0085,0x0083,0x9152,0x9151,0x0083,0x9150,0xEDAB,0x0181,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x914F, 0x914E,0x0083,0x914D,0x914C,0x0085,0x0083,0x914B,0x914A,0x0083,0x9149,0xC4BD,0x0089,0x0085,0x0083,0x9148,0x9147, 0x0083,0x9146,0xC9E5,0x0085,0x0083,0x9145,0x9144,0x0083,0xC9F7,0x9143,0x0091,0x0089,0x0085,0x0083,0xBBC5,0x9142, 0x0083,0xE3BB,0x9141,0x0085,0x0083,0xB4C8,0x9140,0x0083,0x90FE,0x90FD,0x0089,0x0085,0x0083,0x90FC,0x90FB,0x0083, 0x90FA,0x90F9,0x0085,0x0083,0x90F8,0xD4B8,0x0083,0x90F7,0x90F6,0x00A1,0x0091,0x0089,0x0085,0x0083,0x90F5,0x90F4, 0x0083,0x90F3,0x90F2,0x0085,0x0083,0x90F1,0x90F0,0x0083,0x90EF,0x90EE,0x0089,0x0085,0x0083,0x90ED,0x90EC,0x0083, 0x90EB,0x90EA,0x0085,0x0083,0x90E9,0x90E8,0x0083,0x90E7,0x90E6,0x0091,0x0089,0x0085,0x0083,0x90E5,0xE3BA,0x0083, 0x90E4,0x90E3,0x0085,0x0083,0x90E2,0xC0A2,0x0083,0xE3B4,0x90E1,0x0089,0x0085,0x0083,0xB7DF,0xE3B6,0x0083,0x90E0, 0x90DF,0x0085,0x0083,0xE3B3,0xB8D0,0x0083,0x90DE,0x90DD,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x90DC,0x90DB, 0x0083,0xD3DE,0x90DA,0x0085,0x0083,0x90D9,0x90D8,0x0083,0x90D7,0xE3B5,0x0089,0x0085,0x0083,0x90D6,0x90D5,0x0083, 0x90D4,0x90D3,0x0085,0x0083,0x90D2,0xD2E2,0x0083,0xE3B9,0xEDAA,0x0091,0x0089,0x0085,0x0083,0x90D1,0x90D0,0x0083, 0x90CF,0xD3E4,0x0085,0x0083,0xD3FA,0x90CE,0x0083,0xEDA9,0x90CD,0x0089,0x0085,0x0083,0x90CC,0x90CB,0x0083,0x90CA, 0xB3EE,0x0085,0x0083,0xE3B8,0x90C9,0x0083,0x90C8,0x90C7,0x00A1,0x0091,0x0089,0x0085,0x0083,0x90C6,0x90C5,0x0083, 0xD0CA,0xC8C7,0x0085,0x0083,0x90C4,0x90C3,0x0083,0xBBCC,0x90C2,0x0089,0x0085,0x0083,0xE3B7,0xCFEB,0x0083,0x90C1, 0x90C0,0x0085,0x0083,0xB6E8,0xB9DF,0x0083,0xB5AC,0xB2D1,0x0091,0x0089,0x0085,0x0083,0xE3AB,0xB1B9,0x0083,0x90BF, 0xB3CD,0x0085,0x0083,0xB2D2,0xBEE5,0x0083,0xB5EB,0x90BE,0x0089,0x0085,0x0083,0x90BD,0x90BC,0x0083,0x90BB,0x90BA, 0x0085,0x0083,0xBBDD,0xCEA9,0x0083,0x90B9,0xE3AE,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xCFA7,0x90B8, 0x0083,0xE3B1,0x90B7,0x0085,0x0083,0xE3AF,0x90B6,0x0083,0x90B5,0xCCE8,0x0089,0x0085,0x0083,0x90B4,0x90B3,0x0083, 0x90B2,0xBBF3,0x0085,0x0083,0x90B1,0x90B0,0x0083,0x90AF,0x90AE,0x0091,0x0089,0x0085,0x0083,0x90AD,0xCDEF,0x0083, 0xBEAA,0x90AC,0x0085,0x0083,0x90AB,0x90AA,0x0083,0xE3B0,0xC7E9,0x0089,0x0085,0x0083,0x90A9,0x90A8,0x0083,0x90A7, 0x90A6,0x0085,0x0083,0x90A5,0x90A4,0x0083,0x90A3,0x90A2,0x00A1,0x0091,0x0089,0x0085,0x0083,0xB5BF,0xE3AC,0x0083, 0x90A1,0x90A0,0x0085,0x0083,0xBCC2,0x909F,0x0083,0x909E,0x909D,0x0089,0x0085,0x0083,0xE3B2,0x909C,0x0083,0xB1AF, 0xE3AD,0x0085,0x0083,0x909B,0xC3F5,0x0083,0x909A,0xE3A5,0x0091,0x0089,0x0085,0x0083,0xD0FC,0xEDA8,0x0083,0x9099, 0x9098,0x0085,0x0083,0xC4FA,0x9097,0x0083,0xD4C3,0x9096,0x0089,0x0085,0x0083,0x9095,0xBBBC,0x0083,0x9094,0x9093, 0x0085,0x0083,0xD3C6,0xCEF2,0x0083,0x9092,0xE3A6,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x9091,0xE3AA,0x0083, 0xE3A4,0x9090,0x0085,0x0083,0x908F,0x908E,0x0083,0xE3A3,0x908D,0x0089,0x0085,0x0083,0xBBDA,0x908C,0x0083,0xE3A8, 0x908B,0x0085,0x0083,0x908A,0x9089,0x0083,0x9088,0xBAB7,0x0091,0x0089,0x0085,0x0083,0xE3A9,0x9087,0x0083,0x9086, 0xCFA4,0x0085,0x0083,0x9085,0x9084,0x0083,0x9083,0x9082,0x0089,0x0085,0x0083,0xC7C4,0xE3A7,0x0083,0x9081,0x9080, 0x0085,0x0083,0x907E,0xD3C1,0x0083,0x907D,0xE3A2,0x00A1,0x0091,0x0089,0x0085,0x0083,0xC4D5,0xE2FC,0x0083,0xE2FD, 0xE2FB,0x0085,0x0083,0xE2FA,0x907C,0x0083,0xB6F1,0x907B,0x0089,0x0085,0x0083,0x907A,0xBFD2,0x0083,0x9079,0x9078, 0x0085,0x0083,0xC7A1,0xCFA2,0x0083,0x9077,0xB9A7,0x0091,0x0089,0x0085,0x0083,0xCCF1,0xB6B2,0x0083,0xE3A1,0xB6F7, 0x0085,0x0083,0xBADE,0xEDA4,0x0083,0x9076,0x9075,0x0089,0x0085,0x0083,0xD0F4,0xEDA7,0x0083,0xBBD6,0x9074,0x0085, 0x0083,0x9073,0x9072,0x0083,0x9071,0xEDA2,0x2069,0x1075,0x087B,0x047D,0x027F,0x017F,0x00FF,0x00BF,0x009F,0x008F, 0x0087,0x0083,0x9070,0x0083,0x906F,0xEDA3,0x0085,0x0083,0xEDA6,0x906E,0x0083,0x906D,0x906C,0x0089,0x0085,0x0083, 0xCBA1,0x906B,0x0083,0x906A,0xBAE3,0x0085,0x0083,0x9069,0xBFD6,0x0083,0x9068,0x9067,0x0091,0x0089,0x0085,0x0083, 0xBBD0,0x9066,0x0083,0xC1B5,0x9065,0x0085,0x0083,0x9064,0x9063,0x0083,0x9062,0x9061,0x0089,0x0085,0x0083,0x9060, 0x905F,0x0083,0xCAD1,0xE2FE,0x0085,0x0083,0xEDA5,0x905E,0x0083,0xE2F8,0x905D,0x00A1,0x0091,0x0089,0x0085,0x0083, 0x905C,0xEDA1,0x0083,0xD7DC,0x905B,0x0085,0x0083,0x905A,0x9059,0x0083,0x9058,0x9057,0x0089,0x0085,0x0083,0xE2F0, 0x9056,0x0083,0x9055,0x9054,0x0085,0x0083,0x9053,0x9052,0x0083,0xC7D3,0x9051,0x0091,0x0089,0x0085,0x0083,0x9050, 0x904F,0x0083,0xE2F6,0xB9D6,0x0085,0x0083,0xE2F5,0xD4B9,0x0083,0xD0D4,0xE2F1,0x0089,0x0085,0x0083,0xBCB1,0x904E, 0x0083,0x904D,0x904C,0x0085,0x0083,0xE2F9,0xB5A1,0x0083,0x904B,0x904A,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083, 0xCBBC,0xC1AF,0x0083,0xE2F2,0x9049,0x0085,0x0083,0xE2EF,0x9048,0x0083,0x9047,0xB2C0,0x0089,0x0085,0x0083,0xC5C2, 0xD5FA,0x0083,0x9046,0xC5AD,0x0085,0x0083,0x9045,0x9044,0x0083,0xE2F3,0xD4F5,0x0091,0x0089,0x0085,0x0083,0xE2F4, 0x9043,0x0083,0x9042,0xE2F7,0x0085,0x0083,0x9041,0x9040,0x0083,0x8FFE,0xE2EB,0x0089,0x0085,0x0083,0xE2EA,0xE2E6, 0x0083,0xE2E4,0xCBCB,0x0085,0x0083,0xCCAC,0xBBB3,0x0083,0xB7DE,0xE2E9,0x00A1,0x0091,0x0089,0x0085,0x0083,0xBAF6, 0x8FFD,0x0083,0xD0C3,0x8FFC,0x0085,0x0083,0x8FFB,0xE2EE,0x0083,0x8FFA,0x8FF9,0x0089,0x0085,0x0083,0xC4EE,0x8FF8, 0x0083,0x8FF7,0x8FF6,0x0085,0x0083,0xB3C0,0x8FF5,0x0083,0x8FF4,0xE2E5,0x0091,0x0089,0x0085,0x0083,0xE2ED,0x8FF3, 0x0083,0xBFEC,0xE2EC,0x0085,0x0083,0x8FF2,0x8FF1,0x0083,0xD3C7,0x8FF0,0x0089,0x0085,0x0083,0x8FEF,0xE2E8,0x0083, 0x8FEE,0x8FED,0x0085,0x0083,0xE2E7,0xD6D2,0x0083,0x8FEC,0x8FEB,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083, 0xE3C3,0x8FEA,0x0083,0x8FE9,0x8FE8,0x0085,0x0083,0xC3A6,0xCDFC,0x0083,0xD6BE,0xE2E2,0x0089,0x0085,0x0083,0x8FE7, 0x8FE6,0x0083,0x8FE5,0xDFAF,0x0085,0x0083,0xECFD,0xECFE,0x0083,0xE2E3,0x8FE4,0x0091,0x0089,0x0085,0x0083,0xC8CC, 0xBCC9,0x0083,0x8FE3,0x8FE2,0x0085,0x0083,0xE2E1,0x8FE1,0x0083,0x8FE0,0xD2E4,0x0089,0x0085,0x0083,0xB1D8,0xE2E0, 0x0083,0xD0C4,0x8FDF,0x0085,0x0083,0x8FDE,0x8FDD,0x0083,0x8FDC,0x8FDB,0x00A1,0x0091,0x0089,0x0085,0x0083,0xBBD5, 0xE1E8,0x0083,0x8FDA,0x8FD9,0x0085,0x0083,0x8FD8,0x8FD7,0x0083,0xB5C2,0x8FD6,0x0089,0x0085,0x0083,0xE1E7,0x8FD5, 0x0083,0x8FD4,0x8FD3,0x0085,0x0083,0x8FD2,0x8FD1,0x0083,0x8FD0,0xCEA2,0x0091,0x0089,0x0085,0x0083,0xE1E6,0x8FCF, 0x0083,0x8FCE,0xD1AD,0x0085,0x0083,0x8FCD,0xE1E5,0x0083,0x8FCC,0x8FCB,0x0089,0x0085,0x0083,0x8FCA,0x8FC9,0x0083, 0x8FC8,0x8FC7,0x0085,0x0083,0xD3F9,0x8FC6,0x0083,0x8FC5,0x8FC4,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x8FC3, 0xE1E4,0x0083,0x8FC2,0x8FC1,0x0085,0x0083,0xE1E3,0xC5C7,0x0083,0xB5C3,0x8FC0,0x0089,0x0085,0x0083,0xE1E2,0x8FBF, 0x0083,0x8FBE,0xCDBD,0x0085,0x0083,0x8FBD,0xD0EC,0x0083,0x8FBC,0x8FBB,0x0091,0x0089,0x0085,0x0083,0x8FBA,0xE1E1, 0x0083,0xC2C9,0xBBB2,0x0085,0x0083,0xE1E0,0xBADC,0x0083,0xE1DF,0x8FB9,0x0089,0x0085,0x0083,0xB4FD,0xBEB6,0x0083, 0x8FB8,0xE1DE,0x0085,0x0083,0xD5F7,0xCDF9,0x0083,0x8FB7,0x8FB6,0x00A1,0x0091,0x0089,0x0085,0x0083,0x8FB5,0xB1CB, 0x0083,0xB3B9,0x8FB4,0x0085,0x0083,0xD2DB,0x8FB3,0x0083,0xE1DD,0x8FB2,0x0089,0x0085,0x0083,0x8FB1,0x8FB0,0x0083, 0xE1DC,0x8FAF,0x0085,0x0083,0xD3B0,0xD5C3,0x0083,0x8FAE,0x8FAD,0x0091,0x0089,0x0085,0x0083,0xC5ED,0xB1F2,0x0083, 0x8FAC,0xB1EB,0x0085,0x0083,0xB2CA,0x8FAB,0x0083,0x8FAA,0xD1E5,0x0089,0x0085,0x0083,0x8FA9,0xCDAE,0x0083,0x8FA8, 0xD0CE,0x0085,0x0083,0xE1EA,0x8FA7,0x0083,0x8FA6,0x8FA5,0x017F,0x00FF,0x00BF,0x009F,0x008F,0x0087,0x0083,0xD2CD, 0x0083,0x8FA4,0x8FA3,0x0085,0x0083,0x8FA2,0x8FA1,0x0083,0xE5E9,0xE5E7,0x0089,0x0085,0x0083,0xE5E8,0xC2BC,0x0083, 0x8FA0,0xB5B1,0x0085,0x0083,0xB9E9,0x8F9F,0x0083,0xE5E6,0x8F9E,0x0091,0x0089,0x0085,0x0083,0x8F9D,0x8F9C,0x0083, 0x8F9B,0x8F9A,0x0085,0x0083,0x8F99,0x8F98,0x0083,0x8F97,0x8F96,0x0089,0x0085,0x0083,0x8F95,0x8F94,0x0083,0x8F93, 0x8F92,0x0085,0x0083,0x8F91,0x8F90,0x0083,0xECB0,0x8F8F,0x00A1,0x0091,0x0089,0x0085,0x0083,0x8F8E,0x8F8D,0x0083, 0xE5F6,0x8F8C,0x0085,0x0083,0xC7BF,0xB5AF,0x0083,0x8F8B,0x8F8A,0x0089,0x0085,0x0083,0x8F89,0x8F88,0x0083,0x8F87, 0x8F86,0x0085,0x0083,0x8F85,0xC8F5,0x0083,0x8F84,0xCDE4,0x0091,0x0089,0x0085,0x0083,0x8F83,0xE5F4,0x0083,0x8F82, 0x8F81,0x0085,0x0083,0xE5F2,0xE5F3,0x0083,0x8F80,0xBBA1,0x0089,0x0085,0x0083,0xCFD2,0xC3D6,0x0083,0x8F7E,0x8F7D, 0x0085,0x0083,0x8F7C,0x8F7B,0x0083,0xD5C5,0xB5DC,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x8F7A,0x8F79,0x0083, 0x8F78,0xB3DA,0x0085,0x0083,0x8F77,0x8F76,0x0083,0xBAEB,0xB8A5,0x0089,0x0085,0x0083,0x8F75,0xD2FD,0x0083,0x8F74, 0xB9AD,0x0085,0x0083,0x8F73,0xDFB1,0x0083,0x8F72,0xCABD,0x0091,0x0089,0x0085,0x0083,0x8F71,0x8F70,0x0083,0x8F6F, 0xDFAE,0x0085,0x0083,0xB1D7,0x8F6E,0x0083,0xDEC4,0x8F6D,0x0089,0x0085,0x0083,0x8F6C,0x8F6B,0x0083,0xC5AA,0xC6FA, 0x0085,0x0083,0xD2EC,0xDBCD,0x0083,0xBFAA,0xD8A5,0x00A1,0x0091,0x0089,0x0085,0x0083,0xDEC3,0x8F6A,0x0083,0x8F69, 0x8F68,0x0085,0x0083,0xBDA8,0x8F67,0x0083,0x8F66,0xCDA2,0x0089,0x0085,0x0083,0xD1D3,0x8F65,0x0083,0xDBC8,0x8F64, 0x0085,0x0083,0x8F63,0x8F62,0x0083,0x8F61,0x8F60,0x0091,0x0089,0x0085,0x0083,0x8F5F,0x8F5E,0x0083,0x8F5D,0x8F5C, 0x0085,0x0083,0xE2DE,0x8F5B,0x0083,0xE2DD,0x8F5A,0x0089,0x0085,0x0083,0x8F59,0x8F58,0x0083,0x8F57,0x8F56,0x0085, 0x0083,0x8F55,0x8F54,0x0083,0x8F53,0x8F52,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x8F51,0x8F50,0x0083, 0x8F4F,0xE2DC,0x0085,0x0083,0x8F4E,0x8F4D,0x0083,0x8F4C,0x8F4B,0x0089,0x0085,0x0083,0xC1CE,0x8F4A,0x0083,0x8F49, 0xC0AA,0x0085,0x0083,0xE2DA,0xE2DB,0x0083,0x8F48,0x8F47,0x0091,0x0089,0x0085,0x0083,0x8F46,0x8F45,0x0083,0x8F44, 0x8F43,0x0085,0x0083,0xC0C8,0xC1AE,0x0083,0x8F42,0x8F41,0x0089,0x0085,0x0083,0x8F40,0x8EFE,0x0083,0x8EFD,0x8EFC, 0x0085,0x0083,0x8EFB,0x8EFA,0x0083,0x8EF9,0x8EF8,0x00A1,0x0091,0x0089,0x0085,0x0083,0xE2D7,0x8EF7,0x0083,0x8EF6, 0x8EF5,0x0085,0x0083,0x8EF4,0xE2D5,0x0083,0xD3B9,0xBFB5,0x0089,0x0085,0x0083,0xCAFC,0xE2D6,0x0083,0x8EF3,0xE2D8, 0x0085,0x0083,0x8EF2,0x8EF1,0x0083,0x8EF0,0x8EEF,0x0091,0x0089,0x0085,0x0083,0x8EEE,0xCDA5,0x0083,0x8EED,0x8EEC, 0x0085,0x0083,0x8EEB,0x8EEA,0x0083,0x8EE9,0xD7F9,0x0089,0x0085,0x0083,0xB6C8,0xE2D3,0x0083,0x8EE8,0x8EE7,0x0085, 0x0083,0x8EE6,0x8EE5,0x0083,0xE2D4,0xB7CF,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xC5D3,0x8EE4,0x0083,0xB8AE, 0x8EE3,0x0085,0x0083,0xB8FD,0xC3ED,0x0083,0x8EE2,0xB5EA,0x0089,0x0085,0x0083,0xE2D2,0xB5D7,0x0083,0xD3A6,0xBFE2, 0x0085,0x0083,0x8EE1,0xE2D0,0x0083,0xC2AE,0xD0F2,0x0091,0x0089,0x0085,0x0083,0x8EE0,0x8EDF,0x0083,0x8EDE,0xE2D1, 0x0085,0x0083,0xB4B2,0x8EDD,0x0083,0x8EDC,0xB1D3,0x0089,0x0085,0x0083,0xC7EC,0x8EDB,0x0083,0xD7AF,0x8EDA,0x0085, 0x0083,0x8ED9,0x8ED8,0x0083,0xE2CF,0xB9E3,0x00A1,0x0091,0x0089,0x0085,0x0083,0x8ED7,0xD3C4,0x0083,0xD3D7,0xBBC3, 0x0085,0x0083,0xE7DB,0x8ED6,0x0083,0xD0D2,0x8ED5,0x0089,0x0085,0x0083,0xB2A2,0x8ED4,0x0083,0xC4EA,0xC6BD,0x0085, 0x0083,0xB8C9,0x8ED3,0x0083,0x8ED2,0x8ED1,0x0091,0x0089,0x0085,0x0083,0x8ED0,0x8ECF,0x0083,0x8ECE,0x8ECD,0x0085, 0x0083,0x8ECC,0x8ECB,0x0083,0x8ECA,0x8EC9,0x0089,0x0085,0x0083,0x8EC8,0x8EC7,0x0083,0x8EC6,0x8EC5,0x0085,0x0083, 0xB4B1,0xE1A6,0x0083,0x8EC4,0x8EC3,0x027F,0x017F,0x00FF,0x00BF,0x009F,0x008F,0x0087,0x0083,0xE1A5,0x0083,0x8EC2, 0x8EC1,0x0085,0x0083,0xE1A4,0x8EC0,0x0083,0x8EBF,0x8EBE,0x0089,0x0085,0x0083,0x8EBD,0x8EBC,0x0083,0xC4BB,0xE1A3, 0x0085,0x0083,0x8EBB,0x8EBA,0x0083,0x8EB9,0x8EB8,0x0091,0x0089,0x0085,0x0083,0x8EB7,0x8EB6,0x0083,0x8EB5,0xBBCF, 0x0085,0x0083,0x8EB4,0x8EB3,0x0083,0x8EB2,0x8EB1,0x0089,0x0085,0x0083,0x8EB0,0x8EAF,0x0083,0xB7F9,0xE1A2,0x0085, 0x0083,0x8EAE,0xC3DD,0x0083,0x8EAD,0x8EAC,0x00A1,0x0091,0x0089,0x0085,0x0083,0x8EAB,0x8EAA,0x0083,0xC3B1,0xE0FE, 0x0085,0x0083,0xE0FD,0x8EA9,0x0083,0x8EA8,0xB3A3,0x0089,0x0085,0x0083,0xE1A1,0x8EA7,0x0083,0x8EA6,0x8EA5,0x0085, 0x0083,0x8EA4,0x8EA3,0x0083,0xE0FC,0x8EA2,0x0091,0x0089,0x0085,0x0083,0x8EA1,0xB0EF,0x0083,0xCFAF,0x8EA0,0x0085, 0x0083,0x8E9F,0x8E9E,0x0083,0x8E9D,0x8E9C,0x0089,0x0085,0x0083,0xD6A1,0xB4F8,0x0083,0x8E9B,0x8E9A,0x0085,0x0083, 0x8E99,0x8E98,0x0083,0x8E97,0x8E96,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x8E95,0x8E94,0x0083,0xB5DB,0xD6C4, 0x0085,0x0083,0xB2AF,0xD6E3,0x0083,0xE0F9,0xC1B1,0x0089,0x0085,0x0083,0x8E93,0xCCFB,0x0083,0xC5C1,0xE0FA,0x0085, 0x0083,0x8E92,0x8E91,0x0083,0xE0FB,0xD5CA,0x0091,0x0089,0x0085,0x0083,0xE0F8,0x8E90,0x0083,0x8E8F,0xCFA3,0x0085, 0x0083,0x8E8E,0x8E8D,0x0083,0x8E8C,0xCAA6,0x0089,0x0085,0x0083,0x8E8B,0xB7AB,0x0083,0xCBA7,0x8E8A,0x0085,0x0083, 0xB2BC,0xCAD0,0x0083,0xB1D2,0x8E89,0x00A1,0x0091,0x0089,0x0085,0x0083,0x8E88,0xBDED,0x0083,0xD9E3,0x8E87,0x0085, 0x0083,0x8E86,0x8E85,0x0083,0x8E84,0x8E83,0x0089,0x0085,0x0083,0xCFEF,0x8E82,0x0083,0x8E81,0xB0CD,0x0085,0x0083, 0xCBC8,0xD2D1,0x0083,0xBCBA,0x8E80,0x0091,0x0089,0x0085,0x0083,0xDBCF,0xB2EE,0x0083,0x8E7E,0x8E7D,0x0085,0x0083, 0xCED7,0x8E7C,0x0083,0xB9AE,0xBEDE,0x0089,0x0085,0x0083,0xC7C9,0xD7F3,0x0083,0xB9A4,0x8E7B,0x0085,0x0083,0x8E7A, 0xB3B2,0x0083,0xD1B2,0x8E79,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x8E78,0xD6DD,0x0083,0xB4A8,0x8E77, 0x0085,0x0083,0xE7DD,0x8E76,0x0083,0x8E75,0x8E74,0x0089,0x0085,0x0083,0x8E73,0x8E72,0x0083,0x8E71,0x8E70,0x0085, 0x0083,0x8E6F,0x8E6E,0x0083,0x8E6D,0x8E6C,0x0091,0x0089,0x0085,0x0083,0x8E6B,0x8E6A,0x0083,0xCEA1,0x8E69,0x0085, 0x0083,0x8E68,0x8E67,0x0083,0x8E66,0x8E65,0x0089,0x0085,0x0083,0x8E64,0x8E63,0x0083,0xE1DB,0x8E62,0x0085,0x0083, 0x8E61,0x8E60,0x0083,0x8E5F,0x8E5E,0x00A1,0x0091,0x0089,0x0085,0x0083,0x8E5D,0x8E5C,0x0083,0x8E5B,0x8E5A,0x0085, 0x0083,0x8E59,0x8E58,0x0083,0x8E57,0x8E56,0x0089,0x0085,0x0083,0xE1DA,0x8E55,0x0083,0x8E54,0x8E53,0x0085,0x0083, 0x8E52,0x8E51,0x0083,0x8E50,0x8E4F,0x0091,0x0089,0x0085,0x0083,0x8E4E,0x8E4D,0x0083,0x8E4C,0x8E4B,0x0085,0x0083, 0x8E4A,0x8E49,0x0083,0x8E48,0x8E47,0x0089,0x0085,0x0083,0x8E46,0x8E45,0x0083,0x8E44,0x8E43,0x0085,0x0083,0x8E42, 0x8E41,0x0083,0x8E40,0x8DFE,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x8DFD,0x8DFC,0x0083,0xE1D8,0x8DFB,0x0085, 0x0083,0x8DFA,0x8DF9,0x0083,0xE1D7,0x8DF8,0x0089,0x0085,0x0083,0x8DF7,0x8DF6,0x0083,0x8DF5,0x8DF4,0x0085,0x0083, 0x8DF3,0x8DF2,0x0083,0x8DF1,0x8DF0,0x0091,0x0089,0x0085,0x0083,0x8DEF,0x8DEE,0x0083,0x8DED,0x8DEC,0x0085,0x0083, 0x8DEB,0x8DEA,0x0083,0x8DE9,0x8DE8,0x0089,0x0085,0x0083,0x8DE7,0x8DE6,0x0083,0x8DE5,0x8DE4,0x0085,0x0083,0x8DE3, 0xE1D6,0x0083,0x8DE2,0x8DE1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x8DE0,0x8DDF,0x0083,0x8DDE,0x8DDD,0x0085,0x0083, 0x8DDC,0x8DDB,0x0083,0x8DDA,0x8DD9,0x0089,0x0085,0x0083,0x8DD8,0x8DD7,0x0083,0x8DD6,0xE1D5,0x0085,0x0083,0x8DD5, 0x8DD4,0x0083,0x8DD3,0x8DD2,0x0091,0x0089,0x0085,0x0083,0xE1CF,0x8DD1,0x0083,0x8DD0,0xE1CD,0x0085,0x0083,0xE1D1, 0x8DCF,0x0083,0xE1D4,0x8DCE,0x0089,0x0085,0x0083,0x8DCD,0x8DCC,0x0083,0x8DCB,0x8DCA,0x0085,0x0083,0x8DC9,0x8DC8, 0x0083,0x8DC7,0x8DC6,0x0181,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x8DC5,0x8DC4,0x0083,0xE1D0,0x8DC3, 0x0085,0x0083,0xE1CE,0x8DC2,0x0083,0x8DC1,0xE1C9,0x0089,0x0085,0x0083,0x8DC0,0x8DBF,0x0083,0x8DBE,0x8DBD,0x0085, 0x0083,0x8DBC,0x8DBB,0x0083,0x8DBA,0x8DB9,0x0091,0x0089,0x0085,0x0083,0x8DB8,0x8DB7,0x0083,0x8DB6,0xC7B6,0x0085, 0x0083,0xE1D2,0xE1D3,0x0083,0x8DB5,0x8DB4,0x0089,0x0085,0x0083,0xEFFA,0x8DB3,0x0083,0x8DB2,0x8DB1,0x0085,0x0083, 0x8DB0,0x8DAF,0x0083,0x8DAE,0x8DAD,0x00A1,0x0091,0x0089,0x0085,0x0083,0x8DAC,0xE1CA,0x0083,0xE1CC,0x8DAB,0x0085, 0x0083,0x8DAA,0x8DA9,0x0083,0x8DA8,0x8DA7,0x0089,0x0085,0x0083,0x8DA6,0x8DA5,0x0083,0x8DA4,0xE1CB,0x0085,0x0083, 0x8DA3,0x8DA2,0x0083,0x8DA1,0x8DA0,0x0091,0x0089,0x0085,0x0083,0x8D9F,0xE1C4,0x0083,0xD5B8,0x8D9E,0x0085,0x0083, 0x8D9D,0x8D9C,0x0083,0xB1C0,0x8D9B,0x0089,0x0085,0x0083,0xE1C2,0xE1C3,0x0083,0x8D9A,0xE1C5,0x0085,0x0083,0x8D99, 0x8D98,0x0083,0x8D97,0x8D96,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x8D95,0xE1C6,0x0083,0x8D94,0x8D93,0x0085, 0x0083,0xE1C8,0x8D92,0x0083,0x8D91,0x8D90,0x0089,0x0085,0x0083,0x8D8F,0xD1C2,0x0083,0x8D8E,0xB4DE,0x0085,0x0083, 0x8D8D,0x8D8C,0x0083,0x8D8B,0x8D8A,0x0091,0x0089,0x0085,0x0083,0x8D89,0xC6E9,0x0083,0x8D88,0x8D87,0x0085,0x0083, 0x8D86,0x8D85,0x0083,0x8D84,0x8D83,0x0089,0x0085,0x0083,0xB3E7,0xE1C7,0x0083,0x8D82,0x8D81,0x0085,0x0083,0xE1C1, 0xE1C0,0x0083,0x8D80,0x8D7E,0x00A1,0x0091,0x0089,0x0085,0x0083,0x8D7D,0x8D7C,0x0083,0x8D7B,0x8D7A,0x0085,0x0083, 0xBEFE,0x8D79,0x0083,0x8D78,0x8D77,0x0089,0x0085,0x0083,0x8D76,0x8D75,0x0083,0x8D74,0x8D73,0x0085,0x0083,0x8D72, 0x8D71,0x0083,0x8D70,0xB7E5,0x0091,0x0089,0x0085,0x0083,0x8D6F,0x8D6E,0x0083,0xC7CD,0x8D6D,0x0085,0x0083,0x8D6C, 0xD3F8,0x0083,0x8D6B,0xB6EB,0x0089,0x0085,0x0083,0x8D6A,0xC2CD,0x0083,0xE1BF,0xE1BD,0x0085,0x0083,0x8D69,0x8D68, 0x0083,0xCFBF,0x8D67,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x8D66,0x8D65,0x0083,0x8D64,0x8D63,0x0085, 0x0083,0x8D62,0x8D61,0x0083,0xD6C5,0x8D60,0x0089,0x0085,0x0083,0x8D5F,0x8D5E,0x0083,0x8D5D,0x8D5C,0x0085,0x0083, 0x8D5B,0xE1BC,0x0083,0x8D5A,0x8D59,0x0091,0x0089,0x0085,0x0083,0x8D58,0x8D57,0x0083,0x8D56,0x8D55,0x0085,0x0083, 0xE1BE,0x8D54,0x0083,0x8D53,0x8D52,0x0089,0x0085,0x0083,0x8D51,0x8D50,0x0083,0x8D4F,0xE1BB,0x0085,0x0083,0x8D4E, 0x8D4D,0x0083,0xE1B9,0x8D4C,0x00A1,0x0091,0x0089,0x0085,0x0083,0xBFF9,0x8D4B,0x0083,0xE1B4,0x8D4A,0x0085,0x0083, 0x8D49,0x8D48,0x0083,0x8D47,0xB0B6,0x0089,0x0085,0x0083,0xE1BA,0x8D46,0x0083,0xE1B2,0x8D45,0x0085,0x0083,0xD4C0, 0x8D44,0x0083,0xE1B7,0x8D43,0x0091,0x0089,0x0085,0x0083,0x8D42,0x8D41,0x0083,0xC1EB,0xE1B5,0x0085,0x0083,0xE1B6, 0x8D40,0x0083,0xD1D2,0x8CFE,0x0089,0x0085,0x0083,0x8CFD,0x8CFC,0x0083,0x8CFB,0x8CFA,0x0085,0x0083,0xE1B8,0xE1B3, 0x0083,0x8CF9,0x8CF8,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x8CF7,0x8CF6,0x0083,0x8CF5,0xE1B1,0x0085,0x0083, 0xB5BA,0xE1B0,0x0083,0xE1AE,0xE1AD,0x0089,0x0085,0x0083,0xB8DA,0xE1AB,0x0083,0x8CF4,0xB2ED,0x0085,0x0083,0x8CF3, 0x8CF2,0x0083,0xE1AF,0xE1AA,0x0091,0x0089,0x0085,0x0083,0x8CF1,0x8CF0,0x0083,0xE1A9,0xE1A7,0x0085,0x0083,0x8CEF, 0x8CEE,0x0083,0x8CED,0xE1AC,0x0089,0x0085,0x0083,0x8CEC,0x8CEB,0x0083,0x8CEA,0x8CE9,0x0085,0x0083,0x8CE8,0xC6F1, 0x0083,0xCBEA,0x8CE7,0x00A1,0x0091,0x0089,0x0085,0x0083,0xD3EC,0x8CE6,0x0083,0x8CE5,0x8CE4,0x0085,0x0083,0x8CE3, 0xE1A8,0x0083,0xD2D9,0x8CE2,0x0089,0x0085,0x0083,0x8CE1,0x8CE0,0x0083,0x8CDF,0x8CDE,0x0085,0x0083,0x8CDD,0x8CDC, 0x0083,0xC9BD,0x8CDB,0x0091,0x0089,0x0085,0x0083,0xCDCD,0xE5F8,0x0083,0x8CDA,0x8CD9,0x0085,0x0083,0x8CD8,0x8CD7, 0x0083,0x8CD6,0x8CD5,0x0089,0x0085,0x0083,0x8CD4,0xE5F0,0x0083,0xC2C4,0x8CD3,0x0085,0x0083,0xE5EF,0x8CD2,0x0083, 0xC2C5,0xCDC0,0x047D,0x027F,0x017F,0x00FF,0x00BF,0x009F,0x008F,0x0087,0x0083,0x8CD1,0x0083,0xCAF4,0x8CD0,0x0085, 0x0083,0x8CCF,0x8CCE,0x0083,0x8CCD,0xE5ED,0x0089,0x0085,0x0083,0x8CCC,0x8CCB,0x0083,0x8CCA,0xD5B9,0x0085,0x0083, 0x8CC9,0x8CC8,0x0083,0x8CC7,0xD0BC,0x0091,0x0089,0x0085,0x0083,0xE5EC,0xC6C1,0x0083,0xCABA,0x8CC6,0x0085,0x0083, 0x8CC5,0xCEDD,0x0083,0xBDEC,0xCCEB,0x0089,0x0085,0x0083,0xC7FC,0x8CC4,0x0083,0x8CC3,0xBED3,0x0085,0x0083,0x8CC2, 0x8CC1,0x0083,0xB2E3,0xC6A8,0x00A1,0x0091,0x0089,0x0085,0x0083,0xBED6,0xC4F2,0x0083,0xCEB2,0xBEA1,0x0085,0x0083, 0xC4E1,0xE5EA,0x0083,0xB3DF,0xD2FC,0x0089,0x0085,0x0083,0xCAAC,0x8CC0,0x0083,0x8CBF,0x8CBE,0x0085,0x0083,0xDECF, 0x8CBD,0x0083,0x8CBC,0xBECD,0x0091,0x0089,0x0085,0x0083,0x8CBB,0x8CBA,0x0083,0x8CB9,0x8CB8,0x0085,0x0083,0xDECE, 0x8CB7,0x0083,0x8CB6,0x8CB5,0x0089,0x0085,0x0083,0x8CB4,0xD2A2,0x0083,0x8CB3,0xDECD,0x0085,0x0083,0xD3C8,0x8CB2, 0x0083,0xDECC,0x8CB1,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x8CB0,0x8CAF,0x0083,0x8CAE,0xB3A2,0x0085,0x0083, 0xE6D9,0x8CAD,0x0083,0xC9D0,0x8CAC,0x0089,0x0085,0x0083,0xB3BE,0x8CAB,0x0083,0xBCE2,0xE6D8,0x0085,0x0083,0xB6FB, 0x8CAA,0x0083,0x8CA9,0xC9D9,0x0091,0x0089,0x0085,0x0083,0x8CA8,0xD0A1,0x0083,0x8CA7,0x8CA6,0x0085,0x0083,0x8CA5, 0x8CA4,0x0083,0xD7F0,0xCEBE,0x0089,0x0085,0x0083,0x8CA3,0x8CA2,0x0083,0xBDAB,0x8CA1,0x0085,0x0083,0xC9E4,0x8CA0, 0x0083,0x8C9F,0xB7E2,0x00A1,0x0091,0x0089,0x0085,0x0083,0x8C9E,0xCAD9,0x0083,0x8C9D,0x8C9C,0x0085,0x0083,0xB5BC, 0xD1B0,0x0083,0xCBC2,0xB6D4,0x0089,0x0085,0x0083,0xB4E7,0x8C9B,0x0083,0x8C9A,0x8C99,0x0085,0x0083,0x8C98,0x8C97, 0x0083,0x8C96,0x8C95,0x0091,0x0089,0x0085,0x0083,0xE5BE,0x8C94,0x0083,0xE5BC,0x8C93,0x0085,0x0083,0x8C92,0x8C91, 0x0083,0x8C90,0x8C8F,0x0089,0x0085,0x0083,0xD5AF,0x8C8E,0x0083,0x8C8D,0xC1C8,0x0085,0x0083,0xE5BB,0x8C8C,0x0083, 0x8C8B,0xB9D1,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x8C8A,0xB2EC,0x0083,0xC4AF,0xC7DE,0x0085,0x0083, 0x8C89,0x8C88,0x0083,0x8C87,0x8C86,0x0089,0x0085,0x0083,0x8C85,0x8C84,0x0083,0x8C83,0x8C82,0x0085,0x0083,0x8C81, 0xD4A2,0x0083,0xBAAE,0x8C80,0x0091,0x0089,0x0085,0x0083,0xC3C2,0x8C7E,0x0083,0x8C7D,0x8C7C,0x0085,0x0083,0xB8BB, 0x8C7B,0x0083,0x8C7A,0x8C79,0x0089,0x0085,0x0083,0x8C78,0xBFDC,0x0083,0xC3DC,0xD2FA,0x0085,0x0083,0xBCC4,0x8C77, 0x0083,0xBCC5,0x8C76,0x00A1,0x0091,0x0089,0x0085,0x0083,0x8C75,0xCBDE,0x0083,0xB1F6,0xBFED,0x0085,0x0083,0x8C74, 0x8C73,0x0083,0x8C72,0xC8DD,0x0089,0x0085,0x0083,0xE5B7,0x8C71,0x0083,0xBCD2,0xCFFC,0x0085,0x0083,0xD1E7,0xBAA6, 0x0083,0x8C70,0x8C6F,0x0091,0x0089,0x0085,0x0083,0xD4D7,0x8C6E,0x0083,0x8C6D,0x8C6C,0x0085,0x0083,0x8C6B,0xB9AC, 0x0083,0xCFDC,0x8C6A,0x0089,0x0085,0x0083,0x8C69,0x8C68,0x0083,0xBBC2,0xE5B6,0x0085,0x0083,0xCAD2,0xD0FB,0x0083, 0xBFCD,0xC9F3,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xB3E8,0x8C67,0x0083,0xCAB5,0xB1A6,0x0085,0x0083,0xD2CB, 0xCDF0,0x0083,0xB6A8,0xD6E6,0x0089,0x0085,0x0083,0xB9D9,0xD7DA,0x0083,0x8C66,0xE5B4,0x0085,0x0083,0x8C65,0xE5B5, 0x0083,0x8C64,0x8C63,0x0091,0x0089,0x0085,0x0083,0x8C62,0xBAEA,0x0083,0x8C61,0x8C60,0x0085,0x0083,0xCDEA,0xCBCE, 0x0083,0x8C5F,0xB0B2,0x0089,0x0085,0x0083,0xCAD8,0xD3EE,0x0083,0x8C5E,0xD5AC,0x0085,0x0083,0xE5B3,0xCBFC,0x0083, 0x8C5D,0xC4FE,0x00A1,0x0091,0x0089,0x0085,0x0083,0xE5B2,0x8C5C,0x0083,0x8C5B,0xC4F5,0x0085,0x0083,0x8C5A,0x8C59, 0x0083,0xC8E6,0x8C58,0x0089,0x0085,0x0083,0x8C57,0x8C56,0x0083,0x8C55,0xB7F5,0x0085,0x0083,0x8C54,0xE6DC,0x0083, 0x8C53,0xE5EE,0x0091,0x0089,0x0085,0x0083,0xCAEB,0x8C52,0x0083,0x8C51,0x8C50,0x0085,0x0083,0xD8AB,0x8C4F,0x0083, 0xC2CF,0xBAA2,0x0089,0x0085,0x0083,0x8C4E,0x8C4D,0x0083,0xD1A7,0xE6DB,0x0085,0x0083,0xB9C2,0xBCBE,0x0083,0xE6DF, 0x8C4C,0x017F,0x00FF,0x00BF,0x009F,0x008F,0x0087,0x0083,0x8C4B,0x0083,0xC3CF,0x8C4A,0x0085,0x0083,0xD0A2,0xD7CE, 0x0083,0xD8C3,0xE6DA,0x0089,0x0085,0x0083,0xCBEF,0xB4E6,0x0083,0xD7D6,0x8C49,0x0085,0x0083,0xD4D0,0xBFD7,0x0083, 0xE6DE,0x8C48,0x0091,0x0089,0x0085,0x0083,0xE6DD,0xD7D3,0x0083,0x8C47,0x8C46,0x0085,0x0083,0x8C45,0x8C44,0x0083, 0x8C43,0x8C42,0x0089,0x0085,0x0083,0x8C41,0x8C40,0x0083,0x8BFE,0x8BFD,0x0085,0x0083,0x8BFC,0x8BFB,0x0083,0x8BFA, 0x8BF9,0x00A1,0x0091,0x0089,0x0085,0x0083,0x8BF8,0xE6D7,0x0083,0x8BF7,0x8BF6,0x0085,0x0083,0x8BF5,0x8BF4,0x0083, 0x8BF3,0x8BF2,0x0089,0x0085,0x0083,0x8BF1,0x8BF0,0x0083,0xE6D6,0x8BEF,0x0085,0x0083,0x8BEE,0xD9F8,0x0083,0x8BED, 0xE6D5,0x0091,0x0089,0x0085,0x0083,0x8BEC,0x8BEB,0x0083,0x8BEA,0x8BE9,0x0085,0x0083,0x8BE8,0x8BE7,0x0083,0x8BE6, 0x8BE5,0x0089,0x0085,0x0083,0x8BE4,0x8BE3,0x0083,0x8BE2,0x8BE1,0x0085,0x0083,0x8BE0,0x8BDF,0x0083,0x8BDE,0x8BDD, 0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x8BDC,0x8BDB,0x0083,0x8BDA,0x8BD9,0x0085,0x0083,0x8BD8,0x8BD7,0x0083, 0x8BD6,0x8BD5,0x0089,0x0085,0x0083,0x8BD4,0x8BD3,0x0083,0xE6D3,0xE6D4,0x0085,0x0083,0x8BD2,0x8BD1,0x0083,0x8BD0, 0x8BCF,0x0091,0x0089,0x0085,0x0083,0x8BCE,0x8BCD,0x0083,0x8BCC,0x8BCB,0x0085,0x0083,0x8BCA,0x8BC9,0x0083,0x8BC8, 0x8BC7,0x0089,0x0085,0x0083,0xE6D2,0x8BC6,0x0083,0x8BC5,0x8BC4,0x0085,0x0083,0x8BC3,0x8BC2,0x0083,0x8BC1,0x8BC0, 0x00A1,0x0091,0x0089,0x0085,0x0083,0x8BBF,0x8BBE,0x0083,0x8BBD,0x8BBC,0x0085,0x0083,0x8BBB,0x8BBA,0x0083,0x8BB9, 0x8BB8,0x0089,0x0085,0x0083,0x8BB7,0x8BB6,0x0083,0x8BB5,0x8BB4,0x0085,0x0083,0x8BB3,0x8BB2,0x0083,0x8BB1,0x8BB0, 0x0091,0x0089,0x0085,0x0083,0xE6CD,0x8BAF,0x0083,0x8BAE,0x8BAD,0x0085,0x0083,0x8BAC,0x8BAB,0x0083,0xE6C6,0x8BAA, 0x0089,0x0085,0x0083,0xC4DB,0x8BA9,0x0083,0x8BA8,0xE6CF,0x0085,0x0083,0x8BA7,0x8BA6,0x0083,0xE6CC,0x8BA5,0x0101, 0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xB5D5,0xE6CB,0x0083,0x8BA4,0x8BA3,0x0085,0x0083,0x8BA2,0xE6D1,0x0083, 0x8BA1,0x8BA0,0x0089,0x0085,0x0083,0x8B9F,0xE6D0,0x0083,0x8B9E,0xE6CE,0x0085,0x0083,0x8B9D,0xE6C9,0x0083,0x8B9C, 0xE6C8,0x0091,0x0089,0x0085,0x0083,0x8B9B,0x8B9A,0x0083,0x8B99,0x8B98,0x0085,0x0083,0x8B97,0xCFD3,0x0083,0x8B96, 0x8B95,0x0089,0x0085,0x0083,0xBCB5,0x8B94,0x0083,0x8B93,0x8B92,0x0085,0x0083,0x8B91,0x8B90,0x0083,0x8B8F,0xC9A9, 0x00A1,0x0091,0x0089,0x0085,0x0083,0xBCDE,0x8B8E,0x0083,0x8B8D,0xE6C5,0x0085,0x0083,0x8B8C,0x8B8B,0x0083,0x8B8A, 0x8B89,0x0089,0x0085,0x0083,0x8B88,0xE6CA,0x0083,0x8B87,0x8B86,0x0085,0x0083,0xEBF4,0x8B85,0x0083,0xCFB1,0xE6C7, 0x0091,0x0089,0x0085,0x0083,0x8B84,0x8B83,0x0083,0x8B82,0x8B81,0x0085,0x0083,0x8B80,0x8B7E,0x0083,0x8B7D,0xE6C1, 0x0089,0x0085,0x0083,0x8B7C,0x8B7B,0x0083,0x8B7A,0x8B79,0x0085,0x0083,0x8B78,0x8B77,0x0083,0x8B76,0x8B75,0x00C1, 0x00A1,0x0091,0x0089,0x0085,0x0083,0x8B74,0x8B73,0x0083,0x8B72,0x8B71,0x0085,0x0083,0x8B70,0x8B6F,0x0083,0xE6C2, 0xC3C4,0x0089,0x0085,0x0083,0x8B6E,0x8B6D,0x0083,0x8B6C,0x8B6B,0x0085,0x0083,0x8B6A,0x8B69,0x0083,0x8B68,0xC3BD, 0x0091,0x0089,0x0085,0x0083,0x8B67,0x8B66,0x0083,0x8B65,0x8B64,0x0085,0x0083,0x8B63,0x8B62,0x0083,0x8B61,0x8B60, 0x0089,0x0085,0x0083,0x8B5F,0x8B5E,0x0083,0x8B5D,0x8B5C,0x0085,0x0083,0x8B5B,0x8B5A,0x0083,0x8B59,0x8B58,0x00A1, 0x0091,0x0089,0x0085,0x0083,0x8B57,0x8B56,0x0083,0xD0F6,0x8B55,0x0085,0x0083,0x8B54,0x8B53,0x0083,0x8B52,0xE6C4, 0x0089,0x0085,0x0083,0x8B51,0x8B50,0x0083,0xE6C3,0xC9F4,0x0085,0x0083,0xE6BF,0xD3A4,0x0083,0x8B4F,0x8B4E,0x0091, 0x0089,0x0085,0x0083,0x8B4D,0x8B4C,0x0083,0x8B4B,0x8B4A,0x0085,0x0083,0x8B49,0x8B48,0x0083,0x8B47,0xC0B7,0x0089, 0x0085,0x0083,0x8B46,0x8B45,0x0083,0xE6BA,0x8B44,0x0085,0x0083,0x8B43,0x8B42,0x0083,0x8B41,0xE6BE,0x027F,0x017F, 0x00FF,0x00BF,0x009F,0x008F,0x0087,0x0083,0x8B40,0x0083,0x8AFE,0x8AFD,0x0085,0x0083,0x8AFC,0x8AFB,0x0083,0x8AFA, 0x8AF9,0x0089,0x0085,0x0083,0xBBE9,0x8AF8,0x0083,0x8AF7,0x8AF6,0x0085,0x0083,0x8AF5,0xE6BC,0x0083,0x8AF4,0x8AF3, 0x0091,0x0089,0x0085,0x0083,0x8AF2,0x8AF1,0x0083,0x8AF0,0x8AEF,0x0085,0x0083,0x8AEE,0x8AED,0x0083,0x8AEC,0x8AEB, 0x0089,0x0085,0x0083,0xE6BB,0xCDF1,0x0083,0x8AEA,0x8AE9,0x0085,0x0083,0xC6C5,0x8AE8,0x0083,0x8AE7,0x8AE6,0x00A1, 0x0091,0x0089,0x0085,0x0083,0x8AE5,0x8AE4,0x0083,0xE6B9,0x8AE3,0x0085,0x0083,0x8AE2,0x8AE1,0x0083,0xE6BD,0x8AE0, 0x0089,0x0085,0x0083,0x8ADF,0x8ADE,0x0083,0x8ADD,0x8ADC,0x0085,0x0083,0xC8A2,0x8ADB,0x0083,0xE6B5,0x8ADA,0x0091, 0x0089,0x0085,0x0083,0xE6B4,0xD3E9,0x0083,0x8AD9,0x8AD8,0x0085,0x0083,0x8AD7,0x8AD6,0x0083,0x8AD5,0x8AD4,0x0089, 0x0085,0x0083,0x8AD3,0xC3E4,0x0083,0x8AD2,0x8AD1,0x0085,0x0083,0x8AD0,0xB6F0,0x0083,0x8ACF,0xE6B7,0x00C1,0x00A1, 0x0091,0x0089,0x0085,0x0083,0x8ACE,0x8ACD,0x0083,0xC9EF,0xBEEA,0x0085,0x0083,0x8ACC,0x8ACB,0x0083,0xC4C8,0x8ACA, 0x0089,0x0085,0x0083,0x8AC9,0x8AC8,0x0083,0xC4EF,0x8AC7,0x0085,0x0083,0x8AC6,0x8AC5,0x0083,0x8AC4,0xE6B8,0x0091, 0x0089,0x0085,0x0083,0x8AC3,0xE6B6,0x0083,0x8AC2,0x8AC1,0x0085,0x0083,0x8AC0,0x8ABF,0x0083,0xE6B2,0x8ABE,0x0089, 0x0085,0x0083,0x8ABD,0xE6B3,0x0083,0xE6AE,0xBDBF,0x0085,0x0083,0xE6AC,0xE6AB,0x0083,0xC2A6,0xCDDE,0x00A1,0x0091, 0x0089,0x0085,0x0083,0x8ABC,0xCDFE,0x0083,0x8ABB,0xD7CB,0x0085,0x0083,0x8ABA,0x8AB9,0x0083,0x8AB8,0xD2F6,0x0089, 0x0085,0x0083,0x8AB7,0xE6B1,0x0083,0x8AB6,0x8AB5,0x0085,0x0083,0x8AB4,0x8AB3,0x0083,0x8AB2,0x8AB1,0x0091,0x0089, 0x0085,0x0083,0x8AB0,0x8AAF,0x0083,0x8AAE,0x8AAD,0x0085,0x0083,0x8AAC,0x8AAB,0x0083,0xBCA7,0x8AAA,0x0089,0x0085, 0x0083,0x8AA9,0x8AA8,0x0083,0xD2CC,0x8AA7,0x0085,0x0083,0x8AA6,0xC0D1,0x0083,0x8AA5,0xE6AF,0x0101,0x00C1,0x00A1, 0x0091,0x0089,0x0085,0x0083,0x8AA4,0x8AA3,0x0083,0x8AA2,0x8AA1,0x0085,0x0083,0x8AA0,0xE6AD,0x0083,0xBDAA,0x8A9F, 0x0089,0x0085,0x0083,0xD2A6,0x8A9E,0x0083,0xE6B0,0xE6A9,0x0085,0x0083,0x8A9D,0x8A9C,0x0083,0xCEAF,0xD0D5,0x0091, 0x0089,0x0085,0x0083,0xE6A6,0xB9C3,0x0083,0xBDE3,0x8A9B,0x0085,0x0083,0x8A9A,0x8A99,0x0083,0x8A98,0xCABC,0x0089, 0x0085,0x0083,0xE6A2,0x8A97,0x0083,0x8A96,0x8A95,0x0085,0x0083,0xC4B7,0x8A94,0x0083,0x8A93,0x8A92,0x00A1,0x0091, 0x0089,0x0085,0x0083,0x8A91,0x8A90,0x0083,0x8A8F,0x8A8E,0x0085,0x0083,0xE6AA,0x8A8D,0x0083,0x8A8C,0xC6DE,0x0089, 0x0085,0x0083,0x8A8B,0xC3C3,0x0083,0x8A8A,0x8A89,0x0085,0x0083,0x8A88,0x8A87,0x0083,0x8A86,0x8A85,0x0091,0x0089, 0x0085,0x0083,0xE6A7,0x8A84,0x0083,0x8A83,0xE6A8,0x0085,0x0083,0xC4DD,0x8A82,0x0083,0x8A81,0xE6A3,0x0089,0x0085, 0x0083,0xE5FD,0xE5FC,0x0083,0xB7C1,0x8A80,0x0085,0x0083,0x8A7E,0xCDD7,0x0083,0xE6A5,0xE5FE,0x00C1,0x00A1,0x0091, 0x0089,0x0085,0x0083,0x8A7D,0x8A7C,0x0083,0x8A7B,0x8A7A,0x0085,0x0083,0xE6A4,0x8A79,0x0083,0x8A78,0x8A77,0x0089, 0x0085,0x0083,0x8A76,0xC3EE,0x0083,0x8A75,0xE6A1,0x0085,0x0083,0xD1FD,0x8A74,0x0083,0x8A73,0xBCCB,0x0091,0x0089, 0x0085,0x0083,0xB6CA,0x8A72,0x0083,0x8A71,0x8A70,0x0085,0x0083,0x8A6F,0xE5FB,0x0083,0x8A6E,0x8A6D,0x0089,0x0085, 0x0083,0xC8D1,0x8A6C,0x0083,0xC2E8,0xB8BE,0x0085,0x0083,0xD7B1,0x8A6B,0x0083,0xCDFD,0xE5FA,0x00A1,0x0091,0x0089, 0x0085,0x0083,0xC8E7,0xE5F9,0x0083,0x8A6A,0x8A69,0x0085,0x0083,0x8A68,0xBAC3,0x0083,0x8A67,0x8A66,0x0089,0x0085, 0x0083,0x8A65,0xCBFD,0x0083,0xBCE9,0x8A64,0x0085,0x0083,0xC4CC,0x8A63,0x0083,0xC5AB,0xC5AE,0x0091,0x0089,0x0085, 0x0083,0x8A62,0x8A61,0x0083,0x8A60,0x8A5F,0x0085,0x0083,0x8A5E,0x8A5D,0x0083,0x8A5C,0x8A5B,0x0089,0x0085,0x0083, 0x8A5A,0x8A59,0x0083,0x8A58,0x8A57,0x0085,0x0083,0x8A56,0xB0C2,0x0083,0x8A55,0x8A54,0x0181,0x0101,0x00C1,0x00A1, 0x0091,0x0089,0x0085,0x0083,0xC9DD,0x8A53,0x0083,0xB5EC,0x8A52,0x0085,0x0083,0x8A51,0x8A50,0x0083,0x8A4F,0x8A4E, 0x0089,0x0085,0x0083,0xDEC9,0x8A4D,0x0083,0xDECA,0xCCD7,0x0085,0x0083,0xBDB1,0xDEC8,0x0083,0xB1BC,0x8A4C,0x0091, 0x0089,0x0085,0x0083,0x8A4B,0xC6F5,0x0083,0x8A4A,0xD7E0,0x0085,0x0083,0xBFFC,0x8A49,0x0083,0x8A48,0xB7DC,0x0089, 0x0085,0x0083,0x8A47,0xB7EE,0x0083,0xC4CE,0xC6E6,0x0085,0x0083,0x8A46,0x8A45,0x0083,0xD1D9,0x8A44,0x00A1,0x0091, 0x0089,0x0085,0x0083,0xDBBC,0xDEC6,0x0083,0x8A43,0x8A42,0x0085,0x0083,0x8A41,0x8A40,0x0083,0xDEC5,0x89FE,0x0089, 0x0085,0x0083,0xB6E1,0xBCD0,0x0083,0xBFE4,0xD2C4,0x0085,0x0083,0x89FD,0x89FC,0x0083,0xCDB7,0x89FB,0x0091,0x0089, 0x0085,0x0083,0x89FA,0xCAA7,0x0083,0x89F9,0xBABB,0x0085,0x0083,0xD1EB,0xD8B2,0x0083,0x89F8,0xB7F2,0x0089,0x0085, 0x0083,0xCCAB,0xCCEC,0x0083,0x89F7,0xB4F3,0x0085,0x0083,0x89F6,0xE2B7,0x0083,0xE2B9,0x89F5,0x00C1,0x00A1,0x0091, 0x0089,0x0085,0x0083,0x89F4,0x89F3,0x0083,0x89F2,0xB9BB,0x0085,0x0083,0x89F1,0x89F0,0x0083,0xD2B9,0x89EF,0x0089, 0x0085,0x0083,0xB6E0,0xD9ED,0x0083,0x89EE,0x89ED,0x0085,0x0083,0xCDE2,0xCFA6,0x0083,0xD9E7,0x89EC,0x0091,0x0089, 0x0085,0x0083,0x89EB,0x89EA,0x0083,0x89E9,0xCFC4,0x0085,0x0083,0x89E8,0xB8B4,0x0083,0x89E7,0x89E6,0x0089,0x0085, 0x0083,0x89E5,0x89E4,0x0083,0x89E3,0xB1B8,0x0085,0x0083,0x89E2,0x89E1,0x0083,0xB4A6,0x89E0,0x00A1,0x0091,0x0089, 0x0085,0x0083,0xE2BA,0x89DF,0x0083,0x89DE,0x89DD,0x0085,0x0083,0x89DC,0x89DB,0x0083,0x89DA,0x89D9,0x0089,0x0085, 0x0083,0x89D8,0xD2BC,0x0083,0x89D7,0x89D6,0x0085,0x0083,0xBAF8,0x89D5,0x0083,0x89D4,0xBFC7,0x0091,0x0089,0x0085, 0x0083,0x89D3,0x89D2,0x0083,0xC9F9,0x89D1,0x0085,0x0083,0xD7B3,0x89D0,0x0083,0xC8C9,0xCABF,0x0089,0x0085,0x0083, 0x89CF,0x89CE,0x0083,0x89CD,0x89CC,0x0085,0x0083,0x89CB,0x89CA,0x0083,0xC8C0,0x89C9,0x0101,0x00C1,0x00A1,0x0091, 0x0089,0x0085,0x0083,0x89C8,0x89C7,0x0083,0x89C6,0x89C5,0x0085,0x0083,0x89C4,0x89C3,0x0083,0x89C2,0x89C1,0x0089, 0x0085,0x0083,0x89C0,0x89BF,0x0083,0x89BE,0x89BD,0x0085,0x0083,0x89BC,0xBABE,0x0083,0x89BB,0x89BA,0x0091,0x0089, 0x0085,0x0083,0x89B9,0xDBD6,0x0083,0x89B8,0x89B7,0x0085,0x0083,0x89B6,0x89B5,0x0083,0x89B4,0x89B3,0x0089,0x0085, 0x0083,0x89B2,0x89B1,0x0083,0x89B0,0x89AF,0x0085,0x0083,0x89AE,0xDBD5,0x0083,0x89AD,0x89AC,0x00A1,0x0091,0x0089, 0x0085,0x0083,0x89AB,0xB1DA,0x0083,0x89AA,0x89A9,0x0085,0x0083,0x89A8,0x89A7,0x0083,0xDBD4,0x89A6,0x0089,0x0085, 0x0083,0x89A5,0x89A4,0x0083,0x89A3,0x89A2,0x0085,0x0083,0x89A1,0x89A0,0x0083,0x899F,0x899E,0x0091,0x0089,0x0085, 0x0083,0x899D,0x899C,0x0083,0x899B,0x899A,0x0085,0x0083,0x8999,0x8998,0x0083,0x8997,0x8996,0x0089,0x0085,0x0083, 0x8995,0xB6D5,0x0083,0xC4AB,0x8994,0x0085,0x0083,0x8993,0x8992,0x0083,0x8991,0x8990,0x00C1,0x00A1,0x0091,0x0089, 0x0085,0x0083,0x898F,0x898E,0x0083,0x898D,0xD0E6,0x0085,0x0083,0xD4F6,0x898C,0x0083,0x898B,0x898A,0x0089,0x0085, 0x0083,0xDCAE,0xC7BD,0x0083,0x8989,0x8988,0x0085,0x0083,0x8987,0x8986,0x0083,0x8985,0xC4B9,0x0091,0x0089,0x0085, 0x0083,0xC9CA,0x8984,0x0083,0x8983,0x8982,0x0085,0x0083,0x8981,0x8980,0x0083,0x897E,0x897D,0x0089,0x0085,0x0083, 0x897C,0xDCAD,0x0083,0x897B,0x897A,0x0085,0x0083,0x8979,0xCAFB,0x0083,0x8978,0xBEB3,0x00A1,0x0091,0x0089,0x0085, 0x0083,0x8977,0xDCAC,0x0083,0xDCAF,0x8976,0x0085,0x0083,0xDBD3,0x8975,0x0083,0x8974,0x8973,0x0089,0x0085,0x0083, 0x8972,0x8971,0x0083,0x8970,0x896F,0x0085,0x0083,0x896E,0x896D,0x0083,0x896C,0x896B,0x0091,0x0089,0x0085,0x0083, 0x896A,0x8969,0x0083,0x8968,0x8967,0x0085,0x0083,0x8966,0x8965,0x0083,0xDCAB,0xCCEE,0x0089,0x0085,0x0083,0x8964, 0x8963,0x0083,0x8962,0x8961,0x0085,0x0083,0x8960,0xDCAA,0x0083,0x895F,0x895E,0x087B,0x047D,0x027F,0x017F,0x00FF, 0x00BF,0x009F,0x008F,0x0087,0x0083,0x895D,0x0083,0x895C,0x895B,0x0085,0x0083,0x895A,0xC8FB,0x0083,0x8959,0x8958, 0x0089,0x0085,0x0083,0x8957,0x8956,0x0083,0x8955,0xCCC1,0x0085,0x0083,0x8954,0x8953,0x0083,0x8952,0xCBFE,0x0091, 0x0089,0x0085,0x0083,0x8951,0x8950,0x0083,0xCBDC,0x894F,0x0085,0x0083,0x894E,0x894D,0x0083,0xEBF3,0xCBFA,0x0089, 0x0085,0x0083,0x894C,0x894B,0x0083,0x894A,0x8949,0x0085,0x0083,0x8948,0x8947,0x0083,0x8946,0xDCA8,0x00A1,0x0091, 0x0089,0x0085,0x0083,0x8945,0x8944,0x0083,0x8943,0x8942,0x0085,0x0083,0x8941,0x8940,0x0083,0x88FE,0x88FD,0x0089, 0x0085,0x0083,0x88FC,0x88FB,0x0083,0x88FA,0x88F9,0x0085,0x0083,0x88F8,0x88F7,0x0083,0xB6C2,0x88F6,0x0091,0x0089, 0x0085,0x0083,0x88F5,0x88F4,0x0083,0x88F3,0xD1DF,0x0085,0x0083,0x88F2,0x88F1,0x0083,0x88F0,0x88EF,0x0089,0x0085, 0x0083,0x88EE,0xBFB0,0x0083,0x88ED,0x88EC,0x0085,0x0083,0x88EB,0x88EA,0x0083,0x88E9,0xB5CC,0x00C1,0x00A1,0x0091, 0x0089,0x0085,0x0083,0x88E8,0x88E7,0x0083,0xB1A4,0xDCA9,0x0085,0x0083,0x88E6,0xDCA6,0x0083,0x88E5,0x88E4,0x0089, 0x0085,0x0083,0x88E3,0x88E2,0x0083,0xDCA7,0x88E1,0x0085,0x0083,0x88E0,0x88DF,0x0083,0xB6E9,0x88DE,0x0091,0x0089, 0x0085,0x0083,0x88DD,0x88DC,0x0083,0xC7B5,0x88DB,0x0085,0x0083,0x88DA,0x88D9,0x0083,0xDCA2,0x88D8,0x0089,0x0085, 0x0083,0xDCA1,0x88D7,0x0083,0x88D6,0x88D5,0x0085,0x0083,0xDDC0,0xB6D1,0x0083,0x88D4,0x88D3,0x00A1,0x0091,0x0089, 0x0085,0x0083,0x88D2,0xCCC3,0x0083,0x88D1,0xDCA5,0x0085,0x0083,0x88D0,0x88CF,0x0083,0xDCA3,0x88CE,0x0089,0x0085, 0x0083,0x88CD,0xBBF9,0x0083,0xC5E0,0xDBFC,0x0085,0x0083,0x88CC,0x88CB,0x0083,0x88CA,0xDBFA,0x0091,0x0089,0x0085, 0x0083,0x88C9,0x88C8,0x0083,0x88C7,0x88C6,0x0085,0x0083,0xDBFB,0x88C5,0x0083,0xDCA4,0x88C4,0x0089,0x0085,0x0083, 0x88C3,0x88C2,0x0083,0x88C1,0x88C0,0x0085,0x0083,0x88BF,0x88BE,0x0083,0x88BD,0xDBFD,0x0101,0x00C1,0x00A1,0x0091, 0x0089,0x0085,0x0083,0x88BC,0x88BB,0x0083,0x88BA,0xB2BA,0x0085,0x0083,0xD3F2,0x88B9,0x0083,0xDBFE,0x88B8,0x0089, 0x0085,0x0083,0x88B7,0xDBF6,0x0083,0xDBF7,0xDBF5,0x0085,0x0083,0x88B6,0x88B5,0x0083,0xDBF4,0xC6D2,0x0091,0x0089, 0x0085,0x0083,0x88B4,0xDBF8,0x0083,0x88B3,0x88B2,0x0085,0x0083,0xDBEF,0xB3C7,0x0083,0x88B1,0x88B0,0x0089,0x0085, 0x0083,0xC2F1,0x88AF,0x0083,0x88AE,0x88AD,0x0085,0x0083,0x88AC,0x88AB,0x0083,0x88AA,0x88A9,0x00A1,0x0091,0x0089, 0x0085,0x0083,0xB0A3,0xB9A1,0x0083,0x88A8,0x88A7,0x0085,0x0083,0x88A6,0x88A5,0x0083,0x88A4,0x88A3,0x0089,0x0085, 0x0083,0x88A2,0x88A1,0x0083,0x88A0,0xDBF9,0x0085,0x0083,0x889F,0x889E,0x0083,0x889D,0xDBF1,0x0091,0x0089,0x0085, 0x0083,0x889C,0xDBEE,0x0083,0x889B,0x889A,0x0085,0x0083,0x8899,0xBFE5,0x0083,0xDBEB,0x8898,0x0089,0x0085,0x0083, 0xB5E6,0x8897,0x0083,0xDBD1,0x8896,0x0085,0x0083,0xDBF0,0xBFD1,0x0083,0x8895,0xDBEC,0x00C1,0x00A1,0x0091,0x0089, 0x0085,0x0083,0xD4AB,0xB9B8,0x0083,0xDBD2,0xDBF3,0x0085,0x0083,0x8894,0x8893,0x0083,0x8892,0x8891,0x0089,0x0085, 0x0083,0xB6E2,0x8890,0x0083,0x888F,0x888E,0x0085,0x0083,0x888D,0x888C,0x0083,0x888B,0x888A,0x0091,0x0089,0x0085, 0x0083,0xDBF2,0xC0DD,0x0083,0x8889,0x8888,0x0085,0x0083,0x8887,0x8886,0x0083,0x8885,0xDBED,0x0089,0x0085,0x0083, 0xD0CD,0x8884,0x0083,0x8883,0x8882,0x0085,0x0083,0x8881,0xDBE4,0x0083,0xDBE2,0xC2A2,0x00A1,0x0091,0x0089,0x0085, 0x0083,0xC0AC,0xB4B9,0x0083,0x8880,0x887E,0x0085,0x0083,0x887D,0x887C,0x0083,0x887B,0xDBE5,0x0089,0x0085,0x0083, 0xDBE6,0x887A,0x0083,0x8879,0x8878,0x0085,0x0083,0xBFC0,0xDBE9,0x0083,0x8877,0x8876,0x0091,0x0089,0x0085,0x0083, 0xDBEA,0x8875,0x0083,0x8874,0x8873,0x0085,0x0083,0xC5F7,0x8872,0x0083,0xDBE8,0x8871,0x0089,0x0085,0x0083,0xDBE3, 0xC6BA,0x0083,0xDBE1,0xDBE7,0x0085,0x0083,0x8870,0xCCB9,0x0083,0x886F,0xC0A4,0x017F,0x00FF,0x00BF,0x009F,0x008F, 0x0087,0x0083,0x886E,0x0083,0x886D,0xC6C2,0x0085,0x0083,0xD7B9,0xB7D8,0x0083,0xCEEB,0xB0D3,0x0089,0x0085,0x0083, 0xDBDE,0xCCB3,0x0083,0xBCE1,0x886C,0x0085,0x0083,0x886B,0xBFE9,0x0083,0x886A,0x8869,0x0091,0x0089,0x0085,0x0083, 0x8868,0x8867,0x0083,0x8866,0xBFD3,0x0085,0x0083,0xD7F8,0xBBB5,0x0083,0xBFB2,0xCCAE,0x0089,0x0085,0x0083,0xDBD0, 0x8865,0x0083,0xB7BB,0x8864,0x0085,0x0083,0x8863,0xBEF9,0x0083,0x8862,0x8861,0x00A1,0x0091,0x0089,0x0085,0x0083, 0x8860,0x885F,0x0083,0xDBE0,0x885E,0x0085,0x0083,0xD6B7,0x885D,0x0083,0xBBF8,0x885C,0x0089,0x0085,0x0083,0x885B, 0xDBDF,0x0083,0xB3A1,0xDBDB,0x0085,0x0083,0x885A,0x8859,0x0083,0x8858,0x8857,0x0091,0x0089,0x0085,0x0083,0x8856, 0xDBDA,0x0083,0x8855,0x8854,0x0085,0x0083,0xB5D8,0xDBDD,0x0083,0xDBDC,0xB9E7,0x0089,0x0085,0x0083,0xDBD8,0x8853, 0x0083,0xDBD9,0xDBD7,0x0085,0x0083,0xD4DA,0x8852,0x0083,0x8851,0x8850,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083, 0x884F,0xCAA5,0x0083,0x884E,0x884D,0x0085,0x0083,0x884C,0xCDC1,0x0083,0x884B,0x884A,0x0089,0x0085,0x0083,0xE0F7, 0x8849,0x0083,0x8848,0x8847,0x0085,0x0083,0x8846,0x8845,0x0083,0x8844,0x8843,0x0091,0x0089,0x0085,0x0083,0x8842, 0x8841,0x0083,0x8840,0x87FE,0x0085,0x0083,0x87FD,0x87FC,0x0083,0x87FB,0x87FA,0x0089,0x0085,0x0083,0x87F9,0x87F8, 0x0083,0xE0F5,0xE0F6,0x0085,0x0083,0xC8A6,0x87F7,0x0083,0xD4B2,0x87F6,0x00A1,0x0091,0x0089,0x0085,0x0083,0xE0F4, 0xC6D4,0x0083,0x87F5,0x87F4,0x0085,0x0083,0x87F3,0xE0F3,0x0083,0xCDBC,0xB9FA,0x0089,0x0085,0x0083,0x87F2,0x87F1, 0x0083,0xB9CC,0xE0F2,0x0085,0x0083,0x87F0,0x87EF,0x0083,0x87EE,0xE0F0,0x0091,0x0089,0x0085,0x0083,0xCEA7,0x87ED, 0x0083,0x87EC,0xB4D1,0x0085,0x0083,0xC0A7,0x87EB,0x0083,0x87EA,0xD4B0,0x0089,0x0085,0x0083,0x87E9,0xE0F1,0x0083, 0x87E8,0x87E7,0x0085,0x0083,0x87E6,0x87E5,0x0083,0x87E4,0x87E3,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083, 0xB6DA,0x87E2,0x0083,0xCDC5,0xE0EF,0x0085,0x0083,0xD2F2,0xD8B6,0x0083,0xBBD8,0xE0EE,0x0089,0x0085,0x0083,0x87E1, 0xCBC4,0x0083,0xC7F4,0x87E0,0x0085,0x0083,0x87DF,0xE0ED,0x0083,0x87DE,0x87DD,0x0091,0x0089,0x0085,0x0083,0xE0EC, 0x87DC,0x0083,0x87DB,0x87DA,0x0085,0x0083,0x87D9,0x87D8,0x0083,0x87D7,0x87D6,0x0089,0x0085,0x0083,0x87D5,0x87D4, 0x0083,0xC4D2,0x87D3,0x0085,0x0083,0x87D2,0x87D1,0x0083,0x87D0,0x87CF,0x00A1,0x0091,0x0089,0x0085,0x0083,0x87CE, 0x87CD,0x0083,0x87CC,0x87CB,0x0085,0x0083,0x87CA,0x87C9,0x0083,0x87C8,0x87C7,0x0089,0x0085,0x0083,0xBDC0,0x87C6, 0x0083,0x87C5,0x87C4,0x0085,0x0083,0x87C3,0xC8C2,0x0083,0x87C2,0x87C1,0x0091,0x0089,0x0085,0x0083,0x87C0,0x87BF, 0x0083,0x87BE,0x87BD,0x0085,0x0083,0x87BC,0xE0EB,0x0083,0x87BB,0x87BA,0x0089,0x0085,0x0083,0x87B9,0x87B8,0x0083, 0x87B7,0x87B6,0x0085,0x0083,0x87B5,0x87B4,0x0083,0x87B3,0x87B2,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x87B1, 0xCFF9,0x0083,0x87B0,0x87AF,0x0085,0x0083,0x87AE,0x87AD,0x0083,0x87AC,0x87AB,0x0089,0x0085,0x0083,0x87AA,0x87A9, 0x0083,0x87A8,0x87A7,0x0085,0x0083,0x87A6,0x87A5,0x0083,0x87A4,0x87A3,0x0091,0x0089,0x0085,0x0083,0x87A2,0xE0EA, 0x0083,0x87A1,0x87A0,0x0085,0x0083,0x879F,0xCCE7,0x0083,0xBABF,0x879E,0x0089,0x0085,0x0083,0x879D,0x879C,0x0083, 0x879B,0x879A,0x0085,0x0083,0x8799,0x8798,0x0083,0xE0E3,0xE0E9,0x00A1,0x0091,0x0089,0x0085,0x0083,0x8797,0x8796, 0x0083,0x8795,0x8794,0x0085,0x0083,0x8793,0x8792,0x0083,0x8791,0x8790,0x0089,0x0085,0x0083,0xE0E8,0xE0E7,0x0083, 0x878F,0x878E,0x0085,0x0083,0x878D,0x878C,0x0083,0xB8C1,0x878B,0x0091,0x0089,0x0085,0x0083,0x878A,0x8789,0x0083, 0x8788,0xE0E5,0x0085,0x0083,0x8787,0x8786,0x0083,0x8785,0x8784,0x0089,0x0085,0x0083,0xCAC9,0xE0E6,0x0083,0xD4EB, 0xD8AC,0x0085,0x0083,0xC6F7,0x8783,0x0083,0x8782,0x8781,0x027F,0x017F,0x00FF,0x00BF,0x009F,0x008F,0x0087,0x0083, 0xE0E4,0x0083,0x8780,0xE0DE,0x0085,0x0083,0x877E,0x877D,0x0083,0x877C,0x877B,0x0089,0x0085,0x0083,0x877A,0xE0E0, 0x0083,0x8779,0x8778,0x0085,0x0083,0xE0DF,0xE0D9,0x0083,0xE0DB,0x8777,0x0091,0x0089,0x0085,0x0083,0x8776,0xE0E2, 0x0083,0x8775,0x8774,0x0085,0x0083,0x8773,0x8772,0x0083,0x8771,0xD2AD,0x0089,0x0085,0x0083,0xE0DD,0xE0E1,0x0083, 0x8770,0x876F,0x0085,0x0083,0x876E,0x876D,0x0083,0x876C,0x876B,0x00A1,0x0091,0x0089,0x0085,0x0083,0x876A,0x8769, 0x0083,0x8768,0x8767,0x0085,0x0083,0x8766,0x8765,0x0083,0xBAD9,0x8764,0x0089,0x0085,0x0083,0x8763,0x8762,0x0083, 0xCEFB,0x8761,0x0085,0x0083,0xE0DA,0x8760,0x0083,0x875F,0xCBBB,0x0091,0x0089,0x0085,0x0083,0x875E,0xD7EC,0x0083, 0x875D,0xB3B0,0x0085,0x0083,0xD6F6,0x875C,0x0083,0x875B,0x875A,0x0089,0x0085,0x0083,0xE0D8,0xE0DC,0x0083,0x8759, 0x8758,0x0085,0x0083,0x8757,0x8756,0x0083,0xE0D7,0x8755,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x8754,0xE0D3, 0x0083,0xE0D4,0x8753,0x0085,0x0083,0x8752,0x8751,0x0083,0xE0BD,0xE0CF,0x0089,0x0085,0x0083,0x8750,0x874F,0x0083, 0xC2EF,0x874E,0x0085,0x0083,0x874D,0xD0EA,0x0083,0x874C,0x874B,0x0091,0x0089,0x0085,0x0083,0x874A,0x8749,0x0083, 0x8748,0x8747,0x0085,0x0083,0x8746,0x8745,0x0083,0xD8C5,0xB8C2,0x0089,0x0085,0x0083,0x8744,0xE0D1,0x0083,0x8743, 0x8742,0x0085,0x0083,0xBCCE,0xE0D0,0x0083,0x8741,0x8740,0x00A1,0x0091,0x0089,0x0085,0x0083,0x86FE,0x86FD,0x0083, 0x86FC,0x86FB,0x0085,0x0083,0xE0D2,0xE0D6,0x0083,0x86FA,0xE0D5,0x0089,0x0085,0x0083,0xCBD4,0x86F9,0x0083,0x86F8, 0x86F7,0x0085,0x0083,0x86F6,0x86F5,0x0083,0xE0BB,0x86F4,0x0091,0x0089,0x0085,0x0083,0xE0CC,0x86F3,0x0083,0xE0C8, 0xE0C7,0x0085,0x0083,0x86F2,0x86F1,0x0083,0xE0C5,0x86F0,0x0089,0x0085,0x0083,0x86EF,0xE0C0,0x0083,0xE0BF,0xE0BA, 0x0085,0x0083,0x86EE,0xE0CB,0x0083,0x86ED,0xE0C2,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xE0C6,0xE0CD, 0x0083,0xCBC3,0x86EC,0x0085,0x0083,0xCECB,0x86EB,0x0083,0xE0B5,0x86EA,0x0089,0x0085,0x0083,0xE0C3,0xCAC8,0x0083, 0x86E9,0x86E8,0x0085,0x0083,0x86E7,0x86E6,0x0083,0x86E5,0xE0B2,0x0091,0x0089,0x0085,0x0083,0x86E4,0xE0C1,0x0083, 0xC9A4,0xE0AA,0x0085,0x0083,0xE0BE,0x86E3,0x0083,0x86E2,0x86E1,0x0089,0x0085,0x0083,0xE0CA,0xE0C9,0x0083,0x86E0, 0x86DF,0x0085,0x0083,0xE0BC,0x86DE,0x0083,0x86DD,0x86DC,0x00A1,0x0091,0x0089,0x0085,0x0083,0xD0E1,0xE0C4,0x0083, 0x86DB,0x86DA,0x0085,0x0083,0x86D9,0x86D8,0x0083,0x86D7,0xE0B7,0x0089,0x0085,0x0083,0xE0B6,0x86D6,0x0083,0xD3F7, 0x86D5,0x0085,0x0083,0xE0AD,0x86D4,0x0083,0xC5E7,0x86D3,0x0091,0x0089,0x0085,0x0083,0xDFF7,0x86D2,0x0083,0xD4FB, 0x86D1,0x0085,0x0083,0xE0AC,0x86D0,0x0083,0x86CF,0x86CE,0x0089,0x0085,0x0083,0x86CD,0x86CC,0x0083,0x86CB,0x86CA, 0x0085,0x0083,0x86C9,0x86C8,0x0083,0xD0FA,0x86C7,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x86C6,0x86C5,0x0083, 0x86C4,0x86C3,0x0085,0x0083,0x86C2,0x86C1,0x0083,0xE0B0,0x86C0,0x0089,0x0085,0x0083,0xBAC8,0xCFB2,0x0083,0x86BF, 0x86BE,0x0085,0x0083,0xE0B9,0xB4AD,0x0083,0x86BD,0x86BC,0x0091,0x0089,0x0085,0x0083,0x86BB,0xE0B8,0x0083,0x86BA, 0x86B9,0x0085,0x0083,0xE0B3,0x86B8,0x0083,0xDFF6,0x86B7,0x0089,0x0085,0x0083,0x86B6,0x86B5,0x0083,0xE0A9,0xBAB0, 0x0085,0x0083,0xBAED,0xE0AE,0x0083,0xC0AE,0x86B4,0x00A1,0x0091,0x0089,0x0085,0x0083,0x86B3,0xC9C6,0x0083,0xE0AB, 0xCEB9,0x0085,0x0083,0xE0AF,0xBFA6,0x0083,0x86B2,0xE0B1,0x0089,0x0085,0x0083,0x86B1,0xCCE4,0x0083,0xE0B4,0x86B0, 0x0085,0x0083,0x86AF,0xD0A5,0x0083,0xE0A5,0xE0A4,0x0091,0x0089,0x0085,0x0083,0xE0A3,0x86AE,0x0083,0x86AD,0x86AC, 0x0085,0x0083,0x86AB,0x86AA,0x0083,0x86A9,0xC4F6,0x0089,0x0085,0x0083,0xDFF9,0xD8C4,0x0083,0x86A8,0xC5BE,0x0085, 0x0083,0x86A7,0x86A6,0x0083,0xDFF5,0xC0B2,0x0181,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xC9B6,0xC6A1, 0x0083,0x86A5,0x86A4,0x0085,0x0083,0xB7C8,0x86A3,0x0083,0x86A2,0x86A1,0x0089,0x0085,0x0083,0x86A0,0xE0A8,0x0083, 0x869F,0x869E,0x0085,0x0083,0x869D,0x869C,0x0083,0x869B,0xE0A2,0x0091,0x0089,0x0085,0x0083,0xDFFB,0x869A,0x0083, 0x8699,0x8698,0x0085,0x0083,0x8697,0xDFFD,0x0083,0x8696,0x8695,0x0089,0x0085,0x0083,0x8694,0x8693,0x0083,0x8692, 0xB0A1,0x0085,0x0083,0xDFF8,0x8691,0x0083,0x8690,0xC9CC,0x00A1,0x0091,0x0089,0x0085,0x0083,0x868F,0xD7C4,0x0083, 0xBFD0,0x868E,0x0085,0x0083,0xDFFA,0x868D,0x0083,0xDFFC,0xCDD9,0x0089,0x0085,0x0083,0x868C,0xDFFE,0x0083,0x868B, 0x868A,0x0085,0x0083,0x8689,0x8688,0x0083,0xE0A1,0x8687,0x0091,0x0089,0x0085,0x0083,0x8686,0x8685,0x0083,0xE0A6, 0x8684,0x0085,0x0083,0xB3AA,0xE0A7,0x0083,0xCEA8,0xCADB,0x0089,0x0085,0x0083,0x8683,0xBBA3,0x0083,0x8682,0xDFF4, 0x0085,0x0083,0x8681,0x8680,0x0083,0xDFF3,0x867E,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x867D,0xBBBD,0x0083, 0xDFF0,0xDFEF,0x0085,0x0083,0x867C,0xDFEB,0x0083,0x867B,0x867A,0x0089,0x0085,0x0083,0x8679,0x8678,0x0083,0xDFE9, 0x8677,0x0085,0x0083,0x8676,0x8675,0x0083,0x8674,0x8673,0x0091,0x0089,0x0085,0x0083,0x8672,0xDFED,0x0083,0x8671, 0x8670,0x0085,0x0083,0xDFF2,0xCCC6,0x0083,0xDFF1,0x866F,0x0089,0x0085,0x0083,0x866E,0x866D,0x0083,0x866C,0x866B, 0x0085,0x0083,0xB0A6,0x866A,0x0083,0xB4BD,0xCBF4,0x00A1,0x0091,0x0089,0x0085,0x0083,0x8669,0x8668,0x0083,0x8667, 0x8666,0x0085,0x0083,0xD1E4,0x8665,0x0083,0xDBC1,0x8664,0x0089,0x0085,0x0083,0xDFEC,0xBADF,0x0083,0x8663,0xB2B8, 0x0085,0x0083,0x8662,0x8661,0x0083,0x8660,0x865F,0x0091,0x0089,0x0085,0x0083,0x865E,0x865D,0x0083,0xDFEE,0xD5DC, 0x0085,0x0083,0x865C,0x865B,0x0083,0x865A,0xCFF8,0x0089,0x0085,0x0083,0xBFDE,0x8659,0x0083,0x8658,0xC4C4,0x0085, 0x0083,0xC1A8,0xC9DA,0x0083,0xDFEA,0xC5B6,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xB8E7,0x8657,0x0083, 0x8656,0x8655,0x0085,0x0083,0x8654,0x8653,0x0083,0xD3B4,0xDFE8,0x0089,0x0085,0x0083,0xDFE6,0xDFE2,0x0083,0x8652, 0xDFE1,0x0085,0x0083,0xDFE0,0x8651,0x0083,0xBBA9,0x8650,0x0091,0x0089,0x0085,0x0083,0xDFDC,0xDFD9,0x0083,0xDFD8, 0xDFD5,0x0085,0x0083,0xD1C6,0xDFD1,0x0083,0xDFE7,0xB0A5,0x0089,0x0085,0x0083,0xCFEC,0xDFDF,0x0083,0x864F,0x864E, 0x0085,0x0083,0xD4D5,0xB9FE,0x0083,0xCDDB,0xB6DF,0x00A1,0x0091,0x0089,0x0085,0x0083,0x864D,0xBAE5,0x0083,0x864C, 0xDFD3,0x0085,0x0083,0xC6B7,0xB0A7,0x0083,0xDFDE,0x864B,0x0089,0x0085,0x0083,0xD1CA,0x864A,0x0083,0xDFDD,0x8649, 0x0085,0x0083,0x8648,0xCFCC,0x0083,0x8647,0x8646,0x0091,0x0089,0x0085,0x0083,0x8645,0xDFD4,0x0083,0xBFC8,0x8644, 0x0085,0x0083,0xD4DB,0x8643,0x0083,0xBFA9,0x8642,0x0089,0x0085,0x0083,0xDFD2,0xD2A7,0x0083,0xE5EB,0xDFE4,0x0085, 0x0083,0xDFE3,0xD7C9,0x0083,0xDFD6,0xDFD7,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x8641,0xDFE5,0x0083,0xDFDB, 0x8640,0x0085,0x0083,0x85FE,0x85FD,0x0083,0x85FC,0x85FB,0x0089,0x0085,0x0083,0xDFD0,0x85FA,0x0083,0xDFCC,0xDFCB, 0x0085,0x0083,0xC1FC,0x85F9,0x0083,0x85F8,0xBFA7,0x0091,0x0089,0x0085,0x0083,0xB9BE,0xDFC7,0x0083,0x85F7,0xD6E4, 0x0085,0x0083,0x85F6,0xB8C0,0x0083,0xD3BD,0xBECC,0x0089,0x0085,0x0083,0x85F5,0xBACD,0x0083,0xD5A6,0x85F4,0x0085, 0x0083,0x85F3,0x85F2,0x0083,0x85F1,0xC5D8,0x00A1,0x0091,0x0089,0x0085,0x0083,0x85F0,0xDFCD,0x0083,0x85EF,0xDFC6, 0x0085,0x0083,0x85EE,0xBED7,0x0083,0x85ED,0x85EC,0x0089,0x0085,0x0083,0xC3FC,0xBAF4,0x0083,0xC9EB,0x85EB,0x0085, 0x0083,0x85EA,0xC5DE,0x0083,0xDFC8,0xDFCE,0x0091,0x0089,0x0085,0x0083,0xBAC7,0x85E9,0x0083,0xCEB6,0xDFDA,0x0085, 0x0083,0xDFC9,0x85E8,0x0083,0x85E7,0x85E6,0x0089,0x0085,0x0083,0x85E5,0x85E4,0x0083,0x85E3,0x85E2,0x0085,0x0083, 0x85E1,0xD6DC,0x0083,0x85E0,0xDFCF,0x047D,0x027F,0x017F,0x00FF,0x00BF,0x009F,0x008F,0x0087,0x0083,0x85DF,0x0083, 0xDFCA,0x85DE,0x0085,0x0083,0xC4D8,0x85DD,0x0083,0x85DC,0x85DB,0x0089,0x0085,0x0083,0x85DA,0x85D9,0x0083,0xCED8, 0xC7BA,0x0085,0x0083,0x85D8,0xDFC3,0x0083,0xD4B1,0xDFC2,0x0091,0x0089,0x0085,0x0083,0xDFBF,0xC5BB,0x0083,0xDFBE, 0xDFBD,0x0085,0x0083,0xDFBC,0x85D7,0x0083,0xC4C5,0x85D6,0x0089,0x0085,0x0083,0x85D5,0x85D4,0x0083,0x85D3,0xDFBB, 0x0085,0x0083,0xB8E6,0x85D2,0x0083,0xB3CA,0x85D1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xB4F4,0x85D0,0x0083,0x85CF, 0xDFC0,0x0085,0x0083,0x85CE,0x85CD,0x0083,0xD1BD,0x85CC,0x0089,0x0085,0x0083,0xCEE1,0x85CB,0x0083,0xBAF0,0xCEC7, 0x0085,0x0083,0x85CA,0xB4B5,0x0083,0xCEFC,0x85C9,0x0091,0x0089,0x0085,0x0083,0x85C8,0xB3B3,0x0083,0xCEE2,0x85C7, 0x0085,0x0083,0xDFC5,0xD6A8,0x0083,0x85C6,0xC6F4,0x0089,0x0085,0x0083,0xCBB1,0xBFD4,0x0083,0xCCFD,0xBAAC,0x0085, 0x0083,0x85C5,0xB7D4,0x0083,0xB6D6,0xB0C9,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xB7F1,0x85C4,0x0083,0x85C3, 0xDFC4,0x0085,0x0083,0x85C2,0xDFC1,0x0083,0xB7CD,0xD2F7,0x0089,0x0085,0x0083,0xCDCC,0xC1DF,0x0083,0x85C1,0xBEFD, 0x0085,0x0083,0x85C0,0x85BF,0x0083,0x85BE,0xC2F0,0x0091,0x0089,0x0085,0x0083,0xDFB9,0xC2C0,0x0083,0x85BD,0xCFC5, 0x0085,0x0083,0xDFB8,0xCFF2,0x0083,0xCDC2,0xC0F4,0x0089,0x0085,0x0083,0xBAF3,0xC3FB,0x0083,0xCDAC,0x85BC,0x0085, 0x0083,0xB5F5,0xBCAA,0x0083,0xBACF,0x85BB,0x00A1,0x0091,0x0089,0x0085,0x0083,0xDFBA,0x85BA,0x0083,0xB8F7,0xB3D4, 0x0085,0x0083,0x85B9,0xD3F5,0x0083,0x85B8,0x85B7,0x0089,0x0085,0x0083,0x85B6,0xDFB4,0x0083,0xB5F0,0xDFB7,0x0085, 0x0083,0x85B5,0xCCBE,0x0083,0xCBBE,0xBAC5,0x0091,0x0089,0x0085,0x0083,0xD2B6,0xD8CF,0x0083,0x85B4,0xD3D2,0x0085, 0x0083,0xCAB7,0xDFB3,0x0083,0xCCA8,0xBFC9,0x0089,0x0085,0x0083,0xB6A3,0xB0C8,0x0083,0xD5D9,0xBDD0,0x0085,0x0083, 0xD6BB,0xDFB5,0x0083,0xDFB6,0x85B3,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xC1ED,0xBEE4,0x0083,0xB9C5, 0xBFDA,0x0085,0x0083,0x85B2,0x85B1,0x0083,0xB5FE,0xDBC5,0x0089,0x0085,0x0083,0x85B0,0x85AF,0x0083,0x85AE,0xC5D1, 0x0085,0x0083,0x85AD,0xD0F0,0x0083,0xB1E4,0xCADC,0x0091,0x0089,0x0085,0x0083,0xC8A1,0x85AC,0x0083,0xCAE5,0x85AB, 0x0085,0x0083,0x85AA,0xB7A2,0x0083,0x85A9,0x85A8,0x0089,0x0085,0x0083,0x85A7,0xB7B4,0x0083,0xCBAB,0xD3D1,0x0085, 0x0083,0xBCB0,0xB2E6,0x0083,0xD3D6,0x85A6,0x00A1,0x0091,0x0089,0x0085,0x0083,0x85A5,0x85A4,0x0083,0x85A3,0x85A2, 0x0085,0x0083,0xB2CE,0xC8FE,0x0083,0x85A1,0xCFD8,0x0089,0x0085,0x0083,0x85A0,0x859F,0x0083,0x859E,0xC8A5,0x0085, 0x0083,0x859D,0x859C,0x0083,0x859B,0x859A,0x0091,0x0089,0x0085,0x0083,0xDBCC,0x8599,0x0083,0x8598,0x8597,0x0085, 0x0083,0x8596,0x8595,0x0083,0x8594,0x8593,0x0089,0x0085,0x0083,0xD8CB,0x8592,0x0083,0x8591,0x8590,0x0085,0x0083, 0x858F,0xBEC7,0x0083,0xB3F8,0x858E,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xCFC3,0xD8CA,0x0083,0x858D,0xD8C9, 0x0085,0x0083,0xCFE1,0x858C,0x0083,0x858B,0xD4AD,0x0089,0x0085,0x0083,0x858A,0xD8C8,0x0083,0x8589,0x8588,0x0085, 0x0083,0xBAF1,0x8587,0x0083,0xC0E5,0x8586,0x0091,0x0089,0x0085,0x0083,0x8585,0xB2DE,0x0083,0x8584,0x8583,0x0085, 0x0083,0x8582,0x8581,0x0083,0x8580,0x857E,0x0089,0x0085,0x0083,0x857D,0xD8C7,0x0083,0xD1E1,0xD1B9,0x0085,0x0083, 0x857C,0xC0F7,0x0083,0x857B,0x857A,0x00A1,0x0091,0x0089,0x0085,0x0083,0xC0FA,0xCCFC,0x0083,0xB6F2,0x8579,0x0085, 0x0083,0xB3A7,0x8578,0x0083,0x8577,0xC7E4,0x0089,0x0085,0x0083,0x8576,0x8575,0x0083,0x8574,0x8573,0x0085,0x0083, 0xDAE1,0x8572,0x0083,0xD0B6,0xBEED,0x0091,0x0089,0x0085,0x0083,0x8571,0xC2D1,0x0083,0xC8B4,0xBCB4,0x0085,0x0083, 0x8570,0xCEA3,0x0083,0xD3A1,0xC3AE,0x0089,0x0085,0x0083,0xD8B4,0x856F,0x0083,0x856E,0xCEC0,0x0085,0x0083,0x856D, 0xDAE0,0x0083,0x856C,0xCED4,0x017F,0x00FF,0x00BF,0x009F,0x008F,0x0087,0x0083,0xD8D4,0x0083,0x856B,0xC2B1,0x0085, 0x0083,0xD8D5,0xC2AC,0x0083,0xBFA8,0xD5BC,0x0089,0x0085,0x0083,0xDFB2,0xB1E5,0x0083,0x856A,0xB2B7,0x0085,0x0083, 0x8569,0xB2A9,0x0083,0x8568,0x8567,0x0091,0x0089,0x0085,0x0083,0xC4CF,0xC2F4,0x0083,0xB5A5,0x8566,0x0085,0x0083, 0xD7BF,0xD7E4,0x0083,0xB1B0,0x8565,0x0089,0x0085,0x0083,0xD0AD,0xBBAA,0x0083,0x8564,0x8563,0x0085,0x0083,0x8562, 0xB0EB,0x0083,0xBBDC,0xCEE7,0x00A1,0x0091,0x0089,0x0085,0x0083,0xC9FD,0x8561,0x0083,0xD8A6,0x8560,0x0085,0x0083, 0xC7A7,0x855F,0x0083,0xCAAE,0x855E,0x0089,0x0085,0x0083,0xC4E4,0xD8D2,0x0083,0x855D,0x855C,0x0085,0x0083,0xD2BD, 0xC7F8,0x0083,0xC6A5,0x855B,0x0091,0x0089,0x0085,0x0083,0x855A,0x8559,0x0083,0x8558,0x8557,0x0085,0x0083,0x8556, 0x8555,0x0083,0x8554,0x8553,0x0089,0x0085,0x0083,0x8552,0xD8D1,0x0083,0x8551,0x8550,0x0085,0x0083,0x854F,0xB7CB, 0x0083,0x854E,0x854D,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x854C,0xD8D0,0x0083,0x854B,0x854A,0x0085,0x0083, 0xCFBB,0x8549,0x0083,0xBFEF,0xBDB3,0x0089,0x0085,0x0083,0x8548,0x8547,0x0083,0xD4D1,0x8546,0x0085,0x0083,0x8545, 0xD8CE,0x0083,0xB3D7,0x8544,0x0091,0x0089,0x0085,0x0083,0xB1B1,0xBBAF,0x0083,0xD8B0,0x8543,0x0085,0x0083,0x8542, 0x8541,0x0083,0x8540,0xD9EB,0x0089,0x0085,0x0083,0xDECB,0x84FE,0x0083,0xD9E9,0x84FD,0x0085,0x0083,0x84FC,0x84FB, 0x0083,0x84FA,0xD0D9,0x00A1,0x0091,0x0089,0x0085,0x0083,0x84F9,0xB4D2,0x0083,0xB0FC,0x84F8,0x0085,0x0083,0x84F7, 0x84F6,0x0083,0x84F5,0xD4C8,0x0089,0x0085,0x0083,0xCEF0,0xB9B4,0x0083,0x84F4,0x84F3,0x0085,0x0083,0x84F2,0xC9D7, 0x0083,0xD9E8,0x84F1,0x0091,0x0089,0x0085,0x0083,0x84F0,0x84EF,0x0083,0x84EE,0x84ED,0x0085,0x0083,0x84EC,0x84EB, 0x0083,0x84EA,0xDBC4,0x0089,0x0085,0x0083,0x84E9,0x84E8,0x0083,0x84E7,0x84E6,0x0085,0x0083,0x84E5,0x84E4,0x0083, 0x84E3,0x84E2,0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x84E1,0x84E0,0x0083,0x84DF,0xC7DA,0x0085,0x0083, 0x84DE,0x84DD,0x0083,0x84DC,0x84DB,0x0089,0x0085,0x0083,0xC4BC,0x84DA,0x0083,0x84D9,0x84D8,0x0085,0x0083,0x84D7, 0x84D6,0x0083,0x84D5,0xBFB1,0x0091,0x0089,0x0085,0x0083,0x84D4,0xDBC3,0x0083,0x84D3,0x84D2,0x0085,0x0083,0x84D1, 0xC0D5,0x0083,0x84D0,0xDBC2,0x0089,0x0085,0x0083,0x84CF,0x84CE,0x0083,0x84CD,0x84CC,0x0085,0x0083,0xD1AB,0x84CB, 0x0083,0xC3E3,0x84CA,0x00A1,0x0091,0x0089,0x0085,0x0083,0xD3C2,0x84C9,0x0083,0x84C8,0x84C7,0x0085,0x0083,0xB2AA, 0x84C6,0x0083,0x84C5,0x84C4,0x0089,0x0085,0x0083,0xCAC6,0xDBC0,0x0083,0x84C3,0x84C2,0x0085,0x0083,0x84C1,0x84C0, 0x0083,0x84BF,0x84BE,0x0091,0x0089,0x0085,0x0083,0x84BD,0x84BC,0x0083,0x84BB,0x84BA,0x0085,0x0083,0xC0CD,0xBEA2, 0x0083,0xC0F8,0x84B9,0x0089,0x0085,0x0083,0x84B8,0x84B7,0x0083,0xDBBF,0xDBBE,0x0085,0x0083,0xBDD9,0xC5AC,0x0083, 0xD6FA,0xB6AF,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x84B6,0x84B5,0x0083,0x84B4,0x84B3,0x0085,0x0083,0xC1D3, 0xDBBD,0x0083,0xCEF1,0xBCD3,0x0089,0x0085,0x0083,0xB9A6,0xB0EC,0x0083,0xC8B0,0x84B2,0x0085,0x0083,0xC1A6,0x84B1, 0x0083,0x84B0,0x84AF,0x0091,0x0089,0x0085,0x0083,0x84AE,0x84AD,0x0083,0x84AC,0x84AB,0x0085,0x0083,0xD8E6,0x84AA, 0x0083,0x84A9,0xD8E5,0x0089,0x0085,0x0083,0x84A8,0x84A7,0x0083,0x84A6,0x84A5,0x0085,0x0083,0x84A4,0x84A3,0x0083, 0x84A2,0xC5FC,0x00A1,0x0091,0x0089,0x0085,0x0083,0x84A1,0x84A0,0x0083,0x849F,0x849E,0x0085,0x0083,0x849D,0xD8E3, 0x0083,0xD8E4,0x849C,0x0089,0x0085,0x0083,0xBDCB,0x849B,0x0083,0xD8E2,0x849A,0x0085,0x0083,0x8499,0x8498,0x0083, 0x8497,0x8496,0x0091,0x0089,0x0085,0x0083,0x8495,0x8494,0x0083,0x8493,0x8492,0x0085,0x0083,0x8491,0xB8EE,0x0083, 0x8490,0x848F,0x0089,0x0085,0x0083,0xB8B1,0x848E,0x0083,0x848D,0x848C,0x0085,0x0083,0x848B,0xBCF4,0x0083,0xCAA3, 0x848A,0x027F,0x017F,0x00FF,0x00BF,0x009F,0x008F,0x0087,0x0083,0xBEE7,0x0083,0x8489,0xB0FE,0x0085,0x0083,0x8488, 0x8487,0x0083,0x8486,0xD8DF,0x0089,0x0085,0x0083,0x8485,0x8484,0x0083,0xD8DE,0x8483,0x0085,0x0083,0xD8E0,0x8482, 0x0083,0x8481,0x8480,0x0091,0x0089,0x0085,0x0083,0x847E,0x847D,0x0083,0xC6CA,0x847C,0x0085,0x0083,0xCCDE,0x847B, 0x0083,0x847A,0xBDA3,0x0089,0x0085,0x0083,0xB9D0,0x8479,0x0083,0x8478,0xC7B0,0x0085,0x0083,0xD8DD,0x8477,0x0083, 0xCFF7,0x8476,0x00A1,0x0091,0x0089,0x0085,0x0083,0x8475,0x8474,0x0083,0x8473,0x8472,0x0085,0x0083,0x8471,0xCCEA, 0x0083,0xBCC1,0xB6E7,0x0089,0x0085,0x0083,0xD8DC,0xD8DB,0x0083,0x8470,0xB9F4,0x0085,0x0083,0x846F,0xBFCC,0x0083, 0xB4CC,0xC9B2,0x0091,0x0089,0x0085,0x0083,0xC8AF,0xCBA2,0x0083,0xD6C6,0x846E,0x0085,0x0083,0x846D,0xD8DA,0x0083, 0x846C,0x846B,0x0089,0x0085,0x0083,0xB5BD,0x846A,0x0083,0xB9CE,0xD8D9,0x0085,0x0083,0x8469,0xB1F0,0x0083,0x8468, 0xC0FB,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xC5D9,0x8467,0x0083,0x8466,0x8465,0x0085,0x0083,0xC5D0,0x8464, 0x0083,0x8463,0x8462,0x0089,0x0085,0x0083,0xC9BE,0x8461,0x0083,0x8460,0xB3F5,0x0085,0x0083,0x845F,0xB4B4,0x0083, 0xB8D5,0xD4F2,0x0091,0x0089,0x0085,0x0083,0xC1F5,0xC1D0,0x0083,0xEBBE,0x845E,0x0085,0x0083,0x845D,0x845C,0x0083, 0xBBAE,0xD0CC,0x0089,0x0085,0x0083,0x845B,0x845A,0x0083,0xD8D8,0xDBBB,0x0085,0x0083,0x8459,0x8458,0x0083,0xBFAF, 0x8457,0x00A1,0x0091,0x0089,0x0085,0x0083,0xD8D7,0xC7D0,0x0083,0xB7D6,0x8456,0x0085,0x0083,0x8455,0xC8D0,0x0083, 0xD8D6,0xB5F3,0x0089,0x0085,0x0083,0xB5B6,0xD4E4,0x0083,0x8454,0xBAAF,0x0085,0x0083,0xDBCA,0xBBF7,0x0083,0xB3F6, 0xB0BC,0x0091,0x0089,0x0085,0x0083,0xCDB9,0x8453,0x0083,0xD0D7,0xDBC9,0x0085,0x0083,0x8452,0xB5CA,0x0083,0x8451, 0x8450,0x0089,0x0085,0x0083,0xBBCB,0xBFAD,0x0083,0x844F,0xC6BE,0x0085,0x0083,0x844E,0xD9EC,0x0083,0x844D,0x844C, 0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x844B,0x844A,0x0083,0x8449,0x8448,0x0085,0x0083,0xB7EF,0x8447, 0x0083,0x8446,0xB7B2,0x0089,0x0085,0x0083,0xBCB8,0x8445,0x0083,0x8444,0xC4FD,0x0085,0x0083,0x8443,0xC1DD,0x0083, 0x8442,0x8441,0x0091,0x0089,0x0085,0x0083,0x8440,0x83FE,0x0083,0x83FD,0x83FC,0x0085,0x0083,0x83FB,0x83FA,0x0083, 0x83F9,0xB4D5,0x0089,0x0085,0x0083,0x83F8,0xBCF5,0x0083,0x83F7,0x83F6,0x0085,0x0083,0xC1E8,0xB5F2,0x0083,0x83F5, 0xC1B9,0x00A1,0x0091,0x0089,0x0085,0x0083,0x83F4,0xDAA1,0x0083,0xD7BC,0x83F3,0x0085,0x0083,0xC6E0,0x83F2,0x0083, 0x83F1,0x83F0,0x0089,0x0085,0x0083,0xBEBB,0x83EF,0x0083,0x83EE,0xD9FD,0x0085,0x0083,0xD9FE,0xB6B3,0x0083,0x83ED, 0x83EC,0x0091,0x0089,0x0085,0x0083,0x83EB,0xC0E4,0x0083,0xD2B1,0xBFF6,0x0085,0x0083,0x83EA,0xBEF6,0x0083,0xB3E5, 0xD9FC,0x0089,0x0085,0x0083,0xB1F9,0xB7EB,0x0083,0x83E9,0x83E8,0x0085,0x0083,0xB6AC,0xD9FB,0x0083,0x83E7,0x83E6, 0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x83E5,0x83E4,0x0083,0x83E3,0xDAA4,0x0085,0x0083,0xD4A9,0x83E2,0x0083, 0xDAA3,0x83E1,0x0089,0x0085,0x0083,0xB9DA,0x83E0,0x0083,0x83DF,0x83DE,0x0085,0x0083,0xC5A9,0xBEFC,0x0083,0x83DD, 0xD0B4,0x0091,0x0089,0x0085,0x0083,0x83DC,0xC8DF,0x0083,0xDAA2,0xC3E1,0x0085,0x0083,0x83DB,0x83DA,0x0083,0xC3B0, 0x83D9,0x0089,0x0085,0x0083,0x83D8,0x83D7,0x0083,0x83D6,0xD4D9,0x0085,0x0083,0xB2E1,0x83D5,0x0083,0x83D4,0xC8BD, 0x00A1,0x0091,0x0089,0x0085,0x0083,0xB8D4,0x83D3,0x0083,0x83D2,0xC4DA,0x0085,0x0083,0x83D1,0x83D0,0x0083,0xD8E7, 0xD9E6,0x0089,0x0085,0x0083,0xBCBD,0x83CF,0x0083,0x83CE,0xCADE,0x0085,0x0083,0xBCE6,0xD1F8,0x0083,0x83CD,0xD7C8, 0x0091,0x0089,0x0085,0x0083,0xB5E4,0xBEDF,0x0083,0xC6E4,0xB1F8,0x0085,0x0083,0xD0CB,0xB9D8,0x0083,0x83CC,0xB9B2, 0x0089,0x0085,0x0083,0xC0BC,0x83CB,0x0083,0xD9E2,0xC1F9,0x0085,0x0083,0xB9AB,0xB0CB,0x0083,0x83CA,0x83C9,0x0181, 0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xC8AB,0x83C8,0x0083,0x83C7,0xC8EB,0x0085,0x0083,0x83C6,0x83C5, 0x0083,0xBEA4,0x83C4,0x0089,0x0085,0x0083,0x83C3,0x83C2,0x0083,0x83C1,0x83C0,0x0085,0x0083,0xB6B5,0x83BF,0x0083, 0xB5B3,0x83BE,0x0091,0x0089,0x0085,0x0083,0x83BD,0x83BC,0x0083,0xD9F0,0xD9EE,0x0085,0x0083,0xCDC3,0x83BB,0x0083, 0x83BA,0xB6D2,0x0089,0x0085,0x0083,0x83B9,0x83B8,0x0083,0x83B7,0xC3E2,0x0085,0x0083,0x83B6,0xBFCB,0x0083,0x83B5, 0xB9E2,0x00A1,0x0091,0x0089,0x0085,0x0083,0xCFC8,0x83B4,0x0083,0xD5D7,0xB3E4,0x0085,0x0083,0xD0D6,0xD4AA,0x0083, 0x83B3,0xD4CA,0x0089,0x0085,0x0083,0xD8A3,0xB6F9,0x0083,0x83B2,0x83B1,0x0085,0x0083,0x83B0,0x83AF,0x0083,0x83AE, 0x83AD,0x0091,0x0089,0x0085,0x0083,0x83AC,0x83AB,0x0083,0x83AA,0x83A9,0x0085,0x0083,0x83A8,0x83A7,0x0083,0x83A6, 0x83A5,0x0089,0x0085,0x0083,0x83A4,0x83A3,0x0083,0x83A2,0x83A1,0x0085,0x0083,0x83A0,0x839F,0x0083,0x839E,0x839D, 0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x839C,0x839B,0x0083,0x839A,0x8399,0x0085,0x0083,0x8398,0x8397,0x0083, 0x8396,0xC0DC,0x0089,0x0085,0x0083,0x8395,0x8394,0x0083,0x8393,0x8392,0x0085,0x0083,0x8391,0x8390,0x0083,0x838F, 0x838E,0x0091,0x0089,0x0085,0x0083,0x838D,0x838C,0x0083,0x838B,0x838A,0x0085,0x0083,0x8389,0x8388,0x0083,0xC8E5, 0x8387,0x0089,0x0085,0x0083,0x8386,0x8385,0x0083,0x8384,0x8383,0x0085,0x0083,0x8382,0xD9D9,0x0083,0x8381,0x8380, 0x00A1,0x0091,0x0089,0x0085,0x0083,0x837E,0xD9D8,0x0083,0xD9D3,0x837D,0x0085,0x0083,0x837C,0x837B,0x0083,0x837A, 0x8379,0x0089,0x0085,0x0083,0x8378,0x8377,0x0083,0x8376,0x8375,0x0085,0x0083,0x8374,0xC6A7,0x0083,0x8373,0x8372, 0x0091,0x0089,0x0085,0x0083,0x8371,0x8370,0x0083,0x836F,0xBDA9,0x0085,0x0083,0x836E,0xCBDB,0x0083,0x836D,0x836C, 0x0089,0x0085,0x0083,0x836B,0x836A,0x0083,0xD9D7,0xD9D4,0x0085,0x0083,0xD9D5,0x8369,0x0083,0x8368,0x8367,0x0101, 0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x8366,0xC9AE,0x0083,0xD9D6,0x8365,0x0085,0x0083,0x8364,0x8363,0x0083, 0x8362,0x8361,0x0089,0x0085,0x0083,0x8360,0x835F,0x0083,0x835E,0x835D,0x0085,0x0083,0x835C,0x835B,0x0083,0xC1C5, 0x835A,0x0091,0x0089,0x0085,0x0083,0x8359,0x8358,0x0083,0xD9D2,0x8357,0x0085,0x0083,0x8356,0x8355,0x0083,0x8354, 0x8353,0x0089,0x0085,0x0083,0x8352,0xCFF1,0x0083,0x8351,0x8350,0x0085,0x0083,0x834F,0x834E,0x0083,0x834D,0x834C, 0x00A1,0x0091,0x0089,0x0085,0x0083,0x834B,0x834A,0x0083,0x8349,0x8348,0x0085,0x0083,0x8347,0x8346,0x0083,0x8345, 0x8344,0x0089,0x0085,0x0083,0x8343,0x8342,0x0083,0x8341,0x8340,0x0085,0x0083,0x82FE,0xC9B5,0x0083,0xD9D1,0x82FD, 0x0091,0x0089,0x0085,0x0083,0x82FC,0x82FB,0x0083,0x82FA,0x82F9,0x0085,0x0083,0x82F8,0x82F7,0x0083,0xB0C1,0x82F6, 0x0089,0x0085,0x0083,0x82F5,0x82F4,0x0083,0x82F3,0x82F2,0x0085,0x0083,0xB4DF,0x82F1,0x0083,0x82F0,0xD9D0,0x00C1, 0x00A1,0x0091,0x0089,0x0085,0x0083,0xB4A2,0xD9CF,0x0083,0x82EF,0xD9CE,0x0085,0x0083,0x82EE,0xB4F6,0x0083,0x82ED, 0x82EC,0x0089,0x0085,0x0083,0x82EB,0x82EA,0x0083,0x82E9,0x82E8,0x0085,0x0083,0x82E7,0x82E6,0x0083,0x82E5,0x82E4, 0x0091,0x0089,0x0085,0x0083,0x82E3,0x82E2,0x0083,0x82E1,0x82E0,0x0085,0x0083,0x82DF,0x82DE,0x0083,0x82DD,0x82DC, 0x0089,0x0085,0x0083,0x82DB,0x82DA,0x0083,0x82D9,0xB0F8,0x0085,0x0083,0x82D8,0x82D7,0x0083,0x82D6,0x82D5,0x00A1, 0x0091,0x0089,0x0085,0x0083,0xC0FC,0x82D4,0x0083,0x82D3,0xB8B5,0x0085,0x0083,0x82D2,0x82D1,0x0083,0x82D0,0x82CF, 0x0089,0x0085,0x0083,0xBFFE,0xB3A5,0x0083,0xD9C7,0x82CE,0x0085,0x0083,0x82CD,0xD9CD,0x0083,0x82CC,0x82CB,0x0091, 0x0089,0x0085,0x0083,0x82CA,0xCDB5,0x0083,0xC5BC,0x82C9,0x0085,0x0083,0x82C8,0x82C7,0x0083,0x82C6,0x82C5,0x0089, 0x0085,0x0083,0x82C4,0x82C3,0x0083,0x82C2,0x82C1,0x0085,0x0083,0xD9CC,0x82C0,0x0083,0x82BF,0x82BE,0x0081,0x0081, 0x047D,0x027F,0x017F,0x00FF,0x00BF,0x009F,0x008F,0x0087,0x0083,0x82BD,0x0083,0x82BC,0x82BB,0x0085,0x0083,0xBDA1, 0x82BA,0x0083,0x82B9,0x82B8,0x0089,0x0085,0x0083,0x82B7,0x82B6,0x0083,0x82B5,0x82B4,0x0085,0x0083,0x82B3,0xCDA3, 0x0083,0x82B2,0xD7F6,0x0091,0x0089,0x0085,0x0083,0x82B1,0x82B0,0x0083,0x82AF,0x82AE,0x0085,0x0083,0xD9C9,0x82AD, 0x0083,0x82AC,0x82AB,0x0089,0x0085,0x0083,0x82AA,0x82A9,0x0083,0xC6AB,0xD9CB,0x0085,0x0083,0x82A8,0xD9BC,0x0083, 0x82A7,0x82A6,0x00A1,0x0091,0x0089,0x0085,0x0083,0x82A5,0xD9CA,0x0083,0xBCD9,0x82A4,0x0085,0x0083,0x82A3,0x82A2, 0x0083,0xD9C8,0x82A1,0x0089,0x0085,0x0083,0x82A0,0x829F,0x0083,0x829E,0xC7E3,0x0085,0x0083,0x829D,0xD6B5,0x0083, 0x829C,0xD5AE,0x0091,0x0089,0x0085,0x0083,0x829B,0x829A,0x0083,0x8299,0x8298,0x0085,0x0083,0x8297,0x8296,0x0083, 0x8295,0x8294,0x0089,0x0085,0x0083,0x8293,0x8292,0x0083,0x8291,0xD9C0,0x0085,0x0083,0xD9C1,0xD9BE,0x0083,0x8290, 0xC4DF,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xD9BB,0xD9C6,0x0083,0x828F,0xBEEB,0x0085,0x0083,0xD9C5,0x828E, 0x0083,0x828D,0x828C,0x0089,0x0085,0x0083,0xB3AB,0x828B,0x0083,0xBDE8,0x828A,0x0085,0x0083,0x8289,0xD9C3,0x0083, 0x8288,0xD2D0,0x0091,0x0089,0x0085,0x0083,0xBAF2,0xCCC8,0x0083,0x8287,0x8286,0x0085,0x0083,0x8285,0xBEF3,0x0083, 0x8284,0xB5B9,0x0089,0x0085,0x0083,0x8283,0x8282,0x0083,0xD9BF,0x8281,0x0085,0x0083,0xB1B6,0xD9C4,0x0083,0x8280, 0x827E,0x00A1,0x0091,0x0089,0x0085,0x0083,0x827D,0x827C,0x0083,0x827B,0x827A,0x0085,0x0083,0x8279,0x8278,0x0083, 0x8277,0x8276,0x0089,0x0085,0x0083,0x8275,0x8274,0x0083,0x8273,0xD9C2,0x0085,0x0083,0x8272,0x8271,0x0083,0x8270, 0xB0B3,0x0091,0x0089,0x0085,0x0083,0x826F,0xD9BA,0x0083,0x826E,0x826D,0x0085,0x0083,0x826C,0x826B,0x0083,0xD9BD, 0x826A,0x0089,0x0085,0x0083,0xBEE3,0x8269,0x0083,0xB8A9,0xD0DE,0x0085,0x0083,0xBCF3,0x8268,0x0083,0x8267,0xD9B3, 0x0101,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xC1A9,0xD9B2,0x0083,0x8266,0xD9B1,0x0085,0x0083,0x8265,0x8264, 0x0083,0xD9B6,0x8263,0x0089,0x0085,0x0083,0xD0C5,0x8262,0x0083,0xD9B9,0xD3E1,0x0085,0x0083,0xB1A3,0xD9B7,0x0083, 0x8261,0xD9B5,0x0091,0x0089,0x0085,0x0083,0x8260,0xB7FD,0x0083,0xCBD7,0x825F,0x0085,0x0083,0x825E,0x825D,0x0083, 0x825C,0x825B,0x0089,0x0085,0x0083,0xD9B8,0xC0FE,0x0083,0xC7CE,0xD9DE,0x0085,0x0083,0x825A,0x8259,0x0083,0x8258, 0xBFA1,0x00A1,0x0091,0x0089,0x0085,0x0083,0x8257,0x8256,0x0083,0x8255,0x8254,0x0085,0x0083,0xD9B4,0xB6ED,0x0083, 0xB4D9,0x8253,0x0089,0x0085,0x0083,0x8252,0x8251,0x0083,0xB1E3,0x8250,0x0085,0x0083,0x824F,0x824E,0x0083,0x824D, 0x824C,0x0091,0x0089,0x0085,0x0083,0x824B,0x824A,0x0083,0x8249,0x8248,0x0085,0x0083,0xC7D6,0x8247,0x0083,0x8246, 0x8245,0x0089,0x0085,0x0083,0x8244,0x8243,0x0083,0xBAEE,0xCEEA,0x0085,0x0083,0x8242,0xD9AF,0x0083,0x8241,0xD9AD, 0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083,0xBFEB,0xC7C8,0x0083,0xB2E0,0xD5EC,0x0085,0x0083,0xBDC4,0x8240,0x0083, 0xC2C2,0x81FE,0x0089,0x0085,0x0083,0x81FD,0xCFC0,0x0083,0x81FC,0x81FB,0x0085,0x0083,0xD2C0,0x81FA,0x0083,0xB9A9, 0x81F9,0x0091,0x0089,0x0085,0x0083,0x81F8,0x81F7,0x0083,0xB6B1,0x81F6,0x0085,0x0083,0x81F5,0xD9B0,0x0083,0x81F4, 0x81F3,0x0089,0x0085,0x0083,0xD9A7,0x81F2,0x0083,0xD9AA,0x81F1,0x0085,0x0083,0xCACC,0x81F0,0x0083,0xC0FD,0x81EF, 0x00A1,0x0091,0x0089,0x0085,0x0083,0xD9A8,0xB3DE,0x0083,0x81EE,0x81ED,0x0085,0x0083,0x81EC,0xD6B6,0x0083,0xD9A9, 0x81EB,0x0089,0x0085,0x0083,0x81EA,0x81E9,0x0083,0xCAB9,0xD9AB,0x0085,0x0083,0x81E8,0xD9AE,0x0083,0xD9AC,0x81E7, 0x0091,0x0089,0x0085,0x0083,0x81E6,0x81E5,0x0083,0x81E4,0xD9A5,0x0085,0x0083,0x81E3,0xD9A6,0x0083,0xBCD1,0x81E2, 0x0089,0x0085,0x0083,0x81E1,0xB0DB,0x0083,0xD1F0,0x81E0,0x0085,0x0083,0x81DF,0xC0D0,0x0083,0x81DE,0x81DD,0x017F, 0x00FF,0x00BF,0x009F,0x008F,0x0087,0x0083,0xC5E5,0x0083,0x81DC,0xD8FB,0x0085,0x0083,0x81DB,0xD9DD,0x0083,0xD8F4, 0xD3B6,0x0089,0x0085,0x0083,0x81DA,0x81D9,0x0083,0xC4E3,0xD9A1,0x0085,0x0083,0xD8FA,0xD8FE,0x0083,0xD7F7,0xB7F0, 0x0091,0x0089,0x0085,0x0083,0xD8FD,0xD3E0,0x0083,0xD9DC,0xD9A2,0x0085,0x0083,0x81D8,0xBACE,0x0083,0x81D7,0xCCE5, 0x0089,0x0085,0x0083,0x81D6,0xD3D3,0x0083,0xD7F4,0xD7A1,0x0085,0x0083,0xB5CD,0xCEBB,0x0083,0x81D5,0x81D4,0x00A1, 0x0091,0x0089,0x0085,0x0083,0x81D3,0x81D2,0x0083,0x81D1,0x81D0,0x0085,0x0083,0xB5AB,0x81CF,0x0083,0x81CE,0xB5E8, 0x0089,0x0085,0x0083,0x81CD,0x81CC,0x0083,0x81CB,0x81CA,0x0085,0x0083,0x81C9,0xD9A4,0x0083,0xCBC6,0x81C8,0x0091, 0x0089,0x0085,0x0083,0xCBC5,0x81C7,0x0083,0xC9EC,0x81C6,0x0085,0x0083,0xC1E6,0x81C5,0x0083,0xB0E9,0x81C4,0x0089, 0x0085,0x0083,0xD9A3,0x81C3,0x0083,0xB9C0,0xB2AE,0x0085,0x0083,0x81C2,0x81C1,0x0083,0x81C0,0xD8F9,0x00C1,0x00A1, 0x0091,0x0089,0x0085,0x0083,0xCEB1,0x81BF,0x0083,0x81BE,0xD8F7,0x0085,0x0083,0xC2D7,0xD8F6,0x0083,0xC9CB,0x81BD, 0x0089,0x0085,0x0083,0xD8F3,0x81BC,0x0083,0xB4AB,0xCEB0,0x0085,0x0083,0xC9A1,0x81BB,0x0083,0x81BA,0xD8F1,0x0091, 0x0089,0x0085,0x0083,0xBBE1,0xBBEF,0x0083,0xD3C5,0xD6DA,0x0085,0x0083,0x81B9,0x81B8,0x0083,0x81B7,0x81B6,0x0089, 0x0085,0x0083,0x81B5,0xD0DD,0x0083,0xB7A5,0xB7FC,0x0085,0x0083,0xBCBF,0xCEE9,0x0083,0x81B4,0x81B3,0x00A1,0x0091, 0x0089,0x0085,0x0083,0xD2C1,0xD8F8,0x0083,0x81B2,0x81B1,0x0085,0x0083,0x81B0,0x81AF,0x0083,0x81AE,0x81AD,0x0089, 0x0085,0x0083,0x81AC,0xC6F3,0x0083,0x81AB,0xB7C2,0x0085,0x0083,0x81AA,0xB7DD,0x0083,0x81A9,0xC8CE,0x0091,0x0089, 0x0085,0x0083,0x81A8,0x81A7,0x0083,0x81A6,0xBCDB,0x0085,0x0083,0xBCFE,0xD8F5,0x0083,0x81A5,0xD8F2,0x0089,0x0085, 0x0083,0xD6D9,0x81A4,0x0083,0xD1F6,0x81A3,0x0085,0x0083,0x81A2,0x81A1,0x0083,0xC3C7,0xD8EF,0x0101,0x00C1,0x00A1, 0x0091,0x0089,0x0085,0x0083,0xD2C7,0x81A0,0x0083,0xD8ED,0x819F,0x0085,0x0083,0x819E,0xD2D4,0x0083,0xC1EE,0xB4FA, 0x0089,0x0085,0x0083,0x819D,0xD8EE,0x0083,0x819C,0xC7AA,0x0085,0x0083,0xD8F0,0xD9DA,0x0083,0x819B,0x819A,0x0091, 0x0089,0x0085,0x0083,0x8199,0xCFC9,0x0083,0xB8B6,0xD5CC,0x0085,0x0083,0xCBFB,0xCACB,0x0083,0xD7D0,0xB2D6,0x0089, 0x0085,0x0083,0x8198,0xC2D8,0x0083,0x8197,0x8196,0x0085,0x0083,0xB4D3,0xC8D4,0x0083,0x8195,0xBDE9,0x00A1,0x0091, 0x0089,0x0085,0x0083,0xBDF1,0xD8EB,0x0083,0x8194,0xB3F0,0x0085,0x0083,0xC6CD,0xBDF6,0x0083,0xD8C6,0xD8EA,0x0089, 0x0085,0x0083,0xD8EC,0xC8CA,0x0083,0xCAB2,0xD2DA,0x0085,0x0083,0x8193,0x8192,0x0083,0x8191,0xD8E9,0x0091,0x0089, 0x0085,0x0083,0xC8CB,0x8190,0x0083,0x818F,0x818E,0x0085,0x0083,0x818D,0xD9F4,0x0083,0x818C,0xD9F1,0x0089,0x0085, 0x0083,0xC7D7,0x818B,0x0083,0x818A,0x8189,0x0085,0x0083,0xC1C1,0xCDA4,0x0083,0xBEA9,0xCFED,0x00C1,0x00A1,0x0091, 0x0089,0x0085,0x0083,0x8188,0xC4B6,0x0083,0xBAE0,0xB2FA,0x0085,0x0083,0xD2E0,0xBAA5,0x0083,0xBDBB,0x8187,0x0089, 0x0085,0x0083,0xBFBA,0xCDF6,0x0083,0xD9EF,0xD8BD,0x0085,0x0083,0x8186,0x8185,0x0083,0x8184,0xD0A9,0x0091,0x0089, 0x0085,0x0083,0xD1C7,0x8183,0x0083,0xD8A8,0x8182,0x0085,0x0083,0x8181,0xBEAE,0x0083,0xCEE5,0xD8C1,0x0089,0x0085, 0x0083,0xBBA5,0xD4C6,0x0083,0x8180,0xBFF7,0x0085,0x0083,0xD3DA,0xD8A1,0x0083,0xB6FE,0xCAC2,0x00A1,0x0091,0x0089, 0x0085,0x0083,0x817E,0xD5F9,0x0083,0xD3E8,0x817D,0x0085,0x0083,0xC1CB,0x817C,0x0083,0x817B,0x817A,0x0089,0x0085, 0x0083,0x8179,0x8178,0x0083,0x8177,0x8176,0x0085,0x0083,0xC7AC,0x8175,0x0083,0x8174,0x8173,0x0091,0x0089,0x0085, 0x0083,0x8172,0x8171,0x0083,0x8170,0x816F,0x0085,0x0083,0x816E,0x816D,0x0083,0x816C,0xC8E9,0x0089,0x0085,0x0083, 0x816B,0xC2D2,0x0083,0xC2F2,0x816A,0x0085,0x0083,0x8169,0x8168,0x0083,0x8167,0x8166,0x0081,0x0081,0x00FF,0x00BF, 0x009F,0x008F,0x0087,0x0083,0x8165,0x0083,0xD8C0,0x8164,0x0085,0x0083,0x8163,0xCAE9,0x0083,0x8162,0x8161,0x0089, 0x0085,0x0083,0x8160,0x815F,0x0083,0xCFE7,0xCFB0,0x0085,0x0083,0xD2B2,0xC6F2,0x0083,0xBEC5,0xD8BF,0x0091,0x0089, 0x0085,0x0083,0x815E,0x815D,0x0083,0xD2D2,0xB3CB,0x0085,0x0083,0x815C,0xB9D4,0x0083,0x815B,0xC7C7,0x0089,0x0085, 0x0083,0xC5D2,0xC6B9,0x0083,0x815A,0xC0D6,0x0085,0x0083,0xB7A6,0xBAF5,0x0083,0xD5A7,0xCEDA,0x00A1,0x0091,0x0089, 0x0085,0x0083,0xD6AE,0x8159,0x0083,0xD2E5,0xC3B4,0x0085,0x0083,0xD8B1,0x8158,0x0083,0xBEC3,0x8157,0x0089,0x0085, 0x0083,0xC4CB,0x8156,0x0083,0x8155,0x8154,0x0085,0x0083,0xD8AF,0xBED9,0x0083,0xC0F6,0x8153,0x0091,0x0089,0x0085, 0x0083,0xD6F7,0xCEAA,0x0083,0xB5A4,0xCDE8,0x0085,0x0083,0x8152,0xD8BC,0x0083,0x8151,0xC1D9,0x0089,0x0085,0x0083, 0x8150,0xB4AE,0x0083,0x814F,0xB7E1,0x0085,0x0083,0x814E,0x814D,0x0083,0xD6D0,0xE3DC,0x00C1,0x00A1,0x0091,0x0089, 0x0085,0x0083,0xD1BE,0xB8F6,0x0083,0x814C,0xD8AD,0x0085,0x0083,0xC9A5,0x814B,0x0083,0xD1CF,0xC1BD,0x0089,0x0085, 0x0083,0x814A,0xB6AA,0x0083,0x8149,0x8148,0x0085,0x0083,0x8147,0xD8A9,0x0083,0xCBBF,0xB6AB,0x0091,0x0089,0x0085, 0x0083,0xB4D4,0xD2B5,0x0083,0xB1FB,0xC7F0,0x0085,0x0083,0x8146,0xCAC0,0x0083,0xD8A7,0xC7D2,0x0089,0x0085,0x0083, 0xD7A8,0x8145,0x0083,0xB3F3,0xD8A4,0x0085,0x0083,0x8144,0xD3EB,0x0083,0xB2BB,0xD8A2,0x0081,0x0091,0x0089,0x0085, 0x0083,0xCFC2,0xC9CF,0x0083,0xC8FD,0xD5C9,0x0085,0x0083,0xCDF2,0x8143,0x0083,0x8142,0x8141,0x0081,0x0085,0x0083, 0xC6DF,0x8140,0x0083,0xB6A1,0xD2BB,0x05BC,0x0219,0x0082,0x0082,0x00BB,0x00B1,0x0082,0x0096,0x0082,0x008B,0x0082, 0x0085,0x0081,0x0082,0xA954,0x0081,0x0083,0xA953,0xA952,0x0086,0x0081,0x0081,0x0081,0xA951,0x0081,0x0082,0x0081, 0xA950,0x0088,0x0082,0x0082,0x0082,0x0081,0x0082,0xA94F,0x008E,0x0089,0x0081,0x0085,0x0083,0xA94E,0xA94D,0x0081, 0xA94C,0x0082,0x0082,0x0082,0xA94B,0x0081,0x0081,0x0081,0x0081,0xA94A,0x0082,0x0082,0x0081,0x0082,0x0082,0x0082, 0x0081,0x0081,0xA949,0x00A5,0x0081,0x0082,0x009C,0x0087,0x0082,0x0082,0x0082,0x0082,0xA95A,0x0086,0x0082,0x0082, 0x0082,0xA2EE,0x0089,0x0085,0x0083,0xA2ED,0xA2EC,0x0083,0xA2EB,0xA2EA,0x0085,0x0083,0xA2E9,0xA2E8,0x0083,0xA2E7, 0xA2E6,0x0081,0x0081,0x0081,0x0081,0x0081,0xA2E5,0x00D1,0x0082,0x0097,0x0082,0x0086,0x0082,0x0082,0x0082,0xA8E9, 0x0089,0x0085,0x0083,0xA8E8,0xA8E7,0x0083,0xA8E6,0xA8E5,0x0085,0x0083,0xA8E4,0xA8E3,0x0083,0xA8E2,0xA8E1,0x00A1, 0x0091,0x0089,0x0085,0x0083,0xA8E0,0xA8DF,0x0083,0xA8DE,0xA8DD,0x0085,0x0083,0xA8DC,0xA8DB,0x0083,0xA8DA,0xA8D9, 0x0089,0x0085,0x0083,0xA8D8,0xA8D7,0x0083,0xA8D6,0xA8D5,0x0085,0x0083,0xA8D4,0xA8D3,0x0083,0xA8D2,0xA8D1,0x0091, 0x0089,0x0085,0x0083,0xA8D0,0xA8CF,0x0083,0xA8CE,0xA8CD,0x0085,0x0083,0xA8CC,0xA8CB,0x0083,0xA8CA,0xA8C9,0x0081, 0x0085,0x0083,0xA8C8,0xA8C7,0x0083,0xA8C6,0xA8C5,0x00F7,0x00B7,0x0097,0x008A,0x0086,0x0082,0x0083,0xA964,0xA963, 0x0081,0x0081,0xA960,0x0086,0x0082,0x0083,0xA5F6,0xA5F5,0x0085,0x0083,0xA5F4,0xA5F3,0x0083,0xA5F2,0xA5F1,0x0091, 0x0089,0x0085,0x0083,0xA5F0,0xA5EF,0x0083,0xA5EE,0xA5ED,0x0085,0x0083,0xA5EC,0xA5EB,0x0083,0xA5EA,0xA5E9,0x0089, 0x0085,0x0083,0xA5E8,0xA5E7,0x0083,0xA5E6,0xA5E5,0x0085,0x0083,0xA5E4,0xA5E3,0x0083,0xA5E2,0xA5E1,0x00A1,0x0091, 0x0089,0x0085,0x0083,0xA5E0,0xA5DF,0x0083,0xA5DE,0xA5DD,0x0085,0x0083,0xA5DC,0xA5DB,0x0083,0xA5DA,0xA5D9,0x0089, 0x0085,0x0083,0xA5D8,0xA5D7,0x0083,0xA5D6,0xA5D5,0x0085,0x0083,0xA5D4,0xA5D3,0x0083,0xA5D2,0xA5D1,0x0091,0x0089, 0x0085,0x0083,0xA5D0,0xA5CF,0x0083,0xA5CE,0xA5CD,0x0085,0x0083,0xA5CC,0xA5CB,0x0083,0xA5CA,0xA5C9,0x0089,0x0085, 0x0083,0xA5C8,0xA5C7,0x0083,0xA5C6,0xA5C5,0x0085,0x0083,0xA5C4,0xA5C3,0x0083,0xA5C2,0xA5C1,0x00C1,0x00A1,0x0091, 0x0089,0x0085,0x0083,0xA5C0,0xA5BF,0x0083,0xA5BE,0xA5BD,0x0085,0x0083,0xA5BC,0xA5BB,0x0083,0xA5BA,0xA5B9,0x0089, 0x0085,0x0083,0xA5B8,0xA5B7,0x0083,0xA5B6,0xA5B5,0x0085,0x0083,0xA5B4,0xA5B3,0x0083,0xA5B2,0xA5B1,0x0091,0x0089, 0x0085,0x0083,0xA5B0,0xA5AF,0x0083,0xA5AE,0xA5AD,0x0085,0x0083,0xA5AC,0xA5AB,0x0083,0xA5AA,0xA5A9,0x0089,0x0085, 0x0083,0xA5A8,0xA5A7,0x0083,0xA5A6,0xA5A5,0x0085,0x0083,0xA5A4,0xA5A3,0x0083,0xA5A2,0xA5A1,0x0093,0x008B,0x0086, 0x0082,0x0083,0xA967,0xA966,0x0081,0x0083,0xA962,0xA961,0x0082,0x0084,0x0082,0xA4F3,0x0083,0xA4F2,0xA4F1,0x0091, 0x0089,0x0085,0x0083,0xA4F0,0xA4EF,0x0083,0xA4EE,0xA4ED,0x0085,0x0083,0xA4EC,0xA4EB,0x0083,0xA4EA,0xA4E9,0x0089, 0x0085,0x0083,0xA4E8,0xA4E7,0x0083,0xA4E6,0xA4E5,0x0085,0x0083,0xA4E4,0xA4E3,0x0083,0xA4E2,0xA4E1,0x0159,0x0081, 0x0081,0x0081,0x014C,0x00FF,0x00BF,0x009F,0x008F,0x0087,0x0083,0xA4E0,0x0083,0xA4DF,0xA4DE,0x0085,0x0083,0xA4DD, 0xA4DC,0x0083,0xA4DB,0xA4DA,0x0089,0x0085,0x0083,0xA4D9,0xA4D8,0x0083,0xA4D7,0xA4D6,0x0085,0x0083,0xA4D5,0xA4D4, 0x0083,0xA4D3,0xA4D2,0x0091,0x0089,0x0085,0x0083,0xA4D1,0xA4D0,0x0083,0xA4CF,0xA4CE,0x0085,0x0083,0xA4CD,0xA4CC, 0x0083,0xA4CB,0xA4CA,0x0089,0x0085,0x0083,0xA4C9,0xA4C8,0x0083,0xA4C7,0xA4C6,0x0085,0x0083,0xA4C5,0xA4C4,0x0083, 0xA4C3,0xA4C2,0x00A1,0x0091,0x0089,0x0085,0x0083,0xA4C1,0xA4C0,0x0083,0xA4BF,0xA4BE,0x0085,0x0083,0xA4BD,0xA4BC, 0x0083,0xA4BB,0xA4BA,0x0089,0x0085,0x0083,0xA4B9,0xA4B8,0x0083,0xA4B7,0xA4B6,0x0085,0x0083,0xA4B5,0xA4B4,0x0083, 0xA4B3,0xA4B2,0x0091,0x0089,0x0085,0x0083,0xA4B1,0xA4B0,0x0083,0xA4AF,0xA4AE,0x0085,0x0083,0xA4AD,0xA4AC,0x0083, 0xA4AB,0xA4AA,0x0089,0x0085,0x0083,0xA4A9,0xA4A8,0x0083,0xA4A7,0xA4A6,0x0085,0x0083,0xA4A5,0xA4A4,0x0083,0xA4A3, 0xA4A2,0x0098,0x0087,0x0081,0x0081,0x0081,0x0081,0xA4A1,0x0082,0x0089,0x0085,0x0083,0xA948,0xA947,0x0083,0xA946, 0xA945,0x0085,0x0083,0xA944,0xA943,0x0083,0xA942,0xA941,0x0098,0x008B,0x0087,0x0084,0x0081,0xA940,0x0082,0xA895, 0x0081,0x0081,0xA894,0x0086,0x0082,0x0083,0xA1BD,0xA1BC,0x0085,0x0083,0xA1B3,0xA1B2,0x0083,0xA1FE,0xA893,0x0091, 0x0089,0x0085,0x0083,0xA1BF,0xA1BE,0x0083,0xA1BB,0xA1BA,0x0085,0x0083,0xA1B9,0xA1B8,0x0083,0xA1B7,0xA1B6,0x0089, 0x0085,0x0083,0xA1B5,0xA1B4,0x0083,0xA996,0xA965,0x0084,0x0081,0xA1A9,0x0083,0xA1A8,0xA1A3,0x0081,0x0081,0x0081, 0x0081,0x0081,0x0081,0x0083,0xA1A2,0xA1A1,0x0203,0x0082,0x00DD,0x008E,0x0082,0x0081,0x0081,0x0086,0x0082,0x0082, 0x0082,0xA1E1,0x0081,0x0081,0x0082,0xA1E2,0x00A1,0x008D,0x0081,0x0081,0x0087,0x0084,0x0081,0xA891,0x0082,0xA1EE, 0x0081,0x0081,0xA1EF,0x008B,0x0081,0x0082,0x0085,0x0083,0xA890,0xA88F,0x0083,0xA88E,0xA88D,0x0082,0x0086,0x0082, 0x0083,0xA1F1,0xA1F2,0x0082,0x0081,0xA1F0,0x0094,0x008D,0x0087,0x0081,0x0082,0x0083,0xA1F3,0xA1F4,0x0082,0x0081, 0x0083,0xA88C,0xA88B,0x0081,0x0082,0x0082,0x0083,0xA1F7,0xA1F8,0x0088,0x0082,0x0081,0x0081,0x0083,0xA1F5,0xA1F6, 0x0089,0x0082,0x0085,0x0083,0xA88A,0xA889,0x0081,0xA888,0x0086,0x0082,0x0083,0xA887,0xA886,0x0085,0x0083,0xA885, 0xA884,0x0083,0xA883,0xA882,0x0166,0x00E6,0x00AC,0x0096,0x0091,0x0089,0x0085,0x0083,0xA881,0xA880,0x0083,0xA87E, 0xA87D,0x0085,0x0083,0xA87C,0xA87B,0x0083,0xA87A,0xA879,0x0081,0x0081,0x0081,0xA878,0x0087,0x0082,0x0082,0x0083, 0xA877,0xA876,0x0089,0x0085,0x0083,0xA875,0xA874,0x0083,0xA873,0xA872,0x0085,0x0083,0xA871,0xA870,0x0083,0xA86F, 0xA86E,0x00A1,0x0091,0x0089,0x0085,0x0083,0xA86D,0xA86C,0x0083,0xA86B,0xA86A,0x0085,0x0083,0xA869,0xA868,0x0083, 0xA867,0xA866,0x0089,0x0085,0x0083,0xA865,0xA864,0x0083,0xA863,0xA862,0x0085,0x0083,0xA861,0xA860,0x0083,0xA85F, 0xA85E,0x0091,0x0089,0x0085,0x0083,0xA85D,0xA85C,0x0083,0xA85B,0xA85A,0x0085,0x0083,0xA859,0xA858,0x0083,0xA857, 0xA856,0x0086,0x0081,0x0083,0xA855,0xA854,0x0082,0x0083,0xA9EF,0xA9EE,0x00C1,0x00A1,0x0091,0x0089,0x0085,0x0083, 0xA9ED,0xA9EC,0x0083,0xA9EB,0xA9EA,0x0085,0x0083,0xA9E9,0xA9E8,0x0083,0xA9E7,0xA9E6,0x0089,0x0085,0x0083,0xA9E5, 0xA9E4,0x0083,0xA9E3,0xA9E2,0x0085,0x0083,0xA9E1,0xA9E0,0x0083,0xA9DF,0xA9DE,0x0091,0x0089,0x0085,0x0083,0xA9DD, 0xA9DC,0x0083,0xA9DB,0xA9DA,0x0085,0x0083,0xA9D9,0xA9D8,0x0083,0xA9D7,0xA9D6,0x0089,0x0085,0x0083,0xA9D5,0xA9D4, 0x0083,0xA9D3,0xA9D2,0x0085,0x0083,0xA9D1,0xA9D0,0x0083,0xA9CF,0xA9CE,0x00A1,0x0091,0x0089,0x0085,0x0083,0xA9CD, 0xA9CC,0x0083,0xA9CB,0xA9CA,0x0085,0x0083,0xA9C9,0xA9C8,0x0083,0xA9C7,0xA9C6,0x0089,0x0085,0x0083,0xA9C5,0xA9C4, 0x0083,0xA9C3,0xA9C2,0x0085,0x0083,0xA9C1,0xA9C0,0x0083,0xA9BF,0xA9BE,0x0091,0x0089,0x0085,0x0083,0xA9BD,0xA9BC, 0x0083,0xA9BB,0xA9BA,0x0085,0x0083,0xA9B9,0xA9B8,0x0083,0xA9B7,0xA9B6,0x0089,0x0085,0x0083,0xA9B5,0xA9B4,0x0083, 0xA9B3,0xA9B2,0x0085,0x0083,0xA9B1,0xA9B0,0x0083,0xA9AF,0xA9AE,0x0099,0x0081,0x0081,0x0091,0x0089,0x0085,0x0083, 0xA9AD,0xA9AC,0x0083,0xA9AB,0xA9AA,0x0085,0x0083,0xA9A9,0xA9A8,0x0083,0xA9A7,0xA9A6,0x0081,0x0081,0x0083,0xA9A5, 0xA9A4,0x0082,0x0088,0x0082,0x0082,0x0082,0x0083,0xA2C4,0xA2C3,0x0091,0x0089,0x0085,0x0083,0xA2C2,0xA2C1,0x0083, 0xA2C0,0xA2BF,0x0085,0x0083,0xA2BE,0xA2BD,0x0083,0xA2BC,0xA2BB,0x0089,0x0085,0x0083,0xA2BA,0xA2B9,0x0083,0xA2B8, 0xA2B7,0x0085,0x0083,0xA2B6,0xA2B5,0x0083,0xA2B4,0xA2B3,0x00E9,0x00C9,0x0081,0x0081,0x00AF,0x009F,0x008F,0x0087, 0x0083,0xA2B2,0x0083,0xA2B1,0xA2D8,0x0085,0x0083,0xA2D7,0xA2D6,0x0083,0xA2D5,0xA2D4,0x0089,0x0085,0x0083,0xA2D3, 0xA2D2,0x0083,0xA2D1,0xA2D0,0x0085,0x0083,0xA2CF,0xA2CE,0x0083,0xA2CD,0xA2CC,0x0081,0x0089,0x0085,0x0083,0xA2CB, 0xA2CA,0x0083,0xA2C9,0xA2C8,0x0085,0x0083,0xA2C7,0xA2C6,0x0081,0xA2C5,0x0081,0x0090,0x0088,0x0084,0x0082,0xA2E2, 0x0083,0xA2E1,0xA2E0,0x0085,0x0083,0xA2DF,0xA2DE,0x0083,0xA2DD,0xA2DC,0x0081,0x0085,0x0083,0xA2DB,0xA2DA,0x0081, 0xA2D9,0x008A,0x0082,0x0082,0x0082,0x0082,0x0081,0x0081,0x0082,0xA1D0,0x0082,0x0088,0x0081,0x0082,0x0082,0x0081, 0x0081,0xA853,0x0087,0x0081,0x0082,0x0082,0x0081,0xA1CD,0x0081,0x0085,0x0082,0x0081,0xA1D1,0x0082,0x0081,0xA892, 0x0109,0x00E9,0x00A2,0x008A,0x0082,0x0082,0x0082,0x0084,0x0082,0xA1DB,0x0081,0xA1DA,0x0093,0x0089,0x0082,0x0084, 0x0082,0xA852,0x0083,0xA851,0xA1DD,0x0087,0x0084,0x0081,0xA1DC,0x0082,0xA1D4,0x0081,0x0081,0xA1D9,0x0082,0x0081, 0x0082,0x0081,0xA850,0x009E,0x008E,0x0089,0x0085,0x0081,0x0081,0xA1D5,0x0081,0x0081,0xA1D6,0x0082,0x0082,0x0082, 0xA1D7,0x0089,0x0082,0x0084,0x0082,0xA1CB,0x0083,0xA1C3,0xA1DF,0x0085,0x0081,0x0081,0xA1E0,0x0082,0x0081,0xA1D3, 0x009B,0x008F,0x0088,0x0084,0x0082,0xA1D2,0x0083,0xA1C8,0xA1C9,0x0085,0x0083,0xA1C5,0xA1C4,0x0082,0xA1CE,0x0085, 0x0081,0x0082,0xA84F,0x0085,0x0083,0xA1CF,0xA84E,0x0083,0xA1DE,0xA1D8,0x0089,0x0085,0x0082,0x0081,0xA1CC,0x0082, 0x0082,0xA84D,0x0085,0x0082,0x0082,0xA1C6,0x0081,0x0082,0xA1C7,0x0089,0x0081,0x0081,0x0081,0x0082,0x0081,0x0081, 0xA1CA,0x0082,0x0082,0x008C,0x0085,0x0082,0x0082,0xA84C,0x0085,0x0083,0xA84B,0xA84A,0x0081,0xA849,0x0088,0x0084, 0x0082,0xA1FD,0x0083,0xA1FA,0xA1FC,0x0081,0x0081,0xA1FB,0x00C3,0x00B6,0x009A,0x0082,0x008D,0x0085,0x0082,0x0082, 0xA2AA,0x0085,0x0083,0xA2A9,0xA2A8,0x0083,0xA2A7,0xA2A6,0x0089,0x0085,0x0083,0xA2A5,0xA2A4,0x0083,0xA2A3,0xA2A2, 0x0081,0x0081,0xA2A1,0x0081,0x0090,0x0088,0x0084,0x0082,0xA2FC,0x0083,0xA2FB,0xA2FA,0x0085,0x0083,0xA2F9,0xA2F8, 0x0083,0xA2F7,0xA2F6,0x0089,0x0085,0x0083,0xA2F5,0xA2F4,0x0083,0xA2F3,0xA2F2,0x0081,0x0081,0xA2F1,0x0082,0x0087, 0x0082,0x0081,0x0082,0x0082,0xA959,0x0081,0x0082,0x0082,0x0081,0xA1ED,0x0090,0x0081,0x0081,0x0089,0x0085,0x0082, 0x0082,0xA848,0x0082,0x0082,0xA847,0x0081,0x0081,0x0082,0xA1E6,0x0082,0x0081,0x0081,0x0081,0x0081,0x0081,0x0080, 0x00B9,0x0081,0x0081,0x0081,0x0081,0x0081,0x0082,0x0092,0x0082,0x0086,0x0081,0x0082,0x0081,0xA1F9,0x0088,0x0084, 0x0081,0xA846,0x0083,0xA1E5,0xA1E4,0x0081,0x0082,0xA1EB,0x008B,0x0086,0x0082,0x0082,0x0082,0xA1AD,0x0081,0x0081, 0x0081,0xA845,0x008D,0x0086,0x0081,0x0083,0xA1B1,0xA1B0,0x0085,0x0083,0xA1AF,0xA1AE,0x0082,0xA1AC,0x0088,0x0085, 0x0083,0xA844,0xA1AA,0x0081,0xA843,0x0081,0x0082,0xA95C,0x0082,0x0082,0x0193,0x0156,0x00E1,0x0082,0x00A0,0x0082, 0x008F,0x0087,0x0084,0x0082,0xA7D7,0x0082,0xA7F1,0x0085,0x0083,0xA7F0,0xA7EF,0x0083,0xA7EE,0xA7ED,0x0089,0x0085, 0x0083,0xA7EC,0xA7EB,0x0083,0xA7EA,0xA7E9,0x0085,0x0083,0xA7E8,0xA7E7,0x0083,0xA7E6,0xA7E5,0x00A1,0x0091,0x0089, 0x0085,0x0083,0xA7E4,0xA7E3,0x0083,0xA7E2,0xA7E1,0x0085,0x0083,0xA7E0,0xA7DF,0x0083,0xA7DE,0xA7DD,0x0089,0x0085, 0x0083,0xA7DC,0xA7DB,0x0083,0xA7DA,0xA7D9,0x0085,0x0083,0xA7D8,0xA7D6,0x0083,0xA7D5,0xA7D4,0x0091,0x0089,0x0085, 0x0083,0xA7D3,0xA7D2,0x0083,0xA7D1,0xA7C1,0x0085,0x0083,0xA7C0,0xA7BF,0x0083,0xA7BE,0xA7BD,0x0089,0x0085,0x0083, 0xA7BC,0xA7BB,0x0083,0xA7BA,0xA7B9,0x0085,0x0083,0xA7B8,0xA7B7,0x0083,0xA7B6,0xA7B5,0x00B1,0x00AA,0x00A1,0x0091, 0x0089,0x0085,0x0083,0xA7B4,0xA7B3,0x0083,0xA7B2,0xA7B1,0x0085,0x0083,0xA7B0,0xA7AF,0x0083,0xA7AE,0xA7AD,0x0089, 0x0085,0x0083,0xA7AC,0xA7AB,0x0083,0xA7AA,0xA7A9,0x0085,0x0083,0xA7A8,0xA7A6,0x0083,0xA7A5,0xA7A4,0x0081,0x0081, 0x0085,0x0083,0xA7A3,0xA7A2,0x0081,0xA7A1,0x0081,0x0081,0x0081,0x0081,0x0082,0xA7A7,0x0092,0x0082,0x0082,0x0088, 0x0084,0x0082,0xA6D8,0x0083,0xA6D7,0xA6D6,0x0085,0x0083,0xA6D5,0xA6D4,0x0083,0xA6D3,0xA6D2,0x00A0,0x0090,0x0088, 0x0084,0x0082,0xA6D1,0x0083,0xA6D0,0xA6CF,0x0085,0x0083,0xA6CE,0xA6CD,0x0083,0xA6CC,0xA6CB,0x0089,0x0085,0x0083, 0xA6CA,0xA6C9,0x0083,0xA6C8,0xA6C7,0x0085,0x0083,0xA6C6,0xA6C5,0x0083,0xA6C4,0xA6C3,0x0087,0x0081,0x0081,0x0083, 0xA6C2,0xA6C1,0x0088,0x0084,0x0082,0xA6B8,0x0083,0xA6B7,0xA6B6,0x0085,0x0083,0xA6B5,0xA6B4,0x0083,0xA6B3,0xA6B2, 0x00A9,0x0081,0x0081,0x00A0,0x0090,0x0088,0x0084,0x0082,0xA6B1,0x0083,0xA6B0,0xA6AF,0x0085,0x0083,0xA6AE,0xA6AD, 0x0083,0xA6AC,0xA6AB,0x0089,0x0085,0x0083,0xA6AA,0xA6A9,0x0083,0xA6A8,0xA6A7,0x0085,0x0083,0xA6A6,0xA6A5,0x0083, 0xA6A4,0xA6A3,0x0081,0x0081,0x0081,0x0083,0xA6A2,0xA6A1,0x0082,0x0081,0x0087,0x0082,0x0081,0x0081,0x0082,0xA842, 0x0086,0x0082,0x0082,0x0082,0xA841,0x0081,0x0085,0x0083,0xA840,0xA1A5,0x0082,0xA1A6,0x00AD,0x008F,0x0082,0x0081, 0x0087,0x0081,0x0081,0x0082,0x0081,0xA8C0,0x0081,0x0081,0x0082,0x0081,0xA8BB,0x0082,0x0081,0x0092,0x0086,0x0082, 0x0082,0x0082,0xA8B8,0x0087,0x0084,0x0082,0xA8B7,0x0082,0xA8B6,0x0084,0x0082,0xA8B5,0x0082,0xA8B3,0x0081,0x0087, 0x0084,0x0082,0xA8AF,0x0082,0xA8AB,0x0081,0x0082,0xA8A3,0x009E,0x0089,0x0082,0x0082,0x0082,0x0081,0x0081,0x0081, 0xA8B1,0x008F,0x0082,0x0086,0x0082,0x0082,0x0081,0xA8AD,0x0085,0x0082,0x0082,0xA8BE,0x0082,0x0082,0xA8BD,0x0082, 0x0082,0x0081,0x0081,0x0081,0xA8A9,0x00B1,0x008D,0x0087,0x0082,0x0081,0x0081,0x0081,0xA8A7,0x0081,0x0081,0x0081, 0x0081,0xA8A5,0x0093,0x0089,0x0085,0x0082,0x0081,0xA8A1,0x0082,0x0082,0xA8B9,0x0087,0x0084,0x0082,0xA8B2,0x0081, 0xA8B4,0x0081,0x0081,0xA1C2,0x008B,0x0086,0x0081,0x0083,0xA8AE,0xA8B0,0x0082,0x0083,0xA8AA,0xA8AC,0x0081,0x0084, 0x0082,0xA8BA,0x0083,0xA8A6,0xA8A8,0x008D,0x0081,0x0087,0x0081,0x0082,0x0083,0xA8A2,0xA8A4,0x0082,0x0081,0x0081, 0xA1C1,0x0087,0x0082,0x0082,0x0081,0x0081,0xA1A4,0x0087,0x0081,0x0082,0x0083,0xA1C0,0xA1E3,0x0085,0x0082,0x0082, 0xA1A7,0x0084,0x0081,0xA1EC,0x0082,0xA1E8, }; // ucs2_to_cp936_elements const TConvFlatTree ucs2_to_cp936 = { 0x00A4, // min key 0xFFE5, // max key 0x0081, // links space start 0x7FFF, // links space end ucs2_to_cp936_numelems, // number of elements (treeval_t *)&ucs2_to_cp936_elements // elements }; // ucs2_to_cp936 const size_t cp936_to_ucs2_numelems = 44536; const treeval_t cp936_to_ucs2_elements[cp936_to_ucs2_numelems] = { 0xEFFE,0xADE7,0xEFFE,0x5B47,0xCB80,0xB38E,0xA796,0xA310,0xA188,0xA0C4,0xA026,0xA000,0xA000,0xA01E,0xA00E,0xA006, 0xA002,0xFA29,0xA002,0xFA28,0xFA27,0xA004,0xA002,0xFA24,0xFA23,0xA002,0xFA21,0xFA20,0xA008,0xA004,0xA002,0xFA1F, 0xFA18,0xA002,0xFA14,0xFA13,0xA004,0xA002,0xFA11,0xFA0F,0xA002,0xFA0E,0xFA0D,0xA000,0xA000,0xA000,0xA000,0xFA0C, 0xA01F,0xA001,0xA001,0xA00D,0xA005,0xA001,0xA002,0xF9F1,0xF9E7,0xA004,0xA002,0xF995,0xF979,0xA002,0xF92C,0x9FA5, 0xA008,0xA004,0xA002,0x9FA4,0x9FA3,0xA002,0x9FA2,0x9FA1,0xA004,0xA002,0x9F9E,0x9F9D,0xA002,0x9F9C,0x9F98,0xA03F, 0xA020,0xA010,0xA008,0xA004,0xA002,0x9F97,0x9F96,0xA002,0x9F95,0x9F94,0xA004,0xA002,0x9F93,0x9F92,0xA002,0x9F91, 0x9F90,0xA008,0xA004,0xA002,0x9F8F,0x9F8E,0xA002,0x9F8D,0x9F82,0xA004,0xA002,0x9F81,0x9F7E,0xA002,0x9F7D,0x9F7C, 0xA00F,0xA007,0xA004,0xA002,0x9F7B,0x9F7A,0xA000,0x9F79,0xA004,0xA002,0x9F78,0x9F77,0xA002,0x9F76,0x9F75,0xA008, 0xA004,0xA002,0x9F74,0x9F73,0xA002,0x9F72,0x9F71,0xA004,0xA002,0x9F70,0x9F6F,0xA002,0x9F6E,0x9F6D,0xA020,0xA010, 0xA008,0xA004,0xA002,0x9F6C,0x9F6B,0xA002,0x9F6A,0x9F69,0xA004,0xA002,0x9F68,0x9F67,0xA002,0x9F66,0x9F65,0xA008, 0xA004,0xA002,0x9F64,0x9F63,0xA002,0x9F62,0x9F61,0xA004,0xA002,0x9F60,0x9F5F,0xA002,0x9F5E,0x9F5D,0xA010,0xA008, 0xA004,0xA002,0x9F5C,0x9F5B,0xA002,0x9F5A,0x9F59,0xA004,0xA002,0x9F58,0x9F57,0xA002,0x9F56,0x9F55,0xA008,0xA004, 0xA002,0x9F54,0x9F53,0xA002,0x9F52,0x9F4F,0xA004,0xA002,0x9F4E,0x9F4D,0xA002,0x9F4C,0x9F4B,0xA02A,0xA000,0xA000, 0xA01E,0xA00E,0xA006,0xA002,0x9F4A,0xA002,0x9F49,0x9F48,0xA004,0xA002,0x9F47,0x9F46,0xA002,0x9F45,0x9F43,0xA008, 0xA004,0xA002,0x9F42,0x9F41,0xA002,0x9F40,0x9F3F,0xA004,0xA002,0x9F3C,0x9F3A,0xA002,0x9F38,0x9F36,0xA000,0xA000, 0xA004,0xA002,0x9F35,0x9F34,0xA002,0x9F33,0x9F32,0xA01B,0xA001,0xA001,0xA009,0xA001,0xA004,0xA002,0x9F31,0x9F30, 0xA002,0x9F2E,0x9F2D,0xA008,0xA004,0xA002,0x9F2B,0x9F2A,0xA002,0x9F29,0x9F28,0xA004,0xA002,0x9F27,0x9F26,0xA002, 0x9F25,0x9F24,0xA03F,0xA020,0xA010,0xA008,0xA004,0xA002,0x9F23,0x9F21,0xA002,0x9F1F,0x9F1E,0xA004,0xA002,0x9F1D, 0x9F1C,0xA002,0x9F1B,0x9F1A,0xA008,0xA004,0xA002,0x9F18,0x9F16,0xA002,0x9F15,0x9F14,0xA004,0xA002,0x9F12,0x9F11, 0xA002,0x9F0F,0x9F0C,0xA00F,0xA008,0xA004,0xA002,0x9F0A,0x9F09,0xA002,0x9F08,0x9F07,0xA003,0xA000,0x9F06,0xA002, 0x9F05,0x9F04,0xA008,0xA004,0xA002,0x9F03,0x9F02,0xA002,0x9F01,0x9F00,0xA004,0xA002,0x9EFF,0x9EFD,0xA002,0x9EFA, 0x9EF8,0xA020,0xA010,0xA008,0xA004,0xA002,0x9EF7,0x9EF6,0xA002,0x9EF5,0x9EF4,0xA004,0xA002,0x9EF3,0x9EF2,0xA002, 0x9EF1,0x9EF0,0xA008,0xA004,0xA002,0x9EEE,0x9EED,0xA002,0x9EEC,0x9EEB,0xA004,0xA002,0x9EE8,0x9EE6,0xA002,0x9EE4, 0x9EE3,0xA010,0xA008,0xA004,0xA002,0x9EE1,0x9EDE,0xA002,0x9EDA,0x9ED9,0xA004,0xA002,0x9ED7,0x9ED6,0xA002,0x9ED5, 0x9ED3,0xA008,0xA004,0xA002,0x9ED2,0x9ED0,0xA002,0x9ECC,0x9ECB,0xA004,0xA002,0x9ECA,0x9EC8,0xA002,0x9EC7,0x9EC6, 0xA0C5,0xA02E,0xA000,0xA000,0xA01E,0xA00E,0xA006,0xA002,0x9EC5,0xA002,0x9EC3,0x9EC2,0xA004,0xA002,0x9EC1,0x9EC0, 0xA002,0x9EBF,0x9EBC,0xA008,0xA004,0xA002,0x9EBA,0x9EB9,0xA002,0x9EB7,0x9EB6,0xA004,0xA002,0x9EB5,0x9EB3,0xA002, 0x9EB2,0x9EB1,0xA000,0xA008,0xA004,0xA002,0x9EB0,0x9EAF,0xA002,0x9EAE,0x9EAD,0xA000,0xA002,0x9EAC,0x9EAB,0xA018, 0xA001,0xA001,0xA006,0xA001,0xA001,0xA002,0x9EAA,0x9EA9,0xA008,0xA004,0xA002,0x9EA8,0x9EA7,0xA002,0x9EA5,0x9EA4, 0xA004,0xA002,0x9EA3,0x9EA2,0xA002,0x9EA1,0x9EA0,0xA03F,0xA020,0xA010,0xA008,0xA004,0xA002,0x9E9E,0x9E9C,0xA002, 0x9E9B,0x9E9A,0xA004,0xA002,0x9E99,0x9E98,0xA002,0x9E97,0x9E96,0xA008,0xA004,0xA002,0x9E95,0x9E94,0xA002,0x9E91, 0x9E90,0xA004,0xA002,0x9E8F,0x9E8E,0xA002,0x9E8D,0x9E8C,0xA00F,0xA008,0xA004,0xA002,0x9E8A,0x9E89,0xA002,0x9E86, 0x9E85,0xA004,0xA002,0x9E84,0x9E83,0xA000,0x9E81,0xA008,0xA004,0xA002,0x9E80,0x9E7D,0xA002,0x9E7C,0x9E7B,0xA004, 0xA002,0x9E7A,0x9E79,0xA002,0x9E78,0x9E77,0xA020,0xA010,0xA008,0xA004,0xA002,0x9E76,0x9E75,0xA002,0x9E74,0x9E72, 0xA004,0xA002,0x9E6F,0x9E6E,0xA002,0x9E65,0x9E62,0xA008,0xA004,0xA002,0x9E61,0x9E60,0xA002,0x9E5F,0x9E5D,0xA004, 0xA002,0x9E59,0x9E56,0xA002,0x9E54,0x9E53,0xA010,0xA008,0xA004,0xA002,0x9E52,0x9E50,0xA002,0x9E4D,0x9E40,0xA004, 0xA002,0x9E3C,0x9E3B,0xA002,0x9E34,0x9E30,0xA008,0xA004,0xA002,0x9E2E,0x9E27,0xA002,0x9E24,0x9E1E,0xA004,0xA002, 0x9E1D,0x9E1C,0xA002,0x9E1B,0x9E1A,0xA031,0xA000,0xA000,0xA01E,0xA00E,0xA006,0xA002,0x9E19,0xA002,0x9E18,0x9E17, 0xA004,0xA002,0x9E16,0x9E15,0xA002,0x9E14,0x9E13,0xA008,0xA004,0xA002,0x9E12,0x9E11,0xA002,0x9E10,0x9E0F,0xA004, 0xA002,0x9E0E,0x9E0D,0xA002,0x9E0C,0x9E0B,0xA000,0xA008,0xA004,0xA002,0x9E0A,0x9E09,0xA002,0x9E08,0x9E07,0xA004, 0xA002,0x9E06,0x9E05,0xA002,0x9E04,0x9E03,0xA013,0xA001,0xA001,0xA001,0xA008,0xA004,0xA002,0x9E02,0x9E01,0xA002, 0x9E00,0x9DFF,0xA004,0xA002,0x9DFE,0x9DFD,0xA002,0x9DFC,0x9DFB,0xA03F,0xA020,0xA010,0xA008,0xA004,0xA002,0x9DFA, 0x9DF9,0xA002,0x9DF8,0x9DF7,0xA004,0xA002,0x9DF6,0x9DF5,0xA002,0x9DF4,0x9DF3,0xA008,0xA004,0xA002,0x9DF2,0x9DF1, 0xA002,0x9DF0,0x9DEF,0xA004,0xA002,0x9DEE,0x9DED,0xA002,0x9DEC,0x9DEB,0xA010,0xA008,0xA004,0xA002,0x9DEA,0x9DE9, 0xA002,0x9DE8,0x9DE7,0xA004,0xA002,0x9DE6,0x9DE5,0xA002,0x9DE4,0x9DE3,0xA007,0xA003,0xA000,0x9DE2,0xA002,0x9DE1, 0x9DE0,0xA004,0xA002,0x9DDF,0x9DDE,0xA002,0x9DDD,0x9DDC,0xA020,0xA010,0xA008,0xA004,0xA002,0x9DDB,0x9DDA,0xA002, 0x9DD9,0x9DD8,0xA004,0xA002,0x9DD7,0x9DD6,0xA002,0x9DD5,0x9DD4,0xA008,0xA004,0xA002,0x9DD3,0x9DD2,0xA002,0x9DD1, 0x9DD0,0xA004,0xA002,0x9DCF,0x9DCE,0xA002,0x9DCD,0x9DCC,0xA010,0xA008,0xA004,0xA002,0x9DCB,0x9DCA,0xA002,0x9DC9, 0x9DC8,0xA004,0xA002,0x9DC7,0x9DC6,0xA002,0x9DC5,0x9DC4,0xA008,0xA004,0xA002,0x9DC3,0x9DC2,0xA002,0x9DC1,0x9DC0, 0xA004,0xA002,0x9DBF,0x9DBE,0xA002,0x9DBD,0x9DBC,0xA18A,0xA0C4,0xA036,0xA000,0xA000,0xA01E,0xA00E,0xA006,0xA002, 0x9DBB,0xA002,0x9DBA,0x9DB9,0xA004,0xA002,0x9DB8,0x9DB7,0xA002,0x9DB6,0x9DB5,0xA008,0xA004,0xA002,0x9DB4,0x9DB3, 0xA002,0x9DB2,0x9DB1,0xA004,0xA002,0x9DB0,0x9DAF,0xA002,0x9DAE,0x9DAD,0xA010,0xA008,0xA004,0xA002,0x9DAC,0x9DAB, 0xA002,0x9DAA,0x9DA9,0xA004,0xA002,0x9DA8,0x9DA7,0xA002,0x9DA6,0x9DA5,0xA000,0xA000,0xA002,0x9DA4,0x9DA3,0xA00F, 0xA001,0xA001,0xA001,0xA004,0xA001,0xA001,0x9DA2,0xA004,0xA002,0x9DA1,0x9DA0,0xA002,0x9D9F,0x9D9E,0xA03F,0xA020, 0xA010,0xA008,0xA004,0xA002,0x9D9D,0x9D9C,0xA002,0x9D9B,0x9D9A,0xA004,0xA002,0x9D99,0x9D98,0xA002,0x9D97,0x9D96, 0xA008,0xA004,0xA002,0x9D95,0x9D94,0xA002,0x9D93,0x9D92,0xA004,0xA002,0x9D91,0x9D90,0xA002,0x9D8F,0x9D8E,0xA010, 0xA008,0xA004,0xA002,0x9D8D,0x9D8C,0xA002,0x9D8B,0x9D8A,0xA004,0xA002,0x9D89,0x9D88,0xA002,0x9D87,0x9D86,0xA008, 0xA004,0xA002,0x9D85,0x9D84,0xA002,0x9D83,0x9D82,0xA003,0xA001,0x9D81,0xA002,0x9D80,0x9D7F,0xA020,0xA010,0xA008, 0xA004,0xA002,0x9D7E,0x9D7D,0xA002,0x9D7C,0x9D7B,0xA004,0xA002,0x9D7A,0x9D79,0xA002,0x9D78,0x9D77,0xA008,0xA004, 0xA002,0x9D76,0x9D75,0xA002,0x9D74,0x9D73,0xA004,0xA002,0x9D72,0x9D71,0xA002,0x9D70,0x9D6F,0xA010,0xA008,0xA004, 0xA002,0x9D6E,0x9D6D,0xA002,0x9D6C,0x9D6B,0xA004,0xA002,0x9D6A,0x9D69,0xA002,0x9D68,0x9D67,0xA008,0xA004,0xA002, 0x9D66,0x9D65,0xA002,0x9D64,0x9D63,0xA004,0xA002,0x9D62,0x9D61,0xA002,0x9D60,0x9D5F,0xA03C,0xA000,0xA000,0xA01E, 0xA00E,0xA006,0xA002,0x9D5E,0xA002,0x9D5D,0x9D5C,0xA004,0xA002,0x9D5B,0x9D5A,0xA002,0x9D59,0x9D58,0xA008,0xA004, 0xA002,0x9D57,0x9D56,0xA002,0x9D55,0x9D54,0xA004,0xA002,0x9D53,0x9D52,0xA002,0x9D51,0x9D50,0xA010,0xA008,0xA004, 0xA002,0x9D4F,0x9D4E,0xA002,0x9D4D,0x9D4C,0xA004,0xA002,0x9D4B,0x9D4A,0xA002,0x9D49,0x9D48,0xA008,0xA004,0xA002, 0x9D47,0x9D46,0xA002,0x9D45,0x9D44,0xA000,0xA000,0x9D43,0xA00B,0xA001,0xA001,0xA001,0xA001,0xA003,0xA001,0x9D42, 0xA002,0x9D41,0x9D40,0xA03F,0xA020,0xA010,0xA008,0xA004,0xA002,0x9D3F,0x9D3E,0xA002,0x9D3D,0x9D3C,0xA004,0xA002, 0x9D3B,0x9D3A,0xA002,0x9D39,0x9D38,0xA008,0xA004,0xA002,0x9D37,0x9D36,0xA002,0x9D35,0x9D34,0xA004,0xA002,0x9D33, 0x9D32,0xA002,0x9D31,0x9D30,0xA010,0xA008,0xA004,0xA002,0x9D2F,0x9D2E,0xA002,0x9D2D,0x9D2C,0xA004,0xA002,0x9D2B, 0x9D2A,0xA002,0x9D29,0x9D28,0xA008,0xA004,0xA002,0x9D27,0x9D26,0xA002,0x9D25,0x9D24,0xA004,0xA002,0x9D23,0x9D22, 0xA001,0x9D21,0xA020,0xA010,0xA008,0xA004,0xA002,0x9D20,0x9D1F,0xA002,0x9D1E,0x9D1D,0xA004,0xA002,0x9D1C,0x9D1B, 0xA002,0x9D1A,0x9D19,0xA008,0xA004,0xA002,0x9D18,0x9D17,0xA002,0x9D16,0x9D15,0xA004,0xA002,0x9D14,0x9D13,0xA002, 0x9D12,0x9D11,0xA010,0xA008,0xA004,0xA002,0x9D10,0x9D0F,0xA002,0x9D0E,0x9D0D,0xA004,0xA002,0x9D0C,0x9D0B,0xA002, 0x9D0A,0x9D09,0xA008,0xA004,0xA002,0x9D08,0x9D07,0xA002,0x9D06,0x9D05,0xA004,0xA002,0x9D04,0x9D03,0xA002,0x9D02, 0x9D01,0xA17C,0xA07F,0xA03E,0xA000,0xA01E,0xA00E,0xA006,0xA002,0x9D00,0xA002,0x9CFF,0x9CFE,0xA004,0xA002,0x9CFD, 0x9CFC,0xA002,0x9CFB,0x9CFA,0xA008,0xA004,0xA002,0x9CF9,0x9CF8,0xA002,0x9CF7,0x9CF6,0xA004,0xA002,0x9CF5,0x9CF4, 0xA002,0x9CF3,0x9CF2,0xA010,0xA008,0xA004,0xA002,0x9CF1,0x9CF0,0xA002,0x9CEF,0x9CEE,0xA004,0xA002,0x9CED,0x9CEC, 0xA002,0x9CEB,0x9CEA,0xA008,0xA004,0xA002,0x9CE9,0x9CE8,0xA002,0x9CE7,0x9CE6,0xA004,0xA002,0x9CE5,0x9CE4,0xA000, 0x9CE3,0xA001,0xA020,0xA010,0xA008,0xA004,0xA002,0x9F44,0x9F3E,0xA002,0x9F3D,0x9F37,0xA004,0xA002,0x9F39,0x9F2F, 0xA002,0x9F2C,0x9F22,0xA008,0xA004,0xA002,0x9EEF,0x9EEA,0xA002,0x9EE5,0x9EE7,0xA004,0xA002,0x9EE9,0x9EE2,0xA002, 0x9EDF,0x9EE0,0xA010,0xA008,0xA004,0xA002,0x9EDD,0x9EDC,0xA002,0x9EDB,0x9E9F,0xA004,0xA002,0x9E9D,0x93D6,0xA002, 0x9E92,0x9E8B,0xA008,0xA004,0xA002,0x9E88,0x9E87,0xA002,0x9E82,0x7E3B,0xA004,0xA002,0x9EBE,0x9EBD,0xA002,0x9B23, 0x9B1F,0xA07E,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x9B13,0xA002,0x9B0F,0x9B08,0xA004,0xA002,0x9AF9,0x9AED,0xA002, 0x9AFB,0x9AEB,0xA008,0xA004,0xA002,0x9AEF,0x9AE6,0xA002,0x9AE1,0x9ADF,0xA004,0xA002,0x9954,0x9955,0xA002,0x992E, 0x990D,0xA010,0xA008,0xA004,0xA002,0x98E8,0x9B51,0xA002,0x9B4D,0x9B48,0xA004,0xA002,0x9B49,0x9B47,0xA002,0x9B43, 0x9B45,0xA008,0xA004,0xA002,0x9AD1,0x9ACC,0xA002,0x9ACB,0x9AC2,0xA004,0xA002,0x9AC5,0x9AC0,0xA002,0x9AC1,0x9ABC, 0xA020,0xA010,0xA008,0xA004,0xA002,0x9ABA,0x9AB6,0xA002,0x9E58,0x9AB7,0xA004,0xA002,0x9AB0,0x9AB1,0xA002,0x97B4, 0x97B2,0xA008,0xA004,0xA002,0x97A3,0x97AB,0xA002,0x97AF,0x9794,0xA004,0xA002,0x9792,0x9791,0xA002,0x9785,0x977C, 0xA010,0xA008,0xA004,0xA002,0x9CE2,0x9CDF,0xA002,0x9CDD,0x9CDC,0xA004,0xA002,0x9CD9,0x9CD8,0xA002,0x9CD7,0x9CD5, 0xA008,0xA004,0xA002,0x9CD4,0x9CD3,0xA002,0x9CD0,0x9CCF,0xA004,0xA002,0x9CCE,0x9CCD,0xA002,0x9CCC,0x9CE1,0xA040, 0xA020,0xA010,0xA008,0xA004,0xA002,0x9CE0,0x9CDB,0xA002,0x9CDA,0x9CD2,0xA004,0xA002,0x9CD1,0x9CC9,0xA002,0x9CC8, 0x9CC2,0xA008,0xA004,0xA002,0x9CC1,0x9CC0,0xA002,0x9CBF,0x9CBE,0xA004,0xA002,0x9CB9,0x9CAF,0xA002,0x9CAC,0x9CAA, 0xA010,0xA008,0xA004,0xA002,0x9C9D,0x9C99,0xA002,0x9C98,0x9C97,0xA004,0xA002,0x9C96,0x9C93,0xA002,0x9C8F,0x9C8C, 0xA008,0xA004,0xA002,0x9C8A,0x9C89,0xA002,0x9C84,0x9C83,0xA004,0xA002,0x9C80,0x9C7E,0xA002,0x9C7D,0x9C7B,0xA01F, 0xA00F,0xA007,0xA003,0xA001,0x9C7A,0xA002,0x9C79,0x9C78,0xA004,0xA002,0x9C77,0x9C76,0xA002,0x9C75,0x9C74,0xA008, 0xA004,0xA002,0x9C73,0x9C72,0xA002,0x9C71,0x9C70,0xA004,0xA002,0x9C6F,0x9C6E,0xA002,0x9C6D,0x9C6C,0xA010,0xA008, 0xA004,0xA002,0x9C6B,0x9C6A,0xA002,0x9C69,0x9C68,0xA004,0xA002,0x9C67,0x9C66,0xA002,0x9C65,0x9C64,0xA008,0xA004, 0xA002,0x9C63,0x9C62,0xA002,0x9C61,0x9C60,0xA004,0xA002,0x9C5F,0x9C5E,0xA002,0x9C5D,0x9C5C,0xA083,0xA045,0xA03E, 0xA01E,0xA00E,0xA006,0xA002,0x9C5B,0xA002,0x9C5A,0x9C59,0xA004,0xA002,0x9C58,0x9C57,0xA002,0x9C56,0x9C55,0xA008, 0xA004,0xA002,0x9C54,0x9C53,0xA002,0x9C52,0x9C51,0xA004,0xA002,0x9C50,0x9C4F,0xA002,0x9C4E,0x9C4D,0xA010,0xA008, 0xA004,0xA002,0x9C4C,0x9C4B,0xA002,0x9C4A,0x9C49,0xA004,0xA002,0x9C48,0x9C47,0xA002,0x9C46,0x9C45,0xA008,0xA004, 0xA002,0x9C44,0x9C43,0xA002,0x9C42,0x9C41,0xA004,0xA002,0x9C40,0x9C3F,0xA002,0x9C3E,0x9C3D,0xA000,0xA000,0xA000, 0xA000,0xA000,0x9C3C,0xA001,0xA01D,0xA00D,0xA005,0xA001,0xA002,0x9CCB,0x9CCA,0xA004,0xA002,0x9CC7,0x9CC6,0xA002, 0x9CC5,0x9CC4,0xA008,0xA004,0xA002,0x9CBD,0x9CBC,0xA002,0x9CBB,0x9CBA,0xA004,0xA002,0x9CB7,0x9CB6,0xA002,0x9CB5, 0x9CB4,0xA010,0xA008,0xA004,0xA002,0x9CB3,0x9CB2,0xA002,0x9CB1,0x9CB0,0xA004,0xA002,0x9CAE,0x9CAD,0xA002,0x9CAB, 0x9CA9,0xA008,0xA004,0xA002,0x9CA8,0x9CA7,0xA002,0x9CA6,0x9CA5,0xA004,0xA002,0x9CA3,0x9CA2,0xA002,0x9CA1,0x9CA0, 0xA07E,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x9C9F,0xA002,0x9C9E,0x9C9B,0xA004,0xA002,0x9C9A,0x9C95,0xA002,0x9C94, 0x9C92,0xA008,0xA004,0xA002,0x9C91,0x9C90,0xA002,0x9C8E,0x9C8B,0xA004,0xA002,0x7A23,0x9C88,0xA002,0x9C87,0x9C86, 0xA010,0xA008,0xA004,0xA002,0x9C85,0x9C82,0xA002,0x9C7F,0x946B,0xA004,0xA002,0x943E,0x938F,0xA002,0x93CA,0x936A, 0xA008,0xA004,0xA002,0x933E,0x92C8,0xA002,0x92AE,0x928E,0xA004,0xA002,0x96E0,0x77BF,0xA002,0x96D2,0x96CE,0xA020, 0xA010,0xA008,0xA004,0xA002,0x96BD,0x96BC,0xA002,0x96B9,0x9F0D,0xA004,0xA002,0x9F0B,0x9EFE,0xA002,0x9F8C,0x9F8A, 0xA008,0xA004,0xA002,0x9F89,0x9F88,0xA002,0x9F87,0x9F86,0xA004,0xA002,0x9F85,0x9F83,0xA002,0x9F80,0x973E,0xA010, 0xA008,0xA004,0xA002,0x9730,0x972D,0xA002,0x972A,0x970E,0xA004,0xA002,0x970F,0x9708,0xA002,0x9701,0x9706,0xA008, 0xA004,0xA002,0x96EF,0x96F3,0xA002,0x96E9,0x9753,0xA004,0xA002,0x8B26,0x8A3E,0xA002,0x89EF,0x89EB,0xA040,0xA020, 0xA010,0xA008,0xA004,0xA002,0x89E5,0x9C3B,0xA002,0x9C3A,0x9C39,0xA004,0xA002,0x9C38,0x9C37,0xA002,0x9C36,0x9C35, 0xA008,0xA004,0xA002,0x9C34,0x9C33,0xA002,0x9C32,0x9C31,0xA004,0xA002,0x9C30,0x9C2F,0xA002,0x9C2E,0x9C2D,0xA010, 0xA008,0xA004,0xA002,0x9C2C,0x9C2B,0xA002,0x9C2A,0x9C29,0xA004,0xA002,0x9C28,0x9C27,0xA002,0x9C26,0x9C25,0xA008, 0xA004,0xA002,0x9C24,0x9C23,0xA002,0x9C22,0x9C21,0xA004,0xA002,0x9C20,0x9C1F,0xA002,0x9C1E,0x9C1D,0xA01F,0xA00F, 0xA007,0xA004,0xA002,0x9C1C,0x9C1B,0xA001,0x9C1A,0xA004,0xA002,0x9C19,0x9C18,0xA002,0x9C17,0x9C16,0xA008,0xA004, 0xA002,0x9C15,0x9C14,0xA002,0x9C13,0x9C12,0xA004,0xA002,0x9C11,0x9C10,0xA002,0x9C0F,0x9C0E,0xA010,0xA008,0xA004, 0xA002,0x9C0D,0x9C0C,0xA002,0x9C0B,0x9C0A,0xA004,0xA002,0x9C09,0x9C08,0xA002,0x9C07,0x9C06,0xA008,0xA004,0xA002, 0x9C05,0x9C04,0xA002,0x9C03,0x9C02,0xA004,0xA002,0x9C01,0x9C00,0xA002,0x9BFF,0x9BFE,0xA5FC,0xA2FE,0xA17E,0xA081, 0xA048,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x9BFD,0xA002,0x9BFC,0x9BFB,0xA004,0xA002,0x9BFA,0x9BF9,0xA002,0x9BF8, 0x9BF7,0xA008,0xA004,0xA002,0x9BF6,0x9BF5,0xA002,0x9BF4,0x9BF3,0xA004,0xA002,0x9BF2,0x9BF1,0xA002,0x9BF0,0x9BEF, 0xA010,0xA008,0xA004,0xA002,0x9BEE,0x9BED,0xA002,0x9BEC,0x9BEB,0xA004,0xA002,0x9BEA,0x9BE9,0xA002,0x9BE8,0x9BE7, 0xA008,0xA004,0xA002,0x9BE6,0x9BE5,0xA002,0x9BE4,0x9BE3,0xA004,0xA002,0x9BE2,0x9BE1,0xA002,0x9BE0,0x9BDF,0xA000, 0xA000,0xA000,0xA004,0xA002,0x9BDE,0x9BDD,0xA000,0x9BDC,0xA001,0xA018,0xA008,0xA001,0xA003,0xA001,0x89DC,0xA002, 0x89DA,0x89DE,0xA008,0xA004,0xA002,0x89D6,0x659B,0xA002,0x8C94,0x8C98,0xA004,0xA002,0x8C85,0x8C8A,0xA002,0x8C82, 0x8C78,0xA010,0xA008,0xA004,0xA002,0x8E9E,0x8E9C,0xA002,0x8E90,0x8E94,0xA004,0xA002,0x8E8F,0x8E85,0xA002,0x8E74, 0x8E6F,0xA008,0xA004,0xA002,0x8E7C,0x8E76,0xA002,0x8E70,0x8E4A,0xA004,0xA002,0x8E52,0x8E51,0xA002,0x8E42,0x8E41, 0xA07E,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x8E49,0xA002,0x8E31,0x8E3D,0xA004,0xA002,0x8E35,0x8E39,0xA002,0x8E40, 0x8E3A,0xA008,0xA004,0xA002,0x8E2F,0x8E23,0xA002,0x8E2E,0x8E2C,0xA004,0xA002,0x8E1F,0x8E1D,0xA002,0x8E14,0x8DFD, 0xA010,0xA008,0xA004,0xA002,0x8E09,0x8DE4,0xA002,0x8DFB,0x8DF9,0xA004,0xA002,0x8DE3,0x8DF8,0xA002,0x8DF7,0x8DEC, 0xA008,0xA004,0xA002,0x8DC6,0x8DDB,0xA002,0x8DCF,0x8DCE,0xA004,0xA002,0x8DDE,0x8DDA,0xA002,0x8DD7,0x8DD6,0xA020, 0xA010,0xA008,0xA004,0xA002,0x8DC4,0x8DBA,0xA002,0x8DBC,0x8DBF,0xA004,0xA002,0x8DB5,0x8E69,0xA002,0x8E59,0x8E05, 0xA008,0xA004,0xA002,0x8DEB,0x8DB8,0xA002,0x9E7E,0x8C55,0xA004,0xA002,0x91BA,0x91B4,0xA002,0x91B5,0x91AF,0xA010, 0xA008,0xA004,0xA002,0x91AE,0x91AD,0xA002,0x91AA,0x91A3,0xA004,0xA002,0x91A2,0x9191,0xA002,0x918D,0x9190,0xA008, 0xA004,0xA002,0x9185,0x918C,0xA002,0x9179,0x9174,0xA004,0xA002,0x9172,0x917E,0xA002,0x917D,0x916F,0xA040,0xA020, 0xA010,0xA008,0xA004,0xA002,0x9169,0x9170,0xA002,0x9161,0x9162,0xA004,0xA002,0x9BDB,0x9BDA,0xA002,0x9BD9,0x9BD8, 0xA008,0xA004,0xA002,0x9BD7,0x9BD6,0xA002,0x9BD5,0x9BD4,0xA004,0xA002,0x9BD3,0x9BD2,0xA002,0x9BD1,0x9BD0,0xA010, 0xA008,0xA004,0xA002,0x9BCF,0x9BCE,0xA002,0x9BCD,0x9BCC,0xA004,0xA002,0x9BCB,0x9BCA,0xA002,0x9BC9,0x9BC8,0xA008, 0xA004,0xA002,0x9BC7,0x9BC6,0xA002,0x9BC5,0x9BC4,0xA004,0xA002,0x9BC3,0x9BC2,0xA002,0x9BC1,0x9BC0,0xA01F,0xA00F, 0xA008,0xA004,0xA002,0x9BBF,0x9BBE,0xA002,0x9BBD,0x9BBC,0xA003,0xA000,0x9BBB,0xA002,0x9BBA,0x9BB9,0xA008,0xA004, 0xA002,0x9BB8,0x9BB7,0xA002,0x9BB6,0x9BB5,0xA004,0xA002,0x9BB4,0x9BB3,0xA002,0x9BB2,0x9BB1,0xA010,0xA008,0xA004, 0xA002,0x9BB0,0x9BAF,0xA002,0x9BAE,0x9BAD,0xA004,0xA002,0x9BAC,0x9BAB,0xA002,0x9BAA,0x9BA9,0xA008,0xA004,0xA002, 0x9BA8,0x9BA7,0xA002,0x9BA6,0x9BA5,0xA004,0xA002,0x9BA4,0x9BA3,0xA002,0x9BA2,0x9BA1,0xA083,0xA04D,0xA03E,0xA01E, 0xA00E,0xA006,0xA002,0x9BA0,0xA002,0x9B9F,0x9B9E,0xA004,0xA002,0x9B9D,0x9B9C,0xA002,0x9B9B,0x9B9A,0xA008,0xA004, 0xA002,0x9B99,0x9B98,0xA002,0x9B97,0x9B96,0xA004,0xA002,0x9B95,0x9B94,0xA002,0x9B93,0x9B92,0xA010,0xA008,0xA004, 0xA002,0x9B91,0x9B90,0xA002,0x9B8F,0x9B8E,0xA004,0xA002,0x9B8D,0x9B8C,0xA002,0x9B8B,0x9B8A,0xA008,0xA004,0xA002, 0x9B89,0x9B88,0xA002,0x9B87,0x9B86,0xA004,0xA002,0x9B85,0x9B84,0xA002,0x9B83,0x9B82,0xA000,0xA000,0xA008,0xA004, 0xA002,0x9B81,0x9B80,0xA002,0x9B7F,0x9B7E,0xA000,0xA002,0x9B7D,0x9B7C,0xA001,0xA015,0xA005,0xA001,0xA001,0xA001, 0x9164,0xA008,0xA004,0xA002,0x914F,0x914E,0xA002,0x9150,0x914A,0xA004,0xA002,0x8C49,0x8C47,0xA002,0x8D6D,0x8D67, 0xA010,0xA008,0xA004,0xA002,0x8DB1,0x8D91,0xA002,0x8D94,0x8D84,0xA004,0xA002,0x8D73,0x9EB4,0xA002,0x9EB8,0x7E9B, 0xA008,0xA004,0xA002,0x7E47,0x7DAE,0xA002,0x7DA6,0x7D77,0xA004,0xA002,0x7CF8,0x7FF3,0xA002,0x7FEE,0x7FE9,0xA07E, 0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x7FE6,0xA002,0x7FE1,0x7FE5,0xA004,0xA002,0x7FD5,0x7FCE,0xA002,0x7FBF,0x66A8, 0xA008,0xA004,0xA002,0x826E,0x7CE8,0xA002,0x7CD7,0x7CC5,0xA004,0xA002,0x7CC8,0x7CCD,0xA002,0x7CCC,0x7CC7,0xA010, 0xA008,0xA004,0xA002,0x7CC1,0x7CBD,0xA002,0x7CBC,0x7CB2,0xA004,0xA002,0x7CA2,0x7C9E,0xA002,0x7C9C,0x7C9D,0xA008, 0xA004,0xA002,0x7C91,0x6549,0xA002,0x7C7C,0x7FB2,0xA004,0xA002,0x7FB0,0x7FAF,0xA002,0x7FA7,0x7F9F,0xA020,0xA010, 0xA008,0xA004,0xA002,0x7F9D,0x895E,0xA002,0x88DF,0x88D8,0xA004,0xA002,0x8888,0x8885,0xA002,0x887E,0x8268,0xA008, 0xA004,0xA002,0x825F,0x825A,0xA002,0x824F,0x824B,0xA004,0xA002,0x8249,0x8244,0xA002,0x823E,0x8234,0xA010,0xA008, 0xA004,0xA002,0x8233,0x823B,0xA002,0x8238,0x822B,0xA004,0xA002,0x8228,0x822F,0xA002,0x822D,0x8223,0xA008,0xA004, 0xA002,0x8222,0x8221,0xA002,0x8844,0x81EC,0xA004,0xA002,0x8204,0x8202,0xA002,0x8201,0x81FE,0xA040,0xA020,0xA010, 0xA008,0xA004,0xA002,0x7C40,0x7C41,0xA002,0x7C38,0x7C26,0xA004,0xA002,0x7C2A,0x7C1F,0xA002,0x9B7B,0x9B7A,0xA008, 0xA004,0xA002,0x9B79,0x9B78,0xA002,0x9B77,0x9B76,0xA004,0xA002,0x9B75,0x9B74,0xA002,0x9B73,0x9B72,0xA010,0xA008, 0xA004,0xA002,0x9B71,0x9B70,0xA002,0x9B6F,0x9B6E,0xA004,0xA002,0x9B6D,0x9B6C,0xA002,0x9B6B,0x9B6A,0xA008,0xA004, 0xA002,0x9B69,0x9B68,0xA002,0x9B67,0x9B66,0xA004,0xA002,0x9B65,0x9B64,0xA002,0x9B63,0x9B62,0xA01F,0xA00F,0xA008, 0xA004,0xA002,0x9B61,0x9B60,0xA002,0x9B5F,0x9B5E,0xA004,0xA002,0x9B5D,0x9B5C,0xA000,0x9B5B,0xA008,0xA004,0xA002, 0x9B5A,0x9B59,0xA002,0x9B58,0x9B57,0xA004,0xA002,0x9B56,0x9B55,0xA002,0x9B53,0x9B52,0xA010,0xA008,0xA004,0xA002, 0x9B50,0x9B4E,0xA002,0x9B4C,0x9B4B,0xA004,0xA002,0x9B4A,0x9B46,0xA002,0x9B40,0x9B3F,0xA008,0xA004,0xA002,0x9B3E, 0x9B3D,0xA002,0x9B3A,0x9B39,0xA004,0xA002,0x9B38,0x9B37,0xA002,0x9B36,0x9B35,0xA17E,0xA081,0xA050,0xA03E,0xA01E, 0xA00E,0xA006,0xA002,0x9B34,0xA002,0x9B33,0x9B31,0xA004,0xA002,0x9B30,0x9B2E,0xA002,0x9B2D,0x9B2C,0xA008,0xA004, 0xA002,0x9B2B,0x9B2A,0xA002,0x9B29,0x9B28,0xA004,0xA002,0x9B27,0x9B26,0xA002,0x9B25,0x9B24,0xA010,0xA008,0xA004, 0xA002,0x9B22,0x9B21,0xA002,0x9B20,0x9B1E,0xA004,0xA002,0x9B1D,0x9B1C,0xA002,0x9B1B,0x9B1A,0xA008,0xA004,0xA002, 0x9B19,0x9B18,0xA002,0x9B17,0x9B16,0xA004,0xA002,0x9B15,0x9B14,0xA002,0x9B12,0x9B11,0xA000,0xA000,0xA008,0xA004, 0xA002,0x9B10,0x9B0E,0xA002,0x9B0D,0x9B0C,0xA004,0xA002,0x9B0B,0x9B0A,0xA002,0x9B09,0x9B07,0xA001,0xA010,0xA001, 0xA007,0xA003,0xA001,0x7C0B,0xA002,0x7C16,0x7C0F,0xA004,0xA002,0x7BFC,0x7BFE,0xA002,0x7C0C,0x7BEA,0xA010,0xA008, 0xA004,0xA002,0x7BE6,0x7BE5,0xA002,0x7BDA,0x7BDD,0xA004,0xA002,0x7BCC,0x7BC1,0xA002,0x7BD1,0x7BB4,0xA008,0xA004, 0xA002,0x7BAB,0x7BA2,0xA002,0x7B9C,0x7BAA,0xA004,0xA002,0x7B85,0x7BA8,0xA002,0x7B9D,0x7BAC,0xA07E,0xA03E,0xA01E, 0xA00E,0xA006,0xA002,0x7BB8,0xA002,0x7BA7,0x7BA6,0xA004,0xA002,0x7B90,0x7B71,0xA002,0x7B72,0x7B62,0xA008,0xA004, 0xA002,0x7B7B,0x7B6E,0xA002,0x7B60,0x7B5D,0xA004,0xA002,0x7B4C,0x7B75,0xA002,0x7B45,0x7B5A,0xA010,0xA008,0xA004, 0xA002,0x7B58,0x7B1E,0xA002,0x7B3E,0x7B33,0xA004,0xA002,0x7B24,0x7B25,0xA002,0x7B20,0x7B31,0xA008,0xA004,0xA002, 0x7B2E,0x7B19,0xA002,0x7B2A,0x7B38,0xA004,0xA002,0x7B47,0x7B0F,0xA002,0x7B2B,0x7B0A,0xA020,0xA010,0xA008,0xA004, 0xA002,0x7B15,0x7B04,0xA002,0x7B03,0x7B08,0xA004,0xA002,0x7AFD,0x7AFA,0xA002,0x8210,0x7F45,0xA008,0xA004,0xA002, 0x7F44,0x7F42,0xA002,0x7F36,0x883C,0xA004,0xA002,0x8839,0x8821,0xA002,0x881B,0x880A,0xA010,0xA008,0xA004,0xA002, 0x87FE,0x8813,0xA002,0x8816,0x87EE,0xA004,0xA002,0x87E0,0x87EA,0xA002,0x87DB,0x87CA,0xA008,0xA004,0xA002,0x87C0, 0x87D1,0xA002,0x87BD,0x87D3,0xA004,0xA002,0x87CB,0x87B3,0xA002,0x87B5,0x87AC,0xA040,0xA020,0xA010,0xA008,0xA004, 0xA002,0x87E5,0x87AB,0xA002,0x8783,0x8797,0xA004,0xA002,0x87AD,0x8785,0xA002,0x8788,0x87C6,0xA008,0xA004,0xA002, 0x9B06,0x9B05,0xA002,0x9B04,0x9B02,0xA004,0xA002,0x9B01,0x9B00,0xA002,0x9AFF,0x9AFE,0xA010,0xA008,0xA004,0xA002, 0x9AFD,0x9AFC,0xA002,0x9AFA,0x9AF8,0xA004,0xA002,0x9AF7,0x9AF6,0xA002,0x9AF5,0x9AF4,0xA008,0xA004,0xA002,0x9AF3, 0x9AF2,0xA002,0x9AF1,0x9AF0,0xA004,0xA002,0x9AEE,0x9AEC,0xA002,0x9AEA,0x9AE9,0xA01F,0xA010,0xA008,0xA004,0xA002, 0x9AE8,0x9AE7,0xA002,0x9AE5,0x9AE4,0xA004,0xA002,0x9AE3,0x9AE2,0xA002,0x9AE0,0x9ADE,0xA007,0xA003,0xA000,0x9ADD, 0xA002,0x9ADC,0x9ADB,0xA004,0xA002,0x9ADA,0x9AD9,0xA002,0x9AD7,0x9AD6,0xA010,0xA008,0xA004,0xA002,0x9AD5,0x9AD4, 0xA002,0x9AD2,0x9AD0,0xA004,0xA002,0x9ACF,0x9ACE,0xA002,0x9ACD,0x9ACA,0xA008,0xA004,0xA002,0x9AC9,0x9AC8,0xA002, 0x9AC7,0x9AC6,0xA004,0xA002,0x9AC4,0x9AC3,0xA002,0x9ABF,0x9ABE,0xA083,0xA055,0xA03E,0xA01E,0xA00E,0xA006,0xA002, 0x9ABD,0xA002,0x9ABB,0x9AB9,0xA004,0xA002,0x9AB5,0x9AB4,0xA002,0x9AB3,0x9AB2,0xA008,0xA004,0xA002,0x9AAF,0x9AAE, 0xA002,0x9AAD,0x9AAC,0xA004,0xA002,0x9AAB,0x9AAA,0xA002,0x9AA9,0x9AA6,0xA010,0xA008,0xA004,0xA002,0x9A99,0x9A95, 0xA002,0x9A94,0x9A8E,0xA004,0xA002,0x9A8D,0x9A89,0xA002,0x9A83,0x9A72,0xA008,0xA004,0xA002,0x9A6B,0x9A6A,0xA002, 0x9A69,0x9A68,0xA004,0xA002,0x9A67,0x9A66,0xA002,0x9A65,0x9A64,0xA000,0xA010,0xA008,0xA004,0xA002,0x9A63,0x9A62, 0xA002,0x9A61,0x9A60,0xA004,0xA002,0x9A5F,0x9A5E,0xA002,0x9A5D,0x9A5C,0xA000,0xA000,0xA002,0x9A5B,0x9A5A,0xA001, 0xA00D,0xA001,0xA004,0xA001,0xA001,0x87D2,0xA004,0xA002,0x87A8,0x87AF,0xA002,0x8793,0x8765,0xA010,0xA008,0xA004, 0xA002,0x8759,0x8764,0xA002,0x877C,0x8763,0xA004,0xA002,0x8753,0x878B,0xA002,0x876E,0x874C,0xA008,0xA004,0xA002, 0x8770,0x8760,0xA002,0x877B,0x877E,0xA004,0xA002,0x877D,0x8722,0xA002,0x8782,0x873F,0xA07E,0xA03E,0xA01E,0xA00E, 0xA006,0xA002,0x8737,0xA002,0x8729,0x8731,0xA004,0xA002,0x8734,0x8748,0xA002,0x873E,0x871A,0xA008,0xA004,0xA002, 0x872E,0x8725,0xA002,0x871E,0x873B,0xA004,0xA002,0x8723,0x8709,0xA002,0x870D,0x870A,0xA010,0xA008,0xA004,0xA002, 0x8708,0x86F8,0xA002,0x8707,0x8703,0xA004,0xA002,0x86D1,0x86D8,0xA002,0x86DF,0x86F4,0xA008,0xA004,0xA002,0x86DE, 0x8713,0xA002,0x86D0,0x86F3,0xA004,0xA002,0x86ED,0x86F2,0xA002,0x86F1,0x86E9,0xA020,0xA010,0xA008,0xA004,0xA002, 0x86B4,0x86CF,0xA002,0x86C9,0x86AF,0xA004,0xA002,0x86B1,0x86BA,0xA002,0x86B0,0x86CE,0xA008,0xA004,0xA002,0x86B5, 0x86C4,0xA002,0x86B6,0x86A9,0xA004,0xA002,0x8693,0x86AA,0xA002,0x86A3,0x86A7,0xA010,0xA008,0xA004,0xA002,0x869D, 0x86AC,0xA002,0x868B,0x868D,0xA004,0xA002,0x86A8,0x867B,0xA002,0x867C,0x867A,0xA008,0xA004,0xA002,0x867F,0x866E, 0xA002,0x866C,0x8654,0xA004,0xA002,0x864D,0x98A6,0xA002,0x98A5,0x98A2,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002, 0x98A1,0x989F,0xA002,0x989E,0x989B,0xA004,0xA002,0x989A,0x9894,0xA002,0x988F,0x988D,0xA008,0xA004,0xA002,0x988C, 0x9889,0xA002,0x9A59,0x9A58,0xA004,0xA002,0x9A57,0x9A56,0xA002,0x9A55,0x9A54,0xA010,0xA008,0xA004,0xA002,0x9A53, 0x9A52,0xA002,0x9A51,0x9A50,0xA004,0xA002,0x9A4F,0x9A4E,0xA002,0x9A4D,0x9A4C,0xA008,0xA004,0xA002,0x9A4B,0x9A4A, 0xA002,0x9A49,0x9A48,0xA004,0xA002,0x9A47,0x9A46,0xA002,0x9A45,0x9A44,0xA01F,0xA010,0xA008,0xA004,0xA002,0x9A43, 0x9A42,0xA002,0x9A41,0x9A40,0xA004,0xA002,0x9A3F,0x9A3E,0xA002,0x9A3D,0x9A3C,0xA007,0xA004,0xA002,0x9A3B,0x9A3A, 0xA000,0x9A39,0xA004,0xA002,0x9A38,0x9A37,0xA002,0x9A36,0x9A35,0xA010,0xA008,0xA004,0xA002,0x9A34,0x9A33,0xA002, 0x9A32,0x9A31,0xA004,0xA002,0x9A30,0x9A2F,0xA002,0x9A2E,0x9A2D,0xA008,0xA004,0xA002,0x9A2C,0x9A2B,0xA002,0x9A2A, 0x9A29,0xA004,0xA002,0x9A28,0x9A27,0xA002,0x9A26,0x9A25,0xA2FF,0xA17F,0xA082,0xA058,0xA03E,0xA01E,0xA00E,0xA006, 0xA002,0x9A24,0xA002,0x9A23,0x9A22,0xA004,0xA002,0x9A21,0x9A20,0xA002,0x9A1F,0x9A1E,0xA008,0xA004,0xA002,0x9A1D, 0x9A1C,0xA002,0x9A1B,0x9A1A,0xA004,0xA002,0x9A19,0x9A18,0xA002,0x9A17,0x9A16,0xA010,0xA008,0xA004,0xA002,0x9A15, 0x9A14,0xA002,0x9A13,0x9A12,0xA004,0xA002,0x9A11,0x9A10,0xA002,0x9A0F,0x9A0E,0xA008,0xA004,0xA002,0x9A0D,0x9A0C, 0xA002,0x9A0B,0x9A0A,0xA004,0xA002,0x9A09,0x9A08,0xA002,0x9A07,0x9A06,0xA000,0xA010,0xA008,0xA004,0xA002,0x9A05, 0x9A04,0xA002,0x9A03,0x9A02,0xA004,0xA002,0x9A01,0x9A00,0xA002,0x99FF,0x99FE,0xA000,0xA004,0xA002,0x99FD,0x99FC, 0xA002,0x99FB,0x99FA,0xA001,0xA009,0xA001,0xA001,0xA003,0xA001,0x9883,0xA002,0x9880,0x9878,0xA010,0xA008,0xA004, 0xA002,0x8983,0x8071,0xA002,0x8069,0x8052,0xA004,0xA002,0x804D,0x8046,0xA002,0x8043,0x8035,0xA008,0xA004,0xA002, 0x800B,0x8031,0xA002,0x8028,0x8029,0xA004,0xA002,0x8027,0x8026,0xA002,0x8025,0x8022,0xA07E,0xA03E,0xA01E,0xA00E, 0xA006,0xA002,0x8020,0xA002,0x801C,0x8016,0xA004,0xA002,0x8014,0x8012,0xA002,0x77DC,0x76B4,0xA008,0xA004,0xA002, 0x76B2,0x80E5,0xA002,0x758B,0x897B,0xA004,0xA002,0x8966,0x8941,0xA002,0x8936,0x892B,0xA010,0xA008,0xA004,0xA002, 0x8934,0x890A,0xA002,0x891B,0x8913,0xA004,0xA002,0x8919,0x8921,0xA002,0x88F0,0x88FE,0xA008,0xA004,0xA002,0x88E8, 0x88FC,0xA002,0x891A,0x88F1,0xA004,0xA002,0x88E5,0x88E3,0xA002,0x88CE,0x88E2,0xA020,0xA010,0xA008,0xA004,0xA002, 0x88C9,0x88BC,0xA002,0x88B7,0x88C6,0xA004,0xA002,0x88A2,0x8882,0xA002,0x887F,0x887D,0xA008,0xA004,0xA002,0x8872, 0x8869,0xA002,0x8864,0x7AB3,0xA004,0xA002,0x7AAD,0x7AA8,0xA002,0x7AAC,0x7AA0,0xA010,0xA008,0xA004,0xA002,0x7AA6, 0x7A95,0xA002,0x7A88,0x7A86,0xA004,0xA002,0x7A80,0x7A79,0xA002,0x7A78,0x7AE6,0xA008,0xA004,0xA002,0x7FCA,0x766F, 0xA002,0x766B,0x7656,0xA004,0xA002,0x765C,0x7654,0xA002,0x765E,0x764D,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002, 0x7633,0x763E,0xA002,0x7643,0x7635,0xA004,0xA002,0x763F,0x7630,0xA002,0x762D,0x7640,0xA008,0xA004,0xA002,0x7620, 0x7622,0xA002,0x763C,0x761B,0xA004,0xA002,0x99F9,0x99F8,0xA002,0x99F7,0x99F6,0xA010,0xA008,0xA004,0xA002,0x99F5, 0x99F4,0xA002,0x99F3,0x99F2,0xA004,0xA002,0x99F1,0x99F0,0xA002,0x99EF,0x99EE,0xA008,0xA004,0xA002,0x99ED,0x99EC, 0xA002,0x99EB,0x99EA,0xA004,0xA002,0x99E9,0x99E8,0xA002,0x99E7,0x99E6,0xA01F,0xA010,0xA008,0xA004,0xA002,0x99E5, 0x99E4,0xA002,0x99E3,0x99E2,0xA004,0xA002,0x99E1,0x99E0,0xA002,0x99DF,0x99DE,0xA008,0xA004,0xA002,0x99DD,0x99DC, 0xA002,0x99DB,0x99DA,0xA003,0xA000,0x99D9,0xA002,0x99D8,0x99D7,0xA010,0xA008,0xA004,0xA002,0x99D6,0x99D5,0xA002, 0x99D4,0x99D3,0xA004,0xA002,0x99D2,0x99D1,0xA002,0x99D0,0x99CF,0xA008,0xA004,0xA002,0x99CE,0x99CD,0xA002,0x99CC, 0x99CB,0xA004,0xA002,0x99CA,0x99C9,0xA002,0x99C8,0x99C7,0xA083,0xA05C,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x99C6, 0xA002,0x99C5,0x99C4,0xA004,0xA002,0x99C3,0x99C2,0xA002,0x99C1,0x99C0,0xA008,0xA004,0xA002,0x99BF,0x99BE,0xA002, 0x99BD,0x99BC,0xA004,0xA002,0x99BB,0x99BA,0xA002,0x99B9,0x99B8,0xA010,0xA008,0xA004,0xA002,0x99B7,0x99B6,0xA002, 0x99B5,0x99B4,0xA004,0xA002,0x99B3,0x99B2,0xA002,0x99B1,0x99B0,0xA008,0xA004,0xA002,0x99AF,0x99AE,0xA002,0x99AD, 0x99AC,0xA004,0xA002,0x99AB,0x99AA,0xA002,0x99A9,0x99A7,0xA000,0xA010,0xA008,0xA004,0xA002,0x99A6,0x99A4,0xA002, 0x99A3,0x99A2,0xA004,0xA002,0x99A1,0x99A0,0xA002,0x999F,0x999E,0xA008,0xA004,0xA002,0x999D,0x999C,0xA002,0x999B, 0x999A,0xA000,0xA002,0x998E,0x998C,0xA001,0xA006,0xA001,0xA001,0xA001,0xA001,0x7619,0xA010,0xA008,0xA004,0xA002, 0x7615,0x7618,0xA002,0x7625,0x760A,0xA004,0xA002,0x7617,0x760C,0xA002,0x7605,0x7600,0xA008,0xA004,0xA002,0x7610, 0x75FF,0xA002,0x75FC,0x75F1,0xA004,0xA002,0x7603,0x75E7,0xA002,0x75EB,0x75E4,0xA07E,0xA03E,0xA01E,0xA00E,0xA006, 0xA002,0x75E6,0xA002,0x75E8,0x75E3,0xA004,0xA002,0x75CD,0x75D6,0xA002,0x75C2,0x75C3,0xA008,0xA004,0xA002,0x75B0, 0x75B1,0xA002,0x75C4,0x75B8,0xA004,0xA002,0x75B4,0x75B3,0xA002,0x75A3,0x75AC,0xA010,0xA008,0xA004,0xA002,0x759D, 0x75A0,0xA002,0x7596,0x7594,0xA004,0xA002,0x7592,0x9E73,0xA002,0x9E6D,0x9E71,0xA008,0xA004,0xA002,0x9E6C,0x9E6B, 0xA002,0x9E6A,0x9E69,0xA004,0xA002,0x9E68,0x9E67,0xA002,0x9E66,0x9E63,0xA020,0xA010,0xA008,0xA004,0xA002,0x9E5E, 0x9E5C,0xA002,0x9E5B,0x9E5A,0xA004,0xA002,0x9E57,0x9E55,0xA002,0x9E51,0x9E4E,0xA008,0xA004,0xA002,0x9E4C,0x9E4B, 0xA002,0x9E49,0x9E48,0xA004,0xA002,0x9E47,0x9E46,0xA002,0x9E44,0x9E42,0xA010,0xA008,0xA004,0xA002,0x9E41,0x9E3E, 0xA002,0x9E3A,0x9E39,0xA004,0xA002,0x9E37,0x9E38,0xA002,0x9E36,0x9E31,0xA008,0xA004,0xA002,0x9E32,0x9E2C,0xA002, 0x9E2B,0x9E2A,0xA004,0xA002,0x9E29,0x9E28,0xA002,0x9E22,0x9E20,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x752C, 0x74E0,0xA002,0x74DE,0x76A4,0xA004,0xA002,0x7699,0x7693,0xA002,0x768E,0x7688,0xA008,0xA004,0xA002,0x7A70,0x99A5, 0xA002,0x9ECF,0x7A51,0xA004,0xA002,0x7A37,0x7A39,0xA002,0x9989,0x9983,0xA010,0xA008,0xA004,0xA002,0x9982,0x997E, 0xA002,0x997B,0x9979,0xA004,0xA002,0x9978,0x9973,0xA002,0x9966,0x9964,0xA008,0xA004,0xA002,0x9962,0x9961,0xA002, 0x9960,0x995F,0xA004,0xA002,0x995E,0x995D,0xA002,0x995C,0x995B,0xA01F,0xA010,0xA008,0xA004,0xA002,0x995A,0x9959, 0xA002,0x9958,0x9957,0xA004,0xA002,0x9956,0x9953,0xA002,0x9952,0x9951,0xA008,0xA004,0xA002,0x9950,0x994F,0xA002, 0x994E,0x994D,0xA004,0xA002,0x994C,0x994B,0xA000,0x994A,0xA010,0xA008,0xA004,0xA002,0x9949,0x9948,0xA002,0x9947, 0x9946,0xA004,0xA002,0x9945,0x9944,0xA002,0x9943,0x9942,0xA008,0xA004,0xA002,0x9941,0x9940,0xA002,0x993F,0x993E, 0xA004,0xA002,0x993D,0x993C,0xA002,0x993B,0x993A,0xA17D,0xA080,0xA05F,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x9939, 0xA002,0x9938,0x9937,0xA004,0xA002,0x9936,0x9935,0xA002,0x9934,0x9933,0xA008,0xA004,0xA002,0x9932,0x9931,0xA002, 0x9930,0x992F,0xA004,0xA002,0x992D,0x992C,0xA002,0x992B,0x992A,0xA010,0xA008,0xA004,0xA002,0x9929,0x9928,0xA002, 0x9927,0x9926,0xA004,0xA002,0x9925,0x9924,0xA002,0x9923,0x9922,0xA008,0xA004,0xA002,0x9921,0x9920,0xA002,0x991F, 0x991E,0xA004,0xA002,0x991D,0x991C,0xA002,0x991B,0x991A,0xA000,0xA010,0xA008,0xA004,0xA002,0x9919,0x9918,0xA002, 0x9917,0x9916,0xA004,0xA002,0x9915,0x9914,0xA002,0x9913,0x9912,0xA008,0xA004,0xA002,0x9911,0x990F,0xA002,0x990E, 0x990C,0xA004,0xA002,0x990B,0x990A,0xA002,0x9909,0x9908,0xA001,0xA001,0xA00F,0xA007,0xA003,0xA001,0x7A14,0xA002, 0x7A1E,0x7A02,0xA004,0xA002,0x7A03,0x5D47,0xA002,0x7A06,0x79EB,0xA008,0xA004,0xA002,0x79E3,0x79ED,0xA002,0x79D5, 0x96C9,0xA004,0xA002,0x77EC,0x77E7,0xA002,0x953A,0x9573,0xA07E,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x9572,0xA002, 0x9571,0x956F,0xA004,0xA002,0x956C,0x956B,0xA002,0x956A,0x9569,0xA008,0xA004,0xA002,0x9568,0x9567,0xA002,0x9566, 0x9565,0xA004,0xA002,0x9564,0x9562,0xA002,0x9561,0x955D,0xA010,0xA008,0xA004,0xA002,0x955F,0x955E,0xA002,0x955B, 0x9559,0xA004,0xA002,0x9558,0x9557,0xA002,0x9556,0x9554,0xA008,0xA004,0xA002,0x9553,0x9552,0xA002,0x954F,0x954E, 0xA004,0xA002,0x954C,0x9549,0xA002,0x9546,0x9545,0xA020,0xA010,0xA008,0xA004,0xA002,0x9544,0x9535,0xA002,0x9542, 0x953F,0xA004,0xA002,0x953E,0x953C,0xA002,0x9538,0x9537,0xA008,0xA004,0xA002,0x9536,0x9534,0xA002,0x9532,0x9531, 0xA004,0xA002,0x952C,0x9529,0xA002,0x952B,0x952A,0xA010,0xA008,0xA004,0xA002,0x9522,0x951F,0xA002,0x951E,0x951D, 0xA004,0xA002,0x951B,0x9518,0xA002,0x9516,0x9515,0xA008,0xA004,0xA002,0x9514,0x9513,0xA002,0x9512,0x950F,0xA004, 0xA002,0x950E,0x950D,0xA002,0x950A,0x9509,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x9507,0x9506,0xA002,0x9502, 0x9503,0xA004,0xA002,0x94FF,0x94FD,0xA002,0x94FC,0x94F9,0xA008,0xA004,0xA002,0x94F7,0x94F5,0xA002,0x94F4,0x94F3, 0xA004,0xA002,0x94EF,0x94EE,0xA002,0x94EB,0x94E9,0xA010,0xA008,0xA004,0xA002,0x9907,0x9906,0xA002,0x9905,0x9904, 0xA004,0xA002,0x9903,0x9902,0xA002,0x9901,0x9900,0xA008,0xA004,0xA002,0x98FF,0x98FE,0xA002,0x98FD,0x98FC,0xA004, 0xA002,0x98FB,0x98FA,0xA002,0x98F9,0x98F8,0xA020,0xA010,0xA008,0xA004,0xA002,0x98F7,0x98F6,0xA002,0x98F5,0x98F4, 0xA004,0xA002,0x98F3,0x98F2,0xA002,0x98F1,0x98F0,0xA008,0xA004,0xA002,0x98EF,0x98EE,0xA002,0x98ED,0x98EC,0xA004, 0xA002,0x98EB,0x98EA,0xA002,0x98E9,0x98E6,0xA00F,0xA007,0xA003,0xA000,0x98E5,0xA002,0x98E4,0x98E3,0xA004,0xA002, 0x98E2,0x98E1,0xA002,0x98E0,0x98DD,0xA008,0xA004,0xA002,0x98DC,0x98DB,0xA002,0x98D7,0x98D6,0xA004,0xA002,0x98D4, 0x98D0,0xA002,0x98CF,0x98CD,0xA083,0xA065,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x98CC,0xA002,0x98CB,0x98CA,0xA004, 0xA002,0x98C9,0x98C8,0xA002,0x98C7,0x98C6,0xA008,0xA004,0xA002,0x98C5,0x98C4,0xA002,0x98C3,0x98C2,0xA004,0xA002, 0x98C1,0x98C0,0xA002,0x98BF,0x98BE,0xA010,0xA008,0xA004,0xA002,0x98BD,0x98BC,0xA002,0x98BB,0x98BA,0xA004,0xA002, 0x98B9,0x98B8,0xA002,0x98B7,0x98B6,0xA008,0xA004,0xA002,0x98B5,0x98B4,0xA002,0x98B3,0x98B2,0xA004,0xA002,0x98B1, 0x98B0,0xA002,0x98AF,0x98AE,0xA020,0xA010,0xA008,0xA004,0xA002,0x98AD,0x98AC,0xA002,0x98AB,0x98AA,0xA004,0xA002, 0x98A9,0x98A8,0xA002,0x98A3,0x9899,0xA008,0xA004,0xA002,0x9895,0x9892,0xA002,0x988E,0x988B,0xA004,0xA002,0x9874, 0x9873,0xA002,0x9872,0x9871,0xA000,0xA000,0xA000,0xA002,0x9870,0x986F,0xA001,0xA001,0xA00C,0xA004,0xA001,0xA001, 0x94EA,0xA004,0xA002,0x94E8,0x94E7,0xA002,0x94E5,0x94E4,0xA008,0xA004,0xA002,0x94E2,0x94E0,0xA002,0x94DF,0x94DE, 0xA004,0xA002,0x94DB,0x94D8,0xA002,0x94D9,0x94D7,0xA07E,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x94D6,0xA002,0x94D5, 0x94D2,0xA004,0xA002,0x94D1,0x94D0,0xA002,0x94CE,0x94CD,0xA008,0xA004,0xA002,0x94CC,0x94CB,0xA002,0x94CA,0x94C9, 0xA004,0xA002,0x94C8,0x94C4,0xA002,0x94BF,0x94BD,0xA010,0xA008,0xA004,0xA002,0x94BC,0x94BA,0xA002,0x94B9,0x94B8, 0xA004,0xA002,0x94B7,0x94B6,0xA002,0x94B4,0x94B2,0xA008,0xA004,0xA002,0x94B0,0x94AF,0xA002,0x94AC,0x94AD,0xA004, 0xA002,0x94AA,0x94AB,0xA002,0x94A4,0x94A3,0xA020,0xA010,0xA008,0xA004,0xA002,0x949C,0x949B,0xA002,0x949A,0x9495, 0xA004,0xA002,0x9497,0x9494,0xA002,0x9490,0x948F,0xA008,0xA004,0xA002,0x948D,0x948C,0xA002,0x948A,0x948B,0xA004, 0xA002,0x9487,0x9486,0xA002,0x9485,0x8832,0xA010,0xA008,0xA004,0xA002,0x76E5,0x76CD,0xA002,0x7F7E,0x7F81,0xA004, 0xA002,0x7F79,0x7F71,0xA002,0x7F74,0x7F68,0xA008,0xA004,0xA002,0x8A48,0x7F5F,0xA002,0x7F61,0x7F58,0xA004,0xA002, 0x7583,0x7579,0xA002,0x7572,0x755B,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x7548,0x754B,0xA002,0x754E,0x7540, 0xA004,0xA002,0x753A,0x77BD,0xA002,0x77B5,0x77B0,0xA008,0xA004,0xA002,0x77A0,0x779F,0xA002,0x7791,0x778C,0xA004, 0xA002,0x7780,0x777D,0xA002,0x778D,0x777F,0xA010,0xA008,0xA004,0xA002,0x7765,0x7762,0xA002,0x986E,0x986D,0xA004, 0xA002,0x986C,0x986B,0xA002,0x986A,0x9869,0xA008,0xA004,0xA002,0x9868,0x9867,0xA002,0x9866,0x9865,0xA004,0xA002, 0x9864,0x9863,0xA002,0x9862,0x9861,0xA020,0xA010,0xA008,0xA004,0xA002,0x9860,0x985F,0xA002,0x985E,0x985D,0xA004, 0xA002,0x985C,0x985B,0xA002,0x985A,0x9859,0xA008,0xA004,0xA002,0x9858,0x9857,0xA002,0x9856,0x9855,0xA004,0xA002, 0x9854,0x9853,0xA002,0x9852,0x9851,0xA00F,0xA007,0xA004,0xA002,0x9850,0x984F,0xA000,0x984E,0xA004,0xA002,0x984D, 0x984C,0xA002,0x984B,0x984A,0xA008,0xA004,0xA002,0x9849,0x9848,0xA002,0x9847,0x9846,0xA004,0xA002,0x9845,0x9844, 0xA002,0x9843,0x9842,0xABF3,0xA5FA,0xA2FB,0xA17D,0xA080,0xA068,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x9841,0xA002, 0x9840,0x983F,0xA004,0xA002,0x983E,0x983D,0xA002,0x983C,0x983B,0xA008,0xA004,0xA002,0x983A,0x9839,0xA002,0x9838, 0x9837,0xA004,0xA002,0x9836,0x9835,0xA002,0x9834,0x9833,0xA010,0xA008,0xA004,0xA002,0x9832,0x9831,0xA002,0x9830, 0x982F,0xA004,0xA002,0x982E,0x982D,0xA002,0x982C,0x982B,0xA008,0xA004,0xA002,0x982A,0x9829,0xA002,0x9828,0x9827, 0xA004,0xA002,0x9826,0x9825,0xA002,0x9824,0x9823,0xA020,0xA010,0xA008,0xA004,0xA002,0x9822,0x9821,0xA002,0x9820, 0x981F,0xA004,0xA002,0x981E,0x981D,0xA002,0x981C,0x981B,0xA008,0xA004,0xA002,0x981A,0x9819,0xA002,0x9818,0x9817, 0xA004,0xA002,0x9816,0x9815,0xA002,0x9814,0x9813,0xA000,0xA000,0xA004,0xA002,0x9812,0x9811,0xA002,0x9810,0x980F, 0xA001,0xA001,0xA006,0xA001,0xA001,0xA002,0x7768,0x775A,0xA008,0xA004,0xA002,0x7743,0x7747,0xA002,0x7751,0x7750, 0xA004,0xA002,0x7738,0x7735,0xA002,0x7726,0x772D,0xA07E,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x7719,0xA002,0x7722, 0x771A,0xA004,0xA002,0x7708,0x7707,0xA002,0x76F9,0x770D,0xA008,0xA004,0xA002,0x7704,0x76F1,0xA002,0x9EFC,0x9EFB, 0xA004,0xA002,0x9EF9,0x9F9B,0xA002,0x7934,0x791E,0xA010,0xA008,0xA004,0xA002,0x7924,0x7913,0xA002,0x78F4,0x7905, 0xA004,0xA002,0x78F2,0x78EC,0xA002,0x78C9,0x78D9,0xA008,0xA004,0xA002,0x78D4,0x78A5,0xA002,0x78B9,0x78B2,0xA004, 0xA002,0x78A3,0x78A1,0xA002,0x789C,0x7887,0xA020,0xA010,0xA008,0xA004,0xA002,0x789A,0x7893,0xA002,0x789B,0x786A, 0xA004,0xA002,0x784C,0x7847,0xA002,0x7850,0x7826,0xA008,0xA004,0xA002,0x7857,0x7856,0xA002,0x786D,0x784E,0xA004, 0xA002,0x7829,0x7823,0xA002,0x782C,0x7825,0xA010,0xA008,0xA004,0xA002,0x783C,0x781F,0xA002,0x783B,0x783A,0xA004, 0xA002,0x7839,0x781D,0xA002,0x781C,0x782D,0xA008,0xA004,0xA002,0x65AB,0x7811,0xA002,0x7818,0x7817,0xA004,0xA002, 0x7809,0x7800,0xA002,0x77F8,0x77F6,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x6DFC,0x6CF6,0xA002,0x6C93,0x807F, 0xA004,0xA002,0x8080,0x6206,0xA002,0x61D1,0x61CB,0xA008,0xA004,0xA002,0x619D,0x61A9,0xA002,0x615D,0x610D,0xA004, 0xA002,0x6106,0x60AB,0xA002,0x6063,0x6059,0xA010,0xA008,0xA004,0xA002,0x6041,0x6067,0xA002,0x605A,0x605D,0xA004, 0xA002,0x603C,0x980E,0xA002,0x980D,0x980C,0xA008,0xA004,0xA002,0x980B,0x980A,0xA002,0x9809,0x9808,0xA004,0xA002, 0x9807,0x9806,0xA002,0x9805,0x9804,0xA020,0xA010,0xA008,0xA004,0xA002,0x9803,0x9802,0xA002,0x9801,0x9800,0xA004, 0xA002,0x97FF,0x97FE,0xA002,0x97FD,0x97FC,0xA008,0xA004,0xA002,0x97FB,0x97FA,0xA002,0x97F9,0x97F8,0xA004,0xA002, 0x97F7,0x97F4,0xA002,0x97F2,0x97F1,0xA00F,0xA008,0xA004,0xA002,0x97F0,0x97EF,0xA002,0x97EE,0x97E8,0xA004,0xA002, 0x97E5,0x97E4,0xA001,0x97E3,0xA008,0xA004,0xA002,0x97E2,0x97E1,0xA002,0x97E0,0x97DF,0xA004,0xA002,0x97DE,0x97DD, 0xA002,0x97DC,0x97DB,0xA081,0xA06E,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x97DA,0xA002,0x97D9,0x97D8,0xA004,0xA002, 0x97D7,0x97D6,0xA002,0x97D5,0x97D4,0xA008,0xA004,0xA002,0x97D3,0x97D2,0xA002,0x97D1,0x97D0,0xA004,0xA002,0x97CF, 0x97CE,0xA002,0x97CD,0x97CC,0xA010,0xA008,0xA004,0xA002,0x97CB,0x97CA,0xA002,0x97C9,0x97C8,0xA004,0xA002,0x97C7, 0x97C6,0xA002,0x97C5,0x97C4,0xA008,0xA004,0xA002,0x97C3,0x97C2,0xA002,0x97C1,0x97C0,0xA004,0xA002,0x97BF,0x97BE, 0xA002,0x97BD,0x97BC,0xA020,0xA010,0xA008,0xA004,0xA002,0x97BB,0x97BA,0xA002,0x97B9,0x97B8,0xA004,0xA002,0x97B7, 0x97B6,0xA002,0x97B5,0x97B3,0xA008,0xA004,0xA002,0x97B1,0x97B0,0xA002,0x97AE,0x97AC,0xA004,0xA002,0x97AA,0x97A9, 0xA002,0x97A8,0x97A7,0xA000,0xA008,0xA004,0xA002,0x97A6,0x97A5,0xA002,0x97A4,0x97A2,0xA004,0xA002,0x97A1,0x979F, 0xA000,0x979E,0xA001,0xA001,0xA001,0xA008,0xA004,0xA002,0x5FD0,0x5FD1,0xA002,0x79B3,0x79A7,0xA004,0xA002,0x799A, 0x798A,0xA002,0x7985,0x797A,0xA07E,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x7967,0xA002,0x796F,0x7960,0xA004,0xA002, 0x7957,0x7962,0xA002,0x795A,0x7953,0xA008,0xA004,0xA002,0x795C,0x795B,0xA002,0x7949,0x7946,0xA004,0xA002,0x7940, 0x793B,0xA002,0x6249,0x6248,0xA010,0xA008,0xA004,0xA002,0x6243,0x623D,0xA002,0x623E,0x71B9,0xA004,0xA002,0x7166, 0x7118,0xA002,0x706C,0x7228,0xA008,0xA004,0xA002,0x721D,0x71F9,0xA002,0x71E7,0x71D4,0xA004,0xA002,0x71E0,0x71A0, 0xA002,0x71A8,0x71B5,0xA020,0xA010,0xA008,0xA004,0xA002,0x71B3,0x7198,0xA002,0x717A,0x7178,0xA004,0xA002,0x714A, 0x7172,0xA002,0x7145,0x7168,0xA008,0xA004,0xA002,0x715C,0x7173,0xA002,0x7131,0x712F,0xA004,0xA002,0x7116,0x7113, 0xA002,0x7110,0x70CA,0xA010,0xA008,0xA004,0xA002,0x70E8,0x70B1,0xA002,0x70AB,0x70B7,0xA004,0xA002,0x70C0,0x70BB, 0xA002,0x709D,0x7096,0xA008,0xA004,0xA002,0x709C,0x7080,0xA002,0x65D6,0x65D2,0xA004,0xA002,0x65CE,0x65CC,0xA002, 0x65C3,0x65C4,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x65C6,0x65BC,0xA002,0x6593,0x9F51,0xA004,0xA002,0x6590, 0x89F3,0xA002,0x6BC2,0x5F40,0xA008,0xA004,0xA002,0x6BB3,0x98DA,0xA002,0x98D9,0x98D5,0xA004,0xA002,0x98D3,0x98D2, 0xA002,0x98D1,0x6B59,0xA010,0xA008,0xA004,0xA002,0x6B46,0x6B43,0xA002,0x6B39,0x6B37,0xA004,0xA002,0x6B24,0x81A6, 0xA002,0x81C1,0x979D,0xA008,0xA004,0xA002,0x979C,0x979B,0xA002,0x979A,0x9799,0xA004,0xA002,0x9797,0x9796,0xA002, 0x9795,0x9793,0xA020,0xA010,0xA008,0xA004,0xA002,0x9790,0x978F,0xA002,0x978E,0x978C,0xA004,0xA002,0x978A,0x9789, 0xA002,0x9788,0x9787,0xA008,0xA004,0xA002,0x9786,0x9784,0xA002,0x9783,0x9782,0xA004,0xA002,0x9781,0x9780,0xA002, 0x977F,0x977E,0xA010,0xA008,0xA004,0xA002,0x977D,0x977B,0xA002,0x977A,0x9779,0xA004,0xA002,0x9778,0x9777,0xA002, 0x9775,0x9772,0xA007,0xA003,0xA001,0x9771,0xA002,0x9770,0x976F,0xA004,0xA002,0x976E,0x976D,0xA002,0x976C,0x976B, 0xA180,0xA083,0xA073,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x976A,0xA002,0x9768,0x9767,0xA004,0xA002,0x9766,0x9764, 0xA002,0x9763,0x975F,0xA008,0xA004,0xA002,0x975D,0x975C,0xA002,0x975A,0x9758,0xA004,0xA002,0x9757,0x9755,0xA002, 0x9754,0x9751,0xA010,0xA008,0xA004,0xA002,0x9750,0x974F,0xA002,0x974E,0x974D,0xA004,0xA002,0x974C,0x974B,0xA002, 0x974A,0x9749,0xA008,0xA004,0xA002,0x9748,0x9747,0xA002,0x9746,0x9745,0xA004,0xA002,0x9744,0x9743,0xA002,0x9742, 0x9741,0xA020,0xA010,0xA008,0xA004,0xA002,0x9740,0x973F,0xA002,0x973D,0x973C,0xA004,0xA002,0x973B,0x973A,0xA002, 0x9737,0x9736,0xA008,0xA004,0xA002,0x9735,0x9734,0xA002,0x9733,0x9731,0xA004,0xA002,0x972F,0x972E,0xA002,0x972C, 0x972B,0xA010,0xA008,0xA004,0xA002,0x9729,0x9728,0xA002,0x9727,0x9726,0xA004,0xA002,0x9725,0x9724,0xA002,0x9723, 0x9722,0xA000,0xA000,0xA000,0x9721,0xA001,0xA001,0xA001,0xA005,0xA001,0xA002,0x81BB,0x81CA,0xA004,0xA002,0x6726, 0x81CC,0xA002,0x81AA,0x81A3,0xA07E,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x6ED5,0xA002,0x8191,0x8182,0xA004,0xA002, 0x8188,0x5AB5,0xA002,0x584D,0x8167,0xA008,0xA004,0xA002,0x816D,0x817D,0xA002,0x817C,0x8169,0xA004,0xA002,0x8160, 0x8171,0xA002,0x815A,0x8159,0xA010,0xA008,0xA004,0xA002,0x8174,0x8153,0xA002,0x814C,0x8148,0xA004,0xA002,0x8132, 0x8118,0xA002,0x812C,0x811E,0xA008,0xA004,0xA002,0x8136,0x8C5A,0xA002,0x8112,0x6715,0xA004,0xA002,0x80FC,0x80F2, 0xA002,0x810E,0x810D,0xA020,0xA010,0xA008,0xA004,0xA002,0x80ED,0x80F4,0xA002,0x80F1,0x80EB,0xA004,0xA002,0x80DD, 0x6710,0xA002,0x80D7,0x80CD,0xA008,0xA004,0xA002,0x80D9,0x80C4,0xA002,0x80C2,0x80DB,0xA004,0xA002,0x80EA,0x80E9, 0xA002,0x80E8,0x80E7,0xA010,0xA008,0xA004,0xA002,0x80B7,0x80B4,0xA002,0x80AD,0x80AB,0xA004,0xA002,0x80B1,0x80BD, 0xA002,0x670A,0x80BC,0xA008,0xA004,0xA002,0x8093,0x809C,0xA002,0x809F,0x5216,0xA004,0xA002,0x8662,0x7230,0xA002, 0x7256,0x7252,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x724D,0x656B,0xA002,0x6555,0x6535,0xA004,0xA002,0x6C32, 0x6C2A,0xA002,0x6C24,0x6C29,0xA008,0xA004,0xA002,0x6C21,0x6C1A,0xA002,0x6C19,0x6C18,0xA004,0xA002,0x6C15,0x6C0D, 0xA002,0x6C06,0x6C07,0xA010,0xA008,0xA004,0xA002,0x6C05,0x6BF9,0xA002,0x6BF5,0x6BFD,0xA004,0xA002,0x6BF3,0x6BEA, 0xA002,0x8004,0x64D8,0xA008,0xA004,0xA002,0x643F,0x9720,0xA002,0x971F,0x971D,0xA004,0xA002,0x971B,0x971A,0xA002, 0x9719,0x9718,0xA020,0xA010,0xA008,0xA004,0xA002,0x9717,0x9715,0xA002,0x9714,0x9712,0xA004,0xA002,0x9711,0x9710, 0xA002,0x970C,0x970B,0xA008,0xA004,0xA002,0x970A,0x9705,0xA002,0x9703,0x9702,0xA004,0xA002,0x96FF,0x96FD,0xA002, 0x96FC,0x96FB,0xA010,0xA008,0xA004,0xA002,0x96FA,0x96F8,0xA002,0x96F5,0x96F4,0xA004,0xA002,0x96F2,0x96F1,0xA002, 0x96F0,0x96EE,0xA007,0xA004,0xA002,0x96ED,0x96EC,0xA001,0x96EB,0xA004,0xA002,0x96E7,0x96E6,0xA002,0x96E5,0x96E4, 0xA082,0xA076,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x96E3,0xA002,0x96E2,0x96E1,0xA004,0xA002,0x96DF,0x96DE,0xA002, 0x96DD,0x96DC,0xA008,0xA004,0xA002,0x96DB,0x96DA,0xA002,0x96D9,0x96D8,0xA004,0xA002,0x96D7,0x96D6,0xA002,0x96D4, 0x96D3,0xA010,0xA008,0xA004,0xA002,0x96D1,0x96D0,0xA002,0x96CB,0x96CA,0xA004,0xA002,0x96C8,0x96C3,0xA002,0x96C2, 0x96BF,0xA008,0xA004,0xA002,0x96BB,0x96BA,0xA002,0x96B8,0x96B7,0xA004,0xA002,0x96B5,0x96B4,0xA002,0x96B2,0x96B1, 0xA020,0xA010,0xA008,0xA004,0xA002,0x96AF,0x96AE,0xA002,0x96AD,0x96AC,0xA004,0xA002,0x96AB,0x96AA,0xA002,0x96A9, 0x96A8,0xA008,0xA004,0xA002,0x96A6,0x96A5,0xA002,0x96A4,0x96A3,0xA004,0xA002,0x96A2,0x96A1,0xA002,0x96A0,0x969F, 0xA010,0xA008,0xA004,0xA002,0x969E,0x969D,0xA002,0x969B,0x969A,0xA004,0xA002,0x9696,0x9695,0xA002,0x9693,0x9692, 0xA000,0xA004,0xA002,0x9691,0x968E,0xA000,0x968C,0xA001,0xA001,0xA001,0xA001,0xA004,0xA002,0x63B0,0x6332,0xA002, 0x6308,0x7292,0xA07E,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x728F,0xA002,0x728D,0x728B,0xA004,0xA002,0x7284,0x727F, 0xA002,0x727E,0x726F,0xA008,0xA004,0xA002,0x7266,0x725D,0xA002,0x729F,0x726E,0xA004,0xA002,0x89D1,0x89D0,0xA002, 0x89CF,0x89CE,0xA010,0xA008,0xA004,0xA002,0x89CC,0x89CB,0xA002,0x89CA,0x89C7,0xA004,0xA002,0x8D59,0x8D55,0xA002, 0x8D4D,0x8D47,0xA008,0xA004,0xA002,0x8D49,0x8D48,0xA002,0x8D46,0x8D45,0xA004,0xA002,0x8D40,0x8D3D,0xA002,0x8D3B, 0x8D36,0xA020,0xA010,0xA008,0xA004,0xA002,0x8D33,0x8D32,0xA002,0x66E9,0x66E6,0xA004,0xA002,0x66DC,0x66DB,0xA002, 0x66BE,0x669D,0xA008,0xA004,0xA002,0x66A7,0x668C,0xA002,0x6684,0x6677,0xA004,0xA002,0x6657,0x6661,0xA002,0x6656, 0x664F,0xA010,0xA008,0xA004,0xA002,0x6641,0x6654,0xA002,0x665F,0x8006,0xA004,0xA002,0x6635,0x6636,0xA002,0x6631, 0x6634,0xA008,0xA004,0xA002,0x661D,0x66F7,0xA002,0x7085,0x6600,0xA004,0xA002,0x6615,0x6603,0xA002,0x6772,0x6619, 0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x660A,0x65F0,0xA002,0x65EF,0x65EE,0xA004,0xA002,0x6534,0x7513,0xA002, 0x7511,0x750F,0xA008,0xA004,0xA002,0x74FF,0x74F4,0xA002,0x74EF,0x81E7,0xA004,0xA002,0x622C,0x6224,0xA002,0x6225, 0x6221,0xA010,0xA008,0xA004,0xA002,0x6222,0x621F,0xA002,0x621B,0x6217,0xA004,0xA002,0x620B,0x8ECE,0xA002,0x8F9A, 0x8F98,0xA008,0xA004,0xA002,0x8F8F,0x8F8E,0xA002,0x8F8D,0x968A,0xA004,0xA002,0x9689,0x9687,0xA002,0x9684,0x9683, 0xA020,0xA010,0xA008,0xA004,0xA002,0x9682,0x9681,0xA002,0x9680,0x967F,0xA004,0xA002,0x967E,0x967D,0xA002,0x967C, 0x967B,0xA008,0xA004,0xA002,0x967A,0x9679,0xA002,0x9678,0x9673,0xA004,0xA002,0x9671,0x9670,0xA002,0x966F,0x966E, 0xA010,0xA008,0xA004,0xA002,0x966D,0x966B,0xA002,0x9666,0x9665,0xA004,0xA002,0x9663,0x9660,0xA002,0x965E,0x965D, 0xA008,0xA004,0xA002,0x965C,0x965A,0xA002,0x9659,0x9658,0xA003,0xA001,0x9657,0xA002,0x9656,0x9653,0xA2FB,0xA17F, 0xA082,0xA07A,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x9652,0xA002,0x9651,0x964F,0xA004,0xA002,0x964E,0x964A,0xA002, 0x9643,0x9641,0xA008,0xA004,0xA002,0x963E,0x963A,0xA002,0x9639,0x9638,0xA004,0xA002,0x9637,0x9630,0xA002,0x962F, 0x962D,0xA010,0xA008,0xA004,0xA002,0x962C,0x962B,0xA002,0x9629,0x9628,0xA004,0xA002,0x9627,0x9626,0xA002,0x9625, 0x9624,0xA008,0xA004,0xA002,0x9623,0x9620,0xA002,0x961E,0x961B,0xA004,0xA002,0x9618,0x9613,0xA002,0x9607,0x95FF, 0xA020,0xA010,0xA008,0xA004,0xA002,0x95EC,0x95E7,0xA002,0x95E6,0x95E5,0xA004,0xA002,0x95E4,0x95E3,0xA002,0x95E2, 0x95E1,0xA008,0xA004,0xA002,0x95E0,0x95DF,0xA002,0x95DE,0x95DD,0xA004,0xA002,0x95DC,0x95DB,0xA002,0x95DA,0x95D9, 0xA010,0xA008,0xA004,0xA002,0x95D8,0x95D7,0xA002,0x95D6,0x95D5,0xA004,0xA002,0x95D4,0x95D3,0xA002,0x95D2,0x95D1, 0xA008,0xA004,0xA002,0x95D0,0x95CF,0xA002,0x95CE,0x95CD,0xA000,0xA000,0x95CC,0xA001,0xA001,0xA001,0xA001,0xA001, 0xA001,0x8F8B,0xA07E,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x8F87,0xA002,0x8F84,0x8F82,0xA004,0xA002,0x8F81,0x8F7E, 0xA002,0x8F7C,0x8F7A,0xA008,0xA004,0xA002,0x8F79,0x8F77,0xA002,0x8F78,0x8F76,0xA004,0xA002,0x8F75,0x8F73,0xA002, 0x8F72,0x8F71,0xA010,0xA008,0xA004,0xA002,0x8F6D,0x8F6B,0xA002,0x6BAA,0x6BA1,0xA004,0xA002,0x6B9B,0x6B9A,0xA002, 0x6B8D,0x6B93,0xA008,0xA004,0xA002,0x6B92,0x6B84,0xA002,0x6B87,0x6B82,0xA004,0xA002,0x6B81,0x7352,0xA002,0x7337, 0x6AAB,0xA020,0xA010,0xA008,0xA004,0xA002,0x6A97,0x6AA9,0xA002,0x6A90,0x6A91,0xA004,0xA002,0x6A7C,0x6A58,0xA002, 0x6A28,0x6A3D,0xA008,0xA004,0xA002,0x6A79,0x6A8E,0xA002,0x6A35,0x6A5B,0xA004,0xA002,0x6A50,0x6AA0,0xA002,0x6A3E, 0x6A44,0xA010,0xA008,0xA004,0xA002,0x69F2,0x6A65,0xA002,0x6A18,0x6A17,0xA004,0xA002,0x69ED,0x6A2F,0xA002,0x69FF, 0x698D,0xA008,0xA004,0xA002,0x69E0,0x6995,0xA002,0x69DF,0x69CA,0xA004,0xA002,0x69C1,0x69B1,0xA002,0x69D4,0x69AD, 0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x69AB,0x69BB,0xA002,0x69A7,0x699B,0xA004,0xA002,0x6979,0x6963,0xA002, 0x6966,0x6989,0xA008,0xA004,0xA002,0x69CE,0x6988,0xA002,0x6987,0x69CC,0xA004,0xA002,0x6934,0x6978,0xA002,0x6998, 0x6980,0xA010,0xA008,0xA004,0xA002,0x696B,0x6984,0xA002,0x695D,0x6942,0xA004,0xA002,0x6960,0x6939,0xA002,0x6971, 0x6910,0xA008,0xA004,0xA002,0x68E3,0x6957,0xA002,0x6901,0x690B,0xA004,0xA002,0x68F0,0x6924,0xA002,0x95CB,0x95CA, 0xA020,0xA010,0xA008,0xA004,0xA002,0x95C9,0x95C8,0xA002,0x95C7,0x95C6,0xA004,0xA002,0x95C5,0x95C4,0xA002,0x95C3, 0x95C2,0xA008,0xA004,0xA002,0x95C1,0x95C0,0xA002,0x95BF,0x95BE,0xA004,0xA002,0x95BD,0x95BC,0xA002,0x95BB,0x95BA, 0xA010,0xA008,0xA004,0xA002,0x95B9,0x95B8,0xA002,0x95B7,0x95B6,0xA004,0xA002,0x95B5,0x95B4,0xA002,0x95B3,0x95B2, 0xA008,0xA004,0xA002,0x95B1,0x95B0,0xA002,0x95AF,0x95AE,0xA004,0xA002,0x95AD,0x95AC,0xA000,0x95AB,0xA07F,0xA000, 0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x95AA,0xA002,0x95A9,0x95A8,0xA004,0xA002,0x95A7,0x95A6,0xA002,0x95A5,0x95A4, 0xA008,0xA004,0xA002,0x95A3,0x95A2,0xA002,0x95A1,0x95A0,0xA004,0xA002,0x959F,0x959E,0xA002,0x959D,0x959C,0xA010, 0xA008,0xA004,0xA002,0x959B,0x959A,0xA002,0x9599,0x9598,0xA004,0xA002,0x9597,0x9596,0xA002,0x9595,0x9594,0xA008, 0xA004,0xA002,0x9593,0x9592,0xA002,0x9591,0x9590,0xA004,0xA002,0x958F,0x958E,0xA002,0x958D,0x958C,0xA020,0xA010, 0xA008,0xA004,0xA002,0x958B,0x958A,0xA002,0x9589,0x9588,0xA004,0xA002,0x9587,0x9586,0xA002,0x9585,0x9584,0xA008, 0xA004,0xA002,0x9583,0x9582,0xA002,0x9581,0x9580,0xA004,0xA002,0x957E,0x957D,0xA002,0x957C,0x957B,0xA010,0xA008, 0xA004,0xA002,0x957A,0x9579,0xA002,0x9578,0x9577,0xA004,0xA002,0x9575,0x9574,0xA002,0x956E,0x9560,0xA008,0xA004, 0xA002,0x955A,0x9555,0xA002,0x954B,0x9548,0xA004,0xA002,0x9543,0x953D,0xA002,0x9533,0x9527,0xA07D,0xA03D,0xA01D, 0xA00D,0xA005,0xA001,0xA002,0x68F9,0x6920,0xA004,0xA002,0x691F,0x68FC,0xA002,0x696E,0x68C2,0xA008,0xA004,0xA002, 0x686B,0x6893,0xA002,0x6877,0x6874,0xA004,0xA002,0x688F,0x68B5,0xA002,0x6829,0x6849,0xA010,0xA008,0xA004,0xA002, 0x684A,0x683E,0xA002,0x6840,0x6867,0xA004,0xA002,0x6841,0x6866,0xA002,0x6855,0x681D,0xA008,0xA004,0xA002,0x6883, 0x6864,0xA002,0x6844,0x6862,0xA004,0xA002,0x684E,0x6861,0xA002,0x6860,0x6833,0xA020,0xA010,0xA008,0xA004,0xA002, 0x6832,0x67FD,0xA002,0x67C1,0x680E,0xA004,0xA002,0x67E2,0x67B8,0xA002,0x67C3,0x6800,0xA008,0xA004,0xA002,0x67DD, 0x67B3,0xA002,0x67DA,0x67B5,0xA004,0xA002,0x67D9,0x680C,0xA002,0x67B0,0x67E9,0xA010,0xA008,0xA004,0xA002,0x680A, 0x67D8,0xA002,0x6809,0x67F0,0xA004,0xA002,0x677C,0x6777,0xA002,0x678B,0x67AD,0xA008,0xA004,0xA002,0x679E,0x67A8, 0xA002,0x6775,0x67A7,0xA004,0xA002,0x6798,0x6773,0xA002,0x676A,0x6787,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002, 0x67A5,0x6769,0xA002,0x6748,0x675E,0xA004,0xA002,0x6753,0x674C,0xA002,0x97EC,0x97EB,0xA008,0xA004,0xA002,0x97EA, 0x74BA,0xA002,0x74D2,0x74A7,0xA004,0xA002,0x7490,0x74A9,0xA002,0x74A8,0x749E,0xA010,0xA008,0xA004,0xA002,0x748B, 0x7487,0xA002,0x7481,0x7480,0xA004,0xA002,0x748E,0x749C,0xA002,0x747E,0x746D,0xA008,0xA004,0xA002,0x7477,0x7459, 0xA002,0x7455,0x7457,0xA004,0xA002,0x745C,0x7441,0xA002,0x741A,0x741B,0xA020,0xA010,0xA008,0xA004,0xA002,0x9520, 0x951C,0xA002,0x94FB,0x94E6,0xA004,0xA002,0x94DA,0x94D4,0xA002,0x94D3,0x94CF,0xA008,0xA004,0xA002,0x94C7,0x9498, 0xA002,0x9496,0x9491,0xA004,0xA002,0x9484,0x9483,0xA002,0x9482,0x9481,0xA010,0xA008,0xA004,0xA002,0x9480,0x947F, 0xA002,0x947E,0x947D,0xA004,0xA002,0x947C,0x947B,0xA002,0x947A,0x9479,0xA008,0xA004,0xA002,0x9478,0x9477,0xA002, 0x9476,0x9475,0xA004,0xA002,0x9474,0x9473,0xA002,0x9472,0x9471,0xA17F,0xA086,0xA07D,0xA03D,0xA01D,0xA00D,0xA005, 0xA002,0x9470,0xA001,0x946F,0xA004,0xA002,0x946E,0x946D,0xA002,0x946C,0x946A,0xA008,0xA004,0xA002,0x9469,0x9468, 0xA002,0x9467,0x9466,0xA004,0xA002,0x9465,0x9464,0xA002,0x9463,0x9462,0xA010,0xA008,0xA004,0xA002,0x9461,0x9460, 0xA002,0x945F,0x945E,0xA004,0xA002,0x945D,0x945C,0xA002,0x945B,0x945A,0xA008,0xA004,0xA002,0x9459,0x9458,0xA002, 0x9457,0x9456,0xA004,0xA002,0x9455,0x9454,0xA002,0x9453,0x9452,0xA020,0xA010,0xA008,0xA004,0xA002,0x9451,0x9450, 0xA002,0x944F,0x944E,0xA004,0xA002,0x944D,0x944C,0xA002,0x944B,0x944A,0xA008,0xA004,0xA002,0x9449,0x9448,0xA002, 0x9447,0x9446,0xA004,0xA002,0x9445,0x9444,0xA002,0x9443,0x9442,0xA010,0xA008,0xA004,0xA002,0x9441,0x9440,0xA002, 0x943F,0x943D,0xA004,0xA002,0x943C,0x943B,0xA002,0x943A,0x9439,0xA008,0xA004,0xA002,0x9438,0x9437,0xA002,0x9436, 0x9435,0xA004,0xA002,0x9434,0x9433,0xA002,0x9432,0x9431,0xA000,0xA000,0xA000,0xA000,0xA000,0xA002,0x9430,0x942F, 0xA079,0xA039,0xA019,0xA009,0xA001,0xA004,0xA002,0x742C,0x742E,0xA002,0x7430,0x7428,0xA008,0xA004,0xA002,0x7425, 0x7426,0xA002,0x745B,0x742A,0xA004,0xA002,0x740F,0x73F2,0xA002,0x73BA,0x73DE,0xA010,0xA008,0xA004,0xA002,0x73E7, 0x73E9,0xA002,0x740A,0x987C,0xA004,0xA002,0x73D9,0x73E5,0xA002,0x73C8,0x73C9,0xA008,0xA004,0xA002,0x73C0,0x73B3, 0xA002,0x73B7,0x73D1,0xA004,0xA002,0x73C2,0x73CF,0xA002,0x739F,0x73A2,0xA020,0xA010,0xA008,0xA004,0xA002,0x73AE, 0x7391,0xA002,0x738E,0x9095,0xA004,0xA002,0x753E,0x5DDB,0xA002,0x757F,0x5E7A,0xA008,0xA004,0xA002,0x7F35,0x7F33, 0xA002,0x7F32,0x7F31,0xA004,0xA002,0x7F30,0x7F2F,0xA002,0x7F2D,0x7F2C,0xA010,0xA008,0xA004,0xA002,0x7F2B,0x7F2A, 0xA002,0x7F27,0x7F26,0xA004,0xA002,0x7F25,0x7F24,0xA002,0x7F23,0x7F22,0xA008,0xA004,0xA002,0x7F21,0x7F1F,0xA002, 0x7F1B,0x7F1C,0xA004,0xA002,0x7F19,0x7F17,0xA002,0x7F12,0x7F11,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x7F0F, 0x7F0C,0xA002,0x7F0B,0x7F08,0xA004,0xA002,0x7F07,0x7F03,0xA002,0x7F02,0x7F01,0xA008,0xA004,0xA002,0x7EFE,0x7EFB, 0xA002,0x7EFA,0x7EF6,0xA004,0xA002,0x7F0D,0x7EF2,0xA002,0x7EF1,0x7EEF,0xA010,0xA008,0xA004,0xA002,0x7EEE,0x7EEB, 0xA002,0x7EE8,0x7EE1,0xA004,0xA002,0x7EE0,0x7EDB,0xA002,0x7ED7,0x7ED4,0xA008,0xA004,0xA002,0x7ED0,0x7ECC,0xA002, 0x7ECB,0x7EC9,0xA004,0xA002,0x7EC2,0x7EC1,0xA002,0x7EC0,0x7EBE,0xA020,0xA010,0xA008,0xA004,0xA002,0x7EB0,0x7EAD, 0xA002,0x942E,0x942D,0xA004,0xA002,0x942C,0x942B,0xA002,0x942A,0x9429,0xA008,0xA004,0xA002,0x9428,0x9427,0xA002, 0x9426,0x9425,0xA004,0xA002,0x9424,0x9423,0xA002,0x9422,0x9421,0xA010,0xA008,0xA004,0xA002,0x9420,0x941F,0xA002, 0x941E,0x941D,0xA004,0xA002,0x941C,0x941B,0xA002,0x941A,0x9419,0xA008,0xA004,0xA002,0x9418,0x9417,0xA002,0x9416, 0x9415,0xA004,0xA002,0x9414,0x9413,0xA002,0x9412,0x9411,0xA089,0xA07D,0xA03D,0xA01D,0xA00D,0xA006,0xA002,0x9410, 0xA002,0x940F,0x940E,0xA003,0xA001,0x940D,0xA002,0x940C,0x940B,0xA008,0xA004,0xA002,0x940A,0x9409,0xA002,0x9408, 0x9407,0xA004,0xA002,0x9406,0x9405,0xA002,0x9404,0x9403,0xA010,0xA008,0xA004,0xA002,0x9402,0x9401,0xA002,0x9400, 0x93FF,0xA004,0xA002,0x93FE,0x93FD,0xA002,0x93FC,0x93FB,0xA008,0xA004,0xA002,0x93FA,0x93F9,0xA002,0x93F8,0x93F7, 0xA004,0xA002,0x93F6,0x93F5,0xA002,0x93F4,0x93F3,0xA020,0xA010,0xA008,0xA004,0xA002,0x93F2,0x93F1,0xA002,0x93F0, 0x93EF,0xA004,0xA002,0x93EE,0x93ED,0xA002,0x93EC,0x93EB,0xA008,0xA004,0xA002,0x93EA,0x93E9,0xA002,0x93E8,0x93E7, 0xA004,0xA002,0x93E6,0x93E5,0xA002,0x93E4,0x93E3,0xA010,0xA008,0xA004,0xA002,0x93E2,0x93E1,0xA002,0x93E0,0x93DF, 0xA004,0xA002,0x93DE,0x93DD,0xA002,0x93DC,0x93DB,0xA008,0xA004,0xA002,0x93DA,0x93D9,0xA002,0x93D8,0x93D7,0xA004, 0xA002,0x93D5,0x93D4,0xA002,0x93D3,0x93D2,0xA000,0xA000,0xA000,0xA000,0xA004,0xA002,0x93D1,0x93D0,0xA002,0x93CF, 0x93CE,0xA076,0xA036,0xA016,0xA006,0xA001,0xA001,0xA002,0x7EA9,0x7EA8,0xA008,0xA004,0xA002,0x7EA5,0x7EA3,0xA002, 0x7EA1,0x7E9F,0xA004,0xA002,0x9AA7,0x9AA5,0xA002,0x9AA3,0x9AA2,0xA010,0xA008,0xA004,0xA002,0x9AA0,0x9A9F,0xA002, 0x9A9D,0x9A9C,0xA004,0xA002,0x9A9B,0x9A98,0xA002,0x9A96,0x9A93,0xA008,0xA004,0xA002,0x9A92,0x9A90,0xA002,0x9A8A, 0x9A88,0xA004,0xA002,0x9A85,0x9A81,0xA002,0x9A80,0x9A7D,0xA020,0xA010,0xA008,0xA004,0xA002,0x9A7F,0x9A7A,0xA002, 0x9A78,0x9A77,0xA004,0xA002,0x9A75,0x5B62,0xA002,0x5B53,0x5B51,0xA008,0xA004,0xA002,0x5B73,0x5B65,0xA002,0x5B5A, 0x5C1C,0xA004,0xA002,0x5C15,0x5B40,0xA002,0x5B37,0x5B32,0xA010,0xA008,0xA004,0xA002,0x5B16,0x5B17,0xA002,0x5B09, 0x5ADC,0xA004,0xA002,0x5AD8,0x5AE6,0xA002,0x5AD6,0x5AF1,0xA008,0xA004,0xA002,0x5AE3,0x5AE0,0xA002,0x5AB8,0x5AD4, 0xA004,0xA002,0x5AD2,0x5AB2,0xA002,0x5AEB,0x5ABE,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x5A7A,0x5A77,0xA002, 0x5A9B,0x5AAA,0xA004,0xA002,0x80EC,0x5A75,0xA002,0x5A62,0x5A3C,0xA008,0xA004,0xA002,0x5A55,0x5A4A,0xA002,0x5A67, 0x5A40,0xA004,0xA002,0x5A13,0x5A23,0xA002,0x5A11,0x5A34,0xA010,0xA008,0xA004,0xA002,0x5A32,0x5A09,0xA002,0x5A0C, 0x59F9,0xA004,0xA002,0x59D8,0x59E3,0xA002,0x5A08,0x59DD,0xA008,0xA004,0xA002,0x5A06,0x5A05,0xA002,0x59BE,0x59D7, 0xA004,0xA002,0x59AF,0x59B2,0xA002,0x59D2,0x59A4,0xA020,0xA010,0xA008,0xA004,0xA002,0x599E,0x59AB,0xA002,0x59CA, 0x5997,0xA004,0xA002,0x93CD,0x93CC,0xA002,0x93CB,0x93C9,0xA008,0xA004,0xA002,0x93C8,0x93C7,0xA002,0x93C6,0x93C5, 0xA004,0xA002,0x93C4,0x93C3,0xA002,0x93C2,0x93C1,0xA010,0xA008,0xA004,0xA002,0x93C0,0x93BF,0xA002,0x93BE,0x93BD, 0xA004,0xA002,0x93BC,0x93BB,0xA002,0x93BA,0x93B9,0xA008,0xA004,0xA002,0x93B8,0x93B7,0xA002,0x93B6,0x93B5,0xA004, 0xA002,0x93B4,0x93B3,0xA002,0x93B2,0x93B1,0xA5FF,0xA2FE,0xA17D,0xA08D,0xA07D,0xA03D,0xA01D,0xA00D,0xA006,0xA002, 0x93B0,0xA002,0x93AF,0x93AE,0xA004,0xA002,0x93AD,0x93AC,0xA001,0x93AB,0xA008,0xA004,0xA002,0x93AA,0x93A9,0xA002, 0x93A8,0x93A7,0xA004,0xA002,0x93A6,0x93A5,0xA002,0x93A4,0x93A3,0xA010,0xA008,0xA004,0xA002,0x93A2,0x93A1,0xA002, 0x93A0,0x939F,0xA004,0xA002,0x939E,0x939D,0xA002,0x939C,0x939B,0xA008,0xA004,0xA002,0x939A,0x9399,0xA002,0x9398, 0x9397,0xA004,0xA002,0x9396,0x9395,0xA002,0x9394,0x9393,0xA020,0xA010,0xA008,0xA004,0xA002,0x9392,0x9391,0xA002, 0x9390,0x938E,0xA004,0xA002,0x938D,0x938C,0xA002,0x938B,0x938A,0xA008,0xA004,0xA002,0x9389,0x9388,0xA002,0x9387, 0x9386,0xA004,0xA002,0x9385,0x9384,0xA002,0x9383,0x9382,0xA010,0xA008,0xA004,0xA002,0x9381,0x9380,0xA002,0x937F, 0x937E,0xA004,0xA002,0x937D,0x937C,0xA002,0x937B,0x937A,0xA008,0xA004,0xA002,0x9379,0x9378,0xA002,0x9377,0x9376, 0xA004,0xA002,0x9375,0x9374,0xA002,0x9373,0x9372,0xA000,0xA000,0xA000,0xA006,0xA002,0x9371,0xA002,0x9370,0x936F, 0xA004,0xA002,0x936E,0x936D,0xA000,0x936C,0xA070,0xA030,0xA010,0xA001,0xA007,0xA003,0xA001,0x59A3,0xA002,0x59AA, 0x59A9,0xA004,0xA002,0x598D,0x5983,0xA002,0x5981,0x5C6E,0xA010,0xA008,0xA004,0xA002,0x9B3B,0x5F3C,0xA002,0x8274, 0x5F2D,0xA004,0xA002,0x5F29,0x5F2A,0xA002,0x7FBC,0x5C66,0xA008,0xA004,0xA002,0x5C63,0x5B71,0xA002,0x5C59,0x5C50, 0xA004,0xA002,0x54AB,0x5C3B,0xA002,0x5F58,0x5F56,0xA020,0xA010,0xA008,0xA004,0xA002,0x5F57,0x5F50,0xA002,0x908B, 0x9083,0xA004,0xA002,0x9088,0x9082,0xA002,0x907D,0x9074,0xA008,0xA004,0xA002,0x66B9,0x905B,0xA002,0x9062,0x9058, 0xA004,0xA002,0x9068,0x9050,0xA002,0x9052,0x9051,0xA010,0xA008,0xA004,0xA002,0x9044,0x902F,0xA002,0x902D,0x9036, 0xA004,0xA002,0x9035,0x9021,0xA002,0x9016,0x900D,0xA008,0xA004,0xA002,0x9011,0x9026,0xA002,0x900B,0x9004,0xA004, 0xA002,0x9005,0x8FE8,0xA002,0x8FF3,0x8FE6,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x8FE9,0x8FE4,0xA002,0x8FEE, 0x8FE5,0xA004,0xA002,0x8FD5,0x8FD3,0xA002,0x8FB6,0x8B07,0xA008,0xA004,0xA002,0x8E47,0x5BF0,0xA002,0x8930,0x5BEE, 0xA004,0xA002,0x5BE4,0x6434,0xA002,0x9A9E,0x752F,0xA010,0xA008,0xA004,0xA002,0x5BB8,0x5BA5,0xA002,0x5B93,0x5B95, 0xA004,0xA002,0x5B84,0x5B80,0xA002,0x705E,0x704F,0xA008,0xA004,0xA002,0x7035,0x7039,0xA002,0x701B,0x7023,0xA004, 0xA002,0x701A,0x6FEF,0xA002,0x6FE0,0x6FDE,0xA020,0xA010,0xA008,0xA004,0xA002,0x6FEE,0x6FE1,0xA002,0x6FC2,0x6FB6, 0xA004,0xA002,0x6FB9,0x6FA7,0xA002,0x6FC9,0x936B,0xA008,0xA004,0xA002,0x9369,0x9368,0xA002,0x9367,0x9366,0xA004, 0xA002,0x9365,0x9364,0xA002,0x9363,0x9362,0xA010,0xA008,0xA004,0xA002,0x9361,0x9360,0xA002,0x935F,0x935E,0xA004, 0xA002,0x935D,0x935C,0xA002,0x935B,0x935A,0xA008,0xA004,0xA002,0x9359,0x9358,0xA002,0x9357,0x9356,0xA004,0xA002, 0x9355,0x9354,0xA002,0x9353,0x9352,0xA094,0xA07D,0xA03D,0xA01D,0xA00E,0xA006,0xA002,0x9351,0xA002,0x9350,0x934F, 0xA004,0xA002,0x934E,0x934D,0xA002,0x934C,0x934B,0xA007,0xA003,0xA000,0x934A,0xA002,0x9349,0x9348,0xA004,0xA002, 0x9347,0x9346,0xA002,0x9345,0x9344,0xA010,0xA008,0xA004,0xA002,0x9343,0x9342,0xA002,0x9341,0x9340,0xA004,0xA002, 0x933F,0x933D,0xA002,0x933C,0x933B,0xA008,0xA004,0xA002,0x933A,0x9339,0xA002,0x9338,0x9337,0xA004,0xA002,0x9336, 0x9335,0xA002,0x9334,0x9333,0xA020,0xA010,0xA008,0xA004,0xA002,0x9332,0x9331,0xA002,0x9330,0x932F,0xA004,0xA002, 0x932E,0x932D,0xA002,0x932C,0x932B,0xA008,0xA004,0xA002,0x932A,0x9329,0xA002,0x9328,0x9327,0xA004,0xA002,0x9326, 0x9325,0xA002,0x9324,0x9323,0xA010,0xA008,0xA004,0xA002,0x9322,0x9321,0xA002,0x9320,0x931F,0xA004,0xA002,0x931E, 0x931D,0xA002,0x931C,0x931B,0xA008,0xA004,0xA002,0x931A,0x9319,0xA002,0x9318,0x9317,0xA004,0xA002,0x9316,0x9315, 0xA002,0x9314,0x9313,0xA000,0xA000,0xA010,0xA008,0xA004,0xA002,0x9312,0x9311,0xA002,0x9310,0x930F,0xA004,0xA002, 0x930E,0x930D,0xA002,0x930C,0x930B,0xA000,0xA000,0xA000,0x930A,0xA06D,0xA02D,0xA00D,0xA001,0xA004,0xA001,0xA001, 0x6FD1,0xA004,0xA002,0x6F7A,0x6F7C,0xA002,0x6F72,0x6F78,0xA010,0xA008,0xA004,0xA002,0x6F8C,0x6F8D,0xA002,0x6F89, 0x6F29,0xA004,0xA002,0x6F09,0x6F2A,0xA002,0x6F74,0x6F4B,0xA008,0xA004,0xA002,0x6F36,0x6F2F,0xA002,0x6EF9,0x6F15, 0xA004,0xA002,0x6F24,0x6F47,0xA002,0x6F46,0x6F62,0xA020,0xA010,0xA008,0xA004,0xA002,0x6E9F,0x6EC2,0xA002,0x6E8F, 0x6ECF,0xA004,0xA002,0x6EB4,0x6ED7,0xA002,0x6EB7,0x6EBB,0xA008,0xA004,0xA002,0x6EBD,0x6EA7,0xA002,0x6EA5,0x6EE2, 0xA004,0xA002,0x6F2D,0x6EE0,0xA002,0x6E98,0x6EB1,0xA010,0xA008,0xA004,0xA002,0x6EDF,0x6E44,0xA002,0x6E25,0x6E32, 0xA004,0xA002,0x6E54,0x6E53,0xA002,0x6E86,0x6E5F,0xA008,0xA004,0xA002,0x6EB2,0x6E6B,0xA002,0x6E4E,0x6E6E,0xA004, 0xA002,0x6E2B,0x6DAE,0xA002,0x6E0C,0x6DAB,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x6E16,0x6DD9,0xA002,0x6DDD, 0x6DE6,0xA004,0xA002,0x6E11,0x6DE0,0xA002,0x6DBF,0x6E0E,0xA008,0xA004,0xA002,0x6DDE,0x6DC5,0xA002,0x6DC7,0x6E1A, 0xA004,0xA002,0x6D63,0x6D7C,0xA002,0x6D60,0x6D5C,0xA010,0xA008,0xA004,0xA002,0x6D94,0x6D93,0xA002,0x6D5E,0x6DA0, 0xA004,0xA002,0x6D9E,0x6D6F,0xA002,0x6D91,0x6D33,0xA008,0xA004,0xA002,0x6D54,0x6D52,0xA002,0x6D4F,0x6D1A,0xA004, 0xA002,0x6D35,0x6D2E,0xA002,0x6D4D,0x6D2B,0xA020,0xA010,0xA008,0xA004,0xA002,0x6D0E,0x6D19,0xA002,0x6D04,0x6D07, 0xA004,0xA002,0x6D48,0x6D43,0xA002,0x6D0C,0x6D27,0xA008,0xA004,0xA002,0x6D39,0x9309,0xA002,0x9308,0x9307,0xA004, 0xA002,0x9306,0x9305,0xA002,0x9304,0x9303,0xA010,0xA008,0xA004,0xA002,0x9302,0x9301,0xA002,0x9300,0x92FF,0xA004, 0xA002,0x92FE,0x92FD,0xA002,0x92FC,0x92FB,0xA008,0xA004,0xA002,0x92FA,0x92F9,0xA002,0x92F8,0x92F7,0xA004,0xA002, 0x92F6,0x92F5,0xA002,0x92F4,0x92F3,0xA180,0xA097,0xA07D,0xA03D,0xA01D,0xA00E,0xA006,0xA002,0x92F2,0xA002,0x92F1, 0x92F0,0xA004,0xA002,0x92EF,0x92EE,0xA002,0x92ED,0x92EC,0xA007,0xA004,0xA002,0x92EB,0x92EA,0xA000,0x92E9,0xA004, 0xA002,0x92E8,0x92E7,0xA002,0x92E6,0x92E5,0xA010,0xA008,0xA004,0xA002,0x92E4,0x92E3,0xA002,0x92E2,0x92E1,0xA004, 0xA002,0x92E0,0x92DF,0xA002,0x92DE,0x92DD,0xA008,0xA004,0xA002,0x92DC,0x92DB,0xA002,0x92DA,0x92D9,0xA004,0xA002, 0x92D8,0x92D7,0xA002,0x92D6,0x92D5,0xA020,0xA010,0xA008,0xA004,0xA002,0x92D4,0x92D3,0xA002,0x92D2,0x92D1,0xA004, 0xA002,0x92D0,0x92CF,0xA002,0x92CE,0x92CD,0xA008,0xA004,0xA002,0x92CC,0x92CB,0xA002,0x92CA,0x92C9,0xA004,0xA002, 0x92C7,0x92C6,0xA002,0x92C5,0x92C4,0xA010,0xA008,0xA004,0xA002,0x92C3,0x92C2,0xA002,0x92C1,0x92C0,0xA004,0xA002, 0x92BF,0x92BE,0xA002,0x92BD,0x92BC,0xA008,0xA004,0xA002,0x92BB,0x92BA,0xA002,0x92B9,0x92B8,0xA004,0xA002,0x92B7, 0x92B6,0xA002,0x92B5,0x92B4,0xA000,0xA000,0xA010,0xA008,0xA004,0xA002,0x92B3,0x92B2,0xA002,0x92B1,0x92B0,0xA004, 0xA002,0x92AF,0x92AD,0xA002,0x92AC,0x92AB,0xA000,0xA004,0xA002,0x92AA,0x92A9,0xA000,0x92A8,0xA069,0xA029,0xA009, 0xA001,0xA001,0xA003,0xA001,0x6CFE,0xA002,0x6CEF,0x6CD3,0xA010,0xA008,0xA004,0xA002,0x6CB1,0x6CEE,0xA002,0x6CEB, 0x6CFA,0xA004,0xA002,0x6CD6,0x6CE0,0xA002,0x6CB2,0x6CD7,0xA008,0xA004,0xA002,0x6CF1,0x6CF8,0xA002,0x6CF7,0x6CAD, 0xA004,0xA002,0x6CD4,0x6CD0,0xA002,0x6CA9,0x6C86,0xA020,0xA010,0xA008,0xA004,0xA002,0x6C76,0x6C74,0xA002,0x6C69, 0x6C68,0xA004,0xA002,0x6C8C,0x6C94,0xA002,0x6C90,0x6C85,0xA008,0xA004,0xA002,0x6CA3,0x6C4A,0xA002,0x6C5C,0x6C54, 0xA004,0xA002,0x6C35,0x6215,0xA002,0x723F,0x4E2C,0xA010,0xA008,0xA004,0xA002,0x961A,0x9619,0xA002,0x9617,0x9616, 0xA004,0xA002,0x9615,0x9612,0xA002,0x960F,0x960D,0xA008,0xA004,0xA002,0x960C,0x960B,0xA002,0x960A,0x9608,0xA004, 0xA002,0x9606,0x9604,0xA002,0x9603,0x95FE,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x95FC,0x95F6,0xA002,0x95F5, 0x95F3,0xA004,0xA002,0x95F1,0x95EB,0xA002,0x95E9,0x96B3,0xA008,0xA004,0xA002,0x5FDD,0x61F5,0xA002,0x61D4,0x61B7, 0xA004,0xA002,0x61A7,0x6194,0xA002,0x61AC,0x6175,0xA010,0xA008,0xA004,0xA002,0x614A,0x612B,0xA002,0x610E,0x6100, 0xA004,0xA002,0x60F4,0x6123,0xA002,0x6115,0x6126,0xA008,0xA004,0xA002,0x6120,0x60B4,0xA002,0x60DA,0x60C6,0xA004, 0xA002,0x60D8,0x60DD,0xA002,0x60B1,0x60BB,0xA020,0xA010,0xA008,0xA004,0xA002,0x60EC,0x609B,0xA002,0x608C,0x6092, 0xA004,0xA002,0x6083,0x609D,0xA002,0x60AD,0x609A,0xA008,0xA004,0xA002,0x6096,0x607D,0xA002,0x606A,0x92A7,0xA004, 0xA002,0x92A6,0x92A5,0xA002,0x92A4,0x92A3,0xA010,0xA008,0xA004,0xA002,0x92A2,0x92A1,0xA002,0x92A0,0x929F,0xA004, 0xA002,0x929E,0x929D,0xA002,0x929C,0x929B,0xA008,0xA004,0xA002,0x929A,0x9299,0xA002,0x9298,0x9297,0xA004,0xA002, 0x9296,0x9295,0xA002,0x9294,0x9293,0xA09B,0xA07D,0xA03D,0xA01D,0xA00E,0xA006,0xA002,0x9292,0xA002,0x9291,0x9290, 0xA004,0xA002,0x928F,0x928D,0xA002,0x928C,0x928B,0xA008,0xA004,0xA002,0x928A,0x9289,0xA002,0x9288,0x9287,0xA003, 0xA000,0x9286,0xA002,0x9285,0x9284,0xA010,0xA008,0xA004,0xA002,0x9283,0x9282,0xA002,0x9281,0x9280,0xA004,0xA002, 0x927F,0x927E,0xA002,0x927D,0x927C,0xA008,0xA004,0xA002,0x927B,0x927A,0xA002,0x9279,0x9278,0xA004,0xA002,0x9277, 0x9276,0xA002,0x9275,0x9273,0xA020,0xA010,0xA008,0xA004,0xA002,0x9272,0x9271,0xA002,0x9270,0x926F,0xA004,0xA002, 0x926E,0x926D,0xA002,0x926C,0x926B,0xA008,0xA004,0xA002,0x926A,0x9269,0xA002,0x9268,0x9267,0xA004,0xA002,0x9266, 0x9265,0xA002,0x9264,0x9263,0xA010,0xA008,0xA004,0xA002,0x9262,0x9261,0xA002,0x9260,0x925F,0xA004,0xA002,0x925E, 0x925D,0xA002,0x925C,0x925B,0xA008,0xA004,0xA002,0x925A,0x9259,0xA002,0x9258,0x9257,0xA004,0xA002,0x9256,0x9255, 0xA002,0x9254,0x9253,0xA000,0xA000,0xA010,0xA008,0xA004,0xA002,0x9252,0x9251,0xA002,0x9250,0x924F,0xA004,0xA002, 0x924E,0x924D,0xA002,0x924C,0x924B,0xA008,0xA004,0xA002,0x924A,0x9249,0xA002,0x9248,0x9247,0xA000,0xA000,0x9246, 0xA066,0xA026,0xA006,0xA001,0xA001,0xA001,0xA001,0x6042,0xA010,0xA008,0xA004,0xA002,0x607A,0x607B,0xA002,0x6079, 0x6078,0xA004,0xA002,0x6021,0x603F,0xA002,0x600A,0x602B,0xA008,0xA004,0xA002,0x6029,0x600D,0xA002,0x600F,0x601B, 0xA004,0xA002,0x6026,0x6035,0xA002,0x6019,0x5FF8,0xA020,0xA010,0xA008,0xA004,0xA002,0x5FED,0x5FEA,0xA002,0x6006, 0x6005,0xA004,0xA002,0x5FFE,0x5FE4,0xA002,0x5FE1,0x6004,0xA008,0xA004,0xA002,0x5FEE,0x6003,0xA002,0x5FCF,0x5FD6, 0xA004,0xA002,0x5FC9,0x5FC4,0xA002,0x81BA,0x5EEA,0xA010,0xA008,0xA004,0xA002,0x5EE8,0x5EDB,0xA002,0x5ED1,0x5ED2, 0xA004,0xA002,0x8D53,0x5EB3,0xA002,0x5EBE,0x5EB5,0xA008,0xA004,0xA002,0x5EB9,0x5EA0,0xA002,0x5EA5,0x5E96,0xA004, 0xA002,0x5E8B,0x5E91,0xA002,0x5E80,0x9995,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x9994,0x9993,0xA002,0x9991, 0x9990,0xA004,0xA002,0x998D,0x998A,0xA002,0x9987,0x9984,0xA008,0xA004,0xA002,0x9980,0x997D,0xA002,0x9977,0x9974, 0xA004,0xA002,0x996C,0x996B,0xA002,0x996A,0x9969,0xA010,0xA008,0xA004,0xA002,0x9968,0x9967,0xA002,0x9963,0x5902, 0xA004,0xA002,0x5924,0x98E7,0xA002,0x5925,0x821B,0xA008,0xA004,0xA002,0x737E,0x736F,0xA002,0x736C,0x7360,0xA004, 0xA002,0x7357,0x734D,0xA002,0x7350,0x7331,0xA020,0xA010,0xA008,0xA004,0xA002,0x7338,0x732C,0xA002,0x7325,0x7339, 0xA004,0xA002,0x7322,0x7315,0xA002,0x731D,0x731E,0xA008,0xA004,0xA002,0x730A,0x7321,0xA002,0x7313,0x7317,0xA004, 0xA002,0x72FB,0x9245,0xA002,0x9244,0x9243,0xA010,0xA008,0xA004,0xA002,0x9242,0x9241,0xA002,0x9240,0x923F,0xA004, 0xA002,0x923E,0x923D,0xA002,0x923C,0x923B,0xA008,0xA004,0xA002,0x923A,0x9239,0xA002,0x9238,0x9237,0xA004,0xA002, 0x9236,0x9235,0xA002,0x9234,0x9233,0xA2FF,0xA17E,0xA09E,0xA07D,0xA03D,0xA01D,0xA00E,0xA006,0xA002,0x9232,0xA002, 0x9231,0x9230,0xA004,0xA002,0x922F,0x922E,0xA002,0x922D,0x922C,0xA008,0xA004,0xA002,0x922B,0x922A,0xA002,0x9229, 0x9228,0xA004,0xA002,0x9227,0x9226,0xA000,0x9225,0xA010,0xA008,0xA004,0xA002,0x9224,0x9223,0xA002,0x9222,0x9221, 0xA004,0xA002,0x9220,0x921F,0xA002,0x921E,0x921D,0xA008,0xA004,0xA002,0x921C,0x921B,0xA002,0x921A,0x9219,0xA004, 0xA002,0x9218,0x9217,0xA002,0x9216,0x9215,0xA020,0xA010,0xA008,0xA004,0xA002,0x9214,0x9213,0xA002,0x9212,0x9211, 0xA004,0xA002,0x9210,0x920F,0xA002,0x920E,0x920D,0xA008,0xA004,0xA002,0x920C,0x920B,0xA002,0x920A,0x9209,0xA004, 0xA002,0x9208,0x9207,0xA002,0x9206,0x9205,0xA010,0xA008,0xA004,0xA002,0x9204,0x9203,0xA002,0x9202,0x9201,0xA004, 0xA002,0x9200,0x91FF,0xA002,0x91FE,0x91FD,0xA008,0xA004,0xA002,0x91FC,0x91FB,0xA002,0x91FA,0x91F9,0xA004,0xA002, 0x91F8,0x91F7,0xA002,0x91F6,0x91F5,0xA000,0xA000,0xA010,0xA008,0xA004,0xA002,0x91F4,0x91F3,0xA002,0x91F2,0x91F1, 0xA004,0xA002,0x91F0,0x91EF,0xA002,0x91EE,0x91ED,0xA008,0xA004,0xA002,0x91EC,0x91EB,0xA002,0x91EA,0x91E9,0xA004, 0xA002,0x91E8,0x91E7,0xA000,0x91E6,0xA060,0xA020,0xA001,0xA00F,0xA007,0xA003,0xA001,0x72FA,0xA002,0x7303,0x72F3, 0xA004,0xA002,0x7301,0x72F7,0xA002,0x72F4,0x72F2,0xA008,0xA004,0xA002,0x72E9,0x72EF,0xA002,0x72E8,0x72D2,0xA004, 0xA002,0x72CD,0x72CE,0xA002,0x72C1,0x72C3,0xA020,0xA010,0xA008,0xA004,0xA002,0x72B8,0x72B7,0xA002,0x72B4,0x72B0, 0xA004,0xA002,0x72AD,0x5F61,0xA002,0x8862,0x5FBC,0xA008,0xA004,0xA002,0x5FB5,0x5FAD,0xA002,0x5FA8,0x5F9C,0xA004, 0xA002,0x5F99,0x5F95,0xA002,0x5F8C,0x5F89,0xA010,0xA008,0xA004,0xA002,0x5F87,0x5F82,0xA002,0x5F77,0x5F73,0xA004, 0xA002,0x5DC5,0x5DB7,0xA002,0x8C73,0x5D9D,0xA008,0xA004,0xA002,0x5D99,0x5D82,0xA002,0x5D74,0x5D69,0xA004,0xA002, 0x5D4A,0x5D4B,0xA002,0x5D6B,0x5D5D,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x5D6F,0x5D5B,0xA002,0x5D6C,0x5D3D, 0xA004,0xA002,0x5D34,0x5D3E,0xA002,0x5D58,0x5D1B,0xA008,0xA004,0xA002,0x5D06,0x5D1E,0xA002,0x5D24,0x5D2E,0xA004, 0xA002,0x5D26,0x5D27,0xA002,0x5D03,0x5D02,0xA010,0xA008,0xA004,0xA002,0x5CE5,0x5CCB,0xA002,0x5CE4,0x5CD2,0xA004, 0xA002,0x5CC4,0x5CB7,0xA002,0x5CC1,0x5CA3,0xA008,0xA004,0xA002,0x5CB1,0x5CAB,0xA002,0x5CAC,0x5CBD,0xA004,0xA002, 0x5CA2,0x5CB5,0xA002,0x5C9C,0x5C9A,0xA020,0xA010,0xA008,0xA004,0xA002,0x5C91,0x5C99,0xA002,0x5C98,0x5C88,0xA004, 0xA002,0x5C96,0x5C90,0xA002,0x5C8D,0x5C7A,0xA008,0xA004,0xA002,0x5C8C,0x5E61,0xA002,0x5E5E,0x5E5B,0xA004,0xA002, 0x5E54,0x5E44,0xA002,0x5E37,0x91E5,0xA010,0xA008,0xA004,0xA002,0x91E4,0x91E3,0xA002,0x91E2,0x91E1,0xA004,0xA002, 0x91E0,0x91DF,0xA002,0x91DE,0x91DD,0xA008,0xA004,0xA002,0x91DB,0x91DA,0xA002,0x91D9,0x91D8,0xA004,0xA002,0x91D7, 0x91D6,0xA002,0x91D5,0x91D4,0xA0A4,0xA07D,0xA03D,0xA01E,0xA00E,0xA006,0xA002,0x91D3,0xA002,0x91D2,0x91D0,0xA004, 0xA002,0x91CB,0x91C8,0xA002,0x91C6,0x91C5,0xA008,0xA004,0xA002,0x91C4,0x91C3,0xA002,0x91C2,0x91C1,0xA004,0xA002, 0x91C0,0x91BF,0xA002,0x91BE,0x91BD,0xA00F,0xA007,0xA003,0xA000,0x91BC,0xA002,0x91BB,0x91B9,0xA004,0xA002,0x91B8, 0x91B7,0xA002,0x91B6,0x91B3,0xA008,0xA004,0xA002,0x91B2,0x91B1,0xA002,0x91B0,0x91AC,0xA004,0xA002,0x91AB,0x91A9, 0xA002,0x91A8,0x91A7,0xA020,0xA010,0xA008,0xA004,0xA002,0x91A6,0x91A5,0xA002,0x91A4,0x91A1,0xA004,0xA002,0x91A0, 0x919F,0xA002,0x919E,0x919D,0xA008,0xA004,0xA002,0x919C,0x9199,0xA002,0x9198,0x9197,0xA004,0xA002,0x9196,0x9195, 0xA002,0x9194,0x9193,0xA010,0xA008,0xA004,0xA002,0x918F,0x918E,0xA002,0x918A,0x9188,0xA004,0xA002,0x9186,0x9184, 0xA002,0x9183,0x9182,0xA008,0xA004,0xA002,0x9181,0x9180,0xA002,0x917C,0x917B,0xA004,0xA002,0x917A,0x9173,0xA002, 0x916D,0x916B,0xA000,0xA020,0xA010,0xA008,0xA004,0xA002,0x9168,0x9167,0xA002,0x9166,0x9160,0xA004,0xA002,0x915F, 0x915C,0xA002,0x915B,0x9159,0xA008,0xA004,0xA002,0x9158,0x9156,0xA002,0x9155,0x9154,0xA004,0xA002,0x9153,0x9151, 0xA002,0x9148,0x9147,0xA000,0xA000,0xA000,0xA000,0x9145,0xA05D,0xA01D,0xA001,0xA00C,0xA004,0xA001,0xA001,0x5E3C, 0xA004,0xA002,0x5E3B,0x5E31,0xA002,0x5E11,0x5E14,0xA008,0xA004,0xA002,0x5E19,0x5E0F,0xA002,0x571C,0x5709,0xA004, 0xA002,0x570A,0x5704,0xA002,0x56FF,0x56F9,0xA020,0xA010,0xA008,0xA004,0xA002,0x56EB,0x56F5,0xA002,0x56E1,0x56DD, 0xA004,0xA002,0x56D7,0x56D4,0xA002,0x56AF,0x5693,0xA008,0xA004,0xA002,0x5685,0x567C,0xA002,0x567B,0x566B,0xA004, 0xA002,0x5671,0x5664,0xA002,0x5686,0x5654,0xA010,0xA008,0xA004,0xA002,0x564C,0x565C,0xA002,0x5659,0x5662,0xA004, 0xA002,0x564D,0x562C,0xA002,0x5657,0x5639,0xA008,0xA004,0xA002,0x5658,0x562D,0xA002,0x5627,0x5600,0xA004,0xA002, 0x55FE,0x5623,0xA002,0x5624,0x5601,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x560C,0x5608,0xA002,0x561E,0x8F94, 0xA004,0xA002,0x55E4,0x55F5,0xA002,0x55E8,0x55CD,0xA008,0xA004,0xA002,0x55CC,0x55F3,0xA002,0x55F2,0x55E5,0xA004, 0xA002,0x55EF,0x55C4,0xA002,0x55DD,0x55E6,0xA010,0xA008,0xA004,0xA002,0x55D4,0x55EC,0xA002,0x55EB,0x55D1,0xA004, 0xA002,0x561F,0x55C9,0xA002,0x55F7,0x55EA,0xA008,0xA004,0xA002,0x5599,0x5594,0xA002,0x55BE,0x55BD,0xA004,0xA002, 0x55DF,0x557B,0xA002,0x5591,0x55D6,0xA020,0xA010,0xA008,0xA004,0xA002,0x557E,0x559F,0xA002,0x5581,0x5588,0xA004, 0xA002,0x55B9,0x55B1,0xA002,0x5583,0x55D2,0xA008,0xA004,0xA002,0x558B,0x555C,0xA002,0x5530,0x5533,0xA004,0xA002, 0x5577,0x5576,0xA002,0x5575,0x5556,0xA010,0xA008,0xA004,0xA002,0x5537,0x9144,0xA002,0x9142,0x9141,0xA004,0xA002, 0x9140,0x913F,0xA002,0x913E,0x913D,0xA008,0xA004,0xA002,0x913C,0x913B,0xA002,0x913A,0x9138,0xA004,0xA002,0x9137, 0x9136,0xA002,0x9135,0x9134,0xA180,0xA0A7,0xA07D,0xA03D,0xA01E,0xA00E,0xA006,0xA002,0x9133,0xA002,0x9132,0x9130, 0xA004,0xA002,0x912E,0x912D,0xA002,0x912C,0x912B,0xA008,0xA004,0xA002,0x912A,0x9129,0xA002,0x9128,0x9127,0xA004, 0xA002,0x9126,0x9125,0xA002,0x9124,0x9121,0xA00F,0xA007,0xA004,0xA002,0x9120,0x911F,0xA000,0x911D,0xA004,0xA002, 0x911C,0x911B,0xA002,0x911A,0x9118,0xA008,0xA004,0xA002,0x9117,0x9116,0xA002,0x9115,0x9114,0xA004,0xA002,0x9113, 0x9112,0xA002,0x9111,0x9110,0xA020,0xA010,0xA008,0xA004,0xA002,0x910F,0x910E,0xA002,0x910D,0x910C,0xA004,0xA002, 0x910B,0x910A,0xA002,0x9109,0x9108,0xA008,0xA004,0xA002,0x9107,0x9106,0xA002,0x9105,0x9103,0xA004,0xA002,0x9101, 0x9100,0xA002,0x90FF,0x90FC,0xA010,0xA008,0xA004,0xA002,0x90FB,0x90FA,0xA002,0x90F9,0x90F7,0xA004,0xA002,0x90F6, 0x90F5,0xA002,0x90F3,0x90F2,0xA008,0xA004,0xA002,0x90F1,0x90F0,0xA002,0x90EE,0x90EC,0xA004,0xA002,0x90EA,0x90E9, 0xA002,0x90E5,0x90E4,0xA000,0xA020,0xA010,0xA008,0xA004,0xA002,0x90E3,0x90E0,0xA002,0x90DF,0x90DE,0xA004,0xA002, 0x90DA,0x90D9,0xA002,0x90D8,0x90D6,0xA008,0xA004,0xA002,0x90D5,0x90D4,0xA002,0x90D2,0x90CD,0xA004,0xA002,0x90CC, 0x90CB,0xA002,0x90C9,0x90C8,0xA000,0xA000,0xA004,0xA002,0x90C6,0x90C3,0xA000,0x90C2,0xA059,0xA019,0xA001,0xA008, 0xA001,0xA003,0xA001,0x553C,0xA002,0x5550,0x553F,0xA008,0xA004,0xA002,0x5555,0x5541,0xA002,0x556D,0x5549,0xA004, 0xA002,0x55B5,0x558F,0xA002,0x5567,0x552A,0xA020,0xA010,0xA008,0xA004,0xA002,0x5527,0x5511,0xA002,0x550F,0x5523, 0xA004,0xA002,0x5522,0x54F3,0xA002,0x5514,0x54FD,0xA008,0xA004,0xA002,0x5520,0x54E7,0xA002,0x551B,0x54DE,0xA004, 0xA002,0x54CF,0x54DD,0xA002,0x54A4,0x54AA,0xA010,0xA008,0xA004,0xA002,0x54A9,0x54DC,0xA002,0x54DA,0x54D9,0xA004, 0xA002,0x54CC,0x54BF,0xA002,0x54BB,0x54D5,0xA008,0xA004,0xA002,0x54A3,0x5472,0xA002,0x54D4,0x54D3,0xA004,0xA002, 0x54A6,0x54A7,0xA002,0x54D2,0x54B4,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x54C2,0x54AD,0xA002,0x54D0,0x549D, 0xA004,0xA002,0x5466,0x5476,0xA002,0x5484,0x549B,0xA008,0xA004,0xA002,0x549A,0x5464,0xA002,0x5471,0x5477,0xA004, 0xA002,0x5494,0x5482,0xA002,0x5432,0x5423,0xA010,0xA008,0xA004,0xA002,0x5459,0x5457,0xA002,0x5421,0x5443,0xA004, 0xA002,0x5456,0x5454,0xA002,0x5453,0x5452,0xA008,0xA004,0xA002,0x544B,0x5406,0xA002,0x5416,0x5412,0xA004,0xA002, 0x53FB,0x53E8,0xA002,0x53E9,0x53FD,0xA020,0xA010,0xA008,0xA004,0xA002,0x53F1,0x535F,0xA002,0x5F11,0x7519,0xA004, 0xA002,0x5FD2,0x5F0B,0xA002,0x652E,0x6525,0xA008,0xA004,0xA002,0x6509,0x64E2,0xA002,0x64E4,0x64D7,0xA004,0xA002, 0x64D0,0x64C0,0xA002,0x64BA,0x6499,0xA010,0xA008,0xA004,0xA002,0x64B8,0x64B7,0xA002,0x647A,0x90C0,0xA004,0xA002, 0x90BF,0x90BD,0xA002,0x90BC,0x90B7,0xA008,0xA004,0xA002,0x90B2,0x90AD,0xA002,0x90AB,0x90A9,0xA004,0xA002,0x90A8, 0x90A7,0xA002,0x90A5,0x90A4,0xA0AB,0xA07D,0xA03D,0xA01E,0xA00E,0xA006,0xA002,0x90A0,0xA002,0x909F,0x909E,0xA004, 0xA002,0x909C,0x909A,0xA002,0x9098,0x9096,0xA008,0xA004,0xA002,0x9094,0x9092,0xA002,0x9090,0x908F,0xA004,0xA002, 0x908E,0x908D,0xA002,0x908C,0x908A,0xA00F,0xA008,0xA004,0xA002,0x9089,0x9087,0xA002,0x9086,0x9085,0xA003,0xA000, 0x9084,0xA002,0x9081,0x907E,0xA008,0xA004,0xA002,0x907C,0x907B,0xA002,0x907A,0x9079,0xA004,0xA002,0x9078,0x9077, 0xA002,0x9076,0x9073,0xA020,0xA010,0xA008,0xA004,0xA002,0x9072,0x9071,0xA002,0x9070,0x906F,0xA004,0xA002,0x906C, 0x906B,0xA002,0x906A,0x9069,0xA008,0xA004,0xA002,0x9067,0x9066,0xA002,0x9064,0x9061,0xA004,0xA002,0x9060,0x905F, 0xA002,0x905E,0x905D,0xA010,0xA008,0xA004,0xA002,0x905C,0x905A,0xA002,0x9059,0x9056,0xA004,0xA002,0x9055,0x9054, 0xA002,0x904E,0x904C,0xA008,0xA004,0xA002,0x904B,0x904A,0xA002,0x9049,0x9048,0xA004,0xA002,0x9046,0x9045,0xA002, 0x9043,0x9040,0xA000,0xA020,0xA010,0xA008,0xA004,0xA002,0x903F,0x903D,0xA002,0x903A,0x9039,0xA004,0xA002,0x9037, 0x9034,0xA002,0x9033,0x9032,0xA008,0xA004,0xA002,0x9031,0x9030,0xA002,0x902C,0x902B,0xA004,0xA002,0x902A,0x9029, 0xA002,0x9028,0x9027,0xA000,0xA008,0xA004,0xA002,0x9025,0x9024,0xA002,0x9023,0x901C,0xA000,0xA000,0x9019,0xA056, 0xA016,0xA001,0xA005,0xA001,0xA001,0xA001,0x6496,0xA008,0xA004,0xA002,0x646D,0x6484,0xA002,0x645E,0x6421,0xA004, 0xA002,0x6426,0x640C,0xA002,0x6420,0x641B,0xA020,0xA010,0xA008,0xA004,0xA002,0x640B,0x6441,0xA002,0x6445,0x63BE, 0xA004,0xA002,0x63C6,0x6452,0xA002,0x63CE,0x63DE,0xA008,0xA004,0xA002,0x63C4,0x63FF,0xA002,0x63E0,0x63F8,0xA004, 0xA002,0x63F2,0x63BC,0xA002,0x63AE,0x6369,0xA010,0xA008,0xA004,0xA002,0x638A,0x63AC,0xA002,0x636D,0x63B4,0xA004, 0xA002,0x638E,0x637A,0xA002,0x6371,0x63F6,0xA008,0xA004,0xA002,0x63AD,0x6343,0xA002,0x634B,0x6339,0xA004,0xA002, 0x62F6,0x6322,0xA002,0x62EE,0x62D7,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x62DA,0x62CA,0xA002,0x62BB,0x629F, 0xA004,0xA002,0x626A,0x624C,0xA002,0x5C34,0x5C2C,0xA008,0xA004,0xA002,0x5C25,0x5C22,0xA002,0x530F,0x5958,0xA004, 0xA002,0x595A,0x5955,0xA002,0x8037,0x5941,0xA010,0xA008,0xA004,0xA002,0x593C,0x5F08,0xA002,0x5EFE,0x863C,0xA004, 0xA002,0x8616,0x8629,0xA002,0x8605,0x8627,0xA008,0xA004,0xA002,0x85FF,0x85DC,0xA002,0x85C1,0x85D3,0xA004,0xA002, 0x85B0,0x85B7,0xA002,0x85B9,0x8585,0xA020,0xA010,0xA008,0xA004,0xA002,0x859C,0x85AE,0xA002,0x8579,0x858F,0xA004, 0xA002,0x8587,0x85A8,0xA002,0x85A4,0x857B,0xA008,0xA004,0xA002,0x8572,0x8543,0xA002,0x77A2,0x857A,0xA004,0xA002, 0x855E,0x8564,0xA002,0x8568,0x8548,0xA010,0xA008,0xA004,0xA002,0x8559,0x84FC,0xA002,0x84FF,0x853B,0xA004,0xA002, 0x8556,0x9018,0xA002,0x9015,0x9013,0xA008,0xA004,0xA002,0x900E,0x900C,0xA002,0x9008,0x9007,0xA004,0xA002,0x8FFF, 0x8FFE,0xA002,0x8FFC,0x8FFB,0xB7DA,0xABEA,0xA5F6,0xA2FB,0xA17C,0xA0AD,0xA07D,0xA03D,0xA01E,0xA00E,0xA006,0xA002, 0x8FFA,0xA002,0x8FF6,0x8FF5,0xA004,0xA002,0x8FF4,0x8FF2,0xA002,0x8FF1,0x8FEF,0xA008,0xA004,0xA002,0x8FEC,0x8FE7, 0xA002,0x8FE3,0x8FE1,0xA004,0xA002,0x8FE0,0x8FDA,0xA002,0x8FD7,0x8FD6,0xA00F,0xA008,0xA004,0xA002,0x8FD2,0x8FCF, 0xA002,0x8FCD,0x8FCC,0xA004,0xA002,0x8FCB,0x8FCA,0xA000,0x8FC9,0xA008,0xA004,0xA002,0x8FC6,0x8FC3,0xA002,0x8FC0, 0x8FBF,0xA004,0xA002,0x8FBC,0x8FBB,0xA002,0x8FBA,0x8FB8,0xA020,0xA010,0xA008,0xA004,0xA002,0x8FB7,0x8FB5,0xA002, 0x8FB4,0x8FB3,0xA004,0xA002,0x8FB2,0x8FAF,0xA002,0x8FAE,0x8FAD,0xA008,0xA004,0xA002,0x8FAC,0x8FAA,0xA002,0x8FA7, 0x8FA6,0xA004,0xA002,0x8FA5,0x8FA4,0xA002,0x8FA2,0x8FA1,0xA010,0xA008,0xA004,0xA002,0x8FA0,0x8F9D,0xA002,0x8F92, 0x8F8C,0xA004,0xA002,0x8F80,0x8F6A,0xA002,0x8F65,0x8F64,0xA008,0xA004,0xA002,0x8F63,0x8F62,0xA002,0x8F61,0x8F60, 0xA004,0xA002,0x8F5F,0x8F5E,0xA002,0x8F5D,0x8F5C,0xA000,0xA01E,0xA00E,0xA006,0xA002,0x8F5B,0xA002,0x8F5A,0x8F59, 0xA004,0xA002,0x8F58,0x8F57,0xA002,0x8F56,0x8F55,0xA008,0xA004,0xA002,0x8F54,0x8F53,0xA002,0x8F52,0x8F51,0xA004, 0xA002,0x8F50,0x8F4F,0xA002,0x8F4E,0x8F4D,0xA000,0xA008,0xA004,0xA002,0x8F4C,0x8F4B,0xA002,0x8F4A,0x8F49,0xA004, 0xA002,0x8F48,0x8F47,0xA002,0x8F46,0x8F45,0xA04F,0xA00F,0xA001,0xA001,0xA005,0xA001,0xA002,0x853A,0x851F,0xA004, 0xA002,0x8539,0x84F0,0xA002,0x8538,0x750D,0xA020,0xA010,0xA008,0xA004,0xA002,0x850C,0x84E3,0xA002,0x84E5,0x8497, 0xA004,0xA002,0x84B4,0x84B9,0xA002,0x84A1,0x84E0,0xA008,0xA004,0xA002,0x84BA,0x84BF,0xA002,0x84CA,0x84D3,0xA004, 0xA002,0x84BD,0x84E6,0xA002,0x84D0,0x84CD,0xA010,0xA008,0xA004,0xA002,0x84C1,0x846D,0xA002,0x8431,0x848E,0xA004, 0xA002,0x848C,0x8476,0xA002,0x8469,0x8446,0xA008,0xA004,0xA002,0x843C,0x8478,0xA002,0x8489,0x847A,0xA004,0xA002, 0x8488,0x8487,0xA002,0x8473,0x8459,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x845A,0x8451,0xA002,0x845C,0x83E1, 0xA004,0xA002,0x83F0,0x8426,0xA002,0x83C0,0x83C5,0xA008,0xA004,0xA002,0x83EA,0x83F9,0xA002,0x83F8,0x8403,0xA004, 0xA002,0x840F,0x83DF,0xA002,0x83D4,0x8406,0xA010,0xA008,0xA004,0xA002,0x8411,0x8438,0xA002,0x841C,0x83D6,0xA004, 0xA002,0x83FD,0x83DD,0xA002,0x840B,0x8418,0xA008,0xA004,0xA002,0x5807,0x83D8,0xA002,0x83E5,0x8401,0xA004,0xA002, 0x83C1,0x83BC,0xA002,0x83BA,0x83A8,0xA020,0xA010,0xA008,0xA004,0xA002,0x839E,0x8398,0xA002,0x837B,0x83B8,0xA004, 0xA002,0x837D,0x83A9,0xA002,0x83B6,0x837C,0xA008,0xA004,0xA002,0x8385,0x839C,0xA002,0x8393,0x83AA,0xA004,0xA002, 0x83A0,0x83B4,0xA002,0x83B3,0x8378,0xA010,0xA008,0xA004,0xA002,0x83B0,0x836E,0xA002,0x836D,0x836A,0xA004,0xA002, 0x836C,0x8369,0xA002,0x831B,0x8368,0xA008,0xA004,0xA002,0x8F44,0x8F43,0xA002,0x8F42,0x8F41,0xA004,0xA002,0x8F40, 0x8F3F,0xA002,0x8F3E,0x8F3D,0xA0B4,0xA07D,0xA03D,0xA01E,0xA00E,0xA006,0xA002,0x8F3C,0xA002,0x8F3B,0x8F3A,0xA004, 0xA002,0x8F39,0x8F38,0xA002,0x8F37,0x8F36,0xA008,0xA004,0xA002,0x8F35,0x8F34,0xA002,0x8F33,0x8F32,0xA004,0xA002, 0x8F31,0x8F30,0xA002,0x8F2F,0x8F2E,0xA010,0xA008,0xA004,0xA002,0x8F2D,0x8F2C,0xA002,0x8F2B,0x8F2A,0xA004,0xA002, 0x8F29,0x8F28,0xA002,0x8F27,0x8F26,0xA007,0xA004,0xA002,0x8F25,0x8F24,0xA001,0x8F23,0xA004,0xA002,0x8F22,0x8F21, 0xA002,0x8F20,0x8F1F,0xA020,0xA010,0xA008,0xA004,0xA002,0x8F1E,0x8F1D,0xA002,0x8F1C,0x8F1B,0xA004,0xA002,0x8F1A, 0x8F19,0xA002,0x8F18,0x8F17,0xA008,0xA004,0xA002,0x8F16,0x8F15,0xA002,0x8F14,0x8F13,0xA004,0xA002,0x8F12,0x8F11, 0xA002,0x8F10,0x8F0F,0xA010,0xA008,0xA004,0xA002,0x8F0E,0x8F0D,0xA002,0x8F0C,0x8F0B,0xA004,0xA002,0x8F0A,0x8F09, 0xA002,0x8F08,0x8F07,0xA008,0xA004,0xA002,0x8F06,0x8F05,0xA002,0x8F04,0x8F03,0xA004,0xA002,0x8F02,0x8F01,0xA002, 0x8F00,0x8EFF,0xA000,0xA020,0xA010,0xA008,0xA004,0xA002,0x8EFE,0x8EFD,0xA002,0x8EFC,0x8EFB,0xA004,0xA002,0x8EFA, 0x8EF9,0xA002,0x8EF8,0x8EF7,0xA008,0xA004,0xA002,0x8EF6,0x8EF5,0xA002,0x8EF4,0x8EF3,0xA004,0xA002,0x8EF2,0x8EF1, 0xA002,0x8EF0,0x8EEF,0xA010,0xA008,0xA004,0xA002,0x8EEE,0x8EED,0xA002,0x8EEC,0x8EEB,0xA004,0xA002,0x8EEA,0x8EE9, 0xA002,0x8EE8,0x8EE7,0xA000,0xA000,0xA002,0x8EE6,0x8EE5,0xA04B,0xA00B,0xA001,0xA001,0xA001,0xA004,0xA002,0x8365, 0x8366,0xA002,0x8333,0x833A,0xA020,0xA010,0xA008,0xA004,0xA002,0x832D,0x8360,0xA002,0x8317,0x8340,0xA004,0xA002, 0x835F,0x8343,0xA002,0x8347,0x834F,0xA008,0xA004,0xA002,0x832F,0x835E,0xA002,0x839B,0x8331,0xA004,0xA002,0x8334, 0x833C,0xA002,0x8392,0x8308,0xA010,0xA008,0xA004,0xA002,0x835C,0x835B,0xA002,0x8351,0x831C,0xA004,0xA002,0x82D5, 0x82E0,0xA002,0x8315,0x8314,0xA008,0xA004,0xA002,0x8306,0x831A,0xA002,0x8311,0x82D3,0xA004,0xA002,0x82FB,0x830C, 0xA002,0x82D8,0x82D2,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x82F4,0x82DC,0xA002,0x8307,0x830F,0xA004,0xA002, 0x82E4,0x82F7,0xA002,0x8309,0x82E1,0xA008,0xA004,0xA002,0x82A4,0x82CE,0xA002,0x82C4,0x829F,0xA004,0xA002,0x82AA, 0x82A1,0xA002,0x82B4,0x82A9,0xA010,0xA008,0xA004,0xA002,0x82C1,0x82CC,0xA002,0x82CB,0x82AE,0xA004,0xA002,0x82B7, 0x8298,0xA002,0x82E3,0x82CA,0xA008,0xA004,0xA002,0x82C8,0x82B0,0xA002,0x82BE,0x82B8,0xA004,0xA002,0x82AB,0x8299, 0xA002,0x8297,0x8291,0xA020,0xA010,0xA008,0xA004,0xA002,0x828E,0x8284,0xA002,0x82A8,0x828A,0xA004,0xA002,0x828F, 0x827F,0xA002,0x827D,0x8279,0xA008,0xA004,0xA002,0x61FF,0x9F19,0xA002,0x99A8,0x5880,0xA004,0xA002,0x589A,0x5889, 0xA002,0x5881,0x586C,0xA010,0xA008,0xA004,0xA002,0x5865,0x5820,0xA002,0x5844,0x5819,0xA004,0xA002,0x581E,0x5800, 0xA002,0x57ED,0x57FD,0xA008,0xA004,0xA002,0x580D,0x580B,0xA002,0x8EE4,0x8EE3,0xA004,0xA002,0x8EE2,0x8EE1,0xA002, 0x8EE0,0x8EDF,0xA17F,0xA0B7,0xA07D,0xA03D,0xA01E,0xA00E,0xA006,0xA002,0x8EDE,0xA002,0x8EDD,0x8EDC,0xA004,0xA002, 0x8EDB,0x8EDA,0xA002,0x8ED9,0x8ED8,0xA008,0xA004,0xA002,0x8ED7,0x8ED6,0xA002,0x8ED5,0x8ED4,0xA004,0xA002,0x8ED3, 0x8ED2,0xA002,0x8ED1,0x8ED0,0xA010,0xA008,0xA004,0xA002,0x8ECF,0x8ECD,0xA002,0x8ECC,0x8ECB,0xA004,0xA002,0x8ECA, 0x8EC9,0xA002,0x8EC8,0x8EC7,0xA008,0xA004,0xA002,0x8EC6,0x8EC5,0xA002,0x8EC4,0x8EC3,0xA003,0xA001,0x8EC2,0xA002, 0x8EC1,0x8EC0,0xA020,0xA010,0xA008,0xA004,0xA002,0x8EBF,0x8EBE,0xA002,0x8EBD,0x8EBC,0xA004,0xA002,0x8EBB,0x8EB9, 0xA002,0x8EB8,0x8EB7,0xA008,0xA004,0xA002,0x8EB6,0x8EB5,0xA002,0x8EB4,0x8EB3,0xA004,0xA002,0x8EB1,0x8EB0,0xA002, 0x8EAE,0x8EAD,0xA010,0xA008,0xA004,0xA002,0x8EAA,0x8EA9,0xA002,0x8EA8,0x8EA7,0xA004,0xA002,0x8EA6,0x8EA5,0xA002, 0x8EA4,0x8EA3,0xA008,0xA004,0xA002,0x8EA2,0x8EA1,0xA002,0x8EA0,0x8E9F,0xA004,0xA002,0x8E9D,0x8E9B,0xA002,0x8E9A, 0x8E99,0xA000,0xA020,0xA010,0xA008,0xA004,0xA002,0x8E98,0x8E97,0xA002,0x8E96,0x8E95,0xA004,0xA002,0x8E93,0x8E92, 0xA002,0x8E91,0x8E8E,0xA008,0xA004,0xA002,0x8E8D,0x8E8C,0xA002,0x8E8B,0x8E8A,0xA004,0xA002,0x8E89,0x8E88,0xA002, 0x8E86,0x8E84,0xA010,0xA008,0xA004,0xA002,0x8E83,0x8E82,0xA002,0x8E80,0x8E7E,0xA004,0xA002,0x8E7D,0x8E7B,0xA002, 0x8E7A,0x8E79,0xA000,0xA004,0xA002,0x8E78,0x8E77,0xA002,0x8E75,0x8E73,0xA048,0xA008,0xA001,0xA001,0xA001,0xA001, 0xA002,0x57DD,0x57E4,0xA020,0xA010,0xA008,0xA004,0xA002,0x57F8,0x57EF,0xA002,0x57F4,0x57B8,0xA004,0xA002,0x57D2, 0x57D9,0xA002,0x57DA,0x57D8,0xA008,0xA004,0xA002,0x57D5,0x57A0,0xA002,0x5793,0x57B4,0xA004,0xA002,0x57A7,0x57CF, 0xA002,0x57B2,0x578C,0xA010,0xA008,0xA004,0xA002,0x57A4,0x57AD,0xA002,0x5773,0x5776,0xA004,0xA002,0x576D,0x5768, 0xA002,0x577B,0x577C,0xA008,0xA004,0xA002,0x5786,0x576B,0xA002,0x5785,0x5769,0xA004,0xA002,0x5742,0x573B,0xA002, 0x575C,0x572F,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x572E,0x5739,0xA002,0x5733,0x572A,0xA004,0xA002,0x572C, 0x5729,0xA002,0x58D1,0x58C5,0xA008,0xA004,0xA002,0x58BC,0x587E,0xA002,0x57A1,0x57A9,0xA004,0xA002,0x574C,0x5DEF, 0xA002,0x755A,0x5F01,0xA010,0xA008,0xA004,0xA002,0x53B6,0x9B2F,0xA002,0x51FC,0x51F5,0xA004,0xA002,0x5EF4,0x77CD, 0xA002,0x71EE,0x53DF,0xA008,0xA004,0xA002,0x52F0,0x52D6,0xA002,0x52D0,0x54FF,0xA004,0xA002,0x52BE,0x52AD,0xA002, 0x52AC,0x52A2,0xA020,0xA010,0xA008,0xA004,0xA002,0x5942,0x520D,0xA002,0x9146,0x9143,0xA004,0xA002,0x9139,0x912F, 0xA002,0x9131,0x9123,0xA008,0xA004,0xA002,0x911E,0x9122,0xA002,0x9104,0x90FE,0xA004,0xA002,0x90EF,0x90EB,0xA002, 0x90DB,0x90D7,0xA010,0xA008,0xA004,0xA002,0x90DC,0x90E2,0xA002,0x90E6,0x90D3,0xA004,0xA002,0x90C7,0x90C4,0xA002, 0x90D0,0x90BE,0xA008,0xA004,0xA002,0x90C5,0x90CF,0xA002,0x90B0,0x90B8,0xA004,0xA002,0x8E71,0x8E6E,0xA002,0x8E6B, 0x8E6A,0xA0BB,0xA07D,0xA03D,0xA01E,0xA00E,0xA006,0xA002,0x8E68,0xA002,0x8E67,0x8E65,0xA004,0xA002,0x8E64,0x8E63, 0xA002,0x8E62,0x8E61,0xA008,0xA004,0xA002,0x8E60,0x8E5F,0xA002,0x8E5E,0x8E5D,0xA004,0xA002,0x8E5C,0x8E5B,0xA002, 0x8E5A,0x8E58,0xA010,0xA008,0xA004,0xA002,0x8E57,0x8E56,0xA002,0x8E55,0x8E54,0xA004,0xA002,0x8E53,0x8E50,0xA002, 0x8E4F,0x8E4E,0xA008,0xA004,0xA002,0x8E4D,0x8E4C,0xA002,0x8E46,0x8E45,0xA004,0xA002,0x8E43,0x8E3F,0xA001,0x8E3E, 0xA020,0xA010,0xA008,0xA004,0xA002,0x8E3C,0x8E3B,0xA002,0x8E38,0x8E37,0xA004,0xA002,0x8E36,0x8E34,0xA002,0x8E33, 0x8E32,0xA008,0xA004,0xA002,0x8E30,0x8E2D,0xA002,0x8E2B,0x8E28,0xA004,0xA002,0x8E27,0x8E26,0xA002,0x8E25,0x8E24, 0xA010,0xA008,0xA004,0xA002,0x8E21,0x8E20,0xA002,0x8E1C,0x8E1B,0xA004,0xA002,0x8E1A,0x8E19,0xA002,0x8E18,0x8E17, 0xA008,0xA004,0xA002,0x8E16,0x8E15,0xA002,0x8E13,0x8E12,0xA004,0xA002,0x8E11,0x8E10,0xA002,0x8E0E,0x8E0D,0xA000, 0xA020,0xA010,0xA008,0xA004,0xA002,0x8E0B,0x8E08,0xA002,0x8E07,0x8E06,0xA004,0xA002,0x8E04,0x8E03,0xA002,0x8E02, 0x8E01,0xA008,0xA004,0xA002,0x8E00,0x8DFF,0xA002,0x8DFE,0x8DFC,0xA004,0xA002,0x8DF6,0x8DF4,0xA002,0x8DF2,0x8DF1, 0xA010,0xA008,0xA004,0xA002,0x8DF0,0x8DEE,0xA002,0x8DED,0x8DE9,0xA004,0xA002,0x8DE7,0x8DE6,0xA002,0x8DE5,0x8DE2, 0xA008,0xA004,0xA002,0x8DE1,0x8DE0,0xA002,0x8DDC,0x8DD9,0xA000,0xA002,0x8DD8,0x8DD5,0xA041,0xA001,0xA020,0xA010, 0xA008,0xA004,0xA002,0x90BA,0x90B6,0xA002,0x90B3,0x90B4,0xA004,0xA002,0x90A1,0x90AC,0xA002,0x9099,0x909D,0xA008, 0xA004,0xA002,0x909B,0x9097,0xA002,0x96B0,0x9697,0xA004,0xA002,0x968D,0x9688,0xA002,0x9674,0x9672,0xA010,0xA008, 0xA004,0xA002,0x966C,0x9667,0xA002,0x965F,0x9654,0xA004,0xA002,0x9649,0x9642,0xA002,0x963C,0x963D,0xA008,0xA004, 0xA002,0x962A,0x9631,0xA002,0x9621,0x9622,0xA004,0xA002,0x961D,0x537A,0xA002,0x5369,0x8C36,0xA040,0xA020,0xA010, 0xA008,0xA004,0xA002,0x8C35,0x8C33,0xA002,0x8C32,0x8C2F,0xA004,0xA002,0x8C2E,0x8C2B,0xA002,0x8C2A,0x8C27,0xA008, 0xA004,0xA002,0x8C25,0x8C21,0xA002,0x8C20,0x8C1F,0xA004,0xA002,0x8C1D,0x8C18,0xA002,0x8C1B,0x8C19,0xA010,0xA008, 0xA004,0xA002,0x8C16,0x8C15,0xA002,0x8C14,0x8C12,0xA004,0xA002,0x8C11,0x8C0F,0xA002,0x8C0C,0x8C07,0xA008,0xA004, 0xA002,0x8C04,0x8C02,0xA002,0x8C00,0x8BFF,0xA004,0xA002,0x8BFC,0x8BF9,0xA002,0x8BF6,0x8BF3,0xA020,0xA010,0xA008, 0xA004,0xA002,0x8BF0,0x8BEE,0xA002,0x8BE9,0x8BE8,0xA004,0xA002,0x8BE4,0x8BE0,0xA002,0x8BDF,0x8BDC,0xA008,0xA004, 0xA002,0x8BD9,0x8BD8,0xA002,0x8BD6,0x8BD4,0xA004,0xA002,0x8BD3,0x8BD2,0xA002,0x8BCE,0x8BCF,0xA010,0xA008,0xA004, 0xA002,0x8BCB,0x8BC3,0xA002,0x8BC2,0x8BB7,0xA004,0xA002,0x8BB5,0x8BB4,0xA002,0x8BAA,0x8BA7,0xA008,0xA004,0xA002, 0x8BA6,0x8BA0,0xA002,0x51A5,0x51A2,0xA004,0xA002,0x5196,0x51C7,0xA002,0x8DD4,0x8DD3,0xA2FF,0xA17F,0xA0C2,0xA07D, 0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x8DD2,0xA002,0x8DD0,0x8DCD,0xA004,0xA002,0x8DCA,0x8DC9,0xA002,0x8DC8,0x8DC7, 0xA008,0xA004,0xA002,0x8DC5,0x8DC2,0xA002,0x8DC1,0x8DC0,0xA004,0xA002,0x8DBD,0x8DBB,0xA002,0x8DB9,0x8DB7,0xA010, 0xA008,0xA004,0xA002,0x8DB6,0x8DB2,0xA002,0x8DB0,0x8DAF,0xA004,0xA002,0x8DAE,0x8DAD,0xA002,0x8DAC,0x8DAB,0xA008, 0xA004,0xA002,0x8DAA,0x8DA9,0xA002,0x8DA8,0x8DA7,0xA004,0xA002,0x8DA6,0x8DA5,0xA002,0x8DA4,0x8DA2,0xA01F,0xA00F, 0xA007,0xA003,0xA001,0x8DA1,0xA002,0x8DA0,0x8D9E,0xA004,0xA002,0x8D9D,0x8D9C,0xA002,0x8D9B,0x8D9A,0xA008,0xA004, 0xA002,0x8D99,0x8D98,0xA002,0x8D97,0x8D96,0xA004,0xA002,0x8D95,0x8D93,0xA002,0x8D92,0x8D90,0xA010,0xA008,0xA004, 0xA002,0x8D8F,0x8D8E,0xA002,0x8D8D,0x8D8C,0xA004,0xA002,0x8D89,0x8D88,0xA002,0x8D87,0x8D86,0xA008,0xA004,0xA002, 0x8D83,0x8D82,0xA002,0x8D80,0x8D7F,0xA004,0xA002,0x8D7E,0x8D7D,0xA002,0x8D7C,0x8D7B,0xA03E,0xA01E,0xA00E,0xA006, 0xA002,0x8D7A,0xA002,0x8D79,0x8D78,0xA004,0xA002,0x8D72,0x8D71,0xA002,0x8D6F,0x8D6E,0xA008,0xA004,0xA002,0x8D6C, 0x8D6A,0xA002,0x8D69,0x8D68,0xA004,0xA002,0x8D65,0x8D5F,0xA002,0x8D57,0x8D52,0xA010,0xA008,0xA004,0xA002,0x8D51, 0x8D20,0xA002,0x8D1C,0x8D1B,0xA004,0xA002,0x8D1A,0x8D19,0xA002,0x8D18,0x8D17,0xA008,0xA004,0xA002,0x8D16,0x8D15, 0xA002,0x8D14,0x8D13,0xA004,0xA002,0x8D12,0x8D11,0xA002,0x8D10,0x8D0F,0xA000,0xA000,0xA000,0xA000,0xA000,0x8D0E, 0xA03D,0xA001,0xA01C,0xA00C,0xA004,0xA001,0xA001,0x51BC,0xA004,0xA002,0x51BD,0x51B1,0xA002,0x51AB,0x7FB8,0xA008, 0xA004,0xA002,0x8803,0x5B34,0xA002,0x7980,0x88D2,0xA004,0xA002,0x8114,0x4EB5,0xA002,0x88A4,0x886E,0xA010,0xA008, 0xA004,0xA002,0x4EB3,0x5156,0xA002,0x4EA0,0x5155,0xA004,0xA002,0x5919,0x51EB,0xA002,0x5310,0x8A07,0xA008,0xA004, 0xA002,0x530D,0x52F9,0xA002,0x5914,0x5181,0xA004,0xA002,0x9998,0x9EC9,0xA002,0x5DFD,0x516E,0xA040,0xA020,0xA010, 0xA008,0xA004,0xA002,0x7C74,0x6C46,0xA002,0x9FA0,0x4FCE,0xA004,0xA002,0x4F65,0x4F58,0xA002,0x6C3D,0x4EDD,0xA008, 0xA004,0xA002,0x510B,0x5107,0xA002,0x50EE,0x50E6,0xA004,0xA002,0x50EC,0x50ED,0xA002,0x5106,0x50D6,0xA010,0xA008, 0xA004,0xA002,0x50BA,0x50A9,0xA002,0x50A7,0x50A5,0xA004,0xA002,0x507B,0x506C,0xA002,0x504E,0x5048,0xA008,0xA004, 0xA002,0x5055,0x5043,0xA002,0x507E,0x5028,0xA004,0xA002,0x5025,0x500C,0xA002,0x501C,0x4FFE,0xA020,0xA010,0xA008, 0xA004,0xA002,0x502D,0x502E,0xA002,0x500F,0x502C,0xA004,0xA002,0x4FF3,0x504C,0xA002,0x5029,0x4FF8,0xA008,0xA004, 0xA002,0x4FDF,0x4FD1,0xA002,0x4FDC,0x4FE3,0xA004,0xA002,0x4FDA,0x4FC5,0xA002,0x4FEA,0x4FE8,0xA010,0xA008,0xA004, 0xA002,0x4FE6,0x4F94,0xA002,0x4FAC,0x4F7C,0xA004,0xA002,0x4FAA,0x4F7B,0xA002,0x4F7E,0x4F8F,0xA008,0xA004,0xA002, 0x4F83,0x4F89,0xA002,0x4F91,0x4F74,0xA004,0xA002,0x4F76,0x4F3D,0xA002,0x4F32,0x4F57,0xA0C7,0xA07D,0xA03E,0xA01E, 0xA00E,0xA006,0xA002,0x4F5F,0xA002,0x8D0D,0x8D0C,0xA004,0xA002,0x8D0B,0x8D0A,0xA002,0x8D09,0x8D08,0xA008,0xA004, 0xA002,0x8D07,0x8D06,0xA002,0x8D05,0x8D04,0xA004,0xA002,0x8D03,0x8D02,0xA002,0x8D01,0x8D00,0xA010,0xA008,0xA004, 0xA002,0x8CFF,0x8CFE,0xA002,0x8CFD,0x8CFC,0xA004,0xA002,0x8CFB,0x8CFA,0xA002,0x8CF9,0x8CF8,0xA008,0xA004,0xA002, 0x8CF7,0x8CF6,0xA002,0x8CF5,0x8CF4,0xA004,0xA002,0x8CF3,0x8CF2,0xA002,0x8CF1,0x8CF0,0xA01F,0xA00F,0xA007,0xA004, 0xA002,0x8CEF,0x8CEE,0xA000,0x8CED,0xA004,0xA002,0x8CEC,0x8CEB,0xA002,0x8CEA,0x8CE9,0xA008,0xA004,0xA002,0x8CE8, 0x8CE7,0xA002,0x8CE6,0x8CE5,0xA004,0xA002,0x8CE4,0x8CE3,0xA002,0x8CE2,0x8CE1,0xA010,0xA008,0xA004,0xA002,0x8CE0, 0x8CDF,0xA002,0x8CDE,0x8CDD,0xA004,0xA002,0x8CDC,0x8CDB,0xA002,0x8CDA,0x8CD9,0xA008,0xA004,0xA002,0x8CD8,0x8CD7, 0xA002,0x8CD6,0x8CD5,0xA004,0xA002,0x8CD4,0x8CD3,0xA002,0x8CD2,0x8CD1,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002, 0x8CD0,0x8CCF,0xA002,0x8CCE,0x8CCD,0xA004,0xA002,0x8CCC,0x8CCB,0xA002,0x8CCA,0x8CC9,0xA008,0xA004,0xA002,0x8CC8, 0x8CC7,0xA002,0x8CC6,0x8CC5,0xA004,0xA002,0x8CC4,0x8CC3,0xA002,0x8CC2,0x8CC1,0xA010,0xA008,0xA004,0xA002,0x8CC0, 0x8CBF,0xA002,0x8CBE,0x8CBD,0xA004,0xA002,0x8CBC,0x8CBB,0xA002,0x8CBA,0x8CB9,0xA008,0xA004,0xA002,0x8CB8,0x8CB7, 0xA002,0x8CB6,0x8CB5,0xA004,0xA002,0x8CB4,0x8CB3,0xA002,0x8CB2,0x8CB1,0xA000,0xA000,0xA000,0xA004,0xA002,0x8CB0, 0x8CAF,0xA000,0x8CAE,0xA039,0xA001,0xA018,0xA008,0xA001,0xA003,0xA001,0x4F5D,0xA002,0x4F5A,0x6538,0xA008,0xA004, 0xA002,0x4F67,0x4F5E,0xA002,0x4F2B,0x4F09,0xA004,0xA002,0x4F27,0x4F25,0xA002,0x4EF5,0x4F64,0xA010,0xA008,0xA004, 0xA002,0x4F22,0x4EF3,0xA002,0x4F1B,0x4EDE,0xA004,0xA002,0x4EEB,0x4EE1,0xA002,0x4EE8,0x4EC2,0xA008,0xA004,0xA002, 0x4EC9,0x4EC3,0xA002,0x4EBB,0x7F54,0xA004,0xA002,0x5182,0x5293,0xA002,0x5290,0x5281,0xA040,0xA020,0xA010,0xA008, 0xA004,0xA002,0x5282,0x527D,0xA002,0x84AF,0x525C,0xA004,0xA002,0x5261,0x525E,0xA002,0x524C,0x5240,0xA008,0xA004, 0xA002,0x523F,0x5233,0xA002,0x522D,0x520E,0xA004,0xA002,0x5208,0x5202,0xA002,0x5363,0x5366,0xA010,0xA008,0xA004, 0xA002,0x8D5C,0x533E,0xA002,0x532E,0x5326,0xA004,0xA002,0x53F5,0x531A,0xA002,0x8D5D,0x9765,0xA008,0xA004,0xA002, 0x53AE,0x53A5,0xA002,0x53A3,0x539D,0xA004,0xA002,0x538D,0x4EC4,0xA002,0x560F,0x556C,0xA020,0xA010,0xA008,0xA004, 0xA002,0x5B5B,0x8288,0xA002,0x4E93,0x4E69,0xA004,0xA002,0x4E5C,0x9F10,0xA002,0x4E9F,0x4E36,0xA008,0xA004,0xA002, 0x9F17,0x777E,0xA002,0x6BD3,0x9997,0xA004,0xA002,0x80E4,0x56DF,0xA002,0x6C10,0x536E,0xA010,0xA008,0xA004,0xA002, 0x723B,0x592D,0xA002,0x4E47,0x5315,0xA004,0xA002,0x4E3F,0x79BA,0xA002,0x4E28,0x5669,0xA008,0xA004,0xA002,0x5B6C, 0x9B32,0xA002,0x4E1E,0x4E98,0xA004,0xA002,0x4E15,0x5345,0xA002,0x5EFF,0x4E10,0xA176,0xA0CB,0xA07D,0xA03E,0xA01E, 0xA00E,0xA006,0xA002,0x5140,0xA002,0x4E0C,0x4E8D,0xA004,0xA002,0x8CAD,0x8CAC,0xA002,0x8CAB,0x8CAA,0xA008,0xA004, 0xA002,0x8CA9,0x8CA8,0xA002,0x8CA7,0x8CA6,0xA004,0xA002,0x8CA5,0x8CA4,0xA002,0x8CA3,0x8CA2,0xA010,0xA008,0xA004, 0xA002,0x8CA1,0x8CA0,0xA002,0x8C9F,0x8C9E,0xA004,0xA002,0x8C9D,0x8C9C,0xA002,0x8C9B,0x8C9A,0xA008,0xA004,0xA002, 0x8C99,0x8C97,0xA002,0x8C96,0x8C95,0xA004,0xA002,0x8C93,0x8C92,0xA002,0x8C91,0x8C90,0xA01F,0xA00F,0xA008,0xA004, 0xA002,0x8C8F,0x8C8E,0xA002,0x8C8D,0x8C8B,0xA003,0xA000,0x8C88,0xA002,0x8C87,0x8C86,0xA008,0xA004,0xA002,0x8C84, 0x8C83,0xA002,0x8C81,0x8C80,0xA004,0xA002,0x8C7F,0x8C7E,0xA002,0x8C7D,0x8C7C,0xA010,0xA008,0xA004,0xA002,0x8C7B, 0x8C77,0xA002,0x8C76,0x8C75,0xA004,0xA002,0x8C74,0x8C72,0xA002,0x8C71,0x8C70,0xA008,0xA004,0xA002,0x8C6F,0x8C6E, 0xA002,0x8C6D,0x8C6C,0xA004,0xA002,0x8C69,0x8C68,0xA002,0x8C67,0x8C66,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002, 0x8C65,0x8C64,0xA002,0x8C63,0x8C60,0xA004,0xA002,0x8C5F,0x8C5E,0xA002,0x8C5D,0x8C5C,0xA008,0xA004,0xA002,0x8C5B, 0x8C59,0xA002,0x8C58,0x8C57,0xA004,0xA002,0x8C56,0x8C54,0xA002,0x8C53,0x8C52,0xA010,0xA008,0xA004,0xA002,0x8C51, 0x8C50,0xA002,0x8C4F,0x8C4E,0xA004,0xA002,0x8C4D,0x8C4B,0xA002,0x8C4A,0x8C48,0xA008,0xA004,0xA002,0x8C45,0x8C44, 0xA002,0x8C43,0x8C42,0xA004,0xA002,0x8C40,0x8C3F,0xA002,0x8C3E,0x8C3D,0xA000,0xA000,0xA008,0xA004,0xA002,0x8C3C, 0x8C3B,0xA002,0x8C3A,0x8C39,0xA000,0xA000,0x8C38,0xA02B,0xA001,0xA00A,0xA001,0xA001,0xA004,0xA002,0x5EA7,0x5750, 0xA002,0x4F5C,0x505A,0xA010,0xA008,0xA004,0xA002,0x67DE,0x4F50,0xA002,0x5DE6,0x6628,0xA004,0xA002,0x9075,0x5C0A, 0xA002,0x7F6A,0x6700,0xA008,0xA004,0xA002,0x9189,0x5634,0xA002,0x7E82,0x94BB,0xA004,0xA002,0x7EC4,0x963B,0xA002, 0x8BC5,0x7956,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x65CF,0x5352,0xA002,0x8DB3,0x79DF,0xA004,0xA002,0x63CD, 0x594F,0xA002,0x8D70,0x90B9,0xA008,0xA004,0xA002,0x7EB5,0x603B,0xA002,0x7EFC,0x5B97,0xA004,0xA002,0x8E2A,0x68D5, 0xA002,0x9B03,0x5B57,0xA010,0xA008,0xA004,0xA002,0x6E0D,0x81EA,0xA002,0x5B50,0x6ED3,0xA004,0xA002,0x7C7D,0x4ED4, 0xA002,0x7D2B,0x5B5C,0xA008,0xA004,0xA002,0x6DC4,0x6ECB,0xA002,0x59FF,0x8D44,0xA004,0xA002,0x54A8,0x5179,0xA002, 0x6D4A,0x707C,0xA020,0xA010,0xA008,0xA004,0xA002,0x7740,0x5544,0xA002,0x914C,0x8301,0xA004,0xA002,0x7422,0x684C, 0xA002,0x5353,0x62D9,0xA008,0xA004,0xA002,0x6349,0x51C6,0xA002,0x8C06,0x7F00,0xA004,0xA002,0x5760,0x8D58,0xA002, 0x8FFD,0x9525,0xA010,0xA008,0xA004,0xA002,0x690E,0x72B6,0xA002,0x58EE,0x649E,0xA004,0xA002,0x5986,0x88C5,0xA002, 0x5E84,0x6869,0xA008,0xA004,0xA002,0x7BC6,0x8D5A,0xA002,0x64B0,0x8F6C,0xA004,0xA002,0x7816,0x4E13,0xA002,0x62FD, 0x722A,0xA0CE,0xA07D,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x6293,0xA002,0x9A7B,0x795D,0xA004,0xA002,0x6CE8,0x4F4F, 0xA002,0x8C1E,0x8C09,0xA008,0xA004,0xA002,0x8BEA,0x8BD0,0xA002,0x8BC7,0x8BBB,0xA004,0xA002,0x8BB1,0x8BAC,0xA002, 0x8B9F,0x8B9E,0xA010,0xA008,0xA004,0xA002,0x8B9D,0x8B9C,0xA002,0x8B9B,0x8B9A,0xA004,0xA002,0x8B99,0x8B98,0xA002, 0x8B97,0x8B96,0xA008,0xA004,0xA002,0x8B95,0x8B94,0xA002,0x8B93,0x8B92,0xA004,0xA002,0x8B91,0x8B90,0xA002,0x8B8F, 0x8B8E,0xA01F,0xA00F,0xA008,0xA004,0xA002,0x8B8D,0x8B8C,0xA002,0x8B8B,0x8B8A,0xA004,0xA002,0x8B89,0x8B88,0xA000, 0x8B87,0xA008,0xA004,0xA002,0x8B86,0x8B85,0xA002,0x8B84,0x8B83,0xA004,0xA002,0x8B82,0x8B81,0xA002,0x8B80,0x8B7F, 0xA010,0xA008,0xA004,0xA002,0x8B7E,0x8B7D,0xA002,0x8B7C,0x8B7B,0xA004,0xA002,0x8B7A,0x8B79,0xA002,0x8B78,0x8B77, 0xA008,0xA004,0xA002,0x8B76,0x8B75,0xA002,0x8B74,0x8B73,0xA004,0xA002,0x8B72,0x8B71,0xA002,0x8B70,0x8B6F,0xA040, 0xA020,0xA010,0xA008,0xA004,0xA002,0x8B6E,0x8B6D,0xA002,0x8B6B,0x8B6A,0xA004,0xA002,0x8B69,0x8B68,0xA002,0x8B67, 0x8B65,0xA008,0xA004,0xA002,0x8B64,0x8B63,0xA002,0x8B62,0x8B61,0xA004,0xA002,0x8B60,0x8B5F,0xA002,0x8B5E,0x8B5D, 0xA010,0xA008,0xA004,0xA002,0x8B5C,0x8B5B,0xA002,0x8B5A,0x8B59,0xA004,0xA002,0x8B58,0x8B57,0xA002,0x8B56,0x8B55, 0xA008,0xA004,0xA002,0x8B54,0x8B53,0xA002,0x8B52,0x8B51,0xA004,0xA002,0x8B50,0x8B4F,0xA002,0x8B4E,0x8B4D,0xA000, 0xA000,0xA008,0xA004,0xA002,0x8B4C,0x8B4B,0xA002,0x8B4A,0x8B49,0xA004,0xA002,0x8B48,0x8B47,0xA000,0x8B46,0xA031, 0xA001,0xA010,0xA001,0xA007,0xA003,0xA001,0x7B51,0xA002,0x94F8,0x8D2E,0xA004,0xA002,0x86C0,0x52A9,0xA002,0x67F1, 0x8457,0xA010,0xA008,0xA004,0xA002,0x4E3B,0x5631,0xA002,0x77A9,0x62C4,0xA004,0xA002,0x716E,0x70DB,0xA002,0x7AF9, 0x9010,0xA008,0xA004,0xA002,0x8BDB,0x8BF8,0xA002,0x732A,0x6731,0xA004,0xA002,0x86DB,0x682A,0xA002,0x73E0,0x9AA4, 0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x663C,0x5B99,0xA002,0x76B1,0x5492,0xA004,0xA002,0x5E1A,0x8098,0xA002, 0x8F74,0x7CA5,0xA008,0xA004,0xA002,0x8BCC,0x6D32,0xA002,0x5DDE,0x5468,0xA004,0xA002,0x821F,0x4F17,0xA002,0x4EF2, 0x91CD,0xA010,0xA008,0xA004,0xA002,0x80BF,0x79CD,0xA002,0x7EC8,0x8877,0xA004,0xA002,0x949F,0x5FE0,0xA002,0x76C5, 0x4E2D,0xA008,0xA004,0xA002,0x7A92,0x6CBB,0xA002,0x6EDE,0x75D4,0xA004,0xA002,0x7099,0x8D28,0xA002,0x7A1A,0x79E9, 0xA020,0xA010,0xA008,0xA004,0xA002,0x667A,0x5236,0xA002,0x5CD9,0x5E1C,0xA004,0xA002,0x7F6E,0x81F4,0xA002,0x81F3, 0x63B7,0xA008,0xA004,0xA002,0x631A,0x5FD7,0xA002,0x7EB8,0x65E8,0xA004,0xA002,0x53EA,0x8DBE,0xA002,0x6B62,0x6307, 0xA010,0xA008,0xA004,0xA002,0x5740,0x4F84,0xA002,0x503C,0x6267,0xA004,0xA002,0x6B96,0x690D,0xA002,0x76F4,0x804C, 0xA008,0xA004,0xA002,0x7EC7,0x4E4B,0xA002,0x6C41,0x8102,0xA004,0xA002,0x80A2,0x77E5,0xA002,0x8718,0x5431,0xA5F6, 0xA2FC,0xA17D,0xA0D2,0xA07D,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x652F,0xA002,0x679D,0x829D,0xA004,0xA002,0x8BC1, 0x90D1,0xA002,0x75C7,0x5E27,0xA008,0xA004,0xA002,0x8B45,0x8B44,0xA002,0x8B43,0x8B42,0xA004,0xA002,0x8B41,0x8B40, 0xA002,0x8B3F,0x8B3E,0xA010,0xA008,0xA004,0xA002,0x8B3D,0x8B3C,0xA002,0x8B3B,0x8B3A,0xA004,0xA002,0x8B39,0x8B38, 0xA002,0x8B37,0x8B36,0xA008,0xA004,0xA002,0x8B35,0x8B34,0xA002,0x8B33,0x8B32,0xA004,0xA002,0x8B31,0x8B30,0xA002, 0x8B2F,0x8B2E,0xA01F,0xA010,0xA008,0xA004,0xA002,0x8B2D,0x8B2C,0xA002,0x8B2B,0x8B2A,0xA004,0xA002,0x8B29,0x8B28, 0xA002,0x8B27,0x8B25,0xA007,0xA003,0xA000,0x8B24,0xA002,0x8B23,0x8B22,0xA004,0xA002,0x8B21,0x8B20,0xA002,0x8B1F, 0x8B1E,0xA010,0xA008,0xA004,0xA002,0x8B1D,0x8B1C,0xA002,0x8B1B,0x8B1A,0xA004,0xA002,0x8B19,0x8B18,0xA002,0x8B17, 0x8B16,0xA008,0xA004,0xA002,0x8B15,0x8B14,0xA002,0x8B13,0x8B12,0xA004,0xA002,0x8B11,0x8B10,0xA002,0x8B0F,0x8B0E, 0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x8B0D,0xA002,0x8B0C,0x8B0B,0xA004,0xA002,0x8B0A,0x8B09,0xA002,0x8B08,0x8B06, 0xA008,0xA004,0xA002,0x8B05,0x8B04,0xA002,0x8B03,0x8B02,0xA004,0xA002,0x8B01,0x8B00,0xA002,0x8AFF,0x8AFE,0xA010, 0xA008,0xA004,0xA002,0x8AFD,0x8AFC,0xA002,0x8AFB,0x8AFA,0xA004,0xA002,0x8AF9,0x8AF8,0xA002,0x8AF7,0x8AF6,0xA008, 0xA004,0xA002,0x8AF5,0x8AF4,0xA002,0x8AF3,0x8AF2,0xA004,0xA002,0x8AF1,0x8AF0,0xA002,0x8AEF,0x8AEE,0xA000,0xA010, 0xA008,0xA004,0xA002,0x8AED,0x8AEC,0xA002,0x8AEB,0x8AEA,0xA004,0xA002,0x8AE9,0x8AE8,0xA002,0x8AE7,0x8AE6,0xA000, 0xA000,0xA002,0x8AE5,0x8AE4,0xA02B,0xA001,0xA00A,0xA001,0xA001,0xA004,0xA002,0x653F,0x6B63,0xA002,0x62EF,0x6574, 0xA010,0xA008,0xA004,0xA002,0x6014,0x4E89,0xA002,0x72F0,0x5F81,0xA004,0xA002,0x7741,0x6323,0xA002,0x84B8,0x9635, 0xA008,0xA004,0xA002,0x9547,0x632F,0xA002,0x9707,0x8BCA,0xA004,0xA002,0x75B9,0x6795,0xA002,0x4FA6,0x9488,0xA040, 0xA020,0xA010,0xA008,0xA004,0xA002,0x8D1E,0x81FB,0xA002,0x7827,0x7504,0xA004,0xA002,0x771F,0x659F,0xA002,0x73CD, 0x6D59,0xA008,0xA004,0xA002,0x8FD9,0x8517,0xA002,0x9517,0x8005,0xA004,0xA002,0x8F99,0x86F0,0xA002,0x54F2,0x6298, 0xA010,0xA008,0xA004,0xA002,0x906E,0x53EC,0xA002,0x8087,0x5146,0xA004,0xA002,0x7F69,0x7167,0xA002,0x8D75,0x6CBC, 0xA008,0xA004,0xA002,0x627E,0x662D,0xA002,0x62DB,0x969C,0xA004,0xA002,0x7634,0x80C0,0xA002,0x4ED7,0x8D26,0xA020, 0xA010,0xA008,0xA004,0xA002,0x5E10,0x4E08,0xA002,0x6756,0x6DA8,0xA004,0xA002,0x638C,0x5F20,0xA002,0x6F33,0x5F70, 0xA008,0xA004,0xA002,0x7AE0,0x6A1F,0xA002,0x7EFD,0x6E5B,0xA004,0xA002,0x7AD9,0x6218,0xA002,0x5360,0x6808,0xA010, 0xA008,0xA004,0xA002,0x8638,0x5C55,0xA002,0x5D2D,0x8F97,0xA004,0xA002,0x65A9,0x76CF,0xA002,0x6CBE,0x7C98,0xA008, 0xA004,0xA002,0x8A79,0x6BE1,0xA002,0x77BB,0x5BE8,0xA004,0xA002,0x503A,0x7A84,0xA002,0x5B85,0x658B,0xA0D7,0xA07D, 0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x6458,0xA002,0x8BC8,0x70B8,0xA004,0xA002,0x4E4D,0x548B,0xA002,0x69A8,0x6805, 0xA008,0xA004,0xA002,0x7728,0x95F8,0xA002,0x94E1,0x8AE3,0xA004,0xA002,0x8AE2,0x8AE1,0xA002,0x8AE0,0x8ADF,0xA010, 0xA008,0xA004,0xA002,0x8ADE,0x8ADD,0xA002,0x8ADC,0x8ADB,0xA004,0xA002,0x8ADA,0x8AD9,0xA002,0x8AD8,0x8AD7,0xA008, 0xA004,0xA002,0x8AD6,0x8AD5,0xA002,0x8AD4,0x8AD3,0xA004,0xA002,0x8AD2,0x8AD1,0xA002,0x8AD0,0x8ACF,0xA01F,0xA010, 0xA008,0xA004,0xA002,0x8ACE,0x8ACD,0xA002,0x8ACC,0x8ACB,0xA004,0xA002,0x8ACA,0x8AC9,0xA002,0x8AC8,0x8AC7,0xA008, 0xA004,0xA002,0x8AC6,0x8AC5,0xA002,0x8AC4,0x8AC3,0xA003,0xA001,0x8AC2,0xA002,0x8AC1,0x8AC0,0xA010,0xA008,0xA004, 0xA002,0x8ABF,0x8ABE,0xA002,0x8ABD,0x8ABC,0xA004,0xA002,0x8ABB,0x8ABA,0xA002,0x8AB9,0x8AB8,0xA008,0xA004,0xA002, 0x8AB7,0x8AB6,0xA002,0x8AB5,0x8AB4,0xA004,0xA002,0x8AB3,0x8AB2,0xA002,0x8AB1,0x8AB0,0xA040,0xA020,0xA010,0xA008, 0xA004,0xA002,0x8AAF,0x8AAE,0xA002,0x8AAD,0x8AAC,0xA004,0xA002,0x8AAB,0x8AAA,0xA002,0x8AA9,0x8AA8,0xA008,0xA004, 0xA002,0x8AA7,0x8AA6,0xA002,0x8AA5,0x8AA4,0xA004,0xA002,0x8AA3,0x8AA2,0xA002,0x8AA1,0x8AA0,0xA010,0xA008,0xA004, 0xA002,0x8A9F,0x8A9E,0xA002,0x8A9D,0x8A9C,0xA004,0xA002,0x8A9B,0x8A9A,0xA002,0x8A99,0x8A98,0xA008,0xA004,0xA002, 0x8A97,0x8A96,0xA002,0x8A95,0x8A94,0xA004,0xA002,0x8A92,0x8A91,0xA002,0x8A90,0x8A8F,0xA000,0xA010,0xA008,0xA004, 0xA002,0x8A8E,0x8A8D,0xA002,0x8A8C,0x8A8B,0xA004,0xA002,0x8A88,0x8A87,0xA002,0x8A86,0x8A85,0xA000,0xA004,0xA002, 0x8A84,0x8A83,0xA002,0x8A82,0x8A81,0xA028,0xA001,0xA007,0xA001,0xA001,0xA001,0xA002,0x8F67,0x672D,0xA010,0xA008, 0xA004,0xA002,0x6E23,0x55B3,0xA002,0x624E,0x8D60,0xA004,0xA002,0x66FE,0x618E,0xA002,0x589E,0x600E,0xA008,0xA004, 0xA002,0x8D3C,0x6CFD,0xA002,0x5219,0x62E9,0xA004,0xA002,0x8D23,0x71E5,0xA002,0x7076,0x7682,0xA040,0xA020,0xA010, 0xA008,0xA004,0xA002,0x9020,0x566A,0xA002,0x8E81,0x86A4,0xA004,0xA002,0x6FA1,0x65E9,0xA002,0x67A3,0x85FB,0xA008, 0xA004,0xA002,0x51FF,0x7CDF,0xA002,0x906D,0x846C,0xA004,0xA002,0x810F,0x8D43,0xA002,0x8D5E,0x6682,0xA010,0xA008, 0xA004,0xA002,0x6512,0x54B1,0xA002,0x5728,0x518D,0xA004,0xA002,0x8F7D,0x5BB0,0xA002,0x707E,0x54C9,0xA008,0xA004, 0xA002,0x683D,0x6742,0xA002,0x7838,0x531D,0xA004,0xA002,0x5B55,0x97F5,0xA002,0x6655,0x915D,0xA020,0xA010,0xA008, 0xA004,0xA002,0x8574,0x8FD0,0xA002,0x5141,0x9668,0xA004,0xA002,0x5300,0x90E7,0xA002,0x4E91,0x8018,0xA008,0xA004, 0xA002,0x9605,0x60A6,0xA002,0x6708,0x7CA4,0xA004,0xA002,0x5CB3,0x94A5,0xA002,0x8DC3,0x8D8A,0xA010,0xA008,0xA004, 0xA002,0x7EA6,0x66F0,0xA002,0x9662,0x6028,0xA004,0xA002,0x613F,0x82D1,0xA002,0x8FDC,0x7F18,0xA008,0xA004,0xA002, 0x6E90,0x733F,0xA002,0x5706,0x5458,0xA004,0xA002,0x56ED,0x8F95,0xA002,0x63F4,0x539F,0xA17D,0xA0DB,0xA07D,0xA03E, 0xA01E,0xA00E,0xA006,0xA002,0x8881,0xA002,0x57A3,0x5143,0xA004,0xA002,0x51A4,0x6E0A,0xA002,0x9E33,0x9A6D,0xA008, 0xA004,0xA002,0x8C6B,0x9884,0xA002,0x88D5,0x5BD3,0xA004,0xA002,0x6D74,0x8A80,0xA002,0x8A7F,0x8A7E,0xA010,0xA008, 0xA004,0xA002,0x8A7D,0x8A7C,0xA002,0x8A7B,0x8A7A,0xA004,0xA002,0x8A78,0x8A77,0xA002,0x8A76,0x8A75,0xA008,0xA004, 0xA002,0x8A74,0x8A73,0xA002,0x8A72,0x8A71,0xA004,0xA002,0x8A70,0x8A6F,0xA002,0x8A6E,0x8A6D,0xA01F,0xA010,0xA008, 0xA004,0xA002,0x8A6C,0x8A6B,0xA002,0x8A6A,0x8A69,0xA004,0xA002,0x8A68,0x8A67,0xA002,0x8A66,0x8A65,0xA008,0xA004, 0xA002,0x8A64,0x8A63,0xA002,0x8A62,0x8A61,0xA004,0xA002,0x8A60,0x8A5F,0xA001,0x8A5E,0xA010,0xA008,0xA004,0xA002, 0x8A5D,0x8A5C,0xA002,0x8A5B,0x8A5A,0xA004,0xA002,0x8A59,0x8A58,0xA002,0x8A57,0x8A56,0xA008,0xA004,0xA002,0x8A55, 0x8A54,0xA002,0x8A53,0x8A52,0xA004,0xA002,0x8A51,0x8A50,0xA002,0x8A4F,0x8A4E,0xA040,0xA020,0xA010,0xA008,0xA004, 0xA002,0x8A4D,0x8A4C,0xA002,0x8A4B,0x8A4A,0xA004,0xA002,0x8A49,0x8A47,0xA002,0x8A46,0x8A45,0xA008,0xA004,0xA002, 0x8A44,0x8A43,0xA002,0x8A42,0x8A41,0xA004,0xA002,0x8A40,0x8A3F,0xA002,0x8A3D,0x8A3C,0xA010,0xA008,0xA004,0xA002, 0x8A3B,0x8A3A,0xA002,0x8A39,0x8A38,0xA004,0xA002,0x8A37,0x8A36,0xA002,0x8A35,0x8A34,0xA008,0xA004,0xA002,0x8A33, 0x8A32,0xA002,0x8A31,0x8A30,0xA004,0xA002,0x8A2F,0x8A2E,0xA002,0x8A2D,0x8A2C,0xA000,0xA010,0xA008,0xA004,0xA002, 0x8A2B,0x8A2A,0xA002,0x8A29,0x8A28,0xA004,0xA002,0x8A27,0x8A26,0xA002,0x8A25,0x8A24,0xA008,0xA004,0xA002,0x8A23, 0x8A22,0xA002,0x8A21,0x8A20,0xA000,0xA002,0x8A1F,0x8A1E,0xA022,0xA001,0xA001,0xA010,0xA008,0xA004,0xA002,0x8A89, 0x80B2,0xA002,0x72F1,0x6B32,0xA004,0xA002,0x6108,0x5FA1,0xA002,0x5CEA,0x55BB,0xA008,0xA004,0xA002,0x9047,0x5401, 0xA002,0x90C1,0x828B,0xA004,0xA002,0x57DF,0x7389,0xA002,0x7FBD,0x8BED,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002, 0x5B87,0x79B9,0xA002,0x5C7F,0x4E0E,0xA004,0xA002,0x96E8,0x5A31,0xA002,0x4E88,0x9685,0xA008,0xA004,0xA002,0x6E14, 0x6E1D,0xA002,0x6109,0x9C7C,0xA004,0xA002,0x903E,0x4FDE,0xA002,0x4F59,0x8206,0xA010,0xA008,0xA004,0xA002,0x611A, 0x865E,0xA002,0x6986,0x76C2,0xA004,0xA002,0x4E8E,0x6DE4,0xA002,0x8FC2,0x5E7C,0xA008,0xA004,0xA002,0x53C8,0x8BF1, 0xA002,0x91C9,0x4F51,0xA004,0xA002,0x53F3,0x53CB,0xA002,0x6709,0x9149,0xA020,0xA010,0xA008,0xA004,0xA002,0x6E38, 0x6CB9,0xA002,0x72B9,0x94C0,0xA004,0xA002,0x90AE,0x7531,0xA002,0x5C24,0x5FE7,0xA008,0xA004,0xA002,0x60A0,0x4F18, 0xA002,0x5E7D,0x7528,0xA004,0xA002,0x52C7,0x607F,0xA002,0x6C38,0x6D8C,0xA010,0xA008,0xA004,0xA002,0x6CF3,0x548F, 0xA002,0x86F9,0x8E0A,0xA004,0xA002,0x96CD,0x5EB8,0xA002,0x75C8,0x81C3,0xA008,0xA004,0xA002,0x4F63,0x62E5,0xA002, 0x54DF,0x6620,0xA004,0xA002,0x786C,0x9896,0xA002,0x5F71,0x76C8,0xA0DE,0xA07D,0xA03E,0xA01E,0xA00E,0xA006,0xA002, 0x8D62,0xA002,0x8FCE,0x8747,0xA004,0xA002,0x8367,0x8425,0xA002,0x8424,0x83B9,0xA008,0xA004,0xA002,0x7F28,0x5E94, 0xA002,0x9E70,0x5A74,0xA004,0xA002,0x6A31,0x82F1,0xA002,0x5370,0x8A1D,0xA010,0xA008,0xA004,0xA002,0x8A1C,0x8A1B, 0xA002,0x8A1A,0x8A19,0xA004,0xA002,0x8A18,0x8A17,0xA002,0x8A16,0x8A15,0xA008,0xA004,0xA002,0x8A14,0x8A13,0xA002, 0x8A12,0x8A11,0xA004,0xA002,0x8A10,0x8A0F,0xA002,0x8A0E,0x8A0D,0xA020,0xA010,0xA008,0xA004,0xA002,0x8A0C,0x8A0B, 0xA002,0x8A0A,0x8A09,0xA004,0xA002,0x8A08,0x8A06,0xA002,0x8A05,0x8A04,0xA008,0xA004,0xA002,0x8A03,0x8A02,0xA002, 0x8A01,0x89FF,0xA004,0xA002,0x89FE,0x89FD,0xA002,0x89FC,0x89FB,0xA00F,0xA007,0xA003,0xA001,0x89FA,0xA002,0x89F9, 0x89F8,0xA004,0xA002,0x89F7,0x89F6,0xA002,0x89F5,0x89F4,0xA008,0xA004,0xA002,0x89F2,0x89F1,0xA002,0x89F0,0x89EE, 0xA004,0xA002,0x89ED,0x89EC,0xA002,0x89EA,0x89E9,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x89E8,0x89E7,0xA002, 0x89E4,0x89E2,0xA004,0xA002,0x89E1,0x89E0,0xA002,0x89DF,0x89DD,0xA008,0xA004,0xA002,0x89DB,0x89D9,0xA002,0x89D8, 0x89D7,0xA004,0xA002,0x89D5,0x89D4,0xA002,0x89D3,0x89CD,0xA010,0xA008,0xA004,0xA002,0x89C3,0x89C0,0xA002,0x89BF, 0x89BE,0xA004,0xA002,0x89BD,0x89BC,0xA002,0x89BB,0x89BA,0xA008,0xA004,0xA002,0x89B9,0x89B8,0xA002,0x89B7,0x89B6, 0xA004,0xA002,0x89B5,0x89B4,0xA002,0x89B3,0x89B2,0xA000,0xA010,0xA008,0xA004,0xA002,0x89B1,0x89B0,0xA002,0x89AF, 0x89AE,0xA004,0xA002,0x89AD,0x89AC,0xA002,0x89AB,0x89AA,0xA008,0xA004,0xA002,0x89A9,0x89A8,0xA002,0x89A7,0x89A6, 0xA004,0xA002,0x89A5,0x89A4,0xA002,0x89A3,0x89A2,0xA01F,0xA001,0xA001,0xA00D,0xA005,0xA001,0xA002,0x9690,0x5F15, 0xA004,0xA002,0x5C39,0x996E,0xA002,0x5BC5,0x6DEB,0xA008,0xA004,0xA002,0x94F6,0x541F,0xA002,0x59FB,0x9634,0xA004, 0xA002,0x97F3,0x6BB7,0xA002,0x56E0,0x836B,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x8335,0x7ECE,0xA002,0x7FCC, 0x7FFC,0xA004,0xA002,0x5F02,0x8BD1,0xA002,0x8C0A,0x8BAE,0xA008,0xA004,0xA002,0x8BE3,0x6EA2,0xA002,0x76CA,0x4E49, 0xA004,0xA002,0x5FC6,0x6BC5,0xA002,0x610F,0x88D4,0xA010,0xA008,0xA004,0xA002,0x4EA6,0x75AB,0xA002,0x8084,0x9038, 0xA004,0xA002,0x81C6,0x5F79,0xA002,0x4EBF,0x5C79,0xA008,0xA004,0xA002,0x9091,0x6613,0xA002,0x6291,0x827A,0xA004, 0xA002,0x4EE5,0x77E3,0xA002,0x4E59,0x5DF2,0xA020,0xA010,0xA008,0xA004,0xA002,0x501A,0x8681,0xA002,0x6905,0x5F5D, 0xA004,0xA002,0x59E8,0x5B9C,0xA002,0x6C82,0x7591,0xA008,0xA004,0xA002,0x80F0,0x4EEA,0xA002,0x79FB,0x9057,0xA004, 0xA002,0x5937,0x9890,0xA002,0x8863,0x4F0A,0xA010,0xA008,0xA004,0xA002,0x4F9D,0x94F1,0xA002,0x63D6,0x533B,0xA004, 0xA002,0x58F9,0x4E00,0xA002,0x6DB2,0x591C,0xA008,0xA004,0xA002,0x814B,0x66F3,0xA002,0x53F6,0x4E1A,0xA004,0xA002, 0x6396,0x9875,0xA002,0x4E5F,0x51B6,0xA2FE,0xA17F,0xA0E4,0xA07D,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x91CE,0xA002, 0x7237,0x8036,0xA004,0xA002,0x564E,0x6930,0xA002,0x8000,0x8981,0xA008,0xA004,0xA002,0x836F,0x8200,0xA002,0x54AC, 0x59DA,0xA004,0xA002,0x8C23,0x7A91,0xA002,0x9065,0x5C27,0xA010,0xA008,0xA004,0xA002,0x6447,0x89A1,0xA002,0x89A0, 0x899F,0xA004,0xA002,0x899E,0x899D,0xA002,0x899C,0x899B,0xA008,0xA004,0xA002,0x899A,0x8999,0xA002,0x8998,0x8997, 0xA004,0xA002,0x8996,0x8995,0xA002,0x8994,0x8993,0xA020,0xA010,0xA008,0xA004,0xA002,0x8992,0x8991,0xA002,0x8990, 0x898F,0xA004,0xA002,0x898E,0x898D,0xA002,0x898C,0x898B,0xA008,0xA004,0xA002,0x898A,0x8989,0xA002,0x8988,0x8987, 0xA004,0xA002,0x8985,0x8984,0xA002,0x8982,0x8980,0xA00F,0xA007,0xA004,0xA002,0x897E,0x897D,0xA001,0x897C,0xA004, 0xA002,0x897A,0x8979,0xA002,0x8978,0x8977,0xA008,0xA004,0xA002,0x8976,0x8975,0xA002,0x8974,0x8973,0xA004,0xA002, 0x8972,0x8971,0xA002,0x8970,0x896F,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x896E,0x896D,0xA002,0x896C,0x896B, 0xA004,0xA002,0x896A,0x8969,0xA002,0x8968,0x8967,0xA008,0xA004,0xA002,0x8965,0x8964,0xA002,0x8963,0x8962,0xA004, 0xA002,0x8961,0x8960,0xA002,0x895D,0x895C,0xA010,0xA008,0xA004,0xA002,0x895B,0x895A,0xA002,0x8959,0x8958,0xA004, 0xA002,0x8957,0x8956,0xA002,0x8955,0x8954,0xA008,0xA004,0xA002,0x8953,0x8952,0xA002,0x8951,0x8950,0xA004,0xA002, 0x894F,0x894E,0xA002,0x894D,0x894C,0xA020,0xA010,0xA008,0xA004,0xA002,0x894B,0x894A,0xA002,0x8949,0x8948,0xA004, 0xA002,0x8947,0x8946,0xA002,0x8945,0x8943,0xA008,0xA004,0xA002,0x8942,0x8940,0xA002,0x893F,0x893E,0xA004,0xA002, 0x893D,0x893C,0xA002,0x893B,0x893A,0xA000,0xA000,0xA000,0xA002,0x8939,0x8938,0xA01B,0xA001,0xA001,0xA009,0xA001, 0xA004,0xA002,0x7476,0x5996,0xA002,0x8170,0x9080,0xA008,0xA004,0xA002,0x6F3E,0x6837,0xA002,0x517B,0x75D2,0xA004, 0xA002,0x4EF0,0x6C27,0xA002,0x9633,0x6D0B,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x7F8A,0x75A1,0xA002,0x4F6F, 0x626C,0xA004,0xA002,0x6768,0x79E7,0xA002,0x9E2F,0x592E,0xA008,0xA004,0xA002,0x6B83,0x9A8C,0xA002,0x8C1A,0x5BB4, 0xA004,0xA002,0x7130,0x5F66,0xA002,0x5501,0x96C1,0xA010,0xA008,0xA004,0xA002,0x781A,0x538C,0xA002,0x71D5,0x5830, 0xA004,0xA002,0x8273,0x6F14,0xA002,0x884D,0x773C,0xA008,0xA004,0xA002,0x63A9,0x5944,0xA002,0x6CBF,0x708E,0xA004, 0xA002,0x960E,0x989C,0xA002,0x8A00,0x5EF6,0xA020,0xA010,0xA008,0xA004,0xA002,0x5CA9,0x8712,0xA002,0x7814,0x4E25, 0xA004,0xA002,0x76D0,0x6DF9,0xA002,0x70DF,0x9609,0xA008,0xA004,0xA002,0x54BD,0x7109,0xA002,0x8BB6,0x4E9A,0xA004, 0xA002,0x54D1,0x96C5,0xA002,0x6DAF,0x8859,0xA010,0xA008,0xA004,0xA002,0x5D16,0x869C,0xA002,0x7259,0x82BD,0xA004, 0xA002,0x4E2B,0x5440,0xA002,0x9E2D,0x9E26,0xA008,0xA004,0xA002,0x62BC,0x538B,0xA002,0x8FC5,0x900A,0xA004,0xA002, 0x8BAF,0x8BAD,0xA002,0x6C5B,0x6B89,0xA0E7,0xA07D,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x5DE1,0xA002,0x9A6F,0x5BFB, 0xA004,0xA002,0x8BE2,0x65EC,0xA002,0x5FAA,0x718F,0xA008,0xA004,0xA002,0x52CB,0x8840,0xA002,0x96EA,0x7A74,0xA004, 0xA002,0x5B66,0x859B,0xA002,0x9774,0x7EDA,0xA010,0xA008,0xA004,0xA002,0x7729,0x7663,0xA002,0x9009,0x8937,0xA004, 0xA002,0x8935,0x8933,0xA002,0x8932,0x8931,0xA008,0xA004,0xA002,0x892F,0x892E,0xA002,0x892D,0x892C,0xA004,0xA002, 0x8929,0x8928,0xA002,0x8927,0x8926,0xA020,0xA010,0xA008,0xA004,0xA002,0x8924,0x8923,0xA002,0x8922,0x8920,0xA004, 0xA002,0x891F,0x891E,0xA002,0x891D,0x891C,0xA008,0xA004,0xA002,0x8918,0x8917,0xA002,0x8916,0x8915,0xA004,0xA002, 0x8914,0x8911,0xA002,0x890F,0x890E,0xA00F,0xA008,0xA004,0xA002,0x890D,0x890C,0xA002,0x890B,0x8909,0xA003,0xA001, 0x8908,0xA002,0x8907,0x8906,0xA008,0xA004,0xA002,0x8905,0x8904,0xA002,0x8903,0x8901,0xA004,0xA002,0x8900,0x88FF, 0xA002,0x88FD,0x88FB,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x88FA,0x88F7,0xA002,0x88F6,0x88F5,0xA004,0xA002, 0x88F2,0x88EF,0xA002,0x88EE,0x88ED,0xA008,0xA004,0xA002,0x88EC,0x88EB,0xA002,0x88EA,0x88E9,0xA004,0xA002,0x88E7, 0x88E6,0xA002,0x88E1,0x88E0,0xA010,0xA008,0xA004,0xA002,0x88DE,0x88DD,0xA002,0x88DC,0x88DB,0xA004,0xA002,0x88DA, 0x88D7,0xA002,0x88D6,0x88D3,0xA008,0xA004,0xA002,0x88D1,0x88D0,0xA002,0x88CF,0x88CD,0xA004,0xA002,0x88CC,0x88CB, 0xA002,0x88CA,0x88C8,0xA020,0xA010,0xA008,0xA004,0xA002,0x88C7,0x88C4,0xA002,0x88C3,0x88C0,0xA004,0xA002,0x88BF, 0x88BE,0xA002,0x88BD,0x88BB,0xA008,0xA004,0xA002,0x88BA,0x88B9,0xA002,0x88B8,0x88B6,0xA004,0xA002,0x88B5,0x88B4, 0xA002,0x88B3,0x88B2,0xA000,0xA000,0xA004,0xA002,0x88B0,0x88AF,0xA002,0x88AE,0x88AC,0xA018,0xA001,0xA001,0xA006, 0xA001,0xA001,0xA002,0x7384,0x65CB,0xA008,0xA004,0xA002,0x60AC,0x5BA3,0xA002,0x55A7,0x8F69,0xA004,0xA002,0x7EED, 0x7EEA,0xA002,0x5A7F,0x7D6E,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x6064,0x755C,0xA002,0x5E8F,0x65ED,0xA004, 0xA002,0x53D9,0x9157,0xA002,0x84C4,0x8BB8,0xA008,0xA004,0xA002,0x5F90,0x987B,0xA002,0x5618,0x865A,0xA004,0xA002, 0x9700,0x620C,0xA002,0x589F,0x7EE3,0xA010,0xA008,0xA004,0xA002,0x8896,0x79C0,0xA002,0x9508,0x55C5,0xA004,0xA002, 0x673D,0x7F9E,0xA002,0x4FEE,0x4F11,0xA008,0xA004,0xA002,0x718A,0x96C4,0xA002,0x6C79,0x5308,0xA004,0xA002,0x80F8, 0x51F6,0xA002,0x5144,0x59D3,0xA020,0xA010,0xA008,0xA004,0xA002,0x6027,0x674F,0xA002,0x5E78,0x9192,0xA004,0xA002, 0x884C,0x90A2,0xA002,0x5F62,0x578B,0xA008,0xA004,0xA002,0x5211,0x5174,0xA002,0x60FA,0x7329,0xA004,0xA002,0x8165, 0x661F,0xA002,0x8845,0x4FE1,0xA010,0xA008,0xA004,0xA002,0x5FC3,0x5FFB,0xA002,0x65B0,0x8F9B,0xA004,0xA002,0x6B23, 0x950C,0xA002,0x82AF,0x85AA,0xA008,0xA004,0xA002,0x5C51,0x8C22,0xA002,0x6CFB,0x6CC4,0xA004,0xA002,0x61C8,0x87F9, 0xA002,0x5378,0x68B0,0xA17E,0xA0EB,0xA07D,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x5199,0xA002,0x8C10,0x80C1,0xA004, 0xA002,0x659C,0x90AA,0xA002,0x643A,0x631F,0xA008,0xA004,0xA002,0x534F,0x978B,0xA002,0x874E,0x6B47,0xA004,0xA002, 0x4E9B,0x6954,0xA002,0x6548,0x7B11,0xA010,0xA008,0xA004,0xA002,0x5578,0x8096,0xA002,0x6821,0x5B5D,0xA004,0xA002, 0x5C0F,0x88AA,0xA002,0x88A9,0x88A8,0xA008,0xA004,0xA002,0x88A7,0x88A6,0xA002,0x88A5,0x88A3,0xA004,0xA002,0x88A1, 0x88A0,0xA002,0x889F,0x889E,0xA020,0xA010,0xA008,0xA004,0xA002,0x889D,0x889B,0xA002,0x889A,0x8899,0xA004,0xA002, 0x8898,0x8897,0xA002,0x8895,0x8894,0xA008,0xA004,0xA002,0x8893,0x8891,0xA002,0x8890,0x888F,0xA004,0xA002,0x888E, 0x888C,0xA002,0x888A,0x8889,0xA00F,0xA008,0xA004,0xA002,0x8887,0x8886,0xA002,0x8883,0x8880,0xA004,0xA002,0x887C, 0x887B,0xA001,0x887A,0xA008,0xA004,0xA002,0x8879,0x8878,0xA002,0x8876,0x8875,0xA004,0xA002,0x8874,0x8873,0xA002, 0x8871,0x886F,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x886D,0x886A,0xA002,0x8867,0x8866,0xA004,0xA002,0x8860, 0x885F,0xA002,0x885E,0x885D,0xA008,0xA004,0xA002,0x885C,0x885B,0xA002,0x885A,0x8858,0xA004,0xA002,0x8856,0x8855, 0xA002,0x8853,0x8852,0xA010,0xA008,0xA004,0xA002,0x8851,0x8850,0xA002,0x884F,0x884E,0xA004,0xA002,0x884B,0x884A, 0xA002,0x8849,0x8848,0xA008,0xA004,0xA002,0x8847,0x8846,0xA002,0x8843,0x8842,0xA004,0xA002,0x8841,0x883F,0xA002, 0x883E,0x883D,0xA020,0xA010,0xA008,0xA004,0xA002,0x883B,0x883A,0xA002,0x8838,0x8837,0xA004,0xA002,0x8836,0x8835, 0xA002,0x8834,0x8833,0xA008,0xA004,0xA002,0x8831,0x8830,0xA002,0x882F,0x882E,0xA004,0xA002,0x882D,0x882C,0xA002, 0x882B,0x882A,0xA000,0xA008,0xA004,0xA002,0x8829,0x8828,0xA002,0x8827,0x8826,0xA000,0xA002,0x8825,0x8824,0xA013, 0xA001,0xA001,0xA001,0xA008,0xA004,0xA002,0x6653,0x6DC6,0xA002,0x5BB5,0x6D88,0xA004,0xA002,0x9500,0x56A3,0xA002, 0x54EE,0x524A,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x9704,0x785D,0xA002,0x8427,0x8C61,0xA004,0xA002,0x5411, 0x50CF,0xA002,0x6A61,0x5DF7,0xA008,0xA004,0xA002,0x9879,0x4EAB,0xA002,0x54CD,0x60F3,0xA004,0xA002,0x8BE6,0x7965, 0xA002,0x7FD4,0x4E61,0xA010,0xA008,0xA004,0xA002,0x6E58,0x8944,0xA002,0x7BB1,0x9999,0xA004,0xA002,0x9576,0x53A2, 0xA002,0x76F8,0x7EBF,0xA008,0xA004,0xA002,0x9650,0x9677,0xA002,0x5BAA,0x7FA1,0xA004,0xA002,0x9985,0x817A,0xA002, 0x53BF,0x732E,0xA020,0xA010,0xA008,0xA004,0xA002,0x73B0,0x9669,0xA002,0x663E,0x5ACC,0xA004,0xA002,0x5F26,0x6D8E, 0xA002,0x95F2,0x8237,0xA008,0xA004,0xA002,0x8854,0x8D24,0xA002,0x54B8,0x7EA4,0xA004,0xA002,0x9C9C,0x4ED9,0xA002, 0x5148,0x9528,0xA010,0xA008,0xA004,0xA002,0x6380,0x5413,0xA002,0x590F,0x53A6,0xA004,0xA002,0x4E0B,0x72ED,0xA002, 0x4FA0,0x5CE1,0xA008,0xA004,0xA002,0x6687,0x8F96,0xA002,0x971E,0x5323,0xA004,0xA002,0x867E,0x778E,0xA002,0x7EC6, 0x620F,0xA0EE,0xA07D,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x9699,0xA002,0x7CFB,0x6D17,0xA004,0xA002,0x94E3,0x559C, 0xA002,0x5AB3,0x4E60,0xA008,0xA004,0xA002,0x5E2D,0x88AD,0xA002,0x6A84,0x7280,0xA004,0xA002,0x6C50,0x6EAA,0xA002, 0x70EF,0x7184,0xA010,0xA008,0xA004,0xA002,0x60DC,0x5915,0xA002,0x819D,0x6089,0xA004,0xA002,0x5E0C,0x606F,0xA002, 0x7A00,0x8823,0xA008,0xA004,0xA002,0x8820,0x881F,0xA002,0x881E,0x881D,0xA004,0xA002,0x881C,0x881A,0xA002,0x8819, 0x8818,0xA020,0xA010,0xA008,0xA004,0xA002,0x8817,0x8814,0xA002,0x8812,0x8811,0xA004,0xA002,0x8810,0x880F,0xA002, 0x880E,0x880D,0xA008,0xA004,0xA002,0x880C,0x880B,0xA002,0x8809,0x8808,0xA004,0xA002,0x8807,0x8806,0xA002,0x8805, 0x8804,0xA010,0xA008,0xA004,0xA002,0x8802,0x8801,0xA002,0x8800,0x87FF,0xA004,0xA002,0x87FD,0x87FC,0xA002,0x87FB, 0x87FA,0xA007,0xA003,0xA001,0x87F8,0xA002,0x87F7,0x87F6,0xA004,0xA002,0x87F5,0x87F4,0xA002,0x87F3,0x87F2,0xA040, 0xA020,0xA010,0xA008,0xA004,0xA002,0x87F1,0x87F0,0xA002,0x87EF,0x87ED,0xA004,0xA002,0x87EC,0x87EB,0xA002,0x87E9, 0x87E8,0xA008,0xA004,0xA002,0x87E7,0x87E6,0xA002,0x87E4,0x87E3,0xA004,0xA002,0x87E2,0x87E1,0xA002,0x87DF,0x87DE, 0xA010,0xA008,0xA004,0xA002,0x87DD,0x87DC,0xA002,0x87DA,0x87D9,0xA004,0xA002,0x87D8,0x87D7,0xA002,0x87D6,0x87D5, 0xA008,0xA004,0xA002,0x87D4,0x87D0,0xA002,0x87CF,0x87CE,0xA004,0xA002,0x87CD,0x87CC,0xA002,0x87C9,0x87C8,0xA020, 0xA010,0xA008,0xA004,0xA002,0x87C7,0x87C5,0xA002,0x87C4,0x87C3,0xA004,0xA002,0x87C2,0x87C1,0xA002,0x87BF,0x87BE, 0xA008,0xA004,0xA002,0x87BC,0x87BB,0xA002,0x87B9,0x87B8,0xA004,0xA002,0x87B7,0x87B6,0xA002,0x87B4,0x87B2,0xA000, 0xA008,0xA004,0xA002,0x87B1,0x87B0,0xA002,0x87AE,0x87AA,0xA004,0xA002,0x87A9,0x87A7,0xA002,0x87A6,0x87A5,0xA010, 0xA001,0xA001,0xA001,0xA005,0xA001,0xA002,0x727A,0x9521,0xA004,0xA002,0x5438,0x563B,0xA002,0x6670,0x77FD,0xA040, 0xA020,0xA010,0xA008,0xA004,0xA002,0x7852,0x897F,0xA002,0x6790,0x7199,0xA004,0xA002,0x6614,0x8BEF,0xA002,0x609F, 0x52A1,0xA008,0xA004,0xA002,0x52FF,0x7269,0xA002,0x6664,0x96FE,0xA004,0xA002,0x620A,0x575E,0xA002,0x4FAE,0x4F0D, 0xA010,0xA008,0xA004,0xA002,0x821E,0x5348,0xA002,0x6342,0x4E94,0xA004,0xA002,0x6B66,0x6BCB,0xA002,0x5434,0x543E, 0xA008,0xA004,0xA002,0x68A7,0x829C,0xA002,0x65E0,0x5C4B,0xA004,0xA002,0x8BEC,0x6C61,0xA002,0x4E4C,0x94A8,0xA020, 0xA010,0xA008,0xA004,0xA002,0x545C,0x5DEB,0xA002,0x6C83,0x63E1,0xA004,0xA002,0x5367,0x65A1,0xA002,0x6211,0x7A9D, 0xA008,0xA004,0xA002,0x6DA1,0x8717,0xA002,0x631D,0x74EE,0xA004,0xA002,0x7FC1,0x55E1,0xA002,0x95EE,0x7D0A,0xA010, 0xA008,0xA004,0xA002,0x7A33,0x543B,0xA002,0x7EB9,0x95FB,0xA004,0xA002,0x6587,0x868A,0xA002,0x6E29,0x761F,0xA008, 0xA004,0xA002,0x536B,0x6170,0xA002,0x5C09,0x8C13,0xA004,0xA002,0x6E2D,0x4F4D,0xA002,0x9B4F,0x5582,0xABF6,0xA5FB, 0xA2FF,0xA17E,0xA0F3,0xA07D,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x80C3,0xA002,0x754F,0x5473,0xA004,0xA002,0x851A, 0x672A,0xA002,0x7EAC,0x5C3E,0xA008,0xA004,0xA002,0x4F2A,0x4F1F,0xA002,0x59D4,0x840E,0xA004,0xA002,0x82C7,0x7EF4, 0xA002,0x6F4D,0x4E3A,0xA010,0xA008,0xA004,0xA002,0x60DF,0x552F,0xA002,0x56F4,0x6845,0xA004,0xA002,0x8FDD,0x97E6, 0xA002,0x5371,0x5FAE,0xA008,0xA004,0xA002,0x5DCD,0x87A4,0xA002,0x87A3,0x87A2,0xA004,0xA002,0x87A1,0x87A0,0xA002, 0x879E,0x879D,0xA020,0xA010,0xA008,0xA004,0xA002,0x879C,0x879B,0xA002,0x879A,0x8799,0xA004,0xA002,0x8798,0x8796, 0xA002,0x8795,0x8794,0xA008,0xA004,0xA002,0x8792,0x8791,0xA002,0x8790,0x878F,0xA004,0xA002,0x878E,0x878C,0xA002, 0x878A,0x8789,0xA010,0xA008,0xA004,0xA002,0x8787,0x8786,0xA002,0x8784,0x8781,0xA004,0xA002,0x8780,0x877F,0xA002, 0x877A,0x8779,0xA007,0xA004,0xA002,0x8778,0x8777,0xA001,0x8775,0xA004,0xA002,0x8773,0x8772,0xA002,0x8771,0x876F, 0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x876D,0xA002,0x876C,0x876B,0xA004,0xA002,0x876A,0x8769,0xA002,0x8768,0x8767, 0xA008,0xA004,0xA002,0x8766,0x8762,0xA002,0x8761,0x875F,0xA004,0xA002,0x875E,0x875D,0xA002,0x875C,0x875B,0xA010, 0xA008,0xA004,0xA002,0x875A,0x8758,0xA002,0x8756,0x8755,0xA004,0xA002,0x8754,0x8752,0xA002,0x8751,0x8750,0xA008, 0xA004,0xA002,0x874F,0x874D,0xA002,0x874B,0x874A,0xA004,0xA002,0x8746,0x8745,0xA002,0x8744,0x8743,0xA020,0xA010, 0xA008,0xA004,0xA002,0x8742,0x8741,0xA002,0x8740,0x873D,0xA004,0xA002,0x873C,0x873A,0xA002,0x8739,0x8738,0xA008, 0xA004,0xA002,0x8736,0x8735,0xA002,0x8733,0x8732,0xA004,0xA002,0x8730,0x872F,0xA002,0x872D,0x872C,0xA010,0xA008, 0xA004,0xA002,0x872B,0x872A,0xA002,0x8728,0x8727,0xA004,0xA002,0x8726,0x8724,0xA002,0x8720,0x871F,0xA000,0xA004, 0xA002,0x871D,0x871B,0xA000,0x8719,0xA00B,0xA001,0xA001,0xA001,0xA001,0xA003,0xA001,0x5A01,0xA002,0x5984,0x5FD8, 0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x671B,0x65FA,0xA002,0x5F80,0x7F51,0xA004,0xA002,0x6789,0x4EA1,0xA002, 0x738B,0x6C6A,0xA008,0xA004,0xA002,0x8155,0x4E07,0xA002,0x5A49,0x5B9B,0xA004,0xA002,0x60CB,0x7696,0xA002,0x665A, 0x633D,0xA010,0xA008,0xA004,0xA002,0x7897,0x5B8C,0xA002,0x70F7,0x4E38,0xA004,0xA002,0x987D,0x73A9,0xA002,0x6E7E, 0x5F2F,0xA008,0xA004,0xA002,0x8C4C,0x5916,0xA002,0x6B6A,0x889C,0xA004,0xA002,0x74E6,0x5A03,0xA002,0x6D3C,0x86D9, 0xA020,0xA010,0xA008,0xA004,0xA002,0x54C7,0x6316,0xA002,0x553E,0x62D3,0xA004,0xA002,0x59A5,0x692D,0xA002,0x9A7C, 0x9A6E,0xA008,0xA004,0xA002,0x9640,0x9E35,0xA002,0x8131,0x6258,0xA004,0xA002,0x62D6,0x81C0,0xA002,0x5C6F,0x541E, 0xA010,0xA008,0xA004,0xA002,0x9000,0x892A,0xA002,0x8715,0x817F,0xA004,0xA002,0x9893,0x63A8,0xA002,0x56E2,0x6E4D, 0xA008,0xA004,0xA002,0x5154,0x5410,0xA002,0x571F,0x5C60,0xA004,0xA002,0x6D82,0x9014,0xA002,0x5F92,0x56FE,0xA0F9, 0xA07D,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x7A81,0xA002,0x79C3,0x51F8,0xA004,0xA002,0x900F,0x5934,0xA002,0x6295, 0x5077,0xA008,0xA004,0xA002,0x75DB,0x7EDF,0xA002,0x7B52,0x6345,0xA004,0xA002,0x6876,0x7AE5,0xA002,0x5F64,0x94DC, 0xA010,0xA008,0xA004,0xA002,0x540C,0x77B3,0xA002,0x916E,0x6850,0xA004,0xA002,0x901A,0x8247,0xA002,0x633A,0x5EAD, 0xA008,0xA004,0xA002,0x4EAD,0x505C,0xA002,0x5EF7,0x6C40,0xA004,0xA002,0x8716,0x8714,0xA002,0x8711,0x8710,0xA020, 0xA010,0xA008,0xA004,0xA002,0x870F,0x870E,0xA002,0x870C,0x870B,0xA004,0xA002,0x8706,0x8705,0xA002,0x8704,0x8701, 0xA008,0xA004,0xA002,0x86FF,0x86FD,0xA002,0x86FC,0x86FB,0xA004,0xA002,0x86FA,0x86F7,0xA002,0x86F6,0x86F5,0xA010, 0xA008,0xA004,0xA002,0x86EF,0x86EC,0xA002,0x86EB,0x86EA,0xA004,0xA002,0x86E8,0x86E7,0xA002,0x86E6,0x86E5,0xA008, 0xA004,0xA002,0x86E3,0x86E2,0xA002,0x86E1,0x86E0,0xA003,0xA000,0x86DD,0xA002,0x86DC,0x86DA,0xA040,0xA020,0xA010, 0xA008,0xA004,0xA002,0x86D7,0x86D6,0xA002,0x86D5,0x86D3,0xA004,0xA002,0x86D2,0x86CD,0xA002,0x86CC,0x86C8,0xA008, 0xA004,0xA002,0x86C5,0x86C3,0xA002,0x86C2,0x86C1,0xA004,0xA002,0x86BF,0x86BE,0xA002,0x86BD,0x86BC,0xA010,0xA008, 0xA004,0xA002,0x86BB,0x86B9,0xA002,0x86B8,0x86B7,0xA004,0xA002,0x86B3,0x86B2,0xA002,0x86AE,0x86AD,0xA008,0xA004, 0xA002,0x86AB,0x86A6,0xA002,0x86A5,0x86A2,0xA004,0xA002,0x86A1,0x86A0,0xA002,0x869F,0x869E,0xA020,0xA010,0xA008, 0xA004,0xA002,0x869B,0x869A,0xA002,0x8699,0x8698,0xA004,0xA002,0x8697,0x8696,0xA002,0x8694,0x8692,0xA008,0xA004, 0xA002,0x8691,0x8690,0xA002,0x868F,0x868E,0xA004,0xA002,0x8689,0x8688,0xA002,0x8687,0x8686,0xA010,0xA008,0xA004, 0xA002,0x8685,0x8684,0xA002,0x8683,0x8678,0xA004,0xA002,0x8677,0x8676,0xA002,0x8675,0x8674,0xA008,0xA004,0xA002, 0x8673,0x8672,0xA002,0x8670,0x866F,0xA000,0xA000,0x866D,0xA008,0xA001,0xA001,0xA001,0xA001,0xA001,0xA001,0x70C3, 0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x542C,0x5385,0xA002,0x5E16,0x94C1,0xA004,0xA002,0x8D34,0x8DF3,0xA002, 0x773A,0x8FE2,0xA008,0xA004,0xA002,0x6761,0x6311,0xA002,0x8146,0x8214,0xA004,0xA002,0x606C,0x751C,0xA002,0x7530, 0x586B,0xA010,0xA008,0xA004,0xA002,0x6DFB,0x5929,0xA002,0x5C49,0x5243,0xA004,0xA002,0x6D95,0x60D5,0xA002,0x568F, 0x66FF,0xA008,0xA004,0xA002,0x4F53,0x557C,0xA002,0x8E44,0x9898,0xA004,0xA002,0x63D0,0x9511,0xA002,0x8E22,0x5254, 0xA020,0xA010,0xA008,0xA004,0xA002,0x68AF,0x8A8A,0xA002,0x75BC,0x817E,0xA004,0xA002,0x85E4,0x7279,0xA002,0x5957, 0x8BA8,0xA008,0xA004,0xA002,0x9676,0x6DD8,0xA002,0x9003,0x6843,0xA004,0xA002,0x8404,0x7EE6,0xA002,0x6ED4,0x6D9B, 0xA010,0xA008,0xA004,0xA002,0x638F,0x70EB,0xA002,0x8D9F,0x6DCC,0xA004,0xA002,0x8EBA,0x5018,0xA002,0x7CD6,0x5510, 0xA008,0xA004,0xA002,0x819B,0x68E0,0xA002,0x5802,0x642A,0xA004,0xA002,0x5858,0x6C64,0xA002,0x70AD,0x53F9,0xA17C, 0xA0FC,0xA07D,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x63A2,0xA002,0x78B3,0x8892,0xA004,0xA002,0x6BEF,0x5766,0xA002, 0x8C08,0x8C2D,0xA008,0xA004,0xA002,0x6F6D,0x75F0,0xA002,0x6A80,0x575B,0xA004,0xA002,0x6EE9,0x762B,0xA002,0x8D2A, 0x644A,0xA010,0xA008,0xA004,0xA002,0x574D,0x6C70,0xA002,0x6001,0x592A,0xA004,0xA002,0x915E,0x6CF0,0xA002,0x53F0, 0x62AC,0xA008,0xA004,0xA002,0x82D4,0x80CE,0xA002,0x8E0F,0x8E4B,0xA004,0xA002,0x631E,0x736D,0xA002,0x866A,0x8669, 0xA020,0xA010,0xA008,0xA004,0xA002,0x8668,0x8667,0xA002,0x8666,0x8665,0xA004,0xA002,0x8664,0x8663,0xA002,0x8661, 0x8660,0xA008,0xA004,0xA002,0x865F,0x865D,0xA002,0x865C,0x865B,0xA004,0xA002,0x8659,0x8658,0xA002,0x8657,0x8656, 0xA010,0xA008,0xA004,0xA002,0x8655,0x8653,0xA002,0x8652,0x864C,0xA004,0xA002,0x864B,0x864A,0xA002,0x8649,0x8648, 0xA008,0xA004,0xA002,0x8647,0x8646,0xA002,0x8645,0x8644,0xA004,0xA002,0x8643,0x8642,0xA000,0x8641,0xA040,0xA020, 0xA010,0xA008,0xA004,0xA002,0x8640,0x863F,0xA002,0x863E,0x863D,0xA004,0xA002,0x863B,0x863A,0xA002,0x8639,0x8637, 0xA008,0xA004,0xA002,0x8636,0x8635,0xA002,0x8634,0x8633,0xA004,0xA002,0x8632,0x8631,0xA002,0x8630,0x862F,0xA010, 0xA008,0xA004,0xA002,0x862E,0x862D,0xA002,0x862C,0x862B,0xA004,0xA002,0x862A,0x8628,0xA002,0x8626,0x8625,0xA008, 0xA004,0xA002,0x8624,0x8623,0xA002,0x8622,0x8621,0xA004,0xA002,0x8620,0x861F,0xA002,0x861E,0x861D,0xA020,0xA010, 0xA008,0xA004,0xA002,0x861C,0x861B,0xA002,0x861A,0x8619,0xA004,0xA002,0x8618,0x8617,0xA002,0x8615,0x8614,0xA008, 0xA004,0xA002,0x8613,0x8612,0xA002,0x8610,0x860F,0xA004,0xA002,0x860E,0x860D,0xA002,0x860C,0x860B,0xA010,0xA008, 0xA004,0xA002,0x860A,0x8609,0xA002,0x8608,0x8607,0xA004,0xA002,0x8606,0x8604,0xA002,0x8603,0x8602,0xA008,0xA004, 0xA002,0x8601,0x8600,0xA002,0x85FE,0x85FD,0xA004,0xA002,0x85FC,0x85FA,0xA000,0x85F9,0xA001,0xA03F,0xA01F,0xA00F, 0xA007,0xA003,0xA001,0x5854,0xA002,0x5979,0x5B83,0xA004,0xA002,0x4ED6,0x584C,0xA002,0x6240,0x9501,0xA008,0xA004, 0xA002,0x7D22,0x7410,0xA002,0x7F29,0x5506,0xA004,0xA002,0x68AD,0x84D1,0xA002,0x7B0B,0x635F,0xA010,0xA008,0xA004, 0xA002,0x5B59,0x795F,0xA002,0x96A7,0x9042,0xA004,0xA002,0x7A57,0x5C81,0xA002,0x788E,0x9AD3,0xA008,0xA004,0xA002, 0x7EE5,0x968F,0xA002,0x968B,0x867D,0xA004,0xA002,0x7B97,0x849C,0xA002,0x9178,0x8083,0xA020,0xA010,0xA008,0xA004, 0xA002,0x8BC9,0x5BBF,0xA002,0x6EAF,0x5851,0xA004,0xA002,0x50F3,0x7C9F,0xA002,0x901F,0x7D20,0xA008,0xA004,0xA002, 0x4FD7,0x9165,0xA002,0x82CF,0x55FD,0xA004,0xA002,0x64DE,0x8258,0xA002,0x641C,0x8BF5,0xA010,0xA008,0xA004,0xA002, 0x8BBC,0x5B8B,0xA002,0x9001,0x9882,0xA004,0xA002,0x6002,0x8038,0xA002,0x677E,0x5DF3,0xA008,0xA004,0xA002,0x9972, 0x4F3C,0xA002,0x4F3A,0x56DB,0xA004,0xA002,0x55E3,0x5BFA,0xA002,0x8086,0x6B7B,0xA0FD,0xA07E,0xA03E,0xA01E,0xA00E, 0xA006,0xA002,0x4E1D,0xA002,0x53F8,0x79C1,0xA004,0xA002,0x601D,0x5636,0xA002,0x6495,0x65AF,0xA008,0xA004,0xA002, 0x70C1,0x6714,0xA002,0x7855,0x8BF4,0xA004,0xA002,0x821C,0x987A,0xA002,0x77AC,0x542E,0xA010,0xA008,0xA004,0xA002, 0x7A0E,0x7761,0xA002,0x6C34,0x8C01,0xA004,0xA002,0x723D,0x53CC,0xA002,0x971C,0x62F4,0xA008,0xA004,0xA002,0x6813, 0x5E05,0xA002,0x7529,0x8870,0xA004,0xA002,0x6454,0x800D,0xA002,0x5237,0x6055,0xA020,0xA010,0xA008,0xA004,0xA002, 0x85F8,0x85F7,0xA002,0x85F6,0x85F5,0xA004,0xA002,0x85F4,0x85F3,0xA002,0x85F2,0x85F1,0xA008,0xA004,0xA002,0x85F0, 0x85EF,0xA002,0x85EE,0x85ED,0xA004,0xA002,0x85EC,0x85EB,0xA002,0x85EA,0x85E8,0xA010,0xA008,0xA004,0xA002,0x85E7, 0x85E6,0xA002,0x85E5,0x85E3,0xA004,0xA002,0x85E2,0x85E1,0xA002,0x85E0,0x85DF,0xA008,0xA004,0xA002,0x85DE,0x85DD, 0xA002,0x85DB,0x85DA,0xA004,0xA002,0x85D9,0x85D8,0xA002,0x85D7,0x85D6,0xA03F,0xA01F,0xA00F,0xA007,0xA003,0xA000, 0x85D4,0xA002,0x85D2,0x85D1,0xA004,0xA002,0x85CE,0x85CD,0xA002,0x85CC,0x85CB,0xA008,0xA004,0xA002,0x85CA,0x85C8, 0xA002,0x85C7,0x85C6,0xA004,0xA002,0x85C5,0x85C4,0xA002,0x85C3,0x85C2,0xA010,0xA008,0xA004,0xA002,0x85C0,0x85BF, 0xA002,0x85BE,0x85BD,0xA004,0xA002,0x85BC,0x85BB,0xA002,0x85BA,0x85B8,0xA008,0xA004,0xA002,0x85B6,0x85B5,0xA002, 0x85B4,0x85B3,0xA004,0xA002,0x85B2,0x85B1,0xA002,0x85AD,0x85AC,0xA020,0xA010,0xA008,0xA004,0xA002,0x85AB,0x85A9, 0xA002,0x85A7,0x85A6,0xA004,0xA002,0x85A5,0x85A3,0xA002,0x85A2,0x85A1,0xA008,0xA004,0xA002,0x85A0,0x859F,0xA002, 0x859E,0x859D,0xA004,0xA002,0x859A,0x8599,0xA002,0x8598,0x8597,0xA010,0xA008,0xA004,0xA002,0x8596,0x8595,0xA002, 0x8594,0x8593,0xA004,0xA002,0x8592,0x8591,0xA002,0x8590,0x858E,0xA008,0xA004,0xA002,0x858D,0x858C,0xA002,0x858B, 0x858A,0xA004,0xA002,0x8589,0x8588,0xA002,0x8586,0x8583,0xA007,0xA000,0xA000,0xA000,0xA000,0xA000,0x8582,0xA03C, 0xA01C,0xA00C,0xA004,0xA001,0xA001,0x6F31,0xA004,0xA002,0x6570,0x5EB6,0xA002,0x5885,0x7AD6,0xA008,0xA004,0xA002, 0x620D,0x675F,0xA002,0x6811,0x8FF0,0xA004,0xA002,0x672F,0x5C5E,0xA002,0x9F20,0x9ECD,0xA010,0xA008,0xA004,0xA002, 0x8700,0x7F72,0xA002,0x66D9,0x6691,0xA004,0xA002,0x85AF,0x719F,0xA002,0x5B70,0x8D4E,0xA008,0xA004,0xA002,0x4E66, 0x758F,0xA002,0x6DD1,0x8212,0xA004,0xA002,0x53D4,0x8F93,0xA002,0x6292,0x6B8A,0xA020,0xA010,0xA008,0xA004,0xA002, 0x68B3,0x67A2,0xA002,0x852C,0x517D,0xA004,0xA002,0x7626,0x53D7,0xA002,0x552E,0x6388,0xA008,0xA004,0xA002,0x5BFF, 0x5B88,0xA002,0x9996,0x624B,0xA004,0xA002,0x6536,0x8BD5,0xA002,0x89C6,0x5BA4,0xA010,0xA008,0xA004,0xA002,0x6043, 0x5E02,0xA002,0x6C0F,0x9970,0xA004,0xA002,0x91CA,0x4F8D,0xA002,0x4ED5,0x9002,0xA008,0xA004,0xA002,0x566C,0x55DC, 0xA002,0x662F,0x52BF,0xA004,0xA002,0x901D,0x8A93,0xA002,0x62ED,0x4E8B,0xA2FC,0xA17E,0xA0FB,0xA07E,0xA03E,0xA01E, 0xA00E,0xA006,0xA002,0x67FF,0xA002,0x4E16,0x58EB,0xA004,0xA002,0x793A,0x5F0F,0xA002,0x59CB,0x9A76,0xA008,0xA004, 0xA002,0x5C4E,0x4F7F,0xA002,0x77E2,0x53F2,0xA004,0xA002,0x8BC6,0x5B9E,0xA002,0x8680,0x98DF,0xA010,0xA008,0xA004, 0xA002,0x4EC0,0x65F6,0xA002,0x62FE,0x77F3,0xA004,0xA002,0x5341,0x8671,0xA002,0x5C38,0x8BD7,0xA008,0xA004,0xA002, 0x6E7F,0x65BD,0xA002,0x72EE,0x5931,0xA004,0xA002,0x5E08,0x5723,0xA002,0x80DC,0x5269,0xA020,0xA010,0xA008,0xA004, 0xA002,0x76DB,0x7701,0xA002,0x8581,0x8580,0xA004,0xA002,0x857F,0x857D,0xA002,0x857C,0x8578,0xA008,0xA004,0xA002, 0x8577,0x8576,0xA002,0x8575,0x8573,0xA004,0xA002,0x8571,0x8570,0xA002,0x856F,0x856E,0xA010,0xA008,0xA004,0xA002, 0x856D,0x856C,0xA002,0x856B,0x856A,0xA004,0xA002,0x8569,0x8567,0xA002,0x8566,0x8565,0xA008,0xA004,0xA002,0x8563, 0x8562,0xA002,0x8561,0x8560,0xA004,0xA002,0x855F,0x855D,0xA002,0x855C,0x855B,0xA03D,0xA01D,0xA00D,0xA006,0xA002, 0x855A,0xA002,0x8558,0x8557,0xA003,0xA001,0x8555,0xA002,0x8554,0x8553,0xA008,0xA004,0xA002,0x8552,0x8551,0xA002, 0x8550,0x854F,0xA004,0xA002,0x854E,0x854D,0xA002,0x854C,0x854B,0xA010,0xA008,0xA004,0xA002,0x8547,0x8546,0xA002, 0x8545,0x8544,0xA004,0xA002,0x8542,0x8541,0xA002,0x8540,0x853F,0xA008,0xA004,0xA002,0x853E,0x8536,0xA002,0x8535, 0x8534,0xA004,0xA002,0x8533,0x8532,0xA002,0x8531,0x8530,0xA020,0xA010,0xA008,0xA004,0xA002,0x852F,0x852E,0xA002, 0x852D,0x852A,0xA004,0xA002,0x8529,0x8528,0xA002,0x8527,0x8526,0xA008,0xA004,0xA002,0x8525,0x8524,0xA002,0x8523, 0x8522,0xA004,0xA002,0x8520,0x851E,0xA002,0x851D,0x851C,0xA010,0xA008,0xA004,0xA002,0x851B,0x8519,0xA002,0x8518, 0x8516,0xA004,0xA002,0x8515,0x8514,0xA002,0x8512,0x8510,0xA008,0xA004,0xA002,0x850F,0x850E,0xA002,0x850D,0x850B, 0xA004,0xA002,0x850A,0x8509,0xA002,0x8508,0x8507,0xA00D,0xA000,0xA000,0xA000,0xA006,0xA002,0x8506,0xA002,0x8505, 0x8504,0xA000,0xA000,0x8503,0xA036,0xA016,0xA006,0xA001,0xA001,0xA002,0x7EF3,0x5347,0xA008,0xA004,0xA002,0x7272, 0x7525,0xA002,0x751F,0x58F0,0xA004,0xA002,0x6E17,0x614E,0xA002,0x80BE,0x751A,0xA010,0xA008,0xA004,0xA002,0x5A76, 0x5BA1,0xA002,0x6C88,0x795E,0xA004,0xA002,0x7EC5,0x5A20,0xA002,0x6DF1,0x8EAB,0xA008,0xA004,0xA002,0x4F38,0x547B, 0xA002,0x7533,0x7837,0xA004,0xA002,0x8BBE,0x793E,0xA002,0x6D89,0x6151,0xA020,0xA010,0xA008,0xA004,0xA002,0x5C04, 0x6444,0xA002,0x8D66,0x820D,0xA004,0xA002,0x820C,0x86C7,0xA002,0x8D4A,0x5962,0xA008,0xA004,0xA002,0x7ECD,0x90B5, 0xA002,0x54E8,0x5C11,0xA004,0xA002,0x97F6,0x52FA,0xA002,0x828D,0x70E7,0xA010,0xA008,0xA004,0xA002,0x7A0D,0x634E, 0xA002,0x68A2,0x88F3,0xA004,0xA002,0x5C1A,0x4E0A,0xA002,0x664C,0x8D4F,0xA008,0xA004,0xA002,0x5546,0x4F24,0xA002, 0x5892,0x7F2E,0xA004,0xA002,0x6247,0x6C55,0xA002,0x5584,0x81B3,0xA0FD,0xA07E,0xA03E,0xA01E,0xA00E,0xA006,0xA002, 0x8D61,0xA002,0x64C5,0x9655,0xA004,0xA002,0x95EA,0x886B,0xA002,0x717D,0x5220,0xA008,0xA004,0xA002,0x5C71,0x6749, 0xA002,0x82EB,0x73CA,0xA004,0xA002,0x6652,0x7B5B,0xA002,0x715E,0x5565,0xA010,0xA008,0xA004,0xA002,0x50BB,0x7EB1, 0xA002,0x6C99,0x5239,0xA004,0xA002,0x6740,0x7802,0xA002,0x838E,0x50E7,0xA008,0xA004,0xA002,0x68EE,0x6DA9,0xA002, 0x8272,0x745F,0xA004,0xA002,0x5AC2,0x626B,0xA002,0x9A9A,0x6414,0xA020,0xA010,0xA008,0xA004,0xA002,0x4E27,0x55D3, 0xA002,0x6851,0x6563,0xA004,0xA002,0x4F1E,0x8502,0xA002,0x8501,0x8500,0xA008,0xA004,0xA002,0x84FE,0x84FD,0xA002, 0x84FB,0x84FA,0xA004,0xA002,0x84F9,0x84F8,0xA002,0x84F7,0x84F6,0xA010,0xA008,0xA004,0xA002,0x84F5,0x84F4,0xA002, 0x84F3,0x84F2,0xA004,0xA002,0x84F1,0x84EF,0xA002,0x84EE,0x84ED,0xA008,0xA004,0xA002,0x84EB,0x84EA,0xA002,0x84E9, 0x84E8,0xA004,0xA002,0x84E7,0x84E4,0xA002,0x84E2,0x84E1,0xA03F,0xA01F,0xA00F,0xA008,0xA004,0xA002,0x84DE,0x84DC, 0xA002,0x84DB,0x84DA,0xA004,0xA002,0x84D9,0x84D8,0xA001,0x84D7,0xA008,0xA004,0xA002,0x84D5,0x84D4,0xA002,0x84D2, 0x84CF,0xA004,0xA002,0x84CE,0x84CC,0xA002,0x84CB,0x84C8,0xA010,0xA008,0xA004,0xA002,0x84C7,0x84C6,0xA002,0x84C5, 0x84C3,0xA004,0xA002,0x84C2,0x84C0,0xA002,0x84BE,0x84BC,0xA008,0xA004,0xA002,0x84BB,0x84B7,0xA002,0x84B6,0x84B5, 0xA004,0xA002,0x84B3,0x84B1,0xA002,0x84B0,0x84AE,0xA020,0xA010,0xA008,0xA004,0xA002,0x84AD,0x84AC,0xA002,0x84AB, 0x84AA,0xA004,0xA002,0x84A9,0x84A8,0xA002,0x84A7,0x84A6,0xA008,0xA004,0xA002,0x84A5,0x84A4,0xA002,0x84A3,0x84A2, 0xA004,0xA002,0x84A0,0x849F,0xA002,0x849E,0x849D,0xA010,0xA008,0xA004,0xA002,0x849B,0x849A,0xA002,0x8498,0x8496, 0xA004,0xA002,0x8495,0x8494,0xA002,0x8493,0x8492,0xA008,0xA004,0xA002,0x8491,0x8490,0xA002,0x848F,0x848D,0xA004, 0xA002,0x848A,0x8486,0xA002,0x8485,0x8484,0xA010,0xA000,0xA000,0xA000,0xA006,0xA002,0x8483,0xA002,0x8481,0x8480, 0xA004,0xA002,0x847F,0x847E,0xA000,0x847D,0xA031,0xA011,0xA001,0xA008,0xA004,0xA002,0x53C1,0x4E09,0xA002,0x8D5B, 0x585E,0xA004,0xA002,0x9CC3,0x816E,0xA002,0x8428,0x6D12,0xA010,0xA008,0xA004,0xA002,0x6492,0x5F31,0xA002,0x82E5, 0x6DA6,0xA004,0xA002,0x95F0,0x9510,0xA002,0x745E,0x854A,0xA008,0xA004,0xA002,0x962E,0x8F6F,0xA002,0x8925,0x5165, 0xA004,0xA002,0x6C5D,0x4E73,0xA002,0x8FB1,0x5982,0xA020,0xA010,0xA008,0xA004,0xA002,0x5B7A,0x5112,0xA002,0x8815, 0x8339,0xA004,0xA002,0x8089,0x67D4,0xA002,0x63C9,0x5197,0xA008,0xA004,0xA002,0x7ED2,0x5BB9,0xA002,0x6EB6,0x7194, 0xA004,0xA002,0x878D,0x8363,0xA002,0x84C9,0x8338,0xA010,0xA008,0xA004,0xA002,0x620E,0x65E5,0xA002,0x4ECD,0x6254, 0xA004,0xA002,0x7EAB,0x598A,0xA002,0x5203,0x8BA4,0xA008,0xA004,0xA002,0x4EFB,0x97E7,0xA002,0x5FCD,0x4EBA,0xA004, 0xA002,0x4EC1,0x58EC,0xA002,0x70ED,0x60F9,0xA180,0xA0FD,0xA07E,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x7ED5,0xA002, 0x6270,0x9976,0xA004,0xA002,0x8BA9,0x56B7,0xA002,0x6518,0x58E4,0xA008,0xA004,0xA002,0x74E4,0x67D3,0xA002,0x5189, 0x71C3,0xA004,0xA002,0x7136,0x7FA4,0xA002,0x88D9,0x96C0,0xA010,0xA008,0xA004,0xA002,0x786E,0x69B7,0xA002,0x9E4A, 0x5374,0xA004,0xA002,0x7638,0x7094,0xA002,0x7F3A,0x529D,0xA008,0xA004,0xA002,0x5238,0x72AC,0xA002,0x62F3,0x75CA, 0xA004,0xA002,0x5168,0x6CC9,0xA002,0x919B,0x6743,0xA020,0xA010,0xA008,0xA004,0xA002,0x98A7,0x5708,0xA002,0x53BB, 0x8DA3,0xA004,0xA002,0x9F8B,0x5A36,0xA002,0x53D6,0x847C,0xA008,0xA004,0xA002,0x847B,0x8479,0xA002,0x8477,0x8474, 0xA004,0xA002,0x8472,0x8470,0xA002,0x846F,0x846E,0xA010,0xA008,0xA004,0xA002,0x846A,0x8468,0xA002,0x8467,0x8466, 0xA004,0xA002,0x8465,0x8464,0xA002,0x8462,0x8460,0xA008,0xA004,0xA002,0x845F,0x845E,0xA002,0x845D,0x8458,0xA004, 0xA002,0x8456,0x8455,0xA002,0x8454,0x8453,0xA03F,0xA01F,0xA010,0xA008,0xA004,0xA002,0x8452,0x8450,0xA002,0x844F, 0x844E,0xA004,0xA002,0x844D,0x844C,0xA002,0x844B,0x844A,0xA007,0xA003,0xA001,0x8449,0xA002,0x8448,0x8447,0xA004, 0xA002,0x8445,0x8444,0xA002,0x8443,0x8442,0xA010,0xA008,0xA004,0xA002,0x8441,0x8440,0xA002,0x843F,0x843E,0xA004, 0xA002,0x843B,0x843A,0xA002,0x8439,0x8437,0xA008,0xA004,0xA002,0x8436,0x8435,0xA002,0x8434,0x8433,0xA004,0xA002, 0x8432,0x8430,0xA002,0x842F,0x842E,0xA020,0xA010,0xA008,0xA004,0xA002,0x842D,0x842C,0xA002,0x842B,0x842A,0xA004, 0xA002,0x8429,0x8423,0xA002,0x8422,0x8421,0xA008,0xA004,0xA002,0x8420,0x841F,0xA002,0x841E,0x841B,0xA004,0xA002, 0x841A,0x8419,0xA002,0x8417,0x8416,0xA010,0xA008,0xA004,0xA002,0x8415,0x8414,0xA002,0x8413,0x8412,0xA004,0xA002, 0x8410,0x840A,0xA002,0x8409,0x8408,0xA008,0xA004,0xA002,0x8407,0x8405,0xA002,0x8402,0x8400,0xA004,0xA002,0x83FF, 0x83FE,0xA002,0x83FC,0x83FB,0xA015,0xA000,0xA000,0xA00E,0xA006,0xA002,0x83FA,0xA002,0x83F7,0x83F6,0xA004,0xA002, 0x83F5,0x83F4,0xA002,0x83F3,0x83EF,0xA000,0xA000,0xA000,0x83EE,0xA02E,0xA00E,0xA001,0xA005,0xA001,0xA002,0x6E20, 0x9A71,0xA004,0xA002,0x5C48,0x8EAF,0xA002,0x66F2,0x86C6,0xA010,0xA008,0xA004,0xA002,0x533A,0x8D8B,0xA002,0x6CC5, 0x914B,0xA004,0xA002,0x56DA,0x6C42,0xA002,0x7403,0x90B1,0xA008,0xA004,0xA002,0x4E18,0x79CB,0xA002,0x7A77,0x743C, 0xA004,0xA002,0x5E86,0x8BF7,0xA002,0x9877,0x60C5,0xA020,0xA010,0xA008,0xA004,0xA002,0x6C30,0x6674,0xA002,0x64CE, 0x6E05,0xA004,0xA002,0x537F,0x503E,0xA002,0x6C22,0x8F7B,0xA008,0xA004,0xA002,0x9752,0x6C81,0xA002,0x5BDD,0x79BD, 0xA004,0xA002,0x64D2,0x82B9,0xA002,0x52E4,0x7434,0xA010,0xA008,0xA004,0xA002,0x79E6,0x4EB2,0xA002,0x4FB5,0x94A6, 0xA004,0xA002,0x7A83,0x602F,0xA002,0x4E14,0x8304,0xA008,0xA004,0xA002,0x5207,0x7A8D,0xA002,0x4FCF,0x5CED,0xA004, 0xA002,0x7FD8,0x64AC,0xA002,0x9798,0x5DE7,0xA0FD,0xA07E,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x4FA8,0xA002,0x4E54, 0x77A7,0xA004,0xA002,0x6865,0x6084,0xA002,0x6572,0x9539,0xA008,0xA004,0xA002,0x6A47,0x62A2,0xA002,0x5F3A,0x8537, 0xA004,0xA002,0x5899,0x7F8C,0xA002,0x8154,0x545B,0xA010,0xA008,0xA004,0xA002,0x67AA,0x6B49,0xA002,0x6B20,0x5D4C, 0xA004,0xA002,0x5811,0x8C34,0xA002,0x6D45,0x9063,0xA008,0xA004,0xA002,0x6F5C,0x524D,0xA002,0x94B3,0x94B1,0xA004, 0xA002,0x9ED4,0x4E7E,0xA002,0x8C26,0x4EDF,0xA020,0xA010,0xA008,0xA004,0xA002,0x7B7E,0x8FC1,0xA002,0x5343,0x94C5, 0xA004,0xA002,0x948E,0x6266,0xA002,0x7275,0x6D3D,0xA008,0xA004,0xA002,0x6070,0x83ED,0xA002,0x83EC,0x83EB,0xA004, 0xA002,0x83E8,0x83E7,0xA002,0x83E6,0x83E4,0xA010,0xA008,0xA004,0xA002,0x83E3,0x83E2,0xA002,0x83DE,0x83DB,0xA004, 0xA002,0x83DA,0x83D9,0xA002,0x83D7,0x83D5,0xA008,0xA004,0xA002,0x83D3,0x83D2,0xA002,0x83D1,0x83D0,0xA004,0xA002, 0x83CE,0x83CD,0xA002,0x83CB,0x83C9,0xA03F,0xA01F,0xA010,0xA008,0xA004,0xA002,0x83C8,0x83C6,0xA002,0x83C4,0x83C3, 0xA004,0xA002,0x83C2,0x83BF,0xA002,0x83BE,0x83BB,0xA007,0xA004,0xA002,0x83B5,0x83AF,0xA001,0x83AE,0xA004,0xA002, 0x83AD,0x83AC,0xA002,0x83A7,0x83A6,0xA010,0xA008,0xA004,0xA002,0x83A5,0x83A4,0xA002,0x83A3,0x83A2,0xA004,0xA002, 0x83A1,0x839F,0xA002,0x839D,0x839A,0xA008,0xA004,0xA002,0x8399,0x8397,0xA002,0x8396,0x8395,0xA004,0xA002,0x8394, 0x8391,0xA002,0x8390,0x838F,0xA020,0xA010,0xA008,0xA004,0xA002,0x838D,0x838C,0xA002,0x838B,0x838A,0xA004,0xA002, 0x8388,0x8387,0xA002,0x8384,0x8383,0xA008,0xA004,0xA002,0x8382,0x8381,0xA002,0x8380,0x837F,0xA004,0xA002,0x837E, 0x837A,0xA002,0x8379,0x8376,0xA010,0xA008,0xA004,0xA002,0x8375,0x8374,0xA002,0x8373,0x8372,0xA004,0xA002,0x8371, 0x8370,0xA002,0x8362,0x835D,0xA008,0xA004,0xA002,0x8359,0x8358,0xA002,0x8357,0x8356,0xA004,0xA002,0x8355,0x8353, 0xA002,0x834E,0x834D,0xA018,0xA000,0xA000,0xA00E,0xA006,0xA002,0x834C,0xA002,0x834B,0x834A,0xA004,0xA002,0x8348, 0x8345,0xA002,0x8344,0x8342,0xA000,0xA004,0xA002,0x8341,0x833F,0xA000,0x833E,0xA02A,0xA00A,0xA001,0xA001,0xA004, 0xA002,0x6390,0x8BAB,0xA002,0x6CE3,0x6C7D,0xA010,0xA008,0xA004,0xA002,0x5F03,0x8FC4,0xA002,0x6C14,0x5668,0xA004, 0xA002,0x780C,0x5951,0xA002,0x542F,0x4F01,0xA008,0xA004,0xA002,0x4E5E,0x5C82,0xA002,0x8D77,0x9A91,0xA004,0xA002, 0x7941,0x7948,0xA002,0x65D7,0x9F50,0xA020,0xA010,0xA008,0xA004,0xA002,0x8110,0x5D0E,0xA002,0x7566,0x6B67,0xA004, 0xA002,0x5947,0x68CB,0xA002,0x5176,0x6C8F,0xA008,0xA004,0xA002,0x67D2,0x6F06,0xA002,0x51C4,0x4E03,0xA004,0xA002, 0x59BB,0x621A,0xA002,0x6816,0x6B3A,0xA010,0xA008,0xA004,0xA002,0x671F,0x7011,0xA002,0x66DD,0x8C31,0xA004,0xA002, 0x6D66,0x666E,0xA002,0x5703,0x6734,0xA008,0xA004,0xA002,0x57D4,0x84B2,0xA002,0x83E9,0x8461,0xA004,0xA002,0x8386, 0x4EC6,0xA002,0x94FA,0x6251,0xA5FA,0xA2FB,0xA17E,0xA0FB,0xA07E,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x5256,0xA002, 0x7C95,0x8FEB,0xA004,0xA002,0x9B44,0x7834,0xA002,0x5A46,0x9887,0xA008,0xA004,0xA002,0x6CFC,0x5761,0xA002,0x5C4F, 0x8BC4,0xA004,0xA002,0x74F6,0x51ED,0xA002,0x5E73,0x840D,0xA010,0xA008,0xA004,0xA002,0x82F9,0x576A,0xA002,0x4E52, 0x8058,0xA004,0xA002,0x54C1,0x8D2B,0xA002,0x9891,0x62FC,0xA008,0xA004,0xA002,0x77A5,0x6487,0xA002,0x7968,0x74E2, 0xA004,0xA002,0x6F02,0x98D8,0xA002,0x9A97,0x7247,0xA020,0xA010,0xA008,0xA004,0xA002,0x504F,0x7BC7,0xA002,0x8B6C, 0x5C41,0xA004,0xA002,0x50FB,0x75DE,0xA002,0x5339,0x76AE,0xA008,0xA004,0xA002,0x75B2,0x813E,0xA002,0x5564,0x833D, 0xA004,0xA002,0x833B,0x8337,0xA002,0x8332,0x8330,0xA010,0xA008,0xA004,0xA002,0x832E,0x832A,0xA002,0x8329,0x8326, 0xA004,0xA002,0x8325,0x8324,0xA002,0x8323,0x8322,0xA008,0xA004,0xA002,0x8321,0x8320,0xA002,0x831F,0x831E,0xA004, 0xA002,0x831D,0x8319,0xA002,0x8318,0x8316,0xA03D,0xA01D,0xA00E,0xA006,0xA002,0x8313,0xA002,0x8312,0x8310,0xA004, 0xA002,0x830D,0x830B,0xA002,0x830A,0x8300,0xA008,0xA004,0xA002,0x82FF,0x82FE,0xA002,0x82FD,0x82FC,0xA003,0xA000, 0x82FA,0xA002,0x82F8,0x82F6,0xA010,0xA008,0xA004,0xA002,0x82F5,0x82F3,0xA002,0x82F2,0x82F0,0xA004,0xA002,0x82EE, 0x82ED,0xA002,0x82EC,0x82EA,0xA008,0xA004,0xA002,0x82E9,0x82E8,0xA002,0x82E7,0x82E2,0xA004,0xA002,0x82DD,0x82DA, 0xA002,0x82D9,0x82D6,0xA020,0xA010,0xA008,0xA004,0xA002,0x82D0,0x82C9,0xA002,0x82C6,0x82C5,0xA004,0xA002,0x82C3, 0x82C2,0xA002,0x82C0,0x82BF,0xA008,0xA004,0xA002,0x82BC,0x82BB,0xA002,0x82BA,0x82B6,0xA004,0xA002,0x82B5,0x82B2, 0xA002,0x82A7,0x82A3,0xA010,0xA008,0xA004,0xA002,0x82A2,0x82A0,0xA002,0x829E,0x829B,0xA004,0xA002,0x829A,0x8296, 0xA002,0x8295,0x8294,0xA008,0xA004,0xA002,0x8293,0x8290,0xA002,0x828C,0x8289,0xA004,0xA002,0x8287,0x8286,0xA002, 0x8285,0x8283,0xA01D,0xA000,0xA000,0xA00E,0xA006,0xA002,0x8281,0xA002,0x8280,0x827C,0xA004,0xA002,0x827B,0x8278, 0xA002,0x8277,0x8276,0xA008,0xA004,0xA002,0x8275,0x8271,0xA002,0x826D,0x826C,0xA000,0xA002,0x826B,0x826A,0xA026, 0xA006,0xA001,0xA001,0xA001,0xA001,0x6BD7,0xA010,0xA008,0xA004,0xA002,0x7435,0x5288,0xA002,0x62AB,0x6279,0xA004, 0xA002,0x9739,0x7812,0xA002,0x576F,0x78B0,0xA008,0xA004,0xA002,0x6367,0x9E4F,0xA002,0x670B,0x81A8,0xA004,0xA002, 0x7BF7,0x787C,0xA002,0x68DA,0x84EC,0xA020,0xA010,0xA008,0xA004,0xA002,0x5F6D,0x6F8E,0xA002,0x70F9,0x62A8,0xA004, 0xA002,0x7830,0x76C6,0xA002,0x55B7,0x6C9B,0xA008,0xA004,0xA002,0x4F69,0x914D,0xA002,0x966A,0x8D54,0xA004,0xA002, 0x88F4,0x57F9,0xA002,0x80DA,0x5478,0xA010,0xA008,0xA004,0xA002,0x6CE1,0x8DD1,0xA002,0x888D,0x70AE,0xA004,0xA002, 0x5228,0x5486,0xA002,0x629B,0x80D6,0xA008,0xA004,0xA002,0x802A,0x65C1,0xA002,0x5E9E,0x4E53,0xA004,0xA002,0x53DB, 0x5224,0xA002,0x7554,0x76FC,0xA0FD,0xA07E,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x78D0,0xA002,0x76D8,0x6F58,0xA004, 0xA002,0x6500,0x6D3E,0xA002,0x6E43,0x5F98,0xA008,0xA004,0xA002,0x724C,0x6392,0xA002,0x62CD,0x7436,0xA004,0xA002, 0x6015,0x5E15,0xA002,0x722C,0x8DB4,0xA010,0xA008,0xA004,0xA002,0x556A,0x6CA4,0xA002,0x5076,0x5455,0xA004,0xA002, 0x85D5,0x6BB4,0xA002,0x9E25,0x6B27,0xA008,0xA004,0xA002,0x54E6,0x8BFA,0xA002,0x7CEF,0x61E6,0xA004,0xA002,0x632A, 0x759F,0xA002,0x8650,0x6696,0xA020,0xA010,0xA008,0xA004,0xA002,0x5973,0x6012,0xA002,0x52AA,0x5974,0xA004,0xA002, 0x5F04,0x519C,0xA002,0x6D53,0x8113,0xA008,0xA004,0xA002,0x7EBD,0x94AE,0xA002,0x626D,0x725B,0xA004,0xA002,0x6CDE, 0x62E7,0xA002,0x8269,0x8267,0xA010,0xA008,0xA004,0xA002,0x8266,0x8265,0xA002,0x8264,0x8263,0xA004,0xA002,0x8262, 0x8261,0xA002,0x8260,0x825E,0xA008,0xA004,0xA002,0x825D,0x825C,0xA002,0x825B,0x8259,0xA004,0xA002,0x8257,0x8256, 0xA002,0x8255,0x8254,0xA03F,0xA01F,0xA010,0xA008,0xA004,0xA002,0x8253,0x8252,0xA002,0x8251,0x8250,0xA004,0xA002, 0x824E,0x824D,0xA002,0x824C,0x824A,0xA008,0xA004,0xA002,0x8248,0x8246,0xA002,0x8245,0x8243,0xA004,0xA002,0x8242, 0x8241,0xA000,0x8240,0xA010,0xA008,0xA004,0xA002,0x823F,0x823D,0xA002,0x823C,0x823A,0xA004,0xA002,0x8232,0x822E, 0xA002,0x8229,0x8227,0xA008,0xA004,0xA002,0x8226,0x8225,0xA002,0x8224,0x8220,0xA004,0xA002,0x821D,0x821A,0xA002, 0x8219,0x8218,0xA020,0xA010,0xA008,0xA004,0xA002,0x8217,0x8216,0xA002,0x8215,0x8213,0xA004,0xA002,0x8211,0x820F, 0xA002,0x820E,0x820B,0xA008,0xA004,0xA002,0x820A,0x8209,0xA002,0x8208,0x8207,0xA004,0xA002,0x8203,0x81FF,0xA002, 0x81FD,0x81FA,0xA010,0xA008,0xA004,0xA002,0x81F9,0x81F8,0xA002,0x81F7,0x81F6,0xA004,0xA002,0x81F5,0x81F2,0xA002, 0x81F1,0x81F0,0xA008,0xA004,0xA002,0x81EF,0x81EE,0xA002,0x81EB,0x81E9,0xA004,0xA002,0x81E8,0x81E6,0xA002,0x81E5, 0x81E4,0xA020,0xA000,0xA000,0xA00E,0xA006,0xA002,0x81E2,0xA002,0x81E1,0x81E0,0xA004,0xA002,0x81DF,0x81DE,0xA002, 0x81DD,0x81DC,0xA008,0xA004,0xA002,0x81DB,0x81DA,0xA002,0x81D9,0x81D8,0xA004,0xA002,0x81D7,0x81D6,0xA002,0x81D5, 0x81D4,0xA020,0xA001,0xA00F,0xA007,0xA003,0xA001,0x5B81,0xA002,0x51DD,0x72DE,0xA004,0xA002,0x67E0,0x60A8,0xA002, 0x6D85,0x954D,0xA008,0xA004,0xA002,0x954A,0x556E,0xA002,0x5B7D,0x8042,0xA004,0xA002,0x634F,0x5C3F,0xA002,0x9E1F, 0x917F,0xA020,0xA010,0xA008,0xA004,0xA002,0x5A18,0x5FF5,0xA002,0x637B,0x64B5,0xA004,0xA002,0x78BE,0x5E74,0xA002, 0x62C8,0x852B,0xA008,0xA004,0xA002,0x6EBA,0x9006,0xA002,0x817B,0x533F,0xA004,0xA002,0x4F60,0x62DF,0xA002,0x5C3C, 0x6CE5,0xA010,0xA008,0xA004,0xA002,0x502A,0x9713,0xA002,0x59AE,0x80FD,0xA004,0xA002,0x5AE9,0x5185,0xA002,0x9981, 0x5462,0xA008,0xA004,0xA002,0x6DD6,0x95F9,0xA002,0x607C,0x8111,0xA004,0xA002,0x6320,0x56CA,0xA002,0x96BE,0x7537, 0xA180,0xA0FD,0xA07E,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x5357,0xA002,0x5948,0x8010,0xA004,0xA002,0x5976,0x4E43, 0xA002,0x6C16,0x7EB3,0xA008,0xA004,0xA002,0x5A1C,0x90A3,0xA002,0x94A0,0x5450,0xA004,0xA002,0x54EA,0x62FF,0xA002, 0x7A46,0x7267,0xA010,0xA008,0xA004,0xA002,0x7766,0x76EE,0xA002,0x6728,0x6155,0xA004,0xA002,0x52DF,0x5E55,0xA002, 0x66AE,0x5893,0xA008,0xA004,0xA002,0x6BCD,0x59C6,0xA002,0x4EA9,0x7261,0xA004,0xA002,0x62C7,0x67D0,0xA002,0x725F, 0x8C0B,0xA020,0xA010,0xA008,0xA004,0xA002,0x964C,0x5BDE,0xA002,0x6F20,0x6CAB,0xA004,0xA002,0x9ED8,0x58A8,0xA002, 0x83AB,0x672B,0xA008,0xA004,0xA002,0x62B9,0x9B54,0xA002,0x6469,0x78E8,0xA004,0xA002,0x819C,0x6A21,0xA002,0x8611, 0x6479,0xA010,0xA008,0xA004,0xA002,0x81D3,0x81D2,0xA002,0x81D1,0x81D0,0xA004,0xA002,0x81CF,0x81CE,0xA002,0x81CD, 0x81CB,0xA008,0xA004,0xA002,0x81C9,0x81C8,0xA002,0x81C7,0x81C5,0xA004,0xA002,0x81C4,0x81BF,0xA002,0x81BE,0x81BD, 0xA03F,0xA020,0xA010,0xA008,0xA004,0xA002,0x81BC,0x81B9,0xA002,0x81B8,0x81B7,0xA004,0xA002,0x81B6,0x81B5,0xA002, 0x81B4,0x81B2,0xA008,0xA004,0xA002,0x81B1,0x81B0,0xA002,0x81AF,0x81AE,0xA004,0xA002,0x81AD,0x81AC,0xA002,0x81AB, 0x81A9,0xA00F,0xA007,0xA003,0xA000,0x81A7,0xA002,0x81A5,0x81A4,0xA004,0xA002,0x81A2,0x81A1,0xA002,0x81A0,0x819F, 0xA008,0xA004,0xA002,0x819E,0x819A,0xA002,0x8199,0x8197,0xA004,0xA002,0x8196,0x8195,0xA002,0x8194,0x8193,0xA020, 0xA010,0xA008,0xA004,0xA002,0x8192,0x8190,0xA002,0x818E,0x818D,0xA004,0xA002,0x818C,0x818B,0xA002,0x8189,0x8187, 0xA008,0xA004,0xA002,0x8186,0x8185,0xA002,0x8184,0x8183,0xA004,0xA002,0x8181,0x8178,0xA002,0x8177,0x8176,0xA010, 0xA008,0xA004,0xA002,0x8175,0x8173,0xA002,0x8172,0x816F,0xA004,0xA002,0x816C,0x816B,0xA002,0x816A,0x8168,0xA008, 0xA004,0xA002,0x8166,0x8164,0xA002,0x8163,0x8162,0xA004,0xA002,0x8161,0x815F,0xA002,0x815E,0x815D,0xA026,0xA000, 0xA01E,0xA00E,0xA006,0xA002,0x815C,0xA002,0x815B,0x8158,0xA004,0xA002,0x8157,0x8156,0xA002,0x8152,0x814F,0xA008, 0xA004,0xA002,0x814E,0x814D,0xA002,0x8149,0x8147,0xA004,0xA002,0x8145,0x8144,0xA002,0x8143,0x8142,0xA000,0xA000, 0xA000,0xA002,0x8141,0x8140,0xA01D,0xA001,0xA00C,0xA004,0xA001,0xA001,0x6478,0xA004,0xA002,0x8C2C,0x547D,0xA002, 0x540D,0x94ED,0xA008,0xA004,0xA002,0x9E23,0x879F,0xA002,0x660E,0x95FD,0xA004,0xA002,0x60AF,0x654F,0xA002,0x76BF, 0x62BF,0xA020,0xA010,0xA008,0xA004,0xA002,0x6C11,0x706D,0xA002,0x8511,0x5999,0xA004,0xA002,0x5E99,0x6E3A,0xA002, 0x79D2,0x85D0,0xA008,0xA004,0xA002,0x7784,0x63CF,0xA002,0x82D7,0x9762,0xA004,0xA002,0x7F05,0x5A29,0xA002,0x52C9, 0x514D,0xA010,0xA008,0xA004,0xA002,0x5195,0x7EF5,0xA002,0x7720,0x68C9,0xA004,0xA002,0x5E42,0x5BC6,0xA002,0x871C, 0x6CCC,0xA008,0xA004,0xA002,0x89C5,0x79D8,0xA002,0x7C73,0x5F25,0xA004,0xA002,0x8C1C,0x8FF7,0xA002,0x7CDC,0x9761, 0xA0FD,0xA07E,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x919A,0xA002,0x772F,0x5B5F,0xA004,0xA002,0x68A6,0x731B,0xA002, 0x9530,0x76DF,0xA008,0xA004,0xA002,0x6AAC,0x8499,0xA002,0x840C,0x4EEC,0xA004,0xA002,0x95F7,0x95E8,0xA002,0x5A9A, 0x59B9,0xA010,0xA008,0xA004,0xA002,0x5BD0,0x6627,0xA002,0x7F8E,0x6BCF,0xA004,0xA002,0x9541,0x5A92,0xA002,0x7709, 0x6CA1,0xA008,0xA004,0xA002,0x7164,0x9709,0xA002,0x9176,0x6885,0xA004,0xA002,0x679A,0x73AB,0xA002,0x4E48,0x8D38, 0xA020,0xA010,0xA008,0xA004,0xA002,0x8C8C,0x5E3D,0xA002,0x5192,0x8302,0xA004,0xA002,0x536F,0x94C6,0xA002,0x77DB, 0x6BDB,0xA008,0xA004,0xA002,0x951A,0x8305,0xA002,0x732B,0x83BD,0xA004,0xA002,0x5FD9,0x6C13,0xA002,0x76F2,0x832B, 0xA010,0xA008,0xA004,0xA002,0x8292,0x8C29,0xA002,0x813F,0x813D,0xA004,0xA002,0x813C,0x813B,0xA002,0x813A,0x8139, 0xA008,0xA004,0xA002,0x8137,0x8135,0xA002,0x8134,0x8133,0xA004,0xA002,0x8130,0x812E,0xA002,0x812D,0x812B,0xA03F, 0xA020,0xA010,0xA008,0xA004,0xA002,0x812A,0x8129,0xA002,0x8128,0x8127,0xA004,0xA002,0x8126,0x8125,0xA002,0x8124, 0x8123,0xA008,0xA004,0xA002,0x8122,0x8121,0xA002,0x8120,0x811F,0xA004,0xA002,0x811D,0x811C,0xA002,0x811B,0x8119, 0xA00F,0xA007,0xA004,0xA002,0x8117,0x8115,0xA000,0x810C,0xA004,0xA002,0x810B,0x8108,0xA002,0x8107,0x8105,0xA008, 0xA004,0xA002,0x8104,0x8103,0xA002,0x8101,0x8100,0xA004,0xA002,0x80FF,0x80FE,0xA002,0x80FB,0x80F9,0xA020,0xA010, 0xA008,0xA004,0xA002,0x80F7,0x80F5,0xA002,0x80EE,0x80E6,0xA004,0xA002,0x80E3,0x80E2,0xA002,0x80E0,0x80DF,0xA008, 0xA004,0xA002,0x80D8,0x80D5,0xA002,0x80D4,0x80D3,0xA004,0xA002,0x80D2,0x80D1,0xA002,0x80D0,0x80CF,0xA010,0xA008, 0xA004,0xA002,0x80CB,0x80CA,0xA002,0x80C9,0x80C8,0xA004,0xA002,0x80C7,0x80C5,0xA002,0x80BB,0x80B9,0xA008,0xA004, 0xA002,0x80B8,0x80B6,0xA002,0x80B5,0x80B3,0xA004,0xA002,0x80B0,0x80AC,0xA002,0x80A8,0x80A7,0xA029,0xA000,0xA01E, 0xA00E,0xA006,0xA002,0x80A6,0xA002,0x80A3,0x809E,0xA004,0xA002,0x8099,0x8097,0xA002,0x8095,0x8094,0xA008,0xA004, 0xA002,0x8092,0x8091,0xA002,0x8090,0x808F,0xA004,0xA002,0x808E,0x808D,0xA002,0x808A,0x8088,0xA000,0xA000,0xA004, 0xA002,0x8085,0x8082,0xA002,0x8081,0x807E,0xA019,0xA001,0xA008,0xA001,0xA003,0xA001,0x6F2B,0xA002,0x6162,0x66FC, 0xA008,0xA004,0xA002,0x8513,0x6EE1,0xA002,0x86EE,0x9992,0xA004,0xA002,0x7792,0x8109,0xA002,0x8FC8,0x5356,0xA020, 0xA010,0xA008,0xA004,0xA002,0x9EA6,0x4E70,0xA002,0x57CB,0x5417,0xA004,0xA002,0x561B,0x9A82,0xA002,0x9A6C,0x8682, 0xA008,0xA004,0xA002,0x7801,0x739B,0xA002,0x9EBB,0x5988,0xA004,0xA002,0x7EDC,0x9A86,0xA002,0x6D1B,0x843D,0xA010, 0xA008,0xA004,0xA002,0x88F8,0x9AA1,0xA002,0x7BA9,0x9523,0xA004,0xA002,0x903B,0x7F57,0xA002,0x87BA,0x841D,0xA008, 0xA004,0xA002,0x8BBA,0x7EB6,0xA002,0x6CA6,0x4ED1,0xA004,0xA002,0x4F26,0x8F6E,0xA002,0x62A1,0x7565,0xA2FE,0xA180, 0xA0FD,0xA07E,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x63A0,0xA002,0x4E71,0x5375,0xA004,0xA002,0x6EE6,0x5B6A,0xA002, 0x631B,0x5CE6,0xA008,0xA004,0xA002,0x7EFF,0x6EE4,0xA002,0x7387,0x5F8B,0xA004,0xA002,0x6C2F,0x8651,0xA002,0x7F15, 0x5C61,0xA010,0xA008,0xA004,0xA002,0x5C65,0x65C5,0xA002,0x4FA3,0x94DD,0xA004,0xA002,0x5415,0x9A74,0xA002,0x622E, 0x9646,0xA008,0xA004,0xA002,0x5F55,0x7984,0xA002,0x6F5E,0x9E7F,0xA004,0xA002,0x8D42,0x8DEF,0xA002,0x9732,0x788C, 0xA020,0xA010,0xA008,0xA004,0xA002,0x9E93,0x9C81,0xA002,0x864F,0x5364,0xA004,0xA002,0x63B3,0x7089,0xA002,0x5E90, 0x9885,0xA008,0xA004,0xA002,0x5362,0x82A6,0xA002,0x964B,0x6F0F,0xA004,0xA002,0x7BD3,0x6402,0xA002,0x5A04,0x697C, 0xA010,0xA008,0xA004,0xA002,0x9647,0x62E2,0xA002,0x5784,0x9686,0xA004,0xA002,0x807D,0x807C,0xA002,0x807B,0x807A, 0xA008,0xA004,0xA002,0x8079,0x8078,0xA002,0x8077,0x8076,0xA004,0xA002,0x8075,0x8074,0xA002,0x8073,0x8072,0xA03F, 0xA020,0xA010,0xA008,0xA004,0xA002,0x8070,0x806F,0xA002,0x806E,0x806D,0xA004,0xA002,0x806C,0x806B,0xA002,0x8068, 0x8067,0xA008,0xA004,0xA002,0x8066,0x8065,0xA002,0x8064,0x8063,0xA004,0xA002,0x8062,0x8061,0xA002,0x8060,0x805F, 0xA00F,0xA008,0xA004,0xA002,0x805E,0x805D,0xA002,0x805C,0x805B,0xA003,0xA000,0x8059,0xA002,0x8057,0x8056,0xA008, 0xA004,0xA002,0x8055,0x8053,0xA002,0x8051,0x8050,0xA004,0xA002,0x804F,0x804E,0xA002,0x8049,0x8048,0xA020,0xA010, 0xA008,0xA004,0xA002,0x8047,0x8045,0xA002,0x8044,0x8041,0xA004,0xA002,0x8040,0x803E,0xA002,0x803C,0x803A,0xA008, 0xA004,0xA002,0x8039,0x8034,0xA002,0x8032,0x8030,0xA004,0xA002,0x802F,0x802E,0xA002,0x802D,0x802C,0xA010,0xA008, 0xA004,0xA002,0x802B,0x8024,0xA002,0x8023,0x8021,0xA004,0xA002,0x801F,0x801E,0xA002,0x801D,0x801B,0xA008,0xA004, 0xA002,0x801A,0x8013,0xA002,0x8011,0x800F,0xA004,0xA002,0x800E,0x800A,0xA002,0x8009,0x8008,0xA02D,0xA000,0xA01E, 0xA00E,0xA006,0xA002,0x8007,0xA002,0x8002,0x7FFF,0xA004,0xA002,0x7FFE,0x7FFD,0xA002,0x7FFA,0x7FF9,0xA008,0xA004, 0xA002,0x7FF8,0x7FF7,0xA002,0x7FF6,0x7FF5,0xA004,0xA002,0x7FF4,0x7FF2,0xA002,0x7FEF,0x7FED,0xA000,0xA008,0xA004, 0xA002,0x7FEC,0x7FEB,0xA002,0x7FEA,0x7FE8,0xA000,0xA002,0x7FE7,0x7FE4,0xA016,0xA001,0xA005,0xA001,0xA001,0xA001, 0x7ABF,0xA008,0xA004,0xA002,0x7B3C,0x5499,0xA002,0x804B,0x9F99,0xA004,0xA002,0x516D,0x67F3,0xA002,0x6D41,0x7624, 0xA020,0xA010,0xA008,0xA004,0xA002,0x5218,0x7559,0xA002,0x998F,0x786B,0xA004,0xA002,0x69B4,0x7409,0xA002,0x6E9C, 0x4EE4,0xA008,0xA004,0xA002,0x53E6,0x9886,0xA002,0x5CAD,0x9675,0xA004,0xA002,0x7075,0x51CC,0xA002,0x7F9A,0x4F36, 0xA010,0xA008,0xA004,0xA002,0x94C3,0x9F84,0xA002,0x96F6,0x83F1,0xA004,0xA002,0x73B2,0x62CE,0xA002,0x541D,0x8D41, 0xA008,0xA004,0xA002,0x51DB,0x6DCB,0xA002,0x9CDE,0x90BB,0xA004,0xA002,0x4E34,0x9716,0xA002,0x78F7,0x6797,0xA0FD, 0xA07E,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x7433,0xA002,0x730E,0x52A3,0xA004,0xA002,0x70C8,0x88C2,0xA002,0x5217, 0x6599,0xA008,0xA004,0xA002,0x5ED6,0x9563,0xA002,0x6482,0x4E86,0xA004,0xA002,0x6F66,0x8FBD,0xA002,0x5BE5,0x71CE, 0xA010,0xA008,0xA004,0xA002,0x7597,0x50DA,0xA002,0x804A,0x64A9,0xA004,0xA002,0x8C05,0x4EAE,0xA002,0x667E,0x91CF, 0xA008,0xA004,0xA002,0x8F86,0x4E24,0xA002,0x826F,0x7CB1,0xA004,0xA002,0x6881,0x51C9,0xA002,0x7CAE,0x7EC3,0xA020, 0xA010,0xA008,0xA004,0xA002,0x70BC,0x604B,0xA002,0x94FE,0x8138,0xA004,0xA002,0x655B,0x5E18,0xA002,0x6D9F,0x601C, 0xA008,0xA004,0xA002,0x5EC9,0x9570,0xA002,0x8FDE,0x83B2,0xA004,0xA002,0x8054,0x4FE9,0xA002,0x54E9,0x7483,0xA010, 0xA008,0xA004,0xA002,0x529B,0x96B6,0xA002,0x6CA5,0x7C92,0xA004,0xA002,0x7ACB,0x75E2,0xA002,0x7FE3,0x7FE2,0xA008, 0xA004,0xA002,0x7FDE,0x7FDD,0xA002,0x7FDC,0x7FDB,0xA004,0xA002,0x7FDA,0x7FD9,0xA002,0x7FD7,0x7FD6,0xA03F,0xA020, 0xA010,0xA008,0xA004,0xA002,0x7FD3,0x7FD2,0xA002,0x7FD1,0x7FD0,0xA004,0xA002,0x7FCF,0x7FCD,0xA002,0x7FCB,0x7FC9, 0xA008,0xA004,0xA002,0x7FC8,0x7FC7,0xA002,0x7FC6,0x7FC4,0xA004,0xA002,0x7FC3,0x7FC2,0xA002,0x7FC0,0x7FBE,0xA00F, 0xA008,0xA004,0xA002,0x7FBB,0x7FBA,0xA002,0x7FB7,0x7FB6,0xA004,0xA002,0x7FB5,0x7FB4,0xA000,0x7FB3,0xA008,0xA004, 0xA002,0x7FB1,0x7FAE,0xA002,0x7FAD,0x7FAC,0xA004,0xA002,0x7FAB,0x7FAA,0xA002,0x7FA9,0x7FA8,0xA020,0xA010,0xA008, 0xA004,0xA002,0x7FA6,0x7FA5,0xA002,0x7FA3,0x7FA2,0xA004,0xA002,0x7FA0,0x7F9C,0xA002,0x7F9B,0x7F99,0xA008,0xA004, 0xA002,0x7F98,0x7F97,0xA002,0x7F96,0x7F95,0xA004,0xA002,0x7F93,0x7F92,0xA002,0x7F91,0x7F90,0xA010,0xA008,0xA004, 0xA002,0x7F8F,0x7F8D,0xA002,0x7F8B,0x7F89,0xA004,0xA002,0x7F88,0x7F87,0xA002,0x7F86,0x7F85,0xA008,0xA004,0xA002, 0x7F84,0x7F83,0xA002,0x7F82,0x7F80,0xA004,0xA002,0x7F7F,0x7F7D,0xA002,0x7F7C,0x7F7B,0xA030,0xA000,0xA01E,0xA00E, 0xA006,0xA002,0x7F7A,0xA002,0x7F78,0x7F77,0xA004,0xA002,0x7F76,0x7F75,0xA002,0x7F73,0x7F70,0xA008,0xA004,0xA002, 0x7F6F,0x7F6D,0xA002,0x7F6C,0x7F6B,0xA004,0xA002,0x7F67,0x7F66,0xA002,0x7F65,0x7F64,0xA000,0xA008,0xA004,0xA002, 0x7F63,0x7F60,0xA002,0x7F5E,0x7F5D,0xA004,0xA002,0x7F5C,0x7F5B,0xA002,0x7F59,0x7F56,0xA011,0xA001,0xA001,0xA007, 0xA003,0xA001,0x4FD0,0xA002,0x4F8B,0x5088,0xA004,0xA002,0x5229,0x5386,0xA002,0x783E,0x52B1,0xA020,0xA010,0xA008, 0xA004,0xA002,0x5389,0x4E3D,0xA002,0x6817,0x540F,0xA004,0xA002,0x8354,0x8389,0xA002,0x793C,0x9CA4,0xA008,0xA004, 0xA002,0x91CC,0x674E,0xA002,0x7406,0x6F13,0xA004,0xA002,0x79BB,0x72F8,0xA002,0x7BF1,0x9ECE,0xA010,0xA008,0xA004, 0xA002,0x7281,0x68A8,0xA002,0x5398,0x51B7,0xA004,0xA002,0x695E,0x68F1,0xA002,0x6CEA,0x7C7B,0xA008,0xA004,0xA002, 0x808B,0x64C2,0xA002,0x5792,0x5121,0xA004,0xA002,0x7D2F,0x78CA,0xA002,0x857E,0x956D,0xA180,0xA0FD,0xA07E,0xA03E, 0xA01E,0xA00E,0xA006,0xA002,0x96F7,0xA002,0x4E50,0x52D2,0xA004,0xA002,0x6D9D,0x70D9,0xA002,0x916A,0x59E5,0xA008, 0xA004,0xA002,0x4F6C,0x8001,0xA002,0x7262,0x52B3,0xA004,0xA002,0x635E,0x6D6A,0xA002,0x6717,0x90CE,0xA010,0xA008, 0xA004,0xA002,0x5ECA,0x72FC,0xA002,0x6994,0x7405,0xA004,0xA002,0x6EE5,0x70C2,0xA002,0x7F06,0x61D2,0xA008,0xA004, 0xA002,0x89C8,0x63FD,0xA002,0x8C30,0x6F9C,0xA004,0xA002,0x5170,0x9611,0xA002,0x7BEE,0x62E6,0xA020,0xA010,0xA008, 0xA004,0xA002,0x680F,0x5A6A,0xA002,0x84DD,0x8D56,0xA004,0xA002,0x6765,0x83B1,0xA002,0x5566,0x8FA3,0xA008,0xA004, 0xA002,0x814A,0x8721,0xA002,0x5587,0x62C9,0xA004,0xA002,0x5783,0x9614,0xA002,0x5ED3,0x6269,0xA010,0xA008,0xA004, 0xA002,0x62EC,0x56F0,0xA002,0x6346,0x6606,0xA004,0xA002,0x5764,0x6E83,0xA002,0x6127,0x9988,0xA008,0xA004,0xA002, 0x7F53,0x7F52,0xA002,0x7F4F,0x7F4E,0xA004,0xA002,0x7F4D,0x7F4C,0xA002,0x7F4B,0x7F4A,0xA03F,0xA020,0xA010,0xA008, 0xA004,0xA002,0x7F49,0x7F48,0xA002,0x7F47,0x7F46,0xA004,0xA002,0x7F43,0x7F41,0xA002,0x7F40,0x7F3F,0xA008,0xA004, 0xA002,0x7F3E,0x7F3D,0xA002,0x7F3C,0x7F3B,0xA004,0xA002,0x7F39,0x7F37,0xA002,0x7F1E,0x7F10,0xA010,0xA008,0xA004, 0xA002,0x7F0A,0x7EF9,0xA002,0x7EEC,0x7EE4,0xA004,0xA002,0x7ED6,0x7EBC,0xA002,0x7EBB,0x7EB4,0xA007,0xA003,0xA000, 0x7EAE,0xA002,0x7E9E,0x7E9D,0xA004,0xA002,0x7E9C,0x7E9A,0xA002,0x7E99,0x7E98,0xA020,0xA010,0xA008,0xA004,0xA002, 0x7E97,0x7E96,0xA002,0x7E95,0x7E94,0xA004,0xA002,0x7E93,0x7E92,0xA002,0x7E91,0x7E90,0xA008,0xA004,0xA002,0x7E8F, 0x7E8E,0xA002,0x7E8D,0x7E8C,0xA004,0xA002,0x7E8B,0x7E8A,0xA002,0x7E89,0x7E88,0xA010,0xA008,0xA004,0xA002,0x7E87, 0x7E86,0xA002,0x7E85,0x7E84,0xA004,0xA002,0x7E83,0x7E81,0xA002,0x7E80,0x7E7F,0xA008,0xA004,0xA002,0x7E7E,0x7E7D, 0xA002,0x7E7C,0x7E7B,0xA004,0xA002,0x7E7A,0x7E79,0xA002,0x7E78,0x7E77,0xA035,0xA000,0xA01E,0xA00E,0xA006,0xA002, 0x7E76,0xA002,0x7E75,0x7E74,0xA004,0xA002,0x7E73,0x7E72,0xA002,0x7E71,0x7E70,0xA008,0xA004,0xA002,0x7E6F,0x7E6E, 0xA002,0x7E6D,0x7E6C,0xA004,0xA002,0x7E6B,0x7E6A,0xA002,0x7E69,0x7E68,0xA010,0xA008,0xA004,0xA002,0x7E67,0x7E66, 0xA002,0x7E65,0x7E64,0xA004,0xA002,0x7E63,0x7E62,0xA002,0x7E61,0x7E60,0xA000,0xA000,0xA002,0x7E5F,0x7E5E,0xA00E, 0xA001,0xA001,0xA004,0xA001,0xA001,0x5080,0xA004,0xA002,0x9B41,0x594E,0xA002,0x8475,0x7AA5,0xA020,0xA010,0xA008, 0xA004,0xA002,0x5CBF,0x76D4,0xA002,0x4E8F,0x51B5,0xA004,0xA002,0x65F7,0x7736,0xA002,0x77FF,0x6846,0xA008,0xA004, 0xA002,0x72C2,0x7B50,0xA002,0x5321,0x6B3E,0xA004,0xA002,0x5BBD,0x5FEB,0xA002,0x4FA9,0x7B77,0xA010,0xA008,0xA004, 0xA002,0x5757,0x80EF,0xA002,0x8DE8,0x630E,0xA004,0xA002,0x57AE,0x5938,0xA002,0x88E4,0x5E93,0xA008,0xA004,0xA002, 0x9177,0x82E6,0xA002,0x7A9F,0x54ED,0xA004,0xA002,0x67AF,0x5BC7,0xA002,0x6263,0x53E3,0xA0FD,0xA07E,0xA03E,0xA01E, 0xA00E,0xA006,0xA002,0x62A0,0xA002,0x63A7,0x5B54,0xA004,0xA002,0x6050,0x7A7A,0xA002,0x542D,0x5751,0xA008,0xA004, 0xA002,0x6073,0x57A6,0xA002,0x5543,0x80AF,0xA004,0xA002,0x8BFE,0x5BA2,0xA002,0x523B,0x514B,0xA010,0xA008,0xA004, 0xA002,0x6E34,0x53EF,0xA002,0x54B3,0x58F3,0xA004,0xA002,0x79D1,0x9897,0xA002,0x78D5,0x68F5,0xA008,0xA004,0xA002, 0x67EF,0x82DB,0xA002,0x5777,0x9760,0xA004,0xA002,0x70E4,0x62F7,0xA002,0x8003,0x7095,0xA020,0xA010,0xA008,0xA004, 0xA002,0x4EA2,0x6297,0xA002,0x625B,0x7CE0,0xA004,0xA002,0x6177,0x5EB7,0xA002,0x770B,0x780D,0xA008,0xA004,0xA002, 0x574E,0x52D8,0xA002,0x582A,0x520A,0xA004,0xA002,0x6168,0x51EF,0xA002,0x6977,0x63E9,0xA010,0xA008,0xA004,0xA002, 0x5F00,0x54AF,0xA002,0x5361,0x5496,0xA004,0xA002,0x5580,0x9A8F,0xA002,0x90E1,0x6D5A,0xA008,0xA004,0xA002,0x7AE3, 0x4FCA,0xA002,0x7E5D,0x7E5C,0xA004,0xA002,0x7E5B,0x7E5A,0xA002,0x7E59,0x7E58,0xA03F,0xA020,0xA010,0xA008,0xA004, 0xA002,0x7E57,0x7E56,0xA002,0x7E55,0x7E54,0xA004,0xA002,0x7E53,0x7E52,0xA002,0x7E51,0x7E50,0xA008,0xA004,0xA002, 0x7E4F,0x7E4E,0xA002,0x7E4D,0x7E4C,0xA004,0xA002,0x7E4B,0x7E4A,0xA002,0x7E49,0x7E48,0xA010,0xA008,0xA004,0xA002, 0x7E46,0x7E45,0xA002,0x7E44,0x7E43,0xA004,0xA002,0x7E42,0x7E40,0xA002,0x7E3F,0x7E3E,0xA007,0xA004,0xA002,0x7E3D, 0x7E3C,0xA000,0x7E3A,0xA004,0xA002,0x7E39,0x7E38,0xA002,0x7E37,0x7E36,0xA020,0xA010,0xA008,0xA004,0xA002,0x7E35, 0x7E34,0xA002,0x7E33,0x7E32,0xA004,0xA002,0x7E31,0x7E30,0xA002,0x7E2F,0x7E2E,0xA008,0xA004,0xA002,0x7E2D,0x7E2C, 0xA002,0x7E2B,0x7E2A,0xA004,0xA002,0x7E29,0x7E28,0xA002,0x7E27,0x7E26,0xA010,0xA008,0xA004,0xA002,0x7E25,0x7E24, 0xA002,0x7E23,0x7E22,0xA004,0xA002,0x7E21,0x7E20,0xA002,0x7E1F,0x7E1E,0xA008,0xA004,0xA002,0x7E1D,0x7E1C,0xA002, 0x7E1B,0x7E1A,0xA004,0xA002,0x7E19,0x7E18,0xA002,0x7E17,0x7E16,0xA038,0xA000,0xA01E,0xA00E,0xA006,0xA002,0x7E15, 0xA002,0x7E14,0x7E13,0xA004,0xA002,0x7E12,0x7E11,0xA002,0x7E10,0x7E0F,0xA008,0xA004,0xA002,0x7E0E,0x7E0D,0xA002, 0x7E0C,0x7E0B,0xA004,0xA002,0x7E0A,0x7E09,0xA002,0x7E08,0x7E07,0xA010,0xA008,0xA004,0xA002,0x7E06,0x7E05,0xA002, 0x7E04,0x7E03,0xA004,0xA002,0x7E02,0x7E01,0xA002,0x7E00,0x7DFF,0xA000,0xA004,0xA002,0x7DFE,0x7DFD,0xA002,0x7DFC, 0x7DFB,0xA00A,0xA001,0xA001,0xA001,0xA003,0xA001,0x5CFB,0xA002,0x541B,0x519B,0xA020,0xA010,0xA008,0xA004,0xA002, 0x94A7,0x83CC,0xA002,0x5747,0x7EDD,0xA004,0xA002,0x8BC0,0x51B3,0xA002,0x89C9,0x7235,0xA008,0xA004,0xA002,0x5014, 0x6398,0xA002,0x6289,0x652B,0xA004,0xA002,0x6485,0x7EE2,0xA002,0x5377,0x7737,0xA010,0xA008,0xA004,0xA002,0x5026, 0x5A1F,0xA002,0x9E43,0x6350,0xA004,0xA002,0x5267,0x70AC,0xA002,0x60E7,0x53E5,0xA008,0xA004,0xA002,0x4FF1,0x952F, 0xA002,0x8E1E,0x8DDD,0xA004,0xA002,0x5177,0x5DE8,0xA002,0x636E,0x62D2,0xC53E,0xB72E,0xABF4,0xA5F9,0xA2FA,0xA17A, 0xA0FB,0xA07E,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x805A,0xA002,0x6CAE,0x4E3E,0xA004,0xA002,0x77E9,0x5480,0xA002, 0x5C40,0x83CA,0xA008,0xA004,0xA002,0x9A79,0x5C45,0xA002,0x75BD,0x72D9,0xA004,0xA002,0x62D8,0x97A0,0xA002,0x759A, 0x5C31,0xA010,0xA008,0xA004,0xA002,0x548E,0x8205,0xA002,0x81FC,0x65E7,0xA004,0xA002,0x6551,0x53A9,0xA002,0x9152, 0x4E5D,0xA008,0xA004,0xA002,0x7078,0x4E45,0xA002,0x97ED,0x7396,0xA004,0xA002,0x7EA0,0x7A76,0xA002,0x63EA,0x7A98, 0xA020,0xA010,0xA008,0xA004,0xA002,0x70AF,0x51C0,0xA002,0x7ADE,0x7ADF,0xA004,0xA002,0x9756,0x75C9,0xA002,0x5F84, 0x955C,0xA008,0xA004,0xA002,0x656C,0x5883,0xA002,0x9759,0x9888,0xA004,0xA002,0x666F,0x8B66,0xA002,0x4E95,0x7ECF, 0xA010,0xA008,0xA004,0xA002,0x7CB3,0x7CBE,0xA002,0x60CA,0x4EAC,0xA004,0xA002,0x9CB8,0x6676,0xA002,0x775B,0x830E, 0xA008,0xA004,0xA002,0x5162,0x8346,0xA002,0x52B2,0x5C3D,0xA004,0xA002,0x7DFA,0x7DF9,0xA002,0x7DF8,0x7DF7,0xA03D, 0xA01E,0xA00E,0xA006,0xA002,0x7DF6,0xA002,0x7DF5,0x7DF4,0xA004,0xA002,0x7DF3,0x7DF2,0xA002,0x7DF1,0x7DF0,0xA008, 0xA004,0xA002,0x7DEF,0x7DEE,0xA002,0x7DED,0x7DEC,0xA004,0xA002,0x7DEB,0x7DEA,0xA002,0x7DE9,0x7DE8,0xA010,0xA008, 0xA004,0xA002,0x7DE7,0x7DE6,0xA002,0x7DE5,0x7DE4,0xA004,0xA002,0x7DE3,0x7DE2,0xA002,0x7DE1,0x7DE0,0xA008,0xA004, 0xA002,0x7DDF,0x7DDE,0xA002,0x7DDD,0x7DDC,0xA004,0xA002,0x7DDB,0x7DDA,0xA001,0x7DD9,0xA020,0xA010,0xA008,0xA004, 0xA002,0x7DD8,0x7DD7,0xA002,0x7DD6,0x7DD5,0xA004,0xA002,0x7DD4,0x7DD3,0xA002,0x7DD2,0x7DD1,0xA008,0xA004,0xA002, 0x7DD0,0x7DCF,0xA002,0x7DCE,0x7DCD,0xA004,0xA002,0x7DCC,0x7DCB,0xA002,0x7DCA,0x7DC9,0xA010,0xA008,0xA004,0xA002, 0x7DC8,0x7DC7,0xA002,0x7DC6,0x7DC5,0xA004,0xA002,0x7DC4,0x7DC3,0xA002,0x7DC2,0x7DC1,0xA008,0xA004,0xA002,0x7DC0, 0x7DBF,0xA002,0x7DBE,0x7DBD,0xA004,0xA002,0x7DBC,0x7DBB,0xA002,0x7DBA,0x7DB9,0xA03E,0xA000,0xA01E,0xA00E,0xA006, 0xA002,0x7DB8,0xA002,0x7DB7,0x7DB6,0xA004,0xA002,0x7DB5,0x7DB4,0xA002,0x7DB3,0x7DB2,0xA008,0xA004,0xA002,0x7DB1, 0x7DB0,0xA002,0x7DAF,0x7DAD,0xA004,0xA002,0x7DAC,0x7DAB,0xA002,0x7DAA,0x7DA9,0xA010,0xA008,0xA004,0xA002,0x7DA8, 0x7DA7,0xA002,0x7DA5,0x7DA4,0xA004,0xA002,0x7DA3,0x7DA2,0xA002,0x7DA1,0x7DA0,0xA008,0xA004,0xA002,0x7D9F,0x7D9E, 0xA002,0x7D9D,0x7D9C,0xA004,0xA002,0x7D9B,0x7D9A,0xA000,0x7D99,0xA001,0xA020,0xA010,0xA008,0xA004,0xA002,0x6D78, 0x70EC,0xA002,0x8FD1,0x7981,0xA004,0xA002,0x664B,0x9773,0xA002,0x8FDB,0x8C28,0xA008,0xA004,0xA002,0x4EC5,0x9526, 0xA002,0x7D27,0x895F,0xA004,0xA002,0x6D25,0x4ECA,0xA002,0x91D1,0x65A4,0xA010,0xA008,0xA004,0xA002,0x7B4B,0x5DFE, 0xA002,0x5C4A,0x8BEB,0xA004,0xA002,0x75A5,0x4ECB,0xA002,0x501F,0x754C,0xA008,0xA004,0xA002,0x82A5,0x85C9,0xA002, 0x6212,0x59D0,0xA004,0xA002,0x89E3,0x7ED3,0xA002,0x6D01,0x7AED,0xA0FD,0xA07E,0xA03E,0xA01E,0xA00E,0xA006,0xA002, 0x776B,0xA002,0x6377,0x6770,0xA004,0xA002,0x6854,0x8282,0xA002,0x52AB,0x622A,0xA008,0xA004,0xA002,0x9636,0x8857, 0xA002,0x79F8,0x7686,0xA004,0xA002,0x63A5,0x63ED,0xA002,0x7A96,0x53EB,0xA010,0xA008,0xA004,0xA002,0x8F83,0x8F7F, 0xA002,0x9175,0x6559,0xA004,0xA002,0x527F,0x7EDE,0xA002,0x7F34,0x997A,0xA008,0xA004,0xA002,0x89D2,0x72E1,0xA002, 0x811A,0x4FA5,0xA004,0xA002,0x77EB,0x94F0,0xA002,0x6405,0x56BC,0xA020,0xA010,0xA008,0xA004,0xA002,0x5A07,0x9A84, 0xA002,0x6D47,0x90CA,0xA004,0xA002,0x4EA4,0x80F6,0xA002,0x7126,0x7901,0xA008,0xA004,0xA002,0x6912,0x8549,0xA002, 0x964D,0x9171,0xA004,0xA002,0x5320,0x8BB2,0xA002,0x5956,0x6868,0xA010,0xA008,0xA004,0xA002,0x848B,0x7586,0xA002, 0x6C5F,0x6D46,0xA004,0xA002,0x5C06,0x59DC,0xA002,0x50F5,0x5EFA,0xA008,0xA004,0xA002,0x6DA7,0x6E85,0xA002,0x6E10, 0x996F,0xA004,0xA002,0x5251,0x8230,0xA002,0x5065,0x7D98,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x7D97,0x7D96, 0xA002,0x7D95,0x7D94,0xA004,0xA002,0x7D93,0x7D92,0xA002,0x7D91,0x7D90,0xA008,0xA004,0xA002,0x7D8F,0x7D8E,0xA002, 0x7D8D,0x7D8C,0xA004,0xA002,0x7D8B,0x7D8A,0xA002,0x7D89,0x7D88,0xA010,0xA008,0xA004,0xA002,0x7D87,0x7D86,0xA002, 0x7D85,0x7D84,0xA004,0xA002,0x7D83,0x7D82,0xA002,0x7D81,0x7D80,0xA008,0xA004,0xA002,0x7D7F,0x7D7E,0xA002,0x7D7D, 0x7D7C,0xA004,0xA002,0x7D7B,0x7D7A,0xA002,0x7D79,0x7D78,0xA01F,0xA00F,0xA007,0xA003,0xA001,0x7D76,0xA002,0x7D75, 0x7D74,0xA004,0xA002,0x7D73,0x7D72,0xA002,0x7D71,0x7D70,0xA008,0xA004,0xA002,0x7D6F,0x7D6D,0xA002,0x7D6C,0x7D6B, 0xA004,0xA002,0x7D6A,0x7D69,0xA002,0x7D68,0x7D67,0xA010,0xA008,0xA004,0xA002,0x7D66,0x7D65,0xA002,0x7D64,0x7D63, 0xA004,0xA002,0x7D62,0x7D61,0xA002,0x7D60,0x7D5F,0xA008,0xA004,0xA002,0x7D5E,0x7D5D,0xA002,0x7D5C,0x7D5B,0xA004, 0xA002,0x7D5A,0x7D59,0xA002,0x7D58,0x7D57,0xA045,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x7D56,0xA002,0x7D55,0x7D54, 0xA004,0xA002,0x7D53,0x7D52,0xA002,0x7D51,0x7D50,0xA008,0xA004,0xA002,0x7D4F,0x7D4E,0xA002,0x7D4D,0x7D4C,0xA004, 0xA002,0x7D4B,0x7D4A,0xA002,0x7D49,0x7D48,0xA010,0xA008,0xA004,0xA002,0x7D47,0x7D46,0xA002,0x7D45,0x7D44,0xA004, 0xA002,0x7D43,0x7D42,0xA002,0x7D41,0x7D40,0xA008,0xA004,0xA002,0x7D3F,0x7D3E,0xA002,0x7D3D,0x7D3C,0xA004,0xA002, 0x7D3B,0x7D3A,0xA002,0x7D39,0x7D38,0xA000,0xA000,0xA000,0xA000,0xA000,0x7D37,0xA001,0xA01D,0xA00D,0xA005,0xA001, 0xA002,0x4EF6,0x7BAD,0xA004,0xA002,0x952E,0x89C1,0xA002,0x8D31,0x8DF5,0xA008,0xA004,0xA002,0x9274,0x69DB,0xA002, 0x8350,0x51CF,0xA004,0xA002,0x526A,0x4FED,0xA002,0x7B80,0x6361,0xA010,0xA008,0xA004,0xA002,0x62E3,0x7877,0xA002, 0x78B1,0x67EC,0xA004,0xA002,0x68C0,0x8327,0xA002,0x7F04,0x5978,0xA008,0xA004,0xA002,0x8270,0x80A9,0xA002,0x517C, 0x714E,0xA004,0xA002,0x95F4,0x7B3A,0xA002,0x5C16,0x575A,0xA17F,0xA0FD,0xA07E,0xA03E,0xA01E,0xA00E,0xA006,0xA002, 0x76D1,0xA002,0x6B7C,0x5AC1,0xA004,0xA002,0x9A7E,0x67B6,0xA002,0x4EF7,0x7A3C,0xA008,0xA004,0xA002,0x5047,0x94BE, 0xA002,0x7532,0x8D3E,0xA004,0xA002,0x988A,0x835A,0xA002,0x52A0,0x5BB6,0xA010,0xA008,0xA004,0xA002,0x4F73,0x5939, 0xA002,0x67B7,0x5609,0xA004,0xA002,0x7EAA,0x7EE7,0xA002,0x5993,0x9645,0xA008,0xA004,0xA002,0x5FCC,0x65E2,0xA002, 0x8BB0,0x8BA1,0xA004,0xA002,0x5BC2,0x5BC4,0xA002,0x6D4E,0x60B8,0xA020,0xA010,0xA008,0xA004,0xA002,0x5242,0x796D, 0xA002,0x4F0E,0x5B63,0xA004,0xA002,0x5180,0x6280,0xA002,0x84DF,0x5DF1,0xA008,0xA004,0xA002,0x810A,0x51E0,0xA002, 0x6324,0x7EA7,0xA004,0xA002,0x5AC9,0x5373,0xA002,0x6C72,0x75BE,0xA010,0xA008,0xA004,0xA002,0x6025,0x53CA,0xA002, 0x96C6,0x7C4D,0xA004,0xA002,0x8F91,0x68D8,0xA002,0x6781,0x5409,0xA008,0xA004,0xA002,0x7F09,0x7EE9,0xA002,0x59EC, 0x9E21,0xA004,0xA002,0x8BA5,0x6FC0,0xA002,0x8FF9,0x9965,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x808C,0x7D36, 0xA002,0x7D35,0x7D34,0xA004,0xA002,0x7D33,0x7D32,0xA002,0x7D31,0x7D30,0xA008,0xA004,0xA002,0x7D2E,0x7D2D,0xA002, 0x7D2C,0x7D2A,0xA004,0xA002,0x7D29,0x7D28,0xA002,0x7D26,0x7D25,0xA010,0xA008,0xA004,0xA002,0x7D24,0x7D23,0xA002, 0x7D21,0x7D1F,0xA004,0xA002,0x7D1E,0x7D1D,0xA002,0x7D1C,0x7D1B,0xA008,0xA004,0xA002,0x7D1A,0x7D19,0xA002,0x7D18, 0x7D17,0xA004,0xA002,0x7D16,0x7D15,0xA002,0x7D14,0x7D13,0xA01F,0xA00F,0xA007,0xA004,0xA002,0x7D12,0x7D11,0xA001, 0x7D10,0xA004,0xA002,0x7D0F,0x7D0E,0xA002,0x7D0D,0x7D0C,0xA008,0xA004,0xA002,0x7D0B,0x7D09,0xA002,0x7D08,0x7D07, 0xA004,0xA002,0x7D06,0x7D05,0xA002,0x7D04,0x7D03,0xA010,0xA008,0xA004,0xA002,0x7D02,0x7D01,0xA002,0x7D00,0x7CFF, 0xA004,0xA002,0x7CFE,0x7CFD,0xA002,0x7CFC,0x7CFA,0xA008,0xA004,0xA002,0x7CF9,0x7CF7,0xA002,0x7CF6,0x7CF5,0xA004, 0xA002,0x7CF4,0x7CF3,0xA002,0x7CF2,0x7CF1,0xA048,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x7CF0,0xA002,0x7CEE,0x7CED, 0xA004,0xA002,0x7CEC,0x7CEB,0xA002,0x7CEA,0x7CE9,0xA008,0xA004,0xA002,0x7CE7,0x7CE6,0xA002,0x7CE5,0x7CE4,0xA004, 0xA002,0x7CE3,0x7CE2,0xA002,0x7CE1,0x7CDE,0xA010,0xA008,0xA004,0xA002,0x7CDD,0x7CDB,0xA002,0x7CDA,0x7CD8,0xA004, 0xA002,0x7CD4,0x7CD3,0xA002,0x7CD2,0x7CD1,0xA008,0xA004,0xA002,0x7CD0,0x7CCF,0xA002,0x7CCE,0x7CCB,0xA004,0xA002, 0x7CC9,0x7CC6,0xA002,0x7CC4,0x7CC3,0xA000,0xA000,0xA000,0xA004,0xA002,0x7CC2,0x7CC0,0xA000,0x7CBF,0xA001,0xA019, 0xA009,0xA001,0xA004,0xA002,0x7B95,0x79EF,0xA002,0x7A3D,0x7578,0xA008,0xA004,0xA002,0x673A,0x57FA,0xA002,0x573E, 0x51FB,0xA004,0xA002,0x7978,0x8D27,0xA002,0x970D,0x60D1,0xA010,0xA008,0xA004,0xA002,0x6216,0x83B7,0xA002,0x706B, 0x4F19,0xA004,0xA002,0x6D3B,0x8C41,0xA002,0x6DF7,0x6D51,0xA008,0xA004,0xA002,0x9B42,0x5A5A,0xA002,0x660F,0x8364, 0xA004,0xA002,0x7ED8,0x8BF2,0xA002,0x8BB3,0x6C47,0xA0FD,0xA07E,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x70E9,0xA002, 0x4F1A,0x79FD,0xA004,0xA002,0x8D3F,0x6666,0xA002,0x60E0,0x5349,0xA008,0xA004,0xA002,0x6167,0x6094,0xA002,0x6BC1, 0x56DE,0xA004,0xA002,0x86D4,0x6062,0xA002,0x5FBD,0x8F89,0xA010,0xA008,0xA004,0xA002,0x6325,0x7070,0xA002,0x8C0E, 0x604D,0xA004,0xA002,0x5E4C,0x6643,0xA002,0x714C,0x60F6,0xA008,0xA004,0xA002,0x51F0,0x7687,0xA002,0x7C27,0x8757, 0xA004,0xA002,0x78FA,0x9EC4,0xA002,0x614C,0x8352,0xA020,0xA010,0xA008,0xA004,0xA002,0x5E7B,0x5BA6,0xA002,0x6DA3, 0x7115,0xA004,0xA002,0x8C62,0x75EA,0xA002,0x5524,0x60A3,0xA008,0xA004,0xA002,0x6362,0x7F13,0xA002,0x8FD8,0x6853, 0xA004,0xA002,0x73AF,0x6B22,0xA002,0x574F,0x6DEE,0xA010,0xA008,0xA004,0xA002,0x6000,0x5F8A,0xA002,0x69D0,0x8BDD, 0xA004,0xA002,0x5316,0x5212,0xA002,0x753B,0x6ED1,0xA008,0xA004,0xA002,0x733E,0x534E,0xA002,0x54D7,0x82B1,0xA004, 0xA002,0x6237,0x6CAA,0xA002,0x4E92,0x62A4,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x552C,0x864E,0xA002,0x5F27, 0x7CBB,0xA004,0xA002,0x7CBA,0x7CB8,0xA002,0x7CB7,0x7CB6,0xA008,0xA004,0xA002,0x7CB5,0x7CB4,0xA002,0x7CB0,0x7CAF, 0xA004,0xA002,0x7CAD,0x7CAC,0xA002,0x7CAB,0x7CA9,0xA010,0xA008,0xA004,0xA002,0x7CA8,0x7CA7,0xA002,0x7CA6,0x7CA3, 0xA004,0xA002,0x7CA1,0x7CA0,0xA002,0x7C9B,0x7C9A,0xA008,0xA004,0xA002,0x7C99,0x7C96,0xA002,0x7C94,0x7C93,0xA004, 0xA002,0x7C90,0x7C8F,0xA002,0x7C8E,0x7C8D,0xA01F,0xA00F,0xA008,0xA004,0xA002,0x7C8C,0x7C8B,0xA002,0x7C8A,0x7C88, 0xA003,0xA001,0x7C87,0xA002,0x7C86,0x7C85,0xA008,0xA004,0xA002,0x7C84,0x7C83,0xA002,0x7C82,0x7C81,0xA004,0xA002, 0x7C80,0x7C7F,0xA002,0x7C7E,0x7C7A,0xA010,0xA008,0xA004,0xA002,0x7C79,0x7C78,0xA002,0x7C77,0x7C76,0xA004,0xA002, 0x7C75,0x7C72,0xA002,0x7C71,0x7C70,0xA008,0xA004,0xA002,0x7C6F,0x7C6E,0xA002,0x7C6D,0x7C6C,0xA004,0xA002,0x7C6B, 0x7C6A,0xA002,0x7C69,0x7C68,0xA04C,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x7C67,0xA002,0x7C66,0x7C65,0xA004,0xA002, 0x7C64,0x7C63,0xA002,0x7C62,0x7C61,0xA008,0xA004,0xA002,0x7C60,0x7C5F,0xA002,0x7C5E,0x7C5D,0xA004,0xA002,0x7C5C, 0x7C5B,0xA002,0x7C5A,0x7C59,0xA010,0xA008,0xA004,0xA002,0x7C58,0x7C57,0xA002,0x7C56,0x7C55,0xA004,0xA002,0x7C54, 0x7C53,0xA002,0x7C52,0x7C51,0xA008,0xA004,0xA002,0x7C50,0x7C4F,0xA002,0x7C4E,0x7C4C,0xA004,0xA002,0x7C4B,0x7C4A, 0xA002,0x7C49,0x7C48,0xA000,0xA000,0xA008,0xA004,0xA002,0x7C47,0x7C46,0xA002,0x7C45,0x7C44,0xA000,0xA000,0x7C43, 0xA001,0xA016,0xA006,0xA001,0xA001,0xA002,0x6E56,0x7CCA,0xA008,0xA004,0xA002,0x72D0,0x8774,0xA002,0x80E1,0x846B, 0xA004,0xA002,0x58F6,0x745A,0xA002,0x5FFD,0x4E4E,0xA010,0xA008,0xA004,0xA002,0x547C,0x540E,0xA002,0x5019,0x539A, 0xA004,0xA002,0x543C,0x7334,0xA002,0x4FAF,0x5589,0xA008,0xA004,0xA002,0x7EA2,0x5F18,0xA002,0x5B8F,0x6D2A,0xA004, 0xA002,0x9E3F,0x8679,0xA002,0x70D8,0x54C4,0xA2FC,0xA17C,0xA0FB,0xA07E,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x8F70, 0xA002,0x6052,0x8861,0xA004,0xA002,0x6A2A,0x4EA8,0xA002,0x54FC,0x6068,0xA008,0xA004,0xA002,0x72E0,0x5F88,0xA002, 0x75D5,0x9ED1,0xA004,0xA002,0x563F,0x8D3A,0xA002,0x9E64,0x8910,0xA010,0xA008,0xA004,0xA002,0x8D6B,0x6DB8,0xA002, 0x6CB3,0x9602,0xA004,0xA002,0x8C89,0x76D2,0xA002,0x5408,0x4F55,0xA008,0xA004,0xA002,0x548C,0x79BE,0xA002,0x6838, 0x83CF,0xA004,0xA002,0x8377,0x559D,0xA002,0x5475,0x6D69,0xA020,0xA010,0xA008,0xA004,0xA002,0x53F7,0x8017,0xA002, 0x597D,0x90DD,0xA004,0xA002,0x6BEB,0x8C6A,0xA002,0x568E,0x58D5,0xA008,0xA004,0xA002,0x822A,0x676D,0xA002,0x592F, 0x6C49,0xA004,0xA002,0x6C57,0x710A,0xA002,0x608D,0x61BE,0xA010,0xA008,0xA004,0xA002,0x65F1,0x634D,0xA002,0x64BC, 0x7FF0,0xA004,0xA002,0x7F55,0x558A,0xA002,0x51FD,0x5BD2,0xA008,0xA004,0xA002,0x6DB5,0x542B,0xA002,0x97E9,0x90AF, 0xA004,0xA002,0x61A8,0x9163,0xA002,0x9A87,0x5BB3,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x4EA5,0xA002,0x6C26,0x6D77, 0xA004,0xA002,0x5B69,0x9AB8,0xA002,0x7C42,0x7C3E,0xA008,0xA004,0xA002,0x7C3D,0x7C3C,0xA002,0x7C3B,0x7C3A,0xA004, 0xA002,0x7C39,0x7C37,0xA002,0x7C36,0x7C35,0xA010,0xA008,0xA004,0xA002,0x7C34,0x7C33,0xA002,0x7C32,0x7C31,0xA004, 0xA002,0x7C30,0x7C2F,0xA002,0x7C2E,0x7C2D,0xA008,0xA004,0xA002,0x7C2C,0x7C2B,0xA002,0x7C29,0x7C28,0xA004,0xA002, 0x7C25,0x7C24,0xA002,0x7C23,0x7C22,0xA01F,0xA00F,0xA008,0xA004,0xA002,0x7C21,0x7C20,0xA002,0x7C1E,0x7C1D,0xA004, 0xA002,0x7C1C,0x7C1B,0xA000,0x7C1A,0xA008,0xA004,0xA002,0x7C19,0x7C18,0xA002,0x7C17,0x7C15,0xA004,0xA002,0x7C14, 0x7C13,0xA002,0x7C12,0x7C11,0xA010,0xA008,0xA004,0xA002,0x7C10,0x7C0E,0xA002,0x7C0D,0x7C0A,0xA004,0xA002,0x7C09, 0x7C08,0xA002,0x7C06,0x7C05,0xA008,0xA004,0xA002,0x7C04,0x7C03,0xA002,0x7C02,0x7C01,0xA004,0xA002,0x7C00,0x7BFF, 0xA002,0x7BFD,0x7BFB,0xA050,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x7BFA,0xA002,0x7BF9,0x7BF8,0xA004,0xA002,0x7BF6, 0x7BF5,0xA002,0x7BF4,0x7BF3,0xA008,0xA004,0xA002,0x7BF2,0x7BF0,0xA002,0x7BEF,0x7BED,0xA004,0xA002,0x7BEC,0x7BEB, 0xA002,0x7BE9,0x7BE8,0xA010,0xA008,0xA004,0xA002,0x7BE7,0x7BE4,0xA002,0x7BE3,0x7BE2,0xA004,0xA002,0x7BE0,0x7BDF, 0xA002,0x7BDE,0x7BDC,0xA008,0xA004,0xA002,0x7BDB,0x7BD8,0xA002,0x7BD7,0x7BD6,0xA004,0xA002,0x7BD5,0x7BD4,0xA002, 0x7BD2,0x7BD0,0xA000,0xA000,0xA008,0xA004,0xA002,0x7BCF,0x7BCE,0xA002,0x7BCD,0x7BCB,0xA004,0xA002,0x7BCA,0x7BC9, 0xA002,0x7BC8,0x7BC5,0xA001,0xA010,0xA001,0xA007,0xA003,0xA001,0x54C8,0xA002,0x8FC7,0x88F9,0xA004,0xA002,0x679C, 0x56FD,0xA002,0x90ED,0x9505,0xA010,0xA008,0xA004,0xA002,0x68CD,0x6EDA,0xA002,0x8F8A,0x523D,0xA004,0xA002,0x8D35, 0x8DEA,0xA002,0x67DC,0x6842,0xA008,0xA004,0xA002,0x7678,0x8BE1,0xA002,0x9B3C,0x8F68,0xA004,0xA002,0x95FA,0x9F9F, 0xA002,0x5F52,0x7845,0xA0FD,0xA07E,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x572D,0xA002,0x89C4,0x7470,0xA004,0xA002, 0x901B,0x5E7F,0xA002,0x5149,0x8D2F,0xA008,0xA004,0xA002,0x704C,0x60EF,0xA002,0x7F50,0x9986,0xA004,0xA002,0x7BA1, 0x89C2,0xA002,0x51A0,0x5B98,0xA010,0xA008,0xA004,0xA002,0x5173,0x68FA,0xA002,0x602A,0x62D0,0xA004,0xA002,0x4E56, 0x8902,0xA002,0x6302,0x5BE1,0xA008,0xA004,0xA002,0x5250,0x74DC,0xA002,0x522E,0x96C7,0xA004,0xA002,0x56FA,0x987E, 0xA002,0x6545,0x80A1,0xA020,0xA010,0xA008,0xA004,0xA002,0x8C37,0x9AA8,0xA002,0x86CA,0x53E4,0xA004,0xA002,0x9F13, 0x59D1,0xA002,0x5B64,0x6CBD,0xA008,0xA004,0xA002,0x4F30,0x7B8D,0xA002,0x5495,0x83C7,0xA004,0xA002,0x8F9C,0x591F, 0xA002,0x8D2D,0x6784,0xA010,0xA008,0xA004,0xA002,0x57A2,0x72D7,0xA002,0x82DF,0x6C9F,0xA004,0xA002,0x52FE,0x94A9, 0xA002,0x5171,0x8D21,0xA008,0xA004,0xA002,0x62F1,0x6C5E,0xA002,0x5DE9,0x5F13,0xA004,0xA002,0x5BAB,0x516C,0xA002, 0x8EAC,0x4F9B,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x9F9A,0x606D,0xA002,0x529F,0x653B,0xA004,0xA002,0x5DE5, 0x6897,0xA002,0x803F,0x57C2,0xA008,0xA004,0xA002,0x7BC4,0x7BC3,0xA002,0x7BC2,0x7BC0,0xA004,0xA002,0x7BBF,0x7BBE, 0xA002,0x7BBD,0x7BBC,0xA010,0xA008,0xA004,0xA002,0x7BBB,0x7BBA,0xA002,0x7BB9,0x7BB7,0xA004,0xA002,0x7BB6,0x7BB5, 0xA002,0x7BB3,0x7BB2,0xA008,0xA004,0xA002,0x7BB0,0x7BAF,0xA002,0x7BAE,0x7BA5,0xA004,0xA002,0x7BA4,0x7BA3,0xA002, 0x7BA0,0x7B9F,0xA01F,0xA010,0xA008,0xA004,0xA002,0x7B9E,0x7B9B,0xA002,0x7B9A,0x7B99,0xA004,0xA002,0x7B98,0x7B96, 0xA002,0x7B93,0x7B92,0xA007,0xA003,0xA000,0x7B91,0xA002,0x7B8F,0x7B8E,0xA004,0xA002,0x7B8C,0x7B8B,0xA002,0x7B8A, 0x7B89,0xA010,0xA008,0xA004,0xA002,0x7B88,0x7B87,0xA002,0x7B86,0x7B84,0xA004,0xA002,0x7B83,0x7B82,0xA002,0x7B81, 0x7B7F,0xA008,0xA004,0xA002,0x7B7D,0x7B7C,0xA002,0x7B7A,0x7B78,0xA004,0xA002,0x7B76,0x7B74,0xA002,0x7B73,0x7B70, 0xA055,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x7B6F,0xA002,0x7B6D,0x7B6C,0xA004,0xA002,0x7B6B,0x7B6A,0xA002,0x7B69, 0x7B68,0xA008,0xA004,0xA002,0x7B67,0x7B66,0xA002,0x7B65,0x7B64,0xA004,0xA002,0x7B63,0x7B61,0xA002,0x7B5F,0x7B5E, 0xA010,0xA008,0xA004,0xA002,0x7B5C,0x7B59,0xA002,0x7B57,0x7B55,0xA004,0xA002,0x7B53,0x7B4E,0xA002,0x7B4D,0x7B4A, 0xA008,0xA004,0xA002,0x7B48,0x7B46,0xA002,0x7B44,0x7B43,0xA004,0xA002,0x7B42,0x7B41,0xA002,0x7B40,0x7B3F,0xA000, 0xA010,0xA008,0xA004,0xA002,0x7B3D,0x7B3B,0xA002,0x7B39,0x7B37,0xA004,0xA002,0x7B36,0x7B35,0xA002,0x7B34,0x7B32, 0xA000,0xA000,0xA002,0x7B30,0x7B2F,0xA001,0xA00D,0xA001,0xA004,0xA001,0xA001,0x7FB9,0xA004,0xA002,0x5E9A,0x66F4, 0xA002,0x8015,0x8DDF,0xA010,0xA008,0xA004,0xA002,0x6839,0x7ED9,0xA002,0x5404,0x4E2A,0xA004,0xA002,0x94EC,0x9694, 0xA002,0x9601,0x86E4,0xA008,0xA004,0xA002,0x683C,0x845B,0xA002,0x9769,0x5272,0xA004,0xA002,0x7599,0x80F3,0xA002, 0x9E3D,0x6208,0xA17F,0xA0FD,0xA07E,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x6401,0xA002,0x6B4C,0x54E5,0xA004,0xA002, 0x544A,0x7A3F,0xA002,0x9550,0x641E,0xA008,0xA004,0xA002,0x7CD5,0x7F94,0xA002,0x818F,0x9AD8,0xA004,0xA002,0x768B, 0x7BD9,0xA002,0x6760,0x6E2F,0xA010,0xA008,0xA004,0xA002,0x5C97,0x7EB2,0xA002,0x809B,0x7F38,0xA004,0xA002,0x94A2, 0x521A,0xA002,0x5188,0x8D63,0xA008,0xA004,0xA002,0x6562,0x79C6,0xA002,0x611F,0x8D76,0xA004,0xA002,0x809D,0x7AFF, 0xA002,0x67D1,0x6746,0xA020,0xA010,0xA008,0xA004,0xA002,0x7518,0x5E72,0xA002,0x6E89,0x76D6,0xA004,0xA002,0x9499, 0x6982,0xA002,0x6539,0x8BE5,0xA008,0xA004,0xA002,0x560E,0x5676,0xA002,0x5490,0x7F1A,0xA004,0xA002,0x5987,0x9644, 0xA002,0x8BA3,0x5BCC,0xA010,0xA008,0xA004,0xA002,0x8D1F,0x8179,0xA002,0x7236,0x961C,0xA004,0xA002,0x4ED8,0x5085, 0xA002,0x590D,0x8D4B,0xA008,0xA004,0xA002,0x8986,0x526F,0xA002,0x8D74,0x8150,0xA004,0xA002,0x5E9C,0x8151,0xA002, 0x812F,0x65A7,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x91DC,0x4FEF,0xA002,0x8F85,0x629A,0xA004,0xA002,0x752B, 0x5F17,0xA002,0x88B1,0x798F,0xA008,0xA004,0xA002,0x6DAA,0x6D6E,0xA002,0x7B2D,0x7B29,0xA004,0xA002,0x7B27,0x7B23, 0xA002,0x7B22,0x7B21,0xA010,0xA008,0xA004,0xA002,0x7B1F,0x7B1D,0xA002,0x7B1C,0x7B1A,0xA004,0xA002,0x7B18,0x7B17, 0xA002,0x7B16,0x7B13,0xA008,0xA004,0xA002,0x7B12,0x7B10,0xA002,0x7B0E,0x7B0D,0xA004,0xA002,0x7B0C,0x7B09,0xA002, 0x7B07,0x7B05,0xA01F,0xA010,0xA008,0xA004,0xA002,0x7B02,0x7B01,0xA002,0x7B00,0x7AFE,0xA004,0xA002,0x7AFC,0x7AFB, 0xA002,0x7AF8,0x7AF7,0xA007,0xA004,0xA002,0x7AF6,0x7AF5,0xA000,0x7AF4,0xA004,0xA002,0x7AF3,0x7AF2,0xA002,0x7AF1, 0x7AF0,0xA010,0xA008,0xA004,0xA002,0x7AEE,0x7AEC,0xA002,0x7AEB,0x7AEA,0xA004,0xA002,0x7AE9,0x7AE8,0xA002,0x7AE7, 0x7AE4,0xA008,0xA004,0xA002,0x7AE2,0x7AE1,0xA002,0x7ADD,0x7ADC,0xA004,0xA002,0x7ADB,0x7ADA,0xA002,0x7AD8,0x7AD7, 0xA058,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x7AD5,0xA002,0x7AD4,0x7AD3,0xA004,0xA002,0x7AD2,0x7AD1,0xA002,0x7AD0, 0x7ACF,0xA008,0xA004,0xA002,0x7ACE,0x7ACD,0xA002,0x7ACC,0x7ACA,0xA004,0xA002,0x7AC9,0x7AC8,0xA002,0x7AC7,0x7AC6, 0xA010,0xA008,0xA004,0xA002,0x7AC5,0x7AC4,0xA002,0x7AC3,0x7AC2,0xA004,0xA002,0x7AC1,0x7AC0,0xA002,0x7ABE,0x7ABD, 0xA008,0xA004,0xA002,0x7ABC,0x7ABB,0xA002,0x7ABA,0x7AB9,0xA004,0xA002,0x7AB8,0x7AB7,0xA002,0x7AB6,0x7AB5,0xA000, 0xA010,0xA008,0xA004,0xA002,0x7AB4,0x7AB2,0xA002,0x7AB1,0x7AB0,0xA004,0xA002,0x7AAF,0x7AAE,0xA002,0x7AAB,0x7AAA, 0xA000,0xA004,0xA002,0x7AA9,0x7AA7,0xA002,0x7AA4,0x7AA3,0xA001,0xA009,0xA001,0xA001,0xA003,0xA001,0x670D,0xA002, 0x4FD8,0x4F0F,0xA010,0xA008,0xA004,0xA002,0x7B26,0x6C1F,0xA002,0x5E45,0x8F90,0xA004,0xA002,0x62C2,0x6276,0xA002, 0x5B75,0x80A4,0xA008,0xA004,0xA002,0x6577,0x592B,0xA002,0x5426,0x4F5B,0xA004,0xA002,0x51E4,0x5949,0xA002,0x8BBD, 0x7F1D,0xA0FD,0xA07E,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x51AF,0xA002,0x9022,0x70FD,0xA004,0xA002,0x75AF,0x98CE, 0xA002,0x950B,0x5CF0,0xA008,0xA004,0xA002,0x8702,0x67AB,0xA002,0x5C01,0x4E30,0xA004,0xA002,0x7CAA,0x6124,0xA002, 0x5FFF,0x4EFD,0xA010,0xA008,0xA004,0xA002,0x594B,0x7C89,0xA002,0x6C7E,0x711A,0xA004,0xA002,0x575F,0x7EB7,0xA002, 0x5206,0x6C1B,0xA008,0xA004,0xA002,0x5429,0x915A,0xA002,0x82AC,0x8D39,0xA004,0xA002,0x6CB8,0x5E9F,0xA002,0x80BA, 0x5420,0xA020,0xA010,0xA008,0xA004,0xA002,0x8BFD,0x532A,0xA002,0x80A5,0x98DE,0xA004,0xA002,0x5561,0x975E,0xA002, 0x83F2,0x653E,0xA008,0xA004,0xA002,0x7EBA,0x8BBF,0xA002,0x4EFF,0x59A8,0xA004,0xA002,0x9632,0x623F,0xA002,0x80AA, 0x65B9,0xA010,0xA008,0xA004,0xA002,0x82B3,0x574A,0xA002,0x6CDB,0x996D,0xA004,0xA002,0x72AF,0x8D29,0xA002,0x8303, 0x8FD4,0xA008,0xA004,0xA002,0x53CD,0x70E6,0xA002,0x51E1,0x7E41,0xA004,0xA002,0x9492,0x77FE,0xA002,0x6A0A,0x7FFB, 0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x756A,0x5E06,0xA002,0x85E9,0x73D0,0xA004,0xA002,0x6CD5,0x9600,0xA002, 0x4E4F,0x4F10,0xA008,0xA004,0xA002,0x7B4F,0x7F5A,0xA002,0x53D1,0x8D30,0xA004,0xA002,0x7AA2,0x7AA1,0xA002,0x7A9E, 0x7A9B,0xA010,0xA008,0xA004,0xA002,0x7A9A,0x7A99,0xA002,0x7A94,0x7A93,0xA004,0xA002,0x7A90,0x7A8F,0xA002,0x7A8E, 0x7A8C,0xA008,0xA004,0xA002,0x7A8B,0x7A8A,0xA002,0x7A89,0x7A87,0xA004,0xA002,0x7A85,0x7A82,0xA002,0x7A7E,0x7A7D, 0xA01F,0xA010,0xA008,0xA004,0xA002,0x7A7C,0x7A7B,0xA002,0x7A75,0x7A73,0xA004,0xA002,0x7A72,0x7A71,0xA002,0x7A6F, 0x7A6E,0xA008,0xA004,0xA002,0x7A6D,0x7A6C,0xA002,0x7A6B,0x7A6A,0xA003,0xA000,0x7A69,0xA002,0x7A68,0x7A67,0xA010, 0xA008,0xA004,0xA002,0x7A66,0x7A65,0xA002,0x7A64,0x7A63,0xA004,0xA002,0x7A62,0x7A61,0xA002,0x7A60,0x7A5F,0xA008, 0xA004,0xA002,0x7A5E,0x7A5D,0xA002,0x7A5C,0x7A5B,0xA004,0xA002,0x7A5A,0x7A59,0xA002,0x7A58,0x7A56,0xA05C,0xA03E, 0xA01E,0xA00E,0xA006,0xA002,0x7A55,0xA002,0x7A54,0x7A53,0xA004,0xA002,0x7A52,0x7A50,0xA002,0x7A4F,0x7A4E,0xA008, 0xA004,0xA002,0x7A4D,0x7A4C,0xA002,0x7A4B,0x7A4A,0xA004,0xA002,0x7A49,0x7A48,0xA002,0x7A47,0x7A45,0xA010,0xA008, 0xA004,0xA002,0x7A44,0x7A43,0xA002,0x7A42,0x7A41,0xA004,0xA002,0x7A40,0x7A3E,0xA002,0x7A3A,0x7A38,0xA008,0xA004, 0xA002,0x7A36,0x7A35,0xA002,0x7A34,0x7A32,0xA004,0xA002,0x7A31,0x7A30,0xA002,0x7A2F,0x7A2E,0xA000,0xA010,0xA008, 0xA004,0xA002,0x7A2D,0x7A2C,0xA002,0x7A2B,0x7A2A,0xA004,0xA002,0x7A29,0x7A28,0xA002,0x7A27,0x7A26,0xA008,0xA004, 0xA002,0x7A25,0x7A24,0xA002,0x7A22,0x7A21,0xA000,0xA002,0x7A1F,0x7A1D,0xA001,0xA006,0xA001,0xA001,0xA001,0xA001, 0x4E8C,0xA010,0xA008,0xA004,0xA002,0x6D31,0x9975,0xA002,0x5C14,0x8033,0xA004,0xA002,0x513F,0x800C,0xA002,0x6069, 0x997F,0xA008,0xA004,0xA002,0x9102,0x904F,0xA002,0x627C,0x5384,0xA004,0xA002,0x6076,0x5A25,0xA002,0x8BB9,0x989D, 0xA5FB,0xA2FD,0xA17E,0xA0FB,0xA07E,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x4FC4,0xA002,0x9E45,0x5CE8,0xA004,0xA002, 0x86FE,0x5815,0xA002,0x60F0,0x5241,0xA008,0xA004,0xA002,0x8235,0x8DFA,0xA002,0x6735,0x8EB2,0xA004,0xA002,0x579B, 0x593A,0xA002,0x591A,0x54C6,0xA010,0xA008,0xA004,0xA002,0x6387,0x9041,0xA002,0x76FE,0x949D,0xA004,0xA002,0x56E4, 0x987F,0xA002,0x6566,0x8E72,0xA008,0xA004,0xA002,0x5428,0x58A9,0xA002,0x5BF9,0x961F,0xA004,0xA002,0x5151,0x5806, 0xA002,0x7F0E,0x65AD,0xA020,0xA010,0xA008,0xA004,0xA002,0x6BB5,0x953B,0xA002,0x77ED,0x7AEF,0xA004,0xA002,0x5992, 0x6E21,0xA002,0x5EA6,0x809A,0xA008,0xA004,0xA002,0x9540,0x675C,0xA002,0x8D4C,0x7779,0xA004,0xA002,0x5835,0x8BFB, 0xA002,0x72EC,0x728A,0xA010,0xA008,0xA004,0xA002,0x6BD2,0x7763,0xA002,0x90FD,0x75D8,0xA004,0xA002,0x9017,0x8C46, 0xA002,0x9661,0x6597,0xA008,0xA004,0xA002,0x6296,0x515C,0xA002,0x6D1E,0x51BB,0xA004,0xA002,0x606B,0x4F97,0xA002, 0x680B,0x52A8,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x61C2,0xA002,0x8463,0x51AC,0xA004,0xA002,0x4E1C,0x4E22,0xA002, 0x8BA2,0x5B9A,0xA008,0xA004,0xA002,0x952D,0x9F0E,0xA002,0x9876,0x9489,0xA004,0xA002,0x53EE,0x76EF,0xA002,0x4E01, 0x7A1C,0xA010,0xA008,0xA004,0xA002,0x7A1B,0x7A19,0xA002,0x7A18,0x7A16,0xA004,0xA002,0x7A15,0x7A13,0xA002,0x7A12, 0x7A11,0xA008,0xA004,0xA002,0x7A10,0x7A0F,0xA002,0x7A0C,0x7A0A,0xA004,0xA002,0x7A09,0x7A08,0xA002,0x7A07,0x7A05, 0xA020,0xA010,0xA008,0xA004,0xA002,0x7A04,0x7A01,0xA002,0x79FF,0x79FE,0xA004,0xA002,0x79FC,0x79FA,0xA002,0x79F9, 0x79F7,0xA008,0xA004,0xA002,0x79F6,0x79F5,0xA002,0x79F4,0x79F3,0xA004,0xA002,0x79F2,0x79F1,0xA002,0x79EE,0x79EC, 0xA00F,0xA007,0xA003,0xA001,0x79EA,0xA002,0x79E8,0x79E5,0xA004,0xA002,0x79E2,0x79E1,0xA002,0x79E0,0x79DE,0xA008, 0xA004,0xA002,0x79DD,0x79DC,0xA002,0x79DB,0x79DA,0xA004,0xA002,0x79D9,0x79D7,0xA002,0x79D6,0x79D4,0xA064,0xA03E, 0xA01E,0xA00E,0xA006,0xA002,0x79D3,0xA002,0x79D0,0x79CF,0xA004,0xA002,0x79CE,0x79CC,0xA002,0x79CA,0x79C8,0xA008, 0xA004,0xA002,0x79C7,0x79C5,0xA002,0x79C4,0x79C2,0xA004,0xA002,0x79BF,0x79BC,0xA002,0x79B8,0x79B7,0xA010,0xA008, 0xA004,0xA002,0x79B6,0x79B5,0xA002,0x79B4,0x79B2,0xA004,0xA002,0x79B1,0x79B0,0xA002,0x79AF,0x79AE,0xA008,0xA004, 0xA002,0x79AD,0x79AC,0xA002,0x79AB,0x79AA,0xA004,0xA002,0x79A9,0x79A8,0xA002,0x79A6,0x79A5,0xA020,0xA010,0xA008, 0xA004,0xA002,0x79A4,0x79A3,0xA002,0x79A2,0x79A1,0xA004,0xA002,0x79A0,0x799F,0xA002,0x799E,0x799D,0xA008,0xA004, 0xA002,0x799C,0x799B,0xA002,0x7999,0x7998,0xA004,0xA002,0x7997,0x7996,0xA002,0x7995,0x7994,0xA000,0xA000,0xA000, 0xA000,0x7993,0xA001,0xA001,0xA00D,0xA005,0xA001,0xA002,0x53E0,0x8C0D,0xA004,0xA002,0x8FED,0x8776,0xA002,0x789F, 0x7239,0xA008,0xA004,0xA002,0x8DCC,0x8C03,0xA002,0x9493,0x540A,0xA004,0xA002,0x6389,0x5201,0xA002,0x51CB,0x96D5, 0xA0FD,0xA07E,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x53FC,0xA002,0x7889,0x6BBF,0xA004,0xA002,0x6DC0,0x5960,0xA002, 0x60E6,0x5E97,0xA008,0xA004,0xA002,0x7538,0x4F43,0xA002,0x7535,0x57AB,0xA004,0xA002,0x975B,0x5178,0xA002,0x70B9, 0x7898,0xA010,0xA008,0xA004,0xA002,0x6EC7,0x6382,0xA002,0x98A0,0x7F14,0xA004,0xA002,0x9012,0x5F1F,0xA002,0x5E1D, 0x7B2C,0xA008,0xA004,0xA002,0x8482,0x5730,0xA002,0x5E95,0x62B5,0xA004,0xA002,0x5AE1,0x7FDF,0xA002,0x6DA4,0x72C4, 0xA020,0xA010,0xA008,0xA004,0xA002,0x7B1B,0x654C,0xA002,0x8FEA,0x6EF4,0xA004,0xA002,0x4F4E,0x5824,0xA002,0x9093, 0x51F3,0xA008,0xA004,0xA002,0x77AA,0x7B49,0xA002,0x767B,0x706F,0xA004,0xA002,0x8E6C,0x7684,0xA002,0x5F97,0x5FB7, 0xA010,0xA008,0xA004,0xA002,0x76D7,0x9053,0xA002,0x60BC,0x7A3B,0xA004,0xA002,0x5230,0x5BFC,0xA002,0x7977,0x5C9B, 0xA008,0xA004,0xA002,0x5012,0x8E48,0xA002,0x6363,0x5200,0xA004,0xA002,0x6863,0x8361,0xA002,0x515A,0x6321,0xA040, 0xA020,0xA010,0xA008,0xA004,0xA002,0x5F53,0x86CB,0xA002,0x5F39,0x8BDE,0xA004,0xA002,0x6DE1,0x60EE,0xA002,0x4F46, 0x6C2E,0xA008,0xA004,0xA002,0x65E6,0x80C6,0xA002,0x63B8,0x90F8,0xA004,0xA002,0x5355,0x4E39,0xA002,0x62C5,0x803D, 0xA010,0xA008,0xA004,0xA002,0x6020,0x7992,0xA002,0x7991,0x7990,0xA004,0xA002,0x798E,0x798D,0xA002,0x798C,0x798B, 0xA008,0xA004,0xA002,0x7989,0x7988,0xA002,0x7987,0x7986,0xA004,0xA002,0x7983,0x7982,0xA002,0x797F,0x797E,0xA020, 0xA010,0xA008,0xA004,0xA002,0x797D,0x797C,0xA002,0x797B,0x7979,0xA004,0xA002,0x7976,0x7975,0xA002,0x7974,0x7973, 0xA008,0xA004,0xA002,0x7972,0x7971,0xA002,0x7970,0x796E,0xA004,0xA002,0x796C,0x796B,0xA002,0x796A,0x7969,0xA00F, 0xA007,0xA004,0xA002,0x7966,0x7964,0xA001,0x7963,0xA004,0xA002,0x7961,0x7959,0xA002,0x7958,0x7955,0xA008,0xA004, 0xA002,0x7954,0x7952,0xA002,0x7951,0x7950,0xA004,0xA002,0x794F,0x794E,0xA002,0x794D,0x794C,0xA067,0xA03E,0xA01E, 0xA00E,0xA006,0xA002,0x794B,0xA002,0x794A,0x7947,0xA004,0xA002,0x7945,0x7944,0xA002,0x7943,0x7942,0xA008,0xA004, 0xA002,0x793F,0x793D,0xA002,0x7939,0x7938,0xA004,0xA002,0x7937,0x7936,0xA002,0x7935,0x7933,0xA010,0xA008,0xA004, 0xA002,0x7932,0x7931,0xA002,0x7930,0x792F,0xA004,0xA002,0x792E,0x792D,0xA002,0x792C,0x792B,0xA008,0xA004,0xA002, 0x792A,0x7929,0xA002,0x7928,0x7927,0xA004,0xA002,0x7926,0x7925,0xA002,0x7923,0x7922,0xA020,0xA010,0xA008,0xA004, 0xA002,0x7921,0x7920,0xA002,0x791F,0x791D,0xA004,0xA002,0x791C,0x791B,0xA002,0x791A,0x7919,0xA008,0xA004,0xA002, 0x7918,0x7917,0xA002,0x7916,0x7915,0xA004,0xA002,0x7914,0x7912,0xA002,0x7911,0x7910,0xA000,0xA000,0xA004,0xA002, 0x790F,0x790E,0xA000,0x790D,0xA001,0xA001,0xA009,0xA001,0xA004,0xA002,0x902E,0x5F85,0xA002,0x888B,0x8D37,0xA008, 0xA004,0xA002,0x4EE3,0x6B86,0xA002,0x5E26,0x6234,0xA004,0xA002,0x50A3,0x6B79,0xA002,0x5446,0x5927,0xA180,0xA0FD, 0xA07E,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x6253,0xA002,0x7629,0x7B54,0xA004,0xA002,0x8FBE,0x642D,0xA002,0x9519, 0x632B,0xA008,0xA004,0xA002,0x63AA,0x6413,0xA002,0x64AE,0x78CB,0xA004,0xA002,0x5BF8,0x5B58,0xA002,0x6751,0x7FE0, 0xA010,0xA008,0xA004,0xA002,0x6DEC,0x7CB9,0xA002,0x7601,0x8106,0xA004,0xA002,0x50AC,0x5D14,0xA002,0x6467,0x7A9C, 0xA008,0xA004,0xA002,0x7BE1,0x8E7F,0xA002,0x4FC3,0x7C07,0xA004,0xA002,0x918B,0x7C97,0xA002,0x51D1,0x4E1B,0xA020, 0xA010,0xA008,0xA004,0xA002,0x4ECE,0x5306,0xA002,0x56F1,0x8471,0xA004,0xA002,0x806A,0x6B21,0xA002,0x8D50,0x523A, 0xA008,0xA004,0xA002,0x6B64,0x8BCD,0xA002,0x74F7,0x6148,0xA004,0xA002,0x8F9E,0x96CC,0xA002,0x78C1,0x8328,0xA010, 0xA008,0xA004,0xA002,0x75B5,0x7EF0,0xA002,0x6233,0x8822,0xA004,0xA002,0x7EAF,0x6DF3,0xA002,0x5507,0x9187,0xA008, 0xA004,0xA002,0x693F,0x6625,0xA002,0x5782,0x9524,0xA004,0xA002,0x6376,0x708A,0xA002,0x5439,0x521B,0xA040,0xA020, 0xA010,0xA008,0xA004,0xA002,0x95EF,0x5E8A,0xA002,0x5E62,0x7A97,0xA004,0xA002,0x75AE,0x4E32,0xA002,0x5598,0x8239, 0xA008,0xA004,0xA002,0x4F20,0x693D,0xA002,0x7A7F,0x5DDD,0xA004,0xA002,0x63E3,0x5904,0xA002,0x89E6,0x6410,0xA010, 0xA008,0xA004,0xA002,0x77D7,0x50A8,0xA002,0x7840,0x790C,0xA004,0xA002,0x790B,0x790A,0xA002,0x7909,0x7908,0xA008, 0xA004,0xA002,0x7907,0x7906,0xA002,0x7904,0x7903,0xA004,0xA002,0x7902,0x7900,0xA002,0x78FF,0x78FE,0xA020,0xA010, 0xA008,0xA004,0xA002,0x78FD,0x78FC,0xA002,0x78FB,0x78F9,0xA004,0xA002,0x78F8,0x78F6,0xA002,0x78F5,0x78F3,0xA008, 0xA004,0xA002,0x78F1,0x78F0,0xA002,0x78EF,0x78EE,0xA004,0xA002,0x78ED,0x78EB,0xA002,0x78EA,0x78E9,0xA00F,0xA008, 0xA004,0xA002,0x78E7,0x78E6,0xA002,0x78E5,0x78E4,0xA003,0xA001,0x78E3,0xA002,0x78E2,0x78E1,0xA008,0xA004,0xA002, 0x78E0,0x78DF,0xA002,0x78DE,0x78DD,0xA004,0xA002,0x78DC,0x78DB,0xA002,0x78DA,0x78D8,0xA06B,0xA03E,0xA01E,0xA00E, 0xA006,0xA002,0x78D7,0xA002,0x78D6,0x78D3,0xA004,0xA002,0x78D2,0x78D1,0xA002,0x78CF,0x78CE,0xA008,0xA004,0xA002, 0x78CD,0x78CC,0xA002,0x78C8,0x78C7,0xA004,0xA002,0x78C6,0x78C4,0xA002,0x78C3,0x78C2,0xA010,0xA008,0xA004,0xA002, 0x78C0,0x78BF,0xA002,0x78BD,0x78BC,0xA004,0xA002,0x78BB,0x78BA,0xA002,0x78B8,0x78B7,0xA008,0xA004,0xA002,0x78B6, 0x78B5,0xA002,0x78AF,0x78AE,0xA004,0xA002,0x78AD,0x78AC,0xA002,0x78AB,0x78AA,0xA020,0xA010,0xA008,0xA004,0xA002, 0x78A9,0x78A8,0xA002,0x78A6,0x78A4,0xA004,0xA002,0x78A2,0x78A0,0xA002,0x789E,0x789D,0xA008,0xA004,0xA002,0x7899, 0x7896,0xA002,0x7895,0x7894,0xA004,0xA002,0x7892,0x7890,0xA002,0x788F,0x788B,0xA000,0xA008,0xA004,0xA002,0x788A, 0x7888,0xA002,0x7886,0x7885,0xA000,0xA000,0x7884,0xA001,0xA001,0xA006,0xA001,0xA001,0xA002,0x695A,0x9664,0xA008, 0xA004,0xA002,0x6EC1,0x96CF,0xA002,0x9504,0x8E87,0xA004,0xA002,0x53A8,0x6A71,0xA002,0x51FA,0x521D,0xA0FD,0xA07E, 0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x81ED,0xA002,0x4E11,0x7785,0xA004,0xA002,0x7EF8,0x4EC7,0xA002,0x7B79,0x6101, 0xA008,0xA004,0xA002,0x7A20,0x8E0C,0xA002,0x7574,0x916C,0xA004,0xA002,0x62BD,0x5BA0,0xA002,0x5D07,0x866B,0xA010, 0xA008,0xA004,0xA002,0x51B2,0x5145,0xA002,0x70BD,0x65A5,0xA004,0xA002,0x7FC5,0x8D64,0xA002,0x5C3A,0x4F88,0xA008, 0xA004,0xA002,0x9F7F,0x803B,0xA002,0x9A70,0x5F1B,0xA004,0xA002,0x8FDF,0x6C60,0xA002,0x5319,0x6301,0xA020,0xA010, 0xA008,0xA004,0xA002,0x75F4,0x5403,0xA002,0x79E4,0x9A8B,0xA004,0xA002,0x901E,0x627F,0xA002,0x8BDA,0x6F84,0xA008, 0xA004,0xA002,0x60E9,0x7A0B,0xA002,0x4E58,0x5448,0xA004,0xA002,0x6210,0x6A59,0xA002,0x57CE,0x79F0,0xA010,0xA008, 0xA004,0xA002,0x6491,0x886C,0xA002,0x8D81,0x9648,0xA004,0xA002,0x6C89,0x5FF1,0xA002,0x6668,0x5C18,0xA008,0xA004, 0xA002,0x8FB0,0x81E3,0xA002,0x90F4,0x6F88,0xA004,0xA002,0x5F7B,0x63A3,0xA002,0x64A4,0x626F,0xA040,0xA020,0xA010, 0xA008,0xA004,0xA002,0x8F66,0x7092,0xA002,0x5435,0x5DE2,0xA004,0xA002,0x6F6E,0x5632,0xA002,0x671D,0x949E,0xA008, 0xA004,0xA002,0x6284,0x8D85,0xA002,0x5021,0x5531,0xA004,0xA002,0x7545,0x655E,0xA002,0x5382,0x80A0,0xA010,0xA008, 0xA004,0xA002,0x507F,0x957F,0xA002,0x5E38,0x5C1D,0xA004,0xA002,0x573A,0x7883,0xA002,0x7882,0x7881,0xA008,0xA004, 0xA002,0x7880,0x787F,0xA002,0x787E,0x787D,0xA004,0xA002,0x787B,0x787A,0xA002,0x7879,0x7878,0xA020,0xA010,0xA008, 0xA004,0xA002,0x7876,0x7875,0xA002,0x7874,0x7873,0xA004,0xA002,0x7872,0x7871,0xA002,0x7870,0x786F,0xA008,0xA004, 0xA002,0x7869,0x7868,0xA002,0x7867,0x7866,0xA004,0xA002,0x7865,0x7864,0xA002,0x7863,0x7862,0xA00F,0xA008,0xA004, 0xA002,0x7861,0x7860,0xA002,0x785F,0x785E,0xA004,0xA002,0x785C,0x785B,0xA001,0x785A,0xA008,0xA004,0xA002,0x7859, 0x7858,0xA002,0x7854,0x7853,0xA004,0xA002,0x7851,0x784F,0xA002,0x784D,0x784B,0xA06E,0xA03E,0xA01E,0xA00E,0xA006, 0xA002,0x784A,0xA002,0x7849,0x7848,0xA004,0xA002,0x7846,0x7844,0xA002,0x7843,0x7842,0xA008,0xA004,0xA002,0x7841, 0x783F,0xA002,0x783D,0x7836,0xA004,0xA002,0x7835,0x7833,0xA002,0x7832,0x7831,0xA010,0xA008,0xA004,0xA002,0x782F, 0x782E,0xA002,0x782B,0x782A,0xA004,0xA002,0x7828,0x7824,0xA002,0x7822,0x7821,0xA008,0xA004,0xA002,0x7820,0x781E, 0xA002,0x781B,0x7819,0xA004,0xA002,0x7815,0x7813,0xA002,0x7810,0x780F,0xA020,0xA010,0xA008,0xA004,0xA002,0x780E, 0x780B,0xA002,0x780A,0x7808,0xA004,0xA002,0x7807,0x7806,0xA002,0x7805,0x7804,0xA008,0xA004,0xA002,0x7803,0x77FC, 0xA002,0x77FB,0x77FA,0xA004,0xA002,0x77F9,0x77F7,0xA002,0x77F5,0x77F4,0xA000,0xA008,0xA004,0xA002,0x77F2,0x77F1, 0xA002,0x77F0,0x77EF,0xA004,0xA002,0x77EA,0x77E8,0xA000,0x77E6,0xA001,0xA001,0xA001,0xA008,0xA004,0xA002,0x7316, 0x660C,0xA002,0x98A4,0x9610,0xA004,0xA002,0x4EA7,0x94F2,0xA002,0x7F20,0x8C17,0xA2FF,0xA180,0xA0FD,0xA07E,0xA03E, 0xA01E,0xA00E,0xA006,0xA002,0x998B,0xA002,0x8749,0x63BA,0xA004,0xA002,0x6400,0x8C7A,0xA002,0x67F4,0x62C6,0xA008, 0xA004,0xA002,0x8BE7,0x5DEE,0xA002,0x5C94,0x5BDF,0xA004,0xA002,0x643D,0x78B4,0xA002,0x67E5,0x8336,0xA010,0xA008, 0xA004,0xA002,0x832C,0x53C9,0xA002,0x63D2,0x8E6D,0xA004,0xA002,0x5C42,0x6D4B,0xA002,0x518C,0x4FA7,0xA008,0xA004, 0xA002,0x7B56,0x5395,0xA002,0x8349,0x66F9,0xA004,0xA002,0x69FD,0x7CD9,0xA002,0x64CD,0x85CF,0xA020,0xA010,0xA008, 0xA004,0xA002,0x6CA7,0x4ED3,0xA002,0x8231,0x82CD,0xA004,0xA002,0x707F,0x60E8,0xA002,0x60ED,0x6B8B,0xA008,0xA004, 0xA002,0x8695,0x53C2,0xA002,0x9910,0x8521,0xA004,0xA002,0x83DC,0x5F69,0xA002,0x91C7,0x8E29,0xA010,0xA008,0xA004, 0xA002,0x776C,0x8D22,0xA002,0x624D,0x6750,0xA004,0xA002,0x88C1,0x731C,0xA002,0x64E6,0x6016,0xA008,0xA004,0xA002, 0x90E8,0x7C3F,0xA002,0x6B65,0x5E03,0xA004,0xA002,0x4E0D,0x57E0,0xA002,0x8865,0x54FA,0xA040,0xA020,0xA010,0xA008, 0xA004,0xA002,0x535C,0x6355,0xA002,0x9A73,0x6CCA,0xA004,0xA002,0x6E24,0x818A,0xA002,0x8116,0x8236,0xA008,0xA004, 0xA002,0x5E1B,0x4F2F,0xA002,0x7B94,0x94C2,0xA004,0xA002,0x640F,0x52C3,0xA002,0x535A,0x6CE2,0xA010,0xA008,0xA004, 0xA002,0x94B5,0x62E8,0xA002,0x64AD,0x83E0,0xA004,0xA002,0x73BB,0x5E76,0xA002,0x75C5,0x77E4,0xA008,0xA004,0xA002, 0x77E1,0x77E0,0xA002,0x77DF,0x77DE,0xA004,0xA002,0x77DD,0x77DA,0xA002,0x77D9,0x77D8,0xA020,0xA010,0xA008,0xA004, 0xA002,0x77D6,0x77D5,0xA002,0x77D4,0x77D3,0xA004,0xA002,0x77D2,0x77D1,0xA002,0x77D0,0x77CF,0xA008,0xA004,0xA002, 0x77CE,0x77CC,0xA002,0x77CB,0x77CA,0xA004,0xA002,0x77C9,0x77C8,0xA002,0x77C7,0x77C6,0xA010,0xA008,0xA004,0xA002, 0x77C5,0x77C4,0xA002,0x77C3,0x77C2,0xA004,0xA002,0x77C1,0x77C0,0xA002,0x77BE,0x77BC,0xA007,0xA003,0xA001,0x77BA, 0xA002,0x77B9,0x77B8,0xA004,0xA002,0x77B7,0x77B6,0xA002,0x77B4,0x77B2,0xA073,0xA03E,0xA01E,0xA00E,0xA006,0xA002, 0x77B1,0xA002,0x77AF,0x77AE,0xA004,0xA002,0x77AD,0x77AB,0xA002,0x77A8,0x77A6,0xA008,0xA004,0xA002,0x77A4,0x77A3, 0xA002,0x77A1,0x779E,0xA004,0xA002,0x779D,0x779C,0xA002,0x779B,0x779A,0xA010,0xA008,0xA004,0xA002,0x7799,0x7798, 0xA002,0x7797,0x7796,0xA004,0xA002,0x7795,0x7794,0xA002,0x7793,0x7790,0xA008,0xA004,0xA002,0x778F,0x778B,0xA002, 0x778A,0x7789,0xA004,0xA002,0x7788,0x7787,0xA002,0x7786,0x7783,0xA020,0xA010,0xA008,0xA004,0xA002,0x7782,0x7781, 0xA002,0x777C,0x777B,0xA004,0xA002,0x777A,0x7778,0xA002,0x7777,0x7776,0xA008,0xA004,0xA002,0x7775,0x7774,0xA002, 0x7773,0x7772,0xA004,0xA002,0x7771,0x7770,0xA002,0x776F,0x776E,0xA010,0xA008,0xA004,0xA002,0x776D,0x776A,0xA002, 0x7769,0x7767,0xA004,0xA002,0x7764,0x7760,0xA002,0x775F,0x775E,0xA000,0xA000,0xA000,0x775D,0xA001,0xA001,0xA001, 0xA005,0xA001,0xA002,0x70B3,0x997C,0xA004,0xA002,0x79C9,0x4E19,0xA002,0x67C4,0x51B0,0xA0FD,0xA07E,0xA03E,0xA01E, 0xA00E,0xA006,0xA002,0x5175,0xA002,0x6448,0x5BBE,0xA004,0xA002,0x6EE8,0x6FD2,0xA002,0x658C,0x5F6C,0xA008,0xA004, 0xA002,0x762A,0x522B,0xA002,0x618B,0x9CD6,0xA004,0xA002,0x8868,0x8198,0xA002,0x5F6A,0x6807,0xA010,0xA008,0xA004, 0xA002,0x904D,0x8FAB,0xA002,0x8FA9,0x8FA8,0xA004,0xA002,0x535E,0x53D8,0xA002,0x4FBF,0x6241,0xA008,0xA004,0xA002, 0x8D2C,0x7F16,0xA002,0x8FB9,0x97AD,0xA004,0xA002,0x965B,0x907F,0xA002,0x81C2,0x58C1,0xA020,0xA010,0xA008,0xA004, 0xA002,0x8F9F,0x5FC5,0xA002,0x5F0A,0x655D,0xA004,0xA002,0x95ED,0x75F9,0xA002,0x5E87,0x5E01,0xA008,0xA004,0xA002, 0x6BD6,0x6BD9,0xA002,0x6BD5,0x853D,0xA004,0xA002,0x84D6,0x78A7,0xA002,0x5F7C,0x7B14,0xA010,0xA008,0xA004,0xA002, 0x9119,0x6BD4,0xA002,0x9F3B,0x903C,0xA004,0xA002,0x8FF8,0x8E66,0xA002,0x6CF5,0x752D,0xA008,0xA004,0xA002,0x7EF7, 0x5D29,0xA002,0x7B28,0x672C,0xA004,0xA002,0x82EF,0x5954,0xA002,0x88AB,0x7119,0xA040,0xA020,0xA010,0xA008,0xA004, 0xA002,0x60EB,0x5907,0xA002,0x72C8,0x500D,0xA004,0xA002,0x94A1,0x8D1D,0xA002,0x80CC,0x8F88,0xA008,0xA004,0xA002, 0x5317,0x5351,0xA002,0x60B2,0x7891,0xA004,0xA002,0x676F,0x7206,0xA002,0x9C8D,0x8C79,0xA010,0xA008,0xA004,0xA002, 0x66B4,0x62A5,0xA002,0x62B1,0x5B9D,0xA004,0xA002,0x9971,0x5821,0xA002,0x4FDD,0x96F9,0xA008,0xA004,0xA002,0x8584, 0x775C,0xA002,0x7759,0x7758,0xA004,0xA002,0x7757,0x7756,0xA002,0x7755,0x7754,0xA020,0xA010,0xA008,0xA004,0xA002, 0x7753,0x7752,0xA002,0x774F,0x774E,0xA004,0xA002,0x774D,0x774C,0xA002,0x774B,0x774A,0xA008,0xA004,0xA002,0x7749, 0x7748,0xA002,0x7746,0x7745,0xA004,0xA002,0x7744,0x7742,0xA002,0x773F,0x773E,0xA010,0xA008,0xA004,0xA002,0x773D, 0x773B,0xA002,0x7739,0x7734,0xA004,0xA002,0x7733,0x7732,0xA002,0x7731,0x7730,0xA007,0xA004,0xA002,0x772E,0x772C, 0xA001,0x772B,0xA004,0xA002,0x772A,0x7727,0xA002,0x7725,0x7724,0xA076,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x7723, 0xA002,0x7721,0x771E,0xA004,0xA002,0x771D,0x771C,0xA002,0x771B,0x7718,0xA008,0xA004,0xA002,0x7717,0x7716,0xA002, 0x7715,0x7714,0xA004,0xA002,0x7713,0x7712,0xA002,0x7711,0x7710,0xA010,0xA008,0xA004,0xA002,0x770F,0x770E,0xA002, 0x770C,0x770A,0xA004,0xA002,0x7706,0x7705,0xA002,0x7703,0x7702,0xA008,0xA004,0xA002,0x7700,0x76FF,0xA002,0x76FD, 0x76FB,0xA004,0xA002,0x76FA,0x76F7,0xA002,0x76F6,0x76F5,0xA020,0xA010,0xA008,0xA004,0xA002,0x76F3,0x76F0,0xA002, 0x76ED,0x76EC,0xA004,0xA002,0x76EB,0x76EA,0xA002,0x76E9,0x76E8,0xA008,0xA004,0xA002,0x76E7,0x76E6,0xA002,0x76E4, 0x76E3,0xA004,0xA002,0x76E2,0x76E1,0xA002,0x76E0,0x76DE,0xA010,0xA008,0xA004,0xA002,0x76DD,0x76DC,0xA002,0x76DA, 0x76D9,0xA004,0xA002,0x76D5,0x76D3,0xA002,0x76CC,0x76CB,0xA000,0xA004,0xA002,0x76C9,0x76C7,0xA000,0x76C4,0xA001, 0xA001,0xA001,0xA001,0xA004,0xA002,0x5265,0x8912,0xA002,0x5305,0x80DE,0xA178,0xA0FD,0xA07E,0xA03E,0xA01E,0xA00E, 0xA006,0xA002,0x82DE,0xA002,0x8C24,0x508D,0xA004,0xA002,0x9551,0x868C,0xA002,0x78C5,0x68D2,0xA008,0xA004,0xA002, 0x7ED1,0x8180,0xA002,0x699C,0x6886,0xA004,0xA002,0x5E2E,0x90A6,0xA002,0x7ECA,0x529E,0xA010,0xA008,0xA004,0xA002, 0x534A,0x74E3,0xA002,0x4F34,0x62CC,0xA004,0xA002,0x626E,0x7248,0xA002,0x677F,0x9881,0xA008,0xA004,0xA002,0x822C, 0x6273,0xA002,0x642C,0x73ED,0xA004,0xA002,0x6591,0x7A17,0xA002,0x62DC,0x8D25,0xA020,0xA010,0xA008,0xA004,0xA002, 0x4F70,0x6446,0xA002,0x767E,0x67CF,0xA004,0xA002,0x767D,0x7238,0xA002,0x7F62,0x9738,0xA008,0xA004,0xA002,0x575D, 0x8019,0xA002,0x628A,0x9776,0xA004,0xA002,0x8DCB,0x62D4,0xA002,0x5DF4,0x75A4,0xA010,0xA008,0xA004,0xA002,0x516B, 0x7B06,0xA002,0x5427,0x53ED,0xA004,0xA002,0x6252,0x634C,0xA002,0x82AD,0x6FB3,0xA008,0xA004,0xA002,0x61CA,0x5965, 0xA002,0x50B2,0x8884,0xA004,0xA002,0x7FF1,0x71AC,0xA002,0x6556,0x51F9,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002, 0x76CE,0x6602,0xA002,0x80AE,0x6848,0xA004,0xA002,0x80FA,0x5CB8,0xA002,0x6697,0x6309,0xA008,0xA004,0xA002,0x4FFA, 0x5B89,0xA002,0x6C28,0x978D,0xA004,0xA002,0x9698,0x7231,0xA002,0x788D,0x827E,0xA010,0xA008,0xA004,0xA002,0x77EE, 0x853C,0xA002,0x764C,0x7691,0xA004,0xA002,0x54C0,0x5509,0xA002,0x54CE,0x6328,0xA008,0xA004,0xA002,0x57C3,0x963F, 0xA002,0x554A,0x76C3,0xA004,0xA002,0x76C1,0x76C0,0xA002,0x76BE,0x76BD,0xA020,0xA010,0xA008,0xA004,0xA002,0x76BC, 0x76BB,0xA002,0x76BA,0x76B9,0xA004,0xA002,0x76B8,0x76B7,0xA002,0x76B6,0x76B5,0xA008,0xA004,0xA002,0x76B3,0x76B0, 0xA002,0x76AF,0x76AD,0xA004,0xA002,0x76AC,0x76AB,0xA002,0x76AA,0x76A9,0xA010,0xA008,0xA004,0xA002,0x76A8,0x76A7, 0xA002,0x76A6,0x76A5,0xA004,0xA002,0x76A3,0x76A2,0xA002,0x76A1,0x76A0,0xA008,0xA004,0xA002,0x769F,0x769E,0xA002, 0x769D,0x769C,0xA003,0xA001,0x769B,0xA002,0x769A,0x7698,0xA000,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x7697,0xA002, 0x7695,0x7694,0xA004,0xA002,0x7692,0x7690,0xA002,0x768F,0x768D,0xA008,0xA004,0xA002,0x768C,0x768A,0xA002,0x7689, 0x7685,0xA004,0xA002,0x7683,0x7681,0xA002,0x7680,0x767F,0xA010,0xA008,0xA004,0xA002,0x767C,0x767A,0xA002,0x7679, 0x7677,0xA004,0xA002,0x7676,0x7675,0xA002,0x7674,0x7673,0xA008,0xA004,0xA002,0x7672,0x7671,0xA002,0x7670,0x766E, 0xA004,0xA002,0x766D,0x766C,0xA002,0x766A,0x7669,0xA020,0xA010,0xA008,0xA004,0xA002,0x7668,0x7667,0xA002,0x7666, 0x7665,0xA004,0xA002,0x7664,0x7662,0xA002,0x7661,0x7660,0xA008,0xA004,0xA002,0x765F,0x765D,0xA002,0x765B,0x765A, 0xA004,0xA002,0x7659,0x7658,0xA002,0x7657,0x7655,0xA010,0xA008,0xA004,0xA002,0x7653,0x7652,0xA002,0x7651,0x7650, 0xA004,0xA002,0x764F,0x764E,0xA002,0x764B,0x764A,0xA008,0xA004,0xA002,0x7649,0x7648,0xA002,0x7647,0x7646,0xA000, 0xA000,0x7645,0xA04A,0xA001,0xA00A,0xA001,0xA001,0xA001,0xA003,0xA001,0x7644,0xA002,0x7642,0x7641,0xA020,0xA010, 0xA008,0xA004,0xA002,0x763D,0x763B,0xA002,0x763A,0x7639,0xA004,0xA002,0x7637,0x7636,0xA002,0x7632,0x7631,0xA008, 0xA004,0xA002,0x762F,0x762E,0xA002,0x762C,0x7628,0xA004,0xA002,0x7627,0x7623,0xA002,0x7621,0x761E,0xA010,0xA008, 0xA004,0xA002,0x761D,0x761C,0xA002,0x761A,0x7616,0xA004,0xA002,0x7614,0x7613,0xA002,0x7612,0x7611,0xA008,0xA004, 0xA002,0x760F,0x760E,0xA002,0x760D,0x760B,0xA004,0xA002,0x7609,0x7608,0xA001,0x7607,0xA000,0xA03E,0xA01E,0xA00E, 0xA006,0xA002,0x7606,0xA002,0x7604,0x7602,0xA004,0xA002,0x75FE,0x75FD,0xA002,0x75FB,0x75FA,0xA008,0xA004,0xA002, 0x75F8,0x75F7,0xA002,0x75F6,0x75F5,0xA004,0xA002,0x75F3,0x75F2,0xA002,0x75EF,0x75EE,0xA010,0xA008,0xA004,0xA002, 0x75ED,0x75EC,0xA002,0x75E9,0x75E5,0xA004,0xA002,0x75E1,0x75E0,0xA002,0x75DF,0x75DD,0xA008,0xA004,0xA002,0x75DC, 0x75DA,0xA002,0x75D9,0x75D7,0xA004,0xA002,0x75D3,0x75D1,0xA002,0x75D0,0x75CF,0xA020,0xA010,0xA008,0xA004,0xA002, 0x75CE,0x75CC,0xA002,0x75CB,0x75C6,0xA004,0xA002,0x75C1,0x75C0,0xA002,0x75BF,0x75BB,0xA008,0xA004,0xA002,0x75BA, 0x75B7,0xA002,0x75B6,0x75AD,0xA004,0xA002,0x75AA,0x75A9,0xA002,0x75A8,0x75A7,0xA010,0xA008,0xA004,0xA002,0x75A6, 0x75A2,0xA002,0x759E,0x759C,0xA004,0xA002,0x759B,0x7598,0xA002,0x7595,0x7593,0xA008,0xA004,0xA002,0x7590,0x758E, 0xA002,0x758D,0x758C,0xA004,0xA002,0x758A,0x7589,0xA000,0x7588,0xA6E8,0xA320,0xA190,0xA0C8,0xA042,0xA001,0xA001, 0xA020,0xA010,0xA008,0xA004,0xA002,0x7587,0x7585,0xA002,0x7584,0x7582,0xA004,0xA002,0x7581,0x7580,0xA002,0x757E, 0x757D,0xA008,0xA004,0xA002,0x757C,0x757B,0xA002,0x757A,0x7577,0xA004,0xA002,0x7576,0x7575,0xA002,0x7573,0x7571, 0xA010,0xA008,0xA004,0xA002,0x7570,0x756F,0xA002,0x756E,0x756D,0xA004,0xA002,0x756C,0x756B,0xA002,0x7569,0x7568, 0xA008,0xA004,0xA002,0x7567,0x7564,0xA002,0x7563,0x7562,0xA004,0xA002,0x7561,0x7560,0xA002,0x755F,0x755E,0xA07D, 0xA03D,0xA01D,0xA00D,0xA005,0xA002,0x755D,0xA001,0x7558,0xA004,0xA002,0x7557,0x7556,0xA002,0x7555,0x7553,0xA008, 0xA004,0xA002,0x7552,0x7551,0xA002,0x7550,0x754D,0xA004,0xA002,0x754A,0x7549,0xA002,0x7547,0x7546,0xA010,0xA008, 0xA004,0xA002,0x7544,0x7543,0xA002,0x7542,0x7541,0xA004,0xA002,0x753F,0x753D,0xA002,0x753C,0x7539,0xA008,0xA004, 0xA002,0x7536,0x7534,0xA002,0x752E,0x752A,0xA004,0xA002,0x7527,0x7526,0xA002,0x7524,0x7523,0xA020,0xA010,0xA008, 0xA004,0xA002,0x7522,0x7521,0xA002,0x7520,0x751E,0xA004,0xA002,0x751D,0x751B,0xA002,0x7517,0x7516,0xA008,0xA004, 0xA002,0x7515,0x7514,0xA002,0x7512,0x7510,0xA004,0xA002,0x750E,0x750C,0xA002,0x750B,0x750A,0xA010,0xA008,0xA004, 0xA002,0x7509,0x7508,0xA002,0x7507,0x7506,0xA004,0xA002,0x7505,0x7503,0xA002,0x7502,0x7501,0xA008,0xA004,0xA002, 0x7500,0x74FE,0xA002,0x74FD,0x74FC,0xA004,0xA002,0x74FB,0x74FA,0xA002,0x74F9,0x74F8,0xA000,0xA000,0xA000,0xA000, 0xA000,0xA002,0x74F5,0x74F3,0xA03F,0xA001,0xA001,0xA01D,0xA00D,0xA005,0xA001,0xA002,0x74F2,0x74F1,0xA004,0xA002, 0x74F0,0x74ED,0xA002,0x74EC,0x74EB,0xA008,0xA004,0xA002,0x74EA,0x74E9,0xA002,0x74E8,0x74E7,0xA004,0xA002,0x74E5, 0x74E1,0xA002,0x74DF,0x74DD,0xA010,0xA008,0xA004,0xA002,0x74DB,0x74DA,0xA002,0x74D9,0x74D8,0xA004,0xA002,0x74D7, 0x74D6,0xA002,0x74D5,0x74D4,0xA008,0xA004,0xA002,0x74D3,0x74D1,0xA002,0x74D0,0x74CF,0xA004,0xA002,0x74CE,0x74CD, 0xA002,0x74CC,0x74CB,0xA07D,0xA03D,0xA01D,0xA00D,0xA006,0xA002,0x74CA,0xA002,0x74C9,0x74C8,0xA003,0xA001,0x74C7, 0xA002,0x74C6,0x74C5,0xA008,0xA004,0xA002,0x74C4,0x74C3,0xA002,0x74C2,0x74C1,0xA004,0xA002,0x74C0,0x74BF,0xA002, 0x74BE,0x74BD,0xA010,0xA008,0xA004,0xA002,0x74BC,0x74BB,0xA002,0x74B9,0x74B8,0xA004,0xA002,0x74B7,0x74B6,0xA002, 0x74B5,0x74B4,0xA008,0xA004,0xA002,0x74B3,0x74B2,0xA002,0x74B1,0x74B0,0xA004,0xA002,0x74AF,0x74AE,0xA002,0x74AD, 0x74AC,0xA020,0xA010,0xA008,0xA004,0xA002,0x74AB,0x74AA,0xA002,0x74A6,0x74A5,0xA004,0xA002,0x74A4,0x74A3,0xA002, 0x74A2,0x74A1,0xA008,0xA004,0xA002,0x74A0,0x749F,0xA002,0x749D,0x749B,0xA004,0xA002,0x749A,0x7499,0xA002,0x7498, 0x7497,0xA010,0xA008,0xA004,0xA002,0x7496,0x7495,0xA002,0x7494,0x7493,0xA004,0xA002,0x7492,0x7491,0xA002,0x748F, 0x748D,0xA008,0xA004,0xA002,0x748C,0x748A,0xA002,0x7489,0x7488,0xA004,0xA002,0x7486,0x7485,0xA002,0x7484,0x7482, 0xA000,0xA000,0xA000,0xA000,0xA004,0xA002,0x747F,0x747D,0xA002,0x747C,0x747B,0xA0C8,0xA03B,0xA001,0xA001,0xA019, 0xA009,0xA001,0xA004,0xA002,0x747A,0x7479,0xA002,0x7478,0x7475,0xA008,0xA004,0xA002,0x7474,0x7473,0xA002,0x7472, 0x7471,0xA004,0xA002,0x746F,0x746E,0xA002,0x746C,0x746B,0xA010,0xA008,0xA004,0xA002,0x746A,0x7469,0xA002,0x7468, 0x7467,0xA004,0xA002,0x7466,0x7465,0xA002,0x7464,0x7463,0xA008,0xA004,0xA002,0x7462,0x7461,0xA002,0x7460,0x745D, 0xA004,0xA002,0x7458,0x7456,0xA002,0x7454,0x7453,0xA07D,0xA03D,0xA01D,0xA00D,0xA006,0xA002,0x7452,0xA002,0x7451, 0x7450,0xA004,0xA002,0x744F,0x744E,0xA001,0x744D,0xA008,0xA004,0xA002,0x744C,0x744B,0xA002,0x744A,0x7449,0xA004, 0xA002,0x7448,0x7447,0xA002,0x7446,0x7445,0xA010,0xA008,0xA004,0xA002,0x7444,0x7443,0xA002,0x7442,0x7440,0xA004, 0xA002,0x743F,0x743E,0xA002,0x743D,0x743B,0xA008,0xA004,0xA002,0x743A,0x7439,0xA002,0x7438,0x7437,0xA004,0xA002, 0x7432,0x7431,0xA002,0x742F,0x742D,0xA020,0xA010,0xA008,0xA004,0xA002,0x742B,0x7429,0xA002,0x7427,0x7424,0xA004, 0xA002,0x7423,0x7421,0xA002,0x7420,0x741F,0xA008,0xA004,0xA002,0x741E,0x741D,0xA002,0x741C,0x7419,0xA004,0xA002, 0x7418,0x7417,0xA002,0x7416,0x7415,0xA010,0xA008,0xA004,0xA002,0x7414,0x7413,0xA002,0x7412,0x7411,0xA004,0xA002, 0x740E,0x740D,0xA002,0x740C,0x740B,0xA008,0xA004,0xA002,0x7408,0x7407,0xA002,0x7404,0x7402,0xA004,0xA002,0x7401, 0x7400,0xA002,0x73FF,0x73FE,0xA000,0xA000,0xA000,0xA008,0xA004,0xA002,0x73FD,0x73FC,0xA002,0x73FB,0x73FA,0xA000, 0xA002,0x73F9,0x73F8,0xA038,0xA001,0xA001,0xA016,0xA006,0xA001,0xA001,0xA002,0x73F7,0x73F6,0xA008,0xA004,0xA002, 0x73F5,0x73F4,0xA002,0x73F3,0x73F1,0xA004,0xA002,0x73F0,0x73EF,0xA002,0x73EE,0x73EC,0xA010,0xA008,0xA004,0xA002, 0x73EB,0x73EA,0xA002,0x73E8,0x73E6,0xA004,0xA002,0x73E4,0x73E3,0xA002,0x73E2,0x73E1,0xA008,0xA004,0xA002,0x73DF, 0x73DD,0xA002,0x73DC,0x73DB,0xA004,0xA002,0x73DA,0x73D8,0xA002,0x73D7,0x73D6,0xA07D,0xA03D,0xA01D,0xA00E,0xA006, 0xA002,0x73D5,0xA002,0x73D4,0x73D3,0xA004,0xA002,0x73D2,0x73CE,0xA002,0x73CC,0x73CB,0xA007,0xA003,0xA001,0x73C7, 0xA002,0x73C6,0x73C5,0xA004,0xA002,0x73C4,0x73C3,0xA002,0x73C1,0x73BF,0xA010,0xA008,0xA004,0xA002,0x73BE,0x73BD, 0xA002,0x73BC,0x73B9,0xA004,0xA002,0x73B8,0x73B6,0xA002,0x73B5,0x73B4,0xA008,0xA004,0xA002,0x73B1,0x73AD,0xA002, 0x73AC,0x73AA,0xA004,0xA002,0x73A8,0x73A7,0xA002,0x73A6,0x73A5,0xA020,0xA010,0xA008,0xA004,0xA002,0x73A4,0x73A3, 0xA002,0x73A1,0x73A0,0xA004,0xA002,0x739E,0x739D,0xA002,0x739C,0x739A,0xA008,0xA004,0xA002,0x7399,0x7398,0xA002, 0x7397,0x7395,0xA004,0xA002,0x7394,0x7393,0xA002,0x7392,0x7390,0xA010,0xA008,0xA004,0xA002,0x738F,0x738D,0xA002, 0x738C,0x738A,0xA004,0xA002,0x7388,0x7386,0xA002,0x7385,0x7383,0xA008,0xA004,0xA002,0x7382,0x7381,0xA002,0x7380, 0x737F,0xA004,0xA002,0x737D,0x737C,0xA002,0x737B,0x737A,0xA000,0xA000,0xA000,0xA008,0xA004,0xA002,0x7379,0x7378, 0xA002,0x7377,0x7376,0xA004,0xA002,0x7375,0x7374,0xA002,0x7373,0x7372,0xA1FB,0xA0C9,0xA032,0xA001,0xA001,0xA010, 0xA001,0xA007,0xA003,0xA001,0x7371,0xA002,0x7370,0x736E,0xA004,0xA002,0x736B,0x736A,0xA002,0x7369,0x7368,0xA010, 0xA008,0xA004,0xA002,0x7367,0x7366,0xA002,0x7365,0x7364,0xA004,0xA002,0x7363,0x7362,0xA002,0x7361,0x735F,0xA008, 0xA004,0xA002,0x735E,0x735D,0xA002,0x735C,0x735B,0xA004,0xA002,0x735A,0x7359,0xA002,0x7358,0x7356,0xA07D,0xA03D, 0xA01D,0xA00E,0xA006,0xA002,0x7355,0xA002,0x7354,0x7353,0xA004,0xA002,0x7351,0x734F,0xA002,0x734E,0x734C,0xA007, 0xA004,0xA002,0x734B,0x734A,0xA000,0x7349,0xA004,0xA002,0x7348,0x7347,0xA002,0x7346,0x7345,0xA010,0xA008,0xA004, 0xA002,0x7344,0x7343,0xA002,0x7342,0x7341,0xA004,0xA002,0x7340,0x733D,0xA002,0x733C,0x733B,0xA008,0xA004,0xA002, 0x733A,0x7336,0xA002,0x7335,0x7333,0xA004,0xA002,0x7332,0x7330,0xA002,0x732F,0x732D,0xA020,0xA010,0xA008,0xA004, 0xA002,0x7328,0x7327,0xA002,0x7326,0x7324,0xA004,0xA002,0x7323,0x7320,0xA002,0x731F,0x731A,0xA008,0xA004,0xA002, 0x7319,0x7318,0xA002,0x7314,0x7312,0xA004,0xA002,0x7311,0x7310,0xA002,0x730F,0x730D,0xA010,0xA008,0xA004,0xA002, 0x730C,0x730B,0xA002,0x7309,0x7308,0xA004,0xA002,0x7307,0x7306,0xA002,0x7305,0x7304,0xA008,0xA004,0xA002,0x7302, 0x7300,0xA002,0x72FF,0x72FE,0xA004,0xA002,0x72FD,0x72F9,0xA002,0x72F6,0x72F5,0xA000,0xA000,0xA010,0xA008,0xA004, 0xA002,0x72EB,0x72EA,0xA002,0x72E7,0x72E6,0xA004,0xA002,0x72E5,0x72E4,0xA002,0x72E3,0x72E2,0xA000,0xA004,0xA002, 0x72DF,0x72DD,0xA000,0x72DC,0xA0A2,0xA04B,0xA00B,0xA001,0xA001,0xA001,0xA004,0xA002,0x254B,0x254A,0xA002,0x2549, 0x2548,0xA020,0xA010,0xA008,0xA004,0xA002,0x2547,0x2546,0xA002,0x2545,0x2544,0xA004,0xA002,0x2543,0x2542,0xA002, 0x2541,0x2540,0xA008,0xA004,0xA002,0x253F,0x253E,0xA002,0x253D,0x253C,0xA004,0xA002,0x253B,0x253A,0xA002,0x2539, 0x2538,0xA010,0xA008,0xA004,0xA002,0x2537,0x2536,0xA002,0x2535,0x2534,0xA004,0xA002,0x2533,0x2532,0xA002,0x2531, 0x2530,0xA008,0xA004,0xA002,0x252F,0x252E,0xA002,0x252D,0x252C,0xA004,0xA002,0x252B,0x252A,0xA002,0x2529,0x2528, 0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x2527,0x2526,0xA002,0x2525,0x2524,0xA004,0xA002,0x2523,0x2522,0xA002, 0x2521,0x2520,0xA008,0xA004,0xA002,0x251F,0x251E,0xA002,0x251D,0x251C,0xA004,0xA002,0x251B,0x251A,0xA002,0x2519, 0x2518,0xA010,0xA008,0xA004,0xA002,0x2517,0x2516,0xA002,0x2515,0x2514,0xA004,0xA002,0x2513,0x2512,0xA002,0x2511, 0x2510,0xA008,0xA004,0xA002,0x250F,0x250E,0xA002,0x250D,0x250C,0xA004,0xA002,0x250B,0x250A,0xA002,0x2509,0x2508, 0xA011,0xA000,0xA008,0xA004,0xA002,0x2507,0x2506,0xA002,0x2505,0x2504,0xA004,0xA002,0x2503,0x2502,0xA002,0x2501, 0x2500,0xA000,0xA001,0xA000,0xA001,0x3007,0xA072,0xA038,0xA018,0xA009,0xA001,0xA004,0xA002,0xFE6B,0xFE6A,0xA002, 0xFE69,0xFE68,0xA008,0xA004,0xA002,0xFE66,0xFE65,0xA002,0xFE64,0xFE63,0xA003,0xA000,0xFE62,0xA002,0xFE61,0xFE60, 0xA010,0xA008,0xA004,0xA002,0xFE5F,0xFE5E,0xA002,0xFE5D,0xFE5C,0xA004,0xA002,0xFE5B,0xFE5A,0xA002,0xFE59,0xFE57, 0xA008,0xA004,0xA002,0xFE56,0xFE55,0xA002,0xFE54,0xFE52,0xA004,0xA002,0xFE51,0xFE50,0xA002,0xFE4F,0xFE4E,0xA01C, 0xA010,0xA008,0xA004,0xA002,0xFE4D,0xFE4C,0xA002,0xFE4B,0xFE4A,0xA004,0xA002,0xFE49,0x309E,0xA002,0x309D,0x3006, 0xA008,0xA004,0xA002,0x30FE,0x30FD,0xA002,0x309C,0x309B,0xA000,0xA000,0x30FC,0xA00E,0xA007,0xA003,0xA000,0x2010, 0xA002,0x3231,0x2121,0xA003,0xA001,0xFFE4,0xA002,0xFFE2,0xFE30,0xA008,0xA004,0xA002,0x33D5,0x33D2,0xA002,0x33D1, 0x33CE,0xA004,0xA002,0x33C4,0x33A1,0xA002,0x339E,0x339D,0xA000,0xA000,0xA010,0xA008,0xA004,0xA002,0x339C,0x338F, 0xA002,0x338E,0x32A3,0xA004,0xA002,0x3029,0x3028,0xA002,0x3027,0x3026,0xA008,0xA004,0xA002,0x3025,0x3024,0xA002, 0x3023,0x3022,0xA000,0xA000,0x3021,0xA13E,0xA0A0,0xA03A,0xA001,0xA019,0xA009,0xA001,0xA004,0xA002,0x3129,0x3128, 0xA002,0x3127,0x3126,0xA008,0xA004,0xA002,0x3125,0x3124,0xA002,0x3123,0x3122,0xA004,0xA002,0x3121,0x3120,0xA002, 0x311F,0x311E,0xA010,0xA008,0xA004,0xA002,0x311D,0x311C,0xA002,0x311B,0x311A,0xA004,0xA002,0x3119,0x3118,0xA002, 0x3117,0x3116,0xA008,0xA004,0xA002,0x3115,0x3114,0xA002,0x3113,0x3112,0xA004,0xA002,0x3111,0x3110,0xA002,0x310F, 0x310E,0xA039,0xA01A,0xA010,0xA008,0xA004,0xA002,0x310D,0x310C,0xA002,0x310B,0x310A,0xA004,0xA002,0x3109,0x3108, 0xA002,0x3107,0x3106,0xA004,0xA000,0xA000,0x3105,0xA003,0xA001,0x0261,0xA001,0x0148,0xA00F,0xA007,0xA003,0xA000, 0x0144,0xA002,0x0251,0x00EA,0xA004,0xA002,0x00FC,0x01DC,0xA002,0x01DA,0x01D8,0xA008,0xA004,0xA002,0x01D6,0x00F9, 0xA002,0x01D4,0x00FA,0xA004,0xA002,0x016B,0x00F2,0xA002,0x01D2,0x00F3,0xA01C,0xA010,0xA008,0xA004,0xA002,0x014D, 0x00EC,0xA002,0x01D0,0x00ED,0xA004,0xA002,0x012B,0x00E8,0xA002,0x011B,0x00E9,0xA008,0xA004,0xA002,0x0113,0x00E0, 0xA002,0x01CE,0x00E1,0xA000,0xA000,0x0101,0xA001,0xA008,0xA004,0xA002,0x301E,0x301D,0xA002,0x3012,0x2295,0xA004, 0xA002,0x2609,0x25E5,0xA002,0x25E4,0x25E3,0xA07D,0xA03D,0xA01D,0xA00E,0xA006,0xA002,0x25E2,0xA002,0x25BD,0x25BC, 0xA004,0xA002,0x2595,0x2594,0xA002,0x2593,0x258F,0xA008,0xA004,0xA002,0x258E,0x258D,0xA002,0x258C,0x258B,0xA004, 0xA002,0x258A,0x2589,0xA000,0x2588,0xA010,0xA008,0xA004,0xA002,0x2587,0x2586,0xA002,0x2585,0x2584,0xA004,0xA002, 0x2583,0x2582,0xA002,0x2581,0x2573,0xA008,0xA004,0xA002,0x2572,0x2571,0xA002,0x2570,0x256F,0xA004,0xA002,0x256E, 0x256D,0xA002,0x256C,0x256B,0xA020,0xA010,0xA008,0xA004,0xA002,0x256A,0x2569,0xA002,0x2568,0x2567,0xA004,0xA002, 0x2566,0x2565,0xA002,0x2564,0x2563,0xA008,0xA004,0xA002,0x2562,0x2561,0xA002,0x2560,0x255F,0xA004,0xA002,0x255E, 0x255D,0xA002,0x255C,0x255B,0xA010,0xA008,0xA004,0xA002,0x255A,0x2559,0xA002,0x2558,0x2557,0xA004,0xA002,0x2556, 0x2555,0xA002,0x2554,0x2553,0xA008,0xA004,0xA002,0x2552,0x2551,0xA002,0x2550,0x22BF,0xA004,0xA002,0x2267,0x2266, 0xA002,0x2252,0x2223,0xA000,0xA000,0xA010,0xA008,0xA004,0xA002,0x221F,0x2215,0xA002,0x2199,0x2198,0xA004,0xA002, 0x2197,0x2196,0xA002,0x2109,0x2105,0xA008,0xA004,0xA002,0x2035,0x2025,0xA002,0x2015,0x2013,0xA004,0xA002,0x02D9, 0x02CB,0xA000,0x02CA,0xA000,0xA047,0xA008,0xA001,0xA001,0xA001,0xA001,0xA002,0x044F,0x044E,0xA020,0xA010,0xA008, 0xA004,0xA002,0x044D,0x044C,0xA002,0x044B,0x044A,0xA004,0xA002,0x0449,0x0448,0xA002,0x0447,0x0446,0xA008,0xA004, 0xA002,0x0445,0x0444,0xA002,0x0443,0x0442,0xA004,0xA002,0x0441,0x0440,0xA002,0x043F,0x043E,0xA010,0xA008,0xA004, 0xA002,0x043D,0x043C,0xA002,0x043B,0x043A,0xA004,0xA002,0x0439,0x0438,0xA002,0x0437,0x0436,0xA008,0xA004,0xA002, 0x0451,0x0435,0xA002,0x0434,0x0433,0xA004,0xA002,0x0432,0x0431,0xA000,0x0430,0xA027,0xA007,0xA001,0xA001,0xA001, 0xA002,0x042F,0x042E,0xA010,0xA008,0xA004,0xA002,0x042D,0x042C,0xA002,0x042B,0x042A,0xA004,0xA002,0x0429,0x0428, 0xA002,0x0427,0x0426,0xA008,0xA004,0xA002,0x0425,0x0424,0xA002,0x0423,0x0422,0xA004,0xA002,0x0421,0x0420,0xA002, 0x041F,0x041E,0xA000,0xA010,0xA008,0xA004,0xA002,0x041D,0x041C,0xA002,0x041B,0x041A,0xA004,0xA002,0x0419,0x0418, 0xA002,0x0417,0x0416,0xA008,0xA004,0xA002,0x0401,0x0415,0xA002,0x0414,0x0413,0xA004,0xA002,0x0412,0x0411,0xA000, 0x0410,0xA2B5,0xA148,0xA095,0xA000,0xA03C,0xA00A,0xA001,0xA001,0xA001,0xA004,0xA002,0xFE34,0xFE33,0xA001,0xFE31, 0xA01D,0xA00D,0xA008,0xA004,0xA002,0xFE38,0xFE37,0xA002,0xFE3C,0xFE3B,0xA001,0xA002,0xFE44,0xFE43,0xA008,0xA004, 0xA002,0xFE42,0xFE41,0xA002,0xFE3E,0xFE3D,0xA004,0xA002,0xFE40,0xFE3F,0xA002,0xFE3A,0xFE39,0xA006,0xA000,0xA000, 0xA002,0xFE36,0xFE35,0xA007,0xA003,0xA001,0x03C9,0xA002,0x03C8,0x03C7,0xA004,0xA002,0x03C6,0x03C5,0xA002,0x03C4, 0x03C3,0xA031,0xA01E,0xA00E,0xA006,0xA002,0x03C1,0xA002,0x03C0,0x03BF,0xA004,0xA002,0x03BE,0x03BD,0xA002,0x03BC, 0x03BB,0xA008,0xA004,0xA002,0x03BA,0x03B9,0xA002,0x03B8,0x03B7,0xA004,0xA002,0x03B6,0x03B5,0xA002,0x03B4,0x03B3, 0xA006,0xA000,0xA000,0xA002,0x03B2,0x03B1,0xA005,0xA001,0xA002,0x03A9,0x03A8,0xA004,0xA002,0x03A7,0x03A6,0xA002, 0x03A5,0x03A4,0xA020,0xA010,0xA008,0xA004,0xA002,0x03A3,0x03A1,0xA002,0x03A0,0x039F,0xA004,0xA002,0x039E,0x039D, 0xA002,0x039C,0x039B,0xA008,0xA004,0xA002,0x039A,0x0399,0xA002,0x0398,0x0397,0xA004,0xA002,0x0396,0x0395,0xA002, 0x0394,0x0393,0xA000,0xA000,0xA000,0xA002,0x0392,0x0391,0xA000,0xA048,0xA008,0xA001,0xA001,0xA001,0xA001,0xA002, 0x30F6,0x30F5,0xA020,0xA010,0xA008,0xA004,0xA002,0x30F4,0x30F3,0xA002,0x30F2,0x30F1,0xA004,0xA002,0x30F0,0x30EF, 0xA002,0x30EE,0x30ED,0xA008,0xA004,0xA002,0x30EC,0x30EB,0xA002,0x30EA,0x30E9,0xA004,0xA002,0x30E8,0x30E7,0xA002, 0x30E6,0x30E5,0xA010,0xA008,0xA004,0xA002,0x30E4,0x30E3,0xA002,0x30E2,0x30E1,0xA004,0xA002,0x30E0,0x30DF,0xA002, 0x30DE,0x30DD,0xA008,0xA004,0xA002,0x30DC,0x30DB,0xA002,0x30DA,0x30D9,0xA004,0xA002,0x30D8,0x30D7,0xA002,0x30D6, 0x30D5,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x30D4,0x30D3,0xA002,0x30D2,0x30D1,0xA004,0xA002,0x30D0,0x30CF, 0xA002,0x30CE,0x30CD,0xA008,0xA004,0xA002,0x30CC,0x30CB,0xA002,0x30CA,0x30C9,0xA004,0xA002,0x30C8,0x30C7,0xA002, 0x30C6,0x30C5,0xA010,0xA008,0xA004,0xA002,0x30C4,0x30C3,0xA002,0x30C2,0x30C1,0xA004,0xA002,0x30C0,0x30BF,0xA002, 0x30BE,0x30BD,0xA008,0xA004,0xA002,0x30BC,0x30BB,0xA002,0x30BA,0x30B9,0xA004,0xA002,0x30B8,0x30B7,0xA002,0x30B6, 0x30B5,0xA020,0xA010,0xA008,0xA004,0xA002,0x30B4,0x30B3,0xA002,0x30B2,0x30B1,0xA004,0xA002,0x30B0,0x30AF,0xA002, 0x30AE,0x30AD,0xA008,0xA004,0xA002,0x30AC,0x30AB,0xA002,0x30AA,0x30A9,0xA004,0xA002,0x30A8,0x30A7,0xA002,0x30A6, 0x30A5,0xA000,0xA000,0xA004,0xA002,0x30A4,0x30A3,0xA002,0x30A2,0x30A1,0xA0AC,0xA000,0xA03D,0xA001,0xA01C,0xA00C, 0xA004,0xA001,0xA001,0x3093,0xA004,0xA002,0x3092,0x3091,0xA002,0x3090,0x308F,0xA008,0xA004,0xA002,0x308E,0x308D, 0xA002,0x308C,0x308B,0xA004,0xA002,0x308A,0x3089,0xA002,0x3088,0x3087,0xA010,0xA008,0xA004,0xA002,0x3086,0x3085, 0xA002,0x3084,0x3083,0xA004,0xA002,0x3082,0x3081,0xA002,0x3080,0x307F,0xA008,0xA004,0xA002,0x307E,0x307D,0xA002, 0x307C,0x307B,0xA004,0xA002,0x307A,0x3079,0xA002,0x3078,0x3077,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x3076, 0x3075,0xA002,0x3074,0x3073,0xA004,0xA002,0x3072,0x3071,0xA002,0x3070,0x306F,0xA008,0xA004,0xA002,0x306E,0x306D, 0xA002,0x306C,0x306B,0xA004,0xA002,0x306A,0x3069,0xA002,0x3068,0x3067,0xA010,0xA008,0xA004,0xA002,0x3066,0x3065, 0xA002,0x3064,0x3063,0xA004,0xA002,0x3062,0x3061,0xA002,0x3060,0x305F,0xA008,0xA004,0xA002,0x305E,0x305D,0xA002, 0x305C,0x305B,0xA004,0xA002,0x305A,0x3059,0xA002,0x3058,0x3057,0xA020,0xA010,0xA008,0xA004,0xA002,0x3056,0x3055, 0xA002,0x3054,0x3053,0xA004,0xA002,0x3052,0x3051,0xA002,0x3050,0x304F,0xA008,0xA004,0xA002,0x304E,0x304D,0xA002, 0x304C,0x304B,0xA004,0xA002,0x304A,0x3049,0xA002,0x3048,0x3047,0xA000,0xA008,0xA004,0xA002,0x3046,0x3045,0xA002, 0x3044,0x3043,0xA000,0xA002,0x3042,0x3041,0xA000,0xA04F,0xA00F,0xA001,0xA001,0xA005,0xA001,0xA002,0xFFE3,0xFF5D, 0xA004,0xA002,0xFF5C,0xFF5B,0xA002,0xFF5A,0xFF59,0xA020,0xA010,0xA008,0xA004,0xA002,0xFF58,0xFF57,0xA002,0xFF56, 0xFF55,0xA004,0xA002,0xFF54,0xFF53,0xA002,0xFF52,0xFF51,0xA008,0xA004,0xA002,0xFF50,0xFF4F,0xA002,0xFF4E,0xFF4D, 0xA004,0xA002,0xFF4C,0xFF4B,0xA002,0xFF4A,0xFF49,0xA010,0xA008,0xA004,0xA002,0xFF48,0xFF47,0xA002,0xFF46,0xFF45, 0xA004,0xA002,0xFF44,0xFF43,0xA002,0xFF42,0xFF41,0xA008,0xA004,0xA002,0xFF40,0xFF3F,0xA002,0xFF3E,0xFF3D,0xA004, 0xA002,0xFF3C,0xFF3B,0xA002,0xFF3A,0xFF39,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0xFF38,0xFF37,0xA002,0xFF36, 0xFF35,0xA004,0xA002,0xFF34,0xFF33,0xA002,0xFF32,0xFF31,0xA008,0xA004,0xA002,0xFF30,0xFF2F,0xA002,0xFF2E,0xFF2D, 0xA004,0xA002,0xFF2C,0xFF2B,0xA002,0xFF2A,0xFF29,0xA010,0xA008,0xA004,0xA002,0xFF28,0xFF27,0xA002,0xFF26,0xFF25, 0xA004,0xA002,0xFF24,0xFF23,0xA002,0xFF22,0xFF21,0xA008,0xA004,0xA002,0xFF20,0xFF1F,0xA002,0xFF1E,0xFF1D,0xA004, 0xA002,0xFF1C,0xFF1B,0xA002,0xFF1A,0xFF19,0xA020,0xA010,0xA008,0xA004,0xA002,0xFF18,0xFF17,0xA002,0xFF16,0xFF15, 0xA004,0xA002,0xFF14,0xFF13,0xA002,0xFF12,0xFF11,0xA008,0xA004,0xA002,0xFF10,0xFF0F,0xA002,0xFF0E,0xFF0D,0xA004, 0xA002,0xFF0C,0xFF0B,0xA002,0xFF0A,0xFF09,0xA000,0xA008,0xA004,0xA002,0xFF08,0xFF07,0xA002,0xFF06,0xFF05,0xA004, 0xA002,0xFFE5,0xFF03,0xA002,0xFF02,0xFF01,0xA171,0xA0AF,0xA000,0xA042,0xA008,0xA001,0xA001,0xA001,0xA001,0xA002, 0x216B,0x216A,0xA01D,0xA010,0xA008,0xA004,0xA002,0x2169,0x2168,0xA002,0x2167,0x2166,0xA004,0xA002,0x2165,0x2164, 0xA002,0x2163,0x2162,0xA005,0xA000,0xA002,0x2161,0x2160,0xA004,0xA002,0x3229,0x3228,0xA002,0x3227,0x3226,0xA00D, 0xA008,0xA004,0xA002,0x3225,0x3224,0xA002,0x3223,0x3222,0xA000,0xA002,0x3221,0x3220,0xA008,0xA004,0xA002,0x2469, 0x2468,0xA002,0x2467,0x2466,0xA004,0xA002,0x2465,0x2464,0xA002,0x2463,0x2462,0xA040,0xA020,0xA010,0xA008,0xA004, 0xA002,0x2461,0x2460,0xA002,0x2487,0x2486,0xA004,0xA002,0x2485,0x2484,0xA002,0x2483,0x2482,0xA008,0xA004,0xA002, 0x2481,0x2480,0xA002,0x247F,0x247E,0xA004,0xA002,0x247D,0x247C,0xA002,0x247B,0x247A,0xA010,0xA008,0xA004,0xA002, 0x2479,0x2478,0xA002,0x2477,0x2476,0xA004,0xA002,0x2475,0x2474,0xA002,0x249B,0x249A,0xA008,0xA004,0xA002,0x2499, 0x2498,0xA002,0x2497,0x2496,0xA004,0xA002,0x2495,0x2494,0xA002,0x2493,0x2492,0xA016,0xA010,0xA008,0xA004,0xA002, 0x2491,0x2490,0xA002,0x248F,0x248E,0xA004,0xA002,0x248D,0x248C,0xA002,0x248B,0x248A,0xA000,0xA000,0xA002,0x2489, 0x2488,0xA010,0xA008,0xA004,0xA002,0x2179,0x2178,0xA002,0x2177,0x2176,0xA004,0xA002,0x2175,0x2174,0xA002,0x2173, 0x2172,0xA000,0xA000,0xA002,0x2171,0x2170,0xA000,0xA048,0xA008,0xA001,0xA001,0xA001,0xA001,0xA002,0x3013,0x2193, 0xA020,0xA010,0xA008,0xA004,0xA002,0x2191,0x2190,0xA002,0x2192,0x203B,0xA004,0xA002,0x25B2,0x25B3,0xA002,0x25A0, 0x25A1,0xA008,0xA004,0xA002,0x25C6,0x25C7,0xA002,0x25CE,0x25CF,0xA004,0xA002,0x25CB,0x2605,0xA002,0x2606,0x2116, 0xA010,0xA008,0xA004,0xA002,0x00A7,0x2030,0xA002,0xFFE1,0xFFE0,0xA004,0xA002,0x00A4,0xFF04,0xA002,0x2103,0x2033, 0xA008,0xA004,0xA002,0x2032,0x00B0,0xA002,0x2640,0x2642,0xA004,0xA002,0x2234,0x2235,0xA002,0x221E,0x2265,0xA040, 0xA020,0xA010,0xA008,0xA004,0xA002,0x2264,0x226F,0xA002,0x226E,0x2260,0xA004,0xA002,0x221D,0x223D,0xA002,0x2248, 0x224C,0xA008,0xA004,0xA002,0x2261,0x222E,0xA002,0x222B,0x2299,0xA004,0xA002,0x2312,0x2220,0xA002,0x2225,0x22A5, 0xA010,0xA008,0xA004,0xA002,0x221A,0x2237,0xA002,0x2208,0x2229,0xA004,0xA002,0x222A,0x220F,0xA002,0x2211,0x2228, 0xA008,0xA004,0xA002,0x2227,0x2236,0xA002,0x00F7,0x00D7,0xA004,0xA002,0x00B1,0x3011,0xA002,0x3010,0x3017,0xA020, 0xA010,0xA008,0xA004,0xA002,0x3016,0x300F,0xA002,0x300E,0x300D,0xA004,0xA002,0x300C,0x300B,0xA002,0x300A,0x3009, 0xA008,0xA004,0xA002,0x3008,0x3015,0xA002,0x3014,0x201D,0xA004,0xA002,0x201C,0x2019,0xA002,0x2018,0x2026,0xA010, 0xA008,0xA004,0xA002,0x2016,0xFF5E,0xA002,0x2014,0x3005,0xA004,0xA002,0x3003,0x00A8,0xA002,0x02C7,0x02C9,0xA000, 0xA004,0xA002,0x00B7,0x3002,0xA002,0x3001,0x3000,0xA17F,0xA0C1,0xA041,0xA001,0xA020,0xA010,0xA008,0xA004,0xA002, 0x72DB,0x72DA,0xA002,0x72D8,0x72D6,0xA004,0xA002,0x72D5,0x72D4,0xA002,0x72D3,0x72D1,0xA008,0xA004,0xA002,0x72CF, 0x72CC,0xA002,0x72CB,0x72CA,0xA004,0xA002,0x72C9,0x72C7,0xA002,0x72C6,0x72C5,0xA010,0xA008,0xA004,0xA002,0x72C0, 0x72BF,0xA002,0x72BE,0x72BD,0xA004,0xA002,0x72BC,0x72BB,0xA002,0x72BA,0x72B5,0xA008,0xA004,0xA002,0x72B3,0x72B2, 0xA002,0x72B1,0x72AE,0xA004,0xA002,0x72AB,0x72AA,0xA002,0x72A9,0x72A8,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002, 0x72A7,0x72A6,0xA002,0x72A5,0x72A4,0xA004,0xA002,0x72A3,0x72A2,0xA002,0x72A1,0x72A0,0xA008,0xA004,0xA002,0x729E, 0x729D,0xA002,0x729C,0x729B,0xA004,0xA002,0x729A,0x7299,0xA002,0x7298,0x7297,0xA010,0xA008,0xA004,0xA002,0x7296, 0x7295,0xA002,0x7294,0x7293,0xA004,0xA002,0x7291,0x7290,0xA002,0x728E,0x728C,0xA008,0xA004,0xA002,0x7289,0x7288, 0xA002,0x7287,0x7286,0xA004,0xA002,0x7285,0x7283,0xA002,0x7282,0x727D,0xA020,0xA010,0xA008,0xA004,0xA002,0x727C, 0x727B,0xA002,0x7278,0x7277,0xA004,0xA002,0x7276,0x7274,0xA002,0x7273,0x7271,0xA008,0xA004,0xA002,0x7270,0x726D, 0xA002,0x726C,0x726B,0xA004,0xA002,0x726A,0x7268,0xA002,0x7265,0x7264,0xA010,0xA008,0xA004,0xA002,0x7263,0x7260, 0xA002,0x725E,0x725C,0xA004,0xA002,0x725A,0x7258,0xA002,0x7257,0x7255,0xA008,0xA004,0xA002,0x7254,0x7253,0xA002, 0x7251,0x7250,0xA004,0xA002,0x724F,0x724E,0xA002,0x724B,0x724A,0xA07D,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x7249, 0xA002,0x7246,0x7245,0xA004,0xA002,0x7244,0x7243,0xA002,0x7242,0x7241,0xA008,0xA004,0xA002,0x7240,0x723E,0xA002, 0x723C,0x723A,0xA004,0xA002,0x7234,0x7233,0xA002,0x7232,0x722F,0xA010,0xA008,0xA004,0xA002,0x722E,0x722D,0xA002, 0x722B,0x7229,0xA004,0xA002,0x7227,0x7226,0xA002,0x7225,0x7224,0xA008,0xA004,0xA002,0x7223,0x7222,0xA002,0x7221, 0x7220,0xA004,0xA002,0x721F,0x721E,0xA002,0x721C,0x721B,0xA01F,0xA00F,0xA007,0xA003,0xA001,0x721A,0xA002,0x7219, 0x7218,0xA004,0xA002,0x7217,0x7216,0xA002,0x7215,0x7214,0xA008,0xA004,0xA002,0x7213,0x7212,0xA002,0x7211,0x7210, 0xA004,0xA002,0x720F,0x720E,0xA002,0x720D,0x720C,0xA010,0xA008,0xA004,0xA002,0x720B,0x720A,0xA002,0x7209,0x7208, 0xA004,0xA002,0x7207,0x7205,0xA002,0x7204,0x7203,0xA008,0xA004,0xA002,0x7202,0x7201,0xA002,0x7200,0x71FF,0xA004, 0xA002,0x71FE,0x71FD,0xA002,0x71FC,0x71FB,0xA000,0xA020,0xA010,0xA008,0xA004,0xA002,0x71FA,0x71F8,0xA002,0x71F7, 0x71F6,0xA004,0xA002,0x71F5,0x71F4,0xA002,0x71F3,0x71F2,0xA008,0xA004,0xA002,0x71F1,0x71F0,0xA002,0x71EF,0x71ED, 0xA004,0xA002,0x71EC,0x71EB,0xA002,0x71EA,0x71E9,0xA010,0xA008,0xA004,0xA002,0x71E8,0x71E6,0xA002,0x71E4,0x71E3, 0xA004,0xA002,0x71E2,0x71E1,0xA002,0x71DF,0x71DE,0xA008,0xA004,0xA002,0x71DD,0x71DC,0xA002,0x71DB,0x71DA,0xA004, 0xA002,0x71D9,0x71D8,0xA002,0x71D7,0x71D6,0xA0BE,0xA03E,0xA001,0xA01D,0xA00D,0xA005,0xA001,0xA002,0x71D3,0x71D2, 0xA004,0xA002,0x71D1,0x71D0,0xA002,0x71CF,0x71CD,0xA008,0xA004,0xA002,0x71CC,0x71CB,0xA002,0x71CA,0x71C9,0xA004, 0xA002,0x71C8,0x71C7,0xA002,0x71C6,0x71C5,0xA010,0xA008,0xA004,0xA002,0x71C4,0x71C2,0xA002,0x71C1,0x71C0,0xA004, 0xA002,0x71BF,0x71BE,0xA002,0x71BD,0x71BC,0xA008,0xA004,0xA002,0x71BB,0x71BA,0xA002,0x71B8,0x71B7,0xA004,0xA002, 0x71B6,0x71B4,0xA002,0x71B2,0x71B1,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x71B0,0x71AF,0xA002,0x71AE,0x71AD, 0xA004,0xA002,0x71AB,0x71AA,0xA002,0x71A9,0x71A7,0xA008,0xA004,0xA002,0x71A6,0x71A5,0xA002,0x71A4,0x71A3,0xA004, 0xA002,0x71A2,0x71A1,0xA002,0x719E,0x719D,0xA010,0xA008,0xA004,0xA002,0x719C,0x719B,0xA002,0x719A,0x7197,0xA004, 0xA002,0x7196,0x7195,0xA002,0x7193,0x7192,0xA008,0xA004,0xA002,0x7191,0x7190,0xA002,0x718E,0x718D,0xA004,0xA002, 0x718C,0x718B,0xA002,0x7189,0x7188,0xA020,0xA010,0xA008,0xA004,0xA002,0x7187,0x7186,0xA002,0x7185,0x7183,0xA004, 0xA002,0x7182,0x7181,0xA002,0x7180,0x717F,0xA008,0xA004,0xA002,0x717E,0x717C,0xA002,0x717B,0x7179,0xA004,0xA002, 0x7177,0x7176,0xA002,0x7175,0x7174,0xA010,0xA008,0xA004,0xA002,0x7171,0x7170,0xA002,0x716F,0x716D,0xA004,0xA002, 0x716C,0x716B,0xA002,0x716A,0x7169,0xA008,0xA004,0xA002,0x7165,0x7163,0xA002,0x7162,0x7161,0xA004,0xA002,0x7160, 0x715F,0xA002,0x715D,0x715B,0xA07D,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x715A,0xA002,0x7159,0x7158,0xA004,0xA002, 0x7157,0x7156,0xA002,0x7155,0x7154,0xA008,0xA004,0xA002,0x7153,0x7152,0xA002,0x7151,0x7150,0xA004,0xA002,0x714F, 0x714D,0xA002,0x714B,0x7149,0xA010,0xA008,0xA004,0xA002,0x7148,0x7147,0xA002,0x7146,0x7144,0xA004,0xA002,0x7143, 0x7142,0xA002,0x7141,0x7140,0xA008,0xA004,0xA002,0x713F,0x713E,0xA002,0x713D,0x713C,0xA004,0xA002,0x713B,0x713A, 0xA002,0x7139,0x7138,0xA01F,0xA00F,0xA007,0xA004,0xA002,0x7137,0x7135,0xA001,0x7134,0xA004,0xA002,0x7133,0x7132, 0xA002,0x712E,0x712D,0xA008,0xA004,0xA002,0x712C,0x712B,0xA002,0x712A,0x7129,0xA004,0xA002,0x7128,0x7127,0xA002, 0x7125,0x7124,0xA010,0xA008,0xA004,0xA002,0x7123,0x7122,0xA002,0x7121,0x7120,0xA004,0xA002,0x711F,0x711E,0xA002, 0x711D,0x711C,0xA008,0xA004,0xA002,0x711B,0x7117,0xA002,0x7114,0x7112,0xA004,0xA002,0x7111,0x710F,0xA002,0x710E, 0x710D,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x710C,0x710B,0xA002,0x7108,0x7107,0xA004,0xA002,0x7106,0x7105, 0xA002,0x7104,0x7103,0xA008,0xA004,0xA002,0x7102,0x7101,0xA002,0x7100,0x70FF,0xA004,0xA002,0x70FE,0x70FC,0xA002, 0x70FB,0x70FA,0xA010,0xA008,0xA004,0xA002,0x70F8,0x70F6,0xA002,0x70F5,0x70F4,0xA004,0xA002,0x70F3,0x70F2,0xA002, 0x70F1,0x70F0,0xA008,0xA004,0xA002,0x70EE,0x70EA,0xA002,0x70E5,0x70E3,0xA004,0xA002,0x70E2,0x70E1,0xA002,0x70E0, 0x70DE,0xA000,0xA000,0xA000,0xA000,0xA002,0x70DD,0x70DC,0xB826,0xAC17,0xA60F,0xA307,0xA183,0xA0B8,0xA03A,0xA001, 0xA019,0xA009,0xA001,0xA004,0xA002,0x70DA,0x70D7,0xA002,0x70D6,0x70D5,0xA008,0xA004,0xA002,0x70D4,0x70D3,0xA002, 0x70D2,0x70D1,0xA004,0xA002,0x70D0,0x70CF,0xA002,0x70CE,0x70CD,0xA010,0xA008,0xA004,0xA002,0x70CC,0x70CB,0xA002, 0x70C9,0x70C7,0xA004,0xA002,0x70C6,0x70C5,0xA002,0x70C4,0x70BF,0xA008,0xA004,0xA002,0x70BE,0x70BA,0xA002,0x70B6, 0x70B5,0xA004,0xA002,0x70B4,0x70B2,0xA002,0x70B0,0x70AA,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x70A9,0xA002,0x70A8, 0x70A7,0xA004,0xA002,0x70A6,0x70A5,0xA002,0x70A4,0x70A3,0xA008,0xA004,0xA002,0x70A2,0x70A1,0xA002,0x70A0,0x709F, 0xA004,0xA002,0x709E,0x709B,0xA002,0x709A,0x7098,0xA010,0xA008,0xA004,0xA002,0x7097,0x7093,0xA002,0x7091,0x7090, 0xA004,0xA002,0x708F,0x708D,0xA002,0x708C,0x708B,0xA008,0xA004,0xA002,0x7088,0x7087,0xA002,0x7086,0x7084,0xA004, 0xA002,0x7083,0x7082,0xA002,0x7081,0x707D,0xA020,0xA010,0xA008,0xA004,0xA002,0x707B,0x707A,0xA002,0x7079,0x7077, 0xA004,0xA002,0x7074,0x7073,0xA002,0x7072,0x7071,0xA008,0xA004,0xA002,0x706E,0x706A,0xA002,0x7069,0x7068,0xA004, 0xA002,0x7067,0x7066,0xA002,0x7065,0x7064,0xA010,0xA008,0xA004,0xA002,0x7063,0x7062,0xA002,0x7061,0x7060,0xA004, 0xA002,0x705F,0x705D,0xA002,0x705C,0x705B,0xA008,0xA004,0xA002,0x705A,0x7059,0xA002,0x7058,0x7057,0xA004,0xA002, 0x7056,0x7055,0xA002,0x7054,0x7053,0xA07D,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x7052,0xA002,0x7051,0x7050,0xA004, 0xA002,0x704E,0x704D,0xA002,0x704B,0x704A,0xA008,0xA004,0xA002,0x7049,0x7048,0xA002,0x7047,0x7046,0xA004,0xA002, 0x7045,0x7044,0xA002,0x7043,0x7042,0xA010,0xA008,0xA004,0xA002,0x7041,0x7040,0xA002,0x703F,0x703E,0xA004,0xA002, 0x703D,0x703C,0xA002,0x703B,0x703A,0xA008,0xA004,0xA002,0x7038,0x7037,0xA002,0x7036,0x7034,0xA004,0xA002,0x7033, 0x7032,0xA002,0x7031,0x7030,0xA01F,0xA00F,0xA008,0xA004,0xA002,0x702F,0x702E,0xA002,0x702D,0x702C,0xA003,0xA000, 0x702B,0xA002,0x702A,0x7029,0xA008,0xA004,0xA002,0x7028,0x7027,0xA002,0x7026,0x7025,0xA004,0xA002,0x7024,0x7022, 0xA002,0x7021,0x7020,0xA010,0xA008,0xA004,0xA002,0x701F,0x701E,0xA002,0x701D,0x701C,0xA004,0xA002,0x7019,0x7018, 0xA002,0x7017,0x7016,0xA008,0xA004,0xA002,0x7015,0x7014,0xA002,0x7013,0x7012,0xA004,0xA002,0x7010,0x700F,0xA002, 0x700E,0x700D,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x700C,0x700B,0xA002,0x700A,0x7009,0xA004,0xA002,0x7008, 0x7007,0xA002,0x7006,0x7005,0xA008,0xA004,0xA002,0x7004,0x7003,0xA002,0x7002,0x7001,0xA004,0xA002,0x7000,0x6FFF, 0xA002,0x6FFE,0x6FFD,0xA010,0xA008,0xA004,0xA002,0x6FFC,0x6FFB,0xA002,0x6FFA,0x6FF9,0xA004,0xA002,0x6FF8,0x6FF7, 0xA002,0x6FF6,0x6FF5,0xA008,0xA004,0xA002,0x6FF4,0x6FF3,0xA002,0x6FF2,0x6FF1,0xA004,0xA002,0x6FF0,0x6FED,0xA002, 0x6FEC,0x6FEB,0xA000,0xA000,0xA008,0xA004,0xA002,0x6FEA,0x6FE9,0xA002,0x6FE8,0x6FE7,0xA000,0xA000,0x6FE6,0xA0B6, 0xA036,0xA001,0xA015,0xA005,0xA001,0xA001,0xA001,0x6FE5,0xA008,0xA004,0xA002,0x6FE4,0x6FE3,0xA002,0x6FE2,0x6FDF, 0xA004,0xA002,0x6FDD,0x6FDC,0xA002,0x6FDB,0x6FDA,0xA010,0xA008,0xA004,0xA002,0x6FD9,0x6FD8,0xA002,0x6FD7,0x6FD6, 0xA004,0xA002,0x6FD5,0x6FD4,0xA002,0x6FD3,0x6FD0,0xA008,0xA004,0xA002,0x6FCF,0x6FCE,0xA002,0x6FCD,0x6FCC,0xA004, 0xA002,0x6FCB,0x6FCA,0xA002,0x6FC8,0x6FC7,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x6FC6,0x6FC5,0xA002,0x6FC4, 0x6FC3,0xA004,0xA002,0x6FC1,0x6FBF,0xA002,0x6FBE,0x6FBD,0xA008,0xA004,0xA002,0x6FBC,0x6FBB,0xA002,0x6FBA,0x6FB8, 0xA004,0xA002,0x6FB7,0x6FB5,0xA002,0x6FB4,0x6FB2,0xA010,0xA008,0xA004,0xA002,0x6FB1,0x6FB0,0xA002,0x6FAF,0x6FAE, 0xA004,0xA002,0x6FAD,0x6FAC,0xA002,0x6FAB,0x6FAA,0xA008,0xA004,0xA002,0x6FA9,0x6FA8,0xA002,0x6FA6,0x6FA5,0xA004, 0xA002,0x6FA4,0x6FA3,0xA002,0x6FA2,0x6FA0,0xA020,0xA010,0xA008,0xA004,0xA002,0x6F9F,0x6F9E,0xA002,0x6F9D,0x6F9B, 0xA004,0xA002,0x6F9A,0x6F99,0xA002,0x6F98,0x6F97,0xA008,0xA004,0xA002,0x6F96,0x6F95,0xA002,0x6F94,0x6F93,0xA004, 0xA002,0x6F92,0x6F91,0xA002,0x6F90,0x6F8F,0xA010,0xA008,0xA004,0xA002,0x6F8B,0x6F8A,0xA002,0x6F87,0x6F86,0xA004, 0xA002,0x6F85,0x6F83,0xA002,0x6F82,0x6F81,0xA008,0xA004,0xA002,0x6F80,0x6F7F,0xA002,0x6F7E,0x6F7D,0xA004,0xA002, 0x6F7B,0x6F79,0xA002,0x6F77,0x6F76,0xA07D,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x6F75,0xA002,0x6F73,0x6F71,0xA004, 0xA002,0x6F70,0x6F6F,0xA002,0x6F6C,0x6F6B,0xA008,0xA004,0xA002,0x6F6A,0x6F69,0xA002,0x6F68,0x6F67,0xA004,0xA002, 0x6F65,0x6F64,0xA002,0x6F63,0x6F61,0xA010,0xA008,0xA004,0xA002,0x6F60,0x6F5F,0xA002,0x6F5D,0x6F5B,0xA004,0xA002, 0x6F5A,0x6F59,0xA002,0x6F57,0x6F56,0xA008,0xA004,0xA002,0x6F55,0x6F54,0xA002,0x6F53,0x6F52,0xA004,0xA002,0x6F51, 0x6F50,0xA002,0x6F4F,0x6F4E,0xA01F,0xA00F,0xA008,0xA004,0xA002,0x6F4C,0x6F4A,0xA002,0x6F49,0x6F48,0xA004,0xA002, 0x6F45,0x6F44,0xA000,0x6F43,0xA008,0xA004,0xA002,0x6F42,0x6F41,0xA002,0x6F40,0x6F3F,0xA004,0xA002,0x6F3D,0x6F3C, 0xA002,0x6F3B,0x6F3A,0xA010,0xA008,0xA004,0xA002,0x6F39,0x6F38,0xA002,0x6F37,0x6F35,0xA004,0xA002,0x6F34,0x6F32, 0xA002,0x6F30,0x6F2E,0xA008,0xA004,0xA002,0x6F2C,0x6F28,0xA002,0x6F27,0x6F26,0xA004,0xA002,0x6F25,0x6F23,0xA002, 0x6F22,0x6F21,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x6F1F,0x6F1E,0xA002,0x6F1D,0x6F1C,0xA004,0xA002,0x6F1B, 0x6F1A,0xA002,0x6F19,0x6F18,0xA008,0xA004,0xA002,0x6F17,0x6F16,0xA002,0x6F12,0x6F11,0xA004,0xA002,0x6F10,0x6F0E, 0xA002,0x6F0D,0x6F0C,0xA010,0xA008,0xA004,0xA002,0x6F0B,0x6F0A,0xA002,0x6F08,0x6F07,0xA004,0xA002,0x6F05,0x6F04, 0xA002,0x6F03,0x6F01,0xA008,0xA004,0xA002,0x6F00,0x6EFF,0xA002,0x6EFE,0x6EFD,0xA004,0xA002,0x6EFC,0x6EFB,0xA002, 0x6EFA,0x6EF8,0xA000,0xA000,0xA008,0xA004,0xA002,0x6EF7,0x6EF6,0xA002,0x6EF5,0x6EF3,0xA004,0xA002,0x6EF2,0x6EF1, 0xA000,0x6EF0,0xA184,0xA0B1,0xA031,0xA001,0xA010,0xA001,0xA007,0xA003,0xA001,0x6EEF,0xA002,0x6EEE,0x6EED,0xA004, 0xA002,0x6EEC,0x6EEB,0xA002,0x6EEA,0x6EE7,0xA010,0xA008,0xA004,0xA002,0x6EE3,0x6EDD,0xA002,0x6EDC,0x6EDB,0xA004, 0xA002,0x6ED9,0x6ED8,0xA002,0x6ED6,0x6ED2,0xA008,0xA004,0xA002,0x6ED0,0x6ECE,0xA002,0x6ECD,0x6ECC,0xA004,0xA002, 0x6ECA,0x6EC9,0xA002,0x6EC8,0x6EC6,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x6EC5,0x6EC4,0xA002,0x6EC3,0x6EC0, 0xA004,0xA002,0x6EBF,0x6EBE,0xA002,0x6EBC,0x6EB9,0xA008,0xA004,0xA002,0x6EB8,0x6EB5,0xA002,0x6EB3,0x6EB0,0xA004, 0xA002,0x6EAE,0x6EAD,0xA002,0x6EAC,0x6EAB,0xA010,0xA008,0xA004,0xA002,0x6EA9,0x6EA8,0xA002,0x6EA6,0x6EA4,0xA004, 0xA002,0x6EA3,0x6EA1,0xA002,0x6EA0,0x6E9E,0xA008,0xA004,0xA002,0x6E9D,0x6E9B,0xA002,0x6E9A,0x6E99,0xA004,0xA002, 0x6E97,0x6E96,0xA002,0x6E95,0x6E94,0xA020,0xA010,0xA008,0xA004,0xA002,0x6E93,0x6E92,0xA002,0x6E91,0x6E8E,0xA004, 0xA002,0x6E8D,0x6E8C,0xA002,0x6E8B,0x6E8A,0xA008,0xA004,0xA002,0x6E88,0x6E87,0xA002,0x6E84,0x6E82,0xA004,0xA002, 0x6E81,0x6E80,0xA002,0x6E7D,0x6E7C,0xA010,0xA008,0xA004,0xA002,0x6E7B,0x6E7A,0xA002,0x6E79,0x6E78,0xA004,0xA002, 0x6E77,0x6E76,0xA002,0x6E75,0x6E74,0xA008,0xA004,0xA002,0x6E73,0x6E72,0xA002,0x6E71,0x6E70,0xA004,0xA002,0x6E6F, 0x6E6D,0xA002,0x6E6C,0x6E6A,0xA07D,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x6E69,0xA002,0x6E68,0x6E67,0xA004,0xA002, 0x6E66,0x6E65,0xA002,0x6E64,0x6E63,0xA008,0xA004,0xA002,0x6E62,0x6E61,0xA002,0x6E60,0x6E5E,0xA004,0xA002,0x6E5D, 0x6E5C,0xA002,0x6E5A,0x6E59,0xA010,0xA008,0xA004,0xA002,0x6E57,0x6E55,0xA002,0x6E52,0x6E51,0xA004,0xA002,0x6E50, 0x6E4F,0xA002,0x6E4C,0x6E4B,0xA008,0xA004,0xA002,0x6E4A,0x6E49,0xA002,0x6E48,0x6E47,0xA004,0xA002,0x6E46,0x6E45, 0xA002,0x6E42,0x6E41,0xA01F,0xA010,0xA008,0xA004,0xA002,0x6E40,0x6E3F,0xA002,0x6E3E,0x6E3D,0xA004,0xA002,0x6E3C, 0x6E3B,0xA002,0x6E39,0x6E37,0xA007,0xA003,0xA000,0x6E36,0xA002,0x6E35,0x6E33,0xA004,0xA002,0x6E31,0x6E30,0xA002, 0x6E2E,0x6E2C,0xA010,0xA008,0xA004,0xA002,0x6E2A,0x6E28,0xA002,0x6E27,0x6E26,0xA004,0xA002,0x6E22,0x6E1F,0xA002, 0x6E1E,0x6E1C,0xA008,0xA004,0xA002,0x6E1B,0x6E19,0xA002,0x6E18,0x6E15,0xA004,0xA002,0x6E13,0x6E12,0xA002,0x6E0F, 0x6E0B,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x6E09,0x6E08,0xA002,0x6E07,0x6E06,0xA004,0xA002,0x6E04,0x6E03, 0xA002,0x6E02,0x6E01,0xA008,0xA004,0xA002,0x6E00,0x6DFF,0xA002,0x6DFE,0x6DFD,0xA004,0xA002,0x6DFA,0x6DF8,0xA002, 0x6DF6,0x6DF5,0xA010,0xA008,0xA004,0xA002,0x6DF4,0x6DF2,0xA002,0x6DF0,0x6DEF,0xA004,0xA002,0x6DED,0x6DEA,0xA002, 0x6DE9,0x6DE8,0xA008,0xA004,0xA002,0x6DE7,0x6DE5,0xA002,0x6DE3,0x6DE2,0xA004,0xA002,0x6DDF,0x6DDC,0xA002,0x6DDB, 0x6DDA,0xA000,0xA010,0xA008,0xA004,0xA002,0x6DD7,0x6DD5,0xA002,0x6DD4,0x6DD3,0xA004,0xA002,0x6DD2,0x6DD0,0xA002, 0x6DCF,0x6DCE,0xA000,0xA000,0xA000,0x6DCD,0xA0AE,0xA02E,0xA001,0xA00D,0xA001,0xA004,0xA001,0xA001,0x6DCA,0xA004, 0xA002,0x6DC9,0x6DC8,0xA002,0x6DC3,0x6DC2,0xA010,0xA008,0xA004,0xA002,0x6DC1,0x6DBE,0xA002,0x6DBD,0x6DBC,0xA004, 0xA002,0x6DBB,0x6DBA,0xA002,0x6DB9,0x6DB7,0xA008,0xA004,0xA002,0x6DB6,0x6DB4,0xA002,0x6DB3,0x6DB1,0xA004,0xA002, 0x6DB0,0x6DAD,0xA002,0x6DAC,0x6DA5,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x6DA2,0x6D9C,0xA002,0x6D9A,0x6D99, 0xA004,0xA002,0x6D98,0x6D97,0xA002,0x6D96,0x6D92,0xA008,0xA004,0xA002,0x6D90,0x6D8F,0xA002,0x6D8D,0x6D8B,0xA004, 0xA002,0x6D8A,0x6D87,0xA002,0x6D86,0x6D84,0xA010,0xA008,0xA004,0xA002,0x6D83,0x6D81,0xA002,0x6D80,0x6D7F,0xA004, 0xA002,0x6D7E,0x6D7D,0xA002,0x6D7B,0x6D7A,0xA008,0xA004,0xA002,0x6D79,0x6D76,0xA002,0x6D75,0x6D73,0xA004,0xA002, 0x6D72,0x6D71,0xA002,0x6D70,0x6D6D,0xA020,0xA010,0xA008,0xA004,0xA002,0x6D6C,0x6D6B,0xA002,0x6D68,0x6D67,0xA004, 0xA002,0x6D65,0x6D64,0xA002,0x6D62,0x6D61,0xA008,0xA004,0xA002,0x6D5F,0x6D5D,0xA002,0x6D5B,0x6D58,0xA004,0xA002, 0x6D57,0x6D56,0xA002,0x6D55,0x6D50,0xA010,0xA008,0xA004,0xA002,0x6D4C,0x6D49,0xA002,0x6D44,0x6D42,0xA004,0xA002, 0x6D40,0x6D3F,0xA002,0x6D3A,0x6D38,0xA008,0xA004,0xA002,0x6D37,0x6D36,0xA002,0x6D34,0x6D30,0xA004,0xA002,0x6D2F, 0x6D2D,0xA002,0x6D2C,0x6D29,0xA07D,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x6D28,0xA002,0x6D26,0x6D24,0xA004,0xA002, 0x6D23,0x6D22,0xA002,0x6D21,0x6D20,0xA008,0xA004,0xA002,0x6D1F,0x6D1D,0xA002,0x6D1C,0x6D18,0xA004,0xA002,0x6D16, 0x6D15,0xA002,0x6D14,0x6D13,0xA010,0xA008,0xA004,0xA002,0x6D11,0x6D10,0xA002,0x6D0F,0x6D0D,0xA004,0xA002,0x6D0A, 0x6D09,0xA002,0x6D08,0x6D06,0xA008,0xA004,0xA002,0x6D05,0x6D03,0xA002,0x6D02,0x6D00,0xA004,0xA002,0x6CFF,0x6CF9, 0xA002,0x6CF4,0x6CF2,0xA01F,0xA010,0xA008,0xA004,0xA002,0x6CED,0x6CEC,0xA002,0x6CE9,0x6CE7,0xA004,0xA002,0x6CE6, 0x6CE4,0xA002,0x6CDF,0x6CDD,0xA007,0xA004,0xA002,0x6CDC,0x6CDA,0xA000,0x6CD9,0xA004,0xA002,0x6CD8,0x6CD2,0xA002, 0x6CD1,0x6CCF,0xA010,0xA008,0xA004,0xA002,0x6CCE,0x6CCD,0xA002,0x6CCB,0x6CC8,0xA004,0xA002,0x6CC7,0x6CC6,0xA002, 0x6CC3,0x6CC2,0xA008,0xA004,0xA002,0x6CC1,0x6CC0,0xA002,0x6CBA,0x6CB7,0xA004,0xA002,0x6CB6,0x6CB5,0xA002,0x6CB4, 0x6CB0,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x6CAF,0x6CAC,0xA002,0x6CA8,0x6CA2,0xA004,0xA002,0x6CA0,0x6C9E, 0xA002,0x6C9D,0x6C9C,0xA008,0xA004,0xA002,0x6C9A,0x6C98,0xA002,0x6C97,0x6C96,0xA004,0xA002,0x6C95,0x6C92,0xA002, 0x6C91,0x6C8E,0xA010,0xA008,0xA004,0xA002,0x6C8D,0x6C8B,0xA002,0x6C8A,0x6C87,0xA004,0xA002,0x6C84,0x6C80,0xA002, 0x6C7F,0x6C7C,0xA008,0xA004,0xA002,0x6C7B,0x6C7A,0xA002,0x6C78,0x6C77,0xA004,0xA002,0x6C75,0x6C73,0xA002,0x6C71, 0x6C6F,0xA000,0xA010,0xA008,0xA004,0xA002,0x6C6E,0x6C6D,0xA002,0x6C6C,0x6C6B,0xA004,0xA002,0x6C67,0x6C66,0xA002, 0x6C65,0x6C63,0xA000,0xA004,0xA002,0x6C62,0x6C5A,0xA000,0x6C59,0xA303,0xA183,0xA0A8,0xA02A,0xA001,0xA009,0xA001, 0xA001,0xA003,0xA001,0x6C58,0xA002,0x6C56,0x6C53,0xA010,0xA008,0xA004,0xA002,0x6C52,0x6C51,0xA002,0x6C4F,0x6C4E, 0xA004,0xA002,0x6C4D,0x6C4C,0xA002,0x6C4B,0x6C48,0xA008,0xA004,0xA002,0x6C45,0x6C44,0xA002,0x6C43,0x6C3F,0xA004, 0xA002,0x6C3E,0x6C3C,0xA002,0x6C3B,0x6C3A,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x6C39,0xA002,0x6C37,0x6C36,0xA004, 0xA002,0x6C33,0x6C31,0xA002,0x6C2D,0x6C2C,0xA008,0xA004,0xA002,0x6C2B,0x6C25,0xA002,0x6C23,0x6C20,0xA004,0xA002, 0x6C1E,0x6C1D,0xA002,0x6C1C,0x6C17,0xA010,0xA008,0xA004,0xA002,0x6C12,0x6C0E,0xA002,0x6C0C,0x6C0B,0xA004,0xA002, 0x6C0A,0x6C09,0xA002,0x6C08,0x6C04,0xA008,0xA004,0xA002,0x6C03,0x6C02,0xA002,0x6C01,0x6C00,0xA004,0xA002,0x6BFF, 0x6BFE,0xA002,0x6BFC,0x6BFB,0xA020,0xA010,0xA008,0xA004,0xA002,0x6BFA,0x6BF8,0xA002,0x6BF7,0x6BF6,0xA004,0xA002, 0x6BF4,0x6BF2,0xA002,0x6BF1,0x6BF0,0xA008,0xA004,0xA002,0x6BEE,0x6BED,0xA002,0x6BEC,0x6BE9,0xA004,0xA002,0x6BE8, 0x6BE7,0xA002,0x6BE6,0x6BE5,0xA010,0xA008,0xA004,0xA002,0x6BE4,0x6BE3,0xA002,0x6BE2,0x6BE0,0xA004,0xA002,0x6BDF, 0x6BDE,0xA002,0x6BDD,0x6BDC,0xA008,0xA004,0xA002,0x6BDA,0x6BD8,0xA002,0x6BD1,0x6BD0,0xA004,0xA002,0x6BCE,0x6BCC, 0xA002,0x6BCA,0x6BC9,0xA07D,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x6BC8,0xA002,0x6BC7,0x6BC6,0xA004,0xA002,0x6BC4, 0x6BC3,0xA002,0x6BC0,0x6BBE,0xA008,0xA004,0xA002,0x6BBD,0x6BBC,0xA002,0x6BBB,0x6BBA,0xA004,0xA002,0x6BB9,0x6BB8, 0xA002,0x6BB6,0x6BB2,0xA010,0xA008,0xA004,0xA002,0x6BB1,0x6BB0,0xA002,0x6BAF,0x6BAE,0xA004,0xA002,0x6BAD,0x6BAC, 0xA002,0x6BAB,0x6BA9,0xA008,0xA004,0xA002,0x6BA8,0x6BA7,0xA002,0x6BA6,0x6BA5,0xA004,0xA002,0x6BA4,0x6BA3,0xA002, 0x6BA2,0x6BA0,0xA01F,0xA010,0xA008,0xA004,0xA002,0x6B9F,0x6B9E,0xA002,0x6B9D,0x6B9C,0xA004,0xA002,0x6B99,0x6B98, 0xA002,0x6B97,0x6B95,0xA008,0xA004,0xA002,0x6B94,0x6B91,0xA002,0x6B90,0x6B8F,0xA004,0xA002,0x6B8E,0x6B8C,0xA001, 0x6B88,0xA010,0xA008,0xA004,0xA002,0x6B85,0x6B80,0xA002,0x6B7F,0x6B7E,0xA004,0xA002,0x6B7D,0x6B7A,0xA002,0x6B78, 0x6B77,0xA008,0xA004,0xA002,0x6B76,0x6B75,0xA002,0x6B74,0x6B73,0xA004,0xA002,0x6B72,0x6B71,0xA002,0x6B70,0x6B6F, 0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x6B6E,0x6B6D,0xA002,0x6B6C,0x6B6B,0xA004,0xA002,0x6B69,0x6B68,0xA002, 0x6B61,0x6B60,0xA008,0xA004,0xA002,0x6B5F,0x6B5E,0xA002,0x6B5D,0x6B5C,0xA004,0xA002,0x6B5B,0x6B5A,0xA002,0x6B58, 0x6B57,0xA010,0xA008,0xA004,0xA002,0x6B56,0x6B55,0xA002,0x6B54,0x6B53,0xA004,0xA002,0x6B52,0x6B51,0xA002,0x6B50, 0x6B4F,0xA008,0xA004,0xA002,0x6B4E,0x6B4D,0xA002,0x6B4B,0x6B4A,0xA004,0xA002,0x6B48,0x6B45,0xA002,0x6B44,0x6B42, 0xA000,0xA010,0xA008,0xA004,0xA002,0x6B41,0x6B40,0xA002,0x6B3F,0x6B3D,0xA004,0xA002,0x6B3C,0x6B3B,0xA002,0x6B38, 0x6B36,0xA008,0xA004,0xA002,0x6B35,0x6B34,0xA002,0x6B33,0x6B31,0xA000,0xA002,0x6B30,0x6B2F,0xA0A2,0xA022,0xA001, 0xA001,0xA010,0xA008,0xA004,0xA002,0x6B2E,0x6B2D,0xA002,0x6B2C,0x6B2B,0xA004,0xA002,0x6B2A,0x6B29,0xA002,0x6B28, 0x6B26,0xA008,0xA004,0xA002,0x6B25,0x6B1F,0xA002,0x6B1E,0x6B1D,0xA004,0xA002,0x6B1C,0x6B1B,0xA002,0x6B1A,0x6B19, 0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x6B18,0x6B17,0xA002,0x6B16,0x6B15,0xA004,0xA002,0x6B14,0x6B13,0xA002, 0x6B12,0x6B11,0xA008,0xA004,0xA002,0x6B10,0x6B0F,0xA002,0x6B0E,0x6B0D,0xA004,0xA002,0x6B0C,0x6B0B,0xA002,0x6B0A, 0x6B09,0xA010,0xA008,0xA004,0xA002,0x6B08,0x6B07,0xA002,0x6B06,0x6B05,0xA004,0xA002,0x6B04,0x6B03,0xA002,0x6B02, 0x6B01,0xA008,0xA004,0xA002,0x6B00,0x6AFF,0xA002,0x6AFE,0x6AFD,0xA004,0xA002,0x6AFC,0x6AFB,0xA002,0x6AFA,0x6AF9, 0xA020,0xA010,0xA008,0xA004,0xA002,0x6AF8,0x6AF7,0xA002,0x6AF6,0x6AF5,0xA004,0xA002,0x6AF4,0x6AF3,0xA002,0x6AF2, 0x6AF1,0xA008,0xA004,0xA002,0x6AF0,0x6AEF,0xA002,0x6AEE,0x6AED,0xA004,0xA002,0x6AEC,0x6AEB,0xA002,0x6AEA,0x6AE9, 0xA010,0xA008,0xA004,0xA002,0x6AE8,0x6AE7,0xA002,0x6AE6,0x6AE5,0xA004,0xA002,0x6AE4,0x6AE3,0xA002,0x6AE2,0x6AE1, 0xA008,0xA004,0xA002,0x6AE0,0x6ADF,0xA002,0x6ADE,0x6ADD,0xA004,0xA002,0x6ADC,0x6ADB,0xA002,0x6ADA,0x6AD9,0xA07D, 0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x6AD8,0xA002,0x6AD7,0x6AD6,0xA004,0xA002,0x6AD5,0x6AD4,0xA002,0x6AD3,0x6AD2, 0xA008,0xA004,0xA002,0x6AD1,0x6AD0,0xA002,0x6ACF,0x6ACE,0xA004,0xA002,0x6ACD,0x6ACC,0xA002,0x6ACB,0x6ACA,0xA010, 0xA008,0xA004,0xA002,0x6AC9,0x6AC8,0xA002,0x6AC7,0x6AC6,0xA004,0xA002,0x6AC5,0x6AC4,0xA002,0x6AC3,0x6AC2,0xA008, 0xA004,0xA002,0x6AC1,0x6AC0,0xA002,0x6ABF,0x6ABE,0xA004,0xA002,0x6ABD,0x6ABC,0xA002,0x6ABB,0x6ABA,0xA020,0xA010, 0xA008,0xA004,0xA002,0x6AB9,0x6AB8,0xA002,0x6AB7,0x6AB6,0xA004,0xA002,0x6AB5,0x6AB4,0xA002,0x6AB3,0x6AB2,0xA008, 0xA004,0xA002,0x6AB1,0x6AB0,0xA002,0x6AAF,0x6AAE,0xA004,0xA002,0x6AAD,0x6AAA,0xA002,0x6AA8,0x6AA7,0xA00F,0xA007, 0xA003,0xA001,0x6AA6,0xA002,0x6AA5,0x6AA4,0xA004,0xA002,0x6AA3,0x6AA2,0xA002,0x6AA1,0x6A9F,0xA008,0xA004,0xA002, 0x6A9E,0x6A9D,0xA002,0x6A9C,0x6A9B,0xA004,0xA002,0x6A9A,0x6A99,0xA002,0x6A98,0x6A96,0xA040,0xA020,0xA010,0xA008, 0xA004,0xA002,0x6A95,0x6A94,0xA002,0x6A93,0x6A92,0xA004,0xA002,0x6A8F,0x6A8D,0xA002,0x6A8C,0x6A8B,0xA008,0xA004, 0xA002,0x6A8A,0x6A89,0xA002,0x6A88,0x6A87,0xA004,0xA002,0x6A86,0x6A85,0xA002,0x6A83,0x6A82,0xA010,0xA008,0xA004, 0xA002,0x6A81,0x6A7F,0xA002,0x6A7E,0x6A7D,0xA004,0xA002,0x6A7B,0x6A7A,0xA002,0x6A78,0x6A77,0xA008,0xA004,0xA002, 0x6A76,0x6A75,0xA002,0x6A74,0x6A73,0xA004,0xA002,0x6A72,0x6A70,0xA002,0x6A6F,0x6A6E,0xA000,0xA010,0xA008,0xA004, 0xA002,0x6A6D,0x6A6C,0xA002,0x6A6B,0x6A6A,0xA004,0xA002,0x6A69,0x6A68,0xA002,0x6A67,0x6A66,0xA008,0xA004,0xA002, 0x6A64,0x6A63,0xA002,0x6A62,0x6A60,0xA004,0xA002,0x6A5F,0x6A5E,0xA002,0x6A5D,0x6A5C,0xA183,0xA09F,0xA01F,0xA001, 0xA001,0xA00D,0xA005,0xA001,0xA002,0x6A5A,0x6A57,0xA004,0xA002,0x6A56,0x6A55,0xA002,0x6A54,0x6A53,0xA008,0xA004, 0xA002,0x6A52,0x6A51,0xA002,0x6A4F,0x6A4E,0xA004,0xA002,0x6A4D,0x6A4C,0xA002,0x6A4B,0x6A4A,0xA040,0xA020,0xA010, 0xA008,0xA004,0xA002,0x6A49,0x6A48,0xA002,0x6A46,0x6A45,0xA004,0xA002,0x6A43,0x6A42,0xA002,0x6A41,0x6A40,0xA008, 0xA004,0xA002,0x6A3F,0x6A3C,0xA002,0x6A3B,0x6A3A,0xA004,0xA002,0x6A39,0x6A38,0xA002,0x6A37,0x6A36,0xA010,0xA008, 0xA004,0xA002,0x6A34,0x6A33,0xA002,0x6A32,0x6A30,0xA004,0xA002,0x6A2E,0x6A2D,0xA002,0x6A2C,0x6A2B,0xA008,0xA004, 0xA002,0x6A29,0x6A27,0xA002,0x6A26,0x6A25,0xA004,0xA002,0x6A24,0x6A23,0xA002,0x6A22,0x6A20,0xA020,0xA010,0xA008, 0xA004,0xA002,0x6A1E,0x6A1D,0xA002,0x6A1C,0x6A1B,0xA004,0xA002,0x6A1A,0x6A19,0xA002,0x6A16,0x6A15,0xA008,0xA004, 0xA002,0x6A14,0x6A13,0xA002,0x6A12,0x6A11,0xA004,0xA002,0x6A10,0x6A0F,0xA002,0x6A0E,0x6A0D,0xA010,0xA008,0xA004, 0xA002,0x6A0C,0x6A0B,0xA002,0x6A09,0x6A08,0xA004,0xA002,0x6A07,0x6A06,0xA002,0x6A05,0x6A04,0xA008,0xA004,0xA002, 0x6A03,0x6A02,0xA002,0x6A01,0x6A00,0xA004,0xA002,0x69FE,0x69FC,0xA002,0x69FB,0x69FA,0xA07D,0xA03E,0xA01E,0xA00E, 0xA006,0xA002,0x69F9,0xA002,0x69F8,0x69F7,0xA004,0xA002,0x69F6,0x69F5,0xA002,0x69F4,0x69F3,0xA008,0xA004,0xA002, 0x69F1,0x69F0,0xA002,0x69EF,0x69EE,0xA004,0xA002,0x69EC,0x69EB,0xA002,0x69EA,0x69E9,0xA010,0xA008,0xA004,0xA002, 0x69E8,0x69E7,0xA002,0x69E6,0x69E5,0xA004,0xA002,0x69E4,0x69E3,0xA002,0x69E2,0x69E1,0xA008,0xA004,0xA002,0x69DE, 0x69DD,0xA002,0x69DC,0x69DA,0xA004,0xA002,0x69D9,0x69D8,0xA002,0x69D7,0x69D6,0xA020,0xA010,0xA008,0xA004,0xA002, 0x69D5,0x69D3,0xA002,0x69D2,0x69D1,0xA004,0xA002,0x69CF,0x69CD,0xA002,0x69CB,0x69C9,0xA008,0xA004,0xA002,0x69C8, 0x69C7,0xA002,0x69C6,0x69C5,0xA004,0xA002,0x69C4,0x69C3,0xA002,0x69C2,0x69C0,0xA00F,0xA007,0xA004,0xA002,0x69BF, 0x69BE,0xA001,0x69BD,0xA004,0xA002,0x69BC,0x69BA,0xA002,0x69B9,0x69B8,0xA008,0xA004,0xA002,0x69B6,0x69B5,0xA002, 0x69B3,0x69B2,0xA004,0xA002,0x69B0,0x69AF,0xA002,0x69AE,0x69AC,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x69AA, 0x69A9,0xA002,0x69A6,0x69A5,0xA004,0xA002,0x69A4,0x69A3,0xA002,0x69A2,0x69A1,0xA008,0xA004,0xA002,0x69A0,0x699F, 0xA002,0x699E,0x699D,0xA004,0xA002,0x699A,0x6999,0xA002,0x6997,0x6996,0xA010,0xA008,0xA004,0xA002,0x6993,0x6992, 0xA002,0x6991,0x6990,0xA004,0xA002,0x698F,0x698E,0xA002,0x698C,0x698B,0xA008,0xA004,0xA002,0x698A,0x6985,0xA002, 0x6983,0x6981,0xA004,0xA002,0x697F,0x697E,0xA002,0x697D,0x697B,0xA020,0xA010,0xA008,0xA004,0xA002,0x697A,0x6976, 0xA002,0x6975,0x6974,0xA004,0xA002,0x6973,0x6972,0xA002,0x6970,0x696F,0xA008,0xA004,0xA002,0x696D,0x696C,0xA002, 0x696A,0x6969,0xA004,0xA002,0x6968,0x6967,0xA002,0x6965,0x6964,0xA000,0xA000,0xA000,0xA002,0x6962,0x6961,0xA09B, 0xA01B,0xA001,0xA001,0xA009,0xA001,0xA004,0xA002,0x695F,0x695C,0xA002,0x695B,0x6959,0xA008,0xA004,0xA002,0x6958, 0x6956,0xA002,0x6955,0x6953,0xA004,0xA002,0x6952,0x6951,0xA002,0x6950,0x694F,0xA040,0xA020,0xA010,0xA008,0xA004, 0xA002,0x694E,0x694D,0xA002,0x694C,0x694B,0xA004,0xA002,0x694A,0x6949,0xA002,0x6948,0x6947,0xA008,0xA004,0xA002, 0x6946,0x6945,0xA002,0x6944,0x6943,0xA004,0xA002,0x6941,0x6940,0xA002,0x693E,0x693C,0xA010,0xA008,0xA004,0xA002, 0x693B,0x693A,0xA002,0x6938,0x6937,0xA004,0xA002,0x6936,0x6935,0xA002,0x6933,0x6932,0xA008,0xA004,0xA002,0x6931, 0x692F,0xA002,0x692E,0x692C,0xA004,0xA002,0x692B,0x692A,0xA002,0x6929,0x6928,0xA020,0xA010,0xA008,0xA004,0xA002, 0x6927,0x6926,0xA002,0x6925,0x6923,0xA004,0xA002,0x6922,0x6921,0xA002,0x691E,0x691D,0xA008,0xA004,0xA002,0x691C, 0x691B,0xA002,0x691A,0x6919,0xA004,0xA002,0x6918,0x6917,0xA002,0x6916,0x6915,0xA010,0xA008,0xA004,0xA002,0x6914, 0x6913,0xA002,0x6911,0x690F,0xA004,0xA002,0x690C,0x690A,0xA002,0x6909,0x6908,0xA008,0xA004,0xA002,0x6907,0x6906, 0xA002,0x6904,0x6903,0xA004,0xA002,0x6902,0x6900,0xA002,0x68FF,0x68FE,0xA07D,0xA03E,0xA01E,0xA00E,0xA006,0xA002, 0x68FD,0xA002,0x68FB,0x68F8,0xA004,0xA002,0x68F7,0x68F6,0xA002,0x68F4,0x68F3,0xA008,0xA004,0xA002,0x68F2,0x68EF, 0xA002,0x68ED,0x68EC,0xA004,0xA002,0x68EB,0x68EA,0xA002,0x68E9,0x68E8,0xA010,0xA008,0xA004,0xA002,0x68E7,0x68E6, 0xA002,0x68E5,0x68E4,0xA004,0xA002,0x68E2,0x68E1,0xA002,0x68DF,0x68DE,0xA008,0xA004,0xA002,0x68DD,0x68DC,0xA002, 0x68DB,0x68D9,0xA004,0xA002,0x68D7,0x68D6,0xA002,0x68D4,0x68D3,0xA020,0xA010,0xA008,0xA004,0xA002,0x68D1,0x68D0, 0xA002,0x68CF,0x68CE,0xA004,0xA002,0x68CC,0x68CA,0xA002,0x68C8,0x68C7,0xA008,0xA004,0xA002,0x68C6,0x68C5,0xA002, 0x68C4,0x68C3,0xA004,0xA002,0x68C1,0x68BF,0xA002,0x68BE,0x68BD,0xA00F,0xA008,0xA004,0xA002,0x68BC,0x68BB,0xA002, 0x68BA,0x68B9,0xA003,0xA001,0x68B8,0xA002,0x68B7,0x68B6,0xA008,0xA004,0xA002,0x68B4,0x68B2,0xA002,0x68B1,0x68AE, 0xA004,0xA002,0x68AC,0x68AB,0xA002,0x68AA,0x68A9,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x68A5,0x68A4,0xA002, 0x68A3,0x68A1,0xA004,0xA002,0x68A0,0x689F,0xA002,0x689E,0x689D,0xA008,0xA004,0xA002,0x689C,0x689B,0xA002,0x689A, 0x6899,0xA004,0xA002,0x6898,0x6896,0xA002,0x6895,0x6894,0xA010,0xA008,0xA004,0xA002,0x6892,0x6891,0xA002,0x6890, 0x688E,0xA004,0xA002,0x688D,0x688C,0xA002,0x688B,0x688A,0xA008,0xA004,0xA002,0x6889,0x6888,0xA002,0x6887,0x6884, 0xA004,0xA002,0x6882,0x6880,0xA002,0x687F,0x687E,0xA020,0xA010,0xA008,0xA004,0xA002,0x687D,0x687C,0xA002,0x687B, 0x687A,0xA004,0xA002,0x6879,0x6878,0xA002,0x6875,0x6873,0xA008,0xA004,0xA002,0x6872,0x6871,0xA002,0x6870,0x686F, 0xA004,0xA002,0x686E,0x686D,0xA002,0x686C,0x686A,0xA000,0xA000,0xA004,0xA002,0x685F,0x685E,0xA002,0x685D,0x685C, 0xA60F,0xA307,0xA183,0xA096,0xA018,0xA001,0xA001,0xA006,0xA001,0xA001,0xA002,0x685B,0x685A,0xA008,0xA004,0xA002, 0x6859,0x6858,0xA002,0x6857,0x6856,0xA004,0xA002,0x6852,0x684F,0xA002,0x684D,0x684B,0xA03E,0xA01E,0xA00E,0xA006, 0xA002,0x6847,0xA002,0x683F,0x683B,0xA004,0xA002,0x683A,0x6836,0xA002,0x6835,0x6834,0xA008,0xA004,0xA002,0x6831, 0x6830,0xA002,0x682F,0x682E,0xA004,0xA002,0x682D,0x682C,0xA002,0x682B,0x6828,0xA010,0xA008,0xA004,0xA002,0x6827, 0x6826,0xA002,0x6825,0x6824,0xA004,0xA002,0x6823,0x6822,0xA002,0x6820,0x681F,0xA008,0xA004,0xA002,0x681E,0x681C, 0xA002,0x681B,0x681A,0xA004,0xA002,0x6819,0x6818,0xA002,0x6815,0x6814,0xA020,0xA010,0xA008,0xA004,0xA002,0x6812, 0x6810,0xA002,0x680D,0x6806,0xA004,0xA002,0x6804,0x6803,0xA002,0x6802,0x6801,0xA008,0xA004,0xA002,0x67FE,0x67FC, 0xA002,0x67FB,0x67FA,0xA004,0xA002,0x67F9,0x67F8,0xA002,0x67F7,0x67F6,0xA010,0xA008,0xA004,0xA002,0x67F5,0x67F2, 0xA002,0x67EE,0x67ED,0xA004,0xA002,0x67EB,0x67EA,0xA002,0x67E8,0x67E7,0xA008,0xA004,0xA002,0x67E6,0x67E4,0xA002, 0x67E3,0x67E1,0xA004,0xA002,0x67DF,0x67DB,0xA002,0x67D7,0x67D6,0xA07D,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x67D5, 0xA002,0x67CE,0x67CD,0xA004,0xA002,0x67CC,0x67CB,0xA002,0x67CA,0x67C9,0xA008,0xA004,0xA002,0x67C8,0x67C7,0xA002, 0x67C6,0x67C5,0xA004,0xA002,0x67C2,0x67C0,0xA002,0x67BF,0x67BE,0xA010,0xA008,0xA004,0xA002,0x67BD,0x67BC,0xA002, 0x67BB,0x67BA,0xA004,0xA002,0x67B9,0x67B4,0xA002,0x67B2,0x67B1,0xA008,0xA004,0xA002,0x67AE,0x67AC,0xA002,0x67A9, 0x67A6,0xA004,0xA002,0x67A4,0x67A1,0xA002,0x67A0,0x679F,0xA020,0xA010,0xA008,0xA004,0xA002,0x679B,0x6799,0xA002, 0x6796,0x6794,0xA004,0xA002,0x6793,0x6792,0xA002,0x6791,0x678F,0xA008,0xA004,0xA002,0x678E,0x678D,0xA002,0x678C, 0x678A,0xA004,0xA002,0x6788,0x6786,0xA002,0x6785,0x6783,0xA00F,0xA008,0xA004,0xA002,0x6782,0x6780,0xA002,0x677D, 0x677B,0xA004,0xA002,0x677A,0x6779,0xA000,0x6778,0xA008,0xA004,0xA002,0x6776,0x6774,0xA002,0x6771,0x676E,0xA004, 0xA002,0x676C,0x676B,0xA002,0x6767,0x6766,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x6764,0x6763,0xA002,0x6762, 0x675D,0xA004,0xA002,0x675B,0x675A,0xA002,0x6759,0x6758,0xA008,0xA004,0xA002,0x6757,0x6755,0xA002,0x6754,0x6752, 0xA004,0xA002,0x674D,0x674B,0xA002,0x674A,0x6747,0xA010,0xA008,0xA004,0xA002,0x6745,0x6744,0xA002,0x6741,0x673F, 0xA004,0xA002,0x673E,0x673C,0xA002,0x673B,0x6739,0xA008,0xA004,0xA002,0x6738,0x6737,0xA002,0x6736,0x6733,0xA004, 0xA002,0x6732,0x6730,0xA002,0x672E,0x6729,0xA020,0xA010,0xA008,0xA004,0xA002,0x6727,0x6725,0xA002,0x6724,0x6723, 0xA004,0xA002,0x6722,0x6721,0xA002,0x6720,0x671E,0xA008,0xA004,0xA002,0x671C,0x671A,0xA002,0x6719,0x6718,0xA004, 0xA002,0x6716,0x6713,0xA002,0x6712,0x6711,0xA000,0xA008,0xA004,0xA002,0x670F,0x670E,0xA002,0x670C,0x6707,0xA004, 0xA002,0x6706,0x6705,0xA000,0x6704,0xA092,0xA012,0xA001,0xA001,0xA001,0xA007,0xA003,0xA001,0x6703,0xA002,0x6702, 0x6701,0xA004,0xA002,0x66FD,0x66FB,0xA002,0x66FA,0x66F8,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x66F6,0x66F5, 0xA002,0x66F1,0x66EF,0xA004,0xA002,0x66EE,0x66ED,0xA002,0x66EC,0x66EB,0xA008,0xA004,0xA002,0x66EA,0x66E8,0xA002, 0x66E7,0x66E5,0xA004,0xA002,0x66E4,0x66E3,0xA002,0x66E2,0x66E1,0xA010,0xA008,0xA004,0xA002,0x66E0,0x66DF,0xA002, 0x66DE,0x66DA,0xA004,0xA002,0x66D8,0x66D7,0xA002,0x66D6,0x66D5,0xA008,0xA004,0xA002,0x66D4,0x66D3,0xA002,0x66D2, 0x66D1,0xA004,0xA002,0x66D0,0x66CF,0xA002,0x66CE,0x66CD,0xA020,0xA010,0xA008,0xA004,0xA002,0x66CC,0x66CB,0xA002, 0x66CA,0x66C9,0xA004,0xA002,0x66C8,0x66C7,0xA002,0x66C6,0x66C5,0xA008,0xA004,0xA002,0x66C4,0x66C3,0xA002,0x66C2, 0x66C1,0xA004,0xA002,0x66C0,0x66BF,0xA002,0x66BD,0x66BC,0xA010,0xA008,0xA004,0xA002,0x66BB,0x66BA,0xA002,0x66B8, 0x66B7,0xA004,0xA002,0x66B6,0x66B5,0xA002,0x66B3,0x66B2,0xA008,0xA004,0xA002,0x66B1,0x66B0,0xA002,0x66AF,0x66AD, 0xA004,0xA002,0x66AC,0x66AB,0xA002,0x66AA,0x66A9,0xA07D,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x66A6,0xA002,0x66A5, 0x66A4,0xA004,0xA002,0x66A3,0x66A2,0xA002,0x66A1,0x66A0,0xA008,0xA004,0xA002,0x669F,0x669E,0xA002,0x669C,0x669B, 0xA004,0xA002,0x669A,0x6699,0xA002,0x6698,0x6695,0xA010,0xA008,0xA004,0xA002,0x6694,0x6693,0xA002,0x6692,0x6690, 0xA004,0xA002,0x668F,0x668E,0xA002,0x668D,0x668B,0xA008,0xA004,0xA002,0x668A,0x6689,0xA002,0x6688,0x6686,0xA004, 0xA002,0x6685,0x6683,0xA002,0x6681,0x6680,0xA020,0xA010,0xA008,0xA004,0xA002,0x667F,0x667D,0xA002,0x667C,0x667B, 0xA004,0xA002,0x6679,0x6678,0xA002,0x6675,0x6673,0xA008,0xA004,0xA002,0x6672,0x6671,0xA002,0x666D,0x666C,0xA004, 0xA002,0x666B,0x666A,0xA002,0x6669,0x6667,0xA010,0xA008,0xA004,0xA002,0x6665,0x6663,0xA002,0x6662,0x6660,0xA004, 0xA002,0x665E,0x665D,0xA002,0x665C,0x665B,0xA007,0xA003,0xA000,0x6659,0xA002,0x6658,0x6651,0xA004,0xA002,0x6650, 0x664E,0xA002,0x664D,0x664A,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x6649,0x6648,0xA002,0x6647,0x6646,0xA004, 0xA002,0x6645,0x6644,0xA002,0x6642,0x6640,0xA008,0xA004,0xA002,0x663F,0x663D,0xA002,0x663B,0x663A,0xA004,0xA002, 0x6639,0x6638,0xA002,0x6637,0x6633,0xA010,0xA008,0xA004,0xA002,0x6632,0x6630,0xA002,0x662E,0x662C,0xA004,0xA002, 0x662B,0x662A,0xA002,0x6629,0x6626,0xA008,0xA004,0xA002,0x6624,0x6623,0xA002,0x6622,0x6621,0xA004,0xA002,0x661E, 0x661C,0xA002,0x661B,0x661A,0xA020,0xA010,0xA008,0xA004,0xA002,0x6618,0x6617,0xA002,0x6616,0x6612,0xA004,0xA002, 0x6611,0x6610,0xA002,0x660D,0x660B,0xA008,0xA004,0xA002,0x6609,0x6608,0xA002,0x6607,0x6605,0xA004,0xA002,0x6604, 0x6601,0xA002,0x65FF,0x65FE,0xA010,0xA008,0xA004,0xA002,0x65FD,0x65FC,0xA002,0x65FB,0x65F9,0xA004,0xA002,0x65F8, 0x65F5,0xA002,0x65F4,0x65F3,0xA000,0xA000,0xA000,0x65F2,0xA184,0xA08F,0xA00F,0xA001,0xA001,0xA001,0xA004,0xA001, 0xA001,0x65EB,0xA004,0xA002,0x65EA,0x65E4,0xA002,0x65E3,0x65E1,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x65DF, 0x65DE,0xA002,0x65DD,0x65DC,0xA004,0xA002,0x65DB,0x65DA,0xA002,0x65D9,0x65D8,0xA008,0xA004,0xA002,0x65D5,0x65D4, 0xA002,0x65D3,0x65D1,0xA004,0xA002,0x65D0,0x65CD,0xA002,0x65CA,0x65C9,0xA010,0xA008,0xA004,0xA002,0x65C8,0x65C7, 0xA002,0x65C2,0x65C0,0xA004,0xA002,0x65BF,0x65BE,0xA002,0x65BB,0x65BA,0xA008,0xA004,0xA002,0x65B8,0x65B7,0xA002, 0x65B6,0x65B5,0xA004,0xA002,0x65B4,0x65B3,0xA002,0x65B2,0x65B1,0xA020,0xA010,0xA008,0xA004,0xA002,0x65AE,0x65AC, 0xA002,0x65AA,0x65A8,0xA004,0xA002,0x65A6,0x65A3,0xA002,0x65A2,0x65A0,0xA008,0xA004,0xA002,0x659E,0x659D,0xA002, 0x659A,0x6598,0xA004,0xA002,0x6596,0x6595,0xA002,0x6594,0x6592,0xA010,0xA008,0xA004,0xA002,0x658F,0x658E,0xA002, 0x658D,0x658A,0xA004,0xA002,0x6589,0x6588,0xA002,0x6586,0x6585,0xA008,0xA004,0xA002,0x6584,0x6583,0xA002,0x6582, 0x6581,0xA004,0xA002,0x6580,0x657F,0xA002,0x657E,0x657D,0xA07D,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x657C,0xA002, 0x657B,0x657A,0xA004,0xA002,0x6579,0x6578,0xA002,0x6576,0x6575,0xA008,0xA004,0xA002,0x6573,0x6571,0xA002,0x656F, 0x656E,0xA004,0xA002,0x656D,0x656A,0xA002,0x6569,0x6568,0xA010,0xA008,0xA004,0xA002,0x6567,0x6565,0xA002,0x6564, 0x6561,0xA004,0xA002,0x6560,0x655F,0xA002,0x655C,0x655A,0xA008,0xA004,0xA002,0x6558,0x6557,0xA002,0x6554,0x6553, 0xA004,0xA002,0x6552,0x6550,0xA002,0x654E,0x654D,0xA020,0xA010,0xA008,0xA004,0xA002,0x654B,0x654A,0xA002,0x6547, 0x6546,0xA004,0xA002,0x6544,0x6543,0xA002,0x6542,0x6541,0xA008,0xA004,0xA002,0x6540,0x653D,0xA002,0x653C,0x653A, 0xA004,0xA002,0x6537,0x6533,0xA002,0x6532,0x6531,0xA010,0xA008,0xA004,0xA002,0x6530,0x652D,0xA002,0x652C,0x652A, 0xA004,0xA002,0x6529,0x6528,0xA002,0x6527,0x6526,0xA007,0xA004,0xA002,0x6524,0x6523,0xA000,0x6522,0xA004,0xA002, 0x6521,0x6520,0xA002,0x651F,0x651E,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x651D,0x651C,0xA002,0x651B,0x651A, 0xA004,0xA002,0x6519,0x6517,0xA002,0x6516,0x6515,0xA008,0xA004,0xA002,0x6514,0x6513,0xA002,0x6511,0x6510,0xA004, 0xA002,0x650F,0x650E,0xA002,0x650D,0x650C,0xA010,0xA008,0xA004,0xA002,0x650B,0x650A,0xA002,0x6508,0x6507,0xA004, 0xA002,0x6506,0x6505,0xA002,0x6504,0x6503,0xA008,0xA004,0xA002,0x6502,0x6501,0xA002,0x64FF,0x64FE,0xA004,0xA002, 0x64FD,0x64FC,0xA002,0x64FB,0x64FA,0xA020,0xA010,0xA008,0xA004,0xA002,0x64F9,0x64F8,0xA002,0x64F7,0x64F6,0xA004, 0xA002,0x64F5,0x64F4,0xA002,0x64F3,0x64F2,0xA008,0xA004,0xA002,0x64F1,0x64F0,0xA002,0x64EF,0x64EE,0xA004,0xA002, 0x64ED,0x64EC,0xA002,0x64EB,0x64EA,0xA010,0xA008,0xA004,0xA002,0x64E9,0x64E8,0xA002,0x64E7,0x64E5,0xA004,0xA002, 0x64E3,0x64E1,0xA002,0x64E0,0x64DF,0xA000,0xA004,0xA002,0x64DD,0x64DC,0xA000,0x64DB,0xA08B,0xA00B,0xA001,0xA001, 0xA001,0xA001,0xA003,0xA001,0x64DA,0xA002,0x64D9,0x64D6,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x64D5,0x64D4, 0xA002,0x64D3,0x64D1,0xA004,0xA002,0x64CF,0x64CC,0xA002,0x64CB,0x64CA,0xA008,0xA004,0xA002,0x64C9,0x64C8,0xA002, 0x64C7,0x64C6,0xA004,0xA002,0x64C4,0x64C3,0xA002,0x64C1,0x64BF,0xA010,0xA008,0xA004,0xA002,0x64BE,0x64BD,0xA002, 0x64BB,0x64B9,0xA004,0xA002,0x64B6,0x64B4,0xA002,0x64B3,0x64B2,0xA008,0xA004,0xA002,0x64B1,0x64AF,0xA002,0x64AB, 0x64AA,0xA004,0xA002,0x64A8,0x64A7,0xA002,0x64A6,0x64A5,0xA020,0xA010,0xA008,0xA004,0xA002,0x64A3,0x64A2,0xA002, 0x64A1,0x64A0,0xA004,0xA002,0x649F,0x649D,0xA002,0x649C,0x649B,0xA008,0xA004,0xA002,0x649A,0x6498,0xA002,0x6497, 0x6494,0xA004,0xA002,0x6493,0x6490,0xA002,0x648F,0x648E,0xA010,0xA008,0xA004,0xA002,0x648D,0x648C,0xA002,0x648B, 0x648A,0xA004,0xA002,0x6489,0x6488,0xA002,0x6486,0x6483,0xA008,0xA004,0xA002,0x6481,0x6480,0xA002,0x647F,0x647E, 0xA004,0xA002,0x647D,0x647C,0xA002,0x647B,0x6477,0xA07D,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x6476,0xA002,0x6475, 0x6474,0xA004,0xA002,0x6473,0x6472,0xA002,0x6471,0x6470,0xA008,0xA004,0xA002,0x646F,0x646E,0xA002,0x646C,0x646B, 0xA004,0xA002,0x646A,0x6468,0xA002,0x6466,0x6465,0xA010,0xA008,0xA004,0xA002,0x6464,0x6463,0xA002,0x6462,0x6461, 0xA004,0xA002,0x6460,0x645F,0xA002,0x645D,0x645C,0xA008,0xA004,0xA002,0x645B,0x645A,0xA002,0x6459,0x6457,0xA004, 0xA002,0x6456,0x6455,0xA002,0x6453,0x6451,0xA020,0xA010,0xA008,0xA004,0xA002,0x6450,0x644F,0xA002,0x644E,0x644D, 0xA004,0xA002,0x644C,0x644B,0xA002,0x6449,0x6443,0xA008,0xA004,0xA002,0x6442,0x6440,0xA002,0x643E,0x643C,0xA004, 0xA002,0x643B,0x6439,0xA002,0x6438,0x6437,0xA010,0xA008,0xA004,0xA002,0x6436,0x6435,0xA002,0x6433,0x6432,0xA004, 0xA002,0x6431,0x6430,0xA002,0x642F,0x642E,0xA008,0xA004,0xA002,0x642B,0x6429,0xA002,0x6428,0x6427,0xA003,0xA000, 0x6425,0xA002,0x6424,0x6423,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x6422,0x641F,0xA002,0x641D,0x641A,0xA004, 0xA002,0x6419,0x6418,0xA002,0x6417,0x6416,0xA008,0xA004,0xA002,0x6415,0x6412,0xA002,0x6411,0x640E,0xA004,0xA002, 0x640D,0x640A,0xA002,0x6409,0x6408,0xA010,0xA008,0xA004,0xA002,0x6407,0x6406,0xA002,0x6404,0x6403,0xA004,0xA002, 0x63FE,0x63FC,0xA002,0x63FB,0x63FA,0xA008,0xA004,0xA002,0x63F9,0x63F7,0xA002,0x63F5,0x63F3,0xA004,0xA002,0x63F1, 0x63F0,0xA002,0x63EF,0x63EE,0xA020,0xA010,0xA008,0xA004,0xA002,0x63EC,0x63EB,0xA002,0x63E8,0x63E7,0xA004,0xA002, 0x63E6,0x63E5,0xA002,0x63E4,0x63E2,0xA008,0xA004,0xA002,0x63DF,0x63DD,0xA002,0x63DC,0x63DB,0xA004,0xA002,0x63DA, 0x63D9,0xA002,0x63D8,0x63D7,0xA010,0xA008,0xA004,0xA002,0x63D5,0x63D4,0xA002,0x63D3,0x63D1,0xA004,0xA002,0x63CC, 0x63CB,0xA002,0x63CA,0x63C8,0xA008,0xA004,0xA002,0x63C7,0x63C5,0xA002,0x63C3,0x63C2,0xA000,0xA000,0x63C1,0xA301, 0xA184,0xA088,0xA008,0xA001,0xA001,0xA001,0xA001,0xA001,0xA001,0x63C0,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002, 0x63BF,0x63BD,0xA002,0x63BB,0x63B9,0xA004,0xA002,0x63B6,0x63B5,0xA002,0x63B2,0x63B1,0xA008,0xA004,0xA002,0x63AF, 0x63AB,0xA002,0x63A6,0x63A4,0xA004,0xA002,0x63A1,0x639F,0xA002,0x639E,0x639D,0xA010,0xA008,0xA004,0xA002,0x639C, 0x639B,0xA002,0x639A,0x6399,0xA004,0xA002,0x6397,0x6395,0xA002,0x6394,0x6393,0xA008,0xA004,0xA002,0x6391,0x638D, 0xA002,0x638B,0x6386,0xA004,0xA002,0x6385,0x6384,0xA002,0x6383,0x6381,0xA020,0xA010,0xA008,0xA004,0xA002,0x637F, 0x637E,0xA002,0x637D,0x637C,0xA004,0xA002,0x6379,0x6378,0xA002,0x6375,0x6374,0xA008,0xA004,0xA002,0x6373,0x6372, 0xA002,0x6370,0x636F,0xA004,0xA002,0x636C,0x636B,0xA002,0x636A,0x6368,0xA010,0xA008,0xA004,0xA002,0x6366,0x6365, 0xA002,0x6364,0x6360,0xA004,0xA002,0x635D,0x635C,0xA002,0x635B,0x635A,0xA008,0xA004,0xA002,0x6359,0x6358,0xA002, 0x6357,0x6356,0xA004,0xA002,0x6354,0x6353,0xA002,0x6352,0x6351,0xA07D,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x634A, 0xA002,0x6348,0x6347,0xA004,0xA002,0x6344,0x6341,0xA002,0x6340,0x633F,0xA008,0xA004,0xA002,0x633E,0x633C,0xA002, 0x633B,0x6338,0xA004,0xA002,0x6337,0x6336,0xA002,0x6335,0x6334,0xA010,0xA008,0xA004,0xA002,0x6333,0x6331,0xA002, 0x6330,0x632E,0xA004,0xA002,0x632D,0x632C,0xA002,0x6329,0x6327,0xA008,0xA004,0xA002,0x6326,0x631C,0xA002,0x6319, 0x6318,0xA004,0xA002,0x6317,0x6315,0xA002,0x6314,0x6313,0xA020,0xA010,0xA008,0xA004,0xA002,0x6312,0x6310,0xA002, 0x630F,0x630D,0xA004,0xA002,0x630C,0x630B,0xA002,0x630A,0x6306,0xA008,0xA004,0xA002,0x6305,0x6304,0xA002,0x6303, 0x6300,0xA004,0xA002,0x62FB,0x62FA,0xA002,0x62F9,0x62F8,0xA010,0xA008,0xA004,0xA002,0x62F5,0x62F2,0xA002,0x62F0, 0x62EB,0xA004,0xA002,0x62EA,0x62E4,0xA002,0x62E1,0x62E0,0xA008,0xA004,0xA002,0x62DE,0x62DD,0xA002,0x62D5,0x62D1, 0xA004,0xA002,0x62CF,0x62CB,0xA000,0x62C3,0xA040,0xA020,0xA010,0xA008,0xA004,0xA002,0x62C1,0x62C0,0xA002,0x62BE, 0x62BA,0xA004,0xA002,0x62B8,0x62B7,0xA002,0x62B6,0x62B4,0xA008,0xA004,0xA002,0x62B3,0x62B2,0xA002,0x62B0,0x62AF, 0xA004,0xA002,0x62AE,0x62AD,0xA002,0x62AA,0x62A9,0xA010,0xA008,0xA004,0xA002,0x62A7,0x62A6,0xA002,0x62A3,0x629E, 0xA004,0xA002,0x629D,0x629C,0xA002,0x6299,0x6294,0xA008,0xA004,0xA002,0x6290,0x628F,0xA002,0x628E,0x628D,0xA004, 0xA002,0x628C,0x628B,0xA002,0x6288,0x6287,0xA020,0xA010,0xA008,0xA004,0xA002,0x6286,0x6285,0xA002,0x6283,0x6282, 0xA004,0xA002,0x6281,0x627D,0xA002,0x627B,0x627A,0xA008,0xA004,0xA002,0x6278,0x6277,0xA002,0x6275,0x6274,0xA004, 0xA002,0x6272,0x6271,0xA002,0x6268,0x6265,0xA010,0xA008,0xA004,0xA002,0x6264,0x6262,0xA002,0x6261,0x6260,0xA004, 0xA002,0x625F,0x625E,0xA002,0x625D,0x625C,0xA008,0xA004,0xA002,0x625A,0x6259,0xA002,0x6257,0x6256,0xA004,0xA002, 0x6255,0x6250,0xA000,0x624F,0xA080,0xA001,0xA03F,0xA01F,0xA00F,0xA007,0xA003,0xA001,0x624A,0xA002,0x6246,0x6245, 0xA004,0xA002,0x6244,0x6242,0xA002,0x623C,0x623B,0xA008,0xA004,0xA002,0x623A,0x6239,0xA002,0x6238,0x6236,0xA004, 0xA002,0x6235,0x6232,0xA002,0x6231,0x6230,0xA010,0xA008,0xA004,0xA002,0x622F,0x622D,0xA002,0x622B,0x6229,0xA004, 0xA002,0x6228,0x6227,0xA002,0x6226,0x6223,0xA008,0xA004,0xA002,0x6220,0x621E,0xA002,0x621D,0x621C,0xA004,0xA002, 0x6219,0x6214,0xA002,0x6213,0x6209,0xA020,0xA010,0xA008,0xA004,0xA002,0x6207,0x6205,0xA002,0x6204,0x6203,0xA004, 0xA002,0x6202,0x6201,0xA002,0x6200,0x61FE,0xA008,0xA004,0xA002,0x61FD,0x61FC,0xA002,0x61FB,0x61FA,0xA004,0xA002, 0x61F9,0x61F8,0xA002,0x61F7,0x61F6,0xA010,0xA008,0xA004,0xA002,0x61F4,0x61F3,0xA002,0x61F2,0x61F1,0xA004,0xA002, 0x61F0,0x61EF,0xA002,0x61EE,0x61ED,0xA008,0xA004,0xA002,0x61EC,0x61EB,0xA002,0x61EA,0x61E9,0xA004,0xA002,0x61E8, 0x61E7,0xA002,0x61E5,0x61E4,0xA07E,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x61E3,0xA002,0x61E2,0x61E1,0xA004,0xA002, 0x61E0,0x61DF,0xA002,0x61DE,0x61DD,0xA008,0xA004,0xA002,0x61DC,0x61DB,0xA002,0x61DA,0x61D9,0xA004,0xA002,0x61D8, 0x61D7,0xA002,0x61D6,0x61D5,0xA010,0xA008,0xA004,0xA002,0x61D3,0x61D0,0xA002,0x61CF,0x61CE,0xA004,0xA002,0x61CD, 0x61CC,0xA002,0x61C9,0x61C7,0xA008,0xA004,0xA002,0x61C6,0x61C5,0xA002,0x61C4,0x61C3,0xA004,0xA002,0x61C1,0x61C0, 0xA002,0x61BF,0x61BD,0xA020,0xA010,0xA008,0xA004,0xA002,0x61BC,0x61BB,0xA002,0x61BA,0x61B9,0xA004,0xA002,0x61B8, 0x61B6,0xA002,0x61B5,0x61B4,0xA008,0xA004,0xA002,0x61B3,0x61B2,0xA002,0x61B1,0x61B0,0xA004,0xA002,0x61AF,0x61AE, 0xA002,0x61AD,0x61AB,0xA010,0xA008,0xA004,0xA002,0x61AA,0x61A6,0xA002,0x61A5,0x61A4,0xA004,0xA002,0x61A3,0x61A2, 0xA002,0x61A1,0x61A0,0xA008,0xA004,0xA002,0x619F,0x619E,0xA002,0x619C,0x619B,0xA004,0xA002,0x619A,0x6199,0xA002, 0x6198,0x6197,0xA03F,0xA01F,0xA00F,0xA007,0xA003,0xA000,0x6196,0xA002,0x6195,0x6193,0xA004,0xA002,0x6192,0x6191, 0xA002,0x6190,0x618F,0xA008,0xA004,0xA002,0x618D,0x618C,0xA002,0x618A,0x6189,0xA004,0xA002,0x6188,0x6187,0xA002, 0x6186,0x6185,0xA010,0xA008,0xA004,0xA002,0x6184,0x6183,0xA002,0x6182,0x6181,0xA004,0xA002,0x6180,0x617F,0xA002, 0x617E,0x617D,0xA008,0xA004,0xA002,0x617C,0x617B,0xA002,0x617A,0x6179,0xA004,0xA002,0x6178,0x6176,0xA002,0x6174, 0x6173,0xA020,0xA010,0xA008,0xA004,0xA002,0x6172,0x6171,0xA002,0x616F,0x616E,0xA004,0xA002,0x616D,0x616C,0xA002, 0x616B,0x616A,0xA008,0xA004,0xA002,0x6169,0x6166,0xA002,0x6165,0x6164,0xA004,0xA002,0x6163,0x6161,0xA002,0x6160, 0x615F,0xA010,0xA008,0xA004,0xA002,0x615E,0x615C,0xA002,0x615B,0x615A,0xA004,0xA002,0x6159,0x6158,0xA002,0x6157, 0x6156,0xA008,0xA004,0xA002,0x6154,0x6153,0xA002,0x6152,0x6150,0xA004,0xA002,0x614F,0x614D,0xA002,0x614B,0x6149, 0xA180,0xA083,0xA007,0xA000,0xA000,0xA000,0xA000,0xA000,0x6147,0xA03C,0xA01C,0xA00C,0xA004,0xA001,0xA001,0x6146, 0xA004,0xA002,0x6145,0x6144,0xA002,0x6143,0x6142,0xA008,0xA004,0xA002,0x6141,0x6140,0xA002,0x613E,0x613D,0xA004, 0xA002,0x613C,0x613B,0xA002,0x613A,0x6139,0xA010,0xA008,0xA004,0xA002,0x6138,0x6137,0xA002,0x6136,0x6135,0xA004, 0xA002,0x6134,0x6133,0xA002,0x6132,0x6131,0xA008,0xA004,0xA002,0x6130,0x612F,0xA002,0x612E,0x612D,0xA004,0xA002, 0x612C,0x612A,0xA002,0x6129,0x6128,0xA020,0xA010,0xA008,0xA004,0xA002,0x6125,0x6122,0xA002,0x6121,0x611E,0xA004, 0xA002,0x611D,0x611C,0xA002,0x611B,0x6119,0xA008,0xA004,0xA002,0x6118,0x6117,0xA002,0x6116,0x6114,0xA004,0xA002, 0x6113,0x6112,0xA002,0x6111,0x6110,0xA010,0xA008,0xA004,0xA002,0x610C,0x610B,0xA002,0x610A,0x6107,0xA004,0xA002, 0x6105,0x6104,0xA002,0x6103,0x6102,0xA008,0xA004,0xA002,0x60FF,0x60FE,0xA002,0x60FD,0x60FC,0xA004,0xA002,0x60FB, 0x60F8,0xA002,0x60F7,0x60F5,0xA07E,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x60F2,0xA002,0x60F1,0x60EA,0xA004,0xA002, 0x60E5,0x60E4,0xA002,0x60E3,0x60E2,0xA008,0xA004,0xA002,0x60E1,0x60DE,0xA002,0x60DB,0x60D9,0xA004,0xA002,0x60D7, 0x60D6,0xA002,0x60D4,0x60D3,0xA010,0xA008,0xA004,0xA002,0x60D2,0x60D0,0xA002,0x60CF,0x60CE,0xA004,0xA002,0x60CD, 0x60CC,0xA002,0x60C9,0x60C8,0xA008,0xA004,0xA002,0x60C7,0x60C4,0xA002,0x60C3,0x60C2,0xA004,0xA002,0x60C1,0x60C0, 0xA002,0x60BF,0x60BE,0xA020,0xA010,0xA008,0xA004,0xA002,0x60BD,0x60BA,0xA002,0x60B9,0x60B7,0xA004,0xA002,0x60B6, 0x60B5,0xA002,0x60B3,0x60B0,0xA008,0xA004,0xA002,0x60AE,0x60AA,0xA002,0x60A9,0x60A7,0xA004,0xA002,0x60A5,0x60A4, 0xA002,0x60A2,0x60A1,0xA010,0xA008,0xA004,0xA002,0x609E,0x609C,0xA002,0x6099,0x6098,0xA004,0xA002,0x6097,0x6095, 0xA002,0x6093,0x6091,0xA008,0xA004,0xA002,0x6090,0x608F,0xA002,0x608E,0x608B,0xA004,0xA002,0x608A,0x6088,0xA002, 0x6087,0x6086,0xA03F,0xA01F,0xA00F,0xA007,0xA004,0xA002,0x6085,0x6082,0xA000,0x6081,0xA004,0xA002,0x6080,0x607E, 0xA002,0x6077,0x6075,0xA008,0xA004,0xA002,0x6074,0x6072,0xA002,0x6071,0x606E,0xA004,0xA002,0x6066,0x6065,0xA002, 0x6061,0x6060,0xA010,0xA008,0xA004,0xA002,0x605F,0x605E,0xA002,0x605C,0x605B,0xA004,0xA002,0x6058,0x6057,0xA002, 0x6056,0x6054,0xA008,0xA004,0xA002,0x6053,0x6051,0xA002,0x604F,0x604E,0xA004,0xA002,0x604C,0x604A,0xA002,0x6049, 0x6048,0xA020,0xA010,0xA008,0xA004,0xA002,0x6047,0x6046,0xA002,0x6045,0x6044,0xA004,0xA002,0x6040,0x603E,0xA002, 0x603D,0x603A,0xA008,0xA004,0xA002,0x6039,0x6038,0xA002,0x6037,0x6036,0xA004,0xA002,0x6034,0x6033,0xA002,0x6032, 0x6031,0xA010,0xA008,0xA004,0xA002,0x6030,0x602E,0xA002,0x602D,0x602C,0xA004,0xA002,0x6024,0x6023,0xA002,0x6022, 0x601F,0xA008,0xA004,0xA002,0x601E,0x601A,0xA002,0x6018,0x6017,0xA004,0xA002,0x6013,0x6011,0xA002,0x6010,0x600C, 0xA082,0xA00A,0xA000,0xA000,0xA000,0xA000,0xA002,0x600B,0xA002,0x6009,0x6008,0xA038,0xA018,0xA008,0xA001,0xA003, 0xA001,0x6007,0xA002,0x5FFC,0x5FFA,0xA008,0xA004,0xA002,0x5FF9,0x5FF7,0xA002,0x5FF6,0x5FF4,0xA004,0xA002,0x5FF3, 0x5FF2,0xA002,0x5FF0,0x5FEF,0xA010,0xA008,0xA004,0xA002,0x5FEC,0x5FE9,0xA002,0x5FE8,0x5FE6,0xA004,0xA002,0x5FE5, 0x5FE3,0xA002,0x5FE2,0x5FDF,0xA008,0xA004,0xA002,0x5FDE,0x5FDC,0xA002,0x5FDB,0x5FDA,0xA004,0xA002,0x5FD5,0x5FD4, 0xA002,0x5FD3,0x5FCE,0xA020,0xA010,0xA008,0xA004,0xA002,0x5FCB,0x5FCA,0xA002,0x5FC8,0x5FC7,0xA004,0xA002,0x5FC2, 0x5FC1,0xA002,0x5FC0,0x5FBF,0xA008,0xA004,0xA002,0x5FBE,0x5FBB,0xA002,0x5FBA,0x5FB9,0xA004,0xA002,0x5FB8,0x5FB6, 0xA002,0x5FB4,0x5FB3,0xA010,0xA008,0xA004,0xA002,0x5FB2,0x5FB1,0xA002,0x5FB0,0x5FAF,0xA004,0xA002,0x5FAC,0x5FAB, 0xA002,0x5FA9,0x5FA7,0xA008,0xA004,0xA002,0x5FA6,0x5FA5,0xA002,0x5FA4,0x5FA3,0xA004,0xA002,0x5FA2,0x5FA0,0xA002, 0x5F9F,0x5F9E,0xA07E,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x5F9D,0xA002,0x5F9B,0x5F9A,0xA004,0xA002,0x5F96,0x5F94, 0xA002,0x5F93,0x5F91,0xA008,0xA004,0xA002,0x5F8F,0x5F8E,0xA002,0x5F8D,0x5F86,0xA004,0xA002,0x5F83,0x5F7F,0xA002, 0x5F7E,0x5F7D,0xA010,0xA008,0xA004,0xA002,0x5F7A,0x5F78,0xA002,0x5F76,0x5F75,0xA004,0xA002,0x5F74,0x5F72,0xA002, 0x5F6F,0x5F6E,0xA008,0xA004,0xA002,0x5F6B,0x5F68,0xA002,0x5F67,0x5F65,0xA004,0xA002,0x5F63,0x5F60,0xA002,0x5F5F, 0x5F5E,0xA020,0xA010,0xA008,0xA004,0xA002,0x5F5C,0x5F5B,0xA002,0x5F5A,0x5F59,0xA004,0xA002,0x5F54,0x5F51,0xA002, 0x5F4F,0x5F4E,0xA008,0xA004,0xA002,0x5F4D,0x5F4C,0xA002,0x5F4B,0x5F4A,0xA004,0xA002,0x5F49,0x5F48,0xA002,0x5F47, 0x5F46,0xA010,0xA008,0xA004,0xA002,0x5F45,0x5F44,0xA002,0x5F43,0x5F42,0xA004,0xA002,0x5F41,0x5F3F,0xA002,0x5F3E, 0x5F3D,0xA008,0xA004,0xA002,0x5F3B,0x5F38,0xA002,0x5F37,0x5F36,0xA004,0xA002,0x5F35,0x5F34,0xA002,0x5F33,0x5F32, 0xA03F,0xA01F,0xA00F,0xA008,0xA004,0xA002,0x5F30,0x5F2E,0xA002,0x5F2C,0x5F2B,0xA003,0xA000,0x5F28,0xA002,0x5F24, 0x5F23,0xA008,0xA004,0xA002,0x5F22,0x5F21,0xA002,0x5F1E,0x5F1D,0xA004,0xA002,0x5F1C,0x5F1A,0xA002,0x5F19,0x5F16, 0xA010,0xA008,0xA004,0xA002,0x5F14,0x5F12,0xA002,0x5F10,0x5F0E,0xA004,0xA002,0x5F0D,0x5F0C,0xA002,0x5F09,0x5F07, 0xA008,0xA004,0xA002,0x5F06,0x5F05,0xA002,0x5EFD,0x5EFC,0xA004,0xA002,0x5EFB,0x5EF9,0xA002,0x5EF8,0x5EF5,0xA020, 0xA010,0xA008,0xA004,0xA002,0x5EF3,0x5EF2,0xA002,0x5EF1,0x5EF0,0xA004,0xA002,0x5EEF,0x5EEE,0xA002,0x5EED,0x5EEC, 0xA008,0xA004,0xA002,0x5EEB,0x5EE9,0xA002,0x5EE7,0x5EE6,0xA004,0xA002,0x5EE5,0x5EE4,0xA002,0x5EE3,0x5EE2,0xA010, 0xA008,0xA004,0xA002,0x5EE1,0x5EE0,0xA002,0x5EDF,0x5EDE,0xA004,0xA002,0x5EDD,0x5EDC,0xA002,0x5EDA,0x5ED9,0xA008, 0xA004,0xA002,0x5ED8,0x5ED7,0xA002,0x5ED5,0x5ED4,0xA004,0xA002,0x5ED0,0x5ECF,0xA002,0x5ECE,0x5ECD,0xABF6,0xA5FB, 0xA2FC,0xA17C,0xA07F,0xA00E,0xA000,0xA000,0xA000,0xA006,0xA002,0x5ECC,0xA002,0x5ECB,0x5EC8,0xA000,0xA002,0x5EC7, 0x5EC6,0xA031,0xA011,0xA001,0xA008,0xA004,0xA002,0x5EC5,0x5EC4,0xA002,0x5EC3,0x5EC2,0xA004,0xA002,0x5EC1,0x5EC0, 0xA002,0x5EBF,0x5EBD,0xA010,0xA008,0xA004,0xA002,0x5EBC,0x5EBB,0xA002,0x5EBA,0x5EB4,0xA004,0xA002,0x5EB2,0x5EB1, 0xA002,0x5EB0,0x5EAF,0xA008,0xA004,0xA002,0x5EAE,0x5EAC,0xA002,0x5EAB,0x5EAA,0xA004,0xA002,0x5EA9,0x5EA8,0xA002, 0x5EA4,0x5EA3,0xA020,0xA010,0xA008,0xA004,0xA002,0x5EA2,0x5EA1,0xA002,0x5E9D,0x5E9B,0xA004,0xA002,0x5E98,0x5E92, 0xA002,0x5E8E,0x5E8D,0xA008,0xA004,0xA002,0x5E8C,0x5E89,0xA002,0x5E88,0x5E85,0xA004,0xA002,0x5E83,0x5E82,0xA002, 0x5E81,0x5E7E,0xA010,0xA008,0xA004,0xA002,0x5E79,0x5E77,0xA002,0x5E75,0x5E71,0xA004,0xA002,0x5E70,0x5E6F,0xA002, 0x5E6E,0x5E6D,0xA008,0xA004,0xA002,0x5E6C,0x5E6B,0xA002,0x5E6A,0x5E69,0xA004,0xA002,0x5E68,0x5E67,0xA002,0x5E66, 0x5E65,0xA07E,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x5E64,0xA002,0x5E63,0x5E60,0xA004,0xA002,0x5E5F,0x5E5D,0xA002, 0x5E5C,0x5E5A,0xA008,0xA004,0xA002,0x5E59,0x5E58,0xA002,0x5E57,0x5E56,0xA004,0xA002,0x5E53,0x5E52,0xA002,0x5E51, 0x5E50,0xA010,0xA008,0xA004,0xA002,0x5E4F,0x5E4E,0xA002,0x5E4D,0x5E4B,0xA004,0xA002,0x5E4A,0x5E49,0xA002,0x5E48, 0x5E47,0xA008,0xA004,0xA002,0x5E46,0x5E43,0xA002,0x5E41,0x5E40,0xA004,0xA002,0x5E3F,0x5E3E,0xA002,0x5E3A,0x5E39, 0xA020,0xA010,0xA008,0xA004,0xA002,0x5E36,0x5E35,0xA002,0x5E34,0x5E33,0xA004,0xA002,0x5E32,0x5E30,0xA002,0x5E2F, 0x5E2C,0xA008,0xA004,0xA002,0x5E2B,0x5E2A,0xA002,0x5E29,0x5E28,0xA004,0xA002,0x5E25,0x5E24,0xA002,0x5E23,0x5E22, 0xA010,0xA008,0xA004,0xA002,0x5E21,0x5E20,0xA002,0x5E1F,0x5E1E,0xA004,0xA002,0x5E17,0x5E13,0xA002,0x5E12,0x5E0E, 0xA008,0xA004,0xA002,0x5E0D,0x5E0B,0xA002,0x5E0A,0x5E09,0xA004,0xA002,0x5E07,0x5E04,0xA002,0x5E00,0x5DFF,0xA03F, 0xA01F,0xA010,0xA008,0xA004,0xA002,0x5DFC,0x5DFB,0xA002,0x5DFA,0x5DF9,0xA004,0xA002,0x5DF8,0x5DF6,0xA002,0x5DF5, 0x5DF0,0xA007,0xA003,0xA001,0x5DED,0xA002,0x5DEC,0x5DEA,0xA004,0xA002,0x5DE4,0x5DE3,0xA002,0x5DE0,0x5DDF,0xA010, 0xA008,0xA004,0xA002,0x5DDC,0x5DDA,0xA002,0x5DD9,0x5DD8,0xA004,0xA002,0x5DD7,0x5DD6,0xA002,0x5DD5,0x5DD4,0xA008, 0xA004,0xA002,0x5DD3,0x5DD2,0xA002,0x5DD1,0x5DD0,0xA004,0xA002,0x5DCF,0x5DCE,0xA002,0x5DCC,0x5DCB,0xA020,0xA010, 0xA008,0xA004,0xA002,0x5DCA,0x5DC9,0xA002,0x5DC8,0x5DC7,0xA004,0xA002,0x5DC6,0x5DC4,0xA002,0x5DC3,0x5DC2,0xA008, 0xA004,0xA002,0x5DC1,0x5DC0,0xA002,0x5DBF,0x5DBE,0xA004,0xA002,0x5DBD,0x5DBC,0xA002,0x5DBB,0x5DBA,0xA010,0xA008, 0xA004,0xA002,0x5DB9,0x5DB8,0xA002,0x5DB6,0x5DB5,0xA004,0xA002,0x5DB4,0x5DB3,0xA002,0x5DB2,0x5DB1,0xA008,0xA004, 0xA002,0x5DB0,0x5DAF,0xA002,0x5DAE,0x5DAD,0xA004,0xA002,0x5DAC,0x5DAB,0xA002,0x5DAA,0x5DA9,0xA083,0xA015,0xA000, 0xA000,0xA00E,0xA006,0xA002,0x5DA8,0xA002,0x5DA7,0x5DA6,0xA004,0xA002,0x5DA5,0x5DA4,0xA002,0x5DA3,0x5DA2,0xA000, 0xA000,0xA000,0x5DA1,0xA02E,0xA00E,0xA001,0xA005,0xA001,0xA002,0x5DA0,0x5D9F,0xA004,0xA002,0x5D9E,0x5D9C,0xA002, 0x5D9B,0x5D9A,0xA010,0xA008,0xA004,0xA002,0x5D98,0x5D97,0xA002,0x5D96,0x5D95,0xA004,0xA002,0x5D94,0x5D93,0xA002, 0x5D92,0x5D91,0xA008,0xA004,0xA002,0x5D90,0x5D8F,0xA002,0x5D8E,0x5D8D,0xA004,0xA002,0x5D8C,0x5D8B,0xA002,0x5D8A, 0x5D89,0xA020,0xA010,0xA008,0xA004,0xA002,0x5D88,0x5D87,0xA002,0x5D86,0x5D85,0xA004,0xA002,0x5D84,0x5D83,0xA002, 0x5D81,0x5D80,0xA008,0xA004,0xA002,0x5D7F,0x5D7E,0xA002,0x5D7D,0x5D7C,0xA004,0xA002,0x5D7B,0x5D7A,0xA002,0x5D79, 0x5D78,0xA010,0xA008,0xA004,0xA002,0x5D77,0x5D76,0xA002,0x5D75,0x5D73,0xA004,0xA002,0x5D72,0x5D71,0xA002,0x5D70, 0x5D6E,0xA008,0xA004,0xA002,0x5D6D,0x5D6A,0xA002,0x5D68,0x5D67,0xA004,0xA002,0x5D66,0x5D65,0xA002,0x5D64,0x5D63, 0xA07E,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x5D62,0xA002,0x5D61,0x5D60,0xA004,0xA002,0x5D5F,0x5D5E,0xA002,0x5D5C, 0x5D5A,0xA008,0xA004,0xA002,0x5D59,0x5D57,0xA002,0x5D56,0x5D55,0xA004,0xA002,0x5D54,0x5D53,0xA002,0x5D52,0x5D51, 0xA010,0xA008,0xA004,0xA002,0x5D50,0x5D4F,0xA002,0x5D4E,0x5D4D,0xA004,0xA002,0x5D49,0x5D48,0xA002,0x5D46,0x5D45, 0xA008,0xA004,0xA002,0x5D44,0x5D43,0xA002,0x5D42,0x5D41,0xA004,0xA002,0x5D40,0x5D3F,0xA002,0x5D3C,0x5D3B,0xA020, 0xA010,0xA008,0xA004,0xA002,0x5D3A,0x5D39,0xA002,0x5D38,0x5D37,0xA004,0xA002,0x5D36,0x5D35,0xA002,0x5D33,0x5D32, 0xA008,0xA004,0xA002,0x5D31,0x5D30,0xA002,0x5D2F,0x5D2C,0xA004,0xA002,0x5D2B,0x5D2A,0xA002,0x5D28,0x5D25,0xA010, 0xA008,0xA004,0xA002,0x5D23,0x5D22,0xA002,0x5D21,0x5D20,0xA004,0xA002,0x5D1F,0x5D1D,0xA002,0x5D1C,0x5D1A,0xA008, 0xA004,0xA002,0x5D19,0x5D18,0xA002,0x5D17,0x5D15,0xA004,0xA002,0x5D13,0x5D12,0xA002,0x5D11,0x5D10,0xA03F,0xA01F, 0xA010,0xA008,0xA004,0xA002,0x5D0F,0x5D0D,0xA002,0x5D0C,0x5D0B,0xA004,0xA002,0x5D0A,0x5D09,0xA002,0x5D08,0x5D05, 0xA007,0xA004,0xA002,0x5D04,0x5D01,0xA001,0x5D00,0xA004,0xA002,0x5CFF,0x5CFE,0xA002,0x5CFD,0x5CFC,0xA010,0xA008, 0xA004,0xA002,0x5CFA,0x5CF9,0xA002,0x5CF8,0x5CF7,0xA004,0xA002,0x5CF6,0x5CF5,0xA002,0x5CF4,0x5CF3,0xA008,0xA004, 0xA002,0x5CF2,0x5CF1,0xA002,0x5CEF,0x5CEE,0xA004,0xA002,0x5CEC,0x5CEB,0xA002,0x5CE9,0x5CE7,0xA020,0xA010,0xA008, 0xA004,0xA002,0x5CE3,0x5CE2,0xA002,0x5CE0,0x5CDF,0xA004,0xA002,0x5CDE,0x5CDD,0xA002,0x5CDC,0x5CDB,0xA008,0xA004, 0xA002,0x5CDA,0x5CD8,0xA002,0x5CD7,0x5CD6,0xA004,0xA002,0x5CD5,0x5CD4,0xA002,0x5CD3,0x5CD1,0xA010,0xA008,0xA004, 0xA002,0x5CD0,0x5CCF,0xA002,0x5CCE,0x5CCD,0xA004,0xA002,0x5CCC,0x5CCA,0xA002,0x5CC9,0x5CC8,0xA008,0xA004,0xA002, 0x5CC7,0x5CC6,0xA002,0x5CC5,0x5CC3,0xA004,0xA002,0x5CC2,0x5CC0,0xA002,0x5CBE,0x5CBC,0xA17F,0xA082,0xA018,0xA000, 0xA000,0xA00E,0xA006,0xA002,0x5CBB,0xA002,0x5CBA,0x5CB9,0xA004,0xA002,0x5CB6,0x5CB4,0xA002,0x5CB2,0x5CB0,0xA000, 0xA004,0xA002,0x5CAF,0x5CAE,0xA000,0x5CAA,0xA02A,0xA00A,0xA001,0xA001,0xA004,0xA002,0x5CA8,0x5CA7,0xA002,0x5CA6, 0x5CA5,0xA010,0xA008,0xA004,0xA002,0x5CA4,0x5CA1,0xA002,0x5CA0,0x5C9F,0xA004,0xA002,0x5C9E,0x5C9D,0xA002,0x5C95, 0x5C93,0xA008,0xA004,0xA002,0x5C92,0x5C8F,0xA002,0x5C8E,0x5C8B,0xA004,0xA002,0x5C8A,0x5C89,0xA002,0x5C87,0x5C86, 0xA020,0xA010,0xA008,0xA004,0xA002,0x5C85,0x5C84,0xA002,0x5C83,0x5C80,0xA004,0xA002,0x5C7E,0x5C7D,0xA002,0x5C7C, 0x5C7B,0xA008,0xA004,0xA002,0x5C78,0x5C77,0xA002,0x5C76,0x5C75,0xA004,0xA002,0x5C74,0x5C73,0xA002,0x5C72,0x5C70, 0xA010,0xA008,0xA004,0xA002,0x5C6D,0x5C6C,0xA002,0x5C6B,0x5C6A,0xA004,0xA002,0x5C69,0x5C68,0xA002,0x5C67,0x5C64, 0xA008,0xA004,0xA002,0x5C62,0x5C5F,0xA002,0x5C5D,0x5C5C,0xA004,0xA002,0x5C5B,0x5C5A,0xA002,0x5C58,0x5C57,0xA07E, 0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x5C56,0xA002,0x5C54,0x5C53,0xA004,0xA002,0x5C52,0x5C4D,0xA002,0x5C4C,0x5C47, 0xA008,0xA004,0xA002,0x5C46,0x5C44,0xA002,0x5C43,0x5C37,0xA004,0xA002,0x5C36,0x5C35,0xA002,0x5C33,0x5C32,0xA010, 0xA008,0xA004,0xA002,0x5C30,0x5C2F,0xA002,0x5C2E,0x5C2D,0xA004,0xA002,0x5C2B,0x5C2A,0xA002,0x5C29,0x5C28,0xA008, 0xA004,0xA002,0x5C26,0x5C23,0xA002,0x5C21,0x5C20,0xA004,0xA002,0x5C1F,0x5C1E,0xA002,0x5C1B,0x5C19,0xA020,0xA010, 0xA008,0xA004,0xA002,0x5C17,0x5C13,0xA002,0x5C12,0x5C10,0xA004,0xA002,0x5C0E,0x5C0D,0xA002,0x5C0C,0x5C0B,0xA008, 0xA004,0xA002,0x5C08,0x5C07,0xA002,0x5C05,0x5C03,0xA004,0xA002,0x5C02,0x5C00,0xA002,0x5BFE,0x5BFD,0xA010,0xA008, 0xA004,0xA002,0x5BF7,0x5BF6,0xA002,0x5BF5,0x5BF4,0xA004,0xA002,0x5BF3,0x5BF2,0xA002,0x5BF1,0x5BEF,0xA008,0xA004, 0xA002,0x5BED,0x5BEC,0xA002,0x5BEB,0x5BEA,0xA004,0xA002,0x5BE9,0x5BE7,0xA002,0x5BE6,0x5BE3,0xA03F,0xA01F,0xA010, 0xA008,0xA004,0xA002,0x5BE2,0x5BE0,0xA002,0x5BDC,0x5BDB,0xA004,0xA002,0x5BDA,0x5BD9,0xA002,0x5BD8,0x5BD7,0xA008, 0xA004,0xA002,0x5BD6,0x5BD5,0xA002,0x5BD4,0x5BD1,0xA003,0xA001,0x5BCF,0xA002,0x5BCE,0x5BCD,0xA010,0xA008,0xA004, 0xA002,0x5BCB,0x5BCA,0xA002,0x5BC9,0x5BC8,0xA004,0xA002,0x5BC3,0x5BC1,0xA002,0x5BC0,0x5BBC,0xA008,0xA004,0xA002, 0x5BBB,0x5BBA,0xA002,0x5BB7,0x5BB2,0xA004,0xA002,0x5BB1,0x5BAF,0xA002,0x5BAE,0x5BAD,0xA020,0xA010,0xA008,0xA004, 0xA002,0x5BAC,0x5BA9,0xA002,0x5BA8,0x5BA7,0xA004,0xA002,0x5B9F,0x5B96,0xA002,0x5B94,0x5B92,0xA008,0xA004,0xA002, 0x5B91,0x5B90,0xA002,0x5B8E,0x5B8D,0xA004,0xA002,0x5B8A,0x5B86,0xA002,0x5B82,0x5B7F,0xA010,0xA008,0xA004,0xA002, 0x5B7E,0x5B7C,0xA002,0x5B7B,0x5B79,0xA004,0xA002,0x5B78,0x5B77,0xA002,0x5B76,0x5B74,0xA008,0xA004,0xA002,0x5B72, 0x5B6F,0xA002,0x5B6E,0x5B6D,0xA004,0xA002,0x5B6B,0x5B68,0xA002,0x5B67,0x5B61,0xA083,0xA01C,0xA000,0xA000,0xA00E, 0xA006,0xA002,0x5B60,0xA002,0x5B5E,0x5B56,0xA004,0xA002,0x5B52,0x5B4F,0xA002,0x5B4E,0x5B4D,0xA008,0xA004,0xA002, 0x5B4C,0x5B4B,0xA002,0x5B4A,0x5B49,0xA000,0xA000,0x5B48,0xA027,0xA007,0xA001,0xA001,0xA001,0xA002,0x5B47,0x5B46, 0xA010,0xA008,0xA004,0xA002,0x5B45,0x5B44,0xA002,0x5B43,0x5B42,0xA004,0xA002,0x5B41,0x5B3F,0xA002,0x5B3E,0x5B3D, 0xA008,0xA004,0xA002,0x5B3C,0x5B3B,0xA002,0x5B3A,0x5B39,0xA004,0xA002,0x5B38,0x5B36,0xA002,0x5B35,0x5B33,0xA020, 0xA010,0xA008,0xA004,0xA002,0x5B31,0x5B30,0xA002,0x5B2F,0x5B2E,0xA004,0xA002,0x5B2D,0x5B2C,0xA002,0x5B2B,0x5B2A, 0xA008,0xA004,0xA002,0x5B29,0x5B28,0xA002,0x5B27,0x5B26,0xA004,0xA002,0x5B25,0x5B24,0xA002,0x5B23,0x5B22,0xA010, 0xA008,0xA004,0xA002,0x5B21,0x5B20,0xA002,0x5B1F,0x5B1E,0xA004,0xA002,0x5B1D,0x5B1C,0xA002,0x5B1B,0x5B1A,0xA008, 0xA004,0xA002,0x5B19,0x5B18,0xA002,0x5B15,0x5B14,0xA004,0xA002,0x5B13,0x5B12,0xA002,0x5B11,0x5B10,0xA07E,0xA03E, 0xA01E,0xA00E,0xA006,0xA002,0x5B0F,0xA002,0x5B0E,0x5B0D,0xA004,0xA002,0x5B0C,0x5B0B,0xA002,0x5B0A,0x5B08,0xA008, 0xA004,0xA002,0x5B07,0x5B06,0xA002,0x5B05,0x5B04,0xA004,0xA002,0x5B03,0x5B02,0xA002,0x5B01,0x5B00,0xA010,0xA008, 0xA004,0xA002,0x5AFF,0x5AFE,0xA002,0x5AFD,0x5AFC,0xA004,0xA002,0x5AFB,0x5AFA,0xA002,0x5AF9,0x5AF8,0xA008,0xA004, 0xA002,0x5AF7,0x5AF6,0xA002,0x5AF5,0x5AF4,0xA004,0xA002,0x5AF3,0x5AF2,0xA002,0x5AF0,0x5AEF,0xA020,0xA010,0xA008, 0xA004,0xA002,0x5AEE,0x5AED,0xA002,0x5AEC,0x5AEA,0xA004,0xA002,0x5AE8,0x5AE7,0xA002,0x5AE5,0x5AE4,0xA008,0xA004, 0xA002,0x5AE2,0x5ADF,0xA002,0x5ADE,0x5ADD,0xA004,0xA002,0x5ADB,0x5ADA,0xA002,0x5AD9,0x5AD7,0xA010,0xA008,0xA004, 0xA002,0x5AD5,0x5AD3,0xA002,0x5AD1,0x5AD0,0xA004,0xA002,0x5ACF,0x5ACE,0xA002,0x5ACD,0x5ACB,0xA008,0xA004,0xA002, 0x5ACA,0x5AC8,0xA002,0x5AC7,0x5AC6,0xA004,0xA002,0x5AC5,0x5AC4,0xA002,0x5AC3,0x5AC0,0xA03F,0xA01F,0xA010,0xA008, 0xA004,0xA002,0x5ABF,0x5ABD,0xA002,0x5ABC,0x5ABB,0xA004,0xA002,0x5ABA,0x5AB9,0xA002,0x5AB7,0x5AB6,0xA008,0xA004, 0xA002,0x5AB4,0x5AB1,0xA002,0x5AB0,0x5AAF,0xA004,0xA002,0x5AAE,0x5AAD,0xA001,0x5AAC,0xA010,0xA008,0xA004,0xA002, 0x5AAB,0x5AA9,0xA002,0x5AA8,0x5AA7,0xA004,0xA002,0x5AA6,0x5AA5,0xA002,0x5AA4,0x5AA3,0xA008,0xA004,0xA002,0x5AA2, 0x5AA1,0xA002,0x5AA0,0x5A9F,0xA004,0xA002,0x5A9E,0x5A9D,0xA002,0x5A9C,0x5A99,0xA020,0xA010,0xA008,0xA004,0xA002, 0x5A98,0x5A97,0xA002,0x5A96,0x5A95,0xA004,0xA002,0x5A94,0x5A93,0xA002,0x5A91,0x5A90,0xA008,0xA004,0xA002,0x5A8F, 0x5A8E,0xA002,0x5A8D,0x5A8C,0xA004,0xA002,0x5A8B,0x5A8A,0xA002,0x5A89,0x5A88,0xA010,0xA008,0xA004,0xA002,0x5A87, 0x5A86,0xA002,0x5A85,0x5A84,0xA004,0xA002,0x5A83,0x5A82,0xA002,0x5A81,0x5A80,0xA008,0xA004,0xA002,0x5A7E,0x5A7D, 0xA002,0x5A7C,0x5A7B,0xA004,0xA002,0x5A79,0x5A78,0xA002,0x5A73,0x5A72,0xA2FC,0xA17C,0xA07F,0xA01F,0xA000,0xA000, 0xA00E,0xA006,0xA002,0x5A71,0xA002,0x5A70,0x5A6F,0xA004,0xA002,0x5A6E,0x5A6D,0xA002,0x5A6C,0x5A6B,0xA008,0xA004, 0xA002,0x5A69,0x5A68,0xA002,0x5A66,0x5A65,0xA004,0xA002,0x5A64,0x5A63,0xA000,0x5A61,0xA020,0xA001,0xA00F,0xA007, 0xA003,0xA001,0x5A60,0xA002,0x5A5F,0x5A5E,0xA004,0xA002,0x5A5D,0x5A5C,0xA002,0x5A5B,0x5A59,0xA008,0xA004,0xA002, 0x5A58,0x5A57,0xA002,0x5A56,0x5A54,0xA004,0xA002,0x5A53,0x5A52,0xA002,0x5A51,0x5A50,0xA020,0xA010,0xA008,0xA004, 0xA002,0x5A4F,0x5A4E,0xA002,0x5A4D,0x5A4C,0xA004,0xA002,0x5A4B,0x5A48,0xA002,0x5A47,0x5A45,0xA008,0xA004,0xA002, 0x5A44,0x5A43,0xA002,0x5A42,0x5A41,0xA004,0xA002,0x5A3F,0x5A3E,0xA002,0x5A3D,0x5A3B,0xA010,0xA008,0xA004,0xA002, 0x5A3A,0x5A39,0xA002,0x5A38,0x5A37,0xA004,0xA002,0x5A35,0x5A33,0xA002,0x5A30,0x5A2F,0xA008,0xA004,0xA002,0x5A2E, 0x5A2D,0xA002,0x5A2C,0x5A2B,0xA004,0xA002,0x5A2A,0x5A28,0xA002,0x5A27,0x5A26,0xA07E,0xA03E,0xA01E,0xA00E,0xA006, 0xA002,0x5A24,0xA002,0x5A22,0x5A21,0xA004,0xA002,0x5A1E,0x5A1D,0xA002,0x5A1B,0x5A1A,0xA008,0xA004,0xA002,0x5A19, 0x5A17,0xA002,0x5A16,0x5A15,0xA004,0xA002,0x5A14,0x5A12,0xA002,0x5A10,0x5A0F,0xA010,0xA008,0xA004,0xA002,0x5A0E, 0x5A0D,0xA002,0x5A0B,0x5A0A,0xA004,0xA002,0x5A02,0x5A00,0xA002,0x59FE,0x59FD,0xA008,0xA004,0xA002,0x59FC,0x59FA, 0xA002,0x59F8,0x59F7,0xA004,0xA002,0x59F6,0x59F5,0xA002,0x59F4,0x59F3,0xA020,0xA010,0xA008,0xA004,0xA002,0x59F2, 0x59F1,0xA002,0x59F0,0x59EF,0xA004,0xA002,0x59EE,0x59ED,0xA002,0x59EB,0x59EA,0xA008,0xA004,0xA002,0x59E9,0x59E7, 0xA002,0x59E6,0x59E4,0xA004,0xA002,0x59E2,0x59E1,0xA002,0x59E0,0x59DF,0xA010,0xA008,0xA004,0xA002,0x59DE,0x59DB, 0xA002,0x59D9,0x59D6,0xA004,0xA002,0x59D5,0x59CF,0xA002,0x59CE,0x59CD,0xA008,0xA004,0xA002,0x59CC,0x59C9,0xA002, 0x59C8,0x59C7,0xA004,0xA002,0x59C5,0x59C4,0xA002,0x59C3,0x59C2,0xA03F,0xA020,0xA010,0xA008,0xA004,0xA002,0x59C1, 0x59C0,0xA002,0x59BF,0x59BD,0xA004,0xA002,0x59BC,0x59BA,0xA002,0x59B8,0x59B7,0xA008,0xA004,0xA002,0x59B6,0x59B5, 0xA002,0x59B4,0x59B3,0xA004,0xA002,0x59B1,0x59B0,0xA002,0x59AD,0x59AC,0xA00F,0xA007,0xA003,0xA000,0x59A7,0xA002, 0x59A6,0x59A2,0xA004,0xA002,0x59A1,0x59A0,0xA002,0x599F,0x599D,0xA008,0xA004,0xA002,0x599C,0x599B,0xA002,0x599A, 0x5998,0xA004,0xA002,0x5995,0x5994,0xA002,0x5991,0x5990,0xA020,0xA010,0xA008,0xA004,0xA002,0x598F,0x598E,0xA002, 0x598C,0x598B,0xA004,0xA002,0x5989,0x5985,0xA002,0x5980,0x597F,0xA008,0xA004,0xA002,0x597E,0x597C,0xA002,0x597B, 0x597A,0xA004,0xA002,0x5977,0x5975,0xA002,0x5972,0x5971,0xA010,0xA008,0xA004,0xA002,0x5970,0x596F,0xA002,0x596E, 0x596D,0xA004,0xA002,0x596C,0x596B,0xA002,0x596A,0x5969,0xA008,0xA004,0xA002,0x5968,0x5967,0xA002,0x5966,0x5964, 0xA004,0xA002,0x5963,0x5961,0xA002,0x595F,0x595E,0xA083,0xA026,0xA000,0xA01E,0xA00E,0xA006,0xA002,0x595D,0xA002, 0x595C,0x595B,0xA004,0xA002,0x5959,0x5953,0xA002,0x5952,0x5950,0xA008,0xA004,0xA002,0x594D,0x594C,0xA002,0x594A, 0x5946,0xA004,0xA002,0x5945,0x5943,0xA002,0x5940,0x593F,0xA000,0xA000,0xA000,0xA002,0x593E,0x593D,0xA01D,0xA001, 0xA00C,0xA004,0xA001,0xA001,0x593B,0xA004,0xA002,0x5936,0x5935,0xA002,0x5933,0x5932,0xA008,0xA004,0xA002,0x5930, 0x592C,0xA002,0x5928,0x5926,0xA004,0xA002,0x5923,0x5922,0xA002,0x5921,0x5920,0xA020,0xA010,0xA008,0xA004,0xA002, 0x591E,0x591D,0xA002,0x591B,0x5918,0xA004,0xA002,0x5917,0x5913,0xA002,0x5912,0x5911,0xA008,0xA004,0xA002,0x5910, 0x590E,0xA002,0x590C,0x590B,0xA004,0xA002,0x590A,0x5909,0xA002,0x5908,0x5906,0xA010,0xA008,0xA004,0xA002,0x5905, 0x5903,0xA002,0x5901,0x5900,0xA004,0xA002,0x58FF,0x58FE,0xA002,0x58FD,0x58FC,0xA008,0xA004,0xA002,0x58FB,0x58FA, 0xA002,0x58F8,0x58F7,0xA004,0xA002,0x58F5,0x58F4,0xA002,0x58F2,0x58F1,0xA07E,0xA03E,0xA01E,0xA00E,0xA006,0xA002, 0x58EF,0xA002,0x58ED,0x58EA,0xA004,0xA002,0x58E9,0x58E8,0xA002,0x58E7,0x58E6,0xA008,0xA004,0xA002,0x58E5,0x58E3, 0xA002,0x58E2,0x58E1,0xA004,0xA002,0x58E0,0x58DF,0xA002,0x58DE,0x58DD,0xA010,0xA008,0xA004,0xA002,0x58DC,0x58DB, 0xA002,0x58DA,0x58D9,0xA004,0xA002,0x58D8,0x58D7,0xA002,0x58D6,0x58D4,0xA008,0xA004,0xA002,0x58D3,0x58D2,0xA002, 0x58D0,0x58CF,0xA004,0xA002,0x58CE,0x58CD,0xA002,0x58CC,0x58CB,0xA020,0xA010,0xA008,0xA004,0xA002,0x58CA,0x58C9, 0xA002,0x58C8,0x58C7,0xA004,0xA002,0x58C6,0x58C4,0xA002,0x58C3,0x58C2,0xA008,0xA004,0xA002,0x58C0,0x58BF,0xA002, 0x58BE,0x58BD,0xA004,0xA002,0x58BB,0x58BA,0xA002,0x58B9,0x58B8,0xA010,0xA008,0xA004,0xA002,0x58B7,0x58B6,0xA002, 0x58B5,0x58B4,0xA004,0xA002,0x58B3,0x58B2,0xA002,0x58B1,0x58B0,0xA008,0xA004,0xA002,0x58AF,0x58AE,0xA002,0x58AD, 0x58AC,0xA004,0xA002,0x58AB,0x58AA,0xA002,0x58A7,0x58A6,0xA03F,0xA020,0xA010,0xA008,0xA004,0xA002,0x58A5,0x58A4, 0xA002,0x58A3,0x58A2,0xA004,0xA002,0x58A1,0x58A0,0xA002,0x589D,0x589C,0xA008,0xA004,0xA002,0x589B,0x5898,0xA002, 0x5897,0x5896,0xA004,0xA002,0x5895,0x5894,0xA002,0x5891,0x5890,0xA00F,0xA007,0xA004,0xA002,0x588F,0x588E,0xA000, 0x588D,0xA004,0xA002,0x588C,0x588B,0xA002,0x588A,0x5888,0xA008,0xA004,0xA002,0x5887,0x5886,0xA002,0x5884,0x5882, 0xA004,0xA002,0x587F,0x587D,0xA002,0x587C,0x587B,0xA020,0xA010,0xA008,0xA004,0xA002,0x587A,0x5879,0xA002,0x5878, 0x5877,0xA004,0xA002,0x5876,0x5875,0xA002,0x5874,0x5873,0xA008,0xA004,0xA002,0x5872,0x5871,0xA002,0x5870,0x586F, 0xA004,0xA002,0x586E,0x586D,0xA002,0x586A,0x5869,0xA010,0xA008,0xA004,0xA002,0x5868,0x5867,0xA002,0x5866,0x5864, 0xA004,0xA002,0x5863,0x5862,0xA002,0x5861,0x5860,0xA008,0xA004,0xA002,0x585F,0x585D,0xA002,0x585C,0x585B,0xA004, 0xA002,0x585A,0x5859,0xA002,0x5857,0x5856,0xA17F,0xA082,0xA029,0xA000,0xA01E,0xA00E,0xA006,0xA002,0x5855,0xA002, 0x5853,0x5852,0xA004,0xA002,0x5850,0x584F,0xA002,0x584E,0x584B,0xA008,0xA004,0xA002,0x584A,0x5849,0xA002,0x5848, 0x5847,0xA004,0xA002,0x5846,0x5845,0xA002,0x5843,0x5842,0xA000,0xA000,0xA004,0xA002,0x5841,0x5840,0xA002,0x583F, 0x583E,0xA019,0xA001,0xA008,0xA001,0xA003,0xA001,0x583D,0xA002,0x583C,0x583B,0xA008,0xA004,0xA002,0x583A,0x5839, 0xA002,0x5838,0x5837,0xA004,0xA002,0x5836,0x5834,0xA002,0x5833,0x5832,0xA020,0xA010,0xA008,0xA004,0xA002,0x5831, 0x582F,0xA002,0x582E,0x582D,0xA004,0xA002,0x582C,0x582B,0xA002,0x5829,0x5828,0xA008,0xA004,0xA002,0x5827,0x5826, 0xA002,0x5825,0x5823,0xA004,0xA002,0x5822,0x581F,0xA002,0x581D,0x581C,0xA010,0xA008,0xA004,0xA002,0x581B,0x581A, 0xA002,0x5818,0x5817,0xA004,0xA002,0x5816,0x5814,0xA002,0x5813,0x5812,0xA008,0xA004,0xA002,0x5810,0x580F,0xA002, 0x580E,0x580C,0xA004,0xA002,0x580A,0x5809,0xA002,0x5808,0x5805,0xA07E,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x5804, 0xA002,0x5803,0x5801,0xA004,0xA002,0x57FF,0x57FE,0xA002,0x57FC,0x57FB,0xA008,0xA004,0xA002,0x57F7,0x57F6,0xA002, 0x57F5,0x57F3,0xA004,0xA002,0x57F2,0x57F1,0xA002,0x57F0,0x57EE,0xA010,0xA008,0xA004,0xA002,0x57EC,0x57EB,0xA002, 0x57EA,0x57E9,0xA004,0xA002,0x57E8,0x57E7,0xA002,0x57E6,0x57E5,0xA008,0xA004,0xA002,0x57E3,0x57E2,0xA002,0x57E1, 0x57DE,0xA004,0xA002,0x57DC,0x57DB,0xA002,0x57D7,0x57D6,0xA020,0xA010,0xA008,0xA004,0xA002,0x57D3,0x57D1,0xA002, 0x57D0,0x57CD,0xA004,0xA002,0x57CC,0x57CA,0xA002,0x57C9,0x57C8,0xA008,0xA004,0xA002,0x57C7,0x57C6,0xA002,0x57C5, 0x57C4,0xA004,0xA002,0x57C1,0x57C0,0xA002,0x57BF,0x57BE,0xA010,0xA008,0xA004,0xA002,0x57BD,0x57BC,0xA002,0x57BB, 0x57BA,0xA004,0xA002,0x57B9,0x57B7,0xA002,0x57B6,0x57B5,0xA008,0xA004,0xA002,0x57B3,0x57B1,0xA002,0x57B0,0x57AF, 0xA004,0xA002,0x57AC,0x57AA,0xA002,0x57A8,0x57A5,0xA03F,0xA020,0xA010,0xA008,0xA004,0xA002,0x579F,0x579E,0xA002, 0x579D,0x579C,0xA004,0xA002,0x579A,0x5799,0xA002,0x5798,0x5797,0xA008,0xA004,0xA002,0x5796,0x5795,0xA002,0x5794, 0x5791,0xA004,0xA002,0x5790,0x578F,0xA002,0x578E,0x578D,0xA00F,0xA008,0xA004,0xA002,0x578A,0x5789,0xA002,0x5788, 0x5787,0xA003,0xA000,0x5781,0xA002,0x5780,0x577F,0xA008,0xA004,0xA002,0x577E,0x577D,0xA002,0x577A,0x5779,0xA004, 0xA002,0x5778,0x5775,0xA002,0x5774,0x5772,0xA020,0xA010,0xA008,0xA004,0xA002,0x5771,0x5770,0xA002,0x576E,0x576C, 0xA004,0xA002,0x5767,0x5765,0xA002,0x5763,0x5762,0xA008,0xA004,0xA002,0x5759,0x5758,0xA002,0x5756,0x5755,0xA004, 0xA002,0x5754,0x5753,0xA002,0x5752,0x574B,0xA010,0xA008,0xA004,0xA002,0x5749,0x5748,0xA002,0x5746,0x5745,0xA004, 0xA002,0x5744,0x5743,0xA002,0x5741,0x573F,0xA008,0xA004,0xA002,0x573D,0x573C,0xA002,0x5738,0x5737,0xA004,0xA002, 0x5736,0x5735,0xA002,0x5734,0x5732,0xA083,0xA02D,0xA000,0xA01E,0xA00E,0xA006,0xA002,0x5731,0xA002,0x572B,0x5727, 0xA004,0xA002,0x5726,0x5725,0xA002,0x5724,0x5722,0xA008,0xA004,0xA002,0x5721,0x5720,0xA002,0x571E,0x571D,0xA004, 0xA002,0x571B,0x571A,0xA002,0x5719,0x5718,0xA000,0xA008,0xA004,0xA002,0x5717,0x5716,0xA002,0x5715,0x5714,0xA000, 0xA002,0x5713,0x5712,0xA016,0xA001,0xA005,0xA001,0xA001,0xA001,0x5711,0xA008,0xA004,0xA002,0x5710,0x570F,0xA002, 0x570E,0x570D,0xA004,0xA002,0x570C,0x570B,0xA002,0x5707,0x5705,0xA020,0xA010,0xA008,0xA004,0xA002,0x5702,0x5701, 0xA002,0x5700,0x56FC,0xA004,0xA002,0x56FB,0x56F8,0xA002,0x56F7,0x56F6,0xA008,0xA004,0xA002,0x56F3,0x56F2,0xA002, 0x56EF,0x56EE,0xA004,0xA002,0x56EC,0x56EA,0xA002,0x56E9,0x56E8,0xA010,0xA008,0xA004,0xA002,0x56E7,0x56E6,0xA002, 0x56E5,0x56E3,0xA004,0xA002,0x56DC,0x56D9,0xA002,0x56D8,0x56D6,0xA008,0xA004,0xA002,0x56D5,0x56D3,0xA002,0x56D2, 0x56D1,0xA004,0xA002,0x56D0,0x56CF,0xA002,0x56CE,0x56CD,0xA07E,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x56CC,0xA002, 0x56CB,0x56C9,0xA004,0xA002,0x56C8,0x56C7,0xA002,0x56C6,0x56C5,0xA008,0xA004,0xA002,0x56C4,0x56C3,0xA002,0x56C2, 0x56C1,0xA004,0xA002,0x56C0,0x56BF,0xA002,0x56BE,0x56BD,0xA010,0xA008,0xA004,0xA002,0x56BB,0x56BA,0xA002,0x56B9, 0x56B8,0xA004,0xA002,0x56B6,0x56B5,0xA002,0x56B4,0x56B3,0xA008,0xA004,0xA002,0x56B2,0x56B1,0xA002,0x56B0,0x56AE, 0xA004,0xA002,0x56AD,0x56AC,0xA002,0x56AB,0x56AA,0xA020,0xA010,0xA008,0xA004,0xA002,0x56A9,0x56A8,0xA002,0x56A7, 0x56A6,0xA004,0xA002,0x56A5,0x56A4,0xA002,0x56A2,0x56A1,0xA008,0xA004,0xA002,0x56A0,0x569F,0xA002,0x569E,0x569D, 0xA004,0xA002,0x569C,0x569B,0xA002,0x569A,0x5699,0xA010,0xA008,0xA004,0xA002,0x5698,0x5697,0xA002,0x5696,0x5695, 0xA004,0xA002,0x5694,0x5692,0xA002,0x5691,0x5690,0xA008,0xA004,0xA002,0x568D,0x568C,0xA002,0x568B,0x568A,0xA004, 0xA002,0x5689,0x5688,0xA002,0x5687,0x5684,0xA03F,0xA020,0xA010,0xA008,0xA004,0xA002,0x5683,0x5682,0xA002,0x5681, 0x5680,0xA004,0xA002,0x567F,0x567E,0xA002,0x567D,0x567A,0xA008,0xA004,0xA002,0x5679,0x5678,0xA002,0x5677,0x5675, 0xA004,0xA002,0x5674,0x5673,0xA002,0x5672,0x5670,0xA00F,0xA008,0xA004,0xA002,0x566F,0x566E,0xA002,0x566D,0x5667, 0xA004,0xA002,0x5666,0x5665,0xA000,0x5663,0xA008,0xA004,0xA002,0x5661,0x5660,0xA002,0x565F,0x565E,0xA004,0xA002, 0x565D,0x565B,0xA002,0x565A,0x5656,0xA020,0xA010,0xA008,0xA004,0xA002,0x5655,0x5653,0xA002,0x5652,0x5651,0xA004, 0xA002,0x5650,0x564F,0xA002,0x564B,0x564A,0xA008,0xA004,0xA002,0x5649,0x5648,0xA002,0x5647,0x5646,0xA004,0xA002, 0x5645,0x5644,0xA002,0x5643,0x5642,0xA010,0xA008,0xA004,0xA002,0x5641,0x5640,0xA002,0x563E,0x563D,0xA004,0xA002, 0x563C,0x563A,0xA002,0x5638,0x5637,0xA008,0xA004,0xA002,0x5635,0x5633,0xA002,0x5630,0x562F,0xA004,0xA002,0x562E, 0x562B,0xA002,0x562A,0x5629,0xA5F7,0xA2FB,0xA17C,0xA07F,0xA030,0xA000,0xA01E,0xA00E,0xA006,0xA002,0x5628,0xA002, 0x5626,0x5625,0xA004,0xA002,0x5622,0x5621,0xA002,0x5620,0x561D,0xA008,0xA004,0xA002,0x561C,0x561A,0xA002,0x5619, 0x5617,0xA004,0xA002,0x5616,0x5615,0xA002,0x5614,0x5613,0xA000,0xA008,0xA004,0xA002,0x5612,0x5611,0xA002,0x5610, 0x560D,0xA004,0xA002,0x560B,0x560A,0xA002,0x5607,0x5606,0xA00F,0xA001,0xA001,0xA005,0xA001,0xA002,0x5605,0x5604, 0xA004,0xA002,0x5603,0x5602,0xA002,0x55FF,0x55FC,0xA020,0xA010,0xA008,0xA004,0xA002,0x55FB,0x55FA,0xA002,0x55F9, 0x55F8,0xA004,0xA002,0x55F6,0x55F4,0xA002,0x55F1,0x55F0,0xA008,0xA004,0xA002,0x55EE,0x55ED,0xA002,0x55E9,0x55E7, 0xA004,0xA002,0x55E2,0x55E0,0xA002,0x55DE,0x55DB,0xA010,0xA008,0xA004,0xA002,0x55DA,0x55D9,0xA002,0x55D8,0x55D7, 0xA004,0xA002,0x55D5,0x55D0,0xA002,0x55CF,0x55CE,0xA008,0xA004,0xA002,0x55CB,0x55CA,0xA002,0x55C8,0x55C7,0xA004, 0xA002,0x55C6,0x55C3,0xA002,0x55C2,0x55C1,0xA07E,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x55C0,0xA002,0x55BF,0x55BC, 0xA004,0xA002,0x55BA,0x55B8,0xA002,0x55B6,0x55B4,0xA008,0xA004,0xA002,0x55B2,0x55B0,0xA002,0x55AF,0x55AE,0xA004, 0xA002,0x55AD,0x55AC,0xA002,0x55AB,0x55AA,0xA010,0xA008,0xA004,0xA002,0x55A9,0x55A8,0xA002,0x55A6,0x55A5,0xA004, 0xA002,0x55A4,0x55A3,0xA002,0x55A2,0x55A1,0xA008,0xA004,0xA002,0x55A0,0x559E,0xA002,0x559B,0x559A,0xA004,0xA002, 0x5597,0x5596,0xA002,0x5595,0x5593,0xA020,0xA010,0xA008,0xA004,0xA002,0x5592,0x5590,0xA002,0x558E,0x558D,0xA004, 0xA002,0x558C,0x5586,0xA002,0x5585,0x557F,0xA008,0xA004,0xA002,0x557D,0x557A,0xA002,0x5579,0x5574,0xA004,0xA002, 0x5573,0x5572,0xA002,0x5571,0x5570,0xA010,0xA008,0xA004,0xA002,0x556F,0x556B,0xA002,0x5569,0x5568,0xA004,0xA002, 0x5563,0x5562,0xA002,0x5560,0x555F,0xA008,0xA004,0xA002,0x555E,0x555D,0xA002,0x555B,0x555A,0xA004,0xA002,0x5559, 0x5558,0xA002,0x5557,0x5554,0xA03F,0xA020,0xA010,0xA008,0xA004,0xA002,0x5553,0x5552,0xA002,0x5551,0x554F,0xA004, 0xA002,0x554E,0x554D,0xA002,0x554C,0x554B,0xA008,0xA004,0xA002,0x5548,0x5547,0xA002,0x5545,0x5542,0xA004,0xA002, 0x5540,0x553D,0xA002,0x553B,0x553A,0xA010,0xA008,0xA004,0xA002,0x5539,0x5538,0xA002,0x5536,0x5535,0xA004,0xA002, 0x5534,0x5532,0xA002,0x552D,0x552B,0xA007,0xA004,0xA002,0x5529,0x5528,0xA001,0x5526,0xA004,0xA002,0x5525,0x5521, 0xA002,0x551F,0x551E,0xA020,0xA010,0xA008,0xA004,0xA002,0x551D,0x551C,0xA002,0x551A,0x5519,0xA004,0xA002,0x5518, 0x5517,0xA002,0x5516,0x5515,0xA008,0xA004,0xA002,0x5513,0x5512,0xA002,0x550E,0x550D,0xA004,0xA002,0x550C,0x550B, 0xA002,0x550A,0x5508,0xA010,0xA008,0xA004,0xA002,0x5505,0x5504,0xA002,0x5503,0x5502,0xA004,0xA002,0x5500,0x54FE, 0xA002,0x54FB,0x54F9,0xA008,0xA004,0xA002,0x54F8,0x54F7,0xA002,0x54F6,0x54F5,0xA004,0xA002,0x54F4,0x54F1,0xA002, 0x54F0,0x54EF,0xA082,0xA037,0xA000,0xA01E,0xA00E,0xA006,0xA002,0x54EC,0xA002,0x54EB,0x54E4,0xA004,0xA002,0x54E3, 0x54E2,0xA002,0x54E1,0x54E0,0xA008,0xA004,0xA002,0x54DB,0x54D8,0xA002,0x54D6,0x54CB,0xA004,0xA002,0x54CA,0x54C5, 0xA002,0x54C3,0x54BE,0xA010,0xA008,0xA004,0xA002,0x54BC,0x54BA,0xA002,0x54B9,0x54B7,0xA004,0xA002,0x54B6,0x54B5, 0xA002,0x54B2,0x54B0,0xA000,0xA004,0xA002,0x54AE,0x54A5,0xA000,0x54A2,0xA00B,0xA001,0xA001,0xA001,0xA004,0xA002, 0x54A1,0x54A0,0xA002,0x549F,0x549E,0xA020,0xA010,0xA008,0xA004,0xA002,0x549C,0x5498,0xA002,0x5497,0x5493,0xA004, 0xA002,0x5491,0x548D,0xA002,0x548A,0x5489,0xA008,0xA004,0xA002,0x5488,0x5487,0xA002,0x5485,0x5483,0xA004,0xA002, 0x5481,0x547F,0xA002,0x547E,0x547A,0xA010,0xA008,0xA004,0xA002,0x5479,0x5474,0xA002,0x5470,0x546F,0xA004,0xA002, 0x546E,0x546D,0xA002,0x546C,0x546B,0xA008,0xA004,0xA002,0x546A,0x5469,0xA002,0x5467,0x5465,0xA004,0xA002,0x5463, 0x5461,0xA002,0x5460,0x545F,0xA07E,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x545E,0xA002,0x545D,0x545A,0xA004,0xA002, 0x5451,0x544F,0xA002,0x544E,0x544D,0xA008,0xA004,0xA002,0x544C,0x5449,0xA002,0x5447,0x5445,0xA004,0xA002,0x5444, 0x5442,0xA002,0x5441,0x543F,0xA010,0xA008,0xA004,0xA002,0x543D,0x543A,0xA002,0x5437,0x5436,0xA004,0xA002,0x5433, 0x5430,0xA002,0x542A,0x5425,0xA008,0xA004,0xA002,0x5424,0x5422,0xA002,0x541C,0x541A,0xA004,0xA002,0x5419,0x5418, 0xA002,0x5414,0x540B,0xA020,0xA010,0xA008,0xA004,0xA002,0x5407,0x5405,0xA002,0x5402,0x5400,0xA004,0xA002,0x53FF, 0x53FE,0xA002,0x53FA,0x53F4,0xA008,0xA004,0xA002,0x53E7,0x53E2,0xA002,0x53E1,0x53DE,0xA004,0xA002,0x53DD,0x53DC, 0xA002,0x53DA,0x53D5,0xA010,0xA008,0xA004,0xA002,0x53D3,0x53D2,0xA002,0x53D0,0x53CF,0xA004,0xA002,0x53CE,0x53C7, 0xA002,0x53C6,0x53C5,0xA008,0xA004,0xA002,0x53C4,0x53C3,0xA002,0x53C0,0x53BE,0xA004,0xA002,0x53BD,0x53BC,0xA002, 0x53BA,0x53B9,0xA03F,0xA020,0xA010,0xA008,0xA004,0xA002,0x53B8,0x53B7,0xA002,0x53B5,0x53B4,0xA004,0xA002,0x53B3, 0x53B2,0xA002,0x53B1,0x53B0,0xA008,0xA004,0xA002,0x53AF,0x53AD,0xA002,0x53AC,0x53AB,0xA004,0xA002,0x53AA,0x53A7, 0xA002,0x53A4,0x53A1,0xA010,0xA008,0xA004,0xA002,0x53A0,0x539E,0xA002,0x539C,0x539B,0xA004,0xA002,0x5399,0x5397, 0xA002,0x5396,0x5394,0xA008,0xA004,0xA002,0x5393,0x5392,0xA002,0x5391,0x5390,0xA003,0xA001,0x538F,0xA002,0x538E, 0x538A,0xA020,0xA010,0xA008,0xA004,0xA002,0x5388,0x5387,0xA002,0x5383,0x5381,0xA004,0xA002,0x5380,0x537E,0xA002, 0x537D,0x537C,0xA008,0xA004,0xA002,0x537B,0x5379,0xA002,0x5376,0x5372,0xA004,0xA002,0x536D,0x536C,0xA002,0x536A, 0x5368,0xA010,0xA008,0xA004,0xA002,0x5365,0x535D,0xA002,0x535B,0x5359,0xA004,0xA002,0x5358,0x5354,0xA002,0x5350, 0x534D,0xA008,0xA004,0xA002,0x534C,0x534B,0xA002,0x5346,0x5344,0xA004,0xA002,0x5342,0x5340,0xA002,0x533D,0x533C, 0xA180,0xA083,0xA03B,0xA000,0xA01E,0xA00E,0xA006,0xA002,0x5338,0xA002,0x5337,0x5336,0xA004,0xA002,0x5335,0x5334, 0xA002,0x5333,0x5332,0xA008,0xA004,0xA002,0x5331,0x5330,0xA002,0x532F,0x532D,0xA004,0xA002,0x532C,0x532B,0xA002, 0x5329,0x5328,0xA010,0xA008,0xA004,0xA002,0x5327,0x5325,0xA002,0x5324,0x5322,0xA004,0xA002,0x531F,0x531E,0xA002, 0x531C,0x531B,0xA008,0xA004,0xA002,0x5318,0x5314,0xA002,0x5313,0x5312,0xA000,0xA000,0x5311,0xA008,0xA001,0xA001, 0xA001,0xA001,0xA002,0x530E,0x530C,0xA020,0xA010,0xA008,0xA004,0xA002,0x530B,0x530A,0xA002,0x5309,0x5307,0xA004, 0xA002,0x5304,0x5303,0xA002,0x5302,0x5301,0xA008,0xA004,0xA002,0x52FD,0x52FC,0xA002,0x52FB,0x52F8,0xA004,0xA002, 0x52F7,0x52F6,0xA002,0x52F5,0x52F4,0xA010,0xA008,0xA004,0xA002,0x52F3,0x52F2,0xA002,0x52F1,0x52EF,0xA004,0xA002, 0x52EE,0x52ED,0xA002,0x52EC,0x52EB,0xA008,0xA004,0xA002,0x52EA,0x52E9,0xA002,0x52E8,0x52E7,0xA004,0xA002,0x52E6, 0x52E5,0xA002,0x52E3,0x52E2,0xA07E,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x52E1,0xA002,0x52E0,0x52DE,0xA004,0xA002, 0x52DD,0x52DC,0xA002,0x52DB,0x52DA,0xA008,0xA004,0xA002,0x52D9,0x52D7,0xA002,0x52D5,0x52D4,0xA004,0xA002,0x52D3, 0x52D1,0xA002,0x52CF,0x52CE,0xA010,0xA008,0xA004,0xA002,0x52CD,0x52CC,0xA002,0x52CA,0x52C8,0xA004,0xA002,0x52C6, 0x52C5,0xA002,0x52C4,0x52C2,0xA008,0xA004,0xA002,0x52C1,0x52C0,0xA002,0x52BD,0x52BC,0xA004,0xA002,0x52BB,0x52BA, 0xA002,0x52B9,0x52B8,0xA020,0xA010,0xA008,0xA004,0xA002,0x52B7,0x52B6,0xA002,0x52B5,0x52B4,0xA004,0xA002,0x52B0, 0x52AF,0xA002,0x52AE,0x52A7,0xA008,0xA004,0xA002,0x52A6,0x52A5,0xA002,0x52A4,0x529C,0xA004,0xA002,0x529A,0x5299, 0xA002,0x5298,0x5297,0xA010,0xA008,0xA004,0xA002,0x5296,0x5295,0xA002,0x5294,0x5292,0xA004,0xA002,0x5291,0x528F, 0xA002,0x528E,0x528D,0xA008,0xA004,0xA002,0x528C,0x528B,0xA002,0x528A,0x5289,0xA004,0xA002,0x5287,0x5286,0xA002, 0x5285,0x5284,0xA03F,0xA020,0xA010,0xA008,0xA004,0xA002,0x5283,0x5280,0xA002,0x527E,0x527C,0xA004,0xA002,0x527B, 0x527A,0xA002,0x5279,0x5278,0xA008,0xA004,0xA002,0x5277,0x5276,0xA002,0x5275,0x5274,0xA004,0xA002,0x5273,0x5271, 0xA002,0x5270,0x526E,0xA010,0xA008,0xA004,0xA002,0x526D,0x526C,0xA002,0x526B,0x5268,0xA004,0xA002,0x5266,0x5264, 0xA002,0x5263,0x5262,0xA008,0xA004,0xA002,0x5260,0x525F,0xA002,0x525D,0x525B,0xA004,0xA002,0x525A,0x5259,0xA001, 0x5258,0xA020,0xA010,0xA008,0xA004,0xA002,0x5257,0x5255,0xA002,0x5253,0x5252,0xA004,0xA002,0x524F,0x524E,0xA002, 0x524B,0x5249,0xA008,0xA004,0xA002,0x5248,0x5247,0xA002,0x5246,0x5245,0xA004,0xA002,0x5244,0x523E,0xA002,0x523C, 0x5235,0xA010,0xA008,0xA004,0xA002,0x5234,0x5232,0xA002,0x5231,0x522F,0xA004,0xA002,0x522C,0x522A,0xA002,0x5227, 0x5226,0xA008,0xA004,0xA002,0x5225,0x5223,0xA002,0x5222,0x5221,0xA004,0xA002,0x521F,0x521E,0xA002,0x521C,0x5215, 0xA07F,0xA03E,0xA000,0xA01E,0xA00E,0xA006,0xA002,0x5214,0xA002,0x5213,0x5210,0xA004,0xA002,0x520F,0x520C,0xA002, 0x520B,0x5209,0xA008,0xA004,0xA002,0x5205,0x5204,0xA002,0x51FE,0x51F7,0xA004,0xA002,0x51F4,0x51F2,0xA002,0x51F1, 0x51EE,0xA010,0xA008,0xA004,0xA002,0x51EC,0x51EA,0xA002,0x51E9,0x51E8,0xA004,0xA002,0x51E7,0x51E6,0xA002,0x51E5, 0x51E3,0xA008,0xA004,0xA002,0x51E2,0x51DF,0xA002,0x51DE,0x51DC,0xA004,0xA002,0x51DA,0x51D9,0xA000,0x51D8,0xA001, 0xA020,0xA010,0xA008,0xA004,0xA002,0x51D7,0x51D6,0xA002,0x51D5,0x51D4,0xA004,0xA002,0x51D3,0x51D2,0xA002,0x51D0, 0x51CE,0xA008,0xA004,0xA002,0x51CD,0x51CA,0xA002,0x51C8,0x51C5,0xA004,0xA002,0x51C3,0x51C2,0xA002,0x51C1,0x51BF, 0xA010,0xA008,0xA004,0xA002,0x51BE,0x51BA,0xA002,0x51B9,0x51B8,0xA004,0xA002,0x51B4,0x51AE,0xA002,0x51AD,0x51AA, 0xA008,0xA004,0xA002,0x51A9,0x51A8,0xA002,0x51A7,0x51A6,0xA004,0xA002,0x51A3,0x51A1,0xA002,0x519F,0x519E,0xA07E, 0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x519D,0xA002,0x519A,0x5198,0xA004,0xA002,0x5194,0x5193,0xA002,0x5191,0x5190, 0xA008,0xA004,0xA002,0x518F,0x518E,0xA002,0x518B,0x518A,0xA004,0xA002,0x5187,0x5186,0xA002,0x5184,0x5183,0xA010, 0xA008,0xA004,0xA002,0x517F,0x517E,0xA002,0x517A,0x5172,0xA004,0xA002,0x516F,0x516A,0xA002,0x5169,0x5167,0xA008, 0xA004,0xA002,0x5166,0x5164,0xA002,0x5163,0x5161,0xA004,0xA002,0x5160,0x515F,0xA002,0x515E,0x515D,0xA020,0xA010, 0xA008,0xA004,0xA002,0x515B,0x5159,0xA002,0x5158,0x5157,0xA004,0xA002,0x5153,0x5152,0xA002,0x5150,0x514F,0xA008, 0xA004,0xA002,0x514E,0x514C,0xA002,0x514A,0x5147,0xA004,0xA002,0x5142,0x513E,0xA002,0x513D,0x513C,0xA010,0xA008, 0xA004,0xA002,0x513B,0x513A,0xA002,0x5139,0x5138,0xA004,0xA002,0x5137,0x5136,0xA002,0x5135,0x5134,0xA008,0xA004, 0xA002,0x5133,0x5132,0xA002,0x5131,0x5130,0xA004,0xA002,0x512F,0x512E,0xA002,0x512D,0x512C,0xA040,0xA020,0xA010, 0xA008,0xA004,0xA002,0x512B,0x512A,0xA002,0x5129,0x5128,0xA004,0xA002,0x5127,0x5126,0xA002,0x5125,0x5124,0xA008, 0xA004,0xA002,0x5123,0x5122,0xA002,0x5120,0x511F,0xA004,0xA002,0x511E,0x511D,0xA002,0x511C,0x511B,0xA010,0xA008, 0xA004,0xA002,0x511A,0x5119,0xA002,0x5118,0x5117,0xA004,0xA002,0x5116,0x5115,0xA002,0x5114,0x5113,0xA008,0xA004, 0xA002,0x5111,0x5110,0xA002,0x510F,0x510E,0xA004,0xA002,0x510D,0x510C,0xA002,0x510A,0x5109,0xA01F,0xA00F,0xA007, 0xA003,0xA001,0x5108,0xA002,0x5105,0x5104,0xA004,0xA002,0x5103,0x5102,0xA002,0x5101,0x5100,0xA008,0xA004,0xA002, 0x50FF,0x50FE,0xA002,0x50FD,0x50FC,0xA004,0xA002,0x50FA,0x50F9,0xA002,0x50F8,0x50F7,0xA010,0xA008,0xA004,0xA002, 0x50F6,0x50F4,0xA002,0x50F2,0x50F1,0xA004,0xA002,0x50F0,0x50EF,0xA002,0x50EB,0x50EA,0xA008,0xA004,0xA002,0x50E9, 0x50E8,0xA002,0x50E5,0x50E4,0xA004,0xA002,0x50E3,0x50E2,0xA002,0x50E1,0x50E0,0xA2FF,0xA180,0xA083,0xA045,0xA03E, 0xA01E,0xA00E,0xA006,0xA002,0x50DF,0xA002,0x50DE,0x50DD,0xA004,0xA002,0x50DC,0x50DB,0xA002,0x50D9,0x50D8,0xA008, 0xA004,0xA002,0x50D7,0x50D5,0xA002,0x50D4,0x50D3,0xA004,0xA002,0x50D2,0x50D1,0xA002,0x50D0,0x50CE,0xA010,0xA008, 0xA004,0xA002,0x50CD,0x50CC,0xA002,0x50CB,0x50CA,0xA004,0xA002,0x50C9,0x50C8,0xA002,0x50C7,0x50C6,0xA008,0xA004, 0xA002,0x50C5,0x50C4,0xA002,0x50C3,0x50C2,0xA004,0xA002,0x50C1,0x50C0,0xA002,0x50BF,0x50BE,0xA000,0xA000,0xA000, 0xA000,0xA000,0x50BD,0xA001,0xA01D,0xA00D,0xA005,0xA001,0xA002,0x50BC,0x50B9,0xA004,0xA002,0x50B8,0x50B7,0xA002, 0x50B6,0x50B5,0xA008,0xA004,0xA002,0x50B4,0x50B3,0xA002,0x50B1,0x50B0,0xA004,0xA002,0x50AF,0x50AE,0xA002,0x50AD, 0x50AB,0xA010,0xA008,0xA004,0xA002,0x50AA,0x50A6,0xA002,0x50A4,0x50A2,0xA004,0xA002,0x50A1,0x50A0,0xA002,0x509F, 0x509E,0xA008,0xA004,0xA002,0x509D,0x509C,0xA002,0x509B,0x509A,0xA004,0xA002,0x5099,0x5098,0xA002,0x5097,0x5096, 0xA07E,0xA03E,0xA01E,0xA00E,0xA006,0xA002,0x5095,0xA002,0x5094,0x5093,0xA004,0xA002,0x5092,0x5091,0xA002,0x5090, 0x508F,0xA008,0xA004,0xA002,0x508E,0x508C,0xA002,0x508B,0x508A,0xA004,0xA002,0x5089,0x5087,0xA002,0x5086,0x5084, 0xA010,0xA008,0xA004,0xA002,0x5083,0x5082,0xA002,0x5081,0x507D,0xA004,0xA002,0x507C,0x507A,0xA002,0x5079,0x5078, 0xA008,0xA004,0xA002,0x5075,0x5074,0xA002,0x5073,0x5072,0xA004,0xA002,0x5071,0x5070,0xA002,0x506F,0x506E,0xA020, 0xA010,0xA008,0xA004,0xA002,0x506D,0x506B,0xA002,0x506A,0x5069,0xA004,0xA002,0x5068,0x5067,0xA002,0x5066,0x5064, 0xA008,0xA004,0xA002,0x5063,0x5062,0xA002,0x5061,0x5060,0xA004,0xA002,0x505F,0x505E,0xA002,0x505D,0x505B,0xA010, 0xA008,0xA004,0xA002,0x5059,0x5058,0xA002,0x5057,0x5056,0xA004,0xA002,0x5054,0x5053,0xA002,0x5052,0x5051,0xA008, 0xA004,0xA002,0x5050,0x504D,0xA002,0x504B,0x504A,0xA004,0xA002,0x5049,0x5046,0xA002,0x5045,0x5044,0xA040,0xA020, 0xA010,0xA008,0xA004,0xA002,0x5042,0x5041,0xA002,0x5040,0x503F,0xA004,0xA002,0x503D,0x503B,0xA002,0x5039,0x5038, 0xA008,0xA004,0xA002,0x5037,0x5036,0xA002,0x5035,0x5034,0xA004,0xA002,0x5033,0x5032,0xA002,0x5031,0x5030,0xA010, 0xA008,0xA004,0xA002,0x502F,0x502B,0xA002,0x5027,0x5024,0xA004,0xA002,0x5023,0x5022,0xA002,0x5020,0x501E,0xA008, 0xA004,0xA002,0x501D,0x501B,0xA002,0x5017,0x5016,0xA004,0xA002,0x5015,0x5013,0xA002,0x5011,0x5010,0xA01F,0xA00F, 0xA007,0xA004,0xA002,0x500E,0x500B,0xA001,0x500A,0xA004,0xA002,0x5009,0x5008,0xA002,0x5007,0x5006,0xA008,0xA004, 0xA002,0x5005,0x5004,0xA002,0x5003,0x5002,0xA004,0xA002,0x5001,0x5000,0xA002,0x4FFF,0x4FFD,0xA010,0xA008,0xA004, 0xA002,0x4FFC,0x4FFB,0xA002,0x4FF9,0x4FF7,0xA004,0xA002,0x4FF6,0x4FF5,0xA002,0x4FF4,0x4FF2,0xA008,0xA004,0xA002, 0x4FF0,0x4FEC,0xA002,0x4FEB,0x4FE7,0xA004,0xA002,0x4FE5,0x4FE4,0xA002,0x4FE2,0x4FE0,0xA082,0xA048,0xA03E,0xA01E, 0xA00E,0xA006,0xA002,0x4FDB,0xA002,0x4FD9,0x4FD6,0xA004,0xA002,0x4FD5,0x4FD4,0xA002,0x4FD3,0x4FD2,0xA008,0xA004, 0xA002,0x4FCD,0x4FCC,0xA002,0x4FCB,0x4FC9,0xA004,0xA002,0x4FC8,0x4FC7,0xA002,0x4FC6,0x4FC2,0xA010,0xA008,0xA004, 0xA002,0x4FC1,0x4FC0,0xA002,0x4FBE,0x4FBD,0xA004,0xA002,0x4FBC,0x4FBB,0xA002,0x4FBA,0x4FB9,0xA008,0xA004,0xA002, 0x4FB8,0x4FB7,0xA002,0x4FB6,0x4FB4,0xA004,0xA002,0x4FB3,0x4FB2,0xA002,0x4FB1,0x4FB0,0xA000,0xA000,0xA000,0xA004, 0xA002,0x4FAD,0x4FAB,0xA000,0x4FA4,0xA001,0xA019,0xA009,0xA001,0xA004,0xA002,0x4FA2,0x4FA1,0xA002,0x4F9F,0x4F9E, 0xA008,0xA004,0xA002,0x4F9C,0x4F9A,0xA002,0x4F99,0x4F98,0xA004,0xA002,0x4F96,0x4F95,0xA002,0x4F93,0x4F92,0xA010, 0xA008,0xA004,0xA002,0x4F90,0x4F8E,0xA002,0x4F8C,0x4F8A,0xA004,0xA002,0x4F87,0x4F86,0xA002,0x4F85,0x4F82,0xA008, 0xA004,0xA002,0x4F81,0x4F80,0xA002,0x4F7D,0x4F7A,0xA004,0xA002,0x4F79,0x4F78,0xA002,0x4F77,0x4F75,0xA07E,0xA03E, 0xA01E,0xA00E,0xA006,0xA002,0x4F72,0xA002,0x4F71,0x4F6E,0xA004,0xA002,0x4F6D,0x4F6B,0xA002,0x4F6A,0x4F68,0xA008, 0xA004,0xA002,0x4F66,0x4F62,0xA002,0x4F61,0x4F56,0xA004,0xA002,0x4F54,0x4F52,0xA002,0x4F4C,0x4F4B,0xA010,0xA008, 0xA004,0xA002,0x4F4A,0x4F49,0xA002,0x4F48,0x4F47,0xA004,0xA002,0x4F45,0x4F44,0xA002,0x4F42,0x4F41,0xA008,0xA004, 0xA002,0x4F40,0x4F3F,0xA002,0x4F3E,0x4F3B,0xA004,0xA002,0x4F39,0x4F37,0xA002,0x4F35,0x4F33,0xA020,0xA010,0xA008, 0xA004,0xA002,0x4F31,0x4F2E,0xA002,0x4F2D,0x4F2C,0xA004,0xA002,0x4F29,0x4F28,0xA002,0x4F23,0x4F21,0xA008,0xA004, 0xA002,0x4F1D,0x4F1C,0xA002,0x4F16,0x4F15,0xA004,0xA002,0x4F14,0x4F13,0xA002,0x4F12,0x4F0C,0xA010,0xA008,0xA004, 0xA002,0x4F0B,0x4F08,0xA002,0x4F07,0x4F06,0xA004,0xA002,0x4F05,0x4F04,0xA002,0x4F03,0x4F02,0xA008,0xA004,0xA002, 0x4F00,0x4EFE,0xA002,0x4EFC,0x4EFA,0xA004,0xA002,0x4EF9,0x4EF8,0xA002,0x4EF4,0x4EF1,0xA040,0xA020,0xA010,0xA008, 0xA004,0xA002,0x4EEF,0x4EEE,0xA002,0x4EED,0x4EE9,0xA004,0xA002,0x4EE7,0x4EE6,0xA002,0x4EE2,0x4EE0,0xA008,0xA004, 0xA002,0x4EDC,0x4EDB,0xA002,0x4EDA,0x4ED2,0xA004,0xA002,0x4ED0,0x4ECF,0xA002,0x4ECC,0x4EC8,0xA010,0xA008,0xA004, 0xA002,0x4EBE,0x4EBD,0xA002,0x4EBC,0x4EB9,0xA004,0xA002,0x4EB8,0x4EB7,0xA002,0x4EB6,0x4EB4,0xA008,0xA004,0xA002, 0x4EB1,0x4EB0,0xA002,0x4EAF,0x4EAA,0xA004,0xA002,0x4EA3,0x4E9E,0xA002,0x4E9D,0x4E9C,0xA01F,0xA00F,0xA008,0xA004, 0xA002,0x4E99,0x4E97,0xA002,0x4E96,0x4E90,0xA003,0xA001,0x4E8A,0xA002,0x4E87,0x4E85,0xA008,0xA004,0xA002,0x4E84, 0x4E83,0xA002,0x4E82,0x4E81,0xA004,0xA002,0x4E80,0x4E7F,0xA002,0x4E7D,0x4E7C,0xA010,0xA008,0xA004,0xA002,0x4E7B, 0x4E7A,0xA002,0x4E79,0x4E78,0xA004,0xA002,0x4E77,0x4E76,0xA002,0x4E75,0x4E74,0xA008,0xA004,0xA002,0x4E72,0x4E6F, 0xA002,0x4E6E,0x4E6D,0xA004,0xA002,0x4E6C,0x4E6B,0xA002,0x4E6A,0x4E68,0xA000,0xA000,0xA000,0xA03E,0xA01E,0xA00E, 0xA006,0xA002,0x4E67,0xA002,0x4E65,0x4E64,0xA004,0xA002,0x4E63,0x4E62,0xA002,0x4E5B,0x4E5A,0xA008,0xA004,0xA002, 0x4E57,0x4E55,0xA002,0x4E51,0x4E4A,0xA004,0xA002,0x4E46,0x4E44,0xA002,0x4E42,0x4E41,0xA010,0xA008,0xA004,0xA002, 0x4E40,0x4E3C,0xA002,0x4E37,0x4E35,0xA004,0xA002,0x4E33,0x4E31,0xA002,0x4E2F,0x4E2E,0xA008,0xA004,0xA002,0x4E29, 0x4E26,0xA002,0x4E23,0x4E21,0xA004,0xA002,0x4E20,0x4E1F,0xA002,0x4E17,0x4E12,0xA000,0xA000,0xA008,0xA004,0xA002, 0x4E0F,0x4E06,0xA002,0x4E05,0x4E04,0xA000,0xA000,0x4E02,0xA001,0xA001,0xA001,0xA001,0xA001,0xA001,0xA001,0xA001, 0xA001,0xA001,0xA001,0xA001,0xA001,0xA001,0xA001,0x20AC, }; // cp936_to_ucs2_elements const TConvFlatTree cp936_to_ucs2 = { 0x0080, // min key 0xFE4F, // max key 0xA000, // links space start 0xEFFF, // links space end cp936_to_ucs2_numelems, // number of elements (treeval_t *)&cp936_to_ucs2_elements // elements }; // cp936_to_ucs2 libsynthesis-3.4.0.47.1/src/sysync_SDK/Sources/dataconversion.h000066400000000000000000000014101226375725500242730ustar00rootroot00000000000000#ifndef DataConversion_H #define DataConversion_H #include "sync_declarations.h" #ifdef __cplusplus #include using namespace sysync; namespace sysync { /** * convert data from one format into another * * @param aSession an active session handle * @param aFromTypeName the original datatype name, like "vCard30" * @param aToTypeName the generated datatype name * @retval aItemData original data, replaced with data in new format * @return true for success */ bool DataConversion(SessionH aSession, const char *aFromTypeName, const char *aToTypeName, std::string &aItemData); } // namespace sysync #endif /* __cplusplus */ #endif /* DataConversion_H */ libsynthesis-3.4.0.47.1/src/sysync_SDK/Sources/dbitem.cpp000066400000000000000000000666471226375725500231020ustar00rootroot00000000000000/* * File: dbitem.cpp * * Author: Beat Forster (bfo@synthesis.ch) * * * Example DBApi database adapter. * TDBItem class for item handling * * Copyright (c) 2005-2011 by Synthesis AG + plan44.ch * */ #include "sync_include.h" // import some global things #include "sync_dbapidef.h" #include "SDK_util.h" // include SDK utilities #include "SDK_support.h" #include "dbitem.h" #ifndef SYSYNC_ENGINE #include "stringutil.h" // local implementation of CStr <=> Str conversions #include "timeutil.h" // local implementation for time routines #endif namespace sysync { #define MyDB "DBItem" // 'DBItem' debug name #define FFirst 10000 // start number for item name (will be incremented) #define ARR_Sep '\x1D' // Array element separator within textdb file #define ARR_SepS "\x1D" // ... the same as string // ---- utility functions ---------------------------------------------------------- // Calculate the length of 's array expansion static int ArrLen( cAppCharP fKey, cAppCharP fVal ) { cAppCharP z= "[0]"; cAppCharP x= "[x]:"; int len= strlen( fVal ); // some additional space is needed for array elements, calculate it first int j= 0; int i; for (i= 0; i increase // don't forget element "[0]" len = 0; if (j>0) { len+= strlen( z ) + j*(strlen( fKey )+strlen( x )); // "yy[x]:" if (j>10) len+= j-10; // "[xx]" } // if return len; } // ArrLen /*! Create an item field */ void MakeField( TDBItemField* &act, cAppCharP field, cAppCharP fieldEnd, int &len, bool convert ) { MakeObj ( act ); if (fieldEnd) act->field.assign( field, (unsigned int)(fieldEnd-field) ); else act->field.assign( field ); if (convert) { string s= ""; // don't touch array separator StrToCStrAppend( act->field.c_str(), s, true, ARR_Sep ); act->field= s; } // if //printf( "len=%3d field='%s'\n", len, act->field.c_str() ); len+= act->field.length()+1; } // MakeField // Get a token string static string Token_Str( string aToken ) { if (aToken.empty()) return ""; else return "[" + aToken + "]"; } // Token_Str; // create a UTC token for time comparisons string CurrentTime( int secsOffs, bool dateOnly ) { string isoStr; lineartime_t f= secondToLinearTimeFactor * secsOffs; #ifdef SYSYNC_ENGINE timecontext_t tctx= TCTX_UTC; if (dateOnly) tctx= TCTX_DATEONLY; //lineartime_t timestamp= getSystemNowAs( TCTX_UTC, (GZones*)aGZones ); lineartime_t timestamp= getSystemNowAs( TCTX_UTC, NULL ); TimestampToISO8601Str( isoStr, timestamp + f, tctx, false, false ); #else lineartime_t timestamp= utcNowAsLineartime(); timeStampToISO8601 ( timestamp + f, isoStr, dateOnly ); #endif return isoStr; } // CurrentTime // Compare time of ISO8601 with / int CompareTokens( string aToken, string aLastToken, string aResumeToken ) { bool chg= aLastToken.empty() || // calculate newer condition aLastToken < aToken; bool res= !aResumeToken.empty() && // calculate resume condition aResumeToken < aToken && aResumeToken > aLastToken; int aStatus= ReadNextItem_Unchanged; if (chg) aStatus= ReadNextItem_Changed; if (res) aStatus= ReadNextItem_Resumed; return aStatus; } // CompareTokens // ------------------------------------------------------------------------- /* Combines and into string * support for blobs, tz names and array fields */ string KeyAndField( cAppCharP sKey, cAppCharP sField ) { cAppCharP fs= strstr( sField, ";" ); // semicolon pattern: BLOB, TZNAME, ... cAppCharP q = sField; cAppCharP qE; string s = sKey; if (fs) { s+= fs; return s; } // with semicolon int i= 0; while (true) { qE= strstr( q, ARR_SepS ); if (!qE && i==0) break; s+= '[' + IntStr( i ) + ']'; if (!qE) break; string tmp; tmp.assign( q, (unsigned int)( qE-q ) ); s+= ':' + tmp + '\n'; i++; q= qE+1; s+= sKey; } // loop s+= ":"; s+= q; return s; } // KeyAndField string KeyAndField( TDBItemField* actKey, TDBItemField* actField ) { return KeyAndField( actKey->field.c_str(), actField->field.c_str() ); } // KeyAndField void AddFields( string &aDat, string aAdd, cAppCharP param1, cAppCharP param2, cAppCharP param3, cAppCharP param4, cAppCharP param5 ) { string p; if (aAdd.empty()) return; int i= 1; while (true) { switch ( i ) { case 1 : p= param1; break; case 2 : p= param2; break; case 3 : p= param3; break; case 4 : p= param4; break; case 5 : p= param5; break; default: p= ""; } // switch string chk= "%" + IntStr( i++ ); string::size_type pos= aAdd.find( chk,0 ); if (pos==string::npos) break; aAdd.replace( pos,chk.length(), p ); } // loop if (!aDat.empty()) { cAppCharP c= aDat.c_str() + aDat.length()-1; // last char if (*c!='\n') aDat+= '\n'; } // if aDat+= aAdd; } // AddFields /* ------------------------------------------------------------------------ */ //! assign ID and callback void TDBItem::init( cAppCharP aItemID, cAppCharP aParentID, void* aCB, TDBItem* aNext ) { itemID = aItemID; parentID= aParentID; fCB = aCB; next = aNext; } // init //! assign ID and callback (overloaded) void TDBItem::init( cAppCharP aItemID, void* aCB, TDBItem* aNext ) { init( aItemID,"", aCB, aNext ); } // init // the combined item/parent string cAppCharP TDBItem::c_str() { fID= itemID; if (!parentID.empty()) { fID+= ","; fID+= parentID; } return fID.c_str(); } // c_str /* Get a specific item , which represents ,. * Returns error, if not found. * If is true (default), start at the beginning of the list, * else continue */ TSyError TDBItem::GetItem( cItemID aID, TDBItem* &actL, bool first ) { char* p= aID->parent; if (!p) p= const_cast(""); if (first) actL= this; while (ListNext( actL )) { if (strcmp( aID->item,actL->itemID.c_str() )==0 && strcmp( p, actL->parentID.c_str() )==0) return LOCERR_OK; } // while actL= NULL; return DB_NotFound; } // GetItem /* Overloaded for only w/o parent ID * Get a specific item , which represents * Returns error, if not found. */ TSyError TDBItem::GetItem( cAppCharP aItemID, TDBItem* &actL, bool first ) { ItemID_Struct a; a.item = (char*)aItemID; a.parent= NULL; return GetItem( &a, actL, first ); } // GetItem /* Overloaded for only w/o parent ID * Get a specific item , which represents * Returns error, if not found. */ TSyError TDBItem::GetItem_2( cAppCharP aItemID, cAppCharP aField2, TDBItem* mpL, TDBItem* &act ) { TSyError err= LOCERR_OK; ItemID_Struct a; a.item = (char*)aItemID; a.parent= NULL; bool first= true; string s; while (true) { err= GetItem( &a, act, first ); if (err) break; // not found mpL->Field ( "2",act, s ); if (strcmp( aField2,s.c_str() )==0) break; // found first= false; } // loop return err; } // GetItem_2 TSyError TDBItem::DeleteItem( TDBItem* actL ) { TDBItem* prvL= actL; ListBack( prvL, this ); // search for the previous element prvL->next= actL->next; actL->next= NULL; // avoid destroying the whole chain delete actL; fChanged= true; return LOCERR_OK; } /* DeleteItem */ TSyError TDBItem::DeleteItem( cItemID aID ) { TSyError err= DB_NotFound; TDBItem* actI; err= GetItem( aID, actI ); if (err) return err; // item must be not available as parent element TDBItem* actL= this; while (ListNext( actL )) { if (strcmp( aID->item,actL->parentID.c_str() )==0) return DB_Forbidden; } // while return DeleteItem( actI ); } /* DeleteItem */ TSyError TDBItem::DeleteItem( cAppCharP aItemID ) { ItemID_Struct a; a.item = (char*)aItemID; a.parent= const_cast(""); return DeleteItem( &a ); } // DeleteItem // parent element must be "" or exist TSyError TDBItem::ParentExist( cAppCharP aItemID, cAppCharP aParentID ) { if (*aParentID==0) return LOCERR_OK; if (strcmp( aItemID,aParentID )==0) return DB_Forbidden; // no recursion allowed TDBItem* actL= this; while (ListNext( actL )) { if (strcmp( aParentID,actL->itemID.c_str() )==0) return LOCERR_OK; } // while return DB_NotFound; } // ParentExists void TDBItem::CreateItem( string newItemID, string parentID, TDBItem* &actL ) { TDBItemField* actK; TDBItemField* actF; TDBItem* newL= new TDBItem; // create item root newL->fCB= fCB; // inherit callback actF= &newL->item; newL->itemID = newItemID; newL->parentID= parentID; actL->next= newL; ListNext( actL ); int n= 0; actK= &item; while (ListNext( actK )) { // number of elements according to the key MakeField ( actF, "", NULL, actL->len ); n++; } // while actL->len--; // termination is included already fChanged= true; } // CreateItem /* The strategy is simple: Take ID="10000" as start, go thru the whole list. * if found, increment. Insert new element at the end. */ TSyError TDBItem::CreateEmptyItem( ItemID aID, string &newItemID, TDBItem* &actL, string newID ) { TSyError err; int itemID= atoi( newID.c_str() ); if (itemID==0) itemID= atoi( F_First ); TDBItem* last; //TDBItem* newL; //TDBItemField* actK; //TDBItemField* actF; // parent element must be "" or exist err= ParentExist( "", aID->parent ); if (err) return err; newItemID= aID->item; if (newItemID.empty()) { actL= this; while (true) { last= actL; if (!ListNext( actL )) break; int itemNum= atoi( actL->itemID.c_str() ); if (itemNum>=itemID) itemID= itemNum+1; // assign largest unique number } // while newItemID= IntStr( itemID ); actL = last; } else { actL= LastElem( this ); // get the last element } // if CreateItem( newItemID, aID->parent, actL ); /* // create item root newL= new TDBItem; newL->fCB= fCB; // inherit callback actF= &newL->item; newL->itemID = newItemID; newL->parentID= aID->parent; actL->next= newL; ListNext( actL ); int n= 0; actK= &item; while (ListNext( actK )) { // number of elements according to the key MakeField ( actF, "", NULL, actL->len ); n++; } // while actL->len--; // termination is included already */ return LOCERR_OK; } // CreateEmptyItem TSyError TDBItem::CreateEmptyItem( cAppCharP aParentID, string &newItemID, TDBItem* &actL ) { ItemID_Struct a; a.item = const_cast(""); a.parent= (char*)aParentID; return CreateEmptyItem ( &a, newItemID, actL ); } // CreateEmptyItem TSyError TDBItem::CreateEmptyItem( string &newItemID, TDBItem* &actL ) { return CreateEmptyItem( "", newItemID, actL ); } // CreateEmptyItem /*! * Check, if can be interpreted as number */ static bool NumKey( cAppCharP aKey, int &iKey ) { iKey= atoi( aKey ); return iKey!=0 || strcmp( aKey,"0")==0; } // NumKey /* Update the specific field with the new value . * Create the whole bunch of missing keys, if not yet available. */ TSyError TDBItem::UpdateField( void* aCB, cAppCharP fKey, cAppCharP fVal, TDBItem* hdI, bool asName ) { TSyError err= DB_NotFound; char* ts; string s; int iKey= 0, iLast= -1; // start value if data base is empty TDBItemField* actK= &item; // the key TDBItemField* lastK; TDBItemField* actI= &hdI->item; TDBItemField* lastI; if (aCB==NULL) aCB= fCB; // get the default callback, if not overridden by // check, if the specific element is already existing while (true) { lastK= actK; if (!ListNext( actK )) break; lastI= actI; // a not existing field will be created (empty) if (!ListNext( actI )) { actI= lastI; MakeField ( actI, "", NULL, hdI->len ); } // if if (strcmp( fKey,actK->field.c_str())==0) { int oldLen= actI->field.length(); int newLen= strlen( fVal ) + ArrLen( fKey,fVal ); hdI->len += newLen-oldLen; // adapt the whole length actI->field= fVal; // and assign value of the new field err= LOCERR_OK; // the new value is assigned, everything is ok fChanged= true; // must be marked for a change break; } // if } // while // ----------------------------------------------------- if (err && !asName) { if (!lastK->field.empty()) iLast= atoi( lastK->field.c_str() ); if (!NumKey( fKey,iKey )) err= DB_NotFound; // not a valid key } // if if (err!=DB_NotFound) { s= KeyAndField( fKey,fVal ); // create name info string vv= hdI->c_str(); if (!vv.empty()) vv= " " + Parans( vv ) + " "; // create debug info string eInfo; if (err) eInfo= " err=" + IntStr( err ); DEBUG_Exotic_DB( aCB, MyDB,"UpdateField", "%s'%s'%s", vv.c_str(), s.c_str(), eInfo.c_str() ); return err; } // if if (asName) iKey= iLast+1; // create just one element // now add the missing key fields int i; for (i= iLast+1; i<=iKey; i++) { string tmp= IntStr( i ); if (asName) ts= (char*)fKey; else ts= (char*)tmp.c_str(); MakeField( lastK, ts, NULL, len ); // create a new key element } // for // and the same for each item TDBItem* actV= this; while (ListNext( actV )) { actI= &actV->item; while (true) { lastI= actI; if (!ListNext( actI )) { for (i= iLast+1; i<=iKey; i++) MakeField( lastI, "", NULL, actV->len ); break; } // if } // loop } // while // the task is not yet done => do it again (recursively) return UpdateField( aCB, fKey, fVal, hdI, asName ); } // UpdateField TSyError TDBItem::Field( cAppCharP fKey, TDBItem* hdI, string &s ) { TDBItemField* actK= &item; TDBItemField* actF= &hdI->item; while (ListNext( actK,actF )) { if (strcmp( actK->field.c_str(),fKey )==0) { s= actF->field.c_str(); return LOCERR_OK; } // if } // while return DB_NotFound; } // Field static void ReplaceArrElem( string &s, int n, string arrElem ) { int pos, v= 0; bool fnd; int i= n; while (true) { pos= v; v= s.find( ARR_Sep, pos ); fnd= v!=(int)string::npos; if (!fnd) v= s.length(); if (i<=0) break; if (!fnd) { if (arrElem.empty()) return; // adding not needed s+= ARR_Sep; } // if v++; i--; } // while s= s.substr( 0, pos ) + arrElem + s.substr( v, s.length()-v ); } // ReplaceArrElem static void CutEmptyEnd( string &s ) { while (!s.empty()) { uInt32 last= s.length()-1; if (s.rfind( ARR_Sep, last )!=last) break; // last char ? s= s.substr ( 0, last ); // if yes, cut it } // while } // CutEmptyEnd static int ArrIndex( cAppCharP q, cAppCharP qN ) { int n= 0; if (qN) { string s; s.assign( q, (unsigned int)( qN-q ) ); CutBracks( s ); n= atoi ( s.c_str() ); } // if return n; } // ArrIndex void TDBItem::Array_TDB( cAppCharP &q, cAppCharP aKey, TDBItem* hdI, string &aVal ) { cAppCharP qR; cAppCharP qN; cAppCharP qA; bool firstElem= true; // true during first element handling string s; // temporary local string int n; //aVal= ""; // init string //string org; Field( aKey, hdI, aVal ); // as it is now while (*q!='\0') { qN= strstr( q,":" ); qA= strstr( q,"[" ); if (!qN) break; // no more regular elements if (!qA || qNfToken= aNewToken; while (*q!='\0') { // break the string ':''\n' into key and value cAppCharP qN= strstr( q, StdPattern ); // normal notation cAppCharP qA= strstr( q,ArrayPattern ); // try array notation //cAppCharP qB= strstr( q, BlobPattern ); // try blob notation //cAppCharP qT= strstr( q, TZPattern ); // try tzname notation cAppCharP qS= strstr( q, ";" ); // semicolon notation bool isArr = qA && (!qN || qA DEBUG_Block ( aCB, DIT, itemID.c_str(), s.c_str() ); // hierarchical log TDBItem* actI= this; while (ListNext( actI )) { // for each item do ... if (*specificItem!=0 && strcmp( specificItem,actI->itemID.c_str() )!=0 ) continue; s= Token_Str( actI->fToken ); DEBUG_( aCB, "%s= (%s) %s", this->c_str(), actI->c_str(), s.c_str() ); TDBItemField* actK= &item; // the key identifier TDBItemField* actF= &actI->item; // the item current field cAppCharP f; while (ListNext( actK )) { // for each element do ... if (ListNext( actF )) f= actF->field.c_str(); else f= ""; // ""; if (allFields || !actF->field.empty()) { // display only under conditions s= KeyAndField( actK->field.c_str(), f ); DEBUG_( aCB, "%s", s.c_str() ); } // if } // while } // while DEBUG_EndBlock( aCB, DIT ); } // Disp_Items static void AddKey( void* aCB, bool withKey, cAppCharP qA, cAppCharP qR, int n, TDBItemField* &actF, int &len ) { if (withKey) MakeField( actF, qA,qR, len, true ); else { // just numbering, starting with "0" string tmp= IntStr( n-2 ); MakeField( actF, tmp.c_str(),NULL, len, true ); DEBUG_Exotic_DB( aCB, MyDB,"AddKey", "'%s'", tmp.c_str() ); } // if } // AddKey TSyError TDBItem::LoadDB( bool withKey, cAppCharP aPrefix, void* aCB ) { cAppCharP LDB= "-LoadDB"; // collapsed display with '-' at the beginning TSyError err= LOCERR_OK; char ch, prv= '\0'; char* q; char* qA; char* qR; char* qC; // create root structure TDBItem* actL= this; TDBItem* actI= NULL; TDBItem* newL= NULL; TDBItemField* actF; TDBItemField* actT; bool first= true; int n= 0, nMax= 0; if (fLoaded) return LOCERR_OK; if (withKey) init( aPrefix, aCB ); if (aCB==NULL) aCB= fCB; // get the default callback, if not overridden by FILE* f= fopen( fFileName.c_str(),"rb" ); if (!f) err= DB_NotFound; /* empty DB */ string s= "err=" + IntStr( err ); string rslt; DEBUG_Block( aCB, LDB, fFileName.c_str(), s.c_str() ); // hierarchical log if (!err) { while (true) { // loop ... bool is0D= false; // last line ended with 0D ? // get lines, make it compatible for Windows, Mac and Linux q= &ch; s= ""; while (true) { if (fread( q, 1,1, f ) != 1) { ; // error ignored } if (feof( f )) break; if (*q=='\x0D') { is0D= true; break; } if (*q=='\x0A') { if (!is0D) break; *q= prv; is0D= false; } // if s += ch; prv= ch; } // while if (s.empty() && feof( f )) break; // .. until end of file q= (char*)s.c_str(); // remove possible UTF-8 lead-in if ((q[0] & 0xFF) == 0xEF && (q[1] & 0xFF) == 0xBB && (q[2] & 0xFF) == 0xBF) { q+=3; // skip UTF-8 lead-in DEBUG_Exotic_DB( aCB, MyDB,"", "UTF-8 lead-in skipped" ); } // if if (*q=='\0') continue; // empty line ? ReplaceLoad( q, rslt ); // textdb specific => normal q= (char*)rslt.c_str(); DEBUG_Exotic_DB( aCB, MyDB,"", "line='%s'", q ); // create index tree if (first) { actT= &actL->item; n= 0; qA= q; while ( *qA!='\0') { qR= strstr( qA,"\t" ); if (!qR) qR= qA + strlen( qA ); // no tab to skip if (n>1) // the index itself is not a field AddKey( aCB, withKey, qA,qR, n, actT, actL->len ); n++; if (*qR=='\0') break; qA= qR+1; } // while nMax= n; // keep it for later appending of additional elements actI= actL; // save it for later use } // if // create item elements if (!first || !withKey) { n= 0; qA= q; while ( *qA!='\0') { qR= strstr( qA,"\t" ); if (!qR) qR= qA + strlen( qA ); // no tab to skip if (n==0) { newL= new TDBItem; // create new item root newL->fCB= fCB; // inherit callback actF= &newL->item; qC= strstr( qA,"," ); if (!qC || qC>qR) qC= qR; /* separate itemID/parentID, if comma separator available */ newL->itemID.assign ( qA, (unsigned int)(qC-qA) ); if (qC!=qR) qC++; newL->parentID.assign( qC, (unsigned int)(qR-qC) ); actL->next= newL; ListNext ( actL ); } else if (n==1) newL->fToken.assign( qA, (unsigned int)(qR-qA) ); else { MakeField( actF, qA,qR, actL->len, true ); //printf( "A: %3d\n", actL->len ); actL->len+= ArrLen( "xx", actF->field.c_str() ); //printf( "B: %3d\n", actL->len ); } // if if (n>=nMax && actI!=NULL) { if (n>1) { //printf( "indexLenV=%d\n", actI->len ); AddKey( aCB, withKey, "???",NULL, n, actT, actI->len ); //printf( "indexLenN=%d\n", actI->len ); } // if nMax++; // adapt the new limit } // if if (*qR=='\0') break; qA= qR+1; n++; } // while } // if actL->len--; // termination is included //printf( "C: %3d\n", actL->len ); //printf( "D: '%s'\n", q ); first= false; // first run is done } // while fclose( f ); fLoaded = true; fChanged= false; } // if DEBUG_EndBlock( aCB, LDB ); return err; } // LoadDB TSyError TDBItem::SaveDB( bool withKey, void* aCB ) { cAppCharP SDB= "-SaveDB"; // collapsed display with '-' at the beginning TSyError err= LOCERR_OK; if (!fChanged) return LOCERR_OK; // nothing changed, no saving if (fFileName.empty()) return DB_NotFound; if (aCB==NULL) aCB= fCB; // get the default callback, if not overridden by FILE* f= fopen( fFileName.c_str(),"wb" ); if (!f) err= DB_NotFound; string s= "err=" + IntStr( err ); string rslt; DEBUG_Block( aCB, SDB, fFileName.c_str(), s.c_str() ); // hierarchical log if (!err) { fputs( "\xEF\xBB\xBF", f ); // UTF-8 lead-in DEBUG_Exotic_DB( aCB, MyDB,"","UTF-8 lead-in written" ); string line; TDBItem* actI= this; while (withKey || ListNext( actI )) { line = actI->c_str(); // starting with the [","] line+= "\t"; line+= actI->fToken.c_str(); // append the timestamp int n= 0; TDBItemField* actF= &actI->item; // the item current field while (ListNext( actF )) { s= ""; // tab separated CStrToStrAppend( actF->field.c_str(), s, false, ARR_Sep ); // don't touch array separator ReplaceSave ( s.c_str(), rslt ); // normal => textdb specific line+= "\t" + rslt; n++; } // while int ii= line.length(); // remove empty items at the end while (ii>0) { if (line[ --ii ]!='\t') break; } line= line.substr( 0, ii+1 ); // now log and write the whole line DEBUG_DB( aCB, MyDB,"", "line='%s'", line.c_str() ); fprintf( f, "%s\r\n", line.c_str() ); withKey= false; } // while fclose( f ); fChanged= false; } // if DEBUG_EndBlock( aCB, SDB ); return err; } // SaveDB } /* namespace */ /* eof */ libsynthesis-3.4.0.47.1/src/sysync_SDK/Sources/dbitem.h000066400000000000000000000174771226375725500225440ustar00rootroot00000000000000/* * File: dbitem.h * * Author: Beat Forster (bfo@synthesis.ch) * * * Example DBApi database adapter. * TDBItem class for item handling * * Copyright (c) 2005-2011 by Synthesis AG + plan44.ch * */ #ifndef DBITEM_H #define DBITEM_H #include "sync_include.h" // import some global things #ifndef SYSYNC_ENGINE #include "stringutil.h" // local implementation of CStr <=> Str conversions #endif #define F_First "10000" // start number for item name (will be incremented) namespace sysync { // ---------- list templates ---------------------------------- //! go to the next element of . Returns true, if available template bool ListNext( T* &act ) { if (act) act= static_cast< T* >( act->next ); return act!=NULL; } // ListNext //! go to the next element of . Returns true, if available // the same with 2 parameters template bool ListNext( T1* &act1, T2* &act2 ) { return ListNext( act1 ) && ListNext( act2 ); } // ListNext template bool ListBack( T* &act, T* li ) // go to the previous element of . Returns true, if available { T* last; if (act==li) return false; do { last= li; } while (ListNext( li ) && li!=act); act= last; return true; } // ListBack template T* LastElem( T* li ) // go to the last element of . { T* act= NULL; ListBack( act,li ); return act; } // LastElem template void DeleteNext( T* &next, void* aCB= NULL, const char* s= "", bool dbg= false ) // delete the rest of the list { #ifndef ANDROID // no rtti support for Android if (dbg) DEBUG_Exotic_DB( aCB, "","Delete", "%s (%s)", typeid( T ).name(), s ); #endif if (next) { delete next; next= NULL; // don't let it undefined } // if } // DeleteNext template void MakeObj( T* &act ) // create an element at position of the given list { T* sv = static_cast< T* >( act->next ); // save it for linking later again act->next= static_cast< T* >( new T ); // create an element of the given type ListNext ( act ); act->next= sv; } // MakeObj // ---------- list class -------------------------------------- class TList : noncopyable { public: TList() { next= NULL; } // constructor virtual ~TList() { DeleteNext( next ); } // destructor (if not yet otherwise deleted) TList* next; // reference to the next element }; // TList // ---------- item field class -------------------------------- class TDBItemField : public TList { typedef TList inherited; public: TDBItemField() { next= NULL; } // constructor virtual ~TDBItemField() { TDBItemField** act= (TDBItemField**)&next; // destructor DeleteNext ( *act ); } string field; // the string field }; // TDBItemField // ---------- item class ------------------------------------- class TDBItem : public TDBItemField { typedef TDBItemField inherited; public: TDBItem( void* aCB= NULL ) { len= 1; fCB= aCB; fLoaded = false; fChanged= false; } // constructor virtual ~TDBItem() { TDBItem** act= (TDBItem**)&next; // destructor DeleteNext( *act, fCB, c_str(), true ); } TDBItemField item; // the header element int len; // length of all fields of this item bool fLoaded; // indicates, if already loaded bool fChanged; // indicates, if already changed string itemID; string parentID; const char* c_str(); // [","] void init( cAppCharP aItemID, cAppCharP aParentID, void* aCB= NULL, TDBItem* aNext= NULL ); // initalize void init( cAppCharP aItemID, void* aCB= NULL, TDBItem* aNext= NULL ); string fFileName; // the (full) file name for LoadDB/SaveDB private: string fID; // internal memory space for c_str() void Array_TDB ( cAppCharP &q, cAppCharP aKey, TDBItem* hdI, string &aVal ); public: string fToken; // the timestamp token (as string) void* fCB; // callback structure // two different versions, overloaded TSyError GetItem ( cItemID aID, TDBItem* &actL, bool first= true ); // get a specific item TSyError GetItem ( cAppCharP aItemID, TDBItem* &actL, bool first= true ); TSyError GetItem_2 ( cAppCharP aItemID, cAppCharP aField2, TDBItem* mpL, TDBItem* &actL ); // get item with specific field 0 // three different versions, overloaded TSyError DeleteItem ( cItemID aID ); TSyError DeleteItem ( cAppCharP aItemID ); TSyError DeleteItem ( TDBItem* actL ); TSyError ParentExist ( cAppCharP aItemID, cAppCharP aParentID ); void CreateItem ( string newItemID, string parentID, TDBItem* &actL ); // three different versions, overloaded TSyError CreateEmptyItem( ItemID aID, string &newItemID, TDBItem* &actL, string itemID= F_First ); TSyError CreateEmptyItem( cAppCharP aParentID, string &newItemID, TDBItem* &actL ); TSyError CreateEmptyItem ( string &newItemID, TDBItem* &actL ); TSyError UpdateField ( void* aCB, cAppCharP fKey, cAppCharP fVal, TDBItem* hdI= NULL, bool asName= true ); TSyError UpdateFields ( void* aCB, cAppCharP aItemData, TDBItem* hdI= NULL, bool asName= true, cAppCharP aNewToken= "" ); TSyError Field ( cAppCharP fKey, TDBItem* hdI, string &s ); bool SameField ( cAppCharP fKey, cAppCharP fVal, TDBItem* hdI ); void Disp_ItemData ( void* aCB, cAppCharP title, cAppCharP attrTxt, cAppCharP aItemData ); void Disp_Items ( void* aCB= NULL, cAppCharP txt= "", bool allFields= true, cAppCharP specificItem= "" ); // load and save the database from/to file TSyError LoadDB ( bool withKey, cAppCharP aPrefix= "", void* aCB= NULL ); TSyError SaveDB ( bool withKey, void* aCB= NULL ); }; // TDBItem // ---- utility functions ---------------------------------------------------------- /*! Create an item field */ void MakeField( TDBItemField* &act, cAppCharP field, cAppCharP fieldEnd, int &len, bool convert= false ); /*! Create a UTC token for time comparisons */ string CurrentTime( int secsOffs= 0, bool dateOnly= false ); /*! Compare time of ISO8601 with / */ int CompareTokens( string aToken, string aLastToken, string aResumeToken ); /*! combine key and field in a string */ string KeyAndField( cAppCharP sKey, cAppCharP sField ); string KeyAndField( TDBItemField* actKey, TDBItemField* actField ); /*! add some item fields to the beginning of . Result is . * If contains %1, it will be replaced by . * " " " %2, " " " " " */ void AddFields( string &aDat, string aAdd, cAppCharP param1= "", cAppCharP param2= "", cAppCharP param3= "", cAppCharP param4= "", cAppCharP param5= "" ); } /* namespace */ #endif /* DBITEM_H */ /* eof */ libsynthesis-3.4.0.47.1/src/sysync_SDK/Sources/engine_defs.h000066400000000000000000000360041226375725500235310ustar00rootroot00000000000000/** * @File engine_defs.h * * @Author Lukas Zeller (luz@plan44.ch) * Beat Forster (bfo@synthesis.ch) * * @brief Definitions needed for the common engine interface * * Copyright (c) 2007-2011 by Synthesis AG + plan44.ch * */ #ifndef ENGINE_DEFS_H #define ENGINE_DEFS_H #include "generic_types.h" #ifdef __cplusplus namespace sysync { #endif /* ---- supported charsets ---- */ enum TCharsetEnum { /** invalid */ CHS_UNKNOWN = 0, /** 7 bit ASCII-only, with nearest char conversion for umlauts etc. */ CHS_ASCII = 1, CHS_ANSI = 2, CHS_ISO_8859_1 = 3, CHS_UTF8 = 4, CHS_UTF16 = 5, CHS_GB2312 = 6, CHS_CP936 = 7, }; /* ---- line end modes ---- */ enum TLineendEnum { /** none specified */ LEM_NONE = 0, /** LF = 0x0A, Unix, Linux, MacOS X */ LEM_UNIX = 1, /** CR = 0x0D, Mac OS classic */ LEM_MAC = 2, /** CRLF = 0x0D 0x0A, Windows, DOS */ LEM_DOS = 3, /** as in C strings, '\n' which is 0x0A normally (but might be 0x0D on some platforms) */ LEM_CSTR = 4, /** 0x0B (filemaker tab-separated text format, CR is shown as 0x0B within fields */ LEM_FILEMAKER = 5 }; /* ---- literal quoting modes ---- */ enum TQuotingEnum { /** none specified */ QM_NONE = 0, /** single quote must be duplicated */ QM_DUPLSINGLE = 1, /** double quote must be duplicated */ QM_DUPLDOUBLE = 2, /** C-string-style escapes of CR,LF,TAB,BS,\," and ' (but no full c-string escape with \xXX etc.) */ QM_BACKSLASH = 3 }; /* ---- time formats ---- */ enum TTimeModeEnum { /** SySync lineartime (64 bit milliseconds) */ TMODE_LINEARTIME = 0, /** SySync lineardate (32 bit days) */ TMODE_LINEARDATE = 1, /** Unix epoch time (32 bit seconds) */ TMODE_UNIXTIME = 2, /** Unix epoch time (64 bit milliseconds) */ TMODE_UNIXTIME_MS = 3, /** Flag that can be added for time in UTC */ TMODE_FLAG_UTC = 0x8000, /** Flag that can be added for time as-is */ TMODE_FLAG_FLOATING = 0x4000, /** Mask to separate time mode */ TMODE_MODEMASK = 0x003F }; /* ---- path separator for settings key paths ---- */ #define SETTINGSKEY_PATH_SEPARATOR '/' /* ---- key/value special IDs ---- */ enum TKeyValEnum { /** special ID to signal unknown subkey or value */ KEYVAL_ID_UNKNOWN = -1, /** special ID to open first subkey */ KEYVAL_ID_FIRST = -2, /** special ID to open next subkey */ KEYVAL_ID_NEXT = -3, /** special ID to create new subkey (empty values) */ KEYVAL_ID_NEW = -4, /** special ID to create new subkey and initialize with (hard-coded or engine-config-predefined) default values */ KEYVAL_ID_NEW_DEFAULT = -5, /** special ID to create new subkey using previously opened subkey as template for initializing values */ KEYVAL_ID_NEW_DUP = -6, /** special ID for values that cannot be accessed by ID AT ALL */ KEYVAL_NO_ID = -7, /** special ID to specify entire contents of a container */ KEYVAL_ID_ALL = -8 }; /* ---- special value names ---- */ #define VALNAME_FIRST ".FIRST" /* for GetValueID(): get first value, for keys that support value iteration */ #define VALNAME_NEXT ".NEXT" /* for GetValueID(): get next value, for keys that support value iteration */ #define VALNAME_FLAG ".FLAG" /* for GetValueID(): get flag mask that can be added to value ID to get special attributes of a value instead of main value */ /* ---- special value name suffixes (not available for all settings keys, but primarily for item keys) ---- */ #define VALSUFF_NAME ".VALNAME" /* return field/value name as VALTYPE_TEXT */ #define VALSUFF_TYPE ".VALTYPE" /* return value's native type (VALTYPE_xxx) name as VALTYPE_INT16 */ #define VALSUFF_ARRSZ ".ARRAYSIZE" /* return size of array as VALTYPE_INT16. Returns DB_NotFound for non-array values */ #define VALSUFF_TZNAME ".TZNAME" /* if value is a time stamp, returns name of the time zone as VALTYPE_TEXT (empty=floating) */ #define VALSUFF_TZOFFS ".TZOFFS" /* if value is a time stamp, returns minute offset east of GMT as VALTYPE_INT16, DB_NotFound for floating timestamps */ #define VALSUFF_NORM ".NORM" /* return normalized value of field */ /* ---- value types ---- */ enum TValTypeEnum { /** Unknown */ VALTYPE_UNKNOWN = 0, /** 8-bit integer */ VALTYPE_INT8 = 1, /** 16-bit integer */ VALTYPE_INT16 = 2, /** 32-bit integer */ VALTYPE_INT32 = 3, /** 64-bit integer */ VALTYPE_INT64 = 4, /** enum (for the SDK user, this is equivalent to VALTYPE_INT8) */ VALTYPE_ENUM = 5, /** no value (for writing only, only works for values that have no value status) */ VALTYPE_NULL = 6, /** raw buffer, binary (for texts, will return application charset, null terminated) */ VALTYPE_BUF = 10, /** text in charset / line-end mode as specified with SetTextMode() */ VALTYPE_TEXT = 20, /** internal use only: text, internally saved in obfuscated format */ VALTYPE_TEXT_OBFUS = 21, /** time specification 64 bit in format specified with SetTimeMode() */ VALTYPE_TIME64 = 30, /** time specification 32 bit in format specified with SetTimeMode() */ VALTYPE_TIME32 = 31, }; /* ---- application feature numbers ---- */ enum TAppFeatureEnum { /** client autosync */ APP_FTR_AUTOSYNC = 1, /** client IPP/DMU */ APP_FTR_IPP = 2, /** client settings for event date range */ APP_FTR_EVENTRANGE = 3, /** client settings for email date and maxsize range */ APP_FTR_EMAILRANGE = 4 }; /* ---- danger flags ---- */ enum TDangerEnum { /** sync session will zap client data */ DANGERFLAG_WILLZAPCLIENT = 1, /** sync session will zap server data */ DANGERFLAG_WILLZAPSERVER = 2 }; /* ---- read-only indicators for certain settings fields --- */ enum TReadOnlyEnum { /** server URI is read-only */ RDONLY_URI = 1, /** URI path suffix is read-only */ RDONLY_URIPATH = 2, /** protocol (transport http/https flag as well as SyncML version) are read-only */ RDONLY_PROTOCOL = 4, /** DB path names */ RDONLY_DBPATH = 8, /** profile may not be deleted or renamed (but non-readonly options can be set) */ RDONLY_PROFILE = 16, /** proxy settings (except proxy auth settings) are read-only */ RDONLY_PROXY = 32 }; /** * Profile modes (MIME DIR mode). * * These are the values also used as parameter of the * MAKETEXTWITHPROFILE/PARSETEXTWITHPROFILE macros. */ enum ProfileModeEnum { PROFILEMODE_DEFAULT = 0, /**< default mode of profile */ PROFILEMODE_OLD = 1, /**< vCard 2.1 and vCalendar 1.0 style */ PROFILEMODE_MIMEDIR = 2 /**< MIME-DIR = vCard 3.0, iCalendar 2.0 style */ }; /* ---- bit definitons for "profileFlags" profile field --- */ enum TProfileFlagsEnum { /** we should log the next session (not handled in engine!) */ PROFILEFLAG_LOGNEXTSYNC = 0x00000001, /** run session in legacy mode */ PROFILEFLAG_LEGACYMODE = 0x00000002, /** run session in lenient mode */ PROFILEFLAG_LENIENTMODE = 0x00000004, /** we should keep msg logs of the next session (not handled in engine!) */ PROFILEFLAG_MSGNEXTSYNC = 0x00000008, /** we should use this profile in global syncs (not handled in engine!) */ PROFILEFLAG_USEINGLOBSYNC = 0x00000008 }; /* ---- bit definitons for "transpFlags" profile field --- */ enum TTranspFlagsEnum { /** SSL certificate verification/expiration errors should be ignored (not handled in engine!) */ TRANSPFLAG_SSLIGNORECERTFAIL = 0x00000001, /** use http auth for server connection (not handled in engine!) */ TRANSPFLAG_USEHTTPAUTH = 0x00000002 }; /* ---- step commands ---- */ /* - input to engine */ enum TStepCmdEnum { /** start a new client session */ STEPCMD_CLIENTSTART = 1, /** start a autosync session */ STEPCMD_CLIENTAUTOSTART = 2, /** just run next step */ STEPCMD_STEP = 10, /** run next step (after receiving STEPCMD_NEEDDATA and putting received SyncML data into buffer using GetSyncMLBuffer/ReturnSyncMLBuffer) */ STEPCMD_GOTDATA = 11, /** run next step (after receiving STEPCMD_SENDDATA and sending SyncML data from buffer using GetSyncMLBuffer/ReturnSyncMLBuffer) */ STEPCMD_SENTDATA = 12, /** suspend the session. Note that this command can be issued out-of order instead of the next pending command (STEPCMD_GOTDATA, STEPCMD_SENTDATA, STEPCMD_STEP) and will always return STEPCMD_OK. The next in-order STEPCMD_xx must be issued in the next step to complete the suspend */ STEPCMD_SUSPEND = 20, /** abort the session (user abort) */ STEPCMD_ABORT = 21, /** transport failure causes aborting the session */ STEPCMD_TRANSPFAIL = 22, /** timeout causes aborting the session */ STEPCMD_TIMEOUT = 23, /** process SAN in SyncML buffer */ STEPCMD_SAN_CHECK = 40, /** check for periodic autosync */ STEPCMD_AUTOSYNC_CHECK = 41, /* - output from engine */ /** engine returns to caller w/o progress info, and should be called again ASAP with STEPCMD_STEP or, if the previous call was STEPCMD_SUSPEND, with the step command that was pending before doing the suspend (for example STEPCMD_GOTDATA, STEPCMD_SENTDATA, STEPCMD_STEP) */ STEPCMD_OK = 100, /** engine returns to caller to show progress, and should be called again ASAP with STEPCMD_STEP */ STEPCMD_PROGRESS = 101, /** error (see return value of SessionStep call) */ STEPCMD_ERROR = 102, /** engine has new data to send to remote, use GetSyncMLBuffer() to get access to the engine buffer containing the message */ STEPCMD_SENDDATA = 110, /** engine needs new data, use GetSyncMLBuffer() to get access to the empty buffer where to put data */ STEPCMD_NEEDDATA = 111, /** engine needs to reset status to resend data */ STEPCMD_RESENDDATA = 112, /** session done, SAN processed, Autosync checked etc. No further action required */ STEPCMD_DONE = 120, /** communication session ends here (close connection!) but SyncML session continues */ STEPCMD_RESTART = 121, /** STEPCMD_AUTOSYNC_CHECK or STEPCMD_SAN_CHECK has detected need for performing a sync session */ STEPCMD_NEEDSYNC = 130 }; /* ---- session type selectors */ enum TSessionSelectorEnum { /* - binfile client engine selectors */ /** normal client session base selector value, add profile ID to select profile */ SESSIONSEL_CLIENT_NORMAL = 0x00000000, /** mask to extract profile ID from selector */ SESSIONSEL_PROFILEID_MASK = 0x0FFFFFFF, /** Autosync (timed, IPP, SAN) checking session */ SESSIONSEL_CLIENT_AS_CHECK = 0x10000000, /* - other special session selectors */ /** test session to access a datastore using DBAPI-like calls */ SESSIONSEL_DBAPI_TUNNEL = 0x80000001 }; /* ---- XML config data reader func type ---- */ #if defined _WIN32 && !defined _MSC_VER #define _CALLING_ __stdcall #else #define _CALLING_ #endif typedef int _CALLING_ (*TXMLConfigReadFunc)( appCharP aBuffer, bufferIndex aMaxSize, bufferIndex *aReadCharsP, void *aContext ); /* ---- Engine progress information ---- */ /* - progress event types */ enum TProgressEventEnum { /* global */ /** some fatal aborting error */ PEV_ERROR = 0, /** extra messages */ PEV_MESSAGE = 1, /** extra error code */ PEV_ERRCODE = 2, /** no extra message, just called to allow aborting */ PEV_NOP = 3, /** called to signal main program, that caller would want to wait for extra1 milliseconds */ PEV_WAIT = 4, /** called to allow debug interactions, extra1=code */ PEV_DEBUG = 5, /* transport-related */ PEV_SENDSTART = 6, PEV_SENDEND = 7, PEV_RECVSTART = 8, PEV_RECVEND = 9, /** expired */ PEV_SSL_EXPIRED = 10, /** not completely trusted */ PEV_SSL_NOTRUST = 11, /** sent periodically when waiting for network, allows application to check connection */ PEV_CONNCHECK = 12, /** sent when client could initiate a explicit suspend */ PEV_SUSPENDCHECK = 13, /* general */ /** alert 100 received from remote, SessionKey's "displayalert" value contains message */ PEV_DISPLAY100 = 14, /* session-related */ PEV_SESSIONSTART = 15, /** session ended, probably with error in extra */ PEV_SESSIONEND = 16, /* datastore-related */ /** preparing (e.g. preflight in some clients), extra1=progress, extra2=total */ PEV_PREPARING = 17, /** deleting (zapping datastore), extra1=progress, extra2=total */ PEV_DELETING = 18, /** datastore alerted (extra1=0 for normal, 1 for slow, 2 for first time slow, extra2=1 for resumed session, extra3=syncmode: 0=twoway, 1=fromserver, 2=fromclient) This used to be reported only in client mode, directly after receiving and checking the ALERT command from the server. Now this event is also reported in server mode at that point in time where the final sync mode is known (in other words, after the client acknowledged the alerted sync mode). Note that a server cannot reliably distinguish between "refresh-from-server" and "slow" sync. A client might delete all its data and then do a "slow" sync - the Synthesis engine itself does that. */ PEV_ALERTED = 19, /** sync started */ PEV_SYNCSTART = 20, /** item received, extra1=current item count, extra2=number of expected changes (if >= 0) */ PEV_ITEMRECEIVED = 21, /** item sent, extra1=current item count, extra2=number of expected items to be sent (if >=0) */ PEV_ITEMSENT = 22, /** item locally processed, extra1=# added, extra2=# updated, extra3=# deleted */ PEV_ITEMPROCESSED = 23, /** sync finished, probably with error in extra1 (0=ok), syncmode in extra2 (0=normal, 1=slow, 2=first time), extra3=1 for resumed session) */ PEV_SYNCEND = 24, /** datastore statistics for local (extra1=# added, extra2=# updated, extra3=# deleted) */ PEV_DSSTATS_L = 25, /** datastore statistics for remote (extra1=# added, extra2=# updated, extra3=# deleted) */ PEV_DSSTATS_R = 26, /** datastore statistics for local/remote rejects (extra1=# locally rejected, extra2=# remotely rejected) */ PEV_DSSTATS_E = 27, /** datastore statistics for server slowsync (extra1=# slowsync matches) */ PEV_DSSTATS_S = 28, /** datastore statistics for server conflicts (extra1=# server won, extra2=# client won, extra3=# duplicated) */ PEV_DSSTATS_C = 29, /** datastore statistics for data volume (extra1=outgoing bytes, extra2=incoming bytes) */ PEV_DSSTATS_D = 30, /** engine is in process of suspending */ PEV_SUSPENDING = 31, /** * range of event codes that can be used by applications for their * own purposes */ PEV_CUSTOM_START = 128, PEV_CUSTOM_END = 255 }; /* - progress event structure */ typedef struct TEngineProgressType { uInt16 eventtype; /* PEV_XXX definition */ sInt32 targetID; /* target ID if event is specific to a target, KEYVAL_ID_UNKNOWN if session global */ sIntPtr extra1; /* extra info, such as error code or count for progress or # of added items */ sIntPtr extra2; /* extra info, such as total for progress or # of updated items */ sIntPtr extra3; /* extra info, such as # of deleted items */ } TEngineProgressInfo; #ifdef __cplusplus } // namespace #endif #endif /* ENGINE_DEFS_H */ /* eof */ libsynthesis-3.4.0.47.1/src/sysync_SDK/Sources/enginemodulebase.cpp000077500000000000000000000150211226375725500251230ustar00rootroot00000000000000/** * @File enginemodulebase.cpp * * @Author Beat Forster (bfo@synthesis.ch) * * @brief TEngineModuleBase * engine bus bar class * * Copyright (c) 2007-2011 by Synthesis AG + plan44.ch * */ #include "prefix_file.h" #include "enginemodulebase.h" #include "SDK_util.h" #if defined SYSYNC_ENGINE || defined SYSYNC_ENGINE_TEST #include "engineentry.h" #endif #if !defined(SYSYNC_ENGINE) || defined(ENGINEINTERFACE_SUPPORT) namespace sysync { // TEngineModuleBase // ================= // local name #define MyName "enginemodulebase" // constructor TEngineModuleBase::TEngineModuleBase() { fCI = NULL; fEngineName= ""; // none fPrgVersion= 0; fDebugFlags= 0; fCIisStatic= false; } // TEngineModuleBase // destructor TEngineModuleBase::~TEngineModuleBase() { #if defined SYSYNC_ENGINE || defined SYSYNC_ENGINE_TEST if (fCI && !fCIisStatic) delete fCI; #endif } // ~TEngineModuleBase // --- Initial connection ------------------------ TSyError TEngineModuleBase::Connect( string aEngineName, CVersion aPrgVersion, uInt16 aDebugFlags) { TSyError err= LOCERR_OK; fEngineName = aEngineName; fPrgVersion = aPrgVersion; fDebugFlags = aDebugFlags; #if defined SYSYNC_ENGINE || defined SYSYNC_ENGINE_TEST uInt16 cbVersion= DB_Callback_Version; // use current by default if (fCI==NULL) { fCI = &fCIBuffer; fCIisStatic = true; } else { cbVersion= fCI->callbackVersion; // the cbVersion from outside (ConnectEngineS) } // if InitCallback_Exotic( fCI, cbVersion ); // be aware that it could be an older version fCI->thisBase= this; // get later for callback calls CB_Connect ( fCI ); #endif if (fPrgVersion==0) fPrgVersion= Plugin_Version( 0 ); // take the internal one if (fPrgVersiondebugFlags= fDebugFlags; if (!err) err= Init(); DEBUG_DB( fCI, MyName, "Connect","version=%08X flags=%04X err=%d", fPrgVersion, fDebugFlags, err ); return err; } // Connect TSyError TEngineModuleBase::Disconnect() { if (!fCI) return LOCERR_OK; DEBUG_DB( fCI, MyName, "Disconnect","" ); TSyError err= Term(); return err; } // Disconnect // ---------------------------------------------------------------------------------------------- TSyError TEngineModuleBase::GetStrValue( KeyH aKeyH, cAppCharP aValName, string &aText ) { TSyError err; const int txtFieldSize= 80; // a readonable string length to catch it at once char txtField[ txtFieldSize ]; memSize txtSize; char* f= (char*)&txtField; // try directly to fit in a short string first err= GetValue( aKeyH, aValName, VALTYPE_TEXT, f, txtFieldSize, txtSize ); bool tooShort= err==LOCERR_TRUNCATED; if (tooShort) { err= GetValue( aKeyH, aValName, VALTYPE_TEXT, f, 0, txtSize ); // get size f= (char*)malloc( txtSize+1 ); // plus NUL termination err= GetValue( aKeyH, aValName, VALTYPE_TEXT, f, txtSize+1, txtSize ); // no error anymore } // if aText.assign(f, txtSize); // assign it if (tooShort) free( f ); // and deallocate again, if used dynamically return err; } // GetStrValue; TSyError TEngineModuleBase::SetStrValue( KeyH aKeyH, cAppCharP aValName, string aText ) { // -1 automatically calculate length from null-terminated string return SetValue( aKeyH, aValName, VALTYPE_TEXT, aText.c_str(), (memSize)-1 ); } // SetStrValue // ---------------------------------------------------------------------------------------------- TSyError TEngineModuleBase::GetInt8Value( KeyH aKeyH, cAppCharP aValName, sInt8 &aValue ) { memSize vSize; return GetValue( aKeyH, aValName, VALTYPE_INT8, &aValue, sizeof(aValue), vSize ); } // GetInt8Value TSyError TEngineModuleBase::GetInt8Value( KeyH aKeyH, cAppCharP aValName, uInt8 &aValue ) { memSize vSize; return GetValue( aKeyH, aValName, VALTYPE_INT8, &aValue, sizeof(aValue), vSize ); } // GetInt8Value TSyError TEngineModuleBase::SetInt8Value( KeyH aKeyH, cAppCharP aValName, uInt8 aValue ) { return SetValue( aKeyH, aValName, VALTYPE_INT8, &aValue, sizeof(aValue) ); } // SetInt8Value // ---------------------------------------------------------------------------------------------- TSyError TEngineModuleBase::GetInt16Value( KeyH aKeyH, cAppCharP aValName, sInt16 &aValue ) { memSize vSize; return GetValue( aKeyH, aValName, VALTYPE_INT16, &aValue, sizeof(aValue), vSize ); } // GetInt16Value TSyError TEngineModuleBase::GetInt16Value( KeyH aKeyH, cAppCharP aValName, uInt16 &aValue ) { memSize vSize; return GetValue( aKeyH, aValName, VALTYPE_INT16, &aValue, sizeof(aValue), vSize ); } // GetInt16Value TSyError TEngineModuleBase::SetInt16Value( KeyH aKeyH, cAppCharP aValName, uInt16 aValue ) { return SetValue( aKeyH, aValName, VALTYPE_INT16, &aValue, sizeof(aValue) ); } // SetInt16Value // ---------------------------------------------------------------------------------------------- TSyError TEngineModuleBase::GetInt32Value( KeyH aKeyH, cAppCharP aValName, sInt32 &aValue ) { memSize vSize; return GetValue( aKeyH, aValName, VALTYPE_INT32, &aValue, sizeof(aValue), vSize ); } // GetInt32Value TSyError TEngineModuleBase::GetInt32Value( KeyH aKeyH, cAppCharP aValName, uInt32 &aValue ) { memSize vSize; return GetValue( aKeyH, aValName, VALTYPE_INT32, &aValue, sizeof(aValue), vSize ); } // GetInt32Value TSyError TEngineModuleBase::SetInt32Value( KeyH aKeyH, cAppCharP aValName, uInt32 aValue ) { return SetValue( aKeyH, aValName, VALTYPE_INT32, &aValue, sizeof(aValue) ); } // SetInt32Value // ---------------------------------------------------------------------------------------------- void TEngineModuleBase::AppendSuffixToID( KeyH aKeyH, sInt32 &aID, cAppCharP aSuffix ) { string s= aSuffix; if (s=="") return; s= VALNAME_FLAG + s; aID+= GetValueID( aKeyH, s.c_str() ); } // AppendSuffixToID } // namespace sysync /* end of TEngineModuleBase implementation */ #endif // not used in engine or engine with ENGINEINTERFACE_SUPPORT // eof libsynthesis-3.4.0.47.1/src/sysync_SDK/Sources/enginemodulebase.h000077500000000000000000000555301226375725500246010ustar00rootroot00000000000000/** * @File enginemodulebase.h * * @Author Beat Forster (bfo@synthesis.ch) * * @brief TEngineModuleBase * engine bus bar class * * Copyright (c) 2007-2011 by Synthesis AG + plan44.ch * */ #ifndef ENGINEMODULEBASE_H #define ENGINEMODULEBASE_H #include "generic_types.h" #include "sync_dbapidef.h" #include "sysync_noncopyable.h" // we need STL strings #include using namespace std; namespace sysync { // Engine module base class TEngineModuleBase : noncopyable { SDK_Interface_Struct fCIBuffer; // used for fCI if the caller of Connect() doesn't set something public: TEngineModuleBase(); // constructor virtual ~TEngineModuleBase(); // destructor UI_Call_In fCI; // call in structure string fEngineName; // name of the SyncML engine to be connected CVersion fPrgVersion; // program's SDK version uInt16 fDebugFlags; // debug flags to be used bool fCIisStatic; // this is kept purely for source code backwards compatibility: // because fCI is *always* statically allocated TSyError Connect( string aEngineName, // connect the SyncML engine CVersion aPrgVersion= 0, uInt16 aDebugFlags= DBG_PLUGIN_NONE ); TSyError Disconnect(); // disconnect the SyncML engine virtual TSyError Init() = 0; virtual TSyError Term() = 0; // Engine init // ----------- /// @brief Set the global mode for string paramaters (when never called, default params are UTF-8 with C-style line ends) /// @param aCharSet[in] charset /// @param aLineEndMode[in] line end mode (default is C-lineends of the platform (almost always LF)) /// @param aBigEndian[in] determines endianness of UTF16 text (defaults to little endian = intel order) /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure virtual TSyError SetStringMode ( uInt16 aCharSet, uInt16 aLineEndMode= LEM_CSTR, bool aBigEndian = false ) = 0; /// @brief init object, optionally passing XML config text in memory /// @param aConfigXML[in] NULL or empty string if no external config needed, config text otherwise /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure virtual TSyError InitEngineXML ( cAppCharP aConfigXML ) = 0; /// @brief init object, optionally passing a open FILE for reading config /// @param aConfigFilePath[in] path to config file /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure virtual TSyError InitEngineFile ( cAppCharP aConfigFilePath ) = 0; /// @brief init object, optionally passing a callback for reading config /// @param aReaderFunc[in] callback function which can deliver next chunk of XML config data /// @param aContext[in] free context pointer passed back with callback /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure virtual TSyError InitEngineCB ( TXMLConfigReadFunc aReaderFunc, void *aContext ) = 0; // Running a Sync Session // ---------------------- /// @brief Open a session /// @param aNewSessionH[out] receives session handle for all session execution calls /// @param aSelector[in] selector, depending on session type. For multi-profile clients: profile ID to use /// @param aSessionName[in] a text name/id to identify a session, useage depending on session type. /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure virtual TSyError OpenSession( SessionH &aNewSessionH, uInt32 aSelector=0, cAppCharP aSessionName=NULL ) = 0; /// @brief open session specific runtime parameter/settings key /// @note key handle obtained with this call must be closed BEFORE SESSION IS CLOSED! /// @param aNewKeyH[out] receives the opened key's handle on success /// @param aSessionH[in] session handle obtained with OpenSession. /// When used as callback from DBApi, this parameter is irrelevant and /// must be set to NULL as a callback from DBApi has an implicit session context /// automatically. /// @param aMode[in] the open mode /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure virtual TSyError OpenSessionKey ( SessionH aSessionH, KeyH &aNewKeyH, uInt16 aMode ) = 0; /// @brief Executes sync session or other sync related activity step by step /// @param aSessionH[in] session handle obtained with OpenSession /// @param aStepCmd[in/out] step command (STEPCMD_xxx): /// - tells caller to send or receive data or end the session etc. /// - instructs engine to suspend or abort the session etc. /// @param aInfoP[in] pointer to a TEngineProgressInfo structure, NULL if no progress info needed /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure virtual TSyError SessionStep( SessionH aSessionH, uInt16 &aStepCmd, TEngineProgressInfo *aInfoP = NULL ) = 0; /// @brief Get access to SyncML message buffer /// @param aSessionH[in] session handle obtained with OpenSession /// @param aForSend[in] direction send/receive /// @param aBuffer[out] receives pointer to buffer (empty for receive, full for send) /// @param aBufSize[out] receives size of empty or full buffer /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure virtual TSyError GetSyncMLBuffer( SessionH aSessionH, bool aForSend, appPointer &aBuffer, memSize &aBufSize ) = 0; /// @brief Return SyncML message buffer to engine /// @param aSessionH[in] session handle obtained with OpenSession /// @param aForSend[in] direction send/receive /// @param aProcessed[in] number of bytes put into or read from the buffer /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure virtual TSyError RetSyncMLBuffer( SessionH aSessionH, bool aForSend, memSize aProcessed ) = 0; /// @brief Read data from SyncML message buffer /// @param aSessionH[in] session handle obtained with OpenSession /// @param aBuffer[in] pointer to buffer /// @param aBufSize[in] size of buffer, maximum to be read /// @param aMsgSize[out] size of data available in the buffer for read INCLUDING just returned data. /// @note If the aBufSize is too small to return all available data LOCERR_TRUNCATED will be returned, and the /// caller can repeat calls to ReadSyncMLBuffer to get the next chunk. /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure virtual TSyError ReadSyncMLBuffer ( SessionH aSessionH, appPointer aBuffer, memSize aBufSize, memSize &aMsgSize ) = 0; /// @brief Write data to SyncML message buffer /// @param aSessionH[in] session handle obtained with OpenSession /// @param aBuffer[in] pointer to buffer /// @param aMsgSize[in] size of message to write to the buffer /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure virtual TSyError WriteSyncMLBuffer( SessionH aSessionH, appPointer aBuffer, memSize aMsgSize ) = 0; /// @brief Close a session /// @note It depends on session type if this also destroys the session or if it may persist and can be re-opened. /// @param aSessionH[in] session handle obtained with OpenSession /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure virtual TSyError CloseSession( SessionH aSessionH ) = 0; // Settings access // --------------- /// @brief open Settings key by path specification /// @param aNewKeyH[out] receives the opened key's handle on success /// @param aParentKeyH[in] NULL if path is absolute from root, handle to an open key for relative access /// @param aPath[in] the path specification as null terminated string /// @param aMode[in] the open mode /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure virtual TSyError OpenKeyByPath ( KeyH &aNewKeyH, KeyH aParentKeyH, cAppCharP aPath, uInt16 aMode ) = 0; /// @brief open Settings subkey key by ID or iterating over all subkeys /// @param aNewKeyH[out] receives the opened key's handle on success /// @param aParentKeyH[in] handle to the parent key /// @param aID[in] the ID of the subkey to open, /// or KEYVAL_ID_FIRST/KEYVAL_ID_NEXT to iterate over existing subkeys /// or KEYVAL_ID_NEW to create a new subkey /// @param aMode[in] the open mode /// @return LOCERR_OK on success, DB_NoContent when no more subkeys are found with /// KEYVAL_ID_FIRST/KEYVAL_ID_NEXT /// or any other SyncML or LOCERR_xxx error code on failure virtual TSyError OpenSubkey ( KeyH &aNewKeyH, KeyH aParentKeyH, sInt32 aID, uInt16 aMode ) = 0; /// @brief delete Settings subkey key by ID /// @param aParentKeyH[in] handle to the parent key /// @param aID[in] the ID of the subkey to delete /// @return LOCERR_OK on success /// or any other SyncML or LOCERR_xxx error code on failure virtual TSyError DeleteSubkey ( KeyH aParentKeyH, sInt32 aID ) = 0; /// @brief Get key ID of currently open key. Note that the Key ID is only locally unique within /// the parent key. /// @param aKeyH[in] an open key handle /// @param aID[out] receives the ID of the open key, which can be used to re-access the /// key within its parent using OpenSubkey() /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure virtual TSyError GetKeyID ( KeyH aKeyH, sInt32 &aID ) = 0; /// @brief Set text format parameters (when never called, default params are those set with global SetStringMode()) /// @param aKeyH[in] an open key handle /// @param aCharSet[in] charset /// @param aLineEndMode[in] line end mode (defaults to C-lineends of the platform (almost always LF)) /// @param aBigEndian[in] determines endianness of UTF16 text (defaults to little endian = intel order) /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure virtual TSyError SetTextMode ( KeyH aKeyH, uInt16 aCharSet, uInt16 aLineEndMode= LEM_CSTR, bool aBigEndian = false ) = 0; /// @brief Set time format parameters /// @param aKeyH[in] an open key handle /// @param aTimeMode[in] time mode, see TMODE_xxx (default is platform's lineratime_t when SetTimeMode() is not used) /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure virtual TSyError SetTimeMode ( KeyH aKeyH, uInt16 aTimeMode ) = 0; /// @brief Closes a key opened by OpenKeyByPath() or OpenSubKey() /// @param aKeyH[in] an open key handle. Will be invalid when call returns with LOCERR_OK. Do not re-use! /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure virtual TSyError CloseKey ( KeyH aKeyH ) = 0; /// @brief Reads a named value in specified format into passed memory buffer /// @param aKeyH[in] an open key handle /// @param aValueName[in] name of the value to read. Some keys offer special ".XXX" /// suffixes to value names, which return alternate values (like a timestamp field's /// time zone name with ".TZNAME"). /// @param aValType[in] desired return type, see VALTYPE_xxxx /// @param aBuffer[in/out] buffer where to store the data /// @param aBufSize[in] size of buffer in bytes (ALWAYS in bytes, even if value is Unicode string) /// Note: to get only size of a value (useful especially for strings), pass 0 as buffer size. /// @param aValSize[out] actual size of value. /// For VALTYPE_TEXT, size is string length (IN BYTES) excluding NULL terminator /// Note that this will be set also when return value is LOCERR_BUFTOOSMALL, /// to indicate the required buffer size /// For values that can be truncated (strings), LOCERR_TRUNCATED will be returned /// when returned value is not entire value - aValSize is truncated size then. /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure virtual TSyError GetValue ( KeyH aKeyH, cAppCharP aValName, uInt16 aValType, appPointer aBuffer, memSize aBufSize, memSize &aValSize ) = 0; /// @brief get value's ID for use with Get/SetValueByID() /// @param aKeyH[in] an open key handle /// @param aName[in] name of the value to write. Some keys offer special ".FLAG.XXX" /// values, which return flag bits which can be added to the regular ID to obtain /// alternate values (like the value name with ".FLAG.VALNAME", useful when iterating /// over values). /// @return KEYVAL_ID_UNKNOWN when no ID available for name, ID of value otherwise virtual sInt32 GetValueID ( KeyH aKeyH, cAppCharP aName ) = 0; /// @brief Reads a named value in specified format into passed memory buffer /// @param aKeyH[in] an open key handle /// @param aID[in] ID of the value to read /// @param arrIndex[in] 0-based array element index for array values. /// @param aValType[in] desired return type, see VALTYPE_xxxx /// @param aBuffer[in/out] buffer where to store the data /// @param aBufSize[in] size of buffer in bytes (ALWAYS in bytes, even if value is Unicode string) /// Note: to get only size of a value (useful especially for strings), pass 0 as buffer size. /// @param aValSize[out] actual size of value. /// For VALTYPE_TEXT, size is string length (IN BYTES) excluding NULL terminator /// Note that this will be set also when return value is LOCERR_BUFTOOSMALL, /// to indicate the required buffer size /// For values that can be truncated (strings), LOCERR_TRUNCATED will be returned /// when returned value is not entire value - aValSize is truncated size then. /// @return LOCERR_OK on success, LOCERR_OUTOFRANGE when array index is out of range /// SyncML or LOCERR_xxx error code on other failure virtual TSyError GetValueByID ( KeyH aKeyH, sInt32 aID, sInt32 arrIndex, uInt16 aValType, appPointer aBuffer, memSize aBufSize, memSize &aValSize ) = 0; /// @brief Writes a named value in specified format passed in memory buffer /// @param aKeyH[in] an open key handle /// @param aValueName[in] name of the value to write. Some keys offer special ".XXX" /// suffixes to value names, which are used to set alternate values (like a /// timestamp field's time zone name with ".TZNAME"). /// @param aValType[in] type of value passed in, see VALTYPE_xxxx /// @param aBuffer[in] buffer containing the data /// @param aValSize[in] size of value. For VALTYPE_TEXT, size can be passed as -1 if string is null terminated /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure. If value /// buffer passed in is too small for aValType (such as only 2 bytes for a VALTYPE_INT32, /// LOCERR_BUFTOOSMALL will be returned and nothing stored. If buffer passed in is too /// long (e.g. for strings) to be entirely stored, only the beginning is stored and /// LOCERR_TRUNCATED is returned. virtual TSyError SetValue ( KeyH aKeyH, cAppCharP aValName, uInt16 aValType, cAppPointer aBuffer, memSize aValSize ) = 0; /// @brief Writes a named value in specified format passed in memory buffer /// @param aKeyH[in] an open key handle /// @param aID[in] ID of the value to read /// @param arrIndex[in] 0-based array element index for array values. /// @param aValType[in] type of value passed in, see VALTYPE_xxxx /// @param aBuffer[in] buffer containing the data /// @param aValSize[in] size of value. For VALTYPE_TEXT, size can be passed as -1 if string is null terminated /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure. If value /// buffer passed in is too small for aValType (such as only 2 bytes for a VALTYPE_INT32, /// LOCERR_BUFTOOSMALL will be returned and nothing stored. If buffer passed in is too /// long (e.g. for strings) to be entirely stored, only the beginning is stored and /// LOCERR_TRUNCATED is returned. virtual TSyError SetValueByID ( KeyH aKeyH, sInt32 aID, sInt32 arrIndex, uInt16 aValType, cAppPointer aBuffer, memSize aValSize ) = 0; // Convenience routines to close and NULL a handle in one step // ----------------------------------------------------------- /// @brief Closes a key and nulls the handle /// @param aKeyH[in/out] an open key handle. Will be set to NULL on exit (to make sure it is not re-used) /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure TSyError CloseKeyAndNULL ( KeyH &aKeyH ) { TSyError sta = CloseKey(aKeyH); if (sta==LOCERR_OK) aKeyH=NULL; return sta; }; /// @brief Closes a session and nulls the handle /// @param aSessionH[in] session handle obtained with OpenSession /// @return LOCERR_OK on success, SyncML or LOCERR_xxx error code on failure TSyError CloseSessionAndNULL ( SessionH &aSessionH ) { TSyError sta = CloseSession(aSessionH); if (sta==LOCERR_OK) aSessionH=NULL; return sta; }; // Convenience routines to access Get/SetValue for specific types // -------------------------------------------------------------- virtual TSyError GetStrValue ( KeyH aKeyH, cAppCharP aValName, string &aText ); virtual TSyError SetStrValue ( KeyH aKeyH, cAppCharP aValName, string aText ); virtual TSyError GetInt8Value ( KeyH aKeyH, cAppCharP aValName, sInt8 &aValue ); // signed virtual TSyError GetInt8Value ( KeyH aKeyH, cAppCharP aValName, uInt8 &aValue ); // unsigned virtual TSyError SetInt8Value ( KeyH aKeyH, cAppCharP aValName, uInt8 aValue ); virtual TSyError GetInt16Value ( KeyH aKeyH, cAppCharP aValName, sInt16 &aValue ); // signed virtual TSyError GetInt16Value ( KeyH aKeyH, cAppCharP aValName, uInt16 &aValue ); // unsigned virtual TSyError SetInt16Value ( KeyH aKeyH, cAppCharP aValName, uInt16 aValue ); virtual TSyError GetInt32Value ( KeyH aKeyH, cAppCharP aValName, sInt32 &aValue ); // signed virtual TSyError GetInt32Value ( KeyH aKeyH, cAppCharP aValName, uInt32 &aValue ); // unsigned virtual TSyError SetInt32Value ( KeyH aKeyH, cAppCharP aValName, uInt32 aValue ); virtual void AppendSuffixToID ( KeyH aKeyH, sInt32 &aID, cAppCharP aSuffix ); // Tunnel Interface Methods --------------------------------------------------------------------- virtual TSyError StartDataRead ( SessionH aSessionH, cAppCharP lastToken, cAppCharP resumeToken ) = 0; virtual TSyError ReadNextItem ( SessionH aSessionH, ItemID aID, appCharP *aItemData, sInt32 *aStatus, bool aFirst ) = 0; virtual TSyError ReadItem ( SessionH aSessionH, cItemID aID, appCharP *aItemData ) = 0; virtual TSyError EndDataRead ( SessionH aSessionH ) = 0; virtual TSyError StartDataWrite ( SessionH aSessionH ) = 0; virtual TSyError InsertItem ( SessionH aSessionH, cAppCharP aItemData, ItemID aID )= 0; virtual TSyError UpdateItem ( SessionH aSessionH, cAppCharP aItemData, cItemID aID, ItemID updID )= 0; virtual TSyError MoveItem ( SessionH aSessionH, cItemID aID, cAppCharP newParID )= 0; virtual TSyError DeleteItem ( SessionH aSessionH, cItemID aID ) = 0; virtual TSyError EndDataWrite ( SessionH aSessionH, bool success, appCharP *newToken )= 0; virtual void DisposeObj ( SessionH aSessionH, void* memory ) = 0; // -- asKey -- virtual TSyError ReadNextItemAsKey( SessionH aSessionH, ItemID aID, KeyH aItemKey, sInt32 *aStatus, bool aFirst )= 0; virtual TSyError ReadItemAsKey ( SessionH aSessionH, cItemID aID, KeyH aItemKey )= 0; virtual TSyError InsertItemAsKey ( SessionH aSessionH, KeyH aItemKey, ItemID aID )= 0; virtual TSyError UpdateItemAsKey ( SessionH aSessionH, KeyH aItemKey, cItemID aID, ItemID updID )= 0; virtual TSyError debugPuts(cAppCharP aFile, int aLine, cAppCharP aFunction, int aDbgLevel, cAppCharP aLinePrefix, cAppCharP aText) { return LOCERR_NOTIMP; } }; // TEngineModuleBase // debug level masks (original definition in sysync_debug.h) #define DBG_HOT 0x00000001 // hot information #define DBG_ERROR 0x00000002 // Error conditions /** * @param aFile source file name from which log entry comes * @param aLine source file line * @param aFunction function name * @param aDbgLevel same bit mask as in the internal TDebugLogger; * currently DBG_HOT and DBG_ERROR are defined publicly * @param aLinePrefix a short string to be displayed in front of each line; * the advantage of passing this separately instead of * making it a part of aText is that the logger might * be able to insert the prefix more efficiently and/or * (depending on the log format) with extra formatting * @param aText the text to be printed, may consist of multiple lines; * the log always starts a new line after the text, regardless * of how many newlines might be at the end of the text */ void SySyncDebugPuts(void* aCB, cAppCharP aFile, int aLine, cAppCharP aFunction, int aDbgLevel, cAppCharP aLinePrefix, cAppCharP aText); // factory function declarations - must be implemented in the source file of the leaf derivates of TEngineInterface #ifdef SYSYNC_CLIENT TEngineModuleBase *newClientEngine(void); #endif #ifdef SYSYNC_SERVER TEngineModuleBase *newServerEngine(void); #endif } // namespace sysync #endif // ENGINEMODULEBASE_H // eof libsynthesis-3.4.0.47.1/src/sysync_SDK/Sources/enginemodulebridge.cpp000066400000000000000000000307111226375725500254450ustar00rootroot00000000000000/* * File: enginemodulebridge.cpp * * Author: Beat Forster (bfo@synthesis.ch) * * * Synthesis SyncML client test connector * * Copyright (c) 2007-2011 by Synthesis AG + plan44.ch * * */ #include "enginemodulebridge.h" // include the interface file and utilities #include "SDK_util.h" #include "UI_util.h" namespace sysync { // local name #define MyName "enginemodulebridge" // -------------------------------------------------------------- TEngineModuleBridge::TEngineModuleBridge() { fDLL= NULL; fIsServer= false; } // constructor TEngineModuleBridge::~TEngineModuleBridge() { Term(); } // destructor // -------------------------------------------------------------- TSyError TEngineModuleBridge::Init() { TSyError err= UI_Connect( fCI, fDLL, fIsServer, fEngineName.c_str(), fPrgVersion, fDebugFlags ); return err; } // Init TSyError TEngineModuleBridge::Term() { TSyError err= LOCERR_OK; if (fCI) { err= UI_Disconnect( fCI, fDLL, fIsServer ); fCI= NULL; } return err; } // Term // -------------------------------------------------------------- TSyError TEngineModuleBridge::SetStringMode( uInt16 aCharSet, uInt16 aLineEndMode, bool aBigEndian ) { SetStringMode_Func p= fCI->ui.SetStringMode; if (!p) return LOCERR_NOTIMP; return p( fCI, aCharSet, aLineEndMode, aBigEndian ); } // SetStringMode TSyError TEngineModuleBridge::InitEngineXML( cAppCharP aConfigXML ) { InitEngineXML_Func p= fCI->ui.InitEngineXML; if (!p) return LOCERR_NOTIMP; return p( fCI, aConfigXML ); } // InitEngineXML TSyError TEngineModuleBridge::InitEngineFile( cAppCharP aConfigFilePath ) { InitEngineFile_Func p= fCI->ui.InitEngineFile; if (!p) return LOCERR_NOTIMP; return p( fCI, aConfigFilePath ); } // InitEngineFile TSyError TEngineModuleBridge::InitEngineCB( TXMLConfigReadFunc aReaderFunc, void* aContext ) { InitEngineCB_Func p= fCI->ui.InitEngineCB; if (!p) return LOCERR_NOTIMP; return p( fCI, aReaderFunc, aContext ); } // InitEngineCB // -------------------------------------------------------------- TSyError TEngineModuleBridge::OpenSession( SessionH &aSessionH, uInt32 aSelector, cAppCharP aSessionName ) { OpenSession_Func p= fCI->ui.OpenSession; if (!p) return LOCERR_NOTIMP; return p( fCI, &aSessionH, aSelector, aSessionName ); } // OpenSession TSyError TEngineModuleBridge::OpenSessionKey( SessionH aSessionH, KeyH &aKeyH, uInt16 aMode ) { OpenSessionKey_Func p= fCI->ui.OpenSessionKey; if (!p) return LOCERR_NOTIMP; return p( fCI, aSessionH, &aKeyH, aMode ); } // OpenSessionKey TSyError TEngineModuleBridge::SessionStep( SessionH aSessionH, uInt16 &aStepCmd, TEngineProgressInfo *aInfoP ) { SessionStep_Func p= fCI->ui.SessionStep; if (!p) return LOCERR_NOTIMP; return p( fCI, aSessionH, &aStepCmd, aInfoP ); } // SessionStep TSyError TEngineModuleBridge::GetSyncMLBuffer( SessionH aSessionH, bool aForSend, appPointer &aBuffer, memSize &aBufSize ) { GetSyncMLBuffer_Func p= fCI->ui.GetSyncMLBuffer; if (!p) return LOCERR_NOTIMP; return p( fCI, aSessionH, aForSend, &aBuffer, &aBufSize ); } // GetSyncMLBuffer TSyError TEngineModuleBridge::RetSyncMLBuffer( SessionH aSessionH, bool aForSend, memSize aRetSize ) { RetSyncMLBuffer_Func p= fCI->ui.RetSyncMLBuffer; if (!p) return LOCERR_NOTIMP; return p( fCI, aSessionH, aForSend, aRetSize ); } // RetSyncMLBuffer TSyError TEngineModuleBridge::ReadSyncMLBuffer( SessionH aSessionH, appPointer aBuffer, memSize aBufSize, memSize &aValSize ) { ReadSyncMLBuffer_Func p= fCI->ui.ReadSyncMLBuffer; if (!p) return LOCERR_NOTIMP; return p( fCI, aSessionH, aBuffer, aBufSize, &aValSize ); } // ReadSyncMLBuffer TSyError TEngineModuleBridge::WriteSyncMLBuffer( SessionH aSessionH, appPointer aBuffer, memSize aValSize ) { WriteSyncMLBuffer_Func p= fCI->ui.WriteSyncMLBuffer; if (!p) return LOCERR_NOTIMP; return p( fCI, aSessionH, aBuffer, aValSize ); } // WriteSyncMLBuffer TSyError TEngineModuleBridge::CloseSession( SessionH aSessionH ) { CloseSession_Func p= fCI->ui.CloseSession; if (!p) return LOCERR_NOTIMP; return p( fCI, aSessionH ); } // CloseSession // -------------------------------------------------------------- TSyError TEngineModuleBridge::OpenKeyByPath( KeyH &aKeyH, KeyH aParentKeyH, cAppCharP aPath, uInt16 aMode ) { OpenKeyByPath_Func p= fCI->ui.OpenKeyByPath; if (!p) return LOCERR_NOTIMP; return p( fCI, &aKeyH, aParentKeyH, aPath, aMode ); } // OpenKeyByPath TSyError TEngineModuleBridge::OpenSubkey( KeyH &aKeyH, KeyH aParentKeyH, sInt32 aID, uInt16 aMode ) { OpenSubkey_Func p= fCI->ui.OpenSubkey; if (!p) return LOCERR_NOTIMP; return p( fCI, &aKeyH, aParentKeyH, aID, aMode ); } // OpenSubKey TSyError TEngineModuleBridge::DeleteSubkey( KeyH aParentKeyH, sInt32 aID ) { DeleteSubkey_Func p= fCI->ui.DeleteSubkey; if (!p) return LOCERR_NOTIMP; return p( fCI, aParentKeyH, aID ); } // DeleteSubkey TSyError TEngineModuleBridge::GetKeyID( KeyH aKeyH, sInt32 &aID ) { GetKeyID_Func p= fCI->ui.GetKeyID; if (!p) return LOCERR_NOTIMP; return p( fCI, aKeyH, &aID ); } // GetKeyID TSyError TEngineModuleBridge::SetTextMode( KeyH aKeyH, uInt16 aCharSet, uInt16 aLineEndMode, bool aBigEndian ) { SetTextMode_Func p= fCI->ui.SetTextMode; if (!p) return LOCERR_NOTIMP; return p( fCI, aKeyH, aCharSet, aLineEndMode, aBigEndian ); } // SetTextMode TSyError TEngineModuleBridge::SetTimeMode( KeyH aKeyH, uInt16 aTimeMode ) { SetTimeMode_Func p= fCI->ui.SetTimeMode; if (!p) return LOCERR_NOTIMP; return p( fCI, aKeyH, aTimeMode ); } // SetTimeMode TSyError TEngineModuleBridge::CloseKey( KeyH aKeyH ) { CloseKey_Func p= fCI->ui.CloseKey; if (!p) return LOCERR_NOTIMP; return p( fCI, aKeyH ); } // CloseKey // -------------------------------------------------------------- TSyError TEngineModuleBridge::GetValue( KeyH aKeyH, cAppCharP aValName, uInt16 aValType, appPointer aBuffer, memSize aBufSize, memSize &aValSize ) { GetValue_Func p= fCI->ui.GetValue; if (!p) return LOCERR_NOTIMP; return p( fCI, aKeyH, aValName, aValType, aBuffer,aBufSize,&aValSize ); } // GetValue TSyError TEngineModuleBridge::GetValueByID( KeyH aKeyH, sInt32 aID, sInt32 arrIndex, uInt16 aValType, appPointer aBuffer, memSize aBufSize, memSize &aValSize ) { GetValueByID_Func p= fCI->ui.GetValueByID; if (!p) return LOCERR_NOTIMP; return p( fCI, aKeyH, aID, arrIndex, aValType, aBuffer,aBufSize,&aValSize ); } // GetValueByID sInt32 TEngineModuleBridge::GetValueID( KeyH aKeyH, cAppCharP aName ) { GetValueID_Func p= fCI->ui.GetValueID; if (!p) return 0; return p( fCI, aKeyH, aName ); } // GetValueID TSyError TEngineModuleBridge::SetValue( KeyH aKeyH, cAppCharP aValName, uInt16 aValType, cAppPointer aBuffer, memSize aValSize ) { SetValue_Func p= fCI->ui.SetValue; if (!p) return LOCERR_NOTIMP; return p( fCI, aKeyH, aValName, aValType, aBuffer,aValSize ); } // SetValue TSyError TEngineModuleBridge::SetValueByID( KeyH aKeyH, sInt32 aID, sInt32 arrIndex, uInt16 aValType, cAppPointer aBuffer, memSize aValSize ) { SetValueByID_Func p= fCI->ui.SetValueByID; if (!p) return LOCERR_NOTIMP; return p( fCI, aKeyH, aID, arrIndex, aValType, aBuffer,aValSize ); } // SetValueByID // ---- tunnel functions ----------------------------------------------------------------- TSyError TEngineModuleBridge::StartDataRead( SessionH aContext, cAppCharP lastToken, cAppCharP resumeToken ) { SDR_Func p= fCI->dt.StartDataRead; if (!p) return LOCERR_NOTIMP; return p( (CContext)aContext, lastToken, resumeToken ); } // StartDataRead TSyError TEngineModuleBridge::ReadNextItem( SessionH aContext, ItemID aID, appCharP *aItemData, sInt32 *aStatus, bool aFirst ) { RdNItemSFunc p= fCI->dt.ReadNextItem; if (!p) return LOCERR_NOTIMP; return p( (CContext)aContext, aID, aItemData, aStatus, aFirst ); } // ReadNextItem TSyError TEngineModuleBridge::ReadItem( SessionH aContext, cItemID aID, appCharP *aItemData ) { Rd_ItemSFunc p= fCI->dt.ReadItem; if (!p) return LOCERR_NOTIMP; return p( (CContext)aContext, aID, aItemData ); } // ReadItem TSyError TEngineModuleBridge::EndDataRead( SessionH aContext ) { EDR_Func p= fCI->dt.EndDataRead; if (!p) return LOCERR_NOTIMP; return p( (CContext)aContext ); } // EndDataRead TSyError TEngineModuleBridge::StartDataWrite( SessionH aContext ) { SDW_Func p= fCI->dt.StartDataWrite; if (!p) return LOCERR_NOTIMP; return p( (CContext)aContext ); } // StartDataWrite TSyError TEngineModuleBridge::InsertItem( SessionH aContext, cAppCharP aItemData, ItemID aID ) { InsItemSFunc p= fCI->dt.InsertItem; if (!p) return LOCERR_NOTIMP; return p( (CContext)aContext, aItemData, aID ); } // InsertItem TSyError TEngineModuleBridge::UpdateItem( SessionH aContext, cAppCharP aItemData, cItemID aID, ItemID updID ) { UpdItemSFunc p= fCI->dt.UpdateItem; if (!p) return LOCERR_NOTIMP; return p( (CContext)aContext, aItemData, aID, updID ); } // UpdateItem TSyError TEngineModuleBridge::MoveItem( SessionH aContext, cItemID aID, cAppCharP newParID ) { MovItem_Func p= fCI->dt.MoveItem; if (!p) return LOCERR_NOTIMP; return p( (CContext)aContext, aID, newParID ); } // MoveItem TSyError TEngineModuleBridge::DeleteItem( SessionH aContext, cItemID aID ) { DelItem_Func p= fCI->dt.DeleteItem; if (!p) return LOCERR_NOTIMP; return p( (CContext)aContext, aID ); } // DeleteItem TSyError TEngineModuleBridge::EndDataWrite( SessionH aContext, bool success, appCharP *newToken ) { EDW_Func p= fCI->dt.EndDataWrite; if (!p) return LOCERR_NOTIMP; return p( (CContext)aContext, success, newToken ); } // EndDataWrite void TEngineModuleBridge::DisposeObj( SessionH aContext, void* memory ) { DisposeProc p= fCI->dt.DisposeObj; if (!p) return; p( (CContext)aContext, memory ); } // DisposeObj // --- asKey --- TSyError TEngineModuleBridge::ReadNextItemAsKey( SessionH aContext, ItemID aID, KeyH aItemKey, sInt32 *aStatus, bool aFirst ) { RdNItemKFunc p= fCI->dt.ReadNextItemAsKey; if (!p) return LOCERR_NOTIMP; return p( (CContext)aContext, aID, aItemKey, aStatus, aFirst ); } // ReadNextItemAsKey TSyError TEngineModuleBridge::ReadItemAsKey( SessionH aContext, cItemID aID, KeyH aItemKey ) { Rd_ItemKFunc p= fCI->dt.ReadItemAsKey; if (!p) return LOCERR_NOTIMP; return p( (CContext)aContext, aID, aItemKey ); } // ReadItemAsKey TSyError TEngineModuleBridge::InsertItemAsKey( SessionH aContext, KeyH aItemKey, ItemID aID ) { InsItemKFunc p= fCI->dt.InsertItemAsKey; if (!p) return LOCERR_NOTIMP; return p( (CContext)aContext, aItemKey, aID ); } // InsertItemAsKey TSyError TEngineModuleBridge::UpdateItemAsKey( SessionH aContext, KeyH aItemKey, cItemID aID, ItemID updID ) { UpdItemKFunc p= fCI->dt.UpdateItemAsKey; if (!p) return LOCERR_NOTIMP; return p( (CContext)aContext, aItemKey, aID, updID ); } // UpdateItemAsKey } // namespace sysync /* eof */ libsynthesis-3.4.0.47.1/src/sysync_SDK/Sources/enginemodulebridge.h000066400000000000000000000137631226375725500251220ustar00rootroot00000000000000/* * File: enginemodulebridge.h * * Author: Beat Forster (bfo@synthesis.ch) * * * Synthesis SyncML client bridge connector * * Copyright (c) 2007-2011 by Synthesis AG + plan44.ch * * */ #ifndef ENGINEMODULEBRIDGE_H #define ENGINEMODULEBRIDGE_H // inherited from ... #include "enginemodulebase.h" namespace sysync { class TEngineModuleBridge : public TEngineModuleBase { typedef TEngineModuleBase inherited; public: TEngineModuleBridge(); virtual ~TEngineModuleBridge(); appPointer fDLL; bool fIsServer; virtual TSyError Init(); virtual TSyError Term(); // ---- Engine init ------------------------------------------------------------------------- virtual TSyError SetStringMode ( uInt16 aCharSet, uInt16 aLineEndMode= LEM_CSTR, bool aBigEndian= false ); virtual TSyError InitEngineXML ( cAppCharP aConfigXML ); virtual TSyError InitEngineFile ( cAppCharP aConfigFilePath ); virtual TSyError InitEngineCB ( TXMLConfigReadFunc aReaderFunc, void* aContext ); // ---- Running a Sync Session -------------------------------------------------------------- virtual TSyError OpenSession ( SessionH &aSessionH, uInt32 aSelector = 0, cAppCharP aSessionName = NULL ); virtual TSyError OpenSessionKey ( SessionH aSessionH, KeyH &aKeyH, uInt16 aMode ); virtual TSyError SessionStep ( SessionH aSessionH, uInt16 &aStepCmd, TEngineProgressInfo *aInfoP= NULL ); virtual TSyError GetSyncMLBuffer ( SessionH aSessionH, bool aForSend, appPointer &aBuffer, memSize &aBufSize ); virtual TSyError RetSyncMLBuffer ( SessionH aSessionH, bool aForSend, memSize aRetSize ); virtual TSyError ReadSyncMLBuffer ( SessionH aSessionH, appPointer aBuffer, memSize aBufSize, memSize &aValSize ); virtual TSyError WriteSyncMLBuffer( SessionH aSessionH, appPointer aBuffer, memSize aValSize ); virtual TSyError CloseSession ( SessionH aSessionH ); // ---- Settings access --------------------------------------------------------------------- virtual TSyError OpenKeyByPath ( KeyH &aKeyH, KeyH aParentKeyH, cAppCharP aPath, uInt16 aMode ); virtual TSyError OpenSubkey ( KeyH &aKeyH, KeyH aParentKeyH, sInt32 aID, uInt16 aMode ); virtual TSyError DeleteSubkey ( KeyH aParentKeyH, sInt32 aID ); virtual TSyError GetKeyID ( KeyH aKeyH, sInt32 &aID ); virtual TSyError SetTextMode ( KeyH aKeyH, uInt16 aCharSet, uInt16 aLineEndMode= LEM_CSTR, bool aBigEndian = false ); virtual TSyError SetTimeMode ( KeyH aKeyH, uInt16 aTimeMode ); virtual TSyError CloseKey ( KeyH aKeyH ); virtual TSyError GetValue ( KeyH aKeyH, cAppCharP aValName, uInt16 aValType, appPointer aBuffer, memSize aBufSize, memSize &aValSize ); virtual TSyError GetValueByID ( KeyH aKeyH, sInt32 aID, sInt32 arrIndex, uInt16 aValType, appPointer aBuffer, memSize aBufSize, memSize &aValSize ); virtual sInt32 GetValueID ( KeyH aKeyH, cAppCharP aName ); virtual TSyError SetValue ( KeyH aKeyH, cAppCharP aValName, uInt16 aValType, cAppPointer aBuffer, memSize aValSize ); virtual TSyError SetValueByID ( KeyH aKeyH, sInt32 aID, sInt32 arrIndex, uInt16 aValType, cAppPointer aBuffer, memSize aValSize ); // ---- Tunnel methods ---------------------------------------------------------------------- virtual TSyError StartDataRead ( SessionH ac, cAppCharP lastToken, cAppCharP resumeToken ); virtual TSyError ReadNextItem ( SessionH ac, ItemID aID, appCharP *aItemData, sInt32 *aStatus, bool aFirst ); virtual TSyError ReadItem ( SessionH ac, cItemID aID, appCharP *aItemData ); virtual TSyError EndDataRead ( SessionH ac ); virtual TSyError StartDataWrite ( SessionH ac ); virtual TSyError InsertItem ( SessionH ac, cAppCharP aItemData, ItemID aID ); virtual TSyError UpdateItem ( SessionH ac, cAppCharP aItemData, cItemID aID, ItemID updID ); virtual TSyError MoveItem ( SessionH ac, cItemID aID, cAppCharP newParID ); virtual TSyError DeleteItem ( SessionH ac, cItemID aID ); virtual TSyError EndDataWrite ( SessionH ac, bool success, appCharP *newToken ); virtual void DisposeObj ( SessionH ac, void* memory ); // ---- asKey ---- virtual TSyError ReadNextItemAsKey( SessionH ac, ItemID aID, KeyH aItemKey, sInt32 *aStatus, bool aFirst ); virtual TSyError ReadItemAsKey ( SessionH ac, cItemID aID, KeyH aItemKey ); virtual TSyError InsertItemAsKey ( SessionH ac, KeyH aItemKey, ItemID aID ); virtual TSyError UpdateItemAsKey ( SessionH ac, KeyH aItemKey, cItemID aID, ItemID updID ); }; // TEngineModuleBridge } // namespace #endif // ENGINEMODULEBRIDGE /* eof */ libsynthesis-3.4.0.47.1/src/sysync_SDK/Sources/enginestubs.c000066400000000000000000000017241226375725500236050ustar00rootroot00000000000000/* * File: enginestubs.c * * Author: Patrick Ohly * * Dummy implementations of the engine entry points * for client and server, to be linked statically against * SDK instead of the real engine. The engine then has * to be opened as module. * * Copyright (c) 2009 by Synthesis AG (www.synthesis.ch) * */ #include "sync_dbapi.h" ENGINE_ENTRY TSyError SYSYNC_EXTERNAL(ConnectEngine) (UI_Call_In *aCI, CVersion *aEngVersion, CVersion aPrgVersion, uInt16 aDebugFlags ) ENTRY_ATTR { return 404; } ENGINE_ENTRY TSyError SYSYNC_EXTERNAL(DisconnectEngine) (UI_Call_In aCI) ENTRY_ATTR { return 404; } ENGINE_ENTRY TSyError SYSYNC_EXTERNAL_SRV(ConnectEngine) (UI_Call_In *aCI, CVersion *aEngVersion, CVersion aPrgVersion, uInt16 aDebugFlags ) ENTRY_ATTR { return 404; } ENGINE_ENTRY TSyError SYSYNC_EXTERNAL_SRV(DisconnectEngine) (UI_Call_In aCI) ENTRY_ATTR { return 404; } libsynthesis-3.4.0.47.1/src/sysync_SDK/Sources/gb2312_tables_inc.cpp000077500000000000000000011523451226375725500247140ustar00rootroot00000000000000const size_t ucs2_to_gb2312_numelems = 28470; const treeval_t ucs2_to_gb2312_elements[ucs2_to_gb2312_numelems] = { 0x284A,0x00E0,0x0000,0x0000,0x0000,0x00D1,0x0000,0x0000,0x000F,0x0000,0x0000,0x0000,0x0000,0x0005,0x0002,0xA3A4, 0x0001,0xA3FE,0x0003,0x0001,0xA1EA,0x0000,0xA1E9,0x0071,0x0031,0x0011,0x0001,0x0008,0x0004,0x0002,0xA1AB,0xA3FD, 0x0002,0xA3FC,0xA3FB,0x0004,0x0002,0xA3FA,0xA3F9,0x0002,0xA3F8,0xA3F7,0x0010,0x0008,0x0004,0x0002,0xA3F6,0xA3F5, 0x0002,0xA3F4,0xA3F3,0x0004,0x0002,0xA3F2,0xA3F1,0x0002,0xA3F0,0xA3EF,0x0008,0x0004,0x0002,0xA3EE,0xA3ED,0x0002, 0xA3EC,0xA3EB,0x0004,0x0002,0xA3EA,0xA3E9,0x0002,0xA3E8,0xA3E7,0x0020,0x0010,0x0008,0x0004,0x0002,0xA3E6,0xA3E5, 0x0002,0xA3E4,0xA3E3,0x0004,0x0002,0xA3E2,0xA3E1,0x0002,0xA3E0,0xA3DF,0x0008,0x0004,0x0002,0xA3DE,0xA3DD,0x0002, 0xA3DC,0xA3DB,0x0004,0x0002,0xA3DA,0xA3D9,0x0002,0xA3D8,0xA3D7,0x0010,0x0008,0x0004,0x0002,0xA3D6,0xA3D5,0x0002, 0xA3D4,0xA3D3,0x0004,0x0002,0xA3D2,0xA3D1,0x0002,0xA3D0,0xA3CF,0x0008,0x0004,0x0002,0xA3CE,0xA3CD,0x0002,0xA3CC, 0xA3CB,0x0004,0x0002,0xA3CA,0xA3C9,0x0002,0xA3C8,0xA3C7,0x0040,0x0020,0x0010,0x0008,0x0004,0x0002,0xA3C6,0xA3C5, 0x0002,0xA3C4,0xA3C3,0x0004,0x0002,0xA3C2,0xA3C1,0x0002,0xA3C0,0xA3BF,0x0008,0x0004,0x0002,0xA3BE,0xA3BD,0x0002, 0xA3BC,0xA3BB,0x0004,0x0002,0xA1C3,0xA3B9,0x0002,0xA3B8,0xA3B7,0x0010,0x0008,0x0004,0x0002,0xA3B6,0xA3B5,0x0002, 0xA3B4,0xA3B3,0x0004,0x0002,0xA3B2,0xA3B1,0x0002,0xA3B0,0xA3AF,0x0008,0x0004,0x0002,0xA3AE,0xA1AA,0x0002,0xA3AC, 0xA3AB,0x0004,0x0002,0xA3AA,0xA3A9,0x0002,0xA3A8,0xA3A7,0x0000,0x0000,0x0008,0x0004,0x0002,0xA3A6,0xA3A5,0x0002, 0xA1E7,0xA3A3,0x0000,0x0002,0xA3A2,0xA3A1,0x0000,0x0001,0x0001,0x0001,0x0000,0x0001,0x0001,0x0001,0x0001,0x0000, 0xD8A3,0x0001,0x1292,0x081E,0x03BD,0x01D8,0x0090,0x0001,0x0043,0x001D,0x0009,0x0001,0x0001,0x0003,0x0000,0xBACD, 0x0002,0xD9DF,0xB9EA,0x000A,0x0005,0x0001,0x0002,0xB9EA,0xEDE8,0x0000,0x0002,0xB9A8,0xC1FA,0x0006,0x0003,0x0001, 0xEDE8,0x0000,0xB9A8,0x0001,0x0000,0xC5D3,0x001C,0x000F,0x0007,0x0003,0x0001,0xC1FA,0x0002,0xF6BB,0xC8A3,0x0004, 0x0002,0xF6BA,0xF6B9,0x0002,0xF6B8,0xF6B7,0x0008,0x0004,0x0002,0xF6B6,0xF6B5,0x0002,0xC1E4,0xF6B4,0x0001,0x0002, 0xF6B3,0xB3DD,0x0005,0x0001,0x0001,0x0001,0xF6BB,0x0001,0x0000,0x0000,0xC8A3,0x002A,0x0017,0x000A,0x0004,0x0001, 0x0000,0xF6B9,0x0003,0x0000,0xF6BA,0x0001,0xC4F6,0x0006,0x0003,0x0000,0xF6B8,0x0001,0xB3F6,0x0003,0x0001,0xC1E4, 0x0002,0xF6B6,0xF6B4,0x0008,0x0004,0x0001,0x0000,0xF6B7,0x0000,0x0001,0xF6B5,0x0004,0x0001,0x0000,0xF6B3,0x0004, 0x0002,0xB3DD,0xECB4,0x0000,0xC6EB,0x000D,0x0008,0x0004,0x0001,0x0001,0xD5AB,0x0000,0x0000,0xC6EB,0x0000,0x0001, 0x0000,0xF7FE,0x000D,0x0007,0x0004,0x0002,0xF7FD,0xF7FC,0x0001,0xB1C7,0x0003,0x0001,0xF7FA,0x0001,0xF7FB,0x0004, 0x0001,0x0000,0xF7FA,0x0001,0x0001,0xF7F9,0x009A,0x0046,0x001D,0x000C,0x0005,0x0000,0x0001,0x0001,0xF7F8,0x0001, 0x0003,0x0001,0xF7F7,0x0001,0xCAF3,0x0005,0x0001,0x0001,0x0000,0xDCB1,0x0006,0x0003,0x0000,0xD8BB,0x0000,0xB6AC, 0x0003,0x0000,0xB9C4,0x0001,0xD8BE,0x0011,0x000C,0x0006,0x0003,0x0001,0xB6A6,0x0000,0xF6BE,0x0003,0x0000,0xF6BD, 0x0000,0xF6BE,0x0000,0x0000,0x0000,0xF7A1,0x000E,0x0008,0x0004,0x0002,0xF6BD,0xF6BC,0x0002,0xF6BC,0xEDEB,0x0003, 0x0000,0xEDEA,0x0000,0xEDE9,0x0006,0x0003,0x0000,0xF7F2,0x0001,0xC3B9,0x0000,0x0001,0xF7F5,0x002D,0x0017,0x000B, 0x0004,0x0000,0x0000,0xF7F6,0x0003,0x0001,0xF7F5,0x0002,0xF7F2,0xB5B3,0x0006,0x0003,0x0000,0xF7F3,0x0000,0xF7F4, 0x0003,0x0001,0xF7F1,0x0001,0xF7EF,0x000E,0x0008,0x0004,0x0002,0xF7F0,0xB5E3,0x0002,0xF7EE,0xF7ED,0x0003,0x0000, 0xF7EC,0x0001,0xC4AC,0x0004,0x0001,0x0001,0xC7AD,0x0001,0x0000,0xBADA,0x0014,0x000C,0x0008,0x0004,0x0002,0xF0A4, 0xC0E8,0x0002,0xCAF2,0xD9E4,0x0001,0x0000,0xD9E4,0x0004,0x0001,0x0001,0xBBC6,0x0000,0x0000,0xBBC6,0x000D,0x0007, 0x0003,0x0001,0xF7E2,0x0002,0xF7E1,0xC3B4,0x0003,0x0000,0xC2E9,0x0001,0xF4EF,0x0000,0x0001,0x0002,0xC3E6,0xF4F0, 0x0045,0x001D,0x000D,0x0005,0x0001,0x0001,0x0000,0xF4EF,0x0000,0x0003,0x0001,0xC2F3,0x0002,0xC2F3,0xB4D6,0x0007, 0x0000,0x0003,0x0000,0xF7EB,0x0000,0xF7EA,0x0004,0x0000,0x0000,0xC0F6,0x0000,0x0002,0xC2B4,0xF7E8,0x000F,0x0007, 0x0001,0x0003,0x0000,0xF7E7,0x0001,0xF7E6,0x0004,0x0000,0x0000,0xF7E5,0x0000,0x0001,0xF7E4,0x000E,0x0008,0x0004, 0x0002,0xC2B9,0xF5BA,0x0002,0xD1CE,0xBCEF,0x0003,0x0001,0xF5BA,0x0000,0xCFCC,0x0004,0x0001,0x0000,0xC2B1,0x0003, 0x0000,0xF0D9,0x0002,0xF0D7,0xD3A5,0x002F,0x0018,0x000D,0x0005,0x0001,0x0002,0xF0D8,0xF0D6,0x0004,0x0002,0xF0D5, 0xF0D4,0x0002,0xF0D3,0xF0D2,0x0007,0x0004,0x0002,0xF0D1,0xF0D0,0x0001,0xBAD7,0x0000,0x0000,0xF0CF,0x000D,0x0006, 0x0003,0x0001,0xF0CE,0x0001,0xF0CD,0x0004,0x0002,0xF0CC,0xF0CB,0x0001,0xF7BD,0x0006,0x0003,0x0000,0xF0CA,0x0000, 0xF0C9,0x0001,0x0000,0xF0C8,0x001E,0x000F,0x0007,0x0004,0x0002,0xC5F4,0xF0C7,0x0001,0xF0C6,0x0004,0x0002,0xF0C5, 0xC8B5,0x0002,0xF0C4,0xF0C3,0x0008,0x0004,0x0002,0xF0C2,0xF0C1,0x0002,0xB6EC,0xF0C0,0x0004,0x0002,0xBEE9,0xF0BF, 0x0000,0xF0BE,0x000E,0x0007,0x0004,0x0002,0xBAE8,0xF0BD,0x0000,0xB8EB,0x0003,0x0001,0xF0BC,0x0002,0xF0BB,0xF0B9, 0x0007,0x0004,0x0002,0xF0BA,0xF0B8,0x0000,0xCDD2,0x0004,0x0002,0xD4A7,0xF0B6,0x0000,0xF0B7,0x00B8,0x0069,0x003F, 0x002E,0x001B,0x000D,0x0005,0x0002,0xD1EC,0x0001,0xD1BC,0x0004,0x0002,0xF0B5,0xF0B4,0x0002,0xF0B3,0xF0B2,0x0007, 0x0003,0x0000,0xF0B1,0x0002,0xD1BB,0xC5B8,0x0003,0x0001,0xC3F9,0x0002,0xF0B0,0xBCA6,0x000E,0x0008,0x0004,0x0002, 0xF0AF,0xC4F1,0x0002,0xF0BD,0xF0BF,0x0003,0x0001,0xF0D9,0x0000,0xF0D0,0x0000,0x0001,0x0001,0xF0B5,0x0001,0x0006, 0x0001,0x0001,0x0002,0xF0D8,0xD3A5,0x0004,0x0000,0x0000,0xF0D6,0x0003,0x0000,0xF0C2,0x0000,0xF0D5,0x0019,0x000B, 0x0005,0x0000,0x0000,0x0001,0xF0D3,0x0000,0x0001,0x0002,0xF0D4,0xF0B8,0x0006,0x0001,0x0001,0x0002,0xF0D2,0xF0BA, 0x0004,0x0000,0x0001,0xC5B8,0x0000,0x0001,0xF0D1,0x0006,0x0001,0x0001,0x0001,0x0000,0xF0CE,0x0006,0x0001,0x0000, 0x0002,0xF0CF,0xF7BD,0x0001,0x0000,0x0000,0xBAD7,0x001F,0x0013,0x0009,0x0000,0x0004,0x0000,0x0001,0xDDBA,0x0001, 0x0001,0xF0CD,0x0005,0x0001,0x0001,0x0000,0xF0CA,0x0000,0x0000,0x0000,0xF0C9,0x0006,0x0000,0x0001,0x0001,0x0001, 0xF0C8,0x0001,0x0001,0x0001,0x0000,0xC8B5,0x0021,0x000F,0x000A,0x0004,0x0000,0x0000,0xB5F1,0x0003,0x0000,0xC5F4, 0x0000,0xF0C6,0x0001,0x0001,0x0001,0xF0C4,0x000A,0x0006,0x0003,0x0000,0xF0C0,0x0001,0xB6EC,0x0000,0x0000,0xF0C3, 0x0001,0x0003,0x0001,0xF0BE,0x0002,0xF0C1,0xBEE9,0x0006,0x0001,0x0001,0x0001,0x0000,0xF0BC,0x0000,0x0004,0x0000, 0x0001,0xB8EB,0x0000,0x0001,0xBAE8,0x0094,0x0035,0x001F,0x0010,0x0006,0x0000,0x0000,0x0002,0xF0BB,0xF0B9,0x0006, 0x0003,0x0000,0xD1BC,0x0000,0xD1EC,0x0000,0x0001,0xF0B3,0x000A,0x0006,0x0003,0x0001,0xF0B7,0x0001,0xF0B6,0x0000, 0x0001,0xD4A7,0x0000,0x0001,0x0001,0xCDD2,0x000C,0x0005,0x0001,0x0001,0x0001,0xD1BB,0x0000,0x0003,0x0001,0xF0B1, 0x0000,0xF0B2,0x0001,0x0004,0x0001,0x0000,0xF0B0,0x0000,0x0002,0xC3F9,0xB7EF,0x0029,0x000F,0x0005,0x0001,0x0001, 0x0001,0xF0AF,0x0006,0x0003,0x0001,0xD9EC,0x0001,0xC4F1,0x0001,0x0000,0xF7AF,0x000D,0x0007,0x0003,0x0001,0xF7AE, 0x0002,0xC1DB,0xF7AD,0x0003,0x0000,0xF7AC,0x0001,0xF7AB,0x0008,0x0004,0x0002,0xF7AA,0xF7A9,0x0002,0xB1EE,0xF7A8, 0x0000,0x0002,0xF7A7,0xF7A6,0x001B,0x000F,0x0008,0x0004,0x0002,0xF7A5,0xF7A4,0x0002,0xF7A3,0xF7A2,0x0004,0x0002, 0xF7A1,0xF6FE,0x0000,0xF6FD,0x0007,0x0003,0x0001,0xF6FC,0x0002,0xF6FB,0xF6FA,0x0000,0x0002,0xF6F9,0xC8FA,0x000B, 0x0004,0x0001,0x0001,0xF6F8,0x0004,0x0002,0xF6F7,0xF6F6,0x0000,0xF6F5,0x0008,0x0004,0x0002,0xBEA8,0xF6F4,0x0002, 0xF6F3,0xF6F2,0x0004,0x0002,0xF6F1,0xF6F0,0x0002,0xF6EF,0xF6EE,0x005E,0x0036,0x001D,0x000D,0x0007,0x0003,0x0000, 0xF6ED,0x0002,0xF6EC,0xF6EB,0x0003,0x0001,0xF6EA,0x0001,0xF6E9,0x0008,0x0004,0x0002,0xF6E8,0xF6E7,0x0002,0xF6E6, 0xF6E5,0x0004,0x0002,0xC0F0,0xF6E4,0x0002,0xF6E3,0xF6E2,0x000E,0x0007,0x0004,0x0002,0xF6E1,0xF6E0,0x0000,0xF6DF, 0x0004,0x0002,0xCFCA,0xF6DE,0x0000,0xF6DD,0x0004,0x0001,0x0001,0xF6DC,0x0003,0x0000,0xF6DB,0x0002,0xF6DA,0xF6D9, 0x0018,0x000B,0x0007,0x0003,0x0000,0xF6D8,0x0002,0xF6D7,0xB1AB,0x0000,0x0001,0xF6D6,0x0008,0x0004,0x0002,0xF6D4, 0xF6D3,0x0002,0xF6D2,0xF6D1,0x0001,0x0002,0xF6D0,0xC2B3,0x000A,0x0004,0x0000,0x0001,0xF6CF,0x0003,0x0000,0xD3E3, 0x0000,0xF6E2,0x0000,0x0000,0x0002,0xF6D4,0xF6F9,0x001C,0x000A,0x0005,0x0000,0x0001,0x0001,0xF6DD,0x0000,0x0000, 0x0001,0xF7AF,0x0005,0x0000,0x0000,0x0001,0xF6D7,0x0007,0x0004,0x0002,0xF6E0,0xC1DB,0x0000,0xF7AC,0x0003,0x0000, 0xF7AD,0x0000,0xF7AE,0x000A,0x0005,0x0001,0x0001,0x0001,0xB1EE,0x0000,0x0000,0x0000,0xF7A8,0x000A,0x0004,0x0001, 0x0000,0xF7A7,0x0003,0x0001,0xF7A9,0x0001,0xF6E4,0x0004,0x0000,0x0001,0xF6E6,0x0003,0x0001,0xF7A6,0x0002,0xF7A1, 0xF6E3,0x020F,0x00C3,0x005E,0x0028,0x0017,0x0010,0x0005,0x0001,0x0000,0x0000,0xF7A2,0x0005,0x0000,0x0002,0xF7A5, 0xF7A3,0x0003,0x0000,0xF7A4,0x0000,0xF6E5,0x0001,0x0001,0x0001,0x0002,0xC8FA,0xF6FB,0x000B,0x0005,0x0001,0x0000, 0x0000,0xF6FA,0x0000,0x0000,0x0002,0xF6FC,0xF6F8,0x0000,0x0001,0x0000,0x0000,0xF6EA,0x0023,0x0015,0x0009,0x0004, 0x0000,0x0001,0xF6F3,0x0001,0x0002,0xF6ED,0xF6EC,0x0006,0x0003,0x0001,0xBEA8,0x0000,0xF6F0,0x0003,0x0001,0xF6EF, 0x0001,0xF6F2,0x0005,0x0001,0x0001,0x0000,0xF6F4,0x0005,0x0001,0x0002,0xF6DF,0xF6EB,0x0000,0x0001,0xF6F6,0x000C, 0x0005,0x0001,0x0001,0x0001,0xF6E8,0x0000,0x0003,0x0000,0xC0F0,0x0000,0xF6E9,0x0000,0x0000,0x0000,0x0002,0xF6E1, 0xF6E7,0x0029,0x0019,0x000C,0x0000,0x0004,0x0001,0x0001,0xCFCA,0x0003,0x0000,0xF6D9,0x0002,0xF6DE,0xF6DB,0x0008, 0x0004,0x0001,0x0001,0xF6DC,0x0001,0x0001,0xF6DA,0x0001,0x0001,0x0001,0xF6D6,0x0007,0x0000,0x0000,0x0000,0x0002, 0xB1AB,0xF6D8,0x0001,0x0004,0x0001,0x0000,0xF6CF,0x0000,0x0001,0xF6D0,0x0013,0x0006,0x0000,0x0000,0x0001,0x0000, 0xC2B3,0x0005,0x0001,0x0001,0x0001,0xD3E3,0x0004,0x0000,0x0001,0xF7CA,0x0000,0x0001,0xC4A7,0x001A,0x000B,0x0007, 0x0003,0x0000,0xF7CE,0x0002,0xCEBA,0xF7CB,0x0000,0x0000,0xF7CD,0x0007,0x0004,0x0002,0xF7CB,0xF7CC,0x0000,0xF7CA, 0x0004,0x0002,0xF7C8,0xC6C7,0x0002,0xF7C9,0xBBEA,0x000A,0x0004,0x0000,0x0000,0xBFFD,0x0003,0x0001,0xB9ED,0x0000, 0xE5F7,0x0001,0x0001,0x0001,0xD8AA,0x008D,0x0041,0x0025,0x0016,0x0009,0x0005,0x0002,0xD3F4,0x0001,0xDBCB,0x0000, 0x0000,0xE3CE,0x0007,0x0003,0x0001,0xE3D2,0x0002,0xBAE5,0xC4D6,0x0003,0x0001,0xB6B7,0x0001,0xF7E0,0x0007,0x0000, 0x0003,0x0000,0xF7DE,0x0001,0xF7DF,0x0004,0x0000,0x0000,0xD0EB,0x0001,0x0001,0xF7DE,0x0012,0x0008,0x0004,0x0001, 0x0001,0xF7DD,0x0000,0x0001,0xBAFA,0x0004,0x0001,0x0000,0xF7DC,0x0003,0x0000,0xCBC9,0x0001,0xD7D7,0x0005,0x0001, 0x0001,0x0001,0xF7D9,0x0000,0x0000,0x0001,0xF7DB,0x0025,0x0012,0x000B,0x0004,0x0001,0x0001,0xF7D7,0x0004,0x0002, 0xB7A2,0xF7DA,0x0001,0xF7D8,0x0001,0x0003,0x0000,0xF7D6,0x0001,0xB7C2,0x0007,0x0000,0x0003,0x0001,0xF7D5,0x0001, 0xF7D4,0x0004,0x0001,0x0000,0xB8DF,0x0004,0x0002,0xF7C5,0xF7C6,0x0002,0xCCE5,0xCBE8,0x0011,0x000C,0x0007,0x0004, 0x0002,0xD4E0,0xF7C7,0x0001,0xF7C3,0x0001,0x0002,0xF7C6,0xF7C5,0x0001,0x0000,0x0001,0xF7C3,0x000B,0x0007,0x0004, 0x0002,0xF7C4,0xF7C1,0x0000,0xF7C2,0x0001,0x0000,0xF7C0,0x0007,0x0003,0x0000,0xF7BF,0x0002,0xBAA1,0xF7BC,0x0000, 0x0000,0xF7BE,0x006C,0x0031,0x0014,0x0008,0x0000,0x0003,0x0001,0xF7BA,0x0002,0xF7BB,0xB0B9,0x0005,0x0001,0x0002, 0xB9C7,0xE6F8,0x0003,0x0001,0xE6F7,0x0002,0xD6E8,0xE6F6,0x0010,0x0008,0x0004,0x0002,0xE6F5,0xC2E2,0x0002,0xE6F4, 0xE6F3,0x0004,0x0002,0xE5B9,0xE6F2,0x0002,0xE6F1,0xE6F0,0x0007,0x0003,0x0000,0xC9A7,0x0002,0xE6EF,0xC6AD,0x0003, 0x0000,0xE6EE,0x0001,0xE6ED,0x001B,0x000D,0x0008,0x0004,0x0002,0xE6EC,0xC6EF,0x0002,0xE6EB,0xBFA5,0x0001,0x0002, 0xD1E9,0xB3D2,0x0007,0x0003,0x0000,0xE6EA,0x0002,0xE6E9,0xBAA7,0x0004,0x0002,0xC2E6,0xE6E8,0x0000,0xBDBE,0x0010, 0x0008,0x0004,0x0002,0xC2EE,0xE6E7,0x0002,0xE6E6,0xE6E4,0x0004,0x0002,0xBCDD,0xE6E5,0x0002,0xCDD5,0xD7A4,0x0008, 0x0004,0x0002,0xE6E3,0xBED4,0x0002,0xE6E2,0xE6E1,0x0004,0x0002,0xCABB,0xE6E0,0x0002,0xC2BF,0xB2B5,0x002C,0x0018, 0x000E,0x0007,0x0003,0x0001,0xC7FD,0x0002,0xB3DB,0xD1B1,0x0004,0x0002,0xCDD4,0xD4A6,0x0000,0xC2ED,0x0004,0x0000, 0x0000,0xE6EA,0x0003,0x0001,0xE6F7,0x0000,0xE6F8,0x000A,0x0006,0x0003,0x0000,0xC2BF,0x0001,0xD6E8,0x0001,0x0001, 0xE6E4,0x0006,0x0003,0x0000,0xBEAA,0x0001,0xD1E9,0x0000,0x0001,0xBDBE,0x0013,0x0008,0x0004,0x0001,0x0001,0xE6F6, 0x0000,0x0001,0xE6E7,0x0004,0x0000,0x0000,0xE6E8,0x0003,0x0001,0xC7FD,0x0002,0xE6F5,0xE6F4,0x000B,0x0007,0x0004, 0x0002,0xE6EE,0xE6F1,0x0000,0xDDEB,0x0000,0x0000,0xC2E2,0x0005,0x0001,0x0002,0xE6F3,0xC9A7,0x0000,0x0000,0xE6E3, 0x010E,0x0061,0x002F,0x0019,0x0010,0x000B,0x0005,0x0002,0xB2DD,0x0001,0xCCDA,0x0003,0x0001,0xE6F2,0x0000,0xE6EF, 0x0000,0x0000,0x0000,0xE5B9,0x0001,0x0004,0x0001,0x0000,0xC6AD,0x0000,0x0001,0xE6F0,0x000D,0x0008,0x0001,0x0004, 0x0002,0xE6EB,0xC6EF,0x0000,0xE6EC,0x0001,0x0001,0x0000,0xE6ED,0x0000,0x0004,0x0001,0x0000,0xB3D2,0x0000,0x0000, 0xBFA5,0x001F,0x0009,0x0000,0x0004,0x0001,0x0000,0xC2E6,0x0001,0x0000,0xBAA7,0x000A,0x0004,0x0000,0x0001,0xE6E9, 0x0003,0x0000,0xE6E1,0x0000,0xCDD5,0x0007,0x0003,0x0000,0xCABB,0x0002,0xE6E2,0xE6E6,0x0001,0x0002,0xBCDD,0xE6E0, 0x0009,0x0000,0x0000,0x0003,0x0001,0xBED4,0x0002,0xE6E5,0xD7A4,0x0005,0x0000,0x0001,0x0000,0xB2B5,0x0001,0x0001, 0x0001,0xD1B1,0x0058,0x0023,0x0015,0x000D,0x0006,0x0003,0x0000,0xB3DB,0x0000,0xCDD4,0x0003,0x0001,0xB7EB,0x0002, 0xD4A6,0xC2ED,0x0004,0x0001,0x0001,0xDCB0,0x0001,0x0000,0xF0A5,0x0001,0x0005,0x0001,0x0002,0xCFE3,0xD9E5,0x0004, 0x0002,0xD8B8,0xCAD7,0x0002,0xE2CE,0xE2CD,0x001D,0x000E,0x0008,0x0004,0x0002,0xE2CC,0xC2F8,0x0002,0xE2CB,0xE2CA, 0x0003,0x0000,0xC1F3,0x0000,0xE2C9,0x0007,0x0004,0x0002,0xB2F6,0xE2C8,0x0001,0xC0A1,0x0004,0x0002,0xE2C7,0xB9DD, 0x0002,0xCFDA,0xE2C6,0x000C,0x0005,0x0001,0x0002,0xC4D9,0xE2C5,0x0003,0x0000,0xB6F6,0x0002,0xE2C4,0xB1FD,0x0004, 0x0000,0x0001,0xBDC8,0x0004,0x0002,0xE2C3,0xC8C4,0x0002,0xB6FC,0xE2C2,0x002F,0x001D,0x000F,0x0007,0x0003,0x0001, 0xCBC7,0x0002,0xB1A5,0xCACE,0x0004,0x0002,0xBDA4,0xD2FB,0x0002,0xB7B9,0xE2C1,0x0008,0x0004,0x0002,0xE2C0,0xE2BF, 0x0002,0xE2BE,0xE2BD,0x0003,0x0000,0xE2BC,0x0000,0xBCA2,0x000A,0x0004,0x0000,0x0000,0xE2BB,0x0003,0x0001,0xB2F6, 0x0001,0xF7D0,0x0001,0x0003,0x0000,0xF7CF,0x0002,0xF7D2,0xF7D3,0x0015,0x000A,0x0006,0x0003,0x0001,0xC8C4,0x0000, 0xBCA2,0x0001,0x0001,0xE2CD,0x0007,0x0003,0x0000,0xC0A1,0x0002,0xE2CB,0xE2CA,0x0001,0x0000,0xC2F8,0x000C,0x0004, 0x0000,0x0000,0xE2C9,0x0004,0x0002,0xE2C8,0xC1F3,0x0002,0xC0A1,0xE2BE,0x0001,0x0001,0x0000,0xCEB9,0x0091,0x0047, 0x0020,0x0010,0x0008,0x0004,0x0000,0x0000,0xE2BC,0x0000,0x0001,0xF7D1,0x0004,0x0001,0x0001,0xB9DD,0x0000,0x0000, 0xCEB9,0x0008,0x0004,0x0001,0x0000,0xCFDA,0x0000,0x0001,0xBDA4,0x0000,0x0004,0x0002,0xE2C6,0xEBC8,0x0001,0xD3E0, 0x0017,0x000D,0x0008,0x0004,0x0002,0xB6F6,0xC4D9,0x0002,0xE2C4,0xB2CD,0x0001,0x0002,0xF7D0,0xB6FC,0x0006,0x0003, 0x0001,0xD1F8,0x0000,0xE2C3,0x0001,0x0000,0xB1FD,0x000B,0x0004,0x0000,0x0000,0xBDC8,0x0003,0x0001,0xCACE,0x0002, 0xB1A5,0xCBC7,0x0001,0x0001,0x0001,0xE2C2,0x002B,0x0016,0x000A,0x0004,0x0000,0x0001,0xD2FB,0x0003,0x0000,0xB7B9, 0x0000,0xE2C1,0x0008,0x0004,0x0002,0xE2C0,0xE2BF,0x0002,0xE2BD,0xF7CF,0x0000,0x0000,0xE2B8,0x0009,0x0004,0x0000, 0x0001,0xBCA2,0x0000,0x0002,0xCAB3,0xB7C9,0x0008,0x0004,0x0002,0xB7C9,0xECAE,0x0002,0xECAD,0xC6AE,0x0001,0x0000, 0xECAC,0x0012,0x000B,0x0007,0x0004,0x0002,0xECAB,0xECAA,0x0000,0xECA9,0x0000,0x0001,0xB7E7,0x0001,0x0003,0x0001, 0xECAD,0x0001,0xC6AE,0x0005,0x0001,0x0001,0x0001,0xECAC,0x0004,0x0000,0x0001,0xD1EF,0x0000,0x0001,0xECAB,0x0071, 0x0034,0x0017,0x000B,0x0006,0x0003,0x0000,0xB9CE,0x0000,0xCCA8,0x0000,0x0002,0xECAA,0xECA9,0x0004,0x0001,0x0001, 0xB7E7,0x0004,0x0002,0xC8A7,0xF2AD,0x0002,0xF2AC,0xB2FC,0x000F,0x0007,0x0003,0x0001,0xF2AB,0x0002,0xF2AA,0xB5DF, 0x0004,0x0002,0xF2A9,0xF2A8,0x0002,0xB6EE,0xD1D5,0x0007,0x0004,0x0002,0xF2A7,0xF2A6,0x0001,0xCCE2,0x0004,0x0002, 0xBFC5,0xD3B1,0x0001,0xF2A5,0x001D,0x000E,0x0007,0x0003,0x0000,0xCDC7,0x0002,0xC6B5,0xD2C3,0x0003,0x0000,0xF2A4, 0x0002,0xF2A3,0xF2A2,0x0007,0x0003,0x0001,0xBCD5,0x0002,0xF2A1,0xBEB1,0x0004,0x0002,0xC6C4,0xC1EC,0x0002,0xC2AD, 0xD4A4,0x0010,0x0008,0x0004,0x0002,0xF1FE,0xCBCC,0x0002,0xB0E4,0xF1FD,0x0004,0x0002,0xB6D9,0xB9CB,0x0002,0xCDE7, 0xE7EF,0x0008,0x0004,0x0002,0xD0EB,0xCBB3,0x0002,0xCFEE,0xF1FC,0x0004,0x0002,0xC7EA,0xB6A5,0x0002,0xD2B3,0xC8A7, 0x0025,0x0015,0x000B,0x0007,0x0003,0x0000,0xF2A8,0x0002,0xC2AD,0xF2AD,0x0000,0x0000,0xCFD4,0x0004,0x0000,0x0000, 0xB2FC,0x0003,0x0000,0xB9CB,0x0000,0xF2AB,0x0008,0x0004,0x0000,0x0001,0xF2A9,0x0000,0x0001,0xC0E0,0x0000,0x0003, 0x0000,0xB5DF,0x0002,0xF2AA,0xD4B8,0x0011,0x000C,0x0004,0x0000,0x0000,0xF2A7,0x0004,0x0002,0xD1D5,0xF2A6,0x0002, 0xB6EE,0xCCE2,0x0001,0x0000,0x0001,0xBFC5,0x0001,0x0007,0x0003,0x0000,0xC6B5,0x0002,0xCDC7,0xBEB1,0x0000,0x0000, 0xF2A5,0x05A8,0x0279,0x0117,0x0089,0x004F,0x001F,0x000F,0x0007,0x0001,0x0003,0x0000,0xBCD5,0x0001,0xCDB7,0x0004, 0x0000,0x0001,0xB8A9,0x0001,0x0000,0xF2A4,0x0007,0x0000,0x0003,0x0000,0xD2C3,0x0001,0xF2A1,0x0004,0x0000,0x0000, 0xF2A2,0x0000,0x0002,0xC1EC,0xC6C4,0x001C,0x000E,0x0007,0x0003,0x0001,0xB6D9,0x0002,0xB0E4,0xCDE7,0x0004,0x0002, 0xD4A4,0xF1FE,0x0000,0xF1FD,0x0006,0x0003,0x0000,0xCBCC,0x0000,0xE7EF,0x0004,0x0002,0xD0EB,0xF1FC,0x0002,0xCBB3, 0xCFEE,0x000B,0x0007,0x0003,0x0001,0xC7EA,0x0002,0xB6A5,0xD2B3,0x0000,0x0001,0xCFEC,0x0004,0x0000,0x0001,0xD4CF, 0x0001,0x0002,0xC9D8,0xD4CF,0x0022,0x0016,0x0008,0x0004,0x0000,0x0001,0xD2F4,0x0001,0x0001,0xBEC2,0x0008,0x0004, 0x0002,0xE8BA,0xE8B9,0x0002,0xE8B8,0xBAAB,0x0003,0x0001,0xC8CD,0x0000,0xCEA4,0x0005,0x0001,0x0001,0x0000,0xE8B9, 0x0000,0x0003,0x0000,0xE8BA,0x0001,0xE8B8,0x0010,0x0005,0x0000,0x0000,0x0001,0xBAAB,0x0007,0x0004,0x0002,0xC8CD, 0xCEA4,0x0001,0xF7B5,0x0001,0x0000,0xC7A7,0x0000,0x0000,0x0003,0x0001,0xF7B2,0x0001,0xE7D6,0x0048,0x0021,0x0014, 0x000C,0x0006,0x0003,0x0000,0xF7B9,0x0000,0xF7B8,0x0003,0x0001,0xF7B5,0x0001,0xB1DE,0x0004,0x0000,0x0001,0xF7B6, 0x0001,0x0000,0xC7EF,0x0008,0x0004,0x0000,0x0001,0xF7B7,0x0000,0x0000,0xBECF,0x0001,0x0000,0x0000,0xC7CA,0x0015, 0x000D,0x0007,0x0003,0x0000,0xF7B4,0x0002,0xF7B3,0xF7B2,0x0003,0x0001,0xB9AE,0x0001,0xB0B0,0x0004,0x0000,0x0001, 0xD0AC,0x0001,0x0001,0xF7B1,0x0008,0x0004,0x0001,0x0000,0xBDD5,0x0001,0x0000,0xE7A5,0x0006,0x0003,0x0000,0xF7B0, 0x0000,0xCDE0,0x0001,0x0000,0xB0D0,0x0027,0x0010,0x0006,0x0000,0x0000,0x0002,0xD1A5,0xBDF9,0x0004,0x0001,0x0001, 0xB8EF,0x0003,0x0000,0xD8CC,0x0001,0xD8CC,0x000B,0x0005,0x0001,0x0002,0xC3E6,0xC3D2,0x0003,0x0000,0xBFBF,0x0000, 0xB7C7,0x0008,0x0004,0x0002,0xBEB2,0xB5E5,0x0002,0xF6A6,0xBEB2,0x0001,0x0000,0xBEB8,0x000C,0x0007,0x0000,0x0003, 0x0001,0xF6A6,0x0000,0xC7E0,0x0001,0x0000,0x0000,0xC1E9,0x000B,0x0006,0x0003,0x0000,0xF6B0,0x0000,0xF6A8,0x0001, 0x0002,0xF6B2,0xF6AB,0x0004,0x0001,0x0001,0xC5F9,0x0000,0x0000,0xB0D4,0x00AE,0x004F,0x0022,0x0012,0x0008,0x0004, 0x0001,0x0001,0xC2B6,0x0000,0x0001,0xF6B1,0x0006,0x0003,0x0000,0xF6B0,0x0001,0xF6AF,0x0001,0x0000,0xCEED,0x0008, 0x0004,0x0000,0x0001,0xC1EF,0x0001,0x0001,0xCFBC,0x0004,0x0000,0x0001,0xCBAA,0x0001,0x0001,0xC1D8,0x0017,0x000B, 0x0004,0x0001,0x0000,0xC4DE,0x0003,0x0000,0xD5B4,0x0002,0xF6AD,0xF6AE,0x0004,0x0000,0x0000,0xBBF4,0x0004,0x0002, 0xC3B9,0xF6AC,0x0002,0xD5F0,0xF6AA,0x000B,0x0004,0x0000,0x0001,0xCFF6,0x0004,0x0002,0xF6AB,0xD0E8,0x0001,0xCEED, 0x0004,0x0001,0x0000,0xB5E7,0x0003,0x0000,0xB1A2,0x0002,0xC0D7,0xC1E3,0x002B,0x0014,0x000B,0x0005,0x0001,0x0002, 0xF6A8,0xD4C6,0x0003,0x0001,0xB7D5,0x0000,0xF6A9,0x0004,0x0001,0x0001,0xD1A9,0x0000,0x0002,0xF6A7,0xD3EA,0x000B, 0x0005,0x0001,0x0002,0xC4D1,0xC0EB,0x0003,0x0001,0xF6C5,0x0001,0xBCA6,0x0006,0x0003,0x0001,0xD4D3,0x0000,0xB3FB, 0x0003,0x0000,0xCBAB,0x0001,0xCBE4,0x001A,0x000B,0x0006,0x0003,0x0000,0xB5F1,0x0001,0xF6C3,0x0001,0x0002,0xB3FB, 0xEEA1,0x0007,0x0004,0x0002,0xD3BA,0xB4C6,0x0000,0xF6C1,0x0004,0x0002,0xEFF4,0xDDC8,0x0002,0xB9CD,0xBCAF,0x000C, 0x0005,0x0000,0x0002,0xD1C5,0xD0DB,0x0004,0x0002,0xD1E3,0xC8B8,0x0001,0xC4D1,0x0007,0x0004,0x0002,0xF6C1,0xF6C0, 0x0000,0xD6BB,0x0004,0x0002,0xF6BF,0xC1A5,0x0001,0xC1A5,0x0051,0x0023,0x0015,0x000B,0x0006,0x0003,0x0001,0xC2A4, 0x0000,0xE3C4,0x0000,0x0002,0xD2FE,0xDAF4,0x0004,0x0001,0x0001,0xCFD5,0x0003,0x0001,0xCBE6,0x0000,0xCBED,0x0001, 0x0006,0x0003,0x0001,0xD5CF,0x0000,0xBCCA,0x0004,0x0002,0xCFB6,0xB0AF,0x0000,0xDAF3,0x001A,0x000C,0x0005,0x0000, 0x0002,0xD4C9,0xB8F4,0x0003,0x0001,0xD2FE,0x0002,0xCBE6,0xBDD7,0x0007,0x0003,0x0000,0xDAF2,0x0002,0xCBE5,0xB6D3, 0x0004,0x0002,0xDAED,0xDAF1,0x0001,0xC2A1,0x0008,0x0000,0x0004,0x0002,0xD3E7,0xB5CC,0x0000,0xD2A3,0x0005,0x0000, 0x0002,0xD1F4,0xE4BE,0x0003,0x0001,0xC2BD,0x0002,0xCFDD,0xCCD5,0x0032,0x0019,0x000C,0x0008,0x0004,0x0002,0xC1EA, 0xDAF0,0x0002,0xB3C2,0xDAEF,0x0000,0x0001,0xD2F5,0x0006,0x0003,0x0001,0xDAEE,0x0001,0xC5E3,0x0004,0x0002,0xCFD5, 0xD4C9,0x0000,0xDAED,0x000E,0x0007,0x0003,0x0001,0xB3FD,0x0002,0xD5F3,0xD4BA,0x0003,0x0000,0xB6B8,0x0002,0xDAEC, 0xC9FD,0x0007,0x0004,0x0002,0xC9C2,0xC9C2,0x0000,0xB1DD,0x0000,0x0001,0xDAEA,0x0018,0x0009,0x0005,0x0000,0x0002, 0xC9C2,0xDAEB,0x0000,0x0001,0xCFDE,0x0007,0x0004,0x0002,0xBDB5,0xC4B0,0x0000,0xC2AA,0x0004,0x0002,0xDAEA,0xB3C2, 0x0002,0xC2A4,0xC2BD,0x000D,0x0007,0x0004,0x0002,0xBCCA,0xB8BD,0x0001,0xDAE9,0x0003,0x0001,0xCDD3,0x0000,0xB0A2, 0x0008,0x0004,0x0002,0xDAE7,0xDAE8,0x0002,0xD7E8,0xDBE6,0x0001,0x0001,0xBDD7,0x018F,0x00C9,0x006F,0x0032,0x0019, 0x000D,0x0006,0x0002,0xD5F3,0x0002,0xD2F5,0xD1F4,0x0004,0x0002,0xB7C0,0xDAE5,0x0001,0xD6B7,0x0006,0x0003,0x0000, 0xC8EE,0x0000,0xBFD3,0x0003,0x0000,0xDAE6,0x0000,0xB6F2,0x000B,0x0004,0x0001,0x0000,0xCDD3,0x0004,0x0002,0xDAE3, 0xDAE4,0x0001,0xB6D3,0x0007,0x0004,0x0002,0xD8EC,0xDAE2,0x0000,0xB8B7,0x0004,0x0002,0xE3DB,0xE3DA,0x0001,0xE3D9, 0x001E,0x000F,0x0007,0x0004,0x0002,0xE3D8,0xE3D7,0x0000,0xC0AB,0x0004,0x0002,0xE3D6,0xC0BB,0x0002,0xB2FB,0xE3D5, 0x0008,0x0004,0x0002,0xD1D6,0xE3D4,0x0002,0xE3D3,0xE3D2,0x0004,0x0002,0xE3D1,0xD1CB,0x0000,0xE3D0,0x000F,0x0008, 0x0004,0x0002,0xE3CF,0xD4C4,0x0002,0xE3CE,0xE3CD,0x0004,0x0002,0xBAD2,0xB8F3,0x0000,0xB7A7,0x0008,0x0004,0x0002, 0xE3CC,0xC3F6,0x0002,0xE3CB,0xCEC5,0x0004,0x0002,0xB9EB,0xC4D6,0x0002,0xD5A2,0xC3C6,0x002E,0x001E,0x0010,0x0008, 0x0004,0x0002,0xE3CA,0xE3C9,0x0002,0xBCE4,0xE3C8,0x0004,0x0002,0xCFD0,0xE3C7,0x0002,0xC8F2,0xB4B3,0x0007,0x0004, 0x0002,0xCECA,0xB1D5,0x0001,0xE3C6,0x0004,0x0002,0xC9C1,0xE3C5,0x0000,0xC3C5,0x0009,0x0004,0x0000,0x0001,0xE3CB, 0x0000,0x0002,0xB1D9,0xB2FB,0x0000,0x0003,0x0000,0xE3DB,0x0000,0xB9D8,0x0016,0x000B,0x0007,0x0004,0x0002,0xB4B3, 0xE3DA,0x0000,0xE3D8,0x0001,0x0000,0xE3D9,0x0005,0x0001,0x0002,0xC0BB,0xE3D7,0x0003,0x0000,0xC0AB,0x0000,0xE3C7, 0x000A,0x0006,0x0003,0x0000,0xB0E5,0x0001,0xE3D6,0x0001,0x0001,0xE3D3,0x0008,0x0004,0x0002,0xE3D0,0xE3D4,0x0002, 0xE3D5,0xD1D6,0x0000,0x0001,0xD1CB,0x0050,0x0027,0x0015,0x0008,0x0004,0x0000,0x0000,0xE3D1,0x0000,0x0001,0xD4C4, 0x0007,0x0003,0x0001,0xE3CC,0x0002,0xE3CF,0xE3CD,0x0003,0x0001,0xC3F6,0x0000,0xB9EB,0x000D,0x0007,0x0003,0x0001, 0xB7A7,0x0002,0xE3D8,0xB8F3,0x0003,0x0001,0xBAD2,0x0001,0xC3D8,0x0001,0x0001,0x0000,0xD5A2,0x0017,0x000C,0x0005, 0x0001,0x0002,0xE3C9,0xBCE4,0x0004,0x0002,0xCFD0,0xCFD0,0x0001,0xC8F2,0x0007,0x0003,0x0000,0xE3C8,0x0002,0xE3CA, 0xBFAA,0x0000,0x0001,0xB1D5,0x000D,0x0006,0x0003,0x0000,0xE3C6,0x0001,0xC9C1,0x0003,0x0000,0xE3C5,0x0002,0xC3C5, 0xB3A4,0x0001,0x0001,0x0001,0xB3A4,0x003B,0x001D,0x000E,0x0006,0x0003,0x0000,0xCFE2,0x0001,0xEFF0,0x0004,0x0002, 0xEFEF,0xEFEE,0x0002,0xC1AD,0xEFED,0x0007,0x0003,0x0001,0xC0D8,0x0002,0xEFEC,0xEFEB,0x0004,0x0002,0xEFEA,0xEFE9, 0x0002,0xEFE8,0xEFE7,0x000F,0x0008,0x0004,0x0002,0xEFE6,0xEFE5,0x0002,0xEFE4,0xC1CD,0x0004,0x0002,0xEFE3,0xEFE2, 0x0001,0xEFE0,0x0008,0x0004,0x0002,0xEFDF,0xEFE1,0x0002,0xBEB5,0xEFDE,0x0003,0x0001,0xEFDD,0x0002,0xEFDC,0xEFDB, 0x001D,0x000F,0x0007,0x0003,0x0000,0xEFDA,0x0002,0xEFD9,0xEFD8,0x0004,0x0002,0xEFD7,0xB0F7,0x0002,0xB8E4,0xEFD6, 0x0007,0x0004,0x0002,0xEFD5,0xC4F8,0x0000,0xEFD4,0x0004,0x0002,0xC4F7,0xEFD3,0x0001,0xD5F2,0x000F,0x0007,0x0004, 0x0002,0xEFD2,0xEFD1,0x0000,0xEFD0,0x0004,0x0002,0xEFCE,0xC3BE,0x0002,0xB6C6,0xEFCD,0x0007,0x0003,0x0000,0xEFCC, 0x0002,0xEFCB,0xB6CD,0x0004,0x0002,0xEFF1,0xC7C2,0x0002,0xEFCA,0xEFC9,0x00F4,0x007B,0x003C,0x001E,0x000F,0x0007, 0x0004,0x0002,0xEFC8,0xEFCF,0x0000,0xEFC7,0x0004,0x0002,0xEFC6,0xEFC5,0x0002,0xC3CC,0xBEE2,0x0008,0x0004,0x0002, 0xBCFC,0xB6A7,0x0002,0xEFC4,0xEFC2,0x0004,0x0002,0xEFC1,0xEFC3,0x0000,0xCFC7,0x000F,0x0008,0x0004,0x0002,0xBDF5, 0xD7B6,0x0002,0xB4B8,0xC2E0,0x0004,0x0002,0xEFC0,0xCEFD,0x0001,0xEFBF,0x0007,0x0004,0x0002,0xEFBE,0xEFBD,0x0001, 0xEFBC,0x0004,0x0002,0xC3AA,0xB4ED,0x0002,0xEFBB,0xD5E0,0x0020,0x0010,0x0008,0x0004,0x0002,0xEFBA,0xEFB9,0x0002, 0xEFB8,0xEFB7,0x0004,0x0002,0xEFB6,0xCCE0,0x0002,0xC8F1,0xEFB5,0x0008,0x0004,0x0002,0xEFB4,0xEFB3,0x0002,0xD0BF, 0xB7E6,0x0004,0x0002,0xEFB2,0xEFB1,0x0002,0xD0E2,0xEFB0,0x0010,0x0008,0x0004,0x0002,0xEFAF,0xB9F8,0x0002,0xB3FA, 0xEFAD,0x0004,0x0002,0xEFAE,0xCBF8,0x0002,0xCFFA,0xEFAC,0x0007,0x0004,0x0002,0xC1B4,0xEFAB,0x0000,0xEFAA,0x0004, 0x0002,0xC6CC,0xEFA9,0x0002,0xD6FD,0xEFA8,0x003E,0x0020,0x0010,0x0008,0x0004,0x0002,0xD2F8,0xEFA7,0x0002,0xEFA6, 0xEFA5,0x0004,0x0002,0xB2F9,0xD2BF,0x0002,0xBDC2,0xEFA4,0x0008,0x0004,0x0002,0xEFA3,0xC3FA,0x0002,0xB8F5,0xEFA2, 0x0004,0x0002,0xEEFE,0xEFA1,0x0002,0xEEFD,0xEEFC,0x000F,0x0007,0x0003,0x0001,0xEEFB,0x0002,0xEEFA,0xCFB3,0x0004, 0x0002,0xEEF9,0xD5A1,0x0002,0xEEF8,0xEEF7,0x0008,0x0004,0x0002,0xEEF6,0xC2C1,0x0002,0xCDAD,0xEEF5,0x0003,0x0001, 0xEEF3,0x0002,0xEEF4,0xEEF2,0x001B,0x000C,0x0005,0x0000,0x0002,0xEEF1,0xEEF0,0x0004,0x0002,0xEEEF,0xEEEE,0x0000, 0xEEED,0x0008,0x0004,0x0002,0xEEEC,0xEEEB,0x0002,0xEEEA,0xEEE9,0x0004,0x0002,0xEEE8,0xEEE7,0x0000,0xEEE6,0x0010, 0x0008,0x0004,0x0002,0xC3AD,0xC7A6,0x0002,0xEEE5,0xC1E5,0x0004,0x0002,0xB2AC,0xCCFA,0x0002,0xD3CB,0xEEE4,0x0008, 0x0004,0x0002,0xBCD8,0xEEE3,0x0002,0xEEE2,0xD7EA,0x0004,0x0002,0xEEE1,0xEEE0,0x0002,0xEEDF,0xEEDE,0x0071,0x003F, 0x0020,0x0010,0x0008,0x0004,0x0002,0xEEDD,0xB2A7,0x0002,0xEEDC,0xC7AF,0x0004,0x0002,0xEEDB,0xC7AE,0x0002,0xEEDA, 0xEED9,0x0008,0x0004,0x0002,0xC5A5,0xEED7,0x0002,0xEED8,0xEED5,0x0004,0x0002,0xEED6,0xB9B3,0x0002,0xCED9,0xBEFB, 0x0010,0x0008,0x0004,0x0002,0xC7D5,0xD4BF,0x0002,0xEED4,0xEED3,0x0004,0x0002,0xB8D6,0xB1B5,0x0002,0xC4C6,0xD6D3, 0x0008,0x0004,0x0002,0xB3AE,0xB6DB,0x0002,0xEED2,0xEED1,0x0004,0x0002,0xEED0,0xB8C6,0x0001,0xEECE,0x001E,0x000E, 0x0007,0x0003,0x0001,0xEECF,0x0002,0xEECD,0xB5F6,0x0003,0x0000,0xB7B0,0x0002,0xEECC,0xEECB,0x0008,0x0004,0x0002, 0xC7A5,0xEECA,0x0002,0xEEC9,0xEEC7,0x0004,0x0002,0xEEC8,0xB6A4,0x0002,0xD5EB,0xEEC6,0x0009,0x0005,0x0000,0x0002, 0xEEC5,0xEEC4,0x0001,0x0001,0xD4E4,0x0007,0x0004,0x0002,0xF6C7,0xD7EA,0x0000,0xC2E0,0x0001,0x0001,0xC4F7,0x001B, 0x0011,0x0007,0x0001,0x0003,0x0000,0xCFE2,0x0000,0xD4BF,0x0006,0x0003,0x0001,0xEFE7,0x0001,0xF6CE,0x0000,0x0000, 0xC2AF,0x0000,0x0005,0x0001,0x0002,0xC5D9,0xEFF0,0x0001,0x0000,0xEEE5,0x000E,0x0006,0x0001,0x0000,0x0002,0xBCF8, 0xBCF8,0x0004,0x0001,0x0000,0xEFD9,0x0000,0x0000,0xEFEC,0x0008,0x0004,0x0001,0x0000,0xD6FD,0x0001,0x0001,0xEFEE, 0x0004,0x0000,0x0000,0xF6CD,0x0003,0x0000,0xEEF5,0x0000,0xEEEC,0x021C,0x00F5,0x0078,0x0037,0x001E,0x0013,0x0009, 0x0004,0x0001,0x0000,0xCCFA,0x0000,0x0002,0xC0D8,0xEFED,0x0004,0x0000,0x0001,0xC1AD,0x0003,0x0000,0xEFD4,0x0001, 0xEFD0,0x0005,0x0001,0x0001,0x0001,0xEFE8,0x0001,0x0001,0x0002,0xEFEB,0xD6D3,0x000C,0x0007,0x0001,0x0003,0x0001, 0xEFA9,0x0001,0xC1CD,0x0001,0x0000,0x0000,0xEFA6,0x0005,0x0001,0x0000,0x0000,0xEEF3,0x0004,0x0001,0x0000,0xD0E2, 0x0001,0x0000,0xEFEA,0x0024,0x000C,0x0007,0x0000,0x0003,0x0000,0xEFE4,0x0000,0xEEFC,0x0001,0x0001,0x0001,0xF6C9, 0x000A,0x0004,0x0001,0x0001,0xEFCE,0x0003,0x0001,0xEFDA,0x0000,0xBEB5,0x0008,0x0004,0x0002,0xB2F9,0xEFDE,0x0002, 0xEFDC,0xEFDB,0x0003,0x0001,0xC6DD,0x0001,0xEFCF,0x0014,0x0009,0x0005,0x0000,0x0002,0xEFAC,0xF7E9,0x0001,0x0000, 0xEFE1,0x0005,0x0001,0x0002,0xEFDD,0xEFD2,0x0003,0x0001,0xF6CB,0x0001,0xC1B4,0x0000,0x0004,0x0000,0x0000,0xD0FD, 0x0000,0x0000,0xEFDF,0x0043,0x0026,0x0016,0x000A,0x0004,0x0001,0x0000,0xEFD8,0x0003,0x0000,0xC4F8,0x0001,0xEFD7, 0x0006,0x0003,0x0001,0xD5F2,0x0001,0xB8E4,0x0003,0x0001,0xEFCB,0x0000,0xEFA1,0x0009,0x0005,0x0000,0x0002,0xEEF8, 0xEFD6,0x0000,0x0001,0xCED9,0x0001,0x0003,0x0001,0xB4B8,0x0001,0xEFD3,0x0010,0x0008,0x0000,0x0004,0x0002,0xC7B9, 0xCBF8,0x0001,0xC8DB,0x0004,0x0000,0x0000,0xF6CC,0x0000,0x0001,0xB0F7,0x0005,0x0001,0x0000,0x0001,0xC3BE,0x0004, 0x0000,0x0001,0xD6D3,0x0000,0x0001,0xD5E0,0x001F,0x0012,0x000A,0x0006,0x0003,0x0001,0xEFC8,0x0000,0xBCFC,0x0001, 0x0001,0xEFCC,0x0004,0x0001,0x0001,0xC7C2,0x0000,0x0001,0xF6CA,0x0006,0x0000,0x0001,0x0002,0xEFC6,0xEFCA,0x0001, 0x0003,0x0000,0xB6CD,0x0001,0xD5A1,0x000D,0x0005,0x0000,0x0001,0x0001,0xEFC9,0x0004,0x0001,0x0000,0xB6C6,0x0000, 0x0000,0xB9F8,0x0006,0x0000,0x0000,0x0002,0xEFC7,0xEECD,0x0004,0x0000,0x0001,0xF6C9,0x0001,0x0001,0xEFAA,0x0089, 0x0045,0x0027,0x0012,0x0008,0x0004,0x0001,0x0000,0xB1ED,0x0000,0x0001,0xC3CC,0x0006,0x0003,0x0001,0xB4ED,0x0000, 0xEFC0,0x0000,0x0001,0xCEFD,0x000A,0x0006,0x0003,0x0000,0xC3AA,0x0000,0xBDF5,0x0001,0x0000,0xC7AE,0x0004,0x0000, 0x0000,0xB6A7,0x0003,0x0001,0xEFBC,0x0002,0xEFA3,0xEFC5,0x000F,0x000A,0x0006,0x0003,0x0000,0xB4B8,0x0001,0xEFBF, 0x0001,0x0000,0xEFB9,0x0000,0x0000,0x0000,0xD7B6,0x000A,0x0004,0x0000,0x0000,0xEFC3,0x0003,0x0000,0xC2BC,0x0001, 0xEFBE,0x0001,0x0000,0x0000,0xB8D6,0x0024,0x0013,0x0008,0x0004,0x0000,0x0000,0xBEE2,0x0001,0x0001,0xEFAB,0x0007, 0x0004,0x0002,0xEFAE,0xEFAF,0x0000,0xEEF1,0x0001,0x0000,0xC6CC,0x000A,0x0006,0x0003,0x0000,0xEFB0,0x0000,0xEFB8, 0x0000,0x0000,0xB3FA,0x0000,0x0003,0x0001,0xEFB7,0x0001,0xEFB2,0x000D,0x0005,0x0001,0x0001,0x0000,0xB7E6,0x0004, 0x0000,0x0001,0xEEF2,0x0000,0x0000,0xEEFA,0x000D,0x0007,0x0004,0x0002,0xF6C8,0xB1B5,0x0001,0xD0BF,0x0003,0x0001, 0xEFB6,0x0001,0xC2C1,0x0001,0x0000,0x0002,0xEFB1,0xCCE0,0x0050,0x002B,0x0016,0x000A,0x0004,0x0000,0x0001,0xCFFA, 0x0003,0x0001,0xC8F1,0x0000,0xBAB8,0x0004,0x0001,0x0000,0xF6C7,0x0004,0x0002,0xEEED,0xEFA4,0x0002,0xEEF0,0xEEFB, 0x000B,0x0007,0x0003,0x0000,0xEFA7,0x0002,0xEEF7,0xD2BF,0x0000,0x0001,0xEFA8,0x0004,0x0000,0x0000,0xEEEE,0x0003, 0x0000,0xCFCE,0x0000,0xEFA2,0x0012,0x000D,0x0007,0x0003,0x0000,0xC3FA,0x0002,0xEEF9,0xD2C4,0x0003,0x0001,0xEEFD, 0x0001,0xCFB3,0x0000,0x0001,0x0000,0xF6C6,0x0008,0x0004,0x0001,0x0001,0xCDAD,0x0000,0x0001,0xEFA5,0x0005,0x0000, 0x0002,0xD2F8,0xEEFE,0x0003,0x0001,0xB8F5,0x0000,0xEEEF,0x0024,0x0010,0x0008,0x0004,0x0000,0x0000,0xBDC2,0x0000, 0x0000,0xBCF8,0x0004,0x0001,0x0001,0xEEE3,0x0000,0x0000,0xEEE2,0x0008,0x0004,0x0001,0x0000,0xEEDB,0x0000,0x0000, 0xB9B3,0x0006,0x0003,0x0000,0xD1EB,0x0000,0xEEE1,0x0003,0x0001,0xC7A6,0x0000,0xC3AD,0x0015,0x0009,0x0004,0x0000, 0x0001,0xC7AF,0x0001,0x0002,0xD7A2,0xB2AC,0x0006,0x0003,0x0001,0xB3FA,0x0001,0xEEE9,0x0003,0x0001,0xC5D9,0x0001, 0xEEE7,0x0008,0x0000,0x0003,0x0000,0xEEE8,0x0002,0xD7EA,0xEED2,0x0008,0x0004,0x0002,0xBCD8,0xEEE4,0x0002,0xD3CB, 0xEEDF,0x0001,0x0002,0xEEDA,0xEEEB,0x0148,0x00A0,0x0047,0x0023,0x0013,0x000C,0x0006,0x0002,0xEEE0,0x0002,0xEEDC, 0xCCA8,0x0003,0x0001,0xC1E5,0x0000,0xEEDD,0x0000,0x0003,0x0001,0xEEE6,0x0001,0xEEEA,0x000B,0x0005,0x0001,0x0002, 0xEED6,0xEED1,0x0003,0x0000,0xEED8,0x0000,0xB8C6,0x0000,0x0001,0x0001,0xBEFB,0x0011,0x0006,0x0001,0x0000,0x0002, 0xC5A5,0xB3AE,0x0007,0x0004,0x0002,0xEED3,0xEED4,0x0000,0xCEFD,0x0000,0x0000,0xB6DB,0x000B,0x0006,0x0003,0x0000, 0xC4C6,0x0001,0xC7A6,0x0000,0x0002,0xD4BF,0xEED7,0x0000,0x0004,0x0002,0xEED5,0xEED9,0x0000,0xBDEF,0x0025,0x0012, 0x000A,0x0006,0x0003,0x0000,0xEECF,0x0000,0xEECA,0x0000,0x0000,0xEECE,0x0004,0x0000,0x0000,0xEED1,0x0000,0x0001, 0xBAB8,0x000D,0x0007,0x0003,0x0000,0xB7B0,0x0002,0xEECB,0xBFDB,0x0003,0x0001,0xEECC,0x0000,0xB5F6,0x0001,0x0000, 0x0002,0xD5EB,0xB8AA,0x001E,0x000E,0x0007,0x0004,0x0002,0xEEC7,0xB6A4,0x0000,0xEEC8,0x0004,0x0002,0xEEC9,0xEEC6, 0x0000,0xEEC5,0x0008,0x0004,0x0002,0xBDF0,0xC0E5,0x0002,0xC1BF,0xD2B0,0x0004,0x0002,0xD6D8,0xC0EF,0x0002,0xCACD, 0xCACD,0x000D,0x0007,0x0003,0x0000,0xD3D4,0x0002,0xB2C9,0xB2C9,0x0003,0x0000,0xF5A6,0x0000,0xF5A7,0x0005,0x0000, 0x0002,0xD0C6,0xC4F0,0x0001,0x0001,0xF5B8,0x004A,0x0024,0x0013,0x0006,0x0001,0x0000,0x0002,0xF5B6,0xF5B7,0x0005, 0x0001,0x0002,0xF5B5,0xF5B4,0x0004,0x0002,0xF5B3,0xBDB4,0x0002,0xD2BD,0xF5B2,0x0006,0x0001,0x0001,0x0002,0xF5B1, 0xF5B0,0x0004,0x0001,0x0001,0xD4CD,0x0003,0x0001,0xB3F3,0x0002,0xC8A9,0xC3D1,0x0011,0x0005,0x0001,0x0001,0x0001, 0xD0D1,0x0005,0x0000,0x0002,0xF5AF,0xF5AD,0x0004,0x0002,0xF5AE,0xF5AB,0x0000,0xB4D7,0x000C,0x0006,0x0003,0x0000, 0xD7ED,0x0000,0xB4BC,0x0003,0x0000,0xF5AC,0x0000,0xEBE7,0x0005,0x0001,0x0002,0xC4F0,0xF5A7,0x0000,0x0000,0xF5A6, 0x0036,0x001D,0x000F,0x0008,0x0004,0x0002,0xF5AA,0xCBE1,0x0002,0xBFE1,0xC3B8,0x0004,0x0002,0xBDCD,0xF5A9,0x0001, 0xF5A8,0x0008,0x0004,0x0002,0xBDB4,0xF5A3,0x0002,0xF5A5,0xCDAA,0x0003,0x0001,0xB3EA,0x0001,0xC0D2,0x000C,0x0004, 0x0000,0x0000,0xF5A4,0x0004,0x0002,0xCBD6,0xF4FE,0x0002,0xBAA8,0xF5A1,0x0007,0x0004,0x0002,0xF5A2,0xCDAA,0x0001, 0xCCAA,0x0003,0x0000,0xD4CD,0x0001,0xB7D3,0x0018,0x0009,0x0005,0x0001,0x0002,0xD0EF,0xF0B2,0x0001,0x0001,0xBEC6, 0x0007,0x0003,0x0001,0xF4FB,0x0002,0xF4FD,0xF4FC,0x0004,0x0002,0xC5E4,0xD7C3,0x0002,0xC7F5,0xF4FA,0x000B,0x0007, 0x0004,0x0002,0xD3CF,0xDBAA,0x0001,0xDBBA,0x0001,0x0000,0xDBB9,0x0001,0x0001,0x0001,0xDAF7,0x00A2,0x004D,0x0028, 0x0017,0x000C,0x0006,0x0003,0x0000,0xDBB8,0x0001,0xDBA6,0x0003,0x0001,0xDAFE,0x0001,0xB5A6,0x0007,0x0004,0x0002, 0xDBB6,0xC1DA,0x0000,0xDBB7,0x0000,0x0000,0xD6A3,0x0009,0x0004,0x0001,0x0000,0xB5CB,0x0001,0x0002,0xDBB5,0xDBB3, 0x0004,0x0001,0x0001,0xDBB4,0x0000,0x0000,0xDEA4,0x0011,0x000C,0x0006,0x0003,0x0000,0xB1C9,0x0001,0xD4C7,0x0003, 0x0001,0xDAF9,0x0001,0xD7DE,0x0000,0x0001,0x0001,0xCFA2,0x000C,0x0006,0x0003,0x0000,0xCFE7,0x0001,0xDBA9,0x0003, 0x0001,0xDBB2,0x0001,0xB6F5,0x0004,0x0001,0x0001,0xDBB1,0x0000,0x0000,0xB6BC,0x002D,0x0015,0x000B,0x0004,0x0000, 0x0001,0xB5A6,0x0004,0x0002,0xD3CA,0xB3BB,0x0000,0xC4DF,0x0004,0x0001,0x0000,0xDBB0,0x0003,0x0000,0xB9F9,0x0000, 0xDBAF,0x000B,0x0007,0x0003,0x0001,0xB2BF,0x0002,0xD4C7,0xDBAA,0x0001,0x0001,0xDBAB,0x0006,0x0003,0x0000,0xBFA4, 0x0000,0xDBA3,0x0004,0x0002,0xBAC2,0xDBAC,0x0000,0xDBAE,0x0014,0x0008,0x0004,0x0001,0x0000,0xDBAD,0x0001,0x0000, 0xDBA9,0x0008,0x0004,0x0002,0xD6A3,0xDBA6,0x0002,0xDBA3,0xC0C9,0x0001,0x0001,0xBDBC,0x0009,0x0004,0x0001,0x0000, 0xDBA8,0x0000,0x0002,0xDBA4,0xDBA7,0x0006,0x0003,0x0000,0xD3F4,0x0001,0xDBA5,0x0001,0x0002,0xC1DA,0xDAFE,0x0063, 0x002F,0x001C,0x000E,0x0007,0x0004,0x0002,0xD7DE,0xDBA1,0x0001,0xDAFD,0x0004,0x0002,0xC9DB,0xDAFB,0x0000,0xDAFC, 0x0008,0x0004,0x0002,0xC7F1,0xDBA2,0x0002,0xBAAA,0xD3CA,0x0003,0x0001,0xDAF9,0x0001,0xD0B0,0x0009,0x0004,0x0001, 0x0001,0xB0EE,0x0001,0x0002,0xC4C7,0xD0CF,0x0004,0x0000,0x0000,0xDAFA,0x0003,0x0000,0xDAF7,0x0000,0xDAF6,0x0019, 0x000D,0x0007,0x0004,0x0002,0xDAF8,0xD3DA,0x0000,0xDAF5,0x0003,0x0000,0xE7DF,0x0000,0xB5CB,0x0007,0x0004,0x0002, 0xD2D8,0xE5CE,0x0000,0xC2DF,0x0001,0x0002,0xE5E5,0xB1DF,0x000D,0x0006,0x0003,0x0001,0xE5E3,0x0000,0xE5C7,0x0003, 0x0001,0xBBB9,0x0002,0xE5E4,0xE5E2,0x0007,0x0004,0x0002,0xC2F5,0xD1FB,0x0000,0xB1DC,0x0004,0x0002,0xE5E1,0xC1C9, 0x0001,0xD2C5,0x002D,0x0015,0x000D,0x0006,0x0003,0x0001,0xD1A1,0x0000,0xC7A8,0x0004,0x0002,0xD7F1,0xE5E0,0x0001, 0xB3D9,0x0004,0x0001,0x0001,0xD5DA,0x0000,0x0000,0xD4E2,0x000C,0x0005,0x0000,0x0002,0xCACA,0xE5DB,0x0003,0x0000, 0xD2A3,0x0002,0xC7B2,0xE5DD,0x0006,0x0003,0x0001,0xD4B6,0x0001,0xB5DD,0x0003,0x0001,0xD1B7,0x0000,0xE5DE,0x001E, 0x000F,0x0007,0x0004,0x0002,0xD2A3,0xE5DC,0x0000,0xD2C5,0x0004,0x0002,0xCEA5,0xB4EF,0x0002,0xB5C0,0xE5D9,0x0008, 0x0004,0x0002,0xE5D8,0xE5DA,0x0002,0xB6F4,0xB9FD,0x0003,0x0000,0xB1E9,0x0002,0xD4CB,0xD3CE,0x000C,0x0006,0x0003, 0x0000,0xD5EC,0x0000,0xD3F6,0x0003,0x0001,0xE5D7,0x0001,0xCBEC,0x0006,0x0003,0x0000,0xB6DD,0x0001,0xD3E2,0x0003, 0x0001,0xB1C6,0x0000,0xC2DF,0x0A97,0x0556,0x02A9,0x0185,0x00C3,0x0062,0x002B,0x0015,0x0009,0x0004,0x0001,0x0000, 0xD2DD,0x0000,0x0002,0xE5D4,0xE5D3,0x0007,0x0004,0x0002,0xBDF8,0xD6DC,0x0001,0xE5D6,0x0000,0x0002,0xB4FE,0xE5D5, 0x0007,0x0001,0x0003,0x0000,0xE5CE,0x0001,0xC1AC,0x0008,0x0004,0x0002,0xB7EA,0xE5D2,0x0002,0xD4EC,0xCBD9,0x0004, 0x0002,0xB3D1,0xCAC5,0x0001,0xB9E4,0x001D,0x000E,0x0007,0x0004,0x0002,0xCDA8,0xD5E2,0x0001,0xB6BA,0x0004,0x0002, 0xE5D1,0xE5C9,0x0000,0xCDBE,0x0008,0x0004,0x0002,0xB5DD,0xE5CF,0x0002,0xD6F0,0xCDB8,0x0003,0x0001,0xE5D0,0x0002, 0xD3C9,0xE5CD,0x000D,0x0005,0x0000,0x0002,0xD1B7,0xD1A1,0x0004,0x0002,0xC4E6,0xE5CB,0x0002,0xE5CC,0xCCD3,0x0007, 0x0004,0x0002,0xCACA,0xCBCD,0x0000,0xCDCB,0x0003,0x0001,0xD7B7,0x0001,0xD2C6,0x0034,0x0018,0x000D,0x0008,0x0004, 0x0002,0xC4CB,0xBCA3,0x0002,0xB1C5,0xC3D4,0x0001,0x0002,0xBBD8,0xE5C9,0x0004,0x0001,0x0000,0xCAF6,0x0004,0x0002, 0xE5C5,0xB5FC,0x0001,0xC6C8,0x000E,0x0007,0x0004,0x0002,0xB5CF,0xE5C7,0x0000,0xE5CA,0x0004,0x0002,0xE5C8,0xE5C4, 0x0000,0xE5C6,0x0006,0x0003,0x0000,0xCCF6,0x0001,0xB3D9,0x0004,0x0002,0xC1AC,0xCEA5,0x0002,0xD4B6,0xBDF8,0x0017, 0x000D,0x0006,0x0003,0x0001,0xD5E2,0x0000,0xBBB9,0x0003,0x0001,0xE5C3,0x0002,0xB7B5,0xE5C2,0x0006,0x0003,0x0001, 0xBDFC,0x0000,0xD4CB,0x0000,0x0000,0xD3AD,0x000C,0x0005,0x0001,0x0002,0xC2F5,0xB9FD,0x0004,0x0002,0xE5C6,0xD1B8, 0x0000,0xC6F9,0x0005,0x0000,0x0002,0xD3D8,0xC7A8,0x0000,0x0002,0xB4EF,0xC1C9,0x006B,0x002E,0x0017,0x0008,0x0004, 0x0000,0x0001,0xB1DF,0x0000,0x0000,0xE5C1,0x0008,0x0004,0x0002,0xC5A9,0xC8E8,0x0002,0xB3BD,0xB1E7,0x0004,0x0002, 0xB1E8,0xB4C7,0x0001,0xB1E8,0x000C,0x0006,0x0003,0x0001,0xB1E7,0x0000,0xB1E6,0x0003,0x0000,0xB0EC,0x0001,0xC0B1, 0x0004,0x0001,0x0001,0xB1D9,0x0003,0x0000,0xB4C7,0x0002,0xB9BC,0xD0C1,0x001E,0x0010,0x0008,0x0004,0x0002,0xEAA5, 0xD5DE,0x0002,0xEAA4,0xD5B7,0x0004,0x0002,0xCFBD,0xD4AF,0x0002,0xE0CE,0xCAE4,0x0007,0x0003,0x0001,0xBCAD,0x0002, 0xB7F8,0xEAA3,0x0004,0x0002,0xEAA2,0xEAA1,0x0001,0xE9FE,0x0010,0x0008,0x0004,0x0002,0xB9F5,0xBBD4,0x0002,0xB1B2, 0xE9FD,0x0004,0x0002,0xC1BE,0xB8A8,0x0002,0xE9FC,0xBDCF,0x0007,0x0004,0x0002,0xE9FB,0xE9FA,0x0001,0xBDCE,0x0004, 0x0002,0xE9F9,0xD4D8,0x0002,0xE9F8,0xC7E1,0x0035,0x0020,0x0010,0x0008,0x0004,0x0002,0xE9F7,0xE9F6,0x0002,0xE9F4, 0xE9F5,0x0004,0x0002,0xE9F3,0xE9F2,0x0002,0xD6E1,0xE9F1,0x0008,0x0004,0x0002,0xE9F0,0xE9EF,0x0002,0xBAE4,0xC8ED, 0x0004,0x0002,0xC2D6,0xE9EE,0x0002,0xD7AA,0xE9ED,0x000D,0x0007,0x0003,0x0001,0xD0F9,0x0002,0xB9EC,0xD4FE,0x0003, 0x0000,0xB3B5,0x0000,0xE9F1,0x0000,0x0004,0x0002,0xE9F6,0xE0CE,0x0001,0xBAE4,0x000B,0x0005,0x0001,0x0001,0x0000, 0xEAA5,0x0001,0x0000,0x0002,0xBDCE,0xD5DE,0x000B,0x0004,0x0000,0x0001,0xD7AA,0x0004,0x0002,0xEAA4,0xD4AF,0x0000, 0xCFBD,0x0006,0x0003,0x0000,0xECB1,0x0001,0xD3DF,0x0003,0x0000,0xD5B7,0x0001,0xB7F8,0x007F,0x0047,0x0022,0x000D, 0x0005,0x0000,0x0001,0x0001,0xCAE4,0x0004,0x0000,0x0000,0xEAA3,0x0000,0x0000,0xBCAD,0x000C,0x0006,0x0003,0x0001, 0xC2D6,0x0000,0xB1B2,0x0003,0x0001,0xE9FD,0x0000,0xB9F5,0x0001,0x0004,0x0002,0xEAA1,0xE9FE,0x0002,0xBBD4,0xEAA2, 0x000F,0x0009,0x0004,0x0000,0x0000,0xC1BE,0x0001,0x0002,0xC7E1,0xB8A8,0x0000,0x0000,0x0002,0xCDEC,0xE9FC,0x000C, 0x0006,0x0003,0x0001,0xE9F9,0x0000,0xD4D8,0x0003,0x0000,0xE9FA,0x0000,0xE9FB,0x0004,0x0000,0x0000,0xBDCF,0x0003, 0x0001,0xE9F8,0x0001,0xE9F3,0x001A,0x000D,0x0000,0x0008,0x0004,0x0002,0xE9F0,0xE9F7,0x0002,0xE9F2,0xD6E1,0x0000, 0x0001,0xE9EE,0x0008,0x0004,0x0000,0x0000,0xE9F4,0x0001,0x0000,0xBED0,0x0001,0x0000,0x0000,0xC8ED,0x0013,0x0008, 0x0004,0x0000,0x0000,0xE9EE,0x0001,0x0001,0xE9ED,0x0004,0x0000,0x0001,0xD0F9,0x0003,0x0001,0xEAA6,0x0002,0xBEFC, 0xB9EC,0x0006,0x0000,0x0000,0x0002,0xD4FE,0xB3B5,0x0000,0x0001,0x0001,0xC7FB,0x0051,0x0024,0x000F,0x0005,0x0000, 0x0000,0x0001,0xCCC9,0x0004,0x0000,0x0001,0xB6E3,0x0003,0x0000,0xC7FB,0x0001,0xB9AA,0x000B,0x0005,0x0000,0x0002, 0xC9ED,0xF5EF,0x0003,0x0001,0xF5F2,0x0000,0xB4DA,0x0004,0x0001,0x0000,0xF5E6,0x0003,0x0001,0xF5F3,0x0001,0xF5F2, 0x0016,0x0008,0x0004,0x0000,0x0001,0xF5D1,0x0001,0x0001,0xF5F0,0x0008,0x0004,0x0002,0xF5D9,0xF5C8,0x0002,0xF5DC, 0xF5F1,0x0003,0x0000,0xF5EF,0x0000,0xD4BE,0x000D,0x0007,0x0004,0x0002,0xF5D2,0xB3EC,0x0000,0xF5BB,0x0003,0x0000, 0xB3F9,0x0000,0xF5EE,0x0004,0x0001,0x0000,0xD4EA,0x0003,0x0000,0xB4DA,0x0001,0xF5EB,0x0029,0x0017,0x000A,0x0004, 0x0000,0x0001,0xF5CE,0x0003,0x0001,0xF5EA,0x0001,0xF5ED,0x0006,0x0003,0x0001,0xB6D7,0x0001,0xF5E9,0x0003,0x0000, 0xF5EC,0x0002,0xB2E4,0xB5C5,0x000A,0x0004,0x0001,0x0000,0xF5BF,0x0003,0x0001,0xB1C4,0x0001,0xD7D9,0x0004,0x0000, 0x0000,0xF5E7,0x0000,0x0000,0xBCA3,0x0012,0x0008,0x0004,0x0001,0x0000,0xF5BE,0x0001,0x0000,0xF5CF,0x0006,0x0003, 0x0001,0xF5E7,0x0000,0xF5E6,0x0001,0x0001,0xF5C4,0x000E,0x0008,0x0004,0x0002,0xCCA3,0xF5E8,0x0002,0xF5E3,0xB5B8, 0x0003,0x0000,0xE5BF,0x0001,0xCCE3,0x0007,0x0003,0x0001,0xF5E5,0x0002,0xF5E4,0xF5DE,0x0001,0x0000,0xF5E1,0x0152, 0x00A5,0x0046,0x002B,0x0015,0x0009,0x0005,0x0001,0x0002,0xF5DD,0xF5DF,0x0001,0x0001,0xF5E0,0x0006,0x0003,0x0000, 0xD3BB,0x0001,0xF5E2,0x0003,0x0001,0xF5DC,0x0000,0xF5DA,0x0008,0x0000,0x0003,0x0000,0xF5D9,0x0002,0xD7D9,0xB2C8, 0x0007,0x0003,0x0001,0xF5DB,0x0002,0xCCDF,0xF2E9,0x0003,0x0001,0xF5D8,0x0002,0xBEE1,0xF5D7,0x000A,0x0001,0x0004, 0x0000,0x0000,0xF5D6,0x0000,0x0002,0xBCF9,0xCCA4,0x000C,0x0007,0x0003,0x0000,0xB3EC,0x0002,0xD3BB,0xF5D4,0x0001, 0x0002,0xB6D7,0xF5BD,0x0001,0x0001,0x0001,0xF5D5,0x0032,0x0018,0x000F,0x0008,0x0004,0x0002,0xBED6,0xF5D2,0x0002, 0xB6E5,0xF5D1,0x0004,0x0002,0xF5CF,0xF5CE,0x0001,0xBCF9,0x0005,0x0000,0x0002,0xB2C8,0xCCF8,0x0000,0x0001,0xC2B7, 0x000B,0x0007,0x0004,0x0002,0xF5CD,0xF5BC,0x0000,0xB9F2,0x0000,0x0000,0xBFE7,0x0008,0x0004,0x0002,0xF5D3,0xF5D0, 0x0002,0xF5DC,0xBCA3,0x0003,0x0001,0xB8FA,0x0002,0xF5C8,0xBEE0,0x0017,0x000C,0x0006,0x0003,0x0001,0xF5CB,0x0000, 0xF5C7,0x0003,0x0001,0xF5C6,0x0000,0xF5C5,0x0004,0x0001,0x0001,0xC5DC,0x0004,0x0002,0xB2C8,0xF5CA,0x0000,0xF5C9, 0x0009,0x0005,0x0000,0x0002,0xB5F8,0xB0CF,0x0001,0x0000,0xF5CC,0x0007,0x0004,0x0002,0xF5C4,0xD4BE,0x0000,0xC6E7, 0x0003,0x0001,0xF5C1,0x0000,0xD6BA,0x0045,0x0022,0x0015,0x000C,0x0006,0x0003,0x0000,0xF5C2,0x0000,0xF5C3,0x0003, 0x0000,0xF5BB,0x0001,0xF5C0,0x0000,0x0004,0x0002,0xC5BF,0xD7E3,0x0002,0xF4F5,0xF4F5,0x0005,0x0001,0x0000,0x0000, 0xC7F7,0x0004,0x0000,0x0001,0xC8A4,0x0000,0x0001,0xCCCB,0x0012,0x0008,0x0004,0x0001,0x0001,0xD5D4,0x0001,0x0001, 0xB8CF,0x0006,0x0003,0x0000,0xF4F3,0x0001,0xF4F4,0x0001,0x0001,0xC7F7,0x000A,0x0006,0x0003,0x0001,0xC7F7,0x0000, 0xD4BD,0x0001,0x0001,0xB3AC,0x0000,0x0003,0x0000,0xF4F2,0x0001,0xB3C3,0x002C,0x0013,0x0008,0x0001,0x0003,0x0001, 0xC6F0,0x0002,0xB8CF,0xD5D4,0x0005,0x0000,0x0002,0xB8B0,0xF4F1,0x0003,0x0000,0xD7DF,0x0001,0xF4F7,0x000A,0x0004, 0x0000,0x0001,0xBAD5,0x0003,0x0001,0xF4F6,0x0000,0xC9E2,0x0008,0x0004,0x0002,0xB3E0,0xB8D3,0x0002,0xD3AE,0xC9C4, 0x0003,0x0000,0xD4F9,0x0002,0xD4DE,0xD8CD,0x001C,0x000F,0x0008,0x0004,0x0002,0xD8D3,0xC8FC,0x0002,0xD7AC,0xEAE7, 0x0003,0x0000,0xD7B8,0x0002,0xC0B5,0xEAE6,0x0005,0x0000,0x0002,0xC5E2,0xE2D9,0x0004,0x0002,0xB4CD,0xC9CD,0x0002, 0xCAEA,0xEAE5,0x0010,0x0008,0x0004,0x0002,0xB6C4,0xB8B3,0x0002,0xC9DE,0xEAE3,0x0004,0x0002,0xEAE2,0xEAE4,0x0002, 0xEAE1,0xEAE0,0x0008,0x0004,0x0002,0xD7CA,0xD4DF,0x0002,0xC2B8,0xC1DE,0x0004,0x0002,0xEADF,0xBBDF,0x0002,0xBCD6, 0xEADE,0x00C2,0x0067,0x003F,0x0020,0x0010,0x0008,0x0004,0x0002,0xD4F4,0xEADD,0x0002,0xBAD8,0xB7D1,0x0004,0x0002, 0xC3B3,0xB4FB,0x0002,0xEADC,0xB9F3,0x0008,0x0004,0x0002,0xCCF9,0xEADB,0x0002,0xEADA,0xBCFA,0x0004,0x0002,0xB7A1, 0xB9E1,0x0002,0xD6FC,0xB9BA,0x0010,0x0008,0x0004,0x0002,0xB1E1,0xC6B6,0x0002,0xCCB0,0xB7B7,0x0004,0x0002,0xD6CA, 0xBBF5,0x0002,0xD5CB,0xB0DC,0x0008,0x0004,0x0002,0xCFCD,0xD4F0,0x0002,0xB2C6,0xB9B1,0x0003,0x0001,0xB8BA,0x0002, 0xD5EA,0xB1B4,0x0015,0x000A,0x0004,0x0000,0x0001,0xB8D3,0x0003,0x0001,0xD8CD,0x0000,0xCAEA,0x0004,0x0000,0x0001, 0xD4DF,0x0004,0x0002,0xEAE1,0xD3AE,0x0001,0xC9C4,0x000A,0x0004,0x0001,0x0000,0xD4DE,0x0003,0x0000,0xD4F9,0x0001, 0xD7B8,0x0004,0x0000,0x0000,0xEADE,0x0001,0x0002,0xD8D3,0xC8FC,0x002D,0x0013,0x000B,0x0007,0x0004,0x0002,0xB9BA, 0xEAE7,0x0000,0xD7AC,0x0000,0x0000,0xCAA3,0x0004,0x0000,0x0000,0xC0B5,0x0001,0x0001,0xB6C4,0x000C,0x0006,0x0003, 0x0000,0xD5CB,0x0000,0xD6CA,0x0003,0x0001,0xEAE6,0x0000,0xB8B3,0x0008,0x0004,0x0002,0xBCFA,0xC2F4,0x0002,0xCFCD, 0xE2D9,0x0003,0x0000,0xC5E2,0x0000,0xC9CD,0x0012,0x000A,0x0006,0x0003,0x0000,0xB4CD,0x0001,0xD6DC,0x0001,0x0001, 0xEAE4,0x0000,0x0003,0x0001,0xB1F6,0x0002,0xC9DE,0xEAE2,0x000D,0x0006,0x0003,0x0000,0xEAE0,0x0000,0xD4F4,0x0004, 0x0002,0xBCD6,0xD7CA,0x0001,0xEAE0,0x0008,0x0004,0x0002,0xBBDF,0xC1DE,0x0002,0xC2B8,0xEADA,0x0004,0x0002,0xBAD8, 0xC3B3,0x0001,0xEADD,0x0052,0x0036,0x001A,0x000E,0x0007,0x0004,0x0002,0xCCF9,0xB7D1,0x0000,0xEADC,0x0004,0x0002, 0xB4FB,0xC2F2,0x0000,0xB1E1,0x0007,0x0004,0x0002,0xB9F3,0xB7A1,0x0000,0xEADF,0x0000,0x0002,0xEADB,0xD6FC,0x000D, 0x0008,0x0004,0x0002,0xD4F0,0xB9E1,0x0002,0xCCB0,0xB7B7,0x0000,0x0002,0xBBF5,0xC6B6,0x0008,0x0004,0x0002,0xD2C6, 0xDFAF,0x0002,0xB9B1,0xB2C6,0x0003,0x0000,0xB8BA,0x0002,0xD5EA,0xB1B4,0x000B,0x0005,0x0001,0x0000,0x0000,0xF5F8, 0x0000,0x0000,0x0002,0xF5F9,0xC3A8,0x000C,0x0007,0x0003,0x0000,0xC3B2,0x0002,0xF5F6,0xBAD1,0x0001,0x0002,0xE2B5, 0xF5F7,0x0000,0x0001,0x0000,0xF5F5,0x001E,0x000E,0x0009,0x0005,0x0001,0x0002,0xB2F2,0xB1AA,0x0000,0x0000,0xF5F4, 0x0000,0x0000,0x0001,0xE1D9,0x0008,0x0000,0x0004,0x0002,0xD6ED,0xD4A5,0x0000,0xBAC0,0x0000,0x0003,0x0000,0xBFD0, 0x0002,0xBBBF,0xCFF3,0x0012,0x0008,0x0004,0x0001,0x0000,0xEBE0,0x0001,0x0001,0xF5B9,0x0004,0x0000,0x0000,0xD1DE, 0x0003,0x0000,0xB7E1,0x0000,0xCAFA,0x000F,0x0008,0x0004,0x0002,0xCDE3,0xB5C7,0x0002,0xB7E1,0xF4F9,0x0004,0x0002, 0xC6F1,0xF4F8,0x0000,0xB6B9,0x0004,0x0001,0x0001,0xBBED,0x0000,0x0001,0xCFAA,0x02DD,0x018F,0x00F1,0x0074,0x0035, 0x0016,0x0006,0x0001,0x0001,0x0002,0xB9C8,0xDADF,0x0008,0x0004,0x0002,0xDADE,0xC7B4,0x0002,0xDADD,0xDADC,0x0004, 0x0002,0xC6D7,0xC0BE,0x0002,0xDADB,0xDADA,0x0010,0x0008,0x0004,0x0002,0xCCB7,0xC3FD,0x0002,0xDAD9,0xDAD8,0x0004, 0x0002,0xC3A1,0xBDF7,0x0002,0xDAD7,0xC7AB,0x0008,0x0004,0x0002,0xDAD6,0xB0F9,0x0002,0xD2A5,0xD0BB,0x0004,0x0002, 0xDAD5,0xDAD4,0x0000,0xDAD3,0x0020,0x0010,0x0008,0x0004,0x0002,0xDAD2,0xC3D5,0x0002,0xDAD0,0xD1E8,0x0004,0x0002, 0xDACF,0xDAD1,0x0002,0xB2F7,0xDACE,0x0008,0x0004,0x0002,0xDACD,0xDACC,0x0002,0xCEBD,0xDACB,0x0004,0x0002,0xDACA, 0xD0B3,0x0002,0xDAC9,0xBBD1,0x000F,0x0008,0x0004,0x0002,0xB5FD,0xDAC8,0x0002,0xC4B1,0xD2EA,0x0003,0x0001,0xCCB8, 0x0002,0xDAC7,0xD7BB,0x0008,0x0004,0x0002,0xC1C2,0xDAC6,0x0002,0xB5F7,0xDAC5,0x0004,0x0002,0xCBAD,0xDAC4,0x0002, 0xDAC3,0xBFCE,0x003F,0x0020,0x0010,0x0008,0x0004,0x0002,0xB7CC,0xDAC2,0x0002,0xB6C1,0xC5B5,0x0004,0x0002,0xDAC1, 0xD6EE,0x0002,0xC7EB,0xDAC0,0x0008,0x0004,0x0002,0xCBD0,0xCBB5,0x0002,0xDABF,0xBBE5,0x0004,0x0002,0xD3D5,0xDABE, 0x0002,0xCEF3,0xDABD,0x000F,0x0007,0x0004,0x0002,0xD3EF,0xCEDC,0x0000,0xBDEB,0x0004,0x0002,0xDABC,0xDABB,0x0002, 0xB2EF,0xCFEA,0x0008,0x0004,0x0002,0xB8C3,0xDABA,0x0002,0xD2E8,0xD1AF,0x0004,0x0002,0xB9EE,0xDAB9,0x0002,0xDAB8, 0xB5AE,0x001F,0x0010,0x0008,0x0004,0x0002,0xBBB0,0xDAB7,0x0002,0xD6EF,0xB3CF,0x0004,0x0002,0xDAB6,0xDAB5,0x0002, 0xCAAB,0xDAB4,0x0008,0x0004,0x0002,0xCAD4,0xDAB3,0x0002,0xDAB2,0xDAB1,0x0003,0x0000,0xD2EB,0x0002,0xDAAF,0xDAB0, 0x000F,0x0008,0x0004,0x0002,0xB4CA,0xD6DF,0x0002,0xDAAE,0xD5EF,0x0004,0x0002,0xCBDF,0xD5A9,0x0001,0xCAB6,0x0008, 0x0004,0x0002,0xD7E7,0xC6C0,0x0002,0xDAAD,0xDAAC,0x0004,0x0002,0xD6A4,0xBEF7,0x0002,0xB7C3,0xC9E8,0x005B,0x003C, 0x001E,0x000F,0x0007,0x0004,0x0002,0xB7ED,0xCBCF,0x0001,0xC2DB,0x0004,0x0002,0xB6EF,0xD0ED,0x0002,0xDAAB,0xD1C8, 0x0008,0x0004,0x0002,0xDAAA,0xDAA9,0x0002,0xBBE4,0xBDB2,0x0003,0x0001,0xBCC7,0x0002,0xD1B6,0xD2E9,0x000F,0x0007, 0x0003,0x0000,0xD1B5,0x0002,0xC6FD,0xDAA8,0x0004,0x0002,0xC8C3,0xCCD6,0x0002,0xDAA7,0xDAA6,0x0008,0x0004,0x0002, 0xBCA5,0xC8CF,0x0002,0xB8BC,0xB6A9,0x0004,0x0002,0xBCC6,0xDAA5,0x0001,0xDADD,0x0015,0x000A,0x0006,0x0003,0x0001, 0xDAD4,0x0001,0xD4DE,0x0001,0x0001,0xDADF,0x0007,0x0003,0x0000,0xC0BE,0x0002,0xC8C3,0xB2F7,0x0001,0x0001,0xF6C5, 0x0005,0x0000,0x0001,0x0001,0xB1E4,0x0001,0x0000,0x0001,0xB6C1,0x0022,0x0012,0x0008,0x0004,0x0000,0x0000,0xD3FE, 0x0001,0x0000,0xBBA4,0x0004,0x0000,0x0001,0xC7B4,0x0003,0x0001,0xD2E9,0x0000,0xD2EB,0x000B,0x0007,0x0004,0x0002, 0xBBD9,0xC6A9,0x0000,0xDADE,0x0001,0x0001,0xBEAF,0x0001,0x0001,0x0000,0xD4EB,0x0013,0x000D,0x0006,0x0003,0x0001, 0xC6D7,0x0001,0xCCB7,0x0004,0x0002,0xDADB,0xCAB6,0x0001,0xDADA,0x0001,0x0001,0x0002,0xBCA5,0xDADC,0x0007,0x0001, 0x0003,0x0000,0xD6A4,0x0001,0xCEFB,0x0001,0x0003,0x0000,0xBBA9,0x0001,0xC3A1,0x009F,0x0047,0x001B,0x000A,0x0005, 0x0001,0x0000,0x0001,0xBDF7,0x0000,0x0001,0x0001,0xDAA9,0x0009,0x0005,0x0001,0x0002,0xC3FD,0xDAD8,0x0001,0x0000, 0xDAD3,0x0004,0x0000,0x0000,0xF6A5,0x0001,0x0000,0xD2A5,0x0015,0x000D,0x0006,0x0003,0x0001,0xD0BB,0x0001,0xBDB2, 0x0004,0x0002,0xDAD6,0xC7AB,0x0001,0xB0F9,0x0004,0x0001,0x0000,0xDACA,0x0001,0x0000,0xDAD7,0x000A,0x0004,0x0000, 0x0000,0xC3D5,0x0003,0x0000,0xBBD1,0x0001,0xE5C0,0x0006,0x0003,0x0001,0xD6DF,0x0000,0xCCDC,0x0004,0x0002,0xCEBD, 0xDACB,0x0000,0xC4B1,0x002C,0x0017,0x000D,0x0006,0x0003,0x0000,0xC5B5,0x0000,0xDACE,0x0003,0x0000,0xD1E8,0x0002, 0xD6EE,0xB7ED,0x0006,0x0003,0x0000,0xDAC8,0x0001,0xDACF,0x0000,0x0001,0xBBE4,0x000B,0x0007,0x0004,0x0002,0xDAD1, 0xDACD,0x0001,0xDAC9,0x0001,0x0001,0xD0B3,0x0006,0x0003,0x0000,0xDAD0,0x0000,0xDACC,0x0000,0x0000,0xDABB,0x0016, 0x000B,0x0007,0x0003,0x0000,0xDAD2,0x0002,0xB5FD,0xDAC4,0x0001,0x0001,0xDAC5,0x0004,0x0000,0x0000,0xC2DB,0x0004, 0x0002,0xC1C2,0xDAC2,0x0001,0xDAC1,0x000C,0x0006,0x0003,0x0001,0xDABA,0x0001,0xC7EB,0x0003,0x0001,0xDAC3,0x0001, 0xCCB8,0x0004,0x0001,0x0000,0xD7BB,0x0003,0x0000,0xDAC6,0x0001,0xB5F7,0x0058,0x0027,0x0012,0x0008,0x0004,0x0001, 0x0000,0xD2EA,0x0000,0x0001,0xB7CC,0x0004,0x0000,0x0000,0xDAC7,0x0003,0x0000,0xBFCE,0x0000,0xCBAD,0x0007,0x0001, 0x0003,0x0000,0xCBB5,0x0000,0xBBE5,0x0008,0x0004,0x0002,0xCBD0,0xDABE,0x0002,0xCEF3,0xCEDC,0x0003,0x0001,0xBDEB, 0x0000,0xB3CF,0x0016,0x000A,0x0004,0x0000,0x0000,0xD3EF,0x0003,0x0000,0xDABD,0x0000,0xD3D5,0x0007,0x0004,0x0002, 0xE3A3,0xB5AE,0x0001,0xCAC4,0x0000,0x0002,0xDAC0,0xDABF,0x000D,0x0006,0x0003,0x0001,0xC8CF,0x0000,0xD6BE,0x0004, 0x0002,0xCCDC,0xD3FE,0x0001,0xBFE4,0x0008,0x0004,0x0002,0xDAB2,0xD6EF,0x0002,0xDAB3,0xB6DF,0x0003,0x0000,0xD9AC, 0x0001,0xDAB4,0x002F,0x0016,0x0008,0x0004,0x0001,0x0000,0xDAB6,0x0000,0x0001,0xD5B2,0x0007,0x0004,0x0002,0xB3EA, 0xDAB7,0x0001,0xCFEA,0x0004,0x0002,0xB8C3,0xBBB0,0x0000,0xDAB5,0x000C,0x0008,0x0004,0x0002,0xDAB9,0xB9EE,0x0002, 0xDAB8,0xB2EF,0x0000,0x0001,0xCAAB,0x0006,0x0003,0x0000,0xCAD4,0x0001,0xD2E8,0x0004,0x0002,0xD1AF,0xDABC,0x0000, 0xD3BD,0x0016,0x000A,0x0006,0x0003,0x0000,0xB4CA,0x0001,0xD7E7,0x0001,0x0000,0xDAB0,0x0006,0x0003,0x0001,0xC6C0, 0x0000,0xDAAF,0x0003,0x0000,0xDAB1,0x0000,0xD5A9,0x0008,0x0004,0x0000,0x0000,0xDAAA,0x0001,0x0000,0xEEBA,0x0004, 0x0000,0x0000,0xDAAE,0x0003,0x0001,0xDAAC,0x0001,0xF6A4,0x0133,0x00AF,0x0058,0x0028,0x0014,0x000A,0x0005,0x0002, 0xF6A4,0x0001,0xD6A4,0x0000,0x0002,0xD7A2,0xD5EF,0x0006,0x0003,0x0001,0xDAAD,0x0001,0xCBDF,0x0001,0x0000,0xD0ED, 0x0009,0x0005,0x0001,0x0002,0xC9E8,0xB3B3,0x0000,0x0001,0xB7C3,0x0006,0x0003,0x0000,0xD3C8,0x0000,0xDAAB,0x0000, 0x0002,0xBEF7,0xD0C0,0x0019,0x000C,0x0006,0x0003,0x0000,0xCBCF,0x0000,0xD1C8,0x0003,0x0000,0xB6EF,0x0001,0xBCC7, 0x0007,0x0004,0x0002,0xCDD0,0xC6FD,0x0000,0xDAA8,0x0003,0x0000,0xD1B5,0x0001,0xDAA6,0x000C,0x0006,0x0003,0x0001, 0xCCD6,0x0001,0xDAA7,0x0003,0x0001,0xD1B6,0x0001,0xBCC6,0x0004,0x0000,0x0000,0xD9EA,0x0004,0x0002,0xB8BC,0xB6A9, 0x0001,0xD1D4,0x001F,0x000D,0x0005,0x0001,0x0001,0x0001,0xB4A5,0x0004,0x0001,0x0001,0xF5FC,0x0000,0x0000,0xECB2, 0x0008,0x0004,0x0000,0x0000,0xF6A3,0x0000,0x0000,0xF6A2,0x0006,0x0003,0x0001,0xB4A5,0x0000,0xF6A1,0x0000,0x0000, 0xBDE2,0x001A,0x000C,0x0008,0x0004,0x0002,0xE2B3,0xF5FC,0x0002,0xB5D6,0xF5FE,0x0000,0x0001,0xF5FD,0x0007,0x0003, 0x0001,0xF5FB,0x0002,0xB4D6,0xBDEF,0x0003,0x0001,0xBDC7,0x0002,0xEAEF,0xEAEE,0x000F,0x0007,0x0004,0x0002,0xEAED, 0xEAEC,0x0001,0xEAEB,0x0004,0x0002,0xEAEA,0xEAE9,0x0002,0xBEF5,0xC0C0,0x0008,0x0004,0x0002,0xEAE8,0xCAD3,0x0002, 0xC3D9,0xB9E6,0x0003,0x0001,0xB9DB,0x0002,0xBCFB,0xB9DB,0x0049,0x0024,0x0012,0x000A,0x0006,0x0003,0x0000,0xEAEB, 0x0000,0xC0C0,0x0000,0x0001,0xBEF5,0x0004,0x0000,0x0000,0xEAEF,0x0000,0x0001,0xEAEE,0x000A,0x0006,0x0003,0x0000, 0xEAED,0x0001,0xEAE9,0x0000,0x0001,0xC7D7,0x0004,0x0000,0x0001,0xEAEC,0x0001,0x0000,0xEAEA,0x0012,0x0007,0x0001, 0x0003,0x0000,0xC3D9,0x0001,0xEAE8,0x0007,0x0004,0x0002,0xCBC5,0xCAD3,0x0000,0xC6B3,0x0000,0x0000,0xC3D9,0x0008, 0x0004,0x0000,0x0000,0xB9E6,0x0000,0x0000,0xBCFB,0x0004,0x0000,0x0001,0xB8B2,0x0004,0x0002,0xF1FB,0xB7A6,0x0000, 0xD2AA,0x0021,0x000D,0x0008,0x0004,0x0000,0x0000,0xCEF7,0x0000,0x0000,0xF1E1,0x0001,0x0000,0x0001,0xCFAE,0x000A, 0x0006,0x0003,0x0000,0xB3C4,0x0001,0xB0DA,0x0000,0x0001,0xCDE0,0x0006,0x0003,0x0001,0xF1E0,0x0001,0xF1DC,0x0001, 0x0001,0xF1C9,0x000D,0x0008,0x0000,0x0004,0x0002,0xBDF3,0xF4C5,0x0000,0xF1CF,0x0000,0x0000,0x0001,0xB0C0,0x0005, 0x0001,0x0001,0x0000,0xF1D0,0x0004,0x0001,0x0001,0xCFE5,0x0001,0x0000,0xF1DF,0x0095,0x003F,0x0022,0x0014,0x0007, 0x0001,0x0003,0x0000,0xD9F4,0x0001,0xF1DA,0x0006,0x0003,0x0001,0xF1DE,0x0001,0xF1DC,0x0004,0x0002,0xF1CD,0xBFE3, 0x0001,0xE5BD,0x0006,0x0001,0x0000,0x0002,0xF1DD,0xCDCA,0x0004,0x0001,0x0000,0xC8EC,0x0001,0x0000,0xF1D7,0x0010, 0x0008,0x0001,0x0004,0x0002,0xF1DA,0xF1D2,0x0000,0xF1D8,0x0001,0x0004,0x0002,0xF1D9,0xB0FD,0x0001,0xBAD6,0x0005, 0x0001,0x0000,0x0001,0xF1DB,0x0004,0x0000,0x0000,0xB8B4,0x0000,0x0001,0xB9D3,0x002A,0x0019,0x000C,0x0007,0x0003, 0x0001,0xF1D5,0x0002,0xD6C6,0xF1D3,0x0001,0x0002,0xB9FC,0xC2E3,0x0006,0x0003,0x0000,0xD9F2,0x0001,0xC5E1,0x0003, 0x0000,0xC9D1,0x0002,0xF1D1,0xF1D6,0x0005,0x0001,0x0001,0x0001,0xF1D4,0x0005,0x0001,0x0002,0xF1D0,0xBFE3,0x0004, 0x0002,0xF1CF,0xF1CD,0x0000,0xC0EF,0x0015,0x000C,0x0007,0x0003,0x0000,0xF4C4,0x0002,0xD7B0,0xB2B9,0x0001,0x0002, 0xC8B9,0xF4C3,0x0005,0x0001,0x0002,0xD4A3,0xD2E1,0x0000,0x0001,0xD9F6,0x000A,0x0004,0x0000,0x0001,0xF1CE,0x0003, 0x0001,0xF4C1,0x0000,0xF1CC,0x0006,0x0003,0x0001,0xF1C9,0x0000,0xD7B0,0x0003,0x0001,0xC1D1,0x0002,0xB2C3,0xD2F0, 0x0043,0x001D,0x000D,0x0005,0x0000,0x0001,0x0001,0xF1CB,0x0004,0x0000,0x0000,0xF1CA,0x0001,0x0000,0xB8A4,0x0008, 0x0004,0x0001,0x0000,0xCFAE,0x0000,0x0000,0xB1BB,0x0004,0x0001,0x0001,0xD9F3,0x0000,0x0001,0xF1C8,0x0011,0x0008, 0x0000,0x0004,0x0002,0xE0F9,0xD9F2,0x0001,0xCDE0,0x0005,0x0000,0x0002,0xD5E4,0xD0E4,0x0000,0x0001,0xCCBB,0x000A, 0x0004,0x0001,0x0000,0xC5DB,0x0003,0x0000,0xB4FC,0x0001,0xF4C2,0x0005,0x0001,0x0002,0xF4C1,0xB0C0,0x0003,0x0001, 0xF1C7,0x0000,0xD4AC,0x002F,0x0016,0x000B,0x0007,0x0004,0x0002,0xF1C6,0xF4C0,0x0000,0xF1C5,0x0001,0x0000,0xD6BB, 0x0005,0x0000,0x0002,0xD6D4,0xB3E5,0x0003,0x0001,0xF1C4,0x0001,0xCBA5,0x000D,0x0006,0x0003,0x0001,0xD9F2,0x0001, 0xB3C4,0x0003,0x0000,0xC9C0,0x0002,0xF1C3,0xB1ED,0x0005,0x0001,0x0002,0xB2B9,0xF1C2,0x0004,0x0002,0xD2C2,0xE1E9, 0x0000,0xBAE2,0x0016,0x000A,0x0004,0x0001,0x0000,0xB3E5,0x0003,0x0000,0xCEC0,0x0000,0xD1C3,0x0008,0x0004,0x0002, 0xBDD6,0xC5AA,0x0002,0xCDAC,0xCFCE,0x0000,0x0000,0xCAF5,0x000B,0x0007,0x0003,0x0001,0xD9A9,0x0002,0xD1DC,0xD0D0, 0x0000,0x0001,0xC3EF,0x0005,0x0001,0x0002,0xD0C6,0xF4AC,0x0001,0x0001,0xD1AA,0x04AA,0x0272,0x0121,0x0088,0x0041, 0x001A,0x0011,0x0008,0x0001,0x0004,0x0002,0xF3BD,0xC2F9,0x0001,0xF3BC,0x0004,0x0001,0x0000,0xB2CF,0x0001,0x0002, 0xEEC3,0xB9C6,0x0001,0x0001,0x0003,0x0001,0xF2C3,0x0002,0xB4C0,0xF3BB,0x0014,0x0008,0x0004,0x0000,0x0001,0xC0AF, 0x0000,0x0001,0xF3BA,0x0005,0x0001,0x0002,0xF3B6,0xC8E4,0x0004,0x0002,0xF2BA,0xF3B7,0x0001,0xF2EE,0x000A,0x0006, 0x0003,0x0000,0xF2D3,0x0001,0xD0AB,0x0001,0x0000,0xF3B9,0x0005,0x0001,0x0002,0xF2B2,0xD3AC,0x0000,0x0001,0xD9F9, 0x0026,0x0012,0x000A,0x0004,0x0001,0x0000,0xF3B8,0x0003,0x0001,0xD2CF,0x0001,0xD0B7,0x0004,0x0001,0x0000,0xF2C9, 0x0001,0x0000,0xB3E6,0x000C,0x0006,0x0003,0x0001,0xF2CD,0x0000,0xF3B5,0x0003,0x0000,0xB2F5,0x0000,0xF3B3,0x0004, 0x0001,0x0001,0xF3A8,0x0000,0x0001,0xF2B1,0x0010,0x0008,0x0004,0x0000,0x0000,0xF3B4,0x0000,0x0001,0xF3B2,0x0001, 0x0003,0x0001,0xF3AD,0x0002,0xF2FE,0xF3AF,0x0007,0x0001,0x0003,0x0001,0xF3AC,0x0000,0xF3B1,0x0006,0x0003,0x0000, 0xF2E5,0x0000,0xF3A1,0x0000,0x0000,0xD5DD,0x004B,0x0027,0x0014,0x000C,0x0006,0x0003,0x0000,0xF3B0,0x0001,0xF3AE, 0x0003,0x0001,0xF2F7,0x0000,0xC2DD,0x0004,0x0001,0x0001,0xF3AA,0x0000,0x0001,0xF3AB,0x000B,0x0006,0x0003,0x0001, 0xF2FC,0x0001,0xF3A4,0x0000,0x0002,0xF3A9,0xF3A7,0x0004,0x0000,0x0000,0xF2FD,0x0001,0x0000,0xD3A9,0x000F,0x0007, 0x0000,0x0003,0x0001,0xC3F8,0x0000,0xC2EC,0x0004,0x0000,0x0001,0xF3A5,0x0000,0x0001,0xF2FB,0x0008,0x0004,0x0001, 0x0001,0xC8DA,0x0000,0x0001,0xF2F4,0x0006,0x0003,0x0000,0xF3A2,0x0001,0xF3A3,0x0004,0x0002,0xF2CF,0xF3A6,0x0000, 0xF2EB,0x0027,0x0014,0x000A,0x0005,0x0001,0x0002,0xF2EE,0xF2ED,0x0000,0x0002,0xF2F7,0xF2EF,0x0006,0x0003,0x0000, 0xCECF,0x0000,0xB5FB,0x0000,0x0000,0xBAFB,0x0007,0x0000,0x0003,0x0000,0xF2F1,0x0000,0xF2F3,0x0007,0x0003,0x0000, 0xCAAD,0x0002,0xCFBA,0xF2FA,0x0000,0x0002,0xF2F8,0xF2F6,0x0012,0x0008,0x0004,0x0000,0x0000,0xF2F0,0x0001,0x0001, 0xF2F9,0x0006,0x0003,0x0001,0xBBC8,0x0001,0xCAB4,0x0000,0x0001,0xF2F5,0x000A,0x0004,0x0001,0x0000,0xD0AB,0x0003, 0x0000,0xF2F2,0x0001,0xB2F5,0x0007,0x0004,0x0002,0xF2E5,0xD3AC,0x0000,0xF2D5,0x0000,0x0001,0xBAE7,0x00AE,0x0059, 0x0026,0x0012,0x000A,0x0005,0x0001,0x0002,0xF2EA,0xF2E4,0x0001,0x0002,0xF2DF,0xC4DE,0x0004,0x0001,0x0000,0xF2E9, 0x0000,0x0001,0xF2E6,0x0007,0x0000,0x0003,0x0000,0xF2E7,0x0001,0xF2E2,0x0005,0x0000,0x0002,0xF2E8,0xB5FB,0x0004, 0x0002,0xF2E1,0xF2E1,0x0002,0xF2DE,0xF2EC,0x0019,0x000C,0x0006,0x0003,0x0000,0xC0AF,0x0001,0xF2E0,0x0003,0x0001, 0xC3DB,0x0001,0xF2E3,0x0006,0x0003,0x0001,0xD6A9,0x0000,0xCECF,0x0003,0x0000,0xCDC9,0x0002,0xF2D1,0xD1D1,0x000B, 0x0004,0x0000,0x0000,0xD1D1,0x0003,0x0000,0xF2DC,0x0002,0xF2EB,0xF2DB,0x0008,0x0004,0x0002,0xF2DD,0xF2DA,0x0002, 0xF2D8,0xF2B9,0x0003,0x0001,0xF2D7,0x0002,0xF2D7,0xB7E4,0x002B,0x0017,0x000B,0x0006,0x0003,0x0001,0xCAF1,0x0001, 0xB6EA,0x0001,0x0002,0xCDC9,0xF2CC,0x0005,0x0000,0x0002,0xD3BC,0xF2D9,0x0003,0x0001,0xF2D3,0x0002,0xF2CF,0xF2CD, 0x000C,0x0007,0x0004,0x0002,0xF2CC,0xD5DD,0x0001,0xC2F9,0x0000,0x0002,0xF2CE,0xF2CB,0x0004,0x0000,0x0000,0xF2CB, 0x0000,0x0001,0xB8F2,0x0012,0x0009,0x0005,0x0001,0x0002,0xF2D4,0xF2D2,0x0001,0x0000,0xD6EB,0x0005,0x0000,0x0002, 0xCDDC,0xF2D5,0x0000,0x0001,0xBBD7,0x000D,0x0008,0x0004,0x0002,0xF2D6,0xF2D0,0x0002,0xF2C9,0xF2C3,0x0001,0x0002, 0xB5B0,0xB9C6,0x0007,0x0003,0x0000,0xF2C8,0x0002,0xC9DF,0xC7F9,0x0000,0x0001,0xF2C1,0x0050,0x002D,0x0013,0x000A, 0x0004,0x0000,0x0001,0xD6FB,0x0003,0x0001,0xBED4,0x0001,0xF2C5,0x0004,0x0001,0x0001,0xF2C0,0x0000,0x0002,0xF2C2, 0xF2CA,0x000D,0x0007,0x0004,0x0002,0xF2C6,0xF2C4,0x0000,0xF2C7,0x0003,0x0001,0xF2B9,0x0001,0xF2BD,0x0007,0x0004, 0x0002,0xF2BF,0xF2B6,0x0000,0xF2BB,0x0003,0x0001,0xD4E9,0x0000,0xF2BC,0x0015,0x0009,0x0004,0x0000,0x0000,0xF7F7, 0x0000,0x0002,0xF2BA,0xD1C1,0x0006,0x0003,0x0001,0xBBD7,0x0001,0xF2B3,0x0003,0x0000,0xB2CF,0x0000,0xF2BE,0x0009, 0x0001,0x0004,0x0002,0xF2B7,0xB0F6,0x0002,0xF2B8,0xCEC3,0x0001,0x0001,0x0001,0xC2EC,0x002F,0x001A,0x0010,0x0008, 0x0004,0x0002,0xD2CF,0xCAB4,0x0002,0xF2B2,0xCFBA,0x0004,0x0002,0xCBE4,0xF2B4,0x0002,0xF2B5,0xF2B3,0x0006,0x0003, 0x0000,0xBAE7,0x0000,0xB8C9,0x0000,0x0001,0xF2C6,0x000D,0x0007,0x0003,0x0000,0xCAAD,0x0002,0xF2B0,0xF2B1,0x0003, 0x0001,0xF2B0,0x0000,0xB3E6,0x0004,0x0001,0x0000,0xBFF7,0x0001,0x0001,0xEBBD,0x0017,0x000C,0x0005,0x0001,0x0002, 0xBAC5,0xD3DD,0x0003,0x0001,0xC2B2,0x0002,0xD0E9,0xD0E9,0x0006,0x0003,0x0000,0xB7FC,0x0001,0xBAF5,0x0000,0x0002, 0xB4A6,0xF2AF,0x0000,0x0008,0x0004,0x0002,0xC2C7,0xC5B0,0x0002,0xC2B2,0xBBA2,0x0000,0x0000,0xF2AE,0x0112,0x007E, 0x0042,0x001B,0x000F,0x0008,0x0004,0x0001,0x0001,0xC2DC,0x0001,0x0000,0xDEC2,0x0000,0x0003,0x0000,0xDDF1,0x0000, 0xD5BA,0x0005,0x0001,0x0000,0x0001,0xC0BC,0x0000,0x0003,0x0001,0xDEC0,0x0001,0xDEBE,0x0012,0x0008,0x0004,0x0000, 0x0000,0xDCD7,0x0000,0x0000,0xDDFC,0x0006,0x0003,0x0000,0xDEBA,0x0001,0xE9DE,0x0000,0x0000,0xDEC1,0x0008,0x0004, 0x0000,0x0001,0xC4A2,0x0001,0x0001,0xC6BB,0x0006,0x0003,0x0000,0xD4CC,0x0001,0xCBD5,0x0004,0x0002,0xC2AB,0xDEBF, 0x0000,0xDEAD,0x001F,0x0013,0x0008,0x0004,0x0001,0x0001,0xDEBD,0x0001,0x0001,0xD4E5,0x0007,0x0004,0x0002,0xDDFE, 0xB0AA,0x0001,0xCAED,0x0000,0x0000,0xDCC2,0x0001,0x0005,0x0000,0x0002,0xDEB4,0xB7AA,0x0003,0x0001,0xD2A9,0x0000, 0xCCD9,0x000E,0x0007,0x0001,0x0003,0x0001,0xD2D5,0x0000,0xDEBC,0x0001,0x0003,0x0001,0xC5BA,0x0001,0xDEBA,0x000A, 0x0005,0x0001,0x0002,0xC3EA,0xB2D8,0x0000,0x0002,0xDDA3,0xC0B6,0x0000,0x0000,0x0001,0xBDE5,0x0048,0x0023,0x000D, 0x0005,0x0000,0x0000,0x0001,0xDEBB,0x0000,0x0004,0x0002,0xDCF9,0xDEB7,0x0001,0xDEB8,0x0009,0x0005,0x0001,0x0002, 0xDEB9,0xCAED,0x0000,0x0000,0xDEB4,0x0007,0x0004,0x0002,0xD0BD,0xC8F8,0x0000,0xDEB0,0x0003,0x0000,0xBCF6,0x0000, 0xDEAF,0x000E,0x0009,0x0004,0x0001,0x0001,0xDDB2,0x0001,0x0002,0xDEB5,0xD1A6,0x0001,0x0001,0x0000,0xC7BE,0x000A, 0x0006,0x0003,0x0001,0xBDAA,0x0001,0xDEB2,0x0001,0x0000,0xDCBC,0x0007,0x0003,0x0000,0xBCBB,0x0002,0xDCF6,0xDEB1, 0x0003,0x0001,0xDEB6,0x0000,0xB1A1,0x0025,0x0012,0x0007,0x0001,0x0003,0x0000,0xC0D9,0x0001,0xDEAE,0x0007,0x0004, 0x0002,0xDEAA,0xDEB3,0x0001,0xDDF7,0x0001,0x0000,0xD4CC,0x0008,0x0004,0x0000,0x0000,0xDEAD,0x0000,0x0001,0xCFF4, 0x0007,0x0004,0x0002,0xCEDF,0xB5B4,0x0000,0xDEA7,0x0001,0x0000,0xDEA8,0x0015,0x0008,0x0004,0x0000,0x0000,0xDDDE, 0x0000,0x0000,0xDEA9,0x0006,0x0003,0x0001,0xDEA5,0x0000,0xDCE9,0x0004,0x0002,0xDEA1,0xDDB5,0x0001,0xDCBF,0x0005, 0x0001,0x0000,0x0000,0xDCF1,0x0007,0x0004,0x0002,0xC8EF,0xBDB6,0x0000,0xDEA6,0x0003,0x0000,0xDDDB,0x0001,0xDEAC, 0x008C,0x0042,0x0024,0x0014,0x000B,0x0004,0x0000,0x0001,0xDDA1,0x0003,0x0001,0xB1CE,0x0002,0xB0AA,0xDEA2,0x0000, 0x0004,0x0002,0xDDFE,0xDDFC,0x0002,0xDDFA,0xC7BE,0x0008,0x0001,0x0003,0x0001,0xD2F1,0x0002,0xCADF,0xC4E8,0x0001, 0x0004,0x0002,0xDCE0,0xB4D0,0x0001,0xBDAF,0x0015,0x000A,0x0006,0x0003,0x0001,0xB2CC,0x0001,0xDDFD,0x0000,0x0000, 0xDDE4,0x0006,0x0003,0x0000,0xCEB5,0x0001,0xD5E1,0x0001,0x0002,0xB2B7,0xC2FB,0x0000,0x0004,0x0000,0x0001,0xC3EF, 0x0001,0x0000,0xDDF8,0x0020,0x000B,0x0000,0x0004,0x0001,0x0001,0xDEA3,0x0003,0x0001,0xDCEA,0x0000,0xDEA4,0x000D, 0x0007,0x0003,0x0001,0xC6C1,0x0002,0xDDFB,0xDCCA,0x0003,0x0000,0xC1AB,0x0000,0xC5EE,0x0001,0x0004,0x0002,0xDDEB, 0xDDF6,0x0001,0xDDF7,0x0013,0x0009,0x0005,0x0001,0x0002,0xDDF1,0xBCBB,0x0000,0x0001,0xC0B6,0x0004,0x0001,0x0001, 0xDDFB,0x0003,0x0000,0xB1CD,0x0001,0xDDED,0x000C,0x0006,0x0003,0x0001,0xCBF2,0x0000,0xDDEA,0x0003,0x0001,0xDDE9, 0x0001,0xB8C7,0x0005,0x0000,0x0002,0xDDEE,0xC8D8,0x0003,0x0000,0xCFAF,0x0000,0xD0EE,0x004D,0x0026,0x0018,0x000D, 0x0007,0x0003,0x0001,0xDDE8,0x0002,0xDDA5,0xDDEF,0x0003,0x0001,0xDDEC,0x0000,0xB2D4,0x0007,0x0004,0x0002,0xDDF0, 0xDDF3,0x0000,0xD5F4,0x0001,0x0000,0xDDF4,0x0008,0x0000,0x0004,0x0002,0xC6D1,0xC6D1,0x0001,0xD8E1,0x0000,0x0001, 0x0002,0xDCE7,0xB5E3,0x0014,0x000A,0x0004,0x0000,0x0001,0xDDF2,0x0003,0x0000,0xDDB0,0x0000,0xCBE2,0x0006,0x0003, 0x0001,0xC3C9,0x0001,0xDDF5,0x0001,0x0000,0xDDAA,0x000B,0x0004,0x0001,0x0000,0xCBD1,0x0003,0x0000,0xDDE5,0x0002, 0xDDE4,0xBDAF,0x0000,0x0003,0x0001,0xDDDE,0x0002,0xDDDC,0xDDDB,0x002B,0x0013,0x0005,0x0000,0x0000,0x0000,0xB5D9, 0x0007,0x0003,0x0000,0xDDDD,0x0002,0xDDDF,0xBBE7,0x0004,0x0002,0xDDE3,0xBFFB,0x0001,0xDDDA,0x000E,0x0007,0x0003, 0x0001,0xB4D0,0x0002,0xDDB4,0xD2A9,0x0003,0x0001,0xDDE7,0x0002,0xD4E1,0xBAF9,0x0004,0x0000,0x0001,0xDDE2,0x0003, 0x0000,0xCEAD,0x0001,0xB6AD,0x0013,0x000B,0x0006,0x0003,0x0001,0xC6CF,0x0000,0xB2CE,0x0001,0x0002,0xDDD6,0xB8F0, 0x0000,0x0004,0x0002,0xDDD8,0xDDD9,0x0001,0xD7C5,0x0006,0x0000,0x0000,0x0002,0xDDA6,0xDDD7,0x0004,0x0000,0x0001, 0xD2B6,0x0000,0x0002,0xDDE1,0xDDCF,0x02D3,0x015C,0x00A3,0x004D,0x0026,0x000E,0x0006,0x0001,0x0001,0x0002,0xC2E4, 0xDDE0,0x0004,0x0001,0x0001,0xDDC7,0x0001,0x0000,0xDDAB,0x000B,0x0006,0x0003,0x0001,0xDDE6,0x0000,0xDDE6,0x0001, 0x0002,0xBED8,0xCDF2,0x0005,0x0001,0x0002,0xE9B1,0xC8F8,0x0004,0x0002,0xCFF4,0xDDD3,0x0002,0xD3AA,0xD3A9,0x000B, 0x0006,0x0001,0x0001,0x0002,0xC2DC,0xDDC6,0x0000,0x0001,0x0001,0xDDC1,0x000E,0x0006,0x0003,0x0000,0xDDE6,0x0000, 0xDDC8,0x0004,0x0002,0xDDCC,0xCEAE,0x0002,0xC6BC,0xC3C8,0x0007,0x0004,0x0002,0xDDC2,0xC0B3,0x0000,0xDDCA,0x0004, 0x0002,0xDCC9,0xDDC9,0x0001,0xCCD1,0x0029,0x0013,0x000A,0x0006,0x0003,0x0000,0xDDCD,0x0000,0xDDBD,0x0001,0x0000, 0xDDC4,0x0005,0x0001,0x0002,0xDDCF,0xDDCE,0x0001,0x0001,0xE2D6,0x000B,0x0007,0x0003,0x0001,0xB7C6,0x0002,0xC1E2, 0xDDD4,0x0000,0x0000,0xBBAA,0x0007,0x0004,0x0002,0xBDF6,0xDDD0,0x0000,0xC6D0,0x0001,0x0000,0xDDBE,0x0016,0x000C, 0x0005,0x0001,0x0002,0xDDD5,0xB2A4,0x0003,0x0000,0xDDCB,0x0002,0xDDC3,0xB2CB,0x0004,0x0001,0x0001,0xDDBF,0x0003, 0x0001,0xDDC5,0x0001,0xDDCA,0x000B,0x0004,0x0001,0x0000,0xD4D6,0x0004,0x0002,0xBACA,0xE7FB,0x0001,0xBEFA,0x0006, 0x0003,0x0001,0xBED5,0x0000,0xC2CC,0x0003,0x0000,0xB9BD,0x0000,0xDDD1,0x005C,0x0031,0x001A,0x000C,0x0005,0x0001, 0x0002,0xDDBC,0xDDD2,0x0003,0x0000,0xB4CC,0x0002,0xC3A7,0xDDBB,0x0007,0x0003,0x0001,0xDDBA,0x0002,0xD3A8,0xDDB5, 0x0004,0x0002,0xBBF1,0xDDB2,0x0001,0xDDAB,0x0009,0x0000,0x0004,0x0002,0xDDAA,0xC1AB,0x0002,0xC0B3,0xDDA8,0x0008, 0x0004,0x0002,0xC4AA,0xDDAD,0x0002,0xDDB3,0xDDB9,0x0003,0x0000,0xDCC8,0x0001,0xDDB5,0x0016,0x000C,0x0006,0x0003, 0x0001,0xBCD4,0x0001,0xDDAC,0x0003,0x0001,0xDDB8,0x0001,0xDDAF,0x0006,0x0003,0x0000,0xDCF0,0x0001,0xDDB7,0x0000, 0x0001,0xBEA5,0x0009,0x0005,0x0000,0x0002,0xDDAE,0xDCEC,0x0000,0x0001,0xC9AF,0x0006,0x0003,0x0001,0xD7AF,0x0000, 0xC0F2,0x0003,0x0001,0xC6CE,0x0000,0xDDB0,0x002C,0x0010,0x0006,0x0001,0x0001,0x0002,0xDDB4,0xDDB1,0x0006,0x0003, 0x0000,0xDDB6,0x0001,0xDDA9,0x0000,0x0000,0xBAC9,0x000C,0x0004,0x0000,0x0000,0xB6B9,0x0004,0x0002,0xD2A9,0xDDA7, 0x0002,0xDDA6,0xDDA4,0x0008,0x0004,0x0002,0xD2F1,0xDDA5,0x0002,0xDDA3,0xDDA1,0x0004,0x0002,0xD3AB,0xDCFD,0x0002, 0xDCFE,0xBBE7,0x0017,0x000E,0x0007,0x0003,0x0000,0xC8D9,0x0002,0xB5B4,0xDCF9,0x0004,0x0002,0xDCF6,0xDCF1,0x0001, 0xDCEA,0x0005,0x0000,0x0002,0xDCE9,0xBCD4,0x0001,0x0001,0xC0F3,0x000D,0x0007,0x0003,0x0001,0xBBC4,0x0002,0xDCE8, 0xBCF6,0x0003,0x0000,0xDCF3,0x0000,0xDCF1,0x0006,0x0003,0x0001,0xBEA3,0x0000,0xB2DD,0x0004,0x0002,0xDCF4,0xBEA3, 0x0000,0xB4F0,0x00C0,0x005F,0x0032,0x001A,0x000B,0x0007,0x0004,0x0002,0xDCF5,0xBBAA,0x0001,0xDCF7,0x0001,0x0001, 0xDCED,0x0007,0x0003,0x0001,0xDCFB,0x0002,0xC8E3,0xC8D7,0x0004,0x0002,0xECB7,0xB2E8,0x0002,0xD2F0,0xDCEE,0x000E, 0x0007,0x0004,0x0002,0xDCFC,0xD7C8,0x0000,0xDCEF,0x0003,0x0000,0xDCF2,0x0002,0xDCFA,0xB2E7,0x0006,0x0003,0x0000, 0xC3A3,0x0001,0xB4C4,0x0000,0x0000,0xBCEB,0x0014,0x0008,0x0004,0x0001,0x0001,0xDEB6,0x0001,0x0001,0xDCE7,0x0005, 0x0000,0x0002,0xDDA2,0xDCE1,0x0003,0x0000,0xDCF8,0x0002,0xDCE4,0xDCE3,0x000C,0x0004,0x0001,0x0000,0xDCE0,0x0004, 0x0002,0xDCD7,0xBEA5,0x0002,0xB9B6,0xDCDD,0x0005,0x0001,0x0002,0xDCD4,0xDCEB,0x0004,0x0002,0xDCD8,0xDCE2,0x0002, 0xC3A9,0xC7D1,0x002A,0x0016,0x0009,0x0000,0x0004,0x0002,0xB7B6,0xC3AF,0x0002,0xD7C2,0xB8A3,0x0007,0x0004,0x0002, 0xDCDE,0xDDAE,0x0000,0xC6BB,0x0003,0x0000,0xDCD5,0x0001,0xDCDA,0x0008,0x0004,0x0001,0x0000,0xD3A2,0x0000,0x0000, 0xB1BD,0x0004,0x0000,0x0000,0xC9BB,0x0004,0x0002,0xDCD1,0xBFE0,0x0002,0xC8F4,0xDCD6,0x001B,0x000E,0x0007,0x0003, 0x0000,0xDCC4,0x0002,0xDCD3,0xDCE5,0x0004,0x0002,0xB9B6,0xB0FA,0x0001,0xDCD9,0x0006,0x0003,0x0000,0xBFC1,0x0001, 0xDCDC,0x0003,0x0000,0xC3E7,0x0002,0xDCE6,0xCCA6,0x000F,0x0007,0x0004,0x0002,0xDCDF,0xDCDB,0x0000,0xD4B7,0x0004, 0x0002,0xCBD5,0xDCD1,0x0002,0xB2D4,0xDCC9,0x0007,0x0004,0x0002,0xDCC8,0xDCC3,0x0001,0xDCC2,0x0003,0x0000,0xCEAD, 0x0001,0xDCD0,0x0066,0x0038,0x001A,0x000D,0x0006,0x0003,0x0000,0xDCD8,0x0000,0xDCCA,0x0003,0x0001,0xDCC0,0x0002, 0xD1BF,0xC3AB,0x0007,0x0003,0x0000,0xDBBB,0x0002,0xC7DB,0xDCBF,0x0003,0x0000,0xDCC6,0x0001,0xDCCC,0x000F,0x0007, 0x0003,0x0000,0xB7BC,0x0002,0xBBA8,0xDCC1,0x0004,0x0002,0xD0BE,0xDCC7,0x0002,0xB0C5,0xB7D2,0x0008,0x0004,0x0002, 0xDCBE,0xDCCE,0x0002,0xDCCB,0xDCB8,0x0003,0x0001,0xC2AB,0x0002,0xBDE6,0xDCD2,0x0014,0x000B,0x0004,0x0001,0x0000, 0xDCCD,0x0003,0x0000,0xDCCF,0x0002,0xD6A5,0xCEDF,0x0005,0x0001,0x0002,0xDCBD,0xDCC5,0x0000,0x0000,0xDCBC,0x000F, 0x0008,0x0004,0x0002,0xDDA9,0xC3A2,0x0002,0xDCBB,0xDCD0,0x0004,0x0002,0xDCB6,0xDCBA,0x0000,0xC9D6,0x0007,0x0004, 0x0002,0xD3F3,0xDCB7,0x0001,0xD8C2,0x0001,0x0001,0xDCB9,0x002F,0x001A,0x000D,0x0006,0x0003,0x0001,0xBDDA,0x0001, 0xDCE6,0x0004,0x0002,0xDCB5,0xB0AC,0x0000,0xDCB4,0x0007,0x0003,0x0001,0xD2D5,0x0002,0xDCB3,0xB2DD,0x0003,0x0000, 0xD1DE,0x0001,0xE5F5,0x000D,0x0008,0x0004,0x0002,0xD1DE,0xC9AB,0x0002,0xBCE8,0xBCE8,0x0000,0x0002,0xC1BC,0xF4DE, 0x0004,0x0001,0x0001,0xF4BF,0x0000,0x0001,0xBDA2,0x0010,0x0008,0x0004,0x0000,0x0000,0xF4B5,0x0000,0x0000,0xF4BE, 0x0000,0x0003,0x0001,0xCBD2,0x0002,0xB2D5,0xCBD2,0x0005,0x0001,0x0000,0x0000,0xF4BC,0x0006,0x0003,0x0000,0xF4BB, 0x0000,0xF4BA,0x0003,0x0000,0xCDA7,0x0002,0xE4E9,0xF4B9,0x015D,0x00AE,0x005A,0x002C,0x0013,0x0005,0x0001,0x0001, 0x0000,0xF4B8,0x0006,0x0003,0x0001,0xF4B5,0x0001,0xB4AC,0x0004,0x0002,0xF4B4,0xCFCF,0x0002,0xB2B0,0xB6E6,0x000E, 0x0007,0x0004,0x0002,0xF4B7,0xF4B6,0x0001,0xB2D5,0x0004,0x0002,0xBDA2,0xF4B1,0x0001,0xF4B0,0x0007,0x0004,0x0002, 0xB0E3,0xF4B3,0x0000,0xBABD,0x0000,0x0000,0xF4B2,0x0013,0x000D,0x0007,0x0003,0x0001,0xF4AF,0x0002,0xF4AE,0xF4AD, 0x0003,0x0001,0xD6DB,0x0000,0xCEE8,0x0000,0x0000,0x0002,0xCBB4,0xE2B6,0x000C,0x0006,0x0003,0x0000,0xCCF2,0x0000, 0xCAE6,0x0003,0x0000,0xF3C2,0x0001,0xC9E1,0x0007,0x0003,0x0000,0xC9E0,0x0002,0xBEC9,0xBED9,0x0004,0x0002,0xD0CB, 0xD3EB,0x0002,0xD3DF,0xBECB,0x002F,0x0018,0x000D,0x0007,0x0003,0x0000,0xF4AA,0x0002,0xF4A9,0xF4A8,0x0003,0x0000, 0xD2A8,0x0000,0xF4A7,0x0007,0x0004,0x0002,0xBECA,0xD5E9,0x0000,0xCCA8,0x0000,0x0001,0xF1F3,0x000A,0x0005,0x0000, 0x0002,0xD6C2,0xD6C1,0x0001,0x0002,0xF4DF,0xB3F4,0x0006,0x0003,0x0000,0xF4AB,0x0000,0xD7D4,0x0004,0x0002,0xC1D9, 0xEAB0,0x0001,0xCED4,0x0013,0x000B,0x0004,0x0000,0x0001,0xB3BC,0x0004,0x0002,0xD9F5,0xD4E0,0x0001,0xC2E3,0x0004, 0x0001,0x0000,0xEBCD,0x0000,0x0000,0xC0B0,0x0007,0x0001,0x0003,0x0001,0xEBF7,0x0001,0xC6EA,0x0007,0x0003,0x0000, 0xEBFB,0x0002,0xEBFD,0xC1B3,0x0001,0x0000,0xD2DC,0x004F,0x0026,0x0016,0x000F,0x0007,0x0003,0x0001,0xD3B7,0x0002, 0xB1DB,0xECA1,0x0004,0x0002,0xCDCE,0xC5A7,0x0002,0xEBDA,0xB5A8,0x0000,0x0003,0x0001,0xEBFE,0x0000,0xE2DF,0x0005, 0x0000,0x0000,0x0001,0xC9C5,0x0005,0x0001,0x0002,0xEBFA,0xC4E5,0x0003,0x0000,0xC5F2,0x0000,0xECA2,0x0015,0x000A, 0x0004,0x0000,0x0001,0xEBF9,0x0003,0x0000,0xBDBA,0x0001,0xCFA5,0x0007,0x0004,0x0002,0xC4A4,0xCCC5,0x0000,0xB7F4, 0x0000,0x0000,0xB1EC,0x0008,0x0004,0x0001,0x0001,0xEBF7,0x0000,0x0001,0xB8E0,0x0006,0x0003,0x0000,0xF1A4,0x0000, 0xB2B2,0x0003,0x0000,0xEBF5,0x0000,0xE0BC,0x0035,0x001A,0x000E,0x0006,0x0003,0x0001,0xEBF0,0x0000,0xEBF6,0x0004, 0x0002,0xB0F2,0xCDC8,0x0002,0xCCDA,0xEBF0,0x0008,0x0004,0x0002,0xEBEF,0xC4E5,0x0002,0xCFD9,0xB8B9,0x0000,0x0000, 0xB3A6,0x000E,0x0007,0x0004,0x0002,0xEBE9,0xBDC5,0x0001,0xEBEC,0x0003,0x0000,0xD1FC,0x0002,0xC8F9,0xEBF1,0x0006, 0x0003,0x0001,0xD6D7,0x0001,0xEBEE,0x0003,0x0001,0xEBF2,0x0002,0xC4D4,0xD0C8,0x0011,0x0008,0x0004,0x0001,0x0001, 0xEBE1,0x0000,0x0000,0xEBED,0x0005,0x0001,0x0002,0xEBEB,0xEBEA,0x0001,0x0001,0xCDF3,0x000D,0x0007,0x0004,0x0002, 0xC7BB,0xEBE8,0x0001,0xB8AD,0x0003,0x0000,0xB8AF,0x0000,0xC9F6,0x0007,0x0004,0x0002,0xEBE7,0xD2B8,0x0000,0xC0B0, 0x0003,0x0000,0xEBE6,0x0000,0xCCF3,0x00B3,0x0052,0x0020,0x000F,0x0005,0x0001,0x0001,0x0000,0xC6A2,0x0004,0x0001, 0x0001,0xD5CD,0x0003,0x0000,0xC1B3,0x0000,0xEBE1,0x0009,0x0005,0x0001,0x0002,0xEBE5,0xCDD1,0x0000,0x0001,0xB8AC, 0x0000,0x0004,0x0002,0xEBE3,0xCDD1,0x0001,0xD0DE,0x0016,0x000A,0x0004,0x0000,0x0001,0xB4BD,0x0003,0x0001,0xD9F5, 0x0000,0xEBE2,0x0006,0x0003,0x0001,0xEBD6,0x0000,0xBDC5,0x0003,0x0000,0xEBE4,0x0000,0xB2B1,0x0010,0x0008,0x0004, 0x0002,0xD9F5,0xC5A7,0x0002,0xEBDF,0xC4D4,0x0004,0x0002,0xC6EA,0xD4E0,0x0002,0xEBDB,0xEBDA,0x0005,0x0001,0x0002, 0xBCB9,0xC2F6,0x0003,0x0000,0xC2F6,0x0002,0xB4E0,0xD0B2,0x0033,0x0015,0x0008,0x0004,0x0001,0x0000,0xD6AC,0x0001, 0x0001,0xC4DC,0x0007,0x0003,0x0000,0xEBDD,0x0002,0xB0B7,0xEBEF,0x0003,0x0000,0xD0D8,0x0000,0xBDBA,0x000F,0x0008, 0x0004,0x0002,0xEBD8,0xB8EC,0x0002,0xEBDC,0xEBD7,0x0004,0x0002,0xD2C8,0xBFE8,0x0001,0xEBD9,0x0008,0x0004,0x0002, 0xE6C0,0xEBD6,0x0002,0xEBCD,0xEBCC,0x0004,0x0002,0xEBCB,0xEBCA,0x0001,0xF1E3,0x001A,0x000B,0x0006,0x0003,0x0000, 0xD8B7,0x0001,0xBAFA,0x0001,0x0002,0xB0FB,0xEBD5,0x0008,0x0004,0x0002,0xCAA4,0xEBCE,0x0002,0xC5DF,0xEBD1,0x0003, 0x0001,0xEBD3,0x0002,0xC5D6,0xB7F4,0x0009,0x0004,0x0001,0x0001,0xD6AB,0x0001,0x0002,0xCCA5,0xEBD2,0x0007,0x0003, 0x0000,0xB1B3,0x0002,0xEBD4,0xB2B2,0x0001,0x0000,0xB5A8,0x0065,0x0033,0x001A,0x0010,0x0008,0x0004,0x0002,0xEBD0, 0xCEB8,0x0002,0xEBCF,0xD0B2,0x0004,0x0002,0xD5CD,0xD6D7,0x0002,0xC9F6,0xEBC4,0x0006,0x0003,0x0000,0xEBC2,0x0000, 0xB7CE,0x0000,0x0001,0xEBC9,0x000E,0x0007,0x0003,0x0000,0xEBC8,0x0002,0xD3FD,0xEBC5,0x0003,0x0001,0xBFCF,0x0002, 0xB0B9,0xEBC7,0x0007,0x0003,0x0001,0xEBC6,0x0002,0xB7BE,0xBCE7,0x0001,0x0001,0xB7CA,0x001C,0x000E,0x0007,0x0003, 0x0000,0xB7F4,0x0002,0xD6AB,0xB9C9,0x0004,0x0002,0xB3A6,0xEBBF,0x0001,0xB8CE,0x0007,0x0004,0x0002,0xEBC0,0xB8D8, 0x0000,0xB6C7,0x0003,0x0000,0xD6E2,0x0002,0xD0A4,0xC8CD,0x0008,0x0004,0x0000,0x0001,0xEBC1,0x0000,0x0000,0xB8EC, 0x0007,0x0004,0x0002,0xBCA1,0xC0DF,0x0001,0xC8E2,0x0003,0x0001,0xD5D8,0x0002,0xCBC1,0xCBE0,0x002A,0x0018,0x000D, 0x0005,0x0000,0x0002,0xD2DE,0xCBE0,0x0004,0x0002,0xEDB1,0xEDB2,0x0002,0xC1FB,0xCCFD,0x0004,0x0001,0x0001,0xF1F7, 0x0003,0x0001,0xD6B0,0x0002,0xC4F4,0xF1F9,0x000C,0x0007,0x0003,0x0001,0xCBCA,0x0002,0xC9F9,0xF1FA,0x0000,0x0002, 0xB4CF,0xC1AA,0x0000,0x0001,0x0002,0xB4CF,0xF1F9,0x000F,0x0005,0x0001,0x0001,0x0000,0xCEC5,0x0004,0x0001,0x0000, 0xBEDB,0x0003,0x0000,0xC6B8,0x0000,0xCAA5,0x000A,0x0006,0x0003,0x0000,0xC1AA,0x0000,0xF1F8,0x0001,0x0001,0xF1F7, 0x0007,0x0004,0x0002,0xD6B0,0xC1FB,0x0000,0xC1C4,0x0001,0x0000,0xF1F6,0x4108,0x287E,0x13B9,0x0A0C,0x0557,0x02EC, 0x0151,0x00AB,0x005E,0x002E,0x0016,0x0009,0x0005,0x0001,0x0002,0xF1F5,0xC4F4,0x0001,0x0000,0xB9A2,0x0006,0x0003, 0x0000,0xB5A2,0x0000,0xB3DC,0x0003,0x0001,0xCBCA,0x0002,0xDEC7,0xD2AE,0x000A,0x0006,0x0003,0x0000,0xF1F4,0x0000, 0xB6FA,0x0000,0x0000,0xF1F2,0x0006,0x0003,0x0001,0xF1EF,0x0001,0xC5D5,0x0004,0x0002,0xF1F0,0xF1F1,0x0002,0xF1EF, 0xF1EE,0x0017,0x000B,0x0006,0x0003,0x0000,0xF1ED,0x0001,0xF1EC,0x0000,0x0002,0xB3FA,0xF1EB,0x0004,0x0000,0x0001, 0xF1EA,0x0004,0x0002,0xB0D2,0xD4C5,0x0002,0xBAC4,0xF1E9,0x000E,0x0007,0x0004,0x0002,0xB8FB,0xF1E8,0x0001,0xF1E7, 0x0004,0x0002,0xD7A8,0xC4CD,0x0000,0xC4CD,0x0007,0x0004,0x0002,0xCBA3,0xB6F8,0x0000,0xF1F3,0x0001,0x0001,0xEAC8, 0x002B,0x0016,0x000C,0x0007,0x0004,0x0002,0xD5DF,0xEBA3,0x0000,0xBFBC,0x0000,0x0002,0xC0CF,0xD2AB,0x0006,0x0003, 0x0001,0xD2ED,0x0000,0xB7AD,0x0000,0x0000,0xC7CC,0x000B,0x0004,0x0001,0x0000,0xF4E8,0x0004,0x0002,0xB0BF,0xBAB2, 0x0001,0xF4E7,0x0004,0x0001,0x0000,0xCDE6,0x0003,0x0000,0xF4E6,0x0001,0xF4E5,0x0010,0x000B,0x0004,0x0000,0x0000, 0xF4E3,0x0004,0x0002,0xF4E4,0xB4E4,0x0000,0xB5D4,0x0001,0x0000,0x0001,0xC7CC,0x000B,0x0007,0x0004,0x0002,0xF4E2, 0xCFE8,0x0001,0xCFB0,0x0001,0x0001,0xF4E1,0x0000,0x0003,0x0001,0xD2EE,0x0001,0xF1B4,0x0053,0x0028,0x0016,0x000A, 0x0004,0x0000,0x0000,0xB3E1,0x0003,0x0000,0xCECC,0x0000,0xF4E0,0x0005,0x0000,0x0002,0xD3F0,0xE5F1,0x0004,0x0002, 0xB8FE,0xD9FA,0x0001,0xEBFE,0x000A,0x0004,0x0001,0x0001,0xF4CB,0x0003,0x0001,0xF4CA,0x0000,0xF4C9,0x0001,0x0004, 0x0002,0xD2E5,0xCFDB,0x0000,0xF4C8,0x0015,0x000E,0x0007,0x0004,0x0002,0xF4C7,0xC8BA,0x0001,0xC8DE,0x0003,0x0000, 0xCFDB,0x0002,0xF4C7,0xD0DF,0x0000,0x0003,0x0000,0xF4C6,0x0001,0xC1E7,0x0008,0x0004,0x0000,0x0001,0xB8E1,0x0001, 0x0001,0xC3C0,0x0008,0x0004,0x0002,0xB4EF,0xC7BC,0x0002,0xD8C2,0xD1F2,0x0003,0x0001,0xEEBF,0x0001,0xEEBC,0x002A, 0x0011,0x000A,0x0004,0x0000,0x0000,0xC2DE,0x0003,0x0000,0xEEBF,0x0001,0xEEC0,0x0001,0x0003,0x0000,0xEEBE,0x0000, 0xB0D5,0x000E,0x0007,0x0004,0x0002,0xC2EE,0xEEBC,0x0001,0xCAF0,0x0004,0x0002,0xEEBD,0xB7A3,0x0001,0xD6C3,0x0004, 0x0001,0x0001,0xD7EF,0x0004,0x0002,0xD5D6,0xEEBB,0x0001,0xEEB7,0x0015,0x000B,0x0005,0x0001,0x0002,0xB9D2,0xB0D5, 0x0003,0x0000,0xEEB8,0x0000,0xEEB9,0x0004,0x0001,0x0001,0xB7A3,0x0003,0x0001,0xEEB7,0x0000,0xC2DE,0x000A,0x0005, 0x0000,0x0002,0xBAB1,0xD8E8,0x0000,0x0002,0xCDF8,0xB9DE,0x0006,0x0003,0x0001,0xF3BF,0x0000,0xCECD,0x0000,0x0001, 0xCCB3,0x00ED,0x0071,0x0034,0x0014,0x0009,0x0005,0x0002,0xF3C1,0x0000,0xF3C0,0x0000,0x0000,0xF3BF,0x0005,0x0000, 0x0002,0xC6BF,0xB2A7,0x0003,0x0000,0xC8B1,0x0000,0xB8D7,0x0010,0x0008,0x0004,0x0002,0xF3BE,0xE7DA,0x0002,0xBDC9, 0xE7D9,0x0004,0x0002,0xE7D8,0xE7D7,0x0002,0xE7D6,0xE7D5,0x0008,0x0004,0x0002,0xC9C9,0xE7D4,0x0002,0xE7D3,0xE7D2, 0x0004,0x0002,0xE7D1,0xCBF5,0x0002,0xD3A7,0xE7D0,0x001F,0x0010,0x0008,0x0004,0x0002,0xE7CF,0xE7CE,0x0002,0xE7CD, 0xE7CC,0x0004,0x0002,0xE7CB,0xE7CA,0x0002,0xB2F8,0xE7C9,0x0007,0x0003,0x0001,0xB7EC,0x0002,0xE7C7,0xE7C8,0x0004, 0x0002,0xB8BF,0xE7C6,0x0002,0xD4B5,0xE7C5,0x000F,0x0008,0x0004,0x0002,0xB1E0,0xC2C6,0x0002,0xB5DE,0xBBBA,0x0004, 0x0002,0xE7C4,0xE7C3,0x0001,0xE7C2,0x0008,0x0004,0x0002,0xB6D0,0xE7B6,0x0002,0xE7C1,0xE7C0,0x0003,0x0001,0xBCA9, 0x0002,0xE7BF,0xE7BE,0x003E,0x001F,0x0010,0x0008,0x0004,0x0002,0xC0C2,0xC3E5,0x0002,0xBCEA,0xE7BD,0x0004,0x0002, 0xE7BC,0xE7BB,0x0002,0xD7BA,0xC2CC,0x0008,0x0004,0x0002,0xE7BA,0xD5C0,0x0002,0xD7DB,0xE7B9,0x0003,0x0000,0xE7B8, 0x0002,0xB3F1,0xB1C1,0x0010,0x0008,0x0004,0x0002,0xE7B7,0xC3E0,0x0002,0xCEAC,0xC9FE,0x0004,0x0002,0xE7B5,0xE7B4, 0x0002,0xB4C2,0xE7B3,0x0007,0x0004,0x0002,0xE7B2,0xD0F8,0x0001,0xE7B1,0x0004,0x0002,0xD0F7,0xBCA8,0x0002,0xE7B0, 0xBCCC,0x001F,0x000F,0x0007,0x0004,0x0002,0xCCD0,0xCBE7,0x0001,0xD0E5,0x0004,0x0002,0xBEEE,0xE7AF,0x0002,0xE7AE, 0xCDB3,0x0008,0x0004,0x0002,0xBDCA,0xBEF8,0x0002,0xC2E7,0xE7AD,0x0004,0x0002,0xD1A4,0xB8F8,0x0002,0xBBE6,0xE7AC, 0x000F,0x0007,0x0003,0x0001,0xC8C6,0x0002,0xE7AB,0xBDE1,0x0004,0x0002,0xC8DE,0xB0F3,0x0002,0xE7AA,0xBEAD,0x0008, 0x0004,0x0002,0xD2EF,0xC9DC,0x0002,0xE7A9,0xE7A8,0x0004,0x0002,0xB0ED,0xE7A7,0x0002,0xD6D5,0xD6AF,0x006B,0x003B, 0x001D,0x0010,0x0008,0x0004,0x0002,0xCFB8,0xC9F0,0x0002,0xD7E9,0xC1B7,0x0004,0x0002,0xE7A6,0xE7A5,0x0002,0xE7A4, 0xCFDF,0x0005,0x0000,0x0002,0xE7A3,0xC5A6,0x0004,0x0002,0xB7C4,0xCEC6,0x0002,0xD6BD,0xB7D7,0x000F,0x0007,0x0004, 0x0002,0xC2DA,0xD7DD,0x0001,0xC4C9,0x0004,0x0002,0xB8D9,0xC9B4,0x0002,0xE7A2,0xB4BF,0x0007,0x0003,0x0001,0xE7A1, 0x0002,0xCEB3,0xC8D2,0x0004,0x0002,0xBCCD,0xE6FE,0x0002,0xE6FD,0xBCB6,0x0019,0x0010,0x0008,0x0004,0x0002,0xD4BC, 0xE6FC,0x0002,0xCFCB,0xE6FB,0x0004,0x0002,0xBAEC,0xE6FA,0x0002,0xBEC0,0xE6F9,0x0005,0x0001,0x0002,0xC0C2,0xF4EE, 0x0001,0x0000,0xE7DA,0x000B,0x0007,0x0003,0x0000,0xCFCB,0x0002,0xB2C5,0xD3A7,0x0001,0x0001,0xB2F8,0x0006,0x0003, 0x0001,0xC0DB,0x0000,0xD0F8,0x0003,0x0000,0xE6FE,0x0000,0xE7D3,0x0024,0x0010,0x0005,0x0001,0x0000,0x0000,0xD7EB, 0x0007,0x0004,0x0002,0xE7D7,0xE7CD,0x0000,0xBCCC,0x0000,0x0001,0xD2EF,0x0009,0x0004,0x0001,0x0001,0xBDC9,0x0001, 0x0002,0xE7D8,0xE7D9,0x0006,0x0003,0x0001,0xBCEB,0x0001,0xCFB5,0x0000,0x0002,0xBBE6,0xC9FE,0x000F,0x0006,0x0001, 0x0000,0x0002,0xE7C0,0xD0E5,0x0004,0x0000,0x0000,0xC8C6,0x0000,0x0002,0xE7D4,0xB7AD,0x000A,0x0006,0x0003,0x0001, 0xC9C9,0x0000,0xD6AF,0x0000,0x0000,0xE7D5,0x0001,0x0001,0x0002,0xF1DF,0xF4ED,0x012F,0x0093,0x004E,0x002F,0x0017, 0x000B,0x0005,0x0002,0xE7D1,0x0000,0xE7D2,0x0003,0x0000,0xB1C1,0x0000,0xB7B1,0x0006,0x0003,0x0001,0xBCA8,0x0000, 0xD7DC,0x0003,0x0000,0xF7E3,0x0000,0xE7CE,0x000E,0x0008,0x0004,0x0002,0xC2C6,0xF4EA,0x0002,0xE7CF,0xCFCB,0x0003, 0x0001,0xE7D0,0x0000,0xD7DD,0x0006,0x0003,0x0001,0xCBF5,0x0000,0xE7CA,0x0000,0x0000,0xB7EC,0x0010,0x0005,0x0001, 0x0000,0x0000,0xCFD8,0x0007,0x0004,0x0002,0xE7C8,0xE7C9,0x0000,0xE7C7,0x0000,0x0000,0xB8BF,0x0006,0x0001,0x0001, 0x0002,0xE7CC,0xE7A7,0x0001,0x0004,0x0002,0xE7C4,0xE7CB,0x0002,0xE7C6,0xDDD3,0x001F,0x0008,0x0001,0x0001,0x0003, 0x0000,0xD6C2,0x0000,0xE7BE,0x000C,0x0006,0x0003,0x0001,0xE7C2,0x0001,0xC1B7,0x0003,0x0001,0xE7BF,0x0000,0xE7C3, 0x0006,0x0003,0x0000,0xCEB3,0x0001,0xC3E5,0x0001,0x0002,0xBBBA,0xB1E0,0x0018,0x000B,0x0004,0x0000,0x0001,0xE7C1, 0x0003,0x0000,0xD4B5,0x0002,0xE7C5,0xB5DE,0x0006,0x0003,0x0001,0xB6D0,0x0000,0xBCA9,0x0003,0x0001,0xCFDF,0x0002, 0xE7BC,0xBCEA,0x0008,0x0004,0x0000,0x0000,0xE7BD,0x0000,0x0001,0xD0F7,0x0001,0x0000,0x0002,0xE7B3,0xBDF4,0x0051, 0x002D,0x0019,0x000A,0x0006,0x0003,0x0000,0xE7BB,0x0001,0xE7B5,0x0001,0x0000,0xBCA9,0x0007,0x0004,0x0002,0xC3E0, 0xE7B1,0x0000,0xB4C2,0x0004,0x0002,0xD5C0,0xE7B2,0x0002,0xE7B8,0xC2DA,0x000C,0x0005,0x0001,0x0002,0xB2CA,0xD7BA, 0x0003,0x0001,0xCDF8,0x0002,0xB8D9,0xE7BA,0x0000,0x0003,0x0001,0xF4EC,0x0002,0xCEAC,0xE7B7,0x0013,0x000C,0x0005, 0x0000,0x0002,0xD7BC,0xF4EB,0x0004,0x0002,0xE7B9,0xB3F1,0x0001,0xC2CC,0x0000,0x0003,0x0001,0xE7B6,0x0001,0xD7DB, 0x0007,0x0001,0x0003,0x0000,0xBEAD,0x0000,0xC0A6,0x0006,0x0003,0x0000,0xCBE7,0x0000,0xE7A8,0x0001,0x0001,0xE7B0, 0x0027,0x0011,0x000A,0x0004,0x0000,0x0001,0xE7AE,0x0003,0x0000,0xE7AF,0x0000,0xB0F3,0x0001,0x0003,0x0000,0xC3E1, 0x0000,0xBEEE,0x000B,0x0004,0x0000,0x0000,0xF4EA,0x0004,0x0002,0xE7AD,0xCBBF,0x0000,0xCDB3,0x0005,0x0000,0x0002, 0xBAA7,0xD0F5,0x0003,0x0001,0xEBB3,0x0001,0xC8DE,0x0014,0x000A,0x0004,0x0000,0x0001,0xB8F8,0x0003,0x0001,0xD1A4, 0x0000,0xC2E7,0x0006,0x0003,0x0001,0xBDCA,0x0001,0xBDE0,0x0000,0x0000,0xCCD0,0x000A,0x0006,0x0003,0x0001,0xE6FE, 0x0000,0xBEF8,0x0001,0x0001,0xBDE1,0x0000,0x0000,0x0002,0xE7A5,0xE7AC,0x00B3,0x005F,0x002D,0x0019,0x000D,0x0006, 0x0003,0x0001,0xB0ED,0x0001,0xD7E9,0x0004,0x0002,0xCFD2,0xD6D5,0x0001,0xE7A9,0x0006,0x0003,0x0000,0xE7AA,0x0001, 0xE7A8,0x0003,0x0001,0xE7A4,0x0000,0xC9DC,0x0009,0x0001,0x0004,0x0002,0xC9F0,0xE7A5,0x0002,0xE7A6,0xCFB8,0x0007, 0x0004,0x0002,0xC0DB,0xD4FA,0x0001,0xB3F1,0x0000,0x0000,0xD7CF,0x0019,0x000B,0x0004,0x0000,0x0000,0xBDF4,0x0003, 0x0001,0xCBF7,0x0002,0xB7C4,0xCBD8,0x0006,0x0003,0x0000,0xF1C6,0x0001,0xE7A1,0x0004,0x0002,0xB7D7,0xBCB6,0x0002, 0xD6BD,0xBAEA,0x000D,0x0007,0x0003,0x0000,0xC9B4,0x0002,0xE7A2,0xB4BF,0x0003,0x0000,0xE7A3,0x0001,0xC5A6,0x0004, 0x0001,0x0000,0xC4C9,0x0004,0x0002,0xCEC6,0xCEC9,0x0002,0xC8D2,0xE6FD,0x002D,0x0019,0x000F,0x0008,0x0004,0x0002, 0xE6FC,0xE6FA,0x0002,0xBAEC,0xD4BC,0x0004,0x0002,0xD1AD,0xE6FB,0x0001,0xBCCD,0x0004,0x0000,0x0001,0xBEC0,0x0003, 0x0000,0xCFB5,0x0001,0xF4E9,0x000C,0x0006,0x0003,0x0001,0xF4D0,0x0001,0xD9E1,0x0003,0x0001,0xF4CF,0x0001,0xCDC5, 0x0004,0x0000,0x0000,0xC5B4,0x0001,0x0001,0xF4DD,0x0014,0x0008,0x0004,0x0000,0x0000,0xC1B8,0x0001,0x0001,0xBFB7, 0x0008,0x0004,0x0002,0xD4E3,0xB7E0,0x0002,0xF4D6,0xC3D3,0x0001,0x0000,0xB2DA,0x0008,0x0000,0x0004,0x0002,0xF4DC, 0xCCC7,0x0000,0xB8E2,0x0005,0x0001,0x0002,0xF4D9,0xF4D8,0x0003,0x0001,0xBAFD,0x0001,0xF4DA,0x004F,0x0028,0x0015, 0x000A,0x0006,0x0003,0x0000,0xF4D7,0x0000,0xF4DB,0x0001,0x0000,0xF4D6,0x0007,0x0003,0x0001,0xBEAB,0x0002,0xF4D5, 0xF4D4,0x0001,0x0000,0xB4E2,0x000B,0x0004,0x0001,0x0000,0xD4C1,0x0004,0x0002,0xBEAC,0xF4D3,0x0000,0xC1BB,0x0004, 0x0000,0x0001,0xC1B8,0x0000,0x0001,0xB7E0,0x0016,0x000A,0x0005,0x0001,0x0002,0xD6E0,0xD4C1,0x0000,0x0002,0xE2CC, 0xF4D2,0x0008,0x0004,0x0002,0xCBDA,0xF4D1,0x0002,0xF4CF,0xF4D0,0x0001,0x0001,0xD5B3,0x000C,0x0006,0x0003,0x0000, 0xB4D6,0x0000,0xC6C9,0x0003,0x0001,0xC1A3,0x0000,0xF4CE,0x0001,0x0001,0x0000,0xB7DB,0x001F,0x000A,0x0001,0x0005, 0x0001,0x0002,0xD7D1,0xF4CC,0x0000,0x0000,0xC0E0,0x0009,0x0004,0x0001,0x0001,0xD9E1,0x0000,0x0002,0xC3D7,0xD3F5, 0x0006,0x0003,0x0001,0xC2E1,0x0001,0xC0E9,0x0003,0x0001,0xF3FD,0x0000,0xF3D6,0x0010,0x0009,0x0005,0x0001,0x0002, 0xD9DF,0xC7A9,0x0001,0x0001,0xC1FD,0x0000,0x0003,0x0000,0xF4A5,0x0001,0xF3EA,0x0005,0x0001,0x0001,0x0001,0xCCD9, 0x0000,0x0001,0x0002,0xBCAE,0xB3EF,0x0272,0x013D,0x008C,0x0043,0x001D,0x0010,0x0007,0x0001,0x0003,0x0001,0xC0BA, 0x0001,0xF4A5,0x0000,0x0004,0x0002,0xF4A6,0xB2BE,0x0002,0xC1B1,0xC7A9,0x0006,0x0000,0x0000,0x0002,0xF4A4,0xE9DC, 0x0001,0x0003,0x0001,0xF3EF,0x0000,0xF4A2,0x0013,0x000C,0x0006,0x0003,0x0001,0xBBC9,0x0000,0xF4A3,0x0003,0x0001, 0xF3F1,0x0001,0xBCF2,0x0000,0x0003,0x0001,0xF4A1,0x0000,0xF3EC,0x0008,0x0004,0x0001,0x0000,0xF3FD,0x0001,0x0001, 0xCBF2,0x0006,0x0003,0x0001,0xF3FC,0x0001,0xC2A8,0x0000,0x0002,0xF3F9,0xF3FE,0x0022,0x000F,0x0005,0x0000,0x0000, 0x0001,0xB4D8,0x0006,0x0003,0x0000,0xF3E5,0x0000,0xF3FA,0x0000,0x0000,0xF3FB,0x000A,0x0004,0x0000,0x0001,0xC5F1, 0x0003,0x0001,0xF3D9,0x0001,0xC0E9,0x0004,0x0001,0x0000,0xC0BA,0x0001,0x0002,0xF3F8,0xC9B8,0x0018,0x000B,0x0005, 0x0001,0x0002,0xF3F7,0xF3F6,0x0003,0x0000,0xF3C6,0x0001,0xB4DB,0x0006,0x0003,0x0000,0xF3E3,0x0001,0xF3F4,0x0003, 0x0001,0xF3E8,0x0002,0xF3F5,0xB8DD,0x0007,0x0001,0x0003,0x0001,0xC2A8,0x0001,0xF3F1,0x0001,0x0004,0x0002,0xF3F3, 0xF3E6,0x0001,0xD6FE,0x0053,0x0027,0x0011,0x000C,0x0006,0x0003,0x0001,0xC6AA,0x0000,0xD7AD,0x0003,0x0000,0xB7B6, 0x0001,0xF3F2,0x0000,0x0000,0x0000,0xBDDA,0x000A,0x0004,0x0000,0x0000,0xF3E7,0x0003,0x0000,0xF3F0,0x0001,0xCFE4, 0x0004,0x0001,0x0001,0xBCFD,0x0004,0x0002,0xF3E8,0xF3EF,0x0002,0xF3EC,0xC2E1,0x0016,0x000C,0x0007,0x0004,0x0002, 0xF3EA,0xF3E6,0x0000,0xF3E5,0x0001,0x0002,0xF3EE,0xB9DC,0x0006,0x0003,0x0000,0xE9A2,0x0001,0xF3E9,0x0000,0x0000, 0xF3ED,0x000A,0x0006,0x0003,0x0001,0xCBE3,0x0001,0xBBFE,0x0000,0x0000,0xB2AD,0x0008,0x0004,0x0002,0xF3E4,0xF3DD, 0x0002,0xF3F8,0xB9BF,0x0000,0x0001,0xBCE3,0x002B,0x0014,0x0008,0x0000,0x0004,0x0002,0xB2AD,0xB8F6,0x0001,0xF3EB, 0x0006,0x0003,0x0000,0xBCF2,0x0000,0xC7A9,0x0003,0x0001,0xF3E0,0x0001,0xB3EF,0x000E,0x0006,0x0003,0x0001,0xBFEA, 0x0001,0xF3DB,0x0004,0x0002,0xB2DF,0xDCF0,0x0002,0xF3E2,0xF3E3,0x0005,0x0001,0x0002,0xF3DF,0xCBE3,0x0001,0x0001, 0xCDB2,0x0018,0x000C,0x0006,0x0003,0x0001,0xF3C8,0x0000,0xB9DC,0x0003,0x0001,0xC0E9,0x0000,0xF3E1,0x0006,0x0003, 0x0000,0xF3DE,0x0001,0xF3DD,0x0003,0x0001,0xC9B8,0x0000,0xF3D9,0x000D,0x0006,0x0003,0x0000,0xF3D8,0x0000,0xB2DF, 0x0003,0x0000,0xB4F0,0x0002,0xCDB2,0xD6FE,0x0007,0x0004,0x0002,0xBFF0,0xB7A4,0x0001,0xCBF1,0x0004,0x0002,0xF3DC, 0xBDEE,0x0001,0xB5C8,0x0099,0x0055,0x002C,0x0014,0x0009,0x0005,0x0001,0x0002,0xF3CC,0xB1CA,0x0000,0x0000,0xF3DA, 0x0004,0x0001,0x0001,0xF3D6,0x0003,0x0001,0xC1FD,0x0002,0xF3CC,0xBCE3,0x000B,0x0004,0x0000,0x0001,0xF3CD,0x0003, 0x0000,0xB7B6,0x0002,0xF3D5,0xF3C7,0x0006,0x0003,0x0000,0xF3D1,0x0001,0xF3D0,0x0003,0x0001,0xB5DA,0x0002,0xF3CA, 0xF3CE,0x0015,0x000B,0x0006,0x0003,0x0001,0xB1BF,0x0001,0xB7FB,0x0000,0x0002,0xF3D3,0xF3D4,0x0006,0x0003,0x0001, 0xF3D2,0x0001,0xF3D7,0x0001,0x0000,0xB5D1,0x0009,0x0004,0x0000,0x0000,0xF3CF,0x0000,0x0002,0xF3C8,0xB1CA,0x0006, 0x0003,0x0000,0xD0A6,0x0000,0xF3CB,0x0001,0x0002,0xCBF1,0xF3C9,0x0025,0x0016,0x000C,0x0006,0x0003,0x0001,0xF3C5, 0x0001,0xB0CA,0x0003,0x0001,0xF3C7,0x0000,0xF3C6,0x0004,0x0001,0x0000,0xB8CD,0x0003,0x0000,0xF3C4,0x0001,0xF3C3, 0x0007,0x0000,0x0003,0x0000,0xD6F1,0x0001,0xBEBA,0x0004,0x0001,0x0000,0xB6CB,0x0000,0x0000,0xBDDF,0x0012,0x000A, 0x0004,0x0001,0x0001,0xF1B5,0x0003,0x0000,0xCDAF,0x0000,0xBFA2,0x0000,0x0003,0x0001,0xD5C2,0x0002,0xBEB9,0xBEBA, 0x0007,0x0000,0x0003,0x0000,0xD5BE,0x0001,0xCAFA,0x0001,0x0001,0x0002,0xC1A2,0xC7D4,0x0053,0x0025,0x0011,0x0009, 0x0004,0x0001,0x0000,0xF1BC,0x0000,0x0002,0xC7CF,0xB4DC,0x0004,0x0001,0x0000,0xC1FE,0x0001,0x0001,0xBFFA,0x0008, 0x0004,0x0001,0x0001,0xF1C0,0x0001,0x0000,0xF1C1,0x0005,0x0001,0x0002,0xD2A4,0xC7EE,0x0004,0x0002,0xF1C0,0xF1BE, 0x0001,0xCDDD,0x0016,0x000B,0x0007,0x0004,0x0002,0xCED1,0xF1BF,0x0001,0xF1BC,0x0000,0x0000,0xBFFA,0x0006,0x0003, 0x0001,0xF1BD,0x0000,0xBFDF,0x0000,0x0002,0xCED1,0xB4DC,0x000D,0x0007,0x0003,0x0001,0xBEBD,0x0002,0xB4B0,0xBDD1, 0x0003,0x0000,0xF1BB,0x0001,0xD6CF,0x0004,0x0000,0x0000,0xD2A4,0x0003,0x0000,0xC7CF,0x0002,0xBFDF,0xCDDD,0x002C, 0x0017,0x000C,0x0006,0x0003,0x0001,0xF1BA,0x0001,0xF1B9,0x0003,0x0001,0xD5AD,0x0000,0xC7D4,0x0007,0x0004,0x0002, 0xCDBB,0xF1B8,0x0000,0xB4A9,0x0001,0x0001,0xBFD5,0x000D,0x0008,0x0004,0x0002,0xF1B7,0xF1B6,0x0002,0xC7EE,0xBEBF, 0x0000,0x0002,0xCDDA,0xD1A8,0x0004,0x0000,0x0001,0xF0A6,0x0001,0x0000,0xBBF1,0x000D,0x0008,0x0004,0x0000,0x0000, 0xCEC8,0x0001,0x0001,0xBBE0,0x0000,0x0000,0x0000,0xF0A3,0x0005,0x0000,0x0001,0x0000,0xCBEB,0x0006,0x0003,0x0000, 0xF0A3,0x0001,0xD3B1,0x0000,0x0002,0xBBFD,0xF6D5,0x0125,0x0097,0x0046,0x0023,0x0011,0x0005,0x0001,0x0000,0x0000, 0xC4C2,0x0005,0x0001,0x0002,0xB9C8,0xB8E5,0x0003,0x0001,0xBBFC,0x0002,0xBCDA,0xB5BE,0x000A,0x0006,0x0003,0x0001, 0xF0A1,0x0001,0xF0A2,0x0001,0x0001,0xCEC8,0x0004,0x0000,0x0001,0xB3C6,0x0000,0x0000,0xD6D6,0x0010,0x0005,0x0001, 0x0001,0x0001,0xF6D5,0x0005,0x0001,0x0002,0xB3ED,0xD9F7,0x0003,0x0000,0xEFFD,0x0000,0xC0E2,0x000B,0x0007,0x0003, 0x0000,0xD6C9,0x0002,0xC6DA,0xB0DE,0x0001,0x0000,0xEFFE,0x0001,0x0004,0x0002,0xCBB0,0xC9D4,0x0001,0xB3CC,0x0029, 0x0019,0x000D,0x0006,0x0003,0x0000,0xDCE8,0x0000,0xB8D1,0x0004,0x0002,0xEFF9,0xCBB0,0x0001,0xEFFB,0x0006,0x0003, 0x0000,0xEFFC,0x0000,0xCFA1,0x0003,0x0001,0xBBE0,0x0001,0xD2C6,0x0005,0x0000,0x0001,0x0000,0xBDD5,0x0005,0x0001, 0x0002,0xB3C6,0xBBFD,0x0003,0x0001,0xEFF6,0x0001,0xEFF7,0x0012,0x000D,0x0006,0x0003,0x0001,0xD6C8,0x0001,0xD1ED, 0x0003,0x0000,0xC7D8,0x0002,0xB3D3,0xEFF7,0x0000,0x0001,0x0001,0xD7E2,0x0009,0x0004,0x0001,0x0000,0xC3D8,0x0000, 0x0002,0xD6BB,0xEFF5,0x0007,0x0004,0x0002,0xC3EB,0xBFC6,0x0001,0xBAC4,0x0003,0x0001,0xD6D6,0x0001,0xC7EF,0x0046, 0x002D,0x001A,0x000C,0x0006,0x0003,0x0001,0xB1FC,0x0000,0xF4CC,0x0003,0x0000,0xB8D1,0x0001,0xCDBA,0x0007,0x0003, 0x0001,0xCBBD,0x0002,0xD0E3,0xCDBA,0x0004,0x0002,0xBACC,0xC7DD,0x0001,0xC0EB,0x0009,0x0005,0x0000,0x0002,0xD8AE, 0xD3ED,0x0001,0x0001,0xECFC,0x0006,0x0003,0x0001,0xB5BB,0x0000,0xECF2,0x0000,0x0000,0xC0F1,0x000B,0x0000,0x0006, 0x0003,0x0000,0xECF8,0x0001,0xECFB,0x0000,0x0000,0xD3F9,0x0005,0x0000,0x0000,0x0000,0xECFA,0x0004,0x0001,0x0001, 0xB8A3,0x0000,0x0002,0xECF5,0xBBF6,0x0022,0x0012,0x000A,0x0004,0x0000,0x0000,0xECF9,0x0003,0x0001,0xECF8,0x0000, 0xC2BB,0x0000,0x0003,0x0001,0xBDFB,0x0002,0xD9F7,0xC2BB,0x0008,0x0000,0x0003,0x0000,0xECF7,0x0002,0xBBF6,0xB5BB, 0x0004,0x0001,0x0001,0xECF5,0x0000,0x0001,0xBCC0,0x0018,0x0009,0x0005,0x0001,0x0002,0xC6B1,0xECF6,0x0000,0x0001, 0xCFE9,0x0007,0x0003,0x0000,0xECF2,0x0002,0xECF4,0xCBEE,0x0004,0x0002,0xC9F1,0xD7A3,0x0002,0xECEF,0xECEE,0x0000, 0x0006,0x0003,0x0000,0xECF1,0x0001,0xECF3,0x0004,0x0002,0xD7E6,0xC3D8,0x0001,0xECF0,0x0085,0x0047,0x002B,0x001A, 0x000C,0x0007,0x0003,0x0001,0xECED,0x0002,0xC6ED,0xD6BB,0x0000,0x0002,0xECEC,0xB0C0,0x0006,0x0003,0x0001,0xC6EE, 0x0000,0xECEB,0x0004,0x0002,0xC9E7,0xC8D4,0x0002,0xC0F1,0xECEA,0x0008,0x0004,0x0000,0x0000,0xCABE,0x0001,0x0000, 0xEDE7,0x0004,0x0000,0x0001,0xEDC3,0x0001,0x0002,0xB7AF,0xC0F9,0x000F,0x000A,0x0004,0x0000,0x0000,0xEDC2,0x0003, 0x0000,0xBFF3,0x0000,0xEDE5,0x0001,0x0000,0x0000,0xEDE6,0x0008,0x0004,0x0000,0x0001,0xB0AD,0x0001,0x0001,0xEDE4, 0x0001,0x0000,0x0000,0xB4A1,0x0021,0x000D,0x0005,0x0001,0x0000,0x0001,0xEDE2,0x0004,0x0000,0x0001,0xBDB8,0x0000, 0x0001,0xEDCD,0x000A,0x0006,0x0003,0x0000,0xBBC7,0x0001,0xC1D7,0x0001,0x0000,0xEDE3,0x0006,0x0003,0x0000,0xEDE1, 0x0001,0xEDB6,0x0001,0x0000,0xEDE0,0x000A,0x0000,0x0005,0x0001,0x0002,0xC4A5,0xEDD3,0x0001,0x0001,0xEDD7,0x000B, 0x0005,0x0000,0x0002,0xD7A9,0xEDDE,0x0003,0x0001,0xBFC4,0x0000,0xEDDD,0x0004,0x0001,0x0000,0xC5CD,0x0001,0x0001, 0xB4E8,0x0058,0x0028,0x0013,0x0009,0x0005,0x0000,0x0002,0xC0DA,0xEDDF,0x0000,0x0001,0xB0F5,0x0004,0x0000,0x0001, 0xB4C5,0x0003,0x0000,0xC4EB,0x0000,0xC2EB,0x000A,0x0005,0x0000,0x0002,0xC8B7,0xEDDB,0x0001,0x0002,0xB2EA,0xCCBC, 0x0007,0x0004,0x0002,0xEDDA,0xBCEE,0x0000,0xC5F6,0x0000,0x0001,0xEDB8,0x001A,0x000D,0x0007,0x0004,0x0002,0xD5E8, 0xCBB6,0x0001,0xB1CC,0x0003,0x0001,0xEDDC,0x0001,0xEDD9,0x0006,0x0003,0x0001,0xEDD8,0x0001,0xB5FA,0x0003,0x0000, 0xD1D2,0x0002,0xEDD7,0xEDD3,0x000B,0x0007,0x0003,0x0000,0xEDD5,0x0002,0xB5E2,0xCDEB,0x0001,0x0001,0xEDD4,0x0004, 0x0000,0x0001,0xB1AE,0x0004,0x0002,0xCBE9,0xB0AD,0x0000,0xC2B5,0x001D,0x000C,0x0007,0x0000,0x0003,0x0001,0xB5EF, 0x0001,0xEDD6,0x0001,0x0001,0x0000,0xC5F0,0x0005,0x0000,0x0001,0x0001,0xBCEF,0x0004,0x0001,0x0001,0xD1E2,0x0004, 0x0002,0xC8B7,0xEDCB,0x0002,0xD3B2,0xC1F2,0x000F,0x000A,0x0006,0x0003,0x0000,0xEDD2,0x0000,0xEDBA,0x0001,0x0000, 0xEDCC,0x0001,0x0000,0x0001,0xCFF5,0x0009,0x0004,0x0001,0x0001,0xEDCD,0x0000,0x0002,0xEDCC,0xCBB6,0x0006,0x0003, 0x0000,0xCEF8,0x0000,0xEDCF,0x0003,0x0000,0xEDCA,0x0000,0xEDD1,0x0506,0x027E,0x0135,0x00A9,0x005A,0x002C,0x0013, 0x0007,0x0001,0x0003,0x0000,0xEDD0,0x0000,0xB9E8,0x0006,0x0003,0x0000,0xD6EC,0x0001,0xB4A1,0x0003,0x0001,0xC0F9, 0x0001,0xEDC5,0x000E,0x0008,0x0004,0x0002,0xEDC3,0xEDC2,0x0002,0xEDC1,0xD4D2,0x0003,0x0000,0xC9E9,0x0001,0xC6C6, 0x0006,0x0003,0x0001,0xC5DA,0x0001,0xC5E9,0x0001,0x0002,0xEDBE,0xEDC7,0x0016,0x000B,0x0004,0x0001,0x0000,0xEDC9, 0x0004,0x0002,0xD5E8,0xEDCE,0x0000,0xEDC6,0x0004,0x0000,0x0000,0xEDC8,0x0003,0x0000,0xEDC4,0x0002,0xEDC0,0xEDBF, 0x000D,0x0006,0x0003,0x0001,0xD1E2,0x0001,0xEDBB,0x0004,0x0002,0xEDBA,0xD7A9,0x0001,0xD1D0,0x0006,0x0003,0x0001, 0xC5F8,0x0000,0xEDBC,0x0001,0x0002,0xBFB3,0xC6F6,0x002A,0x0016,0x0008,0x0004,0x0001,0x0000,0xEDB9,0x0001,0x0000, 0xC0F7,0x0007,0x0003,0x0001,0xC9B0,0x0002,0xC2EB,0xEDB8,0x0004,0x0002,0xBFF3,0xB7AF,0x0000,0xCEF9,0x0008,0x0004, 0x0001,0x0001,0xEDB7,0x0000,0x0001,0xEDB6,0x0004,0x0000,0x0000,0xCAAF,0x0004,0x0002,0xBDC3,0xB0AB,0x0002,0xB6CC, 0xEFF3,0x0017,0x000C,0x0006,0x0003,0x0000,0xBDC3,0x0000,0xBED8,0x0003,0x0000,0xEFF2,0x0000,0xD6AA,0x0005,0x0000, 0x0002,0xD2D3,0xCAB8,0x0003,0x0001,0xDADC,0x0001,0xF1E6,0x0009,0x0005,0x0000,0x0002,0xC3AC,0xD6F5,0x0000,0x0000, 0xB4A3,0x0001,0x0001,0x0000,0xDBC7,0x0045,0x0020,0x000D,0x0005,0x0001,0x0000,0x0000,0xC3C9,0x0001,0x0003,0x0000, 0xF6C4,0x0002,0xEEAD,0xEDFA,0x0008,0x0004,0x0000,0x0000,0xD5B0,0x0001,0x0000,0xEEAC,0x0006,0x0003,0x0000,0xCDAB, 0x0001,0xEEAB,0x0001,0x0002,0xC1CB,0xCBB2,0x0017,0x000C,0x0006,0x0003,0x0001,0xB5C9,0x0000,0xD6F5,0x0003,0x0000, 0xC7C6,0x0000,0xC6B3,0x0006,0x0003,0x0001,0xDEAB,0x0001,0xEEAA,0x0000,0x0002,0xEEA9,0xC2F7,0x0001,0x0006,0x0003, 0x0001,0xC2F7,0x0000,0xEEA8,0x0003,0x0001,0xCFB9,0x0002,0xEEA4,0xEEA7,0x001D,0x0013,0x0008,0x0001,0x0003,0x0000, 0xC3D0,0x0002,0xB3F2,0xC3E9,0x0004,0x0001,0x0001,0xEEA6,0x0004,0x0002,0xEEA3,0xD8BA,0x0000,0xEEA5,0x0005,0x0000, 0x0001,0x0000,0xB6C3,0x0001,0x0001,0x0001,0xB2C7,0x001B,0x000D,0x0007,0x0004,0x0002,0xBDDE,0xD8BA,0x0001,0xEDFE, 0x0003,0x0001,0xC4C0,0x0000,0xEEA2,0x0008,0x0004,0x0002,0xB6BD,0xEEA1,0x0002,0xCBAF,0xBEEC,0x0003,0x0001,0xEDF9, 0x0001,0xD5F6,0x0006,0x0000,0x0000,0x0002,0xBEA6,0xEDFD,0x0005,0x0001,0x0002,0xEDFA,0xEDF9,0x0000,0x0000,0xC0A7, 0x00AC,0x004C,0x002D,0x0014,0x0007,0x0003,0x0000,0xB6ED,0x0000,0x0001,0xEDFB,0x0007,0x0004,0x0002,0xC7C6,0xEDFC, 0x0001,0xD5F6,0x0003,0x0000,0xD7C5,0x0000,0xD6DA,0x000F,0x0007,0x0003,0x0000,0xD1DB,0x0002,0xCCF7,0xEBDE,0x0004, 0x0002,0xEDF8,0xBEEC,0x0002,0xBFF4,0xEDF7,0x0004,0x0000,0x0000,0xD1A3,0x0003,0x0001,0xC3D0,0x0001,0xEDF5,0x0014, 0x000B,0x0004,0x0001,0x0001,0xD1A3,0x0003,0x0000,0xD5A3,0x0002,0xEDF6,0xEDF6,0x0004,0x0001,0x0000,0xEDF3,0x0000, 0x0002,0xC3DF,0xD5E6,0x0006,0x0000,0x0001,0x0002,0xEDF2,0xEDF4,0x0001,0x0001,0x0001,0xEDEE,0x002E,0x0016,0x000C, 0x0007,0x0003,0x0001,0xBFB4,0x0002,0xEBA3,0xC3BC,0x0000,0x0002,0xEDF1,0xEDF0,0x0006,0x0003,0x0000,0xEDED,0x0001, 0xCAA1,0x0001,0x0000,0xB6DC,0x000A,0x0006,0x0003,0x0000,0xC5CE,0x0001,0xEDEF,0x0000,0x0000,0xCFE0,0x0008,0x0004, 0x0002,0xD6B1,0xC3A4,0x0002,0xC3A4,0xEDEC,0x0003,0x0001,0xB6A2,0x0000,0xC4BF,0x0017,0x000A,0x0004,0x0001,0x0000, 0xB5B4,0x0003,0x0001,0xC2AC,0x0001,0xEEC2,0x0007,0x0004,0x0002,0xC5CC,0xBCE0,0x0001,0xBEA1,0x0003,0x0001,0xC3CB, 0x0000,0xD5B5,0x000C,0x0005,0x0000,0x0002,0xB5C1,0xCAA2,0x0004,0x0002,0xC5CC,0xB5C1,0x0000,0xB8C7,0x0007,0x0003, 0x0000,0xBFF8,0x0002,0xBAD0,0xBCE0,0x0004,0x0002,0xD1CE,0xD5B5,0x0002,0xB0BB,0xEEC1,0x0043,0x002A,0x0015,0x000B, 0x0004,0x0001,0x0000,0xD2E6,0x0003,0x0000,0xD3AF,0x0002,0xC5E8,0xD6D1,0x0006,0x0003,0x0001,0xB1AD,0x0000,0xD3DB, 0x0000,0x0001,0xC3F3,0x0008,0x0004,0x0001,0x0000,0xD6E5,0x0000,0x0000,0xF1E4,0x0007,0x0003,0x0000,0xF1E5,0x0002, 0xF1E4,0xD6E5,0x0003,0x0000,0xF0E5,0x0000,0xC6A4,0x0006,0x0001,0x0000,0x0000,0x0000,0xF0AB,0x0009,0x0005,0x0001, 0x0002,0xB0A8,0xCEFA,0x0001,0x0000,0xCDEE,0x0006,0x0003,0x0001,0xF0A9,0x0001,0xB0A8,0x0001,0x0000,0xF0A8,0x002D, 0x0017,0x000B,0x0004,0x0000,0x0001,0xB8DE,0x0004,0x0002,0xF0A7,0xBBCA,0x0000,0xBDD4,0x0007,0x0003,0x0000,0xB5C4, 0x0002,0xD4ED,0xD4ED,0x0001,0x0002,0xB0D9,0xB0D7,0x0009,0x0005,0x0000,0x0002,0xB7A2,0xB5C7,0x0000,0x0000,0xB9EF, 0x0005,0x0001,0x0002,0xF1B2,0xCCB1,0x0004,0x0002,0xD3B8,0xF1B3,0x0002,0xF1AB,0xF1A8,0x0019,0x000B,0x0007,0x0004, 0x0002,0xD1A2,0xF1B2,0x0001,0xF1AE,0x0001,0x0001,0xD6A2,0x0008,0x0004,0x0002,0xF0DC,0xD1A2,0x0002,0xD1F7,0xB3D5, 0x0003,0x0001,0xB1F1,0x0000,0xF1AE,0x000A,0x0004,0x0000,0x0000,0xF1B0,0x0003,0x0000,0xF0DD,0x0000,0xF1B1,0x0006, 0x0003,0x0000,0xF1AF,0x0000,0xD3FA,0x0001,0x0001,0xF1AD,0x0169,0x00BA,0x005C,0x0029,0x0016,0x000A,0x0003,0x0000, 0xB0A9,0x0003,0x0000,0xF0F7,0x0002,0xF0EF,0xF0EC,0x0005,0x0001,0x0002,0xF1AA,0xC1C6,0x0003,0x0001,0xF1A5,0x0002, 0xF1A8,0xF1AB,0x0008,0x0004,0x0000,0x0001,0xF1A2,0x0000,0x0001,0xC8B3,0x0007,0x0004,0x0002,0xF1A9,0xD5CE,0x0000, 0xF1AC,0x0000,0x0001,0xF1A7,0x001D,0x000E,0x0007,0x0003,0x0000,0xF1A6,0x0002,0xCCB1,0xB1F1,0x0003,0x0000,0xB4F1, 0x0002,0xC5B1,0xCADD,0x0007,0x0004,0x0002,0xF0FB,0xC1F6,0x0001,0xF1A3,0x0004,0x0002,0xB4AF,0xF1A4,0x0002,0xCEC1, 0xF0F9,0x000C,0x0004,0x0001,0x0000,0xF1A1,0x0004,0x0002,0xF0FE,0xF0FC,0x0002,0xF0F9,0xE0B3,0x0006,0x0003,0x0000, 0xF0FD,0x0000,0xBBBE,0x0000,0x0001,0xF0F5,0x0031,0x001B,0x000D,0x0008,0x0004,0x0002,0xD1F1,0xF0F8,0x0002,0xB7E8, 0xF0FA,0x0000,0x0002,0xD3FA,0xF1A1,0x0006,0x0003,0x0000,0xF0F7,0x0000,0xF0F1,0x0004,0x0002,0xB4E1,0xF0F6,0x0002, 0xF0F4,0xF0E2,0x000A,0x0006,0x0003,0x0001,0xF0F3,0x0001,0xB1D4,0x0000,0x0000,0xB1D4,0x0007,0x0003,0x0001,0xB3D5, 0x0002,0xC2E9,0xC2E9,0x0000,0x0002,0xF0F2,0xCCB5,0x0017,0x000C,0x0005,0x0001,0x0002,0xF0EF,0xBBBE,0x0003,0x0001, 0xF0EC,0x0002,0xF0F0,0xF0ED,0x0007,0x0003,0x0001,0xF0EE,0x0002,0xF0EB,0xC1A1,0x0001,0x0001,0xC6A6,0x000B,0x0004, 0x0001,0x0000,0xCDB4,0x0004,0x0002,0xBEB7,0xB6BB,0x0001,0xF0E9,0x0007,0x0004,0x0002,0xBADB,0xD6CC,0x0001,0xD1F7, 0x0000,0x0001,0xBBD7,0x0065,0x0037,0x001D,0x000E,0x0007,0x0004,0x0002,0xF0EA,0xB6B2,0x0001,0xC8AC,0x0004,0x0002, 0xBEB7,0xD3B8,0x0000,0xD6A2,0x0008,0x0004,0x0002,0xB2A1,0xF0E4,0x0002,0xF0E7,0xF0E8,0x0003,0x0000,0xDAE7,0x0002, 0xF0F2,0xBCB2,0x000A,0x0005,0x0000,0x0002,0xBED2,0xCCDB,0x0000,0x0002,0xD5EE,0xF0E3,0x0008,0x0004,0x0002,0xB4C3, 0xF0E2,0x0002,0xF0E1,0xC6A3,0x0004,0x0002,0xF0E5,0xF0E6,0x0002,0xB7E8,0xB4AF,0x0015,0x0007,0x0000,0x0003,0x0001, 0xF0DF,0x0000,0xD2DF,0x0007,0x0004,0x0002,0xBDEA,0xB0CC,0x0000,0xF0E0,0x0004,0x0002,0xD1F1,0xF0DD,0x0000,0xC5B1, 0x000D,0x0006,0x0003,0x0000,0xF0DE,0x0001,0xBECE,0x0003,0x0000,0xB8ED,0x0002,0xC1C6,0xF0DC,0x0006,0x0003,0x0001, 0xF0DB,0x0001,0xF0DA,0x0003,0x0000,0xD2C9,0x0000,0xCAE8,0x0024,0x0012,0x000A,0x0005,0x0001,0x0002,0xF1E2,0xB5FE, 0x0001,0x0002,0xB3EB,0xBDAE,0x0004,0x0001,0x0000,0xEEB6,0x0001,0x0000,0xE7DC,0x0008,0x0001,0x0004,0x0002,0xEEB5, 0xBBFB,0x0001,0xB5B1,0x0006,0x0003,0x0001,0xB3EB,0x0001,0xEEB4,0x0000,0x0001,0xD2EC,0x0011,0x0009,0x0005,0x0001, 0x0002,0xBBAD,0xB7AC,0x0001,0x0001,0xC6E8,0x0000,0x0003,0x0000,0xC2D4,0x0002,0xB4F0,0xB1CF,0x000C,0x0008,0x0004, 0x0002,0xC4B6,0xD0F3,0x0002,0xEEB3,0xDBCE,0x0000,0x0000,0xC1F4,0x0004,0x0000,0x0001,0xC5CF,0x0001,0x0002,0xCEB7, 0xEEB0,0x00A2,0x005D,0x002D,0x0014,0x000A,0x0006,0x0003,0x0001,0xBDE7,0x0000,0xEEB1,0x0000,0x0001,0xEEB2,0x0004, 0x0000,0x0000,0xB3A9,0x0003,0x0001,0xEEAF,0x0001,0xE7DE,0x000B,0x0005,0x0001,0x0002,0xBBAD,0xEEAE,0x0003,0x0001, 0xB5E9,0x0000,0xC4D0,0x0007,0x0003,0x0000,0xB5E7,0x0002,0xC9EA,0xBCD7,0x0004,0x0002,0xD3C9,0xCCEF,0x0000,0xE5B8, 0x0019,0x000F,0x0008,0x0004,0x0002,0xB1C2,0xF0AE,0x0002,0xB8A6,0xBDC7,0x0004,0x0002,0xCBA6,0xD3C3,0x0001,0xCBD5, 0x0006,0x0003,0x0000,0xC9FB,0x0001,0xB2FA,0x0001,0x0000,0xC9FA,0x000B,0x0006,0x0003,0x0001,0xCCF0,0x0001,0xC9F5, 0x0000,0x0002,0xDFB0,0xB8CA,0x0006,0x0003,0x0000,0xCECD,0x0000,0xEAB6,0x0003,0x0000,0xEAB5,0x0000,0xEAB4,0x001D, 0x000E,0x0006,0x0000,0x0000,0x0002,0xDDF9,0xEAB1,0x0004,0x0000,0x0001,0xD5E7,0x0001,0x0000,0xEAB3,0x0006,0x0001, 0x0001,0x0002,0xB4C9,0xC6BF,0x0004,0x0000,0x0001,0xEAB2,0x0001,0x0002,0xEAB1,0xCECD,0x0014,0x0007,0x0001,0x0003, 0x0001,0xB8D7,0x0001,0xCDDF,0x0007,0x0003,0x0001,0xC8BF,0x0002,0xB0EA,0xC6B0,0x0003,0x0001,0xF0AD,0x0001,0xF0AC, 0x000A,0x0006,0x0003,0x0001,0xB9CF,0x0001,0xE8B6,0x0001,0x0001,0xCFE2,0x0006,0x0003,0x0001,0xE8AC,0x0001,0xE8B6, 0x0001,0x0000,0xE7E7,0x0033,0x0016,0x000A,0x0005,0x0000,0x0001,0x0001,0xC7ED,0x0001,0x0001,0x0000,0xE8AF,0x0007, 0x0000,0x0003,0x0000,0xE7F4,0x0001,0xE8B7,0x0001,0x0000,0x0001,0xBBB7,0x0011,0x0009,0x0001,0x0004,0x0002,0xE8B3, 0xE8B2,0x0002,0xE8B5,0xE8A8,0x0004,0x0001,0x0000,0xE7E1,0x0001,0x0001,0xE8B1,0x0005,0x0000,0x0000,0x0001,0xE8AB, 0x0001,0x0003,0x0001,0xE8B4,0x0001,0xE8AC,0x0023,0x0015,0x000A,0x0004,0x0001,0x0000,0xE8B0,0x0003,0x0000,0xE7F6, 0x0000,0xE8AF,0x0004,0x0001,0x0000,0xC1A7,0x0004,0x0002,0xE8AE,0xE8AD,0x0001,0xE8AA,0x0006,0x0001,0x0001,0x0002, 0xE8A8,0xD1FE,0x0001,0x0004,0x0002,0xD5F2,0xB9E5,0x0000,0xC0C5,0x0015,0x000A,0x0006,0x0003,0x0000,0xE8A9,0x0001, 0xC2EA,0x0000,0x0000,0xD3A8,0x0006,0x0003,0x0001,0xD1FE,0x0000,0xCBF6,0x0001,0x0002,0xC9AA,0xC8F0,0x000D,0x0007, 0x0003,0x0001,0xE8A4,0x0002,0xE7F8,0xBAF7,0x0003,0x0000,0xE8A7,0x0000,0xE8A5,0x0000,0x0000,0x0000,0xE8A6,0x0267, 0x0123,0x0087,0x0045,0x0022,0x000C,0x0005,0x0000,0x0001,0x0001,0xE7E2,0x0001,0x0003,0x0001,0xE8A3,0x0001,0xE7F5, 0x0008,0x0004,0x0001,0x0000,0xC7ED,0x0000,0x0000,0xB7A9,0x0008,0x0004,0x0002,0xC5C3,0xC5FD,0x0002,0xC7D9,0xC1D5, 0x0003,0x0001,0xB5F1,0x0000,0xE7FC,0x0015,0x000C,0x0006,0x0003,0x0000,0xE7FD,0x0000,0xE7FE,0x0003,0x0000,0xE7F7, 0x0000,0xE7FB,0x0005,0x0000,0x0002,0xE7F9,0xE7FA,0x0000,0x0000,0xD7C1,0x0008,0x0004,0x0001,0x0001,0xE8A1,0x0000, 0x0000,0xE8A2,0x0001,0x0001,0x0002,0xCBF6,0xE7F6,0x001E,0x0014,0x0009,0x0004,0x0000,0x0001,0xC1A7,0x0000,0x0002, 0xE7F0,0xC1F0,0x0007,0x0004,0x0002,0xC0ED,0xC0C5,0x0001,0xC7F2,0x0000,0x0001,0xE8AF,0x0005,0x0000,0x0000,0x0000, 0xCFD6,0x0001,0x0000,0x0000,0xE7F5,0x0014,0x000C,0x0005,0x0000,0x0002,0xC5E5,0xB0E0,0x0004,0x0002,0xB9E7,0xE7F1, 0x0001,0xE7F2,0x0004,0x0000,0x0001,0xE7ED,0x0001,0x0000,0xD6E9,0x0008,0x0004,0x0000,0x0000,0xE7F3,0x0000,0x0001, 0xE7EE,0x0001,0x0003,0x0001,0xE7E7,0x0002,0xB7A9,0xE7E5,0x004D,0x0028,0x0012,0x000B,0x0004,0x0000,0x0001,0xD5E4, 0x0004,0x0002,0xC9BA,0xE7EB,0x0000,0xE7EC,0x0001,0x0003,0x0000,0xE7E6,0x0000,0xE7EA,0x000B,0x0005,0x0001,0x0002, 0xB4C3,0xB2A3,0x0003,0x0000,0xE7F4,0x0001,0xE7E8,0x0004,0x0001,0x0001,0xE7E9,0x0003,0x0000,0xC1E1,0x0002,0xCFD6, 0xBBB7,0x0016,0x000C,0x0006,0x0003,0x0000,0xE7E2,0x0001,0xC3B5,0x0003,0x0001,0xCDE6,0x0000,0xE7E5,0x0004,0x0000, 0x0000,0xBEF6,0x0003,0x0000,0xE7E3,0x0001,0xE7E4,0x0005,0x0000,0x0001,0x0001,0xC2EA,0x0006,0x0003,0x0000,0xBEC1, 0x0000,0xEECB,0x0000,0x0001,0xE7E1,0x0030,0x0017,0x000C,0x0006,0x0003,0x0000,0xE7E0,0x0001,0xCDF5,0x0003,0x0001, 0xD3F1,0x0001,0xC2CA,0x0007,0x0004,0x0002,0xD7C8,0xC3EE,0x0000,0xD0FE,0x0001,0x0000,0xE2A4,0x000E,0x0007,0x0003, 0x0000,0xE2B5,0x0002,0xE2A8,0xCFD7,0x0003,0x0000,0xCCA1,0x0002,0xCADE,0xE1EE,0x0004,0x0000,0x0001,0xC1D4,0x0003, 0x0000,0xBBF1,0x0002,0xC4FC,0xE2B4,0x0013,0x000E,0x0008,0x0004,0x0002,0xE2A8,0xCCA1,0x0002,0xE2B3,0xE1FD,0x0003, 0x0000,0xE1F6,0x0000,0xB6C0,0x0001,0x0001,0x0000,0xE2B2,0x0005,0x0001,0x0001,0x0001,0xE2B1,0x0001,0x0003,0x0000, 0xE9E1,0x0000,0xE2AF,0x00A5,0x0056,0x0026,0x000F,0x0006,0x0000,0x0002,0xBDB1,0x0000,0xE2B0,0x0005,0x0001,0x0002, 0xCAA8,0xD3FC,0x0000,0x0000,0xB4F4,0x000C,0x0005,0x0000,0x0002,0xD4B3,0xBBAB,0x0003,0x0000,0xE1F8,0x0002,0xE2AA, 0xE2AD,0x0007,0x0004,0x0002,0xE9E0,0xD3CC,0x0001,0xBAEF,0x0001,0x0000,0xE2AE,0x0017,0x000D,0x0006,0x0003,0x0001, 0xCFD7,0x0001,0xE2AC,0x0004,0x0002,0xC3A8,0xD6ED,0x0000,0xD0C9,0x0004,0x0001,0x0000,0xE2AB,0x0003,0x0001,0xE2A9, 0x0000,0xE2A4,0x000D,0x0007,0x0003,0x0001,0xE2A6,0x0002,0xE2A7,0xB2C2,0x0003,0x0000,0xC3CD,0x0000,0xD5F8,0x0007, 0x0004,0x0002,0xE2A2,0xB2FE,0x0000,0xE2A8,0x0000,0x0002,0xE2A3,0xF7D0,0x002A,0x000F,0x0008,0x0004,0x0000,0x0001, 0xC1D4,0x0000,0x0001,0xE2A5,0x0001,0x0003,0x0000,0xE1FD,0x0000,0xE1FB,0x000D,0x0005,0x0001,0x0002,0xB1B7,0xC0C7, 0x0004,0x0002,0xE2A1,0xE1FE,0x0002,0xCFC1,0xC0EA,0x0006,0x0003,0x0000,0xE1FA,0x0001,0xE1F9,0x0004,0x0002,0xE1FC, 0xE1F8,0x0002,0xD3FC,0xD5F8,0x0013,0x000D,0x0008,0x0004,0x0002,0xE1F6,0xCAA8,0x0002,0xCFC1,0xB6C0,0x0001,0x0002, 0xE1F7,0xE1F5,0x0001,0x0001,0x0002,0xBDC6,0xBADD,0x0008,0x0004,0x0000,0x0001,0xC4FC,0x0001,0x0000,0xBED1,0x0004, 0x0000,0x0000,0xB9B7,0x0003,0x0001,0xE1F4,0x0001,0xBAFC,0x0048,0x0028,0x0017,0x000B,0x0007,0x0003,0x0001,0xE1F2, 0x0002,0xE1F3,0xD0C9,0x0001,0x0001,0xB1B7,0x0004,0x0001,0x0001,0xB5D2,0x0004,0x0002,0xE1F0,0xBFF1,0x0002,0xE1F1, 0xD7B4,0x0006,0x0001,0x0001,0x0002,0xD3CC,0xE1EF,0x0007,0x0004,0x0002,0xE1EE,0xD7B4,0x0001,0xE1ED,0x0001,0x0001, 0xE1EC,0x0010,0x0008,0x0000,0x0003,0x0000,0xB7B8,0x0002,0xE1EB,0xC8AE,0x0004,0x0000,0x0000,0xCEFE,0x0000,0x0001, 0xB6BF,0x0005,0x0000,0x0000,0x0000,0xEAF1,0x0004,0x0000,0x0001,0xDCFD,0x0004,0x0002,0xDBBB,0xEAFB,0x0000,0xEAF8, 0x002C,0x0016,0x000B,0x0006,0x0003,0x0000,0xEAFA,0x0000,0xEAF9,0x0000,0x0002,0xEAF8,0xB6BF,0x0006,0x0003,0x0001, 0xCCD8,0x0001,0xEAF7,0x0001,0x0002,0xC0E7,0xCFAC,0x000D,0x0007,0x0004,0x0002,0xEAF6,0xEAF5,0x0000,0xC7A3,0x0003, 0x0001,0xCEFE,0x0000,0xCCD8,0x0005,0x0001,0x0002,0xC7A3,0xB5D6,0x0000,0x0001,0xC9FC,0x0016,0x0009,0x0005,0x0000, 0x0002,0xEAF4,0xEAF0,0x0001,0x0000,0xCEEF,0x0005,0x0000,0x0002,0xC4C1,0xEAF3,0x0004,0x0002,0xC8CD,0xC0CE,0x0002, 0xC4B5,0xCBFC,0x000D,0x0006,0x0003,0x0000,0xC4B2,0x0000,0xEAF2,0x0003,0x0000,0xC5A3,0x0002,0xD1C0,0xEBB9,0x0004, 0x0000,0x0001,0xEBBB,0x0000,0x0001,0xEBBA,0x011F,0x008B,0x0049,0x002F,0x0015,0x000A,0x0005,0x0002,0xF1BE,0x0001, 0xEBB9,0x0000,0x0002,0xC5C6,0xBCE3,0x0007,0x0004,0x0002,0xB0E6,0xC6AC,0x0000,0xC7BD,0x0001,0x0001,0xBFC2,0x000E, 0x0007,0x0003,0x0001,0xE3DD,0x0002,0xB6FB,0xCBAC,0x0003,0x0001,0xD8B3,0x0002,0xD2AF,0xB5F9,0x0008,0x0004,0x0002, 0xB0D6,0xD2AF,0x0002,0xB8B8,0xBEF4,0x0001,0x0001,0xB0AE,0x0011,0x000C,0x0006,0x0003,0x0000,0xEBBC,0x0001,0xD5F9, 0x0003,0x0000,0xC5C0,0x0000,0xD7A6,0x0000,0x0000,0x0000,0xECE0,0x0000,0x0004,0x0001,0x0001,0xECDF,0x0000,0x0001, 0xC0C3,0x001C,0x000C,0x0007,0x0000,0x0003,0x0000,0xC2AF,0x0001,0xCBB8,0x0000,0x0001,0x0000,0xB1AC,0x000B,0x0004, 0x0001,0x0000,0xECE2,0x0004,0x0002,0xBDFD,0xD1AC,0x0001,0xECDE,0x0001,0x0000,0x0000,0xBBE2,0x0011,0x0009,0x0005, 0x0001,0x0002,0xDBC6,0xD6F2,0x0000,0x0000,0xBBD9,0x0000,0x0003,0x0001,0xECDD,0x0002,0xB2D3,0xD4EF,0x000B,0x0005, 0x0000,0x0002,0xECDB,0xD3AA,0x0003,0x0000,0xECCB,0x0001,0xCCCC,0x0004,0x0001,0x0001,0xD1E0,0x0003,0x0000,0xECDC, 0x0000,0xC9D5,0x0045,0x0027,0x0015,0x000A,0x0006,0x0003,0x0000,0xC1D7,0x0000,0xC1C7,0x0001,0x0001,0xECC0,0x0004, 0x0000,0x0000,0xB5C6,0x0004,0x0002,0xD1E6,0xC8BC,0x0001,0xECC7,0x0008,0x0004,0x0001,0x0000,0xB3E3,0x0001,0x0001, 0xECE4,0x0004,0x0001,0x0001,0xECD8,0x0003,0x0001,0xECD7,0x0001,0xC8C8,0x000A,0x0005,0x0001,0x0000,0x0000,0xB0BE, 0x0000,0x0000,0x0000,0xECD9,0x0009,0x0005,0x0000,0x0002,0xECDA,0xCAEC,0x0001,0x0001,0xCEF5,0x0005,0x0000,0x0002, 0xECD6,0xECC1,0x0003,0x0000,0xC8DB,0x0000,0xD3AB,0x001F,0x000D,0x0008,0x0004,0x0000,0x0001,0xD1AC,0x0001,0x0000, 0xD0DC,0x0001,0x0000,0x0000,0xCFA8,0x0008,0x0004,0x0001,0x0001,0xC9BF,0x0001,0x0000,0xECD5,0x0004,0x0000,0x0000, 0xECD4,0x0003,0x0001,0xECCE,0x0000,0xECD2,0x0019,0x000A,0x0004,0x0001,0x0000,0xD6F3,0x0003,0x0000,0xECBE,0x0001, 0xB7B3,0x0008,0x0004,0x0002,0xECD0,0xD5D5,0x0002,0xECE3,0xBBC0,0x0004,0x0002,0xC3BA,0xC8E0,0x0000,0xDCE4,0x000D, 0x0007,0x0004,0x0002,0xD5A8,0xDFDC,0x0000,0xC9B7,0x0003,0x0000,0xECCF,0x0001,0xD1CC,0x0004,0x0001,0x0000,0xC5AF, 0x0003,0x0000,0xC9BC,0x0000,0xECBF,0x0086,0x003D,0x001B,0x0012,0x000B,0x0004,0x0001,0x0000,0xBCE5,0x0003,0x0000, 0xBBCD,0x0002,0xECD3,0xC1B6,0x0000,0x0003,0x0001,0xBBD4,0x0001,0xECD1,0x0001,0x0004,0x0001,0x0000,0xC8BB,0x0001, 0x0001,0xECCD,0x000E,0x0006,0x0000,0x0000,0x0002,0xD1E6,0xECCC,0x0004,0x0001,0x0000,0xBDB9,0x0001,0x0001,0xCEDE, 0x0009,0x0004,0x0000,0x0000,0xB4E3,0x0001,0x0002,0xB7D9,0xB1BA,0x0007,0x0003,0x0000,0xECE2,0x0002,0xECCB,0xBBC0, 0x0000,0x0001,0xECCA,0x0021,0x0011,0x0009,0x0004,0x0000,0x0000,0xECC9,0x0001,0x0002,0xBAB8,0xD1C9,0x0004,0x0001, 0x0000,0xE4B8,0x0000,0x0000,0xD1AC,0x0008,0x0004,0x0001,0x0001,0xB7E9,0x0001,0x0001,0xC5EB,0x0004,0x0000,0x0001, 0xCDE9,0x0000,0x0000,0xCCFE,0x0019,0x000E,0x0007,0x0004,0x0002,0xE2D2,0xCFA9,0x0001,0xC8C8,0x0004,0x0002,0xBDFD, 0xCCCC,0x0001,0xBBE2,0x0007,0x0004,0x0002,0xECC7,0xC9D5,0x0000,0xB7B3,0x0000,0x0000,0xBFBE,0x000A,0x0004,0x0000, 0x0001,0xD1CC,0x0003,0x0001,0xD6F2,0x0001,0xC0D3,0x0000,0x0000,0x0000,0xBAE6,0x0054,0x002E,0x0015,0x000A,0x0004, 0x0000,0x0001,0xCEDA,0x0003,0x0001,0xD0DD,0x0000,0xECC8,0x0004,0x0000,0x0000,0xC1D2,0x0003,0x0001,0xCCFE,0x0002, 0xC0C3,0xCBB8,0x000E,0x0006,0x0003,0x0000,0xECC3,0x0001,0xB3E3,0x0004,0x0002,0xC1B6,0xECC2,0x0002,0xCEAA,0xB5E3, 0x0005,0x0000,0x0002,0xD5A8,0xECC4,0x0003,0x0001,0xB1FE,0x0001,0xECC6,0x0011,0x000C,0x0007,0x0003,0x0001,0xBEBC, 0x0002,0xC5DA,0xCCBF,0x0000,0x0002,0xBEE6,0xECC5,0x0001,0x0000,0x0000,0xD5D5,0x000A,0x0004,0x0001,0x0001,0xECC1, 0x0003,0x0000,0xECBF,0x0001,0xD6CB,0x0005,0x0001,0x0002,0xECC0,0xBFBB,0x0003,0x0000,0xC8B2,0x0000,0xB3B4,0x0025, 0x000E,0x0009,0x0004,0x0001,0x0000,0xD1D7,0x0001,0x0002,0xB4B6,0xC2AF,0x0000,0x0001,0x0001,0xEAC1,0x000C,0x0008, 0x0004,0x0002,0xECBE,0xB2D3,0x0002,0xD4D6,0xD4D6,0x0000,0x0000,0xD7C6,0x0007,0x0003,0x0000,0xBEC4,0x0002,0xD4EE, 0xC1E9,0x0000,0x0000,0xBAE6,0x0012,0x000C,0x0007,0x0004,0x0002,0xBBD2,0xB5C6,0x0001,0xC3F0,0x0000,0x0002,0xECE1, 0xBBF0,0x0001,0x0000,0x0002,0xC2D0,0xCDE5,0x0006,0x0000,0x0001,0x0002,0xE5B1,0xE5B0,0x0006,0x0003,0x0000,0xCCB2, 0x0001,0xC0EC,0x0001,0x0001,0xC8F7,0x09EA,0x0541,0x0265,0x011A,0x0087,0x0042,0x001E,0x000F,0x0008,0x0004,0x0001, 0x0000,0xE5B0,0x0000,0x0001,0xB9E0,0x0001,0x0003,0x0001,0xE4DC,0x0000,0xE3E3,0x0005,0x0000,0x0001,0x0001,0xC0BD, 0x0004,0x0000,0x0000,0xE5AE,0x0003,0x0000,0xE5AF,0x0001,0xE4F2,0x000F,0x0005,0x0000,0x0000,0x0001,0xC3D6,0x0006, 0x0003,0x0001,0xE4FE,0x0000,0xE3F1,0x0001,0x0000,0xE5AC,0x000D,0x0006,0x0003,0x0001,0xE4EB,0x0000,0xE4EC,0x0003, 0x0000,0xC1A4,0x0002,0xE5AD,0xE5AB,0x0004,0x0000,0x0001,0xE3F2,0x0000,0x0000,0xB1F4,0x001C,0x0011,0x000A,0x0006, 0x0003,0x0000,0xC6D9,0x0000,0xE4AF,0x0001,0x0000,0xC9F2,0x0000,0x0003,0x0000,0xD0BA,0x0001,0xE4C2,0x0000,0x0004, 0x0001,0x0001,0xC2CB,0x0003,0x0001,0xE3F8,0x0001,0xBDA6,0x0013,0x000E,0x0008,0x0004,0x0002,0xB1F5,0xCEAB,0x0002, 0xE5AA,0xE5A7,0x0003,0x0001,0xBFA3,0x0000,0xC0C4,0x0001,0x0000,0x0001,0xCCCE,0x000C,0x0008,0x0004,0x0002,0xE5A6, 0xE5A9,0x0002,0xBCC3,0xE5A8,0x0001,0x0000,0xC3C9,0x0004,0x0000,0x0001,0xC5A2,0x0003,0x0000,0xCAAA,0x0001,0xB1F4, 0x003D,0x001E,0x000E,0x0005,0x0000,0x0000,0x0000,0xE4FE,0x0004,0x0000,0x0000,0xE5A1,0x0001,0x0002,0xC5A8,0xE5A5, 0x0006,0x0000,0x0000,0x0002,0xD7C7,0xBCA4,0x0006,0x0003,0x0000,0xE5A3,0x0001,0xE5A4,0x0001,0x0000,0xB0C4,0x0011, 0x0007,0x0000,0x0003,0x0000,0xB5ED,0x0001,0xE4AB,0x0006,0x0003,0x0000,0xEDB4,0x0000,0xE5A2,0x0000,0x0001,0xD4F3, 0x0009,0x0005,0x0000,0x0002,0xD4E8,0xE4C5,0x0000,0x0001,0xC0BD,0x0000,0x0001,0x0000,0xBDA7,0x002F,0x0017,0x0009, 0x0004,0x0001,0x0001,0xC5EC,0x0000,0x0002,0xE4F8,0xE4F9,0x0008,0x0004,0x0002,0xE4F7,0xB3BA,0x0002,0xC0D4,0xBDBD, 0x0003,0x0001,0xB3CE,0x0001,0xB3CE,0x000C,0x0006,0x0003,0x0001,0xC9AC,0x0000,0xE4B6,0x0003,0x0001,0xE4FC,0x0001, 0xE4FD,0x0006,0x0003,0x0001,0xE4FA,0x0000,0xE4E4,0x0003,0x0001,0xE4F3,0x0001,0xE4FB,0x0015,0x000B,0x0007,0x0003, 0x0001,0xC0A3,0x0002,0xE4B1,0xB3B1,0x0000,0x0000,0xCCB6,0x0004,0x0001,0x0001,0xC1CA,0x0003,0x0001,0xC8F3,0x0001, 0xE4EA,0x000A,0x0004,0x0001,0x0001,0xC2BA,0x0003,0x0001,0xC7B1,0x0000,0xC7B1,0x0004,0x0000,0x0001,0xC5CB,0x0000, 0x0001,0xBDE0,0x00AD,0x0056,0x0028,0x0011,0x0009,0x0003,0x0000,0xC6C3,0x0003,0x0001,0xCEAB,0x0001,0xE4F2,0x0004, 0x0001,0x0001,0xE4EC,0x0000,0x0000,0xE4EB,0x000C,0x0006,0x0003,0x0001,0xF2A3,0x0001,0xBDAC,0x0003,0x0000,0xD1FA, 0x0000,0xB4DD,0x0004,0x0001,0x0000,0xBDA5,0x0004,0x0002,0xE4F1,0xE4D3,0x0001,0xD5C4,0x001C,0x000E,0x0007,0x0004, 0x0002,0xD5C7,0xCAFE,0x0001,0xE4F0,0x0003,0x0001,0xE4DD,0x0002,0xD7D5,0xC2FE,0x0007,0x0004,0x0002,0xE4F4,0xE4F6, 0x0001,0xB8C9,0x0003,0x0001,0xCDDD,0x0002,0xE4ED,0xC1B0,0x0007,0x0000,0x0003,0x0000,0xBABA,0x0000,0xC4AE,0x0004, 0x0000,0x0000,0xC5BD,0x0003,0x0001,0xE4EE,0x0002,0xD1DD,0xC0EC,0x0025,0x000F,0x0005,0x0000,0x0001,0x0001,0xC2A9, 0x0004,0x0000,0x0001,0xE4F5,0x0003,0x0000,0xC6E1,0x0001,0xBCC5,0x000B,0x0007,0x0004,0x0002,0xC6AF,0xD3E6,0x0001, 0xC2FA,0x0000,0x0000,0xB9F6,0x0007,0x0003,0x0001,0xE4EF,0x0002,0xE4B0,0xC2B1,0x0001,0x0000,0xB5CE,0x0017,0x000A, 0x0006,0x0003,0x0000,0xC9F8,0x0001,0xD6CD,0x0001,0x0000,0xBBA6,0x0006,0x0003,0x0001,0xCCB2,0x0000,0xB1F5,0x0004, 0x0002,0xC2D0,0xC0C4,0x0000,0xC2CB,0x000E,0x0008,0x0004,0x0002,0xE4DE,0xC2FA,0x0002,0xE4DC,0xE4D9,0x0003,0x0000, 0xD6CD,0x0000,0xE0C6,0x0006,0x0003,0x0000,0xB9F6,0x0001,0xE4E4,0x0003,0x0001,0xEBF8,0x0002,0xCCCF,0xD7D2,0x005E, 0x0032,0x001A,0x000D,0x0006,0x0003,0x0001,0xBBAC,0x0001,0xE4E6,0x0003,0x0000,0xDCFE,0x0002,0xB5D3,0xD7CC,0x0007, 0x0003,0x0000,0xC6FB,0x0002,0xB8E4,0xB5E1,0x0003,0x0001,0xC3F0,0x0000,0xB2D7,0x000C,0x0005,0x0000,0x0002,0xE4E8, 0xB3FC,0x0003,0x0001,0xE4E1,0x0002,0xCAAA,0xE4E2,0x0006,0x0003,0x0000,0xC4E7,0x0001,0xE4E3,0x0003,0x0000,0xC8DC, 0x0000,0xE4E5,0x0015,0x000B,0x0007,0x0004,0x0002,0xE4D1,0xE4DA,0x0001,0xCBDD,0x0001,0x0001,0xCEC2,0x0006,0x0003, 0x0000,0xCFAA,0x0001,0xE4E0,0x0000,0x0001,0xE4DF,0x000D,0x0006,0x0003,0x0000,0xD2E7,0x0001,0xE4E9,0x0004,0x0002, 0xE4D1,0xB9B5,0x0000,0xC1EF,0x0004,0x0001,0x0000,0xE4DB,0x0003,0x0000,0xD7BC,0x0001,0xD5B3,0x001C,0x0013,0x0006, 0x0000,0x0001,0x0002,0xD4B4,0xE4E7,0x0006,0x0003,0x0001,0xB8C8,0x0000,0xE3ED,0x0004,0x0002,0xE4D3,0xBDA6,0x0001, 0xC0A3,0x0000,0x0004,0x0001,0x0001,0xCAAA,0x0000,0x0000,0xCDE5,0x000F,0x000A,0x0004,0x0001,0x0001,0xCCC0,0x0003, 0x0000,0xE4CE,0x0001,0xE4D0,0x0000,0x0001,0x0001,0xD3BF,0x000A,0x0004,0x0001,0x0001,0xE4D2,0x0003,0x0000,0xE4A5, 0x0001,0xD5BF,0x0004,0x0001,0x0000,0xCFE6,0x0003,0x0000,0xBAFE,0x0002,0xE4D5,0xE4D4,0x015A,0x00B1,0x0056,0x0021, 0x000F,0x0007,0x0001,0x0003,0x0001,0xE4CF,0x0000,0xCDC4,0x0004,0x0000,0x0001,0xB4D5,0x0001,0x0001,0xE4D8,0x0008, 0x0004,0x0000,0x0000,0xC5C8,0x0000,0x0001,0xBBEB,0x0006,0x0003,0x0001,0xC3EC,0x0001,0xD3CE,0x0001,0x0001,0xBFCA, 0x001C,0x000F,0x0007,0x0004,0x0002,0xB6FD,0xE4D6,0x0001,0xD1CD,0x0004,0x0002,0xB8DB,0xBACA,0x0002,0xCEBC,0xB2E2, 0x0006,0x0003,0x0000,0xE4CD,0x0000,0xCEC2,0x0003,0x0001,0xCED0,0x0002,0xE4D7,0xB2B3,0x000B,0x0007,0x0003,0x0000, 0xD4FC,0x0002,0xB6C9,0xC7FE,0x0001,0x0000,0xD3E5,0x0007,0x0004,0x0002,0xBCF5,0xE4BE,0x0000,0xBBC1,0x0004,0x0002, 0xC9F8,0xE4C9,0x0001,0xD3E6,0x0027,0x0014,0x000C,0x0005,0x0001,0x0002,0xE4C5,0xBDA5,0x0003,0x0001,0xE4C2,0x0002, 0xD7D5,0xE4CB,0x0004,0x0000,0x0001,0xD4A8,0x0001,0x0000,0xC7E5,0x0005,0x0001,0x0001,0x0001,0xEDB5,0x0007,0x0004, 0x0002,0xCCED,0xC7B3,0x0000,0xD1CD,0x0004,0x0002,0xBBEC,0xE4B5,0x0000,0xD4A8,0x001C,0x000E,0x0007,0x0003,0x0000, 0xB4BE,0x0002,0xC9EE,0xEEBD,0x0004,0x0002,0xD3FD,0xBBB4,0x0001,0xB4E3,0x0008,0x0004,0x0002,0xD2F9,0xC2D9,0x0002, 0xC1E8,0xBEBB,0x0003,0x0001,0xE4C6,0x0001,0xD3D9,0x000C,0x0005,0x0001,0x0002,0xB5AD,0xE4C4,0x0003,0x0001,0xE4C1, 0x0002,0xE4C7,0xB7EB,0x0008,0x0004,0x0002,0xE4C0,0xC0E1,0x0002,0xE4C8,0xCCD4,0x0000,0x0001,0xC4D7,0x0059,0x002A, 0x0016,0x000A,0x0006,0x0003,0x0001,0xC6E0,0x0000,0xCAE7,0x0001,0x0001,0xCCCA,0x0004,0x0000,0x0000,0xC1DC,0x0004, 0x0002,0xE4BF,0xCFFD,0x0002,0xE4C0,0xD7CD,0x000C,0x0006,0x0003,0x0001,0xB5C3,0x0001,0xB5ED,0x0003,0x0000,0xE4C3, 0x0001,0xC1B9,0x0004,0x0001,0x0001,0xBAD4,0x0001,0x0000,0xBAAD,0x0018,0x0009,0x0004,0x0000,0x0001,0xD2BA,0x0000, 0x0002,0xD1C4,0xE4CC,0x0008,0x0004,0x0002,0xE4CA,0xB8A2,0x0002,0xC9AC,0xD5C7,0x0004,0x0002,0xBDA7,0xC8F3,0x0001, 0xB5D3,0x000E,0x0007,0x0003,0x0000,0xBBC1,0x0002,0xCED0,0xE4B6,0x0004,0x0002,0xC1B0,0xE4B5,0x0000,0xC0D4,0x0004, 0x0000,0x0000,0xCCCE,0x0001,0x0002,0xCCE9,0xE4B9,0x002A,0x0017,0x000C,0x0006,0x0003,0x0000,0xE4B8,0x0000,0xE4B3, 0x0003,0x0001,0xCFD1,0x0001,0xD3BF,0x0005,0x0001,0x0002,0xC9E6,0xCFFB,0x0003,0x0000,0xE3FE,0x0000,0xC4F9,0x0008, 0x0004,0x0000,0x0001,0xCDBF,0x0001,0x0001,0xE4BC,0x0005,0x0001,0x0002,0xE4A4,0xBDFE,0x0003,0x0000,0xBAA3,0x0001, 0xD4A1,0x0010,0x0006,0x0001,0x0000,0x0002,0xE4B4,0xB8A1,0x0006,0x0003,0x0001,0xC0CB,0x0000,0xBAC6,0x0000,0x0001, 0xC6D6,0x000C,0x0006,0x0003,0x0000,0xE4BD,0x0001,0xE4BB,0x0003,0x0001,0xE4B7,0x0001,0xE4BA,0x0006,0x0003,0x0001, 0xBFA3,0x0000,0xD5E3,0x0001,0x0001,0xE4B1,0x00C0,0x005E,0x0036,0x001C,0x000E,0x0007,0x0004,0x0002,0xC5A8,0xE4B0, 0x0000,0xBBEB,0x0004,0x0002,0xE4AF,0xBCC3,0x0000,0xE4AB,0x0007,0x0004,0x0002,0xB2E2,0xD7C7,0x0001,0xE4A5,0x0004, 0x0002,0xBDBD,0xBDAC,0x0000,0xC7B3,0x000E,0x0006,0x0003,0x0000,0xE4A4,0x0000,0xC1F7,0x0004,0x0002,0xCEDB,0xC5C9, 0x0002,0xC7A2,0xCDDD,0x0006,0x0003,0x0000,0xBBEE,0x0000,0xE4A1,0x0003,0x0001,0xD0DA,0x0000,0xE4AD,0x0018,0x000B, 0x0007,0x0004,0x0002,0xE4B2,0xD6DE,0x0000,0xB6FD,0x0000,0x0001,0xE4AC,0x0007,0x0004,0x0002,0xE4AA,0xBAE9,0x0000, 0xD0B9,0x0003,0x0000,0xE4A2,0x0000,0xBDF2,0x0005,0x0001,0x0000,0x0001,0xB6B4,0x0007,0x0004,0x0002,0xC2E5,0xE4AE, 0x0000,0xE4A8,0x0000,0x0000,0xCFB4,0x002F,0x0015,0x000A,0x0004,0x0000,0x0001,0xC8F7,0x0003,0x0001,0xE4A9,0x0001, 0xE4A3,0x0005,0x0000,0x0002,0xD1F3,0xBCF6,0x0003,0x0000,0xE4A6,0x0001,0xE4A7,0x000C,0x0005,0x0001,0x0002,0xBDE0, 0xB0E3,0x0003,0x0001,0xE3FE,0x0002,0xD4F3,0xC6C3,0x0007,0x0004,0x0002,0xD0BA,0xE3F8,0x0001,0xE3F2,0x0004,0x0002, 0xE3F1,0xEDB4,0x0000,0xB1C3,0x0019,0x000E,0x0007,0x0003,0x0000,0xD3BE,0x0002,0xE3F3,0xCCA9,0x0004,0x0002,0xE3FD, 0xE3FA,0x0000,0xE8F5,0x0007,0x0004,0x0002,0xE3F9,0xC0E1,0x0001,0xD7A2,0x0001,0x0000,0xC4E0,0x000E,0x0008,0x0004, 0x0002,0xC6FC,0xB2A8,0x0002,0xC5DD,0xE3F6,0x0003,0x0001,0xC5A2,0x0000,0xCBDD,0x0004,0x0000,0x0000,0xB7BA,0x0004, 0x0002,0xE3F4,0xE3F7,0x0002,0xB7A8,0xE3EF,0x0061,0x002D,0x0019,0x000C,0x0006,0x0003,0x0000,0xE3FC,0x0001,0xE3EE, 0x0003,0x0000,0xC9E6,0x0001,0xC3DA,0x0006,0x0003,0x0001,0xB2B4,0x0000,0xC8AA,0x0003,0x0001,0xD2E7,0x0002,0xC7F6, 0xD0B9,0x000C,0x0004,0x0001,0x0000,0xBFF6,0x0004,0x0002,0xD1D8,0xD5B4,0x0002,0xB9C1,0xD5D3,0x0000,0x0003,0x0000, 0xD6CE,0x0002,0xD3CD,0xB7D0,0x001C,0x000D,0x0007,0x0004,0x0002,0xBAD3,0xE3F5,0x0000,0xE3FB,0x0003,0x0001,0xBEDA, 0x0000,0xE3F0,0x0007,0x0004,0x0002,0xC4AD,0xBBA6,0x0000,0xE3ED,0x0004,0x0002,0xB2D7,0xC2D9,0x0002,0xC1A4,0xC5BD, 0x000C,0x0006,0x0003,0x0000,0xE3E3,0x0000,0xC3BB,0x0003,0x0000,0xB9B5,0x0001,0xE3FA,0x0006,0x0003,0x0000,0xC5E6, 0x0000,0xC9B3,0x0003,0x0001,0xB3E5,0x0001,0xE3E6,0x0033,0x001A,0x000E,0x0007,0x0004,0x0002,0xEDB3,0xC3BB,0x0001, 0xE3E5,0x0003,0x0000,0xC6E3,0x0002,0xD9FC,0xE3E7,0x0005,0x0001,0x0002,0xB3C1,0xC9F2,0x0004,0x0002,0xD9F0,0xE3EC, 0x0000,0xE3E4,0x000D,0x0007,0x0004,0x0002,0xCED6,0xD2CA,0x0000,0xC7DF,0x0003,0x0001,0xB7DA,0x0000,0xC6FB,0x0006, 0x0003,0x0001,0xBEF6,0x0000,0xD0DA,0x0003,0x0001,0xE3EB,0x0001,0xE3EA,0x0014,0x0007,0x0000,0x0003,0x0001,0xBCB3, 0x0001,0xCCAD,0x0007,0x0003,0x0001,0xCDF4,0x0002,0xE3E8,0xE3E8,0x0003,0x0000,0xE1A9,0x0001,0xCCC0,0x000D,0x0005, 0x0001,0x0002,0xCEDB,0xB3D8,0x0004,0x0002,0xBDAD,0xB9AF,0x0002,0xC8EA,0xE3E1,0x0006,0x0003,0x0000,0xD1B4,0x0000, 0xCEDB,0x0003,0x0000,0xBAB9,0x0002,0xC9C7,0xE3E0,0x0268,0x0162,0x00B4,0x0061,0x002A,0x0017,0x000A,0x0004,0x0001, 0x0000,0xC3A3,0x0003,0x0000,0xCFAB,0x0000,0xB7BA,0x0007,0x0003,0x0001,0xE5AE,0x0002,0xE3E2,0xBABA,0x0003,0x0001, 0xBBE3,0x0000,0xD9DB,0x000C,0x0005,0x0001,0x0002,0xC7F3,0xD6AD,0x0003,0x0000,0xCDA1,0x0002,0xB7BA,0xD9DB,0x0001, 0x0003,0x0000,0xD3C0,0x0001,0xE3DF,0x001D,0x000E,0x0007,0x0004,0x0002,0xCBAE,0xEBB5,0x0000,0xEBB5,0x0004,0x0002, 0xC7E8,0xC2C8,0x0000,0xB5AA,0x0008,0x0004,0x0002,0xEBB2,0xC7E2,0x0002,0xEBB4,0xEBB2,0x0004,0x0002,0xB0B1,0xD1F5, 0x0000,0xBAA4,0x000C,0x0008,0x0004,0x0002,0xEBB3,0xC6F8,0x0002,0xC7E2,0xEBB1,0x0000,0x0001,0xB7FA,0x0007,0x0003, 0x0001,0xB7D5,0x0002,0xEBB0,0xEBAF,0x0003,0x0000,0xEBAE,0x0002,0xC4CA,0xEBAD,0x002C,0x001A,0x000E,0x0007,0x0004, 0x0002,0xC6F8,0xC3A5,0x0001,0xC3F1,0x0004,0x0002,0xD8B5,0xCACF,0x0001,0xEBAC,0x0004,0x0000,0x0000,0xEBAA,0x0004, 0x0002,0xD5B1,0xEBAA,0x0002,0xEBAB,0xEBA9,0x000A,0x0004,0x0001,0x0000,0xEAF3,0x0003,0x0001,0xEBA7,0x0001,0xEBA6, 0x0004,0x0001,0x0001,0xEBA8,0x0001,0x0001,0xEBA7,0x0013,0x0008,0x0004,0x0000,0x0001,0xEBA5,0x0000,0x0001,0xCCBA, 0x0007,0x0004,0x0002,0xC7F2,0xBAC1,0x0000,0xEBA4,0x0000,0x0001,0xC8DE,0x0005,0x0000,0x0001,0x0001,0xD5B1,0x0007, 0x0003,0x0001,0xC3AB,0x0002,0xB2C5,0xB1D0,0x0004,0x0002,0xC5FE,0xC5FE,0x0002,0xB1D1,0xB1CF,0x005A,0x002F,0x0017, 0x000D,0x0007,0x0004,0x0002,0xB1C8,0xD8B9,0x0000,0xB6BE,0x0003,0x0001,0xC3BF,0x0001,0xC4B8,0x0005,0x0000,0x0002, 0xCEE3,0xCEE3,0x0001,0x0002,0xC5B9,0xD2E3,0x000C,0x0005,0x0001,0x0002,0xECB1,0xBBD9,0x0004,0x0002,0xBBD9,0xB5EE, 0x0001,0xCFFD,0x0006,0x0003,0x0000,0xBFC7,0x0000,0xC9B1,0x0003,0x0001,0xD2F3,0x0001,0xB6CE,0x0014,0x000D,0x0007, 0x0004,0x0002,0xC5B9,0xECAF,0x0000,0xBCDF,0x0003,0x0001,0xE9EB,0x0000,0xE9E7,0x0000,0x0003,0x0001,0xE9E9,0x0000, 0xE9EC,0x000A,0x0006,0x0003,0x0000,0xE9E4,0x0001,0xE9EB,0x0001,0x0000,0xE9E6,0x0006,0x0003,0x0001,0xE9EA,0x0000, 0xE9E9,0x0004,0x0002,0xB2D0,0xD1DA,0x0000,0xD6B3,0x0030,0x0017,0x000A,0x0006,0x0003,0x0001,0xE9E7,0x0000,0xE9E6, 0x0001,0x0001,0xE9E8,0x0007,0x0003,0x0001,0xB2D0,0x0002,0xCAE2,0xD1B3,0x0003,0x0001,0xE9E4,0x0000,0xB4F9,0x000D, 0x0008,0x0004,0x0002,0xE9E5,0xD1EA,0x0002,0xE9E3,0xE9E2,0x0000,0x0002,0xD8B2,0xE9E2,0x0007,0x0004,0x0002,0xBCDF, 0xCBC0,0x0001,0xB4F5,0x0000,0x0002,0xB9E9,0xC0FA,0x0013,0x0008,0x0004,0x0001,0x0000,0xCBEA,0x0001,0x0001,0xF5D8, 0x0004,0x0001,0x0000,0xCDE1,0x0003,0x0001,0xC6E7,0x0002,0xCEE4,0xB2BD,0x000C,0x0008,0x0004,0x0002,0xB4CB,0xD5FD, 0x0002,0xD6B9,0xBBB6,0x0000,0x0001,0xECA3,0x0000,0x0001,0x0001,0xECA8,0x008D,0x0050,0x002D,0x0014,0x0007,0x0001, 0x0003,0x0001,0xC5B7,0x0001,0xCCBE,0x0005,0x0000,0x0002,0xCED8,0xB8E8,0x0004,0x0002,0xC7B8,0xD3E4,0x0002,0xD0AA, 0xECA7,0x000C,0x0007,0x0003,0x0000,0xE4CE,0x0002,0xECA6,0xF2A7,0x0001,0x0002,0xBFB2,0xBFEE,0x0006,0x0003,0x0000, 0xC7D5,0x0001,0xC6DB,0x0003,0x0000,0xECA5,0x0002,0xECA4,0xE0CA,0x0010,0x0008,0x0004,0x0001,0x0001,0xD3FB,0x0000, 0x0000,0xBAC8,0x0004,0x0000,0x0001,0xBFC8,0x0001,0x0000,0xC5B7,0x000E,0x0007,0x0003,0x0001,0xECA3,0x0002,0xD0C0, 0xBBB6,0x0004,0x0002,0xB4CE,0xC7B7,0x0001,0xE8F9,0x0001,0x0001,0x0001,0xE9AD,0x001B,0x000D,0x0008,0x0004,0x0001, 0x0001,0xE8EF,0x0001,0x0000,0xE9A1,0x0000,0x0001,0x0001,0xC8A8,0x0005,0x0000,0x0000,0x0001,0xC0B8,0x0005,0x0001, 0x0002,0xD3A3,0xE8F9,0x0000,0x0001,0xE9B7,0x0011,0x0005,0x0000,0x0001,0x0000,0xE8D0,0x0006,0x0003,0x0001,0xE9B4, 0x0001,0xE8C0,0x0003,0x0001,0xE8D3,0x0000,0xE9C6,0x0009,0x0004,0x0000,0x0000,0xB3F7,0x0001,0x0002,0xE8DD,0xE9DA, 0x0000,0x0003,0x0000,0xE8FC,0x0002,0xE8CE,0xE9B5,0x0037,0x0014,0x0006,0x0000,0x0000,0x0001,0x0000,0xE9D6,0x0006, 0x0000,0x0001,0x0002,0xB9F1,0xE8FE,0x0004,0x0001,0x0000,0xBCF7,0x0000,0x0001,0xC4FB,0x0012,0x0008,0x0004,0x0001, 0x0000,0xE9C4,0x0001,0x0000,0xCCA8,0x0006,0x0003,0x0001,0xC3CA,0x0000,0xE9DF,0x0000,0x0000,0xE9DD,0x0009,0x0005, 0x0001,0x0002,0xE9C9,0xBCEC,0x0000,0x0001,0xE9D1,0x0004,0x0000,0x0001,0xE8ED,0x0001,0x0000,0xE9DE,0x0023,0x0010, 0x000B,0x0004,0x0000,0x0001,0xB5B5,0x0004,0x0002,0xE9DB,0xE9DC,0x0001,0xE9D5,0x0001,0x0000,0x0000,0xE8DF,0x000B, 0x0004,0x0000,0x0001,0xCFAD,0x0004,0x0002,0xE9DD,0xCCB4,0x0001,0xC7C2,0x0004,0x0000,0x0001,0xE9DA,0x0000,0x0000, 0xE9D6,0x000A,0x0005,0x0001,0x0000,0x0000,0xB3F7,0x0000,0x0001,0x0000,0xBAE1,0x000C,0x0006,0x0003,0x0000,0xE9CD, 0x0001,0xCDD6,0x0003,0x0000,0xCFF0,0x0000,0xBBFA,0x0004,0x0001,0x0000,0xE9D3,0x0000,0x0002,0xB3C8,0xE9D9,0x012F, 0x008A,0x0048,0x001F,0x000E,0x0005,0x0001,0x0001,0x0000,0xE9D2,0x0004,0x0001,0x0001,0xC7C5,0x0001,0x0002,0xE8E3, 0xC7C1,0x0005,0x0000,0x0001,0x0000,0xE9CF,0x0005,0x0000,0x0002,0xE9D0,0xE9D7,0x0004,0x0002,0xE8EB,0xCAF7,0x0000, 0xC6D3,0x0011,0x000A,0x0004,0x0000,0x0001,0xE9D4,0x0003,0x0001,0xD3A3,0x0001,0xE9C9,0x0001,0x0003,0x0000,0xBAE1, 0x0000,0xE9D8,0x000A,0x0004,0x0001,0x0001,0xD1F9,0x0003,0x0001,0xC4A3,0x0001,0xD5C1,0x0007,0x0004,0x0002,0xCAE0, 0xE9AB,0x0001,0xC7F3,0x0003,0x0001,0xB1EA,0x0002,0xE9CC,0xE9CB,0x0024,0x000E,0x0009,0x0005,0x0001,0x0002,0xB3B2, 0xC2A5,0x0000,0x0001,0xC1BA,0x0001,0x0000,0x0000,0xB7AE,0x000B,0x0004,0x0000,0x0001,0xE8C8,0x0004,0x0002,0xC0D6, 0xD7AE,0x0001,0xE9C8,0x0007,0x0004,0x0002,0xEFDC,0xB2DB,0x0000,0xB9E6,0x0001,0x0001,0xF4AB,0x0011,0x0008,0x0004, 0x0001,0x0001,0xBDB0,0x0000,0x0000,0xE9CE,0x0004,0x0000,0x0001,0xE9CA,0x0001,0x0002,0xE9A4,0xE8FD,0x0008,0x0001, 0x0003,0x0000,0xD0A8,0x0002,0xE9C6,0xE9C4,0x0000,0x0001,0x0001,0xBCF7,0x004D,0x0027,0x0015,0x0009,0x0005,0x0001, 0x0002,0xE9C0,0xB8DC,0x0001,0x0000,0xBBB1,0x0008,0x0004,0x0002,0xE9B6,0xC7B9,0x0002,0xE9B3,0xB9B9,0x0000,0x0000, 0xE9C3,0x000A,0x0004,0x0001,0x0001,0xC5CC,0x0003,0x0001,0xE9C2,0x0001,0xE8E7,0x0004,0x0001,0x0001,0xE9BD,0x0001, 0x0001,0xC8B6,0x0016,0x0008,0x0004,0x0001,0x0000,0xC1F1,0x0000,0x0001,0xE9C1,0x0007,0x0004,0x0002,0xC8D9,0xE9BF, 0x0001,0xE9BE,0x0003,0x0000,0xE8BF,0x0002,0xD5A5,0xE9BC,0x0007,0x0000,0x0003,0x0000,0xB8C9,0x0000,0xE8EE,0x0005, 0x0001,0x0002,0xB0F1,0xE9BB,0x0001,0x0000,0xE9B0,0x002A,0x0013,0x0007,0x0000,0x0003,0x0001,0xE9C5,0x0000,0xC0C6, 0x0005,0x0000,0x0002,0xE9B1,0xE9C7,0x0003,0x0001,0xE9B7,0x0002,0xE9B5,0xE9B4,0x000C,0x0006,0x0003,0x0000,0xD3DC, 0x0000,0xE9AD,0x0003,0x0000,0xB8C5,0x0000,0xE9AF,0x0004,0x0001,0x0000,0xC2A5,0x0003,0x0001,0xE9BA,0x0002,0xE9B1, 0xBFAC,0x0017,0x000A,0x0004,0x0000,0x0001,0xBCAB,0x0003,0x0001,0xE9A8,0x0001,0xB6DC,0x0007,0x0004,0x0002,0xE8FA, 0xD2B5,0x0001,0xE9AE,0x0003,0x0000,0xB5FA,0x0000,0xE8E5,0x000B,0x0007,0x0004,0x0002,0xE9B8,0xE9B8,0x0001,0xE9B9, 0x0001,0x0000,0xE9AA,0x0005,0x0000,0x0002,0xC0E3,0xE9AC,0x0004,0x0002,0xB3FE,0xC3AF,0x0001,0xE9A5,0x0083,0x003E, 0x0021,0x0010,0x000B,0x0007,0x0003,0x0000,0xE8CE,0x0002,0xD0A8,0xB7E3,0x0000,0x0000,0xCBBC,0x0001,0x0000,0x0000, 0xD1EE,0x0007,0x0001,0x0003,0x0000,0xE9AB,0x0001,0xB4BB,0x0004,0x0000,0x0001,0xB4AA,0x0003,0x0001,0xE9A9,0x0001, 0xBCEA,0x000F,0x000A,0x0006,0x0003,0x0001,0xBCCF,0x0000,0xE9B2,0x0001,0x0000,0xD2AC,0x0000,0x0000,0x0001,0xCDD6, 0x0009,0x0004,0x0001,0x0000,0xE9A1,0x0001,0x0002,0xE8FD,0xE8FC,0x0001,0x0001,0x0001,0xEDD6,0x0021,0x0010,0x0008, 0x0001,0x0003,0x0000,0xBDB7,0x0002,0xE9A7,0xE8E2,0x0000,0x0004,0x0002,0xD7B5,0xD6B2,0x0001,0xE9A3,0x0008,0x0004, 0x0000,0x0001,0xD2CE,0x0000,0x0001,0xE9A4,0x0004,0x0001,0x0000,0xE8FB,0x0000,0x0002,0xB9D7,0xE8FE,0x0013,0x000B, 0x0004,0x0000,0x0001,0xBFC3,0x0004,0x0002,0xC6DC,0xC0E2,0x0000,0xE9A2,0x0004,0x0000,0x0000,0xC9AD,0x0001,0x0001, 0xD5BB,0x0009,0x0004,0x0001,0x0001,0xE9A6,0x0001,0x0002,0xCCC4,0xB6B0,0x0001,0x0003,0x0000,0xC5EF,0x0002,0xBCAC, 0xD4E6,0x004A,0x0020,0x0015,0x000B,0x0005,0x0000,0x0002,0xE8C7,0xD7D8,0x0003,0x0000,0xB0F4,0x0000,0xF3F5,0x0006, 0x0003,0x0001,0xB9F7,0x0001,0xC6E5,0x0000,0x0001,0xC3DE,0x0000,0x0004,0x0001,0x0000,0xC6FA,0x0003,0x0000,0xE8F9, 0x0000,0xBCEC,0x0018,0x000D,0x0006,0x0003,0x0001,0xE8F3,0x0001,0xCAE1,0x0003,0x0000,0xCDD1,0x0002,0xD0B5,0xCCDD, 0x0004,0x0000,0x0001,0xCBF3,0x0003,0x0000,0xB6B9,0x0002,0xC0E6,0xCEE0,0x000A,0x0004,0x0000,0x0000,0xC3CE,0x0003, 0x0000,0xC9D2,0x0001,0xE8C9,0x0004,0x0000,0x0001,0xCCF5,0x0001,0x0001,0xB9A3,0x0021,0x000A,0x0000,0x0005,0x0001, 0x0002,0xE8D9,0xE8F7,0x0001,0x0001,0xE8F4,0x000D,0x0007,0x0004,0x0002,0xB0F0,0xC3B7,0x0001,0xE8E8,0x0003,0x0001, 0xC1BA,0x0001,0xB8CB,0x0004,0x0001,0x0000,0xC6E1,0x0003,0x0001,0xC0C6,0x0001,0xE8F6,0x0014,0x0007,0x0000,0x0003, 0x0000,0xCDB0,0x0000,0xE8F5,0x0006,0x0003,0x0000,0xB1AD,0x0001,0xE8F8,0x0003,0x0001,0xD7AE,0x0002,0xBDB0,0xE8ED, 0x0000,0x0008,0x0004,0x0002,0xE8EB,0xC7C5,0x0002,0xE8E7,0xB5B5,0x0004,0x0002,0xE8E5,0xE8E3,0x0000,0xE8E2,0x0543, 0x029D,0x0159,0x00AD,0x004E,0x0034,0x0019,0x000C,0x0005,0x0001,0x0002,0xE8EA,0xBDDB,0x0003,0x0000,0xBBB8,0x0002, 0xC9A3,0xCDA9,0x0006,0x0003,0x0001,0xE8E4,0x0001,0xD7C0,0x0003,0x0001,0xE8F0,0x0002,0xE8F1,0xB0B8,0x000F,0x0007, 0x0003,0x0001,0xBFF2,0x0002,0xCEA6,0xE8E6,0x0004,0x0002,0xCCD2,0xB9F0,0x0002,0xE8EC,0xE8EE,0x0007,0x0003,0x0001, 0xE8EF,0x0002,0xD4D4,0xB8F1,0x0001,0x0002,0xB8F9,0xBACB,0x0010,0x0009,0x0004,0x0000,0x0000,0xD1F9,0x0000,0x0002, 0xE8E1,0xE8E0,0x0001,0x0003,0x0001,0xD6EA,0x0000,0xE8F2,0x0005,0x0001,0x0001,0x0000,0xD0A3,0x0000,0x0001,0x0000, 0xE8E9,0x002D,0x001C,0x000D,0x0007,0x0004,0x0002,0xC0F5,0xC6DC,0x0001,0xC6F5,0x0003,0x0000,0xCBA8,0x0000,0xCAF7, 0x0007,0x0004,0x0002,0xC0B8,0xE8DD,0x0001,0xE8D3,0x0004,0x0002,0xB6B0,0xE8D0,0x0002,0xE8CE,0xD5BB,0x000A,0x0006, 0x0003,0x0000,0xB1EA,0x0000,0xD5A4,0x0001,0x0001,0xE8D9,0x0000,0x0003,0x0000,0xCAC1,0x0000,0xE8DF,0x0016,0x000C, 0x0005,0x0001,0x0002,0xD5A4,0xB2F1,0x0003,0x0000,0xC1F8,0x0002,0xD6F9,0xE8CD,0x0006,0x0003,0x0000,0xBFC2,0x0001, 0xBCED,0x0001,0x0000,0xE8D1,0x000D,0x0007,0x0003,0x0000,0xF5FD,0x0002,0xB2E9,0xD9DE,0x0003,0x0001,0xE8DC,0x0001, 0xC4FB,0x0008,0x0004,0x0002,0xE9AA,0xD7F5,0x0002,0xE8D8,0xB9F1,0x0003,0x0001,0xE8D6,0x0002,0xE8D4,0xE8CF,0x0057, 0x0024,0x0014,0x000C,0x0004,0x0001,0x0001,0xC8E1,0x0004,0x0002,0xC8BE,0xC6E2,0x0002,0xB8CC,0xC4B3,0x0004,0x0000, 0x0000,0xB0D8,0x0001,0x0001,0xC5CC,0x000A,0x0004,0x0001,0x0001,0xB1FA,0x0003,0x0000,0xE8DA,0x0000,0xE8DE,0x0001, 0x0001,0x0002,0xE8F5,0xE8DB,0x001B,0x000E,0x0008,0x0004,0x0002,0xBCCF,0xBCDC,0x0002,0xE8D5,0xB9D5,0x0003,0x0000, 0xE8D7,0x0001,0xE8D2,0x0006,0x0003,0x0000,0xBFDD,0x0000,0xE8C9,0x0004,0x0002,0xB7E3,0xC7B9,0x0001,0xE8C7,0x000B, 0x0006,0x0003,0x0000,0xE8C5,0x0000,0xE8C0,0x0000,0x0002,0xD4E6,0xCAE0,0x0007,0x0003,0x0001,0xE8C8,0x0002,0xD6A6, 0xB9FB,0x0003,0x0001,0xC3B6,0x0001,0xE8C4,0x0028,0x0016,0x000C,0x0006,0x0003,0x0000,0xC1D6,0x0000,0xD5ED,0x0003, 0x0001,0xE8E2,0x0001,0xCEF6,0x0004,0x0001,0x0001,0xE8FB,0x0003,0x0000,0xE8CA,0x0000,0xCDF7,0x000A,0x0006,0x0003, 0x0000,0xE8C1,0x0001,0xB9B9,0x0001,0x0000,0xBCAB,0x0000,0x0004,0x0002,0xB0E5,0xCBC9,0x0001,0xE8CC,0x001B,0x000E, 0x0006,0x0003,0x0000,0xE8CB,0x0000,0xE8C6,0x0004,0x0002,0xE8C3,0xEABD,0x0002,0xB6AB,0xBDDC,0x0006,0x0003,0x0000, 0xB1AD,0x0000,0xBABC,0x0003,0x0001,0xE8C2,0x0002,0xE8BF,0xD1EE,0x0009,0x0004,0x0001,0x0000,0xC0B4,0x0001,0x0002, 0xCCF5,0xB8DC,0x0000,0x0004,0x0002,0xCAF8,0xE8BD,0x0002,0xC0E9,0xB6C5,0x00B4,0x005D,0x0030,0x0017,0x000A,0x0004, 0x0001,0x0000,0xD5C8,0x0003,0x0001,0xE8BC,0x0001,0xB4E5,0x0007,0x0004,0x0002,0xB2C4,0xD0D3,0x0000,0xC0EE,0x0003, 0x0000,0xE8BB,0x0001,0xC9BC,0x000D,0x0007,0x0003,0x0000,0xE8BE,0x0002,0xB8CB,0xD3DB,0x0003,0x0001,0xC8A8,0x0000, 0xD4D3,0x0007,0x0004,0x0002,0xC9B1,0xCAF8,0x0001,0xD0E0,0x0001,0x0002,0xBBFA,0xF3FE,0x0018,0x000A,0x0004,0x0001, 0x0001,0xB6E4,0x0003,0x0000,0xC6D3,0x0001,0xD6EC,0x0007,0x0003,0x0001,0xCAF5,0x0002,0xCAF5,0xD4FD,0x0004,0x0002, 0xB1BE,0xC4A9,0x0000,0xCEB4,0x000B,0x0007,0x0004,0x0002,0xC4BE,0xEBCA,0x0000,0xEBFC,0x0001,0x0000,0xCDFB,0x0006, 0x0003,0x0001,0xC6DA,0x0001,0xB3AF,0x0000,0x0001,0xCDFB,0x002F,0x0018,0x000B,0x0006,0x0003,0x0001,0xC0CA,0x0001, 0xEBDE,0x0000,0x0002,0xCBB7,0xECF6,0x0006,0x0003,0x0000,0xEBD4,0x0001,0xB7FE,0x0003,0x0001,0xC5F3,0x0002,0xEBC3, 0xD3D0,0x000A,0x0006,0x0003,0x0000,0xD4C2,0x0001,0xEAC2,0x0000,0x0001,0xBBE1,0x0007,0x0004,0x0002,0xD7EE,0xCCE6, 0x0000,0xD4F8,0x0003,0x0000,0xC2FC,0x0001,0xB2DC,0x0016,0x000C,0x0005,0x0000,0x0002,0xCAE9,0xEAC2,0x0004,0x0002, 0xB8FC,0xD2B7,0x0000,0xC7FA,0x0004,0x0000,0x0000,0xD4BB,0x0003,0x0000,0xC9B9,0x0001,0xEAD9,0x0005,0x0000,0x0001, 0x0000,0xEAD8,0x0006,0x0003,0x0000,0xBFF5,0x0001,0xC6D8,0x0004,0x0002,0xEAD7,0xEAD6,0x0001,0xCAEF,0x003D,0x001C, 0x000A,0x0005,0x0000,0x0001,0x0000,0xEAD3,0x0001,0x0001,0x0001,0xCFFE,0x000A,0x0006,0x0003,0x0001,0xEABC,0x0000, 0xC0FA,0x0000,0x0000,0xEACA,0x0004,0x0001,0x0000,0xEAD5,0x0001,0x0001,0xE5DF,0x0011,0x0007,0x0001,0x0003,0x0000, 0xB1A9,0x0001,0xEAC7,0x0004,0x0001,0x0000,0xC4BA,0x0003,0x0001,0xD4DD,0x0000,0xC2F7,0x0009,0x0005,0x0000,0x0002, 0xF4DF,0xEAD3,0x0001,0x0000,0xB3A9,0x0000,0x0003,0x0000,0xF0A9,0x0001,0xEAD4,0x0028,0x0011,0x000A,0x0006,0x0003, 0x0001,0xB0B5,0x0000,0xC5AF,0x0001,0x0001,0xCAEE,0x0001,0x0003,0x0000,0xEAD2,0x0001,0xEACD,0x000B,0x0005,0x0000, 0x0002,0xD4CE,0xCFBE,0x0003,0x0000,0xEAD1,0x0000,0xD4DD,0x0006,0x0003,0x0000,0xCDFA,0x0000,0xC1C0,0x0003,0x0001, 0xB0B5,0x0000,0xD6C7,0x0012,0x000A,0x0006,0x0003,0x0001,0xEAD0,0x0000,0xBEA7,0x0000,0x0000,0xC7E7,0x0000,0x0004, 0x0002,0xCEFA,0xBEB0,0x0000,0xC6D5,0x000D,0x0006,0x0003,0x0000,0xB3BF,0x0000,0xBBDE,0x0003,0x0000,0xCEEE,0x0002, 0xCEFA,0xEACE,0x0006,0x0003,0x0001,0xEAC9,0x0001,0xD6E7,0x0003,0x0000,0xC0A5,0x0000,0xCDED,0x014F,0x00A2,0x0054, 0x002A,0x0017,0x000D,0x0005,0x0001,0x0002,0xEACF,0xEACD,0x0004,0x0002,0xD4CE,0xEACA,0x0002,0xCFFE,0xC9B9,0x0004, 0x0001,0x0000,0xEACC,0x0003,0x0001,0xC9CE,0x0000,0xBDFA,0x0009,0x0004,0x0000,0x0000,0xBDFA,0x0001,0x0002,0xBBCE, 0xCAB1,0x0006,0x0003,0x0000,0xEACB,0x0001,0xCFD4,0x0000,0x0001,0xD6E7,0x0015,0x000B,0x0004,0x0001,0x0001,0xEAC6, 0x0004,0x0002,0xEAC7,0xEAC4,0x0000,0xD2DD,0x0006,0x0003,0x0000,0xEAC5,0x0000,0xCAC7,0x0000,0x0000,0xD5D1,0x000A, 0x0006,0x0003,0x0001,0xD7F2,0x0000,0xC3C1,0x0000,0x0000,0xB4BA,0x0007,0x0004,0x0002,0xEAC5,0xD3B3,0x0000,0xD0C7, 0x0000,0x0000,0xEAC3,0x0028,0x0016,0x000B,0x0004,0x0000,0x0000,0xEABC,0x0004,0x0002,0xEABF,0xCEF4,0x0000,0xD2D7, 0x0005,0x0001,0x0002,0xBBE8,0xC3F7,0x0003,0x0001,0xB2FD,0x0001,0xEABB,0x000A,0x0005,0x0001,0x0002,0xC9FD,0xC0A5, 0x0001,0x0002,0xEABE,0xB0BA,0x0004,0x0000,0x0001,0xEAC0,0x0001,0x0001,0xCDFA,0x0013,0x0006,0x0000,0x0001,0x0002, 0xBFF5,0xCAB1,0x0008,0x0004,0x0002,0xBAB5,0xEABA,0x0002,0xEAB9,0xEAB8,0x0000,0x0002,0xD0F1,0xD1AE,0x000E,0x0008, 0x0004,0x0002,0xD4E7,0xD6BC,0x0002,0xBEC9,0xB5A9,0x0003,0x0000,0xC8D5,0x0001,0xBCC8,0x0000,0x0000,0x0001,0xCEDE, 0x005C,0x002C,0x0015,0x0009,0x0005,0x0001,0x0002,0xC6EC,0xECBD,0x0001,0x0001,0xECBC,0x0005,0x0001,0x0002,0xD7E5, 0xECBB,0x0004,0x0002,0xECBA,0xECBA,0x0000,0xD0FD,0x000C,0x0004,0x0001,0x0001,0xECB7,0x0004,0x0002,0xC2C3,0xECB8, 0x0002,0xECB9,0xC6EC,0x0006,0x0003,0x0000,0xC5D4,0x0000,0xD3CE,0x0000,0x0002,0xCAA9,0xD3DA,0x0019,0x000B,0x0006, 0x0003,0x0000,0xB7BD,0x0000,0xB6CF,0x0001,0x0002,0xC7DB,0xEDBD,0x0007,0x0003,0x0001,0xD0C2,0x0002,0xCBB9,0xEDBD, 0x0004,0x0002,0xB6CF,0xD5B6,0x0000,0xEDBD,0x000B,0x0006,0x0003,0x0000,0xD5B6,0x0000,0xB8AB,0x0000,0x0002,0xB3E2, 0xBDEF,0x0006,0x0003,0x0000,0xCED3,0x0000,0xD5E5,0x0003,0x0001,0xD0B1,0x0000,0xF5FA,0x0026,0x0017,0x000C,0x0006, 0x0003,0x0000,0xC1CF,0x0000,0xB6B7,0x0003,0x0000,0xECB5,0x0000,0xECB5,0x0005,0x0000,0x0002,0xB0DF,0xECB3,0x0003, 0x0001,0xB1F3,0x0000,0xD5AB,0x0009,0x0004,0x0001,0x0000,0xCEC4,0x0001,0x0002,0xB1D0,0xC1B2,0x0001,0x0001,0x0002, 0xE5C4,0xC7FD,0x0018,0x000D,0x0006,0x0003,0x0001,0xCAFD,0x0000,0xB7F3,0x0004,0x0002,0xB5D0,0xD5FB,0x0001,0xC7C3, 0x0004,0x0000,0x0001,0xCAFD,0x0003,0x0001,0xBEB4,0x0002,0xEBB8,0xB6DE,0x0009,0x0004,0x0001,0x0001,0xB6D8,0x0001, 0x0002,0xC9A2,0xB8D2,0x0004,0x0001,0x0001,0xB3A8,0x0003,0x0000,0xB1D6,0x0000,0xC1B2,0x00A6,0x0054,0x0028,0x0016, 0x000C,0x0008,0x0004,0x0002,0xBDCC,0xD0F0,0x0002,0xB0DC,0xB0BD,0x0000,0x0000,0xEBB7,0x0006,0x0003,0x0000,0xBEC8, 0x0000,0xC3F4,0x0000,0x0001,0xB5D0,0x0009,0x0005,0x0000,0x0002,0xF4CD,0xD0A7,0x0000,0x0000,0xB9CA,0x0005,0x0001, 0x0002,0xD5FE,0xB7C5,0x0001,0x0000,0xB9A5,0x001B,0x000F,0x0008,0x0004,0x0002,0xB8C4,0xD8FC,0x0002,0xBFBC,0xCAD5, 0x0004,0x0002,0xEBB6,0xEAB7,0x0001,0xECA5,0x0005,0x0001,0x0002,0xD6A7,0xDFAD,0x0003,0x0001,0xC0BF,0x0002,0xBEF0, 0xBDC1,0x0009,0x0001,0x0004,0x0002,0xDFAC,0xCCAF,0x0002,0xC2CE,0xD4DC,0x0001,0x0004,0x0002,0xC9E3,0xD0AF,0x0000, 0xDFA5,0x0029,0x0012,0x000D,0x0007,0x0004,0x0002,0xB2F3,0xC8C1,0x0001,0xDEFC,0x0003,0x0001,0xC0B9,0x0001,0xD4DC, 0x0000,0x0001,0x0000,0xC2A3,0x000A,0x0006,0x0003,0x0000,0xDFAB,0x0001,0xC4EC,0x0000,0x0001,0xDEF3,0x0006,0x0003, 0x0001,0xC5CA,0x0001,0xC8C5,0x0003,0x0001,0xDFA3,0x0002,0xCBD3,0xB0DA,0x0015,0x000A,0x0004,0x0001,0x0000,0xDFA2, 0x0003,0x0001,0xC0A9,0x0001,0xD6C0,0x0007,0x0004,0x0002,0xB8E9,0xC5A1,0x0000,0xB1F7,0x0000,0x0001,0xC4E2,0x000A, 0x0004,0x0001,0x0001,0xB2C1,0x0003,0x0001,0xDFA9,0x0001,0xDFAA,0x0006,0x0003,0x0001,0xBCB7,0x0001,0xCBD3,0x0001, 0x0001,0xBEDD,0x0066,0x0033,0x0019,0x000C,0x0006,0x0003,0x0001,0xEBA2,0x0000,0xDFA8,0x0003,0x0001,0xB5A3,0x0001, 0xC7DC,0x0006,0x0003,0x0001,0xDFA7,0x0001,0xC7E6,0x0003,0x0000,0xB2D9,0x0002,0xB5B2,0xBBF7,0x000B,0x0004,0x0001, 0x0000,0xD4F1,0x0004,0x0002,0xC9C3,0xC2B0,0x0001,0xC0DE,0x0008,0x0004,0x0002,0xD3B5,0xDFA6,0x0002,0xBCF1,0xCECE, 0x0003,0x0001,0xBAB3,0x0002,0xCCA2,0xDFA5,0x001B,0x000D,0x0006,0x0003,0x0001,0xDFA3,0x0000,0xDFA2,0x0003,0x0000, 0xC4EC,0x0002,0xDEEC,0xC6CB,0x0007,0x0004,0x0002,0xCDD6,0xD7AB,0x0001,0xB4E9,0x0004,0x0002,0xB2A5,0xC7CB,0x0000, 0xB8A7,0x000D,0x0006,0x0003,0x0000,0xC1C3,0x0001,0xB3B6,0x0004,0x0002,0xB2A6,0xB3B7,0x0000,0xB5A7,0x0005,0x0001, 0x0002,0xDED8,0xD7B2,0x0003,0x0001,0xD5FC,0x0001,0xC4ED,0x0026,0x0013,0x000D,0x0006,0x0003,0x0000,0xDFA4,0x0001, 0xDEFE,0x0003,0x0000,0xCBBA,0x0002,0xC4D3,0xC8F6,0x0000,0x0000,0x0002,0xB3C5,0xB3C5,0x000D,0x0006,0x0003,0x0001, 0xC0CC,0x0000,0xC6B2,0x0004,0x0002,0xBEEF,0xDEFC,0x0001,0xC1CC,0x0001,0x0001,0x0002,0xB2F4,0xD5DB,0x0013,0x000B, 0x0007,0x0004,0x0002,0xC4A1,0xC3FE,0x0001,0xDED2,0x0001,0x0000,0xBFD9,0x0004,0x0001,0x0000,0xD6BF,0x0000,0x0000, 0xDEFD,0x0007,0x0000,0x0003,0x0000,0xC4A6,0x0000,0xB4DD,0x0007,0x0003,0x0001,0xD7DC,0x0002,0xC2A7,0xDEFB,0x0000, 0x0001,0xDEE8,0x02E8,0x0172,0x00B7,0x005B,0x002C,0x0012,0x0009,0x0004,0x0001,0x0000,0xD5AA,0x0001,0x0002,0xCBA4, 0xB7EC,0x0005,0x0000,0x0002,0xDEF0,0xDEE2,0x0000,0x0000,0xC7F3,0x000F,0x0007,0x0003,0x0000,0xCCAF,0x0002,0xB1F7, 0xD2A1,0x0004,0x0002,0xB0DA,0xDEF3,0x0002,0xC9E3,0xBFB8,0x0006,0x0003,0x0001,0xDEF4,0x0001,0xEBA1,0x0000,0x0002, 0xD5A5,0xB2EB,0x0015,0x000B,0x0005,0x0000,0x0002,0xD0AF,0xCED5,0x0003,0x0000,0xC7C0,0x0000,0xE5BA,0x0004,0x0001, 0x0001,0xCCCD,0x0003,0x0001,0xB4EE,0x0000,0xB0E1,0x000D,0x0006,0x0003,0x0000,0xCCC2,0x0000,0xCDD8,0x0004,0x0002, 0xDEF9,0xB4B7,0x0000,0xB6F3,0x0006,0x0003,0x0001,0xDEFA,0x0000,0xDEF7,0x0003,0x0000,0xB8E3,0x0002,0xCBD1,0xDEF6, 0x002C,0x0017,0x000B,0x0004,0x0001,0x0001,0xB5B7,0x0003,0x0000,0xD2A1,0x0002,0xC9A6,0xB4EA,0x0005,0x0001,0x0002, 0xB4A4,0xB2AB,0x0003,0x0001,0xCBF0,0x0002,0xDEF8,0xDEF5,0x0009,0x0004,0x0000,0x0001,0xC8B6,0x0000,0x0002,0xB9B9, 0xBDC1,0x0008,0x0004,0x0002,0xC2A7,0xB8E9,0x0002,0xB2F3,0xDEEC,0x0000,0x0001,0xC0BF,0x0019,0x000E,0x0006,0x0003, 0x0001,0xB1B3,0x0000,0xDEEA,0x0004,0x0002,0xDEDE,0xDEE7,0x0002,0xD4AE,0xD0A8,0x0004,0x0000,0x0000,0xDEE9,0x0004, 0x0002,0xBBD3,0xBDD2,0x0001,0xBEBE,0x0009,0x0005,0x0000,0x0002,0xBEBE,0xBFAB,0x0001,0x0001,0xB4A7,0x0006,0x0003, 0x0001,0xCED5,0x0000,0xDEEB,0x0004,0x0002,0xDEEE,0xDFAC,0x0002,0xD1DA,0xBBBB,0x005D,0x002B,0x0014,0x0008,0x0004, 0x0000,0x0000,0xD1EF,0x0000,0x0000,0xD2BE,0x0007,0x0003,0x0000,0xB2E5,0x0002,0xCCE1,0xC3E8,0x0000,0x0002,0xDEEF, 0xD7E1,0x000C,0x0004,0x0000,0x0001,0xC8E0,0x0004,0x0002,0xDEF1,0xD1D0,0x0002,0xDEED,0xBCE3,0x0004,0x0001,0x0000, 0xBCF0,0x0004,0x0002,0xDEF2,0xC5F6,0x0000,0xDEE8,0x0017,0x000C,0x0007,0x0003,0x0000,0xB2F4,0x0002,0xB5A7,0xD6C0, 0x0001,0x0002,0xDEE2,0xC2B0,0x0004,0x0001,0x0000,0xEAFE,0x0004,0x0002,0xDEE7,0xDEDD,0x0000,0xDEE4,0x000E,0x0008, 0x0004,0x0002,0xB4EB,0xD1DA,0x0002,0xCDC6,0xBFD8,0x0003,0x0001,0xBDD3,0x0001,0xB3B8,0x0007,0x0004,0x0002,0xCCBD, 0xB2C9,0x0000,0xC2D3,0x0003,0x0000,0xD8DF,0x0001,0xB9D2,0x002F,0x0017,0x000A,0x0006,0x0003,0x0001,0xD5F5,0x0000, 0xBEF2,0x0000,0x0000,0xD2B4,0x0007,0x0003,0x0000,0xC5C5,0x0002,0xC6FE,0xCCCD,0x0003,0x0000,0xDEE1,0x0000,0xD5C6, 0x000D,0x0008,0x0004,0x0002,0xDEE5,0xB5F4,0x0002,0xCADA,0xB6DE,0x0001,0x0002,0xC2D5,0xC9A8,0x0006,0x0003,0x0000, 0xB5E0,0x0000,0xCFC6,0x0001,0x0002,0xC5B2,0xC4ED,0x0017,0x000B,0x0006,0x0003,0x0000,0xDEE0,0x0001,0xBDDD,0x0000, 0x0002,0xB4B7,0xDED3,0x0005,0x0000,0x0002,0xBEED,0xDEDF,0x0004,0x0002,0xBEDD,0xDEE3,0x0001,0xDED1,0x000D,0x0007, 0x0003,0x0001,0xDEE6,0x0002,0xC9E1,0xC5F5,0x0003,0x0001,0xCDF3,0x0001,0xB5B7,0x0007,0x0004,0x0002,0xBBBB,0xBCF1, 0x0001,0xCBF0,0x0000,0x0000,0xC0CC,0x00B3,0x0058,0x002E,0x0013,0x0007,0x0001,0x0003,0x0001,0xB9CE,0x0000,0xB2B6, 0x0004,0x0001,0x0001,0xBEE8,0x0004,0x0002,0xC4F3,0xC9D3,0x0002,0xBAB4,0xB0C6,0x000D,0x0006,0x0003,0x0000,0xDEDB, 0x0000,0xD7BD,0x0003,0x0001,0xC0A6,0x0002,0xCDB1,0xBEC8,0x0007,0x0004,0x0002,0xDEDC,0xCEE6,0x0000,0xBDC1,0x0003, 0x0001,0xD0AE,0x0002,0xCDEC,0xC5B2,0x000F,0x0007,0x0000,0x0003,0x0001,0xCDA6,0x0000,0xDEDA,0x0004,0x0000,0x0001, 0xEAFD,0x0000,0x0000,0xD5F1,0x000C,0x0007,0x0004,0x0002,0xB4EC,0xC5B2,0x0001,0xB0A4,0x0001,0x0002,0xBBD3,0xBCB7, 0x0008,0x0004,0x0002,0xD5F5,0xDED8,0x0002,0xB5B2,0xC4D3,0x0004,0x0002,0xD0AE,0xCCA2,0x0000,0xCECE,0x002B,0x0014, 0x0009,0x0005,0x0000,0x0002,0xC2CE,0xD6BF,0x0000,0x0001,0xCDDA,0x0005,0x0001,0x0002,0xCCF4,0xC4C3,0x0003,0x0001, 0xBFE6,0x0000,0xD0A3,0x0009,0x0005,0x0001,0x0002,0xB0B4,0xEAFC,0x0000,0x0000,0xD6B8,0x0006,0x0003,0x0001,0xB9D2, 0x0000,0xB3D6,0x0004,0x0002,0xC4C3,0xCAB0,0x0002,0xD7A7,0xC6B4,0x0019,0x000B,0x0004,0x0001,0x0000,0xC0AD,0x0004, 0x0002,0xBFBD,0xDED9,0x0001,0xCBA9,0x0006,0x0003,0x0000,0xC8AD,0x0000,0xB9B0,0x0004,0x0002,0xD5FC,0xDED7,0x0002, 0xCAC3,0xC0A8,0x000C,0x0005,0x0001,0x0002,0xD4F1,0xB2A6,0x0004,0x0002,0xC5A1,0xC0B9,0x0000,0xD3B5,0x0005,0x0000, 0x0002,0xBCF0,0xC2A3,0x0003,0x0000,0xC4E2,0x0001,0xB0DD,0x0064,0x003B,0x001F,0x000F,0x0008,0x0004,0x0002,0xD5D0, 0xDED5,0x0002,0xD7BE,0xBED0,0x0004,0x0002,0xDED6,0xCDCF,0x0001,0xB0CE,0x0008,0x0004,0x0002,0xCDD8,0xBEDC,0x0002, 0xC7AF,0xB9D5,0x0004,0x0002,0xC4C3,0xC1E0,0x0002,0xC5C4,0xB0E8,0x0010,0x0008,0x0004,0x0002,0xC5D7,0xDED4,0x0002, 0xC0AD,0xC4E9,0x0004,0x0002,0xC4B4,0xB2F0,0x0002,0xB5A3,0xD6F4,0x0004,0x0000,0x0001,0xB7F7,0x0004,0x0002,0xC3F2, 0xBDD9,0x0002,0xB3E9,0xD1BA,0x0013,0x000B,0x0006,0x0003,0x0000,0xDED3,0x0000,0xC4A8,0x0001,0x0002,0xB5D6,0xD7A7, 0x0004,0x0001,0x0000,0xB1A7,0x0001,0x0001,0xCCA7,0x000B,0x0006,0x0003,0x0000,0xC5FB,0x0001,0xC5EA,0x0001,0x0002, 0xB1A8,0xBBA4,0x0007,0x0003,0x0001,0xC7C0,0x0002,0xC2D5,0xBFD9,0x0000,0x0000,0xDED2,0x002D,0x0016,0x000E,0x0007, 0x0004,0x0002,0xC5D7,0xB8A7,0x0001,0xD5DB,0x0004,0x0002,0xBFB9,0xB6B6,0x0000,0xCDB6,0x0000,0x0004,0x0002,0xD7A5, 0xCAE3,0x0000,0xD2D6,0x000C,0x0006,0x0003,0x0001,0xB0D1,0x0000,0xBEF1,0x0003,0x0000,0xBFDB,0x0001,0xB3AD,0x0004, 0x0001,0x0001,0xBCBC,0x0004,0x0002,0xB3D0,0xD5D2,0x0001,0xB6F3,0x0019,0x000B,0x0007,0x0004,0x0002,0xE8CE,0xB5D6, 0x0000,0xC5FA,0x0000,0x0001,0xB7F6,0x0006,0x0003,0x0000,0xB0E2,0x0001,0xC8C5,0x0004,0x0002,0xB3B6,0xB0E7,0x0002, 0xC5A4,0xD1EF,0x000E,0x0007,0x0004,0x0002,0xC9A8,0xDED1,0x0000,0xC0A9,0x0004,0x0002,0xD6B4,0xC7A4,0x0001,0xBAB4, 0x0005,0x0000,0x0002,0xBFDB,0xC7A4,0x0003,0x0001,0xDFA6,0x0001,0xCDD0,0x014B,0x00B4,0x005C,0x0030,0x0016,0x0009, 0x0005,0x0002,0xBFB8,0x0001,0xB8ED,0x0000,0x0000,0xCDD0,0x0008,0x0004,0x0002,0xC8D3,0xB4F2,0x0002,0xB0C7,0xC6CB, 0x0001,0x0002,0xD4FA,0xB2C5,0x000C,0x0007,0x0004,0x0002,0xDED0,0xCAD6,0x0001,0xECE9,0x0000,0x0002,0xECE8,0xC9C8, 0x0006,0x0003,0x0001,0xECE7,0x0001,0xB1E2,0x0004,0x0002,0xCBF9,0xB7BF,0x0002,0xECE5,0xECE6,0x0014,0x0007,0x0001, 0x0003,0x0001,0xBBA7,0x0000,0xBBA7,0x0007,0x0004,0x0002,0xB4F7,0xB4C1,0x0000,0xCFB7,0x0003,0x0000,0xD5BD,0x0000, 0xC2BE,0x000D,0x0007,0x0003,0x0000,0xEAAF,0x0002,0xBDD8,0xEAAF,0x0003,0x0001,0xEAA8,0x0001,0xEAAD,0x0007,0x0003, 0x0000,0xEAAE,0x0002,0xEAAB,0xEAAC,0x0000,0x0001,0xEAAA,0x0034,0x001D,0x000E,0x0006,0x0003,0x0001,0xEAA9,0x0000, 0xC6DD,0x0004,0x0002,0xD5BD,0xEAA8,0x0002,0xBBF2,0xE3DE,0x0007,0x0003,0x0000,0xEAA7,0x0002,0xBDE4,0xCED2,0x0004, 0x0002,0xB3C9,0xCFB7,0x0002,0xC8D6,0xCAF9,0x000F,0x0008,0x0004,0x0002,0xD0E7,0xEAA7,0x0002,0xCEEC,0xCEEC,0x0004, 0x0002,0xB8EA,0xEDB0,0x0000,0xEDB0,0x0001,0x0004,0x0002,0xC1B5,0xDCB2,0x0000,0xC9E5,0x0013,0x000E,0x0006,0x0003, 0x0000,0xBEE5,0x0000,0xE2E3,0x0004,0x0002,0xD0FC,0xBBB3,0x0002,0xC0C1,0xE3C2,0x0000,0x0001,0x0000,0xB3CD,0x0007, 0x0001,0x0003,0x0000,0xE2FB,0x0000,0xC5B3,0x0004,0x0000,0x0001,0xEDAF,0x0003,0x0001,0xEDA1,0x0000,0xC3C9,0x0048, 0x0023,0x000C,0x0001,0x0007,0x0003,0x0000,0xE3C1,0x0002,0xC0C1,0xEDAF,0x0001,0x0001,0xE3C1,0x000D,0x0008,0x0004, 0x0002,0xE2F8,0xEDAE,0x0002,0xB0C3,0xD3A6,0x0000,0x0002,0xD0B8,0xBFD2,0x0006,0x0003,0x0001,0xC7DA,0x0000,0xB6AE, 0x0001,0x0000,0xBAB6,0x0011,0x0007,0x0001,0x0003,0x0001,0xE3C0,0x0000,0xD2E4,0x0004,0x0001,0x0000,0xCFDC,0x0003, 0x0001,0xB2D2,0x0000,0xE2E4,0x000C,0x0007,0x0004,0x0002,0xE3BD,0xC3F5,0x0001,0xEDAC,0x0000,0x0002,0xBAA9,0xE3BF, 0x0004,0x0000,0x0000,0xB7DF,0x0001,0x0001,0xEDAD,0x0022,0x0013,0x0005,0x0000,0x0001,0x0000,0xB5AC,0x0007,0x0003, 0x0000,0xE3BE,0x0002,0xE3B4,0xC6BE,0x0003,0x0000,0xC1AF,0x0002,0xD4F7,0xBDBE,0x0007,0x0000,0x0003,0x0001,0xB1EF, 0x0000,0xB1B9,0x0004,0x0001,0x0000,0xD3C7,0x0001,0x0000,0xD3FB,0x0016,0x000B,0x0004,0x0000,0x0000,0xC6DD,0x0003, 0x0001,0xBFB6,0x0002,0xC7EC,0xE3BC,0x0005,0x0000,0x0002,0xC9E5,0xE3A5,0x0003,0x0000,0xCEBF,0x0000,0xC2C7,0x000B, 0x0006,0x0003,0x0001,0xCBCB,0x0000,0xE2E6,0x0000,0x0002,0xBFAE,0xBBDB,0x0006,0x0003,0x0001,0xB9DF,0x0000,0xC2FD, 0x0003,0x0001,0xE2FA,0x0001,0xEDAB,0x00AE,0x004E,0x002E,0x0013,0x000A,0x0004,0x0001,0x0000,0xB2D1,0x0003,0x0000, 0xB2D2,0x0001,0xC4BD,0x0004,0x0001,0x0001,0xC9E5,0x0001,0x0002,0xC9F7,0xE3B3,0x000F,0x0008,0x0004,0x0002,0xBBC5, 0xCCAC,0x0002,0xE3BB,0xD0F3,0x0004,0x0002,0xB4C8,0xD2F3,0x0000,0xE8BA,0x0006,0x0003,0x0000,0xC0F5,0x0001,0xBBEC, 0x0003,0x0001,0xD4B8,0x0000,0xE2E9,0x000A,0x0005,0x0001,0x0000,0x0001,0xE2FD,0x0000,0x0000,0x0000,0xE2EB,0x000C, 0x0005,0x0000,0x0002,0xCBDF,0xE3BA,0x0004,0x0002,0xEDA8,0xC0A2,0x0000,0xE3B4,0x0005,0x0000,0x0002,0xB7DF,0xE3B6, 0x0000,0x0002,0xE3B3,0xB8D0,0x0029,0x0017,0x000B,0x0007,0x0004,0x0002,0xE3AB,0xB0AE,0x0000,0xD3DE,0x0001,0x0001, 0xE3B5,0x0004,0x0000,0x0001,0xCCE8,0x0004,0x0002,0xC3E5,0xD2E2,0x0002,0xE3B9,0xEDAA,0x000A,0x0004,0x0001,0x0001, 0xD3E4,0x0003,0x0000,0xD3FA,0x0000,0xEDA9,0x0004,0x0001,0x0001,0xB3EE,0x0000,0x0000,0xE3B8,0x001E,0x000E,0x0007, 0x0003,0x0001,0xE2FC,0x0002,0xD0CA,0xC8C7,0x0004,0x0002,0xDCE4,0xB4C0,0x0000,0xBBCC,0x0008,0x0004,0x0002,0xE3B7, 0xCFEB,0x0002,0xE3A2,0xC4D5,0x0004,0x0002,0xB6E8,0xB9DF,0x0002,0xB5AC,0xB2D1,0x000E,0x0007,0x0004,0x0002,0xE3AB, 0xB1B9,0x0001,0xB3CD,0x0004,0x0002,0xB2D2,0xBEE5,0x0000,0xB5EB,0x0004,0x0001,0x0001,0xB6F1,0x0004,0x0002,0xBBDD, 0xCEA9,0x0001,0xE3AE,0x0057,0x0028,0x0018,0x000E,0x0008,0x0004,0x0002,0xCFA7,0xC3C6,0x0002,0xE3B1,0xEAA1,0x0003, 0x0000,0xE3AF,0x0001,0xCCE8,0x0006,0x0003,0x0000,0xB5AD,0x0001,0xBBF3,0x0000,0x0001,0xC0B7,0x000B,0x0006,0x0003, 0x0001,0xCDEF,0x0000,0xBEAA,0x0001,0x0002,0xE3B0,0xC7E9,0x0001,0x0001,0x0001,0xC6E0,0x0019,0x000C,0x0005,0x0000, 0x0002,0xB5BF,0xE3AC,0x0003,0x0000,0xBCC2,0x0002,0xC3C6,0xE2EA,0x0007,0x0003,0x0000,0xE3B2,0x0002,0xB1AF,0xE3AD, 0x0003,0x0001,0xC3F5,0x0001,0xE3A5,0x000B,0x0005,0x0000,0x0002,0xD0FC,0xEDA8,0x0003,0x0000,0xC4FA,0x0000,0xD4C3, 0x0004,0x0000,0x0001,0xBBBC,0x0004,0x0002,0xD3C6,0xCEF2,0x0001,0xE3A6,0x002D,0x0016,0x000A,0x0006,0x0003,0x0001, 0xE3AA,0x0000,0xE3A4,0x0001,0x0000,0xE3A3,0x0006,0x0003,0x0000,0xBBDA,0x0000,0xE3A8,0x0003,0x0000,0xCCE8,0x0001, 0xBAB7,0x000C,0x0007,0x0003,0x0000,0xE3A9,0x0002,0xD5DC,0xCFA4,0x0001,0x0002,0xD4A5,0xD4C3,0x0005,0x0000,0x0002, 0xC7C4,0xE3A7,0x0003,0x0001,0xD3C1,0x0001,0xE3A2,0x0019,0x000E,0x0008,0x0004,0x0002,0xC4D5,0xE2FC,0x0002,0xE2FD, 0xE2FB,0x0003,0x0000,0xE2FA,0x0000,0xB6F1,0x0004,0x0000,0x0001,0xBFD2,0x0004,0x0002,0xC7A1,0xCFA2,0x0001,0xB9A7, 0x000F,0x0008,0x0004,0x0002,0xCCF1,0xB6B2,0x0002,0xE3A1,0xB6F7,0x0004,0x0002,0xBADE,0xEDA4,0x0001,0xB3DC,0x0007, 0x0004,0x0002,0xD0F4,0xEDA7,0x0000,0xBBD6,0x0001,0x0001,0xEDA2,0x150C,0x0A08,0x0515,0x02CC,0x0164,0x00B1,0x0052, 0x0029,0x0012,0x0008,0x0004,0x0001,0x0001,0xEDA3,0x0000,0x0000,0xEDA6,0x0006,0x0003,0x0000,0xCBA1,0x0001,0xBAE3, 0x0000,0x0001,0xBFD6,0x000C,0x0006,0x0003,0x0000,0xBBD0,0x0000,0xC1B5,0x0003,0x0000,0xD6BC,0x0001,0xBAE3,0x0005, 0x0001,0x0002,0xCAD1,0xE2FE,0x0003,0x0000,0xEDA5,0x0000,0xE2F8,0x0011,0x0007,0x0000,0x0003,0x0001,0xEDA1,0x0000, 0xD7DC,0x0006,0x0003,0x0000,0xE2F0,0x0000,0xBBD0,0x0001,0x0000,0xC7D3,0x000D,0x0005,0x0001,0x0002,0xE2F6,0xB9D6, 0x0004,0x0002,0xE2F5,0xD4B9,0x0002,0xD0D4,0xE2F1,0x0004,0x0000,0x0000,0xBCB1,0x0004,0x0002,0xE2F9,0xB5A1,0x0001, 0xE6A8,0x0035,0x001B,0x000F,0x0008,0x0004,0x0002,0xCBBC,0xC1AF,0x0002,0xE2F2,0xBDE3,0x0003,0x0000,0xE2EF,0x0002, 0xCCFB,0xB2C0,0x0007,0x0004,0x0002,0xC5C2,0xD5FA,0x0001,0xC5AD,0x0001,0x0002,0xE2F3,0xD4F5,0x000A,0x0006,0x0003, 0x0000,0xE2F4,0x0001,0xE2F7,0x0001,0x0001,0xE2EB,0x0008,0x0004,0x0002,0xE2EA,0xE2E6,0x0002,0xE2E4,0xCBCB,0x0004, 0x0002,0xCCAC,0xBBB3,0x0002,0xB7DE,0xE2E9,0x0014,0x000A,0x0006,0x0003,0x0000,0xBAF6,0x0000,0xD0C3,0x0000,0x0001, 0xE2EE,0x0004,0x0000,0x0000,0xC4EE,0x0003,0x0000,0xB3C0,0x0001,0xE2E5,0x000D,0x0007,0x0003,0x0000,0xE2ED,0x0002, 0xBFEC,0xE2EC,0x0003,0x0001,0xCDE6,0x0000,0xD3C7,0x0004,0x0000,0x0001,0xE2E8,0x0000,0x0002,0xE2E7,0xD6D2,0x0051, 0x002A,0x0017,0x000C,0x0004,0x0000,0x0000,0xE3C3,0x0004,0x0002,0xC3A6,0xCDFC,0x0002,0xD6BE,0xE2E2,0x0004,0x0001, 0x0001,0xDFAF,0x0004,0x0002,0xECFD,0xECFE,0x0000,0xE2E3,0x000B,0x0005,0x0000,0x0002,0xC8CC,0xBCC9,0x0003,0x0000, 0xE2E1,0x0001,0xD2E4,0x0000,0x0004,0x0002,0xB1D8,0xE2E0,0x0000,0xD0C4,0x0014,0x000B,0x0005,0x0000,0x0002,0xBBD5, 0xE1E8,0x0003,0x0000,0xB3B9,0x0000,0xB5C2,0x0004,0x0000,0x0000,0xD5F7,0x0001,0x0002,0xF5E8,0xCEA2,0x000B,0x0006, 0x0003,0x0000,0xE1E6,0x0001,0xD1AD,0x0000,0x0002,0xB8B4,0xE1E5,0x0001,0x0004,0x0002,0xD3F9,0xE1E2,0x0001,0xB4D3, 0x0032,0x0016,0x000B,0x0004,0x0000,0x0001,0xE1E4,0x0004,0x0002,0xE1E3,0xC5C7,0x0000,0xB5C3,0x0006,0x0003,0x0000, 0xE1E2,0x0001,0xCDBD,0x0000,0x0002,0xBEB6,0xD0EC,0x000E,0x0007,0x0003,0x0001,0xBAF3,0x0002,0xC2C9,0xBBB2,0x0004, 0x0002,0xE1E0,0xBADC,0x0000,0xE1DF,0x0007,0x0004,0x0002,0xB4FD,0xBEB6,0x0001,0xE1DE,0x0004,0x0002,0xD5F7,0xCDF9, 0x0000,0xB7F0,0x0017,0x000E,0x0006,0x0003,0x0001,0xB1CB,0x0000,0xB3B9,0x0004,0x0002,0xD2DB,0xE2EC,0x0002,0xE1DD, 0xBCB3,0x0004,0x0001,0x0000,0xE1DC,0x0000,0x0002,0xD3B0,0xD5C3,0x000E,0x0008,0x0004,0x0002,0xC5ED,0xB1F2,0x0002, 0xB5F1,0xB1EB,0x0003,0x0000,0xB2CA,0x0001,0xD1E5,0x0007,0x0004,0x0002,0xD1E5,0xCDAE,0x0001,0xD0CE,0x0000,0x0000, 0xE1EA,0x00B0,0x0057,0x002B,0x0017,0x000A,0x0003,0x0000,0xD2CD,0x0003,0x0001,0xBBE3,0x0002,0xE5E9,0xE5E7,0x0007, 0x0004,0x0002,0xE5E8,0xC2BC,0x0001,0xB5B1,0x0003,0x0000,0xB9E9,0x0000,0xE5E6,0x000C,0x0006,0x0003,0x0000,0xCDE4, 0x0000,0xC3D6,0x0003,0x0000,0xC7BF,0x0000,0xB5AF,0x0004,0x0000,0x0000,0xB1F0,0x0001,0x0000,0xECB0,0x0017,0x000B, 0x0004,0x0001,0x0000,0xE5F6,0x0004,0x0002,0xC7BF,0xB5AF,0x0001,0xC7BF,0x0006,0x0003,0x0001,0xD5C5,0x0001,0xE5F2, 0x0003,0x0001,0xC8F5,0x0001,0xCDE4,0x000B,0x0004,0x0000,0x0001,0xE5F4,0x0004,0x0002,0xE5F2,0xE5F3,0x0001,0xBBA1, 0x0005,0x0000,0x0002,0xCFD2,0xC3D6,0x0001,0x0002,0xD5C5,0xB5DC,0x0030,0x0019,0x000B,0x0006,0x0003,0x0001,0xB0D0, 0x0001,0xB3DA,0x0001,0x0002,0xBAEB,0xB8A5,0x0007,0x0003,0x0001,0xD2FD,0x0002,0xB5F5,0xB9AD,0x0004,0x0002,0xDFB1, 0xDFB1,0x0001,0xCABD,0x000A,0x0004,0x0001,0x0001,0xDFAE,0x0003,0x0000,0xB1D7,0x0000,0xDEC4,0x0005,0x0001,0x0002, 0xC5AA,0xC6FA,0x0004,0x0002,0xD2EC,0xDBCD,0x0002,0xBFAA,0xD8A5,0x0012,0x000A,0x0004,0x0000,0x0000,0xDEC3,0x0003, 0x0000,0xBDA8,0x0001,0xCDA2,0x0000,0x0003,0x0000,0xD1D3,0x0002,0xDBC8,0xCCFC,0x000B,0x0004,0x0001,0x0000,0xC2AE, 0x0004,0x0002,0xE2DE,0xE2DE,0x0000,0xE2DD,0x0004,0x0001,0x0001,0xB9E3,0x0004,0x0002,0xB7CF,0xE2D0,0x0002,0xB3A7, 0xC3ED,0x0059,0x002E,0x0019,0x000C,0x0006,0x0003,0x0001,0xD8CB,0x0001,0xE2DC,0x0003,0x0000,0xB3F8,0x0001,0xD5B1, 0x0008,0x0004,0x0002,0xC1CE,0xD2F1,0x0002,0xC2A5,0xC0AA,0x0000,0x0002,0xE2DA,0xE2DB,0x000C,0x0005,0x0001,0x0002, 0xF5F4,0xCBD1,0x0004,0x0002,0xC0C8,0xC1AE,0x0000,0xCFC3,0x0004,0x0001,0x0000,0xBEC7,0x0000,0x0002,0xCFE1,0xB2DE, 0x0013,0x000B,0x0004,0x0000,0x0000,0xE2D7,0x0003,0x0001,0xE2D5,0x0002,0xD3B9,0xBFB5,0x0000,0x0004,0x0002,0xCAFC, 0xE2D6,0x0001,0xE2D8,0x000C,0x0006,0x0003,0x0001,0xCDA5,0x0001,0xBFE2,0x0003,0x0000,0xE2D1,0x0001,0xD7F9,0x0007, 0x0004,0x0002,0xB6C8,0xE2D3,0x0000,0xD6C5,0x0001,0x0002,0xE2D4,0xB7CF,0x0033,0x001C,0x000D,0x0006,0x0003,0x0000, 0xC5D3,0x0000,0xB8AE,0x0004,0x0002,0xB8FD,0xC3ED,0x0001,0xB5EA,0x0008,0x0004,0x0002,0xE2D2,0xB5D7,0x0002,0xD3A6, 0xBFE2,0x0003,0x0001,0xE2D0,0x0002,0xC2AE,0xD0F2,0x000A,0x0004,0x0001,0x0001,0xE2D1,0x0003,0x0000,0xB4B2,0x0001, 0xB1D3,0x0006,0x0003,0x0000,0xC7EC,0x0000,0xD7AF,0x0003,0x0000,0xB2E0,0x0002,0xE2CF,0xB9E3,0x001B,0x000F,0x0008, 0x0004,0x0002,0xBCB8,0xD3C4,0x0002,0xD3D7,0xBBC3,0x0004,0x0002,0xE7DB,0xB8C9,0x0000,0xD0D2,0x0008,0x0004,0x0002, 0xB2A2,0xBFAA,0x0002,0xC4EA,0xC6BD,0x0000,0x0000,0xB8C9,0x0006,0x0000,0x0001,0x0002,0xE0FC,0xB0EF,0x0004,0x0001, 0x0001,0xB1D2,0x0004,0x0002,0xB4B1,0xE1A6,0x0001,0xD6C4,0x011C,0x00AF,0x004D,0x0025,0x0014,0x000C,0x0005,0x0002, 0xE1A5,0x0001,0xBEB0,0x0003,0x0000,0xE1A4,0x0002,0xC4BB,0xE0FD,0x0000,0x0003,0x0000,0xE0FE,0x0002,0xC4BB,0xE1A3, 0x0005,0x0000,0x0001,0x0001,0xBBCF,0x0005,0x0001,0x0002,0xB7F9,0xE1A2,0x0004,0x0002,0xE0F8,0xC3DD,0x0001,0xD6A1, 0x0016,0x000B,0x0005,0x0001,0x0002,0xC3B1,0xE0FE,0x0003,0x0000,0xE0FD,0x0001,0xB3A3,0x0005,0x0000,0x0002,0xE1A1, 0xB4F8,0x0003,0x0000,0xD5CA,0x0000,0xE0FC,0x000A,0x0006,0x0003,0x0001,0xB0EF,0x0000,0xCFAF,0x0000,0x0000,0xCAA6, 0x0000,0x0004,0x0002,0xD6A1,0xB4F8,0x0000,0xCBA7,0x0030,0x0019,0x000D,0x0005,0x0001,0x0002,0xB5DB,0xD6C4,0x0004, 0x0002,0xB2AF,0xD6E3,0x0002,0xE0F9,0xC1B1,0x0007,0x0003,0x0001,0xCCFB,0x0002,0xC5C1,0xE0FA,0x0001,0x0002,0xE0FB, 0xD5CA,0x000A,0x0006,0x0003,0x0000,0xE0F8,0x0001,0xCFA3,0x0001,0x0001,0xCAA6,0x0006,0x0003,0x0001,0xB7AB,0x0000, 0xCBA7,0x0004,0x0002,0xB2BC,0xCAD0,0x0000,0xB1D2,0x0019,0x000B,0x0007,0x0004,0x0002,0xCAD0,0xBDED,0x0000,0xD9E3, 0x0001,0x0000,0xDAE1,0x0006,0x0003,0x0000,0xCFEF,0x0001,0xB0CD,0x0004,0x0002,0xCBC8,0xD2D1,0x0002,0xBCBA,0xDBCF, 0x000C,0x0005,0x0000,0x0002,0xDBCF,0xB2EE,0x0003,0x0000,0xCED7,0x0002,0xB9AE,0xBEDE,0x0007,0x0004,0x0002,0xC7C9, 0xD7F3,0x0000,0xB9A4,0x0003,0x0001,0xB3B2,0x0000,0xD1B2,0x003C,0x0021,0x0014,0x000A,0x0006,0x0003,0x0001,0xD6DD, 0x0000,0xB4A8,0x0000,0x0000,0xE7DD,0x0006,0x0003,0x0001,0xD1D2,0x0001,0xE1DB,0x0000,0x0001,0xC2CD,0x0008,0x0004, 0x0001,0x0000,0xCEA1,0x0000,0x0000,0xBFF9,0x0000,0x0001,0x0000,0xE1DB,0x0012,0x000B,0x0005,0x0001,0x0002,0xD4C0, 0xD3EC,0x0003,0x0001,0xC1EB,0x0001,0xE1C9,0x0000,0x0003,0x0000,0xE1DA,0x0001,0xE1AE,0x0001,0x0004,0x0000,0x0000, 0xE1BB,0x0001,0x0001,0xE1BD,0x001E,0x000D,0x0008,0x0004,0x0001,0x0000,0xE1D8,0x0001,0x0000,0xE1D7,0x0000,0x0000, 0x0000,0xE1C0,0x0005,0x0001,0x0000,0x0001,0xB4DD,0x0006,0x0003,0x0000,0xE1AB,0x0001,0xD5B8,0x0003,0x0001,0xE1D6, 0x0000,0xE1D0,0x0006,0x0001,0x0000,0x0001,0x0001,0xE1D5,0x0000,0x0006,0x0003,0x0000,0xE1CF,0x0001,0xE1CD,0x0003, 0x0000,0xE1D1,0x0000,0xE1D4,0x0090,0x0040,0x001F,0x0011,0x000A,0x0004,0x0001,0x0000,0xE1D0,0x0003,0x0000,0xE1CE, 0x0001,0xE1C9,0x0001,0x0003,0x0001,0xD1D2,0x0001,0xE1B0,0x0009,0x0004,0x0001,0x0001,0xC7B6,0x0000,0x0002,0xE1D2, 0xE1D3,0x0000,0x0000,0x0000,0xEFFA,0x000C,0x0007,0x0000,0x0003,0x0001,0xE1CA,0x0000,0xE1CC,0x0000,0x0001,0x0001, 0xE1CB,0x000A,0x0006,0x0003,0x0001,0xE1C4,0x0000,0xD5B8,0x0001,0x0000,0xB1C0,0x0007,0x0004,0x0002,0xE1C2,0xE1C3, 0x0001,0xE1C5,0x0000,0x0001,0xE1BF,0x0027,0x0016,0x000B,0x0004,0x0000,0x0001,0xE1C6,0x0004,0x0002,0xE1C8,0xBEFE, 0x0000,0xC2D8,0x0007,0x0004,0x0002,0xB8DA,0xD1C2,0x0001,0xB4DE,0x0001,0x0000,0xC0A5,0x0007,0x0000,0x0003,0x0001, 0xC6E9,0x0000,0xE1C1,0x0005,0x0000,0x0002,0xB3E7,0xE1C7,0x0000,0x0002,0xE1C1,0xE1C0,0x0014,0x000A,0x0006,0x0003, 0x0000,0xF6B9,0x0000,0xCFBF,0x0000,0x0000,0xBEFE,0x0006,0x0003,0x0001,0xB5BA,0x0001,0xE1AD,0x0001,0x0001,0xB7E5, 0x000A,0x0004,0x0001,0x0000,0xC7CD,0x0003,0x0001,0xD3F8,0x0001,0xB6EB,0x0007,0x0003,0x0001,0xC2CD,0x0002,0xE1BF, 0xE1BD,0x0001,0x0000,0xCFBF,0x004A,0x001B,0x000D,0x0008,0x0004,0x0000,0x0001,0xE1CD,0x0001,0x0000,0xD6C5,0x0001, 0x0000,0x0001,0xE1BC,0x0006,0x0001,0x0000,0x0002,0xE1BE,0xB8B7,0x0004,0x0001,0x0001,0xE1BB,0x0001,0x0000,0xE1B9, 0x0016,0x000A,0x0006,0x0003,0x0000,0xBFF9,0x0000,0xE1B4,0x0001,0x0001,0xB0B6,0x0006,0x0003,0x0000,0xE1BA,0x0000, 0xE1B2,0x0003,0x0000,0xD4C0,0x0000,0xE1B7,0x000E,0x0007,0x0003,0x0001,0xCDD3,0x0002,0xC1EB,0xE1B5,0x0003,0x0000, 0xE1B6,0x0002,0xD1D2,0xF6B4,0x0004,0x0001,0x0000,0xDAE9,0x0004,0x0002,0xE1B8,0xE1B3,0x0000,0xB8D4,0x002A,0x001A, 0x000E,0x0006,0x0003,0x0000,0xCFBF,0x0001,0xE1B1,0x0004,0x0002,0xB5BA,0xE1B0,0x0002,0xE1AE,0xE1AD,0x0007,0x0004, 0x0002,0xB8DA,0xE1AB,0x0001,0xB2ED,0x0001,0x0002,0xE1AF,0xE1AA,0x0009,0x0005,0x0001,0x0002,0xE1A9,0xE1A7,0x0001, 0x0001,0xE1AC,0x0001,0x0003,0x0001,0xC6F1,0x0000,0xCBEA,0x000F,0x000A,0x0004,0x0000,0x0000,0xD3EC,0x0003,0x0001, 0xE1A8,0x0000,0xD2D9,0x0001,0x0001,0x0000,0xC9BD,0x000B,0x0007,0x0004,0x0002,0xCDCD,0xE5F8,0x0001,0xCAF4,0x0001, 0x0001,0xE5F0,0x0007,0x0003,0x0001,0xE5F0,0x0002,0xC2C4,0xB2E3,0x0004,0x0002,0xE5EF,0xC2C5,0x0002,0xC2C5,0xCDC0, 0x0284,0x0189,0x00C3,0x005B,0x002E,0x0012,0x000A,0x0004,0x0001,0x0000,0xCAF4,0x0003,0x0000,0xCCEB,0x0001,0xE5ED, 0x0004,0x0001,0x0001,0xD5B9,0x0001,0x0001,0xD0BC,0x000F,0x0008,0x0004,0x0002,0xE5EC,0xC6C1,0x0002,0xCABA,0xCAAC, 0x0003,0x0001,0xCEDD,0x0002,0xBDEC,0xCCEB,0x0008,0x0004,0x0002,0xC7FC,0xBDEC,0x0002,0xBDEC,0xBED3,0x0001,0x0002, 0xB2E3,0xC6A8,0x001B,0x0010,0x0008,0x0004,0x0002,0xBED6,0xC4F2,0x0002,0xCEB2,0xBEA1,0x0004,0x0002,0xC4E1,0xE5EA, 0x0002,0xB3DF,0xD2FC,0x0005,0x0000,0x0002,0xCAAC,0xDECF,0x0003,0x0000,0xDECF,0x0001,0xBECD,0x0005,0x0001,0x0000, 0x0000,0xDECE,0x0007,0x0004,0x0002,0xC5D3,0xD2A2,0x0001,0xDECD,0x0003,0x0000,0xD3C8,0x0000,0xDECC,0x0036,0x001A, 0x000C,0x0006,0x0003,0x0001,0xCFCA,0x0001,0xB3A2,0x0003,0x0000,0xE6D9,0x0000,0xC9D0,0x0007,0x0003,0x0000,0xB3BE, 0x0002,0xBCE2,0xE6D8,0x0003,0x0000,0xB6FB,0x0002,0xB6FB,0xC9D9,0x000E,0x0007,0x0003,0x0001,0xD0A1,0x0002,0xB5BC, 0xB6D4,0x0003,0x0001,0xD1B0,0x0002,0xD7F0,0xCEBE,0x0007,0x0004,0x0002,0xD7A8,0xBDAB,0x0000,0xBDAB,0x0004,0x0002, 0xC9E4,0xB7F3,0x0001,0xB7E2,0x0014,0x000C,0x0004,0x0000,0x0001,0xCAD9,0x0004,0x0002,0xB5BC,0xD1B0,0x0002,0xCBC2, 0xB6D4,0x0000,0x0003,0x0000,0xB4E7,0x0002,0xB1A6,0xB3E8,0x000E,0x0007,0x0004,0x0002,0xE5BE,0xBFA1,0x0000,0xE5BC, 0x0004,0x0002,0xBFED,0xD0B4,0x0001,0xC9F3,0x0008,0x0004,0x0002,0xD5AF,0xC4FE,0x0002,0xCAB5,0xC1C8,0x0004,0x0002, 0xE5BB,0xCEF2,0x0002,0xC7DE,0xB9D1,0x0064,0x0031,0x001A,0x000C,0x0008,0x0004,0x0002,0xF1C0,0xB2EC,0x0002,0xC4AF, 0xC7DE,0x0001,0x0001,0xF1C1,0x0006,0x0003,0x0000,0xD6C3,0x0000,0xBDFE,0x0004,0x0002,0xCAB5,0xD4A2,0x0002,0xBAAE, 0xC7DE,0x000A,0x0006,0x0003,0x0000,0xC3C2,0x0001,0xC4FE,0x0000,0x0000,0xB8BB,0x0007,0x0003,0x0001,0xBFDC,0x0002, 0xC3DC,0xD2FA,0x0003,0x0000,0xBCC4,0x0000,0xBCC5,0x0018,0x000C,0x0008,0x0004,0x0002,0xB2C9,0xCBDE,0x0002,0xB1F6, 0xBFED,0x0001,0x0001,0xC8DD,0x0007,0x0003,0x0000,0xE5B7,0x0002,0xBCD2,0xCFFC,0x0000,0x0002,0xD1E7,0xBAA6,0x000C, 0x0006,0x0003,0x0000,0xD4D7,0x0000,0xB9AC,0x0003,0x0001,0xB9AC,0x0000,0xCFDC,0x0007,0x0003,0x0001,0xBBC2,0x0002, 0xBBC2,0xE5B6,0x0004,0x0002,0xCAD2,0xD0FB,0x0002,0xBFCD,0xC9F3,0x0033,0x001A,0x000F,0x0007,0x0003,0x0000,0xB3E8, 0x0002,0xCAB5,0xB1A6,0x0004,0x0002,0xD2CB,0xCDF0,0x0002,0xB6A8,0xD6E6,0x0007,0x0004,0x0002,0xB9D9,0xD7DA,0x0001, 0xE5B4,0x0000,0x0001,0xE5B5,0x000B,0x0004,0x0000,0x0001,0xBAEA,0x0004,0x0002,0xCDEA,0xCBCE,0x0001,0xB0B2,0x0007, 0x0004,0x0002,0xCAD8,0xD3EE,0x0001,0xD5AC,0x0004,0x0002,0xE5B3,0xCBFC,0x0001,0xC4FE,0x0017,0x000B,0x0007,0x0004, 0x0002,0xE5B2,0xC2CF,0x0001,0xC4F5,0x0001,0x0000,0xC8E6,0x0006,0x0003,0x0000,0xD1A7,0x0001,0xB7F5,0x0003,0x0001, 0xE6DC,0x0001,0xE5EE,0x000C,0x0004,0x0000,0x0000,0xCAEB,0x0004,0x0002,0xD8AB,0xCBEF,0x0002,0xC2CF,0xBAA2,0x0005, 0x0001,0x0002,0xD1A7,0xE6DB,0x0004,0x0002,0xB9C2,0xBCBE,0x0000,0xE6DF,0x007F,0x0046,0x0028,0x001A,0x000C,0x0004, 0x0001,0x0000,0xC3CF,0x0004,0x0002,0xD0A2,0xD7CE,0x0002,0xD8C3,0xE6DA,0x0007,0x0004,0x0002,0xCBEF,0xB4E6,0x0000, 0xD7D6,0x0004,0x0002,0xD4D0,0xBFD7,0x0000,0xE6DE,0x0009,0x0005,0x0000,0x0002,0xE6DD,0xD7D3,0x0000,0x0001,0xE6AE, 0x0001,0x0001,0x0000,0xC4EF,0x0011,0x0005,0x0000,0x0000,0x0001,0xE6D7,0x0006,0x0003,0x0001,0xC9F4,0x0000,0xE6D6, 0x0003,0x0001,0xD9F8,0x0001,0xE6D5,0x0008,0x0004,0x0000,0x0001,0xD3A4,0x0001,0x0001,0xE6C9,0x0001,0x0000,0x0001, 0xE6D6,0x001D,0x0010,0x0008,0x0004,0x0000,0x0000,0xE6C8,0x0000,0x0000,0xF4C1,0x0000,0x0003,0x0000,0xE6CD,0x0002, 0xE6D3,0xE6D4,0x0007,0x0001,0x0003,0x0001,0xBDBF,0x0000,0xE6BF,0x0000,0x0000,0x0002,0xE6D2,0xE6AC,0x000A,0x0005, 0x0001,0x0001,0x0000,0xE6B5,0x0001,0x0000,0x0000,0xE5FC,0x0008,0x0004,0x0000,0x0000,0xE6CD,0x0001,0x0000,0xE6C6, 0x0006,0x0003,0x0000,0xC4DB,0x0001,0xE6CF,0x0001,0x0000,0xE6CC,0x004D,0x0029,0x001A,0x000D,0x0007,0x0004,0x0002, 0xB5D5,0xE6CB,0x0000,0xEAC7,0x0003,0x0001,0xE6D1,0x0001,0xC2FD,0x0007,0x0003,0x0001,0xE6D0,0x0002,0xE5FD,0xE6CE, 0x0003,0x0001,0xE6C9,0x0001,0xE6C8,0x0007,0x0001,0x0003,0x0001,0xCFD3,0x0000,0xF4C1,0x0004,0x0000,0x0000,0xBCB5, 0x0001,0x0001,0xC9A9,0x0016,0x000B,0x0006,0x0003,0x0000,0xBCDE,0x0001,0xE6C5,0x0000,0x0002,0xC2E8,0xE6C1,0x0004, 0x0000,0x0001,0xE6CA,0x0003,0x0000,0xEBF4,0x0002,0xCFB1,0xE6C7,0x0009,0x0005,0x0001,0x0002,0xE6A3,0xCDB5,0x0001, 0x0001,0xE6C1,0x0000,0x0001,0x0000,0xE6B4,0x000C,0x0000,0x0006,0x0001,0x0001,0x0002,0xE6C2,0xC3C4,0x0001,0x0001, 0x0001,0xC3BD,0x0012,0x0008,0x0004,0x0001,0x0000,0xD0F6,0x0001,0x0001,0xE6C4,0x0005,0x0001,0x0002,0xE6C3,0xC9F4, 0x0000,0x0002,0xE6BF,0xD3A4,0x0008,0x0001,0x0004,0x0002,0xE6AB,0xD2F9,0x0001,0xC0B7,0x0005,0x0001,0x0002,0xE6BA, 0xB8BE,0x0001,0x0001,0xE6BE,0x012C,0x0089,0x003D,0x0019,0x000B,0x0001,0x0006,0x0003,0x0000,0xBBE9,0x0001,0xC4DD, 0x0000,0x0001,0xE6BC,0x0005,0x0000,0x0001,0x0000,0xE6B9,0x0005,0x0000,0x0002,0xE6BB,0xCDF1,0x0000,0x0000,0xC6C5, 0x0011,0x000A,0x0006,0x0003,0x0001,0xC2A6,0x0000,0xE6B9,0x0001,0x0000,0xE6BD,0x0001,0x0003,0x0000,0xC8A2,0x0000, 0xE6B5,0x0009,0x0005,0x0000,0x0002,0xE6B4,0xD3E9,0x0000,0x0001,0xE6D2,0x0004,0x0000,0x0001,0xC3E4,0x0003,0x0001, 0xB6F0,0x0001,0xE6B7,0x0029,0x0012,0x000A,0x0005,0x0001,0x0002,0xC9EF,0xBEEA,0x0001,0x0002,0xC4C8,0xD3E9,0x0004, 0x0001,0x0000,0xC4EF,0x0001,0x0001,0xE6B8,0x0008,0x0004,0x0000,0x0001,0xE6B6,0x0001,0x0000,0xE6B2,0x0007,0x0003, 0x0001,0xE6B3,0x0002,0xE6AE,0xBDBF,0x0004,0x0002,0xE6AC,0xE6AB,0x0002,0xC2A6,0xCDDE,0x0011,0x000A,0x0006,0x0003, 0x0001,0xCDFE,0x0001,0xD7CB,0x0001,0x0001,0xD2F6,0x0000,0x0003,0x0001,0xE6B1,0x0001,0xD9A7,0x0005,0x0001,0x0001, 0x0000,0xBCA7,0x0006,0x0003,0x0000,0xD6B6,0x0000,0xD2CC,0x0004,0x0002,0xBCE9,0xC0D1,0x0001,0xE6AF,0x0053,0x0028, 0x0013,0x0007,0x0001,0x0003,0x0001,0xE6AD,0x0000,0xBDAA,0x0007,0x0003,0x0000,0xD2A6,0x0002,0xE6B0,0xE6A9,0x0001, 0x0002,0xCEAF,0xD0D5,0x000D,0x0007,0x0004,0x0002,0xE6A6,0xB9C3,0x0000,0xBDE3,0x0003,0x0001,0xE6A9,0x0001,0xCABC, 0x0004,0x0000,0x0000,0xE6A2,0x0000,0x0000,0xC4B7,0x0010,0x0007,0x0001,0x0003,0x0000,0xE6AA,0x0001,0xC6DE,0x0005, 0x0000,0x0002,0xC3C3,0xC3C3,0x0001,0x0001,0xC4E3,0x000C,0x0006,0x0003,0x0000,0xE6A7,0x0001,0xE6A8,0x0003,0x0000, 0xC4DD,0x0001,0xE6A3,0x0007,0x0004,0x0002,0xE5FD,0xE5FC,0x0000,0xB7C1,0x0004,0x0002,0xB7E1,0xCDD7,0x0002,0xE6A5, 0xE5FE,0x0028,0x0012,0x0006,0x0001,0x0000,0x0002,0xE6A4,0xD7B1,0x0006,0x0003,0x0001,0xC3EE,0x0001,0xE6A1,0x0003, 0x0000,0xD1FD,0x0001,0xBCCB,0x0008,0x0004,0x0000,0x0000,0xB6CA,0x0000,0x0001,0xE5FB,0x0007,0x0003,0x0000,0xC8D1, 0x0002,0xC2E8,0xB8BE,0x0003,0x0000,0xD7B1,0x0002,0xCDFD,0xE5FA,0x0018,0x000B,0x0005,0x0000,0x0002,0xC8E7,0xE5F9, 0x0003,0x0001,0xBAC3,0x0000,0xE6B1,0x0006,0x0003,0x0001,0xCBFD,0x0000,0xBCE9,0x0003,0x0000,0xC4CC,0x0002,0xC5AB, 0xC5AE,0x0005,0x0001,0x0000,0x0000,0xB7DC,0x0007,0x0004,0x0002,0xB6E1,0xDEC6,0x0001,0xB0C2,0x0000,0x0001,0xB0C2, 0x00B1,0x005F,0x002E,0x0016,0x0007,0x0000,0x0003,0x0000,0xC9DD,0x0000,0xB5EC,0x0007,0x0003,0x0000,0xDEC9,0x0002, 0xDECA,0xCCD7,0x0004,0x0002,0xBDB1,0xDEC8,0x0002,0xB1BC,0xC9DD,0x000D,0x0007,0x0003,0x0001,0xC6F5,0x0002,0xDBBC, 0xD7E0,0x0003,0x0000,0xBFFC,0x0001,0xB7DC,0x0007,0x0003,0x0001,0xB7EE,0x0002,0xC4CE,0xC6E6,0x0001,0x0000,0xD1D9, 0x0017,0x000B,0x0005,0x0000,0x0002,0xDBBC,0xDEC6,0x0003,0x0000,0xBCD0,0x0000,0xDEC5,0x0008,0x0004,0x0002,0xB6E1, 0xBCD0,0x0002,0xBFE4,0xD2C4,0x0001,0x0000,0xCDB7,0x000D,0x0006,0x0003,0x0001,0xCAA7,0x0001,0xBABB,0x0004,0x0002, 0xD1EB,0xD8B2,0x0001,0xB7F2,0x0007,0x0004,0x0002,0xCCAB,0xCCEC,0x0001,0xB4F3,0x0003,0x0001,0xE2B7,0x0000,0xE2B9, 0x0027,0x0017,0x000B,0x0007,0x0003,0x0000,0xC3CE,0x0002,0xB9BB,0xB9BB,0x0001,0x0000,0xD2B9,0x0005,0x0000,0x0002, 0xB6E0,0xD9ED,0x0004,0x0002,0xCDE2,0xCFA6,0x0000,0xD9E7,0x0008,0x0004,0x0001,0x0001,0xCFC4,0x0000,0x0001,0xB8B4, 0x0004,0x0001,0x0001,0xB1B8,0x0001,0x0000,0xB4A6,0x0017,0x000C,0x0006,0x0003,0x0000,0xE2BA,0x0001,0xB6D7,0x0003, 0x0001,0xCAD9,0x0000,0xBAF8,0x0005,0x0000,0x0002,0xBAF8,0xD2BC,0x0003,0x0000,0xBAF8,0x0001,0xBFC7,0x000C,0x0005, 0x0001,0x0002,0xC9F9,0xD7B3,0x0003,0x0000,0xD7B3,0x0002,0xC8C9,0xCABF,0x0004,0x0000,0x0001,0xB0D3,0x0001,0x0000, 0xC8C0,0x0048,0x0027,0x0017,0x000A,0x0006,0x0003,0x0000,0xDBDE,0x0001,0xC2A2,0x0000,0x0000,0xBBB5,0x0007,0x0004, 0x0002,0xDBE4,0xDBDB,0x0000,0xC0DD,0x0003,0x0001,0xBABE,0x0001,0xD1B9,0x0008,0x0004,0x0000,0x0001,0xDBD6,0x0000, 0x0000,0xDBF7,0x0004,0x0001,0x0001,0xCCB3,0x0000,0x0001,0xDBD5,0x000F,0x000A,0x0004,0x0000,0x0001,0xB1DA,0x0003, 0x0000,0xBFD1,0x0000,0xDBD4,0x0001,0x0001,0x0001,0xB7D8,0x000B,0x0004,0x0000,0x0001,0xEDE3,0x0003,0x0000,0xB6E9, 0x0002,0xB5D8,0xB6D7,0x0000,0x0003,0x0001,0xB6D5,0x0000,0xC4AB,0x0027,0x0014,0x000B,0x0004,0x0001,0x0001,0xD0E6, 0x0004,0x0002,0xD4F6,0xEDCD,0x0000,0xD7B9,0x0005,0x0000,0x0002,0xDCAE,0xC7BD,0x0001,0x0001,0xC4B9,0x0008,0x0004, 0x0000,0x0000,0xC9CA,0x0000,0x0000,0xB9F9,0x0005,0x0000,0x0002,0xB5E6,0xDCAD,0x0003,0x0001,0xCAFB,0x0001,0xBEB3, 0x0016,0x000C,0x0006,0x0003,0x0001,0xDCAC,0x0000,0xDCAF,0x0003,0x0000,0xDBD3,0x0000,0xD7A9,0x0004,0x0000,0x0001, 0xC7B5,0x0003,0x0001,0xB3BE,0x0000,0xDCA1,0x0006,0x0001,0x0001,0x0002,0xDCAB,0xCCEE,0x0001,0x0003,0x0001,0xDCAA, 0x0000,0xDBF7,0x0562,0x0287,0x013D,0x0099,0x004B,0x0029,0x0013,0x0007,0x0003,0x0000,0xCEEB,0x0000,0x0001,0xC8FB, 0x0006,0x0003,0x0001,0xDAA3,0x0001,0xCCC1,0x0003,0x0000,0xCDBF,0x0001,0xCBFE,0x000D,0x0006,0x0003,0x0001,0xDBF5, 0x0000,0xCBDC,0x0003,0x0000,0xDBEE,0x0002,0xEBF3,0xCBFA,0x0005,0x0000,0x0002,0xDCE3,0xBFE9,0x0001,0x0001,0xDCA8, 0x000D,0x0007,0x0001,0x0003,0x0000,0xBCEE,0x0000,0xB8D4,0x0001,0x0001,0x0002,0xB6C2,0xB3A1,0x000D,0x0007,0x0003, 0x0001,0xBCB2,0x0002,0xB1A8,0xD1DF,0x0003,0x0000,0xD2A2,0x0000,0xBBCA,0x0004,0x0000,0x0001,0xBFB0,0x0001,0x0001, 0xB5CC,0x0027,0x0013,0x000B,0x0005,0x0001,0x0002,0xB1A4,0xDCA9,0x0003,0x0001,0xDCA6,0x0000,0xDBF6,0x0004,0x0001, 0x0000,0xDCA7,0x0001,0x0000,0xB6E9,0x0008,0x0004,0x0001,0x0000,0xC7B5,0x0001,0x0000,0xDCA2,0x0005,0x0000,0x0002, 0xDCA1,0xDBD1,0x0004,0x0002,0xDDC0,0xB6D1,0x0000,0xBCE1,0x0018,0x000A,0x0006,0x0003,0x0001,0xCCC3,0x0001,0xDCA5, 0x0001,0x0000,0xDCA3,0x0007,0x0003,0x0001,0xBBF9,0x0002,0xC5E0,0xDBFC,0x0004,0x0002,0xD6B4,0xD6B4,0x0001,0xDBFA, 0x000A,0x0004,0x0000,0x0000,0xBFB2,0x0003,0x0000,0xDBFB,0x0000,0xDCA4,0x0001,0x0001,0x0001,0xDBFD,0x0051,0x0029, 0x0018,0x000C,0x0005,0x0001,0x0002,0xDBEB,0xB2BA,0x0003,0x0000,0xD3F2,0x0002,0xDBFE,0xD2B0,0x0007,0x0003,0x0001, 0xDBF6,0x0002,0xDBF7,0xDBF5,0x0001,0x0002,0xDBF4,0xC6D2,0x0009,0x0004,0x0000,0x0001,0xDBF8,0x0000,0x0002,0xDBEF, 0xB3C7,0x0004,0x0000,0x0000,0xC2F1,0x0000,0x0000,0xF0AE,0x0011,0x0006,0x0000,0x0000,0x0002,0xB0A3,0xB9A1,0x0006, 0x0003,0x0001,0xDBAE,0x0001,0xDBF9,0x0001,0x0002,0xDBFB,0xDBF1,0x000A,0x0004,0x0000,0x0001,0xDBEE,0x0003,0x0001, 0xBFE5,0x0000,0xDBEB,0x0006,0x0003,0x0000,0xB5E6,0x0000,0xDBD1,0x0004,0x0002,0xDBF0,0xBFD1,0x0001,0xDBEC,0x0026, 0x0012,0x0009,0x0000,0x0004,0x0002,0xD4AB,0xB9B8,0x0002,0xDBD2,0xDBF3,0x0004,0x0000,0x0000,0xB6E2,0x0001,0x0002, 0xBAF1,0xDCA7,0x0009,0x0005,0x0000,0x0002,0xDBF2,0xC0DD,0x0001,0x0001,0xDBED,0x0004,0x0000,0x0000,0xD0CD,0x0003, 0x0001,0xDBE4,0x0002,0xDBE2,0xC2A2,0x0015,0x0009,0x0005,0x0000,0x0002,0xC0AC,0xB4B9,0x0001,0x0001,0xDBE5,0x0004, 0x0000,0x0000,0xDBE6,0x0004,0x0002,0xBFC0,0xDBE9,0x0002,0xC7F0,0xC2BD,0x000A,0x0004,0x0000,0x0000,0xDBEA,0x0003, 0x0000,0xC5F7,0x0000,0xDBE8,0x0008,0x0004,0x0002,0xDBE3,0xC6BA,0x0002,0xDBE1,0xDBE7,0x0003,0x0001,0xCCB9,0x0001, 0xC0A4,0x00AC,0x0057,0x002D,0x0017,0x000C,0x0004,0x0001,0x0001,0xC6C2,0x0004,0x0002,0xD7B9,0xB7D8,0x0002,0xCEEB, 0xB0D3,0x0007,0x0004,0x0002,0xDBDE,0xCCB3,0x0000,0xBCE1,0x0000,0x0001,0xBFE9,0x000C,0x0004,0x0001,0x0001,0xBFD3, 0x0004,0x0002,0xD7F8,0xBBB5,0x0002,0xBFB2,0xCCAE,0x0006,0x0003,0x0000,0xDBD0,0x0000,0xB7BB,0x0000,0x0001,0xBEF9, 0x0013,0x000B,0x0005,0x0001,0x0002,0xDBE0,0xDBE6,0x0003,0x0000,0xD6B7,0x0000,0xBBF8,0x0000,0x0003,0x0001,0xDBDF, 0x0002,0xB3A1,0xDBDB,0x000C,0x0004,0x0000,0x0001,0xDBDA,0x0004,0x0002,0xB5D8,0xDBDD,0x0002,0xDBDC,0xB9E7,0x0007, 0x0003,0x0000,0xDBD8,0x0002,0xDBD9,0xDBD7,0x0000,0x0000,0xD4DA,0x002C,0x0014,0x000A,0x0006,0x0003,0x0001,0xCAA5, 0x0000,0xEEAE,0x0000,0x0001,0xCDC1,0x0004,0x0000,0x0000,0xE0F7,0x0003,0x0000,0xCDC5,0x0000,0xCDBC,0x000A,0x0006, 0x0003,0x0001,0xD4B2,0x0000,0xD4B0,0x0001,0x0001,0xCEA7,0x0007,0x0003,0x0001,0xB9FA,0x0002,0xE0F5,0xE0F6,0x0004, 0x0002,0xC8A6,0xE0F0,0x0000,0xD4B2,0x0015,0x000C,0x0005,0x0000,0x0002,0xE0F4,0xC6D4,0x0003,0x0001,0xE0F3,0x0002, 0xCDBC,0xB9FA,0x0005,0x0001,0x0002,0xB9CC,0xE0F2,0x0001,0x0001,0xE0F0,0x000D,0x0006,0x0003,0x0000,0xCEA7,0x0001, 0xB4D1,0x0003,0x0000,0xC0A7,0x0002,0xB6EF,0xD4B0,0x0000,0x0003,0x0001,0xE0F1,0x0000,0xB4D1,0x0052,0x002C,0x0019, 0x000F,0x0007,0x0003,0x0000,0xB6DA,0x0002,0xCDC5,0xE0EF,0x0004,0x0002,0xD2F2,0xD8B6,0x0002,0xBBD8,0xE0EE,0x0006, 0x0003,0x0001,0xCBC4,0x0000,0xC7F4,0x0000,0x0001,0xBFDA,0x0008,0x0000,0x0004,0x0002,0xE0EC,0xC4F6,0x0001,0xD6F6, 0x0007,0x0003,0x0000,0xCBD5,0x0002,0xC4D2,0xC2DE,0x0000,0x0000,0xDFBD,0x0013,0x0009,0x0005,0x0001,0x0002,0xCFF9, 0xE0BF,0x0000,0x0000,0xDFF9,0x0004,0x0000,0x0000,0xBDC0,0x0003,0x0001,0xC8C2,0x0000,0xE0D3,0x000B,0x0005,0x0000, 0x0002,0xD1CF,0xE0B7,0x0003,0x0001,0xE0EB,0x0000,0xCFF2,0x0001,0x0003,0x0000,0xC1FC,0x0002,0xDFBF,0xD1CA,0x0020, 0x000D,0x0005,0x0000,0x0000,0x0001,0xCFF9,0x0004,0x0001,0x0001,0xC4F6,0x0001,0x0001,0xE0E0,0x000B,0x0004,0x0000, 0x0001,0xE0EA,0x0004,0x0002,0xB3A2,0xCCE7,0x0000,0xBABF,0x0001,0x0003,0x0001,0xCFC5,0x0002,0xE0E3,0xE0E9,0x0012, 0x0005,0x0001,0x0000,0x0000,0xDFCC,0x0007,0x0004,0x0002,0xE0E8,0xE0E7,0x0001,0xB5B1,0x0003,0x0000,0xB6D6,0x0000, 0xB8C1,0x000B,0x0007,0x0003,0x0000,0xC5E7,0x0002,0xDFE0,0xE0E5,0x0000,0x0001,0xE0C8,0x0008,0x0004,0x0002,0xCAC9, 0xE0E6,0x0002,0xD4EB,0xD8AC,0x0003,0x0000,0xC6F7,0x0002,0xDFDC,0xDFE6,0x016A,0x00AD,0x0054,0x0027,0x0014,0x0009, 0x0005,0x0002,0xE0E4,0x0001,0xE0DE,0x0000,0x0001,0xDFD5,0x0004,0x0000,0x0001,0xE0E0,0x0004,0x0002,0xE0DF,0xE0D9, 0x0000,0xE0DB,0x000A,0x0006,0x0003,0x0001,0xE0E2,0x0000,0xD0EA,0x0001,0x0001,0xD2AD,0x0005,0x0000,0x0002,0xE0DD, 0xE0E1,0x0000,0x0001,0xF5BE,0x0012,0x0007,0x0001,0x0003,0x0000,0xB6F1,0x0000,0xBAD9,0x0004,0x0001,0x0000,0xCEFB, 0x0004,0x0002,0xE0DA,0xDFBC,0x0001,0xCBBB,0x0010,0x0008,0x0004,0x0002,0xDFD8,0xD7EC,0x0002,0xE0B0,0xB3B0,0x0004, 0x0002,0xD6F6,0xDFB4,0x0002,0xD0A5,0xDFEB,0x0005,0x0000,0x0002,0xE0D8,0xE0DC,0x0003,0x0000,0xBBA9,0x0000,0xE0D7, 0x002D,0x0018,0x000B,0x0006,0x0003,0x0001,0xE0D3,0x0000,0xE0D4,0x0001,0x0002,0xE0BD,0xE0CF,0x0006,0x0003,0x0001, 0xDFE9,0x0000,0xC2EF,0x0003,0x0001,0xD0EA,0x0002,0xB3A2,0xDFF5,0x0009,0x0004,0x0000,0x0001,0xC5BB,0x0001,0x0002, 0xD8C5,0xB8C2,0x0005,0x0000,0x0002,0xE0B6,0xE0D1,0x0004,0x0002,0xBCCE,0xE0D0,0x0001,0xCCBE,0x0013,0x0008,0x0001, 0x0004,0x0002,0xE0D2,0xE0D6,0x0001,0xE0D5,0x0006,0x0003,0x0000,0xCBD4,0x0001,0xB4DF,0x0001,0x0002,0xE0BB,0xDFD9, 0x000B,0x0007,0x0003,0x0000,0xE0CC,0x0002,0xE0C8,0xE0C7,0x0001,0x0000,0xE0C5,0x0007,0x0003,0x0001,0xE0C0,0x0002, 0xE0BF,0xE0BA,0x0004,0x0002,0xDFEF,0xE0CB,0x0001,0xE0C2,0x0062,0x0032,0x0019,0x000D,0x0007,0x0004,0x0002,0xE0C6, 0xE0CD,0x0000,0xCBC3,0x0003,0x0000,0xCECB,0x0000,0xE0B5,0x0008,0x0004,0x0002,0xE0C3,0xCAC8,0x0002,0xC7B8,0xCED8, 0x0001,0x0001,0xE0B2,0x000D,0x0007,0x0003,0x0001,0xE0C1,0x0002,0xC9A4,0xE0AA,0x0003,0x0000,0xE0BE,0x0001,0xC2F0, 0x0005,0x0000,0x0002,0xE0CA,0xE0C9,0x0003,0x0000,0xE0BC,0x0002,0xD8C4,0xC7BA,0x0016,0x000A,0x0005,0x0000,0x0002, 0xD0E1,0xE0C4,0x0001,0x0002,0xD4EB,0xE0B7,0x0006,0x0003,0x0000,0xE0B6,0x0000,0xD3F7,0x0003,0x0000,0xE0AD,0x0000, 0xC5E7,0x000D,0x0007,0x0003,0x0000,0xDFF7,0x0002,0xD4FB,0xD3B4,0x0003,0x0000,0xE0AC,0x0001,0xB5A5,0x0008,0x0004, 0x0002,0xD1E4,0xC7C7,0x0002,0xB3D4,0xC9A5,0x0001,0x0002,0xD0FA,0xD1D2,0x002C,0x0014,0x0008,0x0004,0x0001,0x0001, 0xECA6,0x0001,0x0000,0xE0B0,0x0007,0x0004,0x0002,0xBAC8,0xCFB2,0x0001,0xBBBD,0x0000,0x0002,0xE0B9,0xB4AD,0x000C, 0x0006,0x0003,0x0001,0xE0B8,0x0001,0xD4DB,0x0003,0x0000,0xE0B3,0x0000,0xDFF6,0x0005,0x0001,0x0002,0xE0A9,0xBAB0, 0x0004,0x0002,0xBAED,0xE0AE,0x0000,0xC0AE,0x001B,0x000E,0x0007,0x0003,0x0001,0xC9C6,0x0002,0xE0AB,0xCEB9,0x0004, 0x0002,0xE0AF,0xBFA6,0x0001,0xE0B1,0x0006,0x0003,0x0001,0xCCE4,0x0000,0xE0B4,0x0003,0x0001,0xD0A5,0x0002,0xE0A5, 0xE0A4,0x0008,0x0004,0x0000,0x0000,0xE0A3,0x0001,0x0001,0xC4F6,0x0007,0x0004,0x0002,0xDFF9,0xD8C4,0x0001,0xC5BE, 0x0001,0x0002,0xDFF5,0xC0B2,0x00A9,0x005B,0x002D,0x0017,0x000E,0x0007,0x0004,0x0002,0xC9B6,0xC6A1,0x0000,0xCFCE, 0x0003,0x0000,0xB7C8,0x0002,0xC6F4,0xD1C6,0x0004,0x0000,0x0001,0xE0A8,0x0001,0x0002,0xE0A2,0xE0A2,0x000C,0x0004, 0x0000,0x0000,0xDFFB,0x0004,0x0002,0xE0A9,0xDFFD,0x0002,0xCECA,0xE2E8,0x0004,0x0001,0x0001,0xB0A1,0x0003,0x0000, 0xDFF8,0x0001,0xC9CC,0x0018,0x000E,0x0007,0x0004,0x0002,0xD7C4,0xD7C4,0x0000,0xBFD0,0x0003,0x0000,0xDFFA,0x0002, 0xDFFC,0xCDD9,0x0004,0x0000,0x0001,0xDFFE,0x0003,0x0001,0xC4EE,0x0000,0xE0A1,0x000C,0x0004,0x0001,0x0000,0xE0A6, 0x0004,0x0002,0xB3AA,0xE0A7,0x0002,0xCEA8,0xCADB,0x0006,0x0003,0x0001,0xBBA3,0x0001,0xDFF4,0x0001,0x0000,0xDFF3, 0x0023,0x0010,0x000B,0x0007,0x0003,0x0001,0xBBBD,0x0002,0xDFF0,0xDFEF,0x0000,0x0001,0xDFEB,0x0000,0x0001,0x0000, 0xDFE9,0x000B,0x0004,0x0000,0x0001,0xDFED,0x0004,0x0002,0xDFF2,0xCCC6,0x0000,0xDFF1,0x0001,0x0003,0x0000,0xB0A6, 0x0002,0xB4BD,0xCBF4,0x0014,0x000B,0x0005,0x0000,0x0002,0xBAAC,0xDFC2,0x0003,0x0000,0xD1E4,0x0000,0xDBC1,0x0000, 0x0004,0x0002,0xDFEC,0xBADF,0x0002,0xF7FD,0xB2B8,0x0009,0x0005,0x0001,0x0002,0xDFEE,0xD5DC,0x0001,0x0001,0xCFF8, 0x0006,0x0003,0x0000,0xBFDE,0x0001,0xC4C4,0x0004,0x0002,0xC1A8,0xC9DA,0x0002,0xDFEA,0xC5B6,0x006B,0x0035,0x0018, 0x000B,0x0004,0x0000,0x0000,0xB8E7,0x0003,0x0000,0xD4B1,0x0002,0xD3B4,0xDFE8,0x0007,0x0004,0x0002,0xDFE6,0xDFE2, 0x0001,0xDFE1,0x0003,0x0000,0xDFE0,0x0000,0xBBA9,0x0010,0x0008,0x0004,0x0002,0xDFDC,0xDFD9,0x0002,0xDFD8,0xDFD5, 0x0004,0x0002,0xD1C6,0xDFD1,0x0002,0xDFE7,0xB0A5,0x0005,0x0000,0x0002,0xCFEC,0xDFDF,0x0004,0x0002,0xD4D5,0xB9FE, 0x0002,0xCDDB,0xB6DF,0x001A,0x000D,0x0006,0x0003,0x0001,0xBAE5,0x0001,0xDFD3,0x0004,0x0002,0xC6B7,0xB0A7,0x0000, 0xDFDE,0x0007,0x0004,0x0002,0xD1CA,0xDFC3,0x0000,0xDFDD,0x0003,0x0001,0xCFCC,0x0001,0xF3C2,0x000C,0x0006,0x0003, 0x0001,0xDFD4,0x0000,0xBFC8,0x0003,0x0000,0xD4DB,0x0000,0xBFA9,0x0008,0x0004,0x0002,0xDFD2,0xD2A7,0x0002,0xE5EB, 0xDFE4,0x0004,0x0002,0xDFE3,0xD7C9,0x0002,0xDFD6,0xDFD7,0x0031,0x0018,0x000B,0x0007,0x0003,0x0001,0xDFE5,0x0002, 0xDFDB,0xDACC,0x0000,0x0001,0xBCA9,0x0007,0x0003,0x0000,0xDFD0,0x0002,0xDFCC,0xDFCB,0x0003,0x0000,0xC1FC,0x0001, 0xBFA7,0x000E,0x0007,0x0004,0x0002,0xB9BE,0xDFC7,0x0001,0xD6E4,0x0003,0x0001,0xB8C0,0x0002,0xD3BD,0xBECC,0x0007, 0x0004,0x0002,0xBFC8,0xBACD,0x0000,0xD5A6,0x0001,0x0001,0xC5D8,0x0018,0x000A,0x0006,0x0003,0x0001,0xDFCD,0x0001, 0xDFC6,0x0000,0x0001,0xBED7,0x0007,0x0004,0x0002,0xC3FC,0xBAF4,0x0000,0xC9EB,0x0003,0x0001,0xC5DE,0x0002,0xDFC8, 0xDFCE,0x000D,0x0008,0x0004,0x0002,0xBAC7,0xBAF0,0x0002,0xCEB6,0xDFDA,0x0000,0x0002,0xDFC9,0xF6A4,0x0001,0x0003, 0x0001,0xD6DC,0x0001,0xDFCF,0x02DF,0x0185,0x00CF,0x0063,0x002C,0x0014,0x0008,0x0004,0x0001,0x0000,0xDFCA,0x0000, 0x0000,0xC4D8,0x0005,0x0001,0x0002,0xCED8,0xC7BA,0x0003,0x0001,0xDFC3,0x0002,0xD4B1,0xDFC2,0x000E,0x0008,0x0004, 0x0002,0xDFBF,0xC5BB,0x0002,0xDFBE,0xDFBD,0x0003,0x0000,0xDFBC,0x0000,0xC4C5,0x0004,0x0001,0x0001,0xDFBB,0x0003, 0x0000,0xB8E6,0x0000,0xB3CA,0x0019,0x000C,0x0006,0x0003,0x0000,0xB4F4,0x0001,0xDFC0,0x0003,0x0000,0xC2C0,0x0000, 0xD1BD,0x0007,0x0003,0x0000,0xCEE1,0x0002,0xBAF0,0xCEC7,0x0003,0x0001,0xB4B5,0x0000,0xCEFC,0x000F,0x0008,0x0004, 0x0002,0xC4C5,0xB3B3,0x0002,0xCEE2,0xCEE2,0x0004,0x0002,0xDFC5,0xD6A8,0x0001,0xC6F4,0x0008,0x0004,0x0002,0xCBB1, 0xBFD4,0x0002,0xCCFD,0xBAAC,0x0003,0x0001,0xB7D4,0x0002,0xB6D6,0xB0C9,0x0035,0x0018,0x000D,0x0006,0x0003,0x0000, 0xB7F1,0x0001,0xDFC4,0x0003,0x0001,0xDFC1,0x0002,0xB7CD,0xD2F7,0x0007,0x0004,0x0002,0xCDCC,0xC1DF,0x0001,0xBEFD, 0x0001,0x0001,0xC2F0,0x000F,0x0007,0x0004,0x0002,0xDFB9,0xC2C0,0x0001,0xCFC5,0x0004,0x0002,0xDFB8,0xCFF2,0x0002, 0xCDC2,0xC0F4,0x0007,0x0004,0x0002,0xBAF3,0xC3FB,0x0000,0xCDAC,0x0004,0x0002,0xB5F5,0xBCAA,0x0000,0xBACF,0x0019, 0x000B,0x0007,0x0003,0x0000,0xDFBA,0x0002,0xB8F7,0xB3D4,0x0000,0x0001,0xD3F5,0x0007,0x0003,0x0001,0xDFB4,0x0002, 0xB5F0,0xDFB7,0x0003,0x0001,0xCCBE,0x0002,0xCBBE,0xBAC5,0x000F,0x0007,0x0004,0x0002,0xD2B6,0xD8CF,0x0001,0xD3D2, 0x0004,0x0002,0xCAB7,0xDFB3,0x0002,0xCCA8,0xBFC9,0x0008,0x0004,0x0002,0xB6A3,0xB0C8,0x0002,0xD5D9,0xBDD0,0x0004, 0x0002,0xD6BB,0xDFB5,0x0000,0xDFB6,0x0057,0x0032,0x001A,0x000F,0x0008,0x0004,0x0002,0xC1ED,0xBEE4,0x0002,0xB9C5, 0xBFDA,0x0003,0x0000,0xB4D4,0x0002,0xB5FE,0xDBC5,0x0004,0x0001,0x0001,0xC5D1,0x0003,0x0001,0xD0F0,0x0002,0xB1E4, 0xCADC,0x000A,0x0006,0x0003,0x0000,0xC8A1,0x0000,0xCAE5,0x0000,0x0001,0xB7A2,0x0007,0x0003,0x0001,0xB7B4,0x0002, 0xCBAB,0xD3D1,0x0004,0x0002,0xBCB0,0xB2E6,0x0000,0xD3D6,0x0010,0x000B,0x0004,0x0001,0x0001,0xB2CE,0x0004,0x0002, 0xB2CE,0xC8FE,0x0001,0xCFD8,0x0000,0x0001,0x0001,0xC8A5,0x000A,0x0006,0x0003,0x0000,0xDBCC,0x0000,0xD8C9,0x0000, 0x0000,0xC0F7,0x0005,0x0000,0x0002,0xD8CB,0xD1E1,0x0003,0x0001,0xBEC7,0x0000,0xB3F8,0x002B,0x0019,0x000E,0x0008, 0x0004,0x0002,0xCFC3,0xD8CA,0x0002,0xC0FA,0xD8C9,0x0003,0x0000,0xCFE1,0x0001,0xD4AD,0x0004,0x0000,0x0001,0xD8C8, 0x0004,0x0002,0xBAF1,0xD8C7,0x0000,0xC0E5,0x0006,0x0000,0x0000,0x0002,0xC5D3,0xB2DE,0x0008,0x0004,0x0002,0xEDC6, 0xD8C7,0x0002,0xD1E1,0xD1B9,0x0000,0x0001,0xC0F7,0x0019,0x000D,0x0007,0x0004,0x0002,0xC0FA,0xCCFC,0x0000,0xB6F2, 0x0003,0x0000,0xB3A7,0x0001,0xC7E4,0x0004,0x0001,0x0001,0xC8B4,0x0004,0x0002,0xDAE1,0xD0F4,0x0002,0xD0B6,0xBEED, 0x000E,0x0007,0x0003,0x0001,0xC2D1,0x0002,0xC8B4,0xBCB4,0x0003,0x0001,0xCEA3,0x0002,0xD3A1,0xC3AE,0x0007,0x0003, 0x0000,0xD8B4,0x0002,0xD1F6,0xCEC0,0x0003,0x0001,0xDAE0,0x0001,0xCED4,0x00B0,0x005E,0x0033,0x0018,0x000D,0x0005, 0x0002,0xD8D4,0x0001,0xC2B1,0x0004,0x0002,0xD8D5,0xC2AC,0x0002,0xBFA8,0xD5BC,0x0007,0x0004,0x0002,0xDFB2,0xB1E5, 0x0001,0xB2B7,0x0000,0x0001,0xB2A9,0x000F,0x0008,0x0004,0x0002,0xC4CF,0xC2F4,0x0002,0xB5A5,0xD0AD,0x0004,0x0002, 0xD7BF,0xD7E4,0x0000,0xB1B0,0x0005,0x0000,0x0002,0xD0AD,0xBBAA,0x0003,0x0001,0xB0EB,0x0002,0xBBDC,0xCEE7,0x001B, 0x000D,0x0006,0x0003,0x0000,0xC9FD,0x0000,0xD8A6,0x0003,0x0000,0xC7A7,0x0002,0xCAAE,0xC7F8,0x0007,0x0004,0x0002, 0xC4E4,0xD8D2,0x0000,0xD9C8,0x0004,0x0002,0xD2BD,0xC7F8,0x0000,0xC6A5,0x0005,0x0001,0x0001,0x0000,0xD8D1,0x0007, 0x0004,0x0002,0xBBE3,0xD8D1,0x0000,0xD8D0,0x0000,0x0001,0xB7CB,0x002F,0x0017,0x000B,0x0004,0x0000,0x0001,0xD8D0, 0x0003,0x0000,0xCFBB,0x0002,0xBFEF,0xBDB3,0x0006,0x0003,0x0000,0xBFBB,0x0000,0xD4D1,0x0003,0x0001,0xD8CE,0x0000, 0xB3D7,0x000B,0x0007,0x0004,0x0002,0xB1B1,0xBBAF,0x0000,0xD8B0,0x0001,0x0001,0xD9EB,0x0006,0x0003,0x0000,0xDECB, 0x0000,0xD9E9,0x0004,0x0002,0xCCD5,0xDEE4,0x0001,0xD0D9,0x0017,0x000A,0x0006,0x0003,0x0001,0xB4D2,0x0000,0xB0FC, 0x0001,0x0001,0xD4C8,0x0005,0x0000,0x0002,0xCEF0,0xB9B4,0x0004,0x0002,0xD4C8,0xC9D7,0x0002,0xD9E8,0xC8B0,0x0000, 0x0004,0x0001,0x0000,0xC0F8,0x0003,0x0000,0xD1AB,0x0002,0xDBBD,0xDBC4,0x0052,0x002D,0x0019,0x000B,0x0006,0x0003, 0x0001,0xBDCB,0x0001,0xC7DA,0x0000,0x0002,0xBCA8,0xCAC6,0x0007,0x0004,0x0002,0xC4BC,0xC0CD,0x0000,0xCAA4,0x0003, 0x0000,0xD1AB,0x0002,0xCEF1,0xBFB1,0x000D,0x0007,0x0004,0x0002,0xDBC3,0xDBC3,0x0000,0xB6AF,0x0003,0x0001,0xC0D5, 0x0001,0xDBC2,0x0001,0x0003,0x0000,0xD1AB,0x0000,0xC3E3,0x0010,0x000A,0x0004,0x0000,0x0000,0xD3C2,0x0003,0x0000, 0xB2AA,0x0000,0xBEA2,0x0000,0x0000,0x0002,0xCAC6,0xDBC0,0x0008,0x0001,0x0004,0x0002,0xC0CD,0xBEA2,0x0000,0xC0F8, 0x0005,0x0001,0x0002,0xDBBF,0xDBBE,0x0004,0x0002,0xBDD9,0xC5AC,0x0002,0xD6FA,0xB6AF,0x002C,0x0017,0x000C,0x0004, 0x0000,0x0001,0xC1A6,0x0004,0x0002,0xC1D3,0xDBBD,0x0002,0xCEF1,0xBCD3,0x0007,0x0004,0x0002,0xB9A6,0xB0EC,0x0000, 0xC8B0,0x0000,0x0000,0xC1A6,0x0008,0x0001,0x0003,0x0000,0xD8E6,0x0002,0xBCC1,0xD8E5,0x0005,0x0001,0x0002,0xBDA3, 0xD8DB,0x0004,0x0002,0xBDCB,0xB9F4,0x0002,0xC1F5,0xC5FC,0x0014,0x000D,0x0006,0x0003,0x0000,0xBEE7,0x0001,0xD4FD, 0x0004,0x0002,0xBBAE,0xD8E3,0x0000,0xD8E4,0x0000,0x0003,0x0000,0xBDCB,0x0000,0xD8E2,0x000B,0x0007,0x0003,0x0000, 0xB2F9,0x0002,0xB4B4,0xD8DC,0x0000,0x0001,0xB8EE,0x0007,0x0004,0x0002,0xB8B1,0xB9D0,0x0001,0xD6C6,0x0003,0x0001, 0xBCF4,0x0000,0xCAA3,0x017A,0x00C3,0x0062,0x002D,0x0015,0x0009,0x0005,0x0002,0xBEE7,0x0001,0xB0FE,0x0001,0x0001, 0xD8DF,0x0005,0x0001,0x0002,0xD8DE,0xB0FE,0x0004,0x0002,0xD8E0,0xB8D5,0x0000,0xCAC2,0x000A,0x0004,0x0001,0x0000, 0xC6CA,0x0003,0x0000,0xCCDE,0x0001,0xBDA3,0x0007,0x0003,0x0000,0xB9D0,0x0002,0xC9B2,0xC7B0,0x0004,0x0002,0xD8DD, 0xBFCB,0x0000,0xCFF7,0x001A,0x000C,0x0004,0x0000,0x0001,0xD4F2,0x0004,0x0002,0xD8D9,0xCCEA,0x0002,0xBCC1,0xB6E7, 0x0007,0x0004,0x0002,0xD8DC,0xD8DB,0x0001,0xB9F4,0x0003,0x0001,0xBFCC,0x0002,0xB4CC,0xC9B2,0x000D,0x0007,0x0004, 0x0002,0xC8AF,0xCBA2,0x0000,0xD6C6,0x0003,0x0001,0xD8DA,0x0001,0xB4B4,0x0007,0x0003,0x0000,0xB5BD,0x0002,0xB9CE, 0xD8D9,0x0003,0x0001,0xB1F0,0x0002,0xC9BE,0xC0FB,0x002C,0x0017,0x000A,0x0006,0x0003,0x0000,0xC5D9,0x0001,0xB1F0, 0x0000,0x0000,0xC5D0,0x0006,0x0003,0x0000,0xC9BE,0x0001,0xB3F5,0x0003,0x0001,0xB4B4,0x0002,0xB8D5,0xD4F2,0x000C, 0x0007,0x0004,0x0002,0xC1F5,0xC1D0,0x0000,0xEBBE,0x0001,0x0002,0xBBAE,0xD0CC,0x0005,0x0001,0x0002,0xD8D8,0xDBBB, 0x0001,0x0000,0xBFAF,0x001D,0x000E,0x0007,0x0004,0x0002,0xD8D7,0xC7D0,0x0000,0xB7D6,0x0003,0x0001,0xC8D0,0x0002, 0xD8D6,0xB5F3,0x0007,0x0004,0x0002,0xB5B6,0xD4E4,0x0001,0xBAAF,0x0004,0x0002,0xDBCA,0xBBF7,0x0002,0xB3F6,0xB0BC, 0x000D,0x0007,0x0003,0x0000,0xCDB9,0x0002,0xD0D7,0xDBC9,0x0003,0x0001,0xB5CA,0x0001,0xBFAD,0x0007,0x0004,0x0002, 0xBBCB,0xBFAD,0x0001,0xC6BE,0x0000,0x0001,0xD9EC,0x0054,0x0024,0x0012,0x0007,0x0001,0x0003,0x0000,0xB7EF,0x0001, 0xB7B2,0x0006,0x0003,0x0000,0xBCB8,0x0001,0xC4FD,0x0000,0x0002,0xC1DD,0xC1DD,0x0005,0x0001,0x0001,0x0001,0xB4D5, 0x0006,0x0003,0x0001,0xBCF5,0x0001,0xB6B3,0x0004,0x0002,0xC1E8,0xB5F2,0x0001,0xC1B9,0x0016,0x000B,0x0007,0x0004, 0x0002,0xBEBB,0xDAA1,0x0000,0xD7BC,0x0000,0x0000,0xC6E0,0x0006,0x0003,0x0000,0xBEBB,0x0001,0xD9FD,0x0000,0x0002, 0xD9FE,0xB6B3,0x000E,0x0007,0x0003,0x0001,0xC0E4,0x0002,0xD2B1,0xBFF6,0x0003,0x0001,0xBEF6,0x0002,0xB3E5,0xD9FC, 0x0005,0x0000,0x0002,0xB1F9,0xB7EB,0x0004,0x0002,0xB6AC,0xD9FB,0x0000,0xC3DD,0x002E,0x0015,0x000A,0x0004,0x0001, 0x0001,0xDAA4,0x0003,0x0000,0xD4A9,0x0000,0xDAA3,0x0004,0x0000,0x0000,0xB9DA,0x0004,0x0002,0xC5A9,0xBEFC,0x0001, 0xD0B4,0x000E,0x0007,0x0003,0x0001,0xC8DF,0x0002,0xDAA2,0xC3E1,0x0003,0x0001,0xB9B9,0x0002,0xC3B0,0xEBD0,0x0004, 0x0001,0x0001,0xD4D9,0x0003,0x0000,0xB2E1,0x0002,0xB2E1,0xC8BD,0x0018,0x000B,0x0006,0x0003,0x0000,0xB8D4,0x0001, 0xC4DA,0x0001,0x0002,0xD8E7,0xD9E6,0x0006,0x0003,0x0000,0xBCBD,0x0001,0xCADE,0x0004,0x0002,0xBCE6,0xD1F8,0x0001, 0xD7C8,0x000F,0x0008,0x0004,0x0002,0xB5E4,0xBEDF,0x0002,0xC6E4,0xB1F8,0x0004,0x0002,0xD0CB,0xB9D8,0x0001,0xB9B2, 0x0007,0x0003,0x0000,0xC0BC,0x0002,0xD9E2,0xC1F9,0x0004,0x0002,0xB9AB,0xB0CB,0x0001,0xC1BD,0x009F,0x0055,0x002B, 0x0012,0x000B,0x0007,0x0004,0x0002,0xC8AB,0xC4DA,0x0001,0xC8EB,0x0001,0x0000,0xBEA4,0x0001,0x0003,0x0000,0xB6B5, 0x0000,0xB5B3,0x000E,0x0007,0x0003,0x0001,0xD9F0,0x0002,0xD9F0,0xD9EE,0x0003,0x0000,0xCDC3,0x0002,0xB6F9,0xB6D2, 0x0004,0x0001,0x0001,0xC3E2,0x0004,0x0002,0xB6D2,0xBFCB,0x0001,0xB9E2,0x001B,0x000F,0x0008,0x0004,0x0002,0xCFC8, 0xD0D7,0x0002,0xD5D7,0xB3E4,0x0004,0x0002,0xD0D6,0xD4AA,0x0001,0xD4CA,0x0005,0x0000,0x0002,0xD8A3,0xB6F9,0x0004, 0x0002,0xD9B2,0xD9CE,0x0000,0xD9D0,0x000A,0x0004,0x0000,0x0001,0xD9B3,0x0003,0x0001,0xB2F3,0x0000,0xB4A2,0x0001, 0x0001,0x0000,0xD3C5,0x0020,0x000A,0x0005,0x0001,0x0001,0x0001,0xC0DC,0x0000,0x0000,0x0001,0xB3A5,0x000C,0x0006, 0x0003,0x0000,0xBEA1,0x0001,0xD9AD,0x0003,0x0000,0xD9B1,0x0000,0xC8E5,0x0004,0x0000,0x0000,0xD9CF,0x0003,0x0001, 0xD9D9,0x0001,0xBCF3,0x0017,0x000D,0x0007,0x0004,0x0002,0xBFEB,0xD9D8,0x0000,0xD9D3,0x0003,0x0000,0xD2DA,0x0000, 0xD9AF,0x0004,0x0000,0x0000,0xD2C7,0x0003,0x0001,0xC6A7,0x0001,0xBCDB,0x000A,0x0004,0x0001,0x0001,0xBDA9,0x0003, 0x0001,0xCBDB,0x0001,0xB9CD,0x0005,0x0001,0x0002,0xD9D7,0xD9D4,0x0000,0x0000,0xD9D5,0x0053,0x0023,0x0011,0x0009, 0x0000,0x0004,0x0002,0xD9C7,0xC9AE,0x0002,0xD9D6,0xBDC4,0x0004,0x0001,0x0001,0xBEDF,0x0001,0x0000,0xC1C5,0x0009, 0x0005,0x0001,0x0002,0xD9D2,0xC6CD,0x0001,0x0001,0xC7C8,0x0004,0x0000,0x0001,0xCFF3,0x0001,0x0002,0xCFC9,0xD9DD, 0x0015,0x000A,0x0006,0x0003,0x0000,0xC2FD,0x0001,0xBDF6,0x0001,0x0000,0xD9CD,0x0005,0x0001,0x0002,0xC7E3,0xD5C2, 0x0003,0x0001,0xC9B5,0x0000,0xD9D1,0x000E,0x0007,0x0003,0x0001,0xC9CB,0x0002,0xEBED,0xD5AE,0x0004,0x0002,0xD8F1, 0xB4AB,0x0000,0xB0C1,0x0007,0x0004,0x0002,0xC5F3,0xD9CC,0x0001,0xD3B6,0x0003,0x0000,0xB4DF,0x0001,0xD9D0,0x002A, 0x0015,0x000D,0x0007,0x0004,0x0002,0xB4A2,0xD9CF,0x0001,0xD9CE,0x0003,0x0001,0xB4F6,0x0000,0xBCD2,0x0001,0x0003, 0x0001,0xC8DD,0x0002,0xD0A7,0xB1B8,0x000D,0x0006,0x0003,0x0000,0xC9A1,0x0000,0xD8F7,0x0003,0x0000,0xE3BB,0x0002, 0xE1E6,0xBDDC,0x0004,0x0001,0x0001,0xB0F8,0x0000,0x0000,0xC2EE,0x0018,0x000A,0x0006,0x0003,0x0000,0xC0FC,0x0001, 0xB8B5,0x0001,0x0000,0xCFB5,0x0008,0x0004,0x0002,0xBFFE,0xB3A5,0x0002,0xD9C7,0xCEB1,0x0003,0x0001,0xD9CD,0x0000, 0xD4DB,0x000B,0x0007,0x0003,0x0001,0xCDB5,0x0002,0xC5BC,0xD5EC,0x0000,0x0000,0xB2E0,0x0004,0x0000,0x0000,0xC6F5, 0x0003,0x0000,0xD9CC,0x0000,0xB1C6,0x0000,0x0000,0x02CC,0x0159,0x009C,0x003F,0x001D,0x000C,0x0005,0x0001,0x0000, 0x0000,0xBDA1,0x0001,0x0003,0x0001,0xCDA3,0x0001,0xD7F6,0x0005,0x0001,0x0000,0x0000,0xD9C9,0x0005,0x0001,0x0002, 0xC6AB,0xD9CB,0x0003,0x0001,0xD9BC,0x0002,0xC6C1,0xF5E1,0x0015,0x000B,0x0007,0x0004,0x0002,0xCEB0,0xD9CA,0x0000, 0xBCD9,0x0001,0x0000,0xD9C8,0x0004,0x0001,0x0001,0xC7E3,0x0003,0x0001,0xD6B5,0x0001,0xD5AE,0x0001,0x0004,0x0001, 0x0001,0xD9C0,0x0004,0x0002,0xD9C1,0xD9BE,0x0002,0xC2D7,0xC4DF,0x0035,0x001B,0x000E,0x0007,0x0004,0x0002,0xD9BB, 0xD9C6,0x0001,0xBEEB,0x0003,0x0000,0xD9C5,0x0002,0xB7C2,0xE6BC,0x0007,0x0003,0x0000,0xB3AB,0x0002,0xBDE8,0xBEA2, 0x0003,0x0001,0xD9C3,0x0001,0xD2D0,0x000D,0x0007,0x0004,0x0002,0xBAF2,0xCCC8,0x0001,0xD0D2,0x0003,0x0001,0xBEF3, 0x0001,0xB5B9,0x0006,0x0003,0x0000,0xC3C7,0x0000,0xD9BF,0x0004,0x0002,0xB1B6,0xD9C4,0x0000,0xB8F6,0x0011,0x0007, 0x0000,0x0003,0x0000,0xB2D6,0x0001,0xC1A9,0x0006,0x0003,0x0001,0xD8F6,0x0001,0xD9C2,0x0001,0x0001,0xB0B3,0x000A, 0x0006,0x0003,0x0001,0xD9BA,0x0001,0xD9C3,0x0001,0x0000,0xD9BD,0x0007,0x0003,0x0000,0xBEE3,0x0002,0xB8A9,0xD0DE, 0x0003,0x0000,0xBCF3,0x0001,0xD9B3,0x005D,0x002F,0x001B,0x000B,0x0007,0x0004,0x0002,0xC1A9,0xD9B2,0x0001,0xD9B1, 0x0001,0x0000,0xD9B6,0x0008,0x0004,0x0002,0xD0C5,0xCFC0,0x0002,0xD9B9,0xD3E1,0x0004,0x0002,0xB1A3,0xD9B7,0x0002, 0xB8A9,0xD9B5,0x0008,0x0000,0x0004,0x0002,0xCFA1,0xB7FD,0x0000,0xCBD7,0x0008,0x0004,0x0002,0xD9B8,0xC0FE,0x0002, 0xC7CE,0xD9DE,0x0001,0x0001,0xBFA1,0x0016,0x000C,0x0004,0x0000,0x0000,0xE5C3,0x0004,0x0002,0xD9B4,0xB6ED,0x0002, 0xB4D9,0xCFB5,0x0006,0x0003,0x0000,0xD9B6,0x0000,0xB1E3,0x0001,0x0000,0xCDD1,0x000D,0x0007,0x0003,0x0000,0xCDA6, 0x0002,0xBED6,0xC2C2,0x0003,0x0000,0xC7D6,0x0000,0xD7F8,0x0005,0x0001,0x0002,0xBAEE,0xCEEA,0x0003,0x0001,0xD9AF, 0x0001,0xD9AD,0x002F,0x0018,0x000E,0x0008,0x0004,0x0002,0xBFEB,0xC7C8,0x0002,0xB2E0,0xD5EC,0x0003,0x0000,0xBDC4, 0x0000,0xC2C2,0x0004,0x0000,0x0001,0xCFC0,0x0003,0x0000,0xD2C0,0x0000,0xB9A9,0x000B,0x0007,0x0003,0x0001,0xB2EF, 0x0002,0xB6B1,0xC2D8,0x0000,0x0001,0xD9B0,0x0006,0x0003,0x0000,0xD9A7,0x0000,0xD9AA,0x0003,0x0000,0xCACC,0x0000, 0xC0FD,0x001C,0x000E,0x0007,0x0004,0x0002,0xD9A8,0xB3DE,0x0001,0xC0B4,0x0004,0x0002,0xEBDC,0xD6B6,0x0000,0xD9A9, 0x0007,0x0003,0x0001,0xD0CD,0x0002,0xCAB9,0xD9AB,0x0004,0x0002,0xB4CE,0xD9AE,0x0000,0xD9AC,0x000B,0x0004,0x0001, 0x0001,0xD9A5,0x0004,0x0002,0xB2A2,0xD9A6,0x0000,0xBCD1,0x0006,0x0003,0x0001,0xB0DB,0x0000,0xD1F0,0x0000,0x0001, 0xC0D0,0x00B8,0x005E,0x0035,0x0019,0x000C,0x0005,0x0002,0xC5E5,0x0001,0xD8FB,0x0003,0x0001,0xD9DD,0x0002,0xD8F4, 0xD3B6,0x0005,0x0001,0x0002,0xC4E3,0xD9A1,0x0004,0x0002,0xD8FA,0xD8FE,0x0002,0xD7F7,0xB7F0,0x000F,0x0008,0x0004, 0x0002,0xD8FD,0xD3E0,0x0002,0xD9DC,0xD9A2,0x0003,0x0001,0xBACE,0x0002,0xD5BC,0xCCE5,0x0008,0x0004,0x0002,0xD1F6, 0xD3D3,0x0002,0xD7F4,0xD7A1,0x0000,0x0002,0xB5CD,0xCEBB,0x0012,0x000B,0x0005,0x0001,0x0002,0xB2BC,0xD8F9,0x0003, 0x0000,0xB5AB,0x0001,0xB5E8,0x0001,0x0003,0x0001,0xD9A4,0x0000,0xCBC6,0x000C,0x0006,0x0003,0x0000,0xCBC5,0x0000, 0xC9EC,0x0003,0x0000,0xC1E6,0x0000,0xB0E9,0x0007,0x0003,0x0000,0xD9A3,0x0002,0xB9C0,0xB2AE,0x0001,0x0001,0xD8F9, 0x0032,0x001A,0x000D,0x0006,0x0003,0x0000,0xCEB1,0x0001,0xD8F7,0x0004,0x0002,0xC2D7,0xD8F6,0x0000,0xC9CB,0x0007, 0x0003,0x0000,0xD8F3,0x0002,0xB4AB,0xCEB0,0x0003,0x0000,0xC9A1,0x0001,0xD8F1,0x000C,0x0008,0x0004,0x0002,0xBBE1, 0xBBEF,0x0002,0xD3C5,0xD6DA,0x0000,0x0001,0xB7F2,0x0007,0x0003,0x0001,0xD0DD,0x0002,0xB7A5,0xB7FC,0x0000,0x0002, 0xBCBF,0xCEE9,0x0012,0x0006,0x0000,0x0000,0x0002,0xD2C1,0xD8F8,0x0006,0x0003,0x0001,0xC6F3,0x0001,0xB7C2,0x0003, 0x0001,0xB7DD,0x0001,0xC8CE,0x000B,0x0004,0x0001,0x0001,0xBCDB,0x0004,0x0002,0xBCFE,0xD8F5,0x0001,0xD8F2,0x0006, 0x0003,0x0000,0xD6D9,0x0000,0xD1F6,0x0001,0x0002,0xC3C7,0xD8EF,0x0064,0x0032,0x0018,0x000D,0x0006,0x0003,0x0000, 0xD2C7,0x0000,0xD8ED,0x0003,0x0001,0xD2D4,0x0002,0xC1EE,0xB4FA,0x0006,0x0003,0x0001,0xD8EE,0x0001,0xC7AA,0x0000, 0x0002,0xD8F0,0xD9DA,0x000F,0x0007,0x0003,0x0001,0xCFC9,0x0002,0xB8B6,0xD5CC,0x0004,0x0002,0xCBFB,0xCACB,0x0002, 0xD7D0,0xB2D6,0x0004,0x0000,0x0001,0xC2D8,0x0004,0x0002,0xB4D3,0xC8D4,0x0001,0xBDE9,0x001B,0x000F,0x0007,0x0004, 0x0002,0xBDF1,0xD8EB,0x0001,0xB3F0,0x0004,0x0002,0xC6CD,0xBDF6,0x0002,0xD8C6,0xD8EA,0x0008,0x0004,0x0002,0xD8EC, 0xC8CA,0x0002,0xCAB2,0xD2DA,0x0001,0x0001,0xD8E9,0x000B,0x0004,0x0000,0x0000,0xC8CB,0x0004,0x0002,0xB5AB,0xD9F4, 0x0001,0xD9F1,0x0004,0x0000,0x0000,0xC7D7,0x0004,0x0002,0xC1C1,0xCDA4,0x0002,0xBEA9,0xCFED,0x0039,0x001C,0x000E, 0x0007,0x0003,0x0001,0xC4B6,0x0002,0xBAE0,0xB2FA,0x0004,0x0002,0xD2E0,0xBAA5,0x0000,0xBDBB,0x0008,0x0004,0x0002, 0xBFBA,0xCDF6,0x0002,0xD9EF,0xD8BD,0x0003,0x0000,0xD1C7,0x0001,0xD0A9,0x000E,0x0007,0x0004,0x0002,0xD1C7,0xD8A8, 0x0000,0xD8A8,0x0003,0x0001,0xBEAE,0x0002,0xCEE5,0xD8C1,0x0007,0x0004,0x0002,0xBBA5,0xD4C6,0x0001,0xBFF7,0x0004, 0x0002,0xD3DA,0xD8A1,0x0002,0xB6FE,0xCAC2,0x0012,0x000A,0x0006,0x0003,0x0001,0xD5F9,0x0000,0xD3E8,0x0000,0x0000, 0xC1CB,0x0004,0x0000,0x0000,0xC2D2,0x0000,0x0000,0xB8C9,0x0005,0x0001,0x0001,0x0001,0xC8E9,0x0000,0x0003,0x0001, 0xC2D2,0x0000,0xC2F2,0x0000,0x0000,0x0061,0x002F,0x0015,0x0008,0x0004,0x0001,0x0000,0xD8C0,0x0000,0x0001,0xCAE9, 0x0005,0x0001,0x0002,0xCFE7,0xCFB0,0x0004,0x0002,0xD2B2,0xC6F2,0x0002,0xBEC5,0xD8BF,0x000B,0x0005,0x0001,0x0002, 0xD2D2,0xB3CB,0x0003,0x0001,0xB9D4,0x0001,0xC7C7,0x0007,0x0004,0x0002,0xC5D2,0xC6B9,0x0001,0xC0D6,0x0004,0x0002, 0xB7A6,0xBAF5,0x0002,0xD5A7,0xCEDA,0x0019,0x000D,0x0007,0x0003,0x0000,0xD6AE,0x0002,0xD2E5,0xC3B4,0x0003,0x0000, 0xD8B1,0x0000,0xBEC3,0x0005,0x0000,0x0002,0xC4CB,0xD8D7,0x0004,0x0002,0xD8AF,0xBED9,0x0000,0xC0F6,0x000E,0x0008, 0x0004,0x0002,0xD6F7,0xCEAA,0x0002,0xB5A4,0xCDE8,0x0003,0x0001,0xD8BC,0x0001,0xC1D9,0x0006,0x0003,0x0001,0xB4AE, 0x0001,0xB7E1,0x0001,0x0002,0xD6D0,0xE3DC,0x0038,0x001B,0x000F,0x0007,0x0004,0x0002,0xD1BE,0xB8F6,0x0001,0xD8AD, 0x0004,0x0002,0xC9A5,0xB2A2,0x0002,0xD1CF,0xC1BD,0x0004,0x0000,0x0001,0xB6AA,0x0004,0x0002,0xB6AA,0xD8A9,0x0002, 0xCBBF,0xB6AB,0x000F,0x0008,0x0004,0x0002,0xB4D4,0xD2B5,0x0002,0xB1FB,0xC7F0,0x0003,0x0001,0xCAC0,0x0002,0xD8A7, 0xC7D2,0x0007,0x0003,0x0000,0xD7A8,0x0002,0xB3F3,0xD8A4,0x0003,0x0001,0xD3EB,0x0002,0xB2BB,0xD8A2,0x0000,0x000C, 0x0008,0x0004,0x0002,0xCFC2,0xC9CF,0x0002,0xC8FD,0xD5C9,0x0000,0x0000,0xCDF2,0x0000,0x0003,0x0000,0xC6DF,0x0002, 0xB6A1,0xD2BB,0x0427,0x014D,0x0001,0x0001,0x0001,0x001F,0x0000,0x0001,0x0016,0x0001,0x0005,0x0001,0x0001,0x0001, 0xA2EE,0x0008,0x0004,0x0002,0xA2ED,0xA2EC,0x0002,0xA2EB,0xA2EA,0x0004,0x0002,0xA2E9,0xA2E8,0x0002,0xA2E7,0xA2E6, 0x0000,0x0000,0x0000,0x0000,0x0000,0xA2E5,0x0050,0x0001,0x0016,0x0001,0x0005,0x0001,0x0001,0x0001,0xA8E9,0x0008, 0x0004,0x0002,0xA8E8,0xA8E7,0x0002,0xA8E6,0xA8E5,0x0004,0x0002,0xA8E4,0xA8E3,0x0002,0xA8E2,0xA8E1,0x0020,0x0010, 0x0008,0x0004,0x0002,0xA8E0,0xA8DF,0x0002,0xA8DE,0xA8DD,0x0004,0x0002,0xA8DC,0xA8DB,0x0002,0xA8DA,0xA8D9,0x0008, 0x0004,0x0002,0xA8D8,0xA8D7,0x0002,0xA8D6,0xA8D5,0x0004,0x0002,0xA8D4,0xA8D3,0x0002,0xA8D2,0xA8D1,0x0010,0x0008, 0x0004,0x0002,0xA8D0,0xA8CF,0x0002,0xA8CE,0xA8CD,0x0004,0x0002,0xA8CC,0xA8CB,0x0002,0xA8CA,0xA8C9,0x0000,0x0004, 0x0002,0xA8C8,0xA8C7,0x0002,0xA8C6,0xA8C5,0x0072,0x0032,0x0012,0x0005,0x0001,0x0000,0x0001,0xA1A4,0x0005,0x0001, 0x0002,0xA5F6,0xA5F5,0x0004,0x0002,0xA5F4,0xA5F3,0x0002,0xA5F2,0xA5F1,0x0010,0x0008,0x0004,0x0002,0xA5F0,0xA5EF, 0x0002,0xA5EE,0xA5ED,0x0004,0x0002,0xA5EC,0xA5EB,0x0002,0xA5EA,0xA5E9,0x0008,0x0004,0x0002,0xA5E8,0xA5E7,0x0002, 0xA5E6,0xA5E5,0x0004,0x0002,0xA5E4,0xA5E3,0x0002,0xA5E2,0xA5E1,0x0020,0x0010,0x0008,0x0004,0x0002,0xA5E0,0xA5DF, 0x0002,0xA5DE,0xA5DD,0x0004,0x0002,0xA5DC,0xA5DB,0x0002,0xA5DA,0xA5D9,0x0008,0x0004,0x0002,0xA5D8,0xA5D7,0x0002, 0xA5D6,0xA5D5,0x0004,0x0002,0xA5D4,0xA5D3,0x0002,0xA5D2,0xA5D1,0x0010,0x0008,0x0004,0x0002,0xA5D0,0xA5CF,0x0002, 0xA5CE,0xA5CD,0x0004,0x0002,0xA5CC,0xA5CB,0x0002,0xA5CA,0xA5C9,0x0008,0x0004,0x0002,0xA5C8,0xA5C7,0x0002,0xA5C6, 0xA5C5,0x0004,0x0002,0xA5C4,0xA5C3,0x0002,0xA5C2,0xA5C1,0x0040,0x0020,0x0010,0x0008,0x0004,0x0002,0xA5C0,0xA5BF, 0x0002,0xA5BE,0xA5BD,0x0004,0x0002,0xA5BC,0xA5BB,0x0002,0xA5BA,0xA5B9,0x0008,0x0004,0x0002,0xA5B8,0xA5B7,0x0002, 0xA5B6,0xA5B5,0x0004,0x0002,0xA5B4,0xA5B3,0x0002,0xA5B2,0xA5B1,0x0010,0x0008,0x0004,0x0002,0xA5B0,0xA5AF,0x0002, 0xA5AE,0xA5AD,0x0004,0x0002,0xA5AC,0xA5AB,0x0002,0xA5AA,0xA5A9,0x0008,0x0004,0x0002,0xA5A8,0xA5A7,0x0002,0xA5A6, 0xA5A5,0x0004,0x0002,0xA5A4,0xA5A3,0x0002,0xA5A2,0xA5A1,0x0009,0x0001,0x0001,0x0003,0x0001,0xA4F3,0x0002,0xA4F2, 0xA4F1,0x0010,0x0008,0x0004,0x0002,0xA4F0,0xA4EF,0x0002,0xA4EE,0xA4ED,0x0004,0x0002,0xA4EC,0xA4EB,0x0002,0xA4EA, 0xA4E9,0x0008,0x0004,0x0002,0xA4E8,0xA4E7,0x0002,0xA4E6,0xA4E5,0x0004,0x0002,0xA4E4,0xA4E3,0x0002,0xA4E2,0xA4E1, 0x00C4,0x0000,0x0000,0x0000,0x00B7,0x007E,0x003E,0x001E,0x000E,0x0006,0x0002,0xA4E0,0x0002,0xA4DF,0xA4DE,0x0004, 0x0002,0xA4DD,0xA4DC,0x0002,0xA4DB,0xA4DA,0x0008,0x0004,0x0002,0xA4D9,0xA4D8,0x0002,0xA4D7,0xA4D6,0x0004,0x0002, 0xA4D5,0xA4D4,0x0002,0xA4D3,0xA4D2,0x0010,0x0008,0x0004,0x0002,0xA4D1,0xA4D0,0x0002,0xA4CF,0xA4CE,0x0004,0x0002, 0xA4CD,0xA4CC,0x0002,0xA4CB,0xA4CA,0x0008,0x0004,0x0002,0xA4C9,0xA4C8,0x0002,0xA4C7,0xA4C6,0x0004,0x0002,0xA4C5, 0xA4C4,0x0002,0xA4C3,0xA4C2,0x0020,0x0010,0x0008,0x0004,0x0002,0xA4C1,0xA4C0,0x0002,0xA4BF,0xA4BE,0x0004,0x0002, 0xA4BD,0xA4BC,0x0002,0xA4BB,0xA4BA,0x0008,0x0004,0x0002,0xA4B9,0xA4B8,0x0002,0xA4B7,0xA4B6,0x0004,0x0002,0xA4B5, 0xA4B4,0x0002,0xA4B3,0xA4B2,0x0010,0x0008,0x0004,0x0002,0xA4B1,0xA4B0,0x0002,0xA4AF,0xA4AE,0x0004,0x0002,0xA4AD, 0xA4AC,0x0002,0xA4AB,0xA4AA,0x0008,0x0004,0x0002,0xA4A9,0xA4A8,0x0002,0xA4A7,0xA4A6,0x0004,0x0002,0xA4A5,0xA4A4, 0x0002,0xA4A3,0xA4A2,0x000C,0x0006,0x0000,0x0000,0x0000,0x0000,0xA4A1,0x0001,0x0000,0x0000,0x0000,0xA8C6,0x0011, 0x0005,0x0000,0x0001,0x0001,0xA1E5,0x0005,0x0001,0x0002,0xA1BD,0xA1BC,0x0004,0x0002,0xA1B3,0xA1B2,0x0000,0xA1FE, 0x0010,0x0008,0x0004,0x0002,0xA1BF,0xA1BE,0x0002,0xA1BB,0xA1BA,0x0004,0x0002,0xA1B9,0xA1B8,0x0002,0xA1B7,0xA1B6, 0x0005,0x0000,0x0002,0xA1B5,0xA1B4,0x0003,0x0000,0xA1A9,0x0002,0xA1A8,0xA1A3,0x0000,0x0000,0x0000,0x0000,0x0000, 0x0000,0x0002,0xA1A2,0xA1A1,0x010C,0x0001,0x0039,0x000D,0x0001,0x0000,0x0000,0x0005,0x0001,0x0001,0x0001,0xA1E1, 0x0000,0x0000,0x0001,0xA1E2,0x0017,0x000C,0x0000,0x0000,0x0006,0x0003,0x0000,0xA1D1,0x0001,0xA1EE,0x0000,0x0000, 0xA1EF,0x0001,0x0001,0x0005,0x0001,0x0002,0xA1F1,0xA1F2,0x0001,0x0000,0xA1F0,0x000E,0x0007,0x0000,0x0000,0x0001, 0x0002,0xA1F3,0xA1F4,0x0000,0x0001,0x0001,0x0002,0xA1F7,0xA1F8,0x0000,0x0001,0x0000,0x0000,0x0001,0xA1F6,0x0092, 0x0012,0x0007,0x0001,0x0001,0x0000,0x0000,0x0000,0xA3AF,0x0001,0x0001,0x0004,0x0000,0x0001,0xA1FE,0x0001,0x0002, 0xA9EF,0xA9EE,0x0040,0x0020,0x0010,0x0008,0x0004,0x0002,0xA9ED,0xA9EC,0x0002,0xA9EB,0xA9EA,0x0004,0x0002,0xA9E9, 0xA9E8,0x0002,0xA9E7,0xA9E6,0x0008,0x0004,0x0002,0xA9E5,0xA9E4,0x0002,0xA9E3,0xA9E2,0x0004,0x0002,0xA9E1,0xA9EF, 0x0002,0xA9DF,0xA9DE,0x0010,0x0008,0x0004,0x0002,0xA9DD,0xA9DC,0x0002,0xA9DB,0xA9DA,0x0004,0x0002,0xA9D9,0xA9DF, 0x0002,0xA9D7,0xA9D6,0x0008,0x0004,0x0002,0xA9D5,0xA9D4,0x0002,0xA9D3,0xA9D2,0x0004,0x0002,0xA9D1,0xA9D7,0x0002, 0xA9CF,0xA9CE,0x0020,0x0010,0x0008,0x0004,0x0002,0xA9CD,0xA9CC,0x0002,0xA9CB,0xA9CA,0x0004,0x0002,0xA9C9,0xA9CF, 0x0002,0xA9C7,0xA9C6,0x0008,0x0004,0x0002,0xA9C5,0xA9C4,0x0002,0xA9C3,0xA9C2,0x0004,0x0002,0xA9C1,0xA9C7,0x0002, 0xA9BF,0xA9BE,0x0010,0x0008,0x0004,0x0002,0xA9BD,0xA9BC,0x0002,0xA9BB,0xA9BA,0x0004,0x0002,0xA9B9,0xA9B8,0x0002, 0xA9B7,0xA9B6,0x0008,0x0004,0x0002,0xA9B5,0xA9B4,0x0002,0xA9B3,0xA9B2,0x0004,0x0002,0xA9B1,0xA9B0,0x0002,0xA9AF, 0xA9AE,0x0018,0x0000,0x0000,0x0010,0x0008,0x0004,0x0002,0xA9AD,0xA9AC,0x0002,0xA9AB,0xA9AA,0x0004,0x0002,0xA9A9, 0xA9A8,0x0002,0xA9A7,0xA9A7,0x0000,0x0000,0x0002,0xA9A5,0xA1AA,0x0001,0x0007,0x0001,0x0001,0x0001,0x0002,0xA2C4, 0xA2C3,0x0010,0x0008,0x0004,0x0002,0xA2C2,0xA2C1,0x0002,0xA2C0,0xA2BF,0x0004,0x0002,0xA2BE,0xA2BD,0x0002,0xA2BC, 0xA2BB,0x0008,0x0004,0x0002,0xA2BA,0xA2B9,0x0002,0xA2B8,0xA2B7,0x0004,0x0002,0xA2B6,0xA2B5,0x0002,0xA2B4,0xA2B3, 0x005F,0x0048,0x0000,0x0000,0x002E,0x001E,0x000E,0x0006,0x0002,0xA2B2,0x0002,0xA2B1,0xA2D8,0x0004,0x0002,0xA2D7, 0xA2D6,0x0002,0xA2D5,0xA2D4,0x0008,0x0004,0x0002,0xA2D3,0xA2D2,0x0002,0xA2D1,0xA2D0,0x0004,0x0002,0xA2CF,0xA2CE, 0x0002,0xA2CD,0xA2CC,0x0000,0x0008,0x0004,0x0002,0xA2CB,0xA2CA,0x0002,0xA2C9,0xA2C8,0x0004,0x0002,0xA2C7,0xA2C6, 0x0000,0xA2C5,0x0000,0x000F,0x0007,0x0003,0x0001,0xA2E2,0x0002,0xA2E1,0xA2E0,0x0004,0x0002,0xA2DF,0xA2DE,0x0002, 0xA2DD,0xA2DC,0x0000,0x0004,0x0002,0xA2DB,0xA2DA,0x0000,0xA2D9,0x0009,0x0001,0x0001,0x0001,0x0001,0x0000,0x0000, 0x0001,0xA1D0,0x0001,0x0001,0x0006,0x0000,0x0001,0x0001,0x0000,0xA1CD,0x0000,0x0000,0x0001,0x0000,0xA1D1,0x007D, 0x0067,0x0021,0x0009,0x0001,0x0001,0x0001,0x0003,0x0001,0xA1DB,0x0000,0xA1DA,0x0012,0x0008,0x0001,0x0003,0x0001, 0xA1DD,0x0002,0xA1DC,0xA1DD,0x0006,0x0003,0x0000,0xA1DC,0x0001,0xA1D4,0x0000,0x0000,0xA1D9,0x0001,0x0000,0x0001, 0x0000,0xA1D5,0x0020,0x000D,0x0008,0x0004,0x0000,0x0000,0xA1D5,0x0000,0x0000,0xA1D6,0x0001,0x0001,0x0001,0xA1D7, 0x000B,0x0004,0x0000,0x0000,0xA1AB,0x0003,0x0001,0xA1CB,0x0002,0xA1C3,0xA1DF,0x0004,0x0000,0x0000,0xA1E0,0x0001, 0x0000,0xA1D3,0x0019,0x000E,0x0007,0x0003,0x0001,0xA1D2,0x0002,0xA1C8,0xA1C9,0x0004,0x0002,0xA1C5,0xA1C4,0x0001, 0xA1AC,0x0004,0x0000,0x0001,0xA9A6,0x0003,0x0000,0xA1CF,0x0002,0xA1DE,0xA1D8,0x0005,0x0000,0x0001,0x0000,0xA1CC, 0x0004,0x0001,0x0001,0xA1C6,0x0000,0x0001,0xA1C7,0x0008,0x0000,0x0000,0x0000,0x0001,0x0000,0x0000,0xA1CA,0x0001, 0x0001,0x0001,0x0007,0x0003,0x0001,0xA1FD,0x0002,0xA1FA,0xA1FC,0x0000,0x0000,0xA1FB,0x0025,0x001D,0x0001,0x0000, 0x000F,0x0007,0x0003,0x0001,0xA2FC,0x0002,0xA2FB,0xA2FA,0x0004,0x0002,0xA2F9,0xA2F8,0x0002,0xA2F7,0xA2F6,0x0008, 0x0004,0x0002,0xA2F5,0xA2F4,0x0002,0xA2F3,0xA2F2,0x0000,0x0000,0xA2F1,0x0001,0x0001,0x0000,0x0001,0x0001,0x0000, 0xA1ED,0x0000,0x0000,0x0000,0x0001,0x0000,0x0000,0x0001,0xA1E6,0x0032,0x0000,0x0000,0x0000,0x0000,0x0000,0x0001, 0x0011,0x0001,0x0005,0x0000,0x0001,0x0000,0xA1F9,0x0007,0x0003,0x0000,0xA3E0,0x0002,0xA1E5,0xA1E4,0x0000,0x0001, 0xA1EB,0x000C,0x0005,0x0001,0x0001,0x0001,0xA1AD,0x0000,0x0003,0x0000,0xA1A7,0x0001,0xA1A4,0x000A,0x0005,0x0000, 0x0002,0xA1B1,0xA1B0,0x0000,0x0002,0xA1AF,0xA1AE,0x0000,0x0000,0x0000,0xA1AA,0x0001,0x0001,0x0108,0x00D5,0x0060, 0x0001,0x001F,0x0001,0x000E,0x0006,0x0003,0x0001,0xA7D7,0x0001,0xA7F1,0x0004,0x0002,0xA7F0,0xA7EF,0x0002,0xA7EE, 0xA7ED,0x0008,0x0004,0x0002,0xA7EC,0xA7EB,0x0002,0xA7EA,0xA7E9,0x0004,0x0002,0xA7E8,0xA7E7,0x0002,0xA7E6,0xA7E5, 0x0020,0x0010,0x0008,0x0004,0x0002,0xA7E4,0xA7E3,0x0002,0xA7E2,0xA7E1,0x0004,0x0002,0xA7E0,0xA7DF,0x0002,0xA7DE, 0xA7DD,0x0008,0x0004,0x0002,0xA7DC,0xA7DB,0x0002,0xA7DA,0xA7D9,0x0004,0x0002,0xA7D8,0xA7D6,0x0002,0xA7D5,0xA7D4, 0x0010,0x0008,0x0004,0x0002,0xA7D3,0xA7D2,0x0002,0xA7D1,0xA7C1,0x0004,0x0002,0xA7C0,0xA7BF,0x0002,0xA7BE,0xA7BD, 0x0008,0x0004,0x0002,0xA7BC,0xA7BB,0x0002,0xA7BA,0xA7B9,0x0004,0x0002,0xA7B8,0xA7B7,0x0002,0xA7B6,0xA7B5,0x0030, 0x0029,0x0020,0x0010,0x0008,0x0004,0x0002,0xA7B4,0xA7B3,0x0002,0xA7B2,0xA7B1,0x0004,0x0002,0xA7B0,0xA7AF,0x0002, 0xA7AE,0xA7AD,0x0008,0x0004,0x0002,0xA7AC,0xA7AB,0x0002,0xA7AA,0xA7A9,0x0004,0x0002,0xA7A8,0xA7A6,0x0002,0xA7A5, 0xA7A4,0x0000,0x0000,0x0004,0x0002,0xA7A3,0xA7A2,0x0000,0xA7A1,0x0000,0x0000,0x0000,0x0000,0x0001,0xA7A7,0x0011, 0x0001,0x0001,0x0007,0x0003,0x0001,0xA6D8,0x0002,0xA6D7,0xA6D6,0x0004,0x0002,0xA6D5,0xA6D4,0x0002,0xA6D3,0xA6D2, 0x001F,0x000F,0x0007,0x0003,0x0001,0xA6D1,0x0002,0xA6D0,0xA6CF,0x0004,0x0002,0xA6CE,0xA6CD,0x0002,0xA6CC,0xA6CB, 0x0008,0x0004,0x0002,0xA6CA,0xA6C9,0x0002,0xA6C8,0xA6C7,0x0004,0x0002,0xA6C6,0xA6C5,0x0002,0xA6C4,0xA6C3,0x0006, 0x0000,0x0000,0x0002,0xA6C2,0xA6C1,0x0007,0x0003,0x0001,0xA6B8,0x0002,0xA6B7,0xA6B6,0x0004,0x0002,0xA6B5,0xA6B4, 0x0002,0xA6B3,0xA1C6,0x0028,0x0000,0x0000,0x001F,0x000F,0x0007,0x0003,0x0001,0xA6B1,0x0002,0xA1C7,0xA6AF,0x0004, 0x0002,0xA6AE,0xA6AD,0x0002,0xA6AC,0xA1C4,0x0008,0x0004,0x0002,0xA6AA,0xA6A9,0x0002,0xA6A8,0xA6A7,0x0004,0x0002, 0xA6A6,0xA6A5,0x0002,0xA6A4,0xA6A3,0x0000,0x0000,0x0000,0x0002,0xA6A2,0xA6A1,0x0001,0x0000,0x0001,0x0001,0x0000, 0x0003,0x0001,0xA1A5,0x0001,0xA1A6,0x001F,0x0001,0x0001,0x0000,0x0011,0x0005,0x0001,0x0001,0x0001,0xA8B8,0x0006, 0x0003,0x0001,0xA8B7,0x0001,0xA8B6,0x0003,0x0001,0xA8B5,0x0001,0xA8B3,0x0000,0x0006,0x0003,0x0001,0xA8AF,0x0001, 0xA8AB,0x0000,0x0001,0xA8A3,0x0016,0x0008,0x0001,0x0001,0x0001,0x0000,0x0000,0x0000,0xA8B1,0x0007,0x0001,0x0000, 0x0001,0x0001,0x0000,0xA8AD,0x0001,0x0001,0x0000,0x0000,0x0000,0xA8A9,0x0030,0x000C,0x0006,0x0001,0x0000,0x0000, 0x0000,0xA8A7,0x0000,0x0000,0x0000,0x0000,0xA8A5,0x0012,0x0008,0x0004,0x0001,0x0000,0xA8A1,0x0001,0x0001,0xA8B9, 0x0006,0x0003,0x0001,0xA8B2,0x0000,0xA8B4,0x0000,0x0000,0xA1C2,0x000A,0x0005,0x0000,0x0002,0xA8AE,0xA8B0,0x0001, 0x0002,0xA8AA,0xA8AC,0x0000,0x0003,0x0001,0xA8BA,0x0002,0xA8A6,0xA8A8,0x000C,0x0000,0x0006,0x0000,0x0001,0x0002, 0xA8A2,0xA8A4,0x0001,0x0000,0x0000,0xA1C1,0x0001,0x0006,0x0000,0x0001,0x0002,0xA1C0,0xA1E3,0x0004,0x0001,0x0001, 0xA1A7,0x0003,0x0000,0xA1EC,0x0001,0xA1E8, }; // ucs2_to_gb2312_elements const TConvFlatTree ucs2_to_gb2312 = { 0x00A4, // min key 0xFFE5, // max key 0x0000, // links space start 0x7FFF, // links space end ucs2_to_gb2312_numelems, // number of elements (treeval_t *)&ucs2_to_gb2312_elements // elements }; // ucs2_to_gb2312 const size_t gb2312_to_ucs2_numelems = 15470; const treeval_t gb2312_to_ucs2_elements[gb2312_to_ucs2_numelems] = { 0xC112,0xB0BD,0xA85E,0xA48F,0xA24B,0xA177,0xA0C0,0xA0AC,0xA056,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x9F44,0x9F3E, 0xA002,0x9F3D,0xA002,0x9F37,0x9F39,0xA004,0xA002,0x9F2F,0x9F2C,0xA002,0x9F22,0xA002,0x9EEF,0x9EF2,0xA00A,0xA004, 0xA002,0x9EE5,0x9EE7,0xA002,0x9EF7,0xA002,0x9EE2,0x9EDF,0xA006,0xA002,0x9EE0,0xA002,0x9EDD,0x9EDC,0xA002,0x9EDB, 0xA002,0x9E9F,0x9E9D,0xA016,0xA00A,0xA004,0xA002,0x93D6,0x9E92,0xA002,0x9E8B,0xA002,0x9E88,0x9E87,0xA006,0xA002, 0x9E82,0xA002,0x7E3B,0x9EBE,0xA002,0x9EBD,0xA002,0x9B23,0x9B1F,0xA00A,0xA004,0xA002,0x9B22,0x9B0F,0xA002,0x9B08, 0xA002,0x9AF9,0x9AED,0xA006,0xA002,0x9AFB,0xA002,0x9AEB,0x9AEF,0xA002,0x9AE6,0xA002,0x9AE1,0x9ADF,0xA02A,0xA014, 0xA00A,0xA004,0xA002,0x9954,0x9955,0xA002,0x992E,0xA002,0x995C,0x9957,0xA004,0xA002,0x9B51,0x9B4D,0xA002,0x9B48, 0xA002,0x9B4E,0x9B58,0xA00A,0xA004,0xA002,0x9B43,0x9B45,0xA002,0x9AD1,0xA002,0x9AD5,0x9AD6,0xA006,0xA002,0x9AC2, 0xA002,0x9ACF,0x9AC0,0xA002,0x9AC1,0xA002,0x9ABC,0x9ABA,0xA016,0xA00A,0xA004,0xA002,0x9AB6,0x9E58,0xA002,0x9AB7, 0xA002,0x9AB0,0x9AB1,0xA006,0xA002,0x97B4,0xA002,0x97B2,0x97A3,0xA002,0x97AB,0xA002,0x97C9,0x9794,0xA00A,0xA004, 0xA002,0x9792,0x97C3,0xA002,0x9785,0xA002,0x977C,0x9CE2,0xA006,0xA002,0x9CDF,0xA002,0x9CDD,0x9CDC,0xA002,0x9CD9, 0xA002,0x9CD8,0x9CD7,0xA000,0xA000,0xA000,0xA00A,0xA004,0xA002,0x9CD5,0x9CD4,0xA002,0x9CD3,0xA002,0x9CD0,0x9CCF, 0xA004,0xA002,0x9CCE,0x9CCD,0xA000,0x9F07,0xA00A,0xA001,0xA001,0xA001,0xA001,0xA001,0xA001,0xA002,0x9CCB,0x9CCA, 0xA056,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x9CC7,0x9CC6,0xA002,0x9CC5,0xA002,0x9CC4,0x9CBD,0xA004,0xA002,0x9CBC, 0x9CBB,0xA002,0x9CBA,0xA002,0x9CB7,0x9CB6,0xA00A,0xA004,0xA002,0x9CB5,0x9CB4,0xA002,0x9CB3,0xA002,0x9CB2,0x9CB1, 0xA006,0xA002,0x9CB0,0xA002,0x9CAE,0x9CAD,0xA002,0x9CAB,0xA002,0x9CA9,0x9CA8,0xA016,0xA00A,0xA004,0xA002,0x9CA7, 0x9CA6,0xA002,0x9CA5,0xA002,0x9CA3,0x9CA2,0xA006,0xA002,0x9CA1,0xA002,0x9CA0,0x9C9F,0xA002,0x9C9E,0xA002,0x9C9B, 0x9C9A,0xA00A,0xA004,0xA002,0x9C95,0x9C94,0xA002,0x9C92,0xA002,0x9C91,0x9C90,0xA006,0xA002,0x9C8E,0xA002,0x9C8B, 0x7A4C,0xA002,0x9C88,0xA002,0x9C87,0x9C86,0xA02B,0xA016,0xA00A,0xA004,0xA002,0x9C85,0x9C82,0xA002,0x9C7F,0xA002, 0x946B,0x943E,0xA006,0xA002,0x938F,0xA002,0x93CA,0x936A,0xA002,0x93E8,0xA002,0x92C8,0x947E,0xA009,0xA004,0xA002, 0x928E,0x96E0,0xA002,0x77BF,0xA000,0x96D2,0xA006,0xA002,0x96CB,0xA002,0x96BC,0x96B9,0xA002,0x9F0D,0xA002,0x9F0B, 0x9EFE,0xA016,0xA00A,0xA004,0xA002,0x9F8C,0x9F8A,0xA002,0x9F89,0xA002,0x9F88,0x9F87,0xA006,0xA002,0x9F86,0xA002, 0x9F85,0x9F83,0xA002,0x9F80,0xA002,0x973E,0x9730,0xA00A,0xA004,0xA002,0x9744,0x972A,0xA002,0x970E,0xA002,0x970F, 0x9708,0xA006,0xA002,0x973D,0xA002,0x9706,0x96EF,0xA002,0x9742,0xA002,0x96E9,0x975A,0xA01D,0xA00E,0xA000,0xA000, 0xA000,0xA000,0xA004,0xA002,0x8B26,0x8A3F,0xA002,0x89EF,0xA002,0x89EB,0x89E5,0xA001,0xA001,0xA001,0xA001,0xA005, 0xA001,0xA002,0x89DC,0x89DA,0xA002,0x89F4,0xA002,0x89D6,0x659B,0xA0AC,0xA056,0xA02A,0xA014,0xA00A,0xA004,0xA002, 0x8C94,0x8C98,0xA002,0x8C85,0xA002,0x8C8A,0x8C82,0xA004,0xA002,0x8C78,0x8E9E,0xA002,0x8EA6,0xA002,0x8E90,0x8E94, 0xA00A,0xA004,0xA002,0x8EAA,0x8E85,0xA002,0x8E74,0xA002,0x8E6F,0x8E7C,0xA006,0xA002,0x8E76,0xA002,0x8E70,0x8E4A, 0xA002,0x8E63,0xA002,0x8EA1,0x8E42,0xA016,0xA00A,0xA004,0xA002,0x8E41,0x8E49,0xA002,0x8E31,0xA002,0x8E3D,0x8E35, 0xA006,0xA002,0x8E39,0xA002,0x8E40,0x8E3A,0xA002,0x8E91,0xA002,0x8E23,0x8E2E,0xA00A,0xA004,0xA002,0x8E93,0x8E1F, 0xA002,0x8E1D,0xA002,0x8E14,0x8DFD,0xA006,0xA002,0x8E09,0xA002,0x8DE4,0x8E8B,0xA002,0x8E9A,0xA002,0x8DE3,0x8E55, 0xA02A,0xA014,0xA00A,0xA004,0xA002,0x8E7A,0x8DEC,0xA002,0x8DC6,0xA002,0x8DDB,0x8DCF,0xA004,0xA002,0x8DCE,0x8E92, 0xA002,0x8DDA,0xA002,0x8DD7,0x8DD6,0xA00A,0xA004,0xA002,0x8E4C,0x8DBA,0xA002,0x8DBC,0xA002,0x8DBF,0x8DB5,0xA006, 0xA002,0x8E69,0xA002,0x8E59,0x8E05,0xA002,0x8DEB,0xA002,0x8E89,0x9E7E,0xA016,0xA00A,0xA004,0xA002,0x8C55,0x91BA, 0xA002,0x91B4,0xA002,0x91B5,0x91AF,0xA006,0xA002,0x91AE,0xA002,0x91AD,0x91AA,0xA002,0x91A3,0xA002,0x91A2,0x9191, 0xA00A,0xA004,0xA002,0x918D,0x9190,0xA002,0x9185,0xA002,0x918C,0x9179,0xA006,0xA002,0x9174,0xA002,0x9172,0x91C3, 0xA002,0x91C5,0xA002,0x916F,0x9169,0xA000,0xA000,0xA000,0xA000,0xA004,0xA002,0x9170,0x9161,0xA000,0x9162,0xA0DA, 0xA0C0,0xA015,0xA001,0xA001,0xA001,0xA006,0xA001,0xA001,0xA002,0x9164,0x914F,0xA006,0xA002,0x914E,0xA002,0x9150, 0x914A,0xA002,0x8C49,0xA002,0x8C47,0x8D6D,0xA056,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x8D67,0x8DB2,0xA002,0x8D91, 0xA002,0x8D94,0x8D84,0xA004,0xA002,0x8D73,0x9EB4,0xA002,0x9EB8,0xA002,0x7E9B,0x7E47,0xA00A,0xA004,0xA002,0x7DAE, 0x7DA6,0xA002,0x7E36,0xA002,0x7CF8,0x7FF3,0xA006,0xA002,0x7FEE,0xA002,0x7FE9,0x7FE6,0xA002,0x7FE1,0xA002,0x7FE5, 0x7FD5,0xA016,0xA00A,0xA004,0xA002,0x7FCE,0x7FBF,0xA002,0x81EE,0xA002,0x826E,0x7CE8,0xA006,0xA002,0x7CD7,0xA002, 0x7CC5,0x7CC8,0xA002,0x7CCD,0xA002,0x7CCC,0x7CC7,0xA00A,0xA004,0xA002,0x7CDD,0x7CBD,0xA002,0x7CBC,0xA002,0x7CB2, 0x7CA2,0xA006,0xA002,0x7C9E,0xA002,0x7CF6,0x7CF2,0xA002,0x7C91,0xA002,0x6549,0x7C7C,0xA029,0xA014,0xA00A,0xA004, 0xA002,0x7FB2,0x7FB0,0xA002,0x7FAF,0xA002,0x7FA7,0x7FA5,0xA004,0xA002,0x7F9D,0x895E,0xA002,0x88DF,0xA002,0x88D8, 0x8888,0xA009,0xA004,0xA002,0x88CA,0x887E,0xA002,0x8268,0xA000,0x825F,0xA006,0xA002,0x824F,0xA002,0x824B,0x8249, 0xA002,0x8244,0xA002,0x823E,0x8234,0xA016,0xA00A,0xA004,0xA002,0x8233,0x8263,0xA002,0x8238,0xA002,0x822B,0x8228, 0xA006,0xA002,0x822F,0xA002,0x822D,0x8223,0xA002,0x8222,0xA002,0x8221,0x8844,0xA00A,0xA004,0xA002,0x81EC,0x8204, 0xA002,0x8202,0xA002,0x8201,0x81FE,0xA006,0xA002,0x7C40,0xA002,0x7C5F,0x7C38,0xA002,0x7C26,0xA002,0x7C2A,0x7C1F, 0xA001,0xA001,0xA001,0xA001,0xA00A,0xA004,0xA002,0x7C0B,0x7C6A,0xA002,0x7C0F,0xA002,0x7BFC,0x7BFE,0xA006,0xA002, 0x7C0C,0xA002,0x7BEA,0x7BE6,0xA002,0x7BE5,0xA002,0x7BDA,0x7BDD,0xA0A8,0xA000,0xA056,0xA02A,0xA014,0xA00A,0xA004, 0xA002,0x7BCC,0x7BC1,0xA002,0x7C23,0xA002,0x7BB4,0x7C2B,0xA004,0xA002,0x7BA2,0x7B9C,0xA002,0x7C1E,0xA002,0x7B85, 0x7C5C,0xA00A,0xA004,0xA002,0x7B9D,0x7BDB,0xA002,0x7BB8,0xA002,0x7BCB,0x7C00,0xA006,0xA002,0x7B90,0xA002,0x7BE0, 0x7B72,0xA002,0x7B62,0xA002,0x7B7B,0x7B6E,0xA016,0xA00A,0xA004,0xA002,0x7B60,0x7B8F,0xA002,0x7B4C,0xA002,0x7B75, 0x7B45,0xA006,0xA002,0x7BF3,0xA002,0x7B58,0x7B1E,0xA002,0x7C69,0xA002,0x7B33,0x7B24,0xA00A,0xA004,0xA002,0x7B25, 0x7B20,0xA002,0x7B31,0xA002,0x7B2E,0x7B19,0xA006,0xA002,0x7B2A,0xA002,0x7B38,0x7B47,0xA002,0x7B0F,0xA002,0x7B2B, 0x7B0A,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x7B67,0x7B32,0xA002,0x7BE4,0xA002,0x7B08,0x7AFD,0xA004,0xA002,0x7AFA, 0x8210,0xA002,0x7F45,0xA002,0x7F44,0x7F4C,0xA00A,0xA004,0xA002,0x7F36,0x883C,0xA002,0x8839,0xA002,0x8821,0x881B, 0xA006,0xA002,0x880A,0xA002,0x87FE,0x8813,0xA002,0x8816,0xA002,0x87EE,0x87E0,0xA016,0xA00A,0xA004,0xA002,0x87EA, 0x87DB,0xA002,0x87CA,0xA002,0x87C0,0x87D1,0xA006,0xA002,0x87BD,0xA002,0x87D3,0x87CB,0xA002,0x87B3,0xA002,0x87B5, 0x87AC,0xA00A,0xA004,0xA002,0x87E5,0x87AB,0xA002,0x8783,0xA002,0x8797,0x87AD,0xA000,0xA002,0x8785,0xA002,0x8788, 0x87C6,0xA020,0xA001,0xA001,0xA008,0xA001,0xA001,0xA002,0x87D2,0xA002,0x87A8,0x87AF,0xA00A,0xA004,0xA002,0x8793, 0x8765,0xA002,0x8759,0xA002,0x8764,0x87BB,0xA006,0xA002,0x8763,0xA002,0x8753,0x878B,0xA002,0x876E,0xA002,0x874C, 0x8770,0xA056,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x8760,0x877B,0xA002,0x8811,0xA002,0x877D,0x8722,0xA004,0xA002, 0x8782,0x873F,0xA002,0x8E21,0xA002,0x8729,0x8731,0xA00A,0xA004,0xA002,0x8734,0x87C8,0xA002,0x873E,0xA002,0x871A, 0x872E,0xA006,0xA002,0x8725,0xA002,0x871E,0x873B,0xA002,0x8723,0xA002,0x8709,0x870D,0xA016,0xA00A,0xA004,0xA002, 0x870A,0x8708,0xA002,0x86F8,0xA002,0x8707,0x8704,0xA006,0xA002,0x86D1,0xA002,0x8746,0x86DF,0xA002,0x8810,0xA002, 0x86DE,0x8713,0xA00A,0xA004,0xA002,0x86D0,0x8784,0xA002,0x86ED,0xA002,0x87EF,0x86FA,0xA006,0xA002,0x86EC,0xA002, 0x86B4,0x87F6,0xA002,0x86C9,0xA002,0x86AF,0x86B1,0xA02C,0xA016,0xA00A,0xA004,0xA002,0x86BA,0x86B0,0xA002,0x8823, 0xA002,0x86B5,0x86C4,0xA006,0xA002,0x86B6,0xA002,0x86A9,0x8693,0xA002,0x86AA,0xA002,0x86A3,0x86A7,0xA00A,0xA004, 0xA002,0x8814,0x8706,0xA002,0x868B,0xA002,0x868D,0x86A8,0xA006,0xA002,0x867B,0xA002,0x867C,0x8696,0xA002,0x8806, 0xA002,0x87E3,0x866F,0xA016,0xA00A,0xA004,0xA002,0x8654,0x864D,0xA002,0x98A6,0xA002,0x98A5,0x98A2,0xA006,0xA002, 0x98A1,0xA002,0x989F,0x989E,0xA002,0x989B,0xA002,0x989A,0x9894,0xA000,0xA004,0xA002,0x988F,0x988D,0xA002,0x988C, 0xA000,0x9889,0xA1B8,0xA0C3,0xA026,0xA001,0xA001,0xA001,0xA00D,0xA001,0xA006,0xA002,0x9883,0xA002,0x9880,0x9878, 0xA002,0x8983,0xA002,0x8071,0x8075,0xA00A,0xA004,0xA002,0x8052,0x8079,0xA002,0x8046,0xA002,0x8043,0x8035,0xA006, 0xA002,0x81F7,0xA002,0x8031,0x8028,0xA002,0x8029,0xA002,0x802C,0x8026,0xA000,0xA056,0xA02A,0xA014,0xA00A,0xA004, 0xA002,0x8025,0x8022,0xA002,0x8020,0xA002,0x801C,0x8016,0xA004,0xA002,0x8014,0x8012,0xA002,0x77DC,0xA002,0x76B4, 0x76B8,0xA00A,0xA004,0xA002,0x80E5,0x758B,0xA002,0x897B,0xA002,0x8966,0x8941,0xA006,0xA002,0x8936,0xA002,0x892B, 0x8964,0xA002,0x890A,0xA002,0x8938,0x8913,0xA016,0xA00A,0xA004,0xA002,0x8919,0x8921,0xA002,0x88F0,0xA002,0x88FE, 0x88E8,0xA006,0xA002,0x88FC,0xA002,0x891A,0x88F1,0xA002,0x8949,0xA002,0x895D,0x88CE,0xA00A,0xA004,0xA002,0x8933, 0x88C9,0xA002,0x88BC,0xA002,0x88B7,0x8960,0xA006,0xA002,0x88A2,0xA002,0x8882,0x887F,0xA002,0x887D,0xA002,0x8872, 0x8869,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x8864,0x7AB3,0xA002,0x7AB6,0xA002,0x7AA8,0x7AAC,0xA004,0xA002,0x7AA0, 0x7AC7,0xA002,0x7A95,0xA002,0x7A88,0x7A86,0xA00A,0xA004,0xA002,0x7A80,0x7A79,0xA002,0x7A78,0xA002,0x7AE6,0x7FCA, 0xA006,0xA002,0x766F,0xA002,0x7672,0x7656,0xA002,0x765C,0xA002,0x7654,0x7669,0xA016,0xA00A,0xA004,0xA002,0x764D, 0x7633,0xA002,0x766E,0xA002,0x7643,0x7635,0xA006,0xA002,0x766D,0xA002,0x7630,0x762D,0xA002,0x7640,0xA002,0x818C, 0x7622,0xA000,0xA000,0xA002,0x763C,0x761B,0xA0C0,0xA02B,0xA001,0xA001,0xA013,0xA007,0xA001,0xA002,0x7619,0xA002, 0x7615,0x7618,0xA006,0xA002,0x7625,0xA002,0x760A,0x761E,0xA002,0x760C,0xA002,0x7649,0x7600,0xA00A,0xA004,0xA002, 0x7610,0x75FF,0xA002,0x75FC,0xA002,0x75F1,0x7603,0xA006,0xA002,0x75E7,0xA002,0x7647,0x75E4,0xA002,0x75E6,0xA002, 0x7646,0x75E3,0xA056,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x75CD,0x75D6,0xA002,0x75C2,0xA002,0x75C3,0x75B0,0xA004, 0xA002,0x76B0,0x75C4,0xA002,0x75B8,0xA002,0x75FE,0x75B3,0xA00A,0xA004,0xA002,0x75A3,0x75AC,0xA002,0x759D,0xA002, 0x7658,0x7664,0xA006,0xA002,0x7594,0xA002,0x7592,0x9E73,0xA002,0x9E6D,0xA002,0x9E71,0x9E6C,0xA016,0xA00A,0xA004, 0xA002,0x9E6B,0x9E6A,0xA002,0x9E69,0xA002,0x9E68,0x9E67,0xA006,0xA002,0x9E66,0xA002,0x9E63,0x9E5E,0xA002,0x9E5C, 0xA002,0x9E5B,0x9E5A,0xA00A,0xA004,0xA002,0x9E57,0x9E55,0xA002,0x9E51,0xA002,0x9E4E,0x9E4C,0xA006,0xA002,0x9E4B, 0xA002,0x9E49,0x9E48,0xA002,0x9E47,0xA002,0x9E46,0x9E44,0xA02B,0xA016,0xA00A,0xA004,0xA002,0x9E42,0x9E41,0xA002, 0x9E3E,0xA002,0x9E3A,0x9E39,0xA006,0xA002,0x9E37,0xA002,0x9E38,0x9E36,0xA002,0x9E31,0xA002,0x9E32,0x9E2C,0xA00A, 0xA004,0xA002,0x9E2B,0x9E2A,0xA002,0x9E29,0xA002,0x9E28,0x9E22,0xA006,0xA002,0x9E20,0xA002,0x752C,0x74E0,0xA002, 0x74DE,0xA000,0x76A4,0xA000,0xA00A,0xA004,0xA002,0x7693,0x768E,0xA002,0x7688,0xA002,0x7A70,0x99A5,0xA006,0xA002, 0x9ECF,0xA002,0x7A61,0x7A37,0xA000,0x7A39,0xA001,0xA001,0xA008,0xA001,0xA001,0xA001,0xA001,0xA002,0x7A14,0x7A1E, 0xA015,0xA009,0xA004,0xA002,0x7A02,0x7A03,0xA002,0x5D47,0xA000,0x7A06,0xA006,0xA002,0x79EB,0xA002,0x79ED,0x79D5, 0xA002,0x96C9,0xA002,0x77EC,0x77E7,0xA00A,0xA004,0xA002,0x953A,0x9573,0xA002,0x9572,0xA002,0x9571,0x956F,0xA006, 0xA002,0x956C,0xA002,0x956B,0x956A,0xA002,0x9569,0xA002,0x9568,0x9567,0xA154,0xA090,0xA000,0xA056,0xA02A,0xA014, 0xA00A,0xA004,0xA002,0x9566,0x9565,0xA002,0x9564,0xA002,0x9562,0x9561,0xA004,0xA002,0x955D,0x955F,0xA002,0x955E, 0xA002,0x955B,0x9559,0xA00A,0xA004,0xA002,0x9558,0x9557,0xA002,0x9556,0xA002,0x9554,0x9553,0xA006,0xA002,0x9552, 0xA002,0x954F,0x954E,0xA002,0x954C,0xA002,0x9549,0x9546,0xA016,0xA00A,0xA004,0xA002,0x9545,0x9544,0xA002,0x9535, 0xA002,0x9542,0x953F,0xA006,0xA002,0x953E,0xA002,0x953C,0x9538,0xA002,0x9537,0xA002,0x9536,0x9534,0xA00A,0xA004, 0xA002,0x9532,0x9531,0xA002,0x952C,0xA002,0x9529,0x952B,0xA006,0xA002,0x952A,0xA002,0x9522,0x951F,0xA002,0x951E, 0xA002,0x951D,0x951B,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x9518,0x9516,0xA002,0x9515,0xA002,0x9514,0x9513,0xA004, 0xA002,0x9512,0x950F,0xA002,0x950E,0xA002,0x950D,0x950A,0xA00A,0xA004,0xA002,0x9509,0x9507,0xA002,0x9506,0xA002, 0x9502,0x9503,0xA006,0xA002,0x94FF,0xA002,0x94FD,0x94FC,0xA002,0x94F9,0xA002,0x94F7,0x94F5,0xA000,0xA00A,0xA004, 0xA002,0x94F4,0x94F3,0xA002,0x94EF,0xA002,0x94EE,0x94EB,0xA000,0xA000,0x94E9,0xA039,0xA001,0xA00C,0xA001,0xA001, 0xA004,0xA001,0xA001,0x94EA,0xA002,0x94E8,0xA002,0x94E7,0x94E5,0xA016,0xA00A,0xA004,0xA002,0x94E4,0x94E2,0xA002, 0x94E0,0xA002,0x94DF,0x94DE,0xA006,0xA002,0x94DB,0xA002,0x94D8,0x94D9,0xA002,0x94D7,0xA002,0x94D6,0x94D5,0xA00A, 0xA004,0xA002,0x94D2,0x94D1,0xA002,0x94D0,0xA002,0x94CE,0x94CD,0xA006,0xA002,0x94CC,0xA002,0x94CB,0x94CA,0xA002, 0x94C9,0xA002,0x94C8,0x94C4,0xA056,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x94BF,0x94BD,0xA002,0x94BC,0xA002,0x94BA, 0x94B9,0xA004,0xA002,0x94B8,0x94B7,0xA002,0x94B6,0xA002,0x94B4,0x94B2,0xA00A,0xA004,0xA002,0x94B0,0x94AF,0xA002, 0x94AC,0xA002,0x94AD,0x94AA,0xA006,0xA002,0x94AB,0xA002,0x94A4,0x94A3,0xA002,0x949C,0xA002,0x949B,0x949A,0xA016, 0xA00A,0xA004,0xA002,0x9495,0x9497,0xA002,0x9494,0xA002,0x9490,0x948F,0xA006,0xA002,0x948D,0xA002,0x948C,0x948A, 0xA002,0x948B,0xA002,0x9487,0x9486,0xA00A,0xA004,0xA002,0x9485,0x8832,0xA002,0x76E5,0xA002,0x76CD,0x7F7E,0xA006, 0xA002,0x7F88,0xA002,0x7F79,0x7F71,0xA002,0x7F86,0xA002,0x7F68,0x8A48,0xA02C,0xA016,0xA00A,0xA004,0xA002,0x7F5F, 0x7F61,0xA002,0x7F66,0xA002,0x7583,0x7579,0xA006,0xA002,0x7572,0xA002,0x755B,0x7548,0xA002,0x754B,0xA002,0x754E, 0x7540,0xA00A,0xA004,0xA002,0x753A,0x77BD,0xA002,0x77B5,0xA002,0x77B0,0x77A0,0xA006,0xA002,0x779F,0xA002,0x7791, 0x778C,0xA002,0x7780,0xA002,0x777D,0x778D,0xA000,0xA000,0xA004,0xA002,0x777F,0x7765,0xA000,0x96CE,0xA041,0xA001, 0xA001,0xA013,0xA001,0xA006,0xA001,0xA001,0xA002,0x7768,0x775A,0xA006,0xA002,0x7743,0xA002,0x7747,0x77BC,0xA002, 0x775E,0xA002,0x7738,0x7735,0xA016,0xA00A,0xA004,0xA002,0x7726,0x772D,0xA002,0x7719,0xA002,0x7722,0x771A,0xA006, 0xA002,0x7708,0xA002,0x7707,0x76F9,0xA002,0x770D,0xA002,0x7704,0x76F1,0xA00A,0xA004,0xA002,0x9EFC,0x9EFB,0xA002, 0x9EF9,0xA002,0x9F9B,0x7934,0xA006,0xA002,0x791E,0xA002,0x7924,0x7913,0xA002,0x78F4,0xA002,0x7905,0x78F2,0xA000, 0xA056,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x78EC,0x78C9,0xA002,0x78D9,0xA002,0x78D4,0x78A5,0xA004,0xA002,0x78B9, 0x78B2,0xA002,0x78A3,0xA002,0x78A1,0x78E3,0xA00A,0xA004,0xA002,0x7887,0x789A,0xA002,0x7893,0xA002,0x78E7,0x786A, 0xA006,0xA002,0x784C,0xA002,0x7847,0x7850,0xA002,0x7826,0xA002,0x78FD,0x7864,0xA016,0xA00A,0xA004,0xA002,0x786D, 0x784E,0xA002,0x7829,0xA002,0x7823,0x782C,0xA006,0xA002,0x7825,0xA002,0x783C,0x781F,0xA002,0x7931,0xA002,0x792A, 0x7839,0xA00A,0xA004,0xA002,0x781D,0x781C,0xA002,0x782D,0xA002,0x65B2,0x7811,0xA006,0xA002,0x7818,0xA002,0x7868, 0x7809,0xA002,0x78AD,0xA002,0x77F8,0x78EF,0xA000,0xA014,0xA00A,0xA004,0xA002,0x6DFC,0x6FA9,0xA002,0x6C93,0xA002, 0x807F,0x8080,0xA004,0xA002,0x6207,0x61E3,0xA002,0x61CB,0xA002,0x619D,0x61A9,0xA00A,0xA004,0xA002,0x615D,0x610D, 0xA002,0x6106,0xA002,0x6128,0x6063,0xA006,0xA002,0x6059,0xA002,0x6041,0x6067,0xA002,0x605A,0xA002,0x605D,0x61DF, 0xA435,0xA246,0xA10B,0xA0BF,0xA044,0xA001,0xA017,0xA001,0xA00A,0xA004,0xA002,0x5FD0,0x5FD1,0xA002,0x79B3,0xA002, 0x79A7,0x799A,0xA006,0xA002,0x798A,0xA002,0x79AA,0x797A,0xA002,0x7967,0xA002,0x798E,0x7960,0xA016,0xA00A,0xA004, 0xA002,0x7957,0x79B0,0xA002,0x795A,0xA002,0x7953,0x795C,0xA006,0xA002,0x795B,0xA002,0x7949,0x7946,0xA002,0x7940, 0xA002,0x793B,0x6249,0xA00A,0xA004,0xA002,0x6248,0x6243,0xA002,0x623D,0xA002,0x623E,0x71B9,0xA006,0xA002,0x7166, 0xA002,0x71FE,0x706C,0xA002,0x7228,0xA002,0x721D,0x71F9,0xA055,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x71E7,0x71D4, 0xA002,0x71E0,0xA002,0x71A0,0x71A8,0xA004,0xA002,0x71B5,0x71B3,0xA002,0x7198,0xA002,0x717A,0x7178,0xA00A,0xA004, 0xA002,0x714A,0x7172,0xA002,0x7145,0xA002,0x7168,0x715C,0xA006,0xA002,0x7173,0xA002,0x7131,0x712F,0xA002,0x71DC, 0xA002,0x7113,0x7110,0xA016,0xA00A,0xA004,0xA002,0x70CA,0x71C1,0xA002,0x70B1,0xA002,0x70AB,0x70B7,0xA006,0xA002, 0x70C0,0xA002,0x70BB,0x7197,0xA002,0x71C9,0xA002,0x7152,0x716C,0xA00A,0xA004,0xA002,0x65D6,0x65D2,0xA002,0x65CE, 0xA002,0x65CD,0x65C3,0xA005,0xA002,0x65C4,0xA000,0x8337,0xA002,0x6595,0xA002,0x9F51,0x6590,0xA000,0xA014,0xA00A, 0xA004,0xA002,0x89F3,0x8F42,0xA002,0x5F40,0xA002,0x6BB3,0x98DA,0xA004,0xA002,0x98D9,0x98D5,0xA002,0x98D3,0xA002, 0x98D2,0x98D1,0xA00A,0xA004,0xA002,0x6B59,0x6B46,0xA002,0x6B43,0xA002,0x6B39,0x6B37,0xA000,0xA002,0x6B5F,0xA002, 0x81A6,0x81C1,0xA001,0xA001,0xA01E,0xA008,0xA001,0xA001,0xA002,0x81BB,0xA002,0x81CA,0x6726,0xA00A,0xA004,0xA002, 0x81CC,0x81AA,0xA002,0x81A3,0xA002,0x6ED5,0x81CF,0xA006,0xA002,0x8182,0xA002,0x8188,0x5AB5,0xA002,0x584D,0xA002, 0x8167,0x816D,0xA016,0xA00A,0xA004,0xA002,0x8183,0x817C,0xA002,0x8169,0xA002,0x8160,0x8171,0xA006,0xA002,0x815A, 0xA002,0x8159,0x8174,0xA002,0x8153,0xA002,0x9183,0x8148,0xA00A,0xA004,0xA002,0x8132,0x8118,0xA002,0x812C,0xA002, 0x811E,0x8161,0xA006,0xA002,0x8C5A,0xA002,0x8112,0x7739,0xA002,0x80FC,0xA002,0x80F2,0x810E,0xA077,0xA000,0xA056, 0xA02A,0xA014,0xA00A,0xA004,0xA002,0x81BE,0x80ED,0xA002,0x80F4,0xA002,0x80F1,0x811B,0xA004,0xA002,0x80DD,0x80CA, 0xA002,0x80D7,0xA002,0x80CD,0x80D9,0xA00A,0xA004,0xA002,0x80C4,0x80C2,0xA002,0x80DB,0xA002,0x81DA,0x80E9,0xA006, 0xA002,0x80E8,0xA002,0x80E7,0x80B7,0xA002,0x991A,0xA002,0x80AD,0x80AB,0xA016,0xA00A,0xA004,0xA002,0x80B1,0x80BD, 0xA002,0x670A,0xA002,0x80BC,0x8093,0xA006,0xA002,0x809C,0xA002,0x809F,0x5216,0xA002,0x8662,0xA002,0x7230,0x7256, 0xA00A,0xA004,0xA002,0x7252,0x7258,0xA002,0x656B,0xA002,0x6555,0x6535,0xA006,0xA002,0x6C33,0xA002,0x6C2A,0x7D6A, 0xA002,0x6C2C,0xA002,0x6C21,0x6C1A,0xA000,0xA014,0xA00A,0xA004,0xA002,0x6C19,0x6C18,0xA002,0x6C15,0xA002,0x6C0D, 0x6C06,0xA004,0xA002,0x6C0C,0x6C05,0xA002,0x6BF9,0xA002,0x6BFF,0x6BFD,0xA000,0xA004,0xA002,0x6BF3,0x6BEA,0xA002, 0x8004,0xA002,0x64D8,0x643F,0xA052,0xA001,0xA025,0xA00F,0xA005,0xA001,0xA001,0xA001,0x63B0,0xA004,0xA002,0x6332, 0x6308,0xA002,0x7292,0xA002,0x728F,0x728D,0xA00A,0xA004,0xA002,0x7291,0x7284,0xA002,0x727F,0xA002,0x727E,0x726F, 0xA006,0xA002,0x7266,0xA002,0x725D,0x729F,0xA002,0x726E,0xA002,0x89D1,0x89D0,0xA016,0xA00A,0xA004,0xA002,0x89CF, 0x89CE,0xA002,0x89CC,0xA002,0x89CB,0x89CA,0xA006,0xA002,0x89C7,0xA002,0x8D59,0x8D55,0xA002,0x8D4D,0xA002,0x8D47, 0x8D49,0xA00A,0xA004,0xA002,0x8D48,0x8D46,0xA002,0x8D45,0xA002,0x8D40,0x8D3D,0xA006,0xA002,0x8D3B,0xA002,0x8D36, 0x8D33,0xA002,0x8D32,0xA002,0x66E9,0x66E6,0xA056,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x66DC,0x66DB,0xA002,0x66BE, 0xA002,0x669D,0x66D6,0xA004,0xA002,0x668C,0x6684,0xA002,0x6677,0xA002,0x6657,0x6661,0xA00A,0xA004,0xA002,0x6689, 0x664F,0xA002,0x6641,0xA002,0x66C4,0x665F,0xA006,0xA002,0x8006,0xA002,0x66B1,0x6636,0xA002,0x6631,0xA002,0x6634, 0x661D,0xA016,0xA00A,0xA004,0xA002,0x6705,0x7085,0xA002,0x6600,0xA002,0x6615,0x6603,0xA006,0xA002,0x6772,0xA002, 0x66C7,0x660A,0xA002,0x65F0,0xA002,0x65EF,0x65EE,0xA00A,0xA004,0xA002,0x6534,0x7513,0xA002,0x7511,0xA002,0x750F, 0x74FF,0xA006,0xA002,0x74F4,0xA002,0x750C,0x81E7,0xA002,0x622C,0xA002,0x6224,0x6225,0xA000,0xA016,0xA00A,0xA004, 0xA002,0x6221,0x6222,0xA002,0x621F,0xA002,0x621B,0x6227,0xA006,0xA002,0x6214,0xA002,0x8ECE,0x8F9A,0xA002,0x8F98, 0xA002,0x8F8F,0x8F8E,0xA000,0xA000,0xA000,0x8F8D,0xA0C3,0xA057,0xA001,0xA001,0xA029,0xA013,0xA009,0xA003,0xA001, 0x8F8B,0xA002,0x8F87,0xA002,0x8F84,0x8F82,0xA004,0xA002,0x8F81,0x8F7E,0xA002,0x8F7C,0xA002,0x8F7A,0x8F79,0xA00A, 0xA004,0xA002,0x8F77,0x8F78,0xA002,0x8F76,0xA002,0x8F75,0x8F73,0xA006,0xA002,0x8F72,0xA002,0x8F71,0x8F6D,0xA002, 0x8F6B,0xA002,0x6BAA,0x6BAF,0xA016,0xA00A,0xA004,0xA002,0x6B9B,0x6BAB,0xA002,0x6B8D,0xA002,0x6BAE,0x6B9E,0xA006, 0xA002,0x6B84,0xA002,0x6BA4,0x6B82,0xA002,0x6B81,0xA002,0x7352,0x7337,0xA00A,0xA004,0xA002,0x6AAB,0x8617,0xA002, 0x6AA9,0xA002,0x7C37,0x6A91,0xA006,0xA002,0x6ADE,0xA002,0x6A58,0x6A28,0xA002,0x6A3D,0xA002,0x6AD3,0x6A8E,0xA000, 0xA056,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x6A35,0x6A5B,0xA002,0x6A50,0xA002,0x6AA0,0x6A3E,0xA004,0xA002,0x6A44, 0x69F2,0xA002,0x6A65,0xA002,0x6A18,0x6A17,0xA00A,0xA004,0xA002,0x69ED,0x6AA3,0xA002,0x69FF,0xA002,0x698D,0x6AE7, 0xA006,0xA002,0x6995,0xA002,0x6AB3,0x69CA,0xA002,0x69C1,0xA002,0x69B1,0x69D4,0xA016,0xA00A,0xA004,0xA002,0x69AD, 0x69AB,0xA002,0x69BB,0xA002,0x69A7,0x699B,0xA006,0xA002,0x6979,0xA002,0x6963,0x6966,0xA002,0x6AF8,0xA002,0x69CE, 0x6ADA,0xA00A,0xA004,0xA002,0x6AEC,0x69CC,0xA002,0x6934,0xA002,0x8429,0x6998,0xA006,0xA002,0x6980,0xA002,0x696B, 0x6B16,0xA002,0x695D,0xA002,0x6A1D,0x6960,0xA000,0xA000,0xA00A,0xA004,0xA002,0x6939,0x6971,0xA002,0x6910,0xA002, 0x68E3,0x6957,0xA004,0xA002,0x69E8,0x690B,0xA002,0x7BA0,0xA000,0x6B0F,0xA0C5,0xA05F,0xA009,0xA001,0xA001,0xA001, 0xA001,0xA001,0xA002,0x6AC2,0x69E7,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x6ADD,0x68FC,0xA002,0x696E,0xA002,0x6B1E, 0x686B,0xA004,0xA002,0x6893,0x6877,0xA002,0x6CED,0xA002,0x688F,0x68B5,0xA00A,0xA004,0xA002,0x6829,0x6849,0xA002, 0x684A,0xA002,0x6B12,0x69A4,0xA006,0xA002,0x6A9C,0xA002,0x6841,0x6A3A,0xA002,0x6855,0xA002,0x681D,0x6883,0xA016, 0xA00A,0xA004,0xA002,0x69BF,0x6844,0xA002,0x6968,0xA002,0x684E,0x6A48,0xA006,0xA002,0x690F,0xA002,0x6833,0x6832, 0xA002,0x6A89,0xA002,0x67C1,0x6ADF,0xA00A,0xA004,0xA002,0x67E2,0x67B8,0xA002,0x67C3,0xA002,0x6894,0x67DD,0xA006, 0xA002,0x67B3,0xA002,0x67DA,0x67B5,0xA002,0x67D9,0xA002,0x6AE8,0x67B0,0xA056,0xA02A,0xA014,0xA00A,0xA004,0xA002, 0x67E9,0x6AF3,0xA002,0x67D8,0xA002,0x6ADB,0x67F0,0xA004,0xA002,0x677C,0x6777,0xA002,0x678B,0xA002,0x689F,0x6A05, 0xA00A,0xA004,0xA002,0x68D6,0x6775,0xA002,0x67A7,0xA002,0x6798,0x6773,0xA006,0xA002,0x676A,0xA002,0x6787,0x6AEA, 0xA002,0x69AA,0xA002,0x6748,0x675E,0xA016,0xA00A,0xA004,0xA002,0x6753,0x674C,0xA002,0x97EC,0xA002,0x97EB,0x97EA, 0xA006,0xA002,0x74BA,0xA002,0x74DA,0x74A7,0xA002,0x7490,0xA002,0x74A9,0x74A8,0xA00A,0xA004,0xA002,0x749E,0x748B, 0xA002,0x74BF,0xA002,0x7481,0x7480,0xA006,0xA002,0x74D4,0xA002,0x749C,0x747E,0xA002,0x746D,0xA002,0x74A6,0x7459, 0xA000,0xA000,0xA00A,0xA004,0xA002,0x7455,0x7457,0xA002,0x745C,0xA002,0x7441,0x741A,0xA000,0xA000,0x741B,0xA001, 0xA00E,0xA001,0xA001,0xA001,0xA005,0xA001,0xA002,0x742C,0x742E,0xA002,0x7430,0xA002,0x83CE,0x7425,0xA02C,0xA016, 0xA00A,0xA004,0xA002,0x7426,0x745B,0xA002,0x742A,0xA002,0x7489,0x743F,0xA006,0xA002,0x74BD,0xA002,0x73DE,0x73E7, 0xA002,0x73E9,0xA002,0x740A,0x987C,0xA00A,0xA004,0xA002,0x73D9,0x73E5,0xA002,0x73C8,0xA002,0x73C9,0x73C0,0xA006, 0xA002,0x73B3,0xA002,0x73B7,0x74CF,0xA002,0x73C2,0xA002,0x73CF,0x739F,0xA016,0xA00A,0xA004,0xA002,0x73A2,0x744B, 0xA002,0x74A3,0xA002,0x738E,0x9095,0xA006,0xA002,0x753E,0xA002,0x5DDB,0x757F,0xA002,0x5E7A,0xA002,0x7F35,0x7F33, 0xA00A,0xA004,0xA002,0x7F32,0x7F31,0xA002,0x97C1,0xA002,0x7F2F,0x7F2D,0xA006,0xA002,0x7F2C,0xA002,0x7F2B,0x7F2A, 0xA002,0x7F27,0xA002,0x7F26,0x7F25,0xA1E3,0xA120,0xA05F,0xA000,0xA056,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x7F24, 0x7F23,0xA002,0x7F22,0xA002,0x7F21,0x7F1F,0xA004,0xA002,0x7F1B,0x7F1C,0xA002,0x7F19,0xA002,0x7F17,0x7F12,0xA00A, 0xA004,0xA002,0x7F11,0x7F0F,0xA002,0x7F0C,0xA002,0x7F0B,0x7F08,0xA006,0xA002,0x7F07,0xA002,0x7F03,0x7F02,0xA002, 0x7F01,0xA002,0x7EFE,0x7EFB,0xA016,0xA00A,0xA004,0xA002,0x7EFA,0x7EF6,0xA002,0x7F0D,0xA002,0x7EF2,0x7EF1,0xA006, 0xA002,0x7EEF,0xA002,0x7EEE,0x7EEB,0xA002,0x7EE8,0xA002,0x7EE1,0x7EE0,0xA00A,0xA004,0xA002,0x7EDB,0x7ED7,0xA002, 0x7ED4,0xA002,0x7ED0,0x7ECC,0xA006,0xA002,0x7ECB,0xA002,0x7EC9,0x7EC2,0xA002,0x977E,0xA002,0x7EC0,0x7EBE,0xA000, 0xA000,0xA000,0xA000,0xA002,0x7EB0,0x7EAD,0xA06A,0xA014,0xA001,0xA001,0xA006,0xA001,0xA001,0xA002,0x7EA9,0x7EA8, 0xA006,0xA002,0x7EA5,0xA002,0x7EA3,0x7EA1,0xA002,0x7E9F,0xA002,0x9AA7,0x9AA5,0xA02A,0xA014,0xA00A,0xA004,0xA002, 0x9AA3,0x9AA2,0xA002,0x9AA0,0xA002,0x9A9F,0x9A9D,0xA004,0xA002,0x9A9C,0x9A9B,0xA002,0x9A98,0xA002,0x9A96,0x9A93, 0xA00A,0xA004,0xA002,0x9A92,0x9A90,0xA002,0x9A8A,0xA002,0x9A88,0x9A85,0xA006,0xA002,0x9A81,0xA002,0x9A80,0x9A7D, 0xA002,0x9A7F,0xA002,0x9A7A,0x9A78,0xA016,0xA00A,0xA004,0xA002,0x9A77,0x9A75,0xA002,0x5B62,0xA002,0x5B53,0x5B51, 0xA006,0xA002,0x5B73,0xA002,0x5B65,0x5B5A,0xA002,0x5C1C,0xA002,0x5C15,0x5B40,0xA00A,0xA004,0xA002,0x5B37,0x5B32, 0xA002,0x5B16,0xA002,0x5B17,0x5B09,0xA006,0xA002,0x5ADC,0xA002,0x5AD8,0x5AE6,0xA002,0x5AD6,0xA002,0x5B19,0x5AE3, 0xA000,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x5AE0,0x5AB8,0xA002,0x5B2A,0xA002,0x5B21,0x5AB2,0xA004,0xA002,0x5AEB, 0x5ABE,0xA002,0x5A7A,0xA002,0x5A77,0x5A9B,0xA00A,0xA004,0xA002,0x5ABC,0x80EC,0xA002,0x5B0B,0xA002,0x5A62,0x5A3C, 0xA006,0xA002,0x5A55,0xA002,0x5A4A,0x5A67,0xA002,0x5A50,0xA002,0x5A13,0x5A23,0xA016,0xA00A,0xA004,0xA002,0x5A11, 0x5AFB,0xA002,0x5AA7,0xA002,0x5A09,0x5A0C,0xA006,0xA002,0x59F9,0xA002,0x59D8,0x59E3,0xA002,0x5B4C,0xA002,0x59DD, 0x5B08,0xA00A,0xA004,0xA002,0x5A6D,0x59BE,0xA002,0x59D7,0xA002,0x601E,0x59B2,0xA006,0xA002,0x59D2,0xA002,0x59A4, 0x599E,0xA002,0x5AAF,0xA002,0x59CA,0x5997,0xA071,0xA001,0xA018,0xA001,0xA001,0xA00A,0xA004,0xA002,0x59A3,0x5AD7, 0xA002,0x5AF5,0xA002,0x598D,0x5983,0xA006,0xA002,0x5981,0xA002,0x5C6E,0x9B3B,0xA002,0x5F3C,0xA002,0x8274,0x5F2D, 0xA02C,0xA016,0xA00A,0xA004,0xA002,0x5F29,0x5F33,0xA002,0x7FBC,0xA002,0x5C68,0x5C63,0xA006,0xA002,0x5B71,0xA002, 0x5C59,0x5C50,0xA002,0x54AB,0xA002,0x5C3B,0x5F58,0xA00A,0xA004,0xA002,0x5F56,0x5F57,0xA002,0x5F50,0xA002,0x908B, 0x9083,0xA006,0xA002,0x9088,0xA002,0x9082,0x907D,0xA002,0x9074,0xA002,0x66B9,0x905B,0xA016,0xA00A,0xA004,0xA002, 0x9062,0x9058,0xA002,0x9068,0xA002,0x9050,0x9052,0xA006,0xA002,0x9051,0xA002,0x9044,0x902F,0xA002,0x902D,0xA002, 0x9036,0x9035,0xA00A,0xA004,0xA002,0x9021,0x9016,0xA002,0x900D,0xA002,0x9011,0x9090,0xA006,0xA002,0x900B,0xA002, 0x9004,0x9005,0xA002,0x8FE8,0xA002,0x9015,0x8FE6,0xA000,0xA000,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x9087,0x8FE4, 0xA002,0x8FEE,0xA002,0x8FE5,0x8FD5,0xA004,0xA002,0x8FD3,0x8FB6,0xA002,0x8B07,0xA002,0x8E47,0x5BF0,0xA00A,0xA004, 0xA002,0x8930,0x5BEE,0xA002,0x5BE4,0xA002,0x6434,0x9A9E,0xA006,0xA002,0x752F,0xA002,0x5BB8,0x5BA5,0xA002,0x5B93, 0xA002,0x5B95,0x5B84,0xA016,0xA00A,0xA004,0xA002,0x5B80,0x705E,0xA002,0x705D,0xA002,0x7035,0x7039,0xA006,0xA002, 0x701B,0xA002,0x7023,0x701A,0xA002,0x6FEF,0xA002,0x6FE0,0x6FDE,0xA00A,0xA004,0xA002,0x6FEE,0x6FE1,0xA002,0x6FC2, 0xA002,0x6FB6,0x6FB9,0xA000,0xA002,0x6FA7,0xA000,0x6FC9,0xA13F,0xA0C3,0xA078,0xA022,0xA001,0xA00B,0xA001,0xA004, 0xA001,0xA001,0x7028,0xA002,0x6F7A,0xA002,0x6F7C,0x6F72,0xA00A,0xA004,0xA002,0x6F78,0x6F8C,0xA002,0x6F8D,0xA002, 0x6F89,0x6F29,0xA006,0xA002,0x6F09,0xA002,0x6F2A,0x6F74,0xA002,0x7032,0xA002,0x6F36,0x6F2F,0xA02A,0xA014,0xA00A, 0xA004,0xA002,0x6EF9,0x6F15,0xA002,0x6F24,0xA002,0x701F,0x7020,0xA004,0xA002,0x6F62,0x8245,0xA002,0x6EC2,0xA002, 0x6E8F,0x6ECF,0xA00A,0xA004,0xA002,0x6EB4,0x6F77,0xA002,0x6EB7,0xA002,0x6EBB,0x6EBD,0xA006,0xA002,0x6EA7,0xA002, 0x6EA5,0x6EE2,0xA002,0x6F2D,0xA002,0x7044,0x6E98,0xA016,0xA00A,0xA004,0xA002,0x6EB1,0x6EDF,0xA002,0x6E44,0xA002, 0x6E25,0x6E32,0xA006,0xA002,0x6E54,0xA002,0x6E53,0x6F35,0xA002,0x6E5F,0xA002,0x6EB2,0x6E6B,0xA00A,0xA004,0xA002, 0x6E4E,0x6E6E,0xA002,0x6E2B,0xA002,0x6DAE,0x6E0C,0xA006,0xA002,0x6DAB,0xA002,0x6E16,0x6DD9,0xA002,0x6DDD,0xA002, 0x6DE6,0x6FA0,0xA000,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x6DE0,0x6DBF,0xA002,0x7006,0xA002,0x6DDE,0x6DDB,0xA004, 0xA002,0x6DC7,0x967C,0xA002,0x6D63,0xA002,0x6D7C,0x6D60,0xA00A,0xA004,0xA002,0x6D5C,0x6D94,0xA002,0x7106,0xA002, 0x6D5E,0x6F7F,0xA006,0xA002,0x6DF6,0xA002,0x6D6F,0x6D91,0xA002,0x6D33,0xA002,0x6F6F,0x6EF8,0xA016,0xA00A,0xA004, 0xA002,0x700F,0x6D1A,0xA002,0x6D35,0xA002,0x6D2E,0x6FAE,0xA006,0xA002,0x6D2B,0xA002,0x6D0E,0x6D19,0xA002,0x6D04, 0xA002,0x6D07,0x6E5E,0xA000,0xA004,0xA002,0x6D79,0x6D0C,0xA002,0x6D27,0xA000,0x6D39,0xA001,0xA024,0xA001,0xA00D, 0xA001,0xA006,0xA002,0x6D87,0xA002,0x6CEF,0x6CD3,0xA002,0x6CB1,0xA002,0x6CEE,0x6CEB,0xA00A,0xA004,0xA002,0x6FFC, 0x6CD6,0xA002,0x6CE0,0xA002,0x6CB2,0x6CD7,0xA006,0xA002,0x6CF1,0xA002,0x7018,0x7027,0xA002,0x6CAD,0xA002,0x6CD4, 0x6CD0,0xA02B,0xA015,0xA009,0xA004,0xA002,0x6E88,0x6C86,0xA002,0x6C76,0xA000,0x6C74,0xA006,0xA002,0x6C69,0xA002, 0x6C8C,0x6C94,0xA002,0x6C90,0xA002,0x6C85,0x7043,0xA00A,0xA004,0xA002,0x6C4A,0x6C5C,0xA002,0x6C54,0xA002,0x6C35, 0x6215,0xA006,0xA002,0x723F,0xA002,0x4E2C,0x961A,0xA002,0x9619,0xA002,0x9617,0x9616,0xA016,0xA00A,0xA004,0xA002, 0x9615,0x9612,0xA002,0x960F,0xA002,0x960D,0x960C,0xA006,0xA002,0x9B29,0xA002,0x960A,0x9608,0xA002,0x9606,0xA002, 0x9B2E,0x9603,0xA00A,0xA004,0xA002,0x95FE,0x95FC,0xA002,0x95F6,0xA002,0x95F5,0x95F3,0xA006,0xA002,0x95F1,0xA002, 0x95EB,0x95E9,0xA002,0x96B3,0xA002,0x5FDD,0x61F5,0xA047,0xA000,0xA000,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x61D4, 0x61B7,0xA002,0x61A7,0xA002,0x6194,0x61AC,0xA004,0xA002,0x6175,0x614A,0xA002,0x612B,0xA002,0x610E,0x6100,0xA00A, 0xA004,0xA002,0x60F4,0x6123,0xA002,0x6115,0xA002,0x6192,0x614D,0xA006,0xA002,0x60B4,0xA002,0x60DA,0x60C6,0xA002, 0x60D8,0xA002,0x60DD,0x60B1,0xA016,0xA00A,0xA004,0xA002,0x60BB,0x611C,0xA002,0x609B,0xA002,0x608C,0x6092,0xA006, 0xA002,0x6083,0xA002,0x609D,0x6173,0xA002,0x609A,0xA002,0x8A96,0x60F2,0xA000,0xA000,0xA000,0x606A,0xA082,0xA02C, 0xA001,0xA015,0xA009,0xA003,0xA001,0x6042,0xA002,0x6137,0xA002,0x60FB,0x61E8,0xA006,0xA002,0x615F,0xA002,0x6021, 0x61CC,0xA002,0x600A,0xA002,0x602B,0x6029,0xA00A,0xA004,0xA002,0x600D,0x600F,0xA002,0x601B,0xA002,0x6026,0x6035, 0xA006,0xA002,0x6019,0xA002,0x5FF8,0x5FED,0xA002,0x5FEA,0xA002,0x6134,0x60B5,0xA02A,0xA014,0xA00A,0xA004,0xA002, 0x613E,0x5FE4,0xA002,0x5FE1,0xA002,0x616A,0x5FEE,0xA004,0xA002,0x61AE,0x61FA,0xA002,0x5FD6,0xA002,0x5FC9,0x5FC4, 0xA00A,0xA004,0xA002,0x81BA,0x5EEA,0xA002,0x5EE8,0xA002,0x5EDB,0x5ED1,0xA006,0xA002,0x5ED2,0xA002,0x8D53,0x5EB3, 0xA002,0x5EBE,0xA002,0x83F4,0x5EB9,0xA016,0xA00A,0xA004,0xA002,0x5EA0,0x5EA5,0xA002,0x70F0,0xA002,0x5EAA,0x5EE1, 0xA006,0xA002,0x5E80,0xA002,0x9995,0x9994,0xA002,0x9993,0xA002,0x9991,0x9990,0xA00A,0xA004,0xA002,0x998D,0x998A, 0xA002,0x9987,0xA002,0x9984,0x9980,0xA006,0xA002,0x997D,0xA002,0x9977,0x9974,0xA002,0x996C,0xA002,0x996B,0x996A, 0xA000,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x9969,0x9968,0xA002,0x9967,0xA002,0x9963,0x5902,0xA004,0xA002,0x5924, 0x98E7,0xA002,0x5925,0xA002,0x821B,0x8C86,0xA00A,0xA004,0xA002,0x736F,0x89DF,0xA002,0x7360,0xA002,0x7357,0x734D, 0xA006,0xA002,0x7350,0xA002,0x7331,0x7338,0xA002,0x732C,0xA002,0x7325,0x7339,0xA000,0xA00A,0xA004,0xA002,0x7322, 0x737C,0xA002,0x731D,0xA002,0x731E,0x730A,0xA006,0xA002,0x7380,0xA002,0x7313,0x7317,0xA000,0x72FB,0xA856,0xA3CC, 0xA21E,0xA0C4,0xA089,0xA001,0xA033,0xA008,0xA001,0xA001,0xA001,0xA001,0xA002,0x72FA,0x736B,0xA016,0xA00A,0xA004, 0xA002,0x72F3,0x7301,0xA002,0x72F7,0xA002,0x72F4,0x733B,0xA006,0xA002,0x72E9,0xA002,0x736A,0x72E8,0xA002,0x72D2, 0xA002,0x72CD,0x72CE,0xA00A,0xA004,0xA002,0x72C1,0x72C3,0xA002,0x72B8,0xA002,0x7377,0x72B4,0xA006,0xA002,0x72B0, 0xA002,0x72AD,0x5F61,0xA002,0x8862,0xA000,0x5FBC,0xA029,0xA013,0xA00A,0xA004,0xA002,0x5FAD,0x5FA8,0xA002,0x5F9C, 0xA002,0x5F99,0x5FA0,0xA003,0xA001,0x5F89,0xA002,0x5F87,0xA002,0x5F82,0x5F77,0xA00A,0xA004,0xA002,0x5F73,0x5DD4, 0xA002,0x5DB7,0xA002,0x8C73,0x5D9D,0xA006,0xA002,0x5D99,0xA002,0x5D82,0x5D74,0xA002,0x5D69,0xA002,0x5D4A,0x5D4B, 0xA016,0xA00A,0xA004,0xA002,0x5D6B,0x5D81,0xA002,0x5D6F,0xA002,0x5D5B,0x5D6C,0xA006,0xA002,0x5D3D,0xA002,0x5D34, 0x5D3E,0xA002,0x5DB8,0xA002,0x5D1B,0x5D06,0xA00A,0xA004,0xA002,0x5D1E,0x5D24,0xA002,0x5D2E,0xA002,0x5D26,0x5D27, 0xA006,0xA002,0x5D0D,0xA002,0x5D97,0x5D22,0xA002,0x5CCB,0xA002,0x5DA0,0x5CD2,0xA000,0xA000,0xA02A,0xA014,0xA00A, 0xA004,0xA002,0x5DA7,0x5CB7,0xA002,0x5CC1,0xA002,0x5CA3,0x5CB1,0xA004,0xA002,0x5CAB,0x5CAC,0xA002,0x5CBD,0xA002, 0x5CA2,0x5CB5,0xA00A,0xA004,0xA002,0x5C9C,0x5D50,0xA002,0x5C91,0xA002,0x5DB4,0x5CF4,0xA006,0xA002,0x5C88,0xA002, 0x5D87,0x5C90,0xA002,0x6C67,0xA002,0x5C7A,0x5C8C,0xA000,0xA00A,0xA004,0xA002,0x5E61,0x5E5E,0xA002,0x5E5B,0xA002, 0x5E54,0x5E44,0xA000,0xA000,0x5E37,0xA0C2,0xA08E,0xA038,0xA00D,0xA001,0xA001,0xA005,0xA001,0xA002,0x5E57,0x5E58, 0xA002,0x5E6C,0xA002,0x5E11,0x5E14,0xA016,0xA00A,0xA004,0xA002,0x889F,0x5E43,0xA002,0x571C,0xA002,0x5709,0x570A, 0xA006,0xA002,0x5704,0xA002,0x56FF,0x56F9,0xA002,0x56EB,0xA002,0x5707,0x56E1,0xA009,0xA003,0xA000,0x56DD,0xA002, 0x56D4,0xA002,0x56AF,0x5693,0xA006,0xA002,0x5685,0xA002,0x567C,0x567B,0xA002,0x566B,0xA002,0x5671,0x5664,0xA02A, 0xA014,0xA00A,0xA004,0xA002,0x5686,0x5654,0xA002,0x564C,0xA002,0x5695,0x5659,0xA004,0xA002,0x5662,0x564D,0xA002, 0x562C,0xA002,0x5657,0x5639,0xA00A,0xA004,0xA002,0x5658,0x562D,0xA002,0x5627,0xA002,0x5600,0x55FE,0xA006,0xA002, 0x5623,0xA002,0x56B6,0x5601,0xA002,0x560C,0xA002,0x5608,0x561E,0xA016,0xA00A,0xA004,0xA002,0x8F94,0x55E4,0xA002, 0x55F5,0xA002,0x55E8,0x6B36,0xA006,0xA002,0x55CC,0xA002,0x566F,0x55F2,0xA002,0x6EDC,0xA002,0x55EF,0x55C4,0xA00A, 0xA004,0xA002,0x55DD,0x55E6,0xA002,0x55D4,0xA002,0x55EC,0x56C1,0xA006,0xA002,0x55D1,0xA002,0x561F,0x8186,0xA002, 0x55F7,0xA002,0x55EA,0x5599,0xA000,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x5594,0x56B3,0xA002,0x560D,0xA002,0x55DF, 0x557B,0xA004,0xA002,0x7616,0x55D6,0xA002,0x557E,0xA002,0x5633,0x5581,0xA00A,0xA004,0xA002,0x5588,0x55B9,0xA002, 0x55B1,0xA002,0x5583,0x55D2,0xA006,0xA002,0x558B,0xA002,0x555C,0x5530,0xA002,0x5533,0xA002,0x5577,0x5576,0xA000, 0xA000,0xA004,0xA002,0x5575,0x5557,0xA000,0x5537,0xA001,0xA03F,0xA013,0xA001,0xA006,0xA001,0xA001,0xA002,0x553C, 0x5550,0xA006,0xA002,0x553F,0xA002,0x5555,0x5541,0xA002,0x56C0,0xA002,0x5549,0x55B5,0xA016,0xA00A,0xA004,0xA002, 0x558F,0x5616,0xA002,0x552A,0xA002,0x5527,0x5511,0xA006,0xA002,0x550F,0xA002,0x5523,0x55E9,0xA002,0x54F3,0xA002, 0x5514,0x54FD,0xA00A,0xA004,0xA002,0x562E,0x54E7,0xA002,0x561C,0xA002,0x54DE,0x54CF,0xA006,0xA002,0x5665,0xA002, 0x54A4,0x54AA,0xA002,0x54A9,0xA002,0x54DC,0x54DA,0xA02C,0xA016,0xA00A,0xA004,0xA002,0x5672,0x54CC,0xA002,0x54BF, 0xA002,0x54BB,0x715F,0xA006,0xA002,0x54A3,0xA002,0x5472,0x55F6,0xA002,0x5635,0xA002,0x54A6,0x54A7,0xA00A,0xA004, 0xA002,0x5660,0x54B4,0xA002,0x54C2,0xA002,0x54AD,0x54D0,0xA006,0xA002,0x549D,0xA002,0x5466,0x5476,0xA002,0x5484, 0xA002,0x5680,0x549A,0xA016,0xA00A,0xA004,0xA002,0x5464,0x5471,0xA002,0x5477,0xA002,0x5494,0x5482,0xA006,0xA002, 0x5432,0xA002,0x5423,0x54BC,0xA002,0x5504,0xA002,0x5421,0x5443,0xA00A,0xA004,0xA002,0x56A6,0x5454,0xA002,0x56C8, 0xA002,0x5638,0x544B,0xA006,0xA002,0x5406,0xA002,0x5416,0x5412,0xA002,0x53FB,0xA002,0x53E8,0x53E9,0xA0EA,0xA02A, 0xA000,0xA000,0xA000,0xA014,0xA00A,0xA004,0xA002,0x5630,0x53F1,0xA002,0x535F,0xA002,0x5F12,0x7519,0xA004,0xA002, 0x8CA3,0x5F0B,0xA002,0x652E,0xA002,0x6525,0x6509,0xA00A,0xA004,0xA002,0x64E2,0x64E4,0xA002,0x64D7,0xA002,0x64D0, 0x64C0,0xA006,0xA002,0x651B,0xA002,0x6499,0x64FC,0xA000,0x64F7,0xA099,0xA043,0xA017,0xA001,0xA00A,0xA004,0xA002, 0x6496,0x646D,0xA002,0x6516,0xA002,0x645E,0x6421,0xA006,0xA002,0x6426,0xA002,0x640C,0x6420,0xA002,0x641B,0xA002, 0x640B,0x6441,0xA016,0xA00A,0xA004,0xA002,0x6504,0x63BE,0xA002,0x63C6,0xA002,0x6452,0x63CE,0xA006,0xA002,0x63DE, 0xA002,0x63C4,0x64B3,0xA002,0x63E0,0xA002,0x63F8,0x63F2,0xA00A,0xA004,0xA002,0x645C,0x63F5,0xA002,0x6369,0xA002, 0x638A,0x63AC,0xA006,0xA002,0x636D,0xA002,0x6451,0x638E,0xA002,0x637A,0xA002,0x6371,0x63F6,0xA02A,0xA014,0xA00A, 0xA004,0xA002,0x63AD,0x6343,0xA002,0x634B,0xA002,0x6339,0x62F6,0xA004,0xA002,0x649F,0x62EE,0xA002,0x62D7,0xA002, 0x62DA,0x62CA,0xA00A,0xA004,0xA002,0x6375,0x6476,0xA002,0x636B,0xA002,0x624C,0x5C37,0xA006,0xA002,0x5C2C,0xA002, 0x5C25,0x5C22,0xA002,0x530F,0xA002,0x5958,0x595A,0xA016,0xA00A,0xA004,0xA002,0x5955,0x8037,0xA002,0x5969,0xA002, 0x593C,0x5F08,0xA006,0xA002,0x5EFE,0xA002,0x863C,0x8616,0xA002,0x8629,0xA002,0x8605,0x8627,0xA00A,0xA004,0xA002, 0x85FF,0x85DC,0xA002,0x85C1,0xA002,0x861A,0x85B0,0xA006,0xA002,0x85B7,0xA002,0x85B9,0x8585,0xA002,0x859C,0xA002, 0x85EA,0x8579,0xA000,0xA000,0xA014,0xA00A,0xA004,0xA002,0x858F,0x8587,0xA002,0x85A8,0xA002,0x85A4,0x857B,0xA004, 0xA002,0x8604,0x8543,0xA002,0x77A2,0xA002,0x857A,0x855E,0xA00A,0xA004,0xA002,0x8564,0x8568,0xA002,0x8548,0xA002, 0x8559,0x911D,0xA000,0xA002,0x84FF,0xA002,0x853B,0x8556,0xA0A3,0xA001,0xA04A,0xA01E,0xA008,0xA001,0xA001,0xA002, 0x85FA,0xA002,0x851F,0x861E,0xA00A,0xA004,0xA002,0x84F0,0x8538,0xA002,0x750D,0xA002,0x850C,0x8577,0xA006,0xA002, 0x84E5,0xA002,0x8497,0x84B4,0xA002,0x84B9,0xA002,0x84A1,0x863A,0xA016,0xA00A,0xA004,0xA002,0x84BA,0x84BF,0xA002, 0x84CA,0xA002,0x84D3,0x84BD,0xA006,0xA002,0x9A40,0xA002,0x84D0,0x84CD,0xA002,0x84C1,0xA002,0x846D,0x8432,0xA00A, 0xA004,0xA002,0x848E,0x851E,0xA002,0x8476,0xA002,0x8469,0x8446,0xA006,0xA002,0x843C,0xA002,0x8478,0x8562,0xA002, 0x847A,0xA002,0x8488,0x8546,0xA02C,0xA016,0xA00A,0xA004,0xA002,0x8473,0x8459,0xA002,0x845A,0xA002,0x8451,0x845C, 0xA006,0xA002,0x83E1,0xA002,0x83F0,0x8426,0xA002,0x83C0,0xA002,0x83C5,0x83EA,0xA00A,0xA004,0xA002,0x8445,0x83F8, 0xA002,0x8403,0xA002,0x840F,0x83DF,0xA006,0xA002,0x8409,0xA002,0x8406,0x96C8,0xA002,0x8438,0xA002,0x841C,0x83D6, 0xA016,0xA00A,0xA004,0xA002,0x83FD,0x83DD,0xA002,0x840B,0xA002,0x8418,0x5807,0xA006,0xA002,0x83D8,0xA002,0x83E5, 0x8401,0xA002,0x83C1,0xA002,0x83BC,0x9DAF,0xA00A,0xA004,0xA002,0x83A8,0x839E,0xA002,0x8398,0xA002,0x837B,0x8555, 0xA006,0xA002,0x8470,0xA002,0x83A9,0x859F,0xA002,0x837C,0xA002,0x849E,0x839C,0xA000,0xA000,0xA000,0xA014,0xA00A, 0xA004,0xA002,0x8393,0x83AA,0xA002,0x83A0,0xA002,0x8435,0x8494,0xA004,0xA002,0x8378,0x83B0,0xA002,0x836E,0xA002, 0x8452,0x84C0,0xA000,0xA004,0xA002,0x836C,0x85CE,0xA002,0x831B,0xA000,0x8541,0xA24A,0xA171,0xA0C3,0xA0A8,0xA052, 0xA026,0xA010,0xA006,0xA001,0xA001,0xA002,0x8365,0x8366,0xA004,0xA002,0x8333,0x833A,0xA002,0x832D,0xA002,0x85BA, 0x8317,0xA00A,0xA004,0xA002,0x8340,0x8588,0xA002,0x8343,0xA002,0x8347,0x834F,0xA006,0xA002,0x832F,0xA002,0x854E, 0x839B,0xA002,0x8331,0xA002,0x8334,0x833C,0xA016,0xA00A,0xA004,0xA002,0x8392,0x8308,0xA002,0x84FD,0xA002,0x8558, 0x8351,0xA006,0xA002,0x84A8,0xA002,0x82D5,0x82E0,0xA002,0x8315,0xA002,0x8314,0x8306,0xA00A,0xA004,0xA002,0x831A, 0x8526,0xA002,0x82D3,0xA002,0x82FB,0x830C,0xA006,0xA002,0x82D8,0xA002,0x82D2,0x82F4,0xA002,0x82DC,0xA002,0x8307, 0x8622,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x82E4,0x82F7,0xA002,0x8309,0xA002,0x82E1,0x82A4,0xA004,0xA002,0x82E7, 0x82C4,0xA002,0x829F,0xA002,0x82AA,0x82A1,0xA00A,0xA004,0xA002,0x82B4,0x82A9,0xA002,0x84EF,0xA002,0x8407,0x83A7, 0xA006,0xA002,0x82AE,0xA002,0x82B7,0x8298,0xA002,0x82E3,0xA002,0x82CA,0x85F6,0xA016,0xA00A,0xA004,0xA002,0x82B0, 0x82BE,0xA002,0x8553,0xA002,0x82AB,0x8299,0xA006,0xA002,0x858C,0xA002,0x8291,0x828E,0xA002,0x8284,0xA002,0x82A8, 0x828A,0xA00A,0xA004,0xA002,0x828F,0x827F,0xA002,0x827D,0xA002,0x8279,0x61FF,0xA006,0xA002,0x9F19,0xA002,0x99A8, 0x5880,0xA002,0x589A,0xA002,0x5889,0x5881,0xA000,0xA000,0xA014,0xA00A,0xA004,0xA002,0x586C,0x5865,0xA002,0x5820, 0xA002,0x5844,0x5819,0xA004,0xA002,0x581E,0x5800,0xA002,0x57ED,0xA002,0x57FD,0x580D,0xA000,0xA000,0xA000,0x5874, 0xA001,0xA055,0xA029,0xA013,0xA009,0xA003,0xA001,0x57DD,0xA002,0x57E4,0xA002,0x57F8,0x57EF,0xA004,0xA002,0x57F4, 0x57B8,0xA002,0x57D2,0xA002,0x58CE,0x581D,0xA00A,0xA004,0xA002,0x5852,0x57D5,0xA002,0x57A0,0xA002,0x5793,0x57B4, 0xA006,0xA002,0x57A7,0xA002,0x57CF,0x584F,0xA002,0x578C,0xA002,0x57A4,0x57E1,0xA016,0xA00A,0xA004,0xA002,0x5773, 0x5776,0xA002,0x576D,0xA002,0x5768,0x963A,0xA006,0xA002,0x577C,0xA002,0x58DA,0x576B,0xA002,0x5785,0xA002,0x5769, 0x5742,0xA00A,0xA004,0xA002,0x573B,0x58E2,0xA002,0x572F,0xA002,0x572E,0x58D9,0xA006,0xA002,0x5733,0xA002,0x572A, 0x572C,0xA002,0x5729,0xA002,0x58D1,0x58C5,0xA02C,0xA016,0xA00A,0xA004,0xA002,0x58BC,0x587E,0xA002,0x57A1,0xA002, 0x580A,0x574C,0xA006,0xA002,0x5DF0,0xA002,0x755A,0x5F01,0xA002,0x53B6,0xA002,0x9B2F,0x51FC,0xA00A,0xA004,0xA002, 0x51F5,0x5EF4,0xA002,0x77CD,0xA002,0x71EE,0x53DF,0xA006,0xA002,0x52F0,0xA002,0x52D7,0x52D0,0xA002,0x54FF,0xA002, 0x52BE,0x52AD,0xA016,0xA00A,0xA004,0xA002,0x52AC,0x52F1,0xA002,0x5950,0xA002,0x82BB,0x9146,0xA006,0xA002,0x9143, 0xA002,0x9139,0x912F,0xA002,0x9131,0xA002,0x9123,0x911E,0xA00A,0xA004,0xA002,0x9122,0x9104,0xA002,0x90FE,0xA002, 0x90EF,0x90EB,0xA006,0xA002,0x90DB,0xA002,0x90D7,0x90DC,0xA002,0x90E2,0xA002,0x9148,0x9106,0xA01F,0xA014,0xA000, 0xA000,0xA000,0xA00A,0xA004,0xA002,0x90C7,0x90C4,0xA002,0x9136,0xA002,0x90BE,0x90C5,0xA004,0xA002,0x90DF,0x90B0, 0xA000,0x90B8,0xA001,0xA001,0xA001,0xA001,0xA001,0xA002,0x9134,0xA002,0x90B6,0x90B3,0xA0AC,0xA056,0xA02A,0xA014, 0xA00A,0xA004,0xA002,0x90B4,0x90A1,0xA002,0x9114,0xA002,0x9099,0x913A,0xA004,0xA002,0x909B,0x9097,0xA002,0x96B0, 0xA002,0x9697,0x968D,0xA00A,0xA004,0xA002,0x9688,0x9674,0xA002,0x9672,0xA002,0x966C,0x9689,0xA006,0xA002,0x965F, 0xA002,0x9654,0x9658,0xA002,0x9642,0xA002,0x963C,0x963D,0xA016,0xA00A,0xA004,0xA002,0x962A,0x9631,0xA002,0x9621, 0xA002,0x9622,0x961D,0xA006,0xA002,0x5DF9,0xA002,0x5369,0x8C36,0xA002,0x8C35,0xA002,0x8C33,0x8C32,0xA00A,0xA004, 0xA002,0x8C2F,0x8C2E,0xA002,0x8C2B,0xA002,0x8C2A,0x8C27,0xA006,0xA002,0x8C25,0xA002,0x8C21,0x8C20,0xA002,0x8C1F, 0xA002,0x8C1D,0x8C18,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x8C1B,0x8C19,0xA002,0x8C16,0xA002,0x8C15,0x8C14,0xA004, 0xA002,0x8C12,0x8C11,0xA002,0x8C0F,0xA002,0x8C0C,0x8C07,0xA00A,0xA004,0xA002,0x8C04,0x8C02,0xA002,0x8C00,0xA002, 0x8BFF,0x8BFC,0xA006,0xA002,0x8BF9,0xA002,0x8BF6,0x8BF3,0xA002,0x8BF0,0xA002,0x8BEE,0x8BE9,0xA016,0xA00A,0xA004, 0xA002,0x8BE8,0x8BE4,0xA002,0x8BE0,0xA002,0x8BDF,0x8BDC,0xA006,0xA002,0x8BD9,0xA002,0x8BD8,0x8BD6,0xA002,0x8BD4, 0xA002,0x8BD3,0x8BD2,0xA00A,0xA004,0xA002,0x8BCE,0x8BCF,0xA002,0x8BCB,0xA002,0x8BC3,0x8BC2,0xA006,0xA002,0x8BB7, 0xA002,0x8BB5,0x8BB4,0xA002,0x8BAA,0xA002,0x8BA7,0x8BA6,0xA000,0xA000,0xA000,0xA000,0xA004,0xA002,0x8BA0,0x51A5, 0xA002,0x585A,0xA002,0x5196,0x51C7,0xA0DA,0xA0BB,0xA010,0xA001,0xA001,0xA001,0xA001,0xA006,0xA002,0x51BC,0xA002, 0x51BD,0x6C8D,0xA002,0x51AB,0xA002,0x7FB8,0x8803,0xA055,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x5B34,0x7A1F,0xA002, 0x88D2,0xA002,0x81E0,0x893B,0xA004,0xA002,0x88A4,0x88F7,0xA002,0x4EB3,0xA002,0x6C87,0x4EA0,0xA00A,0xA004,0xA002, 0x5155,0x5919,0xA002,0x9CE7,0xA002,0x5310,0x8A07,0xA006,0xA002,0x530D,0xA002,0x52F9,0x5914,0xA002,0x5181,0xA002, 0x9998,0x9ECC,0xA015,0xA009,0xA004,0xA002,0x5DFD,0x516E,0xA002,0x7CF4,0xA001,0x9FA0,0xA006,0xA002,0x67E4,0xA002, 0x50C9,0x4F58,0xA002,0x6C46,0xA002,0x4EDD,0x510B,0xA00A,0xA004,0xA002,0x5107,0x50EE,0xA002,0x50E6,0xA002,0x50EC, 0x50ED,0xA006,0xA002,0x5106,0xA002,0x50D6,0x50BA,0xA002,0x513A,0xA002,0x5110,0x513B,0xA02A,0xA014,0xA00A,0xA004, 0xA002,0x50C2,0x50AF,0xA002,0x504E,0xA002,0x5048,0x5055,0xA004,0xA002,0x533D,0x50E8,0xA002,0x5028,0xA002,0x5025, 0x500C,0xA00A,0xA004,0xA002,0x501C,0x4FFE,0xA002,0x502D,0xA002,0x502E,0x500F,0xA006,0xA002,0x502C,0xA002,0x4FF3, 0x504C,0xA002,0x5029,0xA002,0x4FF8,0x4FDF,0xA016,0xA00A,0xA004,0xA002,0x4FD1,0x4FDC,0xA002,0x4FE3,0xA002,0x4FDA, 0x4FC5,0xA006,0xA002,0x5137,0xA002,0x513C,0x5114,0xA002,0x4F94,0xA002,0x5102,0x4F7C,0xA00A,0xA004,0xA002,0x5115, 0x8A82,0xA002,0x4F7E,0xA002,0x4F8F,0x884E,0xA006,0xA002,0x4F89,0xA002,0x59F7,0x4F74,0xA002,0x4F76,0xA002,0x4F3D, 0x4F32,0xA009,0xA000,0xA000,0xA000,0xA000,0xA000,0xA002,0x4F57,0x4F5F,0xA001,0xA001,0xA001,0xA007,0xA001,0xA002, 0x4F5D,0xA002,0x4F5A,0x6538,0xA006,0xA002,0x4F67,0xA002,0x4F5E,0x4F47,0xA002,0x4F09,0xA002,0x5096,0x5000,0xA0AC, 0xA000,0xA056,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x4EF5,0x4F64,0xA002,0x4F22,0xA002,0x4EF3,0x50B4,0xA004,0xA002, 0x4EDE,0x4EEB,0xA002,0x4EE1,0xA002,0x4EE8,0x961E,0xA00A,0xA004,0xA002,0x4EC9,0x4EC3,0xA002,0x4EBB,0xA002,0x7F54, 0x5182,0xA006,0xA002,0x5293,0xA002,0x5290,0x5281,0xA002,0x5282,0xA002,0x527D,0x84AF,0xA016,0xA00A,0xA004,0xA002, 0x525C,0x639E,0xA002,0x525E,0xA002,0x524C,0x5274,0xA006,0xA002,0x528C,0xA002,0x5233,0x5244,0xA002,0x520E,0xA002, 0x5208,0x5202,0xA00A,0xA004,0xA002,0x5363,0x5366,0xA002,0x8D5C,0xA002,0x533E,0x5331,0xA006,0xA002,0x532D,0xA002, 0x53F5,0x531A,0xA002,0x8D5D,0xA002,0x9768,0x5EDD,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x53A5,0x53B4,0xA002,0x539D, 0xA002,0x5399,0x4EC4,0xA004,0xA002,0x560F,0x55C7,0xA002,0x5B5B,0xA002,0x8288,0x4E93,0xA00A,0xA004,0xA002,0x4E69, 0x4E5C,0xA002,0x9F10,0xA002,0x4E9F,0x4E36,0xA006,0xA002,0x9F17,0xA002,0x777E,0x6BD3,0xA002,0x9997,0xA002,0x80E4, 0x56DF,0xA016,0xA00A,0xA004,0xA002,0x6C10,0x536E,0xA002,0x723B,0xA002,0x6B80,0x4E47,0xA006,0xA002,0x5315,0xA002, 0x4E3F,0x79BA,0xA002,0x4E28,0xA002,0x5669,0x5B6C,0xA00A,0xA004,0xA002,0x9B32,0x4E1E,0xA002,0x4E99,0xA002,0x4E15, 0x5345,0xA006,0xA002,0x5EFF,0xA002,0x4E10,0xFA0C,0xA002,0x4E0C,0xA000,0x4E8D,0xA014,0xA001,0xA001,0xA001,0xA005, 0xA001,0xA001,0xA001,0x5EA7,0xA006,0xA002,0x5750,0xA002,0x4F5C,0x505A,0xA002,0x67DE,0xA002,0x4F50,0x5DE6,0xA056, 0xA02A,0xA014,0xA00A,0xA004,0xA002,0x6628,0x9075,0xA002,0x5C0A,0xA002,0x7F6A,0x6700,0xA004,0xA002,0x9189,0x5634, 0xA002,0x7E82,0xA002,0x94BB,0x7EC4,0xA00A,0xA004,0xA002,0x963B,0x8BC5,0xA002,0x7956,0xA002,0x65CF,0x5352,0xA006, 0xA002,0x8DB3,0xA002,0x79DF,0x63CD,0xA002,0x594F,0xA002,0x8D70,0x9112,0xA016,0xA00A,0xA004,0xA002,0x7EB5,0x7E3D, 0xA002,0x7EFC,0xA002,0x5B97,0x8E64,0xA006,0xA002,0x68D5,0xA002,0x9B03,0x5B57,0xA002,0x6F2C,0xA002,0x81EA,0x5B50, 0xA00A,0xA004,0xA002,0x6ED3,0x7C7D,0xA002,0x4ED4,0xA002,0x7D2B,0x5B5C,0xA006,0xA002,0x6DC4,0xA002,0x6ECB,0x59FF, 0xA002,0x8D44,0xA002,0x54A8,0x8332,0xA02C,0xA016,0xA00A,0xA004,0xA002,0x6FC1,0x707C,0xA002,0x8457,0xA002,0x5545, 0x914C,0xA006,0xA002,0x8301,0xA002,0x7422,0x684C,0xA002,0x5353,0xA002,0x62D9,0x6349,0xA00A,0xA004,0xA002,0x7DA7, 0x8C06,0xA002,0x7F00,0xA002,0x589C,0x8D58,0xA006,0xA002,0x8FFD,0xA002,0x9525,0x690E,0xA002,0x72C0,0xA002,0x58EF, 0x649E,0xA016,0xA00A,0xA004,0xA002,0x599D,0x88DD,0xA002,0x838A,0xA002,0x6A01,0x7BC6,0xA006,0xA002,0x8D5A,0xA002, 0x64B0,0x8F6C,0xA002,0x78DA,0xA002,0x8011,0x62FD,0xA00A,0xA004,0xA002,0x722A,0x6293,0xA002,0x9A7B,0xA002,0x795D, 0x9252,0xA000,0xA000,0x4F4F,0xA3CF,0xA1B5,0xA0C4,0xA023,0xA001,0xA001,0xA001,0xA00B,0xA001,0xA004,0xA001,0xA001, 0x7BC9,0xA002,0x94F8,0xA002,0x8D2E,0x86C0,0xA009,0xA004,0xA002,0x52A9,0x67F1,0xA001,0xA002,0x4E3B,0x56D1,0xA006, 0xA002,0x77DA,0xA002,0x62C4,0x716E,0xA002,0x71ED,0xA002,0x7AF9,0x9010,0xA000,0xA056,0xA02A,0xA014,0xA00A,0xA004, 0xA002,0x8BDB,0x8BF8,0xA002,0x8C6C,0xA002,0x7843,0x86DB,0xA004,0xA002,0x682A,0x73E0,0xA002,0x9AA4,0xA002,0x665D, 0x5B99,0xA00A,0xA004,0xA002,0x76BA,0x5492,0xA002,0x5E1A,0xA002,0x8098,0x8F74,0xA006,0xA002,0x7CA5,0xA002,0x8BCC, 0x6D32,0xA002,0x5DDE,0xA002,0x9031,0x821F,0xA016,0xA00A,0xA004,0xA002,0x773E,0x4EF2,0xA002,0x91CD,0xA002,0x816B, 0x7A2E,0xA006,0xA002,0x7EC8,0xA002,0x8877,0x949F,0xA002,0x5FE0,0xA002,0x76C5,0x4E2D,0xA00A,0xA004,0xA002,0x7A92, 0x6CBB,0xA002,0x6EEF,0xA002,0x75D4,0x7099,0xA006,0xA002,0x8D28,0xA002,0x7A1A,0x79E9,0xA002,0x667A,0xA002,0x88FD, 0x5EA4,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x5E5F,0x7F6E,0xA002,0x81F4,0xA002,0x81F3,0x64F2,0xA004,0xA002,0x646F, 0x8A8C,0xA002,0x7EB8,0xA002,0x65E8,0x96BB,0xA00A,0xA004,0xA002,0x8DBE,0x6B62,0xA002,0x6307,0xA002,0x962F,0x59EA, 0xA006,0xA002,0x503C,0xA002,0x6267,0x6B96,0xA002,0x690D,0xA002,0x76F4,0x8077,0xA016,0xA00A,0xA004,0xA002,0x7EC7, 0x4E4B,0xA002,0x6C41,0xA002,0x8102,0x80D1,0xA006,0xA002,0x77E5,0xA002,0x8718,0x5431,0xA002,0x652F,0xA002,0x679D, 0x829D,0xA000,0xA004,0xA002,0x8BC1,0x912D,0xA002,0x7665,0xA000,0x5E40,0xA0C2,0xA029,0xA001,0xA001,0xA011,0xA005, 0xA001,0xA001,0xA001,0x653F,0xA006,0xA002,0x6B63,0xA002,0x649C,0x6574,0xA002,0x6014,0xA002,0x722D,0x7319,0xA00A, 0xA004,0xA002,0x5FB5,0x775C,0xA002,0x6399,0xA002,0x84B8,0x9663,0xA006,0xA002,0x9547,0xA002,0x632F,0x9707,0xA002, 0x8BCA,0xA002,0x75B9,0x6795,0xA056,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x9049,0x9488,0xA002,0x8D1E,0xA002,0x81FB, 0x78AA,0xA004,0xA002,0x7504,0x771F,0xA002,0x659F,0xA002,0x8897,0x6D59,0xA00A,0xA004,0xA002,0x9019,0x8517,0xA002, 0x9517,0xA002,0x8005,0x8F99,0xA006,0xA002,0x87C4,0xA002,0x608A,0x647A,0xA002,0x906E,0xA002,0x53EC,0x8087,0xA016, 0xA00A,0xA004,0xA002,0x5146,0x7F69,0xA002,0x7167,0xA002,0x8D99,0x6CBC,0xA006,0xA002,0x627E,0xA002,0x662D,0x62DB, 0xA002,0x969C,0xA002,0x7634,0x8139,0xA00A,0xA004,0xA002,0x4ED7,0x8D26,0xA002,0x5E33,0xA002,0x4E08,0x6756,0xA006, 0xA002,0x6F32,0xA002,0x638C,0x5F35,0xA002,0x6F33,0xA002,0x5F70,0x7AE0,0xA02C,0xA016,0xA00A,0xA004,0xA002,0x6A1F, 0x7EFD,0xA002,0x6E5B,0xA002,0x7AD9,0x6230,0xA006,0xA002,0x5360,0xA002,0x68E7,0x8638,0xA002,0x5C55,0xA002,0x5D84, 0x8F97,0xA00A,0xA004,0xA002,0x65AC,0x76DE,0xA002,0x9711,0xA002,0x7C98,0x8A79,0xA006,0xA002,0x6C08,0xA002,0x77BB, 0x5BE8,0xA002,0x50B5,0xA002,0x7A84,0x5B85,0xA000,0xA00A,0xA004,0xA002,0x9F4B,0x6458,0xA002,0x8BC8,0xA002,0x7160, 0x4E4D,0xA006,0xA002,0x548B,0xA002,0x69A8,0x6805,0xA002,0x7728,0xA002,0x95F8,0x94E1,0xA001,0xA001,0xA001,0xA016, 0xA00A,0xA004,0xA002,0x8F67,0x672D,0xA002,0x6E23,0xA002,0x55B3,0x7D2E,0xA006,0xA002,0x8D60,0xA002,0x66FE,0x618E, 0xA002,0x589E,0xA002,0x600E,0x8D3C,0xA00A,0xA004,0xA002,0x6FA4,0x5247,0xA002,0x64C7,0xA002,0x8D23,0x71E5,0xA006, 0xA002,0x7076,0xA002,0x7682,0x9020,0xA002,0x8B5F,0xA002,0x8E81,0x86A4,0xA156,0xA093,0xA000,0xA056,0xA02A,0xA014, 0xA00A,0xA004,0xA002,0x6FA1,0x65E9,0xA002,0x68D7,0xA002,0x85FB,0x947F,0xA004,0xA002,0x7CDF,0x906D,0xA002,0x846C, 0xA002,0x9AD2,0x8D43,0xA00A,0xA004,0xA002,0x8D5E,0x66AB,0xA002,0x6522,0xA002,0x5592,0x5728,0xA006,0xA002,0x518D, 0xA002,0x8F7D,0x5BB0,0xA002,0x83D1,0xA002,0x54C9,0x683D,0xA016,0xA00A,0xA004,0xA002,0x96DC,0x7838,0xA002,0x531D, 0xA002,0x5B55,0x97FB,0xA006,0xA002,0x6688,0xA002,0x919E,0x860A,0xA002,0x904B,0xA002,0x5141,0x9695,0xA00A,0xA004, 0xA002,0x5300,0x9116,0xA002,0x96F2,0xA002,0x8018,0x9605,0xA006,0xA002,0x60A6,0xA002,0x6708,0x7CB5,0xA002,0x5DBD, 0xA002,0x94A5,0x8E8D,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x8D8A,0x7EA6,0xA002,0x66F0,0xA002,0x9662,0x6028,0xA004, 0xA002,0x9858,0x82D1,0xA002,0x9060,0xA002,0x7F18,0x6E90,0xA00A,0xA004,0xA002,0x733F,0x5713,0xA002,0x54E1,0xA002, 0x5712,0x8F95,0xA006,0xA002,0x63F4,0xA002,0x539F,0x8881,0xA002,0x57A3,0xA002,0x5143,0x51A4,0xA000,0xA00A,0xA004, 0xA002,0x6E0A,0x9E33,0xA002,0x9A6D,0xA002,0x8C6B,0x9884,0xA000,0xA002,0x88D5,0xA002,0x5BD3,0x6D74,0xA035,0xA001, 0xA008,0xA001,0xA001,0xA001,0xA001,0xA002,0x8B7D,0x80B2,0xA016,0xA00A,0xA004,0xA002,0x7344,0x6B32,0xA002,0x7652, 0xA002,0x79A6,0x5CEA,0xA006,0xA002,0x55BB,0xA002,0x9047,0x7C72,0xA002,0x9B31,0xA002,0x828B,0x57DF,0xA00A,0xA004, 0xA002,0x7389,0x7FBD,0xA002,0x8BED,0xA002,0x5B87,0x79B9,0xA006,0xA002,0x5DBC,0xA002,0x8207,0x96E8,0xA002,0x5A31, 0xA002,0x4E88,0x9685,0xA056,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x6F01,0x6E1D,0xA002,0x6B48,0xA002,0x9C7C,0x903E, 0xA004,0xA002,0x4FDE,0x9918,0xA002,0x8F3F,0xA002,0x611A,0x865E,0xA00A,0xA004,0xA002,0x6986,0x76C2,0xA002,0x9098, 0xA002,0x6DE4,0x8FC2,0xA006,0xA002,0x5E7C,0xA002,0x53C8,0x8BF1,0xA002,0x91C9,0xA002,0x4F51,0x53F3,0xA016,0xA00A, 0xA004,0xA002,0x53CB,0x6709,0xA002,0x9149,0xA002,0x904A,0x6CB9,0xA006,0xA002,0x7336,0xA002,0x94C0,0x90F5,0xA002, 0x900C,0xA002,0x8A27,0x6182,0xA00A,0xA004,0xA002,0x60A0,0x512A,0xA002,0x5E7D,0xA002,0x7528,0x52C7,0xA006,0xA002, 0x607F,0xA002,0x6C38,0x6E67,0xA002,0x6CF3,0xA002,0x8A60,0x86F9,0xA02C,0xA016,0xA00A,0xA004,0xA002,0x8E34,0x96CD, 0xA002,0x5EB8,0xA002,0x7670,0x81C3,0xA006,0xA002,0x50AD,0xA002,0x64C1,0x55B2,0xA002,0x6620,0xA002,0x786C,0x9896, 0xA00A,0xA004,0xA002,0x5F71,0x76C8,0xA002,0x8D62,0xA002,0x8FCE,0x8805,0xA006,0xA002,0x8367,0xA002,0x8425,0x87A2, 0xA002,0x83B9,0xA002,0x7F28,0x61C9,0xA000,0xA000,0xA004,0xA002,0x9E70,0x5B30,0xA002,0x6AFB,0xA002,0x82F1,0x5370, 0xA03C,0xA001,0xA001,0xA00E,0xA001,0xA001,0xA006,0xA002,0x96B1,0xA002,0x5F15,0x5C39,0xA002,0x996E,0xA002,0x5BC5, 0x6DEB,0xA016,0xA00A,0xA004,0xA002,0x94F6,0x541F,0xA002,0x59FB,0xA002,0x9670,0x97F3,0xA006,0xA002,0x6BB7,0xA002, 0x56E0,0x852D,0xA002,0x88C0,0xA002,0x7ECE,0x7FCC,0xA00A,0xA004,0xA002,0x7FFC,0x7570,0xA002,0x8BD1,0xA002,0x8C0A, 0x8BAE,0xA006,0xA002,0x8BE3,0xA002,0x6EA2,0x76CA,0xA002,0x7FA9,0xA002,0x61B6,0x6BC5,0xA000,0xA056,0xA02A,0xA014, 0xA00A,0xA004,0xA002,0x610F,0x88D4,0xA002,0x4EA6,0xA002,0x75AB,0x8084,0xA004,0xA002,0x9038,0x81C6,0xA002,0x5F79, 0xA002,0x5104,0x5C79,0xA00A,0xA004,0xA002,0x9091,0x6613,0xA002,0x6291,0xA002,0x85DD,0x4EE5,0xA006,0xA002,0x77E3, 0xA002,0x4E59,0x5DF2,0xA002,0x501A,0xA002,0x87FB,0x6905,0xA016,0xA00A,0xA004,0xA002,0x5F5D,0x59E8,0xA002,0x5B9C, 0xA002,0x6C82,0x7591,0xA006,0xA002,0x80F0,0xA002,0x5100,0x8FFB,0xA002,0x907A,0xA002,0x9295,0x9890,0xA00A,0xA004, 0xA002,0x8863,0x4F0A,0xA002,0x4F9D,0xA002,0x94F1,0x63D6,0xA006,0xA002,0x91AB,0xA002,0x58F9,0x4E00,0xA002,0x6DB2, 0xA002,0x591C,0x814B,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x66F3,0x8449,0xA002,0x696D,0xA002,0x6396,0x9875,0xA004, 0xA002,0x4E5F,0x51B6,0xA002,0x91CE,0xA002,0x723A,0x8036,0xA00A,0xA004,0xA002,0x564E,0x6930,0xA002,0x8000,0xA002, 0x8981,0x85E5,0xA006,0xA002,0x8200,0xA002,0x54AC,0x59DA,0xA002,0x8C23,0xA002,0x7AAF,0x9683,0xA000,0xA000,0xA000, 0xA002,0x5C27,0x6447,0xA248,0xA10B,0xA0C1,0xA041,0xA001,0xA014,0xA001,0xA007,0xA001,0xA002,0x7476,0xA002,0x5996, 0x8170,0xA006,0xA002,0x9080,0xA002,0x6F3E,0x6A23,0xA002,0x990A,0xA002,0x7662,0x536C,0xA016,0xA00A,0xA004,0xA002, 0x6C27,0x967D,0xA002,0x6D0B,0xA002,0x7F8A,0x760D,0xA006,0xA002,0x4F6F,0xA002,0x98BA,0x694A,0xA002,0x79E7,0xA002, 0x9E2F,0x9260,0xA00A,0xA004,0xA002,0x6B83,0x9A8C,0xA002,0x8C1A,0xA002,0x5BB4,0x71C4,0xA006,0xA002,0x5F66,0xA002, 0x55AD,0x96C1,0xA002,0x786F,0xA002,0x53AD,0x71D5,0xA056,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x5830,0x8C54,0xA002, 0x6F14,0xA002,0x884D,0x773C,0xA004,0xA002,0x6B97,0x5944,0xA002,0x6CBF,0xA002,0x708E,0x960E,0xA00A,0xA004,0xA002, 0x989C,0x8A00,0xA002,0x5EF6,0xA002,0x789E,0x8712,0xA006,0xA002,0x7814,0xA002,0x56B4,0x9E7D,0xA002,0x6E30,0xA002, 0x7159,0x9609,0xA016,0xA00A,0xA004,0xA002,0x56A5,0x7109,0xA002,0x8BB6,0xA002,0x4E9E,0x555E,0xA006,0xA002,0x96C5, 0xA002,0x6DAF,0x8859,0xA002,0x5D16,0xA002,0x869C,0x7259,0xA00A,0xA004,0xA002,0x82BD,0x4E2B,0xA002,0x5440,0xA002, 0x9E2D,0x9E26,0xA006,0xA002,0x62BC,0xA002,0x58D3,0x8FC5,0xA002,0x905C,0xA002,0x8BAF,0x8BAD,0xA000,0xA014,0xA00A, 0xA004,0xA002,0x6C5B,0x6B89,0xA002,0x5DE1,0xA002,0x9A6F,0x5C0B,0xA004,0xA002,0x8BE2,0x65EC,0xA002,0x7D03,0xA002, 0x71FB,0x52F3,0xA00A,0xA004,0xA002,0x8840,0x96EA,0xA002,0x7A74,0xA002,0x5B78,0x859B,0xA006,0xA002,0x9774,0xA002, 0x7EDA,0x7734,0xA002,0x766C,0xA000,0x9078,0xA001,0xA001,0xA01C,0xA006,0xA001,0xA001,0xA001,0xA001,0x7384,0xA00A, 0xA004,0xA002,0x93C7,0x61F8,0xA002,0x5BA3,0xA002,0x55A7,0x8F69,0xA006,0xA002,0x7EED,0xA002,0x7EEA,0x5A7F,0xA002, 0x7D6E,0xA002,0x6064,0x755C,0xA016,0xA00A,0xA004,0xA002,0x5E8F,0x65ED,0xA002,0x6558,0xA002,0x9157,0x84C4,0xA006, 0xA002,0x8BB8,0xA002,0x5F90,0x9B1A,0xA002,0x5653,0xA002,0x865B,0x9700,0xA00A,0xA004,0xA002,0x620C,0x589F,0xA002, 0x7EE3,0xA002,0x8896,0x79C0,0xA006,0xA002,0x9508,0xA002,0x55C5,0x673D,0xA002,0x7F9E,0xA002,0x8129,0x70CB,0xA07C, 0xA000,0xA056,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x718A,0x96C4,0xA002,0x6D36,0xA002,0x5308,0x80F8,0xA004,0xA002, 0x51F6,0x5144,0xA002,0x59D3,0xA002,0x6027,0x674F,0xA00A,0xA004,0xA002,0x5E78,0x9192,0xA002,0x884C,0xA002,0x90A2, 0x5F62,0xA006,0xA002,0x578B,0xA002,0x5211,0x8208,0xA002,0x60FA,0xA002,0x7329,0x8165,0xA016,0xA00A,0xA004,0xA002, 0x661F,0x91C1,0xA002,0x4FE1,0xA002,0x5FC3,0x5FFB,0xA006,0xA002,0x65B0,0xA002,0x8F9B,0x8A22,0xA002,0x950C,0xA002, 0x82AF,0x85AA,0xA00A,0xA004,0xA002,0x5C51,0x8C22,0xA002,0x7009,0xA002,0x6D29,0x61C8,0xA006,0xA002,0x87F9,0xA002, 0x5378,0x68B0,0xA002,0x5BEB,0xA002,0x8C10,0x8105,0xA000,0xA014,0xA00A,0xA004,0xA002,0x659C,0x90AA,0xA002,0x651C, 0xA002,0x633E,0x5354,0xA004,0xA002,0x978B,0x880D,0xA002,0x6B47,0xA002,0x4E9B,0x69E2,0xA00A,0xA004,0xA002,0x6548, 0x7B11,0xA002,0x562F,0xA002,0x8096,0x6821,0xA000,0xA002,0x5B5D,0xA000,0x5C0F,0xA04C,0xA001,0xA01F,0xA00A,0xA001, 0xA003,0xA001,0x66C9,0xA002,0x6DC6,0xA002,0x5BB5,0x6D88,0xA00A,0xA004,0xA002,0x9500,0x56C2,0xA002,0x54EE,0xA002, 0x524A,0x9704,0xA006,0xA002,0x785D,0xA002,0x856D,0x8C61,0xA002,0x56AE,0xA001,0x6A61,0xA016,0xA00A,0xA004,0xA002, 0x5DF7,0x9879,0xA002,0x4EAB,0xA002,0x97FF,0x60F3,0xA006,0xA002,0x8BE6,0xA002,0x7965,0x7FD4,0xA002,0x9109,0xA002, 0x6E58,0x8944,0xA00A,0xA004,0xA002,0x7BB1,0x9999,0xA002,0x9576,0xA002,0x5EC2,0x76F8,0xA006,0xA002,0x7EBF,0xA002, 0x9650,0x9677,0xA002,0x61B2,0xA002,0x7FA8,0x9985,0xA056,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x817A,0x7E23,0xA002, 0x737B,0xA002,0x73FE,0x96AA,0xA004,0xA002,0x986F,0x5ACC,0xA002,0x7D43,0xA002,0x6D8E,0x95F2,0xA00A,0xA004,0xA002, 0x8237,0x929C,0xA002,0x8D24,0xA002,0x9E79,0x7EA4,0xA006,0xA002,0x9C9C,0xA002,0x50CA,0x5148,0xA002,0x9528,0xA002, 0x6380,0x5687,0xA016,0xA00A,0xA004,0xA002,0x590F,0x5EC8,0xA002,0x4E0B,0xA002,0x72F9,0x4FE0,0xA006,0xA002,0x5CFD, 0xA002,0x6687,0x8F96,0xA002,0x971E,0xA002,0x5323,0x8766,0xA00A,0xA004,0xA002,0x778E,0x7EC6,0xA002,0x6232,0xA002, 0x9699,0x7E6B,0xA006,0xA002,0x6D17,0xA002,0x94E3,0x559C,0xA002,0x5AB3,0xA002,0x7FD2,0x84C6,0xA000,0xA016,0xA00A, 0xA004,0xA002,0x8972,0x6A84,0xA002,0x7280,0xA002,0x6C50,0x8C3F,0xA006,0xA002,0x70EF,0xA002,0x7184,0x60DC,0xA002, 0x5915,0xA002,0x819D,0x6089,0xA000,0xA004,0xA002,0x5E0C,0x910E,0xA000,0x7A00,0xA0C5,0xA054,0xA001,0xA001,0xA026, 0xA010,0xA006,0xA001,0xA001,0xA002,0x72A7,0x9521,0xA004,0xA002,0x5438,0x8B46,0xA002,0x7699,0xA002,0x77FD,0x7852, 0xA00A,0xA004,0xA002,0x897F,0x6790,0xA002,0x7199,0xA002,0x6614,0x8BEF,0xA006,0xA002,0x609F,0xA002,0x52D9,0x52FF, 0xA002,0x7269,0xA002,0x6664,0x9727,0xA016,0xA00A,0xA004,0xA002,0x620A,0x5862,0xA002,0x4FAE,0xA002,0x4F0D,0x821E, 0xA006,0xA002,0x5348,0xA002,0x6342,0x4E94,0xA002,0x6B66,0xA002,0x6BCC,0x5434,0xA00A,0xA004,0xA002,0x543E,0x68A7, 0xA002,0x856A,0xA002,0x7121,0x5C4B,0xA006,0xA002,0x8BEC,0xA002,0x6D3F,0x70CF,0xA002,0x94A8,0xA002,0x6B4D,0x5DEB, 0xA000,0xA056,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x6C83,0x6439,0xA002,0x81E5,0xA002,0x65A1,0x6211,0xA004,0xA002, 0x7AA9,0x6E26,0xA002,0x8778,0xA002,0x64BE,0x7F4B,0xA00A,0xA004,0xA002,0x7FC1,0x55E1,0xA002,0x95EE,0xA002,0x7D0A, 0x7A69,0xA006,0xA002,0x543B,0xA002,0x7EB9,0x95FB,0xA002,0x6587,0xA002,0x868A,0x6EAB,0xA016,0xA00A,0xA004,0xA002, 0x761F,0x885B,0xA002,0x6170,0xA002,0x5C09,0x8C13,0xA006,0xA002,0x6E2D,0xA002,0x4F4D,0x9B4F,0xA002,0x9935,0xA002, 0x80C3,0x754F,0xA00A,0xA004,0xA002,0x5473,0x851A,0xA002,0x672A,0xA002,0x7EAC,0x5C3E,0xA006,0xA002,0x507D,0xA002, 0x5049,0x59D4,0xA002,0x840E,0xA002,0x8466,0x7EF4,0xA000,0xA014,0xA00A,0xA004,0xA002,0x6FF0,0x70BA,0xA002,0x60DF, 0xA002,0x552F,0x570D,0xA004,0xA002,0x6845,0x9055,0xA002,0x97E6,0xA002,0x5371,0x5FAE,0xA000,0xA000,0xA000,0x5DCD, 0xA0C0,0xA057,0xA001,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x5A01,0x5984,0xA002,0x5FD8,0xA002,0x6722,0x6680,0xA004, 0xA002,0x5F80,0x7F51,0xA002,0x6789,0xA002,0x4EA1,0x738B,0xA00A,0xA004,0xA002,0x6C6A,0x8155,0xA002,0x842C,0xA002, 0x5A49,0x5B9B,0xA006,0xA002,0x60CB,0xA002,0x7696,0x665A,0xA002,0x8F13,0xA002,0x7897,0x5B8C,0xA016,0xA00A,0xA004, 0xA002,0x70F7,0x4E38,0xA002,0x987D,0xA002,0x7FEB,0x7063,0xA006,0xA002,0x5F4E,0xA002,0x8C4C,0x5916,0xA002,0x6B6A, 0xA002,0x977A,0x74E6,0xA00A,0xA004,0xA002,0x5A03,0x7AAA,0xA002,0x86D9,0xA002,0x54C7,0x7A75,0xA006,0xA002,0x553E, 0xA002,0x6428,0x59A5,0xA002,0x6A62,0xA002,0x9A7C,0x9A6E,0xA056,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x9640,0x9E35, 0xA002,0x8131,0xA002,0x8A17,0x62D6,0xA004,0xA002,0x81C0,0x5C6F,0xA002,0x541E,0xA002,0x9000,0x892A,0xA00A,0xA004, 0xA002,0x8715,0x817F,0xA002,0x9893,0xA002,0x63A8,0x7CF0,0xA006,0xA002,0x6E4D,0xA002,0x5154,0x5410,0xA002,0x571F, 0xA002,0x5C60,0x6D82,0xA016,0xA00A,0xA004,0xA002,0x9014,0x5F92,0xA002,0x5716,0xA002,0x7A81,0x79C3,0xA006,0xA002, 0x51F8,0xA002,0x900F,0x982D,0xA002,0x6295,0xA002,0x5AAE,0x75DB,0xA00A,0xA004,0xA002,0x7EDF,0x7B69,0xA002,0x6345, 0xA002,0x6876,0x7AE5,0xA006,0xA002,0x5F64,0xA002,0x94DC,0x8855,0xA002,0x77B3,0xA002,0x916E,0x6850,0xA000,0xA000, 0xA00A,0xA004,0xA002,0x901A,0x8247,0xA002,0x633A,0xA002,0x5EAD,0x4EAD,0xA000,0xA002,0x505C,0xA002,0x5EF7,0x6C40, 0xA001,0xA00A,0xA001,0xA001,0xA001,0xA001,0xA002,0x70F4,0xA002,0x807D,0x5EF3,0xA02C,0xA016,0xA00A,0xA004,0xA002, 0x6017,0x94C1,0xA002,0x8D34,0xA002,0x8DF3,0x773A,0xA006,0xA002,0x8FE2,0xA002,0x689D,0x6311,0xA002,0x8146,0xA002, 0x8214,0x606C,0xA00A,0xA004,0xA002,0x751C,0x7530,0xA002,0x586B,0xA002,0x6DFB,0x5929,0xA006,0xA002,0x5C5C,0xA002, 0x5243,0x6D95,0xA002,0x6113,0xA002,0x568F,0x66FF,0xA016,0xA00A,0xA004,0xA002,0x9AD4,0x557C,0xA002,0x8E44,0xA002, 0x9898,0x63D0,0xA006,0xA002,0x9511,0xA002,0x8E22,0x5254,0xA002,0x68AF,0xA002,0x8B04,0x75BC,0xA00A,0xA004,0xA002, 0x9A30,0x85E4,0xA002,0x7286,0xA002,0x5957,0x8BA8,0xA006,0xA002,0x9676,0xA002,0x6DD8,0x9003,0xA002,0x6843,0xA002, 0x8404,0x7EE6,0xB068,0xA804,0xA434,0xA1E9,0xA126,0xA063,0xA000,0xA056,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x6ED4, 0x6FE4,0xA002,0x642F,0xA002,0x71D9,0x8D9F,0xA004,0xA002,0x6DCC,0x8EBA,0xA002,0x5018,0xA002,0x7CD6,0x5510,0xA00A, 0xA004,0xA002,0x819B,0x68E0,0xA002,0x5802,0xA002,0x642A,0x5858,0xA006,0xA002,0x6E6F,0xA002,0x70AD,0x6B4E,0xA002, 0x63A2,0xA002,0x78B3,0x8892,0xA016,0xA00A,0xA004,0xA002,0x6BEF,0x5766,0xA002,0x8C08,0xA002,0x8C2D,0x6F6D,0xA006, 0xA002,0x75F0,0xA002,0x6A80,0x7F48,0xA002,0x7058,0xA002,0x7671,0x8D2A,0xA00A,0xA004,0xA002,0x6524,0x574D,0xA002, 0x6C70,0xA002,0x614B,0x592A,0xA006,0xA002,0x915E,0xA002,0x6CF0,0x98B1,0xA002,0x62AC,0xA002,0x82D4,0x80CE,0xA000, 0xA000,0xA000,0xA004,0xA002,0x8E0F,0x8E4B,0xA002,0x64BB,0xA000,0x737A,0xA065,0xA00F,0xA001,0xA001,0xA001,0xA006, 0xA002,0x5854,0xA002,0x5979,0x7260,0xA002,0x4ED6,0xA002,0x584C,0x6240,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x9501, 0x7D22,0xA002,0x7463,0xA002,0x7F29,0x5506,0xA004,0xA002,0x68AD,0x84D1,0xA002,0x7B4D,0xA002,0x640D,0x5B6B,0xA00A, 0xA004,0xA002,0x795F,0x96A7,0xA002,0x9042,0xA002,0x7A57,0x6B72,0xA006,0xA002,0x788E,0xA002,0x9AD3,0x7EE5,0xA002, 0x96A8,0xA002,0x968B,0x96D6,0xA016,0xA00A,0xA004,0xA002,0x7B97,0x849C,0xA002,0x9178,0xA002,0x8085,0x8BC9,0xA006, 0xA002,0x5BBF,0xA002,0x6EAF,0x5851,0xA002,0x50F3,0xA002,0x7C9F,0x901F,0xA00A,0xA004,0xA002,0x7D20,0x4FD7,0xA002, 0x9165,0xA002,0x8607,0x55FD,0xA006,0xA002,0x64FB,0xA002,0x825A,0x8490,0xA002,0x8BF5,0xA002,0x8BBC,0x5B8B,0xA056, 0xA02A,0xA014,0xA00A,0xA004,0xA002,0x9001,0x9882,0xA002,0x616B,0xA002,0x8073,0x9B06,0xA004,0xA002,0x5DF3,0x9972, 0xA002,0x4F3C,0xA002,0x8997,0x56DB,0xA00A,0xA004,0xA002,0x55E3,0x5BFA,0xA002,0x8086,0xA002,0x6B7B,0x7D72,0xA006, 0xA002,0x53F8,0xA002,0x79C1,0x6952,0xA002,0x5636,0xA002,0x6495,0x65AF,0xA016,0xA00A,0xA004,0xA002,0x720D,0x6714, 0xA002,0x78A9,0xA002,0x8BF4,0x821C,0xA006,0xA002,0x987A,0xA002,0x77AC,0x542E,0xA002,0x7A0E,0xA002,0x7761,0x6C34, 0xA00A,0xA004,0xA002,0x8C01,0x723D,0xA002,0x96D9,0xA002,0x971C,0x62F4,0xA006,0xA002,0x6813,0xA002,0x5E25,0x7529, 0xA002,0x8870,0xA002,0x6454,0x800D,0xA000,0xA000,0xA000,0xA000,0xA002,0x5237,0x6055,0xA06C,0xA001,0xA015,0xA001, 0xA001,0xA007,0xA001,0xA002,0x6F31,0xA002,0x6578,0x5EB6,0xA006,0xA002,0x5885,0xA002,0x8C4E,0x620D,0xA002,0x675F, 0xA002,0x6A39,0x8FF0,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x8853,0x5C6C,0xA002,0x9F20,0xA002,0x9ECD,0x8700,0xA004, 0xA002,0x7F72,0x66D9,0xA002,0x6691,0xA002,0x85F7,0x719F,0xA00A,0xA004,0xA002,0x5B70,0x8D4E,0xA002,0x66F8,0xA002, 0x758F,0x6DD1,0xA006,0xA002,0x8212,0xA002,0x53D4,0x8F93,0xA002,0x6292,0xA002,0x6B8A,0x68B3,0xA016,0xA00A,0xA004, 0xA002,0x6A1E,0x852C,0xA002,0x7378,0xA002,0x7626,0x53D7,0xA006,0xA002,0x552E,0xA002,0x6388,0x5BFF,0xA002,0x5B88, 0xA002,0x9996,0x624B,0xA00A,0xA004,0xA002,0x6536,0x8BD5,0xA002,0x89C6,0xA002,0x5BA4,0x6043,0xA006,0xA002,0x5E02, 0xA002,0x6C0F,0x9970,0xA002,0x91CB,0xA002,0x4F8D,0x4ED5,0xA000,0xA000,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x9069, 0x566C,0xA002,0x55DC,0xA002,0x662F,0x52E2,0xA004,0xA002,0x901D,0x8A93,0xA002,0x62ED,0xA002,0x525A,0x67FF,0xA00A, 0xA004,0xA002,0x4E16,0x58EB,0xA002,0x793A,0xA002,0x5F0F,0x59CB,0xA006,0xA002,0x9A76,0xA002,0x5C4E,0x4F7F,0xA002, 0x77E2,0xA002,0x53F2,0x8BC6,0xA016,0xA00A,0xA004,0xA002,0x5BE6,0x8755,0xA002,0x98DF,0xA002,0x4EC0,0x6642,0xA006, 0xA002,0x62FE,0xA002,0x77F3,0x5341,0xA002,0x8768,0xA002,0x5C4D,0x8BD7,0xA00A,0xA004,0xA002,0x6FD5,0x65BD,0xA002, 0x7345,0xA002,0x5931,0x5E2B,0xA006,0xA002,0x8056,0xA002,0x80DC,0x8CF8,0xA002,0x76DB,0xA000,0x7701,0xA13C,0xA0C4, 0xA073,0xA01D,0xA001,0xA006,0xA001,0xA001,0xA001,0xA001,0x7EF3,0xA00A,0xA004,0xA002,0x965E,0x7272,0xA002,0x7525, 0xA002,0x751F,0x8072,0xA006,0xA002,0x6EF2,0xA002,0x614E,0x814E,0xA002,0x751A,0xA002,0x5B38,0x5BE9,0xA02A,0xA014, 0xA00A,0xA004,0xA002,0x700B,0x795E,0xA002,0x7EC5,0xA002,0x5A20,0x6DF1,0xA004,0xA002,0x8EAB,0x4F38,0xA002,0x547B, 0xA002,0x7533,0x7837,0xA00A,0xA004,0xA002,0x8BBE,0x793E,0xA002,0x6D89,0xA002,0x61FE,0x5C04,0xA006,0xA002,0x651D, 0xA002,0x8D66,0x820D,0xA002,0x820C,0xA002,0x86C7,0x8D4A,0xA016,0xA00A,0xA004,0xA002,0x5962,0x7ECD,0xA002,0x90B5, 0xA002,0x54E8,0x5C11,0xA006,0xA002,0x97F6,0xA002,0x52FA,0x828D,0xA002,0x71D2,0xA002,0x7A0D,0x634E,0xA00A,0xA004, 0xA002,0x68A2,0x88F3,0xA002,0x5C1A,0xA002,0x4E0A,0x664C,0xA006,0xA002,0x8D4F,0xA002,0x5546,0x50B7,0xA002,0x5892, 0xA002,0x7F2E,0x6247,0xA000,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x6C55,0x5584,0xA002,0x81B3,0xA002,0x8D61,0x64C5, 0xA004,0xA002,0x965D,0x95EA,0xA002,0x886B,0xA002,0x717D,0x522A,0xA00A,0xA004,0xA002,0x5C71,0x7154,0xA002,0x82EB, 0xA002,0x73CA,0x66EC,0xA006,0xA002,0x7BE9,0xA002,0x715E,0x5565,0xA002,0x50BB,0xA002,0x7EB1,0x6C99,0xA016,0xA00A, 0xA004,0xA002,0x524E,0x6BBA,0xA002,0x7802,0xA002,0x838E,0x50E7,0xA006,0xA002,0x68EE,0xA002,0x6F80,0x8272,0xA002, 0x745F,0xA002,0x5AC2,0x6383,0xA00A,0xA004,0xA002,0x9A9A,0x6414,0xA002,0x55AA,0xA002,0x55D3,0x6851,0xA000,0xA002, 0x6563,0xA000,0x5098,0xA001,0xA01F,0xA001,0xA008,0xA001,0xA001,0xA002,0x53C1,0xA002,0x4E09,0x8D5B,0xA00A,0xA004, 0xA002,0x585E,0x9CC3,0xA002,0x816E,0xA002,0x85A9,0x7051,0xA006,0xA002,0x6492,0xA002,0x5F31,0x82E5,0xA002,0x6F64, 0xA002,0x95F0,0x9510,0xA02C,0xA016,0xA00A,0xA004,0xA002,0x745E,0x854A,0xA002,0x962E,0xA002,0x8F6F,0x8925,0xA006, 0xA002,0x5165,0xA002,0x6C5D,0x4E73,0xA002,0x8FB1,0xA002,0x5982,0x5B7A,0xA00A,0xA004,0xA002,0x5112,0x8815,0xA002, 0x8339,0xA002,0x8089,0x67D4,0xA006,0xA002,0x7163,0xA002,0x5197,0x7FA2,0xA002,0x5BB9,0xA002,0x6EB6,0x9394,0xA016, 0xA00A,0xA004,0xA002,0x878D,0x8363,0xA002,0x84C9,0xA002,0x8338,0x620E,0xA006,0xA002,0x65E5,0xA002,0x793D,0x6254, 0xA002,0x7EAB,0xA002,0x598A,0x5203,0xA00A,0xA004,0xA002,0x8BA4,0x4EFB,0xA002,0x97E7,0xA002,0x5FCD,0x4EBA,0xA006, 0xA002,0x4EC1,0xA002,0x58EC,0x71B1,0xA002,0x60F9,0xA002,0x7ED5,0x64FE,0xA04C,0xA000,0xA000,0xA02A,0xA014,0xA00A, 0xA004,0xA002,0x9976,0x8BA9,0xA002,0x56B7,0xA002,0x6518,0x58E4,0xA004,0xA002,0x74E4,0x67D3,0xA002,0x5189,0xA002, 0x71C3,0x7136,0xA00A,0xA004,0xA002,0x7FA4,0x88D9,0xA002,0x96C0,0xA002,0x78BA,0x69B7,0xA006,0xA002,0x9E4A,0xA002, 0x537B,0x7638,0xA002,0x7094,0xA002,0x7F3A,0x52F8,0xA016,0xA00A,0xA004,0xA002,0x5238,0x72AC,0xA002,0x62F3,0xA002, 0x75CA,0x5168,0xA006,0xA002,0x6CC9,0xA002,0x919B,0x6B0A,0xA002,0x98A7,0xA002,0x5708,0x53BB,0xA000,0xA004,0xA002, 0x8DA3,0x9F8B,0xA002,0x5A36,0xA000,0x53D6,0xA07E,0xA028,0xA001,0xA011,0xA005,0xA001,0xA001,0xA001,0x6E20,0xA006, 0xA002,0x9A71,0xA002,0x5C48,0x8EC0,0xA002,0x66F2,0xA002,0x86C6,0x5340,0xA00A,0xA004,0xA002,0x8DA8,0x6CC5,0xA002, 0x914B,0xA002,0x56DA,0x6C42,0xA006,0xA002,0x7403,0xA002,0x90B1,0x5775,0xA002,0x97A6,0xA002,0x7AAE,0x74CA,0xA02A, 0xA014,0xA00A,0xA004,0xA002,0x6176,0x8BF7,0xA002,0x9877,0xA002,0x60C5,0x6C30,0xA004,0xA002,0x6674,0x64CE,0xA002, 0x6E05,0xA002,0x537F,0x50BE,0xA00A,0xA004,0xA002,0x6C2B,0x8F7B,0xA002,0x9752,0xA002,0x6C81,0x5BE2,0xA006,0xA002, 0x79BD,0xA002,0x64D2,0x82B9,0xA002,0x61C3,0xA002,0x7434,0x79E6,0xA016,0xA00A,0xA004,0xA002,0x89AA,0x4FB5,0xA002, 0x94A6,0xA002,0x7ACA,0x602F,0xA006,0xA002,0x4E14,0xA002,0x8304,0x5207,0xA002,0x7AC5,0xA002,0x4FCF,0x5CED,0xA00A, 0xA004,0xA002,0x7FF9,0x64AC,0xA002,0x9798,0xA002,0x5DE7,0x50D1,0xA006,0xA002,0x55AC,0xA002,0x77A7,0x6A4B,0xA002, 0x6084,0xA002,0x6572,0x9539,0xA000,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x6A47,0x6436,0xA002,0x5F4A,0xA002,0x8594, 0x7246,0xA004,0xA002,0x7F8C,0x8154,0xA002,0x55C6,0xA002,0x9397,0x6B49,0xA00A,0xA004,0xA002,0x6B20,0x5D4C,0xA002, 0x5879,0xA002,0x8C34,0x6DFA,0xA006,0xA002,0x9063,0xA002,0x6F5C,0x524D,0xA002,0x94B3,0xA002,0x94B1,0x9ED4,0xA015, 0xA009,0xA003,0xA001,0x8C26,0xA002,0x4EDF,0xA002,0x7C64,0x9077,0xA006,0xA002,0x97C6,0xA002,0x94C5,0x948E,0xA002, 0x6266,0xA002,0x727D,0x6D3D,0xA000,0xA000,0xA000,0x6070,0xA219,0xA0C3,0xA083,0xA001,0xA02C,0xA001,0xA015,0xA009, 0xA003,0xA001,0x6390,0xA002,0x8BAB,0xA002,0x6CE3,0x6ECA,0xA006,0xA002,0x68C4,0xA002,0x8FC4,0x6C23,0xA002,0x5668, 0xA002,0x780C,0x6814,0xA00A,0xA004,0xA002,0x555F,0x4F01,0xA002,0x4E5E,0xA002,0x8C48,0x8D77,0xA006,0xA002,0x9A91, 0xA002,0x7941,0x7948,0xA002,0x65D7,0xA002,0x9F50,0x81CD,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x5D0E,0x7566,0xA002, 0x8DC2,0xA002,0x5947,0x68CB,0xA004,0xA002,0x5176,0x6C8F,0xA002,0x67D2,0xA002,0x6F06,0x6DD2,0xA00A,0xA004,0xA002, 0x4E03,0x59BB,0xA002,0x93DA,0xA002,0x68F2,0x6B3A,0xA006,0xA002,0x7A18,0xA002,0x7011,0x66DD,0xA002,0x8C31,0xA002, 0x6D66,0x666E,0xA016,0xA00A,0xA004,0xA002,0x5703,0x6A38,0xA002,0x57D4,0xA002,0x84B2,0x83E9,0xA006,0xA002,0x8461, 0xA002,0x8386,0x50D5,0xA002,0x94FA,0xA002,0x64B2,0x5256,0xA00A,0xA004,0xA002,0x7C95,0x8FEB,0xA002,0x9B44,0xA002, 0x7834,0x5A46,0xA006,0xA002,0x9887,0xA002,0x6F51,0x5761,0xA002,0x84F1,0xA002,0x8BC4,0x7F3E,0xA000,0xA000,0xA02A, 0xA014,0xA00A,0xA004,0xA002,0x6191,0x5E73,0xA002,0x840D,0xA002,0x860B,0x576A,0xA004,0xA002,0x4E52,0x8058,0xA002, 0x54C1,0xA002,0x8D2B,0x9891,0xA00A,0xA004,0xA002,0x62FC,0x8995,0xA002,0x6487,0xA002,0x7968,0x74E2,0xA006,0xA002, 0x6F02,0xA002,0x98D8,0x9A97,0xA002,0x7247,0xA002,0x504F,0x7BC7,0xA000,0xA00A,0xA004,0xA002,0x8B6C,0x5C41,0xA002, 0x50FB,0xA002,0x75DE,0x5339,0xA006,0xA002,0x76AE,0xA002,0x75B2,0x813E,0xA000,0x5564,0xA0C4,0xA08A,0xA034,0xA008, 0xA001,0xA001,0xA001,0xA001,0xA002,0x6BD8,0x7435,0xA016,0xA00A,0xA004,0xA002,0x5288,0x62AB,0xA002,0x6279,0xA002, 0x9739,0x7812,0xA006,0xA002,0x576F,0xA002,0x78B0,0x6367,0xA002,0x9E4F,0xA002,0x670B,0x81A8,0xA00A,0xA004,0xA002, 0x7BF7,0x787C,0xA002,0x68DA,0xA002,0x84EC,0x5F6D,0xA006,0xA002,0x6F8E,0xA002,0x70F9,0x62A8,0xA002,0x7830,0xA002, 0x76C6,0x5674,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x6C9B,0x73EE,0xA002,0x914D,0xA002,0x966A,0x8D54,0xA004,0xA002, 0x88F4,0x57F9,0xA002,0x80DA,0xA002,0x5478,0x6CE1,0xA00A,0xA004,0xA002,0x8DD1,0x888D,0xA002,0x7832,0xA002,0x9464, 0x5486,0xA006,0xA002,0x62CB,0xA002,0x80D6,0x802A,0xA002,0x65C1,0xA002,0x9F90,0x4E53,0xA016,0xA00A,0xA004,0xA002, 0x53DB,0x5224,0xA002,0x7554,0xA002,0x76FC,0x78D0,0xA006,0xA002,0x76E4,0xA002,0x6F58,0x6500,0xA002,0x6D3E,0xA002, 0x6E43,0x5F98,0xA00A,0xA004,0xA002,0x724C,0x6392,0xA002,0x62CD,0xA002,0x7436,0x6015,0xA006,0xA002,0x5E15,0xA002, 0x722C,0x8DB4,0xA002,0x556A,0xA002,0x6F1A,0x5076,0xA000,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x5614,0x85D5,0xA002, 0x6BC6,0xA002,0x9E25,0x6B50,0xA004,0xA002,0x54E6,0x8BFA,0xA002,0x7CEF,0xA002,0x61E6,0x637C,0xA00A,0xA004,0xA002, 0x7627,0x8650,0xA002,0x7156,0xA002,0x5973,0x6012,0xA006,0xA002,0x52AA,0xA002,0x5974,0x8856,0xA002,0x8FB2,0xA002, 0x6FC3,0x81BF,0xA000,0xA00A,0xA004,0xA002,0x7EBD,0x94AE,0xA002,0x626D,0xA002,0x725B,0x6FD8,0xA000,0xA000,0x64F0, 0xA001,0xA039,0xA00D,0xA001,0xA001,0xA005,0xA001,0xA002,0x5BE7,0x51DD,0xA002,0x7370,0xA002,0x6AB8,0x60A8,0xA016, 0xA00A,0xA004,0xA002,0x6D85,0x954D,0xA002,0x954A,0xA002,0x9F67,0x5B7D,0xA006,0xA002,0x8076,0xA002,0x634F,0x5C3F, 0xA002,0x9E1F,0xA002,0x91C0,0x5B43,0xA00A,0xA004,0xA002,0x5FF5,0x649A,0xA002,0x6506,0xA002,0x78BE,0x5E74,0xA006, 0xA002,0x62C8,0xA002,0x852B,0x6EBA,0xA002,0x9006,0xA002,0x81A9,0x533F,0xA02C,0xA016,0xA00A,0xA004,0xA002,0x59B3, 0x64EC,0xA002,0x5C3C,0xA002,0x6CE5,0x90F3,0xA006,0xA002,0x9713,0xA002,0x5A57,0x80FD,0xA002,0x5AE9,0xA002,0x5185, 0x9981,0xA00A,0xA004,0xA002,0x5462,0x6DD6,0xA002,0x9B27,0xA002,0x60F1,0x8166,0xA006,0xA002,0x6493,0xA002,0x56CA, 0x96E3,0xA002,0x7537,0xA002,0x5357,0x5948,0xA016,0xA00A,0xA004,0xA002,0x8010,0x5976,0xA002,0x8FFA,0xA002,0x6C16, 0x7EB3,0xA006,0xA002,0x5A1C,0xA002,0x90A3,0x94A0,0xA002,0x5450,0xA002,0x54EA,0x6310,0xA00A,0xA004,0xA002,0x7A46, 0x7267,0xA002,0x7766,0xA002,0x76EE,0x6728,0xA006,0xA002,0x6155,0xA002,0x52DF,0x5E59,0xA002,0x66AE,0xA002,0x5893, 0x6BCD,0xA0F4,0xA033,0xA000,0xA000,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x59C6,0x755D,0xA002,0x7261,0xA002,0x62C7, 0x67D0,0xA004,0xA002,0x725F,0x8C0B,0xA002,0x964C,0xA002,0x5BDE,0x6F20,0xA00A,0xA004,0xA002,0x6CAB,0x9ED8,0xA002, 0x58A8,0xA002,0x83AB,0x672B,0xA006,0xA002,0x62B9,0xA002,0x9B54,0x6469,0xA002,0x78E8,0xA002,0x819C,0x6A21,0xA000, 0xA000,0xA000,0xA002,0x8611,0x6479,0xA095,0xA03F,0xA013,0xA001,0xA006,0xA001,0xA001,0xA002,0x6478,0x8C2C,0xA006, 0xA002,0x547D,0xA002,0x540D,0x94ED,0xA002,0x9E23,0xA002,0x879F,0x660E,0xA016,0xA00A,0xA004,0xA002,0x95FD,0x61AB, 0xA002,0x654F,0xA002,0x76BF,0x62BF,0xA006,0xA002,0x6C11,0xA002,0x706D,0x884A,0xA002,0x7385,0xA002,0x5EDF,0x6E3A, 0xA00A,0xA004,0xA002,0x79D2,0x85D0,0xA002,0x7784,0xA002,0x63CF,0x82D7,0xA006,0xA002,0x9EB5,0xA002,0x7F05,0x5A29, 0xA002,0x52C9,0xA002,0x514D,0x7D7B,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x7EF5,0x7720,0xA002,0x68C9,0xA002,0x5E42, 0x5BC6,0xA004,0xA002,0x871C,0x6CCC,0xA002,0x89C5,0xA002,0x959F,0x7C73,0xA00A,0xA004,0xA002,0x7030,0x8C1C,0xA002, 0x8FF7,0xA002,0x7CDC,0x9761,0xA006,0xA002,0x919A,0xA002,0x7787,0x5B5F,0xA002,0x68A6,0xA002,0x731B,0x9530,0xA016, 0xA00A,0xA004,0xA002,0x76DF,0x6AAC,0xA002,0x8499,0xA002,0x840C,0x5011,0xA006,0xA002,0x95F7,0xA002,0x95E8,0x5A9A, 0xA002,0x59BA,0xA002,0x5BD0,0x6627,0xA00A,0xA004,0xA002,0x7F8E,0x6BCF,0xA002,0x9541,0xA002,0x5A92,0x7709,0xA006, 0xA002,0x6CA1,0xA002,0x7164,0x9EF4,0xA002,0x9176,0xA002,0x6885,0x679A,0xA000,0xA000,0xA014,0xA00A,0xA004,0xA002, 0x73AB,0x9EBC,0xA002,0x8D38,0xA002,0x8C8C,0x5E3D,0xA004,0xA002,0x5192,0x8302,0xA002,0x536F,0xA002,0x94C6,0x77DB, 0xA00A,0xA004,0xA002,0x82BC,0x951A,0xA002,0x8305,0xA002,0x8C93,0x83BD,0xA006,0xA002,0x5FD9,0xA002,0x6C13,0x76F3, 0xA002,0x832B,0xA002,0x8292,0x8C29,0xA09C,0xA001,0xA043,0xA017,0xA001,0xA00A,0xA004,0xA002,0x6F2B,0x6162,0xA002, 0x66FC,0xA002,0x8513,0x6EFF,0xA006,0xA002,0x883B,0xA002,0x9992,0x779E,0xA002,0x8109,0xA002,0x9081,0x8CE3,0xA016, 0xA00A,0xA004,0xA002,0x9EA6,0x8CB7,0xA002,0x57CB,0xA002,0x55CE,0x561B,0xA006,0xA002,0x9A82,0xA002,0x9A6C,0x879E, 0xA002,0x78BC,0xA002,0x746A,0x9EBB,0xA00A,0xA004,0xA002,0x5ABD,0x7EDC,0xA002,0x9A86,0xA002,0x6D1B,0x843D,0xA006, 0xA002,0x88F8,0xA002,0x9AA1,0x7C6E,0xA002,0x9523,0xA002,0x908F,0x7F85,0xA02C,0xA016,0xA00A,0xA004,0xA002,0x87BA, 0x863F,0xA002,0x8BBA,0xA002,0x7EB6,0x6DEA,0xA006,0xA002,0x5D19,0xA002,0x502B,0x8F6E,0xA002,0x6384,0xA002,0x7565, 0x63A0,0xA00A,0xA004,0xA002,0x4E82,0x5375,0xA002,0x7064,0xA002,0x5B7F,0x6523,0xA006,0xA002,0x5DD2,0xA002,0x83C9, 0x6FFE,0xA002,0x7387,0xA002,0x5F8B,0x6C2F,0xA016,0xA00A,0xA004,0xA002,0x8651,0x7F15,0xA002,0x5C62,0xA002,0x5C65, 0x65C5,0xA006,0xA002,0x4FB6,0xA002,0x94DD,0x5442,0xA002,0x9A74,0xA002,0x622E,0x9678,0xA00A,0xA004,0xA002,0x9304, 0x7984,0xA002,0x6F5E,0xA002,0x9E7F,0x8D42,0xA006,0xA002,0x8DEF,0xA002,0x9732,0x788C,0xA002,0x9E93,0xA002,0x9C81, 0x865C,0xA000,0xA000,0xA000,0xA014,0xA00A,0xA004,0xA002,0x9E75,0x64C4,0xA002,0x946A,0xA002,0x5EEC,0x9885,0xA004, 0xA002,0x76E7,0x8606,0xA002,0x964B,0xA002,0x6F0F,0x7C0D,0xA00A,0xA004,0xA002,0x645F,0x5A41,0xA002,0x6A13,0xA002, 0x96B4,0x650F,0xA000,0xA002,0x58DF,0xA000,0x9686,0xA493,0xA248,0xA16C,0xA0C2,0xA0A2,0xA04C,0xA020,0xA00A,0xA001, 0xA003,0xA001,0x7ABF,0xA002,0x7C60,0xA002,0x56A8,0x807E,0xA00A,0xA004,0xA002,0x9F99,0x516D,0xA002,0x67F3,0xA002, 0x6D41,0x7624,0xA006,0xA002,0x5289,0xA002,0x7559,0x998F,0xA002,0x786B,0xA002,0x69B4,0x7409,0xA016,0xA00A,0xA004, 0xA002,0x9724,0x4EE4,0xA002,0x53E6,0xA002,0x9886,0x5DBA,0xA006,0xA002,0x9675,0xA002,0x9748,0x6DE9,0xA002,0x7F9A, 0xA002,0x4F36,0x94C3,0xA00A,0xA004,0xA002,0x9F84,0x96F6,0xA002,0x83F1,0xA002,0x73B2,0x62CE,0xA006,0xA002,0x541D, 0xA002,0x8D41,0x51DC,0xA002,0x6DCB,0xA002,0x9CDE,0x9130,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x81E8,0x9716,0xA002, 0x78F7,0xA002,0x6797,0x7433,0xA004,0xA002,0x7375,0x52A3,0xA002,0x70C8,0xA002,0x88C2,0x5217,0xA00A,0xA004,0xA002, 0x6599,0x5ED6,0xA002,0x9563,0xA002,0x6482,0x77AD,0xA006,0xA002,0x6F66,0xA002,0x907C,0x5BE5,0xA002,0x71CE,0xA002, 0x7642,0x50DA,0xA016,0xA00A,0xA004,0xA002,0x804A,0x64A9,0xA002,0x8C05,0xA002,0x4EAE,0x667E,0xA006,0xA002,0x91CF, 0xA002,0x8F86,0x5169,0xA002,0x826F,0xA002,0x7CB1,0x6A11,0xA00A,0xA004,0xA002,0x6DBC,0x7CE7,0xA002,0x7EC3,0xA002, 0x7149,0x6200,0xA006,0xA002,0x94FE,0xA002,0x81C9,0x6582,0xA002,0x7C3E,0xA002,0x6F23,0x6190,0xA000,0xA000,0xA014, 0xA00A,0xA004,0xA002,0x5EC9,0x9570,0xA002,0x9023,0xA002,0x84EE,0x806F,0xA004,0xA002,0x5006,0x54E9,0xA002,0x7483, 0xA002,0x52A6,0x96B8,0xA000,0xA004,0xA002,0x701D,0x7C92,0xA002,0x7ACB,0xA000,0x75E2,0xA001,0xA051,0xA025,0xA00F, 0xA005,0xA001,0xA001,0xA001,0x4FD0,0xA004,0xA002,0x4F8B,0x5088,0xA002,0x5229,0xA002,0x6B77,0x792B,0xA00A,0xA004, 0xA002,0x52F5,0x7805,0xA002,0x9E97,0xA002,0x6817,0x540F,0xA006,0xA002,0x8354,0xA002,0x8389,0x79AE,0xA002,0x9CA4, 0xA002,0x91CC,0x674E,0xA016,0xA00A,0xA004,0xA002,0x7406,0x7055,0xA002,0x96E2,0xA002,0x72F8,0x7C6C,0xA006,0xA002, 0x9ECE,0xA002,0x7281,0x68A8,0xA002,0x91D0,0xA002,0x51B7,0x695E,0xA00A,0xA004,0xA002,0x7A1C,0x6DDA,0xA002,0x985E, 0xA002,0x808B,0x64C2,0xA006,0xA002,0x58D8,0xA002,0x5121,0x7E8D,0xA002,0x78CA,0xA002,0x857E,0x956D,0xA02C,0xA016, 0xA00A,0xA004,0xA002,0x96F7,0x6A02,0xA002,0x52D2,0xA002,0x6F87,0x70D9,0xA006,0xA002,0x916A,0xA002,0x59E5,0x4F6C, 0xA002,0x8001,0xA002,0x7262,0x52DE,0xA00A,0xA004,0xA002,0x6488,0x6D6A,0xA002,0x6717,0xA002,0x90CE,0x5ECA,0xA006, 0xA002,0x72FC,0xA002,0x6994,0x746F,0xA002,0x6FEB,0xA002,0x721B,0x7F06,0xA016,0xA00A,0xA004,0xA002,0x61F6,0x89C8, 0xA002,0x652C,0xA002,0x8C30,0x703E,0xA006,0xA002,0x862D,0xA002,0x9611,0x7C43,0xA002,0x6514,0xA002,0x6B04,0x60CF, 0xA00A,0xA004,0xA002,0x85CD,0x8D56,0xA002,0x6765,0xA002,0x840A,0x5566,0xA006,0xA002,0x8FA3,0xA002,0x81D8,0x881F, 0xA002,0x5587,0xA002,0x62F9,0x5783,0xA01C,0xA000,0xA000,0xA000,0xA014,0xA00A,0xA004,0xA002,0x9614,0x5ED3,0xA002, 0x64F4,0xA002,0x62EC,0x774F,0xA004,0xA002,0x7D91,0x665C,0xA002,0x5764,0xA002,0x6F70,0x6127,0xA000,0xA000,0xA000, 0x9988,0xA0AC,0xA056,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x5080,0x9B41,0xA002,0x594E,0xA002,0x8475,0x7ABA,0xA004, 0xA002,0x5DCB,0x76D4,0xA002,0x8667,0xA002,0x6CC1,0x66E0,0xA00A,0xA004,0xA002,0x7736,0x7926,0xA002,0x6846,0xA002, 0x72C2,0x7B50,0xA006,0xA002,0x5321,0xA002,0x6B3E,0x5BEC,0xA002,0x5FEB,0xA002,0x5108,0x7B77,0xA016,0xA00A,0xA004, 0xA002,0x584A,0x80EF,0xA002,0x8DE8,0xA002,0x630E,0x57AE,0xA006,0xA002,0x8A87,0xA002,0x8932,0x5EAB,0xA002,0x9177, 0xA002,0x82E6,0x7A9F,0xA00A,0xA004,0xA002,0x54ED,0x67AF,0xA002,0x5BC7,0xA002,0x91E6,0x56D7,0xA006,0xA002,0x6473, 0xA002,0x63A7,0x5B54,0xA002,0x6050,0xA002,0x7A7A,0x542D,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x962C,0x61C7,0xA002, 0x58BE,0xA002,0x8C64,0x80AF,0xA004,0xA002,0x8BFE,0x5BA2,0xA002,0x523B,0xA002,0x524B,0x6E34,0xA00A,0xA004,0xA002, 0x53EF,0x6B2C,0xA002,0x6BBC,0xA002,0x79D1,0x9897,0xA006,0xA002,0x78D5,0xA002,0x68F5,0x7241,0xA002,0x82DB,0xA002, 0x5777,0x9760,0xA016,0xA00A,0xA004,0xA002,0x70E4,0x62F7,0xA002,0x8003,0xA002,0x7095,0x4EA2,0xA006,0xA002,0x6297, 0xA002,0x6443,0x7CE0,0xA002,0x6177,0xA002,0x5EB7,0x770B,0xA00A,0xA004,0xA002,0x780D,0x6B3F,0xA002,0x52D8,0xA002, 0x582A,0x520A,0xA006,0xA002,0x6168,0xA002,0x51F1,0x6977,0xA002,0x63E9,0xA002,0x958B,0x54AF,0xA000,0xA000,0xA000, 0xA00A,0xA004,0xA002,0x5361,0x5496,0xA002,0x5580,0xA002,0x9A8F,0x90E1,0xA004,0xA002,0x6FEC,0x7AE3,0xA000,0x5BEF, 0xA0D5,0xA0B7,0xA00B,0xA001,0xA001,0xA001,0xA001,0xA001,0xA002,0x5D1A,0xA002,0x541B,0x8ECD,0xA056,0xA02A,0xA014, 0xA00A,0xA004,0xA002,0x94A7,0x83CC,0xA002,0x5747,0xA002,0x7EDD,0x8BC0,0xA004,0xA002,0x73A6,0x89C9,0xA002,0x7235, 0xA002,0x5014,0x6398,0xA00A,0xA004,0xA002,0x6289,0x652B,0xA002,0x6485,0xA002,0x7EE2,0x6372,0xA006,0xA002,0x7760, 0xA002,0x5026,0x5A1F,0xA002,0x9E43,0xA002,0x6350,0x5287,0xA016,0xA00A,0xA004,0xA002,0x70AC,0x61FC,0xA002,0x53E5, 0xA002,0x4FF1,0x952F,0xA006,0xA002,0x8E1E,0xA002,0x8DDD,0x5177,0xA002,0x5DE8,0xA002,0x64DA,0x62D2,0xA00A,0xA004, 0xA002,0x805A,0x6CAE,0xA002,0x8209,0xA002,0x842D,0x5480,0xA006,0xA002,0x8DFC,0xA002,0x83CA,0x9A79,0xA002,0x5C45, 0xA002,0x75BD,0x72D9,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x8EE5,0x97A0,0xA002,0x759A,0xA002,0x5C31,0x548E,0xA004, 0xA002,0x8205,0x81FC,0xA002,0x820A,0xA002,0x6551,0x5EC4,0xA00A,0xA004,0xA002,0x9152,0x4E5D,0xA002,0x7078,0xA002, 0x4E45,0x97ED,0xA006,0xA002,0x7396,0xA002,0x7EA0,0x7A76,0xA002,0x63EB,0xA002,0x7A98,0x70AF,0xA016,0xA00A,0xA004, 0xA002,0x6DE8,0x7AF6,0xA002,0x7ADF,0xA002,0x9756,0x75D9,0xA006,0xA002,0x5F91,0xA002,0x955C,0x656C,0xA002,0x5883, 0xA002,0x975C,0x9888,0xA00A,0xA004,0xA002,0x666F,0x8B66,0xA002,0x4E95,0xA002,0x7ECF,0x7CB3,0xA006,0xA002,0x7CBE, 0xA002,0x9A5A,0x4EAC,0xA002,0x9CB8,0xA002,0x6676,0x775B,0xA00E,0xA000,0xA000,0xA000,0xA000,0xA004,0xA002,0x8396, 0x5162,0xA002,0x834A,0xA002,0x52C1,0x76E1,0xA001,0xA001,0xA001,0xA001,0xA006,0xA002,0x6D78,0xA002,0x71FC,0x8FD1, 0xA002,0x7981,0xA002,0x664B,0x9773,0xA0B5,0xA0AC,0xA056,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x9032,0x8C28,0xA002, 0x83EB,0xA002,0x9526,0x7DCA,0xA004,0xA002,0x895F,0x6D25,0xA002,0x4ECA,0xA002,0x91D1,0x91FF,0xA00A,0xA004,0xA002, 0x7B4B,0x5DFE,0xA002,0x5C4A,0xA002,0x8BEB,0x75A5,0xA006,0xA002,0x4ECB,0xA002,0x501F,0x754C,0xA002,0x82A5,0xA002, 0x85C9,0x6212,0xA016,0xA00A,0xA004,0xA002,0x601A,0x89E3,0xA002,0x7ED3,0xA002,0x7D5C,0x7AED,0xA006,0xA002,0x776B, 0xA002,0x6377,0x6770,0xA002,0x6854,0xA002,0x8282,0x62BE,0xA00A,0xA004,0xA002,0x622A,0x968E,0xA002,0x8857,0xA002, 0x9782,0x7686,0xA006,0xA002,0x63A5,0xA002,0x63ED,0x7A96,0xA002,0x53EB,0xA002,0x8F83,0x8F7F,0xA02A,0xA014,0xA00A, 0xA004,0xA002,0x9175,0x6559,0xA002,0x52E6,0xA002,0x7EDE,0x7F34,0xA004,0xA002,0x997A,0x89D2,0xA002,0x72E1,0xA002, 0x8173,0x50E5,0xA00A,0xA004,0xA002,0x77EF,0x94F0,0xA002,0x652A,0xA002,0x56BC,0x5B0C,0xA006,0xA002,0x9A84,0xA002, 0x6F86,0x90CA,0xA002,0x4EA4,0xA002,0x81A0,0x7126,0xA016,0xA00A,0xA004,0xA002,0x7901,0x6912,0xA002,0x8549,0xA002, 0x964D,0x91AC,0xA006,0xA002,0x5320,0xA002,0x8BB2,0x734E,0xA002,0x69F3,0xA002,0x8523,0x7586,0xA00A,0xA004,0xA002, 0x6C5F,0x6F3F,0xA002,0x5C07,0xA002,0x8591,0x50F5,0xA006,0xA002,0x5EFA,0xA002,0x6F97,0x6FFA,0xA002,0x6F38,0xA002, 0x996F,0x528D,0xA000,0xA000,0xA000,0xA000,0xA000,0xA002,0x8266,0x5065,0xA016,0xA001,0xA001,0xA001,0xA007,0xA001, 0xA002,0x4EF6,0xA002,0x7BAD,0x952E,0xA006,0xA002,0x89C1,0xA002,0x8D31,0x8E10,0xA002,0x9452,0xA002,0x6ABB,0x85A6, 0xA056,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x6E1B,0x526A,0xA002,0x5109,0xA002,0x7C21,0x64BF,0xA004,0xA002,0x63C0, 0x9E7C,0xA002,0x78B1,0xA002,0x67EC,0x6AA2,0xA00A,0xA004,0xA002,0x8327,0x7F04,0xA002,0x59E6,0xA002,0x8271,0x80A9, 0xA006,0xA002,0x517C,0xA002,0x714E,0x95F4,0xA002,0x7B8B,0xA002,0x5C16,0x5805,0xA016,0xA00A,0xA004,0xA002,0x76E3, 0x6BB2,0xA002,0x5AC1,0xA002,0x9A7E,0x67B6,0xA006,0xA002,0x50F9,0xA002,0x7A3C,0x5047,0xA002,0x94BE,0xA002,0x7532, 0x8D3E,0xA00A,0xA004,0xA002,0x988A,0x83A2,0xA002,0x52A0,0xA002,0x5BB6,0x4F73,0xA006,0xA002,0x593E,0xA002,0x6935, 0x5609,0xA002,0x7EAA,0xA002,0x7EE7,0x5993,0xA02C,0xA016,0xA00A,0xA004,0xA002,0x969B,0x5FCC,0xA002,0x65E2,0xA002, 0x8BB0,0x8BA1,0xA006,0xA002,0x6F03,0xA002,0x5BC4,0x6FDF,0xA002,0x60B8,0xA002,0x5291,0x796D,0xA00A,0xA004,0xA002, 0x4F0E,0x5B63,0xA002,0x5180,0xA002,0x6280,0x858A,0xA006,0xA002,0x5DF1,0xA002,0x810A,0x5E7E,0xA002,0x64E0,0xA002, 0x7EA7,0x5AC9,0xA016,0xA00A,0xA004,0xA002,0x5373,0x6C72,0xA002,0x75BE,0xA002,0x6025,0x53CA,0xA006,0xA002,0x96C6, 0xA002,0x7C4D,0x8F91,0xA002,0x68D8,0xA002,0x6975,0x5409,0xA00A,0xA004,0xA002,0x7F09,0x7EE9,0xA002,0x59EC,0xA002, 0x9E21,0x8BA5,0xA006,0xA002,0x6FC0,0xA002,0x8FF9,0x9965,0xA000,0x808C,0xA1B4,0xA0C6,0xA01F,0xA001,0xA001,0xA001, 0xA006,0xA001,0xA001,0xA001,0xA001,0x7B95,0xA00A,0xA004,0xA002,0x7A4D,0x7A3D,0xA002,0x7578,0xA002,0x6A5F,0x57FA, 0xA006,0xA002,0x573E,0xA002,0x64CA,0x798D,0xA002,0x8D27,0xA002,0x970D,0x60D1,0xA000,0xA056,0xA02A,0xA014,0xA00A, 0xA004,0xA002,0x6216,0x83B7,0xA002,0x706B,0xA002,0x4F19,0x6D3B,0xA004,0xA002,0x8C41,0x6DF7,0xA002,0x6E3E,0xA002, 0x9B42,0x5A5A,0xA00A,0xA004,0xA002,0x660F,0x8477,0xA002,0x7ED8,0xA002,0x8BF2,0x8BB3,0xA006,0xA002,0x6C47,0xA002, 0x71F4,0x6703,0xA002,0x7A62,0xA002,0x8D3F,0x6666,0xA016,0xA00A,0xA004,0xA002,0x60E0,0x5349,0xA002,0x6167,0xA002, 0x6094,0x8B6D,0xA006,0xA002,0x8FF4,0xA002,0x86D4,0x6062,0xA002,0x5FBD,0xA002,0x8F89,0x63EE,0xA00A,0xA004,0xA002, 0x7070,0x8C0E,0xA002,0x604D,0xA002,0x5E4C,0x6643,0xA006,0xA002,0x714C,0xA002,0x60F6,0x51F0,0xA002,0x7687,0xA002, 0x7C27,0x8757,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x78FA,0x9EC4,0xA002,0x614C,0xA002,0x8352,0x5E7B,0xA004,0xA002, 0x5BA7,0x6E19,0xA002,0x7165,0xA002,0x8C62,0x7613,0xA00A,0xA004,0xA002,0x559A,0x60A3,0xA002,0x63DB,0xA002,0x7F13, 0x9084,0xA006,0xA002,0x6853,0xA002,0x74B0,0x6B61,0xA002,0x58DE,0xA002,0x6DEE,0x61F7,0xA016,0xA00A,0xA004,0xA002, 0x5F8A,0x69D0,0xA002,0x8BDD,0xA002,0x5316,0x5283,0xA006,0xA002,0x756B,0xA002,0x6ED1,0x733E,0xA002,0x83EF,0xA002, 0x8B41,0x82B1,0xA00A,0xA004,0xA002,0x6237,0x6EEC,0xA002,0x4E92,0xA002,0x8B77,0x552C,0xA000,0xA002,0x864E,0xA000, 0x5F27,0xA0C3,0xA023,0xA001,0xA001,0xA00B,0xA001,0xA004,0xA001,0xA001,0x6E56,0xA002,0x7CCA,0xA002,0x72D0,0x8774, 0xA00A,0xA004,0xA002,0x9B0D,0x846B,0xA002,0x58FC,0xA002,0x745A,0x5FFD,0xA006,0xA002,0x8656,0xA002,0x547C,0x5F8C, 0xA002,0x5019,0xA002,0x5795,0x5474,0xA056,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x7334,0x4FAF,0xA002,0x5589,0xA002, 0x7EA2,0x5F18,0xA004,0xA002,0x7D18,0x6D2A,0xA002,0x9E3F,0xA002,0x8743,0x70D8,0xA00A,0xA004,0xA002,0x9B28,0x8F70, 0xA002,0x6052,0xA002,0x8861,0x6A6B,0xA006,0xA002,0x4EA8,0xA002,0x54FC,0x6068,0xA002,0x72E0,0xA002,0x5F88,0x75D5, 0xA016,0xA00A,0xA004,0xA002,0x9ED1,0x563F,0xA002,0x8D3A,0xA002,0x9E64,0x8910,0xA006,0xA002,0x8D6B,0xA002,0x6DB8, 0x6CB3,0xA002,0x9602,0xA002,0x8C89,0x76D2,0xA00A,0xA004,0xA002,0x5408,0x4F55,0xA002,0x9FA2,0xA002,0x79BE,0x6838, 0xA006,0xA002,0x83CF,0xA002,0x8377,0x6B31,0xA002,0x5475,0xA002,0x6D69,0x865F,0xA02C,0xA016,0xA00A,0xA004,0xA002, 0x8017,0x597D,0xA002,0x90DD,0xA002,0x6BEB,0x8C6A,0xA006,0xA002,0x568E,0xA002,0x58D5,0x822A,0xA002,0x676D,0xA002, 0x592F,0x6F22,0xA00A,0xA004,0xA002,0x6C57,0x92B2,0xA002,0x608D,0xA002,0x61BE,0x65F1,0xA006,0xA002,0x634D,0xA002, 0x64BC,0x7FF0,0xA002,0x7F55,0xA002,0x558A,0x51FD,0xA016,0xA00A,0xA004,0xA002,0x5BD2,0x6DB5,0xA002,0x5505,0xA002, 0x97E9,0x90AF,0xA006,0xA002,0x61A8,0xA002,0x9163,0x9A87,0xA002,0x5BB3,0xA002,0x4EA5,0x6C26,0xA000,0xA004,0xA002, 0x6D77,0x5B69,0xA000,0x9AB8,0xA001,0xA001,0xA001,0xA012,0xA006,0xA001,0xA001,0xA002,0x54C8,0x904E,0xA006,0xA002, 0x88F9,0xA002,0x679C,0x570B,0xA002,0x90ED,0xA002,0x9505,0x68CD,0xA00A,0xA004,0xA002,0x6EFE,0x8F8A,0xA002,0x528A, 0xA002,0x8D35,0x8DEA,0xA006,0xA002,0x6AC3,0xA002,0x6842,0x7678,0xA002,0x8BE1,0xA002,0x9B3C,0x8F68,0xA159,0xA098, 0xA000,0xA056,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x95FA,0x9F9F,0xA002,0x6B78,0xA002,0x7845,0x73EA,0xA004,0xA002, 0x89C4,0x7470,0xA002,0x901B,0xA002,0x5EE3,0x5149,0xA00A,0xA004,0xA002,0x8D2F,0x704C,0xA002,0x6163,0xA002,0x7F50, 0x9986,0xA006,0xA002,0x7BA1,0xA002,0x89C2,0x51A0,0xA002,0x5B98,0xA002,0x95DC,0x68FA,0xA016,0xA00A,0xA004,0xA002, 0x602A,0x67B4,0xA002,0x4E56,0xA002,0x8902,0x7F63,0xA006,0xA002,0x5BE1,0xA002,0x526E,0x74DC,0xA002,0x98B3,0xA002, 0x96C7,0x56FA,0xA00A,0xA004,0xA002,0x987E,0x6545,0xA002,0x80A1,0xA002,0x8C37,0x9AA8,0xA006,0xA002,0x8831,0xA002, 0x53E4,0x9F13,0xA002,0x59D1,0xA002,0x5B64,0x6CBD,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x4F30,0x7B8D,0xA002,0x5495, 0xA002,0x83C7,0x8F9C,0xA004,0xA002,0x5920,0x8D2D,0xA002,0x69CB,0xA002,0x57A2,0x72D7,0xA00A,0xA004,0xA002,0x830D, 0x6E9D,0xA002,0x52FE,0xA002,0x94A9,0x5171,0xA006,0xA002,0x8D21,0xA002,0x62F1,0x6C5E,0xA002,0x978F,0xA002,0x5F13, 0x5BAE,0xA000,0xA00A,0xA004,0xA002,0x516C,0x8EAC,0xA002,0x4F9B,0xA002,0x9F9A,0x606D,0xA006,0xA002,0x529F,0xA002, 0x653B,0x5DE5,0xA002,0x6897,0xA002,0x803F,0x57C2,0xA02D,0xA001,0xA001,0xA015,0xA009,0xA003,0xA001,0x7FB9,0xA002, 0x5E9A,0xA002,0x66F4,0x8015,0xA006,0xA002,0x8DDF,0xA002,0x6839,0x7ED9,0xA002,0x5404,0xA002,0x7B87,0x94EC,0xA00A, 0xA004,0xA002,0x9694,0x9601,0xA002,0x86E4,0xA002,0x683C,0x845B,0xA006,0xA002,0x9769,0xA002,0x5272,0x7599,0xA002, 0x80F3,0xA002,0x9E3D,0x6208,0xA056,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x64F1,0x6B4C,0xA002,0x54E5,0xA002,0x544A, 0x7A3F,0xA004,0xA002,0x9550,0x641E,0xA002,0x7CD5,0xA002,0x7F94,0x818F,0xA00A,0xA004,0xA002,0x9AD8,0x768B,0xA002, 0x7BD9,0xA002,0x69D3,0x6E2F,0xA006,0xA002,0x5D17,0xA002,0x7EB2,0x809B,0xA002,0x7F38,0xA002,0x94A2,0x525B,0xA016, 0xA00A,0xA004,0xA002,0x5CA1,0x8D63,0xA002,0x6562,0xA002,0x7A08,0x611F,0xA006,0xA002,0x8D95,0xA002,0x809D,0x7AFF, 0xA002,0x67D1,0xA002,0x687F,0x7518,0xA00A,0xA004,0xA002,0x8677,0x6E89,0xA002,0x84CB,0xA002,0x9499,0x6982,0xA006, 0xA002,0x6539,0xA002,0x8BE5,0x560E,0xA002,0x5676,0xA002,0x5490,0x7F1A,0xA02C,0xA016,0xA00A,0xA004,0xA002,0x5A66, 0x9644,0xA002,0x8BA3,0xA002,0x5BCC,0x8D1F,0xA006,0xA002,0x8179,0xA002,0x7236,0x961C,0xA002,0x4ED8,0xA002,0x5085, 0x8907,0xA00A,0xA004,0xA002,0x8D4B,0x8986,0xA002,0x526F,0xA002,0x8D74,0x8150,0xA006,0xA002,0x5E9C,0xA002,0x8151, 0x812F,0xA002,0x65A7,0xA002,0x91DC,0x982B,0xA000,0xA00A,0xA004,0xA002,0x8F85,0x64AB,0xA002,0x752B,0xA002,0x5F17, 0x88B1,0xA000,0xA002,0x8300,0xA002,0x6DAA,0x6D6E,0xA037,0xA001,0xA001,0xA009,0xA001,0xA001,0xA001,0xA002,0x670D, 0xA002,0x4FD8,0x8659,0xA016,0xA00A,0xA004,0xA002,0x7B26,0x6C1F,0xA002,0x5E45,0xA002,0x8F90,0x62C2,0xA006,0xA002, 0x6276,0xA002,0x5B75,0x819A,0xA002,0x6577,0xA002,0x592B,0x5426,0xA00A,0xA004,0xA002,0x5F7F,0x9CF3,0xA002,0x5949, 0xA002,0x8BBD,0x7F1D,0xA006,0xA002,0x99AE,0xA002,0x9022,0x70FD,0xA002,0x760B,0xA002,0x98CE,0x950B,0xA000,0xA056, 0xA02A,0xA014,0xA00A,0xA004,0xA002,0x5CF0,0x8702,0xA002,0x6953,0xA002,0x5C01,0x8C50,0xA004,0xA002,0x7CDE,0x61A4, 0xA002,0x5FFF,0xA002,0x4EFD,0x596E,0xA00A,0xA004,0xA002,0x7C89,0x6C7E,0xA002,0x711A,0xA002,0x58B3,0x7EB7,0xA006, 0xA002,0x5206,0xA002,0x96F0,0x5429,0xA002,0x915A,0xA002,0x82AC,0x8D39,0xA016,0xA00A,0xA004,0xA002,0x6CB8,0x5EE2, 0xA002,0x80BA,0xA002,0x5420,0x8BFD,0xA006,0xA002,0x532A,0xA002,0x80A5,0x98DE,0xA002,0x5561,0xA002,0x975E,0x83F2, 0xA00A,0xA004,0xA002,0x653E,0x7EBA,0xA002,0x8BBF,0xA002,0x9AE3,0x59A8,0xA006,0xA002,0x9632,0xA002,0x623F,0x80AA, 0xA002,0x65B9,0xA002,0x82B3,0x574A,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x6CDB,0x996D,0xA002,0x72AF,0xA002,0x8D29, 0x8303,0xA004,0xA002,0x8FD4,0x53CD,0xA002,0x7169,0xA002,0x51E1,0x7E41,0xA00A,0xA004,0xA002,0x9492,0x792C,0xA002, 0x6A0A,0xA002,0x7FFB,0x756A,0xA006,0xA002,0x5E06,0xA002,0x85E9,0x743A,0xA002,0x6CD5,0xA002,0x9600,0x8982,0xA000, 0xA000,0xA004,0xA002,0x4F10,0x7B4F,0xA002,0x7F70,0xA002,0x9AEE,0x8D30,0xA555,0xA428,0xA249,0xA104,0xA0C2,0xA03B, 0xA001,0xA00E,0xA001,0xA001,0xA006,0xA002,0x4E8C,0xA002,0x6E33,0x9975,0xA002,0x723E,0xA002,0x8033,0x5152,0xA016, 0xA00A,0xA004,0xA002,0x800C,0x6069,0xA002,0x997F,0xA002,0x9102,0x904F,0xA006,0xA002,0x6424,0xA002,0x9628,0x60E1, 0xA002,0x5A25,0xA002,0x8BB9,0x989D,0xA00A,0xA004,0xA002,0x774B,0x9E45,0xA002,0x5CE8,0xA002,0x86FE,0x58AE,0xA006, 0xA002,0x60F0,0xA002,0x5241,0x8235,0xA002,0x8DFA,0xA002,0x6735,0x8EB2,0xA056,0xA02A,0xA014,0xA00A,0xA004,0xA002, 0x579B,0x596A,0xA002,0x591A,0xA002,0x8A83,0x656A,0xA004,0xA002,0x9041,0x76FE,0xA002,0x949D,0xA002,0x56E4,0x987F, 0xA00A,0xA004,0xA002,0x6566,0x8E72,0xA002,0x5678,0xA002,0x58A9,0x5C0D,0xA006,0xA002,0x968A,0xA002,0x5151,0x5806, 0xA002,0x7F0E,0xA002,0x65B7,0x6BB5,0xA016,0xA00A,0xA004,0xA002,0x953B,0x77ED,0xA002,0x7AEF,0xA002,0x5992,0x6E21, 0xA006,0xA002,0x5EA6,0xA002,0x809A,0x9540,0xA002,0x675C,0xA002,0x8D4C,0x7779,0xA00A,0xA004,0xA002,0x5835,0x8BFB, 0xA002,0x7368,0xA002,0x72A2,0x6BD2,0xA006,0xA002,0x7763,0xA002,0x90FD,0x75D8,0xA002,0x9017,0xA002,0x8C46,0x9661, 0xA02A,0xA014,0xA00A,0xA004,0xA002,0x9B25,0x6296,0xA002,0x515C,0xA002,0x6D1E,0x51CD,0xA004,0xA002,0x75CC,0x4F97, 0xA002,0x68DF,0xA002,0x52D5,0x61C2,0xA00A,0xA004,0xA002,0x8463,0x9F15,0xA002,0x6771,0xA002,0x4E22,0x8BA2,0xA006, 0xA002,0x5B9A,0xA002,0x952D,0x9F0E,0xA002,0x9876,0xA002,0x9489,0x53EE,0xA000,0xA000,0xA000,0xA002,0x76EF,0x4E01, 0xA001,0xA001,0xA014,0xA001,0xA007,0xA001,0xA002,0x758A,0xA002,0x8C0D,0x8FED,0xA006,0xA002,0x8776,0xA002,0x789F, 0x7239,0xA002,0x8DCC,0xA002,0x8C03,0x9493,0xA016,0xA00A,0xA004,0xA002,0x5F14,0x6389,0xA002,0x5201,0xA002,0x51CB, 0x9D70,0xA006,0xA002,0x53FC,0xA002,0x7889,0x6BBF,0xA002,0x6FB1,0xA002,0x5960,0x60E6,0xA00A,0xA004,0xA002,0x5E97, 0x7538,0xA002,0x4F43,0xA002,0x96FB,0x588A,0xA006,0xA002,0x975B,0xA002,0x5178,0x9EDE,0xA002,0x7898,0xA002,0x6EC7, 0x6382,0xA081,0xA000,0xA056,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x98A0,0x7F14,0xA002,0x905E,0xA002,0x5F1F,0x5E1D, 0xA004,0xA002,0x7B2C,0x8482,0xA002,0x58AC,0xA002,0x5E95,0x89DD,0xA00A,0xA004,0xA002,0x5AE1,0x7FDF,0xA002,0x6ECC, 0xA002,0x72C4,0x7B1B,0xA006,0xA002,0x6575,0xA002,0x8FEA,0x6EF4,0xA002,0x4F4E,0xA002,0x9684,0x9127,0xA016,0xA00A, 0xA004,0xA002,0x51F3,0x77AA,0xA002,0x7B49,0xA002,0x8C4B,0x71C8,0xA006,0xA002,0x8E6C,0xA002,0x7684,0x6DC2,0xA002, 0x5FB7,0xA002,0x76DC,0x9053,0xA00A,0xA004,0xA002,0x60BC,0x7A3B,0xA002,0x5230,0xA002,0x5C0E,0x79B1,0xA006,0xA002, 0x5CF6,0xA002,0x5012,0x8E48,0xA002,0x6417,0xA002,0x5200,0x6A94,0xA000,0xA014,0xA00A,0xA004,0xA002,0x8569,0x9EE8, 0xA002,0x64CB,0xA002,0x7576,0x86CB,0xA004,0xA002,0x5F48,0x8BDE,0xA002,0x6DE1,0xA002,0x619A,0x4F46,0xA00A,0xA004, 0xA002,0x6C2E,0x65E6,0xA002,0x81BD,0xA002,0x64A3,0x9132,0xA006,0xA002,0x55AE,0xA002,0x4E39,0x64D4,0xA002,0x803D, 0xA000,0x6020,0xA049,0xA001,0xA01C,0xA006,0xA001,0xA001,0xA001,0xA001,0x902E,0xA00A,0xA004,0xA002,0x5F85,0x888B, 0xA002,0x8D37,0xA002,0x4EE3,0x6B86,0xA006,0xA002,0x5E36,0xA002,0x6234,0x50A3,0xA002,0x6B79,0xA002,0x7343,0x5927, 0xA016,0xA00A,0xA004,0xA002,0x6253,0x7629,0xA002,0x8345,0xA002,0x9054,0x642D,0xA006,0xA002,0x9519,0xA002,0x632B, 0x63AA,0xA002,0x6413,0xA002,0x64AE,0x78CB,0xA00A,0xA004,0xA002,0x5BF8,0x5B58,0xA002,0x6751,0xA002,0x7FE0,0x7120, 0xA006,0xA002,0x7CB9,0xA002,0x7601,0x8106,0xA002,0x55FA,0xA002,0x5D14,0x6F3C,0xA056,0xA02A,0xA014,0xA00A,0xA004, 0xA002,0x7AC4,0x7BE1,0xA002,0x8EA5,0xA002,0x4FC3,0x7C07,0xA004,0xA002,0x918B,0x9EA4,0xA002,0x6E4A,0xA002,0x53E2, 0x5F9E,0xA00A,0xA004,0xA002,0x5306,0x56F1,0xA002,0x8525,0xA002,0x8070,0x6B21,0xA006,0xA002,0x8D50,0xA002,0x83BF, 0x6B64,0xA002,0x8BCD,0xA002,0x74F7,0x6148,0xA016,0xA00A,0xA004,0xA002,0x8FAD,0x96CC,0xA002,0x78C1,0xA002,0x8328, 0x75B5,0xA006,0xA002,0x7EF0,0xA002,0x6233,0x8822,0xA002,0x7EAF,0xA002,0x6DF3,0x8123,0xA00A,0xA004,0xA002,0x9187, 0x693F,0xA002,0x6625,0xA002,0x5782,0x9524,0xA006,0xA002,0x6425,0xA002,0x708A,0x5439,0xA002,0x5275,0xA002,0x95EF, 0x5E8A,0xA000,0xA016,0xA00A,0xA004,0xA002,0x5E62,0x7A97,0xA002,0x7621,0xA002,0x4E32,0x5598,0xA006,0xA002,0x8239, 0xA002,0x50B3,0x693D,0xA002,0x7A7F,0xA002,0x5DDD,0x63E3,0xA00A,0xA004,0xA002,0x8655,0x89F8,0xA002,0x6410,0xA002, 0x77D7,0x5132,0xA000,0xA000,0x790E,0xA0C4,0xA04E,0xA001,0xA001,0xA020,0xA00A,0xA001,0xA003,0xA001,0x695A,0xA002, 0x9664,0xA002,0x6EC1,0x96DB,0xA00A,0xA004,0xA002,0x9504,0x8E87,0xA002,0x5EDA,0xA002,0x6AE5,0x9F63,0xA006,0xA002, 0x521D,0xA002,0x81ED,0x919C,0xA002,0x7785,0xA002,0x7EF8,0x4EC7,0xA016,0xA00A,0xA004,0xA002,0x7C4C,0x6101,0xA002, 0x7A20,0xA002,0x8E8A,0x7587,0xA006,0xA002,0x916C,0xA002,0x62BD,0x5BF5,0xA002,0x5D07,0xA002,0x87F2,0x8876,0xA00A, 0xA004,0xA002,0x5145,0x71BE,0xA002,0x65A5,0xA002,0x7FC5,0x8D64,0xA006,0xA002,0x5C3A,0xA002,0x4F88,0x9F7F,0xA002, 0x803B,0xA002,0x9A70,0x5F1B,0xA000,0xA056,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x9072,0x6C60,0xA002,0x5319,0xA002, 0x6301,0x7661,0xA004,0xA002,0x55AB,0x79E4,0xA002,0x9A8B,0xA002,0x901E,0x627F,0xA00A,0xA004,0xA002,0x8BDA,0x6F84, 0xA002,0x61F2,0xA002,0x7A0B,0x4E58,0xA006,0xA002,0x5448,0xA002,0x6210,0x6A59,0xA002,0x57CE,0xA002,0x7A31,0x6491, 0xA016,0xA00A,0xA004,0xA002,0x896F,0x8D81,0xA002,0x9673,0xA002,0x6C89,0x5FF1,0xA006,0xA002,0x6668,0xA002,0x5C18, 0x8FB0,0xA002,0x81E3,0xA002,0x90F4,0x6F88,0xA00A,0xA004,0xA002,0x5FB9,0x63A3,0xA002,0x64A4,0xA002,0x64A6,0x8F66, 0xA006,0xA002,0x7092,0xA002,0x8A2C,0x6A14,0xA002,0x6F6E,0xA002,0x5632,0x671D,0xA000,0xA014,0xA00A,0xA004,0xA002, 0x949E,0x6284,0xA002,0x8D85,0xA002,0x5021,0x5531,0xA004,0xA002,0x7545,0x655E,0xA002,0x5EE0,0xA002,0x8178,0x511F, 0xA000,0xA004,0xA002,0x957F,0x5E38,0xA002,0x5C1D,0xA000,0x5834,0xA0C1,0xA053,0xA001,0xA026,0xA010,0xA006,0xA001, 0xA001,0xA002,0x7316,0x660C,0xA004,0xA002,0x98A4,0x9610,0xA002,0x7522,0xA002,0x94F2,0x7F20,0xA00A,0xA004,0xA002, 0x8C17,0x998B,0xA002,0x87EC,0xA002,0x647B,0x6519,0xA006,0xA002,0x8C7A,0xA002,0x67F4,0x62C6,0xA002,0x8BE7,0xA002, 0x5DEE,0x5C94,0xA016,0xA00A,0xA004,0xA002,0x5BDF,0x643D,0xA002,0x78B4,0xA002,0x67E5,0x8336,0xA006,0xA002,0x832C, 0xA002,0x53C9,0x63D2,0xA002,0x8E6D,0xA002,0x5C64,0x6E2C,0xA00A,0xA004,0xA002,0x518C,0x5E82,0xA002,0x7B74,0xA002, 0x5EC1,0x9A32,0xA006,0xA002,0x66F9,0xA002,0x69FD,0x7CD9,0xA002,0x64CD,0xA002,0x85CF,0x6EC4,0xA056,0xA02A,0xA014, 0xA00A,0xA004,0xA002,0x5009,0x8259,0xA002,0x84BC,0xA002,0x71E6,0x61AF,0xA004,0xA002,0x615A,0x6B98,0xA002,0x8836, 0xA002,0x8460,0x9910,0xA00A,0xA004,0xA002,0x8521,0x83DC,0xA002,0x7DB5,0xA002,0x91C7,0x8E29,0xA006,0xA002,0x776C, 0xA002,0x8D22,0x7E94,0xA002,0x6750,0xA002,0x88C1,0x731C,0xA016,0xA00A,0xA004,0xA002,0x64E6,0x6016,0xA002,0x90E8, 0xA002,0x7C3F,0x6B65,0xA006,0xA002,0x5E03,0xA002,0x4E0D,0x57E0,0xA002,0x88DC,0xA002,0x54FA,0x8514,0xA00A,0xA004, 0xA002,0x6355,0x9A73,0xA002,0x6CCA,0xA002,0x6E24,0x818A,0xA006,0xA002,0x8116,0xA002,0x8236,0x5E1B,0xA002,0x4F2F, 0xA002,0x7B94,0x94C2,0xA000,0xA000,0xA00A,0xA004,0xA002,0x640F,0x52C3,0xA002,0x535A,0xA002,0x6CE2,0x94B5,0xA006, 0xA002,0x64A5,0xA002,0x64AD,0x83E0,0xA002,0x73BB,0xA002,0x5E76,0x75C5,0xA001,0xA001,0xA02C,0xA016,0xA00A,0xA004, 0xA002,0x70B3,0x997C,0xA002,0x79C9,0xA002,0x4E19,0x67C4,0xA006,0xA002,0x51B0,0xA002,0x5175,0x64EF,0xA002,0x8CD3, 0xA002,0x6FF1,0x7015,0xA00A,0xA004,0xA002,0x658C,0x5F6C,0xA002,0x765F,0xA002,0x5F46,0x618B,0xA006,0xA002,0x9CD6, 0xA002,0x9336,0x8198,0xA002,0x5F6A,0xA002,0x6A19,0x904D,0xA016,0xA00A,0xA004,0xA002,0x8FAE,0x8FAF,0xA002,0x8FA8, 0xA002,0x535E,0x8B8A,0xA006,0xA002,0x4FBF,0xA002,0x6241,0x8D2C,0xA002,0x7F16,0xA002,0x908A,0x97AD,0xA00A,0xA004, 0xA002,0x965B,0x907F,0xA002,0x81C2,0xA002,0x58C1,0x95E2,0xA006,0xA002,0x5FC5,0xA002,0x5F0A,0x655D,0xA002,0x95ED, 0xA002,0x75FA,0x5E87,0xA000,0xA000,0xA068,0xA000,0xA056,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x5E63,0x6BD6,0xA002, 0x6BD9,0xA002,0x7562,0x853D,0xA004,0xA002,0x84D6,0x78A7,0xA002,0x5F7C,0xA002,0x7B46,0x9119,0xA00A,0xA004,0xA002, 0x6BD4,0x9F3B,0xA002,0x903C,0xA002,0x8FF8,0x8E66,0xA006,0xA002,0x6CF5,0xA002,0x752D,0x7EF7,0xA002,0x5D29,0xA002, 0x7B28,0x672C,0xA016,0xA00A,0xA004,0xA002,0x82EF,0x5954,0xA002,0x88AB,0xA002,0x7119,0x618A,0xA006,0xA002,0x5907, 0xA002,0x72FD,0x500D,0xA002,0x94A1,0xA002,0x8D1D,0x80CC,0xA00A,0xA004,0xA002,0x8F88,0x5317,0xA002,0x5351,0xA002, 0x60B2,0x7891,0xA006,0xA002,0x76C3,0xA002,0x7206,0x9C8D,0xA002,0x8C79,0xA002,0x66B4,0x62A5,0xA000,0xA000,0xA00A, 0xA004,0xA002,0x62B1,0x5BF6,0xA002,0x9971,0xA002,0x5821,0x4FDD,0xA000,0xA002,0x96F9,0x8584,0xA060,0xA00A,0xA001, 0xA001,0xA001,0xA001,0xA002,0x5265,0xA002,0x8912,0x5305,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x80DE,0x82DE,0xA002, 0x8C24,0xA002,0x508D,0x9551,0xA004,0xA002,0x868C,0x78C5,0xA002,0x68D2,0xA002,0x7ED1,0x8180,0xA00A,0xA004,0xA002, 0x699C,0x6886,0xA002,0x5E6B,0xA002,0x90A6,0x7ECA,0xA006,0xA002,0x8FA6,0xA002,0x534A,0x74E3,0xA002,0x4F34,0xA002, 0x62CC,0x626E,0xA016,0xA00A,0xA004,0xA002,0x7248,0x95C6,0xA002,0x9881,0xA002,0x822C,0x6273,0xA006,0xA002,0x642C, 0xA002,0x73ED,0x6591,0xA002,0x7A17,0xA002,0x62DC,0x8D25,0xA00A,0xA004,0xA002,0x4F70,0x896C,0xA002,0x767E,0xA002, 0x67CF,0x767D,0xA006,0xA002,0x7238,0xA002,0x7F77,0x9738,0xA002,0x58E9,0xA002,0x8019,0x628A,0xA056,0xA02A,0xA014, 0xA00A,0xA004,0xA002,0x9776,0x8DCB,0xA002,0x62D4,0xA002,0x5DF4,0x75A4,0xA004,0xA002,0x516B,0x7B06,0xA002,0x5427, 0xA002,0x53ED,0x6252,0xA00A,0xA004,0xA002,0x634C,0x82AD,0xA002,0x6FB3,0xA002,0x61CA,0x5967,0xA006,0xA002,0x50B2, 0xA002,0x8956,0x7FF1,0xA002,0x71AC,0xA002,0x6556,0x51F9,0xA016,0xA00A,0xA004,0xA002,0x76CE,0x6602,0xA002,0x9AAF, 0xA002,0x6848,0x80FA,0xA006,0xA002,0x5CB8,0xA002,0x6697,0x6309,0xA002,0x4FFA,0xA002,0x5B89,0x6C28,0xA00A,0xA004, 0xA002,0x978D,0x9698,0xA002,0x7231,0xA002,0x7919,0x827E,0xA006,0xA002,0x77EE,0xA002,0x85F9,0x764C,0xA002,0x769A, 0xA002,0x54C0,0x5509,0xA000,0xA000,0xA000,0xA004,0xA002,0x54CE,0x6328,0xA002,0x57C3,0xA002,0x963F,0x554A,0xA1B5, 0xA06D,0xA001,0xA001,0xA001,0xA017,0xA001,0xA001,0xA009,0xA003,0xA001,0x254B,0xA002,0x254A,0xA002,0x2549,0x2548, 0xA006,0xA002,0x2547,0xA002,0x2546,0x2545,0xA002,0x2544,0xA002,0x2543,0x2542,0xA029,0xA015,0xA00A,0xA004,0xA002, 0x2541,0x2540,0xA002,0x253F,0xA002,0x253E,0x253D,0xA005,0xA001,0xA002,0x253B,0x253A,0xA002,0x2539,0xA002,0x2538, 0x2537,0xA009,0xA004,0xA002,0x2536,0x2535,0xA001,0xA002,0x2533,0x2532,0xA006,0xA002,0x2531,0xA002,0x2530,0x252F, 0xA002,0x252E,0xA000,0x252D,0xA015,0xA00A,0xA004,0xA002,0x252B,0x252A,0xA002,0x2529,0xA002,0x2528,0x2527,0xA005, 0xA002,0x2526,0xA000,0x2525,0xA002,0x2523,0xA002,0x2522,0x2521,0xA009,0xA004,0xA002,0x2520,0x251F,0xA002,0x251E, 0xA000,0x251D,0xA006,0xA002,0x251B,0xA002,0x251A,0x2519,0xA002,0x2518,0xA002,0x2517,0x2516,0xA0B7,0xA02D,0xA000, 0xA000,0xA000,0xA014,0xA00A,0xA004,0xA002,0x2515,0x2514,0xA002,0x2513,0xA002,0x2512,0x2511,0xA004,0xA002,0x2510, 0x250F,0xA002,0x250E,0xA002,0x250D,0x250C,0xA00A,0xA004,0xA002,0x250B,0x250A,0xA002,0x2509,0xA002,0x2508,0x2507, 0xA006,0xA002,0x2506,0xA002,0x2505,0x2504,0xA002,0x2503,0xA002,0x2223,0x2501,0xA058,0xA013,0xA001,0xA001,0xA005, 0xA001,0xA001,0xA001,0x3129,0xA006,0xA002,0x3128,0xA002,0x3127,0x3126,0xA002,0x3125,0xA002,0x3124,0x3123,0xA02A, 0xA014,0xA00A,0xA004,0xA002,0x3122,0x3121,0xA002,0x3120,0xA002,0x311F,0x311E,0xA004,0xA002,0x311D,0x311C,0xA002, 0x311B,0xA002,0x311A,0x3119,0xA00A,0xA004,0xA002,0x3118,0x3117,0xA002,0x3116,0xA002,0x3115,0x3114,0xA006,0xA002, 0x3113,0xA002,0x3112,0x3111,0xA002,0x3110,0xA002,0x310F,0x310E,0xA013,0xA00A,0xA004,0xA002,0x310D,0x310C,0xA002, 0x310B,0xA002,0x310A,0x3109,0xA006,0xA002,0x3108,0xA002,0x3107,0x3106,0xA000,0x3105,0xA001,0xA001,0xA002,0x00EA, 0xA002,0x00FC,0x01DC,0xA000,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x01DA,0x01D8,0xA002,0x01D6,0xA002,0x00F9,0x01D4, 0xA004,0xA002,0x00FA,0x016B,0xA002,0x00F2,0xA002,0x01D2,0x00F3,0xA00A,0xA004,0xA002,0x014D,0x00EC,0xA002,0x01D0, 0xA002,0x00ED,0x012B,0xA006,0xA002,0x00E8,0xA002,0x011B,0x00E9,0xA002,0x0113,0xA002,0x00E0,0x01CE,0xA000,0xA000, 0xA000,0xA002,0x00E1,0x0101,0xA067,0xA001,0xA028,0xA001,0xA011,0xA005,0xA001,0xA001,0xA001,0x044F,0xA006,0xA002, 0x044E,0xA002,0x044D,0x044C,0xA002,0x044B,0xA002,0x044A,0x0449,0xA00A,0xA004,0xA002,0x0448,0x0447,0xA002,0x0446, 0xA002,0x0445,0x0444,0xA006,0xA002,0x0443,0xA002,0x0442,0x0441,0xA002,0x0440,0xA002,0x043F,0x043E,0xA020,0xA016, 0xA00A,0xA004,0xA002,0x043D,0x043C,0xA002,0x043B,0xA002,0x043A,0x0439,0xA006,0xA002,0x0438,0xA002,0x0437,0x0436, 0xA002,0x0451,0xA002,0x0435,0x0434,0xA000,0xA004,0xA002,0x0433,0x0432,0xA002,0x0431,0xA000,0x0430,0xA008,0xA001, 0xA001,0xA002,0x042F,0xA002,0x042E,0x042D,0xA00A,0xA004,0xA002,0x042C,0x042B,0xA002,0x042A,0xA002,0x0429,0x0428, 0xA006,0xA002,0x0427,0xA002,0x0426,0x0425,0xA002,0x0424,0xA002,0x0423,0x0422,0xA000,0xA000,0xA000,0xA014,0xA00A, 0xA004,0xA002,0x0421,0x0420,0xA002,0x041F,0xA002,0x041E,0x041D,0xA004,0xA002,0x041C,0x041B,0xA002,0x041A,0xA002, 0x0419,0x0418,0xA00A,0xA004,0xA002,0x0417,0x0416,0xA002,0x0401,0xA002,0x0415,0x0414,0xA006,0xA002,0x0413,0xA002, 0x0412,0x0411,0xA000,0x0410,0xA1CA,0xA0FF,0xA068,0xA046,0xA001,0xA026,0xA010,0xA006,0xA001,0xA001,0xA002,0x03C9, 0x03C8,0xA004,0xA002,0x03C7,0x03C6,0xA002,0x03C5,0xA002,0x03C4,0x03C3,0xA00A,0xA004,0xA002,0x03C1,0x03C0,0xA002, 0x03BF,0xA002,0x03BE,0x03BD,0xA006,0xA002,0x03BC,0xA002,0x03BB,0x03BA,0xA002,0x03B9,0xA002,0x03B8,0x03B7,0xA00E, 0xA00A,0xA004,0xA002,0x03B6,0x03B5,0xA002,0x03B4,0xA002,0x03B3,0x03B2,0xA000,0xA000,0x03B1,0xA006,0xA001,0xA001, 0xA002,0x03A9,0x03A8,0xA006,0xA002,0x03A7,0xA002,0x03A6,0x03A5,0xA002,0x03A4,0xA001,0x03A1,0xA000,0xA000,0xA012, 0xA009,0xA003,0xA001,0x039F,0xA002,0x039E,0xA002,0x039D,0x039C,0xA003,0xA001,0x039A,0xA002,0x0399,0xA002,0x0398, 0x0397,0xA00A,0xA004,0xA002,0x0396,0x0395,0xA002,0x0394,0xA002,0x0393,0x0392,0xA000,0xA000,0x0391,0xA001,0xA03E, 0xA012,0xA001,0xA005,0xA001,0xA001,0xA001,0x30F6,0xA006,0xA002,0x30F5,0xA002,0x30F4,0x30F3,0xA002,0x30F2,0xA002, 0x30F1,0x30F0,0xA016,0xA00A,0xA004,0xA002,0x30EF,0x30EE,0xA002,0x30ED,0xA002,0x30EC,0x30EB,0xA006,0xA002,0x30EA, 0xA002,0x30E9,0x30E8,0xA002,0x30E7,0xA002,0x30E6,0x30E5,0xA00A,0xA004,0xA002,0x30E4,0x30E3,0xA002,0x30E2,0xA002, 0x30E1,0x30E0,0xA006,0xA002,0x30DF,0xA002,0x30DE,0x30DD,0xA002,0x30DC,0xA002,0x30DB,0x30DA,0xA02C,0xA016,0xA00A, 0xA004,0xA002,0x30D9,0x30D8,0xA002,0x30D7,0xA002,0x30D6,0x30D5,0xA006,0xA002,0x30D4,0xA002,0x30D3,0x30D2,0xA002, 0x30D1,0xA002,0x30D0,0x30CF,0xA00A,0xA004,0xA002,0x30CE,0x30CD,0xA002,0x30CC,0xA002,0x30CB,0x30CA,0xA006,0xA002, 0x30C9,0xA002,0x30C8,0x30C7,0xA002,0x30C6,0xA002,0x30C5,0x30C4,0xA016,0xA00A,0xA004,0xA002,0x30C3,0x30C2,0xA002, 0x30C1,0xA002,0x30C0,0x30BF,0xA006,0xA002,0x30BE,0xA002,0x30BD,0x30BC,0xA002,0x30BB,0xA002,0x30BA,0x30B9,0xA00A, 0xA004,0xA002,0x30B8,0x30B7,0xA002,0x30B6,0xA002,0x30B5,0x30B4,0xA006,0xA002,0x30B3,0xA002,0x30B2,0x30B1,0xA002, 0x30B0,0xA002,0x30AF,0x30AE,0xA01F,0xA000,0xA000,0xA000,0xA014,0xA00A,0xA004,0xA002,0x30AD,0x30AC,0xA002,0x30AB, 0xA002,0x30AA,0x30A9,0xA004,0xA002,0x30A8,0x30A7,0xA002,0x30A6,0xA002,0x30A5,0x30A4,0xA000,0xA004,0xA002,0x30A3, 0x30A2,0xA000,0x30A1,0xA095,0xA03F,0xA013,0xA001,0xA006,0xA001,0xA001,0xA002,0x3093,0x3092,0xA006,0xA002,0x3091, 0xA002,0x3090,0x308F,0xA002,0x308E,0xA002,0x308D,0x308C,0xA016,0xA00A,0xA004,0xA002,0x308B,0x308A,0xA002,0x3089, 0xA002,0x3088,0x3087,0xA006,0xA002,0x3086,0xA002,0x3085,0x3084,0xA002,0x3083,0xA002,0x3082,0x3081,0xA00A,0xA004, 0xA002,0x3080,0x307F,0xA002,0x307E,0xA002,0x307D,0x307C,0xA006,0xA002,0x307B,0xA002,0x307A,0x3079,0xA002,0x3078, 0xA002,0x3077,0x3076,0xA02A,0xA014,0xA00A,0xA004,0xA002,0x3075,0x3074,0xA002,0x3073,0xA002,0x3072,0x3071,0xA004, 0xA002,0x3070,0x306F,0xA002,0x306E,0xA002,0x306D,0x306C,0xA00A,0xA004,0xA002,0x306B,0x306A,0xA002,0x3069,0xA002, 0x3068,0x3067,0xA006,0xA002,0x3066,0xA002,0x3065,0x3064,0xA002,0x3063,0xA002,0x3062,0x3061,0xA016,0xA00A,0xA004, 0xA002,0x3060,0x305F,0xA002,0x305E,0xA002,0x305D,0x305C,0xA006,0xA002,0x305B,0xA002,0x305A,0x3059,0xA002,0x3058, 0xA002,0x3057,0x3056,0xA00A,0xA004,0xA002,0x3055,0x3054,0xA002,0x3053,0xA002,0x3052,0x3051,0xA006,0xA002,0x3050, 0xA002,0x304F,0x304E,0xA002,0x304D,0xA002,0x304C,0x304B,0xA000,0xA000,0xA000,0xA00A,0xA004,0xA002,0x304A,0x3049, 0xA002,0x3048,0xA002,0x3047,0x3046,0xA004,0xA002,0x3045,0x3044,0xA002,0x3043,0xA002,0x3042,0x3041,0xA0CF,0xA0B3, 0xA009,0xA001,0xA001,0xA001,0xA001,0xA001,0xA001,0xA001,0xFFE3,0xA056,0xA02A,0xA014,0xA00A,0xA004,0xA002,0xFF5D, 0xFF5C,0xA002,0xFF5B,0xA002,0xFF5A,0xFF59,0xA004,0xA002,0xFF58,0xFF57,0xA002,0xFF56,0xA002,0xFF55,0xFF54,0xA00A, 0xA004,0xA002,0xFF53,0xFF52,0xA002,0xFF51,0xA002,0xFF50,0xFF4F,0xA006,0xA002,0xFF4E,0xA002,0xFF4D,0xFF4C,0xA002, 0xFF4B,0xA002,0xFF4A,0xFF49,0xA016,0xA00A,0xA004,0xA002,0xFF48,0xFF47,0xA002,0xFF46,0xA002,0xFF45,0xFF44,0xA006, 0xA002,0xFF43,0xA002,0xFF42,0xFF41,0xA002,0xFF40,0xA002,0xFF3F,0xFF3E,0xA00A,0xA004,0xA002,0xFF3D,0xFF3C,0xA002, 0xFF3B,0xA002,0xFF3A,0xFF39,0xA006,0xA002,0xFF38,0xA002,0xFF37,0xFF36,0xA002,0xFF35,0xA002,0xFF34,0xFF33,0xA02A, 0xA014,0xA00A,0xA004,0xA002,0xFF32,0xFF31,0xA002,0xFF30,0xA002,0xFF2F,0xFF2E,0xA004,0xA002,0xFF2D,0xFF2C,0xA002, 0xFF2B,0xA002,0xFF2A,0xFF29,0xA00A,0xA004,0xA002,0xFF28,0xFF27,0xA002,0xFF26,0xA002,0xFF25,0xFF24,0xA006,0xA002, 0xFF23,0xA002,0xFF22,0xFF21,0xA002,0xFF20,0xA002,0xFF1F,0xFF1E,0xA015,0xA009,0xA004,0xA002,0xFF1D,0xFF1C,0xA002, 0xFF1B,0xA001,0xFF19,0xA006,0xA002,0xFF18,0xA002,0xFF17,0xFF16,0xA002,0xFF15,0xA002,0xFF14,0xFF13,0xA00A,0xA004, 0xA002,0xFF12,0xFF11,0xA002,0xFF10,0xA002,0xFF0F,0xFF0E,0xA005,0xA001,0xA002,0xFF0C,0xFF0B,0xA002,0xFF0A,0xA002, 0xFF09,0xFF08,0xA012,0xA000,0xA000,0xA000,0xA00A,0xA004,0xA002,0xFF07,0xFF06,0xA002,0xFF05,0xA002,0xFFE5,0xFF03, 0xA000,0xA002,0xFF02,0xFF01,0xA001,0xA001,0xA001,0xA001,0xA001,0xA001,0xA002,0x216B,0x216A,0xA092,0xA000,0xA051, 0xA027,0xA014,0xA00A,0xA004,0xA002,0x2169,0x2168,0xA002,0x2167,0xA002,0x2166,0x2165,0xA004,0xA002,0x2164,0x2163, 0xA002,0x2162,0xA002,0x2161,0x2160,0xA007,0xA001,0xA002,0x3229,0xA002,0x3228,0x3227,0xA006,0xA002,0x3226,0xA002, 0x3225,0x3224,0xA002,0x3223,0xA002,0x3222,0x3221,0xA014,0xA008,0xA003,0xA000,0x3220,0xA001,0xA002,0x2469,0x2468, 0xA006,0xA002,0x2467,0xA002,0x2466,0x2465,0xA002,0x2464,0xA002,0x2463,0x2462,0xA00A,0xA004,0xA002,0x2461,0x2460, 0xA002,0x2487,0xA002,0x2486,0x2485,0xA006,0xA002,0x2484,0xA002,0x2483,0x2482,0xA002,0x2481,0xA002,0x2480,0x247F, 0xA02A,0xA014,0xA00A,0xA004,0xA002,0x247E,0x247D,0xA002,0x247C,0xA002,0x247B,0x247A,0xA004,0xA002,0x2479,0x2478, 0xA002,0x2477,0xA002,0x2476,0x2475,0xA00A,0xA004,0xA002,0x2474,0x249B,0xA002,0x249A,0xA002,0x2499,0x2498,0xA006, 0xA002,0x2497,0xA002,0x2496,0x2495,0xA002,0x2494,0xA002,0x2493,0x2492,0xA000,0xA00A,0xA004,0xA002,0x2491,0x2490, 0xA002,0x248F,0xA002,0x248E,0x248D,0xA006,0xA002,0x248C,0xA002,0x248B,0x248A,0xA002,0x2489,0xA000,0x2488,0xA014, 0xA001,0xA001,0xA001,0xA005,0xA001,0xA001,0xA001,0x3013,0xA006,0xA002,0x2193,0xA002,0x2191,0x2190,0xA002,0x2192, 0xA002,0x203B,0x25B2,0xA054,0xA029,0xA013,0xA009,0xA004,0xA002,0x25B3,0x25A0,0xA001,0xA002,0x25C6,0x25C7,0xA004, 0xA002,0x25CE,0x25CF,0xA002,0x25CB,0xA002,0x2605,0x2606,0xA00A,0xA004,0xA002,0x2116,0x00A7,0xA002,0x2030,0xA002, 0xFFE1,0xFFE0,0xA006,0xA002,0x00A4,0xA002,0xFF04,0x2103,0xA002,0x301E,0xA002,0x2032,0x00B0,0xA016,0xA00A,0xA004, 0xA002,0x2640,0x2642,0xA002,0x2234,0xA002,0x2235,0x221E,0xA006,0xA002,0x2267,0xA002,0x2266,0x226F,0xA002,0x226E, 0xA002,0x2260,0x221D,0xA00A,0xA004,0xA002,0x223D,0x2248,0xA002,0x2252,0xA002,0x2261,0x222E,0xA006,0xA002,0x222B, 0xA002,0x2609,0x2312,0xA002,0x2220,0xA001,0x22A5,0xA02C,0xA016,0xA00A,0xA004,0xA002,0x221A,0x2237,0xA002,0x2208, 0xA002,0x2229,0x222A,0xA006,0xA002,0x220F,0xA002,0x2211,0x2228,0xA002,0x2227,0xA002,0xFF1A,0x00F7,0xA00A,0xA004, 0xA002,0x00D7,0x00B1,0xA002,0x3011,0xA002,0x3010,0x3017,0xA006,0xA002,0x3016,0xA002,0x300F,0x300E,0xA002,0x300D, 0xA002,0x300C,0x300B,0xA016,0xA00A,0xA004,0xA002,0x300A,0x3009,0xA002,0x3008,0xA002,0x3015,0x3014,0xA006,0xA002, 0x201D,0xA002,0x201C,0x2019,0xA002,0x2018,0xA002,0x2026,0x2225,0xA00A,0xA004,0xA002,0xFF5E,0xFF0D,0xA002,0x3005, 0xA002,0x3003,0x2025,0xA006,0xA002,0x02C7,0xA002,0x02C9,0x30FB,0xA002,0x3002,0xA002,0x3001,0x3000, }; // gb2312_to_ucs2_elements const TConvFlatTree gb2312_to_ucs2 = { 0xA1A1, // min key 0xF7FE, // max key 0xA000, // links space start 0xEFFF, // links space end gb2312_to_ucs2_numelems, // number of elements (treeval_t *)&gb2312_to_ucs2_elements // elements }; // gb2312_to_ucs2 libsynthesis-3.4.0.47.1/src/sysync_SDK/Sources/generic_types.h000077500000000000000000000077461226375725500241410ustar00rootroot00000000000000/* generic types to avoid int size dependencies */ /* ============================================ */ /* NOTE: this file is part of the mod_sysync source files. */ /* NOTE: As this file should work for all kind of plain C compilers * comments with double slashes "//" must be avoided !! */ #ifndef GENERIC_TYPES_H #define GENERIC_TYPES_H #ifdef HAVE_CONFIG_H # include #endif #if defined(HAVE_STDINT_H) # include #endif #ifndef __WORDSIZE /* 64 platforms should have this defined, so assume that */ /* platforms without the define are 32 bit. */ # define __WORDSIZE 32 #endif #ifdef __cplusplus namespace sysync { #endif #if defined(HAVE_STDINT_H) typedef uint64_t uInt64; typedef int64_t sInt64; typedef uint32_t uInt32; typedef int32_t sInt32; typedef uint16_t uInt16; typedef int16_t sInt16; typedef uint8_t uInt8; typedef int8_t sInt8; typedef uintptr_t uIntPtr; typedef intptr_t sIntPtr; typedef uintptr_t bufferIndex; /* index into app buffers (small platforms may have 16bit here) */ typedef uintptr_t stringIndex; /* index into string (small platforms may have 16bit here) */ typedef uintptr_t stringSize; /* size of a string object */ typedef uintptr_t memSize; /* size of a memory buffer */ #else /* defined size types */ /* - integers */ #ifdef _MSC_VER typedef unsigned __int64 uInt64; typedef signed __int64 sInt64; #else typedef unsigned long long uInt64; typedef signed long long sInt64; #endif /* machine size integer, at least 32 bits */ typedef unsigned long uIntArch; typedef signed long sIntArch; /* TODO, FIXME %%%% for now, we need uInt32 to be 64bit actually */ /*#define UINT32_HAS_64BITS_ON_ARCH64 1 */ #if defined(UINT32_HAS_64BITS_ON_ARCH64) || defined(__PALM_OS__) || (__WORDSIZE < 32) /* must use long to get a 32bit int (but gets 64bit in 64-bit architectures) */ typedef unsigned long uInt32; typedef signed long sInt32; #ifdef UINT32_HAS_64BITS_ON_ARCH64 #warning "%%% UINT32_HAS_64BITS_ON_ARCH64 - which means that uInt32 is really 64bit: UGLY & DANGEROUS, please be careful" #endif #else /* according to the ILP32/LP64 std for all other platforms, int is 32bit (and long is 64bit) */ typedef unsigned int uInt32; typedef signed int sInt32; #endif typedef unsigned short uInt16; typedef signed short sInt16; typedef unsigned char uInt8; typedef signed char sInt8; #if __WORDSIZE == 64 typedef unsigned long long uIntPtr; typedef signed long long sIntPtr; #else typedef unsigned long uIntPtr; typedef signed long sIntPtr; #endif /* - application integers */ typedef uIntArch bufferIndex; /* index into app buffers (small platforms may have 16bit here) */ typedef uIntArch stringIndex; /* index into string (small platforms may have 16bit here) */ typedef uIntArch stringSize; /* size of a string object */ typedef uIntArch memSize; /* size of a memory buffer */ #endif /* HAVE_STDINT_H */ /* undefined size types */ /* - application chars & pointers */ typedef char appChar; typedef char *appCharP; typedef const char *cAppCharP; /* - application bool */ #ifdef __cplusplus typedef bool appBool; /* Just define application-specific true and false constants */ #define appFalse false #define appTrue true #else /* we have no appBool in C, as C++/C mixture could cause bad */ /* surprises if types were differently defined in C and C++ */ /* Just define application-specific true and false constants */ #define appFalse 0 #define appTrue 1 #endif /* - application pointers */ typedef void * appPointer; typedef const void * cAppPointer; /* - bytes, byte pointers */ /* Note: gcc does not like using "typedef uInt8 *UInt8P" for some strange reason */ typedef uInt8 *uInt8P; typedef const uInt8 *cUInt8P; /* - Context/Version variables */ typedef struct ContextType *CContext; typedef unsigned long CVersion; /* - ssize_t is not predefined for Windows CW or EVC */ #if defined _WIN32 && (!defined _MSC_VER || defined WINCE) typedef sInt32 ssize_t; #endif #ifdef __cplusplus } // namespace #endif #endif /* GENERIC_TYPES_H */ /* eof */ libsynthesis-3.4.0.47.1/src/sysync_SDK/Sources/lineartime.cpp000077500000000000000000000263141226375725500237550ustar00rootroot00000000000000/* * File: lineartime.c * * Author: Lukas Zeller (luz@plan44.ch) * * conversion from/to linear time scale. * * Copyright (c) 2002-2011 by Synthesis AG + plan44.ch * * 2002-04-14 : luz : created from pascal source (plani.ch) * */ #include "prefix_file.h" #include "sync_include.h" #include "lineartime.h" #include "timezones.h" #if defined(SYSYNC_TOOL) #include "syncappbase.h" // for CONSOLEPRINTF #include "vtimezone.h" // for CONSOLEPRINTF #endif namespace sysync { // Support for SySync Diagnostic Tool #ifdef SYSYNC_TOOL // convert between different time formats and zones int timeConv(int argc, const char *argv[]) { if (argc<0) { // help requested CONSOLEPRINTF((" time []")); CONSOLEPRINTF((" Convert between time zone representations:")); CONSOLEPRINTF((" special input zone names: ")); CONSOLEPRINTF((" - \"now\" : input is current system time (no required)")); CONSOLEPRINTF((" - \"floating\" : floating time (when no zone from ISO8601 input")); CONSOLEPRINTF((" - \"vtimezone\" : output zone as VTIMEZONE")); return EXIT_SUCCESS; } // check for argument if (argc<2 || argc>3) { CONSOLEPRINTF(("2 or 3 arguments required")); return EXIT_FAILURE; } // mode string inzone,outzone,s,z; // internal representation lineartime_t intime; sInt16 minOffs; timecontext_t incontext,outcontext; GZones zones; // get input mode inzone=argv[0]; outzone=argv[1]; // check special "now" case if (strucmp(inzone.c_str(),"now")==0) { // input time is current time in system zone incontext = TCTX_SYSTEM; intime = getSystemNowAs(incontext,&zones); } else { // get input context from name (internal or olson) if (!TimeZoneNameToContext(inzone.c_str(),incontext,&zones, true)) incontext=TCTX_UNKNOWN; // input time from 3rd argument if (argc!=3) { CONSOLEPRINTF(("input time required as 3rd argument")); return EXIT_FAILURE; } // try to parse as ISO8601 timecontext_t inpctx; uInt16 n=ISO8601StrToTimestamp(argv[2],intime,inpctx); if (n==0 || argv[2][n]!=0) { // no ISO, read as lineartime inpctx=TCTX_UNKNOWN; n=StrToLongLong(argv[2],intime); if (n==0) { CONSOLEPRINTF(("input time must be either ISO8601 or decimal lineartime units")); return EXIT_FAILURE; } } if (!TCTX_IS_UNKNOWN(inpctx)) incontext=inpctx; } // get output context if (strucmp(outzone.c_str(),"vtimezone")==0) { // show input time zone as VTIMEZONE and DAYLIGHT (for current date) intime = getSystemNowAs(incontext,&zones); internalToVTIMEZONE(incontext,z,&zones); CONSOLEPRINTF(("Input time zone represented as VTIMEZONE :\n\nBEGIN:VTIMEZONE\n%sEND:VTIMEZONE\n",z.c_str())); timecontext_t stdoffs; ContextToTzDaylight(incontext,intime,z,stdoffs,&zones); s.erase(); ContextToISO8601StrAppend(s, stdoffs, true); CONSOLEPRINTF(("Input time zone represented as TZ/DAYLIGHT :\n\nTZ:%s\nDAYLIGHT:%s\n",s.c_str(),z.c_str())); } else if (!TimeZoneNameToContext(outzone.c_str(),outcontext,&zones, true)) outcontext=TCTX_UNKNOWN; // now show CONSOLEPRINTF(("")); // - input TimestampToISO8601Str(s, intime, incontext, true, true); TimeZoneContextToName(incontext, z, &zones); TzResolveToOffset(incontext, minOffs, intime, false, &zones); CONSOLEPRINTF(("Input : %-25s (%+03hd:%02hd - '%s')", s.c_str(), minOffs/MinsPerHour, abs(minOffs)%MinsPerHour, z.c_str())); // - convert to output if (!TzConvertTimestamp(intime,incontext,outcontext,&zones)) { CONSOLEPRINTF(("input zone cannot be converted to output zone")); return EXIT_FAILURE; } else { // - input TimestampToISO8601Str(s, intime, outcontext, true, true); TimeZoneContextToName(outcontext, z, &zones); TzResolveToOffset(outcontext, minOffs, intime, false, &zones); CONSOLEPRINTF(("Output : %-25s (%+03hd:%02hd - '%s')", s.c_str(), minOffs/MinsPerHour, abs(minOffs)%MinsPerHour, z.c_str())); } return EXIT_SUCCESS; } // timeConv #endif // SYSYNC_TOOL #ifndef PLATFORM_LROUND // use generic implementation of lround static sInt32 lround(double x) { sInt32 l; l=(sInt32)(x+0.5); return l; } #endif #ifndef PLATFORM_TRUNC // use generic implementation of trunc static double trunc(double x) { sInt64 ll; ll=(sInt64)(x); return (double)ll; } #endif #ifndef PLATFORM_DATE2LINEARDATE // helper: Returns the biggest integer smaller than x static sInt32 lfloor(double x) { #if ( defined __MACH__ && defined __GNUC__ ) || defined _MSC_VER // XCode or Visual Studio if (x<0) x= x-1; return lround( x-0.5 ); #else return (sInt32)floor( x ); #endif } // lfloor // convert date to linear date (generic version using our internal scale) /* procedure calcEphTime(year:integer;month,day:byte;hour:single;var julDat:double); { Berechnet Julianisches Datum aus Weltzeit } */ lineardate_t date2lineardate(sInt16 aYear, sInt16 aMonth, sInt16 aDay) { // use custom algorithm that goes back to year -4712... /* const MinYear= -4712; */ const sInt32 MinYear = -4712; /* var a,b:integer; */ sInt32 a,b; /* if aMonth<3 then begin year:=year-1; aMonth:=aMonth+12; end; */ if (aMonth<3) { aYear--; aMonth+=12; } /* if (aYear<1582) or ((aYear=1582) and (aMonth<10)) or ((aYear=1582) and (aMonth=10) and (aDay<15)) */ if ( aYear<1582 || (aYear==1582 && aMonth<10) || (aYear==1582 && aMonth==10 && aDay<15) ) { // julian /* then b:=0 { julianisch } */ b=0; } else { // gregorian /* else begin a:=floor(aYear/100); b:=2-a+floor(a/4) end; { gregorianisch } */ a=lfloor(aYear/100); b=2-a+lfloor(a/4); } // now calc julian date /*JulDat:=floor(365.25*(aYear-minYear)+1E-6)+round(30.6*(aMonth-3))+aDay+b+58.5; JulDat:=JulDat+hour/24; */ return( (lfloor(365.25*(aYear-MinYear)+1E-6)+lround(30.6*(aMonth-3))+aDay+b+59) - linearDateOriginOffset // apply offset used for this target platform ); } // date2lineardate #endif // PLATFORM_DATE2LINEARDATE // convert date to linear time lineartime_t date2lineartime(sInt16 aYear, sInt16 aMonth, sInt16 aDay) { return date2lineardate(aYear,aMonth,aDay) * linearDateToTimeFactor; } // date2lineartime // convert time to linear time lineartime_t time2lineartime(sInt16 aHour, sInt16 aMinute, sInt16 aSecond, sInt16 aMS) { lineartime_t ti = ((((lineartime_t)aHour)*60 + (lineartime_t)aMinute)*60 + (lineartime_t)aSecond)*secondToLinearTimeFactor; if (secondToLinearTimeFactor==1000) ti+=aMS; return ti; } // time2lineartime // convert lineardate to weekday // 0=sunday, 1=monday ... 6=saturday sInt16 lineardate2weekday(lineardate_t aLinearDate) { return (aLinearDate+linearDateOriginWeekday) % 7; } // lineardate2weekday // convert lineartime to weekday // 0=sunday, 1=monday ... 6=saturday sInt16 lineartime2weekday(lineartime_t aLinearTime) { // juldat seems to be sunday-based :-) return lineardate2weekday(aLinearTime / linearDateToTimeFactor); } // lineardate2weekday // get number of days in a month sInt16 getMonthDays(lineardate_t aLinearDate) { sInt16 y,m,d; lineardate_t ld; // get year and month of given date lineardate2date(aLinearDate,&y,&m,&d); // get first of this month ld = date2lineardate(y,m,1); // calculate next month m++; if (m>12) { m=1; y++; } // return difference between 1st of current and 1st of next month = number of days in month return date2lineardate(y,m,1) - ld; } // getMonthDays #ifndef PLATFORM_LINEARDATE2DATE // convert lineardate to year/month/day /* procedure calcDat(zeitZone,julDat:double;var year:integer;var month,day,hour,min:byte;var sec:single); { Berechnet das Kalenderdatum und Weltzeit aus Julianischem Datum } */ void lineardate2date(lineardate_t aLinearDate,sInt16 *aYearP, sInt16 *aMonthP, sInt16 *aDayP) { // custom algorithm /* var JD0,JD,C,E:double; B,D,F:integer; hh:single; */ double C,E; sInt32 B,D,F; // apply offset correction aLinearDate+=linearDateOriginOffset; // no time, no "correction" for date change at noon /* JD:=julDat+zeitZone/24; JD0:=sInt32(Jd+0.5); */ /* if JD0<2299161 then begin B:=0; C:=JD0+1524; end else begin B:=trunc((JD0-1867216.25)/36524.25); C:=Jd0+(B-trunc(B/4))+1525.0; end; */ if (aLinearDate<2299161) { B=0; C=aLinearDate+1524; } else { B=(sInt32)(trunc((aLinearDate-1867216.25)/36524.25)); C=aLinearDate+(B-trunc((double)B/4))+1525.0; } /* D:=trunc((C-122.1)/365.25); E:=365.0*D+trunc(D/4); F:=trunc((C-E)/30.6001); day:=trunc(C-E+0.5)-trunc(30.6001*F); month:=F-1-12*trunc(F/14); year:=D-4715-trunc((7+month)/10); */ D=(sInt32)(trunc((C-122.1)/365.25)); E=365.0*D+trunc((double)D/4); F=(sInt32)(trunc((C-E)/30.6001)); // return date sInt16 month = (sInt16)(F-1-12*trunc((double)F/14)); if (aDayP) *aDayP=(sInt16)(trunc(C-E+0.5)-trunc(30.6001*F)); if (aMonthP) *aMonthP=month; if (aYearP) *aYearP=(sInt16)(D-4715-trunc((double)(7+month)/10.0)); // no time /* hh:=24*(JD+0.5-JD0); hour:=trunc(hh); hh:=(hh-hour)*60; min:=trunc(hh); hh:=(hh-min)*60; sec:=trunc(hh); */ } // lineardate2date #endif // PLATFORM_LINEARDATE2DATE // convert lineartime to year/month/day void lineartime2date(lineartime_t aLinearTime, sInt16 *aYearP, sInt16 *aMonthP, sInt16 *aDayP) { lineardate2date(lineartime2dateonly(aLinearTime), aYearP, aMonthP, aDayP); } // lineartime2date // convert lineartime to h,m,s,ms void lineartime2time(lineartime_t aLinearTime, sInt16 *aHourP, sInt16 *aMinP, sInt16 *aSecP, sInt16 *aMSP) { if (aLinearTime<0) { // negative time, create wrap around to make sure time remains positive aLinearTime = lineartime2timeonly(aLinearTime); } if (secondToLinearTimeFactor==1) { // no sub-seconds if (aMSP) *aMSP = 0; } else { // we have sub-seconds if (aMSP) *aMSP = aLinearTime % secondToLinearTimeFactor; aLinearTime /= secondToLinearTimeFactor; } if (aSecP) *aSecP = aLinearTime % 60; aLinearTime /= 60; if (aMinP) *aMinP = aLinearTime % 60; aLinearTime /= 60; if (aHourP) *aHourP = aLinearTime % 24; // to make sure we don't convert date part } // lineartime2time // convert seconds to linear time lineartime_t seconds2lineartime(sInt32 aSeconds) { return aSeconds*secondToLinearTimeFactor; } // seconds2lineartime // convert linear time to seconds sInt32 lineartime2seconds(lineartime_t aLinearTime) { return aLinearTime/secondToLinearTimeFactor; } // lineartime2seconds // get time-only part of a linear time lineartime_t lineartime2timeonly(lineartime_t aLinearTime) { //return aLinearTime % linearDateToTimeFactor; return aLinearTime-lineartime2dateonlyTime(aLinearTime); } // lineartime2timeonly // get date-only part of a linear time lineardate_t lineartime2dateonly(lineartime_t aLinearTime) { return aLinearTime/linearDateToTimeFactor - (aLinearTime<0 ? 1 : 0); } // lineartime2dateonly // get date-only part of a linear time, in lineartime_t units lineartime_t lineartime2dateonlyTime(lineartime_t aLinearTime) { lineartime_t ts = lineartime2dateonly(aLinearTime); ts *= linearDateToTimeFactor; return ts; } // lineartime2dateonlyTime } // namespace sysync /* eof */ libsynthesis-3.4.0.47.1/src/sysync_SDK/Sources/lineartime.h000077500000000000000000000162131226375725500234170ustar00rootroot00000000000000/* * File: lineartime.h * * Author: Lukas Zeller (luz@plan44.ch) * * conversion from/to linear time scale. * * Copyright (c) 2002-2011 by Synthesis AG + plan44.ch * * 2002-04-14 : luz : created from pascal source (plani.ch) * */ #ifndef LINEARTIME_H #define LINEARTIME_H #include "prefix_file.h" #include "generic_types.h" #ifndef PLATFORM_LINEARTIMEDEF // Standard lineartime_t definition as 64bit integer, // in milliseconds since -4712-01-01 00:00:00 // -------------------------------------------------- #ifdef __cplusplus namespace sysync { #endif // Linear date and time types typedef sInt32 lineardate_t; typedef sInt64 lineartime_t; // max and min constants const lineartime_t noLinearTime = 0x0; ///< undefined lineartime value #ifdef _MSC_VER const lineartime_t maxLinearTime = 0x7FFFFFFFFFFFFFFFi64; ///< maximum future lineartime (signed 64 bit) #else const lineartime_t maxLinearTime = 0x7FFFFFFFFFFFFFFFLL; ///< maximum future lineartime (signed 64 bit) #endif // date origin definition relative to algorithm's origin -4712-01-01 00:00:00 const lineardate_t linearDateOriginOffset=0; ///< offset between algorithm's origin (-4712-01-01) and lineardate_t's zero const sInt16 linearDateOriginWeekday=1; ///< weekday of lineartime origin: Monday // scaling of lineartime relative to seconds const lineartime_t secondToLinearTimeFactor = 1000; ///< how many lineartime_t units make a seconds const lineartime_t nanosecondsPerLinearTime = 1000000; ///< duration of one lineartime_t in nanoseconds #ifdef __cplusplus } // namespace sysync #endif #endif // not PLATFORM_LINEARTIMEDEF // the platform specific definitions of the time support // Note: if PLATFORM_LINEARTIMEDEF is set, this must define lineartime_t and related // constants. // If it defines PLATFORM_LINEARDATE2DATE etc., // implementation of these routines must be implemented platform-specific as well. #include "platform_time.h" #ifdef __cplusplus namespace sysync { #endif #ifdef SYSYNC_TOOL // convert between different time formats and zones int timeConv(int argc, const char *argv[]); #endif // Time context type definition. Defined here to avoid mutual inclusion need of // this file and timezones.h. typedef uInt32 timecontext_t; ///< define a time context (dateonly,time zone, etc.) // Generic utility factors and routines // ------------------------------------ /// useful time/date definitions const int SecsPerMin = 60; const int MinsPerHour= 60; const int SecsPerHour= SecsPerMin*MinsPerHour; const int HoursPerDay= 24; const int DaysPerWk = 7; /// @brief conversion factor for lineardate_t to lineartime_t const lineartime_t linearDateToTimeFactor = (secondToLinearTimeFactor*SecsPerHour*HoursPerDay); /// @brief offset from lineartime_t to UNIX time(), which is based 1970-01-01 00:00:00 /// @Note units of this constants are still lineartime_t units and need /// division by secondToLinearTimeFactor to get actual UNIX time in seconds const lineartime_t UnixToLineartimeOffset = ( 2440588 // offset between algorithm base and 1970-01-01 - linearDateOriginOffset // offset between lineardate_t base and algorithm base ) * linearDateToTimeFactor; /// @brief offset from lineartime_t to NSDate reference time, which is based 2001-01-01 00:00:00 /// @Note units of this constants are still lineartime_t units and need /// division by secondToLinearTimeFactor to get actual NSDate in seconds const lineartime_t NSDateToLineartimeOffset = ( 2451911 // offset between algorithm base and 2001-01-01 - linearDateOriginOffset // offset between lineardate_t base and algorithm base ) * linearDateToTimeFactor; /// @brief convert date to linear date /// @return specified date converted to lineardate_t (unit=days) /// @param[in] aYear,aMonth,aDay : date specification lineardate_t date2lineardate(sInt16 aYear, sInt16 aMonth, sInt16 aDay); /// @brief convert date to linear time /// @return specified date converted to lineartime_t (unit=lineartime units) /// @param[in] aYear,aMonth,aDay : date specification lineartime_t date2lineartime(sInt16 aYear, sInt16 aMonth, sInt16 aDay); /// @brief convert time to linear time /// @return specified time converted to lineartime_t units /// @param[in] aMinute,aSecond,aMS : time specification lineartime_t time2lineartime(sInt16 aHour, sInt16 aMinute, sInt16 aSecond, sInt16 aMS); /// @brief convert lineardate to weekday /// @return 0=sunday, 1=monday ... 6=saturday /// @param[in] aLinearDate linear date (in days) sInt16 lineardate2weekday(lineardate_t aLinearDate); /// @brief convert lineartime to weekday /// @return 0=sunday, 1=monday ... 6=saturday /// @param[in] aLinearTime linear time (in lineartime_t units) sInt16 lineartime2weekday(lineartime_t aLinearTime); /// @brief convert lineardate to year/month/day /// @param[in] aLinearDate linear date (in days) /// @param[out] aYearP,aMonthP,aDayP : date components, may be NULL if component not needed void lineardate2date(lineardate_t aLinearDate,sInt16 *aYearP, sInt16 *aMonthP, sInt16 *aDayP); /// @brief convert lineartime to year/month/day /// @param[in] aLinearTime linear time (in lineartime_t units) /// @param[out] aYearP,aMonthP,aDayP : date components, may be NULL if component not needed void lineartime2date(lineartime_t aLinearTime, sInt16 *aYearP, sInt16 *aMonthP, sInt16 *aDayP); /// @brief get number of days in a month /// @return number of days in month (28..31) /// @param[in] aLinearDate linear date (in days) sInt16 getMonthDays(lineardate_t aLinearDate); /// @brief convert lineartime to h,m,s,ms /// @param[in] aLinearTime linear time (in lineartime_t units) /// @param[out] aHourP,aMinP,aSecP,aMSP : time components, may be NULL if component not needed void lineartime2time(lineartime_t aLinearTime, sInt16 *aHourP, sInt16 *aMinP, sInt16 *aSecP, sInt16 *aMSP); /// @brief convert seconds to linear time /// @return number of lineartime_t units /// @param[in] aSeconds a number of seconds lineartime_t seconds2lineartime(sInt32 aSeconds); /// @brief convert linear time to seconds /// @return number of seconds /// @param[in] aLinearTime lineartime_t units sInt32 lineartime2seconds(lineartime_t aLinearTime); /// @brief get time-only part of a linear time /// @return time only in lineartime_t units since midnight /// @param[in] aLinearTime a date/timestamp in lineartime_t units lineartime_t lineartime2timeonly(lineartime_t aLinearTime); /// @brief get date-only part of a linear time /// @return date only in lineardate_t units (days) /// @param[in] aLinearTime a date/timestamp in lineartime_t units lineardate_t lineartime2dateonly(lineartime_t aLinearTime); /// @brief get date-only part, but IN LINEARTIME /// @return date only in lineartime_t units /// @param[in] aLinearTime a date/timestamp in lineartime_t units lineartime_t lineartime2dateonlyTime(lineartime_t aLinearTime); // Implementation of the following routines is platform specific // ------------------------------------------------------------- /// @brief fine resolution sleep support /// @param[in] aHowLong desired time to wait in lineartime_t units void sleepLineartime(lineartime_t aHowLong); #ifdef __cplusplus } // namespace sysync #endif #endif // LINEARTIME_H /* eof */ libsynthesis-3.4.0.47.1/src/sysync_SDK/Sources/prefix_file.h000066400000000000000000000002641226375725500235560ustar00rootroot00000000000000/* * File: prefix_file.h * * Author: Beat Forster (bfo@synthesis.ch) * * * Copyright (c) 2006-2011 by Synthesis AG + plan44.ch * */ /* intentionally left blank */ libsynthesis-3.4.0.47.1/src/sysync_SDK/Sources/san.cpp000077500000000000000000000563041226375725500224070ustar00rootroot00000000000000/* * File: san.cpp * * Author: Beat Forster (bfo@synthesis.ch) * * Server Alerted Notification * for OMA DS 1.2 * * Copyright (c) 2005-2011 by Synthesis AG + plan44.ch * * */ /* 128 bit 64 bit + n char +------------+--------------------+--------------------+ | | | | | digest | notification-hdr | notification-body | | | | | +------------+--------------------+--------------------+ / \ \ / \ --------- \ / \ \ \ -------------------- ------ \ \ / \ \ \ / \ \ \ +---------+---------+-----------+--------+---------+--------+--------+ +----------+ | version | ui-mode | initiator | future | session | server | server | | usage | | | | | use | id | ident | ident | | specific | | | | | | | length | | | | +---------+---------+-----------+--------+---------+--------+--------+ +----------+ 10 bit 2 bit 1 bit 27 bit 16 bit 8 bit n char H = MD5 hashing function B64 = Base64 encoding digest= H(B64(H(server-identifier:password)):nonce:B64(H(notification))) notification body: +-------+--------+--------+--------+----------+ | num | future | sync 1 | sync N | vendor | | syncs | use | | | specific | | | | | | | +-------+--------+--------+--------+----------+ 4 bit 4 bit / \ n char / \ ---------- ------- / \ / \ +------+--------+---------+--------+--------+ | sync | future | content | server | server | | type | use | type | URI | URI | | | | | length | | +------+--------+---------+--------+--------+ 4 bit 4 bit 24 bit 8 bit n char */ #ifdef HAVE_CONFIG_H # include #endif #include "prefix_file.h" #include "sync_include.h" #include "san.h" #include "sysync_md5.h" #include "sysync_b64.h" #ifndef WITHOUT_SAN_1_1 #include "sysync_utils.h" #endif const uInt16 SyncML12 = 12; // currently supported SyncML version const uInt16 SyncML11 = 11; // currently supported SyncML version const uInt16 SyncML10 = 10; // currently supported SyncML version #pragma options align= packed // allow direct mapping of the structure using namespace sysync; namespace sysync { // ---- structure definition --------------------------------------------- #define BpB 8 // bits per byte #define NBits 7 // bytes of the notification-hdr bits #define BBits 4 // bytes of the notification-body bits #define DB_Full 420 // memory full error #define DB_Error 510 // general DB error struct TPackage { TDigestField digest; uInt8 bitField[ NBits ]; // version, ui-mode, initiator, future use, sesion id uInt8 serverID_len; }; // TPackage struct TBody { uInt8 bitField[ BBits ]; // sync type, future use, content type uInt8 serverURI_len; }; // TBody // ---- defined locally for the moment to avoid dependencies ---- // // MD5 and B64 given string static void MD5B64_Local(const char *aString, sInt32 aLen, string &aMD5B64) { // determine input length if (aLen<=0) aLen=strlen(aString); // calc MD5 md5::SYSYNC_MD5_CTX context; uInt8 digest[16]; md5::Init (&context); md5::Update (&context, (const uInt8 *)aString,aLen); md5::Final (digest, &context); // b64 encode the MD5 digest uInt32 b64md5len; char *b64md5=b64::encode(digest,16,&b64md5len); // assign result aMD5B64.assign(b64md5,b64md5len); // done b64::free(b64md5); // return buffer allocated by b64::encode } // MD5B64_Local // ---- constructor/destructor ------------------------------------------- SanPackage::SanPackage() // constructor { fBody= NULL; CreateEmptyNotificationBody(); memset( &fDigest, 0, DigestSize ); fProtocolVersion= 0; fUI_Mode = UI_not_specified; fInitiator = Initiator_Server; fSessionID = 0; fSan = NULL; fSanSize = 0; } // constructor SanPackage::~SanPackage() // destructor { ReleasePackage(); ReleaseNotificationBody(); } // destructor // ---- digest creation -------------------------------------------------- TDigestField SanPackage::H( string s ) { TDigestField df; // calc MD5 md5::SYSYNC_MD5_CTX context; md5::Init ( &context ); md5::Update ( &context, (const uInt8 *)s.c_str(), s.length() ); md5::Final( df.b, &context ); return df; } // DigestField string SanPackage::B64_H( string s1, string s2 ) { if (!s2.empty()) s1+= ":" + s2; MD5B64_Local( s1.c_str(), s1.size(), s1 ); return s1; } // B64_H string SanPackage::B64_H_Notification( void* san, size_t sanSize ) { string s; const char* v= (const char*)san + DigestSize; size_t nfySize= sanSize - DigestSize; MD5B64_Local( v, nfySize, s ); return s; } // B64_H /*! Prepare the SAN record */ void SanPackage::PreparePackage( string aB64_H_srvID_pwd, string aNonce, uInt16 aProtocolVersion, UI_Mode aUI_Mode, Initiator aInitiator, uInt16 aSessionID, string aSrvID ) { fB64_H_srvID_pwd= aB64_H_srvID_pwd; fNonce = aNonce; fProtocolVersion= aProtocolVersion; fUI_Mode = aUI_Mode; fInitiator = aInitiator; fSessionID = aSessionID; fServerID = aSrvID; } // PreparePackage // if only hashes are available TSyError SanPackage::CreateDigest( const char* b64_h_serverID_password, const char* aNonce, void* san, size_t sanSize ) { string s= b64_h_serverID_password; if ( s.empty()) { for (int i= 0; ib[ i ]) return false; } // for return true; } // DigestOK // ---- bit operations --------------------------------------------------- void SanPackage::AddBits( void* ptr, int pos, int n, uInt32 value ) { byte* b= (byte*)ptr; int lim= pos+n; if (lim>BpB*NBits) return; // check if within the field while (lim>BpB) { b++; lim-= BpB; } int i; for (i=0; iBpB*NBits) return 0; // check if within the field while (lim>BpB) { b++; lim-= BpB; } int i; for (i=0; i value= value / 2; lim--; if (lim==0) { lim= BpB; b--; } } // for return value; } // GetBits // ---- notification body generation ------------------------------------- void SanPackage::CreateEmptyNotificationBody() { ReleaseNotificationBody(); fEmpty= 0x00; // no sync fields = ALL data stores concerned fBody= &fEmpty; fBodySize= sizeof(fEmpty); fNSync= 0; } // CreateEmptyNotificationBody TSyError SanPackage::AddSync( int syncType, uInt32 contentType, const char* serverURI ) { int len= strlen(serverURI); int nLen= BBits + 1 + len; // length of the new part int newLen= fBodySize + nLen; // total length of the new block void* fb= malloc( newLen ); // allocate it memcpy( fb, fBody,fBodySize ); // copy existing structure to beginning byte* b = (byte*)fb; b+= fBodySize; // get a pointer to the new part ReleaseNotificationBody(); // release the old structure fNSync++; // adapt number of available parts fBody = fb; // now the new bigger structure is assigned fBodySize= newLen; // fill in new counter value AddBits( fBody, 0, 4, fNSync ); // number of sync datastores AddBits( fBody, 4, 4, 0 ); // future use // fill in contents of the nth structure TBody* tb= (TBody*)b; AddBits( tb->bitField, 0, 4, syncType-200 ); // the sync type 206..210 AddBits( tb->bitField, 4, 4, 0 ); // future use AddBits( tb->bitField, 8,24, contentType ); // the content tye tb->serverURI_len= len; byte* pp= (byte*)(tb+1); // = right after TBody memcpy( (void*) pp, (void*)serverURI, len ); return LOCERR_OK; } // AddSync void SanPackage::ReleaseNotificationBody() { if (fBody!=NULL && fBody!=&fEmpty) { free( fBody ); fBody= NULL; } } // ReleaseNotificationBody #ifndef WITHOUT_SAN_1_1 // general callback entry for all others static Ret_t univ( ... ) { //printf( "callback\n" ); return 0; } // univ static Ret_t startM( InstanceID_t id, VoidPtr_t userData, SmlSyncHdrPtr_t pContent ) { cAppCharP Sy= "SyncML/"; size_t n = strlen(Sy); SanPackage* a= (SanPackage*)userData; string mup = ""; string nonce= ""; uInt16 major=0,minor=0; cAppCharP verP = smlPCDataToCharP(pContent->proto); if (strucmp(verP,Sy,n)==0) { n+=StrToUShort(verP+n,major); if (verP[n]=='.') { n++; StrToUShort(verP+n,minor); } } sInt32 sessionID; smlPCDataToLong( pContent->sessionID, sessionID ); string srvID= smlSrcTargLocURIToCharP(pContent->source); a->PreparePackage( mup, nonce, 10*major+minor, UI_not_specified, Initiator_Server, sessionID, srvID ); a->CreateEmptyNotificationBody(); return 0; } // startM static Ret_t alertM( InstanceID_t id, VoidPtr_t userData, SmlAlertPtr_t pContent ) { SanPackage* a= (SanPackage*)userData; sInt32 syncType; smlPCDataToLong( pContent->data, syncType ); uInt32 contentType= 0; // always 0 SmlItemListPtr_t el= pContent->itemList; while (true) { // can be a chained list of elements string locURI= smlSrcTargLocURIToCharP(el->item->source); a->AddSync( syncType, contentType, locURI.c_str() ); // for each element add one if (el->next==NULL) break; el= el->next; } // while //printf( "alert\n" ); return 0; } // alert static Ret_t endM( InstanceID_t id, VoidPtr_t userData, Boolean_t final ) { //printf( "end\n" ); return 0; } // endM // Callback record, most of the routines are not used static const SmlCallbacks_t mySmlCallbacks = { /* message callbacks */ startM, // smlStartMessageCallback, endM, // smlEndMessageCallback, /* grouping commands */ (smlStartSyncFunc) univ, // smlStartSyncCallback, (smlEndSyncFunc) univ, // smlEndSyncCallback, #ifdef ATOMIC_RECEIVE /* these callbacks are NOT included in the Toolkit lite version */ univ, // smlStartAtomicCallback, univ, // smlEndAtomicCallback, #endif #ifdef SEQUENCE_RECEIVE univ, // smlStartSequenceCallback, univ, // smlEndSequenceCallback, #endif /* Sync Commands */ (smlAddCmdFunc) univ, // smlAddCmdCallback, alertM, // smlAlertCmdCallback, (smlDeleteCmdFunc)univ, // smlDeleteCmdCallback, (smlGetCmdFunc) univ, // smlGetCmdCallback, (smlPutCmdFunc) univ, // smlPutCmdCallback, #ifdef MAP_RECEIVE (smlMapCmdFunc) univ, // smlMapCmdCallback, #endif #ifdef RESULT_RECEIVE (smlResultsCmdFunc)univ, // smlResultsCmdCallback, #endif (smlStatusCmdFunc) univ, // smlStatusCmdCallback, (smlReplaceCmdFunc)univ, // smlReplaceCmdCallback, /* other commands */ #ifdef COPY_RECEIVE /* these callbacks are NOT included in the Toolkit lite version */ univ, // smlCopyCmdCallback, #endif #ifdef EXEC_RECEIVE univ, // smlExecCmdCallback, #endif #ifdef SEARCH_RECEIVE univ, // smlSearchCmdCallback, #endif smlMoveCmdFunc(univ), // smlMoveCmdCallback, /* Other Callbacks */ smlHandleErrorFunc (univ), // smlHandleErrorCallback, smlTransmitChunkFunc(univ) // smlTransmitChunkCallback }; /* sml_callbacks struct */ // Try to convert a 1.1 message // - if successful, fill in values into 1.2 fields // - if not successful, interpret it as 1.2 structure TSyError SanPackage::Check_11( void* san, size_t sanSize ) { TSyError err; SmlCallbacks_t scb= mySmlCallbacks; SmlInstanceOptions_t sIOpts; InstanceID_t id; Ret_t cer; MemPtr_t wPos; MemSize_t freeSize; // struct assignment / 1k buffer sIOpts.encoding = SML_WBXML; // it is always WBXML sIOpts.workspaceSize = 1024*30; // should be always sufficient sIOpts.maxOutgoingSize= 0; // disabled for now err= smlInitInstance( &scb, &sIOpts, this, &id ); if (err) return err; do { err= smlLockWriteBuffer ( id, &wPos, &freeSize ); if (err) break; memcpy( wPos, san,sanSize ); // now we have a new internal copy err= smlUnlockWriteBuffer( id, sanSize ); if (err) break; err= smlProcessData ( id, SML_ALL_COMMANDS ); if (err) break; } while (false); cer= smlTerminateInstance( id ); if (!err) err= cer; return err; } // Check_11 #endif // WITHOUT_SAN_1_1 TSyError SanPackage::PassSan( void* san, size_t sanSize, int mode) { TSyError err = LOCERR_OK; bool use_as_12= true; ReleasePackage(); //printf( "here we will have the potential 1.1 -> 1.2 conversion\n" ); #ifndef WITHOUT_SAN_1_1 if (mode == 0 || mode == 1) { err= Check_11 ( san,sanSize ); if (!err) err= GetPackage( san,sanSize ); //use_as_12= err==SML_ERR_XLT_INCOMP_WBXML_VERS; use_as_12= err!=0; //printf( "err=%d\n", err ); } #endif if (use_as_12 && mode !=1) { err= DB_Full; fSan= malloc( sanSize ); if (fSan) { fSanSize= sanSize; memcpy( fSan, san,sanSize ); // now we have a new internal copy err= LOCERR_OK; } // if } // if return err; } // PassSan TSyError SanPackage::GetSanSize( void* san, size_t &sanSize ) { TPackage* tp= (TPackage*)san; TBody* tb = NULL; byte* b= (byte*)(tp+1); byte* v; b+= tp->serverID_len; int nth= GetBits( b, 0,4 ); // first not valid = the end b++; // start of 1st element int n= nth; while (n>0) { n--; tb= (TBody*)b; b = (byte*)(tb+1); if (b > (byte*)san+sanSize && sanSize>0) return DB_Forbidden; v= b + tb->serverURI_len; if (b > (byte*)san+sanSize && sanSize>0) return DB_Forbidden; if (n==0) break; b= v; } // while b+= tb->serverURI_len; // finally the serverURI length size_t rslt= b - (byte*)san; if (sanSize>0 && sanSizedigest; fProtocolVersion= GetBits( tp->bitField, 0,10 ); fUI_Mode = (UI_Mode)GetBits( tp->bitField, 10, 2 ); fInitiator = (Initiator)GetBits( tp->bitField, 12, 1 ); fSessionID = GetBits( tp->bitField, 40,16 ); /*If the version does not match, this should be an invalid SAN message*/ if (fProtocolVersion!=SyncML12 && fProtocolVersion!=SyncML11 && fProtocolVersion!=SyncML10) return DB_Forbidden; byte* b= (byte*)(tp+1); byte* v; fServerID.assign( (const char*)b,(unsigned int)tp->serverID_len ); b+= tp->serverID_len; fNSync= GetBits( b, 0,4 ); if (nth==0) return LOCERR_OK; if (nth<1 || nth>fNSync ) return DB_NotFound; b++; // start of 1st element int n= nth; while (n>0) { n--; tb= (TBody*)b; b = (byte*)(tb+1); if (b > (byte*)fSan+fSanSize) return DB_Forbidden; // no access behind the message v= b + tb->serverURI_len; if (v > (byte*)fSan+fSanSize) return DB_Forbidden; // no access behind the message if (n==0) break; b= v; } // while syncType = 200 + GetBits( tb->bitField, 0, 4 ); contentType= GetBits( tb->bitField, 8,24 ); serverURI.assign( (const char*)b,(unsigned int)tb->serverURI_len ); return LOCERR_OK; } // GetNthSync TSyError SanPackage::GetHeader() { int syncType; // these 3 variables are not really used uInt32 contentType; string serverURI; return GetNthSync( 0, syncType,contentType,serverURI ); } // GetHeader // ---- package generation ----------------------------------------------- TSyError SanPackage::GetPackage( void* &san, size_t &sanSize, void* vendorSpecific, size_t vendorSpecificSize ) { ReleasePackage(); // remove a previous one byte len = (byte)fServerID.length(); // calulate the full size sanSize= sizeof(TPackage) + len + fBodySize + vendorSpecificSize; //size_t nfySize= sanSize - DigestSize; fSan = malloc( sanSize ); san = fSan; TPackage* tp= (TPackage*)fSan; // ------------------- AddBits( tp->bitField, 0,10, fProtocolVersion ); AddBits( tp->bitField, 10, 2, fUI_Mode ); AddBits( tp->bitField, 12, 1, fInitiator ); AddBits( tp->bitField, 13,27, 0 ); // future use, must be "0" AddBits( tp->bitField, 40,16, fSessionID ); tp->serverID_len= len; // copy string at the end of TPackage struct byte* pp= (byte*)(tp+1); // = right after TPackage memcpy( (void*) pp, (void*)fServerID.c_str(), len ); memcpy( (void*)(pp+len), fBody, fBodySize ); if (vendorSpecific!=NULL && vendorSpecificSize>0) memcpy( (void*)(pp+len+fBodySize), vendorSpecific,vendorSpecificSize ); CreateDigest( fB64_H_srvID_pwd.c_str(), fNonce.c_str(), san,sanSize ); tp->digest= fDigest; fSanSize= sanSize; return LOCERR_OK; } // GetPackage void SanPackage::ReleasePackage() { if (fSan!=NULL) { free( fSan ); fSan= NULL; } } // ReleasePackage #ifndef WITHOUT_SAN_1_1 const char * const SyncMLVerProtoNames[] = { "undefined", "SyncML/1.0", "SyncML/1.1", "SyncML/1.2" }; const char *const SyncMLVerDTDNames[] = { "???", "1.0", "1.1", "1.2" }; const SmlVersion_t SmlVersionCodes[] = { SML_VERS_UNDEF, SML_VERS_1_0, SML_VERS_1_1, SML_VERS_1_1 }; TSyError SanPackage::GetPackageLegacy( void* &san, size_t &sanSize, const vector >& sources, int alertCode, bool wbxml) { ReleasePackage(); // remove a previous one TSyError err; SmlCallbacks_t scb= mySmlCallbacks; SmlInstanceOptions_t sIOpts; InstanceID_t id; // struct assignment / 1k buffer sIOpts.encoding = wbxml ? SML_WBXML : SML_XML; sIOpts.workspaceSize = 1024; // should be always sufficient sIOpts.maxOutgoingSize= 0; // disabled for now err= smlInitInstance( &scb, &sIOpts, this, &id ); if (err) return err; SmlSyncHdrPtr_t headerP = NULL; SmlAlertPtr_t alertP = NULL; do { SYSYNC_TRY{ //create SyncHdr headerP = SML_NEW (SmlSyncHdr_t); headerP->elementType = SML_PE_HEADER; if (fProtocolVersion != 10 && fProtocolVersion != 11){ //wrong version! err = DB_Error; break; } int version = fProtocolVersion - 10 + 1; headerP->version = newPCDataString (SyncMLVerDTDNames[version]); headerP->proto = newPCDataString (SyncMLVerProtoNames[version]); headerP->sessionID = newPCDataLong (fSessionID); headerP->msgID = newPCDataString ("1"); headerP->target = newLocation ("/", ""); headerP->source = newLocation (fServerID.c_str(), ""); headerP->respURI = NULL; headerP->meta = NULL; headerP->flags = 0; //TODO generate the cred element for authentication headerP->cred = NULL; //create SyncMessage err = smlStartMessageExt (id, headerP, SmlVersionCodes[version]); if (err) break; //create Alert Commands //internal Alert element alertP = SML_NEW (SmlAlert_t); alertP->elementType = SML_PE_ALERT; alertP->cmdID = newPCDataLong(1); alertP->flags = 0; alertP->data = newPCDataLong (alertCode); alertP->cred = NULL; alertP->itemList = NULL; alertP->flags = 0; //for each source, add a item for (unsigned int num =0; num < sources.size(); num++) { SmlItemPtr_t alertItemP = newItem(); alertItemP->source = newOptLocation (sources[num].second.c_str()); alertItemP->meta = newMetaType (sources[num].first.c_str()); addItemToList (alertItemP, &alertP->itemList); } err = smlAlertCmd (id, alertP); if (err) break; err = smlEndMessage (id, true); if (err) break; MemPtr_t buf = NULL; err = smlLockReadBuffer (id, (MemPtr_t *) &buf, (MemSize_t *)&sanSize); if (err) break; fSan = malloc( sanSize ); if (!fSan) {err = DB_Full; break;} san = fSan; memcpy (san, buf, sanSize); err = smlUnlockReadBuffer (id, sanSize); if (err) break; } SYSYNC_CATCH (...) if (headerP) { smlFreeProtoElement (headerP); headerP = NULL; } if (alertP) { smlFreeProtoElement (alertP); alertP = NULL; } err = DB_Full; SYSYNC_ENDCATCH } while (false); if (headerP) { smlFreeProtoElement (headerP); } if (alertP) { smlFreeProtoElement (alertP); } if (err) return err; err = smlTerminateInstance( id ); return err; } #endif } // namespace sysync // eof libsynthesis-3.4.0.47.1/src/sysync_SDK/Sources/san.h000066400000000000000000000223451226375725500220470ustar00rootroot00000000000000/* * File: san.h * * Author: Beat Forster (bfo@synthesis.ch) * * Server Alerted Notification * for OMA DS 1.2 * * Copyright (c) 2005-2011 by Synthesis AG + plan44.ch * */ #ifndef San_H #define San_H // ---------- standalone definitions ------------------------------ #include "generic_types.h" // some basic defs, which aren't available #include "syerror.h" // error code definitions #include "sysync_noncopyable.h" #include // used for printf calls #include // used for strcpy/strlen calls #ifdef __cplusplus #include // STL includes #include #include using namespace std; #endif typedef unsigned char byte; // ---------------------------------------------------- namespace sysync { // The digest field structure #define DigestSize 16 struct TDigestField { uInt8 b[ DigestSize ]; }; // TDigestField enum UI_Mode { UI_not_specified = 0, // "00" UI_background = 1, // "01" UI_informative = 2, // "10" UI_user_interaction = 3 // "11" }; enum Initiator { Initiator_User = 0, // "0" Initiator_Server = 1 // "1" }; /*! * How to create a SAN package (on server side): * 1) Prepare the SAN package using 'PreparePackage' * * If all datastores need to be notified, skip 2 and 3 * If specific datastores need to be notified, call 2 and 3 * * 2) Call 'CreateEmptyNotificationBody' (not needed 1st time) and * 3) call 'AddSync' for each datastore to be notified * * 4) Create the SAN package with 'GetPackage'. * A vendor specific record can be added, if required. * * How to create a Legacy SAN package (server side SAN 1.0/1.1): * 1) Prepare the SAN package using 'PreparePackage' * 2) Call 'CreateEmptyNotificationBody' (not needed 1st time) and * 3) Create the SAN package with 'GetPackageLegacy'. * *-------------------------------------------------------------------- * How to check a SAN package (on client side): * 1) pass the san message with 'PassSan' * 1) create first (using 'CreateDigest') * 2) call 'DigestOK', to verify it * * How to get the th sync message: * call 'GetNthSync( n, .. )' * [ call 'GetHeader ( )' or * GetNthSync( 0, .. )' to get header params only ] * */ class SanPackage : noncopyable { // for Klocwork, noncopyable alone was not enough SanPackage & operator = (const SanPackage &); public: SanPackage(); // constructor ~SanPackage(); // destructor /*! Base64 encoded MD5, two strings can be concatenated with ":" */ string B64_H( string s1, string s2= "" ); /*! Base64 encoded MD5 of the notification part of ,. */ string B64_H_Notification( void* san, size_t sanSize ); /*! Prepare the SAN package */ void PreparePackage( string aB64_H_srvID_pwd, string aNonce, uInt16 aProtocolVersion, UI_Mode aUI_Mode, Initiator aInitiator, uInt16 aSessionID, string aSrvID ); /*! These variables will be assigned with the 'PreparePackage' call * : 10*version => max= V102.3 / V1.0 = 10 ) * for OMA DS 1.2 use '12' */ string fB64_H_srvID_pwd; string fNonce; uInt16 fProtocolVersion; // 10 bit UI_Mode fUI_Mode; // 2 bit Initiator fInitiator; // 1 bit uInt16 fSessionID; // 16 bit string fServerID; /*! Create an empty notification body */ void CreateEmptyNotificationBody(); /*! Add a sync sequence to the notification body * * (in) * @param 206..210 (internally less 200: 206 -> 6) * @param MIME media content type (24 bit) * @param server's URI */ TSyError AddSync( int syncType, uInt32 contentType, const char* serverURI ); /*! Get the SAN package for v1.2 * * (out) * @param get the pointer to the SAN message. * @param get the SAN message size (in bytes). * * (in) * @param reference to vendor specific part * @param size (in bytes) of vendor specific part * * @return error code if operation can't be performed * * NOTE: The notification body will be added automatically * */ TSyError GetPackage( void* &san, size_t &sanSize, void* vendorSpecific= NULL, size_t vendorSpecificSize= 0 ); #ifndef WITHOUT_SAN_1_1 /*! Get the SAN package for v1.1/v1.0 * * (out) * @param get the pointer to the SAN message. * @param get the SAN message size (in bytes). * * (in) * @param vector of alerted sources * @param the synchronization mode * @param use wbxml or plain xml * * @return error code if operation can't be performed * * NOTE: The notification body will be added automatically * */ TSyError GetPackageLegacy( void* &san, size_t &sanSize, const vector > &sources, int alertCode, bool wbxml = true); #endif /*! Create the digest for the SAN package: * digest= H(B64(H(server-identifier:password)):nonce:B64(H(notification))) * where notification will be calculated from /. */ TSyError CreateDigest( const char* aSrvID, const char* aPwd, const char* aNonce, void* san, size_t sanSize ); /*! overloaded version, if only the B64 hashes are available */ TSyError CreateDigest( const char* b64_h_srvID_pwd, const char* aNonce, void* san, size_t sanSize ); /*! Check, if the digest of is correct */ bool DigestOK( void* san ); /*! Pass SAN message , to object, * a local copy will be kept then internally * (in) * @param the pointer to the SAN message * @param the max. SAN message size (in bytes) * @param 0|1|2, 0 tries both San 1.1 and 1.2, 1 tries only * 1.1 and 2 tries only 1.2 */ TSyError PassSan( void* san, size_t sanSize , int mode = 0); /*! Get the effective size of an already created message * (without vendor specific part) * * (in) * @param the pointer to the SAN message * @param the max. SAN message size (in bytes) * 0, if unknown. * (out) * @param the effective SAN message size (in bytes) * * @return error code 403, if input is too small */ TSyError GetSanSize( void* san, size_t &sanSize ); /*! Get the nth sync info * * (in) * @param the pointer to the SAN message * @param the SAN message size (in bytes) * @param asks for the sync info * nth=0 is allowed also, but will only assign * the header variables * (out) * @param 206..210 (internally less 200: 206 -> 6) * @param MIME media content type (24 bit) * @param server's URI * * @return error code 403, if is too small * 404, if is out of range */ //TSyError GetNthSync( void* san, size_t sanSize, int nth, TSyError GetNthSync( int nth, int &syncType, uInt32 &contentType, string &serverURI ); /*! Alternative call for GetNthSync( 0, ... ) */ //TSyError GetHeader ( void* san, size_t sanSize ); TSyError GetHeader (); TDigestField fDigest; // The digest, created with "CreateDigest" int fNSync; // number of actual sync fields private: /*! the internally built notification-body structure */ byte fEmpty; // direct reference to empty structure void* fBody; // the body structure ... size_t fBodySize; // .. and its size /*! local copies of , */ void* fSan; size_t fSanSize; /*! MD5 conversion */ TDigestField H( string s ); /* Try to interpret SyncML 1.1 SAN */ TSyError Check_11( void* san, size_t sanSize ); /*! Add into field at , */ void AddBits( void* ptr, int pos, int n, uInt32 value ); /*! Get value from field at , */ uInt32 GetBits( void* ptr, int pos, int n ); /*! Release notification body */ void ReleaseNotificationBody(); /*! Release the SAN package */ void ReleasePackage(); }; // SanPackage } // namespace sysync #endif // San_H // eof libsynthesis-3.4.0.47.1/src/sysync_SDK/Sources/stringutil.cpp000066400000000000000000000166541226375725500240330ustar00rootroot00000000000000/* * File: stringutil.cpp * * Authors: Lukas Zeller (luz@plan44.ch) * Beat Forster (bfo@synthesis.ch) * * C++ string utils * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * */ #include "target_options.h" #ifndef WITHOUT_SAN_1_1 #if defined __MACH__ && !defined __GNUC__ /* used for va_list support */ #include #else #include #endif #ifdef __GNUC__ #include #else #ifndef _MSC_VER #include #endif #endif #include "stringutil.h" #ifdef __cplusplus namespace sysync { #endif // case insensitive strcmp, NULL allowed as empty string input sInt16 strucmp( cAppCharP s1, cAppCharP s2, size_t len1, size_t len2 ) { // allow NULL as empty strings if (!s1) s1 = ""; if (!s2) s2 = ""; // s1>s2 : 1, s1==s2 : 0, s1len2 ? len2 : len1)); for (i=0; (!len || itoupper(*s2) ? 1 : -1; // different // next s1++; s2++; } // equal up to end of shorter string or reached len // - if both reached end or len -> equal if ( ((len1 ? i==len1 : false) || *s1==0) && ((len2 ? i==len2 : false) || *s2==0) ) return 0; // - not equal, longer string is larger // (if not reached end of s1 or stopped before len1, s1 is longer // but note than len1 can be longer than actual length of s1, so we // must check for *s1 to make sure we have really not reached end of s1) return (len1 ? i'9' ? toupper(*p)-'A'+0x0A : *p-'0'); p++; n++; } break; } // c is the char to add } else if (aStopAtQuoteOrCtrl && (c=='"' || c<0x20)) { // terminating char is NOT consumed p--; break; // stop here } // otherwise, ignore any control characters else if (c<0x20 && c!=ignore) continue; // add it to the result if (c) aString+=c; } // return number of converted chars return p-aStr; } // CStrToStrAppend // returns number of string-escaped chars successfully converted to C-string sInt16 StrToCStrAppend( cAppCharP aStr, string &aString, bool aAllow8Bit, char ignore ) { unsigned char c; const char *p=aStr; while ((c=*p++)) { // check for specials if (c==ignore) aString+= c; else if (c==0x09) aString+="\\t"; else if (c==0x0A) aString+="\\n"; else if (c==0x0D) aString+="\\r"; else if (c==0x22) aString+="\\\""; else if (c=='\\') aString+="\\\\"; // escape the backslash as well else if (c<0x20 || c==0x7F || (!aAllow8Bit && c>=0x80)) { StringObjAppendPrintf(aString,"\\x%02hX",(uInt16)c); } else { // as is aString+=c; } } // return number of converted chars return p-aStr; } // StrToCStrAppend // old-style C-formatted output into string object static void vStringObjPrintf( string &aStringObj, cAppCharP aFormat, bool aAppend, va_list aArgs ) { #ifndef NO_VSNPRINTF const size_t bufsiz=128; #else const size_t bufsiz=2048; #endif int actualsize; char buf[bufsiz]; buf[0]='\0'; char *bufP = NULL; if (!aAppend) aStringObj.erase(); actualsize = vsnprintf(buf, bufsiz, aFormat, aArgs); #ifndef NO_VSNPRINTF if (actualsize>=(int)bufsiz) { // default buffer was too small, create bigger dynamic buffer bufP = new char[actualsize+1]; actualsize = vsnprintf(bufP, actualsize+1, aFormat, aArgs); if (actualsize>0) { aStringObj += bufP; } delete bufP; } else #endif { // small default buffer was big enough, add it if (actualsize<0) return; // abort, error aStringObj += buf; } } // vStringObjPrintf // old-style C-formatted output appending into string object void StringObjAppendPrintf( string &aStringObj, cAppCharP aFormat, ... ) { va_list args; va_start(args, aFormat); // now make the string vStringObjPrintf(aStringObj,aFormat,true,args); va_end(args); } // StringObjAppendPrintf // returns number of successfully converted chars sInt16 HexStrToULong( cAppCharP aStr, uInt32 &aLong, sInt16 aMaxDigits ) { // our own implementation char c; sInt16 n=0; aLong=0; while (aStr && (c=*aStr++) && (n #include "target_options.h" #include "generic_types.h" using namespace std; #ifdef __cplusplus namespace sysync { #endif // case insensitive strcmp, NULL allowed as empty string input sInt16 strucmp( cAppCharP s1, cAppCharP s2, size_t len1=0, size_t len2=0 ); // returns number of C-string-escaped chars successfully converted to string sInt16 CStrToStrAppend( cAppCharP aStr, string &aString, bool aStopAtQuoteOrCtrl=false, char ignore='\0' ); // returns number of string-escaped chars successfully converted to C-string sInt16 StrToCStrAppend( cAppCharP aStr, string &aString, bool aAllow8Bit=false, char ignore='\0' ); // old-style C-formatted output into string object void StringObjAppendPrintf( string &aStringObj, cAppCharP aFormat, ... ); sInt16 StrToULong ( cAppCharP aStr, uInt32 &aLong, sInt16 aMaxDigits= 100 ); sInt16 StrToLong ( cAppCharP aStr, sInt32 &aLong, sInt16 aMaxDigits= 100 ); sInt16 StrToUShort ( cAppCharP aStr, uInt16 &aShort, sInt16 aMaxDigits= 100 ); sInt16 HexStrToULong ( cAppCharP aStr, uInt32 &aLong, sInt16 aMaxDigits= 100 ); sInt16 HexStrToULongLong( cAppCharP aStr, uInt64 &aLongLong, sInt16 aMaxDigits= 100 ); sInt16 HexStrToUIntPtr ( cAppCharP aStr, uIntPtr &aIntPtr, sInt16 aMaxDigits= 100 ); #ifdef __cplusplus } // namespace #endif #endif // STRINGUTIL_H libsynthesis-3.4.0.47.1/src/sysync_SDK/Sources/syerror.h000066400000000000000000000151231226375725500227670ustar00rootroot00000000000000/* * File: syerror.h * * Author: luz@synthesis.ch / bfo@synthesis.ch * * Synthesis SyncML engine error code definitions * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * */ #ifndef SYERROR_H #define SYERROR_H #include "generic_types.h" #ifdef __cplusplus namespace sysync { #endif /** * global type for error codes * * Using an integer simplifies some arithmetic, * allows assigning HTTP error codes to it, * and most importantly, ensures that the ABI * does not accidentally change. */ typedef uInt16 TSyError; /** * Local error codes */ enum TSyErrorEnum { /** ok */ LOCERR_OK = 0, /** * May be returned by a store when an operation was started without * completing it yet. Engine will call the same operation again * later. When called a second time, the store must finish the started * operation and return the final result. */ LOCERR_AGAIN = 1, /** no content / end of file / end of iteration / empty/NULL value */ DB_NoContent = 204, /** while adding item, additional data (from external source or other syncset item) has been merged */ DB_DataMerged = 207, /** adding item has replaced an existing item */ DB_DataReplaced = 208, /** not authorized */ DB_Unauthorized = 401, /** forbidden / access denied */ DB_Forbidden = 403, /** object not found / unassigned field */ DB_NotFound = 404, /** command not allowed (possibly: only at this time) */ DB_NotAllowed = 405, /** proxy authentication required */ DB_ProxyAuth = 407, /** conflict, item was not stored because it requires merge (on part of the engine) first */ DB_Conflict = 409, /** item already exists */ DB_AlreadyExists = 418, /** command failed / fatal DB error */ DB_Fatal = 500, /** general DB error */ DB_Error = 510, /** database / memory full error */ DB_Full = 420, /** bad or unknown protocol */ LOCERR_BADPROTO = 20001, /** fatal problem with SML init/setuserdata etc. */ LOCERR_SMLFATAL = 20002, /** cannot open communication (TCP level) */ LOCERR_COMMOPEN = 20003, /** cannot send data */ LOCERR_SENDDATA = 20004, /** cannot receive data */ LOCERR_RECVDATA = 20005, /** Bad content in response (i.e. non-SyncML, exceeding buffer or HTTP status not 200) */ LOCERR_BADCONTENT = 20006, /** SML (or SAN) error processing incoming message */ LOCERR_PROCESSMSG = 20007, /** cannot close communication */ LOCERR_COMMCLOSE = 20008, /** transport layer authorisation (e.g. HTTP auth) failed */ LOCERR_AUTHFAIL = 20009, /** error parsing config file */ LOCERR_CFGPARSE = 20010, /** error reading config file */ LOCERR_CFGREAD = 20011, /** no config/profile found at all, or not enough for requested op (client session start) */ LOCERR_NOCFG = 20012, /** config file could not be found */ LOCERR_NOCFGFILE = 20013, /** expired */ LOCERR_EXPIRED = 20014, /** bad usage (e.g. wrong order of library calls) */ LOCERR_WRONGUSAGE = 20015, /** bad handle (e.g. datastore) */ LOCERR_BADHANDLE = 20016, /** aborted by user */ LOCERR_USERABORT = 20017, /** bad registration (not valid generally or for current product) */ LOCERR_BADREG = 20018, /** limited trial version */ LOCERR_LIMITED = 20019, /** connection timeout */ LOCERR_TIMEOUT = 20020, /** connection SSL certificate expired */ LOCERR_CERT_EXPIRED = 20021, /** connection SSL certificate invalid */ LOCERR_CERT_INVALID = 20022, /** incomplete sync session (some datastores or items have failed) */ LOCERR_INCOMPLETE = 20023, /** internal code signalling that client should retry sending message (instance buffer still contains the message) */ LOCERR_RETRYMSG = 20024, /** out of memory */ LOCERR_OUTOFMEM = 20025, /** we have no means to open a connection (such as phone flight mode etc.) */ LOCERR_NOCONN = 20026, /** connection (not TCP, but underlying PPP/GPRS/BT or whatever) cannot be established */ LOCERR_CONN = 20027, /** element is already installed */ LOCERR_ALREADY = 20028, /** this build is too new for this license (need upgrading license) */ LOCERR_TOONEW = 20029, /** function not implemented */ LOCERR_NOTIMP = 20030, /** this license code is valid, but not for this product */ LOCERR_WRONGPROD = 20031, /** explicitly suspended by user */ LOCERR_USERSUSPEND = 20032, /** this build is too old for this SDK/plugin */ LOCERR_TOOOLD = 20033, /** unknown subsystem */ LOCERR_UNKSUBSYSTEM = 20034, /** internal code signalling that next message will be a session restart (client should disconnect transport) */ LOCERR_SESSIONRST = 20035, /** local datastore is not ready (used to pop up alert) */ LOCERR_LOCDBNOTRDY = 20036, /** session should be restarted from scratch */ LOCERR_RESTART = 20037, /** internal pipe communication problem */ LOCERR_PIPECOMM = 20038, /** buffer too small for requested value */ LOCERR_BUFTOOSMALL = 20039, /** value truncated to fit into field or buffer */ LOCERR_TRUNCATED = 20040, /** bad parameter */ LOCERR_BADPARAM = 20041, /** out of range */ LOCERR_OUTOFRANGE = 20042, /** external transport failure (no details known in engine) */ LOCERR_TRANSPFAIL = 20043, /** class not registered */ LOCERR_CLASSNOTREG = 20044, /** interface not registered */ LOCERR_IIDNOTREG = 20045, /** bad URL */ LOCERR_BADURL = 20046, /** server not found */ LOCERR_SRVNOTFOUND = 20047, /** * ABORTDATASTORE() parameter to flag the current datastore as bad * without aborting the whole session. Exact reason for abort depends * on caller of that macro. */ LOCERR_DATASTORE_ABORT = 20048, /** cURL error code */ LOCERR_CURL = 21000, /** base code for linux signals (SIGXXX). SIGXXX enum value will be added to LOCERR_SIGNAL */ LOCERR_SIGNAL = 20500, /** TSyncException without specific error code set */ LOCERR_EXCEPTION = 20998, /** undefined error message */ LOCERR_UNDEFINED = 20999, /** * A range of error codes not used by the engine itself, start and * end included. Can be used to pass application specific error * codes from the DB layer up to the UI. */ APP_STATUS_CODE_START = 22000, APP_STATUS_CODE_END = 22999, /** * Local codes signalling SyncML status are shown as LOCAL_STATUS_CODE+. * This applies to codes >= LOCAL_STATUS_CODE and <= LOCAL_STATUS_CODE_END = 10599. * * For example, 500 = DB_Fatal = fatal error signaled by peer. * 10500 = LOCAL_STATUS_CODE + DB_Fatal = fatal error encountered locally. */ LOCAL_STATUS_CODE = 10000, LOCAL_STATUS_CODE_END = 10599 }; #ifdef __cplusplus } // namespace #endif #endif /* SYERROR_H */ /* eof */ libsynthesis-3.4.0.47.1/src/sysync_SDK/Sources/sync_dbapi.h000077500000000000000000001360601226375725500234040ustar00rootroot00000000000000/* * File: sync_dbapi.h * * Author: Beat Forster (bfo@synthesis.ch) * * C/C++ Programming interface between the * Synthesis SyncML engine and * the database layer for plug-ins * * Copyright (c) 2005-2011 by Synthesis AG + plan44.ch * */ /* * This is the calling interface between the Synthesis SyncML engine * and a customized module "sync_dbapi". * The same interface can be used either for Standard C or for C++. * And there is a equivalent interface for JNI (Java Native Interface). * Normally the customized module will be compiled as DLL and will * be called by the SyncML engine. A linkable library is available * (for C++) as well. * * For more detailed information about the DBApi interface * please consult the SDK_manual.pdf which contains a tutorial, * detailed descriptions and some example code. * * The flow for accessing the datastores is always the same: * The SyncML engine will call these routines step by step * * DATASTORE ACCESS FLOW * ===================== * * 1) CreateContext * 2) [ContextSupport] (optional) * 3) [FilterSupport] (optional) * 4) [Read Admin Data] (optional) * * 5) StartDataRead * 6) do ReadNextItem while (aStatus!=ReadNextItem_EOF); * 7) any number of random calls to: * - ReadItem * - ReadBlob * - [AdaptItem] (optional) * 8) EndDataRead * * 9) StartDataWrite * 10) any number of random calls to: * - InsertItem * - UpdateItem * - DeleteItem * - DeleteSyncSet * - ReadItem * - WriteBlob * - ReadBlob * - DeleteBlob * - [AdaptItem] (optional) * - FinalizeLocalID (at the end) * 11) EndDataWrite * * 12) [Write Admin Data] (optional) * 13) DeleteContext * * * NOTE: 'DisposeObj' calls can occur anywhere between any statement * of the flow above (but not before 'CreateContext' and not after * 'DeleteContext'). The SyncML engine is responsible for * disposing all and objects after use. * * NOTE: Returned errors (value > 0) will influence the flow * Error at 1) will not call any further step. * " " 2)..3) these functions do not return errors * " " 5)..10) will cause an 'EndDataWrite' call with * = false, then 'DeleteContext'. * " " 4) * 11)..12) 'DeleteContext' will be called afterwards. * * The module must be able to handle several contexts in parallel. * All routines will have an parameter (assigned by * 'CreateContext'), which allows to identify the correct context. * Routines can be called from different threads, but they are * always sequential for each context. If the thread changes, * 'ThreadMayChangeNow' will notify the module about this issue. * This routine can left empty and ignored, if not used. * * NOTE: As the SyncML engine calls the plug-in multithreaded, * all global structure accesses must be thread save. */ #ifndef SYNC_DBAPI_H #define SYNC_DBAPI_H /* Global declarations */ #include "sync_dbapidef.h" #if defined __cplusplus /* combine the definitions of different namespaces */ using sysync::sInt32; using sysync::uInt32; using sysync::CContext; using sysync::CVersion; using sysync::TSyError; using sysync::ItemID; using sysync::MapID; using sysync::cItemID; using sysync::cMapID; using sysync::appCharP; using sysync::cAppCharP; using sysync::appPointer; using sysync::memSize; using sysync::KeyH; using sysync::SDK_Interface_Struct; using sysync::DB_Callback; using sysync::UI_Call_In; #endif /* C/C++ and DLL/library support * SYSYNC_ENGINE : true ( within the engine itself ) / false ( outside ) * SYSYNC_ENGINE_TEST: true ( within a test engine module ) / false ( outside ) * DBAPI_LINKED : true ( at standalone APP, e.g. "helloX" ) / false ( within engine/within DLL ) * PLUGIN_INFO : true ( within "plugin_info" program ) / false ( everywhere else ) */ #if !defined SYSYNC_ENGINE && !defined SYSYNC_ENGINE_TEST && !defined DBAPI_LINKED && !defined PLUGIN_INFO && !defined DLL_EXPORT #define DLL_EXPORT 1 #endif #undef _ENTRY_ /* could be defined already here */ #ifdef DLL_EXPORT #define _ENTRY_ ENGINE_ENTRY #else #define _ENTRY_ #endif /* -- MODULE -------------------------------------------------------------------- */ /*! Create a module context \ * This routine will be called as the 2nd call, when the module will be connected. * (The 1st call is a 'Module_Version( 0 )' call outside any context). * * It will be called not only once, but once for each session and datastore context, * as defined at the XML config file. This routine can return error 20028 (LOCERR_ALREADY), * if already created. This will be treated not as an error. For this case, it must * return the same \ as for the former call(s). * * NOTE: The module context can exist once and can be shared for all plug-in accesses. * This can either be done with an allocated global variable at the plug-in or * even better using the "GlobContext" structure provided by the SyncML engine. * Please note, that write access to such a common module context structure must * be thread-safe, when accessed from the session or datastore context. * All the 'Module_CreateContext' calls for this module will be called * sequentially by one thread. The plug-in programmer is responsible not to * re-initialize the context for subsequent calls. * * If the module name at the XML config file is defined as "aaa!bbb!ccc" it will be passed * as "aaa" to \ and "bbb!ccc" to \. This mechanism can be used to * cascade plug-in modules, where the next module gets "bbb" as \ and "ccc" as * \. The JNI plug-in for Java is using this structure to address the JNI plug-in * and its assigned Java class. Error 20034 (LOCERR_UNKSUBSYSTEM) should be returned in case * the subsystem does not exist, no error if no subsystem has been chosen at all. * * * @param Returns a value, which allows to identify this module context. * Allowed values: Anything except 0, which is reserved for no context. * @param Name of this plug-in * @param Name of sub module (if available) * @param Name of the (datastore) context, e.g. "contacts"; * this string is empty for calll concerning the session. * @param DB_Callback structure for module logging * * @return error code if context could not be created (e.g. not enough memory) * LOCERR_ALREADY if global module context already exists (not treated as error) * 0 if context successfully created. */ _ENTRY_ TSyError Module_CreateContext( CContext *mContext, cAppCharP moduleName, cAppCharP subName, cAppCharP mContextName, DB_Callback mCB ); /*! Get the module's version. * * NOTE: The SyncML will take decisions depending on this version number, so * the plug-in developer should not change the values at the delivered sample code. * Plugin_Version( short buildNumber ) of 'SDK_util' should be used. * The \ can be defined by the user. * * NOTE: This function can be called by the engine outside any context with * \ = 0. For this case, any callback is not permitted (as no DB_Callback * is available). * * @param The module context ( 0, if none ). * @return current version as SDK_VERSION_MAJOR | SDK_VERSION_MINOR) * | SDK_SUBVERSION | buildNumber */ _ENTRY_ CVersion Module_Version( CContext mContext ); /*! Get the module's capabilities * Currently the SyncML engine currently understands and supports: * - "plugin_sessionauth" * - "plugin_deviceadmin" * - "plugin_datastoreadmin" * - "plugin_datastore" * * If one of these identifiers will be defined as "no" ( e.g. "plugin_sessionauth:no" ), * the according routines will not be connected and used. * * NOTE: The \ can be allocated with "StrAlloc" (SDK_util.h) for C/C++ * * @param The module context. * @param Returns the module's capabilities as multiline * aa:bb\cc:dd[\] * @return error code */ _ENTRY_ TSyError Module_Capabilities( CContext mContext, appCharP *mCapabilities ); /*! The module's config params will be sent to the plug-in. * It can be used for access path definitions or other things. * The \ can be defined individually for each session and datastore. * The SyncML engine checks the syntax, but not the content. * This routine should return an error 20010 (LOCERR_CFGPARSE), if one of * these parameters is not supported. * * EXAMPLE: Definition at XML config file:\n * \\n * \/var/log/sysync\\n * \42\\n * \ * * will be passed as:\n * "datapath:/var/log/sysync\n * ultimate_answer:42" * * NOTE: Module_PluginParams will be called ALWAYS for each module context, * even if no plug-in parameter is defined. This allows to react consistently * on parameters, which are not always available. * * @param The module context. * @param The plugin params as multiline aa:bb\cc:dd[\] * @param The SyncML engine's version * @return error code */ _ENTRY_ TSyError Module_PluginParams( CContext mContext, cAppCharP mConfigParams, CVersion engineVersion ); /*! Disposes memory, which has been allocated within the module context. * (At the moment this is only the capabilities string). * 'Module_DisposeObj' can occur at any time within \. * * NOTE: - If \ has been allocated with "StrAlloc", use "Str_Dispose" * (SDK_util.h) to release the memory again. * - If it is defined as const within the plugin module (the module * itself knows about !), this routine can be implemented empty. * * @param The module context. * @param Dispose allocated memory. * @return - */ _ENTRY_ void Module_DisposeObj( CContext mContext, void* memory ); /*! This routine will be called as the last call, before this module is disconnected. * The SyncML engine will call 'Module_DisposeObj' (if required) before this call * * NOTE: This routine will be called ONLY, if the server stops in a controlled way. * Its good programming practice not to wait for this 'DeleteContext' call. * * @param The module context. * @return error code */ _ENTRY_ TSyError Module_DeleteContext( CContext mContext ); /* -- SESSION ------------------------------------------------------------------- */ /*! By default the session context will be handled by the ODBC interface. * The session context of this plug-in module will be used only, * if \ and \ is defined * ( \name_of_the_plugin\ ). * \ can be defined individually. * * @param Returns a value, which allows to identify this session context. * @param Name of this session * @param DB_Callback structure for session logging * * @result error code, if context could not be created (e.g. not enough memory) * 0 if context successfully created, * * Flags (at the XML config file): * - \yes\: "Session_CheckDevice", "Session_GetNonce" * "Session_SaveNonce" and * "Session_SaveDeviceInfo" will be used. * * - \yes\: "Session_PasswordMode", * "Session_Login" and "Session_Logout" will be used. */ _ENTRY_ TSyError Session_CreateContext( CContext *sContext, cAppCharP sessionName, DB_Callback sCB ); /*! This function adapts itemData * * @param The session context * @param The 1st item's data * @param The 2nd item's data * @param The local vars * @param To identify, where it is called * * @return error code * * NOTE: The memory for adapted strings must be allocated locally. * The SyncML engine will call 'DisposeObj' later, to release again its memory. * One or more strings can be returned unchanged as well. */ _ENTRY_ TSyError Session_AdaptItem( CContext sContext, appCharP *sItemData1, appCharP *sItemData2, appCharP *sLocalVars, uInt32 sIdentifier ); /*! Check the database entry of \ and return its \ string. * If \ is not yet available at the plug-in, return "" for \ * * @param The session context * @param The assigned device ID string * @param The device key string (will be used for datastore accesses later) * @param The nonce string of the last session * If \ is not yet available, return "" for \ * and error code 0. * * @result error code 403 (Forbidden), if plugin_deviceadmin is not supported; * 0, if successful * * USED ONLY WITH \ */ _ENTRY_ TSyError Session_CheckDevice( CContext sContext, cAppCharP aDeviceID, appCharP *sDevKey, appCharP *nonce ); /*! Get a new nonce from the database. If this routine returns an error, * the SyncML engine will create its own nonce. * * @param The session context * @param A valid new nonce value (for the assigned device ID). * * @return error code 404 (NotFound), if no \ has been generated; * 0, if a valid \ has been generated * * USED ONLY WITH \ */ _ENTRY_ TSyError Session_GetNonce( CContext sContext, appCharP *nonce ); /*! Save the new nonce (which will be expected to be returned in the * next session for this device ID. * * @param The session context * @param New \ for the next session (of the assigned device ID) * * @result error code 403 (Forbidden), if plugin_deviceadmin is not supported; * 0, if successful * * USED ONLY WITH \ */ _ENTRY_ TSyError Session_SaveNonce( CContext sContext, cAppCharP nonce ); /*! Save the device info for \ * * @param The session context * @param More information about the assigned device (for DB and logging) * * @result error code 403 (Forbidden), if plugin_deviceadmin is not supported; * 0, if successful * * USED ONLY WITH \ */ _ENTRY_ TSyError Session_SaveDeviceInfo( CContext sContext, cAppCharP aDeviceInfo ); /*! Get the current DB time of \ * * @param The session context * @param The current time of the plugin's DB (as ISO8601 format). * * @result error code 403 (Forbidden), if plugin_deviceadmin is not supported; * 404 (NotFound), if not available -> the engine creates its own time * 0, if successful */ _ENTRY_ TSyError Session_GetDBTime( CContext sContext, appCharP *currentDBTime ); /*--------------------------------------------------------------------------------*/ /*! Get the password mode. * There are currently 4 different password modes supported. * * @param The session context * * @result * - Password_ClrText_IN : 'SessionLogin' will get clear text password * - Password_ClrText_OUT : " must return clear text password * - Password_MD5_OUT : " must return MD5 coded password * - Password_MD5_Nonce_IN: " will get MD5B64(MD5B64(user:pwd):nonce) * * USED ONLY WITH \ */ _ENTRY_ sInt32 Session_PasswordMode( CContext sContext ); /*! Get \ of \,\ in the session context. * * @param The session context * @param The user name ... * @param ... and the password. \ is an input parameter for 'Password_ClrTxt_IN' mode and an output parameter for * 'Password_ClrText_OUT' and 'Password_MD5_OUT' modes. * @param Returns the internal reference key, which will be passed to * to the datastore contexts later. * * @result error code 403 (Forbidden), if plugin_sessionauth is not supported; * 0, if successful * * USED ONLY WITH \ */ _ENTRY_ TSyError Session_Login( CContext sContext, cAppCharP sUsername, appCharP *sPassword, appCharP *sUsrKey ); /*! Logout for this session context * * @param The session context * * @result error code 403 (Forbidden), if plugin_sessionauth is not supported; * 0, if successful * * USED ONLY WITH \ */ _ENTRY_ TSyError Session_Logout( CContext sContext ); /*! Disposes memory, which has been allocated within the session context. * 'Session_DisposeObj' can occur at any time within \. * * @param The session context. * @param Dispose allocated memory. * * @return - */ _ENTRY_ void Session_DisposeObj( CContext sContext, void* memory ); /*! Due to the architecture of the SyncML engine, the system may run in a multithread * environment. The consequence is that each routine of this plugin module can be * called by a different thread. Normally this is not a problem, nevertheless * this routine notifies about thread changes in \. * It can be ignored ( =implemented empty), if not really needed. * * @param The session context * @return - */ _ENTRY_ void Session_ThreadMayChangeNow( CContext sContext ); /*! Writes the context of all items to dbg output path * This routine is implemented for debug purposes only and will NOT BE CALLED by the * SyncML engine. Can be implemented empty * * @param The session context * @param true : all fields, also empty ones, will be displayed; * false: only fields <> "" will be shown * @param "" : all items will be shown; * else shows the \ * * @return - */ _ENTRY_ void Session_DispItems( CContext sContext, bool allFields, cAppCharP specificItem ); /*! Delete a session context. * No access to \ will be done after this call * * @param The session context * @return error code, if context could not be deleted. */ _ENTRY_ TSyError Session_DeleteContext( CContext sContext ); /* -- OPEN ---------------------------------------------------------------------- */ /*! This routine is called to create a new context for a datastore access. * It must allocate all resources for this context and initialize the \ * parameter with a value that allows re-identifying the context. * \ can either be a pointer to the local context structure or any key * value which allows to re-identify the context later. * Subsequent calls related to this context will pass the \ value as returned * from CreateContext. The context must be valid until 'DeleteContext' is called. * \ can be defined individually. * * NOTE: The SyncML engine treats \ simply as a key. The only condition * is uniqueness for all datastore contexts. Even \ = 0 can be used. * * @param Returns a value, which allows to identify this datastore context. * @param Allows to identify the context, if more than one must be * handled. \ is defined at the XML configuration. * @param DB_Callback structure for datatstore logging. * @param The result of 'Session_CheckDevice' comes in here. * @param The result of 'Session_Login' comes in here. * * @return error code, if context could not be created (e.g. not enough memory), * 0 if context successfully created. */ _ENTRY_ TSyError CreateContext( CContext *aContext, cAppCharP aContextName, DB_Callback aCB, cAppCharP sDevKey, cAppCharP sUsrKey ); /*! This function asks for specific context configurations * * @param The datastore context * @param The SyncML sends a list of support rules. * This function has to reply, up to which rule, * contexts are supported (and switched on now). * Data is formatted as multiline aa:bb\cc:dd[\] * * @return Up to \ fields are supported (and switched on) for this context. * If 0 will be returned, no field of \ is supported. * */ _ENTRY_ uInt32 ContextSupport( CContext aContext, cAppCharP aSupportRules ); /*! This function asks for filter support. * * @param The datastore context * @param The SyncML sends a list of filter rules. * This function has to reply, up to which rule, * filters are supported (and switched on now). * Data is formatted as multiline aa:bb\cc:dd[\] * * @return Up to \ filters are supported (and switched on) for this context * If 0 will be returned, no field of \ are supported. */ _ENTRY_ uInt32 FilterSupport( CContext aContext, cAppCharP aFilterRules ); /* -- GENERAL ------------------------------------------------------------------- */ /*! Due to the architecture of the SyncML engine, the system may run in a multithread * environment. The consequence is that each routine of this API module can be * called by a different thread. Normally this is not a problem, nevertheless * this routine notifies about thread changes in \. * It can be ignored ( =implemented empty), if not really needed. * * @param The datastore context. * * @result - */ _ENTRY_ void ThreadMayChangeNow( CContext aContext ); /*! This functions writes \ for this context * Can be implemented empty, if not needed. * * @param The datastore context. * @param Logging information, formatted as multiline aa:bb\cc:dd[\] * * @result - */ _ENTRY_ void WriteLogData( CContext aContext, cAppCharP logData ); /*! Writes the context of all items to dbg output path * This routine is implemented for debug purposes only and will NOT BE CALLED by the * SyncML engine. Can be implemented empty, if not needed. * * @param The datastore context. * @param * - true : all fields, also empty ones, will be displayed; * - false: only fields <> "" will be shown * @param * - "" : all items will be shown; * - else : shows the \ * * @return - */ _ENTRY_ void DispItems( CContext aContext, bool allFields, cAppCharP specificItem ); /* -- ADMINISTRATION ------------------------------------------------------------ */ /* This section contains the 'admin read' and 'admin write' routines. */ /*! This function gets the stored information about the record with the four paramters: * \, \, \, \. * * - \yes\: Admin/Map routines will be used. * * @param The datastore context * @param Name of the local DB * @param Name of the remote DB * @param The data, saved with the last 'SaveAdminData' call * * @return error code 404 (NotFound), if record is not (yet) available, * 0 (no error) if admin data found * * NOTE: \ and \ have been passed with 'CreateContext' already. * The plug-in module must have stored them within the datastore context. * * USED ONLY WITH \ */ _ENTRY_ TSyError LoadAdminData ( CContext aContext, cAppCharP aLocDB, cAppCharP aRemDB, appCharP *adminData ); /*! This is the equivalent to 'LoadAdminData', but using a key instead of a data string */ _ENTRY_ TSyError LoadAdminDataAsKey( CContext aContext, cAppCharP aLocDB, cAppCharP aRemDB, KeyH aItemKey ); /*! This functions stores the new \ for this context * * @param The datastore context * @param The new set of admin data to be stored, will be loaded again * with the next 'LoadAdminData' call. * * @result error code, if data could not be saved (e.g. not enough memory); * 0 if successfully created. * * USED ONLY WITH \ */ _ENTRY_ TSyError SaveAdminData ( CContext aContext, cAppCharP adminData ); /*! This is the equivalent to 'SaveAdminData', but using a key instead of a data string */ _ENTRY_ TSyError SaveAdminDataAsKey( CContext aContext, KeyH aItemKey ); /*! Map table handling: Get the next map item of this context. * If \ is true, the routine must start to return the first element * * @param The datastore context * @param MapID ( with \,\, and \ ). * @param Starting with the first MapID. When creating a context, * the first call will get the first MapID, even if \ * is false. * * @return * - true: as long as there is a MapID available, which must be assigned to * - false: if there is no more MapID. Nothing must be assigned to * * USED ONLY WITH \ */ _ENTRY_ bool ReadNextMapItem( CContext aContext, MapID mID, bool aFirst ); /*! Map table handling: Insert a map item of this context * * @param The datastore context * @param MapID ( with \,\, \ and \ ). * * @return error code, if this MapID can't be inserted, or if already existing * * USED ONLY WITH \ */ _ENTRY_ TSyError InsertMapItem( CContext aContext, cMapID mID ); /*! Map table handling: Update a map item of this context * * @param The datastore context * @param MapID ( with \,\, \ and \ ). * If there is already a MapID element with \ and \, * it will be updated, else created. * * @return error code, if this MapID can't be updated (e.g. not yet existing). * * USED ONLY WITH \ */ _ENTRY_ TSyError UpdateMapItem( CContext aContext, cMapID mID ); /*! Map table handling: Delete a map item of this context * * @param The datastore context * @param MapID ( with \,\, \ and \ ). * * @return error code, if this MapID can't deleted, * or if this MapID does not exist. * * USED ONLY WITH \ */ _ENTRY_ TSyError DeleteMapItem( CContext aContext, cMapID mID ); /* -- READ ---------------------------------------------------------------------- */ /*! This routine initializes reading from the database * StartDataRead must prepare the database to return the objects of this context. * * @param The datastore context. * @param The value which has been returned by this module * at the last "EndDataWrite" call will be given. * It will be "", when called the first time. * Normally this token is an ISO8601 formatted string * which represents the module's current time (at the * beginning of a session). It will be used to decide at * 'ReadNextItem' whether a record has been changed. * @param Token for Suspend/Resume mode. * * @return error code */ _ENTRY_ TSyError StartDataRead( CContext aContext, cAppCharP lastToken, cAppCharP resumeToken ); /*! This routine reads the next ItemID from the database. * \ of 'ContextSupport' ( "ReadNextItem:allfields" ) and * \ of 'FilterSupport' must be considered. * If \ is true, the routine must return the first element (again). * * @param The datastore context. * @param The assigned ItemID in the database; * will be ignored by the SyncML engine, if \ = 0 * @param The data, formatted as multiline aa:bb\cc:dd[\]; * will be ignored by the SyncML engine, if \ = 0 * @param * - ReadItem_EOF ( =0 ) for none ( =eof ), * - ReadItem_Changed ( =1 ) for a changed item, * - ReadItem_Unchanged ( =2 ) for unchanged item. * - ReadItem_Resumed ( =3 ) for a changed item (since resumed) * @param * - true: the routine must return the first element * - false: the routine must return the next element * * @return error code, if not ok. No datasets found is a success as well ! * * * NOTE: The memory for \ and \ must be allocated locally. * The SyncML engine will call 'DisposeObj' later for these objects to * release the memory again. It needn't to be allocated, if \ * is ReadItem_EOF. * * NOTE: By default, the SyncML engine asks for \ only. * \ can be returned, if anyway available or * \ must be returned, if the engine asks for it * (when calling "ReadNextItem:allfields" at 'ContextSupport' with \). */ _ENTRY_ TSyError ReadNextItem ( CContext aContext, ItemID aID, appCharP *aItemData, sInt32 *aStatus, bool aFirst ); /*! This is the equivalent to 'ReadNextItem', but using a key instead of a data string */ _ENTRY_ TSyError ReadNextItemAsKey( CContext aContext, ItemID aID, KeyH aItemKey, sInt32 *aStatus, bool aFirst ); /*! This routine reads the contents of a specific ItemID \ from the database. * * @param The datastore context. * @param The assigned ItemID in the database * @param Returns the data, formatted as multiline aa:bb\cc:dd[\] * * @return error code, if not ok ( e.g. invalid \ ) * * * NOTE: The memory for \ must be allocated locally. * The SyncML engine will call 'DisposeObj' later for \, * to release again its memory. */ _ENTRY_ TSyError ReadItem ( CContext aContext, cItemID aID, appCharP *aItemData ); /*! This is the equivalent to 'ReadItem', but using a key instead of a data string */ _ENTRY_ TSyError ReadItemAsKey( CContext aContext, cItemID aID, KeyH aItemKey ); /*! This routine reads the specific binary logic block \,\ * from the database. * * @param The datastore context. * @param ItemID ( with \,\ ). * @param The assigned ID of the blob. * * @param Position and size (in bytes) of the blob block. * @param * - Input: Maximum size (in bytes) of the blob block to be read. * If \ is 0, the result size is not limited. * - Output: Size (in bytes) of the blob block. * \ must not be larger than its input value. * @param Total size of the blob (in bytes), can be also 0, * if not available, e.g. for a stream. * * @param (Input) * - true : Engine asks for the first block of this blob. * - false: Engine asks for the next block of this blob. * * @param (Output) * - true : This is the last part (or the whole) blob. * - false: More blocks will follow. * * @return error code, if not ok ( e.g. invalid \,\ ) * * * NOTE 1) The memory at \,\ must be allocated locally. * The SyncML engine will call 'DisposeObj' later for \, * to release the memory. * * NOTE 2) Empty blobs are allowed, \ and \ must be set to 0, * \ can be undefined, \ must be true. * No 'DisposeObj' call is required for this case. * * NOTE 3) The SyncML engine can change to read another blob before * having read the whole blob. It will never resume reading of this * incomplete blob, but start reading again with \ = true. */ _ENTRY_ TSyError ReadBlob( CContext aContext, cItemID aID, cAppCharP aBlobID, appPointer *aBlkPtr, memSize *aBlkSize, memSize *aTotSize, bool aFirst, bool *aLast ); /*! This routine terminates the read from database phase * It can be used e.g. for termination of a transaction. * In standard case it can be implemented empty, returning simply a value LOCERR_OK = 0. * * @param The datastore context. * @return error code */ _ENTRY_ TSyError EndDataRead( CContext aContext ); /* -- WRITE --------------------------------------------------------------------- */ /*! This routine initializes writing to the database * * @param The datastore context. * @return error code, if not ok (e.g. invalid select options) */ _ENTRY_ TSyError StartDataWrite( CContext aContext ); /*! This routine inserts a new dataset to the database. The assigned * new ItemID \ will be returned. * * @param The datastore context. * @param The data, formatted as multiline aa:bb\cc:dd[\] * @param Database key of the new dataset. * * @return error code * - LOCERR_OK ( =0 ), if successful * - DB_DataMerged ( =207 ), if successful, but item actually stored * was updated with data from * external source or another * sync set item. Engine will * request updated version * using ReadItem. * (server add case only) * - DB_DataReplaced ( =208 ), if successful, but item added replaces * another item that already * existed in the sync set. * (server add case only) * - DB_Conflict ( =409 ), if database requests engine to merge * existing data with the * to-be stored data first. * - DB_Forbidden ( =403 ), if \ can't be resolved * - DB_Full ( =420 ), if not enough space in the DB * - ... or any other SyncML error code, see Reference Manual * * NOTE: The memory for \ must be allocated locally. * The SyncML engine will call 'DisposeObj' later for \, * to release the memory * */ _ENTRY_ TSyError InsertItem ( CContext aContext, cAppCharP aItemData, ItemID aID ); /*! This is the equivalent to 'InsertItem', but using a key instead of a data string */ _ENTRY_ TSyError InsertItemAsKey( CContext aContext, KeyH aItemKey, ItemID aID ); /*! This routine updates an existing dataset of the database * * @param The datastore context. * @param The data, formatted as multiline aa:bb\cc:dd[\] * @param Database key of dataset to be updated * @param * - Input: NULL is assigned as default value to * \ and \. * - Output: The updated database key for \. * Can be NULL, if the same as \ * * @return error code * - LOCERR_OK ( =0 ), if successful * - DB_Forbidden ( =403 ), if \ can't be resolved * - DB_NotFound ( =404 ), if unknown \ * - DB_Full ( =420 ), if not enough space in the DB * - ... or any other SyncML error code, see Reference Manual * * * NOTE: \ must either contain NULL references ( if the same as \ ), * or the memory for \,\ must be allocated locally. * The SyncML engine will call 'DisposeObj' later for \ and * \ to release the memory. * \ can be NULL, if the hierarchical model is not supported. */ _ENTRY_ TSyError UpdateItem ( CContext aContext, cAppCharP aItemData, cItemID aID, ItemID updID ); /*! This is the equivalent to 'UpdateItem', but using a key instead of a data string */ _ENTRY_ TSyError UpdateItemAsKey( CContext aContext, KeyH aItemKey, cItemID aID, ItemID updID ); /*! This routine moves \ from \ to \ * * @param The datastore context. * @param ItemID ( with \,\ ) to be moved. * @param New parent ID for \ * * @return error code * - LOCERR_OK ( =0 ), if successful * - DB_NotFound ( =404 ), if unknown \ * - DB_Full ( =420 ), if not enough space in the DB * - ... or any other SyncML error code, see Reference Manual */ _ENTRY_ TSyError MoveItem( CContext aContext, cItemID aID, cAppCharP newParID ); /*! This routine deletes a dataset from the database * * @param The datastore context. * @param ItemID ( with \,\ ) to be deleted. * * @return error code * - LOCERR_OK ( =0 ), if successful * - DB_NotFound ( =404 ), if unknown \ * - ... or any other SyncML error code, see Reference Manual */ _ENTRY_ TSyError DeleteItem( CContext aContext, cItemID aID ); /*! This routine updates a temporary to an at the end * For cached systems which assign IDs at the end of a run. * * @param The datastore context. * @param Database key of dataset to be updated * @param * - Input: NULL is assigned as default value to * \ and \. * - Output: The updated database key for \. * Can be NULL, if the same as \ * * @return error code * - LOCERR_OK ( =0 ), if successful * - DB_Forbidden ( =403 ), if \ can't be resolved * - DB_NotFound ( =404 ), if unknown \ * - LOCERR_NOTIMP ( =20030 ), if no finalizing is needed at all * - ... or any other SyncML error code, see Reference Manual * * NOTE: \ must either contain NULL references ( if the same as \ ), * or the memory for \ must be allocated locally. * The SyncML engine will call 'DisposeObj' later for \ * to release the memory. \should be always NULL. */ _ENTRY_ TSyError FinalizeLocalID( CContext aContext, cItemID aID, ItemID updID ); /*! This routine deletes all datasets from the database * * @param The datastore context. * * @return error code * - LOCERR_OK ( =0 ), if successful * - LOCERR_NOTIMP ( =20030 ). For this case, the engine removes all items directly * - ... or any other SyncML error code, see Reference Manual */ _ENTRY_ TSyError DeleteSyncSet( CContext aContext ); /*! This routine writes the specific binary logic block \ to the database. * * @param The datastore context. * @param ItemID ( with \,\ ). * @param The assigned ID of the blob. * * @param * @param Position and size (in bytes) of the blob block. * @param Total size of the blob (in bytes), * Can be also 0, if not available, e.g. for a stream. * * @param * - true : this is the first block of the blob. * - false: this is the next block. * @param * - true : this is the last block. * - false: more blocks will follow. * * @return error code, if not ok ( e.g. invalid \,\ ) * * NOTE: Empty blobs are possible, \ and \ will be set to 0, * \ will be NULL, \ and \ will be true. */ _ENTRY_ TSyError WriteBlob( CContext aContext, cItemID aID, cAppCharP aBlobID, appPointer aBlkPtr, memSize aBlkSize, memSize aTotSize, bool aFirst, bool aLast ); /*! This routine deletes the specific binary logic block \ at the database. * * @param The datastore context. * @param ItemID ( with \,\ ). * @param The assigned ID of the blob. * * @return error code, if not ok ( e.g. invalid \,\ ) */ _ENTRY_ TSyError DeleteBlob( CContext aContext, cItemID aID, cAppCharP aBlobID ); /*! Advises the database to finsish the running transaction * * @param The datastore context. * @param * - true: All former actions were successful, * so the database can commit * - false: The transaction was not successful, * so the database may rollback or ignore the transaction. * * @param An internally generated string value, which * will be used to identify changed database records. * It is normally an ISO8601 formatted string, which * represents the module's current time (at the * time the 'StartDataRead' of this context has been * called). All changed records of the currrent context * must get this token as timestamp as as well. * The SyncML engine will return this value with the * 'StartDataRead' call within the next session. * It must return NULL in case of no \. * * @return error code, if operation can't be performed. No \ is not an error. * * * NOTE: By default, the SyncML engine expects an ISO8601 string for \. * But the SyncML engine can be configured to treat this value completely * opaque, if implemented in a different way. * * The \ must be allocated locally and will be * disposed with a 'DisposeObj' call later by the SyncML engine. */ _ENTRY_ TSyError EndDataWrite( CContext aContext, bool success, appCharP *newToken ); /* ---- ADAPT ITEM -------------------------------------------------------------- */ /*! This function adapts aItemData * * @param The datastore context * @param The 1st item's data * @param The 2nd item's data * @param The local vars * @param To identify, where it is called * * @return error code * * NOTE: The memory for adapted strings must be allocated locally. * The SyncML engine will call 'DisposeObj' later, to release again its memory. * One or more strings can be returned unchanged as well. */ _ENTRY_ TSyError AdaptItem( CContext aContext, appCharP *aItemData1, appCharP *aItemData2, appCharP *aLocalVars, uInt32 aIdentifier ); /* -- DISPOSE / CLOSE ----------------------------------------------------------- */ /*! Disposes memory, which has been allocated within the datastore context. * 'DisposeObj' can occur at any time within \. * * @param The datastore context. * @param Dispose allocated memory. * * @return - * */ _ENTRY_ void DisposeObj( CContext aContext, void* memory ); /*! This routine is called to delete a context, that was previously created with * 'CreateContext'. The DB Module must free all resources related to this context. * No calls with \ will be done after calling this routine, so the * assigned structure, allocated at 'CreateContext' can be released here. * * @param The datastore context. * * @result error code, if context could not be deleted ( e.g. not existing \ ). */ _ENTRY_ TSyError DeleteContext( CContext aContext ); #endif /* eof */ libsynthesis-3.4.0.47.1/src/sysync_SDK/Sources/sync_dbapidef.h000077500000000000000000000771511226375725500240700ustar00rootroot00000000000000/* * File: sync_dbapidef.h * * Author: Beat Forster (bfo@synthesis.ch) * * C/C++ Programming interface between * the Synthesis SyncML engine * and the database layer * * Copyright (c) 2004-2011 by Synthesis AG + plan44.ch * * * These are the definitions for the calling interface between the * Synthesis SyncML engine and a customized module "sync_dbapi". * The same interface can be used either for Standard C or for C++. * Normally the customized module will be compiled as DLL and will * be called by the SyncML engine. A linkable library is available * (for C++) as well. * */ /* NOTE: As this file should work for all kind of plain C compilers * comments with double slashes "//" must be avoided !! */ #ifndef SYNC_DBAPIDEF_H #define SYNC_DBAPIDEF_H #include "sync_include.h" #include "sync_declarations.h" /* export prefix and suffix is dependent on platform and source language */ #ifdef __cplusplus #define ENTRY_C extern "C" #else #define ENTRY_C #endif #if defined MACOSX #define ENGINE_ENTRY ENTRY_C #define ENGINE_ENTRY_CXX #ifdef __GNUC__ #define ENTRY_ATTR __attribute__((visibility("default"))) #else #define ENTRY_ATTR #endif #elif defined _MSC_VER /* Visual Studio 2005 requires a specific entry point definition */ /* This definition is empty for all other platforms */ #define ENGINE_ENTRY ENTRY_C _declspec(dllexport) #define ENGINE_ENTRY_CXX ENGINE_ENTRY #define ENTRY_ATTR #else #define ENGINE_ENTRY ENTRY_C #define ENGINE_ENTRY_CXX #define ENTRY_ATTR #endif /* compose name of external symbols with C binding: * by default use parameter as-is (backwards compatibility) for client, * and use "SySync_srv_" prefix for server. * Newer builds usually use "SySync_" as prefix for client entry points. * can be changed in any file that is included before * this file */ #ifndef SYSYNC_EXTERNAL # define SYSYNC_EXTERNAL(_x) _x # define SYSYNC_PREFIX "" #endif #ifndef SYSYNC_EXTERNAL_SRV # define SYSYNC_EXTERNAL_SRV(_x) SySync_srv_ ## _x # define SYSYNC_PREFIX_SRV "SySync_srv_" #endif #ifdef __cplusplus namespace sysync { #endif /* ---- Plugin versions ------------------------------------------------------------------------------- */ /* To make the SyncML engine and the Plugin SDK upwards/downwards compatible to each other, * some version info must be checked and compared: VP_XXX is the min version of the plugin to * support a certain feature, VE_XXX is the min version of the engine to support a feature. * The plugin will get the engine's version with "Plugin_Params". * The version number for engine AND plugin is defined as SDK_VERSION/SUBVERSION at "SDK_util.c" * Normally, the version number of the engine must be equal or higher than the plugin's version. */ /* ---- Plugin support ---- */ /* For the first versions, "N" is the platform identifier */ enum Version { /*VP_Init 0x01000000 * V1.0.N.0 : Initial version */ /*VP_1st 0x01000002 * V1.0.N.2 : 1st delivered version */ /*VP_Session_Login 0x01000003 * V1.0.N.3 : VAR_String for Session_Login: this version only */ /*VP_EngineVersionParam 0x01000004 * V1.0.N.4 : param for "Module_PluginParams" */ /*VP_CB_Version2 = 0x01000005 * V1.0.N.5 : Callback version >= 2 supported */ /** V1.0.N.6 : With new function "DeleteBlob" */ VP_DeleteBlob = 0x01000006, /** V1.0.N.7 : With new "scripting" function "AdaptItemData" */ VP_AdaptItemData = 0x01000007, /** V1.0.N.8 : Supports "InsertMapItem" */ VP_InsertMapItem = 0x01000008, /* From now on, the platform info can be found at he capabilities, "X" is a user defined build nr */ /** V1.0.5.X : "X": With customer defined plugin build number */ VP_NewBuildNumber = 0x01000500, /** V1.0.6.X : Suspend/Resume extension for 'StartDataRead' */ VP_ResumeToken = 0x01000600, /** V1.0.8.X : "Session_GetDBTime" supported */ VP_GetDBTime = 0x01000800, /** V1.0.9.X : Callback version >= 3 supported: exotic */ VP_CB_Version3 = 0x01000900, /** V1.0.10.X: Callback version >= 4 supported: allowDLL */ VP_CB_Version4 = 0x01000a00, /** V1.0.10.X: With enhanced "scripting" function "AdaptItem" */ VP_AdaptItem = 0x01000a00, /* The new SyncML engine V2.9.X/V3.X.X runs best with versions from here onwards */ /** V1.1.0.X : Enhanced Plugin Info support: Server > 2.9.5.0 */ VP_Plugin_Info = 0x01010000, /** V1.2.1.X : With additional password mode + JNI adaption */ VP_MD5_Nonce_IN = 0x01020100, /*VP_061012 0x01020200 * V1.2.2 : Released 12-Oct-06 */ /*VP_061207 0x01030000 * V1.3.0 : Released 07-Dec-06, Visual Studio support */ /** V1.3.1.X : With UI function support */ VP_UI_Support = 0x01030100, /*VP_070131 0x01030200 * V1.3.2 : Released 31-Jan-07 */ /*VP_070201 0x01030300 * V1.3.3 : Released 01-Feb-07 */ /** V1.3.4.X : Java Callback with */ VP_Call_cContext = 0x01030400, /** V1.3.4.X : Callback version >= 7 supported: UI / thisCB */ VP_CB_Version7 = 0x01030400, /*VP_070212 0x01030600 * V1.3.6.X : Released 12-Feb-07 */ /** V1.3.8.X : Support for GlobContext structure */ VP_GlobContext = 0x01030800, /** V1.3.9.X : Callback version >= 8 supported: extended UI */ VP_CB_Version8 = 0x01030900, /** V1.4.0.X : With UI application support / Beta release */ VP_UIApp = 0x01040000, /** V1.4.7.X : Callback version >= 9 supported: dbapi tunnel */ VP_CB_Version9 = 0x01040700, /** V1.4.8.X : "FinalizeLocalID"/"DeleteSyncSet" support. */ VP_FLI_DSS = 0x01040800, /** V1.5.0.X : Released version Aug 2008 */ VP_Release_1_5_0 = 0x01050000, /** V1.5.1.X : Multiple global contexts supported */ VP_GlobMulti = 0x01050100, /** V1.5.2.X : Callback version >= 11 supported: dbapi tunnel */ VP_CB_Version11 = 0x01050200, /** V1.6.0.X : Tunnel support */ VP_Tunnel = 0x01060000, /** V1.6.1.X : Correct SetValue support */ VP_SetValue = 0x01060100, /** V1.6.2.X : 64 bit Java BLOB signature */ VP_BLOB_JSignature = 0x01060200, /*VP_091221 0x01060200 * V1.6.2 : Released 21-Dec-09 */ /** V1.7.0.X : First release of the Android client */ VP_Android_1st_Release = 0x01070000, /*VP_100429 0x01070000 * V1.7.0 : Released 29-Apr-10 */ /* 0x01070200 * V1.7.2 : never released as SDK */ VP_ADMIN_AS_KEY = 0x01080000, /*VP_110131 = 0x01090000 * V1.9.0 : Released 31-Jan-11 (Android) */ /** V1.9.1.X : Current version, use 'Plugin_Version()' */ VP_CurrentVersion = 0x01090100, /** -------- : Bad/undefined version */ VP_BadVersion = 0xffffffff, /* ---- Engine support ---- */ /** V1.0.7.0 : Engine supports "InsertMapItem" */ VE_InsertMapItem = 0x01000700 }; /* ---- Function names -------------------------------------------------------------------------------- */ /* ---- module ---- */ #define Mo_CC "Module_CreateContext" #define Mo_Ve "Module_Version" #define Mo_Ca "Module_Capabilities" #define Mo_PP "Module_PluginParams" #define Mo_DO "Module_DisposeObj" #define Mo_DC "Module_DeleteContext" /* ---- session ---- */ #define Se_CC "Session_CreateContext" #define Se_TC "Session_ThreadMayChangeNow" #define Se_DI "Session_DispItems" #define Se_CD "Session_CheckDevice" #define Se_GN "Session_GetNonce" #define Se_SN "Session_SaveNonce" #define Se_SD "Session_SaveDeviceInfo" #define Se_GT "Session_GetDBTime" #define Se_PM "Session_PasswordMode" #define Se_LI "Session_Login" #define Se_LO "Session_Logout" #define Se_DO "Session_DisposeObj" #define Se_DC "Session_DeleteContext" /* ---- datastore ---- */ #define Da_CC "CreateContext" #define Da_CS "ContextSupport" #define Da_FS "FilterSupport" #define Da_LA "LoadAdminData" #define Da_LAK "LoadAdminDataAsKey" #define Da_SA "SaveAdminData" #define Da_SAK "SaveAdminDataAsKey" #define Da_RM "ReadNextMapItem" #define Da_IM "InsertMapItem" #define Da_UM "UpdateMapItem" #define Da_DM "DeleteMapItem" #define Da_TC "ThreadMayChangeNow" #define Da_DI "DispItems" #define Da_WL "WriteLogData" #define Da_SR "StartDataRead" #define Da_RN "ReadNextItem" #define Da_RNK "ReadNextItemAsKey" #define Da_RI "ReadItem" #define Da_RIK "ReadItemAsKey" #define Da_RB "ReadBlob" #define Da_ER "EndDataRead" #define Da_SW "StartDataWrite" #define Da_II "InsertItem" #define Da_IIK "InsertItemAsKey" #define Da_UI "UpdateItem" #define Da_UIK "UpdateItemAsKey" #define Da_MvI "MoveItem" #define Da_DeI "DeleteItem" #define Da_DSS "DeleteSyncSet" #define Da_FLI "FinalizeLocalID" #define Da_WB "WriteBlob" #define Da_DB "DeleteBlob" #define Da_EW "EndDataWrite" #define Da_DO "DisposeObj" #define Da_DC "DeleteContext" /* ---- Predefined capability names ------------------------------------------------------------------- */ #define CA_MinVersion "MINVERSION" /* Minimum requested engine version by the plugin */ #define CA_SubVersion "SUBVERSION" /* version of the sub system */ #define CA_SubSystem "SUBSYSTEM" /* Name of the sub system, used as capability separator */ #define CA_Manufacturer "MANUFACTURER" /* Name of the plugin manufacturer */ #define CA_Description "DESCRIPTION" /* A short description, what the plugin module is doing */ #define CA_Platform "PLATFORM" /* The software platform, e.g. "Windows", "Java", ... */ #define CA_DLL "DLL" /* Indicates, if plugin is a DLL */ #define CA_JNI "JNI" /* Indicates, if plugin is based on JNI */ #define CA_CSHARP "C#" /* Indicates, if plugin is based on C# */ #define CA_GUID "GUID" /* GUID */ #define CA_Plugin "PLUGIN" /* Built-In plugin name */ #define CA_GlobContext "GlobContext" /* The global context, if available */ #define CA_ADMIN_Info "ADMIN_Info" /* Get ADMIN info as "ADMIN" with 'CreateContext' */ /* (supported for V1.3.7 and higher) */ #define CA_ItemAsKey "ITEM_AS_KEY" /* Supports the AsKey" mode */ #define CA_AdminAsKey "ADMIN_AS_KEY" /* Supports the AsKey" mode for Load/SaveAdminData */ #define CA_DeleteSyncSet "DeleteSyncSet"/* DeleteSyncSet ist fully implemented */ #define CA_ResumeSupported "ResumeSupported" /* InsertMapItem is functional, defaults to "yes" if the method is available. Can be used to override its usage. */ #define CA_Error "ERROR" /* Capability error */ /* Predefined identifiers */ #define ADMIN_Ident " ADMIN" /* Appended identifier for admin datastore recognition */ /* Activated with capability CA_ADMIN_Info */ /* ---- Allow to switch off certain parts of the plug-in module --------------------------------------- */ #define Plugin_Start "plugin_start" #define Plugin_Param "plugin_param" #define Plugin_Session "plugin_se" #define Plugin_SE_Adapt "plugin_sessionadapt" #define Plugin_SE_Auth "plugin_sessionauth" #define Plugin_DV_Admin "plugin_deviceadmin" #define Plugin_DV_DBTime "plugin_dbtime" #define Plugin_Datastore "plugin_ds" #define Plugin_DS_General "plugin_datageneral" #define Plugin_DS_Admin "plugin_datastoreadmin" #define Plugin_DS_Admin_Str "plugin_datastoreadmin_str" #define Plugin_DS_Admin_Key "plugin_datastoreadmin_key" #define Plugin_DS_Admin_Map "plugin_datastoreadmin_map" #define Plugin_DS_Data "plugin_datastore" #define Plugin_DS_Data_Str "plugin_datastore_str" #define Plugin_DS_Data_Key "plugin_datastore_key" #define Plugin_DS_Blob "plugin_datablob" #define Plugin_DS_Adapt "plugin_dataadapt" #define Plugin_UI "plugin_ui" /* Compatibility to older versions */ #define Plugin_SE_Auth_OLD "plugin_sessionauth_OLD" #define Plugin_DS_Data_OLD1 "plugin_datastore_OLD1" #define Plugin_DS_Data_OLD2 "plugin_datastore_OLD2" #define Plugin_DS_Admin_OLD "plugin_datastoreadmin_OLD" #define Plugin_DS_Blob_OLD1 "plugin_datablob_OLD1" #define Plugin_DS_Blob_OLD2 "plugin_datablob_OLD2" /* ---------------------------------------------------------------------------------------------------- */ /*! Item and its special definitions */ #define StdPattern ":" /* std identifier */ #define ArrayPattern "[" /* array identifier */ #define BlobPattern ";BLOBID=" /* blob identifier */ #define TZNamePattern ";TZNAME=" /* tzname identifier */ #define TZOffsPattern ";TZOFFS=" /* tzoffs identifier */ /*! Result value of Session_PasswordMode */ enum PasswordMode { Password_Mode_Undefined = -1, /* undefined mode */ Password_ClrText_IN = 0, Password_ClrText_OUT = 1, Password_MD5_OUT = 2, /* MD5B64(user:pwd) */ Password_MD5_Nonce_IN = 3, /* MD5B64(MD5B64(user:pwd):nonce) */ }; /*! Result status of ReadNextItem */ enum ReadNextItemResult { ReadNextItem_EOF = 0, /* no more items to read */ ReadNextItem_Changed = 1, ReadNextItem_Unchanged = 2, ReadNextItem_Resumed = 3, /* OMA DS 1.2 suspend/resume support */ }; /*! Structure of hierarchical item ID */ struct ItemIDType { appCharP item; appCharP parent; }; /*! Structure of map ID */ struct MapIDType { appCharP localID; appCharP remoteID; uInt16 flags; uInt8 ident; }; /*! Structure of GlobContext */ struct GlobContext { void* ref; /* reference field */ struct GlobContext* next; /* reference to the next GlobContext structure */ uInt32 cnt; /* link count */ char refName[ 80 ]; /* the reference's name, length restricted */ }; #define GlobContext_JavaVM "JavaVM" /*! Undefined function for place holder at 'ConnectFunctions', must have pointer size */ #define XX (char *)-1 /* ---- CALLBACK / CALL-IN -------------------------------------------------------- */ /*! The callback structure allows logging of debug information within the * files of the Synthesis SyncML engine. 'CreateContext' for module, session * and datastore will pass a reference to such a struct. * The same structure contains all call-in functions for the UI Api. */ /** * : Reserved plugin specific bit masks. * These flags are only used by the SDK_util logging helper functions. * They are *not* passed into the Synthesis engine and thus cannot * control how the logged text is stored in the log file. */ enum DebugFlags { /** No debugging */ DBG_PLUGIN_NONE = 0x0000, /** Engine internal calls for plugin interface */ DBG_PLUGIN_INT = 0x0001, /** DB access calls, standard for all plugin examples */ DBG_PLUGIN_DB = 0x0002, /** DB access calls, exotic calls as well */ DBG_PLUGIN_EXOT = 0x0004, /** direct printf calls for test */ DBG_PLUGIN_DIRECT= 0x0008, /** GetValue/SetValue debugging */ DBG_GET_SET_VALUE= 0x0010, /** Default mask: all bits set */ DBG_PLUGIN_ALL = 0xffff, }; /*! Function prototypes for Debug calls */ typedef void (*DB_DebugPuts_Func) ( void* aCallbackRef, cAppCharP aText ); typedef void (*DB_DebugExotic_Func) ( void* aCallbackRef, cAppCharP aText ); typedef void (*DB_DebugBlock_Func) ( void* aCallbackRef, cAppCharP aTag, cAppCharP aDesc, cAppCharP aAttrText ); typedef void (*DB_DebugEndBlock_Func) ( void* aCallbackRef, cAppCharP aTag ); typedef void (*DB_DebugEndThread_Func)( void* aCallbackRef ); /* Function prototypes for UI call-in */ /* ---- Engine init ---- */ typedef TSyError (*SetStringMode_Func) ( void* aCB, uInt16 aCharSet, uInt16 aLineEndMode, bool aBigEndian ); typedef TSyError (*InitEngineXML_Func) ( void* aCB, cAppCharP aConfigXML ); typedef TSyError (*InitEngineFile_Func) ( void* aCB, cAppCharP aConfigFilePath ); typedef TSyError (*InitEngineCB_Func) ( void* aCB, TXMLConfigReadFunc aReaderFunc, void* aContext ); /* ---- Running a Sync Session ---- */ typedef TSyError (*OpenSession_Func) ( void* aCB, SessionH *aSessionH, uInt32 aSelector, cAppCharP aSessionName ); typedef TSyError (*OpenSessionKey_Func) ( void* aCB, SessionH aSessionH, KeyH *aKeyH, uInt16 aMode ); typedef TSyError (*SessionStep_Func) ( void* aCB, SessionH aSessionH, uInt16 *aStepCmd, TEngineProgressInfo *aInfoP ); typedef TSyError (*GetSyncMLBuffer_Func) ( void* aCB, SessionH aSessionH, bool aForSend, appPointer *aBuffer, memSize *aBufSize ); typedef TSyError (*RetSyncMLBuffer_Func) ( void* aCB, SessionH aSessionH, bool aForSend, memSize aRetSize ); typedef TSyError (*ReadSyncMLBuffer_Func) ( void* aCB, SessionH aSessionH, appPointer aBuffer, memSize aBufSize, memSize *aValSize ); typedef TSyError (*WriteSyncMLBuffer_Func)( void* aCB, SessionH aSessionH, appPointer aBuffer, memSize aValSize ); typedef TSyError (*CloseSession_Func) ( void* aCB, SessionH aSessionH ); /* ---- Settings access ---- */ typedef TSyError (*OpenKeyByPath_Func) ( void* aCB, KeyH *aKeyH, KeyH aParentKeyH, cAppCharP aPath, uInt16 aMode ); typedef TSyError (*OpenSubkey_Func) ( void* aCB, KeyH *aKeyH, KeyH aParentKeyH, sInt32 aID, uInt16 aMode ); typedef TSyError (*DeleteSubkey_Func) ( void* aCB, KeyH aParentKeyH, sInt32 aID ); typedef TSyError (*GetKeyID_Func) ( void* aCB, KeyH aKeyH, sInt32 *aID ); typedef TSyError (*SetTextMode_Func) ( void* aCB, KeyH aKeyH, uInt16 aCharSet, uInt16 aLineEndMode, bool aBigEndian ); typedef TSyError (*SetTimeMode_Func) ( void* aCB, KeyH aKeyH, uInt16 aTimeMode ); typedef TSyError (*CloseKey_Func) ( void* aCB, KeyH aKeyH ); typedef TSyError (*GetValue_Func) ( void* aCB, KeyH aKeyH, cAppCharP aValName, uInt16 aValType, appPointer aBuffer, memSize aBufSize, memSize *aValSize ); typedef TSyError (*GetValueByID_Func) ( void* aCB, KeyH aKeyH, sInt32 aID, sInt32 arrIndex, uInt16 aValType, appPointer aBuffer, memSize aBufSize, memSize *aValSize ); typedef sInt32 (*GetValueID_Func) ( void* aCB, KeyH aKeyH, cAppCharP aName ); typedef TSyError (*SetValue_Func) ( void* aCB, KeyH aKeyH, cAppCharP aValName, uInt16 aValType, cAppPointer aBuffer, memSize aValSize ); typedef TSyError (*SetValueByID_Func) ( void* aCB, KeyH aKeyH, sInt32 aID, sInt32 arrIndex, uInt16 aValType, cAppPointer aBuffer, memSize aValSize ); /* ---- Function prototypes for DBApi ------------------------------------------------------------------- */ typedef TSyError (*SDR_Func)( CContext ac, cAppCharP lastToken, cAppCharP resumeToken ); typedef TSyError (*RdNItemSFunc)( CContext ac, ItemID aID, appCharP *aItemData, sInt32 *aStatus, bool aFirst ); typedef TSyError (*RdNItemKFunc)( CContext ac, ItemID aID, KeyH aItemKey, sInt32 *aStatus, bool aFirst ); typedef TSyError (*Rd_ItemSFunc)( CContext ac, cItemID aID, appCharP *aItemData ); typedef TSyError (*Rd_ItemKFunc)( CContext ac, cItemID aID, KeyH aItemKey ); typedef TSyError (*EDR_Func)( CContext ac ); typedef TSyError (*SDW_Func)( CContext ac ); typedef TSyError (*InsItemSFunc)( CContext ac, cAppCharP aItemData, ItemID aID ); typedef TSyError (*InsItemKFunc)( CContext ac, KeyH aItemKey, ItemID aID ); typedef TSyError (*UpdItemSFunc)( CContext ac, cAppCharP aItemData, cItemID aID, ItemID updID ); typedef TSyError (*UpdItemKFunc)( CContext ac, KeyH aItemKey, cItemID aID, ItemID updID ); typedef TSyError (*MovItem_Func)( CContext ac, cItemID aID, cAppCharP newParID ); typedef TSyError (*DelItem_Func)( CContext ac, cItemID aID ); typedef TSyError (*FLI_Func)( CContext ac, cItemID aID, ItemID updID ); typedef TSyError (*DelSS_Func)( CContext ac ); typedef TSyError (*EDW_Func)( CContext ac, bool success, appCharP *newToken ); typedef void (*DisposeProc)( CContext xContext, void* memory ); /* ------------------------------------------------------------------------------------------------------ */ /*!< UI Api methods * NOTE: As this struct is part of the SDK_Interface_Struct, it is frozen and not directly extendable */ typedef struct { SetStringMode_Func SetStringMode; InitEngineXML_Func InitEngineXML; InitEngineFile_Func InitEngineFile; InitEngineCB_Func InitEngineCB; OpenSession_Func OpenSession; OpenSessionKey_Func OpenSessionKey; SessionStep_Func SessionStep; GetSyncMLBuffer_Func GetSyncMLBuffer; RetSyncMLBuffer_Func RetSyncMLBuffer; ReadSyncMLBuffer_Func ReadSyncMLBuffer; WriteSyncMLBuffer_Func WriteSyncMLBuffer; CloseSession_Func CloseSession; OpenKeyByPath_Func OpenKeyByPath; OpenSubkey_Func OpenSubkey; DeleteSubkey_Func DeleteSubkey; GetKeyID_Func GetKeyID; SetTextMode_Func SetTextMode; SetTimeMode_Func SetTimeMode; CloseKey_Func CloseKey; GetValue_Func GetValue; GetValueByID_Func GetValueByID; GetValueID_Func GetValueID; SetValue_Func SetValue; SetValueByID_Func SetValueByID; } SDK_UI_Struct; /*! The SDK dbapi tunnel structure (for internal use only) * NOTE: As this struct is part of the SDK_Interface_Struct, it is frozen and not directly extendable */ typedef struct { SDR_Func StartDataRead; RdNItemSFunc ReadNextItem; Rd_ItemSFunc ReadItem; EDR_Func EndDataRead; SDW_Func StartDataWrite; InsItemSFunc InsertItem; UpdItemSFunc UpdateItem; MovItem_Func MoveItem; DelItem_Func DeleteItem; EDW_Func EndDataWrite; DisposeProc DisposeObj; /* --- asKey functions */ RdNItemKFunc ReadNextItemAsKey; Rd_ItemKFunc ReadItemAsKey; InsItemKFunc InsertItemAsKey; UpdItemKFunc UpdateItemAsKey; } SDK_Tunnel_Struct; enum { /** Current callback version */ DB_Callback_Version = 11 }; /*! The SDK interface structure for callback and call-in */ typedef struct SDK_InterfaceType { uInt16 callbackVersion; /*!< The version of this callback struct */ appPointer callbackRef; /*!< The opaque pointer that must be returned in * the \ argument of all callbacks */ /* ---- callbackVersion>=1 fields ---- */ uInt16 debugFlags; /*!< Debug control flags: if<>0, debug is enabled */ DB_DebugPuts_Func DB_DebugPuts; /*!< Output prodedure to add things to the debug log */ CContext cContext; /*!< Callback C/C++ context, normally identical with * \; different e.g. for JNI */ CContext mContext; /*!< Module context */ CContext sContext; /*!< Session context */ /* ---- callbackVersion>=2 fields ---- */ DB_DebugBlock_Func DB_DebugBlock; /*!< Output proc to open a named (=aTag) structure block in the log */ DB_DebugEndBlock_Func DB_DebugEndBlock; /*!< Output proc to close a prev. opened named structure block in the log */ DB_DebugEndThread_Func DB_DebugEndThread; /*!< Output proc to signal debug logging system that no more debug output * will come from the calling thread */ uInt32 lCount; /*!< Level counter, for internal use only */ /* ---- callbackVersion>=3 fields ---- */ DB_DebugExotic_Func DB_DebugExotic; /*!< Output prodedure to add exotic things to the debug log */ /* ---- callbackVersion>=4 fields ---- */ uInt16 allow_DLL_legacy; /*!< Legacy, because of alignment problems * (as bool) on some platforms, * Use for new applications. */ /* ---- callbackVersion>=5 fields ---- */ uInt16 allow_DLL; /*!< DLLs can be used */ /* ---- callbackVersion>=6 fields ---- */ uInt32 reserved1; /*!< (Legacy UI_* funcs, no longer used) */ uInt32 reserved2; uInt32 reserved3; uInt32 reserved4; /* ---- callbackVersion>=7 fields ---- */ appPointer thisCB; /*!< a reference to this structure directly */ uInt32 logCount; /*!< Incremental counter for logs */ /* ---- callbackVersion>=8 fields ---- */ appPointer thisBase; /*!< base for abstract method calling */ appPointer jRef; /*!< base for java access */ CContext gContext; /*!< common global context */ SDK_UI_Struct ui; /*!< UI Api methods */ /* ---- callbackVersion>=9 fields ---- */ memSize SDK_Interface_size; /* size of this structure */ SDK_Tunnel_Struct dt; /* dbapi tunnel callback functions, for internal use only */ /* ---- callbackVersion>=10 fields ---- */ /* no additional fields, just information that SUBSYSTEM (CA_SubSystem) is supported */ /* ---- callbackVersion>=11 fields ---- */ /* SDK_Tunnel_Struct extended (at the end) with "asKey" functions */ /* ---- callbackVersion>=12 fields will go here ---- */ /* ... */ } SDK_Interface_Struct, *DB_Callback, *UI_Call_In; /* special case for = 8, higher versions contain a size field */ #define SDK_Interface_Struct_V8 8 #define SDK_Interface_Struct_V8_Size 184 /*! Wrapper for tunnel context callback */ struct TunnelWrapper { UI_Call_In tCB; /* the Call-In reference */ SessionH tContext; /* the tunnel session context */ appCharP tContextName; /* the tunnel session context name, needed for reopen in context */ KeyH tItemKey; /* an item key element for AsKey operations */ uInt16 tAfterWrite; /* is true after first Insert/Update/Move/Delete */ }; /* Tunnelwrapper */ /* -------------------------------------------------------------------------------------- */ /*! Function prototypes for engine connection/disconnection */ typedef TSyError (*ConnectEngine_Func) ( UI_Call_In *aCI, CVersion *aEngVersion, CVersion aPrgVersion, uInt16 aDebugFlags ); typedef TSyError (*ConnectEngineS_Func) ( UI_Call_In aCI, uInt16 aCallbackVersion, CVersion *aEngVersion, CVersion aPrgVersion, uInt16 aDebugFlags ); typedef TSyError (*DisconnectEngine_Func) ( UI_Call_In aCI ); /* Entry point for connecting the SyncML engine as client from outside */ ENGINE_ENTRY TSyError SYSYNC_EXTERNAL(ConnectEngine) ( UI_Call_In *aCI, CVersion *aEngVersion, CVersion aPrgVersion, uInt16 aDebugFlags ) ENTRY_ATTR; ENGINE_ENTRY TSyError SYSYNC_EXTERNAL(ConnectEngineS) ( UI_Call_In aCI, uInt16 aCallbackVersion, CVersion *aEngVersion, CVersion aPrgVersion, uInt16 aDebugFlags ) ENTRY_ATTR; /* Entry point for connecting the SyncML engine as server from outside */ ENGINE_ENTRY TSyError SYSYNC_EXTERNAL_SRV(ConnectEngine) ( UI_Call_In *aCI, CVersion *aEngVersion, CVersion aPrgVersion, uInt16 aDebugFlags ) ENTRY_ATTR; ENGINE_ENTRY TSyError SYSYNC_EXTERNAL_SRV(ConnectEngineS) ( UI_Call_In aCI, uInt16 aCallbackVersion, CVersion *aEngVersion, CVersion aPrgVersion, uInt16 aDebugFlags ) ENTRY_ATTR; /* Entry point for disconnecting the client engine at the end */ ENGINE_ENTRY TSyError SYSYNC_EXTERNAL(DisconnectEngine) ( UI_Call_In aCI ) ENTRY_ATTR; /* Entry point for disconnecting the client engine at the end */ ENGINE_ENTRY TSyError SYSYNC_EXTERNAL_SRV(DisconnectEngine) ( UI_Call_In aCI ) ENTRY_ATTR; #ifdef __cplusplus } // namespace #endif #endif /* eof */ libsynthesis-3.4.0.47.1/src/sysync_SDK/Sources/sync_declarations.h000066400000000000000000000032721226375725500247700ustar00rootroot00000000000000/* * File: sync_declarations.h * * Author: Patrick Ohly * * C/C++ Programming interface between * the Synthesis SyncML engine * and the database layer * * Copyright (c) 2004-2011 by Synthesis AG + plan44.ch * * These are the declarations for the calling interface between the * Synthesis SyncML engine and a UI and/or DB plugin. Use this * header file when you only need the declaration (= names) of the * various items defined in sync_dbapidef.h. For definitions of * enums include engine_defs.h. * * The following naming convention is used: * - struct fooType = struct or class name * - typedef struct { } foo_Struct = struct itself (in both C++ and C!) * - typedef struct { } *foo = pointer to struct * * This convention has evolved over time and is not used completely * consistently. * * Also note that some types refer to structs which have no real * definition anywhere: they are only introduced to make interfaces * type-safe. These pointer types use fooH as naming scheme. */ #ifndef SYNC_DECLARATIONS_H #define SYNC_DECLARATIONS_H #ifdef __cplusplus namespace sysync { #endif struct SDK_InterfaceType; struct ItemIDType; typedef struct ItemIDType ItemID_Struct, *ItemID; typedef const struct ItemIDType *cItemID; struct MapIDType; typedef struct MapIDType MapID_Struct, *MapID; typedef const struct MapIDType *cMapID; struct TEngineProgressType; typedef struct SessionType *SessionH; typedef struct KeyType *KeyH; /* @TODO: typedef const MapID cMapID: a const pointer or a pointer to const struct?! */ #ifdef __cplusplus } /* namespace sysync */ #endif #endif /* SYNC_DECLARATIONS_H */ libsynthesis-3.4.0.47.1/src/sysync_SDK/Sources/sync_include.h000066400000000000000000000040261226375725500237410ustar00rootroot00000000000000/* * File: sync_include.h * * Authors: Beat Forster (bfo@synthesis.ch) * * * SDK include definitions * * Copyright (c) 2004-2011 by Synthesis AG + plan44.ch * */ #ifndef SYNC_INCLUDE_H #define SYNC_INCLUDE_H #include "target_options.h" #include "generic_types.h" /* some basic defs, which aren't available */ #include "engine_defs.h" #include "syerror.h" /* "syerror.h" uses "generic_types.h" */ #if !defined(__cplusplus) && !defined(__OBJC__) #if !defined(SYSYNC_ENGINE) || !defined(__MACH__) || defined(__GNUC__) typedef unsigned char bool; #define false 0 #define true 1 #endif #endif #if !defined SYSYNC_ENGINE || !defined LINUX || defined __MACH__ typedef unsigned long ulong; #endif #ifdef SYSYNC_ENGINE /* ==> if it is running within the SyncML engine */ #ifdef __cplusplus #include "sysync.h" #include "platform_file.h" #else #if defined _MSC_VER #define NULL 0 #endif #include "sysync_debug.h" #endif #else /* ==> if running standalone, e.g. at a plug-in module */ #include /* used for printf calls */ #include /* used for the malloc/free calls */ #include /* used for strcpy/strlen calls */ #ifdef __cplusplus #ifndef __MACH__ /* MACH: IOFBF/RAND_MAX duplicate problem */ #include /* STL includes */ #include #endif #ifdef __GNUC__ #include #else #include /* type_info class */ #endif using namespace std; #endif #if defined __MACH__ && !defined __GNUC__ /* used for va_list support */ #include #else #include #endif #endif #ifdef DBAPI_FILEOBJ #ifndef FILEOBJ_SUPPORT #define FILEOBJ_SUPPORT 1 #endif #define PLATFORM_FILE 1 #endif /* JAVA native interface JNI */ #ifdef JNI_SUPPORT #include //#ifdef MACOSX // #include //#else // #include //#endif #endif #endif /* SYNC_INCLUDE_H */ /* eof */ libsynthesis-3.4.0.47.1/src/sysync_SDK/Sources/sync_uiapi.h000077500000000000000000000056451226375725500234400ustar00rootroot00000000000000/* * File: sync_uiapi.h * * Author: Beat Forster (bfo@synthesis.ch) * * C/C++ Programming interface between the * Synthesis SyncML engine and * the user interface layer for plug-ins * * Copyright (c) 2007-2011 by Synthesis AG + plan44.ch * */ /* * This is the calling interface between the Synthesis SyncML engine * and a customized module "sync_uiapi". * The same interface can be used either for Standard C or for C++. * And there is a equivalent interface for JNI (Java Native Interface). * Normally the customized module will be compiled as DLL and will * be called by the SyncML engine. A linkable library is available * (for C++) as well. * * NOTE: The plugin's module context is currently defined at * "sync_dbapi.h" as it is the same structure as for the * data base plugin. * * NOTE: As the SyncML engine calls the plug-in multithreaded, * all global structure accesses must be thread save. */ #ifndef SYNC_UIAPI_H #define SYNC_UIAPI_H /* // Global declarations #if defined __cplusplus // combine the definitions of different namespaces #ifdef SYSYNC_ENGINE using sysync::TSyError; #endif #endif */ /* C/C++ and DLL/library support * SYSYNC_ENGINE: true ( within the engine itself ) / false ( outside ) * PLUGIN_INFO : true ( within "plugin_info" program ) / false ( everywhere else ) */ #if !defined SYSYNC_ENGINE && !defined SYSYNC_ENGINE_TEST && !defined DBAPI_LINKED && !defined PLUGIN_INFO && !defined DLL_EXPORT #define DLL_EXPORT #endif /* Visual Studio 2005 requires a specific entry point definition */ /* This definition is empty for all other platforms */ #undef _ENTRY_ #ifdef DLL_EXPORT #define _ENTRY_ ENGINE_ENTRY #else #define _ENTRY_ #endif /* -- UI interface -------------------------------------------------------------- */ /*! Create a user interface context \ * * @param Returns a value, which allows to identify this UI context. * @param Name of this user interface context * @param UI_Callback structure for module logging * * @return error code, if context could not be created (e.g. not enough memory), * 0 if context successfully created. */ _ENTRY_ TSyError UI_CreateContext( CContext *uContext, cAppCharP uiName, UI_Call_In uCI ); /*! Start interaction with user interface at \. */ _ENTRY_ TSyError UI_RunContext( CContext uContext ); /*! This routine will be called as the last call, before this module is disconnected. * The SyncML engine will call 'UI_DisposeObj' (if required) before this call * * NOTE: This routine will be called ONLY, if the server stops in a controlled way. * Its good programming practice not to wait for this 'DeleteContext' call. * * @param The module context. * @return error code */ _ENTRY_ TSyError UI_DeleteContext( CContext uContext ); #endif /* eof */ libsynthesis-3.4.0.47.1/src/sysync_SDK/Sources/syncexception.cpp000077500000000000000000000024621226375725500245150ustar00rootroot00000000000000/* * File: SyncException.cpp * * Author: Lukas Zeller (luz@plan44.ch) * * TSyncException... * SySync Exception classes * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * 2001-05-28 : luz : created * */ // includes #include "prefix_file.h" #include "sync_include.h" #include "sysync.h" #include "syncexception.h" using namespace sysync; TSyncException::TSyncException(const char *aMsg1, localstatus aLocalStatus) NOTHROW { fMessage = aMsg1; fLocalStatus = aLocalStatus; } // TSyncException::TSyncException TSyncException::TSyncException(localstatus aLocalStatus) NOTHROW { fLocalStatus = aLocalStatus; fMessage = "Exception due to local error status"; } // TSyncException::TSyncException TSyncException::~TSyncException() NOTHROW { } // TSyncException::~TSyncException const char *TSyncException::what() const NOTHROW { return fMessage.c_str(); } // TSyncException::getMessage void TSyncException::setMsg(const char *p) { fMessage=p; } // TSyncException::setMsg TSmlException::TSmlException(const char *aMsg, Ret_t aSmlError) NOTHROW { const int msgsiz=256; char msg[msgsiz]; fSmlError=aSmlError; msg[0]=0; snprintf(msg,msgsiz,"SyncML Toolkit error=0x%04hX, %s",(uInt16)fSmlError,aMsg); setMsg(msg); } // TSmlException::TSmlException // eof libsynthesis-3.4.0.47.1/src/sysync_SDK/Sources/syncexception.h000077500000000000000000000037261226375725500241660ustar00rootroot00000000000000/* * File: SyncException.cpp * * Author: Lukas Zeller (luz@plan44.ch) * * TSyncException... * SySync Exception classes * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * 2001-05-28 : luz : created * */ #ifndef SyncException_H #define SyncException_H using namespace std; namespace sysync { #if defined(WINCE) || defined(__EPOC_OS__) || defined(ANDROID) // eVC + EPOC cannot process throw() qualifier #define NOTHROW // eVC + EPOC has no exception base class class exception { public: exception() {}; exception(const exception&) {}; exception& operator= (const exception&) {return *this;}; virtual ~exception() {}; virtual const char* what() const {return "exception";}; }; #else #define NOTHROW throw() #endif class TSyncException : public exception { typedef exception inherited; public: TSyncException(const char *aMsg1, localstatus aLocalStatus=LOCERR_EXCEPTION) NOTHROW; TSyncException(localstatus aLocalStatus) NOTHROW; TSyncException() NOTHROW { fLocalStatus=LOCERR_EXCEPTION; }; virtual ~TSyncException() NOTHROW; virtual const char * what() const NOTHROW; localstatus status(void) NOTHROW { return fLocalStatus; } protected: void setMsg(const char *p); string fMessage; private: localstatus fLocalStatus; }; // TSyncException class TSmlException : public TSyncException { typedef TSyncException inherited; public: TSmlException(const char *aMsg, Ret_t aSmlError) NOTHROW; Ret_t getSmlError(void) { return fSmlError; }; private: Ret_t fSmlError; }; // TSmlException class TStructException : public TSyncException { typedef TSyncException inherited; public: TStructException(const char *aMsg) NOTHROW: TSyncException (aMsg) {}; }; // TStructException class TMemException : public TSyncException { typedef TSyncException inherited; public: TMemException(const char *aMsg) NOTHROW: TSyncException (aMsg) {}; }; // TMemException } // namespace sysync #endif // SyncException_H // eof libsynthesis-3.4.0.47.1/src/sysync_SDK/Sources/sysync_b64.cpp000077500000000000000000000170401226375725500236230ustar00rootroot00000000000000/* b64 encoding/decoding */ #include "prefix_file.h" #include #include #include "sysync_b64.h" #include "sync_include.h" using namespace b64; static const char table [64] = { 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P', 'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f', 'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v', 'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/' }; // free memory allocated with encode or decode above void b64::free(void *mem) { // we use normal malloc below, so use normal free as well ::free(mem); } char *b64::encode (const uInt8 *instr, uInt32 len, uInt32 *outlenP, sInt16 maxLineLen, bool crLineEnd) { // no line breaks -- this is just a straight b64 transform uInt32 i_off = 0; uInt32 o_off = 0; uInt8 inbuf [3]; uInt32 inlen,outlen,inover; uInt32 triples; uInt32 i; sInt16 linechars; char *outstr = NULL; if ( (instr == NULL) || (len == 0) ) { return(NULL); } inlen = len; inover = inlen%3; triples = ((inlen-inover)/3); outlen = 4*triples+1; if (inover) { outlen+=4; } if (maxLineLen) { // make whole number of quads fit on one line maxLineLen &= ~3; // clear bit 0&1 // also add room for CRs or CRLFs outlen += (outlen/maxLineLen+1) << (crLineEnd ? 0 : 1); } outstr = (char *)malloc(outlen*sizeof(char)); memset(outstr,0,outlen); linechars=0; o_off=0; for (i = 0; i < triples; i++) { i_off = i*3; // o_off = i*4; %%% not ok as there might be line ends in between inbuf[0] = instr[i_off]; inbuf[1] = instr[i_off+1]; inbuf[2] = instr[i_off+2]; outstr[o_off++] = table[(inbuf [0] & 0xFC) >> 2]; outstr[o_off++] = table[((inbuf [0] & 0x03) << 4) | ((inbuf [1] & 0xF0) >> 4)]; outstr[o_off++] = table[((inbuf [1] & 0x0F) << 2) | ((inbuf [2] & 0xC0) >> 6)]; outstr[o_off++] = table[inbuf [2] & 0x3F]; // check line wrapping linechars+=4; if ( maxLineLen && linechars>=maxLineLen && // line limit enabled (i 1 ) { inbuf[1] = instr[i_off+1]; } inbuf[2] = 0; outstr[o_off] = table[(inbuf [0] & 0xFC) >> 2]; outstr[o_off+1] = table[((inbuf [0] & 0x03) << 4) | ((inbuf [1] & 0xF0) >> 4)]; outstr[o_off+2] = table[((inbuf [1] & 0x0F) << 2) | ((inbuf [2] & 0xC0) >> 6)]; outstr[o_off+3] = table[inbuf [2] & 0x3F]; // generate b64 strings that are padded with = to // make multiple's of 4 (this is how it must be) if (inover < 3 ) { outstr[o_off+3] = '='; if (inover < 2 ) { outstr[o_off+2] = '='; } } } // output length is either size of all complete quadruples including line feeds (o_off) or 4 more if // input was not evenly divisible by 3 // (%%% luz added case for inover<>0, which produced 4 NULLs at end of string on inover==0) if (outlenP) *outlenP = o_off+ (inover==0 ? 0 : 4); return(outstr); } uInt8 *b64::decode(const char *instr, uInt32 len, uInt32 *outlenP) { uInt8 inbuf [4]; uInt32 n; sInt16 quadi; bool done; const char *p; char c=0; uInt8 *outstr,*q; // get length if not passed as argument if (!instr) len=0; else if (len==0) len=strlen(instr); p = instr; // this should always be more than enough len: // 3 times number of quads touched plus one for NUL terminator outstr = (uInt8 *)malloc(((3*(len/4+1))+1) * sizeof(char)); if (!outstr) return NULL; q=outstr; // process input string now n=0; quadi=0; // index within quad done=false; // not done yet while (!done) { if (n= 'A') && (c <= 'Z')) c = c - 'A'; else if ((c >= 'a') && (c <= 'z')) c = c - 'a' + 26; else if ((c >= '0') && (c <= '9')) c = c - '0' + 52; else if (c == '+') c = 62; else if (c == '/') c = 63; else if (c == '=') { // reaching a "=" is like end of data done=true; } else continue; // ignore all others } else done=true; // save in char if (!done) inbuf[quadi++] = c; // check if done or full quadruple if (done || quadi==4) { // produce data now if (quadi>=2) { // two input bytes, first byte is there for sure *q++ = (inbuf [0] << 2) | ((inbuf [1] & 0x30) >> 4); if (quadi>=3) { // three input bytes, two output bytes are there *q++ = ((inbuf [1] & 0x0F) << 4) | ((inbuf [2] & 0x3C) >> 2); if (quadi==4) { // all 4 bytes there, produce three bytes *q++ = ((inbuf [2] & 0x03) << 6) | (inbuf [3] & 0x3F); } } } // start new quad quadi=0; } } // while // return length if requested if (outlenP) *outlenP = q-outstr; // make sure output ends with NUL in case it is interpreted as a c string *q=0; // return string return(outstr); /* unsigned int i_off, o_off; uInt8 inbuf [4]; unsigned int inlen,outlen,inover; unsigned int quads; int i,cnt; uInt8 *outstr = NULL; char ch; if (len==0) len=strlen(instr); if ( (instr == NULL) || (len==0) ) { return(NULL); } inlen = len; inover = inlen%4; quads = ((inlen-inover)/4); // this should always be more than enough len outlen = (3*(quads+1))+1; outstr = (uInt8 *)malloc(outlen * sizeof(char)); memset(outstr,0,outlen); for (i = 0; i < quads; i++) { i_off = i*4; o_off = i*3; for (cnt = 0; cnt < 4; cnt++) { ch = instr[i_off+cnt]; if ((ch >= 'A') && (ch <= 'Z')) ch = ch - 'A'; else if ((ch >= 'a') && (ch <= 'z')) ch = ch - 'a' + 26; else if ((ch >= '0') && (ch <= '9')) ch = ch - '0' + 52; else if (ch == '+') ch = 62; else if (ch == '=') //no op -- can't ignore this one* ch = 0; else if (ch == '/') ch = 63; inbuf[cnt] = ch; } outstr[o_off] = (inbuf [0] << 2) | ((inbuf [1] & 0x30) >> 4); outstr[o_off+1] = ((inbuf [1] & 0x0F) << 4) | ((inbuf [2] & 0x3C) >> 2); outstr[o_off+2] = ((inbuf [2] & 0x03) << 6) | (inbuf [3] & 0x3F); } // handle b64 strings that are not padded correctly if (inover) { i_off = i*4; o_off = i*3; memset(inbuf,0,4); for (cnt = 0; cnt < inover; cnt++) { ch = instr[i_off+cnt]; if ((ch >= 'A') && (ch <= 'Z')) ch = ch - 'A'; else if ((ch >= 'a') && (ch <= 'z')) ch = ch - 'a' + 26; else if ((ch >= '0') && (ch <= '9')) ch = ch - '0' + 52; else if (ch == '+') ch = 62; else if (ch == '=') //no op -- can't ignore this one* ch = 0; else if (ch == '/') ch = 63; inbuf[cnt] = ch; } outstr[o_off] = (inbuf [0] << 2) | ((inbuf [1] & 0x30) >> 4); outstr[o_off+1] = ((inbuf [1] & 0x0F) << 4) | ((inbuf [2] & 0x3C) >> 2); outstr[o_off+2] = ((inbuf [2] & 0x03) << 6) | (inbuf [3] & 0x3F); } if (outlenP) *outlenP = o_off+3; return(outstr); */ } // eof libsynthesis-3.4.0.47.1/src/sysync_SDK/Sources/sysync_b64.h000077500000000000000000000011411226375725500232630ustar00rootroot00000000000000/* b64 encoding/decoding */ #ifndef SYSYNC_B64_H #define SYSYNC_B64_H #include "generic_types.h" using namespace sysync; namespace b64 { // encode data to B64, returns allocated buffer // does line breaks if maxLineLen!=0 char *encode ( const uInt8 *instr, uInt32 len, uInt32 *outlenP=NULL, sInt16 maxLineLen=0, bool crLineEnd=false ); // decode B64 string to data (len=0 calculates string length automatically) uInt8 *decode(const char *instr, uInt32 len=0, uInt32 *outlenP=NULL); // free memory allocated with encode or decode above void free(void *mem); } #endif /* SYSYNC_B64_H */ /* eof */ libsynthesis-3.4.0.47.1/src/sysync_SDK/Sources/sysync_md5.cpp000077500000000000000000000303061226375725500237150ustar00rootroot00000000000000/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm */ /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All rights reserved. License to copy and use this software is granted provided that it is identified as the "RSA Data Security, Inc. MD5 Message-Digest Algorithm" in all material mentioning or referencing this software or this function. License is also granted to make and use derivative works provided that such works are identified as "derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm" in all material mentioning or referencing the derived work. RSA Data Security, Inc. makes no representations concerning either the merchantability of this software or the suitability of this software for any particular purpose. It is provided "as is" without express or implied warranty of any kind. These notices must be retained in any copies of any part of this documentation and/or software. */ /* 2001-05-29: adapted to MW-C and ANSI-C by luz */ /* 2001-08-07: added MD5_MSB_FIRST variant for Motorola order digest output*/ #include "prefix_file.h" #include "sysync_md5.h" /* Constants for MD5Transform routine. */ using namespace md5; #define S11 7 #define S12 12 #define S13 17 #define S14 22 #define S21 5 #define S22 9 #define S23 14 #define S24 20 #define S31 4 #define S32 11 #define S33 16 #define S34 23 #define S41 6 #define S42 10 #define S43 15 #define S44 21 /* local prototypes */ static void MD5Transform (SYSYNC_UINT4 [4], const uInt8 [64]); static void Encode (uInt8 *, const SYSYNC_UINT4 *, uInt32); #ifdef MD5_MSB_FIRST static void EncodeMSBfirst (uInt8 *, const SYSYNC_UINT4 *, uInt32); #endif static void Decode (SYSYNC_UINT4 *, const uInt8 *, uInt32); static void MD5_memcpy (SYSYNC_POINTER, SYSYNC_POINTER, uInt32); static void MD5_memset (SYSYNC_POINTER, sInt32, uInt32); /* moved to SYSYNC_MD5_CTX as statics are not allowed in some environments static uInt8 PADDING[64] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; */ /* F, G, H and I are basic MD5 functions. */ #define F(x, y, z) (((x) & (y)) | ((~x) & (z))) #define G(x, y, z) (((x) & (z)) | ((y) & (~z))) #define H(x, y, z) ((x) ^ (y) ^ (z)) #define I(x, y, z) ((y) ^ ((x) | (~z))) /* ROTATE_LEFT rotates x left n bits. */ #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. Rotation is separate from addition to prevent recomputation. */ #define FF(a, b, c, d, x, s, ac) { (a) += F ((b), (c), (d)) + (x) + (SYSYNC_UINT4)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); } #define GG(a, b, c, d, x, s, ac) { (a) += G ((b), (c), (d)) + (x) + (SYSYNC_UINT4)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); } #define HH(a, b, c, d, x, s, ac) { (a) += H ((b), (c), (d)) + (x) + (SYSYNC_UINT4)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); } #define II(a, b, c, d, x, s, ac) { (a) += I ((b), (c), (d)) + (x) + (SYSYNC_UINT4)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); } /* MD5 initialization. Begins an MD5 operation, writing a new context. */ void md5::Init (SYSYNC_MD5_CTX *context) { context->count[0] = context->count[1] = 0; /* Load magic initialization constants. */ context->state[0] = 0x67452301; context->state[1] = 0xefcdab89; context->state[2] = 0x98badcfe; context->state[3] = 0x10325476; /* initialize the padding space, don't know if this is necessary */ MD5_memset ((SYSYNC_POINTER)context->PADDING, 0, 64); context->PADDING[0]=0x80; } /* MD5 block update operation. Continues an MD5 message-digest operation, processing another message block, and updating the context. */ void md5::Update ( SYSYNC_MD5_CTX *context, /* context */ const uInt8 *input, /* input block */ uInt32 inputLen /* length of input block */ ) { uInt32 i, index, partLen; /* Compute number of bytes mod 64 */ index = (uInt32)((context->count[0] >> 3) & 0x3F); /* Update number of bits */ if ((context->count[0] += ((SYSYNC_UINT4)inputLen << 3)) < ((SYSYNC_UINT4)inputLen << 3)) context->count[1]++; context->count[1] += ((SYSYNC_UINT4)inputLen >> 29); partLen = 64 - index; /* Transform as many times as possible. */ if (inputLen >= partLen) { MD5_memcpy ((SYSYNC_POINTER)&context->buffer[index], (SYSYNC_POINTER)input, partLen); MD5Transform (context->state, context->buffer); for (i = partLen; i + 63 < inputLen; i += 64) MD5Transform (context->state, &input[i]); index = 0; } else i = 0; /* Buffer remaining input */ MD5_memcpy ((SYSYNC_POINTER)&context->buffer[index], (SYSYNC_POINTER)&input[i], inputLen-i); } /* MD5 finalization. Ends an MD5 message-digest operation, writing the the message digest and zeroizing the context. */ void md5::Final ( uInt8 digest[16], /* message digest */ SYSYNC_MD5_CTX *context /* context */ ) { uInt8 bits[8]; uInt32 index, padLen; /* Save number of bits */ Encode (bits, context->count, 8); /* Pad out to 56 mod 64. */ index = (uInt32)((context->count[0] >> 3) & 0x3f); padLen = (index < 56) ? (56 - index) : (120 - index); md5::Update (context, context->PADDING, padLen); /* Append length (before padding) */ md5::Update (context, bits, 8); /* Store state in digest */ Encode (digest, context->state, 16); /* Zeroize sensitive information. */ MD5_memset ((SYSYNC_POINTER)context, 0, sizeof (*context)); } /* MD5 basic transformation. Transforms state based on block. */ static void MD5Transform ( SYSYNC_UINT4 state[4], const uInt8 block[64] ) { SYSYNC_UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; Decode (x, block, 64); /* Round 1 */ FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ /* Round 2 */ GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ /* Round 3 */ HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ /* Round 4 */ II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ state[0] += a; state[1] += b; state[2] += c; state[3] += d; /* Zeroize sensitive information. */ MD5_memset ((SYSYNC_POINTER)x, 0, sizeof (x)); } /* Encodes input (SYSYNC_UINT4) into output (uInt8). Assumes len is a multiple of 4. */ static void Encode ( uInt8 *output, const SYSYNC_UINT4 *input, uInt32 len ) { uInt32 i, j; for (i = 0, j = 0; j < len; i++, j += 4) { output[j] = (uInt8)(input[i] & 0xff); output[j+1] = (uInt8)((input[i] >> 8) & 0xff); output[j+2] = (uInt8)((input[i] >> 16) & 0xff); output[j+3] = (uInt8)((input[i] >> 24) & 0xff); } } /* Decodes input (uInt8) into output (SYSYNC_UINT4). Assumes len is a multiple of 4. */ static void Decode ( SYSYNC_UINT4 *output, const uInt8 *input, uInt32 len ) { uInt32 i, j; for (i = 0, j = 0; j < len; i++, j += 4) output[i] = ((SYSYNC_UINT4)input[j]) | (((SYSYNC_UINT4)input[j+1]) << 8) | (((SYSYNC_UINT4)input[j+2]) << 16) | (((SYSYNC_UINT4)input[j+3]) << 24); } /* Note: Replace "for loop" with standard memcpy if possible. */ static void MD5_memcpy ( SYSYNC_POINTER output, SYSYNC_POINTER input, uInt32 len ) { uInt32 i; for (i = 0; i < len; i++) output[i] = input[i]; } /* Note: Replace "for loop" with standard memset if possible. */ static void MD5_memset ( SYSYNC_POINTER output, sInt32 value, uInt32 len ) { uInt32 i; for (i = 0; i < len; i++) ((char *)output)[i] = (char)value; } #ifdef MD5_TEST_FUNCS /* MD5 Test stuff */ /* Digests a string and prints the result. */ void md5::String (const char *aString, char *s) { SYSYNC_MD5_CTX context; uInt8 digest[16]; uInt32 len = strlen (aString); Init (&context); Update (&context, (uInt8 *) aString, len); Final (digest, &context); sprintf (s,"MD5 (\"%s\") = ", aString); s+=strlen(s); Print (digest,s); } /* Prints a message digest in hexadecimal. */ void md5::Print (uInt8 *digest, char * &s) { uInt32 i; for (i = 0; i < 16; i++) { sprintf (s,"%02hx", (uInt16)digest[i]); s+=strlen(s); } } void md5::dotest(void) { printf("================= MD5 Test Suite ==========================="); char buf[1024]; md5::String ("",buf); printf("%s (should be: d41d8cd98f00b204e9800998ecf8427e)",buf); md5::String ("a",buf); printf("%s (should be: 0cc175b9c0f1b6a831c399e269772661)",buf); md5::String ("abc",buf); printf("%s (should be: 900150983cd24fb0d6963f7d28e17f72)",buf); md5::String ("message digest",buf); printf("%s (should be: f96b697d7cb7938d525a2f31aaf161d0)",buf); md5::String ("abcdefghijklmnopqrstuvwxyz",buf); printf("%s (should be: c3fcd3d76192e4007dfb496cca67e13b)",buf); md5::String ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",buf); printf("%s (should be: d174ab98d277d9f5a5611c2c9f419d9f)",buf); md5::String ("12345678901234567890123456789012345678901234567890123456789012345678901234567890",buf); printf("%s (should be: 57edf4a22be3c955ac49da2e2107b67a)",buf); md5::String ("luz:gaga",buf); printf("%s (should be: )",buf); printf("================= end MD5 Test Suite ==========================="); } #endif /* eof */ libsynthesis-3.4.0.47.1/src/sysync_SDK/Sources/sysync_md5.h000077500000000000000000000044661226375725500233720ustar00rootroot00000000000000/* MD5.H - header file for MD5C.C */ /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All rights reserved. License to copy and use this software is granted provided that it is identified as the "RSA Data Security, Inc. MD5 Message-Digest Algorithm" in all material mentioning or referencing this software or this function. License is also granted to make and use derivative works provided that such works are identified as "derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm" in all material mentioning or referencing the derived work. RSA Data Security, Inc. makes no representations concerning either the merchantability of this software or the suitability of this software for any particular purpose. It is provided "as is" without express or implied warranty of any kind. These notices must be retained in any copies of any part of this documentation and/or software. */ /* 2001-05-29: adapted to MW-C and ANSI-C by luz */ /* originally GLOBAL.H - RSAREF types and constants * now moved here to keep everything in namespace */ // define this to add test functions String() and Print() // #define MD5_TEST_FUNCS 1 #ifndef SYSYNC_MD5_H #define SYSYNC_MD5_H #include "generic_types.h" using namespace sysync; namespace md5 { /* POINTER defines a generic pointer type */ typedef uInt8 *SYSYNC_POINTER; /* UINT2 defines a two byte word */ typedef uInt16 SYSYNC_UINT2; /* UINT4 defines a four byte word */ /* Note: "typedef uInt32 SYSYNC_UINT4;" is unreliable as uInt32 was 64bit in some weird builds */ #if !defined(__WORDSIZE) || (__WORDSIZE < 32) typedef unsigned long SYSYNC_UINT4; #else typedef unsigned int SYSYNC_UINT4; #endif /* MD5 context. */ typedef struct { SYSYNC_UINT4 state[4]; /* state (ABCD) */ SYSYNC_UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */ uInt8 buffer[64]; /* input buffer */ uInt8 PADDING[64]; /* padding space */ } SYSYNC_MD5_CTX; /* MD5 functions */ void Init (SYSYNC_MD5_CTX *); void Update (SYSYNC_MD5_CTX *, const uInt8 *, uInt32); void Final (uInt8 [16], SYSYNC_MD5_CTX *); #ifdef MD5_TEST_FUNCS /* for test */ void String (const char *aString, char *s); void Print (uInt8 *digest, char * &s); void dotest(void); #endif } // end namespace md5 #endif // SYSYNC_MD5_H /* eof */ libsynthesis-3.4.0.47.1/src/sysync_SDK/Sources/sysync_noncopyable.h000066400000000000000000000013651226375725500252060ustar00rootroot00000000000000/* * File: sysync_noncopyable.h * * Author: Patrick Ohly (patrick.ohly@intel.com) * * Derive from sysync::noncopyable in all classes which must not be copied, * for example because they contain pointers. * Accidentally copying with the default copy constructor will then * lead to compile instead of runtime errors. * * Same approach as in boost::noncopyable. * * Copyright (c) 2013 by Synthesis AG + plan44.ch */ #ifndef SYSYNC_NONCOPYABLE_H #define SYSYNC_NONCOPYABLE_H namespace sysync { class noncopyable { protected: noncopyable() {} ~noncopyable() {} private: noncopyable( const noncopyable& ); const noncopyable& operator=( const noncopyable& ); }; } // namespace sysync #endif // SYSYNC_NONCOPYABLE libsynthesis-3.4.0.47.1/src/sysync_SDK/Sources/sysync_utils.cpp000077500000000000000000002706461226375725500244050ustar00rootroot00000000000000/* * File: sysync_utils.cpp * * Author: Lukas Zeller (luz@plan44.ch) * * Provides some helper functions interfacing between SyncML Toolkit * and C++ * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * 2001-05-16 : luz : created * */ #include "prefix_file.h" #include "sync_include.h" #include "sysync_utils.h" #include "libmem.h" #ifdef SYSYNC_TOOL #include "syncappbase.h" // for CONSOLEPRINTF #include "customimplagent.h" // for DBCharSetNames #endif namespace sysync { // Support for SySync Diagnostic Tool #ifdef SYSYNC_TOOL // parse RFC 2822 addr spec int parse2822AddrSpec(int argc, const char *argv[]) { if (argc<0) { // help requested CONSOLEPRINTF((" addrparse ")); CONSOLEPRINTF((" Parse name and email address out of a RFC2822-type addr-spec")); return EXIT_SUCCESS; } // check for argument if (argc<1) { CONSOLEPRINTF(("1 argument required")); return EXIT_FAILURE; } // parse string addrname,addremail; const char* p=argv[0]; p=parseRFC2822AddrSpec(p,addrname,addremail); // show CONSOLEPRINTF(("Input : %s",argv[0])); CONSOLEPRINTF(("Name : %s",addrname.c_str())); CONSOLEPRINTF(("email : %s",addremail.c_str())); CONSOLEPRINTF(("unparsed rest : %s",p)); return EXIT_SUCCESS; } // parse2822AddrSpec // convert between character sets int charConv(int argc, const char *argv[]) { if (argc<0) { // help requested CONSOLEPRINTF((" charconv [] ")); CONSOLEPRINTF((" Convert from one charset to another. Default input is UTF-8")); return EXIT_SUCCESS; } #ifdef __TEST_EQUALITY_OF_CP936_WITH_GB2312__ // quick test uInt32 ch_in; for (ch_in=0x8100; ch_in<=0xFFFF; ch_in++) { // convert into internal UTF-8 string s_internal,s_in; s_in.erase(); if (ch_in>=0x8100) s_in+=(ch_in >> 8) & 0xFF; s_in+=(ch_in & 0xFF); s_internal.erase(); appendStringAsUTF8( s_in.c_str(), s_internal, chs_gb2312 ); // convert into output format string s_out; s_out.erase(); appendUTF8ToString( s_internal.c_str(), s_out, chs_cp936 ); // show differences if (s_in!=s_out && s_out.size()>0 && s_out[0]!=INCONVERTIBLE_PLACEHOLDER) { string s1,s2; s1.erase(); StrToCStrAppend(s_in.c_str(), s1); s2.erase(); StrToCStrAppend(s_out.c_str(), s2); CONSOLEPRINTF(("\"%s\" != \"%s\"",s1.c_str(),s2.c_str())); } } return EXIT_SUCCESS; #endif // check for argument if (argc<2) { CONSOLEPRINTF(("2 or 3 arguments required")); return EXIT_FAILURE; } int ochsarg=1; sInt16 enu; // get input charset TCharSets charset_in=chs_utf8; if (argc==3) { // first arg is input charset if (!StrToEnum(DBCharSetNames, numCharSets, enu, argv[0])) { CONSOLEPRINTF(("'%s' is not a valid input charset name",argv[0])); return EXIT_FAILURE; } charset_in = (TCharSets)enu; } else { ochsarg=0; // first arg ist input charset } // get output charset TCharSets charset_out; if (!StrToEnum(DBCharSetNames, numCharSets, enu, argv[ochsarg])) { CONSOLEPRINTF(("'%s' is not a valid output charset name",argv[ochsarg])); return EXIT_FAILURE; } charset_out = (TCharSets)enu; // get string to convert string s_in; s_in.erase(); CStrToStrAppend(argv[ochsarg+1], s_in); // convert into internal UTF-8 string s_internal; s_internal.erase(); appendStringAsUTF8( s_in.c_str(), s_internal, charset_in ); // convert into output format string s_out; s_out.erase(); appendUTF8ToString( s_internal.c_str(), s_out, charset_out ); // show all three string show; // - input show.erase(); StrToCStrAppend(s_in.c_str(), show); CONSOLEPRINTF(("Input : %-20s = \"%s\"",DBCharSetNames[charset_in], show.c_str())); // - internal UTF8 show.erase(); StrToCStrAppend(s_internal.c_str(), show); CONSOLEPRINTF(("Internal : %-20s = \"%s\"",DBCharSetNames[chs_utf8], show.c_str())); // - output show.erase(); StrToCStrAppend(s_out.c_str(), show); CONSOLEPRINTF(("Output : %-20s = \"%s\"",DBCharSetNames[charset_out], show.c_str())); return EXIT_SUCCESS; } // charConv #endif // SYSYNC_TOOL // conversion table from ANSI 0x80..0x9F to UCS4 static const uInt32 Ansi_80_to_9F_to_UCS4[0x20] = { 0x20AC, 0 ,0x201A,0x0192, 0x201E,0x2026,0x2020,0x2021, // 0x80..0x87 0x02C6,0x2030,0x0160,0x2039, 0x0152, 0 ,0x017D, 0 , // 0x88..0x8F 0 ,0x2018,0x2019,0x201C, 0x201D,0x2022,0x2013,0x2014, // 0x90..0x97 0x02DC,0x2122,0x0161,0x203A, 0x0153, 0 ,0x017E,0x0178 // 0x98..0x9F }; // ASCIIfy table to convert umlauts etc. to nearest plain ASCII typedef struct { uInt32 ucs4; uInt8 ascii; } TASCIIfyEntry; static const TASCIIfyEntry ASCIIfyTable[] = { { 0x000000C4, 'A' }, // Adieresis { 0x000000C5, 'A' }, // Aring { 0x000000C7, 'C' }, // Ccedilla { 0x000000C9, 'E' }, // Eacute { 0x000000D1, 'N' }, // Ntilde { 0x000000D6, 'O' }, // Odieresis { 0x000000DC, 'U' }, // Udieresis { 0x000000E1, 'a' }, // aacute { 0x000000E0, 'a' }, // agrave { 0x000000E2, 'a' }, // acircumflex { 0x000000E4, 'a' }, // adieresis { 0x000000E3, 'a' }, // atilde { 0x000000E5, 'a' }, // aring { 0x000000E7, 'c' }, // ccedilla { 0x000000E9, 'e' }, // eacute { 0x000000E8, 'e' }, // egrave { 0x000000EA, 'e' }, // ecircumflex { 0x000000EB, 'e' }, // edieresis { 0x000000ED, 'i' }, // iacute { 0x000000EC, 'i' }, // igrave { 0x000000EE, 'i' }, // icircumflex { 0x000000EF, 'i' }, // idieresis { 0x000000F1, 'n' }, // ntilde { 0x000000F3, 'o' }, // oacute { 0x000000F2, 'o' }, // ograve { 0x000000F4, 'o' }, // ocircumflex { 0x000000F6, 'o' }, // odieresis { 0x000000F5, 'o' }, // otilde { 0x000000FA, 'u' }, // uacute { 0x000000F9, 'u' }, // ugrave { 0x000000FB, 'u' }, // ucircumflex { 0x000000FC, 'u' }, // udieresis { 0x000000DF, 's' }, // germandoubles { 0x000000D8, 'O' }, // Oslash { 0x000000F8, 'o' }, // oslash { 0x000000C0, 'A' }, // Agrave { 0x000000C3, 'A' }, // Atilde { 0x000000D5, 'O' }, // Otilde { 0x00000152, 'O' }, // OE { 0x00000153, 'o' }, // oe { 0x000000C6, 'A' }, // AE { 0x000000E6, 'a' }, // ae { 0x000000C2, 'A' }, // Acircumflex { 0x000000CA, 'E' }, // Ecircumflex { 0x000000C1, 'A' }, // Aacute { 0x000000CB, 'E' }, // Edieresis { 0x000000C8, 'E' }, // Egrave { 0x000000CD, 'I' }, // Iacute { 0x000000CC, 'I' }, // Igrave { 0x000000CE, 'i' }, // Icircumflex { 0x000000CF, 'i' }, // Odieresis { 0x000000D3, 'O' }, // Oacute { 0x000000D2, 'O' }, // Ograve { 0x000000D4, 'O' }, // Ocircumflex // terminator { 0,0 } }; // line end mode names const char * const lineEndModeNames[numLineEndModes] = { "none", // none specified "unix", // 0x0A "mac", // 0x0D "dos", // 0x0D 0x0A "cstr", // as in C strings, '\n' which is 0x0A normally (but might be 0x0D on some platforms) "filemaker" // 0x0B (filemaker tab-separated text format, CR is shown as 0x0B within fields }; // literal quoting mode names const char * const quotingModeNames[numQuotingModes] = { "none", // none specified "singlequote", // single quote must be duplicated "doublequote", // double quote must be duplicated "backslash" // C-string-style escapes of CR,LF,TAB,BS,\," and ' (but no full c-string escape with \xXX etc.) }; // Encoding format names for SyncML const char * const encodingFmtSyncMLNames[numFmtTypes] = { "chr", // plain chars "bin", // binary "b64" // base 64 encoding }; // Encoding format names for user const char * const encodingFmtNames[numFmtTypes] = { "plain-text", // no encoding (plain text) "binary", // plain binary (in WBXML only) "base64" // base 64 encoding }; // field (property) data type names const char * const propDataTypeNames[numPropDataTypes] = { "chr", // Character "int", // Integer "bool", // Boolean "bin", // Binary "datetime", // Date and time of day "phonenum", // Phone number "text", // plain text "???" // unknown }; // Auth type names const char * const authTypeSyncMLNames[numAuthTypes] = { NULL, // no authorisation "syncml:auth-basic", // basic (B64 encoded user pw string) "syncml:auth-md5" // Md5 encoded user:pw:nonce }; // MIME encoding types const char * const MIMEEncodingNames[numMIMEencodings] = { "", "7BIT", "8BIT", "BINARY", "QUOTED-PRINTABLE", "BASE64", "B" }; // Charset names for MIME based strings const char * const MIMECharSetNames[numCharSets] = { "unknown", "US-ASCII", "ANSI", "ISO-8859-1", "UTF-8", "UTF-16", #ifdef CHINESE_SUPPORT "GB2312", "CP936", #endif }; #ifdef SYSYNC_ENGINE // generate RFC2822-style address specificiation // - Common Name will be quoted // - recipient will be put in angle brackets void makeRFC2822AddrSpec( cAppCharP aCommonName, cAppCharP aRecipient, string &aRFCAddr ) { if (aCommonName && *aCommonName) { aRFCAddr='"'; while (*aCommonName) { if (*aCommonName=='"') aRFCAddr += "\\\""; else aRFCAddr += *aCommonName; aCommonName++; } aRFCAddr+="\" <"; aRFCAddr+=aRecipient; aRFCAddr+=">"; } else { // plain email address aRFCAddr=aRecipient; } } // makeRFC2822AddrSpec // sysytool -f syncserv_odbc.xml addrparse "(Lukas Peter) luz@synthesis.ch (Zeller), gaga" // Parse RFC2822-style address specificiation // - aName will receive name and all (possible) comments // - aRecipient will receive the (first, in case of a group) email address cAppCharP parseRFC2822AddrSpec( cAppCharP aText, string &aName, string &aRecipient ) { const char *p; char c; enum { pstate_sepspace, pstate_trailing, pstate_text, pstate_comment, pstate_quoted, pstate_email } pstate = pstate_trailing; string text,groupname; bool textcouldbeemail=true; bool atfound=false; aName.erase(); aRecipient.erase(); p=aText; do { c=*p; // check end of input if (c==0) break; // done with the string // advance to next char p++; // check according to state switch (pstate) { case pstate_sepspace: if (c==' ') { aName+=c; } pstate=pstate_trailing; // otherwise treat like trailing case pstate_trailing: textcouldbeemail=aRecipient.empty(); atfound=false; // skip trailing WSP first if (c==' ' || c=='\t' || c=='\n' || c=='\r') break; // simply ignore WSP in trailing mode else pstate=pstate_text; // fall trough to do text analysis case pstate_text: // now check specials if (c==',') { c=0; break; } // end of address, cause exit from loop, next will start after comma else if (c==';') { c=0; break; } // end of group address list, treat it like single address else if (c=='@' && textcouldbeemail) atfound=true; // flag presence of @ // check if text could still be a email address by itself if (textcouldbeemail && !isalnum(c) && c!='@' && c!='_' && c!='-' && c!='.') { textcouldbeemail=false; if (atfound) { aRecipient=text; text.erase(); } atfound=false; } // now check other specials if (c=='"') { pstate=pstate_quoted; } // start of quoted string else if (c=='(') { pstate=pstate_comment; } // start of comment else if (c=='<') { aRecipient.erase(); pstate=pstate_email; } // start of angle-addr, overrides other recipient texts else if (c==':') { groupname=aRecipient; // what we've probably parsed as recipient groupname+=aName; // plus name so far groupname+=text; // plus additional text text.erase(); aName.erase(); aRecipient.erase(); pstate=pstate_trailing; } // flag presence of a group name (which can be used as name if addr itself does not have one) else { // add other text chars to the text text += c; } break; case pstate_quoted: if (c=='\\') { if (*p) c=*p++; else break; // get next char (if any) and add to result untested } else if (c=='"') { // end of quoted string pstate=pstate_sepspace; aName+=text; text.erase(); break; } // add to text text += c; break; case pstate_comment: if (c==')') { // end of comment aName+=text; text.erase(); pstate=pstate_sepspace; break; } // add to text text += c; break; case pstate_email: if (!isalnum(c) && c!='@' && c!='_' && c!='-' && c!='.') { // any non-email char terminates email, not only '>', but only '>' is swallowed if (c!='>') p--; // re-evaluate char in next state pstate=pstate_sepspace; break; } // add to email aRecipient += c; break; } // switch } while (c!=0); // handle case of pure email address without name and without < > brackets or : if (aRecipient.empty() && textcouldbeemail && atfound) aRecipient = text; else aName += text; // if name is (now) empty, but we have a group name, use the group name if (aName.empty()) aName=groupname; // remove trailing spaces in aName string::size_type n=aName.find_last_not_of(' '); if (n!=string::npos) aName.resize(n+1); // return where to continue parsing for next addr-spec (if not end of string) return p; } // parseRFC2822AddrSpec // append internal UTF8 string as RFC2047 style encoding const char *appendUTF8AsRFC2047( const char *aText, string &aString ) { const char *p,*q,*r; char c; p=aText; do { q=p; // remember start // find chars until next char that must be stored as encoded word do { c=*p; if (c==0 || (c & 0x80) || (c=='=' && *(p+1)=='?')) break; p++; } while(true); // copy chars outside encoded word directly if (p-q>0) aString.append(q,p-q); // check if end of string if (c==0) break; // pack some chars into encoded word // - start word aString.append("=?utf-8?B?"); // 10 chars start (+ 2 chars will be added at end) // - encoded data must be 75-12=63 chars or less // Using B (=b64) encoding, output of 63 chars = 63/4*3 = max 47 chars. // We use 45 max, as this is evenly divisible by 3 and output is 60 chars q=p; while (true) { // find next space while (*q && !isspace(*q) && q-p<45) q++; if (q-p>=45) break; // abort if exhausted already // find next non-space r=q; while (isspace(*r)) r++; // check if next non-space will start a new word if (*r & 0x80) { // we should include the next word as well, if possible without exceeding size if (r-p<45) { q=r; continue; } } break; } // encode binary stream and append to string appendEncoded((const uInt8 *)p,q-p,aString,enc_b); p=q; // - end word aString.append("?="); } while (true); return p; } // appendUTF8AsRFC2047 // parse character string from RFC2047 style encoding to UTF8 internal string const char *appendRFC2047AsUTF8( const char *aRFC2047, stringSize aSize, string &aString, TLineEndModes aLEM ) { const char *p,*q,*r,*w; char c = 0; const char *eot = aRFC2047+aSize; p=aRFC2047; w=NULL; // start of last detected word (to avoid re-scanning) while (p=eot || c==0) break; // try to parse encoded word q=p+2; scanword: // q is now where we start to parse word contents // p is where we would re-start reading normally if current word turns out not to be a word at all // - remember start of word scan (to avoid re-scanning it) w=p; // - get charset r=q; while (q=eot || *q!='?') continue; // is not an encoded word, parse normally sInt16 en; TCharSets charset=chs_unknown; if (StrToEnum(MIMECharSetNames, numCharSets, en, r, q-r)) charset=(TCharSets)en; // - get encoding r=++q; // continue after ? separator while (q=eot || *q!='?') continue; // is not an encoded word, parse normally TEncodingTypes encoding=enc_8bit; if (StrToEnum(MIMEEncodingNames, numMIMEencodings, en, r, q-r)) encoding=(TEncodingTypes)en; // - get data part r=++q; while (q+1=eot || *q!='?') continue; // is not an encoded word, parse normally // - decode string decoded; appendDecoded(r,q-r,decoded,encoding); // - convert to UTF-8 appendStringAsUTF8( decoded.c_str(), aString, charset, aLEM ); // - skip word terminator p=q+2; // - check for special case of adjacent words q=p; while (qp && *q=='=' && *(q+1)=='?') { // adjacent encoded words, only separated by space -> ignore space // p is after previous word q+=2; // q is after lead-in of next word goto scanword; } // p is where we continue reading } return p; } // appendRFC2047AsUTF8 // decode encoded data and append to string const char *appendDecoded( const char *aText, size_t aSize, string &aBinString, TEncodingTypes aEncoding ) { char c; const char *p=aText; uInt32 binsz; uInt8 *binP; switch (aEncoding) { case enc_quoted_printable : // decode quoted-printable content while ((c=*p++)) { // char found if (c=='=') { uInt16 code; char hex[2]; // check for soft break first if (*p=='\x0D' || *p=='\x0A') { // soft break, swallow if (*p=='\x0D') p++; if (*p=='\x0A') p++; continue; } // decode hex[0]=*p; if (*p) { p++; hex[1]=*p; if (*p) { p++; if (HexStrToUShort(hex,code,2)==2) { c=code; // decoded char } else continue; // simply ignore } else break; } else break; } // append char aBinString+=c; } aText=p; break; case enc_base64: case enc_b: // decode base 64 binsz=0; binP = b64::decode(aText, aSize, &binsz); aBinString.append((const char *)binP,binsz); b64::free(binP); aText+=aSize; break; case enc_7bit: case enc_8bit: // copy no more than size if (aSize>0) aBinString.reserve(aBinString.size()+aSize); while (*p && aSize>0) { aBinString+=*p++; aSize--; } aText=p; break; case enc_none: case enc_binary: // copy bytes aBinString.append(aText,aSize); aText+=aSize; break; case numMIMEencodings: // invalid break; } // quoted printable return aText; } // appendDecoded // encode binary stream and append to string void appendEncoded( const uInt8 *aBinary, size_t aSize, string &aString, TEncodingTypes aEncoding, sInt16 aMaxLineSize, sInt32 aCurrLineSize, bool aSoftBreaksAsCR, bool aEncodeBinary ) { char c; string::size_type linestart; const uInt8 *p; bool softbreak; uInt32 b64len; char *b64; bool processed; switch (aEncoding) { case enc_binary : case enc_none : case enc_8bit : case enc_7bit : // assume we have no 8bit chars // just copy 1:1 aString.append((const char *)aBinary,aSize); break; case enc_quoted_printable: // quote-printable encoding // - determine start of last line in aString // Note: this is because property text will be folded when lines aMaxLineSize linestart=aString.size()-aCurrLineSize; for (p=aBinary;p=string::size_type(aMaxLineSize)-8); if (!aEncodeBinary) { if (c=='\r') continue; // ignore them if (c=='\b') continue; // ignore them (optional break indicators, not relevant for QP output) if (c=='\n') { // - encode line ends aString.append("=0D=0A"); // special string for Line Ends (CR LF) processed = true; // c is processed now softbreak = true; } // if } // if // - handle soft line break (but only if really doing line breaking) // Also: avoid adding a soft break at the very end of the string if (softbreak && aMaxLineSize && p+10x7F || (uInt8)c<0x20; // '\0' will be encoded as well if (encodeIt) { // encode all non ASCII chars > 0x7F (and control chars as well) aString+="="; aString+=NibbleToHexDigit(c>>4); aString+=NibbleToHexDigit(c); } else aString+=c; // just copy } // if } break; case enc_base64: case enc_b: // use base64 encoding if (aSize>0) { // don't call b64 with size=0! b64 = b64::encode( aBinary,aSize, // what to encode &b64len, // output size aMaxLineSize, // max line size aSoftBreaksAsCR ); // append to output, if any if (b64) { aString.append(b64,b64len); // release buffer b64::free(b64); } if (aEncoding!=enc_b) { // make sure it ends with a newline for "base64" (but NOT for "b" as used in RFC2047) // Note: when used in vCard2.1, that newline is part of the property and show as an // empty line in the vCard. aString += aSoftBreaksAsCR ? "\r" : "\x0D\x0A"; } } break; default: // do nothing break; } // switch } // appendEncoded #ifdef CHINESE_SUPPORT // the flatBinTree tables for converting to and from GB2312 #include "gb2312_tables_inc.cpp" // the flatBinTree tables for converting to and from CP936 #include "cp936_tables_inc.cpp" #endif // add char (possibly multi-byte) as UTF8 to value and apply charset translation if needed // - returns > 0 if aNumChars was not correct number of bytes needed to convert an entire character; // return value is number of bytes needed to generate one output character. If return value // is<>0, no char has been appended to aVal. uInt16 appendCharsAsUTF8(const char *aChars, string &aVal, TCharSets aCharSet, uInt16 aNumChars) { uInt32 ucs4; // first char uInt8 c=*aChars; // this is a 8-bit char switch(aCharSet) { case chs_utf8 : // UTF8 is native charset of the application, simply add aVal+=c; break; case chs_ansi : case chs_iso_8859_1 : // do poor man's conversion to UCS4 // - most ANSI chars are 1:1 mapped ucs4 = ((uInt8)c & 0xFF); // - except 0x80..0x9F, use table for these if (ucs4>=0x80 && ucs4<=0x9F) ucs4=Ansi_80_to_9F_to_UCS4[ucs4-0x80]; // - convert to UTF8 UCS4toUTF8(ucs4,aVal); break; #ifdef CHINESE_SUPPORT case chs_gb2312 : // simplified Chinese GB-2312 charset // all below 0x80 are passed as-is if (c<0x80) aVal+=c; // simply append else { // 16-bit GB2312 char if (aNumChars!=2) return 2; // we need 2 chars for a successful GB-2312 // we have 2 bytes, convert them ucs4 = searchFlatBintree(gb2312_to_ucs2, (c<<8) + (uInt8)aChars[1], INCONVERTIBLE_PLACEHOLDER); // - convert to UTF8 UCS4toUTF8(ucs4,aVal); } break; case chs_cp936: // simplified chinese Windows codepage CP936 if (c<0x80) aVal+=c; // simply append else { // 0x0080 (euro sign) or 2-byte CP936 if (c==0x80) ucs4=searchFlatBintree(cp936_to_ucs2, 0x0080, INCONVERTIBLE_PLACEHOLDER); else { // 16-bit GB2312 char if (aNumChars!=2) return 2; // we need 2 chars for a successful CP936 // we have 2 bytes, convert them ucs4 = searchFlatBintree(cp936_to_ucs2, (c<<8) + (uInt8)aChars[1], INCONVERTIBLE_PLACEHOLDER); } // - convert to UTF8 UCS4toUTF8(ucs4,aVal); } break; #endif case chs_ascii : // plain 7-bit ASCII default : // unknown // only 7-bit allowed if (c & 0x80) aVal+=INCONVERTIBLE_PLACEHOLDER; else aVal+=c; break; } // switch return 0; // ok, converted aNumChars } // appendCharsAsUTF8 // add string as UTF8 to value and apply charset translation if needed // - if lineEndMode is not lem_none, all sorts of line ends will be converted // to the specified mode. void appendStringAsUTF8(const char *s, string &aVal, TCharSets aCharSet, TLineEndModes aLEM, bool aAllowFilemakerCR) { char c; const char *start=s; if (s) { while ((c=*s++)!=0) { if (aLEM!=lem_none) { // line end handling enabled if (c==0x0D) { // could be mac (0x0D) or DOS (0x0D/0x0A) if (*s==0x0A) { // this is DOS-type line end // - consume the 0x0A as well s++; // - check for 0x0D 0x0D 0x0A special case (caused by // DOS-text-file conversion of non-DOS strings) if (s>=start+3) { if (*(s-3)==0x0D) { // char before the DOS-CRLF was a 0x0D as well (and // has already produced a newline in the output // --> completely ignore this CRLF continue; } } } // is a line end, convert it to platform-lineend c='\n'; // platform } else if (c==0x0A) { // 0x0A without preceeding 0x0D = unix c='\n'; // platform } else if (c==0x0B && aAllowFilemakerCR) { // 0x0B is used as lineend in filemaker export and achilformat c='\n'; } // line end converted to platform if (c=='\n' && aLEM!=lem_cstr) { // produce specified line end switch (aLEM) { case lem_mac : c=0x0D; break; case lem_unix : c=0x0A; break; case lem_filemaker : c=0x0B; break; case lem_dos : c=0x0A; // LF will be added later aVal+=0x0D; // add CR break; default: break; } } } // line end handling enabled // normal add uInt16 i,seqlen=1; // assume logical char consists of single byte do { seqlen=appendCharsAsUTF8(s-seqlen,aVal,aCharSet,seqlen); // add char (possibly with UTF8 expansion) to aVal if (seqlen<=1) break; // done for (i=1;i=start+3) { if (*(aUTF8-3)==0x0D) { // char before the DOS-CRLF was a 0x0D as well (and // has already produced a newline in the output // --> completely ignore this CRLF continue; } } } // is a line end, convert it to platform-lineend c='\n'; // platform } else { // must be 0x0A // 0x0A without preceeding 0x0D = unix c='\n'; // platform } // line end converted to platform if (aLEM!=lem_cstr) { // produce specified line end switch (aLEM) { case lem_mac : c=0x0D; break; case lem_filemaker : c=0x0B; break; case lem_unix : c=0x0A; break; case lem_dos : c=0x0A; // LF will be added later n++; // count it extra if (aMaxBytes && n>=aMaxBytes) goto stringfull; // no room to complete it, ignore it appendCharToString(0x0D,aVal,aQuotingMode); break; default: break; } } appendCharToString(c,aVal,aQuotingMode); n++; // count it } // line end, handling enabled else { // non lineend (or lineend not handled specially) if (aCharSet==chs_utf8) { aUTF8++; // - simply add char appendCharToString(c,aVal,aQuotingMode); n++; } else { // - make UCS4 p=aUTF8; // save previous position to detect if we have processed all aUTF8=UTF8toUCS4(aUTF8,ucs4); // now we have UCS4 if (ucs4==0) { // UTF8 resulting in UCS4 null char is not allowed ucs4=INCONVERTIBLE_PLACEHOLDER; } else { // convert to specified charset switch (aCharSet) { case chs_ansi: case chs_iso_8859_1: if ((ucs4<=0xFF && ucs4>=0xA0) || ucs4<0x80) // 00..7F and A0..FF directly map to ANSI appendCharToString(ucs4,aVal,aQuotingMode); else { // search for matching ANSI in table uInt8 k; for (k=0; k<0x20; k++) { if (ucs4==Ansi_80_to_9F_to_UCS4[k]) { // found in table break; } } if (k<0x20) // conversion found aVal+=k+0x80; else // no conversion found in table aVal+=INCONVERTIBLE_PLACEHOLDER; } // not in 1:1 range 0..7F, A0..FF n++; break; #ifdef CHINESE_SUPPORT case chs_gb2312 : // simplified Chinese GB-2312 charset // all below 0x80 are passed as-is if (ucs4<0x80) { appendCharToString(ucs4,aVal,aQuotingMode); // simply append ASCII codes n++; } else { // convert to 16-bit GB2312 char uInt16 gb = searchFlatBintree(ucs2_to_gb2312, ucs4, INCONVERTIBLE_PLACEHOLDER); // check if we have space if (aMaxBytes!=0 && n+2>aMaxBytes) goto stringfull; // append as two bytes to output string aVal+=gb >> 8; aVal+=gb & 0xFF; n+=2; } break; case chs_cp936 : // simplified Chinese CP936 windows codepage // all below 0x80 are passed as-is if (ucs4<0x80) { appendCharToString(ucs4,aVal,aQuotingMode); // simply append ASCII codes n++; } else { // convert to CP936 16-bit representation uInt16 twobytes = searchFlatBintree(ucs2_to_cp936, ucs4, INCONVERTIBLE_PLACEHOLDER); // append as two bytes to output string, but only this is a CP936 two-byte at all if (twobytes>0x0080) { // check if we have space if (aMaxBytes!=0 && n+2>aMaxBytes) goto stringfull; aVal+=twobytes >> 8; // sub-page lead in n++; } aVal+=twobytes & 0xFF; // sub-page code n++; } break; #endif case chs_ascii: // explicit ASCII: convert some special chars to plain ASCII if ((ucs4 & 0xFFFFFF80) !=0) { // search in ASCIIfy table uInt16 k=0; while (ASCIIfyTable[k].ucs4!=0) { if (ucs4==ASCIIfyTable[k].ucs4) { // found, fetch ASCII-equivalent ucs4=ASCIIfyTable[k].ascii; break; // use it } k++; } } // fall through to default, which does not know ANY non-ASCII default: // only 7 bit ASCII is allowed if ((ucs4 & 0xFFFFFF80) !=0) aVal+=INCONVERTIBLE_PLACEHOLDER; else appendCharToString(ucs4,aVal,aQuotingMode); // simply append ASCII codes n++; break; } // switch } // valid UCS4 } // not already UTF8 } // if not lineend // processed until here p=aUTF8; } // while not end of input string } // not already UTF8 // return true if input string completely consumed stringfull: return (*p==0); } // appendUTF8ToString // convert UTF8 to UCS4 // - returns pointer to next char // - returns UCS4=0 on error (no char, bad sequence, sequence not complete) const char *UTF8toUCS4(const char *aUTF8, uInt32 &aUCS4) { uInt8 c; sInt16 morechars; if ((c=*aUTF8)!=0) { aUTF8++; // there is a char morechars=0; // decode UTF8 lead-in if ((c & 0x80) == 0) { // single byte aUCS4=c; morechars=0; } else if ((c & 0xE0) == 0xC0) { // two bytes aUCS4=c & 0x1F; morechars=1; } else if ((c & 0xF0) == 0xE0) { aUCS4=c & 0x0F; morechars=2; } else if ((c & 0xF8) == 0xF0) { aUCS4=c & 0x07; morechars=3; } else if ((c & 0xFC) == 0xF8) { aUCS4=c & 0x03; morechars=4; } else if ((c & 0xFE) == 0xFC) { aUCS4=c & 0x01; morechars=5; } else { // bad char aUCS4=0; } // process additional chars while(morechars--) { if ((c=*aUTF8)==0) { // unfinished sequence aUCS4=0; break; } aUTF8++; if ((c & 0xC0) != 0x80) { // bad additional char aUCS4=0; break; } // each additional char adds 6 new bits aUCS4 = aUCS4 << 6; // shift existing bits aUCS4 |= (c & 0x3F); // add new bits } } else { // no char aUCS4=0; } // return pointer to next char return aUTF8; } // UTF8toUCS4 // convert UCS4 to UTF8 (0 char is not allowed and will be ignored!) void UCS4toUTF8(uInt32 aUCS4, string &aUTF8) { uInt8 c; // ignore null char if (aUCS4==0) return; // create UTF8 lead-in sInt16 morechars=0; if (aUCS4<0x00000080) { // one byte c=aUCS4; } else if (aUCS4<0x00000800) { // two bytes c=0xC0 | ((aUCS4 >> 6) & 0x1F); morechars=1; } else if (aUCS4<0x00010000) { // three bytes c=0xE0 | ((aUCS4 >> 12) & 0x0F); morechars=2; } else if (aUCS4<0x00200000) { // four bytes c=0xF0 | ((aUCS4 >> 18) & 0x07); morechars=3; } else if (aUCS4<0x04000000) { // five bytes c=0xF8 | ((aUCS4 >> 24) & 0x03); morechars=4; } else { // six bytes c=0xFC | ((aUCS4 >> 30) & 0x01); morechars=5; } // add lead-in aUTF8+=c; // add rest of sequence while (morechars--) { c= 0x80 | ((aUCS4 >> (morechars * 6)) & 0x3F); aUTF8+=c; } } // UCS4toUTF8 /* Encoding UTF-16 (excerpt from RFC 2781, paragraph 2.1) Encoding of a single character from an ISO 10646 character value to UTF-16 proceeds as follows. Let U be the character number, no greater than 0x10FFFF. 1) If U < 0x10000, encode U as a 16-bit unsigned integer and terminate. 2) Let U' = U - 0x10000. Because U is less than or equal to 0x10FFFF, U' must be less than or equal to 0xFFFFF. That is, U' can be represented in 20 bits. 3) Initialize two 16-bit unsigned integers, W1 and W2, to 0xD800 and 0xDC00, respectively. These integers each have 10 bits free to encode the character value, for a total of 20 bits. 4) Assign the 10 high-order bits of the 20-bit U' to the 10 low-order bits of W1 and the 10 low-order bits of U' to the 10 low-order bits of W2. Terminate. Graphically, steps 2 through 4 look like: U' = yyyyyyyyyyxxxxxxxxxx W1 = 110110yyyyyyyyyy W2 = 110111xxxxxxxxxx */ // convert UCS4 to UTF-16 // - returns 0 for UNICODE range UCS4 and first word of UTF-16 for non UNICODE uInt16 UCS4toUTF16(uInt32 aUCS4, uInt16 &aUTF16) { if (aUCS4<0x10000) { // in unicode range: single UNICODE char aUTF16=aUCS4; return 0; // no second char } else { // out of UNICODE range aUCS4-=0x10000; if (aUCS4>0xFFFF) { // inconvertible aUTF16=INCONVERTIBLE_PLACEHOLDER; return 0; } else { // convert to two-word UNICODE / UCS-2 aUTF16=0xD800+(aUCS4>>10); return 0xDC00+(aUCS4 & 0x03FF); } } } // UCS4toUTF16 /* Decoding UTF-16 Decoding of a single character from UTF-16 to an ISO 10646 character value proceeds as follows. Let W1 be the next 16-bit integer in the sequence of integers representing the text. Let W2 be the (eventual) next integer following W1. 1) If W1 < 0xD800 or W1 > 0xDFFF, the character value U is the value of W1. Terminate. 2) Determine if W1 is between 0xD800 and 0xDBFF. If not, the sequence is in error and no valid character can be obtained using W1. Terminate. 3) If there is no W2 (that is, the sequence ends with W1), or if W2 is not between 0xDC00 and 0xDFFF, the sequence is in error. Terminate. 4) Construct a 20-bit unsigned integer U', taking the 10 low-order bits of W1 as its 10 high-order bits and the 10 low-order bits of W2 as its 10 low-order bits. 5) Add 0x10000 to U' to obtain the character value U. Terminate. Note that steps 2 and 3 indicate errors. Error recovery is not specified by this document. When terminating with an error in steps 2 and 3, it may be wise to set U to the value of W1 to help the caller diagnose the error and not lose information. Also note that a string decoding algorithm, as opposed to the single-character decoding described above, need not terminate upon detection of an error, if proper error reporting and/or recovery is provided. */ // convert UTF-16 to UCS4 // - returns pointer to next char // - returns UCS4=0 on error (no char, bad sequence, sequence not complete) const uInt16 *UTF16toUCS4(const uInt16 *aUTF16P, uInt32 &aUCS4) { uInt16 utf16=*aUTF16P++; if (utf16<0xD800 || utf16>0xDFFF) { // single char unicode aUCS4=utf16; } else { // could be two-char if (utf16<=0xDBFF) { // valid first char: check second char uInt16 utf16_2 = *aUTF16P; // next if (utf16_2 && utf16_2>=0xDC00 && utf16_2<=0xDFFF) { // second char exists and is valid aUTF16P++; // advance now aUCS4 = ((utf16 & 0x3FF) << 10) + (utf16_2 & 0x3FF); } else aUCS4=0; // no char } else { aUCS4=0; // no char } } // return advanced pointer return aUTF16P; } // UCS4toUTF16 // add UTF8 string as UTF-16 byte stream to 8-bit string // - if aLEM is not lem_none, occurrence of any type of Linefeeds // (LF,CR,CRLF and even CRCRLF) in input string will be // replaced by the specified line end type // - output is clipped after ByteString reaches aMaxBytes size (if not 0), = approx half as many Unicode chars // - returns true if all input could be converted, false if output is clipped bool appendUTF8ToUTF16ByteString( cAppCharP aUTF8, string &aUTF16ByteString, bool aBigEndian, TLineEndModes aLEM, uInt32 aMaxBytes ) { uInt32 ucs4; uInt16 utf16=0,utf16_1; cAppCharP p; while (aUTF8 && *aUTF8) { // convert next UTF8 char to UCS4 p=UTF8toUCS4(aUTF8, ucs4); if (ucs4==0) break; // error in UTF8 encoding, exit // convert line ends if (ucs4 == '\n' && aLEM!=lem_none && aLEM!=lem_cstr) { // produce specified line end utf16_1=0; switch (aLEM) { case lem_mac : utf16=0x0D; break; case lem_filemaker : utf16=0x0B; break; case lem_unix : utf16=0x0A; break; case lem_dos : utf16_1=0x0D; // CR.. utf16=0x0A; // ..then LF break; default: break; } } else { // ordinary char, use UTF16 encoding utf16_1 = UCS4toUTF16(ucs4,utf16); } // check if appending UTF16 would exceed max size specified if (aMaxBytes!=0 && aUTF16ByteString.size() + (utf16_1 ? 4 : 2) > aMaxBytes) break; // we can append, advance input pointer aUTF8 = p; // now append if (aBigEndian) { // Big end first, Motorola order if (utf16_1) { aUTF16ByteString += (char)((utf16_1 >> 8) & 0xFF); aUTF16ByteString += (char)(utf16_1 & 0xFF); } aUTF16ByteString += (char)((utf16 >> 8) & 0xFF); aUTF16ByteString += (char)(utf16 & 0xFF); } else { // Little end first, Intel order if (utf16_1) { aUTF16ByteString += (char)((utf16_1 >> 8) & 0xFF); aUTF16ByteString += (char)(utf16_1 & 0xFF); } aUTF16ByteString += (char)(utf16 & 0xFF); aUTF16ByteString += (char)((utf16 >> 8) & 0xFF); } } // while // true if all input consumed return (aUTF8==NULL) || (*aUTF8==0); } // appendUTF8ToUTF16ByteString // add UTF16 byte string as UTF8 to value void appendUTF16AsUTF8( const uInt16 *aUTF16, uInt32 aNumUTF16Chars, bool aBigEndian, string &aVal, bool aConvertLineEnds, bool aAllowFilemakerCR ) { uInt32 ucs4; uInt16 utf16pair[2]; cAppCharP inP = (cAppCharP)aUTF16; bool lastWasCR=false; while (inP && !(*inP==0 && *(inP+1)==0) && aNumUTF16Chars>0) { // get two words (in case of surrogate pair) if (aBigEndian) { // Motorola order utf16pair[0]=((*(inP) & 0xFF)<<8) + (*(inP+1) & 0xFF); if (aNumUTF16Chars>1) utf16pair[1]=((*(inP+2) & 0xFF)<<8) + (*(inP+3) & 0xFF); } else { // Intel order utf16pair[0]=((*(inP+1) & 0xFF)<<8) + (*(inP) & 0xFF); if (aNumUTF16Chars>1) utf16pair[1]=((*(inP+3) & 0xFF)<<8) + (*(inP+2) & 0xFF); } cAppCharP hP = (cAppCharP)UTF16toUCS4(utf16pair, ucs4); /* PDEBUGPRINTFX(DBG_PARSE+DBG_EXOTIC,( "Parsed %ld bytes: *(inP)=0x%02hX, *(inP+1)=0x%02hX, *(inP+2)=0x%02hX, *(inP+3)=0x%02hX, utf16pair[0]=0x%04hX, utf16pair[1]=0x%04hX, ucs4=0x%04lX", (uInt32)(hP-(cAppCharP)utf16pair), (uInt16)*(inP), (uInt16)*(inP+1), (uInt16)*(inP+2), (uInt16)*(inP+3), (uInt16)utf16pair[0], (uInt16)utf16pair[1], (uInt32)ucs4 )); */ uInt32 bytes=hP-(cAppCharP)utf16pair; inP+=bytes; // next UTF16 to check aNumUTF16Chars-=bytes/2; // count down UTF16 chars // convert line ends if selected if (aConvertLineEnds) { if (ucs4 == 0x0D) { lastWasCR=true; continue; } else { if (ucs4 == 0x0A || (aAllowFilemakerCR && ucs4 == 0x0B)) ucs4 = '\n'; // convert to LineEnd else if (lastWasCR) aVal += '\n'; // insert a LineEnd lastWasCR=false; } } // append to UTF-8 string UCS4toUTF8(ucs4, aVal); } if (lastWasCR) aVal += '\n'; // input string ended on CR, must be shown in output } // appendUTF16AsUTF8 #ifdef BINTREE_GENERATOR // add a key/value pair to the binary tree void addToBinTree(TBinTreeNode *&aBinTree, treeval_t aMinKey, treeval_t aMaxKey, treeval_t aKey, treeval_t aValue) { // start at root TBinTreeNode **nextPP = &aBinTree; treeval_t cmpval; do { // create the new decision value from max and min cmpval = aMinKey+((aMaxKey-aMinKey) >> 1); // create the node if not already there if (*nextPP==NULL) { *nextPP = new TBinTreeNode; (*nextPP)->key = cmpval; (*nextPP)->nextHigher=NULL; (*nextPP)->nextLowerOrEqual=NULL; (*nextPP)->value=0; } // check if the node CREATED is a leaf node // this is the case if max==min if (aMaxKey==aMinKey) { // save leaf value (possibly overwriting existing leaf value for same code) (*nextPP)->value=aValue; break; } // decide which way to go if (aKey>cmpval) { // go to the "higher" side nextPP = &((*nextPP)->nextHigher); // determine new minimum aMinKey = cmpval+1; // minimum must be higher than cmpval } else { // go to the "lower or equal" side nextPP = &((*nextPP)->nextLowerOrEqual); // determine new maximum aMaxKey = cmpval; // maximum must be lower or equal than cmpval } } while(true); } // addToBinTree // dispose a bintree void disposeBinTree(TBinTreeNode *&aBinTree) { if (!aBinTree) return; if (aBinTree->nextHigher) disposeBinTree(aBinTree->nextHigher); if (aBinTree->nextLowerOrEqual) disposeBinTree(aBinTree->nextLowerOrEqual); delete aBinTree; aBinTree=NULL; } // disposeBinTree // convert key to value using a flat bintree treeval_t searchBintree(TBinTreeNode *aBinTree, treeval_t aKey, treeval_t aUndefValue, treeval_t aMinKey, treeval_t aMaxKey) { treeval_t cmpval; while(aBinTree) { // create the new decision value from max and min cmpval = aMinKey+((aMaxKey-aMinKey) >> 1); // must match stored cmpval if (cmpval!=aBinTree->key) return aUndefValue; // check if next node must be leaf if the tree contains our key, // this is the case if max==min if (aMaxKey==aMinKey) { if (aBinTree->nextHigher!=NULL || aBinTree->nextLowerOrEqual!=NULL) { // no leaf value here, should not be the case ever (we should have // encountered a node with no left or right link before this!) return aUndefValue; } else { // found a leaf value here return aBinTree->value; } } // decide which way to go if (aKey>cmpval) { // go to the "higher" side = just next element in array, except if we have the special marker here if (aBinTree->nextHigher == NULL) return aUndefValue; // we should go higher-side, but can't -> unknown key aBinTree=aBinTree->nextHigher; // determine new minimum aMinKey = cmpval+1; // minimum must be higher than cmpval } else { // go to the "lower" side = element at index indicated by current element, except if we have the special marker here if (aBinTree->nextLowerOrEqual == NULL) return aUndefValue; // we should go lower-or-equal-side, but can't -> unknown key aBinTree=aBinTree->nextLowerOrEqual; // determine new maximum aMaxKey = cmpval; // maximum must be lower or equal than cmpval } } // if we reach the end of the array, key is not in the tree return aUndefValue; } // searchBintree // make a flat form representation of the bintree in a one-dimensional array // - higher-side links are implicit (nodes following each other), // lower-or-equal-side links are explicit static bool flatBinTreeRecursion( TBinTreeNode *aBinTree, size_t &aIndex, treeval_t *aFlatArray, size_t aArrSize, treeval_t aLinksStart, treeval_t aLinksEnd ) { // check if array is full if (aIndex>=aArrSize) return false; // examine node to flatten if (aBinTree->nextHigher==NULL && aBinTree->nextLowerOrEqual==NULL) { // this is a leaf node, containing only the value if (aBinTree->value>=aLinksStart && aBinTree->value<=aLinksEnd) return false; // link space and value space overlap aFlatArray[aIndex]=aBinTree->value; aIndex++; } else if (aBinTree->nextHigher==NULL) { // lower-side-only node: set special mark to specify that lower-or-equal side // implicitly follows (instead of higher-side) aFlatArray[aIndex]=aLinksStart + 1; // no node points to the immediately following node explicitly, so 1 can be used as special marker aIndex++; // - recurse to generate it if (!flatBinTreeRecursion(aBinTree->nextLowerOrEqual,aIndex,aFlatArray,aArrSize,aLinksStart,aLinksEnd)) return false; } else { // this is a branch // - lower-or-equal side is represented as an index in the array aFlatArray[aIndex]=aLinksStart + 0; // default to not-existing (no node points to itself, so 0 can be used as NIL index value) // - higher side branch follows immediately size_t linkindex = aIndex++; // - recurse to generate it if (!flatBinTreeRecursion(aBinTree->nextHigher,aIndex,aFlatArray,aArrSize,aLinksStart,aLinksEnd)) return false; // - now we have the index where we must insert the lower-or-equal side if (aBinTree->nextLowerOrEqual!=NULL) { // there is a lower-or-equal side // - place relative link from original node uInt32 rellink=aIndex-linkindex; if ((uInt32)aLinksStart+rellink>(uInt32)aLinksEnd-1L) { // we need a long link // - move generated higher side branch one up for (size_t k=aIndex-1; k>linkindex; k--) aFlatArray[k+1]=aFlatArray[k]; aIndex++; // we've eaten up one extra entry now // - now set long link aFlatArray[linkindex]=aLinksEnd-1; // long link marker if (rellink>0xFFFF) return false; // cannot jump more than 64k aFlatArray[linkindex+1]=rellink; // long link } else { // short link is ok aFlatArray[linkindex]=aLinksStart+rellink; } // - now create the lower-or-equal side if (!flatBinTreeRecursion(aBinTree->nextLowerOrEqual,aIndex,aFlatArray,aArrSize,aLinksStart,aLinksEnd)) return false; } } return true; } // flatBinTreeRecursion // make a flat form representation of the bintree in a one-dimensional array // - higher-side links are implicit (nodes following each other), // lower-or-equal-side links are explicit bool flatBinTree( TBinTreeNode *aBinTree, TConvFlatTree &aFlatTree, size_t aArrSize, treeval_t aMinKey, treeval_t aMaxKey, treeval_t aLinksStart, treeval_t aLinksEnd ) { // save tree params aFlatTree.numelems=0; aFlatTree.minkey=aMinKey; aFlatTree.maxkey=aMaxKey; aFlatTree.linksstart=aLinksStart; aFlatTree.linksend=aLinksEnd; // now create actual tree size_t index=0; if (!flatBinTreeRecursion(aBinTree,index,aFlatTree.elements,aArrSize,aLinksStart,aLinksEnd)) return false; aFlatTree.numelems=index; // actual length of array return true; } // flatBinTree #endif // convert key to value using a flat bintree treeval_t searchFlatBintree(const TConvFlatTree &aFlatTree, treeval_t aKey, treeval_t aUndefValue) { treeval_t cmpval,thisnode; size_t index=0; // get start min and max treeval_t minKey = aFlatTree.minkey; treeval_t maxKey = aFlatTree.maxkey; // reject out-of-bounds keys immediately if (aKeymaxKey) return aUndefValue; do { // create the new decision value from max and min cmpval = minKey+((maxKey-minKey) >> 1); thisnode = aFlatTree.elements[index]; // check if next node must be leaf if the tree contains our key, // this is the case if max==min if (maxKey==minKey) { #ifdef BINTREE_GENERATOR if (thisnode>=aFlatTree.linksstart && thisnode<=aFlatTree.linksend) { // no leaf value here, should not be the case ever (we should have // encountered a node with no left or right link before this!) return aUndefValue; } else #endif { // found a leaf value here return (treeval_t) thisnode; } } // decide which way to go if (aKey>cmpval) { // go to the "higher" side = just next element in array, except if we have the special marker here if (thisnode == aFlatTree.linksstart+1) return aUndefValue; // we should go higher-side, but can't -> unknown key // next node is next index (or one more in case this is a long link) if (thisnode == aFlatTree.linksend-1) index++; index++; // determine new minimum minKey = cmpval+1; // minimum must be higher than cmpval } else { // go to the "lower" side = element at index indicated by current element, except if we have the special marker here if (thisnode == aFlatTree.linksstart+1) index++; // special case, "lower" side is immediately following because there is no "higher" side else { #ifdef BINTREE_GENERATOR // if node contains a leaf value instead of a link, something is wrong if (thisnodeaFlatTree.linksend) return aUndefValue; // no leaf expected here #endif if (thisnode==aFlatTree.linksend-1) { // long link index++; // skip long link marker thisnode = aFlatTree.elements[index]; // get link value index = index+thisnode; // jump by link value } else { // short link index = index+(thisnode-aFlatTree.linksstart); // get index of next node (relative branch) } if (index==0) return aUndefValue; // there is no link } // determine new maximum maxKey = cmpval; // maximum must be lower or equal than cmpval } } while(index0) { AppendHexByte(aStringObj,*aBinary++); aBinSz--; } } // StringObjHexString // add (already encoded!) CGI to existing URL string bool addCGItoString(string &aStringObj, cAppCharP aCGI, bool noduplicate) { if (!noduplicate || aStringObj.find(aCGI)==string::npos) { // - Add CGI separator if and only if none exists already if (aStringObj.find("?")==string::npos) aStringObj += '?'; aStringObj += aCGI; return true; // added } return false; // nothing added } // encode string for being used as a CGI key/value element string encodeForCGI(cAppCharP aCGI) { string cgi; cAppCharP p = aCGI; while (p && *p) { if (*p>0x7E || *p<=0x20 || *p=='%' || *p=='?' || *p=='&' || *p=='#') { // CGI encode these cgi += '%'; AppendHexByte(cgi, *p); } else { // use as-is cgi += *p; } p++; } return cgi; } // encodeForCGI // Count bits int countbits(uInt32 aMask) { int bits=0; uInt32 mask=0x0000001; while (mask) { if (aMask & mask) bits++; mask=mask << 1; } return bits; } // countbits // make uppercase void StringUpper(string &aString) { for(uInt32 k=0; kcontent) { // no content at all aStringObj.erase(); } else if ( // NOTE: Opaque works only with modified syncML toolkit which // makes sure opaque content is ALSO TERMINATED LIKE A C-STRING aPcdataP->contentType == SML_PCDATA_STRING || aPcdataP->contentType == SML_PCDATA_OPAQUE ) { // string or opaque type aStringObj.assign((char *)aPcdataP->content, aPcdataP->length); } else if (aPcdataP->contentType == SML_PCDATA_EXTENSION) { // extension type StringObjPrintf(aStringObj,"[PCDATA_EXTENSION Type=%hd]",(sInt16)aPcdataP->extension); } else { // other type StringObjPrintf(aStringObj,"[PCDATA Type=%hd]",(sInt16)aPcdataP->contentType); } } // smlPCDataToStringObj // returns item string or empty string (NEVER NULL) const char *smlItemDataToCharP(const SmlItemPtr_t aItemP) { if (!aItemP) return ""; return smlPCDataToCharP(aItemP->data); } // smlItemDataToCharP // returns first item string or empty string (NEVER NULL) const char *smlFirstItemDataToCharP(const SmlItemListPtr_t aItemListP) { if (!aItemListP) return ""; return smlItemDataToCharP(aItemListP->item); } // smlFirstItemDataToCharP #endif //SYSYNC_ENGINE // returns pointer to PCdata contents or null string. If aSizeP!=NULL, length will be stored in *aSize const char *smlPCDataToCharP(const SmlPcdataPtr_t aPcdataP, stringSize *aSizeP) { const char *str = smlPCDataOptToCharP(aPcdataP, aSizeP); if (str) return str; return ""; } // smlPCDataToCharP // returns pointer to PCdata contents if existing, NULL otherwise. // If aSizeP!=NULL, length will be stored in *aSize const char *smlPCDataOptToCharP(const SmlPcdataPtr_t aPcdataP, stringSize *aSizeP) { if (!aPcdataP || !aPcdataP->content) { return NULL; // we have no value, it could be empty howevert if (aSizeP) *aSizeP=0; } if (aPcdataP->length==0) { // empty content if (aSizeP) *aSizeP=0; return ""; // return empty string } else if ( // NOTE: Opaque works only with modified syncML toolkit which // makes sure opaque content is ALSO TERMINATED LIKE A C-STRING aPcdataP->contentType == SML_PCDATA_STRING || aPcdataP->contentType == SML_PCDATA_CDATA || // XML only aPcdataP->contentType == SML_PCDATA_OPAQUE // WBXML only ) { // return pointer to content if (aSizeP) *aSizeP=aPcdataP->length; return (char *) aPcdataP->content; } else { // no string if (aSizeP) *aSizeP=11; return "[no string]"; } } // smlPCDataOptToCharP // returns pointer to source or target LocURI const char *smlSrcTargLocURIToCharP(const SmlTargetPtr_t aSrcTargP) { if (!aSrcTargP || !aSrcTargP->locURI) { return ""; // empty string } else { // return PCdata string contents return smlPCDataToCharP(aSrcTargP->locURI); } } // smlSrcTargLocURIToCharP // returns pointer to source or target LocName const char *smlSrcTargLocNameToCharP(const SmlTargetPtr_t aSrcTargP) { if (!aSrcTargP || !aSrcTargP->locName) { return ""; // empty string } else { // return PCdata string contents return smlPCDataToCharP(aSrcTargP->locName); } } // smlSrcTargLocNameToCharP #ifdef SYSYNC_ENGINE // returns error code made ready for SyncML sending (that is, remove offset // of 10000 if present, and make generic error 500 for non-SyncML errors, // and return LOCERR_OK as 200) localstatus syncmlError(localstatus aErr) { if (aErr==LOCERR_OK) return 200; // SyncML ok code if (aErr<999) return aErr; // return as is if (aErr>=LOCAL_STATUS_CODE+100 && aErr<=999) return aErr-LOCAL_STATUS_CODE; // return with offset removed // no suitable conversion return 500; // return generic "bad" } // localError // returns error code made local (that is, offset by 10000 in case aErr is a // SyncML status code <10000, and convert 200 into LOCERR_OK) localstatus localError(localstatus aErr) { if (aErr==200 || aErr==0) return LOCERR_OK; if (aErrassign(p,q-p); if (aPort) aPort->assign(q+1); } else { // no prot spec if (aAddr) aAddr->assign(p); if (aPort) aPort->erase(); } } // splitHostname // translate %XX into corresponding character in-place void urlDecode(string *str) { // nothing todo? if (!str || str->find('%') == string::npos) return; string replacement; replacement.reserve(str->size()); const char *in = str->c_str(); char c; while ((c = *in++) != 0) { if (c == '%') { c = tolower(*in++); unsigned char value = 0; if (!c) { break; } else if (c >= '0' && c <= '9') { value = c - '0'; } else if (c >= 'a' && c <= 'f') { value = c - 'a' + 10; } else { // silently skip invalid character } value *= 16; c = tolower(*in++); if (!c) { break; } else if (c >= '0' && c <= '9') { value += c - '0'; replacement.append((char *)&value, 1); } else if (c >= 'a' && c <= 'f') { value += c - 'a' + 10; replacement.append((char *)&value, 1); } else { // silently skip invalid character } } else { replacement.append(&c, 1); } } *str = replacement; } // split URL into protocol, hostname, document name and auth-info (user, password); // the optional query and port are not url-decoded, everything else is void splitURL(const char *aURI,string *aProtocol,string *aHost, string *aDoc, string *aUser, string *aPasswd, string *aPort, string *aQuery) { const char *p,*q,*r; p=aURI; // extract protocol q=strchr(p,':'); if (q) { // protocol found if (aProtocol) aProtocol->assign(p,q-p); p=q+1; // past colon int count = 0; while (*p=='/' && count < 2) { p++; // past trailing slashes (two expected, ignore if less are given) count++; } // now identify end of host part string host; q=strchr(p, '/'); if (!q) { // no slash, skip forward to end of string q = p + strlen(p); } host.assign(p, q - p); // if protocol specified, check for auth info const char *h = host.c_str(); q=strchr(h,'@'); r=strchr(h,':'); if (q && r && q>r) { // auth exists if (aUser) aUser->assign(h,r-h); if (aPasswd) aPasswd->assign(r+1,q-r-1); // skip auth in full string p += q + 1 - h; } else { // no auth found if (aUser) aUser->erase(); if (aPasswd) aPasswd->erase(); } // p now points to host part, as expected below } else { // no protocol found if (aProtocol) aProtocol->erase(); // no protocol, no auth if (aUser) aUser->erase(); if (aPasswd) aPasswd->erase(); } // separate hostname and document std::string host; // - check for path q=strchr(p,'/'); // - if no path, check if there is a CGI param directly after the host name if (!q) { // doc part left empty in this case if (aDoc) aDoc->erase(); q=strchr(p,'?'); if (q) { // query directly follows host host.assign(p, q - p); if (aQuery) aQuery->assign(q + 1); } else { // entire string is considered the host host.assign(p); if (aQuery) aQuery->erase(); } } else { // host part stops at slash host.assign(p, q - p); // in case of '/', do not put slash into docname // even if it would be empty (caller expected to add // slash as needed) p = q + 1; // exclude slash // now check for query q=strchr(p,'?'); if (q) { // split at question mark if (aDoc) aDoc->assign(p, q - p); if (aQuery) aQuery->assign(q + 1); } else { // whole string is document name if (aDoc) aDoc->assign(p); if (aQuery) aQuery->erase(); } } // remove optional port from host part before url-decoding, because // that might introduce new : characters into the host name size_t colon = host.find(':'); if (colon != host.npos) { if (aHost) aHost->assign(host.substr(0, colon)); if (aPort) aPort->assign(host.substr(colon + 1)); } else { if (aHost) aHost->assign(host); if (aPort) aPort->erase(); } } // splitURL #ifdef SPLIT_URL_MAIN #include #include static void test(const std::string &in, const std::string &expected) { string protocol, host, doc, user, password, port, query; char buffer[1024]; splitURL(in.c_str(), &protocol, &host, &doc, &user, &password, &port, &query); // URL-decode each part urlDecode(&protocol); urlDecode(&host); urlDecode(&doc); urlDecode(&user); urlDecode(&password); sprintf(buffer, "prot '%s' user '%s' passwd '%s' host '%s' port '%s' doc '%s' query '%s'", protocol.c_str(), user.c_str(), password.c_str(), host.c_str(), port.c_str(), doc.c_str(), query.c_str()); printf("%s -> %s\n", in.c_str(), buffer); assert(expected == buffer); } int main(int argc, char **argv) { test("http://user:passwd@host/patha/pathb?query", "prot 'http' user 'user' passwd 'passwd' host 'host' port '' doc 'patha/pathb' query 'query'"); test("http://user:passwd@host:port/patha/pathb?query", "prot 'http' user 'user' passwd 'passwd' host 'host' port 'port' doc 'patha/pathb' query 'query'"); test("file:///foo/bar", "prot 'file' user '' passwd '' host '' port '' doc 'foo/bar' query ''"); test("http://host%3a:port?param=value", "prot 'http' user '' passwd '' host 'host:' port 'port' doc '' query 'param=value'"); test("http://host%3a?param=value", "prot 'http' user '' passwd '' host 'host:' port '' doc '' query 'param=value'"); test("foo%24", "prot '' user '' passwd '' host 'foo$' port '' doc '' query ''"); test("foo%2f", "prot '' user '' passwd '' host 'foo/' port '' doc '' query ''"); test("foo%2A", "prot '' user '' passwd '' host 'foo*' port '' doc '' query ''"); test("foo%24bar", "prot '' user '' passwd '' host 'foo$bar' port '' doc '' query ''"); test("%24bar", "prot '' user '' passwd '' host '$bar' port '' doc '' query ''"); test("foo%2", "prot '' user '' passwd '' host 'foo' port '' doc '' query ''"); test("foo%", "prot '' user '' passwd '' host 'foo' port '' doc '' query ''"); test("foo%g", "prot '' user '' passwd '' host 'foo' port '' doc '' query ''"); test("foo%gh", "prot '' user '' passwd '' host 'foo' port '' doc '' query ''"); test("%ghbar", "prot '' user '' passwd '' host 'bar' port '' doc '' query ''"); return 0; } #endif // SPLIT_URL_MAIN #endif //SYSYNC_ENGINE // returns type from meta const char *smlMetaTypeToCharP(SmlMetInfMetInfPtr_t aMetaP) { if (!aMetaP) return NULL; // no meta at all return smlPCDataToCharP(aMetaP->type); } // smlMetaTypeToCharP // returns Next Anchor from meta const char *smlMetaNextAnchorToCharP(SmlMetInfMetInfPtr_t aMetaP) { if (!aMetaP) return NULL; // no meta at all if (!aMetaP->anchor) return NULL; // no anchor at all return smlPCDataToCharP(aMetaP->anchor->next); } // smlMetaAnchorToCharP // returns Last Anchor from meta const char *smlMetaLastAnchorToCharP(SmlMetInfMetInfPtr_t aMetaP) { if (!aMetaP) return NULL; // no meta at all if (!aMetaP->anchor) return NULL; // no anchor at all return smlPCDataToCharP(aMetaP->anchor->last); } // smlMetaLastAnchorToCharP // returns DevInf pointer if any in specified PCData, NULL otherwise SmlDevInfDevInfPtr_t smlPCDataToDevInfP(const SmlPcdataPtr_t aPCDataP) { if (!aPCDataP) return NULL; if (aPCDataP->contentType!=SML_PCDATA_EXTENSION) return NULL; if (aPCDataP->extension!=SML_EXT_DEVINF) return NULL; return (SmlDevInfDevInfPtr_t)(aPCDataP->content); } // smlPCDataToDevInfP // returns MetInf pointer if any in specified PCData, NULL otherwise SmlMetInfMetInfPtr_t smlPCDataToMetInfP(const SmlPcdataPtr_t aPCDataP) { if (!aPCDataP) return NULL; if (aPCDataP->contentType!=SML_PCDATA_EXTENSION) return NULL; if (aPCDataP->extension!=SML_EXT_METINF) return NULL; return (SmlMetInfMetInfPtr_t)(aPCDataP->content); } // smlPCDataToMetInfP // allocate memory via SyncML toolkit allocation function, but throw // exception if it fails. Used by SML void *_smlMalloc(MemSize_t size) { void *p; p=smlLibMalloc(size); if (!p) SYSYNC_THROW(TMemException("smlLibMalloc() failed")); return p; } // _smlMalloc // returns true on successful conversion of PCData string to sInt32 bool smlPCDataToULong(const SmlPcdataPtr_t aPCDataP, uInt32 &aLong) { return StrToULong(smlPCDataToCharP(aPCDataP),aLong); } // smlPCDataToLong // returns true on successful conversion of PCData string to sInt32 bool smlPCDataToLong(const SmlPcdataPtr_t aPCDataP, sInt32 &aLong) { return StrToLong(smlPCDataToCharP(aPCDataP),aLong); } // smlPCDataToLong #ifdef SYSYNC_ENGINE // returns true on successful conversion of PCData string to format bool smlPCDataToFormat(const SmlPcdataPtr_t aPCDataP, TFmtTypes &aFmt) { const char *fmt = smlPCDataToCharP(aPCDataP); sInt16 sh; if (*fmt) { if (!StrToEnum(encodingFmtSyncMLNames,numFmtTypes,sh,fmt)) return false; // unknown format aFmt=(TFmtTypes)sh; } else { aFmt=fmt_chr; // no spec = chr } return true; } // smlPCDataToFormat #endif //SYSYNC_ENGINE // build Meta anchor SmlPcdataPtr_t newMetaAnchor(const char *aNextAnchor, const char *aLastAnchor) { SmlPcdataPtr_t metaP; SmlMetInfAnchorPtr_t anchorP; // - create empty meta metaP=newMeta(); // - create new anchor anchorP=SML_NEW(SmlMetInfAnchor_t); // - set anchor contents //%%% anchorP->last=newPCDataOptEmptyString(aLastAnchor); // optional, but omitted only if string is NULL (not if only empty) anchorP->last=newPCDataOptString(aLastAnchor); // optional anchorP->next=newPCDataString(aNextAnchor); // mandatory // - set anchor ((SmlMetInfMetInfPtr_t)(metaP->content))->anchor=anchorP; // return return metaP; } // newMetaAnchor // build Meta type SmlPcdataPtr_t newMetaType(const char *aMetaType) { SmlPcdataPtr_t metaP; // - if not type, we don't create a meta at all if (aMetaType==NULL || *aMetaType==0) return NULL; // - create empty meta metaP=newMeta(); // - set type ((SmlMetInfMetInfPtr_t)(metaP->content))->type=newPCDataString(aMetaType); // return return metaP; } // newMetaType // build empty Meta SmlPcdataPtr_t newMeta(void) { SmlPcdataPtr_t metaP; SmlMetInfMetInfPtr_t metinfP; // - create empty PCData metaP = SML_NEW(SmlPcdata_t); metaP->contentType=SML_PCDATA_EXTENSION; metaP->extension=SML_EXT_METINF; // - %%% assume length is not relevant for structured content (looks like in mgrutil.c) metaP->length=0; // - create empty meta metinfP = SML_NEW(SmlMetInfMetInf_t); metaP->content=metinfP; // link to PCdata // - init meta options metinfP->version=NULL; metinfP->format=NULL; metinfP->type=NULL; metinfP->mark=NULL; metinfP->size=NULL; metinfP->nextnonce=NULL; metinfP->maxmsgsize=NULL; metinfP->mem=NULL; metinfP->emi=NULL; // PCData list metinfP->anchor=NULL; // - SyncML 1.1 metinfP->maxobjsize=NULL; // - SyncML 1.2 metinfP->flags=0; // return return metaP; } // newMeta // copy meta from existing meta (for data items only // anchor, mem, emi, nonce are not copied!) // Note however that we copy maxobjsize, as we (mis-)use it for ZIPPED_BINDATA_SUPPORT SmlPcdataPtr_t copyMeta(SmlPcdataPtr_t aOldMetaP) { if (!aOldMetaP) return NULL; SmlPcdataPtr_t newmetaP=newMeta(); if (!newmetaP) return NULL; SmlMetInfMetInfPtr_t oldmetinfP = smlPCDataToMetInfP(aOldMetaP); if (!oldmetinfP) return NULL; SmlMetInfMetInfPtr_t newmetInfP = smlPCDataToMetInfP(newmetaP); // - copy meta newmetInfP->version = smlPcdataDup(oldmetinfP->version); newmetInfP->format = smlPcdataDup(oldmetinfP->format); newmetInfP->type = smlPcdataDup(oldmetinfP->type); newmetInfP->mark = smlPcdataDup(oldmetinfP->mark); newmetInfP->size = smlPcdataDup(oldmetinfP->size); newmetInfP->maxobjsize = smlPcdataDup(oldmetinfP->maxobjsize); // return return newmetaP; } // copyMeta // add an item to an item list SmlItemListPtr_t *addItemToList( SmlItemPtr_t aItemP, // existing item data structure, ownership is passed to list SmlItemListPtr_t *aItemListPP // adress of pointer to existing item list or NULL ) { if (aItemListPP && aItemP) { // find last itemlist pointer while (*aItemListPP) { aItemListPP=&((*aItemListPP)->next); } // aItemListPP now points to a NULL pointer which must be replaced by addr of new ItemList entry *aItemListPP = SML_NEW(SmlItemList_t); (*aItemListPP)->next=NULL; (*aItemListPP)->item=aItemP; // insert new item // return pointer to pointer to next element (which is now NULL). // Can be passed in to addPCDataToList() again to append more elements without searching // for end-of-list return &((*aItemListPP)->next); } // nop, return pointer unmodified return aItemListPP; } // addItemToList // add a CTData item to a CTDataList SmlDevInfCTDataListPtr_t *addCTDataToList( SmlDevInfCTDataPtr_t aCTDataP, // existing CTData item data structure, ownership is passed to list SmlDevInfCTDataListPtr_t *aCTDataListPP // adress of pointer to existing item list or NULL ) { if (aCTDataListPP && aCTDataP) { // find last itemlist pointer while (*aCTDataListPP) { aCTDataListPP=&((*aCTDataListPP)->next); } // aItemListPP now points to a NULL pointer which must be replaced by addr of new ItemList entry *aCTDataListPP = SML_NEW(SmlDevInfCTDataList_t); (*aCTDataListPP)->next=NULL; (*aCTDataListPP)->data=aCTDataP; // insert new data // return pointer to pointer to next element (which is now NULL). // Can be passed in to addPCDataToList() again to append more elements without searching // for end-of-list return &((*aCTDataListPP)->next); } // nop, return pointer unmodified return aCTDataListPP; } // addCTDataToList // add a CTDataProp item to a CTDataPropList SmlDevInfCTDataPropListPtr_t *addCTDataPropToList( SmlDevInfCTDataPropPtr_t aCTDataPropP, // existing CTDataProp item data structure, ownership is passed to list SmlDevInfCTDataPropListPtr_t *aCTDataPropListPP // adress of pointer to existing item list or NULL ) { if (aCTDataPropListPP && aCTDataPropP) { // find last itemlist pointer while (*aCTDataPropListPP) { aCTDataPropListPP=&((*aCTDataPropListPP)->next); } // aItemListPP now points to a NULL pointer which must be replaced by addr of new ItemList entry *aCTDataPropListPP = SML_NEW(SmlDevInfCTDataPropList_t); (*aCTDataPropListPP)->next=NULL; (*aCTDataPropListPP)->data=aCTDataPropP; // insert new data // return pointer to pointer to next element (which is now NULL). // Can be passed in to addPCDataToList() again to append more elements without searching // for end-of-list return &((*aCTDataPropListPP)->next); } // nop, return pointer unmodified return aCTDataPropListPP; } // addCTDataPropToList // add a CTData describing a property (as returned by newDevInfCTData()) // as a new property without parameters to a CTDataPropList SmlDevInfCTDataPropListPtr_t *addNewPropToList( SmlDevInfCTDataPtr_t aPropCTData, // CTData describing property SmlDevInfCTDataPropListPtr_t *aCTDataPropListPP // adress of pointer to existing item list or NULL ) { SmlDevInfCTDataPropPtr_t propdataP = SML_NEW(SmlDevInfCTDataProp_t); propdataP->param = NULL; // no params propdataP->prop = aPropCTData; return addCTDataPropToList(propdataP, aCTDataPropListPP); } // addNewPropToList // add PCData element to a PCData list SmlPcdataListPtr_t *addPCDataToList( SmlPcdataPtr_t aPCDataP, // Existing PCData element to be added, ownership is passed to list SmlPcdataListPtr_t *aPCDataListPP // adress of pointer to existing PCData list or NULL ) { if (aPCDataListPP) { // find last PCDataList pointer while (*aPCDataListPP) { aPCDataListPP=&((*aPCDataListPP)->next); } // aItemListPP now points to a NULL pointer which must be replaced by addr of new PCDataList entry *aPCDataListPP = SML_NEW(SmlPcdataList_t); (*aPCDataListPP)->next=NULL; (*aPCDataListPP)->data=aPCDataP; // insert new item // return pointer to pointer to next element (which is now NULL). // Can be passed in to addPCDataToList() again to append more elements without searching // for end-of-list return &((*aPCDataListPP)->next); } return NULL; } // addPCDataToList // add PCData string to a PCData list SmlPcdataListPtr_t *addPCDataStringToList( const char *aString, // String to be added SmlPcdataListPtr_t *aPCDataListPP // adress of pointer to existing PCData list or NULL ) { return addPCDataToList(newPCDataString(aString),aPCDataListPP); } // addPCDataStringToList // create new optional location (source or target) // Returns NULL if URI specified is NULL or empty SmlSourcePtr_t newOptLocation( const char *aLocURI, const char *aLocName ) { if (!aLocURI || *aLocURI==0) return NULL; else return newLocation(aLocURI,aLocName); } // newOptLocation // create new location (source or target) // always returns location, even if URI and/or name are empty // If name is NULL or empty, only URI is generated SmlSourcePtr_t newLocation( const char *aLocURI, const char *aLocName ) { SmlSourcePtr_t locP; locP = SML_NEW(SmlSource_t); // URI is always present (might be empty, though) locP->locURI=newPCDataString(aLocURI); // name only if not empty if (aLocName && *aLocName!=0) locP->locName=newPCDataString(aLocName); else locP->locName=NULL; // filter defaults to NULL locP->filter=NULL; return locP; } // newLocation // create new empty Item SmlItemPtr_t newItem(void) { SmlItemPtr_t itemP; itemP = SML_NEW(SmlItem_t); itemP->target=NULL; itemP->source=NULL; itemP->meta=NULL; itemP->data=NULL; // SyncML 1.1, no MoreData set itemP->flags=0; // SyncML 1.2 itemP->targetParent=NULL; itemP->sourceParent=NULL; // custom data of client itemP->aux=NULL; return itemP; } // newItem // create new Item with string-type data SmlItemPtr_t newStringDataItem( const char *aString ) { SmlItemPtr_t itemP=newItem(); itemP->data=newPCDataString(aString); return itemP; } // newStringDataItem // create meta-format PCData SmlPcdataPtr_t newPCDataFormat( TFmtTypes aFmtType, bool aShowDefault ) { if (aFmtType==fmt_chr && !aShowDefault) return NULL; // default else return newPCDataString(encodingFmtSyncMLNames[aFmtType]); // show format type } // newPCDataFormat // create new string-type PCData, if NULL or empty string is passed for aData, // NULL is returned (optional info not there) SmlPcdataPtr_t newPCDataFormatted( const uInt8 *aData, // data sInt32 aLength, // length of data, if<=0 then string length is calculated TFmtTypes aFmtType, // encoding Format bool aNeedsOpaque // set opaque needed (string that could confuse XML parsing or even binary) ) { if (!aData) return NULL; // no data if (aLength==0) aLength=strlen((const char *)aData); if (aLength==0) return NULL; // no data // encode input string if needed SmlPcdataPtr_t pcdataP; char *b64data; uInt32 b64len; switch (aFmtType) { case fmt_b64: // convert to b64 b64len=0; b64data=b64::encode(aData, aLength, &b64len); pcdataP = newPCDataString(b64data,b64len); b64::free(b64data); return pcdataP; default: // just copy into string or opaque/C_DATA string return newPCDataStringX(aData, aNeedsOpaque, aLength); } } // newPCDataEncoded // create new string-type PCData, if NULL or empty string is passed for aString, // NULL is returned (optional info not there) SmlPcdataPtr_t newPCDataOptString( const char *aString, sInt32 aLength // length of string, if<0 then length is calculated ) { if (aString && (*aString!=0)) return newPCDataString(aString,aLength); else return NULL; } // newPCDataOptString // create new string-type PCData, if NULL is passed for aString, // NULL is returned (optional info not there) // if empty string is passed, PCData with empty contents will be created SmlPcdataPtr_t newPCDataOptEmptyString( const char *aString, sInt32 aLength // length of string, if<0 then length is calculated ) { if (aString) return newPCDataString(aString,aLength); else return NULL; } // newPCDataOptEmptyString // create new string-type PCData, if NULL is passed for aString, // an empty string is created (that is, a PCData with string terminator as // content only, length=0) SmlPcdataPtr_t newPCDataString( const char *aString, sInt32 aLength // length of string, if<0 then length is calculated ) { return newPCDataStringX((const uInt8 *)aString,false,aLength); } // newPCDataString // create new PCData, aOpaque can be used to generate non-string data // Note: empty strings are always coded as non-opaque, even if aOpaque is set SmlPcdataPtr_t newPCDataStringX( const uInt8 *aString, bool aOpaque, // if set, an opaque method (OPAQUE or CDATA) is used sInt32 aLength // length of string, if<0 then length is calculated ) { SmlPcdataPtr_t pcdataP; pcdataP = SML_NEW(SmlPcdata_t); // determine length if (aLength>=0 && aString) pcdataP->length = aLength; // as specified, and string argument not NULL else pcdataP->length = aString ? strlen((const char *)aString) : 0; // from argument, if NULL -> length=0 // determine type if (aOpaque && aLength!=0) { // Note: due to modification in RTK, this generates // OPAQUE in WBXML and CDATA in XML pcdataP->contentType=SML_PCDATA_OPAQUE; } else { // non-critical string #ifdef SML_STRINGS_AS_OPAQUE pcdataP->contentType=SML_PCDATA_OPAQUE; #else pcdataP->contentType=SML_PCDATA_STRING; #endif } pcdataP->extension=SML_EXT_UNDEFINED; // - allocate data space (ALWAYS with room for a terminator, even if Opaque or empty string) pcdataP->content=smlLibMalloc(pcdataP->length+1); // +1 for terminator, see below // copy data (if any) if (pcdataP->length>0) { // - copy string smlLibMemcpy(pcdataP->content,aString,pcdataP->length); } // set terminator ((char *)(pcdataP->content))[pcdataP->length]=0; // terminate C string // return return pcdataP; } // newPCDataStringX // create new string-type PCData from C++ string SmlPcdataPtr_t newPCDataString( const string &aString ) { return newPCDataString(aString.c_str(),aString.length()); } // newPCDataString(string&) // create new decimal string representation of sInt32 as PCData SmlPcdataPtr_t newPCDataLong( sInt32 aLong ) { const int ssiz=20; char s[ssiz]; snprintf(s,ssiz,"%ld",(long)aLong); return newPCDataString(s); } // newPCDataLong // Nonce generator allowing last-session nonce to be correctly re-generated in next session void generateNonce(string &aNonce, const char *aDevStaticString, sInt32 aSessionStaticID) { md5::SYSYNC_MD5_CTX context; uInt8 digest[16]; md5::Init (&context); // - add in static device string md5::Update (&context, (const uInt8 *)aDevStaticString, strlen(aDevStaticString)); // - add in session static ID in binary format md5::Update (&context, (const uInt8 *)&aSessionStaticID, sizeof(sInt32)); // - done md5::Final (digest, &context); // - make string of first 48 bit of MD5: 48 bits, use 6 bits per char = 8 chars uInt64 dig48 = ((uInt32)digest[0] << 0) | ((uInt32)digest[1] << 8) | ((uInt32)digest[2] << 16) | ((uInt32)digest[3] << 24); aNonce.erase(); for (sInt16 k=0; k<8; k++) { aNonce+=((dig48 & 0x03F) + 0x21); dig48 = dig48 >> 6; } } // generateNonce // create challenge of requested type SmlChalPtr_t newChallenge(TAuthTypes aAuthType, const string &aNextNonce, bool aBinaryAllowed) { SmlChalPtr_t chalP=NULL; SmlMetInfMetInfPtr_t metaP; if (aAuthType!=auth_none) { // new challenge record chalP = SML_NEW(SmlChal_t); // add empty meta chalP->meta=newMeta(); metaP=(SmlMetInfMetInfPtr_t)(chalP->meta->content); // add type and format // - type metaP->type=newPCDataString(authTypeSyncMLNames[aAuthType]); // - format const char *fmt = NULL; switch (aAuthType) { case auth_basic: // always request b64 fmt=encodingFmtSyncMLNames[fmt_b64]; break; case auth_md5: // request b64 only for non-binary capable encoding (that is, XML) /* %%% dont do that, Nokia9210 miserably fails when we do that, * it sends its data B64 encoded, but obviously with bad * data in it. Ericsson T39m seems to do it correctly however. if (!aBinaryAllowed) fmt=encodingFmtSyncMLNames[fmt_b64]; */ // always request b64 for now, seems to be safer with not fully compatible clients fmt=encodingFmtSyncMLNames[fmt_b64]; break; default: break; } metaP->format=newPCDataOptString(fmt); // set format, but not empty // - add nonce if needed if (aAuthType==auth_md5) { // MD5 also might need nonce if (!aNextNonce.empty()) { // add base64 encoded nonce string uInt32 b64len; char *b64=b64::encode((const uInt8 *)aNextNonce.c_str(),aNextNonce.size(),&b64len); metaP->nextnonce=newPCDataString(b64,b64len); b64::free(b64); // return buffer allocated by b64_encode } } } return chalP; } // newChallenge // create new property or param descriptor for CTCap SmlDevInfCTDataPtr_t newDevInfCTData(cAppCharP aName,uInt32 aSize, bool aNoTruncate, uInt32 aMaxOccur, cAppCharP aDataType) { SmlDevInfCTDataPtr_t result = SML_NEW(SmlDevInfCTData_t); // fill descriptor // - name if property or param result->name=newPCDataString(aName); // - no display name so far result->dname=NULL; // no display name // - datatype (optional) result->datatype=newPCDataOptString(aDataType); // - max size if (aSize==0) result->maxsize=NULL; // no size else result->maxsize=newPCDataLong(aSize); // set size // - no valenum here, will be added later if any result->valenum=NULL; // no valenum // SyncML 1.2 if (aMaxOccur==0) result->maxoccur=NULL; // no maxoccur else result->maxoccur=newPCDataLong(aMaxOccur); // set maxoccur result->flags = aNoTruncate ? SmlDevInfNoTruncate_f : 0; // notruncate flag or none return result; } // newDevInfCTData // frees prototype element and sets calling pointer to NULL void FreeProtoElement(void * &aVoidP) { if (aVoidP) smlFreeProtoElement(aVoidP); aVoidP=NULL; } // FreeProtoElement } // namespace sysync // eof libsynthesis-3.4.0.47.1/src/sysync_SDK/Sources/sysync_utils.h000077500000000000000000000477171226375725500240530ustar00rootroot00000000000000/* * File: sysync_utils.h * * Author: Lukas Zeller (luz@plan44.ch) * * Provides some helper functions interfacing between SyncML Toolkit * and C++ plus other utilities * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * * 2001-05-16 : luz : created * */ #ifndef SYSYNC_UTILS_H #define SYSYNC_UTILS_H #include "sysync_globs.h" #include "sysync_noncopyable.h" // include external utils in separate files #include "sysync_b64.h" #include "sysync_md5.h" #ifndef SYSYNC_ENGINE #include "stringutil.h" #endif #include "lineartime.h" #include "iso8601.h" #ifndef FULLY_STANDALONE #include "sysync.h" #endif #include "sml.h" #include "smldevinfdtd.h" #include "smlmetinfdtd.h" namespace sysync { #ifdef SYSYNC_TOOL // convert between character sets int charConv(int argc, const char *argv[]); // parse RFC 2822 addr spec int parse2822AddrSpec(int argc, const char *argv[]); #endif // max line size for MIME content (used while encoding and folding) #define MIME_MAXLINESIZE 75 // supported charsets typedef enum { chs_unknown, // invalid chs_ascii, // 7 bit ASCII-only, with nearest char conversion for umlauts etc. chs_ansi, chs_iso_8859_1, chs_utf8, chs_utf16, #ifdef CHINESE_SUPPORT chs_gb2312, chs_cp936, #endif numCharSets } TCharSets; // Note: Char set names are defined after this enum in other files, // such as MimeDirItemType // supported MIME encoding types typedef enum { enc_none, enc_7bit, enc_8bit, enc_binary, enc_quoted_printable, enc_base64, // b64 including terminating with CRLF at end enc_b, // b64 without termination (as needed in RFC2047) numMIMEencodings } TEncodingTypes; // line end modes typedef enum { lem_none, // none specified lem_unix, // 0x0A lem_mac, // 0x0D lem_dos, // 0x0D 0x0A lem_cstr, // as in C strings, '\n' which is 0x0A normally (but might be 0x0D on some platforms) lem_filemaker, // 0x0B (filemaker tab-separated text format, CR is shown as 0x0B within fields numLineEndModes } TLineEndModes; extern const char * const lineEndModeNames[numLineEndModes]; // literal quoting modes typedef enum { qm_none, // none specified qm_duplsingle, // single quote must be duplicated qm_dupldouble, // double quote must be duplicated qm_backslash, // C-string-style escapes of CR,LF,TAB,BS,\," and ' (but no full c-string escape with \xXX etc.) numQuotingModes } TQuotingModes; extern const char * const quotingModeNames[numQuotingModes]; /* The value of this element SHOULD BE one of bin, bool, b64, chr, int, node, null or xml. If the element type is missing, the default value is chr. If the value is bin, then the format of the content is binary data. If the value is bool, then the format of the content is either true or false. If the value is b64, then the format of the content information is binary data that has been character encoded using the Base64 transfer encoding defined by [RFC2045]. If the value is chr, then the format of the content information is clear-text in the character set specified on either the transport protocol, the MIME content type header or the XML prolog. If the value is int, then the format of the content information is numeric text representing an unsigned integer between zero and 2**32-1. If the value is node, then the content represents an interior object in the management tree. If the value is null, then there is no content information. This value is used by some synchronization data models to delete the content, but not the presence of the property. If the value is xml, then the format of the content information is XML structured mark-up data. */ // format types typedef enum { fmt_chr, // default fmt_bin, fmt_b64, numFmtTypes } TFmtTypes; extern const char * const encodingFmtNames[numFmtTypes]; extern const char * const encodingFmtSyncMLNames[numFmtTypes]; extern const char * const MIMEEncodingNames[numMIMEencodings]; extern const char * const MIMECharSetNames[numCharSets]; // field (property) data types typedef enum { proptype_chr, // Character proptype_int, // Integer proptype_bool, // Boolean proptype_bin, // Binary proptype_datetime, // Date and time of day proptype_phonenum, // Phone number proptype_text, // plain text proptype_unknown, // unknown numPropDataTypes } TPropDataTypes; extern const char * const propDataTypeNames[numPropDataTypes]; // Authorization types typedef enum { auth_none, auth_basic, auth_md5, numAuthTypes } TAuthTypes; extern const char * const authTypeSyncMLNames[numAuthTypes]; //extern const char * const authFormatNames[numAuthTypes]; // char that is used for non-convertible chars #define INCONVERTIBLE_PLACEHOLDER '_' // encoding functions // encode binary stream and append to string void appendEncoded( const uInt8 *aBinary, size_t aSize, string &aString, TEncodingTypes aEncoding, sInt16 aMaxLineSize=76, sInt32 aCurrLineSize=0, // how may chars are on the first line bool aSoftBreaksAsCR=false, // if set, soft breaks are not added as CRLF, but only indicated as CR bool aEncodeBinary=false // quoted printable: binary coding: both CR and LF will be // always replaced by "=0D" and "=0A" ); // decode encoded data and append to string const char *appendDecoded( const char *aText, size_t aSize, string &aBinString, TEncodingTypes aEncoding ); // generate RFC2822-style address specificiation // - Common Name will be quoted // - recipient will be put in angle brackets void makeRFC2822AddrSpec( cAppCharP aCommonName, cAppCharP aRecipient, string &aRFCAddr ); // Parse RFC2822-style address specificiation // - aName will receive name and all (possible) comments // - aRecipient will receive the (first, in case of a group) email address cAppCharP parseRFC2822AddrSpec( cAppCharP aText, string &aName, string &aRecipient ); // RFC2047 encoding // append internal UTF8 string as RFC2047 style encoding const char *appendUTF8AsRFC2047( const char *aText, string &aString ); // parse character string from RFC2047 style encoding to UTF8 internal string const char *appendRFC2047AsUTF8( const char *aRFC2047, stringSize aSize, // max number of chars to look at string &aString, TLineEndModes aLEM=lem_none ); // charset conversion functions // generic bintree-based conversion functions typedef uInt16 treeval_t; typedef struct { treeval_t minkey; treeval_t maxkey; treeval_t linksstart; treeval_t linksend; size_t numelems; treeval_t *elements; } TConvFlatTree; #ifdef BINTREE_GENERATOR typedef struct TBinTreeNode { treeval_t key; struct TBinTreeNode *nextHigher; struct TBinTreeNode *nextLowerOrEqual; treeval_t value; // valid only if links are both NULL } TBinTreeNode; // add a key/value pair to the binary tree void addToBinTree(TBinTreeNode *&aBinTree, treeval_t aMinKey, treeval_t aMaxKey, treeval_t aKey, treeval_t aValue); // dispose a bintree void disposeBinTree(TBinTreeNode *&aBinTree); // search directly in bintree treeval_t searchBintree(TBinTreeNode *aBinTree, treeval_t aKey, treeval_t aUndefValue, treeval_t aMinKey, treeval_t aMaxKey); // make a flat form representation of the bintree in a one-dimensional array bool flatBinTree( TBinTreeNode *aBinTree, TConvFlatTree &aFlatTree, size_t aArrSize, treeval_t aMinKey, treeval_t aMaxKey, treeval_t aLinksStart, treeval_t aLinksEnd ); #endif // search flattened bintree for a specific key value treeval_t searchFlatBintree(const TConvFlatTree &aFlatTree, treeval_t aKey, treeval_t aUndefValue); // add byte char as UTF8 to string value and apply charset translation if needed //void appendCharAsUTF8(char c, string &aVal, TCharSets aCharSet); uInt16 appendCharsAsUTF8(const char *aChars, string &aVal, TCharSets aCharSet, uInt16 aNumChars=1); // add string as UTF8 to value and apply charset translation if needed // - if aLineEndChar is specified, occurrence of this will be replaced // by '\n', occurrence of non matching LF/CR will be ignored void appendStringAsUTF8( const char *s, string &aVal, TCharSets aCharSet, TLineEndModes aLEM=lem_cstr, bool aAllowFilemakerCR=false // if set, 0x0B is interpreted as line end as well ); // add UTF8 string to value in custom charset // - aLEM specifies line ends to be used // - aQuotingMode specifies what quoting (for ODBC literals for example) should be used // - output is clipped after aMaxBytes bytes (if not 0) // - returns true if all input could be converted, false if output is clipped bool appendUTF8ToString( cAppCharP aUTF8, string &aVal, TCharSets aCharSet, TLineEndModes aLEM=lem_none, TQuotingModes aQuotingMode=qm_none, size_t aMaxBytes=0 ); // same, but output string is cleared first bool storeUTF8ToString( cAppCharP aUTF8, string &aVal, TCharSets aCharSet, TLineEndModes aLEM=lem_none, TQuotingModes aQuotingMode=qm_none, size_t aMaxBytes=0 ); // convert UTF8 to UCS4 // - returns pointer to next char // - returns UCS4=0 on error (no char, bad sequence, sequence not complete) const char *UTF8toUCS4(const char *aUTF8, uInt32 &aUCS4); // convert UCS4 to UTF8 (0 char is not allowed and will be ignored!) void UCS4toUTF8(uInt32 aUCS4, string &aUTF8); // convert UTF-16 to UCS4 // - returns pointer to next char // - returns UCS4=0 on error (no char, bad sequence, sequence not complete) const uInt16 *UTF16toUCS4(const uInt16 *aUTF16P, uInt32 &aUCS4); // convert UCS4 to UTF-16 // - returns 0 for UNICODE range UCS4 and first word of UTF-16 for non UNICODE uInt16 UCS4toUTF16(uInt32 aUCS4, uInt16 &aUTF16); // add UTF8 string as UTF-16 byte stream to 8-bit string // - if aLEM is not lem_none, occurrence of any type of Linefeeds // (LF,CR,CRLF and even CRCRLF) in input string will be // replaced by the specified line end type // - output is clipped after ByteString reaches aMaxBytes size (if not 0), = approx half as many Unicode chars // - returns true if all input could be converted, false if output is clipped bool appendUTF8ToUTF16ByteString( cAppCharP aUTF8, string &aUTF16ByteString, bool aBigEndian, TLineEndModes aLEM=lem_none, uInt32 aMaxBytes=0 ); // add UTF16 byte string as UTF8 to value void appendUTF16AsUTF8( const uInt16 *aUTF16, uInt32 aNumUTF16Chars, bool aBigEndian, string &aVal, bool aConvertLineEnds=false, bool aAllowFilemakerCR=false ); // MD5 and B64 given string void MD5B64(const char *aString, sInt32 aLen, string &aMD5B64); // format as Timestamp text, usually for logfiles void StringObjTimestamp(string &aStringObj, lineartime_t aTimer); // format as hex byte string void StringObjHexString(string &aStringObj, const uInt8 *aBinary, uInt32 aBinSz); // add (already encoded!) CGI to existing URL string bool addCGItoString(string &aStringObj, cAppCharP aCGI, bool noduplicate=true); // encode string for being used as a CGI key/value element string encodeForCGI(cAppCharP aCGI); // Count bits int countbits(uInt32 aMask); // make uppercase void StringUpper(string &aString); // make lowercase void StringLower(string &aString); // Substitute occurences of pattern with replacement in string void StringSubst( string &aString, const char *aPattern, const string &aReplacement, sInt32 aPatternLen, TCharSets aCharSet, TLineEndModes aLEM, TQuotingModes aQuotingMode ); void StringSubst( string &aString, const char *aPattern, const char *aReplacement, sInt32 aPatternLen, sInt32 aReplacementLen, TCharSets aCharSet=chs_unknown, TLineEndModes aLEM=lem_none, TQuotingModes aQuotingMode=qm_none ); void StringSubst(string &aString, const char *aPattern, const string &aReplacement, sInt32 aPatternLen=-1); void StringSubst(string &aString, const char *aPattern, sInt32 aNumber, sInt32 aPatternLen=-1); /* subst regexp i\=0\; *while\(\(i\=([^.]+)\.find\(\"([^"]+)\",i\)\)\!\=string::npos\) *\{ *[^.]+\.replace\(i,([0-9]+),(.+)\)\; i\+\=.*$ StringSubst(\1,"\2",\4,\3); */ // helper macro for allocation of SyncML Toolkit structures from C++ code #define SML_NEW(ty) ((ty*) _smlMalloc(sizeof(ty))) #define SML_FREE(m) smlLibFree(m) // allocate memory via SyncML toolkit allocation function, but throw // exception if it fails. Used by SML void *_smlMalloc(MemSize_t size); // copy PCdata contents into std::string object void smlPCDataToStringObj(const SmlPcdataPtr_t aPcdataP, string &aStringObj); // returns pointer to PCdata contents or null string. If aSizeP!=NULL, length will be stored in *aSize const char *smlPCDataToCharP(const SmlPcdataPtr_t aPcdata, stringSize *aSizeP=NULL); // returns pointer to PCdata contents if existing, NULL otherwise. // If aSizeP!=NULL, length will be stored in *aSize const char *smlPCDataOptToCharP(const SmlPcdataPtr_t aPcdataP, stringSize *aSizeP=NULL); // returns item string or empty string (NEVER NULL) const char *smlItemDataToCharP(const SmlItemPtr_t aItemP); // returns first item string or empty string (NEVER NULL) const char *smlFirstItemDataToCharP(const SmlItemListPtr_t aItemListP); // split Hostname into address and port parts void splitHostname(const char *aHost,string *aAddr,string *aPort); // split URL into protocol, hostname, document name and auth-info (user, password); // none of the strings are url-decoded, do that as needed void splitURL(const char *aURI,string *aProtocol,string *aHost,string *aDoc,string *aUser, string *aPasswd, string *aPort, string *aQuery); // in-place decoding of %XX, NULL pointer allowed void urlDecode(string *str); // returns error code made ready for SyncML sending (that is, remove offset // of 10000 if present, and make generic error 500 for non-SyncML errors, // and return LOCERR_OK as 200) localstatus syncmlError(localstatus aErr); // returns error code made local (that is, offset by 10000 in case aErr is a // SyncML status code <10000, and convert 200 into LOCERR_OK) localstatus localError(localstatus aErr); // returns pure relative URI, if specified relative or absolute to // optionally given server URI const char *relativeURI(const char *aURI,const char *aServerURI=NULL); // returns pointer to source or target LocURI const char *smlSrcTargLocURIToCharP(const SmlTargetPtr_t aSrcTargP); // returns pointer to source or target LocName const char *smlSrcTargLocNameToCharP(const SmlTargetPtr_t aSrcTargP); // returns DevInf pointer if any in specified PCData, NULL otherwise SmlDevInfDevInfPtr_t smlPCDataToDevInfP(const SmlPcdataPtr_t aPCDataP); // returns MetInf pointer if any in specified PCData, NULL otherwise SmlMetInfMetInfPtr_t smlPCDataToMetInfP(const SmlPcdataPtr_t aPCDataP); // returns true on successful conversion of PCData string to format bool smlPCDataToFormat(const SmlPcdataPtr_t aPCDataP, TFmtTypes &aFmt); // returns type from meta const char *smlMetaTypeToCharP(SmlMetInfMetInfPtr_t aMetaP); // returns Next Anchor from meta const char *smlMetaNextAnchorToCharP(SmlMetInfMetInfPtr_t aMetaP); // returns Last Anchor from meta const char *smlMetaLastAnchorToCharP(SmlMetInfMetInfPtr_t aMetaP); // build Meta anchor SmlPcdataPtr_t newMetaAnchor(const char *aNextAnchor, const char *aLastAnchor=NULL); // build Meta type SmlPcdataPtr_t newMetaType(const char *aMetaType); // build empty Meta SmlPcdataPtr_t newMeta(void); // copy meta from existing meta (for data items only // anchor, mem, emi, maxobjsize, nonce are not copied!) SmlPcdataPtr_t copyMeta(SmlPcdataPtr_t aOldMetaP); // add an item to an item list SmlItemListPtr_t *addItemToList( SmlItemPtr_t aItemP, // existing item data structure, ownership is passed to list SmlItemListPtr_t *aItemListPP // adress of pointer to existing item list or NULL ); // add a CTData item to a CTDataList SmlDevInfCTDataListPtr_t *addCTDataToList( SmlDevInfCTDataPtr_t aCTDataP, // existing CTData item data structure, ownership is passed to list SmlDevInfCTDataListPtr_t *aCTDataListPP // adress of pointer to existing item list or NULL ); // add a CTDataProp item to a CTDataPropList SmlDevInfCTDataPropListPtr_t *addCTDataPropToList( SmlDevInfCTDataPropPtr_t aCTDataPropP, // existing CTDataProp item data structure, ownership is passed to list SmlDevInfCTDataPropListPtr_t *aCTDataPropListPP // adress of pointer to existing item list or NULL ); // add a CTData describing a property (as returned by newDevInfCTData()) // as a new property without parameters to a CTDataPropList SmlDevInfCTDataPropListPtr_t *addNewPropToList( SmlDevInfCTDataPtr_t aPropCTData, // CTData describing property SmlDevInfCTDataPropListPtr_t *aCTDataPropListPP // adress of pointer to existing item list or NULL ); // add PCData element to a PCData list SmlPcdataListPtr_t *addPCDataToList( SmlPcdataPtr_t aPCDataP, // Existing PCData element to be added, ownership is passed to list SmlPcdataListPtr_t *aPCDataListPP // adress of pointer to existing PCData list or NULL ); // add PCData string to a PCData list SmlPcdataListPtr_t *addPCDataStringToList( const char *aString, // String to be added SmlPcdataListPtr_t *aPCDataListPP // adress of pointer to existing PCData list or NULL ); // create new optional location (source or target) SmlSourcePtr_t newOptLocation( const char *aLocURI, const char *aLocName=NULL ); // create new location (source or target) SmlSourcePtr_t newLocation( const char *aLocURI, const char *aLocName=NULL ); // create new empty Item SmlItemPtr_t newItem(void); // create new Item with string-type data SmlItemPtr_t newStringDataItem( const char *aString ); // create format PCData SmlPcdataPtr_t newPCDataFormat( TFmtTypes aFmtType, bool aShowDefault ); // create new string-type PCData, if NULL or empty string is passed for aData, // NULL is returned (optional info not there) SmlPcdataPtr_t newPCDataFormatted( const uInt8 *aData, // data sInt32 aLength, // length of data, if<0 then string length is calculated TFmtTypes aEncType, // encoding bool aNeedsOpaque // set opaque needed (string that could confuse XML parsing or even binary) ); // create new string-type PCData, if NULL is passed for aString, NULL is returned (optional info not there) SmlPcdataPtr_t newPCDataOptString( const char *aString, sInt32 aLength=-1 // length of string, if<0 then length is calculated ); // create new string-type PCData, if NULL is passed for aString, // NULL is returned (optional info not there) // if empty string is passed, PCData with empty contents will be created SmlPcdataPtr_t newPCDataOptEmptyString( const char *aString, sInt32 aLength=-1 // length of string, if<0 then length is calculated ); // create new string-type PCData, if NULL is passed for aString, an empty string is created SmlPcdataPtr_t newPCDataString( const char *aString, sInt32 aLength=-1 // length of string, if<0 then length is calculate ); // create new PCData, aOpaque can be used to generate non-string data SmlPcdataPtr_t newPCDataStringX( const uInt8 *aString, bool aOpaque=false, // if set, an opaque method (OPAQUE or CDATA) is used sInt32 aLength=-1 // length of string, if<0 then length is calculate ); // create new string-type PCData from C++ string SmlPcdataPtr_t newPCDataString(const string &aString); // create new decimal string representation of long as PCData SmlPcdataPtr_t newPCDataLong(sInt32 aLong); // returns true on successful conversion of PCData string to long bool smlPCDataToLong(const SmlPcdataPtr_t aPCDataP, sInt32 &aLong); bool smlPCDataToULong(const SmlPcdataPtr_t aPCDataP, uInt32 &aLong); // create challenge of requested type SmlChalPtr_t newChallenge(TAuthTypes aAuthType, const string &aNextNonce, bool aBinaryAllowed); // Nonce generator allowing last-session nonce to be correctly re-generated in next session void generateNonce(string &aNonce, const char *aDevStaticString, sInt32 aSessionStaticID); // create new property or param descriptor for CTCap SmlDevInfCTDataPtr_t newDevInfCTData(cAppCharP aName,uInt32 aSize=0, bool aNoTruncate=false, uInt32 aMaxOccur=0, cAppCharP aDataType=NULL); // frees prototype element and sets calling pointer to NULL void FreeProtoElement(void * &aVoidP); // macro to overcome pointer reference conversion constraints #ifdef PREFER_MACROS #define FREEPROTOELEMENT(p) FreeProtoElement((void *&)p) #else template void FREEPROTOELEMENT(T *&p) { smlFreeProtoElement(static_cast(p)); p = NULL; } #endif } // namespace sysync #endif // eof libsynthesis-3.4.0.47.1/src/sysync_SDK/Sources/timeutil.cpp000066400000000000000000000070331226375725500234520ustar00rootroot00000000000000/* * File: timeutil.cpp * * Authors: Lukas Zeller (luz@plan44.ch) * Beat Forster (bfo@synthesis.ch) * * ISO8601 / Lineartime functions * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * */ //#include "target_options.h" #include "sync_include.h" #if defined LINUX || defined MACOSX // problems with "trunc" #define _ISOC99_SOURCE 1 #include #endif #ifdef _MSC_VER static int trunc( double d ) { return (int)( d-0.5 ); } #endif #ifdef MACOSX #include #endif #include #include "timeutil.h" #include "stringutil.h" using namespace std; #ifdef __cplusplus namespace sysync { #endif typedef struct tm struct_tm; typedef sInt32 lineardate_t; const lineartime_t linearDateToTimeFactor= (secondToLinearTimeFactor*60*60*24); // offset between algorithm base and 1970-01-01 const lineartime_t UnixToLineartimeOffset= 2440588*linearDateToTimeFactor; // static version of time zone calculation // should be replaced by a full functioning version, when used static lineartime_t zoneOffsetAsSeconds() { return (1)*60*60; // for CET //return (1+1)*60*60; // for CEST } // zoneOffsetAsSeconds // get system current date/time // this very simple implementation is rather local time than UTC lineartime_t utcNowAsLineartime() { lineartime_t secs= time(NULL) - zoneOffsetAsSeconds(); return secs*secondToLinearTimeFactor + UnixToLineartimeOffset; } // utcNowAsLineartime static void lineardate2date( lineardate_t julDat,sInt16 *year, sInt16 *month, sInt16 *day ) { double C,E; sInt32 B,D,F; if (julDat<2299161) { B=0; C=julDat+1524; } else { B= (sInt32)(trunc((julDat-1867216.25)/36524.25)); C=julDat+(B-trunc((double)B/4))+1525.0; } // if D=(sInt32)(trunc((C-122.1)/365.25)); E= 365.0*D+trunc((double)D/4); F=(sInt32)(trunc((C-E)/30.6001)); // return date *day = (sInt16)(trunc(C-E+0.5)-trunc(30.6001*F)); *month= (sInt16)(F-1-12*trunc((double)F/14)); *year = (sInt16)(D-4715-trunc((double)(7+*month)/10.0)); } // lineardate2date // convert lineartime to h,m,s,ms static void lineartime2time( lineartime_t aTim, sInt16 *hour, sInt16 *min, sInt16 *sec, sInt16 *ms ) { // we have sub-seconds *ms = aTim % secondToLinearTimeFactor; aTim /= secondToLinearTimeFactor; *sec = aTim % 60; aTim /= 60; *min = aTim % 60; aTim /= 60; *hour= aTim % 24; // to make sure we don't convert date part } // lineartime2time // convert struct tm to linear time (in milliseconds) static void lineartime2tm( lineartime_t aLt, struct_tm *tim ) { sInt16 y,mo,d, h,m,s, ms; // date lineardate2date( aLt/linearDateToTimeFactor, &y,&mo,&d ); tim->tm_year= y-1900; tim->tm_mon = mo-1; tim->tm_mday= d; // time lineartime2time( aLt, &h,&m,&s, &ms ); tim->tm_hour= h; tim->tm_min = m; tim->tm_sec = s; } // tm2lineartime // convert UTC lineartimestamp to ISO8601 string representation // (and return how long expired) sInt32 timeStampToISO8601( lineartime_t aTimeStamp, string &aString, bool dateOnly ) { aString.erase(); if (aTimeStamp==0) return 0; struct_tm t; lineartime2tm( aTimeStamp,&t ); // format as ISO8601 UTC StringObjAppendPrintf ( aString, "%04d%02d%02d", t.tm_year+1900, t.tm_mon+1, t.tm_mday ); if (!dateOnly) { StringObjAppendPrintf( aString, "T%02hd%02hd%02hd", t.tm_hour, t.tm_min, t.tm_sec ); aString+= 'Z'; // add UTC designator } // if return 0; } // timeStampToISO8601 #ifdef __cplusplus } // namespace #endif /* eof */ libsynthesis-3.4.0.47.1/src/sysync_SDK/Sources/timeutil.h000066400000000000000000000016761226375725500231260ustar00rootroot00000000000000/* * File: timeutil.h * * Authors: Lukas Zeller (luz@plan44.ch) * Beat Forster (bfo@synthesis.ch) * * ISO8601 / Lineartime functions * * Copyright (c) 2001-2011 by Synthesis AG + plan44.ch * */ #ifndef TIMEUTIL_H #define TIMEUTIL_H #include "sync_dbapidef.h" #ifdef __cplusplus #include using namespace std; #endif #ifdef __cplusplus namespace sysync { #endif #if defined MACOSX || defined _WIN32 || defined LINUX typedef sInt64 lineartime_t; #else #error unknown platform #endif #ifdef __cplusplus const lineartime_t secondToLinearTimeFactor = 1000; // unit is milliseconds // get system current date/time lineartime_t utcNowAsLineartime(); // convert timestamp to ISO8601 string representation sInt32 timeStampToISO8601( lineartime_t aTimeStamp, string &aString, bool dateOnly= false ); #endif #ifdef __cplusplus } // namespace #endif #endif /* TIMEUTIL_H */ /* eof */ libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/000077500000000000000000000000001226375725500211145ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/README000066400000000000000000000022711226375725500217760ustar00rootroot00000000000000The sample configs contain common elements (datatypes, scripts, remote rules, debug settings) which are maintained as separate files in the corresponding directories. When modifying those common elements, run "update-samples.pl" in this directory to update the sample configs. The complete samples are under version control for several reasons: 1. avoid dependency on Perl unless common elements need to be updated 2. effect of changes on complete config show up in patches 3. the file layout and unshared parts ( and ) are determined by the sample configs The naming of common elements determines the order in which they get inserted. Files not ending in .xml are ignored. Elements that only apply to a client or server are stored in the corresponding sub directories, while the shared elements are in the "debug/scripting/datatypes/remoterules". It is a somewhat subjective choice which elements are stored in one file and which ones are split up. The three elements of a datatype definition (field list, profile, datatype) where split up because there might be multiple different profiles using the same field list and some users of these files might want to replace the default one. libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/datatypes/000077500000000000000000000000001226375725500231125ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/datatypes/00vcard-fieldlist.xml000066400000000000000000000072021226375725500270510ustar00rootroot00000000000000 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/datatypes/01vcard-profile.xml000066400000000000000000000125121226375725500265330ustar00rootroot00000000000000 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/datatypes/02vcard-types.xml000066400000000000000000000006031226375725500262360ustar00rootroot00000000000000 2.1 3.0 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/datatypes/10calendar-fieldlist.xml000066400000000000000000000063441226375725500275320ustar00rootroot00000000000000 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/datatypes/11calendar-profile.xml000066400000000000000000000472461226375725500272220ustar00rootroot00000000000000 current olson libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/datatypes/12calendar-types.xml000066400000000000000000000014511226375725500267130ustar00rootroot00000000000000 1.0 2.0 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/datatypes/20note-fieldlist.xml000066400000000000000000000004771226375725500267300ustar00rootroot00000000000000 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/datatypes/21note-profile.xml000066400000000000000000000006411226375725500264030ustar00rootroot00000000000000 1 false true SUBJECT 0 false true libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/datatypes/22notes-types.xml000066400000000000000000000005321226375725500262720ustar00rootroot00000000000000 text/plain 1.0 text/plain 1.1 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/datatypes/30bookmark-fieldlist.xml000066400000000000000000000013421226375725500275610ustar00rootroot00000000000000 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/datatypes/31bookmark-profile.xml000066400000000000000000000017601226375725500272470ustar00rootroot00000000000000 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/datatypes/32bookmark-type.xml000066400000000000000000000004071226375725500265660ustar00rootroot00000000000000 text/x-vbookmark 1.0 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/datatypes/server/000077500000000000000000000000001226375725500244205ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/datatypes/server/40email-fieldlist.xml000066400000000000000000000026241226375725500303560ustar00rootroot00000000000000 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/datatypes/server/41email-profile.xml000066400000000000000000000055361226375725500300450ustar00rootroot00000000000000 true 100 ATT_COUNT ATT_MIMETYPES ATT_CONTENTS ATT_SIZES ATT_NAMES LIMIT From: rfc2047 true FROM To: rfc2047 true TO Cc: rfc2047 true CC Bcc: rfc2047 true BCC Reply-To: rfc2047 true Subject: rfc2047 true SUBJECT X-Priority: true date Date: true Status: true X-Sync-Parent-Folder: true X-Sync-Message-Read: true X-Sync-Lastmodified: true body 0 false true libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/datatypes/server/42email-type-zipped.xml000066400000000000000000000027311226375725500306520ustar00rootroot00000000000000 application/x-zip-message 1.1 yes yes 9 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/datatypes/server/42email-type.xml000066400000000000000000000013541226375725500273610ustar00rootroot00000000000000 text/message 1.0 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/datatypes/server/43email-sonyericsson.xml000066400000000000000000000014011226375725500311300ustar00rootroot00000000000000 message/rfc822 1.0 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/datatypes/server/44email-nokia9500.xml000066400000000000000000000117201226375725500300170ustar00rootroot00000000000000 message/x-rfc822 1.0 SIZELIMIT())) { // force conflict only if this is a reload FORCECONFLICT(); } // make sure we never overwrite a body in the inbox BODY = UNASSIGNED; // delete always wins over replace in inbox (to avoid adds to inbox) DELETEWINS(); } } } else if (UPPERCASE(FOLDER)=="OUTBOX") { // never try to change something in outbox IGNOREUPDATE(); if (SYNCOP()!="delete") { // - date of mail is NOW, set it such that a correct date is written to the DB MAILDATE = DBNOW(); // MAILDATE = (INTEGER)DBNOW() - TIMEUNITS(120); // %%% backdate it 2 mins to make sure it does not get retransmitted // - echo item as delete (this causes that it is moved to the "sent" folder in the 9500) ECHOITEM("delete"); } CONFLICTSTRATEGY("client-wins"); } else { // Other folder // - silently discard incoming item for other folder than the above // except if it is a delete if (SYNCOP()!="delete") REJECTITEM(0); } ]]> =STARTDATE(); RETURN PASSES; ]]> libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/debug/000077500000000000000000000000001226375725500222025ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/debug/00default.xml000066400000000000000000000063141226375725500245140ustar00rootroot00000000000000 buffered yes html auto yes no yes separate no no no no libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/remoterules/000077500000000000000000000000001226375725500234625ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/remoterules/server/000077500000000000000000000000001226375725500247705ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/remoterules/server/00_t39m.xml000066400000000000000000000004761226375725500266140ustar00rootroot00000000000000 Ericsson R1A yes ANSI Ericsson T39m libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/remoterules/server/01_t68.xml000066400000000000000000000004731226375725500264370ustar00rootroot00000000000000 Ericsson R1B yes ANSI Ericsson T68 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/remoterules/server/02_V3.xml000066400000000000000000000006631226375725500263100ustar00rootroot00000000000000 Motorola* V3 yes yes yes ANSI ANSI Motorola V3 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/remoterules/server/03_V3i.xml000066400000000000000000000006171226375725500264610ustar00rootroot00000000000000 Motorola* V3i yes yes yes ANSI Motorola V3i libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/remoterules/server/04_6230.xml000066400000000000000000000004111226375725500264030ustar00rootroot00000000000000 NOKIA 6230 yes yes Nokia 6230 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/remoterules/server/05_9210.xml000066400000000000000000000005271226375725500264150ustar00rootroot00000000000000 NOKIA 9210 yes Nokia 9210 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/remoterules/server/06_9210i.xml000066400000000000000000000005311226375725500265620ustar00rootroot00000000000000 NOKIA 9210i yes Nokia 9210 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/remoterules/server/07_3220.xml000066400000000000000000000006141226375725500264070ustar00rootroot00000000000000 NOKIA 3220 yes yes Nokia 3220 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/remoterules/server/08_3230.xml000066400000000000000000000006141226375725500264110ustar00rootroot00000000000000 NOKIA 3230 yes yes Nokia 3230 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/remoterules/server/09_3600.xml000066400000000000000000000006141226375725500264130ustar00rootroot00000000000000 NOKIA 3600 yes yes Nokia 3600 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/remoterules/server/10_3620.xml000066400000000000000000000006141226375725500264050ustar00rootroot00000000000000 NOKIA 3620 yes yes Nokia 3620 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/remoterules/server/11_3650.xml000066400000000000000000000006141226375725500264110ustar00rootroot00000000000000 NOKIA 3650 yes yes Nokia 3650 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/remoterules/server/12_3660.xml000066400000000000000000000006141226375725500264130ustar00rootroot00000000000000 NOKIA 3660 yes yes Nokia 3660 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/remoterules/server/13_6260.xml000066400000000000000000000006141226375725500264130ustar00rootroot00000000000000 NOKIA 6260 yes yes Nokia 6260 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/remoterules/server/14_6600.xml000066400000000000000000000006141226375725500264120ustar00rootroot00000000000000 NOKIA 6600 yes yes Nokia 6600 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/remoterules/server/15_6620.xml000066400000000000000000000006141226375725500264150ustar00rootroot00000000000000 NOKIA 6620 yes yes Nokia 6620 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/remoterules/server/16_6630.xml000066400000000000000000000006141226375725500264170ustar00rootroot00000000000000 NOKIA 6630 yes yes Nokia 6630 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/remoterules/server/17_6670.xml000066400000000000000000000006141226375725500264240ustar00rootroot00000000000000 NOKIA 6670 yes yes Nokia 6670 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/remoterules/server/18_7250.xml000066400000000000000000000006141226375725500264200ustar00rootroot00000000000000 NOKIA 7250 yes yes Nokia 7250 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/remoterules/server/19_7250i.xml000066400000000000000000000006171226375725500265750ustar00rootroot00000000000000 NOKIA 7250i yes yes Nokia 7250i libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/remoterules/server/20_7260.xml000066400000000000000000000006141226375725500264120ustar00rootroot00000000000000 NOKIA 7260 yes yes Nokia 7260 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/remoterules/server/21_7610.xml000066400000000000000000000006141226375725500264120ustar00rootroot00000000000000 NOKIA 7610 yes yes Nokia 7610 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/remoterules/server/22_7650.xml000066400000000000000000000006141226375725500264170ustar00rootroot00000000000000 NOKIA 7650 yes yes Nokia 7650 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/remoterules/server/23_N-Gage.xml000066400000000000000000000006221226375725500270540ustar00rootroot00000000000000 NOKIA N-Gage yes yes Nokia N-Gage libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/remoterules/server/24_N-Gage_QD.xml000066400000000000000000000006331226375725500274430ustar00rootroot00000000000000 NOKIA N-Gage QD yes yes Nokia N-Gage QD libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/remoterules/server/25_9300.xml000066400000000000000000000006511226375725500264150ustar00rootroot00000000000000 NOKIA 9300 yes yes Nokia 9300 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/remoterules/server/26_9500.xml000066400000000000000000000006511226375725500264200ustar00rootroot00000000000000 NOKIA 9500 yes yes Nokia 9500 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/remoterules/server/27_E90.xml000066400000000000000000000005361226375725500263630ustar00rootroot00000000000000 NOKIA E90 yes Nokia E90 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/remoterules/server/28_X.xml000066400000000000000000000006031226375725500262310ustar00rootroot00000000000000 Sendo X yes yes Sendo X libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/remoterules/server/29_SX1.xml000066400000000000000000000010011226375725500264270ustar00rootroot00000000000000 SIEMENS SX1 yes yes yes Siemens SX1 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/remoterules/server/30_M55.xml000066400000000000000000000004121226375725500263570ustar00rootroot00000000000000 SIEMENS M55 yes yes Siemens M55 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/remoterules/server/31_SL55.xml000066400000000000000000000004151226375725500265050ustar00rootroot00000000000000 SIEMENS SL55 yes yes Siemens SL55 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/remoterules/server/32_S55.xml000066400000000000000000000004121226375725500263670ustar00rootroot00000000000000 SIEMENS S55 yes yes Siemens S55 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/remoterules/server/33_S65.xml000066400000000000000000000004121226375725500263710ustar00rootroot00000000000000 SIEMENS S65 yes yes Siemens S65 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/remoterules/server/34_SL65.xml000066400000000000000000000004151226375725500265110ustar00rootroot00000000000000 SIEMENS SL65 yes yes Siemens SL65 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/remoterules/server/35_K700.xml000066400000000000000000000007271226375725500264500ustar00rootroot00000000000000 SonyEricsson SEMC Phone R3B yes SonyEricsson K700 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/remoterules/server/36_T610_T630.xml000066400000000000000000000021071226375725500271700ustar00rootroot00000000000000 SonyEricsson R2B yes SonyEricsson T610/T630 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/remoterules/server/37_M600i.xml000066400000000000000000000025531226375725500266230ustar00rootroot00000000000000 Sony Ericsson M600i no yes SonyEricsson M600i libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/remoterules/server/38_P800.xml000066400000000000000000000025501226375725500264550ustar00rootroot00000000000000 Sony Ericsson P800 no yes SonyEricsson P800 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/remoterules/server/39_P900.xml000066400000000000000000000025501226375725500264570ustar00rootroot00000000000000 Sony Ericsson P900 no yes SonyEricsson P900 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/remoterules/server/40_P910.xml000066400000000000000000000025551226375725500264550ustar00rootroot00000000000000 Sony Ericsson P910 no yes SonyEricsson P910 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/remoterules/server/41_P910i.xml000066400000000000000000000025601226375725500266230ustar00rootroot00000000000000 Sony Ericsson P910i no yes SonyEricsson P910i libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/remoterules/server/42_P990i.xml000066400000000000000000000011321226375725500266260ustar00rootroot00000000000000 Sony Ericsson P990i no yes SonyEricsson P990i libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/remoterules/server/43_t68i.xml000066400000000000000000000005121226375725500266100ustar00rootroot00000000000000 SonyEricsson R2A yes ANSI SonyEricsson T68i libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/remoterules/server/44_Funambol_Outlook.xml000066400000000000000000000005141226375725500313000ustar00rootroot00000000000000 Funambol Outlook Sync Client yes Funambol Outlook Sync Client libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/remoterules/server/45_SyncJe_Outlook.xml000066400000000000000000000005111226375725500307260ustar00rootroot00000000000000 SyncJe Outlook Edition yes NextHaus SyncJe Outlook Client libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/scripting/000077500000000000000000000000001226375725500231165ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/scripting/10newuid.xml000066400000000000000000000003021226375725500252670ustar00rootroot00000000000000 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/scripting/11calendar.xml000066400000000000000000000123241226375725500255550ustar00rootroot00000000000000 0) { // DTSTART and DTEND represent allday event, make them date-only values // - convert start to user zone (or floating) so it represents midnight DTSTART = CONVERTTOUSERZONE(DTSTART); MAKEALLDAY(DTSTART,DTEND,i); } else { // iCalendar 2.0 - only if DTSTART is a date-only value this really is an allday if (ISDATEONLY(DTSTART)) { // reshape to make sure we don't have invalid zero-duration alldays (old OCS 9 servers) MAKEALLDAY(DTSTART,DTEND,i); } } // - shape attendees (and make sure ATTENDEES[] is assigned even for empty email addresses) i=0; while(i0) { DUE = DATEONLY(DUE); } } // Common alarm handling // - handle relative alarm time (as possible with VALARM TRIGGER) if (ISDURATION(ALARM_TIME)) { if (ALARM_REL==2) ts = DTEND; // relative to end else { if (ISEVENT) ts = DTSTART; // relative to start for events else ts = DUE; // relative to due for todos } // for now, make ALARM user(=system) zone in all cases ALARM_TIME = CONVERTTOUSERZONE(POINTINTIME(ts),TRUE) + ALARM_TIME; } ]]> libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/scripting/client/000077500000000000000000000000001226375725500243745ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/scripting/client/00timeout.xml000066400000000000000000000000421226375725500267400ustar00rootroot00000000000000 5 libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/scripting/server/000077500000000000000000000000001226375725500244245ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/scripting/server/12email.xml000066400000000000000000000141461226375725500264060ustar00rootroot00000000000000 SIZELIMIT())) { // force conflict only if this is a reload FORCECONFLICT(); } // make sure we never overwrite a body in the inbox BODY = UNASSIGNED; // delete always wins over replace in inbox (to avoid adds to inbox) DELETEWINS(); } } } else if (UPPERCASE(FOLDER)=="OUTBOX") { // never try to change something in outbox IGNOREUPDATE(); if (SYNCOP()!="delete") { // - date of mail is NOW, set it such that a correct date is written to the DB MAILDATE = DBNOW(); // MAILDATE = (INTEGER)DBNOW() - TIMEUNITS(120); // %%% backdate it 2 mins to make sure it does not get retransmitted // - echo item as replace (to force-move it to the sent folder) ECHOITEM("replace"); } CONFLICTSTRATEGY("client-wins"); } else if (UPPERCASE(FOLDER)=="SENT") { // never try to change something in sent folder IGNOREUPDATE(); // Server has precedence in case of conflicts CONFLICTSTRATEGY("server-wins"); // Implement reload capability for sent items as well if (SLOWSYNC()) { // do not add new sent items to the server in slowsync PREVENTADD(); // causes extra sent items on the client to be deleted } else { // make sure that existing server item will conflict with this item if (SYNCOP()=="replace") { if (LIMIT!=EMPTY && (LIMIT<0 || LIMIT>SIZELIMIT())) { // force conflict only if this is a reload FORCECONFLICT(); REJECTITEM(200); // but do not process the item further } else { // silently ignore other types of changes REJECTITEM(200); } // make sure we never overwrite a body in the sent folder BODY = UNASSIGNED; } } } else { // Other folder // - silently discard incoming item for other folder than the above // except if it is a delete if (SYNCOP()!="delete") REJECTITEM(0); } ]]> =V1.0.8.21 IF (LIMIT==EMPTY) LIMIT = SIZELIMIT(); // if none set already, use default for this item (=default of datastore, if not SETSIZELIMIT() called before for this item generation) } // set limit for item generator if (LIMIT!=EMPTY) SETSIZELIMIT(LIMIT); ]]> =STARTDATE(); RETURN PASSES; ]]> libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/sunbird_client.xml000077500000000000000000001035361226375725500246550ustar00rootroot00000000000000 Sunbird/Lightning 0.5 client demo using SQLite direct access $(logpath) flush yes html yes no yes separate yes no no no true 5 1.0 $(prefs_path)\synthesis.ch\syncml_client_$(targetdb) UTF-8 unix $(logpath)\$(targetdb)_synclog.txt $(logpath)/sunbirdsynclog.txt yes 20 1001 $(mozillaprofile)\storage.sdb $(prefs_path)/Sunbird/Profiles/$(sunbirdprofile)/storage.sdb unixtime_us UTF-8 unix UTC yes no yes SELECT id || coalesce(recurrence_id,'') as fullid,last_modified FROM cal_events %WF no SELECT %N FROM cal_events WHERE id || coalesce(recurrence_id,'')='%k' INSERT INTO cal_events (id,last_modified,time_created,%N,cal_id,priority,event_start_tz,event_end_tz) VALUES ('%k',%M,%M,%v,0,0,'/mozilla.org/20070129_1/Africa/Ceuta','/mozilla.org/20070129_1/Africa/Ceuta') UPDATE cal_events SET last_modified=%M,%V WHERE id || coalesce(recurrence_id,'')='%k' DELETE FROM cal_events WHERE id || coalesce(recurrence_id,'')='%k' yes F.KIND:=EVENT yes yes 0) { // all day - make dates span full day (required by SunBird) flags = flags | 0x08; // set allday bit DTSTART = CONVERTTOUSERZONE(DTSTART); // convert non-floating to user zone SETFLOATING(DTSTART); // make floating DTSTART = DATEONLY(DTSTART); // set to beginning of day DTEND = DTSTART + DAYUNITS(i); // make end exact number of days after start } // check for recurrence if (NORMALIZED(RR_FREQ)!=EMPTY) flags = flags | 0x10; // set recurrence bit ]]> 0) RR_FMASK = RR_FMASK | (1<0) { // counting from beginning RR_FMASK = RR_FMASK | (1< libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/syncclient_sample_config.xml000066400000000000000000001576501226375725500267150ustar00rootroot00000000000000 Synthesis SyncML Client Engine 3.4 sample config buffered yes html auto yes no yes separate no no no no true 5 0) { // DTSTART and DTEND represent allday event, make them date-only values // - convert start to user zone (or floating) so it represents midnight DTSTART = CONVERTTOUSERZONE(DTSTART); MAKEALLDAY(DTSTART,DTEND,i); } else { // iCalendar 2.0 - only if DTSTART is a date-only value this really is an allday if (ISDATEONLY(DTSTART)) { // reshape to make sure we don't have invalid zero-duration alldays (old OCS 9 servers) MAKEALLDAY(DTSTART,DTEND,i); } } // - shape attendees (and make sure ATTENDEES[] is assigned even for empty email addresses) i=0; while(i0) { DUE = DATEONLY(DUE); } } // Common alarm handling // - handle relative alarm time (as possible with VALARM TRIGGER) if (ISDURATION(ALARM_TIME)) { if (ALARM_REL==2) ts = DTEND; // relative to end else { if (ISEVENT) ts = DTSTART; // relative to start for events else ts = DUE; // relative to due for todos } // for now, make ALARM user(=system) zone in all cases ALARM_TIME = CONVERTTOUSERZONE(POINTINTIME(ts),TRUE) + ALARM_TIME; } ]]> 2.1 3.0 current olson 1.0 2.0 1 false true SUBJECT 0 false true text/plain 1.0 text/plain 1.1 text/x-vbookmark 1.0 [SDK_textdb] yes yes test test false UTF-8 unix yes 20 [SDK_textdb] yes UTF-8 unix yes yes yes [SDK_textdb] yes UTF-8 unix yes yes yes [SDK_textdb] yes UTF-8 unix yes yes yes [SDK_textdb] yes UTF-8 unix yes yes yes [SDK_textdb] yes UTF-8 unix yes yes yes libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/syncserv_sample_config.xml000077500000000000000000003311021226375725500264030ustar00rootroot00000000000000 Synthesis SyncML Server Engine 3.4 sample config buffered yes html auto yes no yes separate no no no no 0) { // DTSTART and DTEND represent allday event, make them date-only values // - convert start to user zone (or floating) so it represents midnight DTSTART = CONVERTTOUSERZONE(DTSTART); MAKEALLDAY(DTSTART,DTEND,i); } else { // iCalendar 2.0 - only if DTSTART is a date-only value this really is an allday if (ISDATEONLY(DTSTART)) { // reshape to make sure we don't have invalid zero-duration alldays (old OCS 9 servers) MAKEALLDAY(DTSTART,DTEND,i); } } // - shape attendees (and make sure ATTENDEES[] is assigned even for empty email addresses) i=0; while(i0) { DUE = DATEONLY(DUE); } } // Common alarm handling // - handle relative alarm time (as possible with VALARM TRIGGER) if (ISDURATION(ALARM_TIME)) { if (ALARM_REL==2) ts = DTEND; // relative to end else { if (ISEVENT) ts = DTSTART; // relative to start for events else ts = DUE; // relative to due for todos } // for now, make ALARM user(=system) zone in all cases ALARM_TIME = CONVERTTOUSERZONE(POINTINTIME(ts),TRUE) + ALARM_TIME; } ]]> SIZELIMIT())) { // force conflict only if this is a reload FORCECONFLICT(); } // make sure we never overwrite a body in the inbox BODY = UNASSIGNED; // delete always wins over replace in inbox (to avoid adds to inbox) DELETEWINS(); } } } else if (UPPERCASE(FOLDER)=="OUTBOX") { // never try to change something in outbox IGNOREUPDATE(); if (SYNCOP()!="delete") { // - date of mail is NOW, set it such that a correct date is written to the DB MAILDATE = DBNOW(); // MAILDATE = (INTEGER)DBNOW() - TIMEUNITS(120); // %%% backdate it 2 mins to make sure it does not get retransmitted // - echo item as replace (to force-move it to the sent folder) ECHOITEM("replace"); } CONFLICTSTRATEGY("client-wins"); } else if (UPPERCASE(FOLDER)=="SENT") { // never try to change something in sent folder IGNOREUPDATE(); // Server has precedence in case of conflicts CONFLICTSTRATEGY("server-wins"); // Implement reload capability for sent items as well if (SLOWSYNC()) { // do not add new sent items to the server in slowsync PREVENTADD(); // causes extra sent items on the client to be deleted } else { // make sure that existing server item will conflict with this item if (SYNCOP()=="replace") { if (LIMIT!=EMPTY && (LIMIT<0 || LIMIT>SIZELIMIT())) { // force conflict only if this is a reload FORCECONFLICT(); REJECTITEM(200); // but do not process the item further } else { // silently ignore other types of changes REJECTITEM(200); } // make sure we never overwrite a body in the sent folder BODY = UNASSIGNED; } } } else { // Other folder // - silently discard incoming item for other folder than the above // except if it is a delete if (SYNCOP()!="delete") REJECTITEM(0); } ]]> =V1.0.8.21 IF (LIMIT==EMPTY) LIMIT = SIZELIMIT(); // if none set already, use default for this item (=default of datastore, if not SETSIZELIMIT() called before for this item generation) } // set limit for item generator if (LIMIT!=EMPTY) SETSIZELIMIT(LIMIT); ]]> =STARTDATE(); RETURN PASSES; ]]> 2.1 3.0 current olson 1.0 2.0 1 false true SUBJECT 0 false true text/plain 1.0 text/plain 1.1 text/x-vbookmark 1.0 true 100 ATT_COUNT ATT_MIMETYPES ATT_CONTENTS ATT_SIZES ATT_NAMES LIMIT From: rfc2047 true FROM To: rfc2047 true TO Cc: rfc2047 true CC Bcc: rfc2047 true BCC Reply-To: rfc2047 true Subject: rfc2047 true SUBJECT X-Priority: true date Date: true Status: true X-Sync-Parent-Folder: true X-Sync-Message-Read: true X-Sync-Lastmodified: true body 0 false true text/message 1.0 application/x-zip-message 1.1 yes yes 9 message/rfc822 1.0 message/x-rfc822 1.0 SIZELIMIT())) { // force conflict only if this is a reload FORCECONFLICT(); } // make sure we never overwrite a body in the inbox BODY = UNASSIGNED; // delete always wins over replace in inbox (to avoid adds to inbox) DELETEWINS(); } } } else if (UPPERCASE(FOLDER)=="OUTBOX") { // never try to change something in outbox IGNOREUPDATE(); if (SYNCOP()!="delete") { // - date of mail is NOW, set it such that a correct date is written to the DB MAILDATE = DBNOW(); // MAILDATE = (INTEGER)DBNOW() - TIMEUNITS(120); // %%% backdate it 2 mins to make sure it does not get retransmitted // - echo item as delete (this causes that it is moved to the "sent" folder in the 9500) ECHOITEM("delete"); } CONFLICTSTRATEGY("client-wins"); } else { // Other folder // - silently discard incoming item for other folder than the above // except if it is a delete if (SYNCOP()!="delete") REJECTITEM(0); } ]]> =STARTDATE(); RETURN PASSES; ]]> [SDK_textdb] yes yes 42 UTF-8 unix yes 300 md5 md5 yes test test [SDK_textdb] yes 42 no newer-wins duplicate F.SYNCLVL:=10 F.SYNCLVL:=0|F.SYNCLVL*=E F.SYNCLVL:=10 UTF-8 unix SYSTEM yes yes yes [SDK_textdb] yes 42 no newer-wins duplicate F.SYNCLVL:=10 F.SYNCLVL:=0|F.SYNCLVL*=E F.SYNCLVL:=10 UTF-8 unix SYSTEM yes yes yes [SDK_textdb] yes 42 no newer-wins duplicate F.SYNCLVL:=10 F.SYNCLVL:=0|F.SYNCLVL*=E F.SYNCLVL:=10 UTF-8 unix SYSTEM yes yes yes yes yes F.ISEVENT:=1 e F.ISEVENT:=0 t [SDK_textdb] yes 42 no newer-wins duplicate F.SYNCLVL:=10 F.SYNCLVL:=0|F.SYNCLVL*=E F.SYNCLVL:=10 UTF-8 unix SYSTEM yes yes yes [SDK_textdb] yes 42 no newer-wins duplicate F.SYNCLVL:=10 F.SYNCLVL:=0|F.SYNCLVL*=E F.SYNCLVL:=10 UTF-8 unix SYSTEM yes yes yes [SDK_textdb] yes 42 no newer-wins duplicate F.SYNCLVL:=10 F.SYNCLVL:=0|F.SYNCLVL*=E F.SYNCLVL:=10 UTF-8 unix SYSTEM yes yes yes Ericsson R1A yes ANSI Ericsson T39m Ericsson R1B yes ANSI Ericsson T68 Motorola* V3 yes yes yes ANSI ANSI Motorola V3 Motorola* V3i yes yes yes ANSI Motorola V3i NOKIA 6230 yes yes Nokia 6230 NOKIA 9210 yes Nokia 9210 NOKIA 9210i yes Nokia 9210 NOKIA 3220 yes yes Nokia 3220 NOKIA 3230 yes yes Nokia 3230 NOKIA 3600 yes yes Nokia 3600 NOKIA 3620 yes yes Nokia 3620 NOKIA 3650 yes yes Nokia 3650 NOKIA 3660 yes yes Nokia 3660 NOKIA 6260 yes yes Nokia 6260 NOKIA 6600 yes yes Nokia 6600 NOKIA 6620 yes yes Nokia 6620 NOKIA 6630 yes yes Nokia 6630 NOKIA 6670 yes yes Nokia 6670 NOKIA 7250 yes yes Nokia 7250 NOKIA 7250i yes yes Nokia 7250i NOKIA 7260 yes yes Nokia 7260 NOKIA 7610 yes yes Nokia 7610 NOKIA 7650 yes yes Nokia 7650 NOKIA N-Gage yes yes Nokia N-Gage NOKIA N-Gage QD yes yes Nokia N-Gage QD NOKIA 9300 yes yes Nokia 9300 NOKIA 9500 yes yes Nokia 9500 NOKIA E90 yes Nokia E90 Sendo X yes yes Sendo X SIEMENS SX1 yes yes yes Siemens SX1 SIEMENS M55 yes yes Siemens M55 SIEMENS SL55 yes yes Siemens SL55 SIEMENS S55 yes yes Siemens S55 SIEMENS S65 yes yes Siemens S65 SIEMENS SL65 yes yes Siemens SL65 SonyEricsson SEMC Phone R3B yes SonyEricsson K700 SonyEricsson R2B yes SonyEricsson T610/T630 Sony Ericsson M600i no yes SonyEricsson M600i Sony Ericsson P800 no yes SonyEricsson P800 Sony Ericsson P900 no yes SonyEricsson P900 Sony Ericsson P910 no yes SonyEricsson P910 Sony Ericsson P910i no yes SonyEricsson P910i Sony Ericsson P990i no yes SonyEricsson P990i SonyEricsson R2A yes ANSI SonyEricsson T68i Funambol Outlook Sync Client yes Funambol Outlook Sync Client SyncJe Outlook Edition yes NextHaus SyncJe Outlook Client libsynthesis-3.4.0.47.1/src/sysync_SDK/configs/update-samples.pl000077500000000000000000000034701226375725500244040ustar00rootroot00000000000000#! /usr/bin/env perl sub basename { $_ = shift; s;.*/;;; return $_; } # Concatenate all files ending in .xml in the given directory # plus those in a specific subdirectory for client or server. # Order lexicographic ascending of the base filename. sub readfragments { my $dir = shift; my $subdir = shift; my @res = (); my @files = (); if (opendir(my $dh, $dir)) { foreach (grep (/.*\.xml$/, readdir($dh))) { push @files, "$dir/$_"; } closedir($dh); if (opendir(my $dh, "$dir/$subdir")) { foreach (grep (/.*\.xml$/, readdir($dh))) { push @files, "$dir/$subdir/$_"; } closedir($dh); } } @files = sort { basename($a) <=> basename($b) } @files; foreach (@files) { open(IN, "<$_") || die "cannot read $_: $!"; push @res, ; close(IN); } return join("", @res); } # replace content of , , and all s # with the corresponding shared and/or client/server .xml fragments sub update { my $file = shift; my $subdir = shift; open(IN, "<$file") || die "cannot read $file: $!"; $_ = join("", ); close(IN) || die "closing $file: $!"; s;(\n).*(\n *);$1 . readfragments("debug", $subdir) . $2;se; s;(\n).*(\n *);$1 . readfragments("scripting", $subdir) . $2;se; s;(\n).*(\n *);$1 . readfragments("datatypes", $subdir) . $2;se; s;(\n *).*;$1 . readfragments("remoterules", $subdir);se; open(OUT, ">$file") || die "cannot write $file: $!"; print OUT; close(OUT) || die "closing $file: $!"; } update("syncclient_sample_config.xml", "client"); update("syncserv_sample_config.xml", "server"); libsynthesis-3.4.0.47.1/src/sysync_SDK/dbplugin_cocoa_sample/000077500000000000000000000000001226375725500237755ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/sysync_SDK/dbplugin_cocoa_sample/dbplugin_cocoa_sample_ios.xcodeproj/000077500000000000000000000000001226375725500331545ustar00rootroot00000000000000project.pbxproj000066400000000000000000000416641226375725500361640ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/sysync_SDK/dbplugin_cocoa_sample/dbplugin_cocoa_sample_ios.xcodeproj// !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 46; objects = { /* Begin PBXBuildFile section */ AA747D9F0F9514B9006C5449 /* dbplugin_cocoa_sample_ios_Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = AA747D9E0F9514B9006C5449 /* dbplugin_cocoa_sample_ios_Prefix.pch */; }; AACBBE4A0F95108600F1A2B1 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AACBBE490F95108600F1A2B1 /* Foundation.framework */; }; EDDBA76A13040BB7005913FE /* dbplugin_cocoa.h in Headers */ = {isa = PBXBuildFile; fileRef = EDDBA75F13040BB7005913FE /* dbplugin_cocoa.h */; }; EDDBA76C13040BB7005913FE /* dbplugin_cocoa_wrapper.mm in Sources */ = {isa = PBXBuildFile; fileRef = EDDBA76113040BB7005913FE /* dbplugin_cocoa_wrapper.mm */; }; EDDBA76D13040BB7005913FE /* SettingsKey.h in Headers */ = {isa = PBXBuildFile; fileRef = EDDBA76213040BB7005913FE /* SettingsKey.h */; }; EDDBA76E13040BB7005913FE /* SettingsKey.m in Sources */ = {isa = PBXBuildFile; fileRef = EDDBA76313040BB7005913FE /* SettingsKey.m */; }; EDDBA77513040CB7005913FE /* sample_dbplugin1.mm in Sources */ = {isa = PBXBuildFile; fileRef = EDDBA77413040CB7005913FE /* sample_dbplugin1.mm */; }; EDDBA77913040F7E005913FE /* sample_dbplugin1.h in Headers */ = {isa = PBXBuildFile; fileRef = EDDBA77813040F7E005913FE /* sample_dbplugin1.h */; }; EDDBA7881304104E005913FE /* SDK_util.h in Headers */ = {isa = PBXBuildFile; fileRef = EDDBA7811304104E005913FE /* SDK_util.h */; }; EDDBA7891304104E005913FE /* syerror.h in Headers */ = {isa = PBXBuildFile; fileRef = EDDBA7821304104E005913FE /* syerror.h */; }; EDDBA78A1304104E005913FE /* sync_dbapi.h in Headers */ = {isa = PBXBuildFile; fileRef = EDDBA7831304104E005913FE /* sync_dbapi.h */; }; EDDBA78B1304104E005913FE /* sync_dbapidef.h in Headers */ = {isa = PBXBuildFile; fileRef = EDDBA7841304104E005913FE /* sync_dbapidef.h */; }; EDDBA78C1304104E005913FE /* sync_declarations.h in Headers */ = {isa = PBXBuildFile; fileRef = EDDBA7851304104E005913FE /* sync_declarations.h */; }; EDDBA78E1304104E005913FE /* sync_uiapi.h in Headers */ = {isa = PBXBuildFile; fileRef = EDDBA7871304104E005913FE /* sync_uiapi.h */; }; EDDBA79413041085005913FE /* sync_include.h in Headers */ = {isa = PBXBuildFile; fileRef = EDDBA79313041085005913FE /* sync_include.h */; }; EDDBA798130410C7005913FE /* target_options.h in Headers */ = {isa = PBXBuildFile; fileRef = EDDBA797130410C7005913FE /* target_options.h */; }; EDDBA7EE13042560005913FE /* sample_dbplugin2.h in Headers */ = {isa = PBXBuildFile; fileRef = EDDBA7E813042560005913FE /* sample_dbplugin2.h */; }; EDDBA7EF13042560005913FE /* sample_dbplugin2.mm in Sources */ = {isa = PBXBuildFile; fileRef = EDDBA7E913042560005913FE /* sample_dbplugin2.mm */; }; EDDBA7F013042560005913FE /* sample_dbplugin3.h in Headers */ = {isa = PBXBuildFile; fileRef = EDDBA7EA13042560005913FE /* sample_dbplugin3.h */; }; EDDBA7F113042560005913FE /* sample_dbplugin3.mm in Sources */ = {isa = PBXBuildFile; fileRef = EDDBA7EB13042560005913FE /* sample_dbplugin3.mm */; }; EDDBA7F213042560005913FE /* sample_dbplugin4.h in Headers */ = {isa = PBXBuildFile; fileRef = EDDBA7EC13042560005913FE /* sample_dbplugin4.h */; }; EDDBA7F313042560005913FE /* sample_dbplugin4.mm in Sources */ = {isa = PBXBuildFile; fileRef = EDDBA7ED13042560005913FE /* sample_dbplugin4.mm */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ AA747D9E0F9514B9006C5449 /* dbplugin_cocoa_sample_ios_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dbplugin_cocoa_sample_ios_Prefix.pch; sourceTree = SOURCE_ROOT; }; AACBBE490F95108600F1A2B1 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; D2AAC07E0554694100DB518D /* libdbplugin_cocoa_sample_ios.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libdbplugin_cocoa_sample_ios.a; sourceTree = BUILT_PRODUCTS_DIR; }; EDDBA75F13040BB7005913FE /* dbplugin_cocoa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dbplugin_cocoa.h; sourceTree = ""; }; EDDBA76013040BB7005913FE /* dbplugin_cocoa.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = dbplugin_cocoa.m; sourceTree = ""; }; EDDBA76113040BB7005913FE /* dbplugin_cocoa_wrapper.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = dbplugin_cocoa_wrapper.mm; sourceTree = ""; }; EDDBA76213040BB7005913FE /* SettingsKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SettingsKey.h; sourceTree = ""; }; EDDBA76313040BB7005913FE /* SettingsKey.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SettingsKey.m; sourceTree = ""; }; EDDBA77413040CB7005913FE /* sample_dbplugin1.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = sample_dbplugin1.mm; sourceTree = ""; }; EDDBA77813040F7E005913FE /* sample_dbplugin1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sample_dbplugin1.h; sourceTree = ""; }; EDDBA7811304104E005913FE /* SDK_util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDK_util.h; sourceTree = ""; }; EDDBA7821304104E005913FE /* syerror.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = syerror.h; sourceTree = ""; }; EDDBA7831304104E005913FE /* sync_dbapi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sync_dbapi.h; sourceTree = ""; }; EDDBA7841304104E005913FE /* sync_dbapidef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sync_dbapidef.h; sourceTree = ""; }; EDDBA7851304104E005913FE /* sync_declarations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sync_declarations.h; sourceTree = ""; }; EDDBA7871304104E005913FE /* sync_uiapi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sync_uiapi.h; sourceTree = ""; }; EDDBA79313041085005913FE /* sync_include.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sync_include.h; sourceTree = ""; }; EDDBA797130410C7005913FE /* target_options.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = target_options.h; sourceTree = ""; }; EDDBA7E813042560005913FE /* sample_dbplugin2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sample_dbplugin2.h; sourceTree = ""; }; EDDBA7E913042560005913FE /* sample_dbplugin2.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = sample_dbplugin2.mm; sourceTree = ""; }; EDDBA7EA13042560005913FE /* sample_dbplugin3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sample_dbplugin3.h; sourceTree = ""; }; EDDBA7EB13042560005913FE /* sample_dbplugin3.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = sample_dbplugin3.mm; sourceTree = ""; }; EDDBA7EC13042560005913FE /* sample_dbplugin4.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sample_dbplugin4.h; sourceTree = ""; }; EDDBA7ED13042560005913FE /* sample_dbplugin4.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = sample_dbplugin4.mm; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ D2AAC07C0554694100DB518D /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( AACBBE4A0F95108600F1A2B1 /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 034768DFFF38A50411DB9C8B /* Products */ = { isa = PBXGroup; children = ( D2AAC07E0554694100DB518D /* libdbplugin_cocoa_sample_ios.a */, ); name = Products; sourceTree = ""; }; 0867D691FE84028FC02AAC07 /* dbplugin_cocoa_sample_ios */ = { isa = PBXGroup; children = ( EDDBA78013040FEB005913FE /* sysync_SDK */, EDDBA75E13040BB7005913FE /* sdk_sources_cocoa */, 08FB77AEFE84172EC02AAC07 /* DB_plugins */, 32C88DFF0371C24200C91783 /* Other Sources */, 0867D69AFE84028FC02AAC07 /* Frameworks */, 034768DFFF38A50411DB9C8B /* Products */, ); name = dbplugin_cocoa_sample_ios; sourceTree = ""; }; 0867D69AFE84028FC02AAC07 /* Frameworks */ = { isa = PBXGroup; children = ( AACBBE490F95108600F1A2B1 /* Foundation.framework */, ); name = Frameworks; sourceTree = ""; }; 08FB77AEFE84172EC02AAC07 /* DB_plugins */ = { isa = PBXGroup; children = ( EDDBA77813040F7E005913FE /* sample_dbplugin1.h */, EDDBA77413040CB7005913FE /* sample_dbplugin1.mm */, EDDBA7E813042560005913FE /* sample_dbplugin2.h */, EDDBA7E913042560005913FE /* sample_dbplugin2.mm */, EDDBA7EA13042560005913FE /* sample_dbplugin3.h */, EDDBA7EB13042560005913FE /* sample_dbplugin3.mm */, EDDBA7EC13042560005913FE /* sample_dbplugin4.h */, EDDBA7ED13042560005913FE /* sample_dbplugin4.mm */, ); name = DB_plugins; sourceTree = ""; }; 32C88DFF0371C24200C91783 /* Other Sources */ = { isa = PBXGroup; children = ( EDDBA797130410C7005913FE /* target_options.h */, AA747D9E0F9514B9006C5449 /* dbplugin_cocoa_sample_ios_Prefix.pch */, ); name = "Other Sources"; sourceTree = ""; }; EDDBA75E13040BB7005913FE /* sdk_sources_cocoa */ = { isa = PBXGroup; children = ( EDDBA75F13040BB7005913FE /* dbplugin_cocoa.h */, EDDBA76013040BB7005913FE /* dbplugin_cocoa.m */, EDDBA76113040BB7005913FE /* dbplugin_cocoa_wrapper.mm */, EDDBA76213040BB7005913FE /* SettingsKey.h */, EDDBA76313040BB7005913FE /* SettingsKey.m */, ); name = sdk_sources_cocoa; path = ../sdk_sources_cocoa; sourceTree = SOURCE_ROOT; }; EDDBA78013040FEB005913FE /* sysync_SDK */ = { isa = PBXGroup; children = ( EDDBA79313041085005913FE /* sync_include.h */, EDDBA7811304104E005913FE /* SDK_util.h */, EDDBA7821304104E005913FE /* syerror.h */, EDDBA7831304104E005913FE /* sync_dbapi.h */, EDDBA7841304104E005913FE /* sync_dbapidef.h */, EDDBA7851304104E005913FE /* sync_declarations.h */, EDDBA7871304104E005913FE /* sync_uiapi.h */, ); name = sysync_SDK; path = ../Sources; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ D2AAC07A0554694100DB518D /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( AA747D9F0F9514B9006C5449 /* dbplugin_cocoa_sample_ios_Prefix.pch in Headers */, EDDBA76A13040BB7005913FE /* dbplugin_cocoa.h in Headers */, EDDBA76D13040BB7005913FE /* SettingsKey.h in Headers */, EDDBA77913040F7E005913FE /* sample_dbplugin1.h in Headers */, EDDBA7881304104E005913FE /* SDK_util.h in Headers */, EDDBA7891304104E005913FE /* syerror.h in Headers */, EDDBA78A1304104E005913FE /* sync_dbapi.h in Headers */, EDDBA78B1304104E005913FE /* sync_dbapidef.h in Headers */, EDDBA78C1304104E005913FE /* sync_declarations.h in Headers */, EDDBA78E1304104E005913FE /* sync_uiapi.h in Headers */, EDDBA79413041085005913FE /* sync_include.h in Headers */, EDDBA798130410C7005913FE /* target_options.h in Headers */, EDDBA7EE13042560005913FE /* sample_dbplugin2.h in Headers */, EDDBA7F013042560005913FE /* sample_dbplugin3.h in Headers */, EDDBA7F213042560005913FE /* sample_dbplugin4.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ D2AAC07D0554694100DB518D /* dbplugin_cocoa_sample_ios */ = { isa = PBXNativeTarget; buildConfigurationList = 1DEB921E08733DC00010E9CD /* Build configuration list for PBXNativeTarget "dbplugin_cocoa_sample_ios" */; buildPhases = ( D2AAC07A0554694100DB518D /* Headers */, D2AAC07B0554694100DB518D /* Sources */, D2AAC07C0554694100DB518D /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = dbplugin_cocoa_sample_ios; productName = dbplugin_cocoa_sample_ios; productReference = D2AAC07E0554694100DB518D /* libdbplugin_cocoa_sample_ios.a */; productType = "com.apple.product-type.library.static"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 0867D690FE84028FC02AAC07 /* Project object */ = { isa = PBXProject; attributes = { LastUpgradeCheck = 0430; }; buildConfigurationList = 1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "dbplugin_cocoa_sample_ios" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( English, Japanese, French, German, ); mainGroup = 0867D691FE84028FC02AAC07 /* dbplugin_cocoa_sample_ios */; productRefGroup = 034768DFFF38A50411DB9C8B /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( D2AAC07D0554694100DB518D /* dbplugin_cocoa_sample_ios */, ); }; /* End PBXProject section */ /* Begin PBXSourcesBuildPhase section */ D2AAC07B0554694100DB518D /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( EDDBA76C13040BB7005913FE /* dbplugin_cocoa_wrapper.mm in Sources */, EDDBA76E13040BB7005913FE /* SettingsKey.m in Sources */, EDDBA77513040CB7005913FE /* sample_dbplugin1.mm in Sources */, EDDBA7EF13042560005913FE /* sample_dbplugin2.mm in Sources */, EDDBA7F113042560005913FE /* sample_dbplugin3.mm in Sources */, EDDBA7F313042560005913FE /* sample_dbplugin4.mm in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin XCBuildConfiguration section */ 1DEB921F08733DC00010E9CD /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ARCHS = "$(ARCHS_STANDARD_32_BIT)"; CONFIGURATION_BUILD_DIR = "$(PROJECT_DIR)/../bin/iOS/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; COPY_PHASE_STRIP = NO; DSTROOT = /tmp/dbplugin_cocoa_sample_ios.dst; GCC_DYNAMIC_NO_PIC = NO; GCC_MODEL_TUNING = G5; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = dbplugin_cocoa_sample_ios_Prefix.pch; INSTALL_PATH = /usr/local/lib; PRODUCT_NAME = dbplugin_cocoa_sample_ios; }; name = Debug; }; 1DEB922008733DC00010E9CD /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ARCHS = "$(ARCHS_STANDARD_32_BIT)"; CONFIGURATION_BUILD_DIR = "$(PROJECT_DIR)/../bin/iOS/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; DSTROOT = /tmp/dbplugin_cocoa_sample_ios.dst; GCC_MODEL_TUNING = G5; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = dbplugin_cocoa_sample_ios_Prefix.pch; INSTALL_PATH = /usr/local/lib; PRODUCT_NAME = dbplugin_cocoa_sample_ios; }; name = Release; }; 1DEB922308733DC00010E9CD /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_BIT)"; GCC_C_LANGUAGE_STANDARD = c99; GCC_OPTIMIZATION_LEVEL = 0; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; OTHER_LDFLAGS = "-ObjC"; SDKROOT = iphoneos; }; name = Debug; }; 1DEB922408733DC00010E9CD /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_BIT)"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; OTHER_LDFLAGS = "-ObjC"; SDKROOT = iphoneos; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 1DEB921E08733DC00010E9CD /* Build configuration list for PBXNativeTarget "dbplugin_cocoa_sample_ios" */ = { isa = XCConfigurationList; buildConfigurations = ( 1DEB921F08733DC00010E9CD /* Debug */, 1DEB922008733DC00010E9CD /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "dbplugin_cocoa_sample_ios" */ = { isa = XCConfigurationList; buildConfigurations = ( 1DEB922308733DC00010E9CD /* Debug */, 1DEB922408733DC00010E9CD /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = 0867D690FE84028FC02AAC07 /* Project object */; } project.xcworkspace/000077500000000000000000000000001226375725500370735ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/sysync_SDK/dbplugin_cocoa_sample/dbplugin_cocoa_sample_ios.xcodeprojcontents.xcworkspacedata000066400000000000000000000002521226375725500440340ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/sysync_SDK/dbplugin_cocoa_sample/dbplugin_cocoa_sample_ios.xcodeproj/project.xcworkspace xcshareddata/000077500000000000000000000000001226375725500355305ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/sysync_SDK/dbplugin_cocoa_sample/dbplugin_cocoa_sample_ios.xcodeprojxcschemes/000077500000000000000000000000001226375725500375125ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/sysync_SDK/dbplugin_cocoa_sample/dbplugin_cocoa_sample_ios.xcodeproj/xcshareddatadbplugin_cocoa_sample_ios.xcscheme000066400000000000000000000040341226375725500464170ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/sysync_SDK/dbplugin_cocoa_sample/dbplugin_cocoa_sample_ios.xcodeproj/xcshareddata/xcschemes libsynthesis-3.4.0.47.1/src/sysync_SDK/dbplugin_cocoa_sample/dbplugin_cocoa_sample_ios_Prefix.pch000066400000000000000000000002741226375725500331740ustar00rootroot00000000000000// // Prefix header for all source files of the 'CocoaTouchStaticLibrary' target in the 'CocoaTouchStaticLibrary' project. // #ifdef __OBJC__ #import #endif libsynthesis-3.4.0.47.1/src/sysync_SDK/dbplugin_cocoa_sample/sample_dbplugin.h000066400000000000000000000050651226375725500273210ustar00rootroot00000000000000/* * File: sample_dbplugin.h * * Author: Lukas Zeller (luz@plan44.ch) * * Sample for statically linked cocoa plugin libraries (as needed for iPhoneOS). * * Copyright (c) 2011 plan44.ch * */ #import #import #import "dbplugin_cocoa.h" @interface SamplePluginModule : CocoaPluginModule { //%%% todo: add member variables here } - (id)initWithModuleName:(cAppCharP)aModuleName subName:(cAppCharP)aSubName contextName:(cAppCharP)aContextName andCB:(DB_Callback)aCB; - (void)dealloc; // Module identification + (int)buildNumber; - (cAppCharP)manufacturerName; - (cAppCharP)moduleName; // parsing plugin parameters - (TSyError)pluginParams:(cAppCharP)aParams fromEngineVersion:(long)aEngineVersion; // creating database context in this module's context - (CocoaPluginDB *)newPluginDBWithName:(cAppCharP)aName deviceKey:(cAppCharP)aDeviceKey userKey:(cAppCharP)aUserKey andCB:(DB_Callback)aCB; @end // SamplePluginModule // Wrapper for the DB context @interface SamplePluginDB : CocoaPluginDB { //%%% todo: add member variables here } - (id)initWithName:(cAppCharP)aName inModule:(CocoaPluginModule *)aModule deviceKey:(cAppCharP)aDeviceKey userKey:(cAppCharP)aUserKey andCB:(DB_Callback)aCB; - (void)dealloc; // Context features - (sInt32)contextSupportRules:(cAppCharP)aContextRules; - (sInt32)filterSupportRules:(cAppCharP)aFilterRules; // Thread change alert - (void)threadMayChangeNow; // Read phase - (TSyError)startDataReadWithLastToken:(cAppCharP)aLastToken andResumeToken:(cAppCharP)aResumeToken; - (TSyError)readNextItemAsKey:(SettingsKey *)aItemKey itemIdP:(NSString **)aItemIdP parentIdP:(NSString **)aParentIdP statusP:(sInt32 *)aStatusP isFirst:(BOOL)aFirst; - (TSyError)readItemAsKey:(SettingsKey *)aItemKey itemID:(NSString *)aItemID parentID:(NSString *)aParentID; - (TSyError)endDataRead; // Write phase - (TSyError)startDataWrite; - (TSyError)insertItemAsKey:(SettingsKey *)aItemKey parentID:(NSString *)aParentID newItemIdP:(NSString **)aNewItemIdP; #ifdef HAS_FINALIZE_LOCALID - (TSyError)finalizeLocalID:(NSString **)aLocIDP; #endif - (TSyError)updateItemAsKey:(SettingsKey *)aItemKey itemIdP:(NSString **)aItemIdP parentIdP:(NSString **)aParentIdP; - (TSyError)moveItem:(NSString *)aItemID fromParentID:(NSString *)aParentID toNewParent:(NSString *)aNewParentID; - (TSyError)deleteItem:(NSString *)aItemID parentID:(NSString *)aParentID; - (TSyError)deleteSyncSet; - (TSyError)endDataWriteWithSuccess:(BOOL)aSuccess andNewToken:(NSString **)aNewTokenP; @end // SamplePluginDB libsynthesis-3.4.0.47.1/src/sysync_SDK/dbplugin_cocoa_sample/sample_dbplugin.m000066400000000000000000000174631226375725500273330ustar00rootroot00000000000000// // sample_dbplugin.m // // Created by Lukas Zeller on 2008/02/21. // Copyright 2008-2010 Synthesis AG. All rights reserved. // #import "sample_dbplugin.h" PLUGIN_NS_BEGIN // the factory function CocoaPluginModule *newPluginModule( cAppCharP aModuleName, cAppCharP aSubName, cAppCharP aContextName, DB_Callback aCB ) { return [[SamplePluginModule alloc] initWithModuleName:aModuleName subName:aSubName contextName:aContextName andCB:aCB ]; } // newPluginModule PLUGIN_NS_END @implementation SamplePluginModule - (id)initWithModuleName:(cAppCharP)aModuleName subName:(cAppCharP)aSubName contextName:(cAppCharP)aContextName andCB:(DB_Callback)aCB { if ([ super initWithModuleName:aModuleName subName:aSubName contextName:aContextName andCB:aCB ]!=nil) { // allocate an autorelease pool for the module context [self debugOut:@"Module context created"]; // %%% todo: initialize module context } return self; } - (void)dealloc { [self debugOut:@"Module context destroyed"]; // %%% todo: deallocate any memory allocated within the context // done [super dealloc]; } + (int)buildNumber { return 0; } - (cAppCharP)manufacturerName { return "Synthesis AG"; } - (cAppCharP)moduleName { return "Sample Plugin"; } - (TSyError)pluginParams:(cAppCharP)aParams fromEngineVersion:(long)aEngineVersion { //%%% todo: parse plugin params if we support any // for now: supports no params // - return error if we get any params here return aParams==NULL || *aParams==0 ? LOCERR_OK : LOCERR_CFGPARSE; } // factory method for creating database context wrappers - (CocoaPluginDB *)newPluginDBWithName:(cAppCharP)aName deviceKey:(cAppCharP)aDeviceKey userKey:(cAppCharP)aUserKey andCB:(DB_Callback)aCB { return [[SamplePluginDB alloc] initWithName:aName inModule:self deviceKey:aDeviceKey userKey:aUserKey andCB:aCB ]; } @end // SamplePluginModule @implementation SamplePluginDB - (id)initWithName:(cAppCharP)aName inModule:(CocoaPluginModule *)aModule deviceKey:(cAppCharP)aDeviceKey userKey:(cAppCharP)aUserKey andCB:(DB_Callback)aCB; { if ([ super initWithName:aName inModule:aModule deviceKey:aDeviceKey userKey:aUserKey andCB:aCB ]!=nil) { [self debugOut:@"DB context created"]; //%%% todo: initialize DB context level stuff if there is any } return self; } - (void)dealloc { [self debugOut:@"DB context destroyed"]; //%%% todo: clean up DB context level stuff // done [super dealloc]; } - (sInt32)contextSupportRules:(cAppCharP)aContextRules { [self debugOut:[NSString stringWithFormat: @"Context support rules: %@", [NSString stringWithCString:aContextRules encoding:NSUTF8StringEncoding] ]]; // %%% todo: parse context support rules // for now none supported return 0; } - (sInt32)filterSupportRules:(cAppCharP)aFilterRules { [self debugOut:[NSString stringWithFormat: @"Filter support rules: %@", [NSString stringWithCString:aFilterRules encoding:NSUTF8StringEncoding] ]]; // %%% todo: parse filters // for now none supported return 0; } - (void)threadMayChangeNow { [self debugOut:@"threadMayChangeNow"]; // %%% todo: make sure changing thread does not cause problems } - (TSyError)startDataReadWithLastToken:(cAppCharP)aLastToken andResumeToken:(cAppCharP)aResumeToken { [self debugOut:[NSString stringWithFormat: @"startDataReadWithLastToken:%@ andResumeToken:%@", [NSString stringWithCString:aLastToken encoding:NSUTF8StringEncoding], [NSString stringWithCString:aResumeToken encoding:NSUTF8StringEncoding] ]]; //%%% todo: actually prepare everything needed for readNextItemAsKey //%%% for now: just return OK return LOCERR_OK; } - (TSyError)readNextItemAsKey:(SettingsKey *)aItemKey itemIdP:(NSString **)aItemIdP parentIdP:(NSString **)aParentIdP statusP:(sInt32 *)aStatusP isFirst:(BOOL)aFirst { TSyError sta = LOCERR_OK; [self debugOut:[NSString stringWithFormat:@"readNextItemAsKey: aFirst=%d", aFirst]]; //%%% todo: actually read first or next item from DB //%%% for now: just simulate empty DB *aStatusP = ReadNextItem_EOF; sta = LOCERR_OK; // done return sta; } - (TSyError)readItemAsKey:(SettingsKey *)aItemKey itemID:(NSString *)aItemID parentID:(NSString *)aParentID { TSyError sta = LOCERR_OK; [self debugOut:[NSString stringWithFormat: @"readItemAsKey: itemID=%@ parentID=%@", aItemID, aParentID ]]; //%%% todo: read item from DB //%%% for now just return "not found" status (our simulated DB is empty) sta = DB_NotFound; // done return sta; } - (TSyError)endDataRead { [self debugOut:@"endDataRead"]; //%%% todo: get rid of ressources only needed during readNextItemAsKey calls (such as cached list of items etc.) //%%% for now: just ok return LOCERR_OK; } - (TSyError)startDataWrite { [self debugOut:@"startDataWrite"]; //%%% todo: prepare DB for writing //%%% for now: just ok return LOCERR_OK; } - (TSyError)insertItemAsKey:(SettingsKey *)aItemKey parentID:(NSString *)aParentID newItemIdP:(NSString **)aNewItemIdP { TSyError sta = LOCERR_OK; [self debugOut:[NSString stringWithFormat: @"insertItemAsKey: parentID=%@", aParentID ]]; //%%% todo: insert item into DB and return new ID //%%% for now just return DB error (our simulated DB is always empty and can't be written) sta = DB_Error; // done return sta; } #ifdef HAS_FINALIZE_LOCALID // check if insert ID is temporary, and if so return real (persistent) - (TSyError)finalizeLocalID:(NSString **)aLocIDP { [self debugOutExotic:[NSString stringWithFormat: @"finalizeLocalID: tempLocID=%@", *aLocIDP ]]; //%%% todo: check if this is a temporary ID that needs to be finalized // Note: this is for DBs which save all changes at once at endDataWriteWithSuccess // and receive persistent IDs only then. For those, insertItemAsKey can // return temporary items which will be finalized using this call. //%%% for now: no finalisation needed return DB_NoContent; } #endif - (TSyError)updateItemAsKey:(SettingsKey *)aItemKey itemIdP:(NSString **)aItemIdP parentIdP:(NSString **)aParentIdP { TSyError sta = LOCERR_OK; [self debugOut:[NSString stringWithFormat: @"updateItemAsKey: parentID=%@, itemID=%@", *aParentIdP, *aItemIdP ]]; //%%% todo: update item in DB //%%% for now just return DB error (our simulated DB is always empty and can't be written) sta = DB_Error; // done return sta; } - (TSyError)moveItem:(NSString *)aItemID fromParentID:(NSString *)aParentID toNewParent:(NSString *)aNewParentID { [self debugOut:@"moveItem"]; // %%% todo: actually move item to new parent (if possible) return LOCERR_NOTIMP; } - (TSyError)deleteItem:(NSString *)aItemID parentID:(NSString *)aParentID { TSyError sta = LOCERR_OK; [self debugOut:[NSString stringWithFormat: @"deleteItem: parentID=%@, itemID=%@", aParentID, aItemID ]]; //%%% todo: delete item from DB //%%% for now just return DB error (our simulated DB is always empty and can't be written) // done return sta; } - (TSyError)deleteSyncSet { TSyError sta = LOCERR_OK; [self debugOut:@"deleteAllItems"]; //%%% todo:delete all items from the DB which belong to the sync set (=usually all, unless we have filters) // done return sta; } - (TSyError)endDataWriteWithSuccess:(BOOL)aSuccess andNewToken:(NSString **)aNewTokenP { TSyError sta = LOCERR_OK; [self debugOut:[NSString stringWithFormat:@"endDataWriteWithSuccess:%d", aSuccess]]; //%%% todo: if needed, commit changes to DB //%%% todo: THEN create "this sync" token (after all changes are saved) //%%% for now we just return the absolute timestamp of now sInt64 ll = CFAbsoluteTimeGetCurrent(); *aNewTokenP = [NSString stringWithFormat:@"%lld",ll]; // done return sta; } @end // SamplePluginDB libsynthesis-3.4.0.47.1/src/sysync_SDK/dbplugin_cocoa_sample/sample_dbplugin1.h000066400000000000000000000050721226375725500274000ustar00rootroot00000000000000/* * File: sample_dbplugin1.h * * Author: Lukas Zeller (luz@plan44.ch) * * Sample for statically linked cocoa plugin libraries (as needed for iPhoneOS). * * Copyright (c) 2011 plan44.ch * */ #import #import #import "dbplugin_cocoa.h" @interface SamplePluginModule1 : CocoaPluginModule { //%%% todo: add member variables here } - (id)initWithModuleName:(cAppCharP)aModuleName subName:(cAppCharP)aSubName contextName:(cAppCharP)aContextName andCB:(DB_Callback)aCB; - (void)dealloc; // Module identification + (int)buildNumber; - (cAppCharP)manufacturerName; - (cAppCharP)moduleName; // parsing plugin parameters - (TSyError)pluginParams:(cAppCharP)aParams fromEngineVersion:(long)aEngineVersion; // creating database context in this module's context - (CocoaPluginDB *)newPluginDBWithName:(cAppCharP)aName deviceKey:(cAppCharP)aDeviceKey userKey:(cAppCharP)aUserKey andCB:(DB_Callback)aCB; @end // SamplePluginModule1 // Wrapper for the DB context @interface SamplePluginDB1 : CocoaPluginDB { //%%% todo: add member variables here } - (id)initWithName:(cAppCharP)aName inModule:(CocoaPluginModule *)aModule deviceKey:(cAppCharP)aDeviceKey userKey:(cAppCharP)aUserKey andCB:(DB_Callback)aCB; - (void)dealloc; // Context features - (sInt32)contextSupportRules:(cAppCharP)aContextRules; - (sInt32)filterSupportRules:(cAppCharP)aFilterRules; // Thread change alert - (void)threadMayChangeNow; // Read phase - (TSyError)startDataReadWithLastToken:(cAppCharP)aLastToken andResumeToken:(cAppCharP)aResumeToken; - (TSyError)readNextItemAsKey:(SettingsKey *)aItemKey itemIdP:(NSString **)aItemIdP parentIdP:(NSString **)aParentIdP statusP:(sInt32 *)aStatusP isFirst:(BOOL)aFirst; - (TSyError)readItemAsKey:(SettingsKey *)aItemKey itemID:(NSString *)aItemID parentID:(NSString *)aParentID; - (TSyError)endDataRead; // Write phase - (TSyError)startDataWrite; - (TSyError)insertItemAsKey:(SettingsKey *)aItemKey parentID:(NSString *)aParentID newItemIdP:(NSString **)aNewItemIdP; #ifdef HAS_FINALIZE_LOCALID - (TSyError)finalizeLocalID:(NSString **)aLocIDP; #endif - (TSyError)updateItemAsKey:(SettingsKey *)aItemKey itemIdP:(NSString **)aItemIdP parentIdP:(NSString **)aParentIdP; - (TSyError)moveItem:(NSString *)aItemID fromParentID:(NSString *)aParentID toNewParent:(NSString *)aNewParentID; - (TSyError)deleteItem:(NSString *)aItemID parentID:(NSString *)aParentID; - (TSyError)deleteSyncSet; - (TSyError)endDataWriteWithSuccess:(BOOL)aSuccess andNewToken:(NSString **)aNewTokenP; @end // SamplePluginDB1 libsynthesis-3.4.0.47.1/src/sysync_SDK/dbplugin_cocoa_sample/sample_dbplugin1.mm000066400000000000000000000211621226375725500275600ustar00rootroot00000000000000/* * File: sample_dbplugin1.mm * * Author: Lukas Zeller (luz@plan44.ch) * * Sample for statically linked cocoa plugin libraries (as needed for iPhoneOS). * * Copyright (c) 2011 plan44.ch * */ // The following defines the name of the plugin to be created. #define DB_PLUGIN_NAMESPACE iPhone_dbplugin1 // include actual source, but as this is a C++ file, the inclusion will also // compile as C++ and can contain namespaces // the generic cocoa interface #include "../sdk_sources_cocoa/dbplugin_cocoa.m" // From here on, the code is independent of dylib or static plugin. For making a dylib plugin out of this, // just copy everything below into a .m file. // (therefore the code below is an copy of sample_dbplugin.m, the sample plugin for the Mac OS X // version of the sysync SDK, with only the object names enumerated to distinguish the 4 sample // plugins that need to co-exist in the one any only Objective C namespace) #import "sample_dbplugin1.h" PLUGIN_NS_BEGIN // the factory function CocoaPluginModule *newPluginModule( cAppCharP aModuleName, cAppCharP aSubName, cAppCharP aContextName, DB_Callback aCB ) { return [[SamplePluginModule1 alloc] initWithModuleName:aModuleName subName:aSubName contextName:aContextName andCB:aCB ]; } // newPluginModule PLUGIN_NS_END @implementation SamplePluginModule1 - (id)initWithModuleName:(cAppCharP)aModuleName subName:(cAppCharP)aSubName contextName:(cAppCharP)aContextName andCB:(DB_Callback)aCB { if ([ super initWithModuleName:aModuleName subName:aSubName contextName:aContextName andCB:aCB ]!=nil) { // allocate an autorelease pool for the module context [self debugOut:@"Module context created"]; // %%% todo: initialize module context } return self; } - (void)dealloc { [self debugOut:@"Module context destroyed"]; // %%% todo: deallocate any memory allocated within the context // done [super dealloc]; } + (int)buildNumber { return 0; } - (cAppCharP)manufacturerName { return "plan44.ch"; } - (cAppCharP)moduleName { return "Sample Plugin 1"; } - (TSyError)pluginParams:(cAppCharP)aParams fromEngineVersion:(long)aEngineVersion { //%%% todo: parse plugin params if we support any // for now: supports no params // - return error if we get any params here return aParams==NULL || *aParams==0 ? LOCERR_OK : LOCERR_CFGPARSE; } // factory method for creating database context wrappers - (CocoaPluginDB *)newPluginDBWithName:(cAppCharP)aName deviceKey:(cAppCharP)aDeviceKey userKey:(cAppCharP)aUserKey andCB:(DB_Callback)aCB { return [[SamplePluginDB1 alloc] initWithName:aName inModule:self deviceKey:aDeviceKey userKey:aUserKey andCB:aCB ]; } @end // SamplePluginModule1 @implementation SamplePluginDB1 - (id)initWithName:(cAppCharP)aName inModule:(CocoaPluginModule *)aModule deviceKey:(cAppCharP)aDeviceKey userKey:(cAppCharP)aUserKey andCB:(DB_Callback)aCB; { if ([ super initWithName:aName inModule:aModule deviceKey:aDeviceKey userKey:aUserKey andCB:aCB ]!=nil) { [self debugOut:@"DB context created"]; //%%% todo: initialize DB context level stuff if there is any } return self; } - (void)dealloc { [self debugOut:@"DB context destroyed"]; //%%% todo: clean up DB context level stuff // done [super dealloc]; } - (sInt32)contextSupportRules:(cAppCharP)aContextRules { [self debugOut:[NSString stringWithFormat: @"Context support rules: %@", [NSString stringWithCString:aContextRules encoding:NSUTF8StringEncoding] ]]; // %%% todo: parse context support rules // for now none supported return 0; } - (sInt32)filterSupportRules:(cAppCharP)aFilterRules { [self debugOut:[NSString stringWithFormat: @"Filter support rules: %@", [NSString stringWithCString:aFilterRules encoding:NSUTF8StringEncoding] ]]; // %%% todo: parse filters // for now none supported return 0; } - (void)threadMayChangeNow { [self debugOut:@"threadMayChangeNow"]; // %%% todo: make sure changing thread does not cause problems } - (TSyError)startDataReadWithLastToken:(cAppCharP)aLastToken andResumeToken:(cAppCharP)aResumeToken { [self debugOut:[NSString stringWithFormat: @"startDataReadWithLastToken:%@ andResumeToken:%@", [NSString stringWithCString:aLastToken encoding:NSUTF8StringEncoding], [NSString stringWithCString:aResumeToken encoding:NSUTF8StringEncoding] ]]; //%%% todo: actually prepare everything needed for readNextItemAsKey //%%% for now: just return OK return LOCERR_OK; } - (TSyError)readNextItemAsKey:(SettingsKey *)aItemKey itemIdP:(NSString **)aItemIdP parentIdP:(NSString **)aParentIdP statusP:(sInt32 *)aStatusP isFirst:(BOOL)aFirst { TSyError sta = LOCERR_OK; [self debugOut:[NSString stringWithFormat:@"readNextItemAsKey: aFirst=%d", aFirst]]; //%%% todo: actually read first or next item from DB //%%% for now: just simulate empty DB *aStatusP = ReadNextItem_EOF; sta = LOCERR_OK; // done return sta; } - (TSyError)readItemAsKey:(SettingsKey *)aItemKey itemID:(NSString *)aItemID parentID:(NSString *)aParentID { TSyError sta = LOCERR_OK; [self debugOut:[NSString stringWithFormat: @"readItemAsKey: itemID=%@ parentID=%@", aItemID, aParentID ]]; //%%% todo: read item from DB //%%% for now just return "not found" status (our simulated DB is empty) sta = DB_NotFound; // done return sta; } - (TSyError)endDataRead { [self debugOut:@"endDataRead"]; //%%% todo: get rid of ressources only needed during readNextItemAsKey calls (such as cached list of items etc.) //%%% for now: just ok return LOCERR_OK; } - (TSyError)startDataWrite { [self debugOut:@"startDataWrite"]; //%%% todo: prepare DB for writing //%%% for now: just ok return LOCERR_OK; } - (TSyError)insertItemAsKey:(SettingsKey *)aItemKey parentID:(NSString *)aParentID newItemIdP:(NSString **)aNewItemIdP { TSyError sta = LOCERR_OK; [self debugOut:[NSString stringWithFormat: @"insertItemAsKey: parentID=%@", aParentID ]]; //%%% todo: insert item into DB and return new ID //%%% for now just return DB error (our simulated DB is always empty and can't be written) sta = DB_Error; // done return sta; } #ifdef HAS_FINALIZE_LOCALID // check if insert ID is temporary, and if so return real (persistent) - (TSyError)finalizeLocalID:(NSString **)aLocIDP { [self debugOutExotic:[NSString stringWithFormat: @"finalizeLocalID: tempLocID=%@", *aLocIDP ]]; //%%% todo: check if this is a temporary ID that needs to be finalized // Note: this is for DBs which save all changes at once at endDataWriteWithSuccess // and receive persistent IDs only then. For those, insertItemAsKey can // return temporary items which will be finalized using this call. //%%% for now: no finalisation needed return DB_NoContent; } #endif - (TSyError)updateItemAsKey:(SettingsKey *)aItemKey itemIdP:(NSString **)aItemIdP parentIdP:(NSString **)aParentIdP { TSyError sta = LOCERR_OK; [self debugOut:[NSString stringWithFormat: @"updateItemAsKey: parentID=%@, itemID=%@", *aParentIdP, *aItemIdP ]]; //%%% todo: update item in DB //%%% for now just return DB error (our simulated DB is always empty and can't be written) sta = DB_Error; // done return sta; } - (TSyError)moveItem:(NSString *)aItemID fromParentID:(NSString *)aParentID toNewParent:(NSString *)aNewParentID { [self debugOut:@"moveItem"]; // %%% todo: actually move item to new parent (if possible) return LOCERR_NOTIMP; } - (TSyError)deleteItem:(NSString *)aItemID parentID:(NSString *)aParentID { TSyError sta = LOCERR_OK; [self debugOut:[NSString stringWithFormat: @"deleteItem: parentID=%@, itemID=%@", aParentID, aItemID ]]; //%%% todo: delete item from DB //%%% for now just return DB error (our simulated DB is always empty and can't be written) // done return sta; } - (TSyError)deleteSyncSet { TSyError sta = LOCERR_OK; [self debugOut:@"deleteAllItems"]; //%%% todo:delete all items from the DB which belong to the sync set (=usually all, unless we have filters) // done return sta; } - (TSyError)endDataWriteWithSuccess:(BOOL)aSuccess andNewToken:(NSString **)aNewTokenP { TSyError sta = LOCERR_OK; [self debugOut:[NSString stringWithFormat:@"endDataWriteWithSuccess:%d", aSuccess]]; //%%% todo: if needed, commit changes to DB //%%% todo: THEN create "this sync" token (after all changes are saved) //%%% for now we just return the absolute timestamp of now sInt64 ll = CFAbsoluteTimeGetCurrent(); *aNewTokenP = [NSString stringWithFormat:@"%lld",ll]; // done return sta; } @end // SamplePluginDB1 /* eof */libsynthesis-3.4.0.47.1/src/sysync_SDK/dbplugin_cocoa_sample/sample_dbplugin2.h000066400000000000000000000050721226375725500274010ustar00rootroot00000000000000/* * File: sample_dbplugin2.h * * Author: Lukas Zeller (luz@plan44.ch) * * Sample for statically linked cocoa plugin libraries (as needed for iPhoneOS). * * Copyright (c) 2011 plan44.ch * */ #import #import #import "dbplugin_cocoa.h" @interface SamplePluginModule2 : CocoaPluginModule { //%%% todo: add member variables here } - (id)initWithModuleName:(cAppCharP)aModuleName subName:(cAppCharP)aSubName contextName:(cAppCharP)aContextName andCB:(DB_Callback)aCB; - (void)dealloc; // Module identification + (int)buildNumber; - (cAppCharP)manufacturerName; - (cAppCharP)moduleName; // parsing plugin parameters - (TSyError)pluginParams:(cAppCharP)aParams fromEngineVersion:(long)aEngineVersion; // creating database context in this module's context - (CocoaPluginDB *)newPluginDBWithName:(cAppCharP)aName deviceKey:(cAppCharP)aDeviceKey userKey:(cAppCharP)aUserKey andCB:(DB_Callback)aCB; @end // SamplePluginModule2 // Wrapper for the DB context @interface SamplePluginDB2 : CocoaPluginDB { //%%% todo: add member variables here } - (id)initWithName:(cAppCharP)aName inModule:(CocoaPluginModule *)aModule deviceKey:(cAppCharP)aDeviceKey userKey:(cAppCharP)aUserKey andCB:(DB_Callback)aCB; - (void)dealloc; // Context features - (sInt32)contextSupportRules:(cAppCharP)aContextRules; - (sInt32)filterSupportRules:(cAppCharP)aFilterRules; // Thread change alert - (void)threadMayChangeNow; // Read phase - (TSyError)startDataReadWithLastToken:(cAppCharP)aLastToken andResumeToken:(cAppCharP)aResumeToken; - (TSyError)readNextItemAsKey:(SettingsKey *)aItemKey itemIdP:(NSString **)aItemIdP parentIdP:(NSString **)aParentIdP statusP:(sInt32 *)aStatusP isFirst:(BOOL)aFirst; - (TSyError)readItemAsKey:(SettingsKey *)aItemKey itemID:(NSString *)aItemID parentID:(NSString *)aParentID; - (TSyError)endDataRead; // Write phase - (TSyError)startDataWrite; - (TSyError)insertItemAsKey:(SettingsKey *)aItemKey parentID:(NSString *)aParentID newItemIdP:(NSString **)aNewItemIdP; #ifdef HAS_FINALIZE_LOCALID - (TSyError)finalizeLocalID:(NSString **)aLocIDP; #endif - (TSyError)updateItemAsKey:(SettingsKey *)aItemKey itemIdP:(NSString **)aItemIdP parentIdP:(NSString **)aParentIdP; - (TSyError)moveItem:(NSString *)aItemID fromParentID:(NSString *)aParentID toNewParent:(NSString *)aNewParentID; - (TSyError)deleteItem:(NSString *)aItemID parentID:(NSString *)aParentID; - (TSyError)deleteSyncSet; - (TSyError)endDataWriteWithSuccess:(BOOL)aSuccess andNewToken:(NSString **)aNewTokenP; @end // SamplePluginDB2 libsynthesis-3.4.0.47.1/src/sysync_SDK/dbplugin_cocoa_sample/sample_dbplugin2.mm000066400000000000000000000211621226375725500275610ustar00rootroot00000000000000/* * File: sample_dbplugin1.mm * * Author: Lukas Zeller (luz@plan44.ch) * * Sample for statically linked cocoa plugin libraries (as needed for iPhoneOS). * * Copyright (c) 2011 plan44.ch * */ // The following defines the name of the plugin to be created. #define DB_PLUGIN_NAMESPACE iPhone_dbplugin2 // include actual source, but as this is a C++ file, the inclusion will also // compile as C++ and can contain namespaces // the generic cocoa interface #include "../sdk_sources_cocoa/dbplugin_cocoa.m" // From here on, the code is independent of dylib or static plugin. For making a dylib plugin out of this, // just copy everything below into a .m file. // (therefore the code below is an copy of sample_dbplugin.m, the sample plugin for the Mac OS X // version of the sysync SDK, with only the object names enumerated to distinguish the 4 sample // plugins that need to co-exist in the one any only Objective C namespace) #import "sample_dbplugin2.h" PLUGIN_NS_BEGIN // the factory function CocoaPluginModule *newPluginModule( cAppCharP aModuleName, cAppCharP aSubName, cAppCharP aContextName, DB_Callback aCB ) { return [[SamplePluginModule2 alloc] initWithModuleName:aModuleName subName:aSubName contextName:aContextName andCB:aCB ]; } // newPluginModule PLUGIN_NS_END @implementation SamplePluginModule2 - (id)initWithModuleName:(cAppCharP)aModuleName subName:(cAppCharP)aSubName contextName:(cAppCharP)aContextName andCB:(DB_Callback)aCB { if ([ super initWithModuleName:aModuleName subName:aSubName contextName:aContextName andCB:aCB ]!=nil) { // allocate an autorelease pool for the module context [self debugOut:@"Module context created"]; // %%% todo: initialize module context } return self; } - (void)dealloc { [self debugOut:@"Module context destroyed"]; // %%% todo: deallocate any memory allocated within the context // done [super dealloc]; } + (int)buildNumber { return 0; } - (cAppCharP)manufacturerName { return "plan44.ch"; } - (cAppCharP)moduleName { return "Sample Plugin 2"; } - (TSyError)pluginParams:(cAppCharP)aParams fromEngineVersion:(long)aEngineVersion { //%%% todo: parse plugin params if we support any // for now: supports no params // - return error if we get any params here return aParams==NULL || *aParams==0 ? LOCERR_OK : LOCERR_CFGPARSE; } // factory method for creating database context wrappers - (CocoaPluginDB *)newPluginDBWithName:(cAppCharP)aName deviceKey:(cAppCharP)aDeviceKey userKey:(cAppCharP)aUserKey andCB:(DB_Callback)aCB { return [[SamplePluginDB2 alloc] initWithName:aName inModule:self deviceKey:aDeviceKey userKey:aUserKey andCB:aCB ]; } @end // SamplePluginModule2 @implementation SamplePluginDB2 - (id)initWithName:(cAppCharP)aName inModule:(CocoaPluginModule *)aModule deviceKey:(cAppCharP)aDeviceKey userKey:(cAppCharP)aUserKey andCB:(DB_Callback)aCB; { if ([ super initWithName:aName inModule:aModule deviceKey:aDeviceKey userKey:aUserKey andCB:aCB ]!=nil) { [self debugOut:@"DB context created"]; //%%% todo: initialize DB context level stuff if there is any } return self; } - (void)dealloc { [self debugOut:@"DB context destroyed"]; //%%% todo: clean up DB context level stuff // done [super dealloc]; } - (sInt32)contextSupportRules:(cAppCharP)aContextRules { [self debugOut:[NSString stringWithFormat: @"Context support rules: %@", [NSString stringWithCString:aContextRules encoding:NSUTF8StringEncoding] ]]; // %%% todo: parse context support rules // for now none supported return 0; } - (sInt32)filterSupportRules:(cAppCharP)aFilterRules { [self debugOut:[NSString stringWithFormat: @"Filter support rules: %@", [NSString stringWithCString:aFilterRules encoding:NSUTF8StringEncoding] ]]; // %%% todo: parse filters // for now none supported return 0; } - (void)threadMayChangeNow { [self debugOut:@"threadMayChangeNow"]; // %%% todo: make sure changing thread does not cause problems } - (TSyError)startDataReadWithLastToken:(cAppCharP)aLastToken andResumeToken:(cAppCharP)aResumeToken { [self debugOut:[NSString stringWithFormat: @"startDataReadWithLastToken:%@ andResumeToken:%@", [NSString stringWithCString:aLastToken encoding:NSUTF8StringEncoding], [NSString stringWithCString:aResumeToken encoding:NSUTF8StringEncoding] ]]; //%%% todo: actually prepare everything needed for readNextItemAsKey //%%% for now: just return OK return LOCERR_OK; } - (TSyError)readNextItemAsKey:(SettingsKey *)aItemKey itemIdP:(NSString **)aItemIdP parentIdP:(NSString **)aParentIdP statusP:(sInt32 *)aStatusP isFirst:(BOOL)aFirst { TSyError sta = LOCERR_OK; [self debugOut:[NSString stringWithFormat:@"readNextItemAsKey: aFirst=%d", aFirst]]; //%%% todo: actually read first or next item from DB //%%% for now: just simulate empty DB *aStatusP = ReadNextItem_EOF; sta = LOCERR_OK; // done return sta; } - (TSyError)readItemAsKey:(SettingsKey *)aItemKey itemID:(NSString *)aItemID parentID:(NSString *)aParentID { TSyError sta = LOCERR_OK; [self debugOut:[NSString stringWithFormat: @"readItemAsKey: itemID=%@ parentID=%@", aItemID, aParentID ]]; //%%% todo: read item from DB //%%% for now just return "not found" status (our simulated DB is empty) sta = DB_NotFound; // done return sta; } - (TSyError)endDataRead { [self debugOut:@"endDataRead"]; //%%% todo: get rid of ressources only needed during readNextItemAsKey calls (such as cached list of items etc.) //%%% for now: just ok return LOCERR_OK; } - (TSyError)startDataWrite { [self debugOut:@"startDataWrite"]; //%%% todo: prepare DB for writing //%%% for now: just ok return LOCERR_OK; } - (TSyError)insertItemAsKey:(SettingsKey *)aItemKey parentID:(NSString *)aParentID newItemIdP:(NSString **)aNewItemIdP { TSyError sta = LOCERR_OK; [self debugOut:[NSString stringWithFormat: @"insertItemAsKey: parentID=%@", aParentID ]]; //%%% todo: insert item into DB and return new ID //%%% for now just return DB error (our simulated DB is always empty and can't be written) sta = DB_Error; // done return sta; } #ifdef HAS_FINALIZE_LOCALID // check if insert ID is temporary, and if so return real (persistent) - (TSyError)finalizeLocalID:(NSString **)aLocIDP { [self debugOutExotic:[NSString stringWithFormat: @"finalizeLocalID: tempLocID=%@", *aLocIDP ]]; //%%% todo: check if this is a temporary ID that needs to be finalized // Note: this is for DBs which save all changes at once at endDataWriteWithSuccess // and receive persistent IDs only then. For those, insertItemAsKey can // return temporary items which will be finalized using this call. //%%% for now: no finalisation needed return DB_NoContent; } #endif - (TSyError)updateItemAsKey:(SettingsKey *)aItemKey itemIdP:(NSString **)aItemIdP parentIdP:(NSString **)aParentIdP { TSyError sta = LOCERR_OK; [self debugOut:[NSString stringWithFormat: @"updateItemAsKey: parentID=%@, itemID=%@", *aParentIdP, *aItemIdP ]]; //%%% todo: update item in DB //%%% for now just return DB error (our simulated DB is always empty and can't be written) sta = DB_Error; // done return sta; } - (TSyError)moveItem:(NSString *)aItemID fromParentID:(NSString *)aParentID toNewParent:(NSString *)aNewParentID { [self debugOut:@"moveItem"]; // %%% todo: actually move item to new parent (if possible) return LOCERR_NOTIMP; } - (TSyError)deleteItem:(NSString *)aItemID parentID:(NSString *)aParentID { TSyError sta = LOCERR_OK; [self debugOut:[NSString stringWithFormat: @"deleteItem: parentID=%@, itemID=%@", aParentID, aItemID ]]; //%%% todo: delete item from DB //%%% for now just return DB error (our simulated DB is always empty and can't be written) // done return sta; } - (TSyError)deleteSyncSet { TSyError sta = LOCERR_OK; [self debugOut:@"deleteAllItems"]; //%%% todo:delete all items from the DB which belong to the sync set (=usually all, unless we have filters) // done return sta; } - (TSyError)endDataWriteWithSuccess:(BOOL)aSuccess andNewToken:(NSString **)aNewTokenP { TSyError sta = LOCERR_OK; [self debugOut:[NSString stringWithFormat:@"endDataWriteWithSuccess:%d", aSuccess]]; //%%% todo: if needed, commit changes to DB //%%% todo: THEN create "this sync" token (after all changes are saved) //%%% for now we just return the absolute timestamp of now sInt64 ll = CFAbsoluteTimeGetCurrent(); *aNewTokenP = [NSString stringWithFormat:@"%lld",ll]; // done return sta; } @end // SamplePluginDB2 /* eof */libsynthesis-3.4.0.47.1/src/sysync_SDK/dbplugin_cocoa_sample/sample_dbplugin3.h000066400000000000000000000050721226375725500274020ustar00rootroot00000000000000/* * File: sample_dbplugin3.h * * Author: Lukas Zeller (luz@plan44.ch) * * Sample for statically linked cocoa plugin libraries (as needed for iPhoneOS). * * Copyright (c) 2011 plan44.ch * */ #import #import #import "dbplugin_cocoa.h" @interface SamplePluginModule3 : CocoaPluginModule { //%%% todo: add member variables here } - (id)initWithModuleName:(cAppCharP)aModuleName subName:(cAppCharP)aSubName contextName:(cAppCharP)aContextName andCB:(DB_Callback)aCB; - (void)dealloc; // Module identification + (int)buildNumber; - (cAppCharP)manufacturerName; - (cAppCharP)moduleName; // parsing plugin parameters - (TSyError)pluginParams:(cAppCharP)aParams fromEngineVersion:(long)aEngineVersion; // creating database context in this module's context - (CocoaPluginDB *)newPluginDBWithName:(cAppCharP)aName deviceKey:(cAppCharP)aDeviceKey userKey:(cAppCharP)aUserKey andCB:(DB_Callback)aCB; @end // SamplePluginModule3 // Wrapper for the DB context @interface SamplePluginDB3 : CocoaPluginDB { //%%% todo: add member variables here } - (id)initWithName:(cAppCharP)aName inModule:(CocoaPluginModule *)aModule deviceKey:(cAppCharP)aDeviceKey userKey:(cAppCharP)aUserKey andCB:(DB_Callback)aCB; - (void)dealloc; // Context features - (sInt32)contextSupportRules:(cAppCharP)aContextRules; - (sInt32)filterSupportRules:(cAppCharP)aFilterRules; // Thread change alert - (void)threadMayChangeNow; // Read phase - (TSyError)startDataReadWithLastToken:(cAppCharP)aLastToken andResumeToken:(cAppCharP)aResumeToken; - (TSyError)readNextItemAsKey:(SettingsKey *)aItemKey itemIdP:(NSString **)aItemIdP parentIdP:(NSString **)aParentIdP statusP:(sInt32 *)aStatusP isFirst:(BOOL)aFirst; - (TSyError)readItemAsKey:(SettingsKey *)aItemKey itemID:(NSString *)aItemID parentID:(NSString *)aParentID; - (TSyError)endDataRead; // Write phase - (TSyError)startDataWrite; - (TSyError)insertItemAsKey:(SettingsKey *)aItemKey parentID:(NSString *)aParentID newItemIdP:(NSString **)aNewItemIdP; #ifdef HAS_FINALIZE_LOCALID - (TSyError)finalizeLocalID:(NSString **)aLocIDP; #endif - (TSyError)updateItemAsKey:(SettingsKey *)aItemKey itemIdP:(NSString **)aItemIdP parentIdP:(NSString **)aParentIdP; - (TSyError)moveItem:(NSString *)aItemID fromParentID:(NSString *)aParentID toNewParent:(NSString *)aNewParentID; - (TSyError)deleteItem:(NSString *)aItemID parentID:(NSString *)aParentID; - (TSyError)deleteSyncSet; - (TSyError)endDataWriteWithSuccess:(BOOL)aSuccess andNewToken:(NSString **)aNewTokenP; @end // SamplePluginDB3 libsynthesis-3.4.0.47.1/src/sysync_SDK/dbplugin_cocoa_sample/sample_dbplugin3.mm000066400000000000000000000211621226375725500275620ustar00rootroot00000000000000/* * File: sample_dbplugin3.mm * * Author: Lukas Zeller (luz@plan44.ch) * * Sample for statically linked cocoa plugin libraries (as needed for iPhoneOS). * * Copyright (c) 2011 plan44.ch * */ // The following defines the name of the plugin to be created. #define DB_PLUGIN_NAMESPACE iPhone_dbplugin3 // include actual source, but as this is a C++ file, the inclusion will also // compile as C++ and can contain namespaces // the generic cocoa interface #include "../sdk_sources_cocoa/dbplugin_cocoa.m" // From here on, the code is independent of dylib or static plugin. For making a dylib plugin out of this, // just copy everything below into a .m file. // (therefore the code below is an copy of sample_dbplugin.m, the sample plugin for the Mac OS X // version of the sysync SDK, with only the object names enumerated to distinguish the 4 sample // plugins that need to co-exist in the one any only Objective C namespace) #import "sample_dbplugin3.h" PLUGIN_NS_BEGIN // the factory function CocoaPluginModule *newPluginModule( cAppCharP aModuleName, cAppCharP aSubName, cAppCharP aContextName, DB_Callback aCB ) { return [[SamplePluginModule3 alloc] initWithModuleName:aModuleName subName:aSubName contextName:aContextName andCB:aCB ]; } // newPluginModule PLUGIN_NS_END @implementation SamplePluginModule3 - (id)initWithModuleName:(cAppCharP)aModuleName subName:(cAppCharP)aSubName contextName:(cAppCharP)aContextName andCB:(DB_Callback)aCB { if ([ super initWithModuleName:aModuleName subName:aSubName contextName:aContextName andCB:aCB ]!=nil) { // allocate an autorelease pool for the module context [self debugOut:@"Module context created"]; // %%% todo: initialize module context } return self; } - (void)dealloc { [self debugOut:@"Module context destroyed"]; // %%% todo: deallocate any memory allocated within the context // done [super dealloc]; } + (int)buildNumber { return 0; } - (cAppCharP)manufacturerName { return "plan44.ch"; } - (cAppCharP)moduleName { return "Sample Plugin 3"; } - (TSyError)pluginParams:(cAppCharP)aParams fromEngineVersion:(long)aEngineVersion { //%%% todo: parse plugin params if we support any // for now: supports no params // - return error if we get any params here return aParams==NULL || *aParams==0 ? LOCERR_OK : LOCERR_CFGPARSE; } // factory method for creating database context wrappers - (CocoaPluginDB *)newPluginDBWithName:(cAppCharP)aName deviceKey:(cAppCharP)aDeviceKey userKey:(cAppCharP)aUserKey andCB:(DB_Callback)aCB { return [[SamplePluginDB3 alloc] initWithName:aName inModule:self deviceKey:aDeviceKey userKey:aUserKey andCB:aCB ]; } @end // SamplePluginModule3 @implementation SamplePluginDB3 - (id)initWithName:(cAppCharP)aName inModule:(CocoaPluginModule *)aModule deviceKey:(cAppCharP)aDeviceKey userKey:(cAppCharP)aUserKey andCB:(DB_Callback)aCB; { if ([ super initWithName:aName inModule:aModule deviceKey:aDeviceKey userKey:aUserKey andCB:aCB ]!=nil) { [self debugOut:@"DB context created"]; //%%% todo: initialize DB context level stuff if there is any } return self; } - (void)dealloc { [self debugOut:@"DB context destroyed"]; //%%% todo: clean up DB context level stuff // done [super dealloc]; } - (sInt32)contextSupportRules:(cAppCharP)aContextRules { [self debugOut:[NSString stringWithFormat: @"Context support rules: %@", [NSString stringWithCString:aContextRules encoding:NSUTF8StringEncoding] ]]; // %%% todo: parse context support rules // for now none supported return 0; } - (sInt32)filterSupportRules:(cAppCharP)aFilterRules { [self debugOut:[NSString stringWithFormat: @"Filter support rules: %@", [NSString stringWithCString:aFilterRules encoding:NSUTF8StringEncoding] ]]; // %%% todo: parse filters // for now none supported return 0; } - (void)threadMayChangeNow { [self debugOut:@"threadMayChangeNow"]; // %%% todo: make sure changing thread does not cause problems } - (TSyError)startDataReadWithLastToken:(cAppCharP)aLastToken andResumeToken:(cAppCharP)aResumeToken { [self debugOut:[NSString stringWithFormat: @"startDataReadWithLastToken:%@ andResumeToken:%@", [NSString stringWithCString:aLastToken encoding:NSUTF8StringEncoding], [NSString stringWithCString:aResumeToken encoding:NSUTF8StringEncoding] ]]; //%%% todo: actually prepare everything needed for readNextItemAsKey //%%% for now: just return OK return LOCERR_OK; } - (TSyError)readNextItemAsKey:(SettingsKey *)aItemKey itemIdP:(NSString **)aItemIdP parentIdP:(NSString **)aParentIdP statusP:(sInt32 *)aStatusP isFirst:(BOOL)aFirst { TSyError sta = LOCERR_OK; [self debugOut:[NSString stringWithFormat:@"readNextItemAsKey: aFirst=%d", aFirst]]; //%%% todo: actually read first or next item from DB //%%% for now: just simulate empty DB *aStatusP = ReadNextItem_EOF; sta = LOCERR_OK; // done return sta; } - (TSyError)readItemAsKey:(SettingsKey *)aItemKey itemID:(NSString *)aItemID parentID:(NSString *)aParentID { TSyError sta = LOCERR_OK; [self debugOut:[NSString stringWithFormat: @"readItemAsKey: itemID=%@ parentID=%@", aItemID, aParentID ]]; //%%% todo: read item from DB //%%% for now just return "not found" status (our simulated DB is empty) sta = DB_NotFound; // done return sta; } - (TSyError)endDataRead { [self debugOut:@"endDataRead"]; //%%% todo: get rid of ressources only needed during readNextItemAsKey calls (such as cached list of items etc.) //%%% for now: just ok return LOCERR_OK; } - (TSyError)startDataWrite { [self debugOut:@"startDataWrite"]; //%%% todo: prepare DB for writing //%%% for now: just ok return LOCERR_OK; } - (TSyError)insertItemAsKey:(SettingsKey *)aItemKey parentID:(NSString *)aParentID newItemIdP:(NSString **)aNewItemIdP { TSyError sta = LOCERR_OK; [self debugOut:[NSString stringWithFormat: @"insertItemAsKey: parentID=%@", aParentID ]]; //%%% todo: insert item into DB and return new ID //%%% for now just return DB error (our simulated DB is always empty and can't be written) sta = DB_Error; // done return sta; } #ifdef HAS_FINALIZE_LOCALID // check if insert ID is temporary, and if so return real (persistent) - (TSyError)finalizeLocalID:(NSString **)aLocIDP { [self debugOutExotic:[NSString stringWithFormat: @"finalizeLocalID: tempLocID=%@", *aLocIDP ]]; //%%% todo: check if this is a temporary ID that needs to be finalized // Note: this is for DBs which save all changes at once at endDataWriteWithSuccess // and receive persistent IDs only then. For those, insertItemAsKey can // return temporary items which will be finalized using this call. //%%% for now: no finalisation needed return DB_NoContent; } #endif - (TSyError)updateItemAsKey:(SettingsKey *)aItemKey itemIdP:(NSString **)aItemIdP parentIdP:(NSString **)aParentIdP { TSyError sta = LOCERR_OK; [self debugOut:[NSString stringWithFormat: @"updateItemAsKey: parentID=%@, itemID=%@", *aParentIdP, *aItemIdP ]]; //%%% todo: update item in DB //%%% for now just return DB error (our simulated DB is always empty and can't be written) sta = DB_Error; // done return sta; } - (TSyError)moveItem:(NSString *)aItemID fromParentID:(NSString *)aParentID toNewParent:(NSString *)aNewParentID { [self debugOut:@"moveItem"]; // %%% todo: actually move item to new parent (if possible) return LOCERR_NOTIMP; } - (TSyError)deleteItem:(NSString *)aItemID parentID:(NSString *)aParentID { TSyError sta = LOCERR_OK; [self debugOut:[NSString stringWithFormat: @"deleteItem: parentID=%@, itemID=%@", aParentID, aItemID ]]; //%%% todo: delete item from DB //%%% for now just return DB error (our simulated DB is always empty and can't be written) // done return sta; } - (TSyError)deleteSyncSet { TSyError sta = LOCERR_OK; [self debugOut:@"deleteAllItems"]; //%%% todo:delete all items from the DB which belong to the sync set (=usually all, unless we have filters) // done return sta; } - (TSyError)endDataWriteWithSuccess:(BOOL)aSuccess andNewToken:(NSString **)aNewTokenP { TSyError sta = LOCERR_OK; [self debugOut:[NSString stringWithFormat:@"endDataWriteWithSuccess:%d", aSuccess]]; //%%% todo: if needed, commit changes to DB //%%% todo: THEN create "this sync" token (after all changes are saved) //%%% for now we just return the absolute timestamp of now sInt64 ll = CFAbsoluteTimeGetCurrent(); *aNewTokenP = [NSString stringWithFormat:@"%lld",ll]; // done return sta; } @end // SamplePluginDB3 /* eof */libsynthesis-3.4.0.47.1/src/sysync_SDK/dbplugin_cocoa_sample/sample_dbplugin4.h000066400000000000000000000050721226375725500274030ustar00rootroot00000000000000/* * File: sample_dbplugin4.h * * Author: Lukas Zeller (luz@plan44.ch) * * Sample for statically linked cocoa plugin libraries (as needed for iPhoneOS). * * Copyright (c) 2011 plan44.ch * */ #import #import #import "dbplugin_cocoa.h" @interface SamplePluginModule4 : CocoaPluginModule { //%%% todo: add member variables here } - (id)initWithModuleName:(cAppCharP)aModuleName subName:(cAppCharP)aSubName contextName:(cAppCharP)aContextName andCB:(DB_Callback)aCB; - (void)dealloc; // Module identification + (int)buildNumber; - (cAppCharP)manufacturerName; - (cAppCharP)moduleName; // parsing plugin parameters - (TSyError)pluginParams:(cAppCharP)aParams fromEngineVersion:(long)aEngineVersion; // creating database context in this module's context - (CocoaPluginDB *)newPluginDBWithName:(cAppCharP)aName deviceKey:(cAppCharP)aDeviceKey userKey:(cAppCharP)aUserKey andCB:(DB_Callback)aCB; @end // SamplePluginModule4 // Wrapper for the DB context @interface SamplePluginDB4 : CocoaPluginDB { //%%% todo: add member variables here } - (id)initWithName:(cAppCharP)aName inModule:(CocoaPluginModule *)aModule deviceKey:(cAppCharP)aDeviceKey userKey:(cAppCharP)aUserKey andCB:(DB_Callback)aCB; - (void)dealloc; // Context features - (sInt32)contextSupportRules:(cAppCharP)aContextRules; - (sInt32)filterSupportRules:(cAppCharP)aFilterRules; // Thread change alert - (void)threadMayChangeNow; // Read phase - (TSyError)startDataReadWithLastToken:(cAppCharP)aLastToken andResumeToken:(cAppCharP)aResumeToken; - (TSyError)readNextItemAsKey:(SettingsKey *)aItemKey itemIdP:(NSString **)aItemIdP parentIdP:(NSString **)aParentIdP statusP:(sInt32 *)aStatusP isFirst:(BOOL)aFirst; - (TSyError)readItemAsKey:(SettingsKey *)aItemKey itemID:(NSString *)aItemID parentID:(NSString *)aParentID; - (TSyError)endDataRead; // Write phase - (TSyError)startDataWrite; - (TSyError)insertItemAsKey:(SettingsKey *)aItemKey parentID:(NSString *)aParentID newItemIdP:(NSString **)aNewItemIdP; #ifdef HAS_FINALIZE_LOCALID - (TSyError)finalizeLocalID:(NSString **)aLocIDP; #endif - (TSyError)updateItemAsKey:(SettingsKey *)aItemKey itemIdP:(NSString **)aItemIdP parentIdP:(NSString **)aParentIdP; - (TSyError)moveItem:(NSString *)aItemID fromParentID:(NSString *)aParentID toNewParent:(NSString *)aNewParentID; - (TSyError)deleteItem:(NSString *)aItemID parentID:(NSString *)aParentID; - (TSyError)deleteSyncSet; - (TSyError)endDataWriteWithSuccess:(BOOL)aSuccess andNewToken:(NSString **)aNewTokenP; @end // SamplePluginDB4 libsynthesis-3.4.0.47.1/src/sysync_SDK/dbplugin_cocoa_sample/sample_dbplugin4.mm000066400000000000000000000211621226375725500275630ustar00rootroot00000000000000/* * File: sample_dbplugin4.mm * * Author: Lukas Zeller (luz@plan44.ch) * * Sample for statically linked cocoa plugin libraries (as needed for iPhoneOS). * * Copyright (c) 2011 plan44.ch * */ // The following defines the name of the plugin to be created. #define DB_PLUGIN_NAMESPACE iPhone_dbplugin4 // include actual source, but as this is a C++ file, the inclusion will also // compile as C++ and can contain namespaces // the generic cocoa interface #include "../sdk_sources_cocoa/dbplugin_cocoa.m" // From here on, the code is independent of dylib or static plugin. For making a dylib plugin out of this, // just copy everything below into a .m file. // (therefore the code below is an copy of sample_dbplugin.m, the sample plugin for the Mac OS X // version of the sysync SDK, with only the object names enumerated to distinguish the 4 sample // plugins that need to co-exist in the one any only Objective C namespace) #import "sample_dbplugin4.h" PLUGIN_NS_BEGIN // the factory function CocoaPluginModule *newPluginModule( cAppCharP aModuleName, cAppCharP aSubName, cAppCharP aContextName, DB_Callback aCB ) { return [[SamplePluginModule4 alloc] initWithModuleName:aModuleName subName:aSubName contextName:aContextName andCB:aCB ]; } // newPluginModule PLUGIN_NS_END @implementation SamplePluginModule4 - (id)initWithModuleName:(cAppCharP)aModuleName subName:(cAppCharP)aSubName contextName:(cAppCharP)aContextName andCB:(DB_Callback)aCB { if ([ super initWithModuleName:aModuleName subName:aSubName contextName:aContextName andCB:aCB ]!=nil) { // allocate an autorelease pool for the module context [self debugOut:@"Module context created"]; // %%% todo: initialize module context } return self; } - (void)dealloc { [self debugOut:@"Module context destroyed"]; // %%% todo: deallocate any memory allocated within the context // done [super dealloc]; } + (int)buildNumber { return 0; } - (cAppCharP)manufacturerName { return "plan44.ch"; } - (cAppCharP)moduleName { return "Sample Plugin 4"; } - (TSyError)pluginParams:(cAppCharP)aParams fromEngineVersion:(long)aEngineVersion { //%%% todo: parse plugin params if we support any // for now: supports no params // - return error if we get any params here return aParams==NULL || *aParams==0 ? LOCERR_OK : LOCERR_CFGPARSE; } // factory method for creating database context wrappers - (CocoaPluginDB *)newPluginDBWithName:(cAppCharP)aName deviceKey:(cAppCharP)aDeviceKey userKey:(cAppCharP)aUserKey andCB:(DB_Callback)aCB { return [[SamplePluginDB4 alloc] initWithName:aName inModule:self deviceKey:aDeviceKey userKey:aUserKey andCB:aCB ]; } @end // SamplePluginModule4 @implementation SamplePluginDB4 - (id)initWithName:(cAppCharP)aName inModule:(CocoaPluginModule *)aModule deviceKey:(cAppCharP)aDeviceKey userKey:(cAppCharP)aUserKey andCB:(DB_Callback)aCB; { if ([ super initWithName:aName inModule:aModule deviceKey:aDeviceKey userKey:aUserKey andCB:aCB ]!=nil) { [self debugOut:@"DB context created"]; //%%% todo: initialize DB context level stuff if there is any } return self; } - (void)dealloc { [self debugOut:@"DB context destroyed"]; //%%% todo: clean up DB context level stuff // done [super dealloc]; } - (sInt32)contextSupportRules:(cAppCharP)aContextRules { [self debugOut:[NSString stringWithFormat: @"Context support rules: %@", [NSString stringWithCString:aContextRules encoding:NSUTF8StringEncoding] ]]; // %%% todo: parse context support rules // for now none supported return 0; } - (sInt32)filterSupportRules:(cAppCharP)aFilterRules { [self debugOut:[NSString stringWithFormat: @"Filter support rules: %@", [NSString stringWithCString:aFilterRules encoding:NSUTF8StringEncoding] ]]; // %%% todo: parse filters // for now none supported return 0; } - (void)threadMayChangeNow { [self debugOut:@"threadMayChangeNow"]; // %%% todo: make sure changing thread does not cause problems } - (TSyError)startDataReadWithLastToken:(cAppCharP)aLastToken andResumeToken:(cAppCharP)aResumeToken { [self debugOut:[NSString stringWithFormat: @"startDataReadWithLastToken:%@ andResumeToken:%@", [NSString stringWithCString:aLastToken encoding:NSUTF8StringEncoding], [NSString stringWithCString:aResumeToken encoding:NSUTF8StringEncoding] ]]; //%%% todo: actually prepare everything needed for readNextItemAsKey //%%% for now: just return OK return LOCERR_OK; } - (TSyError)readNextItemAsKey:(SettingsKey *)aItemKey itemIdP:(NSString **)aItemIdP parentIdP:(NSString **)aParentIdP statusP:(sInt32 *)aStatusP isFirst:(BOOL)aFirst { TSyError sta = LOCERR_OK; [self debugOut:[NSString stringWithFormat:@"readNextItemAsKey: aFirst=%d", aFirst]]; //%%% todo: actually read first or next item from DB //%%% for now: just simulate empty DB *aStatusP = ReadNextItem_EOF; sta = LOCERR_OK; // done return sta; } - (TSyError)readItemAsKey:(SettingsKey *)aItemKey itemID:(NSString *)aItemID parentID:(NSString *)aParentID { TSyError sta = LOCERR_OK; [self debugOut:[NSString stringWithFormat: @"readItemAsKey: itemID=%@ parentID=%@", aItemID, aParentID ]]; //%%% todo: read item from DB //%%% for now just return "not found" status (our simulated DB is empty) sta = DB_NotFound; // done return sta; } - (TSyError)endDataRead { [self debugOut:@"endDataRead"]; //%%% todo: get rid of ressources only needed during readNextItemAsKey calls (such as cached list of items etc.) //%%% for now: just ok return LOCERR_OK; } - (TSyError)startDataWrite { [self debugOut:@"startDataWrite"]; //%%% todo: prepare DB for writing //%%% for now: just ok return LOCERR_OK; } - (TSyError)insertItemAsKey:(SettingsKey *)aItemKey parentID:(NSString *)aParentID newItemIdP:(NSString **)aNewItemIdP { TSyError sta = LOCERR_OK; [self debugOut:[NSString stringWithFormat: @"insertItemAsKey: parentID=%@", aParentID ]]; //%%% todo: insert item into DB and return new ID //%%% for now just return DB error (our simulated DB is always empty and can't be written) sta = DB_Error; // done return sta; } #ifdef HAS_FINALIZE_LOCALID // check if insert ID is temporary, and if so return real (persistent) - (TSyError)finalizeLocalID:(NSString **)aLocIDP { [self debugOutExotic:[NSString stringWithFormat: @"finalizeLocalID: tempLocID=%@", *aLocIDP ]]; //%%% todo: check if this is a temporary ID that needs to be finalized // Note: this is for DBs which save all changes at once at endDataWriteWithSuccess // and receive persistent IDs only then. For those, insertItemAsKey can // return temporary items which will be finalized using this call. //%%% for now: no finalisation needed return DB_NoContent; } #endif - (TSyError)updateItemAsKey:(SettingsKey *)aItemKey itemIdP:(NSString **)aItemIdP parentIdP:(NSString **)aParentIdP { TSyError sta = LOCERR_OK; [self debugOut:[NSString stringWithFormat: @"updateItemAsKey: parentID=%@, itemID=%@", *aParentIdP, *aItemIdP ]]; //%%% todo: update item in DB //%%% for now just return DB error (our simulated DB is always empty and can't be written) sta = DB_Error; // done return sta; } - (TSyError)moveItem:(NSString *)aItemID fromParentID:(NSString *)aParentID toNewParent:(NSString *)aNewParentID { [self debugOut:@"moveItem"]; // %%% todo: actually move item to new parent (if possible) return LOCERR_NOTIMP; } - (TSyError)deleteItem:(NSString *)aItemID parentID:(NSString *)aParentID { TSyError sta = LOCERR_OK; [self debugOut:[NSString stringWithFormat: @"deleteItem: parentID=%@, itemID=%@", aParentID, aItemID ]]; //%%% todo: delete item from DB //%%% for now just return DB error (our simulated DB is always empty and can't be written) // done return sta; } - (TSyError)deleteSyncSet { TSyError sta = LOCERR_OK; [self debugOut:@"deleteAllItems"]; //%%% todo:delete all items from the DB which belong to the sync set (=usually all, unless we have filters) // done return sta; } - (TSyError)endDataWriteWithSuccess:(BOOL)aSuccess andNewToken:(NSString **)aNewTokenP { TSyError sta = LOCERR_OK; [self debugOut:[NSString stringWithFormat:@"endDataWriteWithSuccess:%d", aSuccess]]; //%%% todo: if needed, commit changes to DB //%%% todo: THEN create "this sync" token (after all changes are saved) //%%% for now we just return the absolute timestamp of now sInt64 ll = CFAbsoluteTimeGetCurrent(); *aNewTokenP = [NSString stringWithFormat:@"%lld",ll]; // done return sta; } @end // SamplePluginDB4 /* eof */libsynthesis-3.4.0.47.1/src/sysync_SDK/dbplugin_cocoa_sample/target_options.h000066400000000000000000000011561226375725500272120ustar00rootroot00000000000000// Sysync related target options for sample database adaptor plugin #ifndef TARGET_OPTIONS_H #define TARGET_OPTIONS_H // define platform // - we are on MACOSX (but on the mobile variant of it) #define MACOSX 1 #define MOBOSX 1 // this is not the SyncML engine itself #undef SYSYNC_ENGINE // Sysync related debug #define SYDEBUG 2 // general app debug #if DEBUG // general app debug #define CONSOLEDBG 1 #else // no output to console, please #undef CONSOLEDBG #endif // this can be #undef'ed when the DB does not need finalizing local IDs #define HAS_FINALIZE_LOCALID 1 #endif // TARGET_OPTIONS_H /* eof */ libsynthesis-3.4.0.47.1/src/sysync_SDK/ios_syncclient_app_sample/000077500000000000000000000000001226375725500247125ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/sysync_SDK/ios_syncclient_app_sample/AppDelegate.h000066400000000000000000000023231226375725500272360ustar00rootroot00000000000000// // AppDelegate.h // ios_syncclient_app_sample // // Created by Lukas Zeller on 2011/09/16. // Copyright (c) 2011 plan44.ch. All rights reserved. // #import // This defines the datatype ("SyncML target") to be used in the app. // This simple sample app just synchronizes a single "target", but libsynthesis // supports synchronizing more than one datatype/target in one sync session // (needs more elaborate UI to allow configuring multiple target DBs and // providing status display for different data types) // // Note: - For the commercial plugins accessing the iOS native PIM databases, the sample configuration // uses the following IDs: // ID 1001 = iOS Address book (using ABAdressbook API) // ID 1003 = iOS Calendar (using EkEventKit API) // - The opensource sample app which stores data in TAB separated text files uses: // ID 2001 = text file based contacts // ID 2002 = text file based calendar #define SYNCML_TARGET_DBID 2001 @class MainViewController; @interface AppDelegate : UIResponder @property (strong, nonatomic) UIWindow *window; @property (strong, nonatomic) MainViewController *mainViewController; @end libsynthesis-3.4.0.47.1/src/sysync_SDK/ios_syncclient_app_sample/AppDelegate.m000066400000000000000000000053711226375725500272510ustar00rootroot00000000000000// // AppDelegate.m // ios_syncclient_app_sample // // Created by Lukas Zeller on 2011/09/16. // Copyright (c) 2011 plan44.ch. All rights reserved. // #import "AppDelegate.h" #import "MainViewController.h" @implementation AppDelegate @synthesize window = _window; @synthesize mainViewController = _mainViewController; - (void)dealloc { [_window release]; [_mainViewController release]; [super dealloc]; } - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; // Override point for customization after application launch. if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { self.mainViewController = [[[MainViewController alloc] initWithNibName:@"MainViewController_iPhone" bundle:nil] autorelease]; } else { self.mainViewController = [[[MainViewController alloc] initWithNibName:@"MainViewController_iPad" bundle:nil] autorelease]; } self.window.rootViewController = self.mainViewController; [self.window makeKeyAndVisible]; return YES; } - (void)applicationWillResignActive:(UIApplication *)application { /* Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. */ } - (void)applicationDidEnterBackground:(UIApplication *)application { /* Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. */ } - (void)applicationWillEnterForeground:(UIApplication *)application { /* Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. */ } - (void)applicationDidBecomeActive:(UIApplication *)application { /* Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. */ } - (void)applicationWillTerminate:(UIApplication *)application { /* Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. */ } @end libsynthesis-3.4.0.47.1/src/sysync_SDK/ios_syncclient_app_sample/FlipsideViewController.h000066400000000000000000000017401226375725500315230ustar00rootroot00000000000000// // FlipsideViewController.h // ios_syncclient_app_sample // // Created by Lukas Zeller on 2011/09/16. // Copyright (c) 2011 plan44.ch. All rights reserved. // #import #import "SyncMLClient.h" @class FlipsideViewController; @protocol FlipsideViewControllerDelegate - (void)flipsideViewControllerDidFinish:(FlipsideViewController *)controller; @end @interface FlipsideViewController : UIViewController { NSArray *syncModes; } @property (assign, nonatomic) SyncMLClient *syncmlClient; @property (assign, nonatomic) IBOutlet id delegate; @property (retain, nonatomic) IBOutlet UITextField *serverURLfield; @property (retain, nonatomic) IBOutlet UITextField *serverUserField; @property (retain, nonatomic) IBOutlet UITextField *serverPasswordField; @property (retain, nonatomic) IBOutlet UITextField *datastorePathField; @property (retain, nonatomic) IBOutlet UIPickerView *datastoreSyncMode; - (IBAction)done:(id)sender; @end libsynthesis-3.4.0.47.1/src/sysync_SDK/ios_syncclient_app_sample/FlipsideViewController.m000066400000000000000000000261311226375725500315310ustar00rootroot00000000000000// // FlipsideViewController.m // ios_syncclient_app_sample // // Created by Lukas Zeller on 2011/09/16. // Copyright (c) 2011 plan44.ch. All rights reserved. // #import "FlipsideViewController.h" #import "ZKeyChainWrapper.h" #import "AppDelegate.h" @implementation FlipsideViewController @synthesize delegate = _delegate; @synthesize syncmlClient = _syncmlClient; @synthesize serverURLfield; @synthesize serverUserField; @synthesize serverPasswordField; @synthesize datastorePathField; @synthesize datastoreSyncMode; - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { self.contentSizeForViewInPopover = CGSizeMake(320.0, 480.0); } return self; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Release any cached data, images, etc that aren't in use. } #pragma mark - View lifecycle - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. // - initialize picker contents array with the 6 sync modes available syncModes = [[NSArray alloc] initWithObjects: @"Normal", @"Slow", @"Update device", @"Reload Device", @"Update Server", @"Reload Server", nil ]; } - (void)viewDidUnload { [syncModes release]; syncModes = nil; [self setServerURLfield:nil]; [self setServerUserField:nil]; [self setServerPasswordField:nil]; [self setDatastorePathField:nil]; [self setDatastoreSyncMode:nil]; [super viewDidUnload]; } - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; } - (void)viewDidDisappear:(BOOL)animated { [super viewDidDisappear:animated]; } - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { // Return YES for supported orientations if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); } else { return YES; } } - (void)dealloc { [serverURLfield release]; [serverUserField release]; [serverPasswordField release]; [datastorePathField release]; [datastoreSyncMode release]; [super dealloc]; } #pragma mark - datasource and delegate methods for sync mode picker view - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView { return 1; // only one component (the sync mode string) } - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component { return [syncModes count]; } - (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component { return [syncModes objectAtIndex:row]; } #pragma mark - text field delegates - (BOOL)textFieldShouldReturn:(UITextField *)textField { // make sure keyboard gets dismissed [textField performSelector:@selector(resignFirstResponder) withObject:nil afterDelay:0]; // otherwise process the return key normally return YES; } //- (BOOL)textFieldShouldEndEditing:(UITextField *)textField //{ // return YES; //} #pragma mark - Actions - (IBAction)done:(id)sender { [self.delegate flipsideViewControllerDidFinish:self]; } #pragma mark - loading and saving SyncML client settings when flip side appears or disappears, resp. - (void)viewWillAppear:(BOOL)animated { // load settings from SyncML engine into controls TSyError sta; // get the first profile's settings. PROFILEID_FIRST_OR_DEFAULT causes a default profile // to be created if none already exists SettingsKey *profileKey = [self.syncmlClient newProfileKeyForID:PROFILEID_FIRST_OR_DEFAULT]; if (profileKey) { // successfully opened profile key. Now we can get the profile-level settings // - Server URL self.serverURLfield.text = [profileKey stringValueByName:"serverURI"]; // - user name self.serverUserField.text = [profileKey stringValueByName:"serverUser"]; // - password. Note that the password can be stored in the profile itself, but this is not recommended // for security reasons (it is stored only obfuscated, not encrypted). // Therefore, we store the password in the keychain, and the SyncMLClient object fetches it // from the keychain when needed while running a session. self.serverPasswordField.text =[[ZKeyChainWrapper sharedKeyChainWrapper] passwordForService:[NSString stringWithFormat:@"SyncMLProfile.%d",[profileKey keyID]] account:@"SyncMLPassword" error:NULL ]; // Now get the per-datastore settings. In this sample, we only have one single datastore. // The datastores are identified by their , which is defined in the the // ios_syncclient_app_sample.xml config file. // For this app, the actual dbtypeid numeric value is defined as SYNCML_TARGET_DBID in AppDelegate.h // - first open the targets container (a "target" represents settings for one datastore) SettingsKey *targetsKey = [profileKey newOpenKeyByPath:"/targets" withMode:0 err:&sta]; if (targetsKey) { // successfully opened targets container // - now open the target we are interested in, by ID ( in the configuration XML file) // Note: See definition of SYNCML_TARGET_DBID in AppDelegate.h for explanation of standard // IDs to use with sample configurations as provided in libsynthesis and plan44.ch // SDKs. SettingsKey *targetKey = [targetsKey newOpenSubKeyByID:SYNCML_TARGET_DBID withMode:0 err:&sta]; if (targetKey) { // successfully opened targets container key. Now we can get the datastore level settings // - the server path for the contacts (defaults to "contacts") self.datastorePathField.text = [targetKey stringValueByName:"remotepath"]; // - the sync mode. This consists of the basic mode (twoway/fromserver/fromclient) plus // a flag with differentiates between slow or normal variant of the basic mode. // // Basic mode Slow end user selection // ------------ ------ ------------------- // two way No Normal // two way Yes Slow // from server No Update device // from server Yes Reload device // from client No Update server // from client Yes Reload server // // - basic mode short syncmode = [targetKey intValueByName:"syncmode"]; // sync mode: 0=twoway, 1=from server only, 2=from client only // - slow sync flag BOOL slowsync = [targetKey intValueByName:"forceslow"]; // YES if user wants to force slow-sync (=reload for one-way mode) // - set current selection in picker [self.datastoreSyncMode selectRow:syncmode*2 + (slowsync ? 1 : 0) inComponent:0 animated:NO]; // close the target key [targetKey release]; } // close the targets container key [targetsKey release]; } // close the current profile [profileKey release]; } [super viewWillAppear:animated]; } - (void)viewWillDisappear:(BOOL)animated { // save settings from controls into SyncML engine TSyError sta; // get the first profile's settings. PROFILEID_FIRST_OR_DEFAULT causes a default profile // to be created if none already exists SettingsKey *profileKey = [self.syncmlClient newProfileKeyForID:PROFILEID_FIRST_OR_DEFAULT]; if (profileKey) { // successfully opened current profile key. Now we can store the profile-level settings // - Server URL [profileKey setStringValueByName:"serverURI" toValue:self.serverURLfield.text]; // - user name [profileKey setStringValueByName:"serverUser" toValue:self.serverUserField.text]; // - password. Note that the password can be stored in the profile itself, but this is not recommended // for security reasons (it is stored only obfuscated, not encrypted). // Therefore, we store the password in the keychain, and the SyncMLClient object fetches it // from the keychain when needed while running a session. [[ZKeyChainWrapper sharedKeyChainWrapper] setPassword:self.serverPasswordField.text forService:[NSString stringWithFormat:@"SyncMLProfile.%d",[profileKey keyID]] account:@"SyncMLPassword" error:NULL ]; // Now save the per-datastore settings. In this sample, we only have one single datastore. // The datastores are identified by their , which is defined in the the // ios_syncclient_app_sample.xml config file. // For this app, the actual dbtypeid numeric value is defined as SYNCML_TARGET_DBID in AppDelegate.h // - first open the targets container (a "target" represents settings for one datastore) SettingsKey *targetsKey = [profileKey newOpenKeyByPath:"/targets" withMode:0 err:&sta]; if (sta==LOCERR_OK) { // successfully opened targets container // - now open the target we are interested in, by ID ( in the configuration XML file) // Note: See definition of SYNCML_TARGET_DBID in AppDelegate.h for explanation of standard // IDs to use with sample configurations as provided in libsynthesis and plan44.ch // SDKs. SettingsKey *targetKey = [targetsKey newOpenSubKeyByID:SYNCML_TARGET_DBID withMode:0 err:&sta]; if (sta==LOCERR_OK) { // successfully opened targets container key. Now we can save the datastore level settings // - always enable sync with our one and only datastore. For SyncML clients supporting multiple datastores, // the enable flag should be presented as a switch to the user to allow synchronizing just // some of the available datastores. [targetKey setIntValueByName:"enabled" toValue:1]; // - the server path for the contacts (defaults to "contacts") [targetKey setStringValueByName:"remotepath" toValue:self.datastorePathField.text]; // - the sync mode. This consists of the basic mode (twoway/fromserver/fromclient) plus // a flag with differentiates between slow or normal variant of the basic mode. // // Basic mode Slow end user selection // - ----------- ------ - ---------------- // 0 two way No 0 Normal // 0 two way Yes 1 Slow // 1 from server No 2 Update device // 1 from server Yes 3 Reload device // 2 from client No 4 Update server // 2 from client Yes 5 Reload server // // - get end user selection short userSyncMode = [self.datastoreSyncMode selectedRowInComponent:0]; // - basic mode [targetKey setIntValueByName:"syncmode" toValue:userSyncMode/2]; // - slow sync flag [targetKey setIntValueByName:"forceslow" toValue:(userSyncMode & 1)!=0]; // odd user selection number means slow-sync (=reload for one-way mode) // close the target key [targetKey release]; } // close the targets container key [targetsKey release]; } // close the current profile [profileKey release]; } [super viewWillDisappear:animated]; } @end libsynthesis-3.4.0.47.1/src/sysync_SDK/ios_syncclient_app_sample/MainViewController.h000066400000000000000000000015771226375725500306600ustar00rootroot00000000000000// // MainViewController.h // ios_syncclient_app_sample // // Created by Lukas Zeller on 2011/09/16. // Copyright (c) 2011 plan44.ch. All rights reserved. // #import "FlipsideViewController.h" #import "SyncMLClient.h" @interface MainViewController : UIViewController { // syncml client SyncMLClient *syncmlClient; } @property (strong, nonatomic) UIPopoverController *flipsidePopoverController; @property (retain, nonatomic) IBOutlet UILabel *targetStatusLabel; @property (retain, nonatomic) IBOutlet UILabel *globalStatusLabel; @property (retain, nonatomic) IBOutlet UIButton *startStopSyncButton; @property (retain, nonatomic) IBOutlet UIActivityIndicatorView *syncActivityIndicator; @property (readonly, nonatomic) SyncMLClient *syncmlClient; - (IBAction)showInfo:(id)sender; - (IBAction)startStopSync:(id)sender; @end libsynthesis-3.4.0.47.1/src/sysync_SDK/ios_syncclient_app_sample/MainViewController.m000066400000000000000000000407251226375725500306630ustar00rootroot00000000000000// // MainViewController.m // ios_syncclient_app_sample // // Created by Lukas Zeller on 2011/09/16. // Copyright (c) 2011 plan44.ch. All rights reserved. // #import "MainViewController.h" #include "AppDelegate.h" @interface MainViewController () // private methods declaration - (void)updateProgressInfo:(NSNotification *)aNotification; - (void)updateStaticStatus; + (NSString *)stringWithErrorText:(TSyError)aSta; + (NSString *)stringWithEventText:(NSDictionary *)aProgressInfoDict andTranspStatus:(TSyError)aTranspStatus; @end @implementation MainViewController @synthesize flipsidePopoverController = _flipsidePopoverController; @synthesize targetStatusLabel = _targetStatusLabel; @synthesize globalStatusLabel = _globalStatusLabel; @synthesize startStopSyncButton = _startStopSyncButton; @synthesize syncActivityIndicator = _syncActivityIndicator; - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Release any cached data, images, etc that aren't in use. } #pragma mark - View lifecycle - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. // - install observer for sync progress [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateProgressInfo:) name:@"SyncMLClientProgress" object:nil ]; } - (void)viewDidUnload { [self setTargetStatusLabel:nil]; [self setGlobalStatusLabel:nil]; [self setStartStopSyncButton:nil]; [self setSyncActivityIndicator:nil]; [syncmlClient release]; syncmlClient = nil; [super viewDidUnload]; // Release any retained subviews of the main view. // e.g. self.myOutlet = nil; } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; } - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; // update the sync static status [self updateStaticStatus]; } - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; } - (void)viewDidDisappear:(BOOL)animated { [super viewDidDisappear:animated]; } - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { // Return YES for supported orientations if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); } else { return YES; } } #pragma mark - Flipside View Controller - (void)flipsideViewControllerDidFinish:(FlipsideViewController *)controller { if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { [self dismissModalViewControllerAnimated:YES]; } else { [self.flipsidePopoverController dismissPopoverAnimated:YES]; } } - (void)dealloc { [_flipsidePopoverController release]; [_syncActivityIndicator release]; [super dealloc]; } - (IBAction)showInfo:(id)sender { if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { FlipsideViewController *controller = [[[FlipsideViewController alloc] initWithNibName:@"FlipsideViewController" bundle:nil] autorelease]; controller.delegate = self; // pass it the SyncMLClient object controller.syncmlClient = self.syncmlClient; controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal; [self presentModalViewController:controller animated:YES]; } else { if (!self.flipsidePopoverController) { FlipsideViewController *controller = [[[FlipsideViewController alloc] initWithNibName:@"FlipsideViewController" bundle:nil] autorelease]; controller.delegate = self; // pass it the SyncMLClient object controller.syncmlClient = self.syncmlClient; self.flipsidePopoverController = [[[UIPopoverController alloc] initWithContentViewController:controller] autorelease]; } if ([self.flipsidePopoverController isPopoverVisible]) { [self.flipsidePopoverController dismissPopoverAnimated:YES]; } else { [self.flipsidePopoverController presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES]; } } } #pragma mark - SyncML client // On-demand creation of SyncML client object - (SyncMLClient *)syncmlClient { if (syncmlClient==nil) { // create syncML client syncmlClient = [[SyncMLClient alloc] initWithClientConfigFile: [[NSBundle mainBundle] pathForResource:@"ios_syncclient_app_sample" ofType:@"xml"] ]; // make main view controller the delegate syncmlClient.delegate = self; } return syncmlClient; } - (IBAction)startStopSync:(id)sender { // if not running - start sync // if running - suspend sync // if suspending - abort sync if (!self.syncmlClient.isRunning) { // not running - start sync // - turn on activity indicator [self.syncActivityIndicator startAnimating]; // - convert start button into suspend button [self.startStopSyncButton setTitle:@"Suspend sync" forState:UIControlStateNormal]; // - initiate sync [self.syncmlClient startWithProfileID:PROFILEID_FIRST inBackgroundThread:NO]; } else { // already running if (!self.syncmlClient.isSuspending) { // not yet suspending, try suspending [self.syncmlClient suspend]; // - convert suspend button into abort button [self.startStopSyncButton setTitle:@"Abort sync" forState:UIControlStateNormal]; } else { // already suspending, abort now [self.syncmlClient stop]; } } } #pragma mark - SyncMLClient delegate methods - (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex { // fatal error, end app process exit(1); } // SyncMLClient delegate method: fatal error occurred - (void)fatalSyncMLError:(NSString *)aErrorMsg syncMLClient:(SyncMLClient *)aSyncMLClient { UIActionSheet *alert = [[UIActionSheet alloc] initWithTitle:[NSString stringWithFormat: @"Fatal error in SyncMLClient: %@", aErrorMsg ] delegate:(id)self cancelButtonTitle:@"Quit" destructiveButtonTitle:nil otherButtonTitles:nil ]; [alert showInView:self.view]; [alert release]; } // SyncMLClient delegate method: opportunity to define additional config vars before XML loading - (void)willInitSyncMLEngine:(SyncEngine *)aSyncEngine { // add setting of SyncML engine configuration variables here. // These will be set before the XML config is loaded TSyError sta; SettingsKey *configVarsKey = [aSyncEngine newOpenKeyByPath:"/configvars" withMode:0 err:&sta]; if (sta==LOCERR_OK) { #if DEBUG // In debug builds, direct XML configuration errors to console (stdout) [configVarsKey setStringValueByName:"conferrpath" toValue:@"console"]; #endif /* %%% enable these if you want a custom model or hardcoded URL // custom devInf model string [configVarsKey setStringValueByName:"custmodel" toValue:@"" CUSTOM_DEVINF_MODEL]; // custom predefined (fixed) URL [configVarsKey setStringValueByName:"serverurl" toValue:@"" CUSTOM_SERVER_URL]; */ } // done with config vars [configVarsKey release]; // if debug build, create the log subdirectory in the sandbox' tmp/, such that // the syncml engine will write detailed HTML logs. The engine checks the presence of // the log directory and disables logging if it is not present. // Note: this has to be in sync with the definition of "logpath" in the XML config #if DEBUG [[NSFileManager defaultManager] createDirectoryAtPath:[NSHomeDirectory() stringByAppendingPathComponent:@"tmp/sysynclogs"] withIntermediateDirectories:NO attributes:nil error:NULL]; #endif } // SyncMLClient delegate method: opportunity to create a default profile, return nil if none created - (SettingsKey *)newDefaultSyncMLProfileIn:(SettingsKey *)aProfilesKey { SettingsKey *profileKey = nil; /* // create new empty profile profileKey = [aProfilesKey newOpenSubKeyByID:KEYVAL_ID_NEW withMode:0 err:&lastStatus]; if (profileKey) { // created, now set some values [profileKey setStringValueByName:"serverURI" toValue:@"http://www.sampleserver.com/syncml" [profileKey setStringValueByName:"serverUser" toValue:@"user" [profileKey setStringValueByName:"serverPassword" toValue:@"supersecretpassword" // .... more setup } */ return profileKey; } // SyncMLClient delegate method: sync has completed - (void)completedSyncMLClientSync:(SyncMLClient *)aSyncMLClient { // Sync done // - turn off activity indicator [self.syncActivityIndicator stopAnimating]; // - button ready for starting next sync [self.startStopSyncButton setTitle:@"Start Sync" forState:UIControlStateNormal]; } #pragma mark - SyncML progress and status display // update static (non-syncing) status display - (void)updateStaticStatus { TSyError sta; // use global status label for "Last Sync" title self.globalStatusLabel.text = @"Last Synchronisation:"; // show the time of last sync of the datastore with ID SYNCML_TARGET_DBID // we need to open the current profile, and find the target with ID SYNCML_TARGET_DBID // (this is the of the datastore as configured in the xml config file) SettingsKey *profileKey = [self.syncmlClient newProfileKeyForID:PROFILEID_FIRST]; if (profileKey) { // successfully opened current profile key // - open the targets container (a "target" represents settings for one datastore) SettingsKey *targetsKey = [profileKey newOpenKeyByPath:"/targets" withMode:0 err:&sta]; if (sta==LOCERR_OK) { // successfully opened targets container // - now open the target we are interested in, which is that for the address book // by its ID 1001 SettingsKey *targetKey = [targetsKey newOpenSubKeyByID:SYNCML_TARGET_DBID withMode:0 err:&sta]; if (sta==LOCERR_OK) { // get the date of last sync NSDate *lastSync = [targetKey dateValueByName:"lastSync"]; // show formatted NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; [formatter setDateStyle:NSDateFormatterMediumStyle]; [formatter setTimeStyle:NSDateFormatterShortStyle]; self.targetStatusLabel.text = (lastSync==nil ? @"Never" : [formatter stringFromDate:lastSync]); [formatter release]; // close the target key [targetKey release]; } // close the targets container key [targetsKey release]; } // close the current profile [profileKey release]; } } - (void)updateProgressInfo:(NSNotification *)aNotification { // get textual message for error, nil if nothing to display for this event NSString *msg = [[self class] stringWithEventText:aNotification.userInfo andTranspStatus:syncmlClient.lastTransportStatus]; // if we got a message, show it if (msg) { // targetID determines which datastore this event is related to // - 0 means global event (no particular datastore) // - other values correspond with the of the datastore as configured in the // xml config file. For this sample implementation, we assume only one datastore // and show all datastore related info in targetStatusLabel if ([[aNotification.userInfo objectForKey:@"targetID"] intValue]!=0) { // event specifically related to a particular datastore, show it in the targetStatusLabel self.targetStatusLabel.text = msg; } else { // otherwise, assume the event is global self.globalStatusLabel.text = msg; } } } // error code as string // See SyncML DS specifications for Error codes 100..599 and syerror.h file for Synthesis SyncML // engine related error codes or refer to the "Error Codes" chapter in the SDK manual + (NSString *)stringWithErrorText:(TSyError)aSta { switch (aSta) { case LOCERR_OK : return @""; // ok case 406 : return @"Feature not supported"; case 401 : case 401+LOCAL_STATUS_CODE: case 407 : case 407+LOCAL_STATUS_CODE: case DB_Forbidden : return @"Access denied"; case DB_NotFound : return @"Server database not found"; case DB_NotFound+ LOCAL_STATUS_CODE : return @"Local database not found"; case DB_NotAllowed : return @"Not allowed"; case DB_Error : return @"Server Database error"; case DB_Error+ LOCAL_STATUS_CODE : return @"Local Database error"; case DB_Full : case DB_Full+ LOCAL_STATUS_CODE : return @"Datastore capacity exceeded"; case LOCERR_BADCONTENT : case LOCERR_PROCESSMSG : return @"Invalid data from server (wrong URL?)"; case LOCERR_NOCFG : return @"Configuration missing or no datastore enabled"; case LOCERR_EXPIRED : return @"License or demo period expired"; case LOCERR_USERABORT : return @"Aborted by user"; case LOCERR_BADREG : return @"License not valid here"; case LOCERR_LIMITED : return @"Limited trial version"; case LOCERR_INCOMPLETE : return @"Sync incomplete"; case LOCERR_OUTOFMEM : return @"Out of memory"; case LOCERR_TOONEW : return @"License too old for this version of the software"; case LOCERR_WRONGPROD : return @"License installed is not valid for this product"; case LOCERR_USERSUSPEND : return @"Suspended by User"; case LOCERR_LOCDBNOTRDY : return @"Local datastore not ready"; case LOCERR_TRANSPFAIL : return @"Network error - check internet connection"; case LOCERR_CERT_INVALID : return @"Invalid SSL Server certificate"; case LOCERR_CERT_EXPIRED : return @"Expired SSL Server certificate"; case LOCERR_BADURL : return @"Bad URL - probably http/https missing"; case LOCERR_SRVNOTFOUND : return @"Server not found - check URL"; default : return [NSString stringWithFormat:@"Error %hd",aSta]; } } + (NSString *)stringWithEventText:(NSDictionary *)aProgressInfoDict andTranspStatus:(TSyError)aTranspStatus { NSString *msg=nil; TSyError sta=LOCERR_OK; // get values from dict int eventtype = [[aProgressInfoDict valueForKey:@"eventtype"] intValue]; int extra1 = [[aProgressInfoDict valueForKey:@"extra1"] intValue]; int extra2 = [[aProgressInfoDict valueForKey:@"extra2"] intValue]; int extra3 = [[aProgressInfoDict valueForKey:@"extra3"] intValue]; switch (eventtype) { // transport-related case PEV_SENDSTART : msg = @"Sending..."; break; case PEV_SENDEND : msg = @"Waiting..."; break; case PEV_RECVSTART : msg = @"Receiving..."; break; case PEV_RECVEND : msg = @"Processing..."; break; case PEV_SESSIONSTART : msg = @"Starting..."; break; case PEV_SUSPENDING : msg = @"Suspending..."; break; case PEV_SESSIONEND : case PEV_SYNCEND : // session ended, probably with error in extra sta = extra1; if (sta==LOCERR_OK) msg = @"Sync successfully completed"; else { if (sta==LOCERR_TRANSPFAIL) sta = aTranspStatus; // use probably more detailed transport failure status msg = [NSString stringWithFormat:@"Sync failed: %@",[MainViewController stringWithErrorText:sta]]; } break; // datastore-related case PEV_PREPARING : msg = [NSString stringWithFormat:@"Checking %d/%d",extra1,extra2]; // preparing (e.g. preflight in some clients), extra1=progress, extra2=total break; case PEV_DELETING : msg = [NSString stringWithFormat:@"Deleting %d/%d",extra1,extra2]; // deleting (zapping datastore), extra1=progress, extra2=total break; case PEV_ALERTED : // datastore alerted (extra1=0 for normal, 1 for slow, 2 for first time slow, extra2=1 for resumed session) if (extra2==1) msg = @"Resumed "; else msg = @""; switch (extra1) { case 0 : msg = [msg stringByAppendingString:@"Normal Sync"]; break; case 1 : msg = [msg stringByAppendingString:@"Slow Sync"]; break; case 2 : msg = [msg stringByAppendingString:@"First Time Slow Sync"]; break; } break; case PEV_ITEMRECEIVED : msg = [NSString stringWithFormat:@"Received %d/%d",extra1,extra2]; // item received, extra1=current item count, extra2=number of expected changes (if >= 0) break; case PEV_ITEMSENT : msg = [NSString stringWithFormat:@"Sent %d/%d",extra1,extra2]; // item sent, extra1=current item count, extra2=number of expected items to be sent (if >=0) break; case PEV_ITEMPROCESSED : msg = [NSString stringWithFormat:@"Added %d, Updated %d, Deleted %d",extra1,extra2,extra3]; // item processed break; } return msg; } @end libsynthesis-3.4.0.47.1/src/sysync_SDK/ios_syncclient_app_sample/READ-ME-iOS_syncclient_sample.txt000066400000000000000000000112731226375725500327550ustar00rootroot00000000000000Sample code for libsynthesis on iOS =================================== This directory contains a fully functional Cocoa touch based iPhone application using libsynthesis for iPhone to implement two-way SyncML synchronisation of contacts and calendar stored in TAB separated text files (using the built-in textdb plugin). Note that plan44.ch licenses commercial plugins for iOS native contacts and calendars, which are not part of libsynthesis. Direct mapping to SQLite3 databases however is part of libsynthesis and can be used to create sync apps without writing DB plugins. See doc/SySync_config_reference.pdf for information about configuration of libsynthesis. Due to the requirement of static linking in iOS, libsynthesis cannot be linked into a iOS app project without also linking another *.a library containing 4 custom plugins (named iphone_dbplugin1..4). The SDK provides a sample project with those 4 (dummy) plugins, which builds such a library (src/dbplugin_cocoa_sample/dbplugin_cocoa_sample_ios.xcodeproj). By adding functionality into the sample_dbplugin1..4.mm/.h files, up to 4 different custom DB backends can be implemented. Please contact plan44.ch for licensing conditions for the native contacts and calendar plugins. SyncML Client sample application -------------------------------- The sample application shows how to interface with the libsynthesis to configure the settings and how to run a sync session. The UI is minimal but fully functional. The "SyncMLClientSample" application is based on the "Utility Application" XCode template which is part of the iPhone OS SDK. It includes libsynthesis and the 4 dummy DB plugins as subprojects. To build and run the SyncMLClientSample iPhone application, take the following steps: 1) Open the "ios_syncclient_app_sample.xcodeproj" XCode project using a recent XCode version with a iOS SDK >4.2 2) Choose the "ios_syncclient_app_sample" target. 3) Set the desired target SDK/Platform. You can build for the simulator or the device. For the device, you need to configure the codesign certificates in the target settings. 4) Build the project to create the "ios_syncclient_app_sample.app" application. 5) Run the app (in the simulator or on a connected debug iOS device. Press the small "i" button to open the settings screen where you can put in a SyncML server URL, login, server path and sync mode. Press "Start Synchronisation" to start a sync session synchronizing the contents of TAB separated text files in the /Documents directory of the app's sandbox to a SyncML server. Linking information ------------------- libsynthesis and the plugins are linked as static libraries (iOS does not allow dylibs). For that, the library projects are included as subprojects into the sample app project. Two settings need to be made to have XCode build and link everything (these are already set up in the sample project, but are important to understand in case you want to use another libsynthesis target or another plugin library) 1) In the app's target settings under "build phases", "target dependencies" need to be defined for the libsynthesis target you want to use and for the plugin library target. 2) Also in the app's target settings, under "build phases", "link binary with libraries" the actual library builds (.a files) need to be selected. When you press "+", the first folder presented is called "workspace" and lists the libraries available. Note: The Debug target build configuration has a GCC_PREPROCESSOR_DEFINITIONS setting DEBUG=1. The DEBUG symbol is used to switch on some extra debug information to the console. Make sure you DONT have DEBUG defined in release builds! The Cocoa wrapper classes for the Sync Engine, Settings Keys, and DB Plugins ---------------------------------------------------------------------------- libsynthesis includes three Objective C wrapper files in the "src/sysync_SDK/sdk_sources_cocoa" which wrap the quite complex libsynthesis C API into easy to use Cocoa objects. The sample project uses the wrapper for the sync engine itself (SyncEngine object, used within the SyncMLClient object), for a sync session (SyncSession object) and for the settings key (SettingsKey object). The SettingsKey object has basic KVC capability so it can be used with UI components which use KVC to address their content (this feature is however not used in the sample app, instead direct accessor methods modelled after the C API of the library are used). The file "dbplugin_cocoa" contains wrapper classes for creating custom database adaptor plugins. The dbplugin_cocoa_sample_ios.xcodeproj project contains a set of 4 dummy DB plugins that can be extended to create real DB plugins. (c) 2011-2012 by plan44.chlibsynthesis-3.4.0.47.1/src/sysync_SDK/ios_syncclient_app_sample/SyncMLClient/000077500000000000000000000000001226375725500272165ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/sysync_SDK/ios_syncclient_app_sample/SyncMLClient/SyncMLClient.h000066400000000000000000000050621226375725500316760ustar00rootroot00000000000000// // SyncMLClient.h // // Created by Lukas Zeller on 2011/02/03. // Copyright 2011 plan44.ch. All rights reserved. // #import #import "SyncEngine.h" #import "ZWebRequest.h" @class SyncMLClient; // Special Profile IDs #define PROFILEID_FIRST -1 // first profile #define PROFILEID_FIRST_OR_DEFAULT -2 // first profile, or newly created default profile if no profile already exists #define PROFILEID_ALL_ENABLED -3 // all profiles enabled for global sync #define PROFILEID_NONE -999 // no profile // custom progress events #define PEV_PROFILEID PEV_CUSTOM_START // extra1=profileID @protocol SyncMLClientDelegate @optional // initialisation - (void)fatalSyncMLError:(NSString *)aErrorMsg syncMLClient:(SyncMLClient *)aSyncMLClient; // report fatal syncml engine error - (void)willInitSyncMLEngine:(SyncEngine *)aSyncEngine; // opportunity to define additional config vars before XML loading - (SettingsKey *)newDefaultSyncMLProfileIn:(SettingsKey *)aProfilesKey; // opportunity to create a default profile, return nil if none created // running syncs - (void)completedSyncMLClientSync:(SyncMLClient *)aSyncMLClient; @end @interface SyncMLClient : ZWebRequest { NSString *clientConfigFile; SyncEngine *syncEngine; TSyError lastStatus; // last status encountered from engine TSyError sessionEndStatus; // end of session status // transport TSyError lastTransportStatus; // last transport status // running sync session SyncSession *syncSession; sInt32 profileSelector; uInt16 stepCmd; BOOL loggingSession; BOOL suspendRequest; BOOL suspendRequested; BOOL abortRequested; BOOL runsInBackgroundThread; BOOL localDataChanged; @private // these need to be kept between startDataExchange and startDataWait memSize syncmlRequestSize; NSString *syncMLURL; // the SyncML URL } @property(readonly) NSString *syncMLURL; @property(readonly) SyncEngine *syncEngine; @property(readonly) TSyError lastStatus; @property(readonly) TSyError lastTransportStatus; @property(readonly) TSyError sessionEndStatus; @property(readonly) BOOL isRunning; @property(readonly) BOOL isSuspending; @property(readonly) BOOL localDataChanged; @property(readonly) BOOL loggingSession; // configure - (id)initWithClientConfigFile:(NSString *)aClientConfigFile; - (SettingsKey *)newProfilesKey; - (SettingsKey *)newProfileKeyForID:(sInt32)aProfileID; - (SettingsKey *)newDefaultProfileKey; // run sync - (BOOL)startWithProfileID:(sInt32)aProfileID inBackgroundThread:(BOOL)aInBackgroundThread; - (void)suspend; - (void)stop; @end // SyncMLClient libsynthesis-3.4.0.47.1/src/sysync_SDK/ios_syncclient_app_sample/SyncMLClient/SyncMLClient.m000066400000000000000000000605761226375725500317160ustar00rootroot00000000000000// // SyncMLClient.m // TodoZ // // Created by Lukas Zeller on 2011/02/03. // Copyright 2011 plan44.ch. All rights reserved. // #import "SyncMLClient.h" #import "ZKeyChainWrapper.h" @interface SyncMLClient () // private methods - (void)fatalError:(NSString *)aErrorMsg; - (void)updateProgressStatus:(TEngineProgressInfo *)aProgressInfoP; @end @implementation SyncMLClient @synthesize lastStatus; @synthesize syncMLURL; @synthesize lastTransportStatus; @synthesize sessionEndStatus; @synthesize localDataChanged; @synthesize loggingSession; - (id)initWithClientConfigFile:(NSString *)aClientConfigFile { if ((self = [super init])) { syncEngine = nil; clientConfigFile = [aClientConfigFile retain]; NSAssert(clientConfigFile, @"SyncMLClient: initWithClientConfigFile: No config file path specified"); syncSession = nil; syncMLURL = nil; localDataChanged = NO; loggingSession = NO; abortRequested = NO; suspendRequest = NO; suspendRequested = NO; runsInBackgroundThread = NO; lastStatus = LOCERR_WRONGUSAGE; lastTransportStatus = LOCERR_WRONGUSAGE; } return self; } - (void)dealloc { [syncSession release]; syncSession=nil; [syncEngine release]; syncEngine=nil; [clientConfigFile release]; clientConfigFile=nil; [syncMLURL release]; syncMLURL=nil; [super dealloc]; // includes stop } #pragma private methods - (void)fatalError:(NSString *)aErrorMsg { DBGNSLOG(@"fatalError: %@",aErrorMsg); if (self.delegate && [self.delegate respondsToSelector:@selector(fatalSyncMLError:syncMLClient:)]) { [self.delegate fatalSyncMLError:aErrorMsg syncMLClient:self]; } } #pragma mark Setting up the SyncML engine // standard configuration of sync engine (before config XML loading) // - calls delegate to add custom config // - can also be derived to add custom config - (TSyError)configSyncEngine:(SyncEngine *)aSyncEngine { TSyError sta; SettingsKey *configVarsKey = [syncEngine newOpenKeyByPath:"/configvars" withMode:0 err:&sta]; if (sta==LOCERR_OK) { // sandbox home path [configVarsKey setStringValueByName:"sandbox" toValue:NSHomeDirectory()]; // pass debug status to config #if DEBUG [configVarsKey setStringValueByName:"debugbuild" toValue:@"1"]; #endif // done with config vars } [configVarsKey release]; // call delegate if (self.delegate && [delegate respondsToSelector:@selector(willInitSyncMLEngine:)]) { [self.delegate willInitSyncMLEngine:syncEngine]; } return sta; } - (SyncEngine *)syncEngine { if (!syncEngine) { // Init SyncML engine lastStatus = LOCERR_OK; // - create the engine syncEngine = [[SyncEngine alloc] initWithLibraryPath:@"dummy_because_statically_linked" andDebugFlags:0 andEntryPointPrefix:@"SySync_" // client entry point ]; DBGNSLOG(@"after SyncEngine init, syncEngine=0x%lX",(unsigned long)(void *)syncEngine); if (syncEngine == nil) { [self fatalError:@"Cannot initialize Sync Engine library as client"]; return nil; } // pre-set some config vars [self configSyncEngine:syncEngine]; // init engine with config lastStatus = [syncEngine initEngineFile:clientConfigFile]; DBGNSLOG(@"initEngineFile:%@ sta=%hd\n",clientConfigFile,lastStatus); if (lastStatus != LOCERR_OK) { if (lastStatus == LOCERR_BADREG) { // unregistered - still allow start-up DBGNSLOG(@"xml config returned LOCERR_BADREG - ignore for now"); } else if (lastStatus == LOCERR_EXPIRED) { // expired - display appropriate message [self fatalError:@"application expired"]; } else { [self fatalError:[NSString stringWithFormat:@"Cannot read XML config - err=%hd\n",lastStatus]]; } } // show some config vars again SettingsKey *configVarsKey = [syncEngine newOpenKeyByPath:"/configvars" withMode:0 err:&lastStatus]; if (lastStatus==LOCERR_OK) { DBGNSLOG(@"logpath = %@\n", [configVarsKey stringValueByName:"logpath"]); } else { DBGNSLOG(@"error opening /configvars, sta=%hd\n",lastStatus); } [configVarsKey release]; } return syncEngine; } #pragma mark configuration management /// create a new default profile (and return the newly created key) - (SettingsKey *)newDefaultProfileKey:(SettingsKey *)aProfilesKey { SettingsKey *profileKey = nil; if (delegate && [delegate respondsToSelector:@selector(newDefaultSyncMLProfileIn:)]) { profileKey = [delegate newDefaultSyncMLProfileIn:aProfilesKey]; } if (!profileKey) { profileKey = [aProfilesKey newOpenSubKeyByID:KEYVAL_ID_NEW_DEFAULT withMode:0 err:&lastStatus]; } return profileKey; } /// create a new profile with default values /// Note: default value are either engine-level or obtained via newDefaultSyncMLProfileIn delegate method - (SettingsKey *)newDefaultProfileKey { SettingsKey *profilesKey = [self newProfilesKey]; SettingsKey *newProfile = [self newDefaultProfileKey:profilesKey]; if (newProfile) [newProfile ownParent:profilesKey]; [profilesKey release]; return newProfile; } - (SettingsKey *)newProfilesKey { return [self.syncEngine newOpenKeyByPath:"/profiles" withMode:0 err:&lastStatus ]; } /// open a key for a given profile. /// @param aProfileID profile to open /// PROFILEID_FIRST=first, /// PROFILEID_FIRST_OR_DEFAULT=first, and create default profile if none exists so far - (SettingsKey *)newProfileKeyForID:(sInt32)aProfileID { // open profiles SettingsKey *profileKey = nil; SettingsKey *profilesKey = [self newProfilesKey]; if (lastStatus==LOCERR_OK) { if (aProfileID>=0) { // specific profile profileKey = [profilesKey newOpenSubKeyByID:aProfileID withMode:0 err:&lastStatus]; } else if (aProfileID==PROFILEID_FIRST || aProfileID==PROFILEID_FIRST_OR_DEFAULT) { // load first profile profileKey = [profilesKey newOpenSubKeyByID:KEYVAL_ID_FIRST withMode:0 err:&lastStatus]; // if no profile at all, create default profile if (lastStatus==DB_NoContent && (aProfileID==PROFILEID_FIRST_OR_DEFAULT)) { profileKey = [self newDefaultProfileKey:profilesKey]; } } // attach container to the returned key, will be closed with it if (profileKey) [profileKey ownParent:profilesKey]; [profilesKey release]; } return profileKey; } #pragma mark running a sync session - (BOOL)isRunning { // when we have a sync session, it is running return syncSession!=nil; } - (BOOL)isSuspending { // running sync session and suspend request pending or processing return self.isRunning && (suspendRequest || suspendRequested); } /// start sync with specified profileID /// @param aProfileID profile to sync /// @return YES if sync could be initiated. - (BOOL)startWithProfileID:(sInt32)aProfileID inBackgroundThread:(BOOL)aInBackgroundThread { if (!self.isRunning) { // start new sync // - check for loggin in the profile SettingsKey *profileKey = [self newProfileKeyForID:aProfileID]; if (profileKey) { // save profileSelector profileSelector = aProfileID; // determine if logging this session loggingSession = ([profileKey intValueByName:"profileFlags"] & PROFILEFLAG_LOGNEXTSYNC)!=0; [profileKey release]; // if so, make sure logging dir exists, as this makes the engine actually creating logs. // Note: for DEBUG builds, always create the logdir #ifndef ALWAYS_KEEP_SYNC_LOGS if (loggingSession) #endif { // - get log path as configured SettingsKey *configVarsKey = [self.syncEngine newOpenKeyByPath:"/configvars" withMode:0 err:&lastStatus]; NSString *logpath = [configVarsKey stringValueByName:"logpath"]; [configVarsKey release]; NSError *nserror; // make sure log directory exists [[NSFileManager defaultManager] createDirectoryAtPath:logpath withIntermediateDirectories:NO attributes:nil error:&nserror]; DBGNSLOG(@"Session will create logs in %@",logpath); } } // - init flags suspendRequest = NO; suspendRequested = NO; localDataChanged = NO; // nothing changed yet // create a new session syncSession = [self.syncEngine newOpenSessionWithSelector:aProfileID andSessionName:"syncMLiOS" err:&lastStatus]; if (lastStatus!=LOCERR_OK) { if (lastStatus==LOCERR_EXPIRED) { [self fatalError:@"Demo library or license has expired"]; } else { [self fatalError:[NSString stringWithFormat:@"Cannot open a sync session handle, error=%d",lastStatus]]; } return NO; // failed } // - initialize stepping state stepCmd = STEPCMD_CLIENTSTART; // - issue pseudo-event TEngineProgressInfo pi; pi.eventtype = PEV_PROFILEID; pi.extra1 = aProfileID; pi.targetID = 0; [self updateProgressStatus:&pi]; // - start sync runsInBackgroundThread = aInBackgroundThread; if (runsInBackgroundThread) { // on a separate thread [self performSelectorInBackground:@selector(syncThreadMain) withObject:nil]; } else { // on main thread [self performSelector:@selector(nextSyncStep) withObject:nil afterDelay:0]; } return YES; // initiated } return NO; // already running, not initiated again } - (void)suspend { if (!suspendRequest) { suspendRequest = YES; // request pending suspendRequested = NO; // not yet proapagated to engine // issue a pseudo early "suspending" event such that we have immediate feedback TEngineProgressInfo pi; pi.eventtype = PEV_SUSPENDING; pi.targetID = 0; [self updateProgressStatus:&pi]; } } - (void)stop { // signal abort to engine abortRequested = YES; // make sure pending network request ends as well [self abortRequest]; } #pragma mark - internal methods for transport handling // called in all cases, on failure as well as on success // on transport level failure, failedWebRequestWithReadStream will be called before - (void)completedWebRequestWithStatus:(CFIndex)aHTTPStatus { // ended network activity [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; // check status if (aHTTPStatus==200) { // pass filled buffer back to engine [syncSession retSyncMLBufferForSend:NO processed:self.answerSize]; // all data received, signal "got data" for next step stepCmd = STEPCMD_GOTDATA; // signal engine that we have received response data } else { // SyncML request failed stepCmd = STEPCMD_TRANSPFAIL; // signal engine that transport failed // see if we need to analyze the HTTP answer code if (lastTransportStatus==LOCERR_OK) { // no details about transport failure yet, try to get some useful info from HTTP response switch (aHTTPStatus) { case 404: lastTransportStatus = LOCERR_SRVNOTFOUND; break; case 401: case 403: lastTransportStatus = LOCERR_AUTHFAIL; break; case ZWEBREQUEST_STATUS_NONE: lastTransportStatus = LOCERR_BADCONTENT; break; // apparently not HTTP case ZWEBREQUEST_STATUS_ABORTED: lastTransportStatus = LOCERR_USERABORT; break; case ZWEBREQUEST_STATUS_NETWORK_ERROR: lastTransportStatus = LOCERR_TRANSPFAIL; break; default: lastTransportStatus = LOCERR_TRANSPFAIL; break; } } } // done with reqest [syncMLURL release]; syncMLURL=nil; // make sure engine gets called next [self performSelector:@selector(nextSyncStep) withObject:nil afterDelay:0]; } // called BEFORE completedWebRequestWithStatus in case there are transport level problems - (void)failedWebRequestWithReadStream:(CFReadStreamRef)aReadStream { CFErrorRef streamErr; streamErr = CFReadStreamCopyError(aReadStream); CFIndex errCode = CFErrorGetCode(streamErr); // now catch some of the distinct error codes to cause better display in the UI switch (errCode) { // CFNetwork case kCFErrorHTTPBadURL : lastTransportStatus = LOCERR_BADURL; break; case kCFHostErrorHostNotFound : lastTransportStatus = LOCERR_SRVNOTFOUND; break; // SSL case kCFURLErrorServerCertificateHasBadDate: case kCFURLErrorServerCertificateNotYetValid: case -9828: // errSSLPeerCertExpired, but SecureTransport.h is missing in SDK. Probably device never returns this, but Simulator does lastTransportStatus = LOCERR_CERT_EXPIRED; break; case kCFURLErrorServerCertificateUntrusted: case kCFURLErrorServerCertificateHasUnknownRoot: case kCFURLErrorSecureConnectionFailed: lastTransportStatus = LOCERR_CERT_INVALID; // invalid cert (or general SSL error) break; default: // catch-all other SSL errors that largely mean invalid certificate // SecureTransport.h is missing in iPhone OS device SDK headers if (errCode<=-9807 && errCode>=-9849) // errSSLXCertChainInvalid..errCode>=errSSLLast (SecureTransport.h is missing in SDK. Probably device never returns these, but Simulator does) lastTransportStatus = LOCERR_CERT_INVALID; // invalid cert (or general SSL error) else lastTransportStatus = LOCERR_TRANSPFAIL; // general network error break; } } // Start SyncML data exchange by setting up SyncML request to server // Note: as request exchange is one operation, actual exchange will start not before startDataWait - (BOOL)startDataExchange { // no transport failure so far lastTransportStatus = LOCERR_OK; // get params from session SettingsKey *sessionKey = [syncSession newOpenSessionKeyWithMode:0 err:&lastStatus]; if (lastStatus!=LOCERR_OK) return false; // error // get URL [syncMLURL release]; syncMLURL = [[sessionKey stringValueByName:"connectURI"] retain]; // get content type self.contentType = [sessionKey stringValueByName:"contenttype"]; // get extra HTTP parameters from profile SettingsKey *profileKey = [sessionKey newOpenKeyByPath:"profile" withMode:0 err:&lastStatus]; if (lastStatus==LOCERR_OK) { // we can access the profile, get extra params if ([profileKey intValueByName:"transpFlags"] & TRANSPFLAG_USEHTTPAUTH) { // Use HTTP auth self.httpUser = [profileKey stringValueByName:"transportUser"]; // get PW from keychain self.httpPassword = [[ZKeyChainWrapper sharedKeyChainWrapper] passwordForService:[NSString stringWithFormat:@"SyncMLProfile.%d",[profileKey keyID]] account:@"transportPassword" error:NULL ]; } else { // do not use HTTP auth self.httpUser = nil; self.httpPassword = nil; } // - use system proxy switch self.useSysProxy = [profileKey intValueByName:"useConnectionProxy"]; // - SSL self.ignoreSSLErrors = [profileKey intValueByName:"transpFlags"] & TRANSPFLAG_SSLIGNORECERTFAIL; // done [profileKey release]; } // close session key [sessionKey release]; // send data to server and expect answer appPointer syncmlRequestData; lastStatus = [syncSession getSyncMLBufferForSend:YES buffer:&syncmlRequestData bufSize:&syncmlRequestSize]; if (lastStatus==LOCERR_OK) { // prepare request [self setRequestBuffer:syncmlRequestData withSize:syncmlRequestSize]; } // Don't start sending yet, first call sync engine again to indicate we have acknowledged the data return lastStatus==LOCERR_OK; } - (BOOL)startDataWait { // send as POST request if ([self sendRequestToURL:self.syncMLURL withHTTPMethod:@"POST"]) { // request initiated // - starting network activity [UIApplication sharedApplication].networkActivityIndicatorVisible = YES; // started ok lastStatus=LOCERR_OK; } else { // failed starting request lastStatus=LOCERR_TRANSPFAIL; // failed } // anyway, release SyncML request buffer [syncSession retSyncMLBufferForSend:YES processed:syncmlRequestSize]; // prepare answer buffer if (lastStatus==LOCERR_OK) { // get the buffer to put SyncML response into appPointer syncmlAnswerData; // buffer pointer (received from SyncML engine) memSize syncmlAnswerMax; // size of buffer lastStatus = [syncSession getSyncMLBufferForSend:NO buffer:&syncmlAnswerData bufSize:&syncmlAnswerMax]; if (lastStatus==LOCERR_OK) { [self setAnswerBuffer:syncmlAnswerData withSize:syncmlAnswerMax]; } } // in case of successful start, completedWebRequestWithStatus will continue execution of sync session return lastStatus==LOCERR_OK; } # pragma mark internal methods for running sync - (void)sendAndReleaseProgressDict:(NSDictionary *)aDict { [[NSNotificationCenter defaultCenter] postNotificationName:@"SyncMLClientProgress" // the name object:self // the sender userInfo:aDict ]; // done [aDict release]; } // report progress - (void)updateProgressStatus:(TEngineProgressInfo *)aProgressInfoP { // Show status to console when compiled with DEBUG=1 defined DBGNSLOG( @"*** Got SyncML Client progress Info: eventtype=%hd, targetid=%ld, extra1=%ld, extra2=%ld, extra3=%ld\n", aProgressInfoP->eventtype, (long int)aProgressInfoP->targetID, aProgressInfoP->extra1, aProgressInfoP->extra2, aProgressInfoP->extra3 ); // check for event that means local data has changed if (aProgressInfoP->eventtype==PEV_ITEMRECEIVED || aProgressInfoP->eventtype==PEV_DELETING) localDataChanged = YES; // check for event that delivers session status if (aProgressInfoP->eventtype==PEV_SESSIONEND) sessionEndStatus = aProgressInfoP->extra1; // make dict NSDictionary *dict = [[NSDictionary alloc] initWithObjectsAndKeys: [NSNumber numberWithInt:aProgressInfoP->eventtype], @"eventtype", [NSNumber numberWithInt:aProgressInfoP->targetID], @"targetID", [NSNumber numberWithInt:aProgressInfoP->extra1], @"extra1", [NSNumber numberWithInt:aProgressInfoP->extra2], @"extra2", [NSNumber numberWithInt:aProgressInfoP->extra3], @"extra3", nil ]; // deliver to main thread if (runsInBackgroundThread) { // execute progress notification on the main thread [self performSelectorOnMainThread:@selector(sendAndReleaseProgressDict:) withObject:dict waitUntilDone:YES]; } else { // we are on the main thread, directly send [self sendAndReleaseProgressDict:dict]; } } - (void)notifyDelegateOfEndOfSync { if (delegate && [delegate respondsToSelector:@selector(completedSyncMLClientSync:)]) { [delegate completedSyncMLClientSync:self]; } } // execute next step of a sync session - (BOOL)nextSyncStep { TEngineProgressInfo progressInfo; TSyError sta; BOOL scheduleNextStepNow = YES; BOOL initSession = stepCmd==STEPCMD_CLIENTSTART || stepCmd==STEPCMD_CLIENTAUTOSTART; // take next step // - first check for suspend or abort, if so, modify step command for next step if (abortRequested) { DBGNSLOG(@"!!! abort request detected - setting stepCmd to STEPCMD_ABORT"); stepCmd = STEPCMD_ABORT; abortRequested = NO; } else if (suspendRequest) { DBGNSLOG(@"!!! suspend request detected - setting stepCmd to STEPCMD_SUSPEND"); stepCmd = STEPCMD_SUSPEND; suspendRequest = NO; suspendRequested = YES; // flag for two step button to issue an abort on second use } DBGNSLOG(@"runSyncStep calling sessionStepWithCmd:%hd",stepCmd); sta = [syncSession sessionStepWithCmd:&stepCmd andProgressInfo:&progressInfo]; DBGNSLOG(@"- sessionStepWithCmd returned stepCmd:%hd sta=%d", stepCmd, sta); if (sta!=LOCERR_OK) { // fatal error, immediately terminate with error DBGNSLOG(@"-> unexpected error %hd while processing session step - discontinue session",sta); } else { // step ran ok, evaluate step command if (initSession) { // Note: the following code can be used to provide the session password on-the-fly // rather than relying on passwords stored in the profile (which is stored obfuscated, // but not hard encrypted). For example, passwords can be stored in the keychain // or requested from the user via a dialog, depending on security needs. // For simplicity of this sample however the password is stored in the profile. // last step was initializing the session, now provide session password from keychain SettingsKey *sessionKey = [syncSession newOpenSessionKeyWithMode:0 err:&sta]; if (sta==LOCERR_OK) { SettingsKey *profileKey = [sessionKey newOpenKeyByPath:"profile" withMode:0 err:&sta]; if (sta==LOCERR_OK) { [sessionKey setStringValueByName:"sessionPassword" toValue: [[ZKeyChainWrapper sharedKeyChainWrapper] passwordForService:[NSString stringWithFormat:@"SyncMLProfile.%d",[profileKey keyID]] account:@"SyncMLPassword" error:NULL ] ]; [profileKey release]; } [sessionKey release]; } } switch (stepCmd) { case STEPCMD_OK: // no progress info, call step again stepCmd = STEPCMD_STEP; break; case STEPCMD_PROGRESS: // new progress info to show [self updateProgressStatus:&progressInfo]; stepCmd = STEPCMD_STEP; break; case STEPCMD_ERROR: // error, terminate (should not happen, as status is already checked above) break; case STEPCMD_RESTART: // make sure connection is closed and will be re-opened for next request // %%% Nop at this time as we don't keep the connection anyway in this simplified sample stepCmd = STEPCMD_STEP; break; case STEPCMD_SENDDATA: // send data to remote if (![self startDataExchange]) stepCmd = STEPCMD_TRANSPFAIL; else stepCmd = STEPCMD_SENTDATA; // signal engine that we have sent the request data break; case STEPCMD_NEEDDATA: // initiate receiving data if ([self startDataWait]) { // start waiting initiated - let runloop notify us when complete scheduleNextStepNow = NO; // end of receiving data will restart the timer } else stepCmd = STEPCMD_TRANSPFAIL; // failure break; } // switch stepcmd } // check for end of session if (stepCmd==STEPCMD_DONE || stepCmd==STEPCMD_ERROR) { // done with session DBGNSLOG(@"SyncML Session terminated with stepCmd:%hd, sessionEndStatus=%hd",stepCmd,sessionEndStatus); // release session [syncSession release]; syncSession = nil; // reset logging flag if we did log if (loggingSession) { SettingsKey *profileKey = [self newProfileKeyForID:profileSelector]; if (profileKey) { // reset log session flag in profile uInt32 profileFlags = [profileKey intValueByName:"profileFlags"]; [profileKey setIntValueByName:"profileFlags" toValue:profileFlags & ~PROFILEFLAG_LOGNEXTSYNC]; [profileKey release]; DBGNSLOG(@"Session was logging, reset log-next-sync flag in profile now"); } } // done if (runsInBackgroundThread) { // just clear the background running flag, this will exit the background thread runsInBackgroundThread = NO; // stop the current runloop CFRunLoopStop(CFRunLoopGetCurrent()); } else { // directly inform delegate if requested [self notifyDelegateOfEndOfSync]; } return NO; // no next step } else if (scheduleNextStepNow) { // continues, let runloop issue next step shortly [self performSelector:@selector(nextSyncStep) withObject:nil afterDelay:0]; } return YES; // next step scheduled directly or will be issued by network callback later } // nextSyncStep #pragma mark - support for running sync on a background thread - (void)syncThreadMain { if (runsInBackgroundThread) { // set up autorelease pool NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // Top-level pool // init a run loop NSRunLoop* myRunLoop = [NSRunLoop currentRunLoop]; // runloop is created on demand if it does not yet exist // add a timer source to fire the next sync step [self performSelector:@selector(nextSyncStep) withObject:nil afterDelay:0]; // now run the loop do { // Start the run loop for 10 seconds max, but return after each source is handled. SInt32 result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 10, YES); // If a source explicitly stopped the run loop, or if there are no // sources or timers, go ahead and exit. if ((result == kCFRunLoopRunStopped) || (result == kCFRunLoopRunFinished)) { runsInBackgroundThread = NO; // done } } while (runsInBackgroundThread); // done with the thread [pool release]; } // have delegate informed on main thread [self performSelectorOnMainThread:@selector(notifyDelegateOfEndOfSync) withObject:nil waitUntilDone:YES]; } @end // SyncMLClient libsynthesis-3.4.0.47.1/src/sysync_SDK/ios_syncclient_app_sample/SyncMLClient/ZKeyChainWrapper.h000066400000000000000000000026021226375725500325550ustar00rootroot00000000000000// // ZKeyChainWrapper.h // // Created by Lukas Zeller on 2011/08/16. // Copyright 2011 plan44.ch. All rights reserved. // #import #import #import #if TARGET_IPHONE_SIMULATOR && __IPHONE_OS_VERSION_MAX_ALLOWED < 30000 #error "requires iOS 3.0 or later for testing on simulator (but works on iPhoneOS 2.x devices)" #endif enum { kZKeyChainWrapperErrorBadArguments = -1001, kZKeyChainWrapperErrorNoPassword = -1002 }; extern NSString* const kZKeyChainWrapperErrorDomain; @interface ZKeyChainWrapper : NSObject { NSString *servicePrefix; } /// returns a shared instance of the keyChain wrapper using the bundle identifier /// (plus a dot) as a prefix to service and account strings + (ZKeyChainWrapper *)sharedKeyChainWrapper; /// create a keychain wrapper with a custom service prefix (can be nil to have none) - (id)initWithServicePrefix:(NSString *)aServicePrefix; /// access the passwords - (NSString *)passwordOrEmptyForService:(NSString *)service account:(NSString *)account; - (NSString *)passwordForService:(NSString *)service account:(NSString *)account error:(NSError **)error; - (BOOL)removePasswordForService:(NSString *)service account:(NSString *)account error:(NSError **)error; - (BOOL)setPassword:(NSString *)password forService:(NSString *)service account:(NSString *)account error:(NSError **)error; @end libsynthesis-3.4.0.47.1/src/sysync_SDK/ios_syncclient_app_sample/SyncMLClient/ZKeyChainWrapper.m000066400000000000000000000110551226375725500325640ustar00rootroot00000000000000// // ZKeyChainWrapper.m // // Created by Lukas Zeller on 2011/08/16. // Copyright 2011 plan44.ch. All rights reserved. // #import "ZKeyChainWrapper.h" @implementation ZKeyChainWrapper static ZKeyChainWrapper *sharedKeyChainWrapper = nil; NSString* const kZKeyChainWrapperErrorDomain = @"ch.plan44.ZKeyChainWrapper"; - (id)initWithServicePrefix:(NSString *)aServicePrefix { if ((self = [super init])) { servicePrefix = [aServicePrefix retain]; } return self; } - (void)dealloc { [servicePrefix release]; [super dealloc]; } + (ZKeyChainWrapper *)sharedKeyChainWrapper { if (!sharedKeyChainWrapper) { sharedKeyChainWrapper = [[self alloc] initWithServicePrefix: [[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"] stringByAppendingString:@"."] ]; } return sharedKeyChainWrapper; } // Most useful info about keychain on iOS so far: // http://useyourloaf.com/blog/2010/4/28/keychain-duplicate-item-when-adding-password.html // Main point is that Apple sample is wrong - what constitues the unique key is account & service, not AttrGeneric - (NSMutableDictionary *)keychainQueryForService:(NSString *)service account:(NSString *)account { NSString *uniqueService = [servicePrefix stringByAppendingString:service]; NSMutableDictionary *query = [NSMutableDictionary dictionaryWithObjectsAndKeys: (id)kSecClassGenericPassword, (id)kSecClass, // class is "generic password" [uniqueService dataUsingEncoding:NSUTF8StringEncoding], (id)kSecAttrGeneric, // use service as generic attr as well, must be NSData! account, (id)kSecAttrAccount, uniqueService, (id)kSecAttrService, nil ]; return query; } - (NSString *)passwordOrEmptyForService:(NSString *)service account:(NSString *)account { NSString *result = [self passwordForService:service account:account error:NULL]; if (!result) result = @""; return result; } - (NSString *)passwordForService:(NSString *)service account:(NSString *)account error:(NSError **)error { OSStatus status = kZKeyChainWrapperErrorBadArguments; NSString *result = nil; if ([service length]>0 && [account length]>0) { CFDataRef passwordData = NULL; // get the basic query data NSMutableDictionary *keychainQuery = [self keychainQueryForService:service account:account]; // add specifics for finding a entry [keychainQuery setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData]; // return password data (rather than all attributes with kSecReturnAttributes=YES) [keychainQuery setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit]; // only one in case of multiples // issue query status = SecItemCopyMatching( (CFDictionaryRef)keychainQuery, (CFTypeRef *)&passwordData ); if (status==noErr && [(NSData *)passwordData length]>0) { // we got a password result = [[[NSString alloc] initWithData:(NSData *)passwordData encoding:NSUTF8StringEncoding ] autorelease]; } if (passwordData!=NULL) { CFRelease(passwordData); } } if (status!=noErr && error!=NULL) { *error = [NSError errorWithDomain:kZKeyChainWrapperErrorDomain code:status userInfo:nil]; } return result; } - (BOOL)removePasswordForService:(NSString *)service account:(NSString *)account error:(NSError **)error { OSStatus status = kZKeyChainWrapperErrorBadArguments; if ([service length]>0 && [account length]>0) { NSMutableDictionary *keychainQuery = [self keychainQueryForService:service account:account]; status = SecItemDelete((CFDictionaryRef)keychainQuery); } if (status!=noErr && error!=NULL) { *error = [NSError errorWithDomain:kZKeyChainWrapperErrorDomain code:status userInfo:nil]; } return status==noErr; } - (BOOL)setPassword:(NSString *)password forService:(NSString *)service account:(NSString *)account error:(NSError **)error { OSStatus status = kZKeyChainWrapperErrorBadArguments; if ([service length]>0 && [account length]>0) { // remove old version first [self removePasswordForService:service account:account error:nil]; // now add new version if ([password length]>0) { NSMutableDictionary *keychainQuery = [self keychainQueryForService:service account:account]; NSData *passwordData = [password dataUsingEncoding:NSUTF8StringEncoding]; [keychainQuery setObject:passwordData forKey:(id)kSecValueData]; status = SecItemAdd((CFDictionaryRef)keychainQuery, NULL); } } if (status!=noErr && error!=NULL) { *error = [NSError errorWithDomain:kZKeyChainWrapperErrorDomain code:status userInfo:nil]; } return status==noErr; } @endlibsynthesis-3.4.0.47.1/src/sysync_SDK/ios_syncclient_app_sample/SyncMLClient/ZWebRequest.h000066400000000000000000000044261226375725500316150ustar00rootroot00000000000000// // ZWebRequest.m // // Created by Lukas Zeller on 2011/02/03. // Copyright (c) 2011 by plan44.ch // #import #import // Some pseudo HTTP-errors #define ZWEBREQUEST_STATUS_NONE 0 // no HTTP status received, but otherwise request ok #define ZWEBREQUEST_STATUS_ABORTED 29999 // aborted request #define ZWEBREQUEST_STATUS_NETWORK_ERROR 29998 // network level error occurred @class ZWebRequest; @protocol ZWebRequestDelegate @optional - (void)completedWebRequest:(ZWebRequest *)aWebRequest withStatus:(UInt16)aHTTPStatus; - (void)failedWebRequest:(ZWebRequest *)aWebRequest withReadStream:(CFReadStreamRef)aReadStreamRef; @end @interface ZWebRequest : NSObject { // properties NSString *httpUser; NSString *httpPassword; NSString *contentType; NSData *requestData; id delegate; BOOL ignoreSSLErrors; BOOL useSysProxy; // internal CFHTTPMessageRef webRequest; CFHTTPAuthenticationRef httpAuthentication; CFDictionaryRef httpCredentials; CFReadStreamRef responseStream; BOOL isSSL; // answer NSMutableData *answerData; BOOL answerBufferExternal; UInt8 *answerBufferP; CFIndex answerBufferSize; CFIndex answerSize; CFIndex answerMaxSize; } @property(nonatomic,retain) NSString *httpUser; @property(nonatomic,retain) NSString *httpPassword; @property(nonatomic,assign) id delegate; @property(nonatomic,retain) NSData *requestData; @property(nonatomic,retain) NSString *contentType; @property(nonatomic,assign) BOOL ignoreSSLErrors; @property(nonatomic,assign) BOOL useSysProxy; // answer @property(nonatomic,readonly) CFIndex answerMaxSize; @property(nonatomic,readonly) CFIndex answerSize; @property(nonatomic,readonly) NSMutableData *answerData; @property(nonatomic,readonly) UInt8 *answerBufferP; @property(nonatomic,readonly) CFIndex answerBufferSize; - (id)init; - (void)setRequestString:(NSString *)aString; - (void)setRequestCString:(const char *)aCString; - (void)setRequestBuffer:(UInt8 *)aBuf withSize:(CFIndex)aSize; - (void)setAnswerBuffer:(UInt8 *)aBuf withSize:(CFIndex)aSize; - (void)setAnswerMaxSize:(CFIndex)aSize; - (BOOL)sendRequestToURL:(NSString *)aURL withHTTPMethod:(NSString *)aMethod; - (BOOL)sendDataToWebDAVURL:(NSString *)aURL; - (BOOL)sendRequest; - (void)abortRequest; @end // ZWebRequest libsynthesis-3.4.0.47.1/src/sysync_SDK/ios_syncclient_app_sample/SyncMLClient/ZWebRequest.m000066400000000000000000000345211226375725500316210ustar00rootroot00000000000000// // ZWebRequest.m // // Created by Lukas Zeller on 2011/02/03. // Copyright (c) 2011 by plan44.ch // #import "ZWebRequest.h" @interface ZWebRequest () // private methods - (void)cleanRequest; - (void)releaseAnswerBuffer; @end // private functions void responseClientCallBack( CFReadStreamRef aReadStream, CFStreamEventType aEventType, void *aClientCallBackInfo ); @implementation ZWebRequest @synthesize httpUser; @synthesize httpPassword; @synthesize delegate; @synthesize requestData; @synthesize contentType; @synthesize ignoreSSLErrors; @synthesize useSysProxy; // answer @synthesize answerData; @synthesize answerSize, answerMaxSize; @synthesize answerBufferP, answerBufferSize; - (id)init { if ((self = [super init])) { httpUser = nil; httpPassword = nil; requestData = nil; contentType = nil; ignoreSSLErrors = NO; useSysProxy = YES; httpCredentials = NULL; httpAuthentication = NULL; webRequest = NULL; responseStream = NULL; isSSL = NO; // answer answerData = nil; answerMaxSize = 0; // no answer expected answerBufferP = NULL; answerBufferSize = 0; answerSize = 0; answerBufferExternal = NO; } return self; } - (void)dealloc { [self releaseAnswerBuffer]; [self cleanRequest]; [httpUser release], httpUser = nil; [httpPassword release], httpPassword = nil; [requestData release], requestData = nil; [contentType release], contentType = nil; delegate = nil; [super dealloc]; } - (void)cleanRequest { if (responseStream) { CFRelease(responseStream); responseStream = NULL; } if (httpAuthentication) { CFRelease(httpAuthentication); httpAuthentication = NULL; } if (httpCredentials) { CFRelease(httpCredentials); httpCredentials = NULL; } if (webRequest) { CFRelease(webRequest); webRequest = NULL; } } - (void)setRequestCString:(const char *)aCString; { if (!aCString) aCString = ""; self.requestData = [[NSData alloc] initWithBytes:(const void *)aCString length:strlen(aCString)]; } - (void)setRequestString:(NSString *)aString { if (!aString) aString = @""; [self setRequestCString:[aString UTF8String]]; } - (void)setRequestBuffer:(UInt8 *)aBuf withSize:(CFIndex)aSize { // contents of buffer is owned by caller, but NSData is not self.requestData = [[NSData alloc] initWithBytesNoCopy:aBuf length:aSize]; } - (void)releaseAnswer { // forget the current answer. // - if we have a buffer, it will be overwritten with the next answer // - if we had a NSData, it will be released answerSize = 0; if (answerData) { [answerData release]; answerData = nil; } } - (void)releaseAnswerBuffer { [self releaseAnswer]; if (!answerBufferExternal) { // we own the buffer, release memory if (answerBufferP) free(answerBufferP); } answerBufferP = NULL; answerBufferSize = 0; answerBufferExternal = NO; } // set the maximum answer size. If not using an external buffer, this must always be set - (void)setAnswerMaxSize:(CFIndex)aSize { [self releaseAnswer]; if (answerBufferP && aSize>answerBufferSize) { aSize = answerBufferSize; // limit to buffer size } answerMaxSize = aSize; } // pass an external buffer for the answer, also sets max answer size to buffer size - (void)setAnswerBuffer:(UInt8 *)aBuf withSize:(CFIndex)aSize { [self releaseAnswerBuffer]; answerBufferP = aBuf; answerBufferSize = aSize; answerBufferExternal = YES; [self setAnswerMaxSize:aSize]; // by default, answer size is limited by the buffer size } - (BOOL)sendRequestToURL:(NSString *)aURL withHTTPMethod:(NSString *)aMethod { [self cleanRequest]; // - make URL (and trim URL in case it has whitespace or LF in front or at end) CFURLRef myURL = CFURLCreateWithString(kCFAllocatorDefault, (CFStringRef)[aURL stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]], NULL ); // - check for SSL NSString *scheme = (NSString *)CFURLCopyScheme(myURL); isSSL = [scheme isEqualToString:@"https"]; [scheme release]; // - create the request webRequest = CFHTTPMessageCreateRequest( kCFAllocatorDefault, (CFStringRef)aMethod, myURL, kCFHTTPVersion1_1 ); CFRelease(myURL); if (requestData) CFHTTPMessageSetBody(webRequest, (CFDataRef)requestData); // attach the data // - set the content type header CFHTTPMessageSetHeaderFieldValue(webRequest, CFSTR("Content-Type"), (CFStringRef)contentType); // send request now return [self sendRequest]; } - (BOOL)sendDataToWebDAVURL:(NSString *)aURL { return [self sendRequestToURL:aURL withHTTPMethod:@"PUT"]; } - (void)completedWebRequestWithStatus:(CFIndex)aHTTPStatus { // Base class action: inform delegate // Note: subclasses will probably override this if (delegate && [delegate respondsToSelector:@selector(completedWebRequest:withStatus:)]) { [delegate completedWebRequest:self withStatus:aHTTPStatus]; } } - (void)failedWebRequestWithReadStream:(CFReadStreamRef)aReadStream { // Base class action: inform delegate // Note: subclasses will probably override this if (delegate && [delegate respondsToSelector:@selector(failedWebRequest:withReadStream:)]) { [delegate failedWebRequest:self withReadStream:aReadStream]; } } - (void)responseClientCallBackWithStream:(CFReadStreamRef)aReadStream andEvent:(CFStreamEventType)aEventType { const CFIndex chunkSize = 1000; const CFIndex initialDataCapactiy = chunkSize*3; char buf[chunkSize]; CFIndex bytesRead; // check the status CFHTTPMessageRef myResponse = (CFHTTPMessageRef)CFReadStreamCopyProperty(aReadStream, kCFStreamPropertyHTTPResponseHeader); // if we did't get that far (e.g. server not reachable), we'll get nil for myResponse CFIndex myHTTPStatus = ZWEBREQUEST_STATUS_NONE; if (myResponse) { myHTTPStatus = CFHTTPMessageGetResponseStatusCode(myResponse); if (myHTTPStatus==401) { // missing or wrong authentication if (httpAuthentication) { // wrong auth - fail with myHTTPStatus goto requestDone; } // create appropriate auth from response (challenge) httpAuthentication = CFHTTPAuthenticationCreateFromResponse(NULL, myResponse); // no need to read more from this stream CFReadStreamClose(aReadStream); CFRelease(myResponse); myResponse = nil; // retry with new auth [self sendRequest]; return; } } // no auth failure - normally evaluate events switch (aEventType) { case kCFStreamEventHasBytesAvailable: // three modes: read to buffer passed from the outside, read into NSData, or discard answer completely if (answerBufferP && answerSize0 && !answerBufferP && answerMaxSize>0 && answerSize 1280 11C43 1934 1138.17 567.00 com.apple.InterfaceBuilder.IBCocoaTouchPlugin 931 IBProxyObject IBUIBarButtonItem IBUILabel IBUITextField IBUINavigationBar IBUINavigationItem IBUIPickerView IBUIView com.apple.InterfaceBuilder.IBCocoaTouchPlugin PluginDependencyRecalculationVersion IBFilesOwner IBCocoaTouchFramework IBFirstResponder IBCocoaTouchFramework 274 290 {320, 44} NO NO IBCocoaTouchFramework 1 SyncML Settings IBCocoaTouchFramework 1 0 IBCocoaTouchFramework 292 {{117, 90}, {183, 31}} NO NO IBCocoaTouchFramework 0 3 3 MAA 2 YES 17 1 7 9 IBCocoaTouchFramework 1 12 Helvetica 12 16 292 {{20, 95}, {49, 21}} NO YES NO IBCocoaTouchFramework User 1 MSAxIDEAA 1 10 1 17 Helvetica 17 16 292 {{117, 51}, {183, 31}} NO NO IBCocoaTouchFramework 0 3 3 MAA YES 17 1 3 9 IBCocoaTouchFramework 292 {{20, 56}, {89, 21}} NO YES NO IBCocoaTouchFramework Server URL 1 10 292 {{117, 129}, {183, 31}} NO NO IBCocoaTouchFramework 0 3 3 MAA YES 17 1 9 YES IBCocoaTouchFramework 292 {{20, 134}, {75, 21}} NO YES NO IBCocoaTouchFramework Password 1 10 292 {{20, 219}, {90, 21}} NO YES NO IBCocoaTouchFramework Sync mode: 1 10 292 {{117, 178}, {183, 31}} NO NO IBCocoaTouchFramework 0 3 3 MAA YES 17 1 3 9 IBCocoaTouchFramework 292 {{20, 183}, {88, 21}} NO YES NO IBCocoaTouchFramework Server path 1 10 292 {{0, 244}, {320, 216}} NO YES YES IBCocoaTouchFramework YES {{0, 20}, {320, 460}} 3 MC4yNQA NO 2 IBCocoaTouchFramework view 41 serverURLfield 58 serverUserField 59 serverPasswordField 60 datastorePathField 62 datastoreSyncMode 63 done: 46 delegate 71 delegate 70 delegate 72 delegate 73 dataSource 64 delegate 65 0 -1 File's Owner -2 40 42 43 44 47 48 49 50 51 52 53 54 55 56 FlipsideViewController com.apple.InterfaceBuilder.IBCocoaTouchPlugin UIResponder com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin 73 FlipsideViewController UIViewController id id done: id editingDidEnd: id UITextField UIPickerView id UITextField UITextField UITextField datastorePathField UITextField datastoreSyncMode UIPickerView delegate id serverPasswordField UITextField serverURLfield UITextField serverUserField UITextField IBProjectSource ./Classes/FlipsideViewController.h 0 IBCocoaTouchFramework YES 3 931 libsynthesis-3.4.0.47.1/src/sysync_SDK/ios_syncclient_app_sample/en.lproj/InfoPlist.strings000066400000000000000000000000551226375725500317630ustar00rootroot00000000000000/* Localized versions of Info.plist keys */ MainViewController_iPad.xib000066400000000000000000000470611226375725500336160ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/sysync_SDK/ios_syncclient_app_sample/en.lproj 1280 11C74 1938 1138.23 567.00 com.apple.InterfaceBuilder.IBCocoaTouchPlugin 933 IBUIView IBUIBarButtonItem IBProxyObject IBUILabel IBUIActivityIndicatorView IBUINavigationBar IBUINavigationItem IBUIButton com.apple.InterfaceBuilder.IBCocoaTouchPlugin PluginDependencyRecalculationVersion IBFilesOwner IBIPadFramework IBFirstResponder IBIPadFramework 274 290 {768, 44} NO NO IBIPadFramework 1 Title Info IBIPadFramework 1 IBIPadFramework 292 {{244, 73}, {280, 37}} NO NO IBIPadFramework 0 0 1 Start Synchronisation Start Synchronisation Start Synchronisation Start Synchronisation 1 MSAxIDEAA 3 MAA 1 MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA Helvetica-Bold Helvetica 2 15 Helvetica-Bold 15 16 292 {{20, 144}, {728, 21}} NO YES NO IBIPadFramework globalStatus 3 MQA 1 10 1 17 Helvetica 17 16 292 {{20, 178}, {728, 21}} NO YES NO IBIPadFramework targetStatus 1 10 292 {{20, 593}, {728, 88}} NO YES 5 NO IBIPadFramework U2FtcGxlIFN5bmNNTCBjbGllbnQgYXBwbGljYXRpb24KZGVtb25zdHJhdGluZyB1c2Ugb2YKbGlic3lu dGhlc2lzIG9wZW4gc291cmNlIFN5bmNNTCBsaWJyYXJ5CsKpIDIwMTEgYnkgcGxhbjQ0LmNoA 1 MCAwLjUwMTk2MDgxIDEAA 10 0 0 Helvetica Helvetica 0 14 Helvetica 14 16 -2147483356 {{366, 369}, {37, 37}} _NS:1062 NO IBIPadFramework 0 {{0, 20}, {768, 1004}} 3 MC4yNQA 2 2 IBIPadFramework view 3 globalStatusLabel 17 targetStatusLabel 18 startStopSyncButton 19 syncActivityIndicator 21 infoButton 22 showInfo: 11 startStopSync: 7 16 0 1 -1 File's Owner -2 7 8 10 12 13 14 15 20 MainViewController com.apple.InterfaceBuilder.IBCocoaTouchPlugin UIResponder com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin 22 MainViewController UIViewController id id showInfo: id startStopSync: id UILabel UIButton UIActivityIndicatorView UILabel globalStatusLabel UILabel startStopSyncButton UIButton syncActivityIndicator UIActivityIndicatorView targetStatusLabel UILabel IBProjectSource ./Classes/MainViewController.h 0 IBIPadFramework YES 3 933 MainViewController_iPhone.xib000066400000000000000000000450211226375725500341550ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/sysync_SDK/ios_syncclient_app_sample/en.lproj 1280 11C74 1938 1138.23 567.00 com.apple.InterfaceBuilder.IBCocoaTouchPlugin 933 IBUIButton IBUIActivityIndicatorView IBUIView IBUILabel IBProxyObject com.apple.InterfaceBuilder.IBCocoaTouchPlugin PluginDependencyRecalculationVersion IBFilesOwner IBCocoaTouchFramework IBFirstResponder IBCocoaTouchFramework 274 265 {{282, 421}, {18, 19}} NO NO IBCocoaTouchFramework 0 0 3 YES 1 MSAxIDEAA 1 MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA 3 MAA Helvetica-Bold Helvetica 2 15 Helvetica-Bold 15 16 292 {{20, 20}, {280, 37}} NO NO IBCocoaTouchFramework 0 0 1 Start Synchronisation Start Synchronisation Start Synchronisation Start Synchronisation 1 MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA 292 {{20, 81}, {280, 21}} NO YES NO IBCocoaTouchFramework globalStatus 3 MQA 1 10 1 17 Helvetica 17 16 292 {{20, 115}, {280, 21}} NO YES NO IBCocoaTouchFramework targetStatus 1 10 292 {{20, 327}, {280, 88}} NO YES 5 NO IBCocoaTouchFramework U2FtcGxlIFN5bmNNTCBjbGllbnQgYXBwbGljYXRpb24KZGVtb25zdHJhdGluZyB1c2Ugb2YKbGlic3lu dGhlc2lzIG9wZW4gc291cmNlIFN5bmNNTCBsaWJyYXJ5CsKpIDIwMTEgYnkgcGxhbjQ0LmNoA 1 MCAwLjUwMTk2MDgxIDEAA 10 0 0 Helvetica Helvetica 0 14 Helvetica 14 16 -2147483356 {{142, 211}, {37, 37}} _NS:1030 NO IBCocoaTouchFramework 0 {{0, 20}, {320, 460}} 3 MC4yNQA 2 NO IBCocoaTouchFramework view 35 targetStatusLabel 43 globalStatusLabel 44 startStopSyncButton 46 syncActivityIndicator 51 showInfo: 7 38 startStopSync: 7 49 0 -1 File's Owner -2 34 36 39 40 41 42 50 MainViewController com.apple.InterfaceBuilder.IBCocoaTouchPlugin UIResponder com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin 51 MainViewController UIViewController id id showInfo: id startStopSync: id UILabel UIButton UIActivityIndicatorView UILabel globalStatusLabel UILabel startStopSyncButton UIButton syncActivityIndicator UIActivityIndicatorView targetStatusLabel UILabel IBProjectSource ./Classes/MainViewController.h 0 IBCocoaTouchFramework YES 3 933 ios_syncclient_app_sample-Info.plist000066400000000000000000000026671226375725500340420ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/sysync_SDK/ios_syncclient_app_sample CFBundleDevelopmentRegion en CFBundleDisplayName ${PRODUCT_NAME} CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIconFiles CFBundleIdentifier ch.plan44.syncmlios.${PRODUCT_NAME:rfc1034identifier} CFBundleInfoDictionaryVersion 6.0 CFBundleName ${PRODUCT_NAME} CFBundlePackageType APPL CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1.0 LSRequiresIPhoneOS UISupportedInterfaceOrientations UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UISupportedInterfaceOrientations~ipad UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIFileSharingEnabled ios_syncclient_app_sample-Prefix.pch000066400000000000000000000007341226375725500340140ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/sysync_SDK/ios_syncclient_app_sample// // Prefix header for all source files of the 'ios_syncclient_app_sample' target in the 'ios_syncclient_app_sample' project // #import #ifndef __IPHONE_4_0 #warning "This project uses features only available in iOS SDK 4.0 and later." #endif // iOS always has statically linked libraries, so it must link libsynthesis statically as well #define SYSYNC_ENGINE_STATIC 1 #ifdef __OBJC__ #import #import #endif ios_syncclient_app_sample.xcodeproj/000077500000000000000000000000001226375725500340555ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/sysync_SDK/ios_syncclient_app_sampleproject.pbxproj000066400000000000000000000672061226375725500371440ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/sysync_SDK/ios_syncclient_app_sample/ios_syncclient_app_sample.xcodeproj// !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 46; objects = { /* Begin PBXBuildFile section */ ED46AB23142347BC0057DC96 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ED46AB22142347BC0057DC96 /* UIKit.framework */; }; ED46AB25142347BC0057DC96 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ED46AB24142347BC0057DC96 /* Foundation.framework */; }; ED46AB27142347BC0057DC96 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ED46AB26142347BC0057DC96 /* CoreGraphics.framework */; }; ED46AB2D142347BC0057DC96 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = ED46AB2B142347BC0057DC96 /* InfoPlist.strings */; }; ED46AB2F142347BC0057DC96 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = ED46AB2E142347BC0057DC96 /* main.m */; }; ED46AB33142347BC0057DC96 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = ED46AB32142347BC0057DC96 /* AppDelegate.m */; }; ED46AB36142347BC0057DC96 /* MainViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = ED46AB35142347BC0057DC96 /* MainViewController.m */; }; ED46AB39142347BC0057DC96 /* FlipsideViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = ED46AB38142347BC0057DC96 /* FlipsideViewController.m */; }; ED46AB3C142347BD0057DC96 /* MainViewController_iPhone.xib in Resources */ = {isa = PBXBuildFile; fileRef = ED46AB3A142347BD0057DC96 /* MainViewController_iPhone.xib */; }; ED46AB3F142347BD0057DC96 /* MainViewController_iPad.xib in Resources */ = {isa = PBXBuildFile; fileRef = ED46AB3D142347BD0057DC96 /* MainViewController_iPad.xib */; }; ED46AB42142347BD0057DC96 /* FlipsideViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = ED46AB40142347BD0057DC96 /* FlipsideViewController.xib */; }; ED46AB78142348C10057DC96 /* SyncEngine.m in Sources */ = {isa = PBXBuildFile; fileRef = ED46AB6B142348C10057DC96 /* SyncEngine.m */; }; ED46AB7B142348C10057DC96 /* SyncMLClient.m in Sources */ = {isa = PBXBuildFile; fileRef = ED46AB74142348C10057DC96 /* SyncMLClient.m */; }; ED46AB7C142348C10057DC96 /* ZWebRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = ED46AB76142348C10057DC96 /* ZWebRequest.m */; }; ED46AB8D14237C4E0057DC96 /* ZKeyChainWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = ED46AB8C14237C4E0057DC96 /* ZKeyChainWrapper.m */; }; ED46AB8F142381860057DC96 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ED46AB8E142381860057DC96 /* CFNetwork.framework */; }; ED46AB91142381A50057DC96 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ED46AB90142381A50057DC96 /* Security.framework */; }; ED46AB95142389E40057DC96 /* libstdc++.6.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = ED46AB94142389E40057DC96 /* libstdc++.6.dylib */; }; ED46AB9914238A160057DC96 /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = ED46AB9814238A160057DC96 /* libsqlite3.dylib */; }; EDAF2DCB14A344510054960A /* ios_syncclient_app_sample.xml in Resources */ = {isa = PBXBuildFile; fileRef = EDAF2DCA14A344510054960A /* ios_syncclient_app_sample.xml */; }; EDC0F81E14A343530006710A /* SettingsKey.m in Sources */ = {isa = PBXBuildFile; fileRef = ED46AB67142348C10057DC96 /* SettingsKey.m */; }; EDE01B23151E975200352246 /* libdbplugin_cocoa_sample_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = EDAF2DD414A346400054960A /* libdbplugin_cocoa_sample_ios.a */; }; EDE01B24151E975200352246 /* libsysync_client_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = EDAF2DDE14A3464D0054960A /* libsysync_client_ios.a */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ EDAF2DD314A346400054960A /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = EDAF2DCC14A346400054960A /* dbplugin_cocoa_sample_ios.xcodeproj */; proxyType = 2; remoteGlobalIDString = D2AAC07E0554694100DB518D; remoteInfo = dbplugin_cocoa_sample_ios; }; EDAF2DDD14A3464D0054960A /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = EDAF2DD514A3464D0054960A /* sysync_ios.xcodeproj */; proxyType = 2; remoteGlobalIDString = ED1ECBC31383B0DB00B3DA02; remoteInfo = static_clientEngine_opensource_ios; }; EDAF2DDF14A3464D0054960A /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = EDAF2DD514A3464D0054960A /* sysync_ios.xcodeproj */; proxyType = 2; remoteGlobalIDString = ED1ECBC41383B0DB00B3DA02; remoteInfo = static_combiEngine_opensource_ios; }; EDAF2DE114A3466D0054960A /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = EDAF2DD514A3464D0054960A /* sysync_ios.xcodeproj */; proxyType = 1; remoteGlobalIDString = ED60E7660DF54F870087381E; remoteInfo = static_clientEngine_opensource_ios; }; EDAF2DE314A346720054960A /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = EDAF2DCC14A346400054960A /* dbplugin_cocoa_sample_ios.xcodeproj */; proxyType = 1; remoteGlobalIDString = D2AAC07D0554694100DB518D; remoteInfo = dbplugin_cocoa_sample_ios; }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ ED46AB1E142347BC0057DC96 /* ios_syncclient_app_sample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ios_syncclient_app_sample.app; sourceTree = BUILT_PRODUCTS_DIR; }; ED46AB22142347BC0057DC96 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; ED46AB24142347BC0057DC96 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; ED46AB26142347BC0057DC96 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; ED46AB2C142347BC0057DC96 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; ED46AB2E142347BC0057DC96 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = main.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; ED46AB31142347BC0057DC96 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = AppDelegate.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; ED46AB32142347BC0057DC96 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = AppDelegate.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; ED46AB34142347BC0057DC96 /* MainViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = MainViewController.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; ED46AB35142347BC0057DC96 /* MainViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = MainViewController.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; ED46AB37142347BC0057DC96 /* FlipsideViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = FlipsideViewController.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; ED46AB38142347BC0057DC96 /* FlipsideViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = FlipsideViewController.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; ED46AB3B142347BD0057DC96 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainViewController_iPhone.xib; sourceTree = ""; }; ED46AB3E142347BD0057DC96 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainViewController_iPad.xib; sourceTree = ""; }; ED46AB41142347BD0057DC96 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/FlipsideViewController.xib; sourceTree = ""; }; ED46AB66142348C10057DC96 /* SettingsKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SettingsKey.h; sourceTree = ""; }; ED46AB67142348C10057DC96 /* SettingsKey.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SettingsKey.m; sourceTree = ""; }; ED46AB6A142348C10057DC96 /* SyncEngine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SyncEngine.h; sourceTree = ""; }; ED46AB6B142348C10057DC96 /* SyncEngine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SyncEngine.m; sourceTree = ""; }; ED46AB73142348C10057DC96 /* SyncMLClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SyncMLClient.h; sourceTree = ""; }; ED46AB74142348C10057DC96 /* SyncMLClient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SyncMLClient.m; sourceTree = ""; }; ED46AB75142348C10057DC96 /* ZWebRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZWebRequest.h; sourceTree = ""; }; ED46AB76142348C10057DC96 /* ZWebRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZWebRequest.m; sourceTree = ""; }; ED46AB8314237AC90057DC96 /* engine_defs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = engine_defs.h; sourceTree = ""; }; ED46AB8414237AC90057DC96 /* generic_types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = generic_types.h; sourceTree = ""; }; ED46AB8514237AC90057DC96 /* SDK_util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDK_util.h; sourceTree = ""; }; ED46AB8614237AC90057DC96 /* syerror.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = syerror.h; sourceTree = ""; }; ED46AB8714237AC90057DC96 /* sync_dbapidef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sync_dbapidef.h; sourceTree = ""; }; ED46AB8814237AC90057DC96 /* sync_declarations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sync_declarations.h; sourceTree = ""; }; ED46AB8914237AC90057DC96 /* sync_include.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sync_include.h; sourceTree = ""; }; ED46AB8A14237AC90057DC96 /* target_options.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = target_options.h; sourceTree = ""; }; ED46AB8B14237C4E0057DC96 /* ZKeyChainWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZKeyChainWrapper.h; sourceTree = ""; }; ED46AB8C14237C4E0057DC96 /* ZKeyChainWrapper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZKeyChainWrapper.m; sourceTree = ""; }; ED46AB8E142381860057DC96 /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; ED46AB90142381A50057DC96 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; ED46AB921423896E0057DC96 /* libc++.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libc++.dylib"; path = "usr/lib/libc++.dylib"; sourceTree = SDKROOT; }; ED46AB94142389E40057DC96 /* libstdc++.6.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libstdc++.6.dylib"; path = "usr/lib/libstdc++.6.dylib"; sourceTree = SDKROOT; }; ED46AB9814238A160057DC96 /* libsqlite3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsqlite3.dylib; path = usr/lib/libsqlite3.dylib; sourceTree = SDKROOT; }; EDAF2DCA14A344510054960A /* ios_syncclient_app_sample.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = ios_syncclient_app_sample.xml; sourceTree = ""; }; EDAF2DCC14A346400054960A /* dbplugin_cocoa_sample_ios.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = dbplugin_cocoa_sample_ios.xcodeproj; path = ../dbplugin_cocoa_sample/dbplugin_cocoa_sample_ios.xcodeproj; sourceTree = ""; }; EDAF2DD514A3464D0054960A /* sysync_ios.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = sysync_ios.xcodeproj; path = ../../sysync_ios.xcodeproj; sourceTree = ""; }; EDC0F81C14A342A30006710A /* ios_syncclient_app_sample-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "ios_syncclient_app_sample-Info.plist"; sourceTree = ""; }; EDC0F81D14A342A30006710A /* ios_syncclient_app_sample-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = "ios_syncclient_app_sample-Prefix.pch"; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ ED46AB1B142347BC0057DC96 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( EDE01B23151E975200352246 /* libdbplugin_cocoa_sample_ios.a in Frameworks */, EDE01B24151E975200352246 /* libsysync_client_ios.a in Frameworks */, ED46AB9914238A160057DC96 /* libsqlite3.dylib in Frameworks */, ED46AB95142389E40057DC96 /* libstdc++.6.dylib in Frameworks */, ED46AB91142381A50057DC96 /* Security.framework in Frameworks */, ED46AB8F142381860057DC96 /* CFNetwork.framework in Frameworks */, ED46AB23142347BC0057DC96 /* UIKit.framework in Frameworks */, ED46AB25142347BC0057DC96 /* Foundation.framework in Frameworks */, ED46AB27142347BC0057DC96 /* CoreGraphics.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ ED46AB13142347BC0057DC96 = { isa = PBXGroup; children = ( EDAF2DD514A3464D0054960A /* sysync_ios.xcodeproj */, EDAF2DCC14A346400054960A /* dbplugin_cocoa_sample_ios.xcodeproj */, ED46AB61142348C10057DC96 /* syncmlios_SDK */, ED46AB28142347BC0057DC96 /* ios_syncclient_app_sample */, ED46AB21142347BC0057DC96 /* Frameworks */, ED46AB1F142347BC0057DC96 /* Products */, ); sourceTree = ""; }; ED46AB1F142347BC0057DC96 /* Products */ = { isa = PBXGroup; children = ( ED46AB1E142347BC0057DC96 /* ios_syncclient_app_sample.app */, ); name = Products; sourceTree = ""; }; ED46AB21142347BC0057DC96 /* Frameworks */ = { isa = PBXGroup; children = ( ED46AB9814238A160057DC96 /* libsqlite3.dylib */, ED46AB94142389E40057DC96 /* libstdc++.6.dylib */, ED46AB921423896E0057DC96 /* libc++.dylib */, ED46AB90142381A50057DC96 /* Security.framework */, ED46AB8E142381860057DC96 /* CFNetwork.framework */, ED46AB22142347BC0057DC96 /* UIKit.framework */, ED46AB24142347BC0057DC96 /* Foundation.framework */, ED46AB26142347BC0057DC96 /* CoreGraphics.framework */, ); name = Frameworks; sourceTree = ""; }; ED46AB28142347BC0057DC96 /* ios_syncclient_app_sample */ = { isa = PBXGroup; children = ( EDAF2DCA14A344510054960A /* ios_syncclient_app_sample.xml */, ED46AB31142347BC0057DC96 /* AppDelegate.h */, ED46AB32142347BC0057DC96 /* AppDelegate.m */, ED46AB34142347BC0057DC96 /* MainViewController.h */, ED46AB35142347BC0057DC96 /* MainViewController.m */, ED46AB3A142347BD0057DC96 /* MainViewController_iPhone.xib */, ED46AB3D142347BD0057DC96 /* MainViewController_iPad.xib */, ED46AB37142347BC0057DC96 /* FlipsideViewController.h */, ED46AB38142347BC0057DC96 /* FlipsideViewController.m */, ED46AB40142347BD0057DC96 /* FlipsideViewController.xib */, ED46AB72142348C10057DC96 /* SyncMLClient */, ED46AB29142347BC0057DC96 /* Supporting Files */, ); name = ios_syncclient_app_sample; sourceTree = SOURCE_ROOT; }; ED46AB29142347BC0057DC96 /* Supporting Files */ = { isa = PBXGroup; children = ( EDC0F81C14A342A30006710A /* ios_syncclient_app_sample-Info.plist */, EDC0F81D14A342A30006710A /* ios_syncclient_app_sample-Prefix.pch */, ED46AB2B142347BC0057DC96 /* InfoPlist.strings */, ED46AB2E142347BC0057DC96 /* main.m */, ); name = "Supporting Files"; sourceTree = ""; }; ED46AB61142348C10057DC96 /* syncmlios_SDK */ = { isa = PBXGroup; children = ( ED46AB8214237AC90057DC96 /* Sources */, ED46AB62142348C10057DC96 /* sdk_sources_cocoa */, ); name = syncmlios_SDK; path = ..; sourceTree = ""; }; ED46AB62142348C10057DC96 /* sdk_sources_cocoa */ = { isa = PBXGroup; children = ( ED46AB8A14237AC90057DC96 /* target_options.h */, ED46AB66142348C10057DC96 /* SettingsKey.h */, ED46AB67142348C10057DC96 /* SettingsKey.m */, ED46AB6A142348C10057DC96 /* SyncEngine.h */, ED46AB6B142348C10057DC96 /* SyncEngine.m */, ); path = sdk_sources_cocoa; sourceTree = ""; }; ED46AB72142348C10057DC96 /* SyncMLClient */ = { isa = PBXGroup; children = ( ED46AB8B14237C4E0057DC96 /* ZKeyChainWrapper.h */, ED46AB8C14237C4E0057DC96 /* ZKeyChainWrapper.m */, ED46AB73142348C10057DC96 /* SyncMLClient.h */, ED46AB74142348C10057DC96 /* SyncMLClient.m */, ED46AB75142348C10057DC96 /* ZWebRequest.h */, ED46AB76142348C10057DC96 /* ZWebRequest.m */, ); path = SyncMLClient; sourceTree = ""; }; ED46AB8214237AC90057DC96 /* Sources */ = { isa = PBXGroup; children = ( ED46AB8314237AC90057DC96 /* engine_defs.h */, ED46AB8414237AC90057DC96 /* generic_types.h */, ED46AB8514237AC90057DC96 /* SDK_util.h */, ED46AB8614237AC90057DC96 /* syerror.h */, ED46AB8714237AC90057DC96 /* sync_dbapidef.h */, ED46AB8814237AC90057DC96 /* sync_declarations.h */, ED46AB8914237AC90057DC96 /* sync_include.h */, ); path = Sources; sourceTree = ""; }; EDAF2DCD14A346400054960A /* Products */ = { isa = PBXGroup; children = ( EDAF2DD414A346400054960A /* libdbplugin_cocoa_sample_ios.a */, ); name = Products; sourceTree = ""; }; EDAF2DD614A3464D0054960A /* Products */ = { isa = PBXGroup; children = ( EDAF2DDE14A3464D0054960A /* libsysync_client_ios.a */, EDAF2DE014A3464D0054960A /* libsysync_combi_ios.a */, ); name = Products; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ ED46AB1D142347BC0057DC96 /* ios_syncclient_app_sample */ = { isa = PBXNativeTarget; buildConfigurationList = ED46AB45142347BD0057DC96 /* Build configuration list for PBXNativeTarget "ios_syncclient_app_sample" */; buildPhases = ( ED46AB1A142347BC0057DC96 /* Sources */, ED46AB1B142347BC0057DC96 /* Frameworks */, ED46AB1C142347BC0057DC96 /* Resources */, ); buildRules = ( ); dependencies = ( EDAF2DE414A346720054960A /* PBXTargetDependency */, EDAF2DE214A3466D0054960A /* PBXTargetDependency */, ); name = ios_syncclient_app_sample; productName = SyncMLClientSample; productReference = ED46AB1E142347BC0057DC96 /* ios_syncclient_app_sample.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ ED46AB15142347BC0057DC96 /* Project object */ = { isa = PBXProject; attributes = { LastUpgradeCheck = 0420; }; buildConfigurationList = ED46AB18142347BC0057DC96 /* Build configuration list for PBXProject "ios_syncclient_app_sample" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( en, ); mainGroup = ED46AB13142347BC0057DC96; productRefGroup = ED46AB1F142347BC0057DC96 /* Products */; projectDirPath = ""; projectReferences = ( { ProductGroup = EDAF2DCD14A346400054960A /* Products */; ProjectRef = EDAF2DCC14A346400054960A /* dbplugin_cocoa_sample_ios.xcodeproj */; }, { ProductGroup = EDAF2DD614A3464D0054960A /* Products */; ProjectRef = EDAF2DD514A3464D0054960A /* sysync_ios.xcodeproj */; }, ); projectRoot = ""; targets = ( ED46AB1D142347BC0057DC96 /* ios_syncclient_app_sample */, ); }; /* End PBXProject section */ /* Begin PBXReferenceProxy section */ EDAF2DD414A346400054960A /* libdbplugin_cocoa_sample_ios.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; path = libdbplugin_cocoa_sample_ios.a; remoteRef = EDAF2DD314A346400054960A /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; EDAF2DDE14A3464D0054960A /* libsysync_client_ios.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; path = libsysync_client_ios.a; remoteRef = EDAF2DDD14A3464D0054960A /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; EDAF2DE014A3464D0054960A /* libsysync_combi_ios.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; path = libsysync_combi_ios.a; remoteRef = EDAF2DDF14A3464D0054960A /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXReferenceProxy section */ /* Begin PBXResourcesBuildPhase section */ ED46AB1C142347BC0057DC96 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ED46AB2D142347BC0057DC96 /* InfoPlist.strings in Resources */, ED46AB3C142347BD0057DC96 /* MainViewController_iPhone.xib in Resources */, ED46AB3F142347BD0057DC96 /* MainViewController_iPad.xib in Resources */, ED46AB42142347BD0057DC96 /* FlipsideViewController.xib in Resources */, EDAF2DCB14A344510054960A /* ios_syncclient_app_sample.xml in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ ED46AB1A142347BC0057DC96 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( ED46AB2F142347BC0057DC96 /* main.m in Sources */, ED46AB33142347BC0057DC96 /* AppDelegate.m in Sources */, ED46AB36142347BC0057DC96 /* MainViewController.m in Sources */, ED46AB39142347BC0057DC96 /* FlipsideViewController.m in Sources */, ED46AB78142348C10057DC96 /* SyncEngine.m in Sources */, ED46AB7B142348C10057DC96 /* SyncMLClient.m in Sources */, ED46AB7C142348C10057DC96 /* ZWebRequest.m in Sources */, ED46AB8D14237C4E0057DC96 /* ZKeyChainWrapper.m in Sources */, EDC0F81E14A343530006710A /* SettingsKey.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ EDAF2DE214A3466D0054960A /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = static_clientEngine_opensource_ios; targetProxy = EDAF2DE114A3466D0054960A /* PBXContainerItemProxy */; }; EDAF2DE414A346720054960A /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = dbplugin_cocoa_sample_ios; targetProxy = EDAF2DE314A346720054960A /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ ED46AB2B142347BC0057DC96 /* InfoPlist.strings */ = { isa = PBXVariantGroup; children = ( ED46AB2C142347BC0057DC96 /* en */, ); name = InfoPlist.strings; sourceTree = ""; }; ED46AB3A142347BD0057DC96 /* MainViewController_iPhone.xib */ = { isa = PBXVariantGroup; children = ( ED46AB3B142347BD0057DC96 /* en */, ); name = MainViewController_iPhone.xib; sourceTree = ""; }; ED46AB3D142347BD0057DC96 /* MainViewController_iPad.xib */ = { isa = PBXVariantGroup; children = ( ED46AB3E142347BD0057DC96 /* en */, ); name = MainViewController_iPad.xib; sourceTree = ""; }; ED46AB40142347BD0057DC96 /* FlipsideViewController.xib */ = { isa = PBXVariantGroup; children = ( ED46AB41142347BD0057DC96 /* en */, ); name = FlipsideViewController.xib; sourceTree = ""; }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ ED46AB43142347BD0057DC96 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ARCHS = "$(ARCHS_STANDARD_32_BIT)"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 4.0; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; ED46AB44142347BD0057DC96 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ARCHS = "$(ARCHS_STANDARD_32_BIT)"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 4.0; OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; name = Release; }; ED46AB46142347BD0057DC96 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "ios_syncclient_app_sample-Prefix.pch"; INFOPLIST_FILE = "ios_syncclient_app_sample-Info.plist"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; name = Debug; }; ED46AB47142347BD0057DC96 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "ios_syncclient_app_sample-Prefix.pch"; INFOPLIST_FILE = "ios_syncclient_app_sample-Info.plist"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ ED46AB18142347BC0057DC96 /* Build configuration list for PBXProject "ios_syncclient_app_sample" */ = { isa = XCConfigurationList; buildConfigurations = ( ED46AB43142347BD0057DC96 /* Debug */, ED46AB44142347BD0057DC96 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; ED46AB45142347BD0057DC96 /* Build configuration list for PBXNativeTarget "ios_syncclient_app_sample" */ = { isa = XCConfigurationList; buildConfigurations = ( ED46AB46142347BD0057DC96 /* Debug */, ED46AB47142347BD0057DC96 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = ED46AB15142347BC0057DC96 /* Project object */; } project.xcworkspace/000077500000000000000000000000001226375725500400535ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/sysync_SDK/ios_syncclient_app_sample/ios_syncclient_app_sample.xcodeprojcontents.xcworkspacedata000066400000000000000000000002431226375725500450140ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/sysync_SDK/ios_syncclient_app_sample/ios_syncclient_app_sample.xcodeproj/project.xcworkspace xcshareddata/000077500000000000000000000000001226375725500365105ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/sysync_SDK/ios_syncclient_app_sample/ios_syncclient_app_sample.xcodeprojxcschemes/000077500000000000000000000000001226375725500404725ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/sysync_SDK/ios_syncclient_app_sample/ios_syncclient_app_sample.xcodeproj/xcshareddataios_syncclient_app_sample.xcscheme000066400000000000000000000064251226375725500474500ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/sysync_SDK/ios_syncclient_app_sample/ios_syncclient_app_sample.xcodeproj/xcshareddata/xcschemes libsynthesis-3.4.0.47.1/src/sysync_SDK/ios_syncclient_app_sample/ios_syncclient_app_sample.xml000066400000000000000000001174601226375725500326730ustar00rootroot00000000000000 iOS sample SyncML client app SySync Client iPhone SAMPLE $(logpath) flush yes html yes no yes separate no no yes no 5 0) { // DTSTART and DTEND probably (could be real 24h timed as well in iCalendar 2.0!) represent allday event if (ITEMDATATYPE()=="vcalendar10") { // vCalendar 1.0 - this must be allday // - convert start to user zone (or floating) so it represents midnight DTSTART = CONVERTTOUSERZONE(DTSTART); // - make them real date-only values MAKEALLDAY(DTSTART,DTEND,i); } else { // iCalendar 2.0 - only if DTSTART is a date-only value this really is an allday if (ISDATEONLY(DTSTART)) { // reshape to make sure we don't have invalid zero-duration alldays (old OCS 9 servers) MAKEALLDAY(DTSTART,DTEND,i); } } } // - shape attendees (and make sure ATTENDEES[] is assigned even for empty email addresses) i=0; while(i 2.1 3.0 yes current olson 1.0 2.0 $(binfilespath) UTF-8 unix no yes 2001 contacts textfile 1 yes [SDK_textdb] no $(textfilespath) UTF-8 unix 2002 calendar textfile 2 [SDK_textdb] no $(textfilespath) F.ISEVENT:=1 yes UTF-8 unix UTC yes makes it show in vCalendar as user time, only need to check allday if (allday) { // this is an allday event, make it dayonly MAKEALLDAY(DTSTART,DTEND); } ]]> libsynthesis-3.4.0.47.1/src/sysync_SDK/ios_syncclient_app_sample/main.m000066400000000000000000000005461226375725500260210ustar00rootroot00000000000000// // main.m // ios_syncclient_app_sample // // Created by Lukas Zeller on 2011/09/16. // Copyright (c) 2011 __MyCompanyName__. All rights reserved. // #import #import "AppDelegate.h" int main(int argc, char *argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } } libsynthesis-3.4.0.47.1/src/sysync_SDK/sdk_sources_cocoa/000077500000000000000000000000001226375725500231545ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/sysync_SDK/sdk_sources_cocoa/SettingsKey.h000066400000000000000000000073021226375725500256000ustar00rootroot00000000000000/* SettingsKey */ #import #import #include "syerror.h" #include "sync_dbapidef.h" // DBGNSLog helper macro, only included when DEBUG is #defined #ifndef DBGNSLOG #ifdef DEBUG #define DBGNSLOG(...) NSLog(__VA_ARGS__) #else #define DBGNSLOG(...) #endif #endif #ifndef DBGEXNSLOG #if defined(DEBUG) && (DEBUG>1) #define DBGEXNSLOG(...) NSLog(__VA_ARGS__) #else #define DBGEXNSLOG(...) #endif #endif #ifdef __cplusplus using namespace sysync; #endif // wrapper for a SySync settings key (engine, session or item) @interface SettingsKey : NSObject { // the call-in structure UI_Call_In fCI; // the engine key handle KeyH fKeyH; id fParentObj; } - (id)initWithCI:(UI_Call_In)aCI andKeyHandle:(void *)aKeyH; - (void)dealloc; // management - (void)ownParent:(id)aParentObj; - (void *)detachFromKeyHandle; // Access to keys - (KeyH)keyH; - (SettingsKey *)newOpenKeyByPath:(cAppCharP)aPath withMode:(uInt16)aMode err:(TSyError *)aErrP; - (SettingsKey *)newOpenSubKeyByID:(sInt32)aID withMode:(uInt16)aMode err:(TSyError *)aErrP; - (sInt32)keyID; - (TSyError)deleteSubKeyByID:(sInt32)aID; // access to values // - modes - (TSyError)setTextCharset:(uInt16)aCharSet andLineEnds:(uInt16)aLineEndMode isBigEndian:(bool)aBigEndian; - (TSyError)setTimeMode:(uInt16)aTimeMode; // - id - (sInt32)valueIDByName:(cAppCharP)aValName; // - raw values - (TSyError)valueByName:(cAppCharP)aValName asType:(uInt16)aValType intoBuffer:(appPointer)aBuffer ofSize:(memSize)aBufSize valSize:(memSize *)aValSizeP; - (TSyError)valueByID:(sInt32)aID arrayIndex:(sInt32)aArrayIndex asType:(uInt16)aValType intoBuffer:(appPointer)aBuffer ofSize:(memSize)aBufSize valSize:(memSize *)aValSizeP; - (TSyError)setValueByName:(cAppCharP)aValName asType:(uInt16)aValType fromBuffer:(cAppPointer)aBuffer ofSize:(memSize)aValSize; - (TSyError)setValueByID:(sInt32)aID arrayIndex:(sInt32)aArrayIndex asType:(uInt16)aValType fromBuffer:(cAppPointer)aBuffer ofSize:(memSize)aValSize; // - strings - (NSString *)stringValueByName:(cAppCharP)aValName; - (NSString *)stringValueByID:(sInt32)aID arrayIndex:(sInt32)aArrayIndex; - (NSString *)stringValueByID:(sInt32)aID arrayIndex:(sInt32)aArrayIndex withStatus:(TSyError *)aStatusP; - (TSyError)setStringValueByName:(cAppCharP)aValName toValue:(NSString *)aString; - (TSyError)setStringValueByID:(sInt32)aID arrayIndex:(sInt32)aArrayIndex toValue:(NSString *)aString; // - 32 bit integers - (sInt32)intValueByName:(cAppCharP)aValName; - (sInt32)intValueByID:(sInt32)aID arrayIndex:(sInt32)aArrayIndex; - (sInt32)intValueByID:(sInt32)aID arrayIndex:(sInt32)aArrayIndex withStatus:(TSyError *)aStatusP; - (TSyError)setIntValueByName:(cAppCharP)aValName toValue:(sInt32)aInt; - (TSyError)setIntValueByID:(sInt32)aID arrayIndex:(sInt32)aArrayIndex toValue:(sInt32)aInt; // - 64 bit integers - (sInt64)int64ValueByName:(cAppCharP)aValName; - (sInt64)int64ValueByID:(sInt32)aID arrayIndex:(sInt32)aArrayIndex; - (sInt64)int64ValueByID:(sInt32)aID arrayIndex:(sInt32)aArrayIndex withStatus:(TSyError *)aStatusP; - (TSyError)setInt64ValueByName:(cAppCharP)aValName toValue:(sInt64)aInt; - (TSyError)setInt64ValueByID:(sInt32)aID arrayIndex:(sInt32)aArrayIndex toValue:(sInt64)aInt; // - date/time - (NSDate *)dateValueByName:(cAppCharP)aValName; - (NSDate *)dateValueByID:(sInt32)aID arrayIndex:(sInt32)aArrayIndex; - (NSDate *)dateValueByID:(sInt32)aID arrayIndex:(sInt32)aArrayIndex withStatus:(TSyError *)aStatusP; - (TSyError)setDateValueByName:(cAppCharP)aValName toValue:(NSDate *)aDate; - (TSyError)setDateValueByID:(sInt32)aID arrayIndex:(sInt32)aArrayIndex toValue:(NSDate *)aDate; // - KVC - (id)valueForKey:(NSString *)key; - (void)setValue:(id)value forKey:(NSString *)key; @end // SettingsKey libsynthesis-3.4.0.47.1/src/sysync_SDK/sdk_sources_cocoa/SettingsKey.m000066400000000000000000000412321226375725500256050ustar00rootroot00000000000000#import "SettingsKey.h" #include #include "sdk_util.h" // for Plugin_Version() // if defined, living instances are recorded in a set to monitor if all are closed properly (DEBUG only) //#define SETTINGSKEY_MONITORINSTANCES 1 #if defined(SETTINGSKEY_MONITORINSTANCES) && defined(DEBUG) NSMutableSet *openSettingsKeySet = nil; void key_created(id aKey) { if (!openSettingsKeySet) { openSettingsKeySet = [[NSMutableSet alloc] init]; } [openSettingsKeySet addObject:[NSNumber numberWithUnsignedLong:(intptr_t)aKey]]; } void key_deleted(id aKey) { [openSettingsKeySet removeObject:[NSNumber numberWithUnsignedLong:(intptr_t)aKey]]; NSMutableString *s = [NSMutableString string]; for (id key in openSettingsKeySet) { id keyPtr = (id)[key unsignedLongValue]; [s appendFormat:@"0x%lX(%d), ", (intptr_t)keyPtr, [keyPtr retainCount]]; } NSLog(@"Still open keys: %@",s); } #define KEY_CREATED(k) key_created(k) #define KEY_DELETED(k) key_deleted(k) #define KEYNSLOG(...) DBGNSLOG(__VA_ARGS__) #else #define KEY_CREATED(k) #define KEY_DELETED(k) #define KEYNSLOG(...) #endif // wrapper for a SySync settings key (engine, session or item) @implementation SettingsKey - (id)initWithCI:(UI_Call_In)aCI andKeyHandle:(void *)aKeyH { if ((self = [super init])) { fCI = aCI; fKeyH = aKeyH; fParentObj=nil; } KEY_CREATED(self); return self; } // initWithCI // have the settings key own another object and release that on close (usually the parent key) - (void)ownParent:(id)aParentObj { fParentObj = [aParentObj retain]; // own it } // ownParent // detach wrapper object from handle - (void *)detachFromKeyHandle { void *keyH = fKeyH; fKeyH = NULL; fCI = NULL; return keyH; } // detachFromKeyHandle // dealloc implicitly closes key (except if it was previously detached with -detachFromKeyHandle) - (void)dealloc { // close key if (fCI && fKeyH) { CloseKey_Func CloseKey= fCI->ui.CloseKey; if (CloseKey) { CloseKey(fCI,fKeyH); fKeyH=NULL; } } // close parent if one is assigned [fParentObj release]; KEYNSLOG(@"Deallocating SettingsKey object = 0x%lX",(intptr_t)self); KEY_DELETED(self); // done [super dealloc]; } // dealloc // Access to keys // note: this is explicitly implemented to make it compatible with 10.4 SDK and compilers - (KeyH)keyH { return fKeyH; } - (SettingsKey *)newOpenKeyByPath:(cAppCharP)aPath withMode:(uInt16)aMode err:(TSyError *)aErrP { TSyError sta=LOCERR_OK; KeyH newKeyH=NULL; SettingsKey *newKey=nil; // no object by default OpenKeyByPath_Func OpenKeyByPath = fCI->ui.OpenKeyByPath; if (!OpenKeyByPath) { sta=LOCERR_NOTIMP; } else { sta = OpenKeyByPath(fCI,&newKeyH,fKeyH,aPath,aMode); if (sta==LOCERR_OK) { newKey=[[SettingsKey alloc] initWithCI:fCI andKeyHandle:newKeyH]; KEYNSLOG(@"Opened settings key %s : SettingsKey object = 0x%lX",aPath,(intptr_t)newKey); } } if (aErrP) *aErrP=sta; return newKey; } // newOpenKeyByPath - (SettingsKey *)newOpenSubKeyByID:(sInt32)aID withMode:(uInt16)aMode err:(TSyError *)aErrP { KeyH newKeyH=NULL; TSyError sta=LOCERR_OK; SettingsKey *newKey=nil; // no object by default OpenSubkey_Func OpenSubkey = fCI->ui.OpenSubkey; if (!OpenSubkey) { sta=LOCERR_NOTIMP; } else { sta = OpenSubkey(fCI,&newKeyH,fKeyH,aID,aMode); if (sta==LOCERR_OK) { newKey=[[SettingsKey alloc] initWithCI:fCI andKeyHandle:newKeyH]; KEYNSLOG(@"Opened settings subkey by ID=%d (actual ID=%d): SettingsKey object = 0x%lX",aID,[newKey keyID],(intptr_t)newKey); } } if (aErrP) *aErrP=sta; return newKey; } // newOpenSubKeyByID - (sInt32)keyID { sInt32 theID = KEYVAL_ID_UNKNOWN; GetKeyID_Func GetKeyID = fCI->ui.GetKeyID; if (!GetKeyID) return KEYVAL_ID_UNKNOWN; GetKeyID(fCI, fKeyH, &theID); return theID; } // keyID - (TSyError)deleteSubKeyByID:(sInt32)aID { DeleteSubkey_Func DeleteSubkey = fCI->ui.DeleteSubkey; if (!DeleteSubkey) return LOCERR_NOTIMP; return DeleteSubkey(fCI, fKeyH, aID); } // deleteSubKeyByID // Modes - (TSyError)setTextCharset:(uInt16)aCharSet andLineEnds:(uInt16)aLineEndMode isBigEndian:(bool)aBigEndian; { SetTextMode_Func SetTextMode = fCI->ui.SetTextMode; if (!SetTextMode) return LOCERR_NOTIMP; return SetTextMode(fCI,fKeyH,aCharSet,aLineEndMode,aBigEndian); } // setTextCharset - (TSyError)setTimeMode:(uInt16)aTimeMode; { SetTimeMode_Func SetTimeMode = fCI->ui.SetTimeMode; if (!SetTimeMode) return LOCERR_NOTIMP; return SetTimeMode(fCI,fKeyH,aTimeMode); } // setTimeMode // IDs - (sInt32)valueIDByName:(cAppCharP)aValName { GetValueID_Func GetValueID= fCI->ui.GetValueID; if (!GetValueID) return KEYVAL_ID_UNKNOWN; return GetValueID(fCI, fKeyH, aValName); } // valueIDByName #pragma mark access to values // - raw - (TSyError)valueByName:(cAppCharP)aValName asType:(uInt16)aValType intoBuffer:(appPointer)aBuffer ofSize:(memSize)aBufSize valSize:(memSize *)aValSizeP { GetValue_Func GetValue= fCI->ui.GetValue; if (!GetValue) return LOCERR_NOTIMP; return GetValue(fCI, fKeyH, aValName, aValType, aBuffer, aBufSize, aValSizeP); } // valueByName - (TSyError)valueByID:(sInt32)aID arrayIndex:(sInt32)aArrayIndex asType:(uInt16)aValType intoBuffer:(appPointer)aBuffer ofSize:(memSize)aBufSize valSize:(memSize *)aValSizeP { GetValueByID_Func GetValueByID= fCI->ui.GetValueByID; if (!GetValueByID) return LOCERR_NOTIMP; return GetValueByID(fCI, fKeyH, aID, aArrayIndex, aValType, aBuffer, aBufSize, aValSizeP); } // valueByID - (TSyError)setValueByName:(cAppCharP)aValName asType:(uInt16)aValType fromBuffer:(cAppPointer)aBuffer ofSize:(memSize)aValSize { SetValue_Func SetValue= fCI->ui.SetValue; if (!SetValue) return LOCERR_NOTIMP; return SetValue(fCI, fKeyH, aValName, aValType, aBuffer, aValSize); } // setValueByName - (TSyError)setValueByID:(sInt32)aID arrayIndex:(sInt32)aArrayIndex asType:(uInt16)aValType fromBuffer:(cAppPointer)aBuffer ofSize:(memSize)aValSize; { SetValueByID_Func SetValueByID= fCI->ui.SetValueByID; if (!SetValueByID) return LOCERR_NOTIMP; return SetValueByID(fCI, fKeyH, aID, aArrayIndex, aValType, aBuffer, aValSize); } // setValueByID // - strings // Note: it is important NOT to simplify the implementation by emulating the byName access by // trying to use valueIDByName and then valueByID, as some string values can ONLY be accessed // by name, and not by ID! - (NSString *)stringValueByName:(cAppCharP)aValName { const size_t stdBufSiz = 255; appCharP strP; size_t valSz; TSyError sta = LOCERR_OUTOFMEM; NSString *result = nil; // try with standard buffer size first strP = malloc(stdBufSiz); if (strP) { sta = [self valueByName:aValName asType:VALTYPE_TEXT intoBuffer:strP ofSize:stdBufSiz valSize:&valSz]; if (sta==LOCERR_BUFTOOSMALL || sta==LOCERR_TRUNCATED) { // buffer too small to return anything, valSz contains needed size free(strP); if (sta==LOCERR_TRUNCATED) { // buffer too small to return all data, but truncated version was returned. // - measure overall data size (valSz only contains size of truncated data now!) sta = [self valueByName:aValName asType:VALTYPE_TEXT intoBuffer:NULL ofSize:0 valSize:&valSz]; } // allocate a buffer that is large enough strP = malloc(valSz+1); if (strP!=NULL) sta = [self valueByName:aValName asType:VALTYPE_TEXT intoBuffer:strP ofSize:valSz+1 valSize:&valSz]; } if (sta==LOCERR_OK) { // got value ok, now fill into NSString // Note: if strP contains invalid UTF8, this will return nil! result = [NSString stringWithCString:strP encoding:NSUTF8StringEncoding]; #ifdef DEBUG if (!result) { DBGNSLOG(@"stringValueByName:%s returns string with incorrect UTF-8 encoding",aValName); } #endif } // return buffer free(strP); } #ifdef DEBUG if (sta!=LOCERR_OK) { DBGEXNSLOG(@"stringValueByName:%s returns err=%hd",aValName,sta); } #endif return result; } // stringValueByName - (NSString *)stringValueByID:(sInt32)aID arrayIndex:(sInt32)aArrayIndex { return [self stringValueByID:aID arrayIndex:aArrayIndex withStatus:NULL]; } // intValueByID - (NSString *)stringValueByID:(sInt32)aID arrayIndex:(sInt32)aArrayIndex withStatus:(TSyError *)aStatusP { const size_t stdBufSiz = 255; appCharP strP; size_t valSz; TSyError sta = LOCERR_OUTOFMEM; NSString *result = nil; // try with standard buffer size first strP = malloc(stdBufSiz); if (strP) { sta = [self valueByID:aID arrayIndex:aArrayIndex asType:VALTYPE_TEXT intoBuffer:strP ofSize:stdBufSiz valSize:&valSz]; if (sta==LOCERR_BUFTOOSMALL || sta==LOCERR_TRUNCATED) { // buffer too small to return anything, valSz contains needed size free(strP); if (sta==LOCERR_TRUNCATED) { // buffer too small to return all data, but truncated version was returned. // - measure overall data size (valSz only contains size of truncated data now!) sta = [self valueByID:aID arrayIndex:aArrayIndex asType:VALTYPE_TEXT intoBuffer:NULL ofSize:0 valSize:&valSz]; } // allocate a buffer that is large enough strP = malloc(valSz+1); if (strP!=NULL) sta = [self valueByID:aID arrayIndex:aArrayIndex asType:VALTYPE_TEXT intoBuffer:strP ofSize:valSz+1 valSize:&valSz]; } if (sta==LOCERR_OK) { // got value ok, now fill into NSString result = [NSString stringWithCString:strP encoding:NSUTF8StringEncoding]; } // return buffer free(strP); } #ifdef DEBUG if (sta!=LOCERR_OK) { DBGEXNSLOG(@"stringValueByID:%ld arrayIndex:%ld returns err=%hd",(sIntArch)aID,(sIntArch)aArrayIndex,sta); } #endif if (aStatusP) *aStatusP=sta; return result; } // stringValueByID - (TSyError)setStringValueByName:(cAppCharP)aValName toValue:(NSString *)aString { return [ self setValueByName:aValName asType:VALTYPE_TEXT fromBuffer:[(aString ? aString : @"") cStringUsingEncoding:NSUTF8StringEncoding] ofSize:(uIntArch)-1 // autosize from C-String ]; } // setStringValueByName - (TSyError)setStringValueByID:(sInt32)aID arrayIndex:(sInt32)aArrayIndex toValue:(NSString *)aString; { return [ self setValueByID:aID arrayIndex:aArrayIndex asType:VALTYPE_TEXT fromBuffer:[(aString ? aString : @"") cStringUsingEncoding:NSUTF8StringEncoding] ofSize:(uIntArch)-1 // autosize from C-String ]; } // setStringValueByID // int32 values - (sInt32)intValueByName:(cAppCharP)aValName { sInt32 myVal=0; size_t myValSz; #ifdef DEBUG TSyError sta; sta = #endif [self valueByName:aValName asType:VALTYPE_INT32 intoBuffer:&myVal ofSize:sizeof(myVal) valSize:&myValSz]; #ifdef DEBUG if (sta!=LOCERR_OK) { DBGEXNSLOG(@"intValueByName:%s returns err=%hd",aValName,sta); } #endif return myVal; } // intValueByName - (sInt32)intValueByID:(sInt32)aID arrayIndex:(sInt32)aArrayIndex { return [self intValueByID:aID arrayIndex:aArrayIndex withStatus:NULL]; } // intValueByID - (sInt32)intValueByID:(sInt32)aID arrayIndex:(sInt32)aArrayIndex withStatus:(TSyError *)aStatusP { sInt32 myVal=0; size_t myValSz; TSyError sta; sta = [self valueByID:aID arrayIndex:aArrayIndex asType:VALTYPE_INT32 intoBuffer:&myVal ofSize:sizeof(myVal) valSize:&myValSz]; #ifdef DEBUG if (sta!=LOCERR_OK) { DBGEXNSLOG(@"intValueByID:%ld arrayIndex:%ld returns err=%hd",(sIntArch)aID,(sIntArch)aArrayIndex,sta); } #endif if (aStatusP) *aStatusP=sta; return myVal; } // intValueByID withStatus - (TSyError)setIntValueByName:(cAppCharP)aValName toValue:(sInt32)aInt { return [self setValueByName:aValName asType:VALTYPE_INT32 fromBuffer:&aInt ofSize:sizeof(aInt)]; } // setIntValueByName - (TSyError)setIntValueByID:(sInt32)aID arrayIndex:(sInt32)aArrayIndex toValue:(sInt32)aInt { return [self setValueByID:aID arrayIndex:aArrayIndex asType:VALTYPE_INT32 fromBuffer:&aInt ofSize:sizeof(aInt)]; } // setIntValueByID // int64 values - (sInt64)int64ValueByName:(cAppCharP)aValName { sInt64 myVal=0; size_t myValSz; #ifdef DEBUG TSyError sta; sta = #endif [self valueByName:aValName asType:VALTYPE_INT64 intoBuffer:&myVal ofSize:sizeof(myVal) valSize:&myValSz]; #ifdef DEBUG if (sta!=LOCERR_OK) { DBGEXNSLOG(@"int64ValueByName:%s returns err=%hd\n",aValName,sta); } #endif return myVal; } // int64ValueByName - (sInt64)int64ValueByID:(sInt32)aID arrayIndex:(sInt32)aArrayIndex { return [self int64ValueByID:aID arrayIndex:aArrayIndex withStatus:NULL]; } // int64ValueByID - (sInt64)int64ValueByID:(sInt32)aID arrayIndex:(sInt32)aArrayIndex withStatus:(TSyError *)aStatusP { sInt64 myVal=0; size_t myValSz; TSyError sta; sta = [self valueByID:aID arrayIndex:aArrayIndex asType:VALTYPE_INT64 intoBuffer:&myVal ofSize:sizeof(myVal) valSize:&myValSz]; #ifdef DEBUG if (sta!=LOCERR_OK) { DBGEXNSLOG(@"intValueByID:%ld arrayIndex:%ld returns err=%hd",(sIntArch)aID,(sIntArch)aArrayIndex,sta); } #endif if (aStatusP) *aStatusP=sta; return myVal; } // int64ValueByID withStatus - (TSyError)setInt64ValueByName:(cAppCharP)aValName toValue:(sInt64)aInt { return [self setValueByName:aValName asType:VALTYPE_INT64 fromBuffer:&aInt ofSize:sizeof(aInt)]; } // setInt64ValueByName - (TSyError)setInt64ValueByID:(sInt32)aID arrayIndex:(sInt32)aArrayIndex toValue:(sInt64)aInt { return [self setValueByID:aID arrayIndex:aArrayIndex asType:VALTYPE_INT32 fromBuffer:&aInt ofSize:sizeof(aInt)]; } // setInt64ValueByID // date values // Note: Date values must be keys that have an ID. ID-less datetime keys cannot be used (but do not exist // in the engine, so the simplified implementation is ok here) - (NSDate *)dateValueByName:(cAppCharP)aValName { // get ID by name sInt32 valID = [self valueIDByName:aValName]; // obtain by ID return [self dateValueByID:valID arrayIndex:0]; } // dateValueByName - (NSDate *)dateValueByID:(sInt32)aID arrayIndex:(sInt32)aArrayIndex { return [self dateValueByID:aID arrayIndex:aArrayIndex withStatus:NULL]; } - (NSDate *)dateValueByID:(sInt32)aID arrayIndex:(sInt32)aArrayIndex withStatus:(TSyError *)aStatusP { sInt64 myVal; size_t myValSz; TSyError sta; [self setTimeMode:TMODE_UNIXTIME_MS+TMODE_FLAG_UTC]; // unix epoch time in milliseconds sta = [self valueByID:aID arrayIndex:aArrayIndex asType:VALTYPE_TIME64 intoBuffer:&myVal ofSize:sizeof(myVal) valSize:&myValSz]; if (aStatusP) *aStatusP=sta; if (sta!=LOCERR_OK) return nil; // no time else { NSDate *nsdat = [NSDate dateWithTimeIntervalSince1970:(NSTimeInterval)myVal/1000.0]; DBGEXNSLOG(@"dateValueByID: myVal = %lld returned as NSDate = %@", myVal, nsdat); return nsdat; } } // dateValueByID - (TSyError)setDateValueByName:(cAppCharP)aValName toValue:(NSDate *)aDate { // get ID by name sInt32 valID = [self valueIDByName:aValName]; // obtain by ID return [self setDateValueByID:valID arrayIndex:0 toValue:aDate]; } // setDateValueByName - (TSyError)setDateValueByID:(sInt32)aID arrayIndex:(sInt32)aArrayIndex toValue:(NSDate *)aDate { sInt64 myVal = 0; // no time if (aDate!=nil) myVal = [aDate timeIntervalSince1970]*1000.0; // milliseconds DBGEXNSLOG(@"setDateValueByID: aDate = %@, returned as myVal = %lld", aDate, myVal); [self setTimeMode:TMODE_UNIXTIME_MS+TMODE_FLAG_UTC]; // unix epoch time in milliseconds return [self setValueByID:aID arrayIndex:aArrayIndex asType:VALTYPE_TIME64 fromBuffer:&myVal ofSize:sizeof(myVal)]; } // setDateValue #pragma mark basic KVC access to values - (id)valueForKey:(NSString *)key { // determine native value type uInt16 valtype; size_t myValSz; [self valueByName:[[key stringByAppendingString:@"" ".VALTYPE"] UTF8String] asType:VALTYPE_INT16 intoBuffer:&valtype ofSize:sizeof(valtype) valSize:&myValSz ]; // handle according to type switch (valtype) { case VALTYPE_TEXT: return [self stringValueByName:[key UTF8String]]; case VALTYPE_TIME64: case VALTYPE_TIME32: return [self dateValueByName:[key UTF8String]]; case VALTYPE_INT64: return [NSNumber numberWithLongLong:[self int64ValueByName:[key UTF8String]]]; case VALTYPE_INT32: case VALTYPE_INT16: case VALTYPE_INT8: return [NSNumber numberWithLong:[self intValueByName:[key UTF8String]]]; default: return nil; } } - (void)setValue:(id)value forKey:(NSString *)key { // handle according to object type if ([value isKindOfClass:[NSString class]]) { // set as string [self setStringValueByName:[key UTF8String] toValue:value]; return; } else if ([value isKindOfClass:[NSDate class]]) { // set as date [self setDateValueByName:[key UTF8String] toValue:value]; return; } else if ([value isKindOfClass:[NSNumber class]]) { [self setInt64ValueByName:[key UTF8String] toValue:[value longLongValue]]; return; } } @end // SettingsKey libsynthesis-3.4.0.47.1/src/sysync_SDK/sdk_sources_cocoa/SyncEngine.h000066400000000000000000000063751226375725500254020ustar00rootroot00000000000000/* SyncEngine */ #import #import #include "syerror.h" #include "sync_dbapidef.h" #include "SettingsKey.h" // wrapper for a sync session @interface SyncSession : NSObject { // the call-in structure UI_Call_In fCI; struct TunnelWrapper fTW; // the session handle SessionH fSessionH; } - (id)initWithCI:(UI_Call_In)aCI andSessionHandle:(SessionH)aSessionH; - (void)dealloc; // access to session key - (SettingsKey *)newOpenSessionKeyWithMode:(uInt16)aMode err:(TSyError *)aErrP; // run the session - (TSyError)sessionStepWithCmd:(uInt16 *)aStepCmdP andProgressInfo:(TEngineProgressInfo *)aInfoP; // read and write the SyncML messages - (TSyError)getSyncMLBufferForSend:(BOOL)aForSend buffer:(appPointer *)aBuffer bufSize:(memSize *)aBufSize; - (TSyError)retSyncMLBufferForSend:(BOOL)aForSend processed:(memSize)aProcessed; // writing to session log - (void)debugLog:(NSString *)aMessage; - (void)errorLog:(NSString *)aMessage; // Tunnel DB API - (TSyError)startDataReadWithLastToken:(cAppCharP)aLastToken andResumeToken:(cAppCharP)aResumeToken; - (TSyError)readNextItemAsKey:(SettingsKey *)aItemKey itemIdP:(NSString **)aItemIdP parentIdP:(NSString **)aParentIdP statusP:(sInt32 *)aStatusP isFirst:(BOOL)aFirst; - (TSyError)readNextItemAsText:(NSString **)aTextP itemIdP:(NSString **)aItemIdP parentIdP:(NSString **)aParentIdP statusP:(sInt32 *)aStatusP isFirst:(BOOL)aFirst; - (TSyError)readItemAsKey:(SettingsKey *)aItemKey itemID:(NSString *)aItemID parentID:(NSString *)aParentID; - (TSyError)readItemAsText:(NSString **)aTextP itemID:(NSString *)aItemID parentID:(NSString *)aParentID; - (TSyError)endDataRead; - (TSyError)startDataWrite; - (TSyError)insertItemAsKey:(SettingsKey *)aItemKey parentID:(NSString *)aParentID newItemIdP:(NSString **)aNewItemIdP; //%%%- (TSyError)finalizeLocalID:(NSString **)aLocIDP; - (TSyError)updateItemAsKey:(SettingsKey *)aItemKey itemIdP:(NSString **)aItemIdP parentIdP:(NSString **)aParentIdP; - (TSyError)moveItem:(NSString *)aItemID fromParentID:(NSString *)aParentID toNewParent:(NSString *)aNewParentID; - (TSyError)deleteItem:(NSString *)aItemID parentID:(NSString *)aParentID; //%%%- (TSyError)deleteSyncSet; - (TSyError)endDataWriteWithSuccess:(BOOL)aSuccess andNewToken:(NSString **)aNewTokenP; @end // wrapper object for the SySync Engine @interface SyncEngine : NSObject { // the DLL interface void *fDLL; CVersion fEngineAPIVersion; // SySync interface UI_Call_In fCI; // call-in structure pointer // disconnect entry point DisconnectEngine_Func DisconnectEngine_Var; } // init and cleanup - (id)initWithLibraryPath:(NSString *)aLibraryPath andDebugFlags:(uInt16)aDebugFlags; - (id)initWithLibraryPath:(NSString *)aLibraryPath andDebugFlags:(uInt16)aDebugFlags andEntryPointPrefix:(NSString *)aEntryPointPrefix; - (void)dealloc; // Engine init - (TSyError)setStringCharset:(uInt16)aCharSet andLineEnds:(uInt16)aLineEndMode isBigEndian:(bool)aBigEndian; - (TSyError)initEngineFile:(NSString *)aPath; // sessions - (SyncSession *)newOpenSessionWithSelector:(uInt32)aSelector andSessionName:(cAppCharP)aSessionName err:(TSyError *)aErrP; // Settings access - (SettingsKey *)newOpenKeyByPath:(cAppCharP)aPath withMode:(uInt16)aMode err:(TSyError *)aErrP; @end libsynthesis-3.4.0.47.1/src/sysync_SDK/sdk_sources_cocoa/SyncEngine.m000066400000000000000000000315361226375725500254040ustar00rootroot00000000000000#import "SyncEngine.h" #include #include "sdk_util.h" // for Plugin_Version() // wrapper for a SyncSession @implementation SyncSession - (id)initWithCI:(UI_Call_In)aCI andSessionHandle:(SessionH)aSessionH; { if ((self = [super init])) { fCI = aCI; fSessionH = aSessionH; // also prepare tunnel wrapper fTW.tCB = fCI; fTW.tContext = fSessionH; } return self; } // initWithCI // dealloc implicitly closes session - (void)dealloc { // close key if (fCI) { CloseSession_Func CloseSession= fCI->ui.CloseSession; if (CloseSession) { CloseSession(fCI,fSessionH); fSessionH=NULL; } } // done #if !__has_feature(objc_arc) [super dealloc]; #endif } // dealloc // open a new session key - (SettingsKey *)newOpenSessionKeyWithMode:(uInt16)aMode err:(TSyError *)aErrP { TSyError sta=LOCERR_OK; KeyH newKeyH=NULL; SettingsKey *newKey=nil; // no object by default OpenSessionKey_Func OpenSessionKey = fCI->ui.OpenSessionKey; if (!OpenSessionKey) { sta=LOCERR_NOTIMP; } else { sta = OpenSessionKey(fCI,fSessionH,&newKeyH,aMode); if (sta==LOCERR_OK) { newKey=[[SettingsKey alloc] initWithCI:fCI andKeyHandle:newKeyH]; } } if (aErrP) *aErrP=sta; return newKey; } - (TSyError)sessionStepWithCmd:(uInt16 *)aStepCmdP andProgressInfo:(TEngineProgressInfo *)aInfoP { SessionStep_Func SessionStep = fCI->ui.SessionStep; if (!SessionStep) return LOCERR_NOTIMP; return SessionStep(fCI,fSessionH,aStepCmdP,aInfoP); } - (TSyError)getSyncMLBufferForSend:(BOOL)aForSend buffer:(appPointer *)aBufferPP bufSize:(memSize *)aBufSizeP { GetSyncMLBuffer_Func GetSyncMLBuffer = fCI->ui.GetSyncMLBuffer; if (!GetSyncMLBuffer) return LOCERR_NOTIMP; return GetSyncMLBuffer(fCI,fSessionH,aForSend,aBufferPP,aBufSizeP); } - (TSyError)retSyncMLBufferForSend:(BOOL)aForSend processed:(memSize)aProcessed; { RetSyncMLBuffer_Func RetSyncMLBuffer = fCI->ui.RetSyncMLBuffer; if (!RetSyncMLBuffer) return LOCERR_NOTIMP; return RetSyncMLBuffer(fCI,fSessionH,aForSend,aProcessed); } // writing to session log - (void)debugLog:(NSString *)aMessage { TSyError sta; SettingsKey *sessionKey = [self newOpenSessionKeyWithMode:0 err:&sta]; if (sta==LOCERR_OK) { [sessionKey setStringValueByName:"debugMsg" toValue:aMessage]; #if !__has_feature(objc_arc) [sessionKey release]; #endif } } - (void)errorLog:(NSString *)aMessage { TSyError sta; SettingsKey *sessionKey = [self newOpenSessionKeyWithMode:0 err:&sta]; if (sta==LOCERR_OK) { [sessionKey setStringValueByName:"errorMsg" toValue:aMessage]; #if !__has_feature(objc_arc) [sessionKey release]; #endif } } // Tunnel DB API - (TSyError)startDataReadWithLastToken:(cAppCharP)aLastToken andResumeToken:(cAppCharP)aResumeToken { SDR_Func StartDataRead = fCI->dt.StartDataRead; if (!StartDataRead) return LOCERR_NOTIMP; // call return StartDataRead((CContext)&fTW,aLastToken,aResumeToken); } - (TSyError)readNextItemAsKey:(SettingsKey *)aItemKey itemIdP:(NSString **)aItemIdP parentIdP:(NSString **)aParentIdP statusP:(sInt32 *)aStatusP isFirst:(BOOL)aFirst { RdNItemKFunc ReadNextItemAsKey = fCI->dt.ReadNextItemAsKey; if (!ReadNextItemAsKey) return LOCERR_NOTIMP; DisposeProc DisposeObj = fCI->dt.DisposeObj; if (!DisposeObj) return LOCERR_NOTIMP; // check params if (!aItemIdP || !aStatusP) return LOCERR_WRONGUSAGE; // prepare item ID ItemID_Struct itemID; itemID.parent = NULL; itemID.item = NULL; *aItemIdP = nil; if (aParentIdP) *aParentIdP = nil; // call TSyError sta = ReadNextItemAsKey((CContext)&fTW,&itemID,[aItemKey keyH],aStatusP,aFirst); // retrieve result strings if (sta==LOCERR_OK) { // get strings if (itemID.item) *aItemIdP = [NSString stringWithUTF8String:itemID.item]; if (itemID.parent && aParentIdP) *aParentIdP = [NSString stringWithUTF8String:itemID.parent]; } // dispose strings (if not NULL) DisposeObj((CContext)&fTW,itemID.item); DisposeObj((CContext)&fTW,itemID.parent); return sta; } - (TSyError)readNextItemAsText:(NSString **)aTextP itemIdP:(NSString **)aItemIdP parentIdP:(NSString **)aParentIdP statusP:(sInt32 *)aStatusP isFirst:(BOOL)aFirst { RdNItemSFunc ReadNextItem = fCI->dt.ReadNextItem; if (!ReadNextItem) return LOCERR_NOTIMP; DisposeProc DisposeObj = fCI->dt.DisposeObj; if (!DisposeObj) return LOCERR_NOTIMP; // check params if (!aItemIdP || !aStatusP) return LOCERR_WRONGUSAGE; // prepare item ID ItemID_Struct itemID; itemID.parent = NULL; itemID.item = NULL; *aItemIdP = nil; if (aParentIdP) *aParentIdP = nil; // call appCharP itemData = NULL; TSyError sta = ReadNextItem((CContext)&fTW,&itemID,&itemData,aStatusP,aFirst); // retrieve result strings if (sta==LOCERR_OK) { // get strings if (itemID.item) *aItemIdP = [NSString stringWithUTF8String:itemID.item]; if (itemID.parent && aParentIdP) *aParentIdP = [NSString stringWithUTF8String:itemID.parent]; if (itemData && aTextP) *aTextP = [NSString stringWithUTF8String:itemData]; } // dispose strings (if not NULL) DisposeObj((CContext)&fTW,itemID.item); DisposeObj((CContext)&fTW,itemID.parent); DisposeObj((CContext)&fTW,itemData); return sta; } - (TSyError)readItemAsKey:(SettingsKey *)aItemKey itemID:(NSString *)aItemID parentID:(NSString *)aParentID { Rd_ItemKFunc ReadItemAsKey = fCI->dt.ReadItemAsKey; if (!ReadItemAsKey) return LOCERR_NOTIMP; // prepare item ID ItemID_Struct itemID; itemID.parent = aParentID ? (appCharP)[aParentID UTF8String] : NULL; if (!aItemID) return LOCERR_WRONGUSAGE; itemID.item = (appCharP)[aItemID UTF8String]; // call return ReadItemAsKey((CContext)&fTW,&itemID,[aItemKey keyH]); } - (TSyError)readItemAsText:(NSString **)aTextP itemID:(NSString *)aItemID parentID:(NSString *)aParentID { Rd_ItemSFunc ReadItem = fCI->dt.ReadItem; if (!ReadItem) return LOCERR_NOTIMP; DisposeProc DisposeObj = fCI->dt.DisposeObj; if (!DisposeObj) return LOCERR_NOTIMP; // prepare item ID ItemID_Struct itemID; itemID.parent = aParentID ? (appCharP)[aParentID UTF8String] : NULL; if (!aItemID) return LOCERR_WRONGUSAGE; itemID.item = (appCharP)[aItemID UTF8String]; // call appCharP itemData = NULL; TSyError sta = ReadItem((CContext)&fTW,&itemID,&itemData); if (sta==LOCERR_OK) { // get strings if (itemData && aTextP) *aTextP = [NSString stringWithUTF8String:itemData]; } // dispose strings (if not NULL) DisposeObj((CContext)&fTW,itemData); return sta; } - (TSyError)endDataRead { EDR_Func EndDataRead = fCI->dt.EndDataRead; if (!EndDataRead) return LOCERR_NOTIMP; // call return EndDataRead((CContext)&fTW); } - (TSyError)startDataWrite { return LOCERR_NOTIMP; } - (TSyError)insertItemAsKey:(SettingsKey *)aItemKey parentID:(NSString *)aParentID newItemIdP:(NSString **)aNewItemIdP { return LOCERR_NOTIMP; } //%%%- (TSyError)finalizeLocalID:(NSString **)aLocIDP; - (TSyError)updateItemAsKey:(SettingsKey *)aItemKey itemIdP:(NSString **)aItemIdP parentIdP:(NSString **)aParentIdP { return LOCERR_NOTIMP; } - (TSyError)moveItem:(NSString *)aItemID fromParentID:(NSString *)aParentID toNewParent:(NSString *)aNewParentID { return LOCERR_NOTIMP; } - (TSyError)deleteItem:(NSString *)aItemID parentID:(NSString *)aParentID { return LOCERR_NOTIMP; } //%%%- (TSyError)deleteSyncSet; - (TSyError)endDataWriteWithSuccess:(BOOL)aSuccess andNewToken:(NSString **)aNewTokenP { return LOCERR_NOTIMP; } @end // SyncSession @implementation SyncEngine - (id)initWithLibraryPath:(NSString *)aLibraryPath andDebugFlags:(uInt16)aDebugFlags andEntryPointPrefix:(NSString *)aEntryPointPrefix { TSyError sta=DB_NotFound; // init members fDLL = NULL; DisconnectEngine_Var = NULL; // empty prefix if none specified if (aEntryPointPrefix==nil) aEntryPointPrefix = @""; // init superclass and DLL if ((self = [super init])) { ConnectEngine_Func ConnectEngine_Var = NULL; #ifdef SYSYNC_ENGINE_STATIC // static: just directly use the entry point. // if prefix contains "srv", we want a server engine if ([aEntryPointPrefix rangeOfString:@"srv"].location!=NSNotFound) { // server ConnectEngine_Var = &SySync_srv_ConnectEngine; DisconnectEngine_Var = &SySync_srv_DisconnectEngine; } else { // client ConnectEngine_Var = &ConnectEngine; DisconnectEngine_Var = &DisconnectEngine; } #else // dynamic: open the DLL, query the entry points fDLL = dlopen([aLibraryPath UTF8String], RTLD_LAZY); if (fDLL==NULL) { // try with .dylib ending fDLL = dlopen([[aLibraryPath stringByAppendingString:@".dylib"] UTF8String], RTLD_LAZY); } if (fDLL!=NULL) { // found the DLL, now get connect entry point (if none specified, use default) ConnectEngine_Var = dlsym(fDLL,[[aEntryPointPrefix stringByAppendingString:@"ConnectEngine"] UTF8String]); // and also remember the disconnect entry point DisconnectEngine_Var = dlsym(fDLL,[[aEntryPointPrefix stringByAppendingString:@"DisconnectEngine"] UTF8String]); } else { DBGNSLOG(@"dlopen() failed: %s\n",dlerror()); } #endif // connect to the library if (ConnectEngine_Var!=NULL) { // got the entry, call it sta = ConnectEngine_Var(&fCI, &fEngineAPIVersion, Plugin_Version(0), aDebugFlags); if (!fCI) sta=LOCERR_NOTIMP; } // now engine should be accessible if (sta==LOCERR_OK) { // prepare engine text mode [self setStringCharset:CHS_UTF8 andLineEnds:LEM_UNIX isBigEndian:true]; // get and print version SettingsKey *engineInfo = [self newOpenKeyByPath:"/engineinfo" withMode:0 err:&sta]; if (sta==LOCERR_OK) { DBGNSLOG(@"SySync engine version = '%@'\n", [engineInfo stringValueByName:"version"]); DBGNSLOG(@"SySync engine platform = '%@'\n", [engineInfo stringValueByName:"platform"]); DBGNSLOG(@"library product name = '%@'\n", [engineInfo stringValueByName:"name"]); DBGNSLOG(@"version comment = '%@'\n", [engineInfo stringValueByName:"comment"]); #if !__has_feature(objc_arc) [engineInfo release]; #endif } } } else sta=LOCERR_OUTOFMEM; // probably... // kill or go if (sta!=LOCERR_OK) { #if !__has_feature(objc_arc) [self dealloc]; #endif return nil; } // ok return self; } // initWithLibraryPath - (id)initWithLibraryPath:(NSString *)aLibraryPath andDebugFlags:(uInt16)aDebugFlags { // using standard entry point for client library return [self initWithLibraryPath:aLibraryPath andDebugFlags:aDebugFlags andEntryPointPrefix:nil]; } // initWithLibraryPath // Dealloc - (void)dealloc { // disconnect engine #ifdef SYSYNC_ENGINE_STATIC if (DisconnectEngine_Var) { DisconnectEngine_Var(fCI); } #else if (fDLL!=NULL) { // call disconnect if (DisconnectEngine_Var) { // call disconnect in engine DisconnectEngine_Var(fCI); } // unload the DLL dlclose(fDLL); fDLL=NULL; } #endif // no longer valid fCI = NULL; DisconnectEngine_Var = NULL; // done #if !__has_feature(objc_arc) [super dealloc]; #endif } // General setup - (TSyError)setStringCharset:(uInt16)aCharSet andLineEnds:(uInt16)aLineEndMode isBigEndian:(bool)aBigEndian { SetStringMode_Func SetStringMode = fCI->ui.SetStringMode; if (!SetStringMode) return LOCERR_NOTIMP; return SetStringMode(fCI,aCharSet,aLineEndMode,aBigEndian); } // setStringCharset // Init with config - (TSyError)initEngineFile:(NSString *)aPath { InitEngineFile_Func InitEngineFile = fCI->ui.InitEngineFile; if (!InitEngineFile) return LOCERR_NOTIMP; return InitEngineFile(fCI, [aPath UTF8String]); } // initEngineFile // Create a session - (SyncSession *)newOpenSessionWithSelector:(uInt32)aSelector andSessionName:(cAppCharP)aSessionName err:(TSyError *)aErrP { TSyError sta=LOCERR_OK; SessionH newSessionH=NULL; SyncSession *newSession=nil; // no object by default OpenSession_Func OpenSession = fCI->ui.OpenSession; if (!OpenSession) { sta=LOCERR_NOTIMP; } else { sta = OpenSession(fCI,&newSessionH,aSelector,aSessionName); if (sta==LOCERR_OK) { newSession=[[SyncSession alloc] initWithCI:fCI andSessionHandle:newSessionH]; } } if (aErrP) *aErrP=sta; return newSession; } // Settings access - (SettingsKey *)newOpenKeyByPath:(cAppCharP)aPath withMode:(uInt16)aMode err:(TSyError *)aErrP { TSyError sta=LOCERR_OK; KeyH newKeyH=NULL; SettingsKey *newKey=nil; // no object by default OpenKeyByPath_Func OpenKeyByPath = fCI->ui.OpenKeyByPath; if (!OpenKeyByPath) { sta=LOCERR_NOTIMP; } else { sta = OpenKeyByPath(fCI,&newKeyH,NULL,aPath,aMode); if (sta==LOCERR_OK) { newKey=[[SettingsKey alloc] initWithCI:fCI andKeyHandle:newKeyH]; DBGNSLOG(@"Opened settings key %s : SettingsKey object = 0x%lX",aPath,(intptr_t)newKey); } } if (aErrP) *aErrP=sta; return newKey; } // newOpenKeyByPath @end // SyncEnginelibsynthesis-3.4.0.47.1/src/sysync_SDK/sdk_sources_cocoa/dbplugin_cocoa.h000066400000000000000000000121141226375725500262740ustar00rootroot00000000000000/* * File: dbplugin_cocoa.h * * Author: Lukas Zeller (luz@plan44.ch) * * Wrapper for writing Synthesis SyncML engine database plugins as * Cocoa objects. * * Copyright (c) 2008-2011 by Synthesis AG + plan44.ch * */ #import #import #include "sync_include.h" // include general SDK definitions #include "sync_dbapidef.h" // include the interface file and utilities #include "SDK_util.h" // include SDK utilities #include "sync_dbapi.h" #include "SettingsKey.h" // macro used to wrap namespace around entry points for use in statically linked plugins (as needed for iPhoneOS) // in this case, .m files are not directly compiled, but included from a mydatastore_plugin_wrapper.mm C++ file // which also defines DB_PLUGIN_NAMESPACE first. // To compile the common baseclass for all statically linked plugins, dbplugin_cocoa.m must be compiled with // PLUGIN_BASECLASS defined (done by dbplugin_cocoa_wrapper.mm) #ifndef PLUGIN_BASECLASS #ifdef DB_PLUGIN_NAMESPACE #define PLUGIN_NS_BEGIN namespace DB_PLUGIN_NAMESPACE { #define PLUGIN_NS_END } #define PLUGIN_NS_USE(sym) DB_PLUGIN_NAMESPACE::sym #else #define PLUGIN_NS_BEGIN #define PLUGIN_NS_END #define PLUGIN_NS_USE(sym) sym #endif #endif // not PLUGIN_BASECLASS // forward @class CocoaPluginModule; @class CocoaPluginDB; #ifndef PLUGIN_BASECLASS PLUGIN_NS_BEGIN // Prototype for the module factory C function // (must be implemented in a subclass) CocoaPluginModule *newPluginModule( cAppCharP aModuleName, cAppCharP aSubName, cAppCharP aContextName, DB_Callback aCB ); PLUGIN_NS_END #endif // not PLUGIN_BASECLASS // Wrapper for the module context @interface CocoaPluginModule : NSObject { // names NSString *fModuleName; NSString *fSubName; NSString *fContextName; // the callback structure DB_Callback fCB; } - (id)initWithModuleName:(cAppCharP)aModuleName subName:(cAppCharP)aSubName contextName:(cAppCharP)aContextName andCB:(DB_Callback)aCB; - (void)dealloc; // module level debug routines - (void)debugOut:(NSString *)aMessage; - (void)debugOutExotic:(NSString *)aMessage; - (void)debugBlockWithTag:(NSString *)aTag andDescription:(NSString *)aDesc andAttrs:(NSString *)aAttrs; - (void)debugEndBlockWithTag:(NSString *)aTag; - (void)debugEndThread; // access to CB - (DB_Callback)getCB; // Module identification + (int)buildNumber; - (cAppCharP)manufacturerName; - (cAppCharP)moduleName; // Module capabilities - (bool)hasDeleteSyncSet; // parsing plugin parameters - (TSyError)pluginParams:(cAppCharP)aParams fromEngineVersion:(long)aEngineVersion; // creating database context in this module's context - (CocoaPluginDB *)newPluginDBWithName:(cAppCharP)aName deviceKey:(cAppCharP)aDeviceKey userKey:(cAppCharP)aUserKey andCB:(DB_Callback)aCB; @end // CocoaPluginModule // Wrapper for the DB context @interface CocoaPluginDB : NSObject { // names NSString *fContextName; NSString *fDeviceKey; NSString *fUserKey; // link to module context CocoaPluginModule *fModule; // the callback structure DB_Callback fCB; } - (id)initWithName:(cAppCharP)aName inModule:(CocoaPluginModule *)aModule deviceKey:(cAppCharP)aDeviceKey userKey:(cAppCharP)aUserKey andCB:(DB_Callback)aCB; - (void)dealloc; // DB level debug routines - (void)debugOut:(NSString *)aMessage; - (void)debugOutExotic:(NSString *)aMessage; - (void)debugBlockWithTag:(NSString *)aTag andDescription:(NSString *)aDesc andAttrs:(NSString *)aAttrs; - (void)debugEndBlockWithTag:(NSString *)aTag; - (void)debugEndThread; // access to CB - (DB_Callback)getCB; // open a key from root level (same functionality as SyncEngine's newOpenKeyByPath - (SettingsKey *)newOpenKeyByPath:(cAppCharP)aPath withMode:(uInt16)aMode err:(TSyError *)aErrP; // access to session key - (SettingsKey *)newOpenSessionKeyWithMode:(uInt16)aMode err:(TSyError *)aErrP; // Context features - (sInt32)contextSupportRules:(cAppCharP)aContextRules; - (sInt32)filterSupportRules:(cAppCharP)aFilterRules; // Thread change alert - (void)threadMayChangeNow; // Read phase - (TSyError)startDataReadWithLastToken:(cAppCharP)aLastToken andResumeToken:(cAppCharP)aResumeToken; - (TSyError)readNextItemAsKey:(SettingsKey *)aItemKey itemIdP:(NSString **)aItemIdP parentIdP:(NSString **)aParentIdP statusP:(sInt32 *)aStatusP isFirst:(BOOL)aFirst; - (TSyError)readItemAsKey:(SettingsKey *)aItemKey itemID:(NSString *)aItemID parentID:(NSString *)aParentID; - (TSyError)endDataRead; // Write phase - (TSyError)startDataWrite; - (TSyError)insertItemAsKey:(SettingsKey *)aItemKey parentID:(NSString *)aParentID newItemIdP:(NSString **)aNewItemIdP; - (TSyError)finalizeLocalID:(NSString **)aLocIDP; - (TSyError)updateItemAsKey:(SettingsKey *)aItemKey itemIdP:(NSString **)aItemIdP parentIdP:(NSString **)aParentIdP; - (TSyError)moveItem:(NSString *)aItemID fromParentID:(NSString *)aParentID toNewParent:(NSString *)aNewParentID; - (TSyError)deleteItem:(NSString *)aItemID parentID:(NSString *)aParentID; - (TSyError)deleteSyncSet; - (TSyError)endDataWriteWithSuccess:(BOOL)aSuccess andNewToken:(NSString **)aNewTokenP; @end // CocoaPluginDB libsynthesis-3.4.0.47.1/src/sysync_SDK/sdk_sources_cocoa/dbplugin_cocoa.m000066400000000000000000000744311226375725500263130ustar00rootroot00000000000000/* * File: dbplugin_cocoa.m * * Author: Lukas Zeller (luz@plan44.ch) * * Wrapper for writing Synthesis SyncML engine database plugins as * Cocoa objects. * * Copyright (c) 2008-2009 by Synthesis AG * */ #include "dbplugin_cocoa.h" #define BuildNumber 0 // User defined build number #define MyDB "cocoaPlugin" /* example debug name */ #define MY_ID 42 /* example datastore context */ #define STRLEN 80 /* Max length of local string copies */ // Note: in case this source file is included from a wrapper .mm file or a static-only plugin.mm // to create statically linked plugins, only the part of the source which is specific to the // C++ namespace of the plugin is compiled, but not the ObjC part which is common to all // statically linked plugins and this must only exist once. // - A defined DB_PLUGIN_NAMESPACE here means that file generates C++ glue in a namespace for // linking the plugin statically // - A defined PLUGIN_BASECLASS here means that file generates only the ObjC baseclass // that must exist only once with statically linked plugins and is shared among all plugins. #ifndef DB_PLUGIN_NAMESPACE /* Show all fields/variables of item represented by aItemKey */ static void ShowFields(DB_Callback cb, KeyH aItemKey) { const stringSize maxstr = 128; appChar fnam[maxstr]; appChar fval[maxstr]; appChar ftz[maxstr]; uInt16 fvaltype; uInt16 farrsize; uInt16 arridx; bool fisarray; uIntArch valsize; TSyError err; uInt32 valueID,nameFlag,typeFlag,arrszFlag,tznamFlag; // set desired time mode cb->ui.SetTimeMode(cb, aItemKey, TMODE_LINEARTIME+TMODE_FLAG_FLOATING); // get flags that can be combined with valueID to get attributes of a value nameFlag = cb->ui.GetValueID(cb, aItemKey, VALNAME_FLAG VALSUFF_NAME); typeFlag = cb->ui.GetValueID(cb, aItemKey, VALNAME_FLAG VALSUFF_TYPE); arrszFlag = cb->ui.GetValueID(cb, aItemKey, VALNAME_FLAG VALSUFF_ARRSZ); tznamFlag = cb->ui.GetValueID(cb, aItemKey, VALNAME_FLAG VALSUFF_TZNAME); // iterate over all fields // - start iteration valueID = cb->ui.GetValueID(cb, aItemKey, VALNAME_FIRST); while (valueID != KEYVAL_ID_UNKNOWN && valueID != KEYVAL_NO_ID) { // get field name err = cb->ui.GetValueByID(cb, aItemKey, valueID + nameFlag, 0, VALTYPE_TEXT, fnam, maxstr, &valsize ); // get field type err = cb->ui.GetValueByID(cb, aItemKey, valueID + typeFlag, 0, VALTYPE_INT16, &fvaltype, sizeof(fvaltype), &valsize ); // check if array, and if array, get number of elements err = cb->ui.GetValueByID(cb, aItemKey, valueID + arrszFlag, 0, VALTYPE_INT16, &farrsize, sizeof(farrsize), &valsize ); fisarray = err==LOCERR_OK; if (!fisarray) { // single value err = cb->ui.GetValueByID(cb, aItemKey, valueID, 0, VALTYPE_TEXT, fval, maxstr, &valsize); if (err==LOCERR_OK) { if (fvaltype==VALTYPE_TIME64) { // for timestamps, get time zone name as well cb->ui.GetValueByID(cb, aItemKey, valueID+tznamFlag, 0, VALTYPE_TEXT, ftz, maxstr, &valsize); DEBUG_(cb, "- %-20s (VALTYPE=%2hd) = %s timezone=%s",fnam,fvaltype,fval,ftz); } else DEBUG_(cb, "- %-20s (VALTYPE=%2hd) = '%s'",fnam,fvaltype,fval); } else DEBUG_(cb, "- %-20s (VALTYPE=%2hd) : No value, error=%hd",fnam,fvaltype,err); } else { // array DEBUG_(cb, "- %-20s (VALTYPE=%2d) = Array with %d elements",fnam,fvaltype,farrsize); // show elements for (arridx=0; arridxui.GetValueByID(cb, aItemKey, valueID, arridx, VALTYPE_TEXT, fval, maxstr, &valsize); if (err==LOCERR_OK) { if (fvaltype==VALTYPE_TIME64) { // for timestamps, get time zone name as well cb->ui.GetValueByID(cb, aItemKey, valueID+tznamFlag, arridx, VALTYPE_TEXT, ftz, maxstr, &valsize); DEBUG_(cb, " %20s[%3hd] = %s timezone=%s",fnam,arridx,fval,ftz); } else DEBUG_(cb, " %20s[%3hd] = '%s'",fnam,arridx,fval); } else DEBUG_(cb, " %20s[%3hd] : No value, error=%hd",fnam,arridx,err); } } // next value valueID = cb->ui.GetValueID(cb, aItemKey, VALNAME_NEXT); } // while more values } /* ShowFields */ // MODULE CONTEXT // ============== @implementation CocoaPluginModule - (id)initWithModuleName:(cAppCharP)aModuleName subName:(cAppCharP)aSubName contextName:(cAppCharP)aContextName andCB:(DB_Callback)aCB { if ([super init]!=nil) { // save the name strings fModuleName = [NSString stringWithCString:aModuleName encoding:NSUTF8StringEncoding]; fSubName = [NSString stringWithCString:aSubName encoding:NSUTF8StringEncoding]; fContextName = [NSString stringWithCString:aContextName encoding:NSUTF8StringEncoding]; // save the callback structure fCB = aCB; } return self; } - (void)dealloc { // done [super dealloc]; } // access to CB - (DB_Callback)getCB { return fCB; } // Debug routines for plugin to send messages into SyncML engine log - (void)debugOut:(NSString *)aMessage { DB_DebugPuts_Func DB_DebugPuts = fCB->DB_DebugPuts; if (!DB_DebugPuts) return; // not implemented, no output DB_DebugPuts(fCB->callbackRef, [aMessage cStringUsingEncoding:NSUTF8StringEncoding]); } - (void)debugOutExotic:(NSString *)aMessage { DB_DebugPuts_Func DB_DebugExotic = fCB->DB_DebugExotic; if (!DB_DebugExotic) return; // not implemented, no output DB_DebugExotic(fCB->callbackRef, [aMessage cStringUsingEncoding:NSUTF8StringEncoding]); } - (void)debugBlockWithTag:(NSString *)aTag andDescription:(NSString *)aDesc andAttrs:(NSString *)aAttrs { DB_DebugBlock_Func DB_DebugBlock = fCB->DB_DebugBlock; if (!DB_DebugBlock) return; // not implemented, no output DB_DebugBlock(fCB->callbackRef, [aTag cStringUsingEncoding:NSUTF8StringEncoding], [aDesc cStringUsingEncoding:NSUTF8StringEncoding], [aAttrs cStringUsingEncoding:NSUTF8StringEncoding] ); } - (void)debugEndBlockWithTag:(NSString *)aTag { DB_DebugEndBlock_Func DB_DebugEndBlock = fCB->DB_DebugEndBlock; if (!DB_DebugEndBlock) return; // not implemented, no output DB_DebugEndBlock(fCB->callbackRef,[aTag cStringUsingEncoding:NSUTF8StringEncoding]); } - (void)debugEndThread { DB_DebugEndThread_Func DB_DebugEndThread = fCB->DB_DebugEndThread; if (!DB_DebugEndThread) return; // not implemented, no output DB_DebugEndThread(fCB->callbackRef); } // Dummy implementation - should be overridden in actual DB implementations in subclass + (int)buildNumber { return 0; } - (cAppCharP)manufacturerName { return "Synthesis AG"; } - (cAppCharP)moduleName { return "CocoaPluginModule"; } - (bool)hasDeleteSyncSet { return NO; // not by default, implementation must explicitly override if it really supports it } - (TSyError)pluginParams:(cAppCharP)aParams fromEngineVersion:(long)aEngineVersion { // base class supports no params // - return error if we get any params here return aParams==NULL || *aParams==0 ? LOCERR_OK : LOCERR_CFGPARSE; } // factory method for creating database context wrappers - (CocoaPluginDB *)newPluginDBWithName:(cAppCharP)aName deviceKey:(cAppCharP)aDeviceKey userKey:(cAppCharP)aUserKey andCB:(DB_Callback)aCB { // subclasses must return a subclass of CocoaPluginDB // this base class cannot return a db plugin return nil; } @end // CocoaPluginModule #endif // not defined DB_PLUGIN_NAMESPACE // Entry points // ------------ #ifndef PLUGIN_BASECLASS PLUGIN_NS_BEGIN // create the module context TSyError Module_CreateContext( CContext *aContext, cAppCharP aModuleName, cAppCharP aSubName, cAppCharP aContextName, DB_Callback aCB ) { // call factory C function to return suitable ObjC wrapper object // (which must be a derivate of CocoaPluginModule) // Note: for statically linked plugins, the factory method must exist in the plugin's namespace CocoaPluginModule *module = PLUGIN_NS_USE(newPluginModule)(aModuleName,aSubName,aContextName,aCB); if (module==nil) return DB_Full; // cannot allocate module context // return the object pointer as module context *aContext= (CContext)module; return LOCERR_OK; } // Module_CreateContext // Get the plug-in's version number CVersion Module_Version(CContext mContext) { // This must work with mContext=0 // (therefore, buildNumber is a class method!) return Plugin_Version([CocoaPluginModule buildNumber]); } // Module_Version // Get the plug-in's capabilities TSyError Module_Capabilities(CContext mContext, char** mCapabilities) { CocoaPluginModule *module = (CocoaPluginModule *)mContext; char s[512]; // create local string sprintf( s, CA_Platform ":%s\n" // platform DLL_Info "\n" // DLL_Info CA_MinVersion ":1.4.0.0\n" // Min version (we need >=1.4.x because of AsKey) CA_Manufacturer ":%s\n" // Manufacturer CA_Description ":%s\n" // Module description CA_ItemAsKey ":true\n" // Note: cocoa based plugins ALWAYS use AsKey mechanism CA_DeleteSyncSet ":%s\n" // Only return yes if the implementation is non-dummy! Just having the routine is not enough! Plugin_Session ":no\n" // no session routines Plugin_DS_Admin ":no\n" // no datastore admin Plugin_DS_Data_Str ":no\n" // no datastore string routines (i.e. only AsKey) Plugin_DS_Adapt ":no\n", // no datastore adapt // the variable parts in the above MyPlatform(), [module manufacturerName], [module moduleName], [module hasDeleteSyncSet] ? "yes" : "no" ); // create return string *mCapabilities= StrAlloc( s ); return LOCERR_OK; } // Module_Capabilities // provide plugin parameters TSyError Module_PluginParams(CContext mContext, cAppCharP mConfigParams, CVersion engineVersion) { CocoaPluginModule *module = (CocoaPluginModule *)mContext; return [module pluginParams:mConfigParams fromEngineVersion:engineVersion]; } // Module_PluginParams // Dispose memory created in the module context and passed back to engine void Module_DisposeObj(CContext mContext, void* memory) { StrDispose(memory); } // Module_DisposeObj // Delete module context TSyError Module_DeleteContext(CContext mContext) { CocoaPluginModule *module = (CocoaPluginModule *)mContext; // context ends, release the ObjC wrapper object [module release]; return LOCERR_OK; } // Module_DeleteContext // SESSION CONTEXT (dummy, no wrapper implemented) // Create a context for a new session TSyError Session_CreateContext(CContext *sContext, cAppCharP sessionName, DB_Callback sCB) { *sContext = 0; // Dummy context return LOCERR_OK; } // Session_CreateContext /* TSyError Session_CheckDevice( long sContext, cAppCharP aDeviceID, char** sDevKey, char** nonce ) { // session context not implemented return LOCERR_NOTIMP; } // Session_CheckDevice TSyError Session_GetNonce(long sContext, char** nonce) { // session context not implemented return LOCERR_NOTIMP; } // Session_GetNonce TSyError Session_SaveNonce(long sContext, cAppCharP nonce) { // session context not implemented return LOCERR_NOTIMP; } // Session_SaveNonce TSyError Session_SaveDeviceInfo(long sContext, cAppCharP aDeviceInfo) { // session context not implemented return LOCERR_NOTIMP; } // Session_SaveDeviceInfo // Get the plugin's DB time TSyError Session_GetDBTime(long sContext, char** currentDBTime) { // plugin does not have separate time *currentDBTime= NULL; return DB_NotFound; } // Session_GetDBTime int Session_PasswordMode(long sContext) { // dummy; session context not implemented return Password_MD5_Nonce_IN; } // Session_PasswordMode TSyError Session_Login( long sContext, cAppCharP sUsername, char** sPassword, char** sUsrKey ) { // session context not implemented return LOCERR_NOTIMP; } // Session_Login TSyError Session_Logout(long sContext) { // session context not implemented return LOCERR_NOTIMP; } // Session_Logout void Session_DisposeObj(long sContext, void* memory) { // Should never be called (we have no session!), but if, it's a string to dispose StrDispose(memory); } // Session_DisposeObj void Session_ThreadMayChangeNow(long sContext) { // NOP } // Session_ThreadMayChangeNow void Session_DispItems(long sContext, bool allFields, cAppCharP specificItem) { // NOP } // Session_DispItems */ // Delete a session context TSyError Session_DeleteContext(CContext sContext) { // NOP because we don't have a session context return LOCERR_OK; } // Session_DeleteContext PLUGIN_NS_END #endif // not PLUGIN_BASECLASS #ifndef DB_PLUGIN_NAMESPACE // DATABASE CONTEXT // ================ @implementation CocoaPluginDB - (id)initWithName:(cAppCharP)aName inModule:(CocoaPluginModule *)aModule deviceKey:(cAppCharP)aDeviceKey userKey:(cAppCharP)aUserKey andCB:(DB_Callback)aCB { if ([super init]!=nil) { // save the name strings fContextName = [NSString stringWithCString:aName encoding:NSUTF8StringEncoding]; fDeviceKey = [NSString stringWithCString:aDeviceKey encoding:NSUTF8StringEncoding]; fUserKey = [NSString stringWithCString:aUserKey encoding:NSUTF8StringEncoding]; // save the callback structure fCB = aCB; // save the link to the module wrapper object fModule = [aModule retain]; // keep it as long as I live myself } return self; } - (void)dealloc { // release the module [fModule release]; // done [super dealloc]; } // access to CB - (DB_Callback)getCB { return fCB; } // Debug routines for plugin to send messages into SyncML engine log - (void)debugOut:(NSString *)aMessage { DB_DebugPuts_Func DB_DebugPuts = fCB->DB_DebugPuts; if (!DB_DebugPuts) return; // not implemented, no output DB_DebugPuts(fCB->callbackRef, [aMessage cStringUsingEncoding:NSUTF8StringEncoding]); } - (void)debugOutExotic:(NSString *)aMessage { DB_DebugPuts_Func DB_DebugExotic = fCB->DB_DebugExotic; if (!DB_DebugExotic) return; // not implemented, no output DB_DebugExotic(fCB->callbackRef, [aMessage cStringUsingEncoding:NSUTF8StringEncoding]); } - (void)debugBlockWithTag:(NSString *)aTag andDescription:(NSString *)aDesc andAttrs:(NSString *)aAttrs { DB_DebugBlock_Func DB_DebugBlock = fCB->DB_DebugBlock; if (!DB_DebugBlock) return; // not implemented, no output DB_DebugBlock(fCB->callbackRef, [aTag cStringUsingEncoding:NSUTF8StringEncoding], [aDesc cStringUsingEncoding:NSUTF8StringEncoding], [aAttrs cStringUsingEncoding:NSUTF8StringEncoding] ); } - (void)debugEndBlockWithTag:(NSString *)aTag { DB_DebugEndBlock_Func DB_DebugEndBlock = fCB->DB_DebugEndBlock; if (!DB_DebugEndBlock) return; // not implemented, no output DB_DebugEndBlock(fCB->callbackRef,[aTag cStringUsingEncoding:NSUTF8StringEncoding]); } - (void)debugEndThread { DB_DebugEndThread_Func DB_DebugEndThread = fCB->DB_DebugEndThread; if (!DB_DebugEndThread) return; // not implemented, no output DB_DebugEndThread(fCB->callbackRef); } // open a session key - (SettingsKey *)newOpenSessionKeyWithMode:(uInt16)aMode err:(TSyError *)aErrP { TSyError sta=LOCERR_OK; KeyH newKeyH=NULL; SettingsKey *newKey=nil; // no object by default OpenSessionKey_Func OpenSessionKey = fCB->ui.OpenSessionKey; if (!OpenSessionKey) { sta=LOCERR_NOTIMP; } else { // get session key of current session (implicit for DB plugins) sta = OpenSessionKey(fCB,NULL,&newKeyH,aMode); if (sta==LOCERR_OK) { newKey=[[SettingsKey alloc] initWithCI:fCB andKeyHandle:newKeyH]; } } if (aErrP) *aErrP=sta; return newKey; } // open a key from root level - (SettingsKey *)newOpenKeyByPath:(cAppCharP)aPath withMode:(uInt16)aMode err:(TSyError *)aErrP { TSyError sta=LOCERR_OK; KeyH newKeyH=NULL; SettingsKey *newKey=nil; // no object by default OpenKeyByPath_Func OpenKeyByPath = fCB->ui.OpenKeyByPath; if (!OpenKeyByPath) { sta=LOCERR_NOTIMP; } else { // open from root (no parent) sta = OpenKeyByPath(fCB,&newKeyH,NULL,aPath,aMode); if (sta==LOCERR_OK) { newKey=[[SettingsKey alloc] initWithCI:fCB andKeyHandle:newKeyH]; DBGNSLOG(@"Opened settings key %s : SettingsKey object = 0x%lX",aPath,(intptr_t)newKey); } } if (aErrP) *aErrP=sta; return newKey; } // newOpenKeyByPath // Dummy implementation - should be overridden in actual DB implementations in subclass - (sInt32)contextSupportRules:(cAppCharP)aContextRules { // none supported return 0; } - (sInt32)filterSupportRules:(cAppCharP)aFilterRules { // none supported return 0; } - (void)threadMayChangeNow { // NOP } - (TSyError)startDataReadWithLastToken:(cAppCharP)aLastToken andResumeToken:(cAppCharP)aResumeToken { return LOCERR_NOTIMP; } - (TSyError)readNextItemAsKey:(SettingsKey *)aItemKey itemIdP:(NSString **)aItemIdP parentIdP:(NSString **)aParentIdP statusP:(sInt32 *)aStatusP isFirst:(BOOL)aFirst { // empty data set *aStatusP = ReadNextItem_EOF; return LOCERR_OK; } - (TSyError)readItemAsKey:(SettingsKey *)aItemKey itemID:(NSString *)aItemID parentID:(NSString *)aParentID { return DB_NotFound; } - (TSyError)endDataRead { return LOCERR_OK; } - (TSyError)startDataWrite { return LOCERR_OK; } - (TSyError)insertItemAsKey:(SettingsKey *)aItemKey parentID:(NSString *)aParentID newItemIdP:(NSString **)aNewItemIdP { return DB_Fatal; } - (TSyError)finalizeLocalID:(NSString **)aLocIDP { return DB_NoContent; // no finalisation } - (TSyError)updateItemAsKey:(SettingsKey *)aItemKey itemIdP:(NSString **)aItemIdP parentIdP:(NSString **)aParentIdP { return DB_NotFound; } - (TSyError)moveItem:(NSString *)aItemID fromParentID:(NSString *)aParentID toNewParent:(NSString *)aNewParentID { return LOCERR_NOTIMP; } - (TSyError)deleteItem:(NSString *)aItemID parentID:(NSString *)aParentID { return DB_NotFound; } - (TSyError)deleteSyncSet { return LOCERR_NOTIMP; // means: deleting items not implemented (but may still do some work, like erasing all address book groups) } - (TSyError)endDataWriteWithSuccess:(BOOL)aSuccess andNewToken:(NSString **)aNewTokenP { return LOCERR_OK; } @end // CocoaPluginDB #endif // not defined DB_PLUGIN_NAMESPACE // Entry points // ------------ #ifndef PLUGIN_BASECLASS PLUGIN_NS_BEGIN // Create a database context TSyError CreateContext( CContext* aContext, cAppCharP aContextName, DB_Callback aCB, cAppCharP sDevKey, cAppCharP sUsrKey ) { // retrieve the module context from aCB if (!aCB) return DB_Fatal; CocoaPluginModule *module = (CocoaPluginModule *)aCB->mContext; if (module==nil) return DB_Fatal; // let module context create the DB context CocoaPluginDB *db = [module newPluginDBWithName:aContextName deviceKey:sDevKey userKey:sUsrKey andCB:aCB ]; if (db==nil) return DB_Full; // return the object pointer as context *aContext= (CContext)db; return LOCERR_OK; } // CreateContext void DispItems(CContext aContext, bool allFields, cAppCharP specificItem) { // NOP } // DispItems uInt32 ContextSupport(CContext aContext, cAppCharP aContextRules) { CocoaPluginDB *db = (CocoaPluginDB *)aContext; return [db contextSupportRules:aContextRules]; } // ContextSupport uInt32 FilterSupport(CContext aContext, cAppCharP aFilterRules) { CocoaPluginDB *db = (CocoaPluginDB *)aContext; return [db filterSupportRules:aFilterRules]; } // FilterSupport // Dispose memory created in the DB context and passed back to engine void DisposeObj(CContext aContext, void* memory) { StrDispose(memory); } // DisposeObj /* TSyError LoadAdminData( CContext aContext, cAppCharP aLocalDB, cAppCharP aRemoteDB, const char** adminData ) { // DB admin not implemeted return LOCERR_NOTIMP; } // LoadAdminData TSyError SaveAdminData(CContext aContext, cAppCharP adminData) { // DB admin not implemeted return LOCERR_NOTIMP; } // SaveAdminData bool ReadNextMapItem(CContext aContext, MapID mID, bool aFirst) { // DB admin not implemeted return false; } // ReadNextMapItem TSyError InsertMapItem(CContext aContext, MapID mID) { // DB admin not implemeted return LOCERR_NOTIMP; } // InsertMapItem TSyError UpdateMapItem(CContext aContext, MapID mID) { // DB admin not implemeted return LOCERR_NOTIMP; } // UpdateMapItem TSyError DeleteMapItem(CContext aContext, MapID mID) { // DB admin not implemeted return LOCERR_NOTIMP; } // DeleteMapItem */ void ThreadMayChangeNow(CContext aContext) { CocoaPluginDB *db = (CocoaPluginDB *)aContext; return [db threadMayChangeNow]; } // ThreadMayChangeNow void WriteLogData(CContext aContext, cAppCharP logData) { // not implemented } // WriteLogData /* TSyError AdaptItem( CContext aContext, char** aItemData1, char** aItemData2, char** aLocalVars, int aIdentifier ) { return LOCERR_NOTIMP; } // AdaptItem */ TSyError StartDataRead( CContext aContext, cAppCharP lastToken, cAppCharP resumeToken ) { CocoaPluginDB *db = (CocoaPluginDB *)aContext; return [db startDataReadWithLastToken:lastToken andResumeToken:resumeToken]; } // StartDataRead /* TSyError ReadNextItem( CContext aContext, ItemID aID, char** aItemData, int* aStatus, bool aFirst ) { // Only XXXAsKey variants are supported return LOCERR_NOTIMP; } // ReadNextItem */ TSyError ReadNextItemAsKey( CContext aContext, ItemID aID, KeyH aItemKey, sInt32 *aStatus, bool aFirst ) { CocoaPluginDB *db = (CocoaPluginDB *)aContext; // pool for strings used in this call NSAutoreleasePool *itemPool = [[NSAutoreleasePool alloc] init]; // prepare strings NSString *itemID = nil; NSString *parentID = nil; // create wrapper for the item key SettingsKey *itemKey = [[SettingsKey alloc] initWithCI:[db getCB] andKeyHandle:aItemKey]; // call the method TSyError sta = [db readNextItemAsKey:itemKey itemIdP:&itemID parentIdP:&parentID statusP:aStatus isFirst:aFirst]; // detach the key wrapper from the handle (must NOT close it when disposing the wrapper now!) [itemKey detachFromKeyHandle]; // release the wrapper [itemKey release]; if (sta==LOCERR_OK && itemID) { // convert back IDs aID->item = StrAlloc([itemID cStringUsingEncoding:NSUTF8StringEncoding]); if (parentID) aID->parent= StrAlloc([parentID cStringUsingEncoding:NSUTF8StringEncoding]); } // release the pool [itemPool release]; // return the status return sta; } // ReadNextItemAsKey /* TSyError ReadItem(CContext aContext, ItemID aID, char** aItemData) { // Only XXXAsKey variants are supported return LOCERR_NOTIMP; } // ReadItem */ TSyError ReadItemAsKey( CContext aContext, cItemID aID, KeyH aItemKey ) { CocoaPluginDB *db = (CocoaPluginDB *)aContext; // pool for strings used in this call NSAutoreleasePool *itemPool = [[NSAutoreleasePool alloc] init]; // prepare strings NSString *itemID = [NSString stringWithCString:aID->item encoding:NSUTF8StringEncoding]; NSString *parentID = nil; if (aID->parent) parentID = [NSString stringWithCString:aID->parent encoding:NSUTF8StringEncoding]; // create wrapper for the item key SettingsKey *itemKey = [[SettingsKey alloc] initWithCI:[db getCB] andKeyHandle:aItemKey]; // call the method TSyError sta = [db readItemAsKey:itemKey itemID:itemID parentID:parentID]; // detach the key wrapper from the handle (must NOT close it when disposing the wrapper now!) [itemKey detachFromKeyHandle]; // release the wrapper [itemKey release]; // release the pool [itemPool release]; // return the status return sta; } // ReadItemAsKey TSyError ReadBlob( CContext aContext, cItemID aID, cAppCharP aBlobID, void** aBlkPtr, unsigned long* aBlkSize, unsigned long* aTotSize, bool aFirst, bool* aLast ) { // Not yet implemeted return LOCERR_NOTIMP; } // ReadBlob TSyError EndDataRead(CContext aContext) { CocoaPluginDB *db = (CocoaPluginDB *)aContext; return [db endDataRead]; } // EndDataRead TSyError StartDataWrite(CContext aContext) { CocoaPluginDB *db = (CocoaPluginDB *)aContext; return [db startDataWrite]; } // StartDataWrite /* TSyError InsertItem(CContext aContext, cAppCharP aItemData, ItemID newID) { // Only XXXAsKey variants are supported return LOCERR_NOTIMP; } // InsertItem */ TSyError InsertItemAsKey(CContext aContext, KeyH aItemKey, ItemID newID) { CocoaPluginDB *db = (CocoaPluginDB *)aContext; // pool for strings used in this call NSAutoreleasePool *itemPool = [[NSAutoreleasePool alloc] init]; // prepare strings // - item ID will be returned NSString *newItemID = nil; // - parent ID might be set from caller NSString *parentID = nil; if (newID->parent) parentID = [NSString stringWithCString:newID->parent encoding:NSUTF8StringEncoding]; // create wrapper for the item key SettingsKey *itemKey = [[SettingsKey alloc] initWithCI:[db getCB] andKeyHandle:aItemKey]; // call the method TSyError sta = [db insertItemAsKey:itemKey parentID:parentID newItemIdP:&newItemID]; // detach the key wrapper from the handle (must NOT close it when disposing the wrapper now!) [itemKey detachFromKeyHandle]; // release the wrapper [itemKey release]; // convert back new ID if (sta==LOCERR_OK && newItemID) { newID->item = StrAlloc([newItemID cStringUsingEncoding:NSUTF8StringEncoding]); } // release the pool [itemPool release]; // return the status return sta; } // InsertItemAsKey TSyError FinalizeLocalID(CContext aContext, cItemID aID, ItemID updID) { CocoaPluginDB *db = (CocoaPluginDB *)aContext; // pool for strings used in this call NSAutoreleasePool *itemPool = [[NSAutoreleasePool alloc] init]; // prepare strings NSString *itemID = [NSString stringWithCString:aID->item encoding:NSUTF8StringEncoding]; // call the method TSyError sta = [db finalizeLocalID:&itemID]; // convert back new ID if (sta==LOCERR_OK && updID) { sta = DB_Error; if (itemID) { const char *s = [itemID cStringUsingEncoding:NSUTF8StringEncoding]; if (s) { // actually converted ID back updID->item = StrAlloc([itemID cStringUsingEncoding:NSUTF8StringEncoding]); sta = LOCERR_OK; } } } // release the pool [itemPool release]; // return the status return sta; } // FinalizeLocalID /* TSyError UpdateItem( CContext aContext, cAppCharP aItemData, const ItemID aID, ItemID updID ) { // Only XXXAsKey variants are supported return LOCERR_NOTIMP; } // UpdateItem */ TSyError UpdateItemAsKey(CContext aContext, KeyH aItemKey, cItemID aID, ItemID updID) { CocoaPluginDB *db = (CocoaPluginDB *)aContext; // pool for strings used in this call NSAutoreleasePool *itemPool = [[NSAutoreleasePool alloc] init]; // prepare strings NSString *itemID = [NSString stringWithCString:aID->item encoding:NSUTF8StringEncoding]; NSString *parentID = nil; if (aID->parent) parentID = [NSString stringWithCString:aID->parent encoding:NSUTF8StringEncoding]; // create wrapper for the item key SettingsKey *itemKey = [[SettingsKey alloc] initWithCI:[db getCB] andKeyHandle:aItemKey]; // call the method TSyError sta = [db updateItemAsKey:itemKey itemIdP:&itemID parentIdP:&parentID]; // detach the key wrapper from the handle (must NOT close it when disposing the wrapper now!) [itemKey detachFromKeyHandle]; // release the wrapper [itemKey release]; // convert back new ID if (sta==LOCERR_OK) { updID->item = StrAlloc([itemID cStringUsingEncoding:NSUTF8StringEncoding]); if (parentID) updID->parent= StrAlloc([parentID cStringUsingEncoding:NSUTF8StringEncoding]); } // release the pool [itemPool release]; // return the status return sta; } // UpdateItemAsKey TSyError MoveItem(CContext aContext, cItemID aID, cAppCharP newParentID) { CocoaPluginDB *db = (CocoaPluginDB *)aContext; // pool for strings used in this call NSAutoreleasePool *itemPool = [[NSAutoreleasePool alloc] init]; // prepare strings NSString *itemID = [NSString stringWithCString:aID->item encoding:NSUTF8StringEncoding]; NSString *parentID = [NSString stringWithCString:aID->parent encoding:NSUTF8StringEncoding]; NSString *newParentIDStr = [NSString stringWithCString:newParentID encoding:NSUTF8StringEncoding]; // call the method TSyError sta = [db moveItem:itemID fromParentID:parentID toNewParent:newParentIDStr]; // release the pool [itemPool release]; // return the status return sta; } // MoveItem TSyError DeleteSyncSet(CContext aContext) { CocoaPluginDB *db = (CocoaPluginDB *)aContext; // pool for strings used in this call NSAutoreleasePool *itemPool = [[NSAutoreleasePool alloc] init]; // call the method TSyError sta = [db deleteSyncSet]; // release the pool [itemPool release]; // return the status return sta; } // DeleteSyncSet TSyError DeleteItem(CContext aContext, cItemID aID) { CocoaPluginDB *db = (CocoaPluginDB *)aContext; // pool for strings used in this call NSAutoreleasePool *itemPool = [[NSAutoreleasePool alloc] init]; // prepare strings NSString *itemID = [NSString stringWithCString:aID->item encoding:NSUTF8StringEncoding]; NSString *parentID = nil; if (aID->parent) parentID = [NSString stringWithCString:aID->parent encoding:NSUTF8StringEncoding]; // call the method TSyError sta = [db deleteItem:itemID parentID:parentID]; // release the pool [itemPool release]; // return the status return sta; } // DeleteItem TSyError WriteBlob( CContext aContext, cItemID aID, cAppCharP aBlobID, void* aBlkPtr, unsigned long aBlkSize, unsigned long aTotSize, bool aFirst, bool aLast ) { // Not yet implemeted return LOCERR_NOTIMP; } // WriteBlob TSyError DeleteBlob(CContext aContext, cItemID aID, cAppCharP aBlobID) { // Not yet implemeted return LOCERR_NOTIMP; } // DeleteBlob TSyError EndDataWrite(CContext aContext, bool success, char** newToken) { CocoaPluginDB *db = (CocoaPluginDB *)aContext; // pool for strings used in this call NSAutoreleasePool *itemPool = [[NSAutoreleasePool alloc] init]; // prepare token string NSString *newTokenString = nil; // call the method TSyError sta = [db endDataWriteWithSuccess:success andNewToken:&newTokenString]; // convert back new token if (sta==LOCERR_OK && newTokenString && newToken) { *newToken = StrAlloc([newTokenString cStringUsingEncoding:NSUTF8StringEncoding]); } // release the pool [itemPool release]; // return the status return sta; } // EndDataWrite // Delete DB context TSyError DeleteContext(CContext mContext) { CocoaPluginDB *db = (CocoaPluginDB *)mContext; // context ends, release the ObjC wrapper object [db release]; return LOCERR_OK; } // DeleteContext PLUGIN_NS_END #endif // not PLUGIN_BASECLASS /* eof */ libsynthesis-3.4.0.47.1/src/sysync_SDK/sdk_sources_cocoa/dbplugin_cocoa_wrapper.mm000066400000000000000000000011521226375725500302160ustar00rootroot00000000000000/* * File: dbplugin_cocoa_wrapper.mm * * Author: Lukas Zeller (luz@plan44.ch) * * Wrapper for creating statically linked base class for cocoa database plugins * * Copyright (c) 2010 by Synthesis AG * */ // this makes dbplugin_cocoa.m compile as baseclass without C/C++ entry points for common use // for all statically linked plugins. // C++ entry points must be created for each plugin in separate namespaces - this is done by // compiling the plugin wrappers or static-only .mm plugin source files #define PLUGIN_BASECLASS 1 // the generic cocoa interface #include "dbplugin_cocoa.m" /* eof */libsynthesis-3.4.0.47.1/src/sysync_SDK/sdk_sources_cocoa/target_options.h000066400000000000000000000004351226375725500263700ustar00rootroot00000000000000// target_options.h for SySync SDK files that need it #ifndef TARGET_OPTIONS #define TARGET_OPTIONS // Sysync related debug #define SYDEBUG 2 #if DEBUG // general app debug #define CONSOLEDBG 1 #else // no output to console, please #undef CONSOLEDBG #endif #endif // TARGET_OPTIONSlibsynthesis-3.4.0.47.1/src/sysync_ios.xcodeproj/000077500000000000000000000000001226375725500216315ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/sysync_ios.xcodeproj/project.pbxproj000066400000000000000000005726411226375725500247240ustar00rootroot00000000000000// !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 46; objects = { /* Begin PBXBuildFile section */ ED16A68E14B9B4E400F24032 /* platform_DLL.h in Headers */ = {isa = PBXBuildFile; fileRef = ED16A68D14B9B4E400F24032 /* platform_DLL.h */; }; ED16A68F14B9B4E400F24032 /* platform_DLL.h in Headers */ = {isa = PBXBuildFile; fileRef = ED16A68D14B9B4E400F24032 /* platform_DLL.h */; }; ED43DAD70E014BC9000A1E5C /* configfiles.mm in Sources */ = {isa = PBXBuildFile; fileRef = ED43DAD60E014BC9000A1E5C /* configfiles.mm */; }; ED4B5EB111523AAB00ECB4A5 /* sysync_utils.h in Headers */ = {isa = PBXBuildFile; fileRef = ED4B5E9511523AAB00ECB4A5 /* sysync_utils.h */; }; ED4B5EB211523AAB00ECB4A5 /* sysync_utils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED4B5E9611523AAB00ECB4A5 /* sysync_utils.cpp */; }; ED4B5EB311523AAB00ECB4A5 /* syncexception.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED4B5E9711523AAB00ECB4A5 /* syncexception.cpp */; }; ED4B5EB611523AAB00ECB4A5 /* lineartime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED4B5E9A11523AAB00ECB4A5 /* lineartime.cpp */; }; ED4B5EB711523AAB00ECB4A5 /* san.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED4B5E9B11523AAB00ECB4A5 /* san.cpp */; }; ED4B5EB811523AAB00ECB4A5 /* san.h in Headers */ = {isa = PBXBuildFile; fileRef = ED4B5E9C11523AAB00ECB4A5 /* san.h */; }; ED4B5EB911523AAB00ECB4A5 /* sysync_md5.h in Headers */ = {isa = PBXBuildFile; fileRef = ED4B5E9D11523AAB00ECB4A5 /* sysync_md5.h */; }; ED4B5EBA11523AAB00ECB4A5 /* sysync_md5.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED4B5E9E11523AAB00ECB4A5 /* sysync_md5.cpp */; }; ED4B5EBB11523AAB00ECB4A5 /* sysync_b64.h in Headers */ = {isa = PBXBuildFile; fileRef = ED4B5E9F11523AAB00ECB4A5 /* sysync_b64.h */; }; ED4B5EBC11523AAB00ECB4A5 /* sysync_b64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED4B5EA011523AAB00ECB4A5 /* sysync_b64.cpp */; }; ED4B5EBD11523AAB00ECB4A5 /* syncexception.h in Headers */ = {isa = PBXBuildFile; fileRef = ED4B5EA111523AAB00ECB4A5 /* syncexception.h */; }; ED4B5EBE11523AAB00ECB4A5 /* lineartime.h in Headers */ = {isa = PBXBuildFile; fileRef = ED4B5EA211523AAB00ECB4A5 /* lineartime.h */; }; ED4B5ECD11523AAB00ECB4A5 /* sysync_utils.h in Headers */ = {isa = PBXBuildFile; fileRef = ED4B5E9511523AAB00ECB4A5 /* sysync_utils.h */; }; ED4B5ECE11523AAB00ECB4A5 /* sysync_utils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED4B5E9611523AAB00ECB4A5 /* sysync_utils.cpp */; }; ED4B5ECF11523AAB00ECB4A5 /* syncexception.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED4B5E9711523AAB00ECB4A5 /* syncexception.cpp */; }; ED4B5ED211523AAB00ECB4A5 /* lineartime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED4B5E9A11523AAB00ECB4A5 /* lineartime.cpp */; }; ED4B5ED311523AAB00ECB4A5 /* san.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED4B5E9B11523AAB00ECB4A5 /* san.cpp */; }; ED4B5ED411523AAB00ECB4A5 /* san.h in Headers */ = {isa = PBXBuildFile; fileRef = ED4B5E9C11523AAB00ECB4A5 /* san.h */; }; ED4B5ED511523AAB00ECB4A5 /* sysync_md5.h in Headers */ = {isa = PBXBuildFile; fileRef = ED4B5E9D11523AAB00ECB4A5 /* sysync_md5.h */; }; ED4B5ED611523AAB00ECB4A5 /* sysync_md5.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED4B5E9E11523AAB00ECB4A5 /* sysync_md5.cpp */; }; ED4B5ED711523AAB00ECB4A5 /* sysync_b64.h in Headers */ = {isa = PBXBuildFile; fileRef = ED4B5E9F11523AAB00ECB4A5 /* sysync_b64.h */; }; ED4B5ED811523AAB00ECB4A5 /* sysync_b64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED4B5EA011523AAB00ECB4A5 /* sysync_b64.cpp */; }; ED4B5ED911523AAB00ECB4A5 /* syncexception.h in Headers */ = {isa = PBXBuildFile; fileRef = ED4B5EA111523AAB00ECB4A5 /* syncexception.h */; }; ED4B5EDA11523AAB00ECB4A5 /* lineartime.h in Headers */ = {isa = PBXBuildFile; fileRef = ED4B5EA211523AAB00ECB4A5 /* lineartime.h */; }; ED55691F10768FAA0008C22F /* enginemodulebase.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3D3D0D8195A800470E44 /* enginemodulebase.h */; }; ED55692010768FAA0008C22F /* engine_defs.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3D3E0D8195A800470E44 /* engine_defs.h */; }; ED55692110768FAA0008C22F /* generic_types.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3D3F0D8195A800470E44 /* generic_types.h */; }; ED55692210768FAA0008C22F /* syerror.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3D400D8195A800470E44 /* syerror.h */; }; ED55692310768FAA0008C22F /* admindata.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3D960D81968D00470E44 /* admindata.h */; }; ED55692410768FAA0008C22F /* blobs.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3D980D81968D00470E44 /* blobs.h */; }; ED55692510768FAA0008C22F /* dbitem.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3D9A0D81968D00470E44 /* dbitem.h */; }; ED55692610768FAA0008C22F /* sync_include.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3D810D81968D00470E44 /* sync_include.h */; }; ED55692710768FAA0008C22F /* sync_dbapidef.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3D820D81968D00470E44 /* sync_dbapidef.h */; }; ED55692810768FAA0008C22F /* sync_dbapi.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3D830D81968D00470E44 /* sync_dbapi.h */; }; ED55692910768FAA0008C22F /* SDK_util.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3D840D81968D00470E44 /* SDK_util.h */; }; ED55692A10768FAA0008C22F /* SDK_support.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3D860D81968D00470E44 /* SDK_support.h */; }; ED55692B10768FAA0008C22F /* sync_dbapiconnect.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3D7E0D81968D00470E44 /* sync_dbapiconnect.h */; }; ED55692C10768FAA0008C22F /* plugindb.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BAB0D81A0FE00F9A79C /* plugindb.h */; }; ED55692D10768FAA0008C22F /* plugindb_precomp.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BAC0D81A0FE00F9A79C /* plugindb_precomp.h */; }; ED55692E10768FAA0008C22F /* dbapi.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3D790D81968D00470E44 /* dbapi.h */; }; ED55692F10768FAA0008C22F /* dbapi_include.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3D7B0D81968D00470E44 /* dbapi_include.h */; }; ED55693010768FAA0008C22F /* pluginapiagent.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3D750D81968D00470E44 /* pluginapiagent.h */; }; ED55693110768FAA0008C22F /* pluginapids.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3D770D81968D00470E44 /* pluginapids.h */; }; ED55693210768FAA0008C22F /* DLL_interface.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3D7C0D81968D00470E44 /* DLL_interface.h */; }; ED55693310768FAA0008C22F /* odbcdb.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3D6D0D81968D00470E44 /* odbcdb.h */; }; ED55693410768FAA0008C22F /* odbcdb_precomp.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3D6E0D81968D00470E44 /* odbcdb_precomp.h */; }; ED55693510768FAA0008C22F /* odbcapiagent.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3D6F0D81968D00470E44 /* odbcapiagent.h */; }; ED55693610768FAA0008C22F /* odbcapids.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3D710D81968D00470E44 /* odbcapids.h */; }; ED55693810768FAA0008C22F /* clientengine_custom.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3DBA0D81969F00470E44 /* clientengine_custom.h */; }; ED55693910768FAA0008C22F /* clientengine_custom_precomp.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3DBB0D81969F00470E44 /* clientengine_custom_precomp.h */; }; ED55693A10768FAA0008C22F /* clientengine_custom_Base.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3DBC0D81969F00470E44 /* clientengine_custom_Base.h */; }; ED55693B10768FAA0008C22F /* platform_pipe.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3DDB0D8196BB00470E44 /* platform_pipe.h */; }; ED55693C10768FAA0008C22F /* platform_exec.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3DE30D8196BB00470E44 /* platform_exec.h */; }; ED55693D10768FAA0008C22F /* platform_headers.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3DE50D8196BB00470E44 /* platform_headers.h */; }; ED55693E10768FAA0008C22F /* platform_time.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3DE60D8196BB00470E44 /* platform_time.h */; }; ED55693F10768FAA0008C22F /* binfile.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3DEA0D8196BB00470E44 /* binfile.h */; }; ED55694010768FAA0008C22F /* configfiles.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3DEB0D8196BB00470E44 /* configfiles.h */; }; ED55694210768FAA0008C22F /* platform_thread.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3DED0D8196BB00470E44 /* platform_thread.h */; }; ED55694310768FAA0008C22F /* platform_mutex.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3DEE0D8196BB00470E44 /* platform_mutex.h */; }; ED55694410768FAA0008C22F /* platform_file.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3DEF0D8196BB00470E44 /* platform_file.h */; }; ED55694510768FAA0008C22F /* profiling.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3DF00D8196BB00470E44 /* profiling.h */; }; ED55694610768FAA0008C22F /* engine_client_precomp.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3DFF0D8196CA00470E44 /* engine_client_precomp.h */; }; ED55694710768FAA0008C22F /* engine_client.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3E000D8196CA00470E44 /* engine_client.h */; }; ED55694810768FAA0008C22F /* engineclientbase.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3E020D8196CA00470E44 /* engineclientbase.h */; }; ED55694910768FAA0008C22F /* wsm.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806C3B0D81A89E00F9A79C /* wsm.h */; }; ED55694A10768FAA0008C22F /* sml.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BC70D81A5AD00F9A79C /* sml.h */; }; ED55694B10768FAA0008C22F /* smldef.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BC80D81A5AD00F9A79C /* smldef.h */; }; ED55694C10768FAA0008C22F /* smldevinfdtd.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BC90D81A5AD00F9A79C /* smldevinfdtd.h */; }; ED55694D10768FAA0008C22F /* smldtd.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BCA0D81A5AD00F9A79C /* smldtd.h */; }; ED55694E10768FAA0008C22F /* smlerr.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BCB0D81A5AD00F9A79C /* smlerr.h */; }; ED55694F10768FAA0008C22F /* smlmetinfdtd.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BCC0D81A5AD00F9A79C /* smlmetinfdtd.h */; }; ED55695010768FAA0008C22F /* liblock.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BBC0D81A58800F9A79C /* liblock.h */; }; ED55695110768FAA0008C22F /* libmem.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BBD0D81A58800F9A79C /* libmem.h */; }; ED55695210768FAA0008C22F /* libstr.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BBE0D81A58800F9A79C /* libstr.h */; }; ED55695310768FAA0008C22F /* libutil.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BBF0D81A58800F9A79C /* libutil.h */; }; ED55695410768FAA0008C22F /* mgr.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BD80D81A5D500F9A79C /* mgr.h */; }; ED55695510768FAA0008C22F /* mgrutil.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BD90D81A5D500F9A79C /* mgrutil.h */; }; ED55695610768FAA0008C22F /* xltdeccom.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BE60D81A5F400F9A79C /* xltdeccom.h */; }; ED55695710768FAA0008C22F /* xltdecwbxml.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BE80D81A5F400F9A79C /* xltdecwbxml.h */; }; ED55695810768FAA0008C22F /* xltdevinf.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BEB0D81A5F400F9A79C /* xltdevinf.h */; }; ED55695910768FAA0008C22F /* xltenccom.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BEE0D81A5F400F9A79C /* xltenccom.h */; }; ED55695A10768FAA0008C22F /* xltencwbxml.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BF00D81A5F400F9A79C /* xltencwbxml.h */; }; ED55695B10768FAA0008C22F /* xltencxml.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BF20D81A5F400F9A79C /* xltencxml.h */; }; ED55695C10768FAA0008C22F /* xltmetinf.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BF40D81A5F400F9A79C /* xltmetinf.h */; }; ED55695D10768FAA0008C22F /* xlttags.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BF60D81A5F400F9A79C /* xlttags.h */; }; ED55695E10768FAA0008C22F /* xlttagtbl.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BF70D81A5F400F9A79C /* xlttagtbl.h */; }; ED55695F10768FAA0008C22F /* xltutilstack.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BF90D81A5F400F9A79C /* xltutilstack.h */; }; ED55696010768FAA0008C22F /* xltdec.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BFB0D81A5F400F9A79C /* xltdec.h */; }; ED55696110768FAA0008C22F /* xltenc.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BFC0D81A5F400F9A79C /* xltenc.h */; }; ED55696210768FAA0008C22F /* binfilebase.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3E900D81970700470E44 /* binfilebase.h */; }; ED55696310768FAA0008C22F /* binfileimplclient.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3E920D81970700470E44 /* binfileimplclient.h */; }; ED55696410768FAA0008C22F /* binfileimplds.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3E940D81970700470E44 /* binfileimplds.h */; }; ED55696510768FAA0008C22F /* engineentry.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3E960D81970700470E44 /* engineentry.h */; }; ED55696610768FAA0008C22F /* engineinterface.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3E980D81970700470E44 /* engineinterface.h */; }; ED55696710768FAA0008C22F /* configelement.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3E990D81970700470E44 /* configelement.h */; }; ED55696810768FAA0008C22F /* customimplds.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3E9B0D81970700470E44 /* customimplds.h */; }; ED55696910768FAA0008C22F /* customimplagent.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3E9D0D81970700470E44 /* customimplagent.h */; }; ED55696A10768FAA0008C22F /* dataobjtype.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3E9F0D81970700470E44 /* dataobjtype.h */; }; ED55696B10768FAA0008C22F /* debuglogger.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EA10D81970700470E44 /* debuglogger.h */; }; ED55696C10768FAA0008C22F /* iso8601.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EA30D81970700470E44 /* iso8601.h */; }; ED55696D10768FAA0008C22F /* itemfield.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EA50D81970700470E44 /* itemfield.h */; }; ED55696F10768FAA0008C22F /* localengineds.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EA90D81970700470E44 /* localengineds.h */; }; ED55697010768FAA0008C22F /* mimediritemtype.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EAB0D81970700470E44 /* mimediritemtype.h */; }; ED55697110768FAA0008C22F /* multifielditem.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EAD0D81970700470E44 /* multifielditem.h */; }; ED55697210768FAA0008C22F /* multifielditemtype.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EAF0D81970700470E44 /* multifielditemtype.h */; }; ED55697310768FAA0008C22F /* remotedatastore.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EB10D81970700470E44 /* remotedatastore.h */; }; ED55697410768FAA0008C22F /* rrules.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EB30D81970700470E44 /* rrules.h */; }; ED55697610768FAA0008C22F /* scriptcontext.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EB70D81970700470E44 /* scriptcontext.h */; }; ED55697710768FAA0008C22F /* simpleitem.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EB90D81970700470E44 /* simpleitem.h */; }; ED55697810768FAA0008C22F /* smltk_precomp.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EBB0D81970700470E44 /* smltk_precomp.h */; }; ED55697910768FAA0008C22F /* smltk_precomp_xpt.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EBC0D81970700470E44 /* smltk_precomp_xpt.h */; }; ED55697A10768FAA0008C22F /* stringutils.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EBD0D81970700470E44 /* stringutils.h */; }; ED55697B10768FAA0008C22F /* superdatastore.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EBF0D81970700470E44 /* superdatastore.h */; }; ED55697C10768FAA0008C22F /* syncappbase.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EC10D81970700470E44 /* syncappbase.h */; }; ED55697D10768FAA0008C22F /* syncclientbase.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EC50D81970700470E44 /* syncclientbase.h */; }; ED55697E10768FAA0008C22F /* synccommand.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EC70D81970700470E44 /* synccommand.h */; }; ED55697F10768FAA0008C22F /* syncdatastore.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EC90D81970700470E44 /* syncdatastore.h */; }; ED55698110768FAA0008C22F /* syncitem.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3ECD0D81970700470E44 /* syncitem.h */; }; ED55698210768FAA0008C22F /* syncitemtype.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3ECF0D81970700470E44 /* syncitemtype.h */; }; ED55698310768FAA0008C22F /* syncsession.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3ED30D81970700470E44 /* syncsession.h */; }; ED55698410768FAA0008C22F /* syserial.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3ED70D81970700470E44 /* syserial.h */; }; ED55698510768FAA0008C22F /* sysync.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3ED90D81970700470E44 /* sysync.h */; }; ED55698710768FAA0008C22F /* sysync_crc16.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EDC0D81970700470E44 /* sysync_crc16.h */; }; ED55698810768FAA0008C22F /* sysync_globs.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EDE0D81970700470E44 /* sysync_globs.h */; }; ED55698A10768FAA0008C22F /* sysync_precomp.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EE10D81970700470E44 /* sysync_precomp.h */; }; ED55698B10768FAA0008C22F /* sysync_precomp_xpt.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EE20D81970700470E44 /* sysync_precomp_xpt.h */; }; ED55698C10768FAA0008C22F /* stdlogicagent.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EE30D81970700470E44 /* stdlogicagent.h */; }; ED55698D10768FAA0008C22F /* stdlogicds.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EE50D81970700470E44 /* stdlogicds.h */; }; ED55698F10768FAA0008C22F /* textitemtype.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EE90D81970700470E44 /* textitemtype.h */; }; ED55699010768FAA0008C22F /* textprofile.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EEB0D81970700470E44 /* textprofile.h */; }; ED55699110768FAA0008C22F /* timezones.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EED0D81970700470E44 /* timezones.h */; }; ED55699210768FAA0008C22F /* uiapi.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EF00D81970700470E44 /* uiapi.h */; }; ED55699310768FAA0008C22F /* vcalendaritemtype.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EF10D81970700470E44 /* vcalendaritemtype.h */; }; ED55699410768FAA0008C22F /* vcarditemtype.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EF30D81970700470E44 /* vcarditemtype.h */; }; ED55699510768FAA0008C22F /* vtimezone.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EF50D81970700470E44 /* vtimezone.h */; }; ED55699610768FAA0008C22F /* tz_table.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EF70D81970700470E44 /* tz_table.h */; }; ED55699710768FAA0008C22F /* zlib.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3F4A0D81971700470E44 /* zlib.h */; }; ED55699810768FAA0008C22F /* zutil.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3F4B0D81971700470E44 /* zutil.h */; }; ED55699910768FAA0008C22F /* xmlparse.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3F460D81971700470E44 /* xmlparse.h */; }; ED55699A10768FAA0008C22F /* pcre_config_macosx.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3F420D81971700470E44 /* pcre_config_macosx.h */; }; ED55699B10768FAA0008C22F /* pcre.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3F430D81971700470E44 /* pcre.h */; }; ED55699C10768FAA0008C22F /* sysync_debug.h in Headers */ = {isa = PBXBuildFile; fileRef = ED55B6960DDDBC43001657F6 /* sysync_debug.h */; }; ED55699D10768FAA0008C22F /* sync_uiapi.h in Headers */ = {isa = PBXBuildFile; fileRef = ED55B6990DDDBCBC001657F6 /* sync_uiapi.h */; }; ED55699E10768FAA0008C22F /* xmltok.h in Headers */ = {isa = PBXBuildFile; fileRef = ED55B69C0DDDBD0A001657F6 /* xmltok.h */; }; ED55699F10768FAA0008C22F /* xmldef.h in Headers */ = {isa = PBXBuildFile; fileRef = ED55B6A90DDDBD4E001657F6 /* xmldef.h */; }; ED5569A010768FAA0008C22F /* ascii.h in Headers */ = {isa = PBXBuildFile; fileRef = ED55B6AF0DDDBDD9001657F6 /* ascii.h */; }; ED5569A110768FAA0008C22F /* asciitab.h in Headers */ = {isa = PBXBuildFile; fileRef = ED55B6B00DDDBDD9001657F6 /* asciitab.h */; }; ED5569A210768FAA0008C22F /* iasciitab.h in Headers */ = {isa = PBXBuildFile; fileRef = ED55B6B10DDDBDD9001657F6 /* iasciitab.h */; }; ED5569A310768FAA0008C22F /* latin1tab.h in Headers */ = {isa = PBXBuildFile; fileRef = ED55B6B20DDDBDD9001657F6 /* latin1tab.h */; }; ED5569A410768FAA0008C22F /* nametab.h in Headers */ = {isa = PBXBuildFile; fileRef = ED55B6B30DDDBDD9001657F6 /* nametab.h */; }; ED5569A510768FAA0008C22F /* utf8tab.h in Headers */ = {isa = PBXBuildFile; fileRef = ED55B6B40DDDBDD9001657F6 /* utf8tab.h */; }; ED5569A610768FAA0008C22F /* xmlrole.h in Headers */ = {isa = PBXBuildFile; fileRef = ED55B6B50DDDBDD9001657F6 /* xmlrole.h */; }; ED5569AA10768FAA0008C22F /* mimedirprofile.h in Headers */ = {isa = PBXBuildFile; fileRef = EDAC08210F179E78005E9AE2 /* mimedirprofile.h */; }; ED5569AB10768FAA0008C22F /* syncagent.h in Headers */ = {isa = PBXBuildFile; fileRef = EDE194C61074A04F00439216 /* syncagent.h */; }; ED5569AE10768FAA0008C22F /* sync_dbapi_text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3D940D81968D00470E44 /* sync_dbapi_text.cpp */; }; ED5569AF10768FAA0008C22F /* enginemodulebase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3D3C0D8195A800470E44 /* enginemodulebase.cpp */; }; ED5569B010768FAA0008C22F /* admindata.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3D970D81968D00470E44 /* admindata.cpp */; }; ED5569B110768FAA0008C22F /* blobs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3D990D81968D00470E44 /* blobs.cpp */; }; ED5569B210768FAA0008C22F /* dbitem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3D9B0D81968D00470E44 /* dbitem.cpp */; }; ED5569B310768FAA0008C22F /* SDK_util.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3D850D81968D00470E44 /* SDK_util.c */; }; ED5569B410768FAA0008C22F /* SDK_support.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3D870D81968D00470E44 /* SDK_support.cpp */; }; ED5569B510768FAA0008C22F /* sync_dbapiconnect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3D7F0D81968D00470E44 /* sync_dbapiconnect.cpp */; }; ED5569B910768FAA0008C22F /* dbapi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3D7A0D81968D00470E44 /* dbapi.cpp */; }; ED5569BA10768FAA0008C22F /* pluginapiagent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3D760D81968D00470E44 /* pluginapiagent.cpp */; }; ED5569BB10768FAA0008C22F /* pluginapids.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3D780D81968D00470E44 /* pluginapids.cpp */; }; ED5569BC10768FAA0008C22F /* DLL_interface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3D7D0D81968D00470E44 /* DLL_interface.cpp */; }; ED5569BD10768FAA0008C22F /* odbcapiagent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3D700D81968D00470E44 /* odbcapiagent.cpp */; }; ED5569BE10768FAA0008C22F /* odbcapids.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3D720D81968D00470E44 /* odbcapids.cpp */; }; ED5569BF10768FAA0008C22F /* clientengine_custom_Base.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3DBD0D81969F00470E44 /* clientengine_custom_Base.cpp */; }; ED5569C010768FAA0008C22F /* platform_pipe.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3DDC0D8196BB00470E44 /* platform_pipe.c */; }; ED5569C110768FAA0008C22F /* platform_thread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3DDD0D8196BB00470E44 /* platform_thread.cpp */; }; ED5569C210768FAA0008C22F /* platform_mutex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3DDE0D8196BB00470E44 /* platform_mutex.cpp */; }; ED5569C310768FAA0008C22F /* platform_file.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3DDF0D8196BB00470E44 /* platform_file.cpp */; }; ED5569C510768FAA0008C22F /* platform_exec.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3DE40D8196BB00470E44 /* platform_exec.c */; }; ED5569C610768FAA0008C22F /* platform_time.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3DE70D8196BB00470E44 /* platform_time.cpp */; }; ED5569C710768FAA0008C22F /* profiling.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3DE80D8196BB00470E44 /* profiling.cpp */; }; ED5569C810768FAA0008C22F /* binfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3DE90D8196BB00470E44 /* binfile.cpp */; }; ED5569C910768FAA0008C22F /* sysyncinit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3DF10D8196BB00470E44 /* sysyncinit.cpp */; }; ED5569CA10768FAA0008C22F /* engineclientbase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3E010D8196CA00470E44 /* engineclientbase.cpp */; }; ED5569CB10768FAA0008C22F /* liblock.c in Sources */ = {isa = PBXBuildFile; fileRef = ED806BB70D81A58800F9A79C /* liblock.c */; }; ED5569CC10768FAA0008C22F /* libmem.c in Sources */ = {isa = PBXBuildFile; fileRef = ED806BB80D81A58800F9A79C /* libmem.c */; }; ED5569CD10768FAA0008C22F /* libstr.c in Sources */ = {isa = PBXBuildFile; fileRef = ED806BB90D81A58800F9A79C /* libstr.c */; }; ED5569CE10768FAA0008C22F /* libutil.c in Sources */ = {isa = PBXBuildFile; fileRef = ED806BBA0D81A58800F9A79C /* libutil.c */; }; ED5569CF10768FAA0008C22F /* mgr.c in Sources */ = {isa = PBXBuildFile; fileRef = ED806BD10D81A5D500F9A79C /* mgr.c */; }; ED5569D010768FAA0008C22F /* mgrcmdbuilder.c in Sources */ = {isa = PBXBuildFile; fileRef = ED806BD20D81A5D500F9A79C /* mgrcmdbuilder.c */; }; ED5569D110768FAA0008C22F /* mgrcmddispatcher.c in Sources */ = {isa = PBXBuildFile; fileRef = ED806BD30D81A5D500F9A79C /* mgrcmddispatcher.c */; }; ED5569D210768FAA0008C22F /* mgrinstancelist.c in Sources */ = {isa = PBXBuildFile; fileRef = ED806BD40D81A5D500F9A79C /* mgrinstancelist.c */; }; ED5569D310768FAA0008C22F /* mgrinstancemgr.c in Sources */ = {isa = PBXBuildFile; fileRef = ED806BD50D81A5D500F9A79C /* mgrinstancemgr.c */; }; ED5569D410768FAA0008C22F /* mgrutil.c in Sources */ = {isa = PBXBuildFile; fileRef = ED806BD60D81A5D500F9A79C /* mgrutil.c */; }; ED5569D510768FAA0008C22F /* xltdec.c in Sources */ = {isa = PBXBuildFile; fileRef = ED806BE50D81A5F400F9A79C /* xltdec.c */; }; ED5569D610768FAA0008C22F /* xltdecwbxml.c in Sources */ = {isa = PBXBuildFile; fileRef = ED806BE70D81A5F400F9A79C /* xltdecwbxml.c */; }; ED5569D710768FAA0008C22F /* xltdecxml.c in Sources */ = {isa = PBXBuildFile; fileRef = ED806BE90D81A5F400F9A79C /* xltdecxml.c */; }; ED5569D810768FAA0008C22F /* xltdevinf.c in Sources */ = {isa = PBXBuildFile; fileRef = ED806BEA0D81A5F400F9A79C /* xltdevinf.c */; }; ED5569D910768FAA0008C22F /* xltenc.c in Sources */ = {isa = PBXBuildFile; fileRef = ED806BEC0D81A5F400F9A79C /* xltenc.c */; }; ED5569DA10768FAA0008C22F /* xltenccom.c in Sources */ = {isa = PBXBuildFile; fileRef = ED806BED0D81A5F400F9A79C /* xltenccom.c */; }; ED5569DB10768FAA0008C22F /* xltencwbxml.c in Sources */ = {isa = PBXBuildFile; fileRef = ED806BEF0D81A5F400F9A79C /* xltencwbxml.c */; }; ED5569DC10768FAA0008C22F /* xltencxml.c in Sources */ = {isa = PBXBuildFile; fileRef = ED806BF10D81A5F400F9A79C /* xltencxml.c */; }; ED5569DD10768FAA0008C22F /* xltmetinf.c in Sources */ = {isa = PBXBuildFile; fileRef = ED806BF30D81A5F400F9A79C /* xltmetinf.c */; }; ED5569DE10768FAA0008C22F /* xlttags.c in Sources */ = {isa = PBXBuildFile; fileRef = ED806BF50D81A5F400F9A79C /* xlttags.c */; }; ED5569DF10768FAA0008C22F /* xltutilstack.c in Sources */ = {isa = PBXBuildFile; fileRef = ED806BF80D81A5F400F9A79C /* xltutilstack.c */; }; ED5569E010768FAA0008C22F /* binfilebase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3E8F0D81970700470E44 /* binfilebase.cpp */; }; ED5569E110768FAA0008C22F /* binfileimplclient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3E910D81970700470E44 /* binfileimplclient.cpp */; }; ED5569E210768FAA0008C22F /* binfileimplds.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3E930D81970700470E44 /* binfileimplds.cpp */; }; ED5569E310768FAA0008C22F /* engineentry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3E950D81970700470E44 /* engineentry.cpp */; }; ED5569E410768FAA0008C22F /* engineinterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3E970D81970700470E44 /* engineinterface.cpp */; }; ED5569E510768FAA0008C22F /* configelement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3E9A0D81970700470E44 /* configelement.cpp */; }; ED5569E610768FAA0008C22F /* customimplds.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3E9C0D81970700470E44 /* customimplds.cpp */; }; ED5569E710768FAA0008C22F /* customimplagent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3E9E0D81970700470E44 /* customimplagent.cpp */; }; ED5569E810768FAA0008C22F /* dataobjtype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EA00D81970700470E44 /* dataobjtype.cpp */; }; ED5569E910768FAA0008C22F /* debuglogger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EA20D81970700470E44 /* debuglogger.cpp */; }; ED5569EA10768FAA0008C22F /* iso8601.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EA40D81970700470E44 /* iso8601.cpp */; }; ED5569EB10768FAA0008C22F /* itemfield.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EA60D81970700470E44 /* itemfield.cpp */; }; ED5569ED10768FAA0008C22F /* localengineds.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EAA0D81970700470E44 /* localengineds.cpp */; }; ED5569EE10768FAA0008C22F /* mimediritemtype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EAC0D81970700470E44 /* mimediritemtype.cpp */; }; ED5569EF10768FAA0008C22F /* multifielditem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EAE0D81970700470E44 /* multifielditem.cpp */; }; ED5569F010768FAA0008C22F /* multifielditemtype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EB00D81970700470E44 /* multifielditemtype.cpp */; }; ED5569F110768FAA0008C22F /* remotedatastore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EB20D81970700470E44 /* remotedatastore.cpp */; }; ED5569F210768FAA0008C22F /* rrules.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EB40D81970700470E44 /* rrules.cpp */; }; ED5569F410768FAA0008C22F /* scriptcontext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EB80D81970700470E44 /* scriptcontext.cpp */; }; ED5569F510768FAA0008C22F /* simpleitem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EBA0D81970700470E44 /* simpleitem.cpp */; }; ED5569F610768FAA0008C22F /* stringutils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EBE0D81970700470E44 /* stringutils.cpp */; }; ED5569F710768FAA0008C22F /* superdatastore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EC00D81970700470E44 /* superdatastore.cpp */; }; ED5569F810768FAA0008C22F /* syncappbase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EC20D81970700470E44 /* syncappbase.cpp */; }; ED5569F910768FAA0008C22F /* syncclientbase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EC60D81970700470E44 /* syncclientbase.cpp */; }; ED5569FA10768FAA0008C22F /* synccommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EC80D81970700470E44 /* synccommand.cpp */; }; ED5569FB10768FAA0008C22F /* syncdatastore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3ECA0D81970700470E44 /* syncdatastore.cpp */; }; ED5569FD10768FAA0008C22F /* syncitem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3ECE0D81970700470E44 /* syncitem.cpp */; }; ED5569FE10768FAA0008C22F /* syncitemtype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3ED00D81970700470E44 /* syncitemtype.cpp */; }; ED5569FF10768FAA0008C22F /* syncsession.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3ED40D81970700470E44 /* syncsession.cpp */; }; ED556A0210768FAA0008C22F /* sysync_crc16.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EDD0D81970700470E44 /* sysync_crc16.cpp */; }; ED556A0410768FAA0008C22F /* stdlogicagent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EE40D81970700470E44 /* stdlogicagent.cpp */; }; ED556A0510768FAA0008C22F /* stdlogicds.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EE60D81970700470E44 /* stdlogicds.cpp */; }; ED556A0710768FAA0008C22F /* textitemtype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EEA0D81970700470E44 /* textitemtype.cpp */; }; ED556A0810768FAA0008C22F /* textprofile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EEC0D81970700470E44 /* textprofile.cpp */; }; ED556A0910768FAA0008C22F /* timezones.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EEE0D81970700470E44 /* timezones.cpp */; }; ED556A0A10768FAA0008C22F /* uiapi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EEF0D81970700470E44 /* uiapi.cpp */; }; ED556A0B10768FAA0008C22F /* vcalendaritemtype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EF20D81970700470E44 /* vcalendaritemtype.cpp */; }; ED556A0C10768FAA0008C22F /* vcarditemtype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EF40D81970700470E44 /* vcarditemtype.cpp */; }; ED556A0D10768FAA0008C22F /* vtimezone.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EF60D81970700470E44 /* vtimezone.cpp */; }; ED556A0E10768FAA0008C22F /* infback.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F4C0D81971700470E44 /* infback.c */; }; ED556A0F10768FAA0008C22F /* gzio.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F4D0D81971700470E44 /* gzio.c */; }; ED556A1010768FAA0008C22F /* deflate.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F4E0D81971700470E44 /* deflate.c */; }; ED556A1110768FAA0008C22F /* uncompr.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F4F0D81971700470E44 /* uncompr.c */; }; ED556A1210768FAA0008C22F /* trees.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F500D81971700470E44 /* trees.c */; }; ED556A1310768FAA0008C22F /* inftrees.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F510D81971700470E44 /* inftrees.c */; }; ED556A1410768FAA0008C22F /* inflate.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F520D81971700470E44 /* inflate.c */; }; ED556A1510768FAA0008C22F /* inffast.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F530D81971700470E44 /* inffast.c */; }; ED556A1610768FAA0008C22F /* zutil.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F540D81971700470E44 /* zutil.c */; }; ED556A1710768FAA0008C22F /* crc32.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F550D81971700470E44 /* crc32.c */; }; ED556A1810768FAA0008C22F /* compress.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F560D81971700470E44 /* compress.c */; }; ED556A1910768FAA0008C22F /* adler32.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F570D81971700470E44 /* adler32.c */; }; ED556A1A10768FAA0008C22F /* xmlparse.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F450D81971700470E44 /* xmlparse.c */; }; ED556A1B10768FAA0008C22F /* xmltok.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F470D81971700470E44 /* xmltok.c */; }; ED556A1C10768FAA0008C22F /* xmlrole.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F480D81971700470E44 /* xmlrole.c */; }; ED556A1D10768FAA0008C22F /* pcre_ord2utf8.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F300D81971700470E44 /* pcre_ord2utf8.c */; }; ED556A1E10768FAA0008C22F /* pcre_chartables.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F310D81971700470E44 /* pcre_chartables.c */; }; ED556A1F10768FAA0008C22F /* pcre_compile.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F320D81971700470E44 /* pcre_compile.c */; }; ED556A2010768FAA0008C22F /* pcre_config.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F330D81971700470E44 /* pcre_config.c */; }; ED556A2110768FAA0008C22F /* pcre_dfa_exec.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F340D81971700470E44 /* pcre_dfa_exec.c */; }; ED556A2210768FAA0008C22F /* pcre_exec.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F350D81971700470E44 /* pcre_exec.c */; }; ED556A2310768FAA0008C22F /* pcre_fullinfo.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F360D81971700470E44 /* pcre_fullinfo.c */; }; ED556A2410768FAA0008C22F /* pcre_get.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F370D81971700470E44 /* pcre_get.c */; }; ED556A2510768FAA0008C22F /* pcre_globals.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F380D81971700470E44 /* pcre_globals.c */; }; ED556A2610768FAA0008C22F /* pcre_info.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F390D81971700470E44 /* pcre_info.c */; }; ED556A2710768FAA0008C22F /* pcre_newline.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F3A0D81971700470E44 /* pcre_newline.c */; }; ED556A2810768FAA0008C22F /* pcre_refcount.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F3B0D81971700470E44 /* pcre_refcount.c */; }; ED556A2910768FAA0008C22F /* pcre_study.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F3C0D81971700470E44 /* pcre_study.c */; }; ED556A2A10768FAA0008C22F /* pcre_tables.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F3D0D81971700470E44 /* pcre_tables.c */; }; ED556A2B10768FAA0008C22F /* pcre_try_flipped.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F3E0D81971700470E44 /* pcre_try_flipped.c */; }; ED556A2C10768FAA0008C22F /* pcre_valid_utf8.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F3F0D81971700470E44 /* pcre_valid_utf8.c */; }; ED556A2D10768FAA0008C22F /* pcre_version.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F400D81971700470E44 /* pcre_version.c */; }; ED556A2E10768FAA0008C22F /* pcre_xclass.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F410D81971700470E44 /* pcre_xclass.c */; }; ED556A2F10768FAA0008C22F /* configfiles.mm in Sources */ = {isa = PBXBuildFile; fileRef = ED43DAD60E014BC9000A1E5C /* configfiles.mm */; }; ED556A3410768FAA0008C22F /* mimedirprofile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EDAC08220F179E78005E9AE2 /* mimedirprofile.cpp */; }; ED556A3510768FAA0008C22F /* platform_timezones.mm in Sources */ = {isa = PBXBuildFile; fileRef = ED5B87FA0F8559C40042779A /* platform_timezones.mm */; }; ED556A3610768FAA0008C22F /* syncagent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EDE194C71074A04F00439216 /* syncagent.cpp */; }; ED556A4410768FD90008C22F /* combi_product_options.h in Headers */ = {isa = PBXBuildFile; fileRef = ED556A3E10768FD90008C22F /* combi_product_options.h */; }; ED556A4510768FD90008C22F /* serverengine_custom.h in Headers */ = {isa = PBXBuildFile; fileRef = ED556A3F10768FD90008C22F /* serverengine_custom.h */; }; ED556A4610768FD90008C22F /* serverengine_custom_precomp.h in Headers */ = {isa = PBXBuildFile; fileRef = ED556A4010768FD90008C22F /* serverengine_custom_precomp.h */; }; ED556A4710768FD90008C22F /* serverengine_custom_Base.h in Headers */ = {isa = PBXBuildFile; fileRef = ED556A4110768FD90008C22F /* serverengine_custom_Base.h */; }; ED556A4810768FD90008C22F /* serverengine_custom_Base.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED556A4210768FD90008C22F /* serverengine_custom_Base.cpp */; }; ED556A50107692F20008C22F /* enginesessiondispatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED556A4E107692F20008C22F /* enginesessiondispatch.cpp */; }; ED556A51107692F20008C22F /* enginesessiondispatch.h in Headers */ = {isa = PBXBuildFile; fileRef = ED556A4F107692F20008C22F /* enginesessiondispatch.h */; }; ED5B87FB0F8559C40042779A /* platform_timezones.mm in Sources */ = {isa = PBXBuildFile; fileRef = ED5B87FA0F8559C40042779A /* platform_timezones.mm */; }; ED60E7680DF54F870087381E /* enginemodulebase.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3D3D0D8195A800470E44 /* enginemodulebase.h */; }; ED60E7690DF54F870087381E /* engine_defs.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3D3E0D8195A800470E44 /* engine_defs.h */; }; ED60E76A0DF54F870087381E /* generic_types.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3D3F0D8195A800470E44 /* generic_types.h */; }; ED60E76B0DF54F870087381E /* syerror.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3D400D8195A800470E44 /* syerror.h */; }; ED60E76C0DF54F870087381E /* admindata.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3D960D81968D00470E44 /* admindata.h */; }; ED60E76D0DF54F870087381E /* blobs.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3D980D81968D00470E44 /* blobs.h */; }; ED60E76E0DF54F870087381E /* dbitem.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3D9A0D81968D00470E44 /* dbitem.h */; }; ED60E76F0DF54F870087381E /* sync_include.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3D810D81968D00470E44 /* sync_include.h */; }; ED60E7700DF54F870087381E /* sync_dbapidef.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3D820D81968D00470E44 /* sync_dbapidef.h */; }; ED60E7710DF54F870087381E /* sync_dbapi.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3D830D81968D00470E44 /* sync_dbapi.h */; }; ED60E7720DF54F870087381E /* SDK_util.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3D840D81968D00470E44 /* SDK_util.h */; }; ED60E7730DF54F870087381E /* SDK_support.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3D860D81968D00470E44 /* SDK_support.h */; }; ED60E7740DF54F870087381E /* sync_dbapiconnect.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3D7E0D81968D00470E44 /* sync_dbapiconnect.h */; }; ED60E7750DF54F870087381E /* plugindb.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BAB0D81A0FE00F9A79C /* plugindb.h */; }; ED60E7760DF54F870087381E /* plugindb_precomp.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BAC0D81A0FE00F9A79C /* plugindb_precomp.h */; }; ED60E7770DF54F870087381E /* dbapi.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3D790D81968D00470E44 /* dbapi.h */; }; ED60E7780DF54F870087381E /* dbapi_include.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3D7B0D81968D00470E44 /* dbapi_include.h */; }; ED60E7790DF54F870087381E /* pluginapiagent.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3D750D81968D00470E44 /* pluginapiagent.h */; }; ED60E77A0DF54F870087381E /* pluginapids.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3D770D81968D00470E44 /* pluginapids.h */; }; ED60E77B0DF54F870087381E /* DLL_interface.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3D7C0D81968D00470E44 /* DLL_interface.h */; }; ED60E77C0DF54F870087381E /* odbcdb.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3D6D0D81968D00470E44 /* odbcdb.h */; }; ED60E77D0DF54F870087381E /* odbcdb_precomp.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3D6E0D81968D00470E44 /* odbcdb_precomp.h */; }; ED60E77E0DF54F870087381E /* odbcapiagent.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3D6F0D81968D00470E44 /* odbcapiagent.h */; }; ED60E77F0DF54F870087381E /* odbcapids.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3D710D81968D00470E44 /* odbcapids.h */; }; ED60E7810DF54F870087381E /* clientengine_custom.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3DBA0D81969F00470E44 /* clientengine_custom.h */; }; ED60E7820DF54F870087381E /* clientengine_custom_precomp.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3DBB0D81969F00470E44 /* clientengine_custom_precomp.h */; }; ED60E7830DF54F870087381E /* clientengine_custom_Base.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3DBC0D81969F00470E44 /* clientengine_custom_Base.h */; }; ED60E7840DF54F870087381E /* platform_pipe.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3DDB0D8196BB00470E44 /* platform_pipe.h */; }; ED60E7850DF54F870087381E /* platform_exec.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3DE30D8196BB00470E44 /* platform_exec.h */; }; ED60E7860DF54F870087381E /* platform_headers.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3DE50D8196BB00470E44 /* platform_headers.h */; }; ED60E7870DF54F870087381E /* platform_time.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3DE60D8196BB00470E44 /* platform_time.h */; }; ED60E7880DF54F870087381E /* binfile.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3DEA0D8196BB00470E44 /* binfile.h */; }; ED60E7890DF54F870087381E /* configfiles.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3DEB0D8196BB00470E44 /* configfiles.h */; }; ED60E78B0DF54F870087381E /* platform_thread.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3DED0D8196BB00470E44 /* platform_thread.h */; }; ED60E78C0DF54F870087381E /* platform_mutex.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3DEE0D8196BB00470E44 /* platform_mutex.h */; }; ED60E78D0DF54F870087381E /* platform_file.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3DEF0D8196BB00470E44 /* platform_file.h */; }; ED60E78E0DF54F870087381E /* profiling.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3DF00D8196BB00470E44 /* profiling.h */; }; ED60E78F0DF54F870087381E /* engine_client_precomp.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3DFF0D8196CA00470E44 /* engine_client_precomp.h */; }; ED60E7900DF54F870087381E /* engine_client.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3E000D8196CA00470E44 /* engine_client.h */; }; ED60E7910DF54F870087381E /* engineclientbase.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3E020D8196CA00470E44 /* engineclientbase.h */; }; ED60E7920DF54F870087381E /* wsm.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806C3B0D81A89E00F9A79C /* wsm.h */; }; ED60E7930DF54F870087381E /* sml.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BC70D81A5AD00F9A79C /* sml.h */; }; ED60E7940DF54F870087381E /* smldef.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BC80D81A5AD00F9A79C /* smldef.h */; }; ED60E7950DF54F870087381E /* smldevinfdtd.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BC90D81A5AD00F9A79C /* smldevinfdtd.h */; }; ED60E7960DF54F870087381E /* smldtd.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BCA0D81A5AD00F9A79C /* smldtd.h */; }; ED60E7970DF54F870087381E /* smlerr.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BCB0D81A5AD00F9A79C /* smlerr.h */; }; ED60E7980DF54F870087381E /* smlmetinfdtd.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BCC0D81A5AD00F9A79C /* smlmetinfdtd.h */; }; ED60E7990DF54F870087381E /* liblock.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BBC0D81A58800F9A79C /* liblock.h */; }; ED60E79A0DF54F870087381E /* libmem.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BBD0D81A58800F9A79C /* libmem.h */; }; ED60E79B0DF54F870087381E /* libstr.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BBE0D81A58800F9A79C /* libstr.h */; }; ED60E79C0DF54F870087381E /* libutil.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BBF0D81A58800F9A79C /* libutil.h */; }; ED60E79D0DF54F870087381E /* mgr.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BD80D81A5D500F9A79C /* mgr.h */; }; ED60E79E0DF54F870087381E /* mgrutil.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BD90D81A5D500F9A79C /* mgrutil.h */; }; ED60E79F0DF54F870087381E /* xltdeccom.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BE60D81A5F400F9A79C /* xltdeccom.h */; }; ED60E7A00DF54F870087381E /* xltdecwbxml.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BE80D81A5F400F9A79C /* xltdecwbxml.h */; }; ED60E7A10DF54F870087381E /* xltdevinf.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BEB0D81A5F400F9A79C /* xltdevinf.h */; }; ED60E7A20DF54F870087381E /* xltenccom.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BEE0D81A5F400F9A79C /* xltenccom.h */; }; ED60E7A30DF54F870087381E /* xltencwbxml.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BF00D81A5F400F9A79C /* xltencwbxml.h */; }; ED60E7A40DF54F870087381E /* xltencxml.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BF20D81A5F400F9A79C /* xltencxml.h */; }; ED60E7A50DF54F870087381E /* xltmetinf.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BF40D81A5F400F9A79C /* xltmetinf.h */; }; ED60E7A60DF54F870087381E /* xlttags.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BF60D81A5F400F9A79C /* xlttags.h */; }; ED60E7A70DF54F870087381E /* xlttagtbl.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BF70D81A5F400F9A79C /* xlttagtbl.h */; }; ED60E7A80DF54F870087381E /* xltutilstack.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BF90D81A5F400F9A79C /* xltutilstack.h */; }; ED60E7A90DF54F870087381E /* xltdec.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BFB0D81A5F400F9A79C /* xltdec.h */; }; ED60E7AA0DF54F870087381E /* xltenc.h in Headers */ = {isa = PBXBuildFile; fileRef = ED806BFC0D81A5F400F9A79C /* xltenc.h */; }; ED60E7AB0DF54F870087381E /* binfilebase.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3E900D81970700470E44 /* binfilebase.h */; }; ED60E7AC0DF54F870087381E /* binfileimplclient.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3E920D81970700470E44 /* binfileimplclient.h */; }; ED60E7AD0DF54F870087381E /* binfileimplds.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3E940D81970700470E44 /* binfileimplds.h */; }; ED60E7AE0DF54F870087381E /* engineentry.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3E960D81970700470E44 /* engineentry.h */; }; ED60E7AF0DF54F870087381E /* engineinterface.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3E980D81970700470E44 /* engineinterface.h */; }; ED60E7B00DF54F870087381E /* configelement.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3E990D81970700470E44 /* configelement.h */; }; ED60E7B10DF54F870087381E /* customimplds.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3E9B0D81970700470E44 /* customimplds.h */; }; ED60E7B20DF54F870087381E /* customimplagent.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3E9D0D81970700470E44 /* customimplagent.h */; }; ED60E7B30DF54F870087381E /* dataobjtype.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3E9F0D81970700470E44 /* dataobjtype.h */; }; ED60E7B40DF54F870087381E /* debuglogger.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EA10D81970700470E44 /* debuglogger.h */; }; ED60E7B50DF54F870087381E /* iso8601.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EA30D81970700470E44 /* iso8601.h */; }; ED60E7B60DF54F870087381E /* itemfield.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EA50D81970700470E44 /* itemfield.h */; }; ED60E7B80DF54F870087381E /* localengineds.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EA90D81970700470E44 /* localengineds.h */; }; ED60E7B90DF54F870087381E /* mimediritemtype.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EAB0D81970700470E44 /* mimediritemtype.h */; }; ED60E7BA0DF54F870087381E /* multifielditem.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EAD0D81970700470E44 /* multifielditem.h */; }; ED60E7BB0DF54F870087381E /* multifielditemtype.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EAF0D81970700470E44 /* multifielditemtype.h */; }; ED60E7BC0DF54F870087381E /* remotedatastore.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EB10D81970700470E44 /* remotedatastore.h */; }; ED60E7BD0DF54F870087381E /* rrules.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EB30D81970700470E44 /* rrules.h */; }; ED60E7BF0DF54F870087381E /* scriptcontext.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EB70D81970700470E44 /* scriptcontext.h */; }; ED60E7C00DF54F870087381E /* simpleitem.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EB90D81970700470E44 /* simpleitem.h */; }; ED60E7C10DF54F870087381E /* smltk_precomp.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EBB0D81970700470E44 /* smltk_precomp.h */; }; ED60E7C20DF54F870087381E /* smltk_precomp_xpt.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EBC0D81970700470E44 /* smltk_precomp_xpt.h */; }; ED60E7C30DF54F870087381E /* stringutils.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EBD0D81970700470E44 /* stringutils.h */; }; ED60E7C40DF54F870087381E /* superdatastore.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EBF0D81970700470E44 /* superdatastore.h */; }; ED60E7C50DF54F870087381E /* syncappbase.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EC10D81970700470E44 /* syncappbase.h */; }; ED60E7C70DF54F870087381E /* syncclientbase.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EC50D81970700470E44 /* syncclientbase.h */; }; ED60E7C80DF54F870087381E /* synccommand.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EC70D81970700470E44 /* synccommand.h */; }; ED60E7C90DF54F870087381E /* syncdatastore.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EC90D81970700470E44 /* syncdatastore.h */; }; ED60E7CB0DF54F870087381E /* syncitem.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3ECD0D81970700470E44 /* syncitem.h */; }; ED60E7CC0DF54F870087381E /* syncitemtype.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3ECF0D81970700470E44 /* syncitemtype.h */; }; ED60E7CD0DF54F870087381E /* syncsession.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3ED30D81970700470E44 /* syncsession.h */; }; ED60E7CE0DF54F870087381E /* syserial.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3ED70D81970700470E44 /* syserial.h */; }; ED60E7CF0DF54F870087381E /* sysync.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3ED90D81970700470E44 /* sysync.h */; }; ED60E7D10DF54F870087381E /* sysync_crc16.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EDC0D81970700470E44 /* sysync_crc16.h */; }; ED60E7D20DF54F870087381E /* sysync_globs.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EDE0D81970700470E44 /* sysync_globs.h */; }; ED60E7D40DF54F870087381E /* sysync_precomp.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EE10D81970700470E44 /* sysync_precomp.h */; }; ED60E7D50DF54F870087381E /* sysync_precomp_xpt.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EE20D81970700470E44 /* sysync_precomp_xpt.h */; }; ED60E7D60DF54F870087381E /* stdlogicagent.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EE30D81970700470E44 /* stdlogicagent.h */; }; ED60E7D70DF54F870087381E /* stdlogicds.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EE50D81970700470E44 /* stdlogicds.h */; }; ED60E7D90DF54F870087381E /* textitemtype.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EE90D81970700470E44 /* textitemtype.h */; }; ED60E7DA0DF54F870087381E /* textprofile.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EEB0D81970700470E44 /* textprofile.h */; }; ED60E7DB0DF54F870087381E /* timezones.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EED0D81970700470E44 /* timezones.h */; }; ED60E7DC0DF54F870087381E /* uiapi.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EF00D81970700470E44 /* uiapi.h */; }; ED60E7DD0DF54F870087381E /* vcalendaritemtype.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EF10D81970700470E44 /* vcalendaritemtype.h */; }; ED60E7DE0DF54F870087381E /* vcarditemtype.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EF30D81970700470E44 /* vcarditemtype.h */; }; ED60E7DF0DF54F870087381E /* vtimezone.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EF50D81970700470E44 /* vtimezone.h */; }; ED60E7E00DF54F870087381E /* tz_table.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3EF70D81970700470E44 /* tz_table.h */; }; ED60E7E10DF54F870087381E /* zlib.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3F4A0D81971700470E44 /* zlib.h */; }; ED60E7E20DF54F870087381E /* zutil.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3F4B0D81971700470E44 /* zutil.h */; }; ED60E7E30DF54F870087381E /* xmlparse.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3F460D81971700470E44 /* xmlparse.h */; }; ED60E7E40DF54F870087381E /* pcre_config_macosx.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3F420D81971700470E44 /* pcre_config_macosx.h */; }; ED60E7E50DF54F870087381E /* pcre.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9D3F430D81971700470E44 /* pcre.h */; }; ED60E7EA0DF54F870087381E /* sysync_debug.h in Headers */ = {isa = PBXBuildFile; fileRef = ED55B6960DDDBC43001657F6 /* sysync_debug.h */; }; ED60E7EB0DF54F870087381E /* sync_uiapi.h in Headers */ = {isa = PBXBuildFile; fileRef = ED55B6990DDDBCBC001657F6 /* sync_uiapi.h */; }; ED60E7EC0DF54F870087381E /* xmltok.h in Headers */ = {isa = PBXBuildFile; fileRef = ED55B69C0DDDBD0A001657F6 /* xmltok.h */; }; ED60E7ED0DF54F870087381E /* xmldef.h in Headers */ = {isa = PBXBuildFile; fileRef = ED55B6A90DDDBD4E001657F6 /* xmldef.h */; }; ED60E7EE0DF54F870087381E /* ascii.h in Headers */ = {isa = PBXBuildFile; fileRef = ED55B6AF0DDDBDD9001657F6 /* ascii.h */; }; ED60E7EF0DF54F870087381E /* asciitab.h in Headers */ = {isa = PBXBuildFile; fileRef = ED55B6B00DDDBDD9001657F6 /* asciitab.h */; }; ED60E7F00DF54F870087381E /* iasciitab.h in Headers */ = {isa = PBXBuildFile; fileRef = ED55B6B10DDDBDD9001657F6 /* iasciitab.h */; }; ED60E7F10DF54F870087381E /* latin1tab.h in Headers */ = {isa = PBXBuildFile; fileRef = ED55B6B20DDDBDD9001657F6 /* latin1tab.h */; }; ED60E7F20DF54F870087381E /* nametab.h in Headers */ = {isa = PBXBuildFile; fileRef = ED55B6B30DDDBDD9001657F6 /* nametab.h */; }; ED60E7F30DF54F870087381E /* utf8tab.h in Headers */ = {isa = PBXBuildFile; fileRef = ED55B6B40DDDBDD9001657F6 /* utf8tab.h */; }; ED60E7F40DF54F870087381E /* xmlrole.h in Headers */ = {isa = PBXBuildFile; fileRef = ED55B6B50DDDBDD9001657F6 /* xmlrole.h */; }; ED60E7F70DF54F870087381E /* sync_dbapi_text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3D940D81968D00470E44 /* sync_dbapi_text.cpp */; }; ED60E7F80DF54F870087381E /* enginemodulebase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3D3C0D8195A800470E44 /* enginemodulebase.cpp */; }; ED60E7F90DF54F870087381E /* admindata.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3D970D81968D00470E44 /* admindata.cpp */; }; ED60E7FA0DF54F870087381E /* blobs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3D990D81968D00470E44 /* blobs.cpp */; }; ED60E7FB0DF54F870087381E /* dbitem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3D9B0D81968D00470E44 /* dbitem.cpp */; }; ED60E7FC0DF54F870087381E /* SDK_util.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3D850D81968D00470E44 /* SDK_util.c */; }; ED60E7FD0DF54F870087381E /* SDK_support.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3D870D81968D00470E44 /* SDK_support.cpp */; }; ED60E7FF0DF54F870087381E /* sync_dbapiconnect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3D7F0D81968D00470E44 /* sync_dbapiconnect.cpp */; }; ED60E8030DF54F870087381E /* dbapi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3D7A0D81968D00470E44 /* dbapi.cpp */; }; ED60E8040DF54F870087381E /* pluginapiagent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3D760D81968D00470E44 /* pluginapiagent.cpp */; }; ED60E8050DF54F870087381E /* pluginapids.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3D780D81968D00470E44 /* pluginapids.cpp */; }; ED60E8060DF54F870087381E /* DLL_interface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3D7D0D81968D00470E44 /* DLL_interface.cpp */; }; ED60E8070DF54F870087381E /* odbcapiagent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3D700D81968D00470E44 /* odbcapiagent.cpp */; }; ED60E8080DF54F870087381E /* odbcapids.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3D720D81968D00470E44 /* odbcapids.cpp */; }; ED60E8090DF54F870087381E /* clientengine_custom_Base.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3DBD0D81969F00470E44 /* clientengine_custom_Base.cpp */; }; ED60E80A0DF54F870087381E /* platform_pipe.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3DDC0D8196BB00470E44 /* platform_pipe.c */; }; ED60E80B0DF54F870087381E /* platform_thread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3DDD0D8196BB00470E44 /* platform_thread.cpp */; }; ED60E80C0DF54F870087381E /* platform_mutex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3DDE0D8196BB00470E44 /* platform_mutex.cpp */; }; ED60E80D0DF54F870087381E /* platform_file.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3DDF0D8196BB00470E44 /* platform_file.cpp */; }; ED60E8100DF54F870087381E /* platform_exec.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3DE40D8196BB00470E44 /* platform_exec.c */; }; ED60E8110DF54F870087381E /* platform_time.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3DE70D8196BB00470E44 /* platform_time.cpp */; }; ED60E8120DF54F870087381E /* profiling.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3DE80D8196BB00470E44 /* profiling.cpp */; }; ED60E8130DF54F870087381E /* binfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3DE90D8196BB00470E44 /* binfile.cpp */; }; ED60E8140DF54F870087381E /* sysyncinit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3DF10D8196BB00470E44 /* sysyncinit.cpp */; }; ED60E8150DF54F870087381E /* engineclientbase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3E010D8196CA00470E44 /* engineclientbase.cpp */; }; ED60E8160DF54F870087381E /* liblock.c in Sources */ = {isa = PBXBuildFile; fileRef = ED806BB70D81A58800F9A79C /* liblock.c */; }; ED60E8170DF54F870087381E /* libmem.c in Sources */ = {isa = PBXBuildFile; fileRef = ED806BB80D81A58800F9A79C /* libmem.c */; }; ED60E8180DF54F870087381E /* libstr.c in Sources */ = {isa = PBXBuildFile; fileRef = ED806BB90D81A58800F9A79C /* libstr.c */; }; ED60E8190DF54F870087381E /* libutil.c in Sources */ = {isa = PBXBuildFile; fileRef = ED806BBA0D81A58800F9A79C /* libutil.c */; }; ED60E81A0DF54F870087381E /* mgr.c in Sources */ = {isa = PBXBuildFile; fileRef = ED806BD10D81A5D500F9A79C /* mgr.c */; }; ED60E81B0DF54F870087381E /* mgrcmdbuilder.c in Sources */ = {isa = PBXBuildFile; fileRef = ED806BD20D81A5D500F9A79C /* mgrcmdbuilder.c */; }; ED60E81C0DF54F870087381E /* mgrcmddispatcher.c in Sources */ = {isa = PBXBuildFile; fileRef = ED806BD30D81A5D500F9A79C /* mgrcmddispatcher.c */; }; ED60E81D0DF54F870087381E /* mgrinstancelist.c in Sources */ = {isa = PBXBuildFile; fileRef = ED806BD40D81A5D500F9A79C /* mgrinstancelist.c */; }; ED60E81E0DF54F870087381E /* mgrinstancemgr.c in Sources */ = {isa = PBXBuildFile; fileRef = ED806BD50D81A5D500F9A79C /* mgrinstancemgr.c */; }; ED60E81F0DF54F870087381E /* mgrutil.c in Sources */ = {isa = PBXBuildFile; fileRef = ED806BD60D81A5D500F9A79C /* mgrutil.c */; }; ED60E8200DF54F870087381E /* xltdec.c in Sources */ = {isa = PBXBuildFile; fileRef = ED806BE50D81A5F400F9A79C /* xltdec.c */; }; ED60E8210DF54F870087381E /* xltdecwbxml.c in Sources */ = {isa = PBXBuildFile; fileRef = ED806BE70D81A5F400F9A79C /* xltdecwbxml.c */; }; ED60E8220DF54F870087381E /* xltdecxml.c in Sources */ = {isa = PBXBuildFile; fileRef = ED806BE90D81A5F400F9A79C /* xltdecxml.c */; }; ED60E8230DF54F870087381E /* xltdevinf.c in Sources */ = {isa = PBXBuildFile; fileRef = ED806BEA0D81A5F400F9A79C /* xltdevinf.c */; }; ED60E8240DF54F870087381E /* xltenc.c in Sources */ = {isa = PBXBuildFile; fileRef = ED806BEC0D81A5F400F9A79C /* xltenc.c */; }; ED60E8250DF54F870087381E /* xltenccom.c in Sources */ = {isa = PBXBuildFile; fileRef = ED806BED0D81A5F400F9A79C /* xltenccom.c */; }; ED60E8260DF54F870087381E /* xltencwbxml.c in Sources */ = {isa = PBXBuildFile; fileRef = ED806BEF0D81A5F400F9A79C /* xltencwbxml.c */; }; ED60E8270DF54F870087381E /* xltencxml.c in Sources */ = {isa = PBXBuildFile; fileRef = ED806BF10D81A5F400F9A79C /* xltencxml.c */; }; ED60E8280DF54F870087381E /* xltmetinf.c in Sources */ = {isa = PBXBuildFile; fileRef = ED806BF30D81A5F400F9A79C /* xltmetinf.c */; }; ED60E8290DF54F870087381E /* xlttags.c in Sources */ = {isa = PBXBuildFile; fileRef = ED806BF50D81A5F400F9A79C /* xlttags.c */; }; ED60E82A0DF54F870087381E /* xltutilstack.c in Sources */ = {isa = PBXBuildFile; fileRef = ED806BF80D81A5F400F9A79C /* xltutilstack.c */; }; ED60E82B0DF54F870087381E /* binfilebase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3E8F0D81970700470E44 /* binfilebase.cpp */; }; ED60E82C0DF54F870087381E /* binfileimplclient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3E910D81970700470E44 /* binfileimplclient.cpp */; }; ED60E82D0DF54F870087381E /* binfileimplds.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3E930D81970700470E44 /* binfileimplds.cpp */; }; ED60E82E0DF54F870087381E /* engineentry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3E950D81970700470E44 /* engineentry.cpp */; }; ED60E82F0DF54F870087381E /* engineinterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3E970D81970700470E44 /* engineinterface.cpp */; }; ED60E8300DF54F870087381E /* configelement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3E9A0D81970700470E44 /* configelement.cpp */; }; ED60E8310DF54F870087381E /* customimplds.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3E9C0D81970700470E44 /* customimplds.cpp */; }; ED60E8320DF54F870087381E /* customimplagent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3E9E0D81970700470E44 /* customimplagent.cpp */; }; ED60E8330DF54F870087381E /* dataobjtype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EA00D81970700470E44 /* dataobjtype.cpp */; }; ED60E8340DF54F870087381E /* debuglogger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EA20D81970700470E44 /* debuglogger.cpp */; }; ED60E8350DF54F870087381E /* iso8601.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EA40D81970700470E44 /* iso8601.cpp */; }; ED60E8360DF54F870087381E /* itemfield.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EA60D81970700470E44 /* itemfield.cpp */; }; ED60E8380DF54F870087381E /* localengineds.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EAA0D81970700470E44 /* localengineds.cpp */; }; ED60E8390DF54F870087381E /* mimediritemtype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EAC0D81970700470E44 /* mimediritemtype.cpp */; }; ED60E83A0DF54F870087381E /* multifielditem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EAE0D81970700470E44 /* multifielditem.cpp */; }; ED60E83B0DF54F870087381E /* multifielditemtype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EB00D81970700470E44 /* multifielditemtype.cpp */; }; ED60E83C0DF54F870087381E /* remotedatastore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EB20D81970700470E44 /* remotedatastore.cpp */; }; ED60E83D0DF54F870087381E /* rrules.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EB40D81970700470E44 /* rrules.cpp */; }; ED60E83F0DF54F870087381E /* scriptcontext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EB80D81970700470E44 /* scriptcontext.cpp */; }; ED60E8400DF54F870087381E /* simpleitem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EBA0D81970700470E44 /* simpleitem.cpp */; }; ED60E8410DF54F870087381E /* stringutils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EBE0D81970700470E44 /* stringutils.cpp */; }; ED60E8420DF54F870087381E /* superdatastore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EC00D81970700470E44 /* superdatastore.cpp */; }; ED60E8430DF54F870087381E /* syncappbase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EC20D81970700470E44 /* syncappbase.cpp */; }; ED60E8450DF54F870087381E /* syncclientbase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EC60D81970700470E44 /* syncclientbase.cpp */; }; ED60E8460DF54F870087381E /* synccommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EC80D81970700470E44 /* synccommand.cpp */; }; ED60E8470DF54F870087381E /* syncdatastore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3ECA0D81970700470E44 /* syncdatastore.cpp */; }; ED60E8490DF54F870087381E /* syncitem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3ECE0D81970700470E44 /* syncitem.cpp */; }; ED60E84A0DF54F870087381E /* syncitemtype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3ED00D81970700470E44 /* syncitemtype.cpp */; }; ED60E84B0DF54F870087381E /* syncsession.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3ED40D81970700470E44 /* syncsession.cpp */; }; ED60E84E0DF54F870087381E /* sysync_crc16.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EDD0D81970700470E44 /* sysync_crc16.cpp */; }; ED60E8500DF54F870087381E /* stdlogicagent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EE40D81970700470E44 /* stdlogicagent.cpp */; }; ED60E8510DF54F870087381E /* stdlogicds.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EE60D81970700470E44 /* stdlogicds.cpp */; }; ED60E8530DF54F870087381E /* textitemtype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EEA0D81970700470E44 /* textitemtype.cpp */; }; ED60E8540DF54F870087381E /* textprofile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EEC0D81970700470E44 /* textprofile.cpp */; }; ED60E8550DF54F870087381E /* timezones.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EEE0D81970700470E44 /* timezones.cpp */; }; ED60E8560DF54F870087381E /* uiapi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EEF0D81970700470E44 /* uiapi.cpp */; }; ED60E8570DF54F870087381E /* vcalendaritemtype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EF20D81970700470E44 /* vcalendaritemtype.cpp */; }; ED60E8580DF54F870087381E /* vcarditemtype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EF40D81970700470E44 /* vcarditemtype.cpp */; }; ED60E8590DF54F870087381E /* vtimezone.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3EF60D81970700470E44 /* vtimezone.cpp */; }; ED60E85A0DF54F870087381E /* infback.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F4C0D81971700470E44 /* infback.c */; }; ED60E85B0DF54F870087381E /* gzio.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F4D0D81971700470E44 /* gzio.c */; }; ED60E85C0DF54F870087381E /* deflate.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F4E0D81971700470E44 /* deflate.c */; }; ED60E85D0DF54F870087381E /* uncompr.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F4F0D81971700470E44 /* uncompr.c */; }; ED60E85E0DF54F870087381E /* trees.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F500D81971700470E44 /* trees.c */; }; ED60E85F0DF54F870087381E /* inftrees.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F510D81971700470E44 /* inftrees.c */; }; ED60E8600DF54F870087381E /* inflate.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F520D81971700470E44 /* inflate.c */; }; ED60E8610DF54F870087381E /* inffast.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F530D81971700470E44 /* inffast.c */; }; ED60E8620DF54F870087381E /* zutil.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F540D81971700470E44 /* zutil.c */; }; ED60E8630DF54F870087381E /* crc32.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F550D81971700470E44 /* crc32.c */; }; ED60E8640DF54F870087381E /* compress.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F560D81971700470E44 /* compress.c */; }; ED60E8650DF54F870087381E /* adler32.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F570D81971700470E44 /* adler32.c */; }; ED60E8660DF54F870087381E /* xmlparse.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F450D81971700470E44 /* xmlparse.c */; }; ED60E8670DF54F870087381E /* xmltok.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F470D81971700470E44 /* xmltok.c */; }; ED60E8680DF54F870087381E /* xmlrole.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F480D81971700470E44 /* xmlrole.c */; }; ED60E8690DF54F870087381E /* pcre_ord2utf8.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F300D81971700470E44 /* pcre_ord2utf8.c */; }; ED60E86A0DF54F870087381E /* pcre_chartables.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F310D81971700470E44 /* pcre_chartables.c */; }; ED60E86B0DF54F870087381E /* pcre_compile.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F320D81971700470E44 /* pcre_compile.c */; }; ED60E86C0DF54F870087381E /* pcre_config.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F330D81971700470E44 /* pcre_config.c */; }; ED60E86D0DF54F870087381E /* pcre_dfa_exec.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F340D81971700470E44 /* pcre_dfa_exec.c */; }; ED60E86E0DF54F870087381E /* pcre_exec.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F350D81971700470E44 /* pcre_exec.c */; }; ED60E86F0DF54F870087381E /* pcre_fullinfo.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F360D81971700470E44 /* pcre_fullinfo.c */; }; ED60E8700DF54F870087381E /* pcre_get.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F370D81971700470E44 /* pcre_get.c */; }; ED60E8710DF54F870087381E /* pcre_globals.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F380D81971700470E44 /* pcre_globals.c */; }; ED60E8720DF54F870087381E /* pcre_info.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F390D81971700470E44 /* pcre_info.c */; }; ED60E8730DF54F870087381E /* pcre_newline.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F3A0D81971700470E44 /* pcre_newline.c */; }; ED60E8740DF54F870087381E /* pcre_refcount.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F3B0D81971700470E44 /* pcre_refcount.c */; }; ED60E8750DF54F870087381E /* pcre_study.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F3C0D81971700470E44 /* pcre_study.c */; }; ED60E8760DF54F870087381E /* pcre_tables.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F3D0D81971700470E44 /* pcre_tables.c */; }; ED60E8770DF54F870087381E /* pcre_try_flipped.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F3E0D81971700470E44 /* pcre_try_flipped.c */; }; ED60E8780DF54F870087381E /* pcre_valid_utf8.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F3F0D81971700470E44 /* pcre_valid_utf8.c */; }; ED60E8790DF54F870087381E /* pcre_version.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F400D81971700470E44 /* pcre_version.c */; }; ED60E87A0DF54F870087381E /* pcre_xclass.c in Sources */ = {isa = PBXBuildFile; fileRef = ED9D3F410D81971700470E44 /* pcre_xclass.c */; }; EDAC08250F179E78005E9AE2 /* mimedirprofile.h in Headers */ = {isa = PBXBuildFile; fileRef = EDAC08210F179E78005E9AE2 /* mimedirprofile.h */; }; EDAC08260F179E78005E9AE2 /* mimedirprofile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EDAC08220F179E78005E9AE2 /* mimedirprofile.cpp */; }; EDDAFD0511A0989D003E33D5 /* rawdataitemtype.h in Headers */ = {isa = PBXBuildFile; fileRef = EDDAFD0111A0989D003E33D5 /* rawdataitemtype.h */; }; EDDAFD0611A0989D003E33D5 /* rawdataitemtype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EDDAFD0211A0989D003E33D5 /* rawdataitemtype.cpp */; }; EDDAFD0911A0989D003E33D5 /* rawdataitemtype.h in Headers */ = {isa = PBXBuildFile; fileRef = EDDAFD0111A0989D003E33D5 /* rawdataitemtype.h */; }; EDDAFD0A11A0989D003E33D5 /* rawdataitemtype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EDDAFD0211A0989D003E33D5 /* rawdataitemtype.cpp */; }; EDDF0814107E435200A119FE /* product_options.h in Headers */ = {isa = PBXBuildFile; fileRef = EDDF0813107E435200A119FE /* product_options.h */; }; EDDF0816107E435200A119FE /* product_options.h in Headers */ = {isa = PBXBuildFile; fileRef = EDDF0813107E435200A119FE /* product_options.h */; }; EDE194C81074A04F00439216 /* syncagent.h in Headers */ = {isa = PBXBuildFile; fileRef = EDE194C61074A04F00439216 /* syncagent.h */; }; EDE194C91074A04F00439216 /* syncagent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EDE194C71074A04F00439216 /* syncagent.cpp */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ ED16A68D14B9B4E400F24032 /* platform_DLL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = platform_DLL.h; path = platform_adapters/platform_DLL.h; sourceTree = SOURCE_ROOT; }; ED1ECBC31383B0DB00B3DA02 /* libsysync_client_ios.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libsysync_client_ios.a; sourceTree = BUILT_PRODUCTS_DIR; }; ED1ECBC41383B0DB00B3DA02 /* libsysync_combi_ios.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libsysync_combi_ios.a; sourceTree = BUILT_PRODUCTS_DIR; }; ED43DAD60E014BC9000A1E5C /* configfiles.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = configfiles.mm; sourceTree = ""; }; ED4B5E9511523AAB00ECB4A5 /* sysync_utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sysync_utils.h; sourceTree = ""; }; ED4B5E9611523AAB00ECB4A5 /* sysync_utils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sysync_utils.cpp; sourceTree = ""; }; ED4B5E9711523AAB00ECB4A5 /* syncexception.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = syncexception.cpp; sourceTree = ""; }; ED4B5E9A11523AAB00ECB4A5 /* lineartime.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lineartime.cpp; sourceTree = ""; }; ED4B5E9B11523AAB00ECB4A5 /* san.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = san.cpp; sourceTree = ""; }; ED4B5E9C11523AAB00ECB4A5 /* san.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = san.h; sourceTree = ""; }; ED4B5E9D11523AAB00ECB4A5 /* sysync_md5.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sysync_md5.h; sourceTree = ""; }; ED4B5E9E11523AAB00ECB4A5 /* sysync_md5.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sysync_md5.cpp; sourceTree = ""; }; ED4B5E9F11523AAB00ECB4A5 /* sysync_b64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sysync_b64.h; sourceTree = ""; }; ED4B5EA011523AAB00ECB4A5 /* sysync_b64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sysync_b64.cpp; sourceTree = ""; }; ED4B5EA111523AAB00ECB4A5 /* syncexception.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = syncexception.h; sourceTree = ""; }; ED4B5EA211523AAB00ECB4A5 /* lineartime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lineartime.h; sourceTree = ""; }; ED556A3E10768FD90008C22F /* combi_product_options.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = combi_product_options.h; sourceTree = ""; }; ED556A3F10768FD90008C22F /* serverengine_custom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = serverengine_custom.h; sourceTree = ""; }; ED556A4010768FD90008C22F /* serverengine_custom_precomp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = serverengine_custom_precomp.h; sourceTree = ""; }; ED556A4110768FD90008C22F /* serverengine_custom_Base.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = serverengine_custom_Base.h; sourceTree = ""; }; ED556A4210768FD90008C22F /* serverengine_custom_Base.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = serverengine_custom_Base.cpp; sourceTree = ""; }; ED556A4E107692F20008C22F /* enginesessiondispatch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = enginesessiondispatch.cpp; sourceTree = ""; }; ED556A4F107692F20008C22F /* enginesessiondispatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = enginesessiondispatch.h; sourceTree = ""; }; ED55B6960DDDBC43001657F6 /* sysync_debug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sysync_debug.h; sourceTree = ""; }; ED55B6990DDDBCBC001657F6 /* sync_uiapi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sync_uiapi.h; sourceTree = ""; }; ED55B69C0DDDBD0A001657F6 /* xmltok.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = xmltok.h; path = expat/xmltok/xmltok.h; sourceTree = ""; }; ED55B6A90DDDBD4E001657F6 /* xmldef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = xmldef.h; path = expat/xmltok/xmldef.h; sourceTree = ""; }; ED55B6AF0DDDBDD9001657F6 /* ascii.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ascii.h; path = expat/xmltok/ascii.h; sourceTree = ""; }; ED55B6B00DDDBDD9001657F6 /* asciitab.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = asciitab.h; path = expat/xmltok/asciitab.h; sourceTree = ""; }; ED55B6B10DDDBDD9001657F6 /* iasciitab.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iasciitab.h; path = expat/xmltok/iasciitab.h; sourceTree = ""; }; ED55B6B20DDDBDD9001657F6 /* latin1tab.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = latin1tab.h; path = expat/xmltok/latin1tab.h; sourceTree = ""; }; ED55B6B30DDDBDD9001657F6 /* nametab.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = nametab.h; path = expat/xmltok/nametab.h; sourceTree = ""; }; ED55B6B40DDDBDD9001657F6 /* utf8tab.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = utf8tab.h; path = expat/xmltok/utf8tab.h; sourceTree = ""; }; ED55B6B50DDDBDD9001657F6 /* xmlrole.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = xmlrole.h; path = expat/xmltok/xmlrole.h; sourceTree = ""; }; ED5B87FA0F8559C40042779A /* platform_timezones.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = platform_timezones.mm; sourceTree = ""; }; ED806BAB0D81A0FE00F9A79C /* plugindb.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = plugindb.h; sourceTree = ""; }; ED806BAC0D81A0FE00F9A79C /* plugindb_precomp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = plugindb_precomp.h; sourceTree = ""; }; ED806BB70D81A58800F9A79C /* liblock.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = liblock.c; sourceTree = ""; }; ED806BB80D81A58800F9A79C /* libmem.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = libmem.c; sourceTree = ""; }; ED806BB90D81A58800F9A79C /* libstr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = libstr.c; sourceTree = ""; }; ED806BBA0D81A58800F9A79C /* libutil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = libutil.c; sourceTree = ""; }; ED806BBC0D81A58800F9A79C /* liblock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = liblock.h; sourceTree = ""; }; ED806BBD0D81A58800F9A79C /* libmem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = libmem.h; sourceTree = ""; }; ED806BBE0D81A58800F9A79C /* libstr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = libstr.h; sourceTree = ""; }; ED806BBF0D81A58800F9A79C /* libutil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = libutil.h; sourceTree = ""; }; ED806BC70D81A5AD00F9A79C /* sml.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sml.h; sourceTree = ""; }; ED806BC80D81A5AD00F9A79C /* smldef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = smldef.h; sourceTree = ""; }; ED806BC90D81A5AD00F9A79C /* smldevinfdtd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = smldevinfdtd.h; sourceTree = ""; }; ED806BCA0D81A5AD00F9A79C /* smldtd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = smldtd.h; sourceTree = ""; }; ED806BCB0D81A5AD00F9A79C /* smlerr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = smlerr.h; sourceTree = ""; }; ED806BCC0D81A5AD00F9A79C /* smlmetinfdtd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = smlmetinfdtd.h; sourceTree = ""; }; ED806BD10D81A5D500F9A79C /* mgr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mgr.c; sourceTree = ""; }; ED806BD20D81A5D500F9A79C /* mgrcmdbuilder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mgrcmdbuilder.c; sourceTree = ""; }; ED806BD30D81A5D500F9A79C /* mgrcmddispatcher.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mgrcmddispatcher.c; sourceTree = ""; }; ED806BD40D81A5D500F9A79C /* mgrinstancelist.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mgrinstancelist.c; sourceTree = ""; }; ED806BD50D81A5D500F9A79C /* mgrinstancemgr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mgrinstancemgr.c; sourceTree = ""; }; ED806BD60D81A5D500F9A79C /* mgrutil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mgrutil.c; sourceTree = ""; }; ED806BD80D81A5D500F9A79C /* mgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mgr.h; sourceTree = ""; }; ED806BD90D81A5D500F9A79C /* mgrutil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mgrutil.h; sourceTree = ""; }; ED806BE50D81A5F400F9A79C /* xltdec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xltdec.c; sourceTree = ""; }; ED806BE60D81A5F400F9A79C /* xltdeccom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xltdeccom.h; sourceTree = ""; }; ED806BE70D81A5F400F9A79C /* xltdecwbxml.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xltdecwbxml.c; sourceTree = ""; }; ED806BE80D81A5F400F9A79C /* xltdecwbxml.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xltdecwbxml.h; sourceTree = ""; }; ED806BE90D81A5F400F9A79C /* xltdecxml.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xltdecxml.c; sourceTree = ""; }; ED806BEA0D81A5F400F9A79C /* xltdevinf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xltdevinf.c; sourceTree = ""; }; ED806BEB0D81A5F400F9A79C /* xltdevinf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xltdevinf.h; sourceTree = ""; }; ED806BEC0D81A5F400F9A79C /* xltenc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xltenc.c; sourceTree = ""; }; ED806BED0D81A5F400F9A79C /* xltenccom.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xltenccom.c; sourceTree = ""; }; ED806BEE0D81A5F400F9A79C /* xltenccom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xltenccom.h; sourceTree = ""; }; ED806BEF0D81A5F400F9A79C /* xltencwbxml.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xltencwbxml.c; sourceTree = ""; }; ED806BF00D81A5F400F9A79C /* xltencwbxml.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xltencwbxml.h; sourceTree = ""; }; ED806BF10D81A5F400F9A79C /* xltencxml.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xltencxml.c; sourceTree = ""; }; ED806BF20D81A5F400F9A79C /* xltencxml.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xltencxml.h; sourceTree = ""; }; ED806BF30D81A5F400F9A79C /* xltmetinf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xltmetinf.c; sourceTree = ""; }; ED806BF40D81A5F400F9A79C /* xltmetinf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xltmetinf.h; sourceTree = ""; }; ED806BF50D81A5F400F9A79C /* xlttags.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xlttags.c; sourceTree = ""; }; ED806BF60D81A5F400F9A79C /* xlttags.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xlttags.h; sourceTree = ""; }; ED806BF70D81A5F400F9A79C /* xlttagtbl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xlttagtbl.h; sourceTree = ""; }; ED806BF80D81A5F400F9A79C /* xltutilstack.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xltutilstack.c; sourceTree = ""; }; ED806BF90D81A5F400F9A79C /* xltutilstack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xltutilstack.h; sourceTree = ""; }; ED806BFB0D81A5F400F9A79C /* xltdec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xltdec.h; sourceTree = ""; }; ED806BFC0D81A5F400F9A79C /* xltenc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xltenc.h; sourceTree = ""; }; ED806C3B0D81A89E00F9A79C /* wsm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wsm.h; sourceTree = ""; }; ED9D3CEC0D81900B00470E44 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; }; ED9D3CF00D81902F00470E44 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; }; ED9D3D3A0D81959E00470E44 /* global_options.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = global_options.h; sourceTree = ""; }; ED9D3D3C0D8195A800470E44 /* enginemodulebase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = enginemodulebase.cpp; sourceTree = ""; }; ED9D3D3D0D8195A800470E44 /* enginemodulebase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = enginemodulebase.h; sourceTree = ""; }; ED9D3D3E0D8195A800470E44 /* engine_defs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = engine_defs.h; sourceTree = ""; }; ED9D3D3F0D8195A800470E44 /* generic_types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = generic_types.h; sourceTree = ""; }; ED9D3D400D8195A800470E44 /* syerror.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = syerror.h; sourceTree = ""; }; ED9D3D6D0D81968D00470E44 /* odbcdb.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = odbcdb.h; sourceTree = ""; }; ED9D3D6E0D81968D00470E44 /* odbcdb_precomp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = odbcdb_precomp.h; sourceTree = ""; }; ED9D3D6F0D81968D00470E44 /* odbcapiagent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = odbcapiagent.h; sourceTree = ""; }; ED9D3D700D81968D00470E44 /* odbcapiagent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = odbcapiagent.cpp; sourceTree = ""; }; ED9D3D710D81968D00470E44 /* odbcapids.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = odbcapids.h; sourceTree = ""; }; ED9D3D720D81968D00470E44 /* odbcapids.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = odbcapids.cpp; sourceTree = ""; }; ED9D3D750D81968D00470E44 /* pluginapiagent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pluginapiagent.h; sourceTree = ""; }; ED9D3D760D81968D00470E44 /* pluginapiagent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pluginapiagent.cpp; sourceTree = ""; }; ED9D3D770D81968D00470E44 /* pluginapids.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pluginapids.h; sourceTree = ""; }; ED9D3D780D81968D00470E44 /* pluginapids.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pluginapids.cpp; sourceTree = ""; }; ED9D3D790D81968D00470E44 /* dbapi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dbapi.h; sourceTree = ""; }; ED9D3D7A0D81968D00470E44 /* dbapi.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dbapi.cpp; sourceTree = ""; }; ED9D3D7B0D81968D00470E44 /* dbapi_include.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dbapi_include.h; sourceTree = ""; }; ED9D3D7C0D81968D00470E44 /* DLL_interface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DLL_interface.h; sourceTree = ""; }; ED9D3D7D0D81968D00470E44 /* DLL_interface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DLL_interface.cpp; sourceTree = ""; }; ED9D3D7E0D81968D00470E44 /* sync_dbapiconnect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sync_dbapiconnect.h; sourceTree = ""; }; ED9D3D7F0D81968D00470E44 /* sync_dbapiconnect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sync_dbapiconnect.cpp; sourceTree = ""; }; ED9D3D810D81968D00470E44 /* sync_include.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sync_include.h; sourceTree = ""; }; ED9D3D820D81968D00470E44 /* sync_dbapidef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sync_dbapidef.h; sourceTree = ""; }; ED9D3D830D81968D00470E44 /* sync_dbapi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sync_dbapi.h; sourceTree = ""; }; ED9D3D840D81968D00470E44 /* SDK_util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDK_util.h; sourceTree = ""; }; ED9D3D850D81968D00470E44 /* SDK_util.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDK_util.c; sourceTree = ""; }; ED9D3D860D81968D00470E44 /* SDK_support.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDK_support.h; sourceTree = ""; }; ED9D3D870D81968D00470E44 /* SDK_support.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SDK_support.cpp; sourceTree = ""; }; ED9D3D940D81968D00470E44 /* sync_dbapi_text.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sync_dbapi_text.cpp; sourceTree = ""; }; ED9D3D960D81968D00470E44 /* admindata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = admindata.h; sourceTree = ""; }; ED9D3D970D81968D00470E44 /* admindata.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = admindata.cpp; sourceTree = ""; }; ED9D3D980D81968D00470E44 /* blobs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = blobs.h; sourceTree = ""; }; ED9D3D990D81968D00470E44 /* blobs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = blobs.cpp; sourceTree = ""; }; ED9D3D9A0D81968D00470E44 /* dbitem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dbitem.h; sourceTree = ""; }; ED9D3D9B0D81968D00470E44 /* dbitem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dbitem.cpp; sourceTree = ""; }; ED9D3DBA0D81969F00470E44 /* clientengine_custom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = clientengine_custom.h; sourceTree = ""; }; ED9D3DBB0D81969F00470E44 /* clientengine_custom_precomp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = clientengine_custom_precomp.h; sourceTree = ""; }; ED9D3DBC0D81969F00470E44 /* clientengine_custom_Base.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = clientengine_custom_Base.h; sourceTree = ""; }; ED9D3DBD0D81969F00470E44 /* clientengine_custom_Base.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = clientengine_custom_Base.cpp; sourceTree = ""; }; ED9D3DDB0D8196BB00470E44 /* platform_pipe.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platform_pipe.h; sourceTree = ""; }; ED9D3DDC0D8196BB00470E44 /* platform_pipe.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = platform_pipe.c; sourceTree = ""; }; ED9D3DDD0D8196BB00470E44 /* platform_thread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = platform_thread.cpp; sourceTree = ""; }; ED9D3DDE0D8196BB00470E44 /* platform_mutex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = platform_mutex.cpp; sourceTree = ""; }; ED9D3DDF0D8196BB00470E44 /* platform_file.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = platform_file.cpp; sourceTree = ""; }; ED9D3DE30D8196BB00470E44 /* platform_exec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platform_exec.h; sourceTree = ""; }; ED9D3DE40D8196BB00470E44 /* platform_exec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = platform_exec.c; sourceTree = ""; }; ED9D3DE50D8196BB00470E44 /* platform_headers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platform_headers.h; sourceTree = ""; }; ED9D3DE60D8196BB00470E44 /* platform_time.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platform_time.h; sourceTree = ""; }; ED9D3DE70D8196BB00470E44 /* platform_time.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = platform_time.cpp; sourceTree = ""; }; ED9D3DE80D8196BB00470E44 /* profiling.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = profiling.cpp; sourceTree = ""; }; ED9D3DE90D8196BB00470E44 /* binfile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = binfile.cpp; sourceTree = ""; }; ED9D3DEA0D8196BB00470E44 /* binfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = binfile.h; sourceTree = ""; }; ED9D3DEB0D8196BB00470E44 /* configfiles.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = configfiles.h; sourceTree = ""; }; ED9D3DED0D8196BB00470E44 /* platform_thread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platform_thread.h; sourceTree = ""; }; ED9D3DEE0D8196BB00470E44 /* platform_mutex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platform_mutex.h; sourceTree = ""; }; ED9D3DEF0D8196BB00470E44 /* platform_file.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platform_file.h; sourceTree = ""; }; ED9D3DF00D8196BB00470E44 /* profiling.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = profiling.h; sourceTree = ""; }; ED9D3DF10D8196BB00470E44 /* sysyncinit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sysyncinit.cpp; sourceTree = ""; }; ED9D3DFF0D8196CA00470E44 /* engine_client_precomp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = engine_client_precomp.h; sourceTree = ""; }; ED9D3E000D8196CA00470E44 /* engine_client.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = engine_client.h; sourceTree = ""; }; ED9D3E010D8196CA00470E44 /* engineclientbase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = engineclientbase.cpp; sourceTree = ""; }; ED9D3E020D8196CA00470E44 /* engineclientbase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = engineclientbase.h; sourceTree = ""; }; ED9D3E8F0D81970700470E44 /* binfilebase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = binfilebase.cpp; sourceTree = ""; }; ED9D3E900D81970700470E44 /* binfilebase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = binfilebase.h; sourceTree = ""; }; ED9D3E910D81970700470E44 /* binfileimplclient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = binfileimplclient.cpp; sourceTree = ""; }; ED9D3E920D81970700470E44 /* binfileimplclient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = binfileimplclient.h; sourceTree = ""; }; ED9D3E930D81970700470E44 /* binfileimplds.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = binfileimplds.cpp; sourceTree = ""; }; ED9D3E940D81970700470E44 /* binfileimplds.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = binfileimplds.h; sourceTree = ""; }; ED9D3E950D81970700470E44 /* engineentry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = engineentry.cpp; sourceTree = ""; }; ED9D3E960D81970700470E44 /* engineentry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = engineentry.h; sourceTree = ""; }; ED9D3E970D81970700470E44 /* engineinterface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = engineinterface.cpp; sourceTree = ""; }; ED9D3E980D81970700470E44 /* engineinterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = engineinterface.h; sourceTree = ""; }; ED9D3E990D81970700470E44 /* configelement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = configelement.h; sourceTree = ""; }; ED9D3E9A0D81970700470E44 /* configelement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = configelement.cpp; sourceTree = ""; }; ED9D3E9B0D81970700470E44 /* customimplds.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = customimplds.h; sourceTree = ""; }; ED9D3E9C0D81970700470E44 /* customimplds.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = customimplds.cpp; sourceTree = ""; }; ED9D3E9D0D81970700470E44 /* customimplagent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = customimplagent.h; sourceTree = ""; }; ED9D3E9E0D81970700470E44 /* customimplagent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = customimplagent.cpp; sourceTree = ""; }; ED9D3E9F0D81970700470E44 /* dataobjtype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dataobjtype.h; sourceTree = ""; }; ED9D3EA00D81970700470E44 /* dataobjtype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dataobjtype.cpp; sourceTree = ""; }; ED9D3EA10D81970700470E44 /* debuglogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debuglogger.h; sourceTree = ""; }; ED9D3EA20D81970700470E44 /* debuglogger.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debuglogger.cpp; sourceTree = ""; }; ED9D3EA30D81970700470E44 /* iso8601.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iso8601.h; sourceTree = ""; }; ED9D3EA40D81970700470E44 /* iso8601.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = iso8601.cpp; sourceTree = ""; }; ED9D3EA50D81970700470E44 /* itemfield.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = itemfield.h; sourceTree = ""; }; ED9D3EA60D81970700470E44 /* itemfield.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = itemfield.cpp; sourceTree = ""; }; ED9D3EA90D81970700470E44 /* localengineds.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = localengineds.h; sourceTree = ""; }; ED9D3EAA0D81970700470E44 /* localengineds.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = localengineds.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; ED9D3EAB0D81970700470E44 /* mimediritemtype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mimediritemtype.h; sourceTree = ""; }; ED9D3EAC0D81970700470E44 /* mimediritemtype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mimediritemtype.cpp; sourceTree = ""; }; ED9D3EAD0D81970700470E44 /* multifielditem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = multifielditem.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; ED9D3EAE0D81970700470E44 /* multifielditem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = multifielditem.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; ED9D3EAF0D81970700470E44 /* multifielditemtype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = multifielditemtype.h; sourceTree = ""; }; ED9D3EB00D81970700470E44 /* multifielditemtype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = multifielditemtype.cpp; sourceTree = ""; }; ED9D3EB10D81970700470E44 /* remotedatastore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = remotedatastore.h; sourceTree = ""; }; ED9D3EB20D81970700470E44 /* remotedatastore.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = remotedatastore.cpp; sourceTree = ""; }; ED9D3EB30D81970700470E44 /* rrules.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rrules.h; sourceTree = ""; }; ED9D3EB40D81970700470E44 /* rrules.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rrules.cpp; sourceTree = ""; }; ED9D3EB70D81970700470E44 /* scriptcontext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scriptcontext.h; sourceTree = ""; }; ED9D3EB80D81970700470E44 /* scriptcontext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scriptcontext.cpp; sourceTree = ""; }; ED9D3EB90D81970700470E44 /* simpleitem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = simpleitem.h; sourceTree = ""; }; ED9D3EBA0D81970700470E44 /* simpleitem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = simpleitem.cpp; sourceTree = ""; }; ED9D3EBB0D81970700470E44 /* smltk_precomp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = smltk_precomp.h; sourceTree = ""; }; ED9D3EBC0D81970700470E44 /* smltk_precomp_xpt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = smltk_precomp_xpt.h; sourceTree = ""; }; ED9D3EBD0D81970700470E44 /* stringutils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stringutils.h; sourceTree = ""; }; ED9D3EBE0D81970700470E44 /* stringutils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = stringutils.cpp; sourceTree = ""; }; ED9D3EBF0D81970700470E44 /* superdatastore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = superdatastore.h; sourceTree = ""; }; ED9D3EC00D81970700470E44 /* superdatastore.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = superdatastore.cpp; sourceTree = ""; }; ED9D3EC10D81970700470E44 /* syncappbase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = syncappbase.h; sourceTree = ""; }; ED9D3EC20D81970700470E44 /* syncappbase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = syncappbase.cpp; sourceTree = ""; }; ED9D3EC50D81970700470E44 /* syncclientbase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = syncclientbase.h; sourceTree = ""; }; ED9D3EC60D81970700470E44 /* syncclientbase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = syncclientbase.cpp; sourceTree = ""; }; ED9D3EC70D81970700470E44 /* synccommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = synccommand.h; sourceTree = ""; }; ED9D3EC80D81970700470E44 /* synccommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = synccommand.cpp; sourceTree = ""; }; ED9D3EC90D81970700470E44 /* syncdatastore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = syncdatastore.h; sourceTree = ""; }; ED9D3ECA0D81970700470E44 /* syncdatastore.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = syncdatastore.cpp; sourceTree = ""; }; ED9D3ECD0D81970700470E44 /* syncitem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = syncitem.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; ED9D3ECE0D81970700470E44 /* syncitem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = syncitem.cpp; sourceTree = ""; }; ED9D3ECF0D81970700470E44 /* syncitemtype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = syncitemtype.h; sourceTree = ""; }; ED9D3ED00D81970700470E44 /* syncitemtype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = syncitemtype.cpp; sourceTree = ""; }; ED9D3ED30D81970700470E44 /* syncsession.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = syncsession.h; sourceTree = ""; }; ED9D3ED40D81970700470E44 /* syncsession.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = syncsession.cpp; sourceTree = ""; }; ED9D3ED70D81970700470E44 /* syserial.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = syserial.h; sourceTree = ""; }; ED9D3ED90D81970700470E44 /* sysync.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sysync.h; sourceTree = ""; }; ED9D3EDC0D81970700470E44 /* sysync_crc16.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sysync_crc16.h; sourceTree = ""; }; ED9D3EDD0D81970700470E44 /* sysync_crc16.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sysync_crc16.cpp; sourceTree = ""; }; ED9D3EDE0D81970700470E44 /* sysync_globs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sysync_globs.h; sourceTree = ""; }; ED9D3EE10D81970700470E44 /* sysync_precomp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sysync_precomp.h; sourceTree = ""; }; ED9D3EE20D81970700470E44 /* sysync_precomp_xpt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sysync_precomp_xpt.h; sourceTree = ""; }; ED9D3EE30D81970700470E44 /* stdlogicagent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stdlogicagent.h; sourceTree = ""; }; ED9D3EE40D81970700470E44 /* stdlogicagent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = stdlogicagent.cpp; sourceTree = ""; }; ED9D3EE50D81970700470E44 /* stdlogicds.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stdlogicds.h; sourceTree = ""; }; ED9D3EE60D81970700470E44 /* stdlogicds.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = stdlogicds.cpp; sourceTree = ""; }; ED9D3EE90D81970700470E44 /* textitemtype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = textitemtype.h; sourceTree = ""; }; ED9D3EEA0D81970700470E44 /* textitemtype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = textitemtype.cpp; sourceTree = ""; }; ED9D3EEB0D81970700470E44 /* textprofile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = textprofile.h; sourceTree = ""; }; ED9D3EEC0D81970700470E44 /* textprofile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = textprofile.cpp; sourceTree = ""; }; ED9D3EED0D81970700470E44 /* timezones.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = timezones.h; sourceTree = ""; }; ED9D3EEE0D81970700470E44 /* timezones.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = timezones.cpp; sourceTree = ""; }; ED9D3EEF0D81970700470E44 /* uiapi.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = uiapi.cpp; sourceTree = ""; }; ED9D3EF00D81970700470E44 /* uiapi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uiapi.h; sourceTree = ""; }; ED9D3EF10D81970700470E44 /* vcalendaritemtype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vcalendaritemtype.h; sourceTree = ""; }; ED9D3EF20D81970700470E44 /* vcalendaritemtype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vcalendaritemtype.cpp; sourceTree = ""; }; ED9D3EF30D81970700470E44 /* vcarditemtype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vcarditemtype.h; sourceTree = ""; }; ED9D3EF40D81970700470E44 /* vcarditemtype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vcarditemtype.cpp; sourceTree = ""; }; ED9D3EF50D81970700470E44 /* vtimezone.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vtimezone.h; sourceTree = ""; }; ED9D3EF60D81970700470E44 /* vtimezone.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vtimezone.cpp; sourceTree = ""; }; ED9D3EF70D81970700470E44 /* tz_table.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tz_table.h; sourceTree = ""; }; ED9D3F300D81971700470E44 /* pcre_ord2utf8.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pcre_ord2utf8.c; path = pcre/pcre_ord2utf8.c; sourceTree = ""; }; ED9D3F310D81971700470E44 /* pcre_chartables.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pcre_chartables.c; path = pcre/pcre_chartables.c; sourceTree = ""; }; ED9D3F320D81971700470E44 /* pcre_compile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pcre_compile.c; path = pcre/pcre_compile.c; sourceTree = ""; }; ED9D3F330D81971700470E44 /* pcre_config.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pcre_config.c; path = pcre/pcre_config.c; sourceTree = ""; }; ED9D3F340D81971700470E44 /* pcre_dfa_exec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pcre_dfa_exec.c; path = pcre/pcre_dfa_exec.c; sourceTree = ""; }; ED9D3F350D81971700470E44 /* pcre_exec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pcre_exec.c; path = pcre/pcre_exec.c; sourceTree = ""; }; ED9D3F360D81971700470E44 /* pcre_fullinfo.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pcre_fullinfo.c; path = pcre/pcre_fullinfo.c; sourceTree = ""; }; ED9D3F370D81971700470E44 /* pcre_get.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pcre_get.c; path = pcre/pcre_get.c; sourceTree = ""; }; ED9D3F380D81971700470E44 /* pcre_globals.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pcre_globals.c; path = pcre/pcre_globals.c; sourceTree = ""; }; ED9D3F390D81971700470E44 /* pcre_info.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pcre_info.c; path = pcre/pcre_info.c; sourceTree = ""; }; ED9D3F3A0D81971700470E44 /* pcre_newline.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pcre_newline.c; path = pcre/pcre_newline.c; sourceTree = ""; }; ED9D3F3B0D81971700470E44 /* pcre_refcount.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pcre_refcount.c; path = pcre/pcre_refcount.c; sourceTree = ""; }; ED9D3F3C0D81971700470E44 /* pcre_study.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pcre_study.c; path = pcre/pcre_study.c; sourceTree = ""; }; ED9D3F3D0D81971700470E44 /* pcre_tables.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pcre_tables.c; path = pcre/pcre_tables.c; sourceTree = ""; }; ED9D3F3E0D81971700470E44 /* pcre_try_flipped.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pcre_try_flipped.c; path = pcre/pcre_try_flipped.c; sourceTree = ""; }; ED9D3F3F0D81971700470E44 /* pcre_valid_utf8.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pcre_valid_utf8.c; path = pcre/pcre_valid_utf8.c; sourceTree = ""; }; ED9D3F400D81971700470E44 /* pcre_version.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pcre_version.c; path = pcre/pcre_version.c; sourceTree = ""; }; ED9D3F410D81971700470E44 /* pcre_xclass.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pcre_xclass.c; path = pcre/pcre_xclass.c; sourceTree = ""; }; ED9D3F420D81971700470E44 /* pcre_config_macosx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = pcre_config_macosx.h; path = pcre/pcre_config_macosx.h; sourceTree = ""; }; ED9D3F430D81971700470E44 /* pcre.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = pcre.h; path = pcre/pcre.h; sourceTree = ""; }; ED9D3F450D81971700470E44 /* xmlparse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = xmlparse.c; path = expat/xmlparse/xmlparse.c; sourceTree = ""; }; ED9D3F460D81971700470E44 /* xmlparse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = xmlparse.h; path = expat/xmlparse/xmlparse.h; sourceTree = ""; }; ED9D3F470D81971700470E44 /* xmltok.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = xmltok.c; path = expat/xmltok/xmltok.c; sourceTree = ""; }; ED9D3F480D81971700470E44 /* xmlrole.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = xmlrole.c; path = expat/xmltok/xmlrole.c; sourceTree = ""; }; ED9D3F4A0D81971700470E44 /* zlib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = zlib.h; path = zlib/zlib.h; sourceTree = ""; }; ED9D3F4B0D81971700470E44 /* zutil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = zutil.h; path = zlib/zutil.h; sourceTree = ""; }; ED9D3F4C0D81971700470E44 /* infback.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = infback.c; path = zlib/infback.c; sourceTree = ""; }; ED9D3F4D0D81971700470E44 /* gzio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = gzio.c; path = zlib/gzio.c; sourceTree = ""; }; ED9D3F4E0D81971700470E44 /* deflate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = deflate.c; path = zlib/deflate.c; sourceTree = ""; }; ED9D3F4F0D81971700470E44 /* uncompr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = uncompr.c; path = zlib/uncompr.c; sourceTree = ""; }; ED9D3F500D81971700470E44 /* trees.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = trees.c; path = zlib/trees.c; sourceTree = ""; }; ED9D3F510D81971700470E44 /* inftrees.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = inftrees.c; path = zlib/inftrees.c; sourceTree = ""; }; ED9D3F520D81971700470E44 /* inflate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = inflate.c; path = zlib/inflate.c; sourceTree = ""; }; ED9D3F530D81971700470E44 /* inffast.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = inffast.c; path = zlib/inffast.c; sourceTree = ""; }; ED9D3F540D81971700470E44 /* zutil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = zutil.c; path = zlib/zutil.c; sourceTree = ""; }; ED9D3F550D81971700470E44 /* crc32.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = crc32.c; path = zlib/crc32.c; sourceTree = ""; }; ED9D3F560D81971700470E44 /* compress.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = compress.c; path = zlib/compress.c; sourceTree = ""; }; ED9D3F570D81971700470E44 /* adler32.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = adler32.c; path = zlib/adler32.c; sourceTree = ""; }; EDAC08210F179E78005E9AE2 /* mimedirprofile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mimedirprofile.h; sourceTree = ""; }; EDAC08220F179E78005E9AE2 /* mimedirprofile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mimedirprofile.cpp; sourceTree = ""; }; EDDAFD0111A0989D003E33D5 /* rawdataitemtype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rawdataitemtype.h; sourceTree = ""; }; EDDAFD0211A0989D003E33D5 /* rawdataitemtype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rawdataitemtype.cpp; sourceTree = ""; }; EDDF0813107E435200A119FE /* product_options.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = product_options.h; sourceTree = ""; }; EDE194C61074A04F00439216 /* syncagent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = syncagent.h; sourceTree = ""; }; EDE194C71074A04F00439216 /* syncagent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = syncagent.cpp; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ ED556A3710768FAA0008C22F /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; ED60E87B0DF54F870087381E /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { isa = PBXGroup; children = ( ED9D3D3A0D81959E00470E44 /* global_options.h */, ED9D3D3B0D8195A800470E44 /* sysync_SDK */, ED9D3D6B0D81968D00470E44 /* DB_interfaces */, ED9D3DB70D81969F00470E44 /* syncapps */, ED9D3DD90D8196BB00470E44 /* platform_adapters */, ED9D3DFD0D8196CA00470E44 /* Transport_interfaces */, ED9D3E200D8196F400470E44 /* syncml_tk */, ED9D3E8E0D81970700470E44 /* sysync */, ED9D3F290D81971700470E44 /* External Code */, 29B97323FDCFA39411CA2CEA /* Frameworks */, ED51F986130AE2DA005A04F2 /* Products */, ); name = CustomTemplate; sourceTree = ""; }; 29B97323FDCFA39411CA2CEA /* Frameworks */ = { isa = PBXGroup; children = ( ED9D3CF00D81902F00470E44 /* IOKit.framework */, ED9D3CEC0D81900B00470E44 /* CoreFoundation.framework */, ); name = Frameworks; sourceTree = ""; }; ED51F986130AE2DA005A04F2 /* Products */ = { isa = PBXGroup; children = ( ED1ECBC31383B0DB00B3DA02 /* libsysync_client_ios.a */, ED1ECBC41383B0DB00B3DA02 /* libsysync_combi_ios.a */, ); name = Products; path = ../..; sourceTree = BUILT_PRODUCTS_DIR; }; ED556A3C10768FD90008C22F /* serverEngine_custom */ = { isa = PBXGroup; children = ( ED556A3E10768FD90008C22F /* combi_product_options.h */, ED556A3F10768FD90008C22F /* serverengine_custom.h */, ED556A4010768FD90008C22F /* serverengine_custom_precomp.h */, ED556A4110768FD90008C22F /* serverengine_custom_Base.h */, ED556A4210768FD90008C22F /* serverengine_custom_Base.cpp */, ); path = serverEngine_custom; sourceTree = ""; }; ED806BA80D81A04000F9A79C /* api_db */ = { isa = PBXGroup; children = ( ED9D3D7F0D81968D00470E44 /* sync_dbapiconnect.cpp */, ED9D3D7E0D81968D00470E44 /* sync_dbapiconnect.h */, ED806BAB0D81A0FE00F9A79C /* plugindb.h */, ED806BAC0D81A0FE00F9A79C /* plugindb_precomp.h */, ED9D3D7A0D81968D00470E44 /* dbapi.cpp */, ED9D3D790D81968D00470E44 /* dbapi.h */, ED9D3D7B0D81968D00470E44 /* dbapi_include.h */, ED9D3D760D81968D00470E44 /* pluginapiagent.cpp */, ED9D3D750D81968D00470E44 /* pluginapiagent.h */, ED9D3D780D81968D00470E44 /* pluginapids.cpp */, ED9D3D770D81968D00470E44 /* pluginapids.h */, ED9D3D7D0D81968D00470E44 /* DLL_interface.cpp */, ED9D3D7C0D81968D00470E44 /* DLL_interface.h */, ); path = api_db; sourceTree = ""; }; ED806BB50D81A58800F9A79C /* lib */ = { isa = PBXGroup; children = ( ED806BB60D81A58800F9A79C /* all */, ED806BBB0D81A58800F9A79C /* inc */, ); path = lib; sourceTree = ""; }; ED806BB60D81A58800F9A79C /* all */ = { isa = PBXGroup; children = ( ED806BB70D81A58800F9A79C /* liblock.c */, ED806BB80D81A58800F9A79C /* libmem.c */, ED806BB90D81A58800F9A79C /* libstr.c */, ED806BBA0D81A58800F9A79C /* libutil.c */, ); path = all; sourceTree = ""; }; ED806BBB0D81A58800F9A79C /* inc */ = { isa = PBXGroup; children = ( ED806BBC0D81A58800F9A79C /* liblock.h */, ED806BBD0D81A58800F9A79C /* libmem.h */, ED806BBE0D81A58800F9A79C /* libstr.h */, ED806BBF0D81A58800F9A79C /* libutil.h */, ); path = inc; sourceTree = ""; }; ED806BC40D81A5AD00F9A79C /* inc */ = { isa = PBXGroup; children = ( ED806BC70D81A5AD00F9A79C /* sml.h */, ED806BC80D81A5AD00F9A79C /* smldef.h */, ED806BC90D81A5AD00F9A79C /* smldevinfdtd.h */, ED806BCA0D81A5AD00F9A79C /* smldtd.h */, ED806BCB0D81A5AD00F9A79C /* smlerr.h */, ED806BCC0D81A5AD00F9A79C /* smlmetinfdtd.h */, ); path = inc; sourceTree = ""; }; ED806BCF0D81A5D500F9A79C /* mgr */ = { isa = PBXGroup; children = ( ED806BD00D81A5D500F9A79C /* all */, ED806BD70D81A5D500F9A79C /* inc */, ); path = mgr; sourceTree = ""; }; ED806BD00D81A5D500F9A79C /* all */ = { isa = PBXGroup; children = ( ED806BD10D81A5D500F9A79C /* mgr.c */, ED806BD20D81A5D500F9A79C /* mgrcmdbuilder.c */, ED806BD30D81A5D500F9A79C /* mgrcmddispatcher.c */, ED806BD40D81A5D500F9A79C /* mgrinstancelist.c */, ED806BD50D81A5D500F9A79C /* mgrinstancemgr.c */, ED806BD60D81A5D500F9A79C /* mgrutil.c */, ); path = all; sourceTree = ""; }; ED806BD70D81A5D500F9A79C /* inc */ = { isa = PBXGroup; children = ( ED806BD80D81A5D500F9A79C /* mgr.h */, ED806BD90D81A5D500F9A79C /* mgrutil.h */, ); path = inc; sourceTree = ""; }; ED806BE30D81A5F400F9A79C /* xlt */ = { isa = PBXGroup; children = ( ED806BE40D81A5F400F9A79C /* all */, ED806BFA0D81A5F400F9A79C /* inc */, ); path = xlt; sourceTree = ""; }; ED806BE40D81A5F400F9A79C /* all */ = { isa = PBXGroup; children = ( ED806BE50D81A5F400F9A79C /* xltdec.c */, ED806BE60D81A5F400F9A79C /* xltdeccom.h */, ED806BE70D81A5F400F9A79C /* xltdecwbxml.c */, ED806BE80D81A5F400F9A79C /* xltdecwbxml.h */, ED806BE90D81A5F400F9A79C /* xltdecxml.c */, ED806BEA0D81A5F400F9A79C /* xltdevinf.c */, ED806BEB0D81A5F400F9A79C /* xltdevinf.h */, ED806BEC0D81A5F400F9A79C /* xltenc.c */, ED806BED0D81A5F400F9A79C /* xltenccom.c */, ED806BEE0D81A5F400F9A79C /* xltenccom.h */, ED806BEF0D81A5F400F9A79C /* xltencwbxml.c */, ED806BF00D81A5F400F9A79C /* xltencwbxml.h */, ED806BF10D81A5F400F9A79C /* xltencxml.c */, ED806BF20D81A5F400F9A79C /* xltencxml.h */, ED806BF30D81A5F400F9A79C /* xltmetinf.c */, ED806BF40D81A5F400F9A79C /* xltmetinf.h */, ED806BF50D81A5F400F9A79C /* xlttags.c */, ED806BF60D81A5F400F9A79C /* xlttags.h */, ED806BF70D81A5F400F9A79C /* xlttagtbl.h */, ED806BF80D81A5F400F9A79C /* xltutilstack.c */, ED806BF90D81A5F400F9A79C /* xltutilstack.h */, ); path = all; sourceTree = ""; }; ED806BFA0D81A5F400F9A79C /* inc */ = { isa = PBXGroup; children = ( ED806BFB0D81A5F400F9A79C /* xltdec.h */, ED806BFC0D81A5F400F9A79C /* xltenc.h */, ); path = inc; sourceTree = ""; }; ED806C370D81A89E00F9A79C /* wsm */ = { isa = PBXGroup; children = ( ED806C3A0D81A89E00F9A79C /* inc */, ); name = wsm; path = src/sml/wsm; sourceTree = ""; }; ED806C3A0D81A89E00F9A79C /* inc */ = { isa = PBXGroup; children = ( ED806C3B0D81A89E00F9A79C /* wsm.h */, ); path = inc; sourceTree = ""; }; ED9D3D3B0D8195A800470E44 /* sysync_SDK */ = { isa = PBXGroup; children = ( ED4B5E9511523AAB00ECB4A5 /* sysync_utils.h */, ED4B5E9611523AAB00ECB4A5 /* sysync_utils.cpp */, ED4B5E9711523AAB00ECB4A5 /* syncexception.cpp */, ED4B5E9A11523AAB00ECB4A5 /* lineartime.cpp */, ED4B5E9B11523AAB00ECB4A5 /* san.cpp */, ED4B5E9C11523AAB00ECB4A5 /* san.h */, ED4B5E9D11523AAB00ECB4A5 /* sysync_md5.h */, ED4B5E9E11523AAB00ECB4A5 /* sysync_md5.cpp */, ED4B5E9F11523AAB00ECB4A5 /* sysync_b64.h */, ED4B5EA011523AAB00ECB4A5 /* sysync_b64.cpp */, ED4B5EA111523AAB00ECB4A5 /* syncexception.h */, ED4B5EA211523AAB00ECB4A5 /* lineartime.h */, ED9D3D880D81968D00470E44 /* DB_Interfaces */, ED9D3D3C0D8195A800470E44 /* enginemodulebase.cpp */, ED9D3D3D0D8195A800470E44 /* enginemodulebase.h */, ED9D3D3E0D8195A800470E44 /* engine_defs.h */, ED9D3D3F0D8195A800470E44 /* generic_types.h */, ED9D3D400D8195A800470E44 /* syerror.h */, ED9D3D970D81968D00470E44 /* admindata.cpp */, ED9D3D960D81968D00470E44 /* admindata.h */, ED9D3D990D81968D00470E44 /* blobs.cpp */, ED9D3D980D81968D00470E44 /* blobs.h */, ED9D3D9B0D81968D00470E44 /* dbitem.cpp */, ED9D3D9A0D81968D00470E44 /* dbitem.h */, ED9D3D810D81968D00470E44 /* sync_include.h */, ED9D3D820D81968D00470E44 /* sync_dbapidef.h */, ED9D3D830D81968D00470E44 /* sync_dbapi.h */, ED55B6990DDDBCBC001657F6 /* sync_uiapi.h */, ED9D3D840D81968D00470E44 /* SDK_util.h */, ED9D3D850D81968D00470E44 /* SDK_util.c */, ED9D3D870D81968D00470E44 /* SDK_support.cpp */, ED9D3D860D81968D00470E44 /* SDK_support.h */, ); name = sysync_SDK; path = sysync_SDK/Sources; sourceTree = ""; }; ED9D3D6B0D81968D00470E44 /* DB_interfaces */ = { isa = PBXGroup; children = ( ED806BA80D81A04000F9A79C /* api_db */, ED9D3D6C0D81968D00470E44 /* odbc_db */, ); path = DB_interfaces; sourceTree = ""; }; ED9D3D6C0D81968D00470E44 /* odbc_db */ = { isa = PBXGroup; children = ( ED9D3D6D0D81968D00470E44 /* odbcdb.h */, ED9D3D6E0D81968D00470E44 /* odbcdb_precomp.h */, ED9D3D6F0D81968D00470E44 /* odbcapiagent.h */, ED9D3D700D81968D00470E44 /* odbcapiagent.cpp */, ED9D3D710D81968D00470E44 /* odbcapids.h */, ED9D3D720D81968D00470E44 /* odbcapids.cpp */, ); path = odbc_db; sourceTree = ""; }; ED9D3D880D81968D00470E44 /* DB_Interfaces */ = { isa = PBXGroup; children = ( ED9D3D930D81968D00470E44 /* text_db */, ); name = DB_Interfaces; path = ../DB_Interfaces; sourceTree = ""; }; ED9D3D930D81968D00470E44 /* text_db */ = { isa = PBXGroup; children = ( ED9D3D940D81968D00470E44 /* sync_dbapi_text.cpp */, ); path = text_db; sourceTree = ""; }; ED9D3DB70D81969F00470E44 /* syncapps */ = { isa = PBXGroup; children = ( ED556A3C10768FD90008C22F /* serverEngine_custom */, ED9D3DB80D81969F00470E44 /* clientEngine_custom */, ); path = syncapps; sourceTree = ""; }; ED9D3DB80D81969F00470E44 /* clientEngine_custom */ = { isa = PBXGroup; children = ( EDDF0813107E435200A119FE /* product_options.h */, ED9D3DBA0D81969F00470E44 /* clientengine_custom.h */, ED9D3DBB0D81969F00470E44 /* clientengine_custom_precomp.h */, ED9D3DBC0D81969F00470E44 /* clientengine_custom_Base.h */, ED9D3DBD0D81969F00470E44 /* clientengine_custom_Base.cpp */, ); path = clientEngine_custom; sourceTree = ""; }; ED9D3DD90D8196BB00470E44 /* platform_adapters */ = { isa = PBXGroup; children = ( ED9D3DDA0D8196BB00470E44 /* unix_common */, ED9D3DE00D8196BB00470E44 /* macosx */, ED9D3DE90D8196BB00470E44 /* binfile.cpp */, ED9D3DEA0D8196BB00470E44 /* binfile.h */, ED9D3DEB0D8196BB00470E44 /* configfiles.h */, ED9D3DED0D8196BB00470E44 /* platform_thread.h */, ED9D3DEE0D8196BB00470E44 /* platform_mutex.h */, ED9D3DEF0D8196BB00470E44 /* platform_file.h */, ED9D3DF00D8196BB00470E44 /* profiling.h */, ED9D3DF10D8196BB00470E44 /* sysyncinit.cpp */, ); path = platform_adapters; sourceTree = ""; }; ED9D3DDA0D8196BB00470E44 /* unix_common */ = { isa = PBXGroup; children = ( ED9D3DDB0D8196BB00470E44 /* platform_pipe.h */, ED9D3DDC0D8196BB00470E44 /* platform_pipe.c */, ED9D3DDD0D8196BB00470E44 /* platform_thread.cpp */, ED9D3DDE0D8196BB00470E44 /* platform_mutex.cpp */, ED9D3DDF0D8196BB00470E44 /* platform_file.cpp */, ); path = unix_common; sourceTree = ""; }; ED9D3DE00D8196BB00470E44 /* macosx */ = { isa = PBXGroup; children = ( ED5B87FA0F8559C40042779A /* platform_timezones.mm */, ED43DAD60E014BC9000A1E5C /* configfiles.mm */, ED16A68D14B9B4E400F24032 /* platform_DLL.h */, ED9D3DE30D8196BB00470E44 /* platform_exec.h */, ED9D3DE40D8196BB00470E44 /* platform_exec.c */, ED9D3DE50D8196BB00470E44 /* platform_headers.h */, ED9D3DE60D8196BB00470E44 /* platform_time.h */, ED9D3DE70D8196BB00470E44 /* platform_time.cpp */, ED9D3DE80D8196BB00470E44 /* profiling.cpp */, ); path = macosx; sourceTree = ""; }; ED9D3DFD0D8196CA00470E44 /* Transport_interfaces */ = { isa = PBXGroup; children = ( ED9D3DFE0D8196CA00470E44 /* engine */, ); path = Transport_interfaces; sourceTree = ""; }; ED9D3DFE0D8196CA00470E44 /* engine */ = { isa = PBXGroup; children = ( ED556A4E107692F20008C22F /* enginesessiondispatch.cpp */, ED556A4F107692F20008C22F /* enginesessiondispatch.h */, ED9D3DFF0D8196CA00470E44 /* engine_client_precomp.h */, ED9D3E000D8196CA00470E44 /* engine_client.h */, ED9D3E010D8196CA00470E44 /* engineclientbase.cpp */, ED9D3E020D8196CA00470E44 /* engineclientbase.h */, ); path = engine; sourceTree = ""; }; ED9D3E200D8196F400470E44 /* syncml_tk */ = { isa = PBXGroup; children = ( ED806C370D81A89E00F9A79C /* wsm */, ED9D3E210D8196F400470E44 /* sml */, ); path = syncml_tk; sourceTree = ""; }; ED9D3E210D8196F400470E44 /* sml */ = { isa = PBXGroup; children = ( ED806BC40D81A5AD00F9A79C /* inc */, ED806BB50D81A58800F9A79C /* lib */, ED806BCF0D81A5D500F9A79C /* mgr */, ED806BE30D81A5F400F9A79C /* xlt */, ); name = sml; path = src/sml; sourceTree = ""; }; ED9D3E8E0D81970700470E44 /* sysync */ = { isa = PBXGroup; children = ( ED9D3E8F0D81970700470E44 /* binfilebase.cpp */, ED9D3E900D81970700470E44 /* binfilebase.h */, ED9D3E910D81970700470E44 /* binfileimplclient.cpp */, ED9D3E920D81970700470E44 /* binfileimplclient.h */, ED9D3E930D81970700470E44 /* binfileimplds.cpp */, ED9D3E940D81970700470E44 /* binfileimplds.h */, ED9D3E950D81970700470E44 /* engineentry.cpp */, ED9D3E960D81970700470E44 /* engineentry.h */, ED9D3E970D81970700470E44 /* engineinterface.cpp */, ED9D3E980D81970700470E44 /* engineinterface.h */, ED9D3E990D81970700470E44 /* configelement.h */, ED9D3E9A0D81970700470E44 /* configelement.cpp */, ED9D3E9B0D81970700470E44 /* customimplds.h */, ED9D3E9C0D81970700470E44 /* customimplds.cpp */, ED9D3E9D0D81970700470E44 /* customimplagent.h */, ED9D3E9E0D81970700470E44 /* customimplagent.cpp */, ED9D3E9F0D81970700470E44 /* dataobjtype.h */, ED9D3EA00D81970700470E44 /* dataobjtype.cpp */, ED9D3EA10D81970700470E44 /* debuglogger.h */, ED9D3EA20D81970700470E44 /* debuglogger.cpp */, ED9D3EA30D81970700470E44 /* iso8601.h */, ED9D3EA40D81970700470E44 /* iso8601.cpp */, ED9D3EA50D81970700470E44 /* itemfield.h */, ED9D3EA60D81970700470E44 /* itemfield.cpp */, ED9D3EA90D81970700470E44 /* localengineds.h */, ED9D3EAA0D81970700470E44 /* localengineds.cpp */, ED9D3EAB0D81970700470E44 /* mimediritemtype.h */, ED9D3EAC0D81970700470E44 /* mimediritemtype.cpp */, EDAC08210F179E78005E9AE2 /* mimedirprofile.h */, EDAC08220F179E78005E9AE2 /* mimedirprofile.cpp */, ED9D3EAD0D81970700470E44 /* multifielditem.h */, ED9D3EAE0D81970700470E44 /* multifielditem.cpp */, ED9D3EAF0D81970700470E44 /* multifielditemtype.h */, ED9D3EB00D81970700470E44 /* multifielditemtype.cpp */, EDDAFD0111A0989D003E33D5 /* rawdataitemtype.h */, EDDAFD0211A0989D003E33D5 /* rawdataitemtype.cpp */, ED9D3EB10D81970700470E44 /* remotedatastore.h */, ED9D3EB20D81970700470E44 /* remotedatastore.cpp */, ED9D3EB30D81970700470E44 /* rrules.h */, ED9D3EB40D81970700470E44 /* rrules.cpp */, ED9D3EB70D81970700470E44 /* scriptcontext.h */, ED9D3EB80D81970700470E44 /* scriptcontext.cpp */, ED9D3EB90D81970700470E44 /* simpleitem.h */, ED9D3EBA0D81970700470E44 /* simpleitem.cpp */, ED9D3EBB0D81970700470E44 /* smltk_precomp.h */, ED9D3EBC0D81970700470E44 /* smltk_precomp_xpt.h */, ED9D3EBD0D81970700470E44 /* stringutils.h */, ED9D3EBE0D81970700470E44 /* stringutils.cpp */, ED9D3EBF0D81970700470E44 /* superdatastore.h */, ED9D3EC00D81970700470E44 /* superdatastore.cpp */, ED9D3EC10D81970700470E44 /* syncappbase.h */, ED9D3EC20D81970700470E44 /* syncappbase.cpp */, EDE194C61074A04F00439216 /* syncagent.h */, EDE194C71074A04F00439216 /* syncagent.cpp */, ED9D3EC50D81970700470E44 /* syncclientbase.h */, ED9D3EC60D81970700470E44 /* syncclientbase.cpp */, ED9D3EC70D81970700470E44 /* synccommand.h */, ED9D3EC80D81970700470E44 /* synccommand.cpp */, ED9D3EC90D81970700470E44 /* syncdatastore.h */, ED9D3ECA0D81970700470E44 /* syncdatastore.cpp */, ED9D3ECD0D81970700470E44 /* syncitem.h */, ED9D3ECE0D81970700470E44 /* syncitem.cpp */, ED9D3ECF0D81970700470E44 /* syncitemtype.h */, ED9D3ED00D81970700470E44 /* syncitemtype.cpp */, ED9D3ED30D81970700470E44 /* syncsession.h */, ED9D3ED40D81970700470E44 /* syncsession.cpp */, ED9D3ED70D81970700470E44 /* syserial.h */, ED9D3ED90D81970700470E44 /* sysync.h */, ED9D3EDC0D81970700470E44 /* sysync_crc16.h */, ED9D3EDD0D81970700470E44 /* sysync_crc16.cpp */, ED55B6960DDDBC43001657F6 /* sysync_debug.h */, ED9D3EDE0D81970700470E44 /* sysync_globs.h */, ED9D3EE10D81970700470E44 /* sysync_precomp.h */, ED9D3EE20D81970700470E44 /* sysync_precomp_xpt.h */, ED9D3EE30D81970700470E44 /* stdlogicagent.h */, ED9D3EE40D81970700470E44 /* stdlogicagent.cpp */, ED9D3EE50D81970700470E44 /* stdlogicds.h */, ED9D3EE60D81970700470E44 /* stdlogicds.cpp */, ED9D3EE90D81970700470E44 /* textitemtype.h */, ED9D3EEA0D81970700470E44 /* textitemtype.cpp */, ED9D3EEB0D81970700470E44 /* textprofile.h */, ED9D3EEC0D81970700470E44 /* textprofile.cpp */, ED9D3EED0D81970700470E44 /* timezones.h */, ED9D3EEE0D81970700470E44 /* timezones.cpp */, ED9D3EEF0D81970700470E44 /* uiapi.cpp */, ED9D3EF00D81970700470E44 /* uiapi.h */, ED9D3EF10D81970700470E44 /* vcalendaritemtype.h */, ED9D3EF20D81970700470E44 /* vcalendaritemtype.cpp */, ED9D3EF30D81970700470E44 /* vcarditemtype.h */, ED9D3EF40D81970700470E44 /* vcarditemtype.cpp */, ED9D3EF50D81970700470E44 /* vtimezone.h */, ED9D3EF60D81970700470E44 /* vtimezone.cpp */, ED9D3EF70D81970700470E44 /* tz_table.h */, ); path = sysync; sourceTree = ""; }; ED9D3F290D81971700470E44 /* External Code */ = { isa = PBXGroup; children = ( ED9D3F490D81971700470E44 /* zlib */, ED9D3F440D81971700470E44 /* expat */, ED9D3F2F0D81971700470E44 /* pcre */, ); name = "External Code"; sourceTree = ""; }; ED9D3F2F0D81971700470E44 /* pcre */ = { isa = PBXGroup; children = ( ED9D3F300D81971700470E44 /* pcre_ord2utf8.c */, ED9D3F310D81971700470E44 /* pcre_chartables.c */, ED9D3F320D81971700470E44 /* pcre_compile.c */, ED9D3F330D81971700470E44 /* pcre_config.c */, ED9D3F340D81971700470E44 /* pcre_dfa_exec.c */, ED9D3F350D81971700470E44 /* pcre_exec.c */, ED9D3F360D81971700470E44 /* pcre_fullinfo.c */, ED9D3F370D81971700470E44 /* pcre_get.c */, ED9D3F380D81971700470E44 /* pcre_globals.c */, ED9D3F390D81971700470E44 /* pcre_info.c */, ED9D3F3A0D81971700470E44 /* pcre_newline.c */, ED9D3F3B0D81971700470E44 /* pcre_refcount.c */, ED9D3F3C0D81971700470E44 /* pcre_study.c */, ED9D3F3D0D81971700470E44 /* pcre_tables.c */, ED9D3F3E0D81971700470E44 /* pcre_try_flipped.c */, ED9D3F3F0D81971700470E44 /* pcre_valid_utf8.c */, ED9D3F400D81971700470E44 /* pcre_version.c */, ED9D3F410D81971700470E44 /* pcre_xclass.c */, ED9D3F420D81971700470E44 /* pcre_config_macosx.h */, ED9D3F430D81971700470E44 /* pcre.h */, ); name = pcre; sourceTree = ""; }; ED9D3F440D81971700470E44 /* expat */ = { isa = PBXGroup; children = ( ED55B6AF0DDDBDD9001657F6 /* ascii.h */, ED55B6B00DDDBDD9001657F6 /* asciitab.h */, ED55B6B10DDDBDD9001657F6 /* iasciitab.h */, ED55B6B20DDDBDD9001657F6 /* latin1tab.h */, ED55B6B30DDDBDD9001657F6 /* nametab.h */, ED55B6B40DDDBDD9001657F6 /* utf8tab.h */, ED55B6B50DDDBDD9001657F6 /* xmlrole.h */, ED55B6A90DDDBD4E001657F6 /* xmldef.h */, ED55B69C0DDDBD0A001657F6 /* xmltok.h */, ED9D3F450D81971700470E44 /* xmlparse.c */, ED9D3F460D81971700470E44 /* xmlparse.h */, ED9D3F470D81971700470E44 /* xmltok.c */, ED9D3F480D81971700470E44 /* xmlrole.c */, ); name = expat; sourceTree = ""; }; ED9D3F490D81971700470E44 /* zlib */ = { isa = PBXGroup; children = ( ED9D3F4A0D81971700470E44 /* zlib.h */, ED9D3F4B0D81971700470E44 /* zutil.h */, ED9D3F4C0D81971700470E44 /* infback.c */, ED9D3F4D0D81971700470E44 /* gzio.c */, ED9D3F4E0D81971700470E44 /* deflate.c */, ED9D3F4F0D81971700470E44 /* uncompr.c */, ED9D3F500D81971700470E44 /* trees.c */, ED9D3F510D81971700470E44 /* inftrees.c */, ED9D3F520D81971700470E44 /* inflate.c */, ED9D3F530D81971700470E44 /* inffast.c */, ED9D3F540D81971700470E44 /* zutil.c */, ED9D3F550D81971700470E44 /* crc32.c */, ED9D3F560D81971700470E44 /* compress.c */, ED9D3F570D81971700470E44 /* adler32.c */, ); name = zlib; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ ED55691E10768FAA0008C22F /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ED55691F10768FAA0008C22F /* enginemodulebase.h in Headers */, ED55692010768FAA0008C22F /* engine_defs.h in Headers */, ED55692110768FAA0008C22F /* generic_types.h in Headers */, ED55692210768FAA0008C22F /* syerror.h in Headers */, ED55692310768FAA0008C22F /* admindata.h in Headers */, ED55692410768FAA0008C22F /* blobs.h in Headers */, ED55692510768FAA0008C22F /* dbitem.h in Headers */, ED55692610768FAA0008C22F /* sync_include.h in Headers */, ED55692710768FAA0008C22F /* sync_dbapidef.h in Headers */, ED55692810768FAA0008C22F /* sync_dbapi.h in Headers */, ED55692910768FAA0008C22F /* SDK_util.h in Headers */, ED55692A10768FAA0008C22F /* SDK_support.h in Headers */, ED55692B10768FAA0008C22F /* sync_dbapiconnect.h in Headers */, ED55692C10768FAA0008C22F /* plugindb.h in Headers */, ED55692D10768FAA0008C22F /* plugindb_precomp.h in Headers */, ED55692E10768FAA0008C22F /* dbapi.h in Headers */, ED55692F10768FAA0008C22F /* dbapi_include.h in Headers */, ED55693010768FAA0008C22F /* pluginapiagent.h in Headers */, ED55693110768FAA0008C22F /* pluginapids.h in Headers */, ED55693210768FAA0008C22F /* DLL_interface.h in Headers */, ED55693310768FAA0008C22F /* odbcdb.h in Headers */, ED55693410768FAA0008C22F /* odbcdb_precomp.h in Headers */, ED55693510768FAA0008C22F /* odbcapiagent.h in Headers */, ED55693610768FAA0008C22F /* odbcapids.h in Headers */, ED55693810768FAA0008C22F /* clientengine_custom.h in Headers */, ED55693910768FAA0008C22F /* clientengine_custom_precomp.h in Headers */, ED55693A10768FAA0008C22F /* clientengine_custom_Base.h in Headers */, ED55693B10768FAA0008C22F /* platform_pipe.h in Headers */, ED55693C10768FAA0008C22F /* platform_exec.h in Headers */, ED55693D10768FAA0008C22F /* platform_headers.h in Headers */, ED55693E10768FAA0008C22F /* platform_time.h in Headers */, ED55693F10768FAA0008C22F /* binfile.h in Headers */, ED55694010768FAA0008C22F /* configfiles.h in Headers */, ED55694210768FAA0008C22F /* platform_thread.h in Headers */, ED55694310768FAA0008C22F /* platform_mutex.h in Headers */, ED55694410768FAA0008C22F /* platform_file.h in Headers */, ED55694510768FAA0008C22F /* profiling.h in Headers */, ED55694610768FAA0008C22F /* engine_client_precomp.h in Headers */, ED55694710768FAA0008C22F /* engine_client.h in Headers */, ED55694810768FAA0008C22F /* engineclientbase.h in Headers */, ED55694910768FAA0008C22F /* wsm.h in Headers */, ED55694A10768FAA0008C22F /* sml.h in Headers */, ED55694B10768FAA0008C22F /* smldef.h in Headers */, ED55694C10768FAA0008C22F /* smldevinfdtd.h in Headers */, ED55694D10768FAA0008C22F /* smldtd.h in Headers */, ED55694E10768FAA0008C22F /* smlerr.h in Headers */, ED55694F10768FAA0008C22F /* smlmetinfdtd.h in Headers */, ED55695010768FAA0008C22F /* liblock.h in Headers */, ED55695110768FAA0008C22F /* libmem.h in Headers */, ED55695210768FAA0008C22F /* libstr.h in Headers */, ED55695310768FAA0008C22F /* libutil.h in Headers */, ED55695410768FAA0008C22F /* mgr.h in Headers */, ED55695510768FAA0008C22F /* mgrutil.h in Headers */, ED55695610768FAA0008C22F /* xltdeccom.h in Headers */, ED55695710768FAA0008C22F /* xltdecwbxml.h in Headers */, ED55695810768FAA0008C22F /* xltdevinf.h in Headers */, ED55695910768FAA0008C22F /* xltenccom.h in Headers */, ED55695A10768FAA0008C22F /* xltencwbxml.h in Headers */, ED55695B10768FAA0008C22F /* xltencxml.h in Headers */, ED55695C10768FAA0008C22F /* xltmetinf.h in Headers */, ED55695D10768FAA0008C22F /* xlttags.h in Headers */, ED55695E10768FAA0008C22F /* xlttagtbl.h in Headers */, ED55695F10768FAA0008C22F /* xltutilstack.h in Headers */, ED55696010768FAA0008C22F /* xltdec.h in Headers */, ED55696110768FAA0008C22F /* xltenc.h in Headers */, ED55696210768FAA0008C22F /* binfilebase.h in Headers */, ED55696310768FAA0008C22F /* binfileimplclient.h in Headers */, ED55696410768FAA0008C22F /* binfileimplds.h in Headers */, ED55696510768FAA0008C22F /* engineentry.h in Headers */, ED55696610768FAA0008C22F /* engineinterface.h in Headers */, ED55696710768FAA0008C22F /* configelement.h in Headers */, ED55696810768FAA0008C22F /* customimplds.h in Headers */, ED55696910768FAA0008C22F /* customimplagent.h in Headers */, ED55696A10768FAA0008C22F /* dataobjtype.h in Headers */, ED55696B10768FAA0008C22F /* debuglogger.h in Headers */, ED55696C10768FAA0008C22F /* iso8601.h in Headers */, ED55696D10768FAA0008C22F /* itemfield.h in Headers */, ED55696F10768FAA0008C22F /* localengineds.h in Headers */, ED55697010768FAA0008C22F /* mimediritemtype.h in Headers */, ED55697110768FAA0008C22F /* multifielditem.h in Headers */, ED55697210768FAA0008C22F /* multifielditemtype.h in Headers */, ED55697310768FAA0008C22F /* remotedatastore.h in Headers */, ED55697410768FAA0008C22F /* rrules.h in Headers */, ED55697610768FAA0008C22F /* scriptcontext.h in Headers */, ED55697710768FAA0008C22F /* simpleitem.h in Headers */, ED55697810768FAA0008C22F /* smltk_precomp.h in Headers */, ED55697910768FAA0008C22F /* smltk_precomp_xpt.h in Headers */, ED55697A10768FAA0008C22F /* stringutils.h in Headers */, ED55697B10768FAA0008C22F /* superdatastore.h in Headers */, ED55697C10768FAA0008C22F /* syncappbase.h in Headers */, ED55697D10768FAA0008C22F /* syncclientbase.h in Headers */, ED55697E10768FAA0008C22F /* synccommand.h in Headers */, ED55697F10768FAA0008C22F /* syncdatastore.h in Headers */, ED55698110768FAA0008C22F /* syncitem.h in Headers */, ED55698210768FAA0008C22F /* syncitemtype.h in Headers */, ED55698310768FAA0008C22F /* syncsession.h in Headers */, ED55698410768FAA0008C22F /* syserial.h in Headers */, ED55698510768FAA0008C22F /* sysync.h in Headers */, ED55698710768FAA0008C22F /* sysync_crc16.h in Headers */, ED55698810768FAA0008C22F /* sysync_globs.h in Headers */, ED55698A10768FAA0008C22F /* sysync_precomp.h in Headers */, ED55698B10768FAA0008C22F /* sysync_precomp_xpt.h in Headers */, ED55698C10768FAA0008C22F /* stdlogicagent.h in Headers */, ED55698D10768FAA0008C22F /* stdlogicds.h in Headers */, ED55698F10768FAA0008C22F /* textitemtype.h in Headers */, ED55699010768FAA0008C22F /* textprofile.h in Headers */, ED55699110768FAA0008C22F /* timezones.h in Headers */, ED55699210768FAA0008C22F /* uiapi.h in Headers */, ED55699310768FAA0008C22F /* vcalendaritemtype.h in Headers */, ED55699410768FAA0008C22F /* vcarditemtype.h in Headers */, ED55699510768FAA0008C22F /* vtimezone.h in Headers */, ED55699610768FAA0008C22F /* tz_table.h in Headers */, ED55699710768FAA0008C22F /* zlib.h in Headers */, ED55699810768FAA0008C22F /* zutil.h in Headers */, ED55699910768FAA0008C22F /* xmlparse.h in Headers */, ED55699A10768FAA0008C22F /* pcre_config_macosx.h in Headers */, ED55699B10768FAA0008C22F /* pcre.h in Headers */, ED55699C10768FAA0008C22F /* sysync_debug.h in Headers */, ED55699D10768FAA0008C22F /* sync_uiapi.h in Headers */, ED55699E10768FAA0008C22F /* xmltok.h in Headers */, ED55699F10768FAA0008C22F /* xmldef.h in Headers */, ED5569A010768FAA0008C22F /* ascii.h in Headers */, ED5569A110768FAA0008C22F /* asciitab.h in Headers */, ED5569A210768FAA0008C22F /* iasciitab.h in Headers */, ED5569A310768FAA0008C22F /* latin1tab.h in Headers */, ED5569A410768FAA0008C22F /* nametab.h in Headers */, ED5569A510768FAA0008C22F /* utf8tab.h in Headers */, ED5569A610768FAA0008C22F /* xmlrole.h in Headers */, ED5569AA10768FAA0008C22F /* mimedirprofile.h in Headers */, ED5569AB10768FAA0008C22F /* syncagent.h in Headers */, ED556A4410768FD90008C22F /* combi_product_options.h in Headers */, ED556A4510768FD90008C22F /* serverengine_custom.h in Headers */, ED556A4610768FD90008C22F /* serverengine_custom_precomp.h in Headers */, ED556A4710768FD90008C22F /* serverengine_custom_Base.h in Headers */, ED556A51107692F20008C22F /* enginesessiondispatch.h in Headers */, EDDF0814107E435200A119FE /* product_options.h in Headers */, ED4B5ECD11523AAB00ECB4A5 /* sysync_utils.h in Headers */, ED4B5ED411523AAB00ECB4A5 /* san.h in Headers */, ED4B5ED511523AAB00ECB4A5 /* sysync_md5.h in Headers */, ED4B5ED711523AAB00ECB4A5 /* sysync_b64.h in Headers */, ED4B5ED911523AAB00ECB4A5 /* syncexception.h in Headers */, ED4B5EDA11523AAB00ECB4A5 /* lineartime.h in Headers */, EDDAFD0911A0989D003E33D5 /* rawdataitemtype.h in Headers */, ED16A68F14B9B4E400F24032 /* platform_DLL.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; ED60E7670DF54F870087381E /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ED60E7680DF54F870087381E /* enginemodulebase.h in Headers */, ED60E7690DF54F870087381E /* engine_defs.h in Headers */, ED60E76A0DF54F870087381E /* generic_types.h in Headers */, ED60E76B0DF54F870087381E /* syerror.h in Headers */, ED60E76C0DF54F870087381E /* admindata.h in Headers */, ED60E76D0DF54F870087381E /* blobs.h in Headers */, ED60E76E0DF54F870087381E /* dbitem.h in Headers */, ED60E76F0DF54F870087381E /* sync_include.h in Headers */, ED60E7700DF54F870087381E /* sync_dbapidef.h in Headers */, ED60E7710DF54F870087381E /* sync_dbapi.h in Headers */, ED60E7720DF54F870087381E /* SDK_util.h in Headers */, ED60E7730DF54F870087381E /* SDK_support.h in Headers */, ED60E7740DF54F870087381E /* sync_dbapiconnect.h in Headers */, ED60E7750DF54F870087381E /* plugindb.h in Headers */, ED60E7760DF54F870087381E /* plugindb_precomp.h in Headers */, ED60E7770DF54F870087381E /* dbapi.h in Headers */, ED60E7780DF54F870087381E /* dbapi_include.h in Headers */, ED60E7790DF54F870087381E /* pluginapiagent.h in Headers */, ED60E77A0DF54F870087381E /* pluginapids.h in Headers */, ED60E77B0DF54F870087381E /* DLL_interface.h in Headers */, ED60E77C0DF54F870087381E /* odbcdb.h in Headers */, ED60E77D0DF54F870087381E /* odbcdb_precomp.h in Headers */, ED60E77E0DF54F870087381E /* odbcapiagent.h in Headers */, ED60E77F0DF54F870087381E /* odbcapids.h in Headers */, ED60E7810DF54F870087381E /* clientengine_custom.h in Headers */, ED60E7820DF54F870087381E /* clientengine_custom_precomp.h in Headers */, ED60E7830DF54F870087381E /* clientengine_custom_Base.h in Headers */, ED60E7840DF54F870087381E /* platform_pipe.h in Headers */, ED60E7850DF54F870087381E /* platform_exec.h in Headers */, ED60E7860DF54F870087381E /* platform_headers.h in Headers */, ED60E7870DF54F870087381E /* platform_time.h in Headers */, ED60E7880DF54F870087381E /* binfile.h in Headers */, ED60E7890DF54F870087381E /* configfiles.h in Headers */, ED60E78B0DF54F870087381E /* platform_thread.h in Headers */, ED60E78C0DF54F870087381E /* platform_mutex.h in Headers */, ED60E78D0DF54F870087381E /* platform_file.h in Headers */, ED60E78E0DF54F870087381E /* profiling.h in Headers */, ED60E78F0DF54F870087381E /* engine_client_precomp.h in Headers */, ED60E7900DF54F870087381E /* engine_client.h in Headers */, ED60E7910DF54F870087381E /* engineclientbase.h in Headers */, ED60E7920DF54F870087381E /* wsm.h in Headers */, ED60E7930DF54F870087381E /* sml.h in Headers */, ED60E7940DF54F870087381E /* smldef.h in Headers */, ED60E7950DF54F870087381E /* smldevinfdtd.h in Headers */, ED60E7960DF54F870087381E /* smldtd.h in Headers */, ED60E7970DF54F870087381E /* smlerr.h in Headers */, ED60E7980DF54F870087381E /* smlmetinfdtd.h in Headers */, ED60E7990DF54F870087381E /* liblock.h in Headers */, ED60E79A0DF54F870087381E /* libmem.h in Headers */, ED60E79B0DF54F870087381E /* libstr.h in Headers */, ED60E79C0DF54F870087381E /* libutil.h in Headers */, ED60E79D0DF54F870087381E /* mgr.h in Headers */, ED60E79E0DF54F870087381E /* mgrutil.h in Headers */, ED60E79F0DF54F870087381E /* xltdeccom.h in Headers */, ED60E7A00DF54F870087381E /* xltdecwbxml.h in Headers */, ED60E7A10DF54F870087381E /* xltdevinf.h in Headers */, ED60E7A20DF54F870087381E /* xltenccom.h in Headers */, ED60E7A30DF54F870087381E /* xltencwbxml.h in Headers */, ED60E7A40DF54F870087381E /* xltencxml.h in Headers */, ED60E7A50DF54F870087381E /* xltmetinf.h in Headers */, ED60E7A60DF54F870087381E /* xlttags.h in Headers */, ED60E7A70DF54F870087381E /* xlttagtbl.h in Headers */, ED60E7A80DF54F870087381E /* xltutilstack.h in Headers */, ED60E7A90DF54F870087381E /* xltdec.h in Headers */, ED60E7AA0DF54F870087381E /* xltenc.h in Headers */, ED60E7AB0DF54F870087381E /* binfilebase.h in Headers */, ED60E7AC0DF54F870087381E /* binfileimplclient.h in Headers */, ED60E7AD0DF54F870087381E /* binfileimplds.h in Headers */, ED60E7AE0DF54F870087381E /* engineentry.h in Headers */, ED60E7AF0DF54F870087381E /* engineinterface.h in Headers */, ED60E7B00DF54F870087381E /* configelement.h in Headers */, ED60E7B10DF54F870087381E /* customimplds.h in Headers */, ED60E7B20DF54F870087381E /* customimplagent.h in Headers */, ED60E7B30DF54F870087381E /* dataobjtype.h in Headers */, ED60E7B40DF54F870087381E /* debuglogger.h in Headers */, ED60E7B50DF54F870087381E /* iso8601.h in Headers */, ED60E7B60DF54F870087381E /* itemfield.h in Headers */, ED60E7B80DF54F870087381E /* localengineds.h in Headers */, ED60E7B90DF54F870087381E /* mimediritemtype.h in Headers */, ED60E7BA0DF54F870087381E /* multifielditem.h in Headers */, ED60E7BB0DF54F870087381E /* multifielditemtype.h in Headers */, ED60E7BC0DF54F870087381E /* remotedatastore.h in Headers */, ED60E7BD0DF54F870087381E /* rrules.h in Headers */, ED60E7BF0DF54F870087381E /* scriptcontext.h in Headers */, ED60E7C00DF54F870087381E /* simpleitem.h in Headers */, ED60E7C10DF54F870087381E /* smltk_precomp.h in Headers */, ED60E7C20DF54F870087381E /* smltk_precomp_xpt.h in Headers */, ED60E7C30DF54F870087381E /* stringutils.h in Headers */, ED60E7C40DF54F870087381E /* superdatastore.h in Headers */, ED60E7C50DF54F870087381E /* syncappbase.h in Headers */, ED60E7C70DF54F870087381E /* syncclientbase.h in Headers */, ED60E7C80DF54F870087381E /* synccommand.h in Headers */, ED60E7C90DF54F870087381E /* syncdatastore.h in Headers */, ED60E7CB0DF54F870087381E /* syncitem.h in Headers */, ED60E7CC0DF54F870087381E /* syncitemtype.h in Headers */, ED60E7CD0DF54F870087381E /* syncsession.h in Headers */, ED60E7CE0DF54F870087381E /* syserial.h in Headers */, ED60E7CF0DF54F870087381E /* sysync.h in Headers */, ED60E7D10DF54F870087381E /* sysync_crc16.h in Headers */, ED60E7D20DF54F870087381E /* sysync_globs.h in Headers */, ED60E7D40DF54F870087381E /* sysync_precomp.h in Headers */, ED60E7D50DF54F870087381E /* sysync_precomp_xpt.h in Headers */, ED60E7D60DF54F870087381E /* stdlogicagent.h in Headers */, ED60E7D70DF54F870087381E /* stdlogicds.h in Headers */, ED60E7D90DF54F870087381E /* textitemtype.h in Headers */, ED60E7DA0DF54F870087381E /* textprofile.h in Headers */, ED60E7DB0DF54F870087381E /* timezones.h in Headers */, ED60E7DC0DF54F870087381E /* uiapi.h in Headers */, ED60E7DD0DF54F870087381E /* vcalendaritemtype.h in Headers */, ED60E7DE0DF54F870087381E /* vcarditemtype.h in Headers */, ED60E7DF0DF54F870087381E /* vtimezone.h in Headers */, ED60E7E00DF54F870087381E /* tz_table.h in Headers */, ED60E7E10DF54F870087381E /* zlib.h in Headers */, ED60E7E20DF54F870087381E /* zutil.h in Headers */, ED60E7E30DF54F870087381E /* xmlparse.h in Headers */, ED60E7E40DF54F870087381E /* pcre_config_macosx.h in Headers */, ED60E7E50DF54F870087381E /* pcre.h in Headers */, ED60E7EA0DF54F870087381E /* sysync_debug.h in Headers */, ED60E7EB0DF54F870087381E /* sync_uiapi.h in Headers */, ED60E7EC0DF54F870087381E /* xmltok.h in Headers */, ED60E7ED0DF54F870087381E /* xmldef.h in Headers */, ED60E7EE0DF54F870087381E /* ascii.h in Headers */, ED60E7EF0DF54F870087381E /* asciitab.h in Headers */, ED60E7F00DF54F870087381E /* iasciitab.h in Headers */, ED60E7F10DF54F870087381E /* latin1tab.h in Headers */, ED60E7F20DF54F870087381E /* nametab.h in Headers */, ED60E7F30DF54F870087381E /* utf8tab.h in Headers */, ED60E7F40DF54F870087381E /* xmlrole.h in Headers */, EDAC08250F179E78005E9AE2 /* mimedirprofile.h in Headers */, EDE194C81074A04F00439216 /* syncagent.h in Headers */, EDDF0816107E435200A119FE /* product_options.h in Headers */, ED4B5EB111523AAB00ECB4A5 /* sysync_utils.h in Headers */, ED4B5EB811523AAB00ECB4A5 /* san.h in Headers */, ED4B5EB911523AAB00ECB4A5 /* sysync_md5.h in Headers */, ED4B5EBB11523AAB00ECB4A5 /* sysync_b64.h in Headers */, ED4B5EBD11523AAB00ECB4A5 /* syncexception.h in Headers */, ED4B5EBE11523AAB00ECB4A5 /* lineartime.h in Headers */, EDDAFD0511A0989D003E33D5 /* rawdataitemtype.h in Headers */, ED16A68E14B9B4E400F24032 /* platform_DLL.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ ED55691D10768FAA0008C22F /* static_combiEngine_opensource_ios */ = { isa = PBXNativeTarget; buildConfigurationList = ED556A3810768FAA0008C22F /* Build configuration list for PBXNativeTarget "static_combiEngine_opensource_ios" */; buildPhases = ( ED55691E10768FAA0008C22F /* Headers */, ED5569AC10768FAA0008C22F /* Sources */, ED556A3710768FAA0008C22F /* Frameworks */, ED1ECC071383F01A00B3DA02 /* ShellScript */, ); buildRules = ( ); dependencies = ( ); name = static_combiEngine_opensource_ios; productName = clientEngine_PROTO_iPhoneOS_static; productReference = ED1ECBC41383B0DB00B3DA02 /* libsysync_combi_ios.a */; productType = "com.apple.product-type.library.static"; }; ED60E7660DF54F870087381E /* static_clientEngine_opensource_ios */ = { isa = PBXNativeTarget; buildConfigurationList = ED60E87C0DF54F870087381E /* Build configuration list for PBXNativeTarget "static_clientEngine_opensource_ios" */; buildPhases = ( ED60E7670DF54F870087381E /* Headers */, ED60E7F50DF54F870087381E /* Sources */, ED60E87B0DF54F870087381E /* Frameworks */, ED1ECC08138400F400B3DA02 /* ShellScript */, ); buildRules = ( ); dependencies = ( ); name = static_clientEngine_opensource_ios; productName = clientEngine_PROTO_iPhoneOS_static; productReference = ED1ECBC31383B0DB00B3DA02 /* libsysync_client_ios.a */; productType = "com.apple.product-type.library.static"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 29B97313FDCFA39411CA2CEA /* Project object */ = { isa = PBXProject; attributes = { LastUpgradeCheck = 0450; ORGANIZATIONNAME = plan44.ch; }; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "sysync_ios" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( English, Japanese, French, German, ); mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; projectDirPath = ""; projectRoot = ""; targets = ( ED60E7660DF54F870087381E /* static_clientEngine_opensource_ios */, ED55691D10768FAA0008C22F /* static_combiEngine_opensource_ios */, ); }; /* End PBXProject section */ /* Begin PBXShellScriptBuildPhase section */ ED1ECC071383F01A00B3DA02 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); outputPaths = ( "$(BUILT_PRODUCTS_DIR)/$(FULL_PRODUCT_NAME)", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "# Make sure we have a recent copy in the SDK /bin\n\n#echo \"TARGET_BUILD_DIR:\"\n#ls -la \"$TARGET_BUILD_DIR\"\n#echo \"BUILT_PRODUCTS_DIR:\"\n#ls -la \"$BUILT_PRODUCTS_DIR\"\necho \"cp -fpv \\\"$TARGET_BUILD_DIR/$FULL_PRODUCT_NAME\\\" \\\"$BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME\\\"\"\ncp -fpv \"$TARGET_BUILD_DIR/$FULL_PRODUCT_NAME\" \"$BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME\"\necho \"cp status = $?\"\n#echo \"BUILT_PRODUCTS_DIR:\"\n#ls -la \"$BUILT_PRODUCTS_DIR\"\n\n# Note: Xcode 4 does some magic and creates (in the Process step at the beginning of the Build)\n# a symlink in BUILT_PRODUCTS_DIR (that's the explicitly specified one in the Sysync SDK /bin)\n# to the actually built library (deep down in XCode's per-scheme build dir)\n# In this case, cp detects the file is \"identical\" and exits with 1. So we must exit with 0\n# here to make the build continue.\n# We'll end up with a link, not a real file, in the SDK /bin in this case, but that's fine\n# for subsequent TodoZ builds.\nexit 0"; }; ED1ECC08138400F400B3DA02 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); outputPaths = ( "$(BUILT_PRODUCTS_DIR)/$(FULL_PRODUCT_NAME)", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "# Make sure we have a recent copy in the SDK /bin\n\n#echo \"TARGET_BUILD_DIR:\"\n#ls -la \"$TARGET_BUILD_DIR\"\n#echo \"BUILT_PRODUCTS_DIR:\"\n#ls -la \"$BUILT_PRODUCTS_DIR\"\necho \"cp -fpv \\\"$TARGET_BUILD_DIR/$FULL_PRODUCT_NAME\\\" \\\"$BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME\\\"\"\ncp -fpv \"$TARGET_BUILD_DIR/$FULL_PRODUCT_NAME\" \"$BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME\"\necho \"cp status = $?\"\n#echo \"BUILT_PRODUCTS_DIR:\"\n#ls -la \"$BUILT_PRODUCTS_DIR\"\n\n# Note: Xcode 4 does some magic and creates (in the Process step at the beginning of the Build)\n# a symlink in BUILT_PRODUCTS_DIR (that's the explicitly specified one in the Sysync SDK /bin)\n# to the actually built library (deep down in XCode's per-scheme build dir)\n# In this case, cp detects the file is \"identical\" and exits with 1. So we must exit with 0\n# here to make the build continue.\n# We'll end up with a link, not a real file, in the SDK /bin in this case, but that's fine\n# for subsequent TodoZ builds.\nexit 0"; }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ ED5569AC10768FAA0008C22F /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( ED5569AE10768FAA0008C22F /* sync_dbapi_text.cpp in Sources */, ED5569AF10768FAA0008C22F /* enginemodulebase.cpp in Sources */, ED5569B010768FAA0008C22F /* admindata.cpp in Sources */, ED5569B110768FAA0008C22F /* blobs.cpp in Sources */, ED5569B210768FAA0008C22F /* dbitem.cpp in Sources */, ED5569B310768FAA0008C22F /* SDK_util.c in Sources */, ED5569B410768FAA0008C22F /* SDK_support.cpp in Sources */, ED5569B510768FAA0008C22F /* sync_dbapiconnect.cpp in Sources */, ED5569B910768FAA0008C22F /* dbapi.cpp in Sources */, ED5569BA10768FAA0008C22F /* pluginapiagent.cpp in Sources */, ED5569BB10768FAA0008C22F /* pluginapids.cpp in Sources */, ED5569BC10768FAA0008C22F /* DLL_interface.cpp in Sources */, ED5569BD10768FAA0008C22F /* odbcapiagent.cpp in Sources */, ED5569BE10768FAA0008C22F /* odbcapids.cpp in Sources */, ED5569BF10768FAA0008C22F /* clientengine_custom_Base.cpp in Sources */, ED5569C010768FAA0008C22F /* platform_pipe.c in Sources */, ED5569C110768FAA0008C22F /* platform_thread.cpp in Sources */, ED5569C210768FAA0008C22F /* platform_mutex.cpp in Sources */, ED5569C310768FAA0008C22F /* platform_file.cpp in Sources */, ED5569C510768FAA0008C22F /* platform_exec.c in Sources */, ED5569C610768FAA0008C22F /* platform_time.cpp in Sources */, ED5569C710768FAA0008C22F /* profiling.cpp in Sources */, ED5569C810768FAA0008C22F /* binfile.cpp in Sources */, ED5569C910768FAA0008C22F /* sysyncinit.cpp in Sources */, ED5569CA10768FAA0008C22F /* engineclientbase.cpp in Sources */, ED5569CB10768FAA0008C22F /* liblock.c in Sources */, ED5569CC10768FAA0008C22F /* libmem.c in Sources */, ED5569CD10768FAA0008C22F /* libstr.c in Sources */, ED5569CE10768FAA0008C22F /* libutil.c in Sources */, ED5569CF10768FAA0008C22F /* mgr.c in Sources */, ED5569D010768FAA0008C22F /* mgrcmdbuilder.c in Sources */, ED5569D110768FAA0008C22F /* mgrcmddispatcher.c in Sources */, ED5569D210768FAA0008C22F /* mgrinstancelist.c in Sources */, ED5569D310768FAA0008C22F /* mgrinstancemgr.c in Sources */, ED5569D410768FAA0008C22F /* mgrutil.c in Sources */, ED5569D510768FAA0008C22F /* xltdec.c in Sources */, ED5569D610768FAA0008C22F /* xltdecwbxml.c in Sources */, ED5569D710768FAA0008C22F /* xltdecxml.c in Sources */, ED5569D810768FAA0008C22F /* xltdevinf.c in Sources */, ED5569D910768FAA0008C22F /* xltenc.c in Sources */, ED5569DA10768FAA0008C22F /* xltenccom.c in Sources */, ED5569DB10768FAA0008C22F /* xltencwbxml.c in Sources */, ED5569DC10768FAA0008C22F /* xltencxml.c in Sources */, ED5569DD10768FAA0008C22F /* xltmetinf.c in Sources */, ED5569DE10768FAA0008C22F /* xlttags.c in Sources */, ED5569DF10768FAA0008C22F /* xltutilstack.c in Sources */, ED5569E010768FAA0008C22F /* binfilebase.cpp in Sources */, ED5569E110768FAA0008C22F /* binfileimplclient.cpp in Sources */, ED5569E210768FAA0008C22F /* binfileimplds.cpp in Sources */, ED5569E310768FAA0008C22F /* engineentry.cpp in Sources */, ED5569E410768FAA0008C22F /* engineinterface.cpp in Sources */, ED5569E510768FAA0008C22F /* configelement.cpp in Sources */, ED5569E610768FAA0008C22F /* customimplds.cpp in Sources */, ED5569E710768FAA0008C22F /* customimplagent.cpp in Sources */, ED5569E810768FAA0008C22F /* dataobjtype.cpp in Sources */, ED5569E910768FAA0008C22F /* debuglogger.cpp in Sources */, ED5569EA10768FAA0008C22F /* iso8601.cpp in Sources */, ED5569EB10768FAA0008C22F /* itemfield.cpp in Sources */, ED5569ED10768FAA0008C22F /* localengineds.cpp in Sources */, ED5569EE10768FAA0008C22F /* mimediritemtype.cpp in Sources */, ED5569EF10768FAA0008C22F /* multifielditem.cpp in Sources */, ED5569F010768FAA0008C22F /* multifielditemtype.cpp in Sources */, ED5569F110768FAA0008C22F /* remotedatastore.cpp in Sources */, ED5569F210768FAA0008C22F /* rrules.cpp in Sources */, ED5569F410768FAA0008C22F /* scriptcontext.cpp in Sources */, ED5569F510768FAA0008C22F /* simpleitem.cpp in Sources */, ED5569F610768FAA0008C22F /* stringutils.cpp in Sources */, ED5569F710768FAA0008C22F /* superdatastore.cpp in Sources */, ED5569F810768FAA0008C22F /* syncappbase.cpp in Sources */, ED5569F910768FAA0008C22F /* syncclientbase.cpp in Sources */, ED5569FA10768FAA0008C22F /* synccommand.cpp in Sources */, ED5569FB10768FAA0008C22F /* syncdatastore.cpp in Sources */, ED5569FD10768FAA0008C22F /* syncitem.cpp in Sources */, ED5569FE10768FAA0008C22F /* syncitemtype.cpp in Sources */, ED5569FF10768FAA0008C22F /* syncsession.cpp in Sources */, ED556A0210768FAA0008C22F /* sysync_crc16.cpp in Sources */, ED556A0410768FAA0008C22F /* stdlogicagent.cpp in Sources */, ED556A0510768FAA0008C22F /* stdlogicds.cpp in Sources */, ED556A0710768FAA0008C22F /* textitemtype.cpp in Sources */, ED556A0810768FAA0008C22F /* textprofile.cpp in Sources */, ED556A0910768FAA0008C22F /* timezones.cpp in Sources */, ED556A0A10768FAA0008C22F /* uiapi.cpp in Sources */, ED556A0B10768FAA0008C22F /* vcalendaritemtype.cpp in Sources */, ED556A0C10768FAA0008C22F /* vcarditemtype.cpp in Sources */, ED556A0D10768FAA0008C22F /* vtimezone.cpp in Sources */, ED556A0E10768FAA0008C22F /* infback.c in Sources */, ED556A0F10768FAA0008C22F /* gzio.c in Sources */, ED556A1010768FAA0008C22F /* deflate.c in Sources */, ED556A1110768FAA0008C22F /* uncompr.c in Sources */, ED556A1210768FAA0008C22F /* trees.c in Sources */, ED556A1310768FAA0008C22F /* inftrees.c in Sources */, ED556A1410768FAA0008C22F /* inflate.c in Sources */, ED556A1510768FAA0008C22F /* inffast.c in Sources */, ED556A1610768FAA0008C22F /* zutil.c in Sources */, ED556A1710768FAA0008C22F /* crc32.c in Sources */, ED556A1810768FAA0008C22F /* compress.c in Sources */, ED556A1910768FAA0008C22F /* adler32.c in Sources */, ED556A1A10768FAA0008C22F /* xmlparse.c in Sources */, ED556A1B10768FAA0008C22F /* xmltok.c in Sources */, ED556A1C10768FAA0008C22F /* xmlrole.c in Sources */, ED556A1D10768FAA0008C22F /* pcre_ord2utf8.c in Sources */, ED556A1E10768FAA0008C22F /* pcre_chartables.c in Sources */, ED556A1F10768FAA0008C22F /* pcre_compile.c in Sources */, ED556A2010768FAA0008C22F /* pcre_config.c in Sources */, ED556A2110768FAA0008C22F /* pcre_dfa_exec.c in Sources */, ED556A2210768FAA0008C22F /* pcre_exec.c in Sources */, ED556A2310768FAA0008C22F /* pcre_fullinfo.c in Sources */, ED556A2410768FAA0008C22F /* pcre_get.c in Sources */, ED556A2510768FAA0008C22F /* pcre_globals.c in Sources */, ED556A2610768FAA0008C22F /* pcre_info.c in Sources */, ED556A2710768FAA0008C22F /* pcre_newline.c in Sources */, ED556A2810768FAA0008C22F /* pcre_refcount.c in Sources */, ED556A2910768FAA0008C22F /* pcre_study.c in Sources */, ED556A2A10768FAA0008C22F /* pcre_tables.c in Sources */, ED556A2B10768FAA0008C22F /* pcre_try_flipped.c in Sources */, ED556A2C10768FAA0008C22F /* pcre_valid_utf8.c in Sources */, ED556A2D10768FAA0008C22F /* pcre_version.c in Sources */, ED556A2E10768FAA0008C22F /* pcre_xclass.c in Sources */, ED556A2F10768FAA0008C22F /* configfiles.mm in Sources */, ED556A3410768FAA0008C22F /* mimedirprofile.cpp in Sources */, ED556A3510768FAA0008C22F /* platform_timezones.mm in Sources */, ED556A3610768FAA0008C22F /* syncagent.cpp in Sources */, ED556A4810768FD90008C22F /* serverengine_custom_Base.cpp in Sources */, ED556A50107692F20008C22F /* enginesessiondispatch.cpp in Sources */, ED4B5ECE11523AAB00ECB4A5 /* sysync_utils.cpp in Sources */, ED4B5ECF11523AAB00ECB4A5 /* syncexception.cpp in Sources */, ED4B5ED211523AAB00ECB4A5 /* lineartime.cpp in Sources */, ED4B5ED311523AAB00ECB4A5 /* san.cpp in Sources */, ED4B5ED611523AAB00ECB4A5 /* sysync_md5.cpp in Sources */, ED4B5ED811523AAB00ECB4A5 /* sysync_b64.cpp in Sources */, EDDAFD0A11A0989D003E33D5 /* rawdataitemtype.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; ED60E7F50DF54F870087381E /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( ED60E7F70DF54F870087381E /* sync_dbapi_text.cpp in Sources */, ED60E7F80DF54F870087381E /* enginemodulebase.cpp in Sources */, ED60E7F90DF54F870087381E /* admindata.cpp in Sources */, ED60E7FA0DF54F870087381E /* blobs.cpp in Sources */, ED60E7FB0DF54F870087381E /* dbitem.cpp in Sources */, ED60E7FC0DF54F870087381E /* SDK_util.c in Sources */, ED60E7FD0DF54F870087381E /* SDK_support.cpp in Sources */, ED60E7FF0DF54F870087381E /* sync_dbapiconnect.cpp in Sources */, ED60E8030DF54F870087381E /* dbapi.cpp in Sources */, ED60E8040DF54F870087381E /* pluginapiagent.cpp in Sources */, ED60E8050DF54F870087381E /* pluginapids.cpp in Sources */, ED60E8060DF54F870087381E /* DLL_interface.cpp in Sources */, ED60E8070DF54F870087381E /* odbcapiagent.cpp in Sources */, ED60E8080DF54F870087381E /* odbcapids.cpp in Sources */, ED60E8090DF54F870087381E /* clientengine_custom_Base.cpp in Sources */, ED60E80A0DF54F870087381E /* platform_pipe.c in Sources */, ED60E80B0DF54F870087381E /* platform_thread.cpp in Sources */, ED60E80C0DF54F870087381E /* platform_mutex.cpp in Sources */, ED60E80D0DF54F870087381E /* platform_file.cpp in Sources */, ED60E8100DF54F870087381E /* platform_exec.c in Sources */, ED60E8110DF54F870087381E /* platform_time.cpp in Sources */, ED60E8120DF54F870087381E /* profiling.cpp in Sources */, ED60E8130DF54F870087381E /* binfile.cpp in Sources */, ED60E8140DF54F870087381E /* sysyncinit.cpp in Sources */, ED60E8150DF54F870087381E /* engineclientbase.cpp in Sources */, ED60E8160DF54F870087381E /* liblock.c in Sources */, ED60E8170DF54F870087381E /* libmem.c in Sources */, ED60E8180DF54F870087381E /* libstr.c in Sources */, ED60E8190DF54F870087381E /* libutil.c in Sources */, ED60E81A0DF54F870087381E /* mgr.c in Sources */, ED60E81B0DF54F870087381E /* mgrcmdbuilder.c in Sources */, ED60E81C0DF54F870087381E /* mgrcmddispatcher.c in Sources */, ED60E81D0DF54F870087381E /* mgrinstancelist.c in Sources */, ED60E81E0DF54F870087381E /* mgrinstancemgr.c in Sources */, ED60E81F0DF54F870087381E /* mgrutil.c in Sources */, ED60E8200DF54F870087381E /* xltdec.c in Sources */, ED60E8210DF54F870087381E /* xltdecwbxml.c in Sources */, ED60E8220DF54F870087381E /* xltdecxml.c in Sources */, ED60E8230DF54F870087381E /* xltdevinf.c in Sources */, ED60E8240DF54F870087381E /* xltenc.c in Sources */, ED60E8250DF54F870087381E /* xltenccom.c in Sources */, ED60E8260DF54F870087381E /* xltencwbxml.c in Sources */, ED60E8270DF54F870087381E /* xltencxml.c in Sources */, ED60E8280DF54F870087381E /* xltmetinf.c in Sources */, ED60E8290DF54F870087381E /* xlttags.c in Sources */, ED60E82A0DF54F870087381E /* xltutilstack.c in Sources */, ED60E82B0DF54F870087381E /* binfilebase.cpp in Sources */, ED60E82C0DF54F870087381E /* binfileimplclient.cpp in Sources */, ED60E82D0DF54F870087381E /* binfileimplds.cpp in Sources */, ED60E82E0DF54F870087381E /* engineentry.cpp in Sources */, ED60E82F0DF54F870087381E /* engineinterface.cpp in Sources */, ED60E8300DF54F870087381E /* configelement.cpp in Sources */, ED60E8310DF54F870087381E /* customimplds.cpp in Sources */, ED60E8320DF54F870087381E /* customimplagent.cpp in Sources */, ED60E8330DF54F870087381E /* dataobjtype.cpp in Sources */, ED60E8340DF54F870087381E /* debuglogger.cpp in Sources */, ED60E8350DF54F870087381E /* iso8601.cpp in Sources */, ED60E8360DF54F870087381E /* itemfield.cpp in Sources */, ED60E8380DF54F870087381E /* localengineds.cpp in Sources */, ED60E8390DF54F870087381E /* mimediritemtype.cpp in Sources */, ED60E83A0DF54F870087381E /* multifielditem.cpp in Sources */, ED60E83B0DF54F870087381E /* multifielditemtype.cpp in Sources */, ED60E83C0DF54F870087381E /* remotedatastore.cpp in Sources */, ED60E83D0DF54F870087381E /* rrules.cpp in Sources */, ED60E83F0DF54F870087381E /* scriptcontext.cpp in Sources */, ED60E8400DF54F870087381E /* simpleitem.cpp in Sources */, ED60E8410DF54F870087381E /* stringutils.cpp in Sources */, ED60E8420DF54F870087381E /* superdatastore.cpp in Sources */, ED60E8430DF54F870087381E /* syncappbase.cpp in Sources */, ED60E8450DF54F870087381E /* syncclientbase.cpp in Sources */, ED60E8460DF54F870087381E /* synccommand.cpp in Sources */, ED60E8470DF54F870087381E /* syncdatastore.cpp in Sources */, ED60E8490DF54F870087381E /* syncitem.cpp in Sources */, ED60E84A0DF54F870087381E /* syncitemtype.cpp in Sources */, ED60E84B0DF54F870087381E /* syncsession.cpp in Sources */, ED60E84E0DF54F870087381E /* sysync_crc16.cpp in Sources */, ED60E8500DF54F870087381E /* stdlogicagent.cpp in Sources */, ED60E8510DF54F870087381E /* stdlogicds.cpp in Sources */, ED60E8530DF54F870087381E /* textitemtype.cpp in Sources */, ED60E8540DF54F870087381E /* textprofile.cpp in Sources */, ED60E8550DF54F870087381E /* timezones.cpp in Sources */, ED60E8560DF54F870087381E /* uiapi.cpp in Sources */, ED60E8570DF54F870087381E /* vcalendaritemtype.cpp in Sources */, ED60E8580DF54F870087381E /* vcarditemtype.cpp in Sources */, ED60E8590DF54F870087381E /* vtimezone.cpp in Sources */, ED60E85A0DF54F870087381E /* infback.c in Sources */, ED60E85B0DF54F870087381E /* gzio.c in Sources */, ED60E85C0DF54F870087381E /* deflate.c in Sources */, ED60E85D0DF54F870087381E /* uncompr.c in Sources */, ED60E85E0DF54F870087381E /* trees.c in Sources */, ED60E85F0DF54F870087381E /* inftrees.c in Sources */, ED60E8600DF54F870087381E /* inflate.c in Sources */, ED60E8610DF54F870087381E /* inffast.c in Sources */, ED60E8620DF54F870087381E /* zutil.c in Sources */, ED60E8630DF54F870087381E /* crc32.c in Sources */, ED60E8640DF54F870087381E /* compress.c in Sources */, ED60E8650DF54F870087381E /* adler32.c in Sources */, ED60E8660DF54F870087381E /* xmlparse.c in Sources */, ED60E8670DF54F870087381E /* xmltok.c in Sources */, ED60E8680DF54F870087381E /* xmlrole.c in Sources */, ED60E8690DF54F870087381E /* pcre_ord2utf8.c in Sources */, ED60E86A0DF54F870087381E /* pcre_chartables.c in Sources */, ED60E86B0DF54F870087381E /* pcre_compile.c in Sources */, ED60E86C0DF54F870087381E /* pcre_config.c in Sources */, ED60E86D0DF54F870087381E /* pcre_dfa_exec.c in Sources */, ED60E86E0DF54F870087381E /* pcre_exec.c in Sources */, ED60E86F0DF54F870087381E /* pcre_fullinfo.c in Sources */, ED60E8700DF54F870087381E /* pcre_get.c in Sources */, ED60E8710DF54F870087381E /* pcre_globals.c in Sources */, ED60E8720DF54F870087381E /* pcre_info.c in Sources */, ED60E8730DF54F870087381E /* pcre_newline.c in Sources */, ED60E8740DF54F870087381E /* pcre_refcount.c in Sources */, ED60E8750DF54F870087381E /* pcre_study.c in Sources */, ED60E8760DF54F870087381E /* pcre_tables.c in Sources */, ED60E8770DF54F870087381E /* pcre_try_flipped.c in Sources */, ED60E8780DF54F870087381E /* pcre_valid_utf8.c in Sources */, ED60E8790DF54F870087381E /* pcre_version.c in Sources */, ED60E87A0DF54F870087381E /* pcre_xclass.c in Sources */, ED43DAD70E014BC9000A1E5C /* configfiles.mm in Sources */, EDAC08260F179E78005E9AE2 /* mimedirprofile.cpp in Sources */, ED5B87FB0F8559C40042779A /* platform_timezones.mm in Sources */, EDE194C91074A04F00439216 /* syncagent.cpp in Sources */, ED4B5EB211523AAB00ECB4A5 /* sysync_utils.cpp in Sources */, ED4B5EB311523AAB00ECB4A5 /* syncexception.cpp in Sources */, ED4B5EB611523AAB00ECB4A5 /* lineartime.cpp in Sources */, ED4B5EB711523AAB00ECB4A5 /* san.cpp in Sources */, ED4B5EBA11523AAB00ECB4A5 /* sysync_md5.cpp in Sources */, ED4B5EBC11523AAB00ECB4A5 /* sysync_b64.cpp in Sources */, EDDAFD0611A0989D003E33D5 /* rawdataitemtype.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin XCBuildConfiguration section */ C01FCF4F08A954540054247B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; GCC_C_LANGUAGE_STANDARD = c99; GCC_THUMB_SUPPORT = NO; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; GENERATE_MASTER_OBJECT_FILE = YES; IPHONEOS_DEPLOYMENT_TARGET = 3.0; ONLY_ACTIVE_ARCH = YES; OTHER_CFLAGS = "-mno-thumb"; SDKROOT = iphoneos; }; name = Debug; }; C01FCF5008A954540054247B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { GCC_C_LANGUAGE_STANDARD = c99; GCC_THUMB_SUPPORT = NO; GENERATE_MASTER_OBJECT_FILE = YES; IPHONEOS_DEPLOYMENT_TARGET = 3.0; OTHER_CFLAGS = "-mno-thumb"; SDKROOT = iphoneos; }; name = Release; }; ED556A3910768FAA0008C22F /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CONFIGURATION_BUILD_DIR = "$(PROJECT_DIR)/sysync_SDK/bin/iOS/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = "DEBUG=1"; GCC_THUMB_SUPPORT = NO; PRODUCT_NAME = sysync_combi_ios; SKIP_INSTALL = YES; USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/Targets/ReleasedProducts/combiEngine_opensource_ios"; }; name = Debug; }; ED556A3A10768FAA0008C22F /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CONFIGURATION_BUILD_DIR = "$(PROJECT_DIR)/sysync_SDK/bin/iOS/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; GCC_C_LANGUAGE_STANDARD = c99; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_THUMB_SUPPORT = NO; PRODUCT_NAME = sysync_combi_ios; SKIP_INSTALL = YES; USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/Targets/ReleasedProducts/combiEngine_opensource_ios"; ZERO_LINK = NO; }; name = Release; }; ED60E87D0DF54F870087381E /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CONFIGURATION_BUILD_DIR = "$(PROJECT_DIR)/sysync_SDK/bin/iOS/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREFIX_HEADER = prefix_file.h; GCC_PREPROCESSOR_DEFINITIONS = "DEBUG=1"; GCC_THUMB_SUPPORT = NO; PRODUCT_NAME = sysync_client_ios; SKIP_INSTALL = YES; USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/Targets/ReleasedProducts/clientEngine_opensource_ios"; }; name = Debug; }; ED60E87E0DF54F870087381E /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CONFIGURATION_BUILD_DIR = "$(PROJECT_DIR)/sysync_SDK/bin/iOS/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_PREFIX_HEADER = prefix_file.h; GCC_THUMB_SUPPORT = NO; PRODUCT_NAME = sysync_client_ios; SKIP_INSTALL = YES; USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/Targets/ReleasedProducts/clientEngine_opensource_ios"; ZERO_LINK = NO; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ C01FCF4E08A954540054247B /* Build configuration list for PBXProject "sysync_ios" */ = { isa = XCConfigurationList; buildConfigurations = ( C01FCF4F08A954540054247B /* Debug */, C01FCF5008A954540054247B /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; ED556A3810768FAA0008C22F /* Build configuration list for PBXNativeTarget "static_combiEngine_opensource_ios" */ = { isa = XCConfigurationList; buildConfigurations = ( ED556A3910768FAA0008C22F /* Debug */, ED556A3A10768FAA0008C22F /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; ED60E87C0DF54F870087381E /* Build configuration list for PBXNativeTarget "static_clientEngine_opensource_ios" */ = { isa = XCConfigurationList; buildConfigurations = ( ED60E87D0DF54F870087381E /* Debug */, ED60E87E0DF54F870087381E /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; } libsynthesis-3.4.0.47.1/src/sysync_ios.xcodeproj/project.xcworkspace/000077500000000000000000000000001226375725500256275ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/sysync_ios.xcodeproj/project.xcworkspace/contents.xcworkspacedata000066400000000000000000000002161226375725500325700ustar00rootroot00000000000000 libsynthesis-3.4.0.47.1/src/sysync_ios.xcodeproj/xcshareddata/000077500000000000000000000000001226375725500242645ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/sysync_ios.xcodeproj/xcshareddata/xcschemes/000077500000000000000000000000001226375725500262465ustar00rootroot00000000000000static_clientEngine_opensource_ios.xcscheme000066400000000000000000000040211226375725500367740ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/sysync_ios.xcodeproj/xcshareddata/xcschemes static_combiEngine_opensource_ios.xcscheme000066400000000000000000000040171226375725500366140ustar00rootroot00000000000000libsynthesis-3.4.0.47.1/src/sysync_ios.xcodeproj/xcshareddata/xcschemes libsynthesis-3.4.0.47.1/synthesis-sdk.pc.in000066400000000000000000000003521226375725500204050ustar00rootroot00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: synthesis Description: Synthesis SyncML SDK Version: @VERSION@ Libs: -L${libdir} -lsynthesissdk -lsmltk -lsynthesisstubs Cflags: -I${includedir} libsynthesis-3.4.0.47.1/synthesis.pc.in000066400000000000000000000003771226375725500176350ustar00rootroot00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: synthesis Description: Synthesis SyncML SDK, Client and Server Engine Version: @VERSION@ Libs: -L${libdir} -lsynthesissdk -lsmltk -lsynthesis Cflags: -I${includedir}